commit 4800a0e3b8e54e415d17b9043e1455ad2fa82c8d Author: 依瑪貓 Date: Tue Mar 10 21:25:26 2026 +0800 Initial commit. diff --git a/htdocs/clio/index.html b/htdocs/clio/index.html new file mode 100644 index 0000000..1f2c197 --- /dev/null +++ b/htdocs/clio/index.html @@ -0,0 +1,26 @@ + + + + +JRڵO Clio's Note + + + +

JRڵO Clio's Note

+

t_Aq@ӯʥFkvҵ{~NͰ_

+

xWkv Female History in formosa

+

̷sѵ review

+

s(Gossip)--LhkHͲU

+ +

kvƮw(Reproduction)

+

d( Historical remains) + + + + + diff --git a/htdocs/emandy/cgi-bin/search.cgi b/htdocs/emandy/cgi-bin/search.cgi new file mode 100755 index 0000000..d69f988 --- /dev/null +++ b/htdocs/emandy/cgi-bin/search.cgi @@ -0,0 +1,55 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# search.cgi: The web site full-text search. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); + +use Fcntl qw(:seek); + +initenv(-allowed => [qw(GET HEAD)], + -session => 0, + -dbi_lock => {"pages" => LOCK_SH, + "legend" => LOCK_SH, + "links" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("search, query, full text search"), + "class" => "search"}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $LIST; + # List handler handles its own error + $LIST = new Selima::emandy::List::Search; + html_header $LIST->{"title"}, $LIST->page_param; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/emandy/favicon.ico b/htdocs/emandy/favicon.ico new file mode 100644 index 0000000..7b30129 Binary files /dev/null and b/htdocs/emandy/favicon.ico differ diff --git a/htdocs/emandy/home/index.html b/htdocs/emandy/home/index.html new file mode 100644 index 0000000..a75712c --- /dev/null +++ b/htdocs/emandy/home/index.html @@ -0,0 +1,70 @@ + + + + + + + + + + + 小招的首頁 + + + +
+ +

小招的首頁

+ +
+
+ + +
+
+ + + +
+

版權所有 © 2006-2020 小招

+
+ +
+ + + diff --git a/htdocs/emandy/home/old/index.html.html b/htdocs/emandy/home/old/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/emandy/home/old/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/emandy/home/old/index.html.xhtml b/htdocs/emandy/home/old/index.html.xhtml new file mode 100644 index 0000000..60b9297 --- /dev/null +++ b/htdocs/emandy/home/old/index.html.xhtml @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + +小招的首頁 + + + + +
+ + +

小招的首頁

+ + + +
+
+ +
+
+
+ +
+ + +
+ + + + diff --git a/htdocs/emandy/images/icon.gif b/htdocs/emandy/images/icon.gif new file mode 100644 index 0000000..10b5b8f Binary files /dev/null and b/htdocs/emandy/images/icon.gif differ diff --git a/htdocs/emandy/images/mandy.jpg b/htdocs/emandy/images/mandy.jpg new file mode 100644 index 0000000..a1b2478 Binary files /dev/null and b/htdocs/emandy/images/mandy.jpg differ diff --git a/htdocs/emandy/images/modperl.png b/htdocs/emandy/images/modperl.png new file mode 100644 index 0000000..9c295b0 Binary files /dev/null and b/htdocs/emandy/images/modperl.png differ diff --git a/htdocs/emandy/index.html.html b/htdocs/emandy/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/emandy/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/emandy/index.html.xhtml b/htdocs/emandy/index.html.xhtml new file mode 100644 index 0000000..8fd3891 --- /dev/null +++ b/htdocs/emandy/index.html.xhtml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + +小招的網站 + + + + + + +
+ +
+ + +

小招的網站

+ +

網站架設中,敬請期待。妳可以先前往下列網站參觀:

+ + + +
+ + +
+ + + + diff --git a/htdocs/emandy/magicat/biography.html b/htdocs/emandy/magicat/biography.html new file mode 100644 index 0000000..b739bfa --- /dev/null +++ b/htdocs/emandy/magicat/biography.html @@ -0,0 +1,34 @@ + + + + + + + +۶ + + + + +

۶

+

ڦbsX͡AbӤpĤƦĤAC{L~@hlh]h֮𪺬KpA`O~ˤCSLШ|AS͡AVӨSŶaڭ̳oǤpġC۸LPǡAڨèSӨӦh檺OAˬO]׹LF@ӧּ֪~A]iXWߦۥDͬ覡C

+ +

F[HӹvѪAڿܦbjǡBsұMvCҾlvAڰѥ[F֪ΡA]wϮ]N@@諸~ǧ@~h^BA~䤤mäBC}ļlާڪOsaX@tCj˲ǵۧ@A~ڦ^30~NpAmIeǡnBѪ٪<>A󦭪|mQǡnBm|nC

+ +

ɾA{ꤺYAoǤǧ@~ڪ|NѦjҵoAiӰѻPǹBBBBBAIJijD[AzձڸsvqBҸꪧijBOBkvqhCHӤhפDجqqFvѻPݼwkB(1891-1918)rAOӤHOҤΪ@BC

+ +

ŪӤhǦAڦb|Ƭs߭¾AOdzNs譱u@Aou@Dnb\ŪBBxTaȴZƤA[HBsXBkɡC

+ +

~AھxjksǪUzsADnu@e|ʱШ|qѱШ|sAäsǦFưȡCPɡAЩߪŤjǤΤMA½ҤesAOW}ovBƥvBvB{Nvҵ{Fu@lûPHP|wŪѬQ|AoZAگqҾǡC

+ +

h~9PxjksǬ@~uAMؤjǾvsҳŤjбª|peiNxWHں--PGغcι20@xWu{NʡvϬ١jsUz]1999~10-2000~9멳^Cu@ejBAΤ@ǭpeF~ȵCݥ|qǥvqTrsC

+ +

bqBΤWAF򥻪ѸƳBz~Ap󨳳tBĦaQκ귽AOثeۧڶiת@¦WCu㴶ΤơAO_uରH̩ҾrAܤ|LwסCUxWBCgAb骺ʭWLkPeX~۴ýסA֪B´ɯVoiAHzLqlκ~|AMDt@ز´siʡCڤ]Fo˪աA]PBͦXuknvqlAwXZAó]knF{ݥäkʤJfhercafeukܡvM@aC]@dzNӻAPsҮɪTn͡AпqvGz׻PơrvvqTAþwebmasterC

+ +

ܩ󥼨ӳWeAڷQ~ŪդhZqƾdzNsAۤġgxWkZLƥvC]D¾ҶqAڤƱdbPdzNsҤAbֿno~Ӫu@gA۫HbʦF~Ȯӷ|[oC~Aڥ`߯ǥѳoӤu@|Al״IdzNsAWs᪺sC

+ + \ No newline at end of file diff --git a/htdocs/emandy/magicat/biography1.html b/htdocs/emandy/magicat/biography1.html new file mode 100644 index 0000000..ee066bb --- /dev/null +++ b/htdocs/emandy/magicat/biography1.html @@ -0,0 +1,32 @@ + + + + + + + +۶ + + + + +

۶

+

ڦbsX͡AbӤpĤƦĤAC{L~@hlh]h֮𪺬KpA`O~ˤCSLШ|AS͡AVӨSŶaڭ̳oǤpġC۸LPǡAڨèSӨӦh檺OAˬO]׹LF@ӧּ֪~A]iXWߦۥDͬ覡C

+ +

F[HӹvѪAڿܦbjǡBsұMvCҾlvAڰѥ[F֪ΡA]wϮ]N@@諸~ǧ@~h^BA~䤤mäBC}ļlާڪOsaX@tCj˲ǵۧ@A~ڦ^30~NpAmIeǡnBѪ٪<>A󦭪|mQǡnBm|nC

+ +

ŪӤhǦAڦb|Ƭs߭¾AOdzNs譱u@Aou@Dnb\ŪBBxTaȴZƤA[HBsXBkɡC

+ +

~AھxjksǪUzsADnu@e|ʱШ|qѱШ|sAäsǦFưȡCPɡAЩߪŤjǤΤMA½ҤesAOW}ovBƥvBvB{Nvҵ{Fu@lûPHP|wŪѬQ|AoZAگqҾǡC

+ +

h~9PxjksǬ@~uAMؤjǾvsҳŤjбª|peiNxWHں--PGغcι20@xWu{NʡvϬ١jsUz]1999~10-2000~9멳^Cu@ejBAΤ@ǭpeF~ȵCݥ|qǥvqTrsC

+ +

bqBΤWAF򥻪ѸƳBz~Ap󨳳tBĦaQκ귽AOثeۧڶiת@¦WCu㴶ΤơAO_uରH̩ҾrAܤ|LwסCUxWBCgAb骺ʭWLkPeX~۴ýסA֪B´ɯVoiAHzLqlκ~|AMDt@ز´siʡCڤ]Fo˪աA]PBͦXuknvqlAwXZAó]knF{ݥäkʤJfhercafeukܡvM@aC]@dzNӻAPsҮɪTn͡AпqvGz׻PơrvvqTAþӺwebmasterC

+ +

ܩ󥼨ӳWeAڰndbdzNҤu@Cbֿno~Ӫu@gA۫HbʦF~Ȯӷ|[oC

+ + diff --git a/htdocs/emandy/magicat/cgi-bin/acctrecs.cgi b/htdocs/emandy/magicat/cgi-bin/acctrecs.cgi new file mode 100755 index 0000000..045f5f4 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/acctrecs.cgi @@ -0,0 +1,242 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# acctrecs.cgi: The accounting record administration. + +# Copyright (c) 2007-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-24 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_seltrx($); +sub import_selsubj($); + +initenv(-restricted => 1, + -this_table => "acctrecs", + -dbi_lock => {"acctrecs" => LOCK_EX, + "accttrx" => LOCK_SH, + "acctsubj" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("accounting")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::AcctRec($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + # Only allowing to run on HTTPS + http_403 if !is_https; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Only allowing to run on HTTPS + http_403 if !is_https; + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::AcctRec(curform); + $checker->redir(qw(seltrx deltrx selsubj delsubj)); + $error = $checker->check(qw(trx type ord subj summary amount)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::AcctRec(curform); + $checker->redir(qw(del seltrx deltrx selsubj delsubj)); + $error = $checker->check(qw(trx type ord subj summary amount)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::AcctRec(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::AcctRec($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Accounting::Records; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the accounting record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This accounting record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $CURRENT{"type"} = $CURRENT{"credit"}? "credit": "debit"; + + # OK + return; +} + +# import_seltrx: Import the selected accounting transaction into the retrieved form +sub import_seltrx($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("trx", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "accttrx"; + return; +} + +# import_selsubj: Import the selected accounting subject into the retrieved form +sub import_selsubj($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("subj", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "acctsubj"; + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/acctreps.cgi b/htdocs/emandy/magicat/cgi-bin/acctreps.cgi new file mode 100755 index 0000000..cb679ac --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/acctreps.cgi @@ -0,0 +1,107 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# acctreps.cgi: The accounting report viewer. + +# Copyright (c) 2007-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-24 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub html_page($); + +initenv(-restricted => 1, + -dbi_lock => {"acctsubj" => LOCK_SH, + "accttrx" => LOCK_SH, + "acctrecs" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("accounting"), + "javascripts" => [qw(/scripts/accounting.js)]}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $error; + # Only allowing requests with GET method + # Check it here, since we still want list preference handlers to work + http_405 qw(GET) if $ENV{"REQUEST_METHOD"} ne "GET"; + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + # Only allowing to run on HTTPS + http_403 if !is_https; + # List handler handles its own error + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $page_param); + $status = $_[0]; + # List the available items + $_ = list_type; + if ($_ eq "cashsum") { + $LIST = new Selima::List::Accounting::Reports::Cash::Summary; + } elsif ($_ eq "ldgr") { + $LIST = new Selima::List::Accounting::Reports::Ledger; + } elsif ($_ eq "ldgrsum") { + $LIST = new Selima::List::Accounting::Reports::Ledger::Summary; + } elsif ($_ eq "journal") { + $LIST = new Selima::List::Accounting::Reports::Journal; + } elsif ($_ eq "tb") { + $LIST = new Selima::List::Accounting::Reports::TriBlnc; + } elsif ($_ eq "incmstat") { + $LIST = new Selima::List::Accounting::Reports::IncmStat; + } elsif ($_ eq "blncshet") { + $LIST = new Selima::List::Accounting::Reports::BlncShet; + } elsif ($_ eq "search") { + $LIST = new Selima::List::Accounting::Reports::Search; + } else { + $LIST = new Selima::List::Accounting::Reports::Cash; + } + # Return the data as a CSV file + return $LIST->html if $LIST->{"iscsv"}; + # Ordinary list + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/acctsubj.cgi b/htdocs/emandy/magicat/cgi-bin/acctsubj.cgi new file mode 100755 index 0000000..1947bc9 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/acctsubj.cgi @@ -0,0 +1,292 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# acctsubj.cgi: The accounting subject administraion. + +# Copyright (c) 2007-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-24 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selparent($); + +initenv(-restricted => 1, + -this_table => "acctsubj", + -dbi_lock => {"acctsubj" => LOCK_EX, + "acctrecs" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("accounting")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::AcctSubj($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + # Only allowing to run on HTTPS + http_403 if !is_https; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new accounting subject from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + return {"msg"=>N_("This accounting subject has [numerate,_1,an accounting sub-subject,accounting sub-subjects]. It cannot be deleted. To delete the subject, [numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] must first be deleted."), + "margs"=>[$CURRENT{"ssubcount"}], + "isform"=>0} + if $CURRENT{"ssubcount"} > 0; + return {"msg"=>N_("This accounting subject has [numerate,_1,an accounting record,accounting records]. It cannot be deleted. To delete the subject, [numerate,_1,its accounting record,all of its accounting records] must first be deleted."), + "margs"=>[$CURRENT{"reccount"}], + "isform"=>0} + if $CURRENT{"reccount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Only allowing to run on HTTPS + http_403 if !is_https; + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new accounting subject from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + # Run the checker + $checker = new Selima::Checker::AcctSubj(curform); + $checker->redir(qw(selparent delparent)); + $error = $checker->check(qw(parent code title)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::AcctSubj(curform); + $checker->redir(qw(del zhsync selparent delparent)); + $error = $checker->check(qw(parent code title)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::AcctSubj(curform); + $checker->redir(qw(cancel)); + return {"msg"=>N_("This accounting subject has [numerate,_1,an accounting sub-subject,accounting sub-subjects]. It cannot be deleted. To delete the subject, [numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] must first be deleted."), + "margs"=>[$CURRENT{"ssubcount"}], + "isform"=>0} + if $CURRENT{"ssubcount"} > 0; + return {"msg"=>N_("This accounting subject has [numerate,_1,an accounting record,accounting records]. It cannot be deleted. To delete the subject, [numerate,_1,its accounting record,all of its accounting records] must first be deleted."), + "margs"=>[$CURRENT{"reccount"}], + "isform"=>0} + if $CURRENT{"reccount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::AcctSubj($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + if (list_type eq "lastlv") { + $LIST = new Selima::List::Accounting::Subjects::LastLv; + } else { + $LIST = new Selima::List::Accounting::Subjects; + } + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lang, $lndb, $lndbdef, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the accounting subject."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This accounting subject does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $lang = getlang; + $lndb = getlang LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + + # Obtain the belonging subjects list + @_ = qw(); + push @_, "sn AS sn"; + if (@ALL_LINGUAS > 1) { + $title = $lang eq $DEFAULT_LANG? "title_$lndb": + "COALESCE(title_$lndb, title_$lndbdef)"; + } else {; + $title = "title"; + } + push @_, $DBH->strcat("code", "' '", $title) . " AS title"; + $sql = "SELECT " . join(", ", @_) . " FROM acctsubj" + . " WHERE parent=$sn" + . " ORDER BY code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"ssubcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"ssubcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"ssub$_" . "sn"} = $$row{"sn"}; + $CURRENT{"ssub$_" . "title"} = $$row{"title"}; + } + + # Obtain the belonging records list + $sql = "SELECT sn FROM acctrecs" + . " WHERE subj=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"reccount"} = $sth->rows; + + # OK + return; +} + +# import_selparent: Import the selected parent into the retrieved form +sub import_selparent($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "acctsubj") { + $FORM->param("parent", $GET->param("selsn")); + $FORM->param("topmost", "false"); + } + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/accttrx.cgi b/htdocs/emandy/magicat/cgi-bin/accttrx.cgi new file mode 100755 index 0000000..f83b4f4 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/accttrx.cgi @@ -0,0 +1,278 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# accttrx.cgi: The accounting transaction administraion. + +# Copyright (c) 2007-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-24 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selsubj($); + +initenv(-restricted => 1, + -this_table => "accttrx", + -dbi_lock => {"accttrx" => LOCK_EX, + "acctrecs" => LOCK_EX, + "acctsubj" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("accounting"), + "javascripts" => [qw(/scripts/accounting.js)]}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::AcctTrx($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + # Only allowing to run on HTTPS + http_403 if !is_https; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Only allowing to run on HTTPS + http_403 if !is_https; + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::AcctTrx(curform); + $checker->redir(qw(cnvttrans selsubj)); + $error = $checker->check(qw(date ord note recs)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::AcctTrx(curform); + $checker->redir(qw(del cnvttrans selsubj)); + $error = $checker->check(qw(date ord note recs)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::AcctTrx(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::AcctTrx($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Accounting::Transacts; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the accounting transaction."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This accounting transaction does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging debit records list + $sql = "SELECT * FROM acctrecs" + . " WHERE trx=$sn" + . " AND NOT credit" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"debtcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"debtcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"debt$_" . "sn"} = $$row{"sn"}; + $CURRENT{"debt$_" . "ord"} = $$row{"ord"}; + $CURRENT{"debt$_" . "subj"} = $$row{"subj"}; + $CURRENT{"debt$_" . "summary"} = $$row{"summary"}; + $CURRENT{"debt$_" . "amount"} = $$row{"amount"}; + } + + # Obtain the belonging credit records list + $sql = "SELECT * FROM acctrecs" + . " WHERE trx=$sn" + . " AND credit" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"crdtcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"crdtcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"crdt$_" . "sn"} = $$row{"sn"}; + $CURRENT{"crdt$_" . "ord"} = $$row{"ord"}; + $CURRENT{"crdt$_" . "subj"} = $$row{"subj"}; + $CURRENT{"crdt$_" . "summary"} = $$row{"summary"}; + $CURRENT{"crdt$_" . "amount"} = $$row{"amount"}; + } + + # Determine the subform type + if ( $CURRENT{"debtcount"} == 1 + && acctsubj_code($CURRENT{"debt0subj"}) eq ACCTSUBJ_CASH + && !defined $CURRENT{"debt0summary"}) { + $CURRENT{"formsub"} = "income"; + } elsif ( $CURRENT{"crdtcount"} == 1 + && acctsubj_code($CURRENT{"crdt0subj"}) eq ACCTSUBJ_CASH + && !defined $CURRENT{"crdt0summary"}) { + $CURRENT{"formsub"} = "expense"; + } else { + $CURRENT{"formsub"} = "trans"; + } + + # OK + return; +} + +# import_selsubj: Import the selected subject into the retrieved form +sub import_selsubj($) { + my $FORM; + $FORM = $_[0]; + # Sanity checks + return $FORM + if !defined $GET->param("selsn") + || !check_sn_in ${$GET->param_fetch("selsn")}[0], "acctsubj" + || !defined $FORM->param("caller_index"); + $FORM->param($FORM->param("caller_index") . "subj", $GET->param("selsn")); + return $FORM; +} diff --git a/htdocs/emandy/magicat/cgi-bin/actlog.cgi b/htdocs/emandy/magicat/cgi-bin/actlog.cgi new file mode 100755 index 0000000..9e01220 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/actlog.cgi @@ -0,0 +1,51 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# actlog.cgi: The activity log viewer. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); + +initenv(-restricted => 1, + -allowed => [qw(GET HEAD)], + -lastmod => 0, + -lmfiles => [$ACTLOG], + -page_param => {"keywords" => N_("activity, logs")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $LIST; + # List handler handles its own error + $LIST = new Selima::List::ActLog; + html_header $LIST->{"title"}; + html_errmsg retrieve_status; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/books.cgi b/htdocs/emandy/magicat/cgi-bin/books.cgi new file mode 100755 index 0000000..861ace9 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/books.cgi @@ -0,0 +1,226 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# books.cgi: The book administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "books", + -dbi_lock => {"books" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("books")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::emandy::Processor::Book($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please create a new book from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please create a new book from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + # Run the checker + $checker = new Selima::emandy::Checker::Book(curform); + $error = $checker->check(qw(title author year origin pub + review comment lib)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::emandy::Checker::Book(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(title author year origin pub + review comment lib)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::emandy::Checker::Book(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::emandy::Form::Book($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + if (list_type eq "toborrow") { + $LIST = new Selima::emandy::List::Books::ToBorrow; + } elsif (list_type eq "nottoborrow") { + $LIST = new Selima::emandy::List::Books::NotToBorrow; + } else { + $LIST = new Selima::emandy::List::Books; + } + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the book."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This book does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/groupmem.cgi b/htdocs/emandy/magicat/cgi-bin/groupmem.cgi new file mode 100755 index 0000000..c9042f7 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/groupmem.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# groupmem.cgi: The group-to-group membership administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); +sub import_selmember($); + +initenv(-restricted => 1, + -this_table => "groupmem", + -dbi_lock => {"groupmem" => LOCK_EX, + "groups" => LOCK_SH, + "groups AS grpmembers" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("group membership")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::GroupMem($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(del selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::GroupMem($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::GroupMem; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the membership record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This membership record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} + +# import_selmember: Import the selected member into the retrieved form +sub import_selmember($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("member", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups AS grpmembers"; + return $FORM; +} diff --git a/htdocs/emandy/magicat/cgi-bin/groups.cgi b/htdocs/emandy/magicat/cgi-bin/groups.cgi new file mode 100755 index 0000000..c5922f0 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/groups.cgi @@ -0,0 +1,357 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# groups.cgi: The account group administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selsubuser($); +sub import_selsubgroup($); +sub import_selsupgroup($); + +initenv(-restricted => 1, + -this_table => "groups", + -dbi_lock => {"groups" => LOCK_EX, + "usermem" => LOCK_EX, + "groupmem" => LOCK_EX, + "users" => LOCK_SH, + "users AS members" => LOCK_SH, + "groups AS members" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("groups")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Group($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my ($error, $FORM, $sn); + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth if !is_su && $sn == su_group_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error, $FORM, $sn); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(selsubuser selsubgroup selsupgroup)); + $error = $checker->check(qw(id dsc subuser subgroup supgroup)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(del selsubuser selsubgroup selsupgroup)); + $error = $checker->check(qw(id dsc subuser subgroup supgroup)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth if !is_su && $sn == su_group_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::Group($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Groups; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the group."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This group does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the user members list + $title = $DBH->strcat("users.id", "' ('", "users.name", "')'"); + $sql = "SELECT users.sn AS sn," + . " $title AS title" + . " FROM usermem" + . " INNER JOIN users ON usermem.member=users.sn" + . " WHERE usermem.grp=$sn" + . " ORDER BY users.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"subusercount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"subusercount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"subuser$_"} = 1; + $CURRENT{"subuser$_" . "sn"} = $$row{"sn"}; + $CURRENT{"subuser$_" . "title"} = $$row{"title"}; + } + + # Obtain the group members list + $sql = "SELECT groups.sn AS sn," + . " groups.dsc AS title FROM groupmem" + . " INNER JOIN groups ON groupmem.member=groups.sn" + . " WHERE groupmem.grp=$sn" + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"subgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"subgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"subgroup$_"} = 1; + $CURRENT{"subgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"subgroup$_" . "title"} = $$row{"title"}; + } + + # Obtain the belonging groups list + $sql = "SELECT groups.sn AS sn," + . " groups.dsc AS title FROM groupmem" + . " INNER JOIN groups ON groupmem.grp=groups.sn" + . " WHERE groupmem.member=$sn" + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"supgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"supgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"supgroup$_"} = 1; + $CURRENT{"supgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"supgroup$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} + +# import_selsubuser: Import the selected user into the retrieved form +sub import_selsubuser($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users AS members") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^subuser\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { userid $a cmp userid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^subuser\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^subuser\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("subuser$_" . "sn", $_[$_]); + $FORM->param("subuser$_", 1) if exists $_{$_[$_]}; + } + } + return; +} + +# import_selsubgroup: Import the selected user into the retrieved form +sub import_selsubgroup($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups AS members") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^subgroup\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { groupid $a cmp groupid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^subgroup\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^subgroup\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("subgroup$_" . "sn", $_[$_]); + $FORM->param("subgroup$_", 1) if exists $_{$_[$_]}; + } + } + return; +} + +# import_selsupgroup: Import the selected user into the retrieved form +sub import_selsupgroup($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^supgroup\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { groupid $a cmp groupid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^supgroup\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^supgroup\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("supgroup$_" . "sn", $_[$_]); + $FORM->param("supgroup$_", 1) if exists $_{$_[$_]}; + } + } + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/legend.cgi b/htdocs/emandy/magicat/cgi-bin/legend.cgi new file mode 100755 index 0000000..7128934 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/legend.cgi @@ -0,0 +1,218 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# legend.cgi: The blog article administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "legend", + -dbi_lock => {"legend" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("legend")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::emandy::Processor::Legend($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please write a new legend entry from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please write a new legend entry from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + # Run the checker + $checker = new Selima::emandy::Checker::Legend(curform); + $error = $checker->check(qw(title body)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::emandy::Checker::Legend(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(title body)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::emandy::Checker::Legend(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::emandy::Form::Legend($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::emandy::List::Legend; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the legend entry."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This legend entry does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/linkcat.cgi b/htdocs/emandy/magicat/cgi-bin/linkcat.cgi new file mode 100755 index 0000000..9d68523 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/linkcat.cgi @@ -0,0 +1,292 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# linkcat.cgi: The related-link category administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selparent($); + +initenv(-restricted => 1, + -this_table => "linkcat", + -dbi_lock => {"linkcat" => LOCK_EX, + "links" => LOCK_SH, + "linkcatz" => LOCK_SH}, + -lastmod => 0, + -page_param => {"keywords" => N_("link categories")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LinkCat($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + return {"msg"=>N_("This category has [numerate,_1,a subcategory,subcategories]. It cannot be deleted. To delete the category, [numerate,_1,its subcategory,all of its subcategories] must first be deleted."), + "margs"=>[$CURRENT{"scatcount"}], + "isform"=>0} + if $CURRENT{"scatcount"} > 0; + return {"msg"=>N_("This category has [numerate,_1,a link,links]. It cannot be deleted. To delete the category, [numerate,_1,its link,all of its links] must first be deleted."), + "margs"=>[$CURRENT{"linkcount"}], + "isform"=>0} + if $CURRENT{"linkcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(selparent delparent)); + $error = $checker->check(qw(parent id ord title kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(del selparent delparent)); + $error = $checker->check(qw(parent id ord title kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(cancel)); + return {"msg"=>N_("This category has [numerate,_1,a subcategory,subcategories]. It cannot be deleted. To delete the category, [numerate,_1,its subcategory,all of its subcategories] must first be deleted."), + "margs"=>[$CURRENT{"scatcount"}], + "isform"=>0} + if $CURRENT{"scatcount"} > 0; + return {"msg"=>N_("This category has [numerate,_1,a link,links]. It cannot be deleted. To delete the category, [numerate,_1,its link,all of its links] must first be deleted."), + "margs"=>[$CURRENT{"linkcount"}], + "isform"=>0} + if $CURRENT{"linkcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::LinkCat($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::LinkCat; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lang, $lndb, $lndbdef, $langfile, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the category."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This category does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $lang = getlang; + $lndb = getlang LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + $langfile = getlang LN_FILENAME; + + # Obtain the belonging subcategories list + @_ = qw(); + push @_, "sn AS sn"; + if (@ALL_LINGUAS > 1) { + $title = $lang eq $DEFAULT_LANG? "title_$lndb": + "COALESCE(title_$lndb, title_$lndbdef)"; + push @_, "linkcat_fulltitle('$lang', parent, $title) AS title"; + } else { + push @_, "linkcat_fulltitle(parent, title) AS title"; + } + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS url"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_ischild($sn, sn)" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"scatcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"scatcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"scat$_" . "sn"} = $$row{"sn"}; + $CURRENT{"scat$_" . "title"} = $$row{"title"}; + $CURRENT{"scat$_" . "url"} = $$row{"url"}; + } + + # Obtain the belonging links list + @_ = qw(); + push @_, "links.sn AS sn"; + push @_, "links.title AS title"; + push @_, "url AS url"; + $sql = "SELECT " . join(", ", @_) . " FROM links" + . " INNER JOIN linkcatz ON linkcatz.link=links.sn" + . " WHERE linkcatz.cat=$sn" + . " ORDER BY title;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"linkcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"linkcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"link$_" . "sn"} = $$row{"sn"}; + $CURRENT{"link$_" . "title"} = $$row{"title"}; + $CURRENT{"link$_" . "url"} = $$row{"url"}; + } + + # OK + return; +} + +# import_selparent: Import the selected parent into the retrieved form +sub import_selparent($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "linkcat") { + $FORM->param("parent", $GET->param("selsn")); + $FORM->param("topmost", "false"); + } + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/linkcatz.cgi b/htdocs/emandy/magicat/cgi-bin/linkcatz.cgi new file mode 100755 index 0000000..1ff3c37 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/linkcatz.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# linkcatz.cgi: The related-link category membership administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selcat($); +sub import_sellink($); + +initenv(-restricted => 1, + -this_table => "linkcatz", + -dbi_lock => {"linkcatz" => LOCK_EX, + "linkcat" => LOCK_SH, + "links" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("link categorization")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LinkCatz($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(selcat delcat sellink dellink)); + $error = $checker->check(qw(cat link)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(del selcat delcat sellink dellink)); + $error = $checker->check(qw(cat link)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::LinkCatz($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::LinkCatz; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the categorization record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This categorization record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selcat: Import the selected category into the retrieved form +sub import_selcat($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("cat", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "linkcat"; + return; +} + +# import_sellink: Import the selected link into the retrieved form +sub import_sellink($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("link", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "links"; + return $FORM; +} diff --git a/htdocs/emandy/magicat/cgi-bin/links.cgi b/htdocs/emandy/magicat/cgi-bin/links.cgi new file mode 100755 index 0000000..19090dd --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/links.cgi @@ -0,0 +1,240 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# links.cgi: The related-link administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "links", + -dbi_lock => {"links" => LOCK_EX, + "linkcatz" => LOCK_EX, + "linkcat" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("related links")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Link($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::Link(curform); + $error = $checker->check(qw(title title_2ln url icon + email addr tel fax dsc cats)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Link(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(title title_2ln url icon + email addr tel fax dsc cats)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::Link(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::Link($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Links; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lang, $lndb, $lndbdef, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the related link."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This related link does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $lang = getlang; + $lndb = getlang LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + + # Obtain the parent categories list + @_ = qw(); + push @_, "linkcat.sn AS sn"; + if (@ALL_LINGUAS > 1) { + $title = $lang eq $DEFAULT_LANG? "linkcat.title_$lndb": + "COALESCE(linkcat.title_$lndb, linkcat.title_$lndbdef)"; + push @_, "linkcat_fulltitle('$lang', linkcat.parent, $title) AS title"; + } else { + push @_, "linkcat_fulltitle(linkcat.parent, linkcat.title) AS title"; + } + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " INNER JOIN linkcatz ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.link=$sn" + . " ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord);\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"catcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"catcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"cat$_"} = $$row{"sn"}; + $CURRENT{"cat$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/logout.cgi b/htdocs/emandy/magicat/cgi-bin/logout.cgi new file mode 100755 index 0000000..48298ca --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/logout.cgi @@ -0,0 +1,158 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# logout.cgi: The log-out script. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub html_logoutform(); +sub html_relogin(); + +initenv(-dbi => DBI_NONE, + -lastmod => 1, + -page_param => {"keywords" => N_("log out")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LogOut($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $status; + # There is a result to display + $status = retrieve_status; + # Successfully logged out + if ( defined $status + && exists $$status{"status"} + && $$status{"status"} eq "success") { + # Nothing to check + return; + } + # Check if this user has logged in + unauth unless defined get_login_sn; + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + # Check if this user has logged in + unauth unless defined get_login_sn; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my $status; + $status = $_[0]; + # Not logged out yet + if (defined get_login_sn) { + html_header __("Log Out"); + html_errmsg $status; + html_logoutform; + html_footer; + + # Logged out + } else { + html_header __("Log Out"); + html_errmsg $status; + html_relogin; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# html_logoutform: Display a form to log out +sub html_logoutform() { + local ($_, %_); + my ($msg, $submit); + $msg = h(__("Are you sure you want to log out?")); + $submit = h(__("Log out")); + print << "EOT"; +
+
+

$msg

+ +
+
+ +EOT + return; +} + +# html_relogin: Display links to log in again +sub html_relogin() { + local ($_, %_); + $_ = h(__("Log in again.")); + print << "EOT"; +

$_

+ +EOT + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/material.cgi b/htdocs/emandy/magicat/cgi-bin/material.cgi new file mode 100755 index 0000000..b5cff19 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/material.cgi @@ -0,0 +1,221 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# material.cgi: The historical material administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-23 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "material", + -dbi_lock => {"material" => LOCK_EX, + "mtrltype" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("materials")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::emandy::Processor::Material($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please create a new material from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please create a new material from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + # Run the checker + $checker = new Selima::emandy::Checker::Material(curform); + $error = $checker->check(qw(type year title body source + author notes)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::emandy::Checker::Material(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(type year title body source + author notes)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::emandy::Checker::Material(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::emandy::Form::Material($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::emandy::List::Material; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the material."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This material does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/mtrltype.cgi b/htdocs/emandy/magicat/cgi-bin/mtrltype.cgi new file mode 100755 index 0000000..2a9716c --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/mtrltype.cgi @@ -0,0 +1,243 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# mtrltype.cgi: The historical material type administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-23 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "mtrltype", + -dbi_lock => {"mtrltype" => LOCK_EX, + "material" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("materials")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::emandy::Processor::MtrlType($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please create a new type from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + return {"msg"=>N_("This type has [numerate,_1,a material,materials]. It cannot be deleted. To delete the type, [numerate,_1,its material,all of its materials] must first be deleted."), + "margs"=>[$CURRENT{"mtrlcount"}], + "isform"=>0} + if $CURRENT{"mtrlcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please create a new type from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + # Run the checker + $checker = new Selima::emandy::Checker::MtrlType(curform); + $error = $checker->check(qw(ord title)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::emandy::Checker::MtrlType(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(ord title)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::emandy::Checker::MtrlType(curform); + $checker->redir(qw(cancel)); + return {"msg"=>N_("This type has [numerate,_1,a material,materials]. It cannot be deleted. To delete the type, [numerate,_1,its material,all of its materials] must first be deleted."), + "margs"=>[$CURRENT{"mtrlcount"}], + "isform"=>0} + if $CURRENT{"mtrlcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::emandy::Form::MtrlType($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::emandy::List::MtrlType; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the type."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This type does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging materials list + @_ = qw(); + push @_, "sn AS sn"; + push @_, "title AS title"; + $sql = "SELECT " . join(", ", @_) . " FROM material" + . " WHERE type=$sn" + . " ORDER BY title;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"mtrlcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"mtrlcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"mtrl$_" . "sn"} = $$row{"sn"}; + $CURRENT{"mtrl$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/pages.cgi b/htdocs/emandy/magicat/cgi-bin/pages.cgi new file mode 100755 index 0000000..e92be56 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/pages.cgi @@ -0,0 +1,221 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# pages.cgi: The web page administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "pages", + -dbi_lock => {"pages" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("pages")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Page($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to preview a submitted item + } elsif ($_ eq "preview") { + # Check at fetch_preview() + $error = fetch_preview; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::Page(curform); + $error = $checker->check(qw(path ord title body kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Page(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(path ord title body kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::Page(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + # A form to preview a submitted item + if (form_type eq "preview") { + html_preview; + + } else { + $FORM = new Selima::Form::Page($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + } + + # List the available items + } else { + $LIST = new Selima::List::Pages; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the page."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This page does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/rebuild.cgi b/htdocs/emandy/magicat/cgi-bin/rebuild.cgi new file mode 100755 index 0000000..d263657 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/rebuild.cgi @@ -0,0 +1,105 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# rebuild.cgi: The web page rebuilder. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); + +initenv(-restricted => 1, + -lastmod => 1, + -page_param => {"keywords" => N_("rebuild pages")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Rebuild($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + # Nothing to check here + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::Checker::Rebuild(curform); + $error = $checker->check(qw(type)); + return $error if defined $error; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $FORM); + $status = $_[0]; + $FORM = new Selima::Form::Rebuild($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/scptpriv.cgi b/htdocs/emandy/magicat/cgi-bin/scptpriv.cgi new file mode 100755 index 0000000..1310962 --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/scptpriv.cgi @@ -0,0 +1,223 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# scptpriv.cgi: The script privilege administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); + +initenv(-restricted => 1, + -this_table => "scptpriv", + -dbi_lock => {"scptpriv" => LOCK_EX, + "groups" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("script privilege")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::ScptPriv($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(selgrp delgrp)); + $error = $checker->check(qw(script grp)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(del selgrp delgrp)); + $error = $checker->check(qw(script grp)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::ScptPriv($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::ScptPriv; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the script privilege record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This script privilege record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/test.cgi b/htdocs/emandy/magicat/cgi-bin/test.cgi new file mode 100755 index 0000000..42ffedc --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/test.cgi @@ -0,0 +1,40 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# test.cgi: The test script. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use utf8; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $r = shift; +my $d = new Selima::Destroy; +# Prototype declaration +use Time::HiRes qw(); +initenv; +$CONTENT_TYPE = "text/plain"; + + +printf "[%s] Done. %0.10f seconds elapsed.\n", + fmttime, Time::HiRes::time-$T_START; +exit 0; +no utf8; diff --git a/htdocs/emandy/magicat/cgi-bin/usermem.cgi b/htdocs/emandy/magicat/cgi-bin/usermem.cgi new file mode 100755 index 0000000..0d4be7d --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/usermem.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# usermem.cgi: The user-to-group membership administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); +sub import_selmember($); + +initenv(-restricted => 1, + -this_table => "usermem", + -dbi_lock => {"usermem" => LOCK_EX, + "groups" => LOCK_SH, + "users AS usrmembers" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("user membership")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::UserMem($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(del selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::UserMem($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::UserMem; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the membership record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This membership record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} + +# import_selmember: Import the selected user into the retrieved form +sub import_selmember($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("member", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users AS usrmembers"; + return $FORM; +} diff --git a/htdocs/emandy/magicat/cgi-bin/userpref.cgi b/htdocs/emandy/magicat/cgi-bin/userpref.cgi new file mode 100755 index 0000000..6d6567c --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/userpref.cgi @@ -0,0 +1,225 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# userpref.cgi: The user preference administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selusr($); + +initenv(-restricted => 1, + -this_table => "userpref", + -dbi_lock => {"userpref" => LOCK_EX, + "users" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("user preference")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::UserPref($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(selusr delusr)); + $error = $checker->check(qw(usr domain name value)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(del selusr delusr)); + $error = $checker->check(qw(usr domain name value)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::UserPref($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::UserPref; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the user preference."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This user preference does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selusr: Import the selected user into the retrieved form +sub import_selusr($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users") { + $FORM->param("usr", $GET->param("selsn")); + $FORM->param("everyone", "false"); + } + return; +} diff --git a/htdocs/emandy/magicat/cgi-bin/users.cgi b/htdocs/emandy/magicat/cgi-bin/users.cgi new file mode 100755 index 0000000..b83570d --- /dev/null +++ b/htdocs/emandy/magicat/cgi-bin/users.cgi @@ -0,0 +1,273 @@ +#! /usr/bin/perl -w +# Mandy Wu's Website +# users.cgi: The user account administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emandy; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-this_table => "users", + -dbi_lock => {"users" => LOCK_EX, + "usermem" => LOCK_EX, + "userpref" => LOCK_EX, + "groupmem" => LOCK_SH, + "groups" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("users")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + # Password not saved + $POST->delete("passwd", "passwd2"); + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::User($POST); + $success = $processor->process; + # Password not saved + $POST->delete("passwd", "passwd2"); + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my ($error, $FORM, $sn); + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Check the privilege to manage this table + unauth if !is_script_permitted; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted || $sn == get_login_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted; + unauth if !is_su && (is_su $sn || $sn == get_login_sn); + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + + # List the available items + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + # List handler handles its own error + } + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error, $FORM, $sn); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Check the privilege to manage this table + unauth unless is_script_permitted; + # Run the checker + $checker = new Selima::Checker::User(curform); + $error = $checker->check(qw(id passwd name supgroup)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted || $sn == get_login_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::User(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(id passwd name supgroup)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted; + unauth if !is_su && (is_su $sn || $sn == get_login_sn); + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::User(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::User($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Users; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the user."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This user does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging groups list + $sql = "SELECT groups.sn AS sn," + . " groups.dsc AS title FROM usermem" + . " INNER JOIN groups ON usermem.grp=groups.sn" + . " WHERE usermem.member=$sn" + . " AND groups.id!=" . $DBH->quote(SU_GROUP) + . " AND groups.id!=" . $DBH->quote(ADMIN_GROUP) + . " AND groups.id!=" . $DBH->quote(ALLUSERS_GROUP) + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"supgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"supgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"supgroup$_"} = 1; + $CURRENT{"supgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"supgroup$_" . "title"} = $$row{"title"}; + } + + # Get the admin flag + $CURRENT{"admin"} = is_admin($sn); + $CURRENT{"su"} = is_su($sn); + + # OK + return; +} diff --git a/htdocs/emandy/magicat/cv.html b/htdocs/emandy/magicat/cv.html new file mode 100644 index 0000000..0351ac9 --- /dev/null +++ b/htdocs/emandy/magicat/cv.html @@ -0,0 +1,72 @@ + + + + + + + + + + + +i + + + +

i

+

ӤH򥻸

+
    +
  • mW: dP
  • +
  • ye: OWٶL
  • +
  • ͤ: 1970.2.9
  • +
  • {~a}:éMs͸401213
  • +
  • Tel:(02)3233-7444]H^
  • +
  • Cell:0953360398
  • +
  • ä[a}:sL135
  • +
  • Tel:(07)7018867
  • +
+

Ш|{

+
    +
  • sꤤA1985~6벦
  • +
  • ٥ߩsA1988~6벦
  • +
  • ƤjǥvǨtA1993~6벦
  • +
  • jǾvtӤhZA1998~6벦
  • +
+

u@g

+
    +
  • ʭ^Tq~ȧUz]1994~^
  • +
  • |Ƭs߱M]1996-1997~^
  • +
  • O_ߤhLӥNұЮv]1997~^
  • +
  • ƱMǮխݥv]1998-1999~^
  • +
  • ߪŤjǭv]1998-^
  • +
  • اXqUs]1998~^
  • +
  • xWjǰksǧUzs]1998-1999~^
  • +
  • äkʤJfhercafeukܡvM@a
  • +
  • MؤjǾvsҳŤjб°|peiNxWHں--PGغcι20@xWu{NʡvϬ١jsUz]1999~10-2000~9멳^
  • +
  • |ǥvqTs
  • +
+ +

ZB

+ +

M

+
    +
  • rZ
  • +
  • qѸƳBz
  • +
  • w쬡
  • +
+ + \ No newline at end of file diff --git a/htdocs/emandy/magicat/include/footer.html b/htdocs/emandy/magicat/include/footer.html new file mode 100644 index 0000000..946762b --- /dev/null +++ b/htdocs/emandy/magicat/include/footer.html @@ -0,0 +1,31 @@ +
+ diff --git a/htdocs/emandy/magicat/include/header.html b/htdocs/emandy/magicat/include/header.html new file mode 100644 index 0000000..44a5955 --- /dev/null +++ b/htdocs/emandy/magicat/include/header.html @@ -0,0 +1,12 @@ +
+ +
diff --git a/htdocs/emandy/magicat/index.html.html b/htdocs/emandy/magicat/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/emandy/magicat/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/emandy/magicat/index.html.xhtml b/htdocs/emandy/magicat/index.html.xhtml new file mode 100644 index 0000000..0b2c454 --- /dev/null +++ b/htdocs/emandy/magicat/index.html.xhtml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + +梅姬妳好 *^_^* + + + + + + + +
+ +
+ + +

我是梅姬,請多多指教 *^_^*

+ +
+

妳好,我是梅姬,是小招網站的守護精靈。妳要怎麼設定網站,請儘管吩咐我喔~!

+
+ +

管理網站

+ + + +

管理帳號

+ + + +

台灣的士青代管帳

+ + + +

其她

+ + + +
+ + +
+ + + + diff --git a/htdocs/emandy/magicat/lib/acctsubj.sql b/htdocs/emandy/magicat/lib/acctsubj.sql new file mode 120000 index 0000000..1602791 --- /dev/null +++ b/htdocs/emandy/magicat/lib/acctsubj.sql @@ -0,0 +1 @@ +../../../wov/magicat/lib/acctsubj.sql \ No newline at end of file diff --git a/htdocs/emandy/magicat/lib/emandy.sql b/htdocs/emandy/magicat/lib/emandy.sql new file mode 100644 index 0000000..a377d73 --- /dev/null +++ b/htdocs/emandy/magicat/lib/emandy.sql @@ -0,0 +1,1404 @@ +-- 檔案名稱: emandy.sql +-- 程式說明: 小招的網站資料庫定義檔 +-- 程式作者: 依瑪貓 imacat +-- 初稿日期: 2006-11-14 +-- 版權字樣: 版權所有 (c) 2006-2014 依瑪貓 +-- Set PGCLIENTENCODING=utf8 before restoring it + +SET NAMES 'utf8'; + +START TRANSACTION; + + +-- +-- Table structure for table "mtime" +-- + +CREATE TABLE mtime ( + tabname varchar(16) NOT NULL PRIMARY KEY, + mtime timestamp NOT NULL DEFAULT now() +); +GRANT SELECT, INSERT, UPDATE, DELETE ON mtime TO nobody; + + +-- +-- Table structure for table "country" +-- + +CREATE TABLE country ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id char(2) NOT NULL UNIQUE CHECK (position(' ' in id) = 0), + name_en varchar(64) NOT NULL CHECK (name_en != ''), + name_zhtw varchar(32) CHECK (name_zhtw IS NULL OR name_zhtw != ''), + special boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL +); +GRANT SELECT, INSERT, UPDATE, DELETE ON country TO nobody; + + +-- +-- Table structure for table "users" +-- + +CREATE TABLE users ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(32) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + passwd char(32) NOT NULL, + name varchar(32) NOT NULL CHECK (name != ''), + disabled boolean NOT NULL DEFAULT FALSE, + deleted boolean NOT NULL DEFAULT FALSE, + lang varchar(5) CHECK (lang IS NULL OR lang != ''), + visits smallint NOT NULL DEFAULT 0 CHECK (visits >= 0), + visited timestamp, + ip inet, + host varchar(128), + ct char(2) REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON users TO nobody; + +CREATE VIEW users_list AS + SELECT + users.sn AS sn, + users.id AS id, + users.name AS name, + CASE WHEN users.disabled THEN '停用' + ELSE '' + END AS disabled, + CASE WHEN users.deleted THEN '已刪' + ELSE '' + END AS deleted, + CASE WHEN users.lang IS NULL THEN '(無)' + ELSE CASE users.lang + WHEN 'en' THEN '英文' + WHEN 'zh-tw' THEN '繁體中文' + WHEN 'zh-cn' THEN '簡體中文' + WHEN 'ja' THEN '日文' + WHEN 'de' THEN '德文' + WHEN 'es' THEN '西班牙文' + ELSE users.lang + END + END AS lang, + users.visits AS visits, + CASE WHEN users.visited IS NULL THEN '(無)' + ELSE to_char(users.visited, 'YYYY-MM-DD HH:MI:SS') + END AS visited, + CASE WHEN users.ip IS NULL THEN '(無)' + ELSE host(users.ip) + END AS ip, + CASE WHEN users.host IS NULL THEN '(無)' + ELSE users.host + END AS host, + CASE WHEN users.ct IS NULL THEN '(無)' + ELSE ct.name_zhtw + END AS ct, + to_char(users.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(users.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM users + LEFT JOIN country AS ct ON users.ct = ct.id + LEFT JOIN users AS createdby ON users.createdby = createdby.sn + LEFT JOIN users AS updatedby ON users.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON users_list TO nobody; + +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (923153018, 'imacat', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '依瑪貓', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (460376330, 'mandy', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '小招', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); + +-- +-- Fixing the country table +-- + +ALTER TABLE country ADD FOREIGN KEY (createdby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +ALTER TABLE country ADD FOREIGN KEY (updatedby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +CREATE VIEW country_list AS + SELECT + country.sn AS sn, + country.id AS id, + COALESCE(country.name_zhtw, country.name_en) AS title, + CASE WHEN country.special THEN '特殊' + ELSE '' + END AS special, + to_char(country.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(country.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM country + LEFT JOIN users AS createdby ON country.createdby = createdby.sn + LEFT JOIN users AS updatedby ON country.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON country_list TO nobody; + + +-- +-- Table structure for table "groups" +-- + +CREATE TABLE groups ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(16) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + dsc varchar(64) NOT NULL CHECK (dsc != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groups TO nobody; + +CREATE VIEW groups_list AS + SELECT + groups.sn AS sn, + groups.id AS id, + groups.dsc AS dsc, + to_char(groups.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groups.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groups + LEFT JOIN users AS createdby ON groups.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groups.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON groups_list TO nobody; + +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (553229108, 'root', '總管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (802339805, 'guests', '暱名訪客', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (958210993, 'users', '已登入使用者', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (329685674, 'admin', '所有網站管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (157696540, 'acctman', '帳號管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (390105230, 'editor', '網站編輯', now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "usermem" +-- + +CREATE TABLE usermem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON usermem TO nobody; + +CREATE VIEW usermem_list AS + SELECT + usermem.sn AS sn, + groups.id || ' (' || groups.dsc || ')' AS grp, + members.id || ' (' || members.name || ')' AS member, + to_char(usermem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(usermem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM usermem + LEFT JOIN groups ON usermem.grp = groups.sn + LEFT JOIN users AS members ON usermem.member = members.sn + LEFT JOIN users AS createdby ON usermem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON usermem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON usermem_list TO nobody; + +-- INSERT INTO usermem (sn, grp, member, created, createdby, updated, updatedby) VALUES (593684712, 553229108, 923153018, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "groupmem" +-- + +CREATE TABLE groupmem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE CHECK (member != grp), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groupmem TO nobody; + +CREATE VIEW groupmem_list AS + SELECT + groupmem.sn AS sn, + groups.id || ' (' || groups.dsc || ')' AS grp, + members.id || ' (' || members.dsc || ')' AS member, + to_char(groupmem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groupmem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groupmem + LEFT JOIN groups ON groupmem.grp = groups.sn + LEFT JOIN groups AS members ON groupmem.member = members.sn + LEFT JOIN users AS createdby ON groupmem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groupmem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON groupmem_list TO nobody; + +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (569742102, 329685674, 157696540, now(), 923153018, now(), 923153018); +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (859385977, 329685674, 390105230, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "scptpriv" +-- + +CREATE TABLE scptpriv ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + script varchar(64) NOT NULL CHECK (script != ''), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (script, grp) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON scptpriv TO nobody; + +CREATE VIEW scptpriv_list AS + SELECT + scptpriv.sn AS sn, + scptpriv.script AS script, + groups.dsc AS grp, + to_char(scptpriv.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(scptpriv.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM scptpriv + LEFT JOIN groups ON scptpriv.grp = groups.sn + LEFT JOIN users AS createdby ON scptpriv.createdby = createdby.sn + LEFT JOIN users AS updatedby ON scptpriv.updatedby = updatedby.sn + ORDER BY script, grp; +GRANT SELECT ON scptpriv_list TO nobody; + + +-- +-- Table structure for table "userpref" +-- + +CREATE TABLE userpref ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + usr int REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + domain varchar(64) CHECK (domain IS NULL OR domain != ''), + name varchar(16) NOT NULL CHECK (name != ''), + value varchar(255) NOT NULL, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (usr, domain, name) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON userpref TO nobody; + +CREATE VIEW userpref_list AS + SELECT + userpref.sn AS sn, + CASE WHEN userpref.usr IS NOT NULL THEN users.name + ELSE '所有人' + END AS usr, + CASE WHEN userpref.domain IS NOT NULL THEN userpref.domain + ELSE '所有地方' + END AS domain, + userpref.name AS name, + userpref.value AS value, + to_char(userpref.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(userpref.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM userpref LEFT JOIN users ON userpref.usr = users.sn + LEFT JOIN users AS createdby ON userpref.createdby = createdby.sn + LEFT JOIN users AS updatedby ON userpref.updatedby = updatedby.sn + ORDER BY domain, usr, name; +GRANT SELECT ON userpref_list TO nobody; + + +-- +-- Table structure for table "pages" +-- + +CREATE TABLE pages ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + path varchar(64) NOT NULL UNIQUE CHECK (path != ''), + ord smallint NOT NULL DEFAULT 5000 CHECK (ord >= 0 AND ord < 10000), + title varchar(128) NOT NULL CHECK (title != ''), + body text NOT NULL CHECK (body != ''), + kw varchar(128) NOT NULL CHECK (kw != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pages TO nobody; + +CREATE VIEW pages_list AS + SELECT + pages.path AS _viewurl, + pages.sn AS sn, + pages.path AS path, + pages.ord AS ord, + pages.title AS title, + pages.body AS body, + pages.kw AS kw, + CASE WHEN pages.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN pages.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(pages.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pages.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pages + LEFT JOIN users AS createdby ON pages.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pages.updatedby = updatedby.sn + ORDER BY path; +GRANT SELECT ON pages_list TO nobody; + + +-- +-- Function definitions for table "links" +-- + +-- boolean linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer); +CREATE FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) RETURNS boolean AS ' + BEGIN + IF parent_arg IS NULL THEN + PERFORM * FROM linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent IS NULL; + RETURN NOT FOUND; + ELSE + PERFORM * FROM linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent=parent_arg; + RETURN NOT FOUND; + END IF; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) TO nobody; + +-- numeric linkcat_fullord(parent_arg integer, ord_arg integer); +CREATE FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) RETURNS numeric AS ' + DECLARE + row record; + sn_loop integer; + ord_loop numeric; + BEGIN + sn_loop := parent_arg; + ord_loop := ord_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, ord FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN NULL; + END IF; + sn_loop := row.parent; + ord_loop := row.ord + ord_loop / 100; + END LOOP; + RETURN ord_loop; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) TO nobody; +-- numeric linkcat_fullord(sn_arg integer); +CREATE FUNCTION linkcat_fullord(sn_arg integer) RETURNS numeric AS ' + BEGIN + RETURN linkcat_fullord(sn_arg, 0); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(sn_arg integer) TO nobody; + +-- boolean linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + -- Check if we have childs + PERFORM links.sn FROM links + INNER JOIN linkcatz ON linkcatz.link=links.sn + WHERE NOT links.hid AND linkcatz.cat=sn_arg; + IF FOUND THEN + RETURN TRUE; + END IF; + -- Check if we have shown child categories + PERFORM sn FROM linkcat WHERE parent=sn_arg AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + RETURN TRUE; + END IF; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; +-- boolean linkcat_isshown(sn_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer) RETURNS boolean AS ' + DECLARE + row record; + BEGIN + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_isshown(sn_arg, row.hid, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer) TO nobody; +-- boolean linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + RETURN TRUE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; + +-- text linkcat_path(sn_arg integer, id_arg text, parent_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + path text; + BEGIN + PERFORM sn FROM linkcat + WHERE parent=sn_arg + AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + path := ''/'' || id_arg || ''/''; + ELSE + path := ''/'' || id_arg || ''.html''; + END IF; + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_loop; + path := ''/'' || row.id || path; + sn_loop := row.parent; + END LOOP; + RETURN path; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) TO nobody; +-- text linkcat_path(sn_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_path(sn_arg, row.id, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer) TO nobody; + +-- boolean linkcat_ischild(parent_arg integer, child_arg integer); +CREATE FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + sn_loop := child_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN FALSE; + END IF; + IF row.parent = parent_arg THEN + RETURN TRUE; + END IF; + sn_loop := row.parent; + END LOOP; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) TO nobody; + +-- text linkcat_fulltitle(sn_arg integer); +CREATE FUNCTION linkcat_fulltitle(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + title_full text; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + title_full := row.title; + WHILE row.parent IS NOT NULL LOOP + sn_loop := row.parent; + SELECT INTO row * FROM linkcat WHERE sn=sn_loop; + title_full := row.title || '' / '' || title_full; + END LOOP; + RETURN title_full; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(sn_arg integer) TO nobody; +-- text linkcat_fulltitle(parent_arg integer, title_arg text); +CREATE FUNCTION linkcat_fulltitle(parent_arg integer, title_arg text) RETURNS text AS ' + BEGIN + IF parent_arg IS NULL THEN + RETURN title_arg; + END IF; + RETURN linkcat_fulltitle(parent_arg) || '' / '' || title_arg; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(parent_arg integer, title_arg text) TO nobody; + + +-- +-- Table structure for table "linkcat" +-- + +CREATE TABLE linkcat ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + parent int REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE CHECK (parent IS NULL OR (parent != sn AND NOT linkcat_ischild(sn, parent))), + id varchar(8) NOT NULL CHECK (char_length(id) >= 2 AND linkcat_id_unique(id, sn, parent)), + ord smallint NOT NULL DEFAULT 50 CHECK (ord >= 0 AND ord < 100), + title varchar(128) NOT NULL CHECK (title != ''), + kw varchar(128) NOT NULL CHECK (kw != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcat TO nobody; + +CREATE VIEW linkcat_list AS + SELECT + '/links' || linkcat_path(linkcat.sn, linkcat.id, linkcat.parent) AS _viewurl, + linkcat.sn AS sn, + linkcat.id AS id, + linkcat.ord AS ord, + linkcat_fulltitle(linkcat.parent, linkcat.title) AS title, + linkcat.kw AS kw, + CASE WHEN linkcat.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(linkcat.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcat.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcat + LEFT JOIN users AS createdby ON linkcat.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcat.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), id; +GRANT SELECT ON linkcat_list TO nobody; + + +-- +-- Table structure for table "links" +-- + +CREATE TABLE links ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + title varchar(96) NOT NULL CHECK (title != ''), + title_2ln varchar(96) CHECK (title_2ln IS NULL OR title_2ln != ''), + url varchar(128) NOT NULL UNIQUE CHECK (url != '' AND url != 'http://'), + email varchar(64) CHECK (email IS NULL OR email != ''), + icon varchar(128) CHECK (icon IS NULL OR (icon != '' AND icon != 'http://')), + addr varchar(128) CHECK (addr IS NULL OR addr != ''), + tel varchar(48) CHECK (tel IS NULL OR tel != ''), + fax varchar(32) CHECK (fax IS NULL OR fax != ''), + dsc varchar(256) NOT NULL CHECK (dsc != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON links TO nobody; + +CREATE VIEW links_list AS + SELECT + links.url AS _viewurl, + links.sn AS sn, + links.title AS title, + links.title_2ln AS title_2ln, + links.url AS url, + links.url AS _urlcheck, + links.icon AS _imgsrc, + links.email AS email, + links.addr AS addr, + links.tel AS tel, + links.fax AS fax, + links.dsc AS dsc, + CASE WHEN links.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(links.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(links.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM links + LEFT JOIN users AS createdby ON links.createdby = createdby.sn + LEFT JOIN users AS updatedby ON links.updatedby = updatedby.sn + ORDER BY links.title; +GRANT SELECT ON links_list TO nobody; + + +-- +-- Table structure for table "linkcatz" +-- + +CREATE TABLE linkcatz ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + cat int NOT NULL REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE, + link int NOT NULL REFERENCES links ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (cat, link) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcatz TO nobody; + +CREATE VIEW linkcatz_list AS + SELECT + linkcatz.sn AS sn, + linkcat_fulltitle(linkcat.parent, linkcat.title) AS cat, + links.title AS link, + to_char(linkcatz.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcatz.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcatz + LEFT JOIN linkcat ON linkcatz.cat = linkcat.sn + LEFT JOIN links ON linkcatz.link = links.sn + LEFT JOIN users AS createdby ON linkcatz.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcatz.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), linkcat.id, link; +GRANT SELECT ON linkcatz_list TO nobody; + + +-- +-- Function definitions for table "legend" +-- + +-- timestamp legend_page_start(pageno_arg integer) +CREATE FUNCTION legend_page_start(pageno_arg integer) RETURNS timestamp AS ' + DECLARE + row record; + BEGIN + SELECT INTO row created FROM legend + WHERE NOT hid AND pageno=pageno_arg + ORDER BY created LIMIT 1; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.created; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION legend_page_start(pageno_arg integer) TO nobody; +-- timestamp legend_page_end(pageno_arg integer) +CREATE FUNCTION legend_page_end(pageno_arg integer) RETURNS timestamp AS ' + DECLARE + row record; + BEGIN + SELECT INTO row created FROM legend + WHERE NOT hid AND pageno=pageno_arg + ORDER BY created DESC LIMIT 1; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.created; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION legend_page_end(pageno_arg integer) TO nobody; + + +-- +-- Table structure for table "legend" +-- + +CREATE TABLE legend ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + title varchar(128) NOT NULL CHECK (title != ''), + body text NOT NULL CHECK (body != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + pageno int NOT NULL, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON legend TO nobody; + +CREATE VIEW legend_list AS + SELECT + '/legend/' || lpad(cast(legend.pageno AS text), 4, '0') || '.html' + || '#ent' || legend.sn + AS _viewurl, + legend.sn AS sn, + to_char(legend.created, 'YYYY-MM-DD') AS date, + legend.title AS title, + legend.body AS body, + CASE WHEN legend.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN legend.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + legend.pageno AS pageno, + to_char(legend.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(legend.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM legend + LEFT JOIN users AS createdby ON legend.createdby = createdby.sn + LEFT JOIN users AS updatedby ON legend.updatedby = updatedby.sn + ORDER BY legend.created DESC; +GRANT SELECT ON legend_list TO nobody; + +CREATE VIEW legend_public AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + title AS title, + body AS body, + html AS html, + pageno AS pageno + FROM legend + WHERE NOT hid + ORDER BY created DESC; +GRANT SELECT ON legend_public TO nobody; + + +-- +-- Table structure for table "books" +-- + +CREATE TABLE books ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + title varchar(128) NOT NULL CHECK (title != ''), + author varchar(64) CHECK (author IS NULL OR author != ''), + year smallint CHECK (year IS NULL OR year != 0), + origin varchar(64) CHECK (origin IS NULL OR origin != ''), + pub varchar(64) CHECK (pub IS NULL OR pub != ''), + toborrow boolean NOT NULL DEFAULT FALSE, + review text CHECK (review IS NULL OR review != ''), + comment text CHECK (comment IS NULL OR comment != ''), + lib text CHECK (lib IS NULL OR lib != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON books TO nobody; + +CREATE VIEW books_list AS + SELECT + books.sn AS sn, + books.title AS title, + books.author AS author, + books.year AS year, + books.origin AS origin, + books.pub AS pub, + CASE WHEN books.toborrow THEN '待借' + ELSE '' + END AS toborrow, + books.review AS review, + books.comment AS comment, + books.lib AS lib, + to_char(books.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(books.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM books + LEFT JOIN users AS createdby ON books.createdby = createdby.sn + LEFT JOIN users AS updatedby ON books.updatedby = updatedby.sn + ORDER BY books.title, books.year DESC, books.author; +GRANT SELECT ON books_list TO nobody; + +CREATE VIEW books_nottoborrow_list AS + SELECT + books.sn AS sn, + books.title AS title, + books.author AS author, + books.year AS year, + books.origin AS origin, + books.pub AS pub, + books.review AS review, + books.comment AS comment, + books.lib AS lib, + to_char(books.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(books.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM books + LEFT JOIN users AS createdby ON books.createdby = createdby.sn + LEFT JOIN users AS updatedby ON books.updatedby = updatedby.sn + WHERE NOT toborrow + ORDER BY books.title, books.year DESC, books.author; +GRANT SELECT ON books_nottoborrow_list TO nobody; + +CREATE VIEW books_toborrow_list AS + SELECT + books.sn AS sn, + books.title AS title, + books.author AS author, + books.year AS year, + books.origin AS origin, + books.pub AS pub, + books.review AS review, + books.comment AS comment, + books.lib AS lib, + to_char(books.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(books.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM books + LEFT JOIN users AS createdby ON books.createdby = createdby.sn + LEFT JOIN users AS updatedby ON books.updatedby = updatedby.sn + WHERE toborrow + ORDER BY books.title, books.year DESC, books.author; +GRANT SELECT ON books_toborrow_list TO nobody; + + +-- +-- Table structure for table "mtrltype" +-- + +CREATE TABLE mtrltype ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + title varchar(128) NOT NULL CHECK (title != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON mtrltype TO nobody; + +CREATE VIEW mtrltype_list AS + SELECT + mtrltype.sn AS sn, + mtrltype.ord AS ord, + mtrltype.title AS title, + to_char(mtrltype.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(mtrltype.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM mtrltype + LEFT JOIN users AS createdby ON mtrltype.createdby = createdby.sn + LEFT JOIN users AS updatedby ON mtrltype.updatedby = updatedby.sn + ORDER BY mtrltype.ord, mtrltype.title; +GRANT SELECT ON mtrltype_list TO nobody; + + +-- +-- Table structure for table "material" +-- + +CREATE TABLE material ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + type int REFERENCES mtrltype ON UPDATE CASCADE DEFERRABLE, + year smallint CHECK (year IS NULL OR year != 0), + title varchar(128) NOT NULL CHECK (title != ''), + body text NOT NULL CHECK (body != ''), + source varchar(128) NOT NULL CHECK (source != ''), + author varchar(64) CHECK (author IS NULL OR author != ''), + notes text CHECK (notes IS NULL OR notes != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON material TO nobody; + +CREATE VIEW material_list AS + SELECT + material.sn AS sn, + mtrltype.title AS type, + material.year AS year, + material.title AS title, + material.body AS body, + material.source AS source, + material.author AS author, + material.notes AS notes, + to_char(material.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(material.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM material + LEFT JOIN mtrltype ON material.type = mtrltype.sn + LEFT JOIN users AS createdby ON material.createdby = createdby.sn + LEFT JOIN users AS updatedby ON material.updatedby = updatedby.sn + ORDER BY material.title; +GRANT SELECT ON material_list TO nobody; + + +-- +-- VIEW: Search +-- +CREATE VIEW search_list AS + (SELECT + 'pages' AS section, + pages.path AS path, + pages.title AS title, + null AS author, + to_char(pages.updated, 'YYYY-MM-DD') AS date, + pages.body AS body, + pages.kw AS kw, + pages.html AS html + FROM pages + WHERE NOT pages.hid + AND pages.path NOT LIKE '/errors/%') + UNION + (SELECT + 'links' AS section, + links.url AS path, + links.title AS title, + null AS author, + to_char(links.updated, 'YYYY-MM-DD') AS date, + links.dsc AS body, + CASE WHEN links.title_2ln IS NULL THEN '' ELSE links.title_2ln END + || ' +' || CASE WHEN links.url IS NULL THEN '' ELSE links.url END + || ' +' || CASE WHEN links.email IS NULL THEN '' ELSE links.email END + || ' +' || CASE WHEN links.addr IS NULL THEN '' ELSE links.addr END + || ' +' || CASE WHEN links.tel IS NULL THEN '' ELSE links.tel END + || ' +' || CASE WHEN links.fax IS NULL THEN '' ELSE links.fax END + AS kw, + FALSE AS html + FROM links + WHERE NOT links.hid) + UNION + (SELECT + 'legend' AS section, + '/legend/' || lpad(cast(legend.pageno AS text), 4, '0') || '.html' + || '#ent' || legend.sn + AS path, + legend.title AS title, + null AS author, + to_char(legend.updated, 'YYYY-MM-DD') AS date, + legend.body AS body, + null AS kw, + legend.html AS html + FROM legend + WHERE NOT legend.hid) + ORDER BY date DESC, title; +GRANT SELECT ON search_list TO nobody; + + +-- +-- Function definitions for table "accttrx" +-- + +-- boolean acctsubj_ischild(parent_arg integer, sn_arg integer, code_arg text); +CREATE FUNCTION acctsubj_ischild(parent_arg integer, sn_arg integer, code_arg text) RETURNS boolean AS ' + DECLARE + row record; + BEGIN + -- First level subjects have no parent + IF char_length(code_arg) = 1 THEN + IF parent_arg IS NULL THEN + RETURN TRUE; + ELSE + RETURN FALSE; + END IF; + END IF; + -- Second level subjects and below must have a parent + IF parent_arg IS NULL THEN + RETURN FALSE; + END IF; + -- A subject must not belong to itself + IF parent_arg IS NOT DISTINCT FROM sn_arg THEN + RETURN FALSE; + END IF; + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + SELECT INTO row code FROM public.acctsubj WHERE sn=parent_arg; + -- parent is guarenteed by FOREIGN KEY constraint, so we do not check it. + -- This helps when importing data from the dump files since we cannot help + -- the data order in the dump files. + IF NOT FOUND THEN + RETURN TRUE; + END IF; + -- The code of the parent must match the preceding part of our code + IF row.code = substring(code_arg FROM 1 FOR char_length(code_arg) - 1) THEN + RETURN TRUE; + END IF; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_ischild(parent_arg integer, sn_arg integer, code_arg text) TO nobody; + +-- text acctsubj_fulltitle(sn_arg integer); +CREATE FUNCTION acctsubj_fulltitle(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + title_full text; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM acctsubj WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + title_full := row.title; + WHILE row.parent IS NOT NULL LOOP + sn_loop := row.parent; + SELECT INTO row * FROM acctsubj WHERE sn=sn_loop; + title_full := row.title || '' / '' || title_full; + END LOOP; + RETURN title_full; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_fulltitle(sn_arg integer) TO nobody; +-- text acctsubj_fulltitle(parent_arg integer, title_arg text); +CREATE FUNCTION acctsubj_fulltitle(parent_arg integer, title_arg text) RETURNS text AS ' + BEGIN + IF parent_arg IS NULL THEN + RETURN title_arg; + END IF; + RETURN acctsubj_fulltitle(parent_arg) || '' / '' || title_arg; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_fulltitle(parent_arg integer, title_arg text) TO nobody; +-- text acctsubj_codetitle(sn_arg integer); +CREATE FUNCTION acctsubj_codetitle(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM acctsubj WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.code || '' '' || row.title; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_codetitle(sn_arg integer) TO nobody; + +-- timestamp acctsubj_recent(subj_arg integer); +CREATE FUNCTION acctsubj_recent(subj_arg integer) RETURNS timestamp AS ' + DECLARE + row record; + BEGIN + IF subj_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row updated FROM acctrecs WHERE subj=subj_arg + ORDER BY updated DESC LIMIT 1; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.updated; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_recent(subj_arg integer) TO nobody; + +-- boolean acctsubj_islastlv(sn_arg integer); +CREATE FUNCTION acctsubj_islastlv(sn_arg integer) RETURNS boolean AS ' + BEGIN + PERFORM sn FROM acctsubj WHERE parent=sn_arg LIMIT 1; + RETURN NOT FOUND; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_islastlv(sn_arg integer) TO nobody; + +-- boolean accttrx_has_subj(sn_arg integer, code_arg text); +CREATE FUNCTION accttrx_has_subj(sn_arg integer, code_arg text) RETURNS boolean AS ' + BEGIN + PERFORM acctrecs.sn FROM acctrecs + LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn + WHERE acctrecs.trx=sn_arg + AND acctsubj.code LIKE code_arg || ''%'' + LIMIT 1; + RETURN FOUND; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION accttrx_has_subj(sn_arg integer, code_arg text) TO nobody; + +-- integer acctsum_debit(year_arg integer, month_arg integer, code_here text); +CREATE FUNCTION acctsum_debit(year_arg integer, month_arg integer, code_here text) RETURNS integer AS ' + DECLARE + row record; + BEGIN + SELECT INTO row sum(acctrecs.amount) AS sum + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + WHERE NOT acctrecs.credit + AND acctsubj.code LIKE code_here || ''%'' + AND extract(year FROM accttrx.date) = year_arg + AND extract(month FROM accttrx.date) = month_arg; + IF row.sum IS NULL THEN + RETURN 0; + END IF; + RETURN row.sum; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsum_debit(year_arg integer, month_arg integer, code_here text) TO nobody; +-- integer acctsum_credit(year_arg integer, month_arg integer, code_here text); +CREATE FUNCTION acctsum_credit(year_arg integer, month_arg integer, code_here text) RETURNS integer AS ' + DECLARE + row record; + BEGIN + SELECT INTO row sum(acctrecs.amount) AS sum + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + WHERE acctrecs.credit + AND acctsubj.code LIKE code_here || ''%'' + AND extract(year FROM accttrx.date) = year_arg + AND extract(month FROM accttrx.date) = month_arg; + IF row.sum IS NULL THEN + RETURN 0; + END IF; + RETURN row.sum; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsum_credit(year_arg integer, month_arg integer, code_here text) TO nobody; +-- integer acctsum_balance(year_arg integer, month_arg integer, code_here text); +CREATE FUNCTION acctsum_balance(year_arg integer, month_arg integer, code_here text) RETURNS integer AS ' + DECLARE + row record; + BEGIN + SELECT INTO row sum(CASE WHEN acctrecs.credit THEN -acctrecs.amount ELSE acctrecs.amount END) AS sum + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + WHERE acctsubj.code LIKE code_here || ''%'' + AND extract(year FROM accttrx.date) * 100 + extract(month FROM accttrx.date) <= year_arg * 100 + month_arg; + IF row.sum IS NULL THEN + RETURN 0; + END IF; + RETURN row.sum; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsum_balance(year_arg integer, month_arg integer, code_here text) TO nobody; + + +-- +-- Table structure for table "acctsubj" +-- + +CREATE TABLE acctsubj ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + parent int REFERENCES acctsubj ON UPDATE CASCADE DEFERRABLE CHECK (acctsubj_ischild(parent, sn, code)), + code varchar(5) NOT NULL UNIQUE CHECK (code != ''), + title varchar(32) NOT NULL CHECK (title != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON acctsubj TO nobody; + +CREATE VIEW acctsubj_list AS + SELECT + acctsubj.sn AS sn, + acctsubj.code AS code, + acctsubj_fulltitle(acctsubj.parent, acctsubj.title) AS title, + to_char(acctsubj.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctsubj.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctsubj + LEFT JOIN users AS createdby ON acctsubj.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctsubj.updatedby = updatedby.sn + ORDER BY acctsubj.code; +GRANT SELECT ON acctsubj_list TO nobody; + +CREATE VIEW acctsubj_lastlv_list AS + SELECT + acctsubj.sn AS sn, + acctsubj.code AS code, + acctsubj_fulltitle(acctsubj.parent, acctsubj.title) AS title, + to_char(acctsubj.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctsubj.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctsubj + LEFT JOIN users AS createdby ON acctsubj.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctsubj.updatedby = updatedby.sn + WHERE acctsubj_islastlv(acctsubj.sn) + ORDER BY acctsubj.code; +GRANT SELECT ON acctsubj_lastlv_list TO nobody; + + +-- +-- Table structure for table "accttrx" +-- + +CREATE TABLE accttrx ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + date date NOT NULL DEFAULT CURRENT_DATE, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + note varchar(128) CHECK (note IS NULL OR note != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON accttrx TO nobody; + +CREATE VIEW accttrx_list AS + SELECT + accttrx.sn AS sn, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS num, + accttrx.note AS note, + to_char(accttrx.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(accttrx.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM accttrx + LEFT JOIN users AS createdby ON accttrx.createdby = createdby.sn + LEFT JOIN users AS updatedby ON accttrx.updatedby = updatedby.sn + ORDER BY accttrx.date DESC, accttrx.ord DESC; +GRANT SELECT ON accttrx_list TO nobody; + + +-- +-- Table structure for table "acctrecs" +-- + +CREATE TABLE acctrecs ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + trx int NOT NULL REFERENCES accttrx ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + credit boolean NOT NULL, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + subj int NOT NULL REFERENCES acctsubj ON UPDATE CASCADE DEFERRABLE, + summary varchar(32) CHECK (summary IS NULL OR summary != ''), + amount int NOT NULL CHECK (amount > 0), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (trx, credit, ord) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON acctrecs TO nobody; + +CREATE VIEW acctrecs_list AS + SELECT + acctrecs.sn AS sn, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS trx, + CASE WHEN credit THEN '貸' ELSE '借' END AS credit, + acctrecs.ord AS ord, + acctsubj.code || ' ' || acctsubj.title AS subj, + acctrecs.summary AS summary, + acctrecs.amount AS amount, + to_char(acctrecs.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctrecs.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + LEFT JOIN users AS createdby ON acctrecs.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctrecs.updatedby = updatedby.sn + ORDER BY accttrx.date DESC, accttrx.ord DESC, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrecs_list TO nobody; + + +-- +-- Accounting reports +-- +CREATE VIEW acctrep_cash_list AS + SELECT + TRUE AS _sel, + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + acctsubj.code AS _subj, + accttrx.date AS _date, + acctrecs.trx AS _trx, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + acctsubj.code || ' ' || acctsubj.title AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS income, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS expense, + 0 AS balance + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 1 ELSE 2 END, acctrecs.ord; +GRANT SELECT ON acctrep_cash_list TO nobody; + +CREATE VIEW acctrep_ledger_list AS + SELECT + TRUE AS _sel, + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + acctsubj.code AS _subj, + accttrx.date AS _date, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + acctsubj.code || ' ' || acctsubj.title AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS debit, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS credit, + 0 AS balance + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrep_ledger_list TO nobody; + +CREATE VIEW acctrep_search_list AS + SELECT + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS trxno, + acctsubj.code || ' ' || acctsubj.title AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS debit, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS credit, + accttrx.note AS note + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrep_search_list TO nobody; + + +COMMIT; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy.pm new file mode 100644 index 0000000..1cf4d91 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy.pm @@ -0,0 +1,70 @@ +# Mandy Wu's Website +# emandy.pm: Mandy Wu's Website. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +package Selima::emandy; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +@EXPORT = qw(); + +# Import our site-specific subroutines +use Selima::emandy::Config; +push @EXPORT, @Selima::emandy::Config::EXPORT; +use Selima::emandy::DataVars qw(:all); +push @EXPORT, @Selima::emandy::DataVars::EXPORT_OK; +use Selima::emandy::HTML; +push @EXPORT, @Selima::emandy::HTML::EXPORT; +use Selima::emandy::Items; +push @EXPORT, @Selima::emandy::Items::EXPORT; +use Selima::emandy::Rebuild; +push @EXPORT, @Selima::emandy::Rebuild::EXPORT; + +# Import our site-specific classess +use Selima::emandy::Checker::Book; +use Selima::emandy::Checker::Legend; +use Selima::emandy::Checker::MtrlType; +use Selima::emandy::Checker::Material; +use Selima::emandy::Form::Book; +use Selima::emandy::Form::Legend; +use Selima::emandy::Form::MtrlType; +use Selima::emandy::Form::Material; +use Selima::emandy::L10N; +use Selima::emandy::List::Books; +use Selima::emandy::List::Books::NotToBorrow; +use Selima::emandy::List::Books::ToBorrow; +use Selima::emandy::List::Legend; +use Selima::emandy::List::Legend::Public; +use Selima::emandy::List::MtrlType; +use Selima::emandy::List::Material; +use Selima::emandy::List::Search; +use Selima::emandy::Processor::Book; +use Selima::emandy::Processor::Legend; +use Selima::emandy::Processor::MtrlType; +use Selima::emandy::Processor::Material; + +# Import our common modules +use Selima; +push @EXPORT, @Selima::EXPORT; + +@EXPORT_OK = @EXPORT; + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Checker/Book.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Checker/Book.pm new file mode 100644 index 0000000..8438523 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Checker/Book.pm @@ -0,0 +1,203 @@ +# Mandy Wu's Website +# Book.pm: The book form checker. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +package Selima::emandy::Checker::Book; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "books" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + ${$self->{"maxlens"}}{"year"} = 4; + return $self; +} + +# _check_title: Check the title +# Use the default title checker + +# _check_author: Check the author +sub _check_author : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("author"); + return $error if defined $error; + # Regularize it + $self->_trim("author"); + # Skip if it is not filled + return if $form->param("author") eq ""; + # Check the length + return {"msg"=>N_("This author is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"author"}]} + if length $form->param("author") > ${$self->{"maxlens"}}{"author"}; + # OK + return; +} + +# _check_year: Check the year +sub _check_year : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("year"); + return $error if defined $error; + # Regularize it + $self->_trim("year"); + # Skip if it is not filled + return if $form->param("year") eq ""; + # Check the length + return {"msg"=>N_("This year is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"year"}]} + if length $form->param("year") > ${$self->{"maxlens"}}{"year"}; + # Check if it is a valid positive integer + return {"msg"=>N_("Please fill in a positive integer year.")} + unless $form->param("year") =~ /^\d+$/; + # Set to an integer + $_ = $form->param("year"); + $_ += 0; + $form->param("year", $_); + # OK + return; +} + +# _check_pub: Check the publisher +sub _check_pub : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("pub"); + return $error if defined $error; + # Regularize it + $self->_trim("pub"); + # Skip if it is not filled + return if $form->param("pub") eq ""; + # Check the length + return {"msg"=>N_("This publisher is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"pub"}]} + if length $form->param("pub") > ${$self->{"maxlens"}}{"pub"}; + # OK + return; +} + +# _check_origin: Check the origin +sub _check_origin : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("origin"); + return $error if defined $error; + # Regularize it + $self->_trim("origin"); + # Skip if it is not filled + return if $form->param("origin") eq ""; + # Check the length + return {"msg"=>N_("This origin is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"origin"}]} + if length $form->param("origin") > ${$self->{"maxlens"}}{"origin"}; + # OK + return; +} + +# _check_review: Check the review +sub _check_review : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("review"); + return $error if defined $error; + # Regularize it + $self->_trimtext("review"); + # Skip if it is not filled + $form->param("review", "") + if $form->param("review") eq __("Fill in the review here."); + return if $form->param("review") eq ""; + # Check the length + return {"msg"=>N_("This review is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"review"}]} + if length $form->param("review") > ${$self->{"maxlens"}}{"review"}; + # OK + return; +} + +# _check_comment: Check the comment +sub _check_comment : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("comment"); + return $error if defined $error; + # Regularize it + $self->_trimtext("comment"); + # Skip if it is not filled + $form->param("comment", "") + if $form->param("comment") eq __("Fill in the comment here."); + return if $form->param("comment") eq ""; + # Check the length + return {"msg"=>N_("This comment is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"comment"}]} + if length $form->param("comment") > ${$self->{"maxlens"}}{"comment"}; + # OK + return; +} + +# _check_lib: Check the libraries +sub _check_lib : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("lib"); + return $error if defined $error; + # Regularize it + $self->_trimtext("lib"); + # Skip if it is not filled + $form->param("lib", "") + if $form->param("lib") eq __("Fill in the libraries here."); + return if $form->param("lib") eq ""; + # Check the length + return {"msg"=>N_("This libraries is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"lib"}]} + if length $form->param("lib") > ${$self->{"maxlens"}}{"lib"}; + # OK + return; +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Checker/Legend.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Checker/Legend.pm new file mode 100644 index 0000000..45ed6b9 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Checker/Legend.pm @@ -0,0 +1,44 @@ +# Mandy Wu's Website +# Legend.pm: The blog article form checker. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +package Selima::emandy::Checker::Legend; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "legend" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + ${$self->{"maxlens"}}{"body"} = 15360; + return $self; +} + +# _check_title: Check the title +# Use the default title checker + +# _check_body: Check the content +# Use the default content checker + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Checker/Material.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Checker/Material.pm new file mode 100644 index 0000000..43aae6b --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Checker/Material.pm @@ -0,0 +1,160 @@ +# Mandy Wu's Website +# Material.pm: The historical material form checker. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-23 + +package Selima::emandy::Checker::Material; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::ChkFunc; +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "material" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_type: Check the type +sub _check_type : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("type"); + return $error if defined $error; + # Regularize it + $self->_trim("type"); + # Skip if it is not filled + return if $form->param("type") eq ""; + # Check if the type exists + return {"msg"=>N_("This type does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("type")}[0], "mtrltype"; + # OK + return; +} + +# _check_year: Check the year +sub _check_year : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("year"); + return $error if defined $error; + # Regularize it + $self->_trim("year"); + # Skip if it is not filled + return if $form->param("year") eq ""; + # Check the length + return {"msg"=>N_("This year is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"year"}]} + if length $form->param("year") > ${$self->{"maxlens"}}{"year"}; + # Check if it is a valid positive integer + return {"msg"=>N_("Please fill in a positive integer year.")} + unless $form->param("year") =~ /^\d+$/; + # Set to an integer + $_ = $form->param("year"); + $_ += 0; + $form->param("year", $_); + # OK + return; +} + +# _check_title: Check the title +# Use the default title checker + +# _check_body: Check the content +# Use the default content checker + +# _check_source: Check the source +sub _check_source : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("source"); + return $error if defined $error; + # Regularize it + $self->_trim("source"); + # Check if it is filled + return {"msg"=>N_("Please fill in the source.")} + if $form->param("source") eq ""; + # Check the length + return {"msg"=>N_("This source is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"source"}]} + if length $form->param("source") > ${$self->{"maxlens"}}{"source"}; + # OK + return; +} + +# _check_author: Check the author +sub _check_author : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("author"); + return $error if defined $error; + # Regularize it + $self->_trim("author"); + # Skip if it is not filled + return if $form->param("author") eq ""; + # Check the length + return {"msg"=>N_("This author is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"author"}]} + if length $form->param("author") > ${$self->{"maxlens"}}{"author"}; + # OK + return; +} + +# _check_notes: Check the notes +sub _check_notes : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("notes"); + return $error if defined $error; + # Regularize it + $self->_trimtext("notes"); + # Skip if it is not filled + $form->param("notes", "") + if $form->param("notes") eq __("Fill in the notes here."); + return if $form->param("notes") eq ""; + # Check the length + return {"msg"=>N_("This notes is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"notes"}]} + if length $form->param("notes") > ${$self->{"maxlens"}}{"notes"}; + # OK + return; +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Checker/MtrlType.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Checker/MtrlType.pm new file mode 100644 index 0000000..b6470ff --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Checker/MtrlType.pm @@ -0,0 +1,46 @@ +# Mandy Wu's Website +# MtrlType.pm: The historical material type form checker. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-23 + +package Selima::emandy::Checker::MtrlType; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "mtrltype" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + ${$self->{"maxlens"}}{"ord"} = 2; + return $self; +} + +# _check_ord: Check the order +# Use the default order checker + +# _check_title: Check the title +# Use the default title checker + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Config.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Config.pm new file mode 100644 index 0000000..12f7a47 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Config.pm @@ -0,0 +1,92 @@ +# Mandy Wu's Website +# Config.pm: The web site configuration. + +# Copyright (c) 2006-2020 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +package Selima::emandy::Config; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(siteconf page_replacements); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub siteconf(); +sub page_replacements(); +} + +# Get into the public variable space and initialize them +use lib $ENV{"DOCUMENT_ROOT"} . qw(/../../lib/perl5); +use Selima::CopyYear; +use Selima::DataVars qw(:all); +use Selima::ShortCut; + +use Selima::emandy::DataVars qw(:all); + +# siteconf: Subroutine to initialize site configuration +sub siteconf() { + local ($_, %_); + + # The package name and the package title + $PACKAGE = "emandy"; + $SITENAME_ABBR = "eMandy"; + # The author and the copyright + $AUTHOR = "小招"; + $COPYRIGHT = "© 小招。小招保有所有權利。"; + # Document root, the library and the l10n directories + $DOC_ROOT = $ENV{"DOCUMENT_ROOT"}; + $SITE_LIBDIR = $DOC_ROOT . "/magicat/lib/perl5"; + $LOCALEDIR = $DOC_ROOT . "/magicat/locale"; + + # Tables to lock when rebuilding pages + @REBUILD_TABLES = qw(linkcat links linkcatz legend); + # The local rebuild type labels + %REBUILD_LABELS = ( + "legend" => N_("Legend"), + ); + + # The languages + $DEFAULT_LANG = "zh-tw"; + @ALL_LINGUAS = qw(zh-tw); + + # The site data variables + + + return; +} + +# page_replacements: Dynamic page elements to be replaced, +# but not part of the content. Used by xfupdate_template(). +sub page_replacements() { + return { + "copyyear" => { + "pattern" => "2006(?:-\\d{4})?", + "content" => copyyear(2006), + }, + "generator" => { + "pattern" => "Selima \\d+\\.\\d+", + "content" => "Selima $Selima::VERSION", + }, + }; +} + +no utf8; +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/DataVars.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/DataVars.pm new file mode 100644 index 0000000..28796f6 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/DataVars.pm @@ -0,0 +1,53 @@ +# Mandy Wu's Website +# DataVars.pm: The site-wide constants and variables. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +package Selima::emandy::DataVars; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT %EXPORT_TAGS @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +%EXPORT_TAGS = ( + forms => [qw()], +); +@EXPORT_OK = qw(); +my %seen; +%seen = qw(); +foreach my $tag (keys %EXPORT_TAGS) { + push @EXPORT_OK, grep !$seen{$_}++, @{$EXPORT_TAGS{$tag}}; +} +$EXPORT_TAGS{"all"} = [@EXPORT_OK]; +# Prototype declaration +sub clear(); +} + +use Selima::DataVars qw(:forms); + +# clear: Clear the data variables +sub clear() { + local ($_, %_); + + + return; +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Form/Book.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Form/Book.pm new file mode 100644 index 0000000..bb0608a --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Form/Book.pm @@ -0,0 +1,129 @@ +# Mandy Wu's Website +# Book.pm: The book form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +package Selima::emandy::Form::Book; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "books" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this book") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to add a new book."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current book."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a book."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(title author year origin pub + toborrow review comment lib)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn title author year origin pub + toborrow review comment lib)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Add a New Book"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Book"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Book"); + } + } + $self = $class->SUPER::new($status, $args); + ${$self->{"maxlens"}}{"year"} = 4; + return $self; +} + +# _html_col_year: The year +sub _html_col_year : method { + $_[0]->_html_coltmpl_text("year", h_abbr(__("Year:")), undef, 4); +} + +# _html_col_pub: The publisher +sub _html_col_pub : method { + $_[0]->_html_coltmpl_text("pub", h_abbr(__("Publisher:"))); +} + +# _html_col_toborrow: To borrow? +sub _html_col_toborrow : method { + $_[0]->_html_coltmpl_bool("toborrow", h_abbr(__("To be borrowed?")), + h_abbr(__("To be borrowed")), h_abbr(__("Not to be borrowed")), + h_abbr(__("This book is to be borrowed."))); +} + +# _html_col_origin: The origin +sub _html_col_origin : method { + $_[0]->_html_coltmpl_text("origin", h_abbr(__("Origin:"))); +} + +# _html_col_review: The review +sub _html_col_review : method { + $_[0]->_html_coltmpl_textarea("review", h_abbr(__("Review:")), + h_abbr(__("Fill in the review here.")), undef, 5); +} + +# _html_col_comment: The comment +sub _html_col_comment : method { + $_[0]->_html_coltmpl_textarea("comment", h_abbr(__("Comment:")), + h_abbr(__("Fill in the comment here.")), undef, 5); +} + +# _html_col_lib: The libraries +sub _html_col_lib : method { + $_[0]->_html_coltmpl_textarea("lib", h_abbr(__("Libraries:")), + h_abbr(__("Fill in the libraries here.")), undef, 5); +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Form/Legend.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Form/Legend.pm new file mode 100644 index 0000000..bf42f26 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Form/Legend.pm @@ -0,0 +1,99 @@ +# Mandy Wu's Website +# Legend.pm: The blog article form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +package Selima::emandy::Form::Legend; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "legend" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this legend entry") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to write a new legend entry."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current legend entry."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a legend entry."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(title body html hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn title body html hid pageno + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Write a New Legend Entry"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Legend Entry"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Legend Entry"); + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_hid: Hide? +sub _html_col_hid : method { + $_[0]->_html_coltmpl_bool("hid", h_abbr(__("Hide?")), + h_abbr(__("Hide this legend entry")), h_abbr(__("Show this legend entry")), + h_abbr(__("Hide this legend entry currently."))); +} + +# _html_col_pageno: The page number +sub _html_col_pageno : method { + $_[0]->_html_coltmpl_ro("pageno", h_abbr(__("Page No.:"))); +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Form/Material.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Form/Material.pm new file mode 100644 index 0000000..b67be89 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Form/Material.pm @@ -0,0 +1,112 @@ +# Mandy Wu's Website +# Material.pm: The historical material form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-23 + +package Selima::emandy::Form::Material; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +use Selima::emandy::Items; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "material" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this material") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to add a new material."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current material."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a material."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(type year title body source + author notes)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn type year title body source + author notes)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Add a New Material"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Material"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Material"); + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_type: The type +sub _html_col_type : method { + $_[0]->_html_coltmpl_select("type", + h_abbr(__("Type:")), \&mtrltype_options, \&mtrltype_title); +} + +# _html_col_year: The year +sub _html_col_year : method { + $_[0]->_html_coltmpl_text("year", h_abbr(__("Year:")), undef, 4); +} + +# _html_col_source: The source +sub _html_col_source : method { + $_[0]->_html_coltmpl_text("source", h_abbr(__("Source:"))); +} + +# _html_col_notes: The notes +sub _html_col_notes : method { + $_[0]->_html_coltmpl_textarea("notes", h_abbr(__("Notes:")), + h_abbr(__("Fill in the notes here.")), undef, 3); +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm new file mode 100644 index 0000000..94956ca --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm @@ -0,0 +1,93 @@ +# Mandy Wu's Website +# MtrlType.pm: The historical material type form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-23 + +package Selima::emandy::Form::MtrlType; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "mtrltype" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this type") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to add a new type."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current type."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a type."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(ord title)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn ord title)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Add a New Material Type"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Material Type"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Material Type"); + } + } + $self = $class->SUPER::new($status, $args); + ${$self->{"maxlens"}}{"ord"} = 2; + if ($self->{"type"} eq "cur") { + if (defined $self->{"cur"}->param("mtrlcount") && $self->{"cur"}->param("mtrlcount") > 0) { + $self->{"nodelete"} = 1; + push @{$self->{"prefmsg"}}, __("This type has [numerate,_1,a material,materials]. It cannot be deleted. To delete the type, [numerate,_1,its material,all of its materials] must first be deleted.", $self->{"cur"}->param("mtrlcount")); + } + } + return $self; +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/HTML.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/HTML.pm new file mode 100644 index 0000000..1259d4e --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/HTML.pm @@ -0,0 +1,752 @@ +# Mandy Wu's Website +# HTML.pm: The HTML web page parts. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +package Selima::emandy::HTML; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(html_header html_title html_message); +push @EXPORT, qw(html_errmsg html_body html_links html_links_index); +push @EXPORT, qw(html_legend_index); +push @EXPORT, qw(html_footer); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub html_header($;$); +sub html_title($;$); +sub html_message($); +sub html_errmsg($); +sub html_nav(;$); +sub html_login(;$); +sub html_nav_admin(;$); +sub html_nav_page(;$); +sub html_body($;$); +sub html_links($;$); +sub html_links_index(\@;$); +sub html_legend_index(\@;$); +sub html_footer(;$); +sub merged_tree($$;$); +} + +use Cwd qw(realpath); +use File::Basename qw(dirname); +use File::Spec::Functions qw(); +use IO::NestedCapture qw(CAPTURE_STDOUT); +use Lingua::ZH::Numbers; + +use Selima::A2HTML; +use Selima::AddGet; +use Selima::AltLang; +use Selima::DataVars qw(:author :env :input :list :lninfo :requri :siteconf); +use Selima::ErrMsg; +use Selima::Format; +use Selima::HTTPS; +use Selima::Links; +use Selima::LnInfo; +use Selima::LogIn; +use Selima::MarkAbbr; +use Selima::MungAddr; +use Selima::PageFunc; +use Selima::Preview; +use Selima::ScptPriv; +use Selima::ShortCut; +use Selima::Unicode; +use Selima::XFileIO; + +use vars qw(@ADMIN_SCRIPTS %HEADER %FOOTER); +@ADMIN_SCRIPTS = ( + { "title" => N_("Manage Content"), + "sub" => [ + { "title" => N_("Legend"), + "path" => "/magicat/cgi-bin/legend.cgi" }, + { "title" => N_("Books"), + "path" => "/magicat/cgi-bin/books.cgi" }, + { "title" => N_("Materials"), + "path" => "/magicat/cgi-bin/material.cgi" }, + { "title" => N_("Material Types"), + "path" => "/magicat/cgi-bin/mtrltype.cgi" }, + { "title" => N_("Pages"), + "path" => "/magicat/cgi-bin/pages.cgi" }, + { "title" => N_("Links"), + "path" => "/magicat/cgi-bin/links.cgi" }, + { "title" => N_("Link Categories"), + "path" => "/magicat/cgi-bin/linkcat.cgi" }, + { "title" => N_("Link Categorization"), + "path" => "/magicat/cgi-bin/linkcatz.cgi" }, + ], + }, + { "title" => N_("Manage Accounts"), + "sub" => [ + { "title" => N_("Users"), + "path" => "/magicat/cgi-bin/users.cgi" }, + { "title" => N_("Groups"), + "path" => "/magicat/cgi-bin/groups.cgi" }, + { "title" => N_("User Membership"), + "path" => "/magicat/cgi-bin/usermem.cgi" }, + { "title" => N_("Group Membership"), + "path" => "/magicat/cgi-bin/groupmem.cgi" }, + { "title" => N_("User Preferences"), + "path" => "/magicat/cgi-bin/userpref.cgi" }, + { "title" => N_("Script Privileges"), + "path" => "/magicat/cgi-bin/scptpriv.cgi" }, + ], + }, + { "title" => N_("Manage Accounting"), + "sub" => [ + { "title" => N_("Reports"), + "path" => "/magicat/cgi-bin/acctreps.cgi", + "https" => 1 }, + { "title" => N_("Transactions"), + "path" => "/magicat/cgi-bin/accttrx.cgi", + "https" => 1 }, + { "title" => N_("Subjects"), + "path" => "/magicat/cgi-bin/acctsubj.cgi", + "https" => 1 }, + { "title" => N_("Records"), + "path" => "/magicat/cgi-bin/acctrecs.cgi", + "https" => 1 }, + ], + }, + { "title" => N_("Miscellaneous"), + "sub" => [ + { "title" => N_("Activity Log"), + "path" => "/magicat/cgi-bin/actlog.cgi" }, + { "title" => N_("Rebuild Pages"), + "path" => "/magicat/cgi-bin/rebuild.cgi" }, + { "title" => N_("Analog"), + "path" => "/magicat/analog/" }, + { "title" => N_("Test Script"), + "path" => "/magicat/cgi-bin/test.cgi" }, + ], + }, +); + +# html_header: Display the page header +sub html_header($;$) { + local ($_, %_); + my ($title, $args, $guide); + my ($langname, $langfile); + my ($author, $copyright, $keywords, $copypage); + my ($stylesheets, $javascripts, $favicon, $class, $onload); + my ($titlelang, $skiptobody); + ($title, $args) = @_; + # Obtain the page parameters + $args = page_param $args; + # Set the language + $langname = h(ln $$args{"lang"}, LN_NAME); + $langfile = ln($$args{"lang"}, LN_FILENAME); + # Misc + # The copyright message should be already HTML-escaped, + # for the copyright sign "©". + $author = exists $$args{"author"}? h($$args{"author"}): + defined $AUTHOR? h($AUTHOR): undef; + $copyright = exists $$args{"copyright"}? $$args{"copyright"}: + defined $COPYRIGHT? $COPYRIGHT: undef; + $keywords = exists $$args{"keywords"}? h($$args{"keywords"}): undef; + $copypage = exists $$args{"copypage"}? h($$args{"copypage"}): undef; + # Style sheets + $stylesheets = []; + push @$stylesheets, "/stylesheets/common.css"; + push @$stylesheets, @{$$args{"stylesheets"}} + if exists $$args{"stylesheets"}; + # JavaScripts + $javascripts = []; + if (exists $$args{"javascripts"}) { + push @$javascripts, "/scripts/common.js"; + push @$javascripts, "/scripts/lang.$langfile.js"; + push @$javascripts, @{$$args{"javascripts"}}; + } + # Favorite icon + $favicon = exists $$args{"favicon"}? + h($$args{"favicon"}): h("/favicon.ico"); + # The class of body + $class = exists $$args{"class"}? + " class=\"" . h($$args{"class"}) . "\"": ""; + # The onload JavaScript event handler + $onload = exists $$args{"onload"}? + " onload=\"" . h($$args{"onload"}) . "\"": ""; + # The accessibility guide + $skiptobody = h(__("Skip to the page content area.")); + $guide = h(__("Page Content Area")); + + print << "EOT"; +" ?> + + + + + + +EOT + # Author, copyright and keywords + print "\n" + if defined $author; + print "\n" + if defined $copyright; + print "\n" + if defined $keywords; + print "\" />\n" + if $$args{"static"}; + # The home page + print "\n"; + # The copyright page + print "\n" + if defined $copypage; + # The author contact information + print "\n"; + # Revelent pages + print "\n" + if exists $$args{"up"}; + print "\n" + if exists $$args{"first"}; + print "\n" + if exists $$args{"prev"}; + print "\n" + if exists $$args{"next"}; + print "\n" + if exists $$args{"last"}; + print "\n" + if exists $$args{"toc"}; + # Style sheets + print "\n" + foreach @$stylesheets; + # JavaScripts + print "\n" + foreach @$javascripts; + # Favorite Icon + print "\n"; + # The title + $titlelang = $$args{"title_lang"} eq $$args{"lang"}? "": + " xml:lang=\"" . h(ln $$args{"title_lang"}, LN_NAME) . "\""; + print "" . h($title) . "\n"; + print << "EOT"; + + + + + + +EOT + + # Show the navigation area + html_nav $args; + # Embrace the content + print << "EOT"; +
+ + +EOT + # Display the title + html_title $title, $args unless $$args{"no_auto_title"}; + + return; +} + +# html_title: Print an HTML title +sub html_title($;$) { + local ($_, %_); + my ($title, $args, $h); + ($title, $args) = @_; + $h = << "EOT"; +

%s

+ +EOT + printf $h, h_abbr($title); + return; +} + +# html_message: Print an HTML message +sub html_message($) { + local ($_, %_); + $_ = $_[0]; + return if !defined $_ || $_ eq ""; + $_ = h_abbr($_); + print << "EOT"; +

$_

+ +EOT + return; +} + +# html_errmsg: Print an HTML error message, a wrapper to html_message() +sub html_errmsg($) { + local ($_, %_); + $_ = $_[0]; + return if !defined $_; + html_message(err2msg $_); + return; +} + +# html_nav: Print the HTML navigation bar +sub html_nav(;$) { + local ($_, %_); + my ($args, $lang, $guide, $FD, @sections); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + $lang = $$args{"lang"}; + # The accessibility guide + $guide = h(__("Navigation Links Area")); + + @sections = qw(); + # Print the primary navigation bar + $HEADER{"file"} = sprintf("%s/magicat/include/header.html", $DOC_ROOT) + if !exists $HEADER{"file"}; + undef $_; + if ( !exists $HEADER{"content"} + || !exists $HEADER{"date"} + || $HEADER{"date"} < ($_ = (stat $HEADER{"file"})[9])) { + $_ = (stat $HEADER{"file"})[9] if !defined $_; + $HEADER{"date"} = $_; + $HEADER{"content"} = hcref_decode ln($lang, LN_CHARSET), xfread $HEADER{"file"}; + } + push @sections, $HEADER{"content"}; + + # Print the section-specific navigation links + push @sections, $$args{"header_html_nav"} + if exists $$args{"header_html_nav"}; + + # Print the log-in information + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_login $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + push @sections, $_ if $_ ne ""; + + # Print the section-specific navigation bar + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + if ($$args{"admin"}) { + html_nav_admin $args; + } else { + html_nav_page $args; + } + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + push @sections, $_ if $_ ne ""; + + # Embrace the navigation links + print << "EOT"; + +
+ +EOT + + return; +} + +# html_login: Print the HTML log-in information +sub html_login(;$) { + local ($_, %_); + my ($args, $msg, $modify, $submit); + $args = $_[0]; + # Skip if not logged-in + return if !defined get_login_sn; + # Obtain the page parameters + $args = page_param $args; + # No log-in bar for static pages + return if $$args{"static"}; + + # The message + $modify = "/magicat/cgi-bin/users.cgi?form=cur&sn=" . get_login_sn; + $msg = sprintf __("Welcome, %s. (Modify)"), + h(get_login_name), h($modify); + $submit = h(__("Log out")); + + print << "EOT"; + +EOT + return; +} + +# html_nav_admin: Print the HTML administrative navigation bar +sub html_nav_admin(;$) { + local ($_, %_); + my ($args, $cgidir, $path, $title); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + + # Find the current CGI directory + $cgidir = "cgi-bin"; + $cgidir = $1 if $REQUEST_PATH =~ /\/(cgi-[a-z0-9]+)\/[a-z0-9]+\.cgi$/; + # Output them + foreach my $cat (@ADMIN_SCRIPTS) { + @_ = qw(); + foreach (@{$$cat{"sub"}}) { + next unless is_script_permitted $$_{"path"}; + ($path, $title) = ($$_{"path"}, $$_{"title"}); + # Fix the path to use the same cgi-* directory alias + $path =~ s/\/cgi-[a-z0-9]+\/([a-z0-9]+\.cgi)$/\/$cgidir\/$1/; + # Fix the path of the HTTPS scripts to use HTTPS + $path = "https://" . https_host . "/$PACKAGE$path" + if exists $$_{"https"} && $$_{"https"} && !is_https; + push @_, sprintf(" %s", + h($path), h_abbr(__($title))); + } + next if @_ == 0; + $title = $$cat{"title"}; + $_ = sprintf(__("%s:"), h_abbr(__($title))); + print "
\n" + . $_ . "\n" . join(" |\n", @_) . "\n" + . "
\n" + if @_ > 0; + } + return; +} + +# html_nav_page: Print the HTML page navigation bar +sub html_nav_page(;$) { + local ($_, %_); + my ($args, $tree); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + # Obtain the page tree + $tree = merged_tree $$args{"path"}, $$args{"lang"}, $$args{"preview"}; + # Bounce for nothing + return if !defined $tree + || !exists $$tree{"pages"} + || !defined $$tree{"pages"} + || @{$$tree{"pages"}} <= 1; + + # Output them + print << "EOT"; + +EOT + return; +} + +# html_body: Print the HTML body +sub html_body($;$) { + local ($_, %_); + my ($page, $args); + ($page, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Output the picture + # To be done + + # Output the content + print "" . (!exists $$page{"html"} || !$$page{"html"}? + a2html($$page{"body"}): $$page{"body"}) . "\n\n"; + + return; +} + +# html_links: Print the HTML links list +sub html_links($;$) { + local ($_, %_); + my ($page, $args); + ($page, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Output the breadcrumb trai + @_ = qw(); + push @_, "" . h(__("Related Links")) . ""; + foreach my $parent (@{$$page{"parents"}}) { + push @_, "" + . h($$parent{"title"}) . ""; + } + push @_, h($$page{"title"}); + print "
\n" + . join(" /\n", @_) . "\n
\n\n"; + + # Output the subcategories + if (@{$$page{"scats"}} > 0) { + print "

" . h(__("Subcategories:")) . "

\n\n
    \n"; + foreach my $cat (@{$$page{"scats"}}) { + $_ = h($$cat{"title"}); + $_ .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
  1. " + . "$_
  2. \n"; + } + print "
\n\n"; + } + + # Output the links + if (@{$$page{"links"}} > 0) { + my $emailalt; + $emailalt = h(__("E-mail")); + print "
    \n"; + foreach my $link (@{$$page{"links"}}) { + my ($url, $title, $ctitle, $dsc); + $url = h($$link{"url"}); + $title = h($$link{"title"}); + print "
  1. \n"; + print "
    \n
    \n" + if defined $$link{"email"}; + # Output the link icon + print "\"$title\"
    \n" + if defined $$link{"icon"}; + # Output the site title + $ctitle = is_usascii_printable($$link{"title"})? + "$title": $title; + if (defined $$link{"title_2ln"}) { + $_ = h($$link{"title_2ln"}); + $_ = "$_" + if is_usascii_printable($$link{"title_2ln"}); + $ctitle .= " $_"; + } + print "$ctitle
    \n"; + # Output the URL + print __("URL:") . " $url
    \n"; + # Output other information + if (defined $$link{"email"}) { + print __("E-mail:") . " "; + print "\n"; + print "\n"; + print mung_email_span(h($$link{"email"})) . "
    \n"; + } + print __("Address:") . " " . h($$link{"addr"}) . "
    \n" + if defined $$link{"addr"}; + print __("Tel.:") . " " . h($$link{"tel"}) . "
    \n" + if defined $$link{"tel"}; + print __("Fax.:") . " " . h($$link{"fax"}) . "
    \n" + if defined $$link{"fax"}; + # Output the description + $dsc = $$link{"dsc"}; + print h($dsc) . "
    \n"; + print "
    \n
    \n" if defined $$link{"email"}; + print "
  2. \n\n"; + } + print "
\n\n"; + } + + return; +} + +# html_links_index: Print the HTML link categories index +sub html_links_index(\@;$) { + local ($_, %_); + my ($cats, $args); + ($cats, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Bounce for nothing + if (@$cats == 0) { + print "

" . h(__("The database is empty.")) . "

\n\n"; + return; + } + + # Output the root categories + print << "EOT"; +
    +EOT + foreach my $cat (@$cats) { + $_ = h($$cat{"title"}); + $_ .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
  • " + . "$_
  • \n"; + } + print << "EOT"; +
+ +EOT + return; +} + +# html_legend_index: Print the HTML legend index +sub html_legend_index(\@;$) { + local ($_, %_); + my ($pages, $args, $parent, $here); + ($pages, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Bounce for nothing + if (@$pages == 0) { + print "

" . h(__("The legend is empty.")) . "

\n\n"; + return; + } + + # Output the index + $_ = h(__("Index")); + print << "EOT"; +

$_

+ +
    +EOT + foreach my $page (reverse @$pages) { + my ($title, $url, $start, $end); + Lingua::ZH::Numbers->charset("traditional"); + $_ = number_to_zh($$page{"no"}); + $title = h(sprintf __("Legend Volume %s"), $_); + $url = h($$page{"path"}); + $start = h(myfmtdate $$page{"start"}); + $end = h(myfmtdate $$page{"end"}); + print << "EOT"; +
  • $title

    +
    $start - $end
  • + +EOT + } + print << "EOT"; +
+ +EOT + return; +} + +# html_footer: Print the HTML footer +sub html_footer(;$) { + local ($_, %_); + my ($args, $lang); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + $lang = $$args{"lang"}; + + # Embrace the content + print << "EOT"; +
+ +EOT + # Print the section-specific navigation bar + print "
\n" . $$args{"footer_html_nav"} . "\n\n" + if exists $$args{"footer_html_nav"}; + + # Print the common footer + $FOOTER{"file"} = sprintf("%s/magicat/include/footer.html", $DOC_ROOT) + if !exists $FOOTER{"file"}; + undef $_; + if ( !exists $FOOTER{"content"} + || !exists $FOOTER{"date"} + || $FOOTER{"date"} < ($_ = (stat $FOOTER{"file"})[9])) { + $_ = (stat $FOOTER{"file"})[9] if !defined $_; + $FOOTER{"date"} = $_; + $FOOTER{"content"} = hcref_decode ln($lang, LN_CHARSET), xfread $FOOTER{"file"}; + } + $_ = $FOOTER{"content"}; + $FOOTER{"perl"} = {} if !exists $FOOTER{"perl"}; + if ($$args{"static"}) { + s/\n+\n+/\n\n/; + } elsif ($IS_MODPERL) { + if (!exists ${$FOOTER{"perl"}}{"modperl"}) { + ${$FOOTER{"perl"}}{"modperl"} = << "EOT"; +
+%s +

%s

+
+EOT + ${$FOOTER{"perl"}}{"modperl"} = sprintf(${$FOOTER{"perl"}}{"modperl"}, + h(__("mod_perl -- Speed, Power, Scalability")), + __("This script is written in Perl and optimized for mod_perl.")); + ${$FOOTER{"perl"}}{"modperl"} =~ s/()/$1 hreflang="en"$2/g + if $lang ne "en"; + } + s/\n/${$FOOTER{"perl"}}{"modperl"}/; + } else { + if (!exists ${$FOOTER{"perl"}}{"cgi"}) { + ${$FOOTER{"perl"}}{"cgi"} = << "EOT"; +
+

%s

+
+EOT + ${$FOOTER{"perl"}}{"cgi"} = sprintf(${$FOOTER{"perl"}}{"cgi"}, + __("This script is written in
Perl.")); + ${$FOOTER{"perl"}}{"cgi"} =~ s/()/$1 hreflang="en"$2/g + if $lang ne "en"; + } + s/\n/${$FOOTER{"perl"}}{"cgi"}/; + } + print $_; + + # Show the HTML preview mark + html_preview_mark $args; + + print "\n\n\n"; + return; +} + +# merged_tree: Get the page tree in a directory +sub merged_tree($$;$) { + local ($_, %_); + my ($path, $lang, $preview); + ($path, $lang, $preview) = @_; + + # Return special areas + if ($path =~ /^\/links\//) { + return link_tree($path, $lang, $preview); + # Non-pages (scripts... etc) + } else { + return {}; + } +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Items.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Items.pm new file mode 100644 index 0000000..3b96918 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Items.pm @@ -0,0 +1,93 @@ +# Mandy Wu's Website +# Items.pm: The data record related subroutines. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +package Selima::emandy::Items; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(mtrltype_title mtrltype_options); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub mtrltype_title($); +sub mtrltype_options($); +} + +use Selima::ChkFunc; +use Selima::CommText; +use Selima::DataVars qw($DBH :l10n :lninfo); +use Selima::EchoForm; +use Selima::GetLang; +use Selima::LnInfo; + +# mtrltype_title: Obtain a material type title +sub mtrltype_title($) { + local ($_, %_); + my ($sn, $sql, $sth, $row); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + + # Check the serial number first + return t_na if !check_sn $sn; + + # Query + $sql = "SELECT title FROM mtrltype" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return t_na unless $sth->rows == 1; + + # Found + return ${$sth->fetch}[0]; +} + +# mtrltype_options: Obtain a material type options list +sub mtrltype_options($) { + local ($_, %_); + my ($value, $sql, $thiscol, $defcol, $content); + $value = $_[0]; + + # Unilingual + if (@ALL_LINGUAS == 1) { + $content = "title AS content"; + # Multilingual + } else { + $thiscol = "title_" . getlang(LN_DATABASE); + # Default language + if (getlang eq $DEFAULT_LANG) { + $content = "$thiscol AS content"; + # Fall back to the default language + } else { + $defcol = "title_" . ln($DEFAULT_LANG, LN_DATABASE); + $content = "COALESCE($thiscol, $defcol) AS content"; + } + } + $sql = "SELECT sn AS value, $content FROM mtrltype" + . " ORDER BY ord;\n"; + return opt_list $sql, $value; +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/L10N.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/L10N.pm new file mode 100644 index 0000000..33d342e --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/L10N.pm @@ -0,0 +1,38 @@ +# Mandy Wu's Website +# L10N.pm: The localization class. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +package Selima::emandy::L10N; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +return 1; + +# The Chinese (Taiwan) localized messages. +package Selima::emandy::L10N::zh_tw; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +sub numerate : method { $_[2] } + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Books.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Books.pm new file mode 100644 index 0000000..afa8568 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Books.pm @@ -0,0 +1,113 @@ +# Mandy Wu's Website +# Books.pm: The book list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +package Selima::emandy::List::Books; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; +use Selima::DataVars qw(:requri); + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "books" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Book"): + __("Manage Books"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "title,-year,author"; + # Columns that should display its brief instead + $self->{"COLS_BRIEF"} = [qw(review comment lib)]; + # Column labels + $self->col_labels( + "author" => __("Author"), + "year" => __("Year"), + "origin" => __("Origin"), + "pub" => __("Publisher"), + "toborrow" => __("To be borrowed?"), + "review" => __("Review"), + "comment" => __("Comment"), + "lib" => __("Libraries"), + ); + # The list switches + $self->{"lists_switch"} = [ + { "url" => $REQUEST_FILE . "?list=nottoborrow", + "title" => __("Books not to be borrowed"), }, + { "url" => $REQUEST_FILE . "?list=toborrow", + "title" => __("Books to be borrowed"), }, + { "url" => $REQUEST_FILE, + "title" => __("All books"), }, + ]; + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Add a new book.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a book:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,book].", $self->{"total"}); + # List result + } else { + return __("[*,_1,book].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,book], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,book], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Books/NotToBorrow.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Books/NotToBorrow.pm new file mode 100644 index 0000000..9baf686 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Books/NotToBorrow.pm @@ -0,0 +1,47 @@ +# Mandy Wu's Website +# NotToBorrow.pm: The not-to-borrow book list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +package Selima::emandy::List::Books::NotToBorrow; +use 5.008; +use strict; +use warnings; +use base qw(Selima::emandy::List::Books); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "books" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Book"): + __("Manage Books Not to Be Borrowed"); + $self->{"view"} = "books_nottoborrow_list"; + # Column labels + $self->col_labels( + ); + return $self; +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Books/ToBorrow.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Books/ToBorrow.pm new file mode 100644 index 0000000..e02a0f7 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Books/ToBorrow.pm @@ -0,0 +1,47 @@ +# Mandy Wu's Website +# ToBorrow.pm: The to-borrow book list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +package Selima::emandy::List::Books::ToBorrow; +use 5.008; +use strict; +use warnings; +use base qw(Selima::emandy::List::Books); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "books" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Book"): + __("Manage Books to be Borrowed"); + $self->{"view"} = "books_toborrow_list"; + # Column labels + $self->col_labels( + ); + return $self; +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Legend.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Legend.pm new file mode 100644 index 0000000..d1e5c7a --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Legend.pm @@ -0,0 +1,100 @@ +# Mandy Wu's Website +# Legend.pm: The administrative blog article list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +package Selima::emandy::List::Legend; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "legend" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Legend Entry"): + __("Manage Legend"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "created"; + # Columns that should display its brief instead + $self->{"COLS_BRIEF"} = [qw(body)]; + # Columns should be displayed in a reversed order + $self->{"reverse"} = 1; + # The list brief size + $self->{"DEFAULT_BRIEF_LEN"} = 20; + # Column labels + $self->col_labels( + "pageno" => __("Page No."), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Write a new legend entry.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a legend entry:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,legend entry,legend entries].", $self->{"total"}); + # List result + } else { + return __("[*,_1,legend entry,legend entries].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,legend entry,legend entries], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,legend entry,legend entries], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Legend/Public.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Legend/Public.pm new file mode 100644 index 0000000..12d3355 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Legend/Public.pm @@ -0,0 +1,152 @@ +# Mandy Wu's Website +# Public.pm: The blog article list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +package Selima::emandy::List::Legend::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use Selima::A2HTML; +use Selima::DataVars qw($DBH); +use Selima::Format; +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "legend" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # Columns should be displayed in a reversed order + $self->{"reverse"} = 1; + # These are static pages + $self->{"static"} = 1; + $self->{"static_lastfile"} = "latest.html"; + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, $table, $sth, $sql, $error); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + + # The view name + $table = $DBH->quote_identifier($self->{"view"}); + + # Obtain everything in this page + $self->{"current"} = []; + # Always reverse + $self->{"select"} = "SELECT * FROM $table" + . " WHERE pageno=" . $self->{"pageno"} . ";\n"; + $sql = $self->{"select"}; + $sth = $DBH->prepare($sql); + $sth->execute; + push @{$self->{"current"}}, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + + # Done + return $self->{"error"}; +} + +# page_param: Obtain page parameters +sub page_param : method { + local ($_, %_); + my ($self, $args); + $self = $_[0]; + # Run the parent method + $args = $self->SUPER::page_param; + # Add the page bar to the page parameters + if (defined $args && $self->{"lastpage"} > 1) { + my $FD; + # Obtain the page bar + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + $self->html_pagebar; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $$args{"header_html_nav"} = join "", <$FD>; + $$args{"header_html_nav"} =~ s/\s+$//; + $$args{"footer_html_nav"} = $$args{"header_html_nav"}; + } + return $args; +} + +# html: Output the list +sub html : method { + local ($_, %_); + my ($self, $args); + ($self, $args) = @_; + # Obtain the page parameters + $args = Selima::PageFunc::page_param $args; + # Fetch the current list if not fetched yet + $self->fetch if !$self->{"fetched"}; + + # List the items + $self->html_list($args); + + return; +} + +# html_list: List the items +sub html_list : method { + local ($_, %_); + my ($self, $args, @htmls); + ($self, $args) = @_; + # Obtain the page parameters + $args = Selima::PageFunc::page_param $args; + # No record to be listed + return if $self->{"total"} == 0; + + foreach my $current (@{$self->{"current"}}) { + my $h; + $h = ""; + $h .= "
\n"; + $h .= "
" . myfmttime($$current{"date"}) . "
\n\n"; + $h .= "

" . h($$current{"title"}) . "

\n\n"; + if ($$current{"html"}) { + $h .= $$current{"body"} . "\n\n"; + } else { + $h .= "
\n" . a2html($$current{"body"}) . "\n
\n\n"; + } + $h .= "
\n\n"; + push @htmls, $h; + } + + $_ = h(__("The legend entry seperator")); + print "
\n\n" + . join("
\n\n", @htmls) . "
\n\n"; + + return; +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Material.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Material.pm new file mode 100644 index 0000000..91a879d --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Material.pm @@ -0,0 +1,100 @@ +# Mandy Wu's Website +# Material.pm: The historical material list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-23 + +package Selima::emandy::List::Material; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "material" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Material"): + __("Manage Materials"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "title"; + # Columns that should display its brief instead + $self->{"COLS_BRIEF"} = [qw(body notes)]; + # Column labels + $self->col_labels( + "type" => __("Type"), + "year" => __("Year"), + "source" => __("Source"), + "author" => __("Author"), + "notes" => __("Notes"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Add a new material.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a material:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,material].", $self->{"total"}); + # List result + } else { + return __("[*,_1,material].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,material], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,material], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/MtrlType.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/MtrlType.pm new file mode 100644 index 0000000..ea86cec --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/MtrlType.pm @@ -0,0 +1,93 @@ +# Mandy Wu's Website +# MtrlType.pm: The historical material type list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-23 + +package Selima::emandy::List::MtrlType; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "mtrltype" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Material Type"): + __("Manage Material Types"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "ord,title"; + # Column labels + $self->col_labels( + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Add a new type.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a type:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,type].", $self->{"total"}); + # List result + } else { + return __("[*,_1,type].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,type], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,type], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Search.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Search.pm new file mode 100644 index 0000000..41f9771 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/List/Search.pm @@ -0,0 +1,179 @@ +# Mandy Wu's Website +# Search.pm: The web site full-text search result list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +package Selima::emandy::List::Search; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::Logging; +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The page title + if (!defined $self->{"query"}) { + $self->{"title"} = __("Full Text Search"); + } else { + $self->{"title"} = __("Search Result"); + } + $self->{"view"} = "search_list"; + $self->{"COLS_NO_SEARCH"} = [qw(section path date html)]; + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my $self; + $self = $_[0]; + # No search specified + if (!defined $self->{"query"}) { + $self->{"total"} = undef; + return $self->{"error"}; + } + # Check the query phrase + # Regularize it + $self->{"query"} =~ s/^\s*(.*?)\s*$/$1/; + # Check if it is filled + if ($self->{"query"} eq"") { + $self->{"total"} = undef; + $self->{"error"} = {"msg"=>N_("Please fill in your query.")}; + return $self->{"error"}; + } + # Run the parent method + $self->SUPER::fetch; + # Add an activity log record + actlog("Query with phrase \"" . $self->{"query"} . "\"."); + # Done + return $self->{"error"}; +} + +# sql_orderby: Get the SQL ORDER BY phase +# Always return nothing +sub sql_orderby : method { return ""; } + +# html_newlink: Display a link to add a new item +# Make it a null function +sub html_newlink : method {} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search in the website:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article].", $self->{"total"}); + # List result + } else { + return __("[*,_1,article].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +# html_list: List the items +sub html_list : method { + local ($_, %_); + my ($self); + $self = $_[0]; + # Do not show the list + return if !defined $self->{"total"}; + # No record to be listed + return if $self->{"total"} == 0; + + print << "EOT"; +
    +EOT + + # Print each record + foreach my $current (@{$self->{"current"}}) { + my ($url, $abstract); + $url = h($$current{"path"}); + $abstract = $self->query_abstract($current); + if ($$current{"section"} eq "pages") { + my $title; + $title = h($$current{"title"}); + + print << "EOT"; +
  1. $title

    +EOT + } elsif ($$current{"section"} eq "links") { + my ($title, $sectitle); + $title = h($$current{"title"}); + $sectitle = h(__("Related Links")); + + print << "EOT"; +
  2. $title

    +
    $sectitle
    +EOT + } elsif ($$current{"section"} eq "legend") { + my ($title, $sectitle); + $title = h($$current{"title"}); + $sectitle = h(__("Legend")); + + print << "EOT"; +
  3. $title

    +
    $sectitle
    +EOT + } + print "\n

    $abstract

    \n" if defined $abstract; + print << "EOT"; +
  4. + +EOT + } + print << "EOT"; +
+ +EOT + return; +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Processor/Book.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Processor/Book.pm new file mode 100644 index 0000000..133bc05 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Processor/Book.pm @@ -0,0 +1,121 @@ +# Mandy Wu's Website +# Book.pm: The book data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +package Selima::emandy::Processor::Book; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw($DBH :addcol); +use Selima::Format; +use Selima::Guest; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "books" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("author", $self->_form("author")); + $self->{"cols"}->addnum("year", $self->_form("year")); + $self->{"cols"}->addstr("origin", $self->_form("origin")); + $self->{"cols"}->addstr("pub", $self->_form("pub")); + $self->{"cols"}->addbool("toborrow", $self->_form("toborrow")); + $self->{"cols"}->addstr("review", $self->_form("review")); + $self->{"cols"}->addstr("comment", $self->_form("comment")); + $self->{"cols"}->addstr("lib", $self->_form("lib")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("author", $self->_form("author"), scalar $cur->param("author")); + $self->{"cols"}->addnum("year", $self->_form("year"), scalar $cur->param("year")); + $self->{"cols"}->addstr("origin", $self->_form("origin"), scalar $cur->param("origin")); + $self->{"cols"}->addstr("pub", $self->_form("pub"), scalar $cur->param("pub")); + $self->{"cols"}->addbool("toborrow", $self->_form("toborrow"), scalar $cur->param("toborrow")); + $self->{"cols"}->addstr("review", $self->_form("review"), scalar $cur->param("review")); + $self->{"cols"}->addstr("comment", $self->_form("comment"), scalar $cur->param("comment")); + $self->{"cols"}->addstr("lib", $self->_form("lib"), scalar $cur->param("lib")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a book \"" . $form->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the book \"" . $form->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the book \"" . $cur->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This book was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This book has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This book has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This book has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Processor/Legend.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Processor/Legend.pm new file mode 100644 index 0000000..0f6fdab --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Processor/Legend.pm @@ -0,0 +1,191 @@ +# Mandy Wu's Website +# Legend.pm: The blog article data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-15 + +package Selima::emandy::Processor::Legend; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor::Guestbook); + +use Selima::DataVars qw($DBH :addcol); +use Selima::Format; +use Selima::Guest; +use Selima::ShortCut; + +use Selima::emandy::Rebuild; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "legend" if @_ < 2; + $self = $class->SUPER::new(@_); + $self->{"form_cols"} = [qw(title body)]; + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("body", $self->_form("body")); + $self->{"cols"}->addbool("html", $self->_form("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + $self->{"cols"}->addnum("pageno", 1); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("body", $self->_form("body"), scalar $cur->param("body")); + $self->{"cols"}->addbool("html", $self->_form("html"), scalar $cur->param("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + } + return; +} + +# _update_cols: Update the columns +sub _update_cols : method { + local ($_, %_); + my $self; + ($self, @_) = @_; + $self->{"curlast"} = $self->_last_page; + $self->SUPER::_update_cols(@_); + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my $self; + $self = $_[0]; + # A form to create a new item + return gactlog "Create a legend entry on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the legend entry on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the legend entry on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This legend entry was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This legend entry has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This legend entry has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This legend entry has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +# _rebuild_partial_pages: Rebuild a limited part of pages +sub _rebuild_partial_pages : method { + local ($_, %_); + my ($self, $form, $cur); + my ($pageno, $is_rebuild); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + + # Check if there is any shown part affected + $is_rebuild = 0; + # A form to create a new item + if ($self->{"type"} eq "new") { + $is_rebuild = 1 unless defined $form->param("hid"); + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $is_rebuild = 1 unless defined $form->param("hid"); + $is_rebuild = 1 unless $cur->param("hid"); + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $is_rebuild = 1 unless $cur->param("hid"); + } + # Nothing to rebuild when no shown parts are modified + return unless $is_rebuild; + + # Find the page number of the current entry + $self->{"newlast"} = $self->_last_page; + # Remove the unwanted pages + $self->_remove_curfile; + $pageno = ($self->{"type"} eq "new")? + $self->{"newlast"}: $cur->param("pageno"); + # If last page changed, we build from its previous page + if ($self->{"curlast"} < $self->{"newlast"}) { + $pageno = $self->{"curlast"} - 1 if $pageno > $self->{"curlast"} - 1; + } elsif ($self->{"curlast"} > $self->{"newlast"}) { + $pageno = $self->{"newlast"} - 1 if $pageno > $self->{"newlast"} - 1; + } + + # Rebuild the pages + rebuild_legend $pageno; + return; +} + +# _remove_curfile: Remove the unwanted page +sub _remove_curfile : method { + local ($_, %_); + my $self; + $self = $_[0]; + for ($_ = $self->{"curlast"}; $_ > $self->{"newlast"}; $_--) { + grmoldfile sprintf "/legend/%04d.html", $_; + } + return; +} + +# _last_page: Find the current last page +sub _last_page : method { + local ($_, %_); + my ($self, $sql, $sth); + $self = $_[0]; + $sql = "SELECT pageno FROM " . $self->{"table"} + . " WHERE NOT hid" + . " ORDER BY pageno DESC LIMIT 1;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return 1 if $sth->rows == 0; + return ${$sth->fetchrow_hashref}{"pageno"}; +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Processor/Material.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Processor/Material.pm new file mode 100644 index 0000000..8211d90 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Processor/Material.pm @@ -0,0 +1,117 @@ +# Mandy Wu's Website +# Material.pm: The historical material data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-23 + +package Selima::emandy::Processor::Material; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw($DBH :addcol); +use Selima::Format; +use Selima::Guest; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "material" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("type", $self->_form("type")); + $self->{"cols"}->addnum("year", $self->_form("year")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("body", $self->_form("body")); + $self->{"cols"}->addstr("source", $self->_form("source")); + $self->{"cols"}->addstr("author", $self->_form("author")); + $self->{"cols"}->addstr("notes", $self->_form("notes")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("type", $self->_form("type"), scalar $cur->param("type")); + $self->{"cols"}->addnum("year", $self->_form("year"), scalar $cur->param("year")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("body", $self->_form("body"), scalar $cur->param("body")); + $self->{"cols"}->addstr("source", $self->_form("source"), scalar $cur->param("source")); + $self->{"cols"}->addstr("author", $self->_form("author"), scalar $cur->param("author")); + $self->{"cols"}->addstr("notes", $self->_form("notes"), scalar $cur->param("notes")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a material \"" . $form->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the material \"" . $form->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the material \"" . $cur->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This material was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This material has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This material has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This material has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm new file mode 100644 index 0000000..8f9e369 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm @@ -0,0 +1,107 @@ +# Mandy Wu's Website +# MtrlType.pm: The historical material type data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-23 + +package Selima::emandy::Processor::MtrlType; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw($DBH :addcol); +use Selima::Format; +use Selima::Guest; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "mtrltype" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("ord", $self->_form("ord")); + $self->{"cols"}->addstr("title", $self->_form("title")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("ord", $self->_form("ord"), scalar $cur->param("ord")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a material type \"" . $form->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the material type \"" . $form->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the material type \"" . $cur->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This type was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This type has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This type has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This type has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Rebuild.pm b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Rebuild.pm new file mode 100644 index 0000000..d089066 --- /dev/null +++ b/htdocs/emandy/magicat/lib/perl5/Selima/emandy/Rebuild.pm @@ -0,0 +1,436 @@ +# Mandy Wu's Website +# Rebuild.pm: The subroutines to rebuild the web pages. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-14 + +package Selima::emandy::Rebuild; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(rebuild_all rebuild_pages rebuild_links rebuild_legend compose_page); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub rebuild_all(); +sub rebuild_pages(;$); +sub rebuild_links(;$); +sub rebuild_legend(;$); +sub compose_page($;$); +} + +use Config qw(%Config); +use Data::Dumper qw(); +use Fcntl qw(:flock); +use File::Basename qw(basename); +use IO::NestedCapture qw(CAPTURE_STDOUT); +use Lingua::ZH::Numbers; + +use Selima::DataVars qw($DBH :output :rebuild :requri); +use Selima::GetLang; +use Selima::Guest; +use Selima::PageFunc; +use Selima::ShortCut; + +use Selima::emandy::HTML; + +use vars qw($PKGL10N); + +# rebuild_all: Rebuild everything +sub rebuild_all() { + local ($_, %_); + # Lock the required tables + $DBH->lock(map { $_ => LOCK_SH } @REBUILD_TABLES); + # Rebuild the pages + rebuild_pages; + # Rebuild the links + rebuild_links; + # Rebuild the legend + rebuild_legend; + # Rebuild the index + # To be done + #rebuild_index; + return; +} + +# rebuild_pages: Rebuild the pages +sub rebuild_pages(;$) { + local ($_, %_); + my ($sql, $sth, $count, $rebuild_everything); + my $lang; + $sql = $_[0]; + + $lang = getlang; + + # Rebuild everything + $rebuild_everything = !defined $sql; + if ($rebuild_everything) { + $sql = "SELECT * FROM pages" + . " WHERE NOT hid;\n"; + } + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + # Bounce if no pages to build on a partial rebuild + # This prevents needless sitemap rebuilding + return if !$rebuild_everything && $count == 0; + # Build each page + for (my $i = 0; $i < $count; $i++) { + my ($page, $html); + $page = $sth->fetchrow_hashref; + # Read the picture into the picture deposit + # To be done + + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + + # Output related pictures only when rebuilding everything + # To be done + } + + return; +} + +# rebuild_links: Rebuild the links +sub rebuild_links(;$) { + local ($_, %_); + my ($sql, $sth, $count, $FD, $rebuild_everything); + my ($lang, $args, $html); + $sql = $_[0]; + + $lang = getlang; + + # Rebuild everything + $rebuild_everything = !defined $sql; + if ($rebuild_everything) { + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_isshown(sn, hid, parent);\n"; + } + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0; $i < $count; $i++) { + my ($page, $sql1, $sth1, $count1, $row1); + $page = $sth->fetchrow_hashref; + + # Find the ancesters + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql1 = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_ischild(sn, " . $$page{"sn"} . ")" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"parents"} = []; $i < $count1; $i++) { + push @{$$page{"parents"}}, $sth1->fetchrow_hashref; + } + + # Find the subcategories + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql1 = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE parent=" . $$page{"sn"} + . " AND linkcat_isshown(sn, hid, parent)" + . " ORDER BY ord;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"scats"} = []; $i < $count1; $i++) { + my ($sql2, $sth2, $row2); + $row1 = $sth1->fetchrow_hashref; + # Find the belonging links + $sql2 = "SELECT count(linkcatz.sn) AS count FROM linkcatz" + . " INNER JOIN links ON linkcatz.link=links.sn" + . " INNER JOIN linkcat ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.cat=" . $$row1{"sn"} + . " AND NOT links.hid;\n"; + $sth2 = $DBH->prepare($sql2); + $sth2->execute; + $row2 = $sth2->fetchrow_hashref; + $$row1{"links"} = $$row2{"count"}; + push @{$$page{"scats"}}, $row1; + } + + # Find the belonging links + @_ = map "links.$_", $DBH->cols("links"); + $sql1 = "SELECT " . join(", ", @_) . " FROM links" + . " INNER JOIN linkcatz ON linkcatz.link=links.sn" + . " WHERE linkcatz.cat=" . $$page{"sn"} + . " AND NOT links.hid;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"links"} = []; $i < $count1; $i++) { + push @{$$page{"links"}}, $sth1->fetchrow_hashref; + } + + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + } + + # Build the root index page + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE parent IS NULL" + . " AND linkcat_isshown(sn, hid, parent)" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @_ = qw(); $_ < $count; $_++) { + my ($cat, $sql1, $sth1, $count1); + $cat = $sth->fetchrow_hashref; + + # Find the belonging links + $sql1 = "SELECT count(linkcatz.sn) AS count FROM linkcatz" + . " INNER JOIN links ON linkcatz.link=links.sn" + . " INNER JOIN linkcat ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.cat=" . $$cat{"sn"} + . " AND NOT links.hid;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $$cat{"links"} = ${$sth1->fetch}[0]; + + push @_, $cat; + } + $ALT_PAGE_PARAM = { + "path" => "/links/", + "lang" => $lang, + "keywords" => __("related links"), + "class" => "links", + "static" => 1, + "all_linguas" => [$lang]}; + $args = page_param; + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header __("Related Links"), $args; + html_links_index @_, $args; + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $html = join "", <$FD>; + undef $ALT_PAGE_PARAM; + goutpage $html, "/links/", $lang; + + return; +} + +# rebuild_legend: Rebuild the legend +sub rebuild_legend(;$) { + local ($_, %_); + my ($start, $sql, $sth, $count, $FD, $page, @pages, $total); + my ($lang, $args, $html); + $start = $_[0]; + $start = 1 if !defined $start; + + $lang = getlang; + + # Obtain the total number of legend entries + $_ = "SELECT count(*) FROM legend WHERE NOT hid;\n"; + $sth = $DBH->prepare($_); + $sth->execute; + $total = ${$sth->fetch}[0]; + + # Obtain all the available pages numbers + @_ = qw(); + push @_, "pageno AS no"; + push @_, "legend_page_start(pageno) AS start"; + push @_, "legend_page_end(pageno) AS end"; + $sql = "SELECT " . join(", ", @_) . " FROM legend" + . " WHERE NOT hid GROUP BY pageno ORDER BY pageno;\n"; + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @pages = qw(); $i < $count; $i++) { + $page = $sth->fetchrow_hashref; + $$page{"path"} = sprintf "/legend/%04d.html", $$page{"no"}; + push @pages, $page; + } + + # Build each page + foreach my $page (@pages) { + next if $$page{"no"} < $start; + + my ($args, $LIST, $html, $FD); + Lingua::ZH::Numbers->charset("traditional"); + $_ = number_to_zh($$page{"no"}); + $$page{"title"} = sprintf __("Legend Volume %s"), $_; + $$page{"kw"} = __("legend"); + $ALT_PAGE_PARAM = { + "path" => $$page{"path"}, + "lang" => $lang, + "keywords" => $$page{"kw"}, + "class" => "legend", + "static" => 1, + "all_linguas" => [$lang]}; + $args = page_param; + # Set the list parameter + $LIST = new Selima::emandy::List::Legend::Public; + $LIST->{"view"} = "legend_public"; + $LIST->{"pageno"} = $$page{"no"}; + $LIST->{"lastpage"} = ${$pages[$#pages]}{"no"}; + $LIST->{"total"} = $total; + $args = {%$args, %{$LIST->page_param}}; + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header $$page{"title"}, $args; + $LIST->html($args); + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $html = join "", <$FD>; + undef $ALT_PAGE_PARAM; + goutpage $html, $$page{"path"}, $lang; + + # Make the symbolic link for the default language + if (defined $Config{"d_symlink"}) { + my ($targfile, $linkfile); + $_ = $$page{"path"}; + $_ .= "index.html" if /\/$/; + $targfile = basename($_ . ".xhtml"); + $linkfile = "$DOC_ROOT$_.html"; + unless (-l $linkfile && readlink $linkfile eq $targfile) { + unlink $linkfile if -l $linkfile; + symlink $targfile, $linkfile; + } + } + } + + # Make the symbolic link for the latest page + if (defined $Config{"d_symlink"}) { + my ($targfile, $linkfile); + if (@pages > 0) { + $targfile = sprintf "%04d.html.xhtml", + ${$pages[$#pages]}{"no"}; + } else { + $targfile = "index.html.xhtml"; + } + $linkfile = "$DOC_ROOT/legend/latest.html.xhtml"; + unless (-l $linkfile && readlink $linkfile eq $targfile) { + unlink $linkfile if -l $linkfile; + symlink $targfile, $linkfile; + } + $targfile = "latest.html.xhtml"; + $linkfile = "$DOC_ROOT/legend/latest.html.html"; + unless (-l $linkfile && readlink $linkfile eq $targfile) { + unlink $linkfile if -l $linkfile; + symlink $targfile, $linkfile; + } + } + + # Build the root index page + $ALT_PAGE_PARAM = { + "path" => "/legend/", + "lang" => $lang, + "keywords" => __("legend"), + "class" => "legend", + "static" => 1, + "all_linguas" => [$lang], + "toc" => ".."}; + if (@pages > 0) { + $$ALT_PAGE_PARAM{"first"} = "0001.html"; + $$ALT_PAGE_PARAM{"last"} = "latest.html"; + ${$pages[$#pages]}{"path"} = "/legend/latest.html"; + } + $args = page_param; + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header __("Legend"), $args; + html_legend_index @pages, $args; + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $html = join "", <$FD>; + undef $ALT_PAGE_PARAM; + goutpage $html, "/legend/", $lang; + + # Make the symbolic link for the default language + if (defined $Config{"d_symlink"}) { + my ($targfile, $linkfile); + $_ = "/legend/index.html"; + $targfile = basename($_ . ".xhtml"); + $linkfile = "$DOC_ROOT$_.html"; + unless (-l $linkfile && readlink $linkfile eq $targfile) { + unlink $linkfile if -l $linkfile; + symlink $targfile, $linkfile; + } + } + + return; +} + +# compose_page: Compose a page +sub compose_page($;$) { + local ($_, %_); + my ($page, $lang, $args, $FD); + ($page, $lang) = @_; + $lang = getlang if !defined $lang; + + $ALT_PAGE_PARAM = { + "path" => $$page{"path"}, + "lang" => $lang, + "keywords" => $$page{"kw"}, + "static" => 1, + "all_linguas" => [$lang]}; + $$ALT_PAGE_PARAM{"preview"} = $page + if exists $$page{"preview"}; + if (exists $$page{"class"} && defined $$page{"class"} && $$page{"class"} ne "") { + $$ALT_PAGE_PARAM{"class"} = $$page{"class"}; + } elsif ($$page{"path"} =~ /^\/links\//) { + $$ALT_PAGE_PARAM{"class"} = "links"; + } + $args = page_param; + + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header $$page{"title"}, $args; + if ($$page{"path"} =~ /^\/links\/$/) { + #html_links_index $page, $args; + } elsif ($$page{"path"} =~ /^\/links\/.+$/) { + html_links $page, $args; + } else { + html_body $page, $args; + } + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + + undef $ALT_PAGE_PARAM; + return $_; +} + +return 1; diff --git a/htdocs/emandy/magicat/locale/zh_TW/LC_MESSAGES/emandy.mo b/htdocs/emandy/magicat/locale/zh_TW/LC_MESSAGES/emandy.mo new file mode 100644 index 0000000..3c480df Binary files /dev/null and b/htdocs/emandy/magicat/locale/zh_TW/LC_MESSAGES/emandy.mo differ diff --git a/htdocs/emandy/magicat/po/Makefile b/htdocs/emandy/magicat/po/Makefile new file mode 100644 index 0000000..5dcb989 --- /dev/null +++ b/htdocs/emandy/magicat/po/Makefile @@ -0,0 +1,45 @@ +# Possible make targets: +# all: Compile the PO files and copy the binary MO files +# into the appropriate directories +# xgettext: Obtain the newest PO template file $(PACKAGE).pot +# from the source programs +# msgmerge: Compare the template $(PACKAGE).pot and the existing +# PO files and get the newest POX files to work with. + + +PACKAGE = emandy +ALLLINGUAS = zh_TW +PKGROOT = ../.. +PODIR = magicat/po +LOCALEDIR = $(PKGROOT)/magicat/locale +CATEGORY = LC_MESSAGES +#PROGRAMS = cgi-bin/*.cgi magicat/cgi-bin/*.cgi magicat/lib/perl5/*/*.pm magicat/lib/perl5/*/*/*.pm magicat/lib/perl5/*/*/*/*.pm magicat/lib/perl5/*/*/*/*/*.pm +PROGRAMS = magicat/cgi-bin/*.cgi magicat/lib/perl5/*/*.pm magicat/lib/perl5/*/*/*.pm magicat/lib/perl5/*/*/*/*.pm magicat/lib/perl5/*/*/*/*/*.pm + +all: + for ln in $(ALLLINGUAS); do \ + msgfmt $$ln.po -o $$ln.gmo; \ + test -d $(LOCALEDIR) || \ + (rm -rf $(LOCALEDIR) && \ + mkdir $(LOCALEDIR)); \ + test -d $(LOCALEDIR)/$$ln || \ + (rm -rf $(LOCALEDIR)/$$ln && \ + mkdir $(LOCALEDIR)/$$ln); \ + test -d $(LOCALEDIR)/$$ln/$(CATEGORY) || \ + (rm -rf $(LOCALEDIR)/$$ln/$(CATEGORY) && \ + mkdir $(LOCALEDIR)/$$ln/$(CATEGORY)); \ + rm -f $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + cp $$ln.gmo $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + done + +xgettext: + cd $(PKGROOT); \ + xgettext --keyword=__ --keyword=N_ -p $(PODIR)/ -o $(PACKAGE).pot \ + --language=c $(PROGRAMS); \ + cd $(PODIR); \ + for ln in $(ALLLINGUAS); do \ + msgmerge $$ln.po $(PACKAGE).pot > $$ln.pox; \ + done + +clean: + rm -f *.gmo diff --git a/htdocs/emandy/magicat/po/emandy.pot b/htdocs/emandy/magicat/po/emandy.pot new file mode 100644 index 0000000..93a50fe --- /dev/null +++ b/htdocs/emandy/magicat/po/emandy.pot @@ -0,0 +1,1069 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-25 01:36+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: magicat/cgi-bin/acctrecs.cgi:30 magicat/cgi-bin/acctreps.cgi:26 +#: magicat/cgi-bin/acctsubj.cgi:28 magicat/cgi-bin/accttrx.cgi:29 +msgid "accounting" +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:94 magicat/cgi-bin/acctrecs.cgi:139 +#: magicat/cgi-bin/acctsubj.cgi:104 magicat/cgi-bin/acctsubj.cgi:162 +#: magicat/cgi-bin/accttrx.cgi:93 magicat/cgi-bin/accttrx.cgi:138 +#: magicat/cgi-bin/books.cgi:94 magicat/cgi-bin/books.cgi:145 +#: magicat/cgi-bin/groupmem.cgi:94 magicat/cgi-bin/groupmem.cgi:139 +#: magicat/cgi-bin/groups.cgi:102 magicat/cgi-bin/groups.cgi:151 +#: magicat/cgi-bin/legend.cgi:94 magicat/cgi-bin/legend.cgi:143 +#: magicat/cgi-bin/linkcat.cgi:101 magicat/cgi-bin/linkcat.cgi:154 +#: magicat/cgi-bin/linkcatz.cgi:94 magicat/cgi-bin/linkcatz.cgi:139 +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:137 +#: magicat/cgi-bin/material.cgi:95 magicat/cgi-bin/material.cgi:146 +#: magicat/cgi-bin/mtrltype.cgi:99 magicat/cgi-bin/mtrltype.cgi:152 +#: magicat/cgi-bin/pages.cgi:96 magicat/cgi-bin/pages.cgi:140 +#: magicat/cgi-bin/scptpriv.cgi:92 magicat/cgi-bin/scptpriv.cgi:137 +#: magicat/cgi-bin/usermem.cgi:94 magicat/cgi-bin/usermem.cgi:139 +#: magicat/cgi-bin/userpref.cgi:92 magicat/cgi-bin/userpref.cgi:137 +#: magicat/cgi-bin/users.cgi:111 magicat/cgi-bin/users.cgi:175 +msgid "Incorrect form: [_1]." +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:186 +msgid "Please select the accounting record." +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:194 +msgid "" +"This accounting record does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:77 magicat/cgi-bin/acctsubj.cgi:122 +msgid "Please add a new accounting subject from [_1]." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:93 magicat/cgi-bin/acctsubj.cgi:151 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the subject, " +"[numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] " +"must first be deleted." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:97 magicat/cgi-bin/acctsubj.cgi:155 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the subject, [numerate,_1,its " +"accounting record,all of its accounting records] must first be deleted." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:214 +msgid "Please select the accounting subject." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:222 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/accttrx.cgi:185 +msgid "Please select the accounting transaction." +msgstr "" + +#: magicat/cgi-bin/accttrx.cgi:193 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "" + +#: magicat/cgi-bin/actlog.cgi:22 +msgid "activity, logs" +msgstr "" + +#: magicat/cgi-bin/books.cgi:26 +msgid "books" +msgstr "" + +#: magicat/cgi-bin/books.cgi:75 magicat/cgi-bin/books.cgi:112 +msgid "Please create a new book from [_1]." +msgstr "" + +#: magicat/cgi-bin/books.cgi:198 +msgid "Please select the book." +msgstr "" + +#: magicat/cgi-bin/books.cgi:206 +msgid "This book does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:30 +msgid "group membership" +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:186 magicat/cgi-bin/usermem.cgi:186 +msgid "Please select the membership record." +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:194 magicat/cgi-bin/usermem.cgi:194 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/groups.cgi:34 +msgid "groups" +msgstr "" + +#: magicat/cgi-bin/groups.cgi:198 +msgid "Please select the group." +msgstr "" + +#: magicat/cgi-bin/groups.cgi:206 +msgid "This group does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/legend.cgi:26 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:274 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:342 +msgid "legend" +msgstr "" + +#: magicat/cgi-bin/legend.cgi:75 magicat/cgi-bin/legend.cgi:112 +msgid "Please write a new legend entry from [_1]." +msgstr "" + +#: magicat/cgi-bin/legend.cgi:190 +msgid "Please select the legend entry." +msgstr "" + +#: magicat/cgi-bin/legend.cgi:198 +msgid "This legend entry does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:29 +msgid "link categories" +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:90 magicat/cgi-bin/linkcat.cgi:143 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:94 magicat/cgi-bin/linkcat.cgi:147 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:202 +msgid "Please select the category." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:210 +msgid "This category does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:30 +msgid "link categorization" +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:186 +msgid "Please select the categorization record." +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:194 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "" + +#: magicat/cgi-bin/links.cgi:28 magicat/lib/perl5/Selima/emandy/Rebuild.pm:213 +msgid "related links" +msgstr "" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Please select the related link." +msgstr "" + +#: magicat/cgi-bin/links.cgi:193 +msgid "This related link does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/logout.cgi:25 +msgid "log out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:98 magicat/cgi-bin/logout.cgi:105 +msgid "Log Out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:121 +msgid "Are you sure you want to log out?" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:122 magicat/lib/perl5/Selima/emandy/HTML.pm:377 +msgid "Log out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:138 +msgid "Log in again." +msgstr "" + +#: magicat/cgi-bin/material.cgi:27 magicat/cgi-bin/mtrltype.cgi:27 +msgid "materials" +msgstr "" + +#: magicat/cgi-bin/material.cgi:76 magicat/cgi-bin/material.cgi:113 +msgid "Please create a new material from [_1]." +msgstr "" + +#: magicat/cgi-bin/material.cgi:193 +msgid "Please select the material." +msgstr "" + +#: magicat/cgi-bin/material.cgi:201 +msgid "This material does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/mtrltype.cgi:76 magicat/cgi-bin/mtrltype.cgi:117 +msgid "Please create a new type from [_1]." +msgstr "" + +#: magicat/cgi-bin/mtrltype.cgi:92 magicat/cgi-bin/mtrltype.cgi:145 +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:73 +msgid "" +"This type has [numerate,_1,a material,materials]. It cannot be deleted. To " +"delete the type, [numerate,_1,its material,all of its materials] must first " +"be deleted." +msgstr "" + +#: magicat/cgi-bin/mtrltype.cgi:199 +msgid "Please select the type." +msgstr "" + +#: magicat/cgi-bin/mtrltype.cgi:207 +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:40 +msgid "This type does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/pages.cgi:26 +msgid "pages" +msgstr "" + +#: magicat/cgi-bin/pages.cgi:193 +msgid "Please select the page." +msgstr "" + +#: magicat/cgi-bin/pages.cgi:201 +msgid "This page does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/rebuild.cgi:23 +msgid "rebuild pages" +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:28 +msgid "script privilege" +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:184 +msgid "Please select the script privilege record." +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:192 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "" + +#: magicat/cgi-bin/usermem.cgi:30 +msgid "user membership" +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:28 +msgid "user preference" +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:184 +msgid "Please select the user preference." +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:192 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/users.cgi:29 +msgid "users" +msgstr "" + +#: magicat/cgi-bin/users.cgi:222 +msgid "Please select the user." +msgstr "" + +#: magicat/cgi-bin/users.cgi:230 +msgid "This user does not exist anymore. Please select another one." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Config.pm:49 +#: magicat/lib/perl5/Selima/emandy/HTML.pm:65 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:356 +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:145 +msgid "Legend" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:63 +msgid "Manage Content" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:67 +msgid "Books" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:69 +msgid "Materials" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:71 +msgid "Material Types" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:73 +msgid "Pages" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:75 +msgid "Links" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:77 +msgid "Link Categories" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:79 +msgid "Link Categorization" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:83 +msgid "Manage Accounts" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:85 +msgid "Users" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:87 +msgid "Groups" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:89 +msgid "User Membership" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:91 +msgid "Group Membership" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:93 +msgid "User Preferences" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:95 +msgid "Script Privileges" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:99 +msgid "Manage Accounting" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:101 +msgid "Transactions" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:103 +msgid "Reports" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:105 +msgid "Subjects" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:107 +msgid "Records" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:111 +msgid "Miscellaneous" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:113 +msgid "Activity Log" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:115 +msgid "Rebuild Pages" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:117 +msgid "Analog" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:119 +msgid "Test Script" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:166 +msgid "Skip to the page content area." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:167 +msgid "Page Content Area" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:300 +msgid "Navigation Links Area" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:375 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:410 +#, c-format +msgid "%s:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:480 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:221 +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:136 +msgid "Related Links" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:491 +msgid "Subcategories:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:506 +msgid "E-mail" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:531 +msgid "URL:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:534 +msgid "E-mail:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:540 +msgid "Address:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:542 +msgid "Tel.:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:544 +msgid "Fax.:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:569 +msgid "The database is empty." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:603 +msgid "The legend is empty." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:608 +msgid "Index" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:618 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:273 +#, c-format +msgid "Legend Volume %s" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:678 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:679 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:692 +msgid "" +"This script is written in Perl." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:43 +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:116 +msgid "This author is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:64 +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:60 +msgid "This year is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:68 +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:64 +msgid "Please fill in a positive integer year." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:92 +msgid "This publisher is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:113 +msgid "This origin is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:133 +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:100 +msgid "Fill in the review here." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:136 +msgid "This review is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:156 +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:106 +msgid "Fill in the comment here." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:159 +msgid "This comment is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:179 +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:112 +msgid "Fill in the libraries here." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:182 +msgid "This libraries is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:92 +msgid "Please fill in the source." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:95 +msgid "This source is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:136 +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:95 +msgid "Fill in the notes here." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:139 +msgid "This notes is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:32 +msgid "Delete this book" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:37 +msgid "This table provides you a form to add a new book." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:40 +msgid "This table provides you a form to edit a current book." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:43 +msgid "This table provides you a form to delete a book." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:61 +msgid "Add a New Book" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:64 +msgid "Edit a Current Book" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:67 +msgid "Delete a Book" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:77 +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:84 +msgid "Year:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:82 +msgid "Publisher:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:87 +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:37 +msgid "To be borrowed?" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:88 +msgid "To be borrowed" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:88 +msgid "Not to be borrowed" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:89 +msgid "This book is to be borrowed." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:94 +msgid "Origin:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:99 +msgid "Review:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:105 +msgid "Comment:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:111 +msgid "Libraries:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:32 +msgid "Delete this legend entry" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:37 +msgid "This table provides you a form to write a new legend entry." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:40 +msgid "This table provides you a form to edit a current legend entry." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:43 +msgid "This table provides you a form to delete a legend entry." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:60 +msgid "Write a New Legend Entry" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:63 +msgid "Edit a Current Legend Entry" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:66 +msgid "Delete a Legend Entry" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:75 +msgid "Hide?" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:76 +msgid "Hide this legend entry" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:76 +msgid "Show this legend entry" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:77 +msgid "Hide this legend entry currently." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:82 +msgid "Page No.:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:34 +msgid "Delete this material" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:39 +msgid "This table provides you a form to add a new material." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:42 +msgid "This table provides you a form to edit a current material." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:45 +msgid "This table provides you a form to delete a material." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:63 +msgid "Add a New Material" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:66 +msgid "Edit a Current Material" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:69 +msgid "Delete a Material" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:79 +msgid "Type:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:89 +msgid "Source:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:94 +msgid "Notes:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:32 +msgid "Delete this type" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:37 +msgid "This table provides you a form to add a new type." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:40 +msgid "This table provides you a form to edit a current type." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:43 +msgid "This table provides you a form to delete a type." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:59 +msgid "Add a New Material Type" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:62 +msgid "Edit a Current Material Type" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:65 +msgid "Delete a Material Type" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:25 +#: magicat/lib/perl5/Selima/emandy/List/Books/NotToBorrow.pm:24 +#: magicat/lib/perl5/Selima/emandy/List/Books/ToBorrow.pm:24 +msgid "Select a Book" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:26 +msgid "Manage Books" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:33 +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:35 +msgid "Author" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:34 +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:33 +msgid "Year" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:35 +msgid "Origin" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:36 +msgid "Publisher" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:38 +msgid "Review" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:39 +msgid "Comment" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:40 +msgid "Libraries" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:45 +msgid "Books not to be borrowed" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:47 +msgid "Books to be borrowed" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:49 +msgid "All books" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:57 +msgid "Add a new book." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:63 +msgid "Search for a book:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:80 +msgid "Your query found [*,_1,book]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:83 +msgid "[*,_1,book]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:89 +msgid "Your query found [*,_1,book], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:93 +msgid "[*,_1,book], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:24 +msgid "Select a Legend Entry" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:25 +msgid "Manage Legend" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:36 +msgid "Page No." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:44 +msgid "Write a new legend entry." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:50 +msgid "Search for a legend entry:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:67 +msgid "Your query found [*,_1,legend entry,legend entries]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:70 +msgid "[*,_1,legend entry,legend entries]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:76 +msgid "" +"Your query found [*,_1,legend entry,legend entries], listing [#,_2] to [#," +"_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:80 +msgid "[*,_1,legend entry,legend entries], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:24 +msgid "Select a Material" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:25 +msgid "Manage Materials" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:32 +msgid "Type" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:34 +msgid "Source" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:36 +msgid "Notes" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:44 +msgid "Add a new material." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:50 +msgid "Search for a material:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:67 +msgid "Your query found [*,_1,material]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:70 +msgid "[*,_1,material]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:76 +msgid "Your query found [*,_1,material], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:80 +msgid "[*,_1,material], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:24 +msgid "Select a Material Type" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:25 +msgid "Manage Material Types" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:37 +msgid "Add a new type." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:43 +msgid "Search for a type:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:60 +msgid "Your query found [*,_1,type]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:63 +msgid "[*,_1,type]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:69 +msgid "Your query found [*,_1,type], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:73 +msgid "[*,_1,type], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:24 +msgid "Full Text Search" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:26 +msgid "Search Result" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:49 +msgid "Please fill in your query." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:71 +msgid "Search in the website:" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:88 +msgid "Your query found [*,_1,article]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:91 +msgid "[*,_1,article]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:97 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:101 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/Book.pm:90 +msgid "This book was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/Book.pm:94 +msgid "This book has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/Book.pm:98 +msgid "This book has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/Book.pm:102 +msgid "This book has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/Legend.pm:93 +msgid "This legend entry was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/Legend.pm:97 +msgid "This legend entry has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/Legend.pm:101 +msgid "This legend entry has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/Legend.pm:105 +msgid "This legend entry has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/Material.pm:86 +msgid "This material was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/Material.pm:90 +msgid "This material has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/Material.pm:94 +msgid "This material has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/Material.pm:98 +msgid "This material has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm:76 +msgid "This type was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm:80 +msgid "This type has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm:84 +msgid "This type has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm:88 +msgid "This type has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books/NotToBorrow.pm:25 +msgid "Manage Books Not to Be Borrowed" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Books/ToBorrow.pm:25 +msgid "Manage Books to be Borrowed" +msgstr "" + +#: magicat/lib/perl5/Selima/emandy/List/Legend/Public.pm:131 +msgid "The legend entry seperator" +msgstr "" diff --git a/htdocs/emandy/magicat/po/zh_TW.gmo b/htdocs/emandy/magicat/po/zh_TW.gmo new file mode 100644 index 0000000..3c480df Binary files /dev/null and b/htdocs/emandy/magicat/po/zh_TW.gmo differ diff --git a/htdocs/emandy/magicat/po/zh_TW.po b/htdocs/emandy/magicat/po/zh_TW.po new file mode 100644 index 0000000..ca34e8b --- /dev/null +++ b/htdocs/emandy/magicat/po/zh_TW.po @@ -0,0 +1,1078 @@ +# Traditional Chinese PO file for the eMandy website +# Copyright (C) 2004-2018 imacat +# This file is distributed under the same license as the emandy package. +# imacat , 2004-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: emandy 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-25 01:36+0800\n" +"PO-Revision-Date: 2018-11-02 00:56+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: magicat/cgi-bin/acctrecs.cgi:30 magicat/cgi-bin/acctreps.cgi:26 +#: magicat/cgi-bin/acctsubj.cgi:28 magicat/cgi-bin/accttrx.cgi:29 +msgid "accounting" +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:94 magicat/cgi-bin/acctrecs.cgi:139 +#: magicat/cgi-bin/acctsubj.cgi:104 magicat/cgi-bin/acctsubj.cgi:162 +#: magicat/cgi-bin/accttrx.cgi:93 magicat/cgi-bin/accttrx.cgi:138 +#: magicat/cgi-bin/books.cgi:94 magicat/cgi-bin/books.cgi:145 +#: magicat/cgi-bin/groupmem.cgi:94 magicat/cgi-bin/groupmem.cgi:139 +#: magicat/cgi-bin/groups.cgi:102 magicat/cgi-bin/groups.cgi:151 +#: magicat/cgi-bin/legend.cgi:94 magicat/cgi-bin/legend.cgi:143 +#: magicat/cgi-bin/linkcat.cgi:101 magicat/cgi-bin/linkcat.cgi:154 +#: magicat/cgi-bin/linkcatz.cgi:94 magicat/cgi-bin/linkcatz.cgi:139 +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:137 +#: magicat/cgi-bin/material.cgi:95 magicat/cgi-bin/material.cgi:146 +#: magicat/cgi-bin/mtrltype.cgi:99 magicat/cgi-bin/mtrltype.cgi:152 +#: magicat/cgi-bin/pages.cgi:96 magicat/cgi-bin/pages.cgi:140 +#: magicat/cgi-bin/scptpriv.cgi:92 magicat/cgi-bin/scptpriv.cgi:137 +#: magicat/cgi-bin/usermem.cgi:94 magicat/cgi-bin/usermem.cgi:139 +#: magicat/cgi-bin/userpref.cgi:92 magicat/cgi-bin/userpref.cgi:137 +#: magicat/cgi-bin/users.cgi:111 magicat/cgi-bin/users.cgi:175 +msgid "Incorrect form: [_1]." +msgstr "查無此表格: [_1] 。" + +#: magicat/cgi-bin/acctrecs.cgi:186 +msgid "Please select the accounting record." +msgstr "請選擇會計分錄。" + +#: magicat/cgi-bin/acctrecs.cgi:194 +msgid "" +"This accounting record does not exist anymore. Please select another one." +msgstr "查無此會計分錄,請重新選擇。" + +#: magicat/cgi-bin/acctsubj.cgi:77 magicat/cgi-bin/acctsubj.cgi:122 +msgid "Please add a new accounting subject from [_1]." +msgstr "請由[_1]建新會計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:93 magicat/cgi-bin/acctsubj.cgi:151 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the subject, " +"[numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] " +"must first be deleted." +msgstr "" +"本會計科目下有子會計科目,不可直接刪除。要刪除本會計科目,請先刪除其下的子會" +"計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:97 magicat/cgi-bin/acctsubj.cgi:155 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the subject, [numerate,_1,its " +"accounting record,all of its accounting records] must first be deleted." +msgstr "" +"本會計科目下有會計分錄,不可直接刪除。要刪除本會計科目,請先刪除其下的會計分" +"錄。" + +#: magicat/cgi-bin/acctsubj.cgi:214 +msgid "Please select the accounting subject." +msgstr "請選擇會計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:222 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "查無此會計科目,請重新選擇。" + +#: magicat/cgi-bin/accttrx.cgi:185 +msgid "Please select the accounting transaction." +msgstr "請選擇會計傳票。" + +#: magicat/cgi-bin/accttrx.cgi:193 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "查無此會計傳票,請重新選擇。" + +#: magicat/cgi-bin/actlog.cgi:22 +msgid "activity, logs" +msgstr "活動, 記錄, 日誌" + +#: magicat/cgi-bin/books.cgi:26 +msgid "books" +msgstr "書" + +#: magicat/cgi-bin/books.cgi:75 magicat/cgi-bin/books.cgi:112 +msgid "Please create a new book from [_1]." +msgstr "請由[_1]建新書目。" + +#: magicat/cgi-bin/books.cgi:198 +msgid "Please select the book." +msgstr "請選擇書目。" + +#: magicat/cgi-bin/books.cgi:206 +msgid "This book does not exist anymore. Please select another one." +msgstr "查無此書,請重新選擇。" + +#: magicat/cgi-bin/groupmem.cgi:30 +msgid "group membership" +msgstr "群組成員" + +#: magicat/cgi-bin/groupmem.cgi:186 magicat/cgi-bin/usermem.cgi:186 +msgid "Please select the membership record." +msgstr "請選擇成員關係。" + +#: magicat/cgi-bin/groupmem.cgi:194 magicat/cgi-bin/usermem.cgi:194 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "查無此成員關係,請重新選擇。" + +#: magicat/cgi-bin/groups.cgi:34 +msgid "groups" +msgstr "群組" + +#: magicat/cgi-bin/groups.cgi:198 +msgid "Please select the group." +msgstr "請選擇群組。" + +#: magicat/cgi-bin/groups.cgi:206 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: magicat/cgi-bin/legend.cgi:26 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:274 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:342 +msgid "legend" +msgstr "傳奇" + +#: magicat/cgi-bin/legend.cgi:75 magicat/cgi-bin/legend.cgi:112 +msgid "Please write a new legend entry from [_1]." +msgstr "請由[_1]撰傳奇。" + +#: magicat/cgi-bin/legend.cgi:190 +msgid "Please select the legend entry." +msgstr "請選擇傳奇。" + +#: magicat/cgi-bin/legend.cgi:198 +msgid "This legend entry does not exist anymore. Please select another one." +msgstr "查無該則傳奇,請重新選擇。" + +#: magicat/cgi-bin/linkcat.cgi:29 +msgid "link categories" +msgstr "相關連結分類" + +#: magicat/cgi-bin/linkcat.cgi:90 magicat/cgi-bin/linkcat.cgi:143 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: magicat/cgi-bin/linkcat.cgi:94 magicat/cgi-bin/linkcat.cgi:147 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: magicat/cgi-bin/linkcat.cgi:202 +msgid "Please select the category." +msgstr "請選擇分類。" + +#: magicat/cgi-bin/linkcat.cgi:210 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: magicat/cgi-bin/linkcatz.cgi:30 +msgid "link categorization" +msgstr "連結分類表" + +#: magicat/cgi-bin/linkcatz.cgi:186 +msgid "Please select the categorization record." +msgstr "請選擇分類資料。" + +#: magicat/cgi-bin/linkcatz.cgi:194 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "查無此分類資料,請重新選擇。" + +#: magicat/cgi-bin/links.cgi:28 magicat/lib/perl5/Selima/emandy/Rebuild.pm:213 +msgid "related links" +msgstr "相關連結" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Please select the related link." +msgstr "請選擇要設定的相關連結。" + +#: magicat/cgi-bin/links.cgi:193 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查無該相關連結,請改選其她相關連結。" + +#: magicat/cgi-bin/logout.cgi:25 +msgid "log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:98 magicat/cgi-bin/logout.cgi:105 +msgid "Log Out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:121 +msgid "Are you sure you want to log out?" +msgstr "妳確定要登出嗎?" + +#: magicat/cgi-bin/logout.cgi:122 magicat/lib/perl5/Selima/emandy/HTML.pm:377 +msgid "Log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:138 +msgid "Log in again." +msgstr "重新登入。" + +#: magicat/cgi-bin/material.cgi:27 magicat/cgi-bin/mtrltype.cgi:27 +msgid "materials" +msgstr "史料" + +#: magicat/cgi-bin/material.cgi:76 magicat/cgi-bin/material.cgi:113 +msgid "Please create a new material from [_1]." +msgstr "請由[_1]建新史料。" + +#: magicat/cgi-bin/material.cgi:193 +msgid "Please select the material." +msgstr "請選擇史料。" + +#: magicat/cgi-bin/material.cgi:201 +msgid "This material does not exist anymore. Please select another one." +msgstr "查無此史料,請重新選擇。" + +#: magicat/cgi-bin/mtrltype.cgi:76 magicat/cgi-bin/mtrltype.cgi:117 +msgid "Please create a new type from [_1]." +msgstr "請由[_1]建新類型。" + +#: magicat/cgi-bin/mtrltype.cgi:92 magicat/cgi-bin/mtrltype.cgi:145 +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:73 +msgid "" +"This type has [numerate,_1,a material,materials]. It cannot be deleted. To " +"delete the type, [numerate,_1,its material,all of its materials] must first " +"be deleted." +msgstr "本類型下有史料,不可直接刪除。要刪除本類型,請先刪除其下的史料。" + +#: magicat/cgi-bin/mtrltype.cgi:199 +msgid "Please select the type." +msgstr "請選擇類型。" + +#: magicat/cgi-bin/mtrltype.cgi:207 +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:40 +msgid "This type does not exist anymore. Please select another one." +msgstr "查無此類型,請改選其她類型。" + +#: magicat/cgi-bin/pages.cgi:26 +msgid "pages" +msgstr "網頁" + +#: magicat/cgi-bin/pages.cgi:193 +msgid "Please select the page." +msgstr "請選擇網頁。" + +#: magicat/cgi-bin/pages.cgi:201 +msgid "This page does not exist anymore. Please select another one." +msgstr "查無此頁,請改選其她網頁。" + +#: magicat/cgi-bin/rebuild.cgi:23 +msgid "rebuild pages" +msgstr "重製網頁" + +#: magicat/cgi-bin/scptpriv.cgi:28 +msgid "script privilege" +msgstr "程式權限" + +#: magicat/cgi-bin/scptpriv.cgi:184 +msgid "Please select the script privilege record." +msgstr "請選擇程式權限。" + +#: magicat/cgi-bin/scptpriv.cgi:192 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "查無該程式權限,請重新選擇。" + +#: magicat/cgi-bin/usermem.cgi:30 +msgid "user membership" +msgstr "使用者成員" + +#: magicat/cgi-bin/userpref.cgi:28 +msgid "user preference" +msgstr "使用者偏好" + +#: magicat/cgi-bin/userpref.cgi:184 +msgid "Please select the user preference." +msgstr "請選擇使用者偏好。" + +#: magicat/cgi-bin/userpref.cgi:192 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "查無該使用者偏好,請重新選擇。" + +#: magicat/cgi-bin/users.cgi:29 +msgid "users" +msgstr "帳號" + +#: magicat/cgi-bin/users.cgi:222 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: magicat/cgi-bin/users.cgi:230 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: magicat/lib/perl5/Selima/emandy/Config.pm:49 +#: magicat/lib/perl5/Selima/emandy/HTML.pm:65 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:356 +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:145 +msgid "Legend" +msgstr "傳奇" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:63 +msgid "Manage Content" +msgstr "管理網站" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:67 +msgid "Books" +msgstr "書目" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:69 +msgid "Materials" +msgstr "史料" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:71 +msgid "Material Types" +msgstr "史料類型" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:73 +msgid "Pages" +msgstr "網頁" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:75 +msgid "Links" +msgstr "連結" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:77 +msgid "Link Categories" +msgstr "連結分類" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:79 +msgid "Link Categorization" +msgstr "連結分類表" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:83 +msgid "Manage Accounts" +msgstr "管理帳號" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:85 +msgid "Users" +msgstr "帳號" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:87 +msgid "Groups" +msgstr "群組" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:89 +msgid "User Membership" +msgstr "使用者成員" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:91 +msgid "Group Membership" +msgstr "群組成員" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:93 +msgid "User Preferences" +msgstr "使用者偏好" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:95 +msgid "Script Privileges" +msgstr "程式權限" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:99 +msgid "Manage Accounting" +msgstr "管理會計" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:101 +msgid "Transactions" +msgstr "傳票" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:103 +msgid "Reports" +msgstr "報表" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:105 +msgid "Subjects" +msgstr "科目" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:107 +msgid "Records" +msgstr "分錄" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:111 +msgid "Miscellaneous" +msgstr "雜項" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:113 +msgid "Activity Log" +msgstr "活動日誌" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:115 +msgid "Rebuild Pages" +msgstr "重製網頁" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:117 +msgid "Analog" +msgstr "訪客統計" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:119 +msgid "Test Script" +msgstr "測試程式" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:166 +msgid "Skip to the page content area." +msgstr "跳到網頁內文區。" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:167 +msgid "Page Content Area" +msgstr "網頁內文區" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:300 +msgid "Navigation Links Area" +msgstr "導覽連結區" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:375 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "%s,妳好!(修改資料)" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:410 +#, c-format +msgid "%s:" +msgstr "%s:" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:480 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:221 +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:136 +msgid "Related Links" +msgstr "相關連結" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:491 +msgid "Subcategories:" +msgstr "子類:" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:506 +msgid "E-mail" +msgstr "E-mail" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:531 +msgid "URL:" +msgstr "網址:" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:534 +msgid "E-mail:" +msgstr "E-mail :" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:540 +msgid "Address:" +msgstr "地址:" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:542 +msgid "Tel.:" +msgstr "電話:" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:544 +msgid "Fax.:" +msgstr "傳真:" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:569 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:603 +msgid "The legend is empty." +msgstr "現無任何傳奇。" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:608 +msgid "Index" +msgstr "卷目" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:618 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:273 +#, c-format +msgid "Legend Volume %s" +msgstr "傳奇卷%s" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:678 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "mod_perl -- 速度,動力,無限可能" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:679 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" +"本程式以 Perl 撰寫,專為 mod_perl 設計強化" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:692 +msgid "" +"This script is written in Perl." +msgstr "" +"本程式以 Perl 撰寫" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:43 +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:116 +msgid "This author is too long. (Max. length [#,_1])" +msgstr "作者太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:64 +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:60 +msgid "This year is too long. (Max. length [#,_1])" +msgstr "年太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:68 +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:64 +msgid "Please fill in a positive integer year." +msgstr "年請填正整數。" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:92 +msgid "This publisher is too long. (Max. length [#,_1])" +msgstr "出版商太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:113 +msgid "This origin is too long. (Max. length [#,_1])" +msgstr "出版地太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:133 +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:100 +msgid "Fill in the review here." +msgstr "請填上書評。" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:136 +msgid "This review is too long. (Max. length [#,_1])" +msgstr "書評太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:156 +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:106 +msgid "Fill in the comment here." +msgstr "請填上讀後感。" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:159 +msgid "This comment is too long. (Max. length [#,_1])" +msgstr "讀後感太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:179 +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:112 +msgid "Fill in the libraries here." +msgstr "請填上館藏。" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:182 +msgid "This libraries is too long. (Max. length [#,_1])" +msgstr "館藏太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:92 +msgid "Please fill in the source." +msgstr "請填上出處。" + +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:95 +msgid "This source is too long. (Max. length [#,_1])" +msgstr "出處太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:136 +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:95 +msgid "Fill in the notes here." +msgstr "請填上備註。" + +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:139 +msgid "This notes is too long. (Max. length [#,_1])" +msgstr "備註太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:32 +msgid "Delete this book" +msgstr "刪掉這本書" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:37 +msgid "This table provides you a form to add a new book." +msgstr "本表提供建新書目的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:40 +msgid "This table provides you a form to edit a current book." +msgstr "本表提供編輯書目的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:43 +msgid "This table provides you a form to delete a book." +msgstr "本表提供刪除書目的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:61 +msgid "Add a New Book" +msgstr "建新書目" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:64 +msgid "Edit a Current Book" +msgstr "編輯書目" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:67 +msgid "Delete a Book" +msgstr "刪除書目" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:77 +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:84 +msgid "Year:" +msgstr "年:" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:82 +msgid "Publisher:" +msgstr "出版商:" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:87 +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:37 +msgid "To be borrowed?" +msgstr "待借?" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:88 +msgid "To be borrowed" +msgstr "待借" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:88 +msgid "Not to be borrowed" +msgstr "不是待借" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:89 +msgid "This book is to be borrowed." +msgstr "這是待借的書。" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:94 +msgid "Origin:" +msgstr "出版地:" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:99 +msgid "Review:" +msgstr "書評:" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:105 +msgid "Comment:" +msgstr "讀後感:" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:111 +msgid "Libraries:" +msgstr "館藏:" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:32 +msgid "Delete this legend entry" +msgstr "刪掉這則傳奇" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:37 +msgid "This table provides you a form to write a new legend entry." +msgstr "本表提供撰傳奇的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:40 +msgid "This table provides you a form to edit a current legend entry." +msgstr "本表提供編輯傳奇的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:43 +msgid "This table provides you a form to delete a legend entry." +msgstr "本表提供刪除傳奇的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:60 +msgid "Write a New Legend Entry" +msgstr "撰傳奇" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:63 +msgid "Edit a Current Legend Entry" +msgstr "編輯傳奇" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:66 +msgid "Delete a Legend Entry" +msgstr "刪除傳奇" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:75 +msgid "Hide?" +msgstr "隱藏?" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:76 +msgid "Hide this legend entry" +msgstr "隱藏這則傳奇" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:76 +msgid "Show this legend entry" +msgstr "秀出這則傳奇" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:77 +msgid "Hide this legend entry currently." +msgstr "暫勿秀出這則傳奇。" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:82 +msgid "Page No.:" +msgstr "頁數:" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:34 +msgid "Delete this material" +msgstr "刪掉這筆史料" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:39 +msgid "This table provides you a form to add a new material." +msgstr "本表提供建新史料的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:42 +msgid "This table provides you a form to edit a current material." +msgstr "本表提供編輯史料的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:45 +msgid "This table provides you a form to delete a material." +msgstr "本表提供刪除史料的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:63 +msgid "Add a New Material" +msgstr "建新史料" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:66 +msgid "Edit a Current Material" +msgstr "編輯史料" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:69 +msgid "Delete a Material" +msgstr "刪除史料" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:79 +msgid "Type:" +msgstr "類型:" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:89 +msgid "Source:" +msgstr "出處:" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:94 +msgid "Notes:" +msgstr "備註:" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:32 +msgid "Delete this type" +msgstr "刪掉本類型" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:37 +msgid "This table provides you a form to add a new type." +msgstr "本表提供建新類型的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:40 +msgid "This table provides you a form to edit a current type." +msgstr "本表提供編輯類型的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:43 +msgid "This table provides you a form to delete a type." +msgstr "本表提供刪除類型的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:59 +msgid "Add a New Material Type" +msgstr "建新史料類型" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:62 +msgid "Edit a Current Material Type" +msgstr "編輯史料類型" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:65 +msgid "Delete a Material Type" +msgstr "刪除史料類型" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:25 +#: magicat/lib/perl5/Selima/emandy/List/Books/NotToBorrow.pm:24 +#: magicat/lib/perl5/Selima/emandy/List/Books/ToBorrow.pm:24 +msgid "Select a Book" +msgstr "選擇書目" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:26 +msgid "Manage Books" +msgstr "管理書目" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:33 +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:35 +msgid "Author" +msgstr "作者" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:34 +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:33 +msgid "Year" +msgstr "年" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:35 +msgid "Origin" +msgstr "出版地" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:36 +msgid "Publisher" +msgstr "出版商" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:38 +msgid "Review" +msgstr "書評" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:39 +msgid "Comment" +msgstr "讀後感" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:40 +msgid "Libraries" +msgstr "館藏" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:45 +msgid "Books not to be borrowed" +msgstr "一般書目" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:47 +msgid "Books to be borrowed" +msgstr "待借書目" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:49 +msgid "All books" +msgstr "所有書目" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:57 +msgid "Add a new book." +msgstr "建新書目。" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:63 +msgid "Search for a book:" +msgstr "搜尋書目:" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:80 +msgid "Your query found [*,_1,book]." +msgstr "共 [#,_1] 本相符的書。" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:83 +msgid "[*,_1,book]." +msgstr "共 [#,_1] 本書。" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:89 +msgid "Your query found [*,_1,book], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 本相符的書,列出第 [#,_2] 本到第 [#,_3] 本。" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:93 +msgid "[*,_1,book], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 本書,列出第 [#,_2] 本到第 [#,_3] 本。" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:24 +msgid "Select a Legend Entry" +msgstr "選擇傳奇" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:25 +msgid "Manage Legend" +msgstr "管理傳奇" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:36 +msgid "Page No." +msgstr "頁數" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:44 +msgid "Write a new legend entry." +msgstr "撰傳奇。" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:50 +msgid "Search for a legend entry:" +msgstr "搜尋傳奇:" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:67 +msgid "Your query found [*,_1,legend entry,legend entries]." +msgstr "共 [#,_1] 則相符的傳奇。" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:70 +msgid "[*,_1,legend entry,legend entries]." +msgstr "共 [#,_1] 則傳奇。" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:76 +msgid "" +"Your query found [*,_1,legend entry,legend entries], listing [#,_2] to [#," +"_3]." +msgstr "共 [#,_1] 則相符的傳奇,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:80 +msgid "[*,_1,legend entry,legend entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則傳奇,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:24 +msgid "Select a Material" +msgstr "選擇史料" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:25 +msgid "Manage Materials" +msgstr "管理史料" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:32 +msgid "Type" +msgstr "類型" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:34 +msgid "Source" +msgstr "出處" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:36 +msgid "Notes" +msgstr "備註" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:44 +msgid "Add a new material." +msgstr "建新史料。" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:50 +msgid "Search for a material:" +msgstr "搜尋史料:" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:67 +msgid "Your query found [*,_1,material]." +msgstr "共 [#,_1] 筆相符的史料。" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:70 +msgid "[*,_1,material]." +msgstr "共 [#,_1] 筆史料。" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:76 +msgid "Your query found [*,_1,material], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的史料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:80 +msgid "[*,_1,material], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆史料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:24 +msgid "Select a Material Type" +msgstr "選擇史料類型" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:25 +msgid "Manage Material Types" +msgstr "管理史料類型" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:37 +msgid "Add a new type." +msgstr "建新類型。" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:43 +msgid "Search for a type:" +msgstr "搜尋類型:" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:60 +msgid "Your query found [*,_1,type]." +msgstr "共 [#,_1] 類相符的類型。" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:63 +msgid "[*,_1,type]." +msgstr "共 [#,_1] 類類型。" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:69 +msgid "Your query found [*,_1,type], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 類相符的類型,列出第 [#,_2] 類到第 [#,_3] 類。" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:73 +msgid "[*,_1,type], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 類類型,列出第 [#,_2] 類到第 [#,_3] 類。" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:24 +msgid "Full Text Search" +msgstr "全文檢索" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:26 +msgid "Search Result" +msgstr "搜尋結果" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:49 +msgid "Please fill in your query." +msgstr "請填上檢索的辭彙。" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:71 +msgid "Search in the website:" +msgstr "網站檢索:" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:88 +msgid "Your query found [*,_1,article]." +msgstr "共 [#,_1] 篇相符的文章。" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:91 +msgid "[*,_1,article]." +msgstr "共 [#,_1] 篇文章。" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:97 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:101 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Book.pm:90 +msgid "This book was not modified." +msgstr "書目未異動。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Book.pm:94 +msgid "This book has been successfully added." +msgstr "書目建好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Book.pm:98 +msgid "This book has been successfully updated." +msgstr "書目存好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Book.pm:102 +msgid "This book has been successfully deleted." +msgstr "書目刪掉了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Legend.pm:93 +msgid "This legend entry was not modified." +msgstr "傳奇未異動。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Legend.pm:97 +msgid "This legend entry has been successfully added." +msgstr "傳奇寫好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Legend.pm:101 +msgid "This legend entry has been successfully updated." +msgstr "傳奇存好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Legend.pm:105 +msgid "This legend entry has been successfully deleted." +msgstr "傳奇刪掉了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Material.pm:86 +msgid "This material was not modified." +msgstr "史料未異動。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Material.pm:90 +msgid "This material has been successfully added." +msgstr "史料建好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Material.pm:94 +msgid "This material has been successfully updated." +msgstr "史料存好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Material.pm:98 +msgid "This material has been successfully deleted." +msgstr "史料刪掉了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm:76 +msgid "This type was not modified." +msgstr "類型未異動。" + +#: magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm:80 +msgid "This type has been successfully added." +msgstr "類型建好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm:84 +msgid "This type has been successfully updated." +msgstr "類型存好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm:88 +msgid "This type has been successfully deleted." +msgstr "類型刪掉了。" + +#: magicat/lib/perl5/Selima/emandy/List/Books/NotToBorrow.pm:25 +msgid "Manage Books Not to Be Borrowed" +msgstr "管理一般書目" + +#: magicat/lib/perl5/Selima/emandy/List/Books/ToBorrow.pm:25 +msgid "Manage Books to be Borrowed" +msgstr "管理待借書目" + +#: magicat/lib/perl5/Selima/emandy/List/Legend/Public.pm:131 +msgid "The legend entry seperator" +msgstr "傳奇分隔線" diff --git a/htdocs/emandy/magicat/po/zh_TW.pox b/htdocs/emandy/magicat/po/zh_TW.pox new file mode 100644 index 0000000..fcca3a0 --- /dev/null +++ b/htdocs/emandy/magicat/po/zh_TW.pox @@ -0,0 +1,1078 @@ +# Traditional Chinese PO file for the eMandy website +# Copyright (C) 2004-2018 imacat +# This file is distributed under the same license as the emandy package. +# imacat , 2004-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: emandy 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-25 01:36+0800\n" +"PO-Revision-Date: 2006-11-15 00:33+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: magicat/cgi-bin/acctrecs.cgi:30 magicat/cgi-bin/acctreps.cgi:26 +#: magicat/cgi-bin/acctsubj.cgi:28 magicat/cgi-bin/accttrx.cgi:29 +msgid "accounting" +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:94 magicat/cgi-bin/acctrecs.cgi:139 +#: magicat/cgi-bin/acctsubj.cgi:104 magicat/cgi-bin/acctsubj.cgi:162 +#: magicat/cgi-bin/accttrx.cgi:93 magicat/cgi-bin/accttrx.cgi:138 +#: magicat/cgi-bin/books.cgi:94 magicat/cgi-bin/books.cgi:145 +#: magicat/cgi-bin/groupmem.cgi:94 magicat/cgi-bin/groupmem.cgi:139 +#: magicat/cgi-bin/groups.cgi:102 magicat/cgi-bin/groups.cgi:151 +#: magicat/cgi-bin/legend.cgi:94 magicat/cgi-bin/legend.cgi:143 +#: magicat/cgi-bin/linkcat.cgi:101 magicat/cgi-bin/linkcat.cgi:154 +#: magicat/cgi-bin/linkcatz.cgi:94 magicat/cgi-bin/linkcatz.cgi:139 +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:137 +#: magicat/cgi-bin/material.cgi:95 magicat/cgi-bin/material.cgi:146 +#: magicat/cgi-bin/mtrltype.cgi:99 magicat/cgi-bin/mtrltype.cgi:152 +#: magicat/cgi-bin/pages.cgi:96 magicat/cgi-bin/pages.cgi:140 +#: magicat/cgi-bin/scptpriv.cgi:92 magicat/cgi-bin/scptpriv.cgi:137 +#: magicat/cgi-bin/usermem.cgi:94 magicat/cgi-bin/usermem.cgi:139 +#: magicat/cgi-bin/userpref.cgi:92 magicat/cgi-bin/userpref.cgi:137 +#: magicat/cgi-bin/users.cgi:111 magicat/cgi-bin/users.cgi:175 +msgid "Incorrect form: [_1]." +msgstr "查無此表格: [_1] 。" + +#: magicat/cgi-bin/acctrecs.cgi:186 +msgid "Please select the accounting record." +msgstr "請選擇會計分錄。" + +#: magicat/cgi-bin/acctrecs.cgi:194 +msgid "" +"This accounting record does not exist anymore. Please select another one." +msgstr "查無此會計分錄,請重新選擇。" + +#: magicat/cgi-bin/acctsubj.cgi:77 magicat/cgi-bin/acctsubj.cgi:122 +msgid "Please add a new accounting subject from [_1]." +msgstr "請由[_1]建新會計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:93 magicat/cgi-bin/acctsubj.cgi:151 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the subject, " +"[numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] " +"must first be deleted." +msgstr "" +"本會計科目下有子會計科目,不可直接刪除。要刪除本會計科目,請先刪除其下的子會" +"計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:97 magicat/cgi-bin/acctsubj.cgi:155 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the subject, [numerate,_1,its " +"accounting record,all of its accounting records] must first be deleted." +msgstr "" +"本會計科目下有會計分錄,不可直接刪除。要刪除本會計科目,請先刪除其下的會計分" +"錄。" + +#: magicat/cgi-bin/acctsubj.cgi:214 +msgid "Please select the accounting subject." +msgstr "請選擇會計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:222 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "查無此會計科目,請重新選擇。" + +#: magicat/cgi-bin/accttrx.cgi:185 +msgid "Please select the accounting transaction." +msgstr "請選擇會計傳票。" + +#: magicat/cgi-bin/accttrx.cgi:193 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "查無此會計傳票,請重新選擇。" + +#: magicat/cgi-bin/actlog.cgi:22 +msgid "activity, logs" +msgstr "活動, 記錄, 日誌" + +#: magicat/cgi-bin/books.cgi:26 +msgid "books" +msgstr "書" + +#: magicat/cgi-bin/books.cgi:75 magicat/cgi-bin/books.cgi:112 +msgid "Please create a new book from [_1]." +msgstr "請由[_1]建新書目。" + +#: magicat/cgi-bin/books.cgi:198 +msgid "Please select the book." +msgstr "請選擇書目。" + +#: magicat/cgi-bin/books.cgi:206 +msgid "This book does not exist anymore. Please select another one." +msgstr "查無此書,請重新選擇。" + +#: magicat/cgi-bin/groupmem.cgi:30 +msgid "group membership" +msgstr "群組成員" + +#: magicat/cgi-bin/groupmem.cgi:186 magicat/cgi-bin/usermem.cgi:186 +msgid "Please select the membership record." +msgstr "請選擇成員關係。" + +#: magicat/cgi-bin/groupmem.cgi:194 magicat/cgi-bin/usermem.cgi:194 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "查無此成員關係,請重新選擇。" + +#: magicat/cgi-bin/groups.cgi:34 +msgid "groups" +msgstr "群組" + +#: magicat/cgi-bin/groups.cgi:198 +msgid "Please select the group." +msgstr "請選擇群組。" + +#: magicat/cgi-bin/groups.cgi:206 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: magicat/cgi-bin/legend.cgi:26 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:274 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:342 +msgid "legend" +msgstr "傳奇" + +#: magicat/cgi-bin/legend.cgi:75 magicat/cgi-bin/legend.cgi:112 +msgid "Please write a new legend entry from [_1]." +msgstr "請由[_1]撰傳奇。" + +#: magicat/cgi-bin/legend.cgi:190 +msgid "Please select the legend entry." +msgstr "請選擇傳奇。" + +#: magicat/cgi-bin/legend.cgi:198 +msgid "This legend entry does not exist anymore. Please select another one." +msgstr "查無該則傳奇,請重新選擇。" + +#: magicat/cgi-bin/linkcat.cgi:29 +msgid "link categories" +msgstr "相關連結分類" + +#: magicat/cgi-bin/linkcat.cgi:90 magicat/cgi-bin/linkcat.cgi:143 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: magicat/cgi-bin/linkcat.cgi:94 magicat/cgi-bin/linkcat.cgi:147 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: magicat/cgi-bin/linkcat.cgi:202 +msgid "Please select the category." +msgstr "請選擇分類。" + +#: magicat/cgi-bin/linkcat.cgi:210 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: magicat/cgi-bin/linkcatz.cgi:30 +msgid "link categorization" +msgstr "連結分類表" + +#: magicat/cgi-bin/linkcatz.cgi:186 +msgid "Please select the categorization record." +msgstr "請選擇分類資料。" + +#: magicat/cgi-bin/linkcatz.cgi:194 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "查無此分類資料,請重新選擇。" + +#: magicat/cgi-bin/links.cgi:28 magicat/lib/perl5/Selima/emandy/Rebuild.pm:213 +msgid "related links" +msgstr "相關連結" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Please select the related link." +msgstr "請選擇要設定的相關連結。" + +#: magicat/cgi-bin/links.cgi:193 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查無該相關連結,請改選其她相關連結。" + +#: magicat/cgi-bin/logout.cgi:25 +msgid "log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:98 magicat/cgi-bin/logout.cgi:105 +msgid "Log Out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:121 +msgid "Are you sure you want to log out?" +msgstr "妳確定要登出嗎?" + +#: magicat/cgi-bin/logout.cgi:122 magicat/lib/perl5/Selima/emandy/HTML.pm:377 +msgid "Log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:138 +msgid "Log in again." +msgstr "重新登入。" + +#: magicat/cgi-bin/material.cgi:27 magicat/cgi-bin/mtrltype.cgi:27 +msgid "materials" +msgstr "史料" + +#: magicat/cgi-bin/material.cgi:76 magicat/cgi-bin/material.cgi:113 +msgid "Please create a new material from [_1]." +msgstr "請由[_1]建新史料。" + +#: magicat/cgi-bin/material.cgi:193 +msgid "Please select the material." +msgstr "請選擇史料。" + +#: magicat/cgi-bin/material.cgi:201 +msgid "This material does not exist anymore. Please select another one." +msgstr "查無此史料,請重新選擇。" + +#: magicat/cgi-bin/mtrltype.cgi:76 magicat/cgi-bin/mtrltype.cgi:117 +msgid "Please create a new type from [_1]." +msgstr "請由[_1]建新類型。" + +#: magicat/cgi-bin/mtrltype.cgi:92 magicat/cgi-bin/mtrltype.cgi:145 +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:73 +msgid "" +"This type has [numerate,_1,a material,materials]. It cannot be deleted. To " +"delete the type, [numerate,_1,its material,all of its materials] must first " +"be deleted." +msgstr "本類型下有史料,不可直接刪除。要刪除本類型,請先刪除其下的史料。" + +#: magicat/cgi-bin/mtrltype.cgi:199 +msgid "Please select the type." +msgstr "請選擇類型。" + +#: magicat/cgi-bin/mtrltype.cgi:207 +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:40 +msgid "This type does not exist anymore. Please select another one." +msgstr "查無此類型,請改選其她類型。" + +#: magicat/cgi-bin/pages.cgi:26 +msgid "pages" +msgstr "網頁" + +#: magicat/cgi-bin/pages.cgi:193 +msgid "Please select the page." +msgstr "請選擇網頁。" + +#: magicat/cgi-bin/pages.cgi:201 +msgid "This page does not exist anymore. Please select another one." +msgstr "查無此頁,請改選其她網頁。" + +#: magicat/cgi-bin/rebuild.cgi:23 +msgid "rebuild pages" +msgstr "重製網頁" + +#: magicat/cgi-bin/scptpriv.cgi:28 +msgid "script privilege" +msgstr "程式權限" + +#: magicat/cgi-bin/scptpriv.cgi:184 +msgid "Please select the script privilege record." +msgstr "請選擇程式權限。" + +#: magicat/cgi-bin/scptpriv.cgi:192 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "查無該程式權限,請重新選擇。" + +#: magicat/cgi-bin/usermem.cgi:30 +msgid "user membership" +msgstr "使用者成員" + +#: magicat/cgi-bin/userpref.cgi:28 +msgid "user preference" +msgstr "使用者偏好" + +#: magicat/cgi-bin/userpref.cgi:184 +msgid "Please select the user preference." +msgstr "請選擇使用者偏好。" + +#: magicat/cgi-bin/userpref.cgi:192 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "查無該使用者偏好,請重新選擇。" + +#: magicat/cgi-bin/users.cgi:29 +msgid "users" +msgstr "帳號" + +#: magicat/cgi-bin/users.cgi:222 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: magicat/cgi-bin/users.cgi:230 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: magicat/lib/perl5/Selima/emandy/Config.pm:49 +#: magicat/lib/perl5/Selima/emandy/HTML.pm:65 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:356 +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:145 +msgid "Legend" +msgstr "傳奇" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:63 +msgid "Manage Content" +msgstr "管理網站" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:67 +msgid "Books" +msgstr "書目" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:69 +msgid "Materials" +msgstr "史料" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:71 +msgid "Material Types" +msgstr "史料類型" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:73 +msgid "Pages" +msgstr "網頁" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:75 +msgid "Links" +msgstr "連結" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:77 +msgid "Link Categories" +msgstr "連結分類" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:79 +msgid "Link Categorization" +msgstr "連結分類表" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:83 +msgid "Manage Accounts" +msgstr "管理帳號" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:85 +msgid "Users" +msgstr "帳號" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:87 +msgid "Groups" +msgstr "群組" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:89 +msgid "User Membership" +msgstr "使用者成員" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:91 +msgid "Group Membership" +msgstr "群組成員" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:93 +msgid "User Preferences" +msgstr "使用者偏好" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:95 +msgid "Script Privileges" +msgstr "程式權限" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:99 +msgid "Manage Accounting" +msgstr "管理會計" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:101 +msgid "Transactions" +msgstr "傳票" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:103 +msgid "Reports" +msgstr "報表" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:105 +msgid "Subjects" +msgstr "科目" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:107 +msgid "Records" +msgstr "分錄" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:111 +msgid "Miscellaneous" +msgstr "雜項" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:113 +msgid "Activity Log" +msgstr "活動日誌" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:115 +msgid "Rebuild Pages" +msgstr "重製網頁" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:117 +msgid "Analog" +msgstr "訪客統計" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:119 +msgid "Test Script" +msgstr "測試程式" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:166 +msgid "Skip to the page content area." +msgstr "跳到網頁內文區。" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:167 +msgid "Page Content Area" +msgstr "網頁內文區" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:300 +msgid "Navigation Links Area" +msgstr "導覽連結區" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:375 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "%s,妳好!(修改資料)" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:410 +#, c-format +msgid "%s:" +msgstr "%s:" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:480 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:221 +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:136 +msgid "Related Links" +msgstr "相關連結" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:491 +msgid "Subcategories:" +msgstr "子類:" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:506 +msgid "E-mail" +msgstr "E-mail" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:531 +msgid "URL:" +msgstr "網址:" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:534 +msgid "E-mail:" +msgstr "E-mail :" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:540 +msgid "Address:" +msgstr "地址:" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:542 +msgid "Tel.:" +msgstr "電話:" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:544 +msgid "Fax.:" +msgstr "傳真:" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:569 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:603 +msgid "The legend is empty." +msgstr "現無任何傳奇。" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:608 +msgid "Index" +msgstr "卷目" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:618 +#: magicat/lib/perl5/Selima/emandy/Rebuild.pm:273 +#, c-format +msgid "Legend Volume %s" +msgstr "傳奇卷%s" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:678 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "mod_perl -- 速度,動力,無限可能" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:679 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" +"本程式以 Perl 撰寫,專為 mod_perl 設計強化" + +#: magicat/lib/perl5/Selima/emandy/HTML.pm:692 +msgid "" +"This script is written in Perl." +msgstr "" +"本程式以 Perl 撰寫" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:43 +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:116 +msgid "This author is too long. (Max. length [#,_1])" +msgstr "作者太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:64 +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:60 +msgid "This year is too long. (Max. length [#,_1])" +msgstr "年太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:68 +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:64 +msgid "Please fill in a positive integer year." +msgstr "年請填正整數。" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:92 +msgid "This publisher is too long. (Max. length [#,_1])" +msgstr "出版商太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:113 +msgid "This origin is too long. (Max. length [#,_1])" +msgstr "出版地太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:133 +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:100 +msgid "Fill in the review here." +msgstr "請填上書評。" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:136 +msgid "This review is too long. (Max. length [#,_1])" +msgstr "書評太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:156 +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:106 +msgid "Fill in the comment here." +msgstr "請填上讀後感。" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:159 +msgid "This comment is too long. (Max. length [#,_1])" +msgstr "讀後感太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:179 +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:112 +msgid "Fill in the libraries here." +msgstr "請填上館藏。" + +#: magicat/lib/perl5/Selima/emandy/Checker/Book.pm:182 +msgid "This libraries is too long. (Max. length [#,_1])" +msgstr "館藏太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:92 +msgid "Please fill in the source." +msgstr "請填上出處。" + +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:95 +msgid "This source is too long. (Max. length [#,_1])" +msgstr "出處太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:136 +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:95 +msgid "Fill in the notes here." +msgstr "請填上備註。" + +#: magicat/lib/perl5/Selima/emandy/Checker/Material.pm:139 +msgid "This notes is too long. (Max. length [#,_1])" +msgstr "備註太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:32 +msgid "Delete this book" +msgstr "刪掉這本書" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:37 +msgid "This table provides you a form to add a new book." +msgstr "本表提供建新書目的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:40 +msgid "This table provides you a form to edit a current book." +msgstr "本表提供編輯書目的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:43 +msgid "This table provides you a form to delete a book." +msgstr "本表提供刪除書目的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:61 +msgid "Add a New Book" +msgstr "建新書目" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:64 +msgid "Edit a Current Book" +msgstr "編輯書目" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:67 +msgid "Delete a Book" +msgstr "刪除書目" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:77 +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:84 +msgid "Year:" +msgstr "年:" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:82 +msgid "Publisher:" +msgstr "出版商:" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:87 +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:37 +msgid "To be borrowed?" +msgstr "待借?" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:88 +msgid "To be borrowed" +msgstr "待借" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:88 +msgid "Not to be borrowed" +msgstr "不是待借" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:89 +msgid "This book is to be borrowed." +msgstr "這是待借的書。" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:94 +msgid "Origin:" +msgstr "出版地:" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:99 +msgid "Review:" +msgstr "書評:" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:105 +msgid "Comment:" +msgstr "讀後感:" + +#: magicat/lib/perl5/Selima/emandy/Form/Book.pm:111 +msgid "Libraries:" +msgstr "館藏:" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:32 +msgid "Delete this legend entry" +msgstr "刪掉這則傳奇" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:37 +msgid "This table provides you a form to write a new legend entry." +msgstr "本表提供撰傳奇的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:40 +msgid "This table provides you a form to edit a current legend entry." +msgstr "本表提供編輯傳奇的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:43 +msgid "This table provides you a form to delete a legend entry." +msgstr "本表提供刪除傳奇的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:60 +msgid "Write a New Legend Entry" +msgstr "撰傳奇" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:63 +msgid "Edit a Current Legend Entry" +msgstr "編輯傳奇" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:66 +msgid "Delete a Legend Entry" +msgstr "刪除傳奇" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:75 +msgid "Hide?" +msgstr "隱藏?" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:76 +msgid "Hide this legend entry" +msgstr "隱藏這則傳奇" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:76 +msgid "Show this legend entry" +msgstr "秀出這則傳奇" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:77 +msgid "Hide this legend entry currently." +msgstr "暫勿秀出這則傳奇。" + +#: magicat/lib/perl5/Selima/emandy/Form/Legend.pm:82 +msgid "Page No.:" +msgstr "頁數:" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:34 +msgid "Delete this material" +msgstr "刪掉這筆史料" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:39 +msgid "This table provides you a form to add a new material." +msgstr "本表提供建新史料的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:42 +msgid "This table provides you a form to edit a current material." +msgstr "本表提供編輯史料的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:45 +msgid "This table provides you a form to delete a material." +msgstr "本表提供刪除史料的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:63 +msgid "Add a New Material" +msgstr "建新史料" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:66 +msgid "Edit a Current Material" +msgstr "編輯史料" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:69 +msgid "Delete a Material" +msgstr "刪除史料" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:79 +msgid "Type:" +msgstr "類型:" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:89 +msgid "Source:" +msgstr "出處:" + +#: magicat/lib/perl5/Selima/emandy/Form/Material.pm:94 +msgid "Notes:" +msgstr "備註:" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:32 +msgid "Delete this type" +msgstr "刪掉本類型" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:37 +msgid "This table provides you a form to add a new type." +msgstr "本表提供建新類型的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:40 +msgid "This table provides you a form to edit a current type." +msgstr "本表提供編輯類型的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:43 +msgid "This table provides you a form to delete a type." +msgstr "本表提供刪除類型的表單。" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:59 +msgid "Add a New Material Type" +msgstr "建新史料類型" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:62 +msgid "Edit a Current Material Type" +msgstr "編輯史料類型" + +#: magicat/lib/perl5/Selima/emandy/Form/MtrlType.pm:65 +msgid "Delete a Material Type" +msgstr "刪除史料類型" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:25 +#: magicat/lib/perl5/Selima/emandy/List/Books/NotToBorrow.pm:24 +#: magicat/lib/perl5/Selima/emandy/List/Books/ToBorrow.pm:24 +msgid "Select a Book" +msgstr "選擇書目" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:26 +msgid "Manage Books" +msgstr "管理書目" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:33 +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:35 +msgid "Author" +msgstr "作者" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:34 +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:33 +msgid "Year" +msgstr "年" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:35 +msgid "Origin" +msgstr "出版地" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:36 +msgid "Publisher" +msgstr "出版商" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:38 +msgid "Review" +msgstr "書評" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:39 +msgid "Comment" +msgstr "讀後感" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:40 +msgid "Libraries" +msgstr "館藏" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:45 +msgid "Books not to be borrowed" +msgstr "一般書目" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:47 +msgid "Books to be borrowed" +msgstr "待借書目" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:49 +msgid "All books" +msgstr "所有書目" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:57 +msgid "Add a new book." +msgstr "建新書目。" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:63 +msgid "Search for a book:" +msgstr "搜尋書目:" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:80 +msgid "Your query found [*,_1,book]." +msgstr "共 [#,_1] 本相符的書。" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:83 +msgid "[*,_1,book]." +msgstr "共 [#,_1] 本書。" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:89 +msgid "Your query found [*,_1,book], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 本相符的書,列出第 [#,_2] 本到第 [#,_3] 本。" + +#: magicat/lib/perl5/Selima/emandy/List/Books.pm:93 +msgid "[*,_1,book], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 本書,列出第 [#,_2] 本到第 [#,_3] 本。" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:24 +msgid "Select a Legend Entry" +msgstr "選擇傳奇" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:25 +msgid "Manage Legend" +msgstr "管理傳奇" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:36 +msgid "Page No." +msgstr "頁數" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:44 +msgid "Write a new legend entry." +msgstr "撰傳奇。" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:50 +msgid "Search for a legend entry:" +msgstr "搜尋傳奇:" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:67 +msgid "Your query found [*,_1,legend entry,legend entries]." +msgstr "共 [#,_1] 則相符的傳奇。" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:70 +msgid "[*,_1,legend entry,legend entries]." +msgstr "共 [#,_1] 則傳奇。" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:76 +msgid "" +"Your query found [*,_1,legend entry,legend entries], listing [#,_2] to [#," +"_3]." +msgstr "共 [#,_1] 則相符的傳奇,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: magicat/lib/perl5/Selima/emandy/List/Legend.pm:80 +msgid "[*,_1,legend entry,legend entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則傳奇,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:24 +msgid "Select a Material" +msgstr "選擇史料" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:25 +msgid "Manage Materials" +msgstr "管理史料" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:32 +msgid "Type" +msgstr "類型" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:34 +msgid "Source" +msgstr "出處" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:36 +msgid "Notes" +msgstr "備註" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:44 +msgid "Add a new material." +msgstr "建新史料。" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:50 +msgid "Search for a material:" +msgstr "搜尋史料:" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:67 +msgid "Your query found [*,_1,material]." +msgstr "共 [#,_1] 筆相符的史料。" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:70 +msgid "[*,_1,material]." +msgstr "共 [#,_1] 筆史料。" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:76 +msgid "Your query found [*,_1,material], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的史料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: magicat/lib/perl5/Selima/emandy/List/Material.pm:80 +msgid "[*,_1,material], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆史料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:24 +msgid "Select a Material Type" +msgstr "選擇史料類型" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:25 +msgid "Manage Material Types" +msgstr "管理史料類型" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:37 +msgid "Add a new type." +msgstr "建新類型。" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:43 +msgid "Search for a type:" +msgstr "搜尋類型:" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:60 +msgid "Your query found [*,_1,type]." +msgstr "共 [#,_1] 類相符的類型。" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:63 +msgid "[*,_1,type]." +msgstr "共 [#,_1] 類類型。" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:69 +msgid "Your query found [*,_1,type], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 類相符的類型,列出第 [#,_2] 類到第 [#,_3] 類。" + +#: magicat/lib/perl5/Selima/emandy/List/MtrlType.pm:73 +msgid "[*,_1,type], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 類類型,列出第 [#,_2] 類到第 [#,_3] 類。" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:24 +msgid "Full Text Search" +msgstr "全文檢索" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:26 +msgid "Search Result" +msgstr "搜尋結果" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:49 +msgid "Please fill in your query." +msgstr "請填上檢索的辭彙。" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:71 +msgid "Search in the website:" +msgstr "網站檢索:" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:88 +msgid "Your query found [*,_1,article]." +msgstr "共 [#,_1] 篇相符的文章。" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:91 +msgid "[*,_1,article]." +msgstr "共 [#,_1] 篇文章。" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:97 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/emandy/List/Search.pm:101 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Book.pm:90 +msgid "This book was not modified." +msgstr "書目未異動。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Book.pm:94 +msgid "This book has been successfully added." +msgstr "書目建好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Book.pm:98 +msgid "This book has been successfully updated." +msgstr "書目存好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Book.pm:102 +msgid "This book has been successfully deleted." +msgstr "書目刪掉了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Legend.pm:93 +msgid "This legend entry was not modified." +msgstr "傳奇未異動。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Legend.pm:97 +msgid "This legend entry has been successfully added." +msgstr "傳奇寫好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Legend.pm:101 +msgid "This legend entry has been successfully updated." +msgstr "傳奇存好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Legend.pm:105 +msgid "This legend entry has been successfully deleted." +msgstr "傳奇刪掉了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Material.pm:86 +msgid "This material was not modified." +msgstr "史料未異動。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Material.pm:90 +msgid "This material has been successfully added." +msgstr "史料建好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Material.pm:94 +msgid "This material has been successfully updated." +msgstr "史料存好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/Material.pm:98 +msgid "This material has been successfully deleted." +msgstr "史料刪掉了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm:76 +msgid "This type was not modified." +msgstr "類型未異動。" + +#: magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm:80 +msgid "This type has been successfully added." +msgstr "類型建好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm:84 +msgid "This type has been successfully updated." +msgstr "類型存好了。" + +#: magicat/lib/perl5/Selima/emandy/Processor/MtrlType.pm:88 +msgid "This type has been successfully deleted." +msgstr "類型刪掉了。" + +#: magicat/lib/perl5/Selima/emandy/List/Books/NotToBorrow.pm:25 +msgid "Manage Books Not to Be Borrowed" +msgstr "管理一般書目" + +#: magicat/lib/perl5/Selima/emandy/List/Books/ToBorrow.pm:25 +msgid "Manage Books to be Borrowed" +msgstr "管理待借書目" + +#: magicat/lib/perl5/Selima/emandy/List/Legend/Public.pm:131 +msgid "The legend entry seperator" +msgstr "傳奇分隔線" diff --git a/htdocs/emandy/magicat/soc-cv.html b/htdocs/emandy/magicat/soc-cv.html new file mode 100644 index 0000000..0b36091 --- /dev/null +++ b/htdocs/emandy/magicat/soc-cv.html @@ -0,0 +1,83 @@ + + + + + + + + + + + +i + + + +

i

+

ӤH򥻸

+
    +
  • mW: dP
  • +
  • ye: OWٶL
  • +
  • ͤ: 1970.2.9
  • +
  • {~a}:éMs͸401213
  • +
  • Tel:(02)3233-7444]H^
  • +
  • Cell:0953360398
  • +
  • ä[a}:sL135
  • +
  • Tel:(07)7018867
  • +
+

Ш|{

+
    +
  • sꤤA1985~6벦
  • +
  • ٥ߩsA1988~6벦
  • +
  • ƤjǥvǨtA1993~6벦
  • +
  • jǾvtӤhZA1998~6벦
  • +
+

ΰѻP

+
    +
  • ƤjǡGN
  • +
  • jǡGk
  • +
+

u@g

+
    +
  • ʭ^Tq~ȧUz]1994~^
  • +
  • |Ƭs߱M]1996-1997~^
  • +
  • O_ߤhLӥNұЮv]1997~^
  • +
  • ƱMǮխݥv]1998-1999~^
  • +
  • ߪŤjǭv]1998-^
  • +
  • اXqUs]1998~^
  • +
  • xWjǰksǧUzs]1998-1999~^
  • +
  • äkʤJfhercafeukܡvM@a
  • +
  • MؤjǾvsҳŤjб°|peiNxWHں--PGغcι20@xWu{NʡvϬ١jsUz]1999~10-2000~9멳^
  • +
  • |ǥvqTs
  • +
+ +

ZB

+ +

dzN@~

+
    +
  • dP]1998^AqqFvѻPݼwkBʡA1891-1918rAjǾvsҺӤhפC
  • +
  • iBdP]1999^AqxWksPʥШ|rAo1999~ѥxjksǥDuʥШ|ڬQ|vC
  • +
  • iBdPBJ@@]1999^AqxһPGqxjksǽͰcبơrAo1999~MjʻP|sǥDuȬwksǵ{Q|vC
  • +
+

M

+
    +
  • rZ
  • +
  • qѸƳBz
  • +
  • w쬡
  • +
+ + \ No newline at end of file diff --git a/htdocs/emandy/robots.txt b/htdocs/emandy/robots.txt new file mode 100644 index 0000000..5fd6448 --- /dev/null +++ b/htdocs/emandy/robots.txt @@ -0,0 +1,10 @@ +User-agent: * +Crawl-delay: 1 +Disallow: /magicat/ +Disallow: /legend/ + +User-agent: chklinks +Disallow: + +User-agent: HTTrack +Disallow: / diff --git a/htdocs/emandy/scripts/accounting.js b/htdocs/emandy/scripts/accounting.js new file mode 100644 index 0000000..dbeccbe --- /dev/null +++ b/htdocs/emandy/scripts/accounting.js @@ -0,0 +1,152 @@ +/* Mandy Wu's Website + * accounting.js: The accounting-related JavaScript subroutines. + */ + +/* Copyright (c) 2007-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2007-09-26 + */ + +// setAutoSummary: Automatically supply a summary +function setAutoSummary(subj) { + var i, j, sum, dateText, today, subjText, subjCode, thisMonth; + // Get the name prefix of this selection + i = subj.name.indexOf("subj"); + // Obtain the summary column + sum = subj.form[subj.name.substr(0, i) + "summary"]; + // Get today's date + today = new Date; + dateText = trim(subj.form.date.value); + if (!isDate(dateText)) + return; + today.setFullYear(dateText.substr(0, 4)); + today.setMonth(dateText.substr(5, 2) - 1); + today.setDate(dateText.substr(8, 2)); + thisMonth = today.getMonth() + 1; + // Obtain the selected subject + // The value of the selection is S/N but not subject code, + // so we have to obtain the subject code from the option text + subjText = subj.options[subj.selectedIndex].text; + subjCode = parseInt(subjText.substr(0, subjText.indexOf(" "))); + switch (subjCode) { + // 62561 和信 0927-02-1680 + case 62561: + sum.value = "和信" + ((thisMonth + 10) % 12 + 1) + "月"; + break; + // 21412 應付帳款—玉山信用卡 + case 21412: + // Only fill in the debit side, as our repay + if (sum.name.substr(0, 4) == "debt") { + // 25 or later - assume to be of this month + if (today.getDate() >= 25) { + sum.value = "玉山信用卡" + thisMonth + "月"; + // Before 25 - assume to be of previous month + } else { + sum.value = "玉山信用卡" + ((thisMonth + 10) % 12 + 1) + "月"; + } + } + break; + // 21413 應付帳款—台新信用卡 + case 21413: + // Only fill in the debitowing side, as our repay + if (sum.name.substr(0, 4) == "debt") { + // 25 or later - assume to be of this month + if (today.getDate() >= 25) { + sum.value = "台新信用卡" + thisMonth + "月"; + // Before 25 - assume to be of previous month + } else { + sum.value = "台新信用卡" + ((thisMonth + 10) % 12 + 1) + "月"; + } + } + break; + } + return; +} + +// acctRepQueryDisableNoUseRanges: Disable range parameters that are not in use +function acctRepQueryDisableNoUseRanges() { + var i, form, curValue; + // Obtain our form + form = document.forms["acctrepquery"]; + if (form == undefined) + return; + // Find the current selection + for (i = 0; i < form.r.length; i++) { + if (form["r"][i].checked) { + curValue = form["r"][i].value; + break; + } + } + // Disable or enable the month selection + if (curValue == "m") + form["m"].disabled = false; + else + form["m"].disabled = true; + // Disable or enable the year selection + if (curValue == "y") + form["y"].disabled = false; + else + form["y"].disabled = true; + // Disable or enable the start and end date + if (curValue == "s") { + form["f"].disabled = false; + form["t"].disabled = false; + } else { + form["f"].disabled = true; + form["t"].disabled = true; + } + return; +} + +// calcTotal: Calculating the total +function calcTotal(amount) { + var i, j, side, sum, a, pos, isNumber; + a = "NT$ 3,433.00"; + side = amount.name.substr(0, 4); + for ( i = 0, sum = 0; + amount.form[side + i + "amount"] != undefined; + i++) { + a = amount.form[side + i + "amount"]; + // Trim the text + a.value = trim(a.value); + // Remove the dollar sign + if (a.value.substr(0, 3) == "NT$") + a.value = a.value.substr(3); + // Trim the text again, for possible spaces after the dollar sign + a.value = trim(a.value); + // Remove the decimal point + if (a.value.substr(a.value.length - 3) == ".00") + a.value = a.value.substr(0, a.value.length - 3); + // Remove the thousand seperators + while ((pos = a.value.indexOf(",")) != -1) { + a.value = a.value.substr(0, pos) + a.value.substr(pos + 1); + } + // Check if it is a number + for (j = 0, isNumber = true; j < a.value.length; j++) { + if (a.value.charCodeAt(j) < 48 || a.value.charCodeAt(j) > 57) { + isNumber = false; + break; + } + } + // Add the amount + if (isNumber) + sum = sum + a.value * 1; + } + a = amount.form[side + "total"]; + if (a != undefined) + a.value = sum; +} diff --git a/htdocs/emandy/scripts/common.js b/htdocs/emandy/scripts/common.js new file mode 100644 index 0000000..43d11f4 --- /dev/null +++ b/htdocs/emandy/scripts/common.js @@ -0,0 +1,139 @@ +/* Mandy Wu's Website + * common.js: The common JavaScript subroutines. + */ + +/* Copyright (c) 2007-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2007-09-27 + */ + +// _: Gettext +function _(msg) { + var i; + for (i = 0; i < lc_messages.length; i++) { + if (lc_messages[i][0] == msg) { + return lc_messages[i][1]; + } + } + return msg; +} +// The messages +lc_messages = []; + +// isEmail: Check if an email address is legal +function isEmail(a) { + var i, c, re; + if (typeof(RegExp) == "undefined") return true; + re = new RegExp("^[\\w\\-]+(\\.[\\w\\-]+)*\\@([\\w\\-]+\\.)+[\\w\\-]+$"); + if (typeof(a) != "string") return false; + a = a.toLowerCase(); + if (re.exec(a) == null) return false; + return true; +} + +// isDate: Check if a date is legal +function isDate(dateText) { + var i, year, month, day, maxDay; + if (dateText.length != 10) { + return false; + } + // Check each character + for (i = 0; i < dateText.length; i++) { + // The dash sign + if (i == 4 || i == 7) { + if (dateText.charAt(i) != "-") + return false; + // The digits + } else { + if (dateText.charCodeAt(i) < 48 || dateText.charCodeAt(i) > 57) + return false; + } + } + // Check if the date is valid + year = dateText.substr(0, 4) * 1; + month = dateText.substr(5, 2) * 1; + day = dateText.substr(8, 2) * 1; + // A reasonable month + if (month < 1 || month > 12) + return false; + // Find the maximum day in this month + switch (month) { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + maxDay = 31; + break; + case 4: + case 6: + case 9: + case 11: + maxDay = 30; + break; + case 2: + maxDay = 28; + if (year % 4 == 0) + maxDay = 29; + if (year % 100 == 0) + maxDay = 28; + if (year % 400 == 0) + maxDay = 29; + break; + } + // A reasonable day + if (day < 1 || day > maxDay) + return false; + return true; +} + +// trim: Trim the leading and tailing spaces +function trim(a) { + var pos, start, len, spaces; + start = 0; + len = a.length; + spaces = " \t\f\n\r"; + for (start = 0; start < a.length && spaces.indexOf(a.charAt(start)) >= 0; start++, len--); + for (pos = a.length - 1; pos >= 0 && spaces.indexOf(a.charAt(pos)) >= 0; pos--, len--); + return a.substr(start, len); +} +function trimText(a) { + var pos, start, len, spaces, newlines; + start = 0; + len = a.length; + spaces = " \t\f\n\r"; + newlines = "\n\r"; + for (start = 0; start < a.length && spaces.indexOf(a.charAt(start)) >= 0; start++, len--); + for ( ; start-1 >= 0 && newlines.indexOf(a.charAt(start-1)) < 0; start--, len++); + for (pos = a.length - 1; pos >= 0 && spaces.indexOf(a.charAt(pos)) >= 0; pos--, len--); + return a.substr(start, len); +} + +// Replace one phace with another in a string +function replace(source, oldStr, newStr) { + var pos; + pos = 0; + while (true) { + pos = source.indexOf(oldStr, pos); + if (pos == -1) break; + source = source.substr(0, pos) + newStr + source.substr(pos + oldStr.length) + pos += newStr.length; + } + return source; +} diff --git a/htdocs/emandy/scripts/lang.zh-tw.js b/htdocs/emandy/scripts/lang.zh-tw.js new file mode 100644 index 0000000..78fe193 --- /dev/null +++ b/htdocs/emandy/scripts/lang.zh-tw.js @@ -0,0 +1,26 @@ +/* Mandy Wu's Website + * lang.zh-tw.js: The Chinese (Taiwan) localized messages. + */ + +/* Copyright (c) 2007-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2007-09-27 + */ + +// The messages +lc_messages = [ +]; diff --git a/htdocs/emandy/stylesheets/analog.css b/htdocs/emandy/stylesheets/analog.css new file mode 100644 index 0000000..e844108 --- /dev/null +++ b/htdocs/emandy/stylesheets/analog.css @@ -0,0 +1,29 @@ +/* Mandy Wu's Website + * analog.css: The style sheet for Analog analysis reports. + */ + +/* Copyright (c) 2006-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2006-11-15 + */ + +@import url("common.css"); + +p { + margin: 1em 0; + text-indent: 0; +} diff --git a/htdocs/emandy/stylesheets/common.css b/htdocs/emandy/stylesheets/common.css new file mode 100644 index 0000000..e6e0c14 --- /dev/null +++ b/htdocs/emandy/stylesheets/common.css @@ -0,0 +1,353 @@ +/* Mandy Wu's Website + * common.css: The common style sheet. + */ + +/* Copyright (c) 2006-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2006-11-15 + */ + +/* General settings */ +body { + /*background: white url("../images/backgrnd.gif") repeat-y scroll;*/ + color: black; + margin: 0; + padding: 0.5em; +} +.body { + margin: 0; + padding: 1em 5em; +} +.body h1 { + margin-left: -1em; +} +a:link, a:visited, a:active { + background-color: transparent; + color: blue; + text-decoration: none; +} +a:hover { + background-color: yellow; + color: inherit; + text-decoration: underline; +} +p { + text-indent: 2em; +} +.en { + font-family: Arial, sans-serif; +} +p.en { + margin: 0 0 0.5em 0; +} +h1, h2, h3, h4, h5, h6 { + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-weight: normal; + margin: 0 0 0.5em 0; + padding: 0; +} +address { + font-size: 0.833em; + display: block; +} +pre { + margin: 0; +} +dl dt { + margin: 0 0 0.5em 0; + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.44em; +} +dl dd { + margin: 0.5em 0 0.5em 3em; +} +caption { + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.44em; +} +form { + margin: 0; +} +#contents { + margin: 1em 15%; +} +.note { + font-size: 0.833em; + font-style: italic; +} +q { + quotes: "「" "」" "『" "』"; +} +div.errmsg { + margin: 1em 0.5in; +} + +/* The navigation bar */ +.navibar, .pagebar, .langs { + text-align: center; + font-size: 0.833em; +} +.navibar .text { + width: 4em; +} +.nav hr { + margin: 0.1em 0; + padding: 0; + height: 0; +} + +/* The title */ +.title { + margin-left: 40px; +} +.intro { + margin: 1em 80px; +} +.toc { + margin: 1em 40px; +} +.toc li { + margin: 1em 40px; +} + +/* The footer */ +.footer { + clear: both; + font-size: 0.833em; + text-align: center; +} +.footer p { + margin: 0; + text-indent: 0; +} +.footer img { + border-style: none; +} +.footer .modperl img { + height: 30px; + width: 110px; +} + +/* The default list */ +.deflist { + margin: 1em 0; +} +.deflist th { + white-space: nowrap; +} +.deflist th, .deflist td { + padding: 0.2em 0.5em; + vertical-align: top; +} +.deflist thead { + background-color: silver; + color: black; +} +.deflist tbody th { + font-weight: normal; +} +.deflist .listno, .deflist .listdel { + text-align: center; +} +.deflist .oddrow { + background-color: #FFE0E0; + color: black; +} +.deflist .evenrow { + background-color: #E0E0FF; + color: black; +} +.deflist .amount { + text-align: right; +} +.deflist .amount .neg { + color: red; + background-color: transparent; +} +.deflist .crdtsubj { + text-indent: 2em; +} +.deflist .subjlv2 { + text-indent: 1em; +} +.deflist .subjlastlv { + text-indent: 2em; +} + +/* The default form */ +.defform { + margin: 0; + width: 100%; +} +/* Refer to http://www.w3.org/Style/threepart-f.css */ +/* The child selectors are a hack to hide these rules from WinIE6 */ +body>form.defform { + width: auto; +} +.defform table { + margin: 0 auto; + width: 100%; +} +.defform th, .defform td { + text-align: left; + vertical-align: top; +} +.defform .thfile { + width: 9em; +} +.defform .th { + width: 8.5em; +} +.defform .oldnew { + width: 3.5em; +} +.defform td .text, .defform td textarea { + width: 100%; +} +.defform td .prompt { + font-style: italic; + margin: 0; +} +.defform td ol, .defform td li ul { + margin: 0 0 0 2em; + padding: 0; +} +.defform td ul, .defform td li { + margin: 0; + padding: 0; +} +.defform td ul li { + list-style: none; +} +.defform td .oneline li { + display: block; + float: left; + margin-right: 0.5em; +} +.defform td h4, .defform td .picinfo, .defform td .piccap { + margin: 0; + padding: 0; +} +.defform .amount { + text-align: right; +} + +/* The home page */ +.covertoc h1, .covertoc h3 { + font-weight: bolder; +} +.covertoc ul li h2 { + font-size: 1.2em; +} + +/* The related links */ +.links .linkslist { + margin: 1em 80px; +} +.links .linkslist li { + margin: 1em 0; +} +.links .linkslist li img { + vertical-align: top; +} +.links .linkslist li cite { + font-family: "標楷體", DFKai-SB, cursive, serif; + font-size: 1.2em; + font-style: normal; +} + +/* The blog */ +.legend .entry { + padding: 1em; + margin: 1em 0; + border-width: thin thick thick thin; + border-style: solid; + border-color: #400020; + background-color: white; + color: inherit; +} +.legend .entry .freetext { + margin: 1em 0 0 0; +} +.legend .entry blockquote { + border-width: thin thick thick thin; + border-style: solid; + border-color: #400020; + margin: 1em; + padding: 1em; +} +@media screen, print { + .legend .entries hr { + display: none; + } +} + +/* The full text search */ +.searchresult em { + background-color: yellow; + color: red; +} +.searchresult h3 { + margin: 0; +} +.searchresult li { + margin-bottom: 1em; +} + +/* The accessibility guides */ +.skiptobody { + position: absolute; + line-height: 0; + left: 0; + top: 0; + z-index: -9; +} +.accessguide { + float: left; + font-size: 0.5em; + color: #FFFFFF; +} +.body .accessguide { + margin: 0 0 0 -10em; +} + +/* The preview mark */ +.previewmark { + position: fixed; + top: 1em; + left: 1em; + border: thick solid red; + color: red; + background-color: transparent; + margin: 0; + padding: 0.5em; +} +.previewmark h2 { + text-transform: uppercase; + text-align: center; + margin: 0; + padding: 0; +} +.previewmark p { + margin: 0; + padding: 0; + text-indent: 0; +} +.previewmark a, .previewmark a:visited, .previewmark a:hover { + color: red; + background-color: transparent; +} diff --git a/htdocs/emily/cgi-bin/counter.cgi b/htdocs/emily/cgi-bin/counter.cgi new file mode 100755 index 0000000..4000ddb --- /dev/null +++ b/htdocs/emily/cgi-bin/counter.cgi @@ -0,0 +1,219 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# counter.cgi: The visitor counter. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-07 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub dont_update(); +sub read_counter(); +sub update_counter(); +sub log_visitor($); +sub counter_cookie(); +sub html_image($); + +use Fcntl qw(:seek); +use Date::Format qw(time2str); +use GD; +use IO::NestedCapture qw(CAPTURE_STDOUT); +use Net::CIDR::Lite qw(); + +use constant DATA_FILE => $ENV{"DOCUMENT_ROOT"} . "/magicat/data/counter.dat"; +use constant LOG_FILE => "/var/log/apache2/emily/counter.log"; +use vars qw($OUR_NETWORKS @FGCOLOR @BGCOLOR $FONT); +# People in our networks will not be counted +$OUR_NETWORKS = Net::CIDR::Lite->new( + qw(127.0.0.1/8 10.0.0.0/8 211.20.30.96/29)); +@FGCOLOR = (0, 0, 0); # #000000 Black +@BGCOLOR = (255, 255, 255); # #FFFFFF White +$FONT = gdLargeFont; +use constant TRANSPARENT => 1; +use constant COOKIE_NAME => "counter"; +use constant COUNT_ARG => "countme"; +use constant IGNORE_ARG => "ignoreme"; +initenv( -allowed => [qw(GET HEAD)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0, + -multilang => 0); + +main; +exit 0; + +sub main() { + local ($_, %_); + + # If we should not update the counter + if (dont_update) { + # Check last-modified here + my (@tables, @files); + @tables = qw(); + @files = (DATA_FILE); + http_304 if not_modified @tables, @files; + html_image read_counter; + + # Update the counter + } else { + $_ = html_image update_counter; + # Log the visitor + log_visitor $_; + } + + # Set the counter cookie + $NEWCOOKIES{COOKIE_NAME()} = $_ if defined ($_ = counter_cookie); + + return; +} + +# dont_update: If we should not update the counter +sub dont_update() { + local ($_, %_); + # Find any reason that we should not update the counter + # If this visitor came from our own network + return 1 if $OUR_NETWORKS->find($ENV{"REMOTE_ADDR"}); + # If this visitor had been counted + return 1 if exists $COOKIES{COOKIE_NAME()}; + # If we are not told to count this visitor + return 1 if !defined $GET->param(COUNT_ARG); + # Well, update it + return 0; +} + +# read_counter: Read the counter +sub read_counter() { + return -s DATA_FILE? xfread DATA_FILE: 0; +} + +# update_counter: Update the counter +sub update_counter() { + local ($_, %_); + # File exists + if (-s DATA_FILE) { + my $FH; + open $FH, "+<", DATA_FILE or http_500 DATA_FILE . ": $!"; + flock $FH, LOCK_EX or http_500 DATA_FILE . ": $!"; + $_ = <$FH>; + $_++; + seek $FH, 0, SEEK_SET or http_500 DATA_FILE . ": $!"; + truncate $FH, 0 or http_500 DATA_FILE . ": $!"; + print $FH $_ or http_500 DATA_FILE . ": $!"; + flock $FH, LOCK_UN or http_500 DATA_FILE . ": $!"; + close $FH or http_500 DATA_FILE . ": $!"; + + # Not exists or zero sized -- create a new one + } else { + xfwrite DATA_FILE, ($_ = 1); + } + return $_; +} + +# log_visitor: Log the visitor +sub log_visitor($) { + local ($_, %_); + my ($host, $user, $date, $uri, $size, $referer, $ua, $langs, $FD); + $size = $_[0]; + + # Gather the infomation to log + $host = (defined remote_host)? remote_host: $ENV{"REMOTE_ADDR"}; + $user = (exists $ENV{"REMOTE_USER"} && $ENV{"REMOTE_USER"} ne "")? + $ENV{"REMOTE_USER"}: "-"; + $date = time2str("%d/%b/%Y:%T %z", time); + $uri = $REQUEST_URI; + $referer = (exists $ENV{"HTTP_REFERER"} && $ENV{"HTTP_REFERER"} ne "")? + $ENV{"HTTP_REFERER"}: "-"; + $ua = (exists $ENV{"HTTP_USER_AGENT"} && $ENV{"HTTP_USER_AGENT"} ne "")? + $ENV{"HTTP_USER_AGENT"}: "="; + $langs = (exists $ENV{"HTTP_ACCEPT_LANGUAGE"} && $ENV{"HTTP_ACCEPT_LANGUAGE"} ne "")? + $ENV{"HTTP_ACCEPT_LANGUAGE"}: "-"; + + # Compose the log record 組合紀錄行 + $_ = sprintf "%s - %s [%s] \"%s %s %s\" 200 %s \"%s\" \"%s\" \"%s\" %s %s\n", + $host, $user, $date, $ENV{"REQUEST_METHOD"}, $uri, + $ENV{"SERVER_PROTOCOL"}, $size, $referer, $ua, $langs, + $ENV{"REMOTE_ADDR"}, country_lookup($ENV{"REMOTE_ADDR"}); + + # Save the log record 儲存記錄 + xfappend LOG_FILE, $_; + + return; +} + +# counter_cookie: Set the counter cookie +sub counter_cookie() { + local ($_, %_); + # Leave our network alone + return if $OUR_NETWORKS->find($ENV{"REMOTE_ADDR"}); + # Already set + return if exists $COOKIES{COOKIE_NAME()}; + # Count me + return new CGI::Cookie( -name=>COOKIE_NAME, + -value=>"counted", + -path=>$REQUEST_PATH) + if defined $GET->param(COUNT_ARG); + # Ignore me + return new CGI::Cookie( -name=>COOKIE_NAME, + -value=>"ignored", + -path=>$REQUEST_PATH) + if defined $GET->param(IGNORE_ARG); + # Leave it alone + return; +} + +# html_image: Make the image from the counter value +sub html_image($) { + local $_; + my ($counter, $image, $width, $height, $fgcolor, $bgcolor); + $counter = $_[0]; + + # Group the counter with commas at thousand digits. + $counter = fmtno($counter); + + # Initialize the image object + # Get the width and height + $width = $FONT->width * (length $counter); + $height = $FONT->height; + # Create an image object + $image = GD::Image->new($width, $height); + # Create the forground/background color objects + $fgcolor = $image->colorAllocate(@FGCOLOR); + $bgcolor = $image->colorAllocate(@BGCOLOR); + + # Draw the image + # Set the transparent background + $image->transparent($bgcolor) if TRANSPARENT; + # Paint the background + $image->filledRectangle(0, 0, $width, $height, $bgcolor); + # Write the text + $image->string($FONT, 0, 0, $counter, $fgcolor); + + # Output + $CONTENT_TYPE = "image/png"; + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1]; + $_ = $image->png; + print $_; + + return length $_; +} diff --git a/htdocs/emily/cgi-bin/last_update.cgi b/htdocs/emily/cgi-bin/last_update.cgi new file mode 100755 index 0000000..1f90250 --- /dev/null +++ b/htdocs/emily/cgi-bin/last_update.cgi @@ -0,0 +1,142 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# last_update.cgi: The last-update date of the whole web site. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-09 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub find_files_in(\@\@); +sub fmttime_local($); +sub html_image($); + +use File::Spec; +use GD; +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use vars qw(@DIREXCS %RDIREXCS @FGCOLOR @BGCOLOR $FONT); +# Directories to be excluded (no leading and trailing slashes) +@DIREXCS = qw(magicat); +@FGCOLOR = (0, 0, 0); # #000000 Black +@BGCOLOR = (255, 255, 255); # #FFFFFF White +$FONT = gdLargeFont; +use constant TRANSPARENT => 1; +initenv( -allowed => [qw(GET HEAD)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0, + -multilang => 0); +%RDIREXCS = map { File::Spec->catfile($DOC_ROOT, $_) => 1 } @DIREXCS; + +main; +exit 0; + +sub main() { + local ($_, %_); + my (@tables, @files); + + @tables = qw(); + @files = qw(); + @_ = ($DOC_ROOT); + find_files_in(@files, @_); + http_304 if not_modified @tables, @files; + + html_image($LAST_MODIFIED); + + return; +} + +# find_files_in: an easy file finder +sub find_files_in(\@\@) { + local ($_, %_); + my ($files, $dirs, @subdirs, $DH, $ent); + ($files, $dirs) = @_; + + # Bounce for nothing + return if scalar(@$dirs) == 0; + # Look in these directories + @subdirs = qw(); + foreach my $dir (@$dirs) { + $dir =~ s/\/$//; + opendir $DH, $dir or die "$dir: $!"; + while (defined($_ = readdir $DH)) { + next if /^\./; + # Using catfile() is better, but a lot slower + $ent = File::Spec->catfile($dir, $_); + #$ent = "$dir/$_"; + if (-f $ent) { + push @$files, $ent; + } elsif (-d $ent) { + push @subdirs, $ent + if !exists $RDIREXCS{$ent}; + } + } + closedir $DH or die "$dir: $!"; + } + # Look in the subdirectories + find_files_in @$files, @subdirs; + return; +} + +# fmttime_local: Format the time using my own format +sub fmttime_local($) { + @_ = localtime $_[0]; + return sprintf "%d.%d.'%02d", $_[4]+1, $_[3], ($_[5]+1900) % 100; +} + +# html_image: Make the image from the last-update value +sub html_image($) { + local $_; + my ($last_update, $image, $width, $height, $fgcolor, $bgcolor); + $last_update = $_[0]; + + # Format the date to my preferred format + $last_update = fmttime_local($last_update); + + # Initialize the image object + # Get the width and height + $width = $FONT->width * (length $last_update); + $height = $FONT->height; + # Create an image object + $image = GD::Image->new($width, $height); + # Create the forground/background color objects + $fgcolor = $image->colorAllocate(@FGCOLOR); + $bgcolor = $image->colorAllocate(@BGCOLOR); + + # Draw the image + # Set the transparent background + $image->transparent($bgcolor) if TRANSPARENT; + # Paint the background + $image->filledRectangle(0, 0, $width, $height, $bgcolor); + # Write the text + $image->string($FONT, 0, 0, $last_update, $fgcolor); + + # Output + $CONTENT_TYPE = "image/png"; + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":raw"; + print $image->png; + + return; +} diff --git a/htdocs/emily/cgi-bin/mailto.cgi b/htdocs/emily/cgi-bin/mailto.cgi new file mode 100755 index 0000000..9e98586 --- /dev/null +++ b/htdocs/emily/cgi-bin/mailto.cgi @@ -0,0 +1,70 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# mailto.cgi: The e-mail hyperlink redirector. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-05-13 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_post(); + +use Fcntl qw(:seek); + +initenv(-allowed => [qw(POST)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $error; + + # Only POSTed forms are allowed + $error = check_post; + # If an error occurs + if (defined $error) { + http_400; + + # Else, save the data + } else { + http_303 "mailto:" . $POST->param("email"); + } + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::Checker::MailTo(curform); + $error = $checker->check(qw(email)); + return $error if defined $error; + # OK + return; +} diff --git a/htdocs/emily/cgi-bin/search.cgi b/htdocs/emily/cgi-bin/search.cgi new file mode 100755 index 0000000..40a6127 --- /dev/null +++ b/htdocs/emily/cgi-bin/search.cgi @@ -0,0 +1,55 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# search.cgi: The web site full-text search. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-11 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); + +use Fcntl qw(:seek); + +initenv(-allowed => [qw(GET HEAD)], + -session => 0, + -dbi_lock => {"pages" => LOCK_SH, + "links" => LOCK_SH, + "guestbook" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("search, query, full text search"), + "class" => "search"}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $LIST; + # List handler handles its own error + $LIST = new Selima::emily::List::Search; + html_header $LIST->{"title"}, $LIST->page_param; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/emily/copying.html.html b/htdocs/emily/copying.html.html new file mode 120000 index 0000000..3649ba5 --- /dev/null +++ b/htdocs/emily/copying.html.html @@ -0,0 +1 @@ +copying.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/copying.html.xhtml b/htdocs/emily/copying.html.xhtml new file mode 100644 index 0000000..17ae331 --- /dev/null +++ b/htdocs/emily/copying.html.xhtml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + +吳芳美網站版權聲明 + + + + + + + +
+ +
+ + +

吳芳美網站版權聲明

+ +

吳芳美網站版權聲明

+ +

吳芳美網站除留言板外,所有圖、文版權屬依瑪貓所有,歡迎轉載、引用,唯請遵守以下事項:

+ +
    +
  1. 必須以下列格式,註明原作者及出處網址: +
    作者:依瑪貓, http://emily.imacat.idv.tw/某某頁.html
    +
  2. +
  3. 不得對內容作任何更動、添增、刪改。
  4. +
  5. 吳芳美網站所有文字,除留言板外,歡迎非商業自由轉載、引用。欲作商業或學術文字轉載(含論文發表、媒體報導、書刊出版),必須事先取得依瑪貓同意。
  6. +
  7. 吳芳美網站所有圖片,在事先知會依瑪貓之下,歡迎非商業自由轉載、引用。欲作商業或學術轉載(含論文發表、媒體報導、書刊出版),必須事先取得依瑪貓同意。
  8. +
  9. 吳芳美網站留言板留言版權與吳芳美網站無關,另以留言板版權聲明為準。
  10. +
+ + +

吳芳美網站留言板版權聲明

+ +

吳芳美網站所有留言板留言版權屬各留言人所有,與吳芳美網站無關吳芳美網站版權聲明不適用於留言板留言。欲轉載、引用任何留言板留言,必須事先取得各該留言人之同意。若無法連絡該留言人,一律禁止轉載、引用。

+ +
+ +
+ + + + diff --git a/htdocs/emily/errors/301.html.html b/htdocs/emily/errors/301.html.html new file mode 120000 index 0000000..7d57edf --- /dev/null +++ b/htdocs/emily/errors/301.html.html @@ -0,0 +1 @@ +301.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/errors/301.html.xhtml b/htdocs/emily/errors/301.html.xhtml new file mode 100644 index 0000000..e0e3768 --- /dev/null +++ b/htdocs/emily/errors/301.html.xhtml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + +HTTP 301 網址已遷 + + + + + + + +
+ +
+ + +

HTTP 301 網址已遷

+ +

本頁已遷址,日後請更新妳的書籤或妳的最愛,並改往新址

+ +
+ +
+ + + + diff --git a/htdocs/emily/errors/303.html.html b/htdocs/emily/errors/303.html.html new file mode 120000 index 0000000..74b918a --- /dev/null +++ b/htdocs/emily/errors/303.html.html @@ -0,0 +1 @@ +303.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/errors/303.html.xhtml b/htdocs/emily/errors/303.html.xhtml new file mode 100644 index 0000000..8d08688 --- /dev/null +++ b/htdocs/emily/errors/303.html.xhtml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + +HTTP 303 續往下址 + + + + + + + +
+ +
+ + +

HTTP 303 續往下址

+ +

請續往後續的網址

+ +
+ +
+ + + + diff --git a/htdocs/emily/errors/307.html.html b/htdocs/emily/errors/307.html.html new file mode 120000 index 0000000..5730eb3 --- /dev/null +++ b/htdocs/emily/errors/307.html.html @@ -0,0 +1 @@ +307.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/errors/307.html.xhtml b/htdocs/emily/errors/307.html.xhtml new file mode 100644 index 0000000..bbe48c1 --- /dev/null +++ b/htdocs/emily/errors/307.html.xhtml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + +HTTP 307 網址暫移 + + + + + + + +
+ +
+ + +

HTTP 307 網址暫移

+ +

請參閱本頁目前的網址

+ +
+ +
+ + + + diff --git a/htdocs/emily/errors/400.html.html b/htdocs/emily/errors/400.html.html new file mode 120000 index 0000000..a1fe2e8 --- /dev/null +++ b/htdocs/emily/errors/400.html.html @@ -0,0 +1 @@ +400.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/errors/400.html.xhtml b/htdocs/emily/errors/400.html.xhtml new file mode 100644 index 0000000..499d5bc --- /dev/null +++ b/htdocs/emily/errors/400.html.xhtml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + +HTTP 400 語法錯誤 + + + + + + + +
+ +
+ + +

HTTP 400 語法錯誤

+ + + +

很抱歉,妳的要求語法錯誤,網站看不懂妳的要求。這可能是瀏覽器的問題,或妳輸入的網址有筆誤。請更正妳的筆誤,或請回吳芳美網站首頁重新瀏覽。

+ +

若有任何問題,請來信告訴我們

+ +
+ +
+ + + + diff --git a/htdocs/emily/errors/401.html.html b/htdocs/emily/errors/401.html.html new file mode 120000 index 0000000..f605262 --- /dev/null +++ b/htdocs/emily/errors/401.html.html @@ -0,0 +1 @@ +401.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/errors/401.html.xhtml b/htdocs/emily/errors/401.html.xhtml new file mode 100644 index 0000000..a1b17c6 --- /dev/null +++ b/htdocs/emily/errors/401.html.xhtml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + +HTTP 401 非請莫入 + + + + + + + +
+ +
+ + +

HTTP 401 非請莫入

+ +

很抱歉,本頁非請莫入,請回吳芳美網站首頁重新瀏覽。

+ +

若有任何問題,請來信告訴我們

+ +
+ +
+ + + + diff --git a/htdocs/emily/errors/403.html.html b/htdocs/emily/errors/403.html.html new file mode 120000 index 0000000..b668e83 --- /dev/null +++ b/htdocs/emily/errors/403.html.html @@ -0,0 +1 @@ +403.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/errors/403.html.xhtml b/htdocs/emily/errors/403.html.xhtml new file mode 100644 index 0000000..8290d2f --- /dev/null +++ b/htdocs/emily/errors/403.html.xhtml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + +HTTP 403 禁止進入 + + + + + + + +
+ +
+ + +

HTTP 403 禁止進入

+ + + +

很抱歉,本頁禁止進入,請回吳芳美網站首頁重新瀏覽。

+ +

若有任何問題,請來信告訴我們

+ +
+ +
+ + + + diff --git a/htdocs/emily/errors/404.html.html b/htdocs/emily/errors/404.html.html new file mode 120000 index 0000000..4a7a8d7 --- /dev/null +++ b/htdocs/emily/errors/404.html.html @@ -0,0 +1 @@ +404.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/errors/404.html.xhtml b/htdocs/emily/errors/404.html.xhtml new file mode 100644 index 0000000..35cb032 --- /dev/null +++ b/htdocs/emily/errors/404.html.xhtml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + +HTTP 404 找不到網頁 + + + + + + + +
+ +
+ + +

HTTP 404 找不到網頁

+ +

很抱歉,找不到妳想連的那一頁。請檢查妳的網址是否有誤。若妳是由其它地方連上這裡,請來信告訴我們

+ +

妳可以回到吳芳美網站首頁重新瀏覽。

+ +
+ +
+ + + + diff --git a/htdocs/emily/errors/405.html.html b/htdocs/emily/errors/405.html.html new file mode 120000 index 0000000..5a1bc52 --- /dev/null +++ b/htdocs/emily/errors/405.html.html @@ -0,0 +1 @@ +405.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/errors/405.html.xhtml b/htdocs/emily/errors/405.html.xhtml new file mode 100644 index 0000000..a8899f2 --- /dev/null +++ b/htdocs/emily/errors/405.html.xhtml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + +HTTP 405 要求方式無效 + + + + + + + +
+ +
+ + +

HTTP 405 要求方式無效

+ +

很抱歉,無法用這個方式連到此頁。請改用以下方式: $allowed 。

+ +

若有任何問題,請來信告訴我們

+ +
+ +
+ + + + diff --git a/htdocs/emily/errors/410.html.html b/htdocs/emily/errors/410.html.html new file mode 120000 index 0000000..a9dad98 --- /dev/null +++ b/htdocs/emily/errors/410.html.html @@ -0,0 +1 @@ +410.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/errors/410.html.xhtml b/htdocs/emily/errors/410.html.xhtml new file mode 100644 index 0000000..b8691c1 --- /dev/null +++ b/htdocs/emily/errors/410.html.xhtml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + +HTTP 410 已刪 + + + + + + + +
+ +
+ + +

HTTP 410 已刪

+ +

本頁內容已刪,造成不便請見諒。

+ +

妳可以回到吳芳美網站首頁重新瀏覽。

+ +
+ +
+ + + + diff --git a/htdocs/emily/errors/500.html.html b/htdocs/emily/errors/500.html.html new file mode 120000 index 0000000..628a797 --- /dev/null +++ b/htdocs/emily/errors/500.html.html @@ -0,0 +1 @@ +500.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/errors/500.html.xhtml b/htdocs/emily/errors/500.html.xhtml new file mode 100644 index 0000000..0a07b7d --- /dev/null +++ b/htdocs/emily/errors/500.html.xhtml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + +HTTP 500 網站執行錯誤 + + + + + + + +
+ +
+ + +

HTTP 500 網站執行錯誤

+ + + +

很抱歉,網站發生錯誤。這通常是 CGI 程式設計問題,請來信告訴我們

+ +

妳可以回到吳芳美網站首頁重新瀏覽。

+ +
+ +
+ + + + diff --git a/htdocs/emily/errors/503.html.html b/htdocs/emily/errors/503.html.html new file mode 120000 index 0000000..45a3b61 --- /dev/null +++ b/htdocs/emily/errors/503.html.html @@ -0,0 +1 @@ +503.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/errors/503.html.xhtml b/htdocs/emily/errors/503.html.xhtml new file mode 100644 index 0000000..fbad2fd --- /dev/null +++ b/htdocs/emily/errors/503.html.xhtml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + +HTTP 503 網站暫停服務 + + + + + + + +
+ +
+ + +

HTTP 503 網站暫停服務

+ + + +

很抱歉,網站暫時停止服務。我們正在更新網站,大約要花一個小時左右。請晚點再來,謝謝。

+ +
+ +
+ + + + diff --git a/htdocs/emily/favicon.ico b/htdocs/emily/favicon.ico new file mode 100644 index 0000000..30c1004 Binary files /dev/null and b/htdocs/emily/favicon.ico differ diff --git a/htdocs/emily/images/backgrnd.gif b/htdocs/emily/images/backgrnd.gif new file mode 100644 index 0000000..0236393 Binary files /dev/null and b/htdocs/emily/images/backgrnd.gif differ diff --git a/htdocs/emily/images/backgrnd.png b/htdocs/emily/images/backgrnd.png new file mode 100644 index 0000000..eaf2012 Binary files /dev/null and b/htdocs/emily/images/backgrnd.png differ diff --git a/htdocs/emily/images/email.gif b/htdocs/emily/images/email.gif new file mode 100644 index 0000000..165ff04 Binary files /dev/null and b/htdocs/emily/images/email.gif differ diff --git a/htdocs/emily/images/email.png b/htdocs/emily/images/email.png new file mode 100644 index 0000000..965fdac Binary files /dev/null and b/htdocs/emily/images/email.png differ diff --git a/htdocs/emily/images/modperl.png b/htdocs/emily/images/modperl.png new file mode 100644 index 0000000..9c295b0 Binary files /dev/null and b/htdocs/emily/images/modperl.png differ diff --git a/htdocs/emily/images/photo.jpg b/htdocs/emily/images/photo.jpg new file mode 100644 index 0000000..f3afba1 Binary files /dev/null and b/htdocs/emily/images/photo.jpg differ diff --git a/htdocs/emily/images/photo.png b/htdocs/emily/images/photo.png new file mode 100644 index 0000000..23610ee Binary files /dev/null and b/htdocs/emily/images/photo.png differ diff --git a/htdocs/emily/images/pridetour.gif b/htdocs/emily/images/pridetour.gif new file mode 100644 index 0000000..6aa3e3d Binary files /dev/null and b/htdocs/emily/images/pridetour.gif differ diff --git a/htdocs/emily/images/pridetour.png b/htdocs/emily/images/pridetour.png new file mode 100644 index 0000000..6455a57 Binary files /dev/null and b/htdocs/emily/images/pridetour.png differ diff --git a/htdocs/emily/index.html.html b/htdocs/emily/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/emily/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/index.html.xhtml b/htdocs/emily/index.html.xhtml new file mode 100644 index 0000000..e46357f --- /dev/null +++ b/htdocs/emily/index.html.xhtml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + +吳芳美 Emily Wu 旅行業專業經理人 + + + + + + + + +
+ + +
吳芳美的照片
+ +

旅行業專業經理人

+

吳芳美 Emily Wu

+ +

厭倦了旅行社眼花撩亂的行程嗎?想要一個真正適合自己的旅遊行程規劃嗎?我累積了十餘年旅行業經驗,經驗豐富,腳步遍及五大洲七十餘國。為您量身規劃專屬於您的行程,讓您玩得盡興,更多彩多姿。

+ + +

簡歷

+ +
    +
  • 觀光局檢證通過的合法旅行業專業經理人執照
  • +
  • 中華民國觀光領隊協會會員
  • +
  • 高雄金興旅行社業務經理
  • +
  • 高雄拾穗國際扶輪社社長 (1996-1997)
  • +
  • 高雄錫安國際聯青社社長 (1998-1999) 、南區總監 (2001-2002)
  • +
  • 高雄國際美術交流協會理事(參與多次國內外畫展之業餘畫家)
  • +
  • 連續十年扶輪社、聯青社等國際社團世界年會,訪問、參展、拜會等組團經驗
  • +
+ + +

服務內容

+ +
    +
  • 代辦護照及各國簽證、機票、訂房等
  • +
  • 提供國內外旅遊資訊
  • +
  • 個人、團體旅遊,特殊行程之規劃及報價
  • +
  • 各種不同旅遊行程之專業解析
  • +
+ + +

和我聯絡

+ +

需要我為您服務嗎?請在留言板上留言,或以 E-mail 和我聯絡。

+ +
+ + +
+ + + + diff --git a/htdocs/emily/links/airlines.html.html b/htdocs/emily/links/airlines.html.html new file mode 120000 index 0000000..a9bce91 --- /dev/null +++ b/htdocs/emily/links/airlines.html.html @@ -0,0 +1 @@ +airlines.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/links/airlines.html.xhtml b/htdocs/emily/links/airlines.html.xhtml new file mode 100644 index 0000000..167dec4 --- /dev/null +++ b/htdocs/emily/links/airlines.html.xhtml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + +航空公司 + + + + + + + +
+ +
+ + +

航空公司

+ + + + + +
+ +
+ + + + diff --git a/htdocs/emily/links/embassy.html.html b/htdocs/emily/links/embassy.html.html new file mode 120000 index 0000000..d86c89d --- /dev/null +++ b/htdocs/emily/links/embassy.html.html @@ -0,0 +1 @@ +embassy.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/links/embassy.html.xhtml b/htdocs/emily/links/embassy.html.xhtml new file mode 100644 index 0000000..1639615 --- /dev/null +++ b/htdocs/emily/links/embassy.html.xhtml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + +各國簽證辦事處 + + + + + + + +
+ +
+ + +

各國簽證辦事處

+ + + + + +
+ +
+ + + + diff --git a/htdocs/emily/links/gov.html.html b/htdocs/emily/links/gov.html.html new file mode 120000 index 0000000..2ec7593 --- /dev/null +++ b/htdocs/emily/links/gov.html.html @@ -0,0 +1 @@ +gov.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/links/gov.html.xhtml b/htdocs/emily/links/gov.html.xhtml new file mode 100644 index 0000000..08dba36 --- /dev/null +++ b/htdocs/emily/links/gov.html.xhtml @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + +政府機關 + + + + + + + +
+ +
+ + +

政府機關

+ + + + + +
+ +
+ + + + diff --git a/htdocs/emily/links/index.html.html b/htdocs/emily/links/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/emily/links/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/links/index.html.xhtml b/htdocs/emily/links/index.html.xhtml new file mode 100644 index 0000000..cb47a6b --- /dev/null +++ b/htdocs/emily/links/index.html.xhtml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + +相關連結 + + + + + + + +
+ + + +
+ + + + diff --git a/htdocs/emily/links/tourbord.html.html b/htdocs/emily/links/tourbord.html.html new file mode 120000 index 0000000..62f18c7 --- /dev/null +++ b/htdocs/emily/links/tourbord.html.html @@ -0,0 +1 @@ +tourbord.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/links/tourbord.html.xhtml b/htdocs/emily/links/tourbord.html.xhtml new file mode 100644 index 0000000..73b5829 --- /dev/null +++ b/htdocs/emily/links/tourbord.html.xhtml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + +各國觀光旅遊局 + + + + + + + +
+ +
+ + +

各國觀光旅遊局

+ + + + + +
+ +
+ + + + diff --git a/htdocs/emily/magicat/archive/cgi-bin/guestbook.cgi b/htdocs/emily/magicat/archive/cgi-bin/guestbook.cgi new file mode 100755 index 0000000..51b5c83 --- /dev/null +++ b/htdocs/emily/magicat/archive/cgi-bin/guestbook.cgi @@ -0,0 +1,136 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# 1-guestbook.cgi: The guestbook. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-07 + +use 5.008; +use utf8; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub html_foreword(); + +initenv(-session => 0, + -this_table => "guestbook", + -dbi_lock => {"guestbook" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("guestbook"), + "class" => "guestbook", + "javascripts" => [qw(/scripts/guestbook.js)]}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::emily::Processor::Guestbook::Public($POST); + $processor->process; + http_303 $REQUEST_FILE; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + # Old styled page number + http_301 $REQUEST_FILE if defined $GET->param("no"); + # List handler handles its own error + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::emily::Checker::Guestbook::Public(curform); + $error = $checker->check(qw(message name identity location + email url flood dup spam)); + return $error if defined $error; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM, $args); + $status = $_[0]; + $FORM = new Selima::emily::Form::Guestbook::Public($status); + $LIST = new Selima::emily::List::Guestbook::Public; + $args = $LIST->page_param; + html_header "留言板", $args; + html_foreword; + html_errmsg $status; + $FORM->html; + $LIST->html; + html_footer $args; + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# html_foreword: Print the HTML foreword +sub html_foreword() { + local ($_, %_); + print << "EOT"; +
+

若您有任何需要或疑問,請在此留言,我將儘速為您服務。

+
+ +EOT + return; +} + +no utf8; diff --git a/htdocs/emily/magicat/archive/magicat/cgi-bin/funds.cgi b/htdocs/emily/magicat/archive/magicat/cgi-bin/funds.cgi new file mode 100755 index 0000000..b520845 --- /dev/null +++ b/htdocs/emily/magicat/archive/magicat/cgi-bin/funds.cgi @@ -0,0 +1,51 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# funds.cgi: The fund performance viewer. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-12-30 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); + +initenv(-restricted => 0, + -this_table => "funds", + -dbi_lock => {"funds" => LOCK_SH}, + -lastmod => 0, + -page_param => {"keywords" => N_("mutual funds, performance, indicators")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $LIST; + # List handler handles its own error + $LIST = new Selima::emily::List::Funds; + html_header $LIST->{"title"}; + html_errmsg retrieve_status; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/emily/magicat/cgi-bin/actlog.cgi b/htdocs/emily/magicat/cgi-bin/actlog.cgi new file mode 100755 index 0000000..f788fca --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/actlog.cgi @@ -0,0 +1,51 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# actlog.cgi: The activity log viewer. + +# Copyright (c) 2005-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-05-10 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); + +initenv(-restricted => 1, + -allowed => [qw(GET HEAD)], + -lastmod => 0, + -lmfiles => [$ACTLOG], + -page_param => {"keywords" => N_("activity, logs")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $LIST; + # List handler handles its own error + $LIST = new Selima::List::ActLog; + html_header $LIST->{"title"}; + html_errmsg retrieve_status; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/emily/magicat/cgi-bin/groupmem.cgi b/htdocs/emily/magicat/cgi-bin/groupmem.cgi new file mode 100755 index 0000000..b6aad4b --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/groupmem.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# groupmem.cgi: The group-to-group membership administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); +sub import_selmember($); + +initenv(-restricted => 1, + -this_table => "groupmem", + -dbi_lock => {"groupmem" => LOCK_EX, + "groups" => LOCK_SH, + "groups AS grpmembers" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("group membership")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::GroupMem($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(del selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::GroupMem($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::GroupMem; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the membership record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This membership record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} + +# import_selmember: Import the selected member into the retrieved form +sub import_selmember($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("member", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups AS grpmembers"; + return $FORM; +} diff --git a/htdocs/emily/magicat/cgi-bin/groups.cgi b/htdocs/emily/magicat/cgi-bin/groups.cgi new file mode 100755 index 0000000..e82e907 --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/groups.cgi @@ -0,0 +1,357 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# groups.cgi: The account group administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selsubuser($); +sub import_selsubgroup($); +sub import_selsupgroup($); + +initenv(-restricted => 1, + -this_table => "groups", + -dbi_lock => {"groups" => LOCK_EX, + "usermem" => LOCK_EX, + "groupmem" => LOCK_EX, + "users" => LOCK_SH, + "users AS members" => LOCK_SH, + "groups AS members" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("groups")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Group($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my ($error, $FORM, $sn); + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth if !is_su && $sn == su_group_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error, $FORM, $sn); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(selsubuser selsubgroup selsupgroup)); + $error = $checker->check(qw(id dsc subuser subgroup supgroup)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(del selsubuser selsubgroup selsupgroup)); + $error = $checker->check(qw(id dsc subuser subgroup supgroup)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth if !is_su && $sn == su_group_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::Group($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Groups; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the group."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This group does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the user members list + $title = $DBH->strcat("users.id", "' ('", "users.name", "')'"); + $sql = "SELECT users.sn AS sn," + . " $title AS title" + . " FROM usermem" + . " INNER JOIN users ON usermem.member=users.sn" + . " WHERE usermem.grp=$sn" + . " ORDER BY users.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"subusercount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"subusercount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"subuser$_"} = 1; + $CURRENT{"subuser$_" . "sn"} = $$row{"sn"}; + $CURRENT{"subuser$_" . "title"} = $$row{"title"}; + } + + # Obtain the group members list + $sql = "SELECT groups.sn AS sn," + . " groups.dsc AS title FROM groupmem" + . " INNER JOIN groups ON groupmem.member=groups.sn" + . " WHERE groupmem.grp=$sn" + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"subgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"subgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"subgroup$_"} = 1; + $CURRENT{"subgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"subgroup$_" . "title"} = $$row{"title"}; + } + + # Obtain the belonging groups list + $sql = "SELECT groups.sn AS sn," + . " groups.dsc AS title FROM groupmem" + . " INNER JOIN groups ON groupmem.grp=groups.sn" + . " WHERE groupmem.member=$sn" + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"supgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"supgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"supgroup$_"} = 1; + $CURRENT{"supgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"supgroup$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} + +# import_selsubuser: Import the selected user into the retrieved form +sub import_selsubuser($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users AS members") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^subuser\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { userid $a cmp userid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^subuser\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^subuser\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("subuser$_" . "sn", $_[$_]); + $FORM->param("subuser$_", 1) if exists $_{$_[$_]}; + } + } + return; +} + +# import_selsubgroup: Import the selected user into the retrieved form +sub import_selsubgroup($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups AS members") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^subgroup\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { groupid $a cmp groupid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^subgroup\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^subgroup\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("subgroup$_" . "sn", $_[$_]); + $FORM->param("subgroup$_", 1) if exists $_{$_[$_]}; + } + } + return; +} + +# import_selsupgroup: Import the selected user into the retrieved form +sub import_selsupgroup($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^supgroup\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { groupid $a cmp groupid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^supgroup\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^supgroup\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("supgroup$_" . "sn", $_[$_]); + $FORM->param("supgroup$_", 1) if exists $_{$_[$_]}; + } + } + return; +} diff --git a/htdocs/emily/magicat/cgi-bin/guestbook.cgi b/htdocs/emily/magicat/cgi-bin/guestbook.cgi new file mode 100755 index 0000000..df1d83a --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/guestbook.cgi @@ -0,0 +1,211 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# guestbook.cgi: The guestbook administration. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-05-11 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "guestbook", + -dbi_lock => {"guestbook" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("guestbook")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Guestbook($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::emily::Checker::Guestbook(curform); + $error = $checker->check(qw(name identity location + email url message)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::emily::Checker::Guestbook(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(name identity location + email url message)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::emily::Checker::Guestbook(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::emily::Form::Guestbook($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::emily::List::Guestbook; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the message."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This message does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/emily/magicat/cgi-bin/linkcat.cgi b/htdocs/emily/magicat/cgi-bin/linkcat.cgi new file mode 100755 index 0000000..b4b5de0 --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/linkcat.cgi @@ -0,0 +1,292 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# linkcat.cgi: The related-link category administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selparent($); + +initenv(-restricted => 1, + -this_table => "linkcat", + -dbi_lock => {"linkcat" => LOCK_EX, + "links" => LOCK_SH, + "linkcatz" => LOCK_SH}, + -lastmod => 0, + -page_param => {"keywords" => N_("link categories")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LinkCat($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + return {"msg"=>N_("This category has [numerate,_1,a subcategory,subcategories]. It cannot be deleted. To delete the category, [numerate,_1,its subcategory,all of its subcategories] must first be deleted."), + "margs"=>[$CURRENT{"scatcount"}], + "isform"=>0} + if $CURRENT{"scatcount"} > 0; + return {"msg"=>N_("This category has [numerate,_1,a link,links]. It cannot be deleted. To delete the category, [numerate,_1,its link,all of its links] must first be deleted."), + "margs"=>[$CURRENT{"linkcount"}], + "isform"=>0} + if $CURRENT{"linkcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(selparent delparent)); + $error = $checker->check(qw(parent id ord title kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(del selparent delparent)); + $error = $checker->check(qw(parent id ord title kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(cancel)); + return {"msg"=>N_("This category has [numerate,_1,a subcategory,subcategories]. It cannot be deleted. To delete the category, [numerate,_1,its subcategory,all of its subcategories] must first be deleted."), + "margs"=>[$CURRENT{"scatcount"}], + "isform"=>0} + if $CURRENT{"scatcount"} > 0; + return {"msg"=>N_("This category has [numerate,_1,a link,links]. It cannot be deleted. To delete the category, [numerate,_1,its link,all of its links] must first be deleted."), + "margs"=>[$CURRENT{"linkcount"}], + "isform"=>0} + if $CURRENT{"linkcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::LinkCat($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::LinkCat; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lang, $lndb, $lndbdef, $langfile, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the category."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This category does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $lang = getlang; + $lndb = getlang LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + $langfile = getlang LN_FILENAME; + + # Obtain the belonging subcategories list + @_ = qw(); + push @_, "sn AS sn"; + if (@ALL_LINGUAS > 1) { + $title = $lang eq $DEFAULT_LANG? "title_$lndb": + "COALESCE(title_$lndb, title_$lndbdef)"; + push @_, "linkcat_fulltitle('$lang', parent, $title) AS title"; + } else { + push @_, "linkcat_fulltitle(parent, title) AS title"; + } + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS url"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_ischild($sn, sn)" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"scatcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"scatcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"scat$_" . "sn"} = $$row{"sn"}; + $CURRENT{"scat$_" . "title"} = $$row{"title"}; + $CURRENT{"scat$_" . "url"} = $$row{"url"}; + } + + # Obtain the belonging links list + @_ = qw(); + push @_, "links.sn AS sn"; + push @_, "links.title AS title"; + push @_, "url AS url"; + $sql = "SELECT " . join(", ", @_) . " FROM links" + . " INNER JOIN linkcatz ON linkcatz.link=links.sn" + . " WHERE linkcatz.cat=$sn" + . " ORDER BY title;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"linkcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"linkcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"link$_" . "sn"} = $$row{"sn"}; + $CURRENT{"link$_" . "title"} = $$row{"title"}; + $CURRENT{"link$_" . "url"} = $$row{"url"}; + } + + # OK + return; +} + +# import_selparent: Import the selected parent into the retrieved form +sub import_selparent($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "linkcat") { + $FORM->param("parent", $GET->param("selsn")); + $FORM->param("topmost", "false"); + } + return; +} diff --git a/htdocs/emily/magicat/cgi-bin/linkcatz.cgi b/htdocs/emily/magicat/cgi-bin/linkcatz.cgi new file mode 100755 index 0000000..989bf5b --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/linkcatz.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# linkcatz.cgi: The related-link category membership administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selcat($); +sub import_sellink($); + +initenv(-restricted => 1, + -this_table => "linkcatz", + -dbi_lock => {"linkcatz" => LOCK_EX, + "linkcat" => LOCK_SH, + "links" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("link categorization")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LinkCatz($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(selcat delcat sellink dellink)); + $error = $checker->check(qw(cat link)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(del selcat delcat sellink dellink)); + $error = $checker->check(qw(cat link)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::LinkCatz($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::LinkCatz; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the categorization record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This categorization record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selcat: Import the selected category into the retrieved form +sub import_selcat($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("cat", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "linkcat"; + return; +} + +# import_sellink: Import the selected link into the retrieved form +sub import_sellink($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("link", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "links"; + return $FORM; +} diff --git a/htdocs/emily/magicat/cgi-bin/links.cgi b/htdocs/emily/magicat/cgi-bin/links.cgi new file mode 100755 index 0000000..378f006 --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/links.cgi @@ -0,0 +1,240 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# links.cgi: The related-link administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "links", + -dbi_lock => {"links" => LOCK_EX, + "linkcatz" => LOCK_EX, + "linkcat" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("related links")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Link($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::Link(curform); + $error = $checker->check(qw(title title_2ln url icon + email addr tel fax dsc cats)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Link(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(title title_2ln url icon + email addr tel fax dsc cats)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::Link(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::Link($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Links; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lang, $lndb, $lndbdef, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the related link."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This related link does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $lang = getlang; + $lndb = getlang LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + + # Obtain the parent categories list + @_ = qw(); + push @_, "linkcat.sn AS sn"; + if (@ALL_LINGUAS > 1) { + $title = $lang eq $DEFAULT_LANG? "linkcat.title_$lndb": + "COALESCE(linkcat.title_$lndb, linkcat.title_$lndbdef)"; + push @_, "linkcat_fulltitle('$lang', linkcat.parent, $title) AS title"; + } else { + push @_, "linkcat_fulltitle(linkcat.parent, linkcat.title) AS title"; + } + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " INNER JOIN linkcatz ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.link=$sn" + . " ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord);\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"catcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"catcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"cat$_"} = $$row{"sn"}; + $CURRENT{"cat$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} diff --git a/htdocs/emily/magicat/cgi-bin/logout.cgi b/htdocs/emily/magicat/cgi-bin/logout.cgi new file mode 100755 index 0000000..b4ef2b6 --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/logout.cgi @@ -0,0 +1,158 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# logout.cgi: The log-out script. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub html_logoutform(); +sub html_relogin(); + +initenv(-dbi => DBI_NONE, + -lastmod => 1, + -page_param => {"keywords" => N_("log out")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LogOut($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $status; + # There is a result to display + $status = retrieve_status; + # Successfully logged out + if ( defined $status + && exists $$status{"status"} + && $$status{"status"} eq "success") { + # Nothing to check + return; + } + # Check if this user has logged in + unauth unless defined get_login_sn; + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + # Check if this user has logged in + unauth unless defined get_login_sn; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my $status; + $status = $_[0]; + # Not logged out yet + if (defined get_login_sn) { + html_header __("Log Out"); + html_errmsg $status; + html_logoutform; + html_footer; + + # Logged out + } else { + html_header __("Log Out"); + html_errmsg $status; + html_relogin; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# html_logoutform: Display a form to log out +sub html_logoutform() { + local ($_, %_); + my ($msg, $submit); + $msg = h(__("Are you sure you want to log out?")); + $submit = h(__("Log out")); + print << "EOT"; +
+
+

$msg

+ +
+
+ +EOT + return; +} + +# html_relogin: Display links to log in again +sub html_relogin() { + local ($_, %_); + $_ = h(__("Log in again.")); + print << "EOT"; +

$_

+ +EOT + return; +} diff --git a/htdocs/emily/magicat/cgi-bin/pages.cgi b/htdocs/emily/magicat/cgi-bin/pages.cgi new file mode 100755 index 0000000..3409190 --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/pages.cgi @@ -0,0 +1,221 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# pages.cgi: The web page administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-03 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "pages", + -dbi_lock => {"pages" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("pages")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Page($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to preview a submitted item + } elsif ($_ eq "preview") { + # Check at fetch_preview() + $error = fetch_preview; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::Page(curform); + $error = $checker->check(qw(path ord title body kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Page(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(path ord title body kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::Page(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + # A form to preview a submitted item + if (form_type eq "preview") { + html_preview; + + } else { + $FORM = new Selima::Form::Page($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + } + + # List the available items + } else { + $LIST = new Selima::List::Pages; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the page."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This page does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/emily/magicat/cgi-bin/rebuild.cgi b/htdocs/emily/magicat/cgi-bin/rebuild.cgi new file mode 100755 index 0000000..c135638 --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/rebuild.cgi @@ -0,0 +1,105 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# rebuild.cgi: The web page rebuilder. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-04 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); + +initenv(-restricted => 1, + -lastmod => 1, + -page_param => {"keywords" => N_("rebuild pages")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Rebuild($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + # Nothing to check here + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::Checker::Rebuild(curform); + $error = $checker->check(qw(type)); + return $error if defined $error; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $FORM); + $status = $_[0]; + $FORM = new Selima::Form::Rebuild($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + return; +} diff --git a/htdocs/emily/magicat/cgi-bin/scptpriv.cgi b/htdocs/emily/magicat/cgi-bin/scptpriv.cgi new file mode 100755 index 0000000..ee8494f --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/scptpriv.cgi @@ -0,0 +1,223 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# scptpriv.cgi: The script privilege administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); + +initenv(-restricted => 1, + -this_table => "scptpriv", + -dbi_lock => {"scptpriv" => LOCK_EX, + "groups" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("script privilege")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::ScptPriv($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(selgrp delgrp)); + $error = $checker->check(qw(script grp)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(del selgrp delgrp)); + $error = $checker->check(qw(script grp)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::ScptPriv($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::ScptPriv; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the script privilege record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This script privilege record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} diff --git a/htdocs/emily/magicat/cgi-bin/test.cgi b/htdocs/emily/magicat/cgi-bin/test.cgi new file mode 100755 index 0000000..39866f8 --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/test.cgi @@ -0,0 +1,40 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# test.cgi: The test script. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +use 5.008; +use utf8; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $r = shift; +my $d = new Selima::Destroy; +# Prototype declaration +use Time::HiRes qw(); +initenv; +$CONTENT_TYPE = "text/plain"; + + +printf "[%s] Done. %0.10f seconds elapsed.\n", + fmttime, Time::HiRes::time-$T_START; +exit 0; +no utf8; diff --git a/htdocs/emily/magicat/cgi-bin/usermem.cgi b/htdocs/emily/magicat/cgi-bin/usermem.cgi new file mode 100755 index 0000000..a11e265 --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/usermem.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# usermem.cgi: The user-to-group membership administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); +sub import_selmember($); + +initenv(-restricted => 1, + -this_table => "usermem", + -dbi_lock => {"usermem" => LOCK_EX, + "groups" => LOCK_SH, + "users AS usrmembers" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("user membership")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::UserMem($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(del selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::UserMem($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::UserMem; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the membership record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This membership record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} + +# import_selmember: Import the selected user into the retrieved form +sub import_selmember($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("member", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users AS usrmembers"; + return $FORM; +} diff --git a/htdocs/emily/magicat/cgi-bin/userpref.cgi b/htdocs/emily/magicat/cgi-bin/userpref.cgi new file mode 100755 index 0000000..e2f7adb --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/userpref.cgi @@ -0,0 +1,225 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# userpref.cgi: The user preference administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selusr($); + +initenv(-restricted => 1, + -this_table => "userpref", + -dbi_lock => {"userpref" => LOCK_EX, + "users" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("user preference")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::UserPref($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(selusr delusr)); + $error = $checker->check(qw(usr domain name value)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(del selusr delusr)); + $error = $checker->check(qw(usr domain name value)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::UserPref($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::UserPref; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the user preference."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This user preference does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selusr: Import the selected user into the retrieved form +sub import_selusr($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users") { + $FORM->param("usr", $GET->param("selsn")); + $FORM->param("everyone", "false"); + } + return; +} diff --git a/htdocs/emily/magicat/cgi-bin/users.cgi b/htdocs/emily/magicat/cgi-bin/users.cgi new file mode 100755 index 0000000..a53203b --- /dev/null +++ b/htdocs/emily/magicat/cgi-bin/users.cgi @@ -0,0 +1,273 @@ +#! /usr/bin/perl -w +# Emily Wu's Website +# users.cgi: The user account administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::emily; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-this_table => "users", + -dbi_lock => {"users" => LOCK_EX, + "usermem" => LOCK_EX, + "userpref" => LOCK_EX, + "groupmem" => LOCK_SH, + "groups" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("users")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + # Password not saved + $POST->delete("passwd", "passwd2"); + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::User($POST); + $success = $processor->process; + # Password not saved + $POST->delete("passwd", "passwd2"); + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my ($error, $FORM, $sn); + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Check the privilege to manage this table + unauth if !is_script_permitted; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted || $sn == get_login_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted; + unauth if !is_su && (is_su $sn || $sn == get_login_sn); + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + + # List the available items + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + # List handler handles its own error + } + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error, $FORM, $sn); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Check the privilege to manage this table + unauth unless is_script_permitted; + # Run the checker + $checker = new Selima::Checker::User(curform); + $error = $checker->check(qw(id passwd name supgroup)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted || $sn == get_login_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::User(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(id passwd name supgroup)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted; + unauth if !is_su && (is_su $sn || $sn == get_login_sn); + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::User(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::User($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Users; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the user."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This user does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging groups list + $sql = "SELECT groups.sn AS sn," + . " groups.dsc AS title FROM usermem" + . " INNER JOIN groups ON usermem.grp=groups.sn" + . " WHERE usermem.member=$sn" + . " AND groups.id!=" . $DBH->quote(SU_GROUP) + . " AND groups.id!=" . $DBH->quote(ADMIN_GROUP) + . " AND groups.id!=" . $DBH->quote(ALLUSERS_GROUP) + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"supgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"supgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"supgroup$_"} = 1; + $CURRENT{"supgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"supgroup$_" . "title"} = $$row{"title"}; + } + + # Get the admin flag + $CURRENT{"admin"} = is_admin($sn); + $CURRENT{"su"} = is_su($sn); + + # OK + return; +} diff --git a/htdocs/emily/magicat/data/counter.dat b/htdocs/emily/magicat/data/counter.dat new file mode 100644 index 0000000..34218e1 --- /dev/null +++ b/htdocs/emily/magicat/data/counter.dat @@ -0,0 +1 @@ +18813 \ No newline at end of file diff --git a/htdocs/emily/magicat/include/footer.html b/htdocs/emily/magicat/include/footer.html new file mode 100644 index 0000000..6cd1c98 --- /dev/null +++ b/htdocs/emily/magicat/include/footer.html @@ -0,0 +1,44 @@ +
+ diff --git a/htdocs/emily/magicat/include/header.html b/htdocs/emily/magicat/include/header.html new file mode 100644 index 0000000..240bc9d --- /dev/null +++ b/htdocs/emily/magicat/include/header.html @@ -0,0 +1,12 @@ +
+ +
diff --git a/htdocs/emily/magicat/index.html.html b/htdocs/emily/magicat/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/emily/magicat/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/emily/magicat/index.html.xhtml b/htdocs/emily/magicat/index.html.xhtml new file mode 100644 index 0000000..053016f --- /dev/null +++ b/htdocs/emily/magicat/index.html.xhtml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + +梅姬妳好 *^_^* + + + + + + + +
+ +
+ + +

我是梅姬,請多多指教 *^_^*

+ +
訪客計數器 訪客計數器
+ +

妳好,我是梅姬,是吳芳美網站的守護精靈。妳要怎麼設定網站,請儘管吩咐我喔~!

+ + +

管理網站

+ + + +

管理帳號

+ + + +

其她

+ + + +
+ + +
+ + + + diff --git a/htdocs/emily/magicat/lib/emily-semila.sql b/htdocs/emily/magicat/lib/emily-semila.sql new file mode 100644 index 0000000..5ce4ffa --- /dev/null +++ b/htdocs/emily/magicat/lib/emily-semila.sql @@ -0,0 +1,1085 @@ +-- 檔案名稱: emily.sql +-- 程式說明: 吳芳美網站資料庫定義檔 +-- 程式作者: 依瑪貓 imacat +-- 初稿日期: 2004-10-16 +-- 版權字樣: 版權所有 (c) 2004-2012 依瑪貓 + +SET NAMES 'big5'; + +START TRANSACTION; + + +-- +-- Table structure for table "mtime" +-- + +CREATE TABLE mtime ( + tabname varchar(16) NOT NULL PRIMARY KEY, + mtime timestamp NOT NULL DEFAULT now() +); +GRANT SELECT, INSERT, UPDATE, DELETE ON mtime TO nobody; + + +-- +-- Function definition for function "eschtml" +-- +-- integer eschtml(source text) +CREATE FUNCTION eschtml(source text) RETURNS text AS ' + DECLARE + result text; + BEGIN + result := source; + result := replace(result, ''&'', ''&''); + result := replace(result, ''<'', ''<''); + result := replace(result, ''>'', ''>''); + result := replace(result, ''"'', ''"''); + return result; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION eschtml(source text) TO nobody; + + +-- +-- Table structure for table "country" +-- + +CREATE TABLE country ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id char(2) NOT NULL UNIQUE CHECK (position(' ' in id) = 0), + name_en varchar(64) NOT NULL CHECK (name_en != ''), + name_zhtw varchar(32) CHECK (name_zhtw IS NULL OR name_zhtw != ''), + special boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL +); +GRANT SELECT, INSERT, UPDATE, DELETE ON country TO nobody; + + +-- +-- Table structure for table "users" +-- + +CREATE TABLE users ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(32) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + passwd char(32) NOT NULL, + name varchar(32) NOT NULL CHECK (name != ''), + disabled boolean NOT NULL DEFAULT FALSE, + deleted boolean NOT NULL DEFAULT FALSE, + lang varchar(5) CHECK (lang IS NULL OR lang != ''), + visits smallint NOT NULL DEFAULT 0 CHECK (visits >= 0), + visited timestamp, + ip inet, + host varchar(128), + ct char(2) REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON users TO nobody; + +CREATE VIEW users_list AS + SELECT + users.sn AS sn, + users.id AS id, + users.name AS name, + CASE WHEN users.disabled THEN '停用' + ELSE '' + END AS disabled, + CASE WHEN users.deleted THEN '已刪' + ELSE '' + END AS deleted, + CASE WHEN users.lang IS NULL THEN '(無)' + ELSE CASE users.lang + WHEN 'en' THEN '英文' + WHEN 'zh-tw' THEN '繁體中文' + WHEN 'zh-cn' THEN '簡體中文' + WHEN 'ja' THEN '日文' + WHEN 'de' THEN '德文' + WHEN 'es' THEN '西班牙文' + ELSE users.lang + END + END AS lang, + users.visits AS visits, + CASE WHEN users.visited IS NULL THEN '(無)' + ELSE to_char(users.visited, 'YYYY-MM-DD HH:MI:SS') + END AS visited, + CASE WHEN users.ip IS NULL THEN '(無)' + ELSE host(users.ip) + END AS ip, + CASE WHEN users.host IS NULL THEN '(無)' + ELSE users.host + END AS host, + CASE WHEN users.ct IS NULL THEN '(無)' + ELSE ct.name_zhtw + END AS ct, + to_char(users.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(users.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM users + LEFT JOIN country AS ct ON users.ct = ct.id + LEFT JOIN users AS createdby ON users.createdby = createdby.sn + LEFT JOIN users AS updatedby ON users.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON users_list TO nobody; + +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (923153018, 'imacat', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '依瑪貓', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (460376330, 'mandy', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '小招', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (723676436, 'guestbook', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '留言本', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); + +-- +-- Fixing the country table +-- + +ALTER TABLE country ADD FOREIGN KEY (createdby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +ALTER TABLE country ADD FOREIGN KEY (updatedby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +CREATE VIEW country_list AS + SELECT + country.sn AS sn, + country.id AS id, + COALESCE(country.name_zhtw, country.name_en) AS title, + CASE WHEN country.special THEN '特殊' + ELSE '' + END AS special, + to_char(country.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(country.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM country + LEFT JOIN users AS createdby ON country.createdby = createdby.sn + LEFT JOIN users AS updatedby ON country.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON country_list TO nobody; + + +-- +-- Table structure for table "groups" +-- + +CREATE TABLE groups ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(16) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + dsc varchar(64) NOT NULL CHECK (dsc != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groups TO nobody; + +CREATE VIEW groups_list AS + SELECT + groups.sn AS sn, + groups.id AS id, + groups.dsc AS dsc, + to_char(groups.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groups.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groups + LEFT JOIN users AS createdby ON groups.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groups.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON groups_list TO nobody; + +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (553229108, 'root', '總管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (802339805, 'guests', '暱名訪客', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (958210993, 'users', '已登入使用者', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (329685674, 'admin', '所有網站管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (157696540, 'acctman', '帳號管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (390105230, 'editor', '網站編輯', now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "usermem" +-- + +CREATE TABLE usermem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON usermem TO nobody; + +CREATE VIEW usermem_list AS + SELECT + usermem.sn AS sn, + groups.id || ' (' || groups.dsc || ')' AS grp, + members.id || ' (' || members.name || ')' AS member, + to_char(usermem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(usermem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM usermem + LEFT JOIN groups ON usermem.grp = groups.sn + LEFT JOIN users AS members ON usermem.member = members.sn + LEFT JOIN users AS createdby ON usermem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON usermem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON usermem_list TO nobody; + +-- INSERT INTO usermem (sn, grp, member, created, createdby, updated, updatedby) VALUES (593684712, 553229108, 923153018, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "groupmem" +-- + +CREATE TABLE groupmem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE CHECK (member != grp), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groupmem TO nobody; + +CREATE VIEW groupmem_list AS + SELECT + groupmem.sn AS sn, + groups.id || ' (' || groups.dsc || ')' AS grp, + members.id || ' (' || members.dsc || ')' AS member, + to_char(groupmem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groupmem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groupmem + LEFT JOIN groups ON groupmem.grp = groups.sn + LEFT JOIN groups AS members ON groupmem.member = members.sn + LEFT JOIN users AS createdby ON groupmem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groupmem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON groupmem_list TO nobody; + +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (569742102, 329685674, 157696540, now(), 923153018, now(), 923153018); +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (859385977, 329685674, 390105230, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "scptpriv" +-- + +CREATE TABLE scptpriv ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + script varchar(64) NOT NULL CHECK (script != ''), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (script, grp) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON scptpriv TO nobody; + +CREATE VIEW scptpriv_list AS + SELECT + scptpriv.sn AS sn, + scptpriv.script AS script, + groups.dsc AS grp, + to_char(scptpriv.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(scptpriv.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM scptpriv + LEFT JOIN groups ON scptpriv.grp = groups.sn + LEFT JOIN users AS createdby ON scptpriv.createdby = createdby.sn + LEFT JOIN users AS updatedby ON scptpriv.updatedby = updatedby.sn + ORDER BY script, grp; +GRANT SELECT ON scptpriv_list TO nobody; + + +-- +-- Table structure for table "userpref" +-- + +CREATE TABLE userpref ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + usr int REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + domain varchar(64) CHECK (domain IS NULL OR domain != ''), + name varchar(16) NOT NULL CHECK (name != ''), + value varchar(255) NOT NULL, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (usr, domain, name) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON userpref TO nobody; + +CREATE VIEW userpref_list AS + SELECT + userpref.sn AS sn, + CASE WHEN userpref.usr IS NOT NULL THEN users.name + ELSE '所有人' + END AS usr, + CASE WHEN userpref.domain IS NOT NULL THEN userpref.domain + ELSE '所有地方' + END AS domain, + userpref.name AS name, + userpref.value AS value, + to_char(userpref.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(userpref.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM userpref LEFT JOIN users ON userpref.usr = users.sn + LEFT JOIN users AS createdby ON userpref.createdby = createdby.sn + LEFT JOIN users AS updatedby ON userpref.updatedby = updatedby.sn + ORDER BY domain, usr, name; +GRANT SELECT ON userpref_list TO nobody; + + +-- +-- Function definitions for table "guestbook" +-- + +-- integer guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) +CREATE FUNCTION guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) RETURNS integer AS ' + DECLARE + row record; + len integer; + BEGIN + -- : 19, sn: 30 + 1, date: 54 + 1 + len := 105; + len := len + octet_length(host(ip)) + 22; + IF hostname IS NOT NULL THEN + len := len + octet_length(hostname) + 24; + END IF; + IF name IS NOT NULL THEN + len := len + octet_length(eschtml(name)) + 24; + END IF; + IF identity IS NOT NULL THEN + len := len + octet_length(eschtml(identity)) + 28; + END IF; + IF location IS NOT NULL THEN + len := len + octet_length(eschtml(location)) + 28; + END IF; + IF email IS NOT NULL THEN + len := len + octet_length(eschtml(email)) + 25; + END IF; + IF url IS NOT NULL THEN + len := len + octet_length(eschtml(url)) + 23; + END IF; + IF message IS NOT NULL THEN + len := len + octet_length(eschtml(message)) + 27; + END IF; + IF updated != date THEN + len := len + 58; + IF updatedby_arg = 923153018 THEN + len := len + 35; + ELSIF updatedby_arg = 460376330 THEN + len := len + 34; + ELSE + SELECT INTO row name FROM users WHERE sn=updatedby_arg; + len := len + octet_length(row.name) + 29; + END IF; + END IF; + RETURN len; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) TO nobody; +-- integer guestbook_oldlen(sn_arg integer) +CREATE FUNCTION guestbook_oldlen(sn_arg integer) RETURNS integer AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM guestbook WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN guestbook_oldlen(row.created, row.ip, row.host, row.name, row.identity, row.location, row.email, row.url, row.message, row.updated, row.updatedby); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(sn_arg integer) TO nobody; + + +-- +-- Table structure for table "guestbook" +-- + +CREATE TABLE guestbook ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + name varchar(32) CHECK (name IS NULL OR name != ''), + identity varchar(64) CHECK (identity IS NULL OR identity != ''), + location varchar(64) CHECK (location IS NULL OR location != ''), + email varchar(64) CHECK (email IS NULL OR email != ''), + url varchar(128) CHECK (url IS NULL OR (url != '' AND url != 'http://')), + message text NOT NULL CHECK (message != ''), + hid boolean NOT NULL DEFAULT FALSE, + ip inet NOT NULL, + host varchar(255) CHECK (host IS NULL OR host != ''), + ct char(2) NOT NULL REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + pageno int NOT NULL, + oldpageno int, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON guestbook TO nobody; + +CREATE VIEW guestbook_list AS + SELECT + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS _viewurl, + guestbook.sn AS sn, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + COALESCE(guestbook.name, '(未設定)') AS name, + COALESCE(guestbook.identity, '(未設定)') AS identity, + COALESCE(guestbook.location, '(未設定)') AS location, + COALESCE(guestbook.email, '(未設定)') AS email, + COALESCE(guestbook.url, '(未設定)') AS url, + guestbook.message AS message, + CASE WHEN guestbook.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + host(guestbook.ip) AS ip, + COALESCE(guestbook.host, '(不可考)') AS host, + COALESCE(country.name_zhtw, country.name_en) AS ct, + guestbook.pageno AS pageno, + guestbook.oldpageno AS oldpageno, + to_char(guestbook.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(guestbook.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM guestbook + LEFT JOIN country ON guestbook.ct = country.id + LEFT JOIN users AS createdby ON guestbook.createdby = createdby.sn + LEFT JOIN users AS updatedby ON guestbook.updatedby = updatedby.sn + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_list TO nobody; + +CREATE VIEW guestbook_public AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + name AS name, + identity AS identity, + location AS location, + email AS email, + url AS url, + message AS message, + pageno AS pageno, + oldpageno AS oldpageno + FROM guestbook + WHERE NOT hid + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_public TO nobody; + + +-- +-- Table structure for table "pages" +-- + +CREATE TABLE pages ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + path varchar(64) NOT NULL UNIQUE CHECK (path != ''), + ord smallint NOT NULL DEFAULT 5000 CHECK (ord >= 0 AND ord < 10000), + title varchar(128) NOT NULL CHECK (title != ''), + body text NOT NULL CHECK (body != ''), + kw varchar(128) NOT NULL CHECK (kw != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pages TO nobody; + +CREATE VIEW pages_list AS + SELECT + pages.path AS _viewurl, + pages.sn AS sn, + pages.path AS path, + pages.ord AS ord, + pages.title AS title, + pages.body AS body, + pages.kw AS kw, + CASE WHEN pages.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN pages.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(pages.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pages.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pages + LEFT JOIN users AS createdby ON pages.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pages.updatedby = updatedby.sn + ORDER BY path; +GRANT SELECT ON pages_list TO nobody; + + +-- +-- Function definitions for table "links" +-- + +-- boolean linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer); +CREATE FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) RETURNS boolean AS ' + BEGIN + IF parent_arg IS NULL THEN + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent IS NULL; + RETURN NOT FOUND; + ELSE + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent=parent_arg; + RETURN NOT FOUND; + END IF; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) TO nobody; + +-- numeric linkcat_fullord(parent_arg integer, ord_arg integer); +CREATE FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) RETURNS numeric AS ' + DECLARE + row record; + sn_loop integer; + ord_loop numeric; + BEGIN + sn_loop := parent_arg; + ord_loop := ord_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, ord FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN NULL; + END IF; + sn_loop := row.parent; + ord_loop := row.ord + ord_loop / 100; + END LOOP; + RETURN ord_loop; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) TO nobody; +-- numeric linkcat_fullord(sn_arg integer); +CREATE FUNCTION linkcat_fullord(sn_arg integer) RETURNS numeric AS ' + BEGIN + RETURN linkcat_fullord(sn_arg, 0); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(sn_arg integer) TO nobody; + +-- boolean linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + -- Check if we have childs + PERFORM links.sn FROM links + INNER JOIN linkcatz ON linkcatz.link=links.sn + WHERE NOT links.hid AND linkcatz.cat=sn_arg; + IF FOUND THEN + RETURN TRUE; + END IF; + -- Check if we have shown child categories + PERFORM sn FROM linkcat WHERE parent=sn_arg AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + RETURN TRUE; + END IF; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; +-- boolean linkcat_isshown(sn_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer) RETURNS boolean AS ' + DECLARE + row record; + BEGIN + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_isshown(sn_arg, row.hid, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer) TO nobody; +-- boolean linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + RETURN TRUE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; + +-- text linkcat_path(sn_arg integer, id_arg text, parent_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + path text; + BEGIN + PERFORM sn FROM linkcat + WHERE parent=sn_arg + AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + path := ''/'' || id_arg || ''/''; + ELSE + path := ''/'' || id_arg || ''.html''; + END IF; + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_loop; + path := ''/'' || row.id || path; + sn_loop := row.parent; + END LOOP; + RETURN path; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) TO nobody; +-- text linkcat_path(sn_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_path(sn_arg, row.id, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer) TO nobody; + +-- boolean linkcat_ischild(parent_arg integer, child_arg integer); +CREATE FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + sn_loop := child_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN FALSE; + END IF; + IF row.parent = parent_arg THEN + RETURN TRUE; + END IF; + sn_loop := row.parent; + END LOOP; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) TO nobody; + +-- text linkcat_fulltitle(sn_arg integer); +CREATE FUNCTION linkcat_fulltitle(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + title_full text; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + title_full := row.title; + WHILE row.parent IS NOT NULL LOOP + sn_loop := row.parent; + SELECT INTO row * FROM linkcat WHERE sn=sn_loop; + title_full := row.title || '' / '' || title_full; + END LOOP; + RETURN title_full; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(sn_arg integer) TO nobody; +-- text linkcat_fulltitle(parent_arg integer, title_arg text); +CREATE FUNCTION linkcat_fulltitle(parent_arg integer, title_arg text) RETURNS text AS ' + BEGIN + IF parent_arg IS NULL THEN + RETURN title_arg; + END IF; + RETURN linkcat_fulltitle(parent_arg) || '' / '' || title_arg; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(parent_arg integer, title_arg text) TO nobody; + + +-- +-- Table structure for table "linkcat" +-- + +CREATE TABLE linkcat ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + parent int REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE CHECK (parent IS NULL OR (parent != sn AND NOT linkcat_ischild(sn, parent))), + id varchar(8) NOT NULL CHECK (char_length(id) >= 2 AND linkcat_id_unique(id, sn, parent)), + ord smallint NOT NULL DEFAULT 50 CHECK (ord >= 0 AND ord < 100), + title varchar(128) NOT NULL CHECK (title != ''), + kw varchar(128) NOT NULL CHECK (kw != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcat TO nobody; + +CREATE VIEW linkcat_list AS + SELECT + '/links' || linkcat_path(linkcat.sn, linkcat.id, linkcat.parent) AS _viewurl, + linkcat.sn AS sn, + linkcat.id AS id, + linkcat.ord AS ord, + linkcat_fulltitle(linkcat.parent, linkcat.title) AS title, + linkcat.kw AS kw, + CASE WHEN linkcat.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(linkcat.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcat.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcat + LEFT JOIN users AS createdby ON linkcat.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcat.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), id; +GRANT SELECT ON linkcat_list TO nobody; + + +-- +-- Table structure for table "links" +-- + +CREATE TABLE links ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + title varchar(96) NOT NULL CHECK (title != ''), + title_2ln varchar(96) CHECK (title_2ln IS NULL OR title_2ln != ''), + url varchar(128) NOT NULL UNIQUE CHECK (url != '' AND url != 'http://'), + email varchar(64) CHECK (email IS NULL OR email != ''), + icon varchar(128) CHECK (icon IS NULL OR (icon != '' AND icon != 'http://')), + addr varchar(128) CHECK (addr IS NULL OR addr != ''), + tel varchar(48) CHECK (tel IS NULL OR tel != ''), + fax varchar(32) CHECK (fax IS NULL OR fax != ''), + dsc varchar(256) NOT NULL CHECK (dsc != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON links TO nobody; + +CREATE VIEW links_list AS + SELECT + links.url AS _viewurl, + links.sn AS sn, + links.title AS title, + links.title_2ln AS title_2ln, + links.url AS url, + links.url AS _urlcheck, + links.icon AS _imgsrc, + links.email AS email, + links.addr AS addr, + links.tel AS tel, + links.fax AS fax, + links.dsc AS dsc, + CASE WHEN links.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(links.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(links.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM links + LEFT JOIN users AS createdby ON links.createdby = createdby.sn + LEFT JOIN users AS updatedby ON links.updatedby = updatedby.sn + ORDER BY links.title; +GRANT SELECT ON links_list TO nobody; + + +-- +-- Table structure for table "linkcatz" +-- + +CREATE TABLE linkcatz ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + cat int NOT NULL REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE, + link int NOT NULL REFERENCES links ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (cat, link) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcatz TO nobody; + +CREATE VIEW linkcatz_list AS + SELECT + linkcatz.sn AS sn, + linkcat_fulltitle(linkcat.parent, linkcat.title) AS cat, + links.title AS link, + to_char(linkcatz.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcatz.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcatz + LEFT JOIN linkcat ON linkcatz.cat = linkcat.sn + LEFT JOIN links ON linkcatz.link = links.sn + LEFT JOIN users AS createdby ON linkcatz.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcatz.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), linkcat.id, link; +GRANT SELECT ON linkcatz_list TO nobody; + + +-- +-- VIEW: Search +-- +CREATE VIEW search_list AS + (SELECT + 'pages' AS section, + pages.path AS path, + pages.title AS title, + null AS author, + to_char(pages.updated, 'YYYY-MM-DD') AS date, + pages.body AS body, + pages.kw AS kw, + pages.html AS html + FROM pages + WHERE NOT pages.hid + AND pages.path NOT LIKE '/errors/%') + UNION + (SELECT + 'links' AS section, + links.url AS path, + links.title AS title, + null AS author, + to_char(links.updated, 'YYYY-MM-DD') AS date, + links.dsc AS body, + CASE WHEN links.title_2ln IS NULL THEN '' ELSE links.title_2ln END + || ' +' || CASE WHEN links.url IS NULL THEN '' ELSE links.url END + || ' +' || CASE WHEN links.email IS NULL THEN '' ELSE links.email END + || ' +' || CASE WHEN links.addr IS NULL THEN '' ELSE links.addr END + || ' +' || CASE WHEN links.tel IS NULL THEN '' ELSE links.tel END + || ' +' || CASE WHEN links.fax IS NULL THEN '' ELSE links.fax END + AS kw, + FALSE AS html + FROM links + WHERE NOT links.hid) + UNION + (SELECT + 'guestbook' AS section, + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS path, + null AS title, + guestbook.name AS author, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + guestbook.message AS body, + CASE WHEN guestbook.identity IS NULL THEN '' ELSE guestbook.identity END + || ' +' || CASE WHEN guestbook.location IS NULL THEN '' ELSE guestbook.location END + || ' +' || CASE WHEN guestbook.email IS NULL THEN '' ELSE guestbook.email END + || ' +' || CASE WHEN guestbook.url IS NULL THEN '' ELSE guestbook.url END + AS kw, + FALSE AS html + FROM guestbook + WHERE NOT guestbook.hid) + ORDER BY date DESC, title; +GRANT SELECT ON search_list TO nobody; + + +-- +-- Table structure for table "funds" +-- + +CREATE TABLE funds ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + cat0 varchar(16) NOT NULL CHECK (cat0 != ''), + cat1 varchar(16) CHECK (cat1 IS NULL OR cat1 != ''), + cat2 varchar(16) CHECK (cat2 IS NULL OR cat2 != ''), + cat3 varchar(16) CHECK (cat3 IS NULL OR cat3 != ''), + title varchar(32) NOT NULL CHECK (title != ''), + m1ret numeric(5, 2), + m1rank numeric(4, 4) CHECK ((m1ret IS NULL AND m1rank IS NULL) OR (m1ret IS NOT NULL AND m1rank IS NOT NULL AND m1rank > 0 AND m1rank < 1)), + m1rnkdsc varchar(16) CHECK ((m1ret IS NULL AND m1rnkdsc IS NULL) OR (m1ret IS NOT NULL AND m1rnkdsc IS NOT NULL AND m1rnkdsc != '')), + m3ret numeric(5, 2), + m3rank numeric(4, 4) CHECK ((m3ret IS NULL AND m3rank IS NULL) OR (m3ret IS NOT NULL AND m3rank IS NOT NULL AND m3rank > 0 AND m3rank < 1)), + m3rnkdsc varchar(16) CHECK ((m3ret IS NULL AND m3rnkdsc IS NULL) OR (m3ret IS NOT NULL AND m3rnkdsc IS NOT NULL AND m3rnkdsc != '')), + m6ret numeric(5, 2), + m6rank numeric(4, 4) CHECK ((m6ret IS NULL AND m6rank IS NULL) OR (m6ret IS NOT NULL AND m6rank IS NOT NULL AND m6rank > 0 AND m6rank < 1)), + m6rnkdsc varchar(16) CHECK ((m6ret IS NULL AND m6rnkdsc IS NULL) OR (m6ret IS NOT NULL AND m6rnkdsc IS NOT NULL AND m6rnkdsc != '')), + y1ret numeric(5, 2), + y1rank numeric(4, 4) CHECK ((y1ret IS NULL AND y1rank IS NULL) OR (y1ret IS NOT NULL AND y1rank IS NOT NULL AND y1rank > 0 AND y1rank < 1)), + y1rnkdsc varchar(16) CHECK ((y1ret IS NULL AND y1rnkdsc IS NULL) OR (y1ret IS NOT NULL AND y1rnkdsc IS NOT NULL AND y1rnkdsc != '')), + y2ret numeric(5, 2), + y2rank numeric(4, 4) CHECK ((y2ret IS NULL AND y2rank IS NULL) OR (y2ret IS NOT NULL AND y2rank IS NOT NULL AND y2rank > 0 AND y2rank < 1)), + y2rnkdsc varchar(16) CHECK ((y2ret IS NULL AND y2rnkdsc IS NULL) OR (y2ret IS NOT NULL AND y2rnkdsc IS NOT NULL AND y2rnkdsc != '')), + y3ret numeric(5, 2), + y3rank numeric(4, 4) CHECK ((y3ret IS NULL AND y3rank IS NULL) OR (y3ret IS NOT NULL AND y3rank IS NOT NULL AND y3rank > 0 AND y3rank < 1)), + y3rnkdsc varchar(16) CHECK ((y3ret IS NULL AND y3rnkdsc IS NULL) OR (y3ret IS NOT NULL AND y3rnkdsc IS NOT NULL AND y3rnkdsc != '')), + y5ret numeric(5, 2), + y5rank numeric(4, 4) CHECK ((y5ret IS NULL AND y5rank IS NULL) OR (y5ret IS NOT NULL AND y5rank IS NOT NULL AND y5rank > 0 AND y5rank < 1)), + y5rnkdsc varchar(16) CHECK ((y5ret IS NULL AND y5rnkdsc IS NULL) OR (y5ret IS NOT NULL AND y5rnkdsc IS NOT NULL AND y5rnkdsc != '')), + y10ret numeric(5, 2), + y10rank numeric(4, 4) CHECK ((y10ret IS NULL AND y10rank IS NULL) OR (y10ret IS NOT NULL AND y10rank IS NOT NULL AND y10rank > 0 AND y10rank < 1)), + y10rnkdsc varchar(16) CHECK ((y10ret IS NULL AND y10rnkdsc IS NULL) OR (y10ret IS NOT NULL AND y10rnkdsc IS NOT NULL AND y10rnkdsc != '')), + ytret numeric(5, 2), + ytrank numeric(4, 4) CHECK ((ytret IS NULL AND ytrank IS NULL) OR (ytret IS NOT NULL AND ytrank IS NOT NULL AND ytrank > 0 AND ytrank < 1)), + ytrnkdsc varchar(16) CHECK ((ytret IS NULL AND ytrnkdsc IS NULL) OR (ytret IS NOT NULL AND ytrnkdsc IS NOT NULL AND ytrnkdsc != '')), + beginret numeric(6, 2), + begindate date NOT NULL, + bestm3 numeric(5, 2), + worstm3 numeric(5, 2), + sd12 numeric(4, 2), + sd24 numeric(4, 2), + beta12 numeric(8, 4), + beta24 numeric(8, 4), + sharpe12 numeric(8, 4), + sharpe24 numeric(8, 4), + jensen12 numeric(8, 4), + jensen24 numeric(8, 4), + treynor12 numeric(11, 4), + treynor24 numeric(8, 4), + infrma12 numeric(8, 4), + infrma24 numeric(8, 4), + infrmi12 numeric(8, 4), + infrmi24 numeric(8, 4), + turnmt numeric(5, 2), + turny1 numeric(6, 2), + duration numeric(3, 2), + rating varchar(64), + newman boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON funds TO nobody; +ALTER TABLE funds OWNER TO robot; + +CREATE VIEW funds_list AS + SELECT + funds.sn AS sn, + cat0 || CASE WHEN cat1 IS NULL THEN '' + ELSE ' / ' || cat1 || CASE WHEN cat2 IS NULL THEN '' + ELSE ' / ' || cat2 || CASE WHEN cat3 IS NULL THEN '' + ELSE ' / ' || cat3 END + END + END AS cat, + funds.title AS title, + funds.m1ret AS m1ret, + funds.m1rank AS _m1rank, + funds.m1rnkdsc AS m1rank, + funds.m3ret AS m3ret, + funds.m3rank AS _m3rank, + funds.m3rnkdsc AS m3rank, + funds.m6ret AS m6ret, + funds.m6rank AS _m6rank, + funds.m6rnkdsc AS m6rank, + funds.y1ret AS y1ret, + funds.y1rank AS _y1rank, + funds.y1rnkdsc AS y1rank, + funds.y2ret AS y2ret, + funds.y2rank AS _y2rank, + funds.y2rnkdsc AS y2rank, + funds.y3ret AS y3ret, + funds.y3rank AS _y3rank, + funds.y3rnkdsc AS y3rank, + funds.y5ret AS y5ret, + funds.y5rank AS _y5rank, + funds.y5rnkdsc AS y5rank, + funds.y10ret AS y10ret, + funds.y10rank AS _y10rank, + funds.y10rnkdsc AS y10rank, + funds.ytret AS ytret, + funds.ytrank AS _ytrank, + funds.ytrnkdsc AS ytrank, + funds.beginret AS beginret, + funds.begindate AS begindate, + funds.bestm3 AS bestm3, + funds.worstm3 AS worstm3, + funds.sd12 AS sd12, + funds.sd24 AS sd24, + funds.beta12 AS beta12, + funds.beta24 AS beta24, + funds.sharpe12 AS sharpe12, + funds.sharpe24 AS sharpe24, + funds.jensen12 AS jensen12, + funds.jensen24 AS jensen24, + funds.treynor12 AS treynor12, + funds.treynor24 AS treynor24, + funds.infrma12 AS infrma12, + funds.infrma24 AS infrma24, + funds.infrmi12 AS infrmi12, + funds.infrmi24 AS infrmi24, + funds.turnmt AS turnmt, + funds.turny1 AS turny1, + funds.duration AS duration, + funds.rating AS rating, + CASE WHEN funds.newman THEN '未滿一年' + ELSE '' + END AS newman, + to_char(funds.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(funds.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM funds + LEFT JOIN users AS createdby ON funds.createdby = createdby.sn + LEFT JOIN users AS updatedby ON funds.updatedby = updatedby.sn + ORDER BY CASE WHEN funds.y5ret IS NULL THEN 0 ELSE funds.y5ret END DESC; +GRANT SELECT ON funds_list TO nobody; + + +COMMIT; + diff --git a/htdocs/emily/magicat/lib/emily.sql b/htdocs/emily/magicat/lib/emily.sql new file mode 100644 index 0000000..55d7267 --- /dev/null +++ b/htdocs/emily/magicat/lib/emily.sql @@ -0,0 +1,943 @@ +-- 檔案名稱: emily.sql +-- 程式說明: 吳芳美網站資料庫定義檔 +-- 程式作者: 依瑪貓 imacat +-- 初稿日期: 2004-10-16 +-- 版權字樣: 版權所有 (c) 2004-2020 依瑪貓 + +SET NAMES 'utf8'; + +START TRANSACTION; + + +-- +-- Table structure for table "mtime" +-- + +CREATE TABLE mtime ( + tabname varchar(16) NOT NULL PRIMARY KEY, + mtime timestamp NOT NULL DEFAULT now() +); +GRANT SELECT, INSERT, UPDATE, DELETE ON mtime TO nobody; + + +-- +-- Function definition for function "eschtml" +-- +-- integer eschtml(source text) +CREATE FUNCTION eschtml(source text) RETURNS text AS ' + DECLARE + result text; + BEGIN + result := source; + result := replace(result, ''&'', ''&''); + result := replace(result, ''<'', ''<''); + result := replace(result, ''>'', ''>''); + result := replace(result, ''"'', ''"''); + return result; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION eschtml(source text) TO nobody; + + +-- +-- Table structure for table "country" +-- + +CREATE TABLE country ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id char(2) NOT NULL UNIQUE CHECK (position(' ' in id) = 0), + name_en varchar(64) NOT NULL CHECK (name_en != ''), + name_zhtw varchar(32) CHECK (name_zhtw IS NULL OR name_zhtw != ''), + special boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL +); +GRANT SELECT, INSERT, UPDATE, DELETE ON country TO nobody; + + +-- +-- Table structure for table "users" +-- + +CREATE TABLE users ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(32) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + passwd char(32) NOT NULL, + name varchar(32) NOT NULL CHECK (name != ''), + disabled boolean NOT NULL DEFAULT FALSE, + deleted boolean NOT NULL DEFAULT FALSE, + lang varchar(5) CHECK (lang IS NULL OR lang != ''), + visits smallint NOT NULL DEFAULT 0 CHECK (visits >= 0), + visited timestamp, + ip inet, + host varchar(128), + ct char(2) REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON users TO nobody; + +CREATE VIEW users_list AS + SELECT + users.sn AS sn, + users.id AS id, + users.name AS name, + CASE WHEN users.disabled THEN '停用' + ELSE '' + END AS disabled, + CASE WHEN users.deleted THEN '已刪' + ELSE '' + END AS deleted, + CASE WHEN users.lang IS NULL THEN '(無)' + ELSE CASE users.lang + WHEN 'en' THEN '英文' + WHEN 'zh-tw' THEN '繁體中文' + WHEN 'zh-cn' THEN '簡體中文' + WHEN 'ja' THEN '日文' + WHEN 'de' THEN '德文' + WHEN 'es' THEN '西班牙文' + ELSE users.lang + END + END AS lang, + users.visits AS visits, + CASE WHEN users.visited IS NULL THEN '(無)' + ELSE to_char(users.visited, 'YYYY-MM-DD HH:MI:SS') + END AS visited, + CASE WHEN users.ip IS NULL THEN '(無)' + ELSE host(users.ip) + END AS ip, + CASE WHEN users.host IS NULL THEN '(無)' + ELSE users.host + END AS host, + CASE WHEN users.ct IS NULL THEN '(無)' + ELSE ct.name_zhtw + END AS ct, + to_char(users.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(users.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM users + LEFT JOIN country AS ct ON users.ct = ct.id + LEFT JOIN users AS createdby ON users.createdby = createdby.sn + LEFT JOIN users AS updatedby ON users.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON users_list TO nobody; + +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (923153018, 'imacat', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '依瑪貓', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (460376330, 'mandy', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '小招', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (723676436, 'guestbook', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '留言本', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); + +-- +-- Fixing the country table +-- + +ALTER TABLE country ADD FOREIGN KEY (createdby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +ALTER TABLE country ADD FOREIGN KEY (updatedby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +CREATE VIEW country_list AS + SELECT + country.sn AS sn, + country.id AS id, + COALESCE(country.name_zhtw, country.name_en) AS title, + CASE WHEN country.special THEN '特殊' + ELSE '' + END AS special, + to_char(country.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(country.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM country + LEFT JOIN users AS createdby ON country.createdby = createdby.sn + LEFT JOIN users AS updatedby ON country.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON country_list TO nobody; + + +-- +-- Table structure for table "groups" +-- + +CREATE TABLE groups ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(16) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + dsc varchar(64) NOT NULL CHECK (dsc != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groups TO nobody; + +CREATE VIEW groups_list AS + SELECT + groups.sn AS sn, + groups.id AS id, + groups.dsc AS dsc, + to_char(groups.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groups.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groups + LEFT JOIN users AS createdby ON groups.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groups.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON groups_list TO nobody; + +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (553229108, 'root', '總管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (802339805, 'guests', '暱名訪客', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (958210993, 'users', '已登入使用者', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (329685674, 'admin', '所有網站管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (157696540, 'acctman', '帳號管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (390105230, 'editor', '網站編輯', now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "usermem" +-- + +CREATE TABLE usermem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON usermem TO nobody; + +CREATE VIEW usermem_list AS + SELECT + usermem.sn AS sn, + groups.id || ' (' || groups.dsc || ')' AS grp, + members.id || ' (' || members.name || ')' AS member, + to_char(usermem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(usermem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM usermem + LEFT JOIN groups ON usermem.grp = groups.sn + LEFT JOIN users AS members ON usermem.member = members.sn + LEFT JOIN users AS createdby ON usermem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON usermem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON usermem_list TO nobody; + +-- INSERT INTO usermem (sn, grp, member, created, createdby, updated, updatedby) VALUES (593684712, 553229108, 923153018, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "groupmem" +-- + +CREATE TABLE groupmem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE CHECK (member != grp), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groupmem TO nobody; + +CREATE VIEW groupmem_list AS + SELECT + groupmem.sn AS sn, + groups.id || ' (' || groups.dsc || ')' AS grp, + members.id || ' (' || members.dsc || ')' AS member, + to_char(groupmem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groupmem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groupmem + LEFT JOIN groups ON groupmem.grp = groups.sn + LEFT JOIN groups AS members ON groupmem.member = members.sn + LEFT JOIN users AS createdby ON groupmem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groupmem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON groupmem_list TO nobody; + +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (569742102, 329685674, 157696540, now(), 923153018, now(), 923153018); +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (859385977, 329685674, 390105230, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "scptpriv" +-- + +CREATE TABLE scptpriv ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + script varchar(64) NOT NULL CHECK (script != ''), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (script, grp) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON scptpriv TO nobody; + +CREATE VIEW scptpriv_list AS + SELECT + scptpriv.sn AS sn, + scptpriv.script AS script, + groups.dsc AS grp, + to_char(scptpriv.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(scptpriv.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM scptpriv + LEFT JOIN groups ON scptpriv.grp = groups.sn + LEFT JOIN users AS createdby ON scptpriv.createdby = createdby.sn + LEFT JOIN users AS updatedby ON scptpriv.updatedby = updatedby.sn + ORDER BY script, grp; +GRANT SELECT ON scptpriv_list TO nobody; + + +-- +-- Table structure for table "userpref" +-- + +CREATE TABLE userpref ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + usr int REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + domain varchar(64) CHECK (domain IS NULL OR domain != ''), + name varchar(16) NOT NULL CHECK (name != ''), + value varchar(255) NOT NULL, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (usr, domain, name) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON userpref TO nobody; + +CREATE VIEW userpref_list AS + SELECT + userpref.sn AS sn, + CASE WHEN userpref.usr IS NOT NULL THEN users.name + ELSE '所有人' + END AS usr, + CASE WHEN userpref.domain IS NOT NULL THEN userpref.domain + ELSE '所有地方' + END AS domain, + userpref.name AS name, + userpref.value AS value, + to_char(userpref.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(userpref.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM userpref LEFT JOIN users ON userpref.usr = users.sn + LEFT JOIN users AS createdby ON userpref.createdby = createdby.sn + LEFT JOIN users AS updatedby ON userpref.updatedby = updatedby.sn + ORDER BY domain, usr, name; +GRANT SELECT ON userpref_list TO nobody; + + +-- +-- Function definitions for table "guestbook" +-- + +-- integer guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) +CREATE FUNCTION guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) RETURNS integer AS ' + DECLARE + row record; + len integer; + BEGIN + -- : 19, sn: 30 + 1, date: 54 + 1 + len := 105; + len := len + octet_length(host(ip)) + 22; + IF hostname IS NOT NULL THEN + len := len + octet_length(hostname) + 24; + END IF; + IF name IS NOT NULL THEN + len := len + octet_length(eschtml(name)) + 24; + END IF; + IF identity IS NOT NULL THEN + len := len + octet_length(eschtml(identity)) + 28; + END IF; + IF location IS NOT NULL THEN + len := len + octet_length(eschtml(location)) + 28; + END IF; + IF email IS NOT NULL THEN + len := len + octet_length(eschtml(email)) + 25; + END IF; + IF url IS NOT NULL THEN + len := len + octet_length(eschtml(url)) + 23; + END IF; + IF message IS NOT NULL THEN + len := len + octet_length(eschtml(message)) + 27; + END IF; + IF updated != date THEN + len := len + 58; + IF updatedby_arg = 923153018 THEN + len := len + 35; + ELSIF updatedby_arg = 460376330 THEN + len := len + 34; + ELSE + SELECT INTO row name FROM users WHERE sn=updatedby_arg; + len := len + octet_length(row.name) + 29; + END IF; + END IF; + RETURN len; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) TO nobody; +-- integer guestbook_oldlen(sn_arg integer) +CREATE FUNCTION guestbook_oldlen(sn_arg integer) RETURNS integer AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM guestbook WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN guestbook_oldlen(row.created, row.ip, row.host, row.name, row.identity, row.location, row.email, row.url, row.message, row.updated, row.updatedby); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(sn_arg integer) TO nobody; + + +-- +-- Table structure for table "guestbook" +-- + +CREATE TABLE guestbook ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + name varchar(32) CHECK (name IS NULL OR name != ''), + identity varchar(64) CHECK (identity IS NULL OR identity != ''), + location varchar(64) CHECK (location IS NULL OR location != ''), + email varchar(64) CHECK (email IS NULL OR email != ''), + url varchar(128) CHECK (url IS NULL OR (url != '' AND url != 'http://')), + message text NOT NULL CHECK (message != ''), + hid boolean NOT NULL DEFAULT FALSE, + ip inet NOT NULL, + host varchar(255) CHECK (host IS NULL OR host != ''), + ct char(2) NOT NULL REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + pageno int NOT NULL, + oldpageno int, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON guestbook TO nobody; + +CREATE VIEW guestbook_list AS + SELECT + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS _viewurl, + guestbook.sn AS sn, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + COALESCE(guestbook.name, '(未設定)') AS name, + COALESCE(guestbook.identity, '(未設定)') AS identity, + COALESCE(guestbook.location, '(未設定)') AS location, + COALESCE(guestbook.email, '(未設定)') AS email, + COALESCE(guestbook.url, '(未設定)') AS url, + guestbook.message AS message, + CASE WHEN guestbook.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + host(guestbook.ip) AS ip, + COALESCE(guestbook.host, '(不可考)') AS host, + COALESCE(country.name_zhtw, country.name_en) AS ct, + guestbook.pageno AS pageno, + guestbook.oldpageno AS oldpageno, + to_char(guestbook.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(guestbook.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM guestbook + LEFT JOIN country ON guestbook.ct = country.id + LEFT JOIN users AS createdby ON guestbook.createdby = createdby.sn + LEFT JOIN users AS updatedby ON guestbook.updatedby = updatedby.sn + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_list TO nobody; + +CREATE VIEW guestbook_public AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + name AS name, + identity AS identity, + location AS location, + email AS email, + url AS url, + message AS message, + pageno AS pageno, + oldpageno AS oldpageno + FROM guestbook + WHERE NOT hid + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_public TO nobody; + + +-- +-- Table structure for table "pages" +-- + +CREATE TABLE pages ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + path varchar(64) NOT NULL UNIQUE CHECK (path != ''), + ord smallint NOT NULL DEFAULT 5000 CHECK (ord >= 0 AND ord < 10000), + title varchar(128) NOT NULL CHECK (title != ''), + body text NOT NULL CHECK (body != ''), + kw varchar(128) NOT NULL CHECK (kw != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pages TO nobody; + +CREATE VIEW pages_list AS + SELECT + pages.path AS _viewurl, + pages.sn AS sn, + pages.path AS path, + pages.ord AS ord, + pages.title AS title, + pages.body AS body, + pages.kw AS kw, + CASE WHEN pages.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN pages.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(pages.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pages.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pages + LEFT JOIN users AS createdby ON pages.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pages.updatedby = updatedby.sn + ORDER BY path; +GRANT SELECT ON pages_list TO nobody; + + +-- +-- Function definitions for table "links" +-- + +-- boolean linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer); +CREATE FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) RETURNS boolean AS ' + BEGIN + IF parent_arg IS NULL THEN + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent IS NULL; + RETURN NOT FOUND; + ELSE + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent=parent_arg; + RETURN NOT FOUND; + END IF; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) TO nobody; + +-- numeric linkcat_fullord(parent_arg integer, ord_arg integer); +CREATE FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) RETURNS numeric AS ' + DECLARE + row record; + sn_loop integer; + ord_loop numeric; + BEGIN + sn_loop := parent_arg; + ord_loop := ord_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, ord FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN NULL; + END IF; + sn_loop := row.parent; + ord_loop := row.ord + ord_loop / 100; + END LOOP; + RETURN ord_loop; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) TO nobody; +-- numeric linkcat_fullord(sn_arg integer); +CREATE FUNCTION linkcat_fullord(sn_arg integer) RETURNS numeric AS ' + BEGIN + RETURN linkcat_fullord(sn_arg, 0); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(sn_arg integer) TO nobody; + +-- boolean linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + -- Check if we have childs + PERFORM links.sn FROM links + INNER JOIN linkcatz ON linkcatz.link=links.sn + WHERE NOT links.hid AND linkcatz.cat=sn_arg; + IF FOUND THEN + RETURN TRUE; + END IF; + -- Check if we have shown child categories + PERFORM sn FROM linkcat WHERE parent=sn_arg AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + RETURN TRUE; + END IF; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; +-- boolean linkcat_isshown(sn_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer) RETURNS boolean AS ' + DECLARE + row record; + BEGIN + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_isshown(sn_arg, row.hid, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer) TO nobody; +-- boolean linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + RETURN TRUE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; + +-- text linkcat_path(sn_arg integer, id_arg text, parent_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + path text; + BEGIN + PERFORM sn FROM linkcat + WHERE parent=sn_arg + AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + path := ''/'' || id_arg || ''/''; + ELSE + path := ''/'' || id_arg || ''.html''; + END IF; + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_loop; + path := ''/'' || row.id || path; + sn_loop := row.parent; + END LOOP; + RETURN path; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) TO nobody; +-- text linkcat_path(sn_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_path(sn_arg, row.id, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer) TO nobody; + +-- boolean linkcat_ischild(parent_arg integer, child_arg integer); +CREATE FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + sn_loop := child_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN FALSE; + END IF; + IF row.parent = parent_arg THEN + RETURN TRUE; + END IF; + sn_loop := row.parent; + END LOOP; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) TO nobody; + +-- text linkcat_fulltitle(sn_arg integer); +CREATE FUNCTION linkcat_fulltitle(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + title_full text; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + title_full := row.title; + WHILE row.parent IS NOT NULL LOOP + sn_loop := row.parent; + SELECT INTO row * FROM linkcat WHERE sn=sn_loop; + title_full := row.title || '' / '' || title_full; + END LOOP; + RETURN title_full; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(sn_arg integer) TO nobody; +-- text linkcat_fulltitle(parent_arg integer, title_arg text); +CREATE FUNCTION linkcat_fulltitle(parent_arg integer, title_arg text) RETURNS text AS ' + BEGIN + IF parent_arg IS NULL THEN + RETURN title_arg; + END IF; + RETURN linkcat_fulltitle(parent_arg) || '' / '' || title_arg; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(parent_arg integer, title_arg text) TO nobody; + + +-- +-- Table structure for table "linkcat" +-- + +CREATE TABLE linkcat ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + parent int REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE CHECK (parent IS NULL OR (parent != sn AND NOT linkcat_ischild(sn, parent))), + id varchar(8) NOT NULL CHECK (char_length(id) >= 2 AND linkcat_id_unique(id, sn, parent)), + ord smallint NOT NULL DEFAULT 50 CHECK (ord >= 0 AND ord < 100), + title varchar(128) NOT NULL CHECK (title != ''), + kw varchar(128) NOT NULL CHECK (kw != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcat TO nobody; + +CREATE VIEW linkcat_list AS + SELECT + '/links' || linkcat_path(linkcat.sn, linkcat.id, linkcat.parent) AS _viewurl, + linkcat.sn AS sn, + linkcat.id AS id, + linkcat.ord AS ord, + linkcat_fulltitle(linkcat.parent, linkcat.title) AS title, + linkcat.kw AS kw, + CASE WHEN linkcat.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(linkcat.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcat.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcat + LEFT JOIN users AS createdby ON linkcat.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcat.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), id; +GRANT SELECT ON linkcat_list TO nobody; + + +-- +-- Table structure for table "links" +-- + +CREATE TABLE links ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + title varchar(96) NOT NULL CHECK (title != ''), + title_2ln varchar(96) CHECK (title_2ln IS NULL OR title_2ln != ''), + url varchar(128) NOT NULL UNIQUE CHECK (url != '' AND url != 'http://'), + email varchar(64) CHECK (email IS NULL OR email != ''), + icon varchar(128) CHECK (icon IS NULL OR (icon != '' AND icon != 'http://')), + addr varchar(128) CHECK (addr IS NULL OR addr != ''), + tel varchar(48) CHECK (tel IS NULL OR tel != ''), + fax varchar(32) CHECK (fax IS NULL OR fax != ''), + dsc varchar(256) NOT NULL CHECK (dsc != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON links TO nobody; + +CREATE VIEW links_list AS + SELECT + links.url AS _viewurl, + links.sn AS sn, + links.title AS title, + links.title_2ln AS title_2ln, + links.url AS url, + links.url AS _urlcheck, + links.icon AS _imgsrc, + links.email AS email, + links.addr AS addr, + links.tel AS tel, + links.fax AS fax, + links.dsc AS dsc, + CASE WHEN links.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(links.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(links.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM links + LEFT JOIN users AS createdby ON links.createdby = createdby.sn + LEFT JOIN users AS updatedby ON links.updatedby = updatedby.sn + ORDER BY links.title; +GRANT SELECT ON links_list TO nobody; + + +-- +-- Table structure for table "linkcatz" +-- + +CREATE TABLE linkcatz ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + cat int NOT NULL REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE, + link int NOT NULL REFERENCES links ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (cat, link) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcatz TO nobody; + +CREATE VIEW linkcatz_list AS + SELECT + linkcatz.sn AS sn, + linkcat_fulltitle(linkcat.parent, linkcat.title) AS cat, + links.title AS link, + to_char(linkcatz.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcatz.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcatz + LEFT JOIN linkcat ON linkcatz.cat = linkcat.sn + LEFT JOIN links ON linkcatz.link = links.sn + LEFT JOIN users AS createdby ON linkcatz.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcatz.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), linkcat.id, link; +GRANT SELECT ON linkcatz_list TO nobody; + + +-- +-- VIEW: Search +-- +CREATE VIEW search_list AS + (SELECT + 'pages' AS section, + pages.path AS path, + pages.title AS title, + null AS author, + to_char(pages.updated, 'YYYY-MM-DD') AS date, + pages.body AS body, + pages.kw AS kw, + pages.html AS html + FROM pages + WHERE NOT pages.hid + AND pages.path NOT LIKE '/errors/%') + UNION + (SELECT + 'links' AS section, + links.url AS path, + links.title AS title, + null AS author, + to_char(links.updated, 'YYYY-MM-DD') AS date, + links.dsc AS body, + CASE WHEN links.title_2ln IS NULL THEN '' ELSE links.title_2ln END + || ' +' || CASE WHEN links.url IS NULL THEN '' ELSE links.url END + || ' +' || CASE WHEN links.email IS NULL THEN '' ELSE links.email END + || ' +' || CASE WHEN links.addr IS NULL THEN '' ELSE links.addr END + || ' +' || CASE WHEN links.tel IS NULL THEN '' ELSE links.tel END + || ' +' || CASE WHEN links.fax IS NULL THEN '' ELSE links.fax END + AS kw, + FALSE AS html + FROM links + WHERE NOT links.hid) + UNION + (SELECT + 'guestbook' AS section, + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS path, + null AS title, + guestbook.name AS author, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + guestbook.message AS body, + CASE WHEN guestbook.identity IS NULL THEN '' ELSE guestbook.identity END + || ' +' || CASE WHEN guestbook.location IS NULL THEN '' ELSE guestbook.location END + || ' +' || CASE WHEN guestbook.email IS NULL THEN '' ELSE guestbook.email END + || ' +' || CASE WHEN guestbook.url IS NULL THEN '' ELSE guestbook.url END + AS kw, + FALSE AS html + FROM guestbook + WHERE NOT guestbook.hid) + ORDER BY date DESC, title; +GRANT SELECT ON search_list TO nobody; + + +COMMIT; + diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily.pm new file mode 100644 index 0000000..a2f2bf8 --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily.pm @@ -0,0 +1,55 @@ +# Emily Wu's Website +# emily.pm: Emily Wu's Website + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-06 + +package Selima::emily; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +@EXPORT = qw(); + +# Import our site-specific subroutines +use Selima::emily::Config; +push @EXPORT, @Selima::emily::Config::EXPORT; +use Selima::emily::HTML; +push @EXPORT, @Selima::emily::HTML::EXPORT; +use Selima::emily::Rebuild; +push @EXPORT, @Selima::emily::Rebuild::EXPORT; + +# Import our site-specific classess +use Selima::emily::Checker::Guestbook; +use Selima::emily::Checker::Guestbook::Public; +use Selima::emily::Form::Guestbook; +use Selima::emily::Form::Guestbook::Public; +use Selima::emily::L10N; +use Selima::emily::List::Guestbook; +use Selima::emily::List::Guestbook::Public; +use Selima::emily::List::Search; +use Selima::emily::List::Funds; +use Selima::emily::Processor::Guestbook::Public; + +# Import our common modules +use Selima; +push @EXPORT, @Selima::EXPORT; + +@EXPORT_OK = @EXPORT; + +return 1; diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily/Checker/Guestbook.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily/Checker/Guestbook.pm new file mode 100644 index 0000000..d7f2e93 --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily/Checker/Guestbook.pm @@ -0,0 +1,48 @@ +# Emily Wu's Website +# Guestbook.pm: The administrative guestbook form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::emily::Checker::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker::Guestbook); + +use Selima::ShortCut; + +# _check_identity: Check the identity +sub _check_identity : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("identity"); + return $error if defined $error; + # Regularize it + $self->_trim("identity"); + # Check the length + return {"msg"=>N_("This occupation is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"identity"}]} + if length $form->param("identity") > ${$self->{"maxlens"}}{"identity"}; + # OK + return; +} + +return 1; diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily/Checker/Guestbook/Public.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily/Checker/Guestbook/Public.pm new file mode 100644 index 0000000..1508cf4 --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily/Checker/Guestbook/Public.pm @@ -0,0 +1,57 @@ +# Emily Wu's Website +# Public.pm: The guestbook form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::emily::Checker::Guestbook::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker::Guestbook::Public); + +use Selima::DataVars qw($DBH); +use Selima::HTTP; +use Selima::Logging; +use Selima::ShortCut; + +# _check_name: Check the name +sub _check_name : method { + # Run the parent checker + return $_[0]->SUPER::_check_name_req; +} + +# _check_identity: Check the identity +sub _check_identity : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("identity"); + return $error if defined $error; + # Regularize it + $self->_trim("identity"); + # Check the length + return {"msg"=>N_("Your occupation is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"identity"}]} + if length $form->param("identity") > ${$self->{"maxlens"}}{"identity"}; + # OK + return; +} + +return 1; diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily/Config.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily/Config.pm new file mode 100644 index 0000000..ee0f402 --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily/Config.pm @@ -0,0 +1,83 @@ +# Emily Wu's Website +# Config.pm: The web site configuration. + +# Copyright (c) 2003-2020 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-06 + +package Selima::emily::Config; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(siteconf page_replacements); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub siteconf(); +sub page_replacements(); +} + +# Get into the public variable space and initialize them +use lib $ENV{"DOCUMENT_ROOT"} . qw(/../../lib/perl5); +use Selima::CopyYear; +use Selima::DataVars qw(:all); +use Selima::ShortCut; + +# siteconf: Subroutine to initialize site configuration +sub siteconf() { + local ($_, %_); + + # The package name and the package title + $PACKAGE = "emily"; + $SITENAME_ABBR = "Emily"; + # The author and the copyright + $AUTHOR = "依瑪貓"; + $COPYRIGHT = "© 依瑪貓。依瑪貓保有所有權利。"; + # Document root, the library and the l10n directories + $DOC_ROOT = $ENV{"DOCUMENT_ROOT"}; + $SITE_LIBDIR = $DOC_ROOT . "/magicat/lib/perl5"; + $LOCALEDIR = $DOC_ROOT . "/magicat/locale"; + + # Tables to lock when rebuilding pages + @REBUILD_TABLES = qw(linkcat links linkcatz); + + # The languages + $DEFAULT_LANG = "zh-tw"; + @ALL_LINGUAS = qw(zh-tw); + + return; +} + +# page_replacements: Dynamic page elements to be replaced, +# but not part of the content. Used by xfupdate_template(). +sub page_replacements() { + return { + "copyyear" => { + "pattern" => "2000(?:-\\d{4})?", + "content" => copyyear(2000), + }, + "generator" => { + "pattern" => "Selima \\d+\\.\\d+", + "content" => "Selima $Selima::VERSION", + }, + }; +} + +no utf8; +return 1; diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily/Form/Guestbook.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily/Form/Guestbook.pm new file mode 100644 index 0000000..59f3865 --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily/Form/Guestbook.pm @@ -0,0 +1,40 @@ +# Emily Wu's Website +# Guestbook.pm: The administrative guestbook form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::emily::Form::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form::Guestbook); + +use Selima::MarkAbbr; +use Selima::ShortCut; + +# _html_col_identity: The identity +sub _html_col_identity : method { + $_[0]->_html_coltmpl_text("identity", h_abbr(__("Occupation:"))); +} + +# _html_col_url: The website URL +sub _html_col_url : method { + $_[0]->_html_coltmpl_url("url", h_abbr(__("Website URL.:"))); +} + +return 1; diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm new file mode 100644 index 0000000..59d5736 --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm @@ -0,0 +1,78 @@ +# Emily Wu's Website +# Public.pm: The guestbook form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::emily::Form::Guestbook::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form::Guestbook::Public); + +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"prefmsg"} = [] if !exists $$args{"prefmsg"}; + push @{$$args{"prefmsg"}}, __("General commercial advertisements are not welcomed. They may be deleted without notice. HTML is not supported."); + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_email: The e-mail +sub _html_col_email : method { + $_[0]->_html_coltmpl_text("email", h_abbr(__("E-mail"))); +} + +# _html_col_identity: The identity +sub _html_col_identity : method { + $_[0]->_html_coltmpl_text("identity", h_abbr(__("Occupation"))); +} + +# _html_col_location: The location +sub _html_col_location : method { + $_[0]->_html_coltmpl_text("location", h_abbr(__("Location"))); +} + +# _html_col_message: The message +sub _html_col_message : method { + $_[0]->_html_coltmpl_textarea("message", h_abbr(__("Message")), + h_abbr(__("Fill in your message here."))); +} + +# _html_col_name: The name +sub _html_col_name : method { + $_[0]->_html_coltmpl_text("name", h_abbr(__("Signature"))); +} + +# _html_col_url: The website URL +sub _html_col_url : method { + $_[0]->_html_coltmpl_url("url", h_abbr(__("Website URL."))); +} + +return 1; diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily/HTML.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily/HTML.pm new file mode 100644 index 0000000..ce21ccb --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily/HTML.pm @@ -0,0 +1,690 @@ +# Emily Wu's Website +# HTML.pm: The HTML web page parts. + +# Copyright (c) 2003-2020 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-06 + +package Selima::emily::HTML; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(html_header html_title html_message); +push @EXPORT, qw(html_errmsg html_body html_links html_links_index html_footer); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub html_header($;$); +sub html_title($;$); +sub html_message($); +sub html_errmsg($); +sub html_nav(;$); +sub html_login(;$); +sub html_nav_admin(;$); +sub html_nav_page(;$); +sub html_body($;$); +sub html_links($;$); +sub html_links_index(\@;$); +sub html_footer(;$); +sub merged_tree($$;$); +} + +use Cwd qw(realpath); +use File::Basename qw(dirname); +use File::Spec::Functions qw(); +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use Selima::A2HTML; +use Selima::AddGet; +use Selima::AltLang; +use Selima::DataVars qw(:author :env :input :list :lninfo :requri :siteconf); +use Selima::ErrMsg; +use Selima::HTTPS; +use Selima::Links; +use Selima::LnInfo; +use Selima::LogIn; +use Selima::MarkAbbr; +use Selima::MungAddr; +use Selima::PageFunc; +use Selima::Preview; +use Selima::ScptPriv; +use Selima::ShortCut; +use Selima::Unicode; +use Selima::XFileIO; + +use vars qw(@ADMIN_SCRIPTS %HEADER %FOOTER); +@ADMIN_SCRIPTS = ( + { "title" => N_("Manage Content"), + "sub" => [ + { "title" => N_("Guestbook"), + "path" => "/magicat/cgi-bin/guestbook.cgi" }, + { "title" => N_("Pages"), + "path" => "/magicat/cgi-bin/pages.cgi" }, + { "title" => N_("Links"), + "path" => "/magicat/cgi-bin/links.cgi" }, + { "title" => N_("Link Categories"), + "path" => "/magicat/cgi-bin/linkcat.cgi" }, + { "title" => N_("Link Categorization"), + "path" => "/magicat/cgi-bin/linkcatz.cgi" }, + ], + }, + { "title" => N_("Manage Accounts"), + "sub" => [ + { "title" => N_("Users"), + "path" => "/magicat/cgi-bin/users.cgi" }, + { "title" => N_("Groups"), + "path" => "/magicat/cgi-bin/groups.cgi" }, + { "title" => N_("User Membership"), + "path" => "/magicat/cgi-bin/usermem.cgi" }, + { "title" => N_("Group Membership"), + "path" => "/magicat/cgi-bin/groupmem.cgi" }, + { "title" => N_("User Preferences"), + "path" => "/magicat/cgi-bin/userpref.cgi" }, + { "title" => N_("Script Privileges"), + "path" => "/magicat/cgi-bin/scptpriv.cgi" }, + ], + }, + { "title" => N_("Miscellaneous"), + "sub" => [ +# { "title" => N_("Funds"), +# "path" => "/magicat/cgi-bin/funds.cgi" }, + { "title" => N_("Activity Log"), + "path" => "/magicat/cgi-bin/actlog.cgi" }, + { "title" => N_("Rebuild Pages"), + "path" => "/magicat/cgi-bin/rebuild.cgi" }, + { "title" => N_("Analog"), + "path" => "/magicat/analog/" }, + { "title" => N_("Test Script"), + "path" => "/magicat/cgi-bin/test.cgi" }, + ], + }, +); + +# html_header: Display the page header +sub html_header($;$) { + local ($_, %_); + my ($title, $args, $guide); + my ($langname, $langfile); + my ($author, $copyright, $keywords, $copypage); + my ($stylesheets, $javascripts, $favicon, $class, $onload); + my ($titlelang, $skiptobody); + ($title, $args) = @_; + # Obtain the page parameters + $args = page_param $args; + # Set the language + $langname = h(ln $$args{"lang"}, LN_NAME); + $langfile = ln($$args{"lang"}, LN_FILENAME); + # Misc + # The copyright message should be already HTML-escaped, + # for the copyright sign "©". + $author = exists $$args{"author"}? h($$args{"author"}): + defined $AUTHOR? h($AUTHOR): undef; + $copyright = exists $$args{"copyright"}? $$args{"copyright"}: + defined $COPYRIGHT? $COPYRIGHT: undef; + $keywords = exists $$args{"keywords"}? h($$args{"keywords"}): undef; + $copypage = exists $$args{"copypage"}? + h($$args{"copypage"}): h("/copying.html"); + # Style sheets + $stylesheets = []; + push @$stylesheets, "/stylesheets/common.css"; + push @$stylesheets, @{$$args{"stylesheets"}} + if exists $$args{"stylesheets"}; + # JavaScripts + $javascripts = []; + if (exists $$args{"javascripts"}) { + push @$javascripts, "/scripts/common.js"; + push @$javascripts, "/scripts/lang.$langfile.js"; + push @$javascripts, @{$$args{"javascripts"}}; + } + # Favorite icon + $favicon = exists $$args{"favicon"}? + h($$args{"favicon"}): h("/favicon.ico"); + # The class of body + $class = exists $$args{"class"}? + " class=\"" . h($$args{"class"}) . "\"": ""; + # The onload JavaScript event handler + $onload = exists $$args{"onload"}? + " onload=\"" . h($$args{"onload"}) . "\"": ""; + # The accessibility guide + $skiptobody = h(__("Skip to the page content area.")); + $guide = h(__("Page Content Area")); + + print << "EOT"; +" ?> + + + + + + +EOT + # Author, copyright and keywords + print "\n" + if defined $author; + print "\n" + if defined $copyright; + print "\n" + if defined $keywords; + print "\" />\n" + if $$args{"static"}; + # The home page + print "\n"; + # The copyright page + print "\n" + if defined $copypage; + # The author contact information + print "\n"; + # Revelent pages + print "\n" + if exists $$args{"up"}; + print "\n" + if exists $$args{"first"}; + print "\n" + if exists $$args{"prev"}; + print "\n" + if exists $$args{"next"}; + print "\n" + if exists $$args{"last"}; + print "\n" + if exists $$args{"toc"}; + # Style sheets + print "\n" + foreach @$stylesheets; + # JavaScripts + print "\n" + foreach @$javascripts; + # Favorite Icon + print "\n"; + # The title + $titlelang = $$args{"title_lang"} eq $$args{"lang"}? "": + " xml:lang=\"" . h(ln $$args{"title_lang"}, LN_NAME) . "\""; + print "" . h($title) . "\n"; + print << "EOT"; + + + + + + +EOT + + # Show the navigation area + html_nav $args; + # Embrace the content + print << "EOT"; +
+ + +EOT + # Display the title + html_title $title, $args unless $$args{"no_auto_title"}; + + return; +} + +# html_title: Print an HTML title +sub html_title($;$) { + local ($_, %_); + my ($title, $args, $h); + ($title, $args) = @_; + $h = << "EOT"; +

%s

+ +EOT + printf $h, h_abbr($title); + return; +} + +# html_message: Print an HTML message +sub html_message($) { + local ($_, %_); + $_ = $_[0]; + return if !defined $_ || $_ eq ""; + $_ = h_abbr($_); + print << "EOT"; +

$_

+ +EOT + return; +} + +# html_errmsg: Print an HTML error message, a wrapper to html_message() +sub html_errmsg($) { + local ($_, %_); + $_ = $_[0]; + return if !defined $_; + html_message(err2msg $_); + return; +} + +# html_nav: Print the HTML navigation bar +sub html_nav(;$) { + local ($_, %_); + my ($args, $lang, $guide, $FD, @sections); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + $lang = $$args{"lang"}; + # The accessibility guide + $guide = h(__("Navigation Links Area")); + + @sections = qw(); + # Print the primary navigation bar + $HEADER{"file"} = sprintf("%s/magicat/include/header.html", $DOC_ROOT) + if !exists $HEADER{"file"}; + undef $_; + if ( !exists $HEADER{"content"} + || !exists $HEADER{"date"} + || $HEADER{"date"} < ($_ = (stat $HEADER{"file"})[9])) { + $_ = (stat $HEADER{"file"})[9] if !defined $_; + $HEADER{"date"} = $_; + $HEADER{"content"} = hcref_decode ln($lang, LN_CHARSET), xfread $HEADER{"file"}; + } + push @sections, $HEADER{"content"}; + + # Print the section-specific navigation links + push @sections, $$args{"header_html_nav"} + if exists $$args{"header_html_nav"}; + + # Print the log-in information + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_login $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + push @sections, $_ if $_ ne ""; + + # Print the section-specific navigation bar + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + if ($$args{"admin"}) { + html_nav_admin $args; + } else { + html_nav_page $args; + } + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + push @sections, $_ if $_ ne ""; + + # Embrace the navigation links + print << "EOT"; + +
+ +EOT + + return; +} + +# html_login: Print the HTML log-in information +sub html_login(;$) { + local ($_, %_); + my ($args, $msg, $modify, $submit); + $args = $_[0]; + # Skip if not logged-in + return if !defined get_login_sn; + # Obtain the page parameters + $args = page_param $args; + # No log-in bar for static pages + return if $$args{"static"}; + + # The message + $modify = "/magicat/cgi-bin/users.cgi?form=cur&sn=" . get_login_sn; + $msg = sprintf __("Welcome, %s. (Modify)"), + h(get_login_name), h($modify); + $submit = h(__("Log out")); + + print << "EOT"; + +EOT + return; +} + +# html_nav_admin: Print the HTML administrative navigation bar +sub html_nav_admin(;$) { + local ($_, %_); + my ($args, $cgidir, $path, $title); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + + # Find the current CGI directory + $cgidir = "cgi-bin"; + $cgidir = $1 if $REQUEST_PATH =~ /\/(cgi-[a-z0-9]+)\/[a-z0-9]+\.cgi$/; + # Output them + foreach my $cat (@ADMIN_SCRIPTS) { + @_ = qw(); + foreach (@{$$cat{"sub"}}) { + next unless is_script_permitted $$_{"path"}; + ($path, $title) = ($$_{"path"}, $$_{"title"}); + # Fix the path to use the same cgi-* directory alias + $path =~ s/\/cgi-[a-z0-9]+\/([a-z0-9]+\.cgi)$/\/$cgidir\/$1/; + # Fix the path of the HTTPS scripts to use HTTPS + $path = "https://" . https_host . "/$PACKAGE$path" + if exists $$_{"https"} && $$_{"https"} && !is_https; + push @_, sprintf(" %s", + h($path), h_abbr(__($title))); + } + next if @_ == 0; + $title = $$cat{"title"}; + $_ = sprintf(__("%s:"), h_abbr(__($title))); + print "
\n" + . $_ . "\n" . join(" |\n", @_) . "\n" + . "
\n" + if @_ > 0; + } + return; +} + +# html_nav_page: Print the HTML page navigation bar +sub html_nav_page(;$) { + local ($_, %_); + my ($args, $tree); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + # Obtain the page tree + $tree = merged_tree $$args{"path"}, $$args{"lang"}, $$args{"preview"}; + # Bounce for nothing + return if !defined $tree + || !exists $$tree{"pages"} + || !defined $$tree{"pages"} + || @{$$tree{"pages"}} <= 1; + + # Output them + print << "EOT"; + +EOT + return; +} + +# html_body: Print the HTML body +sub html_body($;$) { + local ($_, %_); + my ($page, $args); + ($page, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Output the picture + # To be done + + # Output the content + print "" . (!exists $$page{"html"} || !$$page{"html"}? + a2html($$page{"body"}): $$page{"body"}) . "\n\n"; + + return; +} + +# html_links: Print the HTML links list +sub html_links($;$) { + local ($_, %_); + my ($page, $args); + ($page, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Output the breadcrumb trai + @_ = qw(); + push @_, "" . h(__("Related Links")) . ""; + foreach my $parent (@{$$page{"parents"}}) { + push @_, "" + . h($$parent{"title"}) . ""; + } + push @_, h($$page{"title"}); + print "
\n" + . join(" /\n", @_) . "\n
\n\n"; + + # Output the subcategories + if (@{$$page{"scats"}} > 0) { + print "

" . h(__("Subcategories:")) . "

\n\n
    \n"; + foreach my $cat (@{$$page{"scats"}}) { + $_ = h($$cat{"title"}); + $_ .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
  1. " + . "$_
  2. \n"; + } + print "
\n\n"; + } + + # Output the links + if (@{$$page{"links"}} > 0) { + my $emailalt; + $emailalt = h(__("E-mail")); + print "
    \n"; + foreach my $link (@{$$page{"links"}}) { + my ($url, $title, $ctitle, $dsc); + $url = h($$link{"url"}); + $title = h($$link{"title"}); + print "
  1. \n"; + print "
    \n
    \n" + if defined $$link{"email"}; + # Output the link icon + print "\"$title\"
    \n" + if defined $$link{"icon"}; + # Output the site title + $ctitle = is_usascii_printable($$link{"title"})? + "$title": $title; + if (defined $$link{"title_2ln"}) { + $_ = h($$link{"title_2ln"}); + $_ = "$_" + if is_usascii_printable($$link{"title_2ln"}); + $ctitle .= " $_"; + } + print "$ctitle
    \n"; + # Output the URL + print __("URL.:") . " $url
    \n"; + # Output other information + if (defined $$link{"email"}) { + print __("E-mail:") . " "; + print "\n"; + print "\n"; + print mung_email_span(h($$link{"email"})) . "
    \n"; + } + print __("Address:") . " " . h($$link{"addr"}) . "
    \n" + if defined $$link{"addr"}; + print __("Tel.:") . " " . h($$link{"tel"}) . "
    \n" + if defined $$link{"tel"}; + print __("Fax.:") . " " . h($$link{"fax"}) . "
    \n" + if defined $$link{"fax"}; + # Output the description + $dsc = $$link{"dsc"}; + print h($dsc) . "
    \n"; + print "
    \n
    \n" if defined $$link{"email"}; + print "
  2. \n\n"; + } + print "
\n\n"; + } + + return; +} + +# html_links_index: Print the HTML link categories index +sub html_links_index(\@;$) { + local ($_, %_); + my ($cats, $args); + ($cats, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Bounce for nothing + if (@$cats == 0) { + print "

" . h(__("The database is empty.")) . "

\n\n"; + return; + } + + # Output the root categories + print << "EOT"; +
+ +
    +EOT + foreach my $cat (@$cats) { + $_ = h($$cat{"title"}); + $_ .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
  • " + . "$_
  • \n"; + } + print << "EOT"; +
+ +
+ + +EOT + return; +} + +# html_footer: Print the HTML footer +sub html_footer(;$) { + local ($_, %_); + my ($args, $lang); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + $lang = $$args{"lang"}; + + # Embrace the content + print << "EOT"; +
+ +EOT + # Print the section-specific navigation bar + print "
\n" . $$args{"footer_html_nav"} . "\n\n" + if exists $$args{"footer_html_nav"}; + + # Print the common footer + $FOOTER{"file"} = sprintf("%s/magicat/include/footer.html", $DOC_ROOT) + if !exists $FOOTER{"file"}; + undef $_; + if ( !exists $FOOTER{"content"} + || !exists $FOOTER{"date"} + || $FOOTER{"date"} < ($_ = (stat $FOOTER{"file"})[9])) { + $_ = (stat $FOOTER{"file"})[9] if !defined $_; + $FOOTER{"date"} = $_; + $FOOTER{"content"} = hcref_decode ln($lang, LN_CHARSET), xfread $FOOTER{"file"}; + } + $_ = $FOOTER{"content"}; + $FOOTER{"perl"} = {} if !exists $FOOTER{"perl"}; + if ($$args{"static"}) { + s/\n+\n+/\n\n/; + } elsif ($IS_MODPERL) { + if (!exists ${$FOOTER{"perl"}}{"modperl"}) { + ${$FOOTER{"perl"}}{"modperl"} = << "EOT"; +
+%s +

%s

+
+EOT + ${$FOOTER{"perl"}}{"modperl"} = sprintf(${$FOOTER{"perl"}}{"modperl"}, + h(__("mod_perl -- Speed, Power, Scalability")), + __("This script is written in Perl and optimized for mod_perl.")); + ${$FOOTER{"perl"}}{"modperl"} =~ s/()/$1 hreflang="en"$2/g + if $lang ne "en"; + } + s/\n/${$FOOTER{"perl"}}{"modperl"}/; + } else { + if (!exists ${$FOOTER{"perl"}}{"cgi"}) { + ${$FOOTER{"perl"}}{"cgi"} = << "EOT"; +
+

%s

+
+EOT + ${$FOOTER{"perl"}}{"cgi"} = sprintf(${$FOOTER{"perl"}}{"cgi"}, + __("This script is written in
Perl.")); + ${$FOOTER{"perl"}}{"cgi"} =~ s/()/$1 hreflang="en"$2/g + if $lang ne "en"; + } + s/\n/${$FOOTER{"perl"}}{"cgi"}/; + } + print $_; + + # Show the HTML preview mark + html_preview_mark $args; + + print "\n\n\n"; + return; +} + +# merged_tree: Get the page tree in a directory +sub merged_tree($$;$) { + local ($_, %_); + my ($path, $lang, $preview); + ($path, $lang, $preview) = @_; + + # Return special areas + if ($path =~ /^\/links\//) { + return link_tree($path, $lang, $preview); + # Non-pages (scripts... etc) + } else { + return {}; + } +} + +return 1; diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily/L10N.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily/L10N.pm new file mode 100644 index 0000000..4212d33 --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily/L10N.pm @@ -0,0 +1,38 @@ +# Emily Wu's Website +# L10N.pm: The localization class. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-26 + +package Selima::emily::L10N; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +return 1; + +# The Chinese (Taiwan) localized messages. +package Selima::emily::L10N::zh_tw; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +sub numerate : method { $_[2] } + +return 1; diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily/List/Funds.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily/List/Funds.pm new file mode 100644 index 0000000..870dadf --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily/List/Funds.pm @@ -0,0 +1,269 @@ +# Emily Wu's Website +# Funds.pm: The fund performance list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-12-30 + +package Selima::emily::List::Funds; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::CommText; +use Selima::DataVars qw(:input :requri); +use Selima::MarkAbbr; +use Selima::ShortCut; + +use Selima::Format; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "funds" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = __("Browse Mutual Fund Performances"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "majcat,mincat,title"; + # Known columns that should not be displayed (has a special purpose) + push @{$self->{"COLS_NO_DISPLAY"}}, qw(_m1rank _m3rank _m6rank + _y1rank _y2rank _y3rank _y5rank _y10rank _ytrank); + # No selection + $self->{"noselect"} = 1; + # Column labels + $self->col_labels( + "title" => __("Name"), + "m1ret" => __("1m return"), + "m1rank" => __("1m ranking"), + "m3ret" => __("3m return"), + "m3rank" => __("3m ranking"), + "m6ret" => __("6m return"), + "m6rank" => __("6m ranking"), + "y1ret" => __("1y return"), + "y1rank" => __("1y ranking"), + "y2ret" => __("2y return"), + "y2rank" => __("2y ranking"), + "y3ret" => __("3y return"), + "y3rank" => __("3y ranking"), + "y5ret" => __("5y return"), + "y5rank" => __("5y ranking"), + "y10ret" => __("10y return"), + "y10rank" => __("10y ranking"), + "ytret" => __("This year return"), + "ytrank" => __("This year ranking"), + "beginret" => __("Total return"), + "begindate" => __("Begin from"), + "bestm3" => __("Best 3m return"), + "worstm3" => __("Worst 3m return"), + "sd12" => __("Standard deviation (12m)"), + "sd24" => __("Standard deviation (24m)"), + "beta12" => __("Beta (12m)"), + "beta24" => __("Beta (24m)"), + "sharpe12" => __("Sharpe (12m)"), + "sharpe24" => __("Sharpe (24m)"), + "jensen12" => __("Jensen (12m)"), + "jensen24" => __("Jensen (24m)"), + "treynor12" => __("Treynor (12m)"), + "treynor24" => __("Treynor (24m)"), + "infrma12" => __("Information Ratio (major categories) (12m)"), + "infrma24" => __("Information Ratio (major categories) (24m)"), + "infrmi12" => __("Information Ratio (minor categories) (12m)"), + "infrmi24" => __("Information Ratio (minor categories) (24m)"), + "turnmt" => __("This month turnover"), + "turny1" => __("12m turnover"), + "duration" => __("Duration"), + "rating" => __("Rating"), + "newman" => __("Manager less than 1y?"), + ); + # The pre-defined filter + $self->{"pre_filter"} = [ + ["y5ret IS NOT NULL AND y5ret > 150 AND m1rank < 1.0/4 AND m3rank < 1.0/4 AND m6rank < 1.0/4 AND y1rank < 1.0/4 AND y2rank < 1.0/4 AND y3rank < 1.0/4 AND y5rank < 1.0/4"], + ["y2ret IS NOT NULL AND y1rank < 1.0/4 AND y2rank < 1.0/4 AND m3rank < 1.0/3 AND m6rank < 1.0/3", __("4433 Principle")], + ]; + return $self; +} + +# pre_filter: Set the pre-defined filter +sub pre_filter : method { + local ($_, %_); + my $self; + $self = $_[0]; + if (!defined $GET->param("filter") || $GET->param("filter") eq "none") { + return undef; + } elsif ($GET->param("filter") eq "free") { + return $GET->param("filtertext") eq ""? undef: + $GET->param("filtertext"); + } elsif ($GET->param("filter") =~ /^\d+$/) { + return $GET->param("filter") <= @{$self->{"pre_filter"}}? + ${${$self->{"pre_filter"}}[$GET->param("filter") - 1]}[0]: undef; + } + return undef; +} + +# sql_filter: Get the SQL WHERE phase +# A filter to update the *rank to _*rank +sub sql_filter : method { + local ($_, %_); + my $self; + $self = $_[0]; + $_ = $self->SUPER::sql_filter; + s/(?SUPER::sql_orderby; + s/(?SUPER::colval($col, %row); +} + +# html_search: Display the search box +sub html_search : method { + local ($_, %_); + my ($self, $prompt, $label, $query, $request_file); + ($self, $prompt) = @_; + $prompt = __("Search for a fund:") if !defined $prompt; + # No search box is displayed if no records yet + if ( $self->{"fetched"} + && defined $self->{"total"} && $self->{"total"} == 0 + && !defined $self->{"query"}) { + return; + } + + $request_file = h($REQUEST_FILE); + $query = defined $self->{"query"}? h($self->{"query"}): ""; + $label = h(__("Search")); + + print << "EOT"; +
+ +
+ +EOT +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,fund].", $self->{"total"}); + # List result + } else { + return __("[*,_1,fund].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,fund], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,fund], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily/List/Guestbook.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily/List/Guestbook.pm new file mode 100644 index 0000000..436f0cf --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily/List/Guestbook.pm @@ -0,0 +1,47 @@ +# Emily Wu's Website +# Guestbook.pm: The administrative guestbook message list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::emily::List::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Guestbook); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "guestbook" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Message"): + __("Manage the Guestbook"); + # Column labels + $self->col_labels( + "identity" => __("Occupation"), + ); + return $self; +} + +return 1; diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily/List/Guestbook/Public.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily/List/Guestbook/Public.pm new file mode 100644 index 0000000..3b27e3f --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily/List/Guestbook/Public.pm @@ -0,0 +1,27 @@ +# Emily Wu's Website +# Public.pm: The guestbook message list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::emily::List::Guestbook::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Guestbook::Public); + +return 1; diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily/List/Search.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily/List/Search.pm new file mode 100644 index 0000000..113cc08 --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily/List/Search.pm @@ -0,0 +1,181 @@ +# Emily Wu's Website +# Search.pm: The web site full-text search result list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-11 + +package Selima::emily::List::Search; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::Logging; +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The page title + if (!defined $self->{"query"}) { + $self->{"title"} = __("Full Text Search"); + } else { + $self->{"title"} = __("Search Result"); + } + $self->{"view"} = "search_list"; + $self->{"COLS_NO_SEARCH"} = [qw(section path date html)]; + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my $self; + $self = $_[0]; + # No search specified + if (!defined $self->{"query"}) { + $self->{"total"} = undef; + return $self->{"error"}; + } + # Check the query phrase + # Regularize it + $self->{"query"} =~ s/^\s*(.*?)\s*$/$1/; + # Check if it is filled + if ($self->{"query"} eq"") { + $self->{"total"} = undef; + $self->{"error"} = {"msg"=>N_("Please fill in your query.")}; + return $self->{"error"}; + } + # Run the parent method + $self->SUPER::fetch; + # Add an activity log record + actlog("Query with phrase \"" . $self->{"query"} . "\"."); + # Done + return $self->{"error"}; +} + +# sql_orderby: Get the SQL ORDER BY phase +# Always return nothing +sub sql_orderby : method { return ""; } + +# html_newlink: Display a link to add a new item +# Make it a null function +sub html_newlink : method {} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search in the website:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article].", $self->{"total"}); + # List result + } else { + return __("[*,_1,article].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +# html_list: List the items +sub html_list : method { + local ($_, %_); + my ($self); + $self = $_[0]; + # Do not show the list + return if !defined $self->{"total"}; + # No record to be listed + return if $self->{"total"} == 0; + + print << "EOT"; +
    +EOT + + # Print each record + foreach my $current (@{$self->{"current"}}) { + my ($url, $abstract); + $url = h($$current{"path"}); + $abstract = $self->query_abstract($current); + if ($$current{"section"} eq "pages") { + my $title; + $title = h($$current{"title"}); + + print << "EOT"; +
  1. $title

    +EOT + } elsif ($$current{"section"} eq "links") { + my ($title, $sectitle); + $title = h($$current{"title"}); + $sectitle = h(__("Related Links")); + + print << "EOT"; +
  2. $title

    +
    $sectitle
    +EOT + } elsif ($$current{"section"} eq "guestbook") { + my ($author, $title, $sectitle); + $author = defined $$current{"author"}? + " " . h($$current{"author"}) . "": ""; + $title = h(__("Guestbook Message on [_1]", $$current{"date"})); + $sectitle = h(__("Guestbook")); + + print << "EOT"; +
  3. $title$author

    +
    $sectitle
    +EOT + } + print "\n

    $abstract

    \n" if defined $abstract; + print << "EOT"; +
  4. + +EOT + } + print << "EOT"; +
+ +EOT + return; +} + +return 1; diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily/Processor/Guestbook/Public.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily/Processor/Guestbook/Public.pm new file mode 100644 index 0000000..e8de62c --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily/Processor/Guestbook/Public.pm @@ -0,0 +1,142 @@ +# Emily Wu's Website +# Public.pm: The guestbook data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-19 + +package Selima::emily::Processor::Guestbook::Public; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Selima::Processor::Guestbook); + +use Selima::Country; +use Selima::DataVars qw(:env :input :scptconf); +use Selima::Format; +use Selima::Guest; +use Selima::GeoIP; +use Selima::RemoHost; +use Selima::Unicode; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[0]->param("form", "new"); + $_[0]->param("confirm", 1); + $self = $class->SUPER::new(@_); + $self->{"notify"} = 1; + $self->{"debug"} = 1; + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my $self; + ($self, @_) = @_; + $self->SUPER::_save_cols(@_); + $self->{"cols"}->{"login"} = 723676436; + return; +} + +# _other_tasks: Perform tasks other than column updates +sub _other_tasks : method { + local ($_, %_); + my ($self, $form); + my ($mail, $body, $charset); + $self = $_[0]; + return unless $self->{"notify"}; + $form = $self->{"form"}; + + # Compose the mail body + $body = ""; + $body .= "若要編輯或刪除這則留言,請連上以下網址:\n"; + $body .= "http://" . $ENV{"SERVER_NAME"} . "/magicat/cgi-bin/guestbook.cgi" + . "?form=cur&sn=" . $self->{"sn"} . "\n\n"; + $body .= "日期: " . fmttime . "\n"; + @_ = qw(); + push @_, ctname_zhtw country_lookup; + push @_, remote_host if defined remote_host; + $body .= "來自: " . $ENV{"REMOTE_ADDR"} + . " (" . join(", ", @_) . ")\n"; + $body .= "簽名: " . $form->param("name") . "\n" + if $form->param("name") ne ""; + $body .= "職業: " . $form->param("identity") . "\n" + if $form->param("identity") ne ""; + $body .= "所在地: " . $form->param("location") . "\n" + if $form->param("location") ne ""; + $body .= "E-mail : " . $form->param("email") . "\n" + if $form->param("email") ne ""; + $body .= "網站網址: " . $form->param("url") . "\n" + if $form->param("url") ne "" && $form->param("url") ne "http://"; + $body .= "留言:\n\n" . $form->param("message") . "\n\n"; + $body .= "原始內容:\n" . $USER_INPUT{"POST_RAWDATA"} . "\n"; + + # Collecting Debugging infomation + if ($self->{"debug"}) { + $body .= "\n"; + $body .= "===== Start Debugging Infomation =====\n"; + if ($IS_MODPERL) { + $_ = $IS_MP2? Apache2::RequestUtil->request->as_string: + Apache->request->as_string; + s/^X-Selima-[^\n]+\n//mg; + s/^((?:[^\n]+\n)+).+?$/$1/s; + $body .= $_; + } else { + foreach (sort grep !/^HTTP_X_SELIMA_/, grep /^HTTP_/, keys %ENV) { + my $hname; + $hname = $_; + $hname =~ s/^HTTP_//; + $hname =~ s/_/-/g; + $hname =~ s/(\w)(\w+)/$1 . lc $2/ge; + $body .= "$hname: $ENV{$_}\n"; + } + } + $body .= "===== End Debugging Infomation =====\n"; + } + + # Set the best appropriate output character set + $charset = is_charset($body, "Big5")? "Big5": "UTF-8"; + + # Compose the mail + $mail = new Selima::Mail; + $mail->charset($charset); + $mail->from($THIS_FILE . "\@" . $ENV{"SERVER_NAME"}, "吳芳美網站留言板"); + $mail->to("emily6wu\@ms27.hinet.net", "吳芳美"); + $mail->cc("imacat\@mail.imacat.idv.tw", "楊士青"); + $mail->subject("[Emily] 留言板留言通知 " . fmtdate); + $mail->body($body); + # Send it + $mail->send; + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my $self; + $self = $_[0]; + # A form to create a new item + return gactlog "Post a new message on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "."; +} + +no utf8; +return 1; diff --git a/htdocs/emily/magicat/lib/perl5/Selima/emily/Rebuild.pm b/htdocs/emily/magicat/lib/perl5/Selima/emily/Rebuild.pm new file mode 100644 index 0000000..52fbb54 --- /dev/null +++ b/htdocs/emily/magicat/lib/perl5/Selima/emily/Rebuild.pm @@ -0,0 +1,283 @@ +# Emily Wu's Website +# Rebuild.pm: The subroutines to rebuild the web pages. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +package Selima::emily::Rebuild; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(rebuild_all rebuild_pages rebuild_links compose_page); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub rebuild_all(); +sub rebuild_pages(;$); +sub rebuild_links(;$); +sub compose_page($;$); +} + +use Data::Dumper qw(); +use Fcntl qw(:flock); +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use Selima::DataVars qw($DBH :output :rebuild); +use Selima::GetLang; +use Selima::Guest; +use Selima::PageFunc; +use Selima::ShortCut; + +use Selima::emily::HTML; + +use vars qw($PKGL10N); + +# rebuild_all: Rebuild everything +sub rebuild_all() { + local ($_, %_); + # Lock the required tables + $DBH->lock(map { $_ => LOCK_SH } @REBUILD_TABLES); + # Rebuild the pages + rebuild_pages; + # Rebuild the links + rebuild_links; + # Rebuild the index + # To be done + #rebuild_index; + return; +} + +# rebuild_pages: Rebuild the pages +sub rebuild_pages(;$) { + local ($_, %_); + my ($sql, $sth, $count, $rebuild_everything); + my $lang; + $sql = $_[0]; + + $lang = getlang; + + # Rebuild everything + $rebuild_everything = !defined $sql; + if ($rebuild_everything) { + $sql = "SELECT * FROM pages" + . " WHERE NOT hid;\n"; + } + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + # Bounce if no pages to build on a partial rebuild + # This prevents needless sitemap rebuilding + return if !$rebuild_everything && $count == 0; + # Build each page + for (my $i = 0; $i < $count; $i++) { + my ($page, $html); + $page = $sth->fetchrow_hashref; + # Read the picture into the picture deposit + # To be done + + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + + # Output related pictures only when rebuilding everything + # To be done + } + + return; +} + +# rebuild_links: Rebuild the links +sub rebuild_links(;$) { + local ($_, %_); + my ($sql, $sth, $count, $FD, $rebuild_everything); + my ($lang, $args, $html); + $sql = $_[0]; + + $lang = getlang; + + # Rebuild everything + $rebuild_everything = !defined $sql; + if ($rebuild_everything) { + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_isshown(sn, hid, parent);\n"; + } + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0; $i < $count; $i++) { + my ($page, $sql1, $sth1, $count1, $row1); + $page = $sth->fetchrow_hashref; + + # Find the ancesters + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql1 = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_ischild(sn, " . $$page{"sn"} . ")" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"parents"} = []; $i < $count1; $i++) { + push @{$$page{"parents"}}, $sth1->fetchrow_hashref; + } + + # Find the subcategories + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql1 = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE parent=" . $$page{"sn"} + . " AND linkcat_isshown(sn, hid, parent)" + . " ORDER BY ord;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"scats"} = []; $i < $count1; $i++) { + my ($sql2, $sth2, $row2); + $row1 = $sth1->fetchrow_hashref; + # Find the belonging links + $sql2 = "SELECT count(linkcatz.sn) AS count FROM linkcatz" + . " INNER JOIN links ON linkcatz.link=links.sn" + . " INNER JOIN linkcat ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.cat=" . $$row1{"sn"} + . " AND NOT links.hid;\n"; + $sth2 = $DBH->prepare($sql2); + $sth2->execute; + $row2 = $sth2->fetchrow_hashref; + $$row1{"links"} = $$row2{"count"}; + push @{$$page{"scats"}}, $row1; + } + + # Find the belonging links + @_ = map "links.$_", $DBH->cols("links"); + $sql1 = "SELECT " . join(", ", @_) . " FROM links" + . " INNER JOIN linkcatz ON linkcatz.link=links.sn" + . " WHERE linkcatz.cat=" . $$page{"sn"} + . " AND NOT links.hid;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"links"} = []; $i < $count1; $i++) { + push @{$$page{"links"}}, $sth1->fetchrow_hashref; + } + + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + } + + # Build the root index page + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE parent IS NULL" + . " AND linkcat_isshown(sn, hid, parent)" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @_ = qw(); $_ < $count; $_++) { + my ($cat, $sql1, $sth1, $count1); + $cat = $sth->fetchrow_hashref; + + # Find the belonging links + $sql1 = "SELECT count(linkcatz.sn) AS count FROM linkcatz" + . " INNER JOIN links ON linkcatz.link=links.sn" + . " INNER JOIN linkcat ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.cat=" . $$cat{"sn"} + . " AND NOT links.hid;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $$cat{"links"} = ${$sth1->fetch}[0]; + + push @_, $cat; + } + $ALT_PAGE_PARAM = { + "path" => "/links/", + "lang" => $lang, + "keywords" => __("related links"), + "class" => "links", + "static" => 1, + "all_linguas" => [$lang]}; + $args = page_param; + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header __("Related Links"), $args; + html_links_index @_, $args; + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $html = join "", <$FD>; + undef $ALT_PAGE_PARAM; + goutpage $html, "/links/", $lang; + + return; +} + +# compose_page: Compose a page +sub compose_page($;$) { + local ($_, %_); + my ($page, $lang, $args, $FD); + ($page, $lang) = @_; + $lang = getlang if !defined $lang; + + $ALT_PAGE_PARAM = { + "path" => $$page{"path"}, + "lang" => $lang, + "keywords" => $$page{"kw"}, + "static" => 1, + "all_linguas" => [$lang]}; + $$ALT_PAGE_PARAM{"preview"} = $page + if exists $$page{"preview"}; + if (exists $$page{"class"} && defined $$page{"class"} && $$page{"class"} ne "") { + $$ALT_PAGE_PARAM{"class"} = $$page{"class"}; + } elsif ($$page{"path"} =~ /^\/links\//) { + $$ALT_PAGE_PARAM{"class"} = "links"; + } + $args = page_param; + + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header $$page{"title"}, $args; + if ($$page{"path"} =~ /^\/links\/$/) { + #html_links_index $page, $args; + } elsif ($$page{"path"} =~ /^\/links\/.+$/) { + html_links $page, $args; + } else { + html_body $page, $args; + } + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + + undef $ALT_PAGE_PARAM; + return $_; +} + +return 1; diff --git a/htdocs/emily/magicat/locale/zh_TW/LC_MESSAGES/emily.mo b/htdocs/emily/magicat/locale/zh_TW/LC_MESSAGES/emily.mo new file mode 100644 index 0000000..fbdac62 Binary files /dev/null and b/htdocs/emily/magicat/locale/zh_TW/LC_MESSAGES/emily.mo differ diff --git a/htdocs/emily/magicat/po/Makefile b/htdocs/emily/magicat/po/Makefile new file mode 100644 index 0000000..778648c --- /dev/null +++ b/htdocs/emily/magicat/po/Makefile @@ -0,0 +1,44 @@ +# Possible make targets: +# all: Compile the PO files and copy the binary MO files +# into the appropriate directories +# xgettext: Obtain the newest PO template file $(PACKAGE).pot +# from the source programs +# msgmerge: Compare the template $(PACKAGE).pot and the existing +# PO files and get the newest POX files to work with. + + +PACKAGE = emily +ALLLINGUAS = zh_TW +PKGROOT = ../.. +PODIR = magicat/po +LOCALEDIR = $(PKGROOT)/magicat/locale +CATEGORY = LC_MESSAGES +PROGRAMS = cgi-bin/*.cgi magicat/cgi-bin/*.cgi magicat/lib/perl5/*/*.pm magicat/lib/perl5/*/*/*.pm magicat/lib/perl5/*/*/*/*.pm magicat/lib/perl5/*/*/*/*/*.pm + +all: + for ln in $(ALLLINGUAS); do \ + msgfmt $$ln.po -o $$ln.gmo; \ + test -d $(LOCALEDIR) || \ + (rm -rf $(LOCALEDIR) && \ + mkdir $(LOCALEDIR)); \ + test -d $(LOCALEDIR)/$$ln || \ + (rm -rf $(LOCALEDIR)/$$ln && \ + mkdir $(LOCALEDIR)/$$ln); \ + test -d $(LOCALEDIR)/$$ln/$(CATEGORY) || \ + (rm -rf $(LOCALEDIR)/$$ln/$(CATEGORY) && \ + mkdir $(LOCALEDIR)/$$ln/$(CATEGORY)); \ + rm -f $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + cp $$ln.gmo $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + done + +xgettext: + cd $(PKGROOT); \ + xgettext --keyword=__ --keyword=N_ -p $(PODIR)/ -o $(PACKAGE).pot \ + --language=c $(PROGRAMS); \ + cd $(PODIR); \ + for ln in $(ALLLINGUAS); do \ + msgmerge $$ln.po $(PACKAGE).pot > $$ln.pox; \ + done + +clean: + rm -f *.gmo diff --git a/htdocs/emily/magicat/po/emily.pot b/htdocs/emily/magicat/po/emily.pot new file mode 100644 index 0000000..aeccecf --- /dev/null +++ b/htdocs/emily/magicat/po/emily.pot @@ -0,0 +1,662 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-02-17 17:16+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: cgi-bin/guestbook.cgi:27 magicat/cgi-bin/guestbook.cgi:26 +msgid "guestbook" +msgstr "" + +#: cgi-bin/search.cgi:26 +msgid "search, query, full text search" +msgstr "" + +#: magicat/cgi-bin/actlog.cgi:22 +msgid "activity, logs" +msgstr "" + +#: magicat/cgi-bin/funds.cgi:22 +msgid "mutual funds, performance, indicators" +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:30 +msgid "group membership" +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:94 magicat/cgi-bin/groupmem.cgi:139 +#: magicat/cgi-bin/groups.cgi:102 magicat/cgi-bin/groups.cgi:151 +#: magicat/cgi-bin/guestbook.cgi:90 magicat/cgi-bin/guestbook.cgi:136 +#: magicat/cgi-bin/linkcat.cgi:101 magicat/cgi-bin/linkcat.cgi:154 +#: magicat/cgi-bin/linkcatz.cgi:94 magicat/cgi-bin/linkcatz.cgi:139 +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:137 +#: magicat/cgi-bin/pages.cgi:96 magicat/cgi-bin/pages.cgi:140 +#: magicat/cgi-bin/scptpriv.cgi:92 magicat/cgi-bin/scptpriv.cgi:137 +#: magicat/cgi-bin/usermem.cgi:94 magicat/cgi-bin/usermem.cgi:139 +#: magicat/cgi-bin/userpref.cgi:92 magicat/cgi-bin/userpref.cgi:137 +#: magicat/cgi-bin/users.cgi:111 magicat/cgi-bin/users.cgi:175 +msgid "Incorrect form: [_1]." +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:186 magicat/cgi-bin/usermem.cgi:186 +msgid "Please select the membership record." +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:194 magicat/cgi-bin/usermem.cgi:194 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/groups.cgi:34 +msgid "groups" +msgstr "" + +#: magicat/cgi-bin/groups.cgi:198 +msgid "Please select the group." +msgstr "" + +#: magicat/cgi-bin/groups.cgi:206 +msgid "This group does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/guestbook.cgi:183 +msgid "Please select the message." +msgstr "" + +#: magicat/cgi-bin/guestbook.cgi:191 +msgid "This message does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:29 +msgid "link categories" +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:90 magicat/cgi-bin/linkcat.cgi:143 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:94 magicat/cgi-bin/linkcat.cgi:147 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:202 +msgid "Please select the category." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:210 +msgid "This category does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:30 +msgid "link categorization" +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:186 +msgid "Please select the categorization record." +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:194 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "" + +#: magicat/cgi-bin/links.cgi:28 magicat/lib/perl5/Selima/emily/Rebuild.pm:207 +msgid "related links" +msgstr "" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Please select the related link." +msgstr "" + +#: magicat/cgi-bin/links.cgi:193 +msgid "This related link does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/logout.cgi:25 +msgid "log out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:98 magicat/cgi-bin/logout.cgi:105 +msgid "Log Out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:121 +msgid "Are you sure you want to log out?" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:122 magicat/lib/perl5/Selima/emily/HTML.pm:362 +msgid "Log out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:138 +msgid "Log in again." +msgstr "" + +#: magicat/cgi-bin/pages.cgi:26 +msgid "pages" +msgstr "" + +#: magicat/cgi-bin/pages.cgi:193 +msgid "Please select the page." +msgstr "" + +#: magicat/cgi-bin/pages.cgi:201 +msgid "This page does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/rebuild.cgi:23 +msgid "rebuild pages" +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:28 +msgid "script privilege" +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:184 +msgid "Please select the script privilege record." +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:192 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "" + +#: magicat/cgi-bin/usermem.cgi:30 +msgid "user membership" +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:28 +msgid "user preference" +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:184 +msgid "Please select the user preference." +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:192 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/users.cgi:29 +msgid "users" +msgstr "" + +#: magicat/cgi-bin/users.cgi:222 +msgid "Please select the user." +msgstr "" + +#: magicat/cgi-bin/users.cgi:230 +msgid "This user does not exist anymore. Please select another one." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:59 +msgid "Manage Content" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:61 +#: magicat/lib/perl5/Selima/emily/List/Search.pm:147 +msgid "Guestbook" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:63 +msgid "Pages" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:65 +msgid "Links" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:67 +msgid "Link Categories" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:69 +msgid "Link Categorization" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:73 +msgid "Manage Accounts" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:75 +msgid "Users" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:77 +msgid "Groups" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:79 +msgid "User Membership" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:81 +msgid "Group Membership" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:83 +msgid "User Preferences" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:85 +msgid "Script Privileges" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:89 +msgid "Miscellaneous" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:91 +msgid "Funds" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:93 +msgid "Activity Log" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:95 +msgid "Rebuild Pages" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:97 +msgid "Analog" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:99 +msgid "Test Script" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:151 +msgid "Skip to the page content area." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:152 +msgid "Page Content Area" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:285 +msgid "Navigation Links Area" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:360 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:402 +#, c-format +msgid "%s:" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:472 +#: magicat/lib/perl5/Selima/emily/Rebuild.pm:215 +#: magicat/lib/perl5/Selima/emily/List/Search.pm:136 +msgid "Related Links" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:483 +msgid "Subcategories:" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:498 +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:35 +msgid "E-mail" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:523 +msgid "URL.:" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:526 +msgid "E-mail:" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:532 +msgid "Address:" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:534 +msgid "Tel.:" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:536 +msgid "Fax.:" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:561 +msgid "The database is empty." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:632 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:633 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:646 +msgid "" +"This script is written in Perl." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/Checker/Guestbook.pm:27 +msgid "This occupation is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook.pm:18 +msgid "Occupation:" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook.pm:23 +msgid "Website URL.:" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:28 +msgid "Browse Mutual Fund Performances" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:38 +msgid "Name" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:39 +msgid "1m return" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:40 +msgid "1m ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:41 +msgid "3m return" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:42 +msgid "3m ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:43 +msgid "6m return" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:44 +msgid "6m ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:45 +msgid "1y return" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:46 +msgid "1y ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:47 +msgid "2y return" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:48 +msgid "2y ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:49 +msgid "3y return" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:50 +msgid "3y ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:51 +msgid "5y return" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:52 +msgid "5y ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:53 +msgid "10y return" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:54 +msgid "10y ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:55 +msgid "This year return" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:56 +msgid "This year ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:57 +msgid "Total return" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:58 +msgid "Begin from" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:59 +msgid "Best 3m return" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:60 +msgid "Worst 3m return" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:61 +msgid "Standard deviation (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:62 +msgid "Standard deviation (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:63 +msgid "Beta (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:64 +msgid "Beta (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:65 +msgid "Sharpe (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:66 +msgid "Sharpe (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:67 +msgid "Jensen (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:68 +msgid "Jensen (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:69 +msgid "Treynor (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:70 +msgid "Treynor (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:71 +msgid "Information Ratio (major categories) (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:72 +msgid "Information Ratio (major categories) (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:73 +msgid "Information Ratio (minor categories) (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:74 +msgid "Information Ratio (minor categories) (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:75 +msgid "This month turnover" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:76 +msgid "12m turnover" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:77 +msgid "Duration" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:78 +msgid "Rating" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:79 +msgid "Manager less than 1y?" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:84 +msgid "4433 Principle" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:149 +msgid "Search for a fund:" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:159 +msgid "Search" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:185 +msgid "Advanced filter:" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:236 +msgid "Your query found [*,_1,fund]." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:239 +msgid "[*,_1,fund]." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:245 +msgid "Your query found [*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:249 +msgid "[*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Guestbook.pm:24 +msgid "Select a Message" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Guestbook.pm:25 +msgid "Manage the Guestbook" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Guestbook.pm:28 +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:40 +msgid "Occupation" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:24 +msgid "Full Text Search" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:26 +msgid "Search Result" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:49 +msgid "Please fill in your query." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:71 +msgid "Search in the website:" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:88 +msgid "Your query found [*,_1,article]." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:91 +msgid "[*,_1,article]." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:97 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:101 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:146 +msgid "Guestbook Message on [_1]" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/Checker/Guestbook/Public.pm:36 +msgid "Your occupation is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:28 +msgid "" +"General commercial advertisements are not welcomed. They may be deleted " +"without notice. HTML is not supported." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:45 +msgid "Location" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:50 +msgid "Message" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:51 +msgid "Fill in your message here." +msgstr "" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:56 +msgid "Signature" +msgstr "" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:61 +msgid "Website URL." +msgstr "" diff --git a/htdocs/emily/magicat/po/zh_TW.gmo b/htdocs/emily/magicat/po/zh_TW.gmo new file mode 100644 index 0000000..fbdac62 Binary files /dev/null and b/htdocs/emily/magicat/po/zh_TW.gmo differ diff --git a/htdocs/emily/magicat/po/zh_TW.po b/htdocs/emily/magicat/po/zh_TW.po new file mode 100644 index 0000000..ac6162a --- /dev/null +++ b/htdocs/emily/magicat/po/zh_TW.po @@ -0,0 +1,667 @@ +# Traditional Chinese PO file for the Emily's website +# Copyright (C) 2004-2018 imacat +# This file is distributed under the same license as the emily package. +# imacat , 2004-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: emily 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-02-17 17:16+0800\n" +"PO-Revision-Date: 2018-11-02 00:56+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: cgi-bin/guestbook.cgi:27 magicat/cgi-bin/guestbook.cgi:26 +msgid "guestbook" +msgstr "留言板" + +#: cgi-bin/search.cgi:26 +msgid "search, query, full text search" +msgstr "搜尋, 檢索, 全文檢索" + +#: magicat/cgi-bin/actlog.cgi:22 +msgid "activity, logs" +msgstr "活動, 記錄, 日誌" + +#: magicat/cgi-bin/funds.cgi:22 +msgid "mutual funds, performance, indicators" +msgstr "共同基金, 績效, 指標" + +#: magicat/cgi-bin/groupmem.cgi:30 +msgid "group membership" +msgstr "群組成員" + +#: magicat/cgi-bin/groupmem.cgi:94 magicat/cgi-bin/groupmem.cgi:139 +#: magicat/cgi-bin/groups.cgi:102 magicat/cgi-bin/groups.cgi:151 +#: magicat/cgi-bin/guestbook.cgi:90 magicat/cgi-bin/guestbook.cgi:136 +#: magicat/cgi-bin/linkcat.cgi:101 magicat/cgi-bin/linkcat.cgi:154 +#: magicat/cgi-bin/linkcatz.cgi:94 magicat/cgi-bin/linkcatz.cgi:139 +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:137 +#: magicat/cgi-bin/pages.cgi:96 magicat/cgi-bin/pages.cgi:140 +#: magicat/cgi-bin/scptpriv.cgi:92 magicat/cgi-bin/scptpriv.cgi:137 +#: magicat/cgi-bin/usermem.cgi:94 magicat/cgi-bin/usermem.cgi:139 +#: magicat/cgi-bin/userpref.cgi:92 magicat/cgi-bin/userpref.cgi:137 +#: magicat/cgi-bin/users.cgi:111 magicat/cgi-bin/users.cgi:175 +msgid "Incorrect form: [_1]." +msgstr "查無此表格: [_1] 。" + +#: magicat/cgi-bin/groupmem.cgi:186 magicat/cgi-bin/usermem.cgi:186 +msgid "Please select the membership record." +msgstr "請選擇者成員關係。" + +#: magicat/cgi-bin/groupmem.cgi:194 magicat/cgi-bin/usermem.cgi:194 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "查無此者成員關係,請重新選擇。" + +#: magicat/cgi-bin/groups.cgi:34 +msgid "groups" +msgstr "群組" + +#: magicat/cgi-bin/groups.cgi:198 +msgid "Please select the group." +msgstr "請選擇群組。" + +#: magicat/cgi-bin/groups.cgi:206 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: magicat/cgi-bin/guestbook.cgi:183 +msgid "Please select the message." +msgstr "請選擇要設定的留言。" + +#: magicat/cgi-bin/guestbook.cgi:191 +msgid "This message does not exist anymore. Please select another one." +msgstr "查無該留言,請改選其她留言。" + +#: magicat/cgi-bin/linkcat.cgi:29 +msgid "link categories" +msgstr "相關連結分類" + +#: magicat/cgi-bin/linkcat.cgi:90 magicat/cgi-bin/linkcat.cgi:143 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: magicat/cgi-bin/linkcat.cgi:94 magicat/cgi-bin/linkcat.cgi:147 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: magicat/cgi-bin/linkcat.cgi:202 +msgid "Please select the category." +msgstr "請選擇分類。" + +#: magicat/cgi-bin/linkcat.cgi:210 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: magicat/cgi-bin/linkcatz.cgi:30 +msgid "link categorization" +msgstr "連結分類表" + +#: magicat/cgi-bin/linkcatz.cgi:186 +msgid "Please select the categorization record." +msgstr "請選擇分類資料。" + +#: magicat/cgi-bin/linkcatz.cgi:194 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "查無此分類資料,請重新選擇。" + +#: magicat/cgi-bin/links.cgi:28 magicat/lib/perl5/Selima/emily/Rebuild.pm:207 +msgid "related links" +msgstr "相關連結" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Please select the related link." +msgstr "請選擇要設定的相關連結。" + +#: magicat/cgi-bin/links.cgi:193 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查無該相關連結,請改選其她相關連結。" + +#: magicat/cgi-bin/logout.cgi:25 +msgid "log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:98 magicat/cgi-bin/logout.cgi:105 +msgid "Log Out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:121 +msgid "Are you sure you want to log out?" +msgstr "妳確定要登出嗎?" + +#: magicat/cgi-bin/logout.cgi:122 magicat/lib/perl5/Selima/emily/HTML.pm:362 +msgid "Log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:138 +msgid "Log in again." +msgstr "重新登入。" + +#: magicat/cgi-bin/pages.cgi:26 +msgid "pages" +msgstr "網頁" + +#: magicat/cgi-bin/pages.cgi:193 +msgid "Please select the page." +msgstr "請選擇網頁。" + +#: magicat/cgi-bin/pages.cgi:201 +msgid "This page does not exist anymore. Please select another one." +msgstr "查無此頁,請改選其她網頁。" + +#: magicat/cgi-bin/rebuild.cgi:23 +msgid "rebuild pages" +msgstr "重製網頁" + +#: magicat/cgi-bin/scptpriv.cgi:28 +msgid "script privilege" +msgstr "程式權限" + +#: magicat/cgi-bin/scptpriv.cgi:184 +msgid "Please select the script privilege record." +msgstr "請選擇程式權限。" + +#: magicat/cgi-bin/scptpriv.cgi:192 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "查無該程式權限,請重新選擇。" + +#: magicat/cgi-bin/usermem.cgi:30 +msgid "user membership" +msgstr "使用者成員" + +#: magicat/cgi-bin/userpref.cgi:28 +msgid "user preference" +msgstr "使用者偏好" + +#: magicat/cgi-bin/userpref.cgi:184 +msgid "Please select the user preference." +msgstr "請選擇使用者偏好。" + +#: magicat/cgi-bin/userpref.cgi:192 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "查無該使用者偏好,請重新選擇。" + +#: magicat/cgi-bin/users.cgi:29 +msgid "users" +msgstr "帳號" + +#: magicat/cgi-bin/users.cgi:222 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: magicat/cgi-bin/users.cgi:230 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:59 +msgid "Manage Content" +msgstr "管理網站" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:61 +#: magicat/lib/perl5/Selima/emily/List/Search.pm:147 +msgid "Guestbook" +msgstr "留言板" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:63 +msgid "Pages" +msgstr "網頁" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:65 +msgid "Links" +msgstr "連結" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:67 +msgid "Link Categories" +msgstr "連結分類" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:69 +msgid "Link Categorization" +msgstr "連結分類表" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:73 +msgid "Manage Accounts" +msgstr "管理帳號" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:75 +msgid "Users" +msgstr "帳號" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:77 +msgid "Groups" +msgstr "群組" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:79 +msgid "User Membership" +msgstr "使用者成員" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:81 +msgid "Group Membership" +msgstr "群組成員" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:83 +msgid "User Preferences" +msgstr "使用者偏好" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:85 +msgid "Script Privileges" +msgstr "程式權限" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:89 +msgid "Miscellaneous" +msgstr "雜項" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:91 +msgid "Funds" +msgstr "基金" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:93 +msgid "Activity Log" +msgstr "活動日誌" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:95 +msgid "Rebuild Pages" +msgstr "重製網頁" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:97 +msgid "Analog" +msgstr "訪客統計" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:99 +msgid "Test Script" +msgstr "測試程式" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:151 +msgid "Skip to the page content area." +msgstr "跳到網頁內文區。" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:152 +msgid "Page Content Area" +msgstr "網頁內文區" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:285 +msgid "Navigation Links Area" +msgstr "導覽連結區" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:360 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "%s,妳好!(修改資料)" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:402 +#, c-format +msgid "%s:" +msgstr "%s:" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:472 +#: magicat/lib/perl5/Selima/emily/Rebuild.pm:215 +#: magicat/lib/perl5/Selima/emily/List/Search.pm:136 +msgid "Related Links" +msgstr "相關連結" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:483 +msgid "Subcategories:" +msgstr "子類:" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:498 +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:35 +msgid "E-mail" +msgstr "E-mail" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:523 +msgid "URL.:" +msgstr "網址:" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:526 +msgid "E-mail:" +msgstr "E-mail :" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:532 +msgid "Address:" +msgstr "地址:" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:534 +msgid "Tel.:" +msgstr "電話:" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:536 +msgid "Fax.:" +msgstr "傳真:" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:561 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:632 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "mod_perl -- 速度,動力,無限可能" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:633 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" +"本程式以 Perl 撰寫,專為 mod_perl 設計強化" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:646 +msgid "" +"This script is written in Perl." +msgstr "" +"本程式以 Perl 撰寫" + +#: magicat/lib/perl5/Selima/emily/Checker/Guestbook.pm:27 +msgid "This occupation is too long. (Max. length [#,_1])" +msgstr "職業太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook.pm:18 +msgid "Occupation:" +msgstr "職業:" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook.pm:23 +msgid "Website URL.:" +msgstr "網站網址:" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:28 +msgid "Browse Mutual Fund Performances" +msgstr "瀏覽共同基金績效" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:38 +msgid "Name" +msgstr "名稱" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:39 +msgid "1m return" +msgstr "一個月報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:40 +msgid "1m ranking" +msgstr "一個月排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:41 +msgid "3m return" +msgstr "三個月報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:42 +msgid "3m ranking" +msgstr "三個月排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:43 +msgid "6m return" +msgstr "六個月報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:44 +msgid "6m ranking" +msgstr "六個月排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:45 +msgid "1y return" +msgstr "一年報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:46 +msgid "1y ranking" +msgstr "一年排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:47 +msgid "2y return" +msgstr "兩年報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:48 +msgid "2y ranking" +msgstr "兩年排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:49 +msgid "3y return" +msgstr "三年報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:50 +msgid "3y ranking" +msgstr "三年排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:51 +msgid "5y return" +msgstr "五年報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:52 +msgid "5y ranking" +msgstr "五年排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:53 +msgid "10y return" +msgstr "十年報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:54 +msgid "10y ranking" +msgstr "十年排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:55 +msgid "This year return" +msgstr "今年報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:56 +msgid "This year ranking" +msgstr "今年排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:57 +msgid "Total return" +msgstr "自成立日報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:58 +msgid "Begin from" +msgstr "基金成立日" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:59 +msgid "Best 3m return" +msgstr "最佳三個月報酬" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:60 +msgid "Worst 3m return" +msgstr "最差三個月報酬" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:61 +msgid "Standard deviation (12m)" +msgstr "標準差 (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:62 +msgid "Standard deviation (24m)" +msgstr "標準差 (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:63 +msgid "Beta (12m)" +msgstr "β (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:64 +msgid "Beta (24m)" +msgstr "β (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:65 +msgid "Sharpe (12m)" +msgstr "夏普指數 (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:66 +msgid "Sharpe (24m)" +msgstr "夏普指數 (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:67 +msgid "Jensen (12m)" +msgstr "詹森指數 (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:68 +msgid "Jensen (24m)" +msgstr "詹森指數 (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:69 +msgid "Treynor (12m)" +msgstr "崔納指數 (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:70 +msgid "Treynor (24m)" +msgstr "崔納指數 (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:71 +msgid "Information Ratio (major categories) (12m)" +msgstr "資訊比例(大分類) (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:72 +msgid "Information Ratio (major categories) (24m)" +msgstr "資訊比例(大分類) (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:73 +msgid "Information Ratio (minor categories) (12m)" +msgstr "資訊比例(細分類) (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:74 +msgid "Information Ratio (minor categories) (24m)" +msgstr "資訊比例(細分類) (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:75 +msgid "This month turnover" +msgstr "當月週轉率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:76 +msgid "12m turnover" +msgstr "累積週轉率 (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:77 +msgid "Duration" +msgstr "存續期間" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:78 +msgid "Rating" +msgstr "信用評等" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:79 +msgid "Manager less than 1y?" +msgstr "經理未滿一年?" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:84 +msgid "4433 Principle" +msgstr "4433 法則" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:149 +msgid "Search for a fund:" +msgstr "搜尋基金:" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:159 +msgid "Search" +msgstr "搜尋" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:185 +msgid "Advanced filter:" +msgstr "進階篩選條件:" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:236 +msgid "Your query found [*,_1,fund]." +msgstr "共 [#,_1] 筆相符的基金。" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:239 +msgid "[*,_1,fund]." +msgstr "[#,_1] 筆基金。" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:245 +msgid "Your query found [*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的基金,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:249 +msgid "[*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆基金,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: magicat/lib/perl5/Selima/emily/List/Guestbook.pm:24 +msgid "Select a Message" +msgstr "選擇留言" + +#: magicat/lib/perl5/Selima/emily/List/Guestbook.pm:25 +msgid "Manage the Guestbook" +msgstr "管理留言板" + +#: magicat/lib/perl5/Selima/emily/List/Guestbook.pm:28 +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:40 +msgid "Occupation" +msgstr "職業" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:24 +msgid "Full Text Search" +msgstr "全文檢索" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:26 +msgid "Search Result" +msgstr "搜尋結果" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:49 +msgid "Please fill in your query." +msgstr "請填上檢索的辭彙。" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:71 +msgid "Search in the website:" +msgstr "網站檢索:" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:88 +msgid "Your query found [*,_1,article]." +msgstr "共 [#,_1] 篇相符的文章。" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:91 +msgid "[*,_1,article]." +msgstr "共 [#,_1] 篇文章。" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:97 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:101 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:146 +msgid "Guestbook Message on [_1]" +msgstr "[_1] 留言" + +#: magicat/lib/perl5/Selima/emily/Checker/Guestbook/Public.pm:36 +msgid "Your occupation is too long. (Max. length [#,_1])" +msgstr "妳的職業太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:28 +msgid "" +"General commercial advertisements are not welcomed. They may be deleted " +"without notice. HTML is not supported." +msgstr "本留言板不歡迎一般商業廣告,請自重。不支援 HTML 語法。" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:45 +msgid "Location" +msgstr "所在地" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:50 +msgid "Message" +msgstr "留言" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:51 +msgid "Fill in your message here." +msgstr "請填上妳的留言。" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:56 +msgid "Signature" +msgstr "簽名" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:61 +msgid "Website URL." +msgstr "網站網址" diff --git a/htdocs/emily/magicat/po/zh_TW.pox b/htdocs/emily/magicat/po/zh_TW.pox new file mode 100644 index 0000000..3717ae4 --- /dev/null +++ b/htdocs/emily/magicat/po/zh_TW.pox @@ -0,0 +1,667 @@ +# Traditional Chinese PO file for the Emily's website +# Copyright (C) 2004-2018 imacat +# This file is distributed under the same license as the emily package. +# imacat , 2004-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: emily 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-02-17 17:16+0800\n" +"PO-Revision-Date: 2012-02-17 17:16+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: cgi-bin/guestbook.cgi:27 magicat/cgi-bin/guestbook.cgi:26 +msgid "guestbook" +msgstr "留言板" + +#: cgi-bin/search.cgi:26 +msgid "search, query, full text search" +msgstr "搜尋, 檢索, 全文檢索" + +#: magicat/cgi-bin/actlog.cgi:22 +msgid "activity, logs" +msgstr "活動, 記錄, 日誌" + +#: magicat/cgi-bin/funds.cgi:22 +msgid "mutual funds, performance, indicators" +msgstr "共同基金, 績效, 指標" + +#: magicat/cgi-bin/groupmem.cgi:30 +msgid "group membership" +msgstr "群組成員" + +#: magicat/cgi-bin/groupmem.cgi:94 magicat/cgi-bin/groupmem.cgi:139 +#: magicat/cgi-bin/groups.cgi:102 magicat/cgi-bin/groups.cgi:151 +#: magicat/cgi-bin/guestbook.cgi:90 magicat/cgi-bin/guestbook.cgi:136 +#: magicat/cgi-bin/linkcat.cgi:101 magicat/cgi-bin/linkcat.cgi:154 +#: magicat/cgi-bin/linkcatz.cgi:94 magicat/cgi-bin/linkcatz.cgi:139 +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:137 +#: magicat/cgi-bin/pages.cgi:96 magicat/cgi-bin/pages.cgi:140 +#: magicat/cgi-bin/scptpriv.cgi:92 magicat/cgi-bin/scptpriv.cgi:137 +#: magicat/cgi-bin/usermem.cgi:94 magicat/cgi-bin/usermem.cgi:139 +#: magicat/cgi-bin/userpref.cgi:92 magicat/cgi-bin/userpref.cgi:137 +#: magicat/cgi-bin/users.cgi:111 magicat/cgi-bin/users.cgi:175 +msgid "Incorrect form: [_1]." +msgstr "查無此表格: [_1] 。" + +#: magicat/cgi-bin/groupmem.cgi:186 magicat/cgi-bin/usermem.cgi:186 +msgid "Please select the membership record." +msgstr "請選擇者成員關係。" + +#: magicat/cgi-bin/groupmem.cgi:194 magicat/cgi-bin/usermem.cgi:194 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "查無此者成員關係,請重新選擇。" + +#: magicat/cgi-bin/groups.cgi:34 +msgid "groups" +msgstr "群組" + +#: magicat/cgi-bin/groups.cgi:198 +msgid "Please select the group." +msgstr "請選擇群組。" + +#: magicat/cgi-bin/groups.cgi:206 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: magicat/cgi-bin/guestbook.cgi:183 +msgid "Please select the message." +msgstr "請選擇要設定的留言。" + +#: magicat/cgi-bin/guestbook.cgi:191 +msgid "This message does not exist anymore. Please select another one." +msgstr "查無該留言,請改選其她留言。" + +#: magicat/cgi-bin/linkcat.cgi:29 +msgid "link categories" +msgstr "相關連結分類" + +#: magicat/cgi-bin/linkcat.cgi:90 magicat/cgi-bin/linkcat.cgi:143 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: magicat/cgi-bin/linkcat.cgi:94 magicat/cgi-bin/linkcat.cgi:147 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: magicat/cgi-bin/linkcat.cgi:202 +msgid "Please select the category." +msgstr "請選擇分類。" + +#: magicat/cgi-bin/linkcat.cgi:210 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: magicat/cgi-bin/linkcatz.cgi:30 +msgid "link categorization" +msgstr "連結分類表" + +#: magicat/cgi-bin/linkcatz.cgi:186 +msgid "Please select the categorization record." +msgstr "請選擇分類資料。" + +#: magicat/cgi-bin/linkcatz.cgi:194 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "查無此分類資料,請重新選擇。" + +#: magicat/cgi-bin/links.cgi:28 magicat/lib/perl5/Selima/emily/Rebuild.pm:207 +msgid "related links" +msgstr "相關連結" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Please select the related link." +msgstr "請選擇要設定的相關連結。" + +#: magicat/cgi-bin/links.cgi:193 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查無該相關連結,請改選其她相關連結。" + +#: magicat/cgi-bin/logout.cgi:25 +msgid "log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:98 magicat/cgi-bin/logout.cgi:105 +msgid "Log Out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:121 +msgid "Are you sure you want to log out?" +msgstr "妳確定要登出嗎?" + +#: magicat/cgi-bin/logout.cgi:122 magicat/lib/perl5/Selima/emily/HTML.pm:362 +msgid "Log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:138 +msgid "Log in again." +msgstr "重新登入。" + +#: magicat/cgi-bin/pages.cgi:26 +msgid "pages" +msgstr "網頁" + +#: magicat/cgi-bin/pages.cgi:193 +msgid "Please select the page." +msgstr "請選擇網頁。" + +#: magicat/cgi-bin/pages.cgi:201 +msgid "This page does not exist anymore. Please select another one." +msgstr "查無此頁,請改選其她網頁。" + +#: magicat/cgi-bin/rebuild.cgi:23 +msgid "rebuild pages" +msgstr "重製網頁" + +#: magicat/cgi-bin/scptpriv.cgi:28 +msgid "script privilege" +msgstr "程式權限" + +#: magicat/cgi-bin/scptpriv.cgi:184 +msgid "Please select the script privilege record." +msgstr "請選擇程式權限。" + +#: magicat/cgi-bin/scptpriv.cgi:192 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "查無該程式權限,請重新選擇。" + +#: magicat/cgi-bin/usermem.cgi:30 +msgid "user membership" +msgstr "使用者成員" + +#: magicat/cgi-bin/userpref.cgi:28 +msgid "user preference" +msgstr "使用者偏好" + +#: magicat/cgi-bin/userpref.cgi:184 +msgid "Please select the user preference." +msgstr "請選擇使用者偏好。" + +#: magicat/cgi-bin/userpref.cgi:192 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "查無該使用者偏好,請重新選擇。" + +#: magicat/cgi-bin/users.cgi:29 +msgid "users" +msgstr "帳號" + +#: magicat/cgi-bin/users.cgi:222 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: magicat/cgi-bin/users.cgi:230 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:59 +msgid "Manage Content" +msgstr "管理網站" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:61 +#: magicat/lib/perl5/Selima/emily/List/Search.pm:147 +msgid "Guestbook" +msgstr "留言板" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:63 +msgid "Pages" +msgstr "網頁" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:65 +msgid "Links" +msgstr "連結" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:67 +msgid "Link Categories" +msgstr "連結分類" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:69 +msgid "Link Categorization" +msgstr "連結分類表" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:73 +msgid "Manage Accounts" +msgstr "管理帳號" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:75 +msgid "Users" +msgstr "帳號" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:77 +msgid "Groups" +msgstr "群組" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:79 +msgid "User Membership" +msgstr "使用者成員" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:81 +msgid "Group Membership" +msgstr "群組成員" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:83 +msgid "User Preferences" +msgstr "使用者偏好" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:85 +msgid "Script Privileges" +msgstr "程式權限" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:89 +msgid "Miscellaneous" +msgstr "雜項" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:91 +msgid "Funds" +msgstr "基金" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:93 +msgid "Activity Log" +msgstr "活動日誌" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:95 +msgid "Rebuild Pages" +msgstr "重製網頁" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:97 +msgid "Analog" +msgstr "訪客統計" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:99 +msgid "Test Script" +msgstr "測試程式" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:151 +msgid "Skip to the page content area." +msgstr "跳到網頁內文區。" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:152 +msgid "Page Content Area" +msgstr "網頁內文區" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:285 +msgid "Navigation Links Area" +msgstr "導覽連結區" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:360 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "%s,妳好!(修改資料)" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:402 +#, c-format +msgid "%s:" +msgstr "%s:" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:472 +#: magicat/lib/perl5/Selima/emily/Rebuild.pm:215 +#: magicat/lib/perl5/Selima/emily/List/Search.pm:136 +msgid "Related Links" +msgstr "相關連結" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:483 +msgid "Subcategories:" +msgstr "子類:" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:498 +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:35 +msgid "E-mail" +msgstr "E-mail" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:523 +msgid "URL.:" +msgstr "網址:" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:526 +msgid "E-mail:" +msgstr "E-mail :" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:532 +msgid "Address:" +msgstr "地址:" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:534 +msgid "Tel.:" +msgstr "電話:" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:536 +msgid "Fax.:" +msgstr "傳真:" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:561 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:632 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "mod_perl -- 速度,動力,無限可能" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:633 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" +"本程式以 Perl 撰寫,專為 mod_perl 設計強化" + +#: magicat/lib/perl5/Selima/emily/HTML.pm:646 +msgid "" +"This script is written in Perl." +msgstr "" +"本程式以 Perl 撰寫" + +#: magicat/lib/perl5/Selima/emily/Checker/Guestbook.pm:27 +msgid "This occupation is too long. (Max. length [#,_1])" +msgstr "職業太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook.pm:18 +msgid "Occupation:" +msgstr "職業:" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook.pm:23 +msgid "Website URL.:" +msgstr "網站網址:" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:28 +msgid "Browse Mutual Fund Performances" +msgstr "瀏覽共同基金績效" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:38 +msgid "Name" +msgstr "名稱" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:39 +msgid "1m return" +msgstr "一個月報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:40 +msgid "1m ranking" +msgstr "一個月排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:41 +msgid "3m return" +msgstr "三個月報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:42 +msgid "3m ranking" +msgstr "三個月排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:43 +msgid "6m return" +msgstr "六個月報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:44 +msgid "6m ranking" +msgstr "六個月排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:45 +msgid "1y return" +msgstr "一年報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:46 +msgid "1y ranking" +msgstr "一年排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:47 +msgid "2y return" +msgstr "兩年報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:48 +msgid "2y ranking" +msgstr "兩年排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:49 +msgid "3y return" +msgstr "三年報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:50 +msgid "3y ranking" +msgstr "三年排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:51 +msgid "5y return" +msgstr "五年報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:52 +msgid "5y ranking" +msgstr "五年排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:53 +msgid "10y return" +msgstr "十年報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:54 +msgid "10y ranking" +msgstr "十年排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:55 +msgid "This year return" +msgstr "今年報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:56 +msgid "This year ranking" +msgstr "今年排名" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:57 +msgid "Total return" +msgstr "自成立日報酬率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:58 +msgid "Begin from" +msgstr "基金成立日" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:59 +msgid "Best 3m return" +msgstr "最佳三個月報酬" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:60 +msgid "Worst 3m return" +msgstr "最差三個月報酬" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:61 +msgid "Standard deviation (12m)" +msgstr "標準差 (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:62 +msgid "Standard deviation (24m)" +msgstr "標準差 (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:63 +msgid "Beta (12m)" +msgstr "β (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:64 +msgid "Beta (24m)" +msgstr "β (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:65 +msgid "Sharpe (12m)" +msgstr "夏普指數 (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:66 +msgid "Sharpe (24m)" +msgstr "夏普指數 (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:67 +msgid "Jensen (12m)" +msgstr "詹森指數 (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:68 +msgid "Jensen (24m)" +msgstr "詹森指數 (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:69 +msgid "Treynor (12m)" +msgstr "崔納指數 (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:70 +msgid "Treynor (24m)" +msgstr "崔納指數 (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:71 +msgid "Information Ratio (major categories) (12m)" +msgstr "資訊比例(大分類) (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:72 +msgid "Information Ratio (major categories) (24m)" +msgstr "資訊比例(大分類) (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:73 +msgid "Information Ratio (minor categories) (12m)" +msgstr "資訊比例(細分類) (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:74 +msgid "Information Ratio (minor categories) (24m)" +msgstr "資訊比例(細分類) (24m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:75 +msgid "This month turnover" +msgstr "當月週轉率" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:76 +msgid "12m turnover" +msgstr "累積週轉率 (12m)" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:77 +msgid "Duration" +msgstr "存續期間" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:78 +msgid "Rating" +msgstr "信用評等" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:79 +msgid "Manager less than 1y?" +msgstr "經理未滿一年?" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:84 +msgid "4433 Principle" +msgstr "4433 法則" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:149 +msgid "Search for a fund:" +msgstr "搜尋基金:" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:159 +msgid "Search" +msgstr "搜尋" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:185 +msgid "Advanced filter:" +msgstr "進階篩選條件:" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:236 +msgid "Your query found [*,_1,fund]." +msgstr "共 [#,_1] 筆相符的基金。" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:239 +msgid "[*,_1,fund]." +msgstr "[#,_1] 筆基金。" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:245 +msgid "Your query found [*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的基金,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: magicat/lib/perl5/Selima/emily/List/Funds.pm:249 +msgid "[*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆基金,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: magicat/lib/perl5/Selima/emily/List/Guestbook.pm:24 +msgid "Select a Message" +msgstr "選擇留言" + +#: magicat/lib/perl5/Selima/emily/List/Guestbook.pm:25 +msgid "Manage the Guestbook" +msgstr "管理留言板" + +#: magicat/lib/perl5/Selima/emily/List/Guestbook.pm:28 +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:40 +msgid "Occupation" +msgstr "職業" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:24 +msgid "Full Text Search" +msgstr "全文檢索" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:26 +msgid "Search Result" +msgstr "搜尋結果" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:49 +msgid "Please fill in your query." +msgstr "請填上檢索的辭彙。" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:71 +msgid "Search in the website:" +msgstr "網站檢索:" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:88 +msgid "Your query found [*,_1,article]." +msgstr "共 [#,_1] 篇相符的文章。" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:91 +msgid "[*,_1,article]." +msgstr "共 [#,_1] 篇文章。" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:97 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:101 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/emily/List/Search.pm:146 +msgid "Guestbook Message on [_1]" +msgstr "[_1] 留言" + +#: magicat/lib/perl5/Selima/emily/Checker/Guestbook/Public.pm:36 +msgid "Your occupation is too long. (Max. length [#,_1])" +msgstr "妳的職業太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:28 +msgid "" +"General commercial advertisements are not welcomed. They may be deleted " +"without notice. HTML is not supported." +msgstr "本留言板不歡迎一般商業廣告,請自重。不支援 HTML 語法。" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:45 +msgid "Location" +msgstr "所在地" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:50 +msgid "Message" +msgstr "留言" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:51 +msgid "Fill in your message here." +msgstr "請填上妳的留言。" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:56 +msgid "Signature" +msgstr "簽名" + +#: magicat/lib/perl5/Selima/emily/Form/Guestbook/Public.pm:61 +msgid "Website URL." +msgstr "網站網址" diff --git a/htdocs/emily/robots.txt b/htdocs/emily/robots.txt new file mode 100644 index 0000000..f6f8dd7 --- /dev/null +++ b/htdocs/emily/robots.txt @@ -0,0 +1,9 @@ +User-agent: * +Crawl-delay: 1 +Disallow: /magicat/ + +User-agent: chklinks +Disallow: + +User-agent: HTTrack +Disallow: / diff --git a/htdocs/emily/scripts/common.js b/htdocs/emily/scripts/common.js new file mode 100644 index 0000000..8efc64e --- /dev/null +++ b/htdocs/emily/scripts/common.js @@ -0,0 +1,88 @@ +/* Emily Wu's Website + * common.js: The common JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-07-25 + */ + +// _: Gettext +function _(msg) { + var i; + for (i = 0; i < lc_messages.length; i++) { + if (lc_messages[i][0] == msg) { + return lc_messages[i][1]; + } + } + return msg; +} +// The messages +lc_messages = []; + +// isEmail: Check if an email address is legal +function isEmail(a) { + var i, c, re; + if (typeof(RegExp) == "undefined") return true; + re = new RegExp("^[\\w\\-]+(\\.[\\w\\-]+)*\\@([\\w\\-]+\\.)+[\\w\\-]+$"); + if (typeof(a) != "string") return false; + a = a.toLowerCase(); + if (re.exec(a) == null) return false; + return true; +} + +// trim: Trim the leading and tailing spaces +function trim(a) { + var pos, start, len, spaces; + start = 0; + len = a.length; + spaces = " \t\f\n\r"; + for (start = 0; start < a.length && spaces.indexOf(a.charAt(start)) >= 0; start++, len--); + for (pos = a.length - 1; pos >= 0 && spaces.indexOf(a.charAt(pos)) >= 0; pos--, len--); + return a.substr(start, len); +} +function trimText(a) { + var pos, start, len, spaces, newlines; + start = 0; + len = a.length; + spaces = " \t\f\n\r"; + newlines = "\n\r"; + for (start = 0; start < a.length && spaces.indexOf(a.charAt(start)) >= 0; start++, len--); + for ( ; start-1 >= 0 && newlines.indexOf(a.charAt(start-1)) < 0; start--, len++); + for (pos = a.length - 1; pos >= 0 && spaces.indexOf(a.charAt(pos)) >= 0; pos--, len--); + return a.substr(start, len); +} + +// replace: Replace one phace with another in a string +function replace(source, oldStr, newStr) { + var pos; + pos = 0; + while (true) { + pos = source.indexOf(oldStr, pos); + if (pos == -1) break; + source = source.substr(0, pos) + newStr + source.substr(pos + oldStr.length) + pos += newStr.length; + } + return source; +} + +// clearDefault: Clear the default value of a column +function clearDefault(col, deftext) { + if (col.value == deftext) { + col.value = ""; + } +} diff --git a/htdocs/emily/scripts/guestbook.js b/htdocs/emily/scripts/guestbook.js new file mode 100644 index 0000000..4a950fc --- /dev/null +++ b/htdocs/emily/scripts/guestbook.js @@ -0,0 +1,55 @@ +/* Emily Wu's Website + * guestbook.js: The guestbook-related JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-07-25 + */ + +// isGuestbookOK: Check if the message is ready to be submitted +function isGuestbookOK(form) { + + // Regularize the fields + form.message.value = trimText(form.message.value); + form.name.value = trim(form.name.value); + form.identity.value = trim(form.identity.value); + form.location.value = trim(form.location.value); + form.email.value = trim(form.email.value); + form.url.value = trim(form.url.value); + + // Check the message + if (form.message.value == "" || form.message.value == _("Fill in your message here.")) { + alert(_("Please fill in your message.")); + form.message.focus(); + return false; + } + if (form.message.value.length > 10240) { + alert(_("Your message is too long. (Max. 10,240 letters)")); + form.message.focus(); + return false; + } + + // Check the signature + if (form.name.value == "") { + alert(_("Please fill in your signature.")); + form.name.focus(); + return false; + } + + return true; +} diff --git a/htdocs/emily/scripts/lang.zh-tw.js b/htdocs/emily/scripts/lang.zh-tw.js new file mode 100644 index 0000000..f573a69 --- /dev/null +++ b/htdocs/emily/scripts/lang.zh-tw.js @@ -0,0 +1,30 @@ +/* Emily Wu's Website + * lang.zh-tw.js: The Chinese (Taiwan) localized messages. + */ + +/* Copyright (c) 2004-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2004-11-06 + */ + +// The messages +lc_messages = [ +["Fill in your message here.", "請填上妳的留言。"], +["Please fill in your message.", "請填上妳的留言。"], +["Your message is too long. (Max. 10,240 letters)", "妳的留言太長了。(最長 10,240 個字)"], +["Please fill in your signature.", "請填上妳的簽名。"], +]; diff --git a/htdocs/emily/stylesheets/analog.css b/htdocs/emily/stylesheets/analog.css new file mode 100644 index 0000000..9cf825e --- /dev/null +++ b/htdocs/emily/stylesheets/analog.css @@ -0,0 +1,24 @@ +/* Emily Wu's Website + * analog.css: The style sheet for Analog analysis reports. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-11-11 + */ + +@import url("common.css"); diff --git a/htdocs/emily/stylesheets/common.css b/htdocs/emily/stylesheets/common.css new file mode 100644 index 0000000..0ee0f36 --- /dev/null +++ b/htdocs/emily/stylesheets/common.css @@ -0,0 +1,369 @@ +/* Emily Wu's Website + * common.css: The common style sheet. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-07-23 + */ + +/* General settings */ +body { + background: #C0E0FF url("../images/backgrnd") repeat-y scroll; + color: black; + margin: 0; + padding: 0.5em 1em; +} +.body { + margin: 1em 0.75in; + padding: 0; + width: 100%; +} +/* Refer to http://www.w3.org/Style/threepart-f.css */ +/* The child selectors are a hack to hide these rules from WinIE6 */ +body>div.body { + width: auto; +} +a:link, a:visited, a:active { + background-color: transparent; + color: blue; + text-decoration: none; +} +a:hover { + background-color: yellow; + color: inherit; + text-decoration: underline; +} +:lang(en) { + font-family: Arial, sans-serif; +} +h1, h2, h3, h4, h5, h6 { + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-weight: normal; + margin: 0; + padding: 0; +} +h1 { + margin: 0.5em 0.75in 1em 0.75in; +} +h1 :lang(en) { + font-family: "Times New Roman", "Times.New.Roman", times, serif; + font-style: italic; + font-weight: bolder; +} +address { + font-size: 0.833em; + display: block; +} +pre { + margin: 0; +} +caption { + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.44em; +} +form { + margin: 0; +} +.note { + font-size: 0.833em; + font-style: italic; +} +div.errmsg { + margin: 1em 0.5in; +} +/* The CAPTCHA */ +.trwebsite, .trlastname { + display: none; +} + +/* The navigation bar */ +.navibar, .pagebar, .langs { + font-size: 0.833em; + text-align: center; +} +.navibar .text { + width: 4em; +} +.nav hr { + margin: 0.1em 0; + padding: 0; + height: 0; +} + +/* The footer */ +.footer { + clear: both; + font-size: 0.833em; + text-align: center; +} +.footer p { + margin: 0; + text-indent: 0; +} +.footer img { + border-style: none; +} +.footer .modperl img { + height: 30px; + width: 110px; +} +.pridetouricon { + height: 100px; + width: 100px; +} + +/* The default list */ +.deflist { + margin: 1em 3em; +} +.deflist th { + white-space: nowrap; +} +.deflist th, .deflist td { + padding: 0.2em 0.5em; + vertical-align: top; +} +.deflist thead { + background-color: silver; + color: black; +} +.deflist tbody th { + font-weight: normal; +} +.deflist .listno, .deflist .listdel { + text-align: center; +} +.oddrow { + background-color: white; + color: black; +} +.evenrow { + background-color: #D0F0FF; + color: black; +} + +/* The default form */ +.defform { + margin: 0 0.75in; + width: 100%; +} +/* Refer to http://www.w3.org/Style/threepart-f.css */ +/* The child selectors are a hack to hide these rules from WinIE6 */ +body>form.defform { + width: auto; +} +.defform table { + margin: 0 auto; + width: 100%; +} +.defform th, .defform td { + text-align: left; + vertical-align: top; +} +.defform .thfile { + width: 9em; +} +.defform .th { + width: 8.5em; +} +.defform .oldnew { + width: 3.5em; +} +.defform td .text, .defform td textarea { + width: 100%; +} +.defform td .prompt { + font-style: italic; + margin: 0; +} +.defform td ol, .defform td li ul { + margin: 0 0 0 2em; + padding: 0; +} +.defform td ul, .defform td li { + margin: 0; + padding: 0; +} +.defform td ul li { + list-style: none; +} +.defform td .oneline li { + display: block; + float: left; + margin-right: 0.5em; +} +.defform td h4, .defform td .picinfo, .defform td .piccap { + margin: 0; + padding: 0; +} + +/* The home page */ +.home .photo { + float: left; + margin: 0 0.5em 0.5em 0; +} +.home h2 { + background-color: #C0C0FF; + color: black; + width: 100%; + border: thin none; + font-size: 1.44em; + padding: 0.1em 1em; +} +/* Refer to http://www.w3.org/Style/threepart-f.css */ +/* The child selectors are a hack to hide these rules from WinIE6 */ +.home .body>h2 { + width: auto; +} + +/* The guestbook */ +.guestbook .defform, .guestbook .foreword { + margin: 1em 0.75in; + padding: 0 0; + width: 100%; +} +/* Refer to http://www.w3.org/Style/threepart-f.css */ +/* The child selectors are a hack to hide these rules from WinIE6 */ +.guestbook .body>form.defform, .guestbook .body>div.foreword { + width: auto; +} +.guestbook .defform p { + text-indent: 0; + margin: 0; +} +.guestbook .defform table { + margin: 0 auto; + width: 100%; +} +.guestbook .defform th { + text-align: left; + vertical-align: top; + width: 5.5em; +} +.guestbook .defform td { + vertical-align: top; +} +.guestbook .defform .text, .guestbook .defform textarea { + font-size: 1em; + width: 100%; +} +.guestbook .entries { + margin: 0 0.5in; +} +.guestbook .entry { + margin: 1em 0.25in; +} +.guestbook .entry div { + margin: 1em 0; +} +.guestbook .entry address { + text-align: right; +} +.guestbook .entry address cite { + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.44em; + font-style: normal; +} +.guestbook .entry address :lang(en) { + font-family: "Times New Roman", "Times.New.Roman", times, serif; +} +.guestbook .entry address samp { + font-style: normal; + vertical-align: text-bottom; +} + +/* The related links */ +.links .linkslist { + margin: 1em 0.75in; + padding: 0; +} +.links .linkslist li { + margin: 1em 0 1em 2em; + padding: 0; +} +.links .linkslist li img { + border: 0; + vertical-align: top; +} +.links .linkslist li cite { + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.2em; + font-style: normal; +} + +/* The full text search */ +.searchresult em { + background-color: transparent; + color: red; + font-weight: bolder; +} +.searchresult h3 { + margin: 0; +} +.searchresult li { + margin-bottom: 1em; +} + +/* The accessibility guides */ +.skiptobody { + position: absolute; + line-height: 0; + left: 0; + top: 0; + z-index: -9; +} +.accessguide { + float: left; + font-size: 0.5em; + color: #FFFFFF; +} + +/* The preview mark */ +.previewmark { + position: fixed; + top: 1em; + left: 1em; + border: thick solid red; + color: red; + background-color: transparent; + margin: 0; + padding: 0.5em; +} +.previewmark h2 { + text-transform: uppercase; + text-align: center; + margin: 0; + padding: 0; +} +.previewmark p { + margin: 0; + padding: 0; + text-indent: 0; +} +.previewmark a, .previewmark a:visited, .previewmark a:hover { + color: red; + background-color: transparent; +} + +/* The breadcrumb trail */ +.breadcrumb { + clear: both; + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.44em; + margin: 0.5em 0.75in; +} diff --git a/htdocs/htc/cgi-bin/1-guestbook.cgi b/htdocs/htc/cgi-bin/1-guestbook.cgi new file mode 100755 index 0000000..18973ad --- /dev/null +++ b/htdocs/htc/cgi-bin/1-guestbook.cgi @@ -0,0 +1,120 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# 1-guestbook.cgi: The guestbook. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-06 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); + +initenv(-session => 0, + -this_table => "guestbook", + -dbi_lock => {"guestbook" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("guestbook"), + "class" => "guestbook", + "javascripts" => [qw(/scripts/guestbook.js)]}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::htc::Processor::Guestbook::Public($POST); + $processor->process; + http_303 $REQUEST_FILE; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + # Old styled page number + http_301 $REQUEST_FILE if defined $GET->param("no"); + # List handler handles its own error + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::htc::Checker::Guestbook::Public(curform); + $error = $checker->check(qw(message name identity location + email url flood dup spam)); + return $error if defined $error; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM, $args); + $status = $_[0]; + $FORM = new Selima::htc::Form::Guestbook::Public($status); + $LIST = new Selima::htc::List::Guestbook::Public; + $args = $LIST->page_param; + html_header __("Guestbook"), $args; + html_errmsg $status; + $FORM->html; + $LIST->html; + html_footer $args; + return; +} + + +################################## +# Subroutines to manage the data # +################################## diff --git a/htdocs/htc/cgi-bin/counter.cgi b/htdocs/htc/cgi-bin/counter.cgi new file mode 100755 index 0000000..90fcc2b --- /dev/null +++ b/htdocs/htc/cgi-bin/counter.cgi @@ -0,0 +1,219 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# counter.cgi: The visitor counter. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-07 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub dont_update(); +sub read_counter(); +sub update_counter(); +sub log_visitor($); +sub counter_cookie(); +sub html_image($); + +use Fcntl qw(:seek); +use Date::Format qw(time2str); +use GD; +use IO::NestedCapture qw(CAPTURE_STDOUT); +use Net::CIDR::Lite qw(); + +use constant DATA_FILE => $ENV{"DOCUMENT_ROOT"} . "/magicat/data/counter.dat"; +use constant LOG_FILE => "/var/log/apache2/htc/counter.log"; +use vars qw($OUR_NETWORKS @FGCOLOR @BGCOLOR $FONT); +# People in our networks will not be counted +$OUR_NETWORKS = Net::CIDR::Lite->new( + qw(127.0.0.1/8 10.0.0.0/8 211.20.30.96/29)); +@FGCOLOR = (0, 0, 0); # #000000 Black +@BGCOLOR = (255, 255, 255); # #FFFFFF White +$FONT = gdLargeFont; +use constant TRANSPARENT => 1; +use constant COOKIE_NAME => "counter"; +use constant COUNT_ARG => "countme"; +use constant IGNORE_ARG => "ignoreme"; +initenv( -allowed => [qw(GET HEAD)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0, + -multilang => 0); + +main; +exit 0; + +sub main() { + local ($_, %_); + + # If we should not update the counter + if (dont_update) { + # Check last-modified here + my (@tables, @files); + @tables = qw(); + @files = (DATA_FILE); + http_304 if not_modified @tables, @files; + html_image read_counter; + + # Update the counter + } else { + $_ = html_image update_counter; + # Log the visitor + log_visitor $_; + } + + # Set the counter cookie + $NEWCOOKIES{COOKIE_NAME()} = $_ if defined ($_ = counter_cookie); + + return; +} + +# dont_update: If we should not update the counter +sub dont_update() { + local ($_, %_); + # Find any reason that we should not update the counter + # If this visitor came from our own network + return 1 if $OUR_NETWORKS->find($ENV{"REMOTE_ADDR"}); + # If this visitor had been counted + return 1 if exists $COOKIES{COOKIE_NAME()}; + # If we are not told to count this visitor + return 1 if !defined $GET->param(COUNT_ARG); + # Well, update it + return 0; +} + +# read_counter: Read the counter +sub read_counter() { + return -s DATA_FILE? xfread DATA_FILE: 0; +} + +# update_counter: Update the counter +sub update_counter() { + local ($_, %_); + # File exists + if (-s DATA_FILE) { + my $FH; + open $FH, "+<", DATA_FILE or http_500 DATA_FILE . ": $!"; + flock $FH, LOCK_EX or http_500 DATA_FILE . ": $!"; + $_ = <$FH>; + $_++; + seek $FH, 0, SEEK_SET or http_500 DATA_FILE . ": $!"; + truncate $FH, 0 or http_500 DATA_FILE . ": $!"; + print $FH $_ or http_500 DATA_FILE . ": $!"; + flock $FH, LOCK_UN or http_500 DATA_FILE . ": $!"; + close $FH or http_500 DATA_FILE . ": $!"; + + # Not exists or zero sized -- create a new one + } else { + xfwrite DATA_FILE, ($_ = 1); + } + return $_; +} + +# log_visitor: Log the visitor +sub log_visitor($) { + local ($_, %_); + my ($host, $user, $date, $uri, $size, $referer, $ua, $langs, $FD); + $size = $_[0]; + + # Gather the infomation to log + $host = (defined remote_host)? remote_host: $ENV{"REMOTE_ADDR"}; + $user = (exists $ENV{"REMOTE_USER"} && $ENV{"REMOTE_USER"} ne "")? + $ENV{"REMOTE_USER"}: "-"; + $date = time2str("%d/%b/%Y:%T %z", time); + $uri = $REQUEST_URI; + $referer = (exists $ENV{"HTTP_REFERER"} && $ENV{"HTTP_REFERER"} ne "")? + $ENV{"HTTP_REFERER"}: "-"; + $ua = (exists $ENV{"HTTP_USER_AGENT"} && $ENV{"HTTP_USER_AGENT"} ne "")? + $ENV{"HTTP_USER_AGENT"}: "="; + $langs = (exists $ENV{"HTTP_ACCEPT_LANGUAGE"} && $ENV{"HTTP_ACCEPT_LANGUAGE"} ne "")? + $ENV{"HTTP_ACCEPT_LANGUAGE"}: "-"; + + # Compose the log record 組合紀錄行 + $_ = sprintf "%s - %s [%s] \"%s %s %s\" 200 %s \"%s\" \"%s\" \"%s\" %s %s\n", + $host, $user, $date, $ENV{"REQUEST_METHOD"}, $uri, + $ENV{"SERVER_PROTOCOL"}, $size, $referer, $ua, $langs, + $ENV{"REMOTE_ADDR"}, country_lookup($ENV{"REMOTE_ADDR"}); + + # Save the log record 儲存記錄 + xfappend LOG_FILE, $_; + + return; +} + +# counter_cookie: Set the counter cookie +sub counter_cookie() { + local ($_, %_); + # Leave our network alone + return if $OUR_NETWORKS->find($ENV{"REMOTE_ADDR"}); + # Already set + return if exists $COOKIES{COOKIE_NAME()}; + # Count me + return new CGI::Cookie( -name=>COOKIE_NAME, + -value=>"counted", + -path=>$REQUEST_PATH) + if defined $GET->param(COUNT_ARG); + # Ignore me + return new CGI::Cookie( -name=>COOKIE_NAME, + -value=>"ignored", + -path=>$REQUEST_PATH) + if defined $GET->param(IGNORE_ARG); + # Leave it alone + return; +} + +# html_image: Make the image from the counter value +sub html_image($) { + local $_; + my ($counter, $image, $width, $height, $fgcolor, $bgcolor); + $counter = $_[0]; + + # Group the counter with commas at thousand digits. + $counter = fmtno($counter); + + # Initialize the image object + # Get the width and height + $width = $FONT->width * (length $counter); + $height = $FONT->height; + # Create an image object + $image = GD::Image->new($width, $height); + # Create the forground/background color objects + $fgcolor = $image->colorAllocate(@FGCOLOR); + $bgcolor = $image->colorAllocate(@BGCOLOR); + + # Draw the image + # Set the transparent background + $image->transparent($bgcolor) if TRANSPARENT; + # Paint the background + $image->filledRectangle(0, 0, $width, $height, $bgcolor); + # Write the text + $image->string($FONT, 0, 0, $counter, $fgcolor); + + # Output + $CONTENT_TYPE = "image/png"; + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":raw"; + $_ = $image->png; + print $_; + + return length $_; +} diff --git a/htdocs/htc/cgi-bin/last_update.cgi b/htdocs/htc/cgi-bin/last_update.cgi new file mode 100755 index 0000000..2b32f7f --- /dev/null +++ b/htdocs/htc/cgi-bin/last_update.cgi @@ -0,0 +1,142 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# last_update.cgi: The last-update date of the whole web site. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-09 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub find_files_in(\@\@); +sub fmttime_local($); +sub html_image($); + +use File::Spec; +use GD; +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use vars qw(@DIREXCS %RDIREXCS @FGCOLOR @BGCOLOR $FONT); +# Directories to be excluded (no leading and trailing slashes) +@DIREXCS = qw(magicat); +@FGCOLOR = (0, 0, 0); # #000000 Black +@BGCOLOR = (255, 255, 255); # #FFFFFF White +$FONT = gdLargeFont; +use constant TRANSPARENT => 1; +initenv( -allowed => [qw(GET HEAD)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0, + -multilang => 0); +%RDIREXCS = map { File::Spec->catfile($DOC_ROOT, $_) => 1 } @DIREXCS; + +main; +exit 0; + +sub main() { + local ($_, %_); + my (@tables, @files); + + @tables = qw(); + @files = qw(); + @_ = ($DOC_ROOT); + find_files_in(@files, @_); + http_304 if not_modified @tables, @files; + + html_image($LAST_MODIFIED); + + return; +} + +# find_files_in: an easy file finder +sub find_files_in(\@\@) { + local ($_, %_); + my ($files, $dirs, @subdirs, $DH, $ent); + ($files, $dirs) = @_; + + # Bounce for nothing + return if scalar(@$dirs) == 0; + # Look in these directories + @subdirs = qw(); + foreach my $dir (@$dirs) { + $dir =~ s/\/$//; + opendir $DH, $dir or die "$dir: $!"; + while (defined($_ = readdir $DH)) { + next if /^\./; + # Using catfile() is better, but a lot slower + $ent = File::Spec->catfile($dir, $_); + #$ent = "$dir/$_"; + if (-f $ent) { + push @$files, $ent; + } elsif (-d $ent) { + push @subdirs, $ent + if !exists $RDIREXCS{$ent}; + } + } + closedir $DH or die "$dir: $!"; + } + # Look in the subdirectories + find_files_in @$files, @subdirs; + return; +} + +# fmttime_local: Format the time using my own format +sub fmttime_local($) { + @_ = localtime $_[0]; + return sprintf "%d.%d.'%02d", $_[4]+1, $_[3], ($_[5]+1900) % 100; +} + +# html_image: Make the image from the last-update value +sub html_image($) { + local $_; + my ($last_update, $image, $width, $height, $fgcolor, $bgcolor); + $last_update = $_[0]; + + # Format the date to my preferred format + $last_update = fmttime_local($last_update); + + # Initialize the image object + # Get the width and height + $width = $FONT->width * (length $last_update); + $height = $FONT->height; + # Create an image object + $image = GD::Image->new($width, $height); + # Create the forground/background color objects + $fgcolor = $image->colorAllocate(@FGCOLOR); + $bgcolor = $image->colorAllocate(@BGCOLOR); + + # Draw the image + # Set the transparent background + $image->transparent($bgcolor) if TRANSPARENT; + # Paint the background + $image->filledRectangle(0, 0, $width, $height, $bgcolor); + # Write the text + $image->string($FONT, 0, 0, $last_update, $fgcolor); + + # Output + $CONTENT_TYPE = "image/png"; + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":raw"; + print $image->png; + + return; +} diff --git a/htdocs/htc/cgi-bin/mailto.cgi b/htdocs/htc/cgi-bin/mailto.cgi new file mode 100755 index 0000000..93bc959 --- /dev/null +++ b/htdocs/htc/cgi-bin/mailto.cgi @@ -0,0 +1,70 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# mailto.cgi: The e-mail hyperlink redirector. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-05-13 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_post(); + +use Fcntl qw(:seek); + +initenv(-allowed => [qw(POST)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $error; + + # Only POSTed forms are allowed + $error = check_post; + # If an error occurs + if (defined $error) { + http_400; + + # Else, save the data + } else { + http_303 "mailto:" . $POST->param("email"); + } + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::Checker::MailTo(curform); + $error = $checker->check(qw(email)); + return $error if defined $error; + # OK + return; +} diff --git a/htdocs/htc/cgi-bin/search.cgi b/htdocs/htc/cgi-bin/search.cgi new file mode 100755 index 0000000..725a689 --- /dev/null +++ b/htdocs/htc/cgi-bin/search.cgi @@ -0,0 +1,55 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# search.cgi: The web site full-text search. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-28 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); + +use Fcntl qw(:seek); + +initenv(-allowed => [qw(GET HEAD)], + -session => 0, + -dbi_lock => {"pages" => LOCK_SH, + "links" => LOCK_SH, + "guestbook" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("search, query, full text search"), + "class" => "search"}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $LIST; + # List handler handles its own error + $LIST = new Selima::htc::List::Search; + html_header $LIST->{"title"}, $LIST->page_param; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/htc/editors.html.html b/htdocs/htc/editors.html.html new file mode 120000 index 0000000..6f446e7 --- /dev/null +++ b/htdocs/htc/editors.html.html @@ -0,0 +1 @@ +editors.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/editors.html.xhtml b/htdocs/htc/editors.html.xhtml new file mode 100644 index 0000000..086eba3 --- /dev/null +++ b/htdocs/htc/editors.html.xhtml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + +編輯群 + + + + + + + +
+ +
+ + +

編輯群

+ +

本刊《歷史:理論與文化》創刊於一九九八年夏,由一群輔仁大學歷史學研究所在學或畢業的青年所共同發起,是一份關於西洋史研究的通訊刊物。

+ +

我們歡迎任何關心臺灣西洋史研究的人士之共同參與,並期待您能參加我們所舉辦的活動。

+ +

《歷史:理論與文化》的編輯群:

+ + + +
+ +
+ + + + diff --git a/htdocs/htc/errors/301.html.html b/htdocs/htc/errors/301.html.html new file mode 120000 index 0000000..7d57edf --- /dev/null +++ b/htdocs/htc/errors/301.html.html @@ -0,0 +1 @@ +301.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/errors/301.html.xhtml b/htdocs/htc/errors/301.html.xhtml new file mode 100644 index 0000000..2322f19 --- /dev/null +++ b/htdocs/htc/errors/301.html.xhtml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + +HTTP 301 網址已遷 + + + + + + + +
+ +
+ + +

HTTP 301 網址已遷

+ +

本頁已遷址,日後請更新妳的書籤或妳的最愛,並改往新址

+ +
+ +
+ + + + diff --git a/htdocs/htc/errors/303.html.html b/htdocs/htc/errors/303.html.html new file mode 120000 index 0000000..74b918a --- /dev/null +++ b/htdocs/htc/errors/303.html.html @@ -0,0 +1 @@ +303.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/errors/303.html.xhtml b/htdocs/htc/errors/303.html.xhtml new file mode 100644 index 0000000..161018f --- /dev/null +++ b/htdocs/htc/errors/303.html.xhtml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + +HTTP 303 續往下址 + + + + + + + +
+ +
+ + +

HTTP 303 續往下址

+ +

請續往後續的網址

+ +
+ +
+ + + + diff --git a/htdocs/htc/errors/307.html.html b/htdocs/htc/errors/307.html.html new file mode 120000 index 0000000..5730eb3 --- /dev/null +++ b/htdocs/htc/errors/307.html.html @@ -0,0 +1 @@ +307.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/errors/307.html.xhtml b/htdocs/htc/errors/307.html.xhtml new file mode 100644 index 0000000..3823148 --- /dev/null +++ b/htdocs/htc/errors/307.html.xhtml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + +HTTP 307 網址暫移 + + + + + + + +
+ +
+ + +

HTTP 307 網址暫移

+ +

請參閱本頁目前的網址

+ +
+ +
+ + + + diff --git a/htdocs/htc/errors/400.html.html b/htdocs/htc/errors/400.html.html new file mode 120000 index 0000000..a1fe2e8 --- /dev/null +++ b/htdocs/htc/errors/400.html.html @@ -0,0 +1 @@ +400.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/errors/400.html.xhtml b/htdocs/htc/errors/400.html.xhtml new file mode 100644 index 0000000..07342a0 --- /dev/null +++ b/htdocs/htc/errors/400.html.xhtml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + +HTTP 400 語法錯誤 + + + + + + + +
+ +
+ + +

HTTP 400 語法錯誤

+ + + +

很抱歉,妳的要求語法錯誤,網站看不懂妳的要求。這可能是瀏覽器的問題,或妳輸入的網址有筆誤。請更正妳的筆誤,或請回歷史:理論與文化首頁重新瀏覽。

+ +

若有任何問題,請來信告訴我們

+ +
+ +
+ + + + diff --git a/htdocs/htc/errors/401.html.html b/htdocs/htc/errors/401.html.html new file mode 120000 index 0000000..f605262 --- /dev/null +++ b/htdocs/htc/errors/401.html.html @@ -0,0 +1 @@ +401.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/errors/401.html.xhtml b/htdocs/htc/errors/401.html.xhtml new file mode 100644 index 0000000..f324679 --- /dev/null +++ b/htdocs/htc/errors/401.html.xhtml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + +HTTP 401 非請莫入 + + + + + + + +
+ +
+ + +

HTTP 401 非請莫入

+ +

很抱歉,本頁非請莫入,請回歷史:理論與文化首頁重新瀏覽。

+ +

若有任何問題,請來信告訴我們

+ +
+ +
+ + + + diff --git a/htdocs/htc/errors/403.html.html b/htdocs/htc/errors/403.html.html new file mode 120000 index 0000000..b668e83 --- /dev/null +++ b/htdocs/htc/errors/403.html.html @@ -0,0 +1 @@ +403.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/errors/403.html.xhtml b/htdocs/htc/errors/403.html.xhtml new file mode 100644 index 0000000..4d4e98a --- /dev/null +++ b/htdocs/htc/errors/403.html.xhtml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + +HTTP 403 禁止進入 + + + + + + + +
+ +
+ + +

HTTP 403 禁止進入

+ + + +

很抱歉,本頁禁止進入,請回歷史:理論與文化首頁重新瀏覽。

+ +

若有任何問題,請來信告訴我們

+ +
+ +
+ + + + diff --git a/htdocs/htc/errors/404.html.html b/htdocs/htc/errors/404.html.html new file mode 120000 index 0000000..4a7a8d7 --- /dev/null +++ b/htdocs/htc/errors/404.html.html @@ -0,0 +1 @@ +404.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/errors/404.html.xhtml b/htdocs/htc/errors/404.html.xhtml new file mode 100644 index 0000000..9332d7c --- /dev/null +++ b/htdocs/htc/errors/404.html.xhtml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + +HTTP 404 找不到網頁 + + + + + + + +
+ +
+ + +

HTTP 404 找不到網頁

+ +

很抱歉,找不到妳想連的那一頁。請檢查妳的網址是否有誤。若妳是由其它地方連上這裡,請來信告訴我們

+ +

妳可以回到歷史:理論與文化首頁重新瀏覽。

+ +
+ +
+ + + + diff --git a/htdocs/htc/errors/405.html.html b/htdocs/htc/errors/405.html.html new file mode 120000 index 0000000..5a1bc52 --- /dev/null +++ b/htdocs/htc/errors/405.html.html @@ -0,0 +1 @@ +405.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/errors/405.html.xhtml b/htdocs/htc/errors/405.html.xhtml new file mode 100644 index 0000000..1256d98 --- /dev/null +++ b/htdocs/htc/errors/405.html.xhtml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + +HTTP 405 要求方式無效 + + + + + + + +
+ +
+ + +

HTTP 405 要求方式無效

+ +

很抱歉,無法用這個方式連到此頁。請改用以下方式: $allowed 。

+ +

若有任何問題,請來信告訴我們

+ +
+ +
+ + + + diff --git a/htdocs/htc/errors/410.html.html b/htdocs/htc/errors/410.html.html new file mode 120000 index 0000000..a9dad98 --- /dev/null +++ b/htdocs/htc/errors/410.html.html @@ -0,0 +1 @@ +410.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/errors/410.html.xhtml b/htdocs/htc/errors/410.html.xhtml new file mode 100644 index 0000000..acea145 --- /dev/null +++ b/htdocs/htc/errors/410.html.xhtml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + +HTTP 410 已刪 + + + + + + + +
+ +
+ + +

HTTP 410 已刪

+ +

本頁內容已刪,造成不便請見諒。

+ +

妳可以回到歷史:理論與文化首頁重新瀏覽。

+ +
+ +
+ + + + diff --git a/htdocs/htc/errors/500.html.html b/htdocs/htc/errors/500.html.html new file mode 120000 index 0000000..628a797 --- /dev/null +++ b/htdocs/htc/errors/500.html.html @@ -0,0 +1 @@ +500.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/errors/500.html.xhtml b/htdocs/htc/errors/500.html.xhtml new file mode 100644 index 0000000..6668283 --- /dev/null +++ b/htdocs/htc/errors/500.html.xhtml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + +HTTP 500 網站執行錯誤 + + + + + + + +
+ +
+ + +

HTTP 500 網站執行錯誤

+ + + +

很抱歉,網站發生錯誤。這通常是 CGI 程式設計問題,請來信告訴我們

+ +

妳可以回到歷史:理論與文化首頁重新瀏覽。

+ +
+ +
+ + + + diff --git a/htdocs/htc/errors/503.html.html b/htdocs/htc/errors/503.html.html new file mode 120000 index 0000000..45a3b61 --- /dev/null +++ b/htdocs/htc/errors/503.html.html @@ -0,0 +1 @@ +503.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/errors/503.html.xhtml b/htdocs/htc/errors/503.html.xhtml new file mode 100644 index 0000000..e850b5f --- /dev/null +++ b/htdocs/htc/errors/503.html.xhtml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + +HTTP 503 網站暫停服務 + + + + + + + +
+ +
+ + +

HTTP 503 網站暫停服務

+ + + +

很抱歉,網站暫時停止服務。我們正在更新網站,大約要花一個小時左右。請晚點再來,謝謝。

+ +
+ +
+ + + + diff --git a/htdocs/htc/favicon.ico b/htdocs/htc/favicon.ico new file mode 100644 index 0000000..b0774be Binary files /dev/null and b/htdocs/htc/favicon.ico differ diff --git a/htdocs/htc/images/backgrnd.gif b/htdocs/htc/images/backgrnd.gif new file mode 100644 index 0000000..3163480 Binary files /dev/null and b/htdocs/htc/images/backgrnd.gif differ diff --git a/htdocs/htc/images/email.gif b/htdocs/htc/images/email.gif new file mode 100644 index 0000000..165ff04 Binary files /dev/null and b/htdocs/htc/images/email.gif differ diff --git a/htdocs/htc/images/email.png b/htdocs/htc/images/email.png new file mode 100644 index 0000000..965fdac Binary files /dev/null and b/htdocs/htc/images/email.png differ diff --git a/htdocs/htc/images/modperl.png b/htdocs/htc/images/modperl.png new file mode 100644 index 0000000..9c295b0 Binary files /dev/null and b/htdocs/htc/images/modperl.png differ diff --git a/htdocs/htc/images/nl0020201.gif b/htdocs/htc/images/nl0020201.gif new file mode 100644 index 0000000..fac78c0 Binary files /dev/null and b/htdocs/htc/images/nl0020201.gif differ diff --git a/htdocs/htc/images/nl0020202.gif b/htdocs/htc/images/nl0020202.gif new file mode 100644 index 0000000..fa05919 Binary files /dev/null and b/htdocs/htc/images/nl0020202.gif differ diff --git a/htdocs/htc/images/nl0020203.gif b/htdocs/htc/images/nl0020203.gif new file mode 100644 index 0000000..525f0eb Binary files /dev/null and b/htdocs/htc/images/nl0020203.gif differ diff --git a/htdocs/htc/images/nl0020204.gif b/htdocs/htc/images/nl0020204.gif new file mode 100644 index 0000000..944911b Binary files /dev/null and b/htdocs/htc/images/nl0020204.gif differ diff --git a/htdocs/htc/images/nl0020205.gif b/htdocs/htc/images/nl0020205.gif new file mode 100644 index 0000000..8429c93 Binary files /dev/null and b/htdocs/htc/images/nl0020205.gif differ diff --git a/htdocs/htc/images/nl0020206.gif b/htdocs/htc/images/nl0020206.gif new file mode 100644 index 0000000..7ae7750 Binary files /dev/null and b/htdocs/htc/images/nl0020206.gif differ diff --git a/htdocs/htc/images/nl0020207.gif b/htdocs/htc/images/nl0020207.gif new file mode 100644 index 0000000..d4c061e Binary files /dev/null and b/htdocs/htc/images/nl0020207.gif differ diff --git a/htdocs/htc/images/nl0020208.gif b/htdocs/htc/images/nl0020208.gif new file mode 100644 index 0000000..d744511 Binary files /dev/null and b/htdocs/htc/images/nl0020208.gif differ diff --git a/htdocs/htc/index.html.html b/htdocs/htc/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/htc/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/index.html.xhtml b/htdocs/htc/index.html.xhtml new file mode 100644 index 0000000..99de213 --- /dev/null +++ b/htdocs/htc/index.html.xhtml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + +歷史:理論與文化 + + + +
+

西洋史研究通訊-----

+

歷史:理論與文化

+ + +
+
+ +

發刊辭

+ +

荷蘭歷史學家赫伊津哈 (Johan Huizinga) 說道:對於歷史而言,問題永遠是:往何處去?過去二十年來,台灣西洋史學界偶有西洋史研究危機的呼聲。但這些零星的呼聲卻如入池的小石,激不起太大的波瀾。對於年輕的西洋史初學者而言,心中所懸念地是:下一步往何處去?在如此疑惑不安的情緒中,我們認為台灣的西洋史研究正處於一個深刻的危機狀態。危機,標識了一個過渡的階段;吾人將從中恢復過來,抑或是僵死過去,端視於我們如何去回應此一危機!

+ +

論者每謂台灣西洋史研究的危機在於基礎研究的欠缺。黃俊傑與邢義田先生早先在有關於研究西洋史應站在西洋史世界史立場的論辯時(一九八一),兩人皆同意基本研究的欠缺確是西洋史研究的重大難題;近來,楊肅獻先生回顧台灣的西洋史研究狀況時,此一現象仍未有多大地改變(一九九七)。

+ +

我們想指出:西洋史研究的危機不在於基礎研究的欠缺;而在於對此一危機性質的誤解!同時,這當中也關涉了對歷史學性質的不同見解。

+ +

無可諱言,基礎研究的欠缺確實是台灣西洋史學界所面臨的重大問題。史料的欠缺與文化的隔閡都加深了研究工作的困難,但是,這卻不應該是構成西洋史研究停滯不前的藉口。可以預見地,台灣的西洋史研究所面臨的限制與窘境不會有太大的改善。果若如此,則西洋史研究者豈不皆坐以待斃!

+ +

這誠然是一個消極的態度;我們可以更積極的態度來面對。這當中牽涉了我們對歷史學性質的一種新的理解。近年來人文科學界中的語言學轉向 (the linguistic turn) ,打破了人們對語言再現實在的透明性的信賴。語言並非一全然透明之物,單純地反映所接受的感覺與料;歷史的認知並非史家被動的接受、蒐集事實,它同時是史家心靈力量的展現。因此,在歷史研究中,事實的歸屬與綜合是同時進行地。

+ +

我們再次地強調:西洋史研究的基礎工作是必須的;但這並非西洋史研究開展的充要條件。西洋史研究工作的進行並非等待基礎研究完成後才能起步。所謂唯有待基礎研究工作完成後,我們才能對西洋史或世界史有屬於我們自己的理解的說法,這是十九世紀西方實證史學的說辭。實證史學假定只有當所有的證據都蒐集完成,才能作進一步的綜合工作。西洋史研究者對基礎研究不振的現象感到憂慮,從而猶豫不前,這樣的學風是受到中央研究院史語所傅斯年先生所謂史學即史料學的影響。令人惋惜地是,台灣的西洋史研究者並未以其對西方史學發展的了解,對此有所匡正,反受其遺毒所害,延擱了西洋史研究工作的進展。

+ +

因此,西洋史研究的危機與其說是基礎研究的欠缺,不如說是大部分的研究者誤解了此一危機的性質。換言之,危機的本身即是西洋史研究者以為危機存在於基礎研究的闕如。

+ +

但在此之下,尚隱藏了更深刻的危機,即歷史研究與現時的脫離。史學無法切合現代人的認知需求。相較於西方學術歷史化 (always historicise!) 的呼聲,台灣的歷史研究仍囿於它學科的門牆之內。它既缺乏對歷史學科本身的反省,亦即對歷史學在快速變動的社會中,它自身性質的轉變;同時也缺乏對現實的反省,亦即歷史學如何去回應現代社會的需求。

+ +

台灣歷史學界對於歷史理論向來缺乏深刻的反省。多數的學者以為對理論的偏好是望空為高,對實際研究缺乏正面的功能與效用。黃進興先生晚近的告白正是此種心態的反應(一九九二)。對黃進興而言,理論與方法論是屬於第二序 (second-order) 的語言,終究無法取代第一序 (first-order) 的實質研究。歷經早年對理論的酷愛,黃進興回歸到經典與史料本身。這種反理論的心態不僅使台灣史學界對歷史理論欠缺反省;同時,也無力肆應當今的後現代情境。

+ +

在歷經幾番躊蹴猶豫底自我懷疑與認同危機後,一群西洋史的初學者共同創造了一個台灣西洋史研究的園地。他們希望透過行動與理論的反省,回應西洋史研究所面臨的窘況,同時催生西洋史研究的蓬勃發展。

+ +

行動之首要,在於創造出一個公開從事學術討論的場域。我們認為,一個公開研究討論與知識交流的園地,是現代學術合法性的一個必要條件,其意義與宗教活動中的儀式並無二致。自去秋(一九九七)伊始,我們在輔仁大學歷史學研究所以歷史學與後現代歷史與文化等為題舉辦了一系列的討論會。希冀透過密集、多樣的小型討論會,提供一個西洋史研究的交流園地。

+ +

進一步,我們將出版一份屬於同仁刊物性質的研究通訊,將諸次討論會的內容化為文字,結集出刊;並提供近來西洋史研究的新動態。以此做為連繫、凝聚西洋史研究的同好,並供各方批評、指教的場所。此份通訊─《歷史:理論與文化》─即是彙聚多次討論會的成果。

+ +

展望未來,我們希望能建立一份屬於台灣西洋史研究者的專業期刊。

+ +

我們要再次地強調學術刊物所具有的公開討論與競技場之功能,是學術合法化與不斷進步的確證,也是本刊《歷史:理論與文化》所欲申張的宗旨。

+ +

在此,我們試擬幾個台灣西洋史學研究方向之芻議。如刊物的標題《歷史:理論與文化》所示,我們認為台灣的西洋史研究可以朝以下方向進行:歷史理論、史學史與文化史。這同時也表明了我們的立場,我們希望透過所揭櫫的西洋史研究綱領引導台灣歷史研究的走向。換言之,它所欲達成的不僅是台灣西洋史研究水準的提昇;同時,我們也希望西洋史工作者能對台灣的中國或本土歷史的研究有所獻替。藉著西方學術的引介,達成更新學術內容的目的。台灣的西洋史研究者所扮演的即是此種文化媒介的角色,這也是西洋史工作者的自我繪像、自我認同。

+ +

首先,我們強調歷史理論的重要性。史學總是不斷地反省著現時、反省著自身。台灣史學界對於當今所謂的後現代情境欠缺了解。今日,在西方所謂的後結構主義 (post-structuralism) 、解構 (deconstruction) 、修辭轉向 (rhetoric turn) 與視覺化理論 (visual theory) 對歷史學性質的反省起了重大的影響。在這一方面海登‧懷特 (Hayden White) 、安克斯密 (F. R. Ankersmit) 、梅驥 (Allan Megill) 、史帝芬‧班恩 (Stephen Bann) 等人的著作頗值得借鏡。

+ +

其次,是著重史學史的研究。在此,所謂的史學史不僅指涉對史家、史著、史學思想、觀念的研究;它同時意指對重要的歷史問題的歷史的研究,也就是所謂的學術史的研究。前者現有的成果已頗有可觀;後者則仍有待努力。

+ +

在新近重出於世的手稿中,柯靈烏 (R. G. Collingwood) 說道:對任何一個歷史問題的研究,首先須掌握的是這一個問題本身的歷史。透過史學史的認知,每一個專門的歷史專論或著作都與普遍史聯繫在一起。因此,西洋史研究中史料上的限制,或可以透過對每一個歷史問題的專門著作的掌握來解決。

+ +

我們的建議是:西洋史研究者應通力合作編輯相關的入門書與工具書,針對討論西洋史中的重大問題的相關著作作一番研究,彙編成冊,做為後學進一步研究的基礎。例如,有關文藝復興 (Renaissance) 、十七世紀的普遍危機 (the general crisis of seventeenth-century) 、法國大革命 (the French Revolution) …等的各家解釋。

+ +

近年來,文化史研究的盛行反應了史家反省自身在群眾社會中的位置。俗民文化成了頗受重視的研究主題。這反應了史家反省他們與下層群眾的關係。史家成為弱勢者的代言人,起著揭露權力如何壓迫、壓抑弱勢者的批判底功能。史家們同時也注意到社會各階層所具有的自主性。

+ +

二十世紀西方史學的發展歷經了世紀初對傳統以政治史為導向的歷史研究的反動後,在六十年代開啟了社會史經濟史的研究熱潮。新史學 (new histories) 在擺脫了大人物傳記寫作的同時,芸芸大眾並未從中獲得解放,反而陷入了結構的牢籠。活生生的個體為抽象的數字、統計圖表所掩蓋。個體的自由意志被無形、非人化的牢籠所圍囿。

+ +

現今的史家則注意到了下層群眾每個人的日常生活經驗。七十年代後出現的新文化史 (the new cultural history) 、日常生活史 (Alltagesgeschichte, history of everyday life) 代表了此一新的取向。這些新的研究取向注重歷史中具體、個別的個體經驗。階級 (class) 、性別 (gender) 、種族 (ethnicity) 成了歷史研究中重要的範疇;而婦女、少數民族及其他弱勢族群成了新興的研究主題。多元的觀點、聲音反映了後現代情境中多元化的現象,也符應多元文化 (multi-culture) 的趨向。

+ +

一九九七年秋,我們一群年輕的西洋史研究者從自我認同的危機出走,繪出台灣西洋史研究的新路徑。誠然,或許我們的思慮未臻周延、文字尚顯生澀,但因為年輕、因為滿懷的理想,我們衷心地期盼:所有的西洋史研究者能重拾自信與認同,扮好媒介者的角色,對台灣歷史研究的進展有所獻替,成為學術創新的源頭活水!

+ + +
+ + + + diff --git a/htdocs/htc/links/archives.html.html b/htdocs/htc/links/archives.html.html new file mode 120000 index 0000000..4cb5dcc --- /dev/null +++ b/htdocs/htc/links/archives.html.html @@ -0,0 +1 @@ +archives.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/links/archives.html.xhtml b/htdocs/htc/links/archives.html.xhtml new file mode 100644 index 0000000..b7c8f13 --- /dev/null +++ b/htdocs/htc/links/archives.html.xhtml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + +史料檔案 + + + + + + + +
+ +
+ + +

史料檔案

+ + + + + +
+ +
+ + + + diff --git a/htdocs/htc/links/index.html.html b/htdocs/htc/links/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/htc/links/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/links/index.html.xhtml b/htdocs/htc/links/index.html.xhtml new file mode 100644 index 0000000..d9171c2 --- /dev/null +++ b/htdocs/htc/links/index.html.xhtml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + +相關連結 + + + + + + + +
+ + + +
+ + + + diff --git a/htdocs/htc/links/institut.html.html b/htdocs/htc/links/institut.html.html new file mode 120000 index 0000000..f777056 --- /dev/null +++ b/htdocs/htc/links/institut.html.html @@ -0,0 +1 @@ +institut.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/links/institut.html.xhtml b/htdocs/htc/links/institut.html.xhtml new file mode 100644 index 0000000..11947be --- /dev/null +++ b/htdocs/htc/links/institut.html.xhtml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + +學術組織 + + + + + + + +
+ +
+ + +

學術組織

+ + + + + +
+ +
+ + + + diff --git a/htdocs/htc/links/journals.html.html b/htdocs/htc/links/journals.html.html new file mode 120000 index 0000000..e8f1da9 --- /dev/null +++ b/htdocs/htc/links/journals.html.html @@ -0,0 +1 @@ +journals.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/links/journals.html.xhtml b/htdocs/htc/links/journals.html.xhtml new file mode 100644 index 0000000..854259f --- /dev/null +++ b/htdocs/htc/links/journals.html.xhtml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + +期刊 + + + + + + + +
+ +
+ + +

期刊

+ + + + + +
+ +
+ + + + diff --git a/htdocs/htc/links/medicine.html.html b/htdocs/htc/links/medicine.html.html new file mode 120000 index 0000000..4734639 --- /dev/null +++ b/htdocs/htc/links/medicine.html.html @@ -0,0 +1 @@ +medicine.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/links/medicine.html.xhtml b/htdocs/htc/links/medicine.html.xhtml new file mode 100644 index 0000000..fa396a2 --- /dev/null +++ b/htdocs/htc/links/medicine.html.xhtml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + +醫學史 + + + + + + + +
+ +
+ + +

醫學史

+ + + + + +
+ +
+ + + + diff --git a/htdocs/htc/links/misc.html.html b/htdocs/htc/links/misc.html.html new file mode 120000 index 0000000..3cc0098 --- /dev/null +++ b/htdocs/htc/links/misc.html.html @@ -0,0 +1 @@ +misc.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/links/misc.html.xhtml b/htdocs/htc/links/misc.html.xhtml new file mode 100644 index 0000000..c6ed92f --- /dev/null +++ b/htdocs/htc/links/misc.html.xhtml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + +其它網站 + + + + + + + +
+ +
+ + +

其它網站

+ + + + + +
+ +
+ + + + diff --git a/htdocs/htc/links/scholars.html.html b/htdocs/htc/links/scholars.html.html new file mode 120000 index 0000000..5a71441 --- /dev/null +++ b/htdocs/htc/links/scholars.html.html @@ -0,0 +1 @@ +scholars.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/links/scholars.html.xhtml b/htdocs/htc/links/scholars.html.xhtml new file mode 100644 index 0000000..f6873b4 --- /dev/null +++ b/htdocs/htc/links/scholars.html.xhtml @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + +學者 + + + + + + + +
+ +
+ + +

學者

+ + + + + +
+ +
+ + + + diff --git a/htdocs/htc/links/sechand.html.html b/htdocs/htc/links/sechand.html.html new file mode 120000 index 0000000..a8bc9b0 --- /dev/null +++ b/htdocs/htc/links/sechand.html.html @@ -0,0 +1 @@ +sechand.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/links/sechand.html.xhtml b/htdocs/htc/links/sechand.html.xhtml new file mode 100644 index 0000000..b77d373 --- /dev/null +++ b/htdocs/htc/links/sechand.html.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + +二手書店 + + + + + + + +
+ +
+ + +

二手書店

+ + + + + +
+ +
+ + + + diff --git a/htdocs/htc/links/women.html.html b/htdocs/htc/links/women.html.html new file mode 120000 index 0000000..8c0ae53 --- /dev/null +++ b/htdocs/htc/links/women.html.html @@ -0,0 +1 @@ +women.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/links/women.html.xhtml b/htdocs/htc/links/women.html.xhtml new file mode 100644 index 0000000..feaf6df --- /dev/null +++ b/htdocs/htc/links/women.html.xhtml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + +婦女史 + + + + + + + +
+ +
+ + +

婦女史

+ + + + + +
+ +
+ + + + diff --git a/htdocs/htc/magicat/cgi-bin/actlog.cgi b/htdocs/htc/magicat/cgi-bin/actlog.cgi new file mode 100755 index 0000000..a2ca9ff --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/actlog.cgi @@ -0,0 +1,51 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# actlog.cgi: The activity log viewer. + +# Copyright (c) 2005-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-05-10 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); + +initenv(-restricted => 1, + -allowed => [qw(GET HEAD)], + -lastmod => 0, + -lmfiles => [$ACTLOG], + -page_param => {"keywords" => N_("activity, logs")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $LIST; + # List handler handles its own error + $LIST = new Selima::List::ActLog; + html_header $LIST->{"title"}; + html_errmsg retrieve_status; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/htc/magicat/cgi-bin/groupmem.cgi b/htdocs/htc/magicat/cgi-bin/groupmem.cgi new file mode 100755 index 0000000..699b378 --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/groupmem.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# groupmem.cgi: The group-to-group membership administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); +sub import_selmember($); + +initenv(-restricted => 1, + -this_table => "groupmem", + -dbi_lock => {"groupmem" => LOCK_EX, + "groups" => LOCK_SH, + "groups AS grpmembers" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("group membership")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::GroupMem($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(del selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::GroupMem($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::GroupMem; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the membership record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This membership record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} + +# import_selmember: Import the selected member into the retrieved form +sub import_selmember($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("member", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups AS grpmembers"; + return $FORM; +} diff --git a/htdocs/htc/magicat/cgi-bin/groups.cgi b/htdocs/htc/magicat/cgi-bin/groups.cgi new file mode 100755 index 0000000..608a115 --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/groups.cgi @@ -0,0 +1,357 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# groups.cgi: The account group administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selsubuser($); +sub import_selsubgroup($); +sub import_selsupgroup($); + +initenv(-restricted => 1, + -this_table => "groups", + -dbi_lock => {"groups" => LOCK_EX, + "usermem" => LOCK_EX, + "groupmem" => LOCK_EX, + "users" => LOCK_SH, + "users AS members" => LOCK_SH, + "groups AS members" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("groups")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Group($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my ($error, $FORM, $sn); + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth if !is_su && $sn == su_group_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error, $FORM, $sn); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(selsubuser selsubgroup selsupgroup)); + $error = $checker->check(qw(id dsc subuser subgroup supgroup)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(del selsubuser selsubgroup selsupgroup)); + $error = $checker->check(qw(id dsc subuser subgroup supgroup)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth if !is_su && $sn == su_group_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::Group($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Groups; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the group."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This group does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the user members list + $title = $DBH->strcat("users.id", "' ('", "users.name", "')'"); + $sql = "SELECT users.sn AS sn," + . " $title AS title" + . " FROM usermem" + . " INNER JOIN users ON usermem.member=users.sn" + . " WHERE usermem.grp=$sn" + . " ORDER BY users.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"subusercount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"subusercount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"subuser$_"} = 1; + $CURRENT{"subuser$_" . "sn"} = $$row{"sn"}; + $CURRENT{"subuser$_" . "title"} = $$row{"title"}; + } + + # Obtain the group members list + $sql = "SELECT groups.sn AS sn," + . " groups.dsc AS title FROM groupmem" + . " INNER JOIN groups ON groupmem.member=groups.sn" + . " WHERE groupmem.grp=$sn" + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"subgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"subgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"subgroup$_"} = 1; + $CURRENT{"subgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"subgroup$_" . "title"} = $$row{"title"}; + } + + # Obtain the belonging groups list + $sql = "SELECT groups.sn AS sn," + . " groups.dsc AS title FROM groupmem" + . " INNER JOIN groups ON groupmem.grp=groups.sn" + . " WHERE groupmem.member=$sn" + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"supgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"supgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"supgroup$_"} = 1; + $CURRENT{"supgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"supgroup$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} + +# import_selsubuser: Import the selected user into the retrieved form +sub import_selsubuser($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users AS members") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^subuser\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { userid $a cmp userid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^subuser\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^subuser\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("subuser$_" . "sn", $_[$_]); + $FORM->param("subuser$_", 1) if exists $_{$_[$_]}; + } + } + return; +} + +# import_selsubgroup: Import the selected user into the retrieved form +sub import_selsubgroup($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups AS members") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^subgroup\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { groupid $a cmp groupid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^subgroup\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^subgroup\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("subgroup$_" . "sn", $_[$_]); + $FORM->param("subgroup$_", 1) if exists $_{$_[$_]}; + } + } + return; +} + +# import_selsupgroup: Import the selected user into the retrieved form +sub import_selsupgroup($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^supgroup\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { groupid $a cmp groupid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^supgroup\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^supgroup\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("supgroup$_" . "sn", $_[$_]); + $FORM->param("supgroup$_", 1) if exists $_{$_[$_]}; + } + } + return; +} diff --git a/htdocs/htc/magicat/cgi-bin/guestbook.cgi b/htdocs/htc/magicat/cgi-bin/guestbook.cgi new file mode 100755 index 0000000..c4ea59c --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/guestbook.cgi @@ -0,0 +1,211 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# guestbook.cgi: The guestbook administration. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-06 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "guestbook", + -dbi_lock => {"guestbook" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("guestbook")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Guestbook($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::htc::Checker::Guestbook(curform); + $error = $checker->check(qw(name identity location + email url message)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::htc::Checker::Guestbook(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(name identity location + email url message)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::htc::Checker::Guestbook(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::htc::Form::Guestbook($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::htc::List::Guestbook; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the message."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This message does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/htc/magicat/cgi-bin/linkcat.cgi b/htdocs/htc/magicat/cgi-bin/linkcat.cgi new file mode 100755 index 0000000..461ef2d --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/linkcat.cgi @@ -0,0 +1,292 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# linkcat.cgi: The related-link category administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selparent($); + +initenv(-restricted => 1, + -this_table => "linkcat", + -dbi_lock => {"linkcat" => LOCK_EX, + "links" => LOCK_SH, + "linkcatz" => LOCK_SH}, + -lastmod => 0, + -page_param => {"keywords" => N_("link categories")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LinkCat($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + return {"msg"=>N_("This category has [numerate,_1,a subcategory,subcategories]. It cannot be deleted. To delete the category, [numerate,_1,its subcategory,all of its subcategories] must first be deleted."), + "margs"=>[$CURRENT{"scatcount"}], + "isform"=>0} + if $CURRENT{"scatcount"} > 0; + return {"msg"=>N_("This category has [numerate,_1,a link,links]. It cannot be deleted. To delete the category, [numerate,_1,its link,all of its links] must first be deleted."), + "margs"=>[$CURRENT{"linkcount"}], + "isform"=>0} + if $CURRENT{"linkcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(selparent delparent)); + $error = $checker->check(qw(parent id ord title kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(del selparent delparent)); + $error = $checker->check(qw(parent id ord title kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(cancel)); + return {"msg"=>N_("This category has [numerate,_1,a subcategory,subcategories]. It cannot be deleted. To delete the category, [numerate,_1,its subcategory,all of its subcategories] must first be deleted."), + "margs"=>[$CURRENT{"scatcount"}], + "isform"=>0} + if $CURRENT{"scatcount"} > 0; + return {"msg"=>N_("This category has [numerate,_1,a link,links]. It cannot be deleted. To delete the category, [numerate,_1,its link,all of its links] must first be deleted."), + "margs"=>[$CURRENT{"linkcount"}], + "isform"=>0} + if $CURRENT{"linkcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::LinkCat($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::LinkCat; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lang, $lndb, $lndbdef, $langfile, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the category."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This category does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $lang = getlang; + $lndb = getlang LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + $langfile = getlang LN_FILENAME; + + # Obtain the belonging subcategories list + @_ = qw(); + push @_, "sn AS sn"; + if (@ALL_LINGUAS > 1) { + $title = $lang eq $DEFAULT_LANG? "title_$lndb": + "COALESCE(title_$lndb, title_$lndbdef)"; + push @_, "linkcat_fulltitle('$lang', parent, $title) AS title"; + } else { + push @_, "linkcat_fulltitle(parent, title) AS title"; + } + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS url"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_ischild($sn, sn)" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"scatcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"scatcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"scat$_" . "sn"} = $$row{"sn"}; + $CURRENT{"scat$_" . "title"} = $$row{"title"}; + $CURRENT{"scat$_" . "url"} = $$row{"url"}; + } + + # Obtain the belonging links list + @_ = qw(); + push @_, "links.sn AS sn"; + push @_, "links.title AS title"; + push @_, "url AS url"; + $sql = "SELECT " . join(", ", @_) . " FROM links" + . " INNER JOIN linkcatz ON linkcatz.link=links.sn" + . " WHERE linkcatz.cat=$sn" + . " ORDER BY title;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"linkcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"linkcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"link$_" . "sn"} = $$row{"sn"}; + $CURRENT{"link$_" . "title"} = $$row{"title"}; + $CURRENT{"link$_" . "url"} = $$row{"url"}; + } + + # OK + return; +} + +# import_selparent: Import the selected parent into the retrieved form +sub import_selparent($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "linkcat") { + $FORM->param("parent", $GET->param("selsn")); + $FORM->param("topmost", "false"); + } + return; +} diff --git a/htdocs/htc/magicat/cgi-bin/linkcatz.cgi b/htdocs/htc/magicat/cgi-bin/linkcatz.cgi new file mode 100755 index 0000000..13d9354 --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/linkcatz.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# linkcatz.cgi: The related-link category membership administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selcat($); +sub import_sellink($); + +initenv(-restricted => 1, + -this_table => "linkcatz", + -dbi_lock => {"linkcatz" => LOCK_EX, + "linkcat" => LOCK_SH, + "links" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("link categorization")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LinkCatz($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(selcat delcat sellink dellink)); + $error = $checker->check(qw(cat link)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(del selcat delcat sellink dellink)); + $error = $checker->check(qw(cat link)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::LinkCatz($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::LinkCatz; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the categorization record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This categorization record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selcat: Import the selected category into the retrieved form +sub import_selcat($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("cat", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "linkcat"; + return; +} + +# import_sellink: Import the selected link into the retrieved form +sub import_sellink($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("link", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "links"; + return $FORM; +} diff --git a/htdocs/htc/magicat/cgi-bin/links.cgi b/htdocs/htc/magicat/cgi-bin/links.cgi new file mode 100755 index 0000000..10bb96f --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/links.cgi @@ -0,0 +1,240 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# links.cgi: The related-link administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "links", + -dbi_lock => {"links" => LOCK_EX, + "linkcatz" => LOCK_EX, + "linkcat" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("related links")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Link($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::Link(curform); + $error = $checker->check(qw(title title_2ln url icon + email addr tel fax dsc cats)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Link(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(title title_2ln url icon + email addr tel fax dsc cats)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::Link(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::Link($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Links; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lang, $lndb, $lndbdef, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the related link."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This related link does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $lang = getlang; + $lndb = getlang LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + + # Obtain the parent categories list + @_ = qw(); + push @_, "linkcat.sn AS sn"; + if (@ALL_LINGUAS > 1) { + $title = $lang eq $DEFAULT_LANG? "linkcat.title_$lndb": + "COALESCE(linkcat.title_$lndb, linkcat.title_$lndbdef)"; + push @_, "linkcat_fulltitle('$lang', linkcat.parent, $title) AS title"; + } else { + push @_, "linkcat_fulltitle(linkcat.parent, linkcat.title) AS title"; + } + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " INNER JOIN linkcatz ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.link=$sn" + . " ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord);\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"catcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"catcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"cat$_"} = $$row{"sn"}; + $CURRENT{"cat$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} diff --git a/htdocs/htc/magicat/cgi-bin/logout.cgi b/htdocs/htc/magicat/cgi-bin/logout.cgi new file mode 100755 index 0000000..5c590bb --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/logout.cgi @@ -0,0 +1,158 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# logout.cgi: The log-out script. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub html_logoutform(); +sub html_relogin(); + +initenv(-dbi => DBI_NONE, + -lastmod => 1, + -page_param => {"keywords" => N_("log out")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LogOut($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $status; + # There is a result to display + $status = retrieve_status; + # Successfully logged out + if ( defined $status + && exists $$status{"status"} + && $$status{"status"} eq "success") { + # Nothing to check + return; + } + # Check if this user has logged in + unauth unless defined get_login_sn; + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + # Check if this user has logged in + unauth unless defined get_login_sn; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my $status; + $status = $_[0]; + # Not logged out yet + if (defined get_login_sn) { + html_header __("Log Out"); + html_errmsg $status; + html_logoutform; + html_footer; + + # Logged out + } else { + html_header __("Log Out"); + html_errmsg $status; + html_relogin; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# html_logoutform: Display a form to log out +sub html_logoutform() { + local ($_, %_); + my ($msg, $submit); + $msg = h(__("Are you sure you want to log out?")); + $submit = h(__("Log out")); + print << "EOT"; +
+
+

$msg

+ +
+
+ +EOT + return; +} + +# html_relogin: Display links to log in again +sub html_relogin() { + local ($_, %_); + $_ = h(__("Log in again.")); + print << "EOT"; +

$_

+ +EOT + return; +} diff --git a/htdocs/htc/magicat/cgi-bin/newslets.cgi b/htdocs/htc/magicat/cgi-bin/newslets.cgi new file mode 100755 index 0000000..c2493a5 --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/newslets.cgi @@ -0,0 +1,345 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# newslets.cgi: The newsletter administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-28 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub fetch_index($$$); + +use Date::Parse qw(str2time); + +initenv(-restricted => 1, + -this_table => "newslets", + -dbi_lock => {"newslets" => LOCK_EX, + "nlindex" => LOCK_EX, + "nlarts" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("newsletters")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::htc::Processor::Newslet($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to preview a submitted item + } elsif ($_ eq "preview") { + my ($sql, $sth, $count, $row, @allno); + # Check at fetch_preview() + $error = fetch_preview; + return $error if defined $error; + $PREVIEW{"path"} = sprintf "/newsletters/%03d/", $PREVIEW{"no"}; + $PREVIEW{"date"} = str2time $PREVIEW{"date"}; + $PREVIEW{"title"} = newslet_textno($PREVIEW{"no"}) . " " . $PREVIEW{"title"}; + + # Obtain all the pages + @_ = qw(); + push @_, "sn!=" . $PREVIEW{"sn"} if exists $PREVIEW{"sn"}; + push @_, "NOT hid"; + $sql = "SELECT no FROM newslets" + . " WHERE " . join(" AND ", @_) + . " ORDER BY no;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @allno = qw(); $i < $count; $i++) { + push @allno, ${$sth->fetch}[0]; + } + undef $sth; + # Insert this page + for ($_ = 0; $_ < @allno; $_++) { + last if $PREVIEW{"no"} < $allno[$_]; + } + @allno = ( + @allno[0..$_-1], + $PREVIEW{"no"}, + @allno[$_..$#allno]); + $PREVIEW{"allno"} = [@allno]; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::htc::Checker::Newslet(curform); + $checker->redir(qw(selndxart delndxart)); + $error = $checker->check(qw(no date title credits kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::htc::Checker::Newslet(curform); + $checker->redir(qw(del selndxart delndxart)); + $error = $checker->check(qw(no date title credits kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::htc::Checker::Newslet(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + # A form to preview a submitted item + if (form_type eq "preview") { + html_preview; + + } else { + $FORM = new Selima::htc::Form::Newslet($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + } + + # List the available items + } else { + $LIST = new Selima::htc::List::Newslets; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the newsletter."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This newsletter does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the date + $CURRENT{"date"} = fmtdate $CURRENT{"date"}; + + # Obtain the belonging index items list + @_ = qw(); + push @_, "sn AS sn"; + push @_, "art AS art"; + push @_, "title AS title"; + $sql = "SELECT " . join(", ", @_) . " FROM nlindex" + . " WHERE newslet=$sn" + . " AND parent IS NULL" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"ndxcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"ndxcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"ndx$_"} = 1; + $CURRENT{"ndx$_" . "sn"} = $$row{"sn"}; + $CURRENT{"ndx$_" . "art"} = $$row{"art"}; + $CURRENT{"ndx$_" . "title"} = $$row{"title"}; + } + for ($_ = 0; $_ < $CURRENT{"ndxcount"}; $_++) { + fetch_index $sn, $CURRENT{"ndx$_" . "sn"}, "ndx$_" . "sub"; + } + + # Obtain the belonging articles list + @_ = qw(); + push @_, "sn AS sn"; + push @_, "title AS title"; + $sql = "SELECT " . join(", ", @_) . " FROM nlarts" + . " WHERE newslet=$sn" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"artcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"artcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"art$_" . "sn"} = $$row{"sn"}; + $CURRENT{"art$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} + +# fetch_index: Fetch the index of the current item +sub fetch_index($$$) { + local ($_, %_); + my ($sn, $parent, $prefix, $sql, $sth, $count, $row); + ($sn, $parent, $prefix) = @_; + + # Find the items + @_ = qw(); + push @_, "sn AS sn"; + push @_, "art AS art"; + push @_, "title AS title"; + $sql = "SELECT " . join(", ", @_) . " FROM nlindex" + . " WHERE newslet=$sn" + . " AND parent=$parent" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + return if $count == 0; + $CURRENT{$prefix} = 1; + $CURRENT{$prefix . "count"} = $count; + for ($_ = 0; $_ < $CURRENT{$prefix . "count"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"$prefix$_"} = 1; + $CURRENT{"$prefix$_" . "sn"} = $$row{"sn"}; + $CURRENT{"$prefix$_" . "art"} = $$row{"art"}; + $CURRENT{"$prefix$_" . "title"} = $$row{"title"}; + } + undef $sth; + + # Find the subitems + for ($_ = 0; $_ < $CURRENT{$prefix . "count"}; $_++) { + fetch_index $sn, $CURRENT{"$prefix$_" . "sn"}, "$prefix$_" . "sub"; + } + return; +} + +# import_selndxart: Import the selected index item article into the retrieved form +sub import_selndxart($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param($FORM->param("caller_index"), $GET->param("selsn")) + if defined $FORM->param("caller_index") + && defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "nlarts"; + return; +} diff --git a/htdocs/htc/magicat/cgi-bin/nlarts.cgi b/htdocs/htc/magicat/cgi-bin/nlarts.cgi new file mode 100755 index 0000000..cb95135 --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/nlarts.cgi @@ -0,0 +1,226 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# nlarts.cgi: The newsletter article administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-30 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selparent($); + +initenv(-restricted => 1, + -this_table => "nlarts", + -dbi_lock => {"nlarts" => LOCK_EX, + "newslets" => LOCK_SH, + "nlindex" => LOCK_SH}, + -lastmod => 0, + -page_param => {"keywords" => N_("newsletter articles")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::htc::Processor::NLArt($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::htc::Checker::NLArt(curform); + $checker->redir(qw(selnewslet delnewslet)); + $error = $checker->check(qw(newslet ord title title_h author + email authors body annots kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::htc::Checker::NLArt(curform); + $checker->redir(qw(del selnewslet delnewslet)); + $error = $checker->check(qw(newslet ord title title_h author + email authors body annots kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::htc::Checker::NLArt(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::htc::Form::NLArt($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::htc::List::NLArts; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the article."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This article does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selnewslet: Import the selected newsletter into the retrieved form +sub import_selnewslet($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("newslet", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "newslets"; + return; +} diff --git a/htdocs/htc/magicat/cgi-bin/nlindex.cgi b/htdocs/htc/magicat/cgi-bin/nlindex.cgi new file mode 100755 index 0000000..7651f2d --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/nlindex.cgi @@ -0,0 +1,273 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# nlindex.cgi: The newsletter index administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selparent($); + +initenv(-restricted => 1, + -this_table => "nlindex", + -dbi_lock => {"nlindex" => LOCK_EX, + "newslets" => LOCK_SH, + "nlarts" => LOCK_SH}, + -lastmod => 0, + -page_param => {"keywords" => N_("newsletter indices")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::htc::Processor::NLIndex($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + return {"msg"=>N_("This index item has [numerate,_1,a subitem,subitems]. It cannot be deleted. To delete the index item, [numerate,_1,its subitem,all of its subitems] must first be deleted."), + "margs"=>[$CURRENT{"subitemcount"}], + "isform"=>0} + if $CURRENT{"subitemcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::htc::Checker::NLIndex(curform); + $checker->redir(qw(selnewslet delnewslet selparent delparent selart delart)); + $error = $checker->check(qw(newslet parent ord art title)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::htc::Checker::NLIndex(curform); + $checker->redir(qw(del selnewslet delnewslet selparent delparent selart delart)); + $error = $checker->check(qw(newslet parent ord art title)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::htc::Checker::NLIndex(curform); + $checker->redir(qw(cancel)); + return {"msg"=>N_("This index item has [numerate,_1,a subitem,subitems]. It cannot be deleted. To delete the index item, [numerate,_1,its subitem,all of its subitems] must first be deleted."), + "margs"=>[$CURRENT{"subitemcount"}], + "isform"=>0} + if $CURRENT{"subitemcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::htc::Form::NLIndex($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::htc::List::NLIndex; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the index item."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This index item does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging subitems list + @_ = qw(); + push @_, "nlindex.sn AS sn"; + push @_, "nlindex_fulltitle(parent, COALESCE(nlindex.title, nlarts.title)) AS title"; + $sql = "SELECT " . join(", ", @_) . " FROM nlindex" + . " LEFT JOIN nlarts ON nlindex.art=nlarts.sn" + . " WHERE nlindex_ischild($sn, nlindex.sn)" + . " ORDER BY nlindex_fullord(nlindex.parent, nlindex.ord);\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"subitemcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"subitemcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"subitem$_" . "sn"} = $$row{"sn"}; + $CURRENT{"subitem$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} + +# import_selnewslet: Import the selected newsletter into the retrieved form +sub import_selnewslet($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("newslet", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "newslets"; + return; +} + +# import_selparent: Import the selected parent into the retrieved form +sub import_selparent($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "nlindex") { + $FORM->param("parent", $GET->param("selsn")); + $FORM->param("topmost", "false"); + } + return; +} + +# import_selart: Import the selected article into the retrieved form +sub import_selart($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("art", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "nlarts"; + return; +} diff --git a/htdocs/htc/magicat/cgi-bin/pages.cgi b/htdocs/htc/magicat/cgi-bin/pages.cgi new file mode 100755 index 0000000..d8f1667 --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/pages.cgi @@ -0,0 +1,221 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# pages.cgi: The web page administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-03 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "pages", + -dbi_lock => {"pages" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("pages")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Page($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to preview a submitted item + } elsif ($_ eq "preview") { + # Check at fetch_preview() + $error = fetch_preview; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::Page(curform); + $error = $checker->check(qw(path ord title body kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Page(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(path ord title body kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::Page(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + # A form to preview a submitted item + if (form_type eq "preview") { + html_preview; + + } else { + $FORM = new Selima::Form::Page($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + } + + # List the available items + } else { + $LIST = new Selima::List::Pages; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the page."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This page does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/htc/magicat/cgi-bin/rebuild.cgi b/htdocs/htc/magicat/cgi-bin/rebuild.cgi new file mode 100755 index 0000000..62acc52 --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/rebuild.cgi @@ -0,0 +1,105 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# rebuild.cgi: The web page rebuilder. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-04 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); + +initenv(-restricted => 1, + -lastmod => 1, + -page_param => {"keywords" => N_("rebuild pages")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Rebuild($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + # Nothing to check here + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::Checker::Rebuild(curform); + $error = $checker->check(qw(type)); + return $error if defined $error; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $FORM); + $status = $_[0]; + $FORM = new Selima::Form::Rebuild($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + return; +} diff --git a/htdocs/htc/magicat/cgi-bin/scptpriv.cgi b/htdocs/htc/magicat/cgi-bin/scptpriv.cgi new file mode 100755 index 0000000..eb582fc --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/scptpriv.cgi @@ -0,0 +1,223 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# scptpriv.cgi: The script privilege administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); + +initenv(-restricted => 1, + -this_table => "scptpriv", + -dbi_lock => {"scptpriv" => LOCK_EX, + "groups" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("script privilege")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::ScptPriv($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(selgrp delgrp)); + $error = $checker->check(qw(script grp)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(del selgrp delgrp)); + $error = $checker->check(qw(script grp)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::ScptPriv($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::ScptPriv; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the script privilege record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This script privilege record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} diff --git a/htdocs/htc/magicat/cgi-bin/test.cgi b/htdocs/htc/magicat/cgi-bin/test.cgi new file mode 100755 index 0000000..520792c --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/test.cgi @@ -0,0 +1,40 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# test.cgi: The test script. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +use 5.008; +use utf8; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $r = shift; +my $d = new Selima::Destroy; +# Prototype declaration +use Time::HiRes qw(); +initenv; +$CONTENT_TYPE = "text/plain"; + + +printf "[%s] Done. %0.10f seconds elapsed.\n", + fmttime, Time::HiRes::time-$T_START; +exit 0; +no utf8; diff --git a/htdocs/htc/magicat/cgi-bin/usermem.cgi b/htdocs/htc/magicat/cgi-bin/usermem.cgi new file mode 100755 index 0000000..09e77ec --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/usermem.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# usermem.cgi: The user-to-group membership administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); +sub import_selmember($); + +initenv(-restricted => 1, + -this_table => "usermem", + -dbi_lock => {"usermem" => LOCK_EX, + "groups" => LOCK_SH, + "users AS usrmembers" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("user membership")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::UserMem($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(del selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::UserMem($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::UserMem; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the membership record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This membership record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} + +# import_selmember: Import the selected user into the retrieved form +sub import_selmember($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("member", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users AS usrmembers"; + return $FORM; +} diff --git a/htdocs/htc/magicat/cgi-bin/userpref.cgi b/htdocs/htc/magicat/cgi-bin/userpref.cgi new file mode 100755 index 0000000..5fd0941 --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/userpref.cgi @@ -0,0 +1,225 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# userpref.cgi: The user preference administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selusr($); + +initenv(-restricted => 1, + -this_table => "userpref", + -dbi_lock => {"userpref" => LOCK_EX, + "users" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("user preference")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::UserPref($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(selusr delusr)); + $error = $checker->check(qw(usr domain name value)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(del selusr delusr)); + $error = $checker->check(qw(usr domain name value)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::UserPref($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::UserPref; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the user preference."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This user preference does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selusr: Import the selected user into the retrieved form +sub import_selusr($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users") { + $FORM->param("usr", $GET->param("selsn")); + $FORM->param("everyone", "false"); + } + return; +} diff --git a/htdocs/htc/magicat/cgi-bin/users.cgi b/htdocs/htc/magicat/cgi-bin/users.cgi new file mode 100755 index 0000000..2dedb95 --- /dev/null +++ b/htdocs/htc/magicat/cgi-bin/users.cgi @@ -0,0 +1,273 @@ +#! /usr/bin/perl -w +# History: Theory and Culture +# users.cgi: The user account administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::htc; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-this_table => "users", + -dbi_lock => {"users" => LOCK_EX, + "usermem" => LOCK_EX, + "userpref" => LOCK_EX, + "groupmem" => LOCK_SH, + "groups" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("users")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + # Password not saved + $POST->delete("passwd", "passwd2"); + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::User($POST); + $success = $processor->process; + # Password not saved + $POST->delete("passwd", "passwd2"); + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my ($error, $FORM, $sn); + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Check the privilege to manage this table + unauth if !is_script_permitted; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted || $sn == get_login_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted; + unauth if !is_su && (is_su $sn || $sn == get_login_sn); + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + + # List the available items + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + # List handler handles its own error + } + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error, $FORM, $sn); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Check the privilege to manage this table + unauth unless is_script_permitted; + # Run the checker + $checker = new Selima::Checker::User(curform); + $error = $checker->check(qw(id passwd name supgroup)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted || $sn == get_login_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::User(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(id passwd name supgroup)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted; + unauth if !is_su && (is_su $sn || $sn == get_login_sn); + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::User(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::User($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Users; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the user."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This user does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging groups list + $sql = "SELECT groups.sn AS sn," + . " groups.dsc AS title FROM usermem" + . " INNER JOIN groups ON usermem.grp=groups.sn" + . " WHERE usermem.member=$sn" + . " AND groups.id!=" . $DBH->quote(SU_GROUP) + . " AND groups.id!=" . $DBH->quote(ADMIN_GROUP) + . " AND groups.id!=" . $DBH->quote(ALLUSERS_GROUP) + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"supgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"supgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"supgroup$_"} = 1; + $CURRENT{"supgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"supgroup$_" . "title"} = $$row{"title"}; + } + + # Get the admin flag + $CURRENT{"admin"} = is_admin($sn); + $CURRENT{"su"} = is_su($sn); + + # OK + return; +} diff --git a/htdocs/htc/magicat/data/counter.dat b/htdocs/htc/magicat/data/counter.dat new file mode 100644 index 0000000..0b1b6bb --- /dev/null +++ b/htdocs/htc/magicat/data/counter.dat @@ -0,0 +1 @@ +86476 \ No newline at end of file diff --git a/htdocs/htc/magicat/include/footer.html b/htdocs/htc/magicat/include/footer.html new file mode 100644 index 0000000..da45a85 --- /dev/null +++ b/htdocs/htc/magicat/include/footer.html @@ -0,0 +1,31 @@ +
+ diff --git a/htdocs/htc/magicat/include/header.html b/htdocs/htc/magicat/include/header.html new file mode 100644 index 0000000..9375674 --- /dev/null +++ b/htdocs/htc/magicat/include/header.html @@ -0,0 +1,9 @@ + diff --git a/htdocs/htc/magicat/index.html.html b/htdocs/htc/magicat/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/htc/magicat/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/magicat/index.html.xhtml b/htdocs/htc/magicat/index.html.xhtml new file mode 100644 index 0000000..bbdafc2 --- /dev/null +++ b/htdocs/htc/magicat/index.html.xhtml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + +梅姬妳好 *^_^* + + + + + + + +
+ +
+ + +

我是梅姬,請多多指教 *^_^*

+ +
訪客計數器 訪客計數器
+ +
+

妳好,我是梅姬,是歷史:理論與文化網站的守護精靈。妳要怎麼設定網站,請儘管吩咐我喔~!

+
+ +

管理網站

+ + + +

管理帳號

+ + + +

其她

+ + + +
+ + +
+ + + + diff --git a/htdocs/htc/magicat/lib/htc.sql b/htdocs/htc/magicat/lib/htc.sql new file mode 100644 index 0000000..c21cb5f --- /dev/null +++ b/htdocs/htc/magicat/lib/htc.sql @@ -0,0 +1,1208 @@ +-- 檔案名稱: htc.sql +-- 程式說明: 歷史:理論與文化資料庫定義檔 +-- 程式作者: 依瑪貓 imacat +-- 初稿日期: 2004-10-16 +-- 版權字樣: 版權所有 (c) 2004-2012 依瑪貓 + +SET NAMES 'big5'; + +START TRANSACTION; + + +-- +-- Table structure for table "mtime" +-- + +CREATE TABLE mtime ( + tabname varchar(16) NOT NULL PRIMARY KEY, + mtime timestamp NOT NULL DEFAULT now() +); +GRANT SELECT, INSERT, UPDATE, DELETE ON mtime TO nobody; + + +-- +-- Function definition for function "eschtml" +-- +-- integer eschtml(source text) +CREATE FUNCTION eschtml(source text) RETURNS text AS ' + DECLARE + result text; + BEGIN + result := source; + result := replace(result, ''&'', ''&''); + result := replace(result, ''<'', ''<''); + result := replace(result, ''>'', ''>''); + result := replace(result, ''"'', ''"''); + return result; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION eschtml(source text) TO nobody; + + +-- +-- Table structure for table "country" +-- + +CREATE TABLE country ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id char(2) NOT NULL UNIQUE CHECK (position(' ' in id) = 0), + name_en varchar(64) NOT NULL CHECK (name_en != ''), + name_zhtw varchar(32) CHECK (name_zhtw IS NULL OR name_zhtw != ''), + special boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL +); +GRANT SELECT, INSERT, UPDATE, DELETE ON country TO nobody; + + +-- +-- Table structure for table "users" +-- + +CREATE TABLE users ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(32) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + passwd char(32) NOT NULL, + name varchar(32) NOT NULL CHECK (name != ''), + disabled boolean NOT NULL DEFAULT FALSE, + deleted boolean NOT NULL DEFAULT FALSE, + lang varchar(5) CHECK (lang IS NULL OR lang != ''), + visits smallint NOT NULL DEFAULT 0 CHECK (visits >= 0), + visited timestamp, + ip inet, + host varchar(128), + ct char(2) REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON users TO nobody; + +CREATE VIEW users_list AS + SELECT + users.sn AS sn, + users.id AS id, + users.name AS name, + CASE WHEN users.disabled THEN '停用' + ELSE '' + END AS disabled, + CASE WHEN users.deleted THEN '已刪' + ELSE '' + END AS deleted, + CASE WHEN users.lang IS NULL THEN '(無)' + ELSE CASE users.lang + WHEN 'en' THEN '英文' + WHEN 'zh-tw' THEN '繁體中文' + WHEN 'zh-cn' THEN '簡體中文' + WHEN 'ja' THEN '日文' + WHEN 'de' THEN '德文' + WHEN 'es' THEN '西班牙文' + ELSE users.lang + END + END AS lang, + users.visits AS visits, + CASE WHEN users.visited IS NULL THEN '(無)' + ELSE to_char(users.visited, 'YYYY-MM-DD HH:MI:SS') + END AS visited, + CASE WHEN users.ip IS NULL THEN '(無)' + ELSE host(users.ip) + END AS ip, + CASE WHEN users.host IS NULL THEN '(無)' + ELSE users.host + END AS host, + CASE WHEN users.ct IS NULL THEN '(無)' + ELSE ct.name_zhtw + END AS ct, + to_char(users.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(users.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM users + LEFT JOIN country AS ct ON users.ct = ct.id + LEFT JOIN users AS createdby ON users.createdby = createdby.sn + LEFT JOIN users AS updatedby ON users.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON users_list TO nobody; + +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (923153018, 'imacat', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '依瑪貓', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (460376330, 'mandy', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '小招', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (723676436, 'guestbook', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '留言本', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); + +-- +-- Fixing the country table +-- + +ALTER TABLE country ADD FOREIGN KEY (createdby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +ALTER TABLE country ADD FOREIGN KEY (updatedby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +CREATE VIEW country_list AS + SELECT + country.sn AS sn, + country.id AS id, + COALESCE(country.name_zhtw, country.name_en) AS title, + CASE WHEN country.special THEN '特殊' + ELSE '' + END AS special, + to_char(country.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(country.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM country + LEFT JOIN users AS createdby ON country.createdby = createdby.sn + LEFT JOIN users AS updatedby ON country.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON country_list TO nobody; + + +-- +-- Table structure for table "groups" +-- + +CREATE TABLE groups ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(16) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + dsc varchar(64) NOT NULL CHECK (dsc != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groups TO nobody; + +CREATE VIEW groups_list AS + SELECT + groups.sn AS sn, + groups.id AS id, + groups.dsc AS dsc, + to_char(groups.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groups.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groups + LEFT JOIN users AS createdby ON groups.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groups.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON groups_list TO nobody; + +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (553229108, 'root', '總管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (802339805, 'guests', '暱名訪客', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (958210993, 'users', '已登入使用者', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (329685674, 'admin', '所有網站管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (157696540, 'acctman', '帳號管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (390105230, 'editor', '網站編輯', now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "usermem" +-- + +CREATE TABLE usermem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON usermem TO nobody; + +CREATE VIEW usermem_list AS + SELECT + usermem.sn AS sn, + groups.id || ' (' || groups.dsc || ')' AS grp, + members.id || ' (' || members.name || ')' AS member, + to_char(usermem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(usermem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM usermem + LEFT JOIN groups ON usermem.grp = groups.sn + LEFT JOIN users AS members ON usermem.member = members.sn + LEFT JOIN users AS createdby ON usermem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON usermem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON usermem_list TO nobody; + +-- INSERT INTO usermem (sn, grp, member, created, createdby, updated, updatedby) VALUES (593684712, 553229108, 923153018, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "groupmem" +-- + +CREATE TABLE groupmem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE CHECK (member != grp), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groupmem TO nobody; + +CREATE VIEW groupmem_list AS + SELECT + groupmem.sn AS sn, + groups.id || ' (' || groups.dsc || ')' AS grp, + members.id || ' (' || members.dsc || ')' AS member, + to_char(groupmem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groupmem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groupmem + LEFT JOIN groups ON groupmem.grp = groups.sn + LEFT JOIN groups AS members ON groupmem.member = members.sn + LEFT JOIN users AS createdby ON groupmem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groupmem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON groupmem_list TO nobody; + +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (569742102, 329685674, 157696540, now(), 923153018, now(), 923153018); +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (859385977, 329685674, 390105230, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "scptpriv" +-- + +CREATE TABLE scptpriv ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + script varchar(64) NOT NULL CHECK (script != ''), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (script, grp) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON scptpriv TO nobody; + +CREATE VIEW scptpriv_list AS + SELECT + scptpriv.sn AS sn, + scptpriv.script AS script, + groups.dsc AS grp, + to_char(scptpriv.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(scptpriv.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM scptpriv + LEFT JOIN groups ON scptpriv.grp = groups.sn + LEFT JOIN users AS createdby ON scptpriv.createdby = createdby.sn + LEFT JOIN users AS updatedby ON scptpriv.updatedby = updatedby.sn + ORDER BY script, grp; +GRANT SELECT ON scptpriv_list TO nobody; + + +-- +-- Table structure for table "userpref" +-- + +CREATE TABLE userpref ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + usr int REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + domain varchar(64) CHECK (domain IS NULL OR domain != ''), + name varchar(16) NOT NULL CHECK (name != ''), + value varchar(255) NOT NULL, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (usr, domain, name) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON userpref TO nobody; + +CREATE VIEW userpref_list AS + SELECT + userpref.sn AS sn, + CASE WHEN userpref.usr IS NOT NULL THEN users.name + ELSE '所有人' + END AS usr, + CASE WHEN userpref.domain IS NOT NULL THEN userpref.domain + ELSE '所有地方' + END AS domain, + userpref.name AS name, + userpref.value AS value, + to_char(userpref.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(userpref.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM userpref LEFT JOIN users ON userpref.usr = users.sn + LEFT JOIN users AS createdby ON userpref.createdby = createdby.sn + LEFT JOIN users AS updatedby ON userpref.updatedby = updatedby.sn + ORDER BY domain, usr, name; +GRANT SELECT ON userpref_list TO nobody; + + +-- +-- Function definitions for table "guestbook" +-- + +-- integer guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) +CREATE FUNCTION guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) RETURNS integer AS ' + DECLARE + row record; + len integer; + BEGIN + -- : 19, sn: 30 + 1, date: 54 + 1 + len := 105; + len := len + octet_length(host(ip)) + 22; + IF hostname IS NOT NULL THEN + len := len + octet_length(hostname) + 24; + END IF; + IF name IS NOT NULL THEN + len := len + octet_length(eschtml(name)) + 24; + END IF; + IF identity IS NOT NULL THEN + len := len + octet_length(eschtml(identity)) + 28; + END IF; + IF location IS NOT NULL THEN + len := len + octet_length(eschtml(location)) + 28; + END IF; + IF email IS NOT NULL THEN + len := len + octet_length(eschtml(email)) + 25; + END IF; + IF url IS NOT NULL THEN + len := len + octet_length(eschtml(url)) + 23; + END IF; + IF message IS NOT NULL THEN + len := len + octet_length(eschtml(message)) + 27; + END IF; + IF updated != date THEN + len := len + 58; + IF updatedby_arg = 923153018 THEN + len := len + 35; + ELSIF updatedby_arg = 460376330 THEN + len := len + 34; + ELSE + SELECT INTO row name FROM users WHERE sn=updatedby_arg; + len := len + octet_length(row.name) + 29; + END IF; + END IF; + RETURN len; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) TO nobody; +-- integer guestbook_oldlen(sn_arg integer) +CREATE FUNCTION guestbook_oldlen(sn_arg integer) RETURNS integer AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM guestbook WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN guestbook_oldlen(row.created, row.ip, row.host, row.name, row.identity, row.location, row.email, row.url, row.message, row.updated, row.updatedby); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(sn_arg integer) TO nobody; + + +-- +-- Table structure for table "guestbook" +-- + +CREATE TABLE guestbook ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + name varchar(32) CHECK (name IS NULL OR name != ''), + identity varchar(64) CHECK (identity IS NULL OR identity != ''), + location varchar(64) CHECK (location IS NULL OR location != ''), + email varchar(64) CHECK (email IS NULL OR email != ''), + url varchar(128) CHECK (url IS NULL OR (url != '' AND url != 'http://')), + message text NOT NULL CHECK (message != ''), + hid boolean NOT NULL DEFAULT FALSE, + ip inet NOT NULL, + host varchar(255) CHECK (host IS NULL OR host != ''), + ct char(2) NOT NULL REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + pageno int NOT NULL, + oldpageno int, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON guestbook TO nobody; + +CREATE VIEW guestbook_list AS + SELECT + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS _viewurl, + guestbook.sn AS sn, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + COALESCE(guestbook.name, '(未設定)') AS name, + COALESCE(guestbook.identity, '(未設定)') AS identity, + COALESCE(guestbook.location, '(未設定)') AS location, + COALESCE(guestbook.email, '(未設定)') AS email, + COALESCE(guestbook.url, '(未設定)') AS url, + guestbook.message AS message, + CASE WHEN guestbook.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + host(guestbook.ip) AS ip, + COALESCE(guestbook.host, '(不可考)') AS host, + COALESCE(country.name_zhtw, country.name_en) AS ct, + guestbook.pageno AS pageno, + guestbook.oldpageno AS oldpageno, + to_char(guestbook.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(guestbook.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM guestbook + LEFT JOIN country ON guestbook.ct = country.id + LEFT JOIN users AS createdby ON guestbook.createdby = createdby.sn + LEFT JOIN users AS updatedby ON guestbook.updatedby = updatedby.sn + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_list TO nobody; + +CREATE VIEW guestbook_public AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + name AS name, + identity AS identity, + location AS location, + email AS email, + url AS url, + message AS message, + pageno AS pageno, + oldpageno AS oldpageno + FROM guestbook + WHERE NOT hid + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_public TO nobody; + + +-- +-- Table structure for table "pages" +-- + +CREATE TABLE pages ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + path varchar(64) NOT NULL UNIQUE CHECK (path != ''), + ord smallint NOT NULL DEFAULT 5000 CHECK (ord >= 0 AND ord < 10000), + title varchar(128) NOT NULL CHECK (title != ''), + body text NOT NULL CHECK (body != ''), + kw varchar(128) NOT NULL CHECK (kw != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pages TO nobody; + +CREATE VIEW pages_list AS + SELECT + pages.path AS _viewurl, + pages.sn AS sn, + pages.path AS path, + pages.ord AS ord, + pages.title AS title, + pages.body AS body, + pages.kw AS kw, + CASE WHEN pages.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN pages.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(pages.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pages.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pages + LEFT JOIN users AS createdby ON pages.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pages.updatedby = updatedby.sn + ORDER BY path; +GRANT SELECT ON pages_list TO nobody; + + +-- +-- Function definitions for table "links" +-- + +-- boolean linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer); +CREATE FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) RETURNS boolean AS ' + BEGIN + IF parent_arg IS NULL THEN + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent IS NULL; + RETURN NOT FOUND; + ELSE + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent=parent_arg; + RETURN NOT FOUND; + END IF; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) TO nobody; + +-- numeric linkcat_fullord(parent_arg integer, ord_arg integer); +CREATE FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) RETURNS numeric AS ' + DECLARE + row record; + sn_loop integer; + ord_loop numeric; + BEGIN + sn_loop := parent_arg; + ord_loop := ord_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, ord FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN NULL; + END IF; + sn_loop := row.parent; + ord_loop := row.ord + ord_loop / 100; + END LOOP; + RETURN ord_loop; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) TO nobody; +-- numeric linkcat_fullord(sn_arg integer); +CREATE FUNCTION linkcat_fullord(sn_arg integer) RETURNS numeric AS ' + BEGIN + RETURN linkcat_fullord(sn_arg, 0); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(sn_arg integer) TO nobody; + +-- boolean linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + -- Check if we have childs + PERFORM links.sn FROM links + INNER JOIN linkcatz ON linkcatz.link=links.sn + WHERE NOT links.hid AND linkcatz.cat=sn_arg; + IF FOUND THEN + RETURN TRUE; + END IF; + -- Check if we have shown child categories + PERFORM sn FROM linkcat WHERE parent=sn_arg AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + RETURN TRUE; + END IF; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; +-- boolean linkcat_isshown(sn_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer) RETURNS boolean AS ' + DECLARE + row record; + BEGIN + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_isshown(sn_arg, row.hid, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer) TO nobody; +-- boolean linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + RETURN TRUE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; + +-- text linkcat_path(sn_arg integer, id_arg text, parent_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + path text; + BEGIN + PERFORM sn FROM linkcat + WHERE parent=sn_arg + AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + path := ''/'' || id_arg || ''/''; + ELSE + path := ''/'' || id_arg || ''.html''; + END IF; + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_loop; + path := ''/'' || row.id || path; + sn_loop := row.parent; + END LOOP; + RETURN path; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) TO nobody; +-- text linkcat_path(sn_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_path(sn_arg, row.id, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer) TO nobody; + +-- boolean linkcat_ischild(parent_arg integer, child_arg integer); +CREATE FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + sn_loop := child_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN FALSE; + END IF; + IF row.parent = parent_arg THEN + RETURN TRUE; + END IF; + sn_loop := row.parent; + END LOOP; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) TO nobody; + +-- text linkcat_fulltitle(sn_arg integer); +CREATE FUNCTION linkcat_fulltitle(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + title_full text; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + title_full := row.title; + WHILE row.parent IS NOT NULL LOOP + sn_loop := row.parent; + SELECT INTO row * FROM linkcat WHERE sn=sn_loop; + title_full := row.title || '' / '' || title_full; + END LOOP; + RETURN title_full; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(sn_arg integer) TO nobody; +-- text linkcat_fulltitle(parent_arg integer, title_arg text); +CREATE FUNCTION linkcat_fulltitle(parent_arg integer, title_arg text) RETURNS text AS ' + BEGIN + IF parent_arg IS NULL THEN + RETURN title_arg; + END IF; + RETURN linkcat_fulltitle(parent_arg) || '' / '' || title_arg; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(parent_arg integer, title_arg text) TO nobody; + + +-- +-- Table structure for table "linkcat" +-- + +CREATE TABLE linkcat ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + parent int REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE CHECK (parent IS NULL OR (parent != sn AND NOT linkcat_ischild(sn, parent))), + id varchar(8) NOT NULL CHECK (char_length(id) >= 2 AND linkcat_id_unique(id, sn, parent)), + ord smallint NOT NULL DEFAULT 50 CHECK (ord >= 0 AND ord < 100), + title varchar(128) NOT NULL CHECK (title != ''), + kw varchar(128) NOT NULL CHECK (kw != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcat TO nobody; + +CREATE VIEW linkcat_list AS + SELECT + '/links' || linkcat_path(linkcat.sn, linkcat.id, linkcat.parent) AS _viewurl, + linkcat.sn AS sn, + linkcat.id AS id, + linkcat.ord AS ord, + linkcat_fulltitle(linkcat.parent, linkcat.title) AS title, + linkcat.kw AS kw, + CASE WHEN linkcat.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(linkcat.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcat.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcat + LEFT JOIN users AS createdby ON linkcat.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcat.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), id; +GRANT SELECT ON linkcat_list TO nobody; + + +-- +-- Table structure for table "links" +-- + +CREATE TABLE links ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + title varchar(96) NOT NULL CHECK (title != ''), + title_2ln varchar(96) CHECK (title_2ln IS NULL OR title_2ln != ''), + url varchar(128) NOT NULL UNIQUE CHECK (url != '' AND url != 'http://'), + email varchar(64) CHECK (email IS NULL OR email != ''), + icon varchar(128) CHECK (icon IS NULL OR (icon != '' AND icon != 'http://')), + addr varchar(128) CHECK (addr IS NULL OR addr != ''), + tel varchar(48) CHECK (tel IS NULL OR tel != ''), + fax varchar(32) CHECK (fax IS NULL OR fax != ''), + dsc varchar(256) NOT NULL CHECK (dsc != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON links TO nobody; + +CREATE VIEW links_list AS + SELECT + links.url AS _viewurl, + links.sn AS sn, + links.title AS title, + links.title_2ln AS title_2ln, + links.url AS url, + links.url AS _urlcheck, + links.icon AS _imgsrc, + links.email AS email, + links.addr AS addr, + links.tel AS tel, + links.fax AS fax, + links.dsc AS dsc, + CASE WHEN links.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(links.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(links.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM links + LEFT JOIN users AS createdby ON links.createdby = createdby.sn + LEFT JOIN users AS updatedby ON links.updatedby = updatedby.sn + ORDER BY links.title; +GRANT SELECT ON links_list TO nobody; + + +-- +-- Table structure for table "linkcatz" +-- + +CREATE TABLE linkcatz ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + cat int NOT NULL REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE, + link int NOT NULL REFERENCES links ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (cat, link) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcatz TO nobody; + +CREATE VIEW linkcatz_list AS + SELECT + linkcatz.sn AS sn, + linkcat_fulltitle(linkcat.parent, linkcat.title) AS cat, + links.title AS link, + to_char(linkcatz.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcatz.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcatz + LEFT JOIN linkcat ON linkcatz.cat = linkcat.sn + LEFT JOIN links ON linkcatz.link = links.sn + LEFT JOIN users AS createdby ON linkcatz.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcatz.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), linkcat.id, link; +GRANT SELECT ON linkcatz_list TO nobody; + + +-- +-- Function definitions for table "newslets" +-- + +-- integer newslet_textno(no integer); +CREATE FUNCTION newslet_textno(no integer) RETURNS text AS ' + DECLARE + ten integer; + one integer; + textno text; + BEGIN + -- sanity check + IF no < 1 THEN + RETURN NULL; + -- number one is special + ELSIF no = 1 THEN + RETURN ''創刊號''; + END IF; + one := no % 10; + ten := (no - one) / 10; + -- We do not process numbers larger than 100. It is difficult and not likely. + IF ten > 9 THEN + RETURN ''第'' || no || ''期''; + END IF; + textno := CASE ten WHEN 0 THEN '''' + WHEN 1 THEN ''十'' WHEN 2 THEN ''二十'' WHEN 3 THEN ''三十'' + WHEN 4 THEN ''四十'' WHEN 5 THEN ''五十'' WHEN 6 THEN ''六十'' + WHEN 7 THEN ''七十'' WHEN 8 THEN ''八十'' WHEN 9 THEN ''九十'' + END || CASE one WHEN 0 THEN '''' + WHEN 1 THEN ''一'' WHEN 2 THEN ''二'' WHEN 3 THEN ''三'' + WHEN 4 THEN ''四'' WHEN 5 THEN ''五'' WHEN 6 THEN ''六'' + WHEN 7 THEN ''七'' WHEN 8 THEN ''八'' WHEN 9 THEN ''九'' + END; + RETURN ''第'' || textno || ''期''; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION newslet_textno(no integer) TO nobody; + +-- numeric nlindex_fullord(parent_arg integer, ord_arg integer); +CREATE FUNCTION nlindex_fullord(parent_arg integer, ord_arg integer) RETURNS numeric AS ' + DECLARE + row record; + sn_loop integer; + ord_loop numeric; + BEGIN + sn_loop := parent_arg; + ord_loop := ord_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, ord FROM nlindex WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN NULL; + END IF; + sn_loop := row.parent; + ord_loop := row.ord + ord_loop / 100; + END LOOP; + RETURN ord_loop; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION nlindex_fullord(parent_arg integer, ord_arg integer) TO nobody; +-- numeric nlindex_fullord(sn_arg integer); +CREATE FUNCTION nlindex_fullord(sn_arg integer) RETURNS numeric AS ' + BEGIN + RETURN nlindex_fullord(sn_arg, 0); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION nlindex_fullord(sn_arg integer) TO nobody; + +-- boolean nlindex_ischild(parent_arg integer, child_arg integer); +CREATE FUNCTION nlindex_ischild(parent_arg integer, child_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + sn_loop := child_arg; + WHILE sn_loop IS NOT NULL LOOP + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + SELECT INTO row parent FROM public.nlindex WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN FALSE; + END IF; + IF row.parent = parent_arg THEN + RETURN TRUE; + END IF; + sn_loop := row.parent; + END LOOP; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION nlindex_ischild(parent_arg integer, child_arg integer) TO nobody; + +-- text nlindex_fulltitle(sn_arg integer); +CREATE FUNCTION nlindex_fulltitle(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + title_full text; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row nlindex.parent AS parent, COALESCE(nlindex.title, nlarts.title) AS title FROM nlindex + LEFT JOIN nlarts ON nlindex.art=nlarts.sn + WHERE nlindex.sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + title_full := row.title; + WHILE row.parent IS NOT NULL LOOP + sn_loop := row.parent; + SELECT INTO row nlindex.parent AS parent, COALESCE(nlindex.title, nlarts.title) AS title FROM nlindex + LEFT JOIN nlarts ON nlindex.art=nlarts.sn + WHERE nlindex.sn=sn_loop; + title_full := row.title || '' / '' || title_full; + END LOOP; + RETURN title_full; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION nlindex_fulltitle(sn_arg integer) TO nobody; +-- text nlindex_fulltitle(parent_arg integer, title_arg text); +CREATE FUNCTION nlindex_fulltitle(parent_arg integer, title_arg text) RETURNS text AS ' + BEGIN + IF parent_arg IS NULL THEN + RETURN title_arg; + END IF; + RETURN nlindex_fulltitle(parent_arg) || '' / '' || title_arg; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION nlindex_fulltitle(parent_arg integer, title_arg text) TO nobody; + + +-- +-- Table structure for table "newslets" +-- + +CREATE TABLE newslets ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + no smallint NOT NULL UNIQUE CHECK (no > 0), + date date NOT NULL DEFAULT CURRENT_DATE, + title varchar(32) CHECK (title IS NULL OR title != ''), + credits varchar(256) CHECK (credits IS NULL OR credits != ''), + kw varchar(64) NOT NULL CHECK (kw != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON newslets TO nobody; + +CREATE VIEW newslets_list AS + SELECT + '/newsletters/' || lpad(cast(newslets.no AS text), 3, '0') || '/' + AS _viewurl, + newslets.sn AS sn, + newslet_textno(newslets.no) AS no, + newslets.date AS date, + newslets.title AS title, + newslets.credits AS credits, + newslets.kw AS kw, + CASE WHEN newslets.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(newslets.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(newslets.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM newslets + LEFT JOIN users AS createdby ON newslets.createdby = createdby.sn + LEFT JOIN users AS updatedby ON newslets.updatedby = updatedby.sn + ORDER BY newslets.no DESC; +GRANT SELECT ON newslets_list TO nobody; + + +-- +-- Table structure for table "nlarts" +-- + +CREATE TABLE nlarts ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + newslet int NOT NULL REFERENCES newslets ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + ord smallint NOT NULL DEFAULT 50 CHECK (ord >= 0 AND ord < 100), + title varchar(256) NOT NULL CHECK (title != ''), + title_h varchar(256) CHECK (title_h IS NULL OR title_h != ''), + author varchar(8) CHECK (author IS NULL OR author != ''), + email varchar(64) CHECK ((author IS NULL AND email IS NULL) OR (author IS NOT NULL AND (email IS NULL OR email != ''))), + authors varchar(64) CHECK ((author IS NULL AND authors IS NULL) OR (author IS NOT NULL AND (authors IS NULL OR authors != ''))), + body text NOT NULL CHECK (body != ''), + annots text CHECK (annots IS NULL OR annots != ''), + kw varchar(128) NOT NULL CHECK (kw != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON nlarts TO nobody; + +CREATE VIEW nlarts_list AS + SELECT + nlarts.sn AS sn, + newslet_textno(newslets.no) AS newslet, + nlarts.ord AS ord, + nlarts.title AS title, + nlarts.title_h AS title_h, + COALESCE(nlarts.authors, nlarts.author) AS author, + nlarts.email AS email, + nlarts.body AS body, + nlarts.annots AS annots, + nlarts.kw AS kw, + CASE WHEN nlarts.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN nlarts.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(nlarts.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(nlarts.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM nlarts + LEFT JOIN newslets ON nlarts.newslet = newslets.sn + LEFT JOIN users AS createdby ON nlarts.createdby = createdby.sn + LEFT JOIN users AS updatedby ON nlarts.updatedby = updatedby.sn + ORDER BY newslets.no DESC, nlarts.ord; +GRANT SELECT ON nlarts_list TO nobody; + + +-- +-- Table structure for table "nlindex" +-- + +CREATE TABLE nlindex ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + newslet int NOT NULL REFERENCES newslets ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + parent int REFERENCES nlindex ON UPDATE CASCADE DEFERRABLE CHECK (parent IS NULL OR (parent != sn AND NOT nlindex_ischild(sn, parent))), + ord smallint NOT NULL DEFAULT 50 CHECK (ord >= 0 AND ord < 100), + art int UNIQUE REFERENCES nlarts ON UPDATE CASCADE DEFERRABLE, + title varchar(128) CHECK ((art IS NULL AND (title IS NOT NULL AND title != '')) OR (art IS NOT NULL AND (title IS NULL OR title != ''))), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON nlindex TO nobody; + +CREATE VIEW nlindex_list AS + SELECT + nlindex.sn AS sn, + newslet_textno(newslets.no) AS newslet, + nlindex.ord AS ord, + nlindex_fulltitle(nlindex.parent, COALESCE(nlindex.title, nlarts.title)) AS title, + to_char(nlindex.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(nlindex.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM nlindex + LEFT JOIN newslets ON nlindex.newslet = newslets.sn + LEFT JOIN nlarts ON nlindex.art = nlarts.sn + LEFT JOIN users AS createdby ON nlindex.createdby = createdby.sn + LEFT JOIN users AS updatedby ON nlindex.updatedby = updatedby.sn + ORDER BY newslets.no DESC, nlindex_fullord(nlindex.parent, nlindex.ord); +GRANT SELECT ON nlindex_list TO nobody; + + +-- +-- VIEW: Search +-- +CREATE VIEW search_list AS + (SELECT + 'pages' AS section, + pages.path AS path, + pages.title AS title, + null AS author, + to_char(pages.updated, 'YYYY-MM-DD') AS date, + pages.body AS body, + pages.kw AS kw, + pages.html AS html + FROM pages + WHERE NOT pages.hid + AND pages.path NOT LIKE '/errors/%') + UNION + (SELECT + 'links' AS section, + links.url AS path, + links.title AS title, + null AS author, + to_char(links.updated, 'YYYY-MM-DD') AS date, + links.dsc AS body, + CASE WHEN links.title_2ln IS NULL THEN '' ELSE links.title_2ln END + || ' +' || CASE WHEN links.url IS NULL THEN '' ELSE links.url END + || ' +' || CASE WHEN links.email IS NULL THEN '' ELSE links.email END + || ' +' || CASE WHEN links.addr IS NULL THEN '' ELSE links.addr END + || ' +' || CASE WHEN links.tel IS NULL THEN '' ELSE links.tel END + || ' +' || CASE WHEN links.fax IS NULL THEN '' ELSE links.fax END + AS kw, + FALSE AS html + FROM links + WHERE NOT links.hid) + UNION + (SELECT + 'guestbook' AS section, + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS path, + null AS title, + guestbook.name AS author, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + guestbook.message AS body, + CASE WHEN guestbook.identity IS NULL THEN '' ELSE guestbook.identity END + || ' +' || CASE WHEN guestbook.location IS NULL THEN '' ELSE guestbook.location END + || ' +' || CASE WHEN guestbook.email IS NULL THEN '' ELSE guestbook.email END + || ' +' || CASE WHEN guestbook.url IS NULL THEN '' ELSE guestbook.url END + AS kw, + FALSE AS html + FROM guestbook + WHERE NOT guestbook.hid) + ORDER BY date DESC, title; +GRANT SELECT ON search_list TO nobody; + + +COMMIT; + diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc.pm new file mode 100644 index 0000000..90ebca4 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc.pm @@ -0,0 +1,70 @@ +# History: Theory and Culture +# htc.pm: History: Theory and Culture + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-06 + +package Selima::htc; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +@EXPORT = qw(); + +# Import our site-specific subroutines +use Selima::htc::Config; +push @EXPORT, @Selima::htc::Config::EXPORT; +use Selima::htc::DataVars qw(:all); +push @EXPORT, @Selima::htc::DataVars::EXPORT_OK; +use Selima::htc::HTML; +push @EXPORT, @Selima::htc::HTML::EXPORT; +use Selima::htc::Items; +push @EXPORT, @Selima::htc::Items::EXPORT; +use Selima::htc::Rebuild; +push @EXPORT, @Selima::htc::Rebuild::EXPORT; + +# Import our site-specific classess +use Selima::htc::Checker::Guestbook; +use Selima::htc::Checker::Guestbook::Public; +use Selima::htc::Checker::Newslet; +use Selima::htc::Checker::NLIndex; +use Selima::htc::Checker::NLArt; +use Selima::htc::Form::Guestbook; +use Selima::htc::Form::Guestbook::Public; +use Selima::htc::Form::Newslet; +use Selima::htc::Form::NLIndex; +use Selima::htc::Form::NLArt; +use Selima::htc::L10N; +use Selima::htc::List::Guestbook; +use Selima::htc::List::Guestbook::Public; +use Selima::htc::List::Newslets; +use Selima::htc::List::NLIndex; +use Selima::htc::List::NLArts; +use Selima::htc::List::Search; +use Selima::htc::Processor::Guestbook::Public; +use Selima::htc::Processor::Newslet; +use Selima::htc::Processor::NLIndex; +use Selima::htc::Processor::NLArt; + +# Import our common modules +use Selima; +push @EXPORT, @Selima::EXPORT; + +@EXPORT_OK = @EXPORT; + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/Guestbook.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/Guestbook.pm new file mode 100644 index 0000000..7503056 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/Guestbook.pm @@ -0,0 +1,54 @@ +# History: Theory and Culture +# Guestbook.pm: The administrative guestbook form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::htc::Checker::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker::Guestbook); + +use Selima::ShortCut; + +# _check_name: Check the name +sub _check_name : method { + # Run the parent checker + return $_[0]->SUPER::_check_name_req; +} + +# _check_identity: Check the identity +sub _check_identity : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("identity"); + return $error if defined $error; + # Regularize it + $self->_trim("identity"); + # Check the length + return {"msg"=>N_("This occupation is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"identity"}]} + if length $form->param("identity") > ${$self->{"maxlens"}}{"identity"}; + # OK + return; +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/Guestbook/Public.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/Guestbook/Public.pm new file mode 100644 index 0000000..b4990bd --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/Guestbook/Public.pm @@ -0,0 +1,57 @@ +# History: Theory and Culture +# Public.pm: The guestbook form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::htc::Checker::Guestbook::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker::Guestbook::Public); + +use Selima::DataVars qw($DBH); +use Selima::HTTP; +use Selima::Logging; +use Selima::ShortCut; + +# _check_name: Check the name +sub _check_name : method { + # Run the parent checker + return $_[0]->SUPER::_check_name_req; +} + +# _check_identity: Check the identity +sub _check_identity : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("identity"); + return $error if defined $error; + # Regularize it + $self->_trim("identity"); + # Check the length + return {"msg"=>N_("Your occupation is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"identity"}]} + if length $form->param("identity") > ${$self->{"maxlens"}}{"identity"}; + # OK + return; +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/NLArt.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/NLArt.pm new file mode 100644 index 0000000..ed36d19 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/NLArt.pm @@ -0,0 +1,205 @@ +# History: Theory and Culture +# NLArt.pm: The newsletter article form checker. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-30 + +package Selima::htc::Checker::NLArt; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Email::Valid; + +use Selima::CallForm; +use Selima::ChkFunc; +use Selima::ShortCut; + +use Selima::htc::DataVars qw(:forms); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "nlarts" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_annots: Check the annotations +sub _check_annots : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("annots"); + return $error if defined $error; + # Regularize it + $self->_trimtext("annots"); + # Skip if it is not filled + $form->param("annots", "") + if $form->param("annots") eq __("Fill in the annotations here."); + return if $form->param("annots") eq ""; + # Check the length + return {"msg"=>N_("This annotations list is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"annots"}]} + if length $form->param("annots") > ${$self->{"maxlens"}}{"annots"}; + # OK + return; +} + +# _check_author: Check the author +sub _check_author : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("author"); + return $error if defined $error; + # Regularize it + $self->_trim("author"); + # Skip if it is not filled + return if $form->param("author") eq ""; + # Check the length + return {"msg"=>N_("This author is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"author"}]} + if length $form->param("author") > ${$self->{"maxlens"}}{"author"}; + # OK + return; +} + +# _check_authors: Check the authors column +sub _check_authors : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("authors"); + return $error if defined $error; + # Regularize it + $self->_trimtext("authors"); + # Skip if it is not filled + $form->param("authors", "") + if $form->param("authors") eq __("Fill in the authors column here."); + return if $form->param("authors") eq ""; + # Check the length + return {"msg"=>N_("This authors column is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"authors"}]} + if length $form->param("authors") > ${$self->{"maxlens"}}{"authors"}; + # OK + return; +} + +# _check_body: Check the content +# Use the default content checker + +# _check_email: Check the e-mail +sub _check_email : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("email"); + return $error if defined $error; + # Regularize it + $self->_trim("email"); + # Skip if it is not filled + return if $form->param("email") eq ""; + # Check the length + return {"msg"=>N_("This e-mail is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"email"}]} + if length $form->param("email") > ${$self->{"maxlens"}}{"email"}; + # Check the e-mail validity + return {"msg"=>N_("Please fill in a valid e-mail address.")} + if !Email::Valid->rfc822($form->param("email")); + # OK + return; +} + +# _check_newslet: Check the newsletter +sub _check_newslet : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("newslet"); + return $error if defined $error; + # Regularize it + $self->_trim("newslet"); + # Check if it is filled + return {"msg"=>N_("Please select a newsletter.")} + if $form->param("newslet") eq ""; + # Check if the newsletter exists + return {"msg"=>N_("This newsletter does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("newslet")}[0], "newslets"; + # OK + return; +} + +# _check_title: Check the title +# Use the default title checker + +# _check_title_h: Check the HTML title +sub _check_title_h : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("title_h"); + return $error if defined $error; + # Regularize it + $self->_trim("title_h"); + # Skip if it is not filled + return if $form->param("title_h") eq ""; + # Check the length + return {"msg"=>N_("This HTML title is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"title_h"}]} + if length $form->param("title_h") > ${$self->{"maxlens"}}{"title_h"}; + # OK + return; +} + +# _redir_selnewslet: Suspend and move to the newsletter selection form +sub _redir_selnewslet : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selnewslet"); + call_form FORM_NEWSLETS, undef, "import_selnewslet"; +} + +# _redir_delnewslet: Remove the newsletter +sub _redir_delnewslet : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("delnewslet"); + $self->{"form"}->delete("newslet"); + success_redirect undef; +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm new file mode 100644 index 0000000..d138a14 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm @@ -0,0 +1,200 @@ +# History: Theory and Culture +# NLIndex.pm: The newsletter index form checker. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-29 + +package Selima::htc::Checker::NLIndex; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::CallForm; +use Selima::ChkFunc; +use Selima::DataVars qw($DBH :forms); +use Selima::ShortCut; + +use Selima::htc::DataVars qw(:forms); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "nlindex" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + ${$self->{"maxlens"}}{"ord"} = 2; + ${$self->{"minlens"}}{"id"} = 2; + return $self; +} + +# _check_newslet: Check the newsletter +sub _check_newslet : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("newslet"); + return $error if defined $error; + # Regularize it + $self->_trim("newslet"); + # Check if it is filled + return {"msg"=>N_("Please select a newsletter.")} + if $form->param("newslet") eq ""; + # Check if the newsletter exists + return {"msg"=>N_("This newsletter does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("newslet")}[0], "newslets"; + # OK + return; +} + +# _check_parent: Check the parent index item +sub _check_parent : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # "topmost not set" has a different form context + return {"msg"=>N_("Please select a parent index item.")} + if $self->_missing("topmost"); + # Regularize it + $self->_trim("topmost"); + # Check the option value + return {"msg"=>N_("This option is invalid. Please select a proper parent index item.")} + unless $form->param("topmost") =~ /^(?:true|false)$/; + # Check the parent index item if not a topmost index item + if ($form->param("topmost") eq "false") { + # Check if it exists + $error = $self->_missing("parent"); + return $error if defined $error; + # Regularize it + $self->_trim("parent"); + # Check if it is filled + return {"msg"=>N_("Please select a parent index item.")} + if $form->param("parent") eq ""; + # Check if this index item exists + return {"msg"=>N_("This parent index item does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("parent")}[0], "nlindex"; + if ($self->{"iscur"}) { + # Check if the parent index item is itself + return {"msg"=>N_("An index item cannot belong to itself. Please select another one.")} + if $form->param("parent") == $self->{"sn"}; + # Check if the parent directory is its descendant + $sql = "SELECT nlindex_ischild(" . $self->{"sn"} . ", " + . $form->param("parent") . ") AS is_child;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("An index item cannot belong to its descendant. Please select another one.")} + if ${$sth->fetchrow_hashref}{"is_child"}; + } + } + # OK + return; +} + +# _check_art: Check the article +sub _check_art : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("art"); + return $error if defined $error; + # Regularize it + $self->_trim("art"); + # Skip if it is not filled + return if $form->param("art") eq ""; + # Check if the article exists + return {"msg"=>N_("This article does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("art")}[0], "nlarts"; + # OK + return; +} + +# _check_title: The default title checker +sub _check_title : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("title"); + return $error if defined $error; + # Regularize it + $self->_trim("title"); + # Check if it is filled + if ($form->param("title") eq "") { + # Title must be filled if there is no article + return {"msg"=>N_("Please fill in the title.")} + if !defined $form->param("art") || $form->param("art") eq ""; + # OK + return; + } + # Check the length + return {"msg"=>N_("This title is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"title"}]} + if length $form->param("title") > ${$self->{"maxlens"}}{"title"}; + # OK + return; +} + +# _redir_selnewslet: Suspend and move to the newsletter selection form +sub _redir_selnewslet : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selnewslet"); + call_form FORM_NEWSLETS, undef, "import_selnewslet"; +} + +# _redir_delnewslet: Remove the newsletter +sub _redir_delnewslet : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("delnewslet"); + $self->{"form"}->delete("newslet"); + success_redirect undef; +} + +# _redir_selart: Suspend and move to the article selection form +sub _redir_selart : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selart"); + call_form FORM_NLARTS, undef, "import_selart"; +} + +# _redir_delart: Remove the article +sub _redir_delart : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("delart"); + $self->{"form"}->delete("art"); + success_redirect undef; +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/Newslet.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/Newslet.pm new file mode 100644 index 0000000..f42637f --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Checker/Newslet.pm @@ -0,0 +1,140 @@ +# History: Theory and Culture +# Newslet.pm: The newsletter form checker. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-28 + +package Selima::htc::Checker::Newslet; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use CGI qw(); + +use Selima::CallForm; +use Selima::ChkFunc; +use Selima::DataVars qw(:dataman); +use Selima::ShortCut; + +use Selima::htc::DataVars qw(:forms); +use Selima::htc::Items; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "newslets" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_no: Check the issue number +# Actually this is to set the issue number, but not to check it +sub _check_no : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Current form + if ($self->{"iscur"}) { + $self->{"form"}->param("no", $CURRENT{"no"}); + return; + } + # Create a new issue for this new newsletter + $self->{"form"}->param("no", new_nl_no); + return; +} + +# _check_date: Check the date +sub _check_date : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("date"); + return $error if defined $error; + # Regularize it + $self->_trim("date"); + # Check if it is filled + return {"msg"=>N_("Please fill in the date.")} + if $form->param("date") eq ""; + # Check the length + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + if length $form->param("date") != ${$self->{"maxlens"}}{"date"}; + # Check the date format + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + if length $form->param("date") !~ /^(\d{4})-(\d{2})-(\d{2})$/; + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + unless defined check_date($1, $2, $3); + # OK + return; +} + +# _check_credits: Check the credits +sub _check_credits : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("credits"); + return $error if defined $error; + # Regularize it + $self->_trimtext("credits"); + # Skip if it is not filled + return if $form->param("credits") eq ""; + # Check the length + return {"msg"=>N_("This credits information is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"credits"}]} + if length $form->param("credits") > ${$self->{"maxlens"}}{"credits"}; + # OK + return; +} + +# _redir_selndxart: Suspend and move to the index item article selection form +sub _redir_selndxart : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Skip if not requested + @_ = grep /^selndx\d+(?:sub\d+)*art$/, sort $form->param; + return if @_ == 0; + $_ = $_[0]; + s/^sel//; + $form->param("caller_index", $_); + call_form FORM_NLARTS, undef, "import_selndxart"; +} + +# _redir_delndxart: Remove the index item article +sub _redir_delndxart : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Skip if not requested + @_ = grep /^delndx\d+(?:sub\d+)*art$/, sort $form->param; + return if @_ == 0; + $_ = $_[0]; + s/^del//; + $form->delete($_); + success_redirect undef; +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Config.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Config.pm new file mode 100644 index 0000000..24144de --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Config.pm @@ -0,0 +1,90 @@ +# History: Theory and Culture +# Config.pm: The web site configuration. + +# Copyright (c) 2003-2020 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-06 + +package Selima::htc::Config; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(siteconf page_replacements); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub siteconf(); +sub page_replacements(); +} + +# Get into the public variable space and initialize them +use lib $ENV{"DOCUMENT_ROOT"} . qw(/../../lib/perl5); +use Selima::CopyYear; +use Selima::DataVars qw(:all); +use Selima::ShortCut; + +use Selima::htc::DataVars qw(:all); + +# siteconf: Subroutine to initialize site configuration +sub siteconf() { + local ($_, %_); + + # The package name and the package title + $PACKAGE = "htc"; + $SITENAME_ABBR = "HTC"; + # The author and the copyright + $AUTHOR = "依瑪貓"; + $COPYRIGHT = "© 歷史:理論與文化編輯群。歷史:理論與文化編輯群保有所有權利。"; + # Document root, the library and the l10n directories + $DOC_ROOT = $ENV{"DOCUMENT_ROOT"}; + $SITE_LIBDIR = $DOC_ROOT . "/magicat/lib/perl5"; + $LOCALEDIR = $DOC_ROOT . "/magicat/locale"; + + # Tables to lock when rebuilding pages + @REBUILD_TABLES = qw(linkcat links linkcatz); + + # The languages + $DEFAULT_LANG = "zh-tw"; + @ALL_LINGUAS = qw(zh-tw); + + # The site data variables + $SCRIPTS{FORM_NEWSLETS()} = "/magicat/cgi-bin/newslets.cgi", + $SCRIPTS{FORM_NLINDEX()} = "/magicat/cgi-bin/nlindex.cgi", + $SCRIPTS{FORM_NLARTS()} = "/magicat/cgi-bin/nlarts.cgi", + + return; +} + +# page_replacements: Dynamic page elements to be replaced, +# but not part of the content. Used by xfupdate_template(). +sub page_replacements() { + return { + "copyyear" => { + "pattern" => "2000(?:-\\d{4})?", + "content" => copyyear(2000), + }, + "generator" => { + "pattern" => "Selima \\d+\\.\\d+", + "content" => "Selima $Selima::VERSION", + }, + }; +} + +no utf8; +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/DataVars.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/DataVars.pm new file mode 100644 index 0000000..4cb21ce --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/DataVars.pm @@ -0,0 +1,60 @@ +# History: Theory and Culture +# DataVars.pm: The site-wide constants and variables. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-29 + +package Selima::htc::DataVars; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT %EXPORT_TAGS @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +%EXPORT_TAGS = ( + forms => [qw(FORM_NEWSLETS FORM_NLINDEX FORM_NLARTS)], +); +@EXPORT_OK = qw(); +my %seen; +%seen = qw(); +foreach my $tag (keys %EXPORT_TAGS) { + push @EXPORT_OK, grep !$seen{$_}++, @{$EXPORT_TAGS{$tag}}; +} +$EXPORT_TAGS{"all"} = [@EXPORT_OK]; +# Prototype declaration +sub clear(); +} + +use Selima::DataVars qw(:forms); + +use constant FORM_NEWSLETS => 1001; +use constant FORM_NLINDEX => 1002; +use constant FORM_NLARTS => 1003; + +# clear: Clear the data variables +sub clear() { + local ($_, %_); + + delete $SCRIPTS{FORM_NEWSLETS()}; + delete $SCRIPTS{FORM_NLINDEX()}; + delete $SCRIPTS{FORM_NLARTS()}; + + return; +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/Guestbook.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/Guestbook.pm new file mode 100644 index 0000000..496fe09 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/Guestbook.pm @@ -0,0 +1,40 @@ +# History: Theory and Culture +# Guestbook.pm: The administrative guestbook form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::htc::Form::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form::Guestbook); + +use Selima::MarkAbbr; +use Selima::ShortCut; + +# _html_col_identity: The identity +sub _html_col_identity : method { + $_[0]->_html_coltmpl_text("identity", h_abbr(__("Occupation:"))); +} + +# _html_col_url: The website URL +sub _html_col_url : method { + $_[0]->_html_coltmpl_url("url", h_abbr(__("Website URL.:"))); +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm new file mode 100644 index 0000000..a6f40ef --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm @@ -0,0 +1,62 @@ +# History: Theory and Culture +# Public.pm: The guestbook form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::htc::Form::Guestbook::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form::Guestbook::Public); + +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# _html_col_email: The e-mail +sub _html_col_email : method { + $_[0]->_html_coltmpl_text("email", h_abbr(__("E-mail"))); +} + +# _html_col_identity: The identity +sub _html_col_identity : method { + $_[0]->_html_coltmpl_text("identity", h_abbr(__("Occupation"))); +} + +# _html_col_location: The location +sub _html_col_location : method { + $_[0]->_html_coltmpl_text("location", h_abbr(__("Location"))); +} + +# _html_col_message: The message +sub _html_col_message : method { + $_[0]->_html_coltmpl_textarea("message", h_abbr(__("Message")), + h_abbr(__("Fill in your message here."))); +} + +# _html_col_name: The name +sub _html_col_name : method { + $_[0]->_html_coltmpl_text("name", h_abbr(__("Signature"))); +} + +# _html_col_url: The website URL +sub _html_col_url : method { + $_[0]->_html_coltmpl_url("url", h_abbr(__("Website URL."))); +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/NLArt.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/NLArt.pm new file mode 100644 index 0000000..5f367c0 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/NLArt.pm @@ -0,0 +1,124 @@ +# History: Theory and Culture +# NLArt.pm: The newsletter article form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-29 + +package Selima::htc::Form::NLArt; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::CommText; +use Selima::DataVars qw(:dataman :requri); +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +use Selima::htc::Items; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "nlarts" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this article") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to add a new article."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current article."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a article."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(newslet ord title title_h author + email authors body annots kw html hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn newslet ord title title_h author + email authors body annots kw html hid + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Add a New Newsletter Article"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Newsletter Article"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Newsletter Article"); + } + } + if (!exists $$args{"preview"}) { + $$args{"preview"} = 1; + } + if ($$args{"preview"} && !exists $$args{"prevmsg"}) { + $$args{"prevmsg"} = __("Preview this article."); + } + $self = $class->SUPER::new($status, $args); + ${$self->{"maxlens"}}{"ord"} = 2; + return $self; +} + +# _html_col_newslet: The newsletter +sub _html_col_newslet : method { + $_[0]->_html_coltmpl_call("newslet", h_abbr(__("Newsletter:")), \&newslet_title); +} + +# _html_col_title_h: The HTML title +sub _html_col_title_h : method { + $_[0]->_html_coltmpl_text("title_h", h_abbr(__("HTML title:")), + h_abbr(__("(Leave it blank if the same as the title.)"))); +} + +# _html_col_authors: The authors column +sub _html_col_authors : method { + $_[0]->_html_coltmpl_textarea("authors", h_abbr(__("Authors column:")), + h_abbr(__("Fill in the authors column here.")), + h_abbr(__("(Leave it blank if the same as the author.)")), 3); +} + +# _html_col_annots: The annotations +sub _html_col_annots : method { + $_[0]->_html_coltmpl_textarea("annots", h_abbr(__("Annotations:")), + h_abbr(__("Fill in the annotations here."))); +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/NLIndex.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/NLIndex.pm new file mode 100644 index 0000000..af4140a --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/NLIndex.pm @@ -0,0 +1,152 @@ +# History: Theory and Culture +# NLIndex.pm: The newsletter index form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-29 + +package Selima::htc::Form::NLIndex; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::CommText; +use Selima::DataVars qw(:requri); +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +use Selima::htc::Items; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "nlindex" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this index item") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to add a new index item."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current index item."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a index item."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(newslet parent ord art title)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn newslet parent ord art title subitems + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Add a New Newsletter Index Item"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Newsletter Index Item"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Newsletter Index Item"); + } + } + $self = $class->SUPER::new($status, $args); + ${$self->{"maxlens"}}{"ord"} = 2; + if ($self->{"type"} eq "cur") { + if (defined $self->{"cur"}->param("subitemcount") && $self->{"cur"}->param("subitemcount") > 0) { + $self->{"nodelete"} = 1; + push @{$self->{"prefmsg"}}, __("This index item has [numerate,_1,a subitem,subitems]. It cannot be deleted. To delete the index item, [numerate,_1,its subitem,all of its subitems] must first be deleted.", $self->{"cur"}->param("subitemcount")); + } + } + return $self; +} + +# _html_col_art: The article +sub _html_col_art : method { + $_[0]->_html_coltmpl_call("art", h_abbr(__("Article:")), \&nlart_title); +} + +# _html_col_newslet: The newsletter +sub _html_col_newslet : method { + $_[0]->_html_coltmpl_call("newslet", h_abbr(__("Newsletter:")), \&newslet_title); +} + +# _html_col_parent: The parent +sub _html_col_parent : method { + $_[0]->_html_coltmpl_call_null("parent", h_abbr(__("Parent item:")), + "topmost", h_abbr(__("At the very top")), \&nlindex_title); +} + +# _html_col_subitems: The subitems +sub _html_col_subitems : method { + local ($_, %_); + my ($self, $form, $current, $label, $url, $mark, $colspan, $thclass, $thcolspan); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("subitems"); + $colspan = $self->_colspan; + $label = h_abbr(__("[numerate,_1,Subitem,Subitems]:", $current->param("subitemcount"))); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label +EOT + print " "; + @_ = qw(); + for ($_ = 0; $_ < $current->param("subitemcount"); $_++) { + push @_, sprintf "
  • %s
  • \n", + h($REQUEST_FILE . "?form=cur&sn=" . $current->param("subitem$_" . "sn")), + $self->_cval_text("subitem$_" . "title"); + } + print @_ > 0? "
      " . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT +} + +# _html_col_title: The title +sub _html_col_title : method { + $_[0]->_html_coltmpl_text("title", h_abbr(__("Title:")), + h_abbr(__("(Leave it blank if the same as the article title.)"))); +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/Newslet.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/Newslet.pm new file mode 100644 index 0000000..84018c7 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Form/Newslet.pm @@ -0,0 +1,396 @@ +# History: Theory and Culture +# Newslet.pm: The newsletter form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-28 + +package Selima::htc::Form::Newslet; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use CGI qw(); + +use Selima::CallForm; +use Selima::CommText; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +use Selima::htc::Items; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "newslets" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this newsletter") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to add a new newsletter."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current newsletter."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a newsletter."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(no date title credits kw hid + index arts)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn no date title credits kw hid + index arts + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Add a New Newsletter"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Newsletter"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Newsletter"); + } + } + if (!exists $$args{"preview"}) { + $$args{"preview"} = 1; + } + if ($$args{"preview"} && !exists $$args{"prevmsg"}) { + $$args{"prevmsg"} = __("Preview this newsletter."); + } + $self = $class->SUPER::new($status, $args); + # The columns -- we need $self->{"form"} to calculate it + @_ = grep /^ndx.+sub$/, sort $self->{"form"}->param; + $_ = 3; + $_ += 2 while (@_ = grep s/\d+sub$//, @_) > 0; + # Take the larger value + $self->{"colspan"} = $_ if $self->{"colspan"} < $_; + return $self; +} + +# _html_col_arts: The articles +sub _html_col_arts : method { + local ($_, %_); + my ($self, $form, $current, $label, $url, $mark, $colspan, $thclass, $thcolspan); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("arts"); + $colspan = $self->_colspan; + $label = h_abbr(__("[numerate,_1,Article,Articles]:", $current->param("artcount"))); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label +EOT + print " "; + @_ = qw(); + for ($_ = 0; $_ < $current->param("artcount"); $_++) { + push @_, sprintf "
  • %s
  • \n", + h("nlarts.cgi?form=cur&sn=" . $current->param("art$_" . "sn")), + $self->_cval_text("art$_" . "title"); + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT +} + +# _html_col_credits: The credits +sub _html_col_credits : method { + $_[0]->_html_coltmpl_textarea("credits", h_abbr(__("Credits:")), + h(__("Fill in the credits here."))); +} + +# _html_col_hid: Hide? +sub _html_col_hid : method { + $_[0]->_html_coltmpl_bool("hid", h_abbr(__("Hide?")), + h_abbr(__("Hide this newsletter")), h_abbr(__("Show this newsletter")), + h_abbr(__("Hide this newsletter currently."))); +} + +# _html_col_index: The index +sub _html_col_index : method { + local ($_, %_); + my ($self, $form, $current, $label, $orig, $new, $mark, $colspan); + my ($rowspan, $rows_new, $htmlsub); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $label = h_abbr(__("Index:")); + $mark = $self->_mark("poems"); + $colspan = $self->_colspan; + + # A form to create a new item + if ($self->{"type"} eq "new") { + ($rowspan, $htmlsub) = $self->__html_col_index_form("ndx"); + $rowspan = $rowspan > 1? " rowspan=\"" . h($rowspan) . "\"": ""; + print << "EOT"; + + +EOT + print $htmlsub . "\n"; + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + ($rows_new, $htmlsub) = $self->__html_col_index_form("ndx"); + $rowspan = $rows_new + 1; + $rows_new = $rows_new > 1? " rowspan=\"" . h($rows_new) . "\"": ""; + $rowspan = $rowspan > 1? " rowspan=\"" . h($rowspan) . "\"": ""; + $orig = h_abbr(__("Original:")); + $new = h_abbr(__("New:")); + print << "EOT"; + + + $orig +EOT + print " "; + print $current->param("ndxcount") > 0? + $self->__html_col_index_cur("ndx") . " ": h_abbr(t_none); + print << "EOT"; + + + + $new +EOT + print $htmlsub . "\n"; + + # A form to delete a current item + } else { + $label = h_abbr(__("Index:")); + print << "EOT"; + + $mark$label +EOT + print " "; + print $current->param("ndxcount") > 0? + $self->__html_col_index_cur("ndx") . " ": h_abbr(t_none); + print << "EOT"; + + +EOT + } + return; +} + +# _html_col_no: The issue number +sub _html_col_no : method { + local ($_, %_); + my ($self, $label, $cur, $mark, $colspan, $thclass, $thcolspan); + $self = $_[0]; + $label = h_abbr(__("Issue:")); + $mark = $self->_mark("no"); + $colspan = $self->_colspan; + + # A form to create a new item + if ($self->{"type"} eq "new") { + $cur = h_abbr(newslet_textno new_nl_no); + print << "EOT" + + $mark$label + $cur + +EOT + + # A current or delete form + } else { + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + $cur = h_abbr(newslet_textno scalar $self->{"cur"}->param("no")); + print << "EOT"; + + $mark$label + $cur + +EOT + } + return; +} + +# __html_col_index_cur: The current index +sub __html_col_index_cur : method { + local ($_, %_); + my ($self, $colpref, $current, $html, $linepref, $title); + ($self, $colpref) = @_; + $current = $self->{"cur"}; + ($_, $linepref) = ($colpref, " "); + $linepref .= " " while s/^\D+\d+//; + + for ($_ = 0, @_ = qw(); $_ < $current->param($colpref . "count"); $_++) { + $title = defined $current->param("$colpref$_" . "title")? + $current->param("$colpref$_" . "title"): + nlart_title($current->param("$colpref$_" . "art")); + if (defined $current->param("$colpref$_" . "sub")) { + push @_, sprintf("%1\$s
  • %2\$s\n%1\$s %3\$s%1\$s
  • \n", $linepref, + h($title), $self->__html_col_index_cur("$colpref$_" . "sub")); + } else { + push @_, sprintf("%s
  • %s
  • \n", $linepref, + h($title)); + } + } + return "
      \n" . join("", @_) . "$linepref
    \n"; +} + +# __html_col_index_form: The index form +sub __html_col_index_form : method { + local ($_, %_); + my ($self, $colpref, $form, $rows, $colspan, $title, $htmlform); + my ($col, $val, $valartlabel, $textsub, $count, $choose, $delete); + my ($labelart, $labeltitle, $labelsub, $labelsubs); + my ($markart, $marktitle, $marksub, $marksubs); + ($self, $colpref) = @_; + $form = $self->{"form"}; + ($_, $colspan) = ($colpref, -2); + $colspan -= 2 while s/^\D+\d+//; + $colspan = $self->_colspan($colspan); + $choose = h_abbr(__("Choose")); + $delete = h_abbr(__("Delete")); + $labelart = h_abbr(__("Article:")); + $labeltitle = h_abbr(__("Title:")); + $labelsub = h_abbr(__("Has subitems?")); + $labelsubs = h_abbr(__("Subitems:")); + $textsub = h(__("This item has subitems.")); + $markart = $self->_mark("ndxart"); + $marktitle = $self->_mark("ndxtitle"); + $marksub = $self->_mark("ndxhassub"); + $marksubs = $self->_mark("ndxsub"); + + # Find the last filled item + for ($_ = 0; defined $form->param("$colpref$_" . "art") + || defined $form->param("$colpref$_" . "title"); $_++) {} + for ($_--; $_ >= 0 + && (!defined $form->param("$colpref$_" . "art") + || $form->param("$colpref$_" . "art") eq "") + && $form->param("$colpref$_" . "title") eq "" + && !defined $form->param("$colpref$_" . "sub"); $_--) {} + $count = $_ + 1 + 2; + for ($_ = 0, $rows = 0, @_ = qw(); $_ < $count; $_++) { + my ($colart, $coltitle, $colsub, $colsub0, $valart, $valtitle, $valsub); + $col = "$colpref$_"; + $val = $self->_val_check($col); + # "" means not selected yet + $form->delete($col . "art") + if defined $form->param($col . "art") && $form->param($col . "art") eq ""; + $valart = $self->_val_text($col . "art"); + $colart = h($col . "art"); + $valartlabel = h(nlart_title $form->param($colart)); + $valtitle = $self->_val_text($col . "title"); + $coltitle = h_abbr($col . "title"); + $valsub = $self->_val_check($col . "sub"); + $colsub = h($col . "sub"); + $colsub0 = h($col . "sub0"); + $col = h($col); + # An index item that has subitems + if (defined $form->param("$colpref$_" . "sub")) { + my ($htmlsub, $rows_form, $rows_sub); + ($rows_sub, $htmlsub) = $self->__html_col_index_form("$colpref$_" . "sub"); + $rows_form = $rows_sub + 3; + $rows += $rows_form; + $rows_form = $rows_form > 1? " rowspan=\"" . h($rows_form) . "\"": ""; + $rows_sub = $rows_sub > 1? " rowspan=\"" . h($rows_sub) . "\"": ""; + $htmlform = ""; + $htmlform .= << "EOT"; + + + + +EOT + if (defined $form->param($col . "art")) { + $htmlform .= << "EOT"; + +EOT + } + $htmlform .= << "EOT"; + + + + + + + + + + + + + + +EOT + $htmlform .= $htmlsub; + + # An end index item + } else { + $rows += 3; + $htmlform = ""; + $htmlform .= << "EOT"; + + + + +EOT + if (defined $form->param($col . "art")) { + $htmlform .= << "EOT"; + +EOT + } + $htmlform .= << "EOT"; + + + + + + + + + + + +EOT + } + push @_, $htmlform; + } + return ($rows, join("\n\n", @_)); +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/HTML.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/HTML.pm new file mode 100644 index 0000000..69ba412 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/HTML.pm @@ -0,0 +1,684 @@ +# History: Theory and Culture +# HTML.pm: The HTML web page parts. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-06 + +package Selima::htc::HTML; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(html_header html_title html_message); +push @EXPORT, qw(html_errmsg html_body html_links html_links_index html_footer); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub html_header($;$); +sub html_title($;$); +sub html_message($); +sub html_errmsg($); +sub html_nav(;$); +sub html_login(;$); +sub html_nav_admin(;$); +sub html_nav_page(;$); +sub html_body($;$); +sub html_links($;$); +sub html_links_index(\@;$); +sub html_footer(;$); +sub merged_tree($$;$); +} + +use Cwd qw(realpath); +use File::Basename qw(dirname); +use File::Spec::Functions qw(); +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use Selima::A2HTML; +use Selima::AddGet; +use Selima::AltLang; +use Selima::DataVars qw(:author :env :input :list :lninfo :requri :siteconf); +use Selima::ErrMsg; +use Selima::HTTPS; +use Selima::Links; +use Selima::LnInfo; +use Selima::LogIn; +use Selima::MarkAbbr; +use Selima::MungAddr; +use Selima::PageFunc; +use Selima::Preview; +use Selima::ScptPriv; +use Selima::ShortCut; +use Selima::Unicode; +use Selima::XFileIO; + +use vars qw(@ADMIN_SCRIPTS %HEADER %FOOTER); +@ADMIN_SCRIPTS = ( + { "title" => N_("Manage Content"), + "sub" => [ + { "title" => N_("Guestbook"), + "path" => "/magicat/cgi-bin/guestbook.cgi" }, + { "title" => N_("Pages"), + "path" => "/magicat/cgi-bin/pages.cgi" }, + { "title" => N_("Links"), + "path" => "/magicat/cgi-bin/links.cgi" }, + { "title" => N_("Link Categories"), + "path" => "/magicat/cgi-bin/linkcat.cgi" }, + { "title" => N_("Link Categorization"), + "path" => "/magicat/cgi-bin/linkcatz.cgi" }, + { "title" => N_("Newsletters"), + "path" => "/magicat/cgi-bin/newslets.cgi" }, + { "title" => N_("Newsletter Indices"), + "path" => "/magicat/cgi-bin/nlindex.cgi" }, + { "title" => N_("Newsletter Articles"), + "path" => "/magicat/cgi-bin/nlarts.cgi" }, + ], + }, + { "title" => N_("Manage Accounts"), + "sub" => [ + { "title" => N_("Users"), + "path" => "/magicat/cgi-bin/users.cgi" }, + { "title" => N_("Groups"), + "path" => "/magicat/cgi-bin/groups.cgi" }, + { "title" => N_("User Membership"), + "path" => "/magicat/cgi-bin/usermem.cgi" }, + { "title" => N_("Group Membership"), + "path" => "/magicat/cgi-bin/groupmem.cgi" }, + { "title" => N_("User Preferences"), + "path" => "/magicat/cgi-bin/userpref.cgi" }, + { "title" => N_("Script Privileges"), + "path" => "/magicat/cgi-bin/scptpriv.cgi" }, + ], + }, + { "title" => N_("Miscellaneous"), + "sub" => [ + { "title" => N_("Activity Log"), + "path" => "/magicat/cgi-bin/actlog.cgi" }, + { "title" => N_("Rebuild Pages"), + "path" => "/magicat/cgi-bin/rebuild.cgi" }, + { "title" => N_("Analog"), + "path" => "/magicat/analog/" }, + { "title" => N_("Test Script"), + "path" => "/magicat/cgi-bin/test.cgi" }, + ], + }, +); + +# html_header: Display the page header +sub html_header($;$) { + local ($_, %_); + my ($title, $args, $guide); + my ($langname, $langfile); + my ($author, $copyright, $keywords, $copypage); + my ($stylesheets, $javascripts, $favicon, $class, $onload); + my ($titlelang, $skiptobody); + ($title, $args) = @_; + # Obtain the page parameters + $args = page_param $args; + # Set the language + $langname = h(ln $$args{"lang"}, LN_NAME); + $langfile = ln($$args{"lang"}, LN_FILENAME); + # Misc + # The copyright message should be already HTML-escaped, + # for the copyright sign "©". + $author = exists $$args{"author"}? h($$args{"author"}): + defined $AUTHOR? h($AUTHOR): undef; + $copyright = exists $$args{"copyright"}? $$args{"copyright"}: + defined $COPYRIGHT? $COPYRIGHT: undef; + $keywords = exists $$args{"keywords"}? h($$args{"keywords"}): undef; + $copypage = exists $$args{"copypage"}? h($$args{"copypage"}): undef; + # Style sheets + $stylesheets = []; + push @$stylesheets, "/stylesheets/common.css"; + push @$stylesheets, @{$$args{"stylesheets"}} + if exists $$args{"stylesheets"}; + # JavaScripts + $javascripts = []; + if (exists $$args{"javascripts"}) { + push @$javascripts, "/scripts/common.js"; + push @$javascripts, "/scripts/lang.$langfile.js"; + push @$javascripts, @{$$args{"javascripts"}}; + } + # Favorite icon + $favicon = exists $$args{"favicon"}? + h($$args{"favicon"}): h("/favicon.ico"); + # The class of body + $class = exists $$args{"class"}? + " class=\"" . h($$args{"class"}) . "\"": ""; + # The onload JavaScript event handler + $onload = exists $$args{"onload"}? + " onload=\"" . h($$args{"onload"}) . "\"": ""; + # The accessibility guide + $skiptobody = h(__("Skip to the page content area.")); + $guide = h(__("Page Content Area")); + + print << "EOT"; +" ?> + + + + + + +EOT + # Author, copyright and keywords + print "\n" + if defined $author; + print "\n" + if defined $copyright; + print "\n" + if defined $keywords; + print "\" />\n" + if $$args{"static"}; + # The home page + print "\n"; + # The copyright page + print "\n" + if defined $copypage; + # The author contact information + print "\n"; + # Revelent pages + print "\n" + if exists $$args{"up"}; + print "\n" + if exists $$args{"first"}; + print "\n" + if exists $$args{"prev"}; + print "\n" + if exists $$args{"next"}; + print "\n" + if exists $$args{"last"}; + print "\n" + if exists $$args{"toc"}; + # Style sheets + print "\n" + foreach @$stylesheets; + # JavaScripts + print "\n" + foreach @$javascripts; + # Favorite Icon + print "\n"; + # The title + $titlelang = $$args{"title_lang"} eq $$args{"lang"}? "": + " xml:lang=\"" . h(ln $$args{"title_lang"}, LN_NAME) . "\""; + print "" . h($title) . "\n"; + print << "EOT"; + + + + + + +EOT + + # Show the navigation area + html_nav $args; + # Embrace the content + print << "EOT"; +
    + + +EOT + # Display the title + html_title $title, $args unless $$args{"no_auto_title"}; + + return; +} + +# html_title: Print an HTML title +sub html_title($;$) { + local ($_, %_); + my ($title, $args, $h); + ($title, $args) = @_; + $h = << "EOT"; +

    %s

    + +EOT + printf $h, h_abbr($title); + return; +} + +# html_message: Print an HTML message +sub html_message($) { + local ($_, %_); + $_ = $_[0]; + return if !defined $_ || $_ eq ""; + $_ = h_abbr($_); + print << "EOT"; +

    $_

    + +EOT + return; +} + +# html_errmsg: Print an HTML error message, a wrapper to html_message() +sub html_errmsg($) { + local ($_, %_); + $_ = $_[0]; + return if !defined $_; + html_message(err2msg $_); + return; +} + +# html_nav: Print the HTML navigation bar +sub html_nav(;$) { + local ($_, %_); + my ($args, $lang, $guide, $FD, @sections); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + $lang = $$args{"lang"}; + # The accessibility guide + $guide = h(__("Navigation Links Area")); + + @sections = qw(); + # Print the primary navigation bar + $HEADER{"file"} = sprintf("%s/magicat/include/header.html", $DOC_ROOT) + if !exists $HEADER{"file"}; + undef $_; + if ( !exists $HEADER{"content"} + || !exists $HEADER{"date"} + || $HEADER{"date"} < ($_ = (stat $HEADER{"file"})[9])) { + $_ = (stat $HEADER{"file"})[9] if !defined $_; + $HEADER{"date"} = $_; + $HEADER{"content"} = hcref_decode ln($lang, LN_CHARSET), xfread $HEADER{"file"}; + } + push @sections, $HEADER{"content"}; + + # Print the log-in information + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_login $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + push @sections, $_ if $_ ne ""; + + # Print the section-specific navigation bar + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + if ($$args{"admin"}) { + html_nav_admin $args; + } else { + html_nav_page $args; + } + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + push @sections, $_ if $_ ne ""; + + # Embrace the navigation links + print << "EOT"; + +
    + +EOT + + return; +} + +# html_login: Print the HTML log-in information +sub html_login(;$) { + local ($_, %_); + my ($args, $msg, $modify, $submit); + $args = $_[0]; + # Skip if not logged-in + return if !defined get_login_sn; + # Obtain the page parameters + $args = page_param $args; + # No log-in bar for static pages + return if $$args{"static"}; + + # The message + $modify = "/magicat/cgi-bin/users.cgi?form=cur&sn=" . get_login_sn; + $msg = sprintf __("Welcome, %s. (Modify)"), + h(get_login_name), h($modify); + $submit = h(__("Log out")); + + print << "EOT"; + +EOT + return; +} + +# html_nav_admin: Print the HTML administrative navigation bar +sub html_nav_admin(;$) { + local ($_, %_); + my ($args, $cgidir, $path, $title); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + + # Find the current CGI directory + $cgidir = "cgi-bin"; + $cgidir = $1 if $REQUEST_PATH =~ /\/(cgi-[a-z0-9]+)\/[a-z0-9]+\.cgi$/; + # Output them + foreach my $cat (@ADMIN_SCRIPTS) { + @_ = qw(); + foreach (@{$$cat{"sub"}}) { + next unless is_script_permitted $$_{"path"}; + ($path, $title) = ($$_{"path"}, $$_{"title"}); + # Fix the path to use the same cgi-* directory alias + $path =~ s/\/cgi-[a-z0-9]+\/([a-z0-9]+\.cgi)$/\/$cgidir\/$1/; + # Fix the path of the HTTPS scripts to use HTTPS + $path = "https://" . https_host . "/$PACKAGE$path" + if exists $$_{"https"} && $$_{"https"} && !is_https; + push @_, sprintf(" %s", + h($path), h_abbr(__($title))); + } + next if @_ == 0; + $title = $$cat{"title"}; + $_ = sprintf(__("%s:"), h_abbr(__($title))); + print "
    \n" + . $_ . "\n" . join(" |\n", @_) . "\n" + . "
    \n" + if @_ > 0; + } + return; +} + +# html_nav_page: Print the HTML page navigation bar +sub html_nav_page(;$) { + local ($_, %_); + my ($args, $tree); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + # Obtain the page tree + $tree = merged_tree $$args{"path"}, $$args{"lang"}, $$args{"preview"}; + # Bounce for nothing + return if !defined $tree + || !exists $$tree{"pages"} + || !defined $$tree{"pages"} + || @{$$tree{"pages"}} <= 1; + + # Output them + print << "EOT"; + +EOT + return; +} + +# html_body: Print the HTML body +sub html_body($;$) { + local ($_, %_); + my ($page, $args); + ($page, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Output the picture + # To be done + + # Output the content + print "" . (!exists $$page{"html"} || !$$page{"html"}? + a2html($$page{"body"}): $$page{"body"}) . "\n\n"; + + return; +} + +# html_links: Print the HTML links list +sub html_links($;$) { + local ($_, %_); + my ($page, $args); + ($page, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Output the breadcrumb trai + @_ = qw(); + push @_, "" . h(__("Related Links")) . ""; + foreach my $parent (@{$$page{"parents"}}) { + push @_, "" + . h($$parent{"title"}) . ""; + } + push @_, h($$page{"title"}); + print "
    \n" + . join(" /\n", @_) . "\n
    \n\n"; + + # Output the subcategories + if (@{$$page{"scats"}} > 0) { + print "

    " . h(__("Subcategories:")) . "

    \n\n
      \n"; + foreach my $cat (@{$$page{"scats"}}) { + $_ = h($$cat{"title"}); + $_ .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
    1. " + . "$_
    2. \n"; + } + print "
    \n\n"; + } + + # Output the links + if (@{$$page{"links"}} > 0) { + my $emailalt; + $emailalt = h(__("E-mail")); + print "
      \n"; + foreach my $link (@{$$page{"links"}}) { + my ($url, $title, $ctitle, $dsc); + $url = h($$link{"url"}); + $title = h($$link{"title"}); + print "
    1. \n"; + print "
      \n
      \n" + if defined $$link{"email"}; + # Output the link icon + print "\"$title\"
      \n" + if defined $$link{"icon"}; + # Output the site title + $ctitle = is_usascii_printable($$link{"title"})? + "$title": $title; + if (defined $$link{"title_2ln"}) { + $_ = h($$link{"title_2ln"}); + $_ = "$_" + if is_usascii_printable($$link{"title_2ln"}); + $ctitle .= " $_"; + } + print "$ctitle
      \n"; + # Output the URL + print __("URL:") . " $url
      \n"; + # Output other information + if (defined $$link{"email"}) { + print __("E-mail:") . " "; + print "\n"; + print "\n"; + print mung_email_span(h($$link{"email"})) . "
      \n"; + } + print __("Address:") . " " . h($$link{"addr"}) . "
      \n" + if defined $$link{"addr"}; + print __("Tel.:") . " " . h($$link{"tel"}) . "
      \n" + if defined $$link{"tel"}; + print __("Fax.:") . " " . h($$link{"fax"}) . "
      \n" + if defined $$link{"fax"}; + # Output the description + $dsc = $$link{"dsc"}; + print h($dsc) . "
      \n"; + print "
      \n
      \n" if defined $$link{"email"}; + print "
    2. \n\n"; + } + print "
    \n\n"; + } + + return; +} + +# html_links_index: Print the HTML link categories index +sub html_links_index(\@;$) { + local ($_, %_); + my ($cats, $args); + ($cats, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Bounce for nothing + if (@$cats == 0) { + print "

    " . h(__("The database is empty.")) . "

    \n\n"; + return; + } + + # Output the root categories + print << "EOT"; +
      +EOT + foreach my $cat (@$cats) { + $_ = h($$cat{"title"}); + $_ .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
    • " + . "$_
    • \n"; + } + print << "EOT"; +
    + +EOT + return; +} + +# html_footer: Print the HTML footer +sub html_footer(;$) { + local ($_, %_); + my ($args, $lang); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + $lang = $$args{"lang"}; + + # Embrace the content + print << "EOT"; +
    + +EOT + # Print the section-specific navigation bar + print "
    \n" . $$args{"footer_html_nav"} . "\n\n" + if exists $$args{"footer_html_nav"}; + + # Print the common footer + $FOOTER{"file"} = sprintf("%s/magicat/include/footer.html", $DOC_ROOT) + if !exists $FOOTER{"file"}; + undef $_; + if ( !exists $FOOTER{"content"} + || !exists $FOOTER{"date"} + || $FOOTER{"date"} < ($_ = (stat $FOOTER{"file"})[9])) { + $_ = (stat $FOOTER{"file"})[9] if !defined $_; + $FOOTER{"date"} = $_; + $FOOTER{"content"} = hcref_decode ln($lang, LN_CHARSET), xfread $FOOTER{"file"}; + } + $_ = $FOOTER{"content"}; + $FOOTER{"perl"} = {} if !exists $FOOTER{"perl"}; + if ($$args{"static"}) { + s/\n+\n+/\n\n/; + } elsif ($IS_MODPERL) { + if (!exists ${$FOOTER{"perl"}}{"modperl"}) { + ${$FOOTER{"perl"}}{"modperl"} = << "EOT"; +
    +%s +

    %s

    +
    +EOT + ${$FOOTER{"perl"}}{"modperl"} = sprintf(${$FOOTER{"perl"}}{"modperl"}, + h(__("mod_perl -- Speed, Power, Scalability")), + __("This script is written in Perl and optimized for mod_perl.")); + ${$FOOTER{"perl"}}{"modperl"} =~ s/()/$1 hreflang="en"$2/g + if $lang ne "en"; + } + s/\n/${$FOOTER{"perl"}}{"modperl"}/; + } else { + if (!exists ${$FOOTER{"perl"}}{"cgi"}) { + ${$FOOTER{"perl"}}{"cgi"} = << "EOT"; +
    +

    %s

    +
    +EOT + ${$FOOTER{"perl"}}{"cgi"} = sprintf(${$FOOTER{"perl"}}{"cgi"}, + __("This script is written in
    Perl.")); + ${$FOOTER{"perl"}}{"cgi"} =~ s/()/$1 hreflang="en"$2/g + if $lang ne "en"; + } + s/\n/${$FOOTER{"perl"}}{"cgi"}/; + } + print $_; + + # Show the HTML preview mark + html_preview_mark $args; + + print "\n\n\n"; + return; +} + +# merged_tree: Get the page tree in a directory +sub merged_tree($$;$) { + local ($_, %_); + my ($path, $lang, $preview); + ($path, $lang, $preview) = @_; + + # Return special areas + if ($path =~ /^\/links\//) { + return link_tree($path, $lang, $preview); + # Non-pages (scripts... etc) + } else { + return {}; + } +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Items.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Items.pm new file mode 100644 index 0000000..5e4c2f5 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Items.pm @@ -0,0 +1,174 @@ +# History: Theory and Culture +# Items.pm: The data record related subroutines. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-28 + +package Selima::htc::Items; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(new_nl_no newslet_textno newslet_title newslet_no); +push @EXPORT, qw(nlindex_title nlart_title); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub new_nl_no(); +sub newslet_textno($); +sub newslet_title($); +sub newslet_no($); +sub nlindex_title($); +sub nlart_title($); +} + +use Encode qw(encode); +use Lingua::ZH::Numbers; + +use Selima::ChkFunc; +use Selima::CommText; +use Selima::DataVars qw($DBH); + +# new_nl_no: Get the issue number for a new newsletter +sub new_nl_no() { + local ($_, %_); + my ($sql, $sth); + $sql = "SELECT no FROM newslets" + . " ORDER BY no DESC LIMIT 1;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return 1 if $sth->rows < 1; + return ${$sth->fetch}[0] + 1; +} + +# newslet_textno: Obtain the text representation of the issue number +sub newslet_textno($) { + local ($_, %_); + $_ = $_[0]; + # Invalid - returned "as is" + return $_ if !defined $_ || /\D/ || $_ < 0; + # First issue + return "創刊號" if $_ == 1; + Lingua::ZH::Numbers->charset("traditional"); + return "第" . number_to_zh($_) . "期"; +} + +# newslet_title: Obtain a newsletter title +sub newslet_title($) { + local ($_, %_); + my ($sn, $sql, $sth, $row); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + + # Check the serial number first + return t_na if !check_sn $sn; + + # Query + $sql = "SELECT no, title FROM newslets" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return t_na unless $sth->rows == 1; + + # Found + $row = $sth->fetchrow_hashref; + $_ = newslet_textno $$row{"no"}; + $_ .= ":「" . $$row{"title"} . "」專號" if defined $$row{"title"}; + return $_; +} + +# newslet_no: Obtain a newsletter number +sub newslet_no($) { + local ($_, %_); + my ($sn, $sql, $sth); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + + # Check the serial number first + return t_na if !check_sn $sn; + + # Query + $sql = "SELECT no FROM newslets" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return t_na unless $sth->rows == 1; + + # Found + return ${$sth->fetch}[0]; +} + +# nlindex_title: Obtain a newsletter index item title +sub nlindex_title($) { + local ($_, %_); + my ($sn, $sql, $sth); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + + # Check the serial number first + return t_na if !check_sn $sn; + + # Query + $sql = "SELECT nlindex_fulltitle(parent, COALESCE(nlindex.title, nlarts.title)) AS title FROM nlindex" + . " LEFT JOIN nlarts ON nlindex.art=nlarts.sn" + . " WHERE nlindex.sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return t_na unless $sth->rows == 1; + + # Found + return ${$sth->fetch}[0]; +} + +# nlart_title: Obtain a newsletter article title +sub nlart_title($) { + local ($_, %_); + my ($sn, $sql, $sth); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + + # Check the serial number first + return t_na if !check_sn $sn; + + # Query + $sql = "SELECT title FROM nlarts" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return t_na unless $sth->rows == 1; + + # Found + return ${$sth->fetch}[0]; +} + +no utf8; +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/L10N.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/L10N.pm new file mode 100644 index 0000000..57ef839 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/L10N.pm @@ -0,0 +1,38 @@ +# History: Theory and Culture +# L10N.pm: The localization class. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-26 + +package Selima::htc::L10N; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +return 1; + +# The Chinese (Taiwan) localized messages. +package Selima::htc::L10N::zh_tw; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +sub numerate : method { $_[2] } + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/List/Guestbook.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/List/Guestbook.pm new file mode 100644 index 0000000..6e9d1dd --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/List/Guestbook.pm @@ -0,0 +1,47 @@ +# History: Theory and Culture +# Guestbook.pm: The administrative guestbook message list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::htc::List::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Guestbook); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "guestbook" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Message"): + __("Manage the Guestbook"); + # Column labels + $self->col_labels( + "identity" => __("Occupation"), + ); + return $self; +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/List/Guestbook/Public.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/List/Guestbook/Public.pm new file mode 100644 index 0000000..e8a3169 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/List/Guestbook/Public.pm @@ -0,0 +1,36 @@ +# History: Theory and Culture +# Public.pm: The guestbook message list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::htc::List::Guestbook::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Guestbook::Public); + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + return $self; +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/List/NLArts.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/List/NLArts.pm new file mode 100644 index 0000000..d58b99f --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/List/NLArts.pm @@ -0,0 +1,98 @@ +# History: Theory and Culture +# NLArts.pm: The newsletter article list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-28 + +package Selima::htc::List::NLArts; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "nlarts" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Newsletter Article"): + __("Manage Newsletter Articles"); + # Columns that should display its brief instead + push @{$self->{"COLS_BRIEF"}}, qw(body annots); + # Column labels + $self->col_labels( + "newslet" => __("Newsletter"), + "title_h" => __("HTML title"), + "author" => __("Author"), + "authors" => __("Authors column"), + "annots" => __("Annotations"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Add a new article.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for an article:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article].", $self->{"total"}); + # List result + } else { + return __("[*,_1,article].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/List/NLIndex.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/List/NLIndex.pm new file mode 100644 index 0000000..05beaa3 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/List/NLIndex.pm @@ -0,0 +1,93 @@ +# History: Theory and Culture +# NLIndex.pm: The newsletter index list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-28 + +package Selima::htc::List::NLIndex; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "nlindex" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Newsletter Index Item"): + __("Manage Newsletter Index"); + # Column labels + $self->col_labels( + "newslet" => __("Newsletter"), + "art" => __("Article"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Add a new index item.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for an index item:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,index item].", $self->{"total"}); + # List result + } else { + return __("[*,_1,index item].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,index item], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,index item], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/List/Newslets.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/List/Newslets.pm new file mode 100644 index 0000000..55d7323 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/List/Newslets.pm @@ -0,0 +1,97 @@ +# History: Theory and Culture +# Newslets.pm: The newsletter list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-28 + +package Selima::htc::List::Newslets; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "newslets" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Newsletter"): + __("Manage Newsletters"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "-no"; + # Columns that should display its brief instead + push @{$self->{"COLS_BRIEF"}}, qw(credits); + # Column labels + $self->col_labels( + "no" => __("Issue"), + "credits" => __("Credits"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Add a new newsletter.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a newsletter:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,newsletter].", $self->{"total"}); + # List result + } else { + return __("[*,_1,newsletter].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,newsletter], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,newsletter], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/List/Search.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/List/Search.pm new file mode 100644 index 0000000..838a807 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/List/Search.pm @@ -0,0 +1,181 @@ +# History: Theory and Culture +# Search.pm: The web site full-text search result list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-28 + +package Selima::htc::List::Search; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::Logging; +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The page title + if (!defined $self->{"query"}) { + $self->{"title"} = __("Full Text Search"); + } else { + $self->{"title"} = __("Search Result"); + } + $self->{"view"} = "search_list"; + $self->{"COLS_NO_SEARCH"} = [qw(section path date html)]; + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my $self; + $self = $_[0]; + # No search specified + if (!defined $self->{"query"}) { + $self->{"total"} = undef; + return $self->{"error"}; + } + # Check the query phrase + # Regularize it + $self->{"query"} =~ s/^\s*(.*?)\s*$/$1/; + # Check if it is filled + if ($self->{"query"} eq"") { + $self->{"total"} = undef; + $self->{"error"} = {"msg"=>N_("Please fill in your query.")}; + return $self->{"error"}; + } + # Run the parent method + $self->SUPER::fetch; + # Add an activity log record + actlog("Query with phrase \"" . $self->{"query"} . "\"."); + # Done + return $self->{"error"}; +} + +# sql_orderby: Get the SQL ORDER BY phase +# Always return nothing +sub sql_orderby : method { return ""; } + +# html_newlink: Display a link to add a new item +# Make it a null function +sub html_newlink : method {} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search in the website:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article].", $self->{"total"}); + # List result + } else { + return __("[*,_1,article].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +# html_list: List the items +sub html_list : method { + local ($_, %_); + my ($self); + $self = $_[0]; + # Do not show the list + return if !defined $self->{"total"}; + # No record to be listed + return if $self->{"total"} == 0; + + print << "EOT"; +
      +EOT + + # Print each record + foreach my $current (@{$self->{"current"}}) { + my ($url, $abstract); + $url = h($$current{"path"}); + $abstract = $self->query_abstract($current); + if ($$current{"section"} eq "pages") { + my $title; + $title = h($$current{"title"}); + + print << "EOT"; +
    1. $title

      +EOT + } elsif ($$current{"section"} eq "links") { + my ($title, $sectitle); + $title = h($$current{"title"}); + $sectitle = h(__("Related Links")); + + print << "EOT"; +
    2. $title

      +
      $sectitle
      +EOT + } elsif ($$current{"section"} eq "guestbook") { + my ($author, $title, $sectitle); + $author = defined $$current{"author"}? + " " . h($$current{"author"}) . "": ""; + $title = h(__("Guestbook Message on [_1]", $$current{"date"})); + $sectitle = h(__("Guestbook")); + + print << "EOT"; +
    3. $title$author

      +
      $sectitle
      +EOT + } + print "\n

      $abstract

      \n" if defined $abstract; + print << "EOT"; +
    4. + +EOT + } + print << "EOT"; +
    + +EOT + return; +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Processor/Guestbook/Public.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Processor/Guestbook/Public.pm new file mode 100644 index 0000000..402eb95 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Processor/Guestbook/Public.pm @@ -0,0 +1,141 @@ +# History: Theory and Culture +# Public.pm: The guestbook data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-19 + +package Selima::htc::Processor::Guestbook::Public; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Selima::Processor::Guestbook); + +use Selima::Country; +use Selima::DataVars qw(:env :input :scptconf); +use Selima::Format; +use Selima::Guest; +use Selima::GeoIP; +use Selima::RemoHost; +use Selima::Unicode; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[0]->param("form", "new"); + $_[0]->param("confirm", 1); + $self = $class->SUPER::new(@_); + $self->{"notify"} = 1; + $self->{"debug"} = 1; + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my $self; + ($self, @_) = @_; + $self->SUPER::_save_cols(@_); + $self->{"cols"}->{"login"} = 723676436; + return; +} + +# _other_tasks: Perform tasks other than column updates +sub _other_tasks : method { + local ($_, %_); + my ($self, $form); + my ($mail, $body, $charset); + $self = $_[0]; + return unless $self->{"notify"}; + $form = $self->{"form"}; + + # Compose the mail body + $body = ""; + $body .= "若要編輯或刪除這則留言,請連上以下網址:\n"; + $body .= "http://" . $ENV{"SERVER_NAME"} . "/magicat/cgi-bin/guestbook.cgi" + . "?form=cur&sn=" . $self->{"sn"} . "\n\n"; + $body .= "日期: " . fmttime . "\n"; + @_ = qw(); + push @_, ctname_zhtw country_lookup; + push @_, remote_host if defined remote_host; + $body .= "來自: " . $ENV{"REMOTE_ADDR"} + . " (" . join(", ", @_) . ")\n"; + $body .= "簽名: " . $form->param("name") . "\n" + if $form->param("name") ne ""; + $body .= "職業: " . $form->param("identity") . "\n" + if $form->param("identity") ne ""; + $body .= "所在地: " . $form->param("location") . "\n" + if $form->param("location") ne ""; + $body .= "E-mail : " . $form->param("email") . "\n" + if $form->param("email") ne ""; + $body .= "網站網址: " . $form->param("url") . "\n" + if $form->param("url") ne "" && $form->param("url") ne "http://"; + $body .= "留言:\n\n" . $form->param("message") . "\n\n"; + $body .= "原始內容:\n" . $USER_INPUT{"POST_RAWDATA"} . "\n"; + + # Collecting Debugging infomation + if ($self->{"debug"}) { + $body .= "\n"; + $body .= "===== Start Debugging Infomation =====\n"; + if ($IS_MODPERL) { + $_ = $IS_MP2? Apache2::RequestUtil->request->as_string: + Apache->request->as_string; + s/^X-Selima-[^\n]+\n//mg; + s/^((?:[^\n]+\n)+).+?$/$1/s; + $body .= $_; + } else { + foreach (sort grep !/^HTTP_X_SELIMA_/, grep /^HTTP_/, keys %ENV) { + my $hname; + $hname = $_; + $hname =~ s/^HTTP_//; + $hname =~ s/_/-/g; + $hname =~ s/(\w)(\w+)/$1 . lc $2/ge; + $body .= "$hname: $ENV{$_}\n"; + } + } + $body .= "===== End Debugging Infomation =====\n"; + } + + # Set the best appropriate output character set + $charset = is_charset($body, "Big5")? "Big5": "UTF-8"; + + # Compose the mail + $mail = new Selima::Mail; + $mail->charset($charset); + $mail->from($THIS_FILE . "\@" . $ENV{"SERVER_NAME"}, "歷史:理論與文化網站留言板"); + $mail->to("htc\@mail.emandy.idv.tw", "歷史:理論與文化編輯"); + $mail->subject("[HTC] 留言板留言通知 " . fmtdate); + $mail->body($body); + # Send it + $mail->send; + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my $self; + $self = $_[0]; + # A form to create a new item + return gactlog "Post a new message on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "."; +} + +no utf8; +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Processor/NLArt.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Processor/NLArt.pm new file mode 100644 index 0000000..50b416f --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Processor/NLArt.pm @@ -0,0 +1,132 @@ +# History: Theory and Culture +# NLArt.pm: The newsletter article processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-30 + +package Selima::htc::Processor::NLArt; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw(:addcol); +use Selima::Guest; +use Selima::ShortCut; + +use Selima::htc::Items; +use Selima::htc::Rebuild; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "nlarts" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("newslet", $self->_form("newslet")); + $self->{"cols"}->addnum("ord", $self->_form("ord")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("title_h", $self->_form("title_h")); + $self->{"cols"}->addstr("author", $self->_form("author")); + $self->{"cols"}->addstr("email", $self->_form("email")); + $self->{"cols"}->addstr("authors", $self->_form("authors")); + $self->{"cols"}->addstr("body", $self->_form("body")); + $self->{"cols"}->addstr("annots", $self->_form("annots")); + $self->{"cols"}->addstr("kw", $self->_form("kw")); + $self->{"cols"}->addbool("html", $self->_form("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("newslet", $self->_form("newslet"), scalar $cur->param("newslet")); + $self->{"cols"}->addnum("ord", $self->_form("ord"), scalar $cur->param("ord")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("title_h", $self->_form("title_h"), scalar $cur->param("title_h")); + $self->{"cols"}->addstr("author", $self->_form("author"), scalar $cur->param("author")); + $self->{"cols"}->addstr("email", $self->_form("email"), scalar $cur->param("email")); + $self->{"cols"}->addstr("authors", $self->_form("authors"), scalar $cur->param("authors")); + $self->{"cols"}->addstr("body", $self->_form("body"), scalar $cur->param("body")); + $self->{"cols"}->addstr("annots", $self->_form("annots"), scalar $cur->param("annots")); + $self->{"cols"}->addstr("kw", $self->_form("kw"), scalar $cur->param("kw")); + $self->{"cols"}->addbool("html", $self->_form("html"), scalar $cur->param("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a newsletter article " . $form->param("title") + . " in newsletter No. " . newslet_no($form->param("newslet")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the newsletter article " . $form->param("title") + . " in newsletter No. " . newslet_no($form->param("newslet")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the newsletter article " . $cur->param("title") + . " in newsletter No. " . newslet_no($cur->param("newslet")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This article was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This article has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This article has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This article has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm new file mode 100644 index 0000000..378f25c --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm @@ -0,0 +1,122 @@ +# History: Theory and Culture +# NLIndex.pm: The newsletter index data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-29 + +package Selima::htc::Processor::NLIndex; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw(:addcol); +use Selima::Guest; +use Selima::ShortCut; + +use Selima::htc::Items; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "nlindex" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur, $o); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + if ($self->{"type"} ne "del") { + # Set the "topmost" parent + $form->delete("parent") if defined $form->param("topmost") + && $form->param("topmost") eq "true"; + } + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("newslet", $self->_form("newslet")); + $self->{"cols"}->addnum("parent", $self->_form("parent")); + $self->{"cols"}->addnum("ord", $self->_form("ord")); + $self->{"cols"}->addnum("art", $self->_form("art")); + $self->{"cols"}->addstr("title", $self->_form("title")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("newslet", $self->_form("newslet"), scalar $cur->param("newslet")); + $self->{"cols"}->addnum("parent", $self->_form("parent"), scalar $cur->param("parent")); + $self->{"cols"}->addnum("ord", $self->_form("ord"), scalar $cur->param("ord")); + $self->{"cols"}->addnum("art", $self->_form("art"), scalar $cur->param("art")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a newsletter index item " . $form->param("title") + . " for newsletter No. " . newslet_no($form->param("newslet")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the newsletter index item " . $form->param("title") + . " for newsletter No. " . newslet_no($form->param("newslet")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the newsletter index item " . $cur->param("title") + . " for newsletter No. " . newslet_no($cur->param("newslet")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This index item was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This index item has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This index item has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This index item has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Processor/Newslet.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Processor/Newslet.pm new file mode 100644 index 0000000..04bdb17 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Processor/Newslet.pm @@ -0,0 +1,121 @@ +# History: Theory and Culture +# Newslet.pm: The newsletter data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-29 + +package Selima::htc::Processor::Newslet; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw(:addcol); +use Selima::Guest; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "newslets" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur, $o); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("no", $self->_form("no")); + $self->{"cols"}->adddate("date", $self->_form("date")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("credits", $self->_form("credits")); + $self->{"cols"}->addstr("kw", $self->_form("kw")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("no", $self->_form("no"), scalar $cur->param("no")); + $self->{"cols"}->adddate("date", $self->_form("date"), scalar $cur->param("date")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("credits", $self->_form("credits"), scalar $cur->param("credits")); + $self->{"cols"}->addstr("kw", $self->_form("kw"), scalar $cur->param("kw")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + # Find the changed items + $_ = new CGI(""); + $_->param("cond", "newslet=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($_, "nlarts"); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a newsletter No. " . $form->param("no") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the newsletter No. " . $form->param("no") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the newsletter No. " . $cur->param("no") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This newsletter was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This newsletter has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This newsletter has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This newsletter has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/htdocs/htc/magicat/lib/perl5/Selima/htc/Rebuild.pm b/htdocs/htc/magicat/lib/perl5/Selima/htc/Rebuild.pm new file mode 100644 index 0000000..8efac60 --- /dev/null +++ b/htdocs/htc/magicat/lib/perl5/Selima/htc/Rebuild.pm @@ -0,0 +1,290 @@ +# History: Theory and Culture +# Rebuild.pm: The subroutines to rebuild the web pages. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +package Selima::htc::Rebuild; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(rebuild_all rebuild_pages rebuild_links rebuild_newslets compose_page); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub rebuild_all(); +sub rebuild_pages(;$); +sub rebuild_links(;$); +sub rebuild_newslets(@); +sub compose_page($;$); +} + +use Data::Dumper qw(); +use Fcntl qw(:flock); +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use Selima::DataVars qw($DBH :output :rebuild); +use Selima::GetLang; +use Selima::Guest; +use Selima::PageFunc; +use Selima::ShortCut; + +use Selima::htc::HTML; + +use vars qw($PKGL10N); + +# rebuild_all: Rebuild everything +sub rebuild_all() { + local ($_, %_); + # Lock the required tables + $DBH->lock(map { $_ => LOCK_SH } @REBUILD_TABLES); + # Rebuild the pages + rebuild_pages; + # Rebuild the links + rebuild_links; + # Rebuild the index + # To be done + #rebuild_index; + return; +} + +# rebuild_pages: Rebuild the pages +sub rebuild_pages(;$) { + local ($_, %_); + my ($sql, $sth, $count, $rebuild_everything); + my $lang; + $sql = $_[0]; + + $lang = getlang; + + # Rebuild everything + $rebuild_everything = !defined $sql; + if ($rebuild_everything) { + $sql = "SELECT * FROM pages" + . " WHERE NOT hid;\n"; + } + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + # Bounce if no pages to build on a partial rebuild + # This prevents needless sitemap rebuilding + return if !$rebuild_everything && $count == 0; + # Build each page + for (my $i = 0; $i < $count; $i++) { + my ($page, $html); + $page = $sth->fetchrow_hashref; + # Read the picture into the picture deposit + # To be done + + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + + # Output related pictures only when rebuilding everything + # To be done + } + + return; +} + +# rebuild_links: Rebuild the links +sub rebuild_links(;$) { + local ($_, %_); + my ($sql, $sth, $count, $FD, $rebuild_everything); + my ($lang, $args, $html); + $sql = $_[0]; + + $lang = getlang; + + # Rebuild everything + $rebuild_everything = !defined $sql; + if ($rebuild_everything) { + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_isshown(sn, hid, parent);\n"; + } + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0; $i < $count; $i++) { + my ($page, $sql1, $sth1, $count1, $row1); + $page = $sth->fetchrow_hashref; + + # Find the ancesters + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql1 = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_ischild(sn, " . $$page{"sn"} . ")" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"parents"} = []; $i < $count1; $i++) { + push @{$$page{"parents"}}, $sth1->fetchrow_hashref; + } + + # Find the subcategories + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql1 = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE parent=" . $$page{"sn"} + . " AND linkcat_isshown(sn, hid, parent)" + . " ORDER BY ord;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"scats"} = []; $i < $count1; $i++) { + my ($sql2, $sth2, $row2); + $row1 = $sth1->fetchrow_hashref; + # Find the belonging links + $sql2 = "SELECT count(linkcatz.sn) AS count FROM linkcatz" + . " INNER JOIN links ON linkcatz.link=links.sn" + . " INNER JOIN linkcat ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.cat=" . $$row1{"sn"} + . " AND NOT links.hid;\n"; + $sth2 = $DBH->prepare($sql2); + $sth2->execute; + $row2 = $sth2->fetchrow_hashref; + $$row1{"links"} = $$row2{"count"}; + push @{$$page{"scats"}}, $row1; + } + + # Find the belonging links + @_ = map "links.$_", $DBH->cols("links"); + $sql1 = "SELECT " . join(", ", @_) . " FROM links" + . " INNER JOIN linkcatz ON linkcatz.link=links.sn" + . " WHERE linkcatz.cat=" . $$page{"sn"} + . " AND NOT links.hid;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"links"} = []; $i < $count1; $i++) { + push @{$$page{"links"}}, $sth1->fetchrow_hashref; + } + + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + } + + # Build the root index page + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE parent IS NULL" + . " AND linkcat_isshown(sn, hid, parent)" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @_ = qw(); $_ < $count; $_++) { + my ($cat, $sql1, $sth1, $count1); + $cat = $sth->fetchrow_hashref; + + # Find the belonging links + $sql1 = "SELECT count(linkcatz.sn) AS count FROM linkcatz" + . " INNER JOIN links ON linkcatz.link=links.sn" + . " INNER JOIN linkcat ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.cat=" . $$cat{"sn"} + . " AND NOT links.hid;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $$cat{"links"} = ${$sth1->fetch}[0]; + + push @_, $cat; + } + $ALT_PAGE_PARAM = { + "path" => "/links/", + "lang" => $lang, + "keywords" => __("related links"), + "class" => "links", + "static" => 1, + "all_linguas" => [$lang]}; + $args = page_param; + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header __("Related Links"), $args; + html_links_index @_, $args; + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $html = join "", <$FD>; + undef $ALT_PAGE_PARAM; + goutpage $html, "/links/", $lang; + + return; +} + +# rebuild_newslets: Rebuild the newsletters +sub rebuild_newslets(@) { + local ($_, %_); + return; +} + +# compose_page: Compose a page +sub compose_page($;$) { + local ($_, %_); + my ($page, $lang, $args, $FD); + ($page, $lang) = @_; + $lang = getlang if !defined $lang; + + $ALT_PAGE_PARAM = { + "path" => $$page{"path"}, + "lang" => $lang, + "keywords" => $$page{"kw"}, + "static" => 1, + "all_linguas" => [$lang]}; + $$ALT_PAGE_PARAM{"preview"} = $page + if exists $$page{"preview"}; + if (exists $$page{"class"} && defined $$page{"class"} && $$page{"class"} ne "") { + $$ALT_PAGE_PARAM{"class"} = $$page{"class"}; + } elsif ($$page{"path"} =~ /^\/links\//) { + $$ALT_PAGE_PARAM{"class"} = "links"; + } + $args = page_param; + + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header $$page{"title"}, $args; + if ($$page{"path"} =~ /^\/links\/$/) { + #html_links_index $page, $args; + } elsif ($$page{"path"} =~ /^\/links\/.+$/) { + html_links $page, $args; + } else { + html_body $page, $args; + } + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + + undef $ALT_PAGE_PARAM; + return $_; +} + +return 1; diff --git a/htdocs/htc/magicat/locale/zh_TW/LC_MESSAGES/htc.mo b/htdocs/htc/magicat/locale/zh_TW/LC_MESSAGES/htc.mo new file mode 100644 index 0000000..46d4832 Binary files /dev/null and b/htdocs/htc/magicat/locale/zh_TW/LC_MESSAGES/htc.mo differ diff --git a/htdocs/htc/magicat/po/Makefile b/htdocs/htc/magicat/po/Makefile new file mode 100644 index 0000000..923562d --- /dev/null +++ b/htdocs/htc/magicat/po/Makefile @@ -0,0 +1,44 @@ +# Possible make targets: +# all: Compile the PO files and copy the binary MO files +# into the appropriate directories +# xgettext: Obtain the newest PO template file $(PACKAGE).pot +# from the source programs +# msgmerge: Compare the template $(PACKAGE).pot and the existing +# PO files and get the newest POX files to work with. + + +PACKAGE = htc +ALLLINGUAS = zh_TW +PKGROOT = ../.. +PODIR = magicat/po +LOCALEDIR = $(PKGROOT)/magicat/locale +CATEGORY = LC_MESSAGES +PROGRAMS = cgi-bin/*.cgi magicat/cgi-bin/*.cgi magicat/lib/perl5/*/*.pm magicat/lib/perl5/*/*/*.pm magicat/lib/perl5/*/*/*/*.pm magicat/lib/perl5/*/*/*/*/*.pm + +all: + for ln in $(ALLLINGUAS); do \ + msgfmt $$ln.po -o $$ln.gmo; \ + test -d $(LOCALEDIR) || \ + (rm -rf $(LOCALEDIR) && \ + mkdir $(LOCALEDIR)); \ + test -d $(LOCALEDIR)/$$ln || \ + (rm -rf $(LOCALEDIR)/$$ln && \ + mkdir $(LOCALEDIR)/$$ln); \ + test -d $(LOCALEDIR)/$$ln/$(CATEGORY) || \ + (rm -rf $(LOCALEDIR)/$$ln/$(CATEGORY) && \ + mkdir $(LOCALEDIR)/$$ln/$(CATEGORY)); \ + rm -f $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + cp $$ln.gmo $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + done + +xgettext: + cd $(PKGROOT); \ + xgettext --keyword=__ --keyword=N_ -p $(PODIR)/ -o $(PACKAGE).pot \ + --language=c $(PROGRAMS); \ + cd $(PODIR); \ + for ln in $(ALLLINGUAS); do \ + msgmerge $$ln.po $(PACKAGE).pot > $$ln.pox; \ + done + +clean: + rm -f *.gmo diff --git a/htdocs/htc/magicat/po/htc.pot b/htdocs/htc/magicat/po/htc.pot new file mode 100644 index 0000000..d3875ac --- /dev/null +++ b/htdocs/htc/magicat/po/htc.pot @@ -0,0 +1,963 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-02-17 17:01+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: cgi-bin/guestbook.cgi:25 magicat/cgi-bin/guestbook.cgi:26 +msgid "guestbook" +msgstr "" + +#: cgi-bin/guestbook.cgi:95 magicat/lib/perl5/Selima/htc/HTML.pm:61 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:147 +msgid "Guestbook" +msgstr "" + +#: cgi-bin/search.cgi:26 +msgid "search, query, full text search" +msgstr "" + +#: magicat/cgi-bin/actlog.cgi:22 +msgid "activity, logs" +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:30 +msgid "group membership" +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:94 magicat/cgi-bin/groupmem.cgi:139 +#: magicat/cgi-bin/groups.cgi:102 magicat/cgi-bin/groups.cgi:151 +#: magicat/cgi-bin/guestbook.cgi:90 magicat/cgi-bin/guestbook.cgi:136 +#: magicat/cgi-bin/linkcat.cgi:101 magicat/cgi-bin/linkcat.cgi:154 +#: magicat/cgi-bin/linkcatz.cgi:94 magicat/cgi-bin/linkcatz.cgi:139 +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:137 +#: magicat/cgi-bin/newslets.cgi:128 magicat/cgi-bin/newslets.cgi:173 +#: magicat/cgi-bin/nlarts.cgi:93 magicat/cgi-bin/nlarts.cgi:140 +#: magicat/cgi-bin/nlindex.cgi:97 magicat/cgi-bin/nlindex.cgi:146 +#: magicat/cgi-bin/pages.cgi:96 magicat/cgi-bin/pages.cgi:140 +#: magicat/cgi-bin/scptpriv.cgi:92 magicat/cgi-bin/scptpriv.cgi:137 +#: magicat/cgi-bin/usermem.cgi:94 magicat/cgi-bin/usermem.cgi:139 +#: magicat/cgi-bin/userpref.cgi:92 magicat/cgi-bin/userpref.cgi:137 +#: magicat/cgi-bin/users.cgi:111 magicat/cgi-bin/users.cgi:175 +msgid "Incorrect form: [_1]." +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:186 magicat/cgi-bin/usermem.cgi:186 +msgid "Please select the membership record." +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:194 magicat/cgi-bin/usermem.cgi:194 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/groups.cgi:34 +msgid "groups" +msgstr "" + +#: magicat/cgi-bin/groups.cgi:198 +msgid "Please select the group." +msgstr "" + +#: magicat/cgi-bin/groups.cgi:206 +msgid "This group does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/guestbook.cgi:183 +msgid "Please select the message." +msgstr "" + +#: magicat/cgi-bin/guestbook.cgi:191 +msgid "This message does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:29 +msgid "link categories" +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:90 magicat/cgi-bin/linkcat.cgi:143 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:94 magicat/cgi-bin/linkcat.cgi:147 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:202 +msgid "Please select the category." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:210 +msgid "This category does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:30 +msgid "link categorization" +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:186 +msgid "Please select the categorization record." +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:194 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "" + +#: magicat/cgi-bin/links.cgi:28 magicat/lib/perl5/Selima/htc/Rebuild.pm:208 +msgid "related links" +msgstr "" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Please select the related link." +msgstr "" + +#: magicat/cgi-bin/links.cgi:193 +msgid "This related link does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/logout.cgi:25 +msgid "log out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:98 magicat/cgi-bin/logout.cgi:105 +msgid "Log Out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:121 +msgid "Are you sure you want to log out?" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:122 magicat/lib/perl5/Selima/htc/HTML.pm:361 +msgid "Log out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:138 +msgid "Log in again." +msgstr "" + +#: magicat/cgi-bin/newslets.cgi:31 +msgid "newsletters" +msgstr "" + +#: magicat/cgi-bin/newslets.cgi:226 +msgid "Please select the newsletter." +msgstr "" + +#: magicat/cgi-bin/newslets.cgi:234 +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:140 +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:47 +msgid "This newsletter does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/nlarts.cgi:29 +msgid "newsletter articles" +msgstr "" + +#: magicat/cgi-bin/nlarts.cgi:187 +msgid "Please select the article." +msgstr "" + +#: magicat/cgi-bin/nlarts.cgi:195 +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:111 +msgid "This article does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/nlindex.cgi:29 +msgid "newsletter indices" +msgstr "" + +#: magicat/cgi-bin/nlindex.cgi:90 magicat/cgi-bin/nlindex.cgi:139 +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:78 +msgid "" +"This index item has [numerate,_1,a subitem,subitems]. It cannot be " +"deleted. To delete the index item, [numerate,_1,its subitem,all of its " +"subitems] must first be deleted." +msgstr "" + +#: magicat/cgi-bin/nlindex.cgi:193 +msgid "Please select the index item." +msgstr "" + +#: magicat/cgi-bin/nlindex.cgi:201 +msgid "This index item does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/pages.cgi:26 +msgid "pages" +msgstr "" + +#: magicat/cgi-bin/pages.cgi:193 +msgid "Please select the page." +msgstr "" + +#: magicat/cgi-bin/pages.cgi:201 +msgid "This page does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/rebuild.cgi:23 +msgid "rebuild pages" +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:28 +msgid "script privilege" +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:184 +msgid "Please select the script privilege record." +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:192 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "" + +#: magicat/cgi-bin/usermem.cgi:30 +msgid "user membership" +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:28 +msgid "user preference" +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:184 +msgid "Please select the user preference." +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:192 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/users.cgi:29 +msgid "users" +msgstr "" + +#: magicat/cgi-bin/users.cgi:222 +msgid "Please select the user." +msgstr "" + +#: magicat/cgi-bin/users.cgi:230 +msgid "This user does not exist anymore. Please select another one." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:59 +msgid "Manage Content" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:63 +msgid "Pages" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:65 +msgid "Links" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:67 +msgid "Link Categories" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:69 +msgid "Link Categorization" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:71 +msgid "Newsletters" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:73 +msgid "Newsletter Indices" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:75 +msgid "Newsletter Articles" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:79 +msgid "Manage Accounts" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:81 +msgid "Users" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:83 +msgid "Groups" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:85 +msgid "User Membership" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:87 +msgid "Group Membership" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:89 +msgid "User Preferences" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:91 +msgid "Script Privileges" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:95 +msgid "Miscellaneous" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:97 +msgid "Activity Log" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:99 +msgid "Rebuild Pages" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:101 +msgid "Analog" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:103 +msgid "Test Script" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:154 +msgid "Skip to the page content area." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:155 +msgid "Page Content Area" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:288 +msgid "Navigation Links Area" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:359 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:401 +#, c-format +msgid "%s:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:471 +#: magicat/lib/perl5/Selima/htc/Rebuild.pm:216 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:136 +msgid "Related Links" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:482 +msgid "Subcategories:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:497 +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:19 +msgid "E-mail" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:522 +msgid "URL:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:525 +msgid "E-mail:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:531 +msgid "Address:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:533 +msgid "Tel.:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:535 +msgid "Fax.:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:560 +msgid "The database is empty." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:626 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:627 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:640 +msgid "" +"This script is written in Perl." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/Guestbook.pm:33 +msgid "This occupation is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:61 +msgid "Please fill in the date." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:64 +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:67 +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:69 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:89 +msgid "This credits information is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:44 +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:107 +msgid "Fill in the annotations here." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:47 +msgid "This annotations list is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:68 +msgid "This author is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:88 +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:100 +msgid "Fill in the authors column here." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:91 +msgid "This authors column is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:115 +msgid "This e-mail is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:119 +msgid "Please fill in a valid e-mail address." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:137 +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:44 +msgid "Please select a newsletter." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:163 +msgid "This HTML title is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:60 +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:75 +msgid "Please select a parent index item." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:65 +msgid "This option is invalid. Please select a proper parent index item." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:78 +msgid "" +"This parent index item does not exist anymore. Please select another one." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:82 +msgid "An index item cannot belong to itself. Please select another one." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:89 +msgid "" +"An index item cannot belong to its descendant. Please select another one." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:131 +msgid "Please fill in the title." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:137 +msgid "This title is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook.pm:18 +msgid "Occupation:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook.pm:23 +msgid "Website URL.:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:38 +msgid "Delete this newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:43 +msgid "This table provides you a form to add a new newsletter." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:46 +msgid "This table provides you a form to edit a current newsletter." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:49 +msgid "This table provides you a form to delete a newsletter." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:68 +msgid "Add a New Newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:71 +msgid "Edit a Current Newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:74 +msgid "Delete a Newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:81 +msgid "Preview this newsletter." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:102 +msgid "[numerate,_1,Article,Articles]:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:127 +msgid "Credits:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:128 +msgid "Fill in the credits here." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:133 +msgid "Hide?" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:134 +msgid "Hide this newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:134 +msgid "Show this newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:135 +msgid "Hide this newsletter currently." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:146 +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:186 +msgid "Index:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:166 +msgid "Original:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:167 +msgid "New:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:207 +msgid "Issue:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:273 +msgid "Choose" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:274 +msgid "Delete" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:275 +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:86 +msgid "Article:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:276 +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:134 +msgid "Title:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:277 +msgid "Has subitems?" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:278 +msgid "Subitems:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:279 +msgid "This item has subitems." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:36 +msgid "Delete this article" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:41 +msgid "This table provides you a form to add a new article." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:44 +msgid "This table provides you a form to edit a current article." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:47 +msgid "This table provides you a form to delete a article." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:66 +msgid "Add a New Newsletter Article" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:69 +msgid "Edit a Current Newsletter Article" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:72 +msgid "Delete a Newsletter Article" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:79 +msgid "Preview this article." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:88 +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:91 +msgid "Newsletter:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:93 +msgid "HTML title:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:94 +msgid "(Leave it blank if the same as the title.)" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:99 +msgid "Authors column:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:101 +msgid "(Leave it blank if the same as the author.)" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:106 +msgid "Annotations:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:36 +msgid "Delete this index item" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:41 +msgid "This table provides you a form to add a new index item." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:44 +msgid "This table provides you a form to edit a current index item." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:47 +msgid "This table provides you a form to delete a index item." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:64 +msgid "Add a New Newsletter Index Item" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:67 +msgid "Edit a Current Newsletter Index Item" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:70 +msgid "Delete a Newsletter Index Item" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:96 +msgid "Parent item:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:97 +msgid "At the very top" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:109 +msgid "[numerate,_1,Subitem,Subitems]:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:135 +msgid "(Leave it blank if the same as the article title.)" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Guestbook.pm:24 +msgid "Select a Message" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Guestbook.pm:25 +msgid "Manage the Guestbook" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Guestbook.pm:28 +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:24 +msgid "Occupation" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:24 +msgid "Select a Newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:25 +msgid "Manage Newsletters" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:32 +msgid "Issue" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:33 +msgid "Credits" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:41 +msgid "Add a new newsletter." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:47 +msgid "Search for a newsletter:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:64 +msgid "Your query found [*,_1,newsletter]." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:67 +msgid "[*,_1,newsletter]." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:73 +msgid "Your query found [*,_1,newsletter], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:77 +msgid "[*,_1,newsletter], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:24 +msgid "Select a Newsletter Article" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:25 +msgid "Manage Newsletter Articles" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:30 +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:28 +msgid "Newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:31 +msgid "HTML title" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:32 +msgid "Author" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:33 +msgid "Authors column" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:34 +msgid "Annotations" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:42 +msgid "Add a new article." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:48 +msgid "Search for an article:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:65 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:88 +msgid "Your query found [*,_1,article]." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:68 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:91 +msgid "[*,_1,article]." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:74 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:97 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:78 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:101 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:24 +msgid "Select a Newsletter Index Item" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:25 +msgid "Manage Newsletter Index" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:29 +msgid "Article" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:37 +msgid "Add a new index item." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:43 +msgid "Search for an index item:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:60 +msgid "Your query found [*,_1,index item]." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:63 +msgid "[*,_1,index item]." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:69 +msgid "Your query found [*,_1,index item], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:73 +msgid "[*,_1,index item], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:24 +msgid "Full Text Search" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:26 +msgid "Search Result" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:49 +msgid "Please fill in your query." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:71 +msgid "Search in the website:" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:146 +msgid "Guestbook Message on [_1]" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Processor/Newslet.pm:90 +msgid "This newsletter was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Processor/Newslet.pm:94 +msgid "This newsletter has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Processor/Newslet.pm:98 +msgid "This newsletter has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Processor/Newslet.pm:102 +msgid "This newsletter has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Processor/NLArt.pm:101 +msgid "This article was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Processor/NLArt.pm:105 +msgid "This article has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Processor/NLArt.pm:109 +msgid "This article has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Processor/NLArt.pm:113 +msgid "This article has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm:91 +msgid "This index item was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm:95 +msgid "This index item has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm:99 +msgid "This index item has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm:103 +msgid "This index item has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Checker/Guestbook/Public.pm:36 +msgid "Your occupation is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:29 +msgid "Location" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:34 +msgid "Message" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:35 +msgid "Fill in your message here." +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:40 +msgid "Signature" +msgstr "" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:45 +msgid "Website URL." +msgstr "" diff --git a/htdocs/htc/magicat/po/zh_TW.gmo b/htdocs/htc/magicat/po/zh_TW.gmo new file mode 100644 index 0000000..46d4832 Binary files /dev/null and b/htdocs/htc/magicat/po/zh_TW.gmo differ diff --git a/htdocs/htc/magicat/po/zh_TW.po b/htdocs/htc/magicat/po/zh_TW.po new file mode 100644 index 0000000..035045c --- /dev/null +++ b/htdocs/htc/magicat/po/zh_TW.po @@ -0,0 +1,969 @@ +# Traditional Chinese PO file for the HTC website +# Copyright (C) 2004-2018 imacat +# This file is distributed under the same license as the htc package. +# imacat , 2004-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: htc 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-02-17 17:01+0800\n" +"PO-Revision-Date: 2018-11-02 00:56+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: cgi-bin/guestbook.cgi:25 magicat/cgi-bin/guestbook.cgi:26 +msgid "guestbook" +msgstr "留言板" + +#: cgi-bin/guestbook.cgi:95 magicat/lib/perl5/Selima/htc/HTML.pm:61 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:147 +msgid "Guestbook" +msgstr "留言板" + +#: cgi-bin/search.cgi:26 +msgid "search, query, full text search" +msgstr "搜尋, 檢索, 全文檢索" + +#: magicat/cgi-bin/actlog.cgi:22 +msgid "activity, logs" +msgstr "活動, 記錄, 日誌" + +#: magicat/cgi-bin/groupmem.cgi:30 +msgid "group membership" +msgstr "群組成員" + +#: magicat/cgi-bin/groupmem.cgi:94 magicat/cgi-bin/groupmem.cgi:139 +#: magicat/cgi-bin/groups.cgi:102 magicat/cgi-bin/groups.cgi:151 +#: magicat/cgi-bin/guestbook.cgi:90 magicat/cgi-bin/guestbook.cgi:136 +#: magicat/cgi-bin/linkcat.cgi:101 magicat/cgi-bin/linkcat.cgi:154 +#: magicat/cgi-bin/linkcatz.cgi:94 magicat/cgi-bin/linkcatz.cgi:139 +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:137 +#: magicat/cgi-bin/newslets.cgi:128 magicat/cgi-bin/newslets.cgi:173 +#: magicat/cgi-bin/nlarts.cgi:93 magicat/cgi-bin/nlarts.cgi:140 +#: magicat/cgi-bin/nlindex.cgi:97 magicat/cgi-bin/nlindex.cgi:146 +#: magicat/cgi-bin/pages.cgi:96 magicat/cgi-bin/pages.cgi:140 +#: magicat/cgi-bin/scptpriv.cgi:92 magicat/cgi-bin/scptpriv.cgi:137 +#: magicat/cgi-bin/usermem.cgi:94 magicat/cgi-bin/usermem.cgi:139 +#: magicat/cgi-bin/userpref.cgi:92 magicat/cgi-bin/userpref.cgi:137 +#: magicat/cgi-bin/users.cgi:111 magicat/cgi-bin/users.cgi:175 +msgid "Incorrect form: [_1]." +msgstr "查無此表格: [_1] 。" + +#: magicat/cgi-bin/groupmem.cgi:186 magicat/cgi-bin/usermem.cgi:186 +msgid "Please select the membership record." +msgstr "請選擇成員關係。" + +#: magicat/cgi-bin/groupmem.cgi:194 magicat/cgi-bin/usermem.cgi:194 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "查無此成員關係,請重新選擇。" + +#: magicat/cgi-bin/groups.cgi:34 +msgid "groups" +msgstr "群組" + +#: magicat/cgi-bin/groups.cgi:198 +msgid "Please select the group." +msgstr "請選擇群組。" + +#: magicat/cgi-bin/groups.cgi:206 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: magicat/cgi-bin/guestbook.cgi:183 +msgid "Please select the message." +msgstr "請選擇要設定的留言。" + +#: magicat/cgi-bin/guestbook.cgi:191 +msgid "This message does not exist anymore. Please select another one." +msgstr "查無該留言,請改選其她留言。" + +#: magicat/cgi-bin/linkcat.cgi:29 +msgid "link categories" +msgstr "相關連結分類" + +#: magicat/cgi-bin/linkcat.cgi:90 magicat/cgi-bin/linkcat.cgi:143 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: magicat/cgi-bin/linkcat.cgi:94 magicat/cgi-bin/linkcat.cgi:147 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: magicat/cgi-bin/linkcat.cgi:202 +msgid "Please select the category." +msgstr "請選擇分類。" + +#: magicat/cgi-bin/linkcat.cgi:210 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: magicat/cgi-bin/linkcatz.cgi:30 +msgid "link categorization" +msgstr "連結分類表" + +#: magicat/cgi-bin/linkcatz.cgi:186 +msgid "Please select the categorization record." +msgstr "請選擇分類資料。" + +#: magicat/cgi-bin/linkcatz.cgi:194 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "查無此分類資料,請重新選擇。" + +#: magicat/cgi-bin/links.cgi:28 magicat/lib/perl5/Selima/htc/Rebuild.pm:208 +msgid "related links" +msgstr "相關連結" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Please select the related link." +msgstr "請選擇要設定的相關連結。" + +#: magicat/cgi-bin/links.cgi:193 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查無該相關連結,請改選其她相關連結。" + +#: magicat/cgi-bin/logout.cgi:25 +msgid "log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:98 magicat/cgi-bin/logout.cgi:105 +msgid "Log Out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:121 +msgid "Are you sure you want to log out?" +msgstr "妳確定要登出嗎?" + +#: magicat/cgi-bin/logout.cgi:122 magicat/lib/perl5/Selima/htc/HTML.pm:361 +msgid "Log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:138 +msgid "Log in again." +msgstr "重新登入。" + +#: magicat/cgi-bin/newslets.cgi:31 +msgid "newsletters" +msgstr "通訊" + +#: magicat/cgi-bin/newslets.cgi:226 +msgid "Please select the newsletter." +msgstr "請選擇通訊。" + +#: magicat/cgi-bin/newslets.cgi:234 +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:140 +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:47 +msgid "This newsletter does not exist anymore. Please select another one." +msgstr "查無此通訊,請重新選擇。" + +#: magicat/cgi-bin/nlarts.cgi:29 +msgid "newsletter articles" +msgstr "通訊文章" + +#: magicat/cgi-bin/nlarts.cgi:187 +msgid "Please select the article." +msgstr "請選擇文章。" + +#: magicat/cgi-bin/nlarts.cgi:195 +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:111 +msgid "This article does not exist anymore. Please select another one." +msgstr "查無該文,請改選其她文章。" + +#: magicat/cgi-bin/nlindex.cgi:29 +msgid "newsletter indices" +msgstr "通訊目錄" + +#: magicat/cgi-bin/nlindex.cgi:90 magicat/cgi-bin/nlindex.cgi:139 +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:78 +msgid "" +"This index item has [numerate,_1,a subitem,subitems]. It cannot be " +"deleted. To delete the index item, [numerate,_1,its subitem,all of its " +"subitems] must first be deleted." +msgstr "" +"本目錄項目下有子項,不可直接刪除。要刪除本目錄項目,請先刪除其下的子項。" + +#: magicat/cgi-bin/nlindex.cgi:193 +msgid "Please select the index item." +msgstr "請選擇目錄項目。" + +#: magicat/cgi-bin/nlindex.cgi:201 +msgid "This index item does not exist anymore. Please select another one." +msgstr "查無此目錄項目,請重新選擇。" + +#: magicat/cgi-bin/pages.cgi:26 +msgid "pages" +msgstr "網頁" + +#: magicat/cgi-bin/pages.cgi:193 +msgid "Please select the page." +msgstr "請選擇網頁。" + +#: magicat/cgi-bin/pages.cgi:201 +msgid "This page does not exist anymore. Please select another one." +msgstr "查無此頁,請改選其她網頁。" + +#: magicat/cgi-bin/rebuild.cgi:23 +msgid "rebuild pages" +msgstr "重製網頁" + +#: magicat/cgi-bin/scptpriv.cgi:28 +msgid "script privilege" +msgstr "程式權限" + +#: magicat/cgi-bin/scptpriv.cgi:184 +msgid "Please select the script privilege record." +msgstr "請選擇程式權限。" + +#: magicat/cgi-bin/scptpriv.cgi:192 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "查無該程式權限,請重新選擇。" + +#: magicat/cgi-bin/usermem.cgi:30 +msgid "user membership" +msgstr "使用者成員" + +#: magicat/cgi-bin/userpref.cgi:28 +msgid "user preference" +msgstr "使用者偏好" + +#: magicat/cgi-bin/userpref.cgi:184 +msgid "Please select the user preference." +msgstr "請選擇使用者偏好。" + +#: magicat/cgi-bin/userpref.cgi:192 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "查無該使用者偏好,請重新選擇。" + +#: magicat/cgi-bin/users.cgi:29 +msgid "users" +msgstr "帳號" + +#: magicat/cgi-bin/users.cgi:222 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: magicat/cgi-bin/users.cgi:230 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:59 +msgid "Manage Content" +msgstr "管理網站" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:63 +msgid "Pages" +msgstr "網頁" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:65 +msgid "Links" +msgstr "連結" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:67 +msgid "Link Categories" +msgstr "連結分類" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:69 +msgid "Link Categorization" +msgstr "連結分類表" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:71 +msgid "Newsletters" +msgstr "通訊" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:73 +msgid "Newsletter Indices" +msgstr "通訊目錄" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:75 +msgid "Newsletter Articles" +msgstr "通訊文章" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:79 +msgid "Manage Accounts" +msgstr "管理帳號" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:81 +msgid "Users" +msgstr "帳號" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:83 +msgid "Groups" +msgstr "群組" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:85 +msgid "User Membership" +msgstr "使用者成員" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:87 +msgid "Group Membership" +msgstr "群組成員" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:89 +msgid "User Preferences" +msgstr "使用者偏好" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:91 +msgid "Script Privileges" +msgstr "程式權限" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:95 +msgid "Miscellaneous" +msgstr "雜項" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:97 +msgid "Activity Log" +msgstr "活動日誌" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:99 +msgid "Rebuild Pages" +msgstr "重製網頁" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:101 +msgid "Analog" +msgstr "訪客統計" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:103 +msgid "Test Script" +msgstr "測試程式" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:154 +msgid "Skip to the page content area." +msgstr "跳到網頁內文區。" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:155 +msgid "Page Content Area" +msgstr "網頁內文區" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:288 +msgid "Navigation Links Area" +msgstr "導覽連結區" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:359 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "%s,妳好!(修改資料)" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:401 +#, c-format +msgid "%s:" +msgstr "%s:" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:471 +#: magicat/lib/perl5/Selima/htc/Rebuild.pm:216 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:136 +msgid "Related Links" +msgstr "相關連結" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:482 +msgid "Subcategories:" +msgstr "子類:" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:497 +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:19 +msgid "E-mail" +msgstr "E-mail" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:522 +msgid "URL:" +msgstr "網址:" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:525 +msgid "E-mail:" +msgstr "E-mail :" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:531 +msgid "Address:" +msgstr "地址:" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:533 +msgid "Tel.:" +msgstr "電話:" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:535 +msgid "Fax.:" +msgstr "傳真:" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:560 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:626 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "mod_perl -- 速度,動力,無限可能" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:627 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" +"本程式以 Perl 撰寫,專為 mod_perl 設計強化" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:640 +msgid "" +"This script is written in Perl." +msgstr "" +"本程式以 Perl 撰寫" + +#: magicat/lib/perl5/Selima/htc/Checker/Guestbook.pm:33 +msgid "This occupation is too long. (Max. length [#,_1])" +msgstr "職業太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:61 +msgid "Please fill in the date." +msgstr "請填上日期。" + +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:64 +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:67 +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:69 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期請以 YYYY-MM-DD 格式填寫。" + +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:89 +msgid "This credits information is too long. (Max. length [#,_1])" +msgstr "發行欄太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:44 +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:107 +msgid "Fill in the annotations here." +msgstr "請填上註釋。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:47 +msgid "This annotations list is too long. (Max. length [#,_1])" +msgstr "註釋太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:68 +msgid "This author is too long. (Max. length [#,_1])" +msgstr "作者太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:88 +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:100 +msgid "Fill in the authors column here." +msgstr "請填上作者欄。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:91 +msgid "This authors column is too long. (Max. length [#,_1])" +msgstr "作者欄太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:115 +msgid "This e-mail is too long. (Max. length [#,_1])" +msgstr "E-mail 太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:119 +msgid "Please fill in a valid e-mail address." +msgstr "請填上正確的 E-mail 信箱。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:137 +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:44 +msgid "Please select a newsletter." +msgstr "請選擇通訊。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:163 +msgid "This HTML title is too long. (Max. length [#,_1])" +msgstr "HTML 標題太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:60 +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:75 +msgid "Please select a parent index item." +msgstr "請選擇所屬的大項。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:65 +msgid "This option is invalid. Please select a proper parent index item." +msgstr "查無此大項,請重新選擇。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:78 +msgid "" +"This parent index item does not exist anymore. Please select another one." +msgstr "查無此大項,請重新選擇。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:82 +msgid "An index item cannot belong to itself. Please select another one." +msgstr "目錄項目不可屬於自己本身,請重新選擇。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:89 +msgid "" +"An index item cannot belong to its descendant. Please select another one." +msgstr "目錄項目不可屬於自己的子項,請重新選擇。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:131 +msgid "Please fill in the title." +msgstr "請填上標題。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:137 +msgid "This title is too long. (Max. length [#,_1])" +msgstr "標題太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook.pm:18 +msgid "Occupation:" +msgstr "職業:" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook.pm:23 +msgid "Website URL.:" +msgstr "網站網址:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:38 +msgid "Delete this newsletter" +msgstr "刪掉這期通訊" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:43 +msgid "This table provides you a form to add a new newsletter." +msgstr "本表提供建新通訊的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:46 +msgid "This table provides you a form to edit a current newsletter." +msgstr "本表提供編輯通訊的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:49 +msgid "This table provides you a form to delete a newsletter." +msgstr "本表提供刪除通訊的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:68 +msgid "Add a New Newsletter" +msgstr "建新通訊" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:71 +msgid "Edit a Current Newsletter" +msgstr "編輯通訊" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:74 +msgid "Delete a Newsletter" +msgstr "刪除通訊" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:81 +msgid "Preview this newsletter." +msgstr "預覽這期通訊。" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:102 +msgid "[numerate,_1,Article,Articles]:" +msgstr "文章:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:127 +msgid "Credits:" +msgstr "發行欄:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:128 +msgid "Fill in the credits here." +msgstr "請填上發行欄。" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:133 +msgid "Hide?" +msgstr "隱藏?" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:134 +msgid "Hide this newsletter" +msgstr "隱藏這期通訊" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:134 +msgid "Show this newsletter" +msgstr "秀出這期通訊" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:135 +msgid "Hide this newsletter currently." +msgstr "暫勿秀出這期通訊。" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:146 +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:186 +msgid "Index:" +msgstr "目錄:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:166 +msgid "Original:" +msgstr "原:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:167 +msgid "New:" +msgstr "新:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:207 +msgid "Issue:" +msgstr "期數:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:273 +msgid "Choose" +msgstr "選擇" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:274 +msgid "Delete" +msgstr "刪除" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:275 +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:86 +msgid "Article:" +msgstr "文章:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:276 +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:134 +msgid "Title:" +msgstr "標題:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:277 +msgid "Has subitems?" +msgstr "有子項?" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:278 +msgid "Subitems:" +msgstr "子項:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:279 +msgid "This item has subitems." +msgstr "這個項目下有子項。" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:36 +msgid "Delete this article" +msgstr "刪掉這篇文章" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:41 +msgid "This table provides you a form to add a new article." +msgstr "本表提供建新文章的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:44 +msgid "This table provides you a form to edit a current article." +msgstr "本表提供編輯文章的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:47 +msgid "This table provides you a form to delete a article." +msgstr "本表提供刪除文章的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:66 +msgid "Add a New Newsletter Article" +msgstr "建新通訊文章" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:69 +msgid "Edit a Current Newsletter Article" +msgstr "編輯通訊文章" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:72 +msgid "Delete a Newsletter Article" +msgstr "刪除通訊文章" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:79 +msgid "Preview this article." +msgstr "預覽這篇文章。" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:88 +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:91 +msgid "Newsletter:" +msgstr "通訊:" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:93 +msgid "HTML title:" +msgstr "HTML 標題:" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:94 +msgid "(Leave it blank if the same as the title.)" +msgstr "(若與標題相同,請留白。)" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:99 +msgid "Authors column:" +msgstr "作者欄:" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:101 +msgid "(Leave it blank if the same as the author.)" +msgstr "(若與作者相同,請留白。)" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:106 +msgid "Annotations:" +msgstr "註釋:" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:36 +msgid "Delete this index item" +msgstr "刪掉這項目錄項目" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:41 +msgid "This table provides you a form to add a new index item." +msgstr "本表提供建新目錄項目的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:44 +msgid "This table provides you a form to edit a current index item." +msgstr "本表提供編輯目錄項目的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:47 +msgid "This table provides you a form to delete a index item." +msgstr "本表提供刪除目錄項目的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:64 +msgid "Add a New Newsletter Index Item" +msgstr "建新通訊目錄項目" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:67 +msgid "Edit a Current Newsletter Index Item" +msgstr "編輯通訊目錄項目" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:70 +msgid "Delete a Newsletter Index Item" +msgstr "刪除通訊目錄項目" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:96 +msgid "Parent item:" +msgstr "大項:" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:97 +msgid "At the very top" +msgstr "最上層" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:109 +msgid "[numerate,_1,Subitem,Subitems]:" +msgstr "子項:" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:135 +msgid "(Leave it blank if the same as the article title.)" +msgstr "(若與文章標題相同,請留白。)" + +#: magicat/lib/perl5/Selima/htc/List/Guestbook.pm:24 +msgid "Select a Message" +msgstr "選擇留言" + +#: magicat/lib/perl5/Selima/htc/List/Guestbook.pm:25 +msgid "Manage the Guestbook" +msgstr "管理留言板" + +#: magicat/lib/perl5/Selima/htc/List/Guestbook.pm:28 +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:24 +msgid "Occupation" +msgstr "職業" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:24 +msgid "Select a Newsletter" +msgstr "選擇通訊" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:25 +msgid "Manage Newsletters" +msgstr "管理通訊" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:32 +msgid "Issue" +msgstr "期數" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:33 +msgid "Credits" +msgstr "發行欄" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:41 +msgid "Add a new newsletter." +msgstr "建新通訊。" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:47 +msgid "Search for a newsletter:" +msgstr "搜尋通訊:" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:64 +msgid "Your query found [*,_1,newsletter]." +msgstr "共 [#,_1] 期相符的通訊。" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:67 +msgid "[*,_1,newsletter]." +msgstr "共 [#,_1] 期通訊。" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:73 +msgid "Your query found [*,_1,newsletter], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 期相符的通訊,列出第 [#,_2] 期到第 [#,_3] 期。" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:77 +msgid "[*,_1,newsletter], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 期通訊,列出第 [#,_2] 期到第 [#,_3] 期。" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:24 +msgid "Select a Newsletter Article" +msgstr "選擇通訊文章" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:25 +msgid "Manage Newsletter Articles" +msgstr "管理通訊文章" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:30 +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:28 +msgid "Newsletter" +msgstr "通訊" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:31 +msgid "HTML title" +msgstr "HTML 標題" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:32 +msgid "Author" +msgstr "作者" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:33 +msgid "Authors column" +msgstr "作者欄" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:34 +msgid "Annotations" +msgstr "註釋" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:42 +msgid "Add a new article." +msgstr "建新文章。" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:48 +msgid "Search for an article:" +msgstr "搜尋文章:" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:65 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:88 +msgid "Your query found [*,_1,article]." +msgstr "共 [#,_1] 篇相符的文章。" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:68 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:91 +msgid "[*,_1,article]." +msgstr "共 [#,_1] 篇文章。" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:74 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:97 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:78 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:101 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:24 +msgid "Select a Newsletter Index Item" +msgstr "選擇通訊目錄項目" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:25 +msgid "Manage Newsletter Index" +msgstr "管理通訊目錄" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:29 +msgid "Article" +msgstr "文章" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:37 +msgid "Add a new index item." +msgstr "建新目錄項目。" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:43 +msgid "Search for an index item:" +msgstr "搜尋目錄項目:" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:60 +msgid "Your query found [*,_1,index item]." +msgstr "共 [#,_1] 項相符的目錄項目。" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:63 +msgid "[*,_1,index item]." +msgstr "共 [#,_1] 項目錄項目。" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:69 +msgid "Your query found [*,_1,index item], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 項相符的目錄項目,列出第 [#,_2] 項到第 [#,_3] 項。" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:73 +msgid "[*,_1,index item], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 項目錄項目,列出第 [#,_2] 項到第 [#,_3] 項。" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:24 +msgid "Full Text Search" +msgstr "全文檢索" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:26 +msgid "Search Result" +msgstr "搜尋結果" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:49 +msgid "Please fill in your query." +msgstr "請填上檢索的辭彙。" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:71 +msgid "Search in the website:" +msgstr "網站檢索:" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:146 +msgid "Guestbook Message on [_1]" +msgstr "[_1] 留言" + +#: magicat/lib/perl5/Selima/htc/Processor/Newslet.pm:90 +msgid "This newsletter was not modified." +msgstr "通訊未異動。" + +#: magicat/lib/perl5/Selima/htc/Processor/Newslet.pm:94 +msgid "This newsletter has been successfully added." +msgstr "通訊建好了。" + +#: magicat/lib/perl5/Selima/htc/Processor/Newslet.pm:98 +msgid "This newsletter has been successfully updated." +msgstr "通訊存好了。" + +#: magicat/lib/perl5/Selima/htc/Processor/Newslet.pm:102 +msgid "This newsletter has been successfully deleted." +msgstr "通訊刪掉了。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLArt.pm:101 +msgid "This article was not modified." +msgstr "文章未異動。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLArt.pm:105 +msgid "This article has been successfully added." +msgstr "文章建好了。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLArt.pm:109 +msgid "This article has been successfully updated." +msgstr "文章存好了。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLArt.pm:113 +msgid "This article has been successfully deleted." +msgstr "文章刪掉了。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm:91 +msgid "This index item was not modified." +msgstr "目錄項目未異動。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm:95 +msgid "This index item has been successfully added." +msgstr "目錄項目建好了。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm:99 +msgid "This index item has been successfully updated." +msgstr "目錄項目存好了。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm:103 +msgid "This index item has been successfully deleted." +msgstr "目錄項目刪掉了。" + +#: magicat/lib/perl5/Selima/htc/Checker/Guestbook/Public.pm:36 +msgid "Your occupation is too long. (Max. length [#,_1])" +msgstr "妳的職業太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:29 +msgid "Location" +msgstr "所在地" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:34 +msgid "Message" +msgstr "留言" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:35 +msgid "Fill in your message here." +msgstr "請填上妳的留言。" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:40 +msgid "Signature" +msgstr "簽名" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:45 +msgid "Website URL." +msgstr "網站網址" diff --git a/htdocs/htc/magicat/po/zh_TW.pox b/htdocs/htc/magicat/po/zh_TW.pox new file mode 100644 index 0000000..2674b6d --- /dev/null +++ b/htdocs/htc/magicat/po/zh_TW.pox @@ -0,0 +1,969 @@ +# Traditional Chinese PO file for the HTC website +# Copyright (C) 2004-2018 imacat +# This file is distributed under the same license as the htc package. +# imacat , 2004-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: htc 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-02-17 17:01+0800\n" +"PO-Revision-Date: 2012-02-17 17:00+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: cgi-bin/guestbook.cgi:25 magicat/cgi-bin/guestbook.cgi:26 +msgid "guestbook" +msgstr "留言板" + +#: cgi-bin/guestbook.cgi:95 magicat/lib/perl5/Selima/htc/HTML.pm:61 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:147 +msgid "Guestbook" +msgstr "留言板" + +#: cgi-bin/search.cgi:26 +msgid "search, query, full text search" +msgstr "搜尋, 檢索, 全文檢索" + +#: magicat/cgi-bin/actlog.cgi:22 +msgid "activity, logs" +msgstr "活動, 記錄, 日誌" + +#: magicat/cgi-bin/groupmem.cgi:30 +msgid "group membership" +msgstr "群組成員" + +#: magicat/cgi-bin/groupmem.cgi:94 magicat/cgi-bin/groupmem.cgi:139 +#: magicat/cgi-bin/groups.cgi:102 magicat/cgi-bin/groups.cgi:151 +#: magicat/cgi-bin/guestbook.cgi:90 magicat/cgi-bin/guestbook.cgi:136 +#: magicat/cgi-bin/linkcat.cgi:101 magicat/cgi-bin/linkcat.cgi:154 +#: magicat/cgi-bin/linkcatz.cgi:94 magicat/cgi-bin/linkcatz.cgi:139 +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:137 +#: magicat/cgi-bin/newslets.cgi:128 magicat/cgi-bin/newslets.cgi:173 +#: magicat/cgi-bin/nlarts.cgi:93 magicat/cgi-bin/nlarts.cgi:140 +#: magicat/cgi-bin/nlindex.cgi:97 magicat/cgi-bin/nlindex.cgi:146 +#: magicat/cgi-bin/pages.cgi:96 magicat/cgi-bin/pages.cgi:140 +#: magicat/cgi-bin/scptpriv.cgi:92 magicat/cgi-bin/scptpriv.cgi:137 +#: magicat/cgi-bin/usermem.cgi:94 magicat/cgi-bin/usermem.cgi:139 +#: magicat/cgi-bin/userpref.cgi:92 magicat/cgi-bin/userpref.cgi:137 +#: magicat/cgi-bin/users.cgi:111 magicat/cgi-bin/users.cgi:175 +msgid "Incorrect form: [_1]." +msgstr "查無此表格: [_1] 。" + +#: magicat/cgi-bin/groupmem.cgi:186 magicat/cgi-bin/usermem.cgi:186 +msgid "Please select the membership record." +msgstr "請選擇成員關係。" + +#: magicat/cgi-bin/groupmem.cgi:194 magicat/cgi-bin/usermem.cgi:194 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "查無此成員關係,請重新選擇。" + +#: magicat/cgi-bin/groups.cgi:34 +msgid "groups" +msgstr "群組" + +#: magicat/cgi-bin/groups.cgi:198 +msgid "Please select the group." +msgstr "請選擇群組。" + +#: magicat/cgi-bin/groups.cgi:206 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: magicat/cgi-bin/guestbook.cgi:183 +msgid "Please select the message." +msgstr "請選擇要設定的留言。" + +#: magicat/cgi-bin/guestbook.cgi:191 +msgid "This message does not exist anymore. Please select another one." +msgstr "查無該留言,請改選其她留言。" + +#: magicat/cgi-bin/linkcat.cgi:29 +msgid "link categories" +msgstr "相關連結分類" + +#: magicat/cgi-bin/linkcat.cgi:90 magicat/cgi-bin/linkcat.cgi:143 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: magicat/cgi-bin/linkcat.cgi:94 magicat/cgi-bin/linkcat.cgi:147 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: magicat/cgi-bin/linkcat.cgi:202 +msgid "Please select the category." +msgstr "請選擇分類。" + +#: magicat/cgi-bin/linkcat.cgi:210 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: magicat/cgi-bin/linkcatz.cgi:30 +msgid "link categorization" +msgstr "連結分類表" + +#: magicat/cgi-bin/linkcatz.cgi:186 +msgid "Please select the categorization record." +msgstr "請選擇分類資料。" + +#: magicat/cgi-bin/linkcatz.cgi:194 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "查無此分類資料,請重新選擇。" + +#: magicat/cgi-bin/links.cgi:28 magicat/lib/perl5/Selima/htc/Rebuild.pm:208 +msgid "related links" +msgstr "相關連結" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Please select the related link." +msgstr "請選擇要設定的相關連結。" + +#: magicat/cgi-bin/links.cgi:193 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查無該相關連結,請改選其她相關連結。" + +#: magicat/cgi-bin/logout.cgi:25 +msgid "log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:98 magicat/cgi-bin/logout.cgi:105 +msgid "Log Out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:121 +msgid "Are you sure you want to log out?" +msgstr "妳確定要登出嗎?" + +#: magicat/cgi-bin/logout.cgi:122 magicat/lib/perl5/Selima/htc/HTML.pm:361 +msgid "Log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:138 +msgid "Log in again." +msgstr "重新登入。" + +#: magicat/cgi-bin/newslets.cgi:31 +msgid "newsletters" +msgstr "通訊" + +#: magicat/cgi-bin/newslets.cgi:226 +msgid "Please select the newsletter." +msgstr "請選擇通訊。" + +#: magicat/cgi-bin/newslets.cgi:234 +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:140 +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:47 +msgid "This newsletter does not exist anymore. Please select another one." +msgstr "查無此通訊,請重新選擇。" + +#: magicat/cgi-bin/nlarts.cgi:29 +msgid "newsletter articles" +msgstr "通訊文章" + +#: magicat/cgi-bin/nlarts.cgi:187 +msgid "Please select the article." +msgstr "請選擇文章。" + +#: magicat/cgi-bin/nlarts.cgi:195 +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:111 +msgid "This article does not exist anymore. Please select another one." +msgstr "查無該文,請改選其她文章。" + +#: magicat/cgi-bin/nlindex.cgi:29 +msgid "newsletter indices" +msgstr "通訊目錄" + +#: magicat/cgi-bin/nlindex.cgi:90 magicat/cgi-bin/nlindex.cgi:139 +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:78 +msgid "" +"This index item has [numerate,_1,a subitem,subitems]. It cannot be " +"deleted. To delete the index item, [numerate,_1,its subitem,all of its " +"subitems] must first be deleted." +msgstr "" +"本目錄項目下有子項,不可直接刪除。要刪除本目錄項目,請先刪除其下的子項。" + +#: magicat/cgi-bin/nlindex.cgi:193 +msgid "Please select the index item." +msgstr "請選擇目錄項目。" + +#: magicat/cgi-bin/nlindex.cgi:201 +msgid "This index item does not exist anymore. Please select another one." +msgstr "查無此目錄項目,請重新選擇。" + +#: magicat/cgi-bin/pages.cgi:26 +msgid "pages" +msgstr "網頁" + +#: magicat/cgi-bin/pages.cgi:193 +msgid "Please select the page." +msgstr "請選擇網頁。" + +#: magicat/cgi-bin/pages.cgi:201 +msgid "This page does not exist anymore. Please select another one." +msgstr "查無此頁,請改選其她網頁。" + +#: magicat/cgi-bin/rebuild.cgi:23 +msgid "rebuild pages" +msgstr "重製網頁" + +#: magicat/cgi-bin/scptpriv.cgi:28 +msgid "script privilege" +msgstr "程式權限" + +#: magicat/cgi-bin/scptpriv.cgi:184 +msgid "Please select the script privilege record." +msgstr "請選擇程式權限。" + +#: magicat/cgi-bin/scptpriv.cgi:192 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "查無該程式權限,請重新選擇。" + +#: magicat/cgi-bin/usermem.cgi:30 +msgid "user membership" +msgstr "使用者成員" + +#: magicat/cgi-bin/userpref.cgi:28 +msgid "user preference" +msgstr "使用者偏好" + +#: magicat/cgi-bin/userpref.cgi:184 +msgid "Please select the user preference." +msgstr "請選擇使用者偏好。" + +#: magicat/cgi-bin/userpref.cgi:192 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "查無該使用者偏好,請重新選擇。" + +#: magicat/cgi-bin/users.cgi:29 +msgid "users" +msgstr "帳號" + +#: magicat/cgi-bin/users.cgi:222 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: magicat/cgi-bin/users.cgi:230 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:59 +msgid "Manage Content" +msgstr "管理網站" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:63 +msgid "Pages" +msgstr "網頁" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:65 +msgid "Links" +msgstr "連結" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:67 +msgid "Link Categories" +msgstr "連結分類" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:69 +msgid "Link Categorization" +msgstr "連結分類表" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:71 +msgid "Newsletters" +msgstr "通訊" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:73 +msgid "Newsletter Indices" +msgstr "通訊目錄" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:75 +msgid "Newsletter Articles" +msgstr "通訊文章" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:79 +msgid "Manage Accounts" +msgstr "管理帳號" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:81 +msgid "Users" +msgstr "帳號" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:83 +msgid "Groups" +msgstr "群組" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:85 +msgid "User Membership" +msgstr "使用者成員" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:87 +msgid "Group Membership" +msgstr "群組成員" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:89 +msgid "User Preferences" +msgstr "使用者偏好" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:91 +msgid "Script Privileges" +msgstr "程式權限" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:95 +msgid "Miscellaneous" +msgstr "雜項" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:97 +msgid "Activity Log" +msgstr "活動日誌" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:99 +msgid "Rebuild Pages" +msgstr "重製網頁" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:101 +msgid "Analog" +msgstr "訪客統計" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:103 +msgid "Test Script" +msgstr "測試程式" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:154 +msgid "Skip to the page content area." +msgstr "跳到網頁內文區。" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:155 +msgid "Page Content Area" +msgstr "網頁內文區" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:288 +msgid "Navigation Links Area" +msgstr "導覽連結區" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:359 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "%s,妳好!(修改資料)" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:401 +#, c-format +msgid "%s:" +msgstr "%s:" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:471 +#: magicat/lib/perl5/Selima/htc/Rebuild.pm:216 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:136 +msgid "Related Links" +msgstr "相關連結" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:482 +msgid "Subcategories:" +msgstr "子類:" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:497 +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:19 +msgid "E-mail" +msgstr "E-mail" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:522 +msgid "URL:" +msgstr "網址:" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:525 +msgid "E-mail:" +msgstr "E-mail :" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:531 +msgid "Address:" +msgstr "地址:" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:533 +msgid "Tel.:" +msgstr "電話:" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:535 +msgid "Fax.:" +msgstr "傳真:" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:560 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:626 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "mod_perl -- 速度,動力,無限可能" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:627 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" +"本程式以 Perl 撰寫,專為 mod_perl 設計強化" + +#: magicat/lib/perl5/Selima/htc/HTML.pm:640 +msgid "" +"This script is written in Perl." +msgstr "" +"本程式以 Perl 撰寫" + +#: magicat/lib/perl5/Selima/htc/Checker/Guestbook.pm:33 +msgid "This occupation is too long. (Max. length [#,_1])" +msgstr "職業太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:61 +msgid "Please fill in the date." +msgstr "請填上日期。" + +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:64 +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:67 +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:69 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期請以 YYYY-MM-DD 格式填寫。" + +#: magicat/lib/perl5/Selima/htc/Checker/Newslet.pm:89 +msgid "This credits information is too long. (Max. length [#,_1])" +msgstr "發行欄太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:44 +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:107 +msgid "Fill in the annotations here." +msgstr "請填上註釋。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:47 +msgid "This annotations list is too long. (Max. length [#,_1])" +msgstr "註釋太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:68 +msgid "This author is too long. (Max. length [#,_1])" +msgstr "作者太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:88 +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:100 +msgid "Fill in the authors column here." +msgstr "請填上作者欄。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:91 +msgid "This authors column is too long. (Max. length [#,_1])" +msgstr "作者欄太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:115 +msgid "This e-mail is too long. (Max. length [#,_1])" +msgstr "E-mail 太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:119 +msgid "Please fill in a valid e-mail address." +msgstr "請填上正確的 E-mail 信箱。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:137 +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:44 +msgid "Please select a newsletter." +msgstr "請選擇通訊。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLArt.pm:163 +msgid "This HTML title is too long. (Max. length [#,_1])" +msgstr "HTML 標題太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:60 +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:75 +msgid "Please select a parent index item." +msgstr "請選擇所屬的大項。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:65 +msgid "This option is invalid. Please select a proper parent index item." +msgstr "查無此大項,請重新選擇。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:78 +msgid "" +"This parent index item does not exist anymore. Please select another one." +msgstr "查無此大項,請重新選擇。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:82 +msgid "An index item cannot belong to itself. Please select another one." +msgstr "目錄項目不可屬於自己本身,請重新選擇。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:89 +msgid "" +"An index item cannot belong to its descendant. Please select another one." +msgstr "目錄項目不可屬於自己的子項,請重新選擇。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:131 +msgid "Please fill in the title." +msgstr "請填上標題。" + +#: magicat/lib/perl5/Selima/htc/Checker/NLIndex.pm:137 +msgid "This title is too long. (Max. length [#,_1])" +msgstr "標題太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook.pm:18 +msgid "Occupation:" +msgstr "職業:" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook.pm:23 +msgid "Website URL.:" +msgstr "網站網址:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:38 +msgid "Delete this newsletter" +msgstr "刪掉這期通訊" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:43 +msgid "This table provides you a form to add a new newsletter." +msgstr "本表提供建新通訊的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:46 +msgid "This table provides you a form to edit a current newsletter." +msgstr "本表提供編輯通訊的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:49 +msgid "This table provides you a form to delete a newsletter." +msgstr "本表提供刪除通訊的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:68 +msgid "Add a New Newsletter" +msgstr "建新通訊" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:71 +msgid "Edit a Current Newsletter" +msgstr "編輯通訊" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:74 +msgid "Delete a Newsletter" +msgstr "刪除通訊" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:81 +msgid "Preview this newsletter." +msgstr "預覽這期通訊。" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:102 +msgid "[numerate,_1,Article,Articles]:" +msgstr "文章:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:127 +msgid "Credits:" +msgstr "發行欄:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:128 +msgid "Fill in the credits here." +msgstr "請填上發行欄。" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:133 +msgid "Hide?" +msgstr "隱藏?" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:134 +msgid "Hide this newsletter" +msgstr "隱藏這期通訊" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:134 +msgid "Show this newsletter" +msgstr "秀出這期通訊" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:135 +msgid "Hide this newsletter currently." +msgstr "暫勿秀出這期通訊。" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:146 +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:186 +msgid "Index:" +msgstr "目錄:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:166 +msgid "Original:" +msgstr "原:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:167 +msgid "New:" +msgstr "新:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:207 +msgid "Issue:" +msgstr "期數:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:273 +msgid "Choose" +msgstr "選擇" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:274 +msgid "Delete" +msgstr "刪除" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:275 +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:86 +msgid "Article:" +msgstr "文章:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:276 +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:134 +msgid "Title:" +msgstr "標題:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:277 +msgid "Has subitems?" +msgstr "有子項?" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:278 +msgid "Subitems:" +msgstr "子項:" + +#: magicat/lib/perl5/Selima/htc/Form/Newslet.pm:279 +msgid "This item has subitems." +msgstr "這個項目下有子項。" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:36 +msgid "Delete this article" +msgstr "刪掉這篇文章" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:41 +msgid "This table provides you a form to add a new article." +msgstr "本表提供建新文章的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:44 +msgid "This table provides you a form to edit a current article." +msgstr "本表提供編輯文章的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:47 +msgid "This table provides you a form to delete a article." +msgstr "本表提供刪除文章的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:66 +msgid "Add a New Newsletter Article" +msgstr "建新通訊文章" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:69 +msgid "Edit a Current Newsletter Article" +msgstr "編輯通訊文章" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:72 +msgid "Delete a Newsletter Article" +msgstr "刪除通訊文章" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:79 +msgid "Preview this article." +msgstr "預覽這篇文章。" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:88 +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:91 +msgid "Newsletter:" +msgstr "通訊:" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:93 +msgid "HTML title:" +msgstr "HTML 標題:" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:94 +msgid "(Leave it blank if the same as the title.)" +msgstr "(若與標題相同,請留白。)" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:99 +msgid "Authors column:" +msgstr "作者欄:" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:101 +msgid "(Leave it blank if the same as the author.)" +msgstr "(若與作者相同,請留白。)" + +#: magicat/lib/perl5/Selima/htc/Form/NLArt.pm:106 +msgid "Annotations:" +msgstr "註釋:" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:36 +msgid "Delete this index item" +msgstr "刪掉這項目錄項目" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:41 +msgid "This table provides you a form to add a new index item." +msgstr "本表提供建新目錄項目的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:44 +msgid "This table provides you a form to edit a current index item." +msgstr "本表提供編輯目錄項目的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:47 +msgid "This table provides you a form to delete a index item." +msgstr "本表提供刪除目錄項目的表單。" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:64 +msgid "Add a New Newsletter Index Item" +msgstr "建新通訊目錄項目" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:67 +msgid "Edit a Current Newsletter Index Item" +msgstr "編輯通訊目錄項目" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:70 +msgid "Delete a Newsletter Index Item" +msgstr "刪除通訊目錄項目" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:96 +msgid "Parent item:" +msgstr "大項:" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:97 +msgid "At the very top" +msgstr "最上層" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:109 +msgid "[numerate,_1,Subitem,Subitems]:" +msgstr "子項:" + +#: magicat/lib/perl5/Selima/htc/Form/NLIndex.pm:135 +msgid "(Leave it blank if the same as the article title.)" +msgstr "(若與文章標題相同,請留白。)" + +#: magicat/lib/perl5/Selima/htc/List/Guestbook.pm:24 +msgid "Select a Message" +msgstr "選擇留言" + +#: magicat/lib/perl5/Selima/htc/List/Guestbook.pm:25 +msgid "Manage the Guestbook" +msgstr "管理留言板" + +#: magicat/lib/perl5/Selima/htc/List/Guestbook.pm:28 +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:24 +msgid "Occupation" +msgstr "職業" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:24 +msgid "Select a Newsletter" +msgstr "選擇通訊" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:25 +msgid "Manage Newsletters" +msgstr "管理通訊" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:32 +msgid "Issue" +msgstr "期數" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:33 +msgid "Credits" +msgstr "發行欄" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:41 +msgid "Add a new newsletter." +msgstr "建新通訊。" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:47 +msgid "Search for a newsletter:" +msgstr "搜尋通訊:" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:64 +msgid "Your query found [*,_1,newsletter]." +msgstr "共 [#,_1] 期相符的通訊。" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:67 +msgid "[*,_1,newsletter]." +msgstr "共 [#,_1] 期通訊。" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:73 +msgid "Your query found [*,_1,newsletter], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 期相符的通訊,列出第 [#,_2] 期到第 [#,_3] 期。" + +#: magicat/lib/perl5/Selima/htc/List/Newslets.pm:77 +msgid "[*,_1,newsletter], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 期通訊,列出第 [#,_2] 期到第 [#,_3] 期。" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:24 +msgid "Select a Newsletter Article" +msgstr "選擇通訊文章" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:25 +msgid "Manage Newsletter Articles" +msgstr "管理通訊文章" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:30 +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:28 +msgid "Newsletter" +msgstr "通訊" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:31 +msgid "HTML title" +msgstr "HTML 標題" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:32 +msgid "Author" +msgstr "作者" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:33 +msgid "Authors column" +msgstr "作者欄" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:34 +msgid "Annotations" +msgstr "註釋" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:42 +msgid "Add a new article." +msgstr "建新文章。" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:48 +msgid "Search for an article:" +msgstr "搜尋文章:" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:65 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:88 +msgid "Your query found [*,_1,article]." +msgstr "共 [#,_1] 篇相符的文章。" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:68 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:91 +msgid "[*,_1,article]." +msgstr "共 [#,_1] 篇文章。" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:74 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:97 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/htc/List/NLArts.pm:78 +#: magicat/lib/perl5/Selima/htc/List/Search.pm:101 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:24 +msgid "Select a Newsletter Index Item" +msgstr "選擇通訊目錄項目" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:25 +msgid "Manage Newsletter Index" +msgstr "管理通訊目錄" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:29 +msgid "Article" +msgstr "文章" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:37 +msgid "Add a new index item." +msgstr "建新目錄項目。" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:43 +msgid "Search for an index item:" +msgstr "搜尋目錄項目:" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:60 +msgid "Your query found [*,_1,index item]." +msgstr "共 [#,_1] 項相符的目錄項目。" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:63 +msgid "[*,_1,index item]." +msgstr "共 [#,_1] 項目錄項目。" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:69 +msgid "Your query found [*,_1,index item], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 項相符的目錄項目,列出第 [#,_2] 項到第 [#,_3] 項。" + +#: magicat/lib/perl5/Selima/htc/List/NLIndex.pm:73 +msgid "[*,_1,index item], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 項目錄項目,列出第 [#,_2] 項到第 [#,_3] 項。" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:24 +msgid "Full Text Search" +msgstr "全文檢索" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:26 +msgid "Search Result" +msgstr "搜尋結果" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:49 +msgid "Please fill in your query." +msgstr "請填上檢索的辭彙。" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:71 +msgid "Search in the website:" +msgstr "網站檢索:" + +#: magicat/lib/perl5/Selima/htc/List/Search.pm:146 +msgid "Guestbook Message on [_1]" +msgstr "[_1] 留言" + +#: magicat/lib/perl5/Selima/htc/Processor/Newslet.pm:90 +msgid "This newsletter was not modified." +msgstr "通訊未異動。" + +#: magicat/lib/perl5/Selima/htc/Processor/Newslet.pm:94 +msgid "This newsletter has been successfully added." +msgstr "通訊建好了。" + +#: magicat/lib/perl5/Selima/htc/Processor/Newslet.pm:98 +msgid "This newsletter has been successfully updated." +msgstr "通訊存好了。" + +#: magicat/lib/perl5/Selima/htc/Processor/Newslet.pm:102 +msgid "This newsletter has been successfully deleted." +msgstr "通訊刪掉了。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLArt.pm:101 +msgid "This article was not modified." +msgstr "文章未異動。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLArt.pm:105 +msgid "This article has been successfully added." +msgstr "文章建好了。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLArt.pm:109 +msgid "This article has been successfully updated." +msgstr "文章存好了。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLArt.pm:113 +msgid "This article has been successfully deleted." +msgstr "文章刪掉了。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm:91 +msgid "This index item was not modified." +msgstr "目錄項目未異動。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm:95 +msgid "This index item has been successfully added." +msgstr "目錄項目建好了。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm:99 +msgid "This index item has been successfully updated." +msgstr "目錄項目存好了。" + +#: magicat/lib/perl5/Selima/htc/Processor/NLIndex.pm:103 +msgid "This index item has been successfully deleted." +msgstr "目錄項目刪掉了。" + +#: magicat/lib/perl5/Selima/htc/Checker/Guestbook/Public.pm:36 +msgid "Your occupation is too long. (Max. length [#,_1])" +msgstr "妳的職業太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:29 +msgid "Location" +msgstr "所在地" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:34 +msgid "Message" +msgstr "留言" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:35 +msgid "Fill in your message here." +msgstr "請填上妳的留言。" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:40 +msgid "Signature" +msgstr "簽名" + +#: magicat/lib/perl5/Selima/htc/Form/Guestbook/Public.pm:45 +msgid "Website URL." +msgstr "網站網址" diff --git a/htdocs/htc/newsletters/001/article01.html.html b/htdocs/htc/newsletters/001/article01.html.html new file mode 120000 index 0000000..f89ba28 --- /dev/null +++ b/htdocs/htc/newsletters/001/article01.html.html @@ -0,0 +1 @@ +article01.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/001/article01.html.xhtml b/htdocs/htc/newsletters/001/article01.html.xhtml new file mode 100644 index 0000000..74cb514 --- /dev/null +++ b/htdocs/htc/newsletters/001/article01.html.xhtml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + +發刊辭 + + + + +
    + +
    + 回目錄 | + 下一篇 +
    + +

    發刊辭

    + +
    +

    荷蘭歷史學家赫伊津哈 (Johan Huizinga) 說道:「對於歷史而言,問題永遠是:往何處去?」過去二十年來,台灣西洋史學界偶有西洋史研究危機的呼聲。但這些零星的呼聲卻如入池的小石,激不起太大的波瀾。對於年輕的西洋史初學者而言,心中所懸念地是:下一步往何處去?在如此疑惑不安的情緒中,我們認為台灣的西洋史研究正處於一個深刻的危機狀態。「危機」,標識了一個過渡的階段;吾人將從中恢復過來,抑或是僵死過去,端視於我們如何去回應此一危機!

    +

    論者每謂台灣西洋史研究的危機在於基礎研究的欠缺。黃俊傑與邢義田先生早先在有關於研究西洋史應站在「西洋史」或「世界史」立場的論辯時(一九八一),兩人皆同意基本研究的欠缺確是西洋史研究的重大難題;近來,楊肅獻先生回顧台灣的西洋史研究狀況時,此一現象仍未有多大地改變(一九九七)。

    +

    我們想指出:西洋史研究的危機不在於基礎研究的欠缺;而在於對此一危機性質的誤解!同時,這當中也關涉了對歷史學性質的不同見解。

    +

    無可諱言,基礎研究的欠缺確實是台灣西洋史學界所面臨的重大問題。史料的欠缺與文化的隔閡都加深了研究工作的困難,但是,這卻不應該是構成西洋史研究停滯不前的藉口。可以預見地,台灣的西洋史研究所面臨的限制與窘境不會有太大的改善。果若如此,則西洋史研究者豈不皆坐以待斃!

    +

    這誠然是一個消極的態度;我們可以更積極的態度來面對。這當中牽涉了我們對歷史學性質的一種新的理解。近年來人文科學界中的語言學轉向 (the linguistic turn) ,打破了人們對語言再現實在的透明性的信賴。語言並非一全然透明之物,單純地反映所接受的感覺與料;歷史的認知並非史家被動的接受、蒐集事實,它同時是史家心靈力量的展現。因此,在歷史研究中,事實的歸屬與綜合是同時進行地。

    +

    我們再次地強調:西洋史研究的基礎工作是必須的;但這並非西洋史研究開展的充要條件。西洋史研究工作的進行並非等待基礎研究完成後才能起步。所謂「唯有待基礎研究工作完成後,我們才能對西洋史或世界史有屬於我們自己的理解」的說法,這是十九世紀西方實證史學的說辭。實證史學假定只有當所有的證據都蒐集完成,才能作進一步的綜合工作。西洋史研究者對基礎研究不振的現象感到憂慮,從而猶豫不前,這樣的學風是受到中央研究院史語所傅斯年先生所謂「史學即史料學」的影響。令人惋惜地是,台灣的西洋史研究者並未以其對西方史學發展的了解,對此有所匡正,反受其遺毒所害,延擱了西洋史研究工作的進展。

    +

    因此,西洋史研究的危機與其說是基礎研究的欠缺,不如說是大部分的研究者誤解了此一危機的性質。換言之,危機的本身即是西洋史研究者以為危機存在於基礎研究的闕如。

    +

    但在此之下,尚隱藏了更深刻的危機,即歷史研究與現時的脫離。史學無法切合現代人的認知需求。相較於西方學術「歷史化」 (always historicise!) 的呼聲,台灣的歷史研究仍囿於它學科的門牆之內。它既缺乏對歷史學科本身的反省,亦即對歷史學在快速變動的社會中,它自身性質的轉變;同時也缺乏對現實的反省,亦即歷史學如何去回應現代社會的需求。

    +

    台灣歷史學界對於歷史理論向來缺乏深刻的反省。多數的學者以為對理論的偏好是望空為高,對實際研究缺乏正面的功能與效用。黃進興先生晚近的告白正是此種心態的反應(一九九二)。對黃進興而言,理論與方法論是屬於「第二序」 (second-order) 的語言,終究無法取代「第一序」 (first-order) 的實質研究。歷經早年對理論的酷愛,黃進興回歸到經典與史料本身。這種反理論的心態不僅使台灣史學界對歷史理論欠缺反省;同時,也無力肆應當今的後現代情境。

    +
    + +
    +

    在歷經幾番躊蹴猶豫底自我懷疑與認同危機後,一群西洋史的初學者共同創造了一個台灣西洋史研究的園地。他們希望透過行動與理論的反省,回應西洋史研究所面臨的窘況,同時催生西洋史研究的蓬勃發展。

    +

    行動之首要,在於創造出一個公開從事學術討論的場域。我們認為,一個公開研究討論與知識交流的園地,是現代學術合法性的一個必要條件,其意義與宗教活動中的儀式並無二致。自去秋(一九九七)伊始,我們在輔仁大學歷史學研究所以「歷史學與後現代」、「歷史與文化」等為題舉辦了一系列的討論會。希冀透過密集、多樣的小型討論會,提供一個西洋史研究的交流園地。

    +

    進一步,我們將出版一份屬於同仁刊物性質的研究通訊,將諸次討論會的內容化為文字,結集出刊;並提供近來西洋史研究的新動態。以此做為連繫、凝聚西洋史研究的同好,並供各方批評、指教的場所。此份通訊─《歷史:理論與文化》─即是彙聚多次討論會的成果。

    +

    展望未來,我們希望能建立一份屬於台灣西洋史研究者的專業期刊。

    +

    我們要再次地強調學術刊物所具有的公開討論與競技場之功能,是學術合法化與不斷進步的確證,也是本刊《歷史:理論與文化》所欲申張的宗旨。

    +
    + +
    +

    在此,我們試擬幾個台灣西洋史學研究方向之芻議。如刊物的標題《歷史:理論與文化》所示,我們認為台灣的西洋史研究可以朝以下方向進行:歷史理論、史學史與文化史。這同時也表明了我們的立場,我們希望透過所揭櫫的西洋史研究綱領引導台灣歷史研究的走向。換言之,它所欲達成的不僅是台灣西洋史研究水準的提昇;同時,我們也希望西洋史工作者能對台灣的中國或本土歷史的研究有所獻替。藉著西方學術的引介,達成更新學術內容的目的。台灣的西洋史研究者所扮演的即是此種文化媒介的角色,這也是西洋史工作者的自我繪像、自我認同。

    +

    首先,我們強調歷史理論的重要性。史學總是不斷地反省著現時、反省著自身。台灣史學界對於當今所謂的「後現代情境」欠缺了解。今日,在西方所謂的後結構主義 (post-structuralism) 、解構 (deconstruction) 、修辭轉向 (rhetoric turn) 與視覺化理論 (visual theory) 對歷史學性質的反省起了重大的影響。在這一方面海登‧懷特 (Hayden White) 、安克斯密 (F. R. Ankersmit) 、梅驥 (Allan Megill) 、史帝芬‧班恩 (Stephen Bann) 等人的著作頗值得借鏡。

    +

    其次,是著重史學史的研究。在此,所謂的史學史不僅指涉對史家、史著、史學思想、觀念的研究;它同時意指對重要的歷史問題的歷史的研究,也就是所謂的「學術史」的研究。前者現有的成果已頗有可觀;後者則仍有待努力。

    +

    在新近重出於世的手稿中,柯靈烏 (R. G. Collingwood) 說道:「對任何一個歷史問題的研究,首先須掌握的是這一個問題本身的歷史。」透過史學史的認知,每一個專門的歷史專論或著作都與普遍史聯繫在一起。因此,西洋史研究中史料上的限制,或可以透過對每一個歷史問題的專門著作的掌握來解決。

    +

    我們的建議是:西洋史研究者應通力合作編輯相關的入門書與工具書,針對討論西洋史中的重大問題的相關著作作一番研究,彙編成冊,做為後學進一步研究的基礎。例如,有關「文藝復興」 (Renaissance) 、「十七世紀的普遍危機」 (the general crisis of seventeenth-century) 、「法國大革命」 (the French Revolution) ……等的各家解釋。

    +

    近年來,文化史研究的盛行反應了史家反省自身在群眾社會中的位置。俗民文化成了頗受重視的研究主題。這反應了史家反省他們與下層群眾的關係。史家成為弱勢者的代言人,起著揭露「權力」如何壓迫、壓抑弱勢者的批判底功能。史家們同時也注意到社會各階層所具有的自主性。

    +

    二十世紀西方史學的發展歷經了世紀初對傳統以政治史為導向的歷史研究的反動後,在六十年代開啟了社會史經濟史的研究熱潮。「新史學」 (new histories) 在擺脫了大人物傳記寫作的同時,芸芸大眾並未從中獲得解放,反而陷入了結構的牢籠。活生生的個體為抽象的數字、統計圖表所掩蓋。個體的自由意志被無形、非人化的牢籠所圍囿。

    +

    現今的史家則注意到了下層群眾每個人的日常生活經驗。七十年代後出現的新文化史 (the new cultural history) 、日常生活史 (Alltagesgeschichte, history of everyday life) 代表了此一新的取向。這些新的研究取向注重歷史中具體、個別的個體經驗。階級 (class) 、性別 (gender) 、種族 (ethnicity) 成了歷史研究中重要的範疇;而婦女、少數民族及其他弱勢族群成了新興的研究主題。多元的觀點、聲音反映了後現代情境中多元化的現象,也符應多元文化 (multi-culture) 的趨向。

    +
    + +
    +

    一九九七年秋,我們一群年輕的西洋史研究者從自我認同的危機出走,繪出台灣西洋史研究的新路徑。誠然,或許我們的思慮未臻周延、文字尚顯生澀,但因為年輕、因為滿懷的理想,我們衷心地期盼:所有的西洋史研究者能重拾自信與認同,扮好媒介者的角色,對台灣歷史研究的進展有所獻替,成為學術創新的源頭活水!

    +
    + +
    + 回目錄 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/001/article02.html.html b/htdocs/htc/newsletters/001/article02.html.html new file mode 120000 index 0000000..fad4a1e --- /dev/null +++ b/htdocs/htc/newsletters/001/article02.html.html @@ -0,0 +1 @@ +article02.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/001/article02.html.xhtml b/htdocs/htc/newsletters/001/article02.html.xhtml new file mode 100644 index 0000000..5604a31 --- /dev/null +++ b/htdocs/htc/newsletters/001/article02.html.xhtml @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + +紀爾茲「稠密描述」:一個文化詮釋理論 + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    紀爾茲「稠密描述」:一個文化詮釋理論

    + +
    +引言人:盛少輝
    +整 理:陳逸雯
    +時 間: 97.12.01
    +
    + +

    這次討論會的主題是紀爾茲 (Clifford Geertz) 的稠密描述 (Thick Description) 。在以下的討論中我除了說明稠密描述的理論外,我將討論稠密描述對於文化史研究的貢獻,並反省歷史學今日所面臨的處境。紀爾茲的稠密描述是一文化人類學的理論,自刊布以來頗受歷史學家的歡迎,並將之視為文化史研究的方法論之一。但頗多學者對之亦多所懷疑,認為歷史學在此之際遭遇嚴厲的挑戰,史學將流於破碎化、片段化,將之等同於史學後現代的表徵。我意圖提出的疑問是:稠密描述做為一種文化理解的理論,其目的在了解人類行動的意義;但此一理論在歷史學中的應用導致歷史研究主題的破碎化,失去歷史理解的整體性,而流於掌故之學。依此,以稠密描述的微觀敘述切入歷史研究,重建一個普遍的歷史意義,而大敘述 (Grand Narrative) 、普遍史 (Universal History) 是否可能?

    +

    首先,我們將對此次討論的文本稠密描述做一番稠密的閱讀。我將說明本文所處的脈絡。

    +

    紀爾茲的文化人類學理論受到西方人文科學自 60 年代以來語言學轉向的影響,他的理論運用頗多分語言哲學的概念。他的文章大量的引用諸如萊爾 (Gilbert Ryle) 、維根斯坦 (Ludwig Wittgenstien) 等人的理論。紀爾茲視語言為一公共性的產物,賦予社會意義,而不純粹是主體性的現象。

    +

    進一步,因為受到此一語言學轉折的影響,紀爾茲本文亦呈現出另一特色,即打破人文科學間的軫域,納入各學科討論的成果,使人類學、史學、社會科學間的界線漸趨模糊。

    +

    另一項特色即是文本化。首先,紀爾茲將文化的概念文本化,將文化解讀成為一個文本,紀爾茲的文化概念是一個語意學的概念。更進一步,人類學者的任務在於解讀、詮釋各個人類學的文本。

    +

    現在,我依本文的行文脈絡來加以解釋。

    +

    紀爾茲的文章起始陳述了西方人文科學界大理論觀念的崩潰。十九世紀以來,學者多希望從經驗事實的研究中推導出普遍的法則,從而建立大理論架構,以對人類社會有更清晰的理解,甚至達到預測的功能。紀爾茲對此一大理論架構的期望甚表懷疑,並認為大理論體系業已崩潰。與人類學先驅克拉克洪等人不同,紀爾茲並不意圖對文化這一概念作出完整的定義,他認為人類學者對文化研究的焦點應轉移到個別、具體的文化現象。

    +

    本文的第二項特點是將文化釋義成一個語意學的概念。紀爾茲引用韋伯的意見,「人類是一種將自己置於自身所編織的意義之網上的動物。」此「意義之網」即是文化。人文科學所從事的是意義的詮釋,而非尋找法則的經驗科學。

    +

    人類學者所從事的是民族誌 (Ethnography) 的工作。我們要掌握人類學分析做為一種知識型式,就必須要了解民族誌是甚麼,或者民族誌所從事的是甚麼?而民族誌的工做即是稠密描述。

    +

    紀爾茲將人類學的描述分成厚描(即稠密描寫)與薄描二種。二者的差異即在於研究者是否能夠分辨出現象所具有的意義階層。對一文化現象若僅以現象學的描述方式,而不對行動者行動背後的「意向性」 (intentionality) 加以了解,將無法獲得對文化的真詮,此為薄的敘述 (thin description) ;反之,若對文化意義結構的階層加以區分,則是所謂的厚描。紀爾茲引萊爾所舉之小孩眨眼為例,指出當中蘊含了不同的意義階層。如一是不自主的抽筋、二是隱含了暗語,是社會約定的符碼、三是刻意的模仿、四是隱含著反諷、取笑的意味……等,構成了不同的意義階層。

    +

    文化是一種符號行動。紀爾茲認為文化是一種符號,人類透過符號形式而達成行動,並互相了解。人類學的理解是人類知識論域的擴充,透過對異文化的了解,使人類的經驗範圍更加擴大。

    +

    人類學的知識是地方知識 (local knowledge) ,了解異文化必須從當地人的角度出發。人類學是一了解他者 (the Other) 的知識,理解異文化時不能以自己的偏見強加於異民族之上。必須從「當地人」 (the native) 的眼光出發,了解當地人的符號系統,了解當地人如何透過這些符號系統建構自身的「身分認同」 (self-identity) 。唯有具備了這樣的條件,人類學家才可能對異文化做細密的描述,以了解文化的意義。

    +

    由以上所論,可見紀爾茲深受詮釋學理論取向的影響。紀爾茲認為所有的文化都是一符號系統,而對於符號行動的了解又都是行動者取向的,而且也必須借助於移情 (empathy) 的作用,了解行動者的思想。更進一步,所有的人類學作品都是一種詮釋,都含有虛構的、人為的成分,都是人類學家腦力的產物,因此都有不完美的傾向。套用蓋力 (W. Gallie) 的術語都是「本質上可爭論的」 (essentially contestable) ,但根據維柯真理與事實可以互換的原則,人類學作品仍有其自身的地位。

    +

    回到民族誌本身。紀爾茲認為民族誌的描寫有四項特性:一它是詮釋性的、二所詮釋的內容是社會論述、三是這樣的詮釋是嘗試去保留過去社會的論述,並用具有說服性的辭彙加以說明、四是微觀取向,紀爾茲認為人類學研究的是具體、個別的文化現象,只能採取微觀的取向來達成,但微觀取向將限制了研究者的視野,紀爾茲並不以為意;相反地,他認為研究的焦點並不等於研究的對象,他說:「人類學家並不是在研究鄉村;而是在鄉村中做研究。」希冀透過鄉村達到對文化的了解。

    +

    最後,人類學需要建構出詮釋的理論。稠密描述不僅是對文化現象的描寫 (inscription) ,而且它最終的目標應是建構出關於文化的理論。正如醫生診治病患的過程,不是對現象加以歸類,導出通則;而是在每個具體的病例中,作出診斷 (specification, diagnosis) ,提供處方。

    +

    底下我要說明稠密描述的一些基本的理論預設。

    +

    首先,是所謂的「文本化」 (textualized) 或「文本論」 (textualism) 的問題。我先前已經提過紀爾茲將文化視為一個文本來閱讀,而且主張人類學家所做的就是閱讀人類學文本,所以文化詮釋本質上就是透過閱讀人類學的文本來理解。從理論的淵源來看,這當然是受了語言哲學與文學批評理論的影響。因此,與其將稠密描寫視為一種文化研究的方法,不如將之視為一種後設理論或後設的反省。稠密描寫不是教導我們敘述的方法,而是我們對文化現象、文本的閱讀應提昇到自覺的程度,能夠分辨出文化的意義階層。

    +

    其次,是「脈絡化」 (contextualization) 的問題。將文化視為文本,並認為人類學所從事者即是對文本的閱讀,且採取微觀的研究取向必然得面臨脈絡化的難題。稠描述所欲解讀的文本最終仍須將之放置文本的前後關係與環境中,但正如所有文本論共有的難題一般,這有方法論上跳躍的困難。

    +

    第三是拒絕因果解釋。因果的觀念已被解構、拆解,稠密描述將因果觀念排除於對文化的理解之外。

    +

    第四是意向性的問題。文化做為符號行動,存在著符號與意義、思想與行動間的關係。

    +

    以下我們回到稠密描述是如何地運用於歷史學研究中。

    +

    首先,是微觀史學的出現。稠密描述的微觀化取向將焦點置於具體與個別的事件,它的設準是:依此我們可以了解文化做為一個整體。在這一方面,金茲堡 (Carlo Ginzburg) 的《乳酪與蟲子》 (The Cheese and the Worms) 是頗具代表性的著作,其他如拉度里 (E. Le Roy Ladurie) 的《蒙他猶》 (Montaillou) 、戴維斯 (Natalie Zemon Davis) 的《軍士返鄉記》 (The Return of Martin Guerre) 都代表了史學中微觀化的傾向。

    +

    人類學的知識是一種地方知識,必須從當地人的眼光來看待事物。這在實踐上有一定的程序,最重要的是能夠建立當地人的自我認同。在史學實踐上有顯著的例子如紀爾茲的巴 島鬥雞與達頓 (Robert Darnton) 的〈屠貓記〉 (the Great Cat Massacre) 都可見出端倪。達頓的《屠貓記》 (The Great Cat Massacre and Other Episodes in French Cultural History) 是一本有趣且頗具啟發性的書,他從近代歐洲的俗民文化 (popular culture) 中去尋找所謂的「法國」或「法國性」 (Frenchness) ,最重要的是必須從當時的下層民眾與工人階級的自我認同去尋找。

    +

    第三是將文化視為一符號系統。這樣一來,史家的研究領域更加多樣化,這我們可以從 70 年代以來「新文化史」 (new cultural history) 的研究獲得佐證。

    +

    當稠密描述應用於歷史研究仍遭遇到許多困難。首先是歷史破碎化、片段化的問題。雖然紀爾茲不斷聲言:研究的焦點並不等於研究的對象,但有關脈絡化的問題,即在處理部分與整體這個問題,紀爾茲的理論仍不甚令人滿意。以紀爾茲自己對爪哇國家與人民的自我建構的研究為例,紀爾茲意圖將爪哇的獨立過程與西方殖民主義與資本主義在東南亞的擴張相連接。但多數學者的意見是,紀爾茲的處理並不令人滿意。在這一方面,我認為金茲堡的《乳酪與蟲子》處理的較令人滿意。金茲堡將十六世紀一個義大利木匠的異端言論,成功地與宗教改革與印刷術的改良連接起來。

    +

    其次是判準學 (criteriology) 的問題。如紀爾茲所言所有的人類學作品都是一種詮釋,也都是不完美的。但我們要如何來斷定那一部作品是較佳的詮釋或者更貼近所欲詮釋的對象,這仍須要一項判準 (criterion) 。紀爾茲並未提供這樣的判準。

    +

    稠密描述若欲將之引入史學研究,則必須加重它歷時性 (diachronic) 的面向。紀爾茲的文化理論較缺乏歷時性的觀念。他將文化隱喻成一張意義之網,就修辭的語言來說,顯然抽離了時間的因素。這與歷史學的思維是否能切合值得深思。不過這大抵符合自布克哈特 (Jacob Burckhardt) 以來歷史學的思維方式,底下若有機會我再做較積極的詮釋,並將之與後現代的歷史思維做一番接合。

    +

    最後,紀爾茲的文化理論充其量只告訴人們過去的文化結構為何,卻無法告訴人們這樣的文化結構究竟是如何地建構出來,又是誰規範了文化的功能與意義。換言之,稠密描述僅具有描述性 (descriptive) 的功能,而不具規範的 (normative) 與意識型態批判 (ideological critique) 的功能,此點特別為馬克思派所批評,而大多數的文化史研究都存在著這樣的缺陷(義大利微觀史學在此一方面較有自覺),某些學者甚至認為此不過是在麻痺人們對現狀的不滿情緒。最著名的當是近來學者對巴赫金 (M. Bakhtin) 那本講述拉伯雷 (Rableais) 的書的詮釋。

    +

    史學的微觀化與多元化的趨向,是現今史學後現代最具挑戰性的問題。套用安克斯密 (F. Ankersmit) 詩性的比喻,在後現代的狀況中,我們所見的歷史不再是樹幹、樹枝,而是樹葉。當秋天一旦來臨,樹葉將隨風飄落,這對於所有史學工作者而言,都是一項亟待反省的課題。

    + +

    後記

    + +

    本文是應同學之邀在歷史學與後現代討論會中,就紀爾茲的稠密描述對文化史的貢獻為題,擔任引言人所做的報告。個人求學關注的焦點一直是集中於探討現代歷史意識的問題。因此,就研究範圍而言,我的興趣一直是在歷史理論、史學史、思想史等領域,文化史本非我的專業。此次跨界的討論令我收穫頗豐,在討論的過程中,對於史學圖像式 (iconological) 的理解方式與後現代視覺化 (visualization) 的趨向特別深感興趣,也獲致了某些新想法,期待他日能將之做完整的表達。我認為後現代史學中的修辭 (rhetoric) 與美學 (aesthetics) 傾向未必如余琛 (Jörn Rüen) 所憂慮的對史學的客觀性與合理性有所損傷,相反地,如余琛對蘭克的詮釋,修辭與美學可以恰切的融入史學研究中,而無害於史學科學性與客觀性的追求,我們所需要的是一種對客觀性新的概念,在這方面文化史的理解方式特別值得加以重視。

    + +

    參考書目

    + +
      +
    • Biersack, Aletta. Local Knowledge, Local History: Geertz and Beyond, ed. Lynn Hunt, The New Cultural History. Berkeley: University of California Press, 1989, pp.72-96.
    • +
    • Chartier, Roger, Text, Symbols and Frenchness: Historical Uses of Symbolic Anthropology, Journal of Modern History, 57(1985): 682-695.
    • +
    • Darnton, Robert. The Great Cat Massacre and Other Episodes in French Cultural History. New York: Vintage, 1984.
    • +
    • ________. Symbolic Element in History, Journal of Modern History, 58(1986): 218-234.
    • +
    • Davis, Natalie Z. The Return Martin Guerre. Cambridge, Mass.: Harvard University Press, 1983.
    • +
    • Ginzburg, Carlo. The Cheese and the worms: The Cosmos of a Sixteenth-Century Miller. Baltimore: The Johns Hopkins University Press, 1981
    • +
    • Geertz, Clifford. The Interpretation of Cultures. New York: Basic Books, 1973.
    • +
    • ________. Local Knowledge: Further Essays in Interpretive Anthropology. Mew York : Basic Books, 1983.
    • +
    • ________. Negara: The Theatre State in Nineteenth-Century Bali. Princeton: Princeton University Press, 1980.
    • +
    • Le Roy Ladurie, E. Montaillou. New York: Vintage, 1978.
    • +
    • LaCapra, Dominick. Chartier, Darnton, and the Great Symbol Massacre, Journal of Modern History, 60(1988): 95-112.
    • +
    • Sahlins, Marshall. Culture and Practical Reason. Chicago: The University of Chicago Press, 1976.
    • +
    • ________. Historical Metaphors and Mythical Realities: Structure in the Early History of the Sandwich Islands Kingdom. Ann Arbor: The University of Michigan Press, 1981.
    • +
    • ________. How “Natives” Think: About Captain Cook, For Example. Chicago: The University of Chicago Press, 1990.
    • +
    • ________. Islands of History. Chicago: The University of Chicago Press, 1985.
    • +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/001/article03.html.html b/htdocs/htc/newsletters/001/article03.html.html new file mode 120000 index 0000000..6a7bb08 --- /dev/null +++ b/htdocs/htc/newsletters/001/article03.html.html @@ -0,0 +1 @@ +article03.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/001/article03.html.xhtml b/htdocs/htc/newsletters/001/article03.html.xhtml new file mode 100644 index 0000000..7732f15 --- /dev/null +++ b/htdocs/htc/newsletters/001/article03.html.xhtml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + +歷史學與後現代主義 + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    歷史學與後現代主義

    + +
    +引言人:黃明田
    +撰稿人:黃明田
    +時 間: 97.12.22
    +
    + +

    本文預備討論的問題,是載於《歷史和理論》 (History and Theory) 中,荷蘭歷史學者安克斯密 (F. R. Ankersmit) 的〈歷史學和後現代〉一文。他認為今天學術研究出現了「生產過剩」的現象,在歷史學亦是如此;此種現象放在當代對後現代主義的相關探討中,他認為對整個以往的歷史學思考造成了變化,產生了新型態的歷史意識,稱為後現代史學;而這個以往的歷史學思考,相對來說,稱為現代主義史學思考。正如歷史思考一般,歷史家習慣將歷史分期為古代和現代,以區分今與昔的不同;後現代的歷史學,被劃分為接著前一時期現代主義歷史學發展而來,是現代主義歷史學下一個時期,與現代主義歷史學不同,而形成獨特的型式。

    +

    此「生產過剩」的現象,安克斯密認為把它放在現代主義或傳統的歷史學觀念裡,暴露許多在歷史學觀念和性質的矛盾之處,所以有必要提出適應此現象的新思考與認知,以反應我們時代歷史研究的實況;而此後現代的歷史思考就是站在反思當代文化因應而生的,可視為是當下歷史學術對時代變化採取的一種途徑;此新思考與認知,安克斯密也認為可以為它提供許多借鏡,豐富歷史學的思考。此外,現代主義或傳統的歷史學觀念,也就是從啟蒙史學發展至今的現代史學觀念,其本身在自己的歷史發展中(歷史的歷史),也出現了它本身在知識論方面的困境,本世紀以來為學界共同認知的「歷史主義的危機」,即為此例。因此,後現代歷史學隱約接著現代史學的發展,提出新的歷史理論,重新對歷史研究(或說歷史寫作)的性質,提出新的見解。以下即要討論這一種有別於現代主義式的歷史思考,就是後現代主義的歷史思考。

    +

    首先,我們來看看生產過剩的現象,產生的直接影響。它影響的第一個觀念就是,歷史研究要形成綜合一致的歷史見解是不可能的。這是大家都可以看到的一個學術寫作現象,歷史學本科或其它學科,不斷在生產歷史作品,不停的重寫歷史,因此許多的歷史的主題,都有為數甚多的論文,並且相同主題的眾多論文,它們的歷史見解彼此不同處明顯於它們的相同處(如果相同處多,它們的研究也就沒有學術價值,甚至會被冠上抄襲之嫌),造成相同歷史主題的歷史研究,它們的歷史觀點是朝向分歧之路;這也是學術規範所要求的,一個好的歷史論文,它必須是有別於之前寫作,應該具有不同的原創性所產生的,不然只是將眾多的歷史解釋,編排在一起不算是歷史研究,清代章學誠稱之為「史纂」,現在只算是學術行情調查。

    +

    就上述,安可斯密在文中舉了一個例子,繼續他的探討。他認為今天研究霍布斯 (Thomas Hobbes) 政治哲學的環境和二十年前大不相同,以前只需要兩本關於霍布斯的評論: Watkins 和 Warrender ,就可引領研究者去詮釋霍布斯,今天如果要去研究霍布斯則需要二十本以上的相關研究,並且我們不得不閱讀他們,否則就缺乏學術行情。此種現象造成,歷史研究本身要求我們不是在真正的研究過去,而是過去的詮釋本身;以前的歷史研究認為,我們透過記載過去的文獻重建過去,現在似乎又多加了一道間隔物,就是過去的詮釋本身,而不是過去本身。

    +

    這反應在今天歷史寫作的性質改變,造成原典證據失去它研究的權威性及原典與二手詮釋區分變的模糊。現今的歷史研究學術規範,認為歷史研究必須以第一手材料為依歸,但是試想如果完全只閱讀原典,我們無法進入眾多二手詮釋對原典詮釋的課題,不知學圈的討論重心為何,使我們對原典的詮釋不能被學圈相同主題的研究者熟知,甚至被同業取笑,我們的研究沒有學術價值,因此必須反過來以二手詮釋為重心,而不再去注意原典的重要性(原典的重要性只在於由二手詮釋關注或提問來強化),使原典不再是高於二手詮釋作為詮釋的判準。另一方面,眾多的二手詮釋觀點,我們必須花去一大部份的時間理解它們,理解之後,這些些觀點影響我們閱讀原典的理解,以致於我們不能純粹理解原典,使我們的研究無法區分何者是原典的真象部份,何者是二手詮釋所產生的理解。最後,我們會發覺這些二手詮釋,就是我們理解過去真象的妨礙物,但是又不能放棄它們。

    +

    那們是否我們能改變這種研究境況,讓我們能單純的研究過去,形成綜合一致的歷史觀點呢?現實上,歷史研究的發展不斷的否定我們。今日的研究趨勢,不斷的要求新視野新的模式詮釋過去,並且是百家爭鳴的狀態。姑且不論各學科研究過去或歷史學科同業的區別,就以法國的年鑑學派為例,從學派成立至今,他們就是在不斷的改變他們的研究模式,尋求新的視野,給歷史研究更新穿著的衣服,從布洛赫 (Marc Bloch) 和費弗爾 (Lucien Febvre) 的經濟與社會到布勞岱 (Fernand Braudel) 的宏觀文化史,至今拉度瓦 (E. Le Roy Ladurie) 、杜比 (George Duby) 及夏堤爾 (Roger Chartier) 的微觀文化史。這使得以往常我們相信歷史研究是不斷在發現過去的真實,糾正錯誤的觀點,綜合正確的事實,產生可靠的歷史知識,至今變的不可能;我們也不在處理過去歷史研究沒研究的部份過去,而是不斷的改變相同主題下,產生不同於過去歷史研究的觀點或現在他人觀點的詮釋。

    +

    「生產過剩」的事實回應傳統歷史學或現代主義歷史觀點的意義,顯然是光怪陸離的;現在歷史研究表現出來的現實現象,對照以往以原典證據為出發,和相信透過史家之筆,利用科學的方法,從過去的文獻中,設身處地的理解過去,重建歷史真實,達到歷史知識的增長,顯得格格不入。這表現在對歷史證據的定位、認識方法上能客觀理解的想法、歷史研究是再現過去真實和歷史知識的求得是反應科學進步的理念,整個歷史學工作與意義的傳統觀念,都被思考歷史研究性質者質疑。於此,當代後現代主義的文化研究,為這種情況提供許多的思考點,對我們瞭解歷史學性質的變化,有很大的幫助。

    +

    首先,面對資訊化的時代,後現代主義認為資訊是流動的、移動的、擴延的、被交易的、被販售的或被組織的;其次,資訊不斷的流動的,當我們討論資訊的內容時,其反應常讓我們無法捉摸其指涉的事物,而只能接觸到資訊自身的事實,使資訊呈現真實,只停留在資訊本身,不再是綁縛在資訊背後事物的真實,也就是資訊傳達的訊息不再指涉資訊之外的事物,而自成一脈絡;而且資訊的流動法則是資訊不斷繁多,資訊的系譜從不被終止,較後的資訊總是評估較前資訊,持續的產生。放在歷史寫作的歷史中,我們會發現偉大的歷史著作,諸如托克維爾 (Tocqueville) 、馬克思 (Karl Marx) 、布克哈特 (Jacob Burckhardt) 、韋伯 (Max Weber) 、赫伊津哈 (Johan Huizinga) 或布勞岱等等,他們寫作的歷史主題以至於形成的歷史觀點,是較有力量和權威的詮釋,帶動更多這方面歷史研究的出版和繁衍出各式各樣的觀點。相對於現代主義的歷史學觀點認為,有意義的資訊可終止該部份的歷史寫作,這來於他們強調科學的研究形式,追求研究對象的科學確定性,以形成知識,剛好事與願違。以現代主義者追求科學確定性的目標,無法解釋這些較有力量和權威的詮釋,為什麼反而成為是歷史研究裡大家討論的事實。也就是說,偉大歷史著作自身發展的歷史,一直無法確定歷史真實何在,反而成為後續研究者可討論的事實,對現代主義者的觀點而言,他們無法解釋這些可討論的的事實,如何是歷史知識和科學進步的基礎。在一個歷史主題中,二手詮釋觀點主導我們對歷史寫作的思路,甚至成為過去真實的部份,模糊化歷史主題中真正的過去,而變成歷史主題詮釋的歷史;過去真正的事實,永遠無法呈現出來,一直伴隨著歷史主題詮釋的系譜流動的,使我們無法掌握。因此,強調科學的研究形式,來認識歷史研究的對象,建立歷史知識的範疇,隱含歷史思考的弔詭。

    +

    現代主義者的觀點,企圖以科學思考為出發點,他們認為歷史貴在求真(實證式的),我們如果將這些「真」(文獻記載的陳述)找出來歸納在一起,那麼我們就可形成大家認可的歷史,以後這段大家認可的歷史就可形成定論。但是現實的歷史研究,靠訴我們歷史的「真」不斷的被重新歸納重寫,將相同歷史主主題的寫作並列,我們會發現何以大家的「真」或歸納綜合的「真」,都不盡相同,以致於我們會該相信誰的「真」。按照歷史研究科學的思考,由於文明不斷的進步,更新的科學方法和文獻不斷的出現,使我們更能研究出歷史之真實為何,也就是現在的研究會比過去的研究更接近歷史之真,相同的未來會比現在更接近歷史之真,因此我們應該相信時代愈後的研究成果。但是這般的思考,對我們來講,似乎歷史寫作的「真」當被往後的「真」取代,而為真正的「真」,如此的結果那麼我們所知到現在的歷史之「真」,在未來看來則永遠肯定是「假」不會是真正的「真」,構成一個循環性的吊詭。

    +

    另一方面,科學思考確保研究對象的認識基礎,也是科學的思考最重要的規範之一,就是因果解釋。在因果的原則中,原因是起源而結果是第二給予的。因果法則確立後,歷史的對象可以依此為研究者所掌握。但在歷史研究中,事實上,因果關係通常被倒轉過來,結果往往優先於原因被給予,原因才是第二給予的,致使結果是原因的原因,結果應該是被當做起源被處理,如此則研究事物的秩序和真實,無法遵尋因果順序自身的原則,暴露研究法則與實際操作的背道而馳,也顯示出因果組織是給定的人造物。因此我們可說科學思考是被建立的,強調科學的理性思考,所導衍出的因果順序法則,是不證自明的,是一種錯誤的概念,由此產生對事物的洞識,所認可的真實往往被不真實所沾污。

    +

    對事物的洞識,其真實性往往被不真實所沾污,我們可以從邏輯和本體論兩方面來瞭解,並由此產生後現代主義對歷史寫作性質的觀念。在邏輯方面,對現代主義者而言,其科學確定性使研究者正確判斷其使用的陳述句可以指涉真實與否,但是陳述句表述事物時,卻通常會出現陳述指涉上說謊者的弔詭。例如:克里特人說:「所有的克里特人都是說謊者。」我們將此句放在陳述句的陳述上,就是「這個陳述是不真實的陳述」,而這個陳述是一個關於自身的陳述。其中弔詭發生之處,在於陳述句無法陳述或判斷自身是否是真或假。因此,科學的確定性並不能保證我們使用陳述句來表達事物的真與假。而在多個陳述句的綜合,亦無法保證可以呈現所指事物的真實與否(傳統的實在論觀點,認為個別陳述的事實總合等於整體的實在)。於此後現代主義者的解決之道,就是擺脫現代主義者的思考路俓,認為陳述本身並不能辨識其所指的事物的真假,但是如果我們還要能認知陳述,就必須將陳述放在其構成的自身脈絡中來理解,也就是陳述的主題,並且陳述的特徵是反應主題的屬性(傳統的觀念論觀點,認為個別陳述是其整體的屬性),不是命題的部份。而在對過去的歷史詮釋(由陳述的子集建立的主題),就必須對比其它的詮釋,才能被辨識;歷史詮釋只有在它們不是什麼的基礎上,才知道它們是什麼。也因此單個歷史詮釋及其產生的歷史洞識,其內涵上都有一個弔詭的性質(因為單個歷史詮釋一點也不能讓我們知道任何現象的詮釋)。

    +

    在本體論方面,前述現代主義者確保研究對象的認識基礎,也是科學的思考最重要的規範之一,就是因果解釋,它經由語言的媒介能提供呈現外在事物的真實能力。在後現代主義的看法,因果解釋是被預設的,其使用的語言並不是透明的媒介物,語言和實在是無法區分的,科學的語言不是「自然的鏡子」,而是一如實在商品目錄的一部份是科學研究中實在的對象。語言被使用於科學中同樣是一件事物,在實在中的事物需要一個擬似語言的性質,反之亦是。也就是事物的實在經由語言呈現出來,呈現的無法是事物本身,還加上語言本身,使我們知覺到的是語言和實在混合一起的東西,你中有我,我中有你。例如,馬克思說明生產力和生產關係的衝突,彷彿他討論的是關於實在的陳述代替實在的外貌。相同的,歷史家想要看見相同的獨特性,寫實化歷史語言當作是歷史現象的特徵。因此,歷史家(馬克思是一例子)潛藏的反抗語言和實在的二分法,懷有此種後現代主義對語言與實在關係與性質的思考。

    +

    既然語言與實在之間的二分法是沒有必要,後現代主義對歷史寫作的思考走向美學主義,認為小說家和歷史家的語言都給我們一個實在的幻覺,既是虛構的也是真實的,一如藝術家的工作,並不是單純對實在的再現。藝術的語言不是實在一個模仿的再生產,而是它的取代或替換。語言和藝術不是反對實在,而是將實在本身當做一個擬真實和因此在真實之中。

    +

    這種美學主義給歷史寫作性質它需要的洞識,就是風格化的尺度。現代主義者的觀點,認為歷史寫作最重要的部份是內容,風格是不相關的。在後現代主義的看法,當歷史家研究相同主題的各方面,結果它們不同在於內容,可能會被當做是研究主題風格或形式的不同。例如關於文藝復興的戰爭和文藝復興的藝術,是寫作文藝復興的不同方式,其風格暗含著是由內容來決定。但是鑑於歷史觀點的不可比較性,風格常優先於內容被用來區分研究主題寫作性質的不同。假若我們要保證有關的歷史討論,其有意義的進步,就必須注意風格而不是內容,是歷史討論中的爭論點。

    +

    此外,重風格而輕內容的作法,是來自於對歷史寫作「意向性脈絡」的強調,認為寫作中的陳述,不可被其它的陳述取代,甚至是相等於該陳述的其它陳述,就是同義語的替代。因為在一個意向性脈絡中的陳述,其精確的形式被假定是為了陳述實在(寫作本身)的必要條件。後現代主義的觀點,認為「文本之外無物」,歷史寫作或文學文本經由語言無法保證其呈現外在事物真實的能力,而是朝向作品自我的真實,文本所選的字詞,規定了寫作的觀點與語言之間的關係,其形式決定寫作性質的獨特性。

    +

    由此我們可說歷史寫作的性質是接近於藝術工作,而與科學研究的特徵有差異的。科學語言是透明的,呈現實在的媒介,假如它妨礙實在的視域,它將要必須被再精煉,因此歷史寫作的歷史表明,歷史寫作是現在不斷的超越過去,未來必定也不斷的優越於現在與過去。但是前述實際歷史寫作的歷史,一些偉大的歷史作品,它們較有力量和權威的詮釋,反而是後來著作可討論的地方,產生更多的出版品。歷史研究者關注偉大的歷史作品的詮釋觀點,不在於他們作品他們已經呈現某時期歷史真實,因為如此則此時期歷史可被終結,而在他們歷史作品的詮釋觀點,表現出他們作品自身的意向性脈絡,呈現其寫作性質的獨特風格,具有不可替換的意義。如果以科學語言的屬性來說,他們的詮釋觀點應該早被拋棄,而事實剛好相反,研究者通常對比於他們的詮釋觀點(這就是何以現在的歷史寫作中,充滿了二手詮釋的觀點),朝向更多不同的歷史詮釋觀點。

    +

    如果我們同意以上的說法,就可以知道歷史證據的使用,在現代主義者和後現代主義者的差別。現代主義者,以科學的視野看待證據,本質上是某些過去發生的證據,過去歷史的真實隱藏在這些資料之後;而後現代主義者認為,證據不是指向過去而是其他的過去詮釋。其中的差別我們舉個比喻:現代主義者認為,證據是一片瓦,由歷史研究者拾起以看見它的下方;相對於後現代主義者,證據是歷史研究者踏在上方的一片瓦,為了移動到另外的一片瓦。證據從現代主義者到後現代主義者的觀點,是水平性取代了垂直性。

    +

    後現代主義對證據的見解,反應了現今歷史研究真正發生的狀況,證據不是一個我們能研究過去的誇大玻璃,而是產生相像於畫家使用刷子的手法去達到一個確定的效果;證據不是將我們送回到過去,而是升起歷史研究者在這裡和現在能做的或不能做的問題。證據組成歷史寫作,引起研究者去組織歷史的證據,是研究者最感性趣的證據。證據被發現的是,不是被說出的地方,在以往的代沒有從證據說出的部份。也就是一個時代的大部份特徵,是不被其時代本身知道,而是由較後時代發現說出。前一時代的歷史,往往是由較後時代來決定,對照於前一時期不是被說的或悄悄地說的、或被表達在微不足道的細節裡(現今的歷史研究中,新興主題的歷史研究都是如此信念)。而證據本身不是被說的事實是較後時代歷史研究者生活和寫作的心理狀態反應,經由對抗證據記錄者的時代心理狀態,決定證據所指時代的要點和意義,此時代的要點和意義是朝向歷史研究者所處時代讀者的呼喚,產生了對前時代(過去)的歷史寫作。因此,過去時代的歷史只顯示在證據記載此時代的過去與較後時代心理狀態之間的不同處。

    +

    在此,後現代主義對證據性質的思考,拉近歷史學和心理分析之間的關係。心理分析教導我們去瞭解什麼是精神病患說的,嘗試在精神病患言說的表面之上投影出一個模型,但不引導我們的注意一些數量元素的因果,可以在精神病患心智中彙整出人體模型,也不表明精神病患的心智有什麼是本質於精神分析詮釋的內容,亦即不去蒐尋在精神病患背後隱藏什麼真正的事實。在歷史學,同樣的我們應該去注意什麼不是被說的和什麼是被壓抑的,正如我們是什麼我們不是的,不想要是的,或在一個過去的確定意義上,什麼是它不是的。也就是後現代主義者對於人或歷史性質的認知,不是要將之當作一個實體,求得過去的真實何在,以發現人或歷史的本質是什麼,以用來思考所有其它人和歷史,而是當作一個美術拚圖,發現一些次要的和似乎是不相關的細節的個別特徵。

    +

    在傳統的歷史學中,常隱含了一些對人或歷史本質性的論述,經由後現代主義的思考途徑,是想解除這些隱含在歷史寫作後設的本質性論述。這些論述,由奧古斯丁 (Augustine) 神學的歷史觀念,和在科學進步中,盲目的信仰進步的觀念,而產生奧古斯丁神學的歷史觀念的世俗化變體,組成的後設敘述。在過往的歷史研究者,總是以此論述握有過去和將之當作理解每一件事的基礎。以一個比喻來說,歷史學的歷史是一個樹,在西方歷史寫作內的本質性的傳統就是這顆樹的樹幹,近代的現代主義者的科學式歷史寫作就是這顆樹的樹枝,由此建構西方歷史的統一。而在後現代主義的歷史寫作,選擇的是這顆樹的樹葉,拒絕進入這顆樹的樹幹或樹枝,再度重新建構此中的本質主義性質。亦即後現代主義者不再去整合、綜合或總體化本質中心的歷史,而是反本質主義,追尋本質中心的歷史殘餘物。其來由是當秋天的風一來掃落這些樹葉,這些樹葉就遠離了樹幹和樹枝,就不再與傳統的本質主義有連繫。

    +

    從今日非西方世界的興起,逐漸瓦解西方傳統的歷史論述,西方歷史的這顆樹,只不過是一片森林的一顆樹,使過往文化種系發生史的主張被打破,就像是這秋天的風吹起,而掃落了樹上的樹葉。面對這種情勢,後現代主義者提出的作法,就是放掉西方本質主義的歷史脈絡,不再以後設敘述來連接歷史根源與脈絡,和傳統的寫作範型籓籬,使寫作既不是文學產品,或思想史,或精神哲學,或認識論,或社會預言等,而是蒐集這些掉落的樹葉混合出一些新式樣的寫作。

    +

    此種新式樣的寫作,使每一件事在顯著的(歷史寫作)共同關係中,變成是當代的,也使每一件事也變成了歷史。也使歷史是相像於現在,現在的意義有採用過去的特質中;不去塑造我們根據或一致於過去(構造一個後設敘述),而是學習去扮演我們關於歷史的文化遊戲。也就是說,所有的歷史文本都是當代的,過去的詮釋是現在的思考與理解,思考關於過去的概念能在當代文化被讀者認識。

    +

    因此,歷史寫作的重要性不在於我們能否重構過去,而是其意義的部份。這讓我們可以解釋為什麼一些偉大的歷史寫作,他們歷史觀點引起許多的批評,但是對歷史的詮釋仍然不失它的魅力,就是他們的歷史寫作中的詮釋概念,具有當代性質。這之中較有力量的,能使歷史寫作產生決定性價值的,並不是在於呈現真正過去的真實能力,而是其採用的歷史概念在隱喻性質上能力。因為我們是無法以純粹的過去事實(過去只發生一次),來批評他們提出的歷史概念,到底錯誤何在,以致於進ㄧ步建構過去,只能對照於其它相同主題的研究,找出此偉大的歷史寫作起作用性質為何,也就是歷史寫作字面上和事實之外的部份。這使著歷史寫作焦點也不再是過去本身,而是在現在與過去的不相稱處之間,及在我們現在地使用語言談論關於過去和過去本身之間,找出這個屬於當代心理狀態下反應出的隱喻性質,而可以理解其歷史寫作的意義。

    +

    最後,我們總結歷史學與後現代的關係。依附著對當代文化討論而來的洞識,如解構主義,及對歷史寫作的現象分析,荷蘭歷史學者安克斯密的〈歷史學和後現代〉一文,以現代主義與後現代主義的術語之分,闡釋傳統(實證史學)歷史寫作性質面對當代歷史寫作現象的矛盾,以及本身對歷史真實思考的弔詭,無法走出其製造的困境。而以後現代主義的思維,提出歷史寫作性質的新見解。期望能解釋當代歷史寫作現象,肯定歷史寫作在美學主義性質上的意義,提供新方向的思考,並且能打破壟斷的科學歷史寫作迷思,使歷史寫作能有更豐富的內涵。

    + +

    參考書目

    + +
      +
    • Ankersmit, F. R. “Historiography and Postmodernism,” History and Theory, vol. 28, no. 2 (1989): 137-153.
    • +
    • ________. “Reply to Professor Zagorin,” History and Theory, vol. 29, no. 3 (1990): 276-296.
    • +
    • Zagorin, Perez. “Historiography and Postmodernism: Reconsiderations,” History and Theory, vol. 29, no. 3 (1990): 263-275.
    • +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/001/article04.html.html b/htdocs/htc/newsletters/001/article04.html.html new file mode 120000 index 0000000..ad4a043 --- /dev/null +++ b/htdocs/htc/newsletters/001/article04.html.html @@ -0,0 +1 @@ +article04.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/001/article04.html.xhtml b/htdocs/htc/newsletters/001/article04.html.xhtml new file mode 100644 index 0000000..d7f48f7 --- /dev/null +++ b/htdocs/htc/newsletters/001/article04.html.xhtml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + +馬克思主義/史學/後現代:多元基進的辯証 + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    馬克思主義/史學/後現代:多元基進的辯証

    + +
    +引言人:徐文路
    +撰 稿:徐文路
    +時 間: 98.01.12
    +
    + +
    +

    每當人類遇到前所未曾經驗過的新事物之際,雖然他不能完全理解,更看不出其中的所以然來,卻往往搜索枯腸,想要為這未知的現象找出一個名目。

    +
    + + +
    +

    道可道,非常道;名可名,非常名。

    +
    + + +

    從 1997 年回溯,史學專業化的發展至今已將近兩個世紀。對於西方而言,近兩百年來,史學本身的發展高低起伏,時盛時衰。不但史學內部對自身學科的反省不斷,外面各種學科也對史學形成挑戰。然而在諸多牽動史學本身變化(研究取向和主題的轉變、對史學原理提出修正或質疑的看法等等)的因素裏,有一個很重要的動力,來自於外在政治社會的變動。馬克思主義便是其中之一。

    +

    馬克思主義從 1840 年代馬克思著文立說開始算起,和史學專業化發展的時間相差不多,也有一百五、六十年。它是一種學術思想,同時也是一股政治社會變革的力量。馬克思主義對史學的影響,不但是在史學研究的內部,同時也在人們所處的社會歷史本身。哈布斯邦在 1968 年寫了一篇名為〈馬克思對史學的貢獻〉的文章1 ,可以做為我們討論的基礎。

    +

    哈布斯邦評價自蘭克 (Leopold von Ranke) 以來的專業化史學發展,可說是褒貶參半。一方面他讚許專業化史學帶動了科學的研究方法,讓史學研究的水準提升;另一方面他認為這一波史學研究的潮流有三個缺點:一、這些學者認為自己的立場是客觀中立的;二、研究主題侷限在政治史、軍事史和外交史,其他的主題幾乎不聞不問,甚至認為那些不是歷史(歷史是用來研究「重大事件」的—蘭克語);三、這些學者一頭栽進檔案史料裏,再也不具備博學者的氣質2 。由於這些問題,引起了另一波高舉反蘭克大旗的史學浪潮,而這一波的浪潮在各國受馬克思主義影響甚大。影響主要來自馬克思主義式的政治社會活動及其所帶動的思想浪潮,即哈布斯邦所說的 " 庸俗式的馬克思主義" (vulgar-Marxism)3 。他認為庸俗式的馬克思主義雖然在反蘭克運動上扮演了積極的角色,但是由於「一切為政治目的服務」,不但僵化了馬克思的思想,把歷史唯物主義 (historical materialism)4 簡化成某種機械論 (mechanism) ,而且也造成馬克思主義的史學研究只侷限在若干主題之上,比如資本主義的發展、工人和農民被壓迫的歷史之類的主題。尤有甚者,在解釋歷史的時候,往往是粗糙僵化的(三十年戰爭之所以打了三十年而不是更快或更慢,是由經濟因素決定的)5 。有鑑於此,他認為有必要把馬克思主義的歷史思想中,對於今日史學研究有助益的地方說清楚。

    +

    首先,哈布斯邦認為,馬克思主義這些年的發展,儘管有上述的問題存在,卻促進了歷史這門學科的科學化。所謂科學化,並非像實証主義 (positivism) 那樣,認為人類社會的變化和發展可以等同於自然科學,而是求真的研究態度和方法。他指出,馬克思主義常常被一些實証主義式的思考弄得不三不四,這種思考把馬克思對資本主義的分析看成是穩定的、恆常不變的社會型態。他認為像阿圖塞 (Louis Althusser) 、李維史托 (Claude Levi-Strauss) 之類的結構主義者的理論就具有這樣的危險性6 。另外,由於庸俗式馬克思主義大行其道,而且它本身也沾染上實証主義的色彩,使得馬克思主義被世人誤解成「經濟決定論」。事實上要分辯馬克思主義和實証主義的差別很簡單。一、馬克思認為人類社會確實存在著一種社會階級;二、社會內部有著各種各樣的矛盾 (contradiction) ,階級矛盾是很重要的矛盾,但只是其中之一;這兩點都是實証主義所忽略的。

    +

    其次,馬克思強調歷史性的分析。所謂歷史性的分析,套個現在流行的術語,是貫時性 (diachronic) 和共時性 (synchronic) 並行的分析方式,這是透過各種矛盾的發展和克服連結而成的。而實証主義很明顯只有共時性的思維7

    +

    哈布斯邦的文章在批判實証主義(包含廣泛意義上的結構功能論)和機械論之後,以期許馬克思主義史家再接再勵做為結束。這是 1968 年的作品。而 1968 年對馬克思主義來說,是個又愛又恨的年代。社會主義陣營內部在 1956 年終於克服了史大林 (Joseph Stalin) 的陰影,蘇共總書記赫魯雪夫 (Nikita Khrushchev) 於蘇共二十大清算了史大林的個人崇拜,並對紅色恐怖時期的政治整肅進行平反。但是就在同年,蘇聯的坦克車也壓碎了匈牙利的自發性革命。這兩件事都對戰後馬克思主義陣營內部8 的發展造成了重大的影響。清算史大林的直接影響就是馬克思主義中人道傾向的復興,而鎮壓匈牙利革命卻使得社會主義的民主化幾乎變成了「不可能的任務」。後者整體的負面結果,這裏用一句話來代表,即馬克思主義及社會主義國家、政黨的公信力受損。最明顯的反彈則來自於西歐的左翼知識份子。以英國的馬克思主義史家來說,哈布斯邦和湯普森 (E. P. Thompson) 恰是兩種代表性的做法。前者對共產黨及馬克思主義思想提出批評,但仍留在英國共產黨內;而後者甚至宣佈脫離共產黨,但還是堅持身為一個馬克思主義者9 。大體上,西歐知識份子對黨的信心的確產生危機,但是卻都還不到脫黨的地步,更不會對馬克思主義產生質疑,可是危機感並未隨著時間推移而緩解,反而漸漸蔓延。到了 1968 年,戲劇性的變化出現,學生運動的火苗繼 1848 年之後再次以全歐的範圍在各地延燒,而巴黎也「按照慣例」首當其衝領銜演出。可是,就在「天下大亂,形勢大好」的情況下,法國共產黨的表現著實令學生錯愕,不但不支持學生運動,甚至指責像龔.本第 (Cohn-Bendit) 之流的學生為無政府主義者10 。這還不算什麼,最讓學生失望的是法國共產黨後來竟然和戴高樂 (Charles De Gaulle) 妥協,同意解散國會,重新改選,而不是成立左翼聯盟建立新政權(後一路線是共產黨和社會黨等左派政黨先前的聯合規劃,也是學生希望達成的)。一波波革命的希望一再被政治的現實當頭澆冷水,共產黨在學生和知識份子的心中日益成為墮落的代名詞,消極的人走向了無政府主義,積極的人重組「非共左派」做為前進的基地。

    +

    這樣的情況不只在法國(最主要仍是法國),而是全歐性、全球性的。當馬克思主義的理念隨著知識份子對共產黨的失望而喪失魅力之後,思想上的真空則被一股「後」 (post-) 的風潮所填補:後馬克思主義 (Post-Marxism) 、後結構主義 (Post-structuralism) 、後現代主義 (Post-modernism) ……等等。唯一在這股「倒馬風潮」中挺立的剩下阿圖塞主義 (Althusserianism) 、美國分析學派的馬克思主義和極少數大家如哈布斯邦、哈伯瑪斯 (Jürgen Habermas) 、科萊蒂 (Lucien Colletti) 等人,以及托派的曼德爾 (Ernest Mandel) 、安德森 (Perry Anderson) 等。

    +

    馬克思主義內部面對後現代的衝擊雖然也有正反兩方的意見,可是大體上都不會自詡為後現代主義者。不要說像哈伯瑪斯和哈布斯邦之類持批判態度者,就連詹明信 (Fredric Jameson) 、拉克勞 (Ernesto Laclau) 和穆芙 (Chantal Mouffe) 等一般被歸類為「後馬克思主義」的人,不但在他們的著作當中絕口不提「後現代」一詞,即使在使用所謂後現代概念的詞語時,幾乎都是以補充或加強馬克思主義的概念為依歸,或是強調後現代的一些主要概念係受馬克思主義的影響。以詹明信為例,他對於 60 年代以後這股「後」的風潮抱有如下的看法:

    + +
    +

    「太凱爾」 (Tel Quel) 小組的成員,例如巴特 (Roland Barthes) 、德希達 (Jacques Derrida) 、布希亞 (Jean Baudrillard) 、里歐塔 (Jean Francois Lyotard) 等人在假定這個問題(指「表述」或「再現」 Representation )存在的同時,又把他們自己的著作在馬克思主義詮譯學中增加了若干疑難問題;……但是上述所有人所寫的著作,都建立在一個更為基本的主導文本,即阿圖塞《解讀〈資本論〉》 (Lire 'le Capital') 的假定之上。11

    +
    + +

    在這篇名為〈馬克思主義與歷史主義〉的文章裏,詹明信把諸多著名的所謂「後現代主義」的哲學家用「後結構主義者」的名號混用,把他們對歷史的看法統稱為「尼釆式反歷史主義的立場」12 。所謂「尼釆式反歷史主義」,詹明信所指的是尼釆對黑格爾的歷史哲學的反動,一個是單線發展的歷史觀,一個是對黑格爾的辯証法的否定。在這裡,阿圖塞所扮演的角色基本上有兩種,一個是這些人對馬克思思想的理解(一種新的詮釋),另一個則是他們對待人文理論的態度:理論生產既不是真實客體的表述,也不是關於真實客體的研究 -- 科學以批判在其之前的意識型態理論實踐中的意識型態「真實」來証明自己的科學真實13 。這種看法雖然某種程度上使得阿圖塞跟上述其他人的文本主義 (textualism) 特徵掛在一起,可是這其中也凸顯詹明信的觀點,即阿圖塞與後現代主義者似乎過從「甚密」。

    +

    另外,拉克勞和穆芙在其著作中,雖然明指她們的分析主線是從葛蘭西 (Antonio Gramsci) 有關文化霸權 (hegemony) 的概念做變革為起點,但是她們之所以要馬在革命理論上有所變革,乃因在現實上和理論上受到多元因素的刺激14 。現實上的刺激指的是以族群、生態和性別為主的新興社會運動在第二次世界大戰後以全球為範圍大量出現,而理論上則是阿圖塞對傳統馬克思主義中有關「矛盾」的觀點做進一步研究所發展出的「多元決定」 (overdetermination) 論點。簡單來說,阿圖塞認為,馬克思原有的二元辯証架構不足以解釋社會各部門、各種力量較勁競逐的多元實況,於是提出所謂的多元決定論,其實這和哈布斯邦強調的階級矛盾不是唯一的矛盾若合符節。從這裡可以看得出來,馬克思主義陣營內部對後現代的探索,阿圖塞幾乎是必經的路徑。所以,阿圖塞對歷史的看法對本文的主題 -- 馬克思主義、後現代和史學的關係就變得非常重要了。

    +

    阿圖塞的理論中,除了上述兩個部份對馬克思主義探索後現代有重大影響之外,主要還有兩個部份對史學有直接影響。首先就是前面提到哈布斯邦擔心的部份,即結構主義的思考方式會造成把社會視做穩定不變的社會結構,以及太過重視共時性分析。阿圖塞的理論的確有這樣的危險性在,雖然哈布斯邦對阿圖塞結構主義的印象顯然主要來自於派森思 (Talcott Parsons) 和李維史托而不是阿圖塞本人。阿圖塞在 1970 年代時曾坦率承認他在 1960 年代的若干主要著作中的確犯了一些錯誤,即在表達自己的想法時常常「不小心」玩弄起結構主義的用語15 ,但是他的理論重心絕對不是結構主義,不但在他自己的聲明中,或是若干深刻研究阿圖塞的理論的人都可以証明這點16 。相反的,阿圖塞重視這兩個部份的結果是他對意識型國家機器 (Ideological state-apparatus) 精闢的分析,促進了歷史唯物主義的理論研究。

    +

    其次,阿圖塞強調馬克思主義的科學性,在 1956 年以後的馬克思主義發展史上看來雖然孤獨,卻是必要的:歷史唯物主義的作用是雙重的,一方面是解釋歷史,一方面是改變歷史。解釋歷史必須有科學求真的態度方能有合理的解釋,而不是像知識的虛無主義 (nihilism) 一般任意編造故事;而改變歷史更須要在歷史研究中指出由若干現象中展現的趨勢或規律,並具有相當程度上的普遍性才能說服大眾,科學則是獲得人們信任的有效保証。這也是哈布斯邦在面對機械論時不得不承認的部份17 。但是阿圖塞提出「歷史是沒有主體的過程」 (history as a process without subjects) 這一看法,著實讓人們驚訝,而且似乎與之前的說法有直接的矛盾,其實不然,這必須回到阿圖塞對人道主義和觀念論歷史哲學的批判上才說得清楚,這不是本文重點。

    +

    可以這麼說,馬克思主義對歷史的研究和理解的雙重性,仍將是綿延不絕的思考方式,科學性是它對歷史這門學科在研究態度上的基本原則,雖然歷經後現代這波猛浪衝擊,卻沒有被打敗,不過也做了若干反思和修正 -- 畢竟後現代的社會分析仍是跳不出馬克思對資本主義社會批判的概念,馬克思主義者永遠要注意的可能不是外力衝擊來自何方,而是何以禍起蕭牆。

    + +

    後記

    + +

    一九九八年一月十二日,承蒙輔大歷史研究所學生主辦的「後現代主義與史學」系列研討會之邀,筆者以「馬克思主義/史學/後現代:多元基進的辯証」提出本文以供師生共同討論。由於在研討會中不少同學的指正和問題,意見極為寶貴。因此,筆者謹以後記聊誌謝意,並做為討論之後的增補。

    +

    同學們的意見主要在於兩個部份,一是阿圖塞的思想在馬克思主義和後現代主義之間的地位,是否如筆者所言這般重要;另外,則是馬克思主義在面對後現代主義的衝擊時如何自處,這個部份又分別從馬克思主義的整體性以及如何處理後現代主義。以下,筆者謹就上述兩個問題,提出本人之看法。

    +

    第一個問題,就筆者目前的理解來看,阿圖塞的位置的確非常重要。首先,結構主義在 1960 年的大鳴大放,是法國本身理性論哲學與結構主義之間具有共容的基礎,這其中最重要的哲學家就是斯賓諾莎。他調節了笛卡爾心物二元論的不歸路,從一元論的角度出發,透過上帝為媒介,把形上思考的結構和事物的秩序之間聯結起來。而 1960 年代首先把斯賓諾莎拉回到現代的人,就是阿圖塞。而後現代主義在法國思想界的重要特徵,便是從結構主義到後結構主義的轉換。

    +

    第二個問題,我在本文文末便已稍微提及,馬克思主義者基本上都不認為,後現代主義是有別於資本主義社會的另一種社會型態。詹明信稱其為「晚期資本主義」的社會特性,是取自托派的政治經濟學家曼德爾的說法。但是後現代主義對現代性的批判,在某些部份的確超越了資本主義和社會主義的社會概念,如事物的整體性的問題。一方面,反對現代性的看法,法蘭克福學派的阿多諾、馬庫色等人早已提出,只是當時他們把這些問題歸諸於資本主義的發展所致,近似於韋伯「工具理性」的問題意識。另一方面,馬克思主義的系譜,至今難以詳載,把排在最左邊的人名和最右邊的人名放在一起,可能會有人不相信他們同是馬家幫的人馬。所以馬克思主義的整體性,在今日的確很難做到。 1970 年代,拉丁美洲和非洲的知識份子融合了列寧、羅莎.盧森堡等人的帝國主義論述,和戰後的民族解放的政治現實,分別提出了異曲同工的「依賴理論」和「不均衡發展」,企圖把資本主義世界中各種型態的社會發展,融合成一個有機分層的體系,但是未竟全功(在台灣,拜學術宗主國美國之賜,「依賴理論」還有幸得聞,在解嚴之後的若干年少量進口來台;「不均衡發展」對大多數人而言,可能連聽都沒聽過。因為非洲是歐洲的,拉丁美洲才是美國的?)。但是,只要資本主義的運作一日不墜,馬克思主義對其理論整體性的追求也不會停止,這應該是很明顯的。

    + +

    參考書目

    + +
      +
    • Hobsbawm, E. J. “Karl Marx's Contribution to Historiography,” Diogenes, no. 64 (Winter 1968): 37-56.
    • +
    • Habermas, Jürgen. The Philosophical Discourse of Modernity. tr. Frederick G. Lawrance. Cambridge, Mass.: The MIT Press, 1991.
    • +
    • 中共中央馬恩列斯著作編譯局編,《馬克思恩格斯選集》第三卷,北京:人民出版社, 1995 。
    • +
    • 國立中興大學編,《國立中興大學第三屆史學史國際研討會論文集》,台中:國立中興大學出版社, 1992 。
    • +
    • 高宣揚,《沙特傳》,台北:蒲公英, 1989 。
    • +
    • 張京媛編,《新歷史主義與文學批評》,北京:北京大學出版社, 1993 。
    • +
    • Laclau, Ernesto & Mouffe, Chantal ,《文化霸權和社會主義的戰略》,陳墇津譯,台北:遠流, 1994 。
    • +
    • Althusser, Louis ,《自我批評論文集》,杜章智、沈起予譯,台北:遠流, 1990 。
    • +
    • Collinicos, Alex ,《阿圖塞的馬克思主義》,杜章智譯,台北:遠流, 1990 。
    • +
    • 彭贇,《阿圖塞思想新探》,台北:唐山, 1993 。
    • +
    • Best, Steven & Douglas Kellner ,《後現代理論 -- 批判的質疑》,朱元鴻譯,台北:巨流, 1994 。
    • +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +
    + +
      +
    1. E. J. Hobsbawm, 'Karl Marx's Contribution to Historiography,' Diogenes, no. 64 (Winter 19680): 37-56. (Back)
    2. +
    3. Ibid., pp. 37-39. (Back)
    4. +
    5. Ibid., p. 42. (Back)
    6. +
    7. 這個名詞首先由恩格斯提出,用來統稱馬克思的歷史思想。詳見恩格斯,〈社會主義從空想到科學的發展〉,收錄於中共中央馬恩列斯著作編譯局編,《馬克思恩格斯選集》第三卷 ( 北京:人民出版社, 1995) ,頁 740 。 (Back)
    8. +
    9. Ibid., p. 44. (Back)
    10. +
    11. Ibid., pp. 50-51. (Back)
    12. +
    13. Ibid., p. 46. (Back)
    14. +
    15. 所謂 “ 馬克思主義陣營內部” 實質上所含蓋的範圍,主要是當時的社會主義國家,尤其是蘇聯和東歐集團及共產中國,同時也包括了世界各地非社會主義國家的共產黨或是以馬克思思想為政策指導的各種名稱的政黨和團體。(有些是合法政黨,有些則否,甚至還有一些是遊擊隊)。 (Back)
    16. +
    17. 有關 1956 年對英國馬克思主義史家的影響,詳見周樑楷,〈 1956 年對英國馬克思史家的衝擊〉,《國立中興大學第三屆史學史國際研討會論文集》 ( 台中:國立中興大學出版社, 1992) ,頁 235-261 。 (Back)
    18. +
    19. 高宣揚,《沙特傳》 ( 台北:蒲公英, 1987) ,頁 231 。 (Back)
    20. +
    21. Fredric Jameson, 'Marxism and Historicism' ,張京媛譯,收錄於張京媛編,《新歷史主義與文學批評》 ( 北京﹔北京大學出版社, 1993) ,頁 17-51 ,節錄的文句出自第 17 頁。這篇文章是詹明信對「意識型態諸理論研究」的其中一部份。 (Back)
    22. +
    23. 前揭書,頁 41 。 (Back)
    24. +
    25. 前揭書,頁 43 。 (Back)
    26. +
    27. Ernesto Laclau & Chantal Mouffe ,《文化霸權和社會主義的戰略》,陳墇津譯 ( 台北:遠流, 1994) ,頁 5-7 。 (Back)
    28. +
    29. Louis Althusser ,《自我批評論文集》,杜章智、沈起予譯 ( 台北:遠流, 1990) ,頁 144 。 (Back)
    30. +
    31. Alex Collinicos ,《阿圖塞的馬克思主義》,杜章智譯 ( 台北:遠流, 1990) ,頁 7-8 。而中文學界中有一本可以說是最傑出的研究也是同樣看法,詳見彭贇,《阿圖塞思想新探》 ( 台北:唐山, 1993) ,頁 218 。 (Back)
    32. +
    33. Op cit, p. 42. (Back)
    34. +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/001/article05.html.html b/htdocs/htc/newsletters/001/article05.html.html new file mode 120000 index 0000000..fe3ea71 --- /dev/null +++ b/htdocs/htc/newsletters/001/article05.html.html @@ -0,0 +1 @@ +article05.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/001/article05.html.xhtml b/htdocs/htc/newsletters/001/article05.html.xhtml new file mode 100644 index 0000000..2d33797 --- /dev/null +++ b/htdocs/htc/newsletters/001/article05.html.xhtml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + +Review of The Great Cat Massacre and Other Episodes in French Cultural History + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    Robert Darnton, The Great Cat Massacre and Other Episodes in French Cultural History. New York: Vintage Books, 1985, xiii + 298 pp.

    + +
    潘宗億
    + +

    一、著作之主旨

    + +

    本文所要介紹與評論的著作,是由羅伯‧達頓 (Robert Darnton) 所撰述的《屠貓記及法國文化史上的若干插曲》( The Great Cat Massacre and Other Episodes in French Cultural History, 以下簡稱《屠貓記》)。

    +

    《屠貓記》一書主要由六個章節所構成,每一章節皆根據達頓所選定的「文本」為基礎進行論述。筆者認為,本書雖然分別獨立為六個不同社群的對像與主題的論述。但是,其中仍隱約可見達頓企圖表達出一連貫的主旨與論點;作者對此一連貫之主旨與論點的敘述脈絡,表現在對每一章節所代表的處於不同社會階層之社群的世界觀的建構,並同時在若干章節進行法國與其他國家的比較,企圖凸顯與建構所謂的法國性 (Frenchness) 。此六個章節則分別為「農民說故事」、「工人叛變:貓之大屠殺」、「一個中產皆級的世界觀:城市作為一個文本」、「一個檢查官員的檔案分類:文學界的分析」、「哲士的知識系譜:百科全書派的認識論策略」、「盧梭與讀者的對話:浪漫感性的具體化」。

    +

    《屠貓記》一書之作者羅伯‧達頓( Robert Danrton, 以下簡稱達氏),在導論的卷首即開宗明義的向讀者揭示了其著作的旨趣,他說:「本書在探究十八世紀法蘭西的思維方式。」1 他希望透過此書一系列主題之研究,從中獲知法國人如何思考?在思考什麼?又如何在心靈中建構他們所處的世界?2 筆者認為,達氏企圖從文化史的研究取向出發,透過對法國社會之中下層文化 (low culture) 到菁英文化 (high culture or culture of elite) 的整體描寫與分析,具體呈現文化如何形塑了人們的思考方式,3 及法國知識分子與一般人民之間如何形成對若干問題的整體性,4 再進而描繪一幅關於十八世紀法國人之世界觀的圖像。

    +

    從本書整體行文的架構與主題來分析,作者的確排列出一個由「模糊不明確的世界觀」逐漸過渡到「較明確而清晰的世界觀」的光譜,具體呈現了「下層文化」到「菁英文化」的過渡性。此外,從在這道作者所描繪的光譜圖像當中,讀者可以從達氏所處理的主題與對像中,察覺其所呈現的若干意義。

    +

    首先,從社會結構與社群上的分布層次來看,其所處理的主題,包括了從一般的農民、城市工匠、地方資產階級、巴黎的政府官員、百科全書派的哲士及盧梭等各社群的世界觀。其次,從文化之整體性的角度看,作者企圖藉由文章脈絡的論述過程,呈現出「下層文化」與「菁英文化」在世界觀上的過渡與「連結」,同時在最末一章具體呈現出十八世紀末法國在思想上向浪漫主義的過渡。換言之,達氏不但要描繪個別社會群體的思想方式與世界觀,更想嘗試從中建立一個「法國人」的整體形像──「法國性」 (Frenchness) 。

    +

    其次,從文化史研究方法論的角度觀察,達氏企圖突破法國年鑑派心態史家從事文化史研究的方法,另外指出一條他認為的康莊大道──「稠密描述」 (Thick Description) 。實際上,從作者的文本進行觀察,不管在導論或結論部分,都明顯地反映出他對年鑑第三代史家所定義的「第三階層」 (The Third Level) 之「統計分析」 (statistical history) 與「計量化」 (quantification) 研究取向的批判與不滿,並明白地指出心態史無法為吾人提出一個清晰明確的結論。同時,在本書之論述過程中,也足以顯示作者在方法使用上的「稠密描述」之特色──強調文本之解讀應行動者原有的觀點 (from the actor's point of view, or from the native's point of view) 進行詮釋的分析角度;其次,主張由文本 (Text) 與歷史現實脈絡 (Context) 之間意義的連結,以構成整個文章論述的結構,並藉以從中建構所謂法國人的世界觀。因此,吾人可說,達頓在《屠貓記》一書中,明顯表現出他企圖建立一套異於「法國路徑」 (the French Trajectories)5 的文化史(心態史)的研究方法,而此一方法論則成為本書的特色之一。

    +

    然而,達氏是否有效的達到其所訂定之著作旨趣,將是本文將加以分析與討論之重點之一;其中問題的焦點在於,下層文化與菁英文化之間是否可能取得『溝通』之管道?或兩者之間是否可能獲得一「整體」的連結與形像?最後,達氏是否成功的透過法國人所體現的世界觀,建構出所謂的「法國性」?藉由上述若干問題之探討,或可對達氏及其著作達成一批判性之理解。

    +

    本文之論述,首先將以著作之內容與方法作為基點,概略介紹本文之主要內容要義,並觀察與討論作者在方法論上之特色,並分別放在「俗文化到菁英文化的過渡」與「稠密描述與符號系統的建構」兩個部分之中加以探討。其中,在「俗文化到菁英文化的過渡」的部分,筆者將歸納若干主題,以進行對達氏之著作的理解、思考與詮釋;分別包括了「倒轉的世界──精神勝利法」與「知識型與讀者群」兩個主題,筆者將把本書六個篇章區分成兩個部分,將前三章放在「倒轉的世界──精神勝利法」的主題之下討論,後三章則放在「知識型與讀者群」的主題下討論。最後,根據全文之分析與思考,探究達氏在本書中企圖建構「法國性」的可能性。

    + +

    二、俗文化到菁英文化的過渡

    + +

    筆者認為《屠貓記》前三章之主旨,主要是企圖透過文本的解讀與詮釋,分別去建構鄉村之農民、城市之工匠與地方之資產階級的世界觀與思想方式。其中,值得注意的是,農民、工匠與資產階級都似乎透過其心靈之想望或文化象徵意義的方式,去建構其理想的世界或在現實中並不存在的世界──倒轉的世界 ( the world turned upside-down ) 。因此,筆者將本章之前三章皆歸諸於「倒轉的世界:精神勝利法」此一綱目之下。

    + +

    倒轉的世界:精神勝利法

    + +

    在第一章當中,達氏透過「小紅帽」等法國民俗故事之文本的敘述與詮釋,呈現了法國農民的生活經驗及其世界觀,並企圖進一步建構所謂的「法國性」。達氏認為,民俗故事不但具體展現了法國農民實際的生活狀況,同時也呈現出農民時常將其對願望、夢想的渴求與期望,「寄托」於故事情節的發展之中,以彌補其在現實生活之中的不足與困頓,並獲得其在「心態」上的平衡。6 其次,就法國的民俗故事所呈現的「法國性」而言,達氏企圖透過與他國家民俗故事的比較分析,歸結出若干法國民俗故事之特性,如機智、優默而詼諧的、較具世俗性與現實感、充滿了非道德的「欺騙主義」 (tricksterism)7 、較具人性面等特性,而此若干特性則具體的體現出法國人觀察世界的方式與獨特性。8 基於此,達氏肯定的指出「法國性」是存在的。9

    +

    本書的第二章,達氏以 1730 年代的巴黎印刷工匠鞏他特 (Nicolas Contat) 所撰述的「屠貓記」之文本為基礎,企圖透過印刷學徒、工匠的屠貓行為,說明其背後所隱涵「反抗工廠主及其妻子」的象徵意義。達氏認為,此屠貓行為呈現了法國舊體制時代的「工匠文化」 (artisanal culture) 與「仇視資產家」、「對勞資之間不平等的不滿」等心態。10 有趣的是,工人的反抗心態一直僅存在於「心靈」之中,或表現在工匠類似「嘉年華」之「象徵意義」的私生活娛樂與節慶活動之中,從未產生「實際」的反抗行為;工人表達其不滿情緒、思想的方式,僅僅局限在具有若干「象徵意義」的行為、動作、啞劇之中,所謂的反抗意識只是停留在「象徵」的層次罷了。11 此頗類似魯迅描寫中國人的「阿 Q 精神」,筆者姑且稱之為「精神勝利法」。

    +

    翻開第三章,場景再次有所轉變,這次來到了法國地方的行政與市場的中心城市,主角則由印刷工匠轉換成一個撰寫「旅行指南」、自視為資產階級的一個「無名氏」。達氏認為,「無名氏」在「旅行指南」中,企圖透過「遊行」隊伍的排列順序,讓觀光客獲得此一城市之真實概念,並呈現其世界觀的終極關懷。12 但是,達氏認為其真實的意圖,乃是要展現一個資產階級所構想的新的社會階層與秩序,13 宣示資產階級已成為「城市的新主人」。14 換言之,指南作者自認為資產階級已然形成一新的階級,並建立起自身的階級文化與生活方式,宣稱資產階級乃是社會的中堅成員與主人。

    + +

    知識型與讀者群

    + +

    傅柯 (Michel Foucault) 在《事物的秩序》 (The Order of Things) 一書當中,以各時代對「知識」 (knowledge) 之意義與概念在認識論上的差異,將歐洲十六世紀到二十世紀分成三個不同知識型的時代,即十六世紀的「文藝復興」時代 (Renaissance) 、十七世紀中到十八世紀的「古典」時代 (Classical Age) 、十九世紀二十世紀中的「現代」 (Modern Age) 。15 同時,不同時代的「知識型」,也呈現出不同的建構世界的方式與形態。16 循於此基本觀念,筆者認為達氏在進行對《屠貓記》後面三章之論述時,即企圖透過對「官員如何分類建檔」、「哲學家如何建立知識的系譜或秩序」、「盧梭與讀者群之互動」的詮釋,進而歸結出其所呈現的思考模式與世界觀的樣貌。

    +

    在第四章當中,達氏藉由一個出版檢查官員的分類檔案,建構一個對十八世紀政府官員之思考模式的理解。在文章之論述中,讀者可發現檢查官員 Joseph d'Hemery 在面對十八世紀的文學界的若干著作時,呈現出態度上之敵意與緊張;這一種表現在作家與官員之間的敵意與緊張關係,則體現出傳統舊勢力與新知識分子在思想上的差異。這一思想上的差異,更明顯的表現在十八世紀哲士知識論的建構上。

    +

    《屠貓記》第五章「哲士的知識系譜:百科全書派的知識論策略」之內容中,達氏即嘗試由培根 (Bacon) 、張伯 (Ephrain Chamber) 與百科全書派的狄德羅與達冷伯 (d'Alembert) 所建構的三個「知識的樹狀圖」 (The Tree of Knowledge) ,具體的呈現出十七、十八世紀思想家所呈現的「知識」之概念與變遷。知識樹狀圖的建構,象徵了思想家企圖將人類世界的知識,建構成一個具有連貫性、整體性、有機的體系與秩序。17 在培根的知識建構中,將人類知識分成個不同之範疇,即「人的學習」 (Human Learing)18 與「神的學習」 (Divine Learing) 。換言之,在培根的認知中,雖人之理性在知識的體系當中已成為一主要之部分;但是,同時神性的部分卻又獨自成一範疇,未將上帝割捨於知識體系之外。19 相反地,在狄德羅與達冷伯的知識體系中,對神性之研究的神學,卻分別下屬於人之「理性──哲學」、「想像──詩」、「記憶──歷史」的範疇之下;如此之建構,一方面凸顯「理性」的重要性,一方面則顯示了百科全書派企圖降低一切屬神知識之重要性,此也就是達氏所稱的「百科全書派認識論之策略」。

    +

    達氏在第六章中,企圖以一位「盧梭迷」的書目及其與書商的來往信件,進行「閱讀習慣的改變」與「作者與讀者之間的溝通」兩個主題之討論。就閱讀習慣的改變言,購買書籍種類較為廣泛,除了神學著作之外,還包括了小說、旅行遊記、教育學、兒童文學、歷史學等;此外,當時之人在閱讀時強調「唸出聲音」、「思考」與「討論」等特色;而且,閱讀不只是閱讀而已,它與生活本身是不能區分開的,20 閱讀乃生活的道德準備。21 就作者與讀者之溝通方面言,盧梭在《新愛露薏絲》的序言中,不但表達了著作的主旨,甚至教導讀者閱讀其書的原則。此外,盧梭甚至在序言中與一個假想的讀者進行「對話」,以表明其著作之立場與觀點。就此而言,盧梭實改變了「讀者」與「作者」、「讀者」與「文本」的關係,22 開啟了作者與讀者之間溝通的管道,衝破了讀者與作者之間的藩籬,23 使讀者深信其著作之真實與生活性,並影響了讀者在面對實際生活時之態度。24 另外,讀者們透過與盧梭信件之交往,也期望達到與作者溝通之目的。最後,達氏認為除了盧梭本身所隱涵的浪漫思想之因子,上述作者與讀者的關係之革命性,開啟了邁向浪漫主義之道路。25

    + +

    三、稠密描述與符號系統的建構

    + +

    筆者在文章著作之主旨部分即指出,在《屠貓記》之論述過程中,顯示出作者對「稠密描述」之運用。其特色則在於強調進行文本之解讀時,應由行動者原有的觀點 (from the actor's point of view, or from the native's point of view) 進行詮釋與分析;其次,主張在文本 (Text) 與歷史現實脈絡 (Context) 之間來回,以建立人類文化中行為的象徵系統與歷史現實之間產生意義的連結,並由此構成一種從事文化史研究的方法與詮釋策略。達氏也藉由此一策略,構成其整個文章論述的結構。以下將先概略介紹「稠密描述」之方法與意義;其次,在討論在本書中運用的實例。

    +

    紀爾茲在其著作《文化詮釋》當中,提出了一種進行文化之詮釋的方法,即所謂的「稠密描述」。紀爾茲借用民族誌的撰寫策略與工作程序,將之運用於文化史的研究之中。而所謂的民族誌或人類學的方法,指的是企圖藉由對符號或象徵系統的建構,去從事對社會與文化中人類行為的理解與描述。在這過程當中,人類的行為被視為一種「符號行動」 (symbolic action) ,26 而此一符號之意義,乃由其所處的文化與歷史的現實所塑造而成的。換言之,其意義猶如韋伯所言的,人類被由其自身所建構的意義之網所束縛,而文化即此一意義之網。

    +

    紀爾茲說,這一種人類學式的詮釋方法,主要是要去理解並詮釋一個民族之符號系統的意義,其出發點必須是「行動者導向」的﹙ actor-oriented ﹚,27 也就是必須回到行為者所處的歷史現實或經驗內容的角度去詮釋之。此外,在文化系統具有一定限度的一貫性之前提下,任何文化中之產物,不論是其意識形態、行為或人造之產物,皆可表現出文化的形式與意涵。再者,紀爾茲強調此一種解讀文本的詮釋策略,其目的在於從歷史現實之驗證賦予文本的意義與內涵,而非要去探究其「真實性」;而此種類似的陳述也曾出現在達爾頓的《屠貓記》當中,而此,或許是值得深思與討論的。28

    +

    達頓在《屠貓記》第一章的開頭,質疑並批判了心理分析學家佛洛姆 (Erich Fromm) 與班特海 (Bruno Bettelheim) 對「小紅帽」的解讀方式。他認為,姑且不論其版本的問題,對「小紅帽」之心理分析學式的解讀方式與結果,如「小紅帽」象徵女性之月經、「空瓶子」象徵處女、「狼」象徵強姦者、「小紅帽」整個故事情節則象徵了「青春期與成年性事的緊張」,以上種種透過「象徵語言」 (symbolic language) 的解碼,都與事實無涉,只是將讀者帶入了一個「不存在」的心靈世界,並且呈現出對民俗故事背後之「歷史現實」的忽略。29

    +

    因此,達頓企圖透過對若干民俗故事之敘述與詮釋,並透過文本與歷史現實在意義上的對照與連結,從中建構「小紅帽」所處之現實世界,及其中法國農民的「共同生活經驗」與所形成的世界觀。30 基本上,達氏認為民俗故事(文本)乃屬於一個「普遍文化」 (popular culture) 的基本構成物,31 他肯定並企圖透過民俗故事文本與歷史現實意義的連結,反映出農民實際的世界觀。因此,他認為民俗故事的內容與情節實際反映了農民的生活經驗及其如何面對、看待他所處的世界。32

    +

    此外,作者認為,基於「文本──現實環境」之關係的邏輯,每一個民俗故事之文本,隨著時、空環境的變遷與刺激,將在故事的「標準化情節」 (standardize plot)33 之基礎上改變其內容與細節,因而有所「變形」並形成不同的「版本」。例如,法國的民俗故事傳到法國之後,經由德國人格林兄弟 (brothers Grimm) 的改造,產生了符合德國歷史現實的「德國版本」。34 換言之,誠如作者所言:「作為一個『歷史性』之文件 (historical document) 的民俗故事,其存在已達數個世紀,並且隨著不同『文化傳統』而產生了不同的變化。」35 在本書第二章「工人叛變──貓之大屠殺的文化意義」當中,達氏在分析並詮釋了文本的「弦外之音」之後,「跳進」了「歷史現實」之中,說明十八世紀的法國工匠在資本家的壟斷與壓迫當中,面臨了在工資、升遷、生活所遭遇的種種剝削與生活條件之不平等。換言之,在歷史現實當中,的確存在著工匠生在現實生上的不滿心態,及資產家與工人之間所呈出之緊張關係。36 此外,達氏也企圖從法國的「歷史現實」中,尋找「貓」與「節慶活動」對於歐洲人、法國人所具現的文化意義與象徵系統。在達氏的詮釋當中,「貓」在十八世紀法國人的心靈中,至少呈現出三種文化意義。

    +

    其一,「貓」象徵了女巫,37 「屠貓」則象徵了對女巫的迫害。達氏認為,工人藉由屠殺象徵工廠主人及妻的貓「小灰」 (la grise) 的行為,象徵了對女巫的迫害,實際上則表露出工人對工廠主及其妻子的憤恨;而工人則在行為之過程的象徵意涵中,獲得其心態上的平衡與快感。其二,「貓」象徵了「性行為」的淫蕩,38 以暗指工廠主之妻的淫蕩。透過貓的象徵意義,工人將夫人與貓之淫蕩畫上等號,並藉以暗指工廠主的愚笨,如此而從中獲得其心靈上對現實生之不滿的瀰補。39 其三,「貓」象徵了在「嘉年華」節慶的「審判」意義,40 工人因而可在其節慶活動中以遂行對工廠主之審判。在工匠們私底下的聚會活動中,經常以「口語」反複重演「屠貓」的行為;當中,聚會活動象徵了「嘉年華」之節慶,口語之重演屠貓行為則象徵了對工廠主及其妻之審判。換言之,工人們在其聚會活動中所建構的「倒轉的世界」中,表達、發洩其對現實社會秩序的不滿情緒,並在「心靈」或「精神」中取得對於反抗資產家的「勝利」。

    +

    達氏在「一個中產階級的世界觀:城市最為一個文本」一章當中,也表現出其對文本之詮釋與歷史現實之間「象徵意義」的巧妙連結。根據達氏對「歷史現實」的研究,他認為不論就法國整體而言,或就指南作者所處的 Montpellier 城而言,或許有少數的土地資本家,也就是所謂的「舊時期」的資產家,但並沒有形成所謂的工業資產「階級」。那麼,指南作者「無名氏」的身分屬性及其著作指南的真正意涵為何呢?要解決此一問題,仍須回到文本上頭,從主角的觀點 (from the native's point of view) 來思考。

    +

    筆者認為,若回到文本之中,思考「遊行」在法國的文化意義,問題或可迎刃而解。對歐洲或法國來說,遊行所具現的意義與嘉年華、節慶、的象徵意義是相類似的。在慶典活動之中,一般平民在當中可「暫時」脫離現實中既定的道德、階級的規範,甚至可在活動之中,打破現實的社會秩序與社會階層的分際,此稱為「倒轉的世界」 ( the world turned upside-down ) 。就好比 Mikhail Bakhtin 所說的,在拉伯雷節中,慶典活動提供了平民「經驗」了一個「沒有階級」之社會或遂行「顛覆舊有社會秩序」的機會。基於此理,筆者主張指南之作者,其藉由遊行隊伍的介紹,從中表達他對社會階層與秩序的新概念,此隱涵了他想要透過其所描述的「遊行」,遂行其「顛覆舊有社會秩序」的意圖。這一種藉由社會文化象徵系統,以呈現對現實之不滿與反動的行為模式,跟第二幕的印刷工匠的屠貓行為,其意義基本上也是相當的。

    +

    綜上所述,達氏在方法上的確顯示了「稠密描述」方法的運用。達氏成功地以若干文本所呈現的象徵意義與歷史現實,進行法國農民、工匠、資產階級等社群團體世界觀的建構。然而,達氏是否能有效地從這些不同社群的世界觀,獲致了一個「整體」的「法國性」呢?也就是說下層文化與菁英文化之間是否可能取得『溝通』之管道?或兩者之間是否可能獲得一「整體」的連結與形像呢?這些都是值得進一步思考與探究的問題。

    + +

    結論:建構「法國性」的可能性

    + +

    達氏在論述農民、工匠或資產階級的世界觀或思考方之建構時,企圖獲得所謂「法國性」的整體印象。但是,建構法國性之可能性,其中仍有若干問題須要進一步的考量。首先,法國本身所呈現的區域之差異性與複雜性,是否影響所謂「法國性」之建構的可能性呢?或者,文中所顯示的若干文化的特性,是否具體呈現了歐洲社會的「一致性」呢?另外,文中所建構之十八世紀法國人民的世界觀或思維方式,是否呈現出其新、舊時代思維方式的斷裂性呢?又,即使是有所謂新、舊思維方式之斷裂性,是否有其「相似性」的部分呢?這些問題的思考,使得關於「法國性」此一主題更顯得其本身的複雜性,而不似達氏所設想的如此簡單。誠如夏悌葉 (Roger Chartier) 所言的:「法國性是存在的,但她並非完全一致的呈顯在某個世紀當中。」41 筆者認為,達氏在論述時,章與章的主題之間並未建立適當之連結,因而,讀者雖然可能分別對農民、工匠或資產階級的世界觀或思考方式有概括之認知,但卻並無法從其詮釋的文字當中,獲得對所謂「法國性」的「整體」印象。

    +

    其次,探究《屠貓記》一書時必需考量的另一個問題是,菁英文化與俗文化之間的互動關係為何?事實上,這也是從事文化史研究時所面臨的最主要的問題;也就是,菁英文化與俗文化在「創造」 (creation) 與「消費」 (consumption) 、「生產」 (production) 與「接受」 (reception) 之間的對應關係是如何的問題?42 是像 Mikhail Bakhtin 所言的:「菁英文化是俗文化的原型,俗文化根源於菁英文化」,43 或者像津茲伯 (Carlo Ginzburg) 所指出的:「一般人經由書本或經由對書本的『詮釋』而滲透進菁英文化之中。」44 關於此類似的問題,達氏在《屠貓記》第一章「農民說故事」的論述中指出,「法國性」之形成過程,表現出「俗文化」與「菁英文化」的互動與連結之「溝通」關係;換言之,農民「口傳」的民俗故事與知識分子之「文字化」的互動,進一步加深了法國人獨特之世界觀的形成。45 但是,筆者認為,達氏在此一問題的處理與論述,仍稍嫌不夠全面與深入,如《屠貓記》前三章與後三章之間呈現出主題與思想層次上之落差,達氏卻未就其間的連結與溝通的關係進行適當的說明,如此如何達成其所企圖建構的「法國性」呢?

    +

    再者,達氏在方法上所呈現的若干缺陷,也影響了建構「法國性」的可能性。由於具人類學取向的稠密描述,其理論本身即呈現出若干缺陷;如文本所呈現的意義是普遍性的 (universal) 或是「地方性」 (local) 的﹖關於文本的真實性問題又如何?因此,使得達氏在進行《屠貓記》之論述時,產生了若干值得深究的問題。首先,達氏在書中所採用的各個文本,是否能完整的代表法國某一社群之整體,或者它僅能代表法國的某一區域而已。同樣地,達氏在書中所歸結的象徵系統,是否也可能只是區域性的,而不能代表法國之整體;換言之,整個法國是否存在一個超越年齡、性別、地位、職業、信仰與教育之差異性而存在的共享的符號系統呢?若沒有,吾人又何以建構所謂的「法國性」呢?其次,關於文本的真實性問題。首先,文本中所描述的行為是否確實發生?又,我們能否確認一文本是否代表其行為本身?假若文本只是呈現了書寫者所「建構」或「創造」的事件與行為,而非真實地反映歷史的現實,吾人又如何去確認所建構之「法國性」的適當性與合理性呢?

    +

    基於上述問題的反省,達氏企圖在「心態史」的路徑之外,以「稠密描述」的方法,另闢一文化史的研究取向,以建構「法國性」的可能性是值得懷疑的。換言之,達氏嘗試透過若干文本的解讀與詮釋,以描繪出一整體的「法國性」的企圖是不成功地。然而,此書仍提供了吾人另一種文化史研究的形式,同時凸顯了從事文化史研究時所面臨且應該思考的問題。但是,這些問題則非本文有限之篇幅所能詳述者,仍猶待更進一步之研究與探討。

    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +
    + +
      +
    1. Robert Darnton, The Great Cat Massacre and Other Episodes in French Cultural History (New York: Vintage Books, 1985), p. 3. (Back)
    2. +
    3. Ibid. (Back)
    4. +
    5. Ibid., p. 6. (Back)
    6. +
    7. Ibid., pp. 6-7. (Back)
    8. +
    9. 「法國路徑」一詞乃筆者借用羅杰‧夏堤爾 (Roger Chartier) 之語,意指法國文化史之研究路徑──心態史 (History of Mentalities) 。 Roger Chartier, “Intellectual History or Sociocultural History History ? The French Trajectories,” in European Intellectual History: Reappraisals and New Perspectives, eds. Dominick LaCapra and Steven L. Kaplan (Ithaca: Cornell University Press, 1982), pp. 13-46; also cf. idem., Cultural History: Between Practices and Representation (Cambridge: Polity Press, 1988), pp. 19-52. (Back)
    10. +
    11. Robert Darnton, op. cit., pp. 29-35; 例如,達頓從歷史現實中「農民的生活經驗」考察,法國的農村生活實充滿了孤兒、寡婦與生活上無止境的磨難,其他如「女性晚婚」、「嬰兒死亡率高」、「生理的營養不良」、「農作物收成少與生活困苦之惡性循環」、「鄉間道路充滿討生活之流浪漢或乞丐」、「嬰兒被父母虐殺」等等之情境,皆呈現在法國的民俗故事當中。如「湯姆的拇指」 (Tom Thumb) 反映了近代法國『兒童死亡』之普遍性及人民對此之冷漠;「魔法師的學徒」 (The Sorcerer's Apprentice) 則象徵了「虐兒」、「生活極度貧困而賣嬰」、「農民與莊園領主的緊張關係」等現實之情狀;「安尼塔的故事」 (Annette's Story) 則呈現了當時法國農村人民「對吃的渴望」、「紀母虐兒」、「審美觀──肥胖」等情狀。此外,在文章中,作者歸結了民俗故事的主要場景,最常出現者包括了家庭、村落、鄉間道路等。這些場景出現的頻繁,則象徵法國農民的生活世界之範圍。 (Back)
    12. +
    13. Ibid., p. 55. (Back)
    14. +
    15. Ibid., pp. 50-51. (Back)
    16. +
    17. Ibid., p. 61. (Back)
    18. +
    19. Ibid., p. 78. (Back)
    20. +
    21. Ibid., p. 101. (Back)
    22. +
    23. Ibid., p. 108. (Back)
    24. +
    25. Ibid., p. 113. (Back)
    26. +
    27. Ibid., p. 140. (Back)
    28. +
    29. Gary Gutting, Michel Foucault's Archaeology of Scientific Reason (Cambridge: Cambridge University Press, 1989), p. 139. (Back)
    30. +
    31. Ibid., p. 142. (Back)
    32. +
    33. Ibid., p. 194. (Back)
    34. +
    35. 此一範疇,又分成「理性」「想像」「記憶」三個部分。 (Back)
    36. +
    37. Ibid., p. 198. (Back)
    38. +
    39. Ibid., p. 228. (Back)
    40. +
    41. Ibid., p. 251. (Back)
    42. +
    43. Ibid., p. 228. (Back)
    44. +
    45. Ibid., pp. 231-234. (Back)
    46. +
    47. Ibid., p. 252. (Back)
    48. +
    49. Ibid., p. 232. (Back)
    50. +
    51. Clifford Geertz, The Interpretation of Cultures (New York: Basic Books, 1973), p. 10; 稠密描述並非由紀爾茲所提出,但他則首先提出作為一種解讀文本之詮釋的系統方法。 (Back)
    52. +
    53. Ibid., p. 14. (Back)
    54. +
    55. Robert Darnton, op. cit., pp. 260-263. (Back)
    56. +
    57. Ibid., pp. 10-11. (Back)
    58. +
    59. Ibid., p. 23. (Back)
    60. +
    61. Ibid., p. 17. (Back)
    62. +
    63. Ibid., p. 51. (Back)
    64. +
    65. Ibid., p. 21. (Back)
    66. +
    67. Ibid., pp. 11-12; 根據作者之說明「格林兄弟童話」乃源自一法國休京教徒的女性的民俗故事版本改編而成。 . (Back)
    68. +
    69. Ibid., p. 13. (Back)
    70. +
    71. Ibid., pp. 79-82. (Back)
    72. +
    73. Ibid., pp. 92-95. (Back)
    74. +
    75. Ibid., p. 95. (Back)
    76. +
    77. Ibid., pp. 96-97. (Back)
    78. +
    79. Ibid., pp. 83-86. (Back)
    80. +
    81. Roger Chartier, Cultural History: Between Practices and Representation (Cambridge: Polity Press, 1988), p. 101. (Back)
    82. +
    83. Ibid., p. 40. (Back)
    84. +
    85. Mikhail Bakhtin, op. cit., p. 58. (Back)
    86. +
    87. Carlo Ginzburg, The Cheese and the Worms: The Cosmos of Sixteenth-Century Miller (Baltimore: The Johns Hopkins University Press, 1980), p. 68. (Back)
    88. +
    89. Robert Darnton, op. cit., pp. 62-65. (Back)
    90. +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/001/article06.html.html b/htdocs/htc/newsletters/001/article06.html.html new file mode 120000 index 0000000..1688ac2 --- /dev/null +++ b/htdocs/htc/newsletters/001/article06.html.html @@ -0,0 +1 @@ +article06.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/001/article06.html.xhtml b/htdocs/htc/newsletters/001/article06.html.xhtml new file mode 100644 index 0000000..f73d52e --- /dev/null +++ b/htdocs/htc/newsletters/001/article06.html.xhtml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + +轉載 彼得柏克心繫何處:新書集結30年文化研究成果 + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +
    轉載
    + +

    彼得柏克心繫何處:新書集結 30 年文化研究成果

    + +
    陳正國
    + +

    有位才識兼備的年輕學者說過一句值得玩味的話:「每個時代讀的書就是那幾本」。台灣對英國歷史學的接受也有各領風騷三五載的趨勢。早幾年,在聯經與時報等公司的推動下,科靈烏 (R. G. Collingwood) 與以撒柏林 (Isaih Berlin) 是思慕外國學術年少學子的聖名。而近來,最為一般讀者市場所熟知的英國史家,大概非霍布斯邦 (Eric Hobsawm) 與彼得柏克 (Peter Burke) 莫屬了。

    +

    這一本由專業的社會學出版杜 Polity 出版的《文化史的變呈》 (Varieties of Cultural History) ,固然可以看成是 Polity 出版方針或許稍有改變,也或許是柏克學術介於史學與社會科學之間,但它更該視為彼得柏克的撒罟收網工作。

    +

    從內容來說,這本書集錄了柏克近二、三十年,在文化史研究上的心得,他勇於嘗試各類文化題材蒐集與研究。諸如夢境在日本、歐洲與美洲(甚至提到中國),文藝復興時期的義大利的詼諧,美洲嘉年華、騎士文化在新大陸等等變異紛呈,直令讀者目不暇給。他的文化史觸角所及之處,都在這本書中得一窺堂奧。

    +

    從柏克的學術生命來說,他原是任教於英國南部一所大學的義大利文藝復興專業史家。得益於他任教該校的歐洲研究院,柏克將研究網撒到西歐荷蘭、西班牙、德、英、法等國庶民文化領域。被聘為劍橋講師之後,他加深了自己對人類學與史學理論的興趣,卻又同時繼續對荷蘭、法國(甚至北歐)的歷史做類似突擊性的研究。他在這段期間所寫的數本著作,彼此間都談不上有何系統關係。於是,這本九七年秋出版的論文集,可以讓人比較清楚看出也這二、三十年持續從事的問題為何。

    +

    這本書的特色仍是柏克一慣的行文簡練。比起霍布斯邦,柏克的筆端多了一份豐腴。也長於敘述體,卻又更長於敘逆中引出清晰的、類似自我詰問與回應的論證。雖然或許有人曾覺得他不饜足於引出一串(空洞的?)人名著作,有浮誇之嫌;這本新論文集,還是可以看出他對史學動態與理論的精確掌握。柏克不是體大思精型的學者,卻是個善於選題的寫手。例如〈新世界的騎士文化〉一文僅僅十一頁。作者忽高忽低地引用斷簡殘篇式的證據,竟橫跨四百多年歷史時段。很難想像這種疏闊文章竟是出自一位名流史家之手,不過也只有長期貫注於心態史研究,兼有「世界史料」眼光者,才能以這樣的主題,羅織成一篇(真直的)歷史:美洲新大陸當然在歷史中回應著歐洲文化的普遍價值。

    +

    掛名指導劍橋政治思想與思想史課程的三十多名授課教師中,柏克是唯一掛著突兀的「文化史」教師頭銜的人。去年,柏克終於如願以償升等為教授。這本書的出版正可以視為他「前教授」時期,在學術草原裡游牧的軌跡。於是人們可能會好奇,從文藝復興精緻文化走進庶民文化研究,從北義大利出走到世界各大洲之後,柏克教授的下個驛站會是那裡?

    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/001/article07.html.html b/htdocs/htc/newsletters/001/article07.html.html new file mode 120000 index 0000000..20ea4b4 --- /dev/null +++ b/htdocs/htc/newsletters/001/article07.html.html @@ -0,0 +1 @@ +article07.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/001/article07.html.xhtml b/htdocs/htc/newsletters/001/article07.html.xhtml new file mode 100644 index 0000000..6690c0f --- /dev/null +++ b/htdocs/htc/newsletters/001/article07.html.xhtml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + +Suggest Readings for Advanced Study in Cultural History + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    Suggest Readings for Advanced Study in Cultural History

    + +
      +
    • Ariès, Philippe. Centuries of Childhood. New York: Vintage, 1962.
    • +
    • ________. The Hour of Our Death. Oxford: Oxford University Press, 1991.
    • +
    • Ariès, Philippe, & Georges Duby, eds. A History of Private Life, 5 vols. Cambridge, Mass.: The Belknap Press of Harvard University Press, 1987.
    • +
    • Bakhtin, Mikhail K. Rabelais and his World. Cambridge, Mass.: Harvard University Press, 1968.
    • +
    • Bloch, Marc. The Royal Touch. New York: Dorest Press, 1961.
    • +
    • Bourdieu, Pierre. Distinction: A Social Critique of the Judgement of Taste. Cambridge, Mass.: Harvard University Press, 1984.
    • +
    • Braudel, Fernand. Civilization & Capitalism 15th-18th Century, 3 vols. Berkeley: The University of California Press, 1992.
    • +
    • Bremmer, Jan, and Herman Roodenburg, ed. A Cultural History of Gesture. Cambridge: Polity Press, 1991.
    • +
    • Burke, Peter. Culture and Society in Renaissance Italy. Princeton: Princeton University Press, 1986.
    • +
    • ________. Varieties of Cultural History. Cambridge: Polity Press, 1997.
    • +
    • ________. New Perspectives on Historical Writing. Cambreidge: Polity Press, 1991.
    • +
    • ________. The Art of Conversation. Cambridge: Polity Press, 1993.
    • +
    • ________. History and Social Theory. Cambridge: Polity Press, 1992
    • +
    • ________. Popualr Culture in Early Modern Europe. New York: Harper & Row, Publishers, 1978.
    • +
    • Burckhardt, Jacob. Civilization of the Renaissance in Italy. New York: Rand House, 1954.
    • +
    • de Certeau, Michel . The Practice of Everyday Life. Berkeley: University of California Press, 1984.
    • +
    • Chartier, Roger. Cultural History: Between Practices and Representation. Cambridge: Polity Press, 1988.
    • +
    • ________. The Cultural Uses of Print in Early Modern France. Princeton: Princeton University Press, 1987.
    • +
    • ________. The Cultural Origins of the French Revolution. New York: Duke University Press, 1993.
    • +
    • ________. Forms and Meaning. Philadelphia: University of Pennsylvania Press, 1995.
    • +
    • Darnton Robert. The Great Cat Massacre and Other Episodes in French Cultural History. New York: Vintage, 1984.
    • +
    • ________. The Kiss of Lamourette: Reflections in Cultural Histroy. New York: W. W. Norton & Company, Inc., 1990.
    • +
    • ________. The Forbidden Best-Sellers of Pre-Revolutionary France. New York: W. W. Norton & Company, 1996.
    • +
    • Davis, Natalie Z. The Return Martin Guerre. Cambridge, Mass.: Harvard University Press, 1983.
    • +
    • ________. Society and Culture in Early Modern France. Cambridge: Polity Press, 1995.
    • +
    • Duby, Georges. The Threes Orders. Chicago: The University of Chicago Press, 1980.
    • +
    • ________. Love and Marriage in the Middle Ages. Cambridge: Polity Press, 1994.
    • +
    • Elias, Norbert. The Civilizing Process. Oxford: Blackwell, 1994.
    • +
    • Febvre, L. The Problem Unbelief in the Sixteenth Century: The Religion of Rabelais. Cambridge, Mass.: Harvard University Press, 1982.
    • +
    • Fichtenau, Heinrich. Living in the Tenth Century: Mentalities and Social Orders. Chicago: The University of Chicago Press, 1991.
    • +
    • Geertz, Clifford. The Interpretation of Cultures. New York: BasicBooks, 1973.
    • +
    • ________. Local Knowledge: Further Essays in Interpretative Anthropology. New York: Basic Books, 1983.
    • +
    • Ginzburg, Carlo. Clues, Myth, and the Historical Method. Baltimore: The Johns Hopkins University Press,1992.
    • +
    • ________. The Cheese and the Worms: The Cosmos of a Sixteenth-Century Miller. Baltimore: The Johns Hopkins University Press,1981.
    • +
    • Habermas, Jürgen. The Structural Transformation of the Public Sphere. Cambridge: Polity Press, 1989.
    • +
    • Halbwachs, Maurice. On Collective Memory. Chicago: The University of Chicago Press, 1992.
    • +
    • Hobsbawm, Eric and Terence Ranger, ed. The Invention of Tradition. Cambridge: Cambridge University Press, 1983.
    • +
    • Huizinga, Johan. The Autumn of Middle Ages. Chicago: The University of Chicago Press, 1995.
    • +
    • ________. Man and Ideas: History, the Middle Ages, the Renaissance. New York: Meridian Books, 1960.
    • +
    • Hunt, Lynn, ed. The New Cultural History. Berkeley: The University of California Press, 1989.
    • +
    • ________. The Family Romace of the French Revolution. Berkeley: University of California Press, 1993.
    • +
    • Hunt, Lynn and Jacques Revel, eds. Histories: French Constructions of the Past. New York: The New Press, 1995.
    • +
    • Kaplan, Steven, ed. Understanding Popular Culture. Berlin: de Guyter, 1984.
    • +
    • Le Golf, Jacques. Time, Work and Culture in the Middle Ages. Chicago: The University of Chicago Press, 1980.
    • +
    • ________. The Medieval Imagination. Chicago: The University of Chicago Press, 1980.
    • +
    • ________. The Birth of Purgatory. Chicago: The University of Chicago Press, 1984.
    • +
    • Le Roy Ladurie, Emmanuel. Carnival in Romans. New York: George Braziler, Inc., 1979.
    • +
    • ________. Montaillou. New York: Vintage, 1978.
    • +
    • ________. The Peasants of Languedoc. Urbana: University of Illinois Press, 1974.
    • +
    • Levi, Giovanni. Inheriting Power: The Story of an Exorcist. Chicago: The University of Chicago Press, 1988.
    • +
    • Lüdtke, Alf. The History of Everyday Life: Reconstructing Historical Experience and Ways of Life. Princeton: Princeton University Press,1995.
    • +
    • Mandrou, R. Introduction to Modern France. London: Croom Helm, 1975.
    • +
    • Muir, Edward. Microhistory & The Lost Peoples of Europe. Baltimore: The Johns Hopkins University Press, 1991.
    • +
    • Munkerji, Chandra, ed. Rethinking Popular Culture: Contemporary Perspective in Cultural Studies. Berkley: The University of California Press, 1997.
    • +
    • Ozouf, M. The Festivals and the French Revolution. Cambridge, Mass.: Harverd University Press, 1988.
    • +
    • Sahlins, Marshall. Culture and Practical Reason. Chicago: The University of Chicago Press, 1976.
    • +
    • ________. Historical Metaphors and Mythical Realities: Structure in the Early History of the Sandwich Islands Kingdom. Ann Arbor: The University of Michigan Press, 1981.
    • +
    • ________. How “Natives” Think: About Captain Cook, For Example. Chicago: The University of Chicago Press, 1990.
    • +
    • ________. Islands of History. Chicago: The University of Chicago Press, 1985.
    • +
    • Schama, Simon. The Embarrassment of Riches: An Interpretation of Dutch Culture in the Golden Age. Berkeley: University of California Press, 1988.
    • +
    • Thompson, E. P. The Making of the English Working Class. Harmonsworth: Penguin Books, 1991.
    • +
    • ________. Customs in Common. Harmonsworth: Penguin Books, 1991.
    • +
    • Vovelle, Michel. Ideologies & Mentalities. Chicago: The University of Chicago Press, 1990.
    • +
    • ________. The Revolution against the Church. Cambridge: Polity Press, 1991.
    • +
    • Zeldin, Theodore. A History of French Passions: 1848-1945, 2 vols. Oxford: Clarendon press,1973.
    • +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/001/article08.html.html b/htdocs/htc/newsletters/001/article08.html.html new file mode 120000 index 0000000..a2dd852 --- /dev/null +++ b/htdocs/htc/newsletters/001/article08.html.html @@ -0,0 +1 @@ +article08.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/001/article08.html.xhtml b/htdocs/htc/newsletters/001/article08.html.xhtml new file mode 100644 index 0000000..bb77b73 --- /dev/null +++ b/htdocs/htc/newsletters/001/article08.html.xhtml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + +最新動態 + + + + +
    + +
    + 回目錄 | + 前一篇 +
    + +

    最新動態

    + +
    +

    輔仁大學歷史學研究所碩士班學生,於八十六年九月至八十七年一月期間,舉辦了一系列以「歷史學與後現代」為專題的研討會,前後分別以「歷史與影像」 (History and Image) 、「歷史與小說」 (History and Fiction) 、「稠密描述」 (Thick Description) 、「歷史學與後現代主義」 (Historiography and Postmodernism) 、「馬克思主義/史學/後現代」等方面之主題進行了六次的活動。同時,研討會的詳細狀況加以文字化後,則集結成《歷史:理論與文化》之西洋史研究通訊。

    +

    在「歷史與影像」此一主題之下總共進行了兩次的討論會。這兩次討論會之進行,分別播放了史家戴維斯 (Natalie Zemon Davis) 的《軍士返鄉記》 (The Return of Martin Guerre) 參與拍攝的同名影片及以描述工業化及其若干社會問題的《翡翠谷》等電影,由參與觀賞影片的與會者,就「影視史學」及影片中之若干內容為主題進行討論。其次,以「歷史與小說」為主題的討論會,就專研中國近代史的史家史景遷 (Jonathan D. Spence) 的著作《胡若望的疑問》 (The Question of Hu) 一書,以「歷史與小說」、「真實與虛構」 (reality and fiction) 等與後現代歷史學的相關爭論進行討論。

    +

    第四次的討論會的主題則是作為新文化史研究之方法論的「稠密描述」 (Thick Description) ,由盛少輝先生擔任引言人,說明其作為文化人類學理論的意涵與特色,及其在西方文化史研究上的價值與影響,進而分析「稠密描述」在西方史學研究上的實踐及其所面臨的困難。本次討論會的詳細內容可參閱本刊《歷史:理論與文化》中〈紀爾茲「稠密描述」:一個文化詮釋理論〉 (Thick Description: Toward an Interpretive Theory of Culture) 一文。

    +

    第五次的討論會,黃明田先生以安克史密 (F. R. Ankersmit) 的 “Historiography and Postmodernism” 及 “Reply to Professor Zagorin” 、與 P. Zagorin 的 “Historiography and Postmodernism Reconsideration” 等三篇文章為主要內容,就「歷史學與後現代主義」此一主題擔任引言人的工作。討論會中分別就史學與後現代主義、臺灣史學如何面對後現代主義等若干問題進行了一場熱烈的討論,其詳細內容也可參閱本刊〈歷史學與後現代主義〉一文。

    +

    第六次的討論會則由徐文路先生以馬克思主義與西方歷史學之關係為主軸,並將之放在後現代主義的問題架構下討論,其詳細內同樣可詳見本刊〈馬克思主義/史學/後現代:多元基進的辯証〉一文。

    +
    + +
    +

    接下來三月至六月期間,主辦單位另外以「歷史與文化」為主題,分別以「文化史的任務」 (The Task of Cultural History) 、「文化史的新版圖:心態歷史」 (The New Map of Cultural History: The History of Mentality) 、「愛爾蘭文藝復興運動」、「文化霸權」等題目,進行一系列之活動,其內容將詳載於《歷史:理論與文化》第二期。

    +
    + +
    +

    最後,在此先作一個預告,本研討會預定自八十七學年度九月起將以「婦女史」為專題進行一系列之討論會,屆時歡迎各方人士之參與。

    +
    + +
    + 回目錄 | + 前一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/001/index.html.html b/htdocs/htc/newsletters/001/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/htc/newsletters/001/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/001/index.html.xhtml b/htdocs/htc/newsletters/001/index.html.xhtml new file mode 100644 index 0000000..18b6464 --- /dev/null +++ b/htdocs/htc/newsletters/001/index.html.xhtml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + +創刊號 目錄 + + + + +
    + + + + +
    + + + + diff --git a/htdocs/htc/newsletters/002/article01.html.html b/htdocs/htc/newsletters/002/article01.html.html new file mode 120000 index 0000000..f89ba28 --- /dev/null +++ b/htdocs/htc/newsletters/002/article01.html.html @@ -0,0 +1 @@ +article01.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/002/article01.html.xhtml b/htdocs/htc/newsletters/002/article01.html.xhtml new file mode 100644 index 0000000..f60ee7a --- /dev/null +++ b/htdocs/htc/newsletters/002/article01.html.xhtml @@ -0,0 +1,426 @@ + + + + + + + + + + + + + + + + + + + +台灣西洋史研究的理論與實際 + + + + +
    + +
    + 回目錄 | + 下一篇 +
    + +

    台灣西洋史研究的理論與實際:一個嘗試*

    + +
    盛少輝
    + +

    本文的主要目的,在於說明《歷史:理論與文化─西洋史研究通訊》 ** (以下簡稱《歷史:理論與文化》)此份刊物創刊的旨趣。在本文中,我將從歷史思維的角度,說明此份刊物的〈發刊辭〉所擬具的主張中,蘊涵的理論預設。

    +

    本文主要包含兩個部分:一個是歷史地;另一個是理論地。首先,我將藉由台灣西洋史研究社群內部歷來對西洋史實踐的回顧與檢視,說明台灣西洋史研究所面臨的問題;其次,我將從理論反省的層次,提出台灣西洋史研究的新取向。

    +

    就歷史考察,也就是歷史實踐的部分,歷來社群內部的討論顯示:台灣的西洋史研究正面臨著發展的困境,而此一困境表現在諸如基礎研究的欠缺、整體研究水平之不能提升、文化與時空差異所造成的隔閡、……等。1 我們將當前台灣西洋史學界所面臨的研究困境,定義為「危機」狀態。2 我們認為西洋史研究的危機,不在基礎研究的闕如;而在於對歷史學性質的誤解!我們認為:以基本研究的欠缺作為西洋史研究的困境的來由;這樣的態度是建立在十九世紀實證史學的基本假定上,而此一假定迄今業已破產。同時,我將論證:西洋史研究與台灣史或中國史研究在歷史知識中,具有相同的的認知地位。

    +

    就理論的部分,我將提出一項關於台灣西洋史研究的新取向─「史學史」的研究。此一概念的提出係援引自二十世紀的英國歷史哲學家柯靈烏 (R. G. Collingwood) 的「史學史」 (history of history) 與荷蘭歷史理論家安可史密斯的「敘述實體」 (narrative substance) 概念。首先,我們主張:歷史研究的真實進展不在於個別事實的不斷增加;而在於我們能對歷史事件提出具有洞察力 (historical insight) 的詮釋,也就是說,能夠提出新穎與不同的觀點。歷史洞察力的產生,在於掌握歷史陳述(或文本)中與不同的歷史陳述(或文本)間的差異。因此,在歷史實踐中,歷史家應對專業領域內同行的著作有深刻地掌握。在本文中,我將追溯此一歷史概念的發展。其次,我將藉由後結構主義 (post-structuralism) 對歷史文本的「互為文本性」 (intertextuality) 的討論,來說明「史學史」的研究取向何以做為適合台灣西洋史研究的新方向。最後,古典修辭學的「主題」 (Topics) 概念,將為歷史社群的討論與歷史文本的詮釋提供一種新的「客觀性」 (objectivity) 概念。

    + +

    + +

    台灣西洋史學者對於社群現狀的反省,總是易於陷入一個陳腔俗套的說法。他們認為台灣西洋史研究的停滯不前,主要在於基礎研究的不足。而基礎研究的不足導因於史料的限制、文化與時空的差異與缺乏整體性的自我觀點。歷來社群內部或外部的反省,如黃俊傑、邢義田與楊肅獻的評論,都顯現了此一共同點。

    +

    隱含在這些對台灣西洋史研究現況的反省背後,是十九世紀的實證主義史學的假定,這即是傅斯年所主張的「史學即史料學」。實證主義史學假定,歷史研究的程序在於歸屬事實的工作完成後,才能進行歷史綜合的工作。因此,歷史家的工作始於史料的蒐集、考證、排比,最後進行綜合的工作。邢義田主張,雖然「不認為綜合性通論的工作非得『基礎研究』建立之後才能開始。……但是我們似應認清『成一家之言』的通論需以無數沉潛有得的專論為基礎,而專論又以一手史料的掌握為根本。捨基礎研究而言落地生根,其可乎?」我們可以從中發現其背後所隱含的史學假定。

    +

    在此處,筆者不擬對實證主義史學提出批判,在下文理論建構部分,我將指出歷史研究工作的開始,並非起源自毫無止境的史料蒐集與批判,而是歷史觀點的建構。歷史觀點的提議,則來自於歷史家理解歷史的觀念架構。此處先就台灣西洋史研究所面臨的所謂「時空與文化的差異」問題申論。

    +

    近年來,隨著本土意識的覺醒,台灣史研究已成顯學。台灣主體性的強調,卻往往陷入偏狹的自我中心論 (parochialism) 。我們對於正在形成全球化的世界的過往─即世界史─欠缺深刻的理解。在〈發刊辭〉中,我們已指出此一現象的弊病,以及在歷史學與人類彼此相互瞭解上的缺憾。但西洋史研究的不振,讓某些人主張西洋史的研究是次要的、無成效的。同時,我們在理解與我們時空相異的歷史與文化時,文化的差異使我們感到理解異文化或「他者」是不可能的,或至少也是十分困難的。在台灣,西洋史的研究便遭遇到此一難題。

    +

    以下,我將論證歷史地理解「他者」 (understanding the other historically) 是可欲的。同時,西洋史的研究與台灣史或中國史研究具有同樣的認知地位。我的論證次序如下:

    +

    首先,藉由討論杜正勝的「同心圓」理論,我將論證在歷史理解中,時空關係並不具一定的優先順序,而所謂的「同心圓」理論將被否證。

    +

    其次,所謂強調「想像」在歷史理解中的作用,亦即透過歷史想像,時空與文化的阻隔無礙於歷史理解的確鑿性,這樣的見解需要進一步的考察,因為所謂的「歷史想像」 (historical imagination) 其中隱含了哲學的現代性 (philosophical modernity) 觀點,即認知主體與客體的分離。為此,我認為後現代主義的「歷史經驗」理論,更適合解決時空文化差異的問題。

    +

    第三,藉由人類學者對「他者」 (the other) 的研究與後現代主義「去脈絡化」 (de-contextualization) 趨向,我將說明:理解異文化或從事西洋史研究並不比理解當代社會或本土文化來得困難。因之,任何研究領域不能宣稱具有較高的認知地位與權威。

    +

    杜正勝提出以鄉土教學與台灣史為重點的「同心圓」理論。3 他認為歷史研究與教學應由近而遠,依本土─中國─世界架構逐漸向外擴展。隨著不同的教育階段(不是認知成長階段),而有不同的著重點。同心圓內的第一圈是鄉土史、第二圈是台灣及其周圍、第三圈是中國史、第四圈是亞洲史、第五圈是世界史層層向外擴展,循序漸進。不過,從根本上來說,這樣的認知程序仍然是輕重先後有別地。杜正勝意圖的是:反對一元觀點的歐洲中心論式的世界史、摒棄大漢沙文主義的亞洲史、中國史,而呈現出多元文化發展的面貌。

    +

    這樣的理論有助於我們思考,在台灣西洋史的研究中,時空差異是否構成一認識論上的問題?以下,我將爭論地是:是否歷史研究或歷史教育需要這樣的認知程序?除了現實的實際需求與本土化(當然,研究主題的「本土化」並不等同於歷史解釋觀點的「本土化」!)的要求外,它在歷史學中是否有認識論的基礎?而西洋史在歷史認知的程序上,是否只佔有邊緣性的角色?我的回答是:歷史知識並不需要這樣的、也沒有一定的認知程序。所謂歷史知識必須由與我們切身周遭開始的假定,欠缺歷史知識論上的妥當性。

    +

    首先,強調歷史教學與學術研究應從我們切身的周遭環境起始,與我們所熟悉的歷史認知方式是有所扞挌地;4 但這並不足以否定它在認識論上的妥當性。所謂歷史是在時間序列中,進行安排事實與詮釋的思維活動。問題的重點在於:甚麼樣的時間序列?傳統的歷史教學是這樣進行的:從邈遠的「史前時期」、古代、中世、近世、到與我們生活密切聯繫、息息相關的現在。

    +

    人類理解的運作常是以因果聯屬的方式進行。依常識,我們認為事物的發生是某一事件 PCCCn 先行條件下,依一系列普遍法則運作而產生的結果。因此,我們理解歷史時,常欲追溯事物的起源,而有所謂「起源」 (origins) 的偶像崇拜。在實際的歷史認知與寫作時,我們總是先敘述事件的起源、插曲、再到它最近的結果。如同亞里斯多德 (Aristotle) 對敘述形式的說明,一齣戲劇包含的開頭(場) (beginning) 、中段 (middle) 與結尾 (end) 。所以在進行歷史認知時,我們所做的其實是由與我們最遙遠的古代到新近的現在。但根據休姆 (David Hume) 對因果觀念的解構,因果關聯,「不過是心靈的慣性 (habit, custom, or propensity) 作用,將經驗中經常相連 (constant conjunction) 的兩個事物視為理所當然的必然連鎖,而將之名為因果關係。所以,事物自身之間並無因果連鎖,那只是人想像作用的產物。」5 因此,在歷史思維中,「起源」並沒有知識論上優越的基礎。同時,根據尼采的系譜學 (genealogy) 與傅柯的知識考古學 (archaeology of knowledge) 方法,以及現代史學中對「起源」的批判、歷史溯源學的方法,都證明了「起源」在歷史認知中並無認知上的優越性。6

    +

    尼采從哲學上批判「起源」偶像、與其對十九世紀歷史學專業的學院文化的批評,迄今仍然有效。如同笛卡兒,尼采批評歷史家沉溺於過去,專注於尋找起源,以致與現時失去了連繫,這是十九世紀特有的歷史病。7 但尼采忽略了西洋史學史發展上的一項重要事實,即西方近代史學超越了歷史學家的實際經驗範圍,而能進入歷史學家實際上無法親證的世界。近代西方史學的一項重要成就即是歷史學超越了親證之知,而成為推論性的知識。對於知識源自親身驗證的強調,將導致歷史懷疑論 (historical pyrrhonism) 。柯靈烏說道:「以親證為知識本質,將使歷史學成為不可能。」8

    +

    在歷史思維中,歷史家思維的起點既非限定於遙遠的「起源」,也非限定於與我們親近的現在。因此,就時間方面言,在歷史思維中並無一定的先後次序,時間中的任何一點都可以被指定為歷史思維的起點。近來,歷史理論家對於歷史敘述的形式分析已驗證了此一論點。歷史事件可以有不同的「情節」 (plot) 編排,以不同的「情節設置」 (emplotment) ,賦予事件不同的意義。9 同樣地,將空間言,在歷史思維中,空間距離的遠近也不具任何認知上的差異。

    +

    柯靈烏嚴厲地批評了休昔底的斯 (Thucydides) 的「當代史」代表了希臘人直率的自我中心的想法 (straightforward egotism) ,將一切非希臘的事物看作是野蠻的,因此不值得嚴肅的加以研究。10 杜正勝的「同心圓」理論正表現了休昔底的斯狹隘的自我中心論。如前所述,現代歷史學的成就在於能夠超越歷史家的親證範圍,而進入與其在時空與文化上異質的世界,強調歷史知識從周身開始的假定,無疑地是從現代歷史學已獲得的成就上退卻,這是歷史學退化的表徵。因此,時空的差異並不足以構成歷史理解上的難題,而類似的假定也欠缺歷史知識論上的妥當性。

    +

    鄧世安試圖解決西洋史研究與教學中時空與文化差異的問題。他意圖以引用上述休姆的理解理論來說明歷史知識的性質,並強調想像在歷史研究與西洋史教學中的重要性,來解決台灣在西洋史教學上所面對的文化差異與歷史理解力問題。正如柯靈烏對歷史知識的推論性質的強調,對於鄧世安而言,「歷史知識的有效性是建立在證據的充足與確鑿上,而非在時空的接近與否上」,由是觀之,「時空阻隔無損於歷【西洋】史的研究與教學。」11

    +

    但將歷史想像引入歷史知識中,將面臨一個知識論上的難題,即所謂哲學的現代性問題。現代主義史學的知識論基礎,在於接受笛卡兒 (Cartesianism) 傳統的假定,劃定認識主體 (subject) 與對象 (object) ,並將之絕然分離。與此相關地,是主觀性 (subjectivity) 與客觀性 (objectivity) 、合理性 (rationality) 與非理性 (irrationality) 之對立。在歷史思維上,這形成了兩互不相聯的現在 (the present) 與過去 (the past) 。因此,歷史思維的重點在於:如何去縫補過去與現在的時間鴻溝。歷史主義者意圖以移情 (empathy) 從方法論來克服「時間距離」 (temporal distance) 的問題,便是此一現代主義歷史思維的產物。海德格 (Martin Heidegger) 與伽達瑪 (Hans-Georg Gadamer) 批評了歷史主義所隱含的技術宰制與方法至上的傾向。12 同樣地,借用柯靈烏的「歷史想像」來克服西洋史研究上的問題,同樣隱含了此一難題。

    +

    最後,我們需要一項理論工具來面對此一難題;而後現代主義中所謂的歷史經驗理論與「去脈絡化」趨向,為我們提供了一個認識的基礎。後現代主義捨棄脈絡化的思維,而回歸到直接的經驗本身。在歷史認知的過程中,現在與過去、自我與他者都不能宣稱具有較高的認知地位。後現代主義的歷史經驗理論,不同於現代主義或歷史主義的歷史理論意圖去接合過去與現在,認知主體以方法策略去復活過去;而是將過去從現在疏離開來,去區別過去與現在的差異 (difference) 所在。13 正如安可史密斯詩意的譬喻:歷史的意義不再依附於歷史之樹的樹枝、樹幹;而僅僅是樹葉本身。秋風一臨,樹葉將隨風飄落。後現代主義史學,是沒有枝幹,僅有樹葉的史學之樹。14

    +

    人類學理論也有助於我們解決時空相異的兩個文化間相互了解的問題。七Ο年代以來,人類學理論被大量引入歷史研究中。人類學的理論讓歷史家們了解,他們所碰觸、會合的是一個與其迥然不同的異質文化,或「他者」。人類學家將他們的研究對象從不同於觀察者的角度來看待。歷史學家之於他的研究對象,正如人類學家所碰觸到的異文化,是一個奇異、神密世界的一部分。15 因此,吾人理解與自己切身相關的歷史與文化時,所遇到的隔閡與困難並不比理解古代文化或異文化要來得少。進一步推論,吾人在理解自身與理解異文化時,同樣有渺不可稽、瞎子摸象之感。如此,豈不是時空相同或相異的二個文化彼此的了解皆成為不可能;歷史理解便失去存在的理據?因此,時空與文化差異並不構成西洋史研究與理解的困難。

    + +

    + +

    在〈發刊辭〉中,我們強調了「史學史」研究對台灣西洋史與歷史研究的重要性。我們說道:

    + +
    +

    所謂的史學史不僅指涉對史家、史著、史學思想、觀念的研究;它同時意指對重要的歷史問題的歷史的研究,也就是所謂的「學術史」的研究。前者現有的成果已頗有可觀;後者則仍有待努力。16

    +
    + +

    在文中,我們呼籲台灣的西洋史學界應對諸如「文藝復興」 (the Renaissance) 、「十七世紀的普遍危機」 (the general crisis of the seventeenth-century) 、「法國大革命」 (the French Revolution) ……等西洋史中重要的問題作史學史的研究。誠如柯靈烏所言:「歷史是人類心智的自我認知。」人渴求認知萬物。然其理解,必自人類自身起;而欲認識自我,必自人類的歷史起始。同樣地,歷史家從事理解人類的歷史時,必須先了解自己工作的性質。所以,歷史家對歷史此一學科自身歷史的了解便是史學史,它是歷史家自我認同的重要來源。更進一步,如引文中所述,我們認為史學史不僅指涉對史家、史著、史學思想、觀念的研究,它同時意指對重要的歷史問題的歷史的研究,也就是所謂的「學術史」的研究。在此,我們所主張之「史學史」研究,即是史學研究者應在其專業範圍內,對其同行專家的著作作深刻的理解。

    +

    以下,我將提出台灣西洋史研究的新取向─「史學史」的研究。此一「史學史」的研究取向,主要係援引自荷蘭後現代主義歷史理論家安可史密斯的「敘述實體」概念。17 我將藉由安可史密斯的「敘述實體」概念,從普遍地來說明歷史學的性質;從特殊地來試擬台灣西洋史研究之芻議。在本文中,我所使用的方法是邁乃克 (Friedrich Meinecke) 式的觀念史。我意圖呈現「史學史」或「敘述實體」概念,在歷史思想與歷史職業中的變遷。我嘗試去追溯「敘述實體」的系譜,將「敘述實體」與歷史主義的核心─「歷史觀念」 (historische idee, historical idea) 、觀念論的「具體的共相」邏輯 (concrete universal) 連接起來,並以近來後現代主義對歷史文本的討論,去更新歷史主義的主要原則─即「個體性」 (individuality) 原則。18 在以下的討論中,我將顯示「個體性」概念,如何從一個形上學實體的概念轉化為一個敘述主義 (narrativism) 的概念。我將依次分別討論洪堡德 (Wilhelm von Humboldt) 的「歷史觀念」、赫伊津哈 (Johan Huizinga) 的「歷史感覺」 (historical sensation) 與「歷史形式」 (historical form-giving) 、歐克秀 (Michael Oakeshott) 的「歷史個體」 (historical individual) 、華雪 (W. H. Walsh) 的「總括,或接合」 (Colligation) 與明克 (Louis O. Mink) 的「形構,或整合形態」 (Configuration) 等概念。在這些人的歷史理論或歷史實踐中,雖然他們都掌握了歷史的「個體性」原則;但在他們中有些人的歷史理論與實踐中潛藏了對歷史實在的形上學思考,歐克秀與明克或許是當中的例外。他們同時也主張,在歷史研究中,歷史家所面臨的不是一系列互不相聯繫的事實 (brutal facts) 。歷史家必須掌握歷史的整體性,提供一個特定的觀點 (individuate a point of view) 使過去得以被理解。在我的討論中,柯靈烏與安可史密斯是此一史學系譜的最高峰 (zenith) 。我認為,以柯靈烏的「史學史」概念與安可史密斯的「敘述實體」概念來說明何謂「史學史」的研究,最為恰切。因為,他們都帶有後現代主義史學中「敘述轉向」 (narrative turn) 的特色。他們對歷史學性質的討論,把我們由過去實在本身、歷史家的認知程序與策略,轉移到歷史實踐與歷史文本當中。也就是說,我們必須將歷史學視為一個歷史學家們所組成的作者與讀者的詮釋社群 (interpretive community) 。19 同時,我們將歷史學中的討論,視為對歷史家們的歷史著作,也就是歷史文本的討論,了解歷史文本間的差異所在。歷史洞視與歷史學科的真實進展,就在於對歷史文本間之差異性的掌握。這將引領我們進入後結構主義對歷史文本的討論。

    + +

    洪堡德:「歷史觀念」

    + +

    洪堡德是十九世紀德國歷史主義的奠基者,蘭普雷希特 (Karl Lamprecht) 喻之為「最偉大的觀念學理論家」 (greatest theorist of the Ideenlehre) 。20 洪堡德試圖為多樣的歷史現象尋求一個和諧地整體,了解歷史中內在的聯繫與一致性 (Zusammenhang, connectedness) 。洪堡德認為,在混亂的現象背後,隱藏了一個永恆的、形上學的實在。所有的歷史現象皆是此一形上實在的具體表達。這一個形上的實在也就是「觀念」 (ideas) 。「個體性」是這些形上觀念的設準。「歷史觀念」儘管是永恆的、無時間性的,但它們都表現在具體的歷史個體中。個體性是一個潛藏的形上實在、倫理觀念的具體的、歷史的表達。21 個體性不只表現在每一個個人身上,同時也表現在社會制度、國家與民族。

    +

    歷史家的任務在於理解每一個歷史個體,也就是「歷史觀念」,而不僅僅在呈現「如其發生」 (present what actually happened) ,必須能發現事件的內在網絡,將之視為一個整體。為了達成這個目的,歷史家必須運用「同情的理解」 (Verstehen, sympathetic understanding) 。

    +

    因此,對洪堡德來說,歷史家的任務在於必須能夠聯繫事實與觀念。

    + +
    +

    有兩種同時進行而獲得歷史的方法:第一,是對事件作精確的 (exact) 、不偏不倚的 (impartial) 、批判的 (critical) 研究;第二,連接所探究的事件,並且以直覺的理解 (intuitive understanding) 那些無法經由第一種手段達到的事件。22

    +
    + +

    第一種方法是歷史批判方法的運用,也就是歷史事實的建立。這是十九世紀日爾曼歷史主義所仰賴的基礎。23 但一個事件僅能部分地經由感官世界被認知,我們經由第一種方法所能獲致的僅是歷史的必要基礎、是它的材料,而非歷史自身;其餘的部分必須經由直覺、推論 (inference) 與猜想 (guess, or divine) ,歷史家必須將這些片段聚集成為一個整體。洪堡德賦予史家的任務不僅是簡單的描繪實在,而是了解觀念。

    +

    第二種方法與藝術家相類似。洪堡德認為歷史與藝術同樣在模擬與再現實在,兩者的基礎同是認知真實的形式、發現必然性與清除偶然的事物。但歷史與藝術不同,藝術家僅僅去透過了解實在的表象,因而遠離了實在;歷史的目的僅僅在於尋找實在,並穿透到實在之中。歷史家尋求事件的真理,正如藝術家尋求形式之真理。

    +

    歷史運作所依賴的成分是實在感,歷史家所尋求的是實在。它包含了對存在在時間中變動的知覺,依賴於過去與現在的原因,同時意識到精神的自由,所以實在除了表面的偶然性,尚有其內在之必然性。歷史家必須能揭示歷史事實間所存在的必然性。

    +

    理解依賴於探究的心靈與探究的對象之融合。理解總是運用一個預先存在的普遍觀念 (a pre-existent general idea) 至那些新鮮的與特殊的事物。但歷史家所賦與他的敘述以形式的,並非想像的哲學價值,或詩性的誘惑,而是真理與精確性。洪堡德反對將黑格爾式的歷史哲學用來加諸於歷史。但他仍承認一個形上學實有的存在,歷史觀念是此一形上學實有的彰顯。歷史家無法直接了解此一形上學實有,僅能透過表達此一形上學實有的歷史觀念來了解。是故,洪堡德說道:人類的判斷無法直接認知到宰制世界的計劃,僅能在彰顯它們自身的觀念中猜想它們。24 因此,所有歷史都是觀念的實現。

    + +

    赫伊津哈:「歷史感覺」與「歷史形式」

    + +

    荷蘭歷史學家赫伊津哈的史學帶有濃厚的美學風格,他特別強調歷史家捕捉過去,而非再現過去的能力,這影響了安可史密斯的歷史理論。25 同時,赫伊津哈意圖綜合在歷史理解中,個別與普遍的因素。對於赫伊津哈來說,歷史理解必須掌握歷史的個體性與普遍性的脈絡。

    +

    赫伊津哈的學術事業的開端正處於十九世紀末與二十世紀初實證主義史學與歷史主義爭論的時期。在德國,蘭普雷希特意圖將自然科學的研究方法引入歷史的領域。對蘭普雷希特而言,唯有能夠推導出普遍概念的學科才能稱之為科學。歷史研究必須能夠推導出關於個別事實的普遍概念,唯有如此,歷史才能夠成為一們科學。同時,蘭普雷希特認為,歷史學的任務在於成為一門社會心理學 (social psychology) ,他為歷史學提供了一種心理學式理解的方法。另一方面,受蘭克 (Leopold von Ranke) 的影響,有些歷史家們認為歷史家的活動在於直覺 (intuition) 與「再經驗」 (re-experience) 個別的事實。德國新康德主義學者 (Neo-Kantian) ,如李克特 (Heinrich Rickert) 與文德爾班 (Wilhelm Windelband) 等意圖建立人文科學的方法論。他們區分「表意的」 (idiographic) 與「律則的」 (nomothetic) 科學。前者處理的是關於個別的知識;後者關心的是普遍的概念。他們認為關於個別的知識,而非普遍概念才是人文科學的真正關心所在。吾人可以如實地「再經驗」事件的獨特過程。26

    +

    赫伊津哈與蘭普雷希特爭論。他認為,將歷史化約為普遍概念,將使事實失去其獨立的意義。同時,他也反對蘭普雷希特的心理學式的歷史理解方法。但他也不認為如蘭克的後學所稱,吾人可以如實地再現過去,史家也沒有意圖去複製 (reproduce) 過去的實在。赫伊津哈認為,歷史同時結合了普遍性與特殊性。歷史經驗是個體性、普遍性的辯證同一。

    +

    赫伊津哈提出了「歷史感覺」或「歷史碰觸」 (historical contact) ─他放棄使用「歷史想像」 (historical imagination) 或「歷史視覺」 (historical vision) 的名稱,因為,就作為一種視覺的概念,太過於受限─的理論。歷史感覺是歷史家從一份文獻檔案、一部編年紀、一份印刷物、一首古老樂譜的記號所喚起的經驗。赫伊津哈以比倫 (Henri Pirenne) 的《比利時史》 (Historie de Belgique) 第一、二部為例,說明比倫在書中並未去描繪人民的實際生活,也未呈現過去的實在;但他給予了豐富的形象,令它們能夠被吾人所感受。27

    +

    赫伊津哈斷言,歷史是一種詮釋過去對吾人意義的科學。在此一歷史概念中,隱含了「安排」 (arrangement) 的概念。歷史並不是歷史家被動地接受史料,毫無批判地將之聚合而成。相反地,歷史家必須去理解脈絡、「形塑」 (form-giving) 、給予意義,指出歷史與當代文化形式間的關係。赫伊津哈提出了「歷史形式」理論,或他所稱的「形態學的方法綱領」 (methodical program of morphology) 。每一個明確定義問題的歷史論文都在回答一個歷史形態學的問題。

    + +
    +

    為了去理解反映在他自身文化中的一個過去片段,無論何時何地,歷史家必須嘗試去觀看這些片段的形式 (forms) 與功能 (functions) ……。

    +

    歷史認知的心靈所知覺到每一個事件,假定了一種對過去的材料之安排,從混亂的實在中,結合了一定數量的資料構成為一個心靈圖像 (mental image) 。28

    +
    + +

    赫伊津哈堅持史家對過去的理解是與他自身的當代文化相關的。在實際的日常生活中,吾人同樣在安排實在。因此對赫伊津哈而言,歷史思想實際上是思想的擴充,對實在採取一種極端唯名論 (nominalism) 的觀點。在日常生活與在政治史、經濟史中,我們經常運用諸如議會 (parliament) 、世界大戰 (world war) 、資本主義 (capitalism) 等唯名的概念賦予過去以一種形式。這種現象在文化史的領域特別顯著。赫伊津哈認為文化史的真正問題在於社會現象的形式、結構與功能的問題。文化史家必須清楚地定義生命、思想、習俗、知識、藝術的形式。但這並不意味著將歷史化約為社會學。文化史家必須考慮現象自身所具有的顯著意義,而非去設計一些從現象中演繹出的普遍有效的規則。赫伊津哈意圖綜合普遍的與個別的,而掌握歷史的個體性。

    + +

    歐克秀:「歷史個體」

    + +

    歐克秀是英國觀念論哲學的祭酒,他的歷史理論是奠基於英國觀念論 (British Idealism) 的哲學之上。英國觀念論者,特別是布萊德雷 (F. H. Bradley) ,結合了對實在的形上學之討論與經驗哲學,可以說是後康德觀念論 (post-Kantian idealism) 與英國經驗主義 (empiricism) 的聯姻。29 但歐克秀否認康德所謂「物自體」 (thing in itself) 存在的可能性,而堅持實在即是經驗。沒有可以與經驗相分離而外在於心靈的事實或對象。因此,歐克修解消了傳統關於認知主體與客體、心與物、思想與事實的二元分歧。在歐克秀的歷史理論中,顯現了他對歷史家實際經驗的注重。歷史世界即是歷史家所建構的經驗世界,是歷史家對於他所面對的所謂的「權威」 (authorities) 或「史料」 (sources) 的一種安排。

    +

    歐克秀從「經驗的整體性」 (experience as a whole, or the totality of experience) 觀點來考察各種經驗模式。歷史是一種抽象的經驗,因為它是建立在其自身之設準 (postulates) 上。對歐克秀而言,經驗是完整的、是全然地自我批判的。經驗建立在其自身之設準,意味著它不是一項完整的經驗,它是經驗遇到阻礙、是有所保留的,是抽象的。因此,它不是完整的經驗;而是經驗的修正 (modification) ,是一種經驗模式 (mode) 。唯有哲學掌握了經驗的整體性,哲學經驗是沒有預設的經驗,使全然地批判的。

    +

    但歐克秀堅持各種經驗模式的自主性,拒斥不相干的考慮介入到其他經驗模式中。歷史是一項建立在其自身的設準,同時能產生適合其自身結論的活動。它是一個自主的觀念系統、經驗形式或論域 (universe of discourse) 。因此,他反對以自然科學的解釋模式運用到歷史的領域,及以實際的考量來解釋歷史,但他也反對將歷史觀點運用到其他經驗模式。因此,歐克秀對歷史理解的自主性之堅持,同時反映了他對十九世紀以來的幾股重要的思潮,如實證主義與歷史主義,所持的保留態度。

    +

    歐克秀堅持實在的判準,是所謂真理的「連貫說」 (coherence theory of truth) ;而非「符應說」 (correspondence theory of truth) 。歐克秀以所謂的歷史建構論 (historical constructionism)30 來反對實證主義史學將歷史定義為史料學。歷史真理的判準在於歷史家所建構的觀念世界是否連貫一致,而非符應於任何既定的觀念或外在於經驗世界的實在。

    +

    同時,歐克秀也否定將歷史區分成客觀的事件過程 (history as it happened, the course of events) 與對其之思想 (history as it is thought) ,這假定了事實與經驗是可以相分離的。同時,歷史家的經驗不是去發現、去捕捉,或者詮釋;而是去創造、去建構。因為去發現、去詮釋隱含了外在於心靈的對象。書寫歷史是創造歷史的唯一方法。31

    +

    歐克秀反對如鮑桑葵 (B. Bosanquet) 等,將歷史視為一個系列 (a series) ,或一個僅是接合的編織物 (a tissue of mere conjunctions) 。同時,歐克秀也批判十九史世紀的所謂「科學地歷史家」 (scientific historians) 對獲得所謂「一手史料」的必要性與精確性、研究工作的必要性的堅持之見解。事實從來不是給定的,而是獲致的。事實與經驗、思想是密不可分的。歷史事實或權威自身是歷史思想的產物,在被運用之前必須被轉譯為歷史的範疇。歷史是斷定證據要求我們去相信的 (what evidence obliged us to believe) ,而非將「事實發生」 (what actually happened) 做為歷史的目的。32

    +

    在歷史研究中,歷史家並非開始於孤立的事實,歷史做為一種經驗模式,是一個世界,而且是一個觀念的世界。歷史家的工作在於將這個給定的世界,使之成為一個更完整的觀念世界。

    + +
    +

    歷史不是開始於蒐集片段的孤立事實,也不是開始於普遍的懷疑,更非開始於空白的與空洞的意識;而是開始於一個同質的觀念世界。33

    +
    + +

    在經驗中所成就的是一個完全連貫一致的觀念世界,它必須獲得最大程度的統一性。但歷史的觀念世界是一個不穩定的觀念世界。在歷史中,新的發現不應被增添入舊的觀念世界,而必須轉變整個觀念世界,使之成為一個更為連貫一致的世界。

    +

    從邏輯的觀點看,歷史中所給定的是一個「設準」 (postulates) 系統。

    + +
    +

    沒有歷史家是開始於一空白的意識、孤立的觀念或普遍的懷疑,心靈狀態從未是如此地。它總是開始於一套設準(大不分未經檢證的),限定它的思想,給予事件過程特殊的觀點,此一點是與它的設準相符的。34

    +
    + +

    歷史經驗的判準是自我完整性 (self-completeness) 或個體性,亦即歷史世界是一個連貫一致的世界,而非由孤立的事實所組成的世界。歷史家在從事其活動時,它的主要任務是去建立事件間具有意義的關係,將前在的 (antecedent) 與接續的 (subsequent) 事件連接起來。這樣的關係是內在的或內部的,而非外在的或外部的。歷史經驗所處理的對象是事件、事物(或制度)與人。它們之間的區分不是絕對的或終極的區分。歷史所處理的對象不是絕對獨特的時空要素。歐克秀斷言這樣的歷史從未被書寫過,也無法被書寫出來。35 同時,前在的事件與接續的事件間關係的構成是一種「偶然性」 (contingency) 的關係。歷史世界整體的同一性來自事件間偶然地黏合 (contiguity) ,或碰觸 (touch) 。36

    +

    歷史研究的對象預設了一個主題的概念,此一主題概念即是「歷史個體」。歷史家必須劃定「歷史個體」做為歷史認知的概念工具。所謂的「歷史個體」,包括歷史事件、事物、制度與歷史人物。對於觀念論而言,設定歷史個體是一抽象的行為,它破壞了經驗的整體性。歷史個體是被預設的,被賦予、指定的 (designated) ;而非被定義的 (defined) 。歷史自身不能、也無法提供歷史個體,歷史是建構在個體性概念的設準上。37

    +

    歐克秀繼續論證道,歷史個體的兩項原則是連續性 (continuity) 與非連續性 (discontinuity) 。歷史個體的個體性,是由非連續性的原則建立 (established) ;由連續性的原則而得以維持 (maintained) 。歐克秀相信這是所有歷史思考中所隱含的假定。38

    +

    歐克秀舉「羅馬帝國」為例,它能被從其環境中指認出來並不是因為它在形狀、大小或內容上從不變化,或者是歷史家選擇了一最少阻礙的界限,將事物的名稱限定到事物變遷,使其個體性變得含混之前或某些不被外在環境改變之核心;而是開始於與先前事件間明顯地持續性的斷裂而標示出來,一但它被建立,它可以保存持續的存在。因此,一個歷史個體能夠從歷史中被指定出來,是因為打破了持續性,並進一步維持其存在。

    +

    在此處,我們面臨必須考察歷史變遷的問題。換言之,即歷史個體在時間中的變遷與持續性。因此,我們面臨的是「同一性」 (sameness) 與「差異」 (difference) 的問題。歐克秀據以解決此一問題的是從黑格爾與布萊德雷那兒得來的「具體的共相」或「差異中的同一性」邏輯。對黑格爾與布萊德雷而言,同一性之設計可達成是因為設定了差異;差異可以被識別是因為設定了同一。歷史個體是一「變遷之同一」 (changing identity) ︰

    + +
    +

    歷史中的個體是不斷生成變化,也持續同一的;它持續一段時間,地方的轉變並不會破壞它的同一性。歷史事件從未僅僅是一個定點,一個歷史事件或制度從未僅僅存在於這兒或那兒;一個歷史人物,只要活著,日復一日,輾轉流徙,依舊保持著其同一性。歷史個體所仰賴維持其同一性之原則是所謂的「不可區分的同一性」 (identity of indiscernibles) 。39

    +
    + +

    此一「不可區分的同一性」意謂著,同一性之做為同一,不因多樣性而使之產生差異。

    +

    歐克秀在本文的討論中所佔有的特殊地位,在於其對所謂歷史個體之論述。他指出歷史理解預設了歷史個體做為歷史認知的概念工具,同時,此一歷史個體的判準是個體性,也就是具體的共相。進一步,基於歷史建構論與經驗與實在不可分離的立場,對歐克秀而言,歷史個體並非外在於歷史家的經驗與思想,而是出於歷史家的建構,這將歷史個體指向敘述主義的個體性概念。

    + +

    華雪:「總括」與明克:「形構」

    + +

    華雪與明克的歷史理論同樣在回應 1943 年韓培爾 (Carl G. Hempel) 的論文─〈普遍法則在史學中的功能〉 ("The Function of General Law in History") 。40 根據韓培爾,歷史解釋的邏輯結構與自然科學是一致的。普遍法則在歷史解釋中的使用,如同在自然科學的解釋是不可或缺的。在歷史解釋中,一個歷史事件(「受闡釋端」, explanandum )得以被解釋,是一系列先行條件(「闡釋端」, explanans ),透過一套普遍法則(一個或多於一個以上的通則)的運用而達成。這即是著名的「覆蓋律」解釋模式 (covering law model) 。

    +

    華雪修正了韓培爾的理論,歷史解釋是一種「準科學」 (quasi-scientific type) 的解釋,同樣需要運用普遍法則到特殊的事件。但歷史解釋所尋求的與自然科學的解釋不同。自然科學的解釋試圖將事件安置到普遍法則之下;歷史解釋則試圖去顯示事件之間的內在關係,使被解釋的事件與之使其與先前、之後的事件連結,構成一個持續的過程,成為一個有意義的整體。為反對韓培爾的理論,華雪捍衛「總括」概念在歷史解釋中的重要性。麥可克雷夫 (C. Behan McCullagh) 說道:「華雪對分析歷史哲學最大的貢獻,在於提出並探討總括一詞在歷史寫作中的功能。」41 所謂「總括」,是將許多不同的事件聚集安置在適當的概念之下 (groups different events together 'under appropriate conceptions') 。42 根據華雪,「總括」一詞,來自於十九世紀的邏輯學家惠威爾 (W. Whewell) 。華雪承認,在歷史學與自然科學中,歷史家與科學家同樣都運用總括的方法。但歷史解釋與自然科學解釋的目的不同。歷史解釋在與解釋事件如何與為何發生。華雪贊同德雷 (W. H. Dray) 的「解釋什麼」 (explaining what) 的看法,在歷史中,詮釋 (interpretation) 多過於解釋 (explanation) 。43 根據華雪,一個事件得以被解釋,是因為能將之置入到一個運動的過程中。

    +

    華雪注意到,在歷史實踐中,歷史家們所經常使用一些引導性與支配性的操作概念,如「工業革命」 (the Industrial Revolution) 、「啟蒙運動」 (the Enlightenment) 、「浪漫運動」 (the Romantic Movement) 、「十九世紀英格蘭的改革世紀」 (the age of reform in nineteenth-century England) 、「獨占資本主義的興起」 (the rise of monopoly capitalism) ……等。這些概念將歷史過程組織成一個可理解的整體。華雪將這些歷史家們經常使用的概念,稱之為「總括」概念。44

    +

    在歷史中使用總括概念意味了去詮釋。華雪指出,我們將不同的事件歸屬到一個單一的發展,並不是將他們以休姆的方式視為鬆散的與分離的。因此,歷史並非個別事實的積累,而必須將他們視為一個整體。歷史家與他們的讀者們最先碰觸到的是一大堆互不聯繫的材料,歷史家接著經由顯示特定的主題或發展,賦予這些材料以特殊的意義。歷史家解釋單一的事件是經由展示這些事件如何地被融入一個持續發展的過程。最值得注意的是,華雪同時注意到在歷史實踐中,「總括」概念,或他所稱的「個殊物的複合體」 (the complex particulars) 自身也有其歷史。我們在以下討論安可史密斯的「敘述實體」概念時,將會發現安可史密斯獲益於華雪「總括」概念之處。

    +

    華雪同時受到柯靈烏與歐克秀的影響,但對二者皆有所保留。一方面,他堅持歷史解釋的對象是行動 (action) ,是一個過程 (process) 。同時,他堅持目的論的 (teleological) 解釋。歷史家所意圖解釋與感興趣的不僅是意圖 (intention) ,也包含結果 (results) 。歷史事件不是如經驗哲學家所言,以外部相連地發生;所有事件必然地是一個行動者或一群行動者在一段時間內從事一項長期的政策 (pursue a long-term policy over a period of time) 。但華雪認為一個計劃的政策不一定能確切執行,它可能遭遇一些阻礙。因此華雪以過程、運動與發展的觀念取代一個已實現的政策為歷史思想的首要部分。這是對柯靈烏的修正之處。

    +

    另一方面,華雪的「總括」概念,與歐克秀的「歷史個體」有相近之處。華雪坦承歐克秀的「歷史個體」與觀念論的「具體的共相」是他的「總括」概念的來源。但歐克秀反對目的論式的歷史詮釋。因為,這種帶有實際的現實目的去解釋歷史,不可避免地將「倒讀歷史」 (reading history backwards) 。我們應嚴格區別「歷史的過去」 (historical past) 與「實際的過去」 (practical past) 。45 華雪認為歷史不可避免地總是「倒讀地」,但這並不意謂我們將會犯了「惠格史家」 (Whig historians) 的謬誤,也不意謂著我們無法區分歷史的過去與實際的過去。46

    +

    麥可克雷夫、德雷與薛必克 (C. B. Cebic) 等人試圖進一步擴大華雪的「總括」概念在歷史寫作中的功能。他們試圖在「總括」概念下引入「分類」 (classification) 概念。換言之,歷史解釋不僅解釋事件的持續過程與運動、發展,同時它也允許將歷史事件作適當的分類,而且也必定蘊含分類概念。換言之,我們可以分析一個「總括」概念所具有的分類概念,而這些分類概念即是此一「總括」概念的性質。歷史爭論即是在討論「總括」概念的分類性質。47

    +

    麥可克雷夫舉艾爾頓 (Geoffrey R. Elton) 對 1532 至 1540 年間由湯瑪士‧克倫威爾 (Thomas Cromwell) 對英國政府統治所帶來的變革之描述為例,來說明「總括」概念所具有的分類性質。艾爾頓將這些特定的事件總括為「都鐸統治革命」 (the Tudor Revolution in Government) 此一概念。根據艾爾頓,此一「統治之革命」,有兩個層面:其一,是國家憲政體制的革命,國王與國會第一次獲得了對領土完整的主權,同時國王擁有對世俗與宗教事物之權威;其二,是政府行政的改革,科層政府體系取代了皇家管家的統治。48

    +

    對麥可克雷夫而言,歷史爭論在於爭辯總括概念下,這些分類概念的性質。以艾爾頓的例子為例,在歷史論爭中,許多歷史家們同意艾爾頓所描述的「革命」,而非「演進」 (evolution) ,那麼多大統治方式的歷史變遷能夠被稱為「革命」?進一步,所謂的憲政與行政上的「統治之革命」,究竟是發生理論上的或實際上的?歷史家必須澄清這些論題。

    +

    華雪所意圖提供的是一個具說服力的觀念論歷史理論,同時也修正了實證主義的歷史思考。在歷史學中,「總括」概念的使用類似黑格爾的「具體的共相」邏輯。所謂「具體的共相」,意指「多樣性中的同一性」 (unity in diversity) ,即是在多樣的現象中尋求出一個統一性。「具體的共相」不同於「抽象的共相」 (abstract universal) ,它是普遍的,但不是抽象的,是具體的,是關於個體事實的。

    +

    明克是分析歷史哲學界中「語言轉向」 (linguistic turn) 的代表。明克對歷史哲學的討論,主要的興趣在於歷史著作的「文本性」 (textuality) 與「互為文本性」。49 對明克而言,歷史論證中最富有意義的結論是埋藏或混含在歷史著作自身的敘述結構之中。50 敘述對於作家與評論家來說不僅僅是一個技術上的問題,而是一個首要的與不可化約的人類理解形式。51 同時,即使是最具分析性的歷史論文,如赫伊津哈的《中世紀的凋零》 (The Waning of Middle Ages) 與拉斯烈 (Peter Laslett) 的《失落的世界》 (The World We Have Lost) ,都預設了歷史家更普遍底理解、敘述形式與歷史變遷模式。明克也注意到了歷史著作的「互為文本性」。他主張歷史家必須閱讀其他史家的作品。這是任何歷史知識的理論必須要考慮到的。52

    +

    明克反對韓培爾將歷史解釋與科學解釋的邏輯結構等同起來,他主張歷史與科學的理解方式是不同的。明克區分了三種組織吾人經驗的理解模式:「理論的」 (theoretical) 、「範疇的」 (categorical) 與「形態的」 (configurational) 分別相應於科學、哲學、歷史與敘述虛構 (narrative fiction) 。53

    +

    所謂「形態的」理解,是將一系列的事物安置到一個單一的、複合的與具體的關係中,作為此一關係複合體的要素。一個特別的事件的整合型態就好像是拼圖 (jigsaw puzzle) 的一部分。54 明克斷言,在人類的理解經驗中,總是試圖將事物視為一體 (seeing-things-together) 。

    +

    明克認為,歷史家的歷史研究,無論多費力與技巧,僅僅只有增加事實知識的精確性而已,它們依舊是偶然與不連續的。對歷史證據的分析與批評在原則上能夠解決關於事實的爭論,但無法解決關於各種關係的可能組合。55 因此,明克主張歷史家的首要任務在於整合與綜合。

    +

    歷史家必須將一個歷史敘述的各個成分透過一個重疊描述的網絡 (a network of overlapping descriptions) 整合在一起。而這些重疊的描述或許不是故事本身的一部分,而僅僅是將它理解成為一個整體。56

    + +
    +

    在形態的理解中,結尾與開端的允諾相連結正如開端與結尾的允諾相連結。如此說來,向後參照的必要性抵銷了向前參照的偶然性。去了解時間的接續性意味著同時以兩個方向思考,因此時間不再是承載著我們沿流而去的河流,而是從空中同時俯瞰逆流而上與順流而下的河流。57

    +
    + +

    明克以空間的語言,透過空間解構了時間的連續性質。歷史認知不再是歷史家沿著時間之流作「歷時性的」 (diachronic) 理解;而是歷史家將自身置於一個時間之流外的空間俯瞰,從一特定的觀點作「共時性的」 (synchronic) 理解。58 歷史理解是從一個位於時間之流外的特定觀點同時以兩個方向來進行的,即逆流 (upstream) 與順流 (downstream) 。在此,明克的「形態的」理解具有雙重意義:其一,是「形態的」繼承了歷史主義對於歷史理解應將過去視為一個連貫的整體的見解,依此看來,明克的「形構」等同於先前洪堡德所言之「歷史觀念」;其二,是明克以空間的隱喻對時間所作之解構,打破歷史主義對時間連續性質的信仰,而指向後現代主義的歷史時間思維。

    +

    從華雪到明克,我們觀察到在歷史理論的幾個重大轉變。其一,在分析歷史哲學界所發生的「語言轉向」,使得分析歷史哲學家的注意焦點從歷史解釋的層面轉移到歷史敘述的問題。從華雪到明克代表了此一轉變。華雪試圖以觀念論的「具體的共相」邏輯,取代自然科學的解釋模式;明克則已注意到敘述作為歷史家敘述地認知的重要性。其二,是從歷時性的到共時性的歷史思維的之轉變。華雪仍然試圖以過程、發展與運動的觀點來認知歷史,他殘留了歷史主義的時間線性思維;明克則以空間的隱喻解構了歷史主義的時間觀念,其三,華雪與明克都試圖去更新在二十世紀已破產的「思辯的歷史哲學」 (speculative philosophy of history) 系統;儘管它們都拒絕「思辯的歷史哲學」系統對歷史過程提出的規範性解說,歷史過程沒有一定的發展模式或韻律。但他們皆同意,「思辯的歷史哲學」將歷史視為一個整體過程的概念,是歷史學中不可或缺的認知工具。59

    +

    從以上對安可史密斯的「敘述實體」之系譜學考察中,歷史主義的「個體性」原則,成為歷史思維的規範性原則。無論是洪堡德的「歷史觀念」、赫伊津哈的「歷史形式」、歐克秀的「歷史個體」、華雪的「總括」或明克的「形構」,都認為歷史認知須在多樣、變化的所謂「事實」中,尋求一個統一的整體。歷史認知不是單純的事實之積累,而必須掌握歷史之整體性。個體性提供了史家一個特定的歷史觀點,從此一歷史觀點,過去可以被視為一個連貫一致的同一體。

    + +

    + +

    以下,我將以柯靈烏的「史學史」與安可史密斯的「敘述實體」觀念為例,從普遍地來說明歷史學的性質;從特殊地來說明西洋史的研究。我並主張二人的理論將有助於我們瞭解:何以「史學史」的研究是歷史研究中重要的工作;同時,它也將獲致豐碩的成果。進一步,二人的理論可以解決台灣西洋史研究中所碰觸的難題。最後,二人的理論又何以對後現代主義史學中對「客觀性」、「連貫、一致性」 (coherence) 、「大敘述」 (Grand Narrative) 、「後設敘述」 (meta-narrative) 等問題的討論有所獻替。60

    +

    選擇柯靈烏與安可史密斯的歷史理論來說明歷史學與西洋史研究的性質,並進而強調「史學史」研究的重要性,自有其理論與實際上的需求與便利之處。首先,柯靈烏與安可史密斯的理論皆是從歷史家的實踐或歷史學專業的現況出發。二十世紀的分析歷史哲學與歷史理論對歷史學性質的討論,經常僅以歷史陳述中的「字」 (word) 、「語句」 (sentence) 、「陳述句」 (statement) 作為分析對象。他們所分析的對象是歷史家們所使用語言的邏輯結構。這樣的分析方法無法瞭解歷史家們實際上所從事的活動為何,同時也與歷史家們實際所從事的狀況不合。61 柯靈烏與安可史密斯的理論不僅注意到歷史思維邏輯,同時也兼顧了歷史家的實際活動。

    +

    其次,柯靈烏與安可史密斯的理論分別代表了現代主義史學62 與後現代主義史學。兩人在歷史認知理解的某些一致之處,可以做為我們回應史學危機的參考,同時做為我們在歷史理論與實踐上前進的基礎。

    + +

    柯靈烏:「史學史」

    + +

    柯靈烏的「史學史」概念見於他新近重出於世的手稿中。相關的討論分別見於一九二六年的〈歷史哲學講義〉 ("Lectures on the Philosophy of History, 1926")63 與一九二八年的〈歷史哲學大綱〉( "Outlines of a Philosophy of History, 1928" ,此即是柯靈烏在其《自傳》中所稱的「 Die 手稿」, Die Manuscripts )。64 根據柯靈烏《自傳》中的記載,他的歷史概念在 1928 年夏天獲得了重大進展。65 杜森 (W. J. van der Dussen) 指出,柯靈烏的歷史思想在一九二六年到一九三0年間起了重大的轉變,他拋棄了早期的實在論 (realism) 的歷史概念,而發展出觀念論 (idealism) 的歷史理論。66 因此,這二篇討論歷史哲學的手稿在柯靈烏歷史理論的發展中占有重要的地位。同時,在其中我們也可發現柯靈烏歷史理論中與後現代主義接近的地方。

    +

    在討論柯靈烏「史學史」觀念之前,首先,我借用梅驥 (Allan Megill) 區分「大敘述」 (Grand Narrative) 的四個「理想型」 (ideal types) 來作為進一步分析的概念工具。所謂「大敘述」,意指在歷史實踐中宣稱給予過去一個普遍的而具權威性的論述,它假定了歷史是一個連貫而一致的整體。梅驥區分了「大敘述」的四個層次,亦即四個「大敘述」的理想型。同時,梅驥認為,「大敘述」的四個層次與西洋史學史的發展相符:其一,是相信一個單一的歷史 (a single History) 的存在,而且我們已理解其究竟;其二,是相信一個單一歷史的存在,但必需待進一步的研究完成,我們方可理解它;其三,是相信一個單一歷史的存在,但它無法被言說,它僅能理想地 (ideally) 存在,作為一個自主學科不可企及的目標。換言之,連貫一致 (coherence) 僅存於歷史家或歷史學科的思維中;其四,所有關於此一單一歷史存在的假定都被質疑,是站不住腳的。不管它是主觀地被視作一項事業,或客觀地作為一項現在或未來可以被言說大敘述。67

    +

    柯靈烏所面臨歷史學上的問題,是屬於梅驥所謂「大敘述」理想型的第二層次;而他所提供的答案是屬於第三層次的。

    +

    柯靈烏反省西洋史學史的發展,他注意到西洋史學中在歷史研究的對象與題材不斷地擴大的過程中,尋求一個對歷史發展的整體觀點之努力。希臘時代,歷史經驗的限制使得所有的歷史都是當代史。歷史寫作的最佳形式是回憶錄 (memoir) 與當代史。柯靈烏以休昔底的斯為例,指出受限於自身的視野,休昔底的斯的史學僅限於歷史家能親證的範圍。柯靈烏抨擊休昔底的斯代表了希臘人直率的自我中心想法,將一切非希臘人的事物視為野蠻的,不值得嚴肅地加以研究。

    +

    羅馬人的歷史經驗擴大了歷史觀念。歷史興趣的擴張,導致在歷史寫作中加入許多新的因素,這些新的興趣是異質的、古老而遙遠與不熟悉的。因此歷史家在撰寫歷史時,面臨到一個問題,即為何我要處理這個而非別的問題?柯靈烏說道,這時我們將面對「選擇」的概念。因此,出現了探討特定單一的歷史主題的歷史「專論」 (monograph) 或「論文」 (essay) 。

    +

    「歷史專論」的作者們承認,他們所處理的是對部分的陳述,是個別的;而不是普遍史。柯靈烏認為,歷史事實並不是孤立的,而是與其他事實相關聯的。「歷史專論」概念的主要缺陷在於將事實從它們的脈絡中抽離出來,而構成一篇歷史專論或論文,是一個抽象的行為。

    +

    因此,這導致十八世紀的作家們嘗試去寫作「普遍史」 (universal histories) 。根據柯靈烏,「普遍史」觀念是「一種認為歷史應被視為一個整體的觀念。從這個觀點看,將會發現擁有一個作為永恆的普遍法則之例證或作為發展一個單一計劃的明確的有機統一體。」但普遍史觀念的最大缺陷在於它的規模過於龐大,歷史的整體無法以單一的歷史著作來掌握,這樣的著作從未被寫定。因此,普遍史變成了從多樣的事實中選擇作者認為重要的與感興趣的,這樣的普遍史不具有普遍性;普遍史的普遍性應是來自於觀點的統一性。

    +

    十九世紀以來,歷史專業化的發展,使職業歷史家尋求更多與更小的細節。與十八世紀的哲學式的歷史家不同,它們相信歷史的事實的總體及對其之敘述已經完整,哲學式的歷史家的任務再於將或多或少的片段融入而為一個整體;十九世紀的職業歷史家們相信歷史的整體尚未被發現,但尚待發現,而且也將被發現,因此歷史家的任務在於收集更多與更多的細節。這即是所謂的實證主義史學或實在論者的歷史理論。

    +

    柯靈烏強烈地批判實在論者 (realists) 的知識理論;同時,對十九世紀實證主義史學宣稱「定論歷史」( ultimate history ,在此,柯靈烏所使用的術語是「歷史個體論」, historical particularism )68 的可能性提出質疑。根據實在論者的知識理論,知識的對象獨立於心靈的認知活動之外,而有其實在性 (actuality) 。認識活動在於認知的心靈能夠掌握 (appropriation) 被認知的對象。根據柯靈烏的歷史理論,實在論者的知識理論在歷史的領域遭到嚴苛的挑戰,完全無法適用。因為歷史知識的對象是已發生的,沒有實在性的。如果實在論者的知識理論成立,那麼,歷史學將失去其知識論上基礎,陷入歷史懷疑論 (historical skepticism) ,歷史知識也將岌岌可危。

    +

    十九世紀的實證主義史學假定待所有研究工作完成後,一個單一、完整的歷史是可以獲致的。面對十九世紀歷史學職業化、專業化的結果,歷史知識大量地擴充,對此一單一、完整的歷史之期望,似乎遙遙無期。柯靈烏認為,這些歷史專論的作者意圖去蒐集所有的現有證據,給予完整的詮釋,如此好像給予某些細節最終的定論。這似乎隱含了歷史家能夠將所有的現有證據在論文中完全掌握。實際上,這是錯誤的。柯靈烏說道:每一個特定的與每一代的歷史家對某一特定之主題擁有一定數量的證據;下一代的歷史家們又將增添新的史料,那麼何處是此一過程的終結?反對這樣的理論,他批判所謂「定論歷史」的可能性。柯靈烏認為,歷史知識的進展並不是在個別的事實上,不斷地增添更多的個別事實。將歷史事實視為一個實際存在的,而且可以被徹底研究掌握的整體,將導致我們去尋求更小的細節。這是十九世紀歷史專業化的後果。我們所需要的並不是去譴責歷史研究專業化,而是提出新的歷史概念。

    +

    在一九二八年的〈歷史哲學大綱〉中,柯靈烏提出了「歷史的理想性」 (the ideality of history) 概念,來解答歷史知識論的基礎問題。他說道:因此,為反對所有的實在論,歷史哲學必須斷言歷史的理想性,以對立於歷史事實的實在性。69 所謂「理想性」,是斷言思想對象是一個理想對象,而沒有實在性。歷史思想的對象並非是過去的實在,而是現在的思想。

    +

    柯靈烏討論二十世紀史學的一個重要問題,即是在歷經十九世紀史學專業化的過程後,二十世紀的史學著作以驚人的速度快速地生產,那麼我們如何對歷史有一番基本的掌握?柯靈烏將此一問題安置在依康德批判的四個範疇中的「量」 (quantity) 與「關係」 (relation) 來討論。在「量」此一範疇(標題)底下,柯靈烏討論了歷史寫作 (composition) 的形式問題,亦即歷史寫作的最佳形式為何?也就是歷史學中的「普遍性」 (universality) 與「特殊性」 (particularity) 問題。在歷史實踐中,我們所有的是「一個單一普遍的世界史」 (a single universal world-history) 或「一種許多個別的歷史的多元性」 (a plurality of particular histories) ?70 柯靈烏的回答是:依「歷史的理想性」原則,「歷史思想嘗試去解決一個歷史問題,它是特殊的,因為它總是新潁的與不同的問題;但它也是普遍的,因為它在史家的心靈中,是唯一的問題。」

    +

    為了解決在歷史知識中,普遍性與特殊性的問題,柯靈烏引入「史學史」( history of history, 或「第二序的歷史」 , history of the second degree )的概念。71 同時,我們在此可以見到柯靈烏對歷史文本的討論。

    +

    柯靈烏指出,對於任何一個歷史問題的研究,首先須掌握的是這一個問題的歷史。歷史思想自身有其歷史,歷史家必須將歷史思想當作是他的思想對象。我們研究一個歷史問題,不能不檢視過去的歷史家們對此一問題努力的成績。當一個歷史家嘗試去解決一個特別的歷史問題時,他的探究程序總是經由蒐集與批判前人已提供的答案。歷史家總是將前人的研究以歷史地觀點加以看待,將它們自身視為一個歷史現象,表達了特定的態度,並且經由批評他的先驅者而建立其自身的觀點。

    +

    歷史家所進行工作是處理兩種材料:其一,是對一手史料的研究;其二,是研究現代的著作,也就是所謂的文獻目錄 (bibliographies) 。對於一手史料的研究,是為歷史;對於現代著作及追溯其思想之發展,是為史學史。歷史家探究的起始,並非陷入可能無窮盡的史料與所謂的「事實」中,而在於對此一歷史問題的掌握;並且,所謂的「史料」與「事實」也不是給定的,而是獲致的。我們對於歷史問題的掌握與瞭解,則來自於我們對於與此一問題相關的歷史著作與論文的瞭解。歸根結柢,史學史(第二序的歷史)優先於第一序的歷史。72

    +

    歷史家在其研究領域的進展仰賴於他對第二序的歷史的研究。柯靈烏主張,史學史在歷史學科中有其特殊地位,它是歷史學中不可或缺的要素,一切的歷史包含與預設了史學史。柯靈烏再次地重申「一切的歷史都是思想史」 (all history is the history of thought) 的學說,史學史是歷史家對他如何達到它所面對的特殊問題的意識。歷史家的進展在於經由其自身思想的進展解決在其心中所提出的問題。此處的思想即是歷史思想,其自我意識的持續性經由第二序的歷史而保存。

    +

    現在我們舉例來說明史學史研究的實踐。就某一歷史主題而言,先後有四位歷史家甲、乙、丙、丁從事相同歷史主題的研究。在歷史實踐中,歷史家在從事實際研究時,必須參考前人對於同一歷史主題相關的研究著作,這可以說是現代歷史學術成立的條件之一。就時間先後順序上來說,乙歷史家在從事與甲歷史家相同主題的歷史研究時,必須參考他的先驅者,即是甲歷史家在同一主題方面的論著,同時修正其不一致之處。同樣地,後起的歷史家們,如丙、丁在從事相同主題的歷史研究時,同樣必須參考甲、乙歷史家在相同領域的著作。任何一位歷史家在提出其新的觀點時,都須借助於其他歷史家們在相同領域的著作。

    +

    但乙歷史家對於甲歷史家的關於此一歷史主題的陳述,並非如「權威」 (authority) 般,不加以批判地全盤的接受。在此,歷史家必須顯現出他的自主性 (autonomy) 。對所謂的「權威」加以質疑,這是歷史認知的自主性的來源。在歷史家的眼中,所謂的「權威」,不過是歷史思想加以處理、批評的「證據」 (evidence) 而已。從甲歷史家到乙、丙與丁歷史家是一個持續不斷地自我批評的過程,每一個歷史家嘗試在理論上改正並超越其先驅者。在每一個歷史思想向前進展的階段,所做出的研究成果都僅是一份「中間報告」 (interim report) 。

    +

    進一步,史料的不斷更新並不足以否定先前歷史著作的史學價值。柯靈烏以對雅典憲政的研究,來說明歷史事實的不斷更新,不足以否定先前歷史著作的價值。二十世紀,亞理斯多德《雅典憲法》 (Constitution) 的出土,並不足以否定先前歷史家對於雅典憲政所提出具有歷史洞視的看法。

    +

    在這裡,可以發現「史學史」概念與柯靈烏在其《自傳》中所稱,他在一九二八年成形的「壓縮理論」 (incapsulative theory) 間的相似性。73 柯靈烏認為歷史過程是一個思想的過程。歷史家認知是過去的思想在現在重演 (re-enactment) 。歷史過去是活的過去,而非已死的過去。斷言歷史的過去是活的過去,柯靈烏作了如下的說明:假設一事件 P1 為事件 P2 所取代。柯靈烏斷言,事件 P1 並未完全消失、或被完全取代;而是以不同的形式留存於事件 P2 中。同樣地,事件 P3…PN 不斷地取代先前的事件,但事件 P1 、事件 P2 仍以不同的形式變形至新的事件 P3…PN 中。

    +

    這樣的歷史理解正是伽達瑪所說的「效應歷史」 (Wirkungsgeschichte, effective history) 。理解並非是如一面明鏡,單純地映現外在的事物。它總是承載著傳統。一個等待被詮釋的歷史文本或歷史問題總是潛藏在一個特別的歷史傳統中。此一歷史傳統自某一歷史文本被寫定或歷史問題被提出即已形成。這些詮釋構成歷史文本或歷史問題存有的歷史實在。因此,理解一個歷史文本或歷史問題意謂著理解它的效應歷史。74

    +

    此一「史學史」概念,及其所隱含之關於歷史過程的「壓縮理論」與柯靈烏的哲學發展相一致。柯靈烏在早期的著作《心智之鏡》中所謂的「心靈辯證法」75 、一九三二年《哲學方法論》中「等級的重疊」 (overlapping of classes) 理論76 、一九四三年《新巨靈》中的「原始的殘留」 (primitive survival) 理論,77 都與「史學史」概念相符合。蘊含在這些哲學概念背後的,即是觀念論的「具體的共相」。

    +

    至此,對柯靈烏而言,史學史構成了一種新的歷史的普遍性,史學史即是普遍史。每一個歷史研究都是個別的,也是普遍的。它是個別的,因為它是關於某一特定歷史主題及其詮釋;它是普遍的,因為它是歷史家心靈在這個時刻所有的唯一問題,同時它是對所有先前討論此一問題所有著作的評論與總結。換言之,普遍性與一致性存在於歷史家的思想與歷史學科中,是理想地存在;而不再是存在於過去本身。這是梅驥所言「大敘述」的第三層次。

    +

    透過「史學史」概念的引介,柯靈烏討論了在歷史實踐中,歷史文本的地位。在「關係」的範疇之下,柯靈烏進一步討論了歷史文本中的問題,也就是歷史文本中,歷史陳述間的關係。在此,柯靈烏已蘊含了安克史密斯對敘述實體之性質的討論。

    +

    透過「歷史的理想性」原則的引入,柯靈烏修正了「專論」 (monograph) 的概念,來說明一個歷史文本的構成。一個歷史文本,亦即是一篇專論,包含了歷史的整體性,或者,究竟地說,歷史的整體性濃縮進一篇專論之中。因此,歷史的整體性成了從某一特別的觀點觀看的世界史。歷史文本,亦即是歷史專論,提供了一個個別的觀點。

    +

    歷史敘述的實體不是一個單一的敘述,或是一系列的事件,而必須以相同的方式同時地經驗。似乎是編年式的序列,必須在史家的思想中認知為共時的整體。歷史理解即是由一個特定的觀點以共時地理解。78

    +

    每一篇論文同時具有其統一性與多元性:

    + +
    +

    就統一性言,它是一個單一的敘述,以藝術地與邏輯地連結而成一個整體。主觀上,它是一篇論文,是關於一個「主題」 (subject) ;客觀上,它是關於某物。就多元性言,它包含了一系列陳述 (statements) 作為某物之述語 (predicates) 。79

    +
    + +

    「某物」,即是一個歷史事件,它是歷史專論的主題,它是包含在歷史敘述中所有陳述的邏輯主體,諸如「法國大革命」之類。此一邏輯主體擁有許多不同的層面,每一層面自身皆是一個事件。撰寫某一特定的歷史主題,即是去列舉它所組成的事件。因此,歷史專論作為一個整體是所有部分的總和,每一個部分都對整體有所獻替,整體是部分所組織的系統。整體必須先於部分;反之,則不成立。我們在此可以看見觀念論的「具體的共相」、「多樣性中的同一性」邏輯的運作,也就是歷史經驗與歷史寫作的規範性原則─「個體性」原則。

    +

    但柯靈烏的「普遍史」觀念仍殘存了形上學的信仰。80 對柯靈烏而言,史學史或歷史著作間的一致性,來自於將歷史視做為一個過程的形上學信仰。柯靈烏認為現在與過去間是密切相關的。過去經由歷史思想活在現在的歷史家的思想中。柯靈烏接受歷史主義對於歷史連續性的基本假定,儘管他放棄了歷史主義線性敘述所隱含的目的論思想。

    +

    因此,在我們更新歷史主義的「個體性」原則的系譜學討論中,最終將引入安克史密斯的「敘述實體」。

    + +

    安可史密斯:「敘述實體」

    + +

    安可史密斯是近年來歷史哲學界新起的敘述主義的代表。他的歷史理論也代表了後現代主義中「去本質化」 (anti-essentialistic) 與「美學主義」 (aestheticism)81 的傾向。安可史密斯的「敘述實體」同時反應了這二項特質。82 同時,安可史密斯也提出了一套關於西方史學史發展的敘述,並且意圖將他的歷史理論接合啟蒙史學、歷史主義與後現代主義史學的發展。83 安可史密斯試圖以歷史主義的核心觀念─「歷史觀念」或「歷史形式」 (historical form) ─即「個體性」與他敘述主義歷史學的理論核心─「敘述實體」相接合。84 根據安可史密斯,去本質化後的歷史主義的「歷史觀念」,便成了敘述主義的「敘述實體」。安可史密斯指出歷史主義的學說如進步 (progress) 、連續性 (continuity) 等形上學信仰如今已失去其基礎;但歷史主義的核心觀念─「歷史觀念」,在歷史實際中,仍有其存在價值。安可史密斯意圖更新歷史主義的學說。對安可史密斯而言,任何歷史寫作者就某種意義言,都是歷史主義者 (historicists) 。

    +

    安可史密斯的歷史理論的優點,在於他以一個簡單的事實出發:即歷史學實踐的現況。與柯靈烏一般,安可史密斯的歷史理論同樣從史家的實踐活動出發,即現今歷史職業中過度生產的現象,如何對歷史獲致一個全然的瞭解成為史家關心的問題。在〈歷史學與後現代主義〉中,安可史密斯從一個簡單的事實,即是歷史學過度生產的現狀,來反省歷史寫作的性質。面對歷史學專業化後歷史作品過度生產的現狀,安可史密斯認為,即便是我們要對關於一個歷史問題的重要著作做全面的概觀便十分困難,何況是永無止境的事實歸屬更加困難。歷史職業的現狀是一個片段化,缺乏一致性的現象;在《敘述邏輯》中,安可史密斯批評傳統歷史哲學,如「覆蓋律」模式 (covering-law model, CLM) 等,沒有考慮到歷史學的一的重要問題,即是敘述地詮釋。「一個歷史著作的史學價值不在於它所揭露的事實,而是對這些事實的敘述詮釋。」85

    +

    安可史密斯將歷史家們的歷史作品與著作稱為「歷史敘述」 (narratio) 。所謂的「歷史敘述」,包含了一切敘述性與非敘述性的文本。安可史密斯認為,即使是最不具故事性、敘述性的,而擅長與著重於結構分析的歷史作品,如赫伊津哈的《中世紀之秋》86 或布勞代爾 (Fernand Braudel) 的《地中海與菲力二世時代的地中海世界》87 也與敘述哲學相關聯。因為敘述哲學所處理的是一些我們在討論過去時所使用的語言實體 (linguistic entities) 之邏輯性質,而非描述一個國家或思想運動在時間中的發展。這些語言實體,安可史密斯將之稱為「敘述實體」,亦即「歷史詮釋」 (historical interpretation) 的同義詞。

    +

    同時,安可史密斯也依違於實在論與觀念論的爭執。安可史密斯捍衛了敘述觀念論的主張,認為一個歷史敘述不等於,或者是大於其個別陳述之總和的說法。同時歷史敘述並不符應於一個外在於敘述自身的實在,它是出於歷史家的建構。他也否定敘述實在論的觀點,即認為歷史敘述符應 (correspond to) 於一個外在於歷史敘述的實在,與一個歷史敘述等於它所包含的關於它自身的陳述之總和的說法。安可史密斯否認過去的實在性。在歷史實踐中,史家所處理的對象不是過去實在自身。安可史密斯認同萊布尼茲的命題理論─「主語中的述語」原則 (peaedictum inest subjecto)88 :述語 (predicates) 總是被包含在命題的主語 (subjects) 之中。歷史敘述應盡可能地除去關係述語 (relational predicates) ,歷史敘述解釋歷史事物並不需要通過外在於歷史敘述的實在而達成。安可史密斯因此而避免了十九世紀歷史主義對歷史實在的信仰。因此,安可史密斯堅稱,敘述邏輯含有強烈的萊布尼茲式的性格。安可史密斯將此一「主語中的述語」原則,從萊布尼茲的命題理論的層次提升到歷史敘述的層次。

    +

    如同華雪一般,安可史密斯注意到在歷史實踐中,歷來的歷史家經常使用一些支配性的操作概念,如「文藝復興」、「啟蒙運動」、「工業革命」,或如赫伊津哈在《中世紀之秋》中,將十四、五世紀(一般所熟知的「文藝復興」)視為一個時代的結束,而非另一個時代的開端,中世紀逐漸走入它的秋天、或者當我們說道:「十七世紀是一個危機時代」……等;安可史密斯將這些操作性的概念統稱為「敘述實體」( narrative substance, 簡稱 Ns, 複數形 narrative substances, 簡稱 Nss )。安可史密斯堅持「敘述實體」是一個敘述主義的概念。安可史密斯自承,他的「敘述實體」觀念來自華雪的「總括」概念;但他反對華雪「總括」概念所蘊函的本質概念,因為「總括」某物,隱含了指涉實在界。同時,他也反對以對過去的圖像 (picture) 或形象 (image) 來稱呼,這同樣有本質論的危險。「敘述實體」一詞,是歷史詮釋的同義詞、是對過去的一個論題 (a thesis on the past) 、是提供觀看過去,而使過去可以被理解的一個特定觀點 (a point of view) 。89

    +

    安可史密斯指出,敘述實體是一套陳述句,而分享了如「狗」或「桌子」這些事物能夠在陳述句中被言說的屬性,而沒有成為這些陳述句自身的一部分。安可史密斯分析吾人日常的生活語言與歷史實踐中所使用的語詞之不同。在歷史敘述中,一個陳述句有雙重功能:第一,一個陳述句可以指涉過去的事物,即過去實在本身,這是如敘述實在論者所主張的;第二,歷史敘述中的陳述句,可以被視為此一歷史敘述的組成部分,它們是一個關於過去的「圖像」或「形象」,這是如敘述觀念論者所主張的。以一個陳述句的句法結構來說,我們可以說,它同時是一個陳述句的主語與述語。

    +

    安可史密斯主張,我們應該將陳述句中的述語當作是敘述實體的性質;將陳述句中的主語當作敘述實體名稱的屬性。以符號來表示,前者如「 N1 包含 p 」、「 N1 包含 q 」,其中, p 或 q 是 N1 的性質;後者如「 N1 是 P 」、「 N1 是 Q 」,其中, P 、 Q 是 N1 的屬性。因此, p 、 q 或 P 、 Q 都是「敘述實體」 N1 的性質或屬性,主語與述語是沒有區別的。安可史密斯要求應有一個邏輯的第三實體 (third entity) ,以區別於主語與述語兩個邏輯實體。此一第三邏輯實體即是「敘述實體。」90

    +

    安可史密斯進一步區分所謂「敘述主體」 (narrative subjects) 與「敘述實體」。敘述主體是從傳統討論命題性質的理論所認知之主體,它僅僅是一系列關於某一歷史敘述之陳述句的總和。敘述實體,正如我們前面所示,並非關於某一歷史敘述之陳述句的總和。同時,正如萊布尼茲的「單子」 (monads) 一般,它們所包含的陳述句並不是他們構成的一部分,而是它們的屬性。因此,在歷史敘述中,所有陳述都只是分析地真實。但個別事實的添改,並無法改變敘述實體的性質。因為,在萊布尼茲與敘述主義的邏輯中,一個陳述的主語比述語佔有更顯著的地位。述語的完全列舉僅僅是說明主語中原已具有的成分。透過述語之完全列舉的程序,無法為歷史敘述帶來認為新的成分。

    +

    安可史密斯主張,我們可以藉由對某一敘述實體所包含的陳述之完全列舉,而識別此一歷史敘述中所含的敘述實體。舉例而言,根據敘述主義對歷史敘述的詮釋,所有相關的陳述,如 p 、 q 、 r 等,可以被閱讀為「 N1 是 p 」、「 N1 是 q 」、「 N1 是 r 」,經由以上的程序敘述實體 N1 可以被個體化。

    +

    安可史密斯以昆汀‧史金納 (Quentin Skinner) 的《現代政治思想的基礎》91 為例,來說明「文藝復興政治思想」 (Renaissance Political Thought) 作為一個「敘述實體」。他顯示,如果我們將「文藝復興政治思想」視為一個敘述實體,我們可以依「 N1 是 p 」、「 N1 是 q 」的方式,清楚無誤地列舉指出「文藝復興政治思想」的性質,諸如,「自由的修辭防衛」 (the rhetorical defence of liberty) 、「德性概念」 (the concept of virtus) 、「人文主義與國家理性」 (Humanism and "reason of state") 等對「文藝復興政治思想」的陳述。92

    +

    在現代中國史學中,類似「敘述實體」的理論概念也為歷史家們所使用。例如,陳寅恪所提出的「關中本位政策」,廣為史家們所熟知。陳寅恪探討中國中古政治史的演變,而提出「關中本位政策」的理論架構。93 有關「關中本位政策」,陳寅恪最明確的定義如下:

    + +
    +

    李唐皇室者唐代三百年統治之中心也,自高祖、太宗創業至高宗統御之前期,其將相文武大臣大抵承西魏、北周及隋以來之世業,即宇文泰「關中本位政策」下所結集團體之後裔也。94

    +
    + +

    + +
    +

    有唐三百年間其統治階級之變遷升降,即是宇文泰「關中本位政策」鳩合集團之興衰及其分化。95

    +
    + +

    「關中本位政策」作為一個敘述實體,是陳寅恪是經由對中國中古歷史發展的理解,從文獻脈絡中提煉而出的理論概念。96 正如昆汀‧史金納講述「文藝復興政治思想」一般,我們亦可就陳寅恪的「關中本位政策」作為一個敘述實體,作如下的分析:我們可以列舉出「關隴集團」、「府兵制」、「關中文化本位政策」……等性質。

    +

    安可史密斯接受了萊布尼茲單子論關於單子 (monads) 和諧地構成宇宙的論題,將之運用到敘述主義的敘述實體理論中,而為所謂「敘述宇宙和諧地構成」。如同萊布尼茲的單子構成自然宇宙一般;敘述實體,即關於敘述實體之陳述或兩個不可比較的敘述實體間,共同構成一個「敘述宇宙」 (narrative universe) 。根據萊布尼茲對自然宇宙的描述,所有單子以「前定和諧」地 (pre-determinedly harmony) 存在;同樣地,敘述實體同樣預設了一個和諧的敘述宇宙。因此,儘管關於敘述實體的陳述,或不同的敘述實體是分析地真實的,它們並不會出相相互矛盾的現象,而構成一個和諧地敘述宇宙。這裡我們可以發現萊布尼茲「觀念中的述語原則」 (predicates in notion principle) ,即述語是意義的一部份,或是主語完全觀念 ("complete notion" of the subject-term) 的一部份;或是觀念論整體先於部分的概念。

    +

    每一個敘述實體都含有歷史研究 (historical research) 的成分,同時,每一個敘述實體所關心的特定歷史主題都包含了長久的歷史傳統。在歷史討論中,同一專業領域的歷史家們所討論的即是諸多「敘述實體」的性質,或提出特殊的論題,而非過去實在自身,也非這些敘述實體是如何產生的。同時,每一個敘述實體都保留了與其他歷史家們共同討論的空間。我們發現:歷史家在撰寫一本歷史著作或一篇論文時,他所做的是提供一個既存的敘述實體之個例 (individuate one of those "already-existing" Nss) ;而某一本歷史著作的讀者在閱讀該歷史著作時,他所做的是在辨別一個既存的敘述實體。從這個觀點看,寫作與閱讀是相同的行為。在從事寫作與閱讀歷史敘述的行為時,某一特定的敘述實體被個體化。此一個體化的過程可以解讀為兩種形式:其一,是此一敘述實體被撰寫出來;其二,是閱讀已被寫作出的敘述實體。在此,歷史學做為一個詮釋的社群之性質完全彰顯。寫作或閱讀歷史著作不是一項孤立的行為,而是參與了歷史文本意義的生產過程。因此,「敘述實體」具有強烈的互為文本性質。

    +

    最後,讓我們進入敘述實體的做為「變化主體」 (subject of change) 的討論。所謂的「變化主體」,即假定在時間的過程中,歷史個體所具有的「個體性」,如何能夠在多樣變化的現象中,維持其同一性。在西方史學的發展中,歷史主義最能掌握個體在時間中的變化 (change in time) ;但歷史主義的變化主體是一形上學的主體,敘述主義,或究竟地說,敘述實體的變化主體是一「去本質化」的主體,亦即敘述主義的主體。安可史密斯繼承了歷史主義對變化主體的討論,但他意圖以敘述主義的敘述實體概念去更新歷史主義的內涵,那就是一個去本質化的個體性。

    +

    就西洋史學史本身的發展來看,「敘述實體」承襲了啟蒙運動史學與歷史主義的核心概念,即「實體」 (substance) 與「歷史觀念」。安可史密斯意圖證成:歷史主義的核心概念「歷史觀念」是啟蒙史學的實體概念動力化的結果;而「敘述實體」則是歷史主義「歷史觀念」的「去本質化」與「徹底化」 (radicalization) 。安可史密斯的理論符合了後現代主義敘述史學的「反本質論」的趨向。同時也符合了自蘭克到布克哈特以來,歷史思想從歷時性的思維到共時性的思維的轉變。97

    +

    在〈歷史主義:一個綜合的嘗試〉一文中,安可史密斯試圖綜合啟蒙史學、歷史主義與敘述主義。他並從史學史的角度,說明一個時常被忽略的事實,即啟蒙運動、歷史主義與敘述主義的關聯性。根據對歷史主義的詮釋傳統,此一傳統將歷史主義與啟蒙運動對立起來,視歷史主義的歷史化與個體性觀點是對啟蒙運動自然法理論普遍性觀點的直截地否認。正如邁乃克所言:歷史主義是以個體化的觀點取代對人性的普遍觀點。98 但根據安可史密斯,歷史主義的「歷史觀念」是啟蒙運動實體概念動力化的結果,而敘述主義的「敘述實體」更是歷史主義「歷史觀念」的去本質化。敘述主義之敘述實體解消歷史主義的個體性中所隱含的形上學思維;敘述實體做為對變化主體之論述,將個體性觀念由形上學實體轉變為語言實體。

    +

    歷史主義強調「發展」原則,這是啟蒙運動實體概念動力化的結果。因此,歷史主義隱含了線性 (linear) 、目的論式的歷時性思維。但當蘭克說道:「每一個時代直接親睹上帝」 (every epoch immediately to God) 時,歷史主義的另一重要原則「個體性」,隱含了共時性的思維。同時,歷史主義線性的目的論式敘述所隱含的進步觀念,亦即現代性的思考蘊涵了一種特定的時間的經驗模式,即空間範疇凌駕了時間範疇,時間被割裂成一個個互不聯繫的空間單位,不再是連貫一致的統一體。99 這是所有後現代主義時間思維的來源。歷史主義從蘭克到布克哈特的發展,正代表了歷時性思維到共時性思維的轉變,而布克哈特也被認為是後現代主義歷史思維的原型。100 布克哈特的經典《義大利文藝復興的文化》代表了此一共時性思維的趨向,同時也是一最佳的「敘述實體」範本。101

    +

    柯靈烏與安可史密斯的理論分別代表了現代主義史學與後現代主義史學回應歷史知識片斷化的問題。他們的理論不僅提供我們思考歷史學的一致性問題,同時也給與台灣的西洋史研究指出一條新路。

    + +

    + +

    與西方自十九世紀以來,史學專業化後所產生的過度生產現象不同,我們可以說:台灣西洋史歷史職業現在所面臨的處境,不在過度生產;而在生產不足。那麼柯靈烏的「史學史」與安可史密斯的「敘述實體」觀念是否適用於西洋史的研究?進一步,安可史密斯的「敘述實體」概念中仍存留著康德先驗論的色彩,如何能與後現代主義「反本質論」與多元的聲音相合?

    +

    面對歷史職業過度生產的現狀,一個判準學 (criteriology) 的問題將被提出:在相互競爭的歷史文本或歷史敘述中,何者是較佳的敘述?安可史密斯的回答是:在兩個相互競爭的歷史敘述中,吾人總是較喜愛最具危險性的 (risk) 與具啟發性的歷史敘述。102

    +

    後結構主義對「互為文本性」的討論,有助於我們來檢視此一問題,即為何我們要作「史學史」或「敘述實體」的研究。羅蘭‧巴特 (Roland Barthes) 首先提出了「互為文本性」這個名詞。根據巴特,寫作或閱讀文本不是孤立的行為,一個特定的文本是其他版本文本的「再碼」 (recoded) 或「轉碼」 (transcoded) 。我們可以在更早先的文本中見到它的前身,而這將陷入一個無限倒退的過程。因此,「參照」 (reference) 將變成「互為文本的」,起源解消,個別的文本因此消失。在歷史實踐中,這將導致一些後果:其一,「第一手史料」或「原始檔案」將失去其優先的地位,因為根據「互為文本性」,各個所謂「史料」、「檔案」都是其他前在文本的衍生物,在歷史研究中,不再具有權威的性質。其二,歷史研究成為研究各個歷史文本間的差異所在,而非對史料或原始檔案的蒐集與考證。歷史文本既為互相參照的,歷史研究在於研究意義如何以互為文本的方式被生產出來。其三,較佳的歷史文本是那些具有啟發性的、與能夠引發我們新穎的歷史洞察力的文本。這將引領我們回到安可史密斯的問題及其所賦予的解答:在相互競爭的歷史文本或歷史敘述中,為何吾人總是較喜愛最具危險性的與具啟發性的歷史敘述?巴特等人的觀點對我們仍然具有啟發性。

    +

    巴特區別了「閱讀性文本」 (readerly texts, lisible) 與「寫作性文本」 (writerly texts, scriptible) 。103 根據巴特,所謂「閱讀性文本」,意指文本中包含了可接受的閱讀與詮釋的約定,因為我們知道如何由約定所告知我們的閱讀策略被動地閱讀這些文本,發現其精確的意義;而「寫作性文本」,挑戰了所有閱讀文本的約定,閱讀文本時,讀者必須進入文本中,主動地參與意義的製作。因此,「寫作性文本」強迫讀者在閱讀一篇文本時,在心中寫作一個另類的 (alternative) 或虛擬 (virtual) 的文本。

    +

    拉卡普拉 (Dominic LaCapra) 同樣以「複合作品」 (complex works) 與「文獻」 (documents) 來指稱與巴特的「寫作性文本」、「閱讀性文本」相類似的文本性質。巴特的「寫作性文本」也類似克莫德 (Frank Kermode) 所定義的「正典文本」 (canonical texts) 。「正典」作品具有多重面向的意義,能夠產生豐富的意義與更多的詮釋;它引發看待古老事物的新方式,並提供前所未見的新事物。

    +

    從以上對互為文本性的討論,「寫作性文本」、「複合作品」與「正典文本」都都根植於文本的詮釋傳統中,它們具有多重而非單一面向的意義,足以引發新穎的歷史觀點,提供更多的歷史詮釋。因此,歷史職業中過度生產與不斷地再生產的現象,並不妨礙我們對歷史獲得客觀的理解,它能創造出更多、更新穎的歷史詮釋觀點。因此,在歷史詮釋社群中,「客觀性」與「主觀性」的問題將喪失其意義。一個詮釋社群不是客觀的,因為它總是帶有特殊的認知旨趣、利益與目的,它總是從特殊的興趣出發,而非中立的;同時,一個詮釋社群所生產的意義與文本也非主觀的,因為它們不是來自於孤立的個體,而是從公共的與習俗的觀點產生的。104

    +

    最後,我們所面臨的是一個去中心化 (de-centralized) 、而多元的 (plural) 後現代世界。安可史密斯的敘述實體概念中,隱含了康德先驗論的架構;而在面對歷史文本時,安可史密斯主張權威性的「正典文本」,即越具啟發性與危險觀點的文本,是歷史家閱讀的對象。安可史密斯的觀點需要進一步的改正。

    +

    面對歷史職業在二十世紀所呈現的無限的複雜性,與歷史論述的多樣性。近來,歷史學家與文學評論家企圖以古典演辯術 (dialectics) 與修辭學 (rhetoric) 中的「主題」 (topics, topos, topoi, lines of argument; locus, loci, places of argument) 概念,來重新定義歷史職業與詮釋社群的「客觀性」問題。105 南茜‧史都佛 (Nancy Struever) 將歷史視為是一項制度 (an institution) 、一門學科 (a discipline) ,而歷史學科的特性即是論證 (argument) 。如果以修辭學的模式來描述歷史論述性質,那麼以「主題」概念來說明歷史學的性質是十分恰切的。因為,「主題」概念是關於歷史家如何論證的。因此,歷史做為一門學科的性質在於它是一門論證的學科。

    +

    所謂的「主題」論證,是將我們在討論任何特定的問題時所可能出現的考量列舉出。將此概念放置入歷史實踐中,歷史客觀性的來源,不再是對某一事件作最終的定論,亦即,對於待所有史料出現,與對之做徹底的研究後,我們將獲致一個完整的歷史的信仰;而是歷史社群對於特定歷史主題的持續討論。在歷史討論中,歷史家所爭論的不是所謂的「定論歷史」,「為反對詮釋學取向強調敘述文本作為詮釋過去的事件,修辭學強調在論爭中敘述所包含的論證需求。」106 因此,從修辭學的觀點,歷史學不是過去事實的再現,而是一個說服 (persuasion) 的過程,它存在於演說者與聽眾,亦即作者與讀者的相互關係中。歷史的客觀性不因此而被破壞。

    +

    史都佛繼續論證道:主題概念最重要的特性,即是他對共同人性的籲求 (appeal to a common humanity) 。正如亞里斯多德所宣稱的,主題概念讓我們能夠從普遍被接受的意見中,去討論對我們所提出的每一個問題。主題概念根植於公共論述 (civil discourse) ,起源於可駁斥的意見 (reputable opinion) 中。因此,主題概念所籲求的客觀性存在於所謂「共同的人性」,亦即公共所關心的主題中、以及在說服的過程中,演說者所運用的修辭策略與規則。歷史職業的多元化、歷史文本的過度生產與歷史知識的片段化並不足以妨礙我們對歷史客觀性的尋求。透過主題概念的引介,我們了解在歷史爭論中,歷史家所關心的是共同的主題,這些主題都指向共同的人性,其本身便是客觀的存在;進一步,在爭論與說服的過程中,參與者都必須遵守共同的修辭策略 (strategies) 與規則 (rules) ,亦即歷史家們必須遵守歷史學科本身所具有的方法規則。

    +

    梅驥同樣意圖以「主題」概念來整合歷史職業專業化後所引起的片段化問題。如先前討論「大敘述」理想型所示,梅驥檢討了西方史學傳統中「大敘述」觀念的演變,歷史職業的現狀是一個多樣的、片段的狀況,任何宣稱獲得對歷史的單一整體的看法都被質疑、站不住腳。我們既無法獲得歷史在本質層次的統一性,因為歷史家在撰寫他的著作時受到他自身社會及其在社會中位置的影響,不同的群體認同對何者為重要的歷史有不同的理解。我們亦無法在方法的抽象層次獲得統一性,不同的關懷領域需要運用不同的方法。

    +

    梅驥同樣在修辭學的「主題」概念中獲得解決片段化的洞視。同時,梅驥修正余琛 (Jorn Rusen) 的「學科範式」 (disciplinary matrices) 理論,他認為余琛的理論特別適合「主題」概念。107 這些「學科範式」提供了創造論證的策略,這是可以經由方法學加以驗證的。歷史職業所從事的是不斷的主題化,同行的歷史家必須不斷地從事於相同主題的研究與討論。

    +

    面對台灣西洋史研究所呈現的生產不足現象,提倡史學史或敘述實體的研究,即是讓西洋史工作者進入歷史職業的詮釋社群中。透過歷史文本的互為文本性質,西洋史工作者從有限的研究成果與西方專業史家的歷史著作中,仍可獲得對西洋史的理解。台灣西洋史研究者所應從事的基本研究,並不是以有涯隨無涯地,亦即是陷入無窮境的史料蒐集、史實的編纂;而是尋出一個有效地理解西洋史的方法。我們在〈發刊辭〉中呼籲:台灣的西洋史學界應能掌握諸如「文藝復興」、「十七世紀的普遍危機」、「法國大革命」……等西洋史中重要的問題,其理論的基點即是柯靈烏的「史學史」與安可史密斯的「敘述實體」觀念。我們認為,西洋史工作者研究工作的起步,應是對他的專業範圍內當代史家同行的著作做全面性的瞭解。

    + + + +
    + 回目錄 | + 下一篇 +
    + +
    + +
    +
    * 本文曾以〈台灣的西洋史研究:《歷史:理論與文化》一九九八宣言〉為題,於一九九八年九月二十四日「何謂歷史學─歷史學作為歷史理論」研討會第二次會中宣讀,今稍作修改,謹此說明。 (Back)
    +
      +
    1. 相關的討論有黃俊傑,〈關於西洋史研究與教學的幾點考慮─一個史學工作者的反省〉,《史學評論》 3 ( 1981, 3 ),頁 117-132; 邢義田,〈「世界史」抑中國文化立場的「西洋史」?〉,《史學評論》 3 ( 1981, 3 ),頁 133-147; 楊肅獻,〈台灣的西洋史研究, 1950-1995 〉,《台大歷史學報》 21 ( 1995, 12 ),頁 322-38 。 (Back)
    2. +
    3. 關於「危機」,最近的討論, cf. Reinhart Koselleck, "Remarks in the History of the Concept of Crisis," in The Ancients and the Moderns, ed. Reginald Lilly (Bloomington: Indiana University Press, 1996), 148-58; Charles R. Bambach, Heidegger, Dilthey, and the Crisis of Historicism (Ithaca: Cornell University Press, 1995), 6-7, 47-49; Harry Ritter, "Crisis," in Dictionary of Concepts in History (Westport, Conn.: Greenwood Press, 1986), 79-84. (Back)
    4. +
    5. 杜正勝,〈鄉土史與歷史意識的建立〉,《中央圖書館台灣分館館刊》 3: 4 (1997) ,頁 1-9; 杜正勝,〈一個新史觀的誕生〉,《當代》 120 (1997, 8) ,頁 20-31. (Back)
    6. +
    7. 吳密察,〈歷史教育與鄉土史教育〉,《當代》 120 (1997, 8) ,頁 35 。 (Back)
    8. +
    9. 鄧世安,〈西洋史教學問題之探討──以羅馬共和之蛻變為例〉,「西洋史與國別史課程教學研討會」(台北:輔仁大學歷史學系, 1997 ),頁 11 。 (Back)
    10. +
    11. 西洋現代史學中對起源偶像批判,最有力的是「年鑑學派」 (the Annales School) 的創始者布洛克, cf. Marc Bloch, The Historian's Craft (Manchester: Manchester University Press, 1992), 24-36; 布洛克歷史溯源方法論的運用 , see Bloch, The French Rural History: An Essay on Its Basic Characteristics (Berkeley: The University of California Press, 1966), introduction. (Back)
    12. +
    13. Firedrich Nietzsche, "On the Uses and Disadvantages of History for Life," Untimely Meditations, tr. R. J. Hollingdale (Cambridge: Cambridge University Press, 1997), 57-123; Hayden White, "The Burden of History," in Tropics of Discourse: Essays in Cultural Criticism (Baltimore: The Johns Hopkins University Press, 1978), 27-50. (Back)
    14. +
    15. R. G. Collingwood, The Idea of History, ed. W. J. Van der Dussen, rev. ed. (Oxford: Clarendon Press, 1993), 233. (Back)
    16. +
    17. Cf. Hayden White, Metahistory: The Historical Imagination of Nineteenth-Century Europe (Baltimore: The Johns Hopkins University Press, 1973), 7-11. (Back)
    18. +
    19. Collingwood, The Idea of History, 451. (Back)
    20. +
    21. 鄧世安,〈西洋史教學問題之探討─以羅馬共和之蛻變為例〉,頁 14 。 (Back)
    22. +
    23. Cf. Bambach, Heidegger, Dilthey, and the Crisis of Historicism; Richard J. Bernstein, Beyond Objectivism and Relativism: Science, Hermeneutics, and Praxis (Philadelphia: University of Pennsylvania Press), 16-20, 34-37. (Back)
    24. +
    25. F. R. Ankersmit, "Historism and Postmodernism: A Phenomenology of Historical Experience," in History and Tropology: The Rise and Fall of Metaphor (Berkeley: The University of California Press, 1993), 200-201. (Back)
    26. +
    27. Ankersmit, "Historiography and Postmodernism," History and Tropology, 180. (Back)
    28. +
    29. Georg G. Iggers, Historiography in the Twentieth Century: From Scientific Objectivity to the Postmodern Challenge (Hanover: Wesleyan University Press, 1997), 116; Ankersmit, "Historicism: An Attempt at Synthesis," History and Theory 34: 3 (Oct. 1995): 159. (Back)
    30. +
    31. 〈發刊辭〉,《歷史:理論與文化》,創刊號 (1998, 7) (詳見文後附錄)。 (Back)
    32. +
    33. Unkindly criticism on Ankersmit's "narrative substance," see C. Behan McCullagh, Review of Narrative Logic: A Semantic Analysis of the Historian's Language, by F. R. Ankersmit, History and Theory 23: 4 (Dec. 1984): 394-403; 關於安可史密斯的後現代主義歷史學, see John H. Zammito, "Ankersmit's Postmodernist Historiography: The Hyperbole of 'Opacity'," History and Theory 37: 3 (Oct. 1998): 330-346; 在中文方面最新的研究,請見黃明田,〈安克史密斯的敘述歷史學〉(台北:輔仁大學歷史學研究所碩士論文, 1999 )。 (Back)
    34. +
    35. 在此,我所使用的是邁乃克對歷史主義的定義。邁乃克定義歷史主義的兩大原則,是「發展」 (development) 與「個體性」 (individuality) , Friedrich Meinecke, Historism: The Rise of an Historical Outlook, tr. J. E. Anderson (London: Herder and Herder, 1972), lv-lvii. (Back)
    36. +
    37. Stanley Fish, Is There a Text in This Class? The Authority of Interpretive Communities (Cambridge, Mass.: Harvard University Press, 1980), 14-16, 167-173. (Back)
    38. +
    39. Georg G. Iggers, "The Idealist Theory of Historiography: Wilhelm von Humboldt's Classical Formulation," in The Theory and Practice of History by Leopold von Ranke, eds. Georg G. Iggers and Konrad von Moltke (Indianapolis: The Bobbs-Merrill Company, Inc., 1973), 3. (Back)
    40. +
    41. Georg G. Iggers, The German Conception of History: The National Tradition of Historical Thought from Herder to the Present, rev. ed. (Middletown, Conn.: Wesleyan University Press, 1983), 58. (Back)
    42. +
    43. Wilhelm von Humboldt, "On the Historian's Task," in The Theory and Practice of History by Leopold von Ranke, 7. (Back)
    44. +
    45. 伊格斯 (Georg G. Iggers) 認為,對文獻的批判研究與對事實精確性的強調,並非十九世紀日爾曼歷史主義的特殊成就及其特色。實際上前一代的歷史家、語言學家、古典學者與聖經學者已發展出這些方法。同時,就地域上言,也不限於日爾曼地區, see Iggers, The German Conception of History, 1, 29. (Back)
    46. +
    47. Humboldt, "On the Historian's Task," The Theory and Practice of History by Leopold von Ranke, 22. (Back)
    48. +
    49. McCullagh, Review of Narrative Logic, 394. (Back)
    50. +
    51. Johan Huizinga, "The Task of Cultural History," Men and Ideas: History, the Middle Ages, the Renaissance, tr. James S. Holmes and Hans van Marle (Princeton: Princeton University Press, 1984), 51-53; 關於赫伊津哈的史學,請參見張淑勤,〈文化史家 Huizinga ( 1872-1945 )的史學〉,《史學與文獻(二)》,東吳大學歷史學系主編(台北:學生, 1998 ),頁 251-271 。 (Back)
    52. +
    53. Huizinga, "The Task of Cultural History," Men and Ideas, 53. (Back)
    54. +
    55. Huizinga, "The Task of Cultural History," Men and Ideas, 58. (Back)
    56. +
    57. Lionel Rubinoff, Introduction to The Presuppositions of Critical History, by F. H. Bradley, ed. Lionel Rubinoff (Chicago: Quadrangle Books, 1968), 1; David Boucher, "The Creation of the Past: British Idealism and Michael Oakeshott's Philosophy of History," History and Theory 23 (1989): 193-214. (Back)
    58. +
    59. 關於「歷史建構論」,請見 Jack W. Meiland, Scepticism and Historical Knowledge (New York: Random House, 1965); Leon J. Goldstein, Historical Knowing (Austin: University of Texas Press, 1976). (Back)
    60. +
    61. Michael Oakeshott, Experience and Its Modes (Cambridge: Cambridge University Press, 1933), 99. (Back)
    62. +
    63. Oakeshott, Experience and Its Modes, 107. (Back)
    64. +
    65. Oakeshott, Experience and Its Modes, 98. (Back)
    66. +
    67. Oakeshott, Experience and Its Modes, 97. (Back)
    68. +
    69. Oakeshott, Experience and Its Modes, 119. (Back)
    70. +
    71. Oakeshott, On History and the Other Essays, 112-13. (Back)
    72. +
    73. Oakeshott, Experience and Its Modes, 120. (Back)
    74. +
    75. Oakeshott, Experience and Its Modes, 123. (Back)
    76. +
    77. Oakeshott, Experience and Its Modes, 124. (Back)
    78. +
    79. Carl G. Hempel, "The Function of General Laws in History," in Theories of History, ed. Patrick Gardiner (Glencoe, Ill.: Fress Press, 1959), 344-56; 有關韓培爾歷史解釋的「覆蓋律」模式,請見黃進興,〈歷史解釋和通則的關係:韓培爾 (Hempel) 觀點之檢討〉,《歷史主義與歷史理論》(台北:允晨, 1992 ),頁 135-57 。 (Back)
    80. +
    81. C. Behan McCullagh, "Colligation and Classification in History," History and Theory 23 (1981): 267-284 ;對華雪「總括」概念之相關討論,請見 C. B. Cebic, "Colligation and the Writing of History," Monist 53 (1969): 140-57; W. H. Dray, "Colligation under Appropriate Conceptions," in Substance and Form in History: A Collections of Essays in the Philosophy of History, eds. Leon Pompa and W. H. Dray (Edinburgh: University of Edinburgh Press, 1981), 156-70. (Back)
    82. +
    83. W. H. Walsh, "Colligatory Concepts in History," in The Philosophy of History, ed. Patrick Gardiner (Oxford: Oxford University Press, 1974), 133. (Back)
    84. +
    85. 在一九六七年的論文〈歷史學中的總括概念〉一文中,華雪放棄了「歷史解釋」,而改用「歷史詮釋」 (historical interpretation) 一詞, see Walsh, "Colligatory Concepts in History," The Philosophy of History, 136. (Back)
    86. +
    87. Walsh, An Introduction to Philosophy of History (Bristol: Thoemmes Press, 1992), 23-24, 59-64. (Back)
    88. +
    89. 對惠格史學的批判, see Oakeshott, Experience and Its Modes, 101-111; idem., "The Activity of Being an Historian," in Rationalism in Politics and Other Essays (Indianapolis: Liberty Press, 1991), 151-183; idem., On History and the Other Essays (Oxford: Basil Blackwell, 1983); Herbert Butterfield, The Whig Interpretation of History (New York: W. W. Norton, 1965); P. B. M. Blaas, Continuity and Anachronism: Parliamentary and Constitutional Development in Whig Historiography and in the Anti-Whig Reaction between 1890 and 1930 (The Hague: Martinus Nijhoff, 1978), introduction. (Back)
    90. +
    91. Walsh, "Colligatory Concepts in History," The Philosophy of History, 138. (Back)
    92. +
    93. 在此,我們可以看到麥可克雷夫以「分類」概念對「總括」概念的解說與安可史密斯認為歷史爭論在於討論「敘述實體」性質的概念之相近之處,但麥可克雷夫在對《敘述邏輯》的書評中,對安可史密斯的「敘述實體」概念作了非善意的批評。主要的原因是,麥可克雷夫捍衛歷史實在論的立場,堅持過去實在性,他抨擊安可史密斯將歷史敘述是為史家所建構、所創造,並將歷史化約為文本的觀點。同時他也質疑安可史密斯將萊布尼茲「單子論」 (monadism) 應用到「敘述實體」的可能性, see McCullagh, Review of Narrative Logic, 394-403. (Back)
    94. +
    95. McCullagh, "Colligation and Classification in History," The Philosophy of History, 273. (Back)
    96. +
    97. Richard T. Vann, "Louis Mink's Linguistic Turn," History and Theory 26 (1987): 1. (Back)
    98. +
    99. Louis O. Mink, "Historical Knowledge," unpublished manuscript, 4; quoted Vann, "Louis Mink's Linguistic Turn," 2-3. (Back)
    100. +
    101. Mink, "Narrative Form as a Cognitive Instrument," in Historical Understanding, eds. Brian Fay, Eugene O. Golob, and Richard T. Vann (Ithaca: Cornell University Press, 1987), 186. (Back)
    102. +
    103. Mink, "Historical Knowledge," unpublished manuscript, quoted Vann, "Louis Mink's Linguistic Turn," 2. (Back)
    104. +
    105. Mink, "History and Fiction as Modes of Comprehension," Historical Understanding, 51-54. (Back)
    106. +
    107. Mink, "History and Fiction as Modes of Comprehension," Historical Understanding, 53. (Back)
    108. +
    109. Mink, "Narrative Form as a Cognitive Instrument," Historical Understanding, 198. (Back)
    110. +
    111. Mink, "History and Fiction as Modes of Comprehension," Historical Understanding, 58. (Back)
    112. +
    113. Mink, "History and Fiction as Modes of Comprehension," Historical Understanding, 56-57. (Back)
    114. +
    115. Cf. Ankersmit, "Historism and Postmodernism: A Phenomenology of Historical Experience," in History and Tropology, 217. (Back)
    116. +
    117. Walsh, "Colligatory Concepts in History," The Philosophy of History, 131; Mink, "Narrative Form as a Cognitive Instrument," Historical Understanding, 189-195; idem., "Is Speculative Philosophy of History Possible?" Historical Understanding,147-162. (Back)
    118. +
    119. 關於這些問題最近的討論有 Peter Novick, That Noble Dream: The "Objectivity Question" and the American Historical Profession (Cambridge: Cambridge University Press, 1988); Leonard Krieger, Time's Reasons: Philosophies of History Old and New (Chicago: The University of Chicago Press, 1989); Robert F. Berkhoffer, Jr., Beyond the Great Story: History as Text and Discourse (Cambridge, Mass.: Harvard University Press, 1995); Allan Megill, "'Grand Narrative' and the Discipline of History," in A New Philosophy of History, eds. F. Ankersmit and Hans Kellner (Chicago: The University of Chicago Press, 1995), 151-73. (Back)
    120. +
    121. 對分析哲學意圖以「分析真理」取代「綜合真理」的有力批判,請見 W. Quine, "Two Dogmas of Empiricism" in From a Logical Point of View (Cambridge, Mass.: Harvard University Press, 1953), 20-46; 對分析歷史哲學的批判,請見 Ankersmit, Narrative Logic: A Semantic Analysis of the Historian's Language (The Hague: Martinus Nijhoff, 1983), ch. 3. (Back)
    122. +
    123. 柯靈烏歷史理論中的某些成分,可以視為後現代主義歷史理論的原型。近來,已有柯靈烏學者注意到了此一對柯靈烏思想後現代的詮釋; cf. David Bates, "Rediscovering Collingwood's Spiritual History (In and Out of Context)," History and Theory 35: 1 (1996): 33; 此處將他視為「現代主義的」,是將他放置到一八九0至一九三0年期間的現代主義思想脈絡中。此處所謂「現代主義的」,意指回應「現代性」所引發的危機, cf. Dorothy Ross, Introduction to Modernist Impulses in the Human Science, 1870-1930, ed. Dorothy Ross (Baltimore: The Johns Hopkins University Press, 1994), 1-25; H. Stuart Hughes, Consciousness and Society: The Reorientation of European Social Thought, 1890-1930, rev. ed. (New York: Vintage, 1977); 對於現代主義如何回應「現代性」危機,在歷史理論方面的討論, see Bambach, Dilthey, Heidegger, and the Crisis of Historicism. (Back)
    124. +
    125. Collingwood, "Lectures on the Philosophy of History," in The Idea of History, 359-425. (Back)
    126. +
    127. Collingwood, "Outlines of a Philosophy of History," in The Idea of History, 426-96. (Back)
    128. +
    129. Collingwood, An Autobiography (Oxford: Clarendon Press, 1978), 107. (Back)
    130. +
    131. W. J. van der Dussen, History as a Science: The Philosophy of R. G. Collingwood (The Hague: Martinus Nijhoff, 1981), 7. (Back)
    132. +
    133. Megill, "'Grand Narrative' and the Discipline of History," in A New Philosophy of History, 153-68. (Back)
    134. +
    135. 關於「定論歷史」,最著名的討論, see E. H. Carr, What is History ? 2nd ed. (Harmondsworth: Penguin, 1987), 7-16. (Back)
    136. +
    137. Collingwood, The Idea of History, 449. (Back)
    138. +
    139. Collingwood, The Idea of History, 462. (Back)
    140. +
    141. Collingwood, The Idea of History, 461. (Back)
    142. +
    143. Collingwood, The Idea of History, 463. (Back)
    144. +
    145. Collingwood, Autobiography, 97-99. (Back)
    146. +
    147. David Harlan, "Deeper into the Wilderness: History Takes the Linguistic Turn," in The Degradation of American History (Chicago: The University of Chicago Press, 1997), 10. (Back)
    148. +
    149. Collingwood, Speculum Mentis or the Map of Knowledge (Oxford: Clarendon Press, 1924). (Back)
    150. +
    151. Collingwood, An Essay on Philosophical Method (Oxford: Clarendon Press, 1932). (Back)
    152. +
    153. Collingwood, New Leviathan or Man, Society, Civilization and Barbarism (Oxford, Clarendon Press, 1943, rev. ed. 1992). (Back)
    154. +
    155. Collingwood, The Idea of History, 478. (Back)
    156. +
    157. Collingwood, The Idea of History, 472; 我們在此可以看到安可史密斯「敘述實體」的原型論述:一個敘述實體(在此,柯靈烏所使用的詞是「論文」),是關於某物;而論文的所有陳述是此一「敘述實體」的述語,亦即它的性質。關於安可史密斯的「敘述實體」,詳見後論。 (Back)
    158. +
    159. Van der Dussen, "Collingwood on the Ideas of Process, Progress and Civilization," in Philosophy, History and Civilization: Interdisciplinary Perspectives on R. G. Collingwood. eds. David Boucher, Tariq Moodod and James Connelly (Cardiff, Wales: Wales University Press, 1995), 256; also Rex Martin, "Collingwood's Claim that Metaphysics is a Historical Discipline," in Philosophy, History and Civilization, 203-45. (Back)
    160. +
    161. 關於「美學主義」,請見 Allan Megill, Prophets of Extremity: Nietzsche, Heidegger, Foucault, Derrida (Berkeley: The University of California Press, 1985), 2-4; also Ankersmit, "Historiography and Postmodernism," History and Tropology, 162-81. (Back)
    162. +
    163. 自一九八0年後期,安可史密斯放棄使用「敘述實體」,而改用「歷史再現」 (historical representation) 一詞。在《敘述邏輯》中,安可史密斯提出「敘述實體」理論,意在從事狄爾泰 (Wilhelm Dilthey) 式的「歷史理性批判」 (Critique of Historical Reason) ,回答「歷史實在的敘述知識是如何可能的?」此一康德式的問題。 Ankersmit, Narrative Logic, 56; 在將一九八0年代的論文集結而成的《歷史與轉喻學》 (History and Tropology) 中,安可史密斯批判任何形式的超驗主義 (transcendentalism) 。「敘述實體」因帶有康德先驗論的色彩而被放棄,改採「歷史再現」一詞。 (Back)
    164. +
    165. 安可史密斯引以為後現代主義史學典範的是「微觀史學」 (microhistories) 、「心態史」 (history of mentalities) 、「日常生活史」 (Alltagsgeschichte, history of everyday life) 與「新文化史」 (new cultural history) , cf. Ankersmit, History and Tropology, 154-58, 174-75; idem, "Historicism: An Attempt at Synthesis," 158-59. (Back)
    166. +
    167. Ankersmit, "Historicism: An Attempt at Synthesis," 143-61, esp. 143-46; idem, "The Origins of Postmodernist Historiography," in Historiography between Modernism and Postmodernism: Contributions to the Methodology of the Historical Research, ed. Jerzy Topolski (Amsterdam: Rodopi, 1994), 87-117. (Back)
    168. +
    169. Ankersmit, Narrative Logic, 1. (Back)
    170. +
    171. Johan Huizinga, The Autumn of Middle Ages, tr. Rodney J. Payton and Ulrich Mammitzsch (Chicago: The University of Chicago Press, 1995). (Back)
    172. +
    173. Fernand Braudel, The Mediterranean and the Mediterranean World in the Age of Philip II, 2 vols, tr. Sian Reynolds (Berkeley: University of California Press, 1995); 關於布勞代爾的《地中海》一書的敘述成分, see Hans Kellner, "Disorderly Conduct: Braudel's Mediterranean," in Language and Historical Representation: Getting the Story Crooked (Madison: The University of Wisconsin Press, 1989), 153-87. (Back)
    174. +
    175. Ankersmit, Narrative Logic, 2, 49, 100. (Back)
    176. +
    177. Ankersmit, Narrative Logic, 12. (Back)
    178. +
    179. Ankersmit, Narrative Logic, 101-2. (Back)
    180. +
    181. Quentin Skinner, Foundations of Modern Political Thought, 2 vols. (Cambridge: Cambridge University Press, 1978). (Back)
    182. +
    183. Ankersmit, Narrative Logic, 103. (Back)
    184. +
    185. 筆者曾以韋伯 (Max Weber) 的「理想型」 (ideal type) 作為分析陳寅恪「關中本位政策」的概念工具。我指出,「關中本位政策」概念的形成,類似韋伯「理想型」方法論的運作。同時,我特別強調,「理想型」概念形成與「價值關聯」 (value relevance) 間的關係;我試圖說明「關中本位政策」概念形成,與陳寅恪的「價值關聯」相聯繫,亦即陳寅恪的「民族文化觀點」對他選擇研究對象與材料間的關聯。同時,借用孔恩 (Thomas Kuhn) 「典範論」 (paradigm) ,我說明陳寅恪的「關中本位政策」在中國中古史研究領域所起的「典範」作用 ; 請參見盛少輝,〈從「關中本位政策」論陳寅恪的史學─以韋伯的社會科學方法論為系絡〉,《史鐸》 19 ( 1995, 6 ),頁 76-95; 在此處,我所強調的是「敘述實體」在歷史職業中的功能,也就是說,歷史實踐中,歷史家們所爭論的是「敘述實體」的性質。我強調的是「敘述實體」在歷史家社群的爭論中,所扮演的角色。以此,我們對於陳寅恪「關中本位政策」的評價,亦應作如是觀,而非去爭辯它到底是否與歷史真實相符。關於歷史學界對陳寅恪「關中本位政策」性質及相關問題的爭論,如「李唐氏族問題」、「府兵制」、「政治黨派分野」……等問題,請參見汪榮祖,《史家陳寅恪傳》(台北:聯經, 1984 ),頁 112-150; 我期望將來有機會能以安可史密斯的「敘述實體」理論,對陳寅恪的「關中本位政策」再作進一步的探討。 (Back)
    186. +
    187. 陳寅恪,《唐代政治史述論稿》(上海:上海古籍出版社, 1982 ),頁 18 。 (Back)
    188. +
    189. 陳寅恪,《唐代政治史述論稿》,頁 48 。 (Back)
    190. +
    191. 余英時,《陳寅恪晚年詩文釋證》(台北:東大, 1998 增定新版),頁 5-6 。余文徵引如下:「在他自己的研究領域內,陳先生也曾相當有效地把中國的人文學術從傳統帶進了現代。一般地說,他的文史論著是中國的傳統學人和現代專家所都能相悅以解的。傳統學人能接受他,因為他的概念結構 (conceptualization) 是從中國文獻的內在脈絡中自然呈露出來的。這是他『舊學邃密』的一面。現代專家能欣賞他,則因為他所處理的問題完全是現代的。這又是他『新知深沉』的一面。……。」 (Back)
    192. +
    193. Meinecke, "Ranke and Burckhardt," in German History: Some New German Views, ed. Hans Kohn (London: George Allen & Unwin Ltd., 1954), 154; Krieger, Time's Reason, 142-43. (Back)
    194. +
    195. Meinecke, Historism, lv; 關於「歷史主義」一詞的意義,請參見 Dwight E. Lee and Robert N. Beck, "The Meaning of 'Historicism,'" American Historical Review, vol. lix, no. 3 (April 1954):568-77; 最近的討論,請見 Iggers, "Historicism: The History and Meaning of the Term," Journal of the History of Ideas 56: 1(Jan. 1995): 129-52; 近來,在歷史理論領域,有許多意圖綜合歷史主義與啟蒙運動的努力,如日耳曼學者如余琛 (Jorn Rusen) 及其學生布朗克 (Horst Walter Blanke) 、耶格 (Freidrich Jaeger) 等人指出歷史主義深植於啟蒙運動的科學理想,余琛特別強調歷史主義者所賴以建立客觀的科學地史學的「學科範式」 (disciplinary matrix) ,便是來自啟蒙科學理性的理想;部分的英美學者將歷史主義視為啟蒙史學「去修辭化」 (de-rhetoricization) 的結果,如海登‧懷特 (Hayden White) 、高思曼 (Lionel Gossman) 、史帝芬‧班恩 (Stephen Bann) 、賴爾 (Peter Hanns Reill) 與梅驥 (Allan Megill) 等人, cf. Ankersmit, "Historicism: An Attempt at Synthesis," 143-61; Hayden V. White, "The Politics of Historical Interpretation: Discipline and De-Sublimation," in The Content of the Form (Baltimore: The Johns Hopkins University Press), 58-82, esp. 65-66 ,懷特所使用的術語是「訓誡化」或「學科化」 (disciplinization) ,我們可以發現濃厚的傅柯色彩 ; Peter Hanns Reill, The German Enlightenment and the Rise of Historicism (Berkeley: The University of California Press, 1975); Megill, "Aesthetic Theory and Historical Consciousness in the Eighteenth Century," History and Theory 17: 1 (1978): 29-62; 另有學者將歷史主義詮釋為「現代性」 (modernity) 危機的展現,而與啟蒙運動相關聯, Bambach, Heidegger, Dilthey, and the Crisis of Historicism. (Back)
    196. +
    197. Marshall Berman, All That Is Solid Melts Into Air: The Experience of Modernity (London: Verso, 1982), 7. (Back)
    198. +
    199. Jorn Rusen, "Jacob Burckhardt: Political Standpoint and Historical Insight on the Border of Post-modernism," History and Theory 24: 3 (1985): 235-46. (Back)
    200. +
    201. 盛少輝,〈布克哈特《義大利文藝復興的文化》的第一章─〈國家好似一件藝術品〉評註〉 ("Burckhardt's First Chapter: A Commentary on 'State as a Work of Art'") (中文,未刊稿)。 (Back)
    202. +
    203. Ankersmit, Narrative Logic, 3. (Back)
    204. +
    205. Harlan, "Deeper into the Wilderness: History Takes the Linguistic Turn," The Degradation of American History, 18-19 ;以下對歷史文本「互為文本性」的討論,主要取材自哈蘭一文,特此說明,以示未敢掠美之意。 (Back)
    206. +
    207. Fish, Is There a Text in This Class, 14. (Back)
    208. +
    209. Nancy Struever, "Topics in History," History and Theory 19: 4 (1980): 66-79; Megill "Jorn Rusen's Theory of Historiography between Modernism and Rhetoric of Inquiry," History and Theory 34: 1 (1994): 39-60; idem., "'Grand Narrative' and the Discipline of History," A New Philosophy of History, 153-68. (Back)
    210. +
    211. Struever, "Topics in History," 74-75. (Back)
    212. +
    213. Megill "Jorn Rusen's Theory of Historiography ," 54-60. (Back)
    214. +
    +
    + +
    + 回目錄 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/002/article02.html.html b/htdocs/htc/newsletters/002/article02.html.html new file mode 120000 index 0000000..fad4a1e --- /dev/null +++ b/htdocs/htc/newsletters/002/article02.html.html @@ -0,0 +1 @@ +article02.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/002/article02.html.xhtml b/htdocs/htc/newsletters/002/article02.html.xhtml new file mode 100644 index 0000000..2fc7cf8 --- /dev/null +++ b/htdocs/htc/newsletters/002/article02.html.xhtml @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + +試析傅柯的系譜學作品 + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    試析傅柯的系譜學作品
    +--《規訓與懲罰》與《性意識史》

    + +
    黃煜文
    + +

    傅柯 (Michel Foucault, 1926-1984) 以考古學所進行的歷史研究,存在著論述與非論述領域無法溝通的問題。除了《古典時代瘋狂史》之外,從《臨床醫學的誕生》 (The Birth of the Clinic) 一直到《知識考古學》 (The Archaeology of Knowledge) ,傅柯似乎都無意處理這個問題。在結構主義的影響下,傅柯整個研究偏向於語言結構的分析,因而使他的歷史分析專注於論述層面,從而破壞了原本他在瘋狂史中所建立的論述與非論述彼此互動的歷史形式。系譜學的出現,為考古學所存在的方法論問題開啟了一道曙光,藉由分析「力」的場域,傅柯開始尋找那些使論述變動的來源,並因此而將歷史研究的範圍重新擴大到非論述的層面。一旦傅柯將系譜學運用到歷史研究上,他所搜尋的主題將不再局限於知識論述層面,傅柯開始尋找與權力相關的課題,由此而開啟了與之前完全不同的歷史領域:監獄與性意識 (sexuality) 。

    +

    本文所涵蓋的時間是從一九七一年到一九七六年,從傅柯成立「監獄信息小組」 (GIP, Groupe d'Information sur les Prisons) 開始,一直到《規訓與懲罰》 (Discipline and Punish) 與《性意識史》 (The History of Sexuality) 分別出版為止。由於本文將斷限止於一九七六年,是否意味著本文將棄一九七七年到一九八四年這段傅柯最後的時期於不顧呢?答案是否定的。一九七六年,傅柯發表《性意識史》,宣佈他將開始進行一長達六卷的性史研究,《性意識史》是這一系列作品的導論也是第一冊。此後,傅柯有八年的時間未曾出版任何作品。最後終於在一九八四年出版了性史第二冊《愉悅的享用》 (The Use of Pleasure) 與第三冊《自我的關切》 (The Care of the Self) ,但就在這兩本書出版的幾個禮拜後,傅柯因病去世。由此看來,本文若要將傅柯的作品依年代順序分別進行分析,則應該將性史第二冊與第三冊列入討論的內容,然而之所以不這麼作的理由有兩點。

    +

    首先,《性意識史》本身的內容就已經包涵了《愉悅的享用》與《自我的關切》,因此可以只將討論集中在《性意識史》上。傅柯一開始進行性史研究時,並沒有想過要分成數卷,但是後來他發現他所面對的內容相當繁雜,因此不得已才將性史分成六冊。而後為了避免讀者將這些書彼此割裂來閱讀,忘卻了它們原是一個整體,因此他先出版了《性意識史》,作為整個性史研究計畫的總論。傅柯生前只完成了三冊性史,在另外三冊沒有完成的狀況下,單憑分析《愉悅的享用》與《自我的關切》,並不足以瞭解傅柯的構想。也許這時我們應該回歸到《性意識史》,或許才是掌握傅柯性史整體性的較佳作法。

    +

    其次,《愉悅的享用》與《自我的關切》與其說是歷史作品,不如說是哲學性的作品。這是因為這兩本書在討論希臘、羅馬思想家的作品時,不只是忽略了歷史脈絡,甚至在作品與文本的挑選上都相當任意。1 面對傅柯這些不尋常的作法,我們與其責怪他在進行歷史研究時舉證輕忽與漫不經心,不如說傅柯有意在此樹立他個人獨有的哲學思維,也就是說,這兩本書並不是歷史作品,而是他個人哲學思想的展現。因此,本文將不對這兩本書進行個別分析,而將其併入《性意識史》之下來進行討論。

    +

    《規訓與懲罰》與《性意識史》乃是傅柯將其系譜學具體運用於實際歷史研究的明證,同時也是傅柯從一九六九年以來對政治活動與權力運作的關注所產生的思想結晶。相較於之前的考古學作品,傅柯這個時期的研究無疑具有濃厚的批判性與實踐要求。值得注意的是,傅柯此期也廣泛參與了改革獄政以及聲援國外異議人士的活動,而這些活動多半是透過與毛派份子結盟來完成的。毛派是西方知識份子吸取毛澤東的理念而形成的左派派別,主張一切由人民決定而非由政府官僚或其他特定團體來決定;毛派認為藉此可以弭平一切階級的差異,而建立真正的民主。傅柯在參與改革獄政的過程中,曾激烈地主張廢除所有的警察機構及法院,而由人民決定社會公敵,並由人民來予以公審及處罰,完全一幅毛派的作風。2 姑且不論毛澤東想法的對錯,我們都必須要知道一件事:西方知識份子對於毛澤東思想的沿用確實帶有一些浪漫情懷,同時也有極大的誤解,而這種誤解來自於西方知識份子對於反體制力量的渴求。現代福利國家的興起與產業的急速分化,一方面使工人的工作環境有所改善,另一方面也使「工人」已變成內容多樣的職業,這使得左派無法組織龐大而團結的工人來對抗政府,但是改革的需要仍然迫切,於是毛澤東在中國掀起的土地改革(一九五0)年代與「文化大革命」 (1966-1976) 遂提供了西方知識份子某種改革社會的靈感與力量(雖然是全然是一種誤解):不再限於工人,而是讓全體民眾站起來,取代政府,自己決定一切。而這群受毛澤東「感召」的西方知識份子便被稱為「毛派份子」 (Maoist) 。

    +

    一九七一年,一群毛派份子計劃要對法國的獄政問題發動抗爭,他們希望能邀請一些德高望重的人物參與,以壯聲勢。傅柯於凡辛大學的表現,早已引起他們的注意,如今傅柯又在一九七0年成為法蘭西學院的教授,因此,這些毛派份子便企圖邀請傅柯參加。最後,他們不僅得到傅柯的同意,而且在他的協助下成立了「監獄信息小組」。「監獄信息小組」主要的工作在於訪問獄中的犯人,藉由他們的嘴來吐露獄中悲慘的實況,然後再利用媒體的傳布來喚起大眾對獄政問題的關注。巧合的是,這個小組成立不久,法國各地監獄便接二連三地發生暴動,大眾媒體對此的廣泛報導,使得「監獄信息小組」利用這個機會讓獄中訪談傳布到法國每一個角落。然而隨著「監獄信息小組」的成功,傅柯也與這個小組漸行漸遠,因為它已脫離傅柯原先所構想的原則。傅柯認為,沒有人有權利代替犯人說話,無論犯人的處境如何,小組的地位只是以犯人為主,要以作為犯人的傳聲筒自期,而不是幫犯人作主;然而隨著小組的擴大,組織開始反客為主地為犯人爭取權益。在傅柯眼裡,這只是一種偽善,看起來是打著援助的旗號,事實上卻是堵住犯人的嘴,自以為是地為犯人作主,這種作法與那些成立監獄的統治機構也沒什麼兩樣。在這種情況下,一九七二年後,傅柯離開了小組。3

    +

    傅柯在揭露獄政的同時,也一邊進行他的學術工作。傅柯一方面著眼於當下的監獄體制,另一方面也從歷史方面去尋找監獄的形成過程。一九七三年,傅柯與一群學者將十九世紀一個有名案例的檔案整理出版,書名為《我,皮耶‧里維耶,殘殺了我的母親、妹妹與弟弟》 (I, Piere Riviere, having slaughtered my mother, my sister, and my brother) 。里維耶於一八三五年的六月三日,在諾曼第的家中殺死了他的母親、十八歲的妹妹與八歲的弟弟。傅柯藉由里維耶當初留下的回憶錄,說明了醫學論述、法律權威與警察系統彼此鬥爭以搶奪權力的過程,發現它們都在爭取以自身的論述作為決定犯人最後結局的最高標準,霎時間一個兇殘的殺人事件變成了論述間的權力鬥爭場,每個論述都在爭奪處置犯人身體與心靈的權力。4 這本書開啟了傅柯從權力角度觀看歷史的一頁,傅柯在一九七五年完成《規訓與懲罰》便是以這本書的分析為基礎,加以擴大寫成的。

    +

    《規訓與懲罰》出版後一年,傅柯完成《性意識史》。相對於監獄,性意識似乎與權力沒什麼關係,同時也與傅柯所從事的政治活動格格不入。也許傅柯未曾將性意識排上他的街頭抗爭議程,然而他卻每週都在法蘭西學院的演講廳中,向他的兩、三百位聽眾說明研究性意識的重要。傅柯認為,在當代社會的權力─知識關係中,性意識正佔領著核心的位置,所以研究性意識乃是瞭解權力─知識關係的關鍵。5 監獄與性意識因此在傅柯的權力研究中有著同等重要的地位,它們是傅柯藉以分析現代社會權力與知識關係的兩條並行主題。

    +

    本章處理傅柯最後一個時期的思想,將從兩個方面來進行討論。首先,本章將說明《規訓與懲罰》與《性意識史》所呈現的新歷史寫法。傅柯為了研究權力而從尼采那裡借用了系譜學方法,以這種方法所寫成的歷史,打破了以往考古學深陷於論述層面的局限,而能合論述與非論述為一整體,構成了新的歷史寫法。其次,本章將評論系譜學所構成的歷史形式。傅柯運用系譜學所呈現的歷史,看似回歸到《古典時代瘋狂史》論述與非論述彼此結合的方式,然而並不完全。由於繼承尼采的觀點,傅柯的系譜學所呈現的歷史形式隱隱帶有反歷史的傾向;另一方面,傅柯原本想藉由研究權力來針砭現代社會的想法,也因尼采權力觀的隱含設定而解消。

    + +

    一、《規訓與懲罰》

    + +

    《規訓與懲罰》的副標題是「監獄的誕生」,與之前的著作相同,傅柯之所以選擇監獄作為他考察的中心,首要的任務就是要顛覆傳統歷史論述在監獄制度上所持的正面看法。傅柯之前的歷史作品,不斷挑戰著傳統歷史論述所認定的人類歷史是一個越來越人道與越來越進步的進程;而面對監獄的歷史,傅柯同樣要證明,監獄的產生與人道、進步沒有關係,相反地,監獄只是另一種權力形式,而且是另一種更徹底的權力技術 (technology of power) 展現場地。

    +

    監獄制度的產生一般被視為是對罪犯的一種「人道」表現。如果閱讀《規訓與懲罰》開頭所描述的一七五七年一場肢解弒君者達米安 (Damien) 的殘酷場景,一直到一八三七年佛榭 (Leon Faucher) 所設計的巴黎少年教養院所呈現的安寧、恬靜與秩序,讀者不得不產生一種印象,那就是從十八世紀(古典時代)到十九世紀(現代),人們在對待罪犯上的確更加的人道與更加的「文明」。6 然而這只是傅柯故意塑造的假象,他隨後就將戳破這個神話。

    +

    傅柯認為,傳統歷史論述之所以會將監獄的產生視為一種人道的象徵,是由於這些論述只從法律與政府理論的層面來考量這個過程。達米安因意圖弒君而招致兇殘的肢解之刑,這對於傳統歷史論述來說,有兩種意義。第一,達米安面對的是「朕即國家」 (Etat est moi.) 的政治體制,在這種體制之下,法律是君王意志的體現,違逆法律等於違逆君王的意志。達米安的犯行,不僅是違逆了君王的抽象意志,而且還訴諸於實際對君王身體的觸碰──弒君。因此達米安所犯的罪乃超乎以往,須配以極刑。第二,處決的過程之所以要公開,在於重新宣揚君王的權力。以殘酷的手法對待達米安,意味著達米安將以自己所受的痛苦來修補他對君王權力所作的侵犯,而讓所有民眾觀看他的哀嚎與懺悔,更可確認此一修補的過程。7

    +

    在舊王朝時代,觸犯法律等於觸犯君王的意志與權力,之後的處分則是為了修補君王的權力,無論是訴諸於身體的傷害或凌虐致死,都得在公開的場合下進行。這種狀況在法國大革命之後改觀。大革命以後的政府權力,來自於社會契約 (social contract) ,因此,觸犯法律等於觸犯了社會全體 (social body) 的意志與權力,罪犯因此將成為社會公敵。8 對於公敵的懲罰,並不像舊王朝時代那樣訴諸於身體的疼痛與生命的奪取,而是以大革命之後所樹立的人權觀念為基準。在這個時期,人的自由被普遍地看重,因此奪取人的自由遂成為懲罰的最佳方式。設立監獄的目的,就是為了要拘禁犯人來剝奪他的自由。從公開處決轉變成拘禁,之所以能說這個過程漸趨人道,可以從幾個方面來看。首先是因為政府的權力來源由君權神授變成社會契約,人民不再只是臣民,而可以藉由代議的方式組成政府;權力由下而上,避免了特權階級與不平等。同時,在懲罰罪犯上面,不再有野蠻的流血場面,同時也不再有君王的任意懲戒,而是從社會全體的利益來思考罪犯罪行的大小,進而決定懲罰的強度,即便要懲罰也訴諸於剝奪犯人的基本權利。9 這個懲罰方式的演變,從以一人利益為考量到以社會全體利益為考量,從任意懲戒到依據罪行訂定罰則,正符合了平等與理性,另一方面則又避免了殘殺,也合乎人道。

    +

    這段罪犯懲戒史之所以看來日趨人道,在於它基於一個設定,認為基於社會契約論所構建的政府,遠較基於君權神授而形成的政府在法律上更能保障社會利益與天賦人權,而當前者為了保障社會利益與天賦人權而不得不對犯法的人作出懲罰時,它的作法也較為溫和。然而傅柯認為,從權力技術運作的角度來看,這段歷史所顯現的其實是權力技術愈趨完善的過程,法國大革命以後的政府實際上並不是為了保障社會利益與天賦人權而存在,它所進行的是新形式的權力運作,也許在運作手法上不像舊王朝那樣明目張膽,但卻更為全面而徹底。也就是說,現代政府所發展的支配體制,反而比舊王朝時代更為周密而完善,它並不是要保障個人自由,而是要更充分地利用它所擁有的人力資源。所以,如果只從法律條文與政府組成方式來衡量這段歷史的話,只能看到形式上的人道,卻完全看不到抬面下實際發生的支配體系,傅柯的權力分析則試圖彌補這一點,並進而推翻前者所創造的人道神話。

    + +

    系譜學內容的再商榷

    + +

    傅柯進行權力分析時所使用的方法,就是我們在第四章曾提過的系譜學。系譜學是傅柯為了補充考古學所發展出來的方法,它的主要任務便是研究權力。然而,系譜學之所以特殊,來自於它所處理的「權力」與一般的權力不同。我們可以引用傅柯自己對「權力」一詞的定義來說明:

    + +
    +

    我所說的權力既不是只在確定的一個國家裡保證公民服從的一系列機構與機器,即「政權」,也不是指某種非暴力的、表現為規章制度的約束方式;也不是指由某一分子或團體對另一分子或團體實行的一般統治體系,其作用透過不斷地分流穿透整個社會機體。用權力的概念研究權力不應該將國家主權、法律形式或統治的同一性設為原始論據;確切地說,它們不過是權力的最終形式。對我來說,首先應該將權力理解為眾多的力的關係,這些關係存在於它們發生作用的那個領域,而這個領域也構成了這些力的組織……權力無所不在……在任意兩點的關係中都會產生權力……權力不是什麼制度,不是什麼結構,不是一些人擁有的什麼勢力,而是人們賦予某一個社會中,複雜戰略形勢的名稱。10

    +
    + +

    據此,權力並不是一個具體之物,而是一個抽象的力,它在任意兩點間發生。無數的點就產生無數的力的交互關係,也就是權力關係。所以,系譜學所研究的是其實是一個抽象的力場 (field of force) ,而非具體的制度或論述。

    +

    傅柯對權力的定義,其實完全承自尼采。事實上他的系譜學也是來自他對尼采思想的解讀,然而這並不表示傅柯原封不動地移植了尼采的想法。在解讀尼采的過程中,傅柯已用自己的理解將系譜學的概念作了轉化,而讓系譜學獲得了新的意義。若比較尼采與傅柯在系譜學上所持的觀點,從同的方面來說,兩人同樣都討論「力」的問題,傅柯接受尼采將權力關係定義為眾多抽象的「力」的關係;從異的方面來說,尼采偏重於力的「破壞」面與否定面,而傅柯則強調力的「生產」面與積極面。

    +

    從〈尼采、系譜學、歷史〉中可以看到,尼采的系譜學強調「力」彼此鬥爭的過程。尼采將「力」定義為暴力,認為較強的力能將較弱的力所樹立的規則與秩序全都掃除殆盡,從而樹立自己的規則與秩序。如果按照尼采的看法,那麼事物的變化總是以衝突與鬥爭為形式來展現,所以新歷史作品的出現必以破壞舊歷史作品為代價,而對於文本的再詮釋必以對舊詮釋的不滿與拋棄為前提。傅柯起初也同尼采一般主張力的破壞面與否定面,然而後來卻改變態度。在一九七七年的訪談中,傅柯曾說明這個轉折來自於他在一九七一、七二年間參與「監獄信息小組」的經驗。在此之前,他認為權力的效果總表現在排除與否定,也就是說,忠於尼采的看法,因此無論在〈論語言〉或〈尼采、系譜學、歷史〉,傅柯並沒有太多自己的創見。然而參加小組之後,他的想法改變,認為權力所具有的性質並不是破壞,而是生產,並因此而寫了《規訓與懲罰》與《性意識史》。11 「權力生產知識」這句話也是在這個思想脈絡下產生的。12

    +

    綜合以上,傅柯的系譜學的研究對象,乃是一抽象的力場,在這力場中,任何一點所發出碰撞另一點的力,看似要破壞對方,其實在碰撞中,會有所生產。然而生產什麼?或怎麼生產?就要從傅柯的實際分析中來判斷了。

    + +

    酷刑、監獄與規訓

    + +

    路易十五( Louis XV, 於 1715-1774 在位)對意圖行刺他的兇嫌達米安所施加的酷刑,在傅柯眼中,象徵兩點之間「力」的作用。當兩點之間有力的作用時,某一點施力於另一點,另一點並不僅僅是受力而已,而且還會產生抵抗作用,也就是會將力量反彈回去。如圖:

    + +
    A 點對 B 點所施之力,與 B 點受力所反彈之力
    + +

    傅柯用這種觀念來解釋達米安的狀況。路易十五在此象徵 A 點,而達米安則是 B 點,當路易十五對達米安施以酷刑時,表示他對達米安施以某種力(權力),然而達米安看似被動地遭受摧殘,但事實上他也回報路易十五某種力(權力)。如圖:

    + +
     路易十五對達米安所施加之力 ( 酷刑 ) ,與達米安在受酷刑中仍回以路易十五的某種力
    + +

    我們可以理解路易十五對達米安所施加的力是什麼,因為它以明顯的酷刑形式表現;但是達米安的身體在遭受肢解時能對路易十五作出什麼反饋呢?這一點就必須要帶入傅柯權力可以生產而非破壞的觀念,才能解釋。

    +

    傅柯認為,公開處決的儀式具有修補君王權力的功能,這個想法與傳統歷史論述並無不同。然而如果再搭配傅柯的權力概念的話,情況就不一樣了。當路易十五對達米安施加某種力(酷刑)時,藉由公開的儀式,在觀看的群眾間形成了對君王權力的感知與談論,因而產生了對君權的論述。也就是說,當路易十五施力於達米安的同時,產生了君權論述,這就是所謂的權力產生知識。另一方面,達米安被凌辱的身體又是如何產生抵抗的力量,反回去作用在君王身上呢?在公開處決的儀式中,群眾除了從恐怖場景中看到令人畏懼的無上君權,也產生了複雜的情緒,不管是集體鼓譟起來叫好或辱罵,或者是不滿處決過程或藉著人多乘機鬧事,都嚴重傷害到君權的莊嚴。13 也就是說,藉由觀看達米安的身體,群眾產生多重論述,不管是英雄論述、弒君論述等等,都直接干擾了君權的完整,於是一場修補君權的儀式很可能弄巧成拙。達米安的身體反過來對君權施加了力,並因此產生了一連串傷害君權的論述。如圖:

    + +
     路易十五對達米安所施加之力 ( 酷刑 ) ,產生了君權論述;達米安在受酷刑中仍回以路易十五的某種力,則產生反君權論述
    + +

    所以,古典時代的無上君權,在往它的臣民伸展權力的同時,也遭到同等力道的反擊。相反於傳統歷史論述所呈現的全方位掌控臣民的現象,傅柯認為,古典時代的君權必須時時刻刻戒慎恐懼,一方面不能錯過確認君權的機會,另一方面則又擔心群眾中所產生的反響。

    +

    這樣的權力運作機制顯然不穩定而且危險,古典時代末期的有識之士早已有見於此:「在舊王朝的最後幾年……審判時,對待窮人更加嚴厲,無視證據就加以定罪,導致上下離心,彼此懷疑、敵視與畏懼。」14 他們開始呼籲在司法上作適當的改革,然而不久大革命爆發,古典時代結束。

    +

    按照傳統歷史論述,大革命後的政府以社會契約論為依歸,保障全體社會利益與天賦人權,然而傅柯反對這種說法。傅柯認為,古典時代要求司法改革的呼聲,延續到革命後的制憲會議,然而改革的目標不是以保障人權或人道為考量,而是賡續古典時代末期對權力運作機制的討論,企圖建立一套更完美的權力系統。改革者認為舊系統之所以不穩定是因為中央的權力過大。以君王的肉身之軀作為權力中心,使得權力的運作不能均勻、持續而綿密地作用在臣民身上;另一方面,手攬大權的君王因為過於醒目,容易變成眾矢之的,而成為民眾反對的目標。新的權力機制因此應該避免使權力過度集中,並且要讓人看不見權力的來源;這樣才能一方面有效率地施力,另一方面卻又使反抗力找不到反擊的目標。15 所以,從古典時代到現代,並不存在一個越來越人道的懲罰方式,而是要求懲罰地有效率並且不帶任何反效果。

    +

    要建立一個全新而運作良好的權力機制,需要有一套新的權力技術,才能滿足改革者所期望的條件:均勻而不間斷地施力卻又不會有反作用力。傅柯發現,這一套新的權力技術其實在古典時代就已經存在,但並沒有被整合為古典時代權力機制的一部分。這套權力技術由兩種機制構成,一是監獄制度,一是規訓機制。

    +

    監獄制度在古典時代的功能在於「把人當做抵押品來扣留」。16 無力償債或者無法服勞役者,可以用監禁來抵償。從法律上來看,關在監獄裡面的人並不是犯人,他們只是採取不同的方式來還債或是服役。古典時代末期,法國由於農作歉收,加上對外戰爭頻仍,使得社會上的游惰著日漸增加。這些游惰者一方面無法繳稅,一方面逃避勞役,因此必須按理要接受監禁;然而另一方面,這些游民數量龐大,有時會觸法犯罪,擾亂社會秩序。在這種狀況下,原本用來扣留人以為抵押的監獄,突然關滿了無法納稅的游民,而其中也夾雜了不少犯法人士。就在這不分青紅皂白共處一室的狀況下,監獄在古典時代末期開始容納犯罪者,並因而形成一種懲戒性機構。17 按照傅柯的分析,監獄制度早在古典時代就已形成一種懲罰機構,並不是在大革命之後才出現,傳統歷史論述的看法因而是錯誤的。

    +

    光是監獄制度本身還不足以構成現代權力機制,更重要的是要搭配上規訓機制。傅柯將規訓定義為一種「規定某種對人體的具體的政治干預模式,一種新的權力的微觀物理學 (micro-physics) ……一種有關細節的政治解剖學。」18 這種政治解剖學以人體為對象,細密地將人體分割為各部分,將每一部分視為政治權力的施力對象,以便得到最大的使用功率。傅柯認為,這種政治干預模式始於古典時代初期,也就是十七世紀,出現的地點原本是在修院,然後逐步擴展到學校、工廠、醫院,最後傳到了軍營裡面。19

    +

    規訓作為一種人體細節的政治干預模式,它的運作可以分成兩個角度。從肉體(被規訓者)的角度來看,規訓從肉體中創造出四種個性。首先是空間性,從空間分配中打斷每個人的聯繫,使混亂的場面單純化,而能單獨地針對每個人進行考核;第二是有機性,將人體的動作分解成細節,並在每個細節上反複練習,所有的人必須以矯正過後的姿勢來進行每一個分解動作,務使人體活動能達到最有效率的境界;第三是創生性,將人體要學習的活動或計劃分割成一系列的步驟,循序漸進,並在每一步驟的末尾加以考核;第四是組合性,要求熟練於以上各種活動的肉體,以一氣呵成的方式進行演練 (maneuver) 。20

    +

    另外,從規訓者的角度來看,則可分為三個層面。首先是層級監視,在被規訓者當中選出一些人,作為被規訓者當中的監視者,以提高整個權力機制的效能;其次是規範化裁決,規定統一的標準,能合乎標準的就獎賞,不能的就懲罰;最後則是考試,結合了層級監視與規範化裁決,考試除了能對後者進行測試並進行賞罰,考試試卷還可以作為文書檔案,當作前者的參考文件。21

    +

    監獄制度與規訓機制結合而成的一套權力技術,構成了現代權力機制的基礎。而藉由這一套權力技術所造就的最有名的例子,便是邊沁 (Jeremy Bentham, 1748-1832) 的全景敞視建築 (panopticon) 。全景敞視建築是一個環形建築,中心是一座瞭望塔樓。瞭望塔有一圈大窗戶對著環形建築。環形建築被分成許多小囚室,每個囚室都貫穿建築物的橫切面。只在中心瞭望塔安排一名監督者,就可以監視所有牢房內的犯人,而犯人卻看不到塔中的人。22 這種建築形式無疑是監獄制度與規訓機制結合的具體表現。藉由全景敞視建築,監獄管理人可以在中央塔輕鬆地對每個單獨被囚禁的犯人進行監視,他可以命令他們進行一連串的動作,並且在同時間對他們進行評比與考核。另一方面,由於犯人看不到塔中的人,因此他無法確定他是否被監視,這使得犯人完全籠罩在規訓機制的陰影中,一刻不得放鬆。也就是說,在全景敞視建築中,權力可以持續不斷地對某一點施力,然而受力點卻無法確知力的來源來自何處。這正滿足了現代改革者對新權力機制的要求:能不斷地施力又能避開反作用力。

    +

    全景敞視建築所展現的權力機制原本局限在學校、工廠、醫院與軍營,然而從十九世紀初開始,逐漸往社會各層面散佈。這個擴展的過程產生了三個現象。首先,現代權力機制對整個社會進行規訓,將社會上所有的人力資源作切實而有效的運用,因此,權力所造成的功效不是壓迫,而是生產。其次,隨著社會逐步地規訓化,整個社會越來越像是一個大型的全景敞視建築,雖然這個建築當中並沒有中央塔,然而藉由權力中心分化成學校、工廠、醫院、軍營及其他社會機構,無數的權力點遂在社會上星羅棋布地散佈開來;受力者所受的力不再像古典時代那樣只來自君王一人,而是來自四面八方不同範疇的力,這些力不訴諸血淋淋的暴力,而是以零碎但又帶著堅決的持續,無聲無息地滲透到人的身體與心靈;沒有明顯的權力來源加上令人難以察覺的細微施力過程,受力者所能反饋的反作用力陷於迷惘而無力,促使權力更能無所忌憚地施為。第三,權力中心雖然已被分化成無數權力點,卻不代表權力中心不存在,它只是默默地在各權力點背後支持著權力點的運作;而其支撐各權力點運作的方式就是設立警察機構,以警察來遂行各規訓機制的運轉,所以這個隱藏的中心其實就是國家。23

    +

    按照傅柯對現代權力機制的分析,我們可以將其比對古典權力機制,以圖對照如下:

    + +

    ( 一 ) 古典權力機制

    + +
     古典權力機制:君王對臣民的肉體所施加之力 ( 酷刑 ) ,與臣民的肉體在受酷刑中回以君王的某種力
    + +

    ( 二 ) 現代權力機制

    + +
     現代權力機制:無數的權力點對人體施加細微而持續之力 ( 規訓 ) 。人體受力而產生反作用力,然而卻因權力的多重與細微而無法明確反饋。均勻散佈而多元的權力點,其背後其實有國家以警察機構支撐其運作
    + +

    由古典時代到現代,改革者一直盼望著權力運作能日趨穩定而且安全,如今終於實現了。國家隱退到學校、工廠、醫院、軍營及其他社會機構之後,以警察機關協助這些權力點貫徹其規訓機制,而被規訓的人們同時受到來自四面八方不同的規訓力量,難以反應也無從反應;古典時代的權力來源過度明顯,這個缺失在現代權力機制中不復存在,血淋淋而暴力的權力運作方式也消失了,現代權力機制因此是一個溫柔卻又狡猾的權力場域──它無聲無息地施力且不受報復。然而,現代權力機制仍隱約存在著一個問題,由於受力者仍會產生反作用力,只是一時間找不到反饋的對象,這一股力量若是不加以消除,難保有一天不回撲權力來源。因此,如果要使現代權力機制更加完美,就必須消除這個潛在的危險,而這個重責,必須交給監獄制度來完成。

    +

    現代監獄採用了全景敞視主義 (Panopticism) ,運用中央塔來管束犯人。監獄的效能不只局限在監禁,還在於規訓。如果從規訓的角度來看,監獄制度試圖要教育犯人、改造犯人,導正其偏差的行為,而能重新進入社會,然而傅柯發現,事實並非如此。監獄制度非但沒有起到減少犯罪的作用,反而成為培養罪犯的地方。24 「監獄使培養罪犯的環境成為可能,甚至有鼓勵其出現的意思。罪犯在監獄中彼此忠誠、排定輩份,並且隨時準備支援及教唆未來的犯罪行動。」25 另一方面,獲釋犯人即便要改過自新也不可能,因為他們留有案底,社會並不接納他們,同時警察也盯緊這些人,隨時準備發現他們的小錯,抓他們入獄。26

    +

    監獄制度因此成為培養累犯的地方。假設一個人初次犯罪,在判刑後被送入監獄,他首先要面對監獄內的罪犯社會,而在出獄之後,他的案底馬上讓他成為被社會排斥與被警察監視的對象。這樣的人在社會找不到工作,而且永遠都被懷疑是可能為惡的人,在這種狀況下,很少有人能不再度墮入犯罪圈而成為累犯。如此一來,監獄制度似乎有需要檢討的地方,因為它非但沒有減少犯罪率,反而培養了累犯。這種矛盾的現象,是否應歸因於監獄制度運作不正常,因此需要對監獄制度進行改革呢?從傅柯的的角度看來,並不需要。傅柯認為,人們應該放棄監獄是用來降低犯罪的這種想法,而應認清,監獄的設立本來就是為了要在社會上劃出一個罪犯階級。27 而這個罪犯階級的存在,對於現代權力機制的完美化,有著關鍵地位。

    +

    現代權力機制藉由監獄制度創造了累犯圈,並利用其他規訓機構散佈與罪犯有關的論述,用以造成社會全體對罪犯的敵視與恐慌,監獄制度與警察機構遂能在這股強大的敵視與恐慌下獲得存在的藉口:抵禦犯罪。乍看之下,這種狀況相當的詭譎,一方面現代權力機制藉著消除犯罪之名,來取得運用監獄制度、規訓機制與警察機關的合法性,但另一方面,這些機構的成立宗旨卻不是為了消除犯罪;事實上,這些機構的成立在於在社會上建立一個犯罪圈,好讓現代權力機制永遠有存在的必要。也就是說,藉由創造出社會公敵,現代權力機制將原本可能遭受的反作用力完全移轉到罪犯身上,並且還使自身得到一個存在的理由,從而化阻力為助力。因此,現代權力機制的技倆,不僅使得社會力量被導離反權力機制的道路,甚至於還使其反過來支援權力機制。我們可以以圖表示這種改良過的現代權力機制:

    + +
     國家以監獄機構與警察機關合力型構無數滿佈於社會的權力點,形成規訓機制,對人體施力;人體的反作用力則被導向犯罪圈,即國家的代罪羔羊
    + +

    古典權力機制以相當單純的方式來建立起權力場域,它只有兩個端點,一端是君王,一端是臣民,當君王施力於臣民,臣民很自然地反饋一股反作用力回去。前面曾提到,這個施力與反饋的過程並不造成壓迫,而是構成生產。權力能生產論述,權力能製造知識。這種現象也出現在現代權力機制中,只是由於現代權力機制的錯綜複雜,使得權力的生產也花樣百出。譬如說,各權力點對人體進行規訓時,就會因運作的機構不同而產生不同的論述:學校為了教育而產生關於如何教育孩子的論述;工廠為了有效管理工人而產生管理的論述;醫院則與監獄在犯罪層面上結合起來,分別產生了犯罪心理學、精神病理學與獄政方面的論述;而所有的規訓機構都在製造關於社會公敵的論述,其中以罪犯的論述最為明顯而有效。另一方面,社會在這重重論述的包圍下,所產生的論述並不是像古典權力機制那種反君權論述,反而是被誘導成反罪犯論述,而在無形中成為現代權力機制的支持者。就以上的討論,我們可以將現代權力機制與論述的關係以圖表示如下:

    + +
     以監獄系統與警察機關形構無數滿佈於社會的權力點,產生犯罪論述;所形成的規訓機制對人體施力,產生規訓論述;被導向犯罪圈的反作用力,則產生反犯罪論。
    + +

    古典時代社會尚可以君權為箭靶,進行抗爭;現代社會則被巧妙而微細的權力機制層層滲透,甚至可以說是被現代權力機制所分化,整個社會分裂成兩部分:罪犯與非罪犯,彼此互相對抗,而讓隱藏在眾多規訓機構後的國家坐收漁利。於是乎在現代權力機制運作下,社會開始被全面的規訓化。我們可以發現,這樣的社會相較於古典時代社會,人類不僅未享有更人道的生活,反而更受到權力的全面管束。傳統歷史論述的觀點,由此看來全成了神話。

    +

    傅柯接下來所進行的性意識研究,看起來似乎與監獄和規訓無關。但傅柯卻從研究中發現,性意識與罪犯一樣,也成為現代權力機制所極力培養的對象,它們兩者都具有確保現代權力機制存在的功能。因此,本章接下來將以《規訓與懲罰》所建立的現代權力機制架構為基礎,討論傅柯如何將性意識放入這個機制當中及其所產生的作用為何。

    + +

    二、《性意識史》

    + +

    《性意識史》是傅柯計畫中六冊性史的第一冊,也是導論。書中雖然曾談到中古甚至希、羅時代的性論述,也旁及女性身體、兒童性行為還有性反常、人口、種族的問題,但這些都只是對未來五冊性史的簡略介紹。28 這本書的主要目標其實是要對一些理論問題進行歷史調查,尤其是要研究維多利亞時代 (1837-1907) 以來這一個多世紀的性壓抑 (sexual repression) 問題。29

    +

    既然傅柯要研究的是維多利亞時代的性壓抑問題,那麼什麼是性壓抑呢?按照一般的意見,所謂性壓抑就是「對(性)陳述本身的控制,而且要嚴格地規定在什麼地方、什麼時候、什麼場合、在什麼人之間、在什麼樣的社會關係上不能談性;也許沒有嚴格到絕對不准談的地步,但要談卻要在一定的範圍內。」30 所以就這個定義來說,性壓抑指的並不是性生理層面的問題,而是指對於與性有關的論述加以限制或規定的現象。但傅柯基於系譜學的設定,對這個定義表示存疑。由於傅柯相信,權力所具有的性質是生產而非壓迫,因此他懷疑:「是否真有性壓抑這個事實存在?」31 為了討論這個問題,傅柯再度訴諸於歷史考察,然而這個考察相當簡略。傅柯只以短短九頁的篇幅來說明性壓抑在中古時代與古典時代的形式,並且強調社會條件不同會造成壓抑方式與內容的不同。然而即便如此,卻已足夠讓傅柯解析出性壓抑的真正性質。

    +

    傅柯之所以要將性壓抑回溯到中古時代,是為了要凸顯性壓抑形式中所帶有的弔詭。從中古時期以來的天主教告解儀式中,教士要求信眾能檢查自己的靈魂及感官、檢查自己所有的想法與言行,甚至於反省自己的夢,用以將其中有關肉欲與享樂的內容和盤托出。32 這是一個自我反省的過程,供認自己在肉欲上的非份享樂是為了讓自己戒除這些罪惡,也就是說,為了使自己不再淪入逾矩的性欲滿足中,就必須先將自己越份的性行為說個明白,因此,許多異色的性論述便在這個狀況下生產出來了。這個狀況的弔詭在於,本來是為了減少不合教義的性論述,卻反倒生產了大量這方面的性論述。因此,性壓抑模式並不是不准談,而是要多談那些不准談的東西,好讓人不再談。所以所謂的性壓抑,並不是要完全消除不合規定的性論述,而是要專談那些不合規定的性論述,目的是要讓人知道這些不能談。如此看來,我們可以說,與其說性壓抑具有排除的功能,倒不如說它扮演了生產的功能。

    +

    性壓抑所帶有的生產性同樣也在古典時代呈現。在古典時代,原本只局限於宗教層面的告解技術開始擴展到俗世生活上,而此時對性論述的壓抑並不是來自於宗教的考量,而是來自於古典時代重視生產力的價值觀,這種價值觀將性與象徵國力的人口資源與勞力資源相聯繫,將性變成與公共利益有關的論述,於是與公共利益無關或違反公共利益的性論述全都受到壓抑。33 然而同樣地,這個看似壓抑的過程其實充滿了生產力,例如政府要求人民不可淫亂,原本旨在使人民回歸家庭生活以生養更多人口,然而卻無形中創造了淫亂的論述;又如學校不准學生談性,卻在發布命令的同時,一次又一次地說出了「性」。如此看來,越是壓抑就越是生產。對傅柯而言,這是再自然也不過的,因為權力的功能原本就是生產而非壓迫,每一次的權力運作,只會生產更多,而不是消滅更多。

    +

    性壓抑的模式一旦放到現代權力機制中,就更加明顯。起初人們在治療心智疾病時,認為心智疾病的病因與病人不正常的性生活有關,這種想法發展到佛洛伊德而達致成熟。性壓抑因此乃與醫學甚至精神病理學結合,從知識的角度盡情地對於不正常的性態度與性行為進行研究,甚至於開會討論並且有大量相關書籍上士。另一方面,在資產階級支配下,由財產繼承問題所形成的一夫一妻制,開始從法律層面壓抑與一夫一妻制悖反的性論述。性論述因而牽涉到法律論述,因此,通姦不再只是私德有虧的問題,而是要在法律條文中明定所有違反婚姻的通姦條件與項目,昭於天日,甚至唯恐有人不知。因此在現代,性壓抑的模式以大剌剌的姿態生產著它所要壓抑的性論述,其生產的效能更勝以往。34 然而,這似乎也呼應著現代權力機制的性格,權力的行使更有效,其產能也更大。

    +

    從傅柯的討論可以發現,性壓抑其實並不壓抑,相反地,性壓抑專門生產它所要壓抑的論述,從中古時代到現代皆然。傅柯雖然從歷史回顧中將性壓抑的性質梳理明白,但我們要注意,傅柯在《性意識史》中的重點仍放在現代。儘管他的討論範圍上溯到中古時代,然而他藉由中古時代與古典時代來討論性壓抑的篇幅其實只有九頁,因此我們無法將傅柯所寫的這段歷史當成一個獨立的主題來分析,而只能將這簡短的歷史回顧視為傅柯為了討論現代權力機制所作的準備。

    +

    在《規訓與懲罰》中,傅柯認為現代權力機制的完美化,有賴於犯罪圈的建立。由於犯罪圈的存在,現代權力機制得以能無限行使規訓機制而不受任何威脅。而在《性意識史》中,傅柯也想藉著分析性壓抑,來得出呼應《規訓與懲罰》的結論。從之前的討論可以得知,現代的性壓抑模式主要與醫學論述、精神病理論述以及法律論述連結在一起。而由於性壓抑與醫學的連結,現代性壓抑模式所要譴責的性論述遂與健康有關,它所敵視的性論述具有傷害身體健康的性質,是一種「違背自然」 (unnatural) 的論述,傅柯稱這些「違背自然」的論述與行為為「性反常」 (perverse) 。35 性反常與心智疾病互為因果,兩者脫不了關係;性反常也違反正常的婚姻生活,因為性反常總是尋覓不尋常的享樂方式,如性錯亂、戀物癖、同性戀……。基於維護健康與導正家庭倫理的理由,醫學與法律於是聯合起來,針對性反常提出一系列的治療與懲罰辦法,醫學與法律因此也生產了大量的性反常論述,然而這些論述卻並不僅僅是用來治療與懲罰,而毋寧說是用來為性反常打上記號,並且固定它的位置,叫人不忘記它。也就是說,醫學機構與法律機構在社會上散佈性反常的論述,讓社會大眾對性反常產生警覺與厭惡;甚至使父母、師長、夫妻陷入恐慌,讓他們時時刻刻提防著自己的子女、學生與配偶,深怕後者突然有性反常的行為;同時也使社會大眾不得不更仰賴醫學與法律機構,隨時聆聽著它們所提供的性反常論述。36 然而,無論社會大眾多麼仰賴醫院與法院,這兩個機構其實都無意要消除性反常。它們也許真的對性反常進行治療與懲處,但是它們事實上所作的更在於「論述」的創造,因此,就算沒有具體的性反常存在,抽象的性反常仍舊會持續地縈繞人心,那麼醫院與法院就永遠有存在的價值。準此,性反常獲得了與罪犯相同的地位,它們都被歸類為社會公敵,它們也都是國家的代罪羔羊,同時,他們也是現代權力機制得以完美的兩大功臣。

    + +

    三、《規訓與懲罰》與《性意識史》的歷史形式

    + +

    上節已經提過,《性意識史》的內容完全可以放到《規訓與懲罰》所建立的現代權力機制中來談。因此,這兩本書其實可以一體視之,它們所呈現的歷史形式,都是傅柯一九七0年系譜學成形後所構成的新形式。由於系譜學專門研究權力,也就是論述如何運作的問題,而論述得以運作的力量並不發自論述內部,而是來自論述以外的非論述領域,因此系譜學的研究必須合論述與非論述兩個層面來共同進行,這便解決了之前考古學一直不能克服的問題。

    +

    系譜學所構成的歷史形式雖然重新恢復了《古典時代瘋狂史》論述與非論述互動的局面,但並不表示這兩者完全相同。如果從論述與非論述的交互作用來說,系譜學的歷史形式顯然較瘋狂史為細膩,因為系譜學能從力的角度來進行分析,因此可以補足後者在說明論述與非論述互動時語焉不詳的部份。系譜學所顯示的論述與非論述的互動過程可以以下圖表示:

    + +
     施力點因施力而產生之論述,反過來合理化施力本身;受力點因反作用力而產生之論述,反過來合理化反作用力本身;而施力點與受力點,則構成了非論述領域
    + +

    原本瘋狂史只有簡單地談到論述與非論述的互動狀態,但系譜學則能清楚地說明非論述層面內權力的互動關係,並且顯示非論述層面是經由權力關係(不管是施力或是因受力而產生的反作用力)來產生論述;同時,論述則是藉由確認權力關係來進行非論述層面的合理化。簡而言之,論述與非論述之間的互動,仰賴權力關係。權力存在於社會的任意兩點之間,而這兩點可以是人也可以是機構,因為有了兩點之間的力的關係(作用力與反作用力),才構成了社會各層次的互動,因而才形成歷史。如果說,馬克思認為人類歷史向前演進的動力是經濟關係的話,那麼傅柯將會認為,歷史不會向前演進,歷史只是不斷無因果地轉變,而這股變的動力便是權力關係。37 至此,傅柯的歷史研究可以說走到了一個新的里程碑。他不僅成功挽救了他自一九六三年以來在歷史形式上沉陷於論述面的困境,還將權力關係置入歷史變動的核心,使歷史內部各層次的互動具有合理的解釋基礎。所以,從歷史學的角度而言,傅柯的《規訓與懲罰》滿足了論述與非論述的互動,維持了歷史的整體性;另一方面,也解釋兩層次之所以能互動的原因,可以說是他所有作品中最完整而成熟的一部。

    +

    然而《規訓與懲罰》也不是沒有缺點。從理論設定來看,傅柯接受尼采將權力定義為抽象的力,以及權力關係就是眾多力的關係的觀點。然而尼采如何能證明世上所有事物之間的關係都屬於「力」的關係?尤其是他認為這些力不可見也無法掌握,只在任意兩點間流竄;如果這些力真不可見,尼采如何得知這些力,又憑什麼認為事物間的關係都是力的關係。尼采顯然作了一個獨斷設定,並且在這個設定之上建立他的理論,因而將事物間的關係約化成「敵對」與「衝突」的對立關係。傅柯在未作合理解釋下就接受了尼采的設定,致使他的研究的理論基礎相當薄弱。

    +

    傅柯以權力關係作為歷史解釋的主軸,將現代社會描繪成一個被權力機制完全滲透的地方,將老師、醫生、工廠經營者及社工 (social workers) 視為規訓機制的參與者與操作者,權力機制藉由他們的運作,一波波地在人們身上產生作用,但這些操作者自己也無法自外於這個機制,他們也要接受規訓。因此,生活在現代權力機制中的人們,只有兩種身份:規訓者與被規訓者,而後者是每個人都具有的。38 傅柯的講法實在很難讓人信服,假設現代權力機制真像傅柯所說的那般完美而強大,那麼傅柯本人將只有「規訓」與「被規訓」兩種身份扮演,又何能寫出這本「反規訓」、「反現代權力機制」的作品呢?如果傅柯能寫出這樣的作品,就表示現代權力機制並沒有傅柯所說的那樣完美,它留下不少空隙,讓傅柯扮演一個「反規訓」的角色。傅柯之所以會在著作中呈現一個近乎完美的現代權力機制,似乎肇因於他對歷史資料的運用方式。由於傅柯過度仰賴權力關係來說明現代歷史,所以將整個繁複的歷史場景壓縮成兩個端點間的力量關係;他將歷史資料堆疊起來,用以符應他的權力觀念,因此《規訓與懲罰》所呈現的其時是抽象的權力關係史,這本書寫的是傅柯個人理想中的規訓社會,而非現實的世界。

    +

    傅柯在這個時期呈現的作品,在斷裂史觀與連續史觀的爭議上已較為淡泊,傅柯並不傾力於營造一個斷裂的歷史,而是專注於分析現代社會的權力機制。而在對權力機制進行分析的過程中,傅柯仍一貫地維持他過去所堅持的反進步史觀,這時遂產生一個有趣的效應。由於傅柯不認為人類歷史呈現出越來越人道的進程,因此他的看法明顯屬於反進步觀;但此刻傅柯卻不像過去那樣謹守斷裂的原則:歷史無進步也無退步,歷史只是無因果地轉變而已;傅柯在《規訓與懲罰》與《性意識史》中認為人類「越來越」受規訓,「越來越」受控制,因此如果從傅柯所呈現的歷史趨勢來看,從中古到現代,權力機制「越趨」強大,人則「越趨」渺小,這似乎暗示著傅柯在某些面向上已悖反了他先前的斷裂史觀,而反而有了連續的觀念!

    +

    從傅柯在《性意識史》中,針對中古時代、古典時代以及現代所呈現的性壓抑形式而作的分析,我們可以發現,每個時代的性壓抑都隨著不同的社會條件而改變,而傅柯在此所設定的社會條件又與《古典時代瘋狂史》相似:中古時代以宗教倫理進行性壓抑、古典時代則以生產力、現代則以醫學和法律來遂行具有繼承權性質的家庭倫理。傅柯因此有重新強調社會條件的傾向,在社會結構的陳述上,隱涵資產階級「逐漸」得勢的現象。如果我們不單憑這一點來證明傅柯已有偏向連續史觀的傾向,那麼傅柯自己也認為(也許是不經意說出來的),中古時代的告解儀式是一種「說」 (telling) 的任務,到了十七世紀,這個任務成為每個人都需負擔的責任。39 也就是說,從中古時代到古典時代,是一個告解技術從宗教界「傳遞」到俗世的過程。而在《規訓與懲罰》中,傅柯將構成現代權力機制的兩個要素(規訓與監獄)回溯到古典時代,這兩個要素的擴大與結合,構成了現代權力機制愈趨完美的條件。而傅柯在說明規訓機制與監獄制度的演變時,由於他不再運用結構主義的設定,因此意外呈現出少見的「歷史氣味」,我們會看到一段監獄與規訓的歷史「過程」。而在也許由這些訊息來判定傅柯已接受連續史觀是過於大膽的推論,然而若比較傅柯之前的著作,我們的確可以斷言,在傅柯晚期的作品中,斷裂的氣味少了,而連續的成份反而多了,這也許是因為傅柯不再運用符號學而引致的現象。

    +

    綜合以上言之,若不論理論的設定問題,傅柯本期的作品的確更正了論述與非論述不相交流的問題,而在重新恢復論述與非論述交流的同時,又能給予這個交流過程一個更基礎的說明:為什麼會交流?因為力。但是若從理論設定來看,那麼可以說相當缺乏合理解釋,因而呈現出獨斷與輕信的疏忽。而重理論而輕資料的結果,使傅柯本期的作品有玄思的 (speculative) 傾向,因此犯了與他原本用來指責黑格爾、馬克思相同的罪名:目的論;唯一的差別是黑格爾、馬克思的歷史指向救贖,而傅柯的歷史則指向完全的被規訓。至於傅柯本其作品中所呈現的連續傾向:越是談體制的越無法避免連續,反之,越是談思想甚至於是談體驗的則越有斷裂的空間。既然傅柯已放棄結構主義的方法,那麼他無論怎麼談體制,都不能拒絕體制中所涵有之堅強內在邏輯,事實證明,他不得不屈服。

    + + + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +
    + +
      +
    1. Jan Goldstein ed., Foucault and the Writing of History (Cambridge, Mass.: Blackwell, 1995), 35. (Back)
    2. +
    3. Michel Foucault, Power/Knowledge: Selected Interviews & Other Writings 1972-1977 (New York: Pantheon Books, 1980), 1-37. (Back)
    4. +
    5. Eribon, Michel Foucault, 224-235. (Back)
    6. +
    7. Michel Foucault ed., I, Piere Riviere, having slaughtered My Mother, My Sister, and My Brother: A Case of Parricide in the 19 th Century (Lincoln, Neb.: University of Nebraska Press, 1982), x-xii. (Back)
    8. +
    9. Paul Rabinow ed., The Essential Works of Michel Foucault, 1954-1984, vol. I (New York: New Press, 1997), xiii-xvii, 73-79. (Back)
    10. +
    11. Michel Foucault, Discipline and Punish: The Birth of the Prison (New York: Vintage Books, 1995), 3-7. (Back)
    12. +
    13. Foucault, Discipline and Punish, 42-54. (Back)
    14. +
    15. Foucault, Discipline and Punish, 89-90. (Back)
    16. +
    17. Foucault, Discipline and Punish, 73-75. (Back)
    18. +
    19. Michel Foucault, The History of Sexuality: An Introduction (New York: Vintage Books, 1990), 92-93. (Back)
    20. +
    21. Foucault, Power/Knowledge, 183-184. (Back)
    22. +
    23. Foucault, Discipline and Punish, 27-28. (Back)
    24. +
    25. Foucault, Discipline and Punish, 57-69. (Back)
    26. +
    27. Foucault, Discipline and Punish, 77. (Back)
    28. +
    29. Foucault, Discipline and Punish, 78-82. (Back)
    30. +
    31. Foucault, Discipline and Punish, 118. (Back)
    32. +
    33. Foucault, Discipline and Punish, 118-126. (Back)
    34. +
    35. Foucault, Discipline and Punish, 139. (Back)
    36. +
    37. Foucault, Discipline and Punish, 138, 149. (Back)
    38. +
    39. Foucault, Discipline and Punish, 141-167. (Back)
    40. +
    41. Foucault, Discipline and Punish, 170-194. (Back)
    42. +
    43. Foucault, Discipline and Punish, 200. (Back)
    44. +
    45. Foucault, Discipline and Punish, 210-216. (Back)
    46. +
    47. Foucault, Discipline and Punish, 265-266. (Back)
    48. +
    49. Foucault, Discipline and Punish, 267. (Back)
    50. +
    51. Foucault, Discipline and Punish, 267. (Back)
    52. +
    53. Foucault, Discipline and Punish, 272. (Back)
    54. +
    55. Bernauer, Michel Foucault's Force of Flight, 137-138. (Back)
    56. +
    57. Foucault, The History of Sexuality, 8. (Back)
    58. +
    59. Foucault, The History of Sexuality, 18. (Back)
    60. +
    61. Foucault, The History of Sexuality, 10. (Back)
    62. +
    63. Foucault, The History of Sexuality, 20. (Back)
    64. +
    65. Foucault, The History of Sexuality, 23-29. (Back)
    66. +
    67. Foucault, The History of Sexuality, 30-31. (Back)
    68. +
    69. Foucault, The History of Sexuality, 39. (Back)
    70. +
    71. Foucault, The History of Sexuality, 36-49. (Back)
    72. +
    73. Barry Smart, Michel Foucault (London: Routledge, 1988), 22. (Back)
    74. +
    75. John E. Grumley, History and Totality: Radical Historicism from Hegel to Foucault (London: Routledge, 1989), 193-205. (Back)
    76. +
    77. Foucault, The History of Sexuality, 20. (Back)
    78. +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/002/article03.html.html b/htdocs/htc/newsletters/002/article03.html.html new file mode 120000 index 0000000..6a7bb08 --- /dev/null +++ b/htdocs/htc/newsletters/002/article03.html.html @@ -0,0 +1 @@ +article03.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/002/article03.html.xhtml b/htdocs/htc/newsletters/002/article03.html.xhtml new file mode 100644 index 0000000..39a030a --- /dev/null +++ b/htdocs/htc/newsletters/002/article03.html.xhtml @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + + + + + + + +論心態史的歷史解釋 + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    論心態史的歷史解釋︰
    +以布洛克《國王神蹟》為中心探討

    + +
    潘宗億
    + +

    在本文的論述當中,筆者企圖說明作為一種文化史研究或思想史研究的心態史之歷史解釋及其所遭遇到的困境。首先,本文內容的第一個部份將就心態歷史的發展、義涵與研究方法做一個概略地說明,其中將特別著重於論述心態史和「整體歷史」 (total History) 之間的邏輯關係與其所呈現的社會科學色彩的「科際整合」取向;其次,為了討論之便,筆者將以布洛克 (Marc Bloch, 1886-1944) 的《國王神蹟》 (The Royal Touch)1 為具體的例證,更進一步探討心態史歷史解釋的特色;再者,在文章前面部份的論述基礎之下,探討心態史研究取向所面臨到的問題與其侷限,以及新世代史家如夏提葉 (Roger Chartier, 1945-) 如何針對這些問題、缺失,在理論與方法層次上進行修補的工作。最後,總結心態史在當代西洋史學發展中的意義。

    + +

    一、年鑑學派與心態史︰整體歷史的追尋

    + +

    首先,筆者從年鑑史學本身發展的角度,來說明心態史此一研究取向的來由、意義、主題等相關問題。

    +

    歐美史學在十九世紀邁入二十世紀之際,其發展的脈絡表現出新世代史學家企圖革新、挑戰傳統史學的現象。基於此一普遍的趨勢,歐美史學不論在歷史寫作的形式、研究的主題或研究方法上,都呈現出「重新取向」 (reorienting) 的發展方向。其中,歷史學研究領域從以政治史獨尊擴展至經濟、社會、文化與思想觀念等主題的探究。其次,歷史寫作的形式則從傳統史學所呈現的敘述形式,轉向強調分析的形式。再者,在歷史研究方法上,則凸顯出科際整合的特色,如計量方法、社會學理論的運用。最後,綜觀歐美史學在十九、二十世紀之交的發展,值得注意的學術發展現象是「社會科學取向」 (social science-oriented) 歷史研究的興起。2 法國年鑑學派也正是在此一歐美史學的共同趨勢之下出現了,但是,必須強調的是,作為法國二十世紀最有影響力的歷史研究社群,事實上仍反映了其沿襲自法國史學傳統本身的「本土」特色,例如心態歷史寫作的路徑。

    +

    西元一九二九年,法國史家布洛克 (Marc Bloch, 1886-1944) 與費弗爾 (Lucien Febvre, 1878-1956) 創辦了《經濟社會史年鑑》 (Annales d'histoire economique et sociale) ,在此期刊的號召下,聚集了一群標榜著革新政治史與事件史傳統、擴張歷史研究領域與提倡科際整合的史家。此一高舉著「新史學」旗幟的運動,最後終於能從史學研究的邊緣,一躍而成為法國二十世紀史學的主流與典範,學者統稱這一推動史學革新的團體為年鑑學派 (Annales School) 。3

    +

    年鑑歷史學派的特色,主要表現在歷史研究領域的擴張、方法的革新、史料觀念的變革、強調科際間的知識交流與多層次的歷史時間觀等方面。4 首先,就歷史研究領域的擴張言,年鑑史家主張「以人類所有活動的歷史,取代傳統史學以政治為主幹的歷史」,他們宣稱傳統的史家只注意到過去歷史發展的表面,而未觸及歷史事實 (historical reality) 中的深層結構。基於此,他們認為唯有從事經濟、社會、文化、地理等「現象」與「實體」的研究,才可達到對歷史整體 (total) 的理解 (comprehension) ,並由此構成其「整體歷史」的概念。在此一「整體歷史」的概念下,年鑑史家將歷史探究的視野,從偉大的君主、政治家等「個人」的歷史,轉移而致力於下層群眾集體生活經驗的歷史。這就是年鑑史家所定義的歷史。而在現實的發展上,年鑑創立期刊初期即以「整體歷史」為訴求確定了社會史與經濟史的研究方向;而第二代大師布勞岱爾 (Fernand Braudel) 則在其《地中海》 (The Mediterranean and the Mediterranean World in the Age of Philip II) 一書當中實踐其對「整體歷史」的追求;5 1960 年代以後的年鑑則發展出以社會整體為基礎的文化史研究。因此,在此一對整體歷史的追尋的理想之下,隨著歷史研究主題之擴充的需求,年鑑史家在從事歷史寫作時也表現出積極打破學科界線與其他人文學科進行知識交流的態度與趨勢。6

    +

    其次,在方法上,年鑑的創立者布洛克與費弗爾提出了「問題史學」 (history-through-problems) 研究的原則,這項原則一直被沿用至今,7 猶如勒高夫 (Jacques Le Goff, 1924-) 所說的「新歷史就是問題史學」。8 「問題導向」 (problem-oriented) 的研究方法,強調史家不能受制於文獻史料從事歷史的研究,主張史家要「質問」文獻,並將之放置在「問題」的架構之下,以此構成史學研究的起點,並由此提出了對傳統史學「敘述」形式的反對,主張將歷史放在一長時段 (longue duree) 系列之架構中進行「分析」、「比較」與「解釋」。此一長時段的歷史時間觀強調時間的相對性與多層次,9 成為年鑑史家從事歷史研究的特殊觀點,此一觀點後來則由布勞岱發展出較有系統的長、中、短三時段論。10

    +

    在史料運用觀念的變革上,年鑑史家擴大了歷史資料運用的範圍。在傳統史學方面,郎格多瓦 (Charles Langlois, 1863-1929) 與塞諾博斯 (Charles Seignobos, 1854-1942) 的實證史學方法論,主張與強調檔案文獻乃是從事歷史研究的唯一依據。而新的歷史則廣泛的使用各種不同性質的資料,各種不同的著述、文學性的作品、考古文物、口語資料,甚至包括了統計數字、物價曲線、照片、器具、碑銘、電影等。

    +

    上述若干年鑑史學的特色,構成了對年鑑史學思想與方法的「革新」色彩,也就在此革新意義上,表現了年鑑史家對「整體歷史」的追求。筆者認為,這樣對「整體歷史」的追求,構成了年鑑學派從事開發史學新領域的主要動機。而在擴張史學研究領域的努力中,「心態歷史」 (history of mentalities) 的研究取向,表現了最為明顯的革新色彩,也表現出其明顯的「整體」史研究的取向。

    +

    從文化史的角度觀之,心態歷史可謂年鑑史家在從事「文化」或「文明」 (civilization) 研究時所採取的一種研究取向,或者一種歷史解釋的架構。其革新的意義,主要體現在史家對一般群眾的普遍心態 (mental universe) 、世界觀與生活經驗的觀察與研究。就此點而言,它與傳統文化史家或思想史家的最大不同,主要在於其所關注的對象已從「菁英的文化」 (culture of elite) 轉移至「一般人的文化」 (culture of common man) 。其次,它還表現了對「歷史實體」 (historical reality) 如器具之使用、人的行為與活動的重視。心態史家企圖從「物質實體」 (material reality) 、「社會結構」 (social structures) 與時代環境中抽離並補捉住時代的集體心態 (collective mentalities) 與心智習慣 (habits of mind) 等「心理實體」 (psychological reality) 。換言之,就是要透過心態的研究,去呈顯所有人類社會活動中各個結構之間的「內在相互關係」。就智識史 (intellectual history) 研究的領域言,年鑑心態史家不同於傳統智識史所強調知識菁英的思想、觀念,轉而探究一般群眾心靈的結構與日常生活的態度,其重心已從「觀念史」 (history of ideas) 轉移至「心智史」 (history of mind) 的面向。11 另外,美國史家羅柏達頓 (Robert Darnton) 則稱心態史為文化史研究取向的智識史研究。12

    +

    從社會史的角度觀之,年鑑史家在關注人類群眾情感、日常生活的態度與價值觀等精神層面的主題之外,他們也企圖藉助社會學與人類學的研究方法與關於人類現象的詮釋觀點,以掌握人類於社會活動背後的複雜的心靈結構,並更進一步從人類心態的描述中探討社群、社會結構、社會變遷之間的關係。由此觀之,心態史家們一方面表現出對於社會整體歷史的追尋,另一方則表現了年鑑史家從事研究時注重學科交流的傾向。

    +

    年鑑學派在心態歷史方面的專家與著作豐富,其研究的盛況到了一九六十年代以後達其高潮。13 因此,心態歷史可說是為年鑑史學發展歷程中的一個主要特色與成就。芒德魯 (Robert Mandrou) 所強調的年鑑「原創風格」 (the original style) ,14 指的就是歷史心理學與或心態史所扮演的重要角色,其重要的意義在於,它不但是從事文化研究的途徑,更是達到「整體歷史」的主要領域之一。15 從另一個角度言,年鑑學派在從事歷史研究時,經常使用「社會結構」的概念來進行不論經濟、社會、文化、包括人類心智狀態的研究﹔這突顯了社會科學理論、觀念與方法在年鑑學派從事歷史研究過程中的重要性。16 因此,心態史的研究取向,也更具有濃厚的科際整合、學科交流的色彩。

    + +

    二、何謂心態史﹕年鑑史家的心態史研究

    + +

    前文筆者已就心態史在年鑑史學發展和文化史或思想史研究的意義與特色做了概略的介紹。以下,筆者將介紹若干年鑑史家的心態史著作,並從中說明眾多年鑑史家對「心態」與「心態史」所下的定義與詮釋。17

    +

    就廣義的心態史而言,筆者認為,心態史注重人類心靈、思想與情感層面之研究的取向,在西洋史學的傳統中,尤其是在法國史學傳統本身之中,已可見其雛形。

    +

    在法國的史學傳統之中,伏爾泰 (Francois-Marie Arouet de Voltaire, 1694-1778) 、米敘烈 (Jules Michelet, 1798-1874) 和古郎治 (Fustel de Coulanges, 1830-1889) 的著作中,已略見他們對於政治、社會制度背後之「精神」層面的因素的重視。18 在伏爾泰的《路易十四的時代》,我們可以發現他對於人類精神文明的描述與重視。同時,在其《重新思索歷史》當中,顯見他對人口、技藝、習俗等人類活動之歷史的追尋。其中,值得注意的是,伏爾泰在其歷史思想中也表現出對單純「記載事件」歷史的嫌惡,強調從對於人類整體結構的掌握中「解釋」歷史的變遷,而非僅是單純地敘述。其次,米敘烈在他著作法國史即說:「歷史家的責任,在於理解並描寫人在歷史中所呈現的『普遍氣候』 (common climate) 。」19 米敘烈的歷史著作中所表現出對人類物質生活與精神活動等主題的研究與描寫,對法國年鑑史家極具啟發性而倍受推崇,勒高夫即稱米序烈為「新歷史的先驅」。20 另外又如古朗治在其經典著作《古代城市》 (The Ancient City) 一書之中,主張人類歷史乃一整體,強調史家必須從制度、信仰、禮儀、社會之全面生活、思想形式等多方面去建構歷史。同時,古朗治進一步指出,人類歷史中之政治、制度變遷的背後,都是人類的精神本身所推動的,並相信政治、經濟、社會之變動即象徵了人類心態的轉變。21 這樣一種強調「整體歷史」的傾向,使得古朗治被稱為「布勞岱爾之前的布勞岱爾主義者」。22 由此上述可見,法國心態史的研究取向,在其傳統中即可找到它的根源。

    +

    另外,我們還可以在法國以外的地區發現若干可歸之為心態史研究的先驅,如布克哈特 (Jacob Burckhardt, 1818-1897) 與赫伊津哈 (Johna Huizinga, 1872-1945) 開始注意人類的精神文明,但前者仍將其焦點投注在所謂的菁英文化,而後者則開始注意宮廷文化與下層群眾的生活體驗與心靈狀態。就布克哈特而言,筆者認為他在《義大利的文藝復興文明》 (Civilization of the Renaissance in Italy) 一書當中,企圖呈現義大利在文藝復興時期在政治、藝術、哲學、個人主義的世界觀等各方面所表現出的時代精神的新面貌。23 而荷蘭史家赫伊津哈在其著作《中世紀之秋》 (The Autumn of Middle Age) 一書當中,運用如范艾克 (Van Eyck) 兄弟之藝術作品與文學家的文學作品,試圖從布根地地區的宮廷文化對一般人民在思想、精神、禮俗等各方面的影響,並從中分析當時期所形成的集體態度 (collective attitude) 和生活與思想的形式 (forms of life and thought) 。24 筆者認為,若由《中世紀之秋》一書之內容與著重點觀之,真可謂一心態史的經典之著。此外,十八世紀的維科 (Giambattista Vico, 1668-1744) 與赫德 (Johann Gottfried von Herder, 1744-1803) 從事歷史研究時,也注意到人類行為背後的精神因素,主張人類行為與事物之本質,乃潛藏於人類社群不同之情感、精神之中,他們被視為現代心理歷史學的拓荒者。25

    +

    另外,值得一提的是,在史學界之外的其他學科領域,我們也可以發現類似心態史研究取向的著作,甚至可說也影響了心態史研究的取向。如李維布留爾 (Lucien Levy-Brhul, 1857-1939) 的《原始思維》 (The Primitive Consciousness)26 、霍布瓦赫 (Maurice Halbwachs, 1877-1945) 的《論集體記憶》 (On Collective Memory)27 、阿里亞斯 (Norbert Elias, 1897-1990) 的《文明的歷程》 (The Civilizing Process)28 等,都是值得注意的學者與著作。其中,尤其值得注意的是,霍布瓦赫與布洛克乃是在史特拉斯堡大學的同事,在思想與知識上的關係與交流頗深,對布洛克產生了相當的影響,後來霍布瓦赫還成為《年鑑》的編輯委員之一。29 李維布留爾的《原始思維》則對布洛克的心態史巨著《國王神蹟》在概念上有著深刻的影響。30

    +

    雖然說法國史學傳統與其他地區早有類似心態史的著作,但直到 1960 年代法國年鑑第三代史家的時期才真正在學院中蔚為一種研究風潮。31 那麼,相較於年鑑心態史家的「祖先」,其所謂的心態與心態史歷史寫作到底呈現出何種新意呢?而其所謂的「心態」或「心態史」的意義又為何呢?

    +

    事實上,年鑑諸史家雖努力的想為心態史一詞下一個清晰而明確的定義,但始終卻未形成一個既定的概念。從年鑑第三代史家勒高夫所撰寫〈心態史:一個模糊不清的歷史〉 (Mentalities: A History of Ambiguitity) 一文的篇名,就可以略知要為心態史下一個確切的定義是不容易的。32 不但如此,由於「心態」一詞由於字義翻譯上的困難,增加了非法語地區之人在理解上的障礙與困難。再者,心態史所處理的研究主題涵蓋面極為廣泛,包括了群眾集體宗教心態、儀式、節慶活動、巫術、對死亡的態度、愛情、婚姻關係、家庭、閱讀習慣等,也使得心態史難以形成一個明確的概念與意義。然而,即使吾人無法從年鑑史家中獲得一有關心態史的確切義涵,我們可以嘗試藉由觀察若干年鑑史家從事心態史研究時所採用的概念、方法與歷史解釋的取向,來捕捉並描述一個心態史在歷史寫作上的主要特色。

    +

    筆者認為,綜觀心態史發展的過程,其中最值得注意的是它與其他人文學科的交流,尤其是社會學、人類學與心理學,而這也充分反應了新生代年鑑史家對其先輩如布洛克、費伏爾所堅持的「跨學科式的歷史研究」之主張的繼承與發揚。誠如勒高夫所指出的,心態史將歷史學引領到與其他人文科學「接觸」的點,也就是朝向科際整合的方向邁進。33 因此,為了討論的方便,筆者將分別以社會學、集體心理學與人類學等取向為切入點,說明心態史的意義與歷史寫作的特色。

    +

    布洛克與費弗爾可以被視為年鑑史家從事心態歷史寫作的先驅,他們的著作呈現出受到社會學、語言學與歷史心理學的影響。布洛克以《國王神蹟》一書所呈現出的宗教心態的解釋觀點、科際整合的研究取向與比較方法的運用等其他特色,為後世史家多所推崇,並奠定了其在史學上重要地位的根基。喬治.杜比 (George Duby) 在說明心態史歷史研究的淵源時回憶道:「從《國王神蹟》到《封建社會》 (Feudal Society)34 ,布洛克鼓勵讀者思考他所研究之時代的『心靈氣候』 (mental climate) 。」但是,實際提議心態史作為一個歷史研究領域,並提出「心態」一詞之明確說明的是費弗爾,他以更堅定地口吻呼籲史家致力於情感、愉快、恐懼和價值系統的歷史研究,而每一個時代皆有其世界觀、感情的風格、思想的風格。35

    +

    就費弗爾而言,他在十六世紀不信神問題之研究當中,可以見其在心態史方面的努力,吾人或可從中理解心態史的義涵。費弗爾治史的特色之一即他致力於歷史學與集體心理學之間的交流與兩者之間關係的探索。因此,在費弗爾有關人類心靈狀態的研究之著作《馬丁路德傳》 (Martin Luther) 與《十六世紀不信仰的問題:拉伯雷的宗教》 (The Problem of Unbelief in the Sixteenth Century: The Religion of Rabelais) 被視為心態歷史或心理歷史 (histoire psychologique) 的開創之作。在《十六世紀不信仰的問題:拉伯雷的宗教》一書當中,費弗爾從「心態器具」 (mental appuratus) 的角度分析在十六世紀特殊的歷史脈絡之中,並沒有所謂「不信神」、甚至是「無神論」的心態,即使思想前衛的拉伯雷亦復如此。費弗爾認為,所謂的「不信神」或「無神論」的論點,不可能出現在當時期「心態世界」 (mental universal) 所制約下的「思想模式」當中;論者將拉伯雷歸為無神論者,實犯了「時代錯置」之罪惡所致。同時,費弗爾強調,思想模式或心態的發展是經由一「長時期」的歷程所形塑而成的,他的發展與消失都極為緩慢。換言之,人類心態呈現了所謂的「惰性」。最後,值得注意的是費弗爾為「心態器具」所下的註解,他這樣指出:「語言在字彙和文法上的狀態,當中表現出語言的系統性概念及思想情感的支柱。」36 換言之,所謂心態器具包括了語言、概念與情感等三個要素。每個時代因其特殊的歷史脈絡、而展現出其在語言、概念與情感上的特色,並因此而形成其獨特的思想模式。所以,在拉伯雷所處的時代,看起來好像與現代人極為接近,但是其實卻是遙遠的,而這是由於心態器具上的極大差異所造成的。由此觀之,費弗爾的心態史研究乃是從語言、文字入手,並以長時段的的歷史時間架構作為其歷史觀察的架構,強調心態本身的不易變動性。

    +

    第二代年鑑史家芒德魯 (Robert Mandrou) 繼承費弗爾的路線,從集體歷史心理學 (historical psychology) 的角度,提出了他對心態一詞的界定。他認為心態意指的是人類社會中某一特定群體在智識及情感的層面所確信、感覺的方式,而所謂的心態史指的是針對某社會群體的「世界觀」 (vision of world) 、態度、行為模式、無意識集體再現 (collective representation) 的歷史研究。37 不過,芒德魯與費弗爾不同之處,在於其將心靈狀態之研究拓展至「集體無意識」的部份,而芒德魯這一種取向則表現在《近代法國導論︰心理歷史學》一書當中。38 同樣地,屬於年鑑外圍的歷史學者阿里斯 (Philippe Aries) 也指出心態指的是集體的無意識,心態史研究是指對一個集體心靈經驗的研究。其次,杜普龍 (Alphonse Dupront) 則從「集體心理歷史」的角度出發,指出其範圍包含了人類社會與文化中的價值、心態、形式、象徵系統和神話的歷史。他進一步指出人類「心態」緩慢變化的特色,他稱之為概念趨勢 (idea-force) ,此與費弗爾所指稱的心態「惰性」與布洛克所言之人類集體意識緩慢變化或從不消失的提議,具有異曲同工之妙。

    +

    勒高夫、杜比與拉度里 (Emmanuel Le Roy Ladurie, 1929-) 有關心態史的著作,則呈現了較濃厚的人類學色彩。首先,勒高夫在〈心態史:一個模糊不清的歷史〉一文中提出了他對心態史的諸多觀點。他指出,任何一個歷史的個體的心態,很明顯的是此一個體和同時代人所共享的;換言之,心態史是在人類每日生活的機械行為的層次在運作的,它的客體是他們思想的、非個人的內容。39 另外,勒高夫之特點在於其將心態史帶領至「集體想像」 (collective imagination) 的方向,將歷史研究的主題拓展至「文學與想像」的世界。40 他認為應該對於物質世界、精神世界與想像力世界給於相等的重視,才能著做出足以表現人類整體生活層次的歷史。由此,又足以表現出心態史的路徑,乃年鑑史家追求整體歷史的一個實踐。

    +

    其次,中世紀史大師杜比的心態史研究亦頗多,其主要的意義在於他標示著年鑑史家轉向「意識形態」相關主題的研究。杜比從事歷史研究時,極為強調人類社會變遷中物質與精神現象之間的關係,如《三個等級︰封建社會的想像》 (The Three Orders: Feudal Society Imagine)41 即呈現出對上述觀點的著重。第三,以《蒙他猶》聞名於世的史家拉度里,他由於受到了文化人類學將人類社會文化視作一象徵體系之觀念的影響,在《蒙他猶》 (Montaillou: The Promised Land of Error)42 一書當中運用了象徵主義方法解讀法國中世紀農民的文化、宗教觀念與行為。以上三位史家的研究方式,代表了年鑑心態史中採取的人類學取向。

    +

    不過,在心態史有關意識形態的研究之中,仍存在一個重大的爭議,即意識形態與心態兩者之間義涵的區別與異同。在杜比之後,伏維爾 (Michel Vovelle) 即嘗試分別兩者之間異同。在區分二者的區別時,伏維爾認為心態與意識形態這兩個概念乃來自兩個不同的思想傳統、模式,前者是經驗的、後者是系統的。雖然如此,伏維爾認為兩個概念之間仍然有其重疊之處。基本上,心態一詞的一詞所涵蓋的內涵似乎較之意識形態更為寬廣,心態可以很自然的呈現在意識形態之中,而意識形態卻只是心態的某一面向、層次,即「意識的覺醒」或「系統的思想」 (awakening of consciousness or formulated(clear) thought) 。相反地,心態一詞所指涉的是尚未系統化 (unformulated) 、無意義而潛藏在無意識層次的「心靈實體」 (mental reality) 。43 由此可知,心態所指者在於人類心靈中尚屬於未經系統化、非意識、甚至無意識的層面,此與上述多位的史家似乎呈現了一般的共識。

    +

    關於心態史的著作極其廣泛,筆者無法一一說明,在上文中僅就科際整合的角度分析其中若干主要的趨勢。當然,除上文所述之外,其他如 Pierre Chaunu 則將計量方法引進到心態史的研究之中,也是非常重要的一個方向,後來有關書籍史的研究,就與計量方法的運用有密切的關係。然而,雖然無法、也不可能全面性地觀察年鑑心態史的整體面向。但是,由以上一一概略地介紹之中,大概可對心態史此一研究趨向獲得一基本的認識。首先,筆者認為心態史之研究取向擴展了史家的歷史視野,傳統受到忽略的主題與範疇受到了重視,例如對於群眾心靈狀態世界的探索,注意到了歷史中常被忽視的「邊緣」社群團體,使這些無名的人在歷史的舞台上獲得了發言權。同時,除了更廣泛地就人類精神層次進行其冒險事業之外,更進一步邁入「無意識」與「想像」的心靈世界中,這些都大大不同於傳統的史學。其次,心態史家充分地與其他人文社會學科進行知識上的交流,使得歷史研究在方法與觀念上獲得了更新、注入了心血,有助於史家在擴展視野的同時,也有能力處理、掌握更深層的人類社會生活中的現象。而此一探索人類精神面貌的科際整合傾向,也是年鑑不同於其祖先的最大特色與優勢。然而,心態史家到底如何形成其對人類心態研究的歷史解釋呢?其反應在歷史寫作中又有何特呢?在下文中,筆者將藉由布洛克《國王神蹟》一書所呈現的歷史解釋模式,進一步更為具體地探討心態史各面的問題。

    + +

    三、馬克布洛克的《國王神蹟》及其歷史解釋

    + +

    年鑑學派作為一個革新西方傳統史學的勢力,在歷史研究的主題、方法與思想各方面都作出了具有典範性的貢獻。在這諸多貢獻之中,年鑑學派在文化史、思想史領域的研究,所提出的心態歷史之研究途徑、解釋架構與歷史觀點,是極具價值與影響性,且是值得效法的。從若干論述年鑑學派的專書中關於心態史方面的介紹,雖足以提供筆者關於心態史研究在發展脈絡、主要著作內容與特色方面的輪廓,卻不足以讓筆者建立有關心態史研究之方法、意義等較為具體而深入的理解。因此,筆者下文將以布洛克《國王神蹟》之研究,作為對心態歷史更進一步之理解與認識的起點,並期望藉此研究,建立對布洛克的歷史思想與方法之初步認識。

    +

    布洛克乃年鑑學派兩位創始人之一,其歷史思想除具有奠定基礎的意義,他和費夫爾所草擬的藍圖,也對其後繼者產生了不可磨滅的影響。44 第二代的大師布勞岱爾曾說,費弗爾與布洛克在 1929-1940 年間已經建立了所謂年鑑的典範 (paradigm) 。此外,第二代年鑑史家在概念上並沒有比第一代有更多的增補。45 就社會史研究方面,布洛克在中世紀的封建制度、農村史、農民史研究等各方面之論述,尤其《封建社會》、《法國農村史》 (French Rural History)46 兩部巨著,仍是相關領域中為今日歷史學者所推崇的經典性詮釋,且奠定了在此一相關領域研究取向與主題的基礎,影響後世至深。就心態歷史的研究而言,布洛克在《國王神蹟》一書中的研究所定下的方向,同樣的佔有先驅者的地位。他在心態歷史研究的觀念及所設定的綱領與方法,對後世的年鑑學者產生了極大的影響。47 此外,還對非年鑑學者如傅科 (Michel Foucault, 1926-1984) 、伊里亞斯等人具有啟發的作用。48 換言之,布洛克以《國王神蹟》一書,奠定了他在心態史研究的先驅地位。例如勒費夫爾有關法國大革命「恐懼」的研究,其關念即部分參考布洛克有關「謠言」的研究,49 又如杜比也承認他與布洛克的師承關係。50 若干中古史家如 Percy Ernst Schramm 、 Ernst Kantorowicz 和 Bernard Guinee 在布洛克的引領之下,也以一種政治心態的描述、神祕的王權概念、豐富了中古的政治史。51 此外,這部著作對於後世的影響之一,主要是因為他在此書當中,揭櫫了「歷史人類學」的研究取向,廣受歷史人類學與歷史社會學家所討論。52 由此觀之,布洛克之貢獻與意義不僅表現在其作為年鑑的創立者的身分上,還表現在其對年鑑學派研究取向、方法上的影響。基於此,筆者在本文當中將以布洛克《國王神蹟》一書及其歷史思想,作為理解年鑑史家從事心態史研究之歷史解釋的特色,並指出其若干的缺陷。

    + +

    著作之動機與主旨

    + +

    《國王神蹟》全書之主旨,在於論述中古十世紀到十八世紀期間,流行於法、英中的一種普遍心態,也就是人們普遍相信經由國王的「御觸」 (royal touch) 可治癒因「國王的邪惡」 (King's Evil) 所引起的皮膚病 (scrofula) ,並論述此種心態的發生、發展與衰落的過程。53

    +

    從本書的導論,概可從中窺探布洛克從事此書之主題研究的動機。布洛克在《國王神蹟》一書中自言其所致力從事的是,對真正的、廣義的歐洲政治史的一項貢獻,對布洛克而言,這是一項什麼樣的貢獻呢?它不是關於行政、司法與經濟體系之運作的研究,而是在於了解過去朝代中長期支配人類的「精神」。這是一種什麼樣的精神呢?布洛克在導論已明確的告訴讀者,這樣的精神便反映在一般人民具有「國王具醫治疾病的神奇力量」的概念。同時,它也反映了人民對國王與王室之「神聖性」的概念。布洛克認為這一種心態的呈現,反映了自古以來人們對「王權」神秘力量之迷信的一種「集體意識」 (collective consciousness) 、一種意識的趨向 (tendencies) 。54

    +

    這樣世俗國王之神聖性的「普遍意識」 (popular consciousness)55 在中世紀從未失去它的活力,而這樣的活力,使得它得以在與反世俗君王的教會人士如格列哥里七世 (Gregory VII) 等人的對抗中獲得勝利。56 並且,經過中世紀基督宗教的塗油 (anoint) 與教皇的「加冕」 (crown) 等「神聖化」 (consecration) 的儀式,使得「王權」之神聖性蓋上了「神的印記」 (divine seal) ,而使「王權」神聖性的概念,更趨穩固而深刻地深植於人民的「心靈」之中。57 換言之,自古以來國王具神聖性的概念,加上中世紀特殊的環境背景,也就是當時基督宗教中「塗油」等儀式之神聖化的過程,使得「國王擁有醫治疾病的神奇力量」的概念得以深植於人民「普遍的心智與靈魂」之中,同時國王也由此獲得人民更大的忠誠與政權的鞏固。58 同樣的,「御觸」此一信仰衰落的原因,除了英、法前後在十七世紀、十八世紀所發生的政治革命之外,最重要的因素還在於十七、十八世紀的知識分子積極地從心智上,排除世界秩序中「超自然」與「專橫」的因素,並同時建立「純理性」的政治體制。如此,使得「御觸」的儀式,逐漸地從法、英兩國的「政治舞臺」上消失。然而,值得注意的是,「它」從未從普遍的心靈 (popular mind) 中消失。59

    +

    筆者發現,布洛克在《國王神蹟》一書之論述中,他除了處理上述心態之起源到衰落的演變之外,更試圖指出十世紀以來到十八世紀之後,歐洲人在心態上從「非理性的」到「理性的」之轉變。前者指的是在「御觸」習俗的起源時代以來,人們所呈現的一個非理性的心理體系,60 人們崇信超自然的力量。後者指的是「御觸」習俗在衰微時期,哲士呈現了對理性之追求的心態,將超自然的崇拜斥之為迷信。61 換言之,他在此本書中同時注意到人類心靈中的理性與非理性因素,並強調兩者對人類歷史發展的影響,此可謂本書的一大特色,而這樣一種強調人類理解其所處外在世界之思維模式轉變的觀點,實際上乃受到了李維布留爾《原始思維》一書之影響。

    +

    布洛克在探討人們相信「御觸」之現象的起源、發展與衰落的發展外,還同時企圖用此現像來解釋歐洲「王權」的觀念。如此,關於王權 (royalty) 對一般人所具現的神秘魅力,便成為作者在進行論述時的主要概念之一。62 因為,布洛克認為深植於人民心靈中「王權」神聖性的印象,乃構成「御觸」此一現象的主要因素,也呈現了十世紀至十八世紀人民的心理結構;也就是說,人們關於國王神聖、奇蹟般特質的概念及儀式本身,乃是此一時期基本的心理狀態 (essentially psychological) 之寫照。這種心理狀態本身,即對國王或王室之神聖性的概念及其崇拜的行為與態度,乃是一種「集體意識」 (collective consciousness) 的反映。布洛克甚至認為,這樣一種心理狀態,其持續性的影響力,一直到新的政治、宗教狀況之時仍發揮其效力。布洛克在他的另外一部著作《戰爭回憶錄 :1914-1915 》 (Memoirs of War: 1914-15) 中即指出,中世紀對王權的奇蹟 (royal miracles) 的態度,同樣出現在 1914-1918 期間士兵與人民的心理中。63 基於此,布洛克認為「王權」此一概念的歷史,支配了整個歐洲體制的發展。64 因此,在布洛克的研究中,「御觸」此一行為與現象,同時反映了長期以來歐洲人對「王權」與人民對國王具有醫治疾病之神奇力量所具有的集體意識。布洛克在書中的導論部分即提到了,過去史家在從事國王神力的研究時,竟無一人提出「御觸」與「王權」觀念及其關係的討論與解釋。他認為不論對王權或國王神力的研究,都不可只進行單方面的敘述,光從政治體系之運作與社會、經濟之組織的角度來看國王的神力與王權的觀念,而不分析「長期支配人類行為的精神、傳說與信仰」與王權的關係,將不足以達成對上述歷史現象的理解。因此,在他看來,「民間傳說」比一切政治理論都還要好,因為從前者,吾人可經由觀察「圍繞在國王周遭的超自然氛圍」,進而對「王權」達到「真正的、廣義的理解」。65 總之,布洛克企圖藉著法、英一項長達八世紀的宗教心態與行為,去描繪這一段期間的人們在心理上的特徵,並為歐洲的政治史作出另一種觀點的詮釋。

    +

    由此觀之,布洛克企圖建構集體心理 (collective psychology) 與王權之間內在相互依存關係的「解釋」中,實反映了他欲建立對心態史的一套解釋方法。更重要的是,布洛克認為這些集體的概念本身影響及於整個社會中的大多數人,從而表現出來一個特殊的「文明」狀態。66 正如他曾說過的一段話:「社會現實是統一的。如果人們不把一種制度與其同時代心態的各種精神的、情感的、神秘的主要潮流相聯繫,人們將不知如何了解這種制度。」67 ,這樣一種藉著描述人類實際行為背後所呈顯的心態,以建構某一長時段文明狀態的研究方式,一反傳統思想史、政治史強調「人為抽像化」理論的研究取向,可說是布洛克著作歷史的特色,這個特色則同樣出現在他的另一部經典之作《封建社會》之中。68 雖然布洛克在文中很少提及「心態」一詞,69 但是類似的字眼如「心靈狀態」 (state of mind)70 、「心靈態度」 (attitude of mind) 、「集體意識」、「普遍意識」、「集體概念」 (collective ideas)71 、「集體信仰」 (collective belief)72 、「集體意見」 (collective opinion)73 、「公眾意見」 (public opinion)74 等詞彙卻經常出現在《國王神蹟》的論述過程之中。因此不論從布洛克著作的動機、歷史的解釋,或從他所採用的若干主要觀念、字眼等概念工具 (conceptual tools) ,都可明顯的呈現出所謂「心態歷史」的基調。

    + +

    「國王神蹟」的批判性解釋

    + +

    然而,布洛克似乎仍不滿意於上述的解釋觀點,他更進一步從現代「醫學」的角度,提出他對於「國王神蹟」的批判性解釋。布洛克在《國王神蹟》一書當中的論述,不但呈現了一古老儀式的興衰,更展現了一個由集體概念和國王的神蹟所揉合而成的一個「心理的合成物」 (psychological complex) 。在這個合成物之下,使英、法的國王得以宣稱他們具有創造神蹟的力量,同時也使人民滿心狂熱地相信「國王神蹟」。但是,布洛克並不滿於這樣的解釋,因為它仍存在著若干問題:如果上述人們所信仰的概念只是一種幻想,它如何在真實經驗的驗證下還得以生存?換言之,國王是否真的將病患醫治好了?若否,人們又如何說服自己相信「國王神蹟」呢?因此,他在本書的最後一個部分,仍試圖為這個「心理的合成物」探求一個更深入且符合理性的解釋。75

    +

    就第一個問題而言,布洛克在經過前人著作的比較與分析後,得出了一個較為合理的解釋。他認為,「御觸」本身乃「想像力」的產物,是一種「心理治療」 (psychotherapy) 的過程,在此過程中,它使人們從「御觸」儀式神聖性的景觀中,獲得了振奮與希望,最後使自己置身在可被治癒的情境之中。由此,布洛克認為不可忽略了「集體幻想」對人類社會、歷史的影響力。就第二個問題言,根據若干資料顯示,許多人在經過「御觸」之後,皮膚病並沒有被治癒。但是,這樣的狀況並未造成人民的懷疑,反而形成另外一種迷信,即認為病患要經過多次「御觸」之後病才會治好。或者,只能怪罪病患自己「教養不良」 (ill-bred) 或缺乏虔信之心,而使「御觸」發生不了效用。總之,在一種類似宗教式的狂熱驅使下,人們並不在乎成功的比例,只確信他們的國王是神聖的,也只有國王才能治癒「國王的邪惡」 (King's evil) 。76

    +

    但是,何以有些人在經過「御觸」之後,馬上得到醫治,而有些人並沒有馬上得到醫治、或經過一段時間之後病才逐漸好轉?以及為何有些人必須經過多次的「御觸」病才會好?根據這些問題,布洛克從醫學的觀點提出了他的解釋。他認為會有上述這些現象的產生,都是由於「肺結核腫瘡」 (Scrofula) 本身並非是一個短期可治癒的疾病,它病發的時間,有時會很長,有時則很短;腫瘡有時會自己就消失了,有時又會復發,而這樣的症狀又經常會周而復始好幾次;所以,它常常被誤認為已經被治好了。這也是為什麼有些人的病會馬上得到醫治,而有些人就必須經過多次的「御觸」或經過很長的時間才會痊癒。換言之,由於在當時確信國王的神聖性及其「超自然」根源的普遍意識之下,人們並不會像現代人一樣從「自然法則」的觀點去分析「國王神蹟」,因此而在一個「集體錯誤」 (collective error) 的狀況之下,使得「國王神蹟」的信念,牢固地縈繞在廣大人民的心靈之中。77

    +

    綜觀全書,布洛克企圖藉「御觸」此一長達八個世紀之儀式的興衰發展,從中描繪其中所彰顯的集體心理或信仰體系,並同時說明「王權」的觀念。此外,布洛克在處理上述三個主要概念或問題時,還企圖從同一長時段的歷史趨勢之下,彰顯三者之間的相互依存關係 (interdependencies) ,78 最後,更在結論部分提出了他個人所謂批判性的解釋,並再此強調人類的心靈或意識在人類歷史發展中的影響力。由此,布洛克不但繼承了米敘烈所言的「歷史家的責任,在於理解並描寫人在歷史中所呈現的『普遍氣候』 (common climates) 。」,更開啟了年鑑學派從事心態史研究的風潮。總之,布洛克從心態的角度所進行的論述與解釋,正是《國王神蹟》一書的主要特色。

    + +

    四、心態史歷史解釋的特色

    + +

    布洛克《國王神蹟》一書的特色,除了表現在其群眾宗教心態的解釋觀點之外,還表現在方法上「比較歷史」與「問題史學」的運用。79 然而,本文的關注的焦點乃在於布洛克在《國王神蹟》一書的論述當中如何達成其宗教心態的歷史解釋?換言之,心態史的歷史解釋與寫作表現出何種特色?筆者認為,布洛克在《國王神蹟》中所呈現出來的從社會實體到心理實體的解釋模式、科際整合的傾向、長時段的時間架構、史料運用範圍的擴大等方面的特色,乃構成該書解釋架構、模式的主要因素。因此,下文筆者將以布洛克《國王神蹟》為中心,輔以年鑑若干心態史家之歷史著作與觀點,進一步具體地探討心態史歷史解釋之特色的意義,及其如何構成其一整體的歷史解釋模式。

    + +

    社會整體的解釋架構與科際整合的取向

    + +

    首先,談及布洛克在《國王神蹟》一書中所呈現出的社會整體的解釋架構與科際整合的取向。布洛克與費弗爾從事歷史研究,一向倡導歷史學與其他人文社會學科如社會學、人類學、人文地理學在觀念與方法上的交流。因此,其著作如《國王神蹟》、《封建社會》與《法國農村史》也都明顯呈現出科際整合的特點,他尤其受到涂爾幹學派如涂爾幹 (Emile Durkheim, 1858-1917) 與霍布瓦克的深刻影響,使得其歷史著作呈現出濃厚的社會科學取向的歷史研究,甚至被後世學者稱為「歷史社會學」 (Historical Sociology) 的先驅之一,並與二十世紀的德國社會學家伊里亞斯 (Norbert Elias) 相比擬。80 這樣一種「科際整合」的研究取向,主要是受到貝爾的啟發與史特拉斯堡鼓勵學科交流的學風所致。81 後來,也成年鑑學派從事歷史研究的主要特色。其次,科際整合的訴求與年鑑史家對歷史之意義的革新、研究主題的擴大有密切的關係。

    +

    布洛克在《國王神蹟》一書中致力於探討宗教、心智態度與社會實體之間的相互依存關係,而不探討其因果關係。82 由於他所探討的主題是國王「御觸」,以及此主題下人們所呈顯的集體心理。因此,他認為必須探討的問題是,當時代的社會環境下,如何形成這樣一個心態,換言之,他所要探尋的是,在當時的社會實體與集體心態間的相互依存關係。如此一來,在進行社會實體的描述時,同時也將一心態予以「具體化」 (incarnation) 了。在一篇有關中世紀農民心態的論文章當中,布洛克即嘗試從自然環境、土地耕作耕作與技術形式、社會結構之相互關係的解釋,提供一個有關於群眾心態的解釋。83 同樣的歷史解釋模式也出現在《封建社會》當中有關中世紀群眾「感情與思想的狀態」一節中特別是有關時間觀的論述,布洛克即非常強調自然環境、社會結構與精神狀態之間的關係。84 而布洛克這一種強調人類生活中各層次結構的歷史解釋,被英國馬克斯主義史家霍布斯邦 (Eric Hobsbawm, 1917-) 讚譽為「社會整體歷史」的最佳典範。85

    +

    筆者認為,此種強調整體歷史的觀點,隨之而來的歷史研究主題、領域的擴大,促使了布洛克與費弗爾必須高舉科際整合的旗幟。他們一方面企圖從其他會學科借用或引進新觀念、方法,以應付愈趨擴大的歷史研究主題;另一方面,新觀念的使用可作為史家從事歷史解釋與分析的概念工具,以利史家能更系統地進行論證。以布洛克為例,他受到了涂爾幹與李維布留爾的深刻影響。從涂爾幹的思想方面,布洛克引進了涂爾幹有關社會、宗教方面之論述的概念如機械社會、集體意識、集體再現等;從李維布留爾方面,布洛克在《國王神蹟》中有關人類心態之理性與非理性狀態的分析,則明顯受到其《原始思維》的啟發與影響。

    +

    所以,讀者在書中常常可看到布洛克使用如「心靈狀態」、「心靈態度」、「集體意識」、「普遍意識」、「集體概念」、「集體信仰」、「集體意見」、「公眾意見」等詞彙。藉著這些概念工具的使用,布洛克建立了一個綜合了「水平面向」與「垂直面向」的解釋模式。「水平面向」指的是「全部」生活層面所呈現的集體心態之描繪,「垂直面向」指的是社會實體與集體心態之間的關係。在此一解釋模式之下,這樣一種致力於人類心態的企圖,不但擴大了歷史研究的視野,也反映了布洛克歷史思想的核心,即強調歷史研究的對像乃是多數的人及其所有的活動。86

    +

    而布洛克在《國王神蹟》一書中所處理的,便包括了社會中的各個階層的人,如國王、貴族、教士、醫生、文學家及一般平民,以及他們在政治、宗教、藝術、文學等各方面的活動。除此之外,布洛克還藉著對上述人所構成的一個心理圖像,進而將歐洲在政治、宗教、藝術等各方面的發展與面貌呈現在讀者面前。正如他在書中所說的,集體概念可影響及於整個社會的生活,並明顯表現出一特定文明的狀態。87 正如他在《史家的技藝》所言:「歐洲封建主義,乃源自於整體的社會情境。」88 。因此,在這個意義下的《國王神蹟》,它不僅是一部心態史,更可說是一部文化史的建構。至於,布洛克基於社會集體心理的注重,所提出的人類精神層面的歷史研究的取向,是否可算是屬於思想史的範疇?基本上,這個問題根本上牽涉到「思想史」或「觀念史」本身在概念上的界定,因此,要嚴格的區分思想史、觀念史、文化史的界限,並不是一個簡單的事情。89 不過,從宏觀的角度來看,筆者認為,布洛克在概念工具與比較方法的運用,實際即構成了心態史或文化史解釋的架構,為年鑑心態史或者是文化史的研究提供了新的面貌與可行的路徑。當然,我們也可說它是思想史的研究,只不過跟所有法國心態史家一樣,他所關懷的重心,主要集中在一般人民的層次。90

    +

    從布洛克有關心態史的歷史論著中,我們發現了其強調社會整體的歷史觀察與解析的特點,也反應出其治史的科際整合的學思傾向。事實上,這樣一種強調社會整體的歷史觀點,不但可上溯至法國史學傳統中的米敘烈、古朗治,也可在年鑑後世史家的著作中被發現到。例如研究中古封建社會三個等級社會的杜比,在他眼中的社會各層面乃是一個不可分割的整體,即人類心態與社會物質生活、政治社會結構與文化之間乃是一個有機的整體。其次,社會群體也是杜比關注的焦點,這使得他特別注意某一個社會中若干特定之社會團體間的關係,由《三個等級︰封建社會的想像》與《騎士、女士與教士》 (The Knight, The Lady and The Priest) 兩本書所處理的問題來觀察,特別顯示其對社會中群體的關注。在有關反省心態史歷史寫作的問題時,杜比特別指出,物質生活、社會結構與人類心態之間的不可分離與社會中的「群體」,乃是心態歷史寫作中最基本的兩個原則。91 事實上,從整體的角度觀之,心態史強調物質生活條件、社會結構與心態的三層次結構關係,曾經對年鑑本身的歷史寫作與發展產生了深刻地影響,直到晚近以來部份史家才放棄了對整體歷史的追尋,甚至產生出「破碎化」的趨勢。92

    +

    在引進社會學科的觀念與方法方面,布洛克與費弗爾兩位年鑑的創始者作出了積極的示範與提倡,而這樣一種路徑尤其呈現在第三代以後的年輕學者。例如夏提葉在《法國大革命的文化起源》 (The Cultural Origins of The French Revolution) 一書當中即運用了社會學家哈伯瑪斯 (Jurgen Habermas) 的「公共領域結構」與伊里亞斯《文明的歷程》中的「心靈經濟學 (Psychic Economy) 」理論,作為其解析法國大革命歷程的概念基礎。93 又例如奧左夫 (Mona Ozouf) 在其著作《節慶與法國大革命中》 (Festivals and the French Revolution) 中,則運用了涂爾幹與佛洛伊德 (Sigmund Freud, 1856-1939) 有關宗教活動方面的理論,來進行其有關節慶活動的論述。94

    + +

    史料的運用、種類及其擴充

    + +

    由於心態史研究對人類所有活動與心理的整體的關懷,使得布洛克在援引史料時,也同時擴大了其取用的範圍,這同樣表現在布洛克《國王神蹟》一書的內容上。其次,心態史家運用史料之種類與範圍的擴大,正隱含一種有別於傳統的新的史料觀念。以下,筆者將論及布洛克與心態史寫作在史料運用上的特色。

    +

    布洛克在《國王神蹟》的論述中,採用的史料種類顯示了多樣性、範圍極為廣泛,正如他在《史家的技藝》一書所說的:「歷史資料的多樣性近乎無窮,人所說的、所寫的、所做的、所接觸的任何事物,都能教導我們有關他的事。許多人由於不熟悉我們的工作,以致低估了歷史資料所可能真正包含的範圍。」95 布洛克自然知道其研究主題所涉及的層面非常之大,單單官方或教會的檔案文件將無法幫助他描繪一個群體所展現的心態。荷蘭史家赫伊津哈在《中世紀之秋》一書從事有關中世紀布根第地區的社會與文化時,也感嘆官方檔案文獻往往無法提供可資史家觀察群眾情感、行為的材料,必須轉向文學、民謠、藝術、繪畫作品當中去捕捉當時群眾的心態。96 因此,由於研究主題及性質使然,布洛克除了宮廷的紀錄與文件之外,其取材還包括了醫學、神學與政治學理論的著作、小冊子、文學著作、聖經、宗教祈禱文、詩文、歷史著作、法律訴訟文件、信件、繪畫作品、錢幣等。布洛克認為,凡是人類所遺留下來的「遺跡」,都可能說出人類行為與精神狀態的意義,誠如他所說的「能教導有關他的事」。

    +

    除了在史料運用上表現了多樣性的特色,更重要的是,布洛克在應用史料時所表現的批判態度。由於布洛克認為對於歷史現象的理解,首要之務在於對史料文件進行仔細而批判性的研究。97 因此,在引用史料論述時,他會對所引的資料進行「比較」分析,以求得較為真確的內容。或者,他會對史料進行批判的工作,需要進一步解釋的史料,他會試圖去找出其繆誤,甚至企圖尋找其背後的真正意義,一獲得可靠的訊息。比如,當官方紀錄、文件與其立論相違背時,他並不急於放棄他的立論,他會從兩個途徑去解決問題。一、考證史料的可靠性,進行對史料時代背景的考察,分析史料是否因時代或地區性的不同,而在紀錄方式、內容上有所不同,以從中找出適當可靠的資料,並進行對資料的解釋工作。例如:他在描述「國王神蹟」的流行程度時,引用了官方的檔案紀錄的數字統計,發現了紀錄中的數字,呈現了有時高有時低的不規則現象。經過一番之考證,結果他發現,數字較少的時候正值國王出外征戰或旅行的時間,所以他認為數字之減少,未必就代表「國王神蹟」之沒落。98 二、質疑史料的可靠性代表性,「即使來源無可置疑的史料也不一定真實,吾人必需查驗史料騙局與錯誤。」99 在布洛克眼中,史料的意義與價值乃是史家所給予的,「史料在史家適當的詢問之下,才開口說話。」100 換言之,史家如法官一樣,必須對史料提出問題與質疑。如文件本身對史家研究的主題有何切題之處?又,文件是否可讓史家信任?在此前提之下,所構成的歷史才會更為可靠與真實。101

    +

    其次,布洛克在史料運用方面的觀念,最大的特色還在於,他非常強調史家必須讀出史料未說明的意涵,正如他在《史家的技藝》一書所說的 : 「我們可以偷聽出資料沒有說出的事情。」102 ,即使沒有官方紀錄或文件,也不可因此而卻步。換言之,任何可以表達出群眾心態的人類活動遺跡、證據,在史家的拷問與理解之後,總能成為正當的歷史寫作的材料。在布洛克的歷史思想中,史家與史料間的地位儼然已經互相置位,這也是他歷史思想的特色之一。103

    +

    由於處理主題的性質使然,心態史家不得不往非傳統、非文字記錄的人類遺跡中找尋材料。筆者認為,由於使用的史料種類、形質的擴充,使得年鑑史家必須借用其他學科知識,以資解讀陌生資料時所需要用到的專業技術,因而邁向了「科際整合」的道路上去。104

    +

    然而,在上述的史料種類之中,文學作品之引用經常容易引起部份論者的質疑。文學作品果真如布洛克所說的,可以呈現時代的心態氛圍?或者,文學作品本身想像的「性質」,是否可供史家使用?或者,與官方文件檔案比較之下,文學作品較容易表現社會的心態,甚至是著作心態史所不可獲缺的資料來源 (unavoidable kind of evidence) ?105 這些問題,是值得進一步思考與商榷的。不過,筆者認為,假若史家能在援引文學作品的同時,經過一番檢證的功夫,再進一步作出合理的解釋,在可以反映歷史的真實的狀況下,文學作品應該是值得史家使用的。另一方面,文學性、非文字史料的運用,其實隱含了史料觀念更進一步的一種革新,關於此點筆者將於本文第四部份進行探討。

    + +

    長時期的歷史觀點

    + +

    《國王神蹟》一書之主題,在時間的向度上橫跨了八個世紀之久。布洛克在此,致力於描繪人民「集體幻想」的普遍趨勢,而此趨勢延續了長達八世紀甚至更長的時段。這種從長時期官觀察一社會機制之發展的觀點,與布勞岱爾所提出長試時段時間觀頗有相似之處。基本上,這也反映了布洛克對於「事件」因素的懷疑,因為他認為從事件的觀點來理解歷史是不全面的,它會忽略了許多社會創制所獨具的慣力與惰性。106 伏維爾將這種心裡的現象稱之為「心靈結構的惰性趨力」。107 換言之,歷史之中有許多的現象或人的心態,經常可持續發展綿延數世紀之久,看似「極為緩慢的變遷」或根本不變的歷史。本書所描述的「國王神蹟」之習俗,便屬於這一種緩慢發展的社會現象。

    +

    因此,在《國王神蹟》一書之論述中,布洛克經常強調,在中古時代具有一股普遍趨向的「心智習慣」,這種心智習慣,習於對人事物採取較為神秘、超自然的解釋,並且相信「奇蹟」。就是在這一種心智習慣之下,國王神蹟的習俗與君權神授的觀念,才得以長期存在於中古時代,並綿延至十八世紀,甚至對二十世紀的法國產生影響。總之,在《國王神蹟》一書中,布洛克不但顯露了他對於長時段歷史的觀點,在書中他也不只一次的使用「長期」 (long period)108 一詞。

    +

    強調長時段的歷史時間觀點,不僅出現在布洛克的歷史解釋之中,也呈現在其他年鑑心態史家的歷史寫作之中,而此乃心態本身的性質使然。比如在本文第二部份提到的費弗爾、杜普龍等人,即非常強調心態本身緩慢變化、不易變動性與惰性等特性,即使社會結構與經濟條件產生變化,人類的精神狀態、價值體系也不易變動。因此,在處理有關某種心態的主題時,就必須採取長時期的歷史觀察視角進行研究與分析,如拉度里、伏維爾等人的著作中,都呈現出長時期歷史觀點的運用。

    + +

    心態史歷史解釋的若干問題

    + +

    從《國王神蹟》一書,吾人不但可以看到布洛克廣闊的歷史思想與視野,還可以從中獲致若干從事歷史研究的方法與特色。筆者認為,其從事歷史論述的敘述邏輯,呈現了「問題導向」的特色,比較方法則為其從事歷史分析與解釋的工具,對史料種類的廣泛運用與批判則為其從事歷史研究的基礎,而長時段的觀點則為其從事歷史觀察所採取的角度。但是,在布洛克上述心態歷史寫作特色當中,仍顯現出若干值得深究的地方。

    +

    首先,布洛克在《國王神蹟》一書建構了「集體心理」的歷史解釋架構,從群體之普遍意識的角度,呈顯中世紀西歐相信「神蹟」的信仰體系,以及在此體系之下的社會情境,同時描繪了歐洲在政治、宗教與文化活動的文明狀態。換言之,布洛克企圖從事於人類心態與社會實體間的相互依存的關係,並從中凸顯「集體心理」在歷史發展中的重要性。在此解釋架構下,他藉由中世紀多數人崇信「國王神蹟」的現象與心態,為「王權」的神聖性提出了中古歐洲政治發展的另類解釋。此外,布洛克還藉由「國王神蹟」從中古到十八世紀的發展脈絡,指出從「非理性」到「理性」思考模式的轉移。值得注意的是,布洛克似乎認為由「御觸」習俗所呈現的普遍意識,其流行的程度與強度,已擴及到整個社會的全體,在這裡,上層的菁英分子與下層的一般人民的文化與思想似乎取得了聯結與調和。相對地,對「整體」的重視,是否忽略了個體的差異性?而兩者之間又將如何調和?心態史的研究取向,果能呈現人類「整體的」精神面貌嗎?布洛克及其心態史寫作所表現出的集體性的傾向,是否使歷史與歷史解釋本身只呈現出歷史現象的同質性 (homogenization) ,而忽略了其差異性呢?這些問題,仍猶待進一步的釐清。

    +

    其次,是關於史料運用的問題。不管是布洛克或眾年鑑史家,在從事所謂心態史研究時所運用的歷史資料,經常包括了若干非官方性的材料,例如宣傳小冊子、文學著作、聖經、宗教祈禱文、詩文、歷史著作、法律訴訟文件、信件、繪畫作品、錢幣、一般平民的遺囑等。上述種類的史料,引起了若干傳統與保守史家對其「真實性」與「正當性」的質疑。而針對布洛克的《國王神蹟》一書而言所引發的問題是,他如何解釋文學作品的可靠性與適當性?就心態史的研究而言,文學作品的運用是否正如伏維爾 (Michel Vovelle) 所言的是不可避免的?

    +

    其三,布洛克以集體心態的角度來看人類歷史的發展,是否忽略或降低了政治、事件因素的重要性。換言之,「事件」本身在心態史研究中所扮演的角色為何?常常強調集體心理之重要性甚於政治事件,正是布洛克在《國王神蹟》一書所呈現的一貫論點。在他眼中,在「國王神蹟」發展史中,「集體幻想」所扮演的角色就好像法庭上的法官,宣判了「國王神蹟」的死刑,而政治事件只是法官手中的木槌而已,甚至法官隨時都有可能改判,就好像「國王神蹟」之集體心態又將從歷史的潮流中顯露出來。因此,在布洛克眼中,「事件」所代表的意義是微乎其微的,此也是吾人必需進一步思考的面向。另外,強調「長時期」的歷史解釋架構,是否因而忽視或遺漏的歷史發展當中的「變遷」因素呢?事實上,這些問題也經常出現眾多論者對心態史的批判當中。109

    + +

    五、心態史與文化史的若干問題與困境

    + +

    在前述有關布洛克《國王神蹟》及心態史歷史解釋的探討基礎上,在下文中,筆者將指出,面臨心態史所隱含的若干歷史觀念的缺陷,若干年鑑史家如何從理論層次上嘗試修正並補充心態研究的不足之處。當然,在探討過程中,其介紹性的成份居大,筆者僅僅企圖從中點出若干值得探討的觀念,至於如何解決上述若干的問題,其所涉及的層面的深與廣,將不是本文所能夠含蓋與處理的。

    + +

    菁英文化與俗文化的關係

    + +

    從對於布洛克的探討中,我們可以看到心態史所面臨的第一個問題是菁英文化與俗文化 (popular culture) 之間的關係為何的問題,這不但是心態史歷史寫作所遭遇到的困難,它也是從事文化史寫作、甚至是思想史寫作所必須思考的一個問題。事實上,這一個困難本身它也牽涉到了一系列複雜難決的問題,如俗人的 (popular) 的義涵所指為何?而其義涵實質上則呈現了多樣性,比如說 (popular religion) 是指農民的宗教,還是指被統治者的宗教,抑或是所有俗人的宗教?又例如俗文學 (popular literature) 是否提供了閱讀材料給農民社會?是否提供了作為識字人與不識字之人之間的公共媒介?或者,它是否意指了全社會所共享的?總之,難以從一系列的主題與行為中,呈現出一個具有整體圖像的平民文化或俗文化。另外一個由於心態史研究所引發的一個值得深思的問題是,平民文化或俗文化是如何形成的?它的根源為何?它是平民所發明創造的?抑或是知識份子根據俗文化為材料的再創造?

    +

    法國年輕一輩的年鑑史家夏提葉 (Roger Chartier, 1945-) 認為,以上所述之問題都是次要的,他認為最要者在於︰如何解決不同文化層次結構如何交叉會通在一起,而形成若干集體的行為、表象與文化產品。他也認為,這同時是思想史 (intellectual history) 研究所必須面臨的問題。換言之,文化史研究所必須克服與面臨的問題是,菁英文化與俗文化如何形成一個人類心態與精神上的混合物(合成物)。110 同時,菁英文化與俗文化之間的關係又如何呢?

    +

    關於上述的問題, Mikhail Bakhtin 在《拉柏雷及其世界》 (Rabelais and His World) 一書中的部份論述文字值得注意。他在說明拉柏雷與民俗文化之間的關係時,他如此描述︰「他的著作是民俗文化的百科全書。」111 他認為,在文學或學術文化的著作上,俗文化展現了其最大程度的一體性,並且顯示了俗文化自身的根源;換言之,俗文化乃根源於菁英文化,或者菁英文化乃是俗文化的「原型」 (matrix) 。112 卡羅金茲柏 (Carlo Ginzburg) 則認為,一般平民可經由書籍以及他們對書籍的詮釋,而使菁英文化的思想因素「滲透」到一般人民的思想當中,甚至更進一步進行再創造的過程。然而,金茲柏的論點仍有漏洞,也就是一個一般平民如何去讀懂書籍甚至詮釋之呢?

    +

    有關菁英文化與俗文化之間關係的探討,還可以從「創造與消費」 (creation and consumption) 與「生產與接受」 (production and reception) 的角度來思考。文化消費者的思想,是否能與思想的發明者融合在一起?思想的本質意義,乃完全獨立於使用它的社會群體與個體嗎?關於此問題,瑟陶 (Michel de Certeau) 認為,文化或思想的「消費」本身,即是一個「生產的過程」,尤其值得注意的是,消費者所形成的表述與作者的原意並不互相一致。113 換言之,一個文化產品如思想、書籍或工具的意義,乃表現在消費者使用產品的方式上,也就是消費者創造與在創造了產品的「意義」。如此,思想與文化的生產者、創造者與消費者、接受者之間並非二分法的世界。由此,我們似乎尋找到菁英文化與俗文化之間關係的一個可能的詮釋角度,也看到兩者之間互相「交流」的可能情況。

    + +

    文本的真實與虛構

    + +

    其次,從事心態史研究或文化史研究,所必須面臨與解決的另外一個困境是文本 (text) 的真實 (reality) 與虛構 (fiction) 的問題。由筆者從布洛克的探討之中,我們可以發現,傳統史學所忽略甚至排除在外的史料證據被大量運用在心態史的歷史寫作之中,諸如遺囑、帳本、信件、日記、教堂人口登記簿、法庭訴訟記錄、商業單據、文學作品等等,而這些證據本身尤其是文學作品本身經常遭受到是否具真實性可靠性的懷疑。關於此,新世代的年鑑史家如夏提葉試圖從後結構以來新的歷史理論與觀念中取得解決之道,而此一解決之道似乎正顯示出一種新的史料觀念的出現。

    +

    依據瑟陶之說,文本的意義乃是由讀者所建構者,讀者在閱讀的過程中,發明了若干不同於文本原來所意指的意義。114 其次,從文本的類型區分來看,檔案文件 (documentary text) 與文學作品 (literary text) 兩者的價值並無分殊,因為不論任何文本的建構,都是寫作者從事寫作時的推論模式與思想類型的產物。換言之,文本所建構的實體或真實,並非真正的實體或真實,而是人們所認知的實體或真實。文學性的文本是如此,檔案性質的文本亦復如此。而心態史所企圖建構的並非真實的實體,而是人們所認知的那個實體,因此,即使如文學性的作品,仍可資史家從中獲得當時之人所呈現出的認知與意向。換言之,史料是否能呈現出原來那個客觀的「實體」並不重要、也不可能,重要的事史家如何去面對文本本身。如此一來,似乎克服了有關文學性史料的正當性問題。115 關於心態史歷史寫作在史料運用與歷史真實等觀念所表現出來的新意,荷蘭史學理論家安可史密斯 (F. R. Ankersmit) 有其獨到的見解,本文限於篇幅將不多作論述。

    + +

    結論

    + +

    在本文當中,筆者探討了心態史歷史寫作在年鑑發展當中的意義、特色。筆者認為,心態史歷史寫作乃是在年鑑史家在前人米敘烈、古朗治的啟發與其本身對整體歷史之認識革新的狀況下所必然產生者。由於整體歷史此一理想的追尋,年鑑史家將歷史研究的重心轉移至社會、經濟與文化史的寫作,寫作的主題也從人類政治、軍事等行為的敘述,轉向對於人類物質生活狀況、社會結構與心態心理結構等範疇的探索,並著重於上述三者之間關係之分析。這樣一種在史學領域與主題的拓荒,直間促使了年鑑史家不但在客觀的心理上高舉打破學科界限的主張,也在歷史實踐的層次上引進、並運用諸如社會學、人類學、心理學等其他人文社會學科的觀念與方法,使得心態史寫作呈現出濃厚地社會科學取向。基於此,心態史具體且集中呈現了年鑑史學企圖建構「整體歷史」與從事「科際整合」的革新意義與特色。

    +

    其次,本文藉由布洛克《國王神蹟》一書當中具體的歷史實踐,進一步討論了心態史歷史寫作的特色與若干問題、缺陷。心態史歷史解釋的第一個特色即強調社會整體結構關係的歷史解釋模式,在整體追尋之下,心態史家在理史寫作上呈現出對於群眾物質生活、社會群體、精神狀態等人類群眾生活經驗三層次結構相互關係的注重。甚且,也同樣基於客觀歷史研究方法與觀念上的需求,呈現出科際整合的特色。第二,由於處理的主性質使然,使得心態史家以長時段的觀點從事其歷史的觀察與論述。其三,基於主題範圍的擴充,使得心態史家運用史料的種類、性質更趨多樣化,同時其中更隱含了史料觀念的革新。

    +

    然而,心態史的歷史寫作仍然引起了許多的批評。除了前文所探討的有關文化史寫作的問題、史料運用所引起的認識論上的問題之外,由於寫作主題的生活化,卻反而遭致論者所批評的「破碎化」的缺陷,並認為此一缺陷使得年鑑史家逐步遠離了年鑑學派企圖追尋「整體歷史」的初衷。116 雖然年鑑新生代史家企圖從理論、方法的層次嘗試修補心態史的缺陷與反駁來自論者的攻擊,呈現出理論化的趨勢。然而,卻無法迴避破碎化所引起的爭議,而此一方面的問題也仍值得更深入地探討。

    +

    然而,筆者必須坦承的是,限於篇幅與筆者的能力,並無法全面性地對有關心態史寫作諸多值得注意與思考的面向進行探討。除了上述所謂「破碎化」的相關問題,許多值得進一步探討的面向仍很多。例如,心態史所遭到批評除了對於歷史中事件與個人的忽略、缺乏對社會變遷的探索之外,也忽略權力關係的探討。

    +

    面對心態史歷史研究的問題,勒高夫曾經感嘆道︰「我們應該復興或者應該埋葬心態史呢?」筆者卻認為,值得挖掘的寶藏仍然非常豐富,猶待論者持續不斷地努力。

    + + + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +
    + +
      +
    1. Marc Bloch, The Royal Touch, trans. J. E. Anderson (New York: Dorset Press, 1961). 《國王神蹟》一書之法文原典的書名為《會魔術的國王們》 (Les Rois thaumaturges) ,而筆者採用的是 J. E. Anderson 所譯的英譯本 The Royal Touch 。由字面上的解釋應為「國王的碰觸」,而由江政寬先生所翻譯的《法國史學革命》一書當中,他將 The Royal Touch 一書翻譯為《神蹟皇帝》,筆者認為「皇帝」部分不妥,而用「國王的碰觸」又無法顯示出主題的「神蹟」色彩。因此,筆者決定採用《國王神蹟》之譯名。 (Back)
    2. +
    3. Georg G. Iggers, Historiography in the Twentieth Century: From Scientific Objectivity to The Postmodern Challenge (London: Wesleyan University Press, 1997), 3-8 ﹔ Geoffrey Barraclough, Main Trends in History (New York: Holmes and Meier, 1979), esp. chapter 2, 3; 有關歷史學與社會學的關係也可參閱 Peter Burke, History and Social Theory (Cambridge: Polity Press, 1992); 這一史學新取向之出現與史學專業本身內部的觀念之轉變、歷史現實上社會與文化的變遷都有相當的關係。在二十世紀初的美國,即羅賓遜 (James Harvey Robinson) 所帶領的「新史學」歷史研究。在德國,即蘭普希特 (Karl Lamprecht) 所引領的社會科學取向的政治思想史研究。在法國,就是由布洛克、費弗爾所創立的年鑑所主張的跨學科範疇的歷史研究。若要深究對於傳統政治、軍事史之質疑與挑戰,可追溯至十九世紀末,如布克哈特 (Jacob Burckhardt) 、米敘烈 (Jules Michelet) 與古郎治 (Fustel de Coulanges) 等史家的歷史研究取向。 (Back)
    4. +
    5. 彼得柏克 (Peter Burke) 在《法國史學革命:年鑑學派 1929-1989 》一書中指出,與其稱其為一個學派,不如說是「年鑑史學運動」。年鑑新生代的史家夏提爾 (Roger Chartier) 、雷凡爾 (Jacques Revel) 則如此形容:她如同一個不斷擴大的雲團、吸引各種不同知識菁英所形成的混合體。參閱 Peter Burke, The French Historical Revolution: The Annales School 1929-89 (Cambridge: Polity Press, 1990), 2, 117; 其他有關年鑑學派之論著,主要列舉如下: Philippe Carrard, Poetics of the New History: French Historical Discourse from Braudel to Chartier (Baltimore: The Johns Hopkins University Press, 1992); Francois Dosse, New History in France: The Triumph of the Annales, trans. Peter V. Conroy, Jr. (Urbana: University of Illinois Press, 1994); Traian Stoianovich, French Historical: The Annales Paradigm (Ithaca: Cornell University Press, 1976). (Back)
    6. +
    7. Iggers, Historiography in the Twentieth Century, 51. (Back)
    8. +
    9. Fernand Braudel, The Mediterranean and the Mediterranean World in the Age of Philip II, 2Vols., trans. Sian Reynolds (Berkeley: University of California Press, 1995). (Back)
    10. +
    11. 關於年鑑史家強調科際間知識交流的特色可參閱: Jean-Pierre V. M. Herubel, "The Annales: Its History and Evolution," in Annales Historiography and Theory: A Selective and Annotated Bibliography, Compiled Jean-Pierre V. M. Herubel (Westport, Connecticut: Greenwood Press, 1994), 1-13. 該作者從「科際整合」的角度概述年鑑史學的發展,他強調年鑑史家歷史寫作的所呈現出來的「科際整合」的趨勢。 (Back)
    12. +
    13. Dosse, New History in France, 55. (Back)
    14. +
    15. 勒高夫在其〈新歷史〉一文當中指出:「要拿出『問題性』的歷史,而不是『自然顯現的歷史』。」參閱 Jacques Le Goff, 〈新歷史(上)〉,《食貨月刊》,梁其姿譯, 12 卷 10-11 期 (1983) , 429 。 (Back)
    16. +
    17. 年鑑學派的主要特色之一即其長時段的歷史時間觀念,強調人之時間的相對性與多層次,如布洛克、布勞岱爾、勒高夫等史家都反應了此一特色。參閱 Iggers, Historiography in the Twentieth Century, 51 ﹔魏楓城,《年鑑史家的長時間觀︰以布洛克、布勞岱爾、雷瓦羅德里三人為討論對象》(臺中︰中興大學歷史學研究所, 1995 )。 (Back)
    18. +
    19. 有關布勞岱爾較為系統的三時段的歷史時間觀之論述,可參閱︰ Fernand Braduel, "History and the Social Sciences: The Longue Duree," in On History, trans. Sarah Matthews Chicago: The University of Chicago Press, 1980), 25-54; Fernand Braudel, "Personal Testimony," Journal of Modern History 44: 4 (Dec. 1972): 448-467. (Back)
    20. +
    21. Patrick H. Hutton, "The History of Mentalities: The New Map of Cultural History," History and Theory 20 (1981): 238; 另外,有關心態史歷史寫作的特色與問題可參閱: Roger Chartier, "Intellectual History and The History of Mentalites: A Dual Re-evalution," in Cultural History: Between Practices and Representation, trans. Lydia G. Cochrane (Cambridge: Polity Press, 1988), 19-52; Robert Darnton, "Intellectual and Cultural History," in Michael Kammen ed., The Past Before Us: Contemporary Historical Writing in the United State (Ithaca: Cornell University Press, 1980). (Back)
    22. +
    23. Darnton, "Intellectual and Cultural History," 337 (Back)
    24. +
    25. 從早期的布洛克與費夫爾,到第三代學者杜比 (George Duby) 、勒高夫、芒德魯 (Robert Mandrou) 、迪普龍 (Alphonse Dupront) 、阿里埃 (Philippe Aries) 、奧祖夫 (Mona Ozouf) 等。 (Back)
    26. +
    27. Burke, The French Historical Revolution: The Annales School, 1929-89, 70. (Back)
    28. +
    29. Dosse, New History in France: The Triumph of the Annales, 63; 此外,伏維爾 (Michel Vovelle) 也認為,心態史研究正反映了年鑑史家對於「整體歷史」此一理想的追求與實踐,可參閱: Michel Vovelle, Ideologies & Mentalities, trans. Eamon O'Flaberty (Chicago: The University of Chicago Press, 1990), 8. (Back)
    30. +
    31. 可參閱 Robert C. Rhodes, "The Revolution in French Historical Thought: Durkheim's Sociologism as a Major Factor in the Transition from Historicist Historiography to the Annales School: 1868-1945." Ph. D. diss., UCLA, 1974. (Back)
    32. +
    33. 有關心態歷史的意義及其發展可參閱︰ Philippe Aries ,〈心態歷史〉,《思與言》,梁其姿譯, 20 卷 4 期 (1982) , 57-73 ;梁其姿,〈心態歷史〉,《史學評論》,第七期 (1984) , 97 。 (Back)
    34. +
    35. 其他如夏特布里昂 (Francois Rene de Chateaubriand, 1768-1848) 、基佐 (Francois Guizot, 1787-1874) 的歷史著作中,也呈現出對於精神與文化層面人類事物與活動的重視。參閱︰ Jacques Le Goff, 〈新歷史(中)〉,《食貨月刊》,梁其姿譯, 12 卷 12 期, 1983 ,頁 462-465 。 (Back)
    36. +
    37. H. Stuart Hughes, Between Commitment and Disillusion: The Obstructed Path & The Sea Change 1930-1965 (Middletown, Connecticut: Wesleyan University Press, 1987), 22. (Back)
    38. +
    39. Le Goff, 〈新歷史(中)〉,頁 462-465 。 (Back)
    40. +
    41. N. D. Fustel de Coulanges ,《希臘羅馬古代社會史》 (La Cite Antique) ,李宗侗譯(臺北︰中國文化大學出版部, 1988 ),頁 3 。 (Back)
    42. +
    43. Pim Den Boer, History as a Profession: The Study of History in France, 1818-1914, trans. Arnold J. Pomerans (Princeton, N. J.: Princeton University Press, 1998), 242-246. (Back)
    44. +
    45. Jacob Burckhardt, Civilization of the Renaissance in Italy (New York: Random House, 1954); Hajo Holborn, "Introduction," in Civilization of the Renaissance in Italy, v-xi. (Back)
    46. +
    47. Johan Huizinga, The Autumn of the Middle Ages, trans. Rodney J. Payton and Ulrich Mamnitzsch (Chicago: The University of Chicago Press,1996), xix-xxi. (Back)
    48. +
    49. Frank E. Manuel, "The Use and Abuse of Psychology in History," in Historical Studies Today, eds. Felix Gilbert and Stephen R. Graubard (New York: W. W. Norton & Company, Inc., 1972), 214. (Back)
    50. +
    51. Lucien Levy-Bruhl ,《原始思維》,丁田譯(北京:商務, 1987 )。 (Back)
    52. +
    53. Maurice Halbwachs, On Collective Memory, trans. Lewis A. Coser (Chicago: The University of Chicago Press, 1992). (Back)
    54. +
    55. Norbert Elias, The Civilizing Process, trans. Edmund Jephcott. (Oxford: Blackwell, 1994). (Back)
    56. +
    57. Halbwachs, On Collective Memory, 5, 9-10. (Back)
    58. +
    59. Nicholas Rogers ,〈社會史中的人類學轉向〉,《走進歷史田野︰歷史人類學的愛爾蘭史個案研究》, Marilyn Silverman & P. H. Gulliver 編,賈士衡譯(台北︰麥田, 1999 ),頁 396 。 (Back)
    60. +
    61. 根據研究顯示,在 1969 到 1979 年期間,《年鑑》之中有關心理狀態、民間傳說、生活飲食習慣等心態史方面的論述,佔所有內容的 30% 。參閱︰ Nicholas Rogers ,〈社會史中的人類學轉向〉,頁 397 。 (Back)
    62. +
    63. Jacques Le Goff, "Mentalities: A History of Ambiguities," in Jacques Revel and Lynn Hunt, ed., Histories: French Constructions of the Past, trans. Arthur Goldhammer (New York: The New Press, 1995), 241-246. (Back)
    64. +
    65. Le Goff, "Mentalities: A History of Ambiguities," 242-243. (Back)
    66. +
    67. Marc Bloch, Feudal Society, trans. L. A. Manyon (Chicago: The University of Chicago Press, 1961). (Back)
    68. +
    69. George Duby, History Continues (Chicago: The University of Chicago Press, 1994), 71-72. (Back)
    70. +
    71. Lucien Febvre, The Problem Unbelief in the Sixteenth Century: The Religion of Rabelais, trans. Beatrice Gottleib (Cambridge, Mass.: Harvard University Press, 1982), 424; 費弗爾認為,每一個「文明」都有其當時代的心態器具,甚至每一個相同的文明中的任何一個時期,其心態器具基於其特殊的目的都會進行些許修正,而每一個文明或時期到其下一個文明或時期之間,並不一定能夠全面地轉變其心態器具。這些器具,可能經過退化、變形或更為進步、複雜。 (Back)
    72. +
    73. Vovelle, Ideologies and Mentalities, 5; 伏維爾在反省心態史研究時指出,芒德魯為心態史所下的定義是最佳的。 (Back)
    74. +
    75. Robert Mandrou, Introduction to Modern France, 1500-1640: An Essay in Historical Psychology, trans. R. E. Hallmark (New York: Holmes & Meier, 1976), 1-10. (Back)
    76. +
    77. Le Goff, "Mentalities: A History of Ambiguities," 245. (Back)
    78. +
    79. Jacques Le Goff, The Medieval Imagination, trans. Arthur Goldhammer (Chicago: The University of Chicago Press, 1988). 在該書中,勒高夫處理了中世紀人對於空間、時間、身體、文學與想像、夢等方面的觀念。 (Back)
    80. +
    81. Georges Duby, The Threes Orders: Feudal Society Imagined, trans. Arthur Goldhammer (Chicago: The University of Chicago Press, 1980); 關於此書之內容大意、特色與影響可參閱︰梁其姿,〈心態歷史〉,《史學評論》,第七期 (1984) ,頁 86-91 。 (Back)
    82. +
    83. Emmanuel Le Roy Ladurie, Montaillou: The Promised Land of Error, trans. Babara Bray (New York: Vintage Books, 1979). (Back)
    84. +
    85. Vovelle, Ideologies and Mentalities, 8. (Back)
    86. +
    87. 有關布洛克歷史思想之特色與影響方面概略性的論述,可參閱: Norman F. Cantor, Inventing the Middle Ages (New York: William Morrow & Co., 1991), 118-160; Carole Fink, "Introduction: Marc Bloch and World War I," in Marc Bloch, Memoirs of War: 1914-15, trans. Carole Fink (Ithaca: Cornell University Press, 1980), 15-73 。其中, Carole Fink 歸結出布洛克在歷史思想上的主要特色與概念分別為:心態 (mentalities) 、歷史實體 (historical reality) 、歷史決定論 (historical determinism) 、長時段 (longue duree) 、綜合的需求 (quest for synthesis) 等。另外,有關布洛克的思想與生平則可參閱 Carole Fink, Marc Bloch: A Life in History (Cambridge: Cambridge University Press, 1991). (Back)
    88. +
    89. Stoianovich, French Historical Method, 10-14. (Back)
    90. +
    91. Marc Bloch, French Rural History: An Essay on Its Basic Characteristics, trans. Janet Sondbeimer (Berkeley: University of California Press, 1966). (Back)
    92. +
    93. Roger Chartier, Cultural History: Between Practices and Representation, trans. Lydia G. Cochrane (Cambridge: Polity Press, 1993), 21; Dosse, New History in France: The Triumph of the Annales, 61-73. (Back)
    94. +
    95. Hutton, "The History of Mentalities: The New Map of Cultural History," 139. (Back)
    96. +
    97. Burke, The French Historical Revolution, 17. (Back)
    98. +
    99. Duby, History Continue, 4, 6, 10; Burke, The French Historical Revolution, 27. (Back)
    100. +
    101. Le Goff, "Mentalities: A History of Ambiguities," 243. (Back)
    102. +
    103. Dosse, New History in France: The Triumph of the Annales, 66. 布洛克與費夫爾的研究取向並不同,費夫爾比較注重心理和語言的層面 ; Aron Gurevich, Historical Anthropology of the Middle Ages, ed. Jana Howlett ( Cambridge: Polity Press, 1992), 27-29. (Back)
    104. +
    105. Bloch, The Royal Touch, 3. (Back)
    106. +
    107. Bloch, The Royal Touch, 3-5. (Back)
    108. +
    109. Bloch, The Royal Touch, 33. (Back)
    110. +
    111. Bloch, The Royal Touch, 149. (Back)
    112. +
    113. Bloch, The Royal Touch, 39-41. (Back)
    114. +
    115. Bloch, The Royal Touch, 91. (Back)
    116. +
    117. Bloch, The Royal Touch, 214-217. (Back)
    118. +
    119. Bloch, The Royal Touch, 29. (Back)
    120. +
    121. Bloch, The Royal Touch, 224. (Back)
    122. +
    123. Bloch, The Royal Touch, 3-5. (Back)
    124. +
    125. Dosse, New History in France: The Triumph of the Annales, 67. (Back)
    126. +
    127. Bloch, The Royal Touch, 4. (Back)
    128. +
    129. Bloch, The Royal Touch, 4. (Back)
    130. +
    131. Bloch, The Royal Touch, 30. (Back)
    132. +
    133. 姚蒙,《法國當代史學主流──從年鑑派到新史學》(臺北:遠流, 1988 ),頁 73 。 (Back)
    134. +
    135. Fink, Marc Bloch: A Life in History, 111. (Back)
    136. +
    137. 布洛克雖很少提及心態 (mentality) 一詞,但在書中頁 63 至少曾提及一次。此外,類似的字眼則出現了不少次,如頁 217 。 (Back)
    138. +
    139. Bloch, The Royal Touch, 214. (Back)
    140. +
    141. Bloch, The Royal Touch, 30. (Back)
    142. +
    143. Bloch, The Royal Touch, 46. (Back)
    144. +
    145. Bloch, The Royal Touch, 89. (Back)
    146. +
    147. Bloch, The Royal Touch, 100. (Back)
    148. +
    149. Bloch, The Royal Touch, 231-232. (Back)
    150. +
    151. Bloch, The Royal Touch, 236-240. (Back)
    152. +
    153. Bloch, The Royal Touch, 242-243. (Back)
    154. +
    155. Dosse, New History in France: The Triumph of the Annales, 66. (Back)
    156. +
    157. Bloch, The Royal Touch, 5. 布洛克在《國王神蹟》導論中明確的指出,本書採用了「比較歷史」的形式,以建構一個不同於傳統政治、民族史的解釋。換言之,比較方法是布洛克在進行《國王神蹟》一書論述時方法論之核心,他企圖透過比較方法的使用,對主題達成一不同於傳統敘述方式的歷史解釋。比較方法的使用,一向是布洛克從事歷史研究的特色,他也曾就這個方法提出他個人的理論建構。關於布洛克比較方法的理論,可參閱: Marc Bloch, "A Contribution toward a Comparative History of European Societies," in Land and Work in Mediaeval Europe, trans. J. E. Anderson (New York: Harper & Row, Publishers, 1969), 44-81; Geoffrey Barraclough, Main Trends in History (New York: Holmes and Meier, 1979), 168-176; Natalie Zemon Davis, "History's Two Bodies," American Historical Review 93: 1 (1988): 18-30; Allette Olin Hill and Boyd H. Hill, " Marc Bloch and Comparative History," American Historical Review 85: 4(1980): 828-857; W. Sewell, "M. Bloch and the Logic of Comparative History," History and Theory 6 (1967): 206-218; Lawrence D. Walker, "A Note on Historical Linguistics and Marc Bloch's Comparative Method," History and Theory 19 (1980): 154-164. (Back)
    158. +
    159. Theda S. Skocpol, "Sociology's Historical Imagination," in Vision and Method in Historical Sociology, ed. Theda S. Skocpol (Cambridge: Cambridge University Press, 1984), 1-21; Theda S. Skocpol, "Emerging Agendas and Recent Strategies," in Vision and Method in Historical Sociology, 356-391; Daniel Chirot, "The Social and Historical Landscape of Marc Bloch," in Vision and Method in Historical Sociology, 22-46; Dennis Smith, The Rise of Historical Sociology (Cambridge: Polity Press, 1991), 41-53; 另外,有關於布洛克歷史思想與涂爾幹社會學派思想之相互關係,可參閱 Susan W. Friedman, Marc Bloch, Sociology and Geography: Encountering Changing Disciplines (Cambridge: Cambridge University Press, 1996), 110-133. (Back)
    160. +
    161. Friedman, Marc Bloch, Sociology and Geography: Encountering Changing Disciplines, 6, 74, 93-96. 史特拉斯堡大學在高等教育體制之架構下,成為法國一次大戰後舉足輕重的一所大學,享有極大之資源,並在當局強調革新的精神中形成強調「科際整合」的學術風氣,而布洛克與費弗爾便在此一環境中成立了以打破學科界線、革新史學的年鑑期刊;此外,值得注意的是,布洛克與費弗爾皆曾待過的梯也爾基金會 (Foundation Thiers) 亦鼓勵學生科際整合取向的研究;亨力貝爾 (Henri Berr) 在 1900 創立《歷史綜合雜誌》 (Revue de Synthese Historique) 可謂之《年鑑》先驅者;另外,有關貝爾的歷史思想、創立雜誌的宗旨及其與年鑑學派之關係可參閱︰ Martin Siegel, "Henri Berr's Revue de Sythese Historique," History and Theory 9 (1970) : 322-334. (Back)
    162. +
    163. Francois Dosse, New History in France: The Triumph of the Annales, 66. (Back)
    164. +
    165. Marc Bloch, "Technical Change as a Problem of Collective Psychology," in Land and Work in Mediaeval Europe, 124-135. (Back)
    166. +
    167. Bloch, Feudal Society, 72-73. (Back)
    168. +
    169. Eric Hobsbawm, "From Social History to the History of Society," in On History (New York: The New Press, 1997), 81-82, 92. (Back)
    170. +
    171. Marc Bloch, The Historian's Craft, trans. Peter Putnam (New York: Vintage Books, 1953), 25-26. 布洛克在《史家的技藝》曾說過這麼一段話:「很久以前,我們偉大的前輩,如米敘烈或古朗治,確曾教導我們認識到歷史的對像原本就是人。我們毋寧說是多數的人……在地理景觀的背後、在工具器械的背後、在看來最形式化的文件背後,以及在看來幾乎已完全背離其創建者的制度背後,就是人本身。 (Back)
    172. +
    173. Bloch, The Royal Touch, 30. (Back)
    174. +
    175. Bloch, The Historian's Craft, 34. (Back)
    176. +
    177. Chartier, Cultural History: Between Practices and Representation, 20. 史家 Robert Darnton 將以人類學方式進行世界觀與集體心態的研究歸類為文化史的範疇。另外,有關德國精神史、美國思想史與法國心態史之比較,可以參閱: Ernst Schulin, "German 'Geistesgeschichte', American 'Intellectual History' and French 'Histoires des Mentalities' Since 1900: A Comparison," History of European Ideas 4: 3 (1981): 195-214. (Back)
    178. +
    179. Hutton, "The History of Mentalities: The New Map of Cultural History," 242. (Back)
    180. +
    181. Duby, History Continues, 73-75. (Back)
    182. +
    183. Lynn Hunt, "French History in the Last Twenty Years: The Rise and Fall of the Annales Paradigm," Journal of Contemporary History 21 (Apr. 1986), 212-215. (Back)
    184. +
    185. Roger Chartier, The Cultural Origins of The French Revolution, trans. Lydia G. Cochrane (New York: Duke University Press, 1993), 6-7, 16-17. (Back)
    186. +
    187. Mona Ozouf, Festivals and the French Revolution, trans Alan Sheridan (Cambridge, Mass.: Harvard University Press, 1988); Joseph F. Byrnes, Review Essays of Festivals and the French Revolution, 113. (Back)
    188. +
    189. Bloch, The Historian's Craft, 66. (Back)
    190. +
    191. Huizinga, The Autumn of the Middle Ages, 9, 27. (Back)
    192. +
    193. Bloch, Land and Work In Medieval Europe, 72. (Back)
    194. +
    195. Bloch, The Royal Touch, 58-59. (Back)
    196. +
    197. Bloch, The Historian's Craft, 91. (Back)
    198. +
    199. Bloch, The Historian's Craft, 64. (Back)
    200. +
    201. Bloch, The Royal Touch, 13,14,15,18,41,57,59,87,110,146,224; 可見布洛克在質疑、批判並解釋史料之例子。 (Back)
    202. +
    203. Bloch, The Historian's Craft, 63. (Back)
    204. +
    205. Adrian Wilson ed., Rethinking Social History: English Society 1570-1920 and its Interpretation (Manchester: Manchester University Press, 1993), 306. (Back)
    206. +
    207. Bloch, The Historian's Craft, 68. (Back)
    208. +
    209. Vovelle, Ideologies and Mentalities, 28. (Back)
    210. +
    211. Bloch, The Historian's Craft, 39. (Back)
    212. +
    213. Vovelle, Ideologies and Mentalities, 8. (Back)
    214. +
    215. Bloch, The Royal Touch, 110, 112, 114. (Back)
    216. +
    217. 有關心態史歷史解釋的缺陷之全面性探討,可參閱︰ Peter Burke, Varieties of Cultural History (Cambridge: Polity Press, 1997), 170-175. (Back)
    218. +
    219. Chartier, Cultural History, 37-39. (Back)
    220. +
    221. Mikhail Bakhtin, Rabelais and His World, trans. Helene Iswolsky (Bloomington: Indiana University Press, 1984), 58. (Back)
    222. +
    223. Chartier, Cultural History, 39. (Back)
    224. +
    225. Michel de Certeau, The Practice of Everyday Life, trans. Steven F. Rendall (Berkeley: The University of California Press, 1984), xi-xxiv. (Back)
    226. +
    227. de Certeau, The Practice of Everyday Life, 165-76. (Back)
    228. +
    229. Chartier, Cultural History, 43-45. (Back)
    230. +
    231. Hunt, "French History in the Last Twenty: The Rise and Fall of the Annales Paradigm," 213-217. (Back)
    232. +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/002/article04.html.html b/htdocs/htc/newsletters/002/article04.html.html new file mode 120000 index 0000000..ad4a043 --- /dev/null +++ b/htdocs/htc/newsletters/002/article04.html.html @@ -0,0 +1 @@ +article04.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/002/article04.html.xhtml b/htdocs/htc/newsletters/002/article04.html.xhtml new file mode 100644 index 0000000..2fd464e --- /dev/null +++ b/htdocs/htc/newsletters/002/article04.html.xhtml @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + + + + +安可史密斯論心態史研究 + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    安可史密斯論心態史研究

    + +
    黃明田
    + +

    本文意圖處理當代「心態史」歷史實踐在歷史理論層次上的研究意義,這裡將以安可史密斯 (F. R. Ankersmit) 敘述主義 (narrativist) 觀點探討。一般說來,「心態史」是近來法國年鑑學派 (Annales) 第三代史家諸如勒高夫 (Jacques Le Golf) 、杜比 (George Duby) 、拉杜瓦 (Emmanuel Le Roy Ladurie) 等主張的新歷史研究趨向,他們主張歷史的研究對象,是生活在過去男人和女人的思考、感覺和經驗,探討他們的行為傾向、集體歷史中的無意識層面,這包括了孩童、母親、家庭、愛、性和死亡的歷史主題。然而,此處所提出欲探討的「心態史」範圍並不限於法國年鑑學派,還包括一些新文化史的寫作,諸如卡羅.金茲伯 (C. Ginzburg) 的《起司和小蟲:十六世紀磨坊主的宇宙》、大衛斯 (Natalie Z. Davis) 的《馬丁‧蓋爾的歸來》 (The Return Martin Guerre)1 等等。以安可史密斯的敘述主義觀點,此心態史的研究趨向在歷史理論的思考上適時反映了後現代主義歷史寫作的向度。

    +

    這包括了心態史研究趨向,在於尋找過去歷史寫作未曾發覺「粗野的」 (raw) 的歷史領域,即未曾被顯現的歷史,並且此歷史往往異於已寫的歷史。其次,視歷史寫作是對過去的實在再現 (representation) ,此再現展示出一種「實在效應」 (effet de reel) 的動力化 (dynamization) ,即每一個時代擁有自身的再現策略,表達他們對過去實在的看法。再者,不在歷史寫作中舖陳宏觀和歷史連續的脈絡、不承認歷史寫作是再現過去實在而是再現自身,再現自身產生於史家歷史經驗的「差異」 (difference) 邏輯,即歷史再現反映的過去實在,永遠不是真正的過去而是不斷與過去實在(前人的歷史實在)呈現差異。以下我們分別論述之。

    + +

    一、

    + +

    安可史密斯認為歷史「再現」的名稱,被視為第三字彙以區別於「描寫」與「解釋」(後者指 1940 年代後的現代歷史學的使用字彙,如覆蓋律 (covering-law model) 和「意義」與「詮釋」(分析詮釋學 (Analytical Hermeneutics) ),在於避免指涉過去實在(雖然「再現」的在以往的用法也傾向指涉實在)。此外,安可史密斯對「再現」字彙的運用,受到當代對於藝術哲學的新見解的啟發。即畫家呈現一幅風景畫、一個人或其他事物等,藝術哲學家視畫家藝術的再現對象,不再是被再現的實在自身而是異己 (alien) 之媒介自身,以界定異己之媒介物表達的名稱。此種看法也可以在當代藝術哲學家古德曼 (N. Goodman) 身上看到。古德曼曾指出沒有比自身更相像自身,因而圖像總是比它們欲再現的對象較相像於其他之物。此段話表達出圖像的再現通常不是被再現物自身,而是另一個可能的實在。如同當我們說一個拿破崙的再現,意味著展示相像於當他活著時候的狀態,我們通常以另一物(文本或圖像)代替欲再現的對象,以此說再現自身相像 (resemblance) 於被再現之物,不過另一物永遠不是活著的拿破崙。此中我們可以看到我們必須承認再現與被再現兩者的個別存在,另一方面又以為再現之物是被再現自身視為同一的,並且是同一在被再現物自身。但是,古德曼通常將其同一性的方向轉變到再現自身,認為再現不是處理相像而是另一物,此另一物就是再現的詞句意義 (denotation) (即再現自身)。2

    +

    到貢布里希和丹圖研究藝術的根源時的「替換理論」,則進一步要求一個再現非參照人像模型的出現。按照安可史密斯的理解,當我們創造出一個「人像模型」 (dummy) ,能歸納大部分真正真實於拿破崙的「過去實在」觀念時,我們也會產生出另一個「人像模型」,如「敘述實體」 (narrative substance)3 的觀念,而後者的「人像模型」就是再現非參照人像模型,此非參照的人像模型產生於另一個拿破崙「過去實在」的人像模型,而不是真正真實的拿破崙自身。尤其當我們擁有很多的拿破崙文本或圖像時,原本歸納大部分真正真實於拿破崙的「過去實在」觀念之「人像模型」,以及如「敘述實體」觀念的「人像模型」,事實上兩者已經沒有差別地僅能是那些「人像模型」下歸納的屬性或性質,能給於我們認識「拿破崙」這個名稱,而不再是真正的拿破崙。也就是將這個「人像模型」放在陳述的語言使用之中來說,拿破崙被視為一個主題,僅是一個邏輯人像模型,其表達的作用僅在於「述語」,而此「述語」指涉「拿破崙」的主題,而不是指涉實在自身的性質。但是這些模型是一個假定再現可能性的必須之物,能允許我們只展示(歷史)實在在一個異己媒介物之中,但不是過去實在自身。也就是說,異己媒介再現的與被再現的實在是不能轉換,根據丹圖的再現觀點是邏輯地放置實在在遠處。4 其意為所處理的不是被再現的對象,而是一異己媒介物自身。被再現的對象作為一個實在觀念,其內容是再現給予的而不是外在於再現的實在自身,因此再現是對立 (opposite) 於實在自身。安可史密斯認為這種藝術的再現觀點,同他的敘述主義的歷史學是一致的。他假定「敘述實體」的語言邏輯實體,它就是歷史實在的再現,而不是歷史實在自身。5

    +

    此外,安可史密斯思考當代美學有關藝術品本體論地位的問題討論中,大部分藝術哲學家不是希望識別藝術品的美學特徵在它的物質方面,「他們已經受到假定一個特別的非物質「美學對象」的引導,去推想藝術的真正工作和美學特質的持有者,這個假定實際上變成二十世紀美學的信條。」6 從這藝術對象物質化的拋棄當中,亦是反應藝術的解美學化觀點,此解美學化觀點指著是拋棄以往對藝術品物質特徵的觀念論述。因此,解美學化觀點造成美學對象的觀念不再有任何在藝術品中的支持點,一個美學對象遠離再現它的顏料和桌布來傳達一個圖像的美學意義。傳統上,藝術的再現總是需要一個異己媒介物以表達自身,在美學對象逐漸消失之中只有藝術再現的純粹觀念保留,以及用這個純粹的觀念來識別現成物 (ready-mades) (藝術原作品)和它們較多常見的相似物(複製品),明顯展示這個純粹的觀念在一個弔詭的方式中。也就是說,以藝術品保留下來的純粹觀念來看藝術品的價值,原作和複製品同樣擁有它藝術上的價值,如此導致原作和複製品沒有差別。另外這個藝術再現的純粹觀念,也是以一個邏輯的「人像模型」(前兩段所提)涉及所有藝術再現,以證明現成物和相似物之間沒有不同,7 以致於必須尋求這些藝術品(原作)其藝術再現的特有價值,以區別於複製品的價值。

    +

    在此,藝術哲學家看待藝術品的物質方面,傾向於藝術價值的實質化 (substantialize) ,也就是藝術品(原作)其藝術再現不再僅僅是為了完成一個實在錯覺的意義,也不是一個似玻璃的銀光幕我們能看透它,而是傾向於拉引觀眾的注意在它們「粗野的」和非詮釋的實質特性,不然我們無法肯定原作的價值不同於複製品。現代藝術作品展示回歸它的實質特徵的傾向,可從丹圖引領我們注意現代畫家的作畫筆法,而不是一個任何東西的再現可以得知它的價值。我們不再看透藝術替換的媒介指涉外在的實在,而是只有看它們(再現自身)「粗野的」和非詮釋的實質特性。

    +

    對於現代藝術的價值在於它們「粗野的」和非詮釋的實質特性,安可史密斯認為在現代的歷史學心態史中也可被發覺。像拉度瓦的《蒙大猶》、金茲柏的微觀故事或大衛斯的《馬丁‧蓋爾的歸來》所從事的歷史實踐被視為代表歷史學的後現代主義傳統,表達出過去實在的歷史再現是在現自身而不是實在自身。這些著作從歷史學的特定觀點,我們可以發現在他們的文本中有一個語言的裝置,歷史家允許語言裝置在敘述話語的異己媒介裡,去創造的一個過去實在的錯覺。此語言裝置,安可史密斯認為是他類似藝術再現的美學對象到歷史學所得到的理解。將此種後現代主義的歷史學與一般歷史家日常傳達給他的觀眾,一種具有意向主義論題 (intentionalist theses) 的過去(筆者認為即脈絡化的歷史,暗含某種歷史發展史觀,如同藝術品的純粹觀念)相較,此時具有意向主義論題的過去在後現代主義歷史學中逐漸消失,同藝術中美學對象的消失一樣。例如金茲柏的《小蟲和起司》中麥派諾西歐 (Menocchio) 的故事,麥派諾西歐的想法,我們不能裝置他十六世紀時期的成套心態 (outillage mental) ,亦無法由他來解釋十六世紀的時代狀態。因此上述心態史形成的歷史學再現只有它自身,它們擁有一個自我參照的能力,相似於有關的現代畫家使用的表達意義。這裡表明藝術和歷史學,最近的發展之間一條顯著的對應,可以增進我們的洞識。8

    + +

    二、

    + +

    安可史密斯對此現代藝術的美學性質之討論,促成其對心態史歷史寫作的性質是外在於康德主義框架,並且是對一個先驗主義的挑戰的美學主義觀點。一般所言的認識論,由於莫不關心我們是否處理關於實在或它的美學再現,更無對再現自身的主體即歷史經驗提供說明,常常視實在為客觀存在的事實。這種自笛卡兒以來在西方哲學的主流中,常以一個先驗(歷史)主體,保證可依賴的(歷史)知識,引導一個(歷史)對象或知識的固定,此種認識論的固定因此刺激本體論的固定,促使過去實在的觀念,不變的和存在的獨立於歷史家,可以被當作一個對象研究;9 再者,(歷史)文本被視為傳達過去實在的透明體,一個非污染、先驗的認知主體「經由文本」,可以尋找到位於它背後的過去實在,也一直被認為是有智識的。

    +

    以上兩者就是歷史寫作的美學主義觀點要挑戰的地方,首先將歷史文本所建構的歷史世界,當作一個文本或語言的問題,10 意即歷史文本再現的不是過去實在(被再現物)而是再現,再現自身涉及歷史經驗主體歷史家,對過去實在的詞句意義的表達,此表達是當代文化世界的一部份,也就是歷史寫作的文化意義;11 其次,此種文化意義所顯現對歷史文本的處理,否定歷史文本的透明性,而去注意它的衝突、躊躇、曖昧及情緒矛盾之處,亦即顯示文本非透明自身,這使我們能朝向一個新歷史學的向度。12 此中的歷史寫作文化意義,關聯於歷史學方面和落實於歷史實踐的方面。安可史密斯意圖表明他從美學主義觀點,一方面來自於其它當代藝術領域理論思考,展開對歷史學或歷史理論特定觀點的形成;另一方面也是從當代歷史寫作實踐中進行反思(特別是心態史)。安可史密斯相信這兩方面的連結,可以為我們呈現前面所講著新歷史學的向度,就是後現代主義歷史學的發展。本節欲探討安可史密斯「實在效應」的理論和實踐兩方面,了解他如何處理「過去實在」觀念的問題,以展開新舊歷史學的不同和新歷史學見解。

    +

    對於過去實在問題的較舊途徑探討,安可史密斯認為二十世紀以來,歷史哲學中,過去實在被處理在歷史陳述和文本,或歷史詮釋和敘述性的討論裡,論題(史家理解歷史的語意自身)在一個整體中是被忽視的一個,而繼續維持過去實在的存在獨立於我們,即區分外在過去實在和歷史文本的歷史實在。13 諸如克羅齊 (B. Croce) 在他的「激進歷史主義」的脈絡中防衛過去實在,他像黑格爾 (G. W. F. Hegel) 一樣,以精神 (The Spirit) 形成歷史立說,一方面過去的實在變化一如精神的成長,另一方面在一些現在關心的基礎上,實在現在所變成的是現在自身的部分,現在的歷史家使過去活的。簡言之,過去的實在變化於歷史的改革與我們關於它的觀念或思考的變遷中產生變化。柯林烏重演的處置要求歷史家重建過去,過去因此移轉到現在和失去它的過去特性,不過重演的裝置只是轉移現在的無時間觀念,以及不是放置在過去的一個思考行動。但是,克羅齊和柯林烏都沒有回答過去實在的問題。到了被稱為建構主義的歷史哲學家如歐克秀 (Michael Oakeshott) 、格特史登 (Leon Goldstein) ,過去實在依然不被否認在歷史寫作中的實踐意義,歷史家在它的文獻基礎上「建構」它的過去形象,但是如此的想像只能被比較於它們自身之中。對建構主義來說,過去實在自身是一個可以比較的對象,關於實在的背景是毫無問題的。以上安可史密斯所舉的例子,他認為都視過去實在的存在獨立於我們,依戀於西方哲學傳統中的先驗主義架構。14

    +

    然而,安可史密斯從羅蘭‧巴特關於(過去)實在再現的觀點出發,提出一個十分不同而具有新意的途徑。這來於巴特視文本是擬自然 (quasi-natural) 實在的創造者,而不是意識型態的反映。因此強調過去實在必須被連結於一個被稱為「實在效應」的東西,此「實在效應」言及於歷史文本中被創造於(文本中)無關的細節。過去實在在歷史文本中是一個效應,經由在歷史文本中和文本之間的一個張力 (tension) 所造成。15 巴特認為這些細節的性質,來自於被稱為過去實在的(使用特殊記號、文字的)「符號法」。在歷史文本中除了符號法外,巴特還在文本中標示「述語」一詞,它是由歷史家察覺或創造的意義 (meaning) 。巴特認為「『歷史事實』想要存在,我們必須先引入意義」(尼采語),16 因此述詞和符號法在歷史文本之中同時擁有類似的張力,只不過此張力造成文本的實在效應外,還產生意義的部分。在述詞和符號法兩者的關係中,符號法使過去顯示自身一如它真正是的,「非虛飾的實在『再現』,一個無遮蔽的說明『什麼是』 (what is (or was)) ,因此看來像一個意義的反抗,這個反抗加強逼真的和可理解的之間最大的如神話般的對應」;「換句話說,在被稱為客觀的歷史中,真實不僅僅是一個非系統陳述的意指 (signified) ,虛擬在有力量的背後也是明顯地現存的參照,這個狀態定義一個可以被稱為實在效應的東西。」17 然而,不像「什麼是」由符號法表達出來,述詞中產生的意義是被建構的所以不能達到實在效果,不過符號法能形成實在效應只有經由對比述詞和意義焉能形成。18

    +

    再者,安可史密斯強調符號法的形成出處,不是在文本中描寫和過去中的事物之間一個超出文本之外的關係,或者形成在歷史文本中真實的陳述裡,而是產生在文本自身之中的實在效應。19 此意為我們不是分析一個先前地給予的歷史實在(意指物),而是首先定義什麼是由符號法表達的實在,因此歷史實在不是一個資料,而是一個由實在效應創造的常規。20 簡單地說,我們必須先標示什麼是歷史實在或真實的表達方式,而使一個實在效應發生在歷史文本中,以構成一個歷史實在。往常認為歷史實在首先我們必須訴諸於一個普遍上可認知的歷史對象,像法國大革命或民族國家的形成,我們必須經由持續地比較歷史原典 (original) 和我們對它的描寫,嘗試所有可能正確地去描寫其實在。安可史密斯認為這種說法不是事實,因為它要求歷史家的歷史文本必須緊密的相像於它的原典,但是由於表達實在的語言說辭太複雜了,我們可能用種種不同的語言組織表達實在的說辭,因此無法保證這些說辭誰較接近真實。實際上在我們對歷史的問題和歷史討論中,首先應該考慮到的是什麼應該被視為法國大革命或民族國家的形成的事實表達方式,21 能使歷史文本產生一個實在效應才是重要的,而不是原典證據的陳述字面所顯示的事實。

    +

    相反而言,歷史文本在確定的限制裡的確有創造一個過去實在的能力。安可史密斯回顧傳統實在主義的過去觀點,發現到最近由澳洲歷史哲學家邊罕‧麥古里重新開始。麥古里 (Behan McCullagh) 認為一個過去的實在,一如我們發現在每天生活中環繞我們的事物資料,這個過去的實在由各式各樣的成分,如行動、事件、歷史過程等組成,可以作為歷史研究的對象。只要使用能讓這些研究對象順從我們發展出數目眾多的模式和規則,就可達到「過去的平實再現」。22 安可史密斯認為如此說法是樸素的實在主義觀點,懷著一個歷史再現相像於原典的心態。不過,安可史密斯認為麥古里的說法倒也指出保證實在主義實在效應的基礎在於這些的模式。正如古德曼所說「實在主義是相關的、決定於在一個給予的時代中一個被給予的文化或個人,所給予的代表性 (representative) 標準系統。」23 此中說明出過去的實在是由這些代表性的標準系統之模式給出符號法,而產生出的一個實在效應。

    +

    但是,安可史密斯認為在這些再現標準系統的模式給出的實在,其所形成的歷史再現事實上是沒有參照的「框架」 (frame) ,也就是說這裡有許多的代表性的再現模式,他們所有的實在觀點沒有一個可以說是最後或最基本的實在。以致於過往的思辨歷史哲學家,像馬克思和黑格爾等一直不斷的要尋找這個框架。24 那麼此「框架」是否也如同「符號法」產生實在效應決定我們歷史實在的表達呢?以及過往思辨歷史哲學家尋求歷史的框架,是否表明我們歷史實在表達的框架處於不斷變化中呢?安可史密斯對於此「框架」的問題,他求諸於視覺藝術以顯示歷史寫作的情況,他分成形式和內容兩方面來說。在前者,安可史密斯從夏皮歐提出傳統繪畫中包含一些非模擬的成分產生對「框架」的說明,安可史密斯主張此成分不是世界自身的對照物,而是大部分繪畫的長方形形式即一個圖畫的框架。這個圖畫的框架就是有效的產生什麼是圖畫意義的象徵,安可史密斯以此類推於歷史寫作,主張一個歷史文本再現世界的部份,也必須在一個由再現定義的一個空間之內表達出來,因此歷史文本的框架形成一個本質的貢獻在它的意義。換句話說,「框架」大大地決定我們過去實在的觀念。進一步地說,當歷史家希望比早期一代的歷史家較深的滲透過去實在而不做一個較舊的代表性策略,至少其部分是受一個永遠企圖去成長或擴展這個框架的刺激,並且以一個較新的歷史性質當作一個較深地滲透過去實在,通常真正是反轉較舊的代表性策略,即將過去的空間置換為閱讀者現在空間的方向,因此「框架」是過去和現在之間的轉淚點,一如標示著兩者的邊界和因此「框架」組成什麼不是以往隸屬於歷史細察的實在表達。相對來說,這也說明「框架」組成「什麼是」的實在,來於每一個歷史研究階段他們感覺是擬自然的表達實在。這個歷史寫作成長在它的框架的企圖,正說明了一個擬自然符號法的歷史化領域,也就是說過去實在的實在效應,只有在擴展框架的動力化(過去實在的歷史化)之內變成視覺化為各時代所接受。此動力化說明出標示繪畫藝術和歷史寫作形式的性質。25

    +

    依此繪畫藝術和歷史寫作形式的動力化性質,安可史密斯繼續談及「框架」的內容方面,他從貢布里希總結風景畫起源的觀點談起,貢布里希認為十五世紀風景畫的主題從宗教和神話學到自然主義的改變運動,不是由一個新的意義中心的引力,而寧願是在至今仍沒有意義的方向中的運動。安可史密斯將貢布里希的觀點放在歷史寫作的變化中,說明歷史寫作的改變不是一個滲透被給予的歷史對象逐漸地較有深度,而是一個前者的意義中心在較早期的施予之下,退讓給似乎是現在無意義和不相關的持續過程。安可史密斯認為這個可以從過去各種歷史主題研究看出這一點,從奧古斯丁宗教觀的歷史、啟蒙運動信仰在進步、拯救歷史的世俗化、黑格爾提供一個關於這個進步觀念壯麗的哲學基礎、較緊密於人類存在的符號法,豎起蘭克和歷史主義民族的歷史、一個新層次的符號法精確地思考不相關,經由馬克思和社會主義者普及的社會和經濟史引出、經由法制史、體制史、地理和氣候史(布勞代爾和拉度瓦),我們最後在過去十年至二十年轉變至心態史的研究,則需求一個日常生活歡樂和悲傷、大和小的歷史尺度。這個過去較新或符號法較新的範疇,是一個朝向我們運動的旅程。它不是一個較深入地滲透進歷史對象,在每一個符號法層次的意義,可以被敲進解釋先前的一個。也就是思想使不能解釋宗教史,經濟使不能解釋思想史,心態史不能解釋政治史。如此我們可以說沒有永恆的歷史對象,歷史對象總在符號法和意義之間的對應之內遭受一個持續的變形。26

    +

    以上所談的過去實在效應,除了說明過去實在的歷史化發展外,更重要的是實在效應被看作是對於過去實在的觀念,使歷史寫作展現在「框架」的成長裡,傾向從現在的實在中分離過去實在,其意為傾向將歷史文本中的歷史意義抹去,其消除的就是前文所說獨立於我們存在的過去實在觀念。並且實在效應的提議,證明過去實在與(每一個)現在史家的經驗是統一的(而不是歷史自身可以形成統一,如「普遍史」),表明過去實在要成為史家歷史中實在,必須是史家當下使用的「符號法」或「框架」能表達實在的方式,而不是過去實在自身使然。安可史密斯認為這個「實在效應」的觀點再一次能從心態史研究包括微觀故事、兩性 (gender) 史等式樣,為我們提供最相應的證據。金茲伯《小蟲和起司》中對宗教裁判的專注,產生有吸引力的以非正統觀點給予我們十六世紀末一位磨坊主的歷史;大衛斯《馬丁‧蓋爾的歸來》中告訴我們一位聰明的冒充者,許多年來令人信服地設法達成,取代一位已經消失丈夫的故事。他們建立的不僅是那個時代主要事件中不為人知的歷史,似乎也是缺乏那個時代的標誌,並且這個故事也可發生在許多世紀之前或之後精確地相同的方式。因此,一如巴特所使用的用語,所謂歷史的意義已經消失和每一件事情都變成符號法。這樣的歷史寫作方式,使處理的過去不再是過去自身,而是關於過去和其寫作的歷史再現自身之間的邊界,一個重構過去和過去的發明之間的重疊,以及歷史對象的輪廓被溶解在一起,展現出理論和歷史奇特的混合形式。27

    +

    而在心態史和兩性史方面,尤其是心態史的確提供一個不同於過去的圖像。心態史主要由法國的歷史家發展和實踐,其焦點在生活在過去男人和女人的思考、感覺和經驗,探討行為傾向、集體歷史最主要的無意識觀念,包括孩童、母親、家庭、愛、性和死亡的歷史。這樣的研究方式打破一般的歷史實踐,來自於對過去歷史性邊緣化的癖好。28 從法國史家博貝勒 (Michel Vovelle) 《意識型態和心態》 (Ideologies & Mentalities) 一書,29 我們可以看出心態史研究相似於巴特,關於意義和符號法之間的對比。博貝勒從意識型態和心態對比,認為心態史研究過去的思考、感覺和經驗世界,不能由馬克思主義意識型態探討歷史作用者的類型,獲得的歷史意義所能理解。這來於心態史的領域由這樣的符號法層次組成,此層次指著是「一個寂空形式的記憶 (a memory of empty form) 」來描述一個心態。這個形式也就是關於「心態結構惰性 (inertia) 」的「反抗的形式」,其較重要的是關於「這些非系統陳述的心態實在,那些明顯地是『無意義的 (meaningless) 』,和那些在無意識動機的層次裡,引導一個秘密的存在。」這個無意義的心態實在,被當作一個佈景 (decor) ,填入符號法的層次內,意味著 (denote) 直接地面對真實。安可史密斯認為博貝勒這裡所談的「無意義的心態實在」與巴特認為的「具體細節 (concrete) 」(或「現存環境的具體性」),「總是被揮舞著當作一個武器反對意義,彷彿什麼是真正存活的,有一些無可置辨的法則不能表示─和相反亦然。」30 可以符號法直接標示,形成歷史的實在效果。

    +

    從心態史裡,安可史密斯看到歷史寫作的過去實在觀念,同在巴特身上看到的是,這個過去實在不是過去史家尋找還未曾發現的實在,在已被認為的歷史實在,將之視為進一步的延伸或更深入化,而寧願是形成另一種不同以往的過去實在,以不同的符號法,另外呈現一個過去的實在效果。並且這個實在對比於以往史家,是後者認為無意義的過去實在,以現在以為的符號法,去超越較早期形成的歷史述詞和意義。這樣的歷史寫作實踐方向就是:

    + +
    +

    在過去兩個世紀中,歷史家創造一系列或多或少複雜的思想結構,在這些觀念的形式,像族群、國家、民族、社會階級、社會結構和思想運動等,具體表達過去和現在之間的距離。在這些名稱和其他的觀念中,過去被永久地分析在它的不同於現在的特性。形成我們總是談論一個確定的族群、一個確定的民族、社會階級的歷史等等─不可懷疑地主張過去和現在之間的持續性。形成我們忘記過去在這些觀念的覆蓋下以明確地脫離現在。這些觀念被證實是歷史家有用的工具和他們應該放棄它是不可思考的。它們使我們給過去一個意義和決定在歷史過程中我們擁有的位置‧

    +

    然而心態史和兩性史已經升起一個歷史形式,是莫不關心和或許甚至是敵視這些名稱的觀念。在符號法優先地接管意義的地方,這些觀念不再被接納。在符號法中,意義的認識是一個名稱上的矛盾。在心態史中,特別是兩性史,現在和過去之間的邊界因此被弄亂的。我們在心態史裡關心我們的中古或現代祖先,較少不同於我們和一個獨特的鄰居或同事的關係。……這或許也解釋心態史流行於一大群非歷史家的觀眾。31

    +
    + +

    從以上微觀故事、心態史和兩性史代表的後現代主義歷史寫作,安可史密斯認為這些歷史研究,都展現一種實在效果的動力化,歷史的實在是被創造於歷史中,已存在的代表性策略,產生一個意義和符號法之間的對應。關於這已存在的代表性策略來源,是本節前面所談認識論莫不關心的地方,再現自身和創造再現的主體(歷史家)之間的關係,是面對自身的文化狀態下的歷史經驗所決定,而不是自有一套先驗主義的東西,即第三物或圖式,可以決定或定義過去實在的性質。32 對安可史密斯來說,一個新的歷史學方向,從上面所提的當代心態史的實踐,可以證明推翻來自實證主義歷史理論的先驗主義合法性。在接下來的段落,我們將探討安可史密斯如何從當代歷史學實踐和後現代主義的文化現象之間的交織情況中,去探討從西方史學傳統歷史主義和後現代主義歷史學之間關於歷史經驗的看法,反應出當代歷史學理論和實踐對過去歷史學的變革,此變革在心態史之中體現出來。

    + +

    三、

    + +

    首先我們從後現代主義說起,關於歷史寫作證據的引用,是否是朝向過去實在提出了看法。他們認為證據不是指向過去而是其他的過去詮釋,證據不是將我們送回到過去,而是升起歷史研究者在這裡和現在能做的或不能做的問題。證據組成歷史寫作,引起研究者去組織歷史的證據,是來於研究者最感興趣的證據。因此證據會被使用不是在於被說出的地方,而是在以往的時代沒有從證據說出的部份,也就是一個時代的大部份特徵,不被時代自身知道而為較後時代發現說出。前一時代的歷史往往是由較後時代來決定,對照於前一時期不是被說的或悄悄地說的、或被表達在微不足道的細節裡(現今的歷史研究中,新興主題的歷史研究都是如此信念)。而證據自身不被說的事實,來自於較後時代歷史研究者生活和寫作的心理狀態反應,經由對抗證據記錄者的時代心理狀態,決定證據所指時代的要點和意義,此時代的要點和意義是朝向歷史研究者所處時代讀者的呼喚,產生了對前時代(過去)的歷史寫作。因此,過去時代的歷史,只顯示在證據記載此時代的過去與較後時代心理狀態之間的不同處。

    +

    在此,安可史密斯認為後現代主義從對證據的看法推及歷史研究的體裁選定,與心理分析的研究方式有相似的特點。心理分析教導我們去瞭解什麼是精神病患說的,嘗試在精神病患言說的表面之上投影出一個模型,但不引導我們的注意一些數量元素的因果,可以在精神病患心智中彙整出人體模型,此人體模型不表明精神病患的心智有什麼是本質於精神分析詮釋的內容,亦即不去蒐尋在精神病患背後隱藏什麼真正的事實。在後現代主義歷史學,同樣的應該是去注意什麼不是被說的和什麼是被壓抑的,正如我們是什麼我們不是的,不想要是的,或在一個過去的確定意義上,什麼是它不是的。33 從上述兩者,可以看出心理分析和歷史學有相近的觀點。對於人或歷史性質的認知,不是要將之當作一個實體,求得過去的真實何在,以發現人或歷史的本質是什麼,以用來思考所有其它人和歷史,而是當作一個美術拚圖,發現一些次要的和似乎是不相關的細節的個別特徵。

    +

    在傳統的歷史學中,安可史密斯斷言常常隱含了一些對人或歷史本質性的論述,也就是前文所提歷史主義和實證主義歷史理論的先驗主義合法性的系譜。這些論述,由奧古斯丁 (Augustine) 神學的歷史觀念,和在科學進步中,盲目的信仰進步的觀念,而產生奧古斯丁神學的歷史觀念的世俗化變體,組成的後設敘述,一直延伸至現代。在過往的歷史研究者,總是以此論述,握有過去和將之當作理解每一件事的基礎。以一個比喻來說,假如歷史學的歷史是一個樹,在西方歷史寫作內的本質性的傳統就是這顆樹的樹幹,近代的現代主義者的科學式歷史寫作就是這顆樹的樹枝,由此建構西方歷史的統一。而在後現代主義的歷史寫作,選擇的是這顆樹的樹葉,拒絕進入這顆樹的樹幹或樹枝,再度重新建構此中的本質主義性質。亦即後現代主義者不再去整合、綜合或總體化本質中心的歷史,而是反本質主義,追尋本質中心的歷史殘餘物。因為當秋天的風一來掃落這些樹葉,這些樹葉就遠離了樹幹和樹枝,就不再與傳統的本質主義有連繫。34

    +

    從今日非西方世界的興起,逐漸瓦解西方傳統的歷史論述中,西方歷史的這顆樹,只不過是一片森林的一顆樹,使過往文化種系發生史的主張被打破,就像是這秋天的風吹起,而掃落了樹上的樹葉。面對這種情勢,後現代主義者提出的作法,就是放掉西方本質主義的歷史脈絡,不再以後設敘述來連接歷史根源與脈絡和傳統的寫作範型籓籬,使寫作既不是文學產品、或思想史、或精神哲學、或認識論、或社會預言等,而是蒐集這些掉落的樹葉混合出一些新式樣的寫作。諸如拉度瓦的《蒙大猶:錯誤的應許之地》 (Montaillou:The Promised Land of Error) 、金茲伯的微觀故事、杜比的《布賓斯的星期日》 (Sunday of Bouvines) 和大衛斯的《馬丁‧蓋爾的歸來》等。此種新式樣的寫作,使每一件事在顯著的(歷史寫作)共同關係中變成是當代的。也使歷史是相像於現在,現在的意義有採用過去的特質中;不去塑造我們根據或一致於過去(構造一個後設敘述),而是學習去扮演我們關於歷史的文化遊戲。35 也就是說,所有的歷史文本都是當代的,過去的詮釋是現在的思考與理解,思考關於過去的概念能在當代文化被讀者認識。

    +

    因此,歷史寫作的重要性不在於我們能否重構過去,而是其意義的部份,特別是與寫作當時的關係。這之中較有力量的是能使歷史寫作產生決定性價值的地方,而不是在於呈現真正過去的真實能力,也就是其採用的歷史概念在隱喻性質上能力。安可史密斯認為隱喻的作用,它招致我們以一個特定觀點的個體看待部分(歷史)實在。例如地球是一艘太空船,招致我們看待地球被定義在地球和太空船概念之間交互作用的特定觀點。如果要反駁這個詮釋,我們必須以另一個隱喻取代它,形成另一個特定觀點。這來於我們是無法以純粹的過去事實(過去只發生一次),來對照既有歷史文本與過去及其中史家洞識的關係,衡量其歷史寫作的價值,因此不能以歷史寫作字面上和事實的部份決定,而只能以隱喻反駁隱喻的方式認識它們。從這樣的見解出發,使著歷史寫作焦點也不再是過去自身,而是在現在與過去的不相稱處之間,及在我們現在地使用語言,談論關於過去和過去自身之間,找出這個屬於當代心理狀態下反應出的隱喻性質,而可以理解其歷史寫作的意義。

    +

    對後現代主義來說,這個屬於當代心理狀態下反應出的隱喻性質,至少反應在兩方面的見解。除了前述歷史寫作的性質,較後時期的史家的歷史寫作,不是綜合一致的歷史事實一致於較前時期的歷史寫作,而是顯示出過去歷史所不是的部分,以隱喻的方式創造不同於以往的歷史風格及其生產的意義。另外關於現代主義歷史求真或客觀化歷史的知識目標,即前面所言對人或歷史本質性的論述。如果後現代主義考慮歷史寫作的價值不在過去實在自身的重建,而是反應在每一個時代下心理狀態的隱喻性質,用在判斷西方傳統史學的本質性建構中,他們也發現此中蘊含一個橫跨時間性的隱喻。雖然就認識論來說,隱喻是一個對科學方法縝密和清晰的曲解,但是如果歷史認識首先是從定義開始,認識論履行一個較好、較後和較可定義的方式,以確定成套的歷史理解,進而拒絕任何隱喻在歷史中去履行一個只是附帶的和偶然的方式,以形成固定的認識方式,事實上這樣就變成一個壟斷的隱喻,在一個廣大地有力量的和無所不在的認識論隱喻主宰歷史寫作的書寫;相對於後現代主義的看法,將歷史文本看作是以隱喻的特定觀點,提供我們如何看待過去,相對於認識論的隱喻來說,提醒我們注意在此隱喻下,每一件事物本質論述中無意義的和不相關的性質,其目的在於經由西方史學傳統先驗主義「去本質」 (de-essentialization) 、去脈絡化、去熟悉化或超越「過去的馴養化 (domestication) 」36 的途徑,打破這一個傳統史學壟斷的隱喻,使我們能以各種隱喻的能力能在打破傳統史學壟斷的隱喻之時,發揮在歷史寫作的創作中。

    + +

    四、

    + +

    對於後現代主義的歷史思考而言,史家不是在重建過去而是過去至今還沒有意義的部分,事實上這涉及到史家的歷史經驗問題。因此安可史密斯進一步探討歷史經驗的現象,他藉由將歷史主義和後現代主義放在一起討論,連接兩者之間的相似和不相似之處,顯示新史學和傳統史學之間聯繫與超越,建立新的歷史經驗理論,37 以表達心態史在理論層次的意義。

    +

    李歐塔 (Lyotard) 曾在《後現代主義的境況》38 一書,提到後現代主義文化對後設敘述 (meta-narratives) 的批評,安可史密斯認為其批評有不妥當之處。安可史密斯主張早在歷史主義初期裡,就已經對思辨哲學系統(如黑格爾)的拒絕中提出辯解。譬如蘭克曾提到知識以絕對獲得是哲學的方法,而歷史的方法是是產生「對殊相自身之中和之旁的一個感覺和喜悅」,39 普遍性對歷史研究只是一個衍生物,這變成是歷史主義的歷史思想印記,而不是李歐塔宣稱過去的知識建構都含有普遍性的後設思考。其次,安可史密斯在建立歷史經驗理論的作法,也聯繫到歷史主義的「歷史觀念」中強調歷史的「個體性」部分,40 表明歷史主義的「歷史觀念」是形成具體事物獨特性的概念。以上兩點,說明歷史主義並不像大家認為思辨系統是它的全部。並且在這兩點中,安可史密斯認為他能進一步建構出後現代主義歷史經驗理論,只不過必須將歷史主義的「徹底化」 (radicalization) ,41 這象徵著他對西方傳統史學的傳承和變革。

    +

    安可史密斯主張「歷史主義主要是一個稱為『歷史形式』或『觀念』的理論,這些形式或觀念包含歷史紀元 (epochs) 或現象不可轉移的個體性,他們只能透過它們之間差異(或不同)的措辭裡被認識:歷史形式證明它們的輪廓在於它們區別於另一個的範圍內,而且不是共同於它們的數個或全部;至於後現代主義理論可能被看作是索緒爾主義 (Saussurian) 『差異』論題的一組變體,在這裡我們發現第一個關於論證歷史主義至後現代主義的表示。」42 從上述得知,安可史密斯認為「歷史形式」或「觀念」是歷史主義以差異邏輯的方法,其認識歷史實在的一種作法是藉由各個歷史現象或時代之間的差異,以建立起呈現歷史實在歷史形式或觀念,歷史形式或觀念變成是識別歷史實在的一個實體,這個實體由歷史現象或時代的差異產生,同時也是各個歷史形式或觀念之間的差異形成,表明歷史主義的「差異」是理解過去的方法學。而在後現代主義的思考中,也依賴差異的邏輯方法,後現代主義認為文本再現不是外於文本的實在,而是文本自身,文本自身只能比較於其他文本,展現與其他文本之間的差異之處以建立自身,因此歷史主義和後現代主義兩者有共通之處。

    +

    對於後現代主義運用同於歷史主義差異邏輯方法的境況,安可史密斯舉了一個例子,猜想我們現在有的歷史作品,每一個歷史現象或時代都只有一本歷史作品書寫,我們可能說每一本歷史作品(再現歷史實在)之間的不同,在這些歷史實在自身有特徵的範圍內,一致或反應於歷史形式或觀念的不同。同理可說,每一本歷史作品再現歷史實在是在歷史形式或觀念之間的差異中被理解(歷史主義之時);但是當我們的歷史作品,每一個歷史時代或現象擁有逐漸增加為數眾多的、競爭的歷史詮釋時,在這些部分歷史實在自身的範圍內,我們就不可能說這僅僅是詮釋的不同,而不注意(各個文本)歷史形式或觀念的不同。43 在歷史主義的時代,以歷史形式或觀念使歷史事實個體化,以作為對過去實在的理解和建立語言和實在之間的聯繫。此時每一個歷史現象和時代各擁有一個歷史形式或觀念,他們不會懷疑歷史實在是有問題的,因此歷史作品的歷史形式或觀念和歷史實在之間似乎是相互對應,兩者亦是無分別的。如今到了後現代多文本的時代,面臨生產過剩的境況,卻形成歷史實在認識的問題,44 我們擁有多個文本詮釋相同的一個歷史主題,我們無法確認那一個歷史詮釋可以被說是正確的歷史形式或觀念(再現歷史實在)之時,我們可能傾向於取消歷史實在的觀念,認為歷史文本和歷史實在之間,或字詞(語言)和實在之間是無法區別的或者是模糊的(見前文說明)。因此,後現代主義認為識別歷史文本,只能在各個文本之間的差異理解,以及歷史文本與歷史實在是無區別的;如同歷史主義理解歷史現象或時代,是由各個歷史形式或觀念之間的差異中而獲得理解,以及歷史形式或觀念與歷史實在是無區別的,其本體論上的見解也是一樣的。45

    +

    由以上的論述,我們可以清楚的看到歷史主義和後現代主義之間的親近關係。雖然在這個親近關係下,歷史主義一方面藉由歷史時代或現象之間的差異,形成歷史形式或觀念之間的差異,以確定認識的歷史實在的性質,這與後現代主義由歷史文本之間的差異,以確定認識對象的性質,兩者其差異邏輯的方法是一致的。但是,兩者對歷史性質的認識卻有所不同,歷史主義認為歷史家的歷史再現能獨立地給出歷史實在,認為史家經過對史料之中的事實考察,能夠直接呈現過去已發生的實在。這種相信歷史可從史料中獲得的過去實在,即相信在歷史的認識過程中,歷史的認知主體可以獨立於歷史寫作之外,語言的媒介猶如一面鏡子可以傳達過去實在,由此形成歷史的本體論觀點,進一步建構出主體與客體關係之下的認識論(蘭克之後的發展)。此種認識方式,亦即表達出史家在語言和實在之間的對應關係中,是以再現的擬態 (mimetic) 模式呈現過去,此中擬態模式則要求「再現」的恰當 (adequacy) (是否符合過去實在)。因此必須區分「再現」和「被再現」兩者(主客體),並且「再現」的階層將要有它的相似物在「被再現」實在自身,由此形成了「什麼是本質」的實在則根據於較恰當的再現;「什麼是偶然」的則根據於較缺乏恰當的一個,如此作法以決定社會歷史實在,是否重要或不重要不證自明的階層,因而建構出思索哲學的本質主義。46

    +

    相對於後現代主義顯示出我們認識過去事物不單純是過去事物自身,也應該包含文本所用語言或概念的所指事物。在後現代主義的觀念中,認為語言和實在之間的對應關係中,二分語言和實在是多餘的,47 歷史再現不是文本之外的實在或被再現之物而只是再現自身,再現自身事實上無被再現物(歷史實在)的參照,所以無法獨立的給予歷史實在,或由歷史實在規定歷史再現展示其相似物。歷史再現的形式必須涉及史家主體的介入,也就是史家的歷史經驗的方式,決定歷史再現的性質,這是歷史主義所忽略的,我們從蘭克的名言「弒去自身」可知,完全不談歷史認識過程歷史主體的重要性。由此可知,安可史密斯認為歷史主義對歷史實在和歷史經驗的性質,似乎仍然位於思辨哲學的不徹底處,後現代主義為此必須清除這個歷史主義的不徹底處,走向歷史主義的徹底化。因此,安可史密斯想要連接歷史主義和後現代主義的相似和不相似之處,其目的就在於排除歷史主義思辨哲學的形上成分,以建構後現代主義歷史經驗的理論,以說明心態史的歷史實踐。

    + +

    五、

    + +

    安可史密斯建構後現代主義歷史經驗理論以詮釋心態史的歷史實踐,其第一步作法,是從個人「懷舊」經驗談起。雖然,懷舊經驗雖然是個人的而不是集體的、過去親自接觸而不是無接觸的,而與歷史經驗具有不同的屬性,安可史密斯則認為懷舊經驗是一個合適的模型,假如我們希望標示歷史主義和後現代主義兩者,在上一節所談的差異邏輯之下,對過去經驗的相似和不相似之處。

    +

    關於懷舊的過去經驗,安可史密斯認為懷舊經驗是渴望孩童時失去的歲月,主要關係到一個取代的覺醒,表達一種疼痛地覺醒何處和何時它不想要是的,顯現出我們關於我們從不寫實目標的選擇意義。比較於歷史主義對過去的經驗,其目標是在一個確認的理解 (Verstehen) ,在一個過去的再體驗,過去的沉溺;換句話說,過去的經驗意圖在重設過去自身,在過去的經驗中取消經驗主體自身,結果就造成對經驗主體歷史經驗的排除,而這來於歷史主義將過去的經驗 (experience of the past) 等同於過去經驗 (past experience) 。相對於歷史主義的過去經驗,懷舊的過去經驗一致地支持對過去的不可獲得性質,期待歷史經驗可能性不在於重設過去自身而是保持與過去自身所必須的距離和差異。因此懷舊不應該關係一個對過去嚮往對象的確認、或一個再捕捉、或一個過去的恢復,而是產生一個無能力的覺醒意識,我們從不能再捕捉或再吸收懷舊願望的以往對象,此結果懷舊剝奪具體存在懷舊願望的對象。因此我們歷史地懷舊的不是過去自身,而是現在和過去之間的差異或距離。48 以上所言懷舊的經驗,至少表明二個特點,一為經驗對象不是過去曾發生的事實,而是過去曾發生事實的差異面,二為懷舊經驗混合經驗時(現在)的想法和過去曾發生的事實,其兩者之間無法區分。由此可知懷舊的經驗,不是過去自身而是其現在對過去的差異處,因此懷舊經驗從不固定過去的對象,而是賦於懷舊對象的可動性,不斷挖掘過去未被發現的經驗(如同「實在效應」的動力化)。從懷舊經驗的過程,我們可以看出上文歷史主義的差異邏輯,並沒有落實在歷史主體的經驗形式上,而後現代主義歷史寫作興趣在無意義和偶然性,或被以往歷史寫作譴責為無意義和偶然性的部分,後現代主義看待過去歷史文本的方式和懷舊經驗是一致的。

    +

    再者,前文所言歷史主義差異的邏輯方法,史家經由歷史時代和現象之間的差異和區別來理解過去,過去主要是一個「清楚的和獨特的」過去,其興趣在於過去可以表達和定義這個明晰和區別的那些特色。而這些特色之間的差異和區別事實上等同於懷舊的差異方式,主要是一個過去和現在之間的差異,引起清楚的路線與輪廓溶解在一起而投射於過去,也就是說歷史主義的差異邏輯使用在過去自身之內,根本也源於過去和現在之間的差異,和懷舊的差異邏輯沒有兩樣。但是,由於歷史主義將過去之間的差異當作是認識的條件,因而必須形成什麼是本質於和什麼是偶然的過去實在的預設,於是過去前景(重要的)和背景(不重要的)區別的就被建構出來。其中,最特別的預設就是普遍史的概念,作為時代之間差異前提的脈絡,最後也就排除歷史經驗的存在,此時就與後現代主義和懷舊經驗不同。

    +

    我們從上述可以得知歷史主義和懷舊經驗或和後現代主義的歷史經驗之間之差別,歷史主義傾向於取消過去經驗時的當下(現在)狀態,將對過去經驗視為過去自身,因此認為過去的自身反應過去之間的區別,以形成我們過去的經驗,而懷舊經驗告訴我們,當下或現在的過去經驗與過去自身之間是有區別的,現在的過去經驗創造於與過去自身的差異之下,以形成們過去的經驗。

    +

    這裡緊接的顯示一個重要的問題是懷舊的個人經驗,是否可作為史家外在於個人過去之外的歷史經驗,以致於可以被視為後現代主義的歷史經驗。安可史密斯認為,此中的問題可能在於懷舊對象的過去必須是個人經驗的過去。其次,懷舊可能從不是歷史經驗的模式,因為懷舊是非過去的經驗,所以懷舊不是歷史經驗。以上兩者,安可史密斯認為混淆經驗的 (of) 和經驗中 (in) 的區別(即混淆個人的過去和非個人的過去,對現在的個人都是不在場)。對安可史密斯來說,對個人或歷史的所有經驗都是發生在現在之中而不是過去,因而一個過去的經驗不管是個人或歷史都不是不可思考的事實。此不可否認的事實表明歷史經驗的對象在於現在我們能看得到的過去證據而不是過去自身,由此說明了懷舊經驗和歷史經驗之間的共通。49

    +

    我們再回到歷史主義和懷舊的經驗或後現代主義的歷史經驗討論。歷史主義尋找重設每一個歷史時代,其途徑從各歷史時代之間的差異中,以「歷史形式」或「觀念」使每一個時代個體化,以及顯現「歷史形式」或「觀念」當作歷史經驗的對象,只不過歷史經驗的對象總是排除歷史經驗主體的加入。蘭克說到「每一個時代直接面對上帝,它的價值一點也不是導衍於它擁有的存在,在它擁有的自我。」50 其中宗教觀點的暗示,使歷史事物的個體化形式或觀念,能去面對一個永恆、無時間性的普遍性假定。從歷史主義到實證主義的發展明顯地也沒有將之拋棄掉,之前我們提到「普遍史」的概念就是他們常用來處理歷史時代差異的邏輯。因此,每一個時代擁有他們的歷史形式或觀念,每一個形式或觀念源於每一個時代之間的差異前提,都被「普遍史」固定於歷史實踐和探討之中。

    +

    然而,安可史密斯認為雖然歷史主義的普遍史預設,導致歷史經驗的懷舊經驗的主體不在場,但是在邁乃克《歷史主義:一個新歷史展望的興起》書中,提到哥德 (Goethe) 在《詩歌和真理》 (Dichtung und Wahrheit) 一書,隱然地表現出過去經驗是一個現在與過去之間差異的經驗,只能被經驗在片刻 (a moment) 統一之中,顯示出接近後現代主義的懷舊經驗。51 只不過邁乃克提及哥德的過去經驗方式是在一個宗教的氣氛當中,個人在片刻的時間之中可以接近上帝創造萬物的意旨。不過,這裡顯示出對過去的經驗是現在認識主體的經驗,如何使過去和現在之間統一於現在的片刻而不是過去自身。

    +

    從邁乃克提及哥德的過去經驗說明,安可史密斯將之比較於赫伊津哈 (J. Huizinga) 歷史感覺 (historical sensation) ,赫伊津哈將歷史感覺比較於我們音樂的理解。音樂的特徵當作「成為時間滅跡的手段」,「一個旋律只能被聽或理解,假如聲音和音度中的差異聚集,在一個片刻中被聽到」,可以被類似於發生在過去的懷舊經驗。赫伊津哈認為歷史感覺可以由「古老檔案中的幾行字,或是一首老調中的幾個譜調音符所引發的。」此表達歷史感覺是過去和現在之間的裂縫,突然滅跡的瞬間迷惑於經驗,使過去在一個零數的片刻顯示它自身,「彷彿它(過去)是或已是」的經驗。52 安可史密斯認為赫伊津哈的歷史感覺,同樣在強調歷史經驗不是過去自身而是現代和過去之間的差異,在認識主體的現在片刻中理解與後現代主義懷舊的歷史經驗是相似的。赫伊津哈寫作《中世紀的凋零》似乎就是這樣的一種體驗,53 我們可以發現歷史感覺或懷舊的經驗,強調歷史經驗的插曲 (episodic) 特徵,安可史密斯認為從赫伊津哈的歷史感覺概念裡獲知,歷史經驗應該不是對過去(留下來的證據)的據實回應,而是一種抵抗。在瞬間片刻拋棄對過去其他歷史文本的脈絡化,也就是歷史經驗是一種解脈絡化的經驗。54

    +

    從以上所述,歷史主義的歷史經驗似乎並沒有完全沉迷於「普遍史」的迷惑之中,但是仍可發現接近於後現代主義的歷史懷舊經驗。然而,這種懷舊經驗同安可史密斯所提歷史主義不徹底處,即「普遍史」建構和其起源處,來自於笛卡兒至康德所建構的先驗主義,在歷史主義中和在西方歷史學中形成一種弔詭。因為歷史主義一方面要求固定的實在觀念和先驗的自我,另一方面歷史主義告訴我們歷史是流變的,必須由每一個時代和建構的歷史形式或觀念的差異,以建立我們的歷史理解。本節我們已經清楚的辨別弔詭的兩端,在隨後歷史經驗的探討裡,我們將繼續考察安可史密斯處理後現代主義的歷史經驗形式和對象。安可史密斯在下一節中的作法,繼續比較歷史主義或西方史學的認識論和後現代主義,以突顯後現代主義的歷史經驗是對歷史主義或西方史學的認識論的反抗,以及後現代主義的懷舊經驗建立在現在和過去之間的差異,如何看待過去(歷史文本)所不是的、無意義的地方,也就是對過去一些本質化論述的拒絕,而產生出後現代主義特有的歷史經驗形式和對象,也就是心態史所顯示的。

    + +

    六、

    + +

    關於後現代主義歷史經驗的產生,就是建立在反抗西方史學傳統的認識論之中,進而反應出歷史經驗對象的形式。因此本節對安可史密斯後現代主義歷史經驗的形式和對象之探討,打算從後現代主義對西方史學傳統的認識論的批判說起。安可史密斯認為康德主義先驗自我的範疇,此一範疇是西方哲學形成知識認識的基礎,主宰包括歷史知識的西方近代知識之建構,如同是一個隱喻性質不斷的衍生它的變體,但是從沒有失去其本質。因此,安可史密斯借用明克的「支配隱喻」 (master-metaphor) 概念,來形容這一套不變本質的認識論系統,以及如何支配西方對知識的思考。

    +

    安可史密斯依明克的看法指出「支配隱喻」是一個空間隱喻,「由於外在於時間之河自身,特定觀點設定一個空間,時間的連續是被取消,在這個意義之中,主張一個時間穿越空間的『解構』」。55 也就是說歷史知識受制於一個特定觀點的空間範圍如先驗自我的圖式,以理解時間脈絡中歷史世界的流變,但是歷史世界的任何事物只能在這特定觀點的空間範圍被理解,不容許其他的特定觀點製造其它的空間範圍,以及這個獨斷的特定觀點造成一個空間範圍,而這個空間範圍不是和不包括特定觀點自身。以一個比喻說,上帝創造萬物,但上帝不是萬物自身,祂超然於祂創造的萬物。也正如蘭克所說的,「我想像神─假如我可以允許我自己這個觀察─正在看歷史的人類的全部在它的總體性(因此位於神之前無時間),以及發現它所有同等的價值。」56 蘭克將上帝放置在一個超歷史的位置正如上述明克所做的,形式地與外在於時間之河的特定觀點具有相同的性質。因此,這個支配隱喻似乎將史家歷史的認識主體化約到僅僅是一個先驗的、超歷史的自我而沒有一個經驗的自我,並且這個先驗的、超歷史的自我被認為是歷史知識客觀的保證。

    +

    以往的歷史哲學家事實上都想解決先驗的、超歷史自我的問題,並且又要確定歷史知識的可能,其中相對主義的作法就是其中一個。相對主義的作法是將歷史認識的主體歷史化,但是最後陷入自我的弔詭中,因為歷史知識一方面要尋求過去的實在,但是一方面又要面對不同歷史認識主體的種種歷史詮釋,結果一個固定的過去實在現實上又沒有唯一的或一致的歷史詮釋,因而完全沒辦法逃脫這個困境,即認知到歷史知識的歷史性但無法與歷史知識的客觀性相容。然而,安可史密斯認為在一個不同的途徑中,他發覺到能給於新意義,促使他能進一步跨越到後現代主義的歷史經驗中。此人就是詮釋學者加達瑪,加達瑪注意到史家歷史認識主體和歷史知識的歷史化,導致一個歷史寫作和歷史學(歷史寫作的歷史)層次的合併,也就是當我們考量歷史自身(或過實在)時,我們不能遠離歷史學自身。安可史密斯繼續說到,事實上加達瑪的觀點不是一個新的觀點,黑格爾早已經注意到歷史的洞識自身是一個歷史情節的構成要素,因為歷史洞識進入「精神」自我實在化的歷史過程是一個歷史的純粹本質。57 從黑格爾或加達瑪的認識中,安可史密斯認為明克的「支配隱喻」似乎就不再可能,因為一個特定觀點通常混合討論特定觀點的特定觀點,而不是純粹的過去實在,所以「支配隱喻」其特定觀點的空間隱喻,傾向於毀滅它自身。

    +

    安可史密斯認為加達瑪在此強調歷史知識的「效應歷史」 (Wirkungsegeschichte) ,加達瑪提到「真正的歷史對象一點也不是一個對象而是一個和另一個的統一,存在歷史實在和歷史理解的實在兩者的關係。一個適當的詮釋學可能必須證明在理解自身之內的歷史效應性,我將要提及這個當作『效應歷史』,理解本質地是一個效應歷史的關係。」58 他強調歷史認識主題的歷史化,不應該僅僅是歷史思考或寫作中層次增殖的結果,歷史化必須變成歷史寫作自身的一部份。依加達瑪的意思,歷史寫作的的歷史實在,必須考量累積在歷史學當中的歷史理解或歷史洞識,變成是歷史寫作中歷史的一部份,也是認識主體歷史經驗的一部份。但是,安可史密斯認為加達瑪的作法是多餘的,而且仍沒有擺脫支配隱喻的範圍,顯示出「效應歷史」的不徹底特徵。這來於一方面「效應歷史」自身並沒有被歷史化,效應歷史自身猶如站在時間之河旁邊安全的高山上,繼續支配歷史知識空間範圍,但不是空間範圍自身;另一方面效應歷史的運動,特定觀點吸收特定觀點,沒有起點也沒有終點,從不形成一個最後的特定觀點,可以用來重構我們自身認識的歷史實在。也就是加達瑪並沒有給予認識主體歷史經驗的獨立地位,而只告訴我們要將過去認識主體的歷史經驗或歷史理解,一併變成我們自身認識的歷史實在的一部份。不過,加達瑪的「效應歷史」,倒是暴露所有努力使歷史知識「朝向穩定性」的作法,以及注意到歷史實在中歷史理解或歷史經驗的部分。59

    +

    在西方近代史學傳統中,歷史主義是主要傳統之一,上述加達瑪的歷史詮釋學的最重要目標就在於歷史主義的徹底化,即企圖解決歷史主義先驗主義的傾向,他的作法是將原本相對主義對歷史認識主體的歷史化,進一步擴展到對歷史特定觀點的歷史化。他考量歷史實在和歷史理解的實在兩者之間的「視域融合」 (Horizontverschmelzung) ,60 注意到歷史寫作當中,除了歷史實在外,寫作者的歷史理解或歷史經驗也是歷史寫作的一部份,因此從事寫作時兩者通常是統一在一起。並且我們考量歷史寫作時,處於時間過程中的不同的歷史狀態,這也是「效應歷史」的一部份,因而加達瑪的歷史詮釋學意識到認識主體的經驗對象,是現在狀態對於歷史文本的經驗,而不是對過去實在的經驗。如同安可史密斯對加達瑪的看法,他認為加達瑪「希望拉引我們注意我們如何經驗文本以及它的意義,不能分離文本在我們現在狀態中,對我們具有意義的問題,也就是文本如何使我們和我們擁有的世界之應用。」61 然而,加達瑪將歷史認識主體經驗歷史,視為效應歷史的一部份,也就是認識主體的經驗成為整個詮釋歷史中經驗歷史性的一份子。此經驗的歷史性因此覆蓋每一個認識主體的經驗,使認識主體的經驗的獨特性因此消失,造成經驗的歷史性之外沒有其經驗存在的可能。而這就像先驗主義一樣,任何論述在先驗主體設定的空間範圍外沒有存在的可能,經驗歷史性中各個獨立的歷史經驗因此被「效應歷史」給溶解掉了。

    +

    不過,如前述從黑格爾或加達瑪的認識,西方(歷史)知識傳統的支配隱喻,通常是自我解構的,62 歷史包括了一個特定觀點通常混合論特定觀點的特定觀點,所以如上述「支配隱喻」其特定觀點的空間隱喻毀滅它自身。簡單的說,支配隱喻宣稱歷史實在的論述為何,當只有一個論述時沒有問題,但是當論述逐漸累積就夾雜了論述的論述,而不是純粹的論述實在。加達瑪的歷史詮釋學注意到這問題,但是他的作法是將論述的論述不斷的加入這樣的連續性歷史詮釋中,也就是使任何一個現在或未來的歷史認識主體不斷的加入這個全部的歷史學當中。安可史密斯則反對這樣的作法,他所主張的後現代主義作法,則是打算徹底的毀滅這樣的連續性歷史詮釋,賦予認識主體獨立的歷史經驗。

    +

    安可史密斯宣稱後現代主義的途徑,事實上也是歷史主義的徹底化,在於他發現到歷史主義的傳統裡,蘊含了後現代主義主張的差異邏輯,尤其是關於「再現」本體論的唯名主義傾向,只不過歷史主義仍然居住在不徹底的先驗主義房子內。以下安可史密斯歸納了一些後現代主義對西方知識傳統包括歷史主義的解構主張,以走向安可史密斯歷史經驗的探討。首先是解脈絡化,歷史主義的「歷史觀念」使用通常被視為一個規則,假如我們希望透過「歷史觀念」理解過去實在,歷史主義傾向將他調查的對象放置在「歷史觀念」的歷史脈絡中。前文曾提到的「普遍史」就是這一個較寬廣脈絡的來源,通常史家不會去懷疑從「普遍史」而來的特定觀點含有形上學的成份。而後現代主義的作法則傾向於去質疑「普遍史」的特定觀點,也就是質疑「普遍史」的特定觀點以為自身不會涉入過去實在當中,並且又能展示過去的實在。後現代主義的作法進而將「普遍史」的脈絡化意圖打破,允許認識主體的歷史經驗介入,以表達過去實在自身不是「普遍史」脈絡化,而是可能有種種不同脈絡化,這造成歷史的書寫則傾向於片斷化,此片斷化不僅是取消所有的歷史文本擁有共同的脈絡,還表現在歷史文本之間可能出現種種互不相屬的脈絡。

    +

    第二點,隱喻組織的崩潰,西方(歷史)知識的基礎奠定於先驗主義的範疇,而這個範疇事實上一如上述就是知識組織的支配隱喻,以及意圖反映或投影過去的隱喻組織化。在此,後現代主義的作法則是使原本組織過去為一個統一的全部之隱喻,轉變為一個無政府主義總體性獨立的微敘述 (petits recits) 。一如心態史的研究情況,他認為如金茲柏的《小蟲和起司》中麥派諾西歐的故事,麥派諾西歐的想法,我們不能裝置他十六世紀時期的成套心態,亦無法由他來解釋十六世紀的時代狀態,即我們無法以「文藝復興」隱喻的「再生」觀念來想像麥派諾西歐的故事。第三點,無深度的結果,63 對歷史主義來說,理解每一件事是一個歷史變革的結果,此結果由於認為「歷史觀念」和過去實在之間的對應是無問題的,因此建立了「什麼是本質」或「什麼是偶然」的階層組織,這使它們產生一個「深度」的錯覺。這個「深度」主張歷史的透視,強調過去實在的歷史本質表現在一個民族、體制、社會階級等等。對此,後現代主義的作法則是否定語言和實在之間對應的無問題看法,強調語言對實在的晦暗不透明,因此就不會使我們去尋找透明語言背後隱藏一個實在的錯覺,也就剪斷歷史文本反映出的歷史現象有它們過去之根本,或者歷史文本的語言表達背後有一個實在,進而轉向去注意我們自身文化的語言狀態下描繪實在的方式,什麼是我們經驗語言直接表達的過去實在,這使我們描繪過去實在的語言變成是語言字面的「實在效應」。第四點,過去的懷舊經驗,64 歷史主義努力以超歷史的先驗自我隱喻重建過去,以縱覽時間之河的方式客觀地給予實在,將要被轉換為一個過去的懷舊經驗,過去不再是一個外在的實在,而是歷史文本自身反應現代意義的自我真實,以往客觀的過去實在觀念讓位給後現代主義的超寫實 (hyperreality) 觀念。65 以上各點反應出後現代主義對西方知識傳統包括歷史主義的解構主張,在於強調後現代主義意圖擺脫以往為了(歷史)知識客觀性而建構出的先驗自我假定,表現出後現代主義對歷史主義的徹底化是朝向注重獨立的歷史經驗形式和對象。

    +

    我們以安可史密斯舉出肯納對年鑑學派學者布勞岱爾 (Braudel) 《地中海》一書詮釋的例子說明。肯納引用勒博 (Claude Lefort) 描寫布勞岱爾,通常由「似乎是對比於社會學作品鼓舞的一個(印象派的)點描繪法」的引導。肯納燦爛的暴露布勞岱爾點描繪法的性質和文本根源,他拉引我們的注意布勞岱爾文本「外表的流沙」;也探索「矛盾修辭法連續的系列」。在布勞岱爾的文本中,布勞岱爾選擇「液體平原」、「水樣的撒拉哈 (Saharas) 」和「沒有海環繞的島嶼」的詞彙,表明布勞岱爾傾向於矛盾修辭法和弔詭,是在一個地中海是關係到西方世界中的地圖,這個地圖展示一個球體,從「南波羅的海在頂端和支配一個廣大的逐漸出現的非洲。」清楚地,肯納注意到布勞岱爾的文本所顯示的,是意圖到「解熟悉化」過去和系統地瓦解任何關於過去我們可能已經有的固定觀念。安可史密斯認為肯納從布勞岱爾文本發現到一種擬自然的解熟悉化正是一個最有價值的線索,如果我們要獲得後現代主義歷史經驗形式和對象的掌握以及它導衍於差異的經驗。另一方面,如前文所提在當代心態史中,以及哥德和賀以津的歷史經驗或歷史感覺,也是另一種「解熟悉化」過去的歷史寫作方式,表現出後現代主義歷史經驗的形式和對象。66

    +

    安可史密斯認為上述這種「解熟悉化」過去的歷史經驗,使史家看待過去不是在一個熟悉化的歷史脈絡,而是在一個現在對過去(歷史文本)的「差異」中的視野(正如我們一直宣稱的後現代主義差異邏輯)。安可史密斯緊接著進一步說明「差異」何以是我們歷史經驗的對象,而不只是歷史主義區分過去實在之間的差異。在此,安可史密斯借用佛羅依德的「異常」 (uncanny) 概念和尼采的「午時片刻」 (grosser Mittag) 與「永恆回歸」 (eternal return) 概念,來闡述這樣的歷史經驗過程。首先是「異常」概念,安可史密斯詮釋它是一種遠離家 (Heim) 的懷舊或思鄉 (Heimweh) 感覺,對比於必須是緊密的關係到「無禮貌」 (Unheimlichkeit) 的感覺。佛羅依德指出異常經驗的特徵是「主體使自身識別於某一個,正如他懷疑他自身是的或關於他擁有異質自身的替換。換句話說,有一個雙重的、區分的和交換的自我。」67 安可史密斯從佛羅依德的看法中,他認為我們可能觀察一個複製的過程,允許一個異常獨立於我們思考應該是我們自身、我們自然的同一性、我們在家的一部份,但是歷史經驗的形式和對象不再是如此。安可史密斯繼續說到佛羅依德的「異常」概念,類似於心態史經驗過去的方式,心態史授與一個異常獨立於我們自身,那些我們總是相信不可改變的性質方面,心態史家證明是歷史地偶然─歷史主義可能總是尋找再一次的中立化,這些異常的方面成為歷史變革過程的一部份,期待整合它們變成我們同一性的方面。換句話說,心態史所從事的歷史研究,不是創新一些新領域,可以為以往歷史學認識結構所能相容,以及在歷史主義史學傳統下的歷史編纂系譜眼光中,心態史的研究似乎是軼事 (anecdote) ,而是傳統下歷史編纂系譜建構的歷史連續性變革常態事物之外,有一個獨立地描繪自身的歷史形象,像是時間之河中堅固的磐石。68

    +

    這裡我們發現到「異常」概念除了和心態史形式的相似之外,在實質上也是近似的,代表著後現代主義歷史寫作的狀況。我們可從心態史開始於情愛、性愛、死亡的恐懼等等主題的研究,特別是死亡的主題和關於死往的思索同佛羅依德主張不謀而合。「許多人經驗異常,在一個最高程度上關係到死亡、和死的身體、死亡的回歸和變成靈魂及鬼。」69 異常和心態史研究過去顯現到我們現在之間是連結在一起。另外,像心態史研究巫術信仰思考過去的人們信仰萬靈論的力量,以及各式各樣的迷信,無疑也是一個異常歷史的研究。不像是啟蒙的理性心態,輕視迷信僅是一個未被啟蒙的過去殘餘,企圖去壓制我們潛意識地認知是我們自身的一部份。後現代主義的心態史研究顯示迷信當作一個永存潛在的可能性,正如它是人們自我表現的結果和不是異於我們。70

    +

    對照「異常」和心態史,安可史密斯認為心態史處理的對象給於我們一個異常的經驗,我們正確地發現在這些對象中,使我們疏遠文化和歷史同一性的部分(西方傳統歷史文本所給予的)。也就是心態史討論異常獨立於文化和歷史同一性的對象,不是服膺於使過去客觀化,而是在與以往歷史文本對比之中不做與它們一致的客觀化,並且位於我們自身和以往歷史學傳統之間,如同歷史主義重建過去之間,主張一個神秘存在的領域。71

    +

    另一個安可史密斯聯結後現代主義歷史經驗的概念,就是尼采的「午時片刻」與「永恆回歸」概念。安可史密斯吸收席塔 (K. Schlechta) 和布爾諾 (O. F. Bollnow) 對尼采的洞識,來重新理解尼采這兩個概念。72 安可史密斯主張尼采的「午時片刻」是尼采午時經驗的觀點,尼采把它投射到歷史時間的觀念,這使安可史密斯可以將他拿來比較歷史主義和後現代主義的不同。並且午時經驗當作時間觀念的象徵,使午時經驗關係到相同的永恆回歸觀念。首先,安可史密斯認為布魯諾將時間的觀念和午時片刻視為明顯相關的是正確的作法,布魯諾提到「在每一個人類存在的循環,將要總是把一個時刻當第一個然後許多個,最後所有包含在最有力量的思考和所有事物永恆回歸的思考裡:對於人類來說,每一段時間都是午時的時刻。」因此,「午時片刻」與「永恆回歸」兩個觀念在時間的觀念的性質上是一致的。73

    +

    安可史密斯進一步認為「午時片刻」與「永恆回歸」是尼采用來批判(歷史主義)的線性觀念,其意為在來自過去線性系列內每一個在現在出現的時間概念直接地優先於線性系列。因此永恆回歸的神秘攻破這個線性,以及時間的革命性概念堅強地強調「片刻自身」。假如一致於永恆回歸的神秘,每一個片刻是永無止盡的重覆,片刻將要從連結它關於它的過去和他的未來之中解放它自身,以及變成一個「永恆片刻」的自身。74 在這個由永恆回歸的時間概念之內,時間不再是線性的而寧願應該被思考是一個平面 (plane) ─一個平面組成無限的平行之線。各個線連結點描繪相同的片刻;經由跨越所有每一條平行線的平面,永恆回歸的相同性必須被放置在每一條線是永恆的部分。75

    +

    另一方面,「永恆片刻」是一種「午時」經驗。安可史密斯在談佛羅依德的「異常」概念時,曾強調佛羅依德的「異常」概念,應該同他的「午時恐怖」 (the terrors of noontime) 概念並置討論。佛羅依德認為異常的經驗是一個午時的感覺,此午時的感覺可以在許多的文明中如古典希臘、埃及發現,這些文明都認為午時的感覺是挑起類似關於死亡、已死和有特徵的已死的回歸,相似的恐懼和焦慮。76 而將「午時恐怖」對比於其他時刻,它明顯的給於我們如自然的家突然不是的感覺,感覺我們自身變成是陌生的、不熟悉的和不親切的,如同異常的經驗。因此「永恆片刻」,從上一段所提排除(歷史主義)線性系列發展的時間觀念,提議「片刻」的時間概念,以及「片刻」時間概念有一個永恆回歸的特徵。而這個特徵就是跨越線性時間特性,具有永恆相同性質的「午時恐怖」經驗,經驗一種異於常態的我們自身,以及我們不熟悉但是我們自身一部份的自我。類比於對過去的經驗,就是我們能真正感覺和接觸的過去只能是解熟悉的過去,在認識主體當下片刻將之表現出來。

    +

    以上所談安可史密斯從「異常」、「午時片刻」、「永恆回歸」等概念的詮釋,無非是要告訴我們後現代主義的歷史寫作,特別是心態史,其經驗過去(歷史文本)的方式以及面對過去的對象,在於史家認識主體看待過去,由一種經驗過去的片刻產生對已熟悉過去的拋棄,尋找一個相對於過去(歷史文本)熟悉的「差異」對象,而這個與過去熟悉的「差異」對象常常是現在解熟悉化過去而獲得的形式。換言之,後現代主義的知識追求策略,如上述所提「解脈絡化」、「隱喻組織的崩潰」、「無深度的結果」和「過去的懷舊經驗」,來於他們對過去的興趣不在一些舊的再現模式,而是諸如追求人性被壓抑的一面反對本質性的論述,因此對過去的經驗的對象,就在與這些過去本質性論述文本的「差異」中產生。

    + + + + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +
    + +
      +
    1. Carlo Ginzburg, The Cheese and the Worms: The Cosmos of a Sixteenth-Century Miller (Batimore: The John Hopkins University Press, 1981); Natalie Z. Davis, The Return Martin Guerre (Cambridge, Mass.: Harvard University Press, 1983). (Back)
    2. +
    3. F. R. Ankersmit, "The Reality Effect in the Writing of History," in History and Tropology: The Rise and Fall of Metaphor (Berkeley: University of California Press, 1994), 109. (Back)
    4. +
    5. 安可史密斯在《敘述邏輯》 (Narrative Logic: A Semantic Analysis of the Historian's Logic( The Hague: Martinus Nijhoff, 1983) 一書提出「敘述實體」的概念,他認為歷史寫作中常常會使用一些概念來指涉過去某時空發生的事實,其概念自身的使用通常到最後取代過去實在自身,而成為我們認識過去實在的部分,諸如文藝復興、工業革命等概念。 (Back)
    6. +
    7. Ankersmit, "Historical Representation," in History and Tropology, 113. (Back)
    8. +
    9. Ankersmit, "Historical Representation," 115, 即從歷史寫作中所能認識的是敘述實體的東西,而不是過去實在自身。 (Back)
    10. +
    11. Ankersmit, "Historical Representation," 119. (Back)
    12. +
    13. Ankersmit, "Historical Representation," 120, 藝術再現只保留藝術對象的觀念,在現代藝術品複製過剩的時代,原作和複製品的藝術價值似乎每有兩樣。區分兩者的價值變成只能在商業的拍賣會上,拍賣價格的多寡決定。 (Back)
    14. +
    15. Ankersmit, "Historical Representation," 121-23. (Back)
    16. +
    17. Ankersmit, "Historical Representation," 128. (Back)
    18. +
    19. Ankersmit, "Historical Representation," 130. (Back)
    20. +
    21. Ankersmit, "Historical Representation," 124. (Back)
    22. +
    23. Ankersmit, "Historical Representation," 128-29. (Back)
    24. +
    25. Ankersmit, "Historical Representation," 136. (Back)
    26. +
    27. Ankersmit, "Historical Representation," 137-38. (Back)
    28. +
    29. Ankersmit, "The Reality Effect in the Writing of History," 139-40. (Back)
    30. +
    31. Roland Barthes, "The Discourse of History," in The Postmodern History Reader, ed. Keith Jenkins (London: Routledge, 1997), 122. (Back)
    32. +
    33. Roland Barthes, "The Reality Effect," in The Rustle of Language, tr. Richard Howard (Berkeley & Los Angeles: University of California Press, 1989), 146-48; Roland Barthes, "The Discourse of History," 120-43. (Back)
    34. +
    35. 安可史密斯認為巴特關於「實在效應」的說明,並沒有區分清楚文本中「實在效應」和「意義」。不過,在此安可史密斯似乎也沒有要將此區分清楚,安可史密斯認為他只是要強調歷史文本中「實在效應」的狀況,因此沒有必要一定要分別清楚「實在效應」和「意義」之間的區別。 (Back)
    36. +
    37. Ankersmit, "The Reality Effect in the Writing of History," 143. (Back)
    38. +
    39. Ankersmit, "The Reality Effect in the Writing of History," 144-45. (Back)
    40. +
    41. Ankersmit, "The Reality Effect in the Writing of History," 144-45. (Back)
    42. +
    43. Roland Barthes, "The Reality Effect," 144-45; or C. Behan McCullagh, "The Truth of Historical Narratives," History and Theory Beiheft 26 (1987): 30-47, 麥古里的論證同其它反對敘述主義的實在主義者一樣,承認實在的可能,但是對於歷史本體論的基礎,卻提不出一套完整的保證。 (Back)
    44. +
    45. Ankersmit, "The Reality Effect in the Writing of History," 146. (Back)
    46. +
    47. Ankersmit, "The Reality Effect in the Writing of History," 147. (Back)
    48. +
    49. Ankersmit, "The Reality Effect in the Writing of History," 147-50. (Back)
    50. +
    51. Ankersmit, "The Reality Effect in the Writing of History," 151-53. (Back)
    52. +
    53. Ankersmit, "The Reality Effect in the Writing of History," 154-6. (Back)
    54. +
    55. Ankersmit, "The Reality Effect in the Writing of History," 156-7. (Back)
    56. +
    57. Michel Vovelle, Ideologies & Mentalities, tr. Eamon O'Flaherty (Chicago: The University of Chicago, 1990). (Back)
    58. +
    59. Ankersmit, "The Reality Effect in the Writing of History," 157. (Back)
    60. +
    61. Ankersmit, "The Reality Effect in the Writing of History," 158. (Back)
    62. +
    63. F. R. Ankersmit, "Representation: History and Politics," in Dimensionen der Historik: Geschtstheorie, Wissenschaftsgeschichte und Geschichtskultur heute, (Jorn Rusen zum 60 Geburtstag) Von Horst Walter Blanke, Friedrich Jaeger und Thomas Sandkuhler (Hg.) (Koln; Weimar; Wien: Bohlau, 1998), 34-7, 對第三物的性質和起源都有進一步的論述。 (Back)
    64. +
    65. Ankersmit, "Historiography and Postmodernism," in History and Tropology: The Rise and Fall of Metaphor, 173-74. (Back)
    66. +
    67. Ankersmit, "Historiography and Postmodernism," 176. (Back)
    68. +
    69. Ankersmit, "Historiography and Postmodernism," 77. (Back)
    70. +
    71. Ankersmit, "Frank Ankersmit," Interview and edited by Ewa Domanska (Anloo, The Netherlands 26 May 1993), Encounters: Philosophy of History after Postmodernism (Charlottesville and London: University Press of Viginia, 1998), 78, 「馴養化」一觀念為海登‧懷特提出,替換康德的美 (beauty) 。 (Back)
    72. +
    73. 安可史密斯所謂歷史主義和後現代主義之間的相似和不相似之處,筆者認為相似處在於兩者思考歷史事物的邏輯形式,都是建立在「差異」的邏輯;不相似處在於歷史主義處理歷史經驗的問題,是一種形上學的思考,預設史家面對歷史書寫時的不在場,以保證歷史寫作的客觀性,對後現代主義來說,傾向於將思考歷史事物的「差異」邏輯形式,用來處理歷史經驗的問題,以擺脫與歷史主義不相似之處,即形上學的思考。本章將處理安可史密斯如何將源於歷史主義的「差異」邏輯,拿來與後現代主義關於歷史經驗的討論並置,以闡述後現代主義對歷史經驗的處理。 (Back)
    74. +
    75. Jean-Francois Lyotard, The Postmodern Condition: A Report on Knowledge (Minneapolis: University of Minnesota Press, 1984). (Back)
    76. +
    77. Ankersmit, "Historism and Postmodernism," 185. (Back)
    78. +
    79. Georg G. Iggers and Konrad von Moltke eds., The Theory and Practice of History: Leopold von Ranke (Indianapolis, New York: The Bobbs-Merrill Company, Inc., 1973). (Back)
    80. +
    81. Ankersmit, "Historicism: An Attempt at Synthesis,"143-61. (Back)
    82. +
    83. Ankersmit, "Historism and Postmodernism," 186. (Back)
    84. +
    85. Ankersmit, "Historism and Postmodernism," 186-87. (Back)
    86. +
    87. 在 Ankersmit, "Historiography and Postmodernism," 一文,安可史密斯也曾提「生產過剩」的學術現象,造成我們追求歷史實在的困難。 (Back)
    88. +
    89. Ankersmit, "Historism and Postmodernism," 188; idem., "The Origins of Postmodernist Historiography," in Historiography between Modernism and Postmodernism: Contributions to the Methodology of the Historical Research, ed. Jerzy Topolski (Amsterdam: Atlanta, GA: Rodopi, 1994), 93, 安可史密斯對於這樣的認識來於羅蒂在 "Nineteenth century idealism and twentieth century textualism," in Consequences of Pragmatism (Brighton: Harvester Press, 1982), 139-59, 一文中,認為當代「文本之外無它」和文本主義同等於十九世紀的觀念論。 (Back)
    90. +
    91. Ankersmit, "Historism and Postmodernism," 192, 另外可參見該論文集〈介紹〉一文。 (Back)
    92. +
    93. 可參見 F. R. Ankersmit, "Experience, Transcendentalism and the Limits of Interpretation," in History and Limits of Interpretation: A Symposium (Rice University Farnsworth Pavilion 15-17, March, 1996); available from http:// www.ruf.rice.edu/~culture/Ankersmit.html; internet (accessed 25 Feb. 1996), 3; "Historical Represention," 115, 安可史密斯認為實在的觀念是多餘的。 (Back)
    94. +
    95. Ankersmit, "Historism and Postmodernism," in History and Tropology: The Rise and Fall of Metaphor, 199-200. (Back)
    96. +
    97. 不過,安可史密斯主張懷舊經驗常被聯想到傷感的和一個假造的理想化,必須被淨化。 (Back)
    98. +
    99. L. von Ranke, "On Progress in History," in The Theory and Practice of History, 53. (Back)
    100. +
    101. 「一個感覺使我越來越難以抵抗,我幾乎不能成功的表達,過去和現在一如是一個的經驗:一個經驗有時是如鬼似的帶到現在,這個感覺被表達在我許多或大或小的作品,以及總是精心盡致合適於詩學,雖然感覺似乎是不可思議的和或許是不合意於每一次它顯示它自身在我的生活自身之中。」轉引 Ankersmit, "Historism and Postmodermism," 207. (Back)
    102. +
    103. Ankersmit, "Historism and Postmodermism," 209. (Back)
    104. +
    105. 赫伊津哈曾說到《中世紀的凋零》中歷史洞識的淵源,「約在 1907 年的夏天,我太太往往需要花上一整個下午照顧小孩子,而我則常到格寧根的郊外去散步……就這樣,在一個星期日的下午,突然有一種觀念來到我的心中;十五世紀左右的中世紀並不是預示一個新時代的來臨,但卻顯露出一個已褪色的、日薄西山的時代。這由范艾克 (Van Eyke) 及其同時代之藝術家的作品中看得到,從他們的作品見不到北方文藝復興的曙光,相反地是中世紀精神的衰微。」見 Huizinga, J., Mijn Wegtot de historie (Leiden, 1946), 49-51( 由張淑勤教授提供 ), 史家陳寅恪先生在中國中古史研究上,提出的「關中本位政策」概念,似乎也有這樣的味道,雖然他為曾講述這個概念的形成過程,不過我們可以看到「關中本位政策」並不是歷史中有誰提出這個名稱,而是陳寅恪觀看中古史朝代興衰中的經驗,可以發現隱含以「關中本位政策」的歷史脈動。 (Back)
    106. +
    107. F. R. Ankersmit, "Can We Experience the Past?" in History-Making, The Intellectual and Social Formation of a Discipline: Proceedings of an International Conference, Uppsala, September 1994 (Stockholm: Kungl. Vitterhets, historie och antikvitets akademien: Distributed by Almqvist & Wiksell International, 1996), 51. (Back)
    108. +
    109. Ankersmit, "Historism and Postmodermism," 217. (Back)
    110. +
    111. Ankersmit, "Historism and Postmodermism," 217. (Back)
    112. +
    113. Ankersmit, "Historism and Postmodermism," 220. (Back)
    114. +
    115. 加達瑪,《真理和方法》,洪漢鼎譯 ( 台北:時報文化, 1993) , 393 。 (Back)
    116. +
    117. Ankersmit, "Historism and Postmodermism," 222. (Back)
    118. +
    119. 加達瑪,《真理和方法》, 401 。 (Back)
    120. +
    121. Ankersmit, "Introduction: Transcendentalism and the Rise and Fall of Metaphor." in History and Tropology, 23. (Back)
    122. +
    123. 安可史密斯對西方後設敘述的看法,與李歐塔的看法正好相反,李歐塔在《後現代境況》 (The Postmodern Condition: A Report on Knowledge) 主張後設敘述主要的功能是合法化科學。安可史密斯則認為剛好相反,主要是前者注意歷史和社會的脈絡,後者則注意科學認識論的合法性。 (Back)
    124. +
    125. Fredric Jameson ,《後現代主義或晚期資本主義的文化邏輯》 (Postmodernism, or, The Cultural Logic of Late Capitalism) ,吳美貞譯(台北:時報, 1998 ), 28 。 (Back)
    126. +
    127. 「懷舊經驗」亦可參考詹明信的《後現代主義或晚期資本主義的文化邏輯》, 335-54 。 (Back)
    128. +
    129. 以上四點特徵可以參見 Ankersmit, "Historism and Postmodermism," 223-24. (Back)
    130. +
    131. Ankersmit, "Historism and Postmodermism," 225-56. (Back)
    132. +
    133. Ankersmit, "Historism and Postmodermism," 228. (Back)
    134. +
    135. Ankersmit, "Historical Representation," 122-23. (Back)
    136. +
    137. Ankersmit, "Historism and Postmodermism," 229. (Back)
    138. +
    139. Ankersmit, "Historism and Postmodermism," 229. (Back)
    140. +
    141. Ankersmit, "Historism and Postmodermism," 233. (Back)
    142. +
    143. Ankersmit, "Historism and Postmodermism," 234. (Back)
    144. +
    145. Ankersmit, "Historism and Postmodermism," 234. (Back)
    146. +
    147. Ankersmit, "Historism and Postmodermism," 234-35. (Back)
    148. +
    149. Ankersmit, "Historism and Postmodermism," 235. (Back)
    150. +
    151. Ankersmit, "Historism and Postmodermism," 230. (Back)
    152. +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/002/article05.html.html b/htdocs/htc/newsletters/002/article05.html.html new file mode 120000 index 0000000..fe3ea71 --- /dev/null +++ b/htdocs/htc/newsletters/002/article05.html.html @@ -0,0 +1 @@ +article05.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/002/article05.html.xhtml b/htdocs/htc/newsletters/002/article05.html.xhtml new file mode 100644 index 0000000..c185816 --- /dev/null +++ b/htdocs/htc/newsletters/002/article05.html.xhtml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + +Review of The Autumn of the Middle Ages + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    Johan Huizinga, The Autumn of the Middle Ages, trans. Rodney J. Payton and Ulrich Mammitzsch. Chicago: University of Chicago Press, 1996, xvii+467 pp .

    + +
    洪靜宜
    + +

    一、前言

    + +

    《中世紀之秋》 (The Autumn of the Middle Ages) 一書主在論述十五世紀法蘭西和尼德蘭地區—包括今天的法國東部、荷蘭、廬森堡、比利時一帶的文化,包括形式 (Forms) 、思想以及藝術的研究。在這裡,作者赫伊津哈 (Johan Huizinga, 1872-1945) 將十四、五世紀的文化視為整個中世紀文化的一部份,由此展現了他重建過去的才能,重新敲開布克哈特 (Jacob Burckhardt, 1818-1897) 的「文藝復興」概念的歷史時期,試圖呈現十四、五世紀法蘭西和尼德蘭的時代精神與心理狀態,用以重新連結被布克哈特所切斷之中世紀與文藝復興的關係。

    +

    基於對歷史連續性的信仰,赫伊津哈不同於布克哈特之以義大利為研究對象,而以尼德蘭和法蘭西為考察對象,來研究這一時期的文化現象,言下之意似乎有不讓義大利專美(文藝復興)於前的味道。其次,在方法上,兩者雖都標榜著文化史的研究,但在取向上卻有相當差異。布克哈特企圖在中古與近代之間,獨立出來一段義大利的文藝復興時代︰認為文藝復興與中古大不相同,舉凡個人主義、繼承特質、效忠觀念、榮譽追求、崇古態度、建築形式等,處處都體現 "art" —人的匠心獨運,大大異於中古的神的世界。

    +

    赫伊津哈承認,在布克哈特的世界裡,阿爾卑斯山南的義大利文化確有其動人之處,但究其實,當時人的精神風貌與心理狀態又何嘗離中世紀多遠?布克哈特似乎過分強調了中古和文藝復興的分界。1 義大利的藝術也是實用的。當那些變形修補過的畫被慎重地用為織物上的圖畫的時候,威尼斯的畫像裡,各個大公、貴婦們也無不極盡其能地將天鵝絨、絲絨、綢衣、織錦穿戴在身,深恐無人不知曉他們的榮華富貴;為的不外是使夏天過得涼爽些,他們不也在自家屋前築起令人賞心悅目的花圃、庭園;又用彩色的磚瓦鋪在屋頂和地板上,將錯綜的圖示、閃閃發光的器皿、象牙的雕像來美化他們的家庭。這些不都也是從實用的觀點出發的嗎?而義大利文藝復興的人的文化面貌表現亦充滿極端:奸謀險詐和政治才能,科學和迷信,憎恨和愉快,在易怒的心靈上交織出文藝復興。這些都跟中世紀太像了,怎能分的那麼絕對呢?文藝復興的特質又何嘗不是孕育於中世紀的心靈當中。因此赫伊津哈便在重新連結中古與近代的出發點上,開始重建與義大利文藝復興同時期北方的「文藝復興」—法蘭西、尼德蘭地區的文化。

    +

    本次研究主要從文本的分析,嘗試了解《中世紀之秋》一書的所要探討的主題為何?用什麼樣的方法?著作中有何特點?以及在作者的匠心獨運之下,十五世紀的法蘭西和尼德蘭地區的文化面貌的真相如何?如何呈現?

    + +

    二、著作的主題、方法及特色

    + +

    悲觀的時代氣氛與極端的心靈狀態

    + +

    從這時期的編年史﹑詩歌﹑佈道文﹑法律文件中反映出來的印象似乎就是「不幸」兩個字,2 似乎每個中世紀的心靈皆縈繞在憂鬱 (melamcholy) 的時代主旋律之中,久久不去。在十五世紀的法蘭西文學中﹐看不到義大利文藝復興式的樂觀,而是處處籠罩在深度的憂鬱之中;就連肖像畫中人物的表情﹐也是陰鬱不樂的。在文學的描述裡面,生命對人而言沒有任何喜悅﹐人活著只有痛苦的份﹐人的老死也是一片恐怖形象﹐對未來前景更是一片晦暗。3 對於死亡亦充滿著對生時的濃蔭悲歎,尤其是對於美好事物的倏忽消逝。4

    +

    這種悲觀的時代氛圍,與當時時局之不安密切相關。十四、十五世紀各國內部的政治極不穩定,王侯宮廷不時傳出廢立罷黜之事: 1399 年英王 Richard II 被其姪 Lancaster 逼迫退位,最後慘死於獄中;法王 Charles VI 時期的派系鬥爭; Louis of Orleans 和其支系勃艮第公爵 John the Fearless 永無止境的報復與爭吵。這些政治上的不安,在人民的理解中,就好像一齣齣不斷上演的血腥浪漫的悲劇。而王侯命運的動盪不安,更給予人民以一種騎士冒險經歷的想像。除了政治籠罩在敵意與報復的聲浪中而少有安寧之外,宗教的分裂,以及外部土耳其人的侵擾,都更加深這種不安的情緒。戰爭的不安,到處流竄的土匪,殘酷而不可靠的法律執行之威脅,對地獄的恐懼﹐對惡魔以及女巫的憂慮,在人民的心理上產生極大的不安全感。5 正是在這樣不安的時代氣氛之下,造就出極端的心靈面貌︰6 明與暗,黑與白,悲與喜,好與壞,健康與殘缺,幸與不幸,殘酷與柔情。

    +

    正是這樣不安的時代氣氛,滋長了這種極端分明的時代心靈。對生活的憂慮,以致對生命抱持輕蔑態度,最明顯地莫過於對女人生子的輕蔑描述。7 也正是這樣不安的時代氣氛,使人無力去與這個處處瀰漫沮喪氣餒厚重氣息的時代氛圍搏鬥,而徹底宣告投降。然而這個時代的不安氣息並不因此而暫緩,仍無情地撲向這些已經舉了白旗的心靈而去。

    + +

    衝突與調和:形式的應用

    + +

    透過赫伊津哈的描繪,我們可以對生活在五百年前的人們有一個印象:他們對一切事物的看法﹐總是那麼涇渭分明﹐沒有灰色地帶;而那種易慟的心靈狀態﹐常常會為了一場遊行﹐一位佈道家的言語而熱淚盈眶。8 在這裡﹐赫伊津哈透過形式 (Form) 的建立﹐與中世紀的心靈僅僅相繫在一起。每一事件、行為都透過特定的與意義深長的形式 (Form) 而被了解。而人的一切活動,如所屬的身分、地位、階級、都可以從服色的穿著上顯示出來;法律的執行、貨物的買賣、婚禮、喪禮的活動之意義,均透過長形的隊伍、呼喊、悲歎而彰顯而明白。9

    +

    這種形式 (Form) 的應用,是赫伊津哈治史的獨到之方。他認為要了解過去並反思自己的文化,史家必須掌握到歷史的「形式」。透過「形式」,歷史才能說話。10 相對地說,也只有透過這種有形的形式,事情才能如圖畫般存在於人的內心;11 心靈與視覺相互呼應,生活在那時代的人才能感受到事情的意義。視覺印象 (Visual Image) 的應用也是赫伊津哈著史的特色之一,目的在喚醒人對歷史的想像。12

    +

    在中世紀,理想與現實之間存在著許多衝突,但表面上卻好像調和得很好而看不出來,那是因為這種衝突的面貌,是以不斷的「新形式」呈現出來的。例如在騎士精神摒除了宗教的完美性,不再是信仰的維護者和被壓迫者的保護人,僅只是一種社會生活的方式,榮譽和光榮的象徵時,人們渴望從其他地方尋求失去的崇高性。因此,騎士精神逐漸讓位於現實的戰略、戰術以及具現代性的步兵和火器;而騎士的形式最後終未消失,但已移轉到田園的形式,最後連比武大會、宮廷慶典也進了田園詩。13 新形式的不斷出現,便是中世紀理想與現實之間的一種調和與轉換,同時也代表中世紀心靈力量的強烈,足以將衝突轉化為另一種形式而加以接受。然而必須注意的是:一種新形式的形成,並非是在舊的已經消亡之時,而是在舊形式的土壤之中孕育而成。14 這是赫伊津哈屢屢強調的概念。

    +

    《中世紀之秋》所採用的這種形式結合視覺意象使人對過去產生圖像式的印象,提供了讀者一個視覺上的畫面,如一棵大樹,它的枝葉因太過繁茂而顯得老重,因為新的枝枒(形式)正不間斷地從舊支幹上冒出,而從不理會這樣的繁茂是否可以讓大樹承受得起。新舊形式的交錯構成了中世紀的文化面貌內容,以「過度」 (Over-) 的形式展開,從有形的到無形的,如 overladen with embellishments ( p. 85 ), overabundance of devotional content, oversensitive mind ( p. 220 )。15 在這個宗教生活支配一切的時代,宗教的虔誠不斷為冗長又無聊的宗教論證,如巴黎大學對徵收學位考試的費用、無止盡的計數比賽;16 過多的圖像、儀式、禮節,言語上過度以宗教包裝等形式所降低,最後流於輕佻的行徑。17 而中世紀的凋零,其實就是代表著中世紀文化面貌的形式,其活力逐漸衰疲、老年的過程。

    + +

    三﹑結論

    + +

    由書名 Autumn 可以看出來,赫伊津哈所要處理的是一個時代逐漸由成熟、老化乃至凋零的「有機」過程,而將整個十四、五世紀的文化視為中世紀文化體的最後階段,試圖表現出過度成熟、即將凋謝、再結新枝的情境。這樣的表現方式與布克哈特是截然不同的:一個是開端,一個是結束。

    +

    在赫伊津哈的歷史世界裡,時代與時代之間是交光互影的:古典形式可以表達陳舊的概念,傳統的形式亦能包含未來時代的精神。所以沒有什麼絕對的疆界可以獨立於歷史的連續性之外。歷史既是連續性的,中古與文藝復興之間的距離就不應那麼遙遠:文藝復興有它的特質,中世紀亦有其時代特性,兩者並非完全不能溝通。

    +

    因此文藝復興在赫伊津哈的理解是將之視為整個中世紀文化的一部份。十五世紀義大利的文藝復興已然消除了中世紀思想的羈絆,相反地,十五世紀法蘭西文明的歷史並不能忘卻中世紀;其人文主義的形式,並未敲響文藝復興的鐘,因為他們的情感傾向仍是中古的。18 所有的中世紀形式:封建主義、騎士精神、謙恭觀念、經院哲學、哥德式建築,皆植根於遠比義大利要深的土壤;在十五世紀,這些形式雖仍居支配地位,但是也都在衰落當中,同時新事物也正在萌生、發芽。

    + + + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +
    + +
      +
    1. Johan Huizinga, The Autumn of The Middle Ages, trans. Rodney J. Payton and Ulrich Mammitzsch (Chicago: The University of Chicago Press, 1996), 74. (Back)
    2. +
    3. Huizinga, The Autumn of The Middle Ages, 29. (Back)
    4. +
    5. Huizinga, The Autumn of The Middle Ages, 32-35, 160. (Back)
    6. +
    7. Huizinga, The Autumn of The Middle Ages, 157-58. (Back)
    8. +
    9. Huizinga, The Autumn of The Middle Ages, 12-24. (Back)
    10. +
    11. Carlo Antoni, From History to Sociology (London: Merlin Press, 1962), 188. (Back)
    12. +
    13. Huizinga, The Autumn of The Middle Ages, 160. (Back)
    14. +
    15. Huizinga, The Autumn of The Middle Ages, 1-9. (Back)
    16. +
    17. Huizinga, The Autumn of The Middle Ages, 1-2. (Back)
    18. +
    19. 張淑勤,〈文化史家 Huizinga ( 1872-1945 )的史學〉,《史學與文獻(二)》(台北:學生, 1998 ), 263 。 (Back)
    20. +
    21. David Gary Shaw, "Huizinga's Timeliness," History and Theory 37: 2 (May 1998): 252. (Back)
    22. +
    23. 赫伊津哈認為歷史研究的基礎是「歷史感覺」 (Historical Sensation) ,而歷史感覺之產生常隨著對「過去」的視覺而來。參見:張淑勤, 12 。 (Back)
    24. +
    25. Huizinga, The Autumn of The Middle Ages, 61-125. (Back)
    26. +
    27. Huizinga, The Autumn of The Middle Ages, 382- 83, 386, 389, 391- 92, 395- 96. (Back)
    28. +
    29. Shaw, "Huizinga's Timeliness," 249. (Back)
    30. +
    31. Huizinga, The Autumn of The Middle Ages, 249- 52. (Back)
    32. +
    33. Huizinga, The Autumn of The Middle Ages, 173- 202. (Back)
    34. +
    35. Huizinga, The Autumn of The Middle Ages, 396. (Back)
    36. +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/002/article06.html.html b/htdocs/htc/newsletters/002/article06.html.html new file mode 120000 index 0000000..1688ac2 --- /dev/null +++ b/htdocs/htc/newsletters/002/article06.html.html @@ -0,0 +1 @@ +article06.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/002/article06.html.xhtml b/htdocs/htc/newsletters/002/article06.html.xhtml new file mode 100644 index 0000000..f95d0ae --- /dev/null +++ b/htdocs/htc/newsletters/002/article06.html.xhtml @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + +Review of American Progressive History + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    Ernst A. Breisach, American Progressive History : An Experiment in Modernization. Chicago and London: The University of Chicago Press, 1993, ix+258 pp.

    + +
    陳思仁
    + +

    + +

    本文所要介紹與評論的著作,是由布萊薩 (Ernst A. Breisach) 所撰述的《美國進步史:現代化的一個嘗試》( American Progressive History : An Experiment In Modernization, 以下簡稱《美國進步史》)。布萊薩以其對於歐洲史學背景的瞭解,將美國進步史學所面臨的現實文化壓力對等於當時歐洲,有別於過去探討美國進步史學的文章,總是將進步史學獨立放在歐洲史學脈絡之外。

    +

    《美國進步史》一書主要由十八個章節所構成,分別列入四個主題加以論述。其一連貫的主旨目的乃在呈現美國進步史學在歷史理論方面做了一個重要嘗試;同時,藉由論述每一個參與建立進步史學的主要學者─魯濱遜 (James Harvey Robinson, 1863-1936) 、畢爾德 (Charles Beard, 1874-1948) 、貝克 (Carl L. Becker, 1873-1945) ─的興趣與傾向,說明進步史學僅管是很鬆散的學派,但是對於其所解釋的主題,仍有其一貫脈絡網──即對於「進步」的信心。

    +

    《美國進步史》的主要四個主題,分別為「走向進步史, 1890-1904 」、「進步史的建立, 1904-1917 」、「成就與穩定的年代, 1920-1929 」、「相對主義者的嘗試及其再評估, 1929-1948 」。第一部份,陳述進入現代性 (modernity) 的美國社會,面臨著社會問題與對美國過去與現在及未來歷史的懷疑,以此說明美國史家探索新史學的背景。作者意圖透過進步史學與美國現實社會所進行的對話方式,說明進步史的產生乃是為解決源自美國社會內部的問題。第二部份,闡述進步史的孕育情形,說明進步史學意圖將充滿現代精神的熱情注入美國史學史中;但是,對於現代性本身所產生的確定 (certainty) 意義又保持著肯定與懷疑兩種態度。第三部份,一方面呈現進步史學可謂形成成熟的學派,卻也呈現其內在的矛盾。第四部份,首先是進步史學的理論基礎在 1930 年代面臨大的轉變──相對主義;爾後,當畢爾德和貝克於 1930-1940 年代面對意識型態上的爭鬥時,為求理論上能更深層的捍衛自由民主而積極的為史學尋求新的穩定的 (stable) 基礎,進而同時也能對於連續性觀點 (a sense of continuity) 的永久需求有更肯定的回應。1

    +

    布萊薩在導論即開宗明義向讀者揭示其著作的旨趣:「我要論証的是,進步史的發展關係著美國史學本身試圖大膽且有系統的現代化。」2 作者透過描述進步史家對於「新史學」 (New History) 的探索,以解釋進步史學建構的開始與過程。而當進步史家在嘗試現代化美國史學時,也意圖現代化美國認知歷史的觀點與修定對自身歷史的瞭解。本文將就布萊薩如何解釋美國所面臨的現代性問題,以導引出布萊薩對進步史學的認知,藉此簡介《美國進步史:現代化的一個嘗試》一書。

    + +

    + +

    「現代」一詞,指涉一新的時間概念,與舊的、古老的相對立;而當我們將之作為一個時代劃分的方式時,它指涉新的時代,與先前時代是相對比的。做為一個「現代化的嘗試」的進步史學,即是在此定義之下,形成一特別的美國史學時期。

    +

    首先,布萊薩在《美國進步史》第一章詳述美國現代化社會的發展,以工業化的命題證明美國進入現代化社會,並將 1893 年在芝加哥展出的「鉛的世界博覽會」,作為象徵美國走向工業化的成就。因此,建立在以辛勤勞動為象徵的「過去」農業傳統,受到芝加哥博覽會所標示的工業化衝擊,在兩相對比之下,形成一種「過去」與「現在」斷裂的歷史個體,所以這也是後來民粹黨為何會要求傳統舊秩序建立的歷史訴求。顯然這之間代表美國克服 (overcome) 過去的表現,具有進步的意義,但是斷裂本身卻標示美國走向現代化的危機之一,因為斷裂中沒有連續的史觀以解釋美國歷史如何從過去過渡到現在,即使是科學史學也無法提供解釋。布萊薩認為,進步史家所要解決的問題,即是如何解釋過去與現在的關係。

    +

    再者,美國的未來指標似乎也呈現疲疺,布萊薩以為,當美國如西歐國家一樣走向現代化社會時,也同時踏入相屬的世界舞臺,美國再也不具備做為一個有獨特 (exceptionality) 歷史發展的國家。曾經,美國拒絕舊社會(西歐)的所有社會經濟衝突,從過去中自我解放,意圖來到美國尋求新世界的發展,自視在上帝眷顧之下(清教徒的神聖使命),努力為未來的使命(建立一個基於民主自由理想的共和政府)而努力,這種信念使新世界的人對於任何變動一直有一定的信心,然而工業化所代表的進步意義,卻使美國人感到美國歷史的使命是否已達到終點(歷史的終結)?未來呈現不確定甚且無方向!進步史學重新解釋美國史及賦予美國一個新的未來指標,就是在此歷史感受之下。

    +

    此外,象徵進步的工業化、科技化與城市化,其負面呈現的卻是普遍的貧窮化、階級衝突、農業的損耗與移民潮帶來的不確定,十九世紀末的移民對於美國未來所抱有的深切使命感再也不如過去十七、八世紀的移民者。而一群集中居住於城市沒有創造力的新興商業階級,並且取代過去傳統領導者,使人認為美國自身創造力已然衰竭,面臨此情境,科學史學卻無法提供任何解釋。布萊薩以為,進步史學的產生乃是要回應此問題,以至進步史家總是隱含「改革」 (reform) 的社會關懷,並且訴求一個新的史學 (New History) (當時西歐國家都在尋求「新史學」以解決自身國家問題),要求一個包含文化、社會及可以整體概括解釋一切現象綜合的史學。

    +

    工業化、科技化、城市化標示著科學結合的成果,科學史學 (scientific history) 因應此科學文化所產生的探索史學基本方法─即史料的考証分析等─也要求必須符合科學規範 (discipline) ,進步史學仍維持此研究 (research) 方法。基本上,科學史學與傳統美國歷史觀能夠相契合,在於美國的民主政治是科學思想的產物,而戰勝文學性質的歷史也是科學史學進步的表現。然而,科學史學的知識卻無法解決現代化的政治社會問題,以及為現代化的美國提供一個持續發展的史觀與未來的指標。

    +

    布萊薩視美國進步史學的產生乃是意圖解決美國現代化所衍生的社會問題,而當時( 19th–20th 間)西歐社會也面臨同樣現實問題,因此,僅管布萊薩將進步史學的史觀發展脈絡,獨立於西歐之外(即意圖解釋美國進步史學不受歐洲史學影響);但是,進步史家探究 (inquiry) 「新史學」的社會背景是與西歐一致的(事實上,布萊薩提示的主要國家是法國與德國)。

    + +

    + +

    布萊薩認為,不被列為進步史家的特納 (Frederick Jackson Turner, 1861-1932) ,其對進步史學貢獻,是使美國史學史由科學史學過渡到進步史學。特納保留科學史所要求的方法,以進行對美國歷史重新詮釋,僅管特納史學的理論性不強,但是,重要的是在於特納提出,要求一個能包含所有一切的史學:如強調歷史的有用性,以群眾史取代過去的事件史,尋求塑造歷史的偉大力量,加重生活中的經濟面向,強調無止盡且普遍的變動,認知世界史以做為指標。3

    +

    特納所建構的地理環境主義 (geographical environmentalism) 是類似於達爾文的進化論。藉由地理空間 (space) 的無時間性以說明其對人類生活的持續影響。空間是一個非常具體的存在實體,美國自己的民主淵源在此情形下被塑造,將是一種無止盡的權利,因此有關美國的「歷史持續性」問題被解決,特納對提供予新史學的乃是連續性 (continuity) 的史觀。

    +

    同時,這個「空間」(即邊疆)也僅有美國獨有。因此,美國創造其特別的民主與群眾,維持其歷史的獨特性 (exceptionality) 。在這個持續緩慢的變動所造就的是永久 (permanency) 的來源:民主。美國的邊疆空間提供一個欲脫離歐洲專制統治的地點,隨著不斷的空間移動,美國也從狩獵與農業的經濟進化至工業,如此突顯早期西部群眾的貢獻,也相對脫離科學史一昧強調的政治史與政治人物的貢獻。再者,特納也嘗試建立因果關係:美國空間與美國民主的形成。

    +

    然而,邊疆的開拓總有止盡,因此其突顯的問題似乎又是:那接下來的美國未來,難道因此而停頓發展?雖然在特納的邊疆論中顯現美國的發展是走向愈來愈美好的社會,並且特納也為美國民主建立一個發自本土的民主發展,一個完全不必訴諸歐洲淵源的民主,使進步史學能更有利的談論「現在」與「未來」。但是,其邊疆論未能適用普遍美國各地,也未能在訴諸美國的獨特性時,建立更有效且強烈支柱。因此這也是進步史學必須完成的工作。

    + +

    + +

    現代主義的歷史觀念在於克服、超越所有舊有的、古老的事物。依筆者之意,布萊薩認為進步史學意圖賦予美國歷史新的解釋,是建立在進步 (progressive) 理念的架構上,「現在」克服、超越了「過去」,代表進步的意義。進步史家意圖以「進步理念」涵蓋社會整體的全面解釋,再佐以其它政治、社會、經濟等社會學理論,以圖保留歷史解釋的科學性。

    +

    那麼「進步」的定義是建立在什麼解釋上?布萊薩認為進步史家賦予史學史新的功用性 (utility) 是:史學史本身必須具備現代心智與未來的取向,並且拒絕保留使過去因子持續運行的舊習慣。如此,史家可以不必汲汲於想捉住過去歷史的完全真實情境以符合現在 (present) 的結構;重要的是,必須理解到「現在」的主導性,當一個新的時代來臨時,超越「過去」是必要的;進步史家的理想,其實是合理化了工業化與資本化的必要性與成就。而史家的責任是「適時」的幫助形塑適切的未來,這可說明為何進步史家喜歡研讀近代史,因為時間愈接近近代,進步的因子分佈的愈多。「過去」成為進入「現在」的必要與自願犧牲者,當過去轉向並且基於未來而開發時代時,新時代即來臨。這也標示進步史時代 (age) 的來臨。

    +

    「過去」與「現在」兩個歷史個體的斷裂成為必然,早期的進步史學基於認同工業化的美國社會,因而必須合理化「現在」的必要性。但是,在「進步」的前題預設 (proposition) 之下,「現在」也會成為「過去」。歷史不再有終結的時候,因為「進步」是指向「未來」。一切焦點是為了使歷史從過去的束縛中解放。因此,史家的責任是在發現阻礙未來進步的過去因子。布萊薩認為,進步史學說服自己,一切衝突 (conflict) 是因為「現在」進步因子( good, 「善」的)仍存有不好的「過去」因子( evil, 「惡」的),故史家的責任是找出何者是「惡」,以利「現在」的進步。而解決一切問題的手段,則以透過「政治」方式為最重要。因此,進步史家對政治史極為重視。

    +

    「進步」本身的信念是經驗式的 (empirical) ,進步的模式源自事實 (facts) 的建立而形成,亦即由事實中尋求攸關進步的解釋,如此,進步史家在事實與解釋 (interpretation) 中建立天衣無縫的聯結。進步史學並未放棄基礎研究,如史料的必要性與科學性,但是,僅只探求史料或直至史料齊備才研究,是無助於解決當代美國社會問題。因此可以如此說,進步史家所突破的即是建立在有史料事實基礎上的進步觀點,並且將所建立的完全事實 (body of facts) 用以揭示代表進步的歷史力量與歷史構造。

    +

    這種「進步」理念取材自達爾文的進化論 (evolution) ,同樣是從對自然現象的研究所獲得的科學論證,因而將其應用於人類世界也同樣具備科學性。而進步史家將「進步」及向前 (upward) 發展的概念等同於進化意義,卻忽略了達爾文主義中所強調的適者生存、為生存爭鬥、及一個很純粹的環境等概念。不過,進化論的確為「進步」理念賦予神聖的科學性,並且保証了社會是從簡單到複雜的過程,因應現代化複雜的社會,進步史學在此尋找到一個提供說明整體社會概念的史學觀,而這是科學史學無法為美國歷史提供的保証。

    + +

    + +

    「人類的歷史乃是人類在社會中的歷史,因此社會史應該極盡廣度」4 ,此句話適足以說明「新史學」對歷史範疇的認知。面臨工業化社會,史家須汲盡靈感以探索及解決社會「整體」問題。於是,進步史學將歷史置於更寬廣的範疇中以探索人類生活,試圖藉用社會科學理論或尋求定則 (law) 以解決社會問題。不過,依布萊薩之意,魯濱遜、畢爾德與貝克等人卻未曾自社會科學理論汲取定則,因為進步史家本身即有一個普遍性的偉大的定則—「進步」。至於桃樂絲‧蘿斯 (Dorothy Ross) 在其著作《美國社會科學起源》中 (The Origins Of American Social Science)5 更強調進步史學與社會科學關係密切。

    +

    魯濱遜的《新史學》 (New History) 一書,即是標明進步史家期望透過其它社會理論方法以解決現實問題。所以,一直為科學史所注重的政治史在新史學的議題中仍佔中樞;而國家 (nation) 也是其中心議題,主要是因為,這關係著勸說美國公民改革共和政治以解決社會問題。但是,畢爾德等人的確深覺過去的政治史是太狹隘,僅是事件的表面敘述,記載國王皇后等名稱,無法提供歷史真實的內涵,甚且導引出能提供解決現實問題的「過去」。因此,畢爾德從經濟方面詮釋美國憲法的制定過程。布萊薩認為,這主要是因為進步史家對於社會問題產生的根源沒有充份的理解。筆者以為,進步史家希冀透過政治層面以改革社會的用心,顯見其對民主政治的信心,例如畢爾德抱怨美國民主的不完整性,因而提出雙元革命論,藉由「美國憲法的經濟解釋論」 (An Economic Interpretation of the Constitution of the United States) 此書,公開批評美國憲法不民主,提供人們意圖藉由改革政治以改善社會問題的合法性。而此書也同樣藉用馬克思 (Karl Marx) 的政治經濟學理論。

    +

    受工業社會的影響,魯濱遜在其書《新史學》中,以工業化生活的結構為衡量標準:亦即注重群眾史,因為工業化使得群眾受苦卻也使大眾獲得某程度的解放,所以群眾從過往的歷史背景中走出來;雖說如此,新史學並未減低長久以來科學史一直重視的獨特個人 (individual) 的歷史角色,進步史家仍然認為其才是決定歷史的代理者 (agent) 。只是,新史學所選擇的個人乃是具有理性 (rational) 、積極扮演進步使者的獨特英雄(一種現代化的史觀),至於群眾的歷史角色,最重要的是使其瞭解歷史中引導進步的動力,這也說明為何新史學成員非常注重教育。

    +

    新史學成員如魯濱遜、畢爾德及貝克等人對於所謂獨特的個人有不同見解,如畢爾德較在乎對歷史科學方面的進步有貢獻者,如培根 (Francis Bacon, 1561-1626) 、牛頓 (Isaac Newton, 1642-1727) 等科學家,亦即對現代化有貢獻者,將個人視為社會改革的重要角色。魯濱遜較注重對於能形塑未來歷史的智識世界的過程有貢獻者。群眾基本上仍然只是停留在偉大參與者背後的點綴角色。

    +

    新史學成員強調且肯定獨特個人對於歷史進步有貢獻者,然而又想在政治事件構造底下尋求一個固定的歷史力量及真實( real ,即指「進步」的史觀),這之間是有衝突的即到底那一種才是真正促進歷史持續進步的主因?而且欲圖尋求與促進「進步」有關的個人或歷史力量,此自我設限的「進步」想法,卻又如實證史觀一樣,事前有一約定成俗的歷史觀,但絕不是先驗的或形上學的史觀;不過,相信「進步」是歷史發展的主要趨勢,這是間接有助於肯定工業化與都市化的現代成就,亦即是站在資本家立場,使美國人不須質疑當代的發展。況且,「進步」觀也透過歐洲工業化社會而證明了其普遍性。

    + +

    + +

    布萊薩在《美國進步史》一書中,顯然對相對論史觀給予較正面的評價,認為貝克將「理念」 (idea) 追溯到過去傳統中,一反進步史學總是將視野 (perspective) 投向未來。「理念」因源於傳統而能獲得權威,現在與過去因為「理念」的「連續性」而獲得聯繫,不再是兩個斷裂的歷史個體,史家的責任轉變成為傳統的維繫者。對進步史學而言,進步理念是前題預設,是意圖可以涵蓋整體社會的現代歷史觀念;對相對論而言,「理念」是指特定的時代氛圍中的觀念與價值。

    +

    對「進步」信念的信仰與樂觀是建立在進步史家對美國工業化的信心。社會現實 (reality) 是「進步」信念的保證,一旦現實經驗失去與進步有任何的直接連想時,「進步」信念就成為一種想像 (imagination) 。

    +

    兩次大戰呈現人類非理性行為,甚且有「西方的沒落」 (The Decline of West) 論調,顯現人類對現實的失望及悲觀。筆者認為,相對論 (relativism) 史觀在大戰後出現,實是前題預設的進步理念與客觀現實無法互印照所產生。這揭穿了原來史家是透過自我主觀的 (self-subjection) 意念編排「過去」;也說明進步史學自以為有了「進步」的保證,「過去」便會如同鏡子般呈現真實的客觀 (objection) 事實是不可能的。故進步史學並未成功的建立現代性史學的理論,亦即進步史學並未獲得一個勝利的結局;進步史學意圖開拓的新史學,也未能成功的為美國對歷史的瞭解創造一個現代觀點與現代史學的模式。因此,進步史學未能使美國史學現代化,因其未能建立一個能呼應現代社會整體的現代史學理論,也因為其進步理念失去歷史實體的支撐,而使其藉用的社會學理論轉而沒有整體概括的力量。

    +

    進步史學的失敗也在於其知識論上無法突破主觀與客觀的對立問題,只能尋求客觀事實的本質( essence, 即「進步」)以保障過去事實重現的客觀性。相對論史觀雖然察覺主觀意識對於獲得客觀事實的主導力,卻仍然堅持知識論上主客觀的存在,而導至相對論的問題,另一方面,「進步」信仰也無法從現實上獲得保證,懷疑論調就此籠照貝克的史觀。不過,整體上而言,進步史學對「進步」的充份信心,使美國在大戰後,能避免如歐洲國家的懷疑主義與文化上悲觀論調。

    + + + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +
    + +
      +
    1. Ernst A. Breisach, American Progressive History : An Experiment in Modernization (Chicago and London: The University of Chicago Press, 1993), 2-3. (Back)
    2. +
    3. Breisach, American Progressive History, 2. (Back)
    4. +
    5. Breisach, American Progressive History, 22. (Back)
    6. +
    7. Breisach, American Progressive History, 42. (Back)
    8. +
    9. Dorothy Ross, The Origins Of American Social Science (Cambridge: Cambridge University Press, 1991). (Back)
    10. +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/002/article07.html.html b/htdocs/htc/newsletters/002/article07.html.html new file mode 120000 index 0000000..20ea4b4 --- /dev/null +++ b/htdocs/htc/newsletters/002/article07.html.html @@ -0,0 +1 @@ +article07.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/002/article07.html.xhtml b/htdocs/htc/newsletters/002/article07.html.xhtml new file mode 100644 index 0000000..d981ea5 --- /dev/null +++ b/htdocs/htc/newsletters/002/article07.html.xhtml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + +編者言 + + + + +
    + +
    + 回目錄 | + 前一篇 +
    + +

    編者言

    + +

    《歷史:理論與文化》於西元一九九八年七月創刊,刊物出版至今已屆週年,期間受到眾多讀者的支持、關懷與指教。在此,全體編輯委員要向所有給予本刊鼓勵與支持的史學同好,致上最真誠的謝意。同時,本刊也將秉持著創刊的宗旨與精神繼續努力,期能對台灣的西洋史研究有所獻替。

    +

    《歷史:理論與文化》第二期刊物在經過一年的辛勤耕耘,總算要出刊了。由於本刊乃由一群年輕的西洋史研究工作者所發起,資源較為匱乏,且在創刊初期投稿者較少的狀況之下,本刊物之發行定為一年一刊。但是,我們也深切的期望這份刊物,將來能發展為一份西洋史研究的專業性期刊。於茲,也希望能有更多的西洋史學同好能不吝指教,甚或踴躍投稿,以期使本刊物更為茁壯。

    +

    在本期內容當中,凡有四篇論著與兩篇書評。其中,由盛少輝所撰寫的〈臺灣史西洋史研究的理論與實際:一個嘗試〉一文,乃基於本刊物創刊宗旨,更進一步的理論說明與探討,特此說明。另外,值得本刊慶賀的是,本期刊物文章也收到多位論著的投稿,其中包括了台大歷史學研究所碩士班黃煜文與輔仁大學歷史學研究所碩士班洪月娥的文章論著與書評,在此特致上本刊最高之謝意,也期待將來更多有心於西洋史研究的同志能踴躍投稿本刊。

    +

    在此,預告本刊第三期與第四期之主題,也希望對相關領域有所專精之論者能踴躍投稿。在本刊第三期當中,將擬定以西洋婦女史為主要研究取向之專號,在第四期當中,則以當代史學史、史學理論為主要研究取向之專號。

    + +
    + 回目錄 | + 前一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/002/article08.html.html b/htdocs/htc/newsletters/002/article08.html.html new file mode 120000 index 0000000..a2dd852 --- /dev/null +++ b/htdocs/htc/newsletters/002/article08.html.html @@ -0,0 +1 @@ +article08.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/002/article08.html.xhtml b/htdocs/htc/newsletters/002/article08.html.xhtml new file mode 100644 index 0000000..ad782c3 --- /dev/null +++ b/htdocs/htc/newsletters/002/article08.html.xhtml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + +誌謝 + + + + +
    + +
    + 回目錄 | + 前一篇 +
    + +

    誌謝

    + +

    《歷史:理論與文化》於西元一九九八年七月創刊,刊物出版至今已屆週年,而第二期刊物在經過一年的辛勤耕耘,總算也要出刊了。期間受到眾多讀者的支持、關懷與指教。在此,全體編輯委員要向所有給予本刊鼓勵與支持的人士,致上最真誠的謝意。

    + +
    +

    贊助者

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    劉崇紘教授遺贈07/23/985000 元整
    王芝芝11/10/982200 元整
    王晴佳04/28/991000 元整
    林慈淑07/30/981000 元整
    林龍江09/03/98500 元整
    吳燕秋09/19/98500 元整06/03/991000 元整
    徐文路11/14/98500 元整
    張 元11/07/98600 元整
    張淑勤11/30/981000 元整
    盛少輝11/14/981000 元整
    陳思仁10/27/982000 元整06/03/991000 元整
    陳逸雯11/30/98500 元整
    習沛祺08/31/981000 元整
    黃耀董08/31/98500 元整
    楊淳嫻04/23/99100 元整
    劉蓮恩02/01/99500 元整
    潘宗億11/14/981000 元整
    顏朝明07/03/981000 元整
    蕭道中11/14/98500 元整
    +
    + +
    + 回目錄 | + 前一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/002/index.html.html b/htdocs/htc/newsletters/002/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/htc/newsletters/002/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/002/index.html.xhtml b/htdocs/htc/newsletters/002/index.html.xhtml new file mode 100644 index 0000000..ad8e384 --- /dev/null +++ b/htdocs/htc/newsletters/002/index.html.xhtml @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + +第二期 目錄 + + + + +
    + +
    +

    歷史:

    +

    理論與文化

    +

    西洋史研究通訊

    +
    + +
    +出版者:
    +《歷史:理論與文化》編輯委員會
    +編輯委員:
    +吳燕秋、徐文路、陳思仁、盛少輝
    +黃明田、蕭道中、潘宗億
    +本期責任編輯:潘宗億
    +本期執行編輯:陳思仁
    +一九九九年七月一日出版
    +一九九八年七月一日創刊
    +
    + + + + +
    + + + + diff --git a/htdocs/htc/newsletters/003/article01.html.html b/htdocs/htc/newsletters/003/article01.html.html new file mode 120000 index 0000000..f89ba28 --- /dev/null +++ b/htdocs/htc/newsletters/003/article01.html.html @@ -0,0 +1 @@ +article01.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/003/article01.html.xhtml b/htdocs/htc/newsletters/003/article01.html.xhtml new file mode 100644 index 0000000..094ff9c --- /dev/null +++ b/htdocs/htc/newsletters/003/article01.html.xhtml @@ -0,0 +1,548 @@ + + + + + + + + + + + + + + + + + + + +布洛克歷史思想的核心概念與方法 + + + + +
    + +
    + 回目錄 | + 下一篇 +
    + +

    布洛克歷史思想的核心概念與方法*

    + +
    潘宗億
    + +
    +

    那是因為我們已經認知到在任何社會內部,無論其性質為何,政治與社會結構、經濟、信仰與心靈最粗糙與最細緻的展現,所有事情都是互相控制與關連的。1

    +

    因為歸根究底,人類的意識是歷史研究的主題;對歷史研究而言,人類意識之間的交互關係、糾纏及感染,就是真實本身。2

    +

    在本質上,歷史的事實是心理的事實。3

    +
    + +

    一、前言

    + +

    法國現代歷史學從 1870 年普法戰後到十九世紀末期間,在高等教育改革的基礎上,完成了歷史學的專業化與方法學派史學典範之建立的歷程。4 然而,方法學派所主張的歷史概念與方法,卻也遭受到社會學者涂爾幹 (Emile Durkheim, 1858-1917) 、西米昂 (Francois Simiand, 1873-1935) 與貝爾 (Henri Berr, 1863-1954) 等人的質疑與批判。爾後,由於歷史現實的發展如德雷福事件 (Dreyfus Affair) 與第一次世界大戰的爆發,使得歷史學家開始思考傳統史學的侷限性,尤其是新世代的史家也逐漸對方法學派的歷史概念、方法與歷史寫作的形式產生質疑。最後,新世代史家布洛克 (Marc Bloch, 1886-1944) 與費弗爾 (Lucien Febvre, 1878-1956) 創辦了《經濟社會史年鑑》( Annales d'histoire economique et sociale ,以下簡稱《年鑑》),基本上奠定了法國新的史學典範之建立的基礎。5

    +

    布洛克曾引阿拉伯諺語說:「人們像自己的時代,更勝於像自己的父親」。6 那麼,布洛克在這樣一個時代的學術歷程中,如何醞釀與形成自己對歷史學的思維呢?此外,面對時代向歷史學術所提出的問題,布洛克又如何提出他的回應與解答呢?

    +

    當法國歷史學與社會學論爭最為激烈的時期,布洛克正在法國巴黎高等師範學院學習歷史。7 他曾經將他對於歷史學與社會學之間論爭的觀點,記錄在 1906 年一份名為「歷史方法論」 ("Historical Methodology") 的筆記當中。8 從這份筆記當中,我們除了可以看到青年布洛克對於當時歷史學與社會學論爭的看法,也可以看出布洛克學生時期的歷史思想。此一筆記,是研究其歷史思想之發展與演變的重要依據。

    +

    首先,我們可以看到布洛克對於有關歷史研究之方法的觀點,一方面似與他的老師塞諾博斯站在同一立場,另一方面卻也抱持著相反的立場。例如,他認為歷史研究的方法在本質上,與其說是分析地,不如說是描述性與編年式的。但是,另外一方面,布洛克對於西米昂對歷史學所持的若干批判觀點,卻表示贊同的意見。例如,他認為歷史學不應該僅僅只是致力於事件、經驗的累積,而該進一步詮釋之。同時,布洛克認為在從事所謂的「心理-社會」 (psycho-social) 的現象之研究時,應該以分析的研究方法取代編年式的研究方法。因為,他認為應該稱「事件」 (events) 為「現象」 (phenomenon) ,而所謂的現象乃分析事件之後的產品。9 由此觀之,布洛克在歷史研究方法方面的思考,同時受到傳統方法學派與涂爾幹社會學派的影響,也表現出若干矛盾之處。

    +

    其次,在有關個人與社會群體之間關係的議題上,布洛克似乎表現出折衷的立場,認為兩者是不可分割的。其中,在一則有關宗教的社會現象的討論當中,他認為一個社會的宗教,在本質上應該是屬於社會整體的現象,而非個體的宗教現象的集合體。換言之,一個社會中所有個體的總和,並不代表就是一個社會之整體。這樣的陳述與涂爾幹社會學的觀點有異曲同工之妙。但是,布洛克並非像涂爾幹學派那般地完全僅著重於社會之整體,而忽略了社會中的個體因素,因為他也強調社會中個體與群體之間的內部互動關係。10 換言之,布洛克在注意到社會群體的因素的同時,也未忽略個體的因素。

    +

    再者,有關歷史學與社會學之關係的議題,布洛克似乎未在兩者之間的作清楚的區別。在他的筆記當中,若干處甚至將歷史家寫成社會學家。他似乎認為歷史學與社會學是非常類似的,同時也認為歷史學家應該可以從社會學的方法獲得助益。11 這樣一種主張科際整合的觀點,其實並不值得驚訝。因為,早在 1894 年,歷史學家拉孔已經發表過類似的言論。但是,與拉孔不同的是,布洛克認同西米昂等人的論述,認為歷史學應該採用問題取向的研究方式。由此觀之,布洛克在其早期的歷史思想中已經有科際整合的傾向,並已呈現出其與涂爾幹社會學的親近性。

    +

    由這份 1906 年的筆記觀之,我們可以發現布洛克在其早期的歷史思想裡,已可窺見若干與傳統方法學派相異之處,更可見其對於社會學知識所抱持的善意。就歷史學的發展而言,面對時代所發出的問題,學生時期的布洛克也表達了他的觀點。

    +

    事實上,布洛克受到父親古斯塔夫的啟蒙,在孩童時期即已經對歷史產生了興趣。古斯塔夫是羅馬史的專家,其治史頗受古朗士的影響。12 進入高中以後,布洛克仍然對於歷史學保持高度的熱誠,在歷史的科目均獲優異的成績。 1904 年高中畢業之後,布洛克以極為優異的成績,通過巴黎高等師範學院歷史科的入學考試,進入高等教育體制中接受深造。13

    +

    1908 年,在通過歷史學與地理學國家檢定考試 (agregation) 之後,依循法國高等教育改革之後的傳統,布洛克赴德國進行短期的進修,曾在柏林大學和萊比錫大學聽課。14 兩年之後,在撰寫博士論文期間,布洛克於 1909 年申請加入了梯也爾基金會 (Fondation Thiers) 。一次世界大戰之後,布洛克於 1919 年進入史特拉斯堡大學任教,擔任中世紀課程的助理講師,一直到 1937 年轉赴巴黎大學索邦學院擔任經濟史講座,才離開史特拉斯堡大學。15 1939 年之後,由於第二次世界大戰的爆發,布洛克自願入伍服役參戰,其歷史研究的生涯也為之中斷。法國戰敗後,布洛克並未像多數學者流亡海外,例如他拒絕了美國紐約新學院 (New School) 的邀約,而選擇留在法國為地下反抗組織盡一分心力。之後,相當不幸地,布洛克於 1944 年三月被德國祕密警察逮捕,並於同年 6 月 16 日槍決,結束了其五十八年的生命之旅。16

    +

    從巴黎高等師範學院求學到進入史特拉斯堡大學任教之前,可謂為布洛克歷史思想的學習期與醞釀期。在巴黎高等師範學院求學期間,受到當時社會環境與思想風潮之影響,布洛克已經初步地萌發了日後革新歷史學的思想因子。首先,受到法國高等教育改革的影響,巴黎高等師範學校瀰漫著一股追求革新的學術氣氛,此也被認為是當時的巴黎高師精神 (normalien spirit) 的特色;其次,當時正值社會學與歷史學之間的論爭的高潮,再加上德雷福事件之後歷史學界已經表現出對如社會與文化新問題的關懷,與對傳統政治史的批判風潮。17 布洛克於此一時期的歷史研究取向上,似乎已經初具革新的色彩。例如,他的學位論文是有關巴黎南區的經濟與社會史的主題,非常不同於當時一般政治史寫作的趨勢。18 又如,布洛克申請加入梯也爾基金會時,其提出的研究計畫之主題為巴黎地區農奴的消失。19 在一次大戰爆發前夕,布洛克於 1913 年完成了他的第一本著作《法蘭西之島》 (The Ile-De-France: The Country around Paris) ,並發表於亨力貝爾所創辦的《綜合歷史評論》。20 貝爾《綜合歷史評論》一向以力促科際整合研究與革新史學為號召,而布洛克《法蘭西之島》一書則運用了語言學、人文地理學、地質學、古文書學、考古學與社會學等學科的概念,從事巴黎地區的農村、經濟與社會狀況之歷史研究。21 由此可見,布洛克在其歷史思想醞釀的時期,已經初具突破傳統政治史寫作與跨學科研究的傾向。

    +

    1919 年到 1936 年,是布洛克的史特拉斯堡時期,也是布洛克歷史思想逐漸成熟的關鍵時期。22 在史特拉斯堡大學任教時,布洛克結識了其一生在思想上最重要的盟友費弗爾,兩人在歷史思想上相互影響,並共同在 1929 年創辦了《年鑑》。23 同時,布洛克還結識了許多的社會科學家,並藉由以提倡科際整合為訴求的讀書會,與他們進行知識上的交流。24 其中,特別重要的是,布洛克也結交了涂爾幹社會學派的學者霍布瓦克,接受了涂爾幹社會學的洗禮。並且,霍布瓦克的集體記憶理論 (collective memory) 也對布洛克產生了深刻的影響。25

    +

    史特拉斯堡時期同時也是布洛克論著最為豐富的時期,主要的著作也大都在此一時期完成。 1920 年他完成了博士論文〈國王與農奴〉 (Rois et serfs) ,並以「非常光榮」 (tres honorable) 的評語通過論文口試。在此論文中,布洛克結合法律、政治、社會、經濟與心理等角度,從事法國十四世紀農奴制度、農奴解放之研究。同時,布洛克在此論文中也呈現出他對於形式 (form) 與儀式行為的興趣。26 而〈國王與農奴〉所呈現出來的特色,也明顯的展現在其日後的著作之中。 1924 年,布洛克出版了《國王神蹟》一書。在此書當中,布洛克結合了醫學、心理學、社會學與人類學的概念,論述中古十世紀到十八世紀期間,流行於法國與英國人們普遍相信經由國王的「御觸」 (royal touch) 可治癒因「國王的邪惡」 (King's Evil) 所引起的皮膚病 (scrofula) 的普遍心態,並論述此種心態的發生、發展與衰落的過程。27 《國王神蹟》一書,可說是布洛克在心態歷史寫作上的經典之作。另外,在此一時期布洛克所完成的主要著作是《法國農村史》一書。《法國農村史》是由 1929 年 8 月布洛克以法國農業體系之相關研究,參加奧斯陸 (Oslo) 的「人類文化比較研究中心」 (Institut pour l'Etude Comparative des Civilisations, or Institute for Comparative Reasearch in Human Culture) 所舉辦的「農業社群發展形式之研究」系列演說所集結而成在《法國農村史》一書當中,布洛克在歷史寫作上呈現了跨學科整合、比較方法的特色。後來,此書被譽為是法國農村史研究的奠基之作。28

    +

    離開史特拉斯堡之後,布洛克來到巴黎的索邦學院教授經濟史。在這最後一段的治史時期,布洛克先後著手寫作了兩本史學巨作,也就是《封建社會》與《史家的技藝》。29 其中,《封建社會》一書可謂是布洛克在其治史生涯中相關主題與領域的集大成之作,可以說充分地展現出布洛克歷史思想的特色。此書不但被視為研究歐洲中世紀封建制度的經典之作,更為後世學者譽為是「社會整體歷史」的最佳典範。30 而《史家的技藝》一書,乃是一部系統地探討歷史思想與方法的理論之作,從中可以窺見布洛克直至逝世之前歷史思想之全貌。此外,他自己本身也曾經以其在兩次世界大戰的經歷,著作了《戰爭回憶錄: 1914-1915 》 (Memoirs of War, 1914-1915) 與《奇異的敗仗》 (Strange Defeat) 兩本小書。31

    +

    在對布洛克學思生涯具有梗概之瞭解的基礎之下,筆者將進一步在本章中,提出對於布洛克歷史思想之核心概念與方法的詮釋。首先,筆者將試圖探討布洛克的社會整體歷史的概念及其科際整合的歷史研究取向。其次,說明布洛克歷史思想中倒讀歷史(倒溯研究法)、多層次的歷史時間觀、長時段等歷史的時間概念。然後,再探究布洛克從事歷史研究與解釋時所呈現的問題取向與比較方法的運用。最後,在布洛克歷史的概念與方法的論述基礎之下,藉由與布洛克學生時期歷史學筆記的兩相對照,從中說明布洛克歷史思想所呈現出的歷程與變遷之樣貌。

    + +

    第一節 歷史學作為一門研究社會的科學

    + +

    在法國現代歷史學的發展歷程中,布洛克最主要的貢獻,除了與費弗爾共同創辦《年鑑》之外,就是他在歷史思想與研究方法上的特殊見解。早在布洛克歷史思想的醞釀時期,就展現出若干革新存在於法國傳統方法歷史學派的弊端的企圖心。從布洛克就讀於巴黎高等師範學院時期所留下來的「 1906 年筆記」,就可見他在面對世紀之交歷史學所遭遇到的問題時,便表現出若干革新之處。總之,筆者認為,法國歷史學所面臨到的時代問題,在布洛克的心靈上實已刻下深刻的印記,並在他一生從事歷史研究的生涯中圖思解決之道。其中,布洛克的最後的未竟力作《史家的技藝》,即嘗試系統地探討有關歷史思維與研究方法的理論之作,來回應時代向歷史學提出的問題,並呈現出其歷史思想之樣貌。因此,在本節當中,將以《史家的技藝》為主軸,以布洛克其他主要著作為輔,探討布洛克如何描繪出歷史學的藍圖。

    + +

    歷史學的正當性問題

    + +

    十九世紀與二十世紀之交,法國歷史學似乎也面臨了該往何處去的十字路口。此時,歷史學術除了因為面臨政治、經濟與社會環境變遷的因素,而引發的內部認同危機之外,也遭遇到來自社會科學界,尤其是涂爾幹社會學家們的挑戰與質疑。其中,史家所遭遇到最為嚴重的質疑,莫過於歷史學的正當性問題。筆者認為,這個問題可以清楚地在《史家的技藝》這本書中獲得答案。

    +

    布洛克一直想要著作一本有關歷史思想與方法的系統論述,雖然《史家的技藝》是一本未竟之作,但已經可以窺見布洛克歷史思想之主要部份。32 雖然《史家的技藝》以「告訴我,爸爸,歷史有什麼用?」這樣一個看似天真、實為嚴肅的問題開展其全書之論述,但這本書實質上所企圖解決的就是歷史學正當性的問題。誠如其所言的:「歷史必須證明她之所以作為知識的一種形式的正當性。」33 此外,布洛克認為,提出這樣的問題與試圖回答這樣的問題並非天真,也並非如塞諾博斯與郎格諾所宣稱的是「無用的問題」。由布洛克嘗試回答這樣一個所謂的「無用的問題」的著作動機來看,我們可以發現到,布洛克企圖由此書開展出與其老師們不同的歷史概念。34

    +

    除了試圖解決歷史學作為一門知識的正當性之外,布洛克也企圖從史家實際從事研究工作的技術與方法的層面,探討史家應該如何從事研究以維護歷史學的正當性。因此,他說:「研究時運用的方法之價值與可靠性,一直到較低層次與複雜的技術細節,都是我們嘗試要評價的。……總之,主要的目標在於解釋歷史學家如何與為何從事其行業。」35 布洛克為了使《史家的技藝》不致流於純粹理論、抽象之作,所以非常強調於歷史學技術層面的說理。甚至,自稱「這只是一本屬於一個總是習於反省日常工作之藝匠的備忘錄。」36

    +

    首先,布洛克批判了歷史學與社會學所殘留的孔德實證主義之科學概念的遺毒。他認為,孔德式的科學概念,也就是追尋自然現象的法則,不應該套用在有關「人」的研究上。37 因為,人類的行為與活動,在本質上是非常複雜的現象,許多方面都超乎了數理上的測量。針對此,布洛克做了一個有趣的比喻:

    + +
    +

    在物理的實體 (physical realities) 與人性的實體 (human realities) 之展現兩者間所具有的差異,就如同鑽孔的工匠與製造琵琶的工匠兩者工作的不同,兩者都分毫必爭,但鑽孔工匠使用的是精密的工具,而琵琶製造者則主要是依賴他對聲音及觸覺的感受性。若由鑽孔工匠採取琵琶製造者的經驗方法,或者由琵琶製造者模仿鑽孔工匠,都是不智的。38

    +
    + +

    此外,由於愛因斯坦相對論的影響,時代的心靈環境已經改變,而科學的觀念也隨之變化。藉此,布洛克認為知識的確定性與普遍性已經失去其絕對的價值,因此,他認為沒有必要將自然科學的知識模型強加於各種知識領域之上,並進一步樂觀地指出,「我們這門學科的不確定性,不應該在其他人的好奇心前掩飾起來,而這種不確定性正是歷史學存在的理由。」39 換言之,所謂的科學性,不但不適合作為有關研究「人」之知識的規範,也已經不是知識是否具有正當性的絕對標準。

    +

    那麼,布洛克所謂的科學所指又為何呢?布洛克認為,能夠真正建立現象間關係之解釋的學科,才是真正的科學。否則,只是博學而已。準此,布洛克進一步指出,「歷史必須不僅僅是支離且近乎無窮盡的舉例,而該具有理性的分類與進步的清晰性,只有在這樣的前提之下,歷史才能正當地在那些真正值得盡力的科學中佔有一席之地。」40 換言之,歷史學必須放棄以往純粹「累積事實」式的敘述史、事件史的研究,改而轉向從事解釋現象間之關係的研究取向。因此,布洛克如此說到:

    + +
    +

    正如所有以人類精神作為對象的科學,歷史此一理性知識領域的新進者,也是一門尚在襁褓中的科學。或者,說得更清楚些,由於孕育於純粹敘述的胚胎中,歷史長期以來受困於傳說,而且長久以來更長久的只關注最醒目的事件。因此,以一門致力於理性分析的學問而言,她還是相當年輕的。41

    +
    + +

    在此,布洛克不但認為歷史學應該是以理性分析從事解釋現象之間關係的一門科學,如此,他批判了傳統法國方法歷史學派的事件史、敘述史的研究取向,也呼應了二十世紀初社會學家對歷史學家的批判,在某種程度上迎合了社會學家強調因果關係之解釋的方法。再者,布洛克肯定了歷史學的科學性質。他雖一再地批判所謂的實證主義的科學概念;但是,另一個方面他又聲稱歷史作為一門科學在知識上所具有的正當性。因此,論者稱布洛克的歷史思維在本質上仍是實證主義的,甚至或稱布洛克跟涂爾幹一樣是一個新實證主義者。筆者則認為,布洛克其實是企圖在其老師塞諾博斯與涂爾幹之間取得調和。42

    +

    最後,布洛克指出歷史學之所以得以存在的原因,還來自於她所獨有的特性。布洛克認為,雖然歷史學是一門具有嚴謹方法訓練的科學,但是,歷史學卻不能因而喪失了她所獨有的某些特性。首先,布洛克認為歷史至少具有某種程度的娛樂價值,因為她會為人們帶來無窮的樂趣。他並且指出,經過有方法、具條理的歷史學的訓練,將使人們更領略歷史所能引發的更為深層的趣味與魅力。43 其次,歷史學具有其獨特的美學上的樂趣與所能引發人類思維中的歷史地想像。因此,他說:「讓我們捍衛我們的科學享有的『詩意』。讓我們意識到以此一詩意特質為恥的傾向。因為,若認為歷史對情緒有強烈的吸引力,而較無法滿足知識份子,這是荒唐透頂的。」44 於茲,當「無窮的可能性取代了嚴格的可度量性」的時代來臨之時,歷史學也將享有更多的可能性。最後,也由於歷史是一項尋求理解的努力,而她又是運動 (in movement) 中的。所以,歷史所具有的不確定性,也是其存在的理由。

    + + +

    歷史學作為一門研究社會的科學

    + +

    那麼,布洛克又如何定義歷史學這門科學呢?

    +

    布洛克沿用希羅多德 (Herodotus, ca. 484-430/420 B.C.) 的意義,認為歷史學是一門致力於「探究」 (inquiry) 的知識。45 但是面對浩瀚無垠的宇宙,歷史所要探究的對象應該是什麼呢?換言之,歷史所要從事探究的實質內容與對象是什麼呢?布洛克所指稱的「歷史學家的確得劃定它的工具所運用的獨特領域」46 所指為何呢?

    +

    對布洛克而言,塞諾博斯與郎格諾所認為的歷史是「研究過去的科學」的說法並不恰當。47 他認為,所謂的歷史,意指「人」的因素之出現。48 例如在說明茲維恩 (Zwin) 海灣淤塞的現象時,布洛克認為不能僅僅從地質學、物理現象的角度來加以說明海灣淤塞,還必須從人類活動、社會的觀點來解釋之。他如此寫道:「海灣的淤塞,無疑地,至少是與提防的建構、水道的改向,以及排水方式有關--而這全都是人的活動,基於集體的需要,且只有在某種社會結構下才有可能的活動。」49 換言之,歷史所要從事探究的對象就是人,而歷史學便是研究「人」的科學。布洛克如此寫到:

    + +
    +

    在很久以前,我們偉大的前輩,如米敘列 (Jules Michelet, 1798-1874) 或古朗士,確實教授我們體認到歷史的對象,在本質上,就是人。我們不如說,是多數的人。遠比利於抽象的單數,複數是相對性的文法形式,更適合研究變遷的科學。在地理面貌、工具、機器、最形式化的文件與在看來幾乎已完全脫離創造者的制度後,就是人本身。而歷史試圖要掌握的,也就是『這些人』。50

    +
    + +

    由此觀之,布洛克認為歷史研究最根本的探究對象就是「人」。更值得注意的是,布洛克進一步指出所謂的「人」意味著是「多數的人」。他說:

    + +
    +

    『我們同時關懷個別的人 (the individual man) --那是哲學,以及社會人 (the social man) 的研究--那是歷史。』這裡無妨再多說些,多年以後,古朗士以更簡潔、完滿的方式論及此,使得上述米敘列的解說看來只不過是他的話一個註腳。他說:『歷史不是發生在過去的各種事件的累積。它是研究人類社會的科學。』但是,這或許削減太多歷史中個人的角色;社會中的人 (man in society) 和社會 (societies) ,並非可完全等同的概念。51

    +
    + +

    在這裡布洛克引用米敘列與古朗士的觀點,進一步說明他所謂的多數的人之意含,指的就是人類社會群體。由此觀之,我們也可以進一步認知到,布洛克認為歷史所要從事探究的對象就是人類社會群體。歷史學便是致力於研究人類社會的科學。但是,由上述這段文字,我們也可看到,布洛克雖同意歷史主要是要致力於人類社會群體的研究,他仍意識到不可過度忽略了歷史發展中「個人」的角色。換言之,一個社會中個體與群體因素是不可分離的。而這樣一個觀點,在其早期即是如此,而在其晚期發展出較為系統的論述。雖然布洛克曾指出,在探究的路途上,歷史的研究對象可以自由地轉向個人或社會。52 但是,布洛克在強調社會群體的因素之餘仍然意識到社會群體中「個人」的角色與作用。不過,觀察他終其一生之著作,確實較著重於群體因素的歷史解釋觀點。例如,在《法蘭西之島》當中,布洛克除了從社會群體形成 (social groupings) 的觀點描繪巴黎地區的社會狀況之外,還特別提醒後世學者必須投注心力,從事城市居民與農民社群的研究。而其博士論文則是一項專力於農奴此一社會群體之研究的成果。53

    +

    其次,上述所引述的文字也說明了歷史研究所竟之功,絕非只是事件的累積而已,如果歷史的探究無法掌握到人類社會群體本身,歷史也將只是一項博聞強記的訓練而已。因此,對於歷史研究的對象,布洛克藉用費弗爾的文字一再強調:「不是人,重申一次,絕不是人。而是人類社會,有組織的團體。」54 至此,我們可說人類社會群體乃是布洛克歷史思想與研究的核心概念。

    + +

    整體歷史:文明

    + +

    布洛克又如何以人類社會群體的核心概念建構其歷史解釋的架構呢?而人類社會群體的活動所指涉的實值內涵又是為何呢?筆者認為,布洛克所謂的「社會」是一個包括了自然地理環境、物質生活條件技術、器具、社會群體關係的形式、人類的心靈狀態等因素所形成的一個由下而上的有機整體。因此,從事歷史研究與歷史解釋的工作時,史家必須從上述這許多方面去理解、分析歷史的人事發展與變遷。爾後,當史家能夠盡全力地認識人類歷史各方面的實況時,他必須進一步將他們加以統合起來。換言之,布洛克在實際進行其歷史寫作時,更重視從整體的角度出發,進而完全掌握人類社會中自然環境、物質生活條件技術、器具、社會群體關係的形式、人類的心靈狀態等各個環節之間的互動關係,並以此分析架構形成其對於歷史整體的理解。誠如布洛克自己所言:

    + +
    +

    1837 年,米敘列向聖貝夫 (Sainte-Beuve) 解釋道:『在我的敘述中如果只有介紹政治史,如果我毫不論及歷史中多樣的因素(宗教、法律、地理、文學、藝術等等),我的敘述方式將會非常不同。但是一個生機性的運動是必須的,因為這些多樣的因素必須聚合在一個統一性的故事當中。』一個世代之後,輪到古朗士對索邦學院的聽眾說:『假設有一百個專家以拼湊的方式分配好撰述法國過去的歷史,你們認為他們最後能寫出法國歷史嗎?』我非常懷疑,至少他們會忽略了事實的連結環,而此一連結環本身就是歷史真實。55

    +
    + +

    布洛克在此藉由米敘列與古朗士的文字表明,史家不僅必須對人類所有的活動建立一個全面、整體的理解,同時更需要把人類各種活動之間的互動連結關係進行分析與解釋,也就是所謂的「連結環本身就是歷史真實」。因此,他進一步地總結說到:

    + +
    +

    那是因為我們已經認知到在任何社會內部,無論其性質如何,每件事情都是互相牽制與關連的-政治與社會結構、經濟體系、宗教信仰、心靈最粗糙與最細緻的表現。我們該如何稱呼這個綜合體?56

    +
    + +

    在此,布洛克明確地指出了其從事歷史解釋的最高原則。

    +

    不但如此,他還進一步以「文明」這個概念來統稱這一個社會的綜合體。然而,十分可惜地,布洛克並未針對文明二字提出清楚的詮釋。他只是約略提及如「毫無疑問的,文明也可能會有所變遷」、「這個社會綜合體的主要重點也會或多或少遭到突然的修改,當這樣的轉變發生時,我們說那是一個文明繼承了另一個」57 類似的字句,這或可以說明文明所代表的意涵,指的就是所謂的社會綜合體。以下,筆者將以費弗爾〈文明:一個字的演變和一群觀念〉 ("Civilization: Evolution of a Word and a Group of Ideas") 一文,進一步說明文明二字意涵。58

    +

    費弗爾在該文中指出,文明一字經過其寫法、用法與觀念地不斷演變與發展,到十八世紀臻於成熟。59 在十八世紀中,文明一字由於受到啟蒙進步觀念的影響,一直具有價值判斷的意涵,它用來指稱一個受到知識教化程度較高的人類社會。但是,除此之外,該字實質上的意義並不清楚。60 費弗爾認為,文明一字的意涵,一直到基佐從事《歐洲文明史》 (The Civilization of Europe) 的寫作時才有了更清楚而豐富的意涵。在基佐的筆下,文明意指了「包含了一個民族所有的資源、一個民族生活中的所有方面的因素、與在生活中所有運作的力量」的社會事實。他進一步說明,文明是人類所創造的產物,其中包括了在人類社會狀況的發展與人類在智識上的發展。換言之,文明的兩大要素就是人類在社會與思想兩方面的發展,而且兩者是一體的。61 由此觀之,布洛克以文明來統稱人類社會的綜合體的論述,與基佐的文明觀有某種程度的親近性。基於此,我們可以說,對布洛克而言,文明意指人類所有活動的全貌。而在實際從事歷史寫作時,布洛克便常常使用這個文明概念。在《封建社會》中,布洛克將作為一種社會類型的封建制度稱為封建文明。62 在《法國農村史》中,他說法國農村是一個包含了各種不同的農業文明的複雜國家。63 例如,在「作物輪耕系統」 (system of crop rotation) 一節的結論時,他說到︰「北方與南方兩種不同的農業系統共同存在於法國的農業機制之中,並同時將其影響力深植於整個文明的根基之中。」而此一結論,乃是「我們從法國農村經濟史中所學習到的最有價值的教訓。」64 甚至,布洛克曾經計畫撰寫一部「在歐洲文明結構之內的法國社會史」。65

    +

    以筆者之見,這樣一個以人類社會為分析架構的歷史解釋模式,在布洛克歷史研究生涯的早期著作如《法蘭西之島》與博士論文〈國王與農奴〉中即已略具雛形,並在其晚期的《封建社會》、《法國農村史》與《史家的技藝》等著作中則更為明顯而成熟。

    +

    在《封建社會》一書當中,布洛克明白地指出其著作的目的,就是要致力於解釋一種社會結構及其得以統一的原理。66 並且,他非常強調:「唯有藉由對整體的人類環境的認識,最後才能理解統制一個社會的制度架構。」67 這樣的歷史理解的原則,由該書的章節安排就可見一斑。在卷一他探討所謂「依附紐帶的成長」 (The Growth of Ties of Dependence) 的論述過程裡,他便漸次地從地理環境、人類物質生活、精神氛圍、社會關係之狀態的探討,說明整個封建社會形成的歷程。而在從事有關中世紀人的時間觀之描繪時,他便是從自然環境、物質條件、社會結構與精神狀態之間整體關係的分析來建構他的詮釋。68

    +

    此外,布洛克也注意到社會實體或社會群體組織中的「人口」因素。在《封建社會》中,布洛克以人口數的升降趨勢與分布的狀態,作為其區分兩個封建時期之分析的基點。他認為,人口因素對於人類生活的物條件、社會習慣、人際關係、經濟活動、社會價值觀的影響是毫無疑問的。因此,發生在 1050 到 1250 年間的人口再定居運動,乃成為封建制度第二個時期的特色。因為,布洛克認為:「當人類關係的網絡相互收緊,商品和貨幣的流通速度加快,在非常鬆散的社會中誕生的歐洲封建社會就發生了根本性的變化。」69 同樣的,在《法國農村史》中,布洛克探討田地的類型、輪耕制度的種類與莊園制度的發展時,他也注意到了「人口」因素在人類歷史的發展與社會的演變中所扮演的重要角色。70

    +

    在《法國農村史》一書中,布洛克不同於前人由法律、制度層面研究莊園制度,他結合了對農村習俗傳統、技術的變革、土地分布形態、農民社群的類型與農民心態的理解,來探究莊園制度的變遷與發展,並建構他對法國農業文明的詮釋。而這就是《法國農村史》在歷史解釋上所表現出來的特色。例如,布洛克在書中指出,每一個農業系統不僅僅只是以其耕作制度為其特徵,而是一個技術與社會關係 (social relations) 交錯而成的綜合體。71 因此,就大體而言,不管耕地區劃的單位是多少,其耕作活動呈現出完全的一致性,即農民會完全地按照社群或傳統習俗所規定的日期來進行各種例行性的農事;同樣地,只要是經由社群所決定的改變也是被允許的。72 另外,雖然若干少數獨特的區域也有可能發生脫離常規的農業習俗。不過,布洛克認為這些區域之所以會如此「脫軌」 (out of course) 是因為其居民所具有的資產階級 (bourgeois) 性質,即他們經常不照一般行為法則而更具個人色彩,因此其從事農業活動也是不同於普遍化的多數整體。73 在此,我們可以發現,布洛克對於社會群體因素的重視,他認為在農業活動與農村社群的性質有密切的關係。因此,布洛克如此說道:「唯有一個由凡事以社群來思考的人所組成的緊密社會,才能形成如此一種農業系統。而土地本身乃是集體勞動的產品。」74 所以,農村社群的強制力量所形成的農業習俗,也直接反映在土地耕作的型式之上,他說:

    + +
    +

    不管是富人或窮人,都受整個團體的習俗所束縛,如此一來也在不同社會階級與不同的耕作方式之間保持某種程度的平衡。這一種『初步的共產主義 (rudimentary communism) 』--這一個詞是從饒勒斯 (Jaures) 的《革命史》 (Histoire de la Revolution) 一書中借來的--乃是此種農業文明的標誌及其存在的理由。75

    +
    + +

    由此觀之,布洛克對於社群概念之重視,強調從社會的角度來探究人類社群組織與農業習作之間的強制關係。同時,也反映出人類物質生活與社會群體之間的互動關係。基於此,布洛克進一步指出,法國農村社會整體結構的變遷,將導致莊園制度發生根本性的變化。76

    +

    不僅如此,布洛克以社會組織的觀點解釋歷史的特色,還表現在他對習俗的強調。對布洛克而言,他認人類初期社會的特點顯現在習俗對社群生活的強制性上,而法律條文往往只是習俗的條文化而已。因此,布洛克認為,在中古法國農業生活之中,習俗對人類活動的強制性是無遠弗屆的,甚至更甚於法律條文。他說︰「這樣的變化,並非法律變遷的結果,因為法律改變不了任何事。而真正的原因,乃是社會秩序 (social order) 的變遷。」77 這樣的觀點,反映出布洛克受到涂爾幹社會學的影響;在這裡,筆者所說的影響指的是涂爾幹的「社會分工論」。

    +

    在布洛克眼中,經濟活動、社會群體與生活方式之間實具有密切之關係,誠如他所說的,「所有的經濟現象,只有在其所處的社會背景之下才得以理解之。」78 例如,在《法國農村史》中有關稅收方式一節的論述當中,布洛克指出,租佃制 (metayage) 此種稅收方式主要分布於貧困或較少開發的地區,其主要成員都是小資產階級;其因乃由於這些小資產階級較能接受這種稅收方式,更重要的是,這種稅收方式適合小資產階級的生活方式。由此可見稅收制度、階級與生活方式之間的關係;所以,布洛克指出,兩種稅收方式正反映了兩種社會類型 (social types) 。79

    +

    布洛克在《法國農村史》有關「社會團體」一章的論述當中,強調歷史的發展與變遷中之社會的互動關係。80 布洛克在此,說明法國農村中的社群組織 (manse) 的重要性及其變遷,同時進一步論證了人類社群組織形態、社群活動與農業耕作形態之間的關係。他認為,人類生活各方面所呈現出來的性質與其社會組織的形態有極其密切的關係。例如,他指出農村集體工作習俗的消失,對耕地的構造、型態都產生了深刻的影響;換言之,農村生活與物質狀況的變遷,乃是人類社會變遷的反映。81 由此,讀者可以獲致布洛克歷史思想重要的觀點,他強調社會生活中的社群結構、生活習慣、心靈態度、物質條件等各方面之間關係的掌握與整體的理解。

    + +

    人類的意識就是歷史研究的題材

    + +

    然而,針對布洛克等其他年鑑史家強調社會整體結構的歷史解釋的特色,馬克思主義史家以為這將導致史家把「人」與「人之意識」的因素,排除在歷史發展之外,甚至認為會陷入決定論 (determinist) 的危險。這樣的批評導源於馬克思主義史家所強調的「人是社會的動物」、「人創造歷史」的概念。然而,這樣的批評是否適當?年鑑史家的歷史解釋果然將「人」的因素給遺忘了嗎?對於此,伊格斯 (Georg G. Iggers) 似乎有較為持平的見解。伊格斯認為,年鑑學派以社會的概念進行歷史研究,將比其他具有社會科學取向的史家或者馬克思主義史家的歷史解釋,還要更具洞識與開放性。82 事實上,布洛克「歷史就是研究人之社會在時間之流之變遷的科學」與「社會是個人心靈的產物」的觀點,似乎與馬克思主義史家有些異曲同工之妙呢!83

    +

    我認為,布洛克並不像批評者所說得那樣,只注意到人類生活的物質因素與物質的狀況;對於人類精神層面的生活與意識的因素,他也非常地重視。布洛克認為,「歸根究底,人類的意識是歷史研究的主題;就歷史研究而言,人類意識之間的交互關係、糾纏與感染,就是真實本身。」84 換言之,對於人類社會的研究,史家必須奮力地挖掘出隱藏於社會生活的背後人類精神的面貌與狀態。布洛克以黑死病造成歐洲人口驟減的現象為例,指出這一個現象是在某些心靈條件的社會下才可能發生。並且說,它在道德方面的影響,也只能以集體意識來加以解釋。85 此外,布洛克進一步指出,社會是個人心靈的產物。例如在分析宗教改革時代紡織工人團體何以成為基督教異端產生的溫床時,布洛克即認為紡織工人此一社群團體獨特的經濟生活與宗教生活兩種生活融合為一,塑造了一個社會特有的心態。86 因此,我們可以更直接了當地說,歷史的事實是心理的事實 (historical facts are psychological facts) 。

    +

    由此可知,雖然布洛克強調由社會結構的觀點從事歷史的研究,他仍然非常重視人類本身的意識、精神因素與力量,並非論者所稱的決定論者。而且,即使布洛克對於人類生活物質條件、狀況十分的重視,但在歷史解釋上,最後總會歸諸人類心理的因素。因此,他絕非是純粹的唯物主義者 (materialist) 。例如,在一篇有關中世紀農民心態與技術革新的論文當中,布洛克除了嘗試從自然環境、土地耕作與技術形式、社會結構之相互關係的觀點提出他的解釋之外,甚至指出有關技術革新的社會現象,其最根本的因素乃是農民的集體心態所致。87 另外,有關農奴制度的論述當中,布洛克同樣指出了人類心態因素的作用。他認為,農奴解放政策並非完全出於政治或社會的因素,解放政策之所以得以形成,實乃「末世審判」的宗教心態使然。同樣的觀點也曾經出現在〈國王與農奴〉當中。88 再者,值得注意的是,在論述莊園制度之瓦解過程的一節當中,布洛克指出資產階級的發展乃法國社會史與農村史最具關鍵性的一件事,因為「他們已經養成了一種資本主義者的心態 (capitalist mentality) ,如此一來也改變了莊園開發土地的方法。」89

    +

    同樣的,在有關法國農業活動、技術與器具的論述當中,布洛克認為法國農村中農業活動的設計與實行,與一種被視為理所當然的「普遍概念」 (general idea) 具有相當密切之關係。如公有地放牧的農民義務乃源自於一種「心靈態度」 (attitude of mind) 。甚且,布洛克還不厭其煩地舉證這些「集體觀念」 (collective idea) 的影響力。90 同樣地,農業習作的習慣之所以產生變化,其原因除了社會結構的改變、農業技術的革新等因素之外,最重要的原因,還在於知識的流通所導致的農民心態的改變。91 因此,在談及不規則敞田與耕作器具的關係時,布洛克認為僅僅依靠物質性的因素,無法有效解釋吾人所觀察到的現象。他問道︰「這些純粹物質的因素足以解釋之嗎?」92 然後,布洛克進一步回答:

    + +
    +

    當然,要展現出在技術發明背後的因果鎖鏈是非常吸引人的。雙輪犁導致了長形田,而長形田又產生了對於集體習慣一個強而有力的刺激,然後安裝導輪的耕犁成為整個社會結構的基礎。但是,我們必須謹慎,這樣的推論,將會忽略了人類行為的多樣與精巧。當然,雙輪犁迫使耕地延長了,但耕田狹窄的因素卻不是如此。……原因是,將所有的土地分散,被認為是可以形成均等的機會,農民們被允許耕種不同種類的土地,可以不至於在自然災害或社會災難中被摧毀,如冰暴、病蟲害、劫掠等,災難總不至於同時摧毀整個地區。這種農民心態 (peasant mentality) 根深蒂固,至今還抵制土地調整的明智之舉。在土地分配上,無論是長形耕地或者是不規則耕地,都受這種思想的影響。93

    +
    + +

    由此觀之,布洛克並不認為是單純的器具因素造成了某種的集體行為,真正的因素是一種長久以來的「農民心態」影響所致。誠如布洛克所言︰「對具有反省能力的人來說,物質的世界只不過是一個面具,而一切真正重要的事情,是在它背後所發生的。」94 這裡所指背後所發生的事物,指的就是人類意識。由此,我們可以說,布洛克在從事說明農業土地形態與技術形態的關係時,並未僅僅重視物質因素,相反地,他把現象的原因歸諸於人類的意識因素。

    +

    關於布洛克對於人類心靈狀態的強調,筆者認為絕對不可以漏掉《國王神蹟》這本著作。布洛克在《國王神蹟》一書中所定下的研究取向,被視為心態歷史研究的先驅之作。在該書中,他對心態歷史研究的觀念及所設定的綱領與方法,對後來的年鑑史家產生了極大的影響。95 不但如此,津茲伯 (Carlo Ginzburg) 也自承,從思想系譜的觀點言,其《起司與小蟲子們》 (The Cheese and the Worms) 之著作深受布洛克的《國王神蹟》所影響。96 前已述及,《國王神蹟》在探討中古十世紀到十八世紀期間,流行於法、英中人們普遍相信經由國王的「御觸」可治癒因「國王的邪惡」所引起的皮膚病的一種普遍心態,並說明此種心態的發生、發展與衰落的過程。人們何以如此呢?布洛克在導論中明確的告訴讀者,一般人民所具有「國王具醫治疾病的神奇力量」的概念,反映了人民對國王與王室之「神聖性」的信仰︰而這一種信仰,反映了自古以來人們對「王權」神秘力量之迷信的一種「集體意識」 (collective consciousness) 、一種意識的趨向 (tendencies) 。97 因此,布洛克認為深植於人民心靈中「王權」神聖性的印象,乃構成「御觸」此一現象的主要因素;也就是說,人們關於國王神聖、奇蹟般特質的概念、儀式、崇拜的行為與態度本身,乃是此一時期心理狀態之寫照。98

    +

    同樣強調人類意識因素的歷史解釋觀點,也隨處出現在《封建社會》一書當中。基本上,布洛克認為,從事社會結構之歷史變遷的研究,其起點就是要分析其精神氛圍。因為,「社會就像思想一般,是由重複不斷的相互作用所交織而成的。」99 例如,布洛克指出,在封建時代的藝術、建築的背後,所隱藏的便是當時人們的宗教情感、價值觀;人口再定居運動所引發的經濟發展,除了影響了人際關係的結構之外,也促成了整個社會價值觀的改變。100 又,在有關日耳曼人與斯堪地那維亞人 (Scandinavian) 之入侵的探討中,布洛克注意到入侵對於人們的影響,不只限於物質層面的損害,也對人類的心理狀態產生了極深刻的影響與損害;人們心裡始終處於恐懼、服從的狀態,基於生存的理由,導致了人口聚居的狀況,並進而造成歐洲社會關係與社會組織的變化。相反地,蠻族入侵也為自己帶來了精神層面的改變,由於信仰基督教的結果,某種程度上促使蠻族自身生活方式的改變;此乃由於促成蠻族長期劫掠與長途遷徙的冒險習俗與心態,在進入西歐之後已經逐漸地瓦解所致。101 最後,最明顯的例子,莫過於布洛克在有關中世紀社會「感情與思想的狀態」 (modes of feeling and thought) 一節中有關人類對自然與時間的態度和宗教心態的論述,特別表現出他對於人類精神層面的興趣。102

    +

    以上,筆者從布洛克歷史思想與實際研究的層面,指出布洛克以社會整體為觀察視野的歷史解釋,並未如論者所稱的忽略了人類本身及其意識的因素,也不會因此而流於決定論之弊端。實際上,一般批評者對布洛克等年鑑史家所抨擊的決定論傾向,其因不僅在於上述的理由,還包括了他們認為年鑑史家表現出對於地理因素的過度重視。

    +

    但是,布洛克雖然表現出對於地理因素的注意,但並未過分地強調。筆者認為,對於地理因素的強調,實際上早已長期存在於法國以往的思想與著作之中。從十六世紀讓波丹 (Jean Bodin, 1530-1596) 的《簡易理解歷史的方法》 (Method for the Easy Comprehension of History) 、十八世紀的孟德斯鳩 (Montesquieu, 1689-1755) 的《法意》 (The Spirit of the Laws) 到十九世紀米敘列的歷史思想,都一再地顯示他們對於地理環境因素的考量。103 其次,就法國當代歷史學而言,對於地理因素的強調也有其學術機制的因素。在本文第一章當中,筆者已述及法國高等教育體制中,歷史與地理學被列為學位考試的同一個科目。同時,法國在十九世紀末到二十世紀初以維達布拉什 (Paul Vidal de la Blache, 1843-1918) 為首的人文地理學的發展也非常興盛。因此,法國高等教育改革後學院體制中的歷史學,或多或少對於地理學的知識都有所接觸,自然對其歷史研究也有相當的影響。

    +

    因此,後來像布洛克、費弗爾或布勞岱爾等年鑑歷史學家,其思想當中也多少呈現出對於人類歷史發展中地理因素的考量。觀察年鑑史家的歷史著作,我們可以發現,其寫作與論述架構通常是以地理環境的介紹為著作的起點。其中,費弗爾與布勞岱爾由於受到維達布拉什人文地理學觀念的影響,對於地理因素重視的程度尤其強烈。就布洛克而言,其一生主要的歷史著作如《法蘭西之島》、《法國農村史》與《封建社會》等,都呈現出對地理因素的注意以及若干人文地理學觀念的運用。然而,不似費弗爾與布勞岱爾那般強烈的地理決定論傾向,布洛克在某種程度上對於維達布拉什的人文地理學的觀點抱持著保留的態度,甚至抱持了反對地理決定論的觀點。在《法蘭西之島》一書當中,布洛克對於地理因素採取了保留的態度。例如,在論及巴黎地區行政區域之發展時,雖然在地理環境上多所著墨,但是,他認為行政區範圍、界限的形成,其決定因素並不在於地理的因素,而在於人所參與的歷史本身的變遷所致。104 除此之外,布洛克甚至對人文地理學式的區域史研究加以批判,提出他所認為理想的區域史研究的方法論。105 在《法國農村史》一書中,布洛克在分析輪耕制度的分布狀況與人口多寡之間的密切關係時,認為大體上來說兩種明顯對比的輪耕制度所形成的兩種農業文明 (agrarian civilisation) ,其成因是多方面的,包括歷史的、民族的和地理的原因等,而不能僅從地理因素加以解釋。106

    +

    綜上所述,我們可以了解到布洛克對於歷史一詞的詮釋。歷史作為一門研究社會的科學,歷史家必須從社會整體的角度去掌握與理解他所研究的對象,進而從事史家的解釋與分析。

    + +

    科際整合與史料觀念之革新

    + +

    筆者認為,以掌握社會整體歷史的理解為職志的歷史思維,乃是布洛克歷史思想的核心。而這樣的歷史思維,不但開拓了歷史的視野,豐富了歷史家的意義,也開啟了法國史學的新頁。

    +

    首先,基於這樣的歷史思維,歷史所探究的是人類社會群體的活動,若僅僅注意到個人,將無法掌握歷史發展的深層而多元的因素。同樣地,若只是關注政治、軍事的事件,而無法從社會群體的整體角度去探究歷史,也將流於膚淺。如此,突破了傳統方法學派過度專注於歷史發展中的個人、事件因素的研究取向。其次,這樣的歷史思維,不但開啟了法國歷史學的新頁,後來也成為年鑑史家的特色之一。他們主張以人類所有活動的歷史,取代傳統方法歷史學派以政治為主幹的歷史。傳統的史家只注意到過去歷史發展的表面,而未觸及歷史事實 (historical reality) 中深層的整體社會結構。換言之,年鑑史家強調以系列的、功能的與結構的路徑來理解社會,因為社會是一個具整體性的有機體。同時,他們也致力於探究一個社會體系如何運作,並以時空、人類、社會、經濟、文化和環境等多層次的角度去理解一個社會群體的功能。107 基於此,他們認為唯有從事經濟、社會、文化、地理與心理等各層次結構的「現象」與「實體」之研究,並關注整個社會整體中各層次結構的互動關係,才可達到對歷史整體的理解。於茲,年鑑史家喊出了所謂「整體歷史」 (total history) 的口號。

    +

    對布洛克或年鑑史家而言,「整體歷史」的概念或許是一個遙不可及的理想。但是,也因為懷抱著這樣的理念,歷史探究的視野也因此而擴大了。在現實的發展上,年鑑創立初期即以「整體歷史」為訴求確定了社會史與經濟史的研究方向。以本文的主人翁布洛克而言,他在《法蘭西之島》、《法國農村史》、《封建社會》與等著作當中,都呈現了強調自然環境、社會結構與精神狀態之間關係的歷史解釋觀點,具體實踐了所謂的「整體歷史」的歷史解釋。而布洛克這種強調人類生活中各層次結構的歷史解釋,更被英國馬克思主義史家霍布斯邦 (Eric Hobsbawm) 讚譽為「社會整體歷史」的最佳典範。其他,如布勞岱爾則在其《地中海及菲力普二世時期的地中海世界》( The Mediterranean and the Mediterranean World in the Age of Philip II, 以下簡稱《地中海》)一書當中,也實踐了此一追尋與建構「整體歷史」的理想。108 再者, 1950 、 1960 年代以後的年鑑史家,則發展出以社會整體為基礎的區域史研究,他們皆企圖描繪一個地區的「整體歷史」,例如拉度里 (Emmanuel Le Roy Ladurie) 的《郎格多瓦的農民》 (The Peasants of Languedoc) 即是一例。109

    +

    其次,隨著歷史認識的視野與研究領域的擴大,為了達成對於人類所有活動的理解,史家便必須採取科際整合的研究取向,並且擴大史料運用的範圍與種類。首先,布洛克從知識之整體性的角度,說明科際整合的必要性。因為,他認為:「每一門科學,就其本身而言,代表的不過是追求知識的普遍性努力中的片斷,我已在前面舉過例子,想瞭解某一學科的研究方法,必須做的是,去看看他們與同時存在於其他領域內所有趨勢之間的關連。」110 因為,各種學科都能在史家探究人類活動的萬般現象時提供知識與概念上的助益。史家們一方面企圖從其他社會學科借用或引進新觀念、方法,以應付愈趨擴大的歷史研究領域;另一方面,新觀念也可用作史家從事歷史解釋與分析的概念工具,以方便其能更有系統地進行論證。如此,才能真正達成對歷史整體的理解。所以,布洛克如此說道:「因為唯一真實的歷史,是人類全體的歷史,只有經由互助才能進步。」111

    +

    就布洛克而言,在與費弗爾共創《年鑑》時,其所揭櫫的主張便是鼓勵科際整合的歷史研究。在其從事歷史研究時,也經常運用社會學、人文地理學、語言學等其他人文學科之概念與方法。同樣地,除了布洛克之外,在此一對「整體歷史」的追尋的理想之下,隨著歷史研究之擴充的需求,年鑑史家在從事歷史寫作時,也表現出積極與其他人文學科進行知識交流的態度。112

    +

    相同地道理,面對歷史研究領域之擴大,史家對史料蒐集與運用,也必隨之更具多樣性。這引發了布洛克對傳統史學史料運用觀念上的批判與革新。在傳統史學方面,郎格諾與塞諾博斯的方法歷史學派方法論,主張與強調檔案文獻等有意識的文字史料乃是從事歷史研究的唯一依據。113 相對地,布洛克則認為所有可以讓史家觀察到人類活動與精神之痕跡的事物,都可以作為史料。因此,非文字如考古文物與無意識的史料,也可以作為史家從事歷史研究時的證據。正如他在《史家的技藝》一書所說的:「歷史資料的多樣性近乎無窮,人所說的、所寫的、所做的、所接觸的任何事物,都能教導我們有關他的事。許多人由於不熟悉我們的工作,以致低估了歷史資料真正可能包含的範圍。」114 基於此,布洛克在其歷史研究中,所使用的史料種類便極為廣泛。其中,比較特殊的例子如,在《封建社會》中,布洛克便企圖運用《羅蘭之歌》 (Chanson de Roland) 、《紀堯姆之歌》 (Chanson de Guillaume) 等史詩,來勾畫一般庶民的歷史記憶與精神狀態。他認為,雖然這些史詩在某種程度上是虛構的,但卻能透露出當時的歷史情境與一般俗民的心靈態度與集體記憶。115 在《法國農村史》中,布洛克則使用了空照地圖,用來描繪法國農業土地利用的形態與分布狀況。116 總之,布洛克運用史料證據的觀念非常靈活,也非常具有新意。除上所述的例子,他曾經運用的史料證據還包括了詩歌、遺囑、祈禱文、考古遺址、墓碑、傳奇文學、請願書、教會檔案、印章、繪畫、浮雕、考古遺址、契據登記簿、地圖、文學作品、備忘錄、統計數據、醫學、神學與政治學理論的著作、錢幣等。117

    +

    另外,由於解釋多樣性史料之需要,史家也因此必須借助其他學門的知識。由於使用的史料種類、性質範圍的擴大,使得史家必須借用其他學科如考古學、地質學、語言學、建築學、心理學的技術與知識來解釋史料。誠如布洛克所言,「如果幾乎所有重要的人類問題需要我們處理各種資料,而另一方面,資料的種類又必然橫跨幾個不同的專業技術。那麼,每一部門的學徒階段是漫長的,而完全的熟練則需要更長且無間斷的練習。」118 因此,由於史料範圍之擴大,促使史家也必需邁向了科際整合的道路上去。

    + +

    第二節 多層次的歷史時間觀:長時段

    + +

    布洛克歷史思想的革新意義,不僅表現在其對於社會整體歷史的詮釋。他在歷史的時間觀念上的見解,也跳脫了傳統僵化的線性時間觀或編年式的歷史時間概念。布洛克在時間觀念上的新意,主要在於他對於歷史的過去與現在之關係的詮釋,以及他所揭示之多層次的歷史時間觀與長時段的概念。因此,在本節當中,筆者首先將介紹布洛克對傳統的歷史時間觀的批判,其次,進一步探討他對於歷史的過去與現在的詮釋;最後,說明布洛克多層次的歷史時間觀與長時段的概念。

    + +

    歷史學是在時間中的人的科學

    + +

    時間與對時間的觀念,是人的歷史意識之中和人在理解歷史之時不可缺少的因素。布洛克認為,不僅僅是歷史學研究者,就算是一般人也必須將其對於人事發展的觀察,放置在時間的脈絡中來理解。誠如他所指出的,歷史的時間是具體而有生命的實體,是沈浸事件的血漿,也是使事件變得可以理解的場所。換言之,「時間」乃是歷史家從事歷史研究時必須考慮的因素。所以,布洛克認為,若只是將歷史稱為「人的科學」仍然是含糊不清,必須說歷史是「在時間中的人的科學」。119 因此,在人的科學的命題中,進一步加入「時間」的因子,如此歷史的理解才得以完滿。誠如布洛克精妙的比喻:

    + +
    +

    只有當史家在可謂為歷史的主角的「人」與可謂為歷史的氣候的「文明」二者的生命航圖上描繪出精確的「時刻」時,才會感到他已給予一幅真確的圖像。120

    +
    + +

    那麼,我們要問,布洛克的歷史時間概念為何呢?他又如何提出他對傳統歷史學時間觀念的批判呢?

    +

    首先,布洛克基於社會之整體的歷史研究的概念,對於傳統歷史學的歷史時間觀提出了批判。布洛克認為過去長久以來的歷史研究,都過度地沈溺於「起源」的研究。基本上,他認為過去汲汲於探索「起源」的研究態度,對於歷史研究本身並沒有實質的幫助。首先,起源取向的歷史已經成了為價值判斷服務的工具,人們用過去來解釋當代,也只是為了想為當代辯護或加以非難。因此,布洛克認為「起源」已經變成熱衷下判斷的魔鬼化身,並且成了真實的歷史的惡敵。121 這裡,布洛克所批判的,便是其父執輩在十九世紀末到二十世紀初所犯的錯誤。其次,布洛克認為,「起源」就其字義而言,不論是作為說明原因、或作為說明功能的開端,都無法幫助歷史家真正瞭解與解釋歷史發展中的萬般現象。在以天主教作為例子的論證當中,他說:「知道其開端,對瞭解實際的宗教現象是不可或缺的,但卻不足以解釋該現象。」因此,「問題不再是耶穌是否先釘死在十字架再復活,而是它是如何被傳下來的,以致於今天有如此多的同胞相信十字架殉難及復活。」所以,布洛克認為:

    + +
    +

    實際上,不管我們從何處發現對信仰的忠誠。所有的證據都指出,它只不過是群體一般生活的一個面向罷了。就像一團線球,由社會結構與心態的種種不同特性交織而成。簡言之,宗教之教義涉及整個人類環境的問題。高大的橡樹,是從小小的櫟子長成的。但是,只有遇上適宜的土壤及氣候條件,才有此結果,而這些條件是完全超乎胚胎學的範圍。122

    +
    + +

    換言之,歷史研究真正所要達成的,並不僅僅是對萬般現象之起源或原因的瞭解,更重要的是從社會整體的角度,去理解歷史中各種現象演變的「土壤與氣候條件」。例如布洛克在《國王神蹟》一書當中,一再地提醒讀者,國王神蹟的起源並不是最重要的,最重要的是要理解國王神蹟何以在中世紀的人類社會中發展為一個群體信仰。此外,布洛克也認為,任何尋求人類活動之起源的研究,都潛藏著把世系與解釋混為一談的危險。以封建制度的起源為例,布洛克認為不論是羅馬的起源、或是日耳曼的起源,歐洲封建制度的特殊建制並不僅僅是殘留物的拼湊。在我們歷史的某個階段,這些特殊建制源自於整個「社會情境」 (social conditions) 。123 因此,就人類活動的現象而言,歷史家最主要的問題就是要去理解它的社會條件與情境。在此,布洛克以社會整體的概念為基礎,呈現出他對傳統歷史學的起源偏執提出了批判。

    +

    其次,布洛克提出了對傳統歷史學的歷史分期概念之批判。布洛克認為傳統歷史學所運用的編年學式的歷史分期觀念如朝代、世紀,往往過於僵化、牽強。124 相對地,布洛克認為應依主題的性質來建構歷史分期的架構。例如,在說明《封建社會》一書的鋪陳方式時,布洛克即指出,一切來源於君主制如帝國、王朝、朝代等從事歷史分析的方式應該加以捨棄,而改以一種以觀察社會現象為基礎的分類體系。125 因此,在分析歐洲封建文明時,布洛克反對依照編年順序的方式從事分析,而主張依社會性質的不同,將整個封建文明區分成兩個不同的時期。126

    + +

    歷史的過去與現在:倒溯研究法 (retrogressive method)

    + +

    其次,由於過去與現在的區別,不但是組成時間概念的主要部份,同時也是歷史意識與歷史知識的基礎。127 基於這樣的概念,布洛克也提出了他對於歷史的過去與現在的思考,同時也指出了歷史家在從事歷史理解時的兩個重要歷程,也就是「由過去理解現在」與「由現在理解過去」的提議。布洛克認為,對「過去」的無知,不但蒙蔽了對「現在」的認識,而且也誤導了現在應採取的行動,換言之,「忽略過去,不可避免的會導致對現在的誤解。」因此,歷史家「由過去理解現在」似乎是理所當然的。相反地,一個人在企圖了解過去時,如果他對現在一無所知者,那麼也可能弄的筋疲力盡而毫無收穫;所以,歷史家必須「由現在理解過去」。128 歷史家或者一般人由過去理解現在,似乎是毋庸置疑的道理。但是,由現在理解過去的道理為何呢?又,史家如何由現在理解過去呢?

    +

    布洛克進一步提出他的說明。他認為,對現在的通曉對於了解過去更有直接的關係。他說:

    + +
    +

    認為歷史學者所採取的研究順序一定得與事件發生順序相符,這的確是個嚴重的錯誤。儘管在最後,他們還得恢復歷史的真正時間順序,但如果在一開始時,他們能如麥特蘭 (Frederic William Maitland, 1850-1906) 所說的「倒讀歷史」 (reading history backwards) ,那麼,他們經常會有不少獲益。因為,所有的研究,其自然的進展,是由最了解的到最含混不清的。129

    +
    + +

    換言之,布洛克認為,對於歷史的觀察與理解,不一定要按照時序由過去推展至現在,也可以從對較為清晰的現在之狀況推向過去。如果歷史的研究只是機械地從前代推向後期,這其中永遠埋伏著一個危險。這個危險就是我們會浪費不少時間去追溯某些現象的起源或原因,而這些起源或原因到最後可能由事實證明只是想像出來的。因此,為了解決由於資料稀少所造成的對於歷史現象之詮釋的困難,並且為了提出正確的問題,布洛克說首要條件是必須觀察並分析我們現在的景觀。布洛克以一個巧妙的比喻,說明這樣的方法:

    + +
    +

    毫無疑問的,在我們朝向過去的源頭溯游而上的旅程中,我們的確可以把這幅永遠靜止的圖片,往前推源於每個階段。在此,就像在其他地方,歷史學者尋求瞭解變化。但是,在他檢驗的影片 (film) 當中,只有最後的圖像仍然是相當清楚的,為了重建其他圖像模糊的面貌,他首先得將底片的捲軸以圖像拍攝時的相反方向放起。130

    +
    + +

    這樣一個「倒讀歷史」、或者我們稱之為「倒溯研究法」的概念,也可見諸布洛克於《法國農村史》一書之方法論的說明當中。在說明該書所運用的方法時,布洛克說:

    + +
    +

    然而,有許多時刻,當我必須使用離我時代較近的證據來理解遙遠的過去,尤其是在從事農業系統的研究時。涂爾幹曾經在一門有關家庭的課程上說︰『若要理解過去,必須首先離開他。』這句話是真實的。但是,有時候也會發生如下的情形,即一個人若要理解過去,一個人必須首先注視著現在或最近的時刻。基於若干原因,我們要使用的方法是以現在的證據來從事農業研究。131

    +
    + +

    布洛克口中所說得原因,指的就是從事法國農村史研究所面臨的在史料上的缺乏。他發現法國農業的歷史一直到十八世紀之後才比較明朗化、比較清楚,而在十八世紀之前用來作為研究的資料是很稀少。因而,為了瞭解法國農業土地形態的多樣性,他必須轉向第一帝國與七月王朝時期所作的調查。132 換言之,倒溯研究法實際上是為了克服研究主題在資料上之闕如而生的。誠如布洛克所言的:「歷史學家永遠要被文件資料所擺佈,尤其是農業史家,假若他們希望破解過去的暗碼,他們大多必須倒讀歷史。」133 最後,布洛克也是以一個有趣的比喻來說明這個方法的意義。他說:「最近的過去所能提供給我們的,就像是我們必須去抽取出影片捲軸中的最後一張底片。」134

    +

    然而,我們要問,從對現在的觀察,就能理解遙遠的過去嗎?歷史難道不是持續變化的嗎?布洛克自己不是也曾說過歷史是變遷的科學嗎?135 其實,雖布洛克也意識到了這個問題,他曾經指出歷史研究的重大難題,正來自於歷史在本質上是個連續體 (continuum) ,同時也是持續的變化。136 那麼,布洛克如何克服這樣的兩難呢?筆者認為,布洛克至少在《法國農村史》嘗試提出他的思考。

    +

    布洛克所提出的倒溯研究法,除了具有在歷史研究方法上的意義之外,似乎還隱藏了意圖展示現在與過去間連續關係之觀點。事實上,布洛克認為,他在《法國農村史》所處理的主題,也就是法國的農村習俗、技術與活動,在本質上都是屬於緩慢變化的活動,即使有變化,也是極細微的。首先,在導論部份他指出:假若農業的習俗在幾個世紀當中都是處於靜態的,那是因為它的變化是極細微的,或者小幅的進步總是在沒有動亂的地方發生的。137 然後,布洛克在法國農業文明之變遷的研究之後,進一步指出,至少有一件事情是可以確定的,節奏的變化儘管在各地有極大的差異,但沒有一個地區是迅速的。138 因此,由於農民社會與農業文明在歷史的時間上所獨具的緩慢發展與變化的特性,布洛克發現中世紀的農業習俗與耕地形態,一直延續到現代法國的農業生活之中。因此,他說:「所以,過去持續支配著現在。今天法國農村的面貌中,幾乎沒有一個特點不能從對過去時代演變的研究中獲得解釋。」139

    +

    我們發現,在《法國農村史》一書當中,隨處可見布洛克關於歷史的現在與過去間之連續關係的觀點,這不但是他在該書從事論述時歷史解釋的特色,也隱含了多層次的歷史時間觀與長時段的概念。140

    + +

    多層次的歷史時間觀:長時段 (longue duree)

    + +

    布洛克時間概念的最大特色在於,他認為不應該以僵化的鐘錶時間作為歷史研究的度量標準,歷史所探究的是人的現象,因此應該依照現象本身所具有的性質作為史家在時間度量上的標準。據此,人類活動中各種現象,基於各種因素,便引發出各種不同層次的時間概念。

    +

    首先,布洛克指出,「簡言之,我們傾向於把一個隨意選取的、刻板有如鐘擺的韻律強加到歷史事實上,而歷史事實與這種規則的韻律是完全不相干的。」141 在此,布洛克企圖藉此批判傳統歷史時間概念的謬誤。那麼,該如何突破這樣的謬誤呢?針對此,他主張歷史家「應當依據現象本身來尋求符合他們的時間」,同時進一步說明歷史時間的多樣性。142 他說:

    + +
    +

    最準確的測量是與該事件之性質配合的最好的。現在,每種形態的現象都有他自己獨特的測量尺度,或者說,有他自己的獨特進位法。社會結構、經濟體系、宗教或心靈態度的變化,不可能依照過度精確的年代學 (chronology) 而不會遭到曲解。143

    +
    + +

    那麼,歷史作為研究人類社會之整體之科學,又應該如何顯示其不同階段的特性呢?布洛克說,問題在於找到社會發展的主調。所以,他提出若干適合用來詮釋社會發展的時間單位。首先,布洛克提議以「世代」 (generation) 作為尺度。因為,同時生長在同樣環境中的人,必然受到類似的影響而具有相似性,因而在每個「世代」之間必然呈現出在行為特性上的差異性。針對此,他說:「在同一個社會的同一個世代裡,習俗與技術通常普遍存在著相似性,而此一相似性之強烈程度,使得沒有人能輕易地脫離一般的習慣。」144 但是,布洛克意識到由於社會中實際上存在著不同的社會階級或社會群體。所以,即使同屬於一個社會的「世代」,其韻律不一定是相同的。換言之,即使同屬於一個「世代」的人,也會因為分屬不同的社會群體而有所不同的週期。另外,布洛克還注意到,由於社會變遷的韻律的快慢,「世代」的週期也非規律或固定不變的。於茲,布洛克多層次的歷史時間觀浮現。145 這樣的概念,我們可以在《封建社會》有關中世紀人的時間觀的論述當中發現,也可以在《法國農村史》的論述過程中發現。

    +

    相對於短暫的「世代」,較長的時間是「文明」。對布洛克而言,文明也可作為一個觀察一個社會整體之發展的時間單位。但是,如前文所述,布洛克並沒有對文明這個概念作清楚的說明,我們只知道他認為基於人類社會發展所具有的緩慢變化的特性,所以以文明作為相對較長的時間向度。為何?布洛克認為,不能僅僅以短暫的年代或世代來衡量社會的發展與變遷。他說:「社會如果要能完全由其緊鄰的前代所塑造,那麼,它的社會結構就必須軟到事實上等於是無脊椎的。」146 換言之,就社會的結構而言,我們無法在短暫的時間中可以觀察到它的變化。因為,社會有其所獨具的慣力與惰性。147 在此,我們可以發現,布洛克認為社會發展與變遷的性質,必須以較長時期的時間作為其理解的向度。

    +

    由上述的觀察,我們可以發現布洛克所呈現的多層次的歷史時間觀。布洛克曾說:

    + +
    +

    總之,人類的時間永遠不會符合時鐘的嚴格一致性或其固定的間隔。人類的事實要求度量的準則配合其自身韻律的變化,並要求其邊界有廣大的邊緣地帶。只有維持這種伸縮性,歷史學才有希望使分類符合柏格森所說的:「事實的真正輪廓」--這正是任何科學的終極目標。148

    +
    + +

    但是,並非所有的歷史現象一定都得像布洛克所認為的,必須以相對較長的時間觀來理解。而他自己也意識到此點,所以,他說:「歷史學者不免擺盪於下述兩者之間:他有時考慮的是跨越長時段之相關現象的巨大波浪,有時則考慮當眾流匯聚成洶湧的漩渦的特定時刻。」149 事實上,他自己也曾經以其在兩次世界大戰的經歷,著作了《戰爭回憶錄: 1914-1915 》與《奇異的敗仗》兩本書。換言之,歷史家從事歷史的觀察與理解時,得依照其所處理之主題的性質選擇運用的時間單位。但是,從布洛克所從事的實際歷史研究,我們可以發現,他特別強調某些長時期發展與變遷的現象。依筆者之見,在布洛克特殊的歷史時間觀中,已經隱然可見布勞岱爾長時段時間觀的雛形。150

    +

    在《封建社會》一書當中,布洛克所處理的主題即是從九世紀中葉到十三世紀初期間的歐洲封建社會的形成、發展與變遷。151 前已述及,基於社會與社會結構變遷所獨具的特性,必須以較長的時段來綜觀其發展。而在這樣的架構底下,布洛克將封建文明區分為兩個時期,他這樣指出:

    + +
    +

    若完全按照年代順序排列處理封建文明這一部文明史,是一個重大的錯誤。由於最後入侵的停止,無疑地或可能促成一系列非常深刻而廣泛的變化,而這些變化則在好幾世代之後,也就是十一世紀的時候才發生的。雖然沒有發生與過去明顯的斷裂,但這種方向性的變化也影響到一切社會活動的圖像。總之,存在著兩個連續而基本性質不相同的封建時期。152

    +
    + +

    在《法國農村史》一書當中,布洛克以「長時段」的觀點,探討十三世紀農村的領主制度到十八、九世紀的農業革命之間,有關人口增殖與居住的形式、農村景觀、地形的種類、地塊的設計與實況、耕種實務、生產的社會模式的發展與演變動態的結構過程,從中探究不同的農業文化類型的結構是如何變動的。在《法國農村史》的結論中,布洛克指出:

    + +
    +

    確實,那一個學科更急切於迫使他的實踐者抓住歷史真正本質的研究方法呢?在人類社會發展的連續統一體 (continuum) 中,分子與分子之間的震動波傳播到遙遠的地方,所以,不論其所在的發展階段為何,都不能以它對最近階段歷史的考察來理解一個單獨的運動。153

    +
    + +

    同時,布洛克也企圖藉由耕地形態之轉變與若干農業習俗衰落之探討,說明個人主義心態之興起、資本主義商業行為之出現與莊園制度的社會如何過渡到資本主義社會之變遷。154

    +

    《國王神蹟》一書之主題,在時間的向度上即橫跨了八個世紀之久。該書之主旨,在於論述十世紀到十八世紀期間,流行於法、英的「御觸」儀式與人民對此儀式的集體信仰。他致力於描繪人民「集體幻想」的普遍趨勢,而此趨勢延續了長達八世紀甚至更長的時段。伏維爾 (Michel Vovelle) 則將這種心理的現象稱之為「心靈結構的惰性趨力」。155 換言之,人的心態經常可持續發展綿延數世紀之久,看似「極為緩慢的變遷」或根本不變的歷史。而該書所描述的「國王神蹟」,便屬於這一種緩慢發展的社會現象。總之,在《國王神蹟》一書中,布洛克以長時期的觀點來考察人類宗教心態的形成、發展與演變,而在書中他也不只一次的使用「長期」 (long period) 一詞。156

    +

    綜上所述,我們可以理解到,布洛克不滿於傳統僵化的編年史、事件史與起源式的歷史時間觀,而提出了倒溯研究法、多層次的歷史時間觀與長時段等概念。此外,筆者認為,布洛克在歷史時間觀上之創獲,實源於其歷史思想中的社會整體歷史之概念。此乃由於史家必須從整體的角度掌握對歷史發展的理解,於是針對不同的研究對象,便必須依照其本身變遷的韻律來觀察,如此便推衍出多層次的歷史時間觀,如地理的時間、社會的時間、人類心態的時間等。

    + +

    第三節 問題取向的歷史研究與比較方法

    + +

    布洛克具有革新意義的歷史思想,不但表現在歷史的概念與時間觀上,也同時表現他所提出的問題取向與比較方法。問題取向的歷史研究是布洛克所堅持的主張,他認為歷史的研究都源於歷史家自身的問題意識,歷史研究的起點便是提出一個適當的問題。比較方法則是布洛克從事歷史的實際研究時經常運用的方法,其意義在於:首先,幫助史家提出適當的問題;其次,則是作為史家從事歷史解釋時所運用的原則、方法。筆者認為,問題取向的歷史研究與比較方法,乃是布洛克方法論的核心,也是布洛克建構其歷史解釋時的基礎。

    + +

    問題取向的歷史研究

    + +

    「問自己問題是有用的,但是去回答他們,是很危險的。」157 這是布洛克的老師塞諾博斯所說的一句話。相反地,布洛克則認為問題的提出乃是歷史研究的起點,他說:「每項歷史研究都假定在一開始就該有個詢問的方向。」158 對布洛克而言,提出問題具有雙重的意義。首先,一方面是要向史料詢問適當的問題,以發掘出在史料背後所隱藏的意義。因此,在布洛克眼中,史料的意義乃是史家所賦予的,「史料在史家適當的詢問之下,才開口說話。」並且得以「偷聽那從不打算說出的事情。」159 換言之,布洛克強調史家不能受制於史料而從事歷史的研究,並主張史家要「質問」文獻,且將之放置在「問題」的架構之下,以此構成史學研究的起點。筆者認為,這項原則的提出,凸顯了史家在歷史研究時的主體性,並構成了史家與史料之間「新」的互動關係,史家不再是受制於史料的奴僕。160 另一方面,提出問題構成了史家從事其歷史研究所進行的方向,史家藉由自問自答的方式,逐步鋪陳、建構其歷史的解釋。布洛克認為,根據對於史料的檢驗與比較,進而提出或形成問題,將有利於史家從事更為合理而準確的解釋。

    +

    對布洛克而言,歷史家所提出的問題,不但是歷史研究的起點,也是從事歷史研究的最重要的一環。他甚至認為,在歷史研究的版圖上,史家最重要的貢獻在於他在某一個特殊的研究領域提出了什麼具有重要意義的問題。當一個歷史研究的開拓者,對布洛克而言乃是更具有重要意義的。在布洛克寫給費弗爾的一封信當中,提及了將《法國農村史》的演說內容經增補後出版成書的念頭時,他如此寫到︰「為了我在奧斯陸的演說,我費盡心力地工作。儘管在演說內容中很明顯地仍有許多晦澀不明與輕率的假設,但是我希望將它變成一本書,因為在某種程度上,它可以說形成了若干問題……你也知道的,在此一領域的研究幾乎沒有綜合性的著作。」161 在《法國農村史》的導論當中,布洛克指出,這本綜合性的著作並不企圖成為定論,他自己預計自己的著作將會被後人所質疑、修正,他期盼這本書能夠刺激出農業史方面較嚴謹的著作。因此,他自己以此一領研究領域的「開拓者」自任,並認為「問題的形成較之於解決的方法還要重要」。162 事實上,對於作為一個開拓者的理想,布洛克的確是成功地,他被稱為是法國農村史最重要的奠基者,而他在相關研究領域所提出的觀點與問題,也被後來的學者如杜比的研究中引申或者解決了。163 同樣地,布洛克《國王神蹟》與《封建社會》兩部書都具有開創性的成就,並且都在著作中提出猶待解決的問題。在《法蘭西之島》當中,布洛克也明確地指出,真正理想的區域史研究應該是問題取向的。164

    +

    布洛克所提出了「問題取向的歷史研究」 (history-through-problems) 的原則,突破了史學一向以來敘述取向的歷史研究與寫作傳統。而這項「問題取向」的歷史研究原則,則一直被年鑑後代史家沿用至今。誠如勒高夫 (Jacques Le Goff, 1924-) 所說的︰「新史學就是問題史學」,其意就在於標榜新史學與傳統史學之間的差異。165

    + +

    比較方法及其運用

    + +

    比較方法的使用,一向是布洛克歷史研究的特色,他也曾就這個方法提出他個人的理論,而此也正是他對當代史學的主要貢獻之一。英國史學家巴勒克拉夫 (Geoffrey Barraclough, 1908-1984) 曾給予布洛克極高的評價,他說:

    + +
    +

    當代歷史家之所以非常重視比較史學,其原因在很大程度上是由於馬克布洛克的教導和他所作出的榜樣。在 1928 年,他寫了一篇對歐洲社會進行比較研究的綱領性論文,及他的那部論述封建社會的名著也為後來的比較歷史提供了楷模。166

    +
    + +

    上述引文中所提及的「綱領性論文」,指的就是布洛克在 1928 年所撰寫的一篇題為〈朝向歐洲社會比較歷史的一個貢獻〉的論文。167 在此文中,布洛克樂觀地認為,將比較方法運用於歷史研究之上具有無限地的可能性與潛力,因此期望史家能夠廣泛第加以運用,甚是說「是史家現在最為迫切的任務。」168 不過,布洛克仍謙虛的表示,比較方法並非他個人的新發現,他只是站在前人的肩膀上,從史家的觀點出發,提出一個較為適當的解釋與補充。因此,在〈朝向歐洲社會比較歷史的一個貢獻〉一文中,布洛克較系統性地提出他對於比較方法之本質及其適用範圍的解釋。169

    +

    首先,布洛克指出比較的意義:

    + +
    +

    從一個或若干社會狀況 (social situations) 當中,選擇兩個或更多一看就具有相似性的現象;然後,追溯這些現象發展的狀況,記錄並解釋其相似性和相異處。歷史地來說,兩種狀況使得比較是可能的:在這些被觀察的現象當中,必須存在著某種程度的相似性,以及在這些若干狀況當中,必須存在著某種程度的相異性。170

    +
    + +

    換言之,比較的意義除了在於建立對若干不同現象間的相似性與相異性之理解外,並且還可能從中建立一個具有統一性的整體。此外,必需強調的是,比較的基礎還在於對「個別的社會、現象的發展」建立一清楚的認識。其次,在上述定義的基礎下,布洛克認為比較方法的使用,根據研究主題與範疇的不同,可分為兩種。第一種是在「不同時空下兩個或以上之社會」的比較,第二種是兩個「相鄰近、同時代、具有相同起源且相互影響之社會」之比較。而布洛克本人,似乎較傾心於第二種比較方法的運用。171

    +

    布洛克在〈朝向歐洲社會比較歷史的一個貢獻〉一文綜合提出了他對於比較方法的說明,整體而言,歷史家運用比較方法的意義與好處頗多。

    +

    首先,布洛克認為,比較方法對於史家最大的用處之一,即是作為從歷史研究時從事史料之考證、批判與分析,最後發現問題、提出問題的工具。布洛克認為幾乎所有的史料證據的考證工作背後,都有比較的問題。它一方面可幫助史家進行對史料的批判,另一方面它還可填補史家進行研究時因缺乏史料所造成的空隙與困難。史家無法從 A 檔案文件知道的訊息,或許可以從 B 檔案文件獲得。因此,史家透過對各種史料的比較,可以彌補史家因為史料不足所形成的缺憾。此外,透過若干方面史料的比較,也可以發現不同現象之間的相異處與相似處。至此,布洛克指出,只有比較方法可以展現出真正的問題。172

    +

    此外,比較方法也可幫助史家從其論述中,進一步提出猶待解決之問題。例如,在《國王神蹟》中,布洛克分別就英、法兩國的「御觸」儀式進行了詳盡的論述之後,經過更進一步的分析與比較,他發現了一個奇怪的現象,即英國雖然已停止實行「御觸」的儀式,其人民信仰的心態,並未因此完全徹底消失;詹姆士二世在外國流亡時仍繼續行使「御觸」儀式,維多利亞時代蘇格蘭地區的人民仍相信有國王肖像的硬幣是萬靈藥等事例,即可證明普遍心理仍舊表現出對一個古老儀式的信仰。相反的,法國在查理十世之後,「御觸」這樣一個存在人們心中的概念,在被停止實行之後卻幾乎完全消滅。為什麼呢?173 --布洛克在這裡為讀者留下了一個新的問題。

    +

    其次,比較方法也可以幫助史家對於歷史現象的分析與詮釋。174 布洛克運用比較方法,建基於這樣一個信念,即歷史除非能在「確立現象之間關係的解釋方面取得成功」,否則就無法理解。因此,比較方法實質上是一個處理解釋性問題的工具。175 其中,藉由對相異、鄰近社會的比較,可以幫助史家辨明社會與社會之間的相互作用與影響;在某些例子的比較當中,比較也可以釐清不同社會間在古代的關係,得以證明在遙遠的過去,有一個整體的文明的存在;另外,藉由比較方法的運用,還可以幫助史家來發現歷史現象真正的原因。176

    +

    再者,筆者認為,就布洛克在歷史解釋方面的特色而言,比較方法最重要的意義,在於通過比較可以發現不同社會之間的獨特性。在此,布洛克採用梅耶類似的說法:比較語言學家的責任在於展示每一種語言的獨創性 (originality) ,他也認為比較方法之使用,除了在於觀察不同歷史現象間的相似性之外,最重要的還是在於發現不同社會之間的差異性與獨創性。177

    +

    此外,布洛克特別指出比較的單位是社會。以農村史的研究為例,布洛克反對那種以比較歷史僅能運用於不同民族和國家間的比較的假定,主張必須拋棄陳腐的地形分隔空間論 (topographical compartment) ;他認為按照這種理論,我們會因此而不顧社會現實。換言之,歐洲的農業地圖與其政治地圖是不相同的,僅僅處理一個區域無法增進史家的理解。再者,布洛克指出比較歷史研究適當的單位是社會,他說:「因為我研究的各種對象是從社會的各方面獲得的,而這個社會就其整體,構成為一個大單位。」178 總之,布洛克認為不能以純粹的國家或地理區域作為比較的單位,任何有關歐洲社會生活之研究,必須找到一個適當的分析架構,而且要從內部的社會結構訂定之,而非從外部的地理或行政區域。179 其次,我們可以拋棄那種集中於兩個或數個社會的研究才是歷史比較的假設。比較的方式有很多,有時是在一個國家之內不同區域間的比較,有時則是在不同的社會體制之間比較,有時是國與國間的比較,都依解釋的問題不同而異。最後,我們必須避免歷史比較研究中最具普遍性的缺點,也就是不作真的比較,只是把兩個具有類似發展的社會相提並論;換言之,歷史的相似性並不一定意味著有關係。180

    +

    西威爾 (Jr. William H. Sewell) 認為,布洛克這種出於多種不同的目的應用比較方法,又把這種方法貫穿於不同的前後關係中,其方法為假說驗證的邏輯。如果一個史家企圖把某一個社會中出現的 A 現象歸因於 B 條件的存在,那他可以通過比較,在另一個社會中尋找一個沒有 B 條件存在而同樣產生了 A 現象的例子來檢驗這一假說。如果他沒有發現可以反駁此一假說的例證,那他就得以增強此一假說的合理性。如果他發現的事例與假說相衝突,他必須徹底地否定假說,或者重新修正它,以便考慮此一互相矛盾的證據,從而再次對它進行比較驗證。通過這樣一個檢驗、重新提出和重新驗證的過程,史家將可獲得具有說服力和精確度的解釋。筆者認為,經由西威爾的詮釋,讀者將更能掌握住比較方法的意義。181

    +

    至此,我們可以說比較方法乃是布洛克從事歷史研究時的重要方法。他不僅提出了比較方法上理論性的建構,也可見之於其實際的歷史研究之中。布洛克在《封建社會》中即試圖利用比較方法,探究封建制度在歐洲社會中所呈現的普遍特徵與區域的獨特性。182 此外,布洛克也試圖藉由比較方法之運用,試圖說明封建制度作為一種社會類型本身所具有的特殊意義與性質。例如,他即試圖透過比較,呈現日本鎖國時期在社會群體關係,與歐洲中古時期封建社會之間的相似性與獨特性。根據比較的結果,布洛克指出:

    + +
    +

    這裡對兩種社會的對比雖然過於簡單,評價過於絕對,但在我看來,這一概述仍能使我們獲得十分可靠的的結論。封建制度不是『在世界上只發生過一次』。像歐洲一樣,儘管有著必然而根深蒂固的差別,日本也經歷了這個階段。其他社會是否也經歷了這個階段?183

    +
    + +

    由此觀之,布洛克似乎認為作為一種社會類型的某個歷史時期是可能的,儘管它並不同時存在於同時代的人類社會中。其次,布洛克似乎意圖藉由其對歐洲封建社會的研究,樹立更進一步之比較的模式。針對此,若干學者認為,布洛克在《封建社會》中所運用的比較方法,與韋伯 (Max Weber, 1864-1920) 的「理想型」 (Ideal Type) 的概念頗為類似。184 再者,巴勒克拉夫則稱《封建社會》是比較歷史的典範。185

    +

    在《法國農村史》一書當中,布洛克自己說到《法國農村史》乃屬於比較研究的形式。186 他指出,除非我們能以宏觀的眼光將法國視作一個整體,並透過進一步的比較,我們才能從中掌握各個不同區域之發展的特殊性。同時,也唯有將法國放在整個歐洲的脈絡之下進行比較,我們才能真正的領略法國的歷史。187 如此,布洛克藉由比較,企圖去描繪與探討法國農村中各種現像與活動的差異性。筆者發現,這樣的分析架構,經常出現在《農村史》一書的論述之中。例如,在探討有關法國土地開墾運動之發展過程當中,布洛克即首先從「將法國視作一個整體」 (France as a whole) 的觀察角度,透過各地區的比較,分析法國在土地開墾運動發展過程中所呈現的區域性與差異性;其次,布洛克將觀察的視角放大到整個歐洲,企圖發現歐洲各地區在土地開墾運動過程中所呈現的差異性。最後,布洛克更由此比較的過程中,發現法國在此一歐洲普遍存在的土地開墾運動中的特殊性。188

    +

    由此觀之,布洛克除了企圖透過歷史研究描繪法國農村地區的發展之外,還進一步透過比較研究,嘗試同時掌握人類活動的整體性與獨特性。而同樣的分析架構,也出現在上述的《封建社會》之中。筆者認為,就歷史認識的角度而言,這是相當有趣而值得思考的一點。著名歐洲近代史學史專家伊格斯曾經指出,縱觀歐美史學在十九世紀到二十世紀初之間的發展,歷史普遍性與獨特性之間的誰是誰非的問題,成為若干史家爭論的主題。兩個主要的陣營分別為代表實證主義傳統的「科學派」歷史家與代表德國學歷史傳統的「歷史主義」學派。有趣的是,他認為法國年鑑學派的歷史思想可以歸於折衷派。189 筆者則認為,就布洛克的歷史思想而言,伊格斯的提議在某種程度上是正確的。因為,在布洛克的歷史解釋中,確實有對於同時掌握歷史之整體性與獨特性的嘗試。不過,我比較持保留態度的是,布洛克並不企圖尋找所謂的普遍性的律則,他只是企圖掌握某些歷史現象的普遍特徵,並從中藉由比較進而探究各區域的獨特性。

    +

    《國王神蹟》一書中也運用了比較方法。布洛克在《國王神蹟》導論中明確的指出,本書採用了「比較歷史」的形式,以建構一個不同於傳統政治、民族史的解釋。190 換言之,比較方法是布洛克在進行《國王神蹟》一書論述時方法論之核心,他企圖透過比較方法的使用,對主題達成一不同於傳統敘述方式的歷史解釋。若從《國王神蹟》一書之內容來看,布洛克在書中所進行的是英、法兩國在同一時期下、同一現象之研究,屬於布洛克所定義的第二種比較類型。從全書的結構的安排看來,布洛克在進行英、法的比較時,也是先從英、法兩國在「國王神蹟」儀式之起源、發展與衰落等方面,分別進行詳盡的論述與分析,並在此基礎上再進行兩者相似性與相異性的綜合比較。因此,吾人可發現,在比較方法的使用下,布洛克所呈現出來的敘述邏輯,是先就英、法個別現象之「分析」著手,再進行兩者的綜合「比較」。其次,就布洛克所獲致的論點來觀察,在英、法「國王神蹟」儀式的背後,人民對國王神聖性之崇拜的普遍意識,正表現了當時歐洲所呈現的「整體性」。基於此,就布洛克而言,比較方法的意義在於,它是作為現象間之關係的解釋工具,以幫助史家對歷史達成真實的理解。

    +

    布洛克曾說:「不經過某種程度的比較是不會有真正的理解。」191 的確,觀察布洛克的歷史思想,我們可以發現,不論就史料運用與歷史解釋而言,比較方法在其從事歷史研究與寫作時都扮演了重要的角色。尤其就歷史的解釋而言,布洛克使用比較的方法,嘗試建構了一個同時能掌握歷史現象之普遍性與獨特性的歷史解釋模式,企圖展現一個較為宏觀的歷史視野。

    +

    在本章當中,筆者從整體的觀點,探討了布洛克歷史思想中的核心概念與方法。首先,我們可以發現,布洛克對於歷史此一概念的認知,已經跳脫法國傳統方法學派以政治的、個人的、事件的歷史研究取向,而以人類社會整體或者文明作為其歷史研究的對象。如此,不但使歷史研究的領域、主題更形擴大,展現了更為廣闊的歷史視野,甚至可以說豐富、開拓了史家這門行業的意義與領域。就此而言,布洛克的確開啟了法國歷史學的新時代。另外,基於社會整體歷史的概念,研究的方法與史料運用的種類也更趨多樣性,歷史研究因而朝向了科際整合的道路上邁進。筆者認為,布洛克所強調科際整合的歷史研究取向,似乎預視了歐美二十世紀中葉以後的發展方向。因此,就此而言,布洛克可為是一個先行者。

    +

    其次,布洛克在歷史的時間觀方面也展現了新意,不同於傳統史學僵化的時間概念。布洛克意識到了歷史時間本身所具有的特殊性質,在歷史的過去與現在之間,時間之流既具有連續性、也同時具有變遷性。針對此,他提出了倒溯研究法企圖同時掌握歷史的連續性與變遷性。更重要的,基於他對於歷史本身所持有的概念,他也指出了歷史的時間多層次的特性。進而,基於對社會結構與人類心態本身所具有的特殊的、緩慢變遷的性格,他也發展出長時段之概念。

    +

    再者,布洛克在歷史研究上所揭櫫的問題取向與比較歷史的兩項原則,打破了傳統史學歷史寫作上的敘述取向,在歷史寫作上轉向詮釋與分析的取向。同時,藉由布洛克在比較方法上的理論建構,我們也可以更進一步了解到比較方法在歷史研究過程中,所能發揮的效果。

    +

    最後,若從布洛克本身歷史思想的歷程而言,比較本章之內容與布洛克學生時期的歷史學筆記,我們可以發現,布洛克的歷史思想,在史特拉斯堡時期之前已趨於穩定,而史特拉斯堡時期則是他歷史思想進一步更形豐富、成熟的時期。首先,在歷史的概念與研究取向方面,布洛克對於人類社會群體與社會結構的重視與科際整合的研究取向,在他早期的著作如《法蘭西之島》中已經略具雛形。進入史特拉斯堡之後,由於長期與其他人文社會學科學者進行知識的交流,使得他在歷史研究上如《國王神蹟》、《法國農村史》、《封建社會》,引進了更多社會學、人類學、人文地理學的概念,作為其歷史研究的概念工具,而使其更具科際整合的研究取向。其次,在歷史研究方法方面,不論是問題取向的原則、或是比較方法的運用,也同樣出現在其早期的著作當中。到了後期,則提出更具系統性的方法論說明,也大量地將其運用在歷史寫作上。因此,筆者認為,布洛克終其一生在歷史思想上的發展與實踐,大體上乃依循其在「 1906 的筆記」當中所呈現的問題意識與基本觀點,從事其歷史的研究,並且從中展現他對於時代問題的解答。

    + + + +
    + 回目錄 | + 下一篇 +
    + +
    + +
    +
    * 本文原為於民國八十九年五月十九日在第六屆全國歷史學論文討論會上宣讀之論文,今稍作修改後發表之,特此說明。 (Back)
    +
      +
    1. Marc Bloch, The Historian's Craft, trans. Peter Putnam (New York: Vintage Books, 1953), 188. (Back)
    2. +
    3. Bloch, The Historian's Craft, 151. (Back)
    4. +
    5. Bloch, The Historian's Craft, 194. (Back)
    6. +
    7. 在此必須說明,這裡所謂的「方法學派」 (ecole mtheodiuqe) 指的就是一般所誤稱的「實證主義歷史學派 (ecole positiviste) 」,事實上,兩者之間的歷史觀念差異頗大。其中,最大的差異在於「實證主義歷史學派」極為強調歷史法則的建立,而「方法學派」則否,筆者認為頂多可以稱「方法學派」為實證主義遺毒下的歷史學派;此外,關於法國現代歷史學專業化之歷程,可參閱 : William R. Keylor, Academy and Community: The Foundation of the French Historical Profession (Cambridge, Mass.: Harvard University Press, 1975); Pim den Boer, History as a Profession: The Study of History in France, 1818-1914 (Princeton, N. J.: Princeton University Press, 1998), 175-223. (Back)
    8. +
    9. 就《年鑑》期刊整體的發展歷程言,其正式的名稱歷經五次變革。 Les Annales d'histoire economique et sociale (1929-1938); Les Annales d'Histoire Sociale (1939); Melanges d'Histoire Sociale (1942-1944); Les Annales d'Histoire Sociale (1945); Les Annales. Economies. Societes. Civilisation (1946-1993); Les Annales Histoire, Sciences Sociales (1994-); 有關年鑑學派之發展的論著,主要列舉如下: Francois Dosse, New History in France: The Triumph of the Annales, trans. Peter V. Conroy, Jr. (Urbana: University of Illinois Press, 1994); Philippe Carrard, Poetics of the New History: French Historical Discourse from Braudel to Chartier (Baltimore: The Johns Hopkins University Press, 1992); Traian Stoianovich, French Historical Method: The Annales Paradigm (Ithaca: Cornell University Press, 1976); Jean-Pierre V. M. Herubel, Annales Historiography and History: A Selective and Annotated Bibliography (Westport, Conn.: Greenwood Press, 1994); Peter Burke, The French Historical Revolution: The Annales School 1929-89 (Cambridge: Polity Press, 1990), 2, 117; 而有關年鑑學派之專論文章可參閱 : Paul Archambault, "An Interview with Jacques Le Goff," Historical Reflection 21, 1(1995): 155-185; George Iggers, New Directions in European Historiography, revised edition (Middletown, Conn.: Wesleyan University Press, 1984), 43-79; George Iggers, Historiography in the Twentieth Century: From Scientific Objective to the Postmodern Challenge (London: Wesleyan University Press, 1997), esp. chapter5; 周樑楷,〈年鑑學派的史學傳統及其轉變〉,《近代歐洲史家及史學思想》(台北 : 華世, 1985 ), 189-206 。 (Back)
    10. +
    11. Bloch, The Historian's Craft, 35; Marc Bloch, Feudal Society, trans. L. A. Manyon (Chicago: The University of Chicago Press, 1961), 148. (Back)
    12. +
    13. 關於法國十九世紀末到二十世紀初歷史學與社會學之論爭,此不贅述。在此,為使讀者理解之便,僅歸納論爭的焦點如下︰首先,歷史知識性質的問題,也就是歷史學到底是否是一門具有科學性的知識?歷史研究的最後目的是否必須能建立人類社會發展之法則?其次,是有關歷史寫作的問題,也就是歷史家在從事歷史的寫作時,是否需要進行歷史解釋?歷史事件間的因果關係如何建立其合理性的解釋呢?歷史的發展是否僅能注意到政治與軍事的因素,而忽略了社會與文化的因素呢?再者,歷史發展中的個體與群體之間關係的問題,歷史學的研究是否過分強調了個人的重要性,而忽略了社會群體的因素?最後,歷史學與社會學的關係應該如何發展呢?這是歷史學術發展歷程中時代向史家所提出的問題,這些問題的思考也在爾後法國的歷史學發展具有深刻的影響。 (Back)
    14. +
    15. Susan W. Friedman, Marc Bloch, Sociology and Geography (Cambridge: Cambridge University Press, 1996), 39, 52-54. (Back)
    16. +
    17. Friedman, Marc Bloch, Sociology and Geography, 52. (Back)
    18. +
    19. Friedman, Marc Bloch, Sociology and Geography, 53. (Back)
    20. +
    21. Friedman, Marc Bloch, Sociology and Geography, 53. (Back)
    22. +
    23. Carole Fink, Marc Bloch: A Life in History (Cambridge: Polity Press, 1990), 7-11, 14. 筆者認為,有關古朗士之歷史思想,不但對古斯塔夫產生了深刻的影響,在本文當中,讀者將可發現古朗士對布洛克之歷史思想也產生了不可磨滅的影響。若干論者也認為,就法國現代史學思想的發展而言,布洛克與古朗士之間具有傳承關係,甚至稱之為「古朗士第二」。參見 : Trygve R. Tholfsen, Historical Thinking (New York: Harper & Row, Publishers, 1967), 186-213; Stoianovich, French Historical Method, 13. (Back)
    24. +
    25. Fink, Marc Bloch: A Life in History, 24. (Back)
    26. +
    27. Fink, Marc Bloch: A Life in History, 37, 39. (Back)
    28. +
    29. Fink, Marc Bloch: A Life in History, 83-84, 186. (Back)
    30. +
    31. Fink, Marc Bloch: A Life in History, 249-266, 293-324. (Back)
    32. +
    33. Fink, Marc Bloch: A Life in History, 25-38. (Back)
    34. +
    35. Fink, Marc Bloch: A Life in History, 27. (Back)
    36. +
    37. Friedman, Marc Bloch, Sociology and Geography, 76. (Back)
    38. +
    39. Marc Bloch, The Ile-De-France: The Country around Paris, trans. J. E. Anderson (Ithaca: Cornell University Press, 1966); Fink, Marc Bloch: A Life in History, 45; Friedman, Marc Bloch, Sociology and Geography, 96; Martin Siegel, "Henri Berr's Revue de Synthese Historique," History and Theory 9(1970): 322-334; Keylor, Academy and Community, 126-139. 貝爾在《綜合歷史評論》中設有「法蘭西區域」 (Les regions de la France) 之專題研究,提倡以歷史社群的集體心理學、跨學科交流與整合為訴求的區域史研究,布洛克的《法蘭西之島》則分別刊載於 1912 、 1913 年的《綜合歷史評論》上。 (Back)
    40. +
    41. 該書有關科際整合概念之運用可參閱 : Bloch, The Ile-De-France, 9, 11, 14-15, 35, 42, 46, 52, 72-73, 118. (Back)
    42. +
    43. Bryce Lyon, "Foreword," in Marc Bloch, French Rural History: An Essay on Its Basic Characteristics, trans. Janet Sondheimer (Berkeley: University of California Press, 1966), xi. (Back)
    44. +
    45. Fink, Marc Bloch: A Life in History, 128-140. (Back)
    46. +
    47. Fink, Marc Bloch: A Life in History, 88-90; Friedman, Marc Bloch, Sociology and Geography, 95-99. (Back)
    48. +
    49. Fink, Marc Bloch: A Life in History, 91; Maurice Hallbwachs, On Collective Memory, trans. Lewis A. Coser (Chicago: The University of Chicago Press, 1992), 9-11, 21-28. (Back)
    50. +
    51. Fink, Marc Bloch: A Life in History, 91-94. (Back)
    52. +
    53. Marc Bloch, The Royal Touch, trans. J. E. Anderson (New York: Direst Press, 1989), 3; Fink, Marc Bloch: A Life in History, 109-114. (Back)
    54. +
    55. Bloch, French Rural History, xvii; Friedman, Marc Bloch, Sociology and Geography, 144; Cf. Frederik Stang, Report on the Activities of the Institute for Comparative Reasearch in Human Culture in the years 1927-1930 (Oslo: Institute for Sammenlignende Kulturforskning, 1930), serie C1-3, 3-7, 19-22. (Back)
    56. +
    57. Bloch, The Historian's Craft; Bloch, Feudal Society. (Back)
    58. +
    59. Eric Hobsbawm, "From Social History to the History of Society," in On History (New York: The New Press, 1997), 81-82, 92. (Back)
    60. +
    61. Marc Bloch, Memoirs of War, 1914-1915, trans. Carole Fink (Ithaca: Cornell University Press, 1980); Marc Bloch, Strange Defeat: A Statement of Evidence Written in 1940 (New York: W. W. Norton & Company, 1968). (Back)
    62. +
    63. Lucien Febvre, "A Note on the Manuscripts of the Present Book," in Bloch, The Historian's Craft, xiii-xviii. (Back)
    64. +
    65. Bloch, The Historian's Craft, 4, 9. 在本文當中由《史家的技藝》一書所摘錄之引文,乃參考周婉窈之譯文略加修改而成,特此說明。參見 : Marc Bloch ,《史家的技藝》,周婉窈譯 ( 台北 : 遠流, 1989). (Back)
    66. +
    67. Bloch, The Historian's Craft, 1-2. 在注釋一當中,我們可以看到布洛克對其師執輩的看法。他如此寫道:「在這裡,我發現自己意想不到的從一開始,就在反對郎格諾與塞諾博斯的《史學原論》。在《史學原論》一書的前言之中,我偶然發現一份『無用的問題』的清單時,上面的這一段文字已經寫好了。在那份清單裏,一字不差地出現了如下的一條:『歷史有什麼用?』對此問題的這種心態,無疑地與對其他那些有關我們之思想與行動的存在理由的任何問題的心態是一樣的:那些天生--或是有意決定使之如此--對這些問題就漠不關心的心靈總是發現難以了解為什麼其他的心靈會以它們為反省關注的對象。雖然如此,由於既然有這樣一個機會,相對於那本名符其實的名著,我認為最好馬上說明我的立場。我自己的書--計畫不同,且在某些部份,遠為不盡理想--斷斷不敢僭越要取而代之。我是該書兩位作者的學生,特別是塞諾博斯的學生。不過,他們兩位不僅教導我們:史學工作者首要的職責是在真誠毋欺;他們也完全了解:我們的研究的進步正是奠基在不同代學者之間不可避免的對立。因此,我將繼續信從他們的教導,當我認為有用時,就毫無顧忌的批判他們;就如同我希望,有朝一日,也輪到我的學生來批評我。」 (Back)
    68. +
    69. Bloch, The Historian's Craft, 12. (Back)
    70. +
    71. Bloch, The Historian's Craft, 19. (Back)
    72. +
    73. Bloch, The Historian's Craft, 14-16. (Back)
    74. +
    75. Bloch, The Historian's Craft, 27. (Back)
    76. +
    77. Bloch, The Historian's Craft, 18. (Back)
    78. +
    79. Bloch, The Historian's Craft, 10. (Back)
    80. +
    81. Bloch, The Historian's Craft, 13-14. (Back)
    82. +
    83. M. M. Postan, "Foreword," in Bloch, Feudal Society, xi-xii; Fink, "Introduction: Marc Bloch and World War I," in Marc Bloch, Memoirs of War, 1914-1915, 23. (Back)
    84. +
    85. Bloch, The Historian's Craft, 7. (Back)
    86. +
    87. Bloch, The Historian's Craft, 8-9. (Back)
    88. +
    89. Bloch, The Historian's Craft, 20. (Back)
    90. +
    91. Bloch, The Historian's Craft, 22. (Back)
    92. +
    93. Bloch, The Historian's Craft, 22. (Back)
    94. +
    95. Bloch, The Historian's Craft, 25. (Back)
    96. +
    97. Bloch, The Historian's Craft, 24. (Back)
    98. +
    99. Bloch, The Historian's Craft, 25-26. (Back)
    100. +
    101. Bloch, The Historian's Craft, 25, 注釋 2. (Back)
    102. +
    103. Bloch, The Historian's Craft, 20, 153. (Back)
    104. +
    105. Bloch, The Ile-De-France, 94, 112. 另外,布洛克還在有關法國農村農業習作的研究中,特別注意到「階級」的問題,甚至明確地說︰「農村社會是由清楚定義的各種階級所組成的。」參閱 : Bloch, French Rural Hisotry, 47-48. 由此,我們不僅可以發現布洛克對社群組織之概念的強調與運用,或許還可以由此思考布洛克是否受到馬克思的影響,抑或是受到社會主義者 Jaures 的影響呢?筆者甚至認為,此一強調整個國家或文明之社會組織及其凝聚力的觀念,可以在十九世紀到二十世紀初的法國社會菁英的思想之中,如史家米敘列與古朗士等,這也正呼應了維科所指出的「人之社會性與社會性之人」的論點,亦即如「人乃是社會的動物」的提法。關於維科的觀點,可參閱 : Leon Pompa, Vico: A Study of the 'New Science', second edition (Cambridge: Cambridge University Press, 1990), 18-30; Alan Swingewood, A Short History of Sociological Thought, second edition (London: Macmillan, 1991), 10-13. (Back)
    106. +
    107. Bloch, The Historian's Craft, 26, 注釋 3. (Back)
    108. +
    109. Bloch, The Historian's Craft, 154-155. (Back)
    110. +
    111. Bloch, The Historian's Craft, 188. (Back)
    112. +
    113. Bloch, The Historian's Craft, 188. (Back)
    114. +
    115. Bloch, The Historian's Craft, 187. 但是,從他引用基佐 (Francois Guizot, 1787-1874) 「在這個綜合體體的核心,所有造成其存在的力量皆匯聚在一起。」這樣一段文字的線索看來,他可能是直接或間接地從基佐身上獲得了文明二字的靈感。為什麼筆者會說他可能直接或間接地從基佐身上獲得文明二字的靈感呢?因為,我們雖然無法獲知布洛克是否真的拜讀過基佐的作品,但至少可以說布洛克是從費弗爾那兒受到啟發的。因為,費弗爾曾經寫過一篇探討「文明」此一觀念之緣起與發展的文章,而布洛克明顯地閱讀過這一篇文章。誠如他所自承的:「感謝費弗爾,我們才對文明這個字的歷史相當熟悉。」參閱︰ Lucien Febvre, "Civilization: Evolution of a Word and a Group of Ideas," in Classical Readings in Culture and Civilization, ed. John Rundell and Stephen Mennell (London: Routledge, 1998), 160-183. (Back)
    116. +
    117. Febvre, "Civilization: Evolution of a Word and a Group of Ideas," 168-171. (Back)
    118. +
    119. Febvre, "Civilization: Evolution of a Word and a Group of Ideas," 172-173. (Back)
    120. +
    121. Febvre, "Civilization: Evolution of a Word and a Group of Ideas," 177-179. (Back)
    122. +
    123. Bloch, Feudal Society, 60. (Back)
    124. +
    125. Bloch, Feudal Society, xxv. (Back)
    126. +
    127. Bloch, French Rural History, 35. 其他例子如頁 16 的歐洲文明與法國文明。頁 36 的農村文明 (rural civilization) 、頁 62 的文明的類型 (types of civilization) 、頁 157 的農業文明的類型 (types of agrarian civilization) 等例子非常多,此不贅述。 (Back)
    128. +
    129. Bloch, The Historian's Craft, xiv. (Back)
    130. +
    131. Bloch, Feudal Society, xix. (Back)
    132. +
    133. Bloch, Feudal Society, 59. (Back)
    134. +
    135. Bloch, Feudal Society, 72-73. (Back)
    136. +
    137. Bloch, Feudal Society, 60-71. (Back)
    138. +
    139. Bloch, French Rural History, 60, 139, 153, 214, 217; 其中,拉度里的《郎格多瓦的農民》 (The Peasants of Languedoc) 可視為此一研究取向的經典之作,參閱 : Iggers, New Directions in European Historiography, 62. (Back)
    140. +
    141. Bloch, French Rural History, 35. (Back)
    142. +
    143. Bloch, French Rural History, 40-41. (Back)
    144. +
    145. Bloch, French Rural History, 41. (Back)
    146. +
    147. Bloch, French Rural History, 45. (Back)
    148. +
    149. Bloch, French Rural History, 48. (Back)
    150. +
    151. Bloch, French Rural History, 104. 又例如在「農業系統︰封閉式田地 (Agrarian Regimes: Enclosed Fields) 」一節之論述中,同樣呈現出布洛克對於「社會」此一因素的重視與運用。他認為,正如同在敞田的一樣,圈田的物質表現乃是深層社會實體的外在表現。在《法國農村史》一書中類似的論述觀點例子相當多,此不贅述。 (Back)
    152. +
    153. Bloch, French Rural History, 167. (Back)
    154. +
    155. Macr Bloch, "Natural Economy or Money Economy," in Land And Work in Medieval Europe, trans. J. E. Anderson (New York: Harper & Row, Publishers, 1967), 241. (Back)
    156. +
    157. Bloch, French Rural History, 145-148. (Back)
    158. +
    159. Bloch, French Rural History, 150-196. (Back)
    160. +
    161. Bloch, French Rural History, 166-167. (Back)
    162. +
    163. Iggers, Historiography in the Twentieth Century, 63; Iggers, New Directions in European Historiography, 68, 70; 另外有關馬克思主義史家的歷史概念可參閱 : 周樑楷,〈英國史家湯姆森夫婦的史學和社會思想〉,《新史學》,第九卷第四期, 1998 , 99-142; 周樑楷,〈《過去與現在》︰英國馬克思史家創辦歷史學術期刊的思想與策略, 1952-1972 〉,錄於周樑楷, "Modern British Labor Historians and Their Conceptions of History," (Ph. D. diss., State University of New York at Buffalo), chs. Five and Six. 未刊稿 ; 周樑楷,〈一九五六年對英國馬克思史家的衝擊︰以哈布斯頗和湯姆森為分析對象〉,《第三屆史學史國際研討會論文集》(台中:中興大學歷史系, 1991 ), 235-261; 周樑楷,〈 " 人" 與 " 歷史" 之間:以湯姆森和布勞岱的歷史撰述為討論實例〉,第四屆史學史研討會,國立中興大學, 1998; 周樑楷先生認為,費弗爾是較偏向歷史主義及唯心論一方的代言人,布洛克則是偏重實證主義及唯物論的開基主,且說布洛克之書中物質因素大過於心理因素,參閱 : 周樑楷,〈年鑑學派的史學傳統及其轉變〉,《近代歐洲史家及史學思想》 ( 台北 : 唐山, 1990), 195-196 。 (Back)
    164. +
    165. Bloch, The Historian's Craft, 22-29, 153. (Back)
    166. +
    167. Bloch, The Historian's Craft, 151. (Back)
    168. +
    169. Bloch, The Historian's Craft, 194. (Back)
    170. +
    171. Bloch, The Historian's Craft, 153. (Back)
    172. +
    173. Bloch, "Technical Change as a Problem of Collective Psychology," in Land and Work in Mediaeval Europe, 124-135. (Back)
    174. +
    175. Bloch, French Rural History, 105-106. (Back)
    176. +
    177. Bloch, French Rural History, 126. (Back)
    178. +
    179. Bloch, French Rural History, 46-47. (Back)
    180. +
    181. Bloch, French Rural History, 241. (Back)
    182. +
    183. Bloch, French Rural History, 54. (Back)
    184. +
    185. Bloch, French Rural History, 54-55. (Back)
    186. +
    187. Bloch, Feudal Society, 83. (Back)
    188. +
    189. Roger Chartier, Cultural History, trans. Lydia G. Cochrane (Cambridge: Polity Press, 1988), 21; Dosse, New History in France, 61-73; Patrick H. Hutton, "The History of Mentalities: The New Map of Cultural History," History and Theory 20(1981), 139; Burke, The French Historical Revolution, 17; Georges Duby, History Continues (Chicago: The University of Chicago Press, 1994), 4, 6, 71-72. (Back)
    190. +
    191. Carlo Ginzburg, Clues, Myths, and the Historical Method, trans. Joan and Anne Tedeschi (Baltimore: The Johns Hopkins University Press, 1992), ix; Carlo Ginzburg, The Cheese and the Worms: The Cosmos of a Sixteenth-Century Miller, trans. Joan and Anne Tedeschi (Baltimore: The Johns Hopkins University Press, 1992). (Back)
    192. +
    193. Bloch, The Royal Touch, 3-5, 106. (Back)
    194. +
    195. 布洛克雖很少提及心態 (mentality) 一詞,但在書中頁 63 至少曾提及一次。此外,類似的字眼則出現了不少次,如如「心靈態度」 (attitude of mind) 、「集體意識」 ( 頁 103) 、「普遍意識」、「集體概念」 (collective ideas)( 頁 30) 、「集體信仰」 (collective belief)( 頁 46) 、「集體意見」 (collective opinion)( 頁 89) 、「心靈狀態」 (state of mind)( 頁 217) 等詞彙卻經常出現在《國王神蹟》的論述過程之中。 (Back)
    196. +
    197. Bloch, Feudal Society, 59. (Back)
    198. +
    199. Bloch, Feudal Society, 59-60, 70-71. (Back)
    200. +
    201. Bloch, Feudal Society, 31-38, 40-42, 54-55. (Back)
    202. +
    203. Bloch, Feudal Society, 72-87. (Back)
    204. +
    205. Jean Bodin, Jean Bodin's Method for the Easy Comprehension of History, trans. Beatrice Reynolds (New York: Columbia University Press, 1966), 9-29; Montesquieu, The Spirit of the Laws, trans. and ed. Anne M. Cohler (Cambridge: Cambridge University Press, 1989). (Back)
    206. +
    207. Bloch, The Ile-De-France, 14. (Back)
    208. +
    209. Bloch, The Ile-De-France, 57-62, 119-123. (Back)
    210. +
    211. Bloch, French Rural History, 34. (Back)
    212. +
    213. Stoianovich, French Historical Method, 236. (Back)
    214. +
    215. Fernand Braudel, The Mediterranean and the Mediterranean World in the Age of Philip II, 2vols., trans. Sian Reynolds (Berkeley: University of California Press, 1995). (Back)
    216. +
    217. Emmanuel Le Roy Ladurie, The Peasants of Languedoc, trans. John Day (Urbana and Chicago: University of Illinois Press, 1976). (Back)
    218. +
    219. Bloch, The Historian's Craft, 18-19. (Back)
    220. +
    221. Bloch, The Historian's Craft, 47. (Back)
    222. +
    223. 關於布洛克在其歷史著作上所呈現的科際整合的特色,將會在論文第三章中進行更為深入的探討。另外,關於年鑑史家強調科際間知識交流的特色可參閱 : Jean-Pierre V. M. Herubel, "The Annales: Its History and Evolution," in Annales Historiography and Theory: A Selective and Annotated Bibliography, compiled by Jean-Pierre V. M. Herubel (Westport, Connecticut: Greenwood Press, 1994), 1-13. 該作者從「科際整合」的角度概述年鑑史學的發展,他強調年鑑史家歷史寫作的所呈現出來的「科際整合」的趨勢。 (Back)
    224. +
    225. Langlois and Seignobos ,《史學原論》,李思純譯 ( 台北 : 商務, 1968), 1, 3. (Back)
    226. +
    227. Bloch, The Historian's Craft, 66. 從事心態歷史取向研究的荷蘭史家赫伊津哈 (Johna Huizinga) ,在《中世紀之秋》 (The Autumn of the Middle Ages) 一書從事有關中世紀布根第地區的社會與文化時,即曾經感嘆官方檔案文獻往往無法提供可資史家觀察群眾情感、行為的材料,必須轉向文學、民謠、藝術、繪畫作品當中去捕捉當時群眾的心態。 Johna Huizinga, The Autumn of the Middle Ages, trans. Rodney J. Payton and Ulrich Mamnitzsch (Chicago: The University of Chicago Press,1996), 9, 27. (Back)
    228. +
    229. Bloch, Feudal Society, 89, 90, 91, 93, 94, 98. (Back)
    230. +
    231. Bloch, French Rural History, 3, 32, 142-143, 206. (Back)
    232. +
    233. 在《封建社會》中使用的史料種類極為廣泛,如詩歌、遺囑、祈禱文、考古遺址、墓碑、傳奇文學、請願書、教會檔案、詩、印章、繪畫、浮雕等,參見 : Bloch, Feudal Society, 35, 41, 44 , 50, 51, 54, 78, 89, 125, 126, 131, 145, 146, 183, 196; 在《法國農村史》中使用的史料包括了 : 考古遺址、契據登記簿、地圖、遺書、莊園登記簿冊、民謠、文學作品、備忘錄、詩作、統計資料等,參見 : Bloch, French Rural History, 1, 2, 3, 4, 6, 11, 38, 41, 56, 119, 143, 182; 在《國王神蹟》的論述中,採用的史料種類也顯示了多樣性,範圍極為廣泛,除了宮廷的紀錄與文件之外,其取材還包括了醫學、神學與政治學理論的著作、小冊子、文學著作、聖經、宗教祈禱文、詩文、歷史著作、法律訴訟文件、信件、繪畫作品、錢幣等,參見 : Bloch, The Royal Touch, 13, 14, 15, 18, 22, 31, 36, 40, 59, 64, 66, 81, 83, 87, 110, 112, 142, 143, 146, 220, 221, 224. (Back)
    234. +
    235. Bloch, The Historian's Craft, 54-68. (Back)
    236. +
    237. Bloch, The Historian's Craft, 27-28. (Back)
    238. +
    239. Bloch, The Historian's Craft, 28. (Back)
    240. +
    241. Bloch, The Historian's Craft, 31. (Back)
    242. +
    243. Bloch, The Historian's Craft, 32. (Back)
    244. +
    245. Bloch, The Historian's Craft, 33-34. (Back)
    246. +
    247. Bloch, The Historian's Craft, 177, 183. (Back)
    248. +
    249. Bloch, Feudal Society, xvi. (Back)
    250. +
    251. Bloch, Feudal Society, 60. (Back)
    252. +
    253. 關於歷史中的過去與現在之概念,勒高夫從心理學、人類學、歷史意識與觀念史的角度提出了一個概略地說明。參見 : Jacques Le Goff, History and Memory, trans. Steven Rendall and Elizabeth Claman (New York: Columbia University Press, 1992), 1-19. (Back)
    254. +
    255. Bloch, The Historian's Craft, 40-42. (Back)
    256. +
    257. Bloch, The Historian's Craft, 45; Bloch, French Rural History, xxvi. (Back)
    258. +
    259. Bloch, The Historian's Craft, 46. (Back)
    260. +
    261. Bloch, French Rural History, xxvi. (Back)
    262. +
    263. Bloch, French Rural History, xxvi-xxvii. (Back)
    264. +
    265. Bloch, French Rural History, xxviii. (Back)
    266. +
    267. Bloch, French Rural History, xxx. (Back)
    268. +
    269. Bloch, French Rural History, xxv. (Back)
    270. +
    271. Bloch, The Historian's Craft, 28. (Back)
    272. +
    273. Bloch, French Rural History, xxvi. (Back)
    274. +
    275. Bloch, French Rural History, 241. (Back)
    276. +
    277. Bloch, French Rural History, 245. (Back)
    278. +
    279. 例如:在論述法國農業系統一節當中,布洛克指出「我們有明顯的證據說明了這種類型的耕作方式從很早以前的時代就已經發明了、甚至是在史前時代田地被重複使用已經歷經好幾世紀了。」 ( 頁 45) ;又如在論及莊園制度的發展一節當中,布洛克運用語言學說明了莊園制度所具有的古代性質。由法國與歐洲的地名研究當中,顯示出莊園制度可追溯至凱薩時期治下的高盧。並肯定地說,中古世紀的莊園領主乃可說是高盧農村首領的後代 ( 頁 76) 。在討論 manse 之發展時,布洛克認為那不只是行政法規的人為創造物而已,它實際上乃淵遠流長、承襲自羅馬的習俗 ( 頁 156-157) 。參閱 : Bloch, French Rural History. (Back)
    280. +
    281. Bloch, The Historian's Craft, 182-183. (Back)
    282. +
    283. Bloch, The Historian's Craft, 183. (Back)
    284. +
    285. Bloch, The Historian's Craft, 184. (Back)
    286. +
    287. Bloch, The Historian's Craft, 113. (Back)
    288. +
    289. Bloch, The Historian's Craft, 184. 另外,著名的中古史家勒高夫在有關中古世紀所謂「商人時間」與「教會時間」之論述,即典型的是從社會群體的時間觀點來探討不同社群之間的時間觀,參見 : Jacques Le Goff, "Merchant's Time and Church's Time in the Middle Ages," in Time, Work, & Culture in the Middle Ages, trans. Arthur Goldhammer (Chicago: The University of Chicago Press, 1980), 29-42. (Back)
    290. +
    291. Bloch, The Historian's Craft, 40. (Back)
    292. +
    293. Bloch, The Historian's Craft, 39. (Back)
    294. +
    295. Bloch, The Historian's Craft, 189. (Back)
    296. +
    297. Bloch, The Historian's Craft, 156. (Back)
    298. +
    299. Carole Fink 歸結出布洛克在歷史思想上的主要特色與概念分別為 : 心態 (mentalites) 、歷史實體 (historical reality) 、歷史決定論 (historical determinism) 、長時段 (longue duree) 、綜合的需求 (quest for synthesis) 等,參見 : Fink, "Introduction: Marc Bloch and World War I," Memoirs of War: 1914-15, 15-73; 有關布勞岱爾較為系統的三時段的歷史時間觀之論述,可參閱︰ Fernand Braduel, "History and the Social Sciences: The Longue Duree," in On History, trans. Sarah Matthews (Chicago: The University of Chicago Press, 1980), 25-54; Fernand Braudel, "Personal Testimony," Journal of Modern History 4(Dec. 1972): 448-467. 事實上,年鑑學派的主要特色之一也就是其長時段的歷史時間觀念,強調人之時間的相對性與多層次,如布洛克、布勞岱爾、勒高夫等史家都反應了此一特色,參閱 Iggers, Historiography in the Twentieth Century, 51 ﹔周樑楷,《近代歐洲史家及史學思想》 , 215-216; 魏楓城,〈年鑑史家的長時間觀︰以布洛克、布勞岱爾、雷瓦羅德里三人為討論對象〉,中興大學歷史學研究所,碩士論文, 1995 。 (Back)
    300. +
    301. Bloch, Feudal Society, xviii. (Back)
    302. +
    303. Bloch, Feudal Society, 60. (Back)
    304. +
    305. Bloch, French Rural History, 248. (Back)
    306. +
    307. Bloch, French Rural History, esp. chapter 5, 6. (Back)
    308. +
    309. Michel Vovelle, Ideologies and Mentalities, trans. Eamon O'Flaberty (Chicago: The University Press, 1990), 8. (Back)
    310. +
    311. Bloch, The Royal Touch, 110, 112, 114. (Back)
    312. +
    313. Bloch, The Historian's Craft, 17. (Back)
    314. +
    315. Bloch, The Historian's Craft, 65. (Back)
    316. +
    317. Bloch, The Historian's Craft, 66. (Back)
    318. +
    319. Adrian Wilson ed., Rethinking Social History: English Society 1570-1920 and its Interpretation (Manchester: Manchester University Press, 1993), 306. (Back)
    320. +
    321. Friedman, Marc Bloch, Sociology and Geography, 144. (Back)
    322. +
    323. Lyon, "Foreword," in Bloch, French Rural History, xiii. (Back)
    324. +
    325. Bloch, French Rural History, xv; Duby, History Continue, 4, 6, 10; Burke, The French Historical Revolution, 27; Robert Davergne 在 1956 出版了此書的增補篇,此一增補主要依據布洛克 1931-1944 後續的相關主題之研究成果與 1931-1956 期間其他學者之研究成果。另外,布洛克認為中世紀的經濟受到兩個長週期的主宰,其一是九到十三世紀之間的擴張,其二是十四到十五世紀之間的緊縮,這個「趨勢」已成為當時代經濟史學者的共識。而這個概念從 1940 年代起已被深入的探究,例如 W. Abel 研究農村荒漠化與危機的研究,以及喬治杜比 (Georges Duby) 1962 年的《農村經濟與鄉村生活》 (Rural Economy and Country Life in the Medieval West) 對這個問題的瞭解有相當大之貢獻,參閱 : Georges Duby, Rural Economy and Country Life in the Medieval West, trans. Cynthia Postan (Philadelphia: University of Pennsylvania Press, 1998). (Back)
    326. +
    327. Bloch, The Ile-de-France, 119. (Back)
    328. +
    329. Archambaut, "An Interview with Jacques Le Goff," 164; Le Goff, History and Memory, 201; Dosse, New History in France: The Triumph of the Annales, 55; 勒高夫在其〈新歷史〉一文當中指出:「要拿出『問題性』的歷史,而不是『自然顯現的歷史』。」參閱 Jacques Le Goff, 〈新歷史(上)〉,《食貨月刊》,梁其姿譯, 12 卷 10-11 期, 1983 , 429. (Back)
    330. +
    331. Barraclough, Main Trends in History, 170. (Back)
    332. +
    333. 本文原是布洛克於 1928 年八月於第六屆國際歷史學會議上所發表的一篇文章,名為 "Pour une histoire comparee des societes europeennes" 。後來此篇文章刊於《綜合歷史評論》 (Revue de synthese historique), 46(1928): 15-50 。這篇文章有兩個英文翻譯的版本 : Marc Bloch, "A Contribution towards a Comparative History of European Societies," in Land and Work In Medieval Europe, 44-81; "Toward a Comparative History of European Societies," trans. Jelle C. Risemersma, in Frederic C. Lane and Jelle C. Risemersma, eds., Enterprise and Secular Change: Reading in Economic History (Homewood, 1953), 494-521. 筆者在本論文中所採用的英文翻譯版本,以前者為主。 (Back)
    334. +
    335. Bloch, "A Contribution towards a Comparative History of European Societies," 44. (Back)
    336. +
    337. Bloch, "A Contribution towards a Comparative History of European Societies," 77. 布洛克自言受到受到亨力皮巒、亨力貝爾與歷史比較語言學家梅耶 (Antoine Millet, 1866-1936) 等人之影響。另外,筆者則認為,布洛克在某種程度上可能也受到了古朗士的影響,因為在《希臘羅馬古代社會史》當中,古朗士也運用了比較方法,參閱 : N. D. Fustel de Coulanges ,《希臘羅馬古代社會史》,李宗侗譯 ( 台北:中國文化大學出版部, 1988) 。 (Back)
    338. +
    339. Bloch, "A Contribution towards a Comparative History of European Societies," 45. (Back)
    340. +
    341. Bloch, "A Contribution towards a Comparative History of European Societies," 45-48. 由於受到歷史比較語言學家梅耶的啟發,布洛克從歷史家的觀點出發,基於兩種不同的思想歷程,可將比較方法區分成兩種類型。 (Back)
    342. +
    343. Bloch, "A Contribution towards a Comparative History of European Societies," 48, 67, 72; Bloch, The Historian's Craft, 110-116. (Back)
    344. +
    345. Bloch, Royal Touch, 220-221, 223, 228. (Back)
    346. +
    347. Bloch, "A Contribution towards a Comparative History of European Societies," 52-54. (Back)
    348. +
    349. Bloch, The Historian's Craft, 10. (Back)
    350. +
    351. Bloch, "A Contribution towards a Comparative History of European Societies," 68-69. (Back)
    352. +
    353. Bloch, "A Contribution towards a Comparative History of European Societies," 58. (Back)
    354. +
    355. Bloch, "A Contribution towards a Comparative History of European Societies," 45. (Back)
    356. +
    357. Bloch, "A Contribution towards a Comparative History of European Societies," 70-71. (Back)
    358. +
    359. Bloch, "A Contribution towards a Comparative History of European Societies," 54. (Back)
    360. +
    361. William H. Sewell, "Marc Bloch and the Logic of Comparative History," History and Theory 6(1967): 206-18. 西威爾認為布洛克比較方法的意義,在於它提供了一種「解釋」的工具,其功能在於「發現不同社群間的獨特性」、「假設問題之檢驗」或「形成歷史研究的問題」。有關布洛克比較方法之意義,也可參閱 : Lawrence D. Walker, "A Note on Historical Linguist and Marc Bloch's Comparative Method," History and Theory 19(1980): 154-164; Allette Olin Hill and Boyd H. Hill, "Marc Bloch and Comparative History," American Historical Review, 4(Oct. 1980): 828-857. (Back)
    362. +
    363. Bloch, Feudal Society, 176-189. (Back)
    364. +
    365. Bloch, Feudal Society, 447. (Back)
    366. +
    367. Walker, "A Note on Historical Linguist and Marc Bloch's Comparative Method," 161; Lawrence D. Walker, "Review of Feudal Society," History and Theory 1(1964), 251. (Back)
    368. +
    369. Barraclough, Main Trends in History, 170. (Back)
    370. +
    371. Bloch, French Rural History, xxiv. (Back)
    372. +
    373. Bloch, French Rural History, xxiv. (Back)
    374. +
    375. Bloch, French Rural History, 13-14. 其他例子例舉一二:在探討法國與歐洲的農業活動、耕作技術時,指出其與近東地區的差異性 ( 頁 24) ;在「農業系統︰開放與長形田地」一節的結論,提醒大家要把此一類型的法國農業文明放置在整個歐洲脈絡中討論,他並由此獲得法國此一類型農業文明的特殊性 ( 頁 48) 。 (Back)
    376. +
    377. Iggers, New Directions in European Historiography, 43-44. (Back)
    378. +
    379. Bloch, The Royal Touch, 5. 根據筆者的整理,從下述若干列舉較重要之地方,概可觀察布洛克使用比較方法的例子。較重要的如 : Bloch, The Royal Touch, 19, 30, 36, 53, 56, 65, 81, 220. 這裡必須說明的是,第一種的比較方式在書中也曾用過,如頁 28 與「玻里尼西亞」人 (Polynesian) 的比較。 (Back)
    380. +
    381. Bloch, The Historian's Craft, 42. (Back)
    382. +
    +
    + +
    + 回目錄 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/003/article02.html.html b/htdocs/htc/newsletters/003/article02.html.html new file mode 120000 index 0000000..fad4a1e --- /dev/null +++ b/htdocs/htc/newsletters/003/article02.html.html @@ -0,0 +1 @@ +article02.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/003/article02.html.xhtml b/htdocs/htc/newsletters/003/article02.html.xhtml new file mode 100644 index 0000000..63b6ddf --- /dev/null +++ b/htdocs/htc/newsletters/003/article02.html.xhtml @@ -0,0 +1,316 @@ + + + + + + + + + + + + + + + + + + + + +周樑楷教授訪談錄 + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    周樑楷教授訪談錄

    + +
    徐文路 整理
    + +
    +

    編者按:本刊為探求國內西洋史學者學思過程,先後於 1999 年 4 月 24 日與 2000 年 7 月 15 日先後兩次與周樑楷教授進行訪談,參加訪談者有陳思仁、吳燕秋、黃明田、徐文路、潘宗億,現將訪談紀錄整理如下以饗讀者。

    +
    + +
    +

    陳:能否談談老師的求學經歷?

    +
    +
    +

    周:你要我從什麼時候講起……?

    +
    +
    +

    黃:例如從你開始對歷史、西洋史的研究講起。

    +
    +
    +

    周:嗯,是這樣,從進大學開始講起,大學進了輔大歷史系,剛開始大一、大二時,讀書東抓一點、西抓一點的讀書,也沒有什麼方向,不過隱約已感覺到喜歡與哲學、思想史有關的。大二升大三那年暑假,一邊讀書一邊反省自己興趣所在,於是決定假設要走歷史這條路,就以研究史學史、史學思想為主。因此,我在日記上寫著,並加強語氣說:「這輩子要是讀歷史,就要讀史學史、史學思想;假設不讀史學史、史學思想,就不讀歷史系。」從此就這樣走下來。大三、大四時,比較集中閱讀這方面書籍,當然因為語文閱讀的方便,當時候接觸中國史學史較多些,如《史通》、《文史通義》都閱讀一遍,還有如《通鑑》、《史記》等也接觸了一點。……你去查閱《史苑雜誌》,我有一篇寫史通的文章,及一篇關於歐陽修的《新五代史》,這是當時閱讀中國古書的緣故。不過,當時也面臨考研究所的問題,而我心理想,若要走這條路,即使要做中國史學,也應該懂得西方史學,剛好我在輔大求學,所以選擇了輔大歷史研究所。那時候,大學畢業後都先當兵,且必然是當預官,我在陸軍官校擔任教官,考上了研究所可保留學籍,沒憂慮。擔任教官,一個禮拜只教六小時的課,所以那年非常輕鬆,所閱讀的基礎科學和科學哲學的書籍。後來回到輔大,三年時間,專心在史學史,但是,當時並沒有專攻西洋史學史的老師,而且外交書就那麼幾本。後來擬定碩士論文題目時,就想寫某一位本身也是研究史學史的史家,如此研究他也可以讀史學史的書,這就是我研究巴特費爾 (Herbert Butterfield) 的原因。他寫史學史,當然也寫外交史。輔大畢業後,運氣很好,到中興大學教書,教西洋史,隔三年就開西洋史學史的課,如此一路下來。我每年至少有一篇文章,寫西洋史學思想的文章。在中興教書、經過六年之後就出國,出國是拿國科會的錢,由於是公費,因此,申請學校,就有較多的選擇,很多人建議選擇名校,可是有一位老師建議找名師,後來我決定選擇名師,因為到名校不一定有自己喜歡的領域,也未必能學得很順暢。由於當時對伊格斯 (Georg Iggers) 的著作已有接觸,也知道他在水牛城紐約州立大學,所以就到了此校唸書。伊格斯這人不僅學問好,待人也很好,而我也這樣子待下來。這是在 1980 年代初期的時候。

    +
    +
    +

    陳:周老師常常談在美國求學的經驗,是否可以談談這部份的轉變。

    +
    +
    +

    周:當然,每個人的思想都會因讀書歷程而改變。出國後,前三年在修課, 1983 年學科考試,由於準備考試,有機會反芻過去閱讀的書,才知道自己對左派和馬克斯主義史學有些瞭解。我們在臺灣做思想史,往往比較偏向觀念史取向,到目前為止,臺灣這種味道仍然是很重,我自己在出國之前也是如此。觀念史取向某個程度而言是右派的,當然不是極右的,也有自由主義思想的右派。不過 1980 年代在美國唸書,自己已感覺到受到左派的影響,尤其是湯姆遜 (E. P. Thompson) ,這是一個很大的轉變,包括思考方式有了轉變。學科考完之後,回到中興教書,時間是 83-86 年。教書期間,也花時間閱讀中國思想、史學史的書,其實我一直都在接觸中國的東西,雖然沒寫文章,但還不致於與中國史脫節。那三年期間,我常請教中興中文系一位教授(雖然未教過我,但我一直尊他為老師),有時聊天到夜晚一、兩點,他是專研老莊,對中國思想頗有研究,非常有智慧的人,我也頗受他影響。記得在 86 年,我自己又有很大的轉變,某種程度上,對中國學術思想有很不同的認識。可以這樣說, 83 年我相當受西方馬克斯主義的影響, 86 年又受中國思想的影響,因此就在中國、西方間互動中思考問題,尤其是史學思想的問題。 86 那一年,我自己在思想上有很大的轉折。譬如,在《歷史學的思維》 ( 正中書局, 1996) 這本書最後一章,有我對於研究歷史意義的心得,我說:「治史的意義,在於歷史意識、社會意識和生命意識的不斷錘鍊和昇揚。」這句話是在 86 年的某個晚上想出來的。 86 年 8 月又拿了公費出國,這回不用修課,很輕鬆,純粹為了寫論文。我的博士論文是談英國左派史家,共有十位史家,其中八位,是夫妻檔,都是左派。

    +

    等到論文快寫完時,自己也快中年了。當時自己想著,中年後的學術工作千萬不能重複自己,原地踏步,因此,想找個陌生的領域來閱讀、接觸,希望透過陌生的領域來獲得新的生命泉源,並刺激原有的史學思想。當時人在美國,我對音樂一向笨拙,只能當作賞心悅目、消遣的事物,於是刻意留心爵士樂,注重大眾文化。逐漸地自己喜歡上了爵士樂。後來,又注意到電影,覺得這領域也滿又意思,並想起電影與歷史的關係,於是決定將爵士樂暫擱一邊,專做電影。很巧的是, 89 年暑假回臺灣時, 1988 年 12 月的 AHR (American Historical Review) ,有一專輯談論有關影視史學,因此後來談影視史學與此關係。不過,我並非純粹為了影視(電影)而講史學,而是擴充自己陌生的領域,從其中吸收更多東西,其實仍在思考史學本身的問題,也就是說,「君子固本」,將根伸展而外,從外部吸收養份。因此,這如同我自大三起就一直想的兩個問題:歷史是什麼,即歷史的定義是什麼?歷史的意義是什麼?《歷史學的思維》,就是扣緊這兩個問題而寫的。我替歷史下定義,也把我對學歷史的意義講出來。所以八○年代出國後我自己很明顯的有幾次的調整。

    +
    +
    +

    陳:關於影視史學,我們可以看到周老師曾在臺灣為此辦過研討會,能否談談你對目前臺灣有關影視史學的研究成果的想法?

    +
    +
    +

    周:目前的成果很有限。第一,當初我做影視史學時,我最關心的是要使它成為一門學問。影視史學既不是電影史,也不是談如何用影視媒體來教學。影視史學可以談電影史、談教學,但是影視史學本身是應該是一門學問。要使它成學問,就必須有自己的知識論,說實在,目前影視史學這門學問的知識基礎尚不是很穩固,因此,我對影視史學的關心,乃是要從知識論的基礎,使之成為一門學問。其實我從大三做史學史時,都是從知識論出發點,我對影視史學的關心點也在此。我自 89 年開始做起,自今略有一點東西出來,可是,距離成為一門學問仍覺尚早;即使西方也一樣,真正從知識論談影視史學的並不多。

    +

    第二,當我們談論影視史學時,我講的並不只是電影、電視與歷史,而是講影像視覺的歷史文本,及其中的思想問題,除此之外,非專業史家的歷史文本,口語的、文字的、圖像的、包括靜態的任何圖像的歷史文本,都是值得研究,所以文字的歷史文本,歷史小說也是。我指導陳思仁研究史考特 (Walter Scott) 的歷史小說,就是將歷史小說當文本來研究史學思想。

    +

    假設要問影響的話,例如輔大有兩位寫歷史小說家的史學思想,目前中興也有兩位研究生研究與影像、圖像有關的論文,這是研究生部份。去年在中興大學舉辦有關影視史學的研討會,是教育部主動委託辦理,這起碼說明臺灣學術界初步肯定它的存在。聽說今年清華史研所入學考試考了一題有關電影的題目,人家以為我出的,其實不是(一笑)。但這表示電影也可以成為考題了。因此,這一切都須要大家一起來做。

    +

    基本上,我不只接觸不同媒體的歷史文化,同時也注意史學史除了處理菁英份子之外,非菁英的、大眾的文化也是值得研究。所以,影視史學史一門課,一方面可以放在史學史的學程來思考,另方面也可以放在大眾文化的學程來思考。談影視史學若能與大眾文化結合,如此,關心的對象與寫作的目的就可以和社會現實連結在一起。

    +
    +
    +

    吳:麥田出版社分別出過兩本有關西方史家評論電影的史學觀點,或許也可算是目前影視史學在臺灣的發展現況之一。那麼目前美國在這方面的發展是如何?

    +
    +
    +

    周:年鑑史家費侯 (Marc Ferro) 所寫的《電影與歷史》,我很喜歡,書中真的涉及到方法論與知識論的層次;另一本《幻想與真像》,較為普通。

    +
    +
    +

    吳:即是那本集結很多史家意見?

    +
    +
    +

    周:是,《幻想與真像》,僅討論電影內容與真實間的差異,沒有太大的理論基礎,只是比較而已,並非很特別的關於影視史學的好書。

    +

    美國其實有好幾個關於電影 (Film) 與歷史的學會成立,也有好幾個學校成立電影與歷史的研究中心 (Center) ,有專業史家投入此行列; AHR 在這十幾年以來經常有討論影視史學的文章或影評;此外, AHR 每月的《 Perspective 》也經常有影視與歷史或影視教學的文章。美國對這方面的研究,已形成學術社群 (community) 。

    +
    +
    +

    黃:歷史表達的方式,有說故事方式的歷史敘述,和強調分析式的敘述,和現今影視的方式。能否針對這三種不同媒介,說明其對於現代歷史在教學、或私交社群可能會產生什麼歷史意識?

    +
    +
    +

    周:西方到十九世紀才有所謂專業化史家,也就是強調專業化訓練。他們以資料的收集、考證為入手,以專題論文、專書的方式來寫作,並形成社群,大學歷史系主要是在十九世紀才有。歷史系培養專業史家,畢業後就在研究機構做研究或大學教書,可見所謂科學派或專業史家的成立,其「行規」是在十九世紀的歐洲才開始的。當社群成立後,形成內聚力,但相對的,也產生排斥的心態,將非我族類當成 " 他者 " (other) 來處理,所以有兩類作品被排斥:一種是自希羅多德 (Herodotus) 到吉朋 (Edward Gibbon) 等以來的史家,他們都有很好的史學作品,雖然他們的敘述方式不再是被學習的對象,但仍有其地位,所以被稱為業餘的史家,肯定他們的地位,但被視為 "Other" 。另一種是把史詩、歷史劇與歷史小說等也當成 "Other" ,那一種 "Other" 呢?即歸為文學類,雖然這些文本牽涉到歷史,但是已不配當成是史學的範圍了。

    +

    第二種 "Other" 離專業史學更遠了,所以我們講史學史會提希羅多德或吉朋,但不會提莎士比亞或史考特,不只這樣,不只這些文字、書寫的史詩、歷史小說、歷史劇或劇本等被當成 "Other" 來處理,同樣的,過去的 oral tradition( 口傳歷史 ) 也被當成 "Other" ,頂多當成史料,而不是正式的歷史的文本。圖像的文本也被如此看待。總之,有一類被當成業餘史家,另一類則根本不是歷史。這種情形,在十九世紀末二十世紀初有一場論戰,即崔衛林與柏理 (J .B. Bury) 等人的論戰,英國崔衛林 (George Macaulay Trevelyan) 想替傳統的業餘史家講話,但卻敵不過學院派史家。

    +

    傳統敘述式的史學,假始稱它為 Clio( 歷史女神 ) ,祂在十九世紀末死掉了。但有趣的是, 1895 年電影誕生的時候,有紀錄片與歷史有關,所以我喜歡說這是「 Clio 的轉世投胎」, Clio 在書寫的文本中失去地位,但轉投胎為 Flim 、影像媒體。但是, Clio 剛開始沒有地位,學院派不重視祂。到了 1960 年代,社會運動時代,大眾文化被重視,專業史家也開始注重影像的東西,如年鑑史家費侯,他的文章大概在 1960-70 年代寫成的。當時有些人不約而同的,開始注重大眾文化,包括影像。這三、四十年來 ( 從 1960 年代開始 ) ,非專業史家或非專業的歷史作品日漸有地位,所以電影、 oral tradition 、圖像等通通拿來重新檢驗。我們無意否定專業史家,更不可能把文字書寫的歷史否定,而是應促使歷史研究以及呈現方式更多元化。如弱勢團體未受專業史家訓練,但他們有自己的聲音講他們的歷史,不管是用什麼媒體表達。當然弱勢團體所講的未必是對的,但應讓他們有聲音出來。所以可以說,應愈來愈 open 、 liberal 。影視史學實際上就是代表這幾年更多元化、更開放化的一個社會的取向。

    +

    我們現在重視大眾文化,背後有一個不同的理論基礎、不同的社會觀點,與過去是不一樣。

    +
    +
    +

    陳:如此說來,專業化史學仍以文字書寫、文字敘述為主?

    +
    +
    +

    周:對,專業史家基本上以大量的文字資料為主,以文字書寫來呈現,與剛剛所提的是不一樣。不過,你會發現,這三十幾年以來有些專業史家,除了專業的作法之外,也用另外的時間、另外不同的作品,和用別的方式來展現他的歷史作品。例如,一方面專業的史家寫專業的著作,文章發表在專業的刊物上;但他另一方面也在積極拍電影,拍紀錄片,等於一個人有兩種不同角色。專業史家也可能在專業作品中容納更多圖像,但不失專業性的處理方式。可見這三十幾年來,專業史家本身也有所調整。

    +
    +
    +

    陳:周老師也從事教科書的編輯,能否談談老師參與的情況,以及期望透過教科書傳達什麼訊息?

    +
    +
    +

    周:關於參與教科書,撇開背後的動機 ( 如對於歷史教育的關心 ) 不談,純粹就學理上來講,其實歷史教科書也是歷史文本。從小學、中學到大學的歷史教科書都是歷史文本,而且這種歷史文本有更多的讀者。我因關心歷史文本不只是傳統式的、菁英史家的作品,我也注意各種形式的歷史文本,所以歷史教科書也變成我的興趣之一,這是第一個理由,等於是把歷史教科書放在廣義的史學史來思考、處理。第二個理由,既然投入書寫教科書,不僅要研究它,還想如何參與、改進臺灣現有的歷史教科書,套用馬克思主義的觀念,我不僅將教科書當成客觀的研究對象,也將自己與教科書之間的互動、實踐關係考慮在其中。我對小學教育、鄉土教育到國中、高中的歷史教育都參與、接觸,目的就是實踐與互動的關係,因為接觸愈多,就愈瞭解,瞭解之後就會修正我自己的史學理論。不能空論,我們要實踐、要落實,這是辯證的過程。第二個理由即在此,不能光說,要去做。

    +
    +
    +

    陳:那溝通狀況如何?

    +
    +
    +

    周:講來是很瑣碎,……今日暫且不談。我常講人人是史家,不是狹義的意思,即人人都有自己的歷史思維,所以很多很多的符號、圖像、文本,都跟歷史有關係,都可以找到歷史文化,這些都是我有興趣去探討研究的。我現在把史學史的定義擴大,不只是領域的擴大,研究取向也調整。領域的擴大和研究取向的調整,兩者之間是不太相同的。

    +
    +
    +

    陳:能否具體的說明?

    +
    +
    +

    周:例如,上史學史課時,我將莎士比亞的歷史劇,或各種歷史小說、電影等納入課程討論。此外,今年度開西洋史學史的課時,我的教法就與以前不太一樣,我先花一個月的時間講史學史的研究取向。這個題目看起來是在講有那些重要的研究取向,其實也在講我自己如何處理史學史的問題。我從幾個知識論的光譜來分析,並配合 concepts of man 來談 concepts of history 的關係。諸如此類都是我把史學史的定義擴展出去之後的結果。但是,要將領域擴展出去,理論的根基必要打得更結實,重新調整,做個比喻,原本是蓋個十層大樓,有十層樓地基,但現在不夠用,須要十二層大樓,十二層大樓並非在十層大樓上加蓋兩層違章建築,也非在大樓旁加蓋兩層房子,我的想法是把十層大樓打掉,重新奠定十二層的地基來蓋十二層大樓。

    +

    所以把「人人當做史家」,把「歷史的文本擴大範圍」之後,整個研究史學史的理論基礎都要翻修。翻修,並不是說過去完全錯的。我的意思是說,延伸出去之後,還得繼續思考「什麼是歷史」?「歷史的意義是什麼」?史學研究的地基就這個地方。所以我處理影視史學,不是因為電影好玩,更不是因電影本身,我最終關心的仍是史學思想本身的問題。

    +
    +
    +

    徐:您所寫的一些有關電影的文章,包括「辛德勒的名單」、「 The Return of Martin Guerre 」、「白宮風暴」等等,涉及電影色彩的運用和主角肢體語言的意涵。您似乎企圖從電影的符號系統中建構出一套意義系統。不知道老師在這方面是否已經有了具體的架構?

    +
    +
    +

    周:我們先回到十九世紀的專業化史家。他們以文字的、分析的方式,做為認知的史料和傳達的工具。我認為,史學的認知和傳達不只限於分析式的文字傳達而已,因此我把它擴張出去,包括所有影象視覺的符號,都可以當做史料和傳達的工具 ( 語音的東西也是 ) 。所以,到目前為止,所有史學方法的理論完全不夠用。以十九世紀的 Bernhiem 《史學方法論》那本書來看,他說明如何應用文字史料,如何用文字來排比、考証、分析、綜合起來。而且很有趣, Bernhiem 那本書最後一章是講「敘述」的問題,可是論頁數卻是那本書各章中最少的的,而且第一句話就說「敘述不重要」。所以我敢誇張一點說,這一百年來史學理論都沒有跳脫開以文字為基礎,不管是觀念論的、實証論的都是一樣。雖然有各家各派的說法,但是在我看來都是一樣的。但假使把影象、語音的史料納進來之後,原有的史學理論就不夠了。重構是個大工程,我這輩子也不能完成,但是我知道未來的史學理論必須處理這些問題。影視史學的名字出來了,但是 Hayden White 只寫一篇文章,此後就不碰這個東西了。當今的要務是要讓它成為一個學問,要有知識論的基礎,否則就只是輔助的角色。我寫電影的文章和寫傳統式的文章不一樣。舉例來說,寫傳統式的學術論文,像是請朋友吃飯一樣,先開好菜單,再到菜市場去買回來處理。寫電影的文章就不同,我到市場去,想買魚,但不一定要固定買什麼魚,只要是新鮮的、對時的就可以買,而後再決定怎麼做這道菜。我先看了什麼電影,再決定怎麼寫。最近看了「神鬼戰士」,我有新的寫法,我從不同的角度企圖建構知識論的基礎。以「辛」片為例,我心裡有底,一直想從顏色來談問題,正好「辛」片被我等到了。於是從顏色 ( 黑、白、紅 ) 讀歷史敘述。

    +
    +
    +

    徐:可是這是要有底子的,沒有經過一番摸索琢磨,他跟本不知怎煮魚,不知道要蒸還是煎。

    +
    +
    +

    周:沒錯。沒有史學史、史學思想底子的人,影視史學一定做不好。

    +
    +
    +

    徐:以討論「白宮風暴」(編者按:本篇尚未公開發表)的文章為例,論理的文字,在量上較以前為多,而且您似乎認為文字仍扮演重要的角色,並且似乎有著畫龍點睛的功用在。您在這篇文章中談到,導演奧利佛.史東以《馬太福音》的一句話作為開頭:「人縱使賺得了全世界,但是賠上了自己的靈魂,於他有什麼好處?」對他而言這句話似乎就是全片的中心思想。到底文字的地位是否就這麼不可動搖?

    +
    +
    +

    周:我從未說過文字不重要,而是強調文字、影像和語音三者要並重。其實這樣說還不夠準確,應該要以各個電影的各項比重來看,有的片子是語音,有的片子是影像或文字為主。在「白」片中,我想說的是,西方用影片、圖像敘述人物傳記的時候,他們要捕捉的東西是什麼。你會發現史東在這部片子所捕捉的,仍然是 Plutarch 的精神,只是以圖像來表現。

    +
    +
    +

    陳:所以儘管現在用影視資料來研究史學,還是得回到文字的脈絡和傳統上。

    +
    +
    +

    周:有的。像他講尼克森,其實跟 Plutarch 寫《希臘羅馬名人傳》的方式,有相同的地方。

    +
    +
    +

    陳:在「辛」片一文,老師談到白人「新保守主義」的問題。在現代好萊塢的電影工業資本的主導情況下,我們如何擁有獨立自主的批判能力?

    +
    +
    +

    周:讀史學史的人,不能只在史學史、史學理論的領域打滾,而要多接觸其它學科,以及相關的歷史背景。當然不可能全面接觸。比如何妳閱讀 Walter Scott 的小說,也要了解當時蘇格蘭的歷史背景。以「神」片而言,它虛構得很厲害。但是虛構多少不是我們的重點。很多人談影視史學時,一再以指出有那些虛構為宗旨,這不是好的取向。我認為,虛構不見得是壞事,莎士比亞的歷史劇也虛構得很厲害,那不是問題。我們看「神」片要看他為什麼虛構、如何虛構。如果我們拿 1963 年蘇菲亞羅蘭主演的「羅馬帝國淪亡錄」來比較,兩部片子都是講羅馬衰亡的事,即西元 180 年時代的事,細節當然不一樣。看「神」那部片,不懂歷史的人不知道,此時(奧理略皇帝統治時期)正是羅馬帝國走向衰亡的時候,繼位者好像還不錯,羅馬似乎走向一個新時代。可是如果看「羅」片,你會清楚感受到,王位沒有傳給那個優秀的大將,而被那個糟糕的親生兒子拿去,象徵著羅馬帝國衰亡的開始。為什麼 1960 年代要拍「羅」片?那時越戰即將開始,甘迺迪剛被暗殺,不安的氣氛在美國已經感受到了。「神」片是美國現在獨大的時候。從 1960 年代初期到 1980 年代,美國的專業史家都有一股帝國將衰的情緒。 1976 年,美國很多史家並非歡慶建國兩百週年,他們反而想到了 1776 年吉朋的《羅馬帝國衰亡史》。不僅如此,他們還聯想到 476 年西羅馬的滅亡。還有,在 1988 、 1989 年時美國還有一本暢銷書叫 The Decline and Fall of the Great Power ,中文翻譯是《強權的興衰》。書中對美國的未來表現出憂慮。杭廷頓 (Samuel P. Huntington) 認為 1950 到 1980 年代,美國有五波認為自己會走向衰亡的浪潮,我認為 1960 到 1980 年代,表現得很清楚。不論是越戰或是 80 年代的經濟衰退,都影響這個心理。可是,沒想到 90 年代蘇聯垮台了,柯林頓政府也不是大有為的政府,美國經濟卻不斷好轉。美國神氣得一蹋糊塗。 1997 年時,美國《時代雜誌》就在反省美國太驕傲了,有一幅畫描寫柯林頓是個超人,手裡拿著一顆地球。第一點,從美國史看美國史家觀看世界的角度,我們可以從電影來分析。第二點,「神」片強調要維護共和國傳統,美國開國是推翻專政,他們一直想要接續羅馬的共和傳統。羅馬時代有一個人擔任將軍,戰勝後人家要他繼續擔任,他拒絕了,而回去當農人(地主而非農奴)。華盛頓就是以他為榜樣自居,後來不當總統。「神」片中的主角,人家要他當將軍他不幹,一心一意要回西班牙當農人。這部片子是把羅馬共和與美國立國精神連在一起講問題。從 1950 年以來,美國拍了很多羅馬時代的片子,一種是以羅馬為背景,講基督教問題,比如「十誡」等。另一種是羅馬歷史的片子。美國很久沒有以羅馬為主題的片子了,我就是看他們會怎麼拍這部片子。「萬夫莫敵」是在講奴隸問題,拍攝於 1950 年代。當時美國黑人的問題也漸漸興起,這部片子是同情奴隸的。所以任何專業、非專史家,看歷史時都是和現實互動的。法國年鑑史家費羅的那本書(編者按:指《電影與歷史》一書,麥田出版社, 1998 )寫得很好,可以參考。如果憑空做理論,我是反對的。台灣現在研究史學史、史學理論,容易偏向理論層次,對於史實的了解比較薄一點。

    +
    +
    +

    黃:老師講到的三種意識的結合,似乎在電影的討論上,只偏重歷史意識和社會意識,生命意識較沒有碰觸到?

    +
    +
    +

    周:這部分的確沒有深入。一個作品本身不見得都會有碰到這部分。

    +
    +
    +

    黃:是否因為老師的思想背景,跟美國的資本主義產生排擠,所以沒注意到?

    +
    +
    +

    周:倒不是這個問題。如果深入來談「神」片,這就牽涉到「國史論述」的問題。十九世紀專業化史家發展的時候,正是國家主義、民族主義的興盛時期。他們把史學當成工具,所以早期的史學都跟國家主義、民族主義有關。近代史學建立和形成的時候,都是在「國史論述」的範圍裏。斷代史也在「國史」的範圍裏。可是這些年,「國史論述」也在鬆動,一方面走向全球化 (globalization) ,一方面走向地方化 (localization) ,這兩者有關連,同時都鬆動「國史論述」。比如外交史,從前都是談國與國的關係。然而今天的外交,不只國跟國的關係,網路根本就無國界了,都是全球化的問題,經濟問題也是一樣。跨國公司把工廠設在勞工最廉價、稅最輕的地方。以國家為單位的歷史已經不適用了,至少應以一個區域來看,比如說亞太地區。另一方面是地方史的問題。我反對「同心圓」的說法,原因就在於地方史跟全球史有關,全球史也跟地方史有關,何來同心圓呢?現在不一樣了。以前的中國史研究,傅斯年研究上古史,陳寅恪就從漢一直到安史之亂,姚從吾就做遼金元明史。這三個留德學生,等於是把一條魚分成三部分來吃,是在「國史論述」裏看問題。錢穆更清楚,書名就叫《國史大綱》。近二十年來由於資本主義更加發展,「國史論述」就更成為問題了。

    +
    +
    +

    徐:現在似乎很多學科都在談全球化的問題。

    +
    +
    +

    周:我明年計劃開一門有關全球化的課,談全球化這個思想發展和演變。從西方中世紀的 universal history ,到現在的 world history 。

    +
    +
    +

    徐:這會不會是美國全球霸權的另一種思潮,像「神」片一樣?

    +
    +
    +

    周:我不講這個,目前的架構已經太大了。不過沒有錯,美國就是以羅馬帝國為仿傚的對象。

    +
    +
    +

    陳:我們都知道,這幾年老師也寫有關於世界史的文章,能否談談你對於所謂「以臺灣為主題」的世界史觀?

    +
    +
    +

    周:這題目很大,……其實我們現在要擺脫所謂歐洲中心論、擺脫任何中心論,這理論臺灣現在都在講,高唱著,但講多了就變成口號。我教世界通史,投入非常多的,而且每年都在修訂我的架構。我們身在臺灣,又即將進入二十一世紀,但談問題不是以臺灣為中心,然後劃三個圈圈擴展出去,而應是以當下來思考世界史觀。若要問我那是什麼,你參考我的世界史教科書綱要就知道,我已有初步的構想,但還不夠成熟。但寫高中教科書的時候,必然會把我的世界觀放在教科書上,那是必然的、正常的。參考教科書就知道我的世界史觀。

    +
    +
    +

    陳:所以那本教書也是老師傳達意識的文本。

    +
    +
    +

    周:對,那沒錯。將來要給人家批判的。(一笑)

    +
    +
    +

    徐:老師寫的《歷史學的思維》,很多史學的問題在這本書中具體而微地呈現出來。那本書裡面,我印象最深刻的一句話就是「歷史就是歷史意識、社會意識和生命意識不斷的錘鍊和昇揚」,這個部分老師能不能多做說明?

    +
    +
    +

    周:我們在讀所謂的史學理論的書籍,大都只是從史學的理論和研究來思考問題;可是,所謂的史學家或專業史家,他也是一個人,會隨著年齡的成長而變化。你要做好歷史研究的學問,其實要充實的部分不是只有史學理論。一個人好比一棵樹,樹根要吸取很多營養,要成為一個專業史家,根要伸張出去,要吸取許多不同的養分。一般大學都在培養史學觀念、史學方法的東西。要成為一個成熟的史家,大概要到四十歲以後。以你們現在的年紀,二、三十歲,成長時要吸取養分,但不可以只有一條根,只吸收史學的養份。而應對社會思想和社會意識多所接觸。另外就是關於個人生命,包括道德問題、價值問題,都會牽涉到,這也是一條根,一個養分。我的意思就是說,要培養一個好的史家,大概要到四十多歲以後,大學的課程著重在史學理論和方法的培養,是不夠的,我們要懂得自己成長。從多方面吸收養分。歷史意識、社會意識和生命意識,不是絕對分開的,其實是互相互動、關連的。學歷史的人,大學時代不妨就應該讓這三方面動起來。

    +
    +
    +

    徐:這是否也可以說是史家的歷史角色、社會角色和個人角色?

    +
    +
    +

    周:這方面我很少跟別人提起。要了解這句話,要從馬克思的、儒家的,甚至是加上老莊的、佛家的想法在裏面。先從儒家和馬克思講起。儒家當然可以上溯到孔子,但我們從章學誠說起,因為他是中國最後一位沒有受過西方思想衝擊的史家。所謂衝擊( impact 而非 influence ),不管對西方的態度是接受或是反對,都算是衝擊。錢穆是反對西方的,但是他也受到西方的衝擊才有這樣的態度。章學誠的東西其實是道地的儒家思想。儒家的觀念對於中國傳統史學的影響,這個問題當然很複雜,但是最核心的就是 the concept of man 的看法。儒家強調,人類與禽獸之別幾稀矣,差別就在「人類有一個自主性的道德心」。儒家用這點來解釋人之所以為人,同時也用這一點來解釋歷史。中國傳統史學中的 concept of history ,背後與儒家的 concept of man 有必然的關係在。章學誠的思想可以從這方面來解釋。其次,儒家和章學誠都強調經世致用,有濃厚的社會意識,關懷現實,左派還是右派先暫時不談。我受馬克思的影響,我認為儒家和馬克思的思想中有一個共通點,就是強調:研究的主體和被認識的客體之間是互動的、辯証的。馬克思所講的「異化」問題,就是關心人的自主性之發展。儒家也重視這個,在這方面是相通的。

    +
    +
    +

    徐:老莊在這方面似乎比較可以跟異化的問題相通,可是儒家……?

    +
    +
    +

    周:孟子講「性善」,是說人生來就有這個性質,人要去培養它,這樣才會異於禽獸。所謂「自主的道德心」,用孔子的說法就是「仁」,用孟子的說法就是「性善」.用王陽明講的就是「良知良能」,章學誠的「史德」就是這個東西。認知的主體同時也是實踐的主體,純粹就這點來講,馬克思和儒家的思想是可以會通的,他們最後都肯定人的主體性。馬克思的思想和孔孟思想當然有很多不一樣,不過不是我談的重點。其次,老子和道家的思想又如何跟馬克思有關呢?如果你觀察馬克思、 E. P. Thompson 和 E. J. Hobsbawm ,會發現他們背後都有一個共同的史觀。那套史觀卻被共產國家教條化了,變成了經濟決定論,歷史變成了五個階段說,這些都是錯的。馬克思的觀念應靈活地運用來觀察這個世界,這是 E. P. Thompson 寫 Poverty of Theory 這本書的意思之所在。他說馬克思所講的所謂「理論」,並非是一般的理論,一般我們所說的理論是指社會學那樣的理論,馬克思本人是反對那樣的理論,或者說,他想超越那種理論。 Thompson 和 Hobsbawm 也是反對這樣的理論,可是並不是表示他們背後就沒有一套自己的思考方法。思考方法是什麼東西呢?老子的《道德經》第一句話:「道可道,非常道」,老子講了半天是那個不可講的「道」。而可道之「道」,就是一般所謂的理論,老子所要講的「道」是不可道的「道」。馬克思和 Thompson 等人所說的歷史的思考方法,不是那些呆板的理論可以說清楚的。這就是我想做的事情,把馬克思的思想和孔孟、老莊的思想在更高的層次上做會通。理解這一點,就可以注意到,我在講這些東西時,牽涉到知識論的層次、形上學的層次、倫理學的層次、政治社會的層次。所以一個史學家就是要把歷史意識、社會意識和生命意識不斷的互動,這互動就是辯証,就是實踐。馬克思、老莊、孔孟都講實踐。所謂「錘鍊」就是這三者在實踐中不斷互動,所謂「昇揚」就是說,這是一個很高遠的理想,永無止境,不斷提昇。

    +
    +
    +

    徐:縲旋上昇?

    +
    +
    +

    周:也不是縲旋上昇,要不著軌跡。如果用套用孔子的話,就是「自強不息」。他們對生命、對歷史的期望是有一個理想、有一個方向感的。這是就觀念性的層面來談這句話。當然,一個史家本來就是要常常做一些實証的工作,要爬梳史料,這是常識。

    +
    +
    +

    徐:從這裏我們進入第二個問題,即史學專業化的問題。專業化史學這個趨勢已經一百多年了,有其不得不然的因素,也有它的侷限性。該要如何解決或看待?強調敘述性是否為它的解決之道?老師這些年來從文史關係的問題到影視史學,似乎都是從同一個方向出發,可否為我們說明?

    +
    +
    +

    周:專業史學和專業化史家,可以分兩個階段兩講。第一個是十九世紀末到第二次世界大戰,第二個是二次大戰之後,尤其是戰後嬰兒潮大量進入學院之後。第一個時期的專業史家除了要把史學專業化之外,本身的文學素養、文字掌握的功力都很好。第二次大戰之後就不一樣了,大量的人進到博士班,表面上越來越專業了,可是所做的題目卻越來越小,人文的素養越來越貧乏。 1980 年代、 1990 年代以後,職業不好找,使得人人都目光如豆,人文涵養越不受重視。有感於此,專業化的史家越像「文化勞工」、高級勞工,那樣的生命狀態是跟自己疏離的,叫我當那樣的史家,我覺得不舒服。如果要賺錢,我還不如去作生意,因為我是商人子弟,當初讀史學,就是不想做生意。如果現在只是為了賺錢,我何必如此?我看到商人生活的缺點,所以想要過一個學者的生活。可是現在的學者,人人的生命跟自己疏離。他們評判一個學者的好壞,是用他發表文章的量來看,而且是知名的刊物,以此來論點數。這不僅是台灣,國外更是如此,受到自然科學的影響。一棵橘子樹的好壞,是用它能生產多少顆橘子來判定這棵樹的好壞,量產不足就把它砍掉。至於松、柏之類的樹由於它們不產果子,於是越不受到重視,現在已經不是重視「松柏不凋」的年代。從 60 年代以來,台灣越來越資本主義化,學術界人士跟自己也越來越疏離,成為「文人勞工」。這就是我寫那本小書的原因(編者按:即《歷史學的思維》),我要提醒自己不要成為那樣的人。真正懂馬克思的人,不見得一天到晚講馬克思。第二個層面,台灣的歷史教育,美其名是要培養所謂的專業史家。可是因為人口的增加,培養了一大堆 professional historians without profession 。大學中一班歷史系的學生畢業,大約四十人,真正走向專業歷史學的,不到五個。加上到國高中教書的,也差不多五個左右,換句話說,真正靠歷史吃飯的不過四分之一,其餘的四分之三自謀生路。我們的歷史教學和教育是這樣的情形,想要培養專業的學者,卻製造出更多的「沒有職業的專業史學家」。怎麼辦?要解決這個問題,我認為,大學教育中專業化的教育當然要持續,可是要多加上 public historians 的培育。 public historians ,既不同於十九世紀的專業化史家,也不同於業餘史家,業餘史家是那些有錢有閒的人做的。 public historians ,可以從事檔案管理的工作,到文獻會,到各鄉鎮市去管理檔案,也可以培養研究地方史的文史工作者,可以參與編寫劇本、歷史性的文學報導等等。這樣的做法,其實美國加州已經有一個學校這麼做。台灣起碼要有人能開一些類似的課程。

    +
    +
    +

    徐:這可能是一個層次,包括史學的出路、發展的問題,或是大眾化的問題,即廣度的問題。就深度來講,您覺得實証的研究是不可少的?

    +
    +
    +

    周:專業的史家,實証的研究、經驗的研究是不可少的,應用一些社會科學的理論我也贊成。可是史家一定要有自己嚴謹的研究方法,否則這門學問便站不住腳。我們要當專業史家,可是也不要變成只重技術性的,跟自己的生命疏離了。因此我在教學生的時候,我都是幫助他們發揮生命的潛力,很少說什麼理論。

    +
    +
    +

    陳:照老師剛才的說法,您是否就像西方所說的「人道主義」者?

    +
    +
    +

    周:也許吧!就學歷史來講,我希望「成就」我自己。這裡的「成就」,不是一般的意思,從我剛才的說法你們可以了解。「成就」和「成功」不同,有成就的不一定會成功,成功的人也不一定有成就。我要幫忙學生成就他自己,不一定就受我影響。

    +
    +
    +

    陳:也就是老師所相信的,人有他自己的自主意識?

    +
    +
    +

    周:對。所以我喜歡從 concept of man 和 concept of history 來談問題。

    +
    +
    +

    陳:談談所謂 concepts of man ,對於強調以 " 人 " 為基調的歷史觀點,是否會忽略與自然界的關係?

    +
    +
    +

    周:五百年前西方所展開的人文主義強調,人要從「非人」的因素從獨立出來、站起來。這五百年來,人確實站了起來,但也做得並不好,如地球被人踐踏得很慘。我想,人仍然要在地球這個空間站起來,不過,下一步應該是人要照顧自然界。五百年來,人要從 " 非人 " 因素走出來,現在,需從人的因素想反思人與自然的互動關係。

    +
    +
    +

    徐:剛才我們似乎比較集中在 concept of man ,較少談到 concept of history 。我們知道老師您早期研究過許多西洋史學的東西,後來又著力於影視史學,加上剛才您談到 public historians 的問題,這跟以前老師所謂的歷史的「求真」和「傳真」是不是有關係?這些好像是一脈相承的?

    +
    +
    +

    周:要回答這個問題,必需回到那本小書來談。那本書重點其實只討論兩個問題,一個是歷史的定義是什麼,一個是歷史的意義是什麼。剛才我們的討論是集中在歷史的意義,現在我們可以談談歷史的定義。我認為,歷史是人們對過去事實的認知及其傳達的成果。詳細的解釋在那本書都談到了,這裏只扼要說明。人們對過去事實的認知是所謂「求真」的問題,屬於知識論的層次。西方有經驗論的、實証論的、馬克思主義的各種派別,中國則有儒家的認知取向。從這個角度來看就牽涉到歷史是科學或是藝術的問題。另外的層面是傳達的層次,可以用文字寫下來,用嘴巴講下來,甚至用各種圖像傳達出來。甚至是後現代所說的,用什麼樣的符號系統傳達,閱聽者接收到什麼樣的訊息,就會有不斷的延宕、轉義等問題在裏面,這就是「傳真」的問題。有傳真的問題一定會有失真的問題,就像我們寫文章一樣,我們所寫的一定跟我們腦子裏所想的不太一樣,閱聽者看了我寫的東西後,一定又會有失真的問題。講到新的文史關係,我所謂的「文」不是指狹義的文,我會重新思考什麼是「文」?什麼是文學?不過這部分我是外行,不敢說。

    +
    +
    +

    陳:老師是專研西洋史的。能否談談老師對於目前臺灣西洋史發展的看法?並提供你對於臺灣西洋史未來發展的意見?

    +
    +
    +

    周:這三十年來,臺灣研究西洋史的是比以前更多了,假使就學位來看,當今擁有高學位的顯然比以前更多了。不過,我們的西洋史人才分散在各校,分散本來無妨,但是卻尚未能形成一個 community ,互動關係不夠強,所以想要培養研究生就比較困難。我們很難有一個單位能好好培養學生,假使把學西洋史人才放在一塊,一起培養學生就很好。我希望國內研究西洋史、外國史、世界史的人能形成 academic community 。其次,由於我們的資源有限,所以儘量的讓研究生能有機會去國外讀書,或者儘量的讓國外的人來臺灣,短期的講學……,一個月或一學期開課是最好。目前臺灣這種國外與國內的互動交流關係太少了。你可以算算,一年之中有幾個外國學者來臺灣演講有關西洋史的?非常少的。憑刊物不太容易形成社群,你們是先有社群才有刊物。你們應該多寫一些 review article ,做一些思辯性的評論,對你們有幫助。

    +
    +
    +

    陳:那史料上的問題呢?

    +
    +
    +

    周:史料一定須要出國拿,現在電腦雖然方便,但也是經人整理過的,有些最原始的資料是電腦所沒有的。我承認電腦可幫了很大的忙,但要做道地的史學研究,很多地方須要靠手工,最原始的耙梳工作,這才是「到家」。不是在家裡按個鍵,有多少算多少那樣就可以研究。在國內,研究生在資料方面的運用只能算是 " 將就 " ,但並不是說那就是正常。

    +
    +
    +

    陳:我們的刊物《歷史:理論與文化》,也是一份關於西洋史研究的刊物,您的意見如何?

    +
    +
    +

    周:基本上很好,要投入人力、物力等去做這個雜誌,我很鼓勵。我是覺得一個讀書人,最重要的就是自我反省能力要很強,有時要懂得自我批判,能夠自我反省表示自己心胸很開闊, open 、開闊的可以不斷吸收不同的意見,及人家對我們的批評,內部也不斷的批評,這樣才能夠長進,這是我的鼓勵話。嗯……,另外,我初步的印象是……,我們做歷史的,假使對理論有興趣是很好的,我自己也是走這條路的。可是研究歷史絕不能空言,不能空論,包括做思想史也不能空論,一定要落實。所以談西方史學理論的東西,西方人談的時候有其現實背景,你應瞭解, Butterfield 、 Meinecke 、 Marx 或傅科等人在講歷史與理論時,他們絕不是空論,一定從其現實背景來講。我們要瞭解他們,首先應回到現實來瞭解他們。歷史這門學問畢竟跟其它學問是不一樣,歷史畢竟是要跟時空扣緊。做理論很好,但不要忘記要落實理論……。務實是必要的,即使韋伯也跟現實密切結合在一起。我對你們的雜誌的初步印象及想法是如此,當然基本上絕對是積極的,值得肯定的。

    +
    +
    +

    陳:謝謝您接受訪問。

    +
    +
    +

    周:不客氣。

    +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/003/article03.html.html b/htdocs/htc/newsletters/003/article03.html.html new file mode 120000 index 0000000..6a7bb08 --- /dev/null +++ b/htdocs/htc/newsletters/003/article03.html.html @@ -0,0 +1 @@ +article03.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/003/article03.html.xhtml b/htdocs/htc/newsletters/003/article03.html.xhtml new file mode 100644 index 0000000..1157a64 --- /dev/null +++ b/htdocs/htc/newsletters/003/article03.html.xhtml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + +我有話要說 + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    我有話要說--
    +《西方女性史》第二冊《中世紀的沈寂》讀後

    +

    Klapisch-Zuber, Christiane. Silences of the Middle Ages, in Georges Duby and Michelle Perrot, eds., A History of Women in the West, vol. II. Cambridge: The Belknap Press of Harvard University Press, 1992, x+575pp.

    + +
    李貞德
    + +

    自從 1992 年五大冊的《西方女性史》英文譯本陸續出版以來,女性史研究者莫不將之引為談論之資。然而在奮力讀畢五百頁《中世紀的沈寂》 (Silences of the Middle Ages) 之後,最大的收穫竟來自於失落之餘的反省。原本期望透過閱讀,能更深入地瞭解中古婦女的生活,卻在讀完半本之時,仍大多停留在中古男性所想像的女性形象中。女性出現在男性教士、醫生、道德家的作品中,被形塑、論述,或不時貶抑,歷史學者則仔細介紹作者的時空社經背景、解讀作品的歧視意味。至於活生生的女人究竟以何種方式存在,就如標題所示地,頗為「沈寂」。不禁令人頓生緊張與疑惑。真的是由於古代女性史的史料極度欠缺?還是由於歷史學的時風潮流使然?

    +

    《西方女性史》五冊,大多由法國和美國學者著述,內容包括從希臘羅馬時代的歐洲至二十世紀的美國。最初以義大利文出版,以一般讀者為對象, 1992 之後始陸續英譯出版。其目的不在全面敘述西方女性的歷史,而在挑選議題和邀請作者的方式下,展現晚近西方女性史研究的成果和趨勢。中古名家 Georges Duby 和 Michelle Perrot 雖然任總編輯,但每一冊皆有獨立的主編。同時因涉及時代甚長,參與學者甚多,每一冊皆有各自的主題、風格和限制。第二冊《中世紀的沈寂》的十二篇論文,除少數由美國和德國學者撰述,主要出自法國和義大利的中古史專家之手。書分四部,首論「控制的規範」 (Norms of Control) ,描述教會、醫家、工商界領袖和政府對女性身體、服飾、家庭責任和社會角色的各種理解、論述和管制。第二部「家庭和社會策略」 (Family and Social Strategies) 則粗按時序介紹自五世紀到十五世紀之間,女性在修院運動、封建體制、宮廷愛情和工商業社會發展的過程中,曾經參與的活動、做過的努力和遭遇的限制。第三部「女性的遺跡與形象」 (Vestiges and Images of Women) 從考古和流傳的文物圖像呈現中古女性的世界。第四部「女性的話語」 (Women's Words) 則利用女性所遺留的書寫資料分析女性自己的聲音及其意義。

    +

    全書五百頁中,第一部規範觀點佔了一百五十頁以上,第二部雖然號稱「女性的策略」,但 Paulette L'Hermite-Leclercq 的〈封建秩序〉 (The Feudal Order) 和 Georges Duby 的〈宮廷模式〉 (The Courtly Model) 合計超過六十頁的論文,主要仍是討論男性焦慮與文學想像,而非女性真實活動的情形。第三部中 Francoise Piponnier 以考古材料所寫〈女性的世界〉 (The World of Women) ,雖然觸及女性生活與工作場所的推敲,但因太過簡短以致稍嫌薄弱(僅十二頁, pp.323-335 )。而第四部則只靠 Danielle Regnier-Bohler 的一篇文章〈文學與神秘的聲音〉 (Literary and Mystical Voices) 綜述所有中古女性所遺留的書寫記錄。無怪讀者在初覽之時,不免心慌意亂,以為中古女性沈寂無聲。其實,不論神學、醫學、文學或封建法規對女性的理解和論述,都有助於讀者認識西歐中世紀一千年的世界,並且本書中大部分描繪規範的文章,一方面提供不少有趣的故事,讓讀者如身歷其境般瞭解男性的觀點和焦慮,另方面也都站在女性主義的立場剖析了各種規訓背後的性別歧視意涵。然而,以此作為女性史專著的重點仍不免失衡,而本書的著作旨趣既在顯示晚近中古女性史研究的成果和趨勢,則其中關於女性的活動和聲音更顯得有待加強。

    +

    中古歐洲以基督教信仰為中心,本書論規範部份亦以 Jacques Dalarum 〈教士的觀看〉 (The Clerical Gaze) 一文為首,介紹自十世紀教會修會化至十二世紀以降社會修會化的過程中,男性教會領袖如何理解女性在救贖路上的位置及其與男性的關係。可想而知的,女性被視為性靈弱者,既容易受誘惑,又傾向誘惑人,在性慾和貞潔的拉鋸戰下,只能以處女、寡婦、主婦的順序進入天堂。將女性以婚姻狀況分類論之,在中古社會聖俗皆然。 Carla Casagrande 〈受保護的女性〉 (The Protected Women) 一文,主旨便在闡明此種少數男性以有限分類論述多數女性的情形。不論是教士以年齡或宗教身份分類女性,或政府(城市法官)以社會階級或職業分類女性,婚姻總是重要的基準。正因為以婚姻狀況(尤其是與其相關的性生活)分類女性,所以俗人雖然比修士更多機會體認到有各種女性的存在和差異,卻未必比修士更同情她們,反而透過裝扮、舉止、言語和飲食等各方面的教導與限制,對女性進行保護管束。

    +

    女性的生殖能力令男性困惑並惶恐。教父們以出生尿屎之間為恥,又感佩童貞女馬利亞誕育救主耶穌,不免衍生出許多對女性生育功能和狀況的想像,並從而發展出一套對性、生殖、自然與罪的論述。 Claude Thomasset 的論文〈女性的本質〉 (The Nature of Women) 便按時代順序介紹自希臘醫生 Galen 等人至阿拉伯醫學影響下的中古醫學對女性身體本質、受孕機制和各種疾病的看法。其中女性行房時達到高潮的能力及其與受孕的關連,亦即「一精論」或「兩精論」的問題,一方面牽涉到基督人神論的基本教義,另方面是判斷強姦是否成立的標準,因而引起熱烈討論。雖然大多數的男性教士多採一精論的立場,但醫生如 Galen 、女性神學家如 Hildegard of Bingen 卻傾向於兩精論。 Hildegard 更發展出一套看法,認為父母行房時愛情充沛有助於生男,而女性若享受了性樂趣,便如太陽般能生育滋養。1 話雖如此,中古社會對女性的期望卻非具有主體意識的母親。 Silvana Vecchio 的論文〈賢妻〉 (The Good Wife) 便指出良婦典型乃在於敬事舅姑(如事父母)、愛慕丈夫(貞潔自守與謙卑順服)、誕育賢子(撫育重於教導的母親角色)、以及持家興族(吝嗇的本性適合節流)。雖然十五世紀新興宗教風潮,或主張男性應積極參與家庭角色以免女性力有未逮,或主張將女性自家務中解放以投身宗教運動,但相關論述中女性賴以「向上提升」的利器:禱告和眼淚,卻在標示了她作為性靈弱者的同時,再次證明了她作為社會弱勢的事實。

    +

    在第一部有關規範的介紹中, Diane Owen Hughes 的〈管制女性服飾〉 (Regulating Women's Fashion) 無寧較能兼顧「再現與實況」兩個女性史研究的面相。一方面服飾乃社會階級的表徵,不論封建貴族或城市富商皆藉由妻女服飾表現自身地位,但另一方面基督教肉體必將朽壞和衣物代表罪性的思維則主導統治階層屢屢頒佈禁奢令。針對女性而發譴責各種高底鞋和蓬蓬裙的言論,在道德批評之外,又訴之於不利健康、有礙生育的說法。而女性的反應則頗多元,在以放棄流行服飾表現效法基督精神的同時,卻不否認服飾應用以表現家族和社會地位。不少貴族和富商之女或陽奉陰違,或直接向政府申請解除禁奢令。而號稱法國第一位女性主義者的 Christine de Pisan 則主張女性穿著華美並非為了吸引男性,純粹是為了愉悅自己。

    +

    法令規範限制女性,女性則或虛與委蛇、或借力使力,在夾縫中求生存,可說是本書第二部的主旨。 Suzanne Fonay Wemple 的〈五到十世紀的女性〉 (Women from the Fifth to the Tenth Century) 討論自羅馬帝國末期到加洛林王朝崩解之後女性在世俗和宗教兩方面的活動。不論世俗的羅馬法、日耳曼法,或教會法,皆以規範婚姻為重點,並藉以保護管束其中的女性。而女性則藉由為婦為母的身份獲得財產繼承與支配的權力。然而,中古初期對女性最特殊的吸引力卻來自於修院。出家修行安慰了害怕生育和婚姻暴力的女性,男女共學的雙修院由女修道院長管理,也為有志於學的貴族婦女開拓了公領域的另類人生。然而不論是法蘭克王國以妾為妻提供女性晉升管道,或修院運動支持女性自立自強,在之後的封建社會中都遭遇挫折。 Paulette L'Hermite-Leclercq 的〈封建秩序〉以十二世紀一宗不孕詐產的騙局展開敘事,說明教會婚姻法形成時,女性雖然得以愛和自由意志作為婚姻基礎,卻也在正妻地位確立的過程中逐漸成為生育和財產轉移的工具。從 Christina of Markyate 的逃婚故事可知,畢竟教會對於性、婚姻和守貞的教導互相矛盾,以致於所謂女性的自由意志,主要不在於結婚對象的選擇而在於出家或出嫁的決定。不幸的是,十二世紀教階制度確立並將女性排除,早期的修女院盛況不再。遭此變局,女性或以神秘主義靈修、或逐漸發展出如 Beguines 等自主修行團體,遊走於聖女和異端的邊緣。

    +

    「愛」確實是十二世紀歐洲社會的主流思維,然而教會所提倡的聖愛和婚姻之愛,卻不時感受到來自俗世貴族文學作品中性愛和情愛的競爭。 Georges Duby 的〈宮廷模式〉先描述文學作品中的婚外情模式:少男迷戀已婚貴婦,以眼神展開熱情追求,卻在「得手」之前嘎然而止。接著說明當代社會接受此一模式的背景因素:少年從領主而居並學習武藝,領主之妻既照顧他的生活也成為他情竇初開的對象;而基於對領主的恩義和身為貴族的榮譽感,為愛所苦的少年即使追求的過程極盡溫柔之能事,卻最終不願越雷池一步。因為文明與自制正顯示了騎士精神有別於其他階層之飢不擇食與「義近禽獸」。

    +

    就長遠的發展而言,宮廷愛情的文學母題似乎確曾影響了後來西方男女的交往模式和對待關係。然而,就緊接著的中古後期社會而言,女性的法律地位並未提升、家庭主權仍在丈夫手中、女性的家庭責任除了產育兒女也包括勞動營生,倘若真有「中古婦女運動」,也只能從女性的宗教經驗中尋求。 Claudia Opitz 的〈中古後期的生活〉 (Life in the Late Middle Ages) 一文,便是以較之前代豐富多元的資料,栩栩如生地描繪了女性為婦為母的選擇(避孕或殺嬰)與無奈(危險而辛苦),勾勒出工商業興起的城市中女性擔任師傅、商人、醫生、產婆的各種面貌,乃至探討了單身女性如妓女和寡婦的自主和困境。在最後一節中,她以 Beguines 修行團體和女神秘主義者的風起雲湧分析女性特有的宗教經驗、表達方式和獲致成果,並且問「中古是否曾有婦女運動」? Opitz 的文字敘述,呈現十三到十五世紀女性在家庭、工商業和宗教生活中豐富的面貌,得到 Francoise Piponnier 以考古遺址和 Chiara Frugoni 以圖像資料加以證實。

    +

    在本書第三部「女性的遺跡與形象」中, Francoise Piponnier 〈女人的世界〉 (The World of Women) 一文以陶器上的指紋推測婦女和小孩參與勞動;以家屋遺址分析女性為主的紡織工業從家內生產發展到工廠作業的軌跡;以屋內地板上搖籃長期滾動的痕跡訴說著女性內外兼顧的辛苦。雖然 Piponnier 提醒讀者不要以為 Christine de Pisan 《女性之城》 (The Book of the City of Ladies) 中的插圖具現了當時法國女性的勞動實況,但 Frugoni 〈想像中的女性〉 (The Imagined Women) 一文卻大量利用類似的圖像,配合教堂的壁畫和浮雕,說明當時聖俗社會中男性對女性的各種焦慮、排擠、期望和讚賞,以及女性的自我認知。可說是以圖像將本書內容總結綜述了一遍。

    +

    Christine de Pisan 的《女性之城》不但以插圖方式提供了對中古女性的各種想像,更是以其文字直接為女性發聲。如果女性自己發聲是婦女運動的先決條件和重要判準,那麼 Claudia Opitz 的問題可說在本書最後一章中得到部份解答。 Danielle Regnier-Bohler 的〈文學與神秘的聲音〉 (Literary and Mystical Voices) 為本書第四部「女性的話語」獨撐大樑。她一方面指出話語即權力:「神說要有光就有光」、「道就是神」的信仰;另方面說明女性被禁聲的文化傳統和社會制約:「夏娃一說話、人類就犯罪」的教導、女性宣講面臨異端指控的現實。接著她便藉由現存作品描繪中古女性如何透過迂迴進取(如 Hildegard of Bingen 說自己只是比較小的號角聲)和直言不諱(如 Christine de Pisan 抨擊男作家的性別偏見)等各種方式來發聲,或群聚說話、或書信敘情、或捍衛信念、或記述前賢、或針貶時事。俗人女作家固有 Christine de Pisan 為典範,神秘主義女性中亦不乏暢所欲言之人。她們以身體經驗為比喻記錄靈修實況,以如病如死如醉如癡形容與神相遇時的狂喜,以氣味、聲響、異象分享感動莫名的反應,終於在體會到己罪太重而神恩太廣的情況下,言語已不敷使用,只能以哭喊表達,以致出現新的發聲模式。 Danielle Regnier-Bohler 此文資料豐富而寫作引人入勝,讀完耳際有如群音並響、百鳥齊鳴,真佳作也。可惜限於篇幅,許多重要的女性作品並未細論。即使最後 Georges Duby 加了一篇後記〈口供與告解〉 (Affidavits and Confessions) ,簡介 1326 年 Jacques Fournier 審判 Cathar 異端 Beatrice 的口供,仍無法道盡中古女性「我有話要說」的風情!

    +

    總而言之,不論是對於中古史還是女性史有興趣的讀者而言,本書確實值得仔細品味。唯必須提醒讀者的是,中古女性的面貌絕對比本書所描繪的豐富,而任何瀏覽過 Dhuoda 、 Heloise 、 Hildegard of Bingen 、 Margery Kempe 、 Christine de Pisan 或 Margaret Paston 等人的私人信件、自傳、神學、醫學和文學作品的人,都難免訝於中古女性的震耳欲聾之聲,絕非「沈寂」一辭所能盡述。2

    + + + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +
    + +
    +
      +
    1. 關於自希臘以來醫學對於一精論和兩精論的介紹與分析,見 Thomas Laqueur, Making Sex: Body and Gender from the Greeks to Freud (Cambridge: Harvard University Press, 1990) ,中文書評可參考祝平一,《新史學》 7.4(1996) , 223-231 。至於 Hildegard of Bingen 和其他醫者教士意見之異同,及其對女性為母意義的看法,見 Clarissa W. Atkinson, The Oldest Vocation: Christian Motherhood in the Middle Ages (Ithaca & London: Cornell University Press, 1991) ,中文書評可參考李貞德,《新史學》 11.1(2000) , 201-208 。 (Back)
    2. +
    3. Dhuoda, Heloise 和 Hildegard of Bingen 的文字,在 Peter Dronke, Women Writers of the Middle Ages: A Critical Study of Texts from Perpetua (+203) to Marguerite Porete(+1310) (Cambridge: Cambridge University Press, 1984) 都有詳細討論。 Dronke 的書還分析了許多其他女性作者的作品。 Margery Kempe 的人生和自傳, Clarissa Atkinson 有專書討論 : Mystic and Pilgrim: The Book and the World of Margery Kempe (Ithaca: Cornell University Press, 1983) 。 Christine de Pisan 號稱法國第一位女性主義者,作品數量繁多,相關研究更是不勝枚舉。而美國學者如 Martha Howell, Women, Production, and Patriarchy in Late Medieval Cities (Chicago: University of Chicago Press, 1986) 以同業公會資料研究法蘭德斯的城市生活,或 Barbara Hanawalt, The Ties that Bound: Peasant Families in Medieval England (Oxford: Oxford University Press, 1986) 以驗屍報告研究英國農村,其中所呈現的女性亦非「賢妻寡言」或「男性觀看」所可涵蓋。相關中文回顧,可參考李貞德,〈婦女在家庭與社會中的角色 -- 歐洲中古婦女史研究〉,《新史學》 4.2(1993) , 121-143 。 (Back)
    4. +
    +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/003/article04.html.html b/htdocs/htc/newsletters/003/article04.html.html new file mode 120000 index 0000000..ad4a043 --- /dev/null +++ b/htdocs/htc/newsletters/003/article04.html.html @@ -0,0 +1 @@ +article04.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/003/article04.html.xhtml b/htdocs/htc/newsletters/003/article04.html.xhtml new file mode 100644 index 0000000..be9365a --- /dev/null +++ b/htdocs/htc/newsletters/003/article04.html.xhtml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + +Review of To the Ends of the Earth + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    Thomas N. Bonner, To the Ends of the Earth: Women's Search for Education in Medicine. Massachusetts: Harvard University Press, 1992, xiv+232 pp.

    + +
    張淑卿
    + +

    本書是一本研究婦女接受醫學教育的專書,時間的斷限是在十九、二十世紀,而此處所指的婦女醫學教育,是指醫師教育,並不包括婦女接受護士或助產士教育。1 作者最早的研究焦點是在 1914 年之前,歐洲大學裡的美國醫生。之後,作者發現這些接受醫學教育課程的外國婦女,對於每個大學城鎮的學術與政治生活,均有重大的影響。這些婦女學習內容為何? 1875 或 1895 年代,為什麼美國的婦女要到蘇黎世、巴黎、日內瓦等大學習醫?是什麼原因迫使東歐的婦女至瑞士或法國達半世紀之久?為什麼有許多的英國婦女在布魯塞爾或巴黎習醫?是什麼原因迫使他們離開家鄉、熟悉的環境而至外國習醫,這些均是作者欲在本書探討的問題。關於婦女習醫過程的研究,作品並不多。在現有的研究中,經常只研究單一國家的狀況,錯失了醫學婦女運動 (medical women's movement) 的國際面向。2 在十九、二十世紀的主要歐美國家,婦女用不同的方式進入醫學領域,同時擁有了不同程度的成就,進而有資格行醫。婦女得以在此時進入學校習醫,與當時西方大學改革、對婦女的看法、科學的信念與努力學習專業,有密切關係。而為了對抗新科學與舊有的性別刻板印象,許多國家的婦女在這個逐漸興起的新科學醫學之中,為自己建立一個活動空間。

    +

    但是,不同國家的婦女,所面臨的變遷力量亦不相同。美國婦女得益於美國社會的自由放任,當原有的醫療機構拒絕美國婦女入學時,她們即建立男女分開的學校與醫院。英國與加拿大的婦女在面對男女共同教育的抵抗時,同樣地依賴私人支持的醫院與女性醫學校,當作是習醫的首要之路。瑞士是第一個因國家力量介入,全面開放舊有的機構,讓女性進入學習。之後,法國與大部分的歐洲內陸國家均跟隨瑞士的路線。具有複雜統治階級的俄國,持續地被知識分子與學術單位所挑戰,一方面不准婦女全面性地進入醫學研究領域,一方面准許極少數的婦女可進入特殊的婦女課程就讀。德國原來極力反對婦女進入醫學體系,但在 1908 年時,有條件地接受婦女習醫,女醫師的數目,也很快的超過美國女醫生人數。

    +

    本書除前言、後記之外,共分為七章,討論蘇黎世、巴黎、俄國、德國、大英帝國以及美國的女醫師教育。誠如作者所言,討論女醫師養成教育的書籍並不多見,因此本書的性質較接近於通論性質,或許可以言之「十九末至二十世紀初期西方女醫師教育史」。本類研究較少見的原因,可能與資料較少、醫療專業以男性為主有關。故當作者接觸到有關歐洲大學裡的美國女醫師資料時,她就開始對這些引人注目的外國婦女,產生相當大地興趣。過去研究醫學教育,幾乎是從醫學專業化、國家介入的角度切入,很少從性別角度來看醫學教育的問題。醫學是個男性主導的專業領域。女性進入該領域的過程,其實是經過長久努力的結果。在本書的第一章,作者舉出一些例子,如 Elizabeth Blackwell 、 Sarah R. Adamson 、 Nancy Talbot Clark 、 Emily Blackwell 等幾位美國女性,均曾在十九世紀中葉進入美國的醫學院就讀,但只有 Elizabeth Blackwell 順利畢業。美國各大醫學院無法接受女性入學的原因在於,醫學院認為女性不能與數百位的男性共學;女性無法參與醫學生所必備的課堂討論,因此女性無法自男教授身上獲得必要的知識與技能。故女醫師 (woman physician) 的地位被描述成可憐的、可恥的與輕視的 (pitiable, ignominious, and despised) 。德國慕尼黑解剖學家 Theodor von Bischoff ,更進一步總結一般認為女性不適合擔任醫生的觀念,他將這些觀念歸因於「婦女腦部小、身體嬴弱、整體的本質就不適合研究醫學」,即使有極少部分的女性,如 Elizabeth Blackwell 可至醫學實習,其實習過程也是飽受排擠,因此,大部分的父母也不讓自己的女兒習醫。另外,也與十九世紀的社會情況有密切關係。在十九世紀的工業社會裡,婦女在家庭與工作中的轉變,讓婦女的地位充滿危機。特別是在英國與美國的工業革命,使得新的勞動階級婦女與舊有的中產階級之女,二者之間的差距愈來愈小。在歐陸地區,經濟變遷與法國大革命的「自由解放」相結合,婦女問題成為政治社會的關懷重點之一。婦女最好是在家庭內,從事家務,此是身為中產階級者的榮耀。婦女在該競爭年代裡,成為舊社會價值的守護者。在維多利亞的社會中,婦女是優雅神聖且天生具有虛弱的體質,在心理上也是較多愁善感、情緒不穩。在此概念下,男女之間有極大的差異存在。女性需要的教育有別於男性。女性應順從其特質,故需要教導其如何照顧丈夫與小孩,如何成為盡職的妻子與母親。數學、科學與古典研究 (classical studies) 幾乎不會被列入婦女的教育課程。這種禁止或不接受女性進入醫學校的狀況在歐美各國均是如此,直至 1870 年代之後才改變。

    +

    美國的醫學教育在 1870 年開始,有突破性的發展。除了部分美國婦女至歐洲習醫之外,美國本土也出現一些婦女醫學校。這個轉變主要與要求自由解放有關。支持自由派的人士,開始倡導婦女走出家庭,經濟與社會地位要獨立,同時改革婦女教育。美國有數百位的女醫師開始執業。這些女醫師主要來自中產階級,經濟的轉變讓她們有機會挑戰舊制度。值得注意的是,這些美國的女醫師年紀大於其男同事,許多人已經結婚生子,在學醫之前,有一些人曾擔任教師。其次,美國的醫學院主要是由私人所支持,而歐陸國家醫學院的資金來源是透過教會。美國婦女改革團體為婦女建立婦女醫學校的情況,無法見於歐陸地區。再者,美國在十九世紀出現多所醫學校的原因,在於順勢療法 (homeopathy) 、折衷醫學 (eclectic medicine) 、水療法 (hydropathy) 與自然療法 (natural remedies) 等特殊治療的盛行。這些治療方式強調避免使用強烈藥物與放血療法。此兩種治療方式均為受過正規訓練的醫師所喜愛。許多倡導特殊療法的團體,在特殊療法無法被正規醫學校接受之時,乃自行創立學校,並開放比正規醫學院更多的名額給婦女就讀。更重要的是,美國於 1850 至 1882 年間,設立了五所專收女性的醫學校。其設立的原因在於為同性的女性需求提供服務。因此,這幾所女性醫學校的課程仍是以衛生學、生理學、產科學、婦科疾病為主。同時,也有許多醫學院願意接受女性入學。但男女共學的情況維持不到三十年,在一些較保守的學校,如哈佛大學醫學院,又再度禁止女性習醫。雖然女性在美國的醫學教育與實習受到挫折,但這股建立女性醫學校或接受女性入學的風潮很快的傳到歐洲,因此造成作者所言之「專業婦女之大移民」 (the largest migration of professional women) 。

    +

    除了美國的女醫師教育之外,作者另一個焦點是歐陸國家的發展。她首先提出七位在瑞士蘇黎世大學接受醫學教育的女性,而一般研究早期婦女醫學教育者,對這七位女性並未特別注意。作者認為這七位來自四個不同國家的婦女,代表著十九世紀婦女習醫的最大勝利。她們在蘇黎世大學的成功,打開了男女共同習醫的大門。同時,蘇黎世大學接受更多外籍女性入學,學生遍及歐洲與北美地區。就女醫學生的人數來看,以俄國女留學生居首位;其次是德國籍;波蘭則為居第三。許多瑞士的大學將婦女教育視為實驗。蘇黎世大學的前六位女醫學生的評比,有四位是「優等」,其餘二位是「特優」。因此蘇黎世大學的教授公開支持女性接受醫學教育。巴黎的情況亦類似於此。

    +

    由於蘇黎世大學的婦女醫學教育的成功,引起其他歐洲國家的注意。巴黎、柏林的醫學院都有女性入學,其中不乏外籍婦女。這些在歐洲就學的外國婦女,雖然在教育方面已得到一個肯定,但在生活方面常受到留學地區居民的排擠。尤其是俄國女性受到排擠的狀況最為嚴重,當然主要原因在於俄國的女留學生人數始終佔全留學生人數的第一位。因此許多國家開始對外籍女學生採取一些管制措施,希望減少其數量。例如;瑞士因為女留學生實在是太多,乃針對外國學生徵收實驗室使用稅。

    +

    除了美、法、瑞士等國家外,作者亦提及俄國與普魯世的發展。這兩國發展婦女醫學教育的過程,與前三國的相似之處頗多,故此不再討論。另一個值得注意的國家是大英帝國。大英帝國雖然在經濟早已經歷工業革命,但整個社會是屬於保守的「維多利亞式」的社會價值與傳統。因此,英國的醫學院(如;愛丁堡大學)不僅無法接受男女共同教育的制度,同時也反對女性參與醫學教育。3 這些情況亦在 1870 年代有所轉變,主要是有美國與瑞士的前例,令英國婦女得以援用,與英國制度相抗爭。英國婦女開始進入愛丁堡大學習醫,至醫院實習,甚至執業。不過她們仍受到相當的阻擾,尤其在男女共學方面,教授總認為女學生在化學、醫學課程的表現不如男學生。若女性有婚姻束縛的話,亦不適合行醫。因此,若一定要設立婦女醫學教育的話,這些婦女畢業之後,理當為同性服務。於是在此概念下,英國出現一些女子醫學校、女子醫學院。4

    +

    至一次大戰前,無論是英、美或是歐陸地區,婦女醫學教育均已達到相當之成就。婦女習醫的過程,其實是充滿艱辛。她面臨的問題可能是被學校拒收、社會不贊同的問題。從該書的敘述,讀者可以看到每位先鋒者、前輩,在申請入學之時,學校以各種理由拒絕其入學,而這些女性則不斷透過各式各樣的方式,來達成習醫的目的。至瑞士習醫,成為是最普遍的處理方法。

    +

    本書主題是西方婦女如何進入醫學教育的歷史,是屬於一個較通論性質的範疇,並未針對某個國家作特別地深入討論,因此,它給讀者一個全面的概念。若對該問題有興趣的話,本書應是一本不錯的入門書。當然,本書仍有某些缺失。首先,本書的章節分配雖以國家為單位,但內容的敘述卻幾乎是以某位人物為中心。作者常以某位婦女的申請入學被拒為始,談論該國的婦女醫學教育發展。作者在本書前言,即開宗明義指出,不談偉大人物的歷史。然而其論述手法仍不脫以人物為中心的敘述方式。亦因以「國家」為論述單位,所以在時間順序上讓讀者較易出現混淆。其次,從本書的內容較無法清楚顯示作者的關懷重心為何。作者在此書中,描寫婦女習醫的困境,未明確交代該書是以女性主義或是性別的角度切入。此寫作方式令人誤以為該書是一本婦女習醫史。而放在教育史的脈落,本書的意義又是為何?再者,十九世紀後期至二十世紀初期,同時是護理與助產專業開始發展的時期,女性是這兩個專業的主要從事者,同樣是擔任與醫療有關的職務,她們彼此之間的關係又是如何呢?本書幾乎未將該個三問題,列入討論,甚為可惜。

    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +
    + +
    +
      +
    1. 本書所言的婦女醫學教育,均專指婦女如何成為醫師的過程,故本書評為論述之方便,均以「女醫師教育」稱之。 (Back)
    2. +
    3. 醫學婦女運動 (medical women's movement) 是指十九世紀中晚期,歐美地區出現一些婦女醫學校,同時有許多婦女習醫的過程。因為飽受以男性為中心的醫院、醫學校所排擠,故過程是相當艱辛的。有關於女醫師的簡史,可參閱 Fohanna Geyer-Kordesch, "Women and Medicine," in W. F. Bynum and Roy Porter ed., Companion Encylopedia of the History of Medicine, Vol. 2 (London: Rouledge, 1993), 895-901. (Back)
    4. +
    5. 維多利亞時代的英國是相當保守的社會,女性異於男性表現在先天與生理兩方面。女性特殊的生理與心理,均需要藉由婦科專科來處理。故表現在教育方面,男女接受教育的內容應該是不同,兩者是不適合共學。有關於十九世紀英國婦科的發展,可參閱 Ornell Moscucci, The Science of Woman: Gynaeology and Gender in England, 1800-1919 (New York: Cambridge: University Press, 1990). (Back)
    6. +
    7. 這些女子醫校包括; Edinburgh, Dublin ,Glasgow, Scottish 等所學校,其中以 Scottish University 的成立最具意義。它是蘇格蘭婦女改革團體與自由派教授辛苦抗爭之後,得到的結果。 (Back)
    8. +
    +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/003/article05.html.html b/htdocs/htc/newsletters/003/article05.html.html new file mode 120000 index 0000000..fe3ea71 --- /dev/null +++ b/htdocs/htc/newsletters/003/article05.html.html @@ -0,0 +1 @@ +article05.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/003/article05.html.xhtml b/htdocs/htc/newsletters/003/article05.html.xhtml new file mode 100644 index 0000000..3a2aa3f --- /dev/null +++ b/htdocs/htc/newsletters/003/article05.html.xhtml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + +編者言 + + + + +
    + +
    + 回目錄 | + 前一篇 +
    + +

    編者言

    + +

    2001 年新春,《歷史:理論與文化》第三期終於付印出版。回顧一、二期的出版過程,我們承載著許多西洋史新進與前輩的支持,在此,小編對本期的脫刊近半年深表歉意。

    +

    今日,網際網路的運用日漸普遍,與其做為一種商業牟利的工具,我們更希望能將之轉回最初為加強學術網絡互動討論的目的,於是,在 2000 年 8 月 26 日,《歷史:語言與文化》官方網站正式啟用,網址為 http://htc.emandy.idv.tw 。透過網路虛擬空間的連結,本刊物跨越實體的空間障礙,陸續將以往各期內容上網,期待能邀得更多讀者的迴響與討論。

    +

    第三期的內容共有四篇。近年來學界對年鑑史學的興趣雖稍冷淡,但相關的著作卻接二連三的引進翻譯出版,與這兩年盛行的科普翻譯風潮相較,實不遑多讓。閱讀翻譯書籍雖是簡便獲取知識的途徑,然而,在貪快嚼不爛的趕譯風潮下,譯者一時不察誤譯而導致讀者誤讀的情形,則不免令人感到憂心。因此,為呼應這樣一個翻譯文化,不妨回頭看看本土對於年鑑史學的相關研究。職是之故,本期為首的是一篇有關年鑑史學大家馬克‧布洛克 (Marc Bloch) 的專論:潘宗億〈布洛克歷史思想的核心概念與方法〉。

    +

    其次是一篇對周樑楷教授的專訪。刊物創立伊始,原就規劃邀請國內著名的西洋史學者進行訪談,分享其學思歷程及治學心得,為有志研究西洋史的後進提供一個可資參考的典範。基於種種考量,本篇訪談稿終於得以面世,希望這個起頭能為以後的訪談錄開創一個好的開始。本期最後,我們將以兩篇婦女史書評作結,並感謝李貞德、張淑卿兩位作者在百忙之中答應本刊的邀稿。尤其是目前國內西洋中古婦女史及女性專業醫療史兩個範疇仍待開發的時刻,相信這兩篇書評必能發揮其引導旨趣。

    +

    當代歷史理論的發展,自六0、七0年代起,其中有一派接受後結構主義 (post-structuralism) 的思路引導,挑戰傳統實證史學的權威,激發史學研究社群內部的反省,並以不同的途徑建構史學中敘述與修辭的性質,從而豐富史學理論的創新。因此,在第四期的《歷史:理論與文化》中,本刊將擬定出版「歷史理論」專號,以當代史學史、史學理論為主要研究取向。最後,本刊誠摯地期待學有專精之各方人士踴躍投稿。

    + +
    + 回目錄 | + 前一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/003/article06.html.html b/htdocs/htc/newsletters/003/article06.html.html new file mode 120000 index 0000000..1688ac2 --- /dev/null +++ b/htdocs/htc/newsletters/003/article06.html.html @@ -0,0 +1 @@ +article06.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/003/article06.html.xhtml b/htdocs/htc/newsletters/003/article06.html.xhtml new file mode 100644 index 0000000..aebda95 --- /dev/null +++ b/htdocs/htc/newsletters/003/article06.html.xhtml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + +誌謝 + + + + +
    + +
    + 回目錄 | + 前一篇 +
    + +

    誌謝

    + +

    《歷史:理論與文化》於西元一九九八年七月創刊,刊物出版至今已堂堂邁入第三年,而第三期刊物經過一年餘的辛勤耕耘,總算也出刊了。期間受到眾多讀者的支持、關懷與指教。在此,全體編輯委員要向所有給予本刊鼓勵與支持的人士,致上最真誠的謝意。

    + +
    +

    贊助者

    + + + + + + + + + + + + + + + + + + + + + + +
    王芝芝12/18/991500 元整
    李貞德10/25/991000 元整
    周雪舫10/15/991000 元整
    吳燕秋09/11/991000 元整
    徐文路09/11/99500 元整
    盛少輝09/11/991000 元整01/15/001000 元整
    陳思仁01/15/001000 元整
    陳逸雯07/15/001000 元整
    黃天成09/21/991000 元整
    黃明田06/24/001000 元整
    郭明贊09/21/99500 元整
    雷俊玲09/20/992000 元整
    潘宗億06/24/001000 元整
    謝英從07/15/001000 元整
    無名氏11/25/994000 元整
    +
    + +
    + 回目錄 | + 前一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/003/index.html.html b/htdocs/htc/newsletters/003/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/htc/newsletters/003/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/003/index.html.xhtml b/htdocs/htc/newsletters/003/index.html.xhtml new file mode 100644 index 0000000..d1890fb --- /dev/null +++ b/htdocs/htc/newsletters/003/index.html.xhtml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + +第三期 目錄 + + + + +
    + + +
    +

    歷史:

    +

    理論與文化

    +

    西洋史研究通訊

    +
    + +
    +出版者:
    +《歷史:理論與文化》編輯委員會
    +編輯委員:
    +吳燕秋、徐文路、陳思仁、盛少輝
    +黃明田、蕭道中、潘宗億
    +本期責任編輯:吳燕秋
    +本期執行編輯:潘宗億
    +二00一年一月一日出版
    +一九九八年七月一日創刊
    +
    + +
    +

    第三期 目錄

    + + +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/004/article01.html.html b/htdocs/htc/newsletters/004/article01.html.html new file mode 120000 index 0000000..f89ba28 --- /dev/null +++ b/htdocs/htc/newsletters/004/article01.html.html @@ -0,0 +1 @@ +article01.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/004/article01.html.xhtml b/htdocs/htc/newsletters/004/article01.html.xhtml new file mode 100644 index 0000000..4cb84ca --- /dev/null +++ b/htdocs/htc/newsletters/004/article01.html.xhtml @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + +特爾慈論基督教信仰之歷史性 + + + + +
    + +
    + 回目錄 | + 下一篇 +
    + +

    特爾慈論基督教信仰之歷史性*

    + +
    高晨揚
    + +

    歷史主義思想家特爾慈 (Ernst Troeltsch, 1865-1923) 在任職於海德堡大學系統神學教授期間,發展出以歷史學的方法與精神作為基督教神學之方法論與知識架構,以將神學轉化為現代學術中之組成部分。本文即討論特爾慈如何處理歷史與信仰之內在關係,包括從方法論的觀點討論如何掌握作為「歷史的基督教」的本質,以及對「歷史上的耶穌」如何作為信仰對象之討論。

    +

    本文要處理的是特爾慈如何將歷史思想應用在對基督教神學的討論中。在傳統神學中,由於將耶穌理解為進入歷史的救贖者,信仰與歷史就開始了難分難捨的關連,1 這種關連除了直接表現在對教會歷史的解釋中,近代神學也以如何理解耶穌身分之「基督論」角度對信仰與歷史的關連進行探討。我們將從與哈納克 (Adolf Harnack, 1850-1931) 對話的角度出發,整理特爾慈對此問題的看法。

    + + +

    哈納克與基督論問題

    + +

    二十世紀的立欶爾學派 (Ritschl) 神學家中,最富盛名的無疑是教會史家哈納克,他於一八八八至一九二一年間年在柏林大學教授教會歷史;哈納克是德皇威廉二世的心腹,曾撰寫德國政府向人民宣告發起第一次世界大戰的文告。奠定他學術地位的是一八八六至一八九0年間所發表的三冊《教義史》,被稱作是十九世紀最重要的教義史著作。其中的主要觀點認為福音原本處於巴勒斯坦的環境,以希伯來的思想模式為主導,後來則轉移至希臘文化的環境,思想模式截然不同,成為基督教思想在歷史上的轉捩點。希臘文化將耶穌的重要性形上學化,因而產生種種關於基督論的教義,這些教義堵塞了真正的宗教泉源,因此一部教義史也就是一個關於基督教精神遭受蒙蔽與退化的故事。馬丁路德 (Martin Luther) 曾嘗試回復原來的基督教,之後新教正統化的發展卻又走向「準天主教」的形態。2

    +

    不過真正使哈納克聲名遠播的則是一九00年出版的《基督教的本質》 (Das Wesen des Christentums) ,這是一八九九至一九00年間他在柏林大學開放給各系學生的授課演講,經一位學生逐字記錄下來。這本書不久便引起廣泛地注意,兩年之內,被翻譯成六種語言出版,在德國引發了十一本出自新教以及十四本出自天主教的回應與爭辯之著作,另外還有大量的專文與書評。3 據當時的人說,沒有一個與宗教有關的會議、期刊與報紙不在評論此書。4 而此後的三十多年中,它的內容仍一直被許多講道家與作家廣泛地引用。5

    +

    在《基督教的本質》這十六篇講稿中,哈納克企圖辨識出基督信仰的精髓。他認為這項工作必須拒絕任何普遍概念的思辯推演,而要單單應用歷史方法,因為基督教是一個具生命的實體。從歷史的角度來看,基督教的起源在於「耶穌基督及其福音」,第一代的門徒就直接受到其影響而開始了教會。但福音並非就完全等同於基督教的最早形式,而是那些在不同的歷史形式中具有持續有效性的事物,因此我們必須從外皮中尋找核心,從教會歷史中分辨出基督教的本質。6 哈納克認為耶穌具神性本質的這種「道成肉身」思想,不能當作基督教的核心,因為耶穌宣告的信息是關於父神的,而不是關於他自己的。這信息可歸納為三個相互關連的真理—上帝的國及其來臨、父神和人類靈魂的無限價值,以及更高的公義和愛的戒命。7 福音是純粹的與具排他性的,免於與任何文化、社會條件與科學有直接的關連,而必須在每一個時代中被個人與宗教群體更新。

    +

    我們看到在「基督教的本質」的辯論中包含著兩個重要的論題,首先是關於如何瞭解基督教的歷史發展,不只是教義史,也包括基督教所表現出來的教會形式與信仰生活;另外更重要的論題是如何瞭解耶穌,以下我們要對這個問題略做說明。

    +

    依據新約聖經,基督教群體的第一篇講章,就是要藉著見證耶穌從死裡復活,指出「以色列全家當確實地知道,你們釘在十字架上的這位耶穌,神已經立祂為主,為基督了」(和合本聖經使徒行傳二章 36 節)。自此以後,耶穌一直是基督教信仰的中心:他是上帝所差來的獨生子,顯明上帝對世人的愛(約翰福音三章 16 節);他成就了救贖的工作,使人得以與上帝和好(羅馬書三章 23 至 24 節;哥林多後書五章 19 至 21 節);他是上帝啟示的高峰,是上帝「本體的真相」(希伯來書一章 1 至 3 節),以致當一個人將拿撒勒人耶穌等同於舊約中所應許的救主基督(即希伯來文的「彌賽亞」,意為「受膏者」),而稱「耶穌基督」時,就表達出個人對基督教信仰的認信。為了理解耶穌的特殊身分,從新約聖經開始,就發展出種種對耶穌之人性與神性問題的討論,在後來的基督教神學中,將這種問題稱為「基督論」 (Christology) 。新約中對這個問題最經典的表達,應該算是使徒約翰對耶穌的介紹:「太初有道,道與神同在,道就是神。……道成了肉身,住在我們中間,充充滿滿地有恩典有真理。我們也見過他的容光,正是父獨生子的容光」(和合本聖經約翰福音一章 1 節; 14 節)。這樣,曾出現在歷史中的那個人,就是真理本體的肉身顯現。

    +

    早期基督教教義的發展中,最早的爭辯就是關於耶穌神人二性的問題。例如,亞流 (Arius, c.250-336) 認為,基督只是受造者中最突出的一位;亞波里拿 (Apollinarius, ?-c.390) 則認為耶穌人性的靈魂被屬神的道所取代,因此他並不具備完整的人性等等,掀起了長達兩個世紀的爭論。這個爭辯導致第一個大公會議— 325 年尼西亞會議 (Nicaea Councils) —的召開,最後在 451 年的迦克墩信經 (Chalcedonian Creed) 中確立了正統的基督論教義,強調耶穌同時具有完整的人性與神性,這成為希臘教會、羅馬教會,以及大部分的新教教會所共同認定的信仰。8

    +

    但是傳統的基督論在啟蒙運動時遭受新的挑戰,萊辛 (G. E. Lessing, 1729-81) 在一七七七年所發表的《論靈與能力的明證》 (On the Proof of Spirit and Power) 中說:

    + +
    +

    若沒有歷史的事實可以被證實,則不可能藉著歷史事實來證明任何事情。亦即歷史作為偶然的真理,不可能成為理性必然真理的明證……若是基於歷史的根據,我並不反對「基督使一個死人復活」,此一陳述,是否就表示我必須承認「神有一個與祂本質相同的兒子」?不反對前者,是否意味著必須要強迫我自己違反理性去接受後者?兩者有何關係?……要由歷史性的真理推論到另一類全然不同的真理,要求我以此為根據形成我所有形而上學及道德的觀念,或因為不能舉出任何有利的證據來否定耶穌的復活,而期望我就此改變我所有基本的神觀……這便是那醜陋的大溝渠,雖然我經常認真地嘗試跳躍,卻無法橫跨。9

    +
    + +

    當代學者麥葛福 (Alister E. McGrath) 將萊辛對耶穌作為啟示真理所提出的質疑歸納為三方面。首先,我們如何能確定耶穌時代真正發生在巴勒斯坦的事是什麼?其次,假定我們對於這個知識的可靠性有把握,拿撒勒人耶穌的歷史與普世性、必然性的真理有什麼關連?也就是說,歷史作為偶發性與暫時性的事件如何能轉變為在任何時間、地點都不改變的理性真理?最後,我們最多只能承認耶穌的教導具有特別的價值,但第一世紀與十八世紀的世界觀如此地不同,這教導與現在歐洲人有什麼關係?總結而言,也就是有一道「醜陋的鴻溝」橫跨在信仰與歷史之間。10

    +

    萊辛的質疑是啟蒙運動的後果。啟蒙運動認為「理性」是必然的與永恆的,然而歷史知識的對象則是偶然的與短暫的。這樣一來,歷史不可能推論出具理性價值的真理,從「耶穌復活」(一個看來相當可疑的「歷史事件」)而推論到耶穌是上帝之子,有與上帝同質的神性,成為不可思議的跳躍。

    +

    這樣,萊辛帶出了一個現代神學無法迴避的課題,也就是我們如何能在歷史人物身上確認與把握住永恆的真理?史萊馬赫 (F. D. Schleiermacher, 1768-1834) 在《基督教信仰論》 (Der Christliche Glaube, 1821) 裡,放棄了任何像「道成肉身」這種有關耶穌「神性先存」的宣稱,而將基督論理解為「救主由於同為人性之故,而和所有世人相像,但其有異處,在祂的上帝意識經常充沛,好使上帝在祂裡頭有了確鑿的存在。」11 在這裡,「上帝意識」的充沛與不足成了耶穌與世人的分別所在,但「上帝意識」卻使這個分別有了某種意義上的連續性,並將耶穌的人性與神性連結起來。這樣,史萊馬赫藉著浪漫主義中內蘊有神論的思想化解了偶然與必然兩者的張力。到了十九世紀後期,立欶爾學派嘗試從新康德學派中擷取資源來處理這個問題,也就是認為宗教知識所涉及的不是事實的判斷與形上學的判斷,而是價值判斷。歷史研究雖然無法確定耶穌的身分,卻可以用來找出耶穌生活與教導中的倫理價值與宗教情操,以成為未來世代的信仰基礎。這樣,立欶爾學派也就能將信仰與歷史之間巧妙地連結起來。作為一個教會史家,哈納克就是以立欶爾學派的觀點來寫基督教歷史。不過原本立欶爾所主張價值判斷與事實判斷之間的對立,現在被解釋成福音的歷史處境從希伯來文化轉換成希臘文化;原本立欶爾以神學不應進行事實判斷為理由迴避傳統基督論的問題,現在哈納克則進一步批評傳統基督論的發展悖離了基督教的核心。哈納克對基督論的看法可以說是立欶爾學派觀點的極端表達。

    +

    自一八九0年代以來,有人開始批判立欶爾學派的做法。韋斯 (Johannes Weiss, 1863-1914) 與史懷哲 (A. Schweitzer, 1875-1965) 認為耶穌所傳講的上帝的國,帶有強烈的末世意味,並非如立欶爾學派所說是一種崇高的倫理理想。宗教歷史學派中的威列得 (William Wrede,1859-1906) 指出,在福音書的記載中,歷史與神學緊密纏繞,無法分開。福音書的記載本身就是神學架構,我們無法繞到它背後去尋找歷史的耶穌。客勒爾 (Martin Kähler, 1835-1912) 則認為應該將「歷史的耶穌」與「信仰的基督」分開,因為基督本身是超歷史的,而非歷史中的人物。對信徒而言,重要的不是基督是誰,而是祂為我們做了什麼。12 我們可以在後面看到,特爾慈對這個問題的看法已受到這些批評的影響。

    +

    特爾慈對這個問題的思考是從歷史的本質開始,再處理歷史與信仰之間的關係。以下我們先討論歷史的層面。

    + + +

    什麼是「基督教的本質」?

    + +

    一九0三年特爾慈發表了〈什麼是「基督教的本質」?〉 (Was heisst “Wesen des Christentums”?) 。本文在一九一三年被收錄於他的文集第二冊時,經過了一些修改,而我們所參考的英譯正是譯自文集第二冊,所以我們的討論也包含他在一九0三至一九一三年間的思想發展。13

    +

    特爾慈首先檢討有關對哈納克的各種意見:教義學家批評哈納克用世俗的方法研究上帝的道;有人不排斥歷史研究,卻認為教義應優先採用內在宗教經驗來考察;還有人認為所謂純粹的歷史研究應該考察的是那些教會認可的主要教義。特爾慈認為這些人都有一項共同的預設:在某項「理念」中發現基督教的不變本質。另一方面,也有學者根本懷疑尋找本質的可行性。天主教學者則說「本質」是不斷改變的複合體,必須從環境脈絡與宣揚福音的條件之真實歷史來理解它。14 對特爾慈而言,哈納克的這本書標示出神學研究歷史化的趨勢,不過一切參與爭辯的人不是不願承認就是不夠重視這一點,以致於沒有人深入地從歷史方法出發來反省這個問題,因此他要從純粹方法論的問題來進行探討。

    +

    特爾慈的出發點在於確立「基督教的本質」是一個現代歷史思維下所產生的問題。萊辛與赫德 (J. G. Herder, 1744-1803) 開始將基督教視為「基督教生活的整體,被瞭解為主導觀念 (driving idea) 的充分性歷史展現。」15 從這種看法出發,基督教的本質也就是在基督教歷史的展現中被人們意識到的主導觀念。十九世紀的科學性神學之發展就是一個不斷嘗試決定基督教本質的過程,這項任務是基於現代性歷史思維的預設上。基於這項預設,「本質」也就是一個抽象理念,是單獨適用於歷史的抽象,藉此可以從整體展現背後的主導觀念來理解相關的脈絡。這整個預設確立於德國觀念論,但後來則從其辯證法與實體的邏輯範疇等概念中獨立出來。16

    +

    這意謂著,對基督教本質的定義在其預設上就排除了教義學的方法。教義學方法的基礎在於神蹟證明,這與現代性歷史思惟有根本的抵觸。當歷史方法被真正運用的時候,「教義被歷史地與心理地解釋為理智的過程……教會及其權威就如同神蹟一樣,失去了他們與本質概念之抽象的聯繫。任何將本質歸類為基督教觀念與自然宗教真理、普遍宗教概念或普遍倫理預設之間的符應的嘗試,都必須被丟棄。」17 在這裡,定義本質雖然是一個純粹歷史的任務,但「歷史的」本身已包括一種整體的世界觀,它「從『經驗—歸納』的歷史寫作的方法與心靈中產生出更高秩序的任務。它在一點上自『經驗—歸納』的歷史轉移到歷史哲學。」18 哈納克的反對者爭辯如何以更合歷史的方式找出本質,卻沒有看到這是屬於歷史哲學的問題,以致於他們實際上採取一些從其餘歷史中區隔出來的權威性要素來當作本質,無論是基於聖經默示的教會教義、基於教會本身的教義,或是敬虔主義環繞著對悔改的確信,都只是不同形式的神蹟。19

    +

    接下來要考慮的是,在定義本質時我們從整體歷史展現中抽象出主導的力量,但這卻不同於對自然律則的陳述。自然律則要說明一致性事實所反覆出現的規律,但本質的陳述卻要解釋多樣性的展現,後者在其自身並非是永恆的,卻使我們有可能去表達出歷史發展脈絡中的長存事物。歷史中的一切形式並非本質之因果必然性的作用,而是目的論必然性的展現。20

    +

    但這種目的論必然性並非如黑格爾學派所主張的,豐富性展現的整體都是本質的表達,因為我們需要在豐富性當中不斷把相異事物隔開,以達到核心。例如新教就不可能將從原始教會至天主教的發展接受為目的論的必然性,而認為是一種斷裂;而小派與神祕主義則就其與原始教會間的獨立關連而拒絕一切形式的教會原則;相反的,教會則認為小派與神秘主義與基督教的本質相對。21 對本質的界定是直接陳述我們自己對基督教的概念與詮釋,我們所作的不只是從整體展現中抽象出本質,還要區分表達出本質、遮蔽了本質、曲解本質,或僅僅是與本質無關的偶然等等不同的展現。這樣一來,對本質的定義就包括了要進行批判,這批判雖然被表達為純粹歷史研究的成果,但卻總是從特定立場出發,這樣個人主觀的成份就不可避免了。22 不過特爾慈否認對本質的定義純粹是個人主觀的問題,他認為在一群夠資格的史家分別對整體資料進行同情地瞭解,並且不斷彼此糾正之下,能夠克服無限制的主觀主義,使定義本質仍然是一件有意義的任務。但即使如此,我們不可能在定義本質時維持一種倫理上的中立立場,因為歷史的目的論必然性指出一個人是出於獨特的「應該如此」的理念而思想與行動,對這種必然性的判斷屬於個人抉擇與內在信念。23

    +

    既然對本質的定義就是要區分本質與非本質,下一步就是要問,在哪裡可以發現最重要的本質展現?一般都同意,可以在起源中發現觀念最有力與純粹的形式,尤其在基督教中,每個信仰者都藉著與創始者的接觸而得到宗教生活的滋養,新約時期的歷史也藉著成為一切信仰群體的判準而發揮著內在影響力。24 但特爾慈並不同意哈納克的看法,認為本質完全內含於起源之中。首先,特爾慈採用威列得所以為的福音書已具神學性質的看法,指出新約中對耶穌面貌的描繪已受到之後信仰群體與偉大使徒的影響,以致於耶穌的佈道與保羅的教訓一起構成了福音的內涵,這使得原始基督教從一開始就有兩個不同的基調,並對基督教歷史發展有著不同的影響,因此我們並沒有關於原始時期的單一權威。25 其次,從使徒時代以來,基督教就已經是對基督與聖靈的信仰,但聖靈並沒有在原始教會耗盡其影響力,而是繼續在不同的時代以不同的方式工作著,以產生新的形式與改革。因此我們沒有理由說原始教會與之後的發展之間有什麼絕對的鴻溝存在,而應該將之後的種種發展都視為隱藏在原始形式中要素在合適處境下的展現,本質必須是一個「具備內在適應性與創生力而創新與吸收的實在……必須是一個發展中的精神原則……具有內在的目的與價值。」26

    +

    這種發展中的精神原則與黑格爾不同的地方在於它不能預先被邏輯必然性建構出來,而是一方面被客觀的歷史所糾正,另一方面進行主觀的評價,因而每一個人都會在其中得出不同的發展途徑。事實上,本質的概念「不能是一個簡單概念,但至此必須在自身內存在著相對與張力。它必須在自身之內包含著在幾個基本觀念間的擺盪。」27 而當這些基本觀念面臨到特定的思想與心靈處境時,它進一步採用相關的要素而展現出新的形式。特爾慈將立欶爾的現世倫理與韋斯和史懷哲的末世論拉在一起,認為原始基督教自身內就包含著一種宗教倫理與人性倫理之間的二元論,前者是展現在耶穌的佈道之中超越的與末世論的倫理觀念;後者是在是普世性教會的發展中從創造論引申出來的內蘊倫理觀。兩者處在一種持久的張力中,構成了像立欶爾所說橢圓的兩個焦點。28

    +

    最後一個重點在於,「未來」的視野在定義本質中是不可避免的。當我們在對基督教進行歷史思考時,必然會將存在的連續性延伸到未來,藉著這樣一個投射而啟發現在與過去。從這個角度來看,對本質的定義在很大的程度上被個人對基督教的態度所影響。假如一個人不再相信基督教的有效性,他將選取那些與現在和未來發展相反的事物作為基督教的本質。相反的,若他對基督教持肯定的立場,會強調那些與現在、未來有共通點的過去作為本質。29 不但如此,「未來的發展將被算進發展中的本質,並且我們是依據基督教觀念的本質與主導力量來洞察應該如何,未來的發展既被此洞察所掌控,本質就從作為一個抽象概念自動地轉變為一個理想概念 (ideal concept) 。」30 這也就是說,不但對未來的態度會影響到對本質的定義,對本質的定義也會反過來影響未來的發展,當既定的過去與形成中的未來連結於對本質的定義時,抽象概念也就轉變為理想概念,也就是從歷史的範疇轉變為倫理學的範疇。

    +

    不可避免地,理想概念使「想像要在本質的概念中預見基本觀念在未來之展現」,31 這是出於在定義本質上「對基督教的態度儘管伴隨著一切歷史哲學與形上思辯的考慮,然而分析到最後是徹底地被現在生活的脈絡中個人的宗教領受與對基督教觀念的支取所制約的個人態度」,32 本質作為理想概念就要求我們對基督教做出個人的抉擇,這抉擇將會型塑未來。這樣,可以看見在定義本質的方法論考慮中,我們「從純粹歷史方法的起點出發,明確地選擇以客觀性為目的,如何關連著最終認知到強烈主觀要素」,33 特爾慈認為「這裡確實發現了整個問題的癥結所在……然而這個癥結並不能在理論上被解決,而只能被結合了客觀與主觀的生命行動……作為唯一可能的解決,儘管這在理論上並不相容。」34 特爾慈又將客觀與主觀的結合稱為一種「創造性的行動」,其中客觀的部份是指必須有著深厚而廣博的歷史基礎,以免除各種偏見與膚淺;而主觀則是指當我們為了找尋本質而沈浸於過去時,是想著這本質要如何引導我們自己以及同時代的人繼續往前行。

    +

    藉著對「基督教的本質」做方法論上的反省,我們看到特爾慈對歷史知識的看法很明顯地已經超出了李克特 (Heinrick Rickert, 1863-1936) 對特定文化主導價值的關懷,甚至打破了李克特所苦心奠定關於歷史知識中價值的先驗論基礎,而承認在歷史知識中有著「理論上」不可避免的主觀性,使得歷史知識再度陷於危機中,必須藉助優秀的史家在「實踐上」以創造性的行動予以克服。但是實踐能否完成理論所無法解決的問題?最終既然訴諸於實踐,那麼我們在理論上顯得永遠無法回答這個問題。不過可以說歷史知識的可靠基礎本身並非特爾慈的主要關懷,他關心的是在現在的行動中使過去能為未來效命,使得過去、現在與未來連結在定義本質這個創造性行動中:

    + +
    +

    既然這並不僅僅尋求對其他人目的性價值的互相作用之翻印,而既然表達出本質的判斷也決定了我們的意願,它就承擔了一部份歷史的目的性特徵,這也就是說,它成為一個行動。只有以行動的勇氣連結過去與未來,藉此以歷史的方式為現在掌握文化複合體的本質,未來才會以被現在需要的方式出現在本質中,同時竭盡歷史脈動的深淵。但假如在這個意義上對本質的定義是一個行動,那麼它就不僅是一個對歷史的判斷,而自身也是歷史的一部份。35

    +
    + +

    定義本質不只是研究歷史,也是在創造歷史,「如同作為知識分子沈浸於歷史中的結果,使得政治學與社會學已影響現代的發展……基督教本質的科學性工作,對於教會界日覆一日爭論的意見與熱情提供了貢獻」。36 可以看到特爾慈同意西南學派 (Southwest German philosophy) 的看法,認為一切知識最終都免不了規範性問題,所謂「科學的」,應該在參與歷史的創造性行動中完成自己的使命。如此一來,對本質的定義與「對我們而言有效的規範」一樣,都是特爾慈「從歷史中獲得規範性」的另一種表達。不過前者因著賦予了時間向度與個體性參與,而取得近似存在主義的意涵,強調科學工作的最終意義並非客觀觀察,而是主動參與,「定義事物的本質就是去重新型塑它……為一個既定的時刻定義基督教的本質,就是去為那時刻形成基督教新的歷史形式。」37

    +

    我們可以將特爾慈對本質的定義總結成:「本質是一個直覺的抽象,一個宗教與倫理的判準,一個適應發展的概念和為著未來而被應用在型塑與結合的工作中之理念。」38 特爾慈認為哈納克對「基督教的本質」的討論之魅力所在正因為符合了對本質的瞭解,做到了結合神學中的歷史要素與規範性要素。相反的,其他人執著於對純粹歷史方法的客觀性追求則徹底誤解了問題的本質。事實上,

    + +
    +

    人們越少自我欺騙,企圖在理論上逃避主觀主義,越能自由地在實際上對它設下限制以除去危險。這最終並非一個徹底的、任意的主觀主義,將任何偶然建議自身的事物都當作本質。這是一個從最具意識與全面的歷史研究中,與從真實歷史學習的意願中形成判斷的問題。這種歷史的工作是處於現代歷史科學融貫的觀點中,它總是在自身之內修正相反的事物,並推進一致的歷史概念。這樣這些就是使判斷將會是融貫的與一致的之保證,並且嚴肅的科學為著現在去發現真理的企圖將導向一致性的結果。39

    +
    + +

    這樣,一方面因著意識到主觀性不可忽視的存在,使得參與工作的人有可能謹慎小心;另一方面是歷史科學本身的預設保證了其判斷的一致性,使得主觀主義得以被適當的限制。但也因此定義本質這種創造歷史的行動並不是所有人都能參與,而是屬於那些有資格的優秀學者的工作。

    +

    最後,特爾慈同意哈納克的看法,認為新的新教不能再以道成肉身的基督論作為信仰的中心,因為「問題在於對新的新教而言,上帝信仰與歷史的關係改變了……信仰與歷史不再藉著道成肉身之基督論的形式相互作用,現在能被經驗到的事物必須被置於歷史之上。」40 但他認為哈納克沒有將歷史的與規範的兩者做清楚的劃分,哈納克使歷史研究不夠獨立,規範的工作又不夠自由。他認為若能將兩者做一種「暫時性與假設性」的區隔,則歷史研究可以擺脫哈納克只注意觀念發展的簡單連續性,而邁向注重宗教觀念與社會處境及世俗力量的緊密關連,認識到基督教觀念發展更豐富的可能性;另一方面,定義本質的規範性任務也可以「作為未來發展的基礎與作為信仰教導的材料,而清楚地與純粹歷史的工作區隔。」41 不過這種區隔是基於歷史與歷史哲學在方法論上的不同性質,生命與知識將再度把兩者統一起來。神學任務就是存在於兩者的統一當中,因為「基督教同時是歷史與信仰」。42

    + + +

    歷史中的信仰

    + +

    十八世紀時萊辛首先提出歷史與信仰之間有著無法跨越的鴻溝,這個問題的性質是在於偶然真理與必然真理有著絕然不同的價值,只有後者才有資格做為理性的基礎。史萊馬赫以「上帝意識」來化解其中的張力;立欶爾學派藉著倫理範疇中的價值判斷將兩者連結起來,不過仍然預設著歷史事實本身不能作為信仰對象,能夠延續到現今的只有耶穌所教導的天國倫理。特爾慈則藉著將歷史與規範、歷史與歷史哲學之間做出劃分,將兩者在立欶爾學派中的倫理範疇聯繫給切斷了,承認基督教同時分屬兩個不同領域,必須應用不同的方法論加以處理。

    +

    特爾慈認為,造成歷史與信仰之間的分離,首要因素在於現代世界的特徵,

    + +
    +

    在每一個領域中,包括宗教領域,現代世界得以被肯定,是通過以個人的洞見來確立認知判斷的普遍有效性。唯有當宗教真理包含在理性的本質之中,而且因此享有理性所具有的普遍有效性,亦即信仰可以由理性衍生之時,宗教的自主性才可能導致普遍認同的判斷及異口同聲的確信。這種態度暗示著,信仰與歷史的權威分離,信仰必須建立在自己的基礎上面。……否則,信仰只不過是在形式上變成毫無價值的相信權威,在實質上也只不過是碰巧出生於該歷史效應範圍之中。43

    +
    + +

    我們看到,特爾慈認為在現代世界中,信仰緊緊聯繫著個人的理性判斷,因而形式上不能訴諸歷史權威,實質上不能基於歷史偶然性,這等於是完全認同於萊辛所說歷史與理性之間的「大鴻溝」。「信心只能夠與現在及永恆的事物相連,不可能只是與過去及暫時的事物相連。當信仰與歷史事實聯繫時,它將歷史事實轉變成非歷史的現實,成為宣告神永恆旨意的神蹟。道成肉身,使得歷史事實不過是罩以面紗的永恆,或是對永恆的啟示。」44 不過特爾慈並不因此就下結論說,現代世界中的人們已不可能存留信仰,而是指出信仰應與歷史分離開來,以「與現在及永恆的事物相連」。這樣,現代人的信仰是一種個人當下的信仰,「也就是對上帝以及那種當下通過內在體驗達到的永恆世界的確信。」45

    +

    除了暫時與永恆的對比之外,特爾慈還像萊辛一樣,強調我們無法確定第一世紀時究竟發生了什麼事。因為歷史將一切事件轉變為被評論的對象,以致於「實際的歷史研究會顯示,這些歷史基礎只不過是相對的、有條件性的……使得過去可能發生過的事實的畫面成為不確定、甚至是善變的……然而,信仰無法容許任何的含糊性,也無法建基於學識。因此,信仰撤退到不需受歷史檢驗的地位。」我們再次看到,特爾慈並不認為歷史的不確定性足以摧毀信仰,而是要藉此指出信仰必須「撤退到不須受歷史檢驗的地位。」46 這樣,歷史與信仰的分離正是對信仰的一種保護。

    +

    不過歷史與信仰的分離,只意味著信仰不再直接以歷史事件或歷史人物為其對象,並不表示歷史與信仰之間不再有任何關連。特爾慈從宗教心理學的角度來討論基督教信仰與歷史之間的聯繫。首先,信仰不是產生於信仰者的主體,而是偉大時代中傑出人物的創造,因此「信仰者需要把整個觀念世界集中到其出發點上,並將其體現在某種原形之中,以便能夠不斷地修正自己,使自己重新獲得生命力。」47 這種原形就是宗教創立者的人格,能為信仰提供方向和動力。從這個角度看來,「信仰依賴於歷史,但不僅僅是為了吸取營養和獲得知識;毋寧說,信仰本身的自我理解就依賴於歷史,依賴於信仰所尋求的啟示在歷史中的具體化。」48 其次,基督教信仰所說的「救贖」不是依靠個人的努力,而是來自基督所啟示出來的上帝,因此「即使在救贖方面,信仰也必須牢固地把握它與歷史泉源之間的聯繫。」49 第三,基督教所創造的群體需要團結與界定,而「落實的方法只有在認識或共同辨認出導致他們存在的歷史力量過程中才能找到……信徒群體必須有意識地建立歷史的關連,找到維繫這個群體的基礎。」50 第四,基督教信仰為了發展和鞏固,必須有一套基督教儀式,它的「主要功用,必須是培養對其起源及創始者、啟示者、英雄的回憶。這種儀式的效力可能是現在的,但卻必定受制於其歷史的根源及落實過程。」51 第五,基督教信仰認為自己是啟示及救贖的最終成就,因此必須對其他文化的宗教採取一個立場。因此基督教信仰必須涉及一種歷史哲學,以一方面將自己與其他宗教聯繫起來,一方面維持自身的最高有效性。總結而言,「內在於信仰本身的心理要求,便促成了信仰與歷史之間的聯繫。」

    +

    信仰與歷史既必須分離,又有本質上的聯繫,成為現代神學的難題。特爾慈認為,「歷史給信仰造成的難題幾乎遠勝於現代形而上學和現代自然科學給信仰造成的難題。」52 特爾慈認為當務之急就是要「保留信仰的歷史關連,但是必須以新的方式加以闡發。」53 就基督教而言,歷史與信仰之間的首要問題在於能否保留某種形態的基督論,「是否仍然能說耶穌對於信仰有任何內在與本質上的意義?」54 傳統的基督論以「道成肉身」來理解歷史上的耶穌,立欶爾學派以耶穌的天國倫理為超越歷史限制的崇高價值。在特爾慈看來,兩者都以歷史為信仰的直接對象。但另一方面,一種不以耶穌為對象的信仰已不再能算是基督教,「即便一個人可以把自己的上帝信仰看作完全倚賴於上帝的內在見證和力量。但是,若沒有基督徒與基督之間有意識的關係,整個基督教信仰都是不可思議的。」55

    +

    特爾慈解決的方法在於把信仰的歷史關連做出「直接」與「間接」的區分。現代的信仰是一種當下的信仰,不再以歷史為直接的對象,「因為人們已經不可能再相信世界歷史曾經有一個完美的開端,六千年後藉著救贖仍然會回到這個開端,或者基督不久就會再度降臨等。」56 那麼當下的信仰又如何與歷史發生關連呢?關鍵在於基督教信仰並非直接臨到個別主體,也不可能由個別主體自發性地產生,而必須透過歷史中的基督教:

    + +
    +

    上帝當下在我們身上所作的工作若要成為現實,只有藉助人們在歷史中對上帝的認識,藉助於在我們身上發生作用、支撐我們並提升我們的宗教力量。所以,對今天的信仰而言,信仰的歷史因素構成了啟示和認識的基礎……這種歷史性言說是不可或缺的,它們具有間接的或歷史的宗教性。57

    +
    + +

    對於基督論而言,這種區分具有什麼含意呢?傳統神學中「道成肉身」的表述方式將歷史的耶穌直接等同於永活的基督,這使得人們必須將與耶穌相關的一切時代處境都不加批判地承受下來,成為信仰的核心要素,同時耶穌也成為上帝在歷史之內的決定性啟示。從歷史批判興起以來,神學家分別以不同的角度尋找「歷史的耶穌」,以說明耶穌對人類歷史持久性的意義。但特爾慈卻認為這種嘗試無法避免個人的主觀要素與信仰立場,58 而且使得基督教信仰暴露在歷史批判的不確定性當中。最終而言,這些神學家追尋「歷史的耶穌」的目的,是要將他放置在人類歷史的中心,以這個歷史人物當作信仰的直接對象。但對現代人而言,「只要人們將人類在地球上的生存追溯和前瞻幾千年來思考,只要人們正視偉大的精神和文化體系的交替與殞落,便不可能將個別人物設想為整個人類歷史的中心。凡此種種印象使耶穌的絕對中心地位和神話無法成立。」59 那麼我們要如何設想一種間接的基督論呢?特爾慈的方法類似前面提過的客勒爾,也就是把「歷史的耶穌」與「信仰的基督」區分開來。不過客勒爾的區分是基於基督是超越歷史的,不受歷史相對性的限制,認為「歷史的耶穌」與信仰無關,信仰是立基於「信仰的基督」。60 但特爾慈不採取這種教義上的理由,它一方面使客勒爾「信仰的基督」不能通過歷史批判的考驗,另一方面使得「歷史的耶穌」與信仰完全分離。特爾慈認為與信仰直接有關的是基督教群體中所發展出的各種「耶穌的形象」,它們有其歷史上的共同根源,就是拿撒勒人耶穌。61

    +

    信仰透過基督教群體,間接地以歷史的耶穌為對象:「假如一個人強調經由群體的中介與由其而來耶穌位格 (Christian personalities) 的活潑影響,他就不是在面對歷史事實,而是面對無限地形態與豐富的持續效果,並且不可能確定什麼是來自耶穌,什麼又是來自之後的時期和現在。」62 如此一來,對耶穌的詮釋脫離耶穌的歷史事實,在信仰群體中發揮持續的力量;而它之所以在信仰群體中發揮力量,是因為來自於歷史事實。我們現在「不會將一切注意力都集中在耶穌身上。耶穌也將不會是對我們的信仰唯一有意義的歷史事實」;63 在早期的著作中〈形上學〉 (Geschichte und Metaphysik, 1898) ,特爾慈就已強調基督教的核心是其「原則」,而非救主個人。64 在〈什麼是「基督教的本質」〉一書中,他更精確的闡述這個立場。他先肯定耶穌作為基督教的起源,具有根本上的重要性。但我們並沒有辦法將耶穌的真正面貌從使徒的影響中區別出來,另一方面,耶穌的教導並沒有帶出單一的倫理觀,而是包含「此世—末世」的兩極對立,在不同的時代處境中這種兩極對立將會展現不同的教會生活形態。65 不過這不是說我們只要重視之後的發展,因為在「起源」與「發展」的互動中,「起源」仍具有優先性。66 這樣理解的好處是在於,基督教仍然間接地以「歷史上的耶穌」為信仰對象,但這種信仰不用受到「歷史學家的耶穌」之分歧性左右,「批判地考察《聖經》的原始記載不可能動搖宣道和位格的基本特徵,將後來經驗性宗教力量與偉大、全能的原型聯繫起來,也決不是宗教思想不可容忍的事情。」67

    +

    保持作為信仰的基督之耶穌形象的歷史根源,可以使其免去任意性,也保障了信仰的真實性。在一九一一年〈耶穌的歷史存在對信仰的意義〉 (Die Bedeutung der Geschichtlichkeit Jesu für den Glauben) 中,特爾慈要說明歷史的耶穌與信仰的間接關連。此文的背景是回應杜魯 (Arthur Drew, 1865-1935) 與詹森 (Peter Jensen, 1861-1936) 的觀點,他們在歷史批判對於拿撒勒人耶穌的研究,已呈現極端分歧的情況下,否認耶穌是一個歷史人物,認為耶穌只是一個神祇(杜魯)或神話人物(詹森),在基督教信仰中純粹只扮演一種象徵的功能。特爾慈同意他們「象徵」 (symbol) 的觀點,但認為「耶穌是基督教信仰的象徵……是根植於歷史的事實性。」68 也就是說,特爾慈不願意將「歷史的耶穌」與「信仰的基督」完全分離,因為只有具備堅實歷史基礎的基督,才能對信仰產生真實的意義。如同對一個基督徒而言,

    + +
    +

    上帝不是一個觀念或可能性,而是一個神聖的實體。他也將會把這個象徵堅守在實際生活的堅實基礎上。對他而言,一個真實的人曾如此生活、掙扎、相信與奮鬥,是一個真正具有意義的事實。而且從這一個實際的生活中,他獲得力量與確實性。對他而言這是一個真實的象徵,其背後是超越與真實的宗教先知的偉大。不但上帝藉此而成為可見的,他也可以在此發現對自身不確定性的支持與力量,就如同他在別處需要保有超越人格之宗教權威,並在生活中用各種方式經驗它。69

    +
    + +

    特爾慈接著說,歷史批判足以確認耶穌存在的歷史性,但只有信仰才適於詮釋這個歷史事實。因此,歷史批判所能給與的,「不是各別細節的問題,而是整個耶穌之歷史現象的事實性,以及他的教導的基本輪廓與他的宗教人格。」70 就是這三項,「能夠藉著歷史批判被建立為歷史實體,只要『基督的象徵』在『耶穌的事實』中具有穩固與堅強的內在基礎。」71

    +

    作為信仰與「歷史的耶穌」之中介的,是基督教群體中發展出來的耶穌形象(也就是作為信仰直接對象的「基督」),那麼信仰群體為什麼需要這種形象?特爾慈認為這必須藉助社會心理學(有時候稱「宗教心理學」)來回答。經過了歷史批判後,傳統基督論內容留下來的「只是一個純粹的歷史事實與耶穌在基督教觀念中例喻 (pedagogical) 與象徵的意義」。72 也就是捨棄了將歷史的耶穌賦予神話意含的解釋後,基於社會心理學的考慮,耶穌仍然是基督教社群 (community) 與基督教儀式 (cult) 的中心:

    + +
    +

    沒有社群與儀式,就不可能對上帝的救贖具確定與有力的知識。被基督教觀念所啟發的儀式,會眾必須總是環繞其元首為中心而聚集,藉著浸潤於基督形象所啟示出來的上帝得到滋養與力量。其擴展並非藉著教義、學說與哲學,而是藉著將基督的形象傳遞與保有其活力,並在基督裡敬拜上帝。只要基督教仍然以任何方式存在,它將總是與在儀式中佔中心地位的基督連結。73

    +
    + +

    這樣,特爾慈認為一種可行的基督論必須藉著社會心理學加以闡述。他也像哈納克一樣從早期教會的發展來分析傳統的基督論教義,不過他沒有將此發展理解為一種墮落,而認為必然產生於以基督為中心的社群與儀式:

    + +
    +

    起初基督教信仰者對上帝的信心,並沒有留下空間給教義與學說,而只藉著相信復活,將整個宗教內容專注於耶穌的神聖化……在基督裡敬拜上帝,並在主的晚餐中與基督有活潑的聯合。……為了聚集起來敬拜作為上帝啟示的基督,產生對社群的需要與對儀式的需要。關於基督的教義是產生於這種基督儀式中,它是為了顯示通往基督之內的永恆上帝的途徑,以創造一個新的社群。74

    +
    + +

    特爾慈認為,基督論的教義從一開始就是從儀式與社群而發展出來的,但今天人們「使他們對活的上帝的信仰獨立於任何與耶穌的內在必然性關連。對他們而言耶穌是基督教生活與文化的歷史起點,他的圖像具有例喻的意義或是基督教的象徵,但基督教觀念與耶穌個人概念上的內在必然關連已不再。」75 所謂「概念上的必然關連」是指傳統神學中,耶穌因著具備與生俱來的神性,而在「原罪—救贖」的架構下所扮演救贖者的角色,這種理解如今不再可能:「從教會的道成肉身和救恩信條的含義來討論耶穌在宇宙中的地位和意義,是不可能的。使全人類在耶穌身上達到峰巔,讓顯現在耶穌身上的宗教力量最終征服整個人類,這種設想也很難實現。」76 信仰雖然失去了與基督在概念上的必然關連,上述「社會心理學的法則」仍是有效的,「與他真實的個人關係事實上是不可能的。但也不是說這個人只是一個純粹的歷史事實,簡單地被歸類為起源而不再是本質上的。因為從社會心理學的理由來看,他對於儀式、能力、功效與擴展都是不可避免的。」77 這樣看來,今天我們不能再持有一種教義上的基督論,而只能維持一個社會心理學上的基督論,但後者已經不是作為信仰上的概念內容,而成為科學神學反思的對象。

    +

    問題似乎並沒有解決,假如基督與信仰已失去「概念上的必然關連」,人們還可能以他為社群與儀式的中心嗎?特爾慈認為,當我們把基督從單一化的教義理論釋放出來,他作為一個具體的、活生生的形象,更能有力地啟發我們的信仰:

    + +
    +

    在評估耶穌的意義上,具決定性的並非救贖不可能發生在基督教之外,而是宗教社群需要一個支持、中心,與宗教生活的象徵。新奇的是,中心與象徵並非是被僵化的教義或定型的道德律所構成,卻是在活生生的、具多種面向之形象中,並同時是具鼓舞能力的位格。我們能夠採用其對生命最深的引領,並從中發現對形塑當代宗教與倫理任務之充分自由的應用。78

    +
    + +

    從教義的單一性到形象的多面性之轉變中,特爾慈發現一種面對當代任務「充分自由的應用」。耶穌的形象獲得充分的適應性,繼續作為現代宗教社群的中心與象徵。不過如此一來,耶穌「不能在理論與理解中被發現,而只在想像與情感之內。」79 因此,接續「耶穌的教義」以連結起信仰的,是這種具備生動與自由之「耶穌的形象」。這樣,特爾慈基本上能夠避免萊辛所指相信偶然真理為永恆啟示的困難。因為現在作為信仰直接對象的不是「歷史的耶穌」,而是「耶穌的形象」,並且信仰的方式也不是藉著教義概念,而是藉著「想像」與「情感」,這與理性的必然真理之間沒有什麼衝突。

    +

    特爾慈的基督論與他所設想的「本質」有關。在〈什麼是「基督教的本質」〉中,他反對將任何的教義當作基督教的本質,而認為「接受天國的條件與滿足這些條件的社群,對我們而言才是本質。」80 而在對基督論問題的討論中,他再度說「從宗教史與宗教心理學的成果,一個人可以清楚的看到,在所有宗教中有價值的不是教義與觀念,而是儀式與社群。」81 從這種對「本質」的觀點看來,將基督論排除在信仰概念之外,並不是貶低或犧牲基督在信仰中的角色,而是將「外皮」(教義)中的基督剝去,以賦予基督真正「核心」(儀式與社群)的地位。事實上,基督雖然失去了他與信仰在概念上的必然連結,但這不是說他與信仰概念不再有任何關係,因為「除了共同的耶穌信仰之外,並沒有其他某種基督教精神共同體的凝聚力量;不把耶穌看成是固有的基督教上帝思想具有創造生命力量的化身,便不可能保有這種上帝思想的活力」。82 這樣,耶穌事實上仍是基督教上帝思想的「化身」,他不在任何必然概念之中,卻能成為一切基督教群體的「凝聚力量」。

    +

    將耶穌從教義概念轉移到具體形象,還會產生另一個重要的後果。過去的基督論,視耶穌的歷史為神聖的權威,再將基督教的超越性建立其上,這使得基督論本身具備護教學的功能。特爾慈將所強調具體形象的耶穌,其影響力主要發揮在基督教社群之中,使基督論不再具備排他性的功能,「我們的靈魂被基督教的上帝信仰之宏偉所佔據,這引導我們承認耶穌,而非相反的程序。」83 因此在優先次序上,我們必須先肯定基督教信仰,才會藉著耶穌進入這個信仰。從某個意義來說,耶穌的生命力必須靠基督教信仰來維持,「只要先知—基督教的上帝信仰具有生命力,耶穌也將為這艘船保持著生命力;只有在對這樣一個人物的仰望中信仰才會上昇,成為超越平庸、懦弱、貧乏的力量和確定信念。如果達到這一點,那麼,隨著基督教信仰力量的增強,耶穌形象也將保持其生命力。」84

    +

    特爾慈雖然堅持基督在信仰中的中心地位,但從近代基督論發展的角度看來,他卻已走上了最極端的道路。傳統的基督論有其獨立的論題及範圍,也就是專注於討論耶穌的神人二性。史萊馬赫在《基督教信仰論》中將基督論的問題放在「意識到神恩之基督徒狀態」的標題之下,也就是將基督論放在整個救贖論的架構之中,以致於「耶穌是誰」是在說明「耶穌為我們做了什麼」之下才有意義;耶穌因著具備「經常充沛的上帝意識」,以致「救主挾著信徒們入至他的上帝意識能力之內,而這就是他的拯救行動了。」85 到了立欶爾學派,我們看到一個只有崇高的倫理教導而沒有拯救行動的基督,基督論開始脫離耶穌的神性,只留下倫理性與宗教性。在特爾慈看來,「耶穌是中心」只有在基督教群體之內才有意義,而沒有普世性的意義,使得基督不但失去了他在傳統神學中的神性,也失去了他在立欶爾學派中倫理上與宗教上的絕對性。「人類歷史時間無比久遠,發展與聯繫存在著巨大變化,並有中斷的可能性。不同文化和不同人類群體獲取的靈性千差萬別。這一切似乎造成了如下的情形:除了基督教以外,始終可能存在著一些宗教性的生活關聯體,它們各自擁有自己的救主和原型。」86

    +

    但相關的問題再度出現,即使在基督教群體之內,失去絕對性的基督還能作為信仰的對象嗎?人們能夠憑著社會心理學的理由敬拜基督嗎?事實上,特爾慈並沒有簡單地將基督的意義限定在社會心理學的層面,「耶穌的形象」也不單單是「歷史的耶穌」無限的變形。前面提過,雖然特爾慈強調「耶穌的形象」具有多面性的豐富發展,但這種發展與「歷史的耶穌」之間仍然具備經得起歷史批判的連續性,也就是耶穌的歷史性、教導的基本輪廓與他的人格。這種連續性使「耶穌的形象」有著超越社會心理學的基礎,它不單單是宗教社群構想出來的「形象」,其背後延續著耶穌的「人格」(有時稱耶穌的位格: person of Jesus ):「不論從那一種意義上將基督教上帝思想與耶穌這一位格分離開來,都意味著切斷此一信仰的所有既往之根,使之脫離一切表述與直觀手段,使之失去一切超越平庸個體的偉大光輝,並因此而最終使其自身限於解體。」87

    +

    其次,「耶穌形象」是上帝在「歷史的耶穌」之外的繼續啟示,也是對我們而言最高的啟示。在〈什麼是「基督教的本質」〉一文中,特爾慈提到基督教是「在基督與聖靈中的信仰」,而聖靈繼續在歷世歷代基督教群體中工作,以不同的方式產生新的形式與改革,以此說明基督教之後的發展也有本質上的重要性。88 同樣的,「耶穌的形象」脫離了「歷史的耶穌」後,不只具有社會心理學與文化上的含意,而是上帝啟示的延伸,「原始教會的信仰將基督的靈從歷史呈現中脫離出來,視其為一個能夠發展的原則。」89 這樣,特爾慈仍然保留傳統神學中「耶穌是上帝的啟示」這個命題,不過將原本含意中的「耶穌」,包含進教會歷史之「耶穌形象」的發展:「對我們而言,『上帝在基督裡』只能表示在耶穌裡我們尊崇著上帝給我們的最高啟示,並且我們使耶穌的形象成為在我們生活領域中所發現上帝證明自己的輻聚點 (rallying-point) 。」90 特爾慈認為,耶穌雖然不具備絕對性,但從歐洲精神文化的發展來看,我們找不到更為質樸有力的宗教啟示:

    + +
    +

    對於我們的生存圈來說,體現和直接展現於先知學說和耶穌身上的宗教信仰、以耶穌為出發點的更高的人類精神,永遠是我們在上帝身上可以找到的和我們能確定的生活中,最深刻、最強大的泉源。我們感覺到自己佇利於上帝面前,站在耶穌放射出的巨大光還之中,我們的任務只是遵循著這條為我們規定的途徑,在我們被上帝把握住之後,實實在在地經歷和把握住上帝。91

    +
    + +

    再者,特爾慈認為「耶穌形象」與個別信徒間有一種神祕的關係,他稱這種看法為「基督神祕主義」:「基督—神祕主義認為,每一個信徒都感道自己是這一中心點的輻射。耶穌是上帝的啟示,使我們超越自身,他歷經千百年世界歷史的作用而得到加強,所有信徒在對耶穌的虔敬領悟和敬拜中,不斷重新連結起來。如果說存在著一種真實的基督信仰的話,這便是這類信仰的核心。」92 因此發生在信徒與創始者之社會心理學聯繫背後的,「是一種與信徒的元首具有內在聯繫的基督神祕主義:從這一元首產生的力量和生命移注於其肢體。而且,在這元首作為上帝啟示而臨在的過程中,完成基督教的固有禮拜儀式。」93

    +

    這樣,耶穌的位格脫離了歷史的束縛,使得歷史中每一個個體得以在自己的時代中,通過與耶穌的神祕聯繫來到上帝那裡。基督雖然失去了絕對性,卻能夠真正作每一個時代的基督,作每一個個體的基督。特爾慈的基督論因此能夠以蘭克 (Leopold von Ranke, 1795-1886) 的用語恰當的表述出來,「任何時代都直接面對上帝,而我們恰恰是一同佇立於基督輻射開來的光環中而直接面對上帝。」94

    + + + +
    + 回目錄 +
    + +
    +
    +
    * 本文為作者碩士論文《特爾慈的現代意識與歷史思維—海德堡時期, 1894-1914 》之一節,今略經修改後刊登於本刊。 (Back)
    +
      +
    1. 洛維特 (Karl Löwith) ,《世界歷史與救贖歷史》,李秋零、田薇譯(香港:漢語基督教文化研究所, 1997 ), 240-253 。 (Back)
    2. +
    3. Welch, Protestant Thought in the Nineteenth Century, Vol. 2: 1870-1914 (New Haven: Yale University Press, 1974), 178-180. (Back)
    4. +
    5. Welch, Protestant Thought in the Nineteenth Century, Vol. 2, 146. (Back)
    6. +
    7. Drescher, Ernst Troeltsch: His Life And Work (Minneapolis: Fortress Press, 1991), 390, notes 108. (Back)
    8. +
    9. 葛倫斯、奧爾森︰《二十世紀神學評論》,劉良淑、任孝琦譯(台北︰校園書房, 1998 ), 70 。 (Back)
    10. +
    11. Welch, Protestant Thought in the Nineteenth Century, Vol. 2, 148. (Back)
    12. +
    13. Welch, Protestant Thought in the Nineteenth Century, Vol. 2, 149. (Back)
    14. +
    15. 迦克墩信經中說:「我們的主耶穌基督,是神性完全人性亦完全者……具有二性,不相混亂,不相交換,不能分開,不能離散」,湯清編譯,《歷代基督教信條》(香港:基督教文藝, 1989 ), 24 。 (Back)
    16. +
    17. 麥葛福 (Alister E. McGrath) ,《基督教神學原典精華》,楊常慧譯(台北:校園書房, 1998 ), 199 。 (Back)
    18. +
    19. 麥葛福 (Alister E. McGrath) ,《基督教神學手冊》, 370-373 。 (Back)
    20. +
    21. 士萊馬赫,《宗教與敬虔》,謝扶雅譯(香港:基督教文藝, 1991 ), 444 。 (Back)
    22. +
    23. 麥葛福 (Alister E. McGrath) ,《基督教神學手冊》, 377-380 。 (Back)
    24. +
    25. 本文的英譯者 S. W. Sykes 詳細討論了兩個版本的不同之處,其中值得我們注意的是 1913 年的修改反應了大量在《基督教社會思想史》中的研究取向與成果,包括嚴格區分「價值關聯」與「價值判斷」;將保羅與耶穌視為具根本差異的兩個基督教要素;對基督教未來的前景抱持保留的態度;認為應考慮倫理與宗教觀念的社會處境等。但以下我們著重於討論特爾慈對史學方法在定義本質上扮演的角色,因此不會特別討論與這些通過宗教社會學研究後的立場,相關討論可見於《特爾慈的現代意識與歷史思維—海德堡時期, 1894-1914 》第四章。關於 1903 與 1913 兩種版本的比較,參 S. W. Sykes, “Note by S. W. Sykes,” Ernst Troeltsch: Writings on Theology and Religion, trans. & edit. Robert Morgan and Michael Pye (London: Duckworth, 1977), 180-181. (Back)
    26. +
    27. Ernst Troeltsch, “What Dose ‘Essence of Christianity’ Mean?” in Ernst Troeltsch: Writings on Theology and Religion, 124-127. (Back)
    28. +
    29. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 129. (Back)
    30. +
    31. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 130-131. (Back)
    32. +
    33. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 132. (Back)
    34. +
    35. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 134. (Back)
    36. +
    37. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 135. (Back)
    38. +
    39. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 137-138. (Back)
    40. +
    41. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 139-141; 這裡的「教會」、「小派」與「神秘主義」都是特爾慈在《基督教社會思想史》中所使用的「理想形態」,有其社會學上的指涉。 (Back)
    42. +
    43. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 140-142. (Back)
    44. +
    45. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 142-145. (Back)
    46. +
    47. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 146-147. (Back)
    48. +
    49. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 148-149. (Back)
    50. +
    51. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 151. (Back)
    52. +
    53. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 153. (Back)
    54. +
    55. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 154. (Back)
    56. +
    57. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 156-159. (Back)
    58. +
    59. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 158. (Back)
    60. +
    61. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 158. (Back)
    62. +
    63. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 159. (Back)
    64. +
    65. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 159-160. (Back)
    66. +
    67. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 160. (Back)
    68. +
    69. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 161. (Back)
    70. +
    71. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 161. (Back)
    72. +
    73. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 162. (Back)
    74. +
    75. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 164. (Back)
    76. +
    77. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 167. (Back)
    78. +
    79. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 173-174. (Back)
    80. +
    81. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 178. (Back)
    82. +
    83. Troeltsch, “What Dose ‘Essence of Christianity’ Mean?,” 179. (Back)
    84. +
    85. 特爾慈,〈信仰與歷史〉 (1910) ,《基督教倫理與現代》,劉小楓編,朱雁冰等譯(香港:漢語基督教文化研究所, 1998 ), 268 。 (Back)
    86. +
    87. 特爾慈,〈信仰與歷史〉, 268-269 。 (Back)
    88. +
    89. 特爾慈,〈信仰與歷史〉, 268-269 。 (Back)
    90. +
    91. 特爾慈,〈信仰與歷史〉, 269 。 (Back)
    92. +
    93. 特爾慈,〈信仰與歷史〉, 265 。 (Back)
    94. +
    95. 特爾慈,〈信仰與歷史〉, 265 。 (Back)
    96. +
    97. 特爾慈,〈信仰與歷史〉, 266 。 (Back)
    98. +
    99. 特爾慈,〈信仰與歷史〉, 266-267 。 (Back)
    100. +
    101. 特爾慈,〈信仰與歷史〉, 266-267 。 (Back)
    102. +
    103. 特爾慈,〈信仰與歷史〉, 271 。 (Back)
    104. +
    105. 特爾慈,〈信仰與歷史〉, 275 。 (Back)
    106. +
    107. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” Ernst Troeltsch: Writings on Theology and Religion, 182. (Back)
    108. +
    109. 特爾慈,〈信仰與歷史〉, 265 。 (Back)
    110. +
    111. 特爾慈,〈信仰與歷史〉, 275 。 (Back)
    112. +
    113. 特爾慈,〈信仰與歷史〉, 276 。 (Back)
    114. +
    115. Troeltsch, “What Does ‘Essence of Christianity’ Mean?,” 140-142, 159-160. (Back)
    116. +
    117. 特爾慈,〈自由基督教的可能性與現代哲學〉,《基督教理論與現代》(香港:漢語基督教文化研究所, 1998 ), 329-330 。 (Back)
    118. +
    119. McGrath ,《基督教神學手冊》, 379-380 。 (Back)
    120. +
    121. 這裡採用 (Sarah Coakley) 對特爾慈基督論的整理,她將特爾慈的看法對比為「歷史的耶穌」與「許多的耶穌」 (Many Christs) 。 Sarah Coakley, Christ without Absolutes: A Study of the Christology of Ernst Troeltsch (New York: Oxford University Press, 1994), 183-184. (Back)
    122. +
    123. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 189. (Back)
    124. +
    125. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 201. (Back)
    126. +
    127. Drescher, Ernst Troeltsch: His Life and Work, 91. (Back)
    128. +
    129. Troeltsch, “What Does ‘Essence of Christianity’ Mean?,” 146-149, 153-156. (Back)
    130. +
    131. Troeltsch, “What Does ‘Essence of Christianity’ Mean?,” 156. (Back)
    132. +
    133. 特爾慈,〈自由基督教的可能性與現代哲學〉, 331 。 (Back)
    134. +
    135. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 197. (Back)
    136. +
    137. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 197-198. (Back)
    138. +
    139. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 198. (Back)
    140. +
    141. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 198. (Back)
    142. +
    143. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 193. (Back)
    144. +
    145. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 196. (Back)
    146. +
    147. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 195. (Back)
    148. +
    149. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 190. (Back)
    150. +
    151. 特爾慈,〈自由基督教的可能性與現代哲學〉, 332 。 (Back)
    152. +
    153. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 197. (Back)
    154. +
    155. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 202. (Back)
    156. +
    157. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 195. (Back)
    158. +
    159. Troeltsch, “What Does ‘Essence of Christianity’ Mean?,” 153. (Back)
    160. +
    161. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 194. (Back)
    162. +
    163. 特爾慈,〈自由基督教的可能性與現代哲學〉 (1910) , 330 。 (Back)
    164. +
    165. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 189. (Back)
    166. +
    167. 特爾慈,〈自由基督教的可能性與現代哲學〉 (1910) , 331 。 (Back)
    168. +
    169. 士萊馬赫,《宗教與敬虔》, 445 。 (Back)
    170. +
    171. 特爾慈,〈自由基督教的可能性與現代哲學〉 (1910) , 332 。 (Back)
    172. +
    173. 特爾慈,〈自由基督教的可能性與現代哲學〉 (1910) , 330 。 (Back)
    174. +
    175. Troeltsch, “What Does ‘Essence of Christianity’ Mean?,” 149-150. (Back)
    176. +
    177. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 203. (Back)
    178. +
    179. Troeltsch, “The Significance of the Historical Existence of Jesus for Faith (1911),” 206. (Back)
    180. +
    181. 特爾慈,〈自由基督教的可能性與現代哲學〉 (1910) , 333 。 (Back)
    182. +
    183. 特爾慈,〈自由基督教的可能性與現代哲學〉 (1910) , 331 。 (Back)
    184. +
    185. 特爾慈,〈自由基督教的可能性與現代哲學〉 (1910) , 334 。 (Back)
    186. +
    187. 特爾慈,〈自由基督教的可能性與現代哲學〉 (1910) , 333 。 (Back)
    188. +
    +
    + +
    + 回目錄 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/004/article02.html.html b/htdocs/htc/newsletters/004/article02.html.html new file mode 120000 index 0000000..fad4a1e --- /dev/null +++ b/htdocs/htc/newsletters/004/article02.html.html @@ -0,0 +1 @@ +article02.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/004/article02.html.xhtml b/htdocs/htc/newsletters/004/article02.html.xhtml new file mode 100644 index 0000000..0c7daea --- /dev/null +++ b/htdocs/htc/newsletters/004/article02.html.xhtml @@ -0,0 +1,464 @@ + + + + + + + + + + + + + + + + + + + + +論朵伊森作品《希臘化時代史》的神意史觀與神義論思想 + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    論朵伊森作品《希臘化時代史》的神意史觀與神義論思想*

    + +
    陳致宏
    + +

    一、「希臘化時代」:概念的起源與演變

    + +

    「亞歷山大這個名字象徵著一個世界史階段的終結,以及另一個階段的開端。」1 德國史家朵伊森 (Johann Gustav Droysen, 1808-1884) 是第一位將自馬其頓的亞歷山大大帝 (Alexander III, der Große, 356-323 B.C.) 統一希臘與東征開始至羅馬帝國時期為止的這段歷史視為一個完整歷史階段的史家。這個亞歷山大所開創的歷史階段,朵伊森稱之為希臘化時代,其德文為 Hellenismus 。傳統史家將亞歷山大所終結的希臘古典時代視為一去不復返的美好時代,而亞歷山大大帝征服希臘以後的時代則為介於希臘古典與羅馬帝國之間一段黑暗而混亂的過渡時期。朵伊森是第一位體認到希臘化時代重要性與積極因素的史家,他認為希臘化時代不是介於光輝的希臘古典時代與羅馬帝國時代之間的過渡,而是具有重要世界史意義的獨立歷史階段。2

    +

    Hellenismus 一詞來自希臘文的動詞 Hellenizein 而來,在目前所知的希臘文典籍裡這個字最早出現在修昔的底斯 (Thukydides, ca. 460-400 B.C.) 作品的第二章第六十八節裡:「之後的幾代在災難的打擊之下,他們〔阿哥斯 (Argos Amphilochion) 人〕招徠安斐洛基亞 (Amphilochia) 地區邊境上的鄰居安布拉基亞 (Ambracia) 人加入他們的殖民地;正是因為與安布拉基亞人的結合,他們學會了現在所使用的希臘語,而其他安斐洛基亞地區的人則仍然是野蠻人。」3

    +

    在這段文字之中值得注意之處有二:第一,「他們學會了現在所使用的希臘語」原文的意義為「他們在語言上被 Hellenizein 」,在提到語言被同化的時候,使用 Hellenizein 這個動詞時還要特別強調是語言這個方面,可以推測出 Hellenizein 這個動詞所包含的意義應不僅限於語言上被希臘同化,這個動詞所包含的應該是更廣義的在文化或生活習俗上的希臘化。4 第二,文中把野蠻人拿來和說希臘語的人相對,這裡的野蠻人原文為 barbaroi ,原意就是非希臘人,因為對希臘人來說非希臘人所說的語言聽起來就像 “barbar” 這樣毫無意義的聲音,所以分辨希臘人與非希臘人主要重點就在於語言,而語言則是可以透過同化而改變的。

    +

    在希臘化時代,由 Hellenizein 衍生出了 Hellenizein 這個詞。「次經」 (Apokryphen)5 的《馬加比書》 (Makkabaion) 記錄了希臘化時代猶太人國家與希臘化王國塞流古王朝 (Seleukide) 相對抗的歷史,在《第二馬加比書》的第四章第十三節提到「透過耶孫 (Jason) 這個不配大祭司之名的瀆神者過份的褻瀆作為,希臘的風俗到達了頂峰,而異邦的習尚也大為增加。」6 這段文字所指的「希臘的風俗」原文就是 Hellenismos ,文中具體提到耶孫這位大祭司所採用的希臘風俗,包括了拋棄猶太人祖先的信仰與習俗而接納希臘的運動競技,建立希臘式的體育館 (Gymnasion) ,仰慕希臘文化、以及崇拜希臘神祇等等。甚至有不少猶太人也採用希臘名字,像引文理所提到的大祭司,他的名字「耶孫」正是希臘式的。所以 Hellenismos 所包含的層面非常廣,不僅限於語言的層次而已。

    +

    受到希臘風俗影響的人被稱為 Hellenistes ,這個字原本的含義是指說希臘語的人。《新約.使徒行傳》的第六章第一節提到了「那時、門徒增多、有說希利尼〔即希臘〕話的猶太人、向希伯來人發怨言.為在天天的供給上忽略了他們的寡婦。」7 而第九章第二十九節也提到「〔掃羅〕奉主的名、放膽傳道.並與說希利尼話的猶太人、講論辯駁.他們卻想法子要殺他。」8 這兩段文字當中的「說希利尼話的猶太人」,其希臘文原文就是 Hellenistes 。

    +

    總之, Hellenizein 、 Hellenismos 與 Hellenistes 這三個字在古代文獻中幾乎都會出現在與非希臘要素相互並列比較的場合,所以這三個字有很強烈的文化同化與融合的含義,而希臘與非希臘元素的接觸與交融,正是自亞歷山大東征之後上古世界的發展主題。 Hellenismos 這個單字字尾拉丁化之後成了 Hellenismus ,這個詞到了德文裡也是泛指希臘的文化與風俗,以及對希臘文化風俗的喜好和採納。

    +

    在朵伊森的手上, Hellenismus 一詞又得到了新的意義,他將 Hellenismus 拿來指從亞歷山大大帝到屋大維 (Gaius Octavianus, 63 B.C.-14 A.D.) 於阿克提烏姆 (Actium) 打敗安東尼 (Marcus Antonius, ca. 80-30 B.C.) 並結束了埃及的托勒密王朝 (Ptolemäer) 為止的這一段希臘人與非希臘人之間緊密交流的時期的歷史與文化。從此以後, Hellenismus 就成為這一個歷史階段的名稱,而中文的「希臘化時代」所指的就是朵伊森賦予 Hellenismus 這個詞的意義。

    +

    朵伊森的《希臘化時代史》是西洋史學史上第一部將希臘化時代視為一個獨特時代而研究的重要作品。在朵伊森之後,歷史學界開始重視到這段歷史時期的重要性,許多上古史學者也撰寫自己的希臘化時代歷史,不論在觀點上或史料上多已超越朵伊森時期甚多,但是這些作品在主要的架構上大多仍然無法脫離朵伊森的影響。

    +

    朵伊森之所以會選擇希臘化時代做為他研究的焦點,背後隱含有相當大的信仰因素以及現實意識。而朵伊森在德國歷史主義 (Historismus) 傳統之中獨樹一格,成為建構歷史理論的重要思想家,又與他的信仰與現實關懷有非常密切的關係。本文擬由朵伊森的信仰與宗教觀切入,來探討包含在《希臘化時代史》這部作品之中的意義。

    + +

    二、朵伊森的生平、學術生涯與重要作品介紹

    + +

    朵伊森於西元 1808 年七月六日出生於波美拉尼亞 (Pommern) 的小城特雷普托夫( Treptow an der Rega, 今波蘭境內之 Trzebiatów ),其父約翰.克里斯多夫.朵伊森 (Johann Christoph Droysen) 為普魯士的軍隊牧師。朵伊森自小成長在新教氣氛濃厚的環境之下,而因為父親曾在普魯士名將領布呂赫 (Gebhard Leberecht von Blücher, 1742-1819) 的軍隊裡擔任牧師,朵伊森自小就受到這位著名將領的影響以及對於普魯士對抗拿破崙的解放戰爭 (die Freiheitskriege) 的記憶,這使得他心中充滿了對普魯士的熱愛。日後充斥在他思想中的新教信仰與普魯士愛國主義早在童年就在心中種下不可磨滅的影響了。

    +

    朵伊森於 1826 年進入柏林大學就讀,這個時期的柏林大學籠罩在黑格爾 (G. W. F. Hegel, 1770-1831) 哲學的影響之下。朵伊森每學期都固定會選修黑格爾以及古典語言學教授柏克 (August Boeckh, 1785-1867) 的課程。正因為受到這兩位教授的影響,雖然他主要的研究領域是以古典語言學 (Philologie) ,他的視野不會只侷限在被瑣碎的史料考證研究上,而會更為重視由歷史現象中所所傳遞出來的意義與隱含的目的。9

    +

    1831 年朵伊森提出了博士論文《論托勒密王朝國王托勒密四世的統治》 (De Lagidarum regno Ptolemaeo VI Philometore rege) , 1832 年他出版了古希臘悲劇作家埃斯基洛斯 (Aischylos, 525-456 B.C.) 作品的德文翻譯與評註。在這部作品之中,朵伊森將希臘悲劇放在古代雅典的歷史脈絡來考察,並且呈現出一個古希臘歷史發展的獨特觀點。 1833 年,朵伊森完成了《亞歷山大大帝傳》 (Geschichte Alexanders des Großen) (也就是日後第二版《希臘化時代史》的第一卷),在這部作品中,作者將亞歷山大大帝視為黑格爾哲學中推動世界前進理念的具體體現者。雖然如此,但是這部作品並不是像黑格爾的《歷史哲學》 (Vorlesungen über die Philosophie der Geschichte) 那樣是以玄思為基礎的哲學作品,在朵伊森寫作博士論文,研究托勒密四世時代的歷史之時,就已經替日後希臘化時代歷史的寫作奠下堅實的史料考證基礎了。

    +

    朵伊森在 1833 年通過柏林大學古典語言學系講師 (Privatdozent) 的資格考試,並且很快地在兩年後( 1835 年)便升格為副教授 (Professor extraordinarius) 。10

    +

    在 1836 與 1838 年之間,朵伊森陸續出版了希臘喜劇作家亞理斯多芬尼 (Aristophanes, ca. 445-385 B.C.) 各個作品的德文翻譯。在 1836 年,他完成了《希臘化時代史》 (Geschichte des Hellenismus) 第一卷《亞歷山大後繼者的歷史》 (Geschichte der Nachfolger Alexanders) 。

    +

    1839 年,朵伊森離開了柏林大學,北上到基爾 (Kiel) ,應基爾大學的聘請而成為正教授 (Professor ordinarius) , 1843 年他出版了《希臘化時代史》的第二卷《希臘化時代國家體系形成的歷史》 (Geschichte der Bildung des hellenistischen Staatensystems) 。雖然他原本的計劃是將《希臘化時代史》至少寫到羅馬帝國時代為止,但是完成了此部作品的寫作之後,朵伊森就不再從事希臘化時代歷史的寫作了。朵伊森雖未完全停止上古史的研究,但是此後他就不再寫作像《希臘化時代史》這樣大規模的上古史著作。

    +

    朵伊森之所以停止《希臘化時代史》的寫作,主要是因為基爾這裡的政治氣氛讓他關切的焦點有了轉移。基耳是霍爾斯坦 (Holstein) 侯國北部的重要城市。霍爾斯坦與其北方的什列斯威 (Schleswig) 這兩個侯國與丹麥之間的關係維繫於丹麥國王一人的身上,自從 1815 年開始,丹麥政府就致力於將這兩個侯國(尤其是北部與丹麥接壤的什列斯威)併入丹麥國土。於是在什列斯威與霍爾斯坦便有了傾向德意志與傾向丹麥兩派民族主義者的論戰。大約在朵伊森到達基爾的前後,什列斯威與霍爾斯坦的問題開始日益激烈。在這個問題的爭議中,朵伊森與他在基爾的幾位同事成了在德意志利益的激烈支持者。而也因為對於政治涉入漸深,朵伊森學術研究的焦點也轉移至近代史之上。

    +

    標誌著這個焦點轉移的重要新作是 1846 年出版,總共兩卷的《關於解放戰爭時代的演講》 (Vorlesungen über das Zeitalter der Freiheitskriege) 。這部作品所涵蓋的範圍包括了從美國獨立革命到維也納會議以及神聖同盟 (Heilige Allianz) 這段期間的歐洲史。朵伊森認為到當時為止,這段對歐洲以及德意志影響深遠的歷史階段,所有相關的歷史著作所反映出的都是英國人,甚至是俄國人等外國人的觀點,所以他寫作這部作品的用意,在於提供了一種從普魯士與德意志的立場為出發點而寫作的歷史作品。11

    +

    西元 1843 年是凡爾登條約 (Vertrag zu Verdun) 訂立的第一千週年,西元 843 年,卡洛琳王朝 (Karolinger) 的虔誠者路易 (Ludwig I der Fromme, 778-840) 的三個兒子在凡爾登 (Verdun) 簽訂條約,將由查理曼 (Karl der Große, 747-814) 所奠定基礎的龐大帝國分為三個部份,其中德意志的路易 (Ludwig II der Deutsche, 843-876) 取得了帝國的東部,而這個部份就是日後德國的雛形。因此 1843 這一年被視為德意志帝國建立的第一千週年紀念。朵伊森在基爾大學慶祝凡爾登條約一千週年的紀念演講會上,他發表了一篇充滿煽動性的演講,鼓吹完成德意志的統一和建立君主立憲的國家,並主張歷史作品應在這個方面發揮功用。

    +

    自 1839 年丹麥國王克里斯提安八世 (Christian VIII, 1786-1848) 在位以來,他就一直致力於將什列斯威與霍爾斯坦併入丹麥,使其成為適用丹麥憲法的國家領土,而非使其與丹麥的關係僅維繫在國王個人的身上而已,尤其是較為靠近丹麥的什列斯威更是他努力的目標。 1846 年克里斯提安八世在一封公開信中宣稱這什列斯威與霍爾斯坦兩個公國是丹麥王國整體的一部份,對此朵伊森與其他基爾大學的教授也以一封公開信作為回應,不管丹麥官方的禁令,這封基耳大學教授的公開信仍被印刷發行。丹麥政府原本想要將這些教授解聘,但礙於輿論並未真正動手。朵伊森為了從歷史上找出他主張的論據,便與一位他教過的學生撒姆維 (Karl Samwer) 合著了一本書,名為《什列斯威和霍爾斯坦公國與丹麥王國》 (Die Herzogtümer Schleswig und Holstein und das Königreich Dänemark) 。12

    +

    1848 年法國革命的風潮蔓延到了什列斯威與霍爾斯坦,三月底臨時政府成立。朵伊森被臨時政府任命為代表,被派往法蘭克福參與法蘭克福國民會議 (Frankfurter Nationalversammlung) 。在會議成員分別黨派之時,朵伊森加入了中間偏右的卡西諾黨 (Casinopartei) ,這個黨派主張統一與立憲的政體,反對社會革命,他們不遺餘力地鼓吹由普魯士主導邁向德國的統一。這個黨派大部分的成員是大學教授與律師,且多為北德人。卡西諾黨與中間偏左,且以西南德人為主的符登堡庭院 (Württembergische Hof) 黨之間有過數次激烈而冗長的辯論。

    +

    朵伊森在法蘭克福國民會議之中最重要的作為,就是他參與了制憲會議。朵伊森在勾畫未來統一德國的藍圖之時,將奧地利排除在外,因為他認為奧地利的領土包含了非德意志民族的部份,而一個統一的德意志民族國家,若包含了非德意志民族的領土,就會有無窮的後患。這種排除奧地利,支持以普魯士為首而統一德國的主張被稱為小德意志主義 (Kleindeutschtum) 。

    +

    1849 年三月二十八日,法蘭克福國民會議透過投票推舉普魯士國王腓特列.威廉四世 (Friedrich Wilhelm IV, 1795-1861) 為德意志帝國的皇帝,四月三日,法蘭克福國民會議的主席與一些代表到柏林,將德意志帝國的皇冠獻給腓特列.威廉四世,卻被普王所拒絕,而普魯士政府更宣佈拒絕接受法蘭克福國民會議所制定的憲法。這意味著普魯士政府正式地與法蘭克福國民會議決裂。國民會議的成員面臨了這樣的打擊,便徘徊在解散或是爆發革命的兩種極端選擇之間。包括朵伊森在內的大多數中間派成員都選擇了放棄努力,離開法蘭克福。對朵伊森來說,沒有普魯士的積極參與,任何統一德國的努力都是徒然的,而企圖訴諸革命的做法更是不智,因為這會使普魯士的保守傾向更為加強,向奧地利與俄國靠攏。

    +

    日後法蘭克福國民會議時期的卡西諾黨在哥達 (Gotha) 又有黨派聚會的活動,但是對於這個聚會,朵伊森不願參與,而且他對這個活動的正當性也不表認可。因為國民會議的失敗,讓他更深刻地體認到德國統一的問題是權力的問題,權力掌握在政府手上,而非掌握在像他這樣的大學教授手上,因此他認為這個權力的問題應該留給普魯士的政權,讓政府自己找到方法來解決。他認為德國的統一不能透過自由來爭取,而是一個純粹的權力問題。他認為德意志民族的前途完全依賴在普魯士的手上,並主張普魯士不能以作為僅次於奧地利的德意志第二強權為滿足,普魯士的歷史使命就是成為德意志的強權,領導德國走向統一。這樣的見解在精神上與日後俾斯麥 (Otto von Bismarck, 1815-1898) 所推行的鐵血政策相當符合。13

    +

    朵伊森站在德國的利益,主張普魯士有責任介入什列斯威.霍爾斯坦問題,因此開罪了丹麥政府。 1851 年,朵伊森為了自身安全的考量,決定接受耶拿 (Jena) 大學的邀請,離開基爾,到耶拿任教。在耶拿任教了不到十年,又於 1859 年應柏林大學的聘請而回到了他的母校任教,此後他就在柏林從事教學與研究的工作,直到 1884 年過世為止。

    +

    在耶拿的時期,他完成了普魯士元帥約克 (Feldmarschall Hans David Ludwig York von Wartenburg, 1759-1830)14 的傳記,這部作品朵伊森在基爾時期就已經開始寫作,在這部傳記之中,他把約克元帥描寫為普魯士精神的具體體現者。這部作品廣受好評,到他過世之時已經發行到第九版;此外,他也開始從事《普魯士政治史》 (Geschichte der preußischen Politik) 這部鉅著的寫作,朵伊森到了柏林之後仍然繼續這項工作,直到他過世之時仍未全部完成。

    +

    值得注意的是,雖然朵伊森自基爾時期就已經把主要的研究寫作方向轉向普魯士的歷史,但在 1877-78 年他又開始從事《希臘化時代史》的改版工作,在這次出版的《希臘化時代史》第二版中,《亞歷山大大帝傳》被納入這套作品之中,成為《希臘化時代史》第二版的第一卷,而原本第一版的第一卷就成了第二版的第二卷,名為《繼承者的歷史》 (Geschichte der Diadochen) ,原第一版的第二卷就成了第二版的第三卷,名為《延續者的歷史》 (Geschichte der Epigonen) 。朵伊森並未在這次的改版中增加新的內容,不過為了因應《亞歷山大大帝傳》的加入,為了讓這三冊作品之間更具連貫性、整體性,朵伊森在內容的安排上做了一些更動,這些更動主要是因為原《亞歷山大大帝傳》的加入,為了讓這三冊能成為一個整體,所以在內容的順序上做了一些更動。除此之外,朵伊森在新版中也把原有文辭大量地重新潤飾,並且加入了一些新的史料。大致上說來,在兩個版本之中作者所呈現出來的歷史觀念並未有根本上的改變。15 在 1952-1953 年,拜爾 (Erich Bayer) 依據朵伊森自己改編的《希臘化時代史》第二版將此書重新編輯出版,在這個版本之中,編者把原本第一版第二卷的作者前言納入這個版本之中,這個前言的標題名為〈歷史的神學〉 (Theologie der Geschichte) ,在其中朵伊森充分地闡釋他對歷史的看法,不過這篇文章因為內容太過強調作者私人的宗教信念,所以朵伊森在世時並未讓這篇前言隨著《希臘化時代史》第一版第二卷的發行而公開印行,只有私底下在作者的幾個朋友之間流傳,這個前言直到他過世之後才被公開。本文從《希臘化時代史》引述的引文,除非特別註明,否則都是出自拜爾所編的這個版本。

    +

    朵伊森在西洋史學史上最大的貢獻大概就是他在史學方法與史學理論上的重要作品。早在朵伊森年輕時,就因為在寫作《希臘化時代史》的過程中深刻地體認到替歷史這門學科建立一套獨自方法與理論的重要性。作者在《希臘化時代史》名為〈歷史的神學〉的序言之中就很明白地表示他這部作品背後所牽涉的歷史理念。

    +

    自 1857 年開始,朵伊森就一直有開授關於歷史知識理論方面的課程,這些課程以「歷史的方法論與總論」 (Enzyklopädie und Methodologie der Geschichte) 或其他名稱進行,而這些課程的相關材料在朵伊森生前只有以大綱的形式出版,名為《歷史知識的理論大綱》 (Grundriß der Historik) 。然而因為這只是朵伊森上課所使用的課程大綱,只具骨架而無血肉,所以內容較為晦澀難懂,雖然曾被翻譯為英文與法文出版,但是造成的影響並不太大。

    +

    到了 1937 年這些課程的講稿才由他的外孫徐本芮 (Rudolf Hübner) 收集並整理出版,以《歷史知識的理論》 (Historik) 為名出版。這個徐本芮所編輯的版本副標題為「關於歷史的總論與方法論的講演」 (Vorlesungen über Enzyklopädie und Methodologie der Geschichte) ,很清楚地表明了這是朵伊森講課內容的重建。在這個版本之中編者也收錄了其他幾篇朵伊森重要的短文,包括了朵伊森生前未出版的〈歷史的神學〉;一篇評論巴克爾 (Henry Thomas Buckle, 1821-1862) 作品《英格蘭文明史》 (History of Civilisation in England) 的書評,名為〈將歷史提升至科學的地位〉 (Erhebung der Geschichte zum Rang einer Wissenschaft) 的文章;以及一篇名為〈自然與歷史〉 (Natur und Geschichte) 的短文等等。

    +

    徐本芮的版本讓朵伊森的《歷史知識的理論》再度受到重視,不過余琛 (Jörn Rüsen) 認為這個版本在考證上非常不符合要求。在這個版本出現之後的四十年,賴 (Peter Leyh) 編輯出版了歷史考證版的《歷史知識的理論》第一冊,16 賴的這個版本在朵伊森講課內容的重建上較為嚴謹,彌補了徐本芮版本的缺陷。17 朵伊森講授歷史知識的理論,目的在於替歷史這門學科建立自己的方法論,然而朵伊森的方法論並不僅侷限於史料考證方法上,他不認為歷史研究的對象是過去 (Vergangenheit) ,而是「此時此地,還沒有完全逝去的過去。」18 對於一些歷史學者所主張的追求絕對客觀,朵伊森將之斥為「太監式的中性」 (eunuchischer Objektivität) ,對之敬謝不敏。19 朵伊森之所以獨特之處,在於他意識到了研究歷史的研究主體,以及研究主體將歷史傳達出來的媒介,所以在他的《歷史知識的理論》之中,他除了探討歷史研究的方法論 (Methodik) 之外,還探討了歷史研究主體與客體關係的系統論 (Systematik) ,以及陳述歷史研究結果的體裁論 (Topik) 。

    +

    1884 年六月十九日,朵伊森病逝於家中。綜觀他的一生,在學術方面兼具了史料考證研究與歷史理論建構兩方面的成就,在政治上也以行動實踐了自由主義中產階級的理念。在歷史學界方面,他可說是第一位專注於替歷史這們學科找尋並建立一套屬於自己獨特的研究方法與理論基礎的思想家,在實踐方面,他也可算是德意志的傳統裡除了馬克思 (Karl Marx, 1818-1883) 之外的另一種將理論與實踐結合的典範。

    + +

    三、希臘化時代史作為西洋上古的「現代史」

    + +

    朵伊森在柏林大學就讀的時期,在學術思想上受到最大的影響來自黑格爾以及柏克這兩位教授。黑格爾對於朵伊森的影響主要是觀念上的,而柏克的影響則大部分是方法上的。朵伊森對於歷史發展的觀點大部分來自於黑格爾的歷史哲學,雖然他日後宣稱在思想上與黑格爾分道揚鑣,但是他們之間的差異主要是政治和宗教觀點上的不同,朵伊森並非因此就完全脫離了黑格爾思想的陰影。20

    +

    黑格爾的歷史哲學受到的最大批評,在於他以玄思取代了以經驗為主的歷史研究,朵伊森雖然受到了黑格爾很大的影響,然而朵伊森對於黑格爾的這個問題也有所自覺,這可歸功於古典語言學教授柏克的影響。柏克為沃爾夫 (Friedrich August Wolf, 1759-1824) 的學生,而沃爾夫可說是古典學 (Altertumswissenschaft) 的創始者,傳統人文學者對西洋古典文化的研究多以美學或博古學的角度出發,而沃爾夫將其轉為嚴謹的,以歷史考證為基礎的學術研究。沃爾夫最著名的作品為《荷馬評論》 (Prolegomena ad Homerum) ,透過嚴謹的文本考證,沃爾夫證明了荷馬史詩不是單一天才詩人的創作,而是透過數代不同作者口傳逐漸累積而成的結果。沃爾夫的這個考證作品打破了傳統古典主義 (Klassizismus) 將荷馬史詩視為單一天才所創作,並且具有內在整體性的傳統觀點。沃爾夫的重要性在於他把歷史性的思維帶進古典語言學 (Philologie) 這門學科之中。21

    +

    柏克承繼了沃爾夫對於古典時期歷史層面的重視,他的哲學傾向並不強。柏克最大的興趣在於將古典世界生活的各個層面做一個整體的關照。此外,他對於古典語言學的方法論也非常重視,他的《語言考證學的總論與方法論》 (Enzyklopädie und Methodologie der philologischen Wissenschaft) 便是這個方面的重要作品。雖然在這部方法論的作品中他僅將所有的重點放在資料的收集及考證,但是在這個方面他的確有不少成就,而更重要的是他重視文本與歷史脈絡之間的相互關連。此外他在柏林大學也培養了一批傑出的學生,而朵伊森便是其中之一。22

    +

    受到黑格爾與柏克兩人的影響,朵伊森在他的作品之中既包含了歷史哲學對於世界史的整體關照,也同時兼顧了經驗實證研究的重要性。傳統的古典主義將西洋上古的希臘羅馬史視為人類歷史發展的極限,是個理想的黃金時代,連沃爾夫也無法完全擺脫古典主義的影響,而將希臘人視為可供當代人模仿的最佳典範,23 然而朵伊森對於這種過於理想而忽視歷史現實的觀點抱持著批判的態度,在他《希臘化時代史》第三卷的前言之中,他指出了對於西洋上古的歷史,傳統上有兩類錯誤的觀點,他的作品就是要與這兩種觀點對抗。

    +

    其中一種觀點認為上古時代的異教徒陷入了無法得到救贖的深淵,相信他們處在「暴怒的生活與敗壞的風俗 (in vitae contumeliam et mortis exitium) 」24 之中,是被上帝拋棄,陷入萬劫不復境地的可憐人。朵伊森認為這種耶穌會的教育理念 (jesuitische Pädagogik) 流行在歐洲一個世紀之久,將歷史中此世 (das Diesseits) 世俗的一面完全否定。「所有道德團體 (sittliche Mächte) 都被他們視為替享樂主義 (Eudämonismus) 服務。」25 朵伊森認為他們從宗教中所珍惜的,只有感動的滿足和心靈的需要,而完全不在意宗教中所包含的積極內涵 (positive Inhalt) ,也不在意任何歷史條件的限制 (historische Bedingtheit) ,對於異教時代的意義並未經過理性的思考就一味地排斥。「他們拒絕承認替基督的教會做預備並加以引導的聖靈,拒絕承認上帝永恆的智慧與愛是無時無刻不得到證明的—它們甚至在異教徒的身上也得到彰顯;他們再一次展開了對預備遭毀滅的器皿 (vasa irae) 、26 崇拜偶像者的罪惡享受以及古典藝術的魔鬼作品的宣戰與憎恨,他們鄙視青年的教化,並且用異教般的嘶吼將之玷污。」27

    +

    對於上述這樣全盤否定異教時代的觀點,朵伊森認為「基督教的基礎並不建立在上帝武斷而隨意的偏愛之上,而是建立在上帝永恆的計劃之上,從原初到了這個所有民族,不論是異教徒或是猶太人,都被引導至、被教育和引至領受聖禮時刻〔指基督教出現的時刻〕。」28 朵伊森的想法意味著歷史的發展是依照上帝的永恆計劃而前進,而在基督教時代之前的異教時代也是上帝歷史計劃中重要的一部份,如果忽視了異教時代在歷史發展過程中的重要性,對於世界歷史的發展就無法全盤地掌握。朵伊森所要駁斥的另一種觀點來自於古典主義。朵伊森嘲諷地指出,古典主義者狂熱而毫不厭煩地:

    + +
    +

    藉著一切最美好而高貴的詞語、最可愛的幻想的描繪,和以烏托邦式的理想為前提的讚嘆,將古典時代描繪為一個失落的天堂。他們之中有好些個人已經對我的意見感到憤怒,因為我討厭德謨提尼斯,不和他們一樣被盲目的愛國情緒所擄獲,而且認為與其說亞理斯多芬尼是個美德的傳道者,不如說是個惡作劇專家。我並非不承認古典時代的偉大,但是對此就好像李希騰堡 (Georg Christoph Lichtenberg, 1742-1799)29 所說的一樣:千足蟲其實也只有十四隻腳而已。30

    +
    + +

    正如李希騰堡說「千足」蟲事實上只有十四隻腳而已,朵伊森要將「光輝燦爛」的古典時代還原回真實的歷史相貌,因此他對於古典主義者將古典時代視為烏托邦的描繪方式採取批判的態度。朵伊森指出這種古典主義的觀點是以教育為出發點而形成的,它所要的不是歷史的真相與關聯,而是古典時代最理想光輝的一面。作者認為古典語言學界的此種主流觀點是缺乏歷史思維的,「他們喜歡把真相的整體放在光亮的太陽底下,放在多采的生命光輝之下關照,愈是著重在個別人物的典範,個別偉大作為的典型之上,就愈不會注意到人物與事件非武斷連結起來的整體圖像的唯一動機。」31 也就是說,為了青年的教育,他們會特別強調個別的人物與作為,卻不會將這些個別的人事物放進整體歷史發展的脈絡裡去關照。

    +

    朵伊森認為古典主義這種「美學和教育學的出發點將上古的科學研究拉離了歷史的基礎。」32 因為這在這種觀點是烏托邦式的,也是非歷史的,在這種觀點之下,「人們無法了解古典希臘與希臘化時代的相互關連;當雅典的美好凋萎之時,人們就以為,接下來的不過是一個荒蕪、噁心衰敗的時代……就認為明顯地認為不值得費力去研究『古典』時期結束之後的時代。」33 於是,希臘化時代的歷史在古典主義者的眼中就顯得毫無價值。朵伊森指出他之所以重視希臘化時代,並非刻意要「以裝飾品將希臘化時代加以美化漂白。」34 然而上述古典主義的這種純粹站在雅典立場上的偏黨之見,「只會遮蔽了那個時代〔希臘化時代〕的記憶,而那時代是偉大遺產的繼承者,以及偉大任務的肩負者。只有當人們了解了它的強處之後,才能認識它的弱點;人們必須了解它整體的意義,才能對其做出公正的評判。」35

    +

    朵伊森進一步指出:「這一類的上古史的觀點,在本質上來說是所謂的歷史性的,很明顯地,實在是一種黨派的偏見。」36 這種偏見就是希臘的愛國主義,「在希臘和羅馬的歷史裡,每一個片刻都提醒我們,過時的權利 (die historischen Rechte) 無法與歷史的權利 (das Recht der Geschichte) 相抗衡。」37 所以對於那些「認為從最美好的『有機的』的和諧狀態開始,希臘的歷史發展到了亞歷山大就終結了,而羅馬的歷史也到了大約格拉古兄弟的時代就結束了。然後他們認為接下來開始了一個不論在觀點、信念以及美德上都是極端衰敗的時期。他們不厭其煩地重複著殘酷的馬其頓人 (Macedonia) 腓力普 (Philip II, 359-336 B. C.) 如何毀壞了希臘的自由,所有的一切如何隨著德謨提尼斯 (Demosthenes) 與亞里斯多德 (Aristotle) 的逝去而結束,所有的歷史生活停止與死亡,除了一個單調的黑夜之外什麼都不剩」38 的人,朵伊森認為他們的觀點「的確是熱愛雅典,熱愛希臘的,但是卻不是歷史性的。」39 他指出馬其頓的霸主地位,其立足點的合法性與斯巴達、雅典以及底比斯之前所擁有霸主地位相同,「誰不會驚嘆於特米斯多克理斯 (Themistocles) 與伯理克理斯 (Pericles) 的雅典呢?但為何忘了,他們奠定基礎並且將力量擴展到半個希臘世界之廣,所憑藉的也是獨裁的統治。」40 朵伊森並非否認雅典在歷史上曾有的輝煌與偉大,但是無視於光輝背後的黑暗面是不對的,「當然自由是個非常美妙的東西;但是在我們的時代很少人會認真地悲歎舊有封建階級的衰微。」41 正如當代的人不會悲歎中古封建傳統的消逝,同樣地人們也不應該為了偏愛雅典的緣故而反對希臘世界中逐漸增強的君主制潮流。

    +

    總之,朵伊森站在歷史的立場來駁斥以上兩種觀點,並且藉此替自己希臘化時代的研究找到合理性的基礎。

    +

    朵伊森明白地說「我把希臘化時代拿來當作上古史的現代 (die moderne Zeit des Altertums) 。」42 他認為希臘歷史朝著一個特定的方向發展,為了達到目標,中間所帶來的舊有權利的犧牲,美好成果的折損,以及最具生命力之物的消耗與毀滅,這一切都是必要的,就好像一個兒童專注而熱情地沈浸在遊戲之中,一旦他長大成人以後,對於這樣的熱情就會保持距離。但是朵伊森認為,歷史對於發展中所帶來的損失,都會替代以豐富的報償。然而他並不會認為新的事物一定比舊的事物好,他強調的是「只有把歷史的整體圖像視作人性 (Menschheit) 的發展,如此個別的形態、民族、文化、國家以及個人才能得到自己的正確含意;甚至那些美好、真實、正確、高貴的事物,並不是超越空間與時間之上,而是它們的程度和力量都包含在時空之內,並且同時投射照映在一個此時此地 (ein Hier und Jetzt) 之上。」43

    +

    在《希臘化時代史》這部作品之中,不論是政治、軍事、國際關係、經濟與宗教等方面,朵伊森都將希臘化時代的歷史當作一個邁向現代的過程來敘述。政治上,朵伊森指出希臘化時代小邦林立時代的終結,而區域性的主權國家代之興起。在這個國家系統發展成形的過程當中,統一大帝國的建立與瓦解是必要的中間階段。朵伊森指出這個現代化的過程是一個由自然走向歷史的過程。浪漫主義的觀點重視自然與有機的發展,並且懷念中古時期的生活。朵伊森的觀點與此相反,他認為不論是中古走向現代,或是希臘古典黃金時期走向希臘化時代的歷史過程,這兩者同樣都是歷史發展的必然過程。在這個過程之中,所有自然的連結與有機的關係都會被打破,取而代之的是新的理性的原則以及歷史的生活。

    +

    朵伊森在敘述馬其頓成為強權的過程時,特別重視現代的層面。在腓力普二世的時代,馬其頓的內部經歷的非常大的改革與變化,其中最重要的,就是軍事的改革。在希臘世界,軍隊的來源通常來自於募兵或傭兵,這類的軍人一般說來並無忠誠的觀念,他們會替任何出得起錢的人打仗。傭兵的來源多半來自希臘人,無論各希臘城邦或是波斯帝國都可以是他們服務效力的對象。

    +

    最著名的一次傭兵戰役發生在波斯皇帝阿塔薛希斯二世 (Artaxerxes II, ca. 451-359/358 B.C.) 的時代,這次事件幾乎動搖了整個波斯帝國的基礎。阿塔薛希斯之弟居魯士 (Kyros, 423-401 B.C.) 覬覦王位,招募了一批主要以斯巴達人為主的希臘傭兵,往亞洲內陸挺進,企圖奪取王位。當阿塔薛希斯得知居魯士的企圖之後,便率兵討伐。在庫那克撒 (Kunaxa) 一役之中,居魯士的企圖幾乎成功了,他親手傷了他的兄長阿塔薛希斯,然而前者在騷亂之中喪生,使得局勢大為扭轉。居魯士殘存的八千六百名希臘傭兵以克色諾芬 (Xenophon, ca. 430-355 B.C.) 為首,經過千辛萬苦終於撤退到海邊。這一次的遠征在克色諾芬的作品《遠征記》 (Anabasis) 有詳細的記載,這一批希臘傭兵得以長驅直入毫無阻礙地進入波斯帝國的心臟地帶,使得希臘人在心理上對波斯帝國的弱點有了更進一步的認識。44

    +

    不像大部分依賴傭兵或募兵的希臘城邦,馬其頓在腓力普二世的領導之下,為了抵禦北方國境的蠻族,腓力普建立起一支具有現代意義的國家軍隊 (Nationalheer) ,這支軍隊是以馬其頓的生產主力,也就是農民為基礎而建立的。朵伊森指出這些農民透過服兵役「發展出了穩固的命令者與服從者之間的秩序,以及階梯般層層的軍階,只有透過服務與勇敢的行為才可能逐次擢升。」45 而透過了常備軍制度的建立,「產生的作用是讓領土境內不同的地域成為一個整體,而馬其頓人則體認到自己是一個民族。」46 而原有的貴族在這個軍事體制之中則轉化為國家的軍官階層,如此一來,這樣的一支軍隊就是馬其頓形成中央集權國家的基礎,也是它賴以成為強權的媒介。

    +

    希臘化時代在經濟的層面也展露出現代的面貌。朵伊森指出亞歷山大大帝改變了上古世界的經濟面貌,「或許再也沒有人在這個方面的關連上以一個個人的影響帶來了這麼迅速、影響這麼深遠、涵蓋範圍如此廣的變化。」47 亞歷山大的事業在經濟上打破了各地原有的自然經濟,並以貨幣經濟取而代之;同時阻礙各地經濟交流的因素也被去除,活躍在山區與沙漠地帶的強盜集團被抑制活動,甚至被強迫定居,而地中海的商業活動則以埃及的亞歷山大城 (Alexandreia) 為中心興盛地發展,這一切都證明了希臘化時代的經濟活動與之前的時代相比有很大的改變。

    +

    經濟生活的重大改變帶來的是物質利益的重要性逐漸提升。朵伊森指出希臘化時代的強權國家之中,最重視物質利益的就是埃及的托勒密王朝 (Ptolemies) 。「在托勒密王朝的對外關係,我們可以隨處看到一個重商主義系統 (Merkantilsystem) 在廣大範圍上的影響。」48 正因為掌握了托勒密王朝重視物質利益的特質,朵伊森便能很清楚地掌握埃及各種外交行動的背後動機,包括對於賽普路斯的控制,以及數次企圖控制殖民地奇瑞尼 (Kyrene) 背後的用心。49 在經濟方面,希臘化時代貨幣經濟的盛行,物質利益的重要,與古典時代相比,希臘化時代經濟的確是更具有現代性的。

    +

    在科學知識方面,希臘化時代是個大有進展的時代。朵伊森指出「透過了亞里斯多德,偉大的經驗論 (Empirismus) 獲得了生命,這是科學為了主宰隨著亞歷山大遠征所帶來的人類知識的大量新資料所必需的。」50 此外,這個時代的歷史研究也進入了一個新的階段。

    + +
    +

    人們現在可以在實際的地點研究,可以把一個民族的傳說拿來與他們的紀念碑相互比較,把一個民族的命運與他們的風俗拿來相互比較。而儘管透過了所謂的亞歷山大的作家所傳播的知識之中有無數的錯誤與神話,然而正是這個時代偉大的歷史研究獲得了它的材料與方法。51

    +
    + +

    而希臘人也在此時從東方獲得了不少寶貴的科學知識,從巴比倫學到了天文觀察,從印度學到了醫藥知識,也從埃及的宗教官員學到了解剖學以及機械方面的知識。朵伊森指出「希臘精神自身的發展原本一直都將哲學描寫為所有知識的本質;現在他們自己從這個單一的認知方向中解放出來;精確的科學開展奠基在獨立的經驗知識,而哲學對於思想與真實之間的關連一直沒有一至的看法。」52 總之,朵伊森筆下的希臘化時代,在科學與知識上的突破性是可以與近代的地理大發現和科學革命相比的。

    +

    希臘化時代另一個重要的意義,在於它打破了傳統與自然的限制,給上古世界創造了新的歷史生活,朵伊森指出,民族是自然的產物,它們受到自然環境以及地理界限的限制,並且依照既有的自然條件各自獨立發展,「它們就好像是這塊地域、這塊土地的產物,與土地同樣進行自然史式的發展。」53 因此各民族的特質也來自於其所賴以發展的環境。當希臘世界以及波斯帝國發展成熟之時,民族的自然發展就已經開始衰微崩解,到了亞歷山大大帝的時候,他企圖把東西民族融為一體,於是「便開始了一個巨大發酵醞釀的過程。」54 亞歷山大大帝死後接下來是動盪不安的繼承者時代,「這時自然的、傳統的以及民族的最後剩餘力量,只要它們仍然帶有國家的功能,全都被摧毀殆盡,自然國家具有束縛力與決定力的最後片刻也被超越克服了。」55 朵伊森指出,雖然此時舊有的力量仍然企圖反撲,但是其結果是替自己帶來更大的毀滅,最後是「所有過時的權利 (historisches Recht) ,所有自然形成的關聯徹底的撕毀。」56 雖然這個歷史發展的過程帶來了混亂的局面,然而它「充滿並孕育了新時代的要素」。57

    +

    這個新時代的要素是什麼呢?朵伊森指出,「人們只是雅典人、斯巴達人、塔倫托人的時代已經過去了,也就是人們只能是公民 (Bürger) 的時代已經過去了,人們開始可能擁有私人生活的領域。」58 然而舊有的限制在更廣泛的層面上被打破,朵伊森指出:

    + +
    +

    一開始是小之又小的城邦之間的區隔……接下來是整體希臘人概念的出現:於是人們愈來愈明顯地感到希臘人與野蠻人之間的對立。亞里斯多德仍然說:他們天生就適合當作奴隸;他建議亞歷山大,對希臘人像個將領帶領士兵一般,而對野蠻人則以主人對奴隸的方式統治,對前者像朋友親戚般對待,對後者則像動植物一般來處理。就連這樣最後一個自然所決定的對立也要被消滅。亞歷山大開始了這項偉大的工作;『他命令所有人……將世界當作自己的城邦,將軍營當作這個世界城邦的衛城 (Akropolis) ,將勇敢的人當作朋友,將差勁的人當作陌生人來對待』。『而芝諾這位斯多噶學派建立者令人讚嘆的政治思想……明智地將思想凝聚成以下的主要學說:那就是我們不再被城邦與地域所區分……而應該將所有的人類視為我們的同胞與同邦人……』共同體的概念首次擴展到超越希臘人與野蠻人等這類民族區分的境界……59

    +
    + +

    希臘化時代打破了原有地域與自然環境所帶來的限制,消除了民族的界限,帶來了將人類做為一個共同體的概念。這種普遍人性思想的出現與普及,正是探討希臘化時代所包含的現代性之中最重要的一個面向。在朵伊森對歷史發展的觀點之中,普遍人性概念的出現,正是為新的宗教發展奠定基礎,對於朵伊森《希臘化時代史》之中的對於希臘化時代在宗教發展上的重要意義,必須以這一點為基礎出發。

    + +

    四、異教發展的最高階段

    + +

    黑格爾在《歷史哲學》 (Vorlesung über die Philosophie der Geschichte) 之中,將希臘的歷史分為三個階段,第一個階段是真實個體 (Individualität) 形成的時期;第二個階段是個體獨立與其對外戰爭勝利的時期,第三個階段則是衰亡的時期。黑格爾也指出,希臘的生活是青年的成就,它開始於一位神話中的青年阿基里斯 (Achill) ,終結於一位真實的青年亞歷山大,而這兩位青年都出現在希臘與亞洲的戰爭裡。60

    +

    在此黑格爾所指的第三階段,就是指亞歷山大大帝死後的希臘歷史,黑格爾指出「此希臘世界歷史的第三階段,其包含了希臘不幸的詳細發展,對我們來說沒有多大的趣味。」61 他認為這個階段的希臘歷史是衰弱無力,註定要被毀滅的,而「治療、挽救與撫慰是不可能的」。62 所以在這個朵伊森稱之為希臘化時代的歷史階段裡,黑格爾看不出其中積極的歷史意義。

    +

    黑格爾指出:曾經有過如此的評論,凱撒 (Gaius Julius Caesar, 100-44 B.C.) 在現實的方面開創了新的世界;而其在精神與內在存在方面的展開則經由奧古斯都 (Augustus, Gaius Octavius) 之手而得以開展。」63 在精神方面:

    + +
    +

    羅馬世界……將與現實的斷裂以及一個只有在內在精神中達成的滿足的普遍渴望推上臺面,並且替一個更高的精神世界準備好了基礎。它〔羅馬〕就是那個命運 (Fatum) ,在祂的服務中壓倒了諸神與快樂的生活,也是淨化並消除人心中所有特殊性的那個權力,所以其整體的狀態與生產的情況相類似,而其痛苦就好像另一個更高精神生產的陣痛,這個更高精神是與基督宗教一起透過啟示而出現的。64

    +
    + +

    由這段引文可以很明顯地看出,黑格爾認為羅馬帝國在精神上替基督教世界的來臨做好的預先的準備。

    +

    朵伊森反對以上的觀點,他不認為希臘化時代只是一個充滿毀滅與衰敗的晦暗時代。黑格爾認為羅馬帝國時代替基督教的出現鋪路,而朵伊森則認為基督教的興起應該放在希臘化時代的時代背景裡,才能得出其歷史意義。朵伊森指出:

    + +
    +

    在亞里斯多德與亞歷山大之前,我們只見到民族的理念。後起的希臘人對蠻人的仇恨,波斯人對生而為奴的民族的驕傲,以及以色列人對異教的高傲,卻都顯示出了人性理念被障蔽。亞歷山大首先表達了他的人性理念的看法:希臘人是唯一善的代表。他將這個理念付之於行動,強調這個理念的正確性;這個思想逐漸貫徹而成泛希臘文化。也正是在這個思想基礎上,基督教世界才發展開來。65

    +
    + +

    由此朵伊森清楚地指出亞歷山大大帝所開創的希臘化時代是基督教發展的思想基礎之所在。在《希臘化時代史》的第三卷裡,朵伊森對於希臘化時代在替基督教建立思想基礎的過程有詳盡的敘述。

    +

    朵伊森指出上古世界的人,生活在受到自然狀態限制的情況之下,其特質與發展的方向皆受到自然的影響。而生活在自然狀態的諸民族,「其歷史就是自然的學習、穿透以及外在表現,而自然就是其原則。」66 而這種自然的狀態,與普遍人性的理念的距離是非常遙遠的。然而朵伊森指出「這就是上古異教世界所追求到達的境界,從這裡出發其歷史才能被掌握。」67

    +

    要到達一個普遍人性的境界,就要超越自然所帶來的限制,也就是要超越各個不同地域的區隔,「上古世界以其自身力量所能達到的最高境界,就是異教的毀滅。」68 這個發展的趨勢驅使歷史不斷前進。朵伊森指出波斯帝國的興起在這個歷史發展中占有重要的地位:在東方有許多國家的興起與衰落,最後由波斯帝國征服了整個上古的東方世界,朵伊森指出波斯的征服只在統治之上,而被征服的諸民族仍然保有自己的宗教、風俗、語言與習俗,雖然這些被征服的民族喪失了獨立與尊嚴,但是屬於他們的內在的獨特性仍然得以保存下來。69

    +

    朵伊森指出這是上古史發展上的重大變化,因為:

    + +
    +

    我們看到,諸民族最內在的生活開始分裂。這些民族不是從宗教與國家,以及神和世界的相互交纏開始的嗎?現在兩者都分離了;古老的國家對他們而言已經毀滅了;對神的信仰並未消頹,然而世界不再存在於這個信仰當中……隨著神權國家的衰亡,無宇宙論 (Akosmismus)70 興起於階層制度的廢墟之中,那個神性意識中的去世界化 (Entweltlichung) ,它只能是無力與衰頹的外顯而已。71

    +
    + +

    因此,朵伊森認為上古近東世界原本的政教合一的體制,在這樣的體制之下,政治上的領袖與宗教上的領袖合為一體,在思想上對於現實世界的秩序的認識也與宗教信仰緊密地結合。而波斯帝國將這些國家征服,卻准其保留原有的宗教信仰,雖然使得原有的宗教信仰得以存續,但是原本宗教與世界秩序的結合卻被破壞,於是宗教便將世界視為虛無的幻象,逐漸把重心放在另一個世界,而真實的世界與宗教信仰的緊密結合便因此被打破了。

    +

    然而,朵伊森認為波斯帝國興起的意義並不僅在於舊有神權國家的衰微而已。「我們可以這麼說,波斯的優勢在於它將這個分離做為開始與原則,國家不再是也不再應該是神權的,而是也應該是君權的。」72 波斯自居為光明之神查拉圖斯特拉 (Zarathustra) 的信奉者,也以光明的名義征服世界,所以在這樣的觀點之下人成為替光明服務的工作者。朵伊森認為波斯是「亞洲第一個道德的 (ethisch) 力量,而沒有任何一個東方的民族能抵禦它。」73 也就是說,波斯是上古近東第一個掙脫神權束縛,而獲得道德力量的世俗化民族。

    +

    然而波斯的優勢面對了新興的希臘人就有了限制。朵伊森指出希臘人在地理上受限於破碎的地形,一開始就分為許多小城邦,而無法在政治上取得統一。在這樣的自然條件之下,希臘各地發展出自己獨自的宗教與方言,於是在所有希臘人居住的土地上便有了無數的宗教傳統,而在各地的希臘人之間的相互交流之下,就無可避免地會產生不同宗教傳統的比較與相互對照 (Ausgleichung) ,「不同氏族與地域的神祇開始組合形成一個神聖的系譜,不同的神話傳說被相互連結與融合,被呈現為一個新的具有相互關聯的整體。」74 而一個普遍希臘民族的整體的概念就是建構在這樣的基礎之上。

    +

    「於是從開始以來我們看到希臘諸氏族超越了自然的決定限制,而古老的東方仍受限在其中。」75 朵伊森指出希臘人的宗教裡沒有階級,沒有祭司階層,沒有一個統一的王國。在這樣自由的環境之下希臘人不斷發展宗教的想像,「東方的民族是那麼地受到恆常與固定的圈子的限制,而希臘的生活是那麼地生動、多樣、那麼地相互交融,並且在內在的意義上不斷進步。」76 朵伊森並且指出正因為希臘與東方相較是較具有多樣性的,所以「不是此地或彼地,不是在某一個或另一個型式才代表真正的希臘;西西里,愛奧尼亞,多里亞人,以及許多島嶼,他們在這個整體的工作 (gemeinsames Werk) 裡都占有自己重要的部份,他們所有結合起來才算是希臘。」77 而在此朵伊森所指的「整體的工作」,讓希臘首次脫離了自然生活而進入歷史生活,它質疑所有既有的事物,企圖超越此時此地的限制,在思想和實踐具有理想性,將現實狀態加以改變,並以此改變為基礎進一步追求更高的理想,「我們將此稱之為教化 (Bildung) 。」78 這個教化可說是希臘啟蒙思想的成就。

    +

    對朵伊森來說,希臘的教化正是希臘超越波斯之處。教化開啟了希臘思想上的啟蒙 (Aufklärung) ,啟蒙的精神批判傳統與神話,「神話以及宗教的一些部份失去了神性力量與現實真相的相互連結,」79 喪失了這個重要的連接之後,神話被視作外在的歷史,並因此被蒐集、研究與批判。與神話的詩性特質相對,「這就是散文 (die Prosa) 的開始。」80 散文的理性方法開始被應用於各個方面的研究。「同時,詩性的藝術也有了一個戲劇性全新的型式。」81 這個新的型式「與一個新的觀點結合,並且透過此觀點而成形,這個新觀點就是道德的關聯,」82 所有的傳統事物都透過這個新的關聯而得到了合法性與重新認可。

    +

    朵伊森指出,希臘啟蒙思想對宗教所帶來的影響,就是將「宗教歷史的一面予以消解,」83 自然哲學取代了舊有的諸神系譜,並且嘗試著去尋找萬物之所以形成背後的原初力量,其結果導致了以下的思想:「人並非最高的,善 (das Gute) 才是最高的,人的尊嚴與力量也是源自於這個至高的善。善是在所有變化現象之上的永恆理性,是唯一的、永恆存在的、在自身中完成的、決定所有事物的、是自身的目的,也是所有事物的目的,只有朝向它運動的才能算得上是存在的事物。」84 朵伊森認為這樣的思想發展到了極致,便導致了「最純潔,最高貴的理神論 (Deismus) 。」85

    +

    儘管這樣的思想在宗教的知識層面給人滿意的解釋,然而,朵伊森並不認為這樣的新思潮能完全取代舊有的宗教。他認為原有的民族宗教與神話當然會受到這股新思潮的影響與衝擊,然而朵伊森指出「明顯地,認識所信仰的對象,是具有正面的內涵的,然而人並非只是為了這個知識上的理由,才去崇拜更高的力量。這是人類心靈上的需要……是的,這個最內在的,繼承而來並且已成為習慣的感受仍然停留在其軌道上……連科學都不斷嘗試將其研究的結果與民族信仰做和解,不斷地與其結合。」86

    +

    然而在這樣的和解與結合當中,「希臘在神話宗教的豐富內涵以及諸神人性化的形態中獲得了自己獨特的特質,然而這些卻為科學所拋棄。」87 朵伊森指出不論是斯多噶學派或是伊比鳩魯 (Epikur, 341-271 B.C.) 的學說都無法抵擋科學的攻擊:

    + +
    +

    斯多噶學派嘗試透過泛神論的比喻來找出隱含在普遍信仰正面內容中的意義,並藉由科學系統的相互連結,將神聖歷史的經驗知識重新給與合理化;然而他們並不能抵禦步步進逼,愈來愈尖銳的歷史批判,也不能與日益進步的自然認識的結果達到相容,在懷疑之中,他們嘗試在絕對 (der Unabweisbare) 之中尋找抵抗的力量。而伊比鳩魯則嘗試讓自己退縮至只有主觀感覺的寂靜主義 (Quietismus) 之中。88

    +
    + +

    朵伊森藉此指出希臘宗教的原則發展至此已經無法與外在物質層面的真實相容,「無可避免地,最後出現一個果敢精明的人,將搖搖欲墜毫無根基的傳統建築物丟棄到垃圾堆裡……並藉此替一個新發展的觀點贏得開闊的空間。這就是優赫美羅斯 (Euhemeros)89 與其《神聖歷史》 (Heilige Geschichte) 的偉大意義。」90 優赫美羅斯認為諸神都曾經是人,而這些人部份是因為參與了偉大事蹟,部份因為曾經是統治者,於是受到了尊崇,到後來就被視為神祇而信仰,這就是朵伊森眼中歷史觀點對於傳統宗教所做出的最有力的批判。

    +

    朵伊森指出在宗教之中對於神性 (Gottheit) 的情感 (Gefühl) ,知識 (Wissen) 以及意欲 (Wollen) 都是不可或缺的,然而希臘宗教發展到了這個地步,「情感自身喪失了其內容的確定性;所留下的只是宗教性的需要,而這個需要是理性抽象思考的結果所無法滿足的。」91 雖然在新的思潮之下,在亞歷山大大帝東西融合的努力之下,原本每個地區性的宗教都被視為一個更高而統一的宗教不同面向的反射。

    + +
    +

    然而這個更高的知識就能充實〔宗教的〕意欲與情感嗎?意欲與作為很早就從宗教生活的基礎中脫離了;自私與自利自從詭辯師的時代開始就已經成了廣泛地被理解的共通行為準則了,只有自我深化的哲學,而非宗教,才可能產生出一個更高貴的倫理學;知識與意欲從傳統宗教的領域中區分開來。而情感呢?就人們喪失了情感歸屬確定性的這個角度來說,無法得到滿足的情感就以逐漸升高的熱情將投注的焦點轉往異國的、晦暗的以及無法理解的事物。92

    +
    + +

    朵伊森認為這就是「人類宗教生活中最晦暗的時代」93 的開始:「在最內在的部份裡溫暖燃燒著的爐火熄滅了,而人們徒勞地嘗試去尋找新的光明,藉以照亮內在與外在荒蕪的黑暗。」94

    +

    儘管上古宗教的發展最後到了這樣令人絕望的地步,但是這個過程正是朵伊森所謂的上古史發展的最高境界,也就是異教的毀滅。朵伊森在《希臘化時代史》這部作品最後的總結部份,他指出在西方與東方的接觸之下,宗教的發展給世界帶來了許多改變,而其中最重要的就是「從古老的耶和華宗教與希臘化力量之間爆發的衝突而來的救世主的理念」。95 朵伊森指出,這個猶太教與希臘化的發展的首次接觸,對猶太教來說就是這個宗教取得了世界史意義的轉捩點:

    + +
    +

    自從無法想像的久遠年代開始它〔猶太教〕就受限於狹小的空間,孤單地立足於信仰異教的民族之間……現在這兩個上古歷史中最終也是最深刻的對立者終於面對面地接觸了;最後也是最具有決定性的上古史自我完成的任務要開始了。「及至時候滿足」,它便完成於道成肉身者的出現之中,完成於新的約之中,在其中最後與最深的對立也會被超越,在其中猶太人與異教徒,世界上所有的民族,民族的力量被摧毀並耗竭而亡。最後,正如先知所預言的……將會找到慰藉與平靜,以及……一個更高也更精神性的上帝國度。96

    +
    + +

    朵伊森將希臘化時代做為基督教世界出現的先決條件,因為在希臘化時代,上古史的發展完成了自身的歷史任務,摧毀了異教的根基,在這樣的環境之下,猶太教才能脫離原本狹小地域的限制,與希臘的精神相互對立,相互衝擊,這樣的激盪最後才導致出基督教思想的出現。而朵伊森之所以寫作《希臘化時代史》,目的之一就在於描述上古史完成自身歷史使命的過程。在這個過程中,宗教在知識、情感與意欲上的完整性被破壞,上層的宗教與哲學滿足了知識的需要,但卻無法填補情感的空白,而下層的傳統民間信仰則無法在知識上與新的科學發展相抗衡,於是這樣的空白就給基督教的興起留下了很大的空間。所以對朵伊森來說,希臘化時代是基督教興起的必要前提。

    +

    在這個異教毀滅而基督教興起的歷史過程中,朵伊森將亞歷山大大帝放在一個重要的位置當中。除了指出亞歷山大帶來了人性的理念,在這個思想基礎上基督教才發展開來。在另一個方面來說,朵伊森重視基督教裡「道成肉身」的觀念,而透過亞歷山大神權統治 (Theokrasie) 的描寫,朵伊森也暗示了亞歷山大是「道成肉身」這個觀念的先驅。

    +

    西元前 331 年,亞歷山大到了埃及西方沙漠的阿蒙神廟 (Ammonion) ,亞歷山大到此神廟拜訪的動機不明,而他在此處得到了何種神諭也沒有為外界所得知。朵伊森將此與亞里斯多德《形上學》中的不動之原動者 (das Unbewegt-Bewegende) 的概念做了聯想。亞里斯多德認為真正的神性就存在於這個不動之原動者當中,他是所有原因的原因,而他自身的存在則是自己導致而不需要藉助外物的。朵伊森認為,當亞歷山大在阿蒙神廟學習了埃及的宗教理論時,可能也學習到了類似的思想,認為所有宗教與政治的權威都是來至一個更高的整體,朵伊森指出:

    + +
    +

    從古老法老時代的碑銘就有提到過『神自己就是自己形成的原因,是透過自己而存在的,本身不是受造的,而是創造天和地的神,是存在與不存在事物的主宰者。』而到了大流士二世 (Dareios II, ?-404 B.C.) 的時代的碑銘更顯示出這個思想仍活生生地流傳下來,並且可能有更進一步的發展。在其中阿蒙.拉 (Ammon-Ra) 是唯一自己創造自己的神,祂從所有存在的事物中展現出自己的存在……所有其他的諸神就好像是祂的屬性 (Prädikate) ,就好像是祂的作為 (Tätigkeiten) 。97

    +
    + +

    而在朵伊森所提的這個大流士二世時代的碑文裡,大流士這位外來的統治者被埃及人尊為阿蒙之子,而亞歷山大大帝到了阿蒙神廟的時候,也被當地的祭司尊稱為宙斯 (Zeus) 的兒子。朵伊森藉此指出這就是亞歷山大日後實行神權統治的思想根源。

    +

    朵伊森指出「我們可以這麼說,透過了啟蒙思想……異教的力量被毀滅,而一個更為精神性的宗教發展就有了可能性。在這個方面沒有其他的事物比神祇的融合 (Göttermischung) 與神權統治更具有作用力。」98 亞歷山大對於他所統治的廣大領土之中所有民族的宗教都同樣的信仰。

    + +
    +

    國王如此的示範很快地就擴大了影響的範圍,人們於是開始更為大膽地,就像希臘人對待其他宗教信仰的方式一樣,將異邦的神祇本土化,並且從異邦的神祇之中重新認識本土的神祇,將不同民族的傳說與神譜相互比較,並且讓不同的信仰之間達到相容和諧的狀態……或多或少深刻地掌握了同一個超越塵世,絕對,以及最終目的的概念。而神祇的名稱、屬性與執掌的不同其實只是外在而偶然的。99

    +
    + +

    這樣的融合,顯示出了「區域與民族性的宗教,也就是異教的時代已經過去了,最終一個統一的人性需要也有能力帶來一個統一而普遍的宗教。」100 雖然「神權統治本身並不能做為一個將所有不同宗教體系融合為一個整體的嘗試。」101 因為亞歷山大生前如此的嘗試並未成功。但是,「在亞歷山大身上希臘異教的人神同形同性論 (Anthropomorphismus) 得以自我完成。人成了神。而這個神的國度在此世,在他身上人類提升到了自身有限性之中最高的極致。」102

    +

    亞歷山大大帝在他所實行的神權統治之中,自身成了人與神的結合體,而在他之後各個希臘化王國的君主也有不少將自己神格化的作為,這些將人與神結合的嘗試,對朵伊森來說暗示出了朝向「道成肉身」這個觀念的歷史趨勢。對黑格爾來說,羅馬的奧古斯都在精神層面開創了近代世界;而對於朵伊森來說,基督教世界降臨之前的精神預備早在亞歷山大和希臘化時代就已經開始了。

    +

    亞歷山大與他所開啟的希臘化時代,透過了普遍人性的觀念動搖了異教傳統的根基,也讓異教思想發展到極致而衰亡。然而朵伊森之所以用如此的方式呈現出這段時期的歷史發展過程,以及為何他認為這樣的發展是必然的,這些問題與朵伊森思想背後的神學思想是密不可分的。

    + +

    五、神意史觀與神義論觀點下的歷史發展

    + +

    朵伊森並不否認希臘化時代有其黑暗與衰敗的一面,然而他將這個黑暗衰敗的一面視為更高層次的精神發展,也就是基督教世界來臨的必要前提。朵伊森指出關於希臘化時代,他提出了一個與傳統觀點完全相反的看法:

    + +
    +

    當這個時代被輕視,被視為一個大空洞,一個人類歷史中致命的污點,一個集所有墮落、錯誤與衰亡於一身的堆積。對我來說,這個時代是一個人類發展鎖鏈中活躍的一環,是偉大遺產的繼承者與活躍的管理者,是偉大命運的肩負者,在其懷中這個命運得以成熟發展。希望我能成功地將這些意義以具有說服力的方式展現出來。我們學科最崇高的任務就是神義論 (Theodicee, Theodizee) 。103

    +
    + +

    神義論一詞公認最早由萊布尼茨 (Gottfried Wilhelm Leibniz, 1646-1716) 所提出。神義論這個詞來自希臘文的 theos (神)與 dike (正義),意思就是「神是正義的」。

    +

    神義論所要解決的,是像基督教這類一神論宗教中關於惡的根源的問題。在一神論的宗教之中,萬物的起源皆被歸因為唯一至高的創造者。然而,這樣的說法表示了惡也是此一創造者的創作。如何釐清創造者與惡之間的關係,並且替創造者辯護,便成了歷代諸思想家所關切的課題。萊布尼茨在 1710 年出版的作品《神義論》 (Essais de théodicée) 中嘗試解決上述的問題。他指出惡必須被放在目的論的脈絡中來看待,因為惡是用來達到更高的善的工具和手段。為了達到更為美好的未來,剷除橫梗在此一道路上的障礙,歷史中的惡便在此發揮了作用。用這樣的方式,萊布尼茨解決了上帝與惡之間的關係,也表示了惡之所以產生,並非上帝的錯誤。

    +

    黑格爾在《歷史哲學》中指出世界史的發展之中有神意 (Vorsehung) 在作用,而「就此而言,我們的觀點就是神義論,是神的正確的證明 (Rechtfertigung) 。」104 他批評萊布尼茨嘗試以形上學的方式,利用不精確且抽象的範疇來嘗試解決這個問題。105 黑格爾認為從世界史之中才能找到神義論的證明。他指出:「神統治世界,而祂的統治的內容,祂的計劃的實行就是世界史 (Weltgeschichte) 。」106 所以黑格爾將世界史的舞台視為上帝計劃實現的場所。而整部《歷史哲學》的結論就是:「世界史就是這個發展的過程,以及精神 (Geist) 實現過程……這就是真正的神義論,在歷史中神的正確的證明。」107

    +

    在世界史發展的過程中,「精神」逐漸開展,而「正如物質的要素是重力,所以我們應該這麼說,精神的本質的要素就是自由。」108 精神對自由的意識是隨著歷史的進步而開展的。自由包含在精神之中,就好像一棵果樹包含在一個種子之中一樣,精神一開始就包含了自由,然而隨著歷史的發展自由才逐漸隨之發展開來。

    + +
    +

    東方人仍不知道精神或者是人做為人是自由的,他們只知道,只有一個人是自由的……這樣的一個人只是專制君主,而不是個自由人。在希臘人之中自由的意識首次昇揚,而正因此他們是自由的;但是他們,羅馬人也一樣,只知道某些人是自由的,而非人做為人是自由的……所以希臘人不只蓄有奴隸,他們的生活與其美好自由的維持都與此緊密連結,這使得他們的自由成為偶然而易謝的花朵,而另一方面來說也與人性或人類的嚴酷奴役無異。只有基督教的日耳曼國家才首次達到了對於人做為人是自由的意識……109

    +
    + +

    然而如果神意充滿在世界史之中,那麼所有的歷史發展都是預定的,都是必然的,如此一來,似乎與歷史是自由的開展這個說法相互矛盾,對於這個問題,黑格爾認為解決之道在於國家 (Staat) ,他認為「只有在道德的整體—國家……之中,個體才擁有並享受自由。」110 黑格爾指出:

    + +
    +

    國家是存在於世界上的神性的理念,它〔國家〕普遍上來說是世界史確定的對象,在其中自由才得到了其客觀性 (Objektivität) ,並且生活在對這個客觀性的享用之中。法律 (Gesetz) 就是精神的客觀性,才是真實的意志 (Wille) ;只有遵守法律的意志才是自由的,因為它所服從的是自己,它是自己獨立的,是自由的。當國家,祖國形成了一個存有的共同體 (eine Gemeinsamkeit des Daseins) 的時候,當人類主觀的意志臣服於法律的時候,自由與必然的對立就消失了。必要的是合理的也是本質的,而當我們將其作為法律而認可,並且將其視為我們獨自本質的實體來遵循,我們就是自由的:於是客觀與主觀的意志就得到和解並且成了一個相同而完美的整體。111

    +
    + +

    對於以上的論點,黑格爾舉了一個例子來說明:當一個雅典公民在做作為一個公民所應做的事的時候,他做起來就像出於本能一般,然而若加以反省,其實這位雅典公民在做這事時,已經運用了他的意志,然而他同時也正在完成他的責任。因此,對於處在共同體內的公民來說,自由和必然是可以同時存在而不相衝突的。112

    +

    黑格爾反對人在原始自然狀態之下是自由的,而國家的出現則約束了這個自由的說法。因為他認為人在自然狀態之下所擁有的不是自由,而是暴力、不受約束的自然的衝動、非人性的作為以及情感。國家雖然給人帶來了限制,不過所限制的是這些粗野不文的衝動,這個限制是自由的意識產生的手段。黑格爾認為將自由僅從形式上與主觀上的意義去了解是錯誤的,這樣的錯誤看法才會將對於未馴服的衝動的限制視為對自由的限制。「反之,這樣的限制反而是解放的必要條件,而社會與國家則是自由實現的必要情境。」113

    +

    由此我們可看出黑格爾對於歷史發展的觀念是樂觀的,他相信歷史是單線發展的,而在這個單線發展中的主題就是精神對於自由之自覺的開展。朵伊森在柏林大學就讀的時期深受黑格爾思想的影響,然而因為朵伊森也有古典語言學堅實的考證基礎,所以朵伊森重視經驗研究的重要性。對朵伊森而言,人類對於歷史的掌握只能從經驗出發,而像黑格爾《歷史哲學》所使用的玄思方法是不能掌握歷史真正的意義。這就是他與黑格爾的不同之處。朵伊森對黑格爾的批判主要的立足點就是在於朵伊森對於歷史研究所採取的態度與黑格爾不同。朵伊森認為黑格爾的歷史哲學所採用的哲學「玄思」 (Spekulation) 方法是錯誤的。

    +

    朵伊森在寫給出版商培特斯 (Friedrich Perthes) 的信件中指出「您〔培特斯〕藉由一段嚴厲但正確的話語指出在哲學的玄思的道路上找不到神,是的,只能找到一個絕對 (ein Absolutes) ,然而這不是神。多年來對哲學的鑽研,以及最後在黑格爾指導之下的努力,也使我迫切地感覺到一個相似的體認。」114 朵伊森認為透過黑格爾式的哲學玄思是無法找到上帝的。「所有人類認知的基礎是經驗的,」115 而「與經驗認知相對的並非玄思,而是絕對的認知 (die absolute Erkenntnis) 。這是直接,而且只屬於神的認知方式。」116 即使人透過哲學的方式來觀察所有人類與自然的經驗,並且由其中的相互關連得知了在其中運行的律則,然而「律則中的律則仍然無法被得知。」117 朵伊森認為人們在歷史中找到了律則以及發展的公式,然而「這些並非我們所尋找的神……然而那個我們視為律則中的律則,視為唯一的,在其中所有的保證、生活與目的都建立在其上的,那個除了透過啟示之外無法以其他方法得知的,那就是神。當人們以信仰來尋找的話,就可以找得著祂。」118 所以朵伊森認為黑格爾的哲學玄思並不能找到上帝,而企圖用這種方法尋找上帝是褻瀆的行為。

    +

    在 1835 年史特勞斯 (David Friedrich Strauß, 1808-1874) 出版了作品《耶穌傳》 (Das Leben Jesu) ,這部作品以理性主義的批判立場,區分「歷史的耶穌」與「神話信仰的耶穌」。朵伊森對於這部作品相當反感,他認為黑格爾的方法所導致的結果就是這種瀆神作品的出現,也正因為如此,朵伊森就更堅決地與黑格爾及其學派劃清界線。119 儘管如此,朵伊森在思想上仍然難以脫離黑格爾的影響。

    +

    黑格爾認為世界史就是上帝實現其計劃的場所,而朵伊森則更為強調神意的無所不在。「我是那麼地沈浸在神無所不能的統治之中,以致於我認為,連一根頭髮從頭上掉下來都不可能不是祂的旨意。」120 然而人因為其本身的有限性,無法完全理解其中的奧妙。儘管如此,朵伊森認為人類仍應該在其有限能力的範圍之內盡力追求上帝的蹤跡。

    + +
    +

    科學崇高的使命就是,企圖從有限與人性的角度出發,去趨近基督教誨中的真理對我們所啟示的事物。並且更精確地說:歷史學家並不能透過進入個別事物來掌握已發生事物的必然性 (Notwendigkeit) ,如果這些事物都只是日常生活的事件;然而我們相信,在所有事物,甚至是最渺小的事物中,神的永恆領導在其中都是有力而充滿關照的。人類以及其意志的自由,自然的法則與其變化,在形態與事件之中可見的偶然而武斷的進展,這一切都不是別的,而是普遍而偉大的必然性的工具。121

    +
    + +

    由此朵伊森清楚地指出歷史研究者對於史料所應採取的心態,他認為如果將史料只是為「日常生活的事件」,只重視史料表面的意義,只重視史料考證的層面,那麼這些事件就永遠只是偶然而瑣碎的,永遠無法得到這些史料真正的意義。

    +

    在 1826 年,蘭克 (Leopold von Ranke, 1795-1886) 與黑格爾的學生李歐 (Heinrich Leo, 1799-1878) 之間引發了一場論戰,在這場論戰之中,蘭克主要堅持的是歷史作者不應該對歷史人物做出任何道德評判,而應該把歷史人物及其思想放進他所屬的歷史脈絡中去考察,而李歐則認為對於歷史人物應該以道德標準來評判,並且應該將歷史人物放進整個世界史的脈絡裡去考察。事實上蘭克並不反對通則化,他認為所有個別事物背後的共同連結就是神,而從每個個別事物之中可以運用詩性的方式來掌握其普遍性。然而蘭克在他的歷史研究之中卻很少做出這種從個別事物中求取普遍性的嘗試,這就是他與李歐之間最大的歧異之處,可以說兩者之所以會引發論爭,不在於對歷史觀點不同,而在於手段的互異。122

    +

    因為蘭克對史料考證的堅持,以及兩者之間政治立場的對立,朵伊森將蘭克批評為只會重視史料考證的史家,「蘭克或者至少是他的學生……將事實的可靠性放在最高的位置,為的是說明歷史的趨勢;於是這個工作便成了無止境的,而可確定的是一個絕對瑣碎而負面的結果。」123 相較之下,他對李歐雖有批評,但對他的觀感就較為正面:「李歐的觀點整體上來說是屬於新哲學的;如果他的觀點不要那麼地具有意圖性 (absichtlich) ,我就會完全認同他的說法。當他只追求發展的方向,是否遵循或偏離這個發展的道路,那麼我相信,他就放棄了真理 (Wahrheit) 。」124 朵伊森認為任何一段歷史的發展,就算其疏離了歷史發展的核心,「它的意義不只決定於這個疏離而已,而是這個疏離也是個必要的階段,」125 也就是說,即使是偏離歷史發展軌道的歷史階段,也應該受到正面的看待,「即使神的精神也不是不會停留在其中。」126 就是這樣的精神驅使朵伊森從事希臘化時代的研究,也就是因為世界上所有大大小小的歷史事件都是上帝計劃中的一部份,都具有神聖的意義,所以朵伊森才會認為歷史研究最重要的目的就是在彰顯神義論,企圖從看似偶然的個別事物之中看出它們都是上帝偉大計劃中的重要部份。

    +

    儘管朵伊森對於黑格爾的歷史哲學有所批判,但是朵伊森在很大的程度上仍然受到黑格爾的影響,在蘭克與李歐的論戰之中,朵伊森較為傾向黑格爾的學生李歐(雖然並非全盤接受)。由此可看出朵伊森較為傾向以世界史的眼光來談論歷史。更重要的是,朵伊森與黑格爾都將歷史視為一個單線的發展,朵伊森指出「但是在一切眾多歷史之上有一個唯一的歷史 (über den Geschichten ist die Geschichte) 。」127 這個唯一的歷史 (die Geschichte) 是單數,並且加上定冠詞的歷史。而朵伊森所重視的是「我們應該用什麼方法說明至高的歷史 (die Geschichte) 與諸史 (die Geschichten) 之間的分野。」128 這個唯一而至高的歷史是遵循著一定的方向運行的,然而歷史運行的過程中也不是完全平順,一律以平穩步伐前進的:「人類的整體生活是一個沒有間斷的河流—在數以千計的漩渦與暗流上下浮沈之中,有一個方向,所有的水流或快或慢都遵循著這個方向。不是說這個河流不會在岸邊積成小水塘而停滯,然而下一波的洪流又會將其捲襲前進;進步並不是說,人類作為的每一個形式都同時而同步地向上發展。」129

    +

    儘管如此,朵伊森卻不像黑格爾一樣以玄思的方式詳細描繪歷史的發展應是如何,在朵伊森的眼中,黑格爾歷史哲學中的「精神」簡直是僭越了上帝的地位,他不認為上帝在世界史中的偉大計劃是可以透過哲學玄思就被人清楚地了解的。朵伊森對於歷史學者所應該扮演的角色是更為謙虛的,他認為「歷史知識並不是『光與真理』,但卻是對『光與真理』的追求、讚美及宣導;如《約翰福音》所說: ouk en to phos, all'hoti martyrese peri tou photos. (他不是那光,乃是要為光做見證)。」130 由此可見,朵伊森認為歷史學者的工作,並不是歷史中絕對真相的發掘。他認為歷史學者所應做的,是透過對於歷史的研究,來追求並宣揚隱含在大大小小事件之中的神聖意義,及其中的相互關聯。

    +

    在黑格爾的《歷史哲學》中,個人的重要性與其在世界史中扮演的角色為何有關,黑格爾提出了「世界史的個人」 (die welthistorischen Individuen) 的概念,黑格爾認為世界史的個人就是那些在成就私人目的的同時卻因此對世界史的發展產生了長遠影響的人物。黑格爾以凱撒為例,他指出「凱撒為了保全他自己的地位,榮譽與安全而奮鬥,而他對於反抗者的勝利,當他的勢力及於羅馬帝國各省的統制權時,他同時也等於征服了整個帝國:於是在不改變國家憲法的情況之下使個人成為國家的獨裁者。」131 而黑格爾認為凱撒此舉對凱撒本人來說只是一個消極的作為,只是成為羅馬的獨裁者而已,然而對於羅馬以及世界史的發展來說卻具有必要的意義,所以凱撒的作為「不只是他讓個人獲得利益而已,而是一個直覺 (Instinkt) ,這個直覺將時機已經成熟的事業加以完成。這就是歷史的偉大人物,在其中個人的目的包含了世界精神的意志的要素。」132

    +

    朵伊森在《亞歷山大大帝傳》裡並未刻意將亞歷山大大帝做為黑格爾所說的「世界史的個人」來描寫,然而朵伊森也有意將亞歷山大描寫為為了個人征服波斯的私人目的而同時達到了東西文化交流這個世界史任務的世界史人物。尤其是在 1833 年出版的第一版的《亞歷山大大帝傳》裡朵伊森更為強調東西的對立,藉此彰顯亞歷山大在其中扮演的重要角色:「正如創世紀的第一天神將光與暗分開,並且從夜晚與早晨中造出了第一個日子,同樣地,自歷史的第一天開始夜晚與早晨的民族133 首次分離以致於永恆地具相互敵對也永恆地追求和解。」134 而就是這樣的敵對與和解的渴望,使得東方的波斯帝國向西侵犯自由的希臘:「這個民族的渴望是個失落的天堂,成長中思想的恐懼,驅使了早晨之地的兒子離開這個天堂,他徒勞無功地爭取自由……他徒勞地趨向夜晚之地,與自由的民族相對立。」135 這就是朵伊森筆下波希戰爭的由來,而波斯帝國與希臘之間的敵視與對立,就終結於亞歷山大的手上。然而朵伊森最為關注的,不是亞歷山大個人的征服亞洲的動機,而流傳下來的史料也不足以讓他對於這個亞歷山大個人心理層面的問題做出完美的解釋。朵伊森所重視的,是亞歷山大在追求個人的目的之時,達到了什麼樣的世界史意義。這個以世界使意義為出發點的觀察方式,朵伊森稱之為歷史觀察 (geschichtliche Betrachtung) :

    + +
    +

    歷史觀察與非歷史觀察方法也有相關性。那些在個別行為者個別目的之下發生的事,對歷史而言並不是研究的目的,而是手段與條件;它們只是變遷脈絡中關鍵時刻的原因。亞歷山大的目的,他之所以征服亞洲,並不是要使亞洲希臘化。也許他利用希臘化做為他野心勃勃征服世界計劃的一個工作。而歷史微笑著說:在他野心中所企望的 (Zweck) ,對我而言卻是使亞洲希臘化的工具。136

    +
    + +

    由這段話可以看出,朵伊森或多或少是以黑格爾所說的「世界史個人」來看待亞歷山大與他的事業。

    +

    朵伊森說他將希臘化時代視為上古時代中的「現代」來處理,137 而在三卷的《希臘化時代史》之中,作者最詳細描寫的就是這個進入現代的過程的政治層面。在他的筆下,從諸城邦林立的情況以致於區域性主權王國的形成,這個發展之中的每一步都像是一個偉大計劃中的一部份,都是是環環相扣,缺一不可的。

    +

    首先是雅典自梭倫 (Solon) 以來自由的發展,朵伊森認為在自由與民主制度是這一連串發展中重要的一環,所以他寧可支持評價不高的克里昂,而非懷疑民主制度的修昔的底斯。

    +

    接著希臘城邦獨立自主性的逐漸衰微,城邦的自由之所以消失,與自由的過度發展有關,自由與啟蒙思想的過度發展,導致了詭辯術的發展與傳統宗教根基的動搖,在這樣的情形之下,朵伊森認為自由而獨立的城邦已經達到了它們的歷史任務,而應被下一個階段的發展取代,於是在這時仍然堅持城邦獨立自主的德謨提尼斯便受到朵伊森嚴厲的批判。希臘啟蒙思想隨著亞歷山大的東征向外傳播,又動搖了東方世界傳統的根基。在這樣的情形之下亞歷山大建立起了一個龐大的帝國。

    +

    然而朵伊森指出亞歷山大的帝國也只不過是歷史的工具,它的用處在於消滅東西原有的政治傳統,並且促進東西的交流,一旦它的功能達成了,為了下一個階段的發展,這個龐大的帝國就必須被毀滅。

    + +
    +

    繼承者之間的鬥爭就象徵著這個漫長而血腥的過程,在這個過程中他們的力量逐漸毀滅,最終會彰顯出新的『教化』。為了實現這個教化,統一的帝國必須沒落,歐亞非各地馬其頓的掌權者首先必需消滅馬其頓的王室……接下來相互攻擊毀滅……藉此最終才能在統一的希臘化世界教化 (Weltbildung) 之下,以及在各自獨立的王國之中成就了新的民族特質,並且塑造出新的『國家個體性』 (Staatindividualitäten) 。138

    +
    + +

    所以朵伊森認為亞歷山大龐大帝國的崩解,以及繼承者之間血腥漫長的鬥爭,都是為了建立起主權國家體系所必須經歷的階段,這些都是歷史的工具。這一系列漫長而混亂的鬥爭並非毫無意義的混亂狀態,而是上帝精心安排的結果。而朵伊森對於處在這些歷史當中的個人,所給予他們的道德評價,也就依據他們是否遵循歷史的潮流而定。就因此朵伊森對於堅持維護城邦獨立自主的德謨提尼斯就給予負面的評價。而對於同樣具有冒險精神和英雄性格的「攻城者」底米特流斯 (Demetrius the Besieger) 與伊比魯斯 (Epirus) 國王皮魯斯 (Pyrrhus) 兩人,朵伊森也分別給予了相當不同的評價,因為底米特流斯身處在繼承者的時代,「他的一生,充滿動盪與冒險性,歷史上少有能與之相比擬者,就像整個繼承者時代本身一樣,是場無止盡狂風暴雨般的騷動,最終自己將力量消耗殆盡……在底米特流斯之中這個少有的時代呈現出其發酵醞釀的特質。」139 所以儘管底米特流斯最後失敗了,但是在朵伊森筆下他成了一個體現出繼承者時代特質的悲劇英雄。而皮魯斯身處的時代已進入了延續者的時代,混亂的狀態將要過去,而穩定的國家體系逐漸成形。所以朵伊森指出,儘管皮魯斯「比所有人都還要類似偉大的亞歷山大,」140 然而「騎士精神與冒險家的時代已經過去了,安提哥那 (Antiochus) 〔二世〕身上具備了新時代的王國所需要的特質,而非皮魯斯。他們之間的鬥爭是兩個時代之間的鬥爭,而政治家最終戰勝了英雄。」141 所以朵伊森認為皮魯斯企圖在一個動亂將要結束,而穩固發展將要開始的時代裡發展他的英雄事業,最後終究是徒勞無功的。

    +

    希臘化時代是個物質利益發達的時代,物質利益往往與享樂主義連結在一起,被視為負面的名詞,於是,傳統上希臘化時代就被視為一個只重視肉體享受而無精神創造力的墮落時代。然而朵伊森認為享樂主義與物質利益的興起也應有其歷史地位:

    + +
    +

    我之所以使用這個被鄙視的名詞『享樂主義』,為的是表明我不會附和那些對於所謂的物質利益所發出的悲歎呻吟……為了理解希臘化時代,我們需要指出它們的正當性。如果不給予享樂主義其應有的權利與地位,那麼一個社會共同體的倫理的成形與基督教超越律法的到來就永遠不可能……克服世界並不意味著詛咒世界或是跳脫世界。142

    +
    + +

    因此朵伊森對於否定肉體享受與物質利益的正當性,進而否定整個希臘化時代的觀點是採取反對態度的。因為對他來說,歷史的研究就是要彰顯神義論,因此這個時代即使充斥著物質的享受,但是這正是神為將來基督教興起提供的預備條件。

    +

    總之,朵伊森將整個世界史視為上帝偉大計劃施展的場所,雖然人因為其自身的有限性,無法完全洞悉此一計劃的全貌,然而,透過經驗的研究,人仍可由此得知其中的一些蛛絲馬跡,藉此確定神意的無所不在,也了解到歷史上所發生的任何事件,無論是正面或負面,光明或黑暗,看來是進步或是倒退的,這一切的發展其實都未偏離神的旨意,即使極端負面的發展,也是神偉大計劃中的一部份,在世界史的眼光之下就具有其合理性,而朵伊森的希臘化時代研究便是建立在這個觀點之上。這樣的歷史觀點,對朵伊森來說,並不只是學院內知識上的滿足而已,更重要的是,它為朵伊森提供了實踐的準則與參考,透過這樣的歷史觀點,朵伊森可以確信他站在歷史發展正確的一方。

    + +

    六、結論

    + +

    總而言之,朵伊森相信歷史的每個階段都包含了上帝的旨意,都屬於祂偉大計劃的重要部份,即使在希臘化時代這樣混亂動盪的時代中,也可見到祂的身影。因此,對於朵伊森來說希臘化時代就不再是黑格爾口中「對我們來說沒有多大的趣味」的混亂與衰敗的過渡時期在朵伊森神義論的觀點之下。希臘化時代所有的「惡」,包括異教傳統的崩解等等,正是替未來更高的「善」的出現排除障礙,可說是「必要之惡」。希臘化時代便因為它是替基督教出現鋪路的預備階段而更顯重要。由此可見朵伊森的《希臘化時代史》背後是有堅定的信仰做為支持的。

    + + + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +
    + +
    +
    * 本文為作者碩士論文《德國史家朵伊森 (J. G. Droysen) 的歷史思想與現實意識》中之一章,今略經修改後刊登於本刊。 (Back)
    +
      +
    1. J. G. Droysen, Geschichte des Hellenismus I, Geschichte Alexanders der Große, Erich Bayer Hg., reprint of th e Edition of Tübingen 1952-1953 (Darmstadt: Primus Verlag, 1998), 3. (Back)
    2. +
    3. A. D. Momigliano, “J. G. Droysen Between Greeks and Jews,” in G. W. Bowersock & T. J. Cornell eds. , Studies on Modern Scholarship (Berkeley: University of California Press, 1994), 147- 148. (Back)
    4. +
    5. Thucydides, History 2:68, in Thucydides, History, Vol 1. The Loeb Classical Library, with an English tr. by C. F. Smi th (Cambridge MA: Havard Universi ty Press, 1956),. 382-385. (Back)
    6. +
    7. The Oxford Classical Dictionary, 3rd. ed. , s. v. “Hellenism, Hellenization.” (Back)
    8. +
    9. 《次經》為猶太教未被收入正典 (Kanon) 之中的文章,然而在舊約希臘文的「七十士譯本」 (Septuagint, LXX) 中這些文章被作為「後典」 (deuterokanonische Bücher) 而收錄在內。天主教將這些經典視為正點,而開啟宗教改革的馬丁.路德 (Martin Luther, 1483-1546) 則將這些經典排除在正典之外。 (Back)
    10. +
    11. 《次經.第二馬加比書》, 4:13 。 (Back)
    12. +
    13. 《新約.使徒行傳》, 6:1 。 (Back)
    14. +
    15. 《新約.使徒行傳》, 9:29 。 (Back)
    16. +
    17. Momigliano, “J. G. Droysen Between Greeks and Jews,” 149. (Back)
    18. +
    19. O. Hinze, “Johann Gustav Droysen”, Soziologie und Geschichte (Göttingen: Vandenhoeck & Ruprecht, 1964), 464; 值得注意的是,德國的大學教育制度與美國有很大的不同。德國大學的教師位階由低而高分別為 Privatdozent, Professor Extraordinarius (ausserordent licher Professor), 以及 Professor Ordinarius (ordent l i cher Professor) 。後兩者接受政府發給的薪水,而 Privatdozent 則無,所有的只是在大學裡授課的權利,而收入則來自聽課學生所繳交的費用。要獲得大學教師的資格除了要有博士學位之外,還要通過 venia legendi 的認可,才有資格 (habil itiert) 在大學裡授課。
      +此外, Privatdozent 又可再細分為 planmäßiger Privatdozent 以及 ausserplanmäßiger Privatdozent 。關於德國大學教師制度,可參考 F. K. Ringer. The Decline of the German Mandarins, The German Academic Community, 1890-1933, reprint . (Hanover NH: Wesleyan University Press, 1990), 32-36 。在 Ringer 的書中, Privatdozent 被英譯為 “Instructor”, Professor Extraordinarius 被譯為“associate professor”, 而 Professor Ordinarius 則被譯為“full professor” ,故本文參考 Ringer 的方式將此三者分別中譯為「講師」、「副教授」,以及「正教授」,但是應特別注意的是這三者與與美式教育體系中相對應的職位有很大的差異。 (Back)
    20. +
    21. Hinze, “Johann Gustav Droysen,” 466. (Back)
    22. +
    23. Hinze, “Johann Gustav Droysen,” 468-470. (Back)
    24. +
    25. Hinze, “Johann Gustav Droysen,” 475-477. (Back)
    26. +
    27. York 也可以被拼成 Yor ck 或 Jork 。 (Back)
    28. +
    29. 參照 J. Rüsen, Begriffene Geschichte, Genesis und Begründung der Geschichtstheorie J. G. Droysens (Paderborn: Ferdinand Schöningh, 1969), 39-40 中註釋 85 的說法。 (Back)
    30. +
    31. J. G. Droysen, Historik, Rekonstruktion der ersten vollständigen Fassung der Vorlesungen (1857) Grundriß der Historik in der ersten handschriftl ichen (1857/58) und in der letzten gedruckten Fassung (1882), ed. Peter Leyh (Stuttgart-Bad Cannstatt: Frommann-Holzboog, 1977). (Back)
    32. +
    33. 余琛,〈引論〉,收入朵伊森著,胡昌智譯,《歷史知識的理論》(台北:聯經, 1987 年,第二版),頁 viii 。 (Back)
    34. +
    35. 朵伊森,《歷史知識的理論》,頁 9 。 (Back)
    36. +
    37. 同上,頁 98 。 (Back)
    38. +
    39. 關於黑格爾對朵伊森的影響以及兩者之間的歧異,在本文的第五部份有更詳細的討論。 (Back)
    40. +
    41. Herman Funke, “F. A. Wolf” in W. W. Briggs and W. M. Calder III eds. , Classical Scholarship, A Biographical Encyclopedia (Garland Press, 1990), 523-525. (Back)
    42. +
    43. Wilamowitz-Moellendorff, Hi story of Classical Scholarship (Balt imore: The Johns Hopkins University Press, 1982), 120-123. (Back)
    44. +
    45. Herman Funke, “F. A. Wol f”,. 525-526. (Back)
    46. +
    47. J. G. Droysen, “Theologie der Geschichte”, in Rudolf Hübner ed., Historik, 371. (Back)
    48. +
    49. Ibid. (Back)
    50. +
    51. vasa irae, 見《舊約.耶力米書》 50:25 ,以及《新約.羅馬書》 9:22 。 (Back)
    52. +
    53. Ibid., 373. (Back)
    54. +
    55. Ibid. (Back)
    56. +
    57. 李希騰堡為德國物理學家與作家。 (Back)
    58. +
    59. Ibid. (Back)
    60. +
    61. Ibid., 374-375. (Back)
    62. +
    63. J. G. Droysen, Geschichte des Hel leni smus III, 414. (Back)
    64. +
    65. Ibid., 415. (Back)
    66. +
    67. Ibid. (Back)
    68. +
    69. Ibid. (Back)
    70. +
    71. J. G. Droysen, “Theologie der Geschichte,” 383. (Back)
    72. +
    73. Ibid. (Back)
    74. +
    75. Ibid. (Back)
    76. +
    77. Ibid. (Back)
    78. +
    79. Ibid., 384. (Back)
    80. +
    81. Ibid. (Back)
    82. +
    83. Ibid., 強調為朵伊森所加。 (Back)
    84. +
    85. Ibid., 385. (Back)
    86. +
    87. J. G. Droysen, Geschichte des Hel leni smus I, 40-42. (Back)
    88. +
    89. Ibid., 60. (Back)
    90. +
    91. Ibid., 強調為朵伊森所加。 (Back)
    92. +
    93. J. G. Droysen, Geschichte des Hel leni smus I, 438. (Back)
    94. +
    95. J. G. Droysen, Geschichte des Hel leni smus III, 37. (Back)
    96. +
    97. Ibid., 37-39. (Back)
    98. +
    99. J. G. Droysen, Geschichte des Hellenismus I, 441. (Back)
    100. +
    101. Ibid. (Back)
    102. +
    103. Ibid. (Back)
    104. +
    105. J. G. Droysen, Geschichte des Hel leni smus III, 5 . (Back)
    106. +
    107. Ibid., 185. (Back)
    108. +
    109. Ibid. (Back)
    110. +
    111. Ibid. (Back)
    112. +
    113. Ibid. (Back)
    114. +
    115. Ibid., 13. (Back)
    116. +
    117. Ibid., 13-14. (Back)
    118. +
    119. G. W. F. Hege l, Werke 12, Vorlesung über die Philosophie der Geschichte, based on the Werke of 1832-45 newly edi ted edi tion, ed. Eva Moldenhauer and Karl Markus Michel (Frankfurt am Main: Suhrkamp, 1999), 276. (Back)
    120. +
    121. Ibid., 335. (Back)
    122. +
    123. Ibid., 338. (Back)
    124. +
    125. Ibid., 385. (Back)
    126. +
    127. Ibid., 386. (Back)
    128. +
    129. 朵伊森,《歷史知識的理論》,頁 52 。 (Back)
    130. +
    131. J. G. Droysen, Geschichte des Hel leni smus III, 6. (Back)
    132. +
    133. Ibid. (Back)
    134. +
    135. Ibid. (Back)
    136. +
    137. Ibid. (Back)
    138. +
    139. 無宇宙論:哲學思想,認為現實世界只是不真實的幻象。 (Back)
    140. +
    141. Ibid. (Back)
    142. +
    143. Ibid. (Back)
    144. +
    145. Ibid. (Back)
    146. +
    147. Ibid., 8. (Back)
    148. +
    149. Ibid. (Back)
    150. +
    151. Ibid. (Back)
    152. +
    153. Ibid. (Back)
    154. +
    155. Ibid. (Back)
    156. +
    157. Ibid., 9. (Back)
    158. +
    159. Ibid. (Back)
    160. +
    161. Ibid. (Back)
    162. +
    163. Ibid. (Back)
    164. +
    165. Ibid., 14. (Back)
    166. +
    167. Ibid., 15. (Back)
    168. +
    169. Ibid. (Back)
    170. +
    171. Ibid. (Back)
    172. +
    173. Ibid., 16. (Back)
    174. +
    175. Ibid. (Back)
    176. +
    177. 優赫美羅斯, Messene 人,生卒年不詳。曾替卡山德服務。他寫作過一部今已佚失的小說(可能寫作於替卡山德服務的時期)。在這部名為《神聖歷史》 (Hiera Anagraphe) 的作品中,他指出烏拉諾斯 (Uranos) 、克羅諾斯 (Kronos) 以及宙斯 (Zeus) 都曾經是偉大的國王,後來被崇拜他們的人民尊崇為神祇。優赫美羅斯的思想源於希臘史詩中人神界線的模糊,而他這樣的說法也可以被視為希臘化時代統治者神化崇拜的合法性依據。 (Back)
    178. +
    179. Ibid, p. 17. (Back)
    180. +
    181. Ibid. (Back)
    182. +
    183. Ibid. (Back)
    184. +
    185. Ibid. (Back)
    186. +
    187. Ibid. (Back)
    188. +
    189. Ibid., 424. (Back)
    190. +
    191. Ibid. (Back)
    192. +
    193. J. G. Droysen, Geschichte des Hel leni smus I, 208. (Back)
    194. +
    195. Ibid., 443. (Back)
    196. +
    197. Ibid., 444. (Back)
    198. +
    199. Ibid. (Back)
    200. +
    201. Ibid. (Back)
    202. +
    203. Ibid. (Back)
    204. +
    205. J. G. Droysen, “Theologi e der Geschichte,” 371. (Back)
    206. +
    207. Hegel, Philosophie der Geschichte, 28. (Back)
    208. +
    209. Ibid. (Back)
    210. +
    211. Ibid. , 53. (Back)
    212. +
    213. Ibid. , 540. (Back)
    214. +
    215. Ibid. , 30. (Back)
    216. +
    217. Ibid. , 31. (Back)
    218. +
    219. Ibid. , 55. (Back)
    220. +
    221. Ibid. , 57. (Back)
    222. +
    223. Ibid. (Back)
    224. +
    225. Ibid. , 59. (Back)
    226. +
    227. J. G. Droysen, Texte zur Geschichtstheorie, 80. (Back)
    228. +
    229. Ibid. (Back)
    230. +
    231. Ibid. , 81. (Back)
    232. +
    233. Ibid. (Back)
    234. +
    235. Ibid. (Back)
    236. +
    237. F. Gilbert, Johann Gustav Droysen und die preußisch-deutsche Frage, 40-41. (Back)
    238. +
    239. J. G. Droysen, Texte zur Geschichtstheorie, 78. (Back)
    240. +
    241. Ibid. (Back)
    242. +
    243. G. G. Igge rs, The German Conception of History (Middletown, Conn.: Wesleyan University Press, 1984), 66-69. (Back)
    244. +
    245. J. G. Droysen, Texte zur Geschichtstheorie, 79. (Back)
    246. +
    247. Ibid. (Back)
    248. +
    249. Ibid. (Back)
    250. +
    251. Ibid. (Back)
    252. +
    253. 朵伊森,《歷史知識的理論》,頁 88 。 (Back)
    254. +
    255. 同上,頁 86 。 (Back)
    256. +
    257. J. G. Droysen, “Theologi e der Geschichte,” 385. (Back)
    258. +
    259. 朵伊森,《歷史知識的理論》,頁 92 。「他不是那光,乃是要為光做見證」出自《新約.約翰福音》 1:8 ,原文為 ouk en ekeinos to Phos, all'hina martyrese peri tou Photos. (Back)
    260. +
    261. Hegel, Philosophie der Geschichte, 45. (Back)
    262. +
    263. Ibid. (Back)
    264. +
    265. 夜晚與早晨的民族:指西方與東方的民族,因為太陽早晨時在東方,而往西方運行時則接近夜晚,所以在德文裡較為文學的說法以夜晚 (Abend) 指西方,早晨 (Morgen) 指東方;而「夜晚之地」 (Abendland) 與「早晨之地」 (Morgenland) 則分別指西方與東方的國度。 (Back)
    266. +
    267. J. G. Droysen, Geschichte Alexanders des Grossen, reprint of the original edition (Leipzig: Alfred Kröner, 1932) , 1. (Back)
    268. +
    269. Ibid. , 1-2. (Back)
    270. +
    271. 朵伊森,《歷史知識的理論》,頁 76 。 (Back)
    272. +
    273. J. G. Droysen, “Theologi e der Geschichte,” 384. (Back)
    274. +
    275. J. G. Droysen, Geschichte des Hellenismus II, 113-114. (Back)
    276. +
    277. Ibid. , 416. (Back)
    278. +
    279. J. G. Droysen, Geschichte des Hellenismus III, 132. (Back)
    280. +
    281. Ibid. , 134. (Back)
    282. +
    283. J. G. Droysen, “Theologi e der Geschichte,” 377. (Back)
    284. +
    +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/004/article03.html.html b/htdocs/htc/newsletters/004/article03.html.html new file mode 120000 index 0000000..6a7bb08 --- /dev/null +++ b/htdocs/htc/newsletters/004/article03.html.html @@ -0,0 +1 @@ +article03.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/004/article03.html.xhtml b/htdocs/htc/newsletters/004/article03.html.xhtml new file mode 100644 index 0000000..9652385 --- /dev/null +++ b/htdocs/htc/newsletters/004/article03.html.xhtml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + +王晴佳教授訪談錄 + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    王晴佳教授訪談錄

    + +
    蕭道中 整理
    + +
    +

    編者按:本刊為探求西洋史學者王晴佳之學思過程,於 2001 年 1 月 8 日與王晴佳教授進行訪談。參與此次訪談者有黃明田與蕭道中。現將訪談紀錄由蕭道中整理如下,以饗讀者。

    +
    + +
    +

    黃:可否針對老師個人的學思過程,可以從老師接觸歷史或從小一些想法開始談起。

    +
    +
    +

    王:其實我開始學習歷史的時間並不是很早,我小時候的情況跟你們不大一樣,我是在文化大革命當中長大的。 1965 年進小學,當年文化大革命開始。中學畢業的時候(那時候沒有國中跟高中的區別)已經是 1976 年,我是當年春天畢業,毛澤東則是當年九月九號過世,所以我是在文化大革命中畢業的。當時也是懵懵懂懂,不過那時候也看了不少書,像小說,也看了一些通史類的歷史書。除了小說之外,也不知道是什麼原因,總感覺還希望看一些比較實在的一些東西,但是只看了一些。因為文革時期時候我在農村勞動,文革當時都是這樣一定要去的。當時當然想要離開這個地方,想要考大學。(鄧小平上台以後我們就可以考大學)。我是第一批考上大學的,當時考的時候,風氣也是要學數理化,所以我有點想考數理化,這是受到風氣的影響,可是當時個人興趣還是在文史哲這方面的。開始準備的時候,由於文革時候學習非常糟糕,所以我數理化的基礎特別差。所以我要先準備數學,再準備物理、化學,時間上實在是來不及。我父母當時給了我封信,就是說你現在主要想法就是要考進大學,有沒有可能這次先考文科試一下。我自己想想蠻好的,這樣準備比較輕鬆一點,因為我自幼感覺對文科方面的書看的非常多,自認為應該還是可以的。考完試之後我也確實感覺考得蠻不錯,不是說特別理想,但是我感覺考得還可以。如果這一次考不上的話,可能會換考工科或其他類的,結果考上了。我就進了華東師範大學。那個時候這所大學是全國最大的一個大學,因為它當時兼併了所有的大學。當時的名稱叫上海師範大學,後來又分開來改成華東師範大學。它是一個所謂的部屬重點大學,當時一個北京師範大學,一個華東師範大學兩個,一個北一個南。當時的這個學校西洋史的幾位老師都非常好。華東師範大學在那個階段,歷史系排名很前面,所以我還滿得意的。但是,我當時填的是哲學系,這與我後來對史學理論比較有興趣,可能有關係。我對文學也滿感興趣,但我感覺若有才華,未必要唸中文系。若要寫小說,無論任何系都可以。為了學習知識,所以我是哲學、歷史、文學這樣子排的。偶然因素,後來進了歷史系,我覺得也是滿好的。作這個決定的原因,後來想,唸西洋史可能也是個因素。因為文革之後,考進大學的人都非常優秀,他們年紀比較大,比我大最多的到十一歲,他們都是在文革中讀了不少書的,儘管當時我也讀了不少書,但還是不能比。他們有國中、高中的基礎,加上愛好文史學而又再學,所以基礎非常好。我當時有一堂姑父,是復旦大學歷史系教授,我與他談論到歷史這門學問要如何學?他說我還年輕,當時我二十歲,下鄉已兩年,比一般人晚,但也沒晚多少,很多人上大學都是三十多歲了,知識非常好,我覺得與他們比起來仍是不行,所以我堂姑夫就建議我在外語上多花點工夫,或在世界史方面多花些功夫。不過我在唸書時,對中國史仍感到興趣,特別是明清時代。畢業後要考研究生,我發覺當時有位郭聖銘老師,是中央大學一九三五或三六年畢業的,是沈剛伯先生的學生,是沈師母的學長,他後來跟我談到些關於他們的事。他當時剛出版一本《西方史學史概要》,是大陸第一本這類著作。當時我剛好畢業,他正開此課程。這老師文筆很好,雖然口才稍不行。大陸考研究所不是考所的,而是跟老師考的,郭聖銘當時是召集委員,收兩位學生,我考上了,另一位是女生。考上後跟著他唸,感覺滿好,也引起我的滿大興趣,並讀了不少書,主要是有關西洋史學史經典的中文版,如希羅多得、修昔底的斯等。可能也是年輕,盡管我也做中國史研究,但對當時所讀之書,印象很深。所以現在即使談西方史學發展,也比較能自如談,因為起碼都讀過,不管是中、英文,我都花下工夫,當時我花在英文方面的時間也多,能考上研究所,與英文不錯也是有關的。不過,英文僅限閱讀方面,說的方面還是不行。我考上研究生是一九八二至八四年時,當時大陸正是文化熱的時候。文化熱就是大陸剛開放,一九八0年大陸開始送學生出國留學時。翻譯的文學名著能在書店販售,買的人是大排長龍;因為與西方隔絕,對西方文化新知封閉十多年,大陸對於西方新知是非常的饑渴。對西洋史學有興趣。我的碩士論文做的是美國史家比爾德 (Charles Beard) ,討論歷史相對論,因此對西洋史學理論較有接觸,因緣既會,正好趕上此風潮。我想也是偶然因素,當時寫了一些有關西洋史學的文章,因為當時也很少人寫。所以現在回到大陸,很多人仍認為我對史學理論方面貢獻滿大。從一九八0年,寫第一篇文章,當時大學尚未畢業,但都是較小文章。到研究所一九八四年,就開始寫些中篇幅的文章,一直到一九八七年離開中國到國外為止,持續寫些論文。所以當時大家都知道我,並向我邀稿。我當時有位朋友是做上海史、地方史的,我則是做史學理論,他與我家人滿熟,就開玩笑說「我像是開一家在小馬路上的店,而我王晴佳呢則就像開在忠孝、南京東路上,很熱鬧的,大家喜歡看的地方」。因為馬克思主義當時已經很僵化,大家不喜歡,所以對西方新知非常饑渴,我的文章也很容易就能發表。

    +

    寫碩士論文時,在北京圖書館看到伊格斯 (Georg G. Iggers) 教授的書 New Directions in European Historiography ,借來看了半天,覺得這書寫得非常好。因為我接觸的都是比較早期,雖說是現代史學,但大都是一次到二次大戰之間的。這本書則是講二次大戰後的史學,這本書第一版是一九七五年出版,所以我就知道了伊格斯的名字。在做碩士論文時,北大有位張芝聯教授,是大陸西洋史的權威學者,英文、法文都非常流利,那時他已與外國學者有很多交流。那時我在華東師大,有位王養沖教授,以前是胡漢民的祕書,後來留法、得巴黎大學博士學位,比張芝聯教授老一輩,我去北大時,他就寫了一封信,叫我去見張芝聯教授。當時張教授借我很多書,我對他非常感激,因為我跟他根本素昧平生,結果第一次見面他就借給我兩大本原版書,其中有本 The Past Before Us 講美國史學的, Micheal Kamman 編,康乃爾大學出版,回顧美國史學發展。這些書都是在國外買到的,他說我用完再寄還給他就好。老一輩學者對我很好,包括郭聖銘老師,到現在與我仍經常交流,他現在在加州,所以得到這些名師的指導,我是非常幸運的。一九八四年,伊格斯到北京來講學,他們學校與北京師範學院有一交流計劃,他正好路過,順便到北京訪問,後來在北大、北師院、中國社科學院世界歷史所講學。當時張芝聯教授給我寫了一封信,告訴了我這一個消息,當時我已即將碩士畢業,華東師範大學已叫我留校。張芝聯教授寫信有兩個目的,其一是要我去聽伊格斯教授的課,另方面是找我做他的博士研究生。我聽了伊格斯教授的課,有些交流,不過當時英文不太好,不過他還是非常好,約我說如果願意的話可以到他的房間談談。後來與他約了見面,在他房間,用英文,當時滿緊張的。他主動問我,是否有興趣到美國唸書,我說當然有的,但是是個「 wishful thinking 」,是個妄想,他說不是,用美國話就是「 It ’ s difficult, but not impossible 」。他說回國後要寄申請表給我,我說,好的。他講話時,也很照顧我,講得很慢,基本上講的都不是生活的事,都是有關歷史的。我因為沒有看很多書,所以也無法跟他多交流。後來,我沒有考北大張芝聯教授的博士生,因為華東師大已叫我留下,所以我要上課。不過,我與張芝聯教授關係仍很好,我出國留學時他也幫我寫推薦信等。這次我在北大講課,他還刻意來聽,他年紀已經很大了;一九一八年生,今年八十三歲,但身體不錯。通過他我才開始跟伊格斯教授交往。

    +

    到了要申請學校,對美國一點兒也不清楚,當時同學告訴我,要申請學校就要申請州立學校,他們有錢會給你錢。這顯然有誤。但是我當時沒這麼想,當時我出版作品非常多,已發表三十幾篇的文章,當時如申請名校的話可能也可以去,不過我也申請了一、兩所名校,如密西根、哥倫比亞大學,他們都收我了,但是規定第一年不給錢的。之所以申請密西根大學,是因當時八五年時托福考試在大陸並不流行,但有一個是 Michigan Test ,是密西根大學辦的所以比較容易申請,申請哥大則是因為伊格斯教授也在紐約州,比較近。也因為這個因素申請了雪城大學 (Syracuse University) 。申請這所學校還有一個很奇怪的原因。因為當時看到了伊格斯在一篇文章中提到雪城大學有蘭克的圖書館,當時心理有種想法,想把蘭克的史學理論學熟。我當時也學了些德文了。結果去了那邊確實是這樣,蘭克是一八九五年去逝的,十五年後雪城大學就把他的圖書館包括椅子、桌子都買下,放在圖書館頂樓。此外雪城大學歷史系有一位做史學史的教授 Joseph M. Levine ,專研英國史學史,他現在已是 Distinguished Professor, 也有很多著作。不過他的思想比較傳統,較不願與新的史學潮流有互動,很專注於本身原先的研究主題。而伊格斯則較能跟上史學時代的發展。當時我就寫信與他聯繫, Levine 教授對柯靈烏 (R. G. Collingwood) 很有興趣,我也寫過關於柯靈烏的文章。後來雪城大學給了獎學金,反而伊格斯教授的學校那一年沒有獎學金。我想這樣圖書館也有,老師也不錯,伊格斯又在旁邊,因為那裡到水牛城也近,開車只要兩、三個小時,就選擇了雪城大學。伊格斯也說我還是可以去水牛城選他的兩三門課,當時他已經用電子郵件了,我們可以電子郵件聯絡,一學期我到水牛城三、四次就可以,他把需要讀的書告訴我,然後我交報告。所以我上過他兩、三門課。後來做論文也多次與他討論。我當時博士資格考是考西洋史的,一個領域是史學理論,另兩個是近代德國史、近代英國史。因我發現德國史學的模式在美國的十九世紀末,很快就被接受,但英國因為有自由主義傳統,所以接受得慢,且這方面的研究得少,所以我當時是想做德國史學對英國史學的影響或交流等,資格考過後,我也著手收集整理有關十九世紀到德國留學的英國史家,並做了資料庫,一共可能有二十幾人。資格考通過後,剛好是八九年發生天安門民主運動。這件事對我影響很大,有一陣很激動。為什麼我會比較衝動的原因,是因為當時文化熱時,我與一些朋友在上海譯文出版社,出了一套叢書,叫當代學術思潮譯叢等,有新聞、經濟等編委,我是歷史組的編委,共有五、六個編委,當中有兩個被抓。我在《讀書》雜誌發表文章時的編輯王焱也被抓進去半年。所以一九八九的民運對我影響很大,原先我想寫完論文就回國,沒有考慮要在美國長待。一九八九年天安門事件以後,為了想把事件的真相告訴中國人,我與幾個同學一起編資料編了一個多月,出版了資料集。後來我回學校通過德文考試,當時 Joseph Levine 教授在普林斯頓大學高級研究院做研究,所以我就去那邊,他勸我此時不要回國,但也認為若學英國史、德國史等,往後在美國教書是不易的,因為英國人都到美國尋找教書機會,中國人在美國教英國史的機會不高,因此他建議我轉向中國史。我當時想想也是對的,他還建議我如要轉向中國史就要找中國史名家討論,後來我經過介紹與余英時教授一起商訂了我的論文題目。爾後我的論文以一些到西洋留學的史家為研究對象,如胡適、羅家倫、傅斯年、姚從吾與何炳松等人,做了一些篩選後,博士論文題目訂為“ Chinese Historians and the West ”,後來又經過許多修改,就是剛出版的「 Inventing China ThroughHhistory 」。

    +

    1992 來我到羅文大學 (Rowan University) 教書,當時還有其他幾個學校也要我,但是這個學校距費城賓州大學近,離普林斯頓也近。從一九九二年開始到現在,教的課亞洲史、歐洲史都有。教史學方法時,我用的例子都是西方史家。由於我有西洋史的背景,我也教西洋文明史,直至九八年,我當了系主任,減了課,才專上亞洲史。但有時仍上史學方法。這大致上是我的學術歷程。

    +
    +
    +

    黃:但確是很清楚的脈絡。

    +
    +
    +

    蕭:我看過張戎的《鴻》,她也是文革後第一屆考上四川大學英文系,她提到當時不知有多少人想進大學,競爭非常激烈。

    +
    +
    +

    王:當時有人開玩笑說是積十年的精華,入學後感覺在同學身上學到很多,他們閱歷豐富,又很發奮,因很不容易才有機會上大學,所以當時我覺得壓力很大。我在文革當中長大,雖然那時功課還算不錯,很輕易對付,但是進了大學以後就感覺不同了。我在大學的第一次考試,讓我印象非常深刻。我花了很多時間準備,感覺是我這輩子最努力準備的考試,想不到得了個八十六分。當時覺得怎麼會只有八十六分,如照以前一定是全班最好的。後來看看別人是怎麼樣讀書、學習的,才自慚不如。我的同學讀書不知讀幾遍,且做筆記,鉅細無遺。那個時代整個來說學生都是很優秀的,成績無法拉開,老師非常痛苦;有一次考試,學生中有百分之三十拿到八十八、八十九分的,因為不能給太多九十以上的。我做歷史研究很注重偶然因素,因為我覺得人的偶然性非常大。在這些優秀的人才中,有些年紀大,到大三就要結婚了,因此為成家也就不考研究所了。而我年紀小,受學術環境影響,想繼續求學,不過若這些人考研究所,也許我未必考的上。儘管後來我的學習成績也不錯,但相對而言,他們可能更好。想想看,他們在下鄉時仍持續苦讀,十年的時間讀了多少書。我記得當時在歷史系上,有些人也懂其他外語的,他們空閒的時候就學外語。此外,每個人似乎都各有專長,有一主題作為個人專業研究領域,例如像佔領一塊有關明朝經濟方面的領域等,自己去看書。另外對學術訓練有幫助的是,當時課開得少,且文革後的教育,開課仍有些顧慮。所以當時是一比一點五,即聽課一小時,再花一個半小時時間自己學習,現在的學生可能會是跑去玩,但當時我們是很用功,天天都在看書,吃中飯等排隊時,手裡都拿著一小冊子在背外文單字。這是我第一次感到一個人的生命是不能浪費的,這確實是在讀大學時才開始的。

    +

    大陸有一很有名的西洋史專家,哈佛大學畢業,叫吳于廑。在哈佛大學時的名字為吳保安,你查楊聯陞的《胡適論學談詩三十年》就有談到他,非常優秀。他後來回大陸教書,是世界史的權威,也作過武漢大學的副校長。有次郭聖銘老師帶我與同學去開會,他也帶了幾個學生去開會,順便問到我們的背景,郭老師回答說是七七級的,吳于廑就說:是七七級就好,七七級就好,很有意思。我當時在文學院的那些朋友現都已是院長校長的。可以說當時是非常 exciting 、非常激動的,學習得也好。且當時我們的社會地位也高,大學生不得了,因此有種自豪感。

    +

    不過,回到你們的問題上,我覺得社會關懷的問題很重要。學西洋史的人,也不例外。從一比較新的觀念來看,不一定是要從後現代的觀點來著眼,都應考慮作者與讀者的關係;在現代社會中,我相信我們在寫作當中,你是寫給誰的,自然應關心,寫法也不一樣。後現代理論提出「作者已死」的說法,雖極端些,也是有道理的,過往史家寫歷史,所以總是想盡辦法要瞭解作者的意圖,但是,應該想到作者在寫作時有其關懷與其聽眾,這都是應考慮的。所以做西洋史研究的,要做得好,不是純粹跟著西洋史家來做,因為他們有他們的關懷,我們做西洋史的也有我們的關懷,所以有些人做中西、臺美關係的,我覺的這是不錯的,有可能對學術有貢獻。我這次講白壁德與陳寅恪,白壁德名氣滿響,陳寅恪也是。白壁德 (Irving Babbit) 在美國有很多人做研究,但研究中很少看到白壁德受到中國文化的影響這一面,或者語焉不詳。這是語言的限制,也是文化的限制。白壁德的東方語文很好,他把巴利文的經典翻譯成英文,他有此背景,但外國人研究是把他放在受美國教育影響下來看的。而中國人寫學衡派時就把他提一下,放在新文化背景下來談,也未能深入瞭解他本人。如果能兼通兩種文化背景,就可以做得深入一些。以前臺灣的留學生侯建,八0年代在美國紐約州立大學石溪分校英文系的博士論文曾做過白壁德,但寫作方式較傳統,未能詳細解釋白壁德的關懷所在,他為什麼會對東方文化有興趣。除此之外,以英文寫有關白壁德與中國或東方文化的關係,到現在為止只看過張星海的一篇文章,他是白壁德的學生,民國時期在上海光華大學做副校長。這一類研究是我們做西洋史的人可以做的,所以不一定要做純粹西洋史的課題。我並不認為我們在此做西洋史就一定困難,或回國後不做西洋史,就認為是退卻,我沒有此種感覺,這是社會關懷的不同所致。所以我寫文章,中英文一樣,都會考慮到讀者,因為社會功用的問題無法回避。

    +

    其次,講到史學專業化的問題,這與史學功用是相關的。蘭克學派有一個說法,認為以往的歷史家都是為道德訓化,而他本人則沒有這種想法的,他只是想如實呈現,所以別人就將他想得很高尚。我認為伊格斯的最大貢獻就是把蘭克史學的另外一面看了出來,蘭克史學思想中,仍認為歷史背後還是有一上帝之手,一般人難以理解歷史,但可注意其中的一點。蘭克注意的是 state ,他認為近代國家興起,是勾勒近代歷史發展的重要原因,所以他注意國家、就因為注意國家所以才注意檔案。因為他當時做的歷史,有兩邊限制,一方面他關切國家,認為國家是最重要的,所以外交、政治檔案就很重要,另方面又過份注重檔案,所以史學非常狹隘,永遠做政治、外交史。伊格斯點出蘭克史學的缺點,他講如實直書當然沒什麼不好,但是他把一般人社會生活史忽略了。後面的史學發展跟功用化很有關係,特別是德國社會科學史的興起,就是為反省德國為何會在兩次大戰中扮演挑起者的角色,在研究過程中,藉用社會科學方法研究德國社會的發展,以現代化的觀察角度,與英美比較,結果發現德國的現代化不夠徹底,走入歧路,由此歪路才導致軍國主義的抬頭,挑起兩次大戰,所以這一德國社會科學史學派的興起也表現了他們的社會關懷。伊格斯有句名言,後來我用來作《史學理論》八八年採訪他的文章的標題,即「歷史與歷史學是分不開的」。歷史學家的關懷是與歷史變化有關的。從史學發展中也可以看出此點。六0年代後發展出的史學,應聯係西方霸權、越戰等問題來看,一些學者看到西方社會的虛偽性,一方面講民主、平等,一方面又歧視、排斥一部分人。所以很多史學新潮都是社會關懷的反照,如此也漸漸突破蘭克史學的局限。

    +
    +
    +

    黃:老師剛才所談的包括了很多層面,涉及到傳授怎麼樣的歷史知識,歷史本身要包括人文關懷,變成一個載體。如果在實際教學方面涉及到層次的問題,傳授的東西愈是加了很多東西、道德關懷,愈可能遠離歷史事實,應該用什麼樣的方式把這種人文關懷發揚出去?其中又可能遇到怎麼樣的困難?

    +
    +
    +

    王:這個問題蠻複雜的,歷史學家一直處在一個兩難境地,一方面我門不能離開史料,但又像黑格爾所說的,我們不能拉著自己頭髮離開地球,我們的關懷還是在這兒。盡管這是一種兩難的狀況,我們還是盡量將之結合起來。例如是在選題的方面,社會關懷的問題就比較突出。如台灣學者對台灣平埔族的研究,就是一例。安德森 (Benedict Anderson) 的《想像的共同體》 (Imagined Communities) ,把民族建構當成是一個想像的結果。這是一種非常天才的觀察。霍布斯邦 (Eric Hobsbawm) 也有一個說法「傳統的創制」 (invention of tradition) ,就是說傳統是想像發明出來的,很有意思。台灣學者以前不太注意平埔族的研究,但是因為要重新認識台灣過去的時候就注意到了他者 (the other) 的存在。以前一直講移民社會的轉型,包括陳其南與李國祁,但平埔族這邊就沒看。像唐山公和唐山媽,這唐山媽在哪裡?這一疑問的提出,就是一種觀念的變化。為了尋找這「他者」,所以就有了平埔族的研究。所以我說這是想像的建構,體現了一種新的社會關懷。但這個研究是否能言之成理,還得要擺事實、講道理,不能為了實現你的理念而隨意歪曲歷史,否則效果則適得其反。因此我說歷史研究處於一種兩難處境,一方面史家無法沒有社會關懷,另一方面歷史研究又要尊重事實。

    +
    +
    +

    黃:可不可以用一句話來概括我先前的問題,人文關懷是讓歷史呈現許多面,而那些面在原來是沒有被發現的,而是符合多文化的或是去發現愈邊緣的東西。在政治上的話,就是那些政治上的弱勢,比較小的歷史把他彰顯出來。我把問題與我們刊物的發刊詞連接起來;一個事實的來源是史料,人文關懷要去發掘史料來建構這個關懷。歷史圖像跟史料通常會形成一個既密切又分離的東西。弱小族群的史料材料少,即使現在重視,材料還是很少,但是如何建構,用人文方法發現歷史圖像的時候,是需要一些理論基礎。歷史理論與所謂的史料的關係,難道理論不能優於先於史料,在台灣的研究環境中。

    +
    +
    +

    王:我同意你的觀點,我剛才在談蘭克史學的時候,其實也就在談這點。蘭克史學當然是史料學派鼻祖,史料是他特別重視的東西。伊格斯教授已經把這些揭開來了。蘭克有一個先行的觀念;我們先不談其宗教觀念,就政治而言,他把 state 看成是近代歷史發展的動力,這已經是他一個信仰了。所以比爾德會說歷史是一個信仰的行為,就是說信仰已經先有了。有這個信仰之後,他才去做這個事情,他才會強調檔案,因為檔案是政府的東西,你如果研究國家的話,當然用這個材料最好。我這裏不是說我們一定要觀念先行,而是說我們很難避免「不」觀念先行。我們無法避免理論觀念,包括史料學派。像傅孟真先生對史料的重視,杜正勝、王汎森先生做了很多研究的,他是在對顧頡剛古史辦運動做出一些回應性的動作。因為顧頡剛利用文獻來證明中國歷史儘有二千多年,沒有四、五千年。這等於是攔腰砍斷,周以前歷史就是不可信的。傅斯年則開啟了另一個觀察史料的角度。他知道從文字史料上已經很難駁倒顧的說法。他為什麼要駁倒顧頡剛,裏面原因很多,他們兩人個人之間有矛盾,就像我們暫且不談蘭克的宗教觀念,我們也暫時不談傅與顧的個人問題。總之我以為,傅有一個觀念,認為中國歷史可能不只於此,所以他從實物史料來做,考古發掘,做了這方面成功後,證明了史學就是史料學,史料的發現可以改變歷史的認識,你想想看,他有沒有觀念?我看他顯然有。傅一向是一個非常強烈的民族主義者,我相信他非常不滿意顧頡剛把中國歷史攔腰砍斷的作法。所以杜正勝說他從疑古到重建,想在科學的基礎上重建中國歷史與中國史料。

    +

    你剛才說有時候史料有限制,我認為不一定有限制,有時候觀念會帶動去發現一些新資料,從史學發展角度來看的話,這個現象很常見,因為史家有社會關懷。你想研究婦女的歷史,在一般史料上找不到,正史上只有少數特定的材料,若是想要做大眾的婦女史,你一定要想辦法去找新的材料;所以你去看筆記、小說從中爬梳出很多東西。在西方的話,原先是看檔案,後來就是看教會的記錄,研究婚姻、出生率等等,這種材料政府檔案不一定會有。所以社會史、文化史開闢了一塊史料的新天地,如同當年傅斯年開闢新天地是一樣的,他主張用考古材料對中國史學的影響巨大。因此中西史學的發展都依賴史料的開發,而史料的開發則與觀念的更新有關。

    +
    +
    +

    黃:就台灣的西洋史特性來講,按照歷史的研究程序來說,要有史料,然後才會有歷史出版物。史書的出現,在台灣研究西洋史的話,通常會有這樣的觀念,如果這是歷史既定的法則的話,在台灣研究西洋史,也是從史料開始。老師剛才所提的是不是指出了研究歷史理論的話,是不是多提供了很多人的生命關懷,多了很多思考,照老師的人文關懷來講,西洋史理論的話,就好像中國或東方的西化,其實都在走這條路,都在走所謂的隱性。隱性要全面性是不可能的,或是部份前題,不管是好是壞,既然是引用進來,都有它的用處,至少說引用者一定是有他的目的,在台灣研究西洋史理論的話,其實應該有它合理性的一面,不知道老師對這方面看法怎麼樣?

    +
    +
    +

    王:我不覺得要先有史料,才有歷史研究。這一觀點基於我的史學實踐。你想想看,你做一篇文章怎麼開始?如你想做 1960 年代美國婦女就業情況,你第一步是什麼?你去看史料嗎?你根本就不知這史料在那裏。你第一步是去圖書館查有沒有發表過這方面的東西,這是二手史料,你先大致看一遍以後,才知道這個課題可不可以做。如果某個題目很想做,但是一看,三本書已經出版了,你可能就沒有必要做,換一個題目。所以我說歷史研究不是由一手史料開始,而是由二手史料開始,例如,安克史密斯 (F. R. Ankersmit) 就注意到這個問題,他談到一個生產過剩 (overproduction) 的問題,他有一種歷史學家的憂慮,就是二手史料太多了,就是生產過剩。我想了解 1960 年代美國婦女就業情況,光是二手史料都看不完,更不用說還有一手材料,就是你要看完這些東西才有一個問題提出來,有一個 topic 才能去找史料。我們現在是一個訊息爆炸的時代,就是說整個過程已經變化了,不管是做台灣還是在做任何地方的研究,都是從二手史料開始,所以我不同意史學研究一定要由一手史料開始。

    +

    史學要建立在史料基礎上,這點我同意,但是要達到這一點不是從史料開始,因為你根本不知道史料在那裏,所以這個過程根本不一樣。所以史學觀念、史學理論這些東西很重要,它們幫助你發現問題。你在讀二手著作的時候,有時你會發現完全不同的觀點。同樣就剛才婦女就業的例子,可能從婦女史的觀點、可能從勞工史的觀點,甚至社會學家都可以對這個問題進行研究,人類學家、經濟學家也可能做這個研究,因此不但有分析,而且有來自不同領域的分析。所以可以說原來蘭克的那種作法完全都已經過時了,他當時的 seminar 是把一個史料放在桌上,讓大家一起去看。他那種史料是非常有限的材料,是一些檔案,看了以後再去找一個題目來做,現在美國大學的 seminar 只是讀二手材料而已,就是一種史學史的研究。如果上美國婦女史,絕對是找一些書來看,讓學生了解研究現狀,然後才能確定今後的作法。老師的作用是在這裏,他不可能給你一堆史料然後你就做研究。所以我認為在這方面,作西洋史,作台灣史,作中國史沒有很大的區別,都是先有問題意識你才能去做研究。單單整理史料,我想很多史家可能也不願意做,即使做了,也只是一個 assignment ,而寫論文是要去「論」的,對不對?

    +
    +
    +

    黃:老師的回答引起我兩個看法,一個是膚淺的問題,裏面又可以分為兩個層次,第一個層次是有些學者認為西洋史的研究要從史料方面著手,避免建立出來的東西空洞而沒有基礎。第二個膚淺與歷史理解與歷史教學比較有關,例如我發覺我的學弟妹,也就是這批 1970 年代以後的學生,他們有一個膚淺化的現象,當然這跟詹明信討論後現代文化現象一樣有深淺度的問題,詹明信談的是歷史理解的方式,我現在談的更實際,為什麼現代學生歷史理解比較膚淺化。第一個,他們不讀歷史原著了,縱使現代的研究是史學史研究,他不讀歷史原著,他直接看電腦中輸入的關鍵字,現在不是歷史解釋的問題了,他們所看到的是資訊,跟各行各業廣告媒體等所發出來的資訊是一樣的東西,他們所理解的,以致於他們所做的歷史報告充滿的都是這種資訊,所以說有膚淺化的危機。

    +
    +
    +

    王:我是這樣想,你說膚淺化,單單只是去看一些二手材料,用一些新名詞,可以稱做膚淺化。但你要看是那一種人,你是碩士研究生,研究生的話這樣是不行的,但大學生的話,他只是去了解一些東西,一個是研究能力的限制,一個是研究條件的限制,你很難叫他直接去看檔案。重點是讓他怎麼掌握一些本領,即萬一我要看檔案的話我能不能看。我想現在成名的歷史學家,他們在大學時代就能寫出水準很高論文的還是比較少,大家就是學一點本領而已。如果你有想法要做一點中外關係史的話,你就要學點外文什麼的,這個是比較基礎的;你要研究日本時代的台灣,你日文就一定要好。這個基礎是可能在大學時代奠立的。如果因為他們現在沒有機會看原始史料就說膚淺化,我認為也沒什麼道理。

    +
    +
    +

    黃:我因為辦刊物,覺得有一個有趣的現象,有一研究生投稿,談史學理論的文章,特別是偏向史學史,歷史發展過程的介紹,他涉入的角度是由海登‧懷特那邊談起,我發現他的內容與所用的著作有一個現象,像老師學習西洋歷史是由希羅多德 (Herodotus) 開始,到了我們的階段,是由蘭克開始讀起,像他們這個世代,大約從 60~70 年代海登‧懷特 (Hayden White) 開始讀起,再之前的可能根本就不看了。他直接從所謂二手詮釋做二手詮釋,從海登‧懷特詮釋史學史,現代人又看海登‧懷特的東西,又過度去理解,這樣變得也不說是好或壞,而有一種歷史的專業性逐漸消失的感覺。

    +
    +
    +

    王:我們的生命有限,所謂生也有涯,知也無涯,以有涯隨無涯,迨矣。史學史的研究當然也是這樣,如果要全看的話,那是很難的,只能厚今薄古。現在的文化變化很大,台灣史學界把後現代理論看得還更多一點,西方可能還沒看那麼多,他們可能還看現代的或前現代的東西,不過為了讓學生了解現在的發展狀況,你當然要讓他們知道希羅多得的情況,能夠看一點節選本,知道古代希臘史學的面貌。第二還有個問題是我剛才說我讀過不少西洋古典的史學名著,這也是在以後的階段,大學時候也是挑著一些看,我認為要考慮大學或研究所的區別,如果你是研究史學史,那麼你當然要讀經典,甚至像一些不太經典的東西你也要讀。就發展的趨勢而言,一定是後面的時代要多一點,這是因為要了解最當代的發展與變化。我認為這不是說現在的學生就不如以前,可能現在的學生在很多方面上還要比以前的學生好一點,不過做老師的話很喜歡說學生不好,這是一個通病。

    +
    +
    +

    黃:我再舉一個有關教學方面的問題。老師在美國教書,你認為有哪些方面,可以讓台灣借鏡的地方?

    +
    +
    +

    王:有一點比較可以注意的是,我們要讓學生自己來選擇題目,我發覺台灣學生甚至亞洲學生都有這樣的問題,習慣接受任務,這是從小到大作功課嘛!這並不是不好,但有一個問題就是習慣了,一定要聽別人說要做什麼才去做什麼。時間久了就會有一個厭倦心理,老接受別人的指令,前面幾年可能還可以接受,愈到後來,一聽到就覺得又要寫一個 paper ,不是你想要做。這是一個弔詭,因為長期以後你也不知道自己要做什麼,沒辦法為自己開拓一個研究領域。有的人到最後在寫博士論文的時候,選題非常非常因難,一下子給你自由,就不知道怎麼去用它,他們的基礎其實非常好的,但到了要去給他創新,要去自己選擇題目的時候,要麼就是非常鬆垮,就像覺得沒有家庭作業了,就在那裏煩惱,無從入手。美國的學生就是不一樣,很喜歡自由的參與,但我認為他們不好的地方就是有時候不紮實,很多數學非常差,因為學數學你就不得不接受老師的教導與作業,但他們在其他領域往往做得比較成功。他們有自由創見,主要是因為他們對所學的有興趣,想做這個研究。所以我說大陸的七七級這一代有一點做得比較好,因為他們比較自由,那時候課又少,他們是有選擇的想去多讀點書。如果教學上能夠讓學生有更多一點的自由,上課的時候自己選擇題目來做,這樣是比較理想的。還有就是老師,應該要可以容納不同意見。在美國大學裡,通常都可以讓學生以各種角度發言,但它的標準就是要言之成理。舉法國革命的例子來說,路易十六的昏庸可以是個原因,中產階級的要求也可以是一個原因。我覺得史學研究就是要提出各種各樣的理由來,而不是告訴你一個答案。你可以把各種因素綜合起來談,說國王昏庸、外患都可以,但你要證明。這種訓練方式我覺得是很有道理的。另一個就是要有批判精神,這一點與文化傳統有關。美國大學的整個研究制度,我認為就是培養批判精神而不輕易信任一個權威,這個在亞洲可能是比較難做到的。在教學方面也應該這樣,一個學生寫論文,老師能幫助你的主要在大綱、方向上,細節上他也幫不了你。這一點周樑楷教授談到伊格斯教授是研究德國史的,他轉而做英國史,可能也是受到美國大學風氣的影響。所以我認為美國大學裡的批判精神,也是可以借鏡的。

    +
    +
    +

    黃:今天非常感謝老師接受我們訪問,讓我們收穫良多,謝謝

    +
    + + + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/004/article04.html.html b/htdocs/htc/newsletters/004/article04.html.html new file mode 120000 index 0000000..ad4a043 --- /dev/null +++ b/htdocs/htc/newsletters/004/article04.html.html @@ -0,0 +1 @@ +article04.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/004/article04.html.xhtml b/htdocs/htc/newsletters/004/article04.html.xhtml new file mode 100644 index 0000000..edd022d --- /dev/null +++ b/htdocs/htc/newsletters/004/article04.html.xhtml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + +Review of That Noble Dream + + + + +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +

    Peter Novick, That Noble Dream: The “Objectivity Question” and the American Historical Profession. New York: Cambridge University Press, 1988, xii+648 pp.

    + +
    陳思仁
    + +

    本文所要介紹與評論的是納維克 (Peter Novick) 《高貴的夢想:「客觀性問題」及美國歷史專業》 (That Noble Dream: The “Objectivity Question” and the American Historical Profession ,以下簡稱《高貴的夢想》) 。首要說明,本文並未就《高貴的夢想》一書內容作詳細敘述,旨在於直接點明此一書的要旨,以便讀者往後自行閱讀時,不會僅就本書細節的探討而失去納維克著作本書的意旨。

    +

    本文寫作,共分四部份,每一部份自成一論述。第一部份,簡要說明《高貴的夢想》一書的寫作形式與意旨。第二部份,說明歷史知識論的建立,以及歷史專業社群的建制,是與「客觀性」 (Objectivity) 有複雜共生關係,間接說明本書內容,即圍繞於此而論述。第三部份,說明幾位史家在面對歷史知識「客觀性」的危機時,如何處理挽救這「客觀性」基石,本段落採取哈廉 (David Harlan) 的論述,1 以與納維克的處理方式做一對照。第四部份,說明史家對於歷史知識「客觀性」的堅持,部份基於「客觀性」作為對「價值」 (value) 的保証,然而,納維克在本書,顯然地是,不再堅持維護「客觀性」的存在必要,其意旨在於使歷史知識有更多可能性。白話地說,唯一真理的去除,多元真理的可能性乃能開展。

    + +

    + +

    作者以「客觀性」議題做為本書一指示 (instrument) ,而不是做為一種宣言 (confession) ,來重新編纂美國百年以來的史學發展,實際上也直指了歷史知識的本體論問題。因此,本書不僅是身為專業史家的納維克,敏銳的抓住十九世紀末以來,專業史學的立基點—客觀性—做為本書的主題,也是對於一九八0年代開始,後結構主義者 (post-structuralist) 對歷史「客觀性」的攻擊,所作的回應與反思。

    +

    本書除了導論之外,共分為四部份:〈立客觀性為王〉 (Objectivity enthroned) :探討客觀性能被建立的理由及其與美國史學專業化形成的關係;〈圍攻客觀性〉 (Objectivity besieged) :解釋二十世紀美國史學產生相對主義的文化、社會、政治背景,及諸多位史家捍衛歷史是客觀的各種說辭;〈重建客觀性〉 (Objectivity reconstructed) :重建一個較新且符合客觀性的綜合法;〈客觀性的危機〉 (Objectivity in crisis) :一九六0年之後,美國社會呈現出的困惑 (confusion) 、對立 (polarization) 、不確定 (uncertainty) 的情境,歷史客觀性顯得更令人質疑。縱觀本書,簡捷扼要的綱目,並以編年方式進行,如一次大戰前後、二次大戰前後、冷戰時期、越戰、一九六0年代及其之後,誠如海克斯特 (J. H. Hexter) 所言,在此一世界歷史的架構下,是一幅大寫歷史 ([H]istory) 。2 其次,本書幾乎囊括美國史學近百年來的專業史家(可謂是一本關於美國史家的百科全書),以及專業史家對於「客觀性」議題的意見 (opinions) ,顯現出納維克對於文獻史料掌握充份的能力。

    +

    讀者亦可自本書清楚辨識到,史家在不同時期基於各自政治、族群、地域或性別等立場而對歷史事件有不同解釋,因此,隨著時間的直線發展,總有同一歷史議題的詮釋被後來的史家予以修正,甚而推翻。讀者自可在本書中辨別與思考有關客觀性的問題,相對的,也不禁質疑著,歷史事實的客觀真理僅能在某一時期或某同一 (identity) 社群中獲得共識,逾過此某一時期或某同一社群,就有不同解釋。歷史事實的客觀真理不僅無法被永恆所定奪,相反的是,歷史事實的客觀真理僅存在於短暫與偶然。其次,本書是透過對於歷史議題的討論,以編排史家主體 (subject) 的認知行為與歷史思考。納維克試圖在書中編排史家對於「過去」歷史事件的解釋,因著不同時間的文化社會背景而呈現解釋的多樣化,以呈現歷史思考的多元,也藉之說明史家的思考方式總是深受歷史環境的影響。因此,本書易予讀者留下歷史相對主義的解讀,這部份可以解釋為是納維克作為一非客觀主義者 (a-objectivist) 而書寫出來的結果。

    +

    不過,在此書值得讀者深思的一點是,史家往往以為有「客觀性」基石的保障,而不認為自身的的政治社會立場會左右個人的意見,以至假「專業」、「客觀」之名強壓、排斥他人論點。例如本書在細說冷戰時代,一些史家因政治立場而受到不公平的待遇時,包括政治人員、學者以及學校行政人員都參與這場「壓迫」,造成學術界的極右傾向,可謂史學專業社群假「客觀」的科學之名,行使權力運作。此外,納維克於本書中描述史家,有因個人偏見而左右了他人學術發展,荷林葛 (David A. Hollinger) 戲稱此為八卦 (gossips) ,然不也點明了學術與政治,常在專業間同時相結合底被執行。

    +

    意圖於論述過程中保持中立 (neutrality) 態度的納維克,史家海克斯特認為納維克以「以色列國土上沒有國王」 (There was no king in Israel ,引自《舊約‧聖經士師記》) 作為本書末篇的章節名,是帶有悲觀的論調,然而此翻解讀不僅受到梅驥 (Allan Megill) 的譏刺,納維克本人也否定。此外,諾維克也反駁荷林葛所以為的,這句話是帶有天啟 (apocalyptic) 的。事實上,這句話影射當前史學解釋的片斷化 (fragmentation) ,及無法將歷史綜合 (synthesis) 為一「整體故事」 (full story) 的事實,也就是梅驥所言的,大敘述 (grand narrative) —不再能被敘述。《高貴的夢想》一書的第四篇共四章 ( 史家梅驥最為推薦的篇章 ) ,即是就當前史學界現象作一追溯,說明自冷戰、一九六0年代起,史學家的多元立場,是使歷史解釋多元化、無法綜合的起因,普世單一真理受到族群、性別、宗教、國家、區域與意識型態多元價值的挑戰,其次,後結構主義對於歷史能否有「客觀性」可能的攻擊,不僅使歷史這門知識的科學性受到動搖,也使依賴歷史專業社群所保證的一致性底歷史解釋,面臨瓦解。本書以回顧的 (retrospective) 方式,綜合百年來史家對各種歷史議題的討論,3 例如以南北戰爭歷史議題,就不同的歷史文本編排出一歷時的脈絡,使讀者可以比較各文本的觀點的差異,是一種文本互為參照的作法,可謂提供了一種史學史的寫作方式,因為文本的差異,說明歷史學的進展;但是,從另一方面而言,本書以「客觀性」為名,卻也反諷的証明「客觀性」的不可能。既然歷史「事件」本身因歷史的解釋而有了歷史性質,歷史知識的基石—「客觀性」—不再是穩固的,歷史知識走向相對。規訓的歷史思考與規訓的歷史寫作,也就不再能宣稱,其對過去提供實在的寫實揭露或呈現所具有的科學性質。本書可說是,納維克站在當下取向 (presentism) 來解讀、處理歷史知識。

    + +

    + +

    統治歷史學科這頂「客觀性」王冠,源於十九世紀科學知識的絕對勝利,促使各學科,包括歷史這門知識,也以建立科學的研究方法做為強調自身科學性的保障。其知識論是洛克先驗主義,強調主體與客體的相對關係。也就是說,對歷史家而言,「客觀性」意謂著相信有獨立於史家心智之外的一先驗過去實在 (a prior reality of past) ,也意謂著相信,歷史真實是作為符應 (correspond) 此一過去實在。而「客觀」也暗示著有相當些關於過去的「事實」 (facts) ,這些事實,獨立存在於史家心智之外,且能為史家捉住並無誤底被瞭解。一旦事實被瞭解,則無論史家是如何有其特殊視野或有任何詮釋傳統,事實都會為自己說話。4 然而,「客觀性」在八0年代後不僅成為受爭議的概念,且史家也瞭解到,史家並非是站在一固定不變的點上瞭解過去,而是身在時間的變遷中,亦即史家也是具有歷史性,所以史家的觀點必是會受到歷史環境影響。因此,歷史知識論上的主體與客體問題,是身為讀者在閱讀本書的認知起點。

    +

    本書名《高貴的夢想:「客觀性問題」及美國的歷史專業化》,即是要說明「客觀性」與美國史學專業化建立過程的脣齒關係。「客觀性」是史家做判斷以及史學專業評價的指導原理;以「客觀性」為中心,而使專業歷史能冒險前進 (venture) ,冒險前進基於「客觀性」這塊基石而得以建成,「客觀性」也是使得冒險前進得以持續存在的理由。不管是對於史家而言或在史家作品中,「客觀性」一直是專業中最受讚美與褒揚的品質 (quality) ,而當吾人界定歷史學術是否是進步的(也就是說,是否愈加靠近過去客觀真實),「客觀性」即是一個重要的術語 (key term) 。5 十九世紀末,美國的史學專業化建立過程,就是依存於此想法。

    +

    本書第一篇章就是在探討美國的史學專業化建立過程與「客觀性問題」逐漸糾纏為一複雜的共生關係。當在建立歷史專業化的歷史知識時,一有資格的社群 (communities of the competent) 及一標準化的技術 (standardized technique) 正是保障歷史知識是客觀性的基本。為避免所獲得的歷史知識是胡謅地、假冒地,一有資格的社群的共識是更能凌駕於個人權力、黨派,因此所探索到的知識,既是非個人性的,且是價值中立的。因此,吾人所探求的歷史事實是否是客觀真實的,則受過專業化社群的訓練,以及方法上是否符合標準,儼然成為判斷標準。方法上的共識雖先後受到科學相對論與社會科學方法的影響與挑戰,但歷史社群仍能維持對追求客觀真實的信心,直至八0年代後,後結構主義直指攻擊史學專業的核心—「客觀性」,加上受過專業訓練的學科人才,其多元性與量的增加,可說是挑戰百年前美國專業史學得以建立的根基。本書綜論美國史學百年發展,即是沿著此一脈絡敘述。

    +

    舉例言之,本書引文寫道:「……現存的專業化史學,有其行規上的特權、以及能使你獲得或失去人們信任的法則、和被崇拜的研究過程及論述的形式,對於這些事我都去做到以得到確信,並且避免做一些使我變得不可信及易受責難,及會使我感到困窘且不被人信任的事。」6 明顯的是,懂得如何使其書收獲得學術社群肯定的納維克,是深諳專業史學規範的操作。就此而言,本書第一篇第一章,是以蘭克 (Leopold von Ranke) 、培根 (Francis Bacon) 與福樓拜 (Gustave Flaubert) 代表史學、方法邏輯與藝術意圖成為一門科學的現象,因為近代自然科學的研究模式,確實是十九世紀任何知識學科意圖仿效的。也說明,專業史學行規,依賴方法學上地操作,是企圖以技術宰制知識的取得。實際上,後現代主義者對於科學採取批判與否定,即基於此。

    +

    至於,將「客觀性」意旨援引於史家主體,則超然 (detachment) 、冷靜 (dispassion) 、中立與誠實 (honesty) ,就成為史家寫作所必須具備的特質,這既有道德性 (morality) 又有本質 (essence) 。但這意涵終究受上述所提的,主體的多元性而不可能。

    + +

    + +

    後現代主義 (postmodernism) 如同二十世紀初相對主義 (relativism) 的懷疑論調,兩者同樣對「客觀性」提出質疑,差別在於前者是全盤否定歷史知識的客觀性本質。面臨後現代主義對歷史知識「客觀性」的挑戰,史家荷林葛 (David Hollinger) 、海斯凱 (David Haskell) 、克洛本柏 (James Kloppenberg) 、艾坡比 (Joyce Appleby) 及杭特 (Lynn Hunt) 和傑考 (Margaret Jacob) ,都意圖重新建構客觀性理論,然卻不成功。

    +

    荷林葛、海斯凱、克洛本柏,曾就三方面嘗試恢復客觀性概念。首先,將客觀性立基於專業的研究步驟中,主要是以孔恩 (Thomas Kuhn) 的《科學革命的結構》 (The Structure of Scientific Revolution) 一書為基礎,如荷林葛援引孔恩的「學科源型」 (disciplinary matrices) 和「學科共識」 (disciplinary consensus) 觀念來比擬歷史學專業。而海斯凱則擁抱孔恩對「客觀性」的定義,即由一特殊歷史的探究社群 (communities of inquiry) 建構、建立與證成一可視為正當的步驟。荷林葛與海斯凱都想要將歷史學專業視為一探究社群,透過社群所獲致的共識,以此挽救「客觀性」傳統概念。這方案基本上是承認,不同時期的社群所建立的共識是不同的,但共識的客觀性是基於社群所認同。顯然地,這項挽救方法仍因專業社群的社會多樣化,如黑人、女人、工人等主體位置 (subject position) 的不一,文化背景與視野也多元,終至無法形成一綜合的共識。關於這方面,納維克《高貴的夢》一書內文,也透露專業歷史學社群之無法建立方法上的共識,原因也是社會分化 (social diversification) 與文化片斷 (cultural fragmentation) 。

    +

    當上述挽救方法不成功時,另一方案則是基於歷史應作為一道德角色,乃試圖將客觀性比喻為與十八世紀啟蒙運動有關聯的傳統與慣例。這個方案認為,整個大社會中的美德與傳統,是我們歷史與文化所允許傳承下,史家主體特質就能深根於此歷史文化。但是十八世紀初的柏克 (Edmund Burke) 是承認傳統的歷史偶然性,但海斯凱卻認為,若傳統與慣例能夠持久幾世紀,就證明了傳統是根基於人的本性 (nature of human) 上。然而,既使是美國獨立革命時所宣稱的自然權利,經由二十世紀多元文化世界人民的詮釋,也有所轉變。傳統的持久性是經不起跨區域的文化差異。

    +

    一九九0年,海斯凱在「客觀不是中立」 (Objectivity Is Not Neutrality) 一文中,認為「客觀性」寧是「對自我克服、超然、誠實與坦白最小限度的尊敬,以使智識社群成為可能。」7 「客觀性」成為被期待而非被定義的術語。因此,嘗試將「客觀性」轉化為一般道德和美學上的義務,成為第三項方案。但即使如此,海斯凱仍想追求較完全底 (more complete) 、較優底 (superior) 陳述,說明了其內心對於沒有基礎 (foundation) 的懼怕。荷林葛、海斯凱、克洛本柏三人都是想為歷史知識保留一穩固基點。然而就如費雪 (Stanley Fish) 所言,「一旦開始了反形式主義的路,就沒有可停之處。」8 意思是,史家要不堅守固有陣地,不放棄對於「客觀性」作為歷史知識底基石的信心,一旦有所動搖,則仿若走上走下坡的滑道中,一路只能滑底了。

    +

    《歷史的真相》 (Telling the Truth about History) 三位史家作者艾坡比、亨特及傑考,則建議歷史寫作應如同團體活動,是共享事業的學術社群,也就是認為,歷史學社群不再是基於「客觀性」基石而組成一團體,未來學術社群是基於「共享事業」 (a shared enterprise) 的基礎上建立出共識。其次,她們仍冀望有一共同認定的集體歷史,並認定美國本身即是代表一些政治價值,如個人自由優先,而這具有的實用性,也可用來為歷史下定義。類似這種意圖挽救客觀性的方案,仍是反諷性質的。

    +

    美國哲學家羅逖 (Richard Rorty) 則建議史家可定期開會,如同在波斯市場議價一般,每年史家透過公開會議,基於可能是相似的信仰而與其它史家討論。不過,羅逖進一步的建議學者們,應以作為一個反諷的自由主義者 (ironic liberalist) 自居,也就是不認為有一絕對價值的存在,而每一次的「共識」的獲得,都是暫時的。羅逖的意見,可以說是完全地接受後現代對於一個穩固基礎的放棄,而這是海斯凱等人無法接受的途徑。

    +

    納維克想表達的是,史家思考過去歷史時應接受採取多元視野 (plurality perspective) 。9 當「客觀性」不再是史家追求的最高境界與唯一,而史家也能將視野轉到其它學科,透過與其它學科的對話,而瞭解學科之間的不同思考方式。此書目的,也並非想為客觀性下一明確的定義,關於「客觀性」,納維克在導論提及:「歷史客觀性並不是一個單一的觀念,而是一大堆零散的假設、態度、渴望及討厭的事物。哲學家蓋里 (W. B. Gallie) 說的最好,他稱客觀性「基本上仍是爭議的概念,就像『社會正義』或『引導至基督教生活』一樣,其真正的意義永遠都在被討論」。10 「我不認為歷史客觀性的觀念是真或假、對或錯:我發現它不只是值得爭議且令人困惑。……。似乎對我而言,說一個歷史作品是否客觀是件空泛 (empty) 的觀察」。11 納維克接受了後現代主義者對於「客觀性」的質疑,不再以追求「真實」作為歷史寫作的理想。《高貴的夢想》一書,透過敘述每一歷史時期的的史家們不間斷地為同一歷史議題,不斷辯證、不斷尋找新史料、新方法,以求更加接近「客觀性」理想,也導致不斷推翻 ( 或補充 ) 前期史家的歷史詮釋,而歷史知識不也就是因此而得以被建構嗎?同一歷史議題正是透過每一次不同的史家的歷史寫作,而得以再被敘述,以及得以再被建構一新的文本脈絡。納維克《高貴的夢想》一書,也正是實踐這一新的歷史寫作形式。納維克正是藉由「客觀性」主題,再度重新詮釋與整合過往史家的各種論點,同時也建構了一對於「客觀性」議題的當代詮釋。而或許可斷言,納維克的歷史主義取向,12 使納維克深刻地瞭解到史家的歷史性,以致他在《高貴的夢想》一書,採取的是一種回顧性的 (retrospective) 歷史寫作。

    + +

    + +

    《高貴的夢》一書出版後,史學界如海斯凱、恪米 (Kenneth Cmiel) 、克洛本柏三人,就分別撰文評論。13 此外,一九九0年十二月二十八日,美國歷史學會年會的一場由羅斯 (Dorothy Ross) 組成的一討論會,亦是針對納維克《高貴的夢》一書而舉辦的,這場會議的發表者,分別有海克斯特、高登 (Lindon Gordon) 、荷林葛、梅驥,納維克則就上述四位史家的提問作答辯,羅斯作總結。會中史家所發表的文章,刊於一九九一年六月第九十六卷的《美國歷史期刊》 (American Historical Review) 。14

    +

    本書是以歷史知識「客觀性」的失效和歷史學術社群的社會分化,說明後現代情境的歷史詮釋片斷化(多元化)。其意旨是就「以色列國土上沒有國王」的現象,使史家重新回顧歷史這門知識的發展,思考著追求「客觀性」的可能。曾經,「客觀性」是區別歷史真實與虛構 (fiction) 的差別、保證史家主體的中立、事實與價值的分別、以及一致地歷史解釋的基石,但在面臨「客觀性」的失效情況下,上述史家仍有想重塑「客觀性」,以期維護「客觀性」的原有功能,如高登、克洛本柏強調証據 (evidence) 以求分別歷史與虛構的差別,而海斯凱則與荷林葛強調史家主體的批判超然立場,或有的仍期望透過「客觀性」以保持歷史解釋的整體性以及事件因果性的可能。然而,納維克則放棄對於「客觀性」的堅持,以求獲得更多豐富的可能性。梅驥則與納維克站在同一陣線上。不過,納維克似乎與海克斯特一樣,不對「客觀性」作哲學性的批判,15 說明其無意再糾葛於「客觀性」的哲學思辯。

    +

    本書不僅敘述了「客觀性」是如何被組織、型式化以及如何被攻擊與捍衛,也敘述了「客觀性」是以何種方式助長歷史學專業的建立與發展。「客觀性」與歷史學專業化的共生關係,卻也因為「客觀性」的備受質疑,而產生互除的現象。因此,我們可以發現,史家要不棄「客觀性」而保護歷史學專業社群的存在,要不則試圖挽救、重建「客觀性」,就在這兩者間猶疑不定,終至不可定奪,也無能解決原有問題。納維克《高貴的夢》一書並不做此嘗試。納維克是否放棄歷史知識的「客觀性」本質,筆者以為,納維克於本書採取回顧式的敘述,已然說明,史家到此刻,該是重看過去,停止關於未來的建構,拒絕建立一「過去–現在–未來」的歷史知識。

    +

    放棄「客觀性」本質,則歷史知識究竟該成什麼,或許非能於本書中獲致滿意的答案,但本書在作為思考歷史知識的文本之一,仍提供了一當代的說法。

    + + + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + +
    + +
    +
      +
    1. 關於此方面的討論,筆者認同 David Harlan 的論點,故本文第三部份,有關於史家如何挽救「客觀性」,乃取自其書 “After Looking into the Abyss,” in The Degradation of American History (Chicago and London: The University of Chicago Press, 1997) 的論述。 (Back)
    2. +
    3. J. H. Hexter, “Carl Becker, Professor Novick, and Me; or, Cheer Up, Professor N. ! ,” American Historical Review 96 (June 1991): 676. (Back)
    4. +
    5. Allan Megill, “Fragmentation and the Future of Historiography,” American Historical Review 96 (June 1991): 698; 梅冀在此文中也有此說法。 (Back)
    6. +
    7. Harlan, The Degradation of American History, 76. (Back)
    8. +
    9. Peter Novick, That Noble Dream ; The “Objectivity Question” and the American Historical Profession (New York: Cambridge University Press, 1988), 1. (Back)
    10. +
    11. Ibid. (Back)
    12. +
    13. Thomas L. Haskell, “Objectivity is not Neutrality: Rhetoric VS. Practice in Peter Novick ’ s That Noble Dream,” History & Theory 29 (1990): 137. (Back)
    14. +
    15. 本句引自 David Harlan, “After Looking into the Abyss,”The Degradation of American History, 92. (Back)
    16. +
    17. Novick, “My Correct Views on Everything,” 702. (Back)
    18. +
    19. Novick, That Noble Dream, 1. (Back)
    20. +
    21. Novick, That Noble Dream, 6. (Back)
    22. +
    23. Novick, That Noble Dream, 7. 納維克於序文,自承「對於客觀性,為何我不能採取反對或贊成的理由,是因為我的歷史主義。」 (Back)
    24. +
    25. Kenneth Cmiel, “After Objectivity: What comes next in History?” American Literary History 2(1990):170-81. James T. Kloppenberg, “Objectivity and Historicism: A century of American Historical Writing,” American Historical Review 94 (October 1989): 1011-30. Thomas L. Haskell, “Objectivity is not Neutrality: Rhetoric VS. Practice in Peter Novick's That Noble Dream,” History & Theory 29 (1990): 129-57. (Back)
    26. +
    27. J. H. Hexter, “Carl Becker, Professor Novick, and Me; or, Cheer Up, Professor N. ! ,” American Historical Review 96 (June 1991): 675-82. Lindon Gordon, “Comments on That Noble Dream,” American Historical Review 96 (June 1991): 683-87. David A. Hollinger, “Postmodernist Theory and Wissenschaftliche Practice,” American Historical Review 96 (June 1991):688-92. Allan Megill, “Fragmentation and the Future of Historiography,” American Historical Review 96 (June 1991):693-98. Peter Novick, “My Correct Views on Everything,” American Historical Review 96 (June 1991): 699-703. Dorothy Ross, “Afterword,” American Historical Review 96 (June 1991): 704-08. (Back)
    28. +
    29. Dorothy Ross, “Afterword,” American Historical Review 96 (June 1991): 705-07. (Back)
    30. +
    +
    + +
    + 回目錄 | + 前一篇 | + 下一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/004/article05.html.html b/htdocs/htc/newsletters/004/article05.html.html new file mode 120000 index 0000000..fe3ea71 --- /dev/null +++ b/htdocs/htc/newsletters/004/article05.html.html @@ -0,0 +1 @@ +article05.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/004/article05.html.xhtml b/htdocs/htc/newsletters/004/article05.html.xhtml new file mode 100644 index 0000000..b3faca5 --- /dev/null +++ b/htdocs/htc/newsletters/004/article05.html.xhtml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + +編者言 + + + + +
    + +
    + 回目錄 | + 前一篇 +
    + +

    編者言

    + +

    2004 年夏,《歷史:理論與文化》第四期終於在歷經波折中付梓出版。

    +

    本期文章與訪談內容於 2002 年間收稿完成,高晨揚的〈特爾慈論基督教信仰之歷史性〉一文是其碩士論文—《特爾慈的現代意識與歷史思維—海德堡時期, 1894-1914 》中的一章;陳致宏〈論朵伊森作品《希臘化時代史》的神意史觀與神義論思想〉是其碩士論文—《德國史家朵伊森的歷史思想與現實意識》中的一章。兩篇專文可視為十九世紀以來德國史學界中對於歷史理論的討論,也是歷史主義的代表人物。

    +

    其次,延續刊物創刊時之規劃,每期專訪研治西洋史的學者,透過其經驗,使後學者有所借鏡。本期專訪西洋史學者王晴佳教授。王教授長久身處美國歷史學界,對於提供台灣學界有關近年西方史學的演變,多所貢獻。此次專訪提供了一位研究西洋史學學者的心路歷程,可作為刊物讀者對王教授的認識起點。

    +

    本期書評一篇,陳思仁以其個人對史學理論中客觀性議題討論的興趣,結合其研究領域—美國史,評介納維克 (Peter Novick) 《高貴的夢想:「客觀性問題」及美國歷史專業》 (That Noble Dream: The “Objectivity Question” and the American Historical Profession) 一書。

    +

    在此感謝提供文稿與訪談的學者,並對本刊物有所期待的學者與關心的前輩們由衷感。本於對西洋史研究的熱誠,下一期將以「意識型態」為專題,期盼學界對本刊物的持續支持。

    + +
    + 回目錄 | + 前一篇 +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/004/index.html.html b/htdocs/htc/newsletters/004/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/htc/newsletters/004/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/004/index.html.xhtml b/htdocs/htc/newsletters/004/index.html.xhtml new file mode 100644 index 0000000..6cf2f7d --- /dev/null +++ b/htdocs/htc/newsletters/004/index.html.xhtml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + +第四期 目錄 + + + + +
    + + +
    +

    歷史:

    +

    理論與文化

    +

    西洋史研究通訊

    +
    + +
    +出版者:
    +《歷史:理論與文化》編輯委員會
    +編輯委員:
    +吳燕秋、徐文路、陳思仁、盛少輝
    +黃明田、蕭道中、潘宗億
    +本期責任編輯:黃明田
    +本期執行編輯:陳思仁
    +二00四年七月一日出版
    +一九九八年七月一日創刊
    +
    + +
    +

    第四期 「歷史主義」專號
    +本期要目

    + + +
    + + +
    + + + + diff --git a/htdocs/htc/newsletters/index.html.html b/htdocs/htc/newsletters/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/htc/newsletters/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/newsletters/index.html.xhtml b/htdocs/htc/newsletters/index.html.xhtml new file mode 100644 index 0000000..7823fbd --- /dev/null +++ b/htdocs/htc/newsletters/index.html.xhtml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + +各期通訊 + + + + +
    + +

    各期通訊

    + + + +

    本刊為同仁刊物,不對外發行,各期通訊皆已全文上網,歡迎點選閱讀。

    + + +
    + + + + diff --git a/htdocs/htc/robots.txt b/htdocs/htc/robots.txt new file mode 100644 index 0000000..f6f8dd7 --- /dev/null +++ b/htdocs/htc/robots.txt @@ -0,0 +1,9 @@ +User-agent: * +Crawl-delay: 1 +Disallow: /magicat/ + +User-agent: chklinks +Disallow: + +User-agent: HTTrack +Disallow: / diff --git a/htdocs/htc/scripts/common.js b/htdocs/htc/scripts/common.js new file mode 100644 index 0000000..6982ab1 --- /dev/null +++ b/htdocs/htc/scripts/common.js @@ -0,0 +1,88 @@ +/* History: Theory and Culture + * common.js: The common JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-07-25 + */ + +// _: Gettext +function _(msg) { + var i; + for (i = 0; i < lc_messages.length; i++) { + if (lc_messages[i][0] == msg) { + return lc_messages[i][1]; + } + } + return msg; +} +// The messages +lc_messages = []; + +// isEmail: Check if an email address is legal +function isEmail(a) { + var i, c, re; + if (typeof(RegExp) == "undefined") return true; + re = new RegExp("^[\\w\\-]+(\\.[\\w\\-]+)*\\@([\\w\\-]+\\.)+[\\w\\-]+$"); + if (typeof(a) != "string") return false; + a = a.toLowerCase(); + if (re.exec(a) == null) return false; + return true; +} + +// trim: Trim the leading and tailing spaces +function trim(a) { + var pos, start, len, spaces; + start = 0; + len = a.length; + spaces = " \t\f\n\r"; + for (start = 0; start < a.length && spaces.indexOf(a.charAt(start)) >= 0; start++, len--); + for (pos = a.length - 1; pos >= 0 && spaces.indexOf(a.charAt(pos)) >= 0; pos--, len--); + return a.substr(start, len); +} +function trimText(a) { + var pos, start, len, spaces, newlines; + start = 0; + len = a.length; + spaces = " \t\f\n\r"; + newlines = "\n\r"; + for (start = 0; start < a.length && spaces.indexOf(a.charAt(start)) >= 0; start++, len--); + for ( ; start-1 >= 0 && newlines.indexOf(a.charAt(start-1)) < 0; start--, len++); + for (pos = a.length - 1; pos >= 0 && spaces.indexOf(a.charAt(pos)) >= 0; pos--, len--); + return a.substr(start, len); +} + +// replace: Replace one phace with another in a string +function replace(source, oldStr, newStr) { + var pos; + pos = 0; + while (true) { + pos = source.indexOf(oldStr, pos); + if (pos == -1) break; + source = source.substr(0, pos) + newStr + source.substr(pos + oldStr.length) + pos += newStr.length; + } + return source; +} + +// clearDefault: Clear the default value of a column +function clearDefault(col, deftext) { + if (col.value == deftext) { + col.value = ""; + } +} diff --git a/htdocs/htc/scripts/guestbook.js b/htdocs/htc/scripts/guestbook.js new file mode 100644 index 0000000..5b433b8 --- /dev/null +++ b/htdocs/htc/scripts/guestbook.js @@ -0,0 +1,55 @@ +/* History: Theory and Culture + * guestbook.js: The guestbook-related JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-07-25 + */ + +// isGuestbookOK: Check if the message is ready to be submitted +function isGuestbookOK(form) { + + // Regularize the fields + form.message.value = trimText(form.message.value); + form.name.value = trim(form.name.value); + form.identity.value = trim(form.identity.value); + form.location.value = trim(form.location.value); + form.email.value = trim(form.email.value); + form.url.value = trim(form.url.value); + + // Check the message + if (form.message.value == "" || form.message.value == _("Fill in your message here.")) { + alert(_("Please fill in your message.")); + form.message.focus(); + return false; + } + if (form.message.value.length > 10240) { + alert(_("Your message is too long. (Max. 10,240 letters)")); + form.message.focus(); + return false; + } + + // Check the signature + if (form.name.value == "") { + alert(_("Please fill in your signature.")); + form.name.focus(); + return false; + } + + return true; +} diff --git a/htdocs/htc/scripts/lang.zh-tw.js b/htdocs/htc/scripts/lang.zh-tw.js new file mode 100644 index 0000000..4baa340 --- /dev/null +++ b/htdocs/htc/scripts/lang.zh-tw.js @@ -0,0 +1,30 @@ +/* History: Theory and Culture + * lang.zh-tw.js: The Chinese (Taiwan) localized messages. + */ + +/* Copyright (c) 2004-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2004-11-06 + */ + +// The messages +lc_messages = [ +["Fill in your message here.", "請填上妳的留言。"], +["Please fill in your message.", "請填上妳的留言。"], +["Your message is too long. (Max. 10,240 letters)", "妳的留言太長了。(最長 10,240 個字)"], +["Please fill in your signature.", "請填上妳的簽名。"], +]; diff --git a/htdocs/htc/stylesheets/analog.css b/htdocs/htc/stylesheets/analog.css new file mode 100644 index 0000000..adb7398 --- /dev/null +++ b/htdocs/htc/stylesheets/analog.css @@ -0,0 +1,29 @@ +/* History: Theory and Culture + * analog.css: The style sheet for Analog analysis reports. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-11-11 + */ + +@import url("common.css"); + +p { + margin: 1em 0; + text-indent: 0; +} diff --git a/htdocs/htc/stylesheets/article.css b/htdocs/htc/stylesheets/article.css new file mode 100644 index 0000000..73348ae --- /dev/null +++ b/htdocs/htc/stylesheets/article.css @@ -0,0 +1,102 @@ +/* History: Theory and Culture + * article.css: The article style sheet. + */ + +/* Copyright (c) 2001-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2001-02-04 + */ + +/* 文章 */ +h1 { + margin: 0.5em 0 2em 0; + text-align: center; +} +#author { + font-family: "標楷體", DFKai-SB, cursive, serif; + font-size: 1.44em; + font-style: normal; + text-align: center; + margin: 2em 0; +} +h2 { + margin: 3em 0 1em 0; + text-align: center; +} +.newsletter001 { + text-align: left; +} +h3 { + margin: 1em 0; +} + +p { + margin: 0.5em 0; + text-indent: 2em; +} +.section { + margin: 1.5em 0; +} +.continued { + text-indent: 0; +} +blockquote { + font-family: "標楷體", DFKai-SB, cursive, serif; + margin: 0.5em 0 0.5em 3em; +} +blockquote p { + margin: 0.25em 0; + text-indent: 0; +} +address.footer { + font-family: "標楷體", DFKai-SB, cursive, serif; + font-style: normal; + font-size: 1em; + margin-bottom: 1em; + text-align: right; +} +#annotations { + font-family: "標楷體", DFKai-SB, cursive, serif; + margin: 1em 0; +} +#annotations address { + font-style: normal; + font-size: 1em; +} +.reviewtitle { + font-family: "Times New Roman", serif; + font-size: 1.2em; + font-weight: normal; + text-align: left; + text-indent: -2em; + margin: 0 0 2em 2em; +} +.image { + text-align: center; + margin: 0.5em 0; +} +#contributers { + margin-bottom: 1em; +} +#contributers h2 { + text-align: left; + margin: 0.5em 0; +} +#contributers table { + margin-left: 2em; + table-layout: fixed; +} diff --git a/htdocs/htc/stylesheets/common.css b/htdocs/htc/stylesheets/common.css new file mode 100644 index 0000000..413d151 --- /dev/null +++ b/htdocs/htc/stylesheets/common.css @@ -0,0 +1,372 @@ +/* History: Theory and Culture + * common.css: The common style sheet. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-07-23 + */ + +/* General settings */ +body { + background: white url("../images/backgrnd.gif") repeat-y scroll; + color: black; + margin: 0; + padding: 0.5em 100px; +} +a:link, a:visited, a:active { + background-color: transparent; + color: blue; + text-decoration: none; +} +a:hover { + background-color: yellow; + color: inherit; + text-decoration: underline; +} +p { + text-indent: 2em; +} +.en { + font-family: Arial, sans-serif; +} +p.en { + margin: 0 0 0.5em 0; +} +h1, h2, h3, h4, h5, h6 { + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-weight: normal; + margin: 0; + padding: 0; +} +address { + font-size: 0.833em; + display: block; +} +pre { + margin: 0; +} +dl { + margin: 1em 40px; +} +dl dt { + margin: 0 0 0.5em 0; + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.44em; +} +dl dd { + margin: 0.5em 0 0.5em 40px; +} +caption { + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.44em; +} +form { + margin: 0; +} +#contents { + margin: 1em 15%; +} +.note { + font-size: 0.833em; + font-style: italic; +} +q { + quotes: "「" "」" "『" "』"; +} +div.errmsg { + margin: 1em 0.5in; +} +/* The CAPTCHA */ +.trwebsite, .trlastname { + display: none; +} + +/* The navigation bar */ +.navibar, .pagebar, .langs { + text-align: center; + font-size: 0.833em; +} +.navibar .text { + width: 4em; +} +.nav hr { + margin: 0.1em 0; + padding: 0; + height: 0; +} + +/* The title */ +.title { + margin-left: 40px; +} +h1 .en { + font-family: "Times New Roman", "Times.New.Roman", times, serif; + font-style: italic; +} +.intro { + margin: 1em 80px; +} +#toc { + margin: 1em 40px; +} +#toc li { + margin: 1em 40px; +} + +/* The footer */ +.footer { + clear: both; + font-size: 0.833em; + text-align: center; +} +.footer p { + margin: 0; + text-indent: 0; +} +.footer img { + border-style: none; +} +.footer .modperl img { + height: 30px; + width: 110px; +} + +/* The default list */ +.deflist { + margin: 1em 3em; +} +.deflist th { + white-space: nowrap; +} +.deflist th, .deflist td { + padding: 0.2em 0.5em; + vertical-align: top; +} +.deflist thead { + background-color: silver; + color: black; +} +.deflist tbody th { + font-weight: normal; +} +.deflist .listno, .deflist .listdel { + text-align: center; +} +.deflist .oddrow { + background-color: #FFE0E0; + color: black; +} +.deflist .evenrow { + background-color: #E0E0FF; + color: black; +} + +/* The default form */ +.defform { + margin: 0; + width: 100%; +} +/* Refer to http://www.w3.org/Style/threepart-f.css */ +/* The child selectors are a hack to hide these rules from WinIE6 */ +body>form.defform { + width: auto; +} +.defform table { + margin: 0 auto; + width: 100%; +} +.defform th, .defform td { + text-align: left; + vertical-align: top; +} +.defform .thfile { + width: 9em; +} +.defform .th { + width: 8.5em; +} +.defform .oldnew { + width: 3.5em; +} +.defform td .text, .defform td textarea { + width: 100%; +} +.defform td .prompt { + font-style: italic; + margin: 0; +} +.defform td ol, .defform td li ul { + margin: 0 0 0 2em; + padding: 0; +} +.defform td ul, .defform td li { + margin: 0; + padding: 0; +} +.defform td ul li { + list-style: none; +} +.defform td .oneline li { + display: block; + float: left; + margin-right: 0.5em; +} +.defform td h4, .defform td .picinfo, .defform td .piccap { + margin: 0; + padding: 0; +} + +/* The home page */ +.covertoc h1, .covertoc h3 { + font-weight: bolder; +} +.covertoc ul li h2 { + font-size: 1.2em; +} + +/* The guestbook */ +.guestbook .defform { + margin: 1em 3em; + padding: 0 0; + width: 70%; +} +/* Refer to http://www.w3.org/Style/threepart-f.css */ +/* The child selectors are a hack to hide these rules from WinIE6 */ +.guestbook body>form.defform { + width: auto; +} +.guestbook .defform table { + margin: 0 auto; + width: 100%; +} +.guestbook .defform th { + text-align: left; + vertical-align: top; + width: 5.5em; +} +.guestbook .defform td { + vertical-align: top; +} +.guestbook .defform .text, .guestbook .defform textarea { + font-size: 1em; + width: 100%; +} +.guestbook entries { + margin: 0 2em; +} +.guestbook .entry { + margin: 1em 1em; +} +.guestbook .entry div { + margin: 1em 0; +} +.guestbook .entry address { + text-align: right; +} +.guestbook .entry address cite { + font-family: "標楷體", DFKai-SB, cursive, serif; + font-size: 1.44em; + font-style: normal; +} +.guestbook .entry address :lang(en) { + font-family: "Times New Roman", "Times.New.Roman", times, serif; +} +.guestbook .entry address samp { + font-style: normal; + vertical-align: text-bottom; +} + +/* The related links */ +.links .linkslist { + margin: 1em 80px; +} +.links .linkslist li { + margin: 1em 0; +} +.links .linkslist li img { + vertical-align: top; +} +.links .linkslist li cite { + font-family: "標楷體", DFKai-SB, cursive, serif; + font-size: 1.2em; + font-style: normal; +} + +/* The editor list */ +.editors li { + font-family: "標楷體", DFKai-SB, cursive, serif; + font-size: 1.44em; + margin-bottom: 0.3em; + margin-top: 1em +} + +/* The rules */ +.rules { + font-style: italic; + text-indent: 0; + margin: 0; +} + +/* The accessibility guides */ +.skiptobody { + position: absolute; + line-height: 0; + left: 0; + top: 0; + z-index: -9; +} +.accessguide { + float: left; + font-size: 0.5em; + color: #FFFFFF; +} + +/* The preview mark */ +.previewmark { + position: fixed; + top: 1em; + left: 1em; + border: thick solid red; + color: red; + background-color: transparent; + margin: 0; + padding: 0.5em; +} +.previewmark h2 { + text-transform: uppercase; + text-align: center; + margin: 0; + padding: 0; +} +.previewmark p { + margin: 0; + padding: 0; + text-indent: 0; +} +.previewmark a, .previewmark a:visited, .previewmark a:hover { + color: red; + background-color: transparent; +} + +/* The breadcrumb trail */ +.breadcrumb { + clear: both; + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.44em; + margin: 0.5em 0 1em 40px; +} diff --git a/htdocs/htc/stylesheets/index.css b/htdocs/htc/stylesheets/index.css new file mode 100644 index 0000000..ae63a17 --- /dev/null +++ b/htdocs/htc/stylesheets/index.css @@ -0,0 +1,67 @@ +/* History: Theory and Culture + * index.css: The style sheet for the table of contents of the newsletters. + */ + +/* Copyright (c) 2001-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2001-02-04 + */ + +/* 各期通訊 */ +.date { + font-family: Arial, sans-serif; + font-size: 0.579em; + font-style: italic; +} + +/* 本期要目 */ +address { + text-align: right; + font-size: 1em; +} +.title { + float: left; + margin: 1em 1em 1em 0; +} +.title h2 { + margin-left: 2em; +} +.title h3 { + margin-left: 6em; +} +#credits { + background-color: white; + border: medium double black; + float: right; + font-family: "標楷體", DFKai-SB, cursive, serif; + font-size: 0.833em; + font-style: normal; + padding: 1em 0.5em; + margin: 1em 0 1em 1em; + text-align: left; + width: 18em; +} +#index { + margin: 1em 0; + clear: both; +} +#index h1 { + text-align: center; +} +#index .en { + font-family: "Times New Roman", serif; +} diff --git a/htdocs/htc/stylesheets/interview.css b/htdocs/htc/stylesheets/interview.css new file mode 100644 index 0000000..2cbf42c --- /dev/null +++ b/htdocs/htc/stylesheets/interview.css @@ -0,0 +1,53 @@ +/* History: Theory and Culture + * interview.css: The style sheet for the interviews. + */ + +/* Copyright (c) 2001-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2001-02-04 + */ + +/* 訪談 */ +h1 { + margin: 0.5em 0 2em 0; + text-align: center; +} +#author { + font-family: "標楷體", DFKai-SB, cursive, serif; + font-size: 1.44em; + font-style: normal; + text-align: center; + margin: 2em 0; +} +blockquote { + font-family: "標楷體", DFKai-SB, cursive, serif; + margin: 0.5em 0 0.5em 3em; +} +blockquote p { + margin: 0.25em 0; + text-indent: 0; +} +.dialog { + margin: 1em 0 1em 2em; +} +p { + margin: 0.5em 0; + text-indent: 0; +} +.first { + text-indent: -2em; +} diff --git a/htdocs/htc/wanted.html.html b/htdocs/htc/wanted.html.html new file mode 120000 index 0000000..74fc9ec --- /dev/null +++ b/htdocs/htc/wanted.html.html @@ -0,0 +1 @@ +wanted.html.xhtml \ No newline at end of file diff --git a/htdocs/htc/wanted.html.xhtml b/htdocs/htc/wanted.html.xhtml new file mode 100644 index 0000000..7e9b63e --- /dev/null +++ b/htdocs/htc/wanted.html.xhtml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + +稿約 + + + + + + + +
    + +
    + + +

    稿約

    + +

    〈歷史:理論與文化〉第四期:歷史理論專題

    + +

    當代歷史理論的發展,自六0、七0年代起,其中有一派接受後結構主義 (post-structuralism) 的思路引導,挑戰傳統實證史學的權威,激發史學研究社群內部的反省,並以不同的途徑建構史學中敘述與修辭的性質,從而豐富史學理論的創新。因此,在第四期的《歷史:理論與文化》中,本刊將擬定出版歷史理論專號,以當代史學史、史學理論為主要研究取向。最後,本刊誠摯地期待學有專精之各方人士踴躍投稿,截稿日期為民國九十年五月三十日。

    + +

    本通訊乃一向各界開放的公開討論園地,本編輯委員會誠摯地歡迎有志者共同參與,期待學有專精之各方人士投稿。若與本通訊之創刊宗旨有所切近者,歡迎踴躍投稿。本通訊之宗旨在於從事有關西洋歷史理論、史學史、文化史等各方面領域之研討。

    + +
      +
    1. 論文字數請在三萬字以內,書評在一萬兩千字以內。
    2. + +
    3. 論文格式:一律採橫式寫作,中文請用新式標點符號;格式請按 Kate L. Turabian, A Manual for Writers of Term Papers, Theses, and Dissertations (Chicago) 之格式。
    4. + +
    5. 來稿請附上磁片與列印稿,並請用 MS-Word 之中文排版軟體,或其他純文字檔。
    6. + +
    7. 來稿請附上作者之中文或英文真實姓名、服務單位、通訊地址、電話或 E-mail 等。來稿請寄下列地址: + +
      +臺北縣中和市中正路 763 號 3 樓
      +《歷史:理論與文化》編輯委員會收 +
      +
    8. + +
    9. 若有任何問題與指教,亦可以電子郵件與本刊編輯委員會連絡。
    10. + +
    11. 來稿本刊保留採用與否之權利,概不退稿,請自留底稿;本刊一律不支稿酬,一經採用,致贈當期通訊三份。
    12. +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/accsblty.html.en.html b/htdocs/imacat/accsblty.html.en.html new file mode 120000 index 0000000..7ba9167 --- /dev/null +++ b/htdocs/imacat/accsblty.html.en.html @@ -0,0 +1 @@ +accsblty.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/accsblty.html.en.xhtml b/htdocs/imacat/accsblty.html.en.xhtml new file mode 100644 index 0000000..269801f --- /dev/null +++ b/htdocs/imacat/accsblty.html.en.xhtml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + +Accessibility Statement + + + + + + + +
    + +
    + + +

    Accessibility Statement

    + +

    Access Keys

    + +

    Certain keyboard shorcuts are available for the navigation on this website:

    + +
      +
    1. C: The page content area.
    2. +
    3. L: The navigation links area.
    4. +
    5. R: The auxiliary links area.
    6. +
    7. 1: The home page.
    8. +
    9. 2: Skip to the page content area.
    10. +
    11. 0: Accessibility details.
    12. +
    + +

    How to use the shortcut key navigation depends on your browser and operating system. Mostly it would be Alt+key or Ctrl+key. Please refer to the help document of your browser on accesskey.

    + + +

    Standards Compliance

    + +

    All pages comply with priority 1, 2 and 3 guidelines of the W3C-WAI Web Content Accessibility Guidelines 1.1 and priority level 3 of the R.O.C. Executive Yuan Web Content Accessibility Development Guidelines.

    + +

    All pages validate as W3C XHTML 1.1.

    + + +

    Navigation Aids

    + +

    All pages have rel=previous, next, up, and home links to aid navigation in text-only browsers and screen readers. Mozilla users can also take advantage of this feature by selecting the View menu, Show/Hide, Site Navigation Bar, Show Only As Needed (or Show Always). Firefox users can install Link Toolbar extension to make use of it. Opera 7 or above has similar functionality, too.

    + + +

    Links

    + +

    Many links have title attributes which describe the link in greater detail, unless the text of the link already fully describes the target (such as the headline of an article).

    + +

    Whenever possible, links are written to make sense out of context. Many browsers (such as JAWS, Home Page Reader, Lynx, and Opera) can extract the list of links on a page and allow the user to browse the list, separately from the page.

    + +

    Two links with the same link text always point to the same address.

    + +

    There are no javascript: pseudo-links. All links can be followed in any browser, even if scripting is turned off.

    + +

    There are no links that open new windows without warning.

    + + +

    Visual Design

    + +

    This site use cascading style sheets for visual layout. If your browser or browsing device does not support stylesheets at all, the content of each page is still readable.

    + +

    The layout is completely liquid, simply filling its viewport (window). It happily accommodates resizing text and, as relative units have been used. You may freely enlarge or reduce the font whenever it is too small or too large for you to read, without messing up the page design.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/accsblty.html.zh-cn.html b/htdocs/imacat/accsblty.html.zh-cn.html new file mode 120000 index 0000000..bc533c8 --- /dev/null +++ b/htdocs/imacat/accsblty.html.zh-cn.html @@ -0,0 +1 @@ +accsblty.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/accsblty.html.zh-cn.xhtml b/htdocs/imacat/accsblty.html.zh-cn.xhtml new file mode 100644 index 0000000..5e666eb --- /dev/null +++ b/htdocs/imacat/accsblty.html.zh-cn.xhtml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + +无障碍网页设计说明 + + + + + + + +
    + +
    + + +

    无障碍网页设计说明

    + +

    键盘导览

    + +

    本站可使用下列键盘快速键浏览:

    + +
      +
    1. C :网页内文区。
    2. +
    3. L :导览连结区。
    4. +
    5. R :辅助连结区。
    6. +
    7. 1 :回首页。
    8. +
    9. 2 :跳到网页内文区。
    10. +
    11. 0 :无障碍网页设计说明。
    12. +
    + +

    快速键使用方式依浏览器或作业系统有所不同,大概是 Alt+Ctrl+ 。请参阅你的浏览器关於 accesskey 的说明。

    + + +

    符合规范

    + +

    本站所有网页,符合 W3C 无障碍网页规范 1.0 第一、二、三优先等级标准规范,及行政院研考会无障碍网页开发规范第三优先等级。

    + +

    本站所有网页,符合 W3C XHTML 1.1 标准。

    + + +

    辅助导览

    + +

    所有网页,均加入 rel=previousnextuphome 等连结,以辅助纯文字浏览器及萤幕阅读机导览。若你使用 Mozilla ,可由工具列选择检视(V)显示/隐藏(W)网站导览列(A)需要时才显示(O)(或一直显示(A)),以利用辅助导览功能。若你使用 Firefox ,可安装导览工具列扩充套件,以使用导览功能。 Opera 7 及以上的版本亦支援此功能。

    + + +

    网页连结

    + +

    本站网页上的连结,除连结文字本身自明者外,均加上标题说明。

    + +

    本站连结所用的文字尽可能自明,尽可能与上下文无关,以便浏览器(如 JAWS 、 Home Page Reader 、 Lynx 、 Opera 等)能直接列出网页上的连结清单,供使用者浏览。

    + +

    本站网页连结文字相同者,其连结网址亦同。

    + +

    本站无 javascript: 虚拟连结,所有连结均可用所有浏览器浏览,不需要 JavaScript 支援。

    + +

    本站连结进入时,不会自动开新视窗。

    + + +

    视觉设计

    + +

    本站使用阶层式样式表 CSS 做视觉设计。即使浏览器不支援样式表,亦可正常显示网页内容。

    + +

    本站网页采非固定式设计,文字在视窗上依序排列。字型大小采用相对单位,可自由在浏览器上放大缩小。若你觉得字型太小或太大,不易阅读,可自行放大缩小阅读,不会影响版面设计。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/accsblty.html.zh-tw.html b/htdocs/imacat/accsblty.html.zh-tw.html new file mode 120000 index 0000000..0af1d9d --- /dev/null +++ b/htdocs/imacat/accsblty.html.zh-tw.html @@ -0,0 +1 @@ +accsblty.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/accsblty.html.zh-tw.xhtml b/htdocs/imacat/accsblty.html.zh-tw.xhtml new file mode 100644 index 0000000..8ee2a58 --- /dev/null +++ b/htdocs/imacat/accsblty.html.zh-tw.xhtml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + +無障礙網頁設計說明 + + + + + + + +
    + +
    + + +

    無障礙網頁設計說明

    + +

    鍵盤導覽

    + +

    本站可使用下列鍵盤快速鍵瀏覽:

    + +
      +
    1. C :網頁內文區。
    2. +
    3. L :導覽連結區。
    4. +
    5. R :輔助連結區。
    6. +
    7. 1 :回首頁。
    8. +
    9. 2 :跳到網頁內文區。
    10. +
    11. 0 :無障礙網頁設計說明。
    12. +
    + +

    快速鍵使用方式依瀏覽器或作業系統有所不同,大概是 Alt+Ctrl+ 。請參閱妳的瀏覽器關於 accesskey 的說明。

    + + +

    符合規範

    + +

    本站所有網頁,符合 W3C 無障礙網頁規範 1.0 第一、二、三優先等級標準規範,及行政院研考會無障礙網頁開發規範第三優先等級。

    + +

    本站所有網頁,符合 W3C XHTML 1.1 標準。

    + + +

    輔助導覽

    + +

    所有網頁,均加入 rel=previousnextuphome 等連結,以輔助純文字瀏覽器及螢幕閱讀機導覽。若你使用 Mozilla ,可由工具列選擇檢視(V)顯示/隱藏(W)網站導覽列(A)需要時才顯示(O)(或一直顯示(A)),以利用輔助導覽功能。若你使用 Firefox ,可安裝導覽工具列擴充套件,以使用導覽功能。 Opera 7 及以上的版本亦支援此功能。

    + + +

    網頁連結

    + +

    本站網頁上的連結,除連結文字本身自明者外,均加上標題說明。

    + +

    本站連結所用的文字儘可能自明,儘可能與上下文無關,以便瀏覽器(如 JAWS 、 Home Page Reader 、 Lynx 、 Opera 等)能直接列出網頁上的連結清單,供使用者瀏覽。

    + +

    本站網頁連結文字相同者,其連結網址亦同。

    + +

    本站無 javascript: 虛擬連結,所有連結均可用所有瀏覽器瀏覽,不需要 JavaScript 支援。

    + +

    本站連結進入時,不會自動開新視窗。

    + + +

    視覺設計

    + +

    本站使用階層式樣式表 CSS 做視覺設計。即使瀏覽器不支援樣式表,亦可正常顯示網頁內容。

    + +

    本站網頁採非固定式設計,文字在視窗上依序排列。字型大小採用相對單位,可自由在瀏覽器上放大縮小。若你覺得字型太小或太大,不易閱讀,可自行放大縮小閱讀,不會影響版面設計。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/bizcard.html.en.html b/htdocs/imacat/bizcard.html.en.html new file mode 120000 index 0000000..24b82ee --- /dev/null +++ b/htdocs/imacat/bizcard.html.en.html @@ -0,0 +1 @@ +bizcard.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/bizcard.html.en.xhtml b/htdocs/imacat/bizcard.html.en.xhtml new file mode 100644 index 0000000..53dd1e3 --- /dev/null +++ b/htdocs/imacat/bizcard.html.en.xhtml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + +imacat + + + + + + + +
    + +
    + + +

    imacat

    + +

    Student of Graduate Institute of Information and Computer Education, NTNU, Free Software Developer

    + + + +

    Titles / Specialities

    + + + +
    + +
    + + + + diff --git a/htdocs/imacat/bizcard.html.zh-cn.html b/htdocs/imacat/bizcard.html.zh-cn.html new file mode 120000 index 0000000..e3858d6 --- /dev/null +++ b/htdocs/imacat/bizcard.html.zh-cn.html @@ -0,0 +1 @@ +bizcard.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/bizcard.html.zh-cn.xhtml b/htdocs/imacat/bizcard.html.zh-cn.xhtml new file mode 100644 index 0000000..403c25b --- /dev/null +++ b/htdocs/imacat/bizcard.html.zh-cn.xhtml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + +依玛猫 + + + + + + + +
    + +
    + + +

    依玛猫

    + +

    师大资讯教育研究所电脑科学教育实验室硕士班研究生,自由软体软体工程师。

    + + + +

    职衔/专长

    + + + +
    + +
    + + + + diff --git a/htdocs/imacat/bizcard.html.zh-tw.html b/htdocs/imacat/bizcard.html.zh-tw.html new file mode 120000 index 0000000..79ac11e --- /dev/null +++ b/htdocs/imacat/bizcard.html.zh-tw.html @@ -0,0 +1 @@ +bizcard.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/bizcard.html.zh-tw.xhtml b/htdocs/imacat/bizcard.html.zh-tw.xhtml new file mode 100644 index 0000000..6952686 --- /dev/null +++ b/htdocs/imacat/bizcard.html.zh-tw.xhtml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + +依瑪貓 + + + + + + + +
    + +
    + + +

    依瑪貓

    + +

    師大資訊教育研究所電腦科學教育實驗室碩士班研究生,自由軟體軟體工程師。

    + + + +

    職銜/專長

    + + + +
    + +
    + + + + diff --git a/htdocs/imacat/cgi-bin/counter.cgi b/htdocs/imacat/cgi-bin/counter.cgi new file mode 100755 index 0000000..e346801 --- /dev/null +++ b/htdocs/imacat/cgi-bin/counter.cgi @@ -0,0 +1,219 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# counter.cgi: The visitor counter. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-07 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub dont_update(); +sub read_counter(); +sub update_counter(); +sub log_visitor($); +sub counter_cookie(); +sub html_image($); + +use Fcntl qw(:seek); +use Date::Format qw(time2str); +use GD; +use IO::NestedCapture qw(CAPTURE_STDOUT); +use Net::CIDR::Lite qw(); + +use constant DATA_FILE => $ENV{"DOCUMENT_ROOT"} . "/magicat/data/counter.dat"; +use constant LOG_FILE => "/var/log/apache2/imacat/counter.log"; +use vars qw($OUR_NETWORKS @FGCOLOR @BGCOLOR $FONT); +# People in our networks will not be counted +$OUR_NETWORKS = Net::CIDR::Lite->new( + qw(127.0.0.1/8 10.0.0.0/8 211.20.30.96/29)); +@FGCOLOR = (255, 255, 128); # #FFFF80 Yellow +@BGCOLOR = (0, 0, 0); # #000000 Black +$FONT = gdLargeFont; +use constant TRANSPARENT => 0; +use constant COOKIE_NAME => "counter"; +use constant COUNT_ARG => "countme"; +use constant IGNORE_ARG => "ignoreme"; +initenv( -allowed => [qw(GET HEAD)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0, + -multilang => 0); + +main; +exit 0; + +sub main() { + local ($_, %_); + + # If we should not update the counter + if (dont_update) { + # Check last-modified here + my (@tables, @files); + @tables = qw(); + @files = (DATA_FILE); + http_304 if not_modified @tables, @files; + html_image read_counter; + + # Update the counter + } else { + $_ = html_image update_counter; + # Log the visitor + log_visitor $_; + } + + # Set the counter cookie + $NEWCOOKIES{COOKIE_NAME()} = $_ if defined ($_ = counter_cookie); + + return; +} + +# dont_update: If we should not update the counter +sub dont_update() { + local ($_, %_); + # Find any reason that we should not update the counter + # If this visitor came from our own network + return 1 if $OUR_NETWORKS->find($ENV{"REMOTE_ADDR"}); + # If this visitor had been counted + return 1 if exists $COOKIES{COOKIE_NAME()}; + # If we are not told to count this visitor + return 1 if !defined $GET->param(COUNT_ARG); + # Well, update it + return 0; +} + +# read_counter: Read the counter +sub read_counter() { + return -s DATA_FILE? xfread DATA_FILE: 0; +} + +# update_counter: Update the counter +sub update_counter() { + local ($_, %_); + # File exists + if (-s DATA_FILE) { + my $FH; + open $FH, "+<", DATA_FILE or http_500 DATA_FILE . ": $!"; + flock $FH, LOCK_EX or http_500 DATA_FILE . ": $!"; + $_ = <$FH>; + $_++; + seek $FH, 0, SEEK_SET or http_500 DATA_FILE . ": $!"; + truncate $FH, 0 or http_500 DATA_FILE . ": $!"; + print $FH $_ or http_500 DATA_FILE . ": $!"; + flock $FH, LOCK_UN or http_500 DATA_FILE . ": $!"; + close $FH or http_500 DATA_FILE . ": $!"; + + # Not exists or zero sized -- create a new one + } else { + xfwrite DATA_FILE, ($_ = 1); + } + return $_; +} + +# log_visitor: Log the visitor +sub log_visitor($) { + local ($_, %_); + my ($host, $user, $date, $uri, $size, $referer, $ua, $langs, $FD); + $size = $_[0]; + + # Gather the infomation to log + $host = (defined remote_host)? remote_host: $ENV{"REMOTE_ADDR"}; + $user = (exists $ENV{"REMOTE_USER"} && $ENV{"REMOTE_USER"} ne "")? + $ENV{"REMOTE_USER"}: "-"; + $date = time2str("%d/%b/%Y:%T %z", time); + $uri = $REQUEST_URI; + $referer = (exists $ENV{"HTTP_REFERER"} && $ENV{"HTTP_REFERER"} ne "")? + $ENV{"HTTP_REFERER"}: "-"; + $ua = (exists $ENV{"HTTP_USER_AGENT"} && $ENV{"HTTP_USER_AGENT"} ne "")? + $ENV{"HTTP_USER_AGENT"}: "="; + $langs = (exists $ENV{"HTTP_ACCEPT_LANGUAGE"} && $ENV{"HTTP_ACCEPT_LANGUAGE"} ne "")? + $ENV{"HTTP_ACCEPT_LANGUAGE"}: "-"; + + # Compose the log record 組合紀錄行 + $_ = sprintf "%s - %s [%s] \"%s %s %s\" 200 %s \"%s\" \"%s\" \"%s\" %s %s\n", + $host, $user, $date, $ENV{"REQUEST_METHOD"}, $uri, + $ENV{"SERVER_PROTOCOL"}, $size, $referer, $ua, $langs, + $ENV{"REMOTE_ADDR"}, country_lookup($ENV{"REMOTE_ADDR"}); + + # Save the log record 儲存記錄 + xfappend LOG_FILE, $_; + + return; +} + +# counter_cookie: Set the counter cookie +sub counter_cookie() { + local ($_, %_); + # Leave our network alone + return if $OUR_NETWORKS->find($ENV{"REMOTE_ADDR"}); + # Already set + return if exists $COOKIES{COOKIE_NAME()}; + # Count me + return new CGI::Cookie( -name=>COOKIE_NAME, + -value=>"counted", + -path=>$REQUEST_PATH) + if defined $GET->param(COUNT_ARG); + # Ignore me + return new CGI::Cookie( -name=>COOKIE_NAME, + -value=>"ignored", + -path=>$REQUEST_PATH) + if defined $GET->param(IGNORE_ARG); + # Leave it alone + return; +} + +# html_image: Make the image from the counter value +sub html_image($) { + local $_; + my ($counter, $image, $width, $height, $fgcolor, $bgcolor); + $counter = $_[0]; + + # Group the counter with commas at thousand digits. + $counter = fmtno($counter); + + # Initialize the image object + # Get the width and height + $width = $FONT->width * (length $counter); + $height = $FONT->height; + # Create an image object + $image = GD::Image->new($width, $height); + # Create the forground/background color objects + $fgcolor = $image->colorAllocate(@FGCOLOR); + $bgcolor = $image->colorAllocate(@BGCOLOR); + + # Draw the image + # Set the transparent background + $image->transparent($bgcolor) if TRANSPARENT; + # Paint the background + $image->filledRectangle(0, 0, $width, $height, $bgcolor); + # Write the text + $image->string($FONT, 0, 0, $counter, $fgcolor); + + # Output + $CONTENT_TYPE = "image/png"; + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":raw"; + $_ = $image->png; + print $_; + + return length $_; +} diff --git a/htdocs/imacat/cgi-bin/garbage.cgi b/htdocs/imacat/cgi-bin/garbage.cgi new file mode 100755 index 0000000..9896850 --- /dev/null +++ b/htdocs/imacat/cgi-bin/garbage.cgi @@ -0,0 +1,141 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# garbage.cgi: The Soundless Backalley. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-06 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub html_foreword(); + +initenv(-session => 0, + -this_table => "garbage", + -dbi_lock => {"garbage" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("garbage, daub, poetry, message, essay"), + "class" => "garbage", + "javascripts" => [qw(/scripts/garbage.js)], + "no_auto_title" => 1}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::Garbage::Public($POST); + $processor->process; + http_303 $REQUEST_FILE; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + # Old styled page number + http_301 $REQUEST_FILE if defined $GET->param("no"); + # List handler handles its own error + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::imacat::Checker::Garbage::Public(curform); + $error = $checker->check(qw(message spam)); + return $error if defined $error; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM, $args); + $status = $_[0]; + $FORM = new Selima::imacat::Form::Garbage::Public($status); + $LIST = new Selima::imacat::List::Garbage::Public; + $args = $LIST->page_param; + html_header __("Soundless Backalley"), $args; + html_ctitle __("

    The

    \n

    Soundless
    Backalley

    "); + html_foreword; + html_errmsg $status; + $FORM->html; + $LIST->html; + html_footer $args; + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# html_foreword: Print the HTML foreword +sub html_foreword() { + local ($_, %_); + my ($p1, $p2); + $p1 = h(__("This is the backalley of Tavern. Every morning barmaid Cotton will put garbages here. Besides that, there's never anyone passing by. Just stinking garbages, drunks unable to tell dead or alive, cats and dogs and flies, piss and vomits. The wall is filled with drawings and words unable to tell whether they are poetry or shits. The vague music and laughters come so faraway from inside the Tavern, like a neverending rhythm repeats itself. The sun is blocked by the buildings. Even the time stops.")); + $p2 = h(__("There's no one here, just you and yourself. Soundless is the loudest sound. No matter how hard if you cry, shout or scream, you're still alone. This is the darkest and the loneliest corner in the Tavern.")); + + print << "EOT"; +
    +

    $p1

    + +

    $p2

    + +
    + +EOT + return; +} diff --git a/htdocs/imacat/cgi-bin/guestbook.cgi b/htdocs/imacat/cgi-bin/guestbook.cgi new file mode 100755 index 0000000..1dad554 --- /dev/null +++ b/htdocs/imacat/cgi-bin/guestbook.cgi @@ -0,0 +1,148 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# 1-guestbook.cgi: The guestbook. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-20 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub html_foreword(); + +initenv(-session => 0, + -this_table => "guestbook", + -dbi_lock => {"guestbook" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("Travellers' Guestbook"), + "class" => "guestbook", + "javascripts" => [qw(/scripts/guestbook.js)], + "no_auto_title" => 1}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::Guestbook::Public($POST); + $processor->process; + http_303 $REQUEST_FILE; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + # Old styled page number + http_301 $REQUEST_FILE if defined $GET->param("no"); + # List handler handles its own error + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::imacat::Checker::Guestbook::Public(curform); + $error = $checker->check(qw(message name identity location + email url flood dup spam)); + return $error if defined $error; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM, $args); + $status = $_[0]; + $FORM = new Selima::imacat::Form::Guestbook::Public($status); + $LIST = new Selima::imacat::List::Guestbook::Public; + $args = $LIST->page_param; + html_header __("Travellers' Guestbook"), $args; + html_ctitle __("

    Tavern IMACAT’s

    \n

    Travellers’
    Guestbook

    "); + html_foreword; + html_errmsg $status; + $FORM->html; + $LIST->html; + html_footer $args; + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# html_foreword: Print the HTML foreword +sub html_foreword() { + local ($_, %_); + my ($p1, $p2, $sr); + $p1 = h(__("Good morning to thee, gentle friend and traveller!")); + $p2 = h(__("I call thee \"traveller\" no matter if thou hast never left thy home town, no matter if thou wilst never again leave thy room, because all of us are travellers. I call thee traveller for truly all of us travel a spiritual or philosophical path -- even if it is simply by living the life that we choose to live, or by searching for a new life when our current one fails to satisfy our needs as thinking spiritual beings.")); + $p2 =~ s/--/—/; + $p2 =~ s/"(.+?)"/$1<\/q>/; + $sr = h(__("-- The Book of Fellowship, Ultima VII")); + $sr =~ s/--/—/; + + print << "EOT"; +
    +

    $p1

    + +

    $p2

    + +
    $sr
    + +
    + +EOT + return; +} diff --git a/htdocs/imacat/cgi-bin/ip.cgi b/htdocs/imacat/cgi-bin/ip.cgi new file mode 100755 index 0000000..4d50644 --- /dev/null +++ b/htdocs/imacat/cgi-bin/ip.cgi @@ -0,0 +1,5 @@ +#! /bin/sh + +echo "Content-Type: text/plain" +echo +echo $REMOTE_ADDR diff --git a/htdocs/imacat/cgi-bin/last_update.cgi b/htdocs/imacat/cgi-bin/last_update.cgi new file mode 100755 index 0000000..f638aee --- /dev/null +++ b/htdocs/imacat/cgi-bin/last_update.cgi @@ -0,0 +1,142 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# last_update.cgi: The last-update date of the whole web site. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-08 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub find_files_in(\@\@); +sub fmttime_local($); +sub html_image($); + +use File::Spec; +use GD; +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use vars qw(@DIREXCS %RDIREXCS @FGCOLOR @BGCOLOR $FONT); +# Directories to be excluded (no leading and trailing slashes) +@DIREXCS = qw(magicat data home misc); +@FGCOLOR = (255, 255, 128); # #FFFF80 Yellow +@BGCOLOR = (0, 0, 0); # #000000 Black +$FONT = gdLargeFont; +use constant TRANSPARENT => 0; +initenv( -allowed => [qw(GET HEAD)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0, + -multilang => 0); +%RDIREXCS = map { File::Spec->catfile($DOC_ROOT, $_) => 1 } @DIREXCS; + +main; +exit 0; + +sub main() { + local ($_, %_); + my (@tables, @files, @dirs); + + @tables = qw(); + @files = qw(); + @dirs = ($DOC_ROOT); + find_files_in(@files, @dirs); + http_304 if not_modified @tables, @files; + + html_image($LAST_MODIFIED); + + return; +} + +# find_files_in: an easy file finder +sub find_files_in(\@\@) { + local ($_, %_); + my ($files, $dirs, @subdirs, $DH, $ent); + ($files, $dirs) = @_; + + # Bounce for nothing + return if scalar(@$dirs) == 0; + # Look in these directories + @subdirs = qw(); + foreach my $dir (@$dirs) { + $dir =~ s/\/$//; + opendir $DH, $dir or die "$dir: $!"; + while (defined($_ = readdir $DH)) { + next if /^\./; + # Using catfile() is better, but a lot slower + $ent = File::Spec->catfile($dir, $_); + #$ent = "$dir/$_"; + if (-f $ent) { + push @$files, $ent; + } elsif (-d $ent) { + push @subdirs, $ent + if !exists $RDIREXCS{$ent}; + } + } + closedir $DH or die "$dir: $!"; + } + # Look in the subdirectories + find_files_in @$files, @subdirs; + return; +} + +# fmttime_local: Format the time using my own format +sub fmttime_local($) { + @_ = localtime $_[0]; + return sprintf "%d.%d.'%02d", $_[4]+1, $_[3], ($_[5]+1900) % 100; +} + +# html_image: Make the image from the last-update value +sub html_image($) { + local $_; + my ($last_update, $image, $width, $height, $fgcolor, $bgcolor); + $last_update = $_[0]; + + # Format the date to my preferred format + $last_update = fmttime_local($last_update); + + # Initialize the image object + # Get the width and height + $width = $FONT->width * (length $last_update); + $height = $FONT->height; + # Create an image object + $image = GD::Image->new($width, $height); + # Create the forground/background color objects + $fgcolor = $image->colorAllocate(@FGCOLOR); + $bgcolor = $image->colorAllocate(@BGCOLOR); + + # Draw the image + # Set the transparent background + $image->transparent($bgcolor) if TRANSPARENT; + # Paint the background + $image->filledRectangle(0, 0, $width, $height, $bgcolor); + # Write the text + $image->string($FONT, 0, 0, $last_update, $fgcolor); + + # Output + $CONTENT_TYPE = "image/png"; + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":raw"; + print $image->png; + + return; +} diff --git a/htdocs/imacat/cgi-bin/mailto.cgi b/htdocs/imacat/cgi-bin/mailto.cgi new file mode 100755 index 0000000..1577087 --- /dev/null +++ b/htdocs/imacat/cgi-bin/mailto.cgi @@ -0,0 +1,70 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# mailto.cgi: The e-mail hyperlink redirector. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-05-12 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_post(); + +use Fcntl qw(:seek); + +initenv(-allowed => [qw(POST)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $error; + + # Only POSTed forms are allowed + $error = check_post; + # If an error occurs + if (defined $error) { + http_400; + + # Else, save the data + } else { + http_303 "mailto:" . $POST->param("email"); + } + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::Checker::MailTo(curform); + $error = $checker->check(qw(email)); + return $error if defined $error; + # OK + return; +} diff --git a/htdocs/imacat/cgi-bin/plurkavatar.cgi b/htdocs/imacat/cgi-bin/plurkavatar.cgi new file mode 100755 index 0000000..c16d607 --- /dev/null +++ b/htdocs/imacat/cgi-bin/plurkavatar.cgi @@ -0,0 +1,132 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# plurkavatar.cgi: The Plurk user avator viewer. + +# Copyright (c) 2009-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2009-09-09 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use LWP::UserAgent qw(); +use IO::NestedCapture qw(CAPTURE_STDOUT); +use Time::HiRes qw(); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $r = shift; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub html_form(); + +initenv( -allowed => [qw(GET HEAD)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0, + -page_param => {"keywords" => N_("Plurk")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($ua, $user, $url, $r, $uid, $max, $found, @avails, $html); + my ($alt, $error); + + # Find the maximum number + $ua = new LWP::UserAgent; + undef $found; + undef $error; + if (defined($user = $GET->param("user"))) { + if ($user =~ /\S/) { + $user =~ s/^\s*//; + $user =~ s/\s*$//; + $url = "http://www.plurk.com/$user"; + $r = $ua->get($url); + if ($r->is_success) { + if ($r->content =~ /\bhttp:\/\/avatars\.plurk\.com\/(\d+)-big(\d*)\.jpg\b/) { + ($uid, $max, $found) = ($1, $2 eq ""? 1: $2, 1); + } elsif ($r->content =~ /\b$user is not found\b/) { + $error = {"msg"=>N_("There is no Plurk user \"[_1]\"."), + "margs"=>[$user]}; + } else { + $error = {"msg"=>N_("Avator is not found for user \"[_1]\"."), + "margs"=>[$user]}; + } + } else { + $error = {"msg"=>N_("Plurk service is not available now.")}; + } + } else { + $error = {"msg"=>N_("Please fill in the Plurk user.")}; + } + } + # Obtain the list of available avatars + if ($found) { + for ($_ = 1, @avails = qw(); $_ <= $max; $_++) { + $url = "http://avatars.plurk.com/$uid-big" + . ($_ == 1? "": $_) . ".jpg"; + push @avails, $_ if $ua->head($url)->is_success; + } + } + + # No avators + if (!$found) { + html_header(__("Plurk Avatars")); + html_errmsg($error) if defined $error; + html_form(); + html_footer(); + + # Show the avatars + } else { + html_header(__("Plurk Avatars for User [_1]", $user)); + html_form(); + print "
    \n"; + foreach (@avails) { + $url = h("http://avatars.plurk.com/$uid-big" + . ($_ == 1? "": $_) . ".jpg"); + $alt = h("$user no.$_"); + print << "EOT"; +
    +$alt +
    + +EOT + } + print "
    \n\n"; + html_footer(); + } + return; +} + +# html_form: Display the form +sub html_form() { + local ($_, %_); + my ($user, $label); + $user = defined $GET->param("user")? h($GET->param("user")): ""; + $label = h(__("Plurk user:")); +print << "EOT"; +
    +
    + + + +
    +
    + +EOT +} diff --git a/htdocs/imacat/cgi-bin/plurkfav.cgi b/htdocs/imacat/cgi-bin/plurkfav.cgi new file mode 100755 index 0000000..7a53a5c --- /dev/null +++ b/htdocs/imacat/cgi-bin/plurkfav.cgi @@ -0,0 +1,128 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# plurkfav.cgi: The Plurk message favorite setting script. + +# Copyright (c) 2010-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2010-03-08 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use LWP::UserAgent qw(); +use IO::NestedCapture qw(CAPTURE_STDOUT); +use Time::HiRes qw(); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $r = shift; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub permlink2plurkid($); +sub html_form(); +sub html_plurkfav_form($); + +initenv( -allowed => [qw(GET HEAD)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0, + -page_param => {"keywords" => N_("Plurk")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($permlink, $plurkid); + + html_header(__("Plurk Favorites")); + html_form(); + if (defined($permlink = $GET->param("permlink"))) { + $plurkid = permlink2plurkid($permlink); + html_plurkfav_form($plurkid); + } + html_footer(); + + return; +} + +# permlink2plurkid: Converts a Plurk permanent link to a Plurk ID +sub permlink2plurkid($) { + local ($_, %_); + my ($permlink, $plurkid); + $permlink = $_[0]; + $permlink =~ s/^http:\/\/www\.plurk\.com\/p\/([a-z0-9]+)$/$1/i; + for (my $i = 0, $plurkid = 0; $i < length $permlink; $i++) { + my ($c, $d); + $c = lc substr $permlink, $i, 1; + if ($c =~ /^\d$/) { + $d = $c + 0; + } else { + $d = 10 + (ord($c) - ord("a")); + } + $plurkid = $plurkid * 36 + $d; + } + return $plurkid; +} + +# html_form: Display the form +sub html_form() { + local ($_, %_); + my ($permlink, $label); + $label = h(__("Plurk permanent link URL:")); + $permlink = "" if !defined($permlink = $GET->param("permlink")); +print << "EOT"; +
    +
    + + + +
    +
    + +EOT +} + +# html_plurkfav_form: Display the Plurk favorite set form +sub html_plurkfav_form($) { + local ($_, %_); + my ($plurkid, $labelid, $labelset, $labelunset); + $plurkid = $_[0]; + $labelid = h(__("Plurk ID: [_1]", $plurkid)); + $labelset = h(__("Set Plurk favorite")); + $labelunset = h(__("Unset Plurk favorite")); +print << "EOT"; +

    $labelid

    + +
    +
    + + + +
    +
    + +
    +
    + + + +
    +
    + +EOT +} diff --git a/htdocs/imacat/cgi-bin/search.cgi b/htdocs/imacat/cgi-bin/search.cgi new file mode 100755 index 0000000..ea5c670 --- /dev/null +++ b/htdocs/imacat/cgi-bin/search.cgi @@ -0,0 +1,60 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# search.cgi: The web site full-text search. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-10 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); + +use Fcntl qw(:seek); + +initenv(-allowed => [qw(GET HEAD)], + -session => 0, + -dbi_lock => {"pages" => LOCK_SH, + "diary" => LOCK_SH, + "changelog" => LOCK_SH, + "links" => LOCK_SH, + "guestbook" => LOCK_SH, + "garbage" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("search, query, full text search"), + "class" => "search", + "no_auto_title" => 1}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $LIST; + # List handler handles its own error + $LIST = new Selima::imacat::List::Search; + html_header $LIST->{"title"}, $LIST->page_param; + html_ctitle $LIST->{"ctitle"}; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/imacat/copying.html.en.html b/htdocs/imacat/copying.html.en.html new file mode 120000 index 0000000..14dc012 --- /dev/null +++ b/htdocs/imacat/copying.html.en.html @@ -0,0 +1 @@ +copying.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/copying.html.en.xhtml b/htdocs/imacat/copying.html.en.xhtml new file mode 100644 index 0000000..a66c852 --- /dev/null +++ b/htdocs/imacat/copying.html.en.xhtml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + +Copyright on Tavern IMACAT’s + + + + + + + +
    + +
    + + +

    Copyright on Tavern IMACAT’s

    + +

    Copyright on Tavern IMACAT’s

    + +

    All graphics, texts in Tavern IMACAT’s are copyrighted by imacat. You are free to forward, transfer provided the following conditions are met:

    + +
      +
    1. The author name and a reference to the source page MUST be included, in a format like this: +
      by imacat, https://www.imacat.idv.tw/somepage.html
      +
    2. +
    3. You MUST NOT modify, add, or remove any or part of the content.
    4. +
    5. All the texts in Tavern IMACAT’s are welcome to be freely distributed, transferred or forwarded under non-commercial purposes. You MUST obtain a prior permission from imacat before any commercial or academical citation or redistribution.
    6. + +
    7. All the graphics in Tavern IMACAT’s are welcome to be freely distributed, transferred or forwarded under non-commercial purposes, provided that you have notified me prior to use them. You MUST obtain a prior permission from imacat before any commercial or academical citation or redistribution.
    8. +
    9. The copyrights regarding to all the messages on the guestbooks of Tavern IMACAT’s are irrevelent to Tavern IMACAT’s. They are subject to Copyright on Guestbooks. The copyright of Woman’s Voice in Tavern is irrevelent to Tavern IMACAT’s. It is subject to Copyright on Woman’s Voice.
    10. +
    + + +

    Copyright on Guestbooks in Tavern IMACAT’s

    + +

    All the messages on all the guestbooks in Tavern IMACAT’s (Travellers’ Guestbook, Soundless Backalley) are copyrighted by their individual authors. Tavern IMACAT’s HAVE NO RIGHT ON THEM. The Copyright on Tavern IMACAT’s does not apply to any message on the guestbooks. You MUST obtain prior permission from the corresponding authors individually before citing or redistributing any message on the guestbooks. If the author of a message is not reachable, any citation or redistribution on that specific message is prohibited.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/copying.html.zh-cn.html b/htdocs/imacat/copying.html.zh-cn.html new file mode 120000 index 0000000..42fbf87 --- /dev/null +++ b/htdocs/imacat/copying.html.zh-cn.html @@ -0,0 +1 @@ +copying.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/copying.html.zh-cn.xhtml b/htdocs/imacat/copying.html.zh-cn.xhtml new file mode 100644 index 0000000..4dfbd71 --- /dev/null +++ b/htdocs/imacat/copying.html.zh-cn.xhtml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + +旅舍依玛版权声明 + + + + + + + +
    + +
    + + +

    旅舍依玛版权声明

    + +

    旅舍依玛版权声明

    + +

    旅舍依玛除留言板与女声外,所有图、文版权属依玛猫所有,欢迎转载、引用,唯请遵守以下事项:

    + +
      +
    1. 必须以下列格式,注明原作者及出处网址: +
      作者:依玛猫, https://www.imacat.idv.tw/某某页.html
      +
    2. +
    3. 不得对内容作任何更动、添增、删改。
    4. +
    5. 旅舍依玛所有文字,除留言板与女声外,欢迎非商业自由转载、引用。欲作商业或学术文字转载(含论文发表、媒体报导、书刊出版),必须事先取得依玛猫同意。
    6. +
    7. 旅舍依玛所有图片,在事先知会依玛猫之下,欢迎非商业自由转载、引用。欲作商业或学术转载(含论文发表、媒体报导、书刊出版),必须事先取得依玛猫同意。
    8. +
    9. 旅舍依玛留言板留言版权与旅舍依玛无关,另以留言板版权声明为准。旅舍依玛中的女声所有版权与旅舍依玛版权声明无关,以《女声》电子报版权声明为准。
    10. + +
    + + +

    旅舍依玛留言板版权声明

    + +

    旅舍依玛所有留言板留言(旅人留言簿、无声的后巷)版权属各留言人所有,与旅舍依玛无关旅舍依玛版权声明不适用於留言板留言。欲转载、引用任何留言板留言,必须事先取得各该留言人之同意。若无法连络该留言人,一律禁止转载、引用。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/copying.html.zh-tw.html b/htdocs/imacat/copying.html.zh-tw.html new file mode 120000 index 0000000..5db280e --- /dev/null +++ b/htdocs/imacat/copying.html.zh-tw.html @@ -0,0 +1 @@ +copying.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/copying.html.zh-tw.xhtml b/htdocs/imacat/copying.html.zh-tw.xhtml new file mode 100644 index 0000000..a9864fe --- /dev/null +++ b/htdocs/imacat/copying.html.zh-tw.xhtml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + +旅舍依瑪版權聲明 + + + + + + + +
    + +
    + + +

    旅舍依瑪版權聲明

    + +

    旅舍依瑪版權聲明

    + +

    旅舍依瑪除留言板與女聲外,所有圖、文版權屬依瑪貓所有,歡迎轉載、引用,唯請遵守以下事項:

    + +
      +
    1. 必須以下列格式,註明原作者及出處網址: +
      作者:依瑪貓, https://www.imacat.idv.tw/某某頁.html
      +
    2. +
    3. 不得對內容作任何更動、添增、刪改。
    4. +
    5. 旅舍依瑪所有文字,除留言板與女聲外,歡迎非商業自由轉載、引用。欲作商業或學術文字轉載(含論文發表、媒體報導、書刊出版),必須事先取得依瑪貓同意。
    6. +
    7. 旅舍依瑪所有圖片,在事先知會依瑪貓之下,歡迎非商業自由轉載、引用。欲作商業或學術轉載(含論文發表、媒體報導、書刊出版),必須事先取得依瑪貓同意。
    8. +
    9. 旅舍依瑪留言板留言版權與旅舍依瑪無關,另以留言板版權聲明為準。旅舍依瑪中的女聲所有版權與旅舍依瑪版權聲明無關,以《女聲》電子報版權聲明為準。
    10. + +
    + + +

    旅舍依瑪留言板版權聲明

    + +

    旅舍依瑪所有留言板留言(旅人留言簿、無聲的後巷)版權屬各留言人所有,與旅舍依瑪無關旅舍依瑪版權聲明不適用於留言板留言。欲轉載、引用任何留言板留言,必須事先取得各該留言人之同意。若無法連絡該留言人,一律禁止轉載、引用。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/301.html.en.html b/htdocs/imacat/errors/301.html.en.html new file mode 120000 index 0000000..1a4e001 --- /dev/null +++ b/htdocs/imacat/errors/301.html.en.html @@ -0,0 +1 @@ +301.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/301.html.en.xhtml b/htdocs/imacat/errors/301.html.en.xhtml new file mode 100644 index 0000000..380c49c --- /dev/null +++ b/htdocs/imacat/errors/301.html.en.xhtml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 301 Moved Permanently + + + + + + + +
    + +
    + + +

    HTTP 301 Moved Permanently

    + +

    This page has been moved permanently. Please update your bookmark and refer to the new address from now on.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/301.html.zh-cn.html b/htdocs/imacat/errors/301.html.zh-cn.html new file mode 120000 index 0000000..2c34567 --- /dev/null +++ b/htdocs/imacat/errors/301.html.zh-cn.html @@ -0,0 +1 @@ +301.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/301.html.zh-cn.xhtml b/htdocs/imacat/errors/301.html.zh-cn.xhtml new file mode 100644 index 0000000..2298418 --- /dev/null +++ b/htdocs/imacat/errors/301.html.zh-cn.xhtml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 301 网址已迁 + + + + + + + +
    + +
    + + +

    HTTP 301 网址已迁

    + +

    本页已迁址,日后请更新你的书签或你的最爱,并改往新址

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/301.html.zh-tw.html b/htdocs/imacat/errors/301.html.zh-tw.html new file mode 120000 index 0000000..ca0c94a --- /dev/null +++ b/htdocs/imacat/errors/301.html.zh-tw.html @@ -0,0 +1 @@ +301.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/301.html.zh-tw.xhtml b/htdocs/imacat/errors/301.html.zh-tw.xhtml new file mode 100644 index 0000000..f6e94ff --- /dev/null +++ b/htdocs/imacat/errors/301.html.zh-tw.xhtml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 301 網址已遷 + + + + + + + +
    + +
    + + +

    HTTP 301 網址已遷

    + +

    本頁已遷址,日後請更新妳的書籤或妳的最愛,並改往新址

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/303.html.en.html b/htdocs/imacat/errors/303.html.en.html new file mode 120000 index 0000000..3dba332 --- /dev/null +++ b/htdocs/imacat/errors/303.html.en.html @@ -0,0 +1 @@ +303.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/303.html.en.xhtml b/htdocs/imacat/errors/303.html.en.xhtml new file mode 100644 index 0000000..6603b67 --- /dev/null +++ b/htdocs/imacat/errors/303.html.en.xhtml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 303 See Other + + + + + + + +
    + +
    + + +

    HTTP 303 See Other

    + +

    Please follow to the next page.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/303.html.zh-cn.html b/htdocs/imacat/errors/303.html.zh-cn.html new file mode 120000 index 0000000..997f478 --- /dev/null +++ b/htdocs/imacat/errors/303.html.zh-cn.html @@ -0,0 +1 @@ +303.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/303.html.zh-cn.xhtml b/htdocs/imacat/errors/303.html.zh-cn.xhtml new file mode 100644 index 0000000..fbcce6d --- /dev/null +++ b/htdocs/imacat/errors/303.html.zh-cn.xhtml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 303 续往下址 + + + + + + + +
    + +
    + + +

    HTTP 303 续往下址

    + +

    请续往后续的网址

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/303.html.zh-tw.html b/htdocs/imacat/errors/303.html.zh-tw.html new file mode 120000 index 0000000..fa3b7a0 --- /dev/null +++ b/htdocs/imacat/errors/303.html.zh-tw.html @@ -0,0 +1 @@ +303.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/303.html.zh-tw.xhtml b/htdocs/imacat/errors/303.html.zh-tw.xhtml new file mode 100644 index 0000000..8d42d89 --- /dev/null +++ b/htdocs/imacat/errors/303.html.zh-tw.xhtml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 303 續往下址 + + + + + + + +
    + +
    + + +

    HTTP 303 續往下址

    + +

    請續往後續的網址

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/307.html.en.html b/htdocs/imacat/errors/307.html.en.html new file mode 120000 index 0000000..f04e0dc --- /dev/null +++ b/htdocs/imacat/errors/307.html.en.html @@ -0,0 +1 @@ +307.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/307.html.en.xhtml b/htdocs/imacat/errors/307.html.en.xhtml new file mode 100644 index 0000000..b91a061 --- /dev/null +++ b/htdocs/imacat/errors/307.html.en.xhtml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 307 Temporary Redirect + + + + + + + +
    + +
    + + +

    HTTP 307 Temporary Redirect

    + +

    Please refer to the current location for this page.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/307.html.zh-cn.html b/htdocs/imacat/errors/307.html.zh-cn.html new file mode 120000 index 0000000..1bdaf2d --- /dev/null +++ b/htdocs/imacat/errors/307.html.zh-cn.html @@ -0,0 +1 @@ +307.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/307.html.zh-cn.xhtml b/htdocs/imacat/errors/307.html.zh-cn.xhtml new file mode 100644 index 0000000..1c1d663 --- /dev/null +++ b/htdocs/imacat/errors/307.html.zh-cn.xhtml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 307 网址暂移 + + + + + + + +
    + +
    + + +

    HTTP 307 网址暂移

    + +

    请参阅本页目前的网址

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/307.html.zh-tw.html b/htdocs/imacat/errors/307.html.zh-tw.html new file mode 120000 index 0000000..afdb33b --- /dev/null +++ b/htdocs/imacat/errors/307.html.zh-tw.html @@ -0,0 +1 @@ +307.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/307.html.zh-tw.xhtml b/htdocs/imacat/errors/307.html.zh-tw.xhtml new file mode 100644 index 0000000..4cf3601 --- /dev/null +++ b/htdocs/imacat/errors/307.html.zh-tw.xhtml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 307 網址暫移 + + + + + + + +
    + +
    + + +

    HTTP 307 網址暫移

    + +

    請參閱本頁目前的網址

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/400.html.en.html b/htdocs/imacat/errors/400.html.en.html new file mode 120000 index 0000000..0dd7e33 --- /dev/null +++ b/htdocs/imacat/errors/400.html.en.html @@ -0,0 +1 @@ +400.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/400.html.en.xhtml b/htdocs/imacat/errors/400.html.en.xhtml new file mode 100644 index 0000000..9f9b0dc --- /dev/null +++ b/htdocs/imacat/errors/400.html.en.xhtml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 400 Bad Request + + + + + + + +
    + +
    + + +

    HTTP 400 Bad Request

    + + + +

    Sorry, you have a syntax error in your request. The server cannot understand your request. This might be a bug of your browser, or a typo in the url you had just keyed in. Please correct this error, or browse back from the Tavern Lobby.

    + +

    If you have any question, please mail to me.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/400.html.zh-cn.html b/htdocs/imacat/errors/400.html.zh-cn.html new file mode 120000 index 0000000..c3f0fa8 --- /dev/null +++ b/htdocs/imacat/errors/400.html.zh-cn.html @@ -0,0 +1 @@ +400.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/400.html.zh-cn.xhtml b/htdocs/imacat/errors/400.html.zh-cn.xhtml new file mode 100644 index 0000000..67934d0 --- /dev/null +++ b/htdocs/imacat/errors/400.html.zh-cn.xhtml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 400 语法错误 + + + + + + + +
    + +
    + + +

    HTTP 400 语法错误

    + + + +

    很抱歉,你的要求语法错误,网站看不懂你的要求。这可能是浏览器的问题,或你输入的网址有笔误。请更正你的笔误,或请回旅舍大厅重新浏览。

    + +

    若有任何问题,请来信告诉依玛

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/400.html.zh-tw.html b/htdocs/imacat/errors/400.html.zh-tw.html new file mode 120000 index 0000000..ff08240 --- /dev/null +++ b/htdocs/imacat/errors/400.html.zh-tw.html @@ -0,0 +1 @@ +400.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/400.html.zh-tw.xhtml b/htdocs/imacat/errors/400.html.zh-tw.xhtml new file mode 100644 index 0000000..ee1a32b --- /dev/null +++ b/htdocs/imacat/errors/400.html.zh-tw.xhtml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 400 語法錯誤 + + + + + + + +
    + +
    + + +

    HTTP 400 語法錯誤

    + + + +

    很抱歉,妳的要求語法錯誤,網站看不懂妳的要求。這可能是瀏覽器的問題,或妳輸入的網址有筆誤。請更正妳的筆誤,或請回旅舍大廳重新瀏覽。

    + +

    若有任何問題,請來信告訴依瑪

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/401.html.en.html b/htdocs/imacat/errors/401.html.en.html new file mode 120000 index 0000000..d248fee --- /dev/null +++ b/htdocs/imacat/errors/401.html.en.html @@ -0,0 +1 @@ +401.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/401.html.en.xhtml b/htdocs/imacat/errors/401.html.en.xhtml new file mode 100644 index 0000000..a06275d --- /dev/null +++ b/htdocs/imacat/errors/401.html.en.xhtml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 401 Unauthorized + + + + + + + +
    + +
    + + +

    HTTP 401 Unauthorized

    + +

    Sorry, this page is restricted. Please browse back from the Tavern Lobby.

    + +

    If you have any question, please mail to me.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/401.html.zh-cn.html b/htdocs/imacat/errors/401.html.zh-cn.html new file mode 120000 index 0000000..af53bed --- /dev/null +++ b/htdocs/imacat/errors/401.html.zh-cn.html @@ -0,0 +1 @@ +401.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/401.html.zh-cn.xhtml b/htdocs/imacat/errors/401.html.zh-cn.xhtml new file mode 100644 index 0000000..65a9b3f --- /dev/null +++ b/htdocs/imacat/errors/401.html.zh-cn.xhtml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 401 非请莫入 + + + + + + + +
    + +
    + + +

    HTTP 401 非请莫入

    + +

    很抱歉,本页非请莫入,请回旅舍大厅重新浏览。

    + +

    若有任何问题,请来信告诉依玛

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/401.html.zh-tw.html b/htdocs/imacat/errors/401.html.zh-tw.html new file mode 120000 index 0000000..414f7f3 --- /dev/null +++ b/htdocs/imacat/errors/401.html.zh-tw.html @@ -0,0 +1 @@ +401.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/401.html.zh-tw.xhtml b/htdocs/imacat/errors/401.html.zh-tw.xhtml new file mode 100644 index 0000000..5da7500 --- /dev/null +++ b/htdocs/imacat/errors/401.html.zh-tw.xhtml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 401 非請莫入 + + + + + + + +
    + +
    + + +

    HTTP 401 非請莫入

    + +

    很抱歉,本頁非請莫入,請回旅舍大廳重新瀏覽。

    + +

    若有任何問題,請來信告訴依瑪

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/403.html.en.html b/htdocs/imacat/errors/403.html.en.html new file mode 120000 index 0000000..4ec2c67 --- /dev/null +++ b/htdocs/imacat/errors/403.html.en.html @@ -0,0 +1 @@ +403.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/403.html.en.xhtml b/htdocs/imacat/errors/403.html.en.xhtml new file mode 100644 index 0000000..5364e29 --- /dev/null +++ b/htdocs/imacat/errors/403.html.en.xhtml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 403 Forbidden + + + + + + + +
    + +
    + + +

    HTTP 403 Forbidden

    + + + +

    Sorry, this page is prohibbited. Please browse back from the Tavern Lobby.

    + +

    If you have any question, please mail to me.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/403.html.zh-cn.html b/htdocs/imacat/errors/403.html.zh-cn.html new file mode 120000 index 0000000..0142bee --- /dev/null +++ b/htdocs/imacat/errors/403.html.zh-cn.html @@ -0,0 +1 @@ +403.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/403.html.zh-cn.xhtml b/htdocs/imacat/errors/403.html.zh-cn.xhtml new file mode 100644 index 0000000..f85f4f0 --- /dev/null +++ b/htdocs/imacat/errors/403.html.zh-cn.xhtml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 403 禁止进入 + + + + + + + +
    + +
    + + +

    HTTP 403 禁止进入

    + + + +

    很抱歉,本页禁止进入,请回旅舍大厅重新浏览。

    + +

    若有任何问题,请来信告诉依玛

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/403.html.zh-tw.html b/htdocs/imacat/errors/403.html.zh-tw.html new file mode 120000 index 0000000..90fdd98 --- /dev/null +++ b/htdocs/imacat/errors/403.html.zh-tw.html @@ -0,0 +1 @@ +403.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/403.html.zh-tw.xhtml b/htdocs/imacat/errors/403.html.zh-tw.xhtml new file mode 100644 index 0000000..7e65b09 --- /dev/null +++ b/htdocs/imacat/errors/403.html.zh-tw.xhtml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 403 禁止進入 + + + + + + + +
    + +
    + + +

    HTTP 403 禁止進入

    + + + +

    很抱歉,本頁禁止進入,請回旅舍大廳重新瀏覽。

    + +

    若有任何問題,請來信告訴依瑪

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/404.html.en.html b/htdocs/imacat/errors/404.html.en.html new file mode 120000 index 0000000..304df2e --- /dev/null +++ b/htdocs/imacat/errors/404.html.en.html @@ -0,0 +1 @@ +404.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/404.html.en.xhtml b/htdocs/imacat/errors/404.html.en.xhtml new file mode 100644 index 0000000..0f3586a --- /dev/null +++ b/htdocs/imacat/errors/404.html.en.xhtml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 404 Not Found + + + + + + + +
    + +
    + + +

    HTTP 404 Not Found

    + +

    Sorry, we could not find the content you’re looking for. Please check your web address again. If you entered here from another place, please mail to me.

    + +

    You could browse back from the Tavern Lobby.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/404.html.zh-cn.html b/htdocs/imacat/errors/404.html.zh-cn.html new file mode 120000 index 0000000..1484be9 --- /dev/null +++ b/htdocs/imacat/errors/404.html.zh-cn.html @@ -0,0 +1 @@ +404.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/404.html.zh-cn.xhtml b/htdocs/imacat/errors/404.html.zh-cn.xhtml new file mode 100644 index 0000000..aa28a1c --- /dev/null +++ b/htdocs/imacat/errors/404.html.zh-cn.xhtml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 404 找不到网页 + + + + + + + +
    + +
    + + +

    HTTP 404 找不到网页

    + +

    很抱歉,找不到你想连的那一页。请检查你的网址是否有误。若你是由其它地方连上这里,请来信告诉依玛

    + +

    你可以回到旅舍大厅重新浏览。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/404.html.zh-tw.html b/htdocs/imacat/errors/404.html.zh-tw.html new file mode 120000 index 0000000..a743524 --- /dev/null +++ b/htdocs/imacat/errors/404.html.zh-tw.html @@ -0,0 +1 @@ +404.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/404.html.zh-tw.xhtml b/htdocs/imacat/errors/404.html.zh-tw.xhtml new file mode 100644 index 0000000..a6aadf2 --- /dev/null +++ b/htdocs/imacat/errors/404.html.zh-tw.xhtml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 404 找不到網頁 + + + + + + + +
    + +
    + + +

    HTTP 404 找不到網頁

    + +

    很抱歉,找不到妳想連的那一頁。請檢查妳的網址是否有誤。若妳是由其它地方連上這裡,請來信告訴依瑪

    + +

    妳可以回到旅舍大廳重新瀏覽。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/405.html.en.html b/htdocs/imacat/errors/405.html.en.html new file mode 120000 index 0000000..c29d4b7 --- /dev/null +++ b/htdocs/imacat/errors/405.html.en.html @@ -0,0 +1 @@ +405.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/405.html.en.xhtml b/htdocs/imacat/errors/405.html.en.xhtml new file mode 100644 index 0000000..2fc818e --- /dev/null +++ b/htdocs/imacat/errors/405.html.en.xhtml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 405 Method Not Allowed + + + + + + + +
    + +
    + + +

    HTTP 405 Method Not Allowed

    + +

    Sorry, this method is not allowed for here. Please use the following methods: $allowed

    + +

    If you have any question, please mail to me.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/405.html.zh-cn.html b/htdocs/imacat/errors/405.html.zh-cn.html new file mode 120000 index 0000000..542afaf --- /dev/null +++ b/htdocs/imacat/errors/405.html.zh-cn.html @@ -0,0 +1 @@ +405.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/405.html.zh-cn.xhtml b/htdocs/imacat/errors/405.html.zh-cn.xhtml new file mode 100644 index 0000000..45cff3c --- /dev/null +++ b/htdocs/imacat/errors/405.html.zh-cn.xhtml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 405 要求方式无效 + + + + + + + +
    + +
    + + +

    HTTP 405 要求方式无效

    + +

    很抱歉,无法用这个方式连到此页。请改用以下方式: $allowed 。

    + +

    若有任何问题,请来信告诉依玛

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/405.html.zh-tw.html b/htdocs/imacat/errors/405.html.zh-tw.html new file mode 120000 index 0000000..919ef82 --- /dev/null +++ b/htdocs/imacat/errors/405.html.zh-tw.html @@ -0,0 +1 @@ +405.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/405.html.zh-tw.xhtml b/htdocs/imacat/errors/405.html.zh-tw.xhtml new file mode 100644 index 0000000..568a03d --- /dev/null +++ b/htdocs/imacat/errors/405.html.zh-tw.xhtml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 405 要求方式無效 + + + + + + + +
    + +
    + + +

    HTTP 405 要求方式無效

    + +

    很抱歉,無法用這個方式連到此頁。請改用以下方式: $allowed 。

    + +

    若有任何問題,請來信告訴依瑪

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/410.html.en.html b/htdocs/imacat/errors/410.html.en.html new file mode 120000 index 0000000..4846b5e --- /dev/null +++ b/htdocs/imacat/errors/410.html.en.html @@ -0,0 +1 @@ +410.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/410.html.en.xhtml b/htdocs/imacat/errors/410.html.en.xhtml new file mode 100644 index 0000000..cf7ef5d --- /dev/null +++ b/htdocs/imacat/errors/410.html.en.xhtml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 410 Gone + + + + + + + +
    + +
    + + +

    HTTP 410 Gone

    + +

    This content has been removed from the website. Sorry for the inconvienence.

    + +

    You could browse back from the Tavern Lobby.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/410.html.zh-cn.html b/htdocs/imacat/errors/410.html.zh-cn.html new file mode 120000 index 0000000..2a83f04 --- /dev/null +++ b/htdocs/imacat/errors/410.html.zh-cn.html @@ -0,0 +1 @@ +410.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/410.html.zh-cn.xhtml b/htdocs/imacat/errors/410.html.zh-cn.xhtml new file mode 100644 index 0000000..1277480 --- /dev/null +++ b/htdocs/imacat/errors/410.html.zh-cn.xhtml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 410 已删 + + + + + + + +
    + +
    + + +

    HTTP 410 已删

    + +

    本页内容已删,造成不便请见谅。

    + +

    你可以回到旅舍大厅重新浏览。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/410.html.zh-tw.html b/htdocs/imacat/errors/410.html.zh-tw.html new file mode 120000 index 0000000..75bb5ba --- /dev/null +++ b/htdocs/imacat/errors/410.html.zh-tw.html @@ -0,0 +1 @@ +410.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/410.html.zh-tw.xhtml b/htdocs/imacat/errors/410.html.zh-tw.xhtml new file mode 100644 index 0000000..c273d3e --- /dev/null +++ b/htdocs/imacat/errors/410.html.zh-tw.xhtml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 410 已刪 + + + + + + + +
    + +
    + + +

    HTTP 410 已刪

    + +

    本頁內容已刪,造成不便請見諒。

    + +

    妳可以回到旅舍大廳重新瀏覽。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/500.html.en.html b/htdocs/imacat/errors/500.html.en.html new file mode 120000 index 0000000..a40e5e5 --- /dev/null +++ b/htdocs/imacat/errors/500.html.en.html @@ -0,0 +1 @@ +500.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/500.html.en.xhtml b/htdocs/imacat/errors/500.html.en.xhtml new file mode 100644 index 0000000..06aa9ed --- /dev/null +++ b/htdocs/imacat/errors/500.html.en.xhtml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 500 Internal Server Error + + + + + + + +
    + +
    + + +

    HTTP 500 Internal Server Error

    + + + +

    Sorry, web server has internal errors. This usually is because of CGI bugs. Please mail to me on this.

    + +

    You can browse back from the Tavern Lobby.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/500.html.zh-cn.html b/htdocs/imacat/errors/500.html.zh-cn.html new file mode 120000 index 0000000..0b88d35 --- /dev/null +++ b/htdocs/imacat/errors/500.html.zh-cn.html @@ -0,0 +1 @@ +500.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/500.html.zh-cn.xhtml b/htdocs/imacat/errors/500.html.zh-cn.xhtml new file mode 100644 index 0000000..f9d7b98 --- /dev/null +++ b/htdocs/imacat/errors/500.html.zh-cn.xhtml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 500 网站执行错误 + + + + + + + +
    + +
    + + +

    HTTP 500 网站执行错误

    + + + +

    很抱歉,网站发生错误。这通常是 CGI 程式设计问题,请来信告诉依玛

    + +

    你可以回到旅舍大厅重新浏览。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/500.html.zh-tw.html b/htdocs/imacat/errors/500.html.zh-tw.html new file mode 120000 index 0000000..9b9f64f --- /dev/null +++ b/htdocs/imacat/errors/500.html.zh-tw.html @@ -0,0 +1 @@ +500.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/500.html.zh-tw.xhtml b/htdocs/imacat/errors/500.html.zh-tw.xhtml new file mode 100644 index 0000000..6e1a006 --- /dev/null +++ b/htdocs/imacat/errors/500.html.zh-tw.xhtml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 500 網站執行錯誤 + + + + + + + +
    + +
    + + +

    HTTP 500 網站執行錯誤

    + + + +

    很抱歉,網站發生錯誤。這通常是 CGI 程式設計問題,請來信告訴依瑪

    + +

    妳可以回到旅舍大廳重新瀏覽。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/503.html.en.html b/htdocs/imacat/errors/503.html.en.html new file mode 120000 index 0000000..4f9cd15 --- /dev/null +++ b/htdocs/imacat/errors/503.html.en.html @@ -0,0 +1 @@ +503.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/503.html.en.xhtml b/htdocs/imacat/errors/503.html.en.xhtml new file mode 100644 index 0000000..84c12f6 --- /dev/null +++ b/htdocs/imacat/errors/503.html.en.xhtml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 503 Service Unavailable + + + + + + + +
    + +
    + + +

    HTTP 503 Service Unavailable

    + + + +

    Sorry, our web service is not available currently. We are updating our web site. The update should take about 1 hour. Please come again later. Thank you.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/503.html.zh-cn.html b/htdocs/imacat/errors/503.html.zh-cn.html new file mode 120000 index 0000000..f4a2c94 --- /dev/null +++ b/htdocs/imacat/errors/503.html.zh-cn.html @@ -0,0 +1 @@ +503.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/503.html.zh-cn.xhtml b/htdocs/imacat/errors/503.html.zh-cn.xhtml new file mode 100644 index 0000000..c7a120f --- /dev/null +++ b/htdocs/imacat/errors/503.html.zh-cn.xhtml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 503 网站暂停服务 + + + + + + + +
    + +
    + + +

    HTTP 503 网站暂停服务

    + + + +

    很抱歉,网站暂时停止服务。我们正在更新网站,大约要花一个小时左右。请晚点再来,谢谢。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/errors/503.html.zh-tw.html b/htdocs/imacat/errors/503.html.zh-tw.html new file mode 120000 index 0000000..83c0015 --- /dev/null +++ b/htdocs/imacat/errors/503.html.zh-tw.html @@ -0,0 +1 @@ +503.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/errors/503.html.zh-tw.xhtml b/htdocs/imacat/errors/503.html.zh-tw.xhtml new file mode 100644 index 0000000..749660c --- /dev/null +++ b/htdocs/imacat/errors/503.html.zh-tw.xhtml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + +HTTP 503 網站暫停服務 + + + + + + + +
    + +
    + + +

    HTTP 503 網站暫停服務

    + + + +

    很抱歉,網站暫時停止服務。我們正在更新網站,大約要花一個小時左右。請晚點再來,謝謝。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/favicon.ico b/htdocs/imacat/favicon.ico new file mode 100644 index 0000000..c935ae3 Binary files /dev/null and b/htdocs/imacat/favicon.ico differ diff --git a/htdocs/imacat/images/03-020.jpg b/htdocs/imacat/images/03-020.jpg new file mode 100644 index 0000000..81a9d54 Binary files /dev/null and b/htdocs/imacat/images/03-020.jpg differ diff --git a/htdocs/imacat/images/[OSDC 2013][DAY1][CYJ]-11.jpg b/htdocs/imacat/images/[OSDC 2013][DAY1][CYJ]-11.jpg new file mode 100644 index 0000000..514cf1d Binary files /dev/null and b/htdocs/imacat/images/[OSDC 2013][DAY1][CYJ]-11.jpg differ diff --git a/htdocs/imacat/images/ada-pan.jpg b/htdocs/imacat/images/ada-pan.jpg new file mode 100644 index 0000000..3af510d Binary files /dev/null and b/htdocs/imacat/images/ada-pan.jpg differ diff --git a/htdocs/imacat/images/akaishi/132.jpg b/htdocs/imacat/images/akaishi/132.jpg new file mode 100644 index 0000000..ce064d0 Binary files /dev/null and b/htdocs/imacat/images/akaishi/132.jpg differ diff --git a/htdocs/imacat/images/akaishi/21.jpg b/htdocs/imacat/images/akaishi/21.jpg new file mode 100644 index 0000000..255a6eb Binary files /dev/null and b/htdocs/imacat/images/akaishi/21.jpg differ diff --git a/htdocs/imacat/images/akaishi/22.jpg b/htdocs/imacat/images/akaishi/22.jpg new file mode 100644 index 0000000..d3f1dd4 Binary files /dev/null and b/htdocs/imacat/images/akaishi/22.jpg differ diff --git a/htdocs/imacat/images/akaishi/5.jpg b/htdocs/imacat/images/akaishi/5.jpg new file mode 100644 index 0000000..83be46d Binary files /dev/null and b/htdocs/imacat/images/akaishi/5.jpg differ diff --git a/htdocs/imacat/images/akaishi/akatukinoaria0710.jpg b/htdocs/imacat/images/akaishi/akatukinoaria0710.jpg new file mode 100644 index 0000000..a8817c2 Binary files /dev/null and b/htdocs/imacat/images/akaishi/akatukinoaria0710.jpg differ diff --git a/htdocs/imacat/images/akaishi/shicho0710.jpg b/htdocs/imacat/images/akaishi/shicho0710.jpg new file mode 100644 index 0000000..c85fc90 Binary files /dev/null and b/htdocs/imacat/images/akaishi/shicho0710.jpg differ diff --git a/htdocs/imacat/images/america_s_sweetheart.jpg b/htdocs/imacat/images/america_s_sweetheart.jpg new file mode 100644 index 0000000..304081e Binary files /dev/null and b/htdocs/imacat/images/america_s_sweetheart.jpg differ diff --git a/htdocs/imacat/images/baden/ganduyan01.jpg b/htdocs/imacat/images/baden/ganduyan01.jpg new file mode 100644 index 0000000..52b670e Binary files /dev/null and b/htdocs/imacat/images/baden/ganduyan01.jpg differ diff --git a/htdocs/imacat/images/baden/ganduyan02.jpg b/htdocs/imacat/images/baden/ganduyan02.jpg new file mode 100644 index 0000000..88e69d1 Binary files /dev/null and b/htdocs/imacat/images/baden/ganduyan02.jpg differ diff --git a/htdocs/imacat/images/baden/ganduyan03.jpg b/htdocs/imacat/images/baden/ganduyan03.jpg new file mode 100644 index 0000000..bb1e32d Binary files /dev/null and b/htdocs/imacat/images/baden/ganduyan03.jpg differ diff --git a/htdocs/imacat/images/baden/starbucks01.jpg b/htdocs/imacat/images/baden/starbucks01.jpg new file mode 100644 index 0000000..3b857cd Binary files /dev/null and b/htdocs/imacat/images/baden/starbucks01.jpg differ diff --git a/htdocs/imacat/images/baden/starbucks02.jpg b/htdocs/imacat/images/baden/starbucks02.jpg new file mode 100644 index 0000000..fd092b0 Binary files /dev/null and b/htdocs/imacat/images/baden/starbucks02.jpg differ diff --git a/htdocs/imacat/images/battery_belt.jpg b/htdocs/imacat/images/battery_belt.jpg new file mode 100644 index 0000000..a13ea09 Binary files /dev/null and b/htdocs/imacat/images/battery_belt.jpg differ diff --git a/htdocs/imacat/images/bg_bedsheet.gif b/htdocs/imacat/images/bg_bedsheet.gif new file mode 100644 index 0000000..1524908 Binary files /dev/null and b/htdocs/imacat/images/bg_bedsheet.gif differ diff --git a/htdocs/imacat/images/bg_bricks.gif b/htdocs/imacat/images/bg_bricks.gif new file mode 100644 index 0000000..e7d576d Binary files /dev/null and b/htdocs/imacat/images/bg_bricks.gif differ diff --git a/htdocs/imacat/images/bg_cloth.gif b/htdocs/imacat/images/bg_cloth.gif new file mode 100644 index 0000000..a9ba52e Binary files /dev/null and b/htdocs/imacat/images/bg_cloth.gif differ diff --git a/htdocs/imacat/images/bg_coconut.png b/htdocs/imacat/images/bg_coconut.png new file mode 100644 index 0000000..7b287f8 Binary files /dev/null and b/htdocs/imacat/images/bg_coconut.png differ diff --git a/htdocs/imacat/images/bg_linen.gif b/htdocs/imacat/images/bg_linen.gif new file mode 100644 index 0000000..f7da3d1 Binary files /dev/null and b/htdocs/imacat/images/bg_linen.gif differ diff --git a/htdocs/imacat/images/bg_linux.gif b/htdocs/imacat/images/bg_linux.gif new file mode 100644 index 0000000..8e003ca Binary files /dev/null and b/htdocs/imacat/images/bg_linux.gif differ diff --git a/htdocs/imacat/images/bg_linux.jpg b/htdocs/imacat/images/bg_linux.jpg new file mode 100644 index 0000000..0ad5027 Binary files /dev/null and b/htdocs/imacat/images/bg_linux.jpg differ diff --git a/htdocs/imacat/images/bg_marble.gif b/htdocs/imacat/images/bg_marble.gif new file mode 100644 index 0000000..eb3a12a Binary files /dev/null and b/htdocs/imacat/images/bg_marble.gif differ diff --git a/htdocs/imacat/images/bg_newyear.gif b/htdocs/imacat/images/bg_newyear.gif new file mode 100644 index 0000000..b030590 Binary files /dev/null and b/htdocs/imacat/images/bg_newyear.gif differ diff --git a/htdocs/imacat/images/bg_pink_triangle.gif b/htdocs/imacat/images/bg_pink_triangle.gif new file mode 100644 index 0000000..244d664 Binary files /dev/null and b/htdocs/imacat/images/bg_pink_triangle.gif differ diff --git a/htdocs/imacat/images/bg_redbricks.gif b/htdocs/imacat/images/bg_redbricks.gif new file mode 100644 index 0000000..370533d Binary files /dev/null and b/htdocs/imacat/images/bg_redbricks.gif differ diff --git a/htdocs/imacat/images/bg_sex.jpg b/htdocs/imacat/images/bg_sex.jpg new file mode 100644 index 0000000..9dfb1a8 Binary files /dev/null and b/htdocs/imacat/images/bg_sex.jpg differ diff --git a/htdocs/imacat/images/button.png b/htdocs/imacat/images/button.png new file mode 100644 index 0000000..12939a0 Binary files /dev/null and b/htdocs/imacat/images/button.png differ diff --git a/htdocs/imacat/images/c2zoom.jpg b/htdocs/imacat/images/c2zoom.jpg new file mode 100644 index 0000000..64cd5bc Binary files /dev/null and b/htdocs/imacat/images/c2zoom.jpg differ diff --git a/htdocs/imacat/images/cat_licks.gif b/htdocs/imacat/images/cat_licks.gif new file mode 100644 index 0000000..bad1cca Binary files /dev/null and b/htdocs/imacat/images/cat_licks.gif differ diff --git a/htdocs/imacat/images/chian01.jpg b/htdocs/imacat/images/chian01.jpg new file mode 100644 index 0000000..845b28e Binary files /dev/null and b/htdocs/imacat/images/chian01.jpg differ diff --git a/htdocs/imacat/images/chian02.jpg b/htdocs/imacat/images/chian02.jpg new file mode 100644 index 0000000..0802347 Binary files /dev/null and b/htdocs/imacat/images/chian02.jpg differ diff --git a/htdocs/imacat/images/cj7_kfc01.jpg b/htdocs/imacat/images/cj7_kfc01.jpg new file mode 100644 index 0000000..f4abd00 Binary files /dev/null and b/htdocs/imacat/images/cj7_kfc01.jpg differ diff --git a/htdocs/imacat/images/cj7_kfc02.jpg b/htdocs/imacat/images/cj7_kfc02.jpg new file mode 100644 index 0000000..fc90417 Binary files /dev/null and b/htdocs/imacat/images/cj7_kfc02.jpg differ diff --git a/htdocs/imacat/images/cj7_kfc03.jpg b/htdocs/imacat/images/cj7_kfc03.jpg new file mode 100644 index 0000000..4c2bbba Binary files /dev/null and b/htdocs/imacat/images/cj7_kfc03.jpg differ diff --git a/htdocs/imacat/images/cj7_kfc04.jpg b/htdocs/imacat/images/cj7_kfc04.jpg new file mode 100644 index 0000000..226223d Binary files /dev/null and b/htdocs/imacat/images/cj7_kfc04.jpg differ diff --git a/htdocs/imacat/images/cj7_kfcall.jpg b/htdocs/imacat/images/cj7_kfcall.jpg new file mode 100644 index 0000000..ddb1513 Binary files /dev/null and b/htdocs/imacat/images/cj7_kfcall.jpg differ diff --git a/htdocs/imacat/images/cococrab.png b/htdocs/imacat/images/cococrab.png new file mode 100644 index 0000000..2097e33 Binary files /dev/null and b/htdocs/imacat/images/cococrab.png differ diff --git a/htdocs/imacat/images/coconut2.png b/htdocs/imacat/images/coconut2.png new file mode 100644 index 0000000..1235a47 Binary files /dev/null and b/htdocs/imacat/images/coconut2.png differ diff --git a/htdocs/imacat/images/coconut3.png b/htdocs/imacat/images/coconut3.png new file mode 100644 index 0000000..eaf5c4f Binary files /dev/null and b/htdocs/imacat/images/coconut3.png differ diff --git a/htdocs/imacat/images/core2fan.png b/htdocs/imacat/images/core2fan.png new file mode 100644 index 0000000..3fa67f4 Binary files /dev/null and b/htdocs/imacat/images/core2fan.png differ diff --git a/htdocs/imacat/images/core2temp.png b/htdocs/imacat/images/core2temp.png new file mode 100644 index 0000000..6530299 Binary files /dev/null and b/htdocs/imacat/images/core2temp.png differ diff --git a/htdocs/imacat/images/cosic_xmas_maid.png b/htdocs/imacat/images/cosic_xmas_maid.png new file mode 100644 index 0000000..62482c4 Binary files /dev/null and b/htdocs/imacat/images/cosic_xmas_maid.png differ diff --git a/htdocs/imacat/images/courtney_love.jpg b/htdocs/imacat/images/courtney_love.jpg new file mode 100644 index 0000000..82eb948 Binary files /dev/null and b/htdocs/imacat/images/courtney_love.jpg differ diff --git a/htdocs/imacat/images/cv.jpg b/htdocs/imacat/images/cv.jpg new file mode 100644 index 0000000..1228e0a Binary files /dev/null and b/htdocs/imacat/images/cv.jpg differ diff --git a/htdocs/imacat/images/dc-2110a.jpg b/htdocs/imacat/images/dc-2110a.jpg new file mode 100644 index 0000000..3b2b449 Binary files /dev/null and b/htdocs/imacat/images/dc-2110a.jpg differ diff --git a/htdocs/imacat/images/deserteagle.jpg b/htdocs/imacat/images/deserteagle.jpg new file mode 100644 index 0000000..6f48bfc Binary files /dev/null and b/htdocs/imacat/images/deserteagle.jpg differ diff --git a/htdocs/imacat/images/dscn2887-1.jpg b/htdocs/imacat/images/dscn2887-1.jpg new file mode 100644 index 0000000..4b92a52 Binary files /dev/null and b/htdocs/imacat/images/dscn2887-1.jpg differ diff --git a/htdocs/imacat/images/email.gif b/htdocs/imacat/images/email.gif new file mode 100644 index 0000000..165ff04 Binary files /dev/null and b/htdocs/imacat/images/email.gif differ diff --git a/htdocs/imacat/images/email.png b/htdocs/imacat/images/email.png new file mode 100644 index 0000000..965fdac Binary files /dev/null and b/htdocs/imacat/images/email.png differ diff --git a/htdocs/imacat/images/emily.png b/htdocs/imacat/images/emily.png new file mode 100644 index 0000000..e84c446 Binary files /dev/null and b/htdocs/imacat/images/emily.png differ diff --git a/htdocs/imacat/images/flashver.fla b/htdocs/imacat/images/flashver.fla new file mode 100644 index 0000000..2d90d1c Binary files /dev/null and b/htdocs/imacat/images/flashver.fla differ diff --git a/htdocs/imacat/images/flashver.swf b/htdocs/imacat/images/flashver.swf new file mode 100644 index 0000000..82287ab Binary files /dev/null and b/htdocs/imacat/images/flashver.swf differ diff --git a/htdocs/imacat/images/fuhow_statue.jpg b/htdocs/imacat/images/fuhow_statue.jpg new file mode 100644 index 0000000..f66ca42 Binary files /dev/null and b/htdocs/imacat/images/fuhow_statue.jpg differ diff --git a/htdocs/imacat/images/fuhow_yue.jpg b/htdocs/imacat/images/fuhow_yue.jpg new file mode 100644 index 0000000..5ab99c2 Binary files /dev/null and b/htdocs/imacat/images/fuhow_yue.jpg differ diff --git a/htdocs/imacat/images/game.gif b/htdocs/imacat/images/game.gif new file mode 100644 index 0000000..365af8c Binary files /dev/null and b/htdocs/imacat/images/game.gif differ diff --git a/htdocs/imacat/images/hppsc1510.jpg b/htdocs/imacat/images/hppsc1510.jpg new file mode 100644 index 0000000..0e2cd55 Binary files /dev/null and b/htdocs/imacat/images/hppsc1510.jpg differ diff --git a/htdocs/imacat/images/hsou.jpg b/htdocs/imacat/images/hsou.jpg new file mode 100644 index 0000000..2102bdb Binary files /dev/null and b/htdocs/imacat/images/hsou.jpg differ diff --git a/htdocs/imacat/images/icon.gif b/htdocs/imacat/images/icon.gif new file mode 100644 index 0000000..d495c34 Binary files /dev/null and b/htdocs/imacat/images/icon.gif differ diff --git a/htdocs/imacat/images/icon.png b/htdocs/imacat/images/icon.png new file mode 100644 index 0000000..66b3a85 Binary files /dev/null and b/htdocs/imacat/images/icon.png differ diff --git a/htdocs/imacat/images/iconani.gif b/htdocs/imacat/images/iconani.gif new file mode 100644 index 0000000..86114a4 Binary files /dev/null and b/htdocs/imacat/images/iconani.gif differ diff --git a/htdocs/imacat/images/icons.jpg b/htdocs/imacat/images/icons.jpg new file mode 100644 index 0000000..2555465 Binary files /dev/null and b/htdocs/imacat/images/icons.jpg differ diff --git a/htdocs/imacat/images/img_8105-1.jpg b/htdocs/imacat/images/img_8105-1.jpg new file mode 100644 index 0000000..b845230 Binary files /dev/null and b/htdocs/imacat/images/img_8105-1.jpg differ diff --git a/htdocs/imacat/images/joyce.jpg b/htdocs/imacat/images/joyce.jpg new file mode 100644 index 0000000..d81d1f3 Binary files /dev/null and b/htdocs/imacat/images/joyce.jpg differ diff --git a/htdocs/imacat/images/linux.png b/htdocs/imacat/images/linux.png new file mode 100644 index 0000000..1b3832f Binary files /dev/null and b/htdocs/imacat/images/linux.png differ diff --git a/htdocs/imacat/images/logo.png b/htdocs/imacat/images/logo.png new file mode 100644 index 0000000..41513dd Binary files /dev/null and b/htdocs/imacat/images/logo.png differ diff --git a/htdocs/imacat/images/logo_small.png b/htdocs/imacat/images/logo_small.png new file mode 100644 index 0000000..5b385e3 Binary files /dev/null and b/htdocs/imacat/images/logo_small.png differ diff --git a/htdocs/imacat/images/logos/analog.png b/htdocs/imacat/images/logos/analog.png new file mode 100644 index 0000000..8e92147 Binary files /dev/null and b/htdocs/imacat/images/logos/analog.png differ diff --git a/htdocs/imacat/images/logos/apache.png b/htdocs/imacat/images/logos/apache.png new file mode 100644 index 0000000..2e2e117 Binary files /dev/null and b/htdocs/imacat/images/logos/apache.png differ diff --git a/htdocs/imacat/images/logos/br.png b/htdocs/imacat/images/logos/br.png new file mode 100644 index 0000000..6fbf8f6 Binary files /dev/null and b/htdocs/imacat/images/logos/br.png differ diff --git a/htdocs/imacat/images/logos/cpan.jpg b/htdocs/imacat/images/logos/cpan.jpg new file mode 100644 index 0000000..d5c29c1 Binary files /dev/null and b/htdocs/imacat/images/logos/cpan.jpg differ diff --git a/htdocs/imacat/images/logos/debian.png b/htdocs/imacat/images/logos/debian.png new file mode 100644 index 0000000..14878be Binary files /dev/null and b/htdocs/imacat/images/logos/debian.png differ diff --git a/htdocs/imacat/images/logos/gif/apache.gif b/htdocs/imacat/images/logos/gif/apache.gif new file mode 100644 index 0000000..6fd80e2 Binary files /dev/null and b/htdocs/imacat/images/logos/gif/apache.gif differ diff --git a/htdocs/imacat/images/logos/gif/java-blue.gif b/htdocs/imacat/images/logos/gif/java-blue.gif new file mode 100644 index 0000000..10a90b7 Binary files /dev/null and b/htdocs/imacat/images/logos/gif/java-blue.gif differ diff --git a/htdocs/imacat/images/logos/gif/java-green.gif b/htdocs/imacat/images/logos/gif/java-green.gif new file mode 100644 index 0000000..a5a44ad Binary files /dev/null and b/htdocs/imacat/images/logos/gif/java-green.gif differ diff --git a/htdocs/imacat/images/logos/gif/java-red.gif b/htdocs/imacat/images/logos/gif/java-red.gif new file mode 100644 index 0000000..a3f6487 Binary files /dev/null and b/htdocs/imacat/images/logos/gif/java-red.gif differ diff --git a/htdocs/imacat/images/logos/gif/modssl.gif b/htdocs/imacat/images/logos/gif/modssl.gif new file mode 100644 index 0000000..aecd3c1 Binary files /dev/null and b/htdocs/imacat/images/logos/gif/modssl.gif differ diff --git a/htdocs/imacat/images/logos/gif/netscape.gif b/htdocs/imacat/images/logos/gif/netscape.gif new file mode 100644 index 0000000..fc95fe0 Binary files /dev/null and b/htdocs/imacat/images/logos/gif/netscape.gif differ diff --git a/htdocs/imacat/images/logos/gif/openssl.gif b/htdocs/imacat/images/logos/gif/openssl.gif new file mode 100644 index 0000000..3d3c90c Binary files /dev/null and b/htdocs/imacat/images/logos/gif/openssl.gif differ diff --git a/htdocs/imacat/images/logos/gif/python.gif b/htdocs/imacat/images/logos/gif/python.gif new file mode 100644 index 0000000..34e774c Binary files /dev/null and b/htdocs/imacat/images/logos/gif/python.gif differ diff --git a/htdocs/imacat/images/logos/gif/redhat.gif b/htdocs/imacat/images/logos/gif/redhat.gif new file mode 100644 index 0000000..78f4513 Binary files /dev/null and b/htdocs/imacat/images/logos/gif/redhat.gif differ diff --git a/htdocs/imacat/images/logos/gif/sendmail.gif b/htdocs/imacat/images/logos/gif/sendmail.gif new file mode 100644 index 0000000..aa3b7c4 Binary files /dev/null and b/htdocs/imacat/images/logos/gif/sendmail.gif differ diff --git a/htdocs/imacat/images/logos/gif/ultraedit.gif b/htdocs/imacat/images/logos/gif/ultraedit.gif new file mode 100644 index 0000000..bcc705f Binary files /dev/null and b/htdocs/imacat/images/logos/gif/ultraedit.gif differ diff --git a/htdocs/imacat/images/logos/java-blue.png b/htdocs/imacat/images/logos/java-blue.png new file mode 100644 index 0000000..8539420 Binary files /dev/null and b/htdocs/imacat/images/logos/java-blue.png differ diff --git a/htdocs/imacat/images/logos/java-green.png b/htdocs/imacat/images/logos/java-green.png new file mode 100644 index 0000000..8bead5e Binary files /dev/null and b/htdocs/imacat/images/logos/java-green.png differ diff --git a/htdocs/imacat/images/logos/java-red.png b/htdocs/imacat/images/logos/java-red.png new file mode 100644 index 0000000..e31b06a Binary files /dev/null and b/htdocs/imacat/images/logos/java-red.png differ diff --git a/htdocs/imacat/images/logos/linux24.png b/htdocs/imacat/images/logos/linux24.png new file mode 100644 index 0000000..578e323 Binary files /dev/null and b/htdocs/imacat/images/logos/linux24.png differ diff --git a/htdocs/imacat/images/logos/mailman.jpg b/htdocs/imacat/images/logos/mailman.jpg new file mode 100644 index 0000000..94a4c01 Binary files /dev/null and b/htdocs/imacat/images/logos/mailman.jpg differ diff --git a/htdocs/imacat/images/logos/modperl.png b/htdocs/imacat/images/logos/modperl.png new file mode 100644 index 0000000..9c295b0 Binary files /dev/null and b/htdocs/imacat/images/logos/modperl.png differ diff --git a/htdocs/imacat/images/logos/modssl.png b/htdocs/imacat/images/logos/modssl.png new file mode 100644 index 0000000..93999d7 Binary files /dev/null and b/htdocs/imacat/images/logos/modssl.png differ diff --git a/htdocs/imacat/images/logos/netscape.png b/htdocs/imacat/images/logos/netscape.png new file mode 100644 index 0000000..d638aa9 Binary files /dev/null and b/htdocs/imacat/images/logos/netscape.png differ diff --git a/htdocs/imacat/images/logos/openssl.png b/htdocs/imacat/images/logos/openssl.png new file mode 100644 index 0000000..efce43b Binary files /dev/null and b/htdocs/imacat/images/logos/openssl.png differ diff --git a/htdocs/imacat/images/logos/pure-ftpd.png b/htdocs/imacat/images/logos/pure-ftpd.png new file mode 100644 index 0000000..6e170bc Binary files /dev/null and b/htdocs/imacat/images/logos/pure-ftpd.png differ diff --git a/htdocs/imacat/images/logos/pureftpd.jpg b/htdocs/imacat/images/logos/pureftpd.jpg new file mode 100644 index 0000000..c1531ad Binary files /dev/null and b/htdocs/imacat/images/logos/pureftpd.jpg differ diff --git a/htdocs/imacat/images/logos/python.png b/htdocs/imacat/images/logos/python.png new file mode 100644 index 0000000..0519b75 Binary files /dev/null and b/htdocs/imacat/images/logos/python.png differ diff --git a/htdocs/imacat/images/logos/redhat.png b/htdocs/imacat/images/logos/redhat.png new file mode 100644 index 0000000..809822f Binary files /dev/null and b/htdocs/imacat/images/logos/redhat.png differ diff --git a/htdocs/imacat/images/logos/sendmail.png b/htdocs/imacat/images/logos/sendmail.png new file mode 100644 index 0000000..283301f Binary files /dev/null and b/htdocs/imacat/images/logos/sendmail.png differ diff --git a/htdocs/imacat/images/logos/sflogo.png b/htdocs/imacat/images/logos/sflogo.png new file mode 100644 index 0000000..b2a9e99 Binary files /dev/null and b/htdocs/imacat/images/logos/sflogo.png differ diff --git a/htdocs/imacat/images/logos/ultraedit.png b/htdocs/imacat/images/logos/ultraedit.png new file mode 100644 index 0000000..f1c691e Binary files /dev/null and b/htdocs/imacat/images/logos/ultraedit.png differ diff --git a/htdocs/imacat/images/me.gif b/htdocs/imacat/images/me.gif new file mode 100644 index 0000000..c46ecc8 Binary files /dev/null and b/htdocs/imacat/images/me.gif differ diff --git a/htdocs/imacat/images/me.jpg b/htdocs/imacat/images/me.jpg new file mode 100644 index 0000000..bdd68ae Binary files /dev/null and b/htdocs/imacat/images/me.jpg differ diff --git a/htdocs/imacat/images/me.png b/htdocs/imacat/images/me.png new file mode 100644 index 0000000..c42601d Binary files /dev/null and b/htdocs/imacat/images/me.png differ diff --git a/htdocs/imacat/images/me_phpBB.png b/htdocs/imacat/images/me_phpBB.png new file mode 100644 index 0000000..bec7cae Binary files /dev/null and b/htdocs/imacat/images/me_phpBB.png differ diff --git a/htdocs/imacat/images/modperl.png b/htdocs/imacat/images/modperl.png new file mode 100644 index 0000000..9c295b0 Binary files /dev/null and b/htdocs/imacat/images/modperl.png differ diff --git a/htdocs/imacat/images/movies/300.jpg b/htdocs/imacat/images/movies/300.jpg new file mode 100644 index 0000000..7433072 Binary files /dev/null and b/htdocs/imacat/images/movies/300.jpg differ diff --git a/htdocs/imacat/images/movies/aeon_flux.jpg b/htdocs/imacat/images/movies/aeon_flux.jpg new file mode 100644 index 0000000..80ee5dd Binary files /dev/null and b/htdocs/imacat/images/movies/aeon_flux.jpg differ diff --git a/htdocs/imacat/images/movies/aeon_flux_comic.jpg b/htdocs/imacat/images/movies/aeon_flux_comic.jpg new file mode 100644 index 0000000..fd24bd3 Binary files /dev/null and b/htdocs/imacat/images/movies/aeon_flux_comic.jpg differ diff --git a/htdocs/imacat/images/movies/blade.jpg b/htdocs/imacat/images/movies/blade.jpg new file mode 100644 index 0000000..3e28a38 Binary files /dev/null and b/htdocs/imacat/images/movies/blade.jpg differ diff --git a/htdocs/imacat/images/movies/blade_2.jpg b/htdocs/imacat/images/movies/blade_2.jpg new file mode 100644 index 0000000..fcf4e62 Binary files /dev/null and b/htdocs/imacat/images/movies/blade_2.jpg differ diff --git a/htdocs/imacat/images/movies/blade_trinity.jpg b/htdocs/imacat/images/movies/blade_trinity.jpg new file mode 100644 index 0000000..b17e8dd Binary files /dev/null and b/htdocs/imacat/images/movies/blade_trinity.jpg differ diff --git a/htdocs/imacat/images/movies/casino.jpg b/htdocs/imacat/images/movies/casino.jpg new file mode 100644 index 0000000..e46a6e2 Binary files /dev/null and b/htdocs/imacat/images/movies/casino.jpg differ diff --git a/htdocs/imacat/images/movies/catch.jpg b/htdocs/imacat/images/movies/catch.jpg new file mode 100644 index 0000000..0471cab Binary files /dev/null and b/htdocs/imacat/images/movies/catch.jpg differ diff --git a/htdocs/imacat/images/movies/election2.jpg b/htdocs/imacat/images/movies/election2.jpg new file mode 100644 index 0000000..a952b09 Binary files /dev/null and b/htdocs/imacat/images/movies/election2.jpg differ diff --git a/htdocs/imacat/images/movies/fun_with_dick_and_jane.jpg b/htdocs/imacat/images/movies/fun_with_dick_and_jane.jpg new file mode 100644 index 0000000..2607b6f Binary files /dev/null and b/htdocs/imacat/images/movies/fun_with_dick_and_jane.jpg differ diff --git a/htdocs/imacat/images/movies/ip_man.jpg b/htdocs/imacat/images/movies/ip_man.jpg new file mode 100644 index 0000000..aa2717f Binary files /dev/null and b/htdocs/imacat/images/movies/ip_man.jpg differ diff --git a/htdocs/imacat/images/movies/kamikaze_girls.jpg b/htdocs/imacat/images/movies/kamikaze_girls.jpg new file mode 100644 index 0000000..8ee373f Binary files /dev/null and b/htdocs/imacat/images/movies/kamikaze_girls.jpg differ diff --git a/htdocs/imacat/images/movies/kill_bill_vol.1.jpg b/htdocs/imacat/images/movies/kill_bill_vol.1.jpg new file mode 100644 index 0000000..9f31c7b Binary files /dev/null and b/htdocs/imacat/images/movies/kill_bill_vol.1.jpg differ diff --git a/htdocs/imacat/images/movies/kill_bill_vol.2.jpg b/htdocs/imacat/images/movies/kill_bill_vol.2.jpg new file mode 100644 index 0000000..26650e7 Binary files /dev/null and b/htdocs/imacat/images/movies/kill_bill_vol.2.jpg differ diff --git a/htdocs/imacat/images/movies/king_kong_2005.jpg b/htdocs/imacat/images/movies/king_kong_2005.jpg new file mode 100644 index 0000000..0da57a7 Binary files /dev/null and b/htdocs/imacat/images/movies/king_kong_2005.jpg differ diff --git a/htdocs/imacat/images/movies/last_quarter.jpg b/htdocs/imacat/images/movies/last_quarter.jpg new file mode 100644 index 0000000..8db2ea1 Binary files /dev/null and b/htdocs/imacat/images/movies/last_quarter.jpg differ diff --git a/htdocs/imacat/images/movies/long_arm_of_the_law.jpg b/htdocs/imacat/images/movies/long_arm_of_the_law.jpg new file mode 100644 index 0000000..ade5071 Binary files /dev/null and b/htdocs/imacat/images/movies/long_arm_of_the_law.jpg differ diff --git a/htdocs/imacat/images/movies/long_arm_of_the_law_2.jpg b/htdocs/imacat/images/movies/long_arm_of_the_law_2.jpg new file mode 100644 index 0000000..adc4753 Binary files /dev/null and b/htdocs/imacat/images/movies/long_arm_of_the_law_2.jpg differ diff --git a/htdocs/imacat/images/movies/long_arm_of_the_law_3.jpg b/htdocs/imacat/images/movies/long_arm_of_the_law_3.jpg new file mode 100644 index 0000000..9ff42fb Binary files /dev/null and b/htdocs/imacat/images/movies/long_arm_of_the_law_3.jpg differ diff --git a/htdocs/imacat/images/movies/maximum_velocity.jpg b/htdocs/imacat/images/movies/maximum_velocity.jpg new file mode 100644 index 0000000..edce590 Binary files /dev/null and b/htdocs/imacat/images/movies/maximum_velocity.jpg differ diff --git a/htdocs/imacat/images/movies/milk.jpg b/htdocs/imacat/images/movies/milk.jpg new file mode 100644 index 0000000..7cc2506 Binary files /dev/null and b/htdocs/imacat/images/movies/milk.jpg differ diff --git a/htdocs/imacat/images/movies/mr_and_mrs_smith.jpg b/htdocs/imacat/images/movies/mr_and_mrs_smith.jpg new file mode 100644 index 0000000..8ddc33a Binary files /dev/null and b/htdocs/imacat/images/movies/mr_and_mrs_smith.jpg differ diff --git a/htdocs/imacat/images/movies/north_country.jpg b/htdocs/imacat/images/movies/north_country.jpg new file mode 100644 index 0000000..64a3544 Binary files /dev/null and b/htdocs/imacat/images/movies/north_country.jpg differ diff --git a/htdocs/imacat/images/movies/ponyo.jpg b/htdocs/imacat/images/movies/ponyo.jpg new file mode 100644 index 0000000..3f01dc8 Binary files /dev/null and b/htdocs/imacat/images/movies/ponyo.jpg differ diff --git a/htdocs/imacat/images/movies/resident_evil_degeneration.jpg b/htdocs/imacat/images/movies/resident_evil_degeneration.jpg new file mode 100644 index 0000000..26fb6fb Binary files /dev/null and b/htdocs/imacat/images/movies/resident_evil_degeneration.jpg differ diff --git a/htdocs/imacat/images/movies/running_out_of_time.jpg b/htdocs/imacat/images/movies/running_out_of_time.jpg new file mode 100644 index 0000000..294fbc1 Binary files /dev/null and b/htdocs/imacat/images/movies/running_out_of_time.jpg differ diff --git a/htdocs/imacat/images/movies/running_out_of_time_2.jpg b/htdocs/imacat/images/movies/running_out_of_time_2.jpg new file mode 100644 index 0000000..c4fe585 Binary files /dev/null and b/htdocs/imacat/images/movies/running_out_of_time_2.jpg differ diff --git a/htdocs/imacat/images/movies/shortbus.jpg b/htdocs/imacat/images/movies/shortbus.jpg new file mode 100644 index 0000000..eb8450d Binary files /dev/null and b/htdocs/imacat/images/movies/shortbus.jpg differ diff --git a/htdocs/imacat/images/movies/sid_and_nancy.jpg b/htdocs/imacat/images/movies/sid_and_nancy.jpg new file mode 100644 index 0000000..89cba6c Binary files /dev/null and b/htdocs/imacat/images/movies/sid_and_nancy.jpg differ diff --git a/htdocs/imacat/images/movies/slumdog_millionaire.jpg b/htdocs/imacat/images/movies/slumdog_millionaire.jpg new file mode 100644 index 0000000..dff4376 Binary files /dev/null and b/htdocs/imacat/images/movies/slumdog_millionaire.jpg differ diff --git a/htdocs/imacat/images/movies/spl.jpg b/htdocs/imacat/images/movies/spl.jpg new file mode 100644 index 0000000..3bf7a97 Binary files /dev/null and b/htdocs/imacat/images/movies/spl.jpg differ diff --git a/htdocs/imacat/images/movies/strategy_above_the_death.jpg b/htdocs/imacat/images/movies/strategy_above_the_death.jpg new file mode 100644 index 0000000..1aabd96 Binary files /dev/null and b/htdocs/imacat/images/movies/strategy_above_the_death.jpg differ diff --git a/htdocs/imacat/images/movies/the_hk_triad.jpg b/htdocs/imacat/images/movies/the_hk_triad.jpg new file mode 100644 index 0000000..6c0c675 Binary files /dev/null and b/htdocs/imacat/images/movies/the_hk_triad.jpg differ diff --git a/htdocs/imacat/images/movies/the_kids_are_all_right.jpg b/htdocs/imacat/images/movies/the_kids_are_all_right.jpg new file mode 100644 index 0000000..12b7c6c Binary files /dev/null and b/htdocs/imacat/images/movies/the_kids_are_all_right.jpg differ diff --git a/htdocs/imacat/images/movies/the_longest_nite.jpg b/htdocs/imacat/images/movies/the_longest_nite.jpg new file mode 100644 index 0000000..22c9e7b Binary files /dev/null and b/htdocs/imacat/images/movies/the_longest_nite.jpg differ diff --git a/htdocs/imacat/images/movies/the_mission.jpg b/htdocs/imacat/images/movies/the_mission.jpg new file mode 100644 index 0000000..9797d26 Binary files /dev/null and b/htdocs/imacat/images/movies/the_mission.jpg differ diff --git a/htdocs/imacat/images/movies/the_private_eyes_requiem.jpg b/htdocs/imacat/images/movies/the_private_eyes_requiem.jpg new file mode 100644 index 0000000..66b601d Binary files /dev/null and b/htdocs/imacat/images/movies/the_private_eyes_requiem.jpg differ diff --git a/htdocs/imacat/images/movies/the_storm_warriors.jpg b/htdocs/imacat/images/movies/the_storm_warriors.jpg new file mode 100644 index 0000000..21218c1 Binary files /dev/null and b/htdocs/imacat/images/movies/the_storm_warriors.jpg differ diff --git a/htdocs/imacat/images/movies/the_warlords.jpg b/htdocs/imacat/images/movies/the_warlords.jpg new file mode 100644 index 0000000..f2a9bbb Binary files /dev/null and b/htdocs/imacat/images/movies/the_warlords.jpg differ diff --git a/htdocs/imacat/images/movies/the_wayward_cloud.jpg b/htdocs/imacat/images/movies/the_wayward_cloud.jpg new file mode 100644 index 0000000..f113dc6 Binary files /dev/null and b/htdocs/imacat/images/movies/the_wayward_cloud.jpg differ diff --git a/htdocs/imacat/images/movies/three_times.jpg b/htdocs/imacat/images/movies/three_times.jpg new file mode 100644 index 0000000..0dccfd6 Binary files /dev/null and b/htdocs/imacat/images/movies/three_times.jpg differ diff --git a/htdocs/imacat/images/movies/too_many_ways_to_be_no.1.jpg b/htdocs/imacat/images/movies/too_many_ways_to_be_no.1.jpg new file mode 100644 index 0000000..49028af Binary files /dev/null and b/htdocs/imacat/images/movies/too_many_ways_to_be_no.1.jpg differ diff --git a/htdocs/imacat/images/movies/touch.jpg b/htdocs/imacat/images/movies/touch.jpg new file mode 100644 index 0000000..cd86e53 Binary files /dev/null and b/htdocs/imacat/images/movies/touch.jpg differ diff --git a/htdocs/imacat/images/movies/transformers.jpg b/htdocs/imacat/images/movies/transformers.jpg new file mode 100644 index 0000000..d8bfc72 Binary files /dev/null and b/htdocs/imacat/images/movies/transformers.jpg differ diff --git a/htdocs/imacat/images/movies/ultraviolet.jpg b/htdocs/imacat/images/movies/ultraviolet.jpg new file mode 100644 index 0000000..2d20f59 Binary files /dev/null and b/htdocs/imacat/images/movies/ultraviolet.jpg differ diff --git a/htdocs/imacat/images/movies/underground_express.jpg b/htdocs/imacat/images/movies/underground_express.jpg new file mode 100644 index 0000000..a35580b Binary files /dev/null and b/htdocs/imacat/images/movies/underground_express.jpg differ diff --git a/htdocs/imacat/images/movies/underworld.jpg b/htdocs/imacat/images/movies/underworld.jpg new file mode 100644 index 0000000..1691e7a Binary files /dev/null and b/htdocs/imacat/images/movies/underworld.jpg differ diff --git a/htdocs/imacat/images/movies/underworld_evolution.jpg b/htdocs/imacat/images/movies/underworld_evolution.jpg new file mode 100644 index 0000000..a189abc Binary files /dev/null and b/htdocs/imacat/images/movies/underworld_evolution.jpg differ diff --git a/htdocs/imacat/images/movies/volcano_high.jpg b/htdocs/imacat/images/movies/volcano_high.jpg new file mode 100644 index 0000000..8bdaa03 Binary files /dev/null and b/htdocs/imacat/images/movies/volcano_high.jpg differ diff --git a/htdocs/imacat/images/movies/x_men_the_last_stand.jpg b/htdocs/imacat/images/movies/x_men_the_last_stand.jpg new file mode 100644 index 0000000..5022540 Binary files /dev/null and b/htdocs/imacat/images/movies/x_men_the_last_stand.jpg differ diff --git a/htdocs/imacat/images/nana/7.8.jpg b/htdocs/imacat/images/nana/7.8.jpg new file mode 100644 index 0000000..882ebda Binary files /dev/null and b/htdocs/imacat/images/nana/7.8.jpg differ diff --git a/htdocs/imacat/images/nana/9.jpg b/htdocs/imacat/images/nana/9.jpg new file mode 100644 index 0000000..9017618 Binary files /dev/null and b/htdocs/imacat/images/nana/9.jpg differ diff --git a/htdocs/imacat/images/nana/honjo_ren.jpg b/htdocs/imacat/images/nana/honjo_ren.jpg new file mode 100644 index 0000000..4e2da05 Binary files /dev/null and b/htdocs/imacat/images/nana/honjo_ren.jpg differ diff --git a/htdocs/imacat/images/nana/jackson_hole_comic.jpg b/htdocs/imacat/images/nana/jackson_hole_comic.jpg new file mode 100644 index 0000000..adcf2fa Binary files /dev/null and b/htdocs/imacat/images/nana/jackson_hole_comic.jpg differ diff --git a/htdocs/imacat/images/nana/jackson_hole_real.jpg b/htdocs/imacat/images/nana/jackson_hole_real.jpg new file mode 100644 index 0000000..95a7180 Binary files /dev/null and b/htdocs/imacat/images/nana/jackson_hole_real.jpg differ diff --git a/htdocs/imacat/images/nana/kawamura_sachiko.jpg b/htdocs/imacat/images/nana/kawamura_sachiko.jpg new file mode 100644 index 0000000..55164ed Binary files /dev/null and b/htdocs/imacat/images/nana/kawamura_sachiko.jpg differ diff --git a/htdocs/imacat/images/nana/love_blast.jpg b/htdocs/imacat/images/nana/love_blast.jpg new file mode 100644 index 0000000..5a37dcf Binary files /dev/null and b/htdocs/imacat/images/nana/love_blast.jpg differ diff --git a/htdocs/imacat/images/nana/love_trapnest.jpg b/htdocs/imacat/images/nana/love_trapnest.jpg new file mode 100644 index 0000000..9dc173c Binary files /dev/null and b/htdocs/imacat/images/nana/love_trapnest.jpg differ diff --git a/htdocs/imacat/images/nana/movie.jpg b/htdocs/imacat/images/nana/movie.jpg new file mode 100644 index 0000000..03730a3 Binary files /dev/null and b/htdocs/imacat/images/nana/movie.jpg differ diff --git a/htdocs/imacat/images/nana/movie_2.jpg b/htdocs/imacat/images/nana/movie_2.jpg new file mode 100644 index 0000000..0089e70 Binary files /dev/null and b/htdocs/imacat/images/nana/movie_2.jpg differ diff --git a/htdocs/imacat/images/nana/nana_tsuchiya_anna.jpg b/htdocs/imacat/images/nana/nana_tsuchiya_anna.jpg new file mode 100644 index 0000000..df71531 Binary files /dev/null and b/htdocs/imacat/images/nana/nana_tsuchiya_anna.jpg differ diff --git a/htdocs/imacat/images/nana/nancy_sid.jpg b/htdocs/imacat/images/nana/nancy_sid.jpg new file mode 100644 index 0000000..372523a Binary files /dev/null and b/htdocs/imacat/images/nana/nancy_sid.jpg differ diff --git a/htdocs/imacat/images/nana/ps2.jpg b/htdocs/imacat/images/nana/ps2.jpg new file mode 100644 index 0000000..ebb5b04 Binary files /dev/null and b/htdocs/imacat/images/nana/ps2.jpg differ diff --git a/htdocs/imacat/images/nana/psp.jpg b/htdocs/imacat/images/nana/psp.jpg new file mode 100644 index 0000000..54a0e37 Binary files /dev/null and b/htdocs/imacat/images/nana/psp.jpg differ diff --git a/htdocs/imacat/images/nana/reira_olivia.jpg b/htdocs/imacat/images/nana/reira_olivia.jpg new file mode 100644 index 0000000..3a4da6f Binary files /dev/null and b/htdocs/imacat/images/nana/reira_olivia.jpg differ diff --git a/htdocs/imacat/images/nana/sato_koichi_comic.jpg b/htdocs/imacat/images/nana/sato_koichi_comic.jpg new file mode 100644 index 0000000..b9cf300 Binary files /dev/null and b/htdocs/imacat/images/nana/sato_koichi_comic.jpg differ diff --git a/htdocs/imacat/images/nana/sato_koichi_real.jpg b/htdocs/imacat/images/nana/sato_koichi_real.jpg new file mode 100644 index 0000000..dfe09a6 Binary files /dev/null and b/htdocs/imacat/images/nana/sato_koichi_real.jpg differ diff --git a/htdocs/imacat/images/nana/sid_vicious.jpg b/htdocs/imacat/images/nana/sid_vicious.jpg new file mode 100644 index 0000000..52f7a68 Binary files /dev/null and b/htdocs/imacat/images/nana/sid_vicious.jpg differ diff --git a/htdocs/imacat/images/nana/uehara_misato.jpg b/htdocs/imacat/images/nana/uehara_misato.jpg new file mode 100644 index 0000000..cf05673 Binary files /dev/null and b/htdocs/imacat/images/nana/uehara_misato.jpg differ diff --git a/htdocs/imacat/images/nana/uehara_misato_flower.jpg b/htdocs/imacat/images/nana/uehara_misato_flower.jpg new file mode 100644 index 0000000..ed2f66c Binary files /dev/null and b/htdocs/imacat/images/nana/uehara_misato_flower.jpg differ diff --git a/htdocs/imacat/images/nana/virtual_sachiko.jpg b/htdocs/imacat/images/nana/virtual_sachiko.jpg new file mode 100644 index 0000000..9e40377 Binary files /dev/null and b/htdocs/imacat/images/nana/virtual_sachiko.jpg differ diff --git a/htdocs/imacat/images/nana/vivienne_westwood.jpg b/htdocs/imacat/images/nana/vivienne_westwood.jpg new file mode 100644 index 0000000..564fce2 Binary files /dev/null and b/htdocs/imacat/images/nana/vivienne_westwood.jpg differ diff --git a/htdocs/imacat/images/nana/wazatodayo.jpg b/htdocs/imacat/images/nana/wazatodayo.jpg new file mode 100644 index 0000000..894e31b Binary files /dev/null and b/htdocs/imacat/images/nana/wazatodayo.jpg differ diff --git a/htdocs/imacat/images/nana/yazawa_eikichi.jpg b/htdocs/imacat/images/nana/yazawa_eikichi.jpg new file mode 100644 index 0000000..8b246ca Binary files /dev/null and b/htdocs/imacat/images/nana/yazawa_eikichi.jpg differ diff --git a/htdocs/imacat/images/nokia6070.jpg b/htdocs/imacat/images/nokia6070.jpg new file mode 100644 index 0000000..270ee97 Binary files /dev/null and b/htdocs/imacat/images/nokia6070.jpg differ diff --git a/htdocs/imacat/images/penguin.gif b/htdocs/imacat/images/penguin.gif new file mode 100644 index 0000000..0eeea68 Binary files /dev/null and b/htdocs/imacat/images/penguin.gif differ diff --git a/htdocs/imacat/images/plurk-theme/Leaves.gif b/htdocs/imacat/images/plurk-theme/Leaves.gif new file mode 100644 index 0000000..b3d2dae Binary files /dev/null and b/htdocs/imacat/images/plurk-theme/Leaves.gif differ diff --git a/htdocs/imacat/images/plurk-theme/Vintage.png b/htdocs/imacat/images/plurk-theme/Vintage.png new file mode 100644 index 0000000..8b1723a Binary files /dev/null and b/htdocs/imacat/images/plurk-theme/Vintage.png differ diff --git a/htdocs/imacat/images/plurk-theme/pinkplurk.png b/htdocs/imacat/images/plurk-theme/pinkplurk.png new file mode 100644 index 0000000..f0b976b Binary files /dev/null and b/htdocs/imacat/images/plurk-theme/pinkplurk.png differ diff --git a/htdocs/imacat/images/plurk-theme/urls.txt b/htdocs/imacat/images/plurk-theme/urls.txt new file mode 100644 index 0000000..104f22d --- /dev/null +++ b/htdocs/imacat/images/plurk-theme/urls.txt @@ -0,0 +1 @@ +wget http://www.maclaughlinstudios.com/Plurk/Vintage/Leaves.gif http://www.maclaughlinstudios.com/Plurk/Vintage/Vintage.png http://www.maclaughlinstudios.com/Plurk/Vintage/pinkplurk.png diff --git a/htdocs/imacat/images/plurk-theme/vintage1.css b/htdocs/imacat/images/plurk-theme/vintage1.css new file mode 100644 index 0000000..26bedf0 --- /dev/null +++ b/htdocs/imacat/images/plurk-theme/vintage1.css @@ -0,0 +1,158 @@ +/* MY PLURK CODE - VINTAGE1 - for more plurk themes, hit my site at www.maclaughlinstudios.com*/ + +/* Special thanks to Plurkers AZJazzyJ, HELLFROZE & STRIFE for many of these fixes */ + +body, html { +background-image: url(http://www.maclaughlinstudios.com/Plurk/Vintage/Leaves.gif); +background-repeat: repeat +color: white; +font-family: Arial, Helvetica, sans-serif; +font-size: 11px; +color: #ffefc6; +} + +/* TIMELINE MODS */ + +#top_login { width: 100%; background: #582C30; } +.dark_icons #top_bar #edit_link {color:#ffefc6;} +#top_bar #edit_link, #top_login a, #footer a, #top_bar a {color:#ffefc6;} +#page_title { +font-size:15px; +color: #ffefc6; +} + +#timeline_holder { +background-image: url(http://www.maclaughlinstudios.com/Plurk/Vintage/Vintage.png); +} + +#timeline_bg .day_start .div_inner { +background: #AF4F8F; +opacity: 0.4; +-moz-opacity: 0.4; +filter: alpha (opacity = 40); +} + +.p_img { border:1px solid #582C30; } +#bottom_line { opacity: 0.5; filter:alpha (opacity=50); +} + +/* Get rid of your plurk character*/ +#dynamic_logo { opacity:0;filter:alpha(opacity=0);zoom:1 +} + +/* Get rid of the annoying little search form*/ +#mini_search form { opacity:0; filter:alpha(opacity=0);zoom=1 +} + +#mini_search form:hover { opacity:1; filter:alpha(opacity=100) +} + +/* TIMELINE PLURK BOX MODS */ + +/* Transparent Plurk Boxes courtesy of HELLFROZE */ + +.plurk_cnt {background: url(http://www.maclaughlinstudios.com/Plurk/Vintage/pinkplurk.png)!important } +} + +.plurk_box .plurk_cnt { border-bottom: 1px solid #582C30; } +.plurk_box .list { +border-right:1px solid #582C30; +} +.plurk_box .mini_form { +border-right:1px solid #582C30; +border-bottom:1px solid #582C30; +} +.plurk_box .caption, .plurk_box .list{ +border-right: 1px solid #582C30; +} +.info_box { +-moz-border-radius: 0px 0px 8px 8px; +border-right: 1px solid #582C30; +} + +#bottom_line, .day_bg .div_inner, #time_show { background:url(http://www.maclaughlinstudios.com/Plurk/Vintage/pinkplurk.png) +} +.dots_inner { background:#f00 +} +#updater { background:#dfc +} + +.response_count, .caption { background:#582C30!important; color: #ffefc6!important; font-size:10px; padding:0 0.25em +} +.new .response_count { background:#8DC2D0!important; color:#ffefc6!important; font-size:10px; padding:0 0.25em +} +.dots .inner { margin-left: 3px; -moz-border-radius:8px 8px 8px 8px; +} + +/* PLURK INPUT BOX MODS */ + +#plurk_form { +background: transparent url("http://www.maclaughlinstudios.com/Plurk/Vintage/pinkplurk.png") repeat; +border-right: 1px solid #AF4F8F; border-bottom: 1px solid #AF4F8F; +z-index: 4; -moz-border-radius: 20px 20px 20px 20px ; padding-bottom: 5px; +-webkit-border-top-right-radius: 21px; +-webkit-border-bottom-left-radius: 21px; +} + +/* DASHBOARD MODS */ + +#karma { +color: #ffefc6; +} + +#plurk-dashboard { +background: #582C30; +border: 1px #ffefc6; +text-align: justify; +font-size: 8pt; +text-align:justify; +background-repeat: repeat; +padding: 5px; +-moz-border-radius:10px 10px 10px 10px; +} + +#plurk-dashboard a{ +color:#ffefc6; +text-decoration:underline; +} + +#plurk-dashboard a:hover{ +color:#ffefc6; +text-decoration:underline; +} + +#plurk-dashboard h2{ +text-transform:uppercase; +background:none; +color:#8DC2D0; +font-weight:bold; +padding:0; +} + +#dash-stats table td { +color:#582C30; +} + +/*get rid of share your plurk page text*/ +#dash-fans div[style]:first-child { position:absolute;opacity:0; font-size:0;height:0; +} + +/* get rid of invite boxes*/ +#dashboard-invite, #invite_url, #mobile-gfx, #widget-gfx, #twitter-gfx { height:0; position:absolute;opacity:0; filter:alpha(opacity=0); zoom=1 +} + +/* Rounded & Colored Filter Tabs */ + +#filter_tab a.filter_selected { +-moz-border-radius: 2px 2px 2px 10px; background:#8DC2D0; color: #582C30; +-webkit-border-bottom-left-radius: 11px;} + +#filter_tab .off_tab { -moz-border-radius: 2px 2px 10px 2px; +background: url(http://www.plurkpix.com/pix/1zl.png) ; +color: #ffefc6; background-color: #582C30; +-webkit-border-bottom-right-radius: 11px; } + +.p_img { -moz-border-radius: 3px 5px 3px 5px; border: solid 1px #582C30; +-webkit-border-bottom-left-radius: 5px;}, +fieldset, img { -moz-border-radius: 3px 5px 3px 5px; +-webkit-border-bottom-left-radius: 5px} \ No newline at end of file diff --git a/htdocs/imacat/images/print01.png b/htdocs/imacat/images/print01.png new file mode 100644 index 0000000..6d4f498 Binary files /dev/null and b/htdocs/imacat/images/print01.png differ diff --git a/htdocs/imacat/images/print02.png b/htdocs/imacat/images/print02.png new file mode 100644 index 0000000..a249aa0 Binary files /dev/null and b/htdocs/imacat/images/print02.png differ diff --git a/htdocs/imacat/images/qcz.jpg b/htdocs/imacat/images/qcz.jpg new file mode 100644 index 0000000..648d91a Binary files /dev/null and b/htdocs/imacat/images/qcz.jpg differ diff --git a/htdocs/imacat/images/sailer_moon.jpg b/htdocs/imacat/images/sailer_moon.jpg new file mode 100644 index 0000000..46628ea Binary files /dev/null and b/htdocs/imacat/images/sailer_moon.jpg differ diff --git a/htdocs/imacat/images/saint_seiya.jpg b/htdocs/imacat/images/saint_seiya.jpg new file mode 100644 index 0000000..63fea42 Binary files /dev/null and b/htdocs/imacat/images/saint_seiya.jpg differ diff --git a/htdocs/imacat/images/scfonts.png b/htdocs/imacat/images/scfonts.png new file mode 100644 index 0000000..9930804 Binary files /dev/null and b/htdocs/imacat/images/scfonts.png differ diff --git a/htdocs/imacat/images/sex01.jpg b/htdocs/imacat/images/sex01.jpg new file mode 100644 index 0000000..9744047 Binary files /dev/null and b/htdocs/imacat/images/sex01.jpg differ diff --git a/htdocs/imacat/images/sex02.jpg b/htdocs/imacat/images/sex02.jpg new file mode 100644 index 0000000..7c8d5c5 Binary files /dev/null and b/htdocs/imacat/images/sex02.jpg differ diff --git a/htdocs/imacat/images/sex03.jpg b/htdocs/imacat/images/sex03.jpg new file mode 100644 index 0000000..1ffc53f Binary files /dev/null and b/htdocs/imacat/images/sex03.jpg differ diff --git a/htdocs/imacat/images/sgml.png b/htdocs/imacat/images/sgml.png new file mode 100644 index 0000000..a10b040 Binary files /dev/null and b/htdocs/imacat/images/sgml.png differ diff --git a/htdocs/imacat/images/siboley_x_6.jpg b/htdocs/imacat/images/siboley_x_6.jpg new file mode 100644 index 0000000..124b2d6 Binary files /dev/null and b/htdocs/imacat/images/siboley_x_6.jpg differ diff --git a/htdocs/imacat/images/tech/sslcerts/badca.en.png b/htdocs/imacat/images/tech/sslcerts/badca.en.png new file mode 100644 index 0000000..d147593 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/badca.en.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/badca.zh-cn.png b/htdocs/imacat/images/tech/sslcerts/badca.zh-cn.png new file mode 100644 index 0000000..7f6776f Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/badca.zh-cn.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/badca.zh-tw.png b/htdocs/imacat/images/tech/sslcerts/badca.zh-tw.png new file mode 100644 index 0000000..218e530 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/badca.zh-tw.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/credcard.en.png b/htdocs/imacat/images/tech/sslcerts/credcard.en.png new file mode 100644 index 0000000..492bf07 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/credcard.en.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/credcard.zh-cn.png b/htdocs/imacat/images/tech/sslcerts/credcard.zh-cn.png new file mode 100644 index 0000000..6b63c00 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/credcard.zh-cn.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/credcard.zh-tw.png b/htdocs/imacat/images/tech/sslcerts/credcard.zh-tw.png new file mode 100644 index 0000000..67e0d1f Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/credcard.zh-tw.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/goodca.en.png b/htdocs/imacat/images/tech/sslcerts/goodca.en.png new file mode 100644 index 0000000..b0093a2 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/goodca.en.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/goodca.zh-cn.png b/htdocs/imacat/images/tech/sslcerts/goodca.zh-cn.png new file mode 100644 index 0000000..596d722 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/goodca.zh-cn.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/goodca.zh-tw.png b/htdocs/imacat/images/tech/sslcerts/goodca.zh-tw.png new file mode 100644 index 0000000..fe5ebe6 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/goodca.zh-tw.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/id.en.png b/htdocs/imacat/images/tech/sslcerts/id.en.png new file mode 100644 index 0000000..be2f28e Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/id.en.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/id.zh-cn.png b/htdocs/imacat/images/tech/sslcerts/id.zh-cn.png new file mode 100644 index 0000000..c65d582 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/id.zh-cn.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/id.zh-tw.png b/htdocs/imacat/images/tech/sslcerts/id.zh-tw.png new file mode 100644 index 0000000..4d6f1b2 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/id.zh-tw.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/myca.en.png b/htdocs/imacat/images/tech/sslcerts/myca.en.png new file mode 100644 index 0000000..cc765aa Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/myca.en.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/myca.zh-cn.png b/htdocs/imacat/images/tech/sslcerts/myca.zh-cn.png new file mode 100644 index 0000000..6eb9c17 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/myca.zh-cn.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/myca.zh-tw.png b/htdocs/imacat/images/tech/sslcerts/myca.zh-tw.png new file mode 100644 index 0000000..0ddccf2 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/myca.zh-tw.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/myca_import.en.png b/htdocs/imacat/images/tech/sslcerts/myca_import.en.png new file mode 100644 index 0000000..8c7001c Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/myca_import.en.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/myca_import.zh-cn.png b/htdocs/imacat/images/tech/sslcerts/myca_import.zh-cn.png new file mode 100644 index 0000000..1d3236f Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/myca_import.zh-cn.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/myca_import.zh-tw.png b/htdocs/imacat/images/tech/sslcerts/myca_import.zh-tw.png new file mode 100644 index 0000000..aed2081 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/myca_import.zh-tw.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/pgp.en.png b/htdocs/imacat/images/tech/sslcerts/pgp.en.png new file mode 100644 index 0000000..dd2fae0 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/pgp.en.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/pgp.zh-cn.png b/htdocs/imacat/images/tech/sslcerts/pgp.zh-cn.png new file mode 100644 index 0000000..3a2d8e3 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/pgp.zh-cn.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/pgp.zh-tw.png b/htdocs/imacat/images/tech/sslcerts/pgp.zh-tw.png new file mode 100644 index 0000000..932054f Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/pgp.zh-tw.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/x509.en.png b/htdocs/imacat/images/tech/sslcerts/x509.en.png new file mode 100644 index 0000000..a50798c Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/x509.en.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/x509.zh-cn.png b/htdocs/imacat/images/tech/sslcerts/x509.zh-cn.png new file mode 100644 index 0000000..7d1d7b2 Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/x509.zh-cn.png differ diff --git a/htdocs/imacat/images/tech/sslcerts/x509.zh-tw.png b/htdocs/imacat/images/tech/sslcerts/x509.zh-tw.png new file mode 100644 index 0000000..172f86d Binary files /dev/null and b/htdocs/imacat/images/tech/sslcerts/x509.zh-tw.png differ diff --git a/htdocs/imacat/images/tlug2002map.png b/htdocs/imacat/images/tlug2002map.png new file mode 100644 index 0000000..6d4aa8a Binary files /dev/null and b/htdocs/imacat/images/tlug2002map.png differ diff --git a/htdocs/imacat/images/u7/fsbomb01.png b/htdocs/imacat/images/u7/fsbomb01.png new file mode 100644 index 0000000..9df41dc Binary files /dev/null and b/htdocs/imacat/images/u7/fsbomb01.png differ diff --git a/htdocs/imacat/images/u7/fsbomb02.png b/htdocs/imacat/images/u7/fsbomb02.png new file mode 100644 index 0000000..ba87514 Binary files /dev/null and b/htdocs/imacat/images/u7/fsbomb02.png differ diff --git a/htdocs/imacat/images/u7/fsbomb03.png b/htdocs/imacat/images/u7/fsbomb03.png new file mode 100644 index 0000000..59373d3 Binary files /dev/null and b/htdocs/imacat/images/u7/fsbomb03.png differ diff --git a/htdocs/imacat/images/u7/millie01.png b/htdocs/imacat/images/u7/millie01.png new file mode 100644 index 0000000..8f762d5 Binary files /dev/null and b/htdocs/imacat/images/u7/millie01.png differ diff --git a/htdocs/imacat/images/u7/millie02.png b/htdocs/imacat/images/u7/millie02.png new file mode 100644 index 0000000..7b89e9f Binary files /dev/null and b/htdocs/imacat/images/u7/millie02.png differ diff --git a/htdocs/imacat/images/u7/millie03.png b/htdocs/imacat/images/u7/millie03.png new file mode 100644 index 0000000..4634e48 Binary files /dev/null and b/htdocs/imacat/images/u7/millie03.png differ diff --git a/htdocs/imacat/images/u7/runes/a.png b/htdocs/imacat/images/u7/runes/a.png new file mode 100644 index 0000000..a23fa65 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/a.png differ diff --git a/htdocs/imacat/images/u7/runes/b.png b/htdocs/imacat/images/u7/runes/b.png new file mode 100644 index 0000000..4858ca8 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/b.png differ diff --git a/htdocs/imacat/images/u7/runes/c.png b/htdocs/imacat/images/u7/runes/c.png new file mode 100644 index 0000000..c5905a3 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/c.png differ diff --git a/htdocs/imacat/images/u7/runes/d.png b/htdocs/imacat/images/u7/runes/d.png new file mode 100644 index 0000000..be1f66a Binary files /dev/null and b/htdocs/imacat/images/u7/runes/d.png differ diff --git a/htdocs/imacat/images/u7/runes/e.png b/htdocs/imacat/images/u7/runes/e.png new file mode 100644 index 0000000..0d2512e Binary files /dev/null and b/htdocs/imacat/images/u7/runes/e.png differ diff --git a/htdocs/imacat/images/u7/runes/ea.png b/htdocs/imacat/images/u7/runes/ea.png new file mode 100644 index 0000000..e1a731e Binary files /dev/null and b/htdocs/imacat/images/u7/runes/ea.png differ diff --git a/htdocs/imacat/images/u7/runes/ee.png b/htdocs/imacat/images/u7/runes/ee.png new file mode 100644 index 0000000..6d7fdd0 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/ee.png differ diff --git a/htdocs/imacat/images/u7/runes/f.png b/htdocs/imacat/images/u7/runes/f.png new file mode 100644 index 0000000..b56d012 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/f.png differ diff --git a/htdocs/imacat/images/u7/runes/g.png b/htdocs/imacat/images/u7/runes/g.png new file mode 100644 index 0000000..03c0c34 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/g.png differ diff --git a/htdocs/imacat/images/u7/runes/h.png b/htdocs/imacat/images/u7/runes/h.png new file mode 100644 index 0000000..3601079 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/h.png differ diff --git a/htdocs/imacat/images/u7/runes/i.png b/htdocs/imacat/images/u7/runes/i.png new file mode 100644 index 0000000..b63dc66 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/i.png differ diff --git a/htdocs/imacat/images/u7/runes/j.png b/htdocs/imacat/images/u7/runes/j.png new file mode 100644 index 0000000..ad06eff Binary files /dev/null and b/htdocs/imacat/images/u7/runes/j.png differ diff --git a/htdocs/imacat/images/u7/runes/k.png b/htdocs/imacat/images/u7/runes/k.png new file mode 100644 index 0000000..98c13d9 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/k.png differ diff --git a/htdocs/imacat/images/u7/runes/l.png b/htdocs/imacat/images/u7/runes/l.png new file mode 100644 index 0000000..bd95162 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/l.png differ diff --git a/htdocs/imacat/images/u7/runes/m.png b/htdocs/imacat/images/u7/runes/m.png new file mode 100644 index 0000000..651c219 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/m.png differ diff --git a/htdocs/imacat/images/u7/runes/n.png b/htdocs/imacat/images/u7/runes/n.png new file mode 100644 index 0000000..fd23c0f Binary files /dev/null and b/htdocs/imacat/images/u7/runes/n.png differ diff --git a/htdocs/imacat/images/u7/runes/ng.png b/htdocs/imacat/images/u7/runes/ng.png new file mode 100644 index 0000000..ca87088 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/ng.png differ diff --git a/htdocs/imacat/images/u7/runes/o.png b/htdocs/imacat/images/u7/runes/o.png new file mode 100644 index 0000000..952491c Binary files /dev/null and b/htdocs/imacat/images/u7/runes/o.png differ diff --git a/htdocs/imacat/images/u7/runes/p.png b/htdocs/imacat/images/u7/runes/p.png new file mode 100644 index 0000000..cc9a2f0 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/p.png differ diff --git a/htdocs/imacat/images/u7/runes/q.png b/htdocs/imacat/images/u7/runes/q.png new file mode 100644 index 0000000..3ea3b27 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/q.png differ diff --git a/htdocs/imacat/images/u7/runes/r.png b/htdocs/imacat/images/u7/runes/r.png new file mode 100644 index 0000000..dc88555 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/r.png differ diff --git a/htdocs/imacat/images/u7/runes/s.png b/htdocs/imacat/images/u7/runes/s.png new file mode 100644 index 0000000..dabf122 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/s.png differ diff --git a/htdocs/imacat/images/u7/runes/space.png b/htdocs/imacat/images/u7/runes/space.png new file mode 100644 index 0000000..fde1028 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/space.png differ diff --git a/htdocs/imacat/images/u7/runes/st.png b/htdocs/imacat/images/u7/runes/st.png new file mode 100644 index 0000000..3cc92be Binary files /dev/null and b/htdocs/imacat/images/u7/runes/st.png differ diff --git a/htdocs/imacat/images/u7/runes/t.png b/htdocs/imacat/images/u7/runes/t.png new file mode 100644 index 0000000..b301a44 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/t.png differ diff --git a/htdocs/imacat/images/u7/runes/th.png b/htdocs/imacat/images/u7/runes/th.png new file mode 100644 index 0000000..d926675 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/th.png differ diff --git a/htdocs/imacat/images/u7/runes/u.png b/htdocs/imacat/images/u7/runes/u.png new file mode 100644 index 0000000..4159a64 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/u.png differ diff --git a/htdocs/imacat/images/u7/runes/v.png b/htdocs/imacat/images/u7/runes/v.png new file mode 100644 index 0000000..a853b76 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/v.png differ diff --git a/htdocs/imacat/images/u7/runes/w.png b/htdocs/imacat/images/u7/runes/w.png new file mode 100644 index 0000000..a0abf56 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/w.png differ diff --git a/htdocs/imacat/images/u7/runes/x.png b/htdocs/imacat/images/u7/runes/x.png new file mode 100644 index 0000000..f19389c Binary files /dev/null and b/htdocs/imacat/images/u7/runes/x.png differ diff --git a/htdocs/imacat/images/u7/runes/y.png b/htdocs/imacat/images/u7/runes/y.png new file mode 100644 index 0000000..526aa09 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/y.png differ diff --git a/htdocs/imacat/images/u7/runes/z.png b/htdocs/imacat/images/u7/runes/z.png new file mode 100644 index 0000000..57614d7 Binary files /dev/null and b/htdocs/imacat/images/u7/runes/z.png differ diff --git a/htdocs/imacat/images/virtualpc.jpg b/htdocs/imacat/images/virtualpc.jpg new file mode 100644 index 0000000..8b44317 Binary files /dev/null and b/htdocs/imacat/images/virtualpc.jpg differ diff --git a/htdocs/imacat/images/wiigun_batbelt.jpg b/htdocs/imacat/images/wiigun_batbelt.jpg new file mode 100644 index 0000000..9c30978 Binary files /dev/null and b/htdocs/imacat/images/wiigun_batbelt.jpg differ diff --git a/htdocs/imacat/images/yellowrice.jpg b/htdocs/imacat/images/yellowrice.jpg new file mode 100644 index 0000000..a91cf99 Binary files /dev/null and b/htdocs/imacat/images/yellowrice.jpg differ diff --git a/htdocs/imacat/images/交大水果妹.jpg b/htdocs/imacat/images/交大水果妹.jpg new file mode 100644 index 0000000..1817526 Binary files /dev/null and b/htdocs/imacat/images/交大水果妹.jpg differ diff --git a/htdocs/imacat/images/美女走光圖.jpg b/htdocs/imacat/images/美女走光圖.jpg new file mode 100644 index 0000000..3bd9ed4 Binary files /dev/null and b/htdocs/imacat/images/美女走光圖.jpg differ diff --git a/htdocs/imacat/index.html.en.html b/htdocs/imacat/index.html.en.html new file mode 120000 index 0000000..08fc4ee --- /dev/null +++ b/htdocs/imacat/index.html.en.html @@ -0,0 +1 @@ +index.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/index.html.en.xhtml b/htdocs/imacat/index.html.en.xhtml new file mode 100644 index 0000000..db5d7cc --- /dev/null +++ b/htdocs/imacat/index.html.en.xhtml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + +Tavern IMACAT’s + + + + + + +
    + + +
    +
    +
    +

    WELCOME TO

    +

    Tavern
    + IMACAT’s

    + +

    Make your self free here! ^_*'

    +
    +
    + +
    +

    Since 3.9.’98, last updated last update.

    + +

    You are the counterth traveller of Tavern! ^_*'

    + +
    + 正體中文 | + 简体中文 | + English
    +
    + +

    Welcome! I’m the barmaid, Cotton. Please sign on our Travellers’ Guestbook first.

    +
    +
    +
    + + +
    + +
    +

    Bulletin Board

    + +

    Full Text Search — Selima 2.20

    + +

    Finally we’ve got a full text search in Tavern now. Though there are still 28 pages not in the database yet, most of the content can be searched now. Yeah! ^_*'

    + + +

    Tavern Diary — Selima 2.12

    + +

    The Tavern Diary editorial system is back with Selima 2.12. Finally I have a place to write things myself without messing with the Travellers’ Guestbook.

    + + +

    Tavern Goes WCAG 1.0

    + +

    Tavern is now following WAI (Web Accessibility Initiative), to enable people with disabilities to use the website. Tavern is currently following WCAG (Web Content Accessibility Guidelines) 1.0, Level Double-A. (In fact, it’s only one step to level Triple-A.) You can see the WCAG 1.0 WAI-AA logo in the bottom of the pages.

    + + +

    New Keep Travelling — Selima 2.1 with Related Links

    + +

    The related links are managed again! The first step of the Selima 2 content manage system is done, with related-links management. You may see that Keep Travelling is updated. This is a major achievement toward a fully-powered Selima content manage system.

    + + +

    New Travellers’ Guestbook — Selima 2 with PostgreSQL

    + +

    Finally Selima 2 is out. This is the total rewrite of the previous Selima system, in order to use SQL database server as our data engine. You’ll feel a little slower on Travellers’ Guestbook, but the site content will be powered up by the new Selima 2 content manage system from now on. ^_*'

    + + +

    vsntp

    + +

    vsntp is an SNTP client daemon for machines without a sane system time. This is my first daemon, my first socket program and my first public-released C program. Any comment or suggestion is welcome. ^_*'

    + +
    +
    + + + + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/index.html.zh-cn.html b/htdocs/imacat/index.html.zh-cn.html new file mode 120000 index 0000000..5ee9c39 --- /dev/null +++ b/htdocs/imacat/index.html.zh-cn.html @@ -0,0 +1 @@ +index.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/index.html.zh-cn.xhtml b/htdocs/imacat/index.html.zh-cn.xhtml new file mode 100644 index 0000000..c5c493a --- /dev/null +++ b/htdocs/imacat/index.html.zh-cn.xhtml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + +旅舍依玛 + + + + + + +
    + + +
    +
    +
    +

    欢迎光临

    +

    旅舍依玛

    + +

    请自便,别客气唷~ ^_*'

    +
    +
    + +
    +

    建于 3.9.’98 ,最近更新日期 最近更新日期

    + +

    妳是旅舍第 访客计数器 位旅人喔! ^_*'

    + +
    + 正體中文 | + 简体中文 | + English
    +
    + +

    欢迎光临~!我是女侍‧絮。请先在旅人留言簿签名。

    +
    +
    +
    + + +
    + +
    +

    旅舍布告栏

    + +

    全文检索— Selima 2.20

    + +

    旅舍终于有了全文检索了。虽然现在所有网页还没有全部建档(还有 28 页左右),不过大部份的内容都已经放上去了。耶~! ^_*'

    + +

    旅舍日记— Selima 2.12

    + +

    旅舍日记编辑系统,终于随着 Selima 2.12 完成了。现在我有地方可以写自己的东西,不用什么东西都写在旅人留言簿啰~ ^_*'

    + + + +

    旅舍迈向 WCAG 1.0

    + +

    旅舍目前所有网页已遵守 WAI (无障碍网页主义),以便身障的朋友浏览。目前遵守的标准是 WCAG (无障碍网页规范) 1.0 双 A 等级。(其实离三 A 等级只差一点。)妳可以在每页最下方看到 WCAG 1.0 WAI-AA 的标志。

    + + +

    新继续旅行— Selima 2.1 相关链接

    + +

    旅舍的相关链接终于又回来了。 Selima 2 的内容管理系统终于跨出了第一步,完成了相关链接管理系统。继续旅行里的网站也跟着刷新过了。这是 Selima 迈向全功能内容管理系统,最重要的一步。

    + + +

    新留言簿— Selima 2 加 PostgreSQL

    + +

    Selima 2 终于写出来了。为改用 PostgreSQL ,几乎改写了整个 Selima 系统。旅人留言簿可能会有一点变慢,不过改用 Selima 2 以后,整个网站管理系统要开始重新起飞了~ ^_*'

    + + +

    vsntp

    + +

    vsntpSNTP 客户端服务程序,专为时间不正常的系统设计。vsntp 是我写的第一个 daemon ,我写的第一个 socket 程序,也是我第一个公开发行的 C 程序。请多多指教~ ^_*'

    + +
    +
    + + + + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/index.html.zh-tw.html b/htdocs/imacat/index.html.zh-tw.html new file mode 120000 index 0000000..6c1b76e --- /dev/null +++ b/htdocs/imacat/index.html.zh-tw.html @@ -0,0 +1 @@ +index.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/index.html.zh-tw.xhtml b/htdocs/imacat/index.html.zh-tw.xhtml new file mode 100644 index 0000000..f1b4af6 --- /dev/null +++ b/htdocs/imacat/index.html.zh-tw.xhtml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + +旅舍依瑪 + + + + + + +
    + + +
    +
    +
    +

    歡迎光臨

    +

    旅舍依瑪

    + +

    請自便,別客氣唷~ ^_*'

    +
    +
    + +
    +

    建於 3.9.’98 ,最近更新日期 最近更新日期

    + +

    妳是旅舍第 訪客計數器 位旅人喔! ^_*'

    + +
    + 正體中文 | + 简体中文 | + English
    +
    + +

    歡迎光臨~!我是女侍‧絮。請先在旅人留言簿簽名。

    +
    +
    +
    + + +
    + +
    +

    旅舍佈告欄

    + +

    全文檢索— Selima 2.20

    + +

    旅舍終於有了全文檢索了。雖然現在所有網頁還沒有全部建檔(還有 28 頁左右),不過大部份的內容都已經放上去了。耶~! ^_*'

    + +

    旅舍日記— Selima 2.12

    + +

    旅舍日記編輯系統,終於隨著 Selima 2.12 完成了。現在我有地方可以寫自己的東西,不用什麼東西都寫在旅人留言簿囉~ ^_*'

    + + + +

    旅舍邁向 WCAG 1.0

    + +

    旅舍目前所有網頁已遵守 WAI (無障礙網頁主義),以便身障的朋友瀏覽。目前遵守的標準是 WCAG (無障礙網頁規範) 1.0 雙 A 等級。(其實離三 A 等級只差一點。)妳可以在每頁最下方看到 WCAG 1.0 WAI-AA 的標誌。

    + + +

    新繼續旅行— Selima 2.1 相關連結

    + +

    旅舍的相關連結終於又回來了。 Selima 2 的內容管理系統終於跨出了第一步,完成了相關連結管理系統。繼續旅行裏的網站也跟著重新整理過了。這是 Selima 邁向全功能內容管理系統,最重要的一步。

    + + +

    新留言簿— Selima 2 加 PostgreSQL

    + +

    Selima 2 終於寫出來了。為改用 PostgreSQL ,幾乎改寫了整個 Selima 系統。旅人留言簿可能會有一點變慢,不過改用 Selima 2 以後,整個網站管理系統要開始重新起飛了~ ^_*'

    + + +

    vsntp

    + +

    vsntpSNTP 客戶端服務程式,專為時間不正常的系統設計。vsntp 是我寫的第一個 daemon ,我寫的第一個 socket 程式,也是我第一個公開發行的 C 程式。請多多指教~ ^_*'

    + +
    +
    + + + + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/activist/index.html.en.html b/htdocs/imacat/links/activist/index.html.en.html new file mode 120000 index 0000000..08fc4ee --- /dev/null +++ b/htdocs/imacat/links/activist/index.html.en.html @@ -0,0 +1 @@ +index.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/activist/index.html.en.xhtml b/htdocs/imacat/links/activist/index.html.en.xhtml new file mode 100644 index 0000000..6adc798 --- /dev/null +++ b/htdocs/imacat/links/activist/index.html.en.xhtml @@ -0,0 +1,412 @@ + + + + + + + + + + + + + + + + + + + + + +Activists + + + + + + + +
    + +
    + + +

    Activists

    + + + +
    + +
    + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/activist/index.html.zh-cn.html b/htdocs/imacat/links/activist/index.html.zh-cn.html new file mode 120000 index 0000000..5ee9c39 --- /dev/null +++ b/htdocs/imacat/links/activist/index.html.zh-cn.html @@ -0,0 +1 @@ +index.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/activist/index.html.zh-cn.xhtml b/htdocs/imacat/links/activist/index.html.zh-cn.xhtml new file mode 100644 index 0000000..b8d5b69 --- /dev/null +++ b/htdocs/imacat/links/activist/index.html.zh-cn.xhtml @@ -0,0 +1,411 @@ + + + + + + + + + + + + + + + + + + + + + +社学运组织 + + + + + + + +
    + +
    + + +

    社学运组织

    + + + + + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/activist/index.html.zh-tw.html b/htdocs/imacat/links/activist/index.html.zh-tw.html new file mode 120000 index 0000000..6c1b76e --- /dev/null +++ b/htdocs/imacat/links/activist/index.html.zh-tw.html @@ -0,0 +1 @@ +index.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/activist/index.html.zh-tw.xhtml b/htdocs/imacat/links/activist/index.html.zh-tw.xhtml new file mode 100644 index 0000000..243b937 --- /dev/null +++ b/htdocs/imacat/links/activist/index.html.zh-tw.xhtml @@ -0,0 +1,411 @@ + + + + + + + + + + + + + + + + + + + + + +社學運組織 + + + + + + + +
    + +
    + + +

    社學運組織

    + + + + + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/activist/intl.html.en.html b/htdocs/imacat/links/activist/intl.html.en.html new file mode 120000 index 0000000..a9116c6 --- /dev/null +++ b/htdocs/imacat/links/activist/intl.html.en.html @@ -0,0 +1 @@ +intl.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/activist/intl.html.en.xhtml b/htdocs/imacat/links/activist/intl.html.en.xhtml new file mode 100644 index 0000000..7e8553f --- /dev/null +++ b/htdocs/imacat/links/activist/intl.html.en.xhtml @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + +Foreign Activists + + + + + + + +
    + +
    + + +

    Foreign Activists

    + + + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/activist/intl.html.zh-cn.html b/htdocs/imacat/links/activist/intl.html.zh-cn.html new file mode 120000 index 0000000..f80dd88 --- /dev/null +++ b/htdocs/imacat/links/activist/intl.html.zh-cn.html @@ -0,0 +1 @@ +intl.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/activist/intl.html.zh-cn.xhtml b/htdocs/imacat/links/activist/intl.html.zh-cn.xhtml new file mode 100644 index 0000000..4be02d8 --- /dev/null +++ b/htdocs/imacat/links/activist/intl.html.zh-cn.xhtml @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + +国外社学运组织 + + + + + + + +
    + +
    + + +

    国外社学运组织

    + + + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/activist/intl.html.zh-tw.html b/htdocs/imacat/links/activist/intl.html.zh-tw.html new file mode 120000 index 0000000..9d6ff2b --- /dev/null +++ b/htdocs/imacat/links/activist/intl.html.zh-tw.html @@ -0,0 +1 @@ +intl.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/activist/intl.html.zh-tw.xhtml b/htdocs/imacat/links/activist/intl.html.zh-tw.xhtml new file mode 100644 index 0000000..c690dbe --- /dev/null +++ b/htdocs/imacat/links/activist/intl.html.zh-tw.xhtml @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + +國外社學運組織 + + + + + + + +
    + +
    + + +

    國外社學運組織

    + + + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/freesoft/index.html.en.html b/htdocs/imacat/links/freesoft/index.html.en.html new file mode 120000 index 0000000..08fc4ee --- /dev/null +++ b/htdocs/imacat/links/freesoft/index.html.en.html @@ -0,0 +1 @@ +index.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/freesoft/index.html.en.xhtml b/htdocs/imacat/links/freesoft/index.html.en.xhtml new file mode 100644 index 0000000..c103e9f --- /dev/null +++ b/htdocs/imacat/links/freesoft/index.html.en.xhtml @@ -0,0 +1,369 @@ + + + + + + + + + + + + + + + + + + + + + +Free Softwares + + + + + + + +
    + +
    + + +

    Free Softwares

    + + + +
    + +
    + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/freesoft/index.html.zh-cn.html b/htdocs/imacat/links/freesoft/index.html.zh-cn.html new file mode 120000 index 0000000..5ee9c39 --- /dev/null +++ b/htdocs/imacat/links/freesoft/index.html.zh-cn.html @@ -0,0 +1 @@ +index.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/freesoft/index.html.zh-cn.xhtml b/htdocs/imacat/links/freesoft/index.html.zh-cn.xhtml new file mode 100644 index 0000000..762a22c --- /dev/null +++ b/htdocs/imacat/links/freesoft/index.html.zh-cn.xhtml @@ -0,0 +1,368 @@ + + + + + + + + + + + + + + + + + + + + + +自由软体 + + + + + + + +
    + +
    + + +

    自由软体

    + + + +
    + +
    + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/freesoft/index.html.zh-tw.html b/htdocs/imacat/links/freesoft/index.html.zh-tw.html new file mode 120000 index 0000000..6c1b76e --- /dev/null +++ b/htdocs/imacat/links/freesoft/index.html.zh-tw.html @@ -0,0 +1 @@ +index.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/freesoft/index.html.zh-tw.xhtml b/htdocs/imacat/links/freesoft/index.html.zh-tw.xhtml new file mode 100644 index 0000000..d3860d5 --- /dev/null +++ b/htdocs/imacat/links/freesoft/index.html.zh-tw.xhtml @@ -0,0 +1,368 @@ + + + + + + + + + + + + + + + + + + + + + +自由軟體 + + + + + + + +
    + +
    + + +

    自由軟體

    + + + +
    + +
    + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/freesoft/nonfree.html.en.html b/htdocs/imacat/links/freesoft/nonfree.html.en.html new file mode 120000 index 0000000..3960442 --- /dev/null +++ b/htdocs/imacat/links/freesoft/nonfree.html.en.html @@ -0,0 +1 @@ +nonfree.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/freesoft/nonfree.html.en.xhtml b/htdocs/imacat/links/freesoft/nonfree.html.en.xhtml new file mode 100644 index 0000000..17d083b --- /dev/null +++ b/htdocs/imacat/links/freesoft/nonfree.html.en.xhtml @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + +Non-free Softwares + + + + + + + +
    + +
    + + +

    Non-free Softwares

    + + + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/freesoft/nonfree.html.zh-cn.html b/htdocs/imacat/links/freesoft/nonfree.html.zh-cn.html new file mode 120000 index 0000000..4805b70 --- /dev/null +++ b/htdocs/imacat/links/freesoft/nonfree.html.zh-cn.html @@ -0,0 +1 @@ +nonfree.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/freesoft/nonfree.html.zh-cn.xhtml b/htdocs/imacat/links/freesoft/nonfree.html.zh-cn.xhtml new file mode 100644 index 0000000..dc355e4 --- /dev/null +++ b/htdocs/imacat/links/freesoft/nonfree.html.zh-cn.xhtml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + +不自由软体 + + + + + + + +
    + +
    + + +

    不自由软体

    + + + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/freesoft/nonfree.html.zh-tw.html b/htdocs/imacat/links/freesoft/nonfree.html.zh-tw.html new file mode 120000 index 0000000..5a4503d --- /dev/null +++ b/htdocs/imacat/links/freesoft/nonfree.html.zh-tw.html @@ -0,0 +1 @@ +nonfree.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/freesoft/nonfree.html.zh-tw.xhtml b/htdocs/imacat/links/freesoft/nonfree.html.zh-tw.xhtml new file mode 100644 index 0000000..50e873b --- /dev/null +++ b/htdocs/imacat/links/freesoft/nonfree.html.zh-tw.xhtml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + +不自由軟體 + + + + + + + +
    + +
    + + +

    不自由軟體

    + + + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/index.html.en.html b/htdocs/imacat/links/index.html.en.html new file mode 120000 index 0000000..08fc4ee --- /dev/null +++ b/htdocs/imacat/links/index.html.en.html @@ -0,0 +1 @@ +index.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/index.html.en.xhtml b/htdocs/imacat/links/index.html.en.xhtml new file mode 100644 index 0000000..e0473b4 --- /dev/null +++ b/htdocs/imacat/links/index.html.en.xhtml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + +Keep Travelling... + + + + + + + +
    + +
    + + +

    Continue Your Journey...

    + +
    +

    Are you ready to check out? Just drop your room key at the counter, and travel for your next stop. Life is a never-ending trip, and Tavern is only one of your many stops. Are you ready to go now?

    + +

    Greetings, traveller. I'm rinse the Tavern Tour Agent. Where is your next stop?

    +
    + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/index.html.zh-cn.html b/htdocs/imacat/links/index.html.zh-cn.html new file mode 120000 index 0000000..5ee9c39 --- /dev/null +++ b/htdocs/imacat/links/index.html.zh-cn.html @@ -0,0 +1 @@ +index.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/index.html.zh-cn.xhtml b/htdocs/imacat/links/index.html.zh-cn.xhtml new file mode 100644 index 0000000..ce87e76 --- /dev/null +++ b/htdocs/imacat/links/index.html.zh-cn.xhtml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + +继续旅行…… + + + + + + + +
    + +
    + + +

    继续妳的旅程……

    + +
    +

    妳要退房了吗?把妳的房门钥匙交还给柜台,该向下一个停靠站出发了。这是一趟永无止境的旅程,旅舍,只是妳的一个中途停靠站。若妳准备好了,就出发啰!

    + +

    妳好,旅行者。我是琳思。妳要往哪里去旅行呢?

    +
    + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/index.html.zh-tw.html b/htdocs/imacat/links/index.html.zh-tw.html new file mode 120000 index 0000000..6c1b76e --- /dev/null +++ b/htdocs/imacat/links/index.html.zh-tw.html @@ -0,0 +1 @@ +index.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/index.html.zh-tw.xhtml b/htdocs/imacat/links/index.html.zh-tw.xhtml new file mode 100644 index 0000000..e8d40be --- /dev/null +++ b/htdocs/imacat/links/index.html.zh-tw.xhtml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + +繼續旅行…… + + + + + + + +
    + +
    + + +

    繼續妳的旅程……

    + +
    +

    妳要退房了嗎?把妳的房門鑰匙交還給櫃臺,該向下一個停靠站出發了。這是一趟永無止境的旅程,旅舍,只是妳的一個中途停靠站。若妳準備好了,就出發囉!

    + +

    妳好,旅行者。我是琳思。妳要往哪裡去旅行呢?

    +
    + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/groups.html.en.html b/htdocs/imacat/links/lesbian/groups.html.en.html new file mode 120000 index 0000000..a059fb6 --- /dev/null +++ b/htdocs/imacat/links/lesbian/groups.html.en.html @@ -0,0 +1 @@ +groups.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/groups.html.en.xhtml b/htdocs/imacat/links/lesbian/groups.html.en.xhtml new file mode 100644 index 0000000..4bfa417 --- /dev/null +++ b/htdocs/imacat/links/lesbian/groups.html.en.xhtml @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + +Lesbian Societies + + + + + + + +
    + +
    + + +

    Lesbian Societies

    + + + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/groups.html.zh-cn.html b/htdocs/imacat/links/lesbian/groups.html.zh-cn.html new file mode 120000 index 0000000..d63f2ff --- /dev/null +++ b/htdocs/imacat/links/lesbian/groups.html.zh-cn.html @@ -0,0 +1 @@ +groups.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/groups.html.zh-cn.xhtml b/htdocs/imacat/links/lesbian/groups.html.zh-cn.xhtml new file mode 100644 index 0000000..e46d546 --- /dev/null +++ b/htdocs/imacat/links/lesbian/groups.html.zh-cn.xhtml @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + +女同志组织 + + + + + + + +
    + +
    + + +

    女同志组织

    + + + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/groups.html.zh-tw.html b/htdocs/imacat/links/lesbian/groups.html.zh-tw.html new file mode 120000 index 0000000..0f1587f --- /dev/null +++ b/htdocs/imacat/links/lesbian/groups.html.zh-tw.html @@ -0,0 +1 @@ +groups.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/groups.html.zh-tw.xhtml b/htdocs/imacat/links/lesbian/groups.html.zh-tw.xhtml new file mode 100644 index 0000000..25b28b0 --- /dev/null +++ b/htdocs/imacat/links/lesbian/groups.html.zh-tw.xhtml @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + +女同志組織 + + + + + + + +
    + +
    + + +

    女同志組織

    + + + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/index.html.en.html b/htdocs/imacat/links/lesbian/index.html.en.html new file mode 120000 index 0000000..08fc4ee --- /dev/null +++ b/htdocs/imacat/links/lesbian/index.html.en.html @@ -0,0 +1 @@ +index.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/index.html.en.xhtml b/htdocs/imacat/links/lesbian/index.html.en.xhtml new file mode 100644 index 0000000..dd1319b --- /dev/null +++ b/htdocs/imacat/links/lesbian/index.html.en.xhtml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + +Lesbian + + + + + + + +
    + +
    + + +

    Lesbian

    + + + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/index.html.zh-cn.html b/htdocs/imacat/links/lesbian/index.html.zh-cn.html new file mode 120000 index 0000000..5ee9c39 --- /dev/null +++ b/htdocs/imacat/links/lesbian/index.html.zh-cn.html @@ -0,0 +1 @@ +index.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/index.html.zh-cn.xhtml b/htdocs/imacat/links/lesbian/index.html.zh-cn.xhtml new file mode 100644 index 0000000..1ce10c6 --- /dev/null +++ b/htdocs/imacat/links/lesbian/index.html.zh-cn.xhtml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + +女同志 + + + + + + + +
    + +
    + + +

    女同志

    + + + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/index.html.zh-tw.html b/htdocs/imacat/links/lesbian/index.html.zh-tw.html new file mode 120000 index 0000000..6c1b76e --- /dev/null +++ b/htdocs/imacat/links/lesbian/index.html.zh-tw.html @@ -0,0 +1 @@ +index.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/index.html.zh-tw.xhtml b/htdocs/imacat/links/lesbian/index.html.zh-tw.xhtml new file mode 100644 index 0000000..b30cf31 --- /dev/null +++ b/htdocs/imacat/links/lesbian/index.html.zh-tw.xhtml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + +女同志 + + + + + + + +
    + +
    + + +

    女同志

    + + + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/intl.html.en.html b/htdocs/imacat/links/lesbian/intl.html.en.html new file mode 120000 index 0000000..a9116c6 --- /dev/null +++ b/htdocs/imacat/links/lesbian/intl.html.en.html @@ -0,0 +1 @@ +intl.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/intl.html.en.xhtml b/htdocs/imacat/links/lesbian/intl.html.en.xhtml new file mode 100644 index 0000000..c688631 --- /dev/null +++ b/htdocs/imacat/links/lesbian/intl.html.en.xhtml @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + +Foreign Lesbian Sites + + + + + + + +
    + +
    + + +

    Foreign Lesbian Sites

    + + + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/intl.html.zh-cn.html b/htdocs/imacat/links/lesbian/intl.html.zh-cn.html new file mode 120000 index 0000000..f80dd88 --- /dev/null +++ b/htdocs/imacat/links/lesbian/intl.html.zh-cn.html @@ -0,0 +1 @@ +intl.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/intl.html.zh-cn.xhtml b/htdocs/imacat/links/lesbian/intl.html.zh-cn.xhtml new file mode 100644 index 0000000..3067cab --- /dev/null +++ b/htdocs/imacat/links/lesbian/intl.html.zh-cn.xhtml @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + +国外女同志网站 + + + + + + + +
    + +
    + + +

    国外女同志网站

    + + + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/intl.html.zh-tw.html b/htdocs/imacat/links/lesbian/intl.html.zh-tw.html new file mode 120000 index 0000000..9d6ff2b --- /dev/null +++ b/htdocs/imacat/links/lesbian/intl.html.zh-tw.html @@ -0,0 +1 @@ +intl.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/intl.html.zh-tw.xhtml b/htdocs/imacat/links/lesbian/intl.html.zh-tw.xhtml new file mode 100644 index 0000000..45508c0 --- /dev/null +++ b/htdocs/imacat/links/lesbian/intl.html.zh-tw.xhtml @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + +國外女同志網站 + + + + + + + +
    + +
    + + +

    國外女同志網站

    + + + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/personal.html.en.html b/htdocs/imacat/links/lesbian/personal.html.en.html new file mode 120000 index 0000000..78880d8 --- /dev/null +++ b/htdocs/imacat/links/lesbian/personal.html.en.html @@ -0,0 +1 @@ +personal.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/personal.html.en.xhtml b/htdocs/imacat/links/lesbian/personal.html.en.xhtml new file mode 100644 index 0000000..a3532e7 --- /dev/null +++ b/htdocs/imacat/links/lesbian/personal.html.en.xhtml @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + +Lesbian Personals + + + + + + + +
    + +
    + + +

    Lesbian Personals

    + + + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/personal.html.zh-cn.html b/htdocs/imacat/links/lesbian/personal.html.zh-cn.html new file mode 120000 index 0000000..2499c9e --- /dev/null +++ b/htdocs/imacat/links/lesbian/personal.html.zh-cn.html @@ -0,0 +1 @@ +personal.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/personal.html.zh-cn.xhtml b/htdocs/imacat/links/lesbian/personal.html.zh-cn.xhtml new file mode 100644 index 0000000..93746d1 --- /dev/null +++ b/htdocs/imacat/links/lesbian/personal.html.zh-cn.xhtml @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + +女同志个人网站 + + + + + + + +
    + +
    + + +

    女同志个人网站

    + + + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/personal.html.zh-tw.html b/htdocs/imacat/links/lesbian/personal.html.zh-tw.html new file mode 120000 index 0000000..fba6aa6 --- /dev/null +++ b/htdocs/imacat/links/lesbian/personal.html.zh-tw.html @@ -0,0 +1 @@ +personal.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/personal.html.zh-tw.xhtml b/htdocs/imacat/links/lesbian/personal.html.zh-tw.xhtml new file mode 100644 index 0000000..105c73d --- /dev/null +++ b/htdocs/imacat/links/lesbian/personal.html.zh-tw.xhtml @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + +女同志個人網站 + + + + + + + +
    + +
    + + +

    女同志個人網站

    + + + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/shops.html.en.html b/htdocs/imacat/links/lesbian/shops.html.en.html new file mode 120000 index 0000000..da981c5 --- /dev/null +++ b/htdocs/imacat/links/lesbian/shops.html.en.html @@ -0,0 +1 @@ +shops.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/shops.html.en.xhtml b/htdocs/imacat/links/lesbian/shops.html.en.xhtml new file mode 100644 index 0000000..c78f274 --- /dev/null +++ b/htdocs/imacat/links/lesbian/shops.html.en.xhtml @@ -0,0 +1,292 @@ + + + + + + + + + + + + + + + + + + + + + +Lesbian Shops + + + + + + + +
    + +
    + + +

    Lesbian Shops

    + + + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/shops.html.zh-cn.html b/htdocs/imacat/links/lesbian/shops.html.zh-cn.html new file mode 120000 index 0000000..77c5948 --- /dev/null +++ b/htdocs/imacat/links/lesbian/shops.html.zh-cn.html @@ -0,0 +1 @@ +shops.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/shops.html.zh-cn.xhtml b/htdocs/imacat/links/lesbian/shops.html.zh-cn.xhtml new file mode 100644 index 0000000..3d9c21d --- /dev/null +++ b/htdocs/imacat/links/lesbian/shops.html.zh-cn.xhtml @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + +女同志商店 + + + + + + + +
    + +
    + + +

    女同志商店

    + + + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/lesbian/shops.html.zh-tw.html b/htdocs/imacat/links/lesbian/shops.html.zh-tw.html new file mode 120000 index 0000000..d5ceb17 --- /dev/null +++ b/htdocs/imacat/links/lesbian/shops.html.zh-tw.html @@ -0,0 +1 @@ +shops.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/lesbian/shops.html.zh-tw.xhtml b/htdocs/imacat/links/lesbian/shops.html.zh-tw.xhtml new file mode 100644 index 0000000..11c78ab --- /dev/null +++ b/htdocs/imacat/links/lesbian/shops.html.zh-tw.xhtml @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + +女同志商店 + + + + + + + +
    + +
    + + +

    女同志商店

    + + + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/misc.html.en.html b/htdocs/imacat/links/misc.html.en.html new file mode 120000 index 0000000..992377a --- /dev/null +++ b/htdocs/imacat/links/misc.html.en.html @@ -0,0 +1 @@ +misc.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/misc.html.en.xhtml b/htdocs/imacat/links/misc.html.en.xhtml new file mode 100644 index 0000000..8129808 --- /dev/null +++ b/htdocs/imacat/links/misc.html.en.xhtml @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + +Others + + + + + + + +
    + +
    + + +

    Others

    + + + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/misc.html.zh-cn.html b/htdocs/imacat/links/misc.html.zh-cn.html new file mode 120000 index 0000000..3af9bdb --- /dev/null +++ b/htdocs/imacat/links/misc.html.zh-cn.html @@ -0,0 +1 @@ +misc.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/misc.html.zh-cn.xhtml b/htdocs/imacat/links/misc.html.zh-cn.xhtml new file mode 100644 index 0000000..9f406e3 --- /dev/null +++ b/htdocs/imacat/links/misc.html.zh-cn.xhtml @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + +其她网站 + + + + + + + +
    + +
    + + +

    其她网站

    + + + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/misc.html.zh-tw.html b/htdocs/imacat/links/misc.html.zh-tw.html new file mode 120000 index 0000000..a91a74b --- /dev/null +++ b/htdocs/imacat/links/misc.html.zh-tw.html @@ -0,0 +1 @@ +misc.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/misc.html.zh-tw.xhtml b/htdocs/imacat/links/misc.html.zh-tw.xhtml new file mode 100644 index 0000000..e089c68 --- /dev/null +++ b/htdocs/imacat/links/misc.html.zh-tw.xhtml @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + +其她網站 + + + + + + + +
    + +
    + + +

    其她網站

    + + + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/my.html.en.html b/htdocs/imacat/links/my.html.en.html new file mode 120000 index 0000000..55313ae --- /dev/null +++ b/htdocs/imacat/links/my.html.en.html @@ -0,0 +1 @@ +my.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/my.html.en.xhtml b/htdocs/imacat/links/my.html.en.xhtml new file mode 100644 index 0000000..12a64d4 --- /dev/null +++ b/htdocs/imacat/links/my.html.en.xhtml @@ -0,0 +1,300 @@ + + + + + + + + + + + + + + + + + + + + + +Built by Me + + + + + + + +
    + +
    + + +

    Built by Me

    + + + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/my.html.zh-cn.html b/htdocs/imacat/links/my.html.zh-cn.html new file mode 120000 index 0000000..679c4aa --- /dev/null +++ b/htdocs/imacat/links/my.html.zh-cn.html @@ -0,0 +1 @@ +my.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/my.html.zh-cn.xhtml b/htdocs/imacat/links/my.html.zh-cn.xhtml new file mode 100644 index 0000000..618b062 --- /dev/null +++ b/htdocs/imacat/links/my.html.zh-cn.xhtml @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + +我做的网站 + + + + + + + +
    + +
    + + +

    我做的网站

    + + + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/my.html.zh-tw.html b/htdocs/imacat/links/my.html.zh-tw.html new file mode 120000 index 0000000..7ecf9ff --- /dev/null +++ b/htdocs/imacat/links/my.html.zh-tw.html @@ -0,0 +1 @@ +my.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/my.html.zh-tw.xhtml b/htdocs/imacat/links/my.html.zh-tw.xhtml new file mode 100644 index 0000000..0498631 --- /dev/null +++ b/htdocs/imacat/links/my.html.zh-tw.xhtml @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + +我做的網站 + + + + + + + +
    + +
    + + +

    我做的網站

    + + + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/women/academic.html.en.html b/htdocs/imacat/links/women/academic.html.en.html new file mode 120000 index 0000000..b057ac8 --- /dev/null +++ b/htdocs/imacat/links/women/academic.html.en.html @@ -0,0 +1 @@ +academic.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/women/academic.html.en.xhtml b/htdocs/imacat/links/women/academic.html.en.xhtml new file mode 100644 index 0000000..951d01f --- /dev/null +++ b/htdocs/imacat/links/women/academic.html.en.xhtml @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + +Women Studies + + + + + + + +
    + +
    + + +

    Women Studies

    + + + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/women/academic.html.zh-cn.html b/htdocs/imacat/links/women/academic.html.zh-cn.html new file mode 120000 index 0000000..9f56096 --- /dev/null +++ b/htdocs/imacat/links/women/academic.html.zh-cn.html @@ -0,0 +1 @@ +academic.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/women/academic.html.zh-cn.xhtml b/htdocs/imacat/links/women/academic.html.zh-cn.xhtml new file mode 100644 index 0000000..8abf9c2 --- /dev/null +++ b/htdocs/imacat/links/women/academic.html.zh-cn.xhtml @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + +女性、性别研究 + + + + + + + +
    + +
    + + +

    女性、性别研究

    + + + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/women/academic.html.zh-tw.html b/htdocs/imacat/links/women/academic.html.zh-tw.html new file mode 120000 index 0000000..c66c6e2 --- /dev/null +++ b/htdocs/imacat/links/women/academic.html.zh-tw.html @@ -0,0 +1 @@ +academic.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/women/academic.html.zh-tw.xhtml b/htdocs/imacat/links/women/academic.html.zh-tw.xhtml new file mode 100644 index 0000000..12c6a43 --- /dev/null +++ b/htdocs/imacat/links/women/academic.html.zh-tw.xhtml @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + +女性、性別研究 + + + + + + + +
    + +
    + + +

    女性、性別研究

    + + + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/women/index.html.en.html b/htdocs/imacat/links/women/index.html.en.html new file mode 120000 index 0000000..08fc4ee --- /dev/null +++ b/htdocs/imacat/links/women/index.html.en.html @@ -0,0 +1 @@ +index.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/women/index.html.en.xhtml b/htdocs/imacat/links/women/index.html.en.xhtml new file mode 100644 index 0000000..2a4cf93 --- /dev/null +++ b/htdocs/imacat/links/women/index.html.en.xhtml @@ -0,0 +1,440 @@ + + + + + + + + + + + + + + + + + + + + + +Feminists and Women Rights + + + + + + + +
    + +
    + + +

    Feminists and Women Rights

    + + + +
    +
    + +
    + +
    + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/women/index.html.zh-cn.html b/htdocs/imacat/links/women/index.html.zh-cn.html new file mode 120000 index 0000000..5ee9c39 --- /dev/null +++ b/htdocs/imacat/links/women/index.html.zh-cn.html @@ -0,0 +1 @@ +index.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/women/index.html.zh-cn.xhtml b/htdocs/imacat/links/women/index.html.zh-cn.xhtml new file mode 100644 index 0000000..77477bd --- /dev/null +++ b/htdocs/imacat/links/women/index.html.zh-cn.xhtml @@ -0,0 +1,439 @@ + + + + + + + + + + + + + + + + + + + + + +妇运、女性主义 + + + + + + + +
    + +
    + + +

    妇运、女性主义

    + + + + + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/women/index.html.zh-tw.html b/htdocs/imacat/links/women/index.html.zh-tw.html new file mode 120000 index 0000000..6c1b76e --- /dev/null +++ b/htdocs/imacat/links/women/index.html.zh-tw.html @@ -0,0 +1 @@ +index.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/women/index.html.zh-tw.xhtml b/htdocs/imacat/links/women/index.html.zh-tw.xhtml new file mode 100644 index 0000000..02e34ae --- /dev/null +++ b/htdocs/imacat/links/women/index.html.zh-tw.xhtml @@ -0,0 +1,439 @@ + + + + + + + + + + + + + + + + + + + + + +女性主義、婦運 + + + + + + + +
    + +
    + + +

    女性主義、婦運

    + + + + + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/women/intl.html.en.html b/htdocs/imacat/links/women/intl.html.en.html new file mode 120000 index 0000000..a9116c6 --- /dev/null +++ b/htdocs/imacat/links/women/intl.html.en.html @@ -0,0 +1 @@ +intl.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/women/intl.html.en.xhtml b/htdocs/imacat/links/women/intl.html.en.xhtml new file mode 100644 index 0000000..b2cef54 --- /dev/null +++ b/htdocs/imacat/links/women/intl.html.en.xhtml @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + + + + + + + +Foreign Feminist Sites + + + + + + + +
    + +
    + + +

    Foreign Feminist Sites

    + + + + + +
    +

    Regiser your site

    + +
    +

    I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you.

    + +

    All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you.

    + +

    General commercial sites besides lesbian shops are not welcome.

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/women/intl.html.zh-cn.html b/htdocs/imacat/links/women/intl.html.zh-cn.html new file mode 120000 index 0000000..f80dd88 --- /dev/null +++ b/htdocs/imacat/links/women/intl.html.zh-cn.html @@ -0,0 +1 @@ +intl.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/women/intl.html.zh-cn.xhtml b/htdocs/imacat/links/women/intl.html.zh-cn.xhtml new file mode 100644 index 0000000..c28e7d9 --- /dev/null +++ b/htdocs/imacat/links/women/intl.html.zh-cn.xhtml @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + +国外妇运女性网站 + + + + + + + +
    + +
    + + +

    国外妇运女性网站

    + + + + + +
    +

    登录网站

    + +
    +

    我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!

    + +

    下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。

    + +

    除女同志商店外,旅舍恕不受理一般商业网站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/links/women/intl.html.zh-tw.html b/htdocs/imacat/links/women/intl.html.zh-tw.html new file mode 120000 index 0000000..9d6ff2b --- /dev/null +++ b/htdocs/imacat/links/women/intl.html.zh-tw.html @@ -0,0 +1 @@ +intl.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/links/women/intl.html.zh-tw.xhtml b/htdocs/imacat/links/women/intl.html.zh-tw.xhtml new file mode 100644 index 0000000..590bfe4 --- /dev/null +++ b/htdocs/imacat/links/women/intl.html.zh-tw.xhtml @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + +國外婦運女性網站 + + + + + + + +
    + +
    + + +

    國外婦運女性網站

    + + + + + +
    +

    登錄網站

    + +
    +

    我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!

    + +

    下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。

    + +

    除女同志商店外,旅舍恕不受理一般商業網站。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/linux/crashie.html.zh-cn.html b/htdocs/imacat/linux/crashie.html.zh-cn.html new file mode 120000 index 0000000..9a66694 --- /dev/null +++ b/htdocs/imacat/linux/crashie.html.zh-cn.html @@ -0,0 +1 @@ +crashie.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/linux/crashie.html.zh-cn.xhtml b/htdocs/imacat/linux/crashie.html.zh-cn.xhtml new file mode 100644 index 0000000..91c947f --- /dev/null +++ b/htdocs/imacat/linux/crashie.html.zh-cn.xhtml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + +Crash Your IE + + + + + + + +
    + +
    + + +

    Crash Your IE

    + + + +

    If you see this page, it means that you are not using internet explorer.

    + + + +
    + +
    + + + + diff --git a/htdocs/imacat/linux/crashie.html.zh-tw.html b/htdocs/imacat/linux/crashie.html.zh-tw.html new file mode 120000 index 0000000..5e2acc6 --- /dev/null +++ b/htdocs/imacat/linux/crashie.html.zh-tw.html @@ -0,0 +1 @@ +crashie.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/linux/crashie.html.zh-tw.xhtml b/htdocs/imacat/linux/crashie.html.zh-tw.xhtml new file mode 100644 index 0000000..818fd74 --- /dev/null +++ b/htdocs/imacat/linux/crashie.html.zh-tw.xhtml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + +Crash Your IE + + + + + + + +
    + +
    + + +

    Crash Your IE

    + + + +

    If you see this page, it means that you are not using internet explorer.

    + + + +
    + +
    + + + + diff --git a/htdocs/imacat/magicat/bin/acctcnvt b/htdocs/imacat/magicat/bin/acctcnvt new file mode 100755 index 0000000..25f1644 --- /dev/null +++ b/htdocs/imacat/magicat/bin/acctcnvt @@ -0,0 +1,1029 @@ +#! /usr/bin/perl -w +# Filename: acctcnvt +# Description: Perl script to convert the accounting data from CSV file into PostgreSQL +# Author: imacat +# Date: 2007-09-24 +# Copyright: (c) 2007 imacat + +use 5.006; +use strict; +use warnings; +use DBI qw(); +use Encode qw(encode decode FB_CROAK); +use Fcntl qw(:flock :seek); +use File::Basename qw(basename); +use Getopt::Long qw(GetOptions); +use Term::ReadKey qw(ReadMode); +# Prototype declaration +sub main(); +sub parse_args(); +sub try_login($); +sub newsn(); +sub table_cols($$); +sub usersn($$); +sub xfread($); +sub xfupdate($$); +sub get_accounting_data($); +sub acct_recs_to_trxs(@); +sub r2t_fundin($\@); +sub r2t_transfer($\@); +sub r2t_interest($\@); +sub r2t_phone($\@); +sub r2t_temp($\@); +sub r2t_miscin($\@); +sub r2t_expense($\@); +sub trxs_to_sqls($$@); +sub map_acct_subjs($); + +use vars qw($THIS_FILE $VERSION $VERBOSE); +$THIS_FILE = basename($0); +$VERSION = "1.14"; +$VERBOSE = 1; + +use vars qw($DEFUSER $USER $PGDATABASE $FILE $OUTFILE); +$DEFUSER = exists $ENV{"PGUSER"}? $ENV{"PGUSER"}: + (getpwuid($>) or die "$THIS_FILE: getpwuid: $!"); +$PGDATABASE = "wov"; +use constant IMPORTER => "importer"; + +use vars qw($VERMSG $SHORTHELP $HELPMSG); +$VERMSG = "$THIS_FILE v$VERSION by imacat "; +$SHORTHELP = "Try `$THIS_FILE --help' for more information."; +$HELPMSG = << "EOT"; +Usage: $THIS_FILE [options] source output +Convert the accounting data from CSV file into PostgreSQL + + -U,--username=NAME Database user name (default: $DEFUSER) + -d,--debug Display debug messages. Multiple --debug to debug more. + -q,--quiet Disable debug messages. An opposite that cancels the + effect of --debug. + -h,--help Display this help. + -v,--version Display version number. + source The source CSV file. + output File to output the result SQL script. + +EOT + +main; +exit 0; + +# main: Main program +sub main() { + local ($_, %_); + my ($dbh, $sql, $sth, $usersn, @recs, @trxs, @sqls); + + # Parse the arguments + parse_args; + + # Try to log in + $dbh = try_login "dbi:Pg:dbname=$PGDATABASE;"; + $sql = "SET NAMES 'utf8';\n"; + $dbh->do($sql) or die "$THIS_FILE: $sql: " . $dbh->errstr; + $sql = "LOCK TABLE acctsubj, users IN SHARE MODE;\n"; + $dbh->do($sql) or die "$THIS_FILE: $sql: " . $dbh->errstr; + $usersn = usersn $dbh, IMPORTER; + + # Read the CSV accounting data file + @recs = get_accounting_data $FILE; + # Convert the accounting records to accounting transactions + @trxs = acct_recs_to_trxs @recs; + # Convert the accounting transactions to SQL statements + @sqls = trxs_to_sqls $dbh, $usersn, @trxs; + # Output the SQL statements + $_ = join "", @sqls; + $_ = encode("UTF-8", $_, FB_CROAK); + xfupdate $OUTFILE, $_; + + $dbh->disconnect or die "$THIS_FILE: " . $dbh->errstr; + undef $dbh; + + print STDERR "Done. " . (time - $^T) . " seconds elapsed.\n" + if $VERBOSE > 0; + return; +} + +# parse_args: Parse the arguments +sub parse_args() { + local ($_, %_); + + # Get the arguments + eval { + local $SIG{"__WARN__"} = sub { die $_[0]; }; + Getopt::Long::Configure(qw(no_auto_abbrev bundling)); + GetOptions( "username|U=s"=>\$USER, + "debug|d+"=>\$VERBOSE, + "quiet|q"=>sub { $VERBOSE-- if $VERBOSE > 0; }, + "help|h"=>sub { print $HELPMSG; exit 0; }, + "version|v"=>sub { print "$VERMSG\n"; exit 0; }); + }; + die "$THIS_FILE: $@$SHORTHELP\n" if $@ ne ""; + + $| = 1 if $VERBOSE > 0; + + # Check the arguments + # The source CSV file + die "$THIS_FILE: Please specify the source CSV file\n$SHORTHELP\n" + if @ARGV == 0; + $FILE = shift @ARGV; + # The output file + die "$THIS_FILE: Please specify the output file\n$SHORTHELP\n" + if @ARGV == 0; + $OUTFILE = shift @ARGV; + + die "$THIS_FILE: Too many arguments: $ARGV[0]\n$SHORTHELP\n" + if @ARGV > 0; + + # The database user + $USER = $DEFUSER if !defined $USER; + + #binmode STDOUT, "encoding(big5)"; + + return; +} + +# try_login: Try to log in, and request the password when required. +sub try_login($) { + local ($_, %_); + my ($dsn, $dbh, $subseq, $passwd); + $dsn = $_[0]; + $subseq = 0; + # Try to log in + while (!defined($dbh = DBI->connect($dsn, $USER, $passwd, { PrintError => 0 }))) { + $_ = DBI->errstr; + if ($subseq) { + print STDERR $_; + sleep 5; + } + $subseq = 1; + # Obtain the current login user + $USER = $1 if !defined $USER && / failed for user "(.+?)"/; + # Disable console echo + ReadMode 2; + print STDERR defined $USER? "PostgreSQL password for $USER: ": + "PostgreSQL password: "; + $passwd = ; + print STDERR "\n"; + die "$THIS_FILE: Failed connecting to the PostgreSQL server\n" + if !defined $passwd; + chomp $passwd; + # Restore console echo status + ReadMode 0; + } + # Return the database handle + return $dbh; +} + +{ +my %SN; +# newsn: Generate a new random S/N +sub newsn() { + local ($_, %_); + do { + $_ = 100000000 + int rand 900000000; + } until !exists $SN{$_}; + return $_; +} +} + +{ +my %cols; +# table_cols: Obtain the columns of a specific SQL table +sub table_cols($$) { + local ($_, %_); + my ($dbh, $table, $sth); + ($dbh, $table) = @_; + + return @{$cols{$table}} if exists $cols{$table}; + + $sth = $dbh->column_info(undef, undef, $table, "%") + or die "$THIS_FILE: $table: " . $dbh->errstr; + @_ = qw(); + push @_, $_ while defined($_ = $sth->fetchrow_hashref); + undef $sth; + $cols{$table} = [ map $$_{"COLUMN_NAME"}, + sort { ${$a}{"ORDINAL_POSITION"} <=> ${$b}{"ORDINAL_POSITION"} } @_ ]; + s/"(.+)"/$1/ foreach @{$cols{$table}}; + + return @{$cols{$table}}; +} +} + +{ +my %USERSN; +# usersn: Find the S/N of the user +sub usersn($$) { + local ($_, %_); + my ($dbh, $id, $sql, $sth); + ($dbh, $id) = @_; + + return $USERSN{$id} if exists $USERSN{$id}; + + $sql = "SELECT sn FROM users" + . " WHERE id=" . $dbh->quote($id) . ";\n"; + $sth = $dbh->prepare($sql) or die "$THIS_FILE: $sql: " . $dbh->errstr; + $sth->execute or die "$THIS_FILE: $sql: " . $sth->errstr; + die "$THIS_FILE: $id: no such user in table \"users\"\n" + if $sth->rows != 1; + + return ($USERSN{$id} = ${$sth->fetch}[0]); +} +} + +# xfread: Read from a file +sub xfread($) { + local ($_, %_); + my ($FH, $file); + $file = $_[0]; + + # Return as lines + if (wantarray) { + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + @_ = <$FH>; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return @_; + + # A scalar file content + } else { + # Regular files + if (-f $file) { + my $size; + @_ = stat $file or die "$THIS_FILE: $file: $!"; + $size = $_[7]; + return "" if $size == 0; + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + read $FH, $_, $size or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return $_; + + # Special files + } else { + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + $_ = join "", <$FH>; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return $_; + } + } +} + +# xfupdate: Update a file +sub xfupdate($$) { + local ($_, %_); + my ($FH, $file, $content); + ($file, $content) = @_; + + if (-e $file) { + open $FH, "+<$file" or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + $_ = join "", <$FH>; + if ($_ ne $content) { + seek $FH, 0, SEEK_SET or die "$THIS_FILE: $file: $!"; + truncate $FH, 0 or die "$THIS_FILE: $file: $!"; + print $FH $content or die "$THIS_FILE: $file: $!"; + } + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + + } else { + open $FH, ">$file" or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_EX or die "$THIS_FILE: $file: $!"; + print $FH $content or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + } + return; +} + +# get_accounting_data: Parse the CSV file and obtain the accounting data +sub get_accounting_data($) { + local ($_, %_); + my ($file, @recs, @lines); + $file = $_[0]; + + # Obtain the record lines + $_ = xfread $file; + $_ = decode("Big5", $_, FB_CROAK); + s/\r\n/\n/g; + @lines = split /\n/, $_; + + # Check each line + # First line is title. We should omit it. + for (my $i = 1, @recs = qw(); $i < @lines; $i++) { + die "$THIS_FILE: Malformed line found:\n$lines[$i]\n" + if $lines[$i] !~ /^(\d{8}),(\d{4}-\d{2}-\d{2}),(\d{4}),((?:"[^"]+")?),(\d+),(\d+),(\d+),(\d+),((?:\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})?)$/; # " + %_ = ( + "no" => $1, + "date" => $2, + "subj" => $3, + "summary" => $4, + "cashin" => $5, + "cashout" => $6, + "bankin" => $7, + "bankout" => $8, + "lastmod" => $9, + ); + # The order + $_{"date"} =~ /^(\d{4})-(\d{2})-(\d{2})$/; + $_ = sprintf "%02d%02d%02d", $1 - 1911, $2, $3; + $_{"no"} =~ /^$_(\d{2})$/; + $_{"ord"} = $1 + 0; + $_{"no"} += 0; + # The subject + $_{"subj"} = map_acct_subjs $_{"subj"}; + die "$THIS_FILE: Unidentifiable subject:\n$lines[$i]\n" + if !defined $_{"subj"}; + # The summary + $_{"summary"} =~ s/^"([^"]+)"$/$1/; # " + $_{"summary"} = undef if $_{"summary"} eq ""; + # The amount + $_{$_} += 0 foreach qw(cashin cashout bankin bankout); + # The last-modified date + $_{"lastmod"} = undef if $_{"lastmod"} eq ""; + push @recs, {%_}; + } + # Sort them + @recs = sort { $$a{"no"} <=> $$b{"no"} } @recs; + + return @recs; +} + +# acct_recs_to_trxs: Convert the accounting records to accounting transactions +sub acct_recs_to_trxs(@) { + local ($_, %_); + my (@recs, @trxs, @dates); + @recs = @_; + # Obtain all the dates + %_ = map { $$_{"date"} => 1 } @recs; + @dates = sort keys %_; + @trxs = qw(); + foreach my $date (@dates) { + my (@remains, @toproc); + @remains = grep $$_{"date"} eq $date, @recs; + # The 74811/74812 incomes + push @trxs, r2t_fundin $date, @remains; + # The 11131 bank/cash transfer + push @trxs, r2t_transfer $date, @remains; + # The 7111 interest + push @trxs, r2t_interest $date, @remains; + # The 6256 phone fee + push @trxs, r2t_phone $date, @remains; + # The 1283/2283 temporarily payment/receipts + push @trxs, r2t_temp $date, @remains; + # There should not be any more bank record + @_ = grep $$_{"bankin"} > 0 || $$_{"bankout"} > 0, @remains; + die "$THIS_FILE: " . ${$_[0]}{"no"} . ": missing bank record" + if @_ > 0; + # The 1283/2283 other incomes + push @trxs, r2t_miscin $date, @remains; + # There should not be any more income record + @_ = grep $$_{"cashin"} > 0, @remains; + die "$THIS_FILE: " . ${$_[0]}{"no"} . ": missing cash income record" + if @_ > 0; + # All the expenses + push @trxs, r2t_expense $date, @remains; + # There should not be any more record + die "$THIS_FILE: " . ${$remains[0]}{"no"} . ": missing cash income record" + if @remains > 0; + } + + # Set the transaction order + %_ = map { $$_{"date"} => 1 } @trxs; + @dates = sort keys %_; + foreach my $date (@dates) { + @_ = grep $$_{"date"} eq $date, @trxs; + @_ = sort { ${${$$a{"recs"}}[0]}{"ord"} <=> ${${$$b{"recs"}}[0]}{"ord"} } @_; + for ($_ = 0; $_ < @_; $_++) { + ${$_[$_]}{"ord"} = $_ + 1; + } + } + # Sort the transaction + @trxs = sort { $$a{"date"} cmp $$b{"date"} || $$a{"ord"} <=> $$b{"ord"} } @trxs; + + # Set the record order + foreach my $trx (@trxs) { + my ($ob, $ol); + ($ob, $ol) = (1, 1); + foreach my $rec (@{$$trx{"recs"}}) { + if ($$rec{"type"} eq "credit") { + $$rec{"ord"} = $ob++; + } elsif ($$rec{"type"} eq "debit") { + $$rec{"ord"} = $ol++; + } + } + } + + return @trxs; +} + +# r2t_fundin: Convert 74811/74812 income records to transactions +sub r2t_fundin($\@) { + local ($_, %_); + my ($date, $recs, @toproc, @trxs, @cash, @bank, @mandy, @imacat); + my ($sum, $summary, $subj); + ($date, $recs) = @_; + @toproc = grep $$_{"subj"} =~ /^7481[12]$/, @$recs; + return if @toproc == 0; + @$recs = grep $$_{"subj"} !~ /^7481[12]$/, @$recs; + + # Only to a single deposit + @cash = grep $$_{"cashin"} > 0, @toproc; + @bank = grep $$_{"bankin"} > 0, @toproc; + # Only cash income + if (@bank == 0) { + @_ = @cash; + $sum = 0; + foreach (@_) { + $$_{"type"} = "credit"; + $$_{"credit"} = 1; + $$_{"amount"} = $$_{"cashin"}; + $sum += $$_{"amount"}; + } + push @_, { + "no" => 99999999, + "date" => $date, + "type" => "debit", + "credit" => 0, + "ord" => 1, + "subj" => 1111, + "summary" => undef, + "amount" => $sum, + "lastmod" => undef, + }; + return {"date" => $date, "recs" => [@_]}; + + # Only bank income + } elsif (@cash == 0) { + @_ = @bank; + $sum = 0; + foreach (@_) { + $$_{"type"} = "credit"; + $$_{"credit"} = 1; + $$_{"amount"} = $$_{"bankin"}; + $sum += $$_{"amount"}; + } + push @_, { + "no" => 99999999, + "date" => $date, + "type" => "debit", + "credit" => 0, + "ord" => 1, + "subj" => 11131, + "summary" => undef, + "amount" => $sum, + "lastmod" => undef, + }; + return {"date" => $date, "recs" => [@_]}; + } + + # Only from a single person + @mandy = grep $$_{"subj"} == 74811, @toproc; + @imacat = grep $$_{"subj"} == 74812, @toproc; + # Only from mandy + if (@imacat == 0) { + @_ = @mandy; + $sum = 0; + $summary = ${$_[0]}{"summary"}; + foreach (@_) { + $$_{"type"} = "debit"; + $$_{"credit"} = 0; + if ($$_{"cashin"} > 0) { + $$_{"subj"} = 1111; + $$_{"amount"} = $$_{"cashin"}; + } elsif ($$_{"bankin"} > 0) { + $$_{"subj"} = 11131; + $$_{"amount"} = $$_{"bankin"}; + } + $$_{"summary"} = undef; + $sum += $$_{"amount"}; + } + push @_, { + "no" => 99999999, + "date" => $date, + "type" => "credit", + "credit" => 1, + "ord" => 1, + "subj" => 74811, + "summary" => $summary, + "amount" => $sum, + "lastmod" => undef, + }; + return {"date" => $date, "recs" => [@_]}; + + # Only from imacat + } elsif (@mandy == 0) { + @_ = @imacat; + $sum = 0; + $summary = ${$_[0]}{"summary"}; + foreach (@_) { + $$_{"type"} = "debit"; + $$_{"credit"} = 0; + if ($$_{"cashin"} > 0) { + $$_{"subj"} = 1111; + $$_{"amount"} = $$_{"cashin"}; + } elsif ($$_{"bankin"} > 0) { + $$_{"subj"} = 11131; + $$_{"amount"} = $$_{"bankin"}; + } + $$_{"summary"} = undef; + $sum += $$_{"amount"}; + } + push @_, { + "no" => 99999999, + "date" => $date, + "type" => "credit", + "credit" => 1, + "ord" => 1, + "subj" => 74812, + "summary" => $summary, + "amount" => $sum, + "lastmod" => undef, + }; + return {"date" => $date, "recs" => [@_]}; + } + + # Others + # In fact only on 2000-06-18 with 2 cross records + @trxs = qw(); + foreach (@toproc) { + $$_{"type"} = "credit"; + $$_{"credit"} = 1; + if ($$_{"cashin"} > 0) { + $subj = 1111; + $$_{"amount"} = $$_{"cashin"}; + } elsif ($$_{"bankin"} > 0) { + $subj = 11131; + $$_{"amount"} = $$_{"bankin"}; + } + @_ = ($_); + push @_, { + "no" => 99999999, + "date" => $date, + "type" => "debit", + "credit" => 0, + "ord" => 1, + "subj" => $subj, + "summary" => undef, + "amount" => $$_{"amount"}, + "lastmod" => $$_{"lastmod"}, + }; + push @trxs, {"date" => $date, "recs" => [@_]}; + } + return @trxs; +} + +# r2t_transfer: Convert 74811/74812 transfer records to transactions +sub r2t_transfer($\@) { + local ($_, %_); + my ($date, $recs, @toproc, @trxs, $trans, $cash, $fee); + ($date, $recs) = @_; + @toproc = grep $$_{"subj"} == 11131 || ($$_{"subj"} == 6288 && $$_{"bankout"} > 0), @$recs; + return if @toproc == 0; + @$recs = grep(!($$_{"subj"} == 11131 || ($$_{"subj"} == 6288 && $$_{"bankout"} > 0)), @$recs); + + @_ = grep $$_{"subj"} == 6288, @toproc; + # Fortunately, all transfers with fee happen on days with only one transfer + if (@_ > 0) { + die "$THIS_FILE: more than one transfer fee on $date" if @_ > 1; + $fee = $_[0]; + $$fee{"type"} = "debit"; + $$fee{"credit"} = 0; + $$fee{"amount"} = $$fee{"bankout"}; + @_ = grep $$_{"subj"} == 11131, @toproc; + die "$THIS_FILE: more than one transfer with transfer fee on $date" if @_ > 1; + die "$THIS_FILE: no transfer found with transfer fee on $date" if @_ < 1; + $trans = $_[0]; + $$trans{"type"} = "credit"; + $$trans{"credit"} = 1; + $$trans{"amount"} = $$trans{"bankout"} + $$fee{"bankout"}; + $cash = { + "no" => 99999999, + "date" => $date, + "type" => "debit", + "credit" => 0, + "ord" => 1, + "subj" => 1111, + "summary" => undef, + "amount" => $$trans{"bankout"}, + "lastmod" => undef, + }; + return {"date" => $date, "recs" => [$trans, $cash, $fee]}; + } + + @trxs = qw(); + foreach $trans (@toproc) { + if ($$trans{"bankout"} > 0) { + $$trans{"type"} = "credit"; + $$trans{"credit"} = 1; + $$trans{"amount"} = $$trans{"bankout"}; + $cash = { + "no" => 99999999, + "date" => $date, + "type" => "debit", + "credit" => 0, + "ord" => 1, + "subj" => 1111, + "summary" => undef, + "amount" => $$trans{"bankout"}, + "lastmod" => undef, + }; + } elsif ($$trans{"bankin"} > 0) { + $$trans{"type"} = "debit"; + $$trans{"credit"} = 0; + $$trans{"amount"} = $$trans{"bankin"}; + $cash = { + "no" => 99999999, + "date" => $date, + "type" => "credit", + "credit" => 1, + "ord" => 1, + "subj" => 1111, + "summary" => undef, + "amount" => $$trans{"bankin"}, + "lastmod" => undef, + }; + } + push @trxs, {"date" => $date, "recs" => [$trans, $cash]}; + } + return @trxs; +} + +# r2t_interest: Convert 7111 interest records to transactions +sub r2t_interest($\@) { + local ($_, %_); + my ($date, $recs, @toproc, @trxs, $intr, $bank); + ($date, $recs) = @_; + @toproc = grep $$_{"subj"} == 7111, @$recs; + return if @toproc == 0; + @$recs = grep $$_{"subj"} != 7111, @$recs; + + # It is impossible to have more than one record in a single day + $intr = $toproc[0]; + $$intr{"type"} = "credit"; + $$intr{"credit"} = 1; + $$intr{"amount"} = $$intr{"bankin"}; + $bank = { + "no" => 99999999, + "date" => $date, + "type" => "debit", + "credit" => 0, + "ord" => 1, + "subj" => 11131, + "summary" => undef, + "amount" => $$intr{"bankin"}, + "lastmod" => undef, + }; + return {"date" => $date, "recs" => [$intr, $bank]}; +} + +# r2t_phone: Convert 6256 phone fee records to transactions +sub r2t_phone($\@) { + local ($_, %_); + my ($date, $recs, @toproc, @trxs, $sum, $credit); + ($date, $recs) = @_; + @toproc = grep $$_{"subj"} == 6256, @$recs; + return if @toproc == 0; + @$recs = grep $$_{"subj"} != 6256, @$recs; + + # 2 records on one day only on 2007-05-22, both paid with cash + # We shall adjust it later. Currently this prevents mistakes. + $sum = 0; + foreach (@toproc) { + $$_{"type"} = "debit"; + $$_{"credit"} = 0; + $$_{"amount"} = $$_{"cashout"} + $$_{"bankout"}; + $sum += $$_{"amount"}; + } + $credit = { + "no" => 99999999, + "date" => $date, + "type" => "credit", + "credit" => 1, + "ord" => 1, + "subj" => 1111, + "summary" => undef, + "amount" => $sum, + "lastmod" => undef, + }; + $$credit{"subj"} = 11131 if ${$toproc[0]}{"bankout"} > 0; + return {"date" => $date, "recs" => [@toproc, $credit]}; +} + +# r2t_temp: Convert 1283/2283 temporarily payment/receipts +sub r2t_temp($\@) { + local ($_, %_); + my ($date, $recs, @toproc, @trxs, $sup); + ($date, $recs) = @_; + @toproc = grep $$_{"subj"} =~ /^[12]283$/, @$recs; + return if @toproc == 0; + @$recs = grep $$_{"subj"} !~ /^[12]283$/, @$recs; + + @trxs = qw(); + foreach (@toproc) { + if ($$_{"cashin"} > 0) { + $$_{"type"} = "credit"; + $$_{"credit"} = 1; + $$_{"amount"} = $$_{"cashin"}; + $sup = { + "no" => 99999999, + "date" => $date, + "type" => "debit", + "credit" => 0, + "ord" => 1, + "subj" => 1111, + "summary" => undef, + "amount" => $$_{"amount"}, + "lastmod" => undef, + }; + } elsif ($$_{"bankin"} > 0) { + $$_{"type"} = "credit"; + $$_{"credit"} = 1; + $$_{"amount"} = $$_{"bankin"}; + $sup = { + "no" => 99999999, + "date" => $date, + "type" => "debit", + "credit" => 0, + "ord" => 1, + "subj" => 11131, + "summary" => undef, + "amount" => $$_{"amount"}, + "lastmod" => undef, + }; + } elsif ($$_{"cashout"} > 0) { + $$_{"type"} = "debit"; + $$_{"credit"} = 0; + $$_{"amount"} = $$_{"cashout"}; + $sup = { + "no" => 99999999, + "date" => $date, + "type" => "credit", + "credit" => 1, + "ord" => 1, + "subj" => 1111, + "summary" => undef, + "amount" => $$_{"amount"}, + "lastmod" => undef, + }; + } elsif ($$_{"bankout"} > 0) { + $$_{"type"} = "debit"; + $$_{"credit"} = 0; + $$_{"amount"} = $$_{"bankout"}; + $sup = { + "no" => 99999999, + "date" => $date, + "type" => "credit", + "credit" => 1, + "ord" => 1, + "subj" => 11131, + "summary" => undef, + "amount" => $$_{"amount"}, + "lastmod" => undef, + }; + } + push @trxs, {"date" => $date, "recs" => [$_, $sup]}; + } + return @trxs; +} + +# r2t_miscin: Convert 7488 other incomes +sub r2t_miscin($\@) { + local ($_, %_); + my ($date, $recs, @toproc, @trxs, $cash); + ($date, $recs) = @_; + @toproc = grep $$_{"subj"} == 7488, @$recs; + return if @toproc == 0; + @$recs = grep $$_{"subj"} != 7488, @$recs; + + # Sanity check + @_ = grep $$_{"cashout"} > 0 || $$_{"bankin"} > 0 || $$_{"bankout"} > 0, @toproc; + die "$THIS_FILE: " . ${$_[0]}{"no"} . ": not cash income" if @_ > 0; + @trxs = qw(); + foreach (@toproc) { + $$_{"type"} = "credit"; + $$_{"credit"} = 1; + $$_{"amount"} = $$_{"cashin"}; + $cash = { + "no" => 99999999, + "date" => $date, + "type" => "debit", + "credit" => 0, + "ord" => 1, + "subj" => 1111, + "summary" => undef, + "amount" => $$_{"amount"}, + "lastmod" => undef, + }; + push @trxs, {"date" => $date, "recs" => [$_, $cash]}; + } + return @trxs; +} + +# r2t_expense: Convert expenses +sub r2t_expense($\@) { + local ($_, %_); + my ($date, $recs, @toproc, $sum, $cash); + ($date, $recs) = @_; + @toproc = grep $$_{"subj"} =~ /^(?:6\d{3}|1441)/, @$recs; + return if @toproc == 0; + @$recs = grep $$_{"subj"} !~ /^(?:6\d{3}|1441)/, @$recs; + + # Sanity check + @_ = grep $$_{"cashin"} > 0 || $$_{"bankin"} > 0 || $$_{"bankout"} > 0, @toproc; + die "$THIS_FILE: " . ${$_[0]}{"no"} . ": not expense" if @_ > 0; + # We merge them into one + $sum = 0; + foreach (@toproc) { + $$_{"type"} = "debit"; + $$_{"credit"} = 0; + $$_{"amount"} = $$_{"cashout"}; + $sum += $$_{"amount"}; + } + $cash = { + "no" => 99999999, + "date" => $date, + "type" => "credit", + "credit" => 1, + "ord" => 1, + "subj" => 1111, + "summary" => undef, + "amount" => $sum, + "lastmod" => undef, + }; + return {"date" => $date, "recs" => [@toproc, $cash]}; +} + +# trxs_to_sqls: Convert the accounting transactions to SQL statements +sub trxs_to_sqls($$@) { + local ($_, %_); + my ($dbh, $usersn, @trxs, @sqls, @colstrx, @colsrec, $trxsn, %subjs); + my ($sql, $sth, $count, $row); + ($dbh, $usersn, @trxs) = @_; + + @sqls = qw(); + push @sqls, "SET NAMES 'utf8';\n"; + push @sqls, "START TRANSACTION;\n"; + push @sqls, "LOCK TABLE accttrx, acctrecs, mtime IN ACCESS EXCLUSIVE MODE;\n"; + push @sqls, "DELETE FROM acctrecs;\n"; + push @sqls, "DELETE FROM accttrx;\n"; + push @sqls, "\n"; + + # Obtain all the subjects + %_ = qw(); + foreach my $trx (@trxs) { + %_ = (%_, map { $$_{"subj"} => 1 } @{$$trx{"recs"}}); + } + $sql = "SELECT sn, code FROM acctsubj" + . " WHERE " . join(" OR ", map "code='$_'", sort keys %_) . ";\n"; + $sth = $dbh->prepare($sql) or die "$THIS_FILE: $sql: " . $dbh->errstr; + $sth->execute or die "$THIS_FILE: $sql: " . $sth->errstr; + $count = $sth->rows; + for ($_ = 0, %subjs = qw(); $_ < $count; $_++) { + $row = $sth->fetchrow_hashref; + $subjs{$$row{"code"}} = $$row{"sn"}; + } + + @colstrx = table_cols $dbh, "accttrx"; + @colsrec = table_cols $dbh, "acctrecs"; + foreach my $trx (@trxs) { + $$trx{"sn"} = newsn; + $$trx{"created"} = $$trx{"date"} . " 00:00:00"; + $$trx{"updated"} = $$trx{"created"}; + $$trx{"updated"} = (reverse sort map $$_{"lastmod"}, @_)[0] + if (@_ = grep defined $$_{"lastmod"}, @{$$trx{"recs"}}) > 0; + @_ = qw(); + foreach (@colstrx) { + if (/^sn$/) { + push @_, [$_, $$trx{$_}]; + } elsif (/^(?:created|updated)$/) { + push @_, [$_, "'" . $$trx{$_} . "'"]; + } elsif (/^(?:createdby|updatedby)$/) { + push @_, [$_, $usersn]; + } elsif (/^ord$/) { + push @_, [$_, $$trx{$_}]; + } elsif (/^date$/) { + push @_, [$_, "'" . $$trx{$_} . "'"]; + } elsif (/^note$/) { + push @_, [$_, "NULL"]; + } + } + push @sqls, "INSERT INTO accttrx" + . " (" . join(", ", map $$_[0], @_) . ") VALUES" + . " (" . join(", ", map $$_[1], @_) . ");\n"; + foreach my $rec (@{$$trx{"recs"}}) { + $$rec{"sn"} = newsn; + $$rec{"created"} = $$trx{"created"}; + $$rec{"updated"} = defined $$rec{"lastmod"}? + $$rec{"lastmod"}: $$rec{"created"}; + @_ = qw(); + foreach (@colsrec) { + if (/^sn$/) { + push @_, [$_, $$rec{$_}]; + } elsif (/^(?:created|updated)$/) { + push @_, [$_, "'" . $$rec{$_} . "'"]; + } elsif (/^(?:createdby|updatedby)$/) { + push @_, [$_, $usersn]; + } elsif (/^trx$/) { + push @_, [$_, $$trx{"sn"}]; + } elsif (/^credit$/) { + push @_, [$_, $$rec{$_}? "TRUE": "FALSE"]; + } elsif (/^(?:ord|amount)$/) { + push @_, [$_, $$rec{$_}]; + } elsif (/^subj$/) { + push @_, [$_, $subjs{$$rec{$_}}]; + } elsif (/^summary$/) { + push @_, [$_, $dbh->quote($$rec{$_})]; + } + } + foreach (@_) { + $$_[1] = "(undef)" if !defined $$_[1]; + } + push @sqls, "INSERT INTO acctrecs" + . " (" . join(", ", map $$_[0], @_) . ") VALUES" + . " (" . join(", ", map $$_[1], @_) . ");\n"; + } + push @sqls, "\n"; + } + + push @sqls, "UPDATE mtime SET mtime=now() WHERE tabname='accttrx';\n"; + push @sqls, "UPDATE mtime SET mtime=now() WHERE tabname='acctrecs';\n"; + push @sqls, "COMMIT;\n"; + push @sqls, "ANALYZE accttrx;\n"; + push @sqls, "ANALYZE acctrecs;\n"; + + return @sqls; +} + +# map_acct_subjs: Map the accounting subjects +# Custom subjects: +# 11131: Ȧs-ls +# 74811: @Pͬ-P +# 74812: @Pͬ-hC +sub map_acct_subjs($) { + local ($_, %_); + $_ = $_[0]; + # { + if ($_ eq 1100) { + return 1111; + # Ȧs-ls + } elsif ($_ eq 1103) { + return 11131; + # ȥI + } elsif ($_ eq 1281) { + return 1283; + # q] + } elsif ($_ eq 1541) { + return 1441; + # Ȧ + } elsif ($_ eq 2281) { + return 2283; + # @Pͬ-P + } elsif ($_ eq 4111) { + return 74811; + # @Pͬ-hC + } elsif ($_ eq 4112) { + return 74812; + # X + } elsif ($_ eq 6111) { + return 6252; + # lqO + } elsif ($_ eq 6115) { + return 6256; + # µO + } elsif ($_ eq 6116) { + return 6257; + # qO + } elsif ($_ eq 6118) { + return 6261; + # ڶO + } elsif ($_ eq 6120) { + return 6264; + # 뭹O + } elsif ($_ eq 6127) { + return 6272; + # qO + } elsif ($_ eq 6134) { + return 6254; + # TֶO + } elsif ($_ eq 6141) { + return 6273; + # + } elsif ($_ eq 6188) { + return 6288; + # QJ + } elsif ($_ eq 7110) { + return 7111; + # 䥦J + } elsif ($_ eq 7480) { + return 7488; + # Non-sense + } else { + return undef; + } +} + +__END__ diff --git a/htdocs/imacat/magicat/bin/gbcnvt b/htdocs/imacat/magicat/bin/gbcnvt new file mode 100755 index 0000000..9ccf431 --- /dev/null +++ b/htdocs/imacat/magicat/bin/gbcnvt @@ -0,0 +1,358 @@ +#! /usr/bin/perl -w +# Filename: gbcnvt +# Description: Perl script to convert the database format +# Author: imacat +# Date: 2003-04-06 +# Copyright: (c) 2003-2007 imacat + +use 5.008; +use strict; +use warnings; +use Encode qw(from_to FB_CROAK); +use Fcntl qw(:flock :seek); +use File::Basename qw(basename); +use Getopt::Long qw(GetOptions); +# Prototype declaration +sub main(); +sub parse_args(); +sub convert_dbfile(); +sub convert_entry($); +sub find_charset(%); +sub dhc($); +sub h($); +sub dh($); +sub newsn(); +sub xfread($); +sub xfupdate($$); + +use vars qw($THIS_FILE $VERSION $VERBOSE); +$THIS_FILE = basename($0); +$VERSION = "2.03"; +$VERBOSE = 1; + +use vars qw($SOURCE $CURRENT $RESULT); +$SOURCE = "/srv/www/htdocs/emily/data/guestbook.txt"; +$CURRENT = "/srv/www/htdocs/emily/data/guestbook.dat"; +$RESULT = "/tmp/guestbook.dat"; +use constant SN_LEN => 9; + +use vars qw(@COLUMNS @TRY_CHARSETS %SN $DATE $CURENC); +@COLUMNS = qw(name identity location email url message); +@TRY_CHARSETS = qw(US-ASCII Big5 GB2312 Shift-JIS Big5-HKSCS GB18030); + +use vars qw(%SPECIAL_CHARSETS); +%SPECIAL_CHARSETS = ( + "2002-06-06 13:15:09" => "GB2312", +); + +use vars qw($VERMSG $SHORTHELP $HELPMSG); +$VERMSG = "$THIS_FILE v$VERSION by imacat "; +$SHORTHELP = "Try `$THIS_FILE --help' for more information."; +$HELPMSG = << "EOT"; +Usage: $THIS_FILE [options] +Convert the database format + + -d,--debug Display debug messages. Multiple --debug to debug more. + -q,--quiet Disable debug messages. An opposite that cancels the + effect of --debug. + -h,--help Display this help. + -v,--version Display version number. + +EOT + +main; +exit 0; + +# main: Main program +sub main() { + local ($_, %_); + + # Parse the arguments + parse_args; + + # No longer a working script + print "Mission completed long time ago. Program stopped to avoid further problems.\n"; + return; + + convert_dbfile; + + print STDERR "Done. " . (time - $^T) . " seconds elapsed.\n" + if $VERBOSE > 0; + return; +} + +# parse_args: Parse the arguments +sub parse_args() { + local ($_, %_); + + # Get the arguments + eval { + local $SIG{"__WARN__"} = sub { die $_[0]; }; + Getopt::Long::Configure(qw(no_auto_abbrev bundling)); + GetOptions( "debug|d+"=>\$VERBOSE, + "quiet|q"=>sub { $VERBOSE-- if $VERBOSE > 0; }, + "help|h"=>sub { print $HELPMSG; exit 0; }, + "version|v"=>sub { print "$VERMSG\n"; exit 0; }); + }; + die "$THIS_FILE: $@$SHORTHELP\n" if $@ ne ""; + + # Check the arguments + # We have no arguments + die "$THIS_FILE: Too many arguments: $ARGV[0]\n$SHORTHELP\n" + if @ARGV > 0; + + return; +} + +# convert_dbfile: Convert a database file +sub convert_dbfile() { + local ($_, %_); + + # Gather current S/N + $_ = xfread $CURRENT; + $SN{$1} = 1 while s/(\d+)<\/col>//i; + + # Read the source file + $_ = xfread $SOURCE; + + # Find the entries + s/^\[Guestbook Entry&\]\n//; + @_ = split /\n+\n\[Guestbook Entry&\]\n/, $_; + # Convert each entry + $_ = convert_entry $_ foreach @_; + # Compose the db file + $_ = "\n" . join("", @_) . "
    \n"; + + # Output the result file + xfupdate $RESULT, $_; + + return; +} + +# convert_entry: Convert an entry +sub convert_entry($) { + local ($_, %_); + my ($source, $charset, $before, $after); + $_ = $_[0]; + + # Preserve the source + $source = $_; + + # Loop for columns + $_{$1} = dh($2) while s/^([^\n=]+)=([^\n]+)\n//; + $_{$1} = dh($2) if s/^(message_orig)=\n+(.+)\n(message=)/$3/s; + $_{$1} = dh($2) if s/^(message)=\n+(.+)//s; + # Check the required date first + warn "$THIS_FILE: WARNING: no date:\n$source\n" if !exists $_{"date"}; + $DATE = $_{"date"}; + + # Check the lost text + warn "$THIS_FILE: WARNING: $DATE:\nunexpected text:\n$_\n" if $_ ne ""; + + # Check the other required columns + warn "$THIS_FILE: WARNING: $DATE:\nno ip:\n$source\n" if !exists $_{"ip"}; + warn "$THIS_FILE: WARNING: $DATE:\nno message:\n$source\n" if !exists $_{"message"}; + + # Replace the columns with the _orig version, if that exists + foreach (@COLUMNS) { + next unless exists $_{$_}; + next unless exists $_{$_ . "_orig"}; + $_{$_} = $_{$_ . "_orig"}; + delete $_{$_ . "_orig"}; + } + $charset = find_charset %_; + if (!defined $charset) { + warn "$THIS_FILE: WARNING: $DATE:\nunknown character set.\n"; + } else { + foreach (@COLUMNS) { + next unless exists $_{$_}; + # Skip US-ASCII-only columns + if ($_{$_} =~ /[\x80-\xFF]/) { + $before = $_{$_}; + from_to($_{$_}, $charset, "UTF-8", FB_CROAK); + $after = $_{$_}; + warn "$THIS_FILE: WARNING: $DATE: $charset: $_:\nnot converted.\n" + if $before eq $after; + } + $_{$_} = dhc $_{$_}; + } + } + + # Compose the columns + @_ = qw(); + push @_, "" . h(newsn()) . ""; + push @_, "" . h($_{"date"}) . ""; + delete $_{"date"}; + push @_, "" . h($_{"ip"}) . ""; + delete $_{"ip"}; + if (exists $_{"host"}) { + push @_, "" . h($_{"host"}) . ""; + delete $_{"host"}; + } + foreach (@COLUMNS) { + next unless exists $_{$_}; + push @_, "" . h($_{$_}) . ""; + delete $_{$_}; + } + # Check for lost columns + warn "$THIS_FILE: WARNING: $DATE:\nunexpected column: $_\n" foreach sort keys %_; + + $_ = "\n" . join("\n", @_) . "\n\n"; + + return $_; +} + +# find_charset: Try every charset specified and return the most appropriate one +sub find_charset(%) { + local ($_, %_); + my (%source, $charset, $right_charset); + %source = @_; + # Special rules + return $SPECIAL_CHARSETS{$DATE} if exists $SPECIAL_CHARSETS{$DATE}; + foreach $charset (@TRY_CHARSETS) { + %_ = %source; + $right_charset = 1; + foreach (@COLUMNS) { + next unless exists $_{$_}; + # Try to convert from this character set to UTF-8 first + eval { + from_to($_{$_}, $charset, "UTF-8", FB_CROAK); + }; + # Something wrong here + if ($@ ne "") { + $right_charset = 0; + last; + } + } + return $charset if $right_charset; + } + # None found, return nothing + return; +} + +# dhc: De-escape HTML character entities +sub dhc($) { + local ($_, %_); + my ($text); + $text = $_[0]; + $text =~ s/&#(\d{1,5});/ + $_ = pack "v", $1; + from_to($_, "UTF-16LE", "UTF-8", FB_CROAK); + $_; /eg; + return $text; +} + +# h: Escape the HTML characters +sub h($) { + local ($_, %_); + $_ = $_[0]; + return "" if !defined $_; + s/&/&/g; + s//>/g; + s/"/"/g; # (xgettext) " + return $_; +} + +# dh: De-escape the HTML characters +sub dh($) { + local ($_, %_); + $_ = $_[0]; + return "" if !defined $_; + s/"/"/g; # (xgettext) " + s/>/>/g; + s/</; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return @_; + + # A scalar file content + } else { + # Regular files + if (-f $file) { + my $size; + @_ = stat $file or die "$THIS_FILE: $file: $!"; + $size = $_[7]; + return "" if $size == 0; + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + read $FH, $_, $size or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return $_; + + # Special files + } else { + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + $_ = join "", <$FH>; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return $_; + } + } +} + +# xfupdate: Update a file +sub xfupdate($$) { + local ($_, %_); + my ($FH, $file, $content); + ($file, $content) = @_; + + if (-e $file) { + open $FH, "+<$file" or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + $_ = join "", <$FH>; + if ($_ ne $content) { + seek $FH, 0, SEEK_SET or die "$THIS_FILE: $file: $!"; + truncate $FH, 0 or die "$THIS_FILE: $file: $!"; + print $FH $content or die "$THIS_FILE: $file: $!"; + } + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + + } else { + open $FH, ">$file" or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_EX or die "$THIS_FILE: $file: $!"; + print $FH $content or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + } + return; +} + +__END__ diff --git a/htdocs/imacat/magicat/bin/gbcnvt2 b/htdocs/imacat/magicat/bin/gbcnvt2 new file mode 100755 index 0000000..cce7730 --- /dev/null +++ b/htdocs/imacat/magicat/bin/gbcnvt2 @@ -0,0 +1,217 @@ +#! /usr/bin/perl -w +# Filename: gbcnvt2 +# Description: Perl script to convert the guestbook from data file into MySQL +# Author: imacat +# Date: 2004-03-27 +# Copyright: (c) 2004-2007 imacat + +use 5.006; +use strict; +use warnings; +use DBI qw(); +use Fcntl qw(:flock); +use File::Basename qw(basename); +use Getopt::Long qw(GetOptions); +use Term::ReadKey qw(ReadMode); +# Prototype declaration +sub main(); +sub parse_args(); +sub try_login($); +sub dh($); +sub xfread($); + +use vars qw($THIS_FILE $VERSION $VERBOSE); +$THIS_FILE = basename($0); +$VERSION = "2.05"; +$VERBOSE = 1; + +use vars qw($USER $FILE $MYSQL_DB $MYSQL_TABLE); +$MYSQL_DB = "emily"; +$MYSQL_TABLE = "guestbook"; +$FILE = "/srv/www/htdocs/$MYSQL_DB/magicat/data/$MYSQL_TABLE.dat"; + +use vars qw($VERMSG $SHORTHELP $HELPMSG); +$VERMSG = "$THIS_FILE v$VERSION by imacat "; +$SHORTHELP = "Try `$THIS_FILE --help' for more information."; +$HELPMSG = << "EOT"; +Usage: $THIS_FILE [options] +Convert the guestbook from data file into MySQL + + -u,--user uname User for logging into MySQL if not current user. + -d,--debug Display debug messages. Multiple --debug to debug more. + -q,--quiet Disable debug messages. An opposite that cancels the + effect of --debug. + -h,--help Display this help. + -v,--version Display version number. + +EOT + +main; +exit 0; + +# main: Main program +sub main() { + local ($_, %_); + my ($FH, $name, $val, @cols); + my ($dsn, $dbh, $sql, $sth); + + # Parse the arguments + parse_args; + + # No longer a working script + print "Mission completed long time ago. Program stopped to avoid further problems.\n"; + return; + + # Read the data file + $_ = xfread $FILE; + + # Try to log in + $dbh = try_login "dbi:mysql:database=$MYSQL_DB;"; + + $sql = "LOCK TABLE $MYSQL_TABLE WRITE;\n"; + $dbh->do($sql) or die "$THIS_FILE: $sql: " . $dbh->errstr; + + s/^\s*]*>\s*//; + s/\s*<\/table>\s*$//; + foreach (split /(?<=<\/record>)\s*(?=)/, $_) { + %_ = qw(); + s/^\s*]*>\s*//; + s/\s*<\/record>\s*$//; + foreach (split /(?<=<\/col>)\s*(?=]*>([^<]+)<\/col>$/; + ($name, $val) = ($1, $2); + $_{dh($name)} = dh($val); + } + + @cols = qw(); + foreach (sort keys %_) { + push @cols, [$_, $dbh->quote($_{$_})]; + } + $sql = "INSERT INTO $MYSQL_TABLE" + . " (" . join(", ", map $$_[0], @cols) . ") VALUES" + . " (" . join(", ", map $$_[1], @cols) . ");\n"; + $sth = $dbh->prepare($sql) or die "$THIS_FILE: $sql: " . $dbh->errstr; + $sth->execute or die "$THIS_FILE: $sql: " . $sth->errstr; + } + + $sql = "UNLOCK TABLE;\n"; + $dbh->do($sql) or die "$THIS_FILE: $sql: " . $dbh->errstr; + + $dbh->disconnect or die "$THIS_FILE: " . $dbh->errstr; + undef $dbh; + + print STDERR "Done. " . (time - $^T) . " seconds elapsed.\n" + if $VERBOSE > 0; + return; +} + +# parse_args: Parse the arguments +sub parse_args() { + local ($_, %_); + + # Get the arguments + eval { + local $SIG{"__WARN__"} = sub { die $_[0]; }; + Getopt::Long::Configure(qw(no_auto_abbrev bundling)); + GetOptions( "user|u=s"=>\$USER, + "debug|d+"=>\$VERBOSE, + "quiet|q"=>sub { $VERBOSE-- if $VERBOSE > 0; }, + "help|h"=>sub { print $HELPMSG; exit 0; }, + "version|v"=>sub { print "$VERMSG\n"; exit 0; }); + }; + die "$THIS_FILE: $@$SHORTHELP\n" if $@ ne ""; + + # Check the arguments + # We have no arguments + die "$THIS_FILE: Too many arguments: $ARGV[0]\n$SHORTHELP\n" + if @ARGV > 0; + + return; +} + +# try_login: Try to log in, and request the password when required. +sub try_login($) { + local ($_, %_); + my ($dsn, $dbh, $subseq, $passwd); + $dsn = $_[0]; + $subseq = 0; + # Try to log in + while (!defined($dbh = DBI->connect($dsn, $USER, $passwd, { PrintError => 0 }))) { + $_ = DBI->errstr; + if ($subseq) { + print STDERR "$_\n"; + sleep 5; + } + $subseq = 1; + # Obtain the current login user + $USER = $1 if !defined $USER && / denied for user '(.+?)'\@'.+?'/; + # Disable console echo + ReadMode 2; + print STDERR defined $USER? "MySQL password for $USER: ": + "MySQL password: "; + $passwd = ; + print STDERR "\n"; + die "$THIS_FILE: Failed connecting to the MySQL server\n" + if !defined $passwd; + chomp $passwd; + # Restore console echo status + ReadMode 0; + } + # Return the database handle + return $dbh; +} + +# dh: De-escape the HTML special characters +sub dh($) { + local ($_, %_); + $_ = $_[0]; + s/"/"/g; + s/>/>/g; + s/</; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return @_; + + # A scalar file content + } else { + # Regular files + if (-f $file) { + my $size; + @_ = stat $file or die "$THIS_FILE: $file: $!"; + $size = $_[7]; + return "" if $size == 0; + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + read $FH, $_, $size or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return $_; + + # Special files + } else { + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + $_ = join "", <$FH>; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return $_; + } + } +} + +__END__ diff --git a/htdocs/imacat/magicat/bin/gbcnvt3 b/htdocs/imacat/magicat/bin/gbcnvt3 new file mode 100755 index 0000000..0a77e4a --- /dev/null +++ b/htdocs/imacat/magicat/bin/gbcnvt3 @@ -0,0 +1,396 @@ +#! /usr/bin/perl -w +# Filename: gbcnvt3 +# Description: Perl script to convert the guestbook from data file into PostgreSQL +# Author: imacat +# Date: 2004-09-10 +# Copyright: (c) 2004-2007 imacat + +use 5.006; +use strict; +use warnings; +use DBI qw(); +use Fcntl qw(:flock); +use File::Basename qw(basename); +use Geo::IP qw(GEOIP_MEMORY_CACHE); +use Getopt::Long qw(GetOptions); +use Net::CIDR::Lite qw(); +use Term::ReadKey qw(ReadMode); +# Prototype declaration +sub main(); +sub parse_args(); +sub try_login($); +sub dh($); +sub country_lookup($); +sub cols($$); +sub update_gbpageno($$); +sub split_page(\@\%$); +sub xfread($); + +use vars qw($THIS_FILE $VERSION $VERBOSE); +$THIS_FILE = basename($0); +$VERSION = "2.09"; +$VERBOSE = 1; + +use vars qw($DEFUSER $USER $PGDATABASE $TABLE $FILE $GI $PRIVATE_NETWORKS); +$DEFUSER = exists $ENV{"PGUSER"}? $ENV{"PGUSER"}: + (getpwuid($>) or die "$THIS_FILE: getpwuid: $!"); +$PGDATABASE = "wov"; +$TABLE = "guestbook"; +$FILE = "/srv/www/htdocs/$PGDATABASE/magicat/data/$TABLE.dat"; +$GI = Geo::IP->new(GEOIP_MEMORY_CACHE); +use constant PRIVATE_CT => "AA"; +use constant UNKNOWN_CT => "ZZ"; +$PRIVATE_NETWORKS = Net::CIDR::Lite->new( + qw(10.0.0.0/8 172.16.0.0/12 192.168.0.0/16)); + +use vars qw($VERMSG $SHORTHELP $HELPMSG); +$VERMSG = "$THIS_FILE v$VERSION by imacat "; +$SHORTHELP = "Try `$THIS_FILE --help' for more information."; +$HELPMSG = << "EOT"; +Usage: $THIS_FILE [options] +Convert the guestbook from data file into PostgreSQL + + -U,--username=NAME Database user name (default: $DEFUSER) + -d,--debug Display debug messages. Multiple --debug to debug more. + -q,--quiet Disable debug messages. An opposite that cancels the + effect of --debug. + -h,--help Display this help. + -v,--version Display version number. + +EOT + +main; +exit 0; + +# main: Main program +sub main() { + local ($_, %_); + my ($dbh, $sql, $sth); + + # Parse the arguments + parse_args; + + # No longer a working script + print "Mission completed long time ago. Program stopped to avoid further problems.\n"; + return; + + # Read the data file + $_ = xfread $FILE; + + # Try to log in + $dbh = try_login "dbi:Pg:dbname=$PGDATABASE;"; + + $dbh->begin_work or die "$THIS_FILE: " . $dbh->errstr; + + $sql = "SET NAMES 'utf8';\n"; + $dbh->do($sql) or die "$THIS_FILE: $sql: " . $dbh->errstr; + + $sql = "LOCK TABLE $TABLE, mtime IN ACCESS EXCLUSIVE MODE;\n"; + $dbh->do($sql) or die "$THIS_FILE: $sql: " . $dbh->errstr; + + $sql = "TRUNCATE TABLE $TABLE;\n"; + $dbh->do($sql) or die "$THIS_FILE: $sql: " . $dbh->errstr; + + s/^\s*]*>\s*//; + s/\s*<\/table>\s*$//; + foreach (split /(?<=<\/record>)\s*(?=)/, $_) { + my ($name, $val, @names, @vals); + %_ = qw(); + s/^\s*]*>\s*//; + s/\s*<\/record>\s*$//; + foreach (split /(?<=<\/col>)\s*(?=]*>([^<]+)<\/col>$/; + ($name, $val) = ($1, $2); + $name = "created" if $name eq "date"; + if ($name eq "updatedby") { + $val = 923153018 if $val eq "imacat"; + $val = 460376330 if $val eq "mandy"; + } + $_{dh $name} = dh $val; + } + $_{"pageno"} = 1; + $_{"oldpageno"} = 1; + $_{"updated"} = $_{"created"} if !exists $_{"updated"}; + $_{"updatedby"} = 723676436 if !exists $_{"updatedby"}; + $_{"createdby"} = 723676436 if !exists $_{"createdby"}; + $_{"ct"} = country_lookup $_{"ip"}; + + foreach (cols $dbh, $TABLE) { + next unless exists $_{$_}; + push @names, $_; + if ($_ eq "ip") { + push @vals, "'$_{$_}'::inet"; + } elsif (/^(?:sn|createdby|updatedby)$/) { + push @vals, $_{$_}; + } else { + push @vals, $dbh->quote($_{$_}); + } + } + $sql = "INSERT INTO $TABLE" + . " (" . join(", ", @names) . ") VALUES" + . " (" . join(", ", @vals) . ");\n"; + $dbh->do($sql) or die "$THIS_FILE: $sql: " . $dbh->errstr; + } + + # Update the guestbook page number + update_gbpageno $dbh, $TABLE; + + # Update the mtime + $sql = "UPDATE mtime SET mtime=now() WHERE tabname='$TABLE';\n"; + $dbh->do($sql) or die "$THIS_FILE: $sql: " . $dbh->errstr; + + $dbh->commit or die "$THIS_FILE: " . $dbh->errstr; + + $dbh->disconnect or die "$THIS_FILE: " . $dbh->errstr; + undef $dbh; + + print STDERR "Done. " . (time - $^T) . " seconds elapsed.\n" + if $VERBOSE > 0; + return; +} + +# parse_args: Parse the arguments +sub parse_args() { + local ($_, %_); + + # Get the arguments + eval { + local $SIG{"__WARN__"} = sub { die $_[0]; }; + Getopt::Long::Configure(qw(no_auto_abbrev bundling)); + GetOptions( "username|U=s"=>\$USER, + "debug|d+"=>\$VERBOSE, + "quiet|q"=>sub { $VERBOSE-- if $VERBOSE > 0; }, + "help|h"=>sub { print $HELPMSG; exit 0; }, + "version|v"=>sub { print "$VERMSG\n"; exit 0; }); + }; + die "$THIS_FILE: $@$SHORTHELP\n" if $@ ne ""; + + $| = 1 if $VERBOSE > 0; + + # Check the arguments + # We have no arguments + die "$THIS_FILE: Too many arguments: $ARGV[0]\n$SHORTHELP\n" + if @ARGV > 0; + + return; +} + +# try_login: Try to log in, and request the password when required. +sub try_login($) { + local ($_, %_); + my ($dsn, $dbh, $subseq, $passwd); + $dsn = $_[0]; + $subseq = 0; + # Try to log in + while (!defined($dbh = DBI->connect($dsn, $USER, $passwd, { PrintError => 0 }))) { + $_ = DBI->errstr; + if ($subseq) { + print STDERR $_; + sleep 5; + } + $subseq = 1; + # Obtain the current login user + $USER = $1 if !defined $USER && / failed for user "(.+?)"/; + # Disable console echo + ReadMode 2; + print STDERR defined $USER? "PostgreSQL password for $USER: ": + "PostgreSQL password: "; + $passwd = ; + print STDERR "\n"; + die "$THIS_FILE: Failed connecting to the PostgreSQL server\n" + if !defined $passwd; + chomp $passwd; + # Restore console echo status + ReadMode 0; + } + # Return the database handle + return $dbh; +} + +# dh: Un-escape the HTML special character references +sub dh($) { + local ($_, %_); + $_ = $_[0]; + s/"/"/g; + s/>/>/g; + s/</country_code_by_addr($ip)); + # Look up private IP + return PRIVATE_CT if $PRIVATE_NETWORKS->find($ip); + # Not known + return UNKNOWN_CT; +} + +# cols: Return the columns of a table (or view) +sub cols($$) { + local ($_, %_); + my ($dbh, $table, $sth); + ($dbh, $table) = @_; + + # Get the columns list + $sth = $dbh->column_info(undef, "public", $table, "%") + or die "$THIS_FILE: ". $dbh->errstr; + @_ = qw(); + push @_, ${$_}{"COLUMN_NAME"} + while defined($_ = $sth->fetchrow_hashref); + + return @_; +} + +# update_gbpageno: Update the guestbook page number +sub update_gbpageno($$) { + local ($_, %_); + my ($dbh, $table, $sql, $sth, $count, $row, $len); + my (@ents, %sizes, %orig, %pagenos); + ($dbh, $table) = @_; + + # Update the current page number + # Ge the size of everyhing + $len = "${table}_len(name, identity, location, email, url, message) AS len"; + # Tavern Backalley has a special table structure + $len = "char_length(message) AS len" + if $table eq "garbage"; + $sql = "SELECT sn, $len, pageno FROM $table WHERE NOT hid ORDER BY created;\n"; + $sth = $dbh->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @ents = qw(), %sizes = qw(), %orig = qw(); $_ < $count; $_++) { + $row = $sth->fetchrow_hashref; + push @ents, $$row{"sn"}; + $sizes{$$row{"sn"}} = $$row{"len"}; + $orig{$$row{"sn"}} = $$row{"pageno"}; + } + # Split page + %pagenos = split_page @ents, %sizes, 2560; + # Update it + foreach (@ents) { + next if $orig{$_} == $pagenos{$_}; + $sql = "UPDATE $table SET pageno=$pagenos{$_} WHERE sn=$_;\n"; + $dbh->do($sql); + } + + # Update the old page number + # Ge the size of everyhing + $len = "${table}_oldlen(created, ip, host, name, identity, location, email, url, message, updated, updatedby) AS len"; + # Tavern Backalley has a special table structure + $len = "garbage_oldlen(created, ip, host, message, updated, updatedby) AS len" + if $table eq "garbage"; + $sql = "SELECT sn, $len, oldpageno FROM $table WHERE NOT hid ORDER BY created;\n"; + $sth = $dbh->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @ents = qw(), %sizes = qw(), %orig = qw(); $_ < $count; $_++) { + $row = $sth->fetchrow_hashref; + push @ents, $$row{"sn"}; + $sizes{$$row{"sn"}} = $$row{"len"}; + $orig{$$row{"sn"}} = $$row{"oldpageno"}; + } + # Split page + # Old page size is always 10240 + %pagenos = split_page @ents, %sizes, 10240; + # Update it + foreach (@ents) { + next if $orig{$_} == $pagenos{$_}; + $sql = "UPDATE $table SET oldpageno=$pagenos{$_} WHERE sn=$_;\n"; + $dbh->do($sql); + } + + return; +} + +# split_page: Split page according to the entry sizes +sub split_page(\@\%$) { + local ($_, %_); + my ($ents, $sizes, $page_size, $startno, $cursize, %pagenos); + ($ents, $sizes, $page_size, $startno) = @_; + $startno = 1 if !defined $startno; + + # Bounce for nothing + return if scalar @$ents == 0; + + # Split pages + %pagenos = qw(); + $pagenos{$$ents[0]} = $startno; + $cursize = $$sizes{$$ents[0]}; + for ($_ = 1; $_ < scalar(@$ents); $_++) { + my ($hi_gap, $lo_gap); + # We need at least one record + if ($cursize == 0) { + $pagenos{$$ents[$_]} = $pagenos{$$ents[$_-1]}; + $cursize += $$sizes{$$ents[$_]}; + next; + # Not oversized yet + } elsif ($cursize + $$sizes{$$ents[$_]} < $page_size) { + $pagenos{$$ents[$_]} = $pagenos{$$ents[$_-1]}; + $cursize += $$sizes{$$ents[$_]}; + next; + } + $hi_gap = $cursize + $$sizes{$$ents[$_]} - $page_size; + $lo_gap = $page_size - $cursize; + # The upper boundary is closer, and the page is not too oversized + if ($hi_gap < $lo_gap && $hi_gap <= $page_size / 4) { + $pagenos{$$ents[$_]} = $pagenos{$$ents[$_-1]}; + $cursize += $$sizes{$$ents[$_]}; + # Or, we prefer the lower, since the page is not oversized + } else { + $pagenos{$$ents[$_]} = $pagenos{$$ents[$_-1]} + 1; + $cursize = $$sizes{$$ents[$_]}; + } + } + + return %pagenos; +} + +# xfread: Read from a file +sub xfread($) { + local ($_, %_); + my ($FH, $file); + $file = $_[0]; + + # Return as lines + if (wantarray) { + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + @_ = <$FH>; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return @_; + + # A scalar file content + } else { + # Regular files + if (-f $file) { + my $size; + @_ = stat $file or die "$THIS_FILE: $file: $!"; + $size = $_[7]; + return "" if $size == 0; + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + read $FH, $_, $size or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return $_; + + # Special files + } else { + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + $_ = join "", <$FH>; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return $_; + } + } +} + +__END__ diff --git a/htdocs/imacat/magicat/cgi-bin/acctrecs.cgi b/htdocs/imacat/magicat/cgi-bin/acctrecs.cgi new file mode 100755 index 0000000..fec3b92 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/acctrecs.cgi @@ -0,0 +1,242 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# acctrecs.cgi: The accounting record administration. + +# Copyright (c) 2007-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-23 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_seltrx($); +sub import_selsubj($); + +initenv(-restricted => 1, + -this_table => "acctrecs", + -dbi_lock => {"acctrecs" => LOCK_EX, + "accttrx" => LOCK_SH, + "acctsubj" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("accounting")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::AcctRec($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + # Only allowing to run on HTTPS + http_403 if !is_https; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Only allowing to run on HTTPS + http_403 if !is_https; + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::AcctRec(curform); + $checker->redir(qw(seltrx deltrx selsubj delsubj)); + $error = $checker->check(qw(trx type ord subj summary amount)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::AcctRec(curform); + $checker->redir(qw(del seltrx deltrx selsubj delsubj)); + $error = $checker->check(qw(trx type ord subj summary amount)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::AcctRec(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::AcctRec($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Accounting::Records; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the accounting record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This accounting record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $CURRENT{"type"} = $CURRENT{"credit"}? "credit": "debit"; + + # OK + return; +} + +# import_seltrx: Import the selected accounting transaction into the retrieved form +sub import_seltrx($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("trx", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "accttrx"; + return; +} + +# import_selsubj: Import the selected accounting subject into the retrieved form +sub import_selsubj($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("subj", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "acctsubj"; + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/acctreps.cgi b/htdocs/imacat/magicat/cgi-bin/acctreps.cgi new file mode 100755 index 0000000..f13f4e9 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/acctreps.cgi @@ -0,0 +1,107 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# acctreps.cgi: The accounting report viewer. + +# Copyright (c) 2007-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-23 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub html_page($); + +initenv(-restricted => 1, + -dbi_lock => {"acctsubj" => LOCK_SH, + "accttrx" => LOCK_SH, + "acctrecs" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("accounting"), + "javascripts" => [qw(/scripts/accounting.js)]}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $error; + # Only allowing requests with GET method + # Check it here, since we still want list preference handlers to work + http_405 qw(GET) if $ENV{"REQUEST_METHOD"} ne "GET"; + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + # Only allowing to run on HTTPS + http_403 if !is_https; + # List handler handles its own error + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $page_param); + $status = $_[0]; + # List the available items + $_ = list_type; + if ($_ eq "cashsum") { + $LIST = new Selima::List::Accounting::Reports::Cash::Summary; + } elsif ($_ eq "ldgr") { + $LIST = new Selima::List::Accounting::Reports::Ledger; + } elsif ($_ eq "ldgrsum") { + $LIST = new Selima::List::Accounting::Reports::Ledger::Summary; + } elsif ($_ eq "journal") { + $LIST = new Selima::List::Accounting::Reports::Journal; + } elsif ($_ eq "tb") { + $LIST = new Selima::List::Accounting::Reports::TriBlnc; + } elsif ($_ eq "incmstat") { + $LIST = new Selima::List::Accounting::Reports::IncmStat; + } elsif ($_ eq "blncshet") { + $LIST = new Selima::List::Accounting::Reports::BlncShet; + } elsif ($_ eq "search") { + $LIST = new Selima::List::Accounting::Reports::Search; + } else { + $LIST = new Selima::List::Accounting::Reports::Cash; + } + # Return the data as a CSV file + return $LIST->html if $LIST->{"iscsv"}; + # Ordinary list + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/acctsubj.cgi b/htdocs/imacat/magicat/cgi-bin/acctsubj.cgi new file mode 100755 index 0000000..4cc7bdd --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/acctsubj.cgi @@ -0,0 +1,292 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# acctsubj.cgi: The accounting subject administraion. + +# Copyright (c) 2007-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-08-23 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selparent($); + +initenv(-restricted => 1, + -this_table => "acctsubj", + -dbi_lock => {"acctsubj" => LOCK_EX, + "acctrecs" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("accounting")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::AcctSubj($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + # Only allowing to run on HTTPS + http_403 if !is_https; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new accounting subject from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + return {"msg"=>N_("This accounting subject has [numerate,_1,an accounting sub-subject,accounting sub-subjects]. It cannot be deleted. To delete the subject, [numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] must first be deleted."), + "margs"=>[$CURRENT{"ssubcount"}], + "isform"=>0} + if $CURRENT{"ssubcount"} > 0; + return {"msg"=>N_("This accounting subject has [numerate,_1,an accounting record,accounting records]. It cannot be deleted. To delete the subject, [numerate,_1,its accounting record,all of its accounting records] must first be deleted."), + "margs"=>[$CURRENT{"reccount"}], + "isform"=>0} + if $CURRENT{"reccount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Only allowing to run on HTTPS + http_403 if !is_https; + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new accounting subject from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + # Run the checker + $checker = new Selima::Checker::AcctSubj(curform); + $checker->redir(qw(selparent delparent)); + $error = $checker->check(qw(parent code title)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::AcctSubj(curform); + $checker->redir(qw(del zhsync selparent delparent)); + $error = $checker->check(qw(parent code title)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::AcctSubj(curform); + $checker->redir(qw(cancel)); + return {"msg"=>N_("This accounting subject has [numerate,_1,an accounting sub-subject,accounting sub-subjects]. It cannot be deleted. To delete the subject, [numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] must first be deleted."), + "margs"=>[$CURRENT{"ssubcount"}], + "isform"=>0} + if $CURRENT{"ssubcount"} > 0; + return {"msg"=>N_("This accounting subject has [numerate,_1,an accounting record,accounting records]. It cannot be deleted. To delete the subject, [numerate,_1,its accounting record,all of its accounting records] must first be deleted."), + "margs"=>[$CURRENT{"reccount"}], + "isform"=>0} + if $CURRENT{"reccount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::AcctSubj($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + if (list_type eq "lastlv") { + $LIST = new Selima::List::Accounting::Subjects::LastLv; + } else { + $LIST = new Selima::List::Accounting::Subjects; + } + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lang, $lndb, $lndbdef, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the accounting subject."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This accounting subject does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $lang = getlang; + $lndb = getlang LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + + # Obtain the belonging subjects list + @_ = qw(); + push @_, "sn AS sn"; + if (@ALL_LINGUAS > 1) { + $title = $lang eq $DEFAULT_LANG? "title_$lndb": + "COALESCE(title_$lndb, title_$lndbdef)"; + } else {; + $title = "title"; + } + push @_, $DBH->strcat("code", "' '", $title) . " AS title"; + $sql = "SELECT " . join(", ", @_) . " FROM acctsubj" + . " WHERE parent=$sn" + . " ORDER BY code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"ssubcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"ssubcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"ssub$_" . "sn"} = $$row{"sn"}; + $CURRENT{"ssub$_" . "title"} = $$row{"title"}; + } + + # Obtain the belonging records list + $sql = "SELECT sn FROM acctrecs" + . " WHERE subj=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"reccount"} = $sth->rows; + + # OK + return; +} + +# import_selparent: Import the selected parent into the retrieved form +sub import_selparent($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "acctsubj") { + $FORM->param("parent", $GET->param("selsn")); + $FORM->param("topmost", "false"); + } + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/accttrx.cgi b/htdocs/imacat/magicat/cgi-bin/accttrx.cgi new file mode 100755 index 0000000..add5343 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/accttrx.cgi @@ -0,0 +1,278 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# accttrx.cgi: The accounting transaction administraion. + +# Copyright (c) 2007-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-08-24 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selsubj($); + +initenv(-restricted => 1, + -this_table => "accttrx", + -dbi_lock => {"accttrx" => LOCK_EX, + "acctrecs" => LOCK_EX, + "acctsubj" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("accounting"), + "javascripts" => [qw(/scripts/accounting.js)]}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::AcctTrx($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + # Only allowing to run on HTTPS + http_403 if !is_https; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Only allowing to run on HTTPS + http_403 if !is_https; + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::AcctTrx(curform); + $checker->redir(qw(cnvttrans selsubj)); + $error = $checker->check(qw(date ord note recs)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::AcctTrx(curform); + $checker->redir(qw(del cnvttrans selsubj)); + $error = $checker->check(qw(date ord note recs)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::AcctTrx(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::AcctTrx($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Accounting::Transacts; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the accounting transaction."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This accounting transaction does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging debit records list + $sql = "SELECT * FROM acctrecs" + . " WHERE trx=$sn" + . " AND NOT credit" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"debtcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"debtcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"debt$_" . "sn"} = $$row{"sn"}; + $CURRENT{"debt$_" . "ord"} = $$row{"ord"}; + $CURRENT{"debt$_" . "subj"} = $$row{"subj"}; + $CURRENT{"debt$_" . "summary"} = $$row{"summary"}; + $CURRENT{"debt$_" . "amount"} = $$row{"amount"}; + } + + # Obtain the belonging credit records list + $sql = "SELECT * FROM acctrecs" + . " WHERE trx=$sn" + . " AND credit" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"crdtcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"crdtcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"crdt$_" . "sn"} = $$row{"sn"}; + $CURRENT{"crdt$_" . "ord"} = $$row{"ord"}; + $CURRENT{"crdt$_" . "subj"} = $$row{"subj"}; + $CURRENT{"crdt$_" . "summary"} = $$row{"summary"}; + $CURRENT{"crdt$_" . "amount"} = $$row{"amount"}; + } + + # Determine the subform type + if ( $CURRENT{"debtcount"} == 1 + && acctsubj_code($CURRENT{"debt0subj"}) eq ACCTSUBJ_CASH + && !defined $CURRENT{"debt0summary"}) { + $CURRENT{"formsub"} = "income"; + } elsif ( $CURRENT{"crdtcount"} == 1 + && acctsubj_code($CURRENT{"crdt0subj"}) eq ACCTSUBJ_CASH + && !defined $CURRENT{"crdt0summary"}) { + $CURRENT{"formsub"} = "expense"; + } else { + $CURRENT{"formsub"} = "trans"; + } + + # OK + return; +} + +# import_selsubj: Import the selected subject into the retrieved form +sub import_selsubj($) { + my $FORM; + $FORM = $_[0]; + # Sanity checks + return $FORM + if !defined $GET->param("selsn") + || !check_sn_in ${$GET->param_fetch("selsn")}[0], "acctsubj" + || !defined $FORM->param("caller_index"); + $FORM->param($FORM->param("caller_index") . "subj", $GET->param("selsn")); + return $FORM; +} diff --git a/htdocs/imacat/magicat/cgi-bin/actlog.cgi b/htdocs/imacat/magicat/cgi-bin/actlog.cgi new file mode 100755 index 0000000..03c2bea --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/actlog.cgi @@ -0,0 +1,51 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# actlog.cgi: The activity log viewer. + +# Copyright (c) 2005-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-05-10 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); + +initenv(-restricted => 1, + -allowed => [qw(GET HEAD)], + -lastmod => 0, + -lmfiles => [$ACTLOG], + -page_param => {"keywords" => N_("activity, logs")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $LIST; + # List handler handles its own error + $LIST = new Selima::List::ActLog; + html_header $LIST->{"title"}; + html_errmsg retrieve_status; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/changelog.cgi b/htdocs/imacat/magicat/cgi-bin/changelog.cgi new file mode 100755 index 0000000..2e2efbd --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/changelog.cgi @@ -0,0 +1,220 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# changelog.cgi: The change log administration. + +# Copyright (c) 2005-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-24 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +use Encode::HanConvert qw(trad_to_simp); + +initenv(-restricted => 1, + -this_table => "changelog", + -dbi_lock => {"changelog" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("change log, history")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::ChangeLog($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please write a new log entry from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please write a new log entry from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + # Run the checker + $checker = new Selima::imacat::Checker::ChangeLog(curform); + $error = $checker->check(qw(body)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::ChangeLog(curform); + $checker->redir(qw(del zhsync)); + $error = $checker->check(qw(body)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::ChangeLog(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::imacat::Form::ChangeLog($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::imacat::List::ChangeLog; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the log entry."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This log entry does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/diary.cgi b/htdocs/imacat/magicat/cgi-bin/diary.cgi new file mode 100755 index 0000000..00d5d75 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/diary.cgi @@ -0,0 +1,220 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# diary.cgi: The diary administration. + +# Copyright (c) 2005-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-17 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +use Encode::HanConvert qw(trad_to_simp); + +initenv(-restricted => 1, + -this_table => "diary", + -dbi_lock => {"diary" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("diary")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::Diary($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please write a new diary entry from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please write a new diary entry from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + # Run the checker + $checker = new Selima::imacat::Checker::Diary(curform); + $error = $checker->check(qw(body)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::Diary(curform); + $checker->redir(qw(del zhsync)); + $error = $checker->check(qw(body)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::Diary(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::imacat::Form::Diary($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::imacat::List::Diary; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the diary entry."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This diary entry does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/funds.cgi b/htdocs/imacat/magicat/cgi-bin/funds.cgi new file mode 100755 index 0000000..0eab304 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/funds.cgi @@ -0,0 +1,51 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# funds.cgi: The fund performance viewer. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-10-29 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); + +initenv(-restricted => 1, + -this_table => "funds", + -dbi_lock => {"funds" => LOCK_SH}, + -lastmod => 0, + -page_param => {"keywords" => N_("mutual funds, performance, indicators")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $LIST; + # List handler handles its own error + $LIST = new Selima::imacat::List::Funds; + html_header $LIST->{"title"}; + html_errmsg retrieve_status; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/garbage.cgi b/htdocs/imacat/magicat/cgi-bin/garbage.cgi new file mode 100755 index 0000000..6ec0798 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/garbage.cgi @@ -0,0 +1,209 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# garbage.cgi: The Soundless Backalley administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-01-26 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "garbage", + -dbi_lock => {"garbage" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("backalley")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::Garbage($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::imacat::Checker::Garbage(curform); + $error = $checker->check(qw(message)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::Garbage(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(message)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::Garbage(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::imacat::Form::Garbage($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::imacat::List::Garbage; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the message."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This message does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/groupmem.cgi b/htdocs/imacat/magicat/cgi-bin/groupmem.cgi new file mode 100755 index 0000000..f6b94e1 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/groupmem.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# groupmem.cgi: The group-to-group membership administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); +sub import_selmember($); + +initenv(-restricted => 1, + -this_table => "groupmem", + -dbi_lock => {"groupmem" => LOCK_EX, + "groups" => LOCK_SH, + "groups AS grpmembers" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("group membership")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::GroupMem($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(del selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::GroupMem($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::GroupMem; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the membership record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This membership record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} + +# import_selmember: Import the selected member into the retrieved form +sub import_selmember($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("member", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups AS grpmembers"; + return $FORM; +} diff --git a/htdocs/imacat/magicat/cgi-bin/groups.cgi b/htdocs/imacat/magicat/cgi-bin/groups.cgi new file mode 100755 index 0000000..59d0a51 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/groups.cgi @@ -0,0 +1,386 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# groups.cgi: The account group administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-12 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selsubuser($); +sub import_selsubgroup($); +sub import_selsupgroup($); + +initenv(-restricted => 1, + -this_table => "groups", + -dbi_lock => {"groups" => LOCK_EX, + "usermem" => LOCK_EX, + "groupmem" => LOCK_EX, + "users" => LOCK_SH, + "users AS members" => LOCK_SH, + "groups AS members" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("groups")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Group($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my ($error, $FORM, $sn); + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + if (getlang ne $DEFAULT_LANG) { + return {"msg"=>N_("Please create a new group from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0}; + } + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth if !is_su && $sn == su_group_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error, $FORM, $sn); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + if (getlang ne $DEFAULT_LANG) { + return {"msg"=>N_("Please create a new group from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0}; + } + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(selsubuser selsubgroup selsupgroup)); + $error = $checker->check(qw(id dsc subuser subgroup supgroup)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(del zhsync selsubuser selsubgroup selsupgroup)); + $error = $checker->check(qw(id dsc subuser subgroup supgroup)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth if !is_su && $sn == su_group_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::Group($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Groups; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lndb, $lndbdef, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the group."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This group does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the user members list + $title = $DBH->strcat("users.id", "' ('", "users.name", "')'"); + $sql = "SELECT users.sn AS sn," + . " $title AS title" + . " FROM usermem" + . " INNER JOIN users ON usermem.member=users.sn" + . " WHERE usermem.grp=$sn" + . " ORDER BY users.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"subusercount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"subusercount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"subuser$_"} = 1; + $CURRENT{"subuser$_" . "sn"} = $$row{"sn"}; + $CURRENT{"subuser$_" . "title"} = $$row{"title"}; + } + + # Obtain the group members list + $lndb = getlang LN_DATABASE; + if (getlang eq $DEFAULT_LANG) { + $title = "groups.dsc_$lndb"; + } else { + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + $title = $DBH->strcat("groups.id", "' ('", + "COALESCE(groups.dsc_$lndb, groups.dsc_$lndbdef)", "')'"); + } + $sql = "SELECT groups.sn AS sn," + . " $title AS title FROM groupmem" + . " INNER JOIN groups ON groupmem.member=groups.sn" + . " WHERE groupmem.grp=$sn" + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"subgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"subgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"subgroup$_"} = 1; + $CURRENT{"subgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"subgroup$_" . "title"} = $$row{"title"}; + } + + # Obtain the belonging groups list + $lndb = getlang LN_DATABASE; + if (getlang eq $DEFAULT_LANG) { + $title = $DBH->strcat("groups.id", "' ('", + "groups.dsc_$lndb", "')'"); + } else { + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + $title = $DBH->strcat("groups.id", "' ('", + "COALESCE(groups.dsc_$lndb, groups.dsc_$lndbdef)", "')'"); + } + $sql = "SELECT groups.sn AS sn," + . " $title AS title FROM groupmem" + . " INNER JOIN groups ON groupmem.grp=groups.sn" + . " WHERE groupmem.member=$sn" + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"supgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"supgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"supgroup$_"} = 1; + $CURRENT{"supgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"supgroup$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} + +# import_selsubuser: Import the selected user into the retrieved form +sub import_selsubuser($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users AS members") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^subuser\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { userid $a cmp userid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^subuser\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^subuser\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("subuser$_" . "sn", $_[$_]); + $FORM->param("subuser$_", 1) if exists $_{$_[$_]}; + } + } + return; +} + +# import_selsubgroup: Import the selected user into the retrieved form +sub import_selsubgroup($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups AS members") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^subgroup\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { groupid $a cmp groupid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^subgroup\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^subgroup\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("subgroup$_" . "sn", $_[$_]); + $FORM->param("subgroup$_", 1) if exists $_{$_[$_]}; + } + } + return; +} + +# import_selsupgroup: Import the selected user into the retrieved form +sub import_selsupgroup($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^supgroup\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { groupid $a cmp groupid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^supgroup\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^supgroup\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("supgroup$_" . "sn", $_[$_]); + $FORM->param("supgroup$_", 1) if exists $_{$_[$_]}; + } + } + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/guestbook.cgi b/htdocs/imacat/magicat/cgi-bin/guestbook.cgi new file mode 100755 index 0000000..437e411 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/guestbook.cgi @@ -0,0 +1,214 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# guestbook.cgi: The guestbook administration. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-05-10 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "guestbook", + -dbi_lock => {"guestbook" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("guestbook")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::Guestbook($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::imacat::Checker::Guestbook(curform); + $error = $checker->check(qw(name identity location + email url message lang)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::Guestbook(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(name identity location + email url message lang)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::Guestbook(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::imacat::Form::Guestbook($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::imacat::List::Guestbook; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the message."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This message does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Set "lang" as "lang0" + $CURRENT{"lang0"} = $CURRENT{"lang"}; + + # OK + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/linkcat.cgi b/htdocs/imacat/magicat/cgi-bin/linkcat.cgi new file mode 100755 index 0000000..3d4ef77 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/linkcat.cgi @@ -0,0 +1,304 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# linkcat.cgi: The related-link category administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selparent($); + +initenv(-restricted => 1, + -this_table => "linkcat", + -dbi_lock => {"linkcat" => LOCK_EX, + "links" => LOCK_SH, + "linkcatz" => LOCK_SH}, + -lastmod => 0, + -page_param => {"keywords" => N_("link categories")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LinkCat($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new category from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + return {"msg"=>N_("This category has [numerate,_1,a subcategory,subcategories]. It cannot be deleted. To delete the category, [numerate,_1,its subcategory,all of its subcategories] must first be deleted."), + "margs"=>[$CURRENT{"scatcount"}], + "isform"=>0} + if $CURRENT{"scatcount"} > 0; + return {"msg"=>N_("This category has [numerate,_1,a link,links]. It cannot be deleted. To delete the category, [numerate,_1,its link,all of its links] must first be deleted."), + "margs"=>[$CURRENT{"linkcount"}], + "isform"=>0} + if $CURRENT{"linkcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new category from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(selparent delparent)); + $error = $checker->check(qw(parent id ord title kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(del zhsync selparent delparent)); + $error = $checker->check(qw(parent id ord title kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(cancel)); + return {"msg"=>N_("This category has [numerate,_1,a subcategory,subcategories]. It cannot be deleted. To delete the category, [numerate,_1,its subcategory,all of its subcategories] must first be deleted."), + "margs"=>[$CURRENT{"scatcount"}], + "isform"=>0} + if $CURRENT{"scatcount"} > 0; + return {"msg"=>N_("This category has [numerate,_1,a link,links]. It cannot be deleted. To delete the category, [numerate,_1,its link,all of its links] must first be deleted."), + "margs"=>[$CURRENT{"linkcount"}], + "isform"=>0} + if $CURRENT{"linkcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::LinkCat($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::LinkCat; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lang, $lndb, $lndbdef, $langfile, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the category."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This category does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $lang = getlang; + $lndb = getlang LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + $langfile = getlang LN_FILENAME; + + # Obtain the belonging subcategories list + @_ = qw(); + push @_, "sn AS sn"; + if (@ALL_LINGUAS > 1) { + $title = $lang eq $DEFAULT_LANG? "title_$lndb": + "COALESCE(title_$lndb, title_$lndbdef)"; + push @_, "linkcat_fulltitle('$lang', parent, $title) AS title"; + } else { + push @_, "linkcat_fulltitle(parent, title) AS title"; + } + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS url"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_ischild($sn, sn)" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"scatcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"scatcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"scat$_" . "sn"} = $$row{"sn"}; + $CURRENT{"scat$_" . "title"} = $$row{"title"}; + $CURRENT{"scat$_" . "url"} = $$row{"url"}; + $CURRENT{"scat$_" . "url"} .= "index.html" + if $CURRENT{"scat$_" . "url"} =~ /\/$/; + $CURRENT{"scat$_" . "url"} .= ".$langfile"; + } + + # Obtain the belonging links list + @_ = qw(); + push @_, "links.sn AS sn"; + push @_, "links.title AS title"; + push @_, "url AS url"; + $sql = "SELECT " . join(", ", @_) . " FROM links" + . " INNER JOIN linkcatz ON linkcatz.link=links.sn" + . " WHERE linkcatz.cat=$sn" + . " ORDER BY title;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"linkcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"linkcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"link$_" . "sn"} = $$row{"sn"}; + $CURRENT{"link$_" . "title"} = $$row{"title"}; + $CURRENT{"link$_" . "url"} = $$row{"url"}; + } + + # OK + return; +} + +# import_selparent: Import the selected parent into the retrieved form +sub import_selparent($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "linkcat") { + $FORM->param("parent", $GET->param("selsn")); + $FORM->param("topmost", "false"); + } + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/linkcatz.cgi b/htdocs/imacat/magicat/cgi-bin/linkcatz.cgi new file mode 100755 index 0000000..6861345 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/linkcatz.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# linkcatz.cgi: The related-link category membership administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-25 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selcat($); +sub import_sellink($); + +initenv(-restricted => 1, + -this_table => "linkcatz", + -dbi_lock => {"linkcatz" => LOCK_EX, + "linkcat" => LOCK_SH, + "links" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("link categorization")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LinkCatz($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(selcat delcat sellink dellink)); + $error = $checker->check(qw(cat link)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(del selcat delcat sellink dellink)); + $error = $checker->check(qw(cat link)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::LinkCatz($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::LinkCatz; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the categorization record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This categorization record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selcat: Import the selected category into the retrieved form +sub import_selcat($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("cat", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "linkcat"; + return; +} + +# import_sellink: Import the selected link into the retrieved form +sub import_sellink($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("link", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "links"; + return $FORM; +} diff --git a/htdocs/imacat/magicat/cgi-bin/links.cgi b/htdocs/imacat/magicat/cgi-bin/links.cgi new file mode 100755 index 0000000..dc65e58 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/links.cgi @@ -0,0 +1,252 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# links.cgi: The related-link administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "links", + -dbi_lock => {"links" => LOCK_EX, + "linkcatz" => LOCK_EX, + "linkcat" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("related links")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Link($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new related link from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new related link from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + # Run the checker + $checker = new Selima::Checker::Link(curform); + $error = $checker->check(qw(title title_2ln url icon + email addr tel fax dsc cats)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Link(curform); + $checker->redir(qw(del zhsync)); + $error = $checker->check(qw(title title_2ln url icon + email addr tel fax dsc cats)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::Link(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::Link($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Links; + $LIST->{"title"} = __("Manage Keep Travelling") + unless $LIST->{"is_called_form"}; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lang, $lndb, $lndbdef, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the related link."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This related link does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $lang = getlang; + $lndb = getlang LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + + # Obtain the parent categories list + @_ = qw(); + push @_, "linkcat.sn AS sn"; + if (@ALL_LINGUAS > 1) { + $title = $lang eq $DEFAULT_LANG? "linkcat.title_$lndb": + "COALESCE(linkcat.title_$lndb, linkcat.title_$lndbdef)"; + push @_, "linkcat_fulltitle('$lang', linkcat.parent, $title) AS title"; + } else { + push @_, "linkcat_fulltitle(linkcat.parent, linkcat.title) AS title"; + } + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " INNER JOIN linkcatz ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.link=$sn" + . " ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord);\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"catcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"catcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"cat$_"} = $$row{"sn"}; + $CURRENT{"cat$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/literalen.cgi b/htdocs/imacat/magicat/cgi-bin/literalen.cgi new file mode 100755 index 0000000..8c031de --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/literalen.cgi @@ -0,0 +1,278 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# literalen.cgi: The English writing administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-24 + +use 5.008; +use utf8; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +use Date::Parse qw(str2time); + +initenv(-restricted => 1, + -this_table => "literalen", + -dbi_lock => {"literalen" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("English literal works")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::LiteralEn($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to preview a submitted item + } elsif ($_ eq "preview") { + my ($sql, $sth, $count, $row, $date, @allworks); + # Check at fetch_preview() + $error = fetch_preview; + return $error if defined $error; + $PREVIEW{"lang"} = "en"; + $PREVIEW{"all_linguas"} = ["en"]; + $date = str2time $PREVIEW{"date"}; + @_ = localtime $date; + $_[5] += 1900; + $_[4]++; + $PREVIEW{"path"} = sprintf("/writings-en/%04d%02d%02d.html", @_[5,4,3]); + + # Obtain all the pages + @_ = qw(); + push @_, "sn!=" . $PREVIEW{"sn"} if exists $PREVIEW{"sn"}; + push @_, "NOT hid"; + $sql = "SELECT date, title, dsc FROM literalen" + . " WHERE " . join(" AND ", @_) + . " ORDER BY date;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @allworks = qw(); $i < $count; $i++) { + $row = $sth->fetchrow_hashref; + @_ = localtime $$row{"date"}; + $_[5] += 1900; + $_[4]++; + $$row{"path"} = sprintf("/writings-en/%04d%02d%02d.html", @_[5,4,3]); + $$row{"title"} = myfmtdate($$row{"date"}) + . (defined $$row{"title"}? " " . $$row{"title"}: ""); + push @allworks, $row; + } + undef $sth; + # Insert this page + for ($_ = 0; $_ < @allworks; $_++) { + last if $date < ${$allworks[$_]}{"date"}; + } + @allworks = ( + @allworks[0..$_-1], + { "date" => $date, + "path" => $PREVIEW{"path"}, + "title" => $PREVIEW{"title"}, + "dsc" => $PREVIEW{"dsc"}, + }, + @allworks[$_..$#allworks]); + # The latest page has a specific path + ${$allworks[$#allworks]}{"_path"} = ${$allworks[$#allworks]}{"path"}; + ${$allworks[$#allworks]}{"path"} = "/writings-en/latest.html"; + $PREVIEW{"allworks"} = [@allworks]; + + $PREVIEW{"date"} = $date; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::imacat::Checker::LiteralEn(curform); + $error = $checker->check(qw(date title dsc body kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::LiteralEn(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(date title dsc body kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::LiteralEn(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + # A form to preview a submitted item + if (form_type eq "preview") { + html_preview; + + } else { + $FORM = new Selima::imacat::Form::LiteralEn($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + } + + # List the available items + } else { + $LIST = new Selima::imacat::List::LiteralEn; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lndb, $lndbdef); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the English literal work."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This English literal work does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the date + $CURRENT{"date"} = fmtdate $CURRENT{"date"}; + + # OK + return; +} + +no utf8; diff --git a/htdocs/imacat/magicat/cgi-bin/literalzh.cgi b/htdocs/imacat/magicat/cgi-bin/literalzh.cgi new file mode 100755 index 0000000..f3d6e00 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/literalzh.cgi @@ -0,0 +1,307 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# literalzh.cgi: The Chinese writing administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-18 + +use 5.008; +use utf8; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +use Date::Parse qw(str2time); + +initenv(-restricted => 1, + -this_table => "literalzh", + -dbi_lock => {"literalzh" => LOCK_EX, + "ltzhpoem" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("Chinese literal works")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::LiteralZh($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to preview a submitted item + } elsif ($_ eq "preview") { + my ($sql, $sth, $count, $row, $date, $title, @allworks); + # Check at fetch_preview() + $error = fetch_preview; + return $error if defined $error; + $PREVIEW{"lang"} = "zh-tw"; + $PREVIEW{"all_linguas"} = [qw(zh-tw zh-cn)]; + $date = str2time $PREVIEW{"date"}; + @_ = localtime $date; + $_[5] += 1900; + $_[4]++; + $PREVIEW{"path"} = sprintf("/writings-zh/%04d%02d%02d.html", @_[5,4,3]); + $title = myfmtdate($date) + . ( defined $PREVIEW{"title"} && $PREVIEW{"title"} ne ""? + " " . $PREVIEW{"title"}: ""); + $PREVIEW{"title"} = "詩 $title"; + + # Set the S/N of each poem + for (my $i = 0; exists $PREVIEW{"poem$i" . "title"}; $i++) { + next unless exists $PREVIEW{"poem$i"} + && !(exists $PREVIEW{"poem$i" . "hid"} + && $PREVIEW{"poem$i" . "hid"}); + next if exists $PREVIEW{"poem$i" . "sn"}; + $PREVIEW{"poem$i" . "sn"} = newsn "ltzhpoem"; + } + + # Obtain all the pages + @_ = qw(); + push @_, "sn!=" . $PREVIEW{"sn"} if exists $PREVIEW{"sn"}; + push @_, "NOT hid"; + $sql = "SELECT date, title, dsc FROM literalzh" + . " WHERE " . join(" AND ", @_) + . " ORDER BY date;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @allworks = qw(); $i < $count; $i++) { + $row = $sth->fetchrow_hashref; + @_ = localtime $$row{"date"}; + $_[5] += 1900; + $_[4]++; + $$row{"path"} = sprintf("/writings-zh/%04d%02d%02d.html", @_[5,4,3]); + $$row{"title"} = myfmtdate($$row{"date"}) + . (defined $$row{"title"}? " " . $$row{"title"}: ""); + push @allworks, $row; + } + undef $sth; + # Insert this page + for ($_ = 0; $_ < @allworks; $_++) { + last if $date < ${$allworks[$_]}{"date"}; + } + @allworks = ( + @allworks[0..$_-1], + { "date" => $date, + "path" => $PREVIEW{"path"}, + "title" => $title, + "dsc" => $PREVIEW{"dsc"}, + }, + @allworks[$_..$#allworks]); + # The latest page has a specific path + ${$allworks[$#allworks]}{"_path"} = ${$allworks[$#allworks]}{"path"}; + ${$allworks[$#allworks]}{"path"} = "/writings-zh/latest.html"; + $PREVIEW{"allworks"} = [@allworks]; + + $PREVIEW{"date"} = $date; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::imacat::Checker::LiteralZh(curform); + $error = $checker->check(qw(date title dsc poems kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::LiteralZh(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(date title dsc poems kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::LiteralZh(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + # A form to preview a submitted item + if (form_type eq "preview") { + html_preview; + + } else { + $FORM = new Selima::imacat::Form::LiteralZh($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + } + + # List the available items + } else { + $LIST = new Selima::imacat::List::LiteralZh; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lndb, $lndbdef); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the Chinese literal work."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This Chinese literal work does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the date + $CURRENT{"date"} = fmtdate $CURRENT{"date"}; + + # Obtain the articles list + $sql = "SELECT * FROM ltzhpoem WHERE set=$sn ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"poemcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"poemcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"poem$_"} = 1; + $CURRENT{"poem$_" . "sn"} = $$row{"sn"}; + $CURRENT{"poem$_" . "ord"} = $$row{"ord"}; + $CURRENT{"poem$_" . "title"} = $$row{"title"}; + $CURRENT{"poem$_" . "body"} = $$row{"body"}; + $CURRENT{"poem$_" . "hid"} = $$row{"hid"}; + } + + # OK + return; +} + +no utf8; diff --git a/htdocs/imacat/magicat/cgi-bin/logout.cgi b/htdocs/imacat/magicat/cgi-bin/logout.cgi new file mode 100755 index 0000000..143b794 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/logout.cgi @@ -0,0 +1,158 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# logout.cgi: The log-out script. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub html_logoutform(); +sub html_relogin(); + +initenv(-dbi => DBI_NONE, + -lastmod => 1, + -page_param => {"keywords" => N_("log out")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LogOut($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $status; + # There is a result to display + $status = retrieve_status; + # Successfully logged out + if ( defined $status + && exists $$status{"status"} + && $$status{"status"} eq "success") { + # Nothing to check + return; + } + # Check if this user has logged in + unauth unless defined get_login_sn; + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + # Check if this user has logged in + unauth unless defined get_login_sn; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my $status; + $status = $_[0]; + # Not logged out yet + if (defined get_login_sn) { + html_header __("Log Out"); + html_errmsg $status; + html_logoutform; + html_footer; + + # Logged out + } else { + html_header __("Log Out"); + html_errmsg $status; + html_relogin; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# html_logoutform: Display a form to log out +sub html_logoutform() { + local ($_, %_); + my ($msg, $submit); + $msg = h(__("Are you sure you want to log out?")); + $submit = h(__("Log out")); + print << "EOT"; +
    +
    +

    $msg

    + +
    +
    + +EOT + return; +} + +# html_relogin: Display links to log in again +sub html_relogin() { + local ($_, %_); + $_ = h(__("Log in again.")); + print << "EOT"; +

    $_

    + +EOT + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/ltzhpoem.cgi b/htdocs/imacat/magicat/cgi-bin/ltzhpoem.cgi new file mode 100755 index 0000000..e5aae73 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/ltzhpoem.cgi @@ -0,0 +1,224 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# ltzhpoem.cgi: The Chinese poem administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-18 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selset($); + +initenv(-restricted => 1, + -this_table => "ltzhpoem", + -dbi_lock => {"ltzhpoem" => LOCK_EX, + "literalzh" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("Chinese poems")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::LtZhPoem($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::imacat::Checker::LtZhPoem(curform); + $checker->redir(qw(selset delset)); + $error = $checker->check(qw(set ord title body)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::LtZhPoem(curform); + $checker->redir(qw(del selset delset)); + $error = $checker->check(qw(set ord title body)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::LtZhPoem(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::imacat::Form::LtZhPoem($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::imacat::List::LtZhPoem; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lndb, $lndbdef); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the Chinese poem."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This Chinese poem does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selset: Import the selected work set into the retrieved form +sub import_selset($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("set", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "literalzh"; + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/pages.cgi b/htdocs/imacat/magicat/cgi-bin/pages.cgi new file mode 100755 index 0000000..20c3303 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/pages.cgi @@ -0,0 +1,230 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# pages.cgi: The web page administration. + +# Copyright (c) 2005-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-28 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "pages", + -dbi_lock => {"pages" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("pages")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::Page($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new page from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to preview a submitted item + } elsif ($_ eq "preview") { + # Check at fetch_preview() + $error = fetch_preview; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new page from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + # Run the checker + $checker = new Selima::imacat::Checker::Page(curform); + $error = $checker->check(qw(path ord title body kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::Page(curform); + $checker->redir(qw(del zhsync)); + $error = $checker->check(qw(path ord title body kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::Page(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + # A form to preview a submitted item + if (form_type eq "preview") { + html_preview; + + } else { + $FORM = new Selima::imacat::Form::Page($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + } + + # List the available items + } else { + $LIST = new Selima::imacat::List::Pages; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the page."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This page does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/papers.cgi b/htdocs/imacat/magicat/cgi-bin/papers.cgi new file mode 100755 index 0000000..97d1767 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/papers.cgi @@ -0,0 +1,253 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# papers.cgi: The research paper administration. + +# Copyright (c) 2012-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "papers", + -dbi_lock => {"papers" => LOCK_EX, + "pprauthr" => LOCK_EX, + "resrcher" => LOCK_EX, + "pprtags" => LOCK_EX, + "tags" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("papers")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::Paper($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::imacat::Checker::Paper(curform); + $error = $checker->check(qw(type year month title authors tags + pub pages doi url)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::Paper(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(type year month title authors tags + pub pages doi url)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::Paper(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::imacat::Form::Paper($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::imacat::List::Papers; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the paper."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This paper does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging authors list + @_ = qw(); + push @_, "resrcher.sn AS sn"; + push @_, "resrcher.name AS title"; + push @_, "resrcher.abbr AS abbr"; + $sql = "SELECT " . join(", ", @_) . " FROM resrcher" + . " LEFT JOIN pprauthr ON pprauthr.author=resrcher.sn" + . " WHERE pprauthr.paper=$sn" + . " ORDER BY resrcher.abbr;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"authorcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"authorcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"author$_"} = 1; + $CURRENT{"author$_" . "sn"} = $$row{"sn"}; + $CURRENT{"author$_" . "title"} = $$row{"title"}; + $CURRENT{"author$_" . "abbr"} = $$row{"abbr"}; + } + + # Obtain the belonging tags list + @_ = qw(); + push @_, "tags.sn AS sn"; + push @_, "tags.title AS title"; + $sql = "SELECT " . join(", ", @_) . " FROM tags" + . " LEFT JOIN pprtags ON pprtags.tag=tags.sn" + . " WHERE pprtags.paper=$sn" + . " ORDER BY tags.title;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"tagcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"tagcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"tag$_"} = 1; + $CURRENT{"tag$_" . "sn"} = $$row{"sn"}; + $CURRENT{"tag$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/pprauthr.cgi b/htdocs/imacat/magicat/cgi-bin/pprauthr.cgi new file mode 100755 index 0000000..4031bfe --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/pprauthr.cgi @@ -0,0 +1,233 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# pprauthr.cgi: The research paper author administration. + +# Copyright (c) 2012-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "pprauthr", + -dbi_lock => {"papers" => LOCK_SH, + "resrcher" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("papers")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::Paper::Author($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::imacat::Checker::Paper::Author(curform); + $checker->redir(qw(selpaper delpaper selauthor delauthor)); + $error = $checker->check(qw(paper author)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::Paper::Author(curform); + $checker->redir(qw(del selpaper delpaper selauthor delauthor)); + $error = $checker->check(qw(paper author)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::Paper::Author(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::imacat::Form::Paper::Author($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::imacat::List::Paper::Authors; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the paper author."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This paper author does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selpaper: Import the selected paper into the retrieved form +sub import_selpaper($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("paper", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "papers"; + return; +} + +# import_selauthor: Import the selected author into the retrieved form +sub import_selauthor($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("author", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "resrcher"; + return $FORM; +} diff --git a/htdocs/imacat/magicat/cgi-bin/pprtags.cgi b/htdocs/imacat/magicat/cgi-bin/pprtags.cgi new file mode 100755 index 0000000..7cf184c --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/pprtags.cgi @@ -0,0 +1,233 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# pprtags.cgi: The paper tag administration. + +# Copyright (c) 2012-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-19 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "pprtags", + -dbi_lock => {"papers" => LOCK_SH, + "tags" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("papers")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::Paper::Tag($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::imacat::Checker::Paper::Tag(curform); + $checker->redir(qw(selpaper delpaper seltag deltag)); + $error = $checker->check(qw(paper tag)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::Paper::Tag(curform); + $checker->redir(qw(del selpaper delpaper seltag deltag)); + $error = $checker->check(qw(paper tag)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::Paper::Tag(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::imacat::Form::Paper::Tag($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::imacat::List::Paper::Tags; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the paper tag."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This paper tag does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selpaper: Import the selected paper into the retrieved form +sub import_selpaper($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("paper", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "papers"; + return; +} + +# import_seltag: Import the selected tag into the retrieved form +sub import_seltag($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("tag", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "tags"; + return $FORM; +} diff --git a/htdocs/imacat/magicat/cgi-bin/pprtypes.cgi b/htdocs/imacat/magicat/cgi-bin/pprtypes.cgi new file mode 100755 index 0000000..dd4fe52 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/pprtypes.cgi @@ -0,0 +1,242 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# pprtypes.cgi: The research paper type administration. + +# Copyright (c) 2012-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-15 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "pprtypes", + -dbi_lock => {"papers" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("papers")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::Paper::Type($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new paper type from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + return {"msg"=>N_("This paper type has [numerate,_1,a paper,papers]. It cannot be deleted. To delete the type, [numerate,_1,its paper,all of its papers] must first be deleted."), + "margs"=>[$CURRENT{"pprcount"}], + "isform"=>0} + if $CURRENT{"pprcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new paper type from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + # Run the checker + $checker = new Selima::imacat::Checker::Paper::Type(curform); + $error = $checker->check(qw(ord title)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::Paper::Type(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(ord title)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::Paper::Type(curform); + $checker->redir(qw(cancel)); + return {"msg"=>N_("This paper type has [numerate,_1,a paper,papers]. It cannot be deleted. To delete the type, [numerate,_1,its paper,all of its papers] must first be deleted."), + "margs"=>[$CURRENT{"pprcount"}], + "isform"=>0} + if $CURRENT{"pprcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::imacat::Form::Paper::Type($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::imacat::List::Paper::Types; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the paper type."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This paper type does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging papers list + @_ = qw(); + push @_, "sn AS sn"; + push @_, "CONCAT(CAST(year AS text), ' - ', title) AS title"; + $sql = "SELECT " . join(", ", @_) . " FROM papers" + . " WHERE type=$sn" + . " ORDER BY year, title;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"pprcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"pprcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"ppr$_" . "sn"} = $$row{"sn"}; + $CURRENT{"ppr$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/rebuild.cgi b/htdocs/imacat/magicat/cgi-bin/rebuild.cgi new file mode 100755 index 0000000..a7acbec --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/rebuild.cgi @@ -0,0 +1,105 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# rebuild.cgi: The web page rebuilder. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-04 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); + +initenv(-restricted => 1, + -lastmod => 1, + -page_param => {"keywords" => N_("rebuild pages")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Rebuild($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + # Nothing to check here + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::Checker::Rebuild(curform); + $error = $checker->check(qw(type)); + return $error if defined $error; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $FORM); + $status = $_[0]; + $FORM = new Selima::Form::Rebuild($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/resrcher.cgi b/htdocs/imacat/magicat/cgi-bin/resrcher.cgi new file mode 100755 index 0000000..132cf3f --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/resrcher.cgi @@ -0,0 +1,237 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# resrcher.cgi: The researcher administration. + +# Copyright (c) 2012-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "resrcher", + -dbi_lock => {"papers" => LOCK_SH, + "pprauthr" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("researchers")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::Researcher($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + return {"msg"=>N_("This researcher has [numerate,_1,a paper,papers]. It cannot be deleted. To delete the researcher, [numerate,_1,its paper,all of its papers] must first be deleted."), + "margs"=>[$CURRENT{"pprcount"}], + "isform"=>0} + if $CURRENT{"pprcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::imacat::Checker::Researcher(curform); + $error = $checker->check(qw(name abbr)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::Researcher(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(name abbr)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::Researcher(curform); + $checker->redir(qw(cancel)); + return {"msg"=>N_("This researcher has [numerate,_1,a paper,papers]. It cannot be deleted. To delete the researcher, [numerate,_1,its paper,all of its papers] must first be deleted."), + "margs"=>[$CURRENT{"pprcount"}], + "isform"=>0} + if $CURRENT{"pprcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::imacat::Form::Researcher($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::imacat::List::Researchers; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the researcher."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This researcher does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging papers list + @_ = qw(); + push @_, "papers.sn AS sn"; + push @_, $DBH->strcat("CAST(papers.year AS text)", + "' - '", "papers.title") + . " AS title"; + $sql = "SELECT " . join(", ", @_) . " FROM papers" + . " LEFT JOIN pprauthr ON pprauthr.paper=papers.sn" + . " WHERE pprauthr.author=$sn" + . " ORDER BY papers.year DESC, papers.title;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"pprcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"pprcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"ppr$_" . "sn"} = $$row{"sn"}; + $CURRENT{"ppr$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/saveform.cgi b/htdocs/imacat/magicat/cgi-bin/saveform.cgi new file mode 100755 index 0000000..53f05e7 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/saveform.cgi @@ -0,0 +1,180 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# saveform.cgi: The session viewer. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-20 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub html_page($); +sub scan_data(); +sub html_select(); +sub html_savedform(); + +use File::Spec::Functions qw(catfile); + +use vars qw(@FORMIDS %SN); +@FORMIDS = qw(); +%SN = qw(); +initenv(-restricted => 1, + -allowed => [qw(GET HEAD)], + -dbi => DBI_NONE, + -lastmod => 0, + -page_param => {"keywords" => N_("saved forms")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $error; + + # Scan the saved forms and return the saved form IDs + scan_data; + # This is always a GET form + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + + # Form specified + if (defined $GET->param("savedform")) { + # Check if this form exists + return {"msg"=>N_("Form [_1] does not exist anymore. Please select another one."), + "margs"=>[$GET->param("savedform")], + "isform"=>0} + if !exists $SN{$GET->param("savedform")}; + } + + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $pagebar); + $status = $_[0]; + + html_header __("Manage the Saved Forms"); + html_errmsg $status; + html_select; + html_savedform; + html_footer; + + return; +} + +# scan_data: Scan the saved forms +sub scan_data() { + local ($_, %_); + my ($DH, $entry, $dir, $file); + + # Scanned before + return if scalar(@FORMIDS) > 0; + + $dir = $Selima::Session::DIR; + opendir $DH, $dir or http_500 "$dir: $!"; + while (defined($entry = readdir $DH)) { + next if $entry =~ /^\./; + $file = catfile($dir, $entry); + next if !-f $file || !-r $file; + $_ = $entry; + push @FORMIDS, $_; + $SN{$_} = $file; + } + closedir $DH or http_500 "$dir: $!"; + @FORMIDS = sort @FORMIDS; + + return; +} + +# html_select: Print the HTML selection +sub html_select() { + local ($_, %_); + my ($select, $request_file_h, $formid); + + # Return of there is no saved form currently + return if scalar(@FORMIDS) == 0; + + $request_file_h = h($REQUEST_FILE); + $select = h(__("Select")); + + $formid = defined $GET->param("savedform")? $GET->param("savedform"): ""; + + print << "EOT"; +
    +
    + + +
    +
    + +EOT + return; +} + +# html_savedform: Print the HTML saved form +sub html_savedform() { + local ($_, %_); + my ($FORM, $content); + + # Return if form not selected + return if !defined $GET->param("savedform"); + # Return if form not exists + return if !exists $SN{$GET->param("savedform")}; + # Get the content + $content = a2html(xfread($SN{$GET->param("savedform")})); + + print << "EOT"; +
    +
    +$content +
    +
    + +EOT + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/scptpriv.cgi b/htdocs/imacat/magicat/cgi-bin/scptpriv.cgi new file mode 100755 index 0000000..f792c40 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/scptpriv.cgi @@ -0,0 +1,223 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# scptpriv.cgi: The script privilege administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); + +initenv(-restricted => 1, + -this_table => "scptpriv", + -dbi_lock => {"scptpriv" => LOCK_EX, + "groups" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("script privilege")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::ScptPriv($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(selgrp delgrp)); + $error = $checker->check(qw(script grp)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(del selgrp delgrp)); + $error = $checker->check(qw(script grp)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::ScptPriv($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::ScptPriv; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the script privilege record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This script privilege record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/showenv.cgi b/htdocs/imacat/magicat/cgi-bin/showenv.cgi new file mode 100755 index 0000000..7b6cf96 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/showenv.cgi @@ -0,0 +1,1054 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# showenv.cgi: The CGI parameters and environment viewer. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-04 + +use 5.006; +use strict; +use warnings; +use CGI qw(header); +use CGI::Cookie qw(); +use Config qw(%Config); +use Cwd qw(cwd); +use Data::Dumper qw(); +use Encode qw(is_utf8); +use IO::NestedCapture qw(CAPTURE_STDOUT); +use Sys::Hostname qw(hostname); +use lib $ENV{"DOCUMENT_ROOT"} . qw(/../../lib/perl5); +use Selima::HTTP; +local $SIG{"__DIE__"} = \&http_500; +# Prototype declaration +sub main($); +sub html_header(); +sub html_dump_get(); +sub html_dump_post(); +sub html_dump_cookies(); +sub html_dump_env(); +sub html_dump_perlvar(); +sub html_dump_perl_inc_array(); +sub html_dump_perl_inc_hash(); +sub html_dump_perl_apache($); +sub html_dump_perl_config(); +sub html_dump_misc(); +sub html_footer(); +sub h($); +sub val_complex($); +sub a2html($); +sub ft($); +sub dump_bin($); +sub dump_bin_chr($$); +BEGIN { +if (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + require Apache2::Connection; + require Apache2::ServerRec; +} +} + +use vars qw(@HEX); +@HEX = qw(0 1 2 3 4 5 6 7 8 9 A B C D E F); +my $r; +$r = shift if exists $ENV{"MOD_PERL"}; +$Data::Dumper::Indent = 1; + +main $r; +exit 0; + +sub main($) { + local ($_, %_); + my ($r, $FD); + $r = $_[0]; + + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header; + html_dump_get; + html_dump_post; + html_dump_cookies; + html_dump_env; + html_dump_perlvar; + html_dump_perl_inc_array; + html_dump_perl_inc_hash; + html_dump_perl_apache $r; + html_dump_perl_config; + html_dump_misc; + html_footer; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + + print header( -type=>"text/html; charset=Big5", + -Content_Length=>length $_); + print $_ if $ENV{"REQUEST_METHOD"} ne "HEAD"; + + return; +} + +sub html_dump_get() { + local ($_, %_); + my ($name, @vals, $oddrow, $rowclass, $GET); + + if (!exists $ENV{"QUERY_STRING"} || $ENV{"QUERY_STRING"} eq "") { + print << "EOT"; +
    +
    +

    GET Parameters

    + +

    None.

    +
    + +EOT + return; + } + + $GET = new CGI($ENV{"QUERY_STRING"}); + + print << "EOT"; +
    +
    +

    GET Parameters

    + + + + + + + + + + +EOT + $oddrow = 0; + foreach $name ($GET->param) { + @vals = $GET->param($name); + $name = h($name); + if (scalar(@vals) == 1) { + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + $vals[0] = h($vals[0]); + print << "EOT"; + + + + +EOT + } else { + for ($_ = 0; $_ < @vals; $_++) { + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + $vals[$_] = h($vals[$_]); + print << "EOT"; + + + + +EOT + } + } + } + print << "EOT"; + +
    NameValue
    $name$vals[0]
    $name ($_)$vals[$_]
    +
    + +EOT + return; +} + +sub html_dump_post() { + local ($_, %_); + my ($name, @vals, $oddrow, $rowclass, $POST); + + if ($ENV{"REQUEST_METHOD"} ne "POST") { + print << "EOT"; +
    +
    +

    POST Parameters

    + +

    Not a POST request.

    +
    + +EOT + return; + } + + eval { require Selima::DataVars; }; + $POST = $Selima::DataVars::USER_INPUT{"POST_RAW"} + if $@ ne "" && exists $Selima::DataVars::USER_INPUT{"POST_RAW"}; + $POST = new CGI if !defined $POST; + + if (scalar(@_ = $POST->param) == 0) { + print << "EOT"; +
    +
    +

    POST Parameters

    + +

    None.

    +
    + +EOT + return; + } + + print << "EOT"; +
    +
    +

    POST Parameters

    + + + + + + + + + + +EOT + $oddrow = 0; + foreach $name ($POST->param) { + @vals = $POST->param($name); + $name = h($name); + if (scalar(@vals) == 1) { + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + $vals[0] = h($vals[0]); + print << "EOT"; + + + + +EOT + } else { + for ($_ = 0; $_ < @vals; $_++) { + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + $vals[$_] = h($vals[$_]); + print << "EOT"; + + + + +EOT + } + } + } + print << "EOT"; + +
    NameValue
    $name$vals[0]
    $name ($_)$vals[$_]
    +
    + +EOT + return; +} + +sub html_dump_cookies() { + local ($_, %_); + my ($name, $value, $oddrow, $rowclass, %COOKIES); + + %COOKIES = fetch CGI::Cookie; + + if (scalar(keys %COOKIES) == 0) { + print << "EOT" ; +
    +
    +

    Cookies

    + +

    None.

    +
    + +EOT + return; + } + + print << "EOT"; +
    +
    +

    Cookies

    + + + + + + + + + + +EOT + $oddrow = 0; + foreach (sort keys %COOKIES) { + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + ($name, $value) = (h($_), h($COOKIES{$_}->value)); + print << "EOT"; + + + + +EOT + } + print << "EOT"; + +
    NameValue
    $name$value
    +
    + +EOT + return; +} + +sub html_dump_env() { + local ($_, %_); + my ($name, $value, $oddrow, $rowclass); + + print << "EOT"; +
    +
    +

    Environment Variables

    + + + + + + + + + + +EOT + $oddrow = 0; + foreach (sort keys %ENV) { + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + ($name, $value) = (h($_), h($ENV{$_})); + print << "EOT"; + + + + +EOT + } + print << "EOT"; + +
    NameValue
    $name$value
    +
    + +EOT + return; +} + +sub html_dump_perlvar() { + local ($_, %_); + my ($name, $value, $desc, $oddrow, $rowclass); + + print << "EOT"; +
    +
    +

    Perl Variables

    + + + + + + + + + + + +EOT + + $oddrow = 0; + + # PID + ($name, $value, $desc) = ("\$\$", h($$), h("Process ID")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + + +EOT + + # UID + ($name, $value, $desc) = ("\$<", h($<), h("Real User ID")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + + +EOT + + # EUID + ($name, $value, $desc) = ("\$>", h($>), h("Effective User ID")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + + +EOT + + # GID + ($name, $value, $desc) = ("\$(", h($(), h("Real Group ID")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + + +EOT + + # EGID + ($name, $value, $desc) = ("\$)", h($)), h("Effective Group ID")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + + +EOT + + # PROGRAM_NAME + ($name, $value, $desc) = (h("\$0"), h($0), h("Program Name")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + + +EOT + + # VERSION + ($name, $value, $desc) = (h("\$]"), h($]), h("Perl Version (Old)")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + + +EOT + + # OSNAME + ($name, $value, $desc) = (h("\$^O"), h($^O), h("OS Name")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + + +EOT + + # BASETIME + ($name, $value, $desc) = (h("\$^T"), h($^T . " (" . ft($^T) . ")"), h("Basetime")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + + +EOT + + # TAINT + ($name, $value, $desc) = (h("\${^TAINT}"), h(${^TAINT}), h("Taint")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + + +EOT + + # PERL_VERSION + ($name, $value, $desc) = (h("\$^V"), h(dump_bin $^V), h("Perl Version")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + + +EOT + + # WARNING + ($name, $value, $desc) = (h("\$^W"), h($^W), h("Warning")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + + +EOT + + # EXECUTABLE_NAME + ($name, $value, $desc) = (h("\$^X"), h($^X), h("Executable Name")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + + +EOT + + print << "EOT"; + +
    NameValueDescription
    $name$value$desc
    $name$value$desc
    $name$value$desc
    $name$value$desc
    $name$value$desc
    $name$value$desc
    $name$value$desc
    $name$value$desc
    $name$value$desc
    $name$value$desc
    $name$value$desc
    $name$value$desc
    $name$value$desc
    +
    + +EOT + return; +} + +sub html_dump_perl_inc_array() { + local ($_, %_); + my ($path, $oddrow, $rowclass); + + print << "EOT"; +
    +
    +

    Perl \@INC Paths

    + + + + +EOT + $oddrow = 0; + foreach (@INC) { + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + $path = h($_); + print << "EOT"; + + + +EOT + } + print << "EOT"; + +
    $path
    +
    + +EOT + return; +} + +sub html_dump_perl_inc_hash() { + local ($_, %_); + my ($name, $value, $oddrow, $rowclass); + + print << "EOT"; +
    +
    +

    Perl %INC Loaded Files

    + + + + + + + + + + +EOT + $oddrow = 0; + foreach (sort keys %INC) { + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + $value = defined $INC{$_}? $INC{$_}: "(undef)"; + ($name, $value) = (h($_), h($value)); + print << "EOT"; + + + + +EOT + } + print << "EOT"; + +
    NameValue
    $name$value
    +
    + +EOT + return; +} + +sub html_dump_perl_config() { + local ($_, %_); + my ($name, $value, $oddrow, $rowclass); + + print << "EOT"; +
    +
    +

    Perl Configuration

    + + + + + + + + + + +EOT + $oddrow = 0; + foreach (sort keys %Config) { + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + $value = defined $Config{$_}? $Config{$_}: "(undef)"; + ($name, $value) = (h($_), h($value)); + print << "EOT"; + + + + +EOT + } + print << "EOT"; + +
    NameValue
    $name$value
    +
    + +EOT + return; +} + +sub html_dump_perl_apache($) { + local ($_, %_); + my ($name, $value, $oddrow, $rowclass, @methods, $r, $c, $s); + $r = $_[0]; + + if (!exists $ENV{"MOD_PERL"}) { + print << "EOT" ; +
    +
    +

    Perl mod_perl Apache Request Object

    + +

    Not under Apache mod_perl.

    +
    + +EOT + return; + } + + print << "EOT"; +
    +
    +

    Perl mod_perl Apache Request Object

    + + + + + + + + + + +EOT + $oddrow = 0; + + if (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + @methods = qw( +allowed ap_auth_type args assbackwards bytes_sent connection content_encoding +content_languages content_type err_headers_out filename finfo handler +header_only headers_in headers_out hostname input_filters main method +method_number mtime next no_local_copy notes output_filters path_info +per_dir_config pool prev proto_input_filters proto_num proto_output_filters +protocol proxyreq request_time server status status_line subprocess_env +the_request unparsed_uri uri user +); + } else { + @methods = qw( +as_string main prev next last is_main is_initial_req allowed +method method_number bytes_sent the_request proxyreq header_only +protocol hostname request_time uri filename location path_info +args headers_in content get_remote_host get_remote_logname +requires auth_type auth_name document_root server_root_relative +allow_options get_server_port current_callback +); + } + foreach $name (@methods) { + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + undef $value; + $value = &$_($r) if defined($_ = $r->can($name)); + ($name, $value) = (h($name), val_complex($value)); + print << "EOT"; + + + + +EOT + } + + $c = $r->connection; + if (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + @methods = qw( +aborted base_server bucket_alloc client_socket get_remote_host id +input_filters keepalive keepalives local_addr local_host local_ip notes +output_filters pool remote_addr remote_ip remote_host +); + } else { + @methods = qw( +remote_host remote_ip local_addr remote_addr remote_logname +user auth_type aborted +); + } + foreach $name (@methods) { + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + undef $value; + $value = &$_($c) if defined($_ = $c->can($name)); + $value = dump_bin $value + if $name eq "local_addr" || $name eq "remote_addr"; + ($name, $value) = (h($name), val_complex($value)); + $value =~ s/(\r?\n)/
    $1/g; + print << "EOT"; + + + + +EOT + } + + $s = $r->server; + if (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + @methods = qw( +error_fname is_virtual keep_alive keep_alive_max keep_alive_timeout +limit_req_fields limit_req_fieldsize limit_req_line loglevel next path port +process server_admin server_hostname timeout +); + } else { + @methods = qw( +server_admin server_hostname port is_virtual names uid gid +loglevel +); + } + foreach $name (@methods) { + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + undef $value; + $value = &$_($s) if defined($_ = $s->can($name)); + ($name, $value) = (h($name), val_complex($value)); + $value =~ s/(\r?\n)/
    $1/g; + print << "EOT"; + + + + +EOT + } + + print << "EOT"; + +
    NameValue
    \$r->$name$value
    \$r->connection->$name$value
    \$r->server->$name$value
    +
    + +EOT + return; +} + +sub html_dump_misc() { + local ($_, %_); + my ($name, $value, $oddrow, $rowclass); + + print << "EOT"; +
    +
    +

    Miscellaneous Parameters

    + + + + + + + + + + +EOT + $oddrow = 0; + + # Process owner + my $procuid; + $procuid = getlogin; + $procuid = getpwuid $< if !defined $procuid; + ($name, $value) = (h("Process Owner"), h(defined $procuid? $procuid: "(n/a)")); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + +EOT + + # Current working directory + ($name, $value) = (h("Current Working Directory"), h(cwd)); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + +EOT + + # Hostname + ($name, $value) = (h("Hostname"), h(hostname)); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + +EOT + + # mod_perl Environment + $value = exists $ENV{"MOD_PERL"}? "yes": "no"; + ($name, $value) = (h("mod_perl"), h($value)); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + +EOT + + # ActiveState Perl for ISAPI Environment + $value = exists $ENV{"PERLXS"} && $ENV{"PERLXS"} eq "PerlIS"? "yes": "no"; + ($name, $value) = (h("Perl for ISAPI"), h($value)); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + +EOT + + # PerlXS + $value = exists $ENV{"PERLXS"}? $ENV{"PERLXS"}: "(n/a)"; + ($name, $value) = (h("\$ENV{\"PERLXS\"}"), h($value)); + $oddrow = !$oddrow; + $rowclass = $oddrow? "oddrow": "evenrow"; + print << "EOT"; + + + + +EOT + + print << "EOT"; + +
    NameValue
    $name$value
    $name$value
    $name$value
    $name$value
    $name$value
    $name$value
    +
    + +EOT + return; +} + +sub html_header() { + print << "EOT"; + + + + + + + + + + +CGI Parameters + + + +

    CGI Parameters

    + + + +EOT + return; +} + +sub html_footer() { + $_ = "Level Triple-A conformance icon, \n W3C-WAI Web Content Accessibility Guidelines 1.0"; + print << "EOT"; +
    +
    +CSS|Valid XHTML 1.1!|Valid CSS!|$_ +By imacat <imacat\@mail.imacat.idv.tw> +
    + + + +EOT + return; +} + +sub h($) { + local ($_, %_); + $_ = $_[0]; + s/&/&/g; + s//>/g; + s/"/"/g; # (xgettext) " + return $_; +} + +sub val_complex($) { + local ($_, %_); + $_ = $_[0]; + # Undefined + return "(undef)" if !defined $_; + # Scalar value + if (ref $_ eq "") { + return h($_) if /^[^\r\n]*$/; + return a2html($_); + } + # Complex value -- use Data::Dumper + $_ = Data::Dumper->Dump([$_], [qw($_)]); + s/^\s*\$_\s*=\s*//; + return a2html($_); +} + +sub a2html($) { + local ($_, %_); + $_ = $_[0]; + $_ = h($_); + s/(\r?\n)/
    $1/g; + s/^ / /mg; + s/ /  /g; + return $_; +} + +sub ft($) { + local ($_, %_); + $_ = $_[0]; + @_ = localtime $_; + $_ = sprintf "%04d-%02d-%02d %02d:%02d:%02d", + $_[5]+1900, $_[4]+1, $_[3], $_[2], $_[1], $_[0]; + return $_; +} + +# dump_bin: Dump a binary text string as its hex representation +sub dump_bin($) { + local ($_, %_); + my ($str, $is_utf8); + $str = $_[0]; + $is_utf8 = is_utf8($str); + @_ = split //, $str; + @_ = map dump_bin_chr($_, $is_utf8), @_; + return join("", @_); +} + +# dump_bin_chr: Dump a binary character as its hex representation +sub dump_bin_chr($$) { + local ($_, %_); + my ($n, $is_utf8); + ($_, $is_utf8) = @_; + $n = ord $_; + $_ = ""; + while ($n > 0) { + $_ = $HEX[$n & 15] . $_; + $n >>= 4; + } + $_ = "0" if $_ eq ""; + if ($is_utf8) { + $_ = "\\x{$_}"; + } else { + $_ = "0$_" if length($_) % 2 == 1; + $_ = "\\x$_"; + } + return $_; +} + +exit; diff --git a/htdocs/imacat/magicat/cgi-bin/tags.cgi b/htdocs/imacat/magicat/cgi-bin/tags.cgi new file mode 100755 index 0000000..95fe465 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/tags.cgi @@ -0,0 +1,237 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# tags.cgi: The tag administration. + +# Copyright (c) 2012-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-19 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "tags", + -dbi_lock => {"pprtags" => LOCK_EX, + "papers" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("tags")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::imacat::Processor::Tag($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + return {"msg"=>N_("This researcher has [numerate,_1,a paper,papers]. It cannot be deleted. To delete the researcher, [numerate,_1,its paper,all of its papers] must first be deleted."), + "margs"=>[$CURRENT{"pprcount"}], + "isform"=>0} + if $CURRENT{"pprcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::imacat::Checker::Tag(curform); + $error = $checker->check(qw(title)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::imacat::Checker::Tag(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(title)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::imacat::Checker::Tag(curform); + $checker->redir(qw(cancel)); + return {"msg"=>N_("This researcher has [numerate,_1,a paper,papers]. It cannot be deleted. To delete the researcher, [numerate,_1,its paper,all of its papers] must first be deleted."), + "margs"=>[$CURRENT{"pprcount"}], + "isform"=>0} + if $CURRENT{"pprcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::imacat::Form::Tag($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::imacat::List::Tags; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the researcher."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This researcher does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging papers list + @_ = qw(); + push @_, "papers.sn AS sn"; + push @_, $DBH->strcat("CAST(papers.year AS text)", + "' - '", "papers.title") + . " AS title"; + $sql = "SELECT " . join(", ", @_) . " FROM papers" + . " LEFT JOIN pprtags ON pprtags.paper=papers.sn" + . " WHERE pprtags.tag=$sn" + . " ORDER BY papers.year DESC, papers.title;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"pprcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"pprcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"ppr$_" . "sn"} = $$row{"sn"}; + $CURRENT{"ppr$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/test.cgi b/htdocs/imacat/magicat/cgi-bin/test.cgi new file mode 100755 index 0000000..4665c24 --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/test.cgi @@ -0,0 +1,73 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# test.cgi: The test script. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-20 + +use 5.008; +use utf8; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $r = shift; +my $d = new Selima::Destroy; +# Prototype declaration +use Time::HiRes qw(); +use IO::NestedCapture qw(CAPTURE_STDOUT); +initenv; +$CONTENT_TYPE = "text/plain"; + +if (0) { + # Send mails from local spool. + $_ = xfread "/tmp/imacat"; + @_ = split /\b(?=From )/, $_; + my $SENDMAIL; + my $counter = 0; + foreach (@_) { + if (s/^From (\S+) [^\n]+\nReturn-path: <\1>\n//) { + my $sender = $1; + my @cmd = qw(/usr/sbin/sendmail -odb); + push @cmd, ("-f", $sender); + push @cmd, "imacat\@mail.imacat.idv.tw"; + open $SENDMAIL, "|-", @cmd or http_500 $_[0] . ": $!"; + print $SENDMAIL $_ or http_500 $_[0] . ": $!"; + close $SENDMAIL or http_500 $_[0] . ": $!"; + $counter++; + print "$counter: $_\n"; + } elsif (s/^From (MAILER-DAEMON) [^\n]+\nReturn-path: <>\n//) { + my $sender = "MAILER-DAEMON\@rinse.wov.idv.tw"; + my @cmd = qw(/usr/sbin/sendmail -odb); + push @cmd, ("-f", $sender); + push @cmd, "imacat\@mail.imacat.idv.tw"; + open $SENDMAIL, "|-", @cmd or http_500 $_[0] . ": $!"; + print $SENDMAIL $_ or http_500 $_[0] . ": $!"; + close $SENDMAIL or http_500 $_[0] . ": $!"; + $counter++; + print "$counter: $_\n"; + } else { + print; + } + } +} + +printf "[%s] Done. %0.10f seconds elapsed.\n", + fmttime, Time::HiRes::time-$T_START; +exit 0; +no utf8; diff --git a/htdocs/imacat/magicat/cgi-bin/usermem.cgi b/htdocs/imacat/magicat/cgi-bin/usermem.cgi new file mode 100755 index 0000000..13940aa --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/usermem.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# usermem.cgi: The user-to-group membership administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-13 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); +sub import_selmember($); + +initenv(-restricted => 1, + -this_table => "usermem", + -dbi_lock => {"usermem" => LOCK_EX, + "groups" => LOCK_SH, + "users AS usrmembers" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("user membership")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::UserMem($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(del selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::UserMem($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::UserMem; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the membership record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This membership record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} + +# import_selmember: Import the selected user into the retrieved form +sub import_selmember($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("member", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users AS usrmembers"; + return $FORM; +} diff --git a/htdocs/imacat/magicat/cgi-bin/userpref.cgi b/htdocs/imacat/magicat/cgi-bin/userpref.cgi new file mode 100755 index 0000000..306cf7e --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/userpref.cgi @@ -0,0 +1,225 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# userpref.cgi: The user preference administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selusr($); + +initenv(-restricted => 1, + -this_table => "userpref", + -dbi_lock => {"userpref" => LOCK_EX, + "users" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("user preference")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::UserPref($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(selusr delusr)); + $error = $checker->check(qw(usr domain name value)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(del selusr delusr)); + $error = $checker->check(qw(usr domain name value)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::UserPref($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::UserPref; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the user preference."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This user preference does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selusr: Import the selected user into the retrieved form +sub import_selusr($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users") { + $FORM->param("usr", $GET->param("selsn")); + $FORM->param("everyone", "false"); + } + return; +} diff --git a/htdocs/imacat/magicat/cgi-bin/users.cgi b/htdocs/imacat/magicat/cgi-bin/users.cgi new file mode 100755 index 0000000..82bb0cb --- /dev/null +++ b/htdocs/imacat/magicat/cgi-bin/users.cgi @@ -0,0 +1,283 @@ +#! /usr/bin/perl -w +# Tavern IMACAT's +# users.cgi: The user account administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-28 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::imacat; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-this_table => "users", + -dbi_lock => {"users" => LOCK_EX, + "usermem" => LOCK_EX, + "userpref" => LOCK_EX, + "groupmem" => LOCK_SH, + "groups" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("users")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + # Password not saved + $POST->delete("passwd", "passwd2"); + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::User($POST); + $success = $processor->process; + # Password not saved + $POST->delete("passwd", "passwd2"); + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my ($error, $FORM, $sn); + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Check the privilege to manage this table + unauth if !is_script_permitted; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted || $sn == get_login_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted; + unauth if !is_su && (is_su $sn || $sn == get_login_sn); + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + + # List the available items + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + # List handler handles its own error + } + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error, $FORM, $sn); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Check the privilege to manage this table + unauth unless is_script_permitted; + # Run the checker + $checker = new Selima::Checker::User(curform); + $error = $checker->check(qw(id passwd name supgroup)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted || $sn == get_login_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::User(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(id passwd name supgroup)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted; + unauth if !is_su && (is_su $sn || $sn == get_login_sn); + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::User(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::User($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Users; + html_header $LIST->{"title"}, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lndb, $lndbdef, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the user."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This user does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging groups list + $lndb = getlang LN_DATABASE; + if (getlang eq $DEFAULT_LANG) { + $title = $DBH->strcat("groups.id", "' ('", + "groups.dsc_$lndb", "')'"); + } else { + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + $title = $DBH->strcat("groups.id", "' ('", + "COALESCE(groups.dsc_$lndb, groups.dsc_$lndbdef)", "')'"); + } + $sql = "SELECT groups.sn AS sn," + . " $title AS title FROM usermem" + . " INNER JOIN groups ON usermem.grp=groups.sn" + . " WHERE usermem.member=$sn" + . " AND groups.id!=" . $DBH->quote(SU_GROUP) + . " AND groups.id!=" . $DBH->quote(ADMIN_GROUP) + . " AND groups.id!=" . $DBH->quote(ALLUSERS_GROUP) + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"supgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"supgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"supgroup$_"} = 1; + $CURRENT{"supgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"supgroup$_" . "title"} = $$row{"title"}; + } + + # Get the admin flag + $CURRENT{"admin"} = is_admin($sn); + $CURRENT{"su"} = is_su($sn); + + # OK + return; +} diff --git a/htdocs/imacat/magicat/data/counter.dat b/htdocs/imacat/magicat/data/counter.dat new file mode 100644 index 0000000..ac87826 --- /dev/null +++ b/htdocs/imacat/magicat/data/counter.dat @@ -0,0 +1 @@ +16460 \ No newline at end of file diff --git a/htdocs/imacat/magicat/data/english_writings.csv b/htdocs/imacat/magicat/data/english_writings.csv new file mode 100644 index 0000000..0ab89fd --- /dev/null +++ b/htdocs/imacat/magicat/data/english_writings.csv @@ -0,0 +1,3 @@ +"date","subject","description","ekeywords","ckeywords" +"1994-05-12","The Drunk","This short novel was written long time ago in 1994 while I was still a college student. It was, actually, a homework of English class. I was crazy about writing then, and made 6 pieces of English writings instead of 3 of Teacher's request. Thanks for Teacher's understanding and helping me to finish it. It is not bad even from today's point of view, so I put it here now.","杜斯妥也夫斯基, 罪","Dostoyevsky, sin, guilt" +"1998-02-01","English Poetry","Triple written at Kaohsiuoung this Chinese New Year. I got a pair of new pants and new shoes that night.","燃, 飛, 跳躍","burn, fly, jump" \ No newline at end of file diff --git a/htdocs/imacat/magicat/include/footer.en.html b/htdocs/imacat/magicat/include/footer.en.html new file mode 100644 index 0000000..1745869 --- /dev/null +++ b/htdocs/imacat/magicat/include/footer.en.html @@ -0,0 +1,42 @@ +
    + diff --git a/htdocs/imacat/magicat/include/footer.zh-cn.html b/htdocs/imacat/magicat/include/footer.zh-cn.html new file mode 100644 index 0000000..f16b7f1 --- /dev/null +++ b/htdocs/imacat/magicat/include/footer.zh-cn.html @@ -0,0 +1,41 @@ +
    + diff --git a/htdocs/imacat/magicat/include/footer.zh-tw.html b/htdocs/imacat/magicat/include/footer.zh-tw.html new file mode 100644 index 0000000..c742def --- /dev/null +++ b/htdocs/imacat/magicat/include/footer.zh-tw.html @@ -0,0 +1,41 @@ +
    + diff --git a/htdocs/imacat/magicat/include/header.en.html b/htdocs/imacat/magicat/include/header.en.html new file mode 100644 index 0000000..33e88cf --- /dev/null +++ b/htdocs/imacat/magicat/include/header.en.html @@ -0,0 +1,12 @@ +
    + +
    diff --git a/htdocs/imacat/magicat/include/header.zh-cn.html b/htdocs/imacat/magicat/include/header.zh-cn.html new file mode 100644 index 0000000..f424dfd --- /dev/null +++ b/htdocs/imacat/magicat/include/header.zh-cn.html @@ -0,0 +1,12 @@ +
    + +
    diff --git a/htdocs/imacat/magicat/include/header.zh-tw.html b/htdocs/imacat/magicat/include/header.zh-tw.html new file mode 100644 index 0000000..a7f1cd6 --- /dev/null +++ b/htdocs/imacat/magicat/include/header.zh-tw.html @@ -0,0 +1,12 @@ +
    + +
    diff --git a/htdocs/imacat/magicat/index.html.en.html b/htdocs/imacat/magicat/index.html.en.html new file mode 120000 index 0000000..08fc4ee --- /dev/null +++ b/htdocs/imacat/magicat/index.html.en.html @@ -0,0 +1 @@ +index.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/magicat/index.html.en.xhtml b/htdocs/imacat/magicat/index.html.en.xhtml new file mode 100644 index 0000000..7eb7036 --- /dev/null +++ b/htdocs/imacat/magicat/index.html.en.xhtml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + +Magicat *^_^* + + + + + + + +
    + + +
    + + +
    +

    TAVERN’S MAGIAN

    +

    Hi, I’m
    Magicat. *^_^*

    +
    + +
    +There has been counter travellers! ^_*' +
    + +
    +

    Hello, I’m Magicat. I’m the Guardian Magian of the Tavern. I’m very powerful. I can do lots of wonderful things. But I only obbey the words from imacat. If you are not imacat, I’ll have to leave you alone. *^_^*

    + +

    Dear imacat, what is your order? *^_^*

    +
    + + + + +
    + + +
    + + + + diff --git a/htdocs/imacat/magicat/index.html.zh-cn.html b/htdocs/imacat/magicat/index.html.zh-cn.html new file mode 120000 index 0000000..5ee9c39 --- /dev/null +++ b/htdocs/imacat/magicat/index.html.zh-cn.html @@ -0,0 +1 @@ +index.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/magicat/index.html.zh-cn.xhtml b/htdocs/imacat/magicat/index.html.zh-cn.xhtml new file mode 100644 index 0000000..0c27879 --- /dev/null +++ b/htdocs/imacat/magicat/index.html.zh-cn.xhtml @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + +梅姬 *^_^* + + + + + + + +
    + + +
    + + +
    +

    旅舍魔法守护使

    +

    梅姬妳好

    +
    + +
    +目前有 访客计数器 位旅人。 +
    + +
    +

    妳好,我是梅姬猫。我是《旅舍依玛》的魔法守护使。我很厉害,可以做很多很了不起的事喔!但我只听老板娘吩咐。若妳不是旅舍老板娘,请不要随便呼唤我喔~! *^_^*

    + +

    亲爱的老板娘,有什么吩咐吗? *^_^*

    +
    + + + + +
    + + +
    + + + + diff --git a/htdocs/imacat/magicat/index.html.zh-tw.html b/htdocs/imacat/magicat/index.html.zh-tw.html new file mode 120000 index 0000000..6c1b76e --- /dev/null +++ b/htdocs/imacat/magicat/index.html.zh-tw.html @@ -0,0 +1 @@ +index.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/magicat/index.html.zh-tw.xhtml b/htdocs/imacat/magicat/index.html.zh-tw.xhtml new file mode 100644 index 0000000..0a1f6f4 --- /dev/null +++ b/htdocs/imacat/magicat/index.html.zh-tw.xhtml @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + +梅姬 *^_^* + + + + + + + +
    + + +
    + + +
    +

    旅舍魔法守護使

    +

    梅姬妳好

    +
    + +
    +目前有 訪客計數器 位旅人。 +
    + +
    +

    妳好,我是梅姬貓。我是《旅舍依瑪》的魔法守護使。我很厲害,可以做很多很了不起的事喔!但我只聽老闆娘吩咐。若妳不是旅舍老闆娘,請不要隨便呼喚我喔~! *^_^*

    + +

    親愛的老闆娘,有什麼吩咐嗎? *^_^*

    +
    + + + + +
    + + +
    + + + + diff --git a/htdocs/imacat/magicat/lib/acctsubj.sql b/htdocs/imacat/magicat/lib/acctsubj.sql new file mode 100644 index 0000000..99773cd --- /dev/null +++ b/htdocs/imacat/magicat/lib/acctsubj.sql @@ -0,0 +1,532 @@ +BEGIN TRANSACTION; +SET NAMES 'utf8'; +LOCK TABLE acctsubj IN ACCESS EXCLUSIVE MODE; +DELETE FROM acctsubj; +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (372638070, NULL, '1', '資產', 'assets', '资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (779709797, NULL, '2', '負債', 'liabilities', '负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (309096272, NULL, '3', '業主權益', 'owners’ equity', '业主权益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (471592709, NULL, '4', '營業收入', 'operating revenue', '营业收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (923390793, NULL, '5', '營業成本', 'operating costs', '营业成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (994752472, NULL, '6', '營業費用', 'operating expenses', '营业费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (962115884, NULL, '7', '營業外收入及費用', 'non-operating revenue and expenses, other income (expense)', '营业外收入及费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (657609207, NULL, '8', '所得稅費用(或利益)', 'income tax expense (or benefit)', '所得税费用(或利益)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (487023601, NULL, '9', '非經常營業損益', 'nonrecurring gain or loss', '非经常营业损益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (802972443, 372638070, '11', '流動資產', 'current assets', '流动资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (492735146, 372638070, '12', '流動資產', 'current assets', '流动资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (602662532, 372638070, '13', '基金及長期投資', 'funds and long-term investments', '基金及长期投资', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (601362886, 372638070, '14', '固定資產', 'property , plant, and equipment', '固定资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (463437233, 372638070, '15', '固定資產', 'property , plant, and equipment', '固定资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (813130827, 372638070, '16', '遞耗資產', 'depletable assets', '递耗资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (888645287, 372638070, '17', '無形資產', 'intangible assets', '无形资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (314299094, 372638070, '18', '其他資產', 'other assets', '其他资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (613824503, 779709797, '21', '流動負債', 'current liabilities', '流动负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (125993341, 779709797, '22', '流動負債', 'current liabilities', '流动负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (434222646, 779709797, '23', '長期負債', 'long-term liabilities', '长期负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (741596219, 779709797, '28', '其他負債', 'other liabilities', '其他负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (714179679, 309096272, '31', '資本', 'capital', '资本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (931945860, 309096272, '32', '資本公積', 'additional paid-in capital', '资本公积', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (926682414, 309096272, '33', '保留盈餘(或累積虧損)', 'retained earnings (accumulated deficit)', '保留盈余(或累积亏损)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (676136047, 309096272, '34', '權益調整', 'equity adjustments', '权益调整', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (793551134, 309096272, '35', '庫藏股', 'treasury stock', '库藏股', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (282449457, 309096272, '36', '少數股權', 'minority interest', '少数股权', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (256854212, 471592709, '41', '銷貨收入', 'sales revenue', '销货收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (864303332, 471592709, '46', '勞務收入', 'service revenue', '劳务收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (685194984, 471592709, '47', '業務收入', 'agency revenue', '业务收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (585168046, 471592709, '48', '其他營業收入', 'other operating revenue', '其他营业收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (776405888, 923390793, '51', '銷貨成本', 'cost of goods sold', '销货成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (484601714, 923390793, '56', '勞務成本製', 'ervice costs', '劳务成本制', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (656473437, 923390793, '57', '業務成本', 'gency costs', '业务成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (526117422, 923390793, '58', '其他營業成本', 'other operating costs', '其他营业成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (847838836, 994752472, '61', '推銷費用', 'selling expenses', '推销费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (202779691, 994752472, '62', '管理及總務費用', 'general & administrative expenses', '管理及总务费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (390721534, 994752472, '63', '研究發展費用', 'research and development expenses', '研究发展费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (613018617, 962115884, '71', '營業外收入', 'non-operating revenue', '营业外收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (874636860, 962115884, '72', '營業外收入', 'non-operating revenue', '营业外收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (933323474, 962115884, '73', '營業外收入', 'non-operating revenue', '营业外收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (837668432, 962115884, '74', '營業外收入', 'non-operating revenue', '营业外收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (658230315, 962115884, '75', '營業外費用', 'non-operating expenses', '营业外费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (963623186, 962115884, '76', '營業外費用', 'non-operating expenses', '营业外费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (726033439, 962115884, '77', '營業外費用', 'non-operating expenses', '营业外费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (107974953, 962115884, '78', '營業外費用', 'non-operating expenses', '营业外费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (531374062, 657609207, '81', '所得稅費用(或利益)', 'income tax expense (or benefit)', '所得税费用(或利益)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (441557451, 487023601, '91', '停業部門損益', 'gain (loss) from discontinued operations', '停业部门损益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (780750379, 487023601, '92', '非常損益', 'extraordinary gain or loss', '非常损益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (576655458, 487023601, '93', '會計原則變動累積影響數', 'cumulative effect of changes in accounting principles', '会计原则变动累积影响数', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (403027649, 487023601, '94', '少數股權淨利', 'minority interest income', '少数股权净利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (382831496, 802972443, '111', '現金及約當現金', 'cash and cash equivalents', '现金及约当现金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (405656198, 802972443, '112', '短期投資', 'short-term investments', '短期投资', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (274218035, 802972443, '113', '應收票據', 'notes receivable', '应收票据', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (236197229, 802972443, '114', '應收帳款', 'accounts receivable', '应收帐款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (990834888, 802972443, '118', '其他應收款', 'other receivables', '其他应收款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (802773250, 492735146, '121', '存貨', 'inventories', '存货', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (466973933, 492735146, '122', '存貨', 'inventories', '存货', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (434050648, 492735146, '125', '預付費用', 'prepaid expenses', '预付费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (349755763, 492735146, '126', '預付款項', 'prepayments', '预付款项', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (336471657, 492735146, '128', '其他流動資產', 'other current assets', '其他流动资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (956889094, 492735146, '129', '其他流動資產', 'other current assets', '其他流动资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (425778949, 602662532, '131', '基金', 'funds', '基金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (640420175, 602662532, '132', '長期投資', 'long-term investments', '长期投资', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (410421689, 601362886, '141', '土地', 'land', '土地', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (503393820, 601362886, '142', '土地改良物', 'land improvements', '土地改良物', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (630438297, 601362886, '143', '房屋及建物', 'buildings', '房屋及建物', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (208976106, 601362886, '144', '機(器)具及設備', 'machinery and equipment', '机(器)具及设备', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (809268229, 601362886, '145', '機(器)具及設備', 'machinery and equipment', '机(器)具及设备', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (885610140, 601362886, '146', '機(器)具及設備', 'machinery and equipment', '机(器)具及设备', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (227011522, 463437233, '151', '租賃資產', 'leased assets', '租赁资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (733081973, 463437233, '152', '租賃權益改良', 'leasehold improvements', '租赁权益改良', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (412438436, 463437233, '156', '未完工程及預付購置設備款', 'construction in progress and prepayments for equipment', '未完工程及预付购置设备款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (373441509, 463437233, '158', '雜項固定資產', 'miscellaneous property, plant, and equipment', '杂项固定资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (731330256, 813130827, '161', '遞耗資產', 'depletable assets', '递耗资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (940611412, 888645287, '171', '商標權', 'trademarks', '商标权', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (138316570, 888645287, '172', '專利權', 'patents', '专利权', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (563900191, 888645287, '173', '特許權', 'franchise', '特许权', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (423341137, 888645287, '174', '著作權', 'copyright', '著作权', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (271146494, 888645287, '175', '電腦軟體', 'computer software', '电脑软体', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (552238504, 888645287, '176', '商譽', 'goodwill', '商誉', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (207990296, 888645287, '177', '開辦費', 'organization costs', '开办费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (425720999, 888645287, '178', '其他無形資產', 'other intangibles', '其他无形资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (902673037, 314299094, '181', '遞延資產', 'deferred assets', '递延资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (966392319, 314299094, '182', '閒置資產', 'idle assets', '闲置资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (310547963, 314299094, '184', '長期應收票據及款項與催收帳款', 'long-term notes , accounts and overdue receivables', '长期应收票据及款项与催收帐款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (134097118, 314299094, '185', '出租資產', 'assets leased to others', '出租资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (393449422, 314299094, '186', '存出保證金', 'refundable deposit', '存出保证金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (464092583, 314299094, '188', '雜項資產', 'miscellaneous assets', '杂项资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (526855977, 613824503, '211', '短期借款', 'short-term borrowings (debt)', '短期借款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (974972811, 613824503, '212', '應付短期票券', 'short-term notes and bills payable', '应付短期票券', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (862092008, 613824503, '213', '應付票據', 'notes payable', '应付票据', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (705668893, 613824503, '214', '應付帳款', 'accounts pay able', '应付帐款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (815852043, 613824503, '216', '應付所得稅', 'income taxes payable', '应付所得税', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (287571641, 613824503, '217', '應付費用', 'accrued expenses', '应付费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (574165963, 613824503, '218', '其他應付款', 'other payables', '其他应付款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (674331210, 613824503, '219', '其他應付款', 'other payables', '其他应付款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (889654543, 125993341, '226', '預收款項', 'advance receipts', '预收款项', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (815683575, 125993341, '227', '一年或一營業週期內到期長期負債', 'long-term liabilities -current portion', '一年或一营业周期内到期长期负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (149212812, 125993341, '228', '其他流動負債', 'other current liabilities', '其他流动负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (124114781, 125993341, '229', '其他流動負債', 'other current liabilities', '其他流动负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (636315607, 434222646, '231', '應付公司債', 'corporate bonds payable', '应付公司债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (663524372, 434222646, '232', '長期借款', 'long-term loans payable', '长期借款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (602970356, 434222646, '233', '長期應付票據及款項', 'long-term notes and accounts payable', '长期应付票据及款项', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (319948252, 434222646, '234', '估計應付土地增值稅', 'accrued liabilities for land value increment tax', '估计应付土地增值税', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (489620321, 434222646, '235', '應計退休金負債', 'accrued pension liabilities', '应计退休金负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (931718543, 434222646, '238', '其他長期負債', 'other long-term liabilities', '其他长期负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (301894518, 741596219, '281', '遞延負債', 'deferred liabilities', '递延负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (753924220, 741596219, '286', '存入保證金', 'deposits received', '存入保证金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (492886608, 741596219, '288', '雜項負債', 'miscellaneous liabilities', '杂项负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (354712237, 714179679, '311', '資本(或股本)', 'capital', '资本(或股本)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (813886254, 931945860, '321', '股票溢價', 'paid-in capital in excess of par', '股票溢价', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (369189273, 931945860, '323', '資產重估增值準備', 'capital surplus from assets revaluation', '资产重估增值准备', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (708649341, 931945860, '324', '處分資產溢價公積', 'capital surplus from gain on disposal of assets', '处分资产溢价公积', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (315953593, 931945860, '325', '合併公積', 'capital surplus from business combination', '合并公积', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (974832633, 931945860, '326', '受贈公積', 'donated surplus', '受赠公积', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (981029756, 931945860, '328', '其他資本公積', 'other additional paid-in capital', '其他资本公积', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (782463283, 926682414, '331', '法定盈餘公積', 'legal reserve', '法定盈余公积', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (511595327, 926682414, '332', '特別盈餘公積', 'special reserve', '特别盈余公积', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (266224620, 926682414, '335', '未分配盈餘(或累積虧損)', 'retained earnings-unappropriated (or accumulated deficit)', '未分配盈余(或累积亏损)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (306542380, 676136047, '341', '長期股權投資未實現跌價損失', 'unrealized loss on market value decline of long-term equity investments', '长期股权投资未实现跌价损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (385524103, 676136047, '342', '累積換算調整數', 'cumulative translation adjustment', '累积换算调整数', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (764640716, 676136047, '343', '未認列為退休金成本之淨損失', 'net loss not recognized as pension cost', '未认列为退休金成本之净损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (277312763, 793551134, '351', '庫藏股', 'treasury stock', '库藏股', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (172889653, 282449457, '361', '少數股權', 'minority interest', '少数股权', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (960138746, 256854212, '411', '銷貨收入', 'sales revenue', '销货收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (989545725, 256854212, '417', '銷貨退回', 'sales return', '销货退回', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (745165875, 256854212, '419', '銷貨折讓', 'sales allowances', '销货折让', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (788006197, 864303332, '461', '勞務收入', 'service revenue', '劳务收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (636092325, 685194984, '471', '業務收入', 'agency revenue', '业务收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (560294799, 585168046, '488', '其他營業收入—其他', 'other operating revenue', '其他营业收入—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (868329781, 776405888, '511', '銷貨成本', 'cost of goods sold', '销货成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (715512696, 776405888, '512', '進貨', 'purchases', '进货', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (900537319, 776405888, '513', '進料', 'materials purchased', '进料', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (613686812, 776405888, '514', '直接人工', 'direct labor', '直接人工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (241828224, 776405888, '515', '製造費用', 'manufacturing overhead', '制造费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (181591613, 776405888, '516', '製造費用', 'manufacturing overhead', '制造费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (304113670, 776405888, '517', '製造費用', 'manufacturing overhead', '制造费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (302614029, 776405888, '518', '製造費用', 'manufacturing overhead', '制造费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (181853880, 484601714, '561', '勞務成本', 'service costs', '劳务成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (760077428, 656473437, '571', '業務成本', 'agency costs', '业务成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (100599165, 526117422, '588', '其他營業成本—其他', 'other operating costs-other', '其他营业成本—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (212916398, 847838836, '615', '推銷費用', 'selling expenses', '推销费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (193074244, 847838836, '616', '推銷費用', 'selling expenses', '推销费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (882721016, 847838836, '617', '推銷費用', 'selling expenses', '推销费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (514554832, 847838836, '618', '推銷費用', 'selling expenses', '推销费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (241184521, 202779691, '625', '管理及總務費用', 'general & administrative expenses', '管理及总务费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (776997540, 202779691, '626', '管理及總務費用', 'general & administrative expenses', '管理及总务费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (324522418, 202779691, '627', '管理及總務費用', 'general & administrative expenses', '管理及总务费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (543298708, 202779691, '628', '管理及總務費用', 'general & administrative expenses', '管理及总务费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (751717808, 390721534, '635', '研究發展費用', 'research and development expenses', '研究发展费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (509842953, 390721534, '636', '研究發展費用', 'research and development expenses', '研究发展费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (334520736, 390721534, '637', '研究發展費用', 'research and development expenses', '研究发展费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (647304802, 390721534, '638', '研究發展費用', 'research and development expenses', '研究发展费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (748583072, 613018617, '711', '利息收入', 'interest revenue', '利息收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (807935097, 613018617, '712', '投資收益', 'investment income', '投资收益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (256128674, 613018617, '713', '兌換利益', 'foreign exchange gain', '兑换利益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (902036208, 613018617, '714', '處分投資收益', 'gain on disposal of investments', '处分投资收益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (206038830, 613018617, '715', '處分資產溢價收入', 'gain on disposal of assets', '处分资产溢价收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (699454747, 837668432, '748', '其他營業外收入', 'other non-operating revenue', '其他营业外收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (988959446, 658230315, '751', '利息費用', 'interest expense', '利息费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (548598499, 658230315, '752', '投資損失', 'investment loss', '投资损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (947980201, 658230315, '753', '兌換損失', 'foreign exchange loss', '兑换损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (286649244, 658230315, '754', '處分投資損失', 'loss on disposal of investments', '处分投资损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (537384847, 658230315, '755', '處分資產損失', 'loss on disposal of assets', '处分资产损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (928820789, 107974953, '788', '其他營業外費用', 'other non-operating expenses', '其他营业外费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (687819205, 531374062, '811', '所得稅費用(或利益)', 'income tax expense (or benefit)', '所得税费用(或利益)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (392121771, 441557451, '911', '停業部門損益—停業前營業損益', 'income (loss) from operations of discontinued segments', '停业部门损益—停业前营业损益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (816367329, 441557451, '912', '停業部門損益—處分損益', 'gain (loss) from disposal of discontinued segments', '停业部门损益—处分损益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (749878410, 780750379, '921', '非常損益', 'extraordinary gain or loss', '非常损益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (575458948, 576655458, '931', '會計原則變動累積影響數', 'cumulative effect of changes in accounting principles', '会计原则变动累积影响数', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (867926470, 403027649, '941', '少數股權淨利', 'minority interest income', '少数股权净利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (709320418, 382831496, '1111', '庫存現金', 'cash on hand', '库存现金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (135867103, 382831496, '1112', '零用金/週轉金', 'petty cash/revolving funds', '零用金/周转金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (321673137, 382831496, '1113', '銀行存款', 'cash in banks', '银行存款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (914806389, 382831496, '1116', '在途現金', 'cash in transit', '在途现金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (408077817, 382831496, '1117', '約當現金', 'cash equivalents', '约当现金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (269390224, 382831496, '1118', '其他現金及約當現金', 'other cash and cash equivalents', '其他现金及约当现金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (114003147, 405656198, '1121', '短期投資—股票', 'short-term investments – stock', '短期投资—股票', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (420496091, 405656198, '1122', '短期投資—短期票券', 'short-term investments – short-term notes and bills', '短期投资—短期票券', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (494011567, 405656198, '1123', '短期投資—政府債券', 'short-term investments – government bonds', '短期投资—政府债券', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (249856724, 405656198, '1124', '短期投資—受益憑證', 'short-term investments – beneficiary certificates', '短期投资—受益凭证', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (216784076, 405656198, '1125', '短期投資—公司債', 'short-term investments – corporate bonds', '短期投资—公司债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (816605640, 405656198, '1128', '短期投資—其他', 'short-term investments – other', '短期投资—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (719765760, 405656198, '1129', '備抵短期投資跌價損失', 'allowance for reduction of short-term investment to market', '备抵短期投资跌价损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (530499921, 274218035, '1131', '應收票據', 'notes receivable', '应收票据', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (983472201, 274218035, '1132', '應收票據貼現', 'discounted notes receivable', '应收票据贴现', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (460805176, 274218035, '1137', '應收票據—關係人', 'notes receivable – related parties', '应收票据—关系人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (221108972, 274218035, '1138', '其他應收票據', 'other notes receivable', '其他应收票据', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (190869303, 274218035, '1139', '備抵呆帳-應收票據', 'allowance for uncollec- tible accounts– notes receivable', '备抵呆帐-应收票据', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (357244797, 236197229, '1141', '應收帳款', 'accounts receivable', '应收帐款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (138999680, 236197229, '1142', '應收分期帳款', 'installment accounts receivable', '应收分期帐款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (171512916, 236197229, '1147', '應收帳款—關係人', 'accounts receivable – related parties', '应收帐款—关系人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (742536124, 236197229, '1149', '備抵呆帳-應收帳款', 'allowance for uncollec- tible accounts – accounts receivable', '备抵呆帐-应收帐款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (508867657, 990834888, '1181', '應收出售遠匯款', 'forward exchange contract receivable', '应收出售远汇款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (616644337, 990834888, '1182', '應收遠匯款—外幣', 'forward exchange contract receivable – foreign currencies', '应收远汇款—外币', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (302006318, 990834888, '1183', '買賣遠匯折價', 'discount on forward ex-change contract', '买卖远汇折价', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (903867355, 990834888, '1184', '應收收益', 'earned revenue receivable', '应收收益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (854876598, 990834888, '1185', '應收退稅款', 'income tax refund receivable', '应收退税款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (641587374, 990834888, '1187', '其他應收款—關係人', 'other receivables – related parties', '其他应收款—关系人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (654713656, 990834888, '1188', '其他應收款—其他', 'other receivables – other', '其他应收款—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (254902966, 990834888, '1189', '備抵呆帳—其他應收款', 'allowance for uncollec- tible accounts – other receivables', '备抵呆帐—其他应收款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (517810159, 802773250, '1211', '商品存貨', 'merchandise inventory', '商品存货', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (856687013, 802773250, '1212', '寄銷商品', 'consigned goods', '寄销商品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (349662815, 802773250, '1213', '在途商品', 'goods in transit', '在途商品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (949622536, 802773250, '1219', '備抵存貨跌價損失', 'allowance for reduction of inventory to market', '备抵存货跌价损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (269987198, 466973933, '1221', '製成品', 'finished goods', '制成品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (339342377, 466973933, '1222', '寄銷製成品', 'consigned finished goods', '寄销制成品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (795640862, 466973933, '1223', '副產品', 'by-products', '副产品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (713275114, 466973933, '1224', '在製品', 'work in process', '在制品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (237383628, 466973933, '1225', '委外加工', 'work in process – outsourced', '委外加工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (968977504, 466973933, '1226', '原料', 'raw materials', '原料', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (712112558, 466973933, '1227', '物料', 'supplies', '物料', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (944100101, 466973933, '1228', '在途原物料', 'materials and supplies in transit', '在途原物料', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (407577736, 466973933, '1229', '備抵存貨跌價損失', 'allowance for reduction of inventory to market', '备抵存货跌价损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (880958169, 434050648, '1251', '預付薪資', 'prepaid payroll', '预付薪资', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (490823964, 434050648, '1252', '預付租金', 'prepaid rents', '预付租金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (917878000, 434050648, '1253', '預付保險費', 'prepaid insurance', '预付保险费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (970366836, 434050648, '1254', '用品盤存', 'office supplies', '用品盘存', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (996500723, 434050648, '1255', '預付所得稅', 'prepaid income tax', '预付所得税', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (473338112, 434050648, '1258', '其他預付費用', 'other prepaid expenses', '其他预付费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (820572193, 349755763, '1261', '預付貨款', 'prepayment for purchases', '预付货款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (739184995, 349755763, '1268', '其他預付款項', 'other prepayments', '其他预付款项', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (799510698, 336471657, '1281', '進項稅額', 'VAT paid ( or input tax)', '进项税额', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (360348142, 336471657, '1282', '留抵稅額', 'excess VAT paid (or overpaid VAT)', '留抵税额', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (108172724, 336471657, '1283', '暫付款', 'temporary payments', '暂付款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (331360768, 336471657, '1284', '代付款', 'payment on behalf of others', '代付款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (341189219, 336471657, '1285', '員工借支', 'advances to employees', '员工借支', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (576455206, 336471657, '1286', '存出保證金', 'refundable deposits', '存出保证金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (777109496, 336471657, '1287', '受限制存款', 'certificate of deposit-restricted', '受限制存款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (683845821, 956889094, '1291', '遞延所得稅資產', 'deferred income tax assets', '递延所得税资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (296452414, 956889094, '1292', '遞延兌換損失', 'deferred foreign exchange losses', '递延兑换损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (961765736, 956889094, '1293', '業主(股東)往來', 'owners’ (stockholders’) current account', '业主(股东)往来', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (775706481, 956889094, '1294', '同業往來', 'current account with others', '同业往来', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (114433500, 956889094, '1298', '其他流動資產—其他', 'other current assets – other', '其他流动资产—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (329070757, 425778949, '1311', '償債基金', 'redemption fund (or sinking fund)', '偿债基金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (141049975, 425778949, '1312', '改良及擴充基金', 'fund for improvement and expansion', '改良及扩充基金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (263604680, 425778949, '1313', '意外損失準備基金', 'contingency fund', '意外损失准备基金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (205596434, 425778949, '1314', '退休基金', 'pension fund', '退休基金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (477861646, 425778949, '1318', '其他基金', 'other funds', '其他基金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (269517922, 640420175, '1321', '長期股權投資', 'long-term equity investments', '长期股权投资', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (237455794, 640420175, '1322', '長期債券投資', 'long-term bond investments', '长期债券投资', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (645642557, 640420175, '1323', '長期不動產投資', 'long-term real estate in-vestments', '长期不动产投资', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (988732317, 640420175, '1324', '人壽保險現金解約價值', 'cash surrender value of life insurance', '人寿保险现金解约价值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (179029710, 640420175, '1328', '其他長期投資', 'other long-term investments', '其他长期投资', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (557110012, 640420175, '1329', '備抵長期投資跌價損失', 'allowance for excess of cost over market value of long-term investments', '备抵长期投资跌价损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (249470146, 410421689, '1411', '土地', 'land', '土地', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (247906429, 410421689, '1418', '土地—重估增值', 'land – revaluation increments', '土地—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (852596764, 503393820, '1421', '土地改良物', 'land improvements', '土地改良物', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (885681227, 503393820, '1428', '土地改良物—重估增值', 'land improvements – revaluation increments', '土地改良物—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (146158043, 503393820, '1429', '累積折舊—土地改良物', 'accumulated depreciation – land improvements', '累积折旧—土地改良物', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (732874115, 630438297, '1431', '房屋及建物', 'buildings', '房屋及建物', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (961492609, 630438297, '1438', '房屋及建物—重估增值', 'buildings –revaluation increments', '房屋及建物—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (472025359, 630438297, '1439', '累積折舊—房屋及建物', 'accumulated depreciation – buildings', '累积折旧—房屋及建物', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (443132757, 208976106, '1441', '機(器)具', 'machinery', '机(器)具', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (878642052, 208976106, '1448', '機(器)具—重估增值', 'machinery – revaluation increments', '机(器)具—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (176634779, 208976106, '1449', '累積折舊—機(器)具', 'accumulated depreciation – machinery', '累积折旧—机(器)具', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (167128653, 227011522, '1511', '租賃資產', 'leased assets', '租赁资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (894698061, 227011522, '1519', '累積折舊—租賃資產', 'accumulated depreciation – leased assets', '累积折旧—租赁资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (848449822, 733081973, '1521', '租賃權益改良', 'leasehold improvements', '租赁权益改良', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (752891550, 733081973, '1529', '累積折舊—租賃權益改良', 'accumulated depreciation – leasehold improvements', '累积折旧—租赁权益改良', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (852551772, 412438436, '1561', '未完工程', 'construction in progress', '未完工程', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (137095705, 412438436, '1562', '預付購置設備款', 'prepayment for equipment', '预付购置设备款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (917546730, 373441509, '1581', '雜項固定資產', 'miscellaneous property, plant, and equipment', '杂项固定资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (615691173, 373441509, '1588', '雜項固定資產—重估增值', 'miscellaneous property, plant, and equipment – revaluation increments', '杂项固定资产—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (334353583, 373441509, '1589', '累積折舊—雜項固定資產', 'accumulated depreciation – miscellaneous property, plant, and equipment', '累积折旧—杂项固定资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (631601277, 731330256, '1611', '天然資源', 'natural resources', '天然资源', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (494736884, 731330256, '1618', '天然資源—重估增值', 'natural resources –revaluation increments', '天然资源—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (708161453, 731330256, '1619', '累積折耗—天然資源', 'accumulated depletion – natural resources', '累积折耗—天然资源', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (898829698, 940611412, '1711', '商標權', 'trademarks', '商标权', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (542872803, 138316570, '1721', '專利權', 'patents', '专利权', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (664609986, 563900191, '1731', '特許權', 'franchise', '特许权', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (683710952, 423341137, '1741', '著作權', 'copyright', '著作权', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (655011428, 271146494, '1751', '電腦軟體', 'computer software cost', '电脑软体', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (491099730, 552238504, '1761', '商譽', 'goodwill', '商誉', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (780653448, 207990296, '1771', '開辦費', 'organization costs', '开办费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (623499301, 425720999, '1781', '遞延退休金成本', 'deferred pension costs', '递延退休金成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (485309798, 425720999, '1782', '租賃權益改良', 'leasehold improvements', '租赁权益改良', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (255497196, 425720999, '1788', '其他無形資產—其他', 'other intangible assets – other', '其他无形资产—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (949323475, 902673037, '1811', '債券發行成本', 'deferred bond issuance costs', '债券发行成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (985965124, 902673037, '1812', '長期預付租金', 'long-term prepaid rent', '长期预付租金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (761148020, 902673037, '1813', '長期預付保險費', 'long-term prepaid insurance', '长期预付保险费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (783218271, 902673037, '1814', '遞延所得稅資產', 'deferred income tax assets', '递延所得税资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (542736097, 902673037, '1815', '預付退休金', 'prepaid pension cost', '预付退休金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (442130454, 902673037, '1818', '其他遞延資產', 'other deferred assets', '其他递延资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (440158264, 966392319, '1821', '閒置資產', 'idle assets', '闲置资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (814490947, 310547963, '1841', '長期應收票據', 'long-term notes receivable', '长期应收票据', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (464584131, 310547963, '1842', '長期應收帳款', 'long-term accounts receivable', '长期应收帐款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (246737265, 310547963, '1843', '催收帳款', 'overdue receivables', '催收帐款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (269841085, 310547963, '1847', '長期應收票據及款項與催收帳款—關係人', 'long-term notes, accounts and overdue receivables– related parties', '长期应收票据及款项与催收帐款—关系人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (972215319, 310547963, '1848', '其他長期應收款項', 'other long-term receivables', '其他长期应收款项', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (273415222, 310547963, '1849', '備抵呆帳—長期應收票據及款項與催收帳款', 'allowance for uncollectible accounts – long-term notes, accounts and overdue receivables', '备抵呆帐—长期应收票据及款项与催收帐款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (342664393, 134097118, '1851', '出租資產', 'assets leased to others', '出租资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (967877399, 134097118, '1858', '出租資產—重估增值', 'assets leased to others – incremental value from revaluation', '出租资产—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (465680425, 134097118, '1859', '累積折舊—出租資產', 'accumulated depreciation – assets leased to others', '累积折旧—出租资产', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (169304689, 393449422, '1861', '存出保證金', 'refundable deposits', '存出保证金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (691103727, 464092583, '1881', '受限制存款', 'certificate of deposit – restricted', '受限制存款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (408984785, 464092583, '1888', '雜項資產—其他', 'miscellaneous assets – other', '杂项资产—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (114592873, 526855977, '2111', '銀行透支', 'bank overdraft', '银行透支', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (155572537, 526855977, '2112', '銀行借款', 'bank loan', '银行借款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (679537588, 526855977, '2114', '短期借款—業主', 'short-term borrowings – owners', '短期借款—业主', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (113826174, 526855977, '2115', '短期借款—員工', 'short-term borrowings – employees', '短期借款—员工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (535176493, 526855977, '2117', '短期借款—關係人', 'short-term borrowings– related parties', '短期借款—关系人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (554436773, 526855977, '2118', '短期借款—其他', 'short-term borrowings – other', '短期借款—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (845861820, 974972811, '2121', '應付商業本票', 'commercial paper payable', '应付商业本票', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (937575852, 974972811, '2122', '銀行承兌匯票', 'bank acceptance', '银行承兑汇票', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (626442033, 974972811, '2128', '其他應付短期票券', 'other short-term notes and bills payable', '其他应付短期票券', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (343837879, 974972811, '2129', '應付短期票券折價', 'discount on short-term notes and bills payable', '应付短期票券折价', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (602560682, 862092008, '2131', '應付票據', 'notes payable', '应付票据', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (188954343, 862092008, '2137', '應付票據—關係人', 'notes payable – related parties', '应付票据—关系人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (716389216, 862092008, '2138', '其他應付票據', 'other notes payable', '其他应付票据', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (778146915, 705668893, '2141', '應付帳款', 'accounts payable', '应付帐款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (277492307, 705668893, '2147', '應付帳款—關係人', 'accounts payable – related parties', '应付帐款—关系人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (458551240, 815852043, '2161', '應付所得稅', 'income tax payable', '应付所得税', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (247253522, 287571641, '2171', '應付薪工', 'accrued payroll', '应付薪工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (995680120, 287571641, '2172', '應付租金', 'accrued rent payable', '应付租金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (655731761, 287571641, '2173', '應付利息', 'accrued interest payable', '应付利息', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (795817638, 287571641, '2174', '應付營業稅', 'accrued VAT payable', '应付营业税', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (701122645, 287571641, '2175', '應付稅捐—其他', 'accrued taxes payable– other', '应付税捐—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (415046011, 287571641, '2178', '其他應付費用', 'other accrued expenses payable', '其他应付费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (303499610, 574165963, '2181', '應付購入遠匯款', 'forward exchange contract payable', '应付购入远汇款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (784043626, 574165963, '2182', '應付遠匯款—外幣', 'forward exchange contract payable – foreign currencies', '应付远汇款—外币', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (855311038, 574165963, '2183', '買賣遠匯溢價', 'premium on forward exchange contract', '买卖远汇溢价', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (196069634, 574165963, '2184', '應付土地房屋款', 'payables on land and building purchased', '应付土地房屋款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (344246957, 574165963, '2185', '應付設備款', 'Payables on equipment', '应付设备款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (522820430, 574165963, '2187', '其他應付款—關係人', 'other payables – related parties', '其他应付款—关系人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (256595974, 674331210, '2191', '應付股利', 'dividend payable', '应付股利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (831657893, 674331210, '2192', '應付紅利', 'bonus payable', '应付红利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (397555135, 674331210, '2193', '應付董監事酬勞', 'compensation payable to directors and supervisors', '应付董监事酬劳', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (727862503, 674331210, '2198', '其他應付款—其他', 'other payables – other', '其他应付款—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (968398485, 889654543, '2261', '預收貨款', 'sales revenue received in advance', '预收货款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (738337468, 889654543, '2262', '預收收入', 'revenue received in advance', '预收收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (563034212, 889654543, '2268', '其他預收款', 'other advance receipts', '其他预收款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (602636212, 815683575, '2271', '一年或一營業週期內到期公司債', 'corporate bonds payable – current portion', '一年或一营业周期内到期公司债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (661663180, 815683575, '2272', '一年或一營業週期內到期長期借款', 'long-term loans payable – current portion', '一年或一营业周期内到期长期借款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (395722825, 815683575, '2273', '一年或一營業週期內到期長期應付票據及款項', 'long-term notes and accounts payable due within one year or one operating cycle', '一年或一营业周期内到期长期应付票据及款项', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (658576158, 815683575, '2277', '一年或一營業週期內到期長期應付票據及款項—關係人', 'long-term notes and accounts payables to related parties – current portion', '一年或一营业周期内到期长期应付票据及款项—关系人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (968075004, 815683575, '2278', '其他一年或一營業週期內到期長期負債', 'other long-term lia- bilities – current portion', '其他一年或一营业周期内到期长期负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (832790463, 149212812, '2281', '銷項稅額', 'VAT received (or output tax)', '销项税额', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (520828967, 149212812, '2283', '暫收款', 'temporary receipts', '暂收款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (900155521, 149212812, '2284', '代收款', 'receipts under custody', '代收款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (962885081, 149212812, '2285', '估計售後服務/保固負債', 'estimated warranty liabilities', '估计售后服务/保固负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (667554008, 124114781, '2291', '遞延所得稅負債', 'deferred income tax liabilities', '递延所得税负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (150466923, 124114781, '2292', '遞延兌換利益', 'deferred foreign exchange gain', '递延兑换利益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (229204760, 124114781, '2293', '業主(股東)往來', 'owners’ current account', '业主(股东)往来', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (743752020, 124114781, '2294', '同業往來', 'current account with others', '同业往来', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (963358650, 124114781, '2298', '其他流動負債—其他', 'other current liabilities – others', '其他流动负债—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (994047310, 636315607, '2311', '應付公司債', 'corporate bonds payable', '应付公司债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (564067541, 636315607, '2319', '應付公司債溢(折)價', 'premium (discount) on corporate bonds payable', '应付公司债溢(折)价', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (332401391, 663524372, '2321', '長期銀行借款', 'long-term loans payable – bank', '长期银行借款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (241134962, 663524372, '2324', '長期借款—業主', 'long-term loans payable – owners', '长期借款—业主', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (536628622, 663524372, '2325', '長期借款—員工', 'long-term loans payable – employees', '长期借款—员工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (130108314, 663524372, '2327', '長期借款—關係人', 'long-term loans payable – related parties', '长期借款—关系人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (324261557, 663524372, '2328', '長期借款—其他', 'long-term loans payable – other', '长期借款—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (448115003, 602970356, '2331', '長期應付票據', 'long-term notes payable', '长期应付票据', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (446205039, 602970356, '2332', '長期應付帳款', 'long-term accounts pay-able', '长期应付帐款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (634999950, 602970356, '2333', '長期應付租賃負債', 'long-term capital lease liabilities', '长期应付租赁负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (704803584, 602970356, '2337', '長期應付票據及款項—關係人', 'Long-term notes and accounts payable – related parties', '长期应付票据及款项—关系人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (581989752, 602970356, '2338', '其他長期應付款項', 'other long-term payables', '其他长期应付款项', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (324818500, 319948252, '2341', '估計應付土地增值稅', 'estimated accrued land value incremental tax pay-able', '估计应付土地增值税', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (123105059, 489620321, '2351', '應計退休金負債', 'accrued pension liabilities', '应计退休金负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (816932701, 931718543, '2388', '其他長期負債—其他', 'other long-term liabilities – other', '其他长期负债—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (371625981, 301894518, '2811', '遞延收入', 'deferred revenue', '递延收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (446449324, 301894518, '2814', '遞延所得稅負債', 'deferred income tax liabilities', '递延所得税负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (507605492, 301894518, '2818', '其他遞延負債', 'other deferred liabilities', '其他递延负债', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (402582161, 753924220, '2861', '存入保證金', 'guarantee deposit received', '存入保证金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (278544397, 492886608, '2888', '雜項負債—其他', 'miscellaneous liabilities – other', '杂项负债—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (828698884, 354712237, '3111', '普通股股本', 'capital – common stock', '普通股股本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (328325342, 354712237, '3112', '特別股股本', 'capital – preferred stock', '特别股股本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (459479972, 354712237, '3113', '預收股本', 'capital collected in advance', '预收股本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (243470269, 354712237, '3114', '待分配股票股利', 'stock dividends to be distributed', '待分配股票股利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (574499376, 354712237, '3115', '資本', 'capital', '资本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (774555174, 813886254, '3211', '普通股股票溢價', 'paid-in capital in excess of par- common stock', '普通股股票溢价', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (429550621, 813886254, '3212', '特別股股票溢價', 'paid-in capital in excess of par- preferred stock', '特别股股票溢价', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (783013002, 369189273, '3231', '資產重估增值準備', 'capital surplus from assets revaluation', '资产重估增值准备', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (505504878, 708649341, '3241', '處分資產溢價公積', 'capital surplus from gain on disposal of assets', '处分资产溢价公积', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (198451128, 315953593, '3251', '合併公積', 'capital surplus from business combination', '合并公积', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (677269224, 974832633, '3261', '受贈公積', 'donated surplus', '受赠公积', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (740275783, 981029756, '3281', '權益法長期股權投資資本公積', 'additional paid-in capital from investee under equity method', '权益法长期股权投资资本公积', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (153032059, 981029756, '3282', '資本公積—庫藏股票交易', 'additional paid-in capital – treasury stock trans-actions', '资本公积—库藏股票交易', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (898896606, 782463283, '3311', '法定盈餘公積', 'legal reserve', '法定盈余公积', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (847258147, 511595327, '3321', '意外損失準備', 'contingency reserve', '意外损失准备', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (140115980, 511595327, '3322', '改良擴充準備', 'improvement and expansion reserve', '改良扩充准备', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (214588543, 511595327, '3323', '償債準備', 'special reserve for redemption of liabilities', '偿债准备', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (296533405, 511595327, '3328', '其他特別盈餘公積', 'other special reserve', '其他特别盈余公积', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (972322693, 266224620, '3351', '累積盈虧', 'accumulated profit or loss', '累积盈亏', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (782859992, 266224620, '3352', '前期損益調整', 'prior period adjustments', '前期损益调整', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (464874427, 266224620, '3353', '本期損益', 'net income or loss for current period', '本期损益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (136762997, 306542380, '3411', '長期股權投資未實現跌價損失', 'unrealized loss on market value decline of long-term equity investments', '长期股权投资未实现跌价损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (361841681, 385524103, '3421', '累積換算調整數', 'cumulative translation adjustments', '累积换算调整数', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (800323292, 764640716, '3431', '未認列為退休金成本之淨損失', 'net loss not recognized as pension costs', '未认列为退休金成本之净损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (796953172, 277312763, '3511', '庫藏股', 'treasury stock', '库藏股', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (332969156, 172889653, '3611', '少數股權', 'minority interest', '少数股权', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (650902163, 960138746, '4111', '銷貨收入', 'sales revenue', '销货收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (873610886, 960138746, '4112', '分期付款銷貨收入', 'installment sales revenue', '分期付款销货收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (480909546, 989545725, '4171', '銷貨退回', 'sales return', '销货退回', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (501414887, 745165875, '4191', '銷貨折讓', 'sales discounts and allowances', '销货折让', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (861798963, 788006197, '4611', '勞務收入', 'service revenue', '劳务收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (884801039, 636092325, '4711', '業務收入', 'agency revenue', '业务收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (859154718, 560294799, '4888', '其他營業收入—其他', 'other operating revenue – other', '其他营业收入—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (491926593, 868329781, '5111', '銷貨成本', 'cost of goods sold', '销货成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (689575672, 868329781, '5112', '分期付款銷貨成本', 'installment cost of goods sold', '分期付款销货成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (513484217, 715512696, '5121', '進貨', 'purchases', '进货', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (746574640, 715512696, '5122', '進貨費用', 'purchase expenses', '进货费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (804616176, 715512696, '5123', '進貨退出', 'purchase returns', '进货退出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (704293010, 715512696, '5124', '進貨折讓', 'charges on purchased merchandise', '进货折让', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (746290542, 900537319, '5131', '進料', 'material purchased', '进料', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (993482623, 900537319, '5132', '進料費用', 'charges on purchased material', '进料费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (917839380, 900537319, '5133', '進料退出', 'material purchase returns', '进料退出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (685864530, 900537319, '5134', '進料折讓', 'material purchase allowances', '进料折让', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (802855875, 613686812, '5141', '直接人工', 'direct labor', '直接人工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (874928238, 241828224, '5151', '間接人工', 'indirect labor', '间接人工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (571990586, 241828224, '5152', '租金支出', 'rent expense, rent', '租金支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (907852408, 241828224, '5153', '文具用品', 'office supplies (expense)', '文具用品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (487824813, 241828224, '5154', '旅費', 'travelling expense, travel', '旅费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (142992418, 241828224, '5155', '運費', 'shipping expenses, freight', '运费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (438547603, 241828224, '5156', '郵電費', 'postage (expenses)', '邮电费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (338883877, 241828224, '5157', '修繕費', 'repair (s) and maintenance (expense )', '修缮费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (405956607, 241828224, '5158', '包裝費', 'packing expenses', '包装费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (472485669, 181591613, '5161', '水電瓦斯費', 'utilities (expense)', '水电瓦斯费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (205274197, 181591613, '5162', '保險費', 'insurance (expense)', '保险费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (372710710, 181591613, '5163', '加工費', 'manufacturing overhead – outsourced', '加工费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (759488099, 181591613, '5166', '稅捐', 'taxes', '税捐', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (624747656, 181591613, '5168', '折舊', 'depreciation expense', '折旧', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (373245274, 181591613, '5169', '各項耗竭及攤提', 'various amortization', '各项耗竭及摊提', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (857831389, 304113670, '5172', '伙食費', 'meal (expenses)', '伙食费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (224729498, 304113670, '5173', '職工福利', 'employee benefits/welfare', '职工福利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (380369895, 304113670, '5176', '訓練費', 'training (expense)', '训练费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (756274240, 304113670, '5177', '間接材料', 'indirect materials', '间接材料', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (716532124, 302614029, '5188', '其他製造費用', 'other manufacturing expenses', '其他制造费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (152349985, 181853880, '5611', '勞務成本', 'service costs', '劳务成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (757538860, 760077428, '5711', '業務成本', 'agency costs', '业务成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (110601204, 100599165, '5888', '其他營業成本—其他', 'other operating costs – other', '其他营业成本—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (501745153, 212916398, '6151', '薪資支出', 'payroll expense', '薪资支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (484688983, 212916398, '6152', '租金支出', 'rent expense, rent', '租金支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (347797343, 212916398, '6153', '文具用品', 'office supplies (expense)', '文具用品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (184863859, 212916398, '6154', '旅費', 'travelling expense, travel', '旅费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (982899606, 212916398, '6155', '運費', 'shipping expenses, freight', '运费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (548256289, 212916398, '6156', '郵電費', 'postage (expenses)', '邮电费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (201382357, 212916398, '6157', '修繕費', 'repair (s) and maintenance (expense)', '修缮费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (945252074, 212916398, '6159', '廣告費', 'advertisement expense, advertisement', '广告费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (912643138, 193074244, '6161', '水電瓦斯費', 'utilities (expense)', '水电瓦斯费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (482723373, 193074244, '6162', '保險費', 'insurance (expense)', '保险费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (667516040, 193074244, '6164', '交際費', 'entertainment (expense)', '交际费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (696487087, 193074244, '6165', '捐贈', 'donation (expense)', '捐赠', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (252695337, 193074244, '6166', '稅捐', 'taxes', '税捐', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (464334795, 193074244, '6167', '呆帳損失', 'loss on uncollectible accounts', '呆帐损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (205262005, 193074244, '6168', '折舊', 'depreciation expense', '折旧', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (929323612, 193074244, '6169', '各項耗竭及攤提', 'various amortization', '各项耗竭及摊提', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (615973093, 882721016, '6172', '伙食費', 'meal (expenses)', '伙食费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (584771226, 882721016, '6173', '職工福利', 'employee benefits/welfare', '职工福利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (193536017, 882721016, '6175', '佣金支出', 'commission (expense)', '佣金支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (893417802, 882721016, '6176', '訓練費', 'training (expense)', '训练费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (764382524, 514554832, '6188', '其他推銷費用', 'other selling expenses', '其他推销费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (851874623, 241184521, '6251', '薪資支出', 'payroll expense', '薪资支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (176861982, 241184521, '6252', '租金支出', 'rent expense, rent', '租金支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (329717777, 241184521, '6253', '文具用品', 'office supplies', '文具用品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (227243112, 241184521, '6254', '旅費', 'travelling expense, travel', '旅费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (489915115, 241184521, '6255', '運費', 'shipping expenses,freight', '运费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (930339612, 241184521, '6256', '郵電費', 'postage (expenses)', '邮电费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (928410985, 241184521, '6257', '修繕費', 'repair (s) and maintenance (expense)', '修缮费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (128201317, 241184521, '6259', '廣告費', 'advertisement expense, advertisement', '广告费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (570663854, 776997540, '6261', '水電瓦斯費', 'utilities (expense)', '水电瓦斯费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (433448958, 776997540, '6262', '保險費', 'insurance (expense)', '保险费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (681610895, 776997540, '6264', '交際費', 'entertainment (expense)', '交际费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (521769517, 776997540, '6265', '捐贈', 'donation (expense)', '捐赠', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (796674668, 776997540, '6266', '稅捐', 'taxes', '税捐', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (829731934, 776997540, '6267', '呆帳損失', 'loss on uncollectible accounts', '呆帐损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (619404096, 776997540, '6268', '折舊', 'depreciation expense', '折旧', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (201420585, 776997540, '6269', '各項耗竭及攤提', 'various amortization', '各项耗竭及摊提', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (761920757, 324522418, '6271', '外銷損失', 'loss on export sales', '外销损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (666597144, 324522418, '6272', '伙食費', 'meal (expenses)', '伙食费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (893939737, 324522418, '6273', '職工福利', 'employee benefits/welfare', '职工福利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (695670103, 324522418, '6274', '研究發展費用', 'research and development expense', '研究发展费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (617144018, 324522418, '6275', '佣金支出', 'commission (expense)', '佣金支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (356589445, 324522418, '6276', '訓練費', 'training (expense)', '训练费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (469570957, 324522418, '6278', '勞務費', 'professional service fees', '劳务费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (877041170, 543298708, '6288', '其他管理及總務費用', 'other general and administrative expenses', '其他管理及总务费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (285629796, 751717808, '6351', '薪資支出', 'payroll expense', '薪资支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (255109839, 751717808, '6352', '租金支出', 'rent expense, rent', '租金支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (293609536, 751717808, '6353', '文具用品', 'office supplies', '文具用品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (870547203, 751717808, '6354', '旅費', 'travelling expense, travel', '旅费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (885107086, 751717808, '6355', '運費', 'shipping expenses, freight', '运费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (987987224, 751717808, '6356', '郵電費', 'postage (expenses)', '邮电费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (438300022, 751717808, '6357', '修繕費', 'repair (s) and maintenance (expense)', '修缮费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (926725156, 509842953, '6361', '水電瓦斯費', 'utilities (expense)', '水电瓦斯费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (371394354, 509842953, '6362', '保險費', 'insurance (expense)', '保险费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (690276284, 509842953, '6364', '交際費', 'entertainment (expense)', '交际费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (991739983, 509842953, '6366', '稅捐', 'taxes', '税捐', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (871746448, 509842953, '6368', '折舊', 'depreciation expense', '折旧', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (895377402, 509842953, '6369', '各項耗竭及攤提', 'various amortization', '各项耗竭及摊提', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (691533190, 334520736, '6372', '伙食費', 'meal (expenses)', '伙食费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (425563486, 334520736, '6373', '職工福利', 'employee benefits/welfare', '职工福利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (730229601, 334520736, '6376', '訓練費', 'training (expense)', '训练费', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (755843878, 334520736, '6378', '其他研究發展費用', 'other research and development expenses', '其他研究发展费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (935512761, 748583072, '7111', '利息收入', 'interest revenue/income', '利息收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (117472286, 807935097, '7121', '權益法認列之投資收益', 'investment income recognized under equity method', '权益法认列之投资收益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (740643479, 807935097, '7122', '股利收入', 'dividends income', '股利收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (893347443, 807935097, '7123', '短期投資市價回升利益', 'gain on market price recovery of short-term investment', '短期投资市价回升利益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (788210158, 256128674, '7131', '兌換利益', 'foreign exchange gain', '兑换利益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (164663168, 902036208, '7141', '處分投資收益', 'gain on disposal of investments', '处分投资收益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (318252073, 206038830, '7151', '處分資產溢價收入', 'gain on disposal of assets', '处分资产溢价收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (444183965, 699454747, '7481', '捐贈收入', 'donation income', '捐赠收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (428472055, 699454747, '7482', '租金收入', 'rent revenue/income', '租金收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (592692377, 699454747, '7483', '佣金收入', 'commission revenue/income', '佣金收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (525102294, 699454747, '7484', '出售下腳及廢料收入', 'revenue from sale of scraps', '出售下脚及废料收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (806095768, 699454747, '7485', '存貨盤盈', 'gain on physical inventory', '存货盘盈', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (742624311, 699454747, '7486', '存貨跌價回升利益', 'gain from price recovery of inventory', '存货跌价回升利益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (666483691, 699454747, '7487', '壞帳轉回利益', 'gain on reversal of bad debts', '坏帐转回利益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (753349254, 699454747, '7488', '其他營業外收入—其他', 'other non-operating revenue– other items', '其他营业外收入—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (438653661, 988959446, '7511', '利息費用', 'interest expense', '利息费用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (647865532, 548598499, '7521', '權益法認列之投資損失', 'investment loss recog- nized under equity method', '权益法认列之投资损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (514482416, 548598499, '7523', '短期投資未實現跌價損失', 'unrealized loss on reduction of short-term investments to market', '短期投资未实现跌价损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (929065316, 947980201, '7531', '兌換損失', 'foreign exchange loss', '兑换损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (869388482, 286649244, '7541', '處分投資損失', 'loss on disposal of investments', '处分投资损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (139281291, 537384847, '7551', '處分資產損失', 'loss on disposal of assets', '处分资产损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (222152959, 928820789, '7881', '停工損失', 'loss on work stoppages', '停工损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (674468763, 928820789, '7882', '災害損失', 'casualty loss', '灾害损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (922455040, 928820789, '7885', '存貨盤損', 'loss on physical inventory', '存货盘损', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (309527256, 928820789, '7886', '存貨跌價及呆滯損失', 'loss for market price decline and obsolete and slow-moving inventories', '存货跌价及呆滞损失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (571194746, 928820789, '7888', '其他營業外費用—其他', 'other non-operating expenses– other', '其他营业外费用—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (792176665, 687819205, '8111', '所得稅費用(或利益)', 'income tax expense ( or benefit)', '所得税费用(或利益)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (958524871, 392121771, '9111', '停業部門損益—停業前營業損益', 'income (loss) from operations of discontinued segment', '停业部门损益—停业前营业损益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (997358780, 816367329, '9121', '停業部門損益—處分損益', 'gain (loss) from disposal of discontinued segment', '停业部门损益—处分损益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (250404501, 749878410, '9211', '非常損益', 'extraordinary gain or loss', '非常损益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (334638274, 575458948, '9311', '會計原則變動累積影響數', 'cumulative effect of changes in accounting principles', '会计原则变动累积影响数', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title_zhtw, title_en, title_zhcn, created, createdby, updated, updatedby) VALUES (474145902, 867926470, '9411', '少數股權淨利', 'minority interest income', '少数股权净利', now(), 923153018, now(), 923153018); +COMMIT; diff --git a/htdocs/imacat/magicat/lib/imacat-selima.sql b/htdocs/imacat/magicat/lib/imacat-selima.sql new file mode 100644 index 0000000..83e4a76 --- /dev/null +++ b/htdocs/imacat/magicat/lib/imacat-selima.sql @@ -0,0 +1,3786 @@ +-- 檔案名稱: imacat.sql +-- 程式說明: 旅舍依瑪資料庫定義檔 +-- 程式作者: 依瑪貓 imacat +-- 初稿日期: 2004-09-10 +-- 版權字樣: 版權所有 (c) 2004-2014 依瑪貓 +-- Set PGCLIENTENCODING=utf8 before restoring it + +SET NAMES 'utf8'; + +START TRANSACTION; + + +-- +-- Table structure for table "mtime" +-- + +CREATE TABLE mtime ( + tabname varchar(16) NOT NULL PRIMARY KEY, + mtime timestamp NOT NULL DEFAULT now() +); +GRANT SELECT, INSERT, UPDATE, DELETE ON mtime TO nobody; +GRANT SELECT, INSERT, UPDATE, DELETE ON mtime TO robot; + + +-- +-- Function definition for function "eschtml" +-- +-- integer eschtml(source text) +CREATE FUNCTION eschtml(source text) RETURNS text AS ' + DECLARE + result text; + BEGIN + result := source; + result := replace(result, ''&'', ''&''); + result := replace(result, ''<'', ''<''); + result := replace(result, ''>'', ''>''); + result := replace(result, ''"'', ''"''); + return result; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION eschtml(source text) TO nobody; + + +-- +-- Table structure for table "country" +-- + +CREATE TABLE country ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id char(2) NOT NULL UNIQUE CHECK (position(' ' in id) = 0), + name_en varchar(64) NOT NULL CHECK (name_en != ''), + name_zhtw varchar(32) CHECK (name_zhtw IS NULL OR name_zhtw != ''), + name_zhcn varchar(32) CHECK (name_zhcn IS NULL OR name_zhcn != ''), + special boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL +); +GRANT SELECT, INSERT, UPDATE, DELETE ON country TO nobody; + + +-- +-- Table structure for table "users" +-- + +CREATE TABLE users ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(32) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + passwd char(32) NOT NULL, + name varchar(32) NOT NULL CHECK (name != ''), + disabled boolean NOT NULL DEFAULT FALSE, + deleted boolean NOT NULL DEFAULT FALSE, + lang varchar(5) CHECK (lang IS NULL OR lang != ''), + visits smallint NOT NULL DEFAULT 0 CHECK (visits >= 0), + visited timestamp, + ip inet, + host varchar(128), + ct char(2) REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON users TO nobody; +GRANT SELECT ON users TO robot; + +CREATE VIEW users_list_zhtw AS + SELECT + users.sn AS sn, + users.id AS id, + users.name AS name, + CASE WHEN users.disabled THEN '停用' + ELSE '' + END AS disabled, + CASE WHEN users.deleted THEN '已刪' + ELSE '' + END AS deleted, + CASE WHEN users.lang IS NULL THEN '(無)' + ELSE CASE users.lang + WHEN 'en' THEN '英文' + WHEN 'zh-tw' THEN '繁體中文' + WHEN 'zh-cn' THEN '簡體中文' + WHEN 'ja' THEN '日文' + WHEN 'de' THEN '德文' + WHEN 'es' THEN '西班牙文' + ELSE users.lang + END + END AS lang, + users.visits AS visits, + CASE WHEN users.visited IS NULL THEN '(無)' + ELSE to_char(users.visited, 'YYYY-MM-DD HH:MI:SS') + END AS visited, + CASE WHEN users.ip IS NULL THEN '(無)' + ELSE host(users.ip) + END AS ip, + CASE WHEN users.host IS NULL THEN '(無)' + ELSE users.host + END AS host, + CASE WHEN users.ct IS NULL THEN '(無)' + ELSE ct.name_zhtw + END AS ct, + to_char(users.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(users.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM users + LEFT JOIN country AS ct ON users.ct = ct.id + LEFT JOIN users AS createdby ON users.createdby = createdby.sn + LEFT JOIN users AS updatedby ON users.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON users_list_zhtw TO nobody; +CREATE VIEW users_list_en AS + SELECT + users.sn AS sn, + users.id AS id, + users.name AS name, + CASE WHEN users.disabled THEN 'Disabled' + ELSE '' + END AS disabled, + CASE WHEN users.deleted THEN 'Deleted' + ELSE '' + END AS deleted, + CASE WHEN users.lang IS NULL THEN '(none)' + ELSE CASE users.lang + WHEN 'en' THEN 'English' + WHEN 'zh-tw' THEN 'Traditional Chinese' + WHEN 'zh-cn' THEN 'Simplified Chinese' + WHEN 'ja' THEN 'Japanese' + WHEN 'de' THEN 'German' + WHEN 'es' THEN 'Spanish' + ELSE users.lang + END + END AS lang, + users.visits AS visits, + CASE WHEN users.visited IS NULL THEN '(none)' + ELSE to_char(users.visited, 'YYYY-MM-DD HH:MI:SS') + END AS visited, + CASE WHEN users.ip IS NULL THEN '(none)' + ELSE host(users.ip) + END AS ip, + CASE WHEN users.host IS NULL THEN '(none)' + ELSE users.host + END AS host, + CASE WHEN users.ct IS NULL THEN '(none)' + ELSE ct.name_en + END AS ct, + to_char(users.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(users.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM users + LEFT JOIN country AS ct ON users.ct = ct.id + LEFT JOIN users AS createdby ON users.createdby = createdby.sn + LEFT JOIN users AS updatedby ON users.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON users_list_en TO nobody; +CREATE VIEW users_list_zhcn AS + SELECT + users.sn AS sn, + users.id AS id, + users.name AS name, + CASE WHEN users.disabled THEN '停用' + ELSE '' + END AS disabled, + CASE WHEN users.deleted THEN '已删' + ELSE '' + END AS deleted, + CASE WHEN users.lang IS NULL THEN '(无)' + ELSE CASE users.lang + WHEN 'en' THEN '英文' + WHEN 'zh-tw' THEN '繁体中文' + WHEN 'zh-cn' THEN '简体中文' + WHEN 'ja' THEN '日文' + WHEN 'de' THEN '德文' + WHEN 'es' THEN '西班牙文' + ELSE users.lang + END + END AS lang, + users.visits AS visits, + CASE WHEN users.visited IS NULL THEN '(无)' + ELSE to_char(users.visited, 'YYYY-MM-DD HH:MI:SS') + END AS visited, + CASE WHEN users.ip IS NULL THEN '(无)' + ELSE host(users.ip) + END AS ip, + CASE WHEN users.host IS NULL THEN '(无)' + ELSE users.host + END AS host, + CASE WHEN users.ct IS NULL THEN '(无)' + ELSE ct.name_en + END AS ct, + to_char(users.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(users.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM users + LEFT JOIN country AS ct ON users.ct = ct.id + LEFT JOIN users AS createdby ON users.createdby = createdby.sn + LEFT JOIN users AS updatedby ON users.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON users_list_zhcn TO nobody; + +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (923153018, 'imacat', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '依瑪貓', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (460376330, 'mandy', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '小招', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (723676436, 'guestbook', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '留言本', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); + +-- +-- Fixing the country table +-- + +ALTER TABLE country ADD FOREIGN KEY (createdby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +ALTER TABLE country ADD FOREIGN KEY (updatedby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +CREATE VIEW country_list_en AS + SELECT + country.sn AS sn, + country.id AS id, + country.name_en AS title, + CASE WHEN country.special THEN 'Special' + ELSE '' + END AS special, + to_char(country.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(country.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM country + LEFT JOIN users AS createdby ON country.createdby = createdby.sn + LEFT JOIN users AS updatedby ON country.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON country_list_en TO nobody; +CREATE VIEW country_list_zhtw AS + SELECT + country.sn AS sn, + country.id AS id, + COALESCE(country.name_zhtw, country.name_en) AS title, + CASE WHEN country.special THEN '特殊' + ELSE '' + END AS special, + to_char(country.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(country.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM country + LEFT JOIN users AS createdby ON country.createdby = createdby.sn + LEFT JOIN users AS updatedby ON country.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON country_list_zhtw TO nobody; +CREATE VIEW country_list_zhcn AS + SELECT + country.sn AS sn, + country.id AS id, + COALESCE(country.name_zhcn, country.name_en) AS title, + CASE WHEN country.special THEN '特殊' + ELSE '' + END AS special, + to_char(country.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(country.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM country + LEFT JOIN users AS createdby ON country.createdby = createdby.sn + LEFT JOIN users AS updatedby ON country.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON country_list_zhcn TO nobody; + + +-- +-- Table structure for table "groups" +-- + +CREATE TABLE groups ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(16) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + dsc_zhtw varchar(64) NOT NULL CHECK (dsc_zhtw != ''), + dsc_en varchar(64) CHECK (dsc_en IS NULL OR dsc_en != ''), + dsc_zhcn varchar(64) CHECK (dsc_zhcn IS NULL OR dsc_zhcn != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groups TO nobody; + +CREATE VIEW groups_list_zhtw AS + SELECT + groups.sn AS sn, + groups.id AS id, + groups.dsc_zhtw AS dsc, + to_char(groups.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groups.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groups + LEFT JOIN users AS createdby ON groups.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groups.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON groups_list_zhtw TO nobody; +CREATE VIEW groups_list_en AS + SELECT + groups.sn AS sn, + groups.id AS id, + COALESCE(groups.dsc_en, groups.dsc_zhtw) AS dsc, + to_char(groups.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groups.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groups + LEFT JOIN users AS createdby ON groups.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groups.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON groups_list_en TO nobody; +CREATE VIEW groups_list_zhcn AS + SELECT + groups.sn AS sn, + groups.id AS id, + COALESCE(groups.dsc_zhcn, groups.dsc_zhtw) AS dsc, + to_char(groups.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groups.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groups + LEFT JOIN users AS createdby ON groups.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groups.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON groups_list_zhcn TO nobody; + +-- INSERT INTO groups (sn, id, dsc_en, dsc_zhtw, created, createdby, updated, updatedby) VALUES (553229108, 'root', 'Super Users', '總管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc_en, dsc_zhtw, created, createdby, updated, updatedby) VALUES (802339805, 'guests', 'Anonymous Guests', '暱名訪客', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc_en, dsc_zhtw, created, createdby, updated, updatedby) VALUES (958210993, 'users', 'All Logged-in Users', '已登入使用者', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc_en, dsc_zhtw, created, createdby, updated, updatedby) VALUES (329685674, 'admin', 'All Administrators', '所有網站管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc_en, dsc_zhtw, created, createdby, updated, updatedby) VALUES (157696540, 'acctman', 'Account Manager', '帳號管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc_en, dsc_zhtw, created, createdby, updated, updatedby) VALUES (390105230, 'editor', 'Website Editors', '網站編輯', now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "usermem" +-- + +CREATE TABLE usermem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON usermem TO nobody; + +CREATE VIEW usermem_list_zhtw AS + SELECT + usermem.sn AS sn, + groups.id || ' (' || groups.dsc_zhtw || ')' AS grp, + members.id || ' (' || members.name || ')' AS member, + to_char(usermem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(usermem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM usermem + LEFT JOIN groups ON usermem.grp = groups.sn + LEFT JOIN users AS members ON usermem.member = members.sn + LEFT JOIN users AS createdby ON usermem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON usermem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON usermem_list_zhtw TO nobody; +CREATE VIEW usermem_list_en AS + SELECT + usermem.sn AS sn, + groups.id || ' (' || COALESCE(groups.dsc_en, groups.dsc_zhtw) || ')' AS grp, + members.id || ' (' || members.name || ')' AS member, + to_char(usermem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(usermem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM usermem + LEFT JOIN groups ON usermem.grp = groups.sn + LEFT JOIN users AS members ON usermem.member = members.sn + LEFT JOIN users AS createdby ON usermem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON usermem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON usermem_list_en TO nobody; +CREATE VIEW usermem_list_zhcn AS + SELECT + usermem.sn AS sn, + groups.id || ' (' || COALESCE(groups.dsc_zhcn, groups.dsc_zhtw) || ')' AS grp, + members.id || ' (' || members.name || ')' AS member, + to_char(usermem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(usermem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM usermem + LEFT JOIN groups ON usermem.grp = groups.sn + LEFT JOIN users AS members ON usermem.member = members.sn + LEFT JOIN users AS createdby ON usermem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON usermem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON usermem_list_zhcn TO nobody; + +-- INSERT INTO usermem (sn, grp, member, created, createdby, updated, updatedby) VALUES (593684712, 553229108, 923153018, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "groupmem" +-- + +CREATE TABLE groupmem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE CHECK (member != grp), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groupmem TO nobody; + +CREATE VIEW groupmem_list_zhtw AS + SELECT + groupmem.sn AS sn, + groups.id || ' (' || groups.dsc_zhtw || ')' AS grp, + members.id || ' (' || members.dsc_zhtw || ')' AS member, + to_char(groupmem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groupmem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groupmem + LEFT JOIN groups ON groupmem.grp = groups.sn + LEFT JOIN groups AS members ON groupmem.member = members.sn + LEFT JOIN users AS createdby ON groupmem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groupmem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON groupmem_list_zhtw TO nobody; +CREATE VIEW groupmem_list_en AS + SELECT + groupmem.sn AS sn, + groups.id || ' (' || COALESCE(groups.dsc_en, groups.dsc_zhtw) || ')' AS grp, + members.id || ' (' || COALESCE(members.dsc_en, members.dsc_zhtw) || ')' AS member, + to_char(groupmem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groupmem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groupmem + LEFT JOIN groups ON groupmem.grp = groups.sn + LEFT JOIN groups AS members ON groupmem.member = members.sn + LEFT JOIN users AS createdby ON groupmem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groupmem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON groupmem_list_en TO nobody; +CREATE VIEW groupmem_list_zhcn AS + SELECT + groupmem.sn AS sn, + groups.id || ' (' || COALESCE(groups.dsc_zhcn, groups.dsc_zhtw) || ')' AS grp, + members.id || ' (' || COALESCE(members.dsc_zhcn, members.dsc_zhtw) || ')' AS member, + to_char(groupmem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groupmem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groupmem + LEFT JOIN groups ON groupmem.grp = groups.sn + LEFT JOIN groups AS members ON groupmem.member = members.sn + LEFT JOIN users AS createdby ON groupmem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groupmem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON groupmem_list_zhcn TO nobody; + +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (569742102, 329685674, 157696540, now(), 923153018, now(), 923153018); +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (859385977, 329685674, 390105230, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "scptpriv" +-- + +CREATE TABLE scptpriv ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + script varchar(64) NOT NULL CHECK (script != ''), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (script, grp) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON scptpriv TO nobody; + +CREATE VIEW scptpriv_list_zhtw AS + SELECT + scptpriv.sn AS sn, + scptpriv.script AS script, + groups.dsc_zhtw AS grp, + to_char(scptpriv.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(scptpriv.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM scptpriv + LEFT JOIN groups ON scptpriv.grp = groups.sn + LEFT JOIN users AS createdby ON scptpriv.createdby = createdby.sn + LEFT JOIN users AS updatedby ON scptpriv.updatedby = updatedby.sn + ORDER BY script, grp; +GRANT SELECT ON scptpriv_list_zhtw TO nobody; +CREATE VIEW scptpriv_list_en AS + SELECT + scptpriv.sn AS sn, + scptpriv.script AS script, + COALESCE(groups.dsc_en, groups.dsc_zhtw) AS grp, + to_char(scptpriv.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(scptpriv.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM scptpriv + LEFT JOIN groups ON scptpriv.grp = groups.sn + LEFT JOIN users AS createdby ON scptpriv.createdby = createdby.sn + LEFT JOIN users AS updatedby ON scptpriv.updatedby = updatedby.sn + ORDER BY script, grp; +GRANT SELECT ON scptpriv_list_en TO nobody; +CREATE VIEW scptpriv_list_zhcn AS + SELECT + scptpriv.sn AS sn, + scptpriv.script AS script, + COALESCE(groups.dsc_zhcn, groups.dsc_zhtw) AS grp, + to_char(scptpriv.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(scptpriv.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM scptpriv + LEFT JOIN groups ON scptpriv.grp = groups.sn + LEFT JOIN users AS createdby ON scptpriv.createdby = createdby.sn + LEFT JOIN users AS updatedby ON scptpriv.updatedby = updatedby.sn + ORDER BY script, grp; +GRANT SELECT ON scptpriv_list_zhcn TO nobody; + + +-- +-- Table structure for table "userpref" +-- + +CREATE TABLE userpref ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + usr int REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + domain varchar(64) CHECK (domain IS NULL OR domain != ''), + name varchar(16) NOT NULL CHECK (name != ''), + value varchar(255) NOT NULL, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (usr, domain, name) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON userpref TO nobody; + +CREATE VIEW userpref_list_zhtw AS + SELECT + userpref.sn AS sn, + CASE WHEN userpref.usr IS NOT NULL THEN users.name + ELSE '所有人' + END AS usr, + CASE WHEN userpref.domain IS NOT NULL THEN userpref.domain + ELSE '所有地方' + END AS domain, + userpref.name AS name, + userpref.value AS value, + to_char(userpref.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(userpref.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM userpref LEFT JOIN users ON userpref.usr = users.sn + LEFT JOIN users AS createdby ON userpref.createdby = createdby.sn + LEFT JOIN users AS updatedby ON userpref.updatedby = updatedby.sn + ORDER BY domain, usr, name; +GRANT SELECT ON userpref_list_zhtw TO nobody; +CREATE VIEW userpref_list_en AS + SELECT + userpref.sn AS sn, + CASE WHEN userpref.usr IS NOT NULL THEN users.name + ELSE 'Everyone' + END AS usr, + CASE WHEN userpref.domain IS NOT NULL THEN userpref.domain + ELSE 'Everywhere' + END AS domain, + userpref.name AS name, + userpref.value AS value, + to_char(userpref.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(userpref.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM userpref + LEFT JOIN users ON userpref.usr = users.sn + LEFT JOIN users AS createdby ON userpref.createdby = createdby.sn + LEFT JOIN users AS updatedby ON userpref.updatedby = updatedby.sn + ORDER BY domain, usr, name; +GRANT SELECT ON userpref_list_en TO nobody; +CREATE VIEW userpref_list_zhcn AS + SELECT + userpref.sn AS sn, + CASE WHEN userpref.usr IS NOT NULL THEN users.name + ELSE '所有人' + END AS usr, + CASE WHEN userpref.domain IS NOT NULL THEN userpref.domain + ELSE '所有地方' + END AS domain, + userpref.name AS name, + userpref.value AS value, + to_char(userpref.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(userpref.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM userpref + LEFT JOIN users ON userpref.usr = users.sn + LEFT JOIN users AS createdby ON userpref.createdby = createdby.sn + LEFT JOIN users AS updatedby ON userpref.updatedby = updatedby.sn + ORDER BY domain, usr, name; +GRANT SELECT ON userpref_list_zhcn TO nobody; + + +-- +-- Function definitions for table "guestbook" +-- + +-- integer guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) +CREATE FUNCTION guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) RETURNS integer AS ' + DECLARE + row record; + len integer; + BEGIN + -- : 19, sn: 30 + 1, date: 54 + 1 + len := 105; + len := len + octet_length(host(ip)) + 22; + IF hostname IS NOT NULL THEN + len := len + octet_length(hostname) + 24; + END IF; + IF name IS NOT NULL THEN + len := len + octet_length(eschtml(name)) + 24; + END IF; + IF identity IS NOT NULL THEN + len := len + octet_length(eschtml(identity)) + 28; + END IF; + IF location IS NOT NULL THEN + len := len + octet_length(eschtml(location)) + 28; + END IF; + IF email IS NOT NULL THEN + len := len + octet_length(eschtml(email)) + 25; + END IF; + IF url IS NOT NULL THEN + len := len + octet_length(eschtml(url)) + 23; + END IF; + IF message IS NOT NULL THEN + len := len + octet_length(eschtml(message)) + 27; + END IF; + IF updated != date THEN + len := len + 58; + IF updatedby_arg = 923153018 THEN + len := len + 35; + ELSIF updatedby_arg = 460376330 THEN + len := len + 34; + ELSE + SELECT INTO row name FROM users WHERE sn=updatedby_arg; + len := len + octet_length(row.name) + 29; + END IF; + END IF; + RETURN len; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) TO nobody; +-- integer guestbook_oldlen(sn_arg integer) +CREATE FUNCTION guestbook_oldlen(sn_arg integer) RETURNS integer AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM guestbook WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN guestbook_oldlen(row.created, row.ip, row.host, row.name, row.identity, row.location, row.email, row.url, row.message, row.updated, row.updatedby); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(sn_arg integer) TO nobody; + + +-- +-- Table structure for table "guestbook" +-- + +CREATE TABLE guestbook ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + name varchar(32) CHECK (name IS NULL OR name != ''), + identity varchar(64) CHECK (identity IS NULL OR identity != ''), + location varchar(64) CHECK (location IS NULL OR location != ''), + email varchar(64) CHECK (email IS NULL OR email != ''), + url varchar(128) CHECK (url IS NULL OR (url != '' AND url != 'http://')), + message text NOT NULL CHECK (message != ''), + hid boolean NOT NULL DEFAULT FALSE, + lang varchar(5) CHECK (lang IS NULL OR lang = 'zh-tw' OR lang='zh-cn'), + ip inet NOT NULL, + host varchar(255) CHECK (host IS NULL OR host != ''), + ct char(2) NOT NULL REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + pageno int NOT NULL, + oldpageno int, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON guestbook TO nobody; + +CREATE VIEW guestbook_list_zhtw AS + SELECT + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS _viewurl, + guestbook.sn AS sn, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + COALESCE(guestbook.name, '(未設定)') AS name, + COALESCE(guestbook.identity, '(未設定)') AS identity, + COALESCE(guestbook.location, '(未設定)') AS location, + COALESCE(guestbook.email, '(未設定)') AS email, + COALESCE(guestbook.url, '(未設定)') AS url, + guestbook.message AS message, + CASE WHEN guestbook.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + CASE WHEN guestbook.lang IS NULL THEN NULL + ELSE CASE guestbook.lang + WHEN 'zh-tw' THEN '繁體中文' + WHEN 'zh-cn' THEN '簡體中文' + ELSE guestbook.lang + END + END AS lang, + host(guestbook.ip) AS ip, + COALESCE(guestbook.host, '(不可考)') AS host, + COALESCE(country.name_zhtw, country.name_en) AS ct, + guestbook.pageno AS pageno, + guestbook.oldpageno AS oldpageno, + to_char(guestbook.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(guestbook.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM guestbook + LEFT JOIN country ON guestbook.ct = country.id + LEFT JOIN users AS createdby ON guestbook.createdby = createdby.sn + LEFT JOIN users AS updatedby ON guestbook.updatedby = updatedby.sn + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_list_zhtw TO nobody; +CREATE VIEW guestbook_list_en AS + SELECT + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS _viewurl, + guestbook.sn AS sn, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + COALESCE(guestbook.name, '(not set)') AS name, + COALESCE(guestbook.identity, '(not set)') AS identity, + COALESCE(guestbook.location, '(not set)') AS location, + COALESCE(guestbook.email, '(not set)') AS email, + COALESCE(guestbook.url, '(not set)') AS url, + guestbook.message AS message, + CASE WHEN guestbook.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + CASE WHEN guestbook.lang IS NULL THEN NULL + ELSE CASE guestbook.lang + WHEN 'zh-tw' THEN 'Traditional Chinese' + WHEN 'zh-cn' THEN 'Simplified Chinese' + ELSE guestbook.lang + END + END AS lang, + host(guestbook.ip) AS ip, + COALESCE(guestbook.host, '(N/A)') AS host, + country.name_en AS ct, + guestbook.pageno AS pageno, + guestbook.oldpageno AS oldpageno, + to_char(guestbook.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(guestbook.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM guestbook + LEFT JOIN country ON guestbook.ct = country.id + LEFT JOIN users AS createdby ON guestbook.createdby = createdby.sn + LEFT JOIN users AS updatedby ON guestbook.updatedby = updatedby.sn + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_list_en TO nobody; +CREATE VIEW guestbook_list_zhcn AS + SELECT + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS _viewurl, + guestbook.sn AS sn, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + COALESCE(guestbook.name, '(未设定)') AS name, + COALESCE(guestbook.identity, '(未设定)') AS identity, + COALESCE(guestbook.location, '(未设定)') AS location, + COALESCE(guestbook.email, '(未设定)') AS email, + COALESCE(guestbook.url, '(未设定)') AS url, + guestbook.message AS message, + CASE WHEN guestbook.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + CASE WHEN guestbook.lang IS NULL THEN NULL + ELSE CASE guestbook.lang + WHEN 'zh-tw' THEN '繁体中文' + WHEN 'zh-cn' THEN '简体中文' + ELSE guestbook.lang + END + END AS lang, + host(guestbook.ip) AS ip, + COALESCE(guestbook.host, '(不可考)') AS host, + COALESCE(country.name_zhcn, country.name_en) AS ct, + guestbook.pageno AS pageno, + guestbook.oldpageno AS oldpageno, + to_char(guestbook.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(guestbook.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM guestbook + LEFT JOIN country ON guestbook.ct = country.id + LEFT JOIN users AS createdby ON guestbook.createdby = createdby.sn + LEFT JOIN users AS updatedby ON guestbook.updatedby = updatedby.sn + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_list_zhcn TO nobody; + +CREATE VIEW guestbook_public AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + name AS name, + identity AS identity, + location AS location, + email AS email, + url AS url, + message AS message, + lang AS lang, + pageno AS pageno, + oldpageno AS oldpageno + FROM guestbook + WHERE NOT hid + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_public TO nobody; + + +-- +-- Function definitions for table "garbage" +-- + +-- integer garbage_oldlen(date timestamp, ip inet, hostname text, message text, updated timestamp, updatedby_arg integer) +CREATE FUNCTION garbage_oldlen(date timestamp, ip inet, hostname text, message text, updated timestamp, updatedby_arg integer) RETURNS integer AS ' + DECLARE + row record; + len integer; + BEGIN + -- : 19, sn: 30 + 1, date: 54 + 1 + len := 105; + len := len + octet_length(host(ip)) + 22; + IF hostname IS NOT NULL THEN + len := len + octet_length(hostname) + 24; + END IF; + IF message IS NOT NULL THEN + len := len + octet_length(eschtml(message)) + 27; + END IF; + IF updated != date THEN + len := len + 58; + IF updatedby_arg = 923153018 THEN + len := len + 35; + ELSIF updatedby_arg = 460376330 THEN + len := len + 34; + ELSE + SELECT INTO row name FROM users WHERE sn=updatedby_arg; + len := len + octet_length(row.name) + 29; + END IF; + END IF; + RETURN len; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION garbage_oldlen(date timestamp, ip inet, hostname text, message text, updated timestamp, updatedby_arg integer) TO nobody; +-- integer garbage_oldlen(sn_arg integer) +CREATE FUNCTION garbage_oldlen(sn_arg integer) RETURNS integer AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM garbage WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN garbage_oldlen(row.created, row.ip, row.host, row.message, row.updated, row.updatedby); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION garbage_oldlen(sn_arg integer) TO nobody; + + +-- +-- Table structure for table "garbage" +-- + +CREATE TABLE garbage ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + message text NOT NULL CHECK (message != ''), + hid boolean NOT NULL DEFAULT FALSE, + ip inet NOT NULL, + host varchar(255) CHECK (host IS NULL OR host != ''), + ct char(2) NOT NULL REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + pageno int NOT NULL, + oldpageno int, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON garbage TO nobody; + +CREATE VIEW garbage_list_zhtw AS + SELECT + '/cgi-bin/garbage.cgi?pageno=' || garbage.pageno + || '#msg' || garbage.sn + AS _viewurl, + garbage.sn AS sn, + to_char(garbage.created, 'YYYY-MM-DD') AS date, + garbage.message AS message, + CASE WHEN garbage.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + host(garbage.ip) AS ip, + COALESCE(garbage.host, '(不可考)') AS host, + COALESCE(country.name_zhtw, country.name_en) AS ct, + garbage.pageno AS pageno, + garbage.oldpageno AS oldpageno, + to_char(garbage.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(garbage.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM garbage + LEFT JOIN country ON garbage.ct = country.id + LEFT JOIN users AS createdby ON garbage.createdby = createdby.sn + LEFT JOIN users AS updatedby ON garbage.updatedby = updatedby.sn + ORDER BY garbage.created DESC; +GRANT SELECT ON garbage_list_zhtw TO nobody; +CREATE VIEW garbage_list_en AS + SELECT + '/cgi-bin/garbage.cgi?pageno=' || garbage.pageno + || '#msg' || garbage.sn + AS _viewurl, + garbage.sn AS sn, + to_char(garbage.created, 'YYYY-MM-DD') AS date, + garbage.message AS message, + CASE WHEN garbage.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + host(garbage.ip) AS ip, + COALESCE(garbage.host, '(N/A)') AS host, + country.name_en AS ct, + garbage.pageno AS pageno, + garbage.oldpageno AS oldpageno, + to_char(garbage.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(garbage.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM garbage + LEFT JOIN country ON garbage.ct = country.id + LEFT JOIN users AS createdby ON garbage.createdby = createdby.sn + LEFT JOIN users AS updatedby ON garbage.updatedby = updatedby.sn + ORDER BY garbage.created DESC; +GRANT SELECT ON garbage_list_en TO nobody; +CREATE VIEW garbage_list_zhcn AS + SELECT + '/cgi-bin/garbage.cgi?pageno=' || garbage.pageno + || '#msg' || garbage.sn + AS _viewurl, + garbage.sn AS sn, + to_char(garbage.created, 'YYYY-MM-DD') AS date, + garbage.message AS message, + CASE WHEN garbage.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + host(garbage.ip) AS ip, + COALESCE(garbage.host, '(不可考)') AS host, + COALESCE(country.name_zhcn, country.name_en) AS ct, + garbage.pageno AS pageno, + garbage.oldpageno AS oldpageno, + to_char(garbage.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(garbage.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM garbage + LEFT JOIN country ON garbage.ct = country.id + LEFT JOIN users AS createdby ON garbage.createdby = createdby.sn + LEFT JOIN users AS updatedby ON garbage.updatedby = updatedby.sn + ORDER BY garbage.created DESC; +GRANT SELECT ON garbage_list_zhcn TO nobody; + +CREATE VIEW garbage_public AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + message AS message, + pageno AS pageno, + oldpageno AS oldpageno + FROM garbage + WHERE NOT hid + ORDER BY garbage.created DESC; +GRANT SELECT ON garbage_public TO nobody; + + +-- +-- Table structure for table "pages" +-- + +CREATE TABLE pages ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + path varchar(64) NOT NULL UNIQUE CHECK (path != ''), + ord smallint NOT NULL DEFAULT 5000 CHECK (ord >= 0 AND ord < 10000), + title_zhtw varchar(128) NOT NULL CHECK (title_zhtw != ''), + body_zhtw text NOT NULL CHECK (body_zhtw != ''), + kw_zhtw varchar(128) NOT NULL CHECK (kw_zhtw != ''), + title_en varchar(128) CHECK (title_en IS NULL OR title_en != ''), + body_en text CHECK ((title_en IS NULL AND body_en IS NULL) OR (title_en IS NOT NULL AND body_en IS NOT NULL AND body_en != '')), + kw_en varchar(128) CHECK ((title_en IS NULL AND kw_en IS NULL) OR (title_en IS NOT NULL AND kw_en IS NOT NULL AND kw_en != '')), + title_zhcn varchar(128) CHECK (title_zhcn IS NULL OR title_zhcn != ''), + body_zhcn text CHECK ((title_zhcn IS NULL AND body_zhcn IS NULL) OR (title_zhcn IS NOT NULL AND body_zhcn IS NOT NULL AND body_zhcn != '')), + kw_zhcn varchar(128) CHECK ((title_zhcn IS NULL AND kw_zhcn IS NULL) OR (title_zhcn IS NOT NULL AND kw_zhcn IS NOT NULL AND kw_zhcn != '')), + class varchar(8) CHECK (class IS NULL OR class != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pages TO nobody; + +CREATE VIEW pages_list_zhtw AS + SELECT + pages.path AS _viewurl, + pages.sn AS sn, + pages.path AS path, + pages.ord AS ord, + pages.title_zhtw AS title, + pages.body_zhtw AS body, + pages.kw_zhtw AS kw, + pages.class AS class, + CASE WHEN pages.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN pages.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(pages.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pages.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pages + LEFT JOIN users AS createdby ON pages.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pages.updatedby = updatedby.sn + ORDER BY path; +GRANT SELECT ON pages_list_zhtw TO nobody; +CREATE VIEW pages_list_en AS + SELECT + pages.path AS _viewurl, + pages.sn AS sn, + pages.path AS path, + pages.ord AS ord, + COALESCE(pages.title_en, pages.title_zhtw) AS title, + COALESCE(pages.body_en, pages.body_zhtw) AS body, + COALESCE(pages.kw_en, pages.kw_zhtw) AS kw, + pages.class AS class, + CASE WHEN pages.html THEN 'HTML' + ELSE 'Plain text' + END AS html, + CASE WHEN pages.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + to_char(pages.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pages.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pages + LEFT JOIN users AS createdby ON pages.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pages.updatedby = updatedby.sn + ORDER BY path; +GRANT SELECT ON pages_list_en TO nobody; +CREATE VIEW pages_list_zhcn AS + SELECT + pages.path AS _viewurl, + pages.sn AS sn, + pages.path AS path, + pages.ord AS ord, + COALESCE(pages.title_zhcn, pages.title_zhtw) AS title, + COALESCE(pages.body_zhcn, pages.body_zhtw) AS body, + COALESCE(pages.kw_zhcn, pages.kw_zhtw) AS kw, + pages.class AS class, + CASE WHEN pages.html THEN 'HTML' + ELSE '纯文字' + END AS html, + CASE WHEN pages.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + to_char(pages.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pages.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pages + LEFT JOIN users AS createdby ON pages.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pages.updatedby = updatedby.sn + ORDER BY path; +GRANT SELECT ON pages_list_zhcn TO nobody; + + +-- +-- Function definitions for table "links" +-- + +-- boolean linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer); +CREATE FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) RETURNS boolean AS ' + BEGIN + IF parent_arg IS NULL THEN + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent IS NULL; + RETURN NOT FOUND; + ELSE + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent=parent_arg; + RETURN NOT FOUND; + END IF; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) TO nobody; + +-- numeric linkcat_fullord(parent_arg integer, ord_arg integer); +CREATE FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) RETURNS numeric AS ' + DECLARE + row record; + sn_loop integer; + ord_loop numeric; + BEGIN + sn_loop := parent_arg; + ord_loop := ord_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, ord FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN NULL; + END IF; + sn_loop := row.parent; + ord_loop := row.ord + ord_loop / 100; + END LOOP; + RETURN ord_loop; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) TO nobody; +-- numeric linkcat_fullord(sn_arg integer); +CREATE FUNCTION linkcat_fullord(sn_arg integer) RETURNS numeric AS ' + BEGIN + RETURN linkcat_fullord(sn_arg, 0); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(sn_arg integer) TO nobody; + +-- boolean linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + -- Check if we have childs + PERFORM links.sn FROM links + INNER JOIN linkcatz ON linkcatz.link=links.sn + WHERE NOT links.hid AND linkcatz.cat=sn_arg; + IF FOUND THEN + RETURN TRUE; + END IF; + -- Check if we have shown child categories + PERFORM sn FROM linkcat WHERE parent=sn_arg AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + RETURN TRUE; + END IF; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; +-- boolean linkcat_isshown(sn_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer) RETURNS boolean AS ' + DECLARE + row record; + BEGIN + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_isshown(sn_arg, row.hid, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer) TO nobody; +-- boolean linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + RETURN TRUE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; + +-- text linkcat_path(sn_arg integer, id_arg text, parent_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + path text; + BEGIN + PERFORM sn FROM linkcat + WHERE parent=sn_arg + AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + path := ''/'' || id_arg || ''/''; + ELSE + path := ''/'' || id_arg || ''.html''; + END IF; + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_loop; + path := ''/'' || row.id || path; + sn_loop := row.parent; + END LOOP; + RETURN path; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) TO nobody; +-- text linkcat_path(sn_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_path(sn_arg, row.id, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer) TO nobody; + +-- boolean linkcat_ischild(parent_arg integer, child_arg integer); +CREATE FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + sn_loop := child_arg; + WHILE sn_loop IS NOT NULL LOOP + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + SELECT INTO row parent FROM public.linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN FALSE; + END IF; + IF row.parent = parent_arg THEN + RETURN TRUE; + END IF; + sn_loop := row.parent; + END LOOP; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) TO nobody; + +-- text linkcat_fulltitle(lang_arg text, sn_arg integer); +CREATE FUNCTION linkcat_fulltitle(lang_arg text, sn_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + title_full text; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + title_full := CASE lang_arg + WHEN ''en'' THEN COALESCE(row.title_en, row.title_zhtw) + ELSE row.title_zhtw + END; + WHILE row.parent IS NOT NULL LOOP + sn_loop := row.parent; + SELECT INTO row * FROM linkcat WHERE sn=sn_loop; + title_full := CASE lang_arg + WHEN ''en'' THEN COALESCE(row.title_en, row.title_zhtw) + ELSE row.title_zhtw + END || '' / '' || title_full; + END LOOP; + RETURN title_full; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(lang_arg text, sn_arg integer) TO nobody; +-- text linkcat_fulltitle(lang_arg text, parent_arg integer, title_arg text); +CREATE FUNCTION linkcat_fulltitle(lang_arg text, parent_arg integer, title_arg text) RETURNS text AS ' + BEGIN + IF parent_arg IS NULL THEN + RETURN title_arg; + END IF; + RETURN linkcat_fulltitle(lang_arg, parent_arg) || '' / '' || title_arg; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(lang_arg text, parent_arg integer, title_arg text) TO nobody; + + +-- +-- Table structure for table "linkcat" +-- + +CREATE TABLE linkcat ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + parent int REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE CHECK (parent IS NULL OR (parent != sn AND NOT linkcat_ischild(sn, parent))), + id varchar(8) NOT NULL CHECK (char_length(id) >= 2 AND linkcat_id_unique(id, sn, parent)), + ord smallint NOT NULL DEFAULT 50 CHECK (ord >= 0 AND ord < 100), + title_zhtw varchar(128) NOT NULL CHECK (title_zhtw != ''), + kw_zhtw varchar(128) NOT NULL CHECK (kw_zhtw != ''), + title_en varchar(128) CHECK (title_en IS NULL OR title_en != ''), + kw_en varchar(128) CHECK ((title_en IS NULL AND kw_en IS NULL) OR (title_en IS NOT NULL AND kw_en IS NOT NULL AND kw_en != '')), + title_zhcn varchar(128) CHECK (title_zhcn IS NULL OR title_zhcn != ''), + kw_zhcn varchar(128) CHECK ((title_zhcn IS NULL AND kw_zhcn IS NULL) OR (title_zhcn IS NOT NULL AND kw_zhcn IS NOT NULL AND kw_zhcn != '')), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcat TO nobody; + +CREATE VIEW linkcat_list_zhtw AS + SELECT + '/links' || linkcat_path(linkcat.sn, linkcat.id, linkcat.parent) || '.zh-tw' AS _viewurl, + linkcat.sn AS sn, + linkcat.id AS id, + linkcat.ord AS ord, + linkcat_fulltitle('zh-tw', linkcat.parent, linkcat.title_zhtw) AS title, + linkcat.kw_zhtw AS kw, + CASE WHEN linkcat.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(linkcat.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcat.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcat + LEFT JOIN users AS createdby ON linkcat.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcat.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), id; +GRANT SELECT ON linkcat_list_zhtw TO nobody; +CREATE VIEW linkcat_list_en AS + SELECT + '/links' || linkcat_path(linkcat.sn, linkcat.id, linkcat.parent) || '.en' AS _viewurl, + linkcat.sn AS sn, + linkcat.id AS id, + linkcat.ord AS ord, + linkcat_fulltitle('en', linkcat.parent, COALESCE(linkcat.title_en, linkcat.title_zhtw)) AS title, + COALESCE(linkcat.kw_en, linkcat.kw_zhtw) AS kw, + CASE WHEN linkcat.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + to_char(linkcat.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcat.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcat + LEFT JOIN users AS createdby ON linkcat.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcat.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), id; +GRANT SELECT ON linkcat_list_en TO nobody; +CREATE VIEW linkcat_list_zhcn AS + SELECT + '/links' || linkcat_path(linkcat.sn, linkcat.id, linkcat.parent) || '.zh-cn' AS _viewurl, + linkcat.sn AS sn, + linkcat.id AS id, + linkcat.ord AS ord, + linkcat_fulltitle('zh-cn', linkcat.parent, COALESCE(linkcat.title_zhcn, linkcat.title_zhtw)) AS title, + COALESCE(linkcat.kw_zhcn, linkcat.kw_zhtw) AS kw, + CASE WHEN linkcat.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + to_char(linkcat.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcat.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcat + LEFT JOIN users AS createdby ON linkcat.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcat.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), id; +GRANT SELECT ON linkcat_list_zhcn TO nobody; + + +-- +-- Table structure for table "links" +-- + +CREATE TABLE links ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + title varchar(96) NOT NULL CHECK (title != ''), + title_2ln varchar(96) CHECK (title_2ln IS NULL OR title_2ln != ''), + url varchar(128) NOT NULL UNIQUE CHECK (url != '' AND url != 'http://'), + email varchar(64) CHECK (email IS NULL OR email != ''), + icon varchar(128) CHECK (icon IS NULL OR (icon != '' AND icon != 'http://')), + addr varchar(128) CHECK (addr IS NULL OR addr != ''), + tel varchar(48) CHECK (tel IS NULL OR tel != ''), + fax varchar(32) CHECK (fax IS NULL OR fax != ''), + dsc_zhtw varchar(256) NOT NULL CHECK (dsc_zhtw != ''), + dsc_en varchar(256) CHECK (dsc_en IS NULL OR dsc_en != ''), + dsc_zhcn varchar(256) CHECK (dsc_zhcn IS NULL OR dsc_zhcn != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON links TO nobody; + +CREATE VIEW links_list_zhtw AS + SELECT + links.url AS _viewurl, + links.sn AS sn, + links.title AS title, + links.title_2ln AS title_2ln, + links.url AS url, + links.url AS _urlcheck, + links.icon AS _imgsrc, + links.email AS email, + links.addr AS addr, + links.tel AS tel, + links.fax AS fax, + links.dsc_zhtw AS dsc, + CASE WHEN links.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(links.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(links.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM links + LEFT JOIN users AS createdby ON links.createdby = createdby.sn + LEFT JOIN users AS updatedby ON links.updatedby = updatedby.sn + ORDER BY links.title; +GRANT SELECT ON links_list_zhtw TO nobody; +CREATE VIEW links_list_en AS + SELECT + links.url AS _viewurl, + links.sn AS sn, + links.title AS title, + links.title_2ln AS title_2ln, + links.url AS url, + links.url AS _urlcheck, + links.icon AS _imgsrc, + links.email AS email, + links.addr AS addr, + links.tel AS tel, + links.fax AS fax, + COALESCE(links.dsc_en, links.dsc_zhtw) AS dsc, + CASE WHEN links.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + to_char(links.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(links.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM links + LEFT JOIN users AS createdby ON links.createdby = createdby.sn + LEFT JOIN users AS updatedby ON links.updatedby = updatedby.sn + ORDER BY links.title; +GRANT SELECT ON links_list_en TO nobody; +CREATE VIEW links_list_zhcn AS + SELECT + links.url AS _viewurl, + links.sn AS sn, + links.title AS title, + links.title_2ln AS title_2ln, + links.url AS url, + links.url AS _urlcheck, + links.icon AS _imgsrc, + links.email AS email, + links.addr AS addr, + links.tel AS tel, + links.fax AS fax, + COALESCE(links.dsc_zhcn, links.dsc_zhtw) AS dsc, + CASE WHEN links.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + to_char(links.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(links.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM links + LEFT JOIN users AS createdby ON links.createdby = createdby.sn + LEFT JOIN users AS updatedby ON links.updatedby = updatedby.sn + ORDER BY links.title; +GRANT SELECT ON links_list_zhcn TO nobody; + + +-- +-- Table structure for table "linkcatz" +-- + +CREATE TABLE linkcatz ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + cat int NOT NULL REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE, + link int NOT NULL REFERENCES links ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (cat, link) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcatz TO nobody; + +CREATE VIEW linkcatz_list_zhtw AS + SELECT + linkcatz.sn AS sn, + linkcat_fulltitle('zh-tw', linkcat.parent, linkcat.title_zhtw) AS cat, + links.title AS link, + to_char(linkcatz.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcatz.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcatz + LEFT JOIN linkcat ON linkcatz.cat = linkcat.sn + LEFT JOIN links ON linkcatz.link = links.sn + LEFT JOIN users AS createdby ON linkcatz.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcatz.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), linkcat.id, link; +GRANT SELECT ON linkcatz_list_zhtw TO nobody; +CREATE VIEW linkcatz_list_en AS + SELECT + linkcatz.sn AS sn, + linkcat_fulltitle('en', linkcat.parent, COALESCE(linkcat.title_en, linkcat.title_zhtw)) AS cat, + links.title AS link, + to_char(linkcatz.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcatz.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcatz + LEFT JOIN linkcat ON linkcatz.cat = linkcat.sn + LEFT JOIN links ON linkcatz.link = links.sn + LEFT JOIN users AS createdby ON linkcatz.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcatz.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), linkcat.id, link; +GRANT SELECT ON linkcatz_list_en TO nobody; +CREATE VIEW linkcatz_list_zhcn AS + SELECT + linkcatz.sn AS sn, + linkcat_fulltitle('zh-cn', linkcat.parent, COALESCE(linkcat.title_zhcn, linkcat.title_zhtw)) AS cat, + links.title AS link, + to_char(linkcatz.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcatz.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcatz + LEFT JOIN linkcat ON linkcatz.cat = linkcat.sn + LEFT JOIN links ON linkcatz.link = links.sn + LEFT JOIN users AS createdby ON linkcatz.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcatz.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), linkcat.id, link; +GRANT SELECT ON linkcatz_list_zhcn TO nobody; + + +-- +-- Function definitions for table "diary" +-- + +-- timestamp diary_page_start(pageno_arg integer) +CREATE FUNCTION diary_page_start(pageno_arg integer) RETURNS timestamp AS ' + DECLARE + row record; + BEGIN + SELECT INTO row created FROM diary + WHERE NOT hid AND pageno=pageno_arg + ORDER BY created LIMIT 1; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.created; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION diary_page_start(pageno_arg integer) TO nobody; +-- timestamp diary_page_end(pageno_arg integer) +CREATE FUNCTION diary_page_end(pageno_arg integer) RETURNS timestamp AS ' + DECLARE + row record; + BEGIN + SELECT INTO row created FROM diary + WHERE NOT hid AND pageno=pageno_arg + ORDER BY created DESC LIMIT 1; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.created; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION diary_page_end(pageno_arg integer) TO nobody; + + +-- +-- Table structure for table "diary" +-- + +CREATE TABLE diary ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + body_zhtw text NOT NULL CHECK (body_zhtw != ''), + body_en text CHECK (body_en IS NULL OR body_en != ''), + body_zhcn text CHECK (body_zhcn IS NULL OR body_zhcn != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + pageno int NOT NULL, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON diary TO nobody; + +CREATE VIEW diary_list_zhtw AS + SELECT + '/me/diary/' || lpad(cast(diary.pageno AS text), 4, '0') || '.html' + || '#ent' || diary.sn + AS _viewurl, + diary.sn AS sn, + to_char(diary.created, 'YYYY-MM-DD') AS date, + diary.body_zhtw AS body, + CASE WHEN diary.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN diary.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + diary.pageno AS pageno, + to_char(diary.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(diary.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM diary + LEFT JOIN users AS createdby ON diary.createdby = createdby.sn + LEFT JOIN users AS updatedby ON diary.updatedby = updatedby.sn + ORDER BY diary.created DESC; +GRANT SELECT ON diary_list_zhtw TO nobody; +CREATE VIEW diary_list_en AS + SELECT + '/me/diary/' || lpad(cast(diary.pageno AS text), 4, '0') || '.html' + || '#ent' || diary.sn + AS _viewurl, + diary.sn AS sn, + to_char(diary.created, 'YYYY-MM-DD') AS date, + COALESCE(diary.body_en, diary.body_zhtw) AS body, + CASE WHEN diary.html THEN 'HTML' + ELSE 'Plain text' + END AS html, + CASE WHEN diary.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + diary.pageno AS pageno, + to_char(diary.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(diary.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM diary + LEFT JOIN users AS createdby ON diary.createdby = createdby.sn + LEFT JOIN users AS updatedby ON diary.updatedby = updatedby.sn + ORDER BY diary.created DESC; +GRANT SELECT ON diary_list_en TO nobody; +CREATE VIEW diary_list_zhcn AS + SELECT + '/me/diary/' || lpad(cast(diary.pageno AS text), 4, '0') || '.html' + || '#ent' || diary.sn + AS _viewurl, + diary.sn AS sn, + to_char(diary.created, 'YYYY-MM-DD') AS date, + COALESCE(diary.body_zhcn, diary.body_zhtw) AS body, + CASE WHEN diary.html THEN 'HTML' + ELSE '纯文字' + END AS html, + CASE WHEN diary.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + diary.pageno AS pageno, + to_char(diary.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(diary.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM diary + LEFT JOIN users AS createdby ON diary.createdby = createdby.sn + LEFT JOIN users AS updatedby ON diary.updatedby = updatedby.sn + ORDER BY diary.created DESC; +GRANT SELECT ON diary_list_zhcn TO nobody; + +CREATE VIEW diary_public_zhtw AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + body_zhtw AS body, + html AS html, + pageno AS pageno + FROM diary + WHERE NOT hid + ORDER BY created DESC; +GRANT SELECT ON diary_public_zhtw TO nobody; +CREATE VIEW diary_public_en AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + COALESCE(body_en, body_zhtw) AS body, + html AS html, + pageno AS pageno + FROM diary + WHERE NOT hid + ORDER BY created DESC; +GRANT SELECT ON diary_public_en TO nobody; +CREATE VIEW diary_public_zhcn AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + COALESCE(body_zhcn, body_zhtw) AS body, + html AS html, + pageno AS pageno + FROM diary + WHERE NOT hid + ORDER BY created DESC; +GRANT SELECT ON diary_public_zhcn TO nobody; + + +-- +-- Function definitions for table "changelog" +-- + +-- timestamp changelog_page_start(pageno_arg integer) +CREATE FUNCTION changelog_page_start(pageno_arg integer) RETURNS timestamp AS ' + DECLARE + row record; + BEGIN + SELECT INTO row created FROM changelog + WHERE NOT hid AND pageno=pageno_arg + ORDER BY created LIMIT 1; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.created; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION changelog_page_start(pageno_arg integer) TO nobody; +-- timestamp changelog_page_end(pageno_arg integer) +CREATE FUNCTION changelog_page_end(pageno_arg integer) RETURNS timestamp AS ' + DECLARE + row record; + BEGIN + SELECT INTO row created FROM changelog + WHERE NOT hid AND pageno=pageno_arg + ORDER BY created DESC LIMIT 1; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.created; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION changelog_page_end(pageno_arg integer) TO nobody; + + +-- +-- Table structure for table "changelog" +-- + +CREATE TABLE changelog ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + body_zhtw text NOT NULL CHECK (body_zhtw != ''), + body_en text CHECK (body_en IS NULL OR body_en != ''), + body_zhcn text CHECK (body_zhcn IS NULL OR body_zhcn != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + pageno int NOT NULL, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON changelog TO nobody; + +CREATE VIEW changelog_list_zhtw AS + SELECT + '/me/changelog/' || lpad(cast(changelog.pageno AS text), 4, '0') || '.html' + || '#ent' || changelog.sn + AS _viewurl, + changelog.sn AS sn, + to_char(changelog.created, 'YYYY-MM-DD') AS date, + changelog.body_zhtw AS body, + CASE WHEN changelog.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN changelog.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + changelog.pageno AS pageno, + to_char(changelog.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(changelog.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM changelog + LEFT JOIN users AS createdby ON changelog.createdby = createdby.sn + LEFT JOIN users AS updatedby ON changelog.updatedby = updatedby.sn + ORDER BY changelog.created DESC; +GRANT SELECT ON changelog_list_zhtw TO nobody; +CREATE VIEW changelog_list_en AS + SELECT + '/me/changelog/' || lpad(cast(changelog.pageno AS text), 4, '0') || '.html' + || '#ent' || changelog.sn + AS _viewurl, + changelog.sn AS sn, + to_char(changelog.created, 'YYYY-MM-DD') AS date, + COALESCE(changelog.body_en, changelog.body_zhtw) AS body, + CASE WHEN changelog.html THEN 'HTML' + ELSE 'Plain text' + END AS html, + CASE WHEN changelog.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + changelog.pageno AS pageno, + to_char(changelog.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(changelog.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM changelog + LEFT JOIN users AS createdby ON changelog.createdby = createdby.sn + LEFT JOIN users AS updatedby ON changelog.updatedby = updatedby.sn + ORDER BY changelog.created DESC; +GRANT SELECT ON changelog_list_en TO nobody; +CREATE VIEW changelog_list_zhcn AS + SELECT + '/me/changelog/' || lpad(cast(changelog.pageno AS text), 4, '0') || '.html' + || '#ent' || changelog.sn + AS _viewurl, + changelog.sn AS sn, + to_char(changelog.created, 'YYYY-MM-DD') AS date, + COALESCE(changelog.body_zhcn, changelog.body_zhtw) AS body, + CASE WHEN changelog.html THEN 'HTML' + ELSE '纯文字' + END AS html, + CASE WHEN changelog.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + changelog.pageno AS pageno, + to_char(changelog.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(changelog.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM changelog + LEFT JOIN users AS createdby ON changelog.createdby = createdby.sn + LEFT JOIN users AS updatedby ON changelog.updatedby = updatedby.sn + ORDER BY changelog.created DESC; +GRANT SELECT ON changelog_list_zhcn TO nobody; + +CREATE VIEW changelog_public_zhtw AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + body_zhtw AS body, + html AS html, + pageno AS pageno + FROM changelog + WHERE NOT hid + ORDER BY created DESC; +GRANT SELECT ON changelog_public_zhtw TO nobody; +CREATE VIEW changelog_public_en AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + COALESCE(body_en, body_zhtw) AS body, + html AS html, + pageno AS pageno + FROM changelog + WHERE NOT hid + ORDER BY created DESC; +GRANT SELECT ON changelog_public_en TO nobody; +CREATE VIEW changelog_public_zhcn AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + COALESCE(body_zhcn, body_zhtw) AS body, + html AS html, + pageno AS pageno + FROM changelog + WHERE NOT hid + ORDER BY created DESC; +GRANT SELECT ON changelog_public_zhcn TO nobody; + + +-- +-- Table structure for table "literalzh" +-- + +CREATE TABLE literalzh ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + date date NOT NULL UNIQUE DEFAULT CURRENT_DATE, + title varchar(16) CHECK (title IS NULL OR title != ''), + dsc varchar(256) NOT NULL CHECK (dsc != ''), + kw varchar(32) NOT NULL CHECK (kw != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON literalzh TO nobody; + +CREATE VIEW literalzh_list_zhtw AS + SELECT + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + AS _viewurl, + literalzh.sn AS sn, + to_char(literalzh.date, 'YYYY-MM-DD') AS date, + literalzh.title AS title, + literalzh.dsc AS dsc, + literalzh.kw AS kw, + CASE WHEN literalzh.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(literalzh.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(literalzh.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM literalzh + LEFT JOIN users AS createdby ON literalzh.createdby = createdby.sn + LEFT JOIN users AS updatedby ON literalzh.updatedby = updatedby.sn + ORDER BY literalzh.date DESC; +GRANT SELECT ON literalzh_list_zhtw TO nobody; +CREATE VIEW literalzh_list_en AS + SELECT + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + AS _viewurl, + literalzh.sn AS sn, + to_char(literalzh.date, 'YYYY-MM-DD') AS date, + literalzh.title AS title, + literalzh.dsc AS dsc, + literalzh.kw AS kw, + CASE WHEN literalzh.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + to_char(literalzh.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(literalzh.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM literalzh + LEFT JOIN users AS createdby ON literalzh.createdby = createdby.sn + LEFT JOIN users AS updatedby ON literalzh.updatedby = updatedby.sn + ORDER BY literalzh.date DESC; +GRANT SELECT ON literalzh_list_en TO nobody; +CREATE VIEW literalzh_list_zhcn AS + SELECT + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + AS _viewurl, + literalzh.sn AS sn, + to_char(literalzh.date, 'YYYY-MM-DD') AS date, + literalzh.title AS title, + literalzh.dsc AS dsc, + literalzh.kw AS kw, + CASE WHEN literalzh.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + to_char(literalzh.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(literalzh.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM literalzh + LEFT JOIN users AS createdby ON literalzh.createdby = createdby.sn + LEFT JOIN users AS updatedby ON literalzh.updatedby = updatedby.sn + ORDER BY literalzh.date DESC; +GRANT SELECT ON literalzh_list_zhcn TO nobody; + + +-- +-- Table structure for table "ltzhpoem" +-- + +CREATE TABLE ltzhpoem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + set int NOT NULL REFERENCES literalzh ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + title varchar(16) NOT NULL CHECK (title != ''), + body text NOT NULL CHECK (body != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON ltzhpoem TO nobody; + +CREATE VIEW ltzhpoem_list_zhtw AS + SELECT + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + || '#poem' || ltzhpoem.sn + AS _viewurl, + ltzhpoem.sn AS sn, + to_char(literalzh.date, 'YYYY-MM-DD') + || CASE WHEN literalzh.title IS NULL THEN '' ELSE ' ' || literalzh.title END + AS set, + ltzhpoem.ord AS ord, + ltzhpoem.title AS title, + ltzhpoem.body AS body, + CASE WHEN ltzhpoem.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(ltzhpoem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(ltzhpoem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM ltzhpoem + LEFT JOIN literalzh ON ltzhpoem.set=literalzh.sn + LEFT JOIN users AS createdby ON ltzhpoem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON ltzhpoem.updatedby = updatedby.sn + ORDER BY literalzh.date DESC, ltzhpoem.ord; +GRANT SELECT ON ltzhpoem_list_zhtw TO nobody; +CREATE VIEW ltzhpoem_list_en AS + SELECT + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + || '#poem' || ltzhpoem.sn + AS _viewurl, + ltzhpoem.sn AS sn, + to_char(literalzh.date, 'YYYY-MM-DD') + || CASE WHEN literalzh.title IS NULL THEN '' ELSE ' ' || literalzh.title END + AS set, + ltzhpoem.ord AS ord, + ltzhpoem.title AS title, + ltzhpoem.body AS body, + CASE WHEN ltzhpoem.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + to_char(ltzhpoem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(ltzhpoem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM ltzhpoem + LEFT JOIN literalzh ON ltzhpoem.set=literalzh.sn + LEFT JOIN users AS createdby ON ltzhpoem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON ltzhpoem.updatedby = updatedby.sn + ORDER BY literalzh.date DESC, ltzhpoem.ord; +GRANT SELECT ON ltzhpoem_list_en TO nobody; +CREATE VIEW ltzhpoem_list_zhcn AS + SELECT + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + || '#poem' || ltzhpoem.sn + AS _viewurl, + ltzhpoem.sn AS sn, + to_char(literalzh.date, 'YYYY-MM-DD') + || CASE WHEN literalzh.title IS NULL THEN '' ELSE ' ' || literalzh.title END + AS set, + ltzhpoem.ord AS ord, + ltzhpoem.title AS title, + ltzhpoem.body AS body, + CASE WHEN ltzhpoem.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + to_char(ltzhpoem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(ltzhpoem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM ltzhpoem + LEFT JOIN literalzh ON ltzhpoem.set=literalzh.sn + LEFT JOIN users AS createdby ON ltzhpoem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON ltzhpoem.updatedby = updatedby.sn + ORDER BY literalzh.date DESC, ltzhpoem.ord; +GRANT SELECT ON ltzhpoem_list_zhcn TO nobody; + + +-- +-- Table structure for table "literalen" +-- + +CREATE TABLE literalen ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + date date NOT NULL UNIQUE DEFAULT CURRENT_DATE, + title varchar(16) CHECK (title IS NULL OR title != ''), + dsc text NOT NULL CHECK (dsc != ''), + body text NOT NULL CHECK (body != ''), + kw varchar(32) NOT NULL CHECK (kw != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON literalen TO nobody; + +CREATE VIEW literalen_list_zhtw AS + SELECT + '/writings-en/' || to_char(literalen.date, 'YYYYMMDD') || '.html' + AS _viewurl, + literalen.sn AS sn, + to_char(literalen.date, 'YYYY-MM-DD') AS date, + literalen.title AS title, + literalen.dsc AS dsc, + literalen.body AS body, + literalen.kw AS kw, + CASE WHEN literalen.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN literalen.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(literalen.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(literalen.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM literalen + LEFT JOIN users AS createdby ON literalen.createdby = createdby.sn + LEFT JOIN users AS updatedby ON literalen.updatedby = updatedby.sn + ORDER BY literalen.date DESC; +GRANT SELECT ON literalen_list_zhtw TO nobody; +CREATE VIEW literalen_list_en AS + SELECT + '/writings-en/' || to_char(literalen.date, 'YYYYMMDD') || '.html' + AS _viewurl, + literalen.sn AS sn, + to_char(literalen.date, 'YYYY-MM-DD') AS date, + literalen.title AS title, + literalen.dsc AS dsc, + literalen.body AS body, + literalen.kw AS kw, + CASE WHEN literalen.html THEN 'HTML' + ELSE 'Plain text' + END AS html, + CASE WHEN literalen.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + to_char(literalen.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(literalen.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM literalen + LEFT JOIN users AS createdby ON literalen.createdby = createdby.sn + LEFT JOIN users AS updatedby ON literalen.updatedby = updatedby.sn + ORDER BY literalen.date DESC; +GRANT SELECT ON literalen_list_en TO nobody; +CREATE VIEW literalen_list_zhcn AS + SELECT + '/writings-en/' || to_char(literalen.date, 'YYYYMMDD') || '.html' + AS _viewurl, + literalen.sn AS sn, + to_char(literalen.date, 'YYYY-MM-DD') AS date, + literalen.title AS title, + literalen.dsc AS dsc, + literalen.body AS body, + literalen.kw AS kw, + CASE WHEN literalen.html THEN 'HTML' + ELSE '纯文字' + END AS html, + CASE WHEN literalen.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + to_char(literalen.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(literalen.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM literalen + LEFT JOIN users AS createdby ON literalen.createdby = createdby.sn + LEFT JOIN users AS updatedby ON literalen.updatedby = updatedby.sn + ORDER BY literalen.date DESC; +GRANT SELECT ON literalen_list_zhcn TO nobody; + + +-- +-- VIEW: Search +-- +CREATE VIEW search_list AS + (SELECT + 'pages' AS section, + pages.path AS path, + pages.title_zhtw AS title, + null AS author, + to_char(pages.updated, 'YYYY-MM-DD') AS date, + pages.body_zhtw AS body, + pages.kw_zhtw AS kw, + pages.html AS html + FROM pages + WHERE NOT pages.hid + AND pages.path NOT LIKE '/errors/%') + UNION + (SELECT + 'pages' AS section, + pages.path AS path, + pages.title_en AS title, + null AS author, + to_char(pages.updated, 'YYYY-MM-DD') AS date, + pages.body_en AS body, + pages.kw_en AS kw, + pages.html AS html + FROM pages + WHERE NOT pages.hid + AND pages.path NOT LIKE '/errors/%' + AND pages.title_en IS NOT NULL) + UNION + (SELECT + 'diary' AS section, + '/me/diary/' || lpad(cast(diary.pageno AS text), 4, '0') || '.html' + || '#ent' || diary.sn + AS path, + null AS title, + null AS author, + to_char(diary.updated, 'YYYY-MM-DD') AS date, + diary.body_zhtw AS body, + null AS kw, + diary.html AS html + FROM diary + WHERE NOT diary.hid) + UNION + (SELECT + 'diary' AS section, + '/me/diary/' || lpad(cast(diary.pageno AS text), 4, '0') || '.html' + || '#ent' || diary.sn + AS path, + null AS title, + null AS author, + to_char(diary.updated, 'YYYY-MM-DD') AS date, + diary.body_en AS body, + null AS kw, + diary.html AS html + FROM diary + WHERE NOT diary.hid + AND diary.body_en IS NOT NULL) + UNION + (SELECT + 'changelog' AS section, + '/me/changelog/' || lpad(cast(changelog.pageno AS text), 4, '0') || '.html' + || '#ent' || changelog.sn + AS path, + null AS title, + null AS author, + to_char(changelog.updated, 'YYYY-MM-DD') AS date, + changelog.body_zhtw AS body, + null AS kw, + changelog.html AS html + FROM changelog + WHERE NOT changelog.hid) + UNION + (SELECT + 'changelog' AS section, + '/me/changelog/' || lpad(cast(changelog.pageno AS text), 4, '0') || '.html' + || '#ent' || changelog.sn + AS path, + null AS title, + null AS author, + to_char(changelog.updated, 'YYYY-MM-DD') AS date, + changelog.body_en AS body, + null AS kw, + changelog.html AS html + FROM changelog + WHERE NOT changelog.hid + AND changelog.body_en IS NOT NULL) + UNION + (SELECT + 'literalzh' AS section, + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + AS path, + literalzh.title AS title, + null AS author, + to_char(literalzh.date, 'YYYY-MM-DD') AS date, + literalzh.dsc AS body, + literalzh.kw AS kw, + FALSE AS html + FROM literalzh + WHERE NOT literalzh.hid) + UNION + (SELECT + 'ltzhpoem' AS section, + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + || '#poem' || ltzhpoem.sn + AS path, + ltzhpoem.title AS title, + null AS author, + to_char(literalzh.date, 'YYYY-MM-DD') AS date, + ltzhpoem.body AS body, + null AS kw, + FALSE AS html + FROM ltzhpoem + LEFT JOIN literalzh ON ltzhpoem.set=literalzh.sn + WHERE NOT ltzhpoem.hid + AND NOT literalzh.hid) + UNION + (SELECT + 'literalen' AS section, + '/writings-en/' || to_char(literalen.date, 'YYYYMMDD') || '.html' + AS path, + literalen.title AS title, + null AS author, + to_char(literalen.date, 'YYYY-MM-DD') AS date, + literalen.body AS body, + literalen.kw || ' +' || literalen.dsc AS kw, + literalen.html AS html + FROM literalen + WHERE NOT literalen.hid) + UNION + (SELECT + 'links' AS section, + links.url AS path, + links.title AS title, + null AS author, + to_char(links.updated, 'YYYY-MM-DD') AS date, + links.dsc_zhtw AS body, + CASE WHEN links.title_2ln IS NULL THEN '' ELSE links.title_2ln END + || ' +' || CASE WHEN links.url IS NULL THEN '' ELSE links.url END + || ' +' || CASE WHEN links.email IS NULL THEN '' ELSE links.email END + || ' +' || CASE WHEN links.addr IS NULL THEN '' ELSE links.addr END + || ' +' || CASE WHEN links.tel IS NULL THEN '' ELSE links.tel END + || ' +' || CASE WHEN links.fax IS NULL THEN '' ELSE links.fax END + AS kw, + FALSE AS html + FROM links + WHERE NOT links.hid) + UNION + (SELECT + 'links' AS section, + links.url AS path, + links.title AS title, + null AS author, + to_char(links.updated, 'YYYY-MM-DD') AS date, + links.dsc_en AS body, + CASE WHEN links.title_2ln IS NULL THEN '' ELSE links.title_2ln END + || ' +' || CASE WHEN links.url IS NULL THEN '' ELSE links.url END + || ' +' || CASE WHEN links.email IS NULL THEN '' ELSE links.email END + || ' +' || CASE WHEN links.addr IS NULL THEN '' ELSE links.addr END + || ' +' || CASE WHEN links.tel IS NULL THEN '' ELSE links.tel END + || ' +' || CASE WHEN links.fax IS NULL THEN '' ELSE links.fax END + AS kw, + FALSE AS html + FROM links + WHERE NOT links.hid + AND links.dsc_en IS NOT NULL) + UNION + (SELECT + 'guestbook' AS section, + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS path, + null AS title, + guestbook.name AS author, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + guestbook.message AS body, + CASE WHEN guestbook.identity IS NULL THEN '' ELSE guestbook.identity END + || ' +' || CASE WHEN guestbook.location IS NULL THEN '' ELSE guestbook.location END + || ' +' || CASE WHEN guestbook.email IS NULL THEN '' ELSE guestbook.email END + || ' +' || CASE WHEN guestbook.url IS NULL THEN '' ELSE guestbook.url END + AS kw, + FALSE AS html + FROM guestbook + WHERE NOT guestbook.hid) + UNION + (SELECT + 'garbage' AS section, + '/cgi-bin/garbage.cgi?pageno=' || garbage.pageno + || '#msg' || garbage.sn + AS path, + null AS title, + null AS author, + to_char(garbage.updated, 'YYYY-MM-DD') AS date, + garbage.message AS body, + null AS kw, + FALSE AS html + FROM garbage + WHERE NOT garbage.hid) + ORDER BY date DESC, title; +GRANT SELECT ON search_list TO nobody; + + +-- +-- Table structure for table "funds" +-- + +CREATE TABLE funds ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + cat0 varchar(16) NOT NULL CHECK (cat0 != ''), + cat1 varchar(16) CHECK (cat1 IS NULL OR cat1 != ''), + cat2 varchar(16) CHECK (cat2 IS NULL OR cat2 != ''), + cat3 varchar(16) CHECK (cat3 IS NULL OR cat3 != ''), + title varchar(32) NOT NULL CHECK (title != ''), + m1ret numeric(5, 2), + m1rank numeric(4, 4) CHECK ((m1ret IS NULL AND m1rank IS NULL) OR (m1ret IS NOT NULL AND m1rank IS NOT NULL AND m1rank > 0 AND m1rank < 1)), + m1rnkdsc varchar(16) CHECK ((m1ret IS NULL AND m1rnkdsc IS NULL) OR (m1ret IS NOT NULL AND m1rnkdsc IS NOT NULL AND m1rnkdsc != '')), + m3ret numeric(5, 2), + m3rank numeric(4, 4) CHECK ((m3ret IS NULL AND m3rank IS NULL) OR (m3ret IS NOT NULL AND m3rank IS NOT NULL AND m3rank > 0 AND m3rank < 1)), + m3rnkdsc varchar(16) CHECK ((m3ret IS NULL AND m3rnkdsc IS NULL) OR (m3ret IS NOT NULL AND m3rnkdsc IS NOT NULL AND m3rnkdsc != '')), + m6ret numeric(5, 2), + m6rank numeric(4, 4) CHECK ((m6ret IS NULL AND m6rank IS NULL) OR (m6ret IS NOT NULL AND m6rank IS NOT NULL AND m6rank > 0 AND m6rank < 1)), + m6rnkdsc varchar(16) CHECK ((m6ret IS NULL AND m6rnkdsc IS NULL) OR (m6ret IS NOT NULL AND m6rnkdsc IS NOT NULL AND m6rnkdsc != '')), + y1ret numeric(5, 2), + y1rank numeric(4, 4) CHECK ((y1ret IS NULL AND y1rank IS NULL) OR (y1ret IS NOT NULL AND y1rank IS NOT NULL AND y1rank > 0 AND y1rank < 1)), + y1rnkdsc varchar(16) CHECK ((y1ret IS NULL AND y1rnkdsc IS NULL) OR (y1ret IS NOT NULL AND y1rnkdsc IS NOT NULL AND y1rnkdsc != '')), + y2ret numeric(5, 2), + y2rank numeric(4, 4) CHECK ((y2ret IS NULL AND y2rank IS NULL) OR (y2ret IS NOT NULL AND y2rank IS NOT NULL AND y2rank > 0 AND y2rank < 1)), + y2rnkdsc varchar(16) CHECK ((y2ret IS NULL AND y2rnkdsc IS NULL) OR (y2ret IS NOT NULL AND y2rnkdsc IS NOT NULL AND y2rnkdsc != '')), + y3ret numeric(5, 2), + y3rank numeric(4, 4) CHECK ((y3ret IS NULL AND y3rank IS NULL) OR (y3ret IS NOT NULL AND y3rank IS NOT NULL AND y3rank > 0 AND y3rank < 1)), + y3rnkdsc varchar(16) CHECK ((y3ret IS NULL AND y3rnkdsc IS NULL) OR (y3ret IS NOT NULL AND y3rnkdsc IS NOT NULL AND y3rnkdsc != '')), + y5ret numeric(5, 2), + y5rank numeric(4, 4) CHECK ((y5ret IS NULL AND y5rank IS NULL) OR (y5ret IS NOT NULL AND y5rank IS NOT NULL AND y5rank > 0 AND y5rank < 1)), + y5rnkdsc varchar(16) CHECK ((y5ret IS NULL AND y5rnkdsc IS NULL) OR (y5ret IS NOT NULL AND y5rnkdsc IS NOT NULL AND y5rnkdsc != '')), + y10ret numeric(5, 2), + y10rank numeric(4, 4) CHECK ((y10ret IS NULL AND y10rank IS NULL) OR (y10ret IS NOT NULL AND y10rank IS NOT NULL AND y10rank > 0 AND y10rank < 1)), + y10rnkdsc varchar(16) CHECK ((y10ret IS NULL AND y10rnkdsc IS NULL) OR (y10ret IS NOT NULL AND y10rnkdsc IS NOT NULL AND y10rnkdsc != '')), + ytret numeric(5, 2), + ytrank numeric(4, 4) CHECK ((ytret IS NULL AND ytrank IS NULL) OR (ytret IS NOT NULL AND ytrank IS NOT NULL AND ytrank > 0 AND ytrank < 1)), + ytrnkdsc varchar(16) CHECK ((ytret IS NULL AND ytrnkdsc IS NULL) OR (ytret IS NOT NULL AND ytrnkdsc IS NOT NULL AND ytrnkdsc != '')), + beginret numeric(6, 2), + begindate date NOT NULL, + bestm3 numeric(5, 2), + worstm3 numeric(5, 2), + sd12 numeric(4, 2), + sd24 numeric(4, 2), + beta12 numeric(8, 4), + beta24 numeric(8, 4), + sharpe12 numeric(8, 4), + sharpe24 numeric(8, 4), + jensen12 numeric(8, 4), + jensen24 numeric(8, 4), + treynor12 numeric(11, 4), + treynor24 numeric(8, 4), + infrma12 numeric(8, 4), + infrma24 numeric(8, 4), + infrmi12 numeric(8, 4), + infrmi24 numeric(8, 4), + turnmt numeric(5, 2), + turny1 numeric(6, 2), + duration numeric(3, 2), + rating varchar(64), + newman boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON funds TO nobody; +ALTER TABLE funds OWNER TO robot; + +CREATE VIEW funds_list_zhtw AS + SELECT + funds.sn AS sn, + cat0 || CASE WHEN cat1 IS NULL THEN '' + ELSE ' / ' || cat1 || CASE WHEN cat2 IS NULL THEN '' + ELSE ' / ' || cat2 || CASE WHEN cat3 IS NULL THEN '' + ELSE ' / ' || cat3 END + END + END AS cat, + funds.title AS title, + funds.m1ret AS m1ret, + funds.m1rank AS _m1rank, + funds.m1rnkdsc AS m1rank, + funds.m3ret AS m3ret, + funds.m3rank AS _m3rank, + funds.m3rnkdsc AS m3rank, + funds.m6ret AS m6ret, + funds.m6rank AS _m6rank, + funds.m6rnkdsc AS m6rank, + funds.y1ret AS y1ret, + funds.y1rank AS _y1rank, + funds.y1rnkdsc AS y1rank, + funds.y2ret AS y2ret, + funds.y2rank AS _y2rank, + funds.y2rnkdsc AS y2rank, + funds.y3ret AS y3ret, + funds.y3rank AS _y3rank, + funds.y3rnkdsc AS y3rank, + funds.y5ret AS y5ret, + funds.y5rank AS _y5rank, + funds.y5rnkdsc AS y5rank, + funds.y10ret AS y10ret, + funds.y10rank AS _y10rank, + funds.y10rnkdsc AS y10rank, + funds.ytret AS ytret, + funds.ytrank AS _ytrank, + funds.ytrnkdsc AS ytrank, + funds.beginret AS beginret, + funds.begindate AS begindate, + funds.bestm3 AS bestm3, + funds.worstm3 AS worstm3, + funds.sd12 AS sd12, + funds.sd24 AS sd24, + funds.beta12 AS beta12, + funds.beta24 AS beta24, + funds.sharpe12 AS sharpe12, + funds.sharpe24 AS sharpe24, + funds.jensen12 AS jensen12, + funds.jensen24 AS jensen24, + funds.treynor12 AS treynor12, + funds.treynor24 AS treynor24, + funds.infrma12 AS infrma12, + funds.infrma24 AS infrma24, + funds.infrmi12 AS infrmi12, + funds.infrmi24 AS infrmi24, + funds.turnmt AS turnmt, + funds.turny1 AS turny1, + funds.duration AS duration, + funds.rating AS rating, + CASE WHEN funds.newman THEN '未滿一年' + ELSE '' + END AS newman, + to_char(funds.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(funds.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM funds + LEFT JOIN users AS createdby ON funds.createdby = createdby.sn + LEFT JOIN users AS updatedby ON funds.updatedby = updatedby.sn + ORDER BY CASE WHEN funds.y5ret IS NULL THEN 0 ELSE funds.y5ret END DESC; +GRANT SELECT ON funds_list_zhtw TO nobody; +CREATE VIEW funds_list_en AS + SELECT + funds.sn AS sn, + cat0 || CASE WHEN cat1 IS NULL THEN '' + ELSE ' / ' || cat1 || CASE WHEN cat2 IS NULL THEN '' + ELSE ' / ' || cat2 || CASE WHEN cat3 IS NULL THEN '' + ELSE ' / ' || cat3 END + END + END AS cat, + funds.title AS title, + funds.m1ret AS m1ret, + funds.m1rank AS _m1rank, + funds.m1rnkdsc AS m1rank, + funds.m3ret AS m3ret, + funds.m3rank AS _m3rank, + funds.m3rnkdsc AS m3rank, + funds.m6ret AS m6ret, + funds.m6rank AS _m6rank, + funds.m6rnkdsc AS m6rank, + funds.y1ret AS y1ret, + funds.y1rank AS _y1rank, + funds.y1rnkdsc AS y1rank, + funds.y2ret AS y2ret, + funds.y2rank AS _y2rank, + funds.y2rnkdsc AS y2rank, + funds.y3ret AS y3ret, + funds.y3rank AS _y3rank, + funds.y3rnkdsc AS y3rank, + funds.y5ret AS y5ret, + funds.y5rank AS _y5rank, + funds.y5rnkdsc AS y5rank, + funds.y10ret AS y10ret, + funds.y10rank AS _y10rank, + funds.y10rnkdsc AS y10rank, + funds.ytret AS ytret, + funds.ytrank AS _ytrank, + funds.ytrnkdsc AS ytrank, + funds.beginret AS beginret, + funds.begindate AS begindate, + funds.bestm3 AS bestm3, + funds.worstm3 AS worstm3, + funds.sd12 AS sd12, + funds.sd24 AS sd24, + funds.beta12 AS beta12, + funds.beta24 AS beta24, + funds.sharpe12 AS sharpe12, + funds.sharpe24 AS sharpe24, + funds.jensen12 AS jensen12, + funds.jensen24 AS jensen24, + funds.treynor12 AS treynor12, + funds.treynor24 AS treynor24, + funds.infrma12 AS infrma12, + funds.infrma24 AS infrma24, + funds.infrmi12 AS infrmi12, + funds.infrmi24 AS infrmi24, + funds.turnmt AS turnmt, + funds.turny1 AS turny1, + funds.duration AS duration, + funds.rating AS rating, + CASE WHEN funds.newman THEN 'Less' + ELSE '' + END AS newman, + to_char(funds.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(funds.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM funds + LEFT JOIN users AS createdby ON funds.createdby = createdby.sn + LEFT JOIN users AS updatedby ON funds.updatedby = updatedby.sn + ORDER BY CASE WHEN funds.y5ret IS NULL THEN 0 ELSE funds.y5ret END DESC; +GRANT SELECT ON funds_list_en TO nobody; +CREATE VIEW funds_list_zhcn AS + SELECT + funds.sn AS sn, + cat0 || CASE WHEN cat1 IS NULL THEN '' + ELSE ' / ' || cat1 || CASE WHEN cat2 IS NULL THEN '' + ELSE ' / ' || cat2 || CASE WHEN cat3 IS NULL THEN '' + ELSE ' / ' || cat3 END + END + END AS cat, + funds.title AS title, + funds.m1ret AS m1ret, + funds.m1rank AS _m1rank, + funds.m1rnkdsc AS m1rank, + funds.m3ret AS m3ret, + funds.m3rank AS _m3rank, + funds.m3rnkdsc AS m3rank, + funds.m6ret AS m6ret, + funds.m6rank AS _m6rank, + funds.m6rnkdsc AS m6rank, + funds.y1ret AS y1ret, + funds.y1rank AS _y1rank, + funds.y1rnkdsc AS y1rank, + funds.y2ret AS y2ret, + funds.y2rank AS _y2rank, + funds.y2rnkdsc AS y2rank, + funds.y3ret AS y3ret, + funds.y3rank AS _y3rank, + funds.y3rnkdsc AS y3rank, + funds.y5ret AS y5ret, + funds.y5rank AS _y5rank, + funds.y5rnkdsc AS y5rank, + funds.y10ret AS y10ret, + funds.y10rank AS _y10rank, + funds.y10rnkdsc AS y10rank, + funds.ytret AS ytret, + funds.ytrank AS _ytrank, + funds.ytrnkdsc AS ytrank, + funds.beginret AS beginret, + funds.begindate AS begindate, + funds.bestm3 AS bestm3, + funds.worstm3 AS worstm3, + funds.sd12 AS sd12, + funds.sd24 AS sd24, + funds.beta12 AS beta12, + funds.beta24 AS beta24, + funds.sharpe12 AS sharpe12, + funds.sharpe24 AS sharpe24, + funds.jensen12 AS jensen12, + funds.jensen24 AS jensen24, + funds.treynor12 AS treynor12, + funds.treynor24 AS treynor24, + funds.infrma12 AS infrma12, + funds.infrma24 AS infrma24, + funds.infrmi12 AS infrmi12, + funds.infrmi24 AS infrmi24, + funds.turnmt AS turnmt, + funds.turny1 AS turny1, + funds.duration AS duration, + funds.rating AS rating, + CASE WHEN funds.newman THEN '未满一年' + ELSE '' + END AS newman, + to_char(funds.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(funds.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM funds + LEFT JOIN users AS createdby ON funds.createdby = createdby.sn + LEFT JOIN users AS updatedby ON funds.updatedby = updatedby.sn + ORDER BY CASE WHEN funds.y5ret IS NULL THEN 0 ELSE funds.y5ret END DESC; +GRANT SELECT ON funds_list_zhcn TO nobody; + + +-- +-- Function definitions for table "accttrx" +-- + +-- boolean acctsubj_ischild(parent_arg integer, sn_arg integer, code_arg text); +CREATE FUNCTION acctsubj_ischild(parent_arg integer, sn_arg integer, code_arg text) RETURNS boolean AS ' + DECLARE + row record; + BEGIN + -- First level subjects have no parent + IF char_length(code_arg) = 1 THEN + IF parent_arg IS NULL THEN + RETURN TRUE; + ELSE + RETURN FALSE; + END IF; + END IF; + -- Second level subjects and below must have a parent + IF parent_arg IS NULL THEN + RETURN FALSE; + END IF; + -- A subject must not belong to itself + IF parent_arg IS NOT DISTINCT FROM sn_arg THEN + RETURN FALSE; + END IF; + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + SELECT INTO row code FROM public.acctsubj WHERE sn=parent_arg; + -- parent is guarenteed by FOREIGN KEY constraint, so we do not check it. + -- This helps when importing data from the dump files since we cannot help + -- the data order in the dump files. + IF NOT FOUND THEN + RETURN TRUE; + END IF; + -- The code of the parent must match the preceding part of our code + IF row.code = substring(code_arg FROM 1 FOR char_length(code_arg) - 1) THEN + RETURN TRUE; + END IF; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_ischild(parent_arg integer, sn_arg integer, code_arg text) TO nobody; + +-- text acctsubj_fulltitle(lang_arg text, sn_arg integer); +CREATE FUNCTION acctsubj_fulltitle(lang_arg text, sn_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + title_full text; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM acctsubj WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + title_full := CASE lang_arg + WHEN ''en'' THEN COALESCE(row.title_en, row.title_zhtw) + WHEN ''zh-cn'' THEN COALESCE(row.title_zhcn, row.title_zhtw) + ELSE row.title_zhtw + END; + WHILE row.parent IS NOT NULL LOOP + sn_loop := row.parent; + SELECT INTO row * FROM acctsubj WHERE sn=sn_loop; + title_full := CASE lang_arg + WHEN ''en'' THEN COALESCE(row.title_en, row.title_zhtw) + WHEN ''zh-cn'' THEN COALESCE(row.title_zhcn, row.title_zhtw) + ELSE row.title_zhtw + END || '' / '' || title_full; + END LOOP; + RETURN title_full; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_fulltitle(lang_arg text, sn_arg integer) TO nobody; +-- text acctsubj_fulltitle(lang_arg text, parent_arg integer, title_arg text); +CREATE FUNCTION acctsubj_fulltitle(lang_arg text, parent_arg integer, title_arg text) RETURNS text AS ' + BEGIN + IF parent_arg IS NULL THEN + RETURN title_arg; + END IF; + RETURN acctsubj_fulltitle(lang_arg, parent_arg) + || '' / '' || title_arg; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_fulltitle(lang_arg text, parent_arg integer, title_arg text) TO nobody; +-- text acctsubj_codetitle(lang_arg text, sn_arg integer); +CREATE FUNCTION acctsubj_codetitle(lang_arg text, sn_arg integer) RETURNS text AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM acctsubj WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.code || '' '' || CASE lang_arg + WHEN ''en'' THEN COALESCE(row.title_en, row.title_zhtw) + WHEN ''zh-cn'' THEN COALESCE(row.title_zhcn, row.title_zhtw) + ELSE row.title_zhtw + END; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_codetitle(lang_arg text, sn_arg integer) TO nobody; + +-- timestamp acctsubj_recent(subj_arg integer); +CREATE FUNCTION acctsubj_recent(subj_arg integer) RETURNS timestamp AS ' + DECLARE + row record; + BEGIN + IF subj_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row updated FROM acctrecs WHERE subj=subj_arg + ORDER BY updated DESC LIMIT 1; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.updated; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_recent(subj_arg integer) TO nobody; + +-- boolean acctsubj_islastlv(sn_arg integer); +CREATE FUNCTION acctsubj_islastlv(sn_arg integer) RETURNS boolean AS ' + BEGIN + PERFORM sn FROM acctsubj WHERE parent=sn_arg LIMIT 1; + RETURN NOT FOUND; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_islastlv(sn_arg integer) TO nobody; + +-- boolean accttrx_has_subj(sn_arg integer, code_arg text); +CREATE FUNCTION accttrx_has_subj(sn_arg integer, code_arg text) RETURNS boolean AS ' + BEGIN + PERFORM acctrecs.sn FROM acctrecs + LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn + WHERE acctrecs.trx=sn_arg + AND acctsubj.code LIKE code_arg || ''%'' + LIMIT 1; + RETURN FOUND; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION accttrx_has_subj(sn_arg integer, code_arg text) TO nobody; + +-- integer acctsum_debit(year_arg integer, month_arg integer, code_here text); +CREATE FUNCTION acctsum_debit(year_arg integer, month_arg integer, code_here text) RETURNS integer AS ' + DECLARE + row record; + BEGIN + SELECT INTO row sum(acctrecs.amount) AS sum + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + WHERE NOT acctrecs.credit + AND acctsubj.code LIKE code_here || ''%'' + AND extract(year FROM accttrx.date) = year_arg + AND extract(month FROM accttrx.date) = month_arg; + IF row.sum IS NULL THEN + RETURN 0; + END IF; + RETURN row.sum; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsum_debit(year_arg integer, month_arg integer, code_here text) TO nobody; +-- integer acctsum_credit(year_arg integer, month_arg integer, code_here text); +CREATE FUNCTION acctsum_credit(year_arg integer, month_arg integer, code_here text) RETURNS integer AS ' + DECLARE + row record; + BEGIN + SELECT INTO row sum(acctrecs.amount) AS sum + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + WHERE acctrecs.credit + AND acctsubj.code LIKE code_here || ''%'' + AND extract(year FROM accttrx.date) = year_arg + AND extract(month FROM accttrx.date) = month_arg; + IF row.sum IS NULL THEN + RETURN 0; + END IF; + RETURN row.sum; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsum_credit(year_arg integer, month_arg integer, code_here text) TO nobody; +-- integer acctsum_balance(year_arg integer, month_arg integer, code_here text); +CREATE FUNCTION acctsum_balance(year_arg integer, month_arg integer, code_here text) RETURNS integer AS ' + DECLARE + row record; + BEGIN + SELECT INTO row sum(CASE WHEN acctrecs.credit THEN -acctrecs.amount ELSE acctrecs.amount END) AS sum + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + WHERE acctsubj.code LIKE code_here || ''%'' + AND extract(year FROM accttrx.date) * 100 + extract(month FROM accttrx.date) <= year_arg * 100 + month_arg; + IF row.sum IS NULL THEN + RETURN 0; + END IF; + RETURN row.sum; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsum_balance(year_arg integer, month_arg integer, code_here text) TO nobody; + + +-- +-- Table structure for table "acctsubj" +-- + +CREATE TABLE acctsubj ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + parent int REFERENCES acctsubj ON UPDATE CASCADE DEFERRABLE CHECK (acctsubj_ischild(parent, sn, code)), + code varchar(5) NOT NULL UNIQUE CHECK (code != ''), + title_zhtw varchar(32) NOT NULL CHECK (title_zhtw != ''), + title_en varchar(128) CHECK (title_en IS NULL OR title_en != ''), + title_zhcn varchar(32) CHECK (title_zhcn IS NULL OR title_zhcn != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON acctsubj TO nobody; + +CREATE VIEW acctsubj_list_zhtw AS + SELECT + acctsubj.sn AS sn, + acctsubj.code AS code, + acctsubj_fulltitle('zh-tw', acctsubj.parent, acctsubj.title_zhtw) AS title, + to_char(acctsubj.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctsubj.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctsubj + LEFT JOIN users AS createdby ON acctsubj.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctsubj.updatedby = updatedby.sn + ORDER BY acctsubj.code; +GRANT SELECT ON acctsubj_list_zhtw TO nobody; +CREATE VIEW acctsubj_list_en AS + SELECT + acctsubj.sn AS sn, + acctsubj.code AS code, + acctsubj_fulltitle('en', acctsubj.parent, COALESCE(acctsubj.title_en, acctsubj.title_zhtw)) AS title, + to_char(acctsubj.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctsubj.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctsubj + LEFT JOIN users AS createdby ON acctsubj.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctsubj.updatedby = updatedby.sn + ORDER BY acctsubj.code; +GRANT SELECT ON acctsubj_list_en TO nobody; +CREATE VIEW acctsubj_list_zhcn AS + SELECT + acctsubj.sn AS sn, + acctsubj.code AS code, + acctsubj_fulltitle('zh-cn', acctsubj.parent, COALESCE(acctsubj.title_zhcn, acctsubj.title_zhtw)) AS title, + to_char(acctsubj.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctsubj.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctsubj + LEFT JOIN users AS createdby ON acctsubj.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctsubj.updatedby = updatedby.sn + ORDER BY acctsubj.code; +GRANT SELECT ON acctsubj_list_zhcn TO nobody; + +CREATE VIEW acctsubj_lastlv_list_zhtw AS + SELECT + acctsubj.sn AS sn, + acctsubj.code AS code, + acctsubj_fulltitle('zh-tw', acctsubj.parent, acctsubj.title_zhtw) AS title, + to_char(acctsubj.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctsubj.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctsubj + LEFT JOIN users AS createdby ON acctsubj.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctsubj.updatedby = updatedby.sn + WHERE acctsubj_islastlv(acctsubj.sn) + ORDER BY acctsubj.code; +GRANT SELECT ON acctsubj_lastlv_list_zhtw TO nobody; +CREATE VIEW acctsubj_lastlv_list_en AS + SELECT + acctsubj.sn AS sn, + acctsubj.code AS code, + acctsubj_fulltitle('en', acctsubj.parent, COALESCE(acctsubj.title_en, acctsubj.title_zhtw)) AS title, + to_char(acctsubj.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctsubj.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctsubj + LEFT JOIN users AS createdby ON acctsubj.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctsubj.updatedby = updatedby.sn + WHERE acctsubj_islastlv(acctsubj.sn) + ORDER BY acctsubj.code; +GRANT SELECT ON acctsubj_lastlv_list_en TO nobody; +CREATE VIEW acctsubj_lastlv_list_zhcn AS + SELECT + acctsubj.sn AS sn, + acctsubj.code AS code, + acctsubj_fulltitle('zh-cn', acctsubj.parent, COALESCE(acctsubj.title_zhcn, acctsubj.title_zhtw)) AS title, + to_char(acctsubj.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctsubj.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctsubj + LEFT JOIN users AS createdby ON acctsubj.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctsubj.updatedby = updatedby.sn + WHERE acctsubj_islastlv(acctsubj.sn) + ORDER BY acctsubj.code; +GRANT SELECT ON acctsubj_lastlv_list_zhcn TO nobody; + + +-- +-- Table structure for table "accttrx" +-- + +CREATE TABLE accttrx ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + date date NOT NULL DEFAULT CURRENT_DATE, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + note varchar(128) CHECK (note IS NULL OR note != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON accttrx TO nobody; + +CREATE VIEW accttrx_list_zhtw AS + SELECT + accttrx.sn AS sn, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS num, + accttrx.note AS note, + to_char(accttrx.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(accttrx.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM accttrx + LEFT JOIN users AS createdby ON accttrx.createdby = createdby.sn + LEFT JOIN users AS updatedby ON accttrx.updatedby = updatedby.sn + ORDER BY accttrx.date DESC, accttrx.ord DESC; +GRANT SELECT ON accttrx_list_zhtw TO nobody; +CREATE VIEW accttrx_list_en AS + SELECT + accttrx.sn AS sn, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS num, + accttrx.note AS note, + to_char(accttrx.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(accttrx.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM accttrx + LEFT JOIN users AS createdby ON accttrx.createdby = createdby.sn + LEFT JOIN users AS updatedby ON accttrx.updatedby = updatedby.sn + ORDER BY accttrx.date DESC, accttrx.ord DESC; +GRANT SELECT ON accttrx_list_en TO nobody; +CREATE VIEW accttrx_list_zhcn AS + SELECT + accttrx.sn AS sn, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS num, + accttrx.note AS note, + to_char(accttrx.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(accttrx.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM accttrx + LEFT JOIN users AS createdby ON accttrx.createdby = createdby.sn + LEFT JOIN users AS updatedby ON accttrx.updatedby = updatedby.sn + ORDER BY accttrx.date DESC, accttrx.ord DESC; +GRANT SELECT ON accttrx_list_zhcn TO nobody; + + +-- +-- Table structure for table "acctrecs" +-- + +CREATE TABLE acctrecs ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + trx int NOT NULL REFERENCES accttrx ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + credit boolean NOT NULL, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + subj int NOT NULL REFERENCES acctsubj ON UPDATE CASCADE DEFERRABLE, + summary varchar(128) CHECK (summary IS NULL OR summary != ''), + amount int NOT NULL CHECK (amount > 0), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (trx, credit, ord) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON acctrecs TO nobody; + +CREATE VIEW acctrecs_list_zhtw AS + SELECT + acctrecs.sn AS sn, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS trx, + CASE WHEN credit THEN '貸' ELSE '借' END AS credit, + acctrecs.ord AS ord, + acctsubj.code || ' ' || acctsubj.title_zhtw AS subj, + acctrecs.summary AS summary, + acctrecs.amount AS amount, + to_char(acctrecs.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctrecs.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + LEFT JOIN users AS createdby ON acctrecs.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctrecs.updatedby = updatedby.sn + ORDER BY accttrx.date DESC, accttrx.ord DESC, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrecs_list_zhtw TO nobody; +CREATE VIEW acctrecs_list_en AS + SELECT + acctrecs.sn AS sn, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS trx, + CASE WHEN credit THEN 'Credit' ELSE 'Debit' END AS credit, + acctrecs.ord AS ord, + acctsubj.code || ' ' + || COALESCE(acctsubj.title_en, acctsubj.title_zhtw) AS subj, + acctrecs.summary AS summary, + acctrecs.amount AS amount, + to_char(acctrecs.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctrecs.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + LEFT JOIN users AS createdby ON acctrecs.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctrecs.updatedby = updatedby.sn + ORDER BY accttrx.date DESC, accttrx.ord DESC, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrecs_list_en TO nobody; +CREATE VIEW acctrecs_list_zhcn AS + SELECT + acctrecs.sn AS sn, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS trx, + CASE WHEN credit THEN '贷' ELSE '借' END AS credit, + acctrecs.ord AS ord, + acctsubj.code || ' ' || + COALESCE(acctsubj.title_zhcn, acctsubj.title_zhtw) AS subj, + acctrecs.summary AS summary, + acctrecs.amount AS amount, + to_char(acctrecs.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctrecs.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + LEFT JOIN users AS createdby ON acctrecs.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctrecs.updatedby = updatedby.sn + ORDER BY accttrx.date DESC, accttrx.ord DESC, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrecs_list_zhcn TO nobody; + + +-- +-- Accounting reports +-- +CREATE VIEW acctrep_cash_list_zhtw AS + SELECT + TRUE AS _sel, + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + acctsubj.code AS _subj, + accttrx.date AS _date, + acctrecs.trx AS _trx, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + acctsubj.code || ' ' || acctsubj.title_zhtw AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS income, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS expense, + 0 AS balance + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 1 ELSE 2 END, acctrecs.ord; +GRANT SELECT ON acctrep_cash_list_zhtw TO nobody; +CREATE VIEW acctrep_cash_list_en AS + SELECT + TRUE AS _sel, + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + acctsubj.code AS _subj, + accttrx.date AS _date, + acctrecs.trx AS _trx, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + acctsubj.code || ' ' || + COALESCE(acctsubj.title_en, acctsubj.title_zhtw) AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS income, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS expense, + 0 AS balance + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 1 ELSE 2 END, acctrecs.ord; +GRANT SELECT ON acctrep_cash_list_en TO nobody; +CREATE VIEW acctrep_cash_list_zhcn AS + SELECT + TRUE AS _sel, + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + acctsubj.code AS _subj, + accttrx.date AS _date, + acctrecs.trx AS _trx, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + acctsubj.code || ' ' || + COALESCE(acctsubj.title_zhcn, acctsubj.title_zhtw) AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS income, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS expense, + 0 AS balance + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 1 ELSE 2 END, acctrecs.ord; +GRANT SELECT ON acctrep_cash_list_zhcn TO nobody; + +CREATE VIEW acctrep_ledger_list_zhtw AS + SELECT + TRUE AS _sel, + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + acctsubj.code AS _subj, + accttrx.date AS _date, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + acctsubj.code || ' ' || acctsubj.title_zhtw AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS debit, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS credit, + 0 AS balance + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrep_ledger_list_zhtw TO nobody; +CREATE VIEW acctrep_ledger_list_en AS + SELECT + TRUE AS _sel, + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + acctsubj.code AS _subj, + accttrx.date AS _date, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + acctsubj.code || ' ' || + COALESCE(acctsubj.title_en, acctsubj.title_zhtw) AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS debit, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS credit, + 0 AS balance + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrep_ledger_list_en TO nobody; +CREATE VIEW acctrep_ledger_list_zhcn AS + SELECT + TRUE AS _sel, + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + acctsubj.code AS _subj, + accttrx.date AS _date, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + acctsubj.code || ' ' || + COALESCE(acctsubj.title_zhcn, acctsubj.title_zhtw) AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS debit, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS credit, + 0 AS balance + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrep_ledger_list_zhcn TO nobody; + +CREATE VIEW acctrep_search_list_zhtw AS + SELECT + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS trxno, + acctsubj.code || ' ' || acctsubj.title_zhtw AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS debit, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS credit, + accttrx.note AS note + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrep_search_list_zhtw TO nobody; +CREATE VIEW acctrep_search_list_en AS + SELECT + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS trxno, + acctsubj.code || ' ' || + COALESCE(acctsubj.title_en, acctsubj.title_zhtw) AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS debit, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS credit, + accttrx.note AS note + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrep_search_list_en TO nobody; +CREATE VIEW acctrep_search_list_zhcn AS + SELECT + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS trxno, + acctsubj.code || ' ' || + COALESCE(acctsubj.title_zhcn, acctsubj.title_zhtw) AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS debit, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS credit, + accttrx.note AS note + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrep_search_list_zhcn TO nobody; + + +-- text paper_authors(sn_arg integer); +CREATE FUNCTION paper_authors(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + authors_list text; + BEGIN + authors_list := ''''; + FOR row IN + SELECT resrcher.name AS name FROM resrcher + LEFT JOIN pprauthr ON pprauthr.author=resrcher.sn + WHERE pprauthr.paper=sn_arg + ORDER BY resrcher.abbr + LOOP + authors_list := authors_list || '', '' || row.name; + END LOOP; + RETURN substring(authors_list FROM 3); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION paper_authors(sn_arg integer) TO nobody; + + +-- +-- Table structure for table "resrcher" +-- + +CREATE TABLE resrcher ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + name varchar(32) NOT NULL UNIQUE CHECK (name != ''), + abbr varchar(32) NOT NULL CHECK (abbr != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON resrcher TO nobody; + +CREATE VIEW resrcher_list_zhtw AS + SELECT + resrcher.sn AS sn, + resrcher.name AS name, + resrcher.abbr AS abbr, + to_char(resrcher.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(resrcher.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM resrcher + LEFT JOIN users AS createdby ON resrcher.createdby = createdby.sn + LEFT JOIN users AS updatedby ON resrcher.updatedby = updatedby.sn + ORDER BY resrcher.abbr; +GRANT SELECT ON resrcher_list_zhtw TO nobody; +CREATE VIEW resrcher_list_en AS + SELECT + resrcher.sn AS sn, + resrcher.name AS name, + resrcher.abbr AS abbr, + to_char(resrcher.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(resrcher.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM resrcher + LEFT JOIN users AS createdby ON resrcher.createdby = createdby.sn + LEFT JOIN users AS updatedby ON resrcher.updatedby = updatedby.sn + ORDER BY resrcher.abbr; +GRANT SELECT ON resrcher_list_en TO nobody; +CREATE VIEW resrcher_list_zhcn AS + SELECT + resrcher.sn AS sn, + resrcher.name AS name, + resrcher.abbr AS abbr, + to_char(resrcher.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(resrcher.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM resrcher + LEFT JOIN users AS createdby ON resrcher.createdby = createdby.sn + LEFT JOIN users AS updatedby ON resrcher.updatedby = updatedby.sn + ORDER BY resrcher.abbr; +GRANT SELECT ON resrcher_list_zhcn TO nobody; + + +-- text paper_tags(sn_arg integer); +CREATE FUNCTION paper_tags(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + tags_list text; + BEGIN + tags_list := ''''; + FOR row IN + SELECT tags.title AS title FROM tags + LEFT JOIN pprtags ON pprtags.tag=tags.sn + WHERE pprtags.paper=sn_arg + ORDER BY tags.title + LOOP + tags_list := tags_list || '', '' || row.title; + END LOOP; + RETURN substring(tags_list FROM 3); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION paper_tags(sn_arg integer) TO nobody; + + +-- +-- Table structure for table "tags" +-- + +CREATE TABLE tags ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + title varchar(32) NOT NULL UNIQUE CHECK (title != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON tags TO nobody; + +CREATE VIEW tags_list_zhtw AS + SELECT + tags.sn AS sn, + tags.title AS title, + to_char(tags.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(tags.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM tags + LEFT JOIN users AS createdby ON tags.createdby = createdby.sn + LEFT JOIN users AS updatedby ON tags.updatedby = updatedby.sn + ORDER BY tags.title; +GRANT SELECT ON tags_list_zhtw TO nobody; +CREATE VIEW tags_list_en AS + SELECT + tags.sn AS sn, + tags.title AS title, + to_char(tags.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(tags.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM tags + LEFT JOIN users AS createdby ON tags.createdby = createdby.sn + LEFT JOIN users AS updatedby ON tags.updatedby = updatedby.sn + ORDER BY tags.title; +GRANT SELECT ON tags_list_en TO nobody; +CREATE VIEW tags_list_zhcn AS + SELECT + tags.sn AS sn, + tags.title AS title, + to_char(tags.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(tags.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM tags + LEFT JOIN users AS createdby ON tags.createdby = createdby.sn + LEFT JOIN users AS updatedby ON tags.updatedby = updatedby.sn + ORDER BY tags.title; +GRANT SELECT ON tags_list_zhcn TO nobody; + + +-- +-- Table structure for table "pprtypes" +-- + +CREATE TABLE pprtypes ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + ord smallint NOT NULL DEFAULT 50 CHECK (ord >= 0 AND ord < 100), + title_zhtw varchar(128) NOT NULL CHECK (title_zhtw != ''), + title_en varchar(128) CHECK (title_en IS NULL OR title_en != ''), + title_zhcn varchar(128) CHECK (title_zhcn IS NULL OR title_zhcn != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pprtypes TO nobody; + +CREATE VIEW pprtypes_list_zhtw AS + SELECT + pprtypes.sn AS sn, + pprtypes.ord AS ord, + pprtypes.title_zhtw AS title, + to_char(pprtypes.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprtypes.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprtypes + LEFT JOIN users AS createdby ON pprtypes.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprtypes.updatedby = updatedby.sn + ORDER BY pprtypes.ord; +GRANT SELECT ON pprtypes_list_zhtw TO nobody; +CREATE VIEW pprtypes_list_en AS + SELECT + pprtypes.sn AS sn, + pprtypes.ord AS ord, + COALESCE(pprtypes.title_en, pprtypes.title_zhtw) AS title, + to_char(pprtypes.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprtypes.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprtypes + LEFT JOIN users AS createdby ON pprtypes.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprtypes.updatedby = updatedby.sn + ORDER BY pprtypes.ord; +GRANT SELECT ON pprtypes_list_en TO nobody; +CREATE VIEW pprtypes_list_zhcn AS + SELECT + pprtypes.sn AS sn, + pprtypes.ord AS ord, + COALESCE(pprtypes.title_zhcn, pprtypes.title_zhtw) AS title, + to_char(pprtypes.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprtypes.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprtypes + LEFT JOIN users AS createdby ON pprtypes.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprtypes.updatedby = updatedby.sn + ORDER BY pprtypes.ord; +GRANT SELECT ON pprtypes_list_zhcn TO nobody; + + +-- +-- Table structure for table "papers" +-- + +CREATE TABLE papers ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + type int NOT NULL REFERENCES pprtypes ON UPDATE CASCADE DEFERRABLE, + year smallint NOT NULL CHECK (year > 1930), + month varchar(12) CHECK (month IS NULL or month != ''), + title varchar(128) NOT NULL CHECK (title != ''), + pub varchar(256) CHECK (pub IS NULL or pub != ''), + pages varchar(9) CHECK (pages IS NULL OR pages != ''), + doi varchar(32) CHECK (doi IS NULL OR doi != ''), + url varchar(128) NOT NULL CHECK (url != '' AND url != 'http://'), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON papers TO nobody; + +CREATE VIEW papers_list_zhtw AS + SELECT + papers.sn AS sn, + pprtypes.title_zhtw AS type, + papers.year AS year, + papers.month AS month, + papers.title AS title, + paper_authors(papers.sn) AS authors, + paper_tags(papers.sn) AS tags, + papers.pub AS pub, + papers.pages AS pages, + papers.doi AS doi, + papers.url AS url, + to_char(papers.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(papers.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM papers + LEFT JOIN pprtypes ON papers.type = pprtypes.sn + LEFT JOIN users AS createdby ON papers.createdby = createdby.sn + LEFT JOIN users AS updatedby ON papers.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title; +GRANT SELECT ON papers_list_zhtw TO nobody; +CREATE VIEW papers_list_en AS + SELECT + papers.sn AS sn, + COALESCE(pprtypes.title_en, pprtypes.title_zhtw) AS type, + papers.year AS year, + papers.month AS month, + papers.title AS title, + paper_authors(papers.sn) AS authors, + paper_tags(papers.sn) AS tags, + papers.pub AS pub, + papers.pages AS pages, + papers.doi AS doi, + papers.url AS url, + to_char(papers.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(papers.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM papers + LEFT JOIN pprtypes ON papers.type = pprtypes.sn + LEFT JOIN users AS createdby ON papers.createdby = createdby.sn + LEFT JOIN users AS updatedby ON papers.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title; +GRANT SELECT ON papers_list_en TO nobody; +CREATE VIEW papers_list_zhcn AS + SELECT + papers.sn AS sn, + COALESCE(pprtypes.title_zhcn, pprtypes.title_zhtw) AS type, + papers.year AS year, + papers.month AS month, + papers.title AS title, + paper_authors(papers.sn) AS authors, + paper_tags(papers.sn) AS tags, + papers.pub AS pub, + papers.pages AS pages, + papers.doi AS doi, + papers.url AS url, + to_char(papers.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(papers.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM papers + LEFT JOIN pprtypes ON papers.type = pprtypes.sn + LEFT JOIN users AS createdby ON papers.createdby = createdby.sn + LEFT JOIN users AS updatedby ON papers.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title; +GRANT SELECT ON papers_list_zhcn TO nobody; + + +-- +-- Table structure for table "pprauthr" +-- + +CREATE TABLE pprauthr ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + paper int NOT NULL REFERENCES papers ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + author int NOT NULL REFERENCES resrcher ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (paper, author) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pprauthr TO nobody; + +CREATE VIEW pprauthr_list_zhtw AS + SELECT + pprauthr.sn AS sn, + CAST(papers.year AS text) || ' - ' || papers.title AS paper, + resrcher.name AS author, + to_char(pprauthr.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprauthr.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprauthr + LEFT JOIN papers ON pprauthr.paper = papers.sn + LEFT JOIN resrcher ON pprauthr.author = resrcher.sn + LEFT JOIN users AS createdby ON pprauthr.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprauthr.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title, resrcher.abbr; +GRANT SELECT ON pprauthr_list_zhtw TO nobody; +CREATE VIEW pprauthr_list_en AS + SELECT + pprauthr.sn AS sn, + CAST(papers.year AS text) || ' - ' || papers.title AS paper, + resrcher.name AS author, + to_char(pprauthr.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprauthr.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprauthr + LEFT JOIN papers ON pprauthr.paper = papers.sn + LEFT JOIN resrcher ON pprauthr.author = resrcher.sn + LEFT JOIN users AS createdby ON pprauthr.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprauthr.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title, resrcher.abbr; +GRANT SELECT ON pprauthr_list_en TO nobody; +CREATE VIEW pprauthr_list_zhcn AS + SELECT + pprauthr.sn AS sn, + CAST(papers.year AS text) || ' - ' || papers.title AS paper, + resrcher.name AS author, + to_char(pprauthr.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprauthr.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprauthr + LEFT JOIN papers ON pprauthr.paper = papers.sn + LEFT JOIN resrcher ON pprauthr.author = resrcher.sn + LEFT JOIN users AS createdby ON pprauthr.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprauthr.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title, resrcher.abbr; +GRANT SELECT ON pprauthr_list_zhcn TO nobody; + + +-- +-- Table structure for table "pprtags" +-- + +CREATE TABLE pprtags ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + paper int NOT NULL REFERENCES papers ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + tag int NOT NULL REFERENCES tags ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (paper, tag) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pprtags TO nobody; + +CREATE VIEW pprtags_list_zhtw AS + SELECT + pprtags.sn AS sn, + CAST(papers.year AS text) || ' - ' || papers.title AS paper, + tags.title AS tag, + to_char(pprtags.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprtags.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprtags + LEFT JOIN papers ON pprtags.paper = papers.sn + LEFT JOIN tags ON pprtags.tag = tags.sn + LEFT JOIN users AS createdby ON pprtags.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprtags.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title, tags.title; +GRANT SELECT ON pprtags_list_zhtw TO nobody; +CREATE VIEW pprtags_list_en AS + SELECT + pprtags.sn AS sn, + CAST(papers.year AS text) || ' - ' || papers.title AS paper, + tags.title AS tag, + to_char(pprtags.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprtags.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprtags + LEFT JOIN papers ON pprtags.paper = papers.sn + LEFT JOIN tags ON pprtags.tag = tags.sn + LEFT JOIN users AS createdby ON pprtags.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprtags.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title, tags.title; +GRANT SELECT ON pprtags_list_en TO nobody; +CREATE VIEW pprtags_list_zhcn AS + SELECT + pprtags.sn AS sn, + CAST(papers.year AS text) || ' - ' || papers.title AS paper, + tags.title AS tag, + to_char(pprtags.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprtags.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprtags + LEFT JOIN papers ON pprtags.paper = papers.sn + LEFT JOIN tags ON pprtags.tag = tags.sn + LEFT JOIN users AS createdby ON pprtags.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprtags.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title, tags.title; +GRANT SELECT ON pprtags_list_zhcn TO nobody; + + +COMMIT; diff --git a/htdocs/imacat/magicat/lib/imacat.sql b/htdocs/imacat/magicat/lib/imacat.sql new file mode 100644 index 0000000..90f6222 --- /dev/null +++ b/htdocs/imacat/magicat/lib/imacat.sql @@ -0,0 +1,2949 @@ +-- 檔案名稱: imacat.sql +-- 程式說明: 旅舍依瑪資料庫定義檔 +-- 程式作者: 依瑪貓 imacat +-- 初稿日期: 2004-09-10 +-- 版權字樣: 版權所有 (c) 2004-2020 依瑪貓 +-- Set PGCLIENTENCODING=utf8 before restoring it + +SET NAMES 'utf8'; + +START TRANSACTION; + +-- +-- Table structure for table "mtime" +-- + +CREATE TABLE mtime ( + tabname varchar(32) NOT NULL PRIMARY KEY, + mtime timestamp with time zone NOT NULL DEFAULT now() +); +GRANT SELECT, INSERT, UPDATE, DELETE ON mtime TO nobody; + + +-- +-- Function definition for function "eschtml" +-- +-- integer eschtml(source text) +CREATE FUNCTION eschtml(source text) RETURNS text AS ' + DECLARE + result text; + BEGIN + result := source; + result := replace(result, ''&'', ''&''); + result := replace(result, ''<'', ''<''); + result := replace(result, ''>'', ''>''); + result := replace(result, ''"'', ''"''); + return result; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION eschtml(source text) TO nobody; + + +-- +-- Table structure for table "country" +-- + +CREATE TABLE country ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id char(2) NOT NULL UNIQUE CHECK (position(' ' in id) = 0), + name_en varchar(64) NOT NULL CHECK (name_en != ''), + name_zhtw varchar(32) CHECK (name_zhtw IS NULL OR name_zhtw != ''), + name_zhcn varchar(32) CHECK (name_zhcn IS NULL OR name_zhcn != ''), + special boolean NOT NULL DEFAULT FALSE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL +); +GRANT SELECT, INSERT, UPDATE, DELETE ON country TO nobody; + + +-- +-- Table structure for table "users" +-- + +CREATE TABLE users ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(32) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + passwd char(32) NOT NULL, + name varchar(32) NOT NULL CHECK (name != ''), + disabled boolean NOT NULL DEFAULT FALSE, + deleted boolean NOT NULL DEFAULT FALSE, + lang varchar(5) CHECK (lang IS NULL OR lang != ''), + visits smallint NOT NULL DEFAULT 0 CHECK (visits >= 0), + visited timestamp with time zone, + ip inet, + host varchar(128), + ct char(2) REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON users TO nobody; + +CREATE VIEW users_list_zhtw AS + SELECT + users.sn AS sn, + users.id AS id, + users.name AS name, + CASE WHEN users.disabled THEN '停用' + ELSE '' + END AS disabled, + CASE WHEN users.deleted THEN '已刪' + ELSE '' + END AS deleted, + CASE WHEN users.lang IS NULL THEN '(無)' + ELSE CASE users.lang + WHEN 'en' THEN '英文' + WHEN 'zh-tw' THEN '繁體中文' + WHEN 'zh-cn' THEN '簡體中文' + WHEN 'ja' THEN '日文' + WHEN 'de' THEN '德文' + WHEN 'es' THEN '西班牙文' + ELSE users.lang + END + END AS lang, + users.visits AS visits, + CASE WHEN users.visited IS NULL THEN '(無)' + ELSE to_char(users.visited, 'YYYY-MM-DD HH:MI:SS') + END AS visited, + CASE WHEN users.ip IS NULL THEN '(無)' + ELSE host(users.ip) + END AS ip, + CASE WHEN users.host IS NULL THEN '(無)' + ELSE users.host + END AS host, + CASE WHEN users.ct IS NULL THEN '(無)' + ELSE ct.name_zhtw + END AS ct, + to_char(users.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(users.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM users + LEFT JOIN country AS ct ON users.ct = ct.id + LEFT JOIN users AS createdby ON users.createdby = createdby.sn + LEFT JOIN users AS updatedby ON users.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON users_list_zhtw TO nobody; +CREATE VIEW users_list_en AS + SELECT + users.sn AS sn, + users.id AS id, + users.name AS name, + CASE WHEN users.disabled THEN 'Disabled' + ELSE '' + END AS disabled, + CASE WHEN users.deleted THEN 'Deleted' + ELSE '' + END AS deleted, + CASE WHEN users.lang IS NULL THEN '(none)' + ELSE CASE users.lang + WHEN 'en' THEN 'English' + WHEN 'zh-tw' THEN 'Traditional Chinese' + WHEN 'zh-cn' THEN 'Simplified Chinese' + WHEN 'ja' THEN 'Japanese' + WHEN 'de' THEN 'German' + WHEN 'es' THEN 'Spanish' + ELSE users.lang + END + END AS lang, + users.visits AS visits, + CASE WHEN users.visited IS NULL THEN '(none)' + ELSE to_char(users.visited, 'YYYY-MM-DD HH:MI:SS') + END AS visited, + CASE WHEN users.ip IS NULL THEN '(none)' + ELSE host(users.ip) + END AS ip, + CASE WHEN users.host IS NULL THEN '(none)' + ELSE users.host + END AS host, + CASE WHEN users.ct IS NULL THEN '(none)' + ELSE ct.name_en + END AS ct, + to_char(users.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(users.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM users + LEFT JOIN country AS ct ON users.ct = ct.id + LEFT JOIN users AS createdby ON users.createdby = createdby.sn + LEFT JOIN users AS updatedby ON users.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON users_list_en TO nobody; +CREATE VIEW users_list_zhcn AS + SELECT + users.sn AS sn, + users.id AS id, + users.name AS name, + CASE WHEN users.disabled THEN '停用' + ELSE '' + END AS disabled, + CASE WHEN users.deleted THEN '已删' + ELSE '' + END AS deleted, + CASE WHEN users.lang IS NULL THEN '(无)' + ELSE CASE users.lang + WHEN 'en' THEN '英文' + WHEN 'zh-tw' THEN '繁体中文' + WHEN 'zh-cn' THEN '简体中文' + WHEN 'ja' THEN '日文' + WHEN 'de' THEN '德文' + WHEN 'es' THEN '西班牙文' + ELSE users.lang + END + END AS lang, + users.visits AS visits, + CASE WHEN users.visited IS NULL THEN '(无)' + ELSE to_char(users.visited, 'YYYY-MM-DD HH:MI:SS') + END AS visited, + CASE WHEN users.ip IS NULL THEN '(无)' + ELSE host(users.ip) + END AS ip, + CASE WHEN users.host IS NULL THEN '(无)' + ELSE users.host + END AS host, + CASE WHEN users.ct IS NULL THEN '(无)' + ELSE ct.name_en + END AS ct, + to_char(users.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(users.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM users + LEFT JOIN country AS ct ON users.ct = ct.id + LEFT JOIN users AS createdby ON users.createdby = createdby.sn + LEFT JOIN users AS updatedby ON users.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON users_list_zhcn TO nobody; + +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (923153018, 'imacat', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '依瑪貓', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (460376330, 'mandy', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '小招', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (723676436, 'guestbook', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '留言本', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); + +-- +-- Fixing the country table +-- + +ALTER TABLE country ADD FOREIGN KEY (createdby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +ALTER TABLE country ADD FOREIGN KEY (updatedby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +CREATE VIEW country_list_en AS + SELECT + country.sn AS sn, + country.id AS id, + country.name_en AS title, + CASE WHEN country.special THEN 'Special' + ELSE '' + END AS special, + to_char(country.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(country.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM country + LEFT JOIN users AS createdby ON country.createdby = createdby.sn + LEFT JOIN users AS updatedby ON country.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON country_list_en TO nobody; +CREATE VIEW country_list_zhtw AS + SELECT + country.sn AS sn, + country.id AS id, + COALESCE(country.name_zhtw, country.name_en) AS title, + CASE WHEN country.special THEN '特殊' + ELSE '' + END AS special, + to_char(country.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(country.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM country + LEFT JOIN users AS createdby ON country.createdby = createdby.sn + LEFT JOIN users AS updatedby ON country.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON country_list_zhtw TO nobody; +CREATE VIEW country_list_zhcn AS + SELECT + country.sn AS sn, + country.id AS id, + COALESCE(country.name_zhcn, country.name_en) AS title, + CASE WHEN country.special THEN '特殊' + ELSE '' + END AS special, + to_char(country.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(country.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM country + LEFT JOIN users AS createdby ON country.createdby = createdby.sn + LEFT JOIN users AS updatedby ON country.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON country_list_zhcn TO nobody; + + +-- +-- Table structure for table "groups" +-- + +CREATE TABLE groups ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(16) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + dsc_zhtw varchar(64) NOT NULL CHECK (dsc_zhtw != ''), + dsc_en varchar(64) CHECK (dsc_en IS NULL OR dsc_en != ''), + dsc_zhcn varchar(64) CHECK (dsc_zhcn IS NULL OR dsc_zhcn != ''), + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groups TO nobody; + +CREATE VIEW groups_list_zhtw AS + SELECT + groups.sn AS sn, + groups.id AS id, + groups.dsc_zhtw AS dsc, + to_char(groups.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groups.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groups + LEFT JOIN users AS createdby ON groups.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groups.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON groups_list_zhtw TO nobody; +CREATE VIEW groups_list_en AS + SELECT + groups.sn AS sn, + groups.id AS id, + COALESCE(groups.dsc_en, groups.dsc_zhtw) AS dsc, + to_char(groups.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groups.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groups + LEFT JOIN users AS createdby ON groups.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groups.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON groups_list_en TO nobody; +CREATE VIEW groups_list_zhcn AS + SELECT + groups.sn AS sn, + groups.id AS id, + COALESCE(groups.dsc_zhcn, groups.dsc_zhtw) AS dsc, + to_char(groups.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groups.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groups + LEFT JOIN users AS createdby ON groups.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groups.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON groups_list_zhcn TO nobody; + +-- INSERT INTO groups (sn, id, dsc_en, dsc_zhtw, created, createdby, updated, updatedby) VALUES (553229108, 'root', 'Super Users', '總管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc_en, dsc_zhtw, created, createdby, updated, updatedby) VALUES (802339805, 'guests', 'Anonymous Guests', '暱名訪客', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc_en, dsc_zhtw, created, createdby, updated, updatedby) VALUES (958210993, 'users', 'All Logged-in Users', '已登入使用者', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc_en, dsc_zhtw, created, createdby, updated, updatedby) VALUES (329685674, 'admin', 'All Administrators', '所有網站管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc_en, dsc_zhtw, created, createdby, updated, updatedby) VALUES (157696540, 'acctman', 'Account Manager', '帳號管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc_en, dsc_zhtw, created, createdby, updated, updatedby) VALUES (390105230, 'editor', 'Website Editors', '網站編輯', now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "usermem" +-- + +CREATE TABLE usermem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON usermem TO nobody; + +CREATE VIEW usermem_list_zhtw AS + SELECT + usermem.sn AS sn, + groups.id || ' (' || groups.dsc_zhtw || ')' AS grp, + members.id || ' (' || members.name || ')' AS member, + to_char(usermem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(usermem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM usermem + LEFT JOIN groups ON usermem.grp = groups.sn + LEFT JOIN users AS members ON usermem.member = members.sn + LEFT JOIN users AS createdby ON usermem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON usermem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON usermem_list_zhtw TO nobody; +CREATE VIEW usermem_list_en AS + SELECT + usermem.sn AS sn, + groups.id || ' (' || COALESCE(groups.dsc_en, groups.dsc_zhtw) || ')' AS grp, + members.id || ' (' || members.name || ')' AS member, + to_char(usermem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(usermem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM usermem + LEFT JOIN groups ON usermem.grp = groups.sn + LEFT JOIN users AS members ON usermem.member = members.sn + LEFT JOIN users AS createdby ON usermem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON usermem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON usermem_list_en TO nobody; +CREATE VIEW usermem_list_zhcn AS + SELECT + usermem.sn AS sn, + groups.id || ' (' || COALESCE(groups.dsc_zhcn, groups.dsc_zhtw) || ')' AS grp, + members.id || ' (' || members.name || ')' AS member, + to_char(usermem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(usermem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM usermem + LEFT JOIN groups ON usermem.grp = groups.sn + LEFT JOIN users AS members ON usermem.member = members.sn + LEFT JOIN users AS createdby ON usermem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON usermem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON usermem_list_zhcn TO nobody; + +-- INSERT INTO usermem (sn, grp, member, created, createdby, updated, updatedby) VALUES (593684712, 553229108, 923153018, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "groupmem" +-- + +CREATE TABLE groupmem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE CHECK (member != grp), + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groupmem TO nobody; + +CREATE VIEW groupmem_list_zhtw AS + SELECT + groupmem.sn AS sn, + groups.id || ' (' || groups.dsc_zhtw || ')' AS grp, + members.id || ' (' || members.dsc_zhtw || ')' AS member, + to_char(groupmem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groupmem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groupmem + LEFT JOIN groups ON groupmem.grp = groups.sn + LEFT JOIN groups AS members ON groupmem.member = members.sn + LEFT JOIN users AS createdby ON groupmem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groupmem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON groupmem_list_zhtw TO nobody; +CREATE VIEW groupmem_list_en AS + SELECT + groupmem.sn AS sn, + groups.id || ' (' || COALESCE(groups.dsc_en, groups.dsc_zhtw) || ')' AS grp, + members.id || ' (' || COALESCE(members.dsc_en, members.dsc_zhtw) || ')' AS member, + to_char(groupmem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groupmem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groupmem + LEFT JOIN groups ON groupmem.grp = groups.sn + LEFT JOIN groups AS members ON groupmem.member = members.sn + LEFT JOIN users AS createdby ON groupmem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groupmem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON groupmem_list_en TO nobody; +CREATE VIEW groupmem_list_zhcn AS + SELECT + groupmem.sn AS sn, + groups.id || ' (' || COALESCE(groups.dsc_zhcn, groups.dsc_zhtw) || ')' AS grp, + members.id || ' (' || COALESCE(members.dsc_zhcn, members.dsc_zhtw) || ')' AS member, + to_char(groupmem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groupmem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groupmem + LEFT JOIN groups ON groupmem.grp = groups.sn + LEFT JOIN groups AS members ON groupmem.member = members.sn + LEFT JOIN users AS createdby ON groupmem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groupmem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON groupmem_list_zhcn TO nobody; + +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (569742102, 329685674, 157696540, now(), 923153018, now(), 923153018); +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (859385977, 329685674, 390105230, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "scptpriv" +-- + +CREATE TABLE scptpriv ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + script varchar(64) NOT NULL CHECK (script != ''), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (script, grp) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON scptpriv TO nobody; + +CREATE VIEW scptpriv_list_zhtw AS + SELECT + scptpriv.sn AS sn, + scptpriv.script AS script, + groups.dsc_zhtw AS grp, + to_char(scptpriv.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(scptpriv.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM scptpriv + LEFT JOIN groups ON scptpriv.grp = groups.sn + LEFT JOIN users AS createdby ON scptpriv.createdby = createdby.sn + LEFT JOIN users AS updatedby ON scptpriv.updatedby = updatedby.sn + ORDER BY script, grp; +GRANT SELECT ON scptpriv_list_zhtw TO nobody; +CREATE VIEW scptpriv_list_en AS + SELECT + scptpriv.sn AS sn, + scptpriv.script AS script, + COALESCE(groups.dsc_en, groups.dsc_zhtw) AS grp, + to_char(scptpriv.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(scptpriv.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM scptpriv + LEFT JOIN groups ON scptpriv.grp = groups.sn + LEFT JOIN users AS createdby ON scptpriv.createdby = createdby.sn + LEFT JOIN users AS updatedby ON scptpriv.updatedby = updatedby.sn + ORDER BY script, grp; +GRANT SELECT ON scptpriv_list_en TO nobody; +CREATE VIEW scptpriv_list_zhcn AS + SELECT + scptpriv.sn AS sn, + scptpriv.script AS script, + COALESCE(groups.dsc_zhcn, groups.dsc_zhtw) AS grp, + to_char(scptpriv.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(scptpriv.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM scptpriv + LEFT JOIN groups ON scptpriv.grp = groups.sn + LEFT JOIN users AS createdby ON scptpriv.createdby = createdby.sn + LEFT JOIN users AS updatedby ON scptpriv.updatedby = updatedby.sn + ORDER BY script, grp; +GRANT SELECT ON scptpriv_list_zhcn TO nobody; + + +-- +-- Table structure for table "userpref" +-- + +CREATE TABLE userpref ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + usr int REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + domain varchar(64) CHECK (domain IS NULL OR domain != ''), + name varchar(16) NOT NULL CHECK (name != ''), + value varchar(255) NOT NULL, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (usr, domain, name) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON userpref TO nobody; + +CREATE VIEW userpref_list_zhtw AS + SELECT + userpref.sn AS sn, + CASE WHEN userpref.usr IS NOT NULL THEN users.name + ELSE '所有人' + END AS usr, + CASE WHEN userpref.domain IS NOT NULL THEN userpref.domain + ELSE '所有地方' + END AS domain, + userpref.name AS name, + userpref.value AS value, + to_char(userpref.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(userpref.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM userpref LEFT JOIN users ON userpref.usr = users.sn + LEFT JOIN users AS createdby ON userpref.createdby = createdby.sn + LEFT JOIN users AS updatedby ON userpref.updatedby = updatedby.sn + ORDER BY domain, usr, name; +GRANT SELECT ON userpref_list_zhtw TO nobody; +CREATE VIEW userpref_list_en AS + SELECT + userpref.sn AS sn, + CASE WHEN userpref.usr IS NOT NULL THEN users.name + ELSE 'Everyone' + END AS usr, + CASE WHEN userpref.domain IS NOT NULL THEN userpref.domain + ELSE 'Everywhere' + END AS domain, + userpref.name AS name, + userpref.value AS value, + to_char(userpref.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(userpref.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM userpref + LEFT JOIN users ON userpref.usr = users.sn + LEFT JOIN users AS createdby ON userpref.createdby = createdby.sn + LEFT JOIN users AS updatedby ON userpref.updatedby = updatedby.sn + ORDER BY domain, usr, name; +GRANT SELECT ON userpref_list_en TO nobody; +CREATE VIEW userpref_list_zhcn AS + SELECT + userpref.sn AS sn, + CASE WHEN userpref.usr IS NOT NULL THEN users.name + ELSE '所有人' + END AS usr, + CASE WHEN userpref.domain IS NOT NULL THEN userpref.domain + ELSE '所有地方' + END AS domain, + userpref.name AS name, + userpref.value AS value, + to_char(userpref.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(userpref.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM userpref + LEFT JOIN users ON userpref.usr = users.sn + LEFT JOIN users AS createdby ON userpref.createdby = createdby.sn + LEFT JOIN users AS updatedby ON userpref.updatedby = updatedby.sn + ORDER BY domain, usr, name; +GRANT SELECT ON userpref_list_zhcn TO nobody; + + +-- +-- Function definitions for table "guestbook" +-- + +-- integer guestbook_oldlen(date timestamp with time zone, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp with time zone, updatedby_arg integer) +CREATE FUNCTION guestbook_oldlen(date timestamp with time zone, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp with time zone, updatedby_arg integer) RETURNS integer AS ' + DECLARE + row record; + len integer; + BEGIN + -- : 19, sn: 30 + 1, date: 54 + 1 + len := 105; + len := len + octet_length(host(ip)) + 22; + IF hostname IS NOT NULL THEN + len := len + octet_length(hostname) + 24; + END IF; + IF name IS NOT NULL THEN + len := len + octet_length(eschtml(name)) + 24; + END IF; + IF identity IS NOT NULL THEN + len := len + octet_length(eschtml(identity)) + 28; + END IF; + IF location IS NOT NULL THEN + len := len + octet_length(eschtml(location)) + 28; + END IF; + IF email IS NOT NULL THEN + len := len + octet_length(eschtml(email)) + 25; + END IF; + IF url IS NOT NULL THEN + len := len + octet_length(eschtml(url)) + 23; + END IF; + IF message IS NOT NULL THEN + len := len + octet_length(eschtml(message)) + 27; + END IF; + IF updated != date THEN + len := len + 58; + IF updatedby_arg = 923153018 THEN + len := len + 35; + ELSIF updatedby_arg = 460376330 THEN + len := len + 34; + ELSE + SELECT INTO row name FROM users WHERE sn=updatedby_arg; + len := len + octet_length(row.name) + 29; + END IF; + END IF; + RETURN len; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(date timestamp with time zone, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp with time zone, updatedby_arg integer) TO nobody; +-- integer guestbook_oldlen(sn_arg integer) +CREATE FUNCTION guestbook_oldlen(sn_arg integer) RETURNS integer AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM guestbook WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN guestbook_oldlen(row.created, row.ip, row.host, row.name, row.identity, row.location, row.email, row.url, row.message, row.updated, row.updatedby); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(sn_arg integer) TO nobody; + + +-- +-- Table structure for table "guestbook" +-- + +CREATE TABLE guestbook ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + name varchar(32) CHECK (name IS NULL OR name != ''), + identity varchar(64) CHECK (identity IS NULL OR identity != ''), + location varchar(64) CHECK (location IS NULL OR location != ''), + email varchar(64) CHECK (email IS NULL OR email != ''), + url varchar(128) CHECK (url IS NULL OR (url != '' AND url != 'http://')), + message text NOT NULL CHECK (message != ''), + hid boolean NOT NULL DEFAULT FALSE, + lang varchar(5) CHECK (lang IS NULL OR lang = 'zh-tw' OR lang='zh-cn'), + ip inet NOT NULL, + host varchar(255) CHECK (host IS NULL OR host != ''), + ct char(2) NOT NULL REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + pageno int NOT NULL, + oldpageno int, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON guestbook TO nobody; + +CREATE VIEW guestbook_list_zhtw AS + SELECT + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS _viewurl, + guestbook.sn AS sn, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + COALESCE(guestbook.name, '(未設定)') AS name, + COALESCE(guestbook.identity, '(未設定)') AS identity, + COALESCE(guestbook.location, '(未設定)') AS location, + COALESCE(guestbook.email, '(未設定)') AS email, + COALESCE(guestbook.url, '(未設定)') AS url, + guestbook.message AS message, + CASE WHEN guestbook.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + CASE WHEN guestbook.lang IS NULL THEN NULL + ELSE CASE guestbook.lang + WHEN 'zh-tw' THEN '繁體中文' + WHEN 'zh-cn' THEN '簡體中文' + ELSE guestbook.lang + END + END AS lang, + host(guestbook.ip) AS ip, + COALESCE(guestbook.host, '(不可考)') AS host, + COALESCE(country.name_zhtw, country.name_en) AS ct, + guestbook.pageno AS pageno, + guestbook.oldpageno AS oldpageno, + to_char(guestbook.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(guestbook.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM guestbook + LEFT JOIN country ON guestbook.ct = country.id + LEFT JOIN users AS createdby ON guestbook.createdby = createdby.sn + LEFT JOIN users AS updatedby ON guestbook.updatedby = updatedby.sn + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_list_zhtw TO nobody; +CREATE VIEW guestbook_list_en AS + SELECT + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS _viewurl, + guestbook.sn AS sn, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + COALESCE(guestbook.name, '(not set)') AS name, + COALESCE(guestbook.identity, '(not set)') AS identity, + COALESCE(guestbook.location, '(not set)') AS location, + COALESCE(guestbook.email, '(not set)') AS email, + COALESCE(guestbook.url, '(not set)') AS url, + guestbook.message AS message, + CASE WHEN guestbook.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + CASE WHEN guestbook.lang IS NULL THEN NULL + ELSE CASE guestbook.lang + WHEN 'zh-tw' THEN 'Traditional Chinese' + WHEN 'zh-cn' THEN 'Simplified Chinese' + ELSE guestbook.lang + END + END AS lang, + host(guestbook.ip) AS ip, + COALESCE(guestbook.host, '(N/A)') AS host, + country.name_en AS ct, + guestbook.pageno AS pageno, + guestbook.oldpageno AS oldpageno, + to_char(guestbook.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(guestbook.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM guestbook + LEFT JOIN country ON guestbook.ct = country.id + LEFT JOIN users AS createdby ON guestbook.createdby = createdby.sn + LEFT JOIN users AS updatedby ON guestbook.updatedby = updatedby.sn + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_list_en TO nobody; +CREATE VIEW guestbook_list_zhcn AS + SELECT + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS _viewurl, + guestbook.sn AS sn, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + COALESCE(guestbook.name, '(未设定)') AS name, + COALESCE(guestbook.identity, '(未设定)') AS identity, + COALESCE(guestbook.location, '(未设定)') AS location, + COALESCE(guestbook.email, '(未设定)') AS email, + COALESCE(guestbook.url, '(未设定)') AS url, + guestbook.message AS message, + CASE WHEN guestbook.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + CASE WHEN guestbook.lang IS NULL THEN NULL + ELSE CASE guestbook.lang + WHEN 'zh-tw' THEN '繁体中文' + WHEN 'zh-cn' THEN '简体中文' + ELSE guestbook.lang + END + END AS lang, + host(guestbook.ip) AS ip, + COALESCE(guestbook.host, '(不可考)') AS host, + COALESCE(country.name_zhcn, country.name_en) AS ct, + guestbook.pageno AS pageno, + guestbook.oldpageno AS oldpageno, + to_char(guestbook.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(guestbook.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM guestbook + LEFT JOIN country ON guestbook.ct = country.id + LEFT JOIN users AS createdby ON guestbook.createdby = createdby.sn + LEFT JOIN users AS updatedby ON guestbook.updatedby = updatedby.sn + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_list_zhcn TO nobody; + +CREATE VIEW guestbook_public AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + name AS name, + identity AS identity, + location AS location, + email AS email, + url AS url, + message AS message, + lang AS lang, + pageno AS pageno, + oldpageno AS oldpageno + FROM guestbook + WHERE NOT hid + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_public TO nobody; + + +-- +-- Function definitions for table "garbage" +-- + +-- integer garbage_oldlen(date timestamp with time zone, ip inet, hostname text, message text, updated timestamp with time zone, updatedby_arg integer) +CREATE FUNCTION garbage_oldlen(date timestamp with time zone, ip inet, hostname text, message text, updated timestamp with time zone, updatedby_arg integer) RETURNS integer AS ' + DECLARE + row record; + len integer; + BEGIN + -- : 19, sn: 30 + 1, date: 54 + 1 + len := 105; + len := len + octet_length(host(ip)) + 22; + IF hostname IS NOT NULL THEN + len := len + octet_length(hostname) + 24; + END IF; + IF message IS NOT NULL THEN + len := len + octet_length(eschtml(message)) + 27; + END IF; + IF updated != date THEN + len := len + 58; + IF updatedby_arg = 923153018 THEN + len := len + 35; + ELSIF updatedby_arg = 460376330 THEN + len := len + 34; + ELSE + SELECT INTO row name FROM users WHERE sn=updatedby_arg; + len := len + octet_length(row.name) + 29; + END IF; + END IF; + RETURN len; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION garbage_oldlen(date timestamp with time zone, ip inet, hostname text, message text, updated timestamp with time zone, updatedby_arg integer) TO nobody; +-- integer garbage_oldlen(sn_arg integer) +CREATE FUNCTION garbage_oldlen(sn_arg integer) RETURNS integer AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM garbage WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN garbage_oldlen(row.created, row.ip, row.host, row.message, row.updated, row.updatedby); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION garbage_oldlen(sn_arg integer) TO nobody; + + +-- +-- Table structure for table "garbage" +-- + +CREATE TABLE garbage ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + message text NOT NULL CHECK (message != ''), + hid boolean NOT NULL DEFAULT FALSE, + ip inet NOT NULL, + host varchar(255) CHECK (host IS NULL OR host != ''), + ct char(2) NOT NULL REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + pageno int NOT NULL, + oldpageno int, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON garbage TO nobody; + +CREATE VIEW garbage_list_zhtw AS + SELECT + '/cgi-bin/garbage.cgi?pageno=' || garbage.pageno + || '#msg' || garbage.sn + AS _viewurl, + garbage.sn AS sn, + to_char(garbage.created, 'YYYY-MM-DD') AS date, + garbage.message AS message, + CASE WHEN garbage.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + host(garbage.ip) AS ip, + COALESCE(garbage.host, '(不可考)') AS host, + COALESCE(country.name_zhtw, country.name_en) AS ct, + garbage.pageno AS pageno, + garbage.oldpageno AS oldpageno, + to_char(garbage.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(garbage.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM garbage + LEFT JOIN country ON garbage.ct = country.id + LEFT JOIN users AS createdby ON garbage.createdby = createdby.sn + LEFT JOIN users AS updatedby ON garbage.updatedby = updatedby.sn + ORDER BY garbage.created DESC; +GRANT SELECT ON garbage_list_zhtw TO nobody; +CREATE VIEW garbage_list_en AS + SELECT + '/cgi-bin/garbage.cgi?pageno=' || garbage.pageno + || '#msg' || garbage.sn + AS _viewurl, + garbage.sn AS sn, + to_char(garbage.created, 'YYYY-MM-DD') AS date, + garbage.message AS message, + CASE WHEN garbage.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + host(garbage.ip) AS ip, + COALESCE(garbage.host, '(N/A)') AS host, + country.name_en AS ct, + garbage.pageno AS pageno, + garbage.oldpageno AS oldpageno, + to_char(garbage.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(garbage.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM garbage + LEFT JOIN country ON garbage.ct = country.id + LEFT JOIN users AS createdby ON garbage.createdby = createdby.sn + LEFT JOIN users AS updatedby ON garbage.updatedby = updatedby.sn + ORDER BY garbage.created DESC; +GRANT SELECT ON garbage_list_en TO nobody; +CREATE VIEW garbage_list_zhcn AS + SELECT + '/cgi-bin/garbage.cgi?pageno=' || garbage.pageno + || '#msg' || garbage.sn + AS _viewurl, + garbage.sn AS sn, + to_char(garbage.created, 'YYYY-MM-DD') AS date, + garbage.message AS message, + CASE WHEN garbage.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + host(garbage.ip) AS ip, + COALESCE(garbage.host, '(不可考)') AS host, + COALESCE(country.name_zhcn, country.name_en) AS ct, + garbage.pageno AS pageno, + garbage.oldpageno AS oldpageno, + to_char(garbage.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(garbage.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM garbage + LEFT JOIN country ON garbage.ct = country.id + LEFT JOIN users AS createdby ON garbage.createdby = createdby.sn + LEFT JOIN users AS updatedby ON garbage.updatedby = updatedby.sn + ORDER BY garbage.created DESC; +GRANT SELECT ON garbage_list_zhcn TO nobody; + +CREATE VIEW garbage_public AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + message AS message, + pageno AS pageno, + oldpageno AS oldpageno + FROM garbage + WHERE NOT hid + ORDER BY garbage.created DESC; +GRANT SELECT ON garbage_public TO nobody; + + +-- +-- Table structure for table "pages" +-- + +CREATE TABLE pages ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + path varchar(64) NOT NULL UNIQUE CHECK (path != ''), + ord smallint NOT NULL DEFAULT 5000 CHECK (ord >= 0 AND ord < 10000), + title_zhtw varchar(128) NOT NULL CHECK (title_zhtw != ''), + body_zhtw text NOT NULL CHECK (body_zhtw != ''), + kw_zhtw varchar(128) NOT NULL CHECK (kw_zhtw != ''), + title_en varchar(128) CHECK (title_en IS NULL OR title_en != ''), + body_en text CHECK ((title_en IS NULL AND body_en IS NULL) OR (title_en IS NOT NULL AND body_en IS NOT NULL AND body_en != '')), + kw_en varchar(128) CHECK ((title_en IS NULL AND kw_en IS NULL) OR (title_en IS NOT NULL AND kw_en IS NOT NULL AND kw_en != '')), + title_zhcn varchar(128) CHECK (title_zhcn IS NULL OR title_zhcn != ''), + body_zhcn text CHECK ((title_zhcn IS NULL AND body_zhcn IS NULL) OR (title_zhcn IS NOT NULL AND body_zhcn IS NOT NULL AND body_zhcn != '')), + kw_zhcn varchar(128) CHECK ((title_zhcn IS NULL AND kw_zhcn IS NULL) OR (title_zhcn IS NOT NULL AND kw_zhcn IS NOT NULL AND kw_zhcn != '')), + class varchar(8) CHECK (class IS NULL OR class != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pages TO nobody; + +CREATE VIEW pages_list_zhtw AS + SELECT + pages.path AS _viewurl, + pages.sn AS sn, + pages.path AS path, + pages.ord AS ord, + pages.title_zhtw AS title, + pages.body_zhtw AS body, + pages.kw_zhtw AS kw, + pages.class AS class, + CASE WHEN pages.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN pages.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(pages.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pages.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pages + LEFT JOIN users AS createdby ON pages.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pages.updatedby = updatedby.sn + ORDER BY path; +GRANT SELECT ON pages_list_zhtw TO nobody; +CREATE VIEW pages_list_en AS + SELECT + pages.path AS _viewurl, + pages.sn AS sn, + pages.path AS path, + pages.ord AS ord, + COALESCE(pages.title_en, pages.title_zhtw) AS title, + COALESCE(pages.body_en, pages.body_zhtw) AS body, + COALESCE(pages.kw_en, pages.kw_zhtw) AS kw, + pages.class AS class, + CASE WHEN pages.html THEN 'HTML' + ELSE 'Plain text' + END AS html, + CASE WHEN pages.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + to_char(pages.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pages.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pages + LEFT JOIN users AS createdby ON pages.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pages.updatedby = updatedby.sn + ORDER BY path; +GRANT SELECT ON pages_list_en TO nobody; +CREATE VIEW pages_list_zhcn AS + SELECT + pages.path AS _viewurl, + pages.sn AS sn, + pages.path AS path, + pages.ord AS ord, + COALESCE(pages.title_zhcn, pages.title_zhtw) AS title, + COALESCE(pages.body_zhcn, pages.body_zhtw) AS body, + COALESCE(pages.kw_zhcn, pages.kw_zhtw) AS kw, + pages.class AS class, + CASE WHEN pages.html THEN 'HTML' + ELSE '纯文字' + END AS html, + CASE WHEN pages.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + to_char(pages.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pages.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pages + LEFT JOIN users AS createdby ON pages.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pages.updatedby = updatedby.sn + ORDER BY path; +GRANT SELECT ON pages_list_zhcn TO nobody; + + +-- +-- Function definitions for table "links" +-- + +-- boolean linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer); +CREATE FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) RETURNS boolean AS ' + BEGIN + IF parent_arg IS NULL THEN + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent IS NULL; + RETURN NOT FOUND; + ELSE + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent=parent_arg; + RETURN NOT FOUND; + END IF; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) TO nobody; + +-- numeric linkcat_fullord(parent_arg integer, ord_arg integer); +CREATE FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) RETURNS numeric AS ' + DECLARE + row record; + sn_loop integer; + ord_loop numeric; + BEGIN + sn_loop := parent_arg; + ord_loop := ord_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, ord FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN NULL; + END IF; + sn_loop := row.parent; + ord_loop := row.ord + ord_loop / 100; + END LOOP; + RETURN ord_loop; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) TO nobody; +-- numeric linkcat_fullord(sn_arg integer); +CREATE FUNCTION linkcat_fullord(sn_arg integer) RETURNS numeric AS ' + BEGIN + RETURN linkcat_fullord(sn_arg, 0); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(sn_arg integer) TO nobody; + +-- boolean linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + -- Check if we have childs + PERFORM links.sn FROM links + INNER JOIN linkcatz ON linkcatz.link=links.sn + WHERE NOT links.hid AND linkcatz.cat=sn_arg; + IF FOUND THEN + RETURN TRUE; + END IF; + -- Check if we have shown child categories + PERFORM sn FROM linkcat WHERE parent=sn_arg AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + RETURN TRUE; + END IF; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; +-- boolean linkcat_isshown(sn_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer) RETURNS boolean AS ' + DECLARE + row record; + BEGIN + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_isshown(sn_arg, row.hid, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer) TO nobody; +-- boolean linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + RETURN TRUE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; + +-- text linkcat_path(sn_arg integer, id_arg text, parent_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + path text; + BEGIN + PERFORM sn FROM linkcat + WHERE parent=sn_arg + AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + path := ''/'' || id_arg || ''/''; + ELSE + path := ''/'' || id_arg || ''.html''; + END IF; + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_loop; + path := ''/'' || row.id || path; + sn_loop := row.parent; + END LOOP; + RETURN path; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) TO nobody; +-- text linkcat_path(sn_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_path(sn_arg, row.id, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer) TO nobody; + +-- boolean linkcat_ischild(parent_arg integer, child_arg integer); +CREATE FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + sn_loop := child_arg; + WHILE sn_loop IS NOT NULL LOOP + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + SELECT INTO row parent FROM public.linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN FALSE; + END IF; + IF row.parent = parent_arg THEN + RETURN TRUE; + END IF; + sn_loop := row.parent; + END LOOP; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) TO nobody; + +-- text linkcat_fulltitle(lang_arg text, sn_arg integer); +CREATE FUNCTION linkcat_fulltitle(lang_arg text, sn_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + title_full text; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + title_full := CASE lang_arg + WHEN ''en'' THEN COALESCE(row.title_en, row.title_zhtw) + ELSE row.title_zhtw + END; + WHILE row.parent IS NOT NULL LOOP + sn_loop := row.parent; + SELECT INTO row * FROM linkcat WHERE sn=sn_loop; + title_full := CASE lang_arg + WHEN ''en'' THEN COALESCE(row.title_en, row.title_zhtw) + ELSE row.title_zhtw + END || '' / '' || title_full; + END LOOP; + RETURN title_full; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(lang_arg text, sn_arg integer) TO nobody; +-- text linkcat_fulltitle(lang_arg text, parent_arg integer, title_arg text); +CREATE FUNCTION linkcat_fulltitle(lang_arg text, parent_arg integer, title_arg text) RETURNS text AS ' + BEGIN + IF parent_arg IS NULL THEN + RETURN title_arg; + END IF; + RETURN linkcat_fulltitle(lang_arg, parent_arg) || '' / '' || title_arg; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(lang_arg text, parent_arg integer, title_arg text) TO nobody; + + +-- +-- Table structure for table "linkcat" +-- + +CREATE TABLE linkcat ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + parent int REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE CHECK (parent IS NULL OR (parent != sn AND NOT linkcat_ischild(sn, parent))), + id varchar(8) NOT NULL CHECK (char_length(id) >= 2 AND linkcat_id_unique(id, sn, parent)), + ord smallint NOT NULL DEFAULT 50 CHECK (ord >= 0 AND ord < 100), + title_zhtw varchar(128) NOT NULL CHECK (title_zhtw != ''), + kw_zhtw varchar(128) NOT NULL CHECK (kw_zhtw != ''), + title_en varchar(128) CHECK (title_en IS NULL OR title_en != ''), + kw_en varchar(128) CHECK ((title_en IS NULL AND kw_en IS NULL) OR (title_en IS NOT NULL AND kw_en IS NOT NULL AND kw_en != '')), + title_zhcn varchar(128) CHECK (title_zhcn IS NULL OR title_zhcn != ''), + kw_zhcn varchar(128) CHECK ((title_zhcn IS NULL AND kw_zhcn IS NULL) OR (title_zhcn IS NOT NULL AND kw_zhcn IS NOT NULL AND kw_zhcn != '')), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcat TO nobody; + +CREATE VIEW linkcat_list_zhtw AS + SELECT + '/links' || linkcat_path(linkcat.sn, linkcat.id, linkcat.parent) || '.zh-tw' AS _viewurl, + linkcat.sn AS sn, + linkcat.id AS id, + linkcat.ord AS ord, + linkcat_fulltitle('zh-tw', linkcat.parent, linkcat.title_zhtw) AS title, + linkcat.kw_zhtw AS kw, + CASE WHEN linkcat.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(linkcat.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcat.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcat + LEFT JOIN users AS createdby ON linkcat.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcat.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), id; +GRANT SELECT ON linkcat_list_zhtw TO nobody; +CREATE VIEW linkcat_list_en AS + SELECT + '/links' || linkcat_path(linkcat.sn, linkcat.id, linkcat.parent) || '.en' AS _viewurl, + linkcat.sn AS sn, + linkcat.id AS id, + linkcat.ord AS ord, + linkcat_fulltitle('en', linkcat.parent, COALESCE(linkcat.title_en, linkcat.title_zhtw)) AS title, + COALESCE(linkcat.kw_en, linkcat.kw_zhtw) AS kw, + CASE WHEN linkcat.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + to_char(linkcat.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcat.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcat + LEFT JOIN users AS createdby ON linkcat.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcat.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), id; +GRANT SELECT ON linkcat_list_en TO nobody; +CREATE VIEW linkcat_list_zhcn AS + SELECT + '/links' || linkcat_path(linkcat.sn, linkcat.id, linkcat.parent) || '.zh-cn' AS _viewurl, + linkcat.sn AS sn, + linkcat.id AS id, + linkcat.ord AS ord, + linkcat_fulltitle('zh-cn', linkcat.parent, COALESCE(linkcat.title_zhcn, linkcat.title_zhtw)) AS title, + COALESCE(linkcat.kw_zhcn, linkcat.kw_zhtw) AS kw, + CASE WHEN linkcat.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + to_char(linkcat.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcat.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcat + LEFT JOIN users AS createdby ON linkcat.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcat.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), id; +GRANT SELECT ON linkcat_list_zhcn TO nobody; + + +-- +-- Table structure for table "links" +-- + +CREATE TABLE links ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + title varchar(96) NOT NULL CHECK (title != ''), + title_2ln varchar(96) CHECK (title_2ln IS NULL OR title_2ln != ''), + url varchar(128) NOT NULL UNIQUE CHECK (url != '' AND url != 'http://'), + email varchar(64) CHECK (email IS NULL OR email != ''), + icon varchar(128) CHECK (icon IS NULL OR (icon != '' AND icon != 'http://')), + addr varchar(128) CHECK (addr IS NULL OR addr != ''), + tel varchar(48) CHECK (tel IS NULL OR tel != ''), + fax varchar(32) CHECK (fax IS NULL OR fax != ''), + dsc_zhtw varchar(256) NOT NULL CHECK (dsc_zhtw != ''), + dsc_en varchar(256) CHECK (dsc_en IS NULL OR dsc_en != ''), + dsc_zhcn varchar(256) CHECK (dsc_zhcn IS NULL OR dsc_zhcn != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON links TO nobody; + +CREATE VIEW links_list_zhtw AS + SELECT + links.url AS _viewurl, + links.sn AS sn, + links.title AS title, + links.title_2ln AS title_2ln, + links.url AS url, + links.url AS _urlcheck, + links.icon AS _imgsrc, + links.email AS email, + links.addr AS addr, + links.tel AS tel, + links.fax AS fax, + links.dsc_zhtw AS dsc, + CASE WHEN links.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(links.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(links.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM links + LEFT JOIN users AS createdby ON links.createdby = createdby.sn + LEFT JOIN users AS updatedby ON links.updatedby = updatedby.sn + ORDER BY links.title; +GRANT SELECT ON links_list_zhtw TO nobody; +CREATE VIEW links_list_en AS + SELECT + links.url AS _viewurl, + links.sn AS sn, + links.title AS title, + links.title_2ln AS title_2ln, + links.url AS url, + links.url AS _urlcheck, + links.icon AS _imgsrc, + links.email AS email, + links.addr AS addr, + links.tel AS tel, + links.fax AS fax, + COALESCE(links.dsc_en, links.dsc_zhtw) AS dsc, + CASE WHEN links.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + to_char(links.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(links.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM links + LEFT JOIN users AS createdby ON links.createdby = createdby.sn + LEFT JOIN users AS updatedby ON links.updatedby = updatedby.sn + ORDER BY links.title; +GRANT SELECT ON links_list_en TO nobody; +CREATE VIEW links_list_zhcn AS + SELECT + links.url AS _viewurl, + links.sn AS sn, + links.title AS title, + links.title_2ln AS title_2ln, + links.url AS url, + links.url AS _urlcheck, + links.icon AS _imgsrc, + links.email AS email, + links.addr AS addr, + links.tel AS tel, + links.fax AS fax, + COALESCE(links.dsc_zhcn, links.dsc_zhtw) AS dsc, + CASE WHEN links.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + to_char(links.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(links.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM links + LEFT JOIN users AS createdby ON links.createdby = createdby.sn + LEFT JOIN users AS updatedby ON links.updatedby = updatedby.sn + ORDER BY links.title; +GRANT SELECT ON links_list_zhcn TO nobody; + + +-- +-- Table structure for table "linkcatz" +-- + +CREATE TABLE linkcatz ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + cat int NOT NULL REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE, + link int NOT NULL REFERENCES links ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (cat, link) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcatz TO nobody; + +CREATE VIEW linkcatz_list_zhtw AS + SELECT + linkcatz.sn AS sn, + linkcat_fulltitle('zh-tw', linkcat.parent, linkcat.title_zhtw) AS cat, + links.title AS link, + to_char(linkcatz.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcatz.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcatz + LEFT JOIN linkcat ON linkcatz.cat = linkcat.sn + LEFT JOIN links ON linkcatz.link = links.sn + LEFT JOIN users AS createdby ON linkcatz.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcatz.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), linkcat.id, link; +GRANT SELECT ON linkcatz_list_zhtw TO nobody; +CREATE VIEW linkcatz_list_en AS + SELECT + linkcatz.sn AS sn, + linkcat_fulltitle('en', linkcat.parent, COALESCE(linkcat.title_en, linkcat.title_zhtw)) AS cat, + links.title AS link, + to_char(linkcatz.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcatz.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcatz + LEFT JOIN linkcat ON linkcatz.cat = linkcat.sn + LEFT JOIN links ON linkcatz.link = links.sn + LEFT JOIN users AS createdby ON linkcatz.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcatz.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), linkcat.id, link; +GRANT SELECT ON linkcatz_list_en TO nobody; +CREATE VIEW linkcatz_list_zhcn AS + SELECT + linkcatz.sn AS sn, + linkcat_fulltitle('zh-cn', linkcat.parent, COALESCE(linkcat.title_zhcn, linkcat.title_zhtw)) AS cat, + links.title AS link, + to_char(linkcatz.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcatz.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcatz + LEFT JOIN linkcat ON linkcatz.cat = linkcat.sn + LEFT JOIN links ON linkcatz.link = links.sn + LEFT JOIN users AS createdby ON linkcatz.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcatz.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), linkcat.id, link; +GRANT SELECT ON linkcatz_list_zhcn TO nobody; + + +-- +-- Function definitions for table "diary" +-- + +-- timestamp with time zone diary_page_start(pageno_arg integer) +CREATE FUNCTION diary_page_start(pageno_arg integer) RETURNS timestamp with time zone AS ' + DECLARE + row record; + BEGIN + SELECT INTO row created FROM diary + WHERE NOT hid AND pageno=pageno_arg + ORDER BY created LIMIT 1; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.created; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION diary_page_start(pageno_arg integer) TO nobody; +-- timestamp with time zone diary_page_end(pageno_arg integer) +CREATE FUNCTION diary_page_end(pageno_arg integer) RETURNS timestamp with time zone AS ' + DECLARE + row record; + BEGIN + SELECT INTO row created FROM diary + WHERE NOT hid AND pageno=pageno_arg + ORDER BY created DESC LIMIT 1; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.created; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION diary_page_end(pageno_arg integer) TO nobody; + + +-- +-- Table structure for table "diary" +-- + +CREATE TABLE diary ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + body_zhtw text NOT NULL CHECK (body_zhtw != ''), + body_en text CHECK (body_en IS NULL OR body_en != ''), + body_zhcn text CHECK (body_zhcn IS NULL OR body_zhcn != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + pageno int NOT NULL, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON diary TO nobody; + +CREATE VIEW diary_list_zhtw AS + SELECT + '/me/diary/' || lpad(cast(diary.pageno AS text), 4, '0') || '.html' + || '#ent' || diary.sn + AS _viewurl, + diary.sn AS sn, + to_char(diary.created, 'YYYY-MM-DD') AS date, + diary.body_zhtw AS body, + CASE WHEN diary.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN diary.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + diary.pageno AS pageno, + to_char(diary.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(diary.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM diary + LEFT JOIN users AS createdby ON diary.createdby = createdby.sn + LEFT JOIN users AS updatedby ON diary.updatedby = updatedby.sn + ORDER BY diary.created DESC; +GRANT SELECT ON diary_list_zhtw TO nobody; +CREATE VIEW diary_list_en AS + SELECT + '/me/diary/' || lpad(cast(diary.pageno AS text), 4, '0') || '.html' + || '#ent' || diary.sn + AS _viewurl, + diary.sn AS sn, + to_char(diary.created, 'YYYY-MM-DD') AS date, + COALESCE(diary.body_en, diary.body_zhtw) AS body, + CASE WHEN diary.html THEN 'HTML' + ELSE 'Plain text' + END AS html, + CASE WHEN diary.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + diary.pageno AS pageno, + to_char(diary.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(diary.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM diary + LEFT JOIN users AS createdby ON diary.createdby = createdby.sn + LEFT JOIN users AS updatedby ON diary.updatedby = updatedby.sn + ORDER BY diary.created DESC; +GRANT SELECT ON diary_list_en TO nobody; +CREATE VIEW diary_list_zhcn AS + SELECT + '/me/diary/' || lpad(cast(diary.pageno AS text), 4, '0') || '.html' + || '#ent' || diary.sn + AS _viewurl, + diary.sn AS sn, + to_char(diary.created, 'YYYY-MM-DD') AS date, + COALESCE(diary.body_zhcn, diary.body_zhtw) AS body, + CASE WHEN diary.html THEN 'HTML' + ELSE '纯文字' + END AS html, + CASE WHEN diary.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + diary.pageno AS pageno, + to_char(diary.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(diary.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM diary + LEFT JOIN users AS createdby ON diary.createdby = createdby.sn + LEFT JOIN users AS updatedby ON diary.updatedby = updatedby.sn + ORDER BY diary.created DESC; +GRANT SELECT ON diary_list_zhcn TO nobody; + +CREATE VIEW diary_public_zhtw AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + body_zhtw AS body, + html AS html, + pageno AS pageno + FROM diary + WHERE NOT hid + ORDER BY created DESC; +GRANT SELECT ON diary_public_zhtw TO nobody; +CREATE VIEW diary_public_en AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + COALESCE(body_en, body_zhtw) AS body, + html AS html, + pageno AS pageno + FROM diary + WHERE NOT hid + ORDER BY created DESC; +GRANT SELECT ON diary_public_en TO nobody; +CREATE VIEW diary_public_zhcn AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + COALESCE(body_zhcn, body_zhtw) AS body, + html AS html, + pageno AS pageno + FROM diary + WHERE NOT hid + ORDER BY created DESC; +GRANT SELECT ON diary_public_zhcn TO nobody; + + +-- +-- Function definitions for table "changelog" +-- + +-- timestamp with time zone changelog_page_start(pageno_arg integer) +CREATE FUNCTION changelog_page_start(pageno_arg integer) RETURNS timestamp with time zone AS ' + DECLARE + row record; + BEGIN + SELECT INTO row created FROM changelog + WHERE NOT hid AND pageno=pageno_arg + ORDER BY created LIMIT 1; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.created; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION changelog_page_start(pageno_arg integer) TO nobody; +-- timestamp with time zone changelog_page_end(pageno_arg integer) +CREATE FUNCTION changelog_page_end(pageno_arg integer) RETURNS timestamp with time zone AS ' + DECLARE + row record; + BEGIN + SELECT INTO row created FROM changelog + WHERE NOT hid AND pageno=pageno_arg + ORDER BY created DESC LIMIT 1; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.created; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION changelog_page_end(pageno_arg integer) TO nobody; + + +-- +-- Table structure for table "changelog" +-- + +CREATE TABLE changelog ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + body_zhtw text NOT NULL CHECK (body_zhtw != ''), + body_en text CHECK (body_en IS NULL OR body_en != ''), + body_zhcn text CHECK (body_zhcn IS NULL OR body_zhcn != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + pageno int NOT NULL, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON changelog TO nobody; + +CREATE VIEW changelog_list_zhtw AS + SELECT + '/me/changelog/' || lpad(cast(changelog.pageno AS text), 4, '0') || '.html' + || '#ent' || changelog.sn + AS _viewurl, + changelog.sn AS sn, + to_char(changelog.created, 'YYYY-MM-DD') AS date, + changelog.body_zhtw AS body, + CASE WHEN changelog.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN changelog.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + changelog.pageno AS pageno, + to_char(changelog.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(changelog.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM changelog + LEFT JOIN users AS createdby ON changelog.createdby = createdby.sn + LEFT JOIN users AS updatedby ON changelog.updatedby = updatedby.sn + ORDER BY changelog.created DESC; +GRANT SELECT ON changelog_list_zhtw TO nobody; +CREATE VIEW changelog_list_en AS + SELECT + '/me/changelog/' || lpad(cast(changelog.pageno AS text), 4, '0') || '.html' + || '#ent' || changelog.sn + AS _viewurl, + changelog.sn AS sn, + to_char(changelog.created, 'YYYY-MM-DD') AS date, + COALESCE(changelog.body_en, changelog.body_zhtw) AS body, + CASE WHEN changelog.html THEN 'HTML' + ELSE 'Plain text' + END AS html, + CASE WHEN changelog.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + changelog.pageno AS pageno, + to_char(changelog.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(changelog.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM changelog + LEFT JOIN users AS createdby ON changelog.createdby = createdby.sn + LEFT JOIN users AS updatedby ON changelog.updatedby = updatedby.sn + ORDER BY changelog.created DESC; +GRANT SELECT ON changelog_list_en TO nobody; +CREATE VIEW changelog_list_zhcn AS + SELECT + '/me/changelog/' || lpad(cast(changelog.pageno AS text), 4, '0') || '.html' + || '#ent' || changelog.sn + AS _viewurl, + changelog.sn AS sn, + to_char(changelog.created, 'YYYY-MM-DD') AS date, + COALESCE(changelog.body_zhcn, changelog.body_zhtw) AS body, + CASE WHEN changelog.html THEN 'HTML' + ELSE '纯文字' + END AS html, + CASE WHEN changelog.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + changelog.pageno AS pageno, + to_char(changelog.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(changelog.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM changelog + LEFT JOIN users AS createdby ON changelog.createdby = createdby.sn + LEFT JOIN users AS updatedby ON changelog.updatedby = updatedby.sn + ORDER BY changelog.created DESC; +GRANT SELECT ON changelog_list_zhcn TO nobody; + +CREATE VIEW changelog_public_zhtw AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + body_zhtw AS body, + html AS html, + pageno AS pageno + FROM changelog + WHERE NOT hid + ORDER BY created DESC; +GRANT SELECT ON changelog_public_zhtw TO nobody; +CREATE VIEW changelog_public_en AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + COALESCE(body_en, body_zhtw) AS body, + html AS html, + pageno AS pageno + FROM changelog + WHERE NOT hid + ORDER BY created DESC; +GRANT SELECT ON changelog_public_en TO nobody; +CREATE VIEW changelog_public_zhcn AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + COALESCE(body_zhcn, body_zhtw) AS body, + html AS html, + pageno AS pageno + FROM changelog + WHERE NOT hid + ORDER BY created DESC; +GRANT SELECT ON changelog_public_zhcn TO nobody; + + +-- +-- Table structure for table "literalzh" +-- + +CREATE TABLE literalzh ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + date date NOT NULL UNIQUE DEFAULT CURRENT_DATE, + title varchar(16) CHECK (title IS NULL OR title != ''), + dsc varchar(256) NOT NULL CHECK (dsc != ''), + kw varchar(32) NOT NULL CHECK (kw != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON literalzh TO nobody; + +CREATE VIEW literalzh_list_zhtw AS + SELECT + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + AS _viewurl, + literalzh.sn AS sn, + to_char(literalzh.date, 'YYYY-MM-DD') AS date, + literalzh.title AS title, + literalzh.dsc AS dsc, + literalzh.kw AS kw, + CASE WHEN literalzh.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(literalzh.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(literalzh.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM literalzh + LEFT JOIN users AS createdby ON literalzh.createdby = createdby.sn + LEFT JOIN users AS updatedby ON literalzh.updatedby = updatedby.sn + ORDER BY literalzh.date DESC; +GRANT SELECT ON literalzh_list_zhtw TO nobody; +CREATE VIEW literalzh_list_en AS + SELECT + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + AS _viewurl, + literalzh.sn AS sn, + to_char(literalzh.date, 'YYYY-MM-DD') AS date, + literalzh.title AS title, + literalzh.dsc AS dsc, + literalzh.kw AS kw, + CASE WHEN literalzh.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + to_char(literalzh.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(literalzh.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM literalzh + LEFT JOIN users AS createdby ON literalzh.createdby = createdby.sn + LEFT JOIN users AS updatedby ON literalzh.updatedby = updatedby.sn + ORDER BY literalzh.date DESC; +GRANT SELECT ON literalzh_list_en TO nobody; +CREATE VIEW literalzh_list_zhcn AS + SELECT + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + AS _viewurl, + literalzh.sn AS sn, + to_char(literalzh.date, 'YYYY-MM-DD') AS date, + literalzh.title AS title, + literalzh.dsc AS dsc, + literalzh.kw AS kw, + CASE WHEN literalzh.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + to_char(literalzh.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(literalzh.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM literalzh + LEFT JOIN users AS createdby ON literalzh.createdby = createdby.sn + LEFT JOIN users AS updatedby ON literalzh.updatedby = updatedby.sn + ORDER BY literalzh.date DESC; +GRANT SELECT ON literalzh_list_zhcn TO nobody; + + +-- +-- Table structure for table "ltzhpoem" +-- + +CREATE TABLE ltzhpoem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + set int NOT NULL REFERENCES literalzh ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + title varchar(16) NOT NULL CHECK (title != ''), + body text NOT NULL CHECK (body != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON ltzhpoem TO nobody; + +CREATE VIEW ltzhpoem_list_zhtw AS + SELECT + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + || '#poem' || ltzhpoem.sn + AS _viewurl, + ltzhpoem.sn AS sn, + to_char(literalzh.date, 'YYYY-MM-DD') + || CASE WHEN literalzh.title IS NULL THEN '' ELSE ' ' || literalzh.title END + AS set, + ltzhpoem.ord AS ord, + ltzhpoem.title AS title, + ltzhpoem.body AS body, + CASE WHEN ltzhpoem.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(ltzhpoem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(ltzhpoem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM ltzhpoem + LEFT JOIN literalzh ON ltzhpoem.set=literalzh.sn + LEFT JOIN users AS createdby ON ltzhpoem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON ltzhpoem.updatedby = updatedby.sn + ORDER BY literalzh.date DESC, ltzhpoem.ord; +GRANT SELECT ON ltzhpoem_list_zhtw TO nobody; +CREATE VIEW ltzhpoem_list_en AS + SELECT + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + || '#poem' || ltzhpoem.sn + AS _viewurl, + ltzhpoem.sn AS sn, + to_char(literalzh.date, 'YYYY-MM-DD') + || CASE WHEN literalzh.title IS NULL THEN '' ELSE ' ' || literalzh.title END + AS set, + ltzhpoem.ord AS ord, + ltzhpoem.title AS title, + ltzhpoem.body AS body, + CASE WHEN ltzhpoem.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + to_char(ltzhpoem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(ltzhpoem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM ltzhpoem + LEFT JOIN literalzh ON ltzhpoem.set=literalzh.sn + LEFT JOIN users AS createdby ON ltzhpoem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON ltzhpoem.updatedby = updatedby.sn + ORDER BY literalzh.date DESC, ltzhpoem.ord; +GRANT SELECT ON ltzhpoem_list_en TO nobody; +CREATE VIEW ltzhpoem_list_zhcn AS + SELECT + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + || '#poem' || ltzhpoem.sn + AS _viewurl, + ltzhpoem.sn AS sn, + to_char(literalzh.date, 'YYYY-MM-DD') + || CASE WHEN literalzh.title IS NULL THEN '' ELSE ' ' || literalzh.title END + AS set, + ltzhpoem.ord AS ord, + ltzhpoem.title AS title, + ltzhpoem.body AS body, + CASE WHEN ltzhpoem.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + to_char(ltzhpoem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(ltzhpoem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM ltzhpoem + LEFT JOIN literalzh ON ltzhpoem.set=literalzh.sn + LEFT JOIN users AS createdby ON ltzhpoem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON ltzhpoem.updatedby = updatedby.sn + ORDER BY literalzh.date DESC, ltzhpoem.ord; +GRANT SELECT ON ltzhpoem_list_zhcn TO nobody; + + +-- +-- Table structure for table "literalen" +-- + +CREATE TABLE literalen ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + date date NOT NULL UNIQUE DEFAULT CURRENT_DATE, + title varchar(16) CHECK (title IS NULL OR title != ''), + dsc text NOT NULL CHECK (dsc != ''), + body text NOT NULL CHECK (body != ''), + kw varchar(32) NOT NULL CHECK (kw != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON literalen TO nobody; + +CREATE VIEW literalen_list_zhtw AS + SELECT + '/writings-en/' || to_char(literalen.date, 'YYYYMMDD') || '.html' + AS _viewurl, + literalen.sn AS sn, + to_char(literalen.date, 'YYYY-MM-DD') AS date, + literalen.title AS title, + literalen.dsc AS dsc, + literalen.body AS body, + literalen.kw AS kw, + CASE WHEN literalen.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN literalen.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(literalen.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(literalen.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM literalen + LEFT JOIN users AS createdby ON literalen.createdby = createdby.sn + LEFT JOIN users AS updatedby ON literalen.updatedby = updatedby.sn + ORDER BY literalen.date DESC; +GRANT SELECT ON literalen_list_zhtw TO nobody; +CREATE VIEW literalen_list_en AS + SELECT + '/writings-en/' || to_char(literalen.date, 'YYYYMMDD') || '.html' + AS _viewurl, + literalen.sn AS sn, + to_char(literalen.date, 'YYYY-MM-DD') AS date, + literalen.title AS title, + literalen.dsc AS dsc, + literalen.body AS body, + literalen.kw AS kw, + CASE WHEN literalen.html THEN 'HTML' + ELSE 'Plain text' + END AS html, + CASE WHEN literalen.hid THEN 'Hidden' + ELSE 'Shown' + END AS hid, + to_char(literalen.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(literalen.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM literalen + LEFT JOIN users AS createdby ON literalen.createdby = createdby.sn + LEFT JOIN users AS updatedby ON literalen.updatedby = updatedby.sn + ORDER BY literalen.date DESC; +GRANT SELECT ON literalen_list_en TO nobody; +CREATE VIEW literalen_list_zhcn AS + SELECT + '/writings-en/' || to_char(literalen.date, 'YYYYMMDD') || '.html' + AS _viewurl, + literalen.sn AS sn, + to_char(literalen.date, 'YYYY-MM-DD') AS date, + literalen.title AS title, + literalen.dsc AS dsc, + literalen.body AS body, + literalen.kw AS kw, + CASE WHEN literalen.html THEN 'HTML' + ELSE '纯文字' + END AS html, + CASE WHEN literalen.hid THEN '隐藏' + ELSE '秀出' + END AS hid, + to_char(literalen.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(literalen.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM literalen + LEFT JOIN users AS createdby ON literalen.createdby = createdby.sn + LEFT JOIN users AS updatedby ON literalen.updatedby = updatedby.sn + ORDER BY literalen.date DESC; +GRANT SELECT ON literalen_list_zhcn TO nobody; + + +-- +-- VIEW: Search +-- +CREATE VIEW search_list AS + (SELECT + 'pages' AS section, + pages.path AS path, + pages.title_zhtw AS title, + null AS author, + to_char(pages.updated, 'YYYY-MM-DD') AS date, + pages.body_zhtw AS body, + pages.kw_zhtw AS kw, + pages.html AS html + FROM pages + WHERE NOT pages.hid + AND pages.path NOT LIKE '/errors/%') + UNION + (SELECT + 'pages' AS section, + pages.path AS path, + pages.title_en AS title, + null AS author, + to_char(pages.updated, 'YYYY-MM-DD') AS date, + pages.body_en AS body, + pages.kw_en AS kw, + pages.html AS html + FROM pages + WHERE NOT pages.hid + AND pages.path NOT LIKE '/errors/%' + AND pages.title_en IS NOT NULL) + UNION + (SELECT + 'diary' AS section, + '/me/diary/' || lpad(cast(diary.pageno AS text), 4, '0') || '.html' + || '#ent' || diary.sn + AS path, + null AS title, + null AS author, + to_char(diary.updated, 'YYYY-MM-DD') AS date, + diary.body_zhtw AS body, + null AS kw, + diary.html AS html + FROM diary + WHERE NOT diary.hid) + UNION + (SELECT + 'diary' AS section, + '/me/diary/' || lpad(cast(diary.pageno AS text), 4, '0') || '.html' + || '#ent' || diary.sn + AS path, + null AS title, + null AS author, + to_char(diary.updated, 'YYYY-MM-DD') AS date, + diary.body_en AS body, + null AS kw, + diary.html AS html + FROM diary + WHERE NOT diary.hid + AND diary.body_en IS NOT NULL) + UNION + (SELECT + 'changelog' AS section, + '/me/changelog/' || lpad(cast(changelog.pageno AS text), 4, '0') || '.html' + || '#ent' || changelog.sn + AS path, + null AS title, + null AS author, + to_char(changelog.updated, 'YYYY-MM-DD') AS date, + changelog.body_zhtw AS body, + null AS kw, + changelog.html AS html + FROM changelog + WHERE NOT changelog.hid) + UNION + (SELECT + 'changelog' AS section, + '/me/changelog/' || lpad(cast(changelog.pageno AS text), 4, '0') || '.html' + || '#ent' || changelog.sn + AS path, + null AS title, + null AS author, + to_char(changelog.updated, 'YYYY-MM-DD') AS date, + changelog.body_en AS body, + null AS kw, + changelog.html AS html + FROM changelog + WHERE NOT changelog.hid + AND changelog.body_en IS NOT NULL) + UNION + (SELECT + 'literalzh' AS section, + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + AS path, + literalzh.title AS title, + null AS author, + to_char(literalzh.date, 'YYYY-MM-DD') AS date, + literalzh.dsc AS body, + literalzh.kw AS kw, + FALSE AS html + FROM literalzh + WHERE NOT literalzh.hid) + UNION + (SELECT + 'ltzhpoem' AS section, + '/writings-zh/' || to_char(literalzh.date, 'YYYYMMDD') || '.html' + || '#poem' || ltzhpoem.sn + AS path, + ltzhpoem.title AS title, + null AS author, + to_char(literalzh.date, 'YYYY-MM-DD') AS date, + ltzhpoem.body AS body, + null AS kw, + FALSE AS html + FROM ltzhpoem + LEFT JOIN literalzh ON ltzhpoem.set=literalzh.sn + WHERE NOT ltzhpoem.hid + AND NOT literalzh.hid) + UNION + (SELECT + 'literalen' AS section, + '/writings-en/' || to_char(literalen.date, 'YYYYMMDD') || '.html' + AS path, + literalen.title AS title, + null AS author, + to_char(literalen.date, 'YYYY-MM-DD') AS date, + literalen.body AS body, + literalen.kw || ' +' || literalen.dsc AS kw, + literalen.html AS html + FROM literalen + WHERE NOT literalen.hid) + UNION + (SELECT + 'links' AS section, + links.url AS path, + links.title AS title, + null AS author, + to_char(links.updated, 'YYYY-MM-DD') AS date, + links.dsc_zhtw AS body, + CASE WHEN links.title_2ln IS NULL THEN '' ELSE links.title_2ln END + || ' +' || CASE WHEN links.url IS NULL THEN '' ELSE links.url END + || ' +' || CASE WHEN links.email IS NULL THEN '' ELSE links.email END + || ' +' || CASE WHEN links.addr IS NULL THEN '' ELSE links.addr END + || ' +' || CASE WHEN links.tel IS NULL THEN '' ELSE links.tel END + || ' +' || CASE WHEN links.fax IS NULL THEN '' ELSE links.fax END + AS kw, + FALSE AS html + FROM links + WHERE NOT links.hid) + UNION + (SELECT + 'links' AS section, + links.url AS path, + links.title AS title, + null AS author, + to_char(links.updated, 'YYYY-MM-DD') AS date, + links.dsc_en AS body, + CASE WHEN links.title_2ln IS NULL THEN '' ELSE links.title_2ln END + || ' +' || CASE WHEN links.url IS NULL THEN '' ELSE links.url END + || ' +' || CASE WHEN links.email IS NULL THEN '' ELSE links.email END + || ' +' || CASE WHEN links.addr IS NULL THEN '' ELSE links.addr END + || ' +' || CASE WHEN links.tel IS NULL THEN '' ELSE links.tel END + || ' +' || CASE WHEN links.fax IS NULL THEN '' ELSE links.fax END + AS kw, + FALSE AS html + FROM links + WHERE NOT links.hid + AND links.dsc_en IS NOT NULL) + UNION + (SELECT + 'guestbook' AS section, + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS path, + null AS title, + guestbook.name AS author, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + guestbook.message AS body, + CASE WHEN guestbook.identity IS NULL THEN '' ELSE guestbook.identity END + || ' +' || CASE WHEN guestbook.location IS NULL THEN '' ELSE guestbook.location END + || ' +' || CASE WHEN guestbook.email IS NULL THEN '' ELSE guestbook.email END + || ' +' || CASE WHEN guestbook.url IS NULL THEN '' ELSE guestbook.url END + AS kw, + FALSE AS html + FROM guestbook + WHERE NOT guestbook.hid) + UNION + (SELECT + 'garbage' AS section, + '/cgi-bin/garbage.cgi?pageno=' || garbage.pageno + || '#msg' || garbage.sn + AS path, + null AS title, + null AS author, + to_char(garbage.updated, 'YYYY-MM-DD') AS date, + garbage.message AS body, + null AS kw, + FALSE AS html + FROM garbage + WHERE NOT garbage.hid) + ORDER BY date DESC, title; +GRANT SELECT ON search_list TO nobody; + + +-- +-- Table structure for table "accounting_account" +-- + +CREATE TABLE accounting_account ( + id int NOT NULL PRIMARY KEY CHECK (id >= 100000000 AND id <= 999999999), + parent_id int REFERENCES accounting_account ON UPDATE CASCADE DEFERRABLE, + code varchar(5) NOT NULL UNIQUE CHECK (code != ''), + title varchar(32) NOT NULL CHECK (title != ''), + created_at timestamp with time zone NOT NULL DEFAULT now(), + created_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated_at timestamp with time zone NOT NULL DEFAULT now(), + updated_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); + + +-- +-- Table structure for table "accounting_account_l10n" +-- + +CREATE TABLE accounting_accountl10n ( + id int NOT NULL PRIMARY KEY CHECK (id >= 100000000 AND id <= 999999999), + master_id int REFERENCES accounting_account ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + name varchar(128) NOT NULL CHECK (name != ''), + language varchar(7) NOT NULL CHECK (language != ''), + value varchar(65535) NOT NULL CHECK (value != ''), + created_at timestamp with time zone NOT NULL DEFAULT now(), + created_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated_at timestamp with time zone NOT NULL DEFAULT now(), + updated_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (master_id, name, language) +); + + +-- +-- Table structure for table "accounting_transaction" +-- + +CREATE TABLE accounting_transaction ( + id int NOT NULL PRIMARY KEY CHECK (id >= 100000000 AND id <= 999999999), + date date NOT NULL DEFAULT CURRENT_DATE, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + notes varchar(128) CHECK (notes IS NULL OR notes != ''), + created_at timestamp with time zone NOT NULL DEFAULT now(), + created_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated_at timestamp with time zone NOT NULL DEFAULT now(), + updated_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); + + +-- +-- Table structure for table "accounting_record" +-- + +CREATE TABLE accounting_record ( + id int NOT NULL PRIMARY KEY CHECK (id >= 100000000 AND id <= 999999999), + transaction_id int NOT NULL REFERENCES accounting_transaction ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + is_credit boolean NOT NULL, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + account_id int NOT NULL REFERENCES accounting_account ON UPDATE CASCADE DEFERRABLE, + summary varchar(128) CHECK (summary IS NULL OR summary != ''), + amount numeric(18,2) NOT NULL CHECK (amount > 0), + created_at timestamp with time zone NOT NULL DEFAULT now(), + created_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated_at timestamp with time zone NOT NULL DEFAULT now(), + updated_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); + + +-- text paper_authors(sn_arg integer); +CREATE FUNCTION paper_authors(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + authors_list text; + BEGIN + authors_list := ''''; + FOR row IN + SELECT resrcher.name AS name FROM resrcher + LEFT JOIN pprauthr ON pprauthr.author=resrcher.sn + WHERE pprauthr.paper=sn_arg + ORDER BY resrcher.abbr + LOOP + authors_list := authors_list || '', '' || row.name; + END LOOP; + RETURN substring(authors_list FROM 3); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION paper_authors(sn_arg integer) TO nobody; + + +-- +-- Table structure for table "resrcher" +-- + +CREATE TABLE resrcher ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + name varchar(32) NOT NULL UNIQUE CHECK (name != ''), + abbr varchar(32) NOT NULL CHECK (abbr != ''), + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON resrcher TO nobody; + +CREATE VIEW resrcher_list_zhtw AS + SELECT + resrcher.sn AS sn, + resrcher.name AS name, + resrcher.abbr AS abbr, + to_char(resrcher.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(resrcher.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM resrcher + LEFT JOIN users AS createdby ON resrcher.createdby = createdby.sn + LEFT JOIN users AS updatedby ON resrcher.updatedby = updatedby.sn + ORDER BY resrcher.abbr; +GRANT SELECT ON resrcher_list_zhtw TO nobody; +CREATE VIEW resrcher_list_en AS + SELECT + resrcher.sn AS sn, + resrcher.name AS name, + resrcher.abbr AS abbr, + to_char(resrcher.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(resrcher.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM resrcher + LEFT JOIN users AS createdby ON resrcher.createdby = createdby.sn + LEFT JOIN users AS updatedby ON resrcher.updatedby = updatedby.sn + ORDER BY resrcher.abbr; +GRANT SELECT ON resrcher_list_en TO nobody; +CREATE VIEW resrcher_list_zhcn AS + SELECT + resrcher.sn AS sn, + resrcher.name AS name, + resrcher.abbr AS abbr, + to_char(resrcher.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(resrcher.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM resrcher + LEFT JOIN users AS createdby ON resrcher.createdby = createdby.sn + LEFT JOIN users AS updatedby ON resrcher.updatedby = updatedby.sn + ORDER BY resrcher.abbr; +GRANT SELECT ON resrcher_list_zhcn TO nobody; + + +-- text paper_tags(sn_arg integer); +CREATE FUNCTION paper_tags(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + tags_list text; + BEGIN + tags_list := ''''; + FOR row IN + SELECT tags.title AS title FROM tags + LEFT JOIN pprtags ON pprtags.tag=tags.sn + WHERE pprtags.paper=sn_arg + ORDER BY tags.title + LOOP + tags_list := tags_list || '', '' || row.title; + END LOOP; + RETURN substring(tags_list FROM 3); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION paper_tags(sn_arg integer) TO nobody; + + +-- +-- Table structure for table "tags" +-- + +CREATE TABLE tags ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + title varchar(32) NOT NULL UNIQUE CHECK (title != ''), + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON tags TO nobody; + +CREATE VIEW tags_list_zhtw AS + SELECT + tags.sn AS sn, + tags.title AS title, + to_char(tags.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(tags.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM tags + LEFT JOIN users AS createdby ON tags.createdby = createdby.sn + LEFT JOIN users AS updatedby ON tags.updatedby = updatedby.sn + ORDER BY tags.title; +GRANT SELECT ON tags_list_zhtw TO nobody; +CREATE VIEW tags_list_en AS + SELECT + tags.sn AS sn, + tags.title AS title, + to_char(tags.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(tags.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM tags + LEFT JOIN users AS createdby ON tags.createdby = createdby.sn + LEFT JOIN users AS updatedby ON tags.updatedby = updatedby.sn + ORDER BY tags.title; +GRANT SELECT ON tags_list_en TO nobody; +CREATE VIEW tags_list_zhcn AS + SELECT + tags.sn AS sn, + tags.title AS title, + to_char(tags.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(tags.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM tags + LEFT JOIN users AS createdby ON tags.createdby = createdby.sn + LEFT JOIN users AS updatedby ON tags.updatedby = updatedby.sn + ORDER BY tags.title; +GRANT SELECT ON tags_list_zhcn TO nobody; + + +-- +-- Table structure for table "pprtypes" +-- + +CREATE TABLE pprtypes ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + ord smallint NOT NULL DEFAULT 50 CHECK (ord >= 0 AND ord < 100), + title_zhtw varchar(128) NOT NULL CHECK (title_zhtw != ''), + title_en varchar(128) CHECK (title_en IS NULL OR title_en != ''), + title_zhcn varchar(128) CHECK (title_zhcn IS NULL OR title_zhcn != ''), + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pprtypes TO nobody; + +CREATE VIEW pprtypes_list_zhtw AS + SELECT + pprtypes.sn AS sn, + pprtypes.ord AS ord, + pprtypes.title_zhtw AS title, + to_char(pprtypes.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprtypes.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprtypes + LEFT JOIN users AS createdby ON pprtypes.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprtypes.updatedby = updatedby.sn + ORDER BY pprtypes.ord; +GRANT SELECT ON pprtypes_list_zhtw TO nobody; +CREATE VIEW pprtypes_list_en AS + SELECT + pprtypes.sn AS sn, + pprtypes.ord AS ord, + COALESCE(pprtypes.title_en, pprtypes.title_zhtw) AS title, + to_char(pprtypes.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprtypes.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprtypes + LEFT JOIN users AS createdby ON pprtypes.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprtypes.updatedby = updatedby.sn + ORDER BY pprtypes.ord; +GRANT SELECT ON pprtypes_list_en TO nobody; +CREATE VIEW pprtypes_list_zhcn AS + SELECT + pprtypes.sn AS sn, + pprtypes.ord AS ord, + COALESCE(pprtypes.title_zhcn, pprtypes.title_zhtw) AS title, + to_char(pprtypes.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprtypes.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprtypes + LEFT JOIN users AS createdby ON pprtypes.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprtypes.updatedby = updatedby.sn + ORDER BY pprtypes.ord; +GRANT SELECT ON pprtypes_list_zhcn TO nobody; + + +-- +-- Table structure for table "papers" +-- + +CREATE TABLE papers ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + type int NOT NULL REFERENCES pprtypes ON UPDATE CASCADE DEFERRABLE, + year smallint NOT NULL CHECK (year > 1930), + month varchar(12) CHECK (month IS NULL or month != ''), + title varchar(128) NOT NULL CHECK (title != ''), + pub varchar(256) CHECK (pub IS NULL or pub != ''), + pages varchar(9) CHECK (pages IS NULL OR pages != ''), + doi varchar(32) CHECK (doi IS NULL OR doi != ''), + url varchar(128) NOT NULL CHECK (url != '' AND url != 'http://'), + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON papers TO nobody; + +CREATE VIEW papers_list_zhtw AS + SELECT + papers.sn AS sn, + pprtypes.title_zhtw AS type, + papers.year AS year, + papers.month AS month, + papers.title AS title, + paper_authors(papers.sn) AS authors, + paper_tags(papers.sn) AS tags, + papers.pub AS pub, + papers.pages AS pages, + papers.doi AS doi, + papers.url AS url, + to_char(papers.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(papers.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM papers + LEFT JOIN pprtypes ON papers.type = pprtypes.sn + LEFT JOIN users AS createdby ON papers.createdby = createdby.sn + LEFT JOIN users AS updatedby ON papers.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title; +GRANT SELECT ON papers_list_zhtw TO nobody; +CREATE VIEW papers_list_en AS + SELECT + papers.sn AS sn, + COALESCE(pprtypes.title_en, pprtypes.title_zhtw) AS type, + papers.year AS year, + papers.month AS month, + papers.title AS title, + paper_authors(papers.sn) AS authors, + paper_tags(papers.sn) AS tags, + papers.pub AS pub, + papers.pages AS pages, + papers.doi AS doi, + papers.url AS url, + to_char(papers.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(papers.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM papers + LEFT JOIN pprtypes ON papers.type = pprtypes.sn + LEFT JOIN users AS createdby ON papers.createdby = createdby.sn + LEFT JOIN users AS updatedby ON papers.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title; +GRANT SELECT ON papers_list_en TO nobody; +CREATE VIEW papers_list_zhcn AS + SELECT + papers.sn AS sn, + COALESCE(pprtypes.title_zhcn, pprtypes.title_zhtw) AS type, + papers.year AS year, + papers.month AS month, + papers.title AS title, + paper_authors(papers.sn) AS authors, + paper_tags(papers.sn) AS tags, + papers.pub AS pub, + papers.pages AS pages, + papers.doi AS doi, + papers.url AS url, + to_char(papers.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(papers.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM papers + LEFT JOIN pprtypes ON papers.type = pprtypes.sn + LEFT JOIN users AS createdby ON papers.createdby = createdby.sn + LEFT JOIN users AS updatedby ON papers.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title; +GRANT SELECT ON papers_list_zhcn TO nobody; + + +-- +-- Table structure for table "pprauthr" +-- + +CREATE TABLE pprauthr ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + paper int NOT NULL REFERENCES papers ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + author int NOT NULL REFERENCES resrcher ON UPDATE CASCADE DEFERRABLE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (paper, author) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pprauthr TO nobody; + +CREATE VIEW pprauthr_list_zhtw AS + SELECT + pprauthr.sn AS sn, + CAST(papers.year AS text) || ' - ' || papers.title AS paper, + resrcher.name AS author, + to_char(pprauthr.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprauthr.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprauthr + LEFT JOIN papers ON pprauthr.paper = papers.sn + LEFT JOIN resrcher ON pprauthr.author = resrcher.sn + LEFT JOIN users AS createdby ON pprauthr.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprauthr.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title, resrcher.abbr; +GRANT SELECT ON pprauthr_list_zhtw TO nobody; +CREATE VIEW pprauthr_list_en AS + SELECT + pprauthr.sn AS sn, + CAST(papers.year AS text) || ' - ' || papers.title AS paper, + resrcher.name AS author, + to_char(pprauthr.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprauthr.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprauthr + LEFT JOIN papers ON pprauthr.paper = papers.sn + LEFT JOIN resrcher ON pprauthr.author = resrcher.sn + LEFT JOIN users AS createdby ON pprauthr.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprauthr.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title, resrcher.abbr; +GRANT SELECT ON pprauthr_list_en TO nobody; +CREATE VIEW pprauthr_list_zhcn AS + SELECT + pprauthr.sn AS sn, + CAST(papers.year AS text) || ' - ' || papers.title AS paper, + resrcher.name AS author, + to_char(pprauthr.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprauthr.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprauthr + LEFT JOIN papers ON pprauthr.paper = papers.sn + LEFT JOIN resrcher ON pprauthr.author = resrcher.sn + LEFT JOIN users AS createdby ON pprauthr.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprauthr.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title, resrcher.abbr; +GRANT SELECT ON pprauthr_list_zhcn TO nobody; + + +-- +-- Table structure for table "pprtags" +-- + +CREATE TABLE pprtags ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + paper int NOT NULL REFERENCES papers ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + tag int NOT NULL REFERENCES tags ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (paper, tag) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pprtags TO nobody; + +CREATE VIEW pprtags_list_zhtw AS + SELECT + pprtags.sn AS sn, + CAST(papers.year AS text) || ' - ' || papers.title AS paper, + tags.title AS tag, + to_char(pprtags.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprtags.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprtags + LEFT JOIN papers ON pprtags.paper = papers.sn + LEFT JOIN tags ON pprtags.tag = tags.sn + LEFT JOIN users AS createdby ON pprtags.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprtags.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title, tags.title; +GRANT SELECT ON pprtags_list_zhtw TO nobody; +CREATE VIEW pprtags_list_en AS + SELECT + pprtags.sn AS sn, + CAST(papers.year AS text) || ' - ' || papers.title AS paper, + tags.title AS tag, + to_char(pprtags.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprtags.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprtags + LEFT JOIN papers ON pprtags.paper = papers.sn + LEFT JOIN tags ON pprtags.tag = tags.sn + LEFT JOIN users AS createdby ON pprtags.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprtags.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title, tags.title; +GRANT SELECT ON pprtags_list_en TO nobody; +CREATE VIEW pprtags_list_zhcn AS + SELECT + pprtags.sn AS sn, + CAST(papers.year AS text) || ' - ' || papers.title AS paper, + tags.title AS tag, + to_char(pprtags.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pprtags.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pprtags + LEFT JOIN papers ON pprtags.paper = papers.sn + LEFT JOIN tags ON pprtags.tag = tags.sn + LEFT JOIN users AS createdby ON pprtags.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pprtags.updatedby = updatedby.sn + ORDER BY papers.year DESC, papers.title, tags.title; +GRANT SELECT ON pprtags_list_zhcn TO nobody; + + +-- +-- Grant privileges +-- +GRANT ALL ON ALL TABLES IN SCHEMA public TO mia; +-- You still need the connect privilege afterwards +-- GRANT CONNECT ON DATABASE imacat TO mia; + + +COMMIT; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat.pm new file mode 100644 index 0000000..0b5321f --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat.pm @@ -0,0 +1,118 @@ +# Tavern IMACAT's +# imacat.pm: Tavern IMACAT's + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-23 + +package Selima::imacat; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +@EXPORT = qw(); + +# Import our site-specific subroutines +use Selima::imacat::Config; +push @EXPORT, @Selima::imacat::Config::EXPORT; +use Selima::imacat::DataVars qw(:all); +push @EXPORT, @Selima::imacat::DataVars::EXPORT_OK; +use Selima::imacat::HTML; +push @EXPORT, @Selima::imacat::HTML::EXPORT; +use Selima::imacat::Items; +push @EXPORT, @Selima::imacat::Items::EXPORT; +use Selima::imacat::Rebuild; +push @EXPORT, @Selima::imacat::Rebuild::EXPORT; + +# Import our site-specific classess +use Selima::imacat::Checker::Page; +use Selima::imacat::Checker::ChangeLog; +use Selima::imacat::Checker::Diary; +use Selima::imacat::Checker::Garbage; +use Selima::imacat::Checker::Garbage::Public; +use Selima::imacat::Checker::Guestbook; +use Selima::imacat::Checker::Guestbook::Public; +use Selima::imacat::Checker::LiteralZh; +use Selima::imacat::Checker::LtZhPoem; +use Selima::imacat::Checker::LiteralEn; +use Selima::imacat::Checker::Researcher; +use Selima::imacat::Checker::Tag; +use Selima::imacat::Checker::Paper; +use Selima::imacat::Checker::Paper::Type; +use Selima::imacat::Checker::Paper::Author; +use Selima::imacat::Checker::Paper::Tag; +use Selima::imacat::Form::Page; +use Selima::imacat::Form::ChangeLog; +use Selima::imacat::Form::Diary; +use Selima::imacat::Form::Garbage; +use Selima::imacat::Form::Garbage::Public; +use Selima::imacat::Form::Guestbook; +use Selima::imacat::Form::Guestbook::Public; +use Selima::imacat::Form::LiteralZh; +use Selima::imacat::Form::LtZhPoem; +use Selima::imacat::Form::LiteralEn; +use Selima::imacat::Form::Researcher; +use Selima::imacat::Form::Tag; +use Selima::imacat::Form::Paper; +use Selima::imacat::Form::Paper::Type; +use Selima::imacat::Form::Paper::Author; +use Selima::imacat::Form::Paper::Tag; +use Selima::imacat::L10N; +use Selima::imacat::List::Pages; +use Selima::imacat::List::ChangeLog; +use Selima::imacat::List::ChangeLog::Public; +use Selima::imacat::List::Diary; +use Selima::imacat::List::Diary::Public; +use Selima::imacat::List::Garbage; +use Selima::imacat::List::Garbage::Public; +use Selima::imacat::List::Guestbook; +use Selima::imacat::List::Guestbook::Public; +use Selima::imacat::List::LiteralZh; +use Selima::imacat::List::LtZhPoem; +use Selima::imacat::List::LiteralEn; +use Selima::imacat::List::Search; +use Selima::imacat::List::Funds; +use Selima::imacat::List::Researchers; +use Selima::imacat::List::Tags; +use Selima::imacat::List::Papers; +use Selima::imacat::List::Paper::Types; +use Selima::imacat::List::Paper::Authors; +use Selima::imacat::List::Paper::Tags; +use Selima::imacat::Processor::Page; +use Selima::imacat::Processor::ChangeLog; +use Selima::imacat::Processor::Diary; +use Selima::imacat::Processor::Garbage; +use Selima::imacat::Processor::Garbage::Public; +use Selima::imacat::Processor::Guestbook; +use Selima::imacat::Processor::Guestbook::Public; +use Selima::imacat::Processor::LiteralZh; +use Selima::imacat::Processor::LtZhPoem; +use Selima::imacat::Processor::LiteralEn; +use Selima::imacat::Processor::Researcher; +use Selima::imacat::Processor::Tag; +use Selima::imacat::Processor::Paper; +use Selima::imacat::Processor::Paper::Type; +use Selima::imacat::Processor::Paper::Author; +use Selima::imacat::Processor::Paper::Tag; + +# Import our common modules +use Selima; +push @EXPORT, @Selima::EXPORT; + +@EXPORT_OK = @EXPORT; + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/ChangeLog.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/ChangeLog.pm new file mode 100644 index 0000000..1f8adb3 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/ChangeLog.pm @@ -0,0 +1,38 @@ +# Tavern IMACAT's +# ChangeLog.pm: The change log form checker. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-24 + +package Selima::imacat::Checker::ChangeLog; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "changelog" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + ${$self->{"maxlens"}}{"body"} = 20480; + return $self; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Diary.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Diary.pm new file mode 100644 index 0000000..0d7f7a3 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Diary.pm @@ -0,0 +1,38 @@ +# Tavern IMACAT's +# Diary.pm: The diary form checker. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-17 + +package Selima::imacat::Checker::Diary; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "diary" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + ${$self->{"maxlens"}}{"body"} = 30720; + return $self; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Garbage.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Garbage.pm new file mode 100644 index 0000000..0b4457d --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Garbage.pm @@ -0,0 +1,37 @@ +# Tavern IMACAT's +# Garbage.pm: The administrative Soundless Backalley form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::imacat::Checker::Garbage; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker::Guestbook); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "garbage" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Garbage/Public.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Garbage/Public.pm new file mode 100644 index 0000000..6d4ed98 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Garbage/Public.pm @@ -0,0 +1,50 @@ +# Tavern IMACAT's +# Public.pm: The Soundless Backalley form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::imacat::Checker::Garbage::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker::Guestbook::Public); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "garbage" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _checkspam_local: Check the local content filter +sub _checkspam_local : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Block virus :p + $self->_block_spam("_checkspam_local(): HTML in message") + if $form->param("message") =~ / +# First written: 2004-10-23 + +package Selima::imacat::Checker::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker::Guestbook); + +use Selima::ShortCut; + +# _check_identity: Check the identity +sub _check_identity : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("identity"); + return $error if defined $error; + # Regularize it + $self->_trim("identity"); + # Check the length + return {"msg"=>N_("This specie is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"identity"}]} + if length $form->param("identity") > ${$self->{"maxlens"}}{"identity"}; + # OK + return; +} + +# _check_email: Check the e-mail +sub _check_email : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("email"); + return $error if defined $error; + # Regularize it + $self->_trim("email"); + # Check the length + return {"msg"=>N_("This e-mail is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"email"}]} + if length $form->param("email") > ${$self->{"maxlens"}}{"email"}; + # OK + return; +} + +# _check_lang: Check the language +sub _check_lang : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("lang0"); + return {"msg"=>N_("Please choose the language.")} + if defined $error; + # Regularize it + $self->_trim("lang0"); + # Check if the language is legal + return {"msg"=>N_("Language [_1] is invalid. Please choose a proper language from the form."), + "margs"=>[$form->param("lang0")]} + if $form->param("lang0") !~ /^(?:none|zh-tw|zh-cn)$/; + # OK + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Guestbook/Public.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Guestbook/Public.pm new file mode 100644 index 0000000..d4385f1 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Guestbook/Public.pm @@ -0,0 +1,97 @@ +# Tavern IMACAT's +# Public.pm: The guestbook form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-23 + +package Selima::imacat::Checker::Guestbook::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker::Guestbook::Public); + +use Selima::DataVars qw($DBH :requri); +use Selima::HTTP; +use Selima::Logging; +use Selima::ShortCut; + +# _check_identity: Check the identity +sub _check_identity : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("identity"); + return $error if defined $error; + # Regularize it + $self->_trim("identity"); + # Check the length + return {"msg"=>N_("Your specie is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"identity"}]} + if length $form->param("identity") > ${$self->{"maxlens"}}{"identity"}; + # OK + return; +} + +# _check_email: Check the e-mail +sub _check_email : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("email"); + return $error if defined $error; + # Regularize it + $self->_trim("email"); + # Check the length + return {"msg"=>N_("Your e-mail is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"email"}]} + if length $form->param("email") > ${$self->{"maxlens"}}{"email"}; + # OK + return; +} + +# _checkspam_local: Check the local content filter +sub _checkspam_local : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Block virus :p + $self->_block_spam("_checkspam_local(): Suspicious spamming from Stephen C.") + if $form->param("name") =~ /stephen/i + || $form->param("name") =~ /ethan/i + || lc $form->param("email") eq "stephen_c\@seed.net.tw"; + # flyboy http://www.egamemp3.com/ + $self->_block_spam("_checkspam_local(): Suspicious spamming from flyboy.") + if $form->param("identity") eq "flyboy"; + # OK + return; +} + +# Old blocker +# 清濤命理網站 http://click.twmis.net/ +# $self->_block_spam("_checkspam_local(): Suspicious spamming from http://click.twmis.net/.") +# if $form->param("message") =~ /http:\/\/click\.twmis\.net/i +# || $form->param("url") =~ /http:\/\/click\.twmis\.net/i +# || $form->param("message") =~ /http:\/\/unn\.sexll\.com/i +# || $form->param("url") =~ /http:\/\/unn\.sexll\.com/i +# || $form->param("message") =~ /靈異節目(?:....)?老師/; + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm new file mode 100644 index 0000000..7009bc4 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm @@ -0,0 +1,91 @@ +# Tavern IMACAT's +# LiteralEn.pm: The English writing form checker. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-25 + +package Selima::imacat::Checker::LiteralEn; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use CGI qw(); + +use Selima::ChkFunc; +use Selima::DataVars qw($DBH); +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "literalen" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_date: Check the date +sub _check_date : method { + local ($_, %_); + my ($self, $form, $error, $sql, $sth); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("date"); + return $error if defined $error; + # Regularize it + $self->_trim("date"); + # Check if it is filled + return {"msg"=>N_("Please fill in the date.")} + if $form->param("date") eq ""; + # Check the length + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + if length $form->param("date") != ${$self->{"maxlens"}}{"date"}; + # Check the date format + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + if length $form->param("date") !~ /^(\d{4})-(\d{2})-(\d{2})$/; + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + unless defined check_date($1, $2, $3); + # Check if this item is duplicated + @_ = qw(); + push @_, "date=" . $DBH->quote($form->param("date")); + push @_, "sn!=" . $self->{"sn"} if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("The literal work on this date already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + # OK + return; +} + +# _check_title: Check the title +# Use the default title checker + +# _check_dsc: Check the description +# Use the default description checker + +# _check_body: Check the content +# Use the default content checker + +# _check_kw: Check the keywords list +# Use the default keywords list checker + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm new file mode 100644 index 0000000..6662c96 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm @@ -0,0 +1,140 @@ +# Tavern IMACAT's +# LiteralZh.pm: The Chinese writing form checker. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-19 + +package Selima::imacat::Checker::LiteralZh; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use CGI qw(); + +use Selima::ChkFunc; +use Selima::DataVars qw($DBH); +use Selima::ShortCut; + +use Selima::imacat::Checker::LtZhPoem; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "literalzh" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_date: Check the date +sub _check_date : method { + local ($_, %_); + my ($self, $form, $error, $sql, $sth); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("date"); + return $error if defined $error; + # Regularize it + $self->_trim("date"); + # Check if it is filled + return {"msg"=>N_("Please fill in the date.")} + if $form->param("date") eq ""; + # Check the length + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + if length $form->param("date") != ${$self->{"maxlens"}}{"date"}; + # Check the date format + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + if length $form->param("date") !~ /^(\d{4})-(\d{2})-(\d{2})$/; + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + unless defined check_date($1, $2, $3); + # Check if this item is duplicated + @_ = qw(); + push @_, "date=" . $DBH->quote($form->param("date")); + push @_, "sn!=" . $self->{"sn"} if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("The literal work on this date already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + # OK + return; +} + +# _check_title: Check the title +sub _check_title : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("title"); + return $error if defined $error; + # Regularize it + $self->_trim("title"); + # Skip if it is not filled + return if $form->param("title") eq ""; + # Check the length + return {"msg"=>N_("This title is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"title"}]} + if length $form->param("title") > ${$self->{"maxlens"}}{"title"}; + # OK + return; +} + +# _check_dsc: Check the description +# Use the default description checker + +# _check_kw: Check the keywords list +# Use the default keywords list checker + +# _check_poems: Check the poems +sub _check_poems : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Remove the default content + foreach (grep /^poem\d+body$/, $form->param) { + $form->param($_, "") + if $form->param($_) eq __("Fill in the content here."); + } + # Loop each poem + for ($_ = 0; !$self->_missing("poem$_" . "title"); $_++) { + my ($subform, $checker, $error); + # Skip unselected ones + next if $self->_missing("poem$_");; + # Regularize it + $self->_trim("poem$_" . "title"); + $self->_trimtext("poem$_" . "body"); + # Check with the subform checker + $subform = new CGI(""); + $subform->param("set", $self->{"sn"}) if $self->{"iscur"}; + $subform->param("title", $form->param("poem$_" . "title")); + $subform->param("body", $form->param("poem$_" . "body")); + $checker = new Selima::imacat::Checker::LtZhPoem($subform); + $error = $checker->check("title", "body"); + return $error if defined $error; + } + + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/LtZhPoem.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/LtZhPoem.pm new file mode 100644 index 0000000..5e24140 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/LtZhPoem.pm @@ -0,0 +1,91 @@ +# Tavern IMACAT's +# LtZhPoem.pm: The Chinese poem form checker. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-19 + +package Selima::imacat::Checker::LtZhPoem; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::CallForm; +use Selima::ChkFunc; +use Selima::ShortCut; + +use Selima::imacat::DataVars qw(:forms); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "ltzhpoem" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_body: Check the content +# Use the default content checker + +# _check_set: Check the literal work set +sub _check_set : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("set"); + return $error if defined $error; + # Regularize it + $self->_trim("set"); + # Check if it is filled + return {"msg"=>N_("Please select a work set.")} + if $form->param("set") eq ""; + # Check if the work set exists + return {"msg"=>N_("This work set does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("set")}[0], "literalzh"; + # OK + return; +} + +# _check_title: Check the title +# Use the default title checker + +# _redir_selset: Suspend and move to the literal work set selection form +sub _redir_selset : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selset"); + call_form FORM_LITERALZH, undef, "import_selset"; +} + +# _redir_delset: Remove the literal work set +sub _redir_delset : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("delset"); + $self->{"form"}->delete("newslet"); + success_redirect undef; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Page.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Page.pm new file mode 100644 index 0000000..22e8d0a --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Page.pm @@ -0,0 +1,48 @@ +# Tavern IMACAT's +# Page.pm: The web page form checker. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-07 + +package Selima::imacat::Checker::Page; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker::Page); + +use Selima::ShortCut; + +# _check_class: Check the HTML class +sub _check_class : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("class"); + return $error if defined $error; + # Regularize it + $self->_trim("class"); + # Check the length + return {"msg"=>N_("This HTML class is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"class"}]} + if length $form->param("class") > ${$self->{"maxlens"}}{"class"}; + # OK + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Paper.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Paper.pm new file mode 100644 index 0000000..60ecd2c --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Paper.pm @@ -0,0 +1,401 @@ +# Tavern IMACAT's +# Paper.pm: The research paper form checker. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +package Selima::imacat::Checker::Paper; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::CallForm; +use Selima::ChkFunc; +use Selima::DataVars qw($DBH); +use Selima::ShortCut; + +use Selima::imacat::DataVars qw(:forms); +use Selima::imacat::Checker::Paper::Author; +use Selima::imacat::Checker::Paper::Tag; +use Selima::imacat::Checker::Researcher; +use Selima::imacat::Checker::Tag; +use Selima::imacat::Items; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "papers" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_type: Check the type +sub _check_type : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("type"); + return $error if defined $error; + # Regularize it + $self->_trim("type"); + # Check if it is filled + return {"msg"=>N_("Please select in the type.")} + if $form->param("type") eq ""; + # Check if the type exists + return {"msg"=>N_("This type does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("type")}[0], "pprtypes"; + # OK + return; +} + +# _check_year: Check the year +sub _check_year : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("year"); + return $error if defined $error; + # Regularize it + $self->_trim("year"); + # Check if it is filled + return {"msg"=>N_("Please fill in the year of publication.")} + if $form->param("year") eq ""; + # Check the length + return {"msg"=>N_("This year of publication is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"year"}]} + if length $form->param("year") > ${$self->{"maxlens"}}{"year"}; + return {"msg"=>N_("This year of publication is too short. (Min. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"year"}]} + if length $form->param("year") < ${$self->{"maxlens"}}{"year"}; + # Check the year format + return {"msg"=>N_("Please fill in a positive integer year of publication.")} + unless $form->param("year") =~ /^\d+$/; + # Set to an integer + $_ = $form->param("year"); + $_ += 0; + $form->param("year", $_); + # Check the year format + return {"msg"=>N_("Year ([#,_1]) out of range. Please specify between [#,_2] and [#,_3]."), + "margs"=>[$form->param("year"), 1930, 2013]} + if $form->param("year") < 1930 || $form->param("year") > 2013; + # OK + return; +} + +# _check_month: Check the month +sub _check_month : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("month"); + return $error if defined $error; + # Regularize it + $self->_trim("month"); + # Skip if it is not filled + return if $form->param("month") eq ""; + # Check the length + return {"msg"=>N_("This month is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"month"}]} + if length $form->param("month") > ${$self->{"maxlens"}}{"month"}; + # Check the format + return {"msg"=>N_("Please fill in the month as ~[month~], ~[month day~] or ~[season~].")} + unless $form->param("month") =~ /^(?:(?:January|February|March|April|May|June|July|August|September|October|November|December)(?: \d\d?)?|(?:Spring|Summer|Fall|Winter))$/; + # OK + return; +} + +# _check_title: Check the title +# Use the default title checker + +# _check_authors: Check the authors +sub _check_authors : method { + local ($_, %_); + my ($self, $form, $error, @sel, $subform, $checker); + my (%cur, $max, %existing, @new, $cond, $sql, $sth, $count, $row); + $self = $_[0]; + $form = $self->{"form"}; + # Get the selected items + @_ = map $_ . "sn", + grep /^author\d+/ && defined $form->param($_ . "sn"), $form->param; + # / + # Regularize them + $self->_trim("authorfree", @_); + # Check if it is filled + return {"msg"=>N_("Please fill in the author.")} + if @_ == 0 && $form->param("authorfree") eq ""; + # Check each item + %_ = map { $form->param($_) => 1 } @_; + $subform = new CGI(""); + $subform->param("paper", $self->{"sn"}) if $self->{"iscur"}; + foreach (keys %_) { + $subform->param("author", $_); + $checker = new Selima::imacat::Checker::Paper::Author($subform); + $error = $checker->check("author"); + return $error if defined $error; + } + # Check the new items + if ($form->param("authorfree") ne "") { + # Obtain the current listed items + %cur = qw(); + foreach ($form->param) { + $cur{$form->param($_)} = $1 + 0 + if /^author(\d+)sn$/; + } + if (values %cur > 0) { + $max = (reverse sort { $a <=> $b } values %cur)[0]; + } else { + $max = -1; + } + # Obtain the new items that exists in the database + @new = split /\s*[,,]\s*/, $form->param("authorfree"); + $cond = join " OR ", map "name=" . $DBH->quote($_), @new; + $sql = "SELECT sn, name FROM resrcher" + . " WHERE $cond;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, %existing = qw(); $_ < $count; $_++) { + $row = $sth->fetchrow_hashref; + $existing{$$row{"name"}} = $$row{"sn"}; + } + @_ = @new; + @new = qw(); + foreach (@_) { + # Non-existing items + if (!exists $existing{$_}) { + push @new, $_; + # Existing but not listed yet + } elsif (!exists $cur{$existing{$_}}) { + $max++; + $form->param("author$max", 1); + $form->param("author$max" . "sn", $existing{$_}); + # Existing and listed + } else { + $form->param("author" . $cur{$existing{$_}}, 1); + } + } + $form->param("authorfree", join(", ", @new)); + # Check each new item + foreach (@new) { + $subform = new CGI(""); + $subform->param("name", $_); + $subform->param("abbr", abbreviate_name $_); + $checker = new Selima::imacat::Checker::Researcher($subform); + $checker->{"iscur"} = 0; + $error = $checker->check("name", "abbr"); + return $error if defined $error; + } + } + # OK + return; +} + +# _check_tags: Check the tags +sub _check_tags : method { + local ($_, %_); + my ($self, $form, $error, @sel, $subform, $checker); + my (%cur, $max, %existing, @new, $cond, $sql, $sth, $count, $row); + $self = $_[0]; + $form = $self->{"form"}; + # Get the selected items + @_ = map $_ . "sn", + grep /^tag\d+/ && defined $form->param($_ . "sn"), $form->param; + # / + # Regularize them + $self->_trim("tagfree", @_); + $form->param("tagfree", lc $form->param("tagfree")); + # Skip if it is not filled + return if @_ == 0 && $form->param("tagfree") eq ""; + # Check each item + %_ = map { $form->param($_) => 1 } @_; + $subform = new CGI(""); + $subform->param("paper", $self->{"sn"}) if $self->{"iscur"}; + foreach (keys %_) { + $subform->param("tag", $_); + $checker = new Selima::imacat::Checker::Paper::Tag($subform); + $error = $checker->check("tag"); + return $error if defined $error; + } + # Check the new items + if ($form->param("tagfree") ne "") { + # Obtain the current listed items + %cur = qw(); + foreach ($form->param) { + $cur{$form->param($_)} = $1 + 0 + if /^tag(\d+)sn$/; + } + if (values %cur > 0) { + $max = (reverse sort { $a <=> $b } values %cur)[0]; + } else { + $max = -1; + } + # Obtain the new items that exists in the database + @new = split /\s*[,,]\s*/, $form->param("tagfree"); + $cond = join " OR ", map "title=" . $DBH->quote($_), @new; + $sql = "SELECT sn, title FROM tags" + . " WHERE $cond;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, %existing = qw(); $_ < $count; $_++) { + $row = $sth->fetchrow_hashref; + $existing{$$row{"title"}} = $$row{"sn"}; + } + @_ = @new; + @new = qw(); + foreach (@_) { + # Non-existing items + if (!exists $existing{$_}) { + push @new, $_; + # Existing but not listed yet + } elsif (!exists $cur{$existing{$_}}) { + $max++; + $form->param("tag$max", 1); + $form->param("tag$max" . "sn", $existing{$_}); + # Existing and listed + } else { + $form->param("tag" . $cur{$existing{$_}}, 1); + } + } + $form->param("tagfree", join(", ", @new)); + # Check each new item + foreach (@new) { + $subform = new CGI(""); + $subform->param("title", $_); + $checker = new Selima::imacat::Checker::Tag($subform); + $checker->{"iscur"} = 0; + $error = $checker->check("title"); + return $error if defined $error; + } + } + # OK + return; +} + +# _check_pub: Check the publication +sub _check_pub : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("pub"); + return $error if defined $error; + # Regularize it + $self->_trim("pub"); + # Skip if it is not filled + return if $form->param("pub") eq ""; + # Check the length + return {"msg"=>N_("This publication is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"pub"}]} + if length $form->param("pub") > ${$self->{"maxlens"}}{"pub"}; + # OK + return; +} + +# _check_pages: Check the pages +sub _check_pages : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("pages"); + return $error if defined $error; + # Regularize it + $self->_trim("pages"); + # Skip if it is not filled + return if $form->param("pages") eq ""; + # Check the length + return {"msg"=>N_("This pages is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"pages"}]} + if length $form->param("pages") > ${$self->{"maxlens"}}{"pages"}; + # Check the format + return {"msg"=>N_("Please fill in the pages as ### or ###-###.")} + unless $form->param("pages") =~ /^\d+(?:-\d+)?$/; + # OK + return; +} + +# _check_doi: Check the digital object identifier +sub _check_doi : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("doi"); + return $error if defined $error; + # Regularize it + $self->_trim("doi"); + # Skip if it is not filled + return if $form->param("doi") eq ""; + # Check the length + return {"msg"=>N_("This DOI is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"doi"}]} + if length $form->param("doi") > ${$self->{"maxlens"}}{"doi"}; + # Check if this item is duplicated + @_ = qw(); + push @_, "doi=" . $DBH->quote($form->param("doi")); + push @_, "sn!=" . $self->{"sn"} if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This paper already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + # OK + return; +} + +# _check_url: The URL checker +sub _check_url : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("url"); + return $error if defined $error; + # Regularize it + $self->_trim("url"); + # Check if it is filled + return {"msg"=>N_("Please fill in the URL.")} + if $form->param("url") eq "" || $form->param("url") eq "http://"; + # Check the length + return {"msg"=>N_("This URL is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"url"}]} + if length $form->param("url") > ${$self->{"maxlens"}}{"url"}; + # Check its format + return {"msg"=>N_("Please fill in a valid URL.")} + if !is_url_wellformed $form->param("url"); + # OK + return; +} + +no utf8; +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm new file mode 100644 index 0000000..ca8c187 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm @@ -0,0 +1,165 @@ +# Tavern IMACAT's +# Author.pm: The research paper author form checker. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +package Selima::imacat::Checker::Paper::Author; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::ChkFunc; +use Selima::CallForm; +use Selima::DataVars qw($DBH); +use Selima::ShortCut; + +use Selima::imacat::DataVars qw(:forms); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "pprauthr" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} +# check: Run a list of checks +sub check : method { + local ($_, %_); + my ($self, $error, @cols); + ($self, @cols) = @_; + # Run the parent method first + $error = $self->SUPER::check(@cols); + return $error if defined $error; + # See if we need to check the duplicates. Check it in the end. + %_ = map { $_ => 1 } @cols; + if (exists $_{"paper"} && exists $_{"author"}) { + $error = $self->__check_dup(); + return $error if defined $error; + } + return; +} + + +# _check_paper: Check the paper +sub _check_paper : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("paper"); + return $error if defined $error; + # Regularize it + $self->_trim("paper"); + # Check if it is filled + return {"msg"=>N_("Please select a paper.")} + if $form->param("paper") eq ""; + # Check if the paper exists + return {"msg"=>N_("This paper does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("paper")}[0], "papers"; + # OK + return; +} + +# _check_author: Check the author +sub _check_author : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("author"); + return $error if defined $error; + # Regularize it + $self->_trim("author"); + # Check if it is filled + return {"msg"=>N_("Please select a author.")} + if $form->param("author") eq ""; + # Check if this author exists + return {"msg"=>N_("This author does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("author")}[0], "resrcher"; + # OK + return; +} + +# __check_dup: Check if this item is duplicated +sub __check_dup : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + @_ = qw(); + push @_, "paper=" . $form->param("paper"); + push @_, "author=" . $form->param("author"); + push @_, "sn!=" . $self->{"sn"} + if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This paper author already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + return; +} + +# _redir_selpaper: Suspend and move to the paper selection form +sub _redir_selpaper : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selpaper"); + call_form FORM_PAPERS, undef, "import_selpaper"; +} + +# _redir_delpaper: Remove the paper +sub _redir_delpaper : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("delpaper"); + $self->{"form"}->delete("paper"); + success_redirect undef; +} + +# _redir_selauthor: Suspend and move to the author selection form +sub _redir_selauthor : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selauthor"); + call_form FORM_RESRCHER, undef, "import_selauthor"; +} + +# _redir_delauthor: Remove the author +sub _redir_delauthor : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("delauthor"); + $self->{"form"}->delete("author"); + success_redirect undef; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm new file mode 100644 index 0000000..bd65032 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm @@ -0,0 +1,165 @@ +# Tavern IMACAT's +# Tag.pm: The paper tag form checker. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-19 + +package Selima::imacat::Checker::Paper::Tag; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::ChkFunc; +use Selima::CallForm; +use Selima::DataVars qw($DBH); +use Selima::ShortCut; + +use Selima::imacat::DataVars qw(:forms); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "pprtags" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} +# check: Run a list of checks +sub check : method { + local ($_, %_); + my ($self, $error, @cols); + ($self, @cols) = @_; + # Run the parent method first + $error = $self->SUPER::check(@cols); + return $error if defined $error; + # See if we need to check the duplicates. Check it in the end. + %_ = map { $_ => 1 } @cols; + if (exists $_{"paper"} && exists $_{"tag"}) { + $error = $self->__check_dup(); + return $error if defined $error; + } + return; +} + + +# _check_paper: Check the paper +sub _check_paper : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("paper"); + return $error if defined $error; + # Regularize it + $self->_trim("paper"); + # Check if it is filled + return {"msg"=>N_("Please select a paper.")} + if $form->param("paper") eq ""; + # Check if the paper exists + return {"msg"=>N_("This paper does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("paper")}[0], "papers"; + # OK + return; +} + +# _check_tag: Check the tag +sub _check_tag : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("tag"); + return $error if defined $error; + # Regularize it + $self->_trim("tag"); + # Check if it is filled + return {"msg"=>N_("Please select a tag.")} + if $form->param("tag") eq ""; + # Check if this tag exists + return {"msg"=>N_("This tag does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("tag")}[0], "tags"; + # OK + return; +} + +# __check_dup: Check if this item is duplicated +sub __check_dup : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + @_ = qw(); + push @_, "paper=" . $form->param("paper"); + push @_, "tag=" . $form->param("tag"); + push @_, "sn!=" . $self->{"sn"} + if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This paper tag already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + return; +} + +# _redir_selpaper: Suspend and move to the paper selection form +sub _redir_selpaper : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selpaper"); + call_form FORM_PAPERS, undef, "import_selpaper"; +} + +# _redir_delpaper: Remove the paper +sub _redir_delpaper : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("delpaper"); + $self->{"form"}->delete("paper"); + success_redirect undef; +} + +# _redir_seltag: Suspend and move to the tag selection form +sub _redir_seltag : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("seltag"); + call_form FORM_TAGS, undef, "import_seltag"; +} + +# _redir_deltag: Remove the tag +sub _redir_deltag : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("deltag"); + $self->{"form"}->delete("tag"); + success_redirect undef; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Paper/Type.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Paper/Type.pm new file mode 100644 index 0000000..824d5a2 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Paper/Type.pm @@ -0,0 +1,43 @@ +# Tavern IMACAT's +# Type.pm: The research paper type form checker. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-15 + +package Selima::imacat::Checker::Paper::Type; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "pprtypes" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_ord: Check the order +# Use the default order checker + +# _check_title: Check the title +# Use the default title checker + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm new file mode 100644 index 0000000..59fe1a3 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm @@ -0,0 +1,83 @@ +# Tavern IMACAT's +# Researcher.pm: The researcher form checker. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +package Selima::imacat::Checker::Researcher; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "resrcher" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_name: Check the name +sub _check_name : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("name"); + return $error if defined $error; + # Regularize it + $self->_trim("name"); + # Check if it is filled + return {"msg"=>N_("Please fill in the full name.")} + if $form->param("name") eq ""; + # Check the length + return {"msg"=>N_("This full name is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"name"}]} + if length $form->param("name") > ${$self->{"maxlens"}}{"name"}; + # OK + return; +} + +# _check_abbr: Check the abbreviation +sub _check_abbr : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("abbr"); + return $error if defined $error; + # Regularize it + $self->_trim("abbr"); + # Check if it is filled + return {"msg"=>N_("Please fill in the abbreviation.")} + if $form->param("abbr") eq ""; + # Check the length + return {"msg"=>N_("This abbreviation is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"abbr"}]} + if length $form->param("abbr") > ${$self->{"maxlens"}}{"abbr"}; + # OK + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Tag.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Tag.pm new file mode 100644 index 0000000..e90ba84 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Checker/Tag.pm @@ -0,0 +1,65 @@ +# Tavern IMACAT's +# Tag.pm: The tag form checker. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-19 + +package Selima::imacat::Checker::Tag; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::DataVars qw($DBH); +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "tags" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_title: Check the title +sub _check_title : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # Run the default title checker + $error = $self->SUPER::_check_title; + return $error if defined $error; + # Regularize it + $form->param("title", lc $form->param("title")); + # Check if this item is duplicated + @_ = qw(); + push @_, "title=" . $DBH->quote($form->param("title")); + push @_, "sn!=" . $self->{"sn"} if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This tag already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + # OK + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Config.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Config.pm new file mode 100644 index 0000000..5c34a79 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Config.pm @@ -0,0 +1,98 @@ +# Tavern IMACAT's +# Config.pm: The web site configuration. + +# Copyright (c) 2003-2020 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-23 + +package Selima::imacat::Config; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(siteconf page_replacements); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub siteconf(); +sub page_replacements(); +} + +# Get into the public variable space and initialize them +use lib $ENV{"DOCUMENT_ROOT"} . qw(/../../lib/perl5); +use Selima::CopyYear; +use Selima::DataVars qw(:all); +use Selima::ShortCut; + +use Selima::imacat::DataVars qw(:all); + +# siteconf: Subroutine to initialize site configuration +sub siteconf() { + local ($_, %_); + + # The package name and the package title + $PACKAGE = "imacat"; + $SITENAME_ABBR = "Tavern"; + # The author and the copyright + $AUTHOR = N_("imacat"); + $COPYRIGHT = N_("© imacat. All rights reserved."); + # Document root, the library and the l10n directories + $DOC_ROOT = $ENV{"DOCUMENT_ROOT"}; + $SITE_LIBDIR = $DOC_ROOT . "/magicat/lib/perl5"; + $LOCALEDIR = $DOC_ROOT . "/magicat/locale"; + + # Tables to lock when rebuilding pages + @REBUILD_TABLES = qw(linkcat links linkcatz); + # The local rebuild type labels + %REBUILD_LABELS = ( + "diary" => N_("Tavern Diary"), + "changelog" => N_("Change Log"), + "literalzh" => N_("Chinese Literal Works"), + "literalen" => N_("English Literal Works"), + ); + + # The languages + $DEFAULT_LANG = "zh-tw"; + @ALL_LINGUAS = qw(zh-tw zh-cn en); + + # The site data variables + $SCRIPTS{FORM_LITERALZH()} = "/magicat/cgi-bin/literalzh.cgi"; + $SCRIPTS{FORM_PAPERS()} = "/magicat/cgi-bin/papers.cgi"; + $SCRIPTS{FORM_RESRCHER()} = "/magicat/cgi-bin/resrcher.cgi"; + $SCRIPTS{FORM_TAGS()} = "/magicat/cgi-bin/tags.cgi"; + + return; +} + +# page_replacements: Dynamic page elements to be replaced, +# but not part of the content. Used by xfupdate_template(). +sub page_replacements() { + return { + "copyyear" => { + "pattern" => "1998(?:-\\d{4})?", + "content" => copyyear(1998), + }, + "generator" => { + "pattern" => "Selima \\d+\\.\\d+", + "content" => "Selima $Selima::VERSION", + }, + }; +} + +no utf8; +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/DataVars.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/DataVars.pm new file mode 100644 index 0000000..980e385 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/DataVars.pm @@ -0,0 +1,62 @@ +# Tavern IMACAT's +# DataVars.pm: The site-wide constants and variables. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-25 + +package Selima::imacat::DataVars; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT %EXPORT_TAGS @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +%EXPORT_TAGS = ( + forms => [qw(FORM_LITERALZH FORM_PAPERS FORM_RESRCHER FORM_TAGS)], +); +@EXPORT_OK = qw(); +my %seen; +%seen = qw(); +foreach my $tag (keys %EXPORT_TAGS) { + push @EXPORT_OK, grep !$seen{$_}++, @{$EXPORT_TAGS{$tag}}; +} +$EXPORT_TAGS{"all"} = [@EXPORT_OK]; +# Prototype declaration +sub clear(); +} + +use Selima::DataVars qw(:forms); + +use constant FORM_LITERALZH => 1001; +use constant FORM_PAPERS => 1002; +use constant FORM_RESRCHER => 1003; +use constant FORM_TAGS => 1004; + +# clear: Clear the data variables +sub clear() { + local ($_, %_); + + delete $SCRIPTS{FORM_LITERALZH()}; + delete $SCRIPTS{FORM_PAPERS()}; + delete $SCRIPTS{FORM_RESRCHER()}; + delete $SCRIPTS{FORM_TAGS()}; + + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm new file mode 100644 index 0000000..178dea4 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm @@ -0,0 +1,99 @@ +# Tavern IMACAT's +# ChangeLog.pm: The change log form. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-24 + +package Selima::imacat::Form::ChangeLog; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "changelog" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this log entry") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to write a new log entry."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current log entry."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a log entry."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(body html hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn body html hid pageno + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Write a New Change Log Entry"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Change Log Entry"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Change Log Entry"); + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_hid: Hide? +sub _html_col_hid : method { + $_[0]->_html_coltmpl_bool("hid", h_abbr(__("Hide?")), + h_abbr(__("Hide this log entry")), h_abbr(__("Show this log entry")), + h_abbr(__("Hide this log entry currently."))); +} + +# _html_col_pageno: The page number +sub _html_col_pageno : method { + $_[0]->_html_coltmpl_ro("pageno", h_abbr(__("Page No.:"))); +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Diary.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Diary.pm new file mode 100644 index 0000000..43c125b --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Diary.pm @@ -0,0 +1,99 @@ +# Tavern IMACAT's +# Diary.pm: The diary form. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-17 + +package Selima::imacat::Form::Diary; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "diary" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this diary entry") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to write a new diary entry."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current diary entry."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a diary entry."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(body html hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn body html hid pageno + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Write a New Diary Entry"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Diary Entry"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Diary Entry"); + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_hid: Hide? +sub _html_col_hid : method { + $_[0]->_html_coltmpl_bool("hid", h_abbr(__("Hide?")), + h_abbr(__("Hide this diary entry")), h_abbr(__("Show this diary entry")), + h_abbr(__("Hide this diary entry currently."))); +} + +# _html_col_pageno: The page number +sub _html_col_pageno : method { + $_[0]->_html_coltmpl_ro("pageno", h_abbr(__("Page No.:"))); +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Garbage.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Garbage.pm new file mode 100644 index 0000000..d0960f2 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Garbage.pm @@ -0,0 +1,75 @@ +# Tavern IMACAT's +# Garbage.pm: The administrative Soundless Backalley form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::imacat::Form::Garbage; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form::Guestbook); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "garbage" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this message") + if !exists $$args{"deltext"}; + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(message hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn message hid + ip host ct pageno oldpageno + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Write a New Message"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Edit a Current Message"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete a Message"); + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Garbage/Public.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Garbage/Public.pm new file mode 100644 index 0000000..b104ab8 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Garbage/Public.pm @@ -0,0 +1,100 @@ +# Tavern IMACAT's +# Public.pm: The Soundless Backalley form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::imacat::Form::Garbage::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form::Guestbook::Public); + +use Selima::DataVars qw(FORM_CAPTCHA); +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + # This should always be always a new form + $$args{"type"} = "new" + if !exists $$args{"type"}; + $$args{"table"} = "garbage" + if !exists $$args{"table"}; + $$args{"footer_buttons"} = [ + { "name" => "submit", "value" => h_abbr(__("I'm sick.")) } ] + if !exists $$args{"footer_buttons"}; + $$args{"show_table"} = 0 + if !exists $$args{"show_table"}; + $$args{"colspan"} = 0 + if !exists $$args{"colspan"}; + $$args{"cols"} = [qw(captcha message)] + if !exists $$args{"cols"}; + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_captcha: The CAPTCHA (human test) +# Add a field that is not displayed and should be empty to trap spam +# See: http://www.hockinson.com/programmer-web-designer-denver-co-usa.php?s=44 +sub _html_col_captcha : method { + local ($_, %_); + my ($self, $col, $label, $prompt, $size, $mark); + my ($thclass, $thcolspan); + $self = $_[0]; + $mark = $self->_mark("captcha"); + $col = FORM_CAPTCHA; + $label = h_abbr(C_("Current Website:")); + $size = h($self->{"defsize"}); + $prompt = "

    " + . h_abbr(C_("Enter your website URL here.")) . "

    "; + + print << "EOT"; +
    +

    +$prompt +
    +EOT + return; +} + +# _html_col_message: The message +sub _html_col_message : method { + local ($_, %_); + my ($self, $val, $label, $default, $hdef); + $self = $_[0]; + $default = C_("Fill in your message here."); + $val = $self->_val_textarea("message", $default); + $hdef = h($default); + print << "EOT"; + +EOT + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm new file mode 100644 index 0000000..a19cb7b --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm @@ -0,0 +1,94 @@ +# Tavern IMACAT's +# Guestbook.pm: The administrative guestbook form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-23 + +package Selima::imacat::Form::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form::Guestbook); + +use Selima::CommText; +use Selima::DataVars qw(:lninfo); +use Selima::FormFunc; +use Selima::HTTP; +use Selima::LnInfo; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(name identity location email url + message hid lang)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn name identity location email url + message hid lang + ip host ct pageno oldpageno + created createdby updated updatedby)]; + } + } + $self = $class->SUPER::new($status, $args); + $self->{"cur"}->param("lang0", "none") + if !defined $self->{"cur"}->param("lang0"); + return $self; +} + +# _html_col_email: The e-mail +sub _html_col_email : method { + $_[0]->_html_coltmpl_text("email", h_abbr(__("E-mail:"))); +} + +# _html_col_identity: The identity +sub _html_col_identity : method { + $_[0]->_html_coltmpl_text("identity", h_abbr(__("Specie:"))); +} + +# _html_col_lang: The language +sub _html_col_lang : method { + local ($_, %_); + my ($self, $opts); + $self = $_[0]; + $opts = [ { "val" => "none", + "title" => t_none, }, + { "val" => "zh-tw", + "title" => ln("zh-tw", LN_DESC_CURLC), }, + { "val" => "zh-cn", + "title" => ln("zh-cn", LN_DESC_CURLC), }, ]; + $self->{"form"}->param("lang0", "none") + if $self->{"is_first_form"} && !defined $self->{"form"}->param("lang0"); + $self->_html_coltmpl_radio("lang0", h_abbr(__("Language tag:")), + $opts, undef, 1); +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm new file mode 100644 index 0000000..2f25579 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm @@ -0,0 +1,57 @@ +# Tavern IMACAT's +# Public.pm: The guestbook form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::imacat::Form::Guestbook::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form::Guestbook::Public); + +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"prefmsg"} = [] if !exists $$args{"prefmsg"}; + push @{$$args{"prefmsg"}}, __("General commercial advertisements are not welcomed and may be deleted at once. HTML is not supported."); + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_email: The e-mail +sub _html_col_email : method { + $_[0]->_html_coltmpl_text("email", h_abbr(__("E-mail:"))); +} + +# _html_col_identity: The identity +sub _html_col_identity : method { + $_[0]->_html_coltmpl_text("identity", h_abbr(__("Specie:"))); +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm new file mode 100644 index 0000000..eac1c4d --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm @@ -0,0 +1,100 @@ +# Tavern IMACAT's +# LiteralEn.pm: The English writing form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-25 + +package Selima::imacat::Form::LiteralEn; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "literalen" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this literal work") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to write a new English literal work."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current English literal work."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a English literal work."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(date title dsc body kw html hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn date title dsc body kw html hid + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Write a New English Literal Work"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current English Literal Work"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a English Literal Work"); + } + } + if (!exists $$args{"preview"}) { + $$args{"preview"} = 1; + } + if ($$args{"preview"} && !exists $$args{"prevmsg"}) { + $$args{"prevmsg"} = __("Preview this literal work."); + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_hid: Hide? +sub _html_col_hid : method { + $_[0]->_html_coltmpl_bool("hid", h_abbr(__("Hide?")), + h_abbr(__("Hide this literal work")), h_abbr(__("Show this literal work")), + h_abbr(__("Hide this literal work currently."))); +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm new file mode 100644 index 0000000..57d5d3a --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm @@ -0,0 +1,303 @@ +# Tavern IMACAT's +# LiteralZh.pm: The Chinese writing form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-19 + +package Selima::imacat::Form::LiteralZh; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::A2HTML; +use Selima::CommText; +use Selima::DataVars qw($DBH); +use Selima::Format; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "literalzh" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this literal work") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to write a new Chinese literal work."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current Chinese literal work."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a Chinese literal work."); + } + } + $$args{"colspan"} = 3 + if !exists $$args{"colspan"}; + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(date title dsc poems kw hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn date title dsc poems kw hid + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Write a New Chinese Literal Work"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Chinese Literal Work"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Chinese Literal Work"); + } + } + if (!exists $$args{"preview"}) { + $$args{"preview"} = 1; + } + if ($$args{"preview"} && !exists $$args{"prevmsg"}) { + $$args{"prevmsg"} = __("Preview this literal work."); + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_poems: The poems +sub _html_col_poems : method { + local ($_, %_); + my ($self, $form, $current, $label, $orig, $new, $mark, $colspan, $cols, $rows); + my ($col, $val, $no, $rowspan, $rows_cur, $rows_new, $count_new); + my ($labeltitle, $labelbody, $labelhid); + my ($marktitle, $markbody, $markhid); + my ($hbodydef, $texthid, $true, $false); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("poems"); + $colspan = $self->_colspan(-2); + $cols = h($self->{"defsize"}); + $rows = h(10); + $labeltitle = h_abbr(__("Title:")); + $labelbody = h_abbr(__("Content:")); + $labelhid = h_abbr(__("Hide?")); + $hbodydef = h(__("Fill in the content here.")); + $texthid = h(__("Hide this poem currently.")); + $marktitle = $self->_mark("poemtitle"); + $markbody = $self->_mark("poembody"); + $markhid = $self->_mark("poemhid"); + $true = h(__("Hide this poem")); + $false = h(__("Show this poem")); + + # A form to create a new item + if ($self->{"type"} eq "new") { + # Find the last filled poem + for ($_ = 0; defined $form->param("poem$_" . "title"); $_++) {} + for ($_--; $_ >= 0 + && $form->param("poem$_" . "title") eq "" + && $form->param("poem$_" . "body") eq ""; $_--) {} + $count_new = $_ + 1 + 3; + $rows_new = $count_new * 3; + $rows_new = $rows_new > 1? " rowspan=\"" . h($rows_new) . "\"": ""; + $label = h_abbr(__("[numerate,_1,Poem]:", 0)); + print << "EOT"; + + +EOT + for ($_ = 0, @_ = qw(); $_ < $count_new; $_++) { + my ($coltitle, $colbody, $colhid, $valtitle, $valbody, $valhid); + $col = "poem$_"; + $val = $self->_val_check($col); + $valtitle = $self->_val_text($col . "title"); + $coltitle = h_abbr($col . "title"); + $valbody = $self->_val_textarea($col . "body", $hbodydef); + $colbody = h($col . "body"); + $valhid = $self->_val_check($col . "hid"); + $colhid = h($col . "hid"); + $col = h($col); + push @_, << "EOT"; + + + + + + + + + + + + +EOT + } + print join("\n\n", @_); + print << "EOT"; + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + # Find the last filled poem + $rows_cur = $current->param("poemcount") > 0? + $current->param("poemcount") * 3: 1; + for ($_ = 0; defined $form->param("poem$_" . "title"); $_++) {} + for ($_-- ; $_ >= 0 + && $form->param("poem$_" . "title") eq "" + && $form->param("poem$_" . "body") eq ""; $_--) {} + $count_new = $_ + 1 + 3; + $rows_new = $count_new * 3; + $rowspan = $rows_cur + $rows_new; + $rows_cur = $rows_cur > 1? " rowspan=\"" . h($rows_cur) . "\"": ""; + $rows_new = $rows_new > 1? " rowspan=\"" . h($rows_new) . "\"": ""; + $rowspan = $rowspan > 1? " rowspan=\"" . h($rowspan) . "\"": ""; + $label = h_abbr(__("[numerate,_1,Poem]:", 0)); + $orig = h_abbr(__("Original:")); + $new = h_abbr(__("New:")); + print << "EOT"; + + + $orig +EOT + for ($_ = 0, @_ = qw(); $_ < $current->param("poemcount"); $_++) { + my ($curtitle, $curbody, $curhid); + $no = h($_ + 1); + $col = "poem$_"; + $curtitle = h_abbr($current->param($col . "title")); + $curbody = a2html($current->param($col . "body")); + $curhid = $self->{"cur"}->param($col . "hid")? $true: $false; + push @_, << "EOT"; + $no + $marktitle$labeltitle + $curtitle + + + $markbody$labelbody + $curbody + + + $markhid$labelhid + $curhid +EOT + } + print @_ > 0? join("\n\n", @_): + " _colspan . ">" . h_abbr(t_none) . "\n"; + print << "EOT"; + + + +EOT + for ($_ = 0, @_ = qw(); $_ < $count_new; $_++) { + my ($coltitle, $colbody, $colhid, $valtitle, $valbody, $valhid); + $col = "poem$_"; + $val = $self->_val_check($col); + $valtitle = $self->_val_text($col . "title"); + $coltitle = h_abbr($col . "title"); + $valbody = $self->_val_textarea($col . "body", $hbodydef); + $colbody = h($col . "body"); + $valhid = $self->_val_check($col . "hid"); + $colhid = h($col . "hid"); + $col = h($col); + push @_, << "EOT"; + + + + + + + + + + + + +EOT + } + print join("\n\n", @_); + print << "EOT"; + +EOT + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + # Find the last filled poem + $rows_cur = $current->param("poemcount") > 0? + $current->param("poemcount") * 3: 1; + $rows_cur = $rows_cur > 1? " rowspan=\"" . h($rows_cur) . "\"": ""; + $label = h_abbr(__("[numerate,_1,Poem]:", $current->param("poemcount"))); + print << "EOT"; + + $mark$label +EOT + for ($_ = 0, @_ = qw(); $_ < $current->param("poemcount"); $_++) { + my ($curtitle, $curbody, $curhid); + $no = h($_ + 1); + $col = "poem$_"; + $curtitle = h_abbr($current->param($col . "title")); + $curbody = a2html($current->param($col . "body")); + $curhid = $self->{"cur"}->param($col . "hid")? $true: $false; + push @_, << "EOT"; + $no + $marktitle$labeltitle + $curtitle + + + $markbody$labelbody + $curbody + + + $markhid$labelhid + $curhid +EOT + } + print @_ > 0? join("\n\n", @_): + " _colspan . ">" . h_abbr(t_none) . "\n"; + print << "EOT"; + +EOT + } + return; +} + +# _html_col_hid: Hide? +sub _html_col_hid : method { + $_[0]->_html_coltmpl_bool("hid", h_abbr(__("Hide?")), + h_abbr(__("Hide this literal work")), h_abbr(__("Show this literal work")), + h_abbr(__("Hide this literal work currently."))); +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm new file mode 100644 index 0000000..82eaa54 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm @@ -0,0 +1,109 @@ +# Tavern IMACAT's +# LtZhPoem.pm: The Chinese poem form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-19 + +package Selima::imacat::Form::LtZhPoem; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::CommText; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +use Selima::imacat::Items; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "ltzhpoem" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this poem") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to write a new Chinese poem."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current Chinese poem."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a Chinese poem."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(set ord title body hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn set ord title body hid + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Write a New Chinese Poem"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Chinese Poem"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Chinese Poem"); + } + } + $self = $class->SUPER::new($status, $args); + ${$self->{"maxlens"}}{"ord"} = 2; + return $self; +} + +# _html_col_set: The work set +sub _html_col_set : method { + $_[0]->_html_coltmpl_call("set", h_abbr(__("Work set:")), \&literalzh_title); +} + +# _html_col_ord: The order +sub _html_col_ord : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Set the default order to maximum + $form->param("ord", 99) + if $self->{"is_first_form"} && $self->{"type"} eq "new"; + $self->_html_coltmpl_text("ord", h_abbr(C_("Order:")), undef, + ${$self->{"maxlens"}}{"ord"}); +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Page.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Page.pm new file mode 100644 index 0000000..d056f76 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Page.pm @@ -0,0 +1,64 @@ +# Tavern IMACAT's +# Page.pm: The web page form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-07 + +package Selima::imacat::Form::Page; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form::Page); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(path ord title body kw class html hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn path ord title body kw class html hid + created createdby updated updatedby)]; + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_class: The HTML class +sub _html_col_class : method { + $_[0]->_html_coltmpl_text("class", h_abbr(__("HTML class:"))); +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Paper.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Paper.pm new file mode 100644 index 0000000..96f5edc --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Paper.pm @@ -0,0 +1,235 @@ +# Tavern IMACAT's +# Paper.pm: The research paper form. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +package Selima::imacat::Form::Paper; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::ChkFunc; +use Selima::CommText; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +use Selima::imacat::Items; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "papers" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this paper") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to add a new paper."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current paper."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a paper."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(type year month title authors tags + pub pages doi url)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn type year month title authors tags + pub pages doi url cite + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Add a New Paper"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Paper"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Paper"); + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_type: The type +sub _html_col_type : method { + $_[0]->_html_coltmpl_select("type", + h_abbr(__("Type:")), \&pprtype_options, \&pprtype_title); +} + +# _html_col_year: The year +sub _html_col_year : method { + $_[0]->_html_coltmpl_text("year", h_abbr(__("Year of publication:")), undef, 4); +} + +# _html_col_month: The month +sub _html_col_month : method { + $_[0]->_html_coltmpl_text("month", h_abbr(__("Month of publication:")), undef, 12); +} + +# _html_col_authors: The authors +sub _html_col_authors : method { + $_[0]->_html_coltmpl_tags("author", h_abbr(__("Authors:")), "resrcher", + \&researcher_name, undef, undef, 1); +} + +# _html_col_tags: The tags +sub _html_col_tags : method { + $_[0]->_html_coltmpl_tags("tag", h_abbr(__("Tags:")), "tags", + \&tag_title, undef, undef, 1); +} + +# _html_col_pub: The publication +sub _html_col_pub : method { + $_[0]->_html_coltmpl_text("pub", h_abbr(__("Publication:"))); +} + +# _html_col_pages: The pages +sub _html_col_pages : method { + $_[0]->_html_coltmpl_text("pages", h_abbr(__("Pages:")), undef, ${$_[0]->{"maxlens"}}{"pages"}); +} + +# _html_col_doi: The digital object identifier +sub _html_col_doi : method { + $_[0]->_html_coltmpl_text("doi", h_abbr(__("DOI.:")), undef, ${$_[0]->{"maxlens"}}{"doi"}); +} + +# _html_col_cite: The APA citation format +sub _html_col_cite : method { + my ($self, $form, $current, $label, $mark, $colspan, $thclass, $thcolspan); + my $val; + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("cite"); + $colspan = $self->_colspan; + $label = h_abbr(__("APA citation:")); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label +
      +EOT + # Print the APA citation style + # In text + $val = ""; + if ($current->param("authorcount") == 1) { + $_ = $current->param("author0abbr"); + s/,.*$//; + $val .= $_; + } elsif ($current->param("authorcount") == 2) { + @_ = qw(); + push @_, $current->param("author0abbr"); + push @_, $current->param("author1abbr"); + foreach (@_) { + s/,.*$//; + } + $val .= join " and ", @_; + } elsif ($current->param("authorcount") >= 6) { + $_ = $current->param("author0abbr"); + s/,.*$//; + $val .= "$_ et al."; + } else { + for (my $i = 0, @_ = qw(); $i < $current->param("authorcount"); $i++) { + $_ = $current->param("author$i" . "abbr"); + s/,.*$//; + push @_, $_; + } + $_[$#_] = "and " . $_[$#_]; + $val .= join ", ", @_; + } + $val .= " (" . $current->param("year") . ")"; + print "
    • $val
    • \n"; + + # In referenece list + $val = ""; + if ($current->param("authorcount") == 1) { + $val .= $current->param("author0abbr"); + } elsif ($current->param("authorcount") == 2) { + $val .= $current->param("author0abbr") + . " and " . $current->param("author1abbr"); + } else { + for (my $i = 0, @_ = qw(); $i < $current->param("authorcount"); $i++) { + push @_, $current->param("author$i" . "abbr"); + } + $_[$#_] = "and " . $_[$#_]; + $val .= join ", ", @_; + } + if (defined $current->param("month")) { + $val .= " (" . $current->param("year") + . ", " . $current->param("month") . "). "; + } else { + $val .= " (" . $current->param("year") . "). "; + } + if ($current->param("title") !~ /\w$/) { + $val .= $current->param("title") . " "; + } else { + $val .= $current->param("title") . ". "; + } + $_ = $current->param("pub"); + if (s/(\d+)(\(\d+\))$/$1<\/cite>$2/) { + $_ = "" . $_; + } else { + $_ = "" . $_ . ""; + } + $val .= "$_"; + if (defined $current->param("pages")) { + $val .= ", " . $current->param("pages") . "."; + } else { + $val .= "."; + } + if (defined $current->param("doi")) { + $val .= " doi:" . $current->param("doi"); + } + print "
    • $val
    • \n"; + + print << "EOT"; +
    + + +EOT +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm new file mode 100644 index 0000000..a5a8d8c --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm @@ -0,0 +1,101 @@ +# Tavern IMACAT's +# Author.pm: The research paper author form. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +package Selima::imacat::Form::Paper::Author; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::CommText; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +use Selima::imacat::Items; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "pprauthr" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this type") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to add a new paper author."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to change a current paper author."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a paper author."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(paper author)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn paper author + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Add a New Paper Author"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Change a Current Paper Author"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Paper Author"); + } + } + $self = $class->SUPER::new($status, $args); + ${$self->{"maxlens"}}{"ord"} = 2; + return $self; +} + +# _html_col_paper: The paper +sub _html_col_paper : method { + $_[0]->_html_coltmpl_call("paper", h_abbr(__("Paper:")), \&paper_title); +} + +# _html_col_author: The author +sub _html_col_author : method { + $_[0]->_html_coltmpl_call("author", h_abbr(__("Author:")), \&researcher_name); +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm new file mode 100644 index 0000000..1947abf --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm @@ -0,0 +1,101 @@ +# Tavern IMACAT's +# Tag.pm: The paper tag form. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-19 + +package Selima::imacat::Form::Paper::Tag; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::CommText; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +use Selima::imacat::Items; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "pprtags" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this type") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to add a new paper tag."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to change a current paper tag."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a paper tag."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(paper tag)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn paper tag + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Add a New Paper Tag"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Change a Current Paper Tag"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Paper Tag"); + } + } + $self = $class->SUPER::new($status, $args); + ${$self->{"maxlens"}}{"ord"} = 2; + return $self; +} + +# _html_col_paper: The paper +sub _html_col_paper : method { + $_[0]->_html_coltmpl_call("paper", h_abbr(__("Paper:")), \&paper_title); +} + +# _html_col_tag: The tag +sub _html_col_tag : method { + $_[0]->_html_coltmpl_call("tag", h_abbr(__("Tag:")), \&tag_title); +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm new file mode 100644 index 0000000..cf1bb86 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm @@ -0,0 +1,125 @@ +# Tavern IMACAT's +# Type.pm: The research paper type form. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-15 + +package Selima::imacat::Form::Paper::Type; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::CommText; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "pprtypes" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this type") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to add a new paper type."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current paper type."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a paper type."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(ord title)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn ord title papers + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Add a New Paper Type"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Paper Type"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Paper Type"); + } + } + $self = $class->SUPER::new($status, $args); + ${$self->{"maxlens"}}{"ord"} = 2; + if ($self->{"type"} eq "cur") { + if (defined $self->{"cur"}->param("pprcount") && $self->{"cur"}->param("pprcount") > 0) { + $self->{"nodelete"} = 1; + push @{$self->{"prefmsg"}}, __("This paper type has [numerate,_1,a paper,papers]. It cannot be deleted. To delete the type, [numerate,_1,its paper,all of its papers] must first be deleted.", $self->{"cur"}->param("ssubcount")); + } + } + return $self; +} + +# _html_col_papers: The papers +sub _html_col_papers : method { + my ($self, $form, $current, $label, $mark, $colspan, $thclass, $thcolspan); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("papers"); + $colspan = $self->_colspan; + $label = h_abbr(__("[numerate,_1,Paper]:", $current->param("pprcount"))); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("pprcount"); $_++) { + push @_, sprintf("
  • %2\$s
  • \n", + h("papers.cgi?form=cur&sn=" . $current->param("ppr$_" . "sn")), + h_abbr($current->param("ppr$_" . "title"))); + } + print @_ > 0? "
      \n" . join("", @_) ."
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Researcher.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Researcher.pm new file mode 100644 index 0000000..3a77fc7 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Researcher.pm @@ -0,0 +1,134 @@ +# Tavern IMACAT's +# Researcher.pm: The researcher form. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +package Selima::imacat::Form::Researcher; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::CommText; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "resrcher" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this researcher") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to add a new researcher."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to update a current researcher."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a researcher."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(name abbr)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn name abbr papers + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Add a New Researcher"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Update a Current Researcher"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Researcher"); + } + } + $self = $class->SUPER::new($status, $args); + if ($self->{"type"} eq "cur") { + if (defined $self->{"cur"}->param("pprcount") && $self->{"cur"}->param("pprcount") > 0) { + $self->{"nodelete"} = 1; + push @{$self->{"prefmsg"}}, __("This researcher has [numerate,_1,a paper,papers]. It cannot be deleted. To delete the researcher, [numerate,_1,its paper,all of its papers] must first be deleted.", $self->{"cur"}->param("ssubcount")); + } + } + return $self; +} + +# _html_col_name: The name +sub _html_col_name : method { + $_[0]->_html_coltmpl_text("name", h_abbr(__("Full name:"))); +} + +# _html_col_abbr: The abbreviation +sub _html_col_abbr : method { + $_[0]->_html_coltmpl_text("abbr", h_abbr(__("Abbreviation:"))); +} + +# _html_col_papers: The papers +sub _html_col_papers : method { + my ($self, $form, $current, $label, $mark, $colspan, $thclass, $thcolspan); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("papers"); + $colspan = $self->_colspan; + $label = h_abbr(__("[numerate,_1,Paper]:", $current->param("pprcount"))); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("pprcount"); $_++) { + push @_, sprintf("
  • %2\$s
  • \n", + h("papers.cgi?form=cur&sn=" . $current->param("ppr$_" . "sn")), + h_abbr($current->param("ppr$_" . "title"))); + } + print @_ > 0? "
      \n" . join("", @_) ."
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Tag.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Tag.pm new file mode 100644 index 0000000..4269c4e --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Form/Tag.pm @@ -0,0 +1,118 @@ +# Tavern IMACAT's +# Tag.pm: The tag form. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-19 + +package Selima::imacat::Form::Tag; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::CommText; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "tags" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this tag") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to add a new tag."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current tag."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a tag."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(title)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn title papers + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Add a New Tag"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Tag"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Tag"); + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_papers: The papers +sub _html_col_papers : method { + my ($self, $form, $current, $label, $mark, $colspan, $thclass, $thcolspan); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("papers"); + $colspan = $self->_colspan; + $label = h_abbr(__("[numerate,_1,Paper]:", $current->param("pprcount"))); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("pprcount"); $_++) { + push @_, sprintf("
  • %2\$s
  • \n", + h("papers.cgi?form=cur&sn=" . $current->param("ppr$_" . "sn")), + h_abbr($current->param("ppr$_" . "title"))); + } + print @_ > 0? "
      \n" . join("", @_) ."
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/HTML.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/HTML.pm new file mode 100644 index 0000000..b98fd60 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/HTML.pm @@ -0,0 +1,1527 @@ +# Tavern IMACAT's +# HTML.pm: The HTML web page parts. + +# Copyright (c) 2003-2020 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-23 + +package Selima::imacat::HTML; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(html_header html_title html_ctitle html_message); +push @EXPORT, qw(html_errmsg html_body html_links html_links_index); +push @EXPORT, qw(html_diary_index html_changelog_index); +push @EXPORT, qw(html_ltzh_pagebar html_ltzh_body html_ltzh_index); +push @EXPORT, qw(html_lten_pagebar html_lten_index); +push @EXPORT, qw(html_footer); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub html_header($;$); +sub html_title($;$); +sub html_ctitle($); +sub html_message($); +sub html_errmsg($); +sub html_langs(;$); +sub html_nav(;$); +sub html_login(;$); +sub html_nav_admin(;$); +sub html_nav_page(;$); +sub html_body($;$); +sub html_links($;$); +sub html_links_index(\@;$); +sub html_links_register(;$); +sub html_diary_index(\@;$); +sub html_changelog_index(\@;$); +sub html_ltzh_pagebar($\@;$); +sub html_ltzh_body($;$); +sub html_ltzh_index($;$); +sub html_footer(;$); +sub merged_tree($$;$); +} + +use Cwd qw(realpath); +use Encode qw(encode FB_HTMLCREF); +use File::Basename qw(dirname); +use File::Spec::Functions qw(); +use IO::NestedCapture qw(CAPTURE_STDOUT); +use Lingua::ZH::Numbers; +use URI::Escape qw(uri_escape); + +use Selima::A2HTML; +use Selima::AddGet; +use Selima::AltLang; +use Selima::DataVars qw($DBH :author :env :input :l10n :list :lninfo :requri :siteconf); +use Selima::ErrMsg; +use Selima::Format; +use Selima::HTTPS; +use Selima::Links; +use Selima::LnInfo; +use Selima::LogIn; +use Selima::MarkAbbr; +use Selima::MungAddr; +use Selima::PageFunc; +use Selima::Preview; +use Selima::ScptPriv; +use Selima::ShortCut; +use Selima::Unicode; +use Selima::XFileIO; + +use vars qw(@ADMIN_SCRIPTS %HEADER %FOOTER); +@ADMIN_SCRIPTS = ( + { "title" => N_("Manage Content"), + "sub" => [ + { "title" => N_("Guestbook"), + "path" => "/magicat/cgi-bin/guestbook.cgi" }, + { "title" => N_("Backalley"), + "path" => "/magicat/cgi-bin/garbage.cgi" }, + { "title" => N_("Diary"), + "path" => "/magicat/cgi-bin/diary.cgi" }, + { "title" => N_("Change Log"), + "path" => "/magicat/cgi-bin/changelog.cgi" }, + { "title" => N_("Pages"), + "path" => "/magicat/cgi-bin/pages.cgi" }, + { "title" => N_("Links"), + "path" => "/magicat/cgi-bin/links.cgi" }, + { "title" => N_("Link Categories"), + "path" => "/magicat/cgi-bin/linkcat.cgi" }, + { "title" => N_("Link Categorization"), + "path" => "/magicat/cgi-bin/linkcatz.cgi" }, + { "title" => N_("Chinese Literal Works"), + "path" => "/magicat/cgi-bin/literalzh.cgi" }, + { "title" => N_("Chinese Poems"), + "path" => "/magicat/cgi-bin/ltzhpoem.cgi" }, + { "title" => N_("English Literal Works"), + "path" => "/magicat/cgi-bin/literalen.cgi" }, + ], + }, + { "title" => N_("Manage Accounts"), + "sub" => [ + { "title" => N_("Users"), + "path" => "/magicat/cgi-bin/users.cgi" }, + { "title" => N_("Groups"), + "path" => "/magicat/cgi-bin/groups.cgi" }, + { "title" => N_("User Membership"), + "path" => "/magicat/cgi-bin/usermem.cgi" }, + { "title" => N_("Group Membership"), + "path" => "/magicat/cgi-bin/groupmem.cgi" }, + { "title" => N_("User Preferences"), + "path" => "/magicat/cgi-bin/userpref.cgi" }, + { "title" => N_("Script Privileges"), + "path" => "/magicat/cgi-bin/scptpriv.cgi" }, + ], + }, +# { "title" => N_("Manage Accounting"), +# "sub" => [ +# { "title" => N_("Reports"), +# "path" => "/magicat/cgi-bin/acctreps.cgi", +# "https" => 1 }, +# { "title" => N_("Transactions"), +# "path" => "/magicat/cgi-bin/accttrx.cgi", +# "https" => 1 }, +# { "title" => N_("Subjects"), +# "path" => "/magicat/cgi-bin/acctsubj.cgi", +# "https" => 1 }, +# { "title" => N_("Records"), +# "path" => "/magicat/cgi-bin/acctrecs.cgi", +# "https" => 1 }, +# ], +# }, + { "title" => N_("Manage Papers"), + "sub" => [ + { "title" => N_("Papers"), + "path" => "/magicat/cgi-bin/papers.cgi" }, + { "title" => N_("Researchers"), + "path" => "/magicat/cgi-bin/resrcher.cgi" }, + { "title" => N_("Tags"), + "path" => "/magicat/cgi-bin/tags.cgi" }, + { "title" => N_("Types"), + "path" => "/magicat/cgi-bin/pprtypes.cgi" }, + { "title" => N_("Authors"), + "path" => "/magicat/cgi-bin/pprauthr.cgi" }, + { "title" => N_("Paper Tags"), + "path" => "/magicat/cgi-bin/pprtags.cgi" }, + ], + }, + { "title" => N_("Miscellaneous"), + "sub" => [ + { "title" => N_("Accounting"), + "path" => "https://mia.imacat.idv.tw/accounting" }, +# { "title" => N_("Funds"), +# "path" => "/magicat/cgi-bin/funds.cgi" }, + { "title" => N_("Activity Log"), + "path" => "/magicat/cgi-bin/actlog.cgi" }, + { "title" => N_("Rebuild Pages"), + "path" => "/magicat/cgi-bin/rebuild.cgi" }, + { "title" => N_("Analog"), + "path" => "/magicat/analog/" }, + { "title" => N_("Test Script"), + "path" => "/magicat/cgi-bin/test.cgi" }, + { "title" => N_("MRTG"), + "path" => "/mrtg/rinse.html" }, + { "title" => N_("Saved Forms"), + "path" => "/magicat/cgi-bin/saveform.cgi" }, + { "title" => N_("CGI Environment"), + "path" => "/magicat/cgi-bin/showenv.cgi" }, + { "title" => "phpinfo();", + "path" => "/magicat/phpinfo.php" }, + { "title" => N_("Server Status"), + "path" => "/magicat/server-status", + "https" => 1 }, + { "title" => N_("Server Information"), + "path" => "/magicat/server-info", + "https" => 1 }, + { "title" => N_("Bwshare Information"), + "path" => "/magicat/bwshare-info", + "https" => 1 }, + { "title" => N_("Bwshare Trace"), + "path" => "/magicat/bwshare-trace", + "https" => 1 }, + { "title" => N_("Perl Status"), + "path" => "/magicat/perl-status", + "https" => 1 }, + ], + }, +); + +# html_header: Display the page header +sub html_header($;$) { + local ($_, %_); + my ($title, $args, $guide); + my ($langname, $langfile); + my ($author, $copyright, $keywords, $copypage); + my ($stylesheets, $javascripts, $favicon, $class, $onload); + my ($titlelang, $skiptobody); + ($title, $args) = @_; + # Obtain the page parameters + $args = page_param $args; + # Set the language + $langname = h(ln $$args{"lang"}, LN_NAME); + $langfile = ln($$args{"lang"}, LN_FILENAME); + # Misc + # The copyright message should be already HTML-escaped, + # for the copyright sign "©". + $author = exists $$args{"author"}? h($$args{"author"}): + defined $AUTHOR? h(__($AUTHOR)): undef; + $copyright = exists $$args{"copyright"}? $$args{"copyright"}: + defined $COPYRIGHT? __($COPYRIGHT): undef; + $keywords = exists $$args{"keywords"}? h($$args{"keywords"}): undef; + $copypage = exists $$args{"copypage"}? + h($$args{"copypage"}): h("/copying.html"); + # Style sheets + $stylesheets = []; + push @$stylesheets, "/stylesheets/common.css"; + push @$stylesheets, "/stylesheets/lang.$langfile.css"; + push @$stylesheets, @{$$args{"stylesheets"}} + if exists $$args{"stylesheets"}; + # JavaScripts + $javascripts = []; + if (exists $$args{"javascripts"}) { + push @$javascripts, "/scripts/common.js"; + push @$javascripts, "/scripts/lang.$langfile.js"; + push @$javascripts, @{$$args{"javascripts"}}; + } + # Favorite icon + $favicon = exists $$args{"favicon"}? + h($$args{"favicon"}): h("/favicon.ico"); + # The class of body + $class = exists $$args{"class"}? + " class=\"" . h($$args{"class"}) . "\"": + $$args{"admin"}? " class=\"magicat\"": ""; + # The onload JavaScript event handler + $onload = exists $$args{"onload"}? + " onload=\"" . h($$args{"onload"}) . "\"": ""; + # The accessibility guide + $skiptobody = h(__("Skip to the page content area.")); + $guide = h(__("Page Content Area")); + + print << "EOT"; +" ?> + + + + + + +EOT + # Author, copyright and keywords + print "\n" + if defined $author; + print "\n" + if defined $copyright; + print "\n" + if defined $keywords; + print "\" />\n" + if $$args{"static"}; + # Language variants + foreach my $ln (grep $_ ne $$args{"lang"}, @{$$args{"all_linguas"}}) { + print "\n"; + } + # The home page + print "\n"; + # The copyright page + print "\n" + if defined $copypage; + # The author contact information + print "\n"; + # The search engine + print "\n"; + # Revelent pages + print "\n" + if exists $$args{"up"}; + print "\n" + if exists $$args{"first"}; + print "\n" + if exists $$args{"prev"}; + print "\n" + if exists $$args{"next"}; + print "\n" + if exists $$args{"last"}; + print "\n" + if exists $$args{"toc"}; + # Style sheets + print "\n" + foreach @$stylesheets; + # JavaScripts + print "\n" + foreach @$javascripts; + # Favorite Icon + print "\n"; + # The title + $titlelang = $$args{"title_lang"} eq $$args{"lang"}? "": + " xml:lang=\"" . h(ln $$args{"title_lang"}, LN_NAME) . "\""; + print "" . h($title) . "\n"; + print << "EOT"; + + + + + + +EOT + + # Show the navigation area + html_nav $args; + # Embrace the content + print << "EOT"; +
    + + +EOT + + # Display the title + html_title $title, $args unless $$args{"no_auto_title"}; + + return; +} + +# html_title: Print an HTML title +sub html_title($;$) { + local ($_, %_); + my ($title, $args, $h); + ($title, $args) = @_; + $title = $_[0]; + # Obtain the page parameters + $args = page_param $args; + + # Website administration + if ($$args{"admin"}) { + $h = << "EOT"; +
    +

    %s

    +

    %s

    +
    + +EOT + printf $h, h_abbr(__("Magicat")), h_abbr($title); + + # Chinese literal works + } elsif ($$args{"path"} =~ /^\/writings-zh\/(?:\d{8}|latest)\.html$/) { + $title = h_abbr($title); + $title =~ s/ (\d+\.\d+\.’\d+\.)/ $1<\/span>/; + print << "EOT"; +

    $title

    + +EOT + + # Ordinary pages + } else { + $h = << "EOT"; +

    %s

    + +EOT + printf $h, h_abbr($title); + } + return; +} + +# html_ctitle: Print an HTML complex title +sub html_ctitle($) { + local ($_, %_); + my ($title, $h); + $title = $_[0]; + $h = << "EOT"; +
    +%s +
    + +EOT + printf $h, markabbr($title); + return; +} + +# html_message: Print an HTML message +sub html_message($) { + local ($_, %_); + $_ = $_[0]; + return if !defined $_ || $_ eq ""; + $_ = h_abbr($_); + print << "EOT"; +

    $_

    + +EOT + return; +} + +# html_errmsg: Print an HTML error message, a wrapper to html_message() +sub html_errmsg($) { + local ($_, %_); + $_ = $_[0]; + return if !defined $_; + html_message(err2msg $_); + return; +} + +# html_nav: Print the HTML navigation links +sub html_nav(;$) { + local ($_, %_); + my ($args, $lang, $guide, $FD, @sections); + my ($guestbook, $links, $home, $email); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + $lang = $$args{"lang"}; + # The accessibility guide + $guide = h(__("Navigation Links Area")); + + @sections = qw(); + # Print the primary navigation bar + $HEADER{$lang} = {} if !exists $HEADER{$lang}; + ${$HEADER{$lang}}{"file"} = sprintf("%s/magicat/include/header.%s.html", + $DOC_ROOT, ln($lang, LN_FILENAME)) + if !exists ${$HEADER{$lang}}{"file"}; + undef $_; + if ( !exists ${$HEADER{$lang}}{"content"} + || !exists ${$HEADER{$lang}}{"date"} + || ${$HEADER{$lang}}{"date"} < ($_ = (stat ${$HEADER{$lang}}{"file"})[9])) { + $_ = (stat ${$HEADER{$lang}}{"file"})[9] if !defined $_; + ${$HEADER{$lang}}{"date"} = $_; + ${$HEADER{$lang}}{"content"} = hcref_decode ln($lang, LN_CHARSET), xfread ${$HEADER{$lang}}{"file"}; + } + push @sections, ${$HEADER{$lang}}{"content"}; + + # Print the language switching links + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_langs $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + push @sections, $_ if $_ ne ""; + + # Print the section-specific navigation links + push @sections, $$args{"header_html_nav"} + if exists $$args{"header_html_nav"}; + + # Print the log-in information + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_login $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + push @sections, $_ if $_ ne ""; + + # Print the section-specific navigation bar + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + if ($$args{"admin"}) { + html_nav_admin $args; + } else { + html_nav_page $args; + } + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + push @sections, $_ if $_ ne ""; + + # Embrace the navigation links + print << "EOT"; + +
    + +EOT + + return; +} + +# html_langs: Print the language switching links +sub html_langs(;$) { + local ($_, %_); + my ($args, $guide); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + # The accessibility guide + $guide = h(__("Language Switching Area")); + + # Special note on the English literal works pages + if ($$args{"path"} =~ /^\/writings-en\//) { + print << "EOT"; +

    抱歉,這裡沒有中文翻譯。

    +EOT + return; + } + + # Compose each link piece + if (@{$$args{"all_linguas"}} > 0) { + @_ = qw(); + foreach my $lang (@{$$args{"all_linguas"}}) { + # No link for the current language + if ($lang eq $$args{"lang"}) { + push @_, " " . h(ln($lang, LN_DESC_SELFLC)) . ""; + } else { + push @_, " " + . h(ln($lang, LN_DESC_SELFLC)) . ""; + } + } + $_ = join " |\n", @_; + print << "EOT"; +
    +$_ +
    +EOT + } + + # Special note on the Chinese literal works pages + print << "EOT" if $$args{"path"} =~ /^\/writings-zh\//; +

    I’m paperrose. Sorry, English is not available here.

    +EOT + return; +} + +# html_login: Print the HTML log-in information +sub html_login(;$) { + local ($_, %_); + my ($args, $msg, $modify, $submit); + $args = $_[0]; + # Skip if not logged-in + return if !defined get_login_sn; + # Obtain the page parameters + $args = page_param $args; + # No log-in links for static pages + return if $$args{"static"}; + + # The message + $modify = "/magicat/cgi-bin/users.cgi?form=cur&sn=" . get_login_sn; + $msg = sprintf __("Welcome, %s. (Modify)"), + h(get_login_name), h($modify); + $submit = h(__("Log out")); + + print << "EOT"; + +EOT + return; +} + +# html_nav_admin: Print the HTML administrative navigation links +sub html_nav_admin(;$) { + local ($_, %_); + my ($args, $cgidir, $path, $title); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + + # Find the current CGI directory + $cgidir = "cgi-bin"; + $cgidir = $1 if $REQUEST_PATH =~ /\/(cgi-[a-z0-9]+)\/[a-z0-9]+\.cgi$/; + # Output them + foreach my $cat (@ADMIN_SCRIPTS) { + @_ = qw(); + foreach (@{$$cat{"sub"}}) { + next unless is_script_permitted $$_{"path"}; + ($path, $title) = ($$_{"path"}, $$_{"title"}); + # Fix the path to use the same cgi-* directory alias + $path =~ s/\/cgi-[a-z0-9]+\/([a-z0-9]+\.cgi)$/\/$cgidir\/$1/; + # Fix the path of the HTTPS scripts to use HTTPS + $path = "https://" . https_host . "/$PACKAGE$path" + if exists $$_{"https"} && $$_{"https"} && !is_https; + push @_, sprintf(" %s", + h($path), h_abbr(__($title))); + } + next if @_ == 0; + $title = $$cat{"title"}; + $_ = sprintf(__("%s:"), h_abbr(__($title))); + print "
    \n" + . $_ . "\n" . join(" |\n", @_) . "\n" + . "
    \n" + if @_ > 0; + } + return; +} + +# html_nav_page: Print the HTML page navigation links +sub html_nav_page(;$) { + local ($_, %_); + my ($args, $tree); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + # Obtain the page tree + $tree = merged_tree $$args{"path"}, $$args{"lang"}, $$args{"preview"}; + # Bounce for nothing + return if !defined $tree + || !exists $$tree{"pages"} + || !defined $$tree{"pages"} + || @{$$tree{"pages"}} <= 1; + + # Output them + print << "EOT"; + +EOT + return; +} + +# html_body: Print the HTML body +sub html_body($;$) { + local ($_, %_); + my ($page, $args); + ($page, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Output the picture + # To be done + + # Output the content + print "" . (!exists $$page{"html"} || !$$page{"html"}? + a2html($$page{"body"}): $$page{"body"}) . "\n\n"; + + return; +} + +# html_links: Print the HTML links list +sub html_links($;$) { + local ($_, %_); + my ($page, $args, $lndb, $lndbdef); + ($page, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + $lndb = ln $$args{"lang"}, LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + + # Output the breadcrumb trai + @_ = qw(); + push @_, "" . h(__("Keep Travelling")) . ""; + foreach my $parent (@{$$page{"parents"}}) { + $_ = defined $$parent{"title_$lndb"}? + $$parent{"title_$lndb"}: $$parent{"title_$lndbdef"}; + push @_, "" . h($_) . ""; + } + push @_, h($$page{"title"}); + print "
    \n" + . join(" /\n", @_) . "\n
    \n\n"; + + # Output the subcategories + if (@{$$page{"scats"}} > 0) { + print << "EOT"; +
    +
    +
    +
      +EOT + # Output the even half + for ($_ = 0; $_ < @{$$page{"scats"}}; $_ += 2) { + my ($cat, $title); + $cat = ${$$page{"scats"}}[$_]; + $title = defined $$cat{"title_$lndb"}? + $$cat{"title_$lndb"}: $$cat{"title_$lndbdef"}; + $title = h($title); + $title .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
    • $title
    • \n"; + } + print << "EOT"; +
    +
    +
    +EOT + if (@{$$page{"scats"}} > 1) { + print << "EOT"; +
    +
    +
      +EOT + # Output the odd half + for ($_ = 1; $_ < @{$$page{"scats"}}; $_ += 2) { + my ($cat, $title); + $cat = ${$$page{"scats"}}[$_]; + $title = defined $$cat{"title_$lndb"}? + $$cat{"title_$lndb"}: $$cat{"title_$lndbdef"}; + $title = h($title); + $title .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
    • $title
    • \n"; + } + print << "EOT"; +
    +
    +
    +EOT + } + print << "EOT"; +
    + +EOT + } + + # Output the links + if (@{$$page{"links"}} > 0) { + my $emailalt; + $emailalt = h(__("E-mail")); + print "
      \n"; + foreach my $link (@{$$page{"links"}}) { + my ($url, $title, $ctitle, $dsc); + $url = h($$link{"url"}); + $title = h($$link{"title"}); + print "
    1. \n"; + print "
      \n
      \n" + if defined $$link{"email"}; + # Output the link icon + print "\"$title\"
      \n" + if defined $$link{"icon"}; + # Output the site title + $ctitle = is_usascii_printable($$link{"title"})? + "$title": $title; + if (defined $$link{"title_2ln"}) { + $_ = h($$link{"title_2ln"}); + $_ = "$_" + if is_usascii_printable($$link{"title_2ln"}); + $ctitle .= " $_"; + } + print "$ctitle
      \n"; + # Output the URL + print __("URL:") . " $url
      \n"; + # Output other information + if (defined $$link{"email"}) { + print __("E-mail:") . " "; + print "\n"; + print "\n"; + print mung_email_span(h($$link{"email"})) . "
      \n"; + } + print __("Address:") . " " . h($$link{"addr"}) . "
      \n" + if defined $$link{"addr"}; + print __("Tel.:") . " " . h($$link{"tel"}) . "
      \n" + if defined $$link{"tel"}; + print __("Fax.:") . " " . h($$link{"fax"}) . "
      \n" + if defined $$link{"fax"}; + # Output the description + $dsc = defined $$link{"dsc_$lndb"}? $$link{"dsc_$lndb"}: + $$link{"dsc_$lndbdef"}; + print h($dsc) . "
      \n"; + print "
      \n
      \n" if defined $$link{"email"}; + print "
    2. \n\n"; + } + print "
    \n\n"; + } + + # Print the link registration form + html_links_register $args; + return; +} + +# html_links_index: Print the HTML link categories index +sub html_links_index(\@;$) { + local ($_, %_); + my ($cats, $args, $lndb, $lndbdef, $p1, $p2); + ($cats, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + $lndb = ln $$args{"lang"}, LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + + # Display the foreword + $p1 = h(__("Are you ready to check out? Just drop your room key at the counter, and travel for your next stop. Life is a never-ending trip, and Tavern is only one of your many stops. Are you ready to go now?")); + $p2 = h(__("Greetings, traveller. I'm rinse the Tavern Tour Agent. Where is your next stop?")); + print << "EOT"; +
    +

    $p1

    + +

    $p2

    +
    + +EOT + + # Bounce for nothing + if (@$cats == 0) { + print "

    " . h(__("The database is empty.")) . "

    \n\n"; + return; + } + + # Output the root categories + print << "EOT"; +
    +
    +
    +
      +EOT + # Output the even half + for ($_ = 0; $_ < @$cats; $_ += 2) { + my ($cat, $title); + $cat = $$cats[$_]; + $title = defined $$cat{"title_$lndb"}? + $$cat{"title_$lndb"}: $$cat{"title_$lndbdef"}; + $title = h($title); + $title .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
    • $title
    • \n"; + } + print << "EOT"; +
    +
    +
    +EOT + if (@$cats > 1) { + print << "EOT"; +
    +
    +
      +EOT + # Output the odd half + for ($_ = 1; $_ < @$cats; $_ += 2) { + my ($cat, $title); + $cat = $$cats[$_]; + $title = defined $$cat{"title_$lndb"}? + $$cat{"title_$lndb"}: $$cat{"title_$lndbdef"}; + $title = h($title); + $title .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
    • $title
    • \n"; + } + print << "EOT"; +
    +
    +
    +EOT + } + print << "EOT"; +
    + +EOT + # Print the link registration form + html_links_register $args; + return; +} + +# html_links_register: Print the HTML link registration form +sub html_links_register(;$) { + local ($_, %_); + my ($args, $subject, $summary, $defdsc, $h, $p1, $p2, $p3, %t); + $args = $_[0]; + # Obtain page parameters + $args = page_param $args; + + $subject = uri_escape(encode(ln($$args{"lang"}, LN_CHARSET), __("~[Tavern~] Website Registration"), FB_HTMLCREF)); + $summary = h(__("This table provide a form to register your site at Tavern \"Keep Travelling\", the data column names and their input fields to fill in the information.")); + $defdsc = h(__("Fill in the description here.")); + $h = h(__("Regiser your site")); + $p1 = __("I sincerely wish to build more hyperlinks with websites that're kind to women/lesbian/queer. If you wish to link with me, or if you have any such information, whether in Chinese or not, please tell me by filling this form below. I'll put it in as soon as possible. Thank you."); + $p2 = __("All fields in the form below, Except for the site name, the URL and the description, are optional. Anything you fill here will be shown to ANYONE who visits Tavern IMACAT's. Tavern does not collect any personal informations. If you do not wish to distribute some private informations, just leave them blank. If you represent some organization, fill as detail as possible to help others finding you."); + $p3 = __("General commercial sites besides lesbian shops are not welcome."); + + $t{"title"} = h(__("Site name:")); + $t{"title_2ln"} = h(__("Site name, 2nd language (if any):")); + $t{"url"} = h(__("Site URL:")); + $t{"icon"} = h(__("Link logo URL:")); + $t{"cat"} = h(__("Category:")); + $t{"dsc"} = h(__("Introduction:")); + $t{"email"} = h(__("E-mail:")); + $t{"addr"} = h(__("Address:")); + $t{"tel"} = h(__("Tel.:")); + $t{"fax"} = h(__("Fax.:")); + $t{"submit"} = h(__("OK!")); + + print << "EOT"; +
    +

    $h

    + +
    +

    $p1

    + +

    $p2

    + +

    $p3

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +EOT + return; +} + +# html_diary_index: Print the HTML diary index +sub html_diary_index(\@;$) { + local ($_, %_); + my ($pages, $args, $parent, $here); + ($pages, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Bounce for nothing + if (@$pages == 0) { + print "

    " . h(__("The diary is empty.")) . "

    \n\n"; + return; + } + + # Output the breadcrumb trai + $parent = __("imacat's Private Bed♥room"); + $here = h(__("Tavern Diary")); + print << "EOT"; + + +EOT + + # Output the index + $_ = h(__("Index")); + print << "EOT"; +

    $_

    + +
      +EOT + foreach my $page (reverse @$pages) { + my ($title, $url, $start, $end); + if ($$args{"lang"} eq "zh-tw") { + Lingua::ZH::Numbers->charset("traditional"); + $_ = number_to_zh($$page{"no"}); + } elsif ($$args{"lang"} eq "zh-cn") { + Lingua::ZH::Numbers->charset("simplified"); + $_ = number_to_zh($$page{"no"}); + } else { + $_ = fmtno($$page{"no"}); + } + $title = h(sprintf __("Tavern Diary Volume %s"), $_); + $url = h($$page{"path"}); + $start = h(myfmtdate $$page{"start"}); + $end = h(myfmtdate $$page{"end"}); + print << "EOT"; +
    1. $title

      +
      $start - $end
    2. + +EOT + } + print << "EOT"; +
    + +EOT + return; +} + +# html_changelog_index: Print the HTML change log index +sub html_changelog_index(\@;$) { + local ($_, %_); + my ($pages, $args, $parent, $here); + ($pages, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Bounce for nothing + if (@$pages == 0) { + print "

    " . h(__("The change log is empty.")) . "

    \n\n"; + return; + } + + # Output the breadcrumb trai + $parent = __("imacat's Private Bed♥room"); + $here = h(__("Tavern Change Log")); + print << "EOT"; + + +EOT + + # Output the index + $_ = h(__("Index")); + print << "EOT"; +

    $_

    + +
      +EOT + foreach my $page (reverse @$pages) { + my ($title, $url, $start, $end); + if ($$args{"lang"} eq "zh-tw") { + Lingua::ZH::Numbers->charset("traditional"); + $_ = number_to_zh($$page{"no"}); + } elsif ($$args{"lang"} eq "zh-cn") { + Lingua::ZH::Numbers->charset("simplified"); + $_ = number_to_zh($$page{"no"}); + } else { + $_ = fmtno($$page{"no"}); + } + $title = h(sprintf __("Tavern Change Log Volume %s"), $_); + $url = h($$page{"path"}); + $start = h(myfmtdate $$page{"start"}); + $end = h(myfmtdate $$page{"end"}); + print << "EOT"; +
    1. $title

      +
      $start - $end
    2. + +EOT + } + print << "EOT"; +
    + +EOT + return; +} + +# html_ltzh_pagebar: Print the HTML Chinese literal work page navigation bar +sub html_ltzh_pagebar($\@;$) { + local ($_, %_); + my ($cur, $all, $args, $start, $end); + my ($FD, $html, $cell); + ($cur, $all, $args) = @_; + + # Fit in one page - paging is not needed + return unless @$all > 1; + + # Obtain page parameters + $args = page_param $args; + + # Fewer than 7 pages + if (@$all <= 7) { + $start = 0; + $end = $#$all; + # Near the beginning + } elsif ($cur < 4) { + $start = 0; + $end = 6; + # Near the end + } elsif ($cur > $#$all - 3) { + $start = $#$all - 6; + $end = $#$all; + # Normal, at the middle + } else { + $start = $cur - 3; + $end = $cur + 3; + } + + # Start output + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + print "
    \n"; + # The index + print " 目錄 |\n"; + # The first page + $cell = h("第一篇"); + if ($cur != 0) { + $cell = "" + . $cell . ""; + } + print " $cell |\n"; + # The previous page + $cell = h("前一篇"); + if ($cur != 0) { + $cell = "" + . $cell . ""; + } + print " $cell |\n"; + + # Pages before + for ($_ = $start; $_ < $cur; $_++) { + print " " + . h($_ + 1) . " |\n"; + } + # Current page + print " " . h($cur + 1) . " |\n"; + # Pages after + for ($_ = $cur + 1; $_ <= $end; $_++) { + print " " + . h($_ + 1) . " |\n"; + } + + # The next page + $cell = h("下一篇"); + if ($cur != $#$all) { + $cell = "" + . $cell . ""; + } + print " $cell |\n"; + # The last page + $cell = h("最新篇"); + if ($cur != $#$all) { + $cell = "" + . $cell . ""; + } + print " $cell\n"; + print "
    "; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + + $_ = all_to_simp $_ if $$args{"lang"} eq "zh-cn"; + + print $_; + + return; +} + +# html_ltzh_body: Print the HTML Chinese literal work +sub html_ltzh_body($;$) { + local ($_, %_); + my ($page, $args, $lndb, @poems, @htmls); + ($page, $args) = @_; + # Obtain page parameters + $args = page_param $args; + # Set the language + $lndb = ln($$args{"lang"}, LN_DATABASE); + + # Obtain the poems + if (defined $$args{"preview"}) { + for ($_ = 0, @poems = qw(); exists $$page{"poem$_" . "title"}; $_++) { + push @poems, { + "sn" => $$page{"poem$_" . "sn"}, + "title_$lndb" => $$page{"poem$_" . "title"}, + "body_$lndb" => $$page{"poem$_" . "body"}, + } if exists $$page{"poem$_"} + && !(exists $$page{"poem$_" . "hid"} + && $$page{"poem$_" . "hid"}); + } + } else { + @poems = @{$$page{"poems"}}; + } + + # No poems + return if @poems == 0; + + # Output each poem + @htmls = qw(); + foreach my $poem (@poems) { + my ($sn, $title, $body); + ($sn, $title, $body) = (h($$poem{"sn"}), h($$poem{"title_$lndb"}), h($$poem{"body_$lndb"})); + push @htmls, << "EOT"; +
    +

    $title

    +
    $body
    +
    +EOT + } + print "
    \n\n" + . join("
    \n\n", @htmls) . "
    \n\n"; + return; +} + +# html_ltzh_index: Print the HTML index of the Chinese literal work +sub html_ltzh_index($;$) { + local ($_, %_); + my ($page, $args, $sql, $sth, $count, $row, @works, @htmls); + ($page, $args) = @_; + # Obtain page parameters + $args = page_param $args; + + # Obtain the literal works + if (exists $$page{"allworks"}) { + @works = @{$$page{"allworks"}}; + } else { + $sql = "SELECT date, title, dsc FROM literalzh" + . " WHERE NOT hid" + . " ORDER BY date;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @works = qw(); $i < $count; $i++) { + $row = $sth->fetchrow_hashref; + @_ = localtime $$row{"date"}; + $_[5] += 1900; + $_[4]++; + $$row{"path"} = sprintf("/writings-zh/%04d%02d%02d.html", @_[5,4,3]); + $$row{"title"} = myfmtdate($$row{"date"}) + . (defined $$row{"title"}? " " . $$row{"title"}: ""); + if ($$args{"lang"} eq "zh-cn") { + $$row{$_} = all_to_simp($$row{$_}) foreach qw(title dsc); + } + push @works, $row; + } + } + + # Output the index + if (@works == 0) { + print << "EOT"; +
    +
    + +EOT + } else { + @htmls = qw(); + $_ = "以下不按標題分類,而按日期分類。許多日期是後來推算的,有點疑問。"; + $_ = all_to_simp($_) if $$args{"lang"} eq "zh-cn"; + push @htmls, "

    " . h($_) . "

    "; + foreach my $work (reverse @works) { + my ($url, $title, $dsc); + ($url, $title, $dsc) = (h($$work{"path"}), h($$work{"title"}), h($$work{"dsc"})); + $title =~ s/^(\d+\.\d+\.’\d+\.)/ $1<\/span>/; + push @htmls, << "EOT"; +

    $title

    +

    $dsc

    +EOT + } + print "
    \n\n" + . join("\n\n", @htmls) . "
    \n\n"; + } + + # Output the introduction + print "
    \n\n"; + print "" . (!exists $$page{"html"} || !$$page{"html"}? + a2html($$page{"body"}): $$page{"body"}) . "\n\n"; + print "
    \n\n"; + + return; +} + +# html_lten_pagebar: Print the HTML English literal work page navigation bar +sub html_lten_pagebar($\@;$) { + local ($_, %_); + my ($cur, $all, $args, $start, $end,); + my ($FD, $html, $cell); + ($cur, $all, $args) = @_; + + # Fit in one page - paging is not needed + return unless @$all > 1; + + # Obtain page parameters + $args = page_param $args; + + # Fewer than 7 pages + if (@$all <= 7) { + $start = 0; + $end = $#$all; + # Near the beginning + } elsif ($cur < 4) { + $start = 0; + $end = 6; + # Near the end + } elsif ($cur > $#$all - 3) { + $start = $#$all - 6; + $end = $#$all; + # Normal, at the middle + } else { + $start = $cur - 3; + $end = $cur + 3; + } + + # Start output + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + print "
    \n"; + # The index + print " Index |\n"; + # The first page + $cell = h("First"); + if ($cur != 0) { + $cell = "" + . $cell . ""; + } + print " $cell |\n"; + # The previous page + $cell = h("Previous"); + if ($cur != 0) { + $cell = "" + . $cell . ""; + } + print " $cell |\n"; + + # Pages before + for ($_ = $start; $_ < $cur; $_++) { + print " " + . h($_ + 1) . " |\n"; + } + # Current page + print " " . h($cur + 1) . " |\n"; + # Pages after + for ($_ = $cur + 1; $_ <= $end; $_++) { + print " " + . h($_ + 1) . " |\n"; + } + + # The next page + $cell = h("Next"); + if ($cur != $#$all) { + $cell = "" + . $cell . ""; + } + print " $cell |\n"; + # The last page + $cell = h("Latest"); + if ($cur != $#$all) { + $cell = "" + . $cell . ""; + } + print " $cell\n"; + print "
    "; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + + $_ = all_to_simp $_ if $$args{"lang"} eq "zh-cn"; + + print $_; + + return; +} + +# html_lten_index: Print the HTML index of the English literal work +sub html_lten_index($;$) { + local ($_, %_); + my ($page, $args); + ($page, $args) = @_; + # Obtain page parameters + $args = page_param $args; + + # Output the index + print join "\n\n", map sprintf("

    %s

    \n\n" + . "

    %s

    ", + h($$_{"path"}), h($$_{"title"}), h($$_{"dsc"})), + reverse @{$$page{"allworks"}}; + return; +} + +# html_footer: Print the HTML footer +sub html_footer(;$) { + local ($_, %_); + my ($args, $lang); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + $lang = $$args{"lang"}; + + # Embrace the content + print << "EOT"; +
    + +EOT + # Print the section-specific navigation bar + print "
    \n" . $$args{"footer_html_nav"} . "\n\n" + if exists $$args{"footer_html_nav"}; + + # Print the common footer + $FOOTER{$lang} = {} if !exists $FOOTER{$lang}; + ${$FOOTER{$lang}}{"file"} = sprintf("%s/magicat/include/footer.%s.html", + $DOC_ROOT, ln($lang, LN_FILENAME)) + if !exists ${$FOOTER{$lang}}{"file"}; + undef $_; + if ( !exists ${$FOOTER{$lang}}{"content"} + || !exists ${$FOOTER{$lang}}{"date"} + || ${$FOOTER{$lang}}{"date"} < ($_ = (stat ${$FOOTER{$lang}}{"file"})[9])) { + $_ = (stat ${$FOOTER{$lang}}{"file"})[9] if !defined $_; + ${$FOOTER{$lang}}{"date"} = $_; + ${$FOOTER{$lang}}{"content"} = hcref_decode ln($lang, LN_CHARSET), xfread ${$FOOTER{$lang}}{"file"}; + } + $_ = ${$FOOTER{$lang}}{"content"}; + ${$FOOTER{$lang}}{"perl"} = {} if !exists ${$FOOTER{$lang}}{"perl"}; + if ($$args{"static"}) { + s/\n+\n+/\n\n/; + } elsif ($IS_MODPERL) { + if (!exists ${${$FOOTER{$lang}}{"perl"}}{"modperl"}) { + ${${$FOOTER{$lang}}{"perl"}}{"modperl"} = << "EOT"; +
    +%s +

    %s

    +
    +EOT + ${${$FOOTER{$lang}}{"perl"}}{"modperl"} = sprintf(${${$FOOTER{$lang}}{"perl"}}{"modperl"}, + h(__("mod_perl -- Speed, Power, Scalability")), + __("This script is written in Perl and optimized for mod_perl.")); + ${${$FOOTER{$lang}}{"perl"}}{"modperl"} =~ s/()/$1 hreflang="en"$2/g + if $lang ne "en"; + } + s/\n/${${$FOOTER{$lang}}{"perl"}}{"modperl"}/; + } else { + if (!exists ${${$FOOTER{$lang}}{"perl"}}{"cgi"}) { + ${${$FOOTER{$lang}}{"perl"}}{"cgi"} = << "EOT"; +
    +

    %s

    +
    +EOT + ${${$FOOTER{$lang}}{"perl"}}{"cgi"} = sprintf(${${$FOOTER{$lang}}{"perl"}}{"cgi"}, + __("This script is written in
    Perl.")); + ${${$FOOTER{$lang}}{"perl"}}{"cgi"} =~ s/()/$1 hreflang="en"$2/g + if $lang ne "en"; + } + s/\n/${${$FOOTER{$lang}}{"perl"}}{"cgi"}/; + } + print $_; + + # Show the HTML preview mark + html_preview_mark $args; + + print "\n\n\n"; + return; +} + +# merged_tree: Get the page tree in a directory +sub merged_tree($$;$) { + local ($_, %_); + my ($path, $lang, $preview); + ($path, $lang, $preview) = @_; + + # Return special areas + if ($path =~ /^\/links\//) { + return link_tree($path, $lang, $preview); + # Non-pages (scripts... etc) + } else { + return {}; + } +} + +no utf8; +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Items.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Items.pm new file mode 100644 index 0000000..085febe --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Items.pm @@ -0,0 +1,279 @@ +# Tavern IMACAT's +# Items.pm: The data record related subroutines. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-22 + +package Selima::imacat::Items; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(markabbr_site literalzh_title literalzh_date); +push @EXPORT, qw(pprtype_title pprtype_options paper_title); +push @EXPORT, qw(researcher_name abbreviate_name tag_title); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub markabbr_site($); +sub literalzh_title($); +sub literalzh_date($); +sub pprtype_title($); +sub pprtype_options($); +sub paper_title($); +sub researcher_name($); +sub abbreviate_name($); +sub tag_title($); +} + +use Selima::ChkFunc; +use Selima::CommText; +use Selima::DataVars qw($DBH :l10n :lninfo); +use Selima::EchoForm; +use Selima::GetLang; +use Selima::LnInfo; + +# markabbr_site: Mark the abbreviation, site extension +sub markabbr_site($) { + local ($_, %_); + $_ = $_[0]; + + # CPAN/PEAR + s/\b(CPAN)\b(?!<\/abbr>|<\/acronym>)/$1<\/acronym>/g; + s/\b(PEAR)\b(?!<\/abbr>|<\/acronym>)/$1<\/acronym>/g; + # SARS + s/\b(SARS)\b(?!<\/abbr>|<\/acronym>)/$1<\/acronym>/g; + # DOI + s/\b(DOI)\b(?!<\/abbr>|<\/acronym>)/$1<\/acronym>/g; + return $_; +} + +# literalzh_title: Obtain a Chinese literal work title +sub literalzh_title($) { + local ($_, %_); + my ($sn, $sql, $sth, $col, $row); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + + # Check the serial number first + return t_na if !check_sn $sn; + + # Query + @_ = qw(); + push @_, "'詩 '"; + push @_, "extract(month FROM date)"; + push @_, "'.'"; + push @_, "extract(day FROM date)"; + push @_, "'.’'"; + push @_, "substring(extract(year FROM date) FROM 3 FOR 2)"; + push @_, "CASE WHEN title IS NULL THEN '' ELSE " + . $DBH->strcat("' '", "title") . " END"; + $_ = $DBH->strcat(@_) . " AS title"; + $sql = "SELECT $_ FROM literalzh" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return t_na unless $sth->rows == 1; + + # Found + return ${$sth->fetch}[0]; +} + +# literalzh_date: Obtain a Chinese literal work date +sub literalzh_date($) { + local ($_, %_); + my ($sn, $sql, $sth, $col, $row); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + + # Check the serial number first + return t_na if !check_sn $sn; + + # Query + $sql = "SELECT to_char(date, 'YYYY-MM-DD') AS date FROM literalzh" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return t_na unless $sth->rows == 1; + + # Found + return ${$sth->fetch}[0]; +} + +# pprtype_title: Obtain a paper type title +sub pprtype_title($) { + local ($_, %_); + my ($sn, $sql, $sth, $row, $thiscol, $defcol, $title); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + + # Check the serial number first + return t_na if !check_sn $sn; + + # Query + # Unilingual + if (@ALL_LINGUAS == 1) { + $title = "title AS title"; + # Multilingual + } else { + $thiscol = "title_" . getlang(LN_DATABASE); + # Default language + if (getlang eq $DEFAULT_LANG) { + $title = "$thiscol AS title"; + # Fall back to the default language + } else { + $defcol = "title_" . ln($DEFAULT_LANG, LN_DATABASE); + $title = "COALESCE($thiscol, $defcol) AS title"; + } + } + $sql = "SELECT $title FROM pprtypes" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return t_na unless $sth->rows == 1; + + # Found + return ${$sth->fetch}[0]; +} + +# pprtype_options: Obtain a paper types options list +sub pprtype_options($) { + local ($_, %_); + my ($value, $sql, $thiscol, $defcol, $content); + $value = $_[0]; + + # Unilingual + if (@ALL_LINGUAS == 1) { + $content = "title AS content"; + # Multilingual + } else { + $thiscol = "title_" . getlang(LN_DATABASE); + # Default language + if (getlang eq $DEFAULT_LANG) { + $content = "$thiscol AS content"; + # Fall back to the default language + } else { + $defcol = "title_" . ln($DEFAULT_LANG, LN_DATABASE); + $content = "COALESCE($thiscol, $defcol) AS content"; + } + } + $sql = "SELECT sn AS value, $content FROM pprtypes" + . " ORDER BY ord;\n"; + return opt_list $sql, $value; +} + +# paper_title: Obtain a paper title +sub paper_title($) { + local ($_, %_); + my ($sn, $sql, $sth, $row, $title); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + + # Check the serial number first + return t_na if !check_sn $sn; + + # Query + $title = $DBH->strcat("CAST(year AS text)", "' - '", "title") + . " AS title"; + $sql = "SELECT $title FROM papers" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return t_na unless $sth->rows == 1; + + # Found + return ${$sth->fetch}[0]; +} + +# researcher_name: Obtain a researcher name +sub researcher_name($) { + local ($_, %_); + my ($sn, $sql, $sth, $row); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + + # Check the serial number first + return t_na if !check_sn $sn; + + # Query + $sql = "SELECT name FROM resrcher" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return t_na unless $sth->rows == 1; + + # Found + return ${$sth->fetch}[0]; +} + +# abbreviate_name: Abbreviate a researcher name +sub abbreviate_name($) { + local ($_, %_); + my ($name, $first, $last); + $name = $_[0]; + if ($name !~ /^(.*)\s+(\S+)$/) { + return $name; + } + ($first, $last) = ($1, $2); + $first =~ s/\b([A-Z])([a-z]+)\b/$1./g; + return "$last, $first"; +} + +# tag_title: Obtain a tag title +sub tag_title($) { + local ($_, %_); + my ($sn, $sql, $sth, $row); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + + # Check the serial number first + return t_na if !check_sn $sn; + + # Query + $sql = "SELECT title FROM tags" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return t_na unless $sth->rows == 1; + + # Found + return ${$sth->fetch}[0]; +} + +no utf8; +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/L10N.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/L10N.pm new file mode 100644 index 0000000..d136178 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/L10N.pm @@ -0,0 +1,58 @@ +# Tavern IMACAT's +# L10N.pm: The localization class. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-26 + +package Selima::imacat::L10N; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +return 1; + +# The Chinese (Taiwan) localized messages. +package Selima::imacat::L10N::zh_tw; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +sub numerate : method { $_[2] } + +return 1; + +# The Chinese (China) localized messages. +package Selima::imacat::L10N::zh_cn; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +sub numerate : method { $_[2] } + +return 1; + +# The English localized messages. +package Selima::imacat::L10N::en; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm new file mode 100644 index 0000000..4e54a21 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm @@ -0,0 +1,100 @@ +# Tavern IMACAT's +# ChangeLog.pm: The administrative change log list. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-24 + +package Selima::imacat::List::ChangeLog; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "changelog" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select an Change Log Entry"): + __("Manage Change Log"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "created"; + # Columns that should display its brief instead + $self->{"COLS_BRIEF"} = [qw(body)]; + # Columns should be displayed in a reversed order + $self->{"reverse"} = 1; + # The list brief size + $self->{"DEFAULT_BRIEF_LEN"} = 20; + # Column labels + $self->col_labels( + "pageno" => __("Page No."), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Write a new log entry.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a log entry:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,log entry,log entries].", $self->{"total"}); + # List result + } else { + return __("[*,_1,log entry,log entries].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,log entry,log entries], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/ChangeLog/Public.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/ChangeLog/Public.pm new file mode 100644 index 0000000..428595a --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/ChangeLog/Public.pm @@ -0,0 +1,153 @@ +# Tavern IMACAT's +# Public.pm: The change log list. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-24 + +package Selima::imacat::List::ChangeLog::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use Selima::A2HTML; +use Selima::DataVars qw($DBH :lninfo); +use Selima::Format; +use Selima::LnInfo; +use Selima::PageFunc qw(); +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "changelog" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # Columns should be displayed in a reversed order + $self->{"reverse"} = 1; + # These are static pages + $self->{"static"} = 1; + $self->{"static_lastfile"} = "latest.html"; + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, $table, $sth, $sql, $error); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + + # The view name + $table = $DBH->quote_identifier($self->{"view"}); + + # Obtain everything in this page + $self->{"current"} = []; + # Always reverse + $self->{"select"} = "SELECT * FROM $table" + . " WHERE pageno=" . $self->{"pageno"} . ";\n"; + $sql = $self->{"select"}; + $sth = $DBH->prepare($sql); + $sth->execute; + push @{$self->{"current"}}, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + + # Done + return $self->{"error"}; +} + +# page_param: Obtain page parameters +sub page_param : method { + local ($_, %_); + my ($self, $args); + $self = $_[0]; + # Run the parent method + $args = $self->SUPER::page_param; + # Add the page bar to the page parameters + if (defined $args && $self->{"lastpage"} > 1) { + my $FD; + # Obtain the page bar + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + $self->html_pagebar; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $$args{"header_html_nav"} = join "", <$FD>; + $$args{"header_html_nav"} =~ s/\s+$//; + $$args{"footer_html_nav"} = $$args{"header_html_nav"}; + } + return $args; +} + +# html: Output the list +sub html : method { + local ($_, %_); + my ($self, $args); + ($self, $args) = @_; + # Obtain the page parameters + $args = Selima::PageFunc::page_param $args; + # Fetch the current list if not fetched yet + $self->fetch if !$self->{"fetched"}; + + # List the items + $self->html_list($args); + + return; +} + +# html_list: List the items +sub html_list : method { + local ($_, %_); + my ($self, $args, @htmls); + ($self, $args) = @_; + # Obtain the page parameters + $args = Selima::PageFunc::page_param $args; + # No record to be listed + return if $self->{"total"} == 0; + + foreach my $current (@{$self->{"current"}}) { + my $h; + $h = ""; + $h .= "
    \n"; + $h .= "
    " . h(__("Date:")) . " " . myfmtdate($$current{"date"}) . "
    \n\n"; + if ($$current{"html"}) { + $h .= $$current{"body"} . "\n\n"; + } else { + $h .= "
    \n" . a2html($$current{"body"}) . "\n
    \n\n"; + } + $h .= "
    \n\n"; + push @htmls, $h; + } + + $_ = h(__("The change log entry seperator")); + print "
    \n\n
    \n\n" + . join("
    \n\n", @htmls) . "
    \n\n"; + + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Diary.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Diary.pm new file mode 100644 index 0000000..5032f31 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Diary.pm @@ -0,0 +1,100 @@ +# Tavern IMACAT's +# Diary.pm: The administrative diary list. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-17 + +package Selima::imacat::List::Diary; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "diary" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Diary Entry"): + __("Manage Diary"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "created"; + # Columns that should display its brief instead + $self->{"COLS_BRIEF"} = [qw(body)]; + # Columns should be displayed in a reversed order + $self->{"reverse"} = 1; + # The list brief size + $self->{"DEFAULT_BRIEF_LEN"} = 20; + # Column labels + $self->col_labels( + "pageno" => __("Page No."), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Write a new diary entry.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a diary entry:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,diary entry,diary entries].", $self->{"total"}); + # List result + } else { + return __("[*,_1,diary entry,diary entries].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,diary entry,diary entries], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,diary entry,diary entries], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Diary/Public.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Diary/Public.pm new file mode 100644 index 0000000..999fbe5 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Diary/Public.pm @@ -0,0 +1,153 @@ +# Tavern IMACAT's +# Public.pm: The diary list. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-18 + +package Selima::imacat::List::Diary::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use Selima::A2HTML; +use Selima::DataVars qw($DBH :lninfo); +use Selima::Format; +use Selima::LnInfo; +use Selima::PageFunc qw(); +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "diary" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # Columns should be displayed in a reversed order + $self->{"reverse"} = 1; + # These are static pages + $self->{"static"} = 1; + $self->{"static_lastfile"} = "latest.html"; + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, $table, $sth, $sql, $error); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + + # The view name + $table = $DBH->quote_identifier($self->{"view"}); + + # Obtain everything in this page + $self->{"current"} = []; + # Always reverse + $self->{"select"} = "SELECT * FROM $table" + . " WHERE pageno=" . $self->{"pageno"} . ";\n"; + $sql = $self->{"select"}; + $sth = $DBH->prepare($sql); + $sth->execute; + push @{$self->{"current"}}, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + + # Done + return $self->{"error"}; +} + +# page_param: Obtain page parameters +sub page_param : method { + local ($_, %_); + my ($self, $args); + $self = $_[0]; + # Run the parent method + $args = $self->SUPER::page_param; + # Add the page bar to the page parameters + if (defined $args && $self->{"lastpage"} > 1) { + my $FD; + # Obtain the page bar + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + $self->html_pagebar; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $$args{"header_html_nav"} = join "", <$FD>; + $$args{"header_html_nav"} =~ s/\s+$//; + $$args{"footer_html_nav"} = $$args{"header_html_nav"}; + } + return $args; +} + +# html: Output the list +sub html : method { + local ($_, %_); + my ($self, $args); + ($self, $args) = @_; + # Obtain the page parameters + $args = Selima::PageFunc::page_param $args; + # Fetch the current list if not fetched yet + $self->fetch if !$self->{"fetched"}; + + # List the items + $self->html_list($args); + + return; +} + +# html_list: List the items +sub html_list : method { + local ($_, %_); + my ($self, $args, @htmls); + ($self, $args) = @_; + # Obtain the page parameters + $args = Selima::PageFunc::page_param $args; + # No record to be listed + return if $self->{"total"} == 0; + + foreach my $current (@{$self->{"current"}}) { + my $h; + $h = ""; + $h .= "
    \n"; + $h .= "
    " . myfmttime($$current{"date"}) . "
    \n\n"; + if ($$current{"html"}) { + $h .= $$current{"body"} . "\n\n"; + } else { + $h .= "
    \n" . a2html($$current{"body"}) . "\n
    \n\n"; + } + $h .= "
    \n\n"; + push @htmls, $h; + } + + $_ = h(__("The diary entry seperator")); + print "
    \n\n
    \n\n" + . join("
    \n\n", @htmls) . "
    \n\n"; + + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Funds.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Funds.pm new file mode 100644 index 0000000..66d042d --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Funds.pm @@ -0,0 +1,269 @@ +# Tavern IMACAT's +# Funds.pm: The fund performance list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-10-29 + +package Selima::imacat::List::Funds; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::CommText; +use Selima::DataVars qw(:input :requri); +use Selima::MarkAbbr; +use Selima::ShortCut; + +use Selima::Format; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "funds" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = __("Browse Mutual Fund Performances"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "majcat,mincat,title"; + # Known columns that should not be displayed (has a special purpose) + push @{$self->{"COLS_NO_DISPLAY"}}, qw(_m1rank _m3rank _m6rank + _y1rank _y2rank _y3rank _y5rank _y10rank _ytrank); + # No selection + $self->{"noselect"} = 1; + # Column labels + $self->col_labels( + "title" => __("Name"), + "m1ret" => __("1m return"), + "m1rank" => __("1m ranking"), + "m3ret" => __("3m return"), + "m3rank" => __("3m ranking"), + "m6ret" => __("6m return"), + "m6rank" => __("6m ranking"), + "y1ret" => __("1y return"), + "y1rank" => __("1y ranking"), + "y2ret" => __("2y return"), + "y2rank" => __("2y ranking"), + "y3ret" => __("3y return"), + "y3rank" => __("3y ranking"), + "y5ret" => __("5y return"), + "y5rank" => __("5y ranking"), + "y10ret" => __("10y return"), + "y10rank" => __("10y ranking"), + "ytret" => __("This year return"), + "ytrank" => __("This year ranking"), + "beginret" => __("Total return"), + "begindate" => __("Begin from"), + "bestm3" => __("Best 3m return"), + "worstm3" => __("Worst 3m return"), + "sd12" => __("Standard deviation (12m)"), + "sd24" => __("Standard deviation (24m)"), + "beta12" => __("Beta (12m)"), + "beta24" => __("Beta (24m)"), + "sharpe12" => __("Sharpe (12m)"), + "sharpe24" => __("Sharpe (24m)"), + "jensen12" => __("Jensen (12m)"), + "jensen24" => __("Jensen (24m)"), + "treynor12" => __("Treynor (12m)"), + "treynor24" => __("Treynor (24m)"), + "infrma12" => __("Information Ratio (major categories) (12m)"), + "infrma24" => __("Information Ratio (major categories) (24m)"), + "infrmi12" => __("Information Ratio (minor categories) (12m)"), + "infrmi24" => __("Information Ratio (minor categories) (24m)"), + "turnmt" => __("This month turnover"), + "turny1" => __("12m turnover"), + "duration" => __("Duration"), + "rating" => __("Rating"), + "newman" => __("Manager less than 1y?"), + ); + # The pre-defined filter + $self->{"pre_filter"} = [ + ["y5ret IS NOT NULL AND y5ret > 150 AND m1rank < 1.0/4 AND m3rank < 1.0/4 AND m6rank < 1.0/4 AND y1rank < 1.0/4 AND y2rank < 1.0/4 AND y3rank < 1.0/4 AND y5rank < 1.0/4"], + ["y2ret IS NOT NULL AND y1rank < 1.0/4 AND y2rank < 1.0/4 AND m3rank < 1.0/3 AND m6rank < 1.0/3", __("4433 Principle")], + ]; + return $self; +} + +# pre_filter: Set the pre-defined filter +sub pre_filter : method { + local ($_, %_); + my $self; + $self = $_[0]; + if (!defined $GET->param("filter") || $GET->param("filter") eq "none") { + return undef; + } elsif ($GET->param("filter") eq "free") { + return $GET->param("filtertext") eq ""? undef: + $GET->param("filtertext"); + } elsif ($GET->param("filter") =~ /^\d+$/) { + return $GET->param("filter") <= @{$self->{"pre_filter"}}? + ${${$self->{"pre_filter"}}[$GET->param("filter") - 1]}[0]: undef; + } + return undef; +} + +# sql_filter: Get the SQL WHERE phase +# A filter to update the *rank to _*rank +sub sql_filter : method { + local ($_, %_); + my $self; + $self = $_[0]; + $_ = $self->SUPER::sql_filter; + s/(?SUPER::sql_orderby; + s/(?SUPER::colval($col, %row); +} + +# html_search: Display the search box +sub html_search : method { + local ($_, %_); + my ($self, $prompt, $label, $query, $request_file); + ($self, $prompt) = @_; + $prompt = __("Search for a fund:") if !defined $prompt; + # No search box is displayed if no records yet + if ( $self->{"fetched"} + && defined $self->{"total"} && $self->{"total"} == 0 + && !defined $self->{"query"}) { + return; + } + + $request_file = h($REQUEST_FILE); + $query = defined $self->{"query"}? h($self->{"query"}): ""; + $label = h(__("Search")); + + print << "EOT"; +
    + +
    + +EOT +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,fund].", $self->{"total"}); + # List result + } else { + return __("[*,_1,fund].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,fund], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,fund], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Garbage.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Garbage.pm new file mode 100644 index 0000000..016aff4 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Garbage.pm @@ -0,0 +1,46 @@ +# Tavern IMACAT's +# Garbage.pm: The administrative Soundless Backalley message list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::imacat::List::Garbage; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Guestbook); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "garbage" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Message"): + __("Manage Soundless Backalley"); + # Column labels + $self->col_labels( + ); + return $self; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Garbage/Public.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Garbage/Public.pm new file mode 100644 index 0000000..a05e74a --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Garbage/Public.pm @@ -0,0 +1,75 @@ +# Tavern IMACAT's +# Public.pm: The Soundless Backalley message list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::imacat::List::Garbage::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Guestbook::Public); + +use Selima::A2HTML; +use Selima::Format; +use Selima::GetLang; +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "garbage" if !defined $_[1]; + $self = $class->SUPER::new(@_); + $self->{"view"} = "garbage_public"; + # Columns should be displayed in a reversed order + $self->{"reverse"} = 1; + return $self; +} + +# html_list: List the items +sub html_list : method { + local ($_, %_); + my ($self, @htmls); + $self = $_[0]; + # No record to be listed + return if $self->{"total"} == 0; + + @htmls = qw(); + foreach my $current (@{$self->{"current"}}) { + my $h; + $h = ""; + $h .= "
    \n"; + $h .= "
    \n" . a2html($$current{"message"}) . "\n
    \n\n"; + if (getlang eq "en") { + $h .= "
    " . myfmttime($$current{"date"}) . "
    \n"; + } else { + $h .= "
    " . myfmttime($$current{"date"}) . "
    \n"; + } + $h .= "
    \n\n"; + push @htmls, $h; + } + + $_ = h(__("The message entry seperator")); + print "
    \n\n
    \n\n" + . join("
    \n\n", @htmls) . "
    \n\n"; + + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Guestbook.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Guestbook.pm new file mode 100644 index 0000000..cefd9dd --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Guestbook.pm @@ -0,0 +1,48 @@ +# Tavern IMACAT's +# Guestbook.pm: The administrative guestbook message list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-23 + +package Selima::imacat::List::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Guestbook); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "guestbook" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Message"): + __("Manage Travellers' Guestbook"); + # Column labels + $self->col_labels( + "identity" => __("Specie"), + "lang" => __("Language tag"), + ); + return $self; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Guestbook/Public.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Guestbook/Public.pm new file mode 100644 index 0000000..b25b4d4 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Guestbook/Public.pm @@ -0,0 +1,38 @@ +# Tavern IMACAT's +# Public.pm: The guestbook message list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-23 + +package Selima::imacat::List::Guestbook::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Guestbook::Public); + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # Enable magical Traditional/Simplified Chinese conversion + $self->{"magic_zhconv"} = 1; + return $self; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm new file mode 100644 index 0000000..3c15651 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm @@ -0,0 +1,93 @@ +# Tavern IMACAT's +# LiteralEn.pm: The English writing list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-24 + +package Selima::imacat::List::LiteralEn; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "literalen" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a English Literal Work"): + __("Manage English Literal Works"); + # Columns that should display its brief instead + $self->{"COLS_BRIEF"} = [qw(dsc)]; + # Column labels + $self->col_labels( + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Write a new English literal work.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a English literal work:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,English literal work].", $self->{"total"}); + # List result + } else { + return __("[*,_1,English literal work].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,English literal work], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,English literal work], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm new file mode 100644 index 0000000..43c0e3d --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm @@ -0,0 +1,93 @@ +# Tavern IMACAT's +# LiteralZh.pm: The Chinese writing list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-18 + +package Selima::imacat::List::LiteralZh; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "literalzh" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Chinese Literal Work"): + __("Manage Chinese Literal Works"); + # Columns that should display its brief instead + $self->{"COLS_BRIEF"} = [qw(dsc)]; + # Column labels + $self->col_labels( + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Write a new Chinese literal work.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a Chinese literal work:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,Chinese literal work].", $self->{"total"}); + # List result + } else { + return __("[*,_1,Chinese literal work].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,Chinese literal work], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,Chinese literal work], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm new file mode 100644 index 0000000..a5d5b36 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm @@ -0,0 +1,94 @@ +# Tavern IMACAT's +# LtZhPoem.pm: The Chinese poem list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-18 + +package Selima::imacat::List::LtZhPoem; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "ltzhpoem" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Chinese Poem"): + __("Manage Chinese Poems"); + # Columns that should display its brief instead + $self->{"COLS_BRIEF"} = [qw(body)]; + # Column labels + $self->col_labels( + "set" => __("Work set"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Write a new Chinese poem.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a Chinese poem:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,Chinese poem].", $self->{"total"}); + # List result + } else { + return __("[*,_1,Chinese poem].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,Chinese poem], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,Chinese poem], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Pages.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Pages.pm new file mode 100644 index 0000000..4cbc4f0 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Pages.pm @@ -0,0 +1,42 @@ +# Tavern IMACAT's +# Pages.pm: The web page list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-07 + +package Selima::imacat::List::Pages; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Pages); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # Column labels + $self->col_labels( + "class" => __("HTML class"), + ); + return $self; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm new file mode 100644 index 0000000..09bc8a4 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm @@ -0,0 +1,93 @@ +# Tavern IMACAT's +# Authors.pm: The research paper author list. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +package Selima::imacat::List::Paper::Authors; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "pprauthr" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Paper Author"): + __("Manage Paper Authors"); + # Column labels + $self->col_labels( + "paper" => __("Paper"), + "author" => __("Author"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Add a new paper author.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a paper author:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,author].", $self->{"total"}); + # List result + } else { + return __("[*,_1,author].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,author], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,author], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm new file mode 100644 index 0000000..0137e4f --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm @@ -0,0 +1,93 @@ +# Tavern IMACAT's +# Tags.pm: The paper tag list. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-19 + +package Selima::imacat::List::Paper::Tags; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "pprtags" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Paper Tag"): + __("Manage Paper Tags"); + # Column labels + $self->col_labels( + "paper" => __("Paper"), + "tag" => __("Tag"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Add a new paper tag.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a paper tag:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,tag].", $self->{"total"}); + # List result + } else { + return __("[*,_1,tag].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,tag], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,tag], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm new file mode 100644 index 0000000..ffafc15 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm @@ -0,0 +1,91 @@ +# Tavern IMACAT's +# Types.pm: The research paper type list. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-15 + +package Selima::imacat::List::Paper::Types; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "pprtypes" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Paper Type"): + __("Manage Paper Types"); + # Column labels + $self->col_labels( + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Add a new paper type.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a paper type:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,type].", $self->{"total"}); + # List result + } else { + return __("[*,_1,type].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,type], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,type], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Papers.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Papers.pm new file mode 100644 index 0000000..b9d79ca --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Papers.pm @@ -0,0 +1,99 @@ +# Tavern IMACAT's +# Papers.pm: The research paper list. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +package Selima::imacat::List::Papers; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "papers" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Paper"): + __("Manage Papers"); + # Column labels + $self->col_labels( + "type" => __("Type"), + "year" => __("Year"), + "month" => __("Month"), + "authors" => __("Authors"), + "tags" => __("Tags"), + "pub" => __("Publication"), + "pages" => __("Pages"), + "doi" => __("DOI"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Add a new paper.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a paper:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,paper].", $self->{"total"}); + # List result + } else { + return __("[*,_1,paper].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,paper], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,paper], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Researchers.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Researchers.pm new file mode 100644 index 0000000..4e6128b --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Researchers.pm @@ -0,0 +1,92 @@ +# Tavern IMACAT's +# Researchers.pm: The researcher list. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +package Selima::imacat::List::Researchers; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "resrcher" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Researcher"): + __("Manage Researchers"); + # Column labels + $self->col_labels( + "abbr" => __("Abbreviation"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Add a new researcher.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a researcher:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,researcher].", $self->{"total"}); + # List result + } else { + return __("[*,_1,researcher].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,researcher], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,researcher], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Search.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Search.pm new file mode 100644 index 0000000..26daed7 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Search.pm @@ -0,0 +1,312 @@ +# Tavern IMACAT's +# Search.pm: The web site full-text search result list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-10 + +package Selima::imacat::List::Search; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::DataVars qw($DBH); +use Selima::Format; +use Selima::Logging; +use Selima::Query; +use Selima::ShortCut; +use Selima::Unicode; + +use Date::Parse qw(str2time); + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The page title + if (!defined $self->{"query"}) { + $self->{"title"} = __("Full Text Search"); + $self->{"ctitle"} = __("

    Tavern IMACAT's

    \n

    Full Text Search

    "); + } else { + $self->{"title"} = __("Search Result"); + $self->{"ctitle"} = __("

    Tavern IMACAT's

    \n

    Search Result

    "); + } + $self->{"view"} = "search_list"; + $self->{"COLS_NO_SEARCH"} = [qw(section path html)]; + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my $self; + $self = $_[0]; + # No search specified + if (!defined $self->{"query"}) { + $self->{"total"} = undef; + return $self->{"error"}; + } + # Check the query phrase + # Regularize it + $self->{"query"} =~ s/^\s*(.*?)\s*$/$1/; + # Check if it is filled + if ($self->{"query"} eq"") { + $self->{"total"} = undef; + $self->{"error"} = {"msg"=>N_("Please fill in your query.")}; + return $self->{"error"}; + } + # Run the parent method + $self->SUPER::fetch; + # Add an activity log record + actlog("Query with phrase \"" . $self->{"query"} . "\"."); + # Done + return $self->{"error"}; +} + +# sql_filter: Get the SQL WHERE phase +sub sql_filter : method { + local ($_, %_); + my ($self, @cols, @conds, @phrases); + $self = $_[0]; + + # No query, return empty string + if (!defined $self->{"query"}) { + return " WHERE " . $_ + if $self->can("pre_filter") && defined($_ = $self->pre_filter()); + return ""; + } + + # Regularize it + $self->{"query"} =~ s/^\s*(.*?)\s*$/$1/; + # Check if it is filled + if ($self->{"query"} eq "") { + $self->{"error"} = {"msg"=>N_("Please fill in your query.")}; + return " WHERE " . $_ + if $self->can("pre_filter") && defined($_ = $self->pre_filter()); + return ""; + } + + $self->{"query_phrases"} = [parse_query $self->{"query"}]; + # Bounce if nothing to query + if (@{$self->{"query_phrases"}} == 0) { + return " WHERE " . $_ + if $self->can("pre_filter") && defined($_ = $self->pre_filter()); + return ""; + } + + # Obtain the columns to query + if ($self->{"useview"}) { + %_ = map { $_ => 1 } @{$self->{"COLS_NO_SEARCH"}}; + @cols = grep !exists $_{$_}, @{$self->{"cols"}}; + # Use the column definition kept so far + } else { + @cols = map ${$_}{"def"}, + grep !in_array(${$_}{"alias"}, @{$self->{"COLS_NO_SEARCH"}}), + @{$self->{"coldefs"}} + } + + # Compose the query condition + @conds = qw(); + $self->{"query_zh_phrases"} = []; + # Obtain each phase + foreach my $phrase (@{$self->{"query_phrases"}}) { + my (@subconds, $trad, $simp); + push @_, ($trad = all_to_trad($phrase)); + push @_, $simp if ($simp = all_to_simp($phrase)) ne $trad; + push @{$self->{"query_zh_phrases"}}, @_; + # Convert to to SQL LIKE phrase + @_ = map "'%" . $DBH->esclike($_) . "%'", @_; + @subconds = qw(); + foreach my $col (@cols) { + push @subconds, join " OR ", map "cast($col AS text) ILIKE $_", @_; + } + push @conds, join " OR ", @subconds; + } + # Append the the pre-defined filter + push @conds, $_ + if $self->can("pre_filter") && defined($_ = $self->pre_filter()); + # Compose the WHERE statement + return " WHERE " . (@conds == 1? $conds[0]: join " AND ", map "($_)", @conds); +} + +# sql_orderby: Get the SQL ORDER BY phase +# Always return nothing +sub sql_orderby : method { return ""; } + +# html_newlink: Display a link to add a new item +# Make it a null function +sub html_newlink : method {} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search in the website:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article].", $self->{"total"}); + # List result + } else { + return __("[*,_1,article].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +# html_list: List the items +sub html_list : method { + local ($_, %_); + my ($self); + $self = $_[0]; + # Do not show the list + return if !defined $self->{"total"}; + # No record to be listed + return if $self->{"total"} == 0; + + print << "EOT"; +
      +EOT + + # Print each record + foreach my $current (@{$self->{"current"}}) { + my ($url, $abstract); + $url = h($$current{"path"}); + $abstract = $self->query_abstract($current); + if ($$current{"section"} eq "pages") { + my $title; + $title = h($$current{"title"}); + + print << "EOT"; +
    1. $title

      +EOT + } elsif ($$current{"section"} eq "diary") { + my ($title, $sectitle); + $title = h(__("Tavern Diary on [_1]", $$current{"date"})); + $sectitle = h(__("Tavern Diary")); + + print << "EOT"; +
    2. $title

      +
      $sectitle
      +EOT + } elsif ($$current{"section"} eq "changelog") { + my ($title, $sectitle); + $title = h(__("Change Log on [_1]", $$current{"date"})); + $sectitle = h(__("Change Log")); + + print << "EOT"; +
    3. $title

      +
      $sectitle
      +EOT + } elsif ($$current{"section"} eq "links") { + my ($title, $sectitle); + $title = h($$current{"title"}); + $sectitle = h(__("Keep Travelling")); + + print << "EOT"; +
    4. $title

      +
      $sectitle
      +EOT + } elsif ($$current{"section"} eq "literalzh") { + my ($title, $sectitle); + $title = h("詩 " . myfmtdate str2time $$current{"date"} + . (defined $$current{"title"}? " " . $$current{"title"}: "")); + $sectitle = h(__("Chinese poems")); + + print << "EOT"; +
    5. $title

      +
      $sectitle
      +EOT + } elsif ($$current{"section"} eq "ltzhpoem") { + my ($title, $sectitle); + $title = h($$current{"title"}); + $sectitle = h(__("Chinese poems")); + + print << "EOT"; +
    6. $title

      +
      $sectitle
      +EOT + } elsif ($$current{"section"} eq "literalen") { + my ($title, $sectitle); + $title = h($$current{"title"}); + $sectitle = h(__("English writings")); + + print << "EOT"; +
    7. $title

      +
      $sectitle
      +EOT + } elsif ($$current{"section"} eq "guestbook") { + my ($author, $title, $sectitle); + $author = defined $$current{"author"}? + " " . h($$current{"author"}) . "": ""; + $title = h(__("Guestbook Message on [_1]", $$current{"date"})); + $sectitle = h(__("Travellers' Guestbook")); + + print << "EOT"; +
    8. $title$author

      +
      $sectitle
      +EOT + } elsif ($$current{"section"} eq "garbage") { + my ($title, $sectitle); + $title = h(__("Guestbook Message on [_1]", $$current{"date"})); + $sectitle = h(__("Soundless Backalley")); + + print << "EOT"; +
    9. $title

      +
      $sectitle
      +EOT + } + print "\n

      $abstract

      \n" if defined $abstract; + print << "EOT"; +
    10. + +EOT + } + print << "EOT"; +
    + +EOT + return; +} + +no utf8; +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Tags.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Tags.pm new file mode 100644 index 0000000..8f0a0b9 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/List/Tags.pm @@ -0,0 +1,91 @@ +# Tavern IMACAT's +# Tags.pm: The tag list. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-19 + +package Selima::imacat::List::Tags; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "tags" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Tag"): + __("Manage Tags"); + # Column labels + $self->col_labels( + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Add a new tag.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a tag:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,tag].", $self->{"total"}); + # List result + } else { + return __("[*,_1,tag].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,tag], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,tag], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm new file mode 100644 index 0000000..27f7159 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm @@ -0,0 +1,193 @@ +# Tavern IMACAT's +# ChangeLog.pm: The change log data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-19 + +package Selima::imacat::Processor::ChangeLog; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor::Guestbook); + +use Selima::DataVars qw($DBH :addcol); +use Selima::Format; +use Selima::Guest; +use Selima::ShortCut; + +use Selima::imacat::Rebuild; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "changelog" if @_ < 2; + $self = $class->SUPER::new(@_); + $self->{"page_size"} = 10240; + $self->{"form_cols"} = [qw(body_zhtw)]; + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("body", $self->_form("body")); + $self->{"cols"}->addbool("html", $self->_form("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + $self->{"cols"}->addnum("pageno", 1); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("body", $self->_form("body"), scalar $cur->param("body")); + $self->{"cols"}->addbool("html", $self->_form("html"), scalar $cur->param("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + } + return; +} + +# _update_cols: Update the columns +sub _update_cols : method { + local ($_, %_); + my $self; + ($self, @_) = @_; + $self->{"curlast"} = $self->_last_page; + $self->SUPER::_update_cols(@_); + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my $self; + $self = $_[0]; + # A form to create a new item + return gactlog "Create a change log entry on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the change log entry on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the change log entry on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This log entry was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This log entry has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This log entry has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This log entry has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +# _rebuild_partial_pages: Rebuild a limited part of pages +sub _rebuild_partial_pages : method { + local ($_, %_); + my ($self, $form, $cur); + my ($pageno, $is_rebuild); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + + # Check if there is any shown part affected + $is_rebuild = 0; + # A form to create a new item + if ($self->{"type"} eq "new") { + $is_rebuild = 1 unless defined $form->param("hid"); + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $is_rebuild = 1 unless defined $form->param("hid"); + $is_rebuild = 1 unless $cur->param("hid"); + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $is_rebuild = 1 unless $cur->param("hid"); + } + # Nothing to rebuild when no shown parts are modified + return unless $is_rebuild; + + # Find the page number of the current entry + $self->{"newlast"} = $self->_last_page; + # Remove the unwanted pages + $self->_remove_curfile; + $pageno = ($self->{"type"} eq "new")? + $self->{"newlast"}: $cur->param("pageno"); + # If last page changed, we build from its previous page + if ($self->{"curlast"} < $self->{"newlast"}) { + $pageno = $self->{"curlast"} - 1 if $pageno > $self->{"curlast"} - 1; + } elsif ($self->{"curlast"} > $self->{"newlast"}) { + $pageno = $self->{"newlast"} - 1 if $pageno > $self->{"newlast"} - 1; + } + + # Rebuild the pages + rebuild_changelog $pageno; + return; +} + +# _remove_curfile: Remove the unwanted page +sub _remove_curfile : method { + local ($_, %_); + my $self; + $self = $_[0]; + for ($_ = $self->{"curlast"}; $_ > $self->{"newlast"}; $_--) { + grmoldfile sprintf "/me/changelog/%04d.html", $_; + } + return; +} + +# _last_page: Find the current last page +sub _last_page : method { + local ($_, %_); + my ($self, $sql, $sth); + $self = $_[0]; + $sql = "SELECT pageno FROM " . $self->{"table"} + . " WHERE NOT hid" + . " ORDER BY pageno DESC LIMIT 1;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return ${$sth->fetchrow_hashref}{"pageno"}; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Diary.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Diary.pm new file mode 100644 index 0000000..2077701 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Diary.pm @@ -0,0 +1,192 @@ +# Tavern IMACAT's +# Diary.pm: The diary data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-19 + +package Selima::imacat::Processor::Diary; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor::Guestbook); + +use Selima::DataVars qw($DBH :addcol); +use Selima::Format; +use Selima::Guest; +use Selima::ShortCut; + +use Selima::imacat::Rebuild; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "diary" if @_ < 2; + $self = $class->SUPER::new(@_); + $self->{"form_cols"} = [qw(body_zhtw)]; + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("body", $self->_form("body")); + $self->{"cols"}->addbool("html", $self->_form("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + $self->{"cols"}->addnum("pageno", 1); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("body", $self->_form("body"), scalar $cur->param("body")); + $self->{"cols"}->addbool("html", $self->_form("html"), scalar $cur->param("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + } + return; +} + +# _update_cols: Update the columns +sub _update_cols : method { + local ($_, %_); + my $self; + ($self, @_) = @_; + $self->{"curlast"} = $self->_last_page; + $self->SUPER::_update_cols(@_); + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my $self; + $self = $_[0]; + # A form to create a new item + return gactlog "Create a diary entry on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the diary entry on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the diary entry on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This diary entry was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This diary entry has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This diary entry has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This diary entry has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +# _rebuild_partial_pages: Rebuild a limited part of pages +sub _rebuild_partial_pages : method { + local ($_, %_); + my ($self, $form, $cur); + my ($pageno, $is_rebuild); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + + # Check if there is any shown part affected + $is_rebuild = 0; + # A form to create a new item + if ($self->{"type"} eq "new") { + $is_rebuild = 1 unless defined $form->param("hid"); + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $is_rebuild = 1 unless defined $form->param("hid"); + $is_rebuild = 1 unless $cur->param("hid"); + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $is_rebuild = 1 unless $cur->param("hid"); + } + # Nothing to rebuild when no shown parts are modified + return unless $is_rebuild; + + # Find the page number of the current entry + $self->{"newlast"} = $self->_last_page; + # Remove the unwanted pages + $self->_remove_curfile; + $pageno = ($self->{"type"} eq "new")? + $self->{"newlast"}: $cur->param("pageno"); + # If last page changed, we build from its previous page + if ($self->{"curlast"} < $self->{"newlast"}) { + $pageno = $self->{"curlast"} - 1 if $pageno > $self->{"curlast"} - 1; + } elsif ($self->{"curlast"} > $self->{"newlast"}) { + $pageno = $self->{"newlast"} - 1 if $pageno > $self->{"newlast"} - 1; + } + + # Rebuild the pages + rebuild_diary $pageno; + return; +} + +# _remove_curfile: Remove the unwanted page +sub _remove_curfile : method { + local ($_, %_); + my $self; + $self = $_[0]; + for ($_ = $self->{"curlast"}; $_ > $self->{"newlast"}; $_--) { + grmoldfile sprintf "/me/diary/%04d.html", $_; + } + return; +} + +# _last_page: Find the current last page +sub _last_page : method { + local ($_, %_); + my ($self, $sql, $sth); + $self = $_[0]; + $sql = "SELECT pageno FROM " . $self->{"table"} + . " WHERE NOT hid" + . " ORDER BY pageno DESC LIMIT 1;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return ${$sth->fetchrow_hashref}{"pageno"}; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Garbage.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Garbage.pm new file mode 100644 index 0000000..40b609b --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Garbage.pm @@ -0,0 +1,69 @@ +# Tavern IMACAT's +# Garbage.pm: The administrative Soundless Backalley data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-19 + +package Selima::imacat::Processor::Garbage; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor::Guestbook); + +use Selima::DataVars qw(:addcol); +use Selima::GeoIP; +use Selima::RemoHost; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "garbage" if @_ < 2; + $self = $class->SUPER::new(@_); + $self->{"form_cols"} = [qw(message)]; + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("message", $self->_form("message")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + $self->{"cols"}->addipaddr("ip", $ENV{"REMOTE_ADDR"}); + $self->{"cols"}->addstr("host", remote_host); + $self->{"cols"}->addstr("ct", country_lookup); + $self->{"cols"}->addnum("pageno", 1); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("message", $self->_form("message"), scalar $cur->param("message")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + } + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Garbage/Public.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Garbage/Public.pm new file mode 100644 index 0000000..0fce562 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Garbage/Public.pm @@ -0,0 +1,131 @@ +# Tavern IMACAT's +# Public.pm: The Soundless Backalley data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-19 + +package Selima::imacat::Processor::Garbage::Public; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Selima::imacat::Processor::Garbage); + +use Selima::Country; +use Selima::DataVars qw(:env :input :scptconf); +use Selima::Format; +use Selima::GeoIP; +use Selima::Guest; +use Selima::RemoHost; +use Selima::Unicode; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[0]->param("form", "new"); + $_[0]->param("confirm", 1); + $self = $class->SUPER::new(@_); + $self->{"notify"} = 1; + $self->{"debug"} = 1; + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my $self; + ($self, @_) = @_; + $self->SUPER::_save_cols(@_); + $self->{"cols"}->{"login"} = 723676436; + return; +} + +# _other_tasks: Perform tasks other than column updates +sub _other_tasks : method { + local ($_, %_); + my ($self, $form); + my ($mail, $body, $charset); + $self = $_[0]; + return unless $self->{"notify"}; + $form = $self->{"form"}; + + # Compose the mail body + $body = ""; + $body .= "若要編輯或刪除這則留言,請連上以下網址:\n"; + $body .= "http://" . $ENV{"SERVER_NAME"} . "/magicat/cgi-bin/garbage.cgi" + . "?form=cur&sn=" . $self->{"sn"} . "\n\n"; + $body .= "日期: " . fmttime . "\n"; + @_ = qw(); + push @_, ctname_zhtw country_lookup; + push @_, remote_host if defined remote_host; + $body .= "來自: " . $ENV{"REMOTE_ADDR"} + . " (" . join(", ", @_) . ")\n"; + $body .= "留言:\n\n" . $form->param("message") . "\n\n"; + $body .= "原始內容:\n" . $USER_INPUT{"POST_RAWDATA"} . "\n"; + + # Collecting Debugging infomation + if ($self->{"debug"}) { + $body .= "\n"; + $body .= "===== Start Debugging Infomation =====\n"; + if ($IS_MODPERL) { + $_ = $IS_MP2? Apache2::RequestUtil->request->as_string: + Apache->request->as_string; + s/^X-Selima-[^\n]+\n//mg; + s/^((?:[^\n]+\n)+).+?$/$1/s; + $body .= $_; + } else { + foreach (sort grep !/^HTTP_X_SELIMA_/, grep /^HTTP_/, keys %ENV) { + my $hname; + $hname = $_; + $hname =~ s/^HTTP_//; + $hname =~ s/_/-/g; + $hname =~ s/(\w)(\w+)/$1 . lc $2/ge; + $body .= "$hname: $ENV{$_}\n"; + } + } + $body .= "===== End Debugging Infomation =====\n"; + } + + # Set the best appropriate output character set + $charset = is_charset($body, "Big5")? "Big5": "UTF-8"; + + # Compose the mail + $mail = new Selima::Mail; + $mail->charset($charset); + $mail->from($THIS_FILE . "\@" . $ENV{"SERVER_NAME"}, "無聲的後巷"); + $mail->to("imacat\@mail.imacat.idv.tw", "依瑪貓"); + $mail->subject("[旅舍] 無聲的後巷留言通知 " . fmtdate); + $mail->body($body); + # Send it + $mail->send; + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my $self; + $self = $_[0]; + # A form to create a new item + return gactlog "Post a new message on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "."; +} + +no utf8; +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Guestbook.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Guestbook.pm new file mode 100644 index 0000000..56e15ac --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Guestbook.pm @@ -0,0 +1,75 @@ +# Tavern IMACAT's +# Guestbook.pm: The administrative guestbook data processor. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-10-11 + +package Selima::imacat::Processor::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor::Guestbook); + +use Selima::DataVars qw(:addcol); +use Selima::GeoIP; +use Selima::RemoHost; + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur, $lang); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # Set the language + undef $lang; + $lang = $form->param("lang0") + if defined $form->param("lang0") + && $form->param("lang0") ne "none"; + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("name", $self->_form("name")); + $self->{"cols"}->addstr("identity", $self->_form("identity")); + $self->{"cols"}->addstr("location", $self->_form("location")); + $self->{"cols"}->addstr("email", $self->_form("email")); + $self->{"cols"}->addurl("url", $self->_form("url")); + $self->{"cols"}->addstr("message", $self->_form("message")); + $self->{"cols"}->addbool("hid", $self->_form("hid"));; + $self->{"cols"}->addstr("lang", $lang); + $self->{"cols"}->addipaddr("ip", $ENV{"REMOTE_ADDR"}); + $self->{"cols"}->addstr("host", remote_host); + $self->{"cols"}->addstr("ct", country_lookup); + $self->{"cols"}->addnum("pageno", 1); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("name", $self->_form("name"), scalar $cur->param("name")); + $self->{"cols"}->addstr("identity", $self->_form("identity"), scalar $cur->param("identity")); + $self->{"cols"}->addstr("location", $self->_form("location"), scalar $cur->param("title_2ln")); + $self->{"cols"}->addstr("email", $self->_form("email"), scalar $cur->param("email")); + $self->{"cols"}->addurl("url", $self->_form("url"), scalar $cur->param("url")); + $self->{"cols"}->addstr("message", $self->_form("message"), scalar $cur->param("message")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + $self->{"cols"}->addstr("lang", $lang, scalar $cur->param("lang")); + } + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Guestbook/Public.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Guestbook/Public.pm new file mode 100644 index 0000000..67bb050 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Guestbook/Public.pm @@ -0,0 +1,141 @@ +# Tavern IMACAT's +# Public.pm: The guestbook data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-19 + +package Selima::imacat::Processor::Guestbook::Public; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Selima::Processor::Guestbook); + +use Selima::Country; +use Selima::DataVars qw(:env :input :scptconf); +use Selima::Format; +use Selima::GeoIP; +use Selima::Guest; +use Selima::RemoHost; +use Selima::Unicode; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[0]->param("form", "new"); + $_[0]->param("confirm", 1); + $self = $class->SUPER::new(@_); + $self->{"notify"} = 1; + $self->{"debug"} = 1; + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my $self; + ($self, @_) = @_; + $self->SUPER::_save_cols(@_); + $self->{"cols"}->{"login"} = 723676436; + return; +} + +# _other_tasks: Perform tasks other than column updates +sub _other_tasks : method { + local ($_, %_); + my ($self, $form); + my ($mail, $body, $charset); + $self = $_[0]; + return unless $self->{"notify"}; + $form = $self->{"form"}; + + # Compose the mail body + $body = ""; + $body .= "若要編輯或刪除這則留言,請連上以下網址:\n"; + $body .= "http://" . $ENV{"SERVER_NAME"} . "/magicat/cgi-bin/guestbook.cgi" + . "?form=cur&sn=" . $self->{"sn"} . "\n\n"; + $body .= "日期: " . fmttime . "\n"; + @_ = qw(); + push @_, ctname_zhtw country_lookup; + push @_, remote_host if defined remote_host; + $body .= "來自: " . $ENV{"REMOTE_ADDR"} + . " (" . join(", ", @_) . ")\n"; + $body .= "簽名: " . $form->param("name") . "\n" + if $form->param("name") ne ""; + $body .= "物種: " . $form->param("identity") . "\n" + if $form->param("identity") ne ""; + $body .= "地點: " . $form->param("location") . "\n" + if $form->param("location") ne ""; + $body .= "信箱: " . $form->param("email") . "\n" + if $form->param("email") ne ""; + $body .= "網址: " . $form->param("url") . "\n" + if $form->param("url") ne "" && $form->param("url") ne "http://"; + $body .= "留言:\n\n" . $form->param("message") . "\n\n"; + $body .= "原始內容:\n" . $USER_INPUT{"POST_RAWDATA"} . "\n"; + + # Collecting Debugging infomation + if ($self->{"debug"}) { + $body .= "\n"; + $body .= "===== Start Debugging Infomation =====\n"; + if ($IS_MODPERL) { + $_ = $IS_MP2? Apache2::RequestUtil->request->as_string: + Apache->request->as_string; + s/^X-Selima-[^\n]+\n//mg; + s/^((?:[^\n]+\n)+).+?$/$1/s; + $body .= $_; + } else { + foreach (sort grep !/^HTTP_X_SELIMA_/, grep /^HTTP_/, keys %ENV) { + my $hname; + $hname = $_; + $hname =~ s/^HTTP_//; + $hname =~ s/_/-/g; + $hname =~ s/(\w)(\w+)/$1 . lc $2/ge; + $body .= "$hname: $ENV{$_}\n"; + } + } + $body .= "===== End Debugging Infomation =====\n"; + } + + # Set the best appropriate output character set + $charset = is_charset($body, "Big5")? "Big5": "UTF-8"; + + # Compose the mail + $mail = new Selima::Mail; + $mail->charset($charset); + $mail->from($THIS_FILE . "\@" . $ENV{"SERVER_NAME"}, "旅人留言本"); + $mail->to("imacat\@mail.imacat.idv.tw", "依瑪貓"); + $mail->subject("[旅舍] 旅人留言本留言通知 " . fmtdate); + $mail->body($body); + # Send it + $mail->send; + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my $self; + $self = $_[0]; + # A form to create a new item + return gactlog "Post a new message on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "."; +} + +no utf8; +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm new file mode 100644 index 0000000..498a36d --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm @@ -0,0 +1,286 @@ +# Tavern IMACAT's +# LiteralEn.pm: The English writing data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-25 + +package Selima::imacat::Processor::LiteralEn; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Date::Parse qw(str2time); + +use Selima::DataVars qw($DBH :addcol :dataman); +use Selima::Format; +use Selima::Guest; +use Selima::ShortCut; + +use Selima::imacat::Rebuild; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "literalen" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur, $o); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->adddate("date", $self->_form("date")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("dsc", $self->_form("dsc")); + $self->{"cols"}->addstr("body", $self->_form("body")); + $self->{"cols"}->addstr("kw", $self->_form("kw")); + $self->{"cols"}->addbool("html", $self->_form("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->adddate("date", $self->_form("date"), scalar $cur->param("date")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("dsc", $self->_form("dsc"), scalar $cur->param("dsc")); + $self->{"cols"}->addstr("body", $self->_form("body"), scalar $cur->param("body")); + $self->{"cols"}->addstr("kw", $self->_form("kw"), scalar $cur->param("kw")); + $self->{"cols"}->addbool("html", $self->_form("html"), scalar $cur->param("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a English literal work on " . $form->param("date") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the English literal work on " . $form->param("date") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the English literal work on " . $cur->param("date") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This English literal work was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This English literal work has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This English literal work has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This English literal work has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +# _rebuild_partial_pages: Rebuild a limited part of pages +sub _rebuild_partial_pages : method { + local ($_, %_); + my ($self, $form, $cur, $curord, $neword, $startdate, $enddate); + my ($sql, $sth, $count, @conds); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # Remove the unwanted pages + $self->_remove_curfile; + + # Check if there is any shown part affected + ($curord, $neword) = (undef, undef); + # A form to create a new item + if ($self->{"type"} eq "new") { + if (!defined $form->param("hid")) { + $sql = "SELECT count(*) + 1 AS ord FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date<" . $DBH->quote($form->param("date")) + . " AND NOT hid;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $neword = ${$sth->fetch}[0]; + } + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + if (!defined $form->param("hid")) { + $sql = "SELECT count(*) + 1 AS ord FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date<" . $DBH->quote($form->param("date")) + . " AND NOT hid;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $neword = ${$sth->fetch}[0]; + } + if (!$cur->param("hid")) { + $sql = "SELECT count(*) + 1 AS ord FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date<" . $DBH->quote($cur->param("date")) + . " AND NOT hid;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $curord = ${$sth->fetch}[0]; + } + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + if (!$cur->param("hid")) { + $sql = "SELECT count(*) + 1 AS ord FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date<" . $DBH->quote($cur->param("date")) + . " AND NOT hid;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $curord = ${$sth->fetch}[0]; + } + } + # Nothing to rebuild when no shown parts are seen + return unless defined $curord || defined $neword; + + # First page changed -- rebuild everything. This is rare. + if ( defined $curord && defined $neword + && ($curord == 1 || $neword == 1) + && $curord != $neword) { + # Rebuild the pages + rebuild_literalen; + return; + } + + @conds = qw(); + # A page gone or a page appear + if (!defined $curord || !defined $neword) { + # Rebuild the following pages since the ordering is changed + # Obtain the start date + $_ = defined $curord? $cur->param("date"): $form->param("date"); + # It is always a current form here + $sql = "SELECT date FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date<" . $DBH->quote($_) + . " AND NOT hid" + . " ORDER BY date DESC LIMIT 6;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + # We have 6 pages more to the first - rebuild the previous 3 pages + # If fewer than 6 pages, start from the first for page bar sliding + if ($count == 6) { + for ($_ = 0; $_ < 3; $_++) { + $startdate = ${$sth->fetch}[0]; + } + push @conds, "date>=" . $DBH->quote(fmtdate $startdate); + } + + # An existing page that keeps existing + } else { + # Rebuild the pages between + # Obtain the start date + $_ = $curord < $neword? $cur->param("date"): $form->param("date"); + # It is always a current form here + $sql = "SELECT date FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date<" . $DBH->quote($_) + . " AND NOT hid" + . " ORDER BY date DESC LIMIT 6;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + # We have 6 pages more to the first - rebuild the previous 3 pages + # If fewer than 6 pages, start from the first for page bar sliding + if ($count == 6) { + for ($_ = 0; $_ < 3; $_++) { + $startdate = ${$sth->fetch}[0]; + } + push @conds, "date>=" . $DBH->quote(fmtdate $startdate); + } + # Obtain the end date + $_ = $curord > $neword? $cur->param("date"): $form->param("date"); + # It is always a current form here + $sql = "SELECT date FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date>" . $DBH->quote($_) + . " AND NOT hid" + . " ORDER BY date LIMIT 6;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @_ = qw(); $i < $count; $i++) { + push @_, ${$sth->fetch}[0]; + } + # We have 6 pages more to the end - rebuild the next 3 pages + # If fewer than 6 pages, build to the end for page bar sliding + if ($count == 6) { + for ($_ = 0; $_ < 3; $_++) { + $startdate = ${$sth->fetch}[0]; + } + push @conds, "date<=" . $DBH->quote(fmtdate $enddate); + } + } + + # Compose the SQL statement + push @conds, "NOT hid"; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @conds) + . " ORDER BY date;\n"; + # Rebuild the pages + rebuild_literalen $sql; + return; +} + +# _remove_curfile: Remove the unwanted pages +sub _remove_curfile : method { + local ($_, %_); + my ($self, $form, $cur, $curpath, $newpath); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # Nothing to remove if there is no current page + return if $self->{"type"} eq "new" || $cur->param("hid"); + + # A current page to be deleted or hidden + @_ = localtime str2time $cur->param("date"); + $_[5] += 1900; + $_[4]++; + $curpath = sprintf "/writings-en/%04d%02d%02d.html", @_[5,4,3]; + return grmoldpage $curpath + if $self->{"type"} eq "del" || defined $form->param("hid"); + # A shown page update with a new page path to check with + @_ = localtime str2time $form->param("date"); + $_[5] += 1900; + $_[4]++; + $newpath = sprintf "/writings-en/%04d%02d%02d.html", @_[5,4,3]; + return grmoldpage $curpath, $newpath; + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm new file mode 100644 index 0000000..c599fc4 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm @@ -0,0 +1,370 @@ +# Tavern IMACAT's +# LiteralZh.pm: The Chinese writing data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-21 + +package Selima::imacat::Processor::LiteralZh; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Date::Parse qw(str2time); + +use Selima::DataVars qw($DBH :addcol :dataman); +use Selima::Format; +use Selima::Guest; +use Selima::ShortCut; + +use Selima::imacat::Rebuild; + +use Selima::imacat::Processor::LtZhPoem; +use Selima::Processor::Deletion; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "literalzh" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur, $o); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->adddate("date", $self->_form("date")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("dsc", $self->_form("dsc")); + $self->{"cols"}->addstr("kw", $self->_form("kw")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + + # Find the changed items + for ($_ = 0, $o = 1; defined $form->param("poem$_" . "title"); $_++) { + my ($subform, $cols); + # Not selected + next unless defined $form->param("poem$_"); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("set", $self->{"sn"}); + $subform->param("ord", $o++); + $subform->param("title", $form->param("poem$_" . "title")); + $subform->param("body", $form->param("poem$_" . "body")); + $subform->param("hid", $form->param("poem$_" . "hid")); + $cols = new Selima::imacat::Processor::LtZhPoem($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->adddate("date", $self->_form("date"), scalar $cur->param("date")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("dsc", $self->_form("dsc"), scalar $cur->param("dsc")); + $self->{"cols"}->addstr("kw", $self->_form("kw"), scalar $cur->param("kw")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + + # Find the changed items + @_ = qw(); + for ( $_ = 0, $o = 1; + $_ < $cur->param("poemcount") + || defined $form->param("poem$_" . "title"); + $_++) { + # Added items to the current + if ($_ >= $cur->param("poemcount")) { + my ($subform, $cols); + # Not selected + next unless defined $form->param("poem$_"); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("set", $self->{"sn"}); + $subform->param("ord", $o++); + $subform->param("title", $form->param("poem$_" . "title")); + $subform->param("body", $form->param("poem$_" . "body")); + $subform->param("hid", $form->param("poem$_" . "hid")); + $cols = new Selima::imacat::Processor::LtZhPoem($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + + # Selected + } elsif (defined $form->param("poem$_")) { + my ($subform, $cols, %CURRENT_SUP); + %CURRENT_SUP = %CURRENT; + %CURRENT = ( + "sn" => $cur->param("poem$_" . "sn"), + "set" => $self->{"sn"}, + "ord" => $cur->param("poem$_" . "ord"), + "title" => $cur->param("poem$_" . "title"), + "body" => $cur->param("poem$_" . "body"), + "hid" => $cur->param("poem$_" . "hid"), + ); + $subform = new CGI(""); + $subform->param("form", "cur"); + $subform->param("sn", $cur->param("poem$_" . "sn")); + $subform->param("set", $self->{"sn"}); + $subform->param("ord", $o++); + $subform->param("title", $form->param("poem$_" . "title")); + $subform->param("body", $form->param("poem$_" . "body")); + $subform->param("hid", $form->param("poem$_" . "hid")); + $cols = new Selima::imacat::Processor::LtZhPoem($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + %CURRENT = %CURRENT_SUP; + + # Not selected + } else { + push @_, $cur->param("poem$_" . "sn"); + } + } + if (@_ > 0) { + my $subform; + $_ = join " OR ", map "sn=$_", @_; + $subform = new CGI(""); + $subform->param("cond", $_); + # Delete first, to spare the order occupied + unshift @{$self->{"subs"}}, new Selima::Processor::Deletion($subform, "ltzhpoem"); + } + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + # Find the changed items + $_ = new CGI(""); + $_->param("cond", "set=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($_, "ltzhpoem"); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a Chinese literal work on " . $form->param("date") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the Chinese literal work on " . $form->param("date") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the Chinese literal work on " . $cur->param("date") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This Chinese literal work was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This Chinese literal work has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This Chinese literal work has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This Chinese literal work has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +# _rebuild_partial_pages: Rebuild a limited part of pages +sub _rebuild_partial_pages : method { + local ($_, %_); + my ($self, $form, $cur, $curord, $neword, $startdate, $enddate); + my ($sql, $sth, $count, @conds); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # Remove the unwanted pages + $self->_remove_curfile; + + # Check if there is any shown part affected + ($curord, $neword) = (undef, undef); + # A form to create a new item + if ($self->{"type"} eq "new") { + if (!defined $form->param("hid")) { + $sql = "SELECT count(*) + 1 AS ord FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date<" . $DBH->quote($form->param("date")) + . " AND NOT hid;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $neword = ${$sth->fetch}[0]; + } + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + if (!defined $form->param("hid")) { + $sql = "SELECT count(*) + 1 AS ord FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date<" . $DBH->quote($form->param("date")) + . " AND NOT hid;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $neword = ${$sth->fetch}[0]; + } + if (!$cur->param("hid")) { + $sql = "SELECT count(*) + 1 AS ord FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date<" . $DBH->quote($cur->param("date")) + . " AND NOT hid;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $curord = ${$sth->fetch}[0]; + } + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + if (!$cur->param("hid")) { + $sql = "SELECT count(*) + 1 AS ord FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date<" . $DBH->quote($cur->param("date")) + . " AND NOT hid;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $curord = ${$sth->fetch}[0]; + } + } + # Nothing to rebuild when no shown parts are seen + return unless defined $curord || defined $neword; + + # First page changed -- rebuild everything. This is rare. + if ( defined $curord && defined $neword + && ($curord == 1 || $neword == 1) + && $curord != $neword) { + # Rebuild the pages + rebuild_literalzh; + return; + } + + @conds = qw(); + # A page gone or a page appear + if (!defined $curord || !defined $neword) { + # Rebuild the following pages since the ordering is changed + # Obtain the start date + $_ = defined $curord? $cur->param("date"): $form->param("date"); + # It is always a current form here + $sql = "SELECT date FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date<" . $DBH->quote($_) + . " AND NOT hid" + . " ORDER BY date DESC LIMIT 6;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + # We have 6 more pages to the first - rebuild the previous 3 pages + # If fewer than 6 pages, start from the first for page bar sliding + if ($count == 6) { + for ($_ = 0; $_ < 3; $_++) { + $startdate = ${$sth->fetch}[0]; + } + push @conds, "date>=" . $DBH->quote(fmtdate $startdate); + } + + # An existing page that keeps existing + } else { + # Rebuild the pages between + # Obtain the start date + $_ = $curord < $neword? $cur->param("date"): $form->param("date"); + # It is always a current form here + $sql = "SELECT date FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date<" . $DBH->quote($_) + . " AND NOT hid" + . " ORDER BY date DESC LIMIT 6;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + # We have 6 more pages to the first - rebuild the previous 3 pages + # If fewer than 6 pages, start from the first for page bar sliding + if ($count == 6) { + for ($_ = 0; $_ < 3; $_++) { + $startdate = ${$sth->fetch}[0]; + } + push @conds, "date>=" . $DBH->quote(fmtdate $startdate); + } + # Obtain the end date + $_ = $curord > $neword? $cur->param("date"): $form->param("date"); + # It is always a current form here + $sql = "SELECT date FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE date>" . $DBH->quote($_) + . " AND NOT hid" + . " ORDER BY date LIMIT 6;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @_ = qw(); $i < $count; $i++) { + push @_, ${$sth->fetch}[0]; + } + # We have 6 more pages to the end - rebuild the next 3 pages + # If fewer than 6 pages, build to the end for page bar sliding + if ($count == 6) { + for ($_ = 0; $_ < 3; $_++) { + $startdate = ${$sth->fetch}[0]; + } + push @conds, "date<=" . $DBH->quote(fmtdate $enddate); + } + } + + # Compose the SQL statement + push @conds, "NOT hid"; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @conds) + . " ORDER BY date;\n"; + # Rebuild the pages + rebuild_literalzh $sql; + return; +} + +# _remove_curfile: Remove the unwanted pages +sub _remove_curfile : method { + local ($_, %_); + my ($self, $form, $cur, $curpath, $newpath); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # Nothing to remove if there is no current page + return if $self->{"type"} eq "new" || $cur->param("hid"); + + # A current page to be deleted or hidden + @_ = localtime str2time $cur->param("date"); + $_[5] += 1900; + $_[4]++; + $curpath = sprintf "/writings-zh/%04d%02d%02d.html", @_[5,4,3]; + return grmoldpage $curpath + if $self->{"type"} eq "del" || defined $form->param("hid"); + # A shown page update with a new page path to check with + @_ = localtime str2time $form->param("date"); + $_[5] += 1900; + $_[4]++; + $newpath = sprintf "/writings-zh/%04d%02d%02d.html", @_[5,4,3]; + return grmoldpage $curpath, $newpath; + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm new file mode 100644 index 0000000..137d45b --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm @@ -0,0 +1,155 @@ +# Tavern IMACAT's +# LtZhPoem.pm: The Chinese poem data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-21 + +package Selima::imacat::Processor::LtZhPoem; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw(:addcol); +use Selima::Guest; +use Selima::ShortCut; + +use Selima::imacat::Items; +use Selima::imacat::Rebuild; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "ltzhpoem" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("set", $self->_form("set")); + $self->{"cols"}->addnum("ord", $self->_form("ord")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("body", $self->_form("body")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("set", $self->_form("set"), scalar $cur->param("set")); + $self->{"cols"}->addnum("ord", $self->_form("ord"), scalar $cur->param("ord")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("author", $self->_form("author"), scalar $cur->param("author")); + $self->{"cols"}->addstr("body", $self->_form("body"), scalar $cur->param("body")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a Chinese poem " . $form->param("title") + . " on " . literalzh_date($form->param("set")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the Chinese poem " . $form->param("title") + . " on " . literalzh_date($form->param("set")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the Chinese poem " . $cur->param("title") + . " on " . literalzh_date($cur->param("set")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This Chinese poem was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This Chinese poem has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This Chinese poem has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This Chinese poem has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +# _rebuild_partial_pages: Rebuild a limited part of pages +sub _rebuild_partial_pages : method { + local ($_, %_); + my ($self, $form, $cur, $sql); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + + # Find the affected shown parts + %_ = qw(); + # A form to create a new item + if ($self->{"type"} eq "new") { + $_{$form->param("set")} = 1 unless defined $form->param("hid"); + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $_{$form->param("set")} = 1 unless defined $form->param("hid"); + $_{$cur->param("set")} = 1 unless $cur->param("hid"); + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $_{$cur->param("set")} = 1 unless $cur->param("hid"); + } + @_ = keys %_; + # Nothing to rebuild when no shown parts are seen + return if @_ == 0; + + # Compose the SQL statement + $_ = join " OR ", map "sn=$_", @_; + $_ = "($_)" if @_ > 1; + $sql = "SELECT * FROM literalzh" + . " WHERE $_" + . " AND NOT hid" + . " ORDER BY date;\n"; + # Rebuild the pages + rebuild_literalzh $sql; + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Page.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Page.pm new file mode 100644 index 0000000..047672b --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Page.pm @@ -0,0 +1,68 @@ +# Tavern IMACAT's +# Page.pm: The web page form data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-07 + +package Selima::imacat::Processor::Page; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor::Page); + +use Selima::DataVars qw(:addcol); + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("path", $self->_form("path")); + $self->{"cols"}->addnum("ord", $self->_form("ord")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("body", $self->_form("body")); + $self->{"cols"}->addstr("kw", $self->_form("kw")); + $self->{"cols"}->addstr("class", $self->_form("class")); + $self->{"cols"}->addbool("html", $self->_form("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("path", $self->_form("path"), scalar $cur->param("path")); + $self->{"cols"}->addnum("ord", $self->_form("ord"), scalar $cur->param("ord")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("body", $self->_form("body"), scalar $cur->param("body")); + $self->{"cols"}->addstr("kw", $self->_form("kw"), scalar $cur->param("kw")); + $self->{"cols"}->addstr("class", $self->_form("class"), scalar $cur->param("class")); + $self->{"cols"}->addbool("html", $self->_form("html"), scalar $cur->param("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + } + return; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Paper.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Paper.pm new file mode 100644 index 0000000..2014cbf --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Paper.pm @@ -0,0 +1,311 @@ +# Tavern IMACAT's +# Paper.pm: The research paper data processor. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +package Selima::imacat::Processor::Paper; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw($DBH :addcol :dataman); +use Selima::Guest; +use Selima::ShortCut; + +use Selima::imacat::Items; +use Selima::imacat::Processor::Paper::Author; +use Selima::imacat::Processor::Paper::Tag; +use Selima::imacat::Processor::Researcher; +use Selima::imacat::Processor::Tag; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "papers" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur, @olditems, @newitems, @additems, @delitems); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("type", $self->_form("type")); + $self->{"cols"}->addnum("year", $self->_form("year")); + $self->{"cols"}->addstr("month", $self->_form("month")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("pub", $self->_form("pub")); + $self->{"cols"}->addstr("pages", $self->_form("pages")); + $self->{"cols"}->addstr("doi", $self->_form("doi")); + $self->{"cols"}->addstr("url", $self->_form("url")); + + # Find the changed items + @additems = qw(); + for ($_ = 0; defined $form->param("author$_" . "sn"); $_++) { + push @additems, $form->param("author$_" . "sn") + if defined $form->param("author$_"); + } + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("paper", $self->{"sn"}); + $subform->param("author", $item); + $cols = new Selima::imacat::Processor::Paper::Author($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + @additems = split /\s*[,,]\s*/, $form->param("authorfree"); + foreach my $item (@additems) { + my ($subform, $cols, $itemsn); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("name", $item); + $subform->param("abbr", abbreviate_name $item); + $cols = new Selima::imacat::Processor::Researcher($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + $itemsn = $cols->{"sn"}; + + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("paper", $self->{"sn"}); + $subform->param("author", $itemsn); + $cols = new Selima::imacat::Processor::Paper::Author($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + + @additems = qw(); + for ($_ = 0; defined $form->param("tag$_" . "sn"); $_++) { + push @additems, $form->param("tag$_" . "sn") + if defined $form->param("tag$_"); + } + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("paper", $self->{"sn"}); + $subform->param("tag", $item); + $cols = new Selima::imacat::Processor::Paper::Tag($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + @additems = split /\s*[,,]\s*/, $form->param("tagfree"); + foreach my $item (@additems) { + my ($subform, $cols, $itemsn); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("title", $item); + $cols = new Selima::imacat::Processor::Tag($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + $itemsn = $cols->{"sn"}; + + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("paper", $self->{"sn"}); + $subform->param("tag", $itemsn); + $cols = new Selima::imacat::Processor::Paper::Tag($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("type", $self->_form("type"), scalar $cur->param("type")); + $self->{"cols"}->addnum("year", $self->_form("year"), scalar $cur->param("year")); + $self->{"cols"}->addstr("month", $self->_form("month"), scalar $cur->param("month")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("pub", $self->_form("pub"), scalar $cur->param("pub")); + $self->{"cols"}->addstr("pages", $self->_form("pages"), scalar $cur->param("pages")); + $self->{"cols"}->addstr("doi", $self->_form("doi"), scalar $cur->param("doi")); + $self->{"cols"}->addstr("url", $self->_form("url"), scalar $cur->param("url")); + + # Find the changed items + @olditems = qw(); + @newitems = qw(); + # Skip for a non-super-user editing a super-user group + for ($_ = 0; $_ < $cur->param("authorcount"); $_++) { + push @olditems, $cur->param("author$_" . "sn"); + } + for ($_ = 0; defined $form->param("author$_" . "sn"); $_++) { + push @newitems, $form->param("author$_" . "sn") + if defined $form->param("author$_"); + } + %_ = map { $_ => 1 } @newitems; + @delitems = grep !exists $_{$_}, @olditems; + %_ = map { $_ => 1 } @olditems; + @additems = grep !exists $_{$_}, @newitems; + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("paper", $self->{"sn"}); + $subform->param("author", $item); + $cols = new Selima::imacat::Processor::Paper::Author($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + if (@delitems > 0) { + my $subform; + @_ = map "author=$_", @delitems; + $_ = (scalar(@_) == 1)? $_[0]: "(" . join(" OR ", @_) . ")"; + $subform = new CGI(""); + $subform->param("cond", "$_ AND paper=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($subform, "pprauthr"); + } + @additems = split /\s*[,,]\s*/, $form->param("authorfree"); + foreach my $item (@additems) { + my ($subform, $cols, $itemsn); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("name", $item); + $subform->param("abbr", abbreviate_name $item); + $cols = new Selima::imacat::Processor::Researcher($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + $itemsn = $cols->{"sn"}; + + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("paper", $self->{"sn"}); + $subform->param("author", $itemsn); + $cols = new Selima::imacat::Processor::Paper::Author($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + + @olditems = qw(); + @newitems = qw(); + # Skip for a non-super-user editing a super-user group + for ($_ = 0; $_ < $cur->param("tagcount"); $_++) { + push @olditems, $cur->param("tag$_" . "sn"); + } + for ($_ = 0; defined $form->param("tag$_" . "sn"); $_++) { + push @newitems, $form->param("tag$_" . "sn") + if defined $form->param("tag$_"); + } + %_ = map { $_ => 1 } @newitems; + @delitems = grep !exists $_{$_}, @olditems; + %_ = map { $_ => 1 } @olditems; + @additems = grep !exists $_{$_}, @newitems; + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("paper", $self->{"sn"}); + $subform->param("tag", $item); + $cols = new Selima::imacat::Processor::Paper::Tag($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + if (@delitems > 0) { + my $subform; + @_ = map "tag=$_", @delitems; + $_ = (scalar(@_) == 1)? $_[0]: "(" . join(" OR ", @_) . ")"; + $subform = new CGI(""); + $subform->param("cond", "$_ AND paper=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($subform, "pprtags"); + } + @additems = split /\s*[,,]\s*/, $form->param("tagfree"); + foreach my $item (@additems) { + my ($subform, $cols, $itemsn); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("title", $item); + $cols = new Selima::imacat::Processor::Tag($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + $itemsn = $cols->{"sn"}; + + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("paper", $self->{"sn"}); + $subform->param("tag", $itemsn); + $cols = new Selima::imacat::Processor::Paper::Tag($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + # Find the changed items + $_ = new CGI(""); + $_->param("cond", "paper=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($_, "pprauthr"); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a paper \"" . $form->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the paper \"" . $form->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the paper \"" . $cur->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This paper was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This paper has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This paper has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This paper has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +no utf8; +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm new file mode 100644 index 0000000..ac321fc --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm @@ -0,0 +1,114 @@ +# Tavern IMACAT's +# Author.pm: The research paper author data processor. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +package Selima::imacat::Processor::Paper::Author; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw($DBH :addcol :dataman); +use Selima::Guest; +use Selima::ShortCut; + +use Selima::imacat::Items; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "pprauthr" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("paper", $self->_form("paper")); + $self->{"cols"}->addnum("author", $self->_form("author")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("paper", $self->_form("paper"), scalar $cur->param("paper")); + $self->{"cols"}->addnum("author", $self->_form("author"), scalar $cur->param("author")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a paper author" + . " \"" . paper_title($form->param("paper")) . "\"" + . " by \"" . researcher_name($form->param("author")) . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the paper author" + . " \"" . paper_title($form->param("paper")) . "\"" + . " by \"" . researcher_name($form->param("author")) . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the paper author" + . " \"" . paper_title($form->param("paper")) . "\"" + . " by \"" . researcher_name($form->param("author")) . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This paper author was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This paper author has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This paper author has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This paper author has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm new file mode 100644 index 0000000..1919aa9 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm @@ -0,0 +1,114 @@ +# Tavern IMACAT's +# Tag.pm: The paper tag data processor. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-19 + +package Selima::imacat::Processor::Paper::Tag; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw($DBH :addcol :dataman); +use Selima::Guest; +use Selima::ShortCut; + +use Selima::imacat::Items; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "pprtags" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("paper", $self->_form("paper")); + $self->{"cols"}->addnum("tag", $self->_form("tag")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("paper", $self->_form("paper"), scalar $cur->param("paper")); + $self->{"cols"}->addnum("tag", $self->_form("tag"), scalar $cur->param("tag")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a paper tag" + . " \"" . paper_title($form->param("paper")) . "\"" + . " as \"" . tag_title($form->param("tag")) . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the paper tag" + . " \"" . paper_title($form->param("paper")) . "\"" + . " as \"" . tag_title($form->param("tag")) . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the paper tag" + . " \"" . paper_title($form->param("paper")) . "\"" + . " as \"" . tag_title($form->param("tag")) . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This paper tag was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This paper tag has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This paper tag has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This paper tag has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm new file mode 100644 index 0000000..360ca8e --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm @@ -0,0 +1,111 @@ +# Tavern IMACAT's +# Type.pm: The research paper type data processor. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-15 + +package Selima::imacat::Processor::Paper::Type; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw($DBH :addcol :dataman); +use Selima::Format; +use Selima::Guest; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "pprtypes" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("ord", $self->_form("ord")); + $self->{"cols"}->addstr("title", $self->_form("title")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("ord", $self->_form("ord"), scalar $cur->param("ord")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a paper type \"" . $form->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the paper type \"" . $form->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the paper type \"" . $cur->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This paper type was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This paper type has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This paper type has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This paper type has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm new file mode 100644 index 0000000..e9c459c --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm @@ -0,0 +1,107 @@ +# Tavern IMACAT's +# Researcher.pm: The researcher data processor. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-16 + +package Selima::imacat::Processor::Researcher; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw($DBH :addcol :dataman); +use Selima::Format; +use Selima::Guest; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "resrcher" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("name", $self->_form("name")); + $self->{"cols"}->addstr("abbr", $self->_form("abbr")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("name", $self->_form("name"), scalar $cur->param("name")); + $self->{"cols"}->addstr("abbr", $self->_form("abbr"), scalar $cur->param("abbr")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a researcher \"" . $form->param("name") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the researcher \"" . $form->param("name") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the researcher \"" . $cur->param("name") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This researcher was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This researcher has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This researcher has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This researcher has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Tag.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Tag.pm new file mode 100644 index 0000000..eb9ee96 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Processor/Tag.pm @@ -0,0 +1,105 @@ +# Tavern IMACAT's +# Tag.pm: The tag data processor. + +# Copyright (c) 2012-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2012-05-19 + +package Selima::imacat::Processor::Tag; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw($DBH :addcol :dataman); +use Selima::Format; +use Selima::Guest; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "tags" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("title", $self->_form("title")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a tag \"" . $form->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the tag \"" . $form->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the tag \"" . $cur->param("title") . "\"" + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This tag was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This tag has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This tag has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This tag has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Rebuild.pm b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Rebuild.pm new file mode 100644 index 0000000..9cae201 --- /dev/null +++ b/htdocs/imacat/magicat/lib/perl5/Selima/imacat/Rebuild.pm @@ -0,0 +1,947 @@ +# Tavern IMACAT's +# Rebuild.pm: The subroutines to rebuild the web pages. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-25 + +package Selima::imacat::Rebuild; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(rebuild_all rebuild_pages rebuild_links rebuild_diary); +push @EXPORT, qw(rebuild_changelog rebuild_literalzh rebuild_literalen); +push @EXPORT, qw(compose_page); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub rebuild_all(); +sub rebuild_pages(;$); +sub rebuild_links(;$); +sub rebuild_diary(;$); +sub rebuild_changelog(;$); +sub rebuild_literalzh(;$); +sub rebuild_literalen(;$); +sub compose_page($;$); +} + +use Config qw(%Config); +use Data::Dumper qw(); +use Fcntl qw(:flock); +use File::Basename qw(basename); +use IO::NestedCapture qw(CAPTURE_STDOUT); +use Lingua::ZH::Numbers; + +use Selima::Array; +use Selima::DataVars qw($DBH :l10n :lninfo :output :rebuild :requri); +use Selima::Format; +use Selima::GetLang; +use Selima::Guest; +use Selima::LnInfo; +use Selima::PageFunc; +use Selima::SetL10N; +use Selima::ShortCut; +use Selima::Unicode; + +use Selima::imacat::HTML; + +use vars qw($PKGL10N); + +# rebuild_all: Rebuild everything +sub rebuild_all() { + local ($_, %_); + # Lock the required tables + $DBH->lock(map { $_ => LOCK_SH } @REBUILD_TABLES); + # Rebuild the pages + rebuild_pages; + # Rebuild the links + rebuild_links; + # Rebuild the diary + rebuild_diary; + # Rebuild the change log + rebuild_changelog; + # Rebuild the Chinese literal works + rebuild_literalzh; + # Rebuild the English literal works + rebuild_literalen; + # Rebuild the index + # To be done + #rebuild_index; + return; +} + +# rebuild_pages: Rebuild the pages +sub rebuild_pages(;$) { + local ($_, %_); + my ($sql, $sth, $count, $rebuild_everything); + $sql = $_[0]; + + # Rebuild everything + $rebuild_everything = !defined $sql; + if ($rebuild_everything) { + $sql = "SELECT * FROM pages" + . " WHERE NOT hid;\n"; + } + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + # Bounce if no pages to build on a partial rebuild + # This prevents needless sitemap rebuilding + return if !$rebuild_everything && $count == 0; + # Build each page + for (my $i = 0; $i < $count; $i++) { + my $page; + $page = $sth->fetchrow_hashref; + # Read the picture into the picture deposit + # To be done + + # Build each language + foreach my $lang (@ALL_LINGUAS) { + my $html; + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + } + + # Output related pictures only when rebuilding everything + # To be done + } + + return; +} + +# rebuild_links: Rebuild the links +sub rebuild_links(;$) { + local ($_, %_); + my ($sql, $sth, $count, $rebuild_everything); + $sql = $_[0]; + + # Rebuild everything + $rebuild_everything = !defined $sql; + if ($rebuild_everything) { + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_isshown(sn, hid, parent);\n"; + } + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0; $i < $count; $i++) { + my ($page, $sql1, $sth1, $count1, $row1); + $page = $sth->fetchrow_hashref; + + # Find the ancesters + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql1 = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_ischild(sn, " . $$page{"sn"} . ")" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"parents"} = []; $i < $count1; $i++) { + push @{$$page{"parents"}}, $sth1->fetchrow_hashref; + } + + # Find the subcategories + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql1 = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE parent=" . $$page{"sn"} + . " AND linkcat_isshown(sn, hid, parent)" + . " ORDER BY ord;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"scats"} = []; $i < $count1; $i++) { + my ($sql2, $sth2, $row2); + $row1 = $sth1->fetchrow_hashref; + # Find the belonging links + $sql2 = "SELECT count(linkcatz.sn) AS count FROM linkcatz" + . " INNER JOIN links ON linkcatz.link=links.sn" + . " INNER JOIN linkcat ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.cat=" . $$row1{"sn"} + . " AND NOT links.hid;\n"; + $sth2 = $DBH->prepare($sql2); + $sth2->execute; + $row2 = $sth2->fetchrow_hashref; + $$row1{"links"} = $$row2{"count"}; + push @{$$page{"scats"}}, $row1; + } + + # Find the belonging links + @_ = map "links.$_", $DBH->cols("links"); + $sql1 = "SELECT " . join(", ", @_) . " FROM links" + . " INNER JOIN linkcatz ON linkcatz.link=links.sn" + . " WHERE linkcatz.cat=" . $$page{"sn"} + . " AND NOT links.hid" + . " ORDER BY lower(links.title);\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"links"} = []; $i < $count1; $i++) { + $row1 = $sth1->fetchrow_hashref; + push @{$$page{"links"}}, $row1; + } + + # Build each language + foreach my $lang (@ALL_LINGUAS) { + my $html; + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + } + set_l10n; + } + + # Build the root index page + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE parent IS NULL" + . " AND linkcat_isshown(sn, hid, parent)" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @_ = qw(); $_ < $count; $_++) { + my ($cat, $sql1, $sth1, $count1); + $cat = $sth->fetchrow_hashref; + + # Find the belonging links + $sql1 = "SELECT count(linkcatz.sn) AS count FROM linkcatz" + . " INNER JOIN links ON linkcatz.link=links.sn" + . " INNER JOIN linkcat ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.cat=" . $$cat{"sn"} + . " AND NOT links.hid;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $$cat{"links"} = ${$sth1->fetch}[0]; + + push @_, $cat; + } + # Build each language + foreach my $lang (@ALL_LINGUAS) { + my ($args, $html, $FD); + set_l10n $lang; + $ALT_PAGE_PARAM = { + "path" => "/links/", + "lang" => $lang, + "keywords" => __("related links"), + "class" => "links", + "javascripts" => [qw(/scripts/links.js)], + "static" => 1, + "all_linguas" => [@ALL_LINGUAS], + "no_auto_title" => 1}; + $args = page_param; + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header __("Keep Travelling..."), $args; + html_title __("Continue Your Journey..."); + html_links_index @_, $args; + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $html = join "", <$FD>; + undef $ALT_PAGE_PARAM; + goutpage $html, "/links/", $lang; + } + set_l10n; + + return; +} + +# rebuild_diary: Rebuild the diary +sub rebuild_diary(;$) { + local ($_, %_); + my ($start, $sql, $sth, $count, $page, @pages, $total); + $start = $_[0]; + $start = 1 if !defined $start; + + # Obtain the total number of diary entries + $_ = "SELECT count(*) FROM diary WHERE NOT hid;\n"; + $sth = $DBH->prepare($_); + $sth->execute; + $total = ${$sth->fetch}[0]; + + # Obtain all the available pages numbers + @_ = qw(); + push @_, "pageno AS no"; + push @_, "diary_page_start(pageno) AS start"; + push @_, "diary_page_end(pageno) AS end"; + $sql = "SELECT " . join(", ", @_) . " FROM diary" + . " WHERE NOT hid GROUP BY pageno ORDER BY pageno;\n"; + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @pages = qw(); $i < $count; $i++) { + $page = $sth->fetchrow_hashref; + $$page{"path"} = sprintf "/me/diary/%04d.html", $$page{"no"}; + push @pages, $page; + } + + # Build each page + foreach my $page (@pages) { + next if $$page{"no"} < $start; + # Build each language + foreach my $lang (@ALL_LINGUAS) { + my ($lndb, $args, $LIST, $html, $FD); + $lndb = ln($lang, LN_DATABASE); + set_l10n $lang; + if ($lang eq "zh-tw") { + Lingua::ZH::Numbers->charset("traditional"); + $_ = number_to_zh($$page{"no"}); + } elsif ($lang eq "zh-cn") { + Lingua::ZH::Numbers->charset("simplified"); + $_ = number_to_zh($$page{"no"}); + } else { + $_ = fmtno($$page{"no"}); + } + $$page{"title"} = sprintf __("Tavern Diary Volume %s"), $_; + $$page{"kw"} = __("diary"); + $ALT_PAGE_PARAM = { + "path" => $$page{"path"}, + "lang" => $lang, + "keywords" => $$page{"kw"}, + "class" => "me", + "static" => 1, + "all_linguas" => [@ALL_LINGUAS], + "no_auto_title" => 1}; + $args = page_param; + # Set the list parameter + $LIST = new Selima::imacat::List::Diary::Public; + $LIST->{"view"} = "diary_public_$lndb"; + $LIST->{"pageno"} = $$page{"no"}; + $LIST->{"lastpage"} = ${$pages[$#pages]}{"no"}; + $LIST->{"total"} = $total; + $args = {%$args, %{$LIST->page_param}}; + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header $$page{"title"}, $args; + html_title $$page{"title"}; + $LIST->html($args); + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $html = join "", <$FD>; + undef $ALT_PAGE_PARAM; + goutpage $html, $$page{"path"}, $lang; + } + set_l10n; + } + + # Make the symbolic link for the latest page + if (defined $Config{"d_symlink"}) { + my ($targfile, $linkfile); + foreach my $lang (@ALL_LINGUAS) { + my $langfile; + $langfile = ln($lang, LN_FILENAME); + if (@pages > 0) { + $targfile = sprintf "%04d.html.$langfile.xhtml", + ${$pages[$#pages]}{"no"}; + } else { + $targfile = "index.html.$langfile.xhtml"; + } + $linkfile = "$DOC_ROOT/me/diary/latest.html.$langfile.xhtml"; + unless (-l $linkfile && readlink $linkfile eq $targfile) { + unlink $linkfile if -l $linkfile; + symlink $targfile, $linkfile; + } + $targfile = "latest.html.$langfile.xhtml"; + $linkfile = "$DOC_ROOT/me/diary/latest.html.$langfile.html"; + unless (-l $linkfile && readlink $linkfile eq $targfile) { + unlink $linkfile if -l $linkfile; + symlink $targfile, $linkfile; + } + } + } + + # Build the root index page + # Build each language + foreach my $lang (@ALL_LINGUAS) { + my ($args, $html, $FD); + set_l10n $lang; + $ALT_PAGE_PARAM = { + "path" => "/me/diary/", + "lang" => $lang, + "keywords" => __("diary"), + "class" => "me", + "static" => 1, + "all_linguas" => [@ALL_LINGUAS], + "no_auto_title" => 1, + "toc" => ".."}; + if (@pages > 0) { + $$ALT_PAGE_PARAM{"first"} = "0001.html"; + $$ALT_PAGE_PARAM{"last"} = "latest.html"; + ${$pages[$#pages]}{"path"} = "/me/diary/latest.html"; + } + $args = page_param; + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header __("Tavern Diary"), $args; + html_title __("Tavern Diary"); + html_diary_index @pages, $args; + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $html = join "", <$FD>; + undef $ALT_PAGE_PARAM; + goutpage $html, "/me/diary/", $lang; + } + set_l10n; + + return; +} + +# rebuild_changelog: Rebuild the change log +sub rebuild_changelog(;$) { + local ($_, %_); + my ($start, $sql, $sth, $count, $page, @pages, $total); + $start = $_[0]; + $start = 1 if !defined $start; + + # Obtain the total number of change log entries + $_ = "SELECT count(*) FROM changelog WHERE NOT hid;\n"; + $sth = $DBH->prepare($_); + $sth->execute; + $total = ${$sth->fetch}[0]; + + # Obtain all the available pages numbers + @_ = qw(); + push @_, "pageno AS no"; + push @_, "changelog_page_start(pageno) AS start"; + push @_, "changelog_page_end(pageno) AS end"; + $sql = "SELECT " . join(", ", @_) . " FROM changelog" + . " WHERE NOT hid GROUP BY pageno ORDER BY pageno;\n"; + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @pages = qw(); $i < $count; $i++) { + $page = $sth->fetchrow_hashref; + $$page{"path"} = sprintf "/me/changelog/%04d.html", $$page{"no"}; + push @pages, $page; + } + + # Build each page + foreach my $page (@pages) { + next if $$page{"no"} < $start; + # Build each language + foreach my $lang (@ALL_LINGUAS) { + my ($lndb, $args, $LIST, $html, $FD); + $lndb = ln($lang, LN_DATABASE); + set_l10n $lang; + if ($lang eq "zh-tw") { + Lingua::ZH::Numbers->charset("traditional"); + $_ = number_to_zh($$page{"no"}); + } elsif ($lang eq "zh-cn") { + Lingua::ZH::Numbers->charset("simplified"); + $_ = number_to_zh($$page{"no"}); + } else { + $_ = fmtno($$page{"no"}); + } + $$page{"title"} = sprintf __("Tavern Change Log Volume %s"), $_; + $$page{"kw"} = __("change log, history"); + $ALT_PAGE_PARAM = { + "path" => $$page{"path"}, + "lang" => $lang, + "keywords" => $$page{"kw"}, + "class" => "me", + "static" => 1, + "all_linguas" => [@ALL_LINGUAS], + "no_auto_title" => 1}; + $args = page_param; + # Set the list parameter + $LIST = new Selima::imacat::List::ChangeLog::Public; + $LIST->{"view"} = "changelog_public_$lndb"; + $LIST->{"pageno"} = $$page{"no"}; + $LIST->{"lastpage"} = ${$pages[$#pages]}{"no"}; + $LIST->{"total"} = $total; + $args = {%$args, %{$LIST->page_param}}; + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header $$page{"title"}, $args; + html_title $$page{"title"}; + $LIST->html($args); + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $html = join "", <$FD>; + undef $ALT_PAGE_PARAM; + goutpage $html, $$page{"path"}, $lang; + } + set_l10n; + } + + # Make the symbolic link for the latest page + if (defined $Config{"d_symlink"}) { + my ($targfile, $linkfile); + foreach my $lang (@ALL_LINGUAS) { + my $langfile; + $langfile = ln($lang, LN_FILENAME); + if (@pages > 0) { + $targfile = sprintf "%04d.html.$langfile.xhtml", + ${$pages[$#pages]}{"no"}; + } else { + $targfile = "index.html.$langfile.xhtml"; + } + $linkfile = "$DOC_ROOT/me/changelog/latest.html.$langfile.xhtml"; + unless (-l $linkfile && readlink $linkfile eq $targfile) { + unlink $linkfile if -l $linkfile; + symlink $targfile, $linkfile; + } + $targfile = "latest.html.$langfile.xhtml"; + $linkfile = "$DOC_ROOT/me/changelog/latest.html.$langfile.html"; + unless (-l $linkfile && readlink $linkfile eq $targfile) { + unlink $linkfile if -l $linkfile; + symlink $targfile, $linkfile; + } + } + } + + # Build the root index page + # Build each language + foreach my $lang (@ALL_LINGUAS) { + my ($args, $html, $FD); + set_l10n $lang; + $ALT_PAGE_PARAM = { + "path" => "/me/changelog/", + "lang" => $lang, + "keywords" => __("change log, history"), + "class" => "me", + "static" => 1, + "all_linguas" => [@ALL_LINGUAS], + "no_auto_title" => 1, + "toc" => ".."}; + if (@pages > 0) { + $$ALT_PAGE_PARAM{"first"} = "0001.html"; + $$ALT_PAGE_PARAM{"last"} = "latest.html"; + ${$pages[$#pages]}{"path"} = "/me/changelog/latest.html"; + } + $args = page_param; + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header __("Tavern Change Log"), $args; + html_title __("Tavern Change Log"); + html_changelog_index @pages, $args; + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $html = join "", <$FD>; + undef $ALT_PAGE_PARAM; + goutpage $html, "/me/changelog/", $lang; + } + set_l10n; + + return; +} + +# rebuild_literalzh: Rebuild the Chinese literal works +sub rebuild_literalzh(;$) { + local ($_, %_); + my ($sql, $sth, $count, $rebuild_everything, $page, @allworks); + my (@all_linguas, $langfilezhtw, $lndbzhtw, $lndbzhcn); + $sql = $_[0]; + @all_linguas = qw(zh-tw zh-cn); + $lndbzhtw = ln("zh-tw", LN_DATABASE); + $lndbzhcn = ln("zh-cn", LN_DATABASE); + $langfilezhtw = ln("zh-tw", LN_FILENAME); + + # Obtain all the pages + { + my ($sql, $sth, $count, $row); + $sql = "SELECT date, title, dsc FROM literalzh" + . " WHERE NOT hid" + . " ORDER BY date;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @allworks = qw(); $i < $count; $i++) { + $row = $sth->fetchrow_hashref; + @_ = localtime $$row{"date"}; + $_[5] += 1900; + $_[4]++; + $$row{"path"} = sprintf("/writings-zh/%04d%02d%02d.html", @_[5,4,3]); + $$row{"title"} = myfmtdate($$row{"date"}) + . (defined $$row{"title"}? " " . $$row{"title"}: ""); + push @allworks, $row; + } + # The latest page has a specific path + ${$allworks[$#allworks]}{"_path"} = ${$allworks[$#allworks]}{"path"}; + ${$allworks[$#allworks]}{"path"} = "/writings-zh/latest.html"; + undef $sth; + } + + # Rebuild everything + $rebuild_everything = !defined $sql; + if ($rebuild_everything) { + $sql = "SELECT * FROM literalzh" + . " WHERE NOT hid" + . " ORDER BY date;\n"; + } + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0; $i < $count; $i++) { + my ($page, $sql1, $sth1, $count1, $row1); + $page = $sth->fetchrow_hashref; + @_ = localtime $$page{"date"}; + $_[5] += 1900; + $_[4]++; + $$page{"path"} = sprintf("/writings-zh/%04d%02d%02d.html", @_[5,4,3]); + $$page{"all_linguas"} = [@all_linguas]; + $$page{"allworks"} = [@allworks]; + $$page{"title"} = "詩 " . myfmtdate($$page{"date"}) + . (defined $$page{"title"}? " " . $$page{"title"}: ""); + # Make the multilingual columns + foreach my $col (qw(title dsc kw)) { + $$page{$col . "_$lndbzhtw"} = $$page{$col}; + $$page{$col . "_$lndbzhcn"} = all_to_simp($$page{$col}); + delete $$page{$col}; + } + + # Find the poems + $sql1 = "SELECT * FROM ltzhpoem" + . " WHERE set=" . $$page{"sn"} + . " AND NOT hid" + . " ORDER BY ord;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"poems"} = []; $i < $count1; $i++) { + my $poem; + $poem = $sth1->fetchrow_hashref; + # Make the multilingual columns + foreach my $col (qw(title body)) { + $$poem{$col . "_$lndbzhtw"} = $$poem{$col}; + $$poem{$col . "_$lndbzhcn"} = all_to_simp($$poem{$col}); + delete $$poem{$col}; + } + push @{$$page{"poems"}}, $poem; + } + + # Build each language + foreach my $lang (@all_linguas) { + my $html; + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + } + set_l10n; + } + + # Make the symbolic link for the latest page + if (defined $Config{"d_symlink"}) { + my ($targfile, $linkfile); + foreach my $lang (@all_linguas) { + my $langfile; + $langfile = ln($lang, LN_FILENAME); + if (@allworks > 0) { + $targfile = basename(${$allworks[$#allworks]}{"_path"} . ".$langfile.xhtml"); + } else { + $targfile = "index.html.$langfile.xhtml"; + } + $linkfile = "$DOC_ROOT/writings-zh/latest.html.$langfile.xhtml"; + unless (-l $linkfile && readlink $linkfile eq $targfile) { + unlink $linkfile if -l $linkfile; + symlink $targfile, $linkfile; + } + $targfile = "latest.html.$langfile.xhtml"; + $linkfile = "$DOC_ROOT/writings-zh/latest.html.$langfile.html"; + unless (-l $linkfile && readlink $linkfile eq $targfile) { + unlink $linkfile if -l $linkfile; + symlink $targfile, $linkfile; + } + } + } + + # Build the root index page + # Obtain the page + $sql = "SELECT * FROM pages WHERE path='/writings-zh/';\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $page = $sth->fetchrow_hashref; + $$page{"all_linguas"} = [@all_linguas]; + $$page{"allworks"} = [@allworks]; + # Build each language + foreach my $lang (@all_linguas) { + my $html; + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + } + set_l10n; + + return; +} + +# rebuild_literalen: Rebuild the English literal works +sub rebuild_literalen(;$) { + local ($_, %_); + my ($sql, $sth, $count, $rebuild_everything, $page, @allworks); + my (@all_linguas, $lang); + $sql = $_[0]; + $lang = "en"; + @all_linguas = @ALL_LINGUAS; + @ALL_LINGUAS = ($lang); + + # Obtain all the pages + { + my ($sql, $sth, $count, $row); + $sql = "SELECT date, title, dsc FROM literalen" + . " WHERE NOT hid" + . " ORDER BY date;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @allworks = qw(); $i < $count; $i++) { + $row = $sth->fetchrow_hashref; + @_ = localtime $$row{"date"}; + $_[5] += 1900; + $_[4]++; + $$row{"path"} = sprintf("/writings-en/%04d%02d%02d.html", @_[5,4,3]); + $$row{"title"} = myfmtdate($$row{"date"}) + . (defined $$row{"title"}? " " . $$row{"title"}: ""); + push @allworks, $row; + } + # The latest page has a specific path + ${$allworks[$#allworks]}{"_path"} = ${$allworks[$#allworks]}{"path"}; + ${$allworks[$#allworks]}{"path"} = "/writings-en/latest.html"; + undef $sth; + } + + # Rebuild everything + $rebuild_everything = !defined $sql; + if ($rebuild_everything) { + $sql = "SELECT * FROM literalen" + . " WHERE NOT hid" + . " ORDER BY date;\n"; + } + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0; $i < $count; $i++) { + my ($page, $html); + $page = $sth->fetchrow_hashref; + @_ = localtime $$page{"date"}; + $_[5] += 1900; + $_[4]++; + $$page{"path"} = sprintf("/writings-en/%04d%02d%02d.html", @_[5,4,3]); + $$page{"all_linguas"} = [$lang]; + $$page{"allworks"} = [@allworks]; + + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + } + + # Make the symbolic link for the latest page + if (defined $Config{"d_symlink"}) { + my ($targfile, $linkfile); + if (@allworks > 0) { + $targfile = basename(${$allworks[$#allworks]}{"_path"} . ".xhtml"); + } else { + $targfile = "index.html.xhtml"; + } + $linkfile = sprintf "%s/writings-en/latest.html.xhtml", $DOC_ROOT; + unless (-l $linkfile && readlink $linkfile eq $targfile) { + unlink $linkfile if -l $linkfile; + symlink $targfile, $linkfile; + } + $targfile = "latest.html.xhtml"; + $linkfile = sprintf "%s/writings-en/latest.html.html", $DOC_ROOT; + unless (-l $linkfile && readlink $linkfile eq $targfile) { + unlink $linkfile if -l $linkfile; + symlink $targfile, $linkfile; + } + } + + # Build the root index page + $page = {}; + $$page{"path"} = "/writings-en/"; + $$page{"all_linguas"} = [$lang]; + $$page{"allworks"} = [@allworks]; + $$page{"title"} = "My English Writings"; + my $html; + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + + @ALL_LINGUAS = @all_linguas; + return; +} + +# compose_page: Compose a page +sub compose_page($;$) { + local ($_, %_); + my ($page, $lang, $lndb, @all_linguas, $args, $path, $FD); + ($page, $lang) = @_; + $lang = getlang if !defined $lang; + # Language in other formats + $lndb = ln($lang, LN_DATABASE); + # Get the available languages for this page + @all_linguas = page_all_linguas $page; + + if (!exists $$page{"title"} || !defined $$page{"title"}) { + my (%keysml, $keyml); + # Return if there is no content in this language + return if !exists $$page{"title_$lndb"} + || !defined $$page{"title_$lndb"}; + # Hash the multi-lingual columns + eval Data::Dumper->Dump([$page], [qw($_)]); + %keysml = map { $_ => 1 } keys_ml %$page; + $page = {}; + foreach my $key (keys_nl %$_) { + $keyml = exists $keysml{$key}? $key . "_" . $lndb : $key; + # We need a copy, not a reference to the same thing + if (ref $$_{$keyml} eq "") { + $$page{$key} = $$_{$keyml}; + } else { + eval Data::Dumper->Dump([$$_{$keyml}], [qw($$page{$key})]); + } + } + } + + $ALT_PAGE_PARAM = { + "path" => $$page{"path"}, + "lang" => $lang, + "keywords" => $$page{"kw"}, + "static" => 1, + "all_linguas" => [@all_linguas], + "no_auto_title" => exists $$page{"no_auto_title"} + && $$page{"no_auto_title"}}; + $$ALT_PAGE_PARAM{"preview"} = $page + if exists $$page{"preview"}; + if (exists $$page{"class"} && defined $$page{"class"} && $$page{"class"} ne "") { + $$ALT_PAGE_PARAM{"class"} = $$page{"class"}; + } elsif ($$page{"path"} =~ /^\/links\//) { + $$ALT_PAGE_PARAM{"class"} = "links"; + } elsif ($$page{"path"} =~ /^\/tech\//) { + $$ALT_PAGE_PARAM{"class"} = "tech"; + } elsif ($$page{"path"} =~ /^\/les\//) { + $$ALT_PAGE_PARAM{"class"} = "les"; + } elsif ($$page{"path"} =~ /^\/me\//) { + $$ALT_PAGE_PARAM{"class"} = "me"; + } elsif ($$page{"path"} =~ /^\/writings-zh\//) { + $$ALT_PAGE_PARAM{"class"} = "literalzh"; + } elsif ($$page{"path"} =~ /^\/writings-en\//) { + $$ALT_PAGE_PARAM{"class"} = "literalen"; + } else { + $$ALT_PAGE_PARAM{"class"} = "misc"; + } + $args = page_param; + + # Special rules for Chinese literal works + if ($$page{"path"} =~ /^\/writings-zh\/(?:\d{8}|latest)\.html$/) { + # The relative pages + $$args{"first"} = ${${$$page{"allworks"}}[0]}{"path"}; + for ($_ = 0; $_ < @{$$page{"allworks"}}; $_++) { + last if ${${$$page{"allworks"}}[$_]}{"date"} == $$page{"date"}; + } + $$args{"prev"} = ${${$$page{"allworks"}}[$_ - 1]}{"path"} + if $_ > 0; + $$args{"next"} = ${${$$page{"allworks"}}[$_ + 1]}{"path"} + if $_ < $#{$$page{"allworks"}}; + $$args{"last"} = "/writings-zh/latest.html"; + + # Obtain the page bar + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_ltzh_pagebar $_, @{$$page{"allworks"}}, $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + if ($_ ne "") { + $$args{"header_html_nav"} = $_; + $$args{"footer_html_nav"} = $_; + } + # Special rules for Chinese literal works + } elsif ($$page{"path"} =~ /^\/writings-en\/(?:\d{8}|latest)\.html$/) { + # The relative pages + $$args{"first"} = ${${$$page{"allworks"}}[0]}{"path"}; + for ($_ = 0; $_ < @{$$page{"allworks"}}; $_++) { + last if ${${$$page{"allworks"}}[$_]}{"date"} == $$page{"date"}; + } + $$args{"prev"} = ${${$$page{"allworks"}}[$_ - 1]}{"path"} + if $_ > 0; + $$args{"next"} = ${${$$page{"allworks"}}[$_ + 1]}{"path"} + if $_ < $#{$$page{"allworks"}}; + $$args{"last"} = "/writings-en/latest.html"; + + # Obtain the page bar + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_lten_pagebar $_, @{$$page{"allworks"}}, $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + if ($_ ne "") { + $$args{"header_html_nav"} = $_; + $$args{"footer_html_nav"} = $_; + } + } + + # Obtain the page + set_l10n $lang; + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header $$page{"title"}, $args; + if ($$page{"path"} =~ /^\/links\/$/) { + #html_links_index $page, $args; + } elsif ($$page{"path"} =~ /^\/links\/.+$/) { + html_links $page, $args; + } elsif ($$page{"path"} =~ /^\/writings-zh\/$/) { + html_ltzh_index $page, $args; + } elsif ($$page{"path"} =~ /^\/writings-zh\/(?:\d{8}|latest)\.html$/) { + html_ltzh_body $page, $args; + } elsif ($$page{"path"} =~ /^\/writings-en\/$/) { + html_lten_index $page, $args; + } elsif ($$page{"path"} =~ /^\/writings-en\/(?:\d{8}|latest)\.html$/) { + html_body $page, $args; + } else { + html_body $page, $args; + } + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + set_l10n; + + undef $ALT_PAGE_PARAM; + return $_; +} + +no utf8; +return 1; diff --git a/htdocs/imacat/magicat/locale/zh/LC_MESSAGES/imacat.mo b/htdocs/imacat/magicat/locale/zh/LC_MESSAGES/imacat.mo new file mode 100644 index 0000000..29fc1ed Binary files /dev/null and b/htdocs/imacat/magicat/locale/zh/LC_MESSAGES/imacat.mo differ diff --git a/htdocs/imacat/magicat/locale/zh_CN/LC_MESSAGES/imacat.mo b/htdocs/imacat/magicat/locale/zh_CN/LC_MESSAGES/imacat.mo new file mode 100644 index 0000000..8641ed7 Binary files /dev/null and b/htdocs/imacat/magicat/locale/zh_CN/LC_MESSAGES/imacat.mo differ diff --git a/htdocs/imacat/magicat/locale/zh_TW/LC_MESSAGES/imacat.mo b/htdocs/imacat/magicat/locale/zh_TW/LC_MESSAGES/imacat.mo new file mode 100644 index 0000000..cffcd7f Binary files /dev/null and b/htdocs/imacat/magicat/locale/zh_TW/LC_MESSAGES/imacat.mo differ diff --git a/htdocs/imacat/magicat/phpinfo.php b/htdocs/imacat/magicat/phpinfo.php new file mode 100644 index 0000000..147cebc --- /dev/null +++ b/htdocs/imacat/magicat/phpinfo.php @@ -0,0 +1 @@ + diff --git a/htdocs/imacat/magicat/phpinfo.phpcgi b/htdocs/imacat/magicat/phpinfo.phpcgi new file mode 120000 index 0000000..7c4c79f --- /dev/null +++ b/htdocs/imacat/magicat/phpinfo.phpcgi @@ -0,0 +1 @@ +phpinfo.php \ No newline at end of file diff --git a/htdocs/imacat/magicat/po/Makefile b/htdocs/imacat/magicat/po/Makefile new file mode 100644 index 0000000..47e25d0 --- /dev/null +++ b/htdocs/imacat/magicat/po/Makefile @@ -0,0 +1,49 @@ +# Possible make targets: +# all: Compile the PO files and copy the binary MO files +# into the appropriate directories +# xgettext: Obtain the newest PO template file $(PACKAGE).pot +# from the source programs, and do msgmerge to compare +# the $(PACKAGE).pot and existing PO files to obtain +# the newest POX files to work with + + +PACKAGE = imacat +#ALLLINGUAS = en_US zh_TW zh_CN +ALLLINGUAS = zh_TW zh_CN +PKGROOT = ../.. +PODIR = magicat/po +LOCALEDIR = $(PKGROOT)/magicat/locale +CATEGORY = LC_MESSAGES +PROGRAMS = cgi-bin/*.cgi magicat/cgi-bin/*.cgi magicat/lib/perl5/*/*.pm magicat/lib/perl5/*/*/*.pm magicat/lib/perl5/*/*/*/*.pm magicat/lib/perl5/*/*/*/*/*.pm + +all: + opencc -c tw2sp.json -i zh_TW.po -o /dev/stdout \ + | sed "s/^# Traditional Chinese PO file for the /# Simplified Chinese PO file for the /" \ + | sed "s/^\"PO-Revision-Date: .*\"/\"PO-Revision-Date: `date \"+%Y-%m-%d %H:%M%z\"`\\\\n\"/" \ + > zh_CN.po; \ + for ln in $(ALLLINGUAS); do \ + msgfmt $$ln.po -o $$ln.gmo; \ + test -d $(LOCALEDIR) || \ + (rm -rf $(LOCALEDIR) && \ + mkdir $(LOCALEDIR)); \ + test -d $(LOCALEDIR)/$$ln || \ + (rm -rf $(LOCALEDIR)/$$ln && \ + mkdir $(LOCALEDIR)/$$ln); \ + test -d $(LOCALEDIR)/$$ln/$(CATEGORY) || \ + (rm -rf $(LOCALEDIR)/$$ln/$(CATEGORY) && \ + mkdir $(LOCALEDIR)/$$ln/$(CATEGORY)); \ + rm -f $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + cp $$ln.gmo $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + done + +xgettext: + cd $(PKGROOT); \ + xgettext --keyword=__ --keyword=N_ -p $(PODIR)/ -o $(PACKAGE).pot \ + --language=c $(PROGRAMS); \ + cd $(PODIR); \ + for ln in $(ALLLINGUAS); do \ + msgmerge $$ln.po $(PACKAGE).pot > $$ln.pox; \ + done + +clean: + rm -f *.gmo diff --git a/htdocs/imacat/magicat/po/imacat.pot b/htdocs/imacat/magicat/po/imacat.pot new file mode 100644 index 0000000..28c8c5f --- /dev/null +++ b/htdocs/imacat/magicat/po/imacat.pot @@ -0,0 +1,2517 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-03-24 07:09+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: cgi-bin/1-guestbook.cgi:40 cgi-bin/1-guestbook.cgi:111 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:282 +msgid "Travellers' Guestbook" +msgstr "" + +#: cgi-bin/1-guestbook.cgi:112 +msgid "" +"

    Tavern IMACAT’s

    \n" +"

    Travellers’
    Guestbook

    " +msgstr "" + +#: cgi-bin/1-guestbook.cgi:129 +msgid "Good morning to thee, gentle friend and traveller!" +msgstr "" + +#: cgi-bin/1-guestbook.cgi:130 +msgid "" +"I call thee \"traveller\" no matter if thou hast never left thy home town, " +"no matter if thou wilst never again leave thy room, because all of us are " +"travellers. I call thee traveller for truly all of us travel a spiritual or " +"philosophical path -- even if it is simply by living the life that we choose " +"to live, or by searching for a new life when our current one fails to " +"satisfy our needs as thinking spiritual beings." +msgstr "" + +#: cgi-bin/1-guestbook.cgi:133 +msgid "-- The Book of Fellowship, Ultima VII" +msgstr "" + +#: cgi-bin/garbage.cgi:40 +msgid "garbage, daub, poetry, message, essay" +msgstr "" + +#: cgi-bin/garbage.cgi:110 magicat/lib/perl5/Selima/imacat/List/Search.pm:291 +msgid "Soundless Backalley" +msgstr "" + +#: cgi-bin/garbage.cgi:111 +msgid "" +"

    The

    \n" +"

    Soundless
    Backalley

    " +msgstr "" + +#: cgi-bin/garbage.cgi:128 +msgid "" +"This is the backalley of Tavern. Every morning barmaid Cotton will put " +"garbages here. Besides that, there's never anyone passing by. Just " +"stinking garbages, drunks unable to tell dead or alive, cats and dogs and " +"flies, piss and vomits. The wall is filled with drawings and words unable " +"to tell whether they are poetry or shits. The vague music and laughters " +"come so faraway from inside the Tavern, like a neverending rhythm repeats " +"itself. The sun is blocked by the buildings. Even the time stops." +msgstr "" + +#: cgi-bin/garbage.cgi:129 +msgid "" +"There's no one here, just you and yourself. Soundless is the loudest " +"sound. No matter how hard if you cry, shout or scream, you're still alone. " +"This is the darkest and the loneliest corner in the Tavern." +msgstr "" + +#: cgi-bin/plurkavatar.cgi:41 cgi-bin/plurkfav.cgi:43 +msgid "Plurk" +msgstr "" + +#: cgi-bin/plurkavatar.cgi:65 +msgid "There is no Plurk user \"[_1]\"." +msgstr "" + +#: cgi-bin/plurkavatar.cgi:68 +msgid "Avator is not found for user \"[_1]\"." +msgstr "" + +#: cgi-bin/plurkavatar.cgi:72 +msgid "Plurk service is not available now." +msgstr "" + +#: cgi-bin/plurkavatar.cgi:75 +msgid "Please fill in the Plurk user." +msgstr "" + +#: cgi-bin/plurkavatar.cgi:89 +msgid "Plurk Avatars" +msgstr "" + +#: cgi-bin/plurkavatar.cgi:96 +msgid "Plurk Avatars for User [_1]" +msgstr "" + +#: cgi-bin/plurkavatar.cgi:121 +msgid "Plurk user:" +msgstr "" + +#: cgi-bin/plurkfav.cgi:52 +msgid "Plurk Favorites" +msgstr "" + +#: cgi-bin/plurkfav.cgi:86 +msgid "Plurk permanent link URL:" +msgstr "" + +#: cgi-bin/plurkfav.cgi:105 +msgid "Plurk ID: [_1]" +msgstr "" + +#: cgi-bin/plurkfav.cgi:106 +msgid "Set Plurk favorite" +msgstr "" + +#: cgi-bin/plurkfav.cgi:107 +msgid "Unset Plurk favorite" +msgstr "" + +#: cgi-bin/search.cgi:43 +msgid "search, query, full text search" +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:44 magicat/cgi-bin/acctreps.cgi:39 +#: magicat/cgi-bin/acctsubj.cgi:42 magicat/cgi-bin/accttrx.cgi:43 +msgid "accounting" +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:110 magicat/cgi-bin/acctrecs.cgi:157 +#: magicat/cgi-bin/acctsubj.cgi:120 magicat/cgi-bin/acctsubj.cgi:180 +#: magicat/cgi-bin/accttrx.cgi:110 magicat/cgi-bin/accttrx.cgi:157 +#: magicat/cgi-bin/changelog.cgi:110 magicat/cgi-bin/changelog.cgi:159 +#: magicat/cgi-bin/diary.cgi:110 magicat/cgi-bin/diary.cgi:159 +#: magicat/cgi-bin/garbage.cgi:104 magicat/cgi-bin/garbage.cgi:148 +#: magicat/cgi-bin/groupmem.cgi:108 magicat/cgi-bin/groupmem.cgi:153 +#: magicat/cgi-bin/groups.cgi:121 magicat/cgi-bin/groups.cgi:176 +#: magicat/cgi-bin/guestbook.cgi:104 magicat/cgi-bin/guestbook.cgi:150 +#: magicat/cgi-bin/linkcat.cgi:119 magicat/cgi-bin/linkcat.cgi:177 +#: magicat/cgi-bin/linkcatz.cgi:108 magicat/cgi-bin/linkcatz.cgi:153 +#: magicat/cgi-bin/links.cgi:110 magicat/cgi-bin/links.cgi:161 +#: magicat/cgi-bin/literalen.cgi:161 magicat/cgi-bin/literalen.cgi:205 +#: magicat/cgi-bin/literalzh.cgi:175 magicat/cgi-bin/literalzh.cgi:219 +#: magicat/cgi-bin/ltzhpoem.cgi:106 magicat/cgi-bin/ltzhpoem.cgi:151 +#: magicat/cgi-bin/pages.cgi:114 magicat/cgi-bin/pages.cgi:163 +#: magicat/cgi-bin/papers.cgi:108 magicat/cgi-bin/papers.cgi:154 +#: magicat/cgi-bin/pprauthr.cgi:105 magicat/cgi-bin/pprauthr.cgi:150 +#: magicat/cgi-bin/pprtags.cgi:105 magicat/cgi-bin/pprtags.cgi:150 +#: magicat/cgi-bin/pprtypes.cgi:112 magicat/cgi-bin/pprtypes.cgi:165 +#: magicat/cgi-bin/resrcher.cgi:109 magicat/cgi-bin/resrcher.cgi:157 +#: magicat/cgi-bin/scptpriv.cgi:106 magicat/cgi-bin/scptpriv.cgi:151 +#: magicat/cgi-bin/tags.cgi:109 magicat/cgi-bin/tags.cgi:157 +#: magicat/cgi-bin/usermem.cgi:108 magicat/cgi-bin/usermem.cgi:153 +#: magicat/cgi-bin/userpref.cgi:106 magicat/cgi-bin/userpref.cgi:151 +#: magicat/cgi-bin/users.cgi:125 magicat/cgi-bin/users.cgi:189 +msgid "Incorrect form: [_1]." +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:204 +msgid "Please select the accounting record." +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:212 +msgid "" +"This accounting record does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:93 magicat/cgi-bin/acctsubj.cgi:140 +msgid "Please add a new accounting subject from [_1]." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:109 magicat/cgi-bin/acctsubj.cgi:169 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the subject, " +"[numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] " +"must first be deleted." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:113 magicat/cgi-bin/acctsubj.cgi:173 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the subject, [numerate,_1,its " +"accounting record,all of its accounting records] must first be deleted." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:232 +msgid "Please select the accounting subject." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:240 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/accttrx.cgi:204 +msgid "Please select the accounting transaction." +msgstr "" + +#: magicat/cgi-bin/accttrx.cgi:212 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "" + +#: magicat/cgi-bin/actlog.cgi:36 +msgid "activity, logs" +msgstr "" + +#: magicat/cgi-bin/changelog.cgi:42 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:472 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:539 +msgid "change log, history" +msgstr "" + +#: magicat/cgi-bin/changelog.cgi:91 magicat/cgi-bin/changelog.cgi:128 +msgid "Please write a new log entry from [_1]." +msgstr "" + +#: magicat/cgi-bin/changelog.cgi:206 +msgid "Please select the log entry." +msgstr "" + +#: magicat/cgi-bin/changelog.cgi:214 +msgid "This log entry does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/diary.cgi:42 magicat/lib/perl5/Selima/imacat/Rebuild.pm:327 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:394 +msgid "diary" +msgstr "" + +#: magicat/cgi-bin/diary.cgi:91 magicat/cgi-bin/diary.cgi:128 +msgid "Please write a new diary entry from [_1]." +msgstr "" + +#: magicat/cgi-bin/diary.cgi:206 +msgid "Please select the diary entry." +msgstr "" + +#: magicat/cgi-bin/diary.cgi:214 +msgid "This diary entry does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/funds.cgi:36 +msgid "mutual funds, performance, indicators" +msgstr "" + +#: magicat/cgi-bin/garbage.cgi:40 +msgid "backalley" +msgstr "" + +#: magicat/cgi-bin/garbage.cgi:195 magicat/cgi-bin/guestbook.cgi:197 +msgid "Please select the message." +msgstr "" + +#: magicat/cgi-bin/garbage.cgi:203 magicat/cgi-bin/guestbook.cgi:205 +msgid "This message does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:44 +msgid "group membership" +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:200 magicat/cgi-bin/usermem.cgi:200 +msgid "Please select the membership record." +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:208 magicat/cgi-bin/usermem.cgi:208 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/groups.cgi:48 +msgid "groups" +msgstr "" + +#: magicat/cgi-bin/groups.cgi:98 magicat/cgi-bin/groups.cgi:140 +msgid "Please create a new group from [_1]." +msgstr "" + +#: magicat/cgi-bin/groups.cgi:224 +msgid "Please select the group." +msgstr "" + +#: magicat/cgi-bin/groups.cgi:232 +msgid "This group does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/guestbook.cgi:40 +msgid "guestbook" +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:43 +msgid "link categories" +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:92 magicat/cgi-bin/linkcat.cgi:137 +msgid "Please add a new category from [_1]." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:108 magicat/cgi-bin/linkcat.cgi:166 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:112 magicat/cgi-bin/linkcat.cgi:170 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:225 +msgid "Please select the category." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:233 +msgid "This category does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:44 +msgid "link categorization" +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:200 +msgid "Please select the categorization record." +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:208 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "" + +#: magicat/cgi-bin/links.cgi:42 magicat/lib/perl5/Selima/imacat/Rebuild.pm:254 +msgid "related links" +msgstr "" + +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:128 +msgid "Please add a new related link from [_1]." +msgstr "" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Manage Keep Travelling" +msgstr "" + +#: magicat/cgi-bin/links.cgi:211 +msgid "Please select the related link." +msgstr "" + +#: magicat/cgi-bin/links.cgi:219 +msgid "This related link does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/literalen.cgi:43 +msgid "English literal works" +msgstr "" + +#: magicat/cgi-bin/literalen.cgi:259 +msgid "Please select the English literal work." +msgstr "" + +#: magicat/cgi-bin/literalen.cgi:267 +msgid "" +"This English literal work does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/literalzh.cgi:44 +msgid "Chinese literal works" +msgstr "" + +#: magicat/cgi-bin/literalzh.cgi:273 +msgid "Please select the Chinese literal work." +msgstr "" + +#: magicat/cgi-bin/literalzh.cgi:281 +msgid "" +"This Chinese literal work does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/logout.cgi:39 +msgid "log out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:112 magicat/cgi-bin/logout.cgi:119 +msgid "Log Out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:135 +msgid "Are you sure you want to log out?" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:136 magicat/lib/perl5/Selima/imacat/HTML.pm:577 +msgid "Log out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:152 +msgid "Log in again." +msgstr "" + +#: magicat/cgi-bin/ltzhpoem.cgi:42 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:253 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:262 +msgid "Chinese poems" +msgstr "" + +#: magicat/cgi-bin/ltzhpoem.cgi:199 +msgid "Please select the Chinese poem." +msgstr "" + +#: magicat/cgi-bin/ltzhpoem.cgi:207 +msgid "This Chinese poem does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/pages.cgi:40 +msgid "pages" +msgstr "" + +#: magicat/cgi-bin/pages.cgi:89 magicat/cgi-bin/pages.cgi:132 +msgid "Please add a new page from [_1]." +msgstr "" + +#: magicat/cgi-bin/pages.cgi:216 +msgid "Please select the page." +msgstr "" + +#: magicat/cgi-bin/pages.cgi:224 +msgid "This page does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/papers.cgi:44 magicat/cgi-bin/pprauthr.cgi:41 +#: magicat/cgi-bin/pprtags.cgi:41 magicat/cgi-bin/pprtypes.cgi:40 +msgid "papers" +msgstr "" + +#: magicat/cgi-bin/papers.cgi:201 +msgid "Please select the paper." +msgstr "" + +#: magicat/cgi-bin/papers.cgi:209 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:76 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:76 +msgid "This paper does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/pprauthr.cgi:197 +msgid "Please select the paper author." +msgstr "" + +#: magicat/cgi-bin/pprauthr.cgi:205 +msgid "This paper author does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/pprtags.cgi:197 +msgid "Please select the paper tag." +msgstr "" + +#: magicat/cgi-bin/pprtags.cgi:205 +msgid "This paper tag does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/pprtypes.cgi:89 magicat/cgi-bin/pprtypes.cgi:130 +msgid "Please add a new paper type from [_1]." +msgstr "" + +#: magicat/cgi-bin/pprtypes.cgi:105 magicat/cgi-bin/pprtypes.cgi:158 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:89 +msgid "" +"This paper type has [numerate,_1,a paper,papers]. It cannot be deleted. To " +"delete the type, [numerate,_1,its paper,all of its papers] must first be " +"deleted." +msgstr "" + +#: magicat/cgi-bin/pprtypes.cgi:212 +msgid "Please select the paper type." +msgstr "" + +#: magicat/cgi-bin/pprtypes.cgi:220 +msgid "This paper type does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/rebuild.cgi:37 +msgid "rebuild pages" +msgstr "" + +#: magicat/cgi-bin/resrcher.cgi:41 +msgid "researchers" +msgstr "" + +#: magicat/cgi-bin/resrcher.cgi:102 magicat/cgi-bin/resrcher.cgi:150 +#: magicat/cgi-bin/tags.cgi:102 magicat/cgi-bin/tags.cgi:150 +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:88 +msgid "" +"This researcher has [numerate,_1,a paper,papers]. It cannot be deleted. To " +"delete the researcher, [numerate,_1,its paper,all of its papers] must first " +"be deleted." +msgstr "" + +#: magicat/cgi-bin/resrcher.cgi:204 magicat/cgi-bin/tags.cgi:204 +msgid "Please select the researcher." +msgstr "" + +#: magicat/cgi-bin/resrcher.cgi:212 magicat/cgi-bin/tags.cgi:212 +msgid "This researcher does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/saveform.cgi:46 +msgid "saved forms" +msgstr "" + +#: magicat/cgi-bin/saveform.cgi:77 +msgid "Form [_1] does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/saveform.cgi:92 +msgid "Manage the Saved Forms" +msgstr "" + +#: magicat/cgi-bin/saveform.cgi:134 +msgid "Select" +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:42 +msgid "script privilege" +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:198 +msgid "Please select the script privilege record." +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:206 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "" + +#: magicat/cgi-bin/tags.cgi:41 +msgid "tags" +msgstr "" + +#: magicat/cgi-bin/usermem.cgi:44 +msgid "user membership" +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:42 +msgid "user preference" +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:198 +msgid "Please select the user preference." +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:206 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/users.cgi:43 +msgid "users" +msgstr "" + +#: magicat/cgi-bin/users.cgi:237 +msgid "Please select the user." +msgstr "" + +#: magicat/cgi-bin/users.cgi:245 +msgid "This user does not exist anymore. Please select another one." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:52 +msgid "imacat" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:53 +msgid "© imacat. All rights reserved." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:63 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1016 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:409 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:410 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:225 +msgid "Tavern Diary" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:64 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:98 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:234 +msgid "Change Log" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:65 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:108 +msgid "Chinese Literal Works" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:66 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:112 +msgid "English Literal Works" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:90 +msgid "Manage Content" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:92 +msgid "Guestbook" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:94 +msgid "Backalley" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:96 +msgid "Diary" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:100 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:48 +msgid "Pages" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:102 +msgid "Links" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:104 +msgid "Link Categories" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:106 +msgid "Link Categorization" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:110 +msgid "Chinese Poems" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:116 +msgid "Manage Accounts" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:118 +msgid "Users" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:120 +msgid "Groups" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:122 +msgid "User Membership" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:124 +msgid "Group Membership" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:126 +msgid "User Preferences" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:128 +msgid "Script Privileges" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:148 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:39 +msgid "Manage Papers" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:150 +msgid "Papers" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:152 +msgid "Researchers" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:154 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:46 +msgid "Tags" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:156 +msgid "Types" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:158 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:45 +msgid "Authors" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:160 +msgid "Paper Tags" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:164 +msgid "Miscellaneous" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:166 +msgid "Accounting" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:168 +msgid "Funds" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:170 +msgid "Activity Log" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:172 +msgid "Rebuild Pages" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:174 +msgid "Analog" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:176 +msgid "Test Script" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:178 +msgid "MRTG" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:180 +msgid "Saved Forms" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:182 +msgid "CGI Environment" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:186 +msgid "Server Status" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:189 +msgid "Server Information" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:192 +msgid "Bwshare Information" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:195 +msgid "Bwshare Trace" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:198 +msgid "Perl Status" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:253 +msgid "Skip to the page content area." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:254 +msgid "Page Content Area" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:372 +msgid "Magicat" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:441 +msgid "Navigation Links Area" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:521 +msgid "Language Switching Area" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:575 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:617 +#, c-format +msgid "%s:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:689 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:243 +msgid "Keep Travelling" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:757 +msgid "E-mail" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:782 +msgid "URL:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:785 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:920 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:69 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:49 +msgid "E-mail:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:791 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:921 +msgid "Address:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:793 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:922 +msgid "Tel.:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:795 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:923 +msgid "Fax.:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:824 +msgid "" +"Are you ready to check out? Just drop your room key at the counter, and " +"travel for your next stop. Life is a never-ending trip, and Tavern is only " +"one of your many stops. Are you ready to go now?" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:825 +msgid "" +"Greetings, traveller. I'm rinse the Tavern Tour Agent. Where is your next " +"stop?" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:837 +msgid "The database is empty." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:906 +msgid "~[Tavern~] Website Registration" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:907 +msgid "" +"This table provide a form to register your site at Tavern \"Keep Travelling" +"\", the data column names and their input fields to fill in the information." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:908 +msgid "Fill in the description here." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:909 +msgid "Regiser your site" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:910 +msgid "" +"I sincerely wish to build more hyperlinks with websites that're kind to " +"women/lesbian/queer. If you wish to link with me, or if you have any such " +"information, whether in Chinese or not, please tell me by filling this form " +"below. I'll put it in as soon as possible. Thank you." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:911 +msgid "" +"All fields in the form below, Except for the site name, the URL and the " +"description, are optional. Anything you fill here will be shown to " +"ANYONE who visits Tavern IMACAT's. Tavern does not collect " +"any personal informations. If you do not wish to distribute some private " +"informations, just leave them blank. If you represent some organization, " +"fill as detail as possible to help others finding you." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:912 +msgid "General commercial sites besides lesbian shops are not welcome." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:914 +msgid "Site name:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:915 +msgid "Site name, 2nd language (if any):" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:916 +msgid "Site URL:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:917 +msgid "Link logo URL:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:918 +msgid "Category:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:919 +msgid "Introduction:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:924 +msgid "OK!" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1010 +msgid "The diary is empty." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1015 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1075 +msgid "imacat's Private Bed♥room" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1025 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1085 +msgid "Index" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1042 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:326 +#, c-format +msgid "Tavern Diary Volume %s" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1070 +msgid "The change log is empty." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1076 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:554 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:555 +msgid "Tavern Change Log" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1102 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:471 +#, c-format +msgid "Tavern Change Log Volume %s" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1482 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1483 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1496 +msgid "" +"This script is written in Perl." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:264 +msgid "Keep Travelling..." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:265 +msgid "Continue Your Journey..." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:41 +msgid "This specie is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:60 +msgid "This e-mail is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:75 +msgid "Please choose the language." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:80 +msgid "" +"Language [_1] is invalid. Please choose a proper language from the form." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:55 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:57 +msgid "Please fill in the date." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:58 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:61 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:63 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:60 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:63 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:65 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:73 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:75 +msgid "" +"The literal work on this date already exists. You cannot create a " +"duplicated one." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:95 +msgid "This title is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:117 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:117 +msgid "Fill in the content here." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/LtZhPoem.pm:58 +msgid "Please select a work set." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/LtZhPoem.pm:61 +msgid "This work set does not exist anymore. Please select another one." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Page.pm:41 +msgid "This HTML class is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:62 +msgid "Please select in the type." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:65 +msgid "This type does not exist anymore. Please select another one." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:83 +msgid "Please fill in the year of publication." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:86 +msgid "This year of publication is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:89 +msgid "This year of publication is too short. (Min. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:93 +msgid "Please fill in a positive integer year of publication." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:100 +msgid "Year ([#,_1]) out of range. Please specify between [#,_2] and [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:121 +msgid "This month is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:125 +msgid "Please fill in the month as ~[month~], ~[month day~] or ~[season~]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:148 +msgid "Please fill in the author." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:313 +msgid "This publication is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:334 +msgid "This pages is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:338 +msgid "Please fill in the pages as ### or ###-###." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:358 +msgid "This DOI is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:369 +msgid "This paper already exists. You cannot create a duplicated one." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:387 +msgid "Please fill in the URL." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:390 +msgid "This URL is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:394 +msgid "Please fill in a valid URL." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:51 +msgid "Please fill in the full name." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:54 +msgid "This full name is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:73 +msgid "Please fill in the abbreviation." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:76 +msgid "This abbreviation is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Tag.pm:59 +msgid "This tag already exists. You cannot create a duplicated one." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:46 +msgid "Delete this log entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:51 +msgid "This table provides you a form to write a new log entry." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:54 +msgid "This table provides you a form to edit a current log entry." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:57 +msgid "This table provides you a form to delete a log entry." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:74 +msgid "Write a New Change Log Entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:77 +msgid "Edit a Current Change Log Entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:80 +msgid "Delete a Change Log Entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:89 +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:89 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:95 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:116 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:298 +msgid "Hide?" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:90 +msgid "Hide this log entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:90 +msgid "Show this log entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:91 +msgid "Hide this log entry currently." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:96 +msgid "Page No.:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:46 +msgid "Delete this diary entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:51 +msgid "This table provides you a form to write a new diary entry." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:54 +msgid "This table provides you a form to edit a current diary entry." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:57 +msgid "This table provides you a form to delete a diary entry." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:74 +msgid "Write a New Diary Entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:77 +msgid "Edit a Current Diary Entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:80 +msgid "Delete a Diary Entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:90 +msgid "Hide this diary entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:90 +msgid "Show this diary entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:91 +msgid "Hide this diary entry currently." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:74 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:54 +msgid "Specie:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:90 +msgid "Language tag:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:46 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:50 +msgid "Delete this literal work" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:51 +msgid "This table provides you a form to write a new English literal work." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:54 +msgid "This table provides you a form to edit a current English literal work." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:57 +msgid "This table provides you a form to delete a English literal work." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:74 +msgid "Write a New English Literal Work" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:77 +msgid "Edit a Current English Literal Work" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:80 +msgid "Delete a English Literal Work" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:87 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:93 +msgid "Preview this literal work." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:299 +msgid "Hide this literal work" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:299 +msgid "Show this literal work" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:97 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:300 +msgid "Hide this literal work currently." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:55 +msgid "This table provides you a form to write a new Chinese literal work." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:58 +msgid "This table provides you a form to edit a current Chinese literal work." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:61 +msgid "This table provides you a form to delete a Chinese literal work." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:80 +msgid "Write a New Chinese Literal Work" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:83 +msgid "Edit a Current Chinese Literal Work" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:86 +msgid "Delete a Chinese Literal Work" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:114 +msgid "Title:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:115 +msgid "Content:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:118 +msgid "Hide this poem currently." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:122 +msgid "Hide this poem" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:123 +msgid "Show this poem" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:135 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:187 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:261 +msgid "[numerate,_1,Poem]:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:188 +msgid "Original:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:189 +msgid "New:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:49 +msgid "Delete this poem" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:54 +msgid "This table provides you a form to write a new Chinese poem." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:57 +msgid "This table provides you a form to edit a current Chinese poem." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:60 +msgid "This table provides you a form to delete a Chinese poem." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:77 +msgid "Write a New Chinese Poem" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:80 +msgid "Edit a Current Chinese Poem" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:83 +msgid "Delete a Chinese Poem" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:93 +msgid "Work set:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Page.pm:61 +msgid "HTML class:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:50 +msgid "Delete this paper" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:55 +msgid "This table provides you a form to add a new paper." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:58 +msgid "This table provides you a form to edit a current paper." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:61 +msgid "This table provides you a form to delete a paper." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:80 +msgid "Add a New Paper" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:83 +msgid "Edit a Current Paper" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:86 +msgid "Delete a Paper" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:96 +msgid "Type:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:101 +msgid "Year of publication:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:106 +msgid "Month of publication:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:111 +msgid "Authors:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:117 +msgid "Tags:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:123 +msgid "Publication:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:128 +msgid "Pages:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:133 +msgid "DOI.:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:145 +msgid "APA citation:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:47 +msgid "Delete this researcher" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:52 +msgid "This table provides you a form to add a new researcher." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:55 +msgid "This table provides you a form to update a current researcher." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:58 +msgid "This table provides you a form to delete a researcher." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:75 +msgid "Add a New Researcher" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:78 +msgid "Update a Current Researcher" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:81 +msgid "Delete a Researcher" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:96 +msgid "Full name:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:101 +msgid "Abbreviation:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:112 +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:103 +msgid "[numerate,_1,Paper]:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:47 +msgid "Delete this tag" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:52 +msgid "This table provides you a form to add a new tag." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:55 +msgid "This table provides you a form to edit a current tag." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:58 +msgid "This table provides you a form to delete a tag." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:75 +msgid "Add a New Tag" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:78 +msgid "Edit a Current Tag" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:81 +msgid "Delete a Tag" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:38 +msgid "Select an Change Log Entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:39 +msgid "Manage Change Log" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:50 +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:50 +msgid "Page No." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:58 +msgid "Write a new log entry." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:64 +msgid "Search for a log entry:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:81 +msgid "Your query found [*,_1,log entry,log entries]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:84 +msgid "[*,_1,log entry,log entries]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:90 +msgid "" +"Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:94 +msgid "[*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:38 +msgid "Select a Diary Entry" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:39 +msgid "Manage Diary" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:58 +msgid "Write a new diary entry." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:64 +msgid "Search for a diary entry:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:81 +msgid "Your query found [*,_1,diary entry,diary entries]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:84 +msgid "[*,_1,diary entry,diary entries]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:90 +msgid "" +"Your query found [*,_1,diary entry,diary entries], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:94 +msgid "[*,_1,diary entry,diary entries], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:42 +msgid "Browse Mutual Fund Performances" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:52 +msgid "Name" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:53 +msgid "1m return" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:54 +msgid "1m ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:55 +msgid "3m return" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:56 +msgid "3m ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:57 +msgid "6m return" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:58 +msgid "6m ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:59 +msgid "1y return" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:60 +msgid "1y ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:61 +msgid "2y return" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:62 +msgid "2y ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:63 +msgid "3y return" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:64 +msgid "3y ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:65 +msgid "5y return" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:66 +msgid "5y ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:67 +msgid "10y return" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:68 +msgid "10y ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:69 +msgid "This year return" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:70 +msgid "This year ranking" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:71 +msgid "Total return" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:72 +msgid "Begin from" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:73 +msgid "Best 3m return" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:74 +msgid "Worst 3m return" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:75 +msgid "Standard deviation (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:76 +msgid "Standard deviation (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:77 +msgid "Beta (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:78 +msgid "Beta (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:79 +msgid "Sharpe (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:80 +msgid "Sharpe (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:81 +msgid "Jensen (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:82 +msgid "Jensen (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:83 +msgid "Treynor (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:84 +msgid "Treynor (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:85 +msgid "Information Ratio (major categories) (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:86 +msgid "Information Ratio (major categories) (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:87 +msgid "Information Ratio (minor categories) (12m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:88 +msgid "Information Ratio (minor categories) (24m)" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:89 +msgid "This month turnover" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:90 +msgid "12m turnover" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:91 +msgid "Duration" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:92 +msgid "Rating" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:93 +msgid "Manager less than 1y?" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:98 +msgid "4433 Principle" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:163 +msgid "Search for a fund:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:173 +msgid "Search" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:199 +msgid "Advanced filter:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:250 +msgid "Your query found [*,_1,fund]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:253 +msgid "[*,_1,fund]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:259 +msgid "Your query found [*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:263 +msgid "[*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage.pm:38 +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:38 +msgid "Select a Message" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage.pm:39 +msgid "Manage Soundless Backalley" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:39 +msgid "Manage Travellers' Guestbook" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:42 +msgid "Specie" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:43 +msgid "Language tag" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:38 +msgid "Select a English Literal Work" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:39 +msgid "Manage English Literal Works" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:51 +msgid "Write a new English literal work." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:57 +msgid "Search for a English literal work:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:74 +msgid "Your query found [*,_1,English literal work]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:77 +msgid "[*,_1,English literal work]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:83 +msgid "Your query found [*,_1,English literal work], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:87 +msgid "[*,_1,English literal work], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:38 +msgid "Select a Chinese Literal Work" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:39 +msgid "Manage Chinese Literal Works" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:51 +msgid "Write a new Chinese literal work." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:57 +msgid "Search for a Chinese literal work:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:74 +msgid "Your query found [*,_1,Chinese literal work]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:77 +msgid "[*,_1,Chinese literal work]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:83 +msgid "Your query found [*,_1,Chinese literal work], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:87 +msgid "[*,_1,Chinese literal work], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:38 +msgid "Select a Chinese Poem" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:39 +msgid "Manage Chinese Poems" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:44 +msgid "Work set" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:52 +msgid "Write a new Chinese poem." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:58 +msgid "Search for a Chinese poem:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:75 +msgid "Your query found [*,_1,Chinese poem]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:78 +msgid "[*,_1,Chinese poem]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:84 +msgid "Your query found [*,_1,Chinese poem], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:88 +msgid "[*,_1,Chinese poem], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Pages.pm:37 +msgid "HTML class" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:38 +msgid "Select a Paper" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:42 +msgid "Type" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:43 +msgid "Year" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:44 +msgid "Month" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:47 +msgid "Publication" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:49 +msgid "DOI" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:57 +msgid "Add a new paper." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:63 +msgid "Search for a paper:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:80 +msgid "Your query found [*,_1,paper]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:83 +msgid "[*,_1,paper]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:89 +msgid "Your query found [*,_1,paper], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:93 +msgid "[*,_1,paper], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:38 +msgid "Select a Researcher" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:39 +msgid "Manage Researchers" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:42 +msgid "Abbreviation" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:50 +msgid "Add a new researcher." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:56 +msgid "Search for a researcher:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:73 +msgid "Your query found [*,_1,researcher]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:76 +msgid "[*,_1,researcher]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:82 +msgid "Your query found [*,_1,researcher], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:86 +msgid "[*,_1,researcher], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:45 +msgid "Full Text Search" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:46 +msgid "" +"

    Tavern IMACAT's

    \n" +"

    Full Text Search

    " +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:48 +msgid "Search Result" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:49 +msgid "" +"

    Tavern IMACAT's

    \n" +"

    Search Result

    " +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:72 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:100 +msgid "Please fill in your query." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:160 +msgid "Search in the website:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:177 +msgid "Your query found [*,_1,article]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:180 +msgid "[*,_1,article]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:186 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:190 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:224 +msgid "Tavern Diary on [_1]" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:233 +msgid "Change Log on [_1]" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:271 +msgid "English writings" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:281 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:290 +msgid "Guestbook Message on [_1]" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:38 +msgid "Select a Tag" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:39 +msgid "Manage Tags" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:49 +msgid "Add a new tag." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:55 +msgid "Search for a tag:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:72 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:74 +msgid "Your query found [*,_1,tag]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:75 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:77 +msgid "[*,_1,tag]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:81 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:83 +msgid "Your query found [*,_1,tag], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:85 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:87 +msgid "[*,_1,tag], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:110 +msgid "This log entry was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:114 +msgid "This log entry has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:118 +msgid "This log entry has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:122 +msgid "This log entry has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:109 +msgid "This diary entry was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:113 +msgid "This diary entry has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:117 +msgid "This diary entry has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:121 +msgid "This diary entry has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:104 +msgid "This English literal work was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:108 +msgid "This English literal work has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:112 +msgid "This English literal work has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:116 +msgid "This English literal work has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:188 +msgid "This Chinese literal work was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:192 +msgid "This Chinese literal work has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:196 +msgid "This Chinese literal work has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:200 +msgid "This Chinese literal work has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:102 +msgid "This Chinese poem was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:106 +msgid "This Chinese poem has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:110 +msgid "This Chinese poem has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:114 +msgid "This Chinese poem has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:293 +msgid "This paper was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:297 +msgid "This paper has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:301 +msgid "This paper has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:305 +msgid "This paper has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:90 +msgid "This researcher was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:94 +msgid "This researcher has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:98 +msgid "This researcher has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:102 +msgid "This researcher has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:88 +msgid "This tag was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:92 +msgid "This tag has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:96 +msgid "This tag has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:100 +msgid "This tag has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook/Public.pm:44 +msgid "Your specie is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook/Public.pm:63 +msgid "Your e-mail is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:73 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:73 +msgid "Please select a paper." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:94 +msgid "Please select a author." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:97 +msgid "This author does not exist anymore. Please select another one." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:118 +msgid "This paper author already exists. You cannot create a duplicated one." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:94 +msgid "Please select a tag." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:97 +msgid "This tag does not exist anymore. Please select another one." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:118 +msgid "This paper tag already exists. You cannot create a duplicated one." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Garbage/Public.pm:48 +msgid "I'm sick." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:42 +msgid "" +"General commercial advertisements are not welcomed and may be deleted at " +"once. HTML is not supported." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:49 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:49 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:47 +msgid "Delete this type" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:54 +msgid "This table provides you a form to add a new paper author." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:57 +msgid "This table provides you a form to change a current paper author." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:60 +msgid "This table provides you a form to delete a paper author." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:77 +msgid "Add a New Paper Author" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:80 +msgid "Change a Current Paper Author" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:83 +msgid "Delete a Paper Author" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:93 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:93 +msgid "Paper:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:98 +msgid "Author:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:54 +msgid "This table provides you a form to add a new paper tag." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:57 +msgid "This table provides you a form to change a current paper tag." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:60 +msgid "This table provides you a form to delete a paper tag." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:77 +msgid "Add a New Paper Tag" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:80 +msgid "Change a Current Paper Tag" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:83 +msgid "Delete a Paper Tag" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:98 +msgid "Tag:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:52 +msgid "This table provides you a form to add a new paper type." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:55 +msgid "This table provides you a form to edit a current paper type." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:58 +msgid "This table provides you a form to delete a paper type." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:75 +msgid "Add a New Paper Type" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:78 +msgid "Edit a Current Paper Type" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:81 +msgid "Delete a Paper Type" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog/Public.pm:136 +msgid "Date:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog/Public.pm:146 +msgid "The change log entry seperator" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Diary/Public.pm:146 +msgid "The diary entry seperator" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage/Public.pm:68 +msgid "The message entry seperator" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:38 +msgid "Select a Paper Author" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:39 +msgid "Manage Paper Authors" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:42 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:42 +msgid "Paper" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:43 +msgid "Author" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:51 +msgid "Add a new paper author." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:57 +msgid "Search for a paper author:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:74 +msgid "Your query found [*,_1,author]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:77 +msgid "[*,_1,author]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:83 +msgid "Your query found [*,_1,author], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:87 +msgid "[*,_1,author], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:38 +msgid "Select a Paper Tag" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:39 +msgid "Manage Paper Tags" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:43 +msgid "Tag" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:51 +msgid "Add a new paper tag." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:57 +msgid "Search for a paper tag:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:38 +msgid "Select a Paper Type" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:39 +msgid "Manage Paper Types" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:49 +msgid "Add a new paper type." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:55 +msgid "Search for a paper type:" +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:72 +msgid "Your query found [*,_1,type]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:75 +msgid "[*,_1,type]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:81 +msgid "Your query found [*,_1,type], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:85 +msgid "[*,_1,type], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:97 +msgid "This paper author was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:101 +msgid "This paper author has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:105 +msgid "This paper author has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:109 +msgid "This paper author has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:97 +msgid "This paper tag was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:101 +msgid "This paper tag has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:105 +msgid "This paper tag has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:109 +msgid "This paper tag has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:94 +msgid "This paper type was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:98 +msgid "This paper type has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:102 +msgid "This paper type has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:106 +msgid "This paper type has been successfully deleted." +msgstr "" diff --git a/htdocs/imacat/magicat/po/zh_CN.gmo b/htdocs/imacat/magicat/po/zh_CN.gmo new file mode 100644 index 0000000..8641ed7 Binary files /dev/null and b/htdocs/imacat/magicat/po/zh_CN.gmo differ diff --git a/htdocs/imacat/magicat/po/zh_CN.po b/htdocs/imacat/magicat/po/zh_CN.po new file mode 100644 index 0000000..b8288cd --- /dev/null +++ b/htdocs/imacat/magicat/po/zh_CN.po @@ -0,0 +1,2572 @@ +# Simplified Chinese PO file for the Tavern IMACAT's website +# Copyright (C) 2003-2018 imacat +# This file is distributed under the same license as the imacat package. +# imacat , 2003-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: imacat 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-03-24 07:09+0800\n" +"PO-Revision-Date: 2020-03-24 07:10+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: cgi-bin/1-guestbook.cgi:40 cgi-bin/1-guestbook.cgi:111 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:282 +msgid "Travellers' Guestbook" +msgstr "旅人留言簿" + +#: cgi-bin/1-guestbook.cgi:112 +msgid "" +"

    Tavern IMACAT’s

    \n" +"

    Travellers’
    Guestbook

    " +msgstr "" +"

    旅舍的

    \n" +"

    旅人留言簿

    " + +#: cgi-bin/1-guestbook.cgi:129 +msgid "Good morning to thee, gentle friend and traveller!" +msgstr "早安。温和的友人及旅行者。" + +#: cgi-bin/1-guestbook.cgi:130 +msgid "" +"I call thee \"traveller\" no matter if thou hast never left thy home town, " +"no matter if thou wilst never again leave thy room, because all of us are " +"travellers. I call thee traveller for truly all of us travel a spiritual or " +"philosophical path -- even if it is simply by living the life that we choose " +"to live, or by searching for a new life when our current one fails to " +"satisfy our needs as thinking spiritual beings." +msgstr "" +"即使妳不曾离开过妳的故乡,也不曾离开妳的房间,我都称呼妳为旅行者,因为我们全" +"都是旅行者。我们在精神或哲学的道路上──即使它只是简单地活在我们选择的生活方式" +"上,或当现在的生活并不能满足精神上的需要时,而寻找另一种新的生活方式。" + +#: cgi-bin/1-guestbook.cgi:133 +msgid "-- The Book of Fellowship, Ultima VII" +msgstr "──友谊会手册‧创世纪Ⅶ" + +#: cgi-bin/garbage.cgi:40 +msgid "garbage, daub, poetry, message, essay" +msgstr "心情垃圾, 涂鸦, 诗, 留言, 短文" + +#: cgi-bin/garbage.cgi:110 magicat/lib/perl5/Selima/imacat/List/Search.pm:291 +msgid "Soundless Backalley" +msgstr "无声的后巷" + +#: cgi-bin/garbage.cgi:111 +msgid "" +"

    The

    \n" +"

    Soundless
    Backalley

    " +msgstr "" +"

    旅舍的

    \n" +"

    无声的后巷

    " + +#: cgi-bin/garbage.cgi:128 +msgid "" +"This is the backalley of Tavern. Every morning barmaid Cotton will put " +"garbages here. Besides that, there's never anyone passing by. Just " +"stinking garbages, drunks unable to tell dead or alive, cats and dogs and " +"flies, piss and vomits. The wall is filled with drawings and words unable " +"to tell whether they are poetry or shits. The vague music and laughters " +"come so faraway from inside the Tavern, like a neverending rhythm repeats " +"itself. The sun is blocked by the buildings. Even the time stops." +msgstr "" +"旅舍的后巷,除了每天清晨,女侍‧絮把垃圾拿出来倒以外,没有人会经过的地方。堆满" +"了腐臭的垃圾、分不清是死是活的醉汉、猫狗、苍蝇、排泄物、呕吐物。墙上画满不知" +"道是诗还是脏话的句子和涂鸦。远处隐约传来旅舍吧抬的音乐和嘈杂声,像永恒的节奏" +"一样在远处反复吟唱着。阳光被旅舍挡住,连时间也不动了。" + +#: cgi-bin/garbage.cgi:129 +msgid "" +"There's no one here, just you and yourself. Soundless is the loudest " +"sound. No matter how hard if you cry, shout or scream, you're still alone. " +"This is the darkest and the loneliest corner in the Tavern." +msgstr "" +"这里没有别人,只有妳和妳自己。无声是最吵杂的声音。妳撕破喉咙哭泣,也没人听得" +"见。这是旅舍最阴暗的地方,也是旅舍最孤寂的角落。" + +#: cgi-bin/plurkavatar.cgi:41 cgi-bin/plurkfav.cgi:43 +msgid "Plurk" +msgstr "噗浪" + +#: cgi-bin/plurkavatar.cgi:65 +msgid "There is no Plurk user \"[_1]\"." +msgstr "查无噗浪用户 [_1] 。" + +#: cgi-bin/plurkavatar.cgi:68 +msgid "Avator is not found for user \"[_1]\"." +msgstr "查无噗浪用户 [_1] 的头像。" + +#: cgi-bin/plurkavatar.cgi:72 +msgid "Plurk service is not available now." +msgstr "噗浪目前无法使用。" + +#: cgi-bin/plurkavatar.cgi:75 +msgid "Please fill in the Plurk user." +msgstr "请填上噗浪用户。" + +#: cgi-bin/plurkavatar.cgi:89 +msgid "Plurk Avatars" +msgstr "噗浪头像" + +#: cgi-bin/plurkavatar.cgi:96 +msgid "Plurk Avatars for User [_1]" +msgstr "[_1] 的噗浪头像" + +#: cgi-bin/plurkavatar.cgi:121 +msgid "Plurk user:" +msgstr "噗浪用户:" + +#: cgi-bin/plurkfav.cgi:52 +msgid "Plurk Favorites" +msgstr "噗浪喜欢" + +#: cgi-bin/plurkfav.cgi:86 +msgid "Plurk permanent link URL:" +msgstr "噗浪链接:" + +#: cgi-bin/plurkfav.cgi:105 +msgid "Plurk ID: [_1]" +msgstr "噗浪编号: [_1]" + +#: cgi-bin/plurkfav.cgi:106 +msgid "Set Plurk favorite" +msgstr "设置噗浪喜欢" + +#: cgi-bin/plurkfav.cgi:107 +msgid "Unset Plurk favorite" +msgstr "取消噗浪喜欢" + +#: cgi-bin/search.cgi:43 +msgid "search, query, full text search" +msgstr "搜索, 检索, 全文检索" + +#: magicat/cgi-bin/acctrecs.cgi:44 magicat/cgi-bin/acctreps.cgi:39 +#: magicat/cgi-bin/acctsubj.cgi:42 magicat/cgi-bin/accttrx.cgi:43 +msgid "accounting" +msgstr "会计" + +#: magicat/cgi-bin/acctrecs.cgi:110 magicat/cgi-bin/acctrecs.cgi:157 +#: magicat/cgi-bin/acctsubj.cgi:120 magicat/cgi-bin/acctsubj.cgi:180 +#: magicat/cgi-bin/accttrx.cgi:110 magicat/cgi-bin/accttrx.cgi:157 +#: magicat/cgi-bin/changelog.cgi:110 magicat/cgi-bin/changelog.cgi:159 +#: magicat/cgi-bin/diary.cgi:110 magicat/cgi-bin/diary.cgi:159 +#: magicat/cgi-bin/garbage.cgi:104 magicat/cgi-bin/garbage.cgi:148 +#: magicat/cgi-bin/groupmem.cgi:108 magicat/cgi-bin/groupmem.cgi:153 +#: magicat/cgi-bin/groups.cgi:121 magicat/cgi-bin/groups.cgi:176 +#: magicat/cgi-bin/guestbook.cgi:104 magicat/cgi-bin/guestbook.cgi:150 +#: magicat/cgi-bin/linkcat.cgi:119 magicat/cgi-bin/linkcat.cgi:177 +#: magicat/cgi-bin/linkcatz.cgi:108 magicat/cgi-bin/linkcatz.cgi:153 +#: magicat/cgi-bin/links.cgi:110 magicat/cgi-bin/links.cgi:161 +#: magicat/cgi-bin/literalen.cgi:161 magicat/cgi-bin/literalen.cgi:205 +#: magicat/cgi-bin/literalzh.cgi:175 magicat/cgi-bin/literalzh.cgi:219 +#: magicat/cgi-bin/ltzhpoem.cgi:106 magicat/cgi-bin/ltzhpoem.cgi:151 +#: magicat/cgi-bin/pages.cgi:114 magicat/cgi-bin/pages.cgi:163 +#: magicat/cgi-bin/papers.cgi:108 magicat/cgi-bin/papers.cgi:154 +#: magicat/cgi-bin/pprauthr.cgi:105 magicat/cgi-bin/pprauthr.cgi:150 +#: magicat/cgi-bin/pprtags.cgi:105 magicat/cgi-bin/pprtags.cgi:150 +#: magicat/cgi-bin/pprtypes.cgi:112 magicat/cgi-bin/pprtypes.cgi:165 +#: magicat/cgi-bin/resrcher.cgi:109 magicat/cgi-bin/resrcher.cgi:157 +#: magicat/cgi-bin/scptpriv.cgi:106 magicat/cgi-bin/scptpriv.cgi:151 +#: magicat/cgi-bin/tags.cgi:109 magicat/cgi-bin/tags.cgi:157 +#: magicat/cgi-bin/usermem.cgi:108 magicat/cgi-bin/usermem.cgi:153 +#: magicat/cgi-bin/userpref.cgi:106 magicat/cgi-bin/userpref.cgi:151 +#: magicat/cgi-bin/users.cgi:125 magicat/cgi-bin/users.cgi:189 +msgid "Incorrect form: [_1]." +msgstr "查无此表格: [_1] 。" + +#: magicat/cgi-bin/acctrecs.cgi:204 +msgid "Please select the accounting record." +msgstr "请选择会计分录。" + +#: magicat/cgi-bin/acctrecs.cgi:212 +msgid "" +"This accounting record does not exist anymore. Please select another one." +msgstr "查无此会计分录,请重新选择。" + +#: magicat/cgi-bin/acctsubj.cgi:93 magicat/cgi-bin/acctsubj.cgi:140 +msgid "Please add a new accounting subject from [_1]." +msgstr "请由[_1]建新会计科目。" + +#: magicat/cgi-bin/acctsubj.cgi:109 magicat/cgi-bin/acctsubj.cgi:169 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the subject, " +"[numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] " +"must first be deleted." +msgstr "" +"本会计科目下有子会计科目,不可直接删除。要删除本会计科目,请先删除其下的子会" +"计科目。" + +#: magicat/cgi-bin/acctsubj.cgi:113 magicat/cgi-bin/acctsubj.cgi:173 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the subject, [numerate,_1,its " +"accounting record,all of its accounting records] must first be deleted." +msgstr "" +"本会计科目下有会计分录,不可直接删除。要删除本会计科目,请先删除其下的会计分" +"录。" + +#: magicat/cgi-bin/acctsubj.cgi:232 +msgid "Please select the accounting subject." +msgstr "请选择会计科目。" + +#: magicat/cgi-bin/acctsubj.cgi:240 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "查无此会计科目,请重新选择。" + +#: magicat/cgi-bin/accttrx.cgi:204 +msgid "Please select the accounting transaction." +msgstr "请选择会计传票。" + +#: magicat/cgi-bin/accttrx.cgi:212 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "查无此会计传票,请重新选择。" + +#: magicat/cgi-bin/actlog.cgi:36 +msgid "activity, logs" +msgstr "活动, 记录, 日志" + +#: magicat/cgi-bin/changelog.cgi:42 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:472 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:539 +msgid "change log, history" +msgstr "更新日志, 变迁史" + +#: magicat/cgi-bin/changelog.cgi:91 magicat/cgi-bin/changelog.cgi:128 +msgid "Please write a new log entry from [_1]." +msgstr "请由[_1]写新日志。" + +#: magicat/cgi-bin/changelog.cgi:206 +msgid "Please select the log entry." +msgstr "请选择日志。" + +#: magicat/cgi-bin/changelog.cgi:214 +msgid "This log entry does not exist anymore. Please select another one." +msgstr "查无该则日志,请重新选择。" + +#: magicat/cgi-bin/diary.cgi:42 magicat/lib/perl5/Selima/imacat/Rebuild.pm:327 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:394 +msgid "diary" +msgstr "日记" + +#: magicat/cgi-bin/diary.cgi:91 magicat/cgi-bin/diary.cgi:128 +msgid "Please write a new diary entry from [_1]." +msgstr "请由[_1]写新日记。" + +#: magicat/cgi-bin/diary.cgi:206 +msgid "Please select the diary entry." +msgstr "请选择日记。" + +#: magicat/cgi-bin/diary.cgi:214 +msgid "This diary entry does not exist anymore. Please select another one." +msgstr "查无该则日记,请重新选择。" + +#: magicat/cgi-bin/funds.cgi:36 +msgid "mutual funds, performance, indicators" +msgstr "共同基金, 绩效, 指针" + +#: magicat/cgi-bin/garbage.cgi:40 +msgid "backalley" +msgstr "后巷" + +#: magicat/cgi-bin/garbage.cgi:195 magicat/cgi-bin/guestbook.cgi:197 +msgid "Please select the message." +msgstr "请选择要设置的留言。" + +#: magicat/cgi-bin/garbage.cgi:203 magicat/cgi-bin/guestbook.cgi:205 +msgid "This message does not exist anymore. Please select another one." +msgstr "查无该留言,请改选其她留言。" + +#: magicat/cgi-bin/groupmem.cgi:44 +msgid "group membership" +msgstr "群组成员" + +#: magicat/cgi-bin/groupmem.cgi:200 magicat/cgi-bin/usermem.cgi:200 +msgid "Please select the membership record." +msgstr "请选择成员关系。" + +#: magicat/cgi-bin/groupmem.cgi:208 magicat/cgi-bin/usermem.cgi:208 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "查无此成员关系,请重新选择。" + +#: magicat/cgi-bin/groups.cgi:48 +msgid "groups" +msgstr "群组" + +#: magicat/cgi-bin/groups.cgi:98 magicat/cgi-bin/groups.cgi:140 +msgid "Please create a new group from [_1]." +msgstr "请由[_1]建新群组。" + +#: magicat/cgi-bin/groups.cgi:224 +msgid "Please select the group." +msgstr "请选择群组。" + +#: magicat/cgi-bin/groups.cgi:232 +msgid "This group does not exist anymore. Please select another one." +msgstr "查无此群组,请重新选择。" + +#: magicat/cgi-bin/guestbook.cgi:40 +msgid "guestbook" +msgstr "留言簿" + +#: magicat/cgi-bin/linkcat.cgi:43 +msgid "link categories" +msgstr "相关链接分类" + +#: magicat/cgi-bin/linkcat.cgi:92 magicat/cgi-bin/linkcat.cgi:137 +msgid "Please add a new category from [_1]." +msgstr "请由[_1]建新分类。" + +#: magicat/cgi-bin/linkcat.cgi:108 magicat/cgi-bin/linkcat.cgi:166 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分类下有子类,不可直接删除。要删除本分类,请先删除其下的子类。" + +#: magicat/cgi-bin/linkcat.cgi:112 magicat/cgi-bin/linkcat.cgi:170 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分类下有链接,不可直接删除。要删除本分类,请先删除其下的链接。" + +#: magicat/cgi-bin/linkcat.cgi:225 +msgid "Please select the category." +msgstr "请选择分类。" + +#: magicat/cgi-bin/linkcat.cgi:233 +msgid "This category does not exist anymore. Please select another one." +msgstr "查无此分类,请重新选择。" + +#: magicat/cgi-bin/linkcatz.cgi:44 +msgid "link categorization" +msgstr "链接分类表" + +#: magicat/cgi-bin/linkcatz.cgi:200 +msgid "Please select the categorization record." +msgstr "请选择分类数据。" + +#: magicat/cgi-bin/linkcatz.cgi:208 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "查无此分类数据,请重新选择。" + +#: magicat/cgi-bin/links.cgi:42 magicat/lib/perl5/Selima/imacat/Rebuild.pm:254 +msgid "related links" +msgstr "相关链接" + +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:128 +msgid "Please add a new related link from [_1]." +msgstr "请由[_1]建新相关链接。" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Manage Keep Travelling" +msgstr "管理继续旅行" + +#: magicat/cgi-bin/links.cgi:211 +msgid "Please select the related link." +msgstr "请选择要设置的相关链接。" + +#: magicat/cgi-bin/links.cgi:219 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查无该相关链接,请改选其她相关链接。" + +#: magicat/cgi-bin/literalen.cgi:43 +msgid "English literal works" +msgstr "英文写作" + +#: magicat/cgi-bin/literalen.cgi:259 +msgid "Please select the English literal work." +msgstr "请选择要编辑的英文写作。" + +#: magicat/cgi-bin/literalen.cgi:267 +msgid "" +"This English literal work does not exist anymore. Please select another one." +msgstr "查无此英文写作,请重新选择。" + +#: magicat/cgi-bin/literalzh.cgi:44 +msgid "Chinese literal works" +msgstr "中文写作" + +#: magicat/cgi-bin/literalzh.cgi:273 +msgid "Please select the Chinese literal work." +msgstr "请选择要编辑的中文写作。" + +#: magicat/cgi-bin/literalzh.cgi:281 +msgid "" +"This Chinese literal work does not exist anymore. Please select another one." +msgstr "查无此中文写作,请重新选择。" + +#: magicat/cgi-bin/logout.cgi:39 +msgid "log out" +msgstr "注销" + +#: magicat/cgi-bin/logout.cgi:112 magicat/cgi-bin/logout.cgi:119 +msgid "Log Out" +msgstr "注销" + +#: magicat/cgi-bin/logout.cgi:135 +msgid "Are you sure you want to log out?" +msgstr "妳确定要注销吗?" + +#: magicat/cgi-bin/logout.cgi:136 magicat/lib/perl5/Selima/imacat/HTML.pm:577 +msgid "Log out" +msgstr "注销" + +#: magicat/cgi-bin/logout.cgi:152 +msgid "Log in again." +msgstr "重新登录。" + +#: magicat/cgi-bin/ltzhpoem.cgi:42 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:253 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:262 +msgid "Chinese poems" +msgstr "中文诗" + +#: magicat/cgi-bin/ltzhpoem.cgi:199 +msgid "Please select the Chinese poem." +msgstr "请选择中文诗。" + +#: magicat/cgi-bin/ltzhpoem.cgi:207 +msgid "This Chinese poem does not exist anymore. Please select another one." +msgstr "查无此中文诗,请重新选择。" + +#: magicat/cgi-bin/pages.cgi:40 +msgid "pages" +msgstr "网页" + +#: magicat/cgi-bin/pages.cgi:89 magicat/cgi-bin/pages.cgi:132 +msgid "Please add a new page from [_1]." +msgstr "请由[_1]写新网页。" + +#: magicat/cgi-bin/pages.cgi:216 +msgid "Please select the page." +msgstr "请选择网页。" + +#: magicat/cgi-bin/pages.cgi:224 +msgid "This page does not exist anymore. Please select another one." +msgstr "查无此页,请改选其她网页。" + +#: magicat/cgi-bin/papers.cgi:44 magicat/cgi-bin/pprauthr.cgi:41 +#: magicat/cgi-bin/pprtags.cgi:41 magicat/cgi-bin/pprtypes.cgi:40 +msgid "papers" +msgstr "论文" + +#: magicat/cgi-bin/papers.cgi:201 +msgid "Please select the paper." +msgstr "请选择论文。" + +#: magicat/cgi-bin/papers.cgi:209 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:76 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:76 +msgid "This paper does not exist anymore. Please select another one." +msgstr "查无此论文,请改选其她论文。" + +#: magicat/cgi-bin/pprauthr.cgi:197 +msgid "Please select the paper author." +msgstr "请选择论文作者。" + +#: magicat/cgi-bin/pprauthr.cgi:205 +msgid "This paper author does not exist anymore. Please select another one." +msgstr "查无此论文作者,请改选其她论文作者。" + +#: magicat/cgi-bin/pprtags.cgi:197 +msgid "Please select the paper tag." +msgstr "请选择论文标签。" + +#: magicat/cgi-bin/pprtags.cgi:205 +msgid "This paper tag does not exist anymore. Please select another one." +msgstr "查无此论文标签,请改选其她论文标签。" + +#: magicat/cgi-bin/pprtypes.cgi:89 magicat/cgi-bin/pprtypes.cgi:130 +msgid "Please add a new paper type from [_1]." +msgstr "请由[_1]建新论文类型。" + +#: magicat/cgi-bin/pprtypes.cgi:105 magicat/cgi-bin/pprtypes.cgi:158 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:89 +msgid "" +"This paper type has [numerate,_1,a paper,papers]. It cannot be deleted. To " +"delete the type, [numerate,_1,its paper,all of its papers] must first be " +"deleted." +msgstr "本论文类型下有论文,不可直接删除。要删除本类型,请先删除其下的论文。" + +#: magicat/cgi-bin/pprtypes.cgi:212 +msgid "Please select the paper type." +msgstr "请选择论文类型。" + +#: magicat/cgi-bin/pprtypes.cgi:220 +msgid "This paper type does not exist anymore. Please select another one." +msgstr "查无此论文类型,请改选其她类型。" + +#: magicat/cgi-bin/rebuild.cgi:37 +msgid "rebuild pages" +msgstr "重制网页" + +#: magicat/cgi-bin/resrcher.cgi:41 +msgid "researchers" +msgstr "研究者" + +#: magicat/cgi-bin/resrcher.cgi:102 magicat/cgi-bin/resrcher.cgi:150 +#: magicat/cgi-bin/tags.cgi:102 magicat/cgi-bin/tags.cgi:150 +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:88 +msgid "" +"This researcher has [numerate,_1,a paper,papers]. It cannot be deleted. To " +"delete the researcher, [numerate,_1,its paper,all of its papers] must first " +"be deleted." +msgstr "本研究者下有论文,不可直接删除。要删除本研究者,请先删除其下的论文。" + +#: magicat/cgi-bin/resrcher.cgi:204 magicat/cgi-bin/tags.cgi:204 +msgid "Please select the researcher." +msgstr "请选择研究者。" + +#: magicat/cgi-bin/resrcher.cgi:212 magicat/cgi-bin/tags.cgi:212 +msgid "This researcher does not exist anymore. Please select another one." +msgstr "查无此研究者,请重新选择。" + +#: magicat/cgi-bin/saveform.cgi:46 +msgid "saved forms" +msgstr "暂存表单" + +#: magicat/cgi-bin/saveform.cgi:77 +msgid "Form [_1] does not exist anymore. Please select another one." +msgstr "查无表单 [_1] ,请改选其她表单。" + +#: magicat/cgi-bin/saveform.cgi:92 +msgid "Manage the Saved Forms" +msgstr "管理暂存表单" + +#: magicat/cgi-bin/saveform.cgi:134 +msgid "Select" +msgstr "选" + +#: magicat/cgi-bin/scptpriv.cgi:42 +msgid "script privilege" +msgstr "程序权限" + +#: magicat/cgi-bin/scptpriv.cgi:198 +msgid "Please select the script privilege record." +msgstr "请选择程序权限。" + +#: magicat/cgi-bin/scptpriv.cgi:206 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "查无该程序权限,请重新选择。" + +#: magicat/cgi-bin/tags.cgi:41 +msgid "tags" +msgstr "标签" + +#: magicat/cgi-bin/usermem.cgi:44 +msgid "user membership" +msgstr "用户成员" + +#: magicat/cgi-bin/userpref.cgi:42 +msgid "user preference" +msgstr "用户偏好" + +#: magicat/cgi-bin/userpref.cgi:198 +msgid "Please select the user preference." +msgstr "请选择用户偏好。" + +#: magicat/cgi-bin/userpref.cgi:206 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "查无该用户偏好,请重新选择。" + +#: magicat/cgi-bin/users.cgi:43 +msgid "users" +msgstr "帐号" + +#: magicat/cgi-bin/users.cgi:237 +msgid "Please select the user." +msgstr "请选择用户。" + +#: magicat/cgi-bin/users.cgi:245 +msgid "This user does not exist anymore. Please select another one." +msgstr "查无此人,请重新选择。" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:52 +msgid "imacat" +msgstr "依玛猫" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:53 +msgid "© imacat. All rights reserved." +msgstr "© 依玛猫。依玛猫保有所有权利。" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:63 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1016 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:409 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:410 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:225 +msgid "Tavern Diary" +msgstr "旅舍日记" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:64 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:98 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:234 +msgid "Change Log" +msgstr "更新日志" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:65 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:108 +msgid "Chinese Literal Works" +msgstr "中文写作" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:66 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:112 +msgid "English Literal Works" +msgstr "英文写作" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:90 +msgid "Manage Content" +msgstr "管理网站" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:92 +msgid "Guestbook" +msgstr "留言簿" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:94 +msgid "Backalley" +msgstr "后巷" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:96 +msgid "Diary" +msgstr "日记" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:100 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:48 +msgid "Pages" +msgstr "网页" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:102 +msgid "Links" +msgstr "链接" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:104 +msgid "Link Categories" +msgstr "链接分类" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:106 +msgid "Link Categorization" +msgstr "链接分类表" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:110 +msgid "Chinese Poems" +msgstr "中文诗" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:116 +msgid "Manage Accounts" +msgstr "管理帐号" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:118 +msgid "Users" +msgstr "帐号" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:120 +msgid "Groups" +msgstr "群组" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:122 +msgid "User Membership" +msgstr "用户成员" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:124 +msgid "Group Membership" +msgstr "群组成员" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:126 +msgid "User Preferences" +msgstr "用户偏好" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:128 +msgid "Script Privileges" +msgstr "程序权限" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:148 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:39 +msgid "Manage Papers" +msgstr "管理论文" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:150 +msgid "Papers" +msgstr "论文" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:152 +msgid "Researchers" +msgstr "研究者" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:154 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:46 +msgid "Tags" +msgstr "标签" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:156 +msgid "Types" +msgstr "类型" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:158 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:45 +msgid "Authors" +msgstr "作者" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:160 +msgid "Paper Tags" +msgstr "论文标签" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:164 +msgid "Miscellaneous" +msgstr "杂项" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:166 +msgid "Accounting" +msgstr "会计" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:168 +msgid "Funds" +msgstr "基金" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:170 +msgid "Activity Log" +msgstr "活动日志" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:172 +msgid "Rebuild Pages" +msgstr "重制网页" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:174 +msgid "Analog" +msgstr "访客统计" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:176 +msgid "Test Script" +msgstr "测试程序" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:178 +msgid "MRTG" +msgstr "流量统计" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:180 +msgid "Saved Forms" +msgstr "暂存表单" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:182 +msgid "CGI Environment" +msgstr "CGI 环境" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:186 +msgid "Server Status" +msgstr "服务器状态" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:189 +msgid "Server Information" +msgstr "服务器信息" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:192 +msgid "Bwshare Information" +msgstr "节频信息" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:195 +msgid "Bwshare Trace" +msgstr "节频记录" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:198 +msgid "Perl Status" +msgstr "Perl 状态" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:253 +msgid "Skip to the page content area." +msgstr "跳到网页内文区。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:254 +msgid "Page Content Area" +msgstr "网页内文区" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:372 +msgid "Magicat" +msgstr "梅姬" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:441 +msgid "Navigation Links Area" +msgstr "导览链接区" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:521 +msgid "Language Switching Area" +msgstr "语言切换区" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:575 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "%s,妳好!(修改数据)" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:617 +#, c-format +msgid "%s:" +msgstr "%s:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:689 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:243 +msgid "Keep Travelling" +msgstr "继续旅行" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:757 +msgid "E-mail" +msgstr "电子邮件信箱" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:782 +msgid "URL:" +msgstr "网址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:785 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:920 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:69 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:49 +msgid "E-mail:" +msgstr "电子邮件信箱:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:791 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:921 +msgid "Address:" +msgstr "地址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:793 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:922 +msgid "Tel.:" +msgstr "电话:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:795 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:923 +msgid "Fax.:" +msgstr "传真:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:824 +msgid "" +"Are you ready to check out? Just drop your room key at the counter, and " +"travel for your next stop. Life is a never-ending trip, and Tavern is only " +"one of your many stops. Are you ready to go now?" +msgstr "" +"妳要退房了吗?把妳的房门钥匙交还给柜台,该向下一个停靠站出发了。这是一趟永无" +"止境的旅程,旅舍,只是妳的一个中途停靠站。若妳准备好了,就出发啰!" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:825 +msgid "" +"Greetings, traveller. I'm rinse the Tavern Tour Agent. Where is your next " +"stop?" +msgstr "妳好,旅行者。我是琳思。妳要往哪里去旅行呢?" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:837 +msgid "The database is empty." +msgstr "现无任何数据。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:906 +msgid "~[Tavern~] Website Registration" +msgstr "~[旅舍回函~] 网站登录" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:907 +msgid "" +"This table provide a form to register your site at Tavern \"Keep Travelling" +"\", the data column names and their input fields to fill in the information." +msgstr "" +"本表提供登录旅舍「继续旅行」的表单,网站数据字段名称,和填写该数据的输入格。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:908 +msgid "Fill in the description here." +msgstr "请填上简介。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:909 +msgid "Regiser your site" +msgstr "登录网站" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:910 +msgid "" +"I sincerely wish to build more hyperlinks with websites that're kind to " +"women/lesbian/queer. If you wish to link with me, or if you have any such " +"information, whether in Chinese or not, please tell me by filling this form " +"below. I'll put it in as soon as possible. Thank you." +msgstr "" +"我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳" +"有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:911 +msgid "" +"All fields in the form below, Except for the site name, the URL and the " +"description, are optional. Anything you fill here will be shown to " +"ANYONE who visits Tavern IMACAT's. Tavern does not collect " +"any personal informations. If you do not wish to distribute some private " +"informations, just leave them blank. If you represent some organization, " +"fill as detail as possible to help others finding you." +msgstr "" +"下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛" +"中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据" +"曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:912 +msgid "General commercial sites besides lesbian shops are not welcome." +msgstr "除女同志商店外,旅舍恕不受理一般商业网站。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:914 +msgid "Site name:" +msgstr "站名:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:915 +msgid "Site name, 2nd language (if any):" +msgstr "站名(第二语言,可略):" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:916 +msgid "Site URL:" +msgstr "网址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:917 +msgid "Link logo URL:" +msgstr "链接小图网址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:918 +msgid "Category:" +msgstr "分类:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:919 +msgid "Introduction:" +msgstr "简介:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:924 +msgid "OK!" +msgstr "好了!" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1010 +msgid "The diary is empty." +msgstr "现无任何日记。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1015 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1075 +msgid "imacat's Private Bed♥room" +msgstr "依玛猫的闺♥房" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1025 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1085 +msgid "Index" +msgstr "目录" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1042 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:326 +#, c-format +msgid "Tavern Diary Volume %s" +msgstr "旅舍日记 卷%s" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1070 +msgid "The change log is empty." +msgstr "现无任何日志。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1076 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:554 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:555 +msgid "Tavern Change Log" +msgstr "旅舍更新日志" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1102 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:471 +#, c-format +msgid "Tavern Change Log Volume %s" +msgstr "旅舍更新日志 卷%s" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1482 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "mod_perl -- 速度,动力,无限可能" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1483 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" +"本程序以 Perl 撰写,专为 mod_perl 设计强化" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1496 +msgid "" +"This script is written in Perl." +msgstr "" +"本程序以 Perl 撰写" + +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:264 +msgid "Keep Travelling..." +msgstr "继续旅行……" + +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:265 +msgid "Continue Your Journey..." +msgstr "继续妳的旅程……" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:41 +msgid "This specie is too long. (Max. length [#,_1])" +msgstr "物种太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:60 +msgid "This e-mail is too long. (Max. length [#,_1])" +msgstr "电子邮件信箱太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:75 +msgid "Please choose the language." +msgstr "请选择语言。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:80 +msgid "" +"Language [_1] is invalid. Please choose a proper language from the form." +msgstr "[_1] 语无效。请由表上选择适当的语言。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:55 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:57 +msgid "Please fill in the date." +msgstr "请填上日期。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:58 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:61 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:63 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:60 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:63 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:65 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期请以 YYYY-MM-DD 格式填写。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:73 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:75 +msgid "" +"The literal work on this date already exists. You cannot create a " +"duplicated one." +msgstr "已有这一天的写作,请勿重复建档。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:95 +msgid "This title is too long. (Max. length [#,_1])" +msgstr "标题太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:117 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:117 +msgid "Fill in the content here." +msgstr "请填上内文。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LtZhPoem.pm:58 +msgid "Please select a work set." +msgstr "请选择写作集。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LtZhPoem.pm:61 +msgid "This work set does not exist anymore. Please select another one." +msgstr "查无此写作集,请重新选择。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Page.pm:41 +msgid "This HTML class is too long. (Max. length [#,_1])" +msgstr "HTML 类别太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:62 +msgid "Please select in the type." +msgstr "请选择类型。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:65 +msgid "This type does not exist anymore. Please select another one." +msgstr "查无此类型,请改选其她类型。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:83 +msgid "Please fill in the year of publication." +msgstr "请填上出版年。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:86 +msgid "This year of publication is too long. (Max. length [#,_1])" +msgstr "出版年太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:89 +msgid "This year of publication is too short. (Min. length [#,_1])" +msgstr "出版年太短了。(最短 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:93 +msgid "Please fill in a positive integer year of publication." +msgstr "出版年请填正整数。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:100 +msgid "Year ([#,_1]) out of range. Please specify between [#,_2] and [#,_3]." +msgstr "年([#,_1])超出范围,请设在 [#,_2] 到 [#,_3] 之间。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:121 +msgid "This month is too long. (Max. length [#,_1])" +msgstr "月份标题太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:125 +msgid "Please fill in the month as ~[month~], ~[month day~] or ~[season~]." +msgstr "月份请以 ~[月份~] 、 ~[月份 日期~] 或 ~[季节~] 格式填写。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:148 +msgid "Please fill in the author." +msgstr "请填上作者。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:313 +msgid "This publication is too long. (Max. length [#,_1])" +msgstr "刊物太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:334 +msgid "This pages is too long. (Max. length [#,_1])" +msgstr "页数太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:338 +msgid "Please fill in the pages as ### or ###-###." +msgstr "页数请填 ### 或 ###-### 格式。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:358 +msgid "This DOI is too long. (Max. length [#,_1])" +msgstr "数字对象识别号太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:369 +msgid "This paper already exists. You cannot create a duplicated one." +msgstr "已有同一篇论文,请勿重复建档。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:387 +msgid "Please fill in the URL." +msgstr "请填上网址。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:390 +msgid "This URL is too long. (Max. length [#,_1])" +msgstr "网址太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:394 +msgid "Please fill in a valid URL." +msgstr "请填上正确的网址。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:51 +msgid "Please fill in the full name." +msgstr "请填上名字。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:54 +msgid "This full name is too long. (Max. length [#,_1])" +msgstr "名字太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:73 +msgid "Please fill in the abbreviation." +msgstr "请填上缩写。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:76 +msgid "This abbreviation is too long. (Max. length [#,_1])" +msgstr "缩写太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Tag.pm:59 +msgid "This tag already exists. You cannot create a duplicated one." +msgstr "已有同一个论文标签,请勿重复建档。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:46 +msgid "Delete this log entry" +msgstr "删掉这则日志" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:51 +msgid "This table provides you a form to write a new log entry." +msgstr "本表提供写新日志的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:54 +msgid "This table provides you a form to edit a current log entry." +msgstr "本表提供编辑日志的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:57 +msgid "This table provides you a form to delete a log entry." +msgstr "本表提供删除日志的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:74 +msgid "Write a New Change Log Entry" +msgstr "写新更新日志" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:77 +msgid "Edit a Current Change Log Entry" +msgstr "编辑更新日志" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:80 +msgid "Delete a Change Log Entry" +msgstr "删除更新日志" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:89 +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:89 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:95 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:116 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:298 +msgid "Hide?" +msgstr "隐藏?" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:90 +msgid "Hide this log entry" +msgstr "隐藏这则日志" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:90 +msgid "Show this log entry" +msgstr "秀出这则日志" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:91 +msgid "Hide this log entry currently." +msgstr "暂勿秀出这则日志。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:96 +msgid "Page No.:" +msgstr "页数:" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:46 +msgid "Delete this diary entry" +msgstr "删掉这则日记" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:51 +msgid "This table provides you a form to write a new diary entry." +msgstr "本表提供写新日记的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:54 +msgid "This table provides you a form to edit a current diary entry." +msgstr "本表提供编辑日记的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:57 +msgid "This table provides you a form to delete a diary entry." +msgstr "本表提供删除日记的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:74 +msgid "Write a New Diary Entry" +msgstr "写新日记" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:77 +msgid "Edit a Current Diary Entry" +msgstr "编辑日记" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:80 +msgid "Delete a Diary Entry" +msgstr "删除日记" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:90 +msgid "Hide this diary entry" +msgstr "隐藏这则日记" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:90 +msgid "Show this diary entry" +msgstr "秀出这则日记" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:91 +msgid "Hide this diary entry currently." +msgstr "暂勿秀出这则日记。" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:74 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:54 +msgid "Specie:" +msgstr "物种:" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:90 +msgid "Language tag:" +msgstr "语言标签:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:46 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:50 +msgid "Delete this literal work" +msgstr "删掉这篇写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:51 +msgid "This table provides you a form to write a new English literal work." +msgstr "本表提供写新英文写作的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:54 +msgid "This table provides you a form to edit a current English literal work." +msgstr "本表提供编辑英文写作的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:57 +msgid "This table provides you a form to delete a English literal work." +msgstr "本表提供删除英文写作的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:74 +msgid "Write a New English Literal Work" +msgstr "写新英文写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:77 +msgid "Edit a Current English Literal Work" +msgstr "编辑英文写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:80 +msgid "Delete a English Literal Work" +msgstr "删除英文写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:87 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:93 +msgid "Preview this literal work." +msgstr "预览这篇写作。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:299 +msgid "Hide this literal work" +msgstr "隐藏这篇写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:299 +msgid "Show this literal work" +msgstr "秀出这篇写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:97 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:300 +msgid "Hide this literal work currently." +msgstr "暂勿秀出这篇写作。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:55 +msgid "This table provides you a form to write a new Chinese literal work." +msgstr "本表提供写新中文写作的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:58 +msgid "This table provides you a form to edit a current Chinese literal work." +msgstr "本表提供编辑中文写作的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:61 +msgid "This table provides you a form to delete a Chinese literal work." +msgstr "本表提供删除中文写作的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:80 +msgid "Write a New Chinese Literal Work" +msgstr "写新中文写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:83 +msgid "Edit a Current Chinese Literal Work" +msgstr "编辑中文写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:86 +msgid "Delete a Chinese Literal Work" +msgstr "删除中文写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:114 +msgid "Title:" +msgstr "标题:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:115 +msgid "Content:" +msgstr "内文:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:118 +msgid "Hide this poem currently." +msgstr "暂勿秀出这首诗。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:122 +msgid "Hide this poem" +msgstr "隐藏这首诗" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:123 +msgid "Show this poem" +msgstr "秀出这首诗" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:135 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:187 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:261 +msgid "[numerate,_1,Poem]:" +msgstr "诗:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:188 +msgid "Original:" +msgstr "原:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:189 +msgid "New:" +msgstr "新:" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:49 +msgid "Delete this poem" +msgstr "删掉这首中文诗" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:54 +msgid "This table provides you a form to write a new Chinese poem." +msgstr "本表提供写新中文诗的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:57 +msgid "This table provides you a form to edit a current Chinese poem." +msgstr "本表提供编辑中文诗的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:60 +msgid "This table provides you a form to delete a Chinese poem." +msgstr "本表提供删除日中文诗的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:77 +msgid "Write a New Chinese Poem" +msgstr "写新中文诗" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:80 +msgid "Edit a Current Chinese Poem" +msgstr "编辑中文诗" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:83 +msgid "Delete a Chinese Poem" +msgstr "删除中文诗" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:93 +msgid "Work set:" +msgstr "写作集:" + +#: magicat/lib/perl5/Selima/imacat/Form/Page.pm:61 +msgid "HTML class:" +msgstr "HTML 类别:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:50 +msgid "Delete this paper" +msgstr "删掉这篇论文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:55 +msgid "This table provides you a form to add a new paper." +msgstr "本表提供建新论文的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:58 +msgid "This table provides you a form to edit a current paper." +msgstr "本表提供编辑论文的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:61 +msgid "This table provides you a form to delete a paper." +msgstr "本表提供删除论文的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:80 +msgid "Add a New Paper" +msgstr "建新论文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:83 +msgid "Edit a Current Paper" +msgstr "编辑论文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:86 +msgid "Delete a Paper" +msgstr "删除论文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:96 +msgid "Type:" +msgstr "类型:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:101 +msgid "Year of publication:" +msgstr "出版年:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:106 +msgid "Month of publication:" +msgstr "出版月:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:111 +msgid "Authors:" +msgstr "作者:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:117 +msgid "Tags:" +msgstr "标签:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:123 +msgid "Publication:" +msgstr "刊物:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:128 +msgid "Pages:" +msgstr "页数:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:133 +msgid "DOI.:" +msgstr "数字对象识别号:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:145 +msgid "APA citation:" +msgstr "APA 书目:" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:47 +msgid "Delete this researcher" +msgstr "删掉这个研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:52 +msgid "This table provides you a form to add a new researcher." +msgstr "本表提供建新研究者的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:55 +msgid "This table provides you a form to update a current researcher." +msgstr "本表提供设置研究者的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:58 +msgid "This table provides you a form to delete a researcher." +msgstr "本表提供删除研究者的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:75 +msgid "Add a New Researcher" +msgstr "建新研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:78 +msgid "Update a Current Researcher" +msgstr "编辑研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:81 +msgid "Delete a Researcher" +msgstr "删除研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:96 +msgid "Full name:" +msgstr "名字:" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:101 +msgid "Abbreviation:" +msgstr "缩写:" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:112 +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:103 +msgid "[numerate,_1,Paper]:" +msgstr "论文:" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:47 +msgid "Delete this tag" +msgstr "删掉这个标签" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:52 +msgid "This table provides you a form to add a new tag." +msgstr "本表提供加新标签的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:55 +msgid "This table provides you a form to edit a current tag." +msgstr "本表提供编辑标签的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:58 +msgid "This table provides you a form to delete a tag." +msgstr "本表提供删除标签的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:75 +msgid "Add a New Tag" +msgstr "加新标签" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:78 +msgid "Edit a Current Tag" +msgstr "编辑标签" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:81 +msgid "Delete a Tag" +msgstr "删除标签" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:38 +msgid "Select an Change Log Entry" +msgstr "选择更新日志" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:39 +msgid "Manage Change Log" +msgstr "管理更新日志" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:50 +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:50 +msgid "Page No." +msgstr "页数" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:58 +msgid "Write a new log entry." +msgstr "写新日志。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:64 +msgid "Search for a log entry:" +msgstr "搜索日志:" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:81 +msgid "Your query found [*,_1,log entry,log entries]." +msgstr "共 [#,_1] 则相符的日志。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:84 +msgid "[*,_1,log entry,log entries]." +msgstr "共 [#,_1] 则日志。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:90 +msgid "" +"Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 则相符的日志,列出第 [#,_2] 则到第 [#,_3] 则。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:94 +msgid "[*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 则日志,列出第 [#,_2] 则到第 [#,_3] 则。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:38 +msgid "Select a Diary Entry" +msgstr "选择日记" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:39 +msgid "Manage Diary" +msgstr "管理日记" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:58 +msgid "Write a new diary entry." +msgstr "写新日记。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:64 +msgid "Search for a diary entry:" +msgstr "搜索日记:" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:81 +msgid "Your query found [*,_1,diary entry,diary entries]." +msgstr "共 [#,_1] 则相符的日记。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:84 +msgid "[*,_1,diary entry,diary entries]." +msgstr "共 [#,_1] 则日记。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:90 +msgid "" +"Your query found [*,_1,diary entry,diary entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 则相符的日记,列出第 [#,_2] 则到第 [#,_3] 则。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:94 +msgid "[*,_1,diary entry,diary entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 则日记,列出第 [#,_2] 则到第 [#,_3] 则。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:42 +msgid "Browse Mutual Fund Performances" +msgstr "浏览共同基金绩效" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:52 +msgid "Name" +msgstr "名称" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:53 +msgid "1m return" +msgstr "一个月报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:54 +msgid "1m ranking" +msgstr "一个月排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:55 +msgid "3m return" +msgstr "三个月报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:56 +msgid "3m ranking" +msgstr "三个月排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:57 +msgid "6m return" +msgstr "六个月报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:58 +msgid "6m ranking" +msgstr "六个月排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:59 +msgid "1y return" +msgstr "一年报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:60 +msgid "1y ranking" +msgstr "一年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:61 +msgid "2y return" +msgstr "两年报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:62 +msgid "2y ranking" +msgstr "两年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:63 +msgid "3y return" +msgstr "三年报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:64 +msgid "3y ranking" +msgstr "三年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:65 +msgid "5y return" +msgstr "五年报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:66 +msgid "5y ranking" +msgstr "五年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:67 +msgid "10y return" +msgstr "十年报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:68 +msgid "10y ranking" +msgstr "十年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:69 +msgid "This year return" +msgstr "今年报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:70 +msgid "This year ranking" +msgstr "今年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:71 +msgid "Total return" +msgstr "自成立日报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:72 +msgid "Begin from" +msgstr "基金成立日" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:73 +msgid "Best 3m return" +msgstr "最佳三个月报酬" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:74 +msgid "Worst 3m return" +msgstr "最差三个月报酬" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:75 +msgid "Standard deviation (12m)" +msgstr "标准差 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:76 +msgid "Standard deviation (24m)" +msgstr "标准差 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:77 +msgid "Beta (12m)" +msgstr "β (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:78 +msgid "Beta (24m)" +msgstr "β (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:79 +msgid "Sharpe (12m)" +msgstr "夏普指数 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:80 +msgid "Sharpe (24m)" +msgstr "夏普指数 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:81 +msgid "Jensen (12m)" +msgstr "詹森指数 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:82 +msgid "Jensen (24m)" +msgstr "詹森指数 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:83 +msgid "Treynor (12m)" +msgstr "崔纳指数 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:84 +msgid "Treynor (24m)" +msgstr "崔纳指数 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:85 +msgid "Information Ratio (major categories) (12m)" +msgstr "信息比例(大分类) (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:86 +msgid "Information Ratio (major categories) (24m)" +msgstr "信息比例(大分类) (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:87 +msgid "Information Ratio (minor categories) (12m)" +msgstr "信息比例(细分类) (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:88 +msgid "Information Ratio (minor categories) (24m)" +msgstr "信息比例(细分类) (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:89 +msgid "This month turnover" +msgstr "当月周转率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:90 +msgid "12m turnover" +msgstr "累积周转率 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:91 +msgid "Duration" +msgstr "存续期间" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:92 +msgid "Rating" +msgstr "信用评等" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:93 +msgid "Manager less than 1y?" +msgstr "经理未满一年?" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:98 +msgid "4433 Principle" +msgstr "4433 法则" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:163 +msgid "Search for a fund:" +msgstr "搜索基金:" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:173 +msgid "Search" +msgstr "搜索" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:199 +msgid "Advanced filter:" +msgstr "高端筛选条件:" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:250 +msgid "Your query found [*,_1,fund]." +msgstr "共 [#,_1] 笔相符的基金。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:253 +msgid "[*,_1,fund]." +msgstr "[#,_1] 笔基金。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:259 +msgid "Your query found [*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的基金,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:263 +msgid "[*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔基金,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage.pm:38 +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:38 +msgid "Select a Message" +msgstr "选择留言" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage.pm:39 +msgid "Manage Soundless Backalley" +msgstr "管理无声的后巷" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:39 +msgid "Manage Travellers' Guestbook" +msgstr "管理旅人留言簿" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:42 +msgid "Specie" +msgstr "物种" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:43 +msgid "Language tag" +msgstr "语言标签" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:38 +msgid "Select a English Literal Work" +msgstr "选择英文写作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:39 +msgid "Manage English Literal Works" +msgstr "管理英文写作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:51 +msgid "Write a new English literal work." +msgstr "写新英文写作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:57 +msgid "Search for a English literal work:" +msgstr "搜索英文写作:" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:74 +msgid "Your query found [*,_1,English literal work]." +msgstr "共 [#,_1] 篇相符的英文写作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:77 +msgid "[*,_1,English literal work]." +msgstr "共 [#,_1] 篇英文写作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:83 +msgid "Your query found [*,_1,English literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的英文写作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:87 +msgid "[*,_1,English literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇英文写作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:38 +msgid "Select a Chinese Literal Work" +msgstr "选择中文写作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:39 +msgid "Manage Chinese Literal Works" +msgstr "管理中文写作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:51 +msgid "Write a new Chinese literal work." +msgstr "写新中文写作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:57 +msgid "Search for a Chinese literal work:" +msgstr "搜索中文写作:" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:74 +msgid "Your query found [*,_1,Chinese literal work]." +msgstr "共 [#,_1] 篇相符的中文写作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:77 +msgid "[*,_1,Chinese literal work]." +msgstr "共 [#,_1] 篇中文写作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:83 +msgid "Your query found [*,_1,Chinese literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的中文写作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:87 +msgid "[*,_1,Chinese literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇中文写作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:38 +msgid "Select a Chinese Poem" +msgstr "选择中文诗" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:39 +msgid "Manage Chinese Poems" +msgstr "管理中文诗" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:44 +msgid "Work set" +msgstr "写作集" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:52 +msgid "Write a new Chinese poem." +msgstr "写新中文诗。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:58 +msgid "Search for a Chinese poem:" +msgstr "搜索中文诗:" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:75 +msgid "Your query found [*,_1,Chinese poem]." +msgstr "共 [#,_1] 首相符的中文诗。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:78 +msgid "[*,_1,Chinese poem]." +msgstr "共 [#,_1] 首中文诗" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:84 +msgid "Your query found [*,_1,Chinese poem], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 首相符的中文诗,列出第 [#,_2] 首到第 [#,_3] 首。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:88 +msgid "[*,_1,Chinese poem], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 首中文诗,列出第 [#,_2] 首到第 [#,_3] 首。" + +#: magicat/lib/perl5/Selima/imacat/List/Pages.pm:37 +msgid "HTML class" +msgstr "HTML 类别" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:38 +msgid "Select a Paper" +msgstr "选择论文" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:42 +msgid "Type" +msgstr "类型" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:43 +msgid "Year" +msgstr "年" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:44 +msgid "Month" +msgstr "月" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:47 +msgid "Publication" +msgstr "刊物" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:49 +msgid "DOI" +msgstr "数字对象识别号" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:57 +msgid "Add a new paper." +msgstr "建新论文。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:63 +msgid "Search for a paper:" +msgstr "搜索论文:" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:80 +msgid "Your query found [*,_1,paper]." +msgstr "共 [#,_1] 篇相符的论文。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:83 +msgid "[*,_1,paper]." +msgstr "共 [#,_1] 篇论文。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:89 +msgid "Your query found [*,_1,paper], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的论文,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:93 +msgid "[*,_1,paper], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇论文,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:38 +msgid "Select a Researcher" +msgstr "选择研究者" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:39 +msgid "Manage Researchers" +msgstr "管理研究者" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:42 +msgid "Abbreviation" +msgstr "缩写" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:50 +msgid "Add a new researcher." +msgstr "建新研究者。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:56 +msgid "Search for a researcher:" +msgstr "搜索研究者:" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:73 +msgid "Your query found [*,_1,researcher]." +msgstr "共 [#,_1] 位相符的研究者。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:76 +msgid "[*,_1,researcher]." +msgstr "共 [#,_1] 位研究者。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:82 +msgid "Your query found [*,_1,researcher], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位相符的研究者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:86 +msgid "[*,_1,researcher], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位研究者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:45 +msgid "Full Text Search" +msgstr "全文检索" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:46 +msgid "" +"

    Tavern IMACAT's

    \n" +"

    Full Text Search

    " +msgstr "" +"

    旅舍依玛

    \n" +"

    全文检索

    " + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:48 +msgid "Search Result" +msgstr "搜索结果" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:49 +msgid "" +"

    Tavern IMACAT's

    \n" +"

    Search Result

    " +msgstr "" +"

    旅舍依玛

    \n" +"

    搜索结果

    " + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:72 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:100 +msgid "Please fill in your query." +msgstr "请填上检索的辞汇。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:160 +msgid "Search in the website:" +msgstr "网站检索:" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:177 +msgid "Your query found [*,_1,article]." +msgstr "共 [#,_1] 篇相符的文章。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:180 +msgid "[*,_1,article]." +msgstr "共 [#,_1] 篇文章。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:186 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:190 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:224 +msgid "Tavern Diary on [_1]" +msgstr "[_1] 旅舍日记" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:233 +msgid "Change Log on [_1]" +msgstr "[_1] 更新日志" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:271 +msgid "English writings" +msgstr "英文写作" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:281 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:290 +msgid "Guestbook Message on [_1]" +msgstr "[_1] 留言" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:38 +msgid "Select a Tag" +msgstr "选择标签" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:39 +msgid "Manage Tags" +msgstr "管理标签" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:49 +msgid "Add a new tag." +msgstr "加新标签。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:55 +msgid "Search for a tag:" +msgstr "搜索标签:" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:72 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:74 +msgid "Your query found [*,_1,tag]." +msgstr "共 [#,_1] 个相符的标签。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:75 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:77 +msgid "[*,_1,tag]." +msgstr "共 [#,_1] 个标签。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:81 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:83 +msgid "Your query found [*,_1,tag], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个相符的标签,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:85 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:87 +msgid "[*,_1,tag], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个标签,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:110 +msgid "This log entry was not modified." +msgstr "日志未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:114 +msgid "This log entry has been successfully added." +msgstr "日志写好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:118 +msgid "This log entry has been successfully updated." +msgstr "日志存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:122 +msgid "This log entry has been successfully deleted." +msgstr "日志删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:109 +msgid "This diary entry was not modified." +msgstr "日记未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:113 +msgid "This diary entry has been successfully added." +msgstr "日记写好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:117 +msgid "This diary entry has been successfully updated." +msgstr "日记存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:121 +msgid "This diary entry has been successfully deleted." +msgstr "日记删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:104 +msgid "This English literal work was not modified." +msgstr "英文写作未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:108 +msgid "This English literal work has been successfully added." +msgstr "英文写作写好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:112 +msgid "This English literal work has been successfully updated." +msgstr "英文写作存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:116 +msgid "This English literal work has been successfully deleted." +msgstr "英文写作删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:188 +msgid "This Chinese literal work was not modified." +msgstr "中文写作未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:192 +msgid "This Chinese literal work has been successfully added." +msgstr "中文写作写好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:196 +msgid "This Chinese literal work has been successfully updated." +msgstr "中文写作存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:200 +msgid "This Chinese literal work has been successfully deleted." +msgstr "中文写作删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:102 +msgid "This Chinese poem was not modified." +msgstr "中文诗未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:106 +msgid "This Chinese poem has been successfully added." +msgstr "中文诗写好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:110 +msgid "This Chinese poem has been successfully updated." +msgstr "中文诗存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:114 +msgid "This Chinese poem has been successfully deleted." +msgstr "中文诗删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:293 +msgid "This paper was not modified." +msgstr "论文未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:297 +msgid "This paper has been successfully added." +msgstr "论文建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:301 +msgid "This paper has been successfully updated." +msgstr "论文存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:305 +msgid "This paper has been successfully deleted." +msgstr "论文删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:90 +msgid "This researcher was not modified." +msgstr "研究者未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:94 +msgid "This researcher has been successfully added." +msgstr "研究者建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:98 +msgid "This researcher has been successfully updated." +msgstr "研究者存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:102 +msgid "This researcher has been successfully deleted." +msgstr "研究者删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:88 +msgid "This tag was not modified." +msgstr "标签未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:92 +msgid "This tag has been successfully added." +msgstr "标签建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:96 +msgid "This tag has been successfully updated." +msgstr "标签存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:100 +msgid "This tag has been successfully deleted." +msgstr "标签删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook/Public.pm:44 +msgid "Your specie is too long. (Max. length [#,_1])" +msgstr "妳的物种太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook/Public.pm:63 +msgid "Your e-mail is too long. (Max. length [#,_1])" +msgstr "妳的电子邮件信箱太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:73 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:73 +msgid "Please select a paper." +msgstr "请选择论文。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:94 +msgid "Please select a author." +msgstr "请选择作者。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:97 +msgid "This author does not exist anymore. Please select another one." +msgstr "查无此作者,请改选其她作者。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:118 +msgid "This paper author already exists. You cannot create a duplicated one." +msgstr "已有同一笔论文作者,请勿重复建档。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:94 +msgid "Please select a tag." +msgstr "请选择标签。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:97 +msgid "This tag does not exist anymore. Please select another one." +msgstr "查无此标签,请改选其她标签。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:118 +msgid "This paper tag already exists. You cannot create a duplicated one." +msgstr "已有同一笔论文标签,请勿重复建档。" + +#: magicat/lib/perl5/Selima/imacat/Form/Garbage/Public.pm:48 +msgid "I'm sick." +msgstr "我要吐了" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:42 +msgid "" +"General commercial advertisements are not welcomed and may be deleted at " +"once. HTML is not supported." +msgstr "旅人留言簿不欢迎一般商业广告,随见随删。不支持 HTML 留言。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:49 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:49 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:47 +msgid "Delete this type" +msgstr "删掉这个类型" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:54 +msgid "This table provides you a form to add a new paper author." +msgstr "本表提供建新论文作者的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:57 +msgid "This table provides you a form to change a current paper author." +msgstr "本表提供编变更论文作者的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:60 +msgid "This table provides you a form to delete a paper author." +msgstr "本表提供删除论文作者的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:77 +msgid "Add a New Paper Author" +msgstr "建新论文作者" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:80 +msgid "Change a Current Paper Author" +msgstr "变更论文作者" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:83 +msgid "Delete a Paper Author" +msgstr "删除论文作者" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:93 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:93 +msgid "Paper:" +msgstr "论文:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:98 +msgid "Author:" +msgstr "作者:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:54 +msgid "This table provides you a form to add a new paper tag." +msgstr "本表提供建新论文标签的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:57 +msgid "This table provides you a form to change a current paper tag." +msgstr "本表提供编变更论文标签的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:60 +msgid "This table provides you a form to delete a paper tag." +msgstr "本表提供删除论文标签的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:77 +msgid "Add a New Paper Tag" +msgstr "建新论文标签" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:80 +msgid "Change a Current Paper Tag" +msgstr "变更论文标签" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:83 +msgid "Delete a Paper Tag" +msgstr "删除论文标签" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:98 +msgid "Tag:" +msgstr "标签:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:52 +msgid "This table provides you a form to add a new paper type." +msgstr "本表提供建新论文类型的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:55 +msgid "This table provides you a form to edit a current paper type." +msgstr "本表提供编辑论文类型的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:58 +msgid "This table provides you a form to delete a paper type." +msgstr "本表提供删除论文类型的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:75 +msgid "Add a New Paper Type" +msgstr "建新论文类型" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:78 +msgid "Edit a Current Paper Type" +msgstr "编辑论文类型" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:81 +msgid "Delete a Paper Type" +msgstr "删除论文类型" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog/Public.pm:136 +msgid "Date:" +msgstr "日期:" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog/Public.pm:146 +msgid "The change log entry seperator" +msgstr "更新日志分隔线" + +#: magicat/lib/perl5/Selima/imacat/List/Diary/Public.pm:146 +msgid "The diary entry seperator" +msgstr "日记分隔线" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage/Public.pm:68 +msgid "The message entry seperator" +msgstr "留言分隔线" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:38 +msgid "Select a Paper Author" +msgstr "选择论文作者" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:39 +msgid "Manage Paper Authors" +msgstr "管理论文作者" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:42 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:42 +msgid "Paper" +msgstr "论文" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:43 +msgid "Author" +msgstr "作者" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:51 +msgid "Add a new paper author." +msgstr "建新论文作者。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:57 +msgid "Search for a paper author:" +msgstr "搜索论文作者:" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:74 +msgid "Your query found [*,_1,author]." +msgstr "共 [#,_1] 位相符的论文作者。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:77 +msgid "[*,_1,author]." +msgstr "共 [#,_1] 位论文作者。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:83 +msgid "Your query found [*,_1,author], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位相符的论文作者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:87 +msgid "[*,_1,author], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位论文作者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:38 +msgid "Select a Paper Tag" +msgstr "选择论文标签" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:39 +msgid "Manage Paper Tags" +msgstr "管理论文标签" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:43 +msgid "Tag" +msgstr "标签" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:51 +msgid "Add a new paper tag." +msgstr "加新论文标签。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:57 +msgid "Search for a paper tag:" +msgstr "搜索论文标签:" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:38 +msgid "Select a Paper Type" +msgstr "选择论文类型" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:39 +msgid "Manage Paper Types" +msgstr "管理论文类型" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:49 +msgid "Add a new paper type." +msgstr "建新论文类型。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:55 +msgid "Search for a paper type:" +msgstr "搜索论文类型:" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:72 +msgid "Your query found [*,_1,type]." +msgstr "共 [#,_1] 类相符的类型。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:75 +msgid "[*,_1,type]." +msgstr "共 [#,_1] 类类型。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:81 +msgid "Your query found [*,_1,type], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 类相符的类型,列出第 [#,_2] 类到第 [#,_3] 类。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:85 +msgid "[*,_1,type], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 类类型,列出第 [#,_2] 类到第 [#,_3] 类。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:97 +msgid "This paper author was not modified." +msgstr "论文作者未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:101 +msgid "This paper author has been successfully added." +msgstr "论文作者建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:105 +msgid "This paper author has been successfully updated." +msgstr "论文作者存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:109 +msgid "This paper author has been successfully deleted." +msgstr "论文作者删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:97 +msgid "This paper tag was not modified." +msgstr "论文标签未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:101 +msgid "This paper tag has been successfully added." +msgstr "论文标签建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:105 +msgid "This paper tag has been successfully updated." +msgstr "论文标签存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:109 +msgid "This paper tag has been successfully deleted." +msgstr "论文标签删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:94 +msgid "This paper type was not modified." +msgstr "论文类型未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:98 +msgid "This paper type has been successfully added." +msgstr "论文类型建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:102 +msgid "This paper type has been successfully updated." +msgstr "论文类型存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:106 +msgid "This paper type has been successfully deleted." +msgstr "论文类型删掉了。" + +#~ msgid "Manage Accounting" +#~ msgstr "管理会计" + +#~ msgid "Reports" +#~ msgstr "报表" + +#~ msgid "Transactions" +#~ msgstr "传票" + +#~ msgid "Subjects" +#~ msgstr "科目" + +#~ msgid "Records" +#~ msgstr "分录" + +#~ msgid "Please fill in the publication." +#~ msgstr "请填上刊物。" + +#~ msgid "This URL is not reachable. Check if there is any typo in it." +#~ msgstr "这个网址连不上,请检查有没有拼错。" diff --git a/htdocs/imacat/magicat/po/zh_CN.pox b/htdocs/imacat/magicat/po/zh_CN.pox new file mode 100644 index 0000000..707e717 --- /dev/null +++ b/htdocs/imacat/magicat/po/zh_CN.pox @@ -0,0 +1,2573 @@ +# Simplified Chinese PO file for the Tavern IMACAT's website +# Copyright (C) 2003-2018 imacat +# This file is distributed under the same license as the imacat package. +# imacat , 2003-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: imacat 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-03-24 07:09+0800\n" +"PO-Revision-Date: 2018-11-02 01:03+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: cgi-bin/1-guestbook.cgi:40 cgi-bin/1-guestbook.cgi:111 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:282 +msgid "Travellers' Guestbook" +msgstr "旅人留言簿" + +#: cgi-bin/1-guestbook.cgi:112 +msgid "" +"

    Tavern IMACAT’s

    \n" +"

    Travellers’
    Guestbook

    " +msgstr "" +"

    旅舍的

    \n" +"

    旅人留言簿

    " + +#: cgi-bin/1-guestbook.cgi:129 +msgid "Good morning to thee, gentle friend and traveller!" +msgstr "早安。温和的友人及旅行者。" + +#: cgi-bin/1-guestbook.cgi:130 +msgid "" +"I call thee \"traveller\" no matter if thou hast never left thy home town, " +"no matter if thou wilst never again leave thy room, because all of us are " +"travellers. I call thee traveller for truly all of us travel a spiritual or " +"philosophical path -- even if it is simply by living the life that we choose " +"to live, or by searching for a new life when our current one fails to " +"satisfy our needs as thinking spiritual beings." +msgstr "" +"即使妳不曾离开过妳的故乡,也不曾离开妳的房间,我都称呼妳为旅行者,因为我们全" +"都是旅行者。我们在精神或哲学的道路上──即使它只是简单地活在我们选择的生活方式" +"上,或当现在的生活并不能满足精神上的需要时,而寻找另一种新的生活方式。" + +#: cgi-bin/1-guestbook.cgi:133 +msgid "-- The Book of Fellowship, Ultima VII" +msgstr "──友谊会手册‧创世纪Ⅶ" + +#: cgi-bin/garbage.cgi:40 +msgid "garbage, daub, poetry, message, essay" +msgstr "心情垃圾, 涂鸦, 诗, 留言, 短文" + +#: cgi-bin/garbage.cgi:110 magicat/lib/perl5/Selima/imacat/List/Search.pm:291 +msgid "Soundless Backalley" +msgstr "无声的后巷" + +#: cgi-bin/garbage.cgi:111 +msgid "" +"

    The

    \n" +"

    Soundless
    Backalley

    " +msgstr "" +"

    旅舍的

    \n" +"

    无声的后巷

    " + +#: cgi-bin/garbage.cgi:128 +msgid "" +"This is the backalley of Tavern. Every morning barmaid Cotton will put " +"garbages here. Besides that, there's never anyone passing by. Just " +"stinking garbages, drunks unable to tell dead or alive, cats and dogs and " +"flies, piss and vomits. The wall is filled with drawings and words unable " +"to tell whether they are poetry or shits. The vague music and laughters " +"come so faraway from inside the Tavern, like a neverending rhythm repeats " +"itself. The sun is blocked by the buildings. Even the time stops." +msgstr "" +"旅舍的后巷,除了每天清晨,女侍‧絮把垃圾拿出来倒以外,没有人会经过的地方。堆满" +"了腐臭的垃圾、分不清是死是活的醉汉、猫狗、苍蝇、排泄物、呕吐物。墙上画满不知" +"道是诗还是脏话的句子和涂鸦。远处隐约传来旅舍吧抬的音乐和嘈杂声,像永恒的节奏" +"一样在远处反复吟唱着。阳光被旅舍挡住,连时间也不动了。" + +#: cgi-bin/garbage.cgi:129 +msgid "" +"There's no one here, just you and yourself. Soundless is the loudest " +"sound. No matter how hard if you cry, shout or scream, you're still alone. " +"This is the darkest and the loneliest corner in the Tavern." +msgstr "" +"这里没有别人,只有妳和妳自己。无声是最吵杂的声音。妳撕破喉咙哭泣,也没人听得" +"见。这是旅舍最阴暗的地方,也是旅舍最孤寂的角落。" + +#: cgi-bin/plurkavatar.cgi:41 cgi-bin/plurkfav.cgi:43 +msgid "Plurk" +msgstr "噗浪" + +#: cgi-bin/plurkavatar.cgi:65 +msgid "There is no Plurk user \"[_1]\"." +msgstr "查无噗浪用户 [_1] 。" + +#: cgi-bin/plurkavatar.cgi:68 +msgid "Avator is not found for user \"[_1]\"." +msgstr "查无噗浪用户 [_1] 的头像。" + +#: cgi-bin/plurkavatar.cgi:72 +msgid "Plurk service is not available now." +msgstr "噗浪目前无法使用。" + +#: cgi-bin/plurkavatar.cgi:75 +msgid "Please fill in the Plurk user." +msgstr "请填上噗浪用户。" + +#: cgi-bin/plurkavatar.cgi:89 +msgid "Plurk Avatars" +msgstr "噗浪头像" + +#: cgi-bin/plurkavatar.cgi:96 +msgid "Plurk Avatars for User [_1]" +msgstr "[_1] 的噗浪头像" + +#: cgi-bin/plurkavatar.cgi:121 +msgid "Plurk user:" +msgstr "噗浪用户:" + +#: cgi-bin/plurkfav.cgi:52 +msgid "Plurk Favorites" +msgstr "噗浪喜欢" + +#: cgi-bin/plurkfav.cgi:86 +msgid "Plurk permanent link URL:" +msgstr "噗浪链接:" + +#: cgi-bin/plurkfav.cgi:105 +msgid "Plurk ID: [_1]" +msgstr "噗浪编号: [_1]" + +#: cgi-bin/plurkfav.cgi:106 +msgid "Set Plurk favorite" +msgstr "设置噗浪喜欢" + +#: cgi-bin/plurkfav.cgi:107 +msgid "Unset Plurk favorite" +msgstr "取消噗浪喜欢" + +#: cgi-bin/search.cgi:43 +msgid "search, query, full text search" +msgstr "搜索, 检索, 全文检索" + +#: magicat/cgi-bin/acctrecs.cgi:44 magicat/cgi-bin/acctreps.cgi:39 +#: magicat/cgi-bin/acctsubj.cgi:42 magicat/cgi-bin/accttrx.cgi:43 +msgid "accounting" +msgstr "会计" + +#: magicat/cgi-bin/acctrecs.cgi:110 magicat/cgi-bin/acctrecs.cgi:157 +#: magicat/cgi-bin/acctsubj.cgi:120 magicat/cgi-bin/acctsubj.cgi:180 +#: magicat/cgi-bin/accttrx.cgi:110 magicat/cgi-bin/accttrx.cgi:157 +#: magicat/cgi-bin/changelog.cgi:110 magicat/cgi-bin/changelog.cgi:159 +#: magicat/cgi-bin/diary.cgi:110 magicat/cgi-bin/diary.cgi:159 +#: magicat/cgi-bin/garbage.cgi:104 magicat/cgi-bin/garbage.cgi:148 +#: magicat/cgi-bin/groupmem.cgi:108 magicat/cgi-bin/groupmem.cgi:153 +#: magicat/cgi-bin/groups.cgi:121 magicat/cgi-bin/groups.cgi:176 +#: magicat/cgi-bin/guestbook.cgi:104 magicat/cgi-bin/guestbook.cgi:150 +#: magicat/cgi-bin/linkcat.cgi:119 magicat/cgi-bin/linkcat.cgi:177 +#: magicat/cgi-bin/linkcatz.cgi:108 magicat/cgi-bin/linkcatz.cgi:153 +#: magicat/cgi-bin/links.cgi:110 magicat/cgi-bin/links.cgi:161 +#: magicat/cgi-bin/literalen.cgi:161 magicat/cgi-bin/literalen.cgi:205 +#: magicat/cgi-bin/literalzh.cgi:175 magicat/cgi-bin/literalzh.cgi:219 +#: magicat/cgi-bin/ltzhpoem.cgi:106 magicat/cgi-bin/ltzhpoem.cgi:151 +#: magicat/cgi-bin/pages.cgi:114 magicat/cgi-bin/pages.cgi:163 +#: magicat/cgi-bin/papers.cgi:108 magicat/cgi-bin/papers.cgi:154 +#: magicat/cgi-bin/pprauthr.cgi:105 magicat/cgi-bin/pprauthr.cgi:150 +#: magicat/cgi-bin/pprtags.cgi:105 magicat/cgi-bin/pprtags.cgi:150 +#: magicat/cgi-bin/pprtypes.cgi:112 magicat/cgi-bin/pprtypes.cgi:165 +#: magicat/cgi-bin/resrcher.cgi:109 magicat/cgi-bin/resrcher.cgi:157 +#: magicat/cgi-bin/scptpriv.cgi:106 magicat/cgi-bin/scptpriv.cgi:151 +#: magicat/cgi-bin/tags.cgi:109 magicat/cgi-bin/tags.cgi:157 +#: magicat/cgi-bin/usermem.cgi:108 magicat/cgi-bin/usermem.cgi:153 +#: magicat/cgi-bin/userpref.cgi:106 magicat/cgi-bin/userpref.cgi:151 +#: magicat/cgi-bin/users.cgi:125 magicat/cgi-bin/users.cgi:189 +msgid "Incorrect form: [_1]." +msgstr "查无此表格: [_1] 。" + +#: magicat/cgi-bin/acctrecs.cgi:204 +msgid "Please select the accounting record." +msgstr "请选择会计分录。" + +#: magicat/cgi-bin/acctrecs.cgi:212 +msgid "" +"This accounting record does not exist anymore. Please select another one." +msgstr "查无此会计分录,请重新选择。" + +#: magicat/cgi-bin/acctsubj.cgi:93 magicat/cgi-bin/acctsubj.cgi:140 +msgid "Please add a new accounting subject from [_1]." +msgstr "请由[_1]建新会计科目。" + +#: magicat/cgi-bin/acctsubj.cgi:109 magicat/cgi-bin/acctsubj.cgi:169 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the subject, " +"[numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] " +"must first be deleted." +msgstr "" +"本会计科目下有子会计科目,不可直接删除。要删除本会计科目,请先删除其下的子会" +"计科目。" + +#: magicat/cgi-bin/acctsubj.cgi:113 magicat/cgi-bin/acctsubj.cgi:173 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the subject, [numerate,_1,its " +"accounting record,all of its accounting records] must first be deleted." +msgstr "" +"本会计科目下有会计分录,不可直接删除。要删除本会计科目,请先删除其下的会计分" +"录。" + +#: magicat/cgi-bin/acctsubj.cgi:232 +msgid "Please select the accounting subject." +msgstr "请选择会计科目。" + +#: magicat/cgi-bin/acctsubj.cgi:240 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "查无此会计科目,请重新选择。" + +#: magicat/cgi-bin/accttrx.cgi:204 +msgid "Please select the accounting transaction." +msgstr "请选择会计传票。" + +#: magicat/cgi-bin/accttrx.cgi:212 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "查无此会计传票,请重新选择。" + +#: magicat/cgi-bin/actlog.cgi:36 +msgid "activity, logs" +msgstr "活动, 记录, 日志" + +#: magicat/cgi-bin/changelog.cgi:42 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:472 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:539 +msgid "change log, history" +msgstr "更新日志, 变迁史" + +#: magicat/cgi-bin/changelog.cgi:91 magicat/cgi-bin/changelog.cgi:128 +msgid "Please write a new log entry from [_1]." +msgstr "请由[_1]写新日志。" + +#: magicat/cgi-bin/changelog.cgi:206 +msgid "Please select the log entry." +msgstr "请选择日志。" + +#: magicat/cgi-bin/changelog.cgi:214 +msgid "This log entry does not exist anymore. Please select another one." +msgstr "查无该则日志,请重新选择。" + +#: magicat/cgi-bin/diary.cgi:42 magicat/lib/perl5/Selima/imacat/Rebuild.pm:327 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:394 +msgid "diary" +msgstr "日记" + +#: magicat/cgi-bin/diary.cgi:91 magicat/cgi-bin/diary.cgi:128 +msgid "Please write a new diary entry from [_1]." +msgstr "请由[_1]写新日记。" + +#: magicat/cgi-bin/diary.cgi:206 +msgid "Please select the diary entry." +msgstr "请选择日记。" + +#: magicat/cgi-bin/diary.cgi:214 +msgid "This diary entry does not exist anymore. Please select another one." +msgstr "查无该则日记,请重新选择。" + +#: magicat/cgi-bin/funds.cgi:36 +msgid "mutual funds, performance, indicators" +msgstr "共同基金, 绩效, 指针" + +#: magicat/cgi-bin/garbage.cgi:40 +msgid "backalley" +msgstr "后巷" + +#: magicat/cgi-bin/garbage.cgi:195 magicat/cgi-bin/guestbook.cgi:197 +msgid "Please select the message." +msgstr "请选择要设置的留言。" + +#: magicat/cgi-bin/garbage.cgi:203 magicat/cgi-bin/guestbook.cgi:205 +msgid "This message does not exist anymore. Please select another one." +msgstr "查无该留言,请改选其她留言。" + +#: magicat/cgi-bin/groupmem.cgi:44 +msgid "group membership" +msgstr "群组成员" + +#: magicat/cgi-bin/groupmem.cgi:200 magicat/cgi-bin/usermem.cgi:200 +msgid "Please select the membership record." +msgstr "请选择成员关系。" + +#: magicat/cgi-bin/groupmem.cgi:208 magicat/cgi-bin/usermem.cgi:208 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "查无此成员关系,请重新选择。" + +#: magicat/cgi-bin/groups.cgi:48 +msgid "groups" +msgstr "群组" + +#: magicat/cgi-bin/groups.cgi:98 magicat/cgi-bin/groups.cgi:140 +msgid "Please create a new group from [_1]." +msgstr "请由[_1]建新群组。" + +#: magicat/cgi-bin/groups.cgi:224 +msgid "Please select the group." +msgstr "请选择群组。" + +#: magicat/cgi-bin/groups.cgi:232 +msgid "This group does not exist anymore. Please select another one." +msgstr "查无此群组,请重新选择。" + +#: magicat/cgi-bin/guestbook.cgi:40 +msgid "guestbook" +msgstr "留言簿" + +#: magicat/cgi-bin/linkcat.cgi:43 +msgid "link categories" +msgstr "相关链接分类" + +#: magicat/cgi-bin/linkcat.cgi:92 magicat/cgi-bin/linkcat.cgi:137 +msgid "Please add a new category from [_1]." +msgstr "请由[_1]建新分类。" + +#: magicat/cgi-bin/linkcat.cgi:108 magicat/cgi-bin/linkcat.cgi:166 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分类下有子类,不可直接删除。要删除本分类,请先删除其下的子类。" + +#: magicat/cgi-bin/linkcat.cgi:112 magicat/cgi-bin/linkcat.cgi:170 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分类下有链接,不可直接删除。要删除本分类,请先删除其下的链接。" + +#: magicat/cgi-bin/linkcat.cgi:225 +msgid "Please select the category." +msgstr "请选择分类。" + +#: magicat/cgi-bin/linkcat.cgi:233 +msgid "This category does not exist anymore. Please select another one." +msgstr "查无此分类,请重新选择。" + +#: magicat/cgi-bin/linkcatz.cgi:44 +msgid "link categorization" +msgstr "链接分类表" + +#: magicat/cgi-bin/linkcatz.cgi:200 +msgid "Please select the categorization record." +msgstr "请选择分类数据。" + +#: magicat/cgi-bin/linkcatz.cgi:208 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "查无此分类数据,请重新选择。" + +#: magicat/cgi-bin/links.cgi:42 magicat/lib/perl5/Selima/imacat/Rebuild.pm:254 +msgid "related links" +msgstr "相关链接" + +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:128 +msgid "Please add a new related link from [_1]." +msgstr "请由[_1]建新相关链接。" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Manage Keep Travelling" +msgstr "管理继续旅行" + +#: magicat/cgi-bin/links.cgi:211 +msgid "Please select the related link." +msgstr "请选择要设置的相关链接。" + +#: magicat/cgi-bin/links.cgi:219 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查无该相关链接,请改选其她相关链接。" + +#: magicat/cgi-bin/literalen.cgi:43 +msgid "English literal works" +msgstr "英文写作" + +#: magicat/cgi-bin/literalen.cgi:259 +msgid "Please select the English literal work." +msgstr "请选择要编辑的英文写作。" + +#: magicat/cgi-bin/literalen.cgi:267 +msgid "" +"This English literal work does not exist anymore. Please select another one." +msgstr "查无此英文写作,请重新选择。" + +#: magicat/cgi-bin/literalzh.cgi:44 +msgid "Chinese literal works" +msgstr "中文写作" + +#: magicat/cgi-bin/literalzh.cgi:273 +msgid "Please select the Chinese literal work." +msgstr "请选择要编辑的中文写作。" + +#: magicat/cgi-bin/literalzh.cgi:281 +msgid "" +"This Chinese literal work does not exist anymore. Please select another one." +msgstr "查无此中文写作,请重新选择。" + +#: magicat/cgi-bin/logout.cgi:39 +msgid "log out" +msgstr "注销" + +#: magicat/cgi-bin/logout.cgi:112 magicat/cgi-bin/logout.cgi:119 +msgid "Log Out" +msgstr "注销" + +#: magicat/cgi-bin/logout.cgi:135 +msgid "Are you sure you want to log out?" +msgstr "妳确定要注销吗?" + +#: magicat/cgi-bin/logout.cgi:136 magicat/lib/perl5/Selima/imacat/HTML.pm:577 +msgid "Log out" +msgstr "注销" + +#: magicat/cgi-bin/logout.cgi:152 +msgid "Log in again." +msgstr "重新登录。" + +#: magicat/cgi-bin/ltzhpoem.cgi:42 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:253 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:262 +msgid "Chinese poems" +msgstr "中文诗" + +#: magicat/cgi-bin/ltzhpoem.cgi:199 +msgid "Please select the Chinese poem." +msgstr "请选择中文诗。" + +#: magicat/cgi-bin/ltzhpoem.cgi:207 +msgid "This Chinese poem does not exist anymore. Please select another one." +msgstr "查无此中文诗,请重新选择。" + +#: magicat/cgi-bin/pages.cgi:40 +msgid "pages" +msgstr "网页" + +#: magicat/cgi-bin/pages.cgi:89 magicat/cgi-bin/pages.cgi:132 +msgid "Please add a new page from [_1]." +msgstr "请由[_1]写新网页。" + +#: magicat/cgi-bin/pages.cgi:216 +msgid "Please select the page." +msgstr "请选择网页。" + +#: magicat/cgi-bin/pages.cgi:224 +msgid "This page does not exist anymore. Please select another one." +msgstr "查无此页,请改选其她网页。" + +#: magicat/cgi-bin/papers.cgi:44 magicat/cgi-bin/pprauthr.cgi:41 +#: magicat/cgi-bin/pprtags.cgi:41 magicat/cgi-bin/pprtypes.cgi:40 +msgid "papers" +msgstr "论文" + +#: magicat/cgi-bin/papers.cgi:201 +msgid "Please select the paper." +msgstr "请选择论文。" + +#: magicat/cgi-bin/papers.cgi:209 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:76 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:76 +msgid "This paper does not exist anymore. Please select another one." +msgstr "查无此论文,请改选其她论文。" + +#: magicat/cgi-bin/pprauthr.cgi:197 +msgid "Please select the paper author." +msgstr "请选择论文作者。" + +#: magicat/cgi-bin/pprauthr.cgi:205 +msgid "This paper author does not exist anymore. Please select another one." +msgstr "查无此论文作者,请改选其她论文作者。" + +#: magicat/cgi-bin/pprtags.cgi:197 +msgid "Please select the paper tag." +msgstr "请选择论文标签。" + +#: magicat/cgi-bin/pprtags.cgi:205 +msgid "This paper tag does not exist anymore. Please select another one." +msgstr "查无此论文标签,请改选其她论文标签。" + +#: magicat/cgi-bin/pprtypes.cgi:89 magicat/cgi-bin/pprtypes.cgi:130 +msgid "Please add a new paper type from [_1]." +msgstr "请由[_1]建新论文类型。" + +#: magicat/cgi-bin/pprtypes.cgi:105 magicat/cgi-bin/pprtypes.cgi:158 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:89 +msgid "" +"This paper type has [numerate,_1,a paper,papers]. It cannot be deleted. To " +"delete the type, [numerate,_1,its paper,all of its papers] must first be " +"deleted." +msgstr "本论文类型下有论文,不可直接删除。要删除本类型,请先删除其下的论文。" + +#: magicat/cgi-bin/pprtypes.cgi:212 +msgid "Please select the paper type." +msgstr "请选择论文类型。" + +#: magicat/cgi-bin/pprtypes.cgi:220 +msgid "This paper type does not exist anymore. Please select another one." +msgstr "查无此论文类型,请改选其她类型。" + +#: magicat/cgi-bin/rebuild.cgi:37 +msgid "rebuild pages" +msgstr "重制网页" + +#: magicat/cgi-bin/resrcher.cgi:41 +msgid "researchers" +msgstr "研究者" + +#: magicat/cgi-bin/resrcher.cgi:102 magicat/cgi-bin/resrcher.cgi:150 +#: magicat/cgi-bin/tags.cgi:102 magicat/cgi-bin/tags.cgi:150 +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:88 +msgid "" +"This researcher has [numerate,_1,a paper,papers]. It cannot be deleted. To " +"delete the researcher, [numerate,_1,its paper,all of its papers] must first " +"be deleted." +msgstr "本研究者下有论文,不可直接删除。要删除本研究者,请先删除其下的论文。" + +#: magicat/cgi-bin/resrcher.cgi:204 magicat/cgi-bin/tags.cgi:204 +msgid "Please select the researcher." +msgstr "请选择研究者。" + +#: magicat/cgi-bin/resrcher.cgi:212 magicat/cgi-bin/tags.cgi:212 +msgid "This researcher does not exist anymore. Please select another one." +msgstr "查无此研究者,请重新选择。" + +#: magicat/cgi-bin/saveform.cgi:46 +msgid "saved forms" +msgstr "暂存表单" + +#: magicat/cgi-bin/saveform.cgi:77 +msgid "Form [_1] does not exist anymore. Please select another one." +msgstr "查无表单 [_1] ,请改选其她表单。" + +#: magicat/cgi-bin/saveform.cgi:92 +msgid "Manage the Saved Forms" +msgstr "管理暂存表单" + +#: magicat/cgi-bin/saveform.cgi:134 +msgid "Select" +msgstr "选" + +#: magicat/cgi-bin/scptpriv.cgi:42 +msgid "script privilege" +msgstr "程序权限" + +#: magicat/cgi-bin/scptpriv.cgi:198 +msgid "Please select the script privilege record." +msgstr "请选择程序权限。" + +#: magicat/cgi-bin/scptpriv.cgi:206 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "查无该程序权限,请重新选择。" + +#: magicat/cgi-bin/tags.cgi:41 +msgid "tags" +msgstr "标签" + +#: magicat/cgi-bin/usermem.cgi:44 +msgid "user membership" +msgstr "用户成员" + +#: magicat/cgi-bin/userpref.cgi:42 +msgid "user preference" +msgstr "用户偏好" + +#: magicat/cgi-bin/userpref.cgi:198 +msgid "Please select the user preference." +msgstr "请选择用户偏好。" + +#: magicat/cgi-bin/userpref.cgi:206 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "查无该用户偏好,请重新选择。" + +#: magicat/cgi-bin/users.cgi:43 +msgid "users" +msgstr "帐号" + +#: magicat/cgi-bin/users.cgi:237 +msgid "Please select the user." +msgstr "请选择用户。" + +#: magicat/cgi-bin/users.cgi:245 +msgid "This user does not exist anymore. Please select another one." +msgstr "查无此人,请重新选择。" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:52 +msgid "imacat" +msgstr "依玛猫" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:53 +msgid "© imacat. All rights reserved." +msgstr "© 依玛猫。依玛猫保有所有权利。" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:63 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1016 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:409 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:410 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:225 +msgid "Tavern Diary" +msgstr "旅舍日记" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:64 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:98 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:234 +msgid "Change Log" +msgstr "更新日志" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:65 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:108 +msgid "Chinese Literal Works" +msgstr "中文写作" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:66 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:112 +msgid "English Literal Works" +msgstr "英文写作" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:90 +msgid "Manage Content" +msgstr "管理网站" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:92 +msgid "Guestbook" +msgstr "留言簿" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:94 +msgid "Backalley" +msgstr "后巷" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:96 +msgid "Diary" +msgstr "日记" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:100 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:48 +msgid "Pages" +msgstr "网页" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:102 +msgid "Links" +msgstr "链接" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:104 +msgid "Link Categories" +msgstr "链接分类" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:106 +msgid "Link Categorization" +msgstr "链接分类表" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:110 +msgid "Chinese Poems" +msgstr "中文诗" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:116 +msgid "Manage Accounts" +msgstr "管理帐号" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:118 +msgid "Users" +msgstr "帐号" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:120 +msgid "Groups" +msgstr "群组" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:122 +msgid "User Membership" +msgstr "用户成员" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:124 +msgid "Group Membership" +msgstr "群组成员" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:126 +msgid "User Preferences" +msgstr "用户偏好" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:128 +msgid "Script Privileges" +msgstr "程序权限" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:148 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:39 +msgid "Manage Papers" +msgstr "管理论文" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:150 +msgid "Papers" +msgstr "论文" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:152 +msgid "Researchers" +msgstr "研究者" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:154 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:46 +msgid "Tags" +msgstr "标签" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:156 +msgid "Types" +msgstr "类型" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:158 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:45 +msgid "Authors" +msgstr "作者" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:160 +msgid "Paper Tags" +msgstr "论文标签" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:164 +msgid "Miscellaneous" +msgstr "杂项" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:166 +#, fuzzy +msgid "Accounting" +msgstr "会计" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:168 +msgid "Funds" +msgstr "基金" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:170 +msgid "Activity Log" +msgstr "活动日志" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:172 +msgid "Rebuild Pages" +msgstr "重制网页" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:174 +msgid "Analog" +msgstr "访客统计" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:176 +msgid "Test Script" +msgstr "测试程序" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:178 +msgid "MRTG" +msgstr "流量统计" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:180 +msgid "Saved Forms" +msgstr "暂存表单" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:182 +msgid "CGI Environment" +msgstr "CGI 环境" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:186 +msgid "Server Status" +msgstr "服务器状态" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:189 +msgid "Server Information" +msgstr "服务器信息" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:192 +msgid "Bwshare Information" +msgstr "节频信息" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:195 +msgid "Bwshare Trace" +msgstr "节频记录" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:198 +msgid "Perl Status" +msgstr "Perl 状态" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:253 +msgid "Skip to the page content area." +msgstr "跳到网页内文区。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:254 +msgid "Page Content Area" +msgstr "网页内文区" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:372 +msgid "Magicat" +msgstr "梅姬" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:441 +msgid "Navigation Links Area" +msgstr "导览链接区" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:521 +msgid "Language Switching Area" +msgstr "语言切换区" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:575 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "%s,妳好!(修改数据)" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:617 +#, c-format +msgid "%s:" +msgstr "%s:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:689 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:243 +msgid "Keep Travelling" +msgstr "继续旅行" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:757 +msgid "E-mail" +msgstr "电子邮件信箱" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:782 +msgid "URL:" +msgstr "网址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:785 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:920 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:69 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:49 +msgid "E-mail:" +msgstr "电子邮件信箱:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:791 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:921 +msgid "Address:" +msgstr "地址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:793 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:922 +msgid "Tel.:" +msgstr "电话:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:795 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:923 +msgid "Fax.:" +msgstr "传真:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:824 +msgid "" +"Are you ready to check out? Just drop your room key at the counter, and " +"travel for your next stop. Life is a never-ending trip, and Tavern is only " +"one of your many stops. Are you ready to go now?" +msgstr "" +"妳要退房了吗?把妳的房门钥匙交还给柜台,该向下一个停靠站出发了。这是一趟永无" +"止境的旅程,旅舍,只是妳的一个中途停靠站。若妳准备好了,就出发啰!" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:825 +msgid "" +"Greetings, traveller. I'm rinse the Tavern Tour Agent. Where is your next " +"stop?" +msgstr "妳好,旅行者。我是琳思。妳要往哪里去旅行呢?" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:837 +msgid "The database is empty." +msgstr "现无任何数据。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:906 +msgid "~[Tavern~] Website Registration" +msgstr "~[旅舍回函~] 网站登录" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:907 +msgid "" +"This table provide a form to register your site at Tavern \"Keep Travelling" +"\", the data column names and their input fields to fill in the information." +msgstr "" +"本表提供登录旅舍「继续旅行」的表单,网站数据字段名称,和填写该数据的输入格。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:908 +msgid "Fill in the description here." +msgstr "请填上简介。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:909 +msgid "Regiser your site" +msgstr "登录网站" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:910 +msgid "" +"I sincerely wish to build more hyperlinks with websites that're kind to " +"women/lesbian/queer. If you wish to link with me, or if you have any such " +"information, whether in Chinese or not, please tell me by filling this form " +"below. I'll put it in as soon as possible. Thank you." +msgstr "" +"我很希望能和各地对女性/同志友善的网站创建超链接。如果妳愿意和我连接,或是妳" +"有其她友善网站的信息,不论中文与否,请填写下表告诉我,我会尽快放进去。谢谢!" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:911 +msgid "" +"All fields in the form below, Except for the site name, the URL and the " +"description, are optional. Anything you fill here will be shown to " +"ANYONE who visits Tavern IMACAT's. Tavern does not collect " +"any personal informations. If you do not wish to distribute some private " +"informations, just leave them blank. If you represent some organization, " +"fill as detail as possible to help others finding you." +msgstr "" +"下表除站名、网址及简介外,所有数据皆为选填。妳填的所有数据都会显示在旅舍依玛" +"中,任何人都看得到。旅舍不搜集任何个人数据。若妳不愿私人数据" +"曝光,请留白勿填。若妳们是组织团体,请尽量详填所有数据,以方便她人联系。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:912 +msgid "General commercial sites besides lesbian shops are not welcome." +msgstr "除女同志商店外,旅舍恕不受理一般商业网站。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:914 +msgid "Site name:" +msgstr "站名:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:915 +msgid "Site name, 2nd language (if any):" +msgstr "站名(第二语言,可略):" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:916 +msgid "Site URL:" +msgstr "网址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:917 +msgid "Link logo URL:" +msgstr "链接小图网址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:918 +msgid "Category:" +msgstr "分类:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:919 +msgid "Introduction:" +msgstr "简介:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:924 +msgid "OK!" +msgstr "好了!" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1010 +msgid "The diary is empty." +msgstr "现无任何日记。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1015 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1075 +msgid "imacat's Private Bed♥room" +msgstr "依玛猫的闺♥房" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1025 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1085 +msgid "Index" +msgstr "目录" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1042 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:326 +#, c-format +msgid "Tavern Diary Volume %s" +msgstr "旅舍日记 卷%s" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1070 +msgid "The change log is empty." +msgstr "现无任何日志。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1076 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:554 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:555 +msgid "Tavern Change Log" +msgstr "旅舍更新日志" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1102 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:471 +#, c-format +msgid "Tavern Change Log Volume %s" +msgstr "旅舍更新日志 卷%s" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1482 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "mod_perl -- 速度,动力,无限可能" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1483 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" +"本程序以 Perl 撰写,专为 mod_perl 设计强化" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1496 +msgid "" +"This script is written in Perl." +msgstr "" +"本程序以 Perl 撰写" + +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:264 +msgid "Keep Travelling..." +msgstr "继续旅行……" + +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:265 +msgid "Continue Your Journey..." +msgstr "继续妳的旅程……" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:41 +msgid "This specie is too long. (Max. length [#,_1])" +msgstr "物种太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:60 +msgid "This e-mail is too long. (Max. length [#,_1])" +msgstr "电子邮件信箱太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:75 +msgid "Please choose the language." +msgstr "请选择语言。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:80 +msgid "" +"Language [_1] is invalid. Please choose a proper language from the form." +msgstr "[_1] 语无效。请由表上选择适当的语言。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:55 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:57 +msgid "Please fill in the date." +msgstr "请填上日期。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:58 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:61 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:63 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:60 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:63 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:65 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期请以 YYYY-MM-DD 格式填写。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:73 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:75 +msgid "" +"The literal work on this date already exists. You cannot create a " +"duplicated one." +msgstr "已有这一天的写作,请勿重复建档。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:95 +msgid "This title is too long. (Max. length [#,_1])" +msgstr "标题太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:117 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:117 +msgid "Fill in the content here." +msgstr "请填上内文。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LtZhPoem.pm:58 +msgid "Please select a work set." +msgstr "请选择写作集。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LtZhPoem.pm:61 +msgid "This work set does not exist anymore. Please select another one." +msgstr "查无此写作集,请重新选择。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Page.pm:41 +msgid "This HTML class is too long. (Max. length [#,_1])" +msgstr "HTML 类别太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:62 +msgid "Please select in the type." +msgstr "请选择类型。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:65 +msgid "This type does not exist anymore. Please select another one." +msgstr "查无此类型,请改选其她类型。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:83 +msgid "Please fill in the year of publication." +msgstr "请填上出版年。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:86 +msgid "This year of publication is too long. (Max. length [#,_1])" +msgstr "出版年太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:89 +msgid "This year of publication is too short. (Min. length [#,_1])" +msgstr "出版年太短了。(最短 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:93 +msgid "Please fill in a positive integer year of publication." +msgstr "出版年请填正整数。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:100 +msgid "Year ([#,_1]) out of range. Please specify between [#,_2] and [#,_3]." +msgstr "年([#,_1])超出范围,请设在 [#,_2] 到 [#,_3] 之间。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:121 +msgid "This month is too long. (Max. length [#,_1])" +msgstr "月份标题太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:125 +msgid "Please fill in the month as ~[month~], ~[month day~] or ~[season~]." +msgstr "月份请以 ~[月份~] 、 ~[月份 日期~] 或 ~[季节~] 格式填写。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:148 +msgid "Please fill in the author." +msgstr "请填上作者。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:313 +msgid "This publication is too long. (Max. length [#,_1])" +msgstr "刊物太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:334 +msgid "This pages is too long. (Max. length [#,_1])" +msgstr "页数太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:338 +msgid "Please fill in the pages as ### or ###-###." +msgstr "页数请填 ### 或 ###-### 格式。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:358 +msgid "This DOI is too long. (Max. length [#,_1])" +msgstr "数字对象识别号太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:369 +msgid "This paper already exists. You cannot create a duplicated one." +msgstr "已有同一篇论文,请勿重复建档。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:387 +msgid "Please fill in the URL." +msgstr "请填上网址。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:390 +msgid "This URL is too long. (Max. length [#,_1])" +msgstr "网址太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:394 +msgid "Please fill in a valid URL." +msgstr "请填上正确的网址。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:51 +msgid "Please fill in the full name." +msgstr "请填上名字。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:54 +msgid "This full name is too long. (Max. length [#,_1])" +msgstr "名字太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:73 +msgid "Please fill in the abbreviation." +msgstr "请填上缩写。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:76 +msgid "This abbreviation is too long. (Max. length [#,_1])" +msgstr "缩写太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Tag.pm:59 +msgid "This tag already exists. You cannot create a duplicated one." +msgstr "已有同一个论文标签,请勿重复建档。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:46 +msgid "Delete this log entry" +msgstr "删掉这则日志" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:51 +msgid "This table provides you a form to write a new log entry." +msgstr "本表提供写新日志的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:54 +msgid "This table provides you a form to edit a current log entry." +msgstr "本表提供编辑日志的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:57 +msgid "This table provides you a form to delete a log entry." +msgstr "本表提供删除日志的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:74 +msgid "Write a New Change Log Entry" +msgstr "写新更新日志" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:77 +msgid "Edit a Current Change Log Entry" +msgstr "编辑更新日志" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:80 +msgid "Delete a Change Log Entry" +msgstr "删除更新日志" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:89 +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:89 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:95 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:116 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:298 +msgid "Hide?" +msgstr "隐藏?" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:90 +msgid "Hide this log entry" +msgstr "隐藏这则日志" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:90 +msgid "Show this log entry" +msgstr "秀出这则日志" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:91 +msgid "Hide this log entry currently." +msgstr "暂勿秀出这则日志。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:96 +msgid "Page No.:" +msgstr "页数:" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:46 +msgid "Delete this diary entry" +msgstr "删掉这则日记" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:51 +msgid "This table provides you a form to write a new diary entry." +msgstr "本表提供写新日记的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:54 +msgid "This table provides you a form to edit a current diary entry." +msgstr "本表提供编辑日记的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:57 +msgid "This table provides you a form to delete a diary entry." +msgstr "本表提供删除日记的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:74 +msgid "Write a New Diary Entry" +msgstr "写新日记" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:77 +msgid "Edit a Current Diary Entry" +msgstr "编辑日记" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:80 +msgid "Delete a Diary Entry" +msgstr "删除日记" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:90 +msgid "Hide this diary entry" +msgstr "隐藏这则日记" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:90 +msgid "Show this diary entry" +msgstr "秀出这则日记" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:91 +msgid "Hide this diary entry currently." +msgstr "暂勿秀出这则日记。" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:74 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:54 +msgid "Specie:" +msgstr "物种:" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:90 +msgid "Language tag:" +msgstr "语言标签:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:46 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:50 +msgid "Delete this literal work" +msgstr "删掉这篇写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:51 +msgid "This table provides you a form to write a new English literal work." +msgstr "本表提供写新英文写作的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:54 +msgid "This table provides you a form to edit a current English literal work." +msgstr "本表提供编辑英文写作的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:57 +msgid "This table provides you a form to delete a English literal work." +msgstr "本表提供删除英文写作的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:74 +msgid "Write a New English Literal Work" +msgstr "写新英文写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:77 +msgid "Edit a Current English Literal Work" +msgstr "编辑英文写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:80 +msgid "Delete a English Literal Work" +msgstr "删除英文写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:87 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:93 +msgid "Preview this literal work." +msgstr "预览这篇写作。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:299 +msgid "Hide this literal work" +msgstr "隐藏这篇写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:299 +msgid "Show this literal work" +msgstr "秀出这篇写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:97 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:300 +msgid "Hide this literal work currently." +msgstr "暂勿秀出这篇写作。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:55 +msgid "This table provides you a form to write a new Chinese literal work." +msgstr "本表提供写新中文写作的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:58 +msgid "This table provides you a form to edit a current Chinese literal work." +msgstr "本表提供编辑中文写作的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:61 +msgid "This table provides you a form to delete a Chinese literal work." +msgstr "本表提供删除中文写作的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:80 +msgid "Write a New Chinese Literal Work" +msgstr "写新中文写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:83 +msgid "Edit a Current Chinese Literal Work" +msgstr "编辑中文写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:86 +msgid "Delete a Chinese Literal Work" +msgstr "删除中文写作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:114 +msgid "Title:" +msgstr "标题:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:115 +msgid "Content:" +msgstr "内文:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:118 +msgid "Hide this poem currently." +msgstr "暂勿秀出这首诗。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:122 +msgid "Hide this poem" +msgstr "隐藏这首诗" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:123 +msgid "Show this poem" +msgstr "秀出这首诗" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:135 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:187 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:261 +msgid "[numerate,_1,Poem]:" +msgstr "诗:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:188 +msgid "Original:" +msgstr "原:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:189 +msgid "New:" +msgstr "新:" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:49 +msgid "Delete this poem" +msgstr "删掉这首中文诗" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:54 +msgid "This table provides you a form to write a new Chinese poem." +msgstr "本表提供写新中文诗的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:57 +msgid "This table provides you a form to edit a current Chinese poem." +msgstr "本表提供编辑中文诗的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:60 +msgid "This table provides you a form to delete a Chinese poem." +msgstr "本表提供删除日中文诗的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:77 +msgid "Write a New Chinese Poem" +msgstr "写新中文诗" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:80 +msgid "Edit a Current Chinese Poem" +msgstr "编辑中文诗" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:83 +msgid "Delete a Chinese Poem" +msgstr "删除中文诗" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:93 +msgid "Work set:" +msgstr "写作集:" + +#: magicat/lib/perl5/Selima/imacat/Form/Page.pm:61 +msgid "HTML class:" +msgstr "HTML 类别:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:50 +msgid "Delete this paper" +msgstr "删掉这篇论文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:55 +msgid "This table provides you a form to add a new paper." +msgstr "本表提供建新论文的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:58 +msgid "This table provides you a form to edit a current paper." +msgstr "本表提供编辑论文的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:61 +msgid "This table provides you a form to delete a paper." +msgstr "本表提供删除论文的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:80 +msgid "Add a New Paper" +msgstr "建新论文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:83 +msgid "Edit a Current Paper" +msgstr "编辑论文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:86 +msgid "Delete a Paper" +msgstr "删除论文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:96 +msgid "Type:" +msgstr "类型:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:101 +msgid "Year of publication:" +msgstr "出版年:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:106 +msgid "Month of publication:" +msgstr "出版月:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:111 +msgid "Authors:" +msgstr "作者:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:117 +msgid "Tags:" +msgstr "标签:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:123 +msgid "Publication:" +msgstr "刊物:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:128 +msgid "Pages:" +msgstr "页数:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:133 +msgid "DOI.:" +msgstr "数字对象识别号:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:145 +msgid "APA citation:" +msgstr "APA 书目:" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:47 +msgid "Delete this researcher" +msgstr "删掉这个研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:52 +msgid "This table provides you a form to add a new researcher." +msgstr "本表提供建新研究者的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:55 +msgid "This table provides you a form to update a current researcher." +msgstr "本表提供设置研究者的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:58 +msgid "This table provides you a form to delete a researcher." +msgstr "本表提供删除研究者的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:75 +msgid "Add a New Researcher" +msgstr "建新研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:78 +msgid "Update a Current Researcher" +msgstr "编辑研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:81 +msgid "Delete a Researcher" +msgstr "删除研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:96 +msgid "Full name:" +msgstr "名字:" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:101 +msgid "Abbreviation:" +msgstr "缩写:" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:112 +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:103 +msgid "[numerate,_1,Paper]:" +msgstr "论文:" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:47 +msgid "Delete this tag" +msgstr "删掉这个标签" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:52 +msgid "This table provides you a form to add a new tag." +msgstr "本表提供加新标签的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:55 +msgid "This table provides you a form to edit a current tag." +msgstr "本表提供编辑标签的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:58 +msgid "This table provides you a form to delete a tag." +msgstr "本表提供删除标签的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:75 +msgid "Add a New Tag" +msgstr "加新标签" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:78 +msgid "Edit a Current Tag" +msgstr "编辑标签" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:81 +msgid "Delete a Tag" +msgstr "删除标签" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:38 +msgid "Select an Change Log Entry" +msgstr "选择更新日志" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:39 +msgid "Manage Change Log" +msgstr "管理更新日志" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:50 +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:50 +msgid "Page No." +msgstr "页数" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:58 +msgid "Write a new log entry." +msgstr "写新日志。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:64 +msgid "Search for a log entry:" +msgstr "搜索日志:" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:81 +msgid "Your query found [*,_1,log entry,log entries]." +msgstr "共 [#,_1] 则相符的日志。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:84 +msgid "[*,_1,log entry,log entries]." +msgstr "共 [#,_1] 则日志。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:90 +msgid "" +"Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 则相符的日志,列出第 [#,_2] 则到第 [#,_3] 则。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:94 +msgid "[*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 则日志,列出第 [#,_2] 则到第 [#,_3] 则。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:38 +msgid "Select a Diary Entry" +msgstr "选择日记" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:39 +msgid "Manage Diary" +msgstr "管理日记" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:58 +msgid "Write a new diary entry." +msgstr "写新日记。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:64 +msgid "Search for a diary entry:" +msgstr "搜索日记:" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:81 +msgid "Your query found [*,_1,diary entry,diary entries]." +msgstr "共 [#,_1] 则相符的日记。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:84 +msgid "[*,_1,diary entry,diary entries]." +msgstr "共 [#,_1] 则日记。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:90 +msgid "" +"Your query found [*,_1,diary entry,diary entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 则相符的日记,列出第 [#,_2] 则到第 [#,_3] 则。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:94 +msgid "[*,_1,diary entry,diary entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 则日记,列出第 [#,_2] 则到第 [#,_3] 则。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:42 +msgid "Browse Mutual Fund Performances" +msgstr "浏览共同基金绩效" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:52 +msgid "Name" +msgstr "名称" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:53 +msgid "1m return" +msgstr "一个月报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:54 +msgid "1m ranking" +msgstr "一个月排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:55 +msgid "3m return" +msgstr "三个月报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:56 +msgid "3m ranking" +msgstr "三个月排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:57 +msgid "6m return" +msgstr "六个月报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:58 +msgid "6m ranking" +msgstr "六个月排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:59 +msgid "1y return" +msgstr "一年报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:60 +msgid "1y ranking" +msgstr "一年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:61 +msgid "2y return" +msgstr "两年报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:62 +msgid "2y ranking" +msgstr "两年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:63 +msgid "3y return" +msgstr "三年报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:64 +msgid "3y ranking" +msgstr "三年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:65 +msgid "5y return" +msgstr "五年报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:66 +msgid "5y ranking" +msgstr "五年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:67 +msgid "10y return" +msgstr "十年报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:68 +msgid "10y ranking" +msgstr "十年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:69 +msgid "This year return" +msgstr "今年报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:70 +msgid "This year ranking" +msgstr "今年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:71 +msgid "Total return" +msgstr "自成立日报酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:72 +msgid "Begin from" +msgstr "基金成立日" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:73 +msgid "Best 3m return" +msgstr "最佳三个月报酬" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:74 +msgid "Worst 3m return" +msgstr "最差三个月报酬" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:75 +msgid "Standard deviation (12m)" +msgstr "标准差 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:76 +msgid "Standard deviation (24m)" +msgstr "标准差 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:77 +msgid "Beta (12m)" +msgstr "β (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:78 +msgid "Beta (24m)" +msgstr "β (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:79 +msgid "Sharpe (12m)" +msgstr "夏普指数 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:80 +msgid "Sharpe (24m)" +msgstr "夏普指数 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:81 +msgid "Jensen (12m)" +msgstr "詹森指数 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:82 +msgid "Jensen (24m)" +msgstr "詹森指数 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:83 +msgid "Treynor (12m)" +msgstr "崔纳指数 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:84 +msgid "Treynor (24m)" +msgstr "崔纳指数 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:85 +msgid "Information Ratio (major categories) (12m)" +msgstr "信息比例(大分类) (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:86 +msgid "Information Ratio (major categories) (24m)" +msgstr "信息比例(大分类) (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:87 +msgid "Information Ratio (minor categories) (12m)" +msgstr "信息比例(细分类) (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:88 +msgid "Information Ratio (minor categories) (24m)" +msgstr "信息比例(细分类) (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:89 +msgid "This month turnover" +msgstr "当月周转率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:90 +msgid "12m turnover" +msgstr "累积周转率 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:91 +msgid "Duration" +msgstr "存续期间" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:92 +msgid "Rating" +msgstr "信用评等" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:93 +msgid "Manager less than 1y?" +msgstr "经理未满一年?" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:98 +msgid "4433 Principle" +msgstr "4433 法则" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:163 +msgid "Search for a fund:" +msgstr "搜索基金:" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:173 +msgid "Search" +msgstr "搜索" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:199 +msgid "Advanced filter:" +msgstr "高端筛选条件:" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:250 +msgid "Your query found [*,_1,fund]." +msgstr "共 [#,_1] 笔相符的基金。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:253 +msgid "[*,_1,fund]." +msgstr "[#,_1] 笔基金。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:259 +msgid "Your query found [*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的基金,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:263 +msgid "[*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔基金,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage.pm:38 +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:38 +msgid "Select a Message" +msgstr "选择留言" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage.pm:39 +msgid "Manage Soundless Backalley" +msgstr "管理无声的后巷" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:39 +msgid "Manage Travellers' Guestbook" +msgstr "管理旅人留言簿" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:42 +msgid "Specie" +msgstr "物种" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:43 +msgid "Language tag" +msgstr "语言标签" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:38 +msgid "Select a English Literal Work" +msgstr "选择英文写作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:39 +msgid "Manage English Literal Works" +msgstr "管理英文写作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:51 +msgid "Write a new English literal work." +msgstr "写新英文写作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:57 +msgid "Search for a English literal work:" +msgstr "搜索英文写作:" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:74 +msgid "Your query found [*,_1,English literal work]." +msgstr "共 [#,_1] 篇相符的英文写作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:77 +msgid "[*,_1,English literal work]." +msgstr "共 [#,_1] 篇英文写作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:83 +msgid "Your query found [*,_1,English literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的英文写作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:87 +msgid "[*,_1,English literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇英文写作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:38 +msgid "Select a Chinese Literal Work" +msgstr "选择中文写作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:39 +msgid "Manage Chinese Literal Works" +msgstr "管理中文写作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:51 +msgid "Write a new Chinese literal work." +msgstr "写新中文写作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:57 +msgid "Search for a Chinese literal work:" +msgstr "搜索中文写作:" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:74 +msgid "Your query found [*,_1,Chinese literal work]." +msgstr "共 [#,_1] 篇相符的中文写作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:77 +msgid "[*,_1,Chinese literal work]." +msgstr "共 [#,_1] 篇中文写作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:83 +msgid "Your query found [*,_1,Chinese literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的中文写作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:87 +msgid "[*,_1,Chinese literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇中文写作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:38 +msgid "Select a Chinese Poem" +msgstr "选择中文诗" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:39 +msgid "Manage Chinese Poems" +msgstr "管理中文诗" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:44 +msgid "Work set" +msgstr "写作集" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:52 +msgid "Write a new Chinese poem." +msgstr "写新中文诗。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:58 +msgid "Search for a Chinese poem:" +msgstr "搜索中文诗:" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:75 +msgid "Your query found [*,_1,Chinese poem]." +msgstr "共 [#,_1] 首相符的中文诗。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:78 +msgid "[*,_1,Chinese poem]." +msgstr "共 [#,_1] 首中文诗" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:84 +msgid "Your query found [*,_1,Chinese poem], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 首相符的中文诗,列出第 [#,_2] 首到第 [#,_3] 首。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:88 +msgid "[*,_1,Chinese poem], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 首中文诗,列出第 [#,_2] 首到第 [#,_3] 首。" + +#: magicat/lib/perl5/Selima/imacat/List/Pages.pm:37 +msgid "HTML class" +msgstr "HTML 类别" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:38 +msgid "Select a Paper" +msgstr "选择论文" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:42 +msgid "Type" +msgstr "类型" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:43 +msgid "Year" +msgstr "年" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:44 +msgid "Month" +msgstr "月" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:47 +msgid "Publication" +msgstr "刊物" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:49 +msgid "DOI" +msgstr "数字对象识别号" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:57 +msgid "Add a new paper." +msgstr "建新论文。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:63 +msgid "Search for a paper:" +msgstr "搜索论文:" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:80 +msgid "Your query found [*,_1,paper]." +msgstr "共 [#,_1] 篇相符的论文。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:83 +msgid "[*,_1,paper]." +msgstr "共 [#,_1] 篇论文。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:89 +msgid "Your query found [*,_1,paper], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的论文,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:93 +msgid "[*,_1,paper], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇论文,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:38 +msgid "Select a Researcher" +msgstr "选择研究者" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:39 +msgid "Manage Researchers" +msgstr "管理研究者" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:42 +msgid "Abbreviation" +msgstr "缩写" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:50 +msgid "Add a new researcher." +msgstr "建新研究者。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:56 +msgid "Search for a researcher:" +msgstr "搜索研究者:" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:73 +msgid "Your query found [*,_1,researcher]." +msgstr "共 [#,_1] 位相符的研究者。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:76 +msgid "[*,_1,researcher]." +msgstr "共 [#,_1] 位研究者。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:82 +msgid "Your query found [*,_1,researcher], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位相符的研究者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:86 +msgid "[*,_1,researcher], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位研究者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:45 +msgid "Full Text Search" +msgstr "全文检索" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:46 +msgid "" +"

    Tavern IMACAT's

    \n" +"

    Full Text Search

    " +msgstr "" +"

    旅舍依玛

    \n" +"

    全文检索

    " + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:48 +msgid "Search Result" +msgstr "搜索结果" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:49 +msgid "" +"

    Tavern IMACAT's

    \n" +"

    Search Result

    " +msgstr "" +"

    旅舍依玛

    \n" +"

    搜索结果

    " + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:72 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:100 +msgid "Please fill in your query." +msgstr "请填上检索的辞汇。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:160 +msgid "Search in the website:" +msgstr "网站检索:" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:177 +msgid "Your query found [*,_1,article]." +msgstr "共 [#,_1] 篇相符的文章。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:180 +msgid "[*,_1,article]." +msgstr "共 [#,_1] 篇文章。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:186 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:190 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:224 +msgid "Tavern Diary on [_1]" +msgstr "[_1] 旅舍日记" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:233 +msgid "Change Log on [_1]" +msgstr "[_1] 更新日志" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:271 +msgid "English writings" +msgstr "英文写作" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:281 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:290 +msgid "Guestbook Message on [_1]" +msgstr "[_1] 留言" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:38 +msgid "Select a Tag" +msgstr "选择标签" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:39 +msgid "Manage Tags" +msgstr "管理标签" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:49 +msgid "Add a new tag." +msgstr "加新标签。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:55 +msgid "Search for a tag:" +msgstr "搜索标签:" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:72 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:74 +msgid "Your query found [*,_1,tag]." +msgstr "共 [#,_1] 个相符的标签。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:75 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:77 +msgid "[*,_1,tag]." +msgstr "共 [#,_1] 个标签。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:81 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:83 +msgid "Your query found [*,_1,tag], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个相符的标签,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:85 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:87 +msgid "[*,_1,tag], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个标签,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:110 +msgid "This log entry was not modified." +msgstr "日志未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:114 +msgid "This log entry has been successfully added." +msgstr "日志写好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:118 +msgid "This log entry has been successfully updated." +msgstr "日志存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:122 +msgid "This log entry has been successfully deleted." +msgstr "日志删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:109 +msgid "This diary entry was not modified." +msgstr "日记未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:113 +msgid "This diary entry has been successfully added." +msgstr "日记写好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:117 +msgid "This diary entry has been successfully updated." +msgstr "日记存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:121 +msgid "This diary entry has been successfully deleted." +msgstr "日记删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:104 +msgid "This English literal work was not modified." +msgstr "英文写作未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:108 +msgid "This English literal work has been successfully added." +msgstr "英文写作写好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:112 +msgid "This English literal work has been successfully updated." +msgstr "英文写作存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:116 +msgid "This English literal work has been successfully deleted." +msgstr "英文写作删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:188 +msgid "This Chinese literal work was not modified." +msgstr "中文写作未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:192 +msgid "This Chinese literal work has been successfully added." +msgstr "中文写作写好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:196 +msgid "This Chinese literal work has been successfully updated." +msgstr "中文写作存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:200 +msgid "This Chinese literal work has been successfully deleted." +msgstr "中文写作删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:102 +msgid "This Chinese poem was not modified." +msgstr "中文诗未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:106 +msgid "This Chinese poem has been successfully added." +msgstr "中文诗写好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:110 +msgid "This Chinese poem has been successfully updated." +msgstr "中文诗存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:114 +msgid "This Chinese poem has been successfully deleted." +msgstr "中文诗删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:293 +msgid "This paper was not modified." +msgstr "论文未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:297 +msgid "This paper has been successfully added." +msgstr "论文建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:301 +msgid "This paper has been successfully updated." +msgstr "论文存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:305 +msgid "This paper has been successfully deleted." +msgstr "论文删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:90 +msgid "This researcher was not modified." +msgstr "研究者未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:94 +msgid "This researcher has been successfully added." +msgstr "研究者建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:98 +msgid "This researcher has been successfully updated." +msgstr "研究者存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:102 +msgid "This researcher has been successfully deleted." +msgstr "研究者删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:88 +msgid "This tag was not modified." +msgstr "标签未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:92 +msgid "This tag has been successfully added." +msgstr "标签建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:96 +msgid "This tag has been successfully updated." +msgstr "标签存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:100 +msgid "This tag has been successfully deleted." +msgstr "标签删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook/Public.pm:44 +msgid "Your specie is too long. (Max. length [#,_1])" +msgstr "妳的物种太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook/Public.pm:63 +msgid "Your e-mail is too long. (Max. length [#,_1])" +msgstr "妳的电子邮件信箱太长了。(最长 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:73 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:73 +msgid "Please select a paper." +msgstr "请选择论文。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:94 +msgid "Please select a author." +msgstr "请选择作者。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:97 +msgid "This author does not exist anymore. Please select another one." +msgstr "查无此作者,请改选其她作者。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:118 +msgid "This paper author already exists. You cannot create a duplicated one." +msgstr "已有同一笔论文作者,请勿重复建档。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:94 +msgid "Please select a tag." +msgstr "请选择标签。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:97 +msgid "This tag does not exist anymore. Please select another one." +msgstr "查无此标签,请改选其她标签。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:118 +msgid "This paper tag already exists. You cannot create a duplicated one." +msgstr "已有同一笔论文标签,请勿重复建档。" + +#: magicat/lib/perl5/Selima/imacat/Form/Garbage/Public.pm:48 +msgid "I'm sick." +msgstr "我要吐了" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:42 +msgid "" +"General commercial advertisements are not welcomed and may be deleted at " +"once. HTML is not supported." +msgstr "旅人留言簿不欢迎一般商业广告,随见随删。不支持 HTML 留言。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:49 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:49 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:47 +msgid "Delete this type" +msgstr "删掉这个类型" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:54 +msgid "This table provides you a form to add a new paper author." +msgstr "本表提供建新论文作者的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:57 +msgid "This table provides you a form to change a current paper author." +msgstr "本表提供编变更论文作者的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:60 +msgid "This table provides you a form to delete a paper author." +msgstr "本表提供删除论文作者的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:77 +msgid "Add a New Paper Author" +msgstr "建新论文作者" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:80 +msgid "Change a Current Paper Author" +msgstr "变更论文作者" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:83 +msgid "Delete a Paper Author" +msgstr "删除论文作者" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:93 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:93 +msgid "Paper:" +msgstr "论文:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:98 +msgid "Author:" +msgstr "作者:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:54 +msgid "This table provides you a form to add a new paper tag." +msgstr "本表提供建新论文标签的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:57 +msgid "This table provides you a form to change a current paper tag." +msgstr "本表提供编变更论文标签的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:60 +msgid "This table provides you a form to delete a paper tag." +msgstr "本表提供删除论文标签的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:77 +msgid "Add a New Paper Tag" +msgstr "建新论文标签" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:80 +msgid "Change a Current Paper Tag" +msgstr "变更论文标签" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:83 +msgid "Delete a Paper Tag" +msgstr "删除论文标签" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:98 +msgid "Tag:" +msgstr "标签:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:52 +msgid "This table provides you a form to add a new paper type." +msgstr "本表提供建新论文类型的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:55 +msgid "This table provides you a form to edit a current paper type." +msgstr "本表提供编辑论文类型的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:58 +msgid "This table provides you a form to delete a paper type." +msgstr "本表提供删除论文类型的表单。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:75 +msgid "Add a New Paper Type" +msgstr "建新论文类型" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:78 +msgid "Edit a Current Paper Type" +msgstr "编辑论文类型" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:81 +msgid "Delete a Paper Type" +msgstr "删除论文类型" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog/Public.pm:136 +msgid "Date:" +msgstr "日期:" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog/Public.pm:146 +msgid "The change log entry seperator" +msgstr "更新日志分隔线" + +#: magicat/lib/perl5/Selima/imacat/List/Diary/Public.pm:146 +msgid "The diary entry seperator" +msgstr "日记分隔线" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage/Public.pm:68 +msgid "The message entry seperator" +msgstr "留言分隔线" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:38 +msgid "Select a Paper Author" +msgstr "选择论文作者" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:39 +msgid "Manage Paper Authors" +msgstr "管理论文作者" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:42 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:42 +msgid "Paper" +msgstr "论文" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:43 +msgid "Author" +msgstr "作者" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:51 +msgid "Add a new paper author." +msgstr "建新论文作者。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:57 +msgid "Search for a paper author:" +msgstr "搜索论文作者:" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:74 +msgid "Your query found [*,_1,author]." +msgstr "共 [#,_1] 位相符的论文作者。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:77 +msgid "[*,_1,author]." +msgstr "共 [#,_1] 位论文作者。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:83 +msgid "Your query found [*,_1,author], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位相符的论文作者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:87 +msgid "[*,_1,author], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位论文作者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:38 +msgid "Select a Paper Tag" +msgstr "选择论文标签" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:39 +msgid "Manage Paper Tags" +msgstr "管理论文标签" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:43 +msgid "Tag" +msgstr "标签" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:51 +msgid "Add a new paper tag." +msgstr "加新论文标签。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:57 +msgid "Search for a paper tag:" +msgstr "搜索论文标签:" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:38 +msgid "Select a Paper Type" +msgstr "选择论文类型" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:39 +msgid "Manage Paper Types" +msgstr "管理论文类型" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:49 +msgid "Add a new paper type." +msgstr "建新论文类型。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:55 +msgid "Search for a paper type:" +msgstr "搜索论文类型:" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:72 +msgid "Your query found [*,_1,type]." +msgstr "共 [#,_1] 类相符的类型。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:75 +msgid "[*,_1,type]." +msgstr "共 [#,_1] 类类型。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:81 +msgid "Your query found [*,_1,type], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 类相符的类型,列出第 [#,_2] 类到第 [#,_3] 类。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:85 +msgid "[*,_1,type], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 类类型,列出第 [#,_2] 类到第 [#,_3] 类。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:97 +msgid "This paper author was not modified." +msgstr "论文作者未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:101 +msgid "This paper author has been successfully added." +msgstr "论文作者建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:105 +msgid "This paper author has been successfully updated." +msgstr "论文作者存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:109 +msgid "This paper author has been successfully deleted." +msgstr "论文作者删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:97 +msgid "This paper tag was not modified." +msgstr "论文标签未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:101 +msgid "This paper tag has been successfully added." +msgstr "论文标签建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:105 +msgid "This paper tag has been successfully updated." +msgstr "论文标签存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:109 +msgid "This paper tag has been successfully deleted." +msgstr "论文标签删掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:94 +msgid "This paper type was not modified." +msgstr "论文类型未异动。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:98 +msgid "This paper type has been successfully added." +msgstr "论文类型建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:102 +msgid "This paper type has been successfully updated." +msgstr "论文类型存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:106 +msgid "This paper type has been successfully deleted." +msgstr "论文类型删掉了。" + +#~ msgid "Manage Accounting" +#~ msgstr "管理会计" + +#~ msgid "Reports" +#~ msgstr "报表" + +#~ msgid "Transactions" +#~ msgstr "传票" + +#~ msgid "Subjects" +#~ msgstr "科目" + +#~ msgid "Records" +#~ msgstr "分录" + +#~ msgid "Please fill in the publication." +#~ msgstr "请填上刊物。" + +#~ msgid "This URL is not reachable. Check if there is any typo in it." +#~ msgstr "这个网址连不上,请检查有没有拼错。" diff --git a/htdocs/imacat/magicat/po/zh_TW.gmo b/htdocs/imacat/magicat/po/zh_TW.gmo new file mode 100644 index 0000000..cffcd7f Binary files /dev/null and b/htdocs/imacat/magicat/po/zh_TW.gmo differ diff --git a/htdocs/imacat/magicat/po/zh_TW.po b/htdocs/imacat/magicat/po/zh_TW.po new file mode 100644 index 0000000..c0ad1e9 --- /dev/null +++ b/htdocs/imacat/magicat/po/zh_TW.po @@ -0,0 +1,2572 @@ +# Traditional Chinese PO file for the Tavern IMACAT's website +# Copyright (C) 2003-2018 imacat +# This file is distributed under the same license as the imacat package. +# imacat , 2003-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: imacat 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-03-24 07:09+0800\n" +"PO-Revision-Date: 2018-11-02 00:56+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: cgi-bin/1-guestbook.cgi:40 cgi-bin/1-guestbook.cgi:111 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:282 +msgid "Travellers' Guestbook" +msgstr "旅人留言簿" + +#: cgi-bin/1-guestbook.cgi:112 +msgid "" +"

    Tavern IMACAT’s

    \n" +"

    Travellers’
    Guestbook

    " +msgstr "" +"

    旅舍的

    \n" +"

    旅人留言簿

    " + +#: cgi-bin/1-guestbook.cgi:129 +msgid "Good morning to thee, gentle friend and traveller!" +msgstr "早安。溫和的友人及旅行者。" + +#: cgi-bin/1-guestbook.cgi:130 +msgid "" +"I call thee \"traveller\" no matter if thou hast never left thy home town, " +"no matter if thou wilst never again leave thy room, because all of us are " +"travellers. I call thee traveller for truly all of us travel a spiritual or " +"philosophical path -- even if it is simply by living the life that we choose " +"to live, or by searching for a new life when our current one fails to " +"satisfy our needs as thinking spiritual beings." +msgstr "" +"即使妳不曾離開過妳的故鄉,也不曾離開妳的房間,我都稱呼妳為旅行者,因為我們全" +"都是旅行者。我們在精神或哲學的道路上──即使它只是簡單地活在我們選擇的生活方式" +"上,或當現在的生活並不能滿足精神上的需要時,而尋找另一種新的生活方式。" + +#: cgi-bin/1-guestbook.cgi:133 +msgid "-- The Book of Fellowship, Ultima VII" +msgstr "──友誼會手冊‧創世紀Ⅶ" + +#: cgi-bin/garbage.cgi:40 +msgid "garbage, daub, poetry, message, essay" +msgstr "心情垃圾, 塗鴉, 詩, 留言, 短文" + +#: cgi-bin/garbage.cgi:110 magicat/lib/perl5/Selima/imacat/List/Search.pm:291 +msgid "Soundless Backalley" +msgstr "無聲的後巷" + +#: cgi-bin/garbage.cgi:111 +msgid "" +"

    The

    \n" +"

    Soundless
    Backalley

    " +msgstr "" +"

    旅舍的

    \n" +"

    無聲的後巷

    " + +#: cgi-bin/garbage.cgi:128 +msgid "" +"This is the backalley of Tavern. Every morning barmaid Cotton will put " +"garbages here. Besides that, there's never anyone passing by. Just " +"stinking garbages, drunks unable to tell dead or alive, cats and dogs and " +"flies, piss and vomits. The wall is filled with drawings and words unable " +"to tell whether they are poetry or shits. The vague music and laughters " +"come so faraway from inside the Tavern, like a neverending rhythm repeats " +"itself. The sun is blocked by the buildings. Even the time stops." +msgstr "" +"旅舍的後巷,除了每天清晨,女侍‧絮把垃圾拿出來倒以外,沒有人會經過的地方。堆滿" +"了腐臭的垃圾、分不清是死是活的醉漢、貓狗、蒼蠅、排洩物、嘔吐物。牆上畫滿不知" +"道是詩還是髒話的句子和塗鴉。遠處隱約傳來旅舍吧抬的音樂和嘈雜聲,像永恆的節奏" +"一樣在遠處反覆吟唱著。陽光被旅舍擋住,連時間也不動了。" + +#: cgi-bin/garbage.cgi:129 +msgid "" +"There's no one here, just you and yourself. Soundless is the loudest " +"sound. No matter how hard if you cry, shout or scream, you're still alone. " +"This is the darkest and the loneliest corner in the Tavern." +msgstr "" +"這裏沒有別人,只有妳和妳自己。無聲是最吵雜的聲音。妳撕破喉嚨哭泣,也沒人聽得" +"見。這是旅舍最陰暗的地方,也是旅舍最孤寂的角落。" + +#: cgi-bin/plurkavatar.cgi:41 cgi-bin/plurkfav.cgi:43 +msgid "Plurk" +msgstr "噗浪" + +#: cgi-bin/plurkavatar.cgi:65 +msgid "There is no Plurk user \"[_1]\"." +msgstr "查無噗浪使用者 [_1] 。" + +#: cgi-bin/plurkavatar.cgi:68 +msgid "Avator is not found for user \"[_1]\"." +msgstr "查無噗浪使用者 [_1] 的頭像。" + +#: cgi-bin/plurkavatar.cgi:72 +msgid "Plurk service is not available now." +msgstr "噗浪目前無法使用。" + +#: cgi-bin/plurkavatar.cgi:75 +msgid "Please fill in the Plurk user." +msgstr "請填上噗浪使用者。" + +#: cgi-bin/plurkavatar.cgi:89 +msgid "Plurk Avatars" +msgstr "噗浪頭像" + +#: cgi-bin/plurkavatar.cgi:96 +msgid "Plurk Avatars for User [_1]" +msgstr "[_1] 的噗浪頭像" + +#: cgi-bin/plurkavatar.cgi:121 +msgid "Plurk user:" +msgstr "噗浪使用者:" + +#: cgi-bin/plurkfav.cgi:52 +msgid "Plurk Favorites" +msgstr "噗浪喜歡" + +#: cgi-bin/plurkfav.cgi:86 +msgid "Plurk permanent link URL:" +msgstr "噗浪連結:" + +#: cgi-bin/plurkfav.cgi:105 +msgid "Plurk ID: [_1]" +msgstr "噗浪編號: [_1]" + +#: cgi-bin/plurkfav.cgi:106 +msgid "Set Plurk favorite" +msgstr "設定噗浪喜歡" + +#: cgi-bin/plurkfav.cgi:107 +msgid "Unset Plurk favorite" +msgstr "取消噗浪喜歡" + +#: cgi-bin/search.cgi:43 +msgid "search, query, full text search" +msgstr "搜尋, 檢索, 全文檢索" + +#: magicat/cgi-bin/acctrecs.cgi:44 magicat/cgi-bin/acctreps.cgi:39 +#: magicat/cgi-bin/acctsubj.cgi:42 magicat/cgi-bin/accttrx.cgi:43 +msgid "accounting" +msgstr "會計" + +#: magicat/cgi-bin/acctrecs.cgi:110 magicat/cgi-bin/acctrecs.cgi:157 +#: magicat/cgi-bin/acctsubj.cgi:120 magicat/cgi-bin/acctsubj.cgi:180 +#: magicat/cgi-bin/accttrx.cgi:110 magicat/cgi-bin/accttrx.cgi:157 +#: magicat/cgi-bin/changelog.cgi:110 magicat/cgi-bin/changelog.cgi:159 +#: magicat/cgi-bin/diary.cgi:110 magicat/cgi-bin/diary.cgi:159 +#: magicat/cgi-bin/garbage.cgi:104 magicat/cgi-bin/garbage.cgi:148 +#: magicat/cgi-bin/groupmem.cgi:108 magicat/cgi-bin/groupmem.cgi:153 +#: magicat/cgi-bin/groups.cgi:121 magicat/cgi-bin/groups.cgi:176 +#: magicat/cgi-bin/guestbook.cgi:104 magicat/cgi-bin/guestbook.cgi:150 +#: magicat/cgi-bin/linkcat.cgi:119 magicat/cgi-bin/linkcat.cgi:177 +#: magicat/cgi-bin/linkcatz.cgi:108 magicat/cgi-bin/linkcatz.cgi:153 +#: magicat/cgi-bin/links.cgi:110 magicat/cgi-bin/links.cgi:161 +#: magicat/cgi-bin/literalen.cgi:161 magicat/cgi-bin/literalen.cgi:205 +#: magicat/cgi-bin/literalzh.cgi:175 magicat/cgi-bin/literalzh.cgi:219 +#: magicat/cgi-bin/ltzhpoem.cgi:106 magicat/cgi-bin/ltzhpoem.cgi:151 +#: magicat/cgi-bin/pages.cgi:114 magicat/cgi-bin/pages.cgi:163 +#: magicat/cgi-bin/papers.cgi:108 magicat/cgi-bin/papers.cgi:154 +#: magicat/cgi-bin/pprauthr.cgi:105 magicat/cgi-bin/pprauthr.cgi:150 +#: magicat/cgi-bin/pprtags.cgi:105 magicat/cgi-bin/pprtags.cgi:150 +#: magicat/cgi-bin/pprtypes.cgi:112 magicat/cgi-bin/pprtypes.cgi:165 +#: magicat/cgi-bin/resrcher.cgi:109 magicat/cgi-bin/resrcher.cgi:157 +#: magicat/cgi-bin/scptpriv.cgi:106 magicat/cgi-bin/scptpriv.cgi:151 +#: magicat/cgi-bin/tags.cgi:109 magicat/cgi-bin/tags.cgi:157 +#: magicat/cgi-bin/usermem.cgi:108 magicat/cgi-bin/usermem.cgi:153 +#: magicat/cgi-bin/userpref.cgi:106 magicat/cgi-bin/userpref.cgi:151 +#: magicat/cgi-bin/users.cgi:125 magicat/cgi-bin/users.cgi:189 +msgid "Incorrect form: [_1]." +msgstr "查無此表格: [_1] 。" + +#: magicat/cgi-bin/acctrecs.cgi:204 +msgid "Please select the accounting record." +msgstr "請選擇會計分錄。" + +#: magicat/cgi-bin/acctrecs.cgi:212 +msgid "" +"This accounting record does not exist anymore. Please select another one." +msgstr "查無此會計分錄,請重新選擇。" + +#: magicat/cgi-bin/acctsubj.cgi:93 magicat/cgi-bin/acctsubj.cgi:140 +msgid "Please add a new accounting subject from [_1]." +msgstr "請由[_1]建新會計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:109 magicat/cgi-bin/acctsubj.cgi:169 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the subject, " +"[numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] " +"must first be deleted." +msgstr "" +"本會計科目下有子會計科目,不可直接刪除。要刪除本會計科目,請先刪除其下的子會" +"計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:113 magicat/cgi-bin/acctsubj.cgi:173 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the subject, [numerate,_1,its " +"accounting record,all of its accounting records] must first be deleted." +msgstr "" +"本會計科目下有會計分錄,不可直接刪除。要刪除本會計科目,請先刪除其下的會計分" +"錄。" + +#: magicat/cgi-bin/acctsubj.cgi:232 +msgid "Please select the accounting subject." +msgstr "請選擇會計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:240 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "查無此會計科目,請重新選擇。" + +#: magicat/cgi-bin/accttrx.cgi:204 +msgid "Please select the accounting transaction." +msgstr "請選擇會計傳票。" + +#: magicat/cgi-bin/accttrx.cgi:212 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "查無此會計傳票,請重新選擇。" + +#: magicat/cgi-bin/actlog.cgi:36 +msgid "activity, logs" +msgstr "活動, 記錄, 日誌" + +#: magicat/cgi-bin/changelog.cgi:42 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:472 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:539 +msgid "change log, history" +msgstr "更新日誌, 變遷史" + +#: magicat/cgi-bin/changelog.cgi:91 magicat/cgi-bin/changelog.cgi:128 +msgid "Please write a new log entry from [_1]." +msgstr "請由[_1]寫新日誌。" + +#: magicat/cgi-bin/changelog.cgi:206 +msgid "Please select the log entry." +msgstr "請選擇日誌。" + +#: magicat/cgi-bin/changelog.cgi:214 +msgid "This log entry does not exist anymore. Please select another one." +msgstr "查無該則日誌,請重新選擇。" + +#: magicat/cgi-bin/diary.cgi:42 magicat/lib/perl5/Selima/imacat/Rebuild.pm:327 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:394 +msgid "diary" +msgstr "日記" + +#: magicat/cgi-bin/diary.cgi:91 magicat/cgi-bin/diary.cgi:128 +msgid "Please write a new diary entry from [_1]." +msgstr "請由[_1]寫新日記。" + +#: magicat/cgi-bin/diary.cgi:206 +msgid "Please select the diary entry." +msgstr "請選擇日記。" + +#: magicat/cgi-bin/diary.cgi:214 +msgid "This diary entry does not exist anymore. Please select another one." +msgstr "查無該則日記,請重新選擇。" + +#: magicat/cgi-bin/funds.cgi:36 +msgid "mutual funds, performance, indicators" +msgstr "共同基金, 績效, 指標" + +#: magicat/cgi-bin/garbage.cgi:40 +msgid "backalley" +msgstr "後巷" + +#: magicat/cgi-bin/garbage.cgi:195 magicat/cgi-bin/guestbook.cgi:197 +msgid "Please select the message." +msgstr "請選擇要設定的留言。" + +#: magicat/cgi-bin/garbage.cgi:203 magicat/cgi-bin/guestbook.cgi:205 +msgid "This message does not exist anymore. Please select another one." +msgstr "查無該留言,請改選其她留言。" + +#: magicat/cgi-bin/groupmem.cgi:44 +msgid "group membership" +msgstr "群組成員" + +#: magicat/cgi-bin/groupmem.cgi:200 magicat/cgi-bin/usermem.cgi:200 +msgid "Please select the membership record." +msgstr "請選擇成員關係。" + +#: magicat/cgi-bin/groupmem.cgi:208 magicat/cgi-bin/usermem.cgi:208 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "查無此成員關係,請重新選擇。" + +#: magicat/cgi-bin/groups.cgi:48 +msgid "groups" +msgstr "群組" + +#: magicat/cgi-bin/groups.cgi:98 magicat/cgi-bin/groups.cgi:140 +msgid "Please create a new group from [_1]." +msgstr "請由[_1]建新群組。" + +#: magicat/cgi-bin/groups.cgi:224 +msgid "Please select the group." +msgstr "請選擇群組。" + +#: magicat/cgi-bin/groups.cgi:232 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: magicat/cgi-bin/guestbook.cgi:40 +msgid "guestbook" +msgstr "留言簿" + +#: magicat/cgi-bin/linkcat.cgi:43 +msgid "link categories" +msgstr "相關連結分類" + +#: magicat/cgi-bin/linkcat.cgi:92 magicat/cgi-bin/linkcat.cgi:137 +msgid "Please add a new category from [_1]." +msgstr "請由[_1]建新分類。" + +#: magicat/cgi-bin/linkcat.cgi:108 magicat/cgi-bin/linkcat.cgi:166 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: magicat/cgi-bin/linkcat.cgi:112 magicat/cgi-bin/linkcat.cgi:170 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: magicat/cgi-bin/linkcat.cgi:225 +msgid "Please select the category." +msgstr "請選擇分類。" + +#: magicat/cgi-bin/linkcat.cgi:233 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: magicat/cgi-bin/linkcatz.cgi:44 +msgid "link categorization" +msgstr "連結分類表" + +#: magicat/cgi-bin/linkcatz.cgi:200 +msgid "Please select the categorization record." +msgstr "請選擇分類資料。" + +#: magicat/cgi-bin/linkcatz.cgi:208 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "查無此分類資料,請重新選擇。" + +#: magicat/cgi-bin/links.cgi:42 magicat/lib/perl5/Selima/imacat/Rebuild.pm:254 +msgid "related links" +msgstr "相關連結" + +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:128 +msgid "Please add a new related link from [_1]." +msgstr "請由[_1]建新相關連結。" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Manage Keep Travelling" +msgstr "管理繼續旅行" + +#: magicat/cgi-bin/links.cgi:211 +msgid "Please select the related link." +msgstr "請選擇要設定的相關連結。" + +#: magicat/cgi-bin/links.cgi:219 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查無該相關連結,請改選其她相關連結。" + +#: magicat/cgi-bin/literalen.cgi:43 +msgid "English literal works" +msgstr "英文寫作" + +#: magicat/cgi-bin/literalen.cgi:259 +msgid "Please select the English literal work." +msgstr "請選擇要編輯的英文寫作。" + +#: magicat/cgi-bin/literalen.cgi:267 +msgid "" +"This English literal work does not exist anymore. Please select another one." +msgstr "查無此英文寫作,請重新選擇。" + +#: magicat/cgi-bin/literalzh.cgi:44 +msgid "Chinese literal works" +msgstr "中文寫作" + +#: magicat/cgi-bin/literalzh.cgi:273 +msgid "Please select the Chinese literal work." +msgstr "請選擇要編輯的中文寫作。" + +#: magicat/cgi-bin/literalzh.cgi:281 +msgid "" +"This Chinese literal work does not exist anymore. Please select another one." +msgstr "查無此中文寫作,請重新選擇。" + +#: magicat/cgi-bin/logout.cgi:39 +msgid "log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:112 magicat/cgi-bin/logout.cgi:119 +msgid "Log Out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:135 +msgid "Are you sure you want to log out?" +msgstr "妳確定要登出嗎?" + +#: magicat/cgi-bin/logout.cgi:136 magicat/lib/perl5/Selima/imacat/HTML.pm:577 +msgid "Log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:152 +msgid "Log in again." +msgstr "重新登入。" + +#: magicat/cgi-bin/ltzhpoem.cgi:42 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:253 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:262 +msgid "Chinese poems" +msgstr "中文詩" + +#: magicat/cgi-bin/ltzhpoem.cgi:199 +msgid "Please select the Chinese poem." +msgstr "請選擇中文詩。" + +#: magicat/cgi-bin/ltzhpoem.cgi:207 +msgid "This Chinese poem does not exist anymore. Please select another one." +msgstr "查無此中文詩,請重新選擇。" + +#: magicat/cgi-bin/pages.cgi:40 +msgid "pages" +msgstr "網頁" + +#: magicat/cgi-bin/pages.cgi:89 magicat/cgi-bin/pages.cgi:132 +msgid "Please add a new page from [_1]." +msgstr "請由[_1]寫新網頁。" + +#: magicat/cgi-bin/pages.cgi:216 +msgid "Please select the page." +msgstr "請選擇網頁。" + +#: magicat/cgi-bin/pages.cgi:224 +msgid "This page does not exist anymore. Please select another one." +msgstr "查無此頁,請改選其她網頁。" + +#: magicat/cgi-bin/papers.cgi:44 magicat/cgi-bin/pprauthr.cgi:41 +#: magicat/cgi-bin/pprtags.cgi:41 magicat/cgi-bin/pprtypes.cgi:40 +msgid "papers" +msgstr "論文" + +#: magicat/cgi-bin/papers.cgi:201 +msgid "Please select the paper." +msgstr "請選擇論文。" + +#: magicat/cgi-bin/papers.cgi:209 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:76 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:76 +msgid "This paper does not exist anymore. Please select another one." +msgstr "查無此論文,請改選其她論文。" + +#: magicat/cgi-bin/pprauthr.cgi:197 +msgid "Please select the paper author." +msgstr "請選擇論文作者。" + +#: magicat/cgi-bin/pprauthr.cgi:205 +msgid "This paper author does not exist anymore. Please select another one." +msgstr "查無此論文作者,請改選其她論文作者。" + +#: magicat/cgi-bin/pprtags.cgi:197 +msgid "Please select the paper tag." +msgstr "請選擇論文標籤。" + +#: magicat/cgi-bin/pprtags.cgi:205 +msgid "This paper tag does not exist anymore. Please select another one." +msgstr "查無此論文標籤,請改選其她論文標籤。" + +#: magicat/cgi-bin/pprtypes.cgi:89 magicat/cgi-bin/pprtypes.cgi:130 +msgid "Please add a new paper type from [_1]." +msgstr "請由[_1]建新論文類型。" + +#: magicat/cgi-bin/pprtypes.cgi:105 magicat/cgi-bin/pprtypes.cgi:158 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:89 +msgid "" +"This paper type has [numerate,_1,a paper,papers]. It cannot be deleted. To " +"delete the type, [numerate,_1,its paper,all of its papers] must first be " +"deleted." +msgstr "本論文類型下有論文,不可直接刪除。要刪除本類型,請先刪除其下的論文。" + +#: magicat/cgi-bin/pprtypes.cgi:212 +msgid "Please select the paper type." +msgstr "請選擇論文類型。" + +#: magicat/cgi-bin/pprtypes.cgi:220 +msgid "This paper type does not exist anymore. Please select another one." +msgstr "查無此論文類型,請改選其她類型。" + +#: magicat/cgi-bin/rebuild.cgi:37 +msgid "rebuild pages" +msgstr "重製網頁" + +#: magicat/cgi-bin/resrcher.cgi:41 +msgid "researchers" +msgstr "研究者" + +#: magicat/cgi-bin/resrcher.cgi:102 magicat/cgi-bin/resrcher.cgi:150 +#: magicat/cgi-bin/tags.cgi:102 magicat/cgi-bin/tags.cgi:150 +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:88 +msgid "" +"This researcher has [numerate,_1,a paper,papers]. It cannot be deleted. To " +"delete the researcher, [numerate,_1,its paper,all of its papers] must first " +"be deleted." +msgstr "本研究者下有論文,不可直接刪除。要刪除本研究者,請先刪除其下的論文。" + +#: magicat/cgi-bin/resrcher.cgi:204 magicat/cgi-bin/tags.cgi:204 +msgid "Please select the researcher." +msgstr "請選擇研究者。" + +#: magicat/cgi-bin/resrcher.cgi:212 magicat/cgi-bin/tags.cgi:212 +msgid "This researcher does not exist anymore. Please select another one." +msgstr "查無此研究者,請重新選擇。" + +#: magicat/cgi-bin/saveform.cgi:46 +msgid "saved forms" +msgstr "暫存表單" + +#: magicat/cgi-bin/saveform.cgi:77 +msgid "Form [_1] does not exist anymore. Please select another one." +msgstr "查無表單 [_1] ,請改選其她表單。" + +#: magicat/cgi-bin/saveform.cgi:92 +msgid "Manage the Saved Forms" +msgstr "管理暫存表單" + +#: magicat/cgi-bin/saveform.cgi:134 +msgid "Select" +msgstr "選" + +#: magicat/cgi-bin/scptpriv.cgi:42 +msgid "script privilege" +msgstr "程式權限" + +#: magicat/cgi-bin/scptpriv.cgi:198 +msgid "Please select the script privilege record." +msgstr "請選擇程式權限。" + +#: magicat/cgi-bin/scptpriv.cgi:206 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "查無該程式權限,請重新選擇。" + +#: magicat/cgi-bin/tags.cgi:41 +msgid "tags" +msgstr "標籤" + +#: magicat/cgi-bin/usermem.cgi:44 +msgid "user membership" +msgstr "使用者成員" + +#: magicat/cgi-bin/userpref.cgi:42 +msgid "user preference" +msgstr "使用者偏好" + +#: magicat/cgi-bin/userpref.cgi:198 +msgid "Please select the user preference." +msgstr "請選擇使用者偏好。" + +#: magicat/cgi-bin/userpref.cgi:206 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "查無該使用者偏好,請重新選擇。" + +#: magicat/cgi-bin/users.cgi:43 +msgid "users" +msgstr "帳號" + +#: magicat/cgi-bin/users.cgi:237 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: magicat/cgi-bin/users.cgi:245 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:52 +msgid "imacat" +msgstr "依瑪貓" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:53 +msgid "© imacat. All rights reserved." +msgstr "© 依瑪貓。依瑪貓保有所有權利。" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:63 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1016 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:409 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:410 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:225 +msgid "Tavern Diary" +msgstr "旅舍日記" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:64 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:98 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:234 +msgid "Change Log" +msgstr "更新日誌" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:65 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:108 +msgid "Chinese Literal Works" +msgstr "中文寫作" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:66 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:112 +msgid "English Literal Works" +msgstr "英文寫作" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:90 +msgid "Manage Content" +msgstr "管理網站" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:92 +msgid "Guestbook" +msgstr "留言簿" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:94 +msgid "Backalley" +msgstr "後巷" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:96 +msgid "Diary" +msgstr "日記" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:100 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:48 +msgid "Pages" +msgstr "網頁" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:102 +msgid "Links" +msgstr "連結" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:104 +msgid "Link Categories" +msgstr "連結分類" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:106 +msgid "Link Categorization" +msgstr "連結分類表" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:110 +msgid "Chinese Poems" +msgstr "中文詩" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:116 +msgid "Manage Accounts" +msgstr "管理帳號" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:118 +msgid "Users" +msgstr "帳號" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:120 +msgid "Groups" +msgstr "群組" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:122 +msgid "User Membership" +msgstr "使用者成員" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:124 +msgid "Group Membership" +msgstr "群組成員" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:126 +msgid "User Preferences" +msgstr "使用者偏好" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:128 +msgid "Script Privileges" +msgstr "程式權限" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:148 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:39 +msgid "Manage Papers" +msgstr "管理論文" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:150 +msgid "Papers" +msgstr "論文" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:152 +msgid "Researchers" +msgstr "研究者" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:154 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:46 +msgid "Tags" +msgstr "標籤" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:156 +msgid "Types" +msgstr "類型" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:158 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:45 +msgid "Authors" +msgstr "作者" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:160 +msgid "Paper Tags" +msgstr "論文標籤" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:164 +msgid "Miscellaneous" +msgstr "雜項" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:166 +msgid "Accounting" +msgstr "會計" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:168 +msgid "Funds" +msgstr "基金" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:170 +msgid "Activity Log" +msgstr "活動日誌" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:172 +msgid "Rebuild Pages" +msgstr "重製網頁" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:174 +msgid "Analog" +msgstr "訪客統計" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:176 +msgid "Test Script" +msgstr "測試程式" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:178 +msgid "MRTG" +msgstr "流量統計" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:180 +msgid "Saved Forms" +msgstr "暫存表單" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:182 +msgid "CGI Environment" +msgstr "CGI 環境" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:186 +msgid "Server Status" +msgstr "伺服器狀態" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:189 +msgid "Server Information" +msgstr "伺服器資訊" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:192 +msgid "Bwshare Information" +msgstr "節頻資訊" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:195 +msgid "Bwshare Trace" +msgstr "節頻記錄" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:198 +msgid "Perl Status" +msgstr "Perl 狀態" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:253 +msgid "Skip to the page content area." +msgstr "跳到網頁內文區。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:254 +msgid "Page Content Area" +msgstr "網頁內文區" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:372 +msgid "Magicat" +msgstr "梅姬" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:441 +msgid "Navigation Links Area" +msgstr "導覽連結區" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:521 +msgid "Language Switching Area" +msgstr "語言切換區" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:575 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "%s,妳好!(修改資料)" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:617 +#, c-format +msgid "%s:" +msgstr "%s:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:689 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:243 +msgid "Keep Travelling" +msgstr "繼續旅行" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:757 +msgid "E-mail" +msgstr "電子郵件信箱" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:782 +msgid "URL:" +msgstr "網址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:785 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:920 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:69 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:49 +msgid "E-mail:" +msgstr "電子郵件信箱:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:791 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:921 +msgid "Address:" +msgstr "地址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:793 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:922 +msgid "Tel.:" +msgstr "電話:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:795 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:923 +msgid "Fax.:" +msgstr "傳真:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:824 +msgid "" +"Are you ready to check out? Just drop your room key at the counter, and " +"travel for your next stop. Life is a never-ending trip, and Tavern is only " +"one of your many stops. Are you ready to go now?" +msgstr "" +"妳要退房了嗎?把妳的房門鑰匙交還給櫃臺,該向下一個停靠站出發了。這是一趟永無" +"止境的旅程,旅舍,只是妳的一個中途停靠站。若妳準備好了,就出發囉!" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:825 +msgid "" +"Greetings, traveller. I'm rinse the Tavern Tour Agent. Where is your next " +"stop?" +msgstr "妳好,旅行者。我是琳思。妳要往哪裡去旅行呢?" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:837 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:906 +msgid "~[Tavern~] Website Registration" +msgstr "~[旅舍回函~] 網站登錄" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:907 +msgid "" +"This table provide a form to register your site at Tavern \"Keep Travelling" +"\", the data column names and their input fields to fill in the information." +msgstr "" +"本表提供登錄旅舍「繼續旅行」的表單,網站資料欄位名稱,和填寫該資料的輸入格。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:908 +msgid "Fill in the description here." +msgstr "請填上簡介。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:909 +msgid "Regiser your site" +msgstr "登錄網站" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:910 +msgid "" +"I sincerely wish to build more hyperlinks with websites that're kind to " +"women/lesbian/queer. If you wish to link with me, or if you have any such " +"information, whether in Chinese or not, please tell me by filling this form " +"below. I'll put it in as soon as possible. Thank you." +msgstr "" +"我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳" +"有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:911 +msgid "" +"All fields in the form below, Except for the site name, the URL and the " +"description, are optional. Anything you fill here will be shown to " +"ANYONE who visits Tavern IMACAT's. Tavern does not collect " +"any personal informations. If you do not wish to distribute some private " +"informations, just leave them blank. If you represent some organization, " +"fill as detail as possible to help others finding you." +msgstr "" +"下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪" +"中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料" +"曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:912 +msgid "General commercial sites besides lesbian shops are not welcome." +msgstr "除女同志商店外,旅舍恕不受理一般商業網站。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:914 +msgid "Site name:" +msgstr "站名:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:915 +msgid "Site name, 2nd language (if any):" +msgstr "站名(第二語言,可略):" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:916 +msgid "Site URL:" +msgstr "網址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:917 +msgid "Link logo URL:" +msgstr "連結小圖網址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:918 +msgid "Category:" +msgstr "分類:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:919 +msgid "Introduction:" +msgstr "簡介:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:924 +msgid "OK!" +msgstr "好了!" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1010 +msgid "The diary is empty." +msgstr "現無任何日記。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1015 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1075 +msgid "imacat's Private Bed♥room" +msgstr "依瑪貓的閨♥房" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1025 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1085 +msgid "Index" +msgstr "目錄" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1042 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:326 +#, c-format +msgid "Tavern Diary Volume %s" +msgstr "旅舍日記 卷%s" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1070 +msgid "The change log is empty." +msgstr "現無任何日誌。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1076 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:554 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:555 +msgid "Tavern Change Log" +msgstr "旅舍更新日誌" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1102 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:471 +#, c-format +msgid "Tavern Change Log Volume %s" +msgstr "旅舍更新日誌 卷%s" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1482 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "mod_perl -- 速度,動力,無限可能" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1483 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" +"本程式以 Perl 撰寫,專為 mod_perl 設計強化" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1496 +msgid "" +"This script is written in Perl." +msgstr "" +"本程式以 Perl 撰寫" + +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:264 +msgid "Keep Travelling..." +msgstr "繼續旅行……" + +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:265 +msgid "Continue Your Journey..." +msgstr "繼續妳的旅程……" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:41 +msgid "This specie is too long. (Max. length [#,_1])" +msgstr "物種太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:60 +msgid "This e-mail is too long. (Max. length [#,_1])" +msgstr "電子郵件信箱太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:75 +msgid "Please choose the language." +msgstr "請選擇語言。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:80 +msgid "" +"Language [_1] is invalid. Please choose a proper language from the form." +msgstr "[_1] 語無效。請由表上選擇適當的語言。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:55 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:57 +msgid "Please fill in the date." +msgstr "請填上日期。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:58 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:61 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:63 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:60 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:63 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:65 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期請以 YYYY-MM-DD 格式填寫。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:73 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:75 +msgid "" +"The literal work on this date already exists. You cannot create a " +"duplicated one." +msgstr "已有這一天的寫作,請勿重複建檔。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:95 +msgid "This title is too long. (Max. length [#,_1])" +msgstr "標題太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:117 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:117 +msgid "Fill in the content here." +msgstr "請填上內文。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LtZhPoem.pm:58 +msgid "Please select a work set." +msgstr "請選擇寫作集。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LtZhPoem.pm:61 +msgid "This work set does not exist anymore. Please select another one." +msgstr "查無此寫作集,請重新選擇。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Page.pm:41 +msgid "This HTML class is too long. (Max. length [#,_1])" +msgstr "HTML 類別太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:62 +msgid "Please select in the type." +msgstr "請選擇類型。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:65 +msgid "This type does not exist anymore. Please select another one." +msgstr "查無此類型,請改選其她類型。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:83 +msgid "Please fill in the year of publication." +msgstr "請填上出版年。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:86 +msgid "This year of publication is too long. (Max. length [#,_1])" +msgstr "出版年太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:89 +msgid "This year of publication is too short. (Min. length [#,_1])" +msgstr "出版年太短了。(最短 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:93 +msgid "Please fill in a positive integer year of publication." +msgstr "出版年請填正整數。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:100 +msgid "Year ([#,_1]) out of range. Please specify between [#,_2] and [#,_3]." +msgstr "年([#,_1])超出範圍,請設在 [#,_2] 到 [#,_3] 之間。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:121 +msgid "This month is too long. (Max. length [#,_1])" +msgstr "月份標題太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:125 +msgid "Please fill in the month as ~[month~], ~[month day~] or ~[season~]." +msgstr "月份請以 ~[月份~] 、 ~[月份 日期~] 或 ~[季節~] 格式填寫。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:148 +msgid "Please fill in the author." +msgstr "請填上作者。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:313 +msgid "This publication is too long. (Max. length [#,_1])" +msgstr "刊物太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:334 +msgid "This pages is too long. (Max. length [#,_1])" +msgstr "頁數太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:338 +msgid "Please fill in the pages as ### or ###-###." +msgstr "頁數請填 ### 或 ###-### 格式。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:358 +msgid "This DOI is too long. (Max. length [#,_1])" +msgstr "數位物件識別號太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:369 +msgid "This paper already exists. You cannot create a duplicated one." +msgstr "已有同一篇論文,請勿重複建檔。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:387 +msgid "Please fill in the URL." +msgstr "請填上網址。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:390 +msgid "This URL is too long. (Max. length [#,_1])" +msgstr "網址太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:394 +msgid "Please fill in a valid URL." +msgstr "請填上正確的網址。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:51 +msgid "Please fill in the full name." +msgstr "請填上名字。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:54 +msgid "This full name is too long. (Max. length [#,_1])" +msgstr "名字太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:73 +msgid "Please fill in the abbreviation." +msgstr "請填上縮寫。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:76 +msgid "This abbreviation is too long. (Max. length [#,_1])" +msgstr "縮寫太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Tag.pm:59 +msgid "This tag already exists. You cannot create a duplicated one." +msgstr "已有同一個論文標籤,請勿重複建檔。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:46 +msgid "Delete this log entry" +msgstr "刪掉這則日誌" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:51 +msgid "This table provides you a form to write a new log entry." +msgstr "本表提供寫新日誌的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:54 +msgid "This table provides you a form to edit a current log entry." +msgstr "本表提供編輯日誌的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:57 +msgid "This table provides you a form to delete a log entry." +msgstr "本表提供刪除日誌的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:74 +msgid "Write a New Change Log Entry" +msgstr "寫新更新日誌" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:77 +msgid "Edit a Current Change Log Entry" +msgstr "編輯更新日誌" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:80 +msgid "Delete a Change Log Entry" +msgstr "刪除更新日誌" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:89 +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:89 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:95 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:116 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:298 +msgid "Hide?" +msgstr "隱藏?" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:90 +msgid "Hide this log entry" +msgstr "隱藏這則日誌" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:90 +msgid "Show this log entry" +msgstr "秀出這則日誌" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:91 +msgid "Hide this log entry currently." +msgstr "暫勿秀出這則日誌。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:96 +msgid "Page No.:" +msgstr "頁數:" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:46 +msgid "Delete this diary entry" +msgstr "刪掉這則日記" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:51 +msgid "This table provides you a form to write a new diary entry." +msgstr "本表提供寫新日記的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:54 +msgid "This table provides you a form to edit a current diary entry." +msgstr "本表提供編輯日記的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:57 +msgid "This table provides you a form to delete a diary entry." +msgstr "本表提供刪除日記的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:74 +msgid "Write a New Diary Entry" +msgstr "寫新日記" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:77 +msgid "Edit a Current Diary Entry" +msgstr "編輯日記" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:80 +msgid "Delete a Diary Entry" +msgstr "刪除日記" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:90 +msgid "Hide this diary entry" +msgstr "隱藏這則日記" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:90 +msgid "Show this diary entry" +msgstr "秀出這則日記" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:91 +msgid "Hide this diary entry currently." +msgstr "暫勿秀出這則日記。" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:74 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:54 +msgid "Specie:" +msgstr "物種:" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:90 +msgid "Language tag:" +msgstr "語言標籤:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:46 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:50 +msgid "Delete this literal work" +msgstr "刪掉這篇寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:51 +msgid "This table provides you a form to write a new English literal work." +msgstr "本表提供寫新英文寫作的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:54 +msgid "This table provides you a form to edit a current English literal work." +msgstr "本表提供編輯英文寫作的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:57 +msgid "This table provides you a form to delete a English literal work." +msgstr "本表提供刪除英文寫作的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:74 +msgid "Write a New English Literal Work" +msgstr "寫新英文寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:77 +msgid "Edit a Current English Literal Work" +msgstr "編輯英文寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:80 +msgid "Delete a English Literal Work" +msgstr "刪除英文寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:87 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:93 +msgid "Preview this literal work." +msgstr "預覽這篇寫作。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:299 +msgid "Hide this literal work" +msgstr "隱藏這篇寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:299 +msgid "Show this literal work" +msgstr "秀出這篇寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:97 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:300 +msgid "Hide this literal work currently." +msgstr "暫勿秀出這篇寫作。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:55 +msgid "This table provides you a form to write a new Chinese literal work." +msgstr "本表提供寫新中文寫作的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:58 +msgid "This table provides you a form to edit a current Chinese literal work." +msgstr "本表提供編輯中文寫作的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:61 +msgid "This table provides you a form to delete a Chinese literal work." +msgstr "本表提供刪除中文寫作的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:80 +msgid "Write a New Chinese Literal Work" +msgstr "寫新中文寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:83 +msgid "Edit a Current Chinese Literal Work" +msgstr "編輯中文寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:86 +msgid "Delete a Chinese Literal Work" +msgstr "刪除中文寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:114 +msgid "Title:" +msgstr "標題:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:115 +msgid "Content:" +msgstr "內文:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:118 +msgid "Hide this poem currently." +msgstr "暫勿秀出這首詩。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:122 +msgid "Hide this poem" +msgstr "隱藏這首詩" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:123 +msgid "Show this poem" +msgstr "秀出這首詩" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:135 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:187 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:261 +msgid "[numerate,_1,Poem]:" +msgstr "詩:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:188 +msgid "Original:" +msgstr "原:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:189 +msgid "New:" +msgstr "新:" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:49 +msgid "Delete this poem" +msgstr "刪掉這首中文詩" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:54 +msgid "This table provides you a form to write a new Chinese poem." +msgstr "本表提供寫新中文詩的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:57 +msgid "This table provides you a form to edit a current Chinese poem." +msgstr "本表提供編輯中文詩的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:60 +msgid "This table provides you a form to delete a Chinese poem." +msgstr "本表提供刪除日中文詩的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:77 +msgid "Write a New Chinese Poem" +msgstr "寫新中文詩" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:80 +msgid "Edit a Current Chinese Poem" +msgstr "編輯中文詩" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:83 +msgid "Delete a Chinese Poem" +msgstr "刪除中文詩" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:93 +msgid "Work set:" +msgstr "寫作集:" + +#: magicat/lib/perl5/Selima/imacat/Form/Page.pm:61 +msgid "HTML class:" +msgstr "HTML 類別:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:50 +msgid "Delete this paper" +msgstr "刪掉這篇論文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:55 +msgid "This table provides you a form to add a new paper." +msgstr "本表提供建新論文的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:58 +msgid "This table provides you a form to edit a current paper." +msgstr "本表提供編輯論文的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:61 +msgid "This table provides you a form to delete a paper." +msgstr "本表提供刪除論文的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:80 +msgid "Add a New Paper" +msgstr "建新論文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:83 +msgid "Edit a Current Paper" +msgstr "編輯論文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:86 +msgid "Delete a Paper" +msgstr "刪除論文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:96 +msgid "Type:" +msgstr "類型:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:101 +msgid "Year of publication:" +msgstr "出版年:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:106 +msgid "Month of publication:" +msgstr "出版月:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:111 +msgid "Authors:" +msgstr "作者:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:117 +msgid "Tags:" +msgstr "標籤:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:123 +msgid "Publication:" +msgstr "刊物:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:128 +msgid "Pages:" +msgstr "頁數:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:133 +msgid "DOI.:" +msgstr "數位物件識別號:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:145 +msgid "APA citation:" +msgstr "APA 書目:" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:47 +msgid "Delete this researcher" +msgstr "刪掉這個研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:52 +msgid "This table provides you a form to add a new researcher." +msgstr "本表提供建新研究者的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:55 +msgid "This table provides you a form to update a current researcher." +msgstr "本表提供設定研究者的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:58 +msgid "This table provides you a form to delete a researcher." +msgstr "本表提供刪除研究者的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:75 +msgid "Add a New Researcher" +msgstr "建新研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:78 +msgid "Update a Current Researcher" +msgstr "編輯研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:81 +msgid "Delete a Researcher" +msgstr "刪除研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:96 +msgid "Full name:" +msgstr "名字:" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:101 +msgid "Abbreviation:" +msgstr "縮寫:" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:112 +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:103 +msgid "[numerate,_1,Paper]:" +msgstr "論文:" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:47 +msgid "Delete this tag" +msgstr "刪掉這個標籤" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:52 +msgid "This table provides you a form to add a new tag." +msgstr "本表提供加新標籤的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:55 +msgid "This table provides you a form to edit a current tag." +msgstr "本表提供編輯標籤的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:58 +msgid "This table provides you a form to delete a tag." +msgstr "本表提供刪除標籤的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:75 +msgid "Add a New Tag" +msgstr "加新標籤" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:78 +msgid "Edit a Current Tag" +msgstr "編輯標籤" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:81 +msgid "Delete a Tag" +msgstr "刪除標籤" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:38 +msgid "Select an Change Log Entry" +msgstr "選擇更新日誌" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:39 +msgid "Manage Change Log" +msgstr "管理更新日誌" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:50 +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:50 +msgid "Page No." +msgstr "頁數" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:58 +msgid "Write a new log entry." +msgstr "寫新日誌。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:64 +msgid "Search for a log entry:" +msgstr "搜尋日誌:" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:81 +msgid "Your query found [*,_1,log entry,log entries]." +msgstr "共 [#,_1] 則相符的日誌。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:84 +msgid "[*,_1,log entry,log entries]." +msgstr "共 [#,_1] 則日誌。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:90 +msgid "" +"Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則相符的日誌,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:94 +msgid "[*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則日誌,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:38 +msgid "Select a Diary Entry" +msgstr "選擇日記" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:39 +msgid "Manage Diary" +msgstr "管理日記" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:58 +msgid "Write a new diary entry." +msgstr "寫新日記。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:64 +msgid "Search for a diary entry:" +msgstr "搜尋日記:" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:81 +msgid "Your query found [*,_1,diary entry,diary entries]." +msgstr "共 [#,_1] 則相符的日記。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:84 +msgid "[*,_1,diary entry,diary entries]." +msgstr "共 [#,_1] 則日記。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:90 +msgid "" +"Your query found [*,_1,diary entry,diary entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則相符的日記,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:94 +msgid "[*,_1,diary entry,diary entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則日記,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:42 +msgid "Browse Mutual Fund Performances" +msgstr "瀏覽共同基金績效" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:52 +msgid "Name" +msgstr "名稱" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:53 +msgid "1m return" +msgstr "一個月報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:54 +msgid "1m ranking" +msgstr "一個月排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:55 +msgid "3m return" +msgstr "三個月報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:56 +msgid "3m ranking" +msgstr "三個月排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:57 +msgid "6m return" +msgstr "六個月報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:58 +msgid "6m ranking" +msgstr "六個月排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:59 +msgid "1y return" +msgstr "一年報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:60 +msgid "1y ranking" +msgstr "一年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:61 +msgid "2y return" +msgstr "兩年報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:62 +msgid "2y ranking" +msgstr "兩年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:63 +msgid "3y return" +msgstr "三年報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:64 +msgid "3y ranking" +msgstr "三年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:65 +msgid "5y return" +msgstr "五年報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:66 +msgid "5y ranking" +msgstr "五年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:67 +msgid "10y return" +msgstr "十年報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:68 +msgid "10y ranking" +msgstr "十年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:69 +msgid "This year return" +msgstr "今年報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:70 +msgid "This year ranking" +msgstr "今年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:71 +msgid "Total return" +msgstr "自成立日報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:72 +msgid "Begin from" +msgstr "基金成立日" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:73 +msgid "Best 3m return" +msgstr "最佳三個月報酬" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:74 +msgid "Worst 3m return" +msgstr "最差三個月報酬" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:75 +msgid "Standard deviation (12m)" +msgstr "標準差 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:76 +msgid "Standard deviation (24m)" +msgstr "標準差 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:77 +msgid "Beta (12m)" +msgstr "β (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:78 +msgid "Beta (24m)" +msgstr "β (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:79 +msgid "Sharpe (12m)" +msgstr "夏普指數 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:80 +msgid "Sharpe (24m)" +msgstr "夏普指數 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:81 +msgid "Jensen (12m)" +msgstr "詹森指數 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:82 +msgid "Jensen (24m)" +msgstr "詹森指數 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:83 +msgid "Treynor (12m)" +msgstr "崔納指數 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:84 +msgid "Treynor (24m)" +msgstr "崔納指數 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:85 +msgid "Information Ratio (major categories) (12m)" +msgstr "資訊比例(大分類) (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:86 +msgid "Information Ratio (major categories) (24m)" +msgstr "資訊比例(大分類) (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:87 +msgid "Information Ratio (minor categories) (12m)" +msgstr "資訊比例(細分類) (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:88 +msgid "Information Ratio (minor categories) (24m)" +msgstr "資訊比例(細分類) (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:89 +msgid "This month turnover" +msgstr "當月週轉率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:90 +msgid "12m turnover" +msgstr "累積週轉率 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:91 +msgid "Duration" +msgstr "存續期間" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:92 +msgid "Rating" +msgstr "信用評等" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:93 +msgid "Manager less than 1y?" +msgstr "經理未滿一年?" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:98 +msgid "4433 Principle" +msgstr "4433 法則" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:163 +msgid "Search for a fund:" +msgstr "搜尋基金:" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:173 +msgid "Search" +msgstr "搜尋" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:199 +msgid "Advanced filter:" +msgstr "進階篩選條件:" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:250 +msgid "Your query found [*,_1,fund]." +msgstr "共 [#,_1] 筆相符的基金。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:253 +msgid "[*,_1,fund]." +msgstr "[#,_1] 筆基金。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:259 +msgid "Your query found [*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的基金,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:263 +msgid "[*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆基金,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage.pm:38 +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:38 +msgid "Select a Message" +msgstr "選擇留言" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage.pm:39 +msgid "Manage Soundless Backalley" +msgstr "管理無聲的後巷" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:39 +msgid "Manage Travellers' Guestbook" +msgstr "管理旅人留言簿" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:42 +msgid "Specie" +msgstr "物種" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:43 +msgid "Language tag" +msgstr "語言標籤" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:38 +msgid "Select a English Literal Work" +msgstr "選擇英文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:39 +msgid "Manage English Literal Works" +msgstr "管理英文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:51 +msgid "Write a new English literal work." +msgstr "寫新英文寫作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:57 +msgid "Search for a English literal work:" +msgstr "搜尋英文寫作:" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:74 +msgid "Your query found [*,_1,English literal work]." +msgstr "共 [#,_1] 篇相符的英文寫作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:77 +msgid "[*,_1,English literal work]." +msgstr "共 [#,_1] 篇英文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:83 +msgid "Your query found [*,_1,English literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的英文寫作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:87 +msgid "[*,_1,English literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇英文寫作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:38 +msgid "Select a Chinese Literal Work" +msgstr "選擇中文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:39 +msgid "Manage Chinese Literal Works" +msgstr "管理中文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:51 +msgid "Write a new Chinese literal work." +msgstr "寫新中文寫作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:57 +msgid "Search for a Chinese literal work:" +msgstr "搜尋中文寫作:" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:74 +msgid "Your query found [*,_1,Chinese literal work]." +msgstr "共 [#,_1] 篇相符的中文寫作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:77 +msgid "[*,_1,Chinese literal work]." +msgstr "共 [#,_1] 篇中文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:83 +msgid "Your query found [*,_1,Chinese literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的中文寫作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:87 +msgid "[*,_1,Chinese literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇中文寫作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:38 +msgid "Select a Chinese Poem" +msgstr "選擇中文詩" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:39 +msgid "Manage Chinese Poems" +msgstr "管理中文詩" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:44 +msgid "Work set" +msgstr "寫作集" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:52 +msgid "Write a new Chinese poem." +msgstr "寫新中文詩。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:58 +msgid "Search for a Chinese poem:" +msgstr "搜尋中文詩:" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:75 +msgid "Your query found [*,_1,Chinese poem]." +msgstr "共 [#,_1] 首相符的中文詩。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:78 +msgid "[*,_1,Chinese poem]." +msgstr "共 [#,_1] 首中文詩" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:84 +msgid "Your query found [*,_1,Chinese poem], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 首相符的中文詩,列出第 [#,_2] 首到第 [#,_3] 首。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:88 +msgid "[*,_1,Chinese poem], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 首中文詩,列出第 [#,_2] 首到第 [#,_3] 首。" + +#: magicat/lib/perl5/Selima/imacat/List/Pages.pm:37 +msgid "HTML class" +msgstr "HTML 類別" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:38 +msgid "Select a Paper" +msgstr "選擇論文" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:42 +msgid "Type" +msgstr "類型" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:43 +msgid "Year" +msgstr "年" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:44 +msgid "Month" +msgstr "月" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:47 +msgid "Publication" +msgstr "刊物" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:49 +msgid "DOI" +msgstr "數位物件識別號" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:57 +msgid "Add a new paper." +msgstr "建新論文。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:63 +msgid "Search for a paper:" +msgstr "搜尋論文:" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:80 +msgid "Your query found [*,_1,paper]." +msgstr "共 [#,_1] 篇相符的論文。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:83 +msgid "[*,_1,paper]." +msgstr "共 [#,_1] 篇論文。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:89 +msgid "Your query found [*,_1,paper], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的論文,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:93 +msgid "[*,_1,paper], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇論文,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:38 +msgid "Select a Researcher" +msgstr "選擇研究者" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:39 +msgid "Manage Researchers" +msgstr "管理研究者" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:42 +msgid "Abbreviation" +msgstr "縮寫" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:50 +msgid "Add a new researcher." +msgstr "建新研究者。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:56 +msgid "Search for a researcher:" +msgstr "搜尋研究者:" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:73 +msgid "Your query found [*,_1,researcher]." +msgstr "共 [#,_1] 位相符的研究者。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:76 +msgid "[*,_1,researcher]." +msgstr "共 [#,_1] 位研究者。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:82 +msgid "Your query found [*,_1,researcher], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位相符的研究者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:86 +msgid "[*,_1,researcher], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位研究者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:45 +msgid "Full Text Search" +msgstr "全文檢索" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:46 +msgid "" +"

    Tavern IMACAT's

    \n" +"

    Full Text Search

    " +msgstr "" +"

    旅舍依瑪

    \n" +"

    全文檢索

    " + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:48 +msgid "Search Result" +msgstr "搜尋結果" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:49 +msgid "" +"

    Tavern IMACAT's

    \n" +"

    Search Result

    " +msgstr "" +"

    旅舍依瑪

    \n" +"

    搜尋結果

    " + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:72 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:100 +msgid "Please fill in your query." +msgstr "請填上檢索的辭彙。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:160 +msgid "Search in the website:" +msgstr "網站檢索:" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:177 +msgid "Your query found [*,_1,article]." +msgstr "共 [#,_1] 篇相符的文章。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:180 +msgid "[*,_1,article]." +msgstr "共 [#,_1] 篇文章。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:186 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:190 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:224 +msgid "Tavern Diary on [_1]" +msgstr "[_1] 旅舍日記" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:233 +msgid "Change Log on [_1]" +msgstr "[_1] 更新日誌" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:271 +msgid "English writings" +msgstr "英文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:281 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:290 +msgid "Guestbook Message on [_1]" +msgstr "[_1] 留言" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:38 +msgid "Select a Tag" +msgstr "選擇標籤" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:39 +msgid "Manage Tags" +msgstr "管理標籤" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:49 +msgid "Add a new tag." +msgstr "加新標籤。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:55 +msgid "Search for a tag:" +msgstr "搜尋標籤:" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:72 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:74 +msgid "Your query found [*,_1,tag]." +msgstr "共 [#,_1] 個相符的標籤。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:75 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:77 +msgid "[*,_1,tag]." +msgstr "共 [#,_1] 個標籤。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:81 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:83 +msgid "Your query found [*,_1,tag], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個相符的標籤,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:85 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:87 +msgid "[*,_1,tag], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個標籤,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:110 +msgid "This log entry was not modified." +msgstr "日誌未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:114 +msgid "This log entry has been successfully added." +msgstr "日誌寫好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:118 +msgid "This log entry has been successfully updated." +msgstr "日誌存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:122 +msgid "This log entry has been successfully deleted." +msgstr "日誌刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:109 +msgid "This diary entry was not modified." +msgstr "日記未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:113 +msgid "This diary entry has been successfully added." +msgstr "日記寫好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:117 +msgid "This diary entry has been successfully updated." +msgstr "日記存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:121 +msgid "This diary entry has been successfully deleted." +msgstr "日記刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:104 +msgid "This English literal work was not modified." +msgstr "英文寫作未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:108 +msgid "This English literal work has been successfully added." +msgstr "英文寫作寫好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:112 +msgid "This English literal work has been successfully updated." +msgstr "英文寫作存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:116 +msgid "This English literal work has been successfully deleted." +msgstr "英文寫作刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:188 +msgid "This Chinese literal work was not modified." +msgstr "中文寫作未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:192 +msgid "This Chinese literal work has been successfully added." +msgstr "中文寫作寫好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:196 +msgid "This Chinese literal work has been successfully updated." +msgstr "中文寫作存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:200 +msgid "This Chinese literal work has been successfully deleted." +msgstr "中文寫作刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:102 +msgid "This Chinese poem was not modified." +msgstr "中文詩未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:106 +msgid "This Chinese poem has been successfully added." +msgstr "中文詩寫好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:110 +msgid "This Chinese poem has been successfully updated." +msgstr "中文詩存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:114 +msgid "This Chinese poem has been successfully deleted." +msgstr "中文詩刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:293 +msgid "This paper was not modified." +msgstr "論文未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:297 +msgid "This paper has been successfully added." +msgstr "論文建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:301 +msgid "This paper has been successfully updated." +msgstr "論文存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:305 +msgid "This paper has been successfully deleted." +msgstr "論文刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:90 +msgid "This researcher was not modified." +msgstr "研究者未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:94 +msgid "This researcher has been successfully added." +msgstr "研究者建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:98 +msgid "This researcher has been successfully updated." +msgstr "研究者存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:102 +msgid "This researcher has been successfully deleted." +msgstr "研究者刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:88 +msgid "This tag was not modified." +msgstr "標籤未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:92 +msgid "This tag has been successfully added." +msgstr "標籤建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:96 +msgid "This tag has been successfully updated." +msgstr "標籤存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:100 +msgid "This tag has been successfully deleted." +msgstr "標籤刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook/Public.pm:44 +msgid "Your specie is too long. (Max. length [#,_1])" +msgstr "妳的物種太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook/Public.pm:63 +msgid "Your e-mail is too long. (Max. length [#,_1])" +msgstr "妳的電子郵件信箱太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:73 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:73 +msgid "Please select a paper." +msgstr "請選擇論文。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:94 +msgid "Please select a author." +msgstr "請選擇作者。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:97 +msgid "This author does not exist anymore. Please select another one." +msgstr "查無此作者,請改選其她作者。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:118 +msgid "This paper author already exists. You cannot create a duplicated one." +msgstr "已有同一筆論文作者,請勿重複建檔。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:94 +msgid "Please select a tag." +msgstr "請選擇標籤。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:97 +msgid "This tag does not exist anymore. Please select another one." +msgstr "查無此標籤,請改選其她標籤。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:118 +msgid "This paper tag already exists. You cannot create a duplicated one." +msgstr "已有同一筆論文標籤,請勿重複建檔。" + +#: magicat/lib/perl5/Selima/imacat/Form/Garbage/Public.pm:48 +msgid "I'm sick." +msgstr "我要吐了" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:42 +msgid "" +"General commercial advertisements are not welcomed and may be deleted at " +"once. HTML is not supported." +msgstr "旅人留言簿不歡迎一般商業廣告,隨見隨刪。不支援 HTML 留言。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:49 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:49 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:47 +msgid "Delete this type" +msgstr "刪掉這個類型" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:54 +msgid "This table provides you a form to add a new paper author." +msgstr "本表提供建新論文作者的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:57 +msgid "This table provides you a form to change a current paper author." +msgstr "本表提供編變更論文作者的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:60 +msgid "This table provides you a form to delete a paper author." +msgstr "本表提供刪除論文作者的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:77 +msgid "Add a New Paper Author" +msgstr "建新論文作者" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:80 +msgid "Change a Current Paper Author" +msgstr "變更論文作者" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:83 +msgid "Delete a Paper Author" +msgstr "刪除論文作者" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:93 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:93 +msgid "Paper:" +msgstr "論文:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:98 +msgid "Author:" +msgstr "作者:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:54 +msgid "This table provides you a form to add a new paper tag." +msgstr "本表提供建新論文標籤的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:57 +msgid "This table provides you a form to change a current paper tag." +msgstr "本表提供編變更論文標籤的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:60 +msgid "This table provides you a form to delete a paper tag." +msgstr "本表提供刪除論文標籤的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:77 +msgid "Add a New Paper Tag" +msgstr "建新論文標籤" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:80 +msgid "Change a Current Paper Tag" +msgstr "變更論文標籤" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:83 +msgid "Delete a Paper Tag" +msgstr "刪除論文標籤" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:98 +msgid "Tag:" +msgstr "標籤:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:52 +msgid "This table provides you a form to add a new paper type." +msgstr "本表提供建新論文類型的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:55 +msgid "This table provides you a form to edit a current paper type." +msgstr "本表提供編輯論文類型的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:58 +msgid "This table provides you a form to delete a paper type." +msgstr "本表提供刪除論文類型的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:75 +msgid "Add a New Paper Type" +msgstr "建新論文類型" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:78 +msgid "Edit a Current Paper Type" +msgstr "編輯論文類型" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:81 +msgid "Delete a Paper Type" +msgstr "刪除論文類型" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog/Public.pm:136 +msgid "Date:" +msgstr "日期:" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog/Public.pm:146 +msgid "The change log entry seperator" +msgstr "更新日誌分隔線" + +#: magicat/lib/perl5/Selima/imacat/List/Diary/Public.pm:146 +msgid "The diary entry seperator" +msgstr "日記分隔線" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage/Public.pm:68 +msgid "The message entry seperator" +msgstr "留言分隔線" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:38 +msgid "Select a Paper Author" +msgstr "選擇論文作者" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:39 +msgid "Manage Paper Authors" +msgstr "管理論文作者" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:42 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:42 +msgid "Paper" +msgstr "論文" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:43 +msgid "Author" +msgstr "作者" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:51 +msgid "Add a new paper author." +msgstr "建新論文作者。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:57 +msgid "Search for a paper author:" +msgstr "搜尋論文作者:" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:74 +msgid "Your query found [*,_1,author]." +msgstr "共 [#,_1] 位相符的論文作者。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:77 +msgid "[*,_1,author]." +msgstr "共 [#,_1] 位論文作者。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:83 +msgid "Your query found [*,_1,author], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位相符的論文作者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:87 +msgid "[*,_1,author], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位論文作者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:38 +msgid "Select a Paper Tag" +msgstr "選擇論文標籤" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:39 +msgid "Manage Paper Tags" +msgstr "管理論文標籤" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:43 +msgid "Tag" +msgstr "標籤" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:51 +msgid "Add a new paper tag." +msgstr "加新論文標籤。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:57 +msgid "Search for a paper tag:" +msgstr "搜尋論文標籤:" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:38 +msgid "Select a Paper Type" +msgstr "選擇論文類型" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:39 +msgid "Manage Paper Types" +msgstr "管理論文類型" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:49 +msgid "Add a new paper type." +msgstr "建新論文類型。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:55 +msgid "Search for a paper type:" +msgstr "搜尋論文類型:" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:72 +msgid "Your query found [*,_1,type]." +msgstr "共 [#,_1] 類相符的類型。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:75 +msgid "[*,_1,type]." +msgstr "共 [#,_1] 類類型。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:81 +msgid "Your query found [*,_1,type], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 類相符的類型,列出第 [#,_2] 類到第 [#,_3] 類。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:85 +msgid "[*,_1,type], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 類類型,列出第 [#,_2] 類到第 [#,_3] 類。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:97 +msgid "This paper author was not modified." +msgstr "論文作者未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:101 +msgid "This paper author has been successfully added." +msgstr "論文作者建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:105 +msgid "This paper author has been successfully updated." +msgstr "論文作者存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:109 +msgid "This paper author has been successfully deleted." +msgstr "論文作者刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:97 +msgid "This paper tag was not modified." +msgstr "論文標籤未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:101 +msgid "This paper tag has been successfully added." +msgstr "論文標籤建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:105 +msgid "This paper tag has been successfully updated." +msgstr "論文標籤存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:109 +msgid "This paper tag has been successfully deleted." +msgstr "論文標籤刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:94 +msgid "This paper type was not modified." +msgstr "論文類型未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:98 +msgid "This paper type has been successfully added." +msgstr "論文類型建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:102 +msgid "This paper type has been successfully updated." +msgstr "論文類型存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:106 +msgid "This paper type has been successfully deleted." +msgstr "論文類型刪掉了。" + +#~ msgid "Manage Accounting" +#~ msgstr "管理會計" + +#~ msgid "Reports" +#~ msgstr "報表" + +#~ msgid "Transactions" +#~ msgstr "傳票" + +#~ msgid "Subjects" +#~ msgstr "科目" + +#~ msgid "Records" +#~ msgstr "分錄" + +#~ msgid "Please fill in the publication." +#~ msgstr "請填上刊物。" + +#~ msgid "This URL is not reachable. Check if there is any typo in it." +#~ msgstr "這個網址連不上,請檢查有沒有拼錯。" diff --git a/htdocs/imacat/magicat/po/zh_TW.pox b/htdocs/imacat/magicat/po/zh_TW.pox new file mode 100644 index 0000000..26c2f04 --- /dev/null +++ b/htdocs/imacat/magicat/po/zh_TW.pox @@ -0,0 +1,2573 @@ +# Traditional Chinese PO file for the Tavern IMACAT's website +# Copyright (C) 2003-2018 imacat +# This file is distributed under the same license as the imacat package. +# imacat , 2003-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: imacat 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-03-24 07:09+0800\n" +"PO-Revision-Date: 2018-11-02 00:56+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: cgi-bin/1-guestbook.cgi:40 cgi-bin/1-guestbook.cgi:111 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:282 +msgid "Travellers' Guestbook" +msgstr "旅人留言簿" + +#: cgi-bin/1-guestbook.cgi:112 +msgid "" +"

    Tavern IMACAT’s

    \n" +"

    Travellers’
    Guestbook

    " +msgstr "" +"

    旅舍的

    \n" +"

    旅人留言簿

    " + +#: cgi-bin/1-guestbook.cgi:129 +msgid "Good morning to thee, gentle friend and traveller!" +msgstr "早安。溫和的友人及旅行者。" + +#: cgi-bin/1-guestbook.cgi:130 +msgid "" +"I call thee \"traveller\" no matter if thou hast never left thy home town, " +"no matter if thou wilst never again leave thy room, because all of us are " +"travellers. I call thee traveller for truly all of us travel a spiritual or " +"philosophical path -- even if it is simply by living the life that we choose " +"to live, or by searching for a new life when our current one fails to " +"satisfy our needs as thinking spiritual beings." +msgstr "" +"即使妳不曾離開過妳的故鄉,也不曾離開妳的房間,我都稱呼妳為旅行者,因為我們全" +"都是旅行者。我們在精神或哲學的道路上──即使它只是簡單地活在我們選擇的生活方式" +"上,或當現在的生活並不能滿足精神上的需要時,而尋找另一種新的生活方式。" + +#: cgi-bin/1-guestbook.cgi:133 +msgid "-- The Book of Fellowship, Ultima VII" +msgstr "──友誼會手冊‧創世紀Ⅶ" + +#: cgi-bin/garbage.cgi:40 +msgid "garbage, daub, poetry, message, essay" +msgstr "心情垃圾, 塗鴉, 詩, 留言, 短文" + +#: cgi-bin/garbage.cgi:110 magicat/lib/perl5/Selima/imacat/List/Search.pm:291 +msgid "Soundless Backalley" +msgstr "無聲的後巷" + +#: cgi-bin/garbage.cgi:111 +msgid "" +"

    The

    \n" +"

    Soundless
    Backalley

    " +msgstr "" +"

    旅舍的

    \n" +"

    無聲的後巷

    " + +#: cgi-bin/garbage.cgi:128 +msgid "" +"This is the backalley of Tavern. Every morning barmaid Cotton will put " +"garbages here. Besides that, there's never anyone passing by. Just " +"stinking garbages, drunks unable to tell dead or alive, cats and dogs and " +"flies, piss and vomits. The wall is filled with drawings and words unable " +"to tell whether they are poetry or shits. The vague music and laughters " +"come so faraway from inside the Tavern, like a neverending rhythm repeats " +"itself. The sun is blocked by the buildings. Even the time stops." +msgstr "" +"旅舍的後巷,除了每天清晨,女侍‧絮把垃圾拿出來倒以外,沒有人會經過的地方。堆滿" +"了腐臭的垃圾、分不清是死是活的醉漢、貓狗、蒼蠅、排洩物、嘔吐物。牆上畫滿不知" +"道是詩還是髒話的句子和塗鴉。遠處隱約傳來旅舍吧抬的音樂和嘈雜聲,像永恆的節奏" +"一樣在遠處反覆吟唱著。陽光被旅舍擋住,連時間也不動了。" + +#: cgi-bin/garbage.cgi:129 +msgid "" +"There's no one here, just you and yourself. Soundless is the loudest " +"sound. No matter how hard if you cry, shout or scream, you're still alone. " +"This is the darkest and the loneliest corner in the Tavern." +msgstr "" +"這裏沒有別人,只有妳和妳自己。無聲是最吵雜的聲音。妳撕破喉嚨哭泣,也沒人聽得" +"見。這是旅舍最陰暗的地方,也是旅舍最孤寂的角落。" + +#: cgi-bin/plurkavatar.cgi:41 cgi-bin/plurkfav.cgi:43 +msgid "Plurk" +msgstr "噗浪" + +#: cgi-bin/plurkavatar.cgi:65 +msgid "There is no Plurk user \"[_1]\"." +msgstr "查無噗浪使用者 [_1] 。" + +#: cgi-bin/plurkavatar.cgi:68 +msgid "Avator is not found for user \"[_1]\"." +msgstr "查無噗浪使用者 [_1] 的頭像。" + +#: cgi-bin/plurkavatar.cgi:72 +msgid "Plurk service is not available now." +msgstr "噗浪目前無法使用。" + +#: cgi-bin/plurkavatar.cgi:75 +msgid "Please fill in the Plurk user." +msgstr "請填上噗浪使用者。" + +#: cgi-bin/plurkavatar.cgi:89 +msgid "Plurk Avatars" +msgstr "噗浪頭像" + +#: cgi-bin/plurkavatar.cgi:96 +msgid "Plurk Avatars for User [_1]" +msgstr "[_1] 的噗浪頭像" + +#: cgi-bin/plurkavatar.cgi:121 +msgid "Plurk user:" +msgstr "噗浪使用者:" + +#: cgi-bin/plurkfav.cgi:52 +msgid "Plurk Favorites" +msgstr "噗浪喜歡" + +#: cgi-bin/plurkfav.cgi:86 +msgid "Plurk permanent link URL:" +msgstr "噗浪連結:" + +#: cgi-bin/plurkfav.cgi:105 +msgid "Plurk ID: [_1]" +msgstr "噗浪編號: [_1]" + +#: cgi-bin/plurkfav.cgi:106 +msgid "Set Plurk favorite" +msgstr "設定噗浪喜歡" + +#: cgi-bin/plurkfav.cgi:107 +msgid "Unset Plurk favorite" +msgstr "取消噗浪喜歡" + +#: cgi-bin/search.cgi:43 +msgid "search, query, full text search" +msgstr "搜尋, 檢索, 全文檢索" + +#: magicat/cgi-bin/acctrecs.cgi:44 magicat/cgi-bin/acctreps.cgi:39 +#: magicat/cgi-bin/acctsubj.cgi:42 magicat/cgi-bin/accttrx.cgi:43 +msgid "accounting" +msgstr "會計" + +#: magicat/cgi-bin/acctrecs.cgi:110 magicat/cgi-bin/acctrecs.cgi:157 +#: magicat/cgi-bin/acctsubj.cgi:120 magicat/cgi-bin/acctsubj.cgi:180 +#: magicat/cgi-bin/accttrx.cgi:110 magicat/cgi-bin/accttrx.cgi:157 +#: magicat/cgi-bin/changelog.cgi:110 magicat/cgi-bin/changelog.cgi:159 +#: magicat/cgi-bin/diary.cgi:110 magicat/cgi-bin/diary.cgi:159 +#: magicat/cgi-bin/garbage.cgi:104 magicat/cgi-bin/garbage.cgi:148 +#: magicat/cgi-bin/groupmem.cgi:108 magicat/cgi-bin/groupmem.cgi:153 +#: magicat/cgi-bin/groups.cgi:121 magicat/cgi-bin/groups.cgi:176 +#: magicat/cgi-bin/guestbook.cgi:104 magicat/cgi-bin/guestbook.cgi:150 +#: magicat/cgi-bin/linkcat.cgi:119 magicat/cgi-bin/linkcat.cgi:177 +#: magicat/cgi-bin/linkcatz.cgi:108 magicat/cgi-bin/linkcatz.cgi:153 +#: magicat/cgi-bin/links.cgi:110 magicat/cgi-bin/links.cgi:161 +#: magicat/cgi-bin/literalen.cgi:161 magicat/cgi-bin/literalen.cgi:205 +#: magicat/cgi-bin/literalzh.cgi:175 magicat/cgi-bin/literalzh.cgi:219 +#: magicat/cgi-bin/ltzhpoem.cgi:106 magicat/cgi-bin/ltzhpoem.cgi:151 +#: magicat/cgi-bin/pages.cgi:114 magicat/cgi-bin/pages.cgi:163 +#: magicat/cgi-bin/papers.cgi:108 magicat/cgi-bin/papers.cgi:154 +#: magicat/cgi-bin/pprauthr.cgi:105 magicat/cgi-bin/pprauthr.cgi:150 +#: magicat/cgi-bin/pprtags.cgi:105 magicat/cgi-bin/pprtags.cgi:150 +#: magicat/cgi-bin/pprtypes.cgi:112 magicat/cgi-bin/pprtypes.cgi:165 +#: magicat/cgi-bin/resrcher.cgi:109 magicat/cgi-bin/resrcher.cgi:157 +#: magicat/cgi-bin/scptpriv.cgi:106 magicat/cgi-bin/scptpriv.cgi:151 +#: magicat/cgi-bin/tags.cgi:109 magicat/cgi-bin/tags.cgi:157 +#: magicat/cgi-bin/usermem.cgi:108 magicat/cgi-bin/usermem.cgi:153 +#: magicat/cgi-bin/userpref.cgi:106 magicat/cgi-bin/userpref.cgi:151 +#: magicat/cgi-bin/users.cgi:125 magicat/cgi-bin/users.cgi:189 +msgid "Incorrect form: [_1]." +msgstr "查無此表格: [_1] 。" + +#: magicat/cgi-bin/acctrecs.cgi:204 +msgid "Please select the accounting record." +msgstr "請選擇會計分錄。" + +#: magicat/cgi-bin/acctrecs.cgi:212 +msgid "" +"This accounting record does not exist anymore. Please select another one." +msgstr "查無此會計分錄,請重新選擇。" + +#: magicat/cgi-bin/acctsubj.cgi:93 magicat/cgi-bin/acctsubj.cgi:140 +msgid "Please add a new accounting subject from [_1]." +msgstr "請由[_1]建新會計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:109 magicat/cgi-bin/acctsubj.cgi:169 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the subject, " +"[numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] " +"must first be deleted." +msgstr "" +"本會計科目下有子會計科目,不可直接刪除。要刪除本會計科目,請先刪除其下的子會" +"計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:113 magicat/cgi-bin/acctsubj.cgi:173 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the subject, [numerate,_1,its " +"accounting record,all of its accounting records] must first be deleted." +msgstr "" +"本會計科目下有會計分錄,不可直接刪除。要刪除本會計科目,請先刪除其下的會計分" +"錄。" + +#: magicat/cgi-bin/acctsubj.cgi:232 +msgid "Please select the accounting subject." +msgstr "請選擇會計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:240 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "查無此會計科目,請重新選擇。" + +#: magicat/cgi-bin/accttrx.cgi:204 +msgid "Please select the accounting transaction." +msgstr "請選擇會計傳票。" + +#: magicat/cgi-bin/accttrx.cgi:212 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "查無此會計傳票,請重新選擇。" + +#: magicat/cgi-bin/actlog.cgi:36 +msgid "activity, logs" +msgstr "活動, 記錄, 日誌" + +#: magicat/cgi-bin/changelog.cgi:42 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:472 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:539 +msgid "change log, history" +msgstr "更新日誌, 變遷史" + +#: magicat/cgi-bin/changelog.cgi:91 magicat/cgi-bin/changelog.cgi:128 +msgid "Please write a new log entry from [_1]." +msgstr "請由[_1]寫新日誌。" + +#: magicat/cgi-bin/changelog.cgi:206 +msgid "Please select the log entry." +msgstr "請選擇日誌。" + +#: magicat/cgi-bin/changelog.cgi:214 +msgid "This log entry does not exist anymore. Please select another one." +msgstr "查無該則日誌,請重新選擇。" + +#: magicat/cgi-bin/diary.cgi:42 magicat/lib/perl5/Selima/imacat/Rebuild.pm:327 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:394 +msgid "diary" +msgstr "日記" + +#: magicat/cgi-bin/diary.cgi:91 magicat/cgi-bin/diary.cgi:128 +msgid "Please write a new diary entry from [_1]." +msgstr "請由[_1]寫新日記。" + +#: magicat/cgi-bin/diary.cgi:206 +msgid "Please select the diary entry." +msgstr "請選擇日記。" + +#: magicat/cgi-bin/diary.cgi:214 +msgid "This diary entry does not exist anymore. Please select another one." +msgstr "查無該則日記,請重新選擇。" + +#: magicat/cgi-bin/funds.cgi:36 +msgid "mutual funds, performance, indicators" +msgstr "共同基金, 績效, 指標" + +#: magicat/cgi-bin/garbage.cgi:40 +msgid "backalley" +msgstr "後巷" + +#: magicat/cgi-bin/garbage.cgi:195 magicat/cgi-bin/guestbook.cgi:197 +msgid "Please select the message." +msgstr "請選擇要設定的留言。" + +#: magicat/cgi-bin/garbage.cgi:203 magicat/cgi-bin/guestbook.cgi:205 +msgid "This message does not exist anymore. Please select another one." +msgstr "查無該留言,請改選其她留言。" + +#: magicat/cgi-bin/groupmem.cgi:44 +msgid "group membership" +msgstr "群組成員" + +#: magicat/cgi-bin/groupmem.cgi:200 magicat/cgi-bin/usermem.cgi:200 +msgid "Please select the membership record." +msgstr "請選擇成員關係。" + +#: magicat/cgi-bin/groupmem.cgi:208 magicat/cgi-bin/usermem.cgi:208 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "查無此成員關係,請重新選擇。" + +#: magicat/cgi-bin/groups.cgi:48 +msgid "groups" +msgstr "群組" + +#: magicat/cgi-bin/groups.cgi:98 magicat/cgi-bin/groups.cgi:140 +msgid "Please create a new group from [_1]." +msgstr "請由[_1]建新群組。" + +#: magicat/cgi-bin/groups.cgi:224 +msgid "Please select the group." +msgstr "請選擇群組。" + +#: magicat/cgi-bin/groups.cgi:232 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: magicat/cgi-bin/guestbook.cgi:40 +msgid "guestbook" +msgstr "留言簿" + +#: magicat/cgi-bin/linkcat.cgi:43 +msgid "link categories" +msgstr "相關連結分類" + +#: magicat/cgi-bin/linkcat.cgi:92 magicat/cgi-bin/linkcat.cgi:137 +msgid "Please add a new category from [_1]." +msgstr "請由[_1]建新分類。" + +#: magicat/cgi-bin/linkcat.cgi:108 magicat/cgi-bin/linkcat.cgi:166 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: magicat/cgi-bin/linkcat.cgi:112 magicat/cgi-bin/linkcat.cgi:170 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: magicat/cgi-bin/linkcat.cgi:225 +msgid "Please select the category." +msgstr "請選擇分類。" + +#: magicat/cgi-bin/linkcat.cgi:233 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: magicat/cgi-bin/linkcatz.cgi:44 +msgid "link categorization" +msgstr "連結分類表" + +#: magicat/cgi-bin/linkcatz.cgi:200 +msgid "Please select the categorization record." +msgstr "請選擇分類資料。" + +#: magicat/cgi-bin/linkcatz.cgi:208 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "查無此分類資料,請重新選擇。" + +#: magicat/cgi-bin/links.cgi:42 magicat/lib/perl5/Selima/imacat/Rebuild.pm:254 +msgid "related links" +msgstr "相關連結" + +#: magicat/cgi-bin/links.cgi:91 magicat/cgi-bin/links.cgi:128 +msgid "Please add a new related link from [_1]." +msgstr "請由[_1]建新相關連結。" + +#: magicat/cgi-bin/links.cgi:185 +msgid "Manage Keep Travelling" +msgstr "管理繼續旅行" + +#: magicat/cgi-bin/links.cgi:211 +msgid "Please select the related link." +msgstr "請選擇要設定的相關連結。" + +#: magicat/cgi-bin/links.cgi:219 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查無該相關連結,請改選其她相關連結。" + +#: magicat/cgi-bin/literalen.cgi:43 +msgid "English literal works" +msgstr "英文寫作" + +#: magicat/cgi-bin/literalen.cgi:259 +msgid "Please select the English literal work." +msgstr "請選擇要編輯的英文寫作。" + +#: magicat/cgi-bin/literalen.cgi:267 +msgid "" +"This English literal work does not exist anymore. Please select another one." +msgstr "查無此英文寫作,請重新選擇。" + +#: magicat/cgi-bin/literalzh.cgi:44 +msgid "Chinese literal works" +msgstr "中文寫作" + +#: magicat/cgi-bin/literalzh.cgi:273 +msgid "Please select the Chinese literal work." +msgstr "請選擇要編輯的中文寫作。" + +#: magicat/cgi-bin/literalzh.cgi:281 +msgid "" +"This Chinese literal work does not exist anymore. Please select another one." +msgstr "查無此中文寫作,請重新選擇。" + +#: magicat/cgi-bin/logout.cgi:39 +msgid "log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:112 magicat/cgi-bin/logout.cgi:119 +msgid "Log Out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:135 +msgid "Are you sure you want to log out?" +msgstr "妳確定要登出嗎?" + +#: magicat/cgi-bin/logout.cgi:136 magicat/lib/perl5/Selima/imacat/HTML.pm:577 +msgid "Log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:152 +msgid "Log in again." +msgstr "重新登入。" + +#: magicat/cgi-bin/ltzhpoem.cgi:42 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:253 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:262 +msgid "Chinese poems" +msgstr "中文詩" + +#: magicat/cgi-bin/ltzhpoem.cgi:199 +msgid "Please select the Chinese poem." +msgstr "請選擇中文詩。" + +#: magicat/cgi-bin/ltzhpoem.cgi:207 +msgid "This Chinese poem does not exist anymore. Please select another one." +msgstr "查無此中文詩,請重新選擇。" + +#: magicat/cgi-bin/pages.cgi:40 +msgid "pages" +msgstr "網頁" + +#: magicat/cgi-bin/pages.cgi:89 magicat/cgi-bin/pages.cgi:132 +msgid "Please add a new page from [_1]." +msgstr "請由[_1]寫新網頁。" + +#: magicat/cgi-bin/pages.cgi:216 +msgid "Please select the page." +msgstr "請選擇網頁。" + +#: magicat/cgi-bin/pages.cgi:224 +msgid "This page does not exist anymore. Please select another one." +msgstr "查無此頁,請改選其她網頁。" + +#: magicat/cgi-bin/papers.cgi:44 magicat/cgi-bin/pprauthr.cgi:41 +#: magicat/cgi-bin/pprtags.cgi:41 magicat/cgi-bin/pprtypes.cgi:40 +msgid "papers" +msgstr "論文" + +#: magicat/cgi-bin/papers.cgi:201 +msgid "Please select the paper." +msgstr "請選擇論文。" + +#: magicat/cgi-bin/papers.cgi:209 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:76 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:76 +msgid "This paper does not exist anymore. Please select another one." +msgstr "查無此論文,請改選其她論文。" + +#: magicat/cgi-bin/pprauthr.cgi:197 +msgid "Please select the paper author." +msgstr "請選擇論文作者。" + +#: magicat/cgi-bin/pprauthr.cgi:205 +msgid "This paper author does not exist anymore. Please select another one." +msgstr "查無此論文作者,請改選其她論文作者。" + +#: magicat/cgi-bin/pprtags.cgi:197 +msgid "Please select the paper tag." +msgstr "請選擇論文標籤。" + +#: magicat/cgi-bin/pprtags.cgi:205 +msgid "This paper tag does not exist anymore. Please select another one." +msgstr "查無此論文標籤,請改選其她論文標籤。" + +#: magicat/cgi-bin/pprtypes.cgi:89 magicat/cgi-bin/pprtypes.cgi:130 +msgid "Please add a new paper type from [_1]." +msgstr "請由[_1]建新論文類型。" + +#: magicat/cgi-bin/pprtypes.cgi:105 magicat/cgi-bin/pprtypes.cgi:158 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:89 +msgid "" +"This paper type has [numerate,_1,a paper,papers]. It cannot be deleted. To " +"delete the type, [numerate,_1,its paper,all of its papers] must first be " +"deleted." +msgstr "本論文類型下有論文,不可直接刪除。要刪除本類型,請先刪除其下的論文。" + +#: magicat/cgi-bin/pprtypes.cgi:212 +msgid "Please select the paper type." +msgstr "請選擇論文類型。" + +#: magicat/cgi-bin/pprtypes.cgi:220 +msgid "This paper type does not exist anymore. Please select another one." +msgstr "查無此論文類型,請改選其她類型。" + +#: magicat/cgi-bin/rebuild.cgi:37 +msgid "rebuild pages" +msgstr "重製網頁" + +#: magicat/cgi-bin/resrcher.cgi:41 +msgid "researchers" +msgstr "研究者" + +#: magicat/cgi-bin/resrcher.cgi:102 magicat/cgi-bin/resrcher.cgi:150 +#: magicat/cgi-bin/tags.cgi:102 magicat/cgi-bin/tags.cgi:150 +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:88 +msgid "" +"This researcher has [numerate,_1,a paper,papers]. It cannot be deleted. To " +"delete the researcher, [numerate,_1,its paper,all of its papers] must first " +"be deleted." +msgstr "本研究者下有論文,不可直接刪除。要刪除本研究者,請先刪除其下的論文。" + +#: magicat/cgi-bin/resrcher.cgi:204 magicat/cgi-bin/tags.cgi:204 +msgid "Please select the researcher." +msgstr "請選擇研究者。" + +#: magicat/cgi-bin/resrcher.cgi:212 magicat/cgi-bin/tags.cgi:212 +msgid "This researcher does not exist anymore. Please select another one." +msgstr "查無此研究者,請重新選擇。" + +#: magicat/cgi-bin/saveform.cgi:46 +msgid "saved forms" +msgstr "暫存表單" + +#: magicat/cgi-bin/saveform.cgi:77 +msgid "Form [_1] does not exist anymore. Please select another one." +msgstr "查無表單 [_1] ,請改選其她表單。" + +#: magicat/cgi-bin/saveform.cgi:92 +msgid "Manage the Saved Forms" +msgstr "管理暫存表單" + +#: magicat/cgi-bin/saveform.cgi:134 +msgid "Select" +msgstr "選" + +#: magicat/cgi-bin/scptpriv.cgi:42 +msgid "script privilege" +msgstr "程式權限" + +#: magicat/cgi-bin/scptpriv.cgi:198 +msgid "Please select the script privilege record." +msgstr "請選擇程式權限。" + +#: magicat/cgi-bin/scptpriv.cgi:206 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "查無該程式權限,請重新選擇。" + +#: magicat/cgi-bin/tags.cgi:41 +msgid "tags" +msgstr "標籤" + +#: magicat/cgi-bin/usermem.cgi:44 +msgid "user membership" +msgstr "使用者成員" + +#: magicat/cgi-bin/userpref.cgi:42 +msgid "user preference" +msgstr "使用者偏好" + +#: magicat/cgi-bin/userpref.cgi:198 +msgid "Please select the user preference." +msgstr "請選擇使用者偏好。" + +#: magicat/cgi-bin/userpref.cgi:206 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "查無該使用者偏好,請重新選擇。" + +#: magicat/cgi-bin/users.cgi:43 +msgid "users" +msgstr "帳號" + +#: magicat/cgi-bin/users.cgi:237 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: magicat/cgi-bin/users.cgi:245 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:52 +msgid "imacat" +msgstr "依瑪貓" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:53 +msgid "© imacat. All rights reserved." +msgstr "© 依瑪貓。依瑪貓保有所有權利。" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:63 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1016 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:409 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:410 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:225 +msgid "Tavern Diary" +msgstr "旅舍日記" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:64 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:98 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:234 +msgid "Change Log" +msgstr "更新日誌" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:65 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:108 +msgid "Chinese Literal Works" +msgstr "中文寫作" + +#: magicat/lib/perl5/Selima/imacat/Config.pm:66 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:112 +msgid "English Literal Works" +msgstr "英文寫作" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:90 +msgid "Manage Content" +msgstr "管理網站" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:92 +msgid "Guestbook" +msgstr "留言簿" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:94 +msgid "Backalley" +msgstr "後巷" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:96 +msgid "Diary" +msgstr "日記" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:100 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:48 +msgid "Pages" +msgstr "網頁" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:102 +msgid "Links" +msgstr "連結" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:104 +msgid "Link Categories" +msgstr "連結分類" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:106 +msgid "Link Categorization" +msgstr "連結分類表" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:110 +msgid "Chinese Poems" +msgstr "中文詩" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:116 +msgid "Manage Accounts" +msgstr "管理帳號" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:118 +msgid "Users" +msgstr "帳號" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:120 +msgid "Groups" +msgstr "群組" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:122 +msgid "User Membership" +msgstr "使用者成員" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:124 +msgid "Group Membership" +msgstr "群組成員" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:126 +msgid "User Preferences" +msgstr "使用者偏好" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:128 +msgid "Script Privileges" +msgstr "程式權限" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:148 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:39 +msgid "Manage Papers" +msgstr "管理論文" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:150 +msgid "Papers" +msgstr "論文" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:152 +msgid "Researchers" +msgstr "研究者" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:154 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:46 +msgid "Tags" +msgstr "標籤" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:156 +msgid "Types" +msgstr "類型" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:158 +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:45 +msgid "Authors" +msgstr "作者" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:160 +msgid "Paper Tags" +msgstr "論文標籤" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:164 +msgid "Miscellaneous" +msgstr "雜項" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:166 +#, fuzzy +msgid "Accounting" +msgstr "會計" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:168 +msgid "Funds" +msgstr "基金" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:170 +msgid "Activity Log" +msgstr "活動日誌" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:172 +msgid "Rebuild Pages" +msgstr "重製網頁" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:174 +msgid "Analog" +msgstr "訪客統計" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:176 +msgid "Test Script" +msgstr "測試程式" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:178 +msgid "MRTG" +msgstr "流量統計" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:180 +msgid "Saved Forms" +msgstr "暫存表單" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:182 +msgid "CGI Environment" +msgstr "CGI 環境" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:186 +msgid "Server Status" +msgstr "伺服器狀態" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:189 +msgid "Server Information" +msgstr "伺服器資訊" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:192 +msgid "Bwshare Information" +msgstr "節頻資訊" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:195 +msgid "Bwshare Trace" +msgstr "節頻記錄" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:198 +msgid "Perl Status" +msgstr "Perl 狀態" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:253 +msgid "Skip to the page content area." +msgstr "跳到網頁內文區。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:254 +msgid "Page Content Area" +msgstr "網頁內文區" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:372 +msgid "Magicat" +msgstr "梅姬" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:441 +msgid "Navigation Links Area" +msgstr "導覽連結區" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:521 +msgid "Language Switching Area" +msgstr "語言切換區" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:575 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "%s,妳好!(修改資料)" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:617 +#, c-format +msgid "%s:" +msgstr "%s:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:689 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:243 +msgid "Keep Travelling" +msgstr "繼續旅行" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:757 +msgid "E-mail" +msgstr "電子郵件信箱" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:782 +msgid "URL:" +msgstr "網址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:785 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:920 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:69 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:49 +msgid "E-mail:" +msgstr "電子郵件信箱:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:791 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:921 +msgid "Address:" +msgstr "地址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:793 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:922 +msgid "Tel.:" +msgstr "電話:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:795 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:923 +msgid "Fax.:" +msgstr "傳真:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:824 +msgid "" +"Are you ready to check out? Just drop your room key at the counter, and " +"travel for your next stop. Life is a never-ending trip, and Tavern is only " +"one of your many stops. Are you ready to go now?" +msgstr "" +"妳要退房了嗎?把妳的房門鑰匙交還給櫃臺,該向下一個停靠站出發了。這是一趟永無" +"止境的旅程,旅舍,只是妳的一個中途停靠站。若妳準備好了,就出發囉!" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:825 +msgid "" +"Greetings, traveller. I'm rinse the Tavern Tour Agent. Where is your next " +"stop?" +msgstr "妳好,旅行者。我是琳思。妳要往哪裡去旅行呢?" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:837 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:906 +msgid "~[Tavern~] Website Registration" +msgstr "~[旅舍回函~] 網站登錄" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:907 +msgid "" +"This table provide a form to register your site at Tavern \"Keep Travelling" +"\", the data column names and their input fields to fill in the information." +msgstr "" +"本表提供登錄旅舍「繼續旅行」的表單,網站資料欄位名稱,和填寫該資料的輸入格。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:908 +msgid "Fill in the description here." +msgstr "請填上簡介。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:909 +msgid "Regiser your site" +msgstr "登錄網站" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:910 +msgid "" +"I sincerely wish to build more hyperlinks with websites that're kind to " +"women/lesbian/queer. If you wish to link with me, or if you have any such " +"information, whether in Chinese or not, please tell me by filling this form " +"below. I'll put it in as soon as possible. Thank you." +msgstr "" +"我很希望能和各地對女性/同志友善的網站建立超連結。如果妳願意和我連線,或是妳" +"有其她友善網站的資訊,不論中文與否,請填寫下表告訴我,我會儘快放進去。謝謝!" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:911 +msgid "" +"All fields in the form below, Except for the site name, the URL and the " +"description, are optional. Anything you fill here will be shown to " +"ANYONE who visits Tavern IMACAT's. Tavern does not collect " +"any personal informations. If you do not wish to distribute some private " +"informations, just leave them blank. If you represent some organization, " +"fill as detail as possible to help others finding you." +msgstr "" +"下表除站名、網址及簡介外,所有資料皆為選填。妳填的所有資料都會顯示在旅舍依瑪" +"中,任何人都看得到。旅舍不搜集任何個人資料。若妳不願私人資料" +"曝光,請留白勿填。若妳們是組織團體,請儘量詳填所有資料,以方便她人聯絡。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:912 +msgid "General commercial sites besides lesbian shops are not welcome." +msgstr "除女同志商店外,旅舍恕不受理一般商業網站。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:914 +msgid "Site name:" +msgstr "站名:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:915 +msgid "Site name, 2nd language (if any):" +msgstr "站名(第二語言,可略):" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:916 +msgid "Site URL:" +msgstr "網址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:917 +msgid "Link logo URL:" +msgstr "連結小圖網址:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:918 +msgid "Category:" +msgstr "分類:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:919 +msgid "Introduction:" +msgstr "簡介:" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:924 +msgid "OK!" +msgstr "好了!" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1010 +msgid "The diary is empty." +msgstr "現無任何日記。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1015 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1075 +msgid "imacat's Private Bed♥room" +msgstr "依瑪貓的閨♥房" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1025 +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1085 +msgid "Index" +msgstr "目錄" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1042 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:326 +#, c-format +msgid "Tavern Diary Volume %s" +msgstr "旅舍日記 卷%s" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1070 +msgid "The change log is empty." +msgstr "現無任何日誌。" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1076 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:554 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:555 +msgid "Tavern Change Log" +msgstr "旅舍更新日誌" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1102 +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:471 +#, c-format +msgid "Tavern Change Log Volume %s" +msgstr "旅舍更新日誌 卷%s" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1482 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "mod_perl -- 速度,動力,無限可能" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1483 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" +"本程式以 Perl 撰寫,專為 mod_perl 設計強化" + +#: magicat/lib/perl5/Selima/imacat/HTML.pm:1496 +msgid "" +"This script is written in Perl." +msgstr "" +"本程式以 Perl 撰寫" + +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:264 +msgid "Keep Travelling..." +msgstr "繼續旅行……" + +#: magicat/lib/perl5/Selima/imacat/Rebuild.pm:265 +msgid "Continue Your Journey..." +msgstr "繼續妳的旅程……" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:41 +msgid "This specie is too long. (Max. length [#,_1])" +msgstr "物種太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:60 +msgid "This e-mail is too long. (Max. length [#,_1])" +msgstr "電子郵件信箱太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:75 +msgid "Please choose the language." +msgstr "請選擇語言。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook.pm:80 +msgid "" +"Language [_1] is invalid. Please choose a proper language from the form." +msgstr "[_1] 語無效。請由表上選擇適當的語言。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:55 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:57 +msgid "Please fill in the date." +msgstr "請填上日期。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:58 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:61 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:63 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:60 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:63 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:65 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期請以 YYYY-MM-DD 格式填寫。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralEn.pm:73 +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:75 +msgid "" +"The literal work on this date already exists. You cannot create a " +"duplicated one." +msgstr "已有這一天的寫作,請勿重複建檔。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:95 +msgid "This title is too long. (Max. length [#,_1])" +msgstr "標題太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/LiteralZh.pm:117 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:117 +msgid "Fill in the content here." +msgstr "請填上內文。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LtZhPoem.pm:58 +msgid "Please select a work set." +msgstr "請選擇寫作集。" + +#: magicat/lib/perl5/Selima/imacat/Checker/LtZhPoem.pm:61 +msgid "This work set does not exist anymore. Please select another one." +msgstr "查無此寫作集,請重新選擇。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Page.pm:41 +msgid "This HTML class is too long. (Max. length [#,_1])" +msgstr "HTML 類別太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:62 +msgid "Please select in the type." +msgstr "請選擇類型。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:65 +msgid "This type does not exist anymore. Please select another one." +msgstr "查無此類型,請改選其她類型。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:83 +msgid "Please fill in the year of publication." +msgstr "請填上出版年。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:86 +msgid "This year of publication is too long. (Max. length [#,_1])" +msgstr "出版年太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:89 +msgid "This year of publication is too short. (Min. length [#,_1])" +msgstr "出版年太短了。(最短 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:93 +msgid "Please fill in a positive integer year of publication." +msgstr "出版年請填正整數。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:100 +msgid "Year ([#,_1]) out of range. Please specify between [#,_2] and [#,_3]." +msgstr "年([#,_1])超出範圍,請設在 [#,_2] 到 [#,_3] 之間。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:121 +msgid "This month is too long. (Max. length [#,_1])" +msgstr "月份標題太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:125 +msgid "Please fill in the month as ~[month~], ~[month day~] or ~[season~]." +msgstr "月份請以 ~[月份~] 、 ~[月份 日期~] 或 ~[季節~] 格式填寫。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:148 +msgid "Please fill in the author." +msgstr "請填上作者。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:313 +msgid "This publication is too long. (Max. length [#,_1])" +msgstr "刊物太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:334 +msgid "This pages is too long. (Max. length [#,_1])" +msgstr "頁數太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:338 +msgid "Please fill in the pages as ### or ###-###." +msgstr "頁數請填 ### 或 ###-### 格式。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:358 +msgid "This DOI is too long. (Max. length [#,_1])" +msgstr "數位物件識別號太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:369 +msgid "This paper already exists. You cannot create a duplicated one." +msgstr "已有同一篇論文,請勿重複建檔。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:387 +msgid "Please fill in the URL." +msgstr "請填上網址。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:390 +msgid "This URL is too long. (Max. length [#,_1])" +msgstr "網址太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper.pm:394 +msgid "Please fill in a valid URL." +msgstr "請填上正確的網址。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:51 +msgid "Please fill in the full name." +msgstr "請填上名字。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:54 +msgid "This full name is too long. (Max. length [#,_1])" +msgstr "名字太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:73 +msgid "Please fill in the abbreviation." +msgstr "請填上縮寫。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Researcher.pm:76 +msgid "This abbreviation is too long. (Max. length [#,_1])" +msgstr "縮寫太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Tag.pm:59 +msgid "This tag already exists. You cannot create a duplicated one." +msgstr "已有同一個論文標籤,請勿重複建檔。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:46 +msgid "Delete this log entry" +msgstr "刪掉這則日誌" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:51 +msgid "This table provides you a form to write a new log entry." +msgstr "本表提供寫新日誌的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:54 +msgid "This table provides you a form to edit a current log entry." +msgstr "本表提供編輯日誌的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:57 +msgid "This table provides you a form to delete a log entry." +msgstr "本表提供刪除日誌的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:74 +msgid "Write a New Change Log Entry" +msgstr "寫新更新日誌" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:77 +msgid "Edit a Current Change Log Entry" +msgstr "編輯更新日誌" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:80 +msgid "Delete a Change Log Entry" +msgstr "刪除更新日誌" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:89 +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:89 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:95 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:116 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:298 +msgid "Hide?" +msgstr "隱藏?" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:90 +msgid "Hide this log entry" +msgstr "隱藏這則日誌" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:90 +msgid "Show this log entry" +msgstr "秀出這則日誌" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:91 +msgid "Hide this log entry currently." +msgstr "暫勿秀出這則日誌。" + +#: magicat/lib/perl5/Selima/imacat/Form/ChangeLog.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:96 +msgid "Page No.:" +msgstr "頁數:" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:46 +msgid "Delete this diary entry" +msgstr "刪掉這則日記" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:51 +msgid "This table provides you a form to write a new diary entry." +msgstr "本表提供寫新日記的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:54 +msgid "This table provides you a form to edit a current diary entry." +msgstr "本表提供編輯日記的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:57 +msgid "This table provides you a form to delete a diary entry." +msgstr "本表提供刪除日記的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:74 +msgid "Write a New Diary Entry" +msgstr "寫新日記" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:77 +msgid "Edit a Current Diary Entry" +msgstr "編輯日記" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:80 +msgid "Delete a Diary Entry" +msgstr "刪除日記" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:90 +msgid "Hide this diary entry" +msgstr "隱藏這則日記" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:90 +msgid "Show this diary entry" +msgstr "秀出這則日記" + +#: magicat/lib/perl5/Selima/imacat/Form/Diary.pm:91 +msgid "Hide this diary entry currently." +msgstr "暫勿秀出這則日記。" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:74 +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:54 +msgid "Specie:" +msgstr "物種:" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook.pm:90 +msgid "Language tag:" +msgstr "語言標籤:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:46 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:50 +msgid "Delete this literal work" +msgstr "刪掉這篇寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:51 +msgid "This table provides you a form to write a new English literal work." +msgstr "本表提供寫新英文寫作的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:54 +msgid "This table provides you a form to edit a current English literal work." +msgstr "本表提供編輯英文寫作的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:57 +msgid "This table provides you a form to delete a English literal work." +msgstr "本表提供刪除英文寫作的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:74 +msgid "Write a New English Literal Work" +msgstr "寫新英文寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:77 +msgid "Edit a Current English Literal Work" +msgstr "編輯英文寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:80 +msgid "Delete a English Literal Work" +msgstr "刪除英文寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:87 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:93 +msgid "Preview this literal work." +msgstr "預覽這篇寫作。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:299 +msgid "Hide this literal work" +msgstr "隱藏這篇寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:299 +msgid "Show this literal work" +msgstr "秀出這篇寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralEn.pm:97 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:300 +msgid "Hide this literal work currently." +msgstr "暫勿秀出這篇寫作。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:55 +msgid "This table provides you a form to write a new Chinese literal work." +msgstr "本表提供寫新中文寫作的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:58 +msgid "This table provides you a form to edit a current Chinese literal work." +msgstr "本表提供編輯中文寫作的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:61 +msgid "This table provides you a form to delete a Chinese literal work." +msgstr "本表提供刪除中文寫作的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:80 +msgid "Write a New Chinese Literal Work" +msgstr "寫新中文寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:83 +msgid "Edit a Current Chinese Literal Work" +msgstr "編輯中文寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:86 +msgid "Delete a Chinese Literal Work" +msgstr "刪除中文寫作" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:114 +msgid "Title:" +msgstr "標題:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:115 +msgid "Content:" +msgstr "內文:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:118 +msgid "Hide this poem currently." +msgstr "暫勿秀出這首詩。" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:122 +msgid "Hide this poem" +msgstr "隱藏這首詩" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:123 +msgid "Show this poem" +msgstr "秀出這首詩" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:135 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:187 +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:261 +msgid "[numerate,_1,Poem]:" +msgstr "詩:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:188 +msgid "Original:" +msgstr "原:" + +#: magicat/lib/perl5/Selima/imacat/Form/LiteralZh.pm:189 +msgid "New:" +msgstr "新:" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:49 +msgid "Delete this poem" +msgstr "刪掉這首中文詩" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:54 +msgid "This table provides you a form to write a new Chinese poem." +msgstr "本表提供寫新中文詩的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:57 +msgid "This table provides you a form to edit a current Chinese poem." +msgstr "本表提供編輯中文詩的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:60 +msgid "This table provides you a form to delete a Chinese poem." +msgstr "本表提供刪除日中文詩的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:77 +msgid "Write a New Chinese Poem" +msgstr "寫新中文詩" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:80 +msgid "Edit a Current Chinese Poem" +msgstr "編輯中文詩" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:83 +msgid "Delete a Chinese Poem" +msgstr "刪除中文詩" + +#: magicat/lib/perl5/Selima/imacat/Form/LtZhPoem.pm:93 +msgid "Work set:" +msgstr "寫作集:" + +#: magicat/lib/perl5/Selima/imacat/Form/Page.pm:61 +msgid "HTML class:" +msgstr "HTML 類別:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:50 +msgid "Delete this paper" +msgstr "刪掉這篇論文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:55 +msgid "This table provides you a form to add a new paper." +msgstr "本表提供建新論文的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:58 +msgid "This table provides you a form to edit a current paper." +msgstr "本表提供編輯論文的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:61 +msgid "This table provides you a form to delete a paper." +msgstr "本表提供刪除論文的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:80 +msgid "Add a New Paper" +msgstr "建新論文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:83 +msgid "Edit a Current Paper" +msgstr "編輯論文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:86 +msgid "Delete a Paper" +msgstr "刪除論文" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:96 +msgid "Type:" +msgstr "類型:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:101 +msgid "Year of publication:" +msgstr "出版年:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:106 +msgid "Month of publication:" +msgstr "出版月:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:111 +msgid "Authors:" +msgstr "作者:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:117 +msgid "Tags:" +msgstr "標籤:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:123 +msgid "Publication:" +msgstr "刊物:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:128 +msgid "Pages:" +msgstr "頁數:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:133 +msgid "DOI.:" +msgstr "數位物件識別號:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper.pm:145 +msgid "APA citation:" +msgstr "APA 書目:" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:47 +msgid "Delete this researcher" +msgstr "刪掉這個研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:52 +msgid "This table provides you a form to add a new researcher." +msgstr "本表提供建新研究者的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:55 +msgid "This table provides you a form to update a current researcher." +msgstr "本表提供設定研究者的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:58 +msgid "This table provides you a form to delete a researcher." +msgstr "本表提供刪除研究者的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:75 +msgid "Add a New Researcher" +msgstr "建新研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:78 +msgid "Update a Current Researcher" +msgstr "編輯研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:81 +msgid "Delete a Researcher" +msgstr "刪除研究者" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:96 +msgid "Full name:" +msgstr "名字:" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:101 +msgid "Abbreviation:" +msgstr "縮寫:" + +#: magicat/lib/perl5/Selima/imacat/Form/Researcher.pm:112 +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:96 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:103 +msgid "[numerate,_1,Paper]:" +msgstr "論文:" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:47 +msgid "Delete this tag" +msgstr "刪掉這個標籤" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:52 +msgid "This table provides you a form to add a new tag." +msgstr "本表提供加新標籤的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:55 +msgid "This table provides you a form to edit a current tag." +msgstr "本表提供編輯標籤的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:58 +msgid "This table provides you a form to delete a tag." +msgstr "本表提供刪除標籤的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:75 +msgid "Add a New Tag" +msgstr "加新標籤" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:78 +msgid "Edit a Current Tag" +msgstr "編輯標籤" + +#: magicat/lib/perl5/Selima/imacat/Form/Tag.pm:81 +msgid "Delete a Tag" +msgstr "刪除標籤" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:38 +msgid "Select an Change Log Entry" +msgstr "選擇更新日誌" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:39 +msgid "Manage Change Log" +msgstr "管理更新日誌" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:50 +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:50 +msgid "Page No." +msgstr "頁數" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:58 +msgid "Write a new log entry." +msgstr "寫新日誌。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:64 +msgid "Search for a log entry:" +msgstr "搜尋日誌:" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:81 +msgid "Your query found [*,_1,log entry,log entries]." +msgstr "共 [#,_1] 則相符的日誌。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:84 +msgid "[*,_1,log entry,log entries]." +msgstr "共 [#,_1] 則日誌。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:90 +msgid "" +"Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則相符的日誌,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog.pm:94 +msgid "[*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則日誌,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:38 +msgid "Select a Diary Entry" +msgstr "選擇日記" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:39 +msgid "Manage Diary" +msgstr "管理日記" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:58 +msgid "Write a new diary entry." +msgstr "寫新日記。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:64 +msgid "Search for a diary entry:" +msgstr "搜尋日記:" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:81 +msgid "Your query found [*,_1,diary entry,diary entries]." +msgstr "共 [#,_1] 則相符的日記。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:84 +msgid "[*,_1,diary entry,diary entries]." +msgstr "共 [#,_1] 則日記。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:90 +msgid "" +"Your query found [*,_1,diary entry,diary entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則相符的日記,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: magicat/lib/perl5/Selima/imacat/List/Diary.pm:94 +msgid "[*,_1,diary entry,diary entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則日記,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:42 +msgid "Browse Mutual Fund Performances" +msgstr "瀏覽共同基金績效" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:52 +msgid "Name" +msgstr "名稱" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:53 +msgid "1m return" +msgstr "一個月報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:54 +msgid "1m ranking" +msgstr "一個月排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:55 +msgid "3m return" +msgstr "三個月報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:56 +msgid "3m ranking" +msgstr "三個月排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:57 +msgid "6m return" +msgstr "六個月報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:58 +msgid "6m ranking" +msgstr "六個月排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:59 +msgid "1y return" +msgstr "一年報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:60 +msgid "1y ranking" +msgstr "一年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:61 +msgid "2y return" +msgstr "兩年報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:62 +msgid "2y ranking" +msgstr "兩年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:63 +msgid "3y return" +msgstr "三年報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:64 +msgid "3y ranking" +msgstr "三年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:65 +msgid "5y return" +msgstr "五年報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:66 +msgid "5y ranking" +msgstr "五年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:67 +msgid "10y return" +msgstr "十年報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:68 +msgid "10y ranking" +msgstr "十年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:69 +msgid "This year return" +msgstr "今年報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:70 +msgid "This year ranking" +msgstr "今年排名" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:71 +msgid "Total return" +msgstr "自成立日報酬率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:72 +msgid "Begin from" +msgstr "基金成立日" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:73 +msgid "Best 3m return" +msgstr "最佳三個月報酬" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:74 +msgid "Worst 3m return" +msgstr "最差三個月報酬" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:75 +msgid "Standard deviation (12m)" +msgstr "標準差 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:76 +msgid "Standard deviation (24m)" +msgstr "標準差 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:77 +msgid "Beta (12m)" +msgstr "β (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:78 +msgid "Beta (24m)" +msgstr "β (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:79 +msgid "Sharpe (12m)" +msgstr "夏普指數 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:80 +msgid "Sharpe (24m)" +msgstr "夏普指數 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:81 +msgid "Jensen (12m)" +msgstr "詹森指數 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:82 +msgid "Jensen (24m)" +msgstr "詹森指數 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:83 +msgid "Treynor (12m)" +msgstr "崔納指數 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:84 +msgid "Treynor (24m)" +msgstr "崔納指數 (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:85 +msgid "Information Ratio (major categories) (12m)" +msgstr "資訊比例(大分類) (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:86 +msgid "Information Ratio (major categories) (24m)" +msgstr "資訊比例(大分類) (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:87 +msgid "Information Ratio (minor categories) (12m)" +msgstr "資訊比例(細分類) (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:88 +msgid "Information Ratio (minor categories) (24m)" +msgstr "資訊比例(細分類) (24m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:89 +msgid "This month turnover" +msgstr "當月週轉率" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:90 +msgid "12m turnover" +msgstr "累積週轉率 (12m)" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:91 +msgid "Duration" +msgstr "存續期間" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:92 +msgid "Rating" +msgstr "信用評等" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:93 +msgid "Manager less than 1y?" +msgstr "經理未滿一年?" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:98 +msgid "4433 Principle" +msgstr "4433 法則" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:163 +msgid "Search for a fund:" +msgstr "搜尋基金:" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:173 +msgid "Search" +msgstr "搜尋" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:199 +msgid "Advanced filter:" +msgstr "進階篩選條件:" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:250 +msgid "Your query found [*,_1,fund]." +msgstr "共 [#,_1] 筆相符的基金。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:253 +msgid "[*,_1,fund]." +msgstr "[#,_1] 筆基金。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:259 +msgid "Your query found [*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的基金,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: magicat/lib/perl5/Selima/imacat/List/Funds.pm:263 +msgid "[*,_1,fund], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆基金,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage.pm:38 +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:38 +msgid "Select a Message" +msgstr "選擇留言" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage.pm:39 +msgid "Manage Soundless Backalley" +msgstr "管理無聲的後巷" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:39 +msgid "Manage Travellers' Guestbook" +msgstr "管理旅人留言簿" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:42 +msgid "Specie" +msgstr "物種" + +#: magicat/lib/perl5/Selima/imacat/List/Guestbook.pm:43 +msgid "Language tag" +msgstr "語言標籤" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:38 +msgid "Select a English Literal Work" +msgstr "選擇英文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:39 +msgid "Manage English Literal Works" +msgstr "管理英文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:51 +msgid "Write a new English literal work." +msgstr "寫新英文寫作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:57 +msgid "Search for a English literal work:" +msgstr "搜尋英文寫作:" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:74 +msgid "Your query found [*,_1,English literal work]." +msgstr "共 [#,_1] 篇相符的英文寫作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:77 +msgid "[*,_1,English literal work]." +msgstr "共 [#,_1] 篇英文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:83 +msgid "Your query found [*,_1,English literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的英文寫作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralEn.pm:87 +msgid "[*,_1,English literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇英文寫作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:38 +msgid "Select a Chinese Literal Work" +msgstr "選擇中文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:39 +msgid "Manage Chinese Literal Works" +msgstr "管理中文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:51 +msgid "Write a new Chinese literal work." +msgstr "寫新中文寫作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:57 +msgid "Search for a Chinese literal work:" +msgstr "搜尋中文寫作:" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:74 +msgid "Your query found [*,_1,Chinese literal work]." +msgstr "共 [#,_1] 篇相符的中文寫作。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:77 +msgid "[*,_1,Chinese literal work]." +msgstr "共 [#,_1] 篇中文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:83 +msgid "Your query found [*,_1,Chinese literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的中文寫作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LiteralZh.pm:87 +msgid "[*,_1,Chinese literal work], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇中文寫作,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:38 +msgid "Select a Chinese Poem" +msgstr "選擇中文詩" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:39 +msgid "Manage Chinese Poems" +msgstr "管理中文詩" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:44 +msgid "Work set" +msgstr "寫作集" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:52 +msgid "Write a new Chinese poem." +msgstr "寫新中文詩。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:58 +msgid "Search for a Chinese poem:" +msgstr "搜尋中文詩:" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:75 +msgid "Your query found [*,_1,Chinese poem]." +msgstr "共 [#,_1] 首相符的中文詩。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:78 +msgid "[*,_1,Chinese poem]." +msgstr "共 [#,_1] 首中文詩" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:84 +msgid "Your query found [*,_1,Chinese poem], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 首相符的中文詩,列出第 [#,_2] 首到第 [#,_3] 首。" + +#: magicat/lib/perl5/Selima/imacat/List/LtZhPoem.pm:88 +msgid "[*,_1,Chinese poem], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 首中文詩,列出第 [#,_2] 首到第 [#,_3] 首。" + +#: magicat/lib/perl5/Selima/imacat/List/Pages.pm:37 +msgid "HTML class" +msgstr "HTML 類別" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:38 +msgid "Select a Paper" +msgstr "選擇論文" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:42 +msgid "Type" +msgstr "類型" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:43 +msgid "Year" +msgstr "年" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:44 +msgid "Month" +msgstr "月" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:47 +msgid "Publication" +msgstr "刊物" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:49 +msgid "DOI" +msgstr "數位物件識別號" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:57 +msgid "Add a new paper." +msgstr "建新論文。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:63 +msgid "Search for a paper:" +msgstr "搜尋論文:" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:80 +msgid "Your query found [*,_1,paper]." +msgstr "共 [#,_1] 篇相符的論文。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:83 +msgid "[*,_1,paper]." +msgstr "共 [#,_1] 篇論文。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:89 +msgid "Your query found [*,_1,paper], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的論文,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Papers.pm:93 +msgid "[*,_1,paper], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇論文,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:38 +msgid "Select a Researcher" +msgstr "選擇研究者" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:39 +msgid "Manage Researchers" +msgstr "管理研究者" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:42 +msgid "Abbreviation" +msgstr "縮寫" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:50 +msgid "Add a new researcher." +msgstr "建新研究者。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:56 +msgid "Search for a researcher:" +msgstr "搜尋研究者:" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:73 +msgid "Your query found [*,_1,researcher]." +msgstr "共 [#,_1] 位相符的研究者。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:76 +msgid "[*,_1,researcher]." +msgstr "共 [#,_1] 位研究者。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:82 +msgid "Your query found [*,_1,researcher], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位相符的研究者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Researchers.pm:86 +msgid "[*,_1,researcher], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位研究者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:45 +msgid "Full Text Search" +msgstr "全文檢索" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:46 +msgid "" +"

    Tavern IMACAT's

    \n" +"

    Full Text Search

    " +msgstr "" +"

    旅舍依瑪

    \n" +"

    全文檢索

    " + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:48 +msgid "Search Result" +msgstr "搜尋結果" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:49 +msgid "" +"

    Tavern IMACAT's

    \n" +"

    Search Result

    " +msgstr "" +"

    旅舍依瑪

    \n" +"

    搜尋結果

    " + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:72 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:100 +msgid "Please fill in your query." +msgstr "請填上檢索的辭彙。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:160 +msgid "Search in the website:" +msgstr "網站檢索:" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:177 +msgid "Your query found [*,_1,article]." +msgstr "共 [#,_1] 篇相符的文章。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:180 +msgid "[*,_1,article]." +msgstr "共 [#,_1] 篇文章。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:186 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:190 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:224 +msgid "Tavern Diary on [_1]" +msgstr "[_1] 旅舍日記" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:233 +msgid "Change Log on [_1]" +msgstr "[_1] 更新日誌" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:271 +msgid "English writings" +msgstr "英文寫作" + +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:281 +#: magicat/lib/perl5/Selima/imacat/List/Search.pm:290 +msgid "Guestbook Message on [_1]" +msgstr "[_1] 留言" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:38 +msgid "Select a Tag" +msgstr "選擇標籤" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:39 +msgid "Manage Tags" +msgstr "管理標籤" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:49 +msgid "Add a new tag." +msgstr "加新標籤。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:55 +msgid "Search for a tag:" +msgstr "搜尋標籤:" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:72 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:74 +msgid "Your query found [*,_1,tag]." +msgstr "共 [#,_1] 個相符的標籤。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:75 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:77 +msgid "[*,_1,tag]." +msgstr "共 [#,_1] 個標籤。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:81 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:83 +msgid "Your query found [*,_1,tag], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個相符的標籤,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: magicat/lib/perl5/Selima/imacat/List/Tags.pm:85 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:87 +msgid "[*,_1,tag], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個標籤,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:110 +msgid "This log entry was not modified." +msgstr "日誌未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:114 +msgid "This log entry has been successfully added." +msgstr "日誌寫好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:118 +msgid "This log entry has been successfully updated." +msgstr "日誌存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/ChangeLog.pm:122 +msgid "This log entry has been successfully deleted." +msgstr "日誌刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:109 +msgid "This diary entry was not modified." +msgstr "日記未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:113 +msgid "This diary entry has been successfully added." +msgstr "日記寫好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:117 +msgid "This diary entry has been successfully updated." +msgstr "日記存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Diary.pm:121 +msgid "This diary entry has been successfully deleted." +msgstr "日記刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:104 +msgid "This English literal work was not modified." +msgstr "英文寫作未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:108 +msgid "This English literal work has been successfully added." +msgstr "英文寫作寫好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:112 +msgid "This English literal work has been successfully updated." +msgstr "英文寫作存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralEn.pm:116 +msgid "This English literal work has been successfully deleted." +msgstr "英文寫作刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:188 +msgid "This Chinese literal work was not modified." +msgstr "中文寫作未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:192 +msgid "This Chinese literal work has been successfully added." +msgstr "中文寫作寫好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:196 +msgid "This Chinese literal work has been successfully updated." +msgstr "中文寫作存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LiteralZh.pm:200 +msgid "This Chinese literal work has been successfully deleted." +msgstr "中文寫作刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:102 +msgid "This Chinese poem was not modified." +msgstr "中文詩未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:106 +msgid "This Chinese poem has been successfully added." +msgstr "中文詩寫好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:110 +msgid "This Chinese poem has been successfully updated." +msgstr "中文詩存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/LtZhPoem.pm:114 +msgid "This Chinese poem has been successfully deleted." +msgstr "中文詩刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:293 +msgid "This paper was not modified." +msgstr "論文未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:297 +msgid "This paper has been successfully added." +msgstr "論文建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:301 +msgid "This paper has been successfully updated." +msgstr "論文存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper.pm:305 +msgid "This paper has been successfully deleted." +msgstr "論文刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:90 +msgid "This researcher was not modified." +msgstr "研究者未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:94 +msgid "This researcher has been successfully added." +msgstr "研究者建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:98 +msgid "This researcher has been successfully updated." +msgstr "研究者存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Researcher.pm:102 +msgid "This researcher has been successfully deleted." +msgstr "研究者刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:88 +msgid "This tag was not modified." +msgstr "標籤未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:92 +msgid "This tag has been successfully added." +msgstr "標籤建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:96 +msgid "This tag has been successfully updated." +msgstr "標籤存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Tag.pm:100 +msgid "This tag has been successfully deleted." +msgstr "標籤刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook/Public.pm:44 +msgid "Your specie is too long. (Max. length [#,_1])" +msgstr "妳的物種太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Guestbook/Public.pm:63 +msgid "Your e-mail is too long. (Max. length [#,_1])" +msgstr "妳的電子郵件信箱太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:73 +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:73 +msgid "Please select a paper." +msgstr "請選擇論文。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:94 +msgid "Please select a author." +msgstr "請選擇作者。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:97 +msgid "This author does not exist anymore. Please select another one." +msgstr "查無此作者,請改選其她作者。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Author.pm:118 +msgid "This paper author already exists. You cannot create a duplicated one." +msgstr "已有同一筆論文作者,請勿重複建檔。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:94 +msgid "Please select a tag." +msgstr "請選擇標籤。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:97 +msgid "This tag does not exist anymore. Please select another one." +msgstr "查無此標籤,請改選其她標籤。" + +#: magicat/lib/perl5/Selima/imacat/Checker/Paper/Tag.pm:118 +msgid "This paper tag already exists. You cannot create a duplicated one." +msgstr "已有同一筆論文標籤,請勿重複建檔。" + +#: magicat/lib/perl5/Selima/imacat/Form/Garbage/Public.pm:48 +msgid "I'm sick." +msgstr "我要吐了" + +#: magicat/lib/perl5/Selima/imacat/Form/Guestbook/Public.pm:42 +msgid "" +"General commercial advertisements are not welcomed and may be deleted at " +"once. HTML is not supported." +msgstr "旅人留言簿不歡迎一般商業廣告,隨見隨刪。不支援 HTML 留言。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:49 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:49 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:47 +msgid "Delete this type" +msgstr "刪掉這個類型" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:54 +msgid "This table provides you a form to add a new paper author." +msgstr "本表提供建新論文作者的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:57 +msgid "This table provides you a form to change a current paper author." +msgstr "本表提供編變更論文作者的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:60 +msgid "This table provides you a form to delete a paper author." +msgstr "本表提供刪除論文作者的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:77 +msgid "Add a New Paper Author" +msgstr "建新論文作者" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:80 +msgid "Change a Current Paper Author" +msgstr "變更論文作者" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:83 +msgid "Delete a Paper Author" +msgstr "刪除論文作者" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:93 +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:93 +msgid "Paper:" +msgstr "論文:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Author.pm:98 +msgid "Author:" +msgstr "作者:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:54 +msgid "This table provides you a form to add a new paper tag." +msgstr "本表提供建新論文標籤的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:57 +msgid "This table provides you a form to change a current paper tag." +msgstr "本表提供編變更論文標籤的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:60 +msgid "This table provides you a form to delete a paper tag." +msgstr "本表提供刪除論文標籤的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:77 +msgid "Add a New Paper Tag" +msgstr "建新論文標籤" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:80 +msgid "Change a Current Paper Tag" +msgstr "變更論文標籤" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:83 +msgid "Delete a Paper Tag" +msgstr "刪除論文標籤" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Tag.pm:98 +msgid "Tag:" +msgstr "標籤:" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:52 +msgid "This table provides you a form to add a new paper type." +msgstr "本表提供建新論文類型的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:55 +msgid "This table provides you a form to edit a current paper type." +msgstr "本表提供編輯論文類型的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:58 +msgid "This table provides you a form to delete a paper type." +msgstr "本表提供刪除論文類型的表單。" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:75 +msgid "Add a New Paper Type" +msgstr "建新論文類型" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:78 +msgid "Edit a Current Paper Type" +msgstr "編輯論文類型" + +#: magicat/lib/perl5/Selima/imacat/Form/Paper/Type.pm:81 +msgid "Delete a Paper Type" +msgstr "刪除論文類型" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog/Public.pm:136 +msgid "Date:" +msgstr "日期:" + +#: magicat/lib/perl5/Selima/imacat/List/ChangeLog/Public.pm:146 +msgid "The change log entry seperator" +msgstr "更新日誌分隔線" + +#: magicat/lib/perl5/Selima/imacat/List/Diary/Public.pm:146 +msgid "The diary entry seperator" +msgstr "日記分隔線" + +#: magicat/lib/perl5/Selima/imacat/List/Garbage/Public.pm:68 +msgid "The message entry seperator" +msgstr "留言分隔線" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:38 +msgid "Select a Paper Author" +msgstr "選擇論文作者" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:39 +msgid "Manage Paper Authors" +msgstr "管理論文作者" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:42 +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:42 +msgid "Paper" +msgstr "論文" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:43 +msgid "Author" +msgstr "作者" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:51 +msgid "Add a new paper author." +msgstr "建新論文作者。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:57 +msgid "Search for a paper author:" +msgstr "搜尋論文作者:" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:74 +msgid "Your query found [*,_1,author]." +msgstr "共 [#,_1] 位相符的論文作者。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:77 +msgid "[*,_1,author]." +msgstr "共 [#,_1] 位論文作者。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:83 +msgid "Your query found [*,_1,author], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位相符的論文作者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Authors.pm:87 +msgid "[*,_1,author], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位論文作者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:38 +msgid "Select a Paper Tag" +msgstr "選擇論文標籤" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:39 +msgid "Manage Paper Tags" +msgstr "管理論文標籤" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:43 +msgid "Tag" +msgstr "標籤" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:51 +msgid "Add a new paper tag." +msgstr "加新論文標籤。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Tags.pm:57 +msgid "Search for a paper tag:" +msgstr "搜尋論文標籤:" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:38 +msgid "Select a Paper Type" +msgstr "選擇論文類型" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:39 +msgid "Manage Paper Types" +msgstr "管理論文類型" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:49 +msgid "Add a new paper type." +msgstr "建新論文類型。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:55 +msgid "Search for a paper type:" +msgstr "搜尋論文類型:" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:72 +msgid "Your query found [*,_1,type]." +msgstr "共 [#,_1] 類相符的類型。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:75 +msgid "[*,_1,type]." +msgstr "共 [#,_1] 類類型。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:81 +msgid "Your query found [*,_1,type], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 類相符的類型,列出第 [#,_2] 類到第 [#,_3] 類。" + +#: magicat/lib/perl5/Selima/imacat/List/Paper/Types.pm:85 +msgid "[*,_1,type], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 類類型,列出第 [#,_2] 類到第 [#,_3] 類。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:97 +msgid "This paper author was not modified." +msgstr "論文作者未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:101 +msgid "This paper author has been successfully added." +msgstr "論文作者建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:105 +msgid "This paper author has been successfully updated." +msgstr "論文作者存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Author.pm:109 +msgid "This paper author has been successfully deleted." +msgstr "論文作者刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:97 +msgid "This paper tag was not modified." +msgstr "論文標籤未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:101 +msgid "This paper tag has been successfully added." +msgstr "論文標籤建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:105 +msgid "This paper tag has been successfully updated." +msgstr "論文標籤存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Tag.pm:109 +msgid "This paper tag has been successfully deleted." +msgstr "論文標籤刪掉了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:94 +msgid "This paper type was not modified." +msgstr "論文類型未異動。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:98 +msgid "This paper type has been successfully added." +msgstr "論文類型建好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:102 +msgid "This paper type has been successfully updated." +msgstr "論文類型存好了。" + +#: magicat/lib/perl5/Selima/imacat/Processor/Paper/Type.pm:106 +msgid "This paper type has been successfully deleted." +msgstr "論文類型刪掉了。" + +#~ msgid "Manage Accounting" +#~ msgstr "管理會計" + +#~ msgid "Reports" +#~ msgstr "報表" + +#~ msgid "Transactions" +#~ msgstr "傳票" + +#~ msgid "Subjects" +#~ msgstr "科目" + +#~ msgid "Records" +#~ msgstr "分錄" + +#~ msgid "Please fill in the publication." +#~ msgstr "請填上刊物。" + +#~ msgid "This URL is not reachable. Check if there is any typo in it." +#~ msgstr "這個網址連不上,請檢查有沒有拼錯。" diff --git a/htdocs/imacat/me/about.html.en.html b/htdocs/imacat/me/about.html.en.html new file mode 120000 index 0000000..da26c62 --- /dev/null +++ b/htdocs/imacat/me/about.html.en.html @@ -0,0 +1 @@ +about.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/about.html.en.xhtml b/htdocs/imacat/me/about.html.en.xhtml new file mode 100644 index 0000000..9824d35 --- /dev/null +++ b/htdocs/imacat/me/about.html.en.xhtml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + +About Tavern IMACAT’s + + + + + + + +
    + +
    + + +

    About Tavern IMACAT’s

    + +
    +imacat’s Private Bed♥room / About Tavern IMACAT’s +
    + +

    Introduction to Tavern IMACAT’s

    + +

    Tavern IMACAT’s is I, imacat, my personal website. It was started at March 9, 1998. I was original built on GeoCities (now acquired by Yahoo!), the largest non-profit on-line free home page community then. It was one of the few Taiwan Lesbian web sites at that time. After years of changes it is now settled on my home server, using GNU Debian Linux, Apache web server and my own Selima 2 content management system.

    + +

    Tavern IMACAT’s has no specific target or mission. It’s only mission is to be my personal website: Publishing my writings, sharing my essays, my knowledges, my experiences, and providing a stage for me.

    + + +

    Why Tavern?

    + +

    The reason I built a tavern is to create a feeling of warmness and comfort and to become a resting corner for the people going by. This may be relevant to my own experiences. People are often busy, here and there, under different preasure for different reason. Numerous people are passed by us day by day without our notice, that we are too busy give a minute to stop a while and say hello. Less than one-tenth of them are relevant to us even we are that close! How lonely we are! I would like Tavern to be a corner where people may stop from their business, put down their coolness, sit down and have a cup of hot tea or coffee, talk with people aside, acquainted or not, until when you feel you are ready for your next trip.

    + +

    In order to fullfill my requirements as to bring the feeling of warmness and comfort, I use warm colors as the main background. The background of Tavern is a piece of tartan. With a piece of tartan I would like to express a feeling like a bakery or a country restaurant. But it has a fatal disadvantage: Its contract is very low, and is a little difficult to read. I would like to say sorry if that does cause trouble to you.

    + +

    So, do you feel the warmness Tavern was trying to show you?

    + + +

    Tavern’s Design

    + +

    I, imacat, is the author of Tavern IMACAT’s. I’m a web programmer, not an art designer. I know nothing on the contract, hue, saturation, radian, ratio, bla bla bla. I don’t know how to use PhotoShop, PhotoImpact, DreamWeaver, FrontPage and Flash, either. I only know what I ought to know: Best web programming with best content. Many lesbians have professional art design training. They built really-pretty websites. I like their websites and admire their beautifulness. But that’s not me. I have my professional skills. Tavern IMACAT’s uses GNU free technology completely, follows strict XHTML 1.1/CSS2.1 standards, follows W3C Web Content Accessibility Guidelines, level Triple-A for the disables, follows RFC 2616 HTTP 1.1, using ISO 639/3109 language and country code standards… There are few websites in Taiwan (or even in the whole Chinese world) can meet these harsh standards. I have confidence to Tavern, because it’s built by myself.

    + +

    If, for this reason you feel upset on Tavern’s outlook, thinking Tavern is not pretty enough, I’m sorry. You may follow the links in Keep Travelling. There are many websites that meet your needs. But, if you like the simpleness of Tavern, the standard-conformance of Tavern, the easiness to visit Tavern with all kinds of tools, like its content, its warmness and its comfort, I would be very happy about it. ^_*'

    + + +
    By imacat 2.25.’05.
    + +
    + +
    + + + + diff --git a/htdocs/imacat/me/about.html.zh-cn.html b/htdocs/imacat/me/about.html.zh-cn.html new file mode 120000 index 0000000..bcf37a8 --- /dev/null +++ b/htdocs/imacat/me/about.html.zh-cn.html @@ -0,0 +1 @@ +about.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/about.html.zh-cn.xhtml b/htdocs/imacat/me/about.html.zh-cn.xhtml new file mode 100644 index 0000000..c531f5d --- /dev/null +++ b/htdocs/imacat/me/about.html.zh-cn.xhtml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + +关於旅舍依玛 + + + + + + + +
    + +
    + + +

    关於旅舍依玛

    + +
    +依玛猫的闺♥房 / 关於旅舍依玛 +
    + +

    旅舍依玛简介

    + +

    旅舍依玛是我依玛猫的个人网站。它创立於 1998 年 3 月 9 日,最初架设在当时最大的非营利网页社群 GeoCities 上(现已被 Yahoo! 收购),是当时台湾少数几个拉子网站之一。经历过许多变迁,目前旅舍架设在依玛猫自己家里的伺服器上,使用 Debian Linux 自由软体作业系统, Apache 网站伺服器,及依玛猫自己写的 Selima 2 内容管理系统运作。

    + +

    旅舍依玛没有什么特定的目标宗旨。唯一确定的目标就是作为我的个人网站,发表我自己写的东西,分享我的心情,分享我的知识经验,或做一些我想做的事。

    + + +

    我心目中的旅舍

    + +

    当初之所以会想做成旅舍,是想要塑造一种温暖的感觉,成为来来去去的人们,暂时歇脚休憩的角落。这可能也跟我的个性有关吧。人的一生,常常在各种压力、原因下,匆匆忙忙地过著忙碌的日子。每天,不知道有多少旁人,会和我们擦身而过,我们却连打一句招呼、问一声好的时间,都嫌奢侈。即使每天这么接近,我们却跟他们不到十分之一有关系。这样活著,好冷漠,好孤寂。我想像中的旅舍,是一个让人暂时歇脚的地方,从日常生活的匆忙和冷漠中,暂时停下脚步,坐下来,喝杯热茶或咖啡,暖暖身子,和身边认识或不认识的人说说话。等自己觉得休息够了,再重新出发。

    + +

    为了满足我想要的温暖的感觉,我用暖色系作为旅舍主要的背景。旅舍的背景图是一张格子花布,我想透过暖色系的格子花布,传达出一种面包店、乡村餐厅的气氛。可是暖色系有一个致命缺点,就是对比很低,阅读起来比较吃力。这是没有办法的事,我只好跟大家说声抱歉。

    + +

    你觉得,旅舍有给你温暖的感觉吗?

    + + +

    关於旅舍的设计

    + +

    旅舍的设计师是我,依玛猫。我是一个网站程式设计师,不是一个网站美术设计师。对於对比、色调、饱和度、弧度、比例等等问题, PhotoShop 、 PhotoImpact 、 DreamWeaver 、 FrontPage 、 Flash 的用法,我完全不懂。我只懂我该懂的:写最好的网站程式,放上最好的内容。有很多拉子网站,很多拉子是学美术设计、广告设计的,网站都非常赏心悦目(例如 AD 、关旎思)。我很羡慕,也很喜欢她们美丽的网站。不过我就是我。我有我的专业领域:旅舍依玛完全使用 GNU 自由软体,符合严格的 XHTML 1.1/CSS2.1 标准,符合 W3C 为身心障碍者制定的无障碍网页规范 WCAG最高等级 3A 级,符合 RFC 2616 HTTP 1.1 通讯协定的标准,使用 ISO 639/3109 语言与国码标准…等等。这些严苛的标准,我相信台湾(甚至整个中文世界)没有几个网站做得到。我对旅舍有信心,因为这是我亲手打造出来的地方。

    + +

    如果你因为这样,觉得旅舍不好看,造成你的困扰,那很抱歉。台湾有很多美丽的女同志网站,你不妨从继续旅行处走访一圈,一定可以找到你喜欢的网站。然而,如果你喜欢这样简单,符合标准,便於以各种方式阅读的旅舍,喜欢旅舍的文字内容,喜欢旅舍温暖的感觉,那我也会觉得很高兴。 ^_*'

    + + +
    依玛猫 2.25.’05.
    + +
    + +
    + + + + diff --git a/htdocs/imacat/me/about.html.zh-tw.html b/htdocs/imacat/me/about.html.zh-tw.html new file mode 120000 index 0000000..5a28364 --- /dev/null +++ b/htdocs/imacat/me/about.html.zh-tw.html @@ -0,0 +1 @@ +about.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/about.html.zh-tw.xhtml b/htdocs/imacat/me/about.html.zh-tw.xhtml new file mode 100644 index 0000000..7924db1 --- /dev/null +++ b/htdocs/imacat/me/about.html.zh-tw.xhtml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + +關於旅舍依瑪 + + + + + + + +
    + +
    + + +

    關於旅舍依瑪

    + +
    +依瑪貓的閨♥房 / 關於旅舍依瑪 +
    + +

    旅舍依瑪簡介

    + +

    旅舍依瑪是我依瑪貓的個人網站。它創立於 1998 年 3 月 9 日,最初架設在當時最大的非營利網頁社群 GeoCities 上(現已被 Yahoo! 收購),是當時台灣少數幾個拉子網站之一。經歷過許多變遷,目前旅舍架設在依瑪貓自己家裏的伺服器上,使用 Debian Linux 自由軟體作業系統, Apache 網站伺服器,及依瑪貓自己寫的 Selima 2 內容管理系統運作。

    + +

    旅舍依瑪沒有什麼特定的目標宗旨。唯一確定的目標就是作為我的個人網站,發表我自己寫的東西,分享我的心情,分享我的知識經驗,或做一些我想做的事。

    + + +

    我心目中的旅舍

    + +

    當初之所以會想做成旅舍,是想要塑造一種溫暖的感覺,成為來來去去的人們,暫時歇腳休憩的角落。這可能也跟我的個性有關吧。人的一生,常常在各種壓力、原因下,匆匆忙忙地過著忙碌的日子。每天,不知道有多少旁人,會和我們擦身而過,我們卻連打一句招呼、問一聲好的時間,都嫌奢侈。即使每天這麼接近,我們卻跟他們不到十分之一有關係。這樣活著,好冷漠,好孤寂。我想像中的旅舍,是一個讓人暫時歇腳的地方,從日常生活的匆忙和冷漠中,暫時停下腳步,坐下來,喝杯熱茶或咖啡,暖暖身子,和身邊認識或不認識的人說說話。等自己覺得休息夠了,再重新出發。

    + +

    為了滿足我想要的溫暖的感覺,我用暖色系作為旅舍主要的背景。旅舍的背景圖是一張格子花布,我想透過暖色系的格子花布,傳達出一種麵包店、鄉村餐廳的氣氛。可是暖色系有一個致命缺點,就是對比很低,閱讀起來比較吃力。這是沒有辦法的事,我只好跟大家說聲抱歉。

    + +

    妳覺得,旅舍有給妳溫暖的感覺嗎?

    + + +

    關於旅舍的設計

    + +

    旅舍的設計師是我,依瑪貓。我是一個網站程式設計師,不是一個網站美術設計師。對於對比、色調、飽和度、弧度、比例等等問題, PhotoShop 、 PhotoImpact 、 DreamWeaver 、 FrontPage 、 Flash 的用法,我完全不懂。我只懂我該懂的:寫最好的網站程式,放上最好的內容。有很多拉子網站,很多拉子是學美術設計、廣告設計的,網站都非常賞心悅目(例如 AD 、關旎思)。我很羨慕,也很喜歡她們美麗的網站。不過我就是我。我有我的專業領域:旅舍依瑪完全使用 GNU 自由軟體,符合嚴格的 XHTML 1.1/CSS2.1 標準,符合 W3C 為身心障礙者制定的無障礙網頁規範 WCAG最高等級 3A 級,符合 RFC 2616 HTTP 1.1 通訊協定的標準,使用 ISO 639/3109 語言與國碼標準…等等。這些嚴苛的標準,我相信台灣(甚至整個中文世界)沒有幾個網站做得到。我對旅舍有信心,因為這是我親手打造出來的地方。

    + +

    如果妳因為這樣,覺得旅舍不好看,造成妳的困擾,那很抱歉。台灣有很多美麗的女同志網站,妳不妨從繼續旅行處走訪一圈,一定可以找到妳喜歡的網站。然而,如果妳喜歡這樣簡單,符合標準,便於以各種方式閱讀的旅舍,喜歡旅舍的文字內容,喜歡旅舍溫暖的感覺,那我也會覺得很高興。 ^_*'

    + + +
    依瑪貓 2.25.’05.
    + +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0001.html.en.html b/htdocs/imacat/me/changelog/0001.html.en.html new file mode 120000 index 0000000..57710c1 --- /dev/null +++ b/htdocs/imacat/me/changelog/0001.html.en.html @@ -0,0 +1 @@ +0001.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0001.html.en.xhtml b/htdocs/imacat/me/changelog/0001.html.en.xhtml new file mode 100644 index 0000000..156f8cc --- /dev/null +++ b/htdocs/imacat/me/changelog/0001.html.en.xhtml @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 1 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 1

    + +
    + +
    + +
    +
    Date: 7.3.’00.
    + +

    Yes! HyperText Playground has finally been finished! I was limited to ASP/VBScript version due to the 2-bytes Chinese problem. Now I've made the Perl and JavaScript version, successfully deal with 2-bytes Chinese by Perl! ^_*'

    + +

    And, HyperText Playground was limited to MSIE and Chinese in the past. Now I've made it available for English, and available for Netscape, too!

    + +
    + +
    + +
    +
    Date: 7.1.’00.
    + +

    Ah ha… I’ve finally finished the new Tavern Diary. After this reformation, I should write Tavern Diary more often. :p

    + +

    The new Tavern Diary has fullfilled my plan -- as my personal guestbook. This is better. It’s easier to note Tavern Diary. I don’t have to fight with HTML codes anymore.

    + +

    As a result, in the 6th reversion of Tavern, I have finally decided the main structure of Tavern website: Simplify web pages, while conserve the advantage to maintain website with database.

    + +

    The basic concepts of CGI are: Save contents in database, while compose and show pages with CGI programs. This can ease the work of website maintainance. The webmaster doesn’t have to rewrite lots of pages for one update. I can use one program to save the contents, while use another program to show the contents.

    + +

    But in fact, most of the contents in Tavern IMACAT’s are static, which don’t need CGI/ASP to produce each time. Tavern IMACAT’s was fully CGI/ASP’s before, which decrease speed and increase unnecessary system burden.

    + +

    Now Tavern are composed parts with CGI programs, parts with static HTML pages proDuced by CGI programs. I choose CGI instead of ASP because the portability to bring website onto any web server. (MS IIS, Domino, Apache… etc.) Building static HTML pages with CGI programs is technically harder, but it’s a more effecient method.

    + +

    Another advantage to use parts with CGIs and parts with HTMLs is the ability to control the executive range of the website, which can increase the site security.

    + +

    Other minor changes includes:

    + +

    Modulized CGI to ease the CGI maintainance.

    + +

    The usage of JavaScript and Dynamic HTMLs to decrease server burden and strengthen the site maintainance ability.

    + +

    The WOV mailing daemon is done. It will not be a hell to send newsletters anymore.

    + +

    Also I’ve done a pretty categorizing engine for relative links, which can define categorizing system, go into several levels of subdirectories, and produce the necessary subfolders and HTML pages. And the relative links’ database of Tavern is seperated with WOV’s Women Interconnect database now. Besides, in the past I was unable to give a good title and description for the relative links. I’ve got a better title now. Although I’m not satisfied yet, it shall be more clear then ever.

    + +
    + +
    + +
    +
    Date: 2.14.’00.
    + +

    The only reason of this 5th reversion is that SCCID server has problems: It cannot execute Perl/CGI well, and I cannot log in. After 2 months of failed aggociation with SCCID crews, and unability to find another free UNIX CGI-enabled server, I had to move Tavern and WOV to an NT server currently administrated by myself. After all Perl/CGI is developed on UNIX, which has lots of problems under NT/Win32, I'd have to reversion Tavern from CGI into ASP.

    + +

    At the same time I was forced to think more seriously about the issue of website building and homepage writing: What is a page? What is a well-structured doculment? What is a well-structured program? What is a highly-portable database? Many of them had never come to me before. For example: What kind of database should be used for links' data? Should I use UNIX internal database? Or Access database which is the most common database in Windows environments? Or the hottest SQL? Which has the highest portability, that can still be available if someday Tavern has to move to UNIX server again?

    + +

    All of them had never come to me before. Thus, while SCCID UNIX server got wrong, I almost could do nothing but stared on those distored data which can only be understood by UNIX.

    + +

    Now I use CSV - Comma Seperated Values data sheets. This is plain text data format, with each record one line, data seperated by commas. Plain text can ensure the ability to be read in all kinds of environments. Although with plain text programs have to become much more complex and longer, but I'll never be helpless staring on distored data, like what had happened just now. Furthormore, .CSV files can be processed with Excel. So I can use Excel to make more complex executions, like sorting, searching, debugging, etc.

    + +

    Besides, I decided to mark the relative informations (like date, title, subject, description, etc.) on the <HEAD> portion of each page, letting programs to read them. Then I won't have to employ one more database, which can save shorter file list. Furthormore, keep informations with their pages will ease the works taken while I maintain them.

    + +

    Talking about shorten the file lists, now I categoried the files, putting different sort of files in different folders. Now it's clearer for me to maintain.

    + +

    And, I planned to write a program to automatically transform all the contents of Tavern together into pure HTML. Mandy is right. Depend too much on CGI/ASP is dangerous. If someday this server is down, or for some reason it cannot run CGI/ASP anymore, I'll have to reversion day after day again.

    + +

    Besides of what listed above, the most important part is that Tavern has finally become a website, not just homepages. Now Tavern is build on a WHOLE virtual NT server. That's the most exciting thing of all. ^_*'

    + +
    + +
    + +
    +
    Date: 8.8.’99.
    + +

    Actually, the previous (3rd) revision of Tavern was not finished. Only the Tavern Lobby, Travellers' Guestbook and Me!! are done. I was then exhausted, and Tavern is desolated for a lone time.

    + +

    This is the 4th revision, for Tavern is moved. GeoCities is less and less friendly after aquired by Yahoo!. Not only the site name, but also the account, free e-mail address, e-mail privilege, mail server, ftp server and the ugly Yahoo! GeoCities Watermark were changed to be merging into Yahoo! member database. imacat became imacat.geo, for there's already another imacat in Yahoo!'s members, and this account is duplicated. That's bullshit! I was the imacat there in GeoCities. I would never ever want to be imacat1999 or so. The previous experience between SCCID and WOV was a success. So I ask the permission from SCCID and move Tavern completely here.

    + +

    The most important point of the 4th revision is the employment of Perl/CGI. SCCID enables Perl/CGI. So I employ what I've learned from the producing of WOV. With Perl/CGI, I can make different HTML with different versions of IE / Netscape, solving the problem that IE and Netscape employs different typesettings. That is the most rediculous part of old Tavern, and the reason the last revision broke off: I support Best View With AnyBrowser, but I can't even have the same effect with Netscape and IE.

    + +

    Not only the typesetting problem is solved. I've made a new Travellers' Guestbook which is more like a guestbook, which I don't have to work up on it like a donkey. The maintenance is easier. The linkings become a small search engine. The Last Update is calculated automatically. It's all for CGI.

    + +
    + +
    + +
    +
    Date: 11.9.’98.
    + +

    This should be the 3rd reversion of Tavern. The first release of Tavern is done by March, which has only plain text without any graphics. At that time I still held the tradition of plain text of DOS, without any tools and experiences handling graphics. In addition I had seen too many homepages which uses lots of pretty graphics, which at last turns into nightmares when transferring their contents on the internet. Then I became repellent to graphical presentations, preferring a web page which lacks representations but is full of contents.

    + +

    The 2nd version were made at the end of March. The key point is the use of graphic tools. I started to practice computer graphing, trying simple functions and bitmap drawings, and made one graphic and another. Because of my background as a student of math dep., I tried several 3D graphics with complex calculating. The greatest result is a black-green background, which looks like the green bamboo in the deep night. I took it as the background of the Tavern Lobby. If you are an old friend of Tavern, maybe you are familiar with it. It does not exist now. I took it away because it conflicted with the atmosphere I wanted for Tavern. It is too cold, too isolated. I wanted travellers to feel Tavern warm. It took a long time for me to make this decision.

    + +

    Finally I chose this as the background. The inspiration is from the texture of cloth pieces, which can be seen often on the desks of some old-fashion restaurants. The manufacture was much simpler, and the warm colors produce warm feelings. I had fixed it once, deepered its color to make clearer text. At the same time I had made backgrounds for other pages, the huge black cat logo on the cover, the little black cat for options, the linking animation icon, etc.. From then on Tavern has lots of different graphics, here and there, and a huge black cat started to stand at the entrance of Tavern, which had scared lots of guests. ^_*'

    + +

    I had tried but failed to make another revision at April. The main idea then was to turn the Tavern completely into an image map: Make the cover into a picture of the Tavern Lobby, which allows travellers to click herself where she wishes to enter. But finally I gaved up because the calculation of the lobby space is too complex.

    + +

    The key to this 3rd revision, as I had said hundreds of times in other pages, is to employ HTML 4.0 & CSS1. The point is to separate the contents from the representations. That structuralized the ontent of a page, and extends the designing limits of the representation. To use style sheets solves the structural disorders which had bothered me for such a long time, at the same time making the looks of Tavern more charming then ever without having to employ more graphics.

    + +
    + +
    + +
    +
    Date: 5.4.’98.
    + +

    In fact, most topics about this homepage are already told in many places: I put in Travellers' Guestbook the reason why I made it a tavern, and in my private bedroom the feelings when I wrote this homepage. What is below are things not told in other places.

    + +

    I do not put many graphic effects, but instead I put a lot of texts. Actually It's against the fashion: Nobody wants to read texts now. People love cool graphic effects. But who cares? I'm nothing but a text worker, and may be a text worker for the lifetime. That's me. I'm very noisy. I speak a lot, write a lot. It's up to you.

    + +

    Another reason I do not put graphics is: Graphics are troublesome. I'm too lazy to download graphic libraris from FTP sites. Besides, graphic libraries have copyright problem. To choose one from thousands in graphic libraries is another thing causes my headache. Its troublesome to build my own graphic library, too. I have no scanner, nor good graphic software. I'm no talent of art as of text.

    + +

    But these are not the main problem. The most important problem is: Graphics are too slow! I live in Taiwan, but GeoCities is in AMERICA!! The transfer time of merely one graphic is equal to about one thousand of words! What will I choose?

    + +

    But I've still put some graphics. You can see that all the background graphics of all pages are made solely by me. I'm very proud of it. So I still build a small graphic library of my own. It would be too poor if even the background are monochrome. With background graphics and plain text typeset, I think I can make a beautiful result, too.

    + +

    Another thing is: I insist to make it dual-language. After all these pages resides in GeoCities. I could not make something GeoCities cannot recognize. That is the basic feedback. And I can identify the ideal of GeoCities in some practice. I can practice my English here, too. It would be great if I can get foreign friends from this.

    + +

    Therefore, while I'm writing most of the texts, I unconsciously consider about English grammar. I'm not writing standard Chinese grammar, but they are still easily read. Hence, I can translate them into english easily.

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 1 | + 2 | + 3 | + 4 | + 5 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0001.html.zh-cn.html b/htdocs/imacat/me/changelog/0001.html.zh-cn.html new file mode 120000 index 0000000..2940024 --- /dev/null +++ b/htdocs/imacat/me/changelog/0001.html.zh-cn.html @@ -0,0 +1 @@ +0001.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0001.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0001.html.zh-cn.xhtml new file mode 100644 index 0000000..e670896 --- /dev/null +++ b/htdocs/imacat/me/changelog/0001.html.zh-cn.xhtml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷一 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷一

    + +
    + +
    + +
    +
    日期: 7.3.’00.
    + +

    超文字游乐场终于完工罗!耶!我以前以为只能写 ASP/VBScript 版本(因为 VBScript 直接支援中文双码文字),现在已经完成 Perl 版本和 JavaScript 版本,成功用 Perl 处理双码中文的问题罗~! ^_*'

    + +

    藉此机会,以前超文字游乐场一直受限于只能用 IE 浏览,而且只能秀中文。现在我不但成功把它英文化,也写出 Netscape 的版本罗!

    + +
    + +
    + +
    +
    日期: 7.1.’00.
    + +

    呵…新的旅舍日记终於完成罗。改成这样了以后。我应该会比较勤於记日记吧。 :p

    + +

    新的旅舍日记,实现了我之前规划的梦想—变成我的个人留言本。这样比较好,记旅舍日记方便得多了,不用再和一堆 HTML 码奋斗。

    + +

    整体而言,旅舍第六次改版,我终於决定了旅舍网站的主要结构,让旅舍的网页简单化,又能保留使用资料库来维护的优点。

    + +

    CGI 基本的运作是:使用资料库来储存内容,网页则用程式去读取资料,再组合而成秀出来。这种作法可以让网站维护工作变得更容易,不用每次网站更新就要重写一大堆网页。我可以用一个程式来储存内容,用另一个程式来秀内容。

    + +

    然而,旅舍网站大部份的内容都是固定的,不需要每次都用 CGI/ASP 程式来秀。过去旅舍全站都用 CGI/ASP 程式来秀,不但降低速度,也增加无谓的网站负担。

    + +

    现在旅舍部份使用 CGI 程式,部份是由 CGI 程式制作的固定 HTML 网页。使用 CGI 弃用 ASP 的原因是移植方便,可以在各种 web 伺服器上运作( MS IIS, Domino, Apache 等)。固定 HTML 网页由 CGI 程式制作并存档。这样做难度比较高,却是比较有效率的作法。

    + +

    另一个部份 CGI 部份 HTML 的好处是:可以管制网站的可执行范围,增加网站的安全性。

    + +

    其她的小改变包括了:

    + +

    CGI 程式模组化,可以简化 CGI 程式的维护工作。

    + +

    开始使用 JavaScript 和 Dynamic HTML 的技术,可以减少网站的负荷,并强化网站管理的能力。

    + +

    《女声》的发报程式做出来了。以后就不用发报发得很辛苦了。

    + +

    我还写了一个很炫的网站连结分类引擎,可以自定分类系统,往下分好几层子目录,制作需要的资料夹和 HTML 网页。相关网站连结的资料库也和《女声》的女网牵手资料库分开了。此外,相关网站区过去一直找不到一个适当的标题,写不出适当的感觉。这次我也终於想出了个比较好的标题,虽然这个标题还是下得很烂,可是定位比以前清楚多了。

    + +
    + +
    + +
    +
    日期: 2.14.’00.
    + +

    旅舍第五次改版,改版的原因是南方的主机出了问题,无法执行 CGI ,也无法登入,经过了两个多月与南方编辑部协调未果,又找不到另一台可执行 CGI 的免费 UNIX 主机以供迁站下,只好将女声与旅舍同时紧急搬迁到一台依玛自己管理的 NT 主机上。因为在 CGI 毕竟是在 UNIX 下发展的环境,在 NT/Win32 下执行有许多困难,因此被迫一定要将 CGI 程式改写成 ASP 程式。

    + +

    改版的同时,我被迫更严谨地思考网站建置和网页写作的问题。何谓一页?何谓一个结构完整的文件?何谓一个结构完整的程式?何谓一个具有高可携性的资料库?很多问题,是这次改版以前没想过的。例如:连结的部份该用何种资料库呢?要用 UNIX 内建资料库吗?还是该用 Windows 最常用的 Access 资料库?还是最热门的 SQL ?何者具有最高相容性和可携性,可以在万一旅舍主程式又要搬到 UNIX主机时,仍可使用?

    + +

    这些,都是之前没想过的问题。因此当南方的 UNIX 主机出问题后,我只能在 98 中望著一堆只有 UNIX 下才看得懂的乱码欲哭无泪,想救资料又不知从何救起。

    + +

    现在我用的是 CSV 逗号分隔值资料表。这是纯文字资料格式,每笔资料一行,资料间以逗号分开。纯文字可以保证任何环境下皆能读取。虽然这样程式要写得很复杂很长,但至少不会再发生南方当机后,我在 98 中望著 UNIX 资料库乱码欲哭无泪的情形。 .CSV 档案可以用 Excel 开启,因此我还可以用 Excel 来做比较复杂的处理,如排序、搜寻、除错等等。

    + +

    另外,我决定将主要的相关内容资讯(如旅舍日记的日期、每篇诗的标题、简短介绍等等),写在网页标头 <HEAD> 部份,然后让程式来读取网页标头资讯。这样就不必用到资料库了,也可以让档案少一点,且让资料跟著网页跑,也减少维护上的困难。

    + +

    关于让档案少一点的部份,现在我把档案分门别类存放,图档、样式表都放在不同的资料夹,所以现在维护起来乾净清楚多了。

    + +

    还有。我打算写一个程式,可以把旅舍的内容自动一口气全部转为纯 HTML 。小招说得对,整个网站全部倚赖 CGI/ASP 程式实在是太危险了,万一哪天网站又再挂掉不能跑 CGI/ASP,要再改版又会欲哭无泪。

    + +

    除此以外,最重要的是,旅舍终于成为一个完整的网站了,而不只是网页。现在旅舍架在一整部虚拟主机上。这是最让我兴奋的。 ^_*'

    + +
    + +
    + +
    +
    日期: 8.8.’99.
    + +

    其实旅舍前一次(第三次)改版没有完成,只有做出旅舍大厅、旅人留言本和我三个部份而已,就没有力气做了。后来,旅舍就荒废了好一阵子。

    + +

    这是旅舍第四次改版,改版的原因是因为旅舍搬家了。因为被 Yahoo! 并吞后的 GeoCities 对会员越来越不友善,不但网站名称,连会员帐号、免费 E-mail 、送信权限、邮件主机、丑丑的 Yahoo! GeoCities 浮水印都为了跟 Yahoo! 会员资料库合并而被迫改变。 imacat 变成 imacat.geo ,因为 Yahoo! 有一个叫做 imacat 的会员,帐号重复。去你的!我死也不当 imacat1999 !之前《女声》电子报和南方人文网站的合作愉快,于是我徵求南方同意,将整个旅舍依玛搬迁到南方。

    + +

    第四次改版最重要的是 Perl/CGI 的应用。南方容许 Perl/CGI 。我将之前做《女声》学到的技术,应用在旅舍上。有了 CGI 程式,可以对不同版本 IE / Netscape 分别做不同的页面,解决了 IE / Netscape 页面排版不同的问题。这是旧旅舍最可笑的地方,也是第三次改版到一半中断的原因:支持建议使用任何浏览器,可是连 Netscape 和 IE 下的效果都不一致。

    + +

    现在不仅解决页面排版问题,也做出了一个更像留言簿的旅人留言簿,还不用整理得半死。旅舍的维护也变得更方便了,对外连结变成一个小型的搜寻引擎,最近更新日期也能自动计算。这些都要归功于 CGI

    + +
    + +
    + +
    +
    日期: 11.9.’98.
    + +

    这算是旅舍的第三次改版了。今年三月初做出来旅舍初版,只有文字没有图型。当时抱持著 DOS 的纯文字传统,加上自己处理图形的工具和经验都有限,再加上看了太多别人的网页用上一大堆漂漂的图档,到最后却读得很慢的案例,就很讨厌、很排斥用美工图形,宁可做一个没有什么外观,文字内容却很充实的网页。

    + +

    第二次改版是三月底的事。当时的关键则是在于绘图程式的运用。我开始练习电脑绘图,利用绘图程式的简易功能和小画家描点法来作出一个又一个的图来。因为数学系毕业的背景,我开始尝试透过计算制作一些 3D 光影的图。当时的作品中最漂亮的是一张绿黑色的背景图,看起来像深夜里的绿竹林一样幽幽的。我把它拿来作旅舍大厅的背景用。如果你是旅舍的老顾客的话,也许你还会记得那个背景。可惜现在已经不在了。把它拿掉的原因是因为和我想要的旅舍气氛不合。它太冷、太孤寂了,而我希望旅舍给孤独的旅人们暖暖的感觉。拿掉的时候还决定了很久,很舍不得呢!

    + +

    最后我选择了这张背景图。它的灵感是来自碎花布的布料纹路,常常可以在复古的餐馆桌上看得到的那种。这张背景图做起来简单得多了,暖色系带给人温暖的感觉。后来我修了一次,加深颜色使文字看得清楚些。同时我做出了其它各页用的背景图,封面那只很大的黑猫,选项用的小黑猫,连结用的动画小图等等。从那时开始旅舍有了一堆大大小小的图;也是从那时开始,一进旅舍开始冒出了只大黑猫,把很多人都吓到了。 ^_*'

    + +

    四月初时曾经想再改一次版,可是没有做出来。当时最主要的构想是想把整个旅舍做成一个image map,把整个旅舍封面做成一张旅馆大厅的图,旅人们可以自己点选想去的地方进去。可是后来因为空间的计算太复杂而作罢。

    + +

    第三次改版,就像我在很多地方都说过很多次的,最主要的关键是应用了 HTML 4.0 和 CSS1 的标准。最重要的就是把网页内容网页外观分开,使网页内容结构化,也使得网页外观的设计更自由,更丰富。使用 Style Sheets 解决了原本就令我头痛不已的结构混乱、毫无章法的问题,同时,在不增加图档的情况之下,反而使得网页的外观意外地漂亮了很多。

    + +
    + +
    + +
    +
    日期: 5.4.’98.
    + +

    其实,关于这个网页中的很多事,在网页里的其他地方都已经说过了:关于为什么我把它做成一个旅舍,在旅人留言簿的引言里有说;关于写这个网页的一些心情和想法,则记在我的主卧室里。这里所记的,是一些在其他地方没写到的。

    + +

    我没有放很多图片,而放了大量的文字。这其实是很违反潮流的。这个时代没有人看文字了,大家都爱看炫炫的图。可是管它的!我没别的长处,这辈子大概只能够做文字工作者了。这就是我。我很罗唆,话很多,字也很多,你不爱看就算了。

    + +

    另一个我不放图的原因是:图实在是太麻烦了。我是很懒得去 FTP 站下载人家的图库的。而且用别人的图库还有版权问题,一想到就很头痛。要从图库里几百个图中选一个来用对处女座求完美的我来说更是头痛的事,看一两百个就昏了。自己做图库则很麻烦,我没有扫描器,也没有很棒的制图软体,美术天份又不如文字天份好。

    + +

    不过这些都不是主因。最重要的原因是:太慢了! GeoCities 在美国耶!我多放三千个字的传送速度等于放一张图而已,我当然选择放文字了!

    + +

    可是我还是放了一些图。每一个画面的背景图都是我自己画出来的,这是我很得意的事。所以我还是建立了我自己的小图库。我觉得如果连背景都是单色的,那就太寒酸了。我想凭著背景图和文字的排版,我还是能把它做得很漂亮的。

    + +

    还有一件事是:我对双语的坚持。毕竟这个网页是建在 GeoCities 。人家提供的资源,不好意思做些连人家都看不懂的东西,这是我认为一些基本的回馈。我还蛮认同 GeoCities 的理想的。而且还可以练习久已生疏的英文。此外,如果能够因此而交到一些来自异地的朋友,就太好了。

    + +

    因此,我写大部份的文字时,都会不自觉顾虑到英文的语法。我写出来的不是很标准的中文语法,可是还是很容易阅读的。于是,我可以很容易地翻译成英文。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 1 | + 2 | + 3 | + 4 | + 5 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0001.html.zh-tw.html b/htdocs/imacat/me/changelog/0001.html.zh-tw.html new file mode 120000 index 0000000..2fca0e8 --- /dev/null +++ b/htdocs/imacat/me/changelog/0001.html.zh-tw.html @@ -0,0 +1 @@ +0001.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0001.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0001.html.zh-tw.xhtml new file mode 100644 index 0000000..663fd7d --- /dev/null +++ b/htdocs/imacat/me/changelog/0001.html.zh-tw.xhtml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷一 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷一

    + +
    + +
    + +
    +
    日期: 7.3.’00.
    + +

    超文字遊樂場終於完工囉!耶!我以前以為只能寫 ASP/VBScript 版本(因為 VBScript 直接支援中文雙碼文字),現在已經完成 Perl 版本和 JavaScript 版本,成功用 Perl 處理雙碼中文的問題囉~! ^_*'

    + +

    藉此機會,以前超文字遊樂場一直受限於只能用 IE 瀏覽,而且只能秀中文。現在我不但成功把它英文化,也寫出 Netscape 的版本囉!

    + +
    + +
    + +
    +
    日期: 7.1.’00.
    + +

    呵…新的旅舍日記終於完成囉。改成這樣了以後。我應該會比較勤於記日記吧。 :p

    + +

    新的旅舍日記,實現了我之前規劃的夢想—變成我的個人留言本。這樣比較好,記旅舍日記方便得多了,不用再和一堆 HTML 碼奮鬥。

    + +

    整體而言,旅舍第六次改版,我終於決定了旅舍網站的主要結構,讓旅舍的網頁簡單化,又能保留使用資料庫來維護的優點。

    + +

    CGI 基本的運作是:使用資料庫來儲存內容,網頁則用程式去讀取資料,再組合而成秀出來。這種作法可以讓網站維護工作變得更容易,不用每次網站更新就要重寫一大堆網頁。我可以用一個程式來儲存內容,用另一個程式來秀內容。

    + +

    然而,旅舍網站大部份的內容都是固定的,不需要每次都用 CGI/ASP 程式來秀。過去旅舍全站都用 CGI/ASP 程式來秀,不但降低速度,也增加無謂的網站負擔。

    + +

    現在旅舍部份使用 CGI 程式,部份是由 CGI 程式製作的固定 HTML 網頁。使用 CGI 棄用 ASP 的原因是移植方便,可以在各種 web 伺服器上運作( MS IIS, Domino, Apache 等)。固定 HTML 網頁由 CGI 程式製作並存檔。這樣做難度比較高,卻是比較有效率的作法。

    + +

    另一個部份 CGI 部份 HTML 的好處是:可以管制網站的可執行範圍,增加網站的安全性。

    + +

    其她的小改變包括了:

    + +

    CGI 程式模組化,可以簡化 CGI 程式的維護工作。

    + +

    開始使用 JavaScript 和 Dynamic HTML 的技術,可以減少網站的負荷,並強化網站管理的能力。

    + +

    《女聲》的發報程式做出來了。以後就不用發報發得很辛苦了。

    + +

    我還寫了一個很炫的網站連結分類引擎,可以自定分類系統,往下分好幾層子目錄,製作需要的資料夾和 HTML 網頁。相關網站連結的資料庫也和《女聲》的女網牽手資料庫分開了。此外,相關網站區過去一直找不到一個適當的標題,寫不出適當的感覺。這次我也終於想出了個比較好的標題,雖然這個標題還是下得很爛,可是定位比以前清楚多了。

    + +
    + +
    + +
    +
    日期: 2.14.’00.
    + +

    旅舍第五次改版,改版的原因是南方的主機出了問題,無法執行 CGI ,也無法登入,經過了兩個多月與南方編輯部協調未果,又找不到另一臺可執行 CGI 的免費 UNIX 主機以供遷站下,只好將女聲與旅舍同時緊急搬遷到一臺依瑪自己管理的 NT 主機上。因為在 CGI 畢竟是在 UNIX 下發展的環境,在 NT/Win32 下執行有許多困難,因此被迫一定要將 CGI 程式改寫成 ASP 程式。

    + +

    改版的同時,我被迫更嚴謹地思考網站建置和網頁寫作的問題。何謂一頁?何謂一個結構完整的文件?何謂一個結構完整的程式?何謂一個具有高可攜性的資料庫?很多問題,是這次改版以前沒想過的。例如:連結的部份該用何種資料庫呢?要用 UNIX 內建資料庫嗎?還是該用 Windows 最常用的 Access 資料庫?還是最熱門的 SQL ?何者具有最高相容性和可攜性,可以在萬一旅舍主程式又要搬到 UNIX主機時,仍可使用?

    + +

    這些,都是之前沒想過的問題。因此當南方的 UNIX 主機出問題後,我只能在 98 中望著一堆只有 UNIX 下才看得懂的亂碼欲哭無淚,想救資料又不知從何救起。

    + +

    現在我用的是 CSV 逗號分隔值資料表。這是純文字資料格式,每筆資料一行,資料間以逗號分開。純文字可以保證任何環境下皆能讀取。雖然這樣程式要寫得很複雜很長,但至少不會再發生南方當機後,我在 98 中望著 UNIX 資料庫亂碼欲哭無淚的情形。 .CSV 檔案可以用 Excel 開啟,因此我還可以用 Excel 來做比較複雜的處理,如排序、搜尋、除錯等等。

    + +

    另外,我決定將主要的相關內容資訊(如旅舍日記的日期、每篇詩的標題、簡短介紹等等),寫在網頁標頭 <HEAD> 部份,然後讓程式來讀取網頁標頭資訊。這樣就不必用到資料庫了,也可以讓檔案少一點,且讓資料跟著網頁跑,也減少維護上的困難。

    + +

    關於讓檔案少一點的部份,現在我把檔案分門別類存放,圖檔、樣式表都放在不同的資料夾,所以現在維護起來乾淨清楚多了。

    + +

    還有。我打算寫一個程式,可以把旅舍的內容自動一口氣全部轉為純 HTML 。小招說得對,整個網站全部倚賴 CGI/ASP 程式實在是太危險了,萬一哪天網站又再掛掉不能跑 CGI/ASP,要再改版又會欲哭無淚。

    + +

    除此以外,最重要的是,旅舍終於成為一個完整的網站了,而不只是網頁。現在旅舍架在一整部虛擬主機上。這是最讓我興奮的。 ^_*'

    + +
    + +
    + +
    +
    日期: 8.8.’99.
    + +

    其實旅舍前一次(第三次)改版沒有完成,只有做出旅舍大廳、旅人留言本和我三個部份而已,就沒有力氣做了。後來,旅舍就荒廢了好一陣子。

    + +

    這是旅舍第四次改版,改版的原因是因為旅舍搬家了。因為被 Yahoo! 併吞後的 GeoCities 對會員越來越不友善,不但網站名稱,連會員帳號、免費 E-mail 、送信權限、郵件主機、醜醜的 Yahoo! GeoCities 浮水印都為了跟 Yahoo! 會員資料庫合併而被迫改變。 imacat 變成 imacat.geo ,因為 Yahoo! 有一個叫做 imacat 的會員,帳號重複。去你的!我死也不當 imacat1999 !之前《女聲》電子報和南方人文網站的合作愉快,於是我徵求南方同意,將整個旅舍依瑪搬遷到南方。

    + +

    第四次改版最重要的是 Perl/CGI 的應用。南方容許 Perl/CGI 。我將之前做《女聲》學到的技術,應用在旅舍上。有了 CGI 程式,可以對不同版本 IE / Netscape 分別做不同的頁面,解決了 IE / Netscape 頁面排版不同的問題。這是舊旅舍最可笑的地方,也是第三次改版到一半中斷的原因:支持建議使用任何瀏覽器,可是連 Netscape 和 IE 下的效果都不一致。

    + +

    現在不僅解決頁面排版問題,也做出了一個更像留言簿的旅人留言簿,還不用整理得半死。旅舍的維護也變得更方便了,對外連結變成一個小型的搜尋引擎,最近更新日期也能自動計算。這些都要歸功於 CGI

    + +
    + +
    + +
    +
    日期: 11.9.’98.
    + +

    這算是旅舍的第三次改版了。今年三月初做出來旅舍初版,只有文字沒有圖型。當時抱持著 DOS 的純文字傳統,加上自己處理圖形的工具和經驗都有限,再加上看了太多別人的網頁用上一大堆漂漂的圖檔,到最後卻讀得很慢的案例,就很討厭、很排斥用美工圖形,寧可做一個沒有什麼外觀,文字內容卻很充實的網頁。

    + +

    第二次改版是三月底的事。當時的關鍵則是在於繪圖程式的運用。我開始練習電腦繪圖,利用繪圖程式的簡易功能和小畫家描點法來作出一個又一個的圖來。因為數學系畢業的背景,我開始嚐試透過計算製作一些 3D 光影的圖。當時的作品中最漂亮的是一張綠黑色的背景圖,看起來像深夜裡的綠竹林一樣幽幽的。我把它拿來作旅舍大廳的背景用。如果妳是旅舍的老顧客的話,也許妳還會記得那個背景。可惜現在已經不在了。把它拿掉的原因是因為和我想要的旅舍氣氛不合。它太冷、太孤寂了,而我希望旅舍給孤獨的旅人們暖暖的感覺。拿掉的時候還決定了很久,很捨不得呢!

    + +

    最後我選擇了這張背景圖。它的靈感是來自碎花布的布料紋路,常常可以在復古的餐館桌上看得到的那種。這張背景圖做起來簡單得多了,暖色系帶給人溫暖的感覺。後來我修了一次,加深顏色使文字看得清楚些。同時我做出了其它各頁用的背景圖,封面那隻很大的黑貓,選項用的小黑貓,連結用的動畫小圖等等。從那時開始旅舍有了一堆大大小小的圖;也是從那時開始,一進旅舍開始冒出了隻大黑貓,把很多人都嚇到了。 ^_*'

    + +

    四月初時曾經想再改一次版,可是沒有做出來。當時最主要的構想是想把整個旅舍做成一個image map,把整個旅舍封面做成一張旅館大廳的圖,旅人們可以自己點選想去的地方進去。可是後來因為空間的計算太複雜而作罷。

    + +

    第三次改版,就像我在很多地方都說過很多次的,最主要的關鍵是應用了 HTML 4.0 和 CSS1 的標準。最重要的就是把網頁內容網頁外觀分開,使網頁內容結構化,也使得網頁外觀的設計更自由,更豐富。使用 Style Sheets 解決了原本就令我頭痛不已的結構混亂、毫無章法的問題,同時,在不增加圖檔的情況之下,反而使得網頁的外觀意外地漂亮了很多。

    + +
    + +
    + +
    +
    日期: 5.4.’98.
    + +

    其實,關於這個網頁中的很多事,在網頁裡的其他地方都已經說過了:關於為什麼我把它做成一個旅舍,在旅人留言簿的引言裡有說;關於寫這個網頁的一些心情和想法,則記在我的主臥室裡。這裡所記的,是一些在其他地方沒寫到的。

    + +

    我沒有放很多圖片,而放了大量的文字。這其實是很違反潮流的。這個時代沒有人看文字了,大家都愛看炫炫的圖。可是管它的!我沒別的長處,這輩子大概只能夠做文字工作者了。這就是我。我很囉唆,話很多,字也很多,妳不愛看就算了。

    + +

    另一個我不放圖的原因是:圖實在是太麻煩了。我是很懶得去 FTP 站下載人家的圖庫的。而且用別人的圖庫還有版權問題,一想到就很頭痛。要從圖庫裡幾百個圖中選一個來用對處女座求完美的我來說更是頭痛的事,看一兩百個就昏了。自己做圖庫則很麻煩,我沒有掃描器,也沒有很棒的製圖軟體,美術天份又不如文字天份好。

    + +

    不過這些都不是主因。最重要的原因是:太慢了! GeoCities 在美國耶!我多放三千個字的傳送速度等於放一張圖而已,我當然選擇放文字了!

    + +

    可是我還是放了一些圖。每一個畫面的背景圖都是我自己畫出來的,這是我很得意的事。所以我還是建立了我自己的小圖庫。我覺得如果連背景都是單色的,那就太寒酸了。我想憑著背景圖和文字的排版,我還是能把它做得很漂亮的。

    + +

    還有一件事是:我對雙語的堅持。畢竟這個網頁是建在 GeoCities 。人家提供的資源,不好意思做些連人家都看不懂的東西,這是我認為一些基本的回饋。我還蠻認同 GeoCities 的理想的。而且還可以練習久已生疏的英文。此外,如果能夠因此而交到一些來自異地的朋友,就太好了。

    + +

    因此,我寫大部份的文字時,都會不自覺顧慮到英文的語法。我寫出來的不是很標準的中文語法,可是還是很容易閱讀的。於是,我可以很容易地翻譯成英文。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 1 | + 2 | + 3 | + 4 | + 5 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0002.html.en.html b/htdocs/imacat/me/changelog/0002.html.en.html new file mode 120000 index 0000000..4e8a442 --- /dev/null +++ b/htdocs/imacat/me/changelog/0002.html.en.html @@ -0,0 +1 @@ +0002.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0002.html.en.xhtml b/htdocs/imacat/me/changelog/0002.html.en.xhtml new file mode 100644 index 0000000..a0459c1 --- /dev/null +++ b/htdocs/imacat/me/changelog/0002.html.en.xhtml @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 2 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 2

    + +
    + +
    + +
    +
    Date: 3.31.’03.
    + +

    The Travellers’ Guestbook has finally back. Ha ha!

    + +

    It had been 2 years since its shut down. The previous programs were written in the middle of 1998, almost 6 years ago. It was very buggy. Although I kept fixing them, I couldn’t break through several major issues. To avoid fixing here and there all the time, I decided to turn it off completely and write a new one. But these issues are so large to solve. Several months later I still had no idea at all. It was completely suspended then, for 2 years.

    + +

    Recently my other PHP web site content management system project — Monica — had come to some progress and solved several major issues. Then last week Quity was trying to ask me some Linux questions. She couldn’t reach me on ICQ. She left a message on ICQ to ask me deal with the guestbook as soon as possible so that she can leave a message even when I’m not on-line. Then I’m wondering: Why not use my experiences on Monica here? What if I migrate the PHP Monica to CGI/Perl or mod_perl? I would also like to see how much time is required for me to write a new guestbook now, with my current power? That becomes the Selima project, which is this new guestbook you see now. I spent about a week for the migration. PHP is quite different than CGI/Perl or mod_perl. There is still some issues. But it seems to be successful now.

    + +

    Monica/Selima has solved the major problems of the old guestbook. The following issues are improved:

    + +
      +
    1. The messages are not shown with <pre>…</pre> anymore. I’m now using a subroutine a2html() to turn the message into HTML, solving the line-breaking problem while preserving the original text format.
    2. + +
    3. Language switching ability is added. The original mixed Chinese/English pages are split into 3 language pages: Traditional Chinese, Simplified Chinese and English.
    4. + +
    5. UTF-8 is used to save the messages. Unicode processing ability is added. This solves the problems where messages from foreign friends become distorted.
    6. + +
    7. Use suspended forms and redirection so that contents are always displayed with GET requests. No more content on POST requests. This solves the issue where pressing reload on POST produce duplicated messages.
    8. + +
    9. The e-mail addresses in the messages are not displayed directly now. This prevents the spammers from scanning the addresses and spamming our friends.
    10. + +
    11. Pages are split from its message sizes but not the numbers of messages now. This prevents the problem that some page are extremely long and some are very short.
    12. + +
    13. Optimized for mod_perl and compatible with CGI/Perl and even command line. It is more efficient and flexible.
    14. +
    + +

    There are so many yet to be listed. It’s a pity that, since Selima uses a complex set of its own libraries, it’s very difficult to release them and let other people understand them. It’s a pity that it cannot be an open-source project.

    + +

    The guestbook data file format has changed. The old messges are not shown currently. I’ll put them on after I put them in order and convert them.

    + +

    The name Selima is an Arabic female name. It means peace. The US-Iraq war is going. The US governments disregards the objection from the UN, invades Iraq and causes numerous innocent deaths. I named it Selima in the memorial to those innocent lives and in the hope that war ceases and peace comes to the Arabic world again.

    + +
    + +
    + +
    +
    Date: 11.5.’00.
    + +

    Tavern IMACAT’s has experienced many changes. It’s time to make a conclusion here.

    + +

    First of all: At the middle of July, my ADSL fast fixed connection is finally installed. Tavern and WOV have finally moved from STS to my own host. This task is much simplier than I’ve expected, because both are Windows 2000 IIS 5.0 hosts, which I’m quite familiar with. Nothing changed. The only problem was: My computer is an old Pentium Ⅱ 233. To be a main Win32 server is too heavy a loading for it.

    + +

    After Tavern and WOV have moved, I had no fears anymore. I resigned from STS at the middle of August. Then I bought a new Pentium Ⅲ 800 as a new server with my severance pay. It runs Red Hat Linux 6.2. (It has been upgraded to 7.0 now.) At the beginning, it was really a hard day. It’s a complete different world with my familiar Win32, with totally different concept. But I got a nice new job, with a whole library of Linux books. I borrowed them home everyday. Not until I was familiar to Apache server, did I move Tavern and WOV onto the new server. According to the records on the WOV editors’ notes, it was Sep. 16th., ’00., about one month after I bought this machine.

    + +

    The major change moving to Linux Apache is the HTTP headers. I was not running CGI, but ISAPI PerlIS under IIS. PerlIS cannot parse HTTP headers, so I had to manually set HTTP headers up. But under Apache CGI, direct HTTP headers cause errors. I had to rewrite all the HTTP headers.

    + +

    Things following up happened intensively.

    + +

    Sep. 26th., I’ve made the guestbook illustration, anded help message on WOV subscribing pages, and artificial HTTP 403 Forbidden message. These were documents I planned to write long time ago. The major point of guestbook illustration is the line-breaking problem: Guestbooks will not break lines automatically. I’m not planning to do automatical line-breaking. It’s the style of prose poems. That’s a habbit since I was playing BBS. But the line-breaking of guestbooks is still a big problem. I’ve seen the line-breaking policy of Yam, Kimo discussion boards, but no better solution was found. This is still a problem to work with.

    + +

    WOV editors’ e-mail is added on the subscribing page, in order to help when subscribing program comes to an error. HTTP 403 is Forbidden, to protect site administration pages and subscribers’ data.

    + +

    Sep. 28th., the robot.txts had done. This is used to limit search engine robots where they can go and where they should not go. This can avoid search engine to build index on private infos, like site administration pages.

    + +

    Oct. 11th., I’ve employed mod_perl. This is another milestone. Because the company does not use Perl, I was unable to know how to use the legendary mod_perl to enhance the websites. At last I’ve found mod_perl and it’s installation documents, re-compiled, re-installed the Apache server. But the HTTP header processing of Apache mod_perl is different from Apache CGI again! To avoid the same problems hereafter, I abandoned manual HTTP headers, replaced it with CGI::header() module to handle it. I took away my own time2str(), too, replacing it with HTTP::Date::time2str().

    + +

    This solved another problem: mod_perl was unable to keep-connection. CGI::header() calls the Apache::Registry header parser, which solves the connection problem.

    + +

    I start to change my old practices. To save system resource and avoid loading unnecessary outer modules, I tried to write my own necessary modules as much as possible. Now to keep the compatibility I rely on outer modules by others as much as possible. This is a important conceptual change for me, especially on Perl and UNIX programming: cooperation. Perl program should be a result of cooperation by different people, but not a fight by a single program dealing all the problems.

    + +

    This goes the same as UNIX. Different programs, processes call each other to cooperate and transfer messages for the result. I can do it in Win32, too, with too few tools and too much system resource cost. This is not the aim of the design of Win32.

    + +

    Until this time, I’ve really entered the world of UNIX, a complete different world with DOS/Win32.

    + +

    And also, mod_perl loads necessary modules and retains them in the apache process, which causes the confusion of module variables. I’ve move the variable settings from the common modules to the seperated scripts. To avoid different common modules with the same name confuses one another, I’ve changed the name of common modules, too.

    + +

    I’ve written a complicated formula to calculate the last-modified time of each volumn of the guestbooks. This formula was removed now, to avoid the confusion of browser cache.

    + +

    I’ve downloaded and installed the W3C HTML validator website, run it on a virtual host.

    + +

    At the same night, I’ve written a more effective internet domain justification with gethostbyname(). I’ve modified the previous formula, to fix the bug that cannot calculate the last modified time when no guestbook messages were present. Also, the atrificial HTTP 303 See Other redirect after saving new guestbook message causes problem at the browser, because mod_perl adds it’s own HTTP 303 message body, causing the length of message body to be wrong. Then the browser cannot judge the real content length. I’ve temporary disabled the Content-Length HTTP header to solve it.

    + +

    Oct. 19th., I added the flock() file locking before every file opening, to avoid read/write corruption at the same time. It should be done long ago, but I was not clear how it works, so I left it there. Now I’ve read carefully the detail of flock(), knowing how it works, I’ve done with them. Besides, for the flock() new method, I’ve rewrite the program flow of WOV subscribing program. This program flow needs another rewrite to solve another problem: The justification of the last modified time.

    + +

    Also, I’ve written my own artificial HTTP 500 Internal Server Error message, and trapped the file opening errors to make HTTP 500 errors. This solves the old problem that, site administration program does not warn when rebuilding pages failed.

    + +

    Oct. 27th is another major milestone. I’ve solved all the problems so far with the weekend. They are described below:

    + +
      +
    1. I’ve trapped all errors on file I/Os and other system calls, causing HTTP 500 error messages, to more strictly protect program processing. The artificial HTTP 500 error was originally quit with exit(). Now it quits with die, leaving message on the server error log.
    2. + +
    3. I’ve rewrite the process flow of the counter, to reduce unnecessary file locking, avoiding stucking. Besides, the counter judges the inner IPs with grep() now.
    4. + +
    5. I’ve made clear the detail how cookies works. So I’ve simplified the counter cookies, replacing CGI::Cookies module with simplier CGI::header().
    6. + +
    7. I’ve made clear the detail of GD module, simplify the graphical processing of the counter, the last update and the subscribers counter.
    8. + +
    9. I’ve found the way to recognize Network Operation System, rewritten the process flow of security contron under Win32, and employed getgrnam() and getpwnam() to do the security control under Linux.
    10. +
    + +

    Sat., Oct. 28th.. I’ve finally done the keywords system!! I’ve rewritten all the databases and site administration interface, adding the keywords field on them. I was planning to do this for a long time. At the same time I’ve rewritten the interface to edit the relative links, providing greater capability and flexibility. I’ve also written the authority announcement and privacy policy, linking the WOV in Tavern to the privacy policy on WOV.

    + +

    I was planning to write a privacy policy for a long time. Since I’ve made clear the detail of cookies transfer, I made it together. I hope this do remind you not to leave personal infomations incautiously. As for the Authority Announcement, well… Basically, I hate these authority stuffs. But some commercial sites just went too far. Besides, some people started to get interested in me and my writings. (What have I committed recently?) To avoid troubles, it’s better to state it clearly.

    + +

    Sun., Oct. 29th.. I’ve improved the artificial error messages, trapping the file I/O errors in the artificial error messages themselves, and sending a mail to the webmaster when artificial HTTP 500 occurs.

    + +

    I’ve solved another prior bug: Because the programs cannot recognize If-Modified-Since HTTP header, and as I’ve described above, the last modified time will trace back to the previous message time when calculating last modified time, this causes the browsers to confuse on the time and data content of their cache, causing the browsers to stuck when re-reading a page. I’ve decided to drop the previous last modified formula, with a new formula according to the last modified date of the program and the data themselves. I also add the support to response to the If-Modified-Since HTTP header, and the artificial HTTP 304 Not Modified message, to support browser cache.

    + +

    I’ve made the artificial HTTP 405 Method Not Allowed error, to avoid request with PUT / DELETE / TRACE … Although this shall never happens normally, it’s rather stupid if it happens without handling.

    + +

    To this point, the site programming has come to an end. I’ve solved all the problems I could figure out, and took a deep breath.

    + +

    Nov. 2nd., there were nearly 600 messages on the Travellers’ Guestbook now. The old database engine was overloaded, causing serious lags. After experimentation with different methods, I’ve rewritten the database engine. The old engine parses data one by one, while the new one does with batch processing. It’s a little tricky, though, but it largely speeds up. The new database engine keeps a nice speed even over 6,000 messages. What if over 10,000 messages? It’s too far for me to worry now. Basically, I’m not planning to use SQL database. It’s a principle: portability. I wish the whole website can move entirely onto any server at any time, not depending on the specific factors of the environments: MySQL? mSQL? PostgreSQL? MS-SQL? Access ODBC? Or IBM DB2?

    + +

    Because the site engineering has come to an end, I planned to release the source of Tavern IMACAT’s. This is a rather large project. Even I was coding with good conventions, I had not make many annotations. They still need lots of annotations for others to understand.

    + +

    This weekend I tried to move Tavern IMACAT’s back to Win32 IIS environment. It’s more complicated then I’ve expected. PerlIS cannot parse HTTP headers, IIS CGI cannot set the current working directory, and mod_perl Apache::Registry deal with CGI::header() differently with others. I’ve spent 3 days, looking for all the Perl and mod_perl documentations and discussions. I’ve finally made the code that, employs absolute path to get the maximum compatibility, and adjust HTTP headers with special situation. This solved the problem I’ve mentioned above: CGI::header() will add message body automatically for artificial HTTP errors under mod_perl Apache::Registry, causing wrong message body length which confused the browsers. Now programs will not send message bodies under mod_perl, leaving this task to mod_perl itself.

    + +

    I’ve rewritten the process flow of the graphical programms, including the counter, the last update, the subscribers counter, in order to fit the convention with other programs on the process flow.

    + +

    There’s still things to do: The process flow of WOV subscribing program needs to be rewritten: Process subscribtion first then judge the last modified time. I’ll have to add more annotations, too, for the source code to release. Also, I’ll have to add the version changes of this website.

    + +

    It’s not a big deal to release the source code. Free source of guestbooks and counters are now available everywhere. But it’s still an important milestone for me.

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 1 | + 2 | + 3 | + 4 | + 5 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0002.html.zh-cn.html b/htdocs/imacat/me/changelog/0002.html.zh-cn.html new file mode 120000 index 0000000..f6628e3 --- /dev/null +++ b/htdocs/imacat/me/changelog/0002.html.zh-cn.html @@ -0,0 +1 @@ +0002.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0002.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0002.html.zh-cn.xhtml new file mode 100644 index 0000000..059506b --- /dev/null +++ b/htdocs/imacat/me/changelog/0002.html.zh-cn.xhtml @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷二 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷二

    + +
    + +
    + +
    +
    日期: 3.31.’03.
    + +

    旅人留言本终於重开了~!哦呵呵呵呵呵~! ^_*'

    + +

    关闭了两年,留言本终於得以重见天日了。之前的主程式是 1998 年中写的,距今已经快六年了。原来的程式问题很多,几年来虽断续修正一些 bug ,但几个重大的问题却迟迟无法突破。为了避免一天到晚在东挖西补,我毅然决定把留言板整个停掉,整个重写。但因为这些问题都很大,一直无法突破,过了几个月还是想不出办法,就整个搁置下来了。就这样,一搁就搁了两年。

    + +

    最近这几个月来,我的另一个 PHP 网站计划— Monica —逐渐有了成果,并突破了几个重大的难关。正好上星期阿光要问我 Linux 的问题,在 ICQ 上找不到我,在 ICQ 上留话,催我快弄一个留言板出来,以便我不在也能留言问我。我想到,何不把 Monica 所累积的经验,转移过来呢?把 PHP 的 Monica ,移植到 CGI/Perl 或 mod_perl 环境中,会有什么结果?我也很想考考自己,以我现在的能力,写一个留言板,要花多久时间?这就是 Selima 计划,也就是大家看到的,新的旅人留言板了。移植的工作,花了一个星期左右。 PHPCGI/Perl 或 mod_perl 差别不小,移植的过程多少有点阻碍,但现在看起来,应该算是成功了。 ^_*'

    + +

    Monica/Selima 所解决的问题,正好也是旧的旅人留言板的主要问题。新的旅人留言板,改善了下列功能:

    + +
      +
    1. 留言不再用 <pre>…</pre> 显示,用一个 a2html() 函式,将留言转为 HTML ,在保留原留言格式外,也解决了断行的问题。
    2. + +
    3. 加上语言切换的功能,将原有的中英对照分开,改分成繁简中文和英文三个语言切换。
    4. + +
    5. UTF-8 存留言,并加上万国码处理能力,以解决外地来的朋友,留言会变乱码的问题。
    6. + +
    7. 改用暂存表单转向,所有的页面都是用 GET 来显示,不再在 POST 上显示页面,以避免在 POST 中按下重新整理,会造成重覆留言的问题。
    8. + +
    9. 留言的 E-mail 不会再直接显示,以避免被广告商的 E-mail 扫描程式扫描,发广告信,造成留言的人困扰。
    10. + +
    11. 留言分页原来是以笔数分类,现改以留言的量分类,避免每页长度多寡不一。
    12. + +
    13. 针对 mod_perl 的特性而写,并相容於 CGI/Perl 和命令列模式,执行的效率提高,也提高执行的弹性。
    14. +
    + +

    其她还有很多,不及列举。可惜的是,因为 Selima 的架构,用到很多自己写的函式库,要把它们一一放到网站上,颇为困难,更别说要让人看得懂原始码了。无法建置成开放原始码的专案,甚憾。

    + +

    因为留言板资料档格式改变,暂时还看不到旅人留言本的旧留言。等我整理完,转完档后,会再放上来。

    + +

    Selima这个字,是来自阿拉伯的女生名字,意思是和平peace。时值美伊战争,美国不顾联合国反对,强行入侵伊拉克,造成无数无辜生命的死伤。取Selima这个名字,一方面为哀悼这些无辜的生命,也希望战争早点结束,让和平早日回到阿拉伯世界。

    + +
    + +
    + +
    +
    日期: 11.5.’00.
    + +

    旅舍依玛经历不少的改变,在这里总结一下。

    + +

    首先,七月中以后,家里的 ADSL 固接宽频网路终於接通了,旅舍和女声也从原本借用益华主机,改搬到家里的电脑上。搬迁工作比预期简单,因为两边都是 Windows 2000 伺服器,我已经对 Windows 2000 IIS 5.0 很熟悉了,没什么改变。唯一的问题是:我的电脑只是 Pentium Ⅱ 233 ,拿来做主要的 Win32 伺服器,跑得很辛苦。

    + +

    旅舍和女声搬迁后,我已经没有顾忌了。八月中辞掉益华的工作,用离职保证金买了新的电脑 Pentium Ⅲ 800 当新的伺服器,作业系统使用 RedHat Linux 6.2 (现在已经升级到 7.0 )。刚换 Linux 的时候,真的很辛苦,因为和以前熟悉的 Win32 环境差太多了,整个概念完全不一样。不过换了一个不错的新工作,公司里有一整个书架的 Linux 书,像图书馆一样天天把书借回家。一直到我对 Apache 熟悉以后,才把旅舍和女声网站搬到新的 Linux 伺服器上。在女声编辑手记上的日志记载,这天是 2000 年 9 月 16 日,大约是买了新伺服器后一个月左右。

    + +

    搬迁到 Linux Apache 最大的改变在於 HTTP 标头的问题。原本在 IIS 下并不是用 CGI ,而是用 ISAPI PerlIS 来执行程式, PerlIS 无法设定正确的 HTTP 标头,所以必需手动设定 HTTP 标头。可是回到 Apache CGI 下,直接送出完整 HTTP 标头会导致错误,所以只得重写所有的 HTTP 标头。

    + +

    接下来的事情,只能用紧锣密鼓来形容。

    + +

    9 月 26 日,做出了留言板使用说明,在女声订阅页上加上求助讯息,加上 HTTP 403 Forbidden 自订错误讯息。这些都是很久以前就想写的说明。留言板说明主要是在断行的问题上:留言板不会自动断行。原则上我不打算自动断行,因为我玩 BBS 的时候,已经习惯了手动断行的散文诗格式。可是留言板断行问题仍然是个很头大的问题。我参考过蕃薯藤、 Kimo 讨论区断行处理方式,还没有找到一个比较好的解决方法。这是个仍待解决的问题。

    + +

    女声订阅页加上了女声编辑的 E-mail ,以便无法订阅时有路可循。 HTTP 403 是 Forbidden ,用来保护网站管理程式和女声订户资料。

    + +

    9 月 28 日,做出了 robot.txt 。这是用来告诉外面的搜寻引擎,哪些地方不可以拿去做全文检索资料库。这样可以避免搜寻引擎把网站管理程式等等的东西都拿去建档了。

    + +

    10 月 11 日,网站改用 mod_perl 。这是另一个重要的里程碑。因为公司不用 Perl ,所以一直不知道该怎么用传说中的 mod_perl 来加强网站程式效率。后来我找到了 mod_perl 和 mod_perl 的安装、设定说明,重新安装整个 Apache 伺服器。没想到 mod_perl 的 HTTP 标头处理方式又和 Apache CGI 不一样。为了避免日后同样的困扰,我舍弃手动设定标头,改用 CGI::header() 模组来处理 HTTP 标头。同时我也拿掉自己写的 time2str() ,改用 HTTP::Date::time2str()

    + +

    改用 CGI::header() 处理标头后,解决了另一个问题: mod_perl 无法持续连线。只要使用 CGI::header() ,就能够启动 Apache::Registry 内部的 HTTP 标头解析引擎,处理连线的相关问题。

    + +

    我开始舍弃过去的做法。过去为了避免载入外部模组浪费系统资源,我尽量自己写所需要的模组。现在我尽量引用别人写好的外部模组,以保持系统的相容性。这是很重要的观念改变,尤其在 Perl 和 UNIX 程式写作观念上:合作。 Perl 程式应该是不同人努力合作的成果,而不是一个程式单打独斗处理所有的问题。

    + +

    UNIX 环境也是。不同程式、行程间相互呼叫、配合、传递讯息,以得到结果。 Win32 也可以这样,只是工具太少,而且所耗的系统资源太多。这也违背了 Win32 环境最初的设计目标。

    + +

    这时候,才真正进入了 UNIX 的世界,一个和 DOS/Win32 完全不同的世界。

    + +

    另外, mod_perl 会载入所需模组并常驻在 Apache 行程中,会造成模组变数的混淆。我把原来在共用模组设定的变数,如 $ID 、$THIS_FILE ,搬到个别程式里设定。为了避免不同网站的共用模组,因为常驻时名称相同而混淆,我也更改了共用模组的名称。

    + +

    我写了一个有点复杂的算式计算留言本每一册的最后更新日期。这个算式后来还是改掉了,以避免浏览器快取的时间计算混乱。

    + +

    我下载了 W3CHTML 认证程式网站,开一个虚拟主机来执行。

    + +

    同一个晚上,我用 gethostbyname() 写出比较有效的计数器网域判别准则。我也小小修改了前面所提,留言本最后更新日期的算式,以解决没有留言时无法计算最后更新日期的错误。另外,留言存档后的自订 HTTP 303 See Other 重新导向讯息,因为 mod_perl 会自行追加 HTTP 303 讯息,导致讯息长度错乱,使浏览器无法判断讯息长度。我暂时拿掉讯息长度 HTTP Content-Length 标头,以解决问题。

    + +

    10 月 19 日,我在每个档案开档时加上了 flock() 档案锁定,以避免档案同时读写错乱。这是很久以前就该做的,可是因为一直不清楚 flock() 档案锁定的做法,所以没加上去。这两天仔细读了 flock() 的相关说明,觉得很有效,就加上去了。另外,因为使用了新的档案锁定方法,我也重写了女声订阅程式的流程。女声订阅程式流程还要再改写,以解决另一个问题:档案最后更新日期的判定方式。

    + +

    其次,我也写了自订的 HTTP 500 伺服器内部错误讯息,并栏截了开档错误,产生 HTTP 500 讯息,以解决网站管理程式重建网页时,网页明明没有更新,却毫无警告讯息的老问题。

    + +

    10 月 27 日那个周末是另一次重期的日期。我把之前想得到所有的大小 bug ,利用两天三夜的周末假期都解决了。分列如下:

    + +
      +
    1. 栏截了所有的档案读写和其它系统函式的错误,并产生 HTTP 500 错误讯息,以更严密地保护程式正常运作。 HTTP 500 原本以 exit() 结束,改以 die 结束,在伺服器错误记录中留下记录。
    2. + +
    3. 重写访客计数器的流程,减少不必要的档案锁定,避免计数器卡死。计数器改以 grep() 判定内部位址。
    4. + +
    5. 摸清楚了 cookies 的详细运作传递方式,简化了计数器的 cookies ,停用 CGI::Cookies 模组,改用 CGI::header() 简化处理。
    6. + +
    7. 摸清楚了 GD 模组的运作方式,简化了计数器、最后更新日期、订户人数图形的处理。
    8. + +
    9. 找到了判别网路作业系统的方式,改写了 Win32 下的安全管制判别流程,并改以 getgrnam()getpwnam() 来做 Linux 下的安全管制。
    10. +
    + +

    10 月 28 日星期六,我改写了所有网站管理程式的介面和资料库,把关键字加上去,终於把不同的关键字整合进网页中。我想做好网页的关键字系统已经想了很久了。我顺便改写了相关连结的设定介面,提供更大的功能和弹性。另外,我也写了旅舍的著作权声明和隐私权声明,并把旅舍中的女声著作权声明连结到女声去。

    + +

    隐私权声明是我之前一直想写的。既然前一天我把 cookies 的传递细节弄清楚了,就顺便一起写出来。希望这可以提醒大家不要在网路上乱留个人资料。至於著作权声明嘛…原则上我很讨厌著作权这种玩意儿。可是最近有些商业网站太过份了,而且有些莫名其妙的人开始对我的网站和我的文章感兴趣。(不知道我招惹到什么了?)为了避免不必要的麻烦,还是写清楚比较好。

    + +

    10 月 29 日星期天,我改进了自订错误讯息,栏截自订错误讯息本身的开关档错误,并在发生自订 HTTP 500 伺服器内部错误时,寄一封信通知网站管理者。

    + +

    解决了之前另一个问题:因为程式无法处理 If-Modified-SinceHTTP 标头,而且最后更新日期按照先前所述,会追溯到先前的留言日期,导致浏览器在重读网页时,快取的日期和资料内容错乱,使浏览器卡死。我决定舍弃前述的最后更新日期算式,改以留言板程式本身和留言板资料档的最后更新日期为准,以方便浏览器快取资料更新。我并且加上了对 If-Modified-Since HTTP 标头的支援,加上了 HTTP 304 Not Modified 自订讯息,以支援浏览器快取功能。

    + +

    我写了自订 HTTP 405 Method Not Allowed 错误,避免有人用 PUT / DELETE / TRACE 等…连上来。虽这种事情应该不可能发生,可是一旦发生了却没有处理,是很笨的事。

    + +

    到这里,网站程式算是告一段落。我想得到的大小问题解决得差不多了,也松了一大口气。

    + +

    11 月 2 日,旅人留言簿资料已经接近 600笔,原来的资料库引擎已经超出负荷,出现严重停滞现象。经过执行速度比对实验后,我改写了资料库引擎。原来程式是一笔一笔比对,改用整批比对的方式,虽然有点取巧,但大幅度加快了资料库解析速度。现在的新资料库引擎,即使超过 6,000 笔留言,仍保持极快的速度。超过 10,000 笔以后呢?那以后再说吧。原则上,留言簿留言我不打算用 SQL 资料库,维持最基本的原则:可携性。我希望整个网站随时可以搬到别的伺服器上,不需要依赖外在环境的特殊因素,例如:是 MySQL ? mSQL ? PostgreSQL ? MS-SQL ? Access ODBC ?还是 IBM DB2 ?

    + +

    因为网站工程告了一段落,我开始打算释出旅舍依玛的原始程式码。这个工程有点浩大,因为即使我程式码写得很清楚,可是注解却不多,如果要释出,还要加上很多注解,才能让别人看得懂。

    + +

    前天 11 月 3 日周末,我尝试把旅舍搬回 Win32 IIS 的环境下,发现问题远比我想像的复杂。 PerlIS 无法正常处理 HTTP 标头、 IIS CGI 无法正确设定程式执行目录, Apache mod_perl Apache::Registry 模组处理 CGI::header() 的方式也很特殊。我花了三天、翻遍 Perl 、mod_perl 的说明和讨论以后,总算写出程式,改用绝对档案路径,以取得最大的相容性,并根据特殊情形修正 HTTP 标头。我并且解决了前述的问题: mod_perl Apache::Registry 模组下, CGI::header() 自订 HTTP 错误会自动加上内文,导致内文长度错乱乱,浏览器无法判别的问题。现在程式若是在 mod_perl 下,不会送出自订错误讯息内文,将内文交给 mod_perl 处理。

    + +

    我重写了图形程式(计数器、上次更新日期、订阅人数)处理流程,以和其它程式的流程惯例一致。

    + +

    想做的事还有一些。女声订阅程式的流程还要再改写,先处理订阅要求,再判断最后更新日期。现在的顺序是倒过来的。另外,要加强程式的注解,才能释出程式码。而且,还要加上记录网站版本的变更。

    + +

    释出程式码其实没什么大不了。现在的留言板、计数器的免费程式码到处都是。但总是一个重要的里程碑。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 1 | + 2 | + 3 | + 4 | + 5 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0002.html.zh-tw.html b/htdocs/imacat/me/changelog/0002.html.zh-tw.html new file mode 120000 index 0000000..66ffd54 --- /dev/null +++ b/htdocs/imacat/me/changelog/0002.html.zh-tw.html @@ -0,0 +1 @@ +0002.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0002.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0002.html.zh-tw.xhtml new file mode 100644 index 0000000..af22198 --- /dev/null +++ b/htdocs/imacat/me/changelog/0002.html.zh-tw.xhtml @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷二 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷二

    + +
    + +
    + +
    +
    日期: 3.31.’03.
    + +

    旅人留言本終於重開了~!哦呵呵呵呵呵~! ^_*'

    + +

    關閉了兩年,留言本終於得以重見天日了。之前的主程式是 1998 年中寫的,距今已經快六年了。原來的程式問題很多,幾年來雖斷續修正一些 bug ,但幾個重大的問題卻遲遲無法突破。為了避免一天到晚在東挖西補,我毅然決定把留言板整個停掉,整個重寫。但因為這些問題都很大,一直無法突破,過了幾個月還是想不出辦法,就整個擱置下來了。就這樣,一擱就擱了兩年。

    + +

    最近這幾個月來,我的另一個 PHP 網站計劃— Monica —逐漸有了成果,並突破了幾個重大的難關。正好上星期阿光要問我 Linux 的問題,在 ICQ 上找不到我,在 ICQ 上留話,催我快弄一個留言板出來,以便我不在也能留言問我。我想到,何不把 Monica 所累積的經驗,轉移過來呢?把 PHP 的 Monica ,移植到 CGI/Perl 或 mod_perl 環境中,會有什麼結果?我也很想考考自己,以我現在的能力,寫一個留言板,要花多久時間?這就是 Selima 計劃,也就是大家看到的,新的旅人留言板了。移植的工作,花了一個星期左右。 PHPCGI/Perl 或 mod_perl 差別不小,移植的過程多少有點阻礙,但現在看起來,應該算是成功了。 ^_*'

    + +

    Monica/Selima 所解決的問題,正好也是舊的旅人留言板的主要問題。新的旅人留言板,改善了下列功能:

    + +
      +
    1. 留言不再用 <pre>…</pre> 顯示,用一個 a2html() 函式,將留言轉為 HTML ,在保留原留言格式外,也解決了斷行的問題。
    2. + +
    3. 加上語言切換的功能,將原有的中英對照分開,改分成繁簡中文和英文三個語言切換。
    4. + +
    5. UTF-8 存留言,並加上萬國碼處理能力,以解決外地來的朋友,留言會變亂碼的問題。
    6. + +
    7. 改用暫存表單轉向,所有的頁面都是用 GET 來顯示,不再在 POST 上顯示頁面,以避免在 POST 中按下重新整理,會造成重覆留言的問題。
    8. + +
    9. 留言的 E-mail 不會再直接顯示,以避免被廣告商的 E-mail 掃描程式掃描,發廣告信,造成留言的人困擾。
    10. + +
    11. 留言分頁原來是以筆數分類,現改以留言的量分類,避免每頁長度多寡不一。
    12. + +
    13. 針對 mod_perl 的特性而寫,並相容於 CGI/Perl 和命令列模式,執行的效率提高,也提高執行的彈性。
    14. +
    + +

    其她還有很多,不及列舉。可惜的是,因為 Selima 的架構,用到很多自己寫的函式庫,要把它們一一放到網站上,頗為困難,更別說要讓人看得懂原始碼了。無法建置成開放原始碼的專案,甚憾。

    + +

    因為留言板資料檔格式改變,暫時還看不到旅人留言本的舊留言。等我整理完,轉完檔後,會再放上來。

    + +

    Selima這個字,是來自阿拉伯的女生名字,意思是和平peace。時值美伊戰爭,美國不顧聯合國反對,強行入侵伊拉克,造成無數無辜生命的死傷。取Selima這個名字,一方面為哀悼這些無辜的生命,也希望戰爭早點結束,讓和平早日回到阿拉伯世界。

    + +
    + +
    + +
    +
    日期: 11.5.’00.
    + +

    旅舍依瑪經歷不少的改變,在這裏總結一下。

    + +

    首先,七月中以後,家裏的 ADSL 固接寬頻網路終於接通了,旅舍和女聲也從原本借用益華主機,改搬到家裏的電腦上。搬遷工作比預期簡單,因為兩邊都是 Windows 2000 伺服器,我已經對 Windows 2000 IIS 5.0 很熟悉了,沒什麼改變。唯一的問題是:我的電腦只是 Pentium Ⅱ 233 ,拿來做主要的 Win32 伺服器,跑得很辛苦。

    + +

    旅舍和女聲搬遷後,我已經沒有顧忌了。八月中辭掉益華的工作,用離職保證金買了新的電腦 Pentium Ⅲ 800 當新的伺服器,作業系統使用 RedHat Linux 6.2 (現在已經昇級到 7.0 )。剛換 Linux 的時候,真的很辛苦,因為和以前熟悉的 Win32 環境差太多了,整個概念完全不一樣。不過換了一個不錯的新工作,公司裏有一整個書架的 Linux 書,像圖書館一樣天天把書借回家。一直到我對 Apache 熟悉以後,才把旅舍和女聲網站搬到新的 Linux 伺服器上。在女聲編輯手記上的日誌記載,這天是 2000 年 9 月 16 日,大約是買了新伺服器後一個月左右。

    + +

    搬遷到 Linux Apache 最大的改變在於 HTTP 標頭的問題。原本在 IIS 下並不是用 CGI ,而是用 ISAPI PerlIS 來執行程式, PerlIS 無法設定正確的 HTTP 標頭,所以必需手動設定 HTTP 標頭。可是回到 Apache CGI 下,直接送出完整 HTTP 標頭會導致錯誤,所以只得重寫所有的 HTTP 標頭。

    + +

    接下來的事情,只能用緊鑼密鼓來形容。

    + +

    9 月 26 日,做出了留言板使用說明,在女聲訂閱頁上加上求助訊息,加上 HTTP 403 Forbidden 自訂錯誤訊息。這些都是很久以前就想寫的說明。留言板說明主要是在斷行的問題上:留言板不會自動斷行。原則上我不打算自動斷行,因為我玩 BBS 的時候,已經習慣了手動斷行的散文詩格式。可是留言板斷行問題仍然是個很頭大的問題。我參考過蕃薯藤、 Kimo 討論區斷行處理方式,還沒有找到一個比較好的解決方法。這是個仍待解決的問題。

    + +

    女聲訂閱頁加上了女聲編輯的 E-mail ,以便無法訂閱時有路可循。 HTTP 403 是 Forbidden ,用來保護網站管理程式和女聲訂戶資料。

    + +

    9 月 28 日,做出了 robot.txt 。這是用來告訴外面的搜尋引擎,哪些地方不可以拿去做全文檢索資料庫。這樣可以避免搜尋引擎把網站管理程式等等的東西都拿去建檔了。

    + +

    10 月 11 日,網站改用 mod_perl 。這是另一個重要的里程碑。因為公司不用 Perl ,所以一直不知道該怎麼用傳說中的 mod_perl 來加強網站程式效率。後來我找到了 mod_perl 和 mod_perl 的安裝、設定說明,重新安裝整個 Apache 伺服器。沒想到 mod_perl 的 HTTP 標頭處理方式又和 Apache CGI 不一樣。為了避免日後同樣的困擾,我捨棄手動設定標頭,改用 CGI::header() 模組來處理 HTTP 標頭。同時我也拿掉自己寫的 time2str() ,改用 HTTP::Date::time2str()

    + +

    改用 CGI::header() 處理標頭後,解決了另一個問題: mod_perl 無法持續連線。只要使用 CGI::header() ,就能夠啟動 Apache::Registry 內部的 HTTP 標頭解析引擎,處理連線的相關問題。

    + +

    我開始捨棄過去的做法。過去為了避免載入外部模組浪費系統資源,我儘量自己寫所需要的模組。現在我儘量引用別人寫好的外部模組,以保持系統的相容性。這是很重要的觀念改變,尤其在 Perl 和 UNIX 程式寫作觀念上:合作。 Perl 程式應該是不同人努力合作的成果,而不是一個程式單打獨鬥處理所有的問題。

    + +

    UNIX 環境也是。不同程式、行程間相互呼叫、配合、傳遞訊息,以得到結果。 Win32 也可以這樣,只是工具太少,而且所耗的系統資源太多。這也違背了 Win32 環境最初的設計目標。

    + +

    這時候,才真正進入了 UNIX 的世界,一個和 DOS/Win32 完全不同的世界。

    + +

    另外, mod_perl 會載入所需模組並常駐在 Apache 行程中,會造成模組變數的混淆。我把原來在共用模組設定的變數,如 $ID 、$THIS_FILE ,搬到個別程式裏設定。為了避免不同網站的共用模組,因為常駐時名稱相同而混淆,我也更改了共用模組的名稱。

    + +

    我寫了一個有點複雜的算式計算留言本每一冊的最後更新日期。這個算式後來還是改掉了,以避免瀏覽器快取的時間計算混亂。

    + +

    我下載了 W3CHTML 認證程式網站,開一個虛擬主機來執行。

    + +

    同一個晚上,我用 gethostbyname() 寫出比較有效的計數器網域判別準則。我也小小修改了前面所提,留言本最後更新日期的算式,以解決沒有留言時無法計算最後更新日期的錯誤。另外,留言存檔後的自訂 HTTP 303 See Other 重新導向訊息,因為 mod_perl 會自行追加 HTTP 303 訊息,導致訊息長度錯亂,使瀏覽器無法判斷訊息長度。我暫時拿掉訊息長度 HTTP Content-Length 標頭,以解決問題。

    + +

    10 月 19 日,我在每個檔案開檔時加上了 flock() 檔案鎖定,以避免檔案同時讀寫錯亂。這是很久以前就該做的,可是因為一直不清楚 flock() 檔案鎖定的做法,所以沒加上去。這兩天仔細讀了 flock() 的相關說明,覺得很有效,就加上去了。另外,因為使用了新的檔案鎖定方法,我也重寫了女聲訂閱程式的流程。女聲訂閱程式流程還要再改寫,以解決另一個問題:檔案最後更新日期的判定方式。

    + +

    其次,我也寫了自訂的 HTTP 500 伺服器內部錯誤訊息,並欄截了開檔錯誤,產生 HTTP 500 訊息,以解決網站管理程式重建網頁時,網頁明明沒有更新,卻毫無警告訊息的老問題。

    + +

    10 月 27 日那個週末是另一次重期的日期。我把之前想得到所有的大小 bug ,利用兩天三夜的周末假期都解決了。分列如下:

    + +
      +
    1. 欄截了所有的檔案讀寫和其它系統函式的錯誤,並產生 HTTP 500 錯誤訊息,以更嚴密地保護程式正常運作。 HTTP 500 原本以 exit() 結束,改以 die 結束,在伺服器錯誤記錄中留下記錄。
    2. + +
    3. 重寫訪客計數器的流程,減少不必要的檔案鎖定,避免計數器卡死。計數器改以 grep() 判定內部位址。
    4. + +
    5. 摸清楚了 cookies 的詳細運作傳遞方式,簡化了計數器的 cookies ,停用 CGI::Cookies 模組,改用 CGI::header() 簡化處理。
    6. + +
    7. 摸清楚了 GD 模組的運作方式,簡化了計數器、最後更新日期、訂戶人數圖形的處理。
    8. + +
    9. 找到了判別網路作業系統的方式,改寫了 Win32 下的安全管制判別流程,並改以 getgrnam()getpwnam() 來做 Linux 下的安全管制。
    10. +
    + +

    10 月 28 日星期六,我改寫了所有網站管理程式的介面和資料庫,把關鍵字加上去,終於把不同的關鍵字整合進網頁中。我想做好網頁的關鍵字系統已經想了很久了。我順便改寫了相關連結的設定介面,提供更大的功能和彈性。另外,我也寫了旅舍的著作權聲明和隱私權聲明,並把旅舍中的女聲著作權聲明連結到女聲去。

    + +

    隱私權聲明是我之前一直想寫的。既然前一天我把 cookies 的傳遞細節弄清楚了,就順便一起寫出來。希望這可以提醒大家不要在網路上亂留個人資料。至於著作權聲明嘛…原則上我很討厭著作權這種玩意兒。可是最近有些商業網站太過份了,而且有些莫名其妙的人開始對我的網站和我的文章感興趣。(不知道我招惹到什麼了?)為了避免不必要的麻煩,還是寫清楚比較好。

    + +

    10 月 29 日星期天,我改進了自訂錯誤訊息,欄截自訂錯誤訊息本身的開關檔錯誤,並在發生自訂 HTTP 500 伺服器內部錯誤時,寄一封信通知網站管理者。

    + +

    解決了之前另一個問題:因為程式無法處理 If-Modified-SinceHTTP 標頭,而且最後更新日期按照先前所述,會追溯到先前的留言日期,導致瀏覽器在重讀網頁時,快取的日期和資料內容錯亂,使瀏覽器卡死。我決定捨棄前述的最後更新日期算式,改以留言板程式本身和留言板資料檔的最後更新日期為準,以方便瀏覽器快取資料更新。我並且加上了對 If-Modified-Since HTTP 標頭的支援,加上了 HTTP 304 Not Modified 自訂訊息,以支援瀏覽器快取功能。

    + +

    我寫了自訂 HTTP 405 Method Not Allowed 錯誤,避免有人用 PUT / DELETE / TRACE 等…連上來。雖這種事情應該不可能發生,可是一旦發生了卻沒有處理,是很笨的事。

    + +

    到這裏,網站程式算是告一段落。我想得到的大小問題解決得差不多了,也鬆了一大口氣。

    + +

    11 月 2 日,旅人留言簿資料已經接近 600筆,原來的資料庫引擎已經超出負荷,出現嚴重停滯現象。經過執行速度比對實驗後,我改寫了資料庫引擎。原來程式是一筆一筆比對,改用整批比對的方式,雖然有點取巧,但大幅度加快了資料庫解析速度。現在的新資料庫引擎,即使超過 6,000 筆留言,仍保持極快的速度。超過 10,000 筆以後呢?那以後再說吧。原則上,留言簿留言我不打算用 SQL 資料庫,維持最基本的原則:可攜性。我希望整個網站隨時可以搬到別的伺服器上,不需要依賴外在環境的特殊因素,例如:是 MySQL ? mSQL ? PostgreSQL ? MS-SQL ? Access ODBC ?還是 IBM DB2 ?

    + +

    因為網站工程告了一段落,我開始打算釋出旅舍依瑪的原始程式碼。這個工程有點浩大,因為即使我程式碼寫得很清楚,可是註解卻不多,如果要釋出,還要加上很多註解,才能讓別人看得懂。

    + +

    前天 11 月 3 日週末,我嚐試把旅舍搬回 Win32 IIS 的環境下,發現問題遠比我想像的複雜。 PerlIS 無法正常處理 HTTP 標頭、 IIS CGI 無法正確設定程式執行目錄, Apache mod_perl Apache::Registry 模組處理 CGI::header() 的方式也很特殊。我花了三天、翻遍 Perl 、mod_perl 的說明和討論以後,總算寫出程式,改用絕對檔案路徑,以取得最大的相容性,並根據特殊情形修正 HTTP 標頭。我並且解決了前述的問題: mod_perl Apache::Registry 模組下, CGI::header() 自訂 HTTP 錯誤會自動加上內文,導致內文長度錯亂亂,瀏覽器無法判別的問題。現在程式若是在 mod_perl 下,不會送出自訂錯誤訊息內文,將內文交給 mod_perl 處理。

    + +

    我重寫了圖形程式(計數器、上次更新日期、訂閱人數)處理流程,以和其它程式的流程慣例一致。

    + +

    想做的事還有一些。女聲訂閱程式的流程還要再改寫,先處理訂閱要求,再判斷最後更新日期。現在的順序是倒過來的。另外,要加強程式的註解,才能釋出程式碼。而且,還要加上記錄網站版本的變更。

    + +

    釋出程式碼其實沒什麼大不了。現在的留言板、計數器的免費程式碼到處都是。但總是一個重要的里程碑。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 1 | + 2 | + 3 | + 4 | + 5 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0003.html.en.html b/htdocs/imacat/me/changelog/0003.html.en.html new file mode 120000 index 0000000..32127b2 --- /dev/null +++ b/htdocs/imacat/me/changelog/0003.html.en.html @@ -0,0 +1 @@ +0003.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0003.html.en.xhtml b/htdocs/imacat/me/changelog/0003.html.en.xhtml new file mode 100644 index 0000000..ff0e675 --- /dev/null +++ b/htdocs/imacat/me/changelog/0003.html.en.xhtml @@ -0,0 +1,528 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 3 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 3

    + +
    + +
    + +
    +
    Date: 10.3.’05.
    + +
      +
    1. 調整了網頁的樣式,儘可能去掉 <hr /> ,改以 CSS 的邊框代替,以符合無障礙網頁規範的要求。
    2. +
    3. 調整了首頁的樣式,黑貓改為 float 到右邊,讓下面的文字移到上面來,以便利閱讀。
    4. +
    5. 調整了旅舍日記的樣式,改用一篇一篇白紙張貼的樣式。
    6. +
    7. 加上無障礙網頁的導盲磚設計。
    8. +
    9. 加上直接跳到網頁內文區的設計。
    10. +
    11. 移除 magicat 下的樣式表,統一改用 magicat.css 代替。
    12. +
    13. 移除 background: fixed 的設定。去除掉無聊的特效,網頁看起來比較正常。
    14. +
    + +

    要怎麼處理瀏覽列,才能讓它看起來簡潔,又能保持簡單呢?煩惱中。

    + +
    + +
    + +
    +
    Date: 6.30.’05.
    + +
      +
    1. Selima::Checker::AccountSelima::Checker::Content 的功能移到 Selima::Checker ,移除 Selima::Checker::AccountSelima::Checker::Content 兩個不必要的中層基礎類別。
    2. +
    3. 加上 Selima::Processor 資料處理類別。
    4. +
    + +
    + +
    + +
    +
    Date: 6.3.’05.
    + +
      +
    1. Selima::List 加上 html_lists_switch() 以顯示多重列表。
    2. +
    + +
    + +
    + +
    +
    Date: 5.27.’05.
    + +
      +
    1. 內容管理系統存檔時(旅舍日記、更新日誌、繼續旅行等),加上正體中文轉簡體中文自動轉換,不需要再到簡體中文頁面編輯、轉換。
    2. +
    3. 修正旅舍日記和更新日誌目錄頁,中文數字使用 big5/gb ,而不是使用 traditional/simplifide ,造成的編碼錯誤。
    4. +
    5. 修正更新日誌目錄頁,連結到旅舍日記的錯誤。
    6. +
    + +
    + +
    + +
    +
    Date: 5.11.’05.
    + +
      +
    1. Selima::List::Actlog and actlog.cgi are added to browse the web site activity log.
    2. +
    3. $Selima::Logging::ACTLOG was not reset when the script begins. Activities were logged into the log file of the first connection, but not the file of this current project. This is fixed now.
    4. +
    + +
    + +
    + +
    +
    Date: 5.7.’05.
    + +
      +
    1. Perl's decoded UTF-8 text is now used throughout the script. It is encoded to the target character set just before the page is output. This helps the code consistency and make my life easier.
    2. + +
    3. getcharset() is added to Selima::GetLang. It is used to obtain the best character set for the client, base on the algorithm described in RFC 2616 HTTP 1.1 section 14.2. But it is not used yet.
    4. + +
    5. Selima::GetLang::getlang() was modified to be more modulized and meet the algorithm described in RFC 2616 HTTP 1.1 section 14.2.
    6. + +
    7. The following 2 variables are not used and hence removed: $MY_CHARSET and $KEY_ENCODING.
    8. + +
    9. Now Selima::SetL10N loads Encode::Big5Common and Encode::HanExtra first, to ensure that the Big5-Common and GB18030 character sets are installed. This helps solve the issue that I forgot to install Encode::HanExtra and GB18030 character set, that some Simplified Chinese messages are not properly decoded and processed.
    10. +
    + +
    + +
    + +
    +
    Date: 5.4.’05.
    + +
      +
    1. Simplified Chinese PO translation was converted with iconv in Makefile first. No more run-time conversion with Encode::HanConvert.
    2. +
    + +
    + +
    + +
    +
    Date: 4.27.’05.
    + +
      +
    1. The text 繁體中文 on the website is corrected to 正體中文.
    2. +
    + +
    + +
    + +
    +
    Date: 4.5.’05.
    + +
      +
    1. Fixed the error that remote_host() may return undef, which was not dealt with in Selima::Logging::log_error() and Selima::Logging::log_warn().
    2. + +
    3. Fixed the caching algorithm when lookup failed in Selima::RemoHost::remote_host().
    4. +
    + +
    + +
    + +
    +
    Date: 3.26.’05.
    + +

    Upgraded Perl to version 5.8.6.

    + +
    + +
    + +
    +
    Date: 3.14.’05.
    + +

    The following methods were added to the Selima::Form class: _val_scalar() and _val_date(). All references to echovalue() were removed. The following functions were removed from the Selima::EchoForm module: echovalue().

    + +
    + +
    + +
    +
    Date: 3.13.’05.
    + +

    2 new web sites are added to the related links:

    + +
      +
    1. Feminism China
    2. + +
    3. Books To Watch Out For: The Lesbian Edition
    4. +
    + +
    + +
    + +
    +
    Date: 3.13.’05.
    + +

    Edit the 12 change log entries grabbed from the Travellers' Guestbook (from 2003-03-31 to 2005-02-20), change its format from plain text message to structural HTML, and add their English translation.

    + +
    + +
    + +
    +
    Date: 3.12.’05.
    + +

    Partial page rebuild rebuild_partial_pages() is added to Tavern Diary and Change Log.

    + +
    + +
    + +
    +
    Date: 3.1.’05.
    + +

    I'll write some description about Selima 1 and 2 when I'm free.

    + +

    This change log is not in a proper standard programming format, though. ^^;

    + +
    + +
    + +
    +
    Date: 3.1.’05.
    + +

    I was writing the web page management subsystem for Selima in the last couple of days. It should be the last and most important subsystem of Selima in the forseeable future. Currently Selima has: User management, guestbook management, related links management, Woman's Voice newsletter management, diary management and change log management subsystems. But they are all subordinate. A content management system is to manage the web pages. Without that it is nothing.

    + +

    The web page management subsystem needs picture uploads, but the picture upload management subsystem is missing yet. In the past few days I was moving the codes of the picture upload subsystem from the PHP Monica project and rewritting them as Perl. This task is a lot more difficult than I expected. The picture upload management subsystem of Monica has grown for years. It has already grown extremely complicated and mature. I cannot hardly recognized those long long codes that were made by myself. I find myself very awful, to made such a large and complicated thing. It's like mountain climbing: You just climb and climb and climb, and when you rest in the mid-slope of the mountain and look downward, you suddenly realized that you have gone so far and climbed so high! Did I really wrote this large, complicated, mature Monica system? I can hardly believe it. ^_*'

    + +

    A large part of the picture upload subsystem is to be migrated yet. Then my original target -- web page management subsystem. And then integrate it with the related links and the diary management subsystems. It's still a long way to go.

    + +
    + +
    + +
    +
    Date: 3.1.’05.
    + +
      +
    1. The method _html_col_pic() is added in Selima::Form, to display picture columns.
    2. + +
    3. The following functions: picurl(), picinfo(), picstyle(), check_pic_ratio(), best_pic_ratio(), newpicx(), newpicy(), echopic(), picpos_label(), and the following constants: PIC_MAX_WIDTH, PIC_MAX_HEIGHT, PIC_MAX_RATIO, @PIC_VALID_POS, %PIC_POS_LABEL, PIC_POS_DEFAULT, SHOWPIC_SCRIPT, are added in Selima::Picture.
    4. +
    + +
    + +
    + +
    +
    Date: 2.27.’05.
    + +

    Two web page manuplation classes Selima::Page and Selima::PageList are written.

    + +
    + +
    + +
    +
    Date: 2.25.’05.
    + +

    I have made a new About Tavern IMACAT's page and wrote some introduction to the website.

    + +
    + +
    + +
    +
    Date: 2.25.’05.
    + +

    This is Selima 2.13. The Tavern change log manager is finished.

    + +

    The change log manager is no different than the Tavern Diary manager. It's only a one-way guestbook system: The back-end management interface is a guestbook program, while the front-end is a page generation and output program.

    + +

    The harder part is to import the old change logs. Unlike Travellers' Guestbook or Tavern Diary which were originally saved in a database-like XML file, change logs were merely an plain HTML web page. Batch import does not work here. I have to open the file, edit and submit the log entries manually.

    + +

    But, for this reason, I re-read the change log once. Well… Seeing myself making different decisions for various reasons, encountering all kinds of difficulties and trying to figure out solutions… Quite interesting, isn't it? ^_*'

    + +

    Because the change log were difficult to edit, I stopped writing new change log after 2000-11-05. Changes were announced on Tarvellers' Guestbook after that. Thus log entries after 2000-11-05 are grabbed from the guestbook. Mosts are small fragments. But their writing styles are more easy. They are more interesting than their ancestors.

    + +

    I'll have to start writing change log more often. It's fundamental for a programmer.

    + +
    + +
    + +
    +
    Date: 2.20.’05.
    + +

    This is Selima 2.12. The Tavern Diary editorial system is finally finished. The abandoned Tavern Diary can finally be restart after 4 years. I don't have to put everything onto the Travellers' guestbook and have my own place to talk to myself now. ^_*'

    + +
    + +
    + +
    +
    Date: 11.3.’04.
    + +

    Today a big thing is done: The related links/keep travelling administrative interface is finally finished. The maintainance of the related links suspended for so many years is restarted. ^_*' Although there are still several obscure bugs, but it is running now.

    + +

    This is a major milestone of Selima 2: Selima has finally make its first step toward a fully-functional content management sysstem. It has its first content managemnet subsystem. ^_*' Ha ha.

    + +

    I have finally achived it. Now I have to suspend Selima temporarily and catch up my mid-term exam now.

    + +
    + +
    + +
    +
    Date: 10.24.’04.
    + +

    I finally got rid of Selima 1's old codes, and upgraded all the programs on Tavern, Woman's Voice and others to Selima 2's database-based system. All those obscure codes of Selima 1 are removed. So fresh and cool! ^_*' Ha ha!

    + +
    + +
    + +
    +
    Date: 10.24.’04.
    + +

    The new Travellers' Guestbook is up and running now. The core is the Selima system version 2 with PostgreSQL database management system. The guestbook pages is renumbered. It's slower, but more powerful.

    + +

    Please tell me if you encounter any problem.

    + +
    + +
    + +
    +
    Date: 3.22.’04.
    + +

    I'm thinkg about using database system in Selima. I might use MySQL.

    + +
    + +
    + +
    +
    Date: 9.26.’03.
    + +

    I just fixed a small bug in the Selima Travellers' Guestbook system.

    + +

    In a previous guestbook message the Russian letters ТАТУ was not displayed correctly. I did not check that issue then. In my previous message the Japenese letters ヒッタイト (Hittite) was not displayed again. I made some check this time, and found it a problem of the Big5 encoding standard. The original Big5 standard built by the major 5 Chinese companies did not include Japanese letters. Later for convienence the ETen Chinese company adds Japanese letters, governmental symbols and other extended characters. But then Microsoft did not adapt ETen's extension in the MS-Windows, but added some European letters and form another Big5's variant. The extended version of Big5 by ETen is now called Big5-ETen, and Microsoft name its Big5 as CP950. The Big5 in Perl's Encode is actually Big5-ETen, with Japanese and Russian letters included and mapped to somewhere in Big5-ETen. But they do not exists in Windows CP950. Then the mapped somewhere cannot be displayed in Windows.

    + +

    Now I mapped to CP950. Japanese letters and Russian letters do not map to Big5 and are displayed as its Unicode representation. I don't like Micorosft. But It should be a correct answer not to map the Japanese and Russian letters to Big5.

    + +
    + +
    + +
    +
    Date: 6.4.’03.
    + +

    I was trying a crazy idea: Writing my own web mail. I thought it was simple, but it stuck now.

    + +

    It seems that the Selima system is not flexable enough. It is quite a failure.

    + +

    Monica, the ancestor of Selima, encountered the same problem, too. I tried to make picture upload and project management, and it stuck there. It is too large, too firm, not flexible, not extensible.

    + +

    Annoyed.

    + +
    + +
    + +
    +
    Date: 5.13.’03.
    + +

    The network of Tavern/Woman’s Voice has been upgraded to 512Kbps. The connection of the web site should speed up a lot. Besides, because the bandwidth is large now, without the fear to cause the network jam, I start to check my own mail when I’m in the office. Together with the new message e-mail notification of the current Selima system, I shall be able to answer the guestbook messages more immediately. ^_*'

    + +

    Of course I have to know how to answer them first. The answering time of a Virgo is quite long, though. ^^;

    + +
    + +
    + +
    +
    Date: 4.26.’03.
    + +

    A bug in the guestbook is solved. He he. ^^;

    + +

    A small place was left unchanged when I was making some foundamental redesign. It was left there for so many days without notice… :p

    + +
    + +
    + +
    +
    Date: 4.18.’03.
    + +

    I made some experiment tonight. The Selima system used in Travellers’ Guestbook would not be run easily under Windows for the use of gettext in GNU glibc as the multilingual solution. It needs cygwin. Or I should say, it would not be run easily besides of Unix.

    + +

    I had considered using Perl’s Maketext as the multilingual solution. Maketext is the current standard multilingual solution for Perl. It does not require GNU glibc and thus can be run on any platform. But Maketext has too less tools and its API is quite complicated. The design is not as neat as gettext. So lets just forget it.

    + +

    Besides, because Selima uses Encode, it has to be run with Perl 5.8.0 or above. It cannot be run with earlier versions of Perl.

    + +

    I thought Selima should be cross-platform with high compatibility. I was wrong. ^^;

    + +
    + +
    + +
    +
    Date: 4.10.’03.
    + +

    The Selima guestbook system is almost finished. The new message notification is now sending mails with Sendmail in the background, to speed up the responding time. I have almost everything I want now.

    + +

    The whole Selima is written purely with Perl. In this age of PHP I want to prove one thing: Perl is fare more excellent and powerful than PHP.

    + +

    Selima is optimized for mod_perl. There are many optimization. But it still maintains the compatibility with Perl/CGI. I even cached the whole guestbook index in Apache’s memory. With the current amount of messages, displaying a page under Perl/CGI it takes about 0.26 seconds, under mod_perl caching it speeds up to 0.03 seconds. With client cache it even busts up to 0.006 seconds!

    + +

    You can feel the true meaning of speed with Selima. You’ll never feel any delay besides your bandwidth. Running CGI programs as a static page -- That’s POWER. ^_*'

    + +

    How can PHP catch this? Ha ha!

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 1 | + 2 | + 3 | + 4 | + 5 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0003.html.zh-cn.html b/htdocs/imacat/me/changelog/0003.html.zh-cn.html new file mode 120000 index 0000000..eb8c5f2 --- /dev/null +++ b/htdocs/imacat/me/changelog/0003.html.zh-cn.html @@ -0,0 +1 @@ +0003.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0003.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0003.html.zh-cn.xhtml new file mode 100644 index 0000000..162b22d --- /dev/null +++ b/htdocs/imacat/me/changelog/0003.html.zh-cn.xhtml @@ -0,0 +1,528 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷三 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷三

    + +
    + +
    + +
    +
    日期: 10.3.’05.
    + +
      +
    1. 调整了网页的样式,尽可能去掉 <hr /> ,改以 CSS 的边框代替,以符合无障碍网页规范的要求。
    2. +
    3. 调整了首页的样式,黑猫改为 float 到右边,让下面的文字移到上面来,以便利阅读。
    4. +
    5. 调整了旅舍日记的样式,改用一篇一篇白纸张贴的样式。
    6. +
    7. 加上无障碍网页的导盲砖设计。
    8. +
    9. 加上直接跳到网页内文区的设计。
    10. +
    11. 移除 magicat 下的样式表,统一改用 magicat.css 代替。
    12. +
    13. 移除 background: fixed 的设定。去除掉无聊的特效,网页看起来比较正常。
    14. +
    + +

    要怎么处理浏览列,才能让它看起来简洁,又能保持简单呢?烦恼中。

    + +
    + +
    + +
    +
    日期: 6.30.’05.
    + +
      +
    1. Selima::Checker::AccountSelima::Checker::Content 的功能移到 Selima::Checker ,移除 Selima::Checker::AccountSelima::Checker::Content 两个不必要的中层基础类别。
    2. +
    3. 加上 Selima::Processor 资料处理类别。
    4. +
    + +
    + +
    + +
    +
    日期: 6.3.’05.
    + +
      +
    1. Selima::List 加上 html_lists_switch() 以显示多重列表。
    2. +
    + +
    + +
    + +
    +
    日期: 5.27.’05.
    + +
      +
    1. 内容管理系统存档时(旅舍日记、更新日志、继续旅行等),加上正体中文转简体中文自动转换,不需要再到简体中文页面编辑、转换。
    2. +
    3. 修正旅舍日记和更新日志目录页,中文数字使用 big5/gb ,而不是使用 traditional/simplifide ,造成的编码错误。
    4. +
    5. 修正更新日志目录页,连结到旅舍日记的错误。
    6. +
    + +
    + +
    + +
    +
    日期: 5.11.’05.
    + +
      +
    1. 加上 Selima::List::Actlogactlog.cgi 以浏览网站活动日志。
    2. +
    3. 修正 $Selima::Logging::ACTLOG 之前一直没有正确在程式执行前重设,导致一直都是记在第一个连线的活动日志档,没有记在现行专案的活动日志档的错误。
    4. +
    + +
    + +
    + +
    +
    日期: 5.7.’05.
    + +
      +
    1. 内部全部改用 Perl UTF-8 解码字串处理,输出时才依所需字集编码,以简化内部一致性。
    2. + +
    3. Selima::GetLang 加上 getcharset() 函式,依 RFC 2616 HTTP 1.1 第 14.2 节规定的演算法,取得最适当的输出字集。目前暂无用途。
    4. + +
    5. 修改 Selima::GetLang::getlang() 函式,以更加模组化,并更加符合 RFC 2616 HTTP 1.1 第 14.4 节规定的演算法。
    6. + +
    7. 取消使用 $MY_CHARSET$KEY_ENCODING 两个变数。
    8. + +
    9. Selima::SetL10N 现在会先行载入 Encode::Big5CommonEncode::HanExtra ,以确保系统有安装 Big5-CommonGB18030 两个字集,解决之前忘记安装 Encode::HanExtra ,没有 GB18030 字集,部份简体中文留言无法正确处理的问题。
    10. +
    + +
    + +
    + +
    +
    日期: 5.4.’05.
    + +
      +
    1. 简体中文在 Makefile 里用 iconv 先做好 PO 档,不再即时用 Encode::HanConvert 转换。
    2. +
    + +
    + +
    + +
    +
    日期: 4.27.’05.
    + +
      +
    1. 网站上的繁体中文字样更正为正体中文
    2. +
    + +
    + +
    + +
    +
    日期: 4.5.’05.
    + +
      +
    1. 修正 Selima::Logging::log_error()Selima::Logging::log_warn()remote_host() 传回值有可能是 undef 的错误。
    2. + +
    3. 修正 Selima::RemoHost::remote_host() 里查不到时回传 undef 的快取处理方式。
    4. +
    + +
    + +
    + +
    +
    日期: 3.26.’05.
    + +

    Perl 升级到 5.8.6 版。

    + +
    + +
    + +
    +
    日期: 3.14.’05.
    + +

    Selima::Form 类别加上 _val_scalar()_val_date() 方法,移除所有 echovalue() 的参考; Selima::EchoForm 模组删掉 echovalue() 函数。

    + +
    + +
    + +
    +
    日期: 3.13.’05.
    + +

    继续旅行相关连结加上两个网站:

    + +
      +
    1. 女权中国
    2. + +
    3. Books To Watch Out For: The Lesbian Edition
    4. +
    + +
    + +
    + +
    +
    日期: 3.13.’05.
    + +

    编辑从过去旅人留言簿上,抓来的 12 篇更新日志( 2003-03-31 到 2005-02-20 ),由随笔留言的纯文字格式,改为有段落结构标记的 HTML 格式,并加上英译。

    + +
    + +
    + +
    +
    日期: 3.12.’05.
    + +

    旅舍日记与更新日志,加上部份档案更新 rebuild_partial_pages() 的功能。

    + +
    + +
    + +
    +
    日期: 3.1.’05.
    + +

    有空,我会把 Selima 1 和 Selima 2 的更新说明补上来。

    + +

    现在的更新日志其实不够严格,没有撰写程式应有的标准格式。 ^^;

    + +
    + +
    + +
    +
    日期: 3.1.’05.
    + +

    这两天在写 Selima 系统的网页管理子系统。这大概是短期内, Selima 的最后一个子系统,也是 Selima 最重要的子系统。目前 Selima 的子系统有:使用者权限管理系统、留言板管理系统、相关连结管理系统、女声电子报管理系统、网站日记管理系统、更新日志管理系统等。然而,在网站管理系统中,这些都只是次要的部门。网站管理系统就是要管理网页用的,不能管理网页的话,就什么都不是了。

    + +

    网页管理子系统需要图片上传,不过 Selima 的图片上传管理子系统,其实一直都没有做出来。这两天我从 PHP Monica 把图片上传子系统的程式码移植过来,再改写成 Perl 。移植的过程中,才发现这个工程,比我想像中大很多。 PHP Monica 的图片上传子系统经过多年蕴酿,早已发展成为一个非常复杂、非常成熟的子系统,这两天改写的时候,看到了之前写的、现在快不认得的程式码,好长好长。觉得自己好可怕,竟然能够写出这么庞大、这么复杂的东西。这种感觉就像爬山一样,埋头一直往上爬,半山腰休息的时候一往下看,才发现自己竟然已经走了这么远,爬得这么高了。 PHP Monica 这么庞大、复杂、成熟的系统,真的是我过去几年来一个字、一个字写出来的东西吗?有种难已置信的感觉。 ^_*'

    + +

    Selima 的图片上传管理子系统,还有很大一部份还没移植好。然后是原来的目标—网页管理子系统,然后是把相关连结、日记管理等等子系统,一起整合进来。想想还有好一段路要走。加油~

    + +
    + +
    + +
    +
    日期: 3.1.’05.
    + +
      +
    1. 写了 Selima::Form 里的 _html_col_pic() 方法,显示图片设定栏位。
    2. + +
    3. 补上 Selima::Picture 里的 picurl()picinfo()picstyle()check_pic_ratio()best_pic_ratio()newpicx()newpicy()echopic()picpos_label() 等函数,及 PIC_MAX_WIDTHPIC_MAX_HEIGHTPIC_MAX_RATIO@PIC_VALID_POS%PIC_POS_LABELPIC_POS_DEFAULTSHOWPIC_SCRIPT 等常数等等。
    4. +
    + +
    + +
    + +
    +
    日期: 2.27.’05.
    + +

    写出了网页管理用的 Selima::PageSelima::PageList 两个类别。

    + +
    + +
    + +
    +
    日期: 2.25.’05.
    + +

    重做了关于旅舍依玛,写了一段旅舍的简介。

    + +
    + +
    + +
    +
    日期: 2.25.’05.
    + +

    这是 Selima 2.13 。我把旅舍更新日志管理程式写出来了

    + +

    旅舍更新日志程式,基本上跟旅舍日记程式差别不大,都是单向的留言板系统:后台管理界面是留言板程式,而前端则是网页制作输出程式。

    + +

    比较辛苦的是旧日志汇入工作:旅舍更新日志不像留言板或旅舍日记一样,原本就存在类资料库格式的 XML 档中。原来的更新日志只是一个普通的 HTML 网页。我没办法写程式直接整批汇入,只能叫出档案,手动一段一段编辑、输入。

    + +

    不过也因此,重读了整个更新日志。呵。看著以前的自己决定这样做那样做的理由,碰到种种的困难并苦思解决之道,很有趣呢~ ^_*'

    + +

    2000 年 11 月 5 日以后,因为不易编辑,我就没有再写更新日志了,有更新都公告在旅人留言簿上。因此 2000 年 11 月 5 日以后的部份,是从旅人留言簿上找来的,有点零碎,可是语气比较生活化,读起来比较有趣。

    + +

    以后要勤快记日志。记日志是撰写程式的基本工夫。基本工夫要做扎实。嗯。

    + +
    + +
    + +
    +
    日期: 2.20.’05.
    + +

    这是 Selima 2.12 。旅舍日记编辑系统终于完成了。荒废了四年没写的旅舍日记,终于可以开始动笔了。以后我有地方可以自言自语,不用什么东西都来写旅人留言簿了~ ^_*'

    + +
    + +
    + +
    +
    日期: 11.3.’04.
    + +

    今天完成了一件大事:相关连结/继续旅行的管理界面,终于完工了。好几年无法管理维护的相关连结,终于又可以正常维护了。 ^_*' 虽然还有几个晦瑟不明的 bug ,不过大体上已经可以正常管理了。

    + +

    这是 Selima 2 的大事: Selima 终于向一个完整的内容管理系统,迈开了第一步,实作出了第一个内容管理的功能~ ^_*' 呵呵。

    + +

    接下来要赶期中考了。终于安心了,放下心中的一块大石。我要暂时把 Selima 搁著了~ ^_*'

    + +
    + +
    + +
    +
    日期: 10.24.’04.
    + +

    终于摆脱了 Selima 1 的奇怪旧程式,把旅舍、女声和各个网站的程式,全面升级到 Selima 2 的资料库系统。旧 Selima 1 麻烦又不好维护的程式码都一一删掉了,心情超好中~ ^_*' 呵呵~

    + +
    + +
    + +
    +
    日期: 10.24.’04.
    + +

    旅人留言簿新程式上路。目前核心是搭配 PostgreSQL 资料库的第二代 Selima 系统。留言簿页数会重排。速度会稍微慢一些,不过功能更强。

    + +

    若有任何问题,请随时告知。

    + +
    + +
    + +
    +
    日期: 3.22.’04.
    + +

    我正在考虑把旅舍的 Selima 系统资料库化。资料库系统方面,可能会采用 MySQL

    + +
    + +
    + +
    +
    日期: 9.26.’03.
    + +

    刚刚修正了旅人留言簿 Selima 系统的一个小问题。

    + +

    之前留言时,ТАТУ不知道为什么,俄文显示出来变成乱码,当时我也未加深究。刚刚留言,尼罗河女儿的ヒッタイト(比泰多王国)日文又变成乱码,我进去查了一次。原来是 Big5 编码标准混乱的问题。当初五大中文商共同订定的原始 Big5 大五码里,不包含日文及一些扩充字元。后来倚天中文为了方便起见,自己在 Big5 加了日文、公文符号及一些扩充字元。可是后来微软 Windows 所用的 Big5 里,没有加上那些扩充字元,形成了另一个版本的 Big5 。倚天扩充版的 Big5 俗称 Big5-ETen ,微软的 Big5 自己取了一个名字叫 CP950 。 PerlEncode 里的 Big5 ,取的是 Big5-ETen ,日文和俄文,都在 Big5-ETen 里有码位,直接对映到 Big5-ETen 的字,可是 Windows 下的 CP950 里没有这些字,所以就变成乱码。

    + +

    我现在改映到 CP950 ,日文和俄文不映到 Big5 下的码位,会正确以 Unicode 表示法显示。虽然很讨厌微软,不过在 Unicode 时代,日文和俄文对应到 Unicode 而不是 Big5 ,应该是比较正确的做法。

    + +
    + +
    + +
    +
    日期: 6.4.’03.
    + +

    最近突发奇想,想自己写一个 web mail 。本来以为很简单,但是现在看样子是卡住了。

    + +

    看样子, Selima 系统的弹性似乎还不够大,蛮失败的。

    + +

    Selima 的前身,公司的 Monica 系统,也面临了同样的问题。想从 Monica 做出图档上传,和专案管理的功能,却碰到了瓶颈。系统太大,也太硬了,没什么弹性,难以扩充。

    + +

    颇烦。

    + +
    + +
    + +
    +
    日期: 5.13.’03.
    + +

    旅舍/女声的线路已升级为双向 512Kbps ,以后网站连线速度会提高很多。此外,因为频宽变大,不怕为了收信瘫痪家里的网路,我也开始在公司收家里的 E-mail 了。加上现在的 Selima 系统的留言邮件通知,对於留言的回应会比以前更即时~ ^_*'

    + +

    当然,也要我想得到该怎么回应才有用。处女座的即时反应是很差的。 ^^;

    + +
    + +
    + +
    +
    日期: 4.26.’03.
    + +

    解决了一个留言本的 bug ,呵。 ^^;

    + +

    之前改了一些基本的设计,可是有个小地方没有跟著改。那么多天了都没发现… :p

    + +
    + +
    + +
    +
    日期: 4.18.’03.
    + +

    今天晚上实验了一下,旅人留言本所用的 Selima 系统,因为多语切换用到 GNU glibcgettext ,所以应该很难在 Windows 下跑(要装 cygwin )。应该说,要在 Unix 之外的作业系统上跑,难度不小。

    + +

    我有考虑过,多语切换用 Perl 专用的 MaketextMaketext 是目前 Perl 的多语标准,不需要 GNU glibc ,可以在任何作业系统上跑。不过 Maketext 工具太少,而且撰写介面颇复杂,整体设计不如 gettext 简洁方便,所以还是算了。

    + +

    另外, Selima 因为用到 Encode ,所以一定要在最新的 Perl 5.8.0 以上跑,无法在之前的 Perl 上跑。

    + +

    我一直以为 Selima 可以跨平台作业,相容性很高,没想到条件其实很严苛~~ ^^;。

    + +
    + +
    + +
    +
    日期: 4.10.’03.
    + +

    Selima 的留言板系统,差不多撰写完成了。留言通知也改用 Sendmail 幕后寄信,加快程式本身反应速度。该要的功能都做出来了。

    + +

    整个 Selima 系统,都是用纯 Perl 写的。在这个 PHP 当道的时代,我要证明一件事: Perl 远比 PHP 优秀,远比 PHP 强。

    + +

    Selima 是一套特别针对 mod_perl 的特性强化的系统,在很多地方做了效能强化处理,可是还是尽量保持 Perl/CGI 的相容性。我甚至把留言板的资料库索引整个快取在 Apache 的记忆体中。以目前的旅人留言簿留言数量来说,在 Perl/CGI 模式下执行,显示页面约需 0.26 秒, +在 mod_perl 下快取执行,显示页面可以加速到 0.03 秒,如果配合浏览器本身的快取的话,反应时间甚至可以缩短到 0.006 秒!

    + +

    在 Selima 上,你可以真正感觉到快。除了频宽以外,你感觉不到任何停顿。 CGI 程式跑起来像静态网页一样。这才是真正的 Power ^_*'

    + +

    PHP 哪有这种 Power ?哇哈哈哈哈哈~~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 1 | + 2 | + 3 | + 4 | + 5 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0003.html.zh-tw.html b/htdocs/imacat/me/changelog/0003.html.zh-tw.html new file mode 120000 index 0000000..5ea98f4 --- /dev/null +++ b/htdocs/imacat/me/changelog/0003.html.zh-tw.html @@ -0,0 +1 @@ +0003.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0003.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0003.html.zh-tw.xhtml new file mode 100644 index 0000000..83bf939 --- /dev/null +++ b/htdocs/imacat/me/changelog/0003.html.zh-tw.xhtml @@ -0,0 +1,528 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷三 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷三

    + +
    + +
    + +
    +
    日期: 10.3.’05.
    + +
      +
    1. 調整了網頁的樣式,儘可能去掉 <hr /> ,改以 CSS 的邊框代替,以符合無障礙網頁規範的要求。
    2. +
    3. 調整了首頁的樣式,黑貓改為 float 到右邊,讓下面的文字移到上面來,以便利閱讀。
    4. +
    5. 調整了旅舍日記的樣式,改用一篇一篇白紙張貼的樣式。
    6. +
    7. 加上無障礙網頁的導盲磚設計。
    8. +
    9. 加上直接跳到網頁內文區的設計。
    10. +
    11. 移除 magicat 下的樣式表,統一改用 magicat.css 代替。
    12. +
    13. 移除 background: fixed 的設定。去除掉無聊的特效,網頁看起來比較正常。
    14. +
    + +

    要怎麼處理瀏覽列,才能讓它看起來簡潔,又能保持簡單呢?煩惱中。

    + +
    + +
    + +
    +
    日期: 6.30.’05.
    + +
      +
    1. Selima::Checker::AccountSelima::Checker::Content 的功能移到 Selima::Checker ,移除 Selima::Checker::AccountSelima::Checker::Content 兩個不必要的中層基礎類別。
    2. +
    3. 加上 Selima::Processor 資料處理類別。
    4. +
    + +
    + +
    + +
    +
    日期: 6.3.’05.
    + +
      +
    1. Selima::List 加上 html_lists_switch() 以顯示多重列表。
    2. +
    + +
    + +
    + +
    +
    日期: 5.27.’05.
    + +
      +
    1. 內容管理系統存檔時(旅舍日記、更新日誌、繼續旅行等),加上正體中文轉簡體中文自動轉換,不需要再到簡體中文頁面編輯、轉換。
    2. +
    3. 修正旅舍日記和更新日誌目錄頁,中文數字使用 big5/gb ,而不是使用 traditional/simplifide ,造成的編碼錯誤。
    4. +
    5. 修正更新日誌目錄頁,連結到旅舍日記的錯誤。
    6. +
    + +
    + +
    + +
    +
    日期: 5.11.’05.
    + +
      +
    1. 加上 Selima::List::Actlogactlog.cgi 以瀏覽網站活動日誌。
    2. +
    3. 修正 $Selima::Logging::ACTLOG 之前一直沒有正確在程式執行前重設,導致一直都是記在第一個連線的活動日誌檔,沒有記在現行專案的活動日誌檔的錯誤。
    4. +
    + +
    + +
    + +
    +
    日期: 5.7.’05.
    + +
      +
    1. 內部全部改用 Perl UTF-8 解碼字串處理,輸出時才依所需字集編碼,以簡化內部一致性。
    2. + +
    3. Selima::GetLang 加上 getcharset() 函式,依 RFC 2616 HTTP 1.1 第 14.2 節規定的演算法,取得最適當的輸出字集。目前暫無用途。
    4. + +
    5. 修改 Selima::GetLang::getlang() 函式,以更加模組化,並更加符合 RFC 2616 HTTP 1.1 第 14.4 節規定的演算法。
    6. + +
    7. 取消使用 $MY_CHARSET$KEY_ENCODING 兩個變數。
    8. + +
    9. Selima::SetL10N 現在會先行載入 Encode::Big5CommonEncode::HanExtra ,以確保系統有安裝 Big5-CommonGB18030 兩個字集,解決之前忘記安裝 Encode::HanExtra ,沒有 GB18030 字集,部份簡體中文留言無法正確處理的問題。
    10. +
    + +
    + +
    + +
    +
    日期: 5.4.’05.
    + +
      +
    1. 簡體中文在 Makefile 裏用 iconv 先做好 PO 檔,不再即時用 Encode::HanConvert 轉換。
    2. +
    + +
    + +
    + +
    +
    日期: 4.27.’05.
    + +
      +
    1. 網站上的繁體中文字樣更正為正體中文
    2. +
    + +
    + +
    + +
    +
    日期: 4.5.’05.
    + +
      +
    1. 修正 Selima::Logging::log_error()Selima::Logging::log_warn()remote_host() 傳回值有可能是 undef 的錯誤。
    2. + +
    3. 修正 Selima::RemoHost::remote_host() 裏查不到時回傳 undef 的快取處理方式。
    4. +
    + +
    + +
    + +
    +
    日期: 3.26.’05.
    + +

    Perl 昇級到 5.8.6 版。

    + +
    + +
    + +
    +
    日期: 3.14.’05.
    + +

    Selima::Form 類別加上 _val_scalar()_val_date() 方法,移除所有 echovalue() 的參考; Selima::EchoForm 模組刪掉 echovalue() 函數。

    + +
    + +
    + +
    +
    日期: 3.13.’05.
    + +

    繼續旅行相關連結加上兩個網站:

    + +
      +
    1. 女權中國
    2. + +
    3. Books To Watch Out For: The Lesbian Edition
    4. +
    + +
    + +
    + +
    +
    日期: 3.13.’05.
    + +

    編輯從過去旅人留言簿上,抓來的 12 篇更新日誌( 2003-03-31 到 2005-02-20 ),由隨筆留言的純文字格式,改為有段落結構標記的 HTML 格式,並加上英譯。

    + +
    + +
    + +
    +
    日期: 3.12.’05.
    + +

    旅舍日記與更新日誌,加上部份檔案更新 rebuild_partial_pages() 的功能。

    + +
    + +
    + +
    +
    日期: 3.1.’05.
    + +

    有空,我會把 Selima 1 和 Selima 2 的更新說明補上來。

    + +

    現在的更新日誌其實不夠嚴格,沒有撰寫程式應有的標準格式。 ^^;

    + +
    + +
    + +
    +
    日期: 3.1.’05.
    + +

    這兩天在寫 Selima 系統的網頁管理子系統。這大概是短期內, Selima 的最後一個子系統,也是 Selima 最重要的子系統。目前 Selima 的子系統有:使用者權限管理系統、留言板管理系統、相關連結管理系統、女聲電子報管理系統、網站日記管理系統、更新日誌管理系統等。然而,在網站管理系統中,這些都只是次要的部門。網站管理系統就是要管理網頁用的,不能管理網頁的話,就什麼都不是了。

    + +

    網頁管理子系統需要圖片上傳,不過 Selima 的圖片上傳管理子系統,其實一直都沒有做出來。這兩天我從 PHP Monica 把圖片上傳子系統的程式碼移植過來,再改寫成 Perl 。移植的過程中,才發現這個工程,比我想像中大很多。 PHP Monica 的圖片上傳子系統經過多年蘊釀,早已發展成為一個非常複雜、非常成熟的子系統,這兩天改寫的時候,看到了之前寫的、現在快不認得的程式碼,好長好長。覺得自己好可怕,竟然能夠寫出這麼龐大、這麼複雜的東西。這種感覺就像爬山一樣,埋頭一直往上爬,半山腰休息的時候一往下看,才發現自己竟然已經走了這麼遠,爬得這麼高了。 PHP Monica 這麼龐大、複雜、成熟的系統,真的是我過去幾年來一個字、一個字寫出來的東西嗎?有種難已置信的感覺。 ^_*'

    + +

    Selima 的圖片上傳管理子系統,還有很大一部份還沒移植好。然後是原來的目標—網頁管理子系統,然後是把相關連結、日記管理等等子系統,一起整合進來。想想還有好一段路要走。加油~

    + +
    + +
    + +
    +
    日期: 3.1.’05.
    + +
      +
    1. 寫了 Selima::Form 裏的 _html_col_pic() 方法,顯示圖片設定欄位。
    2. + +
    3. 補上 Selima::Picture 裏的 picurl()picinfo()picstyle()check_pic_ratio()best_pic_ratio()newpicx()newpicy()echopic()picpos_label() 等函數,及 PIC_MAX_WIDTHPIC_MAX_HEIGHTPIC_MAX_RATIO@PIC_VALID_POS%PIC_POS_LABELPIC_POS_DEFAULTSHOWPIC_SCRIPT 等常數等等。
    4. +
    + +
    + +
    + +
    +
    日期: 2.27.’05.
    + +

    寫出了網頁管理用的 Selima::PageSelima::PageList 兩個類別。

    + +
    + +
    + +
    +
    日期: 2.25.’05.
    + +

    重做了關於旅舍依瑪,寫了一段旅舍的簡介。

    + +
    + +
    + +
    +
    日期: 2.25.’05.
    + +

    這是 Selima 2.13 。我把旅舍更新日誌管理程式寫出來了

    + +

    旅舍更新日誌程式,基本上跟旅舍日記程式差別不大,都是單向的留言板系統:後台管理界面是留言板程式,而前端則是網頁製作輸出程式。

    + +

    比較辛苦的是舊日誌匯入工作:旅舍更新日誌不像留言板或旅舍日記一樣,原本就存在類資料庫格式的 XML 檔中。原來的更新日誌只是一個普通的 HTML 網頁。我沒辦法寫程式直接整批匯入,只能叫出檔案,手動一段一段編輯、輸入。

    + +

    不過也因此,重讀了整個更新日誌。呵。看著以前的自己決定這樣做那樣做的理由,碰到種種的困難並苦思解決之道,很有趣呢~ ^_*'

    + +

    2000 年 11 月 5 日以後,因為不易編輯,我就沒有再寫更新日誌了,有更新都公告在旅人留言簿上。因此 2000 年 11 月 5 日以後的部份,是從旅人留言簿上找來的,有點零碎,可是語氣比較生活化,讀起來比較有趣。

    + +

    以後要勤快記日誌。記日誌是撰寫程式的基本工夫。基本工夫要做扎實。嗯。

    + +
    + +
    + +
    +
    日期: 2.20.’05.
    + +

    這是 Selima 2.12 。旅舍日記編輯系統終於完成了。荒廢了四年沒寫的旅舍日記,終於可以開始動筆了。以後我有地方可以自言自語,不用什麼東西都來寫旅人留言簿了~ ^_*'

    + +
    + +
    + +
    +
    日期: 11.3.’04.
    + +

    今天完成了一件大事:相關連結/繼續旅行的管理界面,終於完工了。好幾年無法管理維護的相關連結,終於又可以正常維護了。 ^_*' 雖然還有幾個晦瑟不明的 bug ,不過大體上已經可以正常管理了。

    + +

    這是 Selima 2 的大事: Selima 終於向一個完整的內容管理系統,邁開了第一步,實作出了第一個內容管理的功能~ ^_*' 呵呵。

    + +

    接下來要趕期中考了。終於安心了,放下心中的一塊大石。我要暫時把 Selima 擱著了~ ^_*'

    + +
    + +
    + +
    +
    日期: 10.24.’04.
    + +

    終於擺脫了 Selima 1 的奇怪舊程式,把旅舍、女聲和各個網站的程式,全面昇級到 Selima 2 的資料庫系統。舊 Selima 1 麻煩又不好維護的程式碼都一一刪掉了,心情超好中~ ^_*' 呵呵~

    + +
    + +
    + +
    +
    日期: 10.24.’04.
    + +

    旅人留言簿新程式上路。目前核心是搭配 PostgreSQL 資料庫的第二代 Selima 系統。留言簿頁數會重排。速度會稍微慢一些,不過功能更強。

    + +

    若有任何問題,請隨時告知。

    + +
    + +
    + +
    +
    日期: 3.22.’04.
    + +

    我正在考慮把旅舍的 Selima 系統資料庫化。資料庫系統方面,可能會採用 MySQL

    + +
    + +
    + +
    +
    日期: 9.26.’03.
    + +

    剛剛修正了旅人留言簿 Selima 系統的一個小問題。

    + +

    之前留言時,ТАТУ不知道為什麼,俄文顯示出來變成亂碼,當時我也未加深究。剛剛留言,尼羅河女兒的ヒッタイト(比泰多王國)日文又變成亂碼,我進去查了一次。原來是 Big5 編碼標準混亂的問題。當初五大中文商共同訂定的原始 Big5 大五碼裏,不包含日文及一些擴充字元。後來倚天中文為了方便起見,自己在 Big5 加了日文、公文符號及一些擴充字元。可是後來微軟 Windows 所用的 Big5 裏,沒有加上那些擴充字元,形成了另一個版本的 Big5 。倚天擴充版的 Big5 俗稱 Big5-ETen ,微軟的 Big5 自己取了一個名字叫 CP950 。 PerlEncode 裏的 Big5 ,取的是 Big5-ETen ,日文和俄文,都在 Big5-ETen 裏有碼位,直接對映到 Big5-ETen 的字,可是 Windows 下的 CP950 裏沒有這些字,所以就變成亂碼。

    + +

    我現在改映到 CP950 ,日文和俄文不映到 Big5 下的碼位,會正確以 Unicode 表示法顯示。雖然很討厭微軟,不過在 Unicode 時代,日文和俄文對應到 Unicode 而不是 Big5 ,應該是比較正確的做法。

    + +
    + +
    + +
    +
    日期: 6.4.’03.
    + +

    最近突發奇想,想自己寫一個 web mail 。本來以為很簡單,但是現在看樣子是卡住了。

    + +

    看樣子, Selima 系統的彈性似乎還不夠大,蠻失敗的。

    + +

    Selima 的前身,公司的 Monica 系統,也面臨了同樣的問題。想從 Monica 做出圖檔上傳,和專案管理的功能,卻碰到了瓶頸。系統太大,也太硬了,沒什麼彈性,難以擴充。

    + +

    頗煩。

    + +
    + +
    + +
    +
    日期: 5.13.’03.
    + +

    旅舍/女聲的線路已昇級為雙向 512Kbps ,以後網站連線速度會提高很多。此外,因為頻寬變大,不怕為了收信癱瘓家裏的網路,我也開始在公司收家裏的 E-mail 了。加上現在的 Selima 系統的留言郵件通知,對於留言的回應會比以前更即時~ ^_*'

    + +

    當然,也要我想得到該怎麼回應才有用。處女座的即時反應是很差的。 ^^;

    + +
    + +
    + +
    +
    日期: 4.26.’03.
    + +

    解決了一個留言本的 bug ,呵。 ^^;

    + +

    之前改了一些基本的設計,可是有個小地方沒有跟著改。那麼多天了都沒發現… :p

    + +
    + +
    + +
    +
    日期: 4.18.’03.
    + +

    今天晚上實驗了一下,旅人留言本所用的 Selima 系統,因為多語切換用到 GNU glibcgettext ,所以應該很難在 Windows 下跑(要裝 cygwin )。應該說,要在 Unix 之外的作業系統上跑,難度不小。

    + +

    我有考慮過,多語切換用 Perl 專用的 MaketextMaketext 是目前 Perl 的多語標準,不需要 GNU glibc ,可以在任何作業系統上跑。不過 Maketext 工具太少,而且撰寫介面頗複雜,整體設計不如 gettext 簡潔方便,所以還是算了。

    + +

    另外, Selima 因為用到 Encode ,所以一定要在最新的 Perl 5.8.0 以上跑,無法在之前的 Perl 上跑。

    + +

    我一直以為 Selima 可以跨平台作業,相容性很高,沒想到條件其實很嚴苛~~ ^^;。

    + +
    + +
    + +
    +
    日期: 4.10.’03.
    + +

    Selima 的留言板系統,差不多撰寫完成了。留言通知也改用 Sendmail 幕後寄信,加快程式本身反應速度。該要的功能都做出來了。

    + +

    整個 Selima 系統,都是用純 Perl 寫的。在這個 PHP 當道的時代,我要證明一件事: Perl 遠比 PHP 優秀,遠比 PHP 強。

    + +

    Selima 是一套特別針對 mod_perl 的特性強化的系統,在很多地方做了效能強化處理,可是還是儘量保持 Perl/CGI 的相容性。我甚至把留言板的資料庫索引整個快取在 Apache 的記憶體中。以目前的旅人留言簿留言數量來說,在 Perl/CGI 模式下執行,顯示頁面約需 0.26 秒, +在 mod_perl 下快取執行,顯示頁面可以加速到 0.03 秒,如果配合瀏覽器本身的快取的話,反應時間甚至可以縮短到 0.006 秒!

    + +

    在 Selima 上,妳可以真正感覺到快。除了頻寬以外,妳感覺不到任何停頓。 CGI 程式跑起來像靜態網頁一樣。這才是真正的 Power ^_*'

    + +

    PHP 哪有這種 Power ?哇哈哈哈哈哈~~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 1 | + 2 | + 3 | + 4 | + 5 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0004.html.en.html b/htdocs/imacat/me/changelog/0004.html.en.html new file mode 120000 index 0000000..72c30d8 --- /dev/null +++ b/htdocs/imacat/me/changelog/0004.html.en.html @@ -0,0 +1 @@ +0004.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0004.html.en.xhtml b/htdocs/imacat/me/changelog/0004.html.en.xhtml new file mode 100644 index 0000000..b3c18e8 --- /dev/null +++ b/htdocs/imacat/me/changelog/0004.html.en.xhtml @@ -0,0 +1,550 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 4 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 4

    + +
    + +
    + +
    +
    Date: 4.1.’06.
    + +
      +
    1. 修正 Selima::AddCol 類別的 addpass() 方法,插入第二個參數 $purge ,以判定是否要寫入空白的無效密碼。
    2. + +
    3. 修正 Selima::Processor::User 類別:加上 _purge_passwd() 方法,判定是否要寫入空白的無效密碼;加上 purge_passwd 屬性,以便從外部設定寫入空白無效密碼;修正原來呼叫 Selima::AddCols::addpass() 處使用的參數。
    4. + +
    5. 修正 Selima::Processor::User 類別,加上 no_set_groups 屬性,以決定是否要設定使用者的群組。
    6. + +
    7. 參考 Monia ,修正 Selima::Processor::User 類別,加上 is_self 屬性,以決定是否為使用者無法登入時,透過會員系統異動自己的資料。
    8. + +
    9. 修正 Selima::AddCol 類別的 addbool() 方法,欄位值的判斷由 defined $val 改為 defined $val && $val ,以方便堆疊呼叫。
    10. +
    + +
    + +
    + +
    +
    Date: 3.29.’06.
    + +
      +
    1. PHP Monica ,修正 Selima::Processor::LinkCatSelima::Processor::Links 類別,將 _shown_files() 方法、 curfiles 屬性及 newfiles 屬性分別改名為 _shown_parts()curshownnewshown ,以便日後維持方法名稱一致性。
    2. + +
    3. PHP Monica ,加上 %Selima::DataVars::REQUEST ,儲存使用者請求;修正 Selima::Processor ,新增儲存 %Selima::DataVars::REQUEST 備日後使用。
    4. + +
    5. 修正 Selima::Processor::_update_cols() 方法,加上執行前先檢查是否曾定義 sn 屬性。
    6. + +
    7. 修正 Selima::Processor ,把 _update_others() 方法改名為 _other_tasks()
    8. +
    + +
    + +
    + +
    +
    Date: 3.28.’06.
    + +
      +
    1. 加上一條新的擋廣告留言規則。
    2. + +
    3. 修正 Selima::MkAllDir::rmoldfile() ,將測試 -f 改為測試 -f || -l ,以正確刪除符號連結。
    4. +
    + +
    + +
    + +
    +
    Date: 3.25.’06.
    + +
      +
    1. 修改 Selima::Form::* ,加上自動縮寫標示。
    2. + +
    3. 修改 Selima::List::* ,把常用的欄位標籤集中到 Selima::List ,減少各別類別需設定的欄位標籤。
    4. +
    + +
    + +
    + +
    +
    Date: 3.24.’06.
    + +
      +
    1. 加上 Selima::MarkAbbr ,作簡單的自動縮寫標示。
    2. + +
    3. 修改 Selima::List::* ,加上自動縮寫標示。
    4. +
    + +
    + +
    + +
    +
    Date: 3.23.’06.
    + +
      +
    1. 整理 Selima::Processor::* ,將 modified()save_cols()rebuild_partial_pages() 改為私有方法。(雖然 Perl 其實沒有什麼真正的私有方法。 ^^; )
    2. + +
    3. 修改 Selima::Processor ,加上 _actlog() 方法,與 _log_message() 分開,以便子類別不需引用 Selima::Guestgactlog() 即可設定記錄訊息,並方便 Selima::Processor::ListPref 重載 _actlog() ,改變記錄方式。
    4. + +
    5. 修改 Selima::Processor::UserPref::_log_message() 方法,以更複雜的方式判定使用者名稱與適用範圍,以便 Selima::Processor::ListPref 堆疊引用,表單沒有 everyoneeverywhere 欄位時,亦可以取得使用者名稱與適用範圍。
    6. +
    + +
    + +
    + +
    +
    Date: 3.22.’06.
    + +
      +
    1. 加上 Selima::Processor::ListPref ,處理列表偏好。
    2. + +
    3. PHP Monica 改寫 Selima::ListPref ,由原來的函式處理改用物件類別處理,並刪除 process_form() 的處理方式(真的是最後一個了 ^^; ),改用 Selima::Processor::ListPref 處理。
    4. + +
    5. Selima::List 加上 set_listpref() 方法。
    6. + +
    7. 修正 Selima::Init ,原來處理列表偏好時,呼叫 Selima::ListPref::main_listpref() 函式,改呼叫 Selima::List::*set_listpref() 方法,或 Selima::ListPrefmain() 方法。
    8. + +
    9. 修正 Selima::*::RebuildSelima::*::Processor::Public::Guestbook 中,使用 use encoding qw(Big5); 未加上 no encoding; 的錯誤。
    10. + +
    11. 修正 Selima::DBD::Pgcols() 方法,去除所得到的欄位名稱的引號。
    12. +
    + +
    + +
    + +
    +
    Date: 3.21.’06.
    + +
      +
    1. 加上 Selima::List::CategorySelima::List::Categorz ,作為 Selima::List::LinkCatSelima::List::LinkCatz 的基礎類別,以便日後共用程式訊息。
    2. +
    + +
    + +
    + +
    +
    Date: 3.20.’06.
    + +
      +
    1. 加上 Selima::*::Processor::Public::GuestbookSelima::imacat::Processor::Public::Guestbook ;更新 guestbook.cgigarbage.cgi ,刪掉 process_form()
    2. +
    + +

    至此,資料儲存處理方式已全面改寫,全面改用新的 Selima::Processor::* 處理器物件,停用原來的 process_form() 處理函式。

    + +
    + +
    + +
    +
    Date: 3.19.’06.
    + +
      +
    1. 加上 Selima::wov::Processor::NewsletSelima::wov::Processor::NLArt ;更新 newslets.cginlarts.cgi ,刪掉 process_form()
    2. + +
    3. 修正 Selima::wov::Rebuild::rebuild_newslets() ,將參數由 SQL 查詢式改為電子報的序號,更便於重建網頁。
    4. +
    + +
    + +
    + +
    +
    Date: 3.19.’06.
    + +
      +
    1. 加上 Selima::imacat::Processor::DiarySelima::imacat::Processor::ChangeLog ;更新 diary.cgichangelog.cgi ,刪掉 process_form()
    2. + +
    3. 修正 Selima:*:Rebuild ,將 -e $linkfile 修正為 -l $linkfile
    4. +
    + +
    + +
    + +
    +
    Date: 3.19.’06.
    + +
      +
    1. SQL 定義檔加上標準檔頭(檔名、說明、作者及日期)。
    2. + +
    3. 修正 SQL 定義檔中的函數定義,以確保可自動匯入匯出無誤。
    4. + +
    5. 修正單語網站的 SQL 資料表定義,將多語資料表定義修正為單語定義。
    6. + +
    7. 修正單語網站的 Selima::*::HTMLSelima::*::Rebuild 及各個 *.cgi 程式檔,改用單語資料表定義。
    8. + +
    9. 修正 Selima::Links ,加上單語資料表的相容性處理。
    10. + +
    11. 修正 Selima::Lists ,加上單語 VIEW 的支援。
    12. + +
    13. Selima::Processor::BaseCat 改名為 Selima::Processor::CategorySelima::Processor::BaseCatz 改名為 Selima::Processor::Categorz ,避免使用不必要的 Selima::Processor::Base* 名稱。
    14. + +
    15. 新增 Selima::Processor::LogOut ;更新 logout.cgi ,刪掉 process_form()
    16. +
    + +
    + +
    + +
    +
    Date: 3.18.’06.
    + +
      +
    1. 加上 Selima::Processor::BaseCatSelima::Processor::BaseCatzSelima::Processor::LinkCatSelima::Processor::LinkSelima::Processor::LinkCatz ,以處理相關連結資料。
    2. + +
    3. 更新 links.cgilinkcat.cgilinkcatz.cgi ,刪掉 process_form()rebuild_partial_pages()remove_curfile()
    4. + +
    5. Selima::Processor::_ret_message() 方法中分出 Selima::Processor::_log_message() 方法,專門處理記錄訊息,以便將回傳的文字訊息與譯文集中管理。
    6. + +
    7. 新增 Selima::Processor::_zhsync() 方法,處理內文繁轉簡的工作。
    8. + +
    9. 更新 Selima::MkAllDir::rmoldfile() ,加上刪除各種語言、 HTML/XHTML 版本檔案的能力。
    10. +
    + +
    + +
    + +
    +
    Date: 3.17.’06.
    + +
      +
    1. PHP Monica 的程式碼,寫出一年前計劃未完成的 Selima::Processor ,加上 Selima::Processor::DeleteSelima::Processor::UserSelima::Processor::GroupSelima::Processor::UserMemSelima::Processor::GroupMemSelima::Processor::UserPrefSelima::Processor::ScptPriv ,以替代 process_form() 處理表單。
    2. + +
    3. 刪掉 users.cgigroups.cgiusermem.cgigroupmem.cgiuserpref.cgiscptpriv.cgi 中的 process_form()
    4. + +
    5. 更新 Selima::DBD::mysql::support() , MySQL 自 5.0 起支援 VIEW 了。
    6. +
    + +
    + +
    + +
    +
    Date: 3.15.’06.
    + +
      +
    1. 修改 links.cgiusers.cgigroups.cgi ,加入計數以便作英文單複數處理。
    2. + +
    3. 加上 Selima::Form::_delcolcount() 方法,以傳回表單欄位子項目的數目。
    4. + +
    5. 修改 Selima::Form::LinksSelima::Form::UsersSelima::Form::Groups ,正確處理表單的英文單複數標嵌。
    6. +
    + +
    + +
    + +
    +
    Date: 3.15.’06.
    + +
      +
    1. 新增兩個擋廣告留言的規則。
    2. + +
    3. 修改 Selima::Form::LinkCatlinkcat.cgi ,正確顯示子項目的單複數英文訊息。
    4. + +
    5. PHP Monica 修正 Selima::Form 的子項目英文訊息。
    6. + +
    7. 修改 Selima::Form ,將 prefmsg 屬性由單一訊息改為 +陣列,以同時顯示多個表單前置訊息。
    8. +
    + +
    + +
    + +
    +
    Date: 2.18.’06.
    + +
      +
    1. 加上自己寫的 Selima::Unicode::all_to_trad()Selima::Unicode::all_to_simp() ,取代原先使用的 Encode::HanConvert::simp_to_trad()Encode::HanConvert::trad_to_simp() ,以作旅人留言簿的自動繁簡轉換。 Encode::HanConvert 的轉換,若將繁體傳給 simp_to_trad() ,或將簡體傳給 trad_to_simp() ,會變成亂碼,無法處理繁簡混合的文字,而且需事先知道是繁是簡才能傳進去轉換,無法處理旅人留言簿混合中文的情形。
    2. + +
    3. 加上 all2trad.dball2simp.db 兩個 GDBM 資料庫。
    4. +
    + +
    + +
    + +
    +
    Date: 2.3.’06.
    + +
      +
    1. 網站程式登入資料庫的密碼,原先直接存在 Selima::DBD::PgSelima::DBD::mysql ,改存在只有 root 可讀的另一個檔案裏,啟動 Apache 時,以 root 權限讀進環境變數中使用。如此不需要把密碼存在網站的權限 nobody 可讀取的檔案中,又可以讓 nobody 可以取得登入資料庫的密碼,登入資料庫。
    2. + +
    3. 加上 Salima::DBILogin 模組,以解譯、取得存於環境變數中的資料庫登入密碼。
    4. +
    + +

    這樣會比較安全,密碼會保護得比較好嗎?嗯嗯,再想想。

    + +
    + +
    + +
    +
    Date: 1.28.’06.
    + +
      +
    1. 加上留言顯示繁簡自動轉換功能。
    2. +
    + +
    + +
    + +
    +
    Date: 1.27.’06.
    + +
      +
    1. 更新 MySQL server ,由 4.1.16 昇級為 5.0.18 。
    2. +
    + +
    + +
    + +
    +
    Date: 1.23.’06.
    + +
      +
    1. 更新 MySQL server ,由 4.0.26 昇級為 4.1.16 。
    2. +
    + +
    + +
    + +
    +
    Date: 1.15.’06.
    + +
      +
    1. 將所有的 Mailman mailing lists 統一置於 rinse HTTPS 下。
    2. +
    + +
    + +
    + +
    +
    Date: 1.3.’06.
    + +
      +
    1. Selima::Checker::Public::Guestbook 新增 _check_spam() 方法,統合原先分散的數個廣告過濾程式。
    2. +
    + +
    + +
    + +
    +
    Date: 10.13.’05.
    + +
      +
    1. 旅舍伺服器作業系統由 Debian GNU/Linux 3.0 Woody 昇級為 Debian GNU/Linux 3.1 Sarge 。
    2. +
    + +
    + +
    + +
    +
    Date: 10.9.’05.
    + +
      +
    1. 修改網頁標頭中的 Content-Type 設定,由 text/html 一律改為 application/xhtml+xml 。
    2. +
    3. 校正幾個其實已經沒在用的舊網頁。
    4. +
    + +
    + +
    + +
    +
    Date: 10.6.’05.
    + +
      +
    1. 修改其它 Selima 網站,全面改為 XHTML ,使用 HTTP/1.1 Content-Negotiation ,網頁加上 .xhtml 附檔名並做 .html 連結,文件類別由 text/html 改為 application/xhtml+xml 與 text/html 並存。
    2. +
    + +
    + +
    + +
    +
    Date: 10.5.’05.
    + +
      +
    1. 旅舍全面改為 XHTML ,使用 HTTP/1.1 Content-Negotiation ,網頁加上 .xhtml 附檔名並做 .html 連結,文件類別由 text/html 改為 application/xhtml+xml 與 text/html 並存。
    2. +
    3. 加上回旅舍大廳 (1)直接跳到網頁內文區 (2)accesskey
    4. +
    5. 新增 /accsblty.html 無障礙網頁設計說明。
    6. +
    + +
    + +
    + +
    +
    Date: 10.4.’05.
    + +
      +
    1. 調整首頁樣式(謝謝阿光 quity 的建議~ ^_*' )
    2. +
    3. 加上無障礙網頁設計的導盲磚。
    4. +
    5. 加上直接跳到網頁內文區的設計。
    6. +
    7. 調整導覽連結區,把語言切換區放到導覽連結區下方。
    8. +
    9. 加上導覽連結區、語言切換區和網頁內文區的 title="…" 說明。
    10. +
    11. 旅舍電腦筆記、椰子拉子區換上標準導覽連結區。
    12. +
    13. 旅舍大廳下方連結碼邊框的樣式,調整為 ridge
    14. +
    15. 恢復留言簿的 <hr />
    16. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 2 | + 3 | + 4 | + 5 | + 6 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0004.html.zh-cn.html b/htdocs/imacat/me/changelog/0004.html.zh-cn.html new file mode 120000 index 0000000..522d949 --- /dev/null +++ b/htdocs/imacat/me/changelog/0004.html.zh-cn.html @@ -0,0 +1 @@ +0004.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0004.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0004.html.zh-cn.xhtml new file mode 100644 index 0000000..a6f2a1b --- /dev/null +++ b/htdocs/imacat/me/changelog/0004.html.zh-cn.xhtml @@ -0,0 +1,549 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷四 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷四

    + +
    + +
    + +
    +
    日期: 4.1.’06.
    + +
      +
    1. 修正 Selima::AddCol 类别的 addpass() 方法,插入第二个参数 $purge ,以判定是否要写入空白的无效密码。
    2. + +
    3. 修正 Selima::Processor::User 类别:加上 _purge_passwd() 方法,判定是否要写入空白的无效密码;加上 purge_passwd 属性,以便从外部设定写入空白无效密码;修正原来呼叫 Selima::AddCols::addpass() 处使用的参数。
    4. + +
    5. 修正 Selima::Processor::User 类别,加上 no_set_groups 属性,以决定是否要设定使用者的群组。
    6. + +
    7. 参考 Monia ,修正 Selima::Processor::User 类别,加上 is_self 属性,以决定是否为使用者无法登入时,透过会员系统异动自己的资料。
    8. + +
    9. 修正 Selima::AddCol 类别的 addbool() 方法,栏位值的判断由 defined $val 改为 defined $val && $val ,以方便堆叠呼叫。
    10. +
    + +
    + +
    + +
    +
    日期: 3.29.’06.
    + +
      +
    1. PHP Monica ,修正 Selima::Processor::LinkCatSelima::Processor::Links 类别,将 _shown_files() 方法、 curfiles 属性及 newfiles 属性分别改名为 _shown_parts()curshownnewshown ,以便日后维持方法名称一致性。
    2. + +
    3. PHP Monica ,加上 %Selima::DataVars::REQUEST ,储存使用者请求;修正 Selima::Processor ,新增储存 %Selima::DataVars::REQUEST 备日后使用。
    4. + +
    5. 修正 Selima::Processor::_update_cols() 方法,加上执行前先检查是否曾定义 sn 属性。
    6. + +
    7. 修正 Selima::Processor ,把 _update_others() 方法改名为 _other_tasks()
    8. +
    + +
    + +
    + +
    +
    日期: 3.28.’06.
    + +
      +
    1. 加上一条新的挡广告留言规则。
    2. + +
    3. 修正 Selima::MkAllDir::rmoldfile() ,将测试 -f 改为测试 -f || -l ,以正确删除符号连结。
    4. +
    + +
    + +
    + +
    +
    日期: 3.25.’06.
    + +
      +
    1. 修改 Selima::Form::* ,加上自动缩写标示。
    2. + +
    3. 修改 Selima::List::* ,把常用的栏位标签集中到 Selima::List ,减少各别类别需设定的栏位标签。
    4. +
    + +
    + +
    + +
    +
    日期: 3.24.’06.
    + +
      +
    1. 加上 Selima::MarkAbbr ,作简单的自动缩写标示。
    2. + +
    3. 修改 Selima::List::* ,加上自动缩写标示。
    4. +
    + +
    + +
    + +
    +
    日期: 3.23.’06.
    + +
      +
    1. 整理 Selima::Processor::* ,将 modified()save_cols()rebuild_partial_pages() 改为私有方法。(虽然 Perl 其实没有什么真正的私有方法。 ^^; )
    2. + +
    3. 修改 Selima::Processor ,加上 _actlog() 方法,与 _log_message() 分开,以便子类别不需引用 Selima::Guestgactlog() 即可设定记录讯息,并方便 Selima::Processor::ListPref 重载 _actlog() ,改变记录方式。
    4. + +
    5. 修改 Selima::Processor::UserPref::_log_message() 方法,以更复杂的方式判定使用者名称与适用范围,以便 Selima::Processor::ListPref 堆叠引用,表单没有 everyoneeverywhere 栏位时,亦可以取得使用者名称与适用范围。
    6. +
    + +
    + +
    + +
    +
    日期: 3.22.’06.
    + +
      +
    1. 加上 Selima::Processor::ListPref ,处理列表偏好。
    2. + +
    3. PHP Monica 改写 Selima::ListPref ,由原来的函式处理改用物件类别处理,并删除 process_form() 的处理方式(真的是最后一个了 ^^; ),改用 Selima::Processor::ListPref 处理。
    4. + +
    5. Selima::List 加上 set_listpref() 方法。
    6. + +
    7. 修正 Selima::Init ,原来处理列表偏好时,呼叫 Selima::ListPref::main_listpref() 函式,改呼叫 Selima::List::*set_listpref() 方法,或 Selima::ListPrefmain() 方法。
    8. + +
    9. 修正 Selima::*::RebuildSelima::*::Processor::Public::Guestbook 中,使用 use encoding qw(Big5); 未加上 no encoding; 的错误。
    10. + +
    11. 修正 Selima::DBD::Pgcols() 方法,去除所得到的栏位名称的引号。
    12. +
    + +
    + +
    + +
    +
    日期: 3.21.’06.
    + +
      +
    1. 加上 Selima::List::CategorySelima::List::Categorz ,作为 Selima::List::LinkCatSelima::List::LinkCatz 的基础类别,以便日后共用程式讯息。
    2. +
    + +
    + +
    + +
    +
    日期: 3.20.’06.
    + +
      +
    1. 加上 Selima::*::Processor::Public::GuestbookSelima::imacat::Processor::Public::Guestbook ;更新 guestbook.cgigarbage.cgi ,删掉 process_form()
    2. +
    + +

    至此,资料储存处理方式已全面改写,全面改用新的 Selima::Processor::* 处理器物件,停用原来的 process_form() 处理函式。

    + +
    + +
    + +
    +
    日期: 3.19.’06.
    + +
      +
    1. 加上 Selima::wov::Processor::NewsletSelima::wov::Processor::NLArt ;更新 newslets.cginlarts.cgi ,删掉 process_form()
    2. + +
    3. 修正 Selima::wov::Rebuild::rebuild_newslets() ,将参数由 SQL 查询式改为电子报的序号,更便于重建网页。
    4. +
    + +
    + +
    + +
    +
    日期: 3.19.’06.
    + +
      +
    1. 加上 Selima::imacat::Processor::DiarySelima::imacat::Processor::ChangeLog ;更新 diary.cgichangelog.cgi ,删掉 process_form()
    2. + +
    3. 修正 Selima:*:Rebuild ,将 -e $linkfile 修正为 -l $linkfile
    4. +
    + +
    + +
    + +
    +
    日期: 3.19.’06.
    + +
      +
    1. SQL 定义档加上标准档头(档名、说明、作者及日期)。
    2. + +
    3. 修正 SQL 定义档中的函数定义,以确保可自动汇入汇出无误。
    4. + +
    5. 修正单语网站的 SQL 资料表定义,将多语资料表定义修正为单语定义。
    6. + +
    7. 修正单语网站的 Selima::*::HTMLSelima::*::Rebuild 及各个 *.cgi 程式档,改用单语资料表定义。
    8. + +
    9. 修正 Selima::Links ,加上单语资料表的相容性处理。
    10. + +
    11. 修正 Selima::Lists ,加上单语 VIEW 的支援。
    12. + +
    13. Selima::Processor::BaseCat 改名为 Selima::Processor::CategorySelima::Processor::BaseCatz 改名为 Selima::Processor::Categorz ,避免使用不必要的 Selima::Processor::Base* 名称。
    14. + +
    15. 新增 Selima::Processor::LogOut ;更新 logout.cgi ,删掉 process_form()
    16. +
    + +
    + +
    + +
    +
    日期: 3.18.’06.
    + +
      +
    1. 加上 Selima::Processor::BaseCatSelima::Processor::BaseCatzSelima::Processor::LinkCatSelima::Processor::LinkSelima::Processor::LinkCatz ,以处理相关连结资料。
    2. + +
    3. 更新 links.cgilinkcat.cgilinkcatz.cgi ,删掉 process_form()rebuild_partial_pages()remove_curfile()
    4. + +
    5. Selima::Processor::_ret_message() 方法中分出 Selima::Processor::_log_message() 方法,专门处理记录讯息,以便将回传的文字讯息与译文集中管理。
    6. + +
    7. 新增 Selima::Processor::_zhsync() 方法,处理内文繁转简的工作。
    8. + +
    9. 更新 Selima::MkAllDir::rmoldfile() ,加上删除各种语言、 HTML/XHTML 版本档案的能力。
    10. +
    + +
    + +
    + +
    +
    日期: 3.17.’06.
    + +
      +
    1. PHP Monica 的程式码,写出一年前计划未完成的 Selima::Processor ,加上 Selima::Processor::DeleteSelima::Processor::UserSelima::Processor::GroupSelima::Processor::UserMemSelima::Processor::GroupMemSelima::Processor::UserPrefSelima::Processor::ScptPriv ,以替代 process_form() 处理表单。
    2. + +
    3. 删掉 users.cgigroups.cgiusermem.cgigroupmem.cgiuserpref.cgiscptpriv.cgi 中的 process_form()
    4. + +
    5. 更新 Selima::DBD::mysql::support() , MySQL 自 5.0 起支援 VIEW 了。
    6. +
    + +
    + +
    + +
    +
    日期: 3.15.’06.
    + +
      +
    1. 修改 links.cgiusers.cgigroups.cgi ,加入计数以便作英文单复数处理。
    2. + +
    3. 加上 Selima::Form::_delcolcount() 方法,以传回表单栏位子项目的数目。
    4. + +
    5. 修改 Selima::Form::LinksSelima::Form::UsersSelima::Form::Groups ,正确处理表单的英文单复数标嵌。
    6. +
    + +
    + +
    + +
    +
    日期: 3.15.’06.
    + +
      +
    1. 新增两个挡广告留言的规则。
    2. + +
    3. 修改 Selima::Form::LinkCatlinkcat.cgi ,正确显示子项目的单复数英文讯息。
    4. + +
    5. PHP Monica 修正 Selima::Form 的子项目英文讯息。
    6. + +
    7. 修改 Selima::Form ,将 prefmsg 属性由单一讯息改为 +阵列,以同时显示多个表单前置讯息。
    8. +
    + +
    + +
    + +
    +
    日期: 2.18.’06.
    + +
      +
    1. 加上自己写的 Selima::Unicode::all_to_trad()Selima::Unicode::all_to_simp() ,取代原先使用的 Encode::HanConvert::simp_to_trad()Encode::HanConvert::trad_to_simp() ,以作旅人留言簿的自动繁简转换。 Encode::HanConvert 的转换,若将繁体传给 simp_to_trad() ,或将简体传给 trad_to_simp() ,会变成乱码,无法处理繁简混合的文字,而且需事先知道是繁是简才能传进去转换,无法处理旅人留言簿混合中文的情形。
    2. + +
    3. 加上 all2trad.dball2simp.db 两个 GDBM 资料库。
    4. +
    + +
    + +
    + +
    +
    日期: 2.3.’06.
    + +
      +
    1. 网站程式登入资料库的密码,原先直接存在 Selima::DBD::PgSelima::DBD::mysql ,改存在只有 root 可读的另一个档案里,启动 Apache 时,以 root 权限读进环境变数中使用。如此不需要把密码存在网站的权限 nobody 可读取的档案中,又可以让 nobody 可以取得登入资料库的密码,登入资料库。
    2. + +
    3. 加上 Salima::DBILogin 模组,以解译、取得存于环境变数中的资料库登入密码。
    4. +
    + +

    这样会比较安全,密码会保护得比较好吗?嗯嗯,再想想。

    + +
    + +
    + +
    +
    日期: 1.28.’06.
    + +
      +
    1. 加上留言显示繁简自动转换功能。
    2. +
    + +
    + +
    + +
    +
    日期: 1.27.’06.
    + +
      +
    1. 更新 MySQL server ,由 4.1.16 升级为 5.0.18 。
    2. +
    + +
    + +
    + +
    +
    日期: 1.23.’06.
    + +
      +
    1. 更新 MySQL server ,由 4.0.26 升级为 4.1.16 。
    2. +
    + +
    + +
    + +
    +
    日期: 1.15.’06.
    + +
      +
    1. 将所有的 Mailman mailing lists 统一置于 rinse HTTPS 下。
    2. +
    + +
    + +
    + +
    +
    日期: 1.3.’06.
    + +
      +
    1. Selima::Checker::Public::Guestbook 新增 _check_spam() 方法,统合原先分散的数个广告过滤程式。
    2. +
    + +
    + +
    + +
    +
    日期: 10.13.’05.
    + +
      +
    1. 旅舍伺服器作业系统由 Debian GNU/Linux 3.0 Woody 升级为 Debian GNU/Linux 3.1 Sarge 。
    2. +
    + +
    + +
    + +
    +
    日期: 10.9.’05.
    + +
      +
    1. 修改网页标头中的 Content-Type 设定,由 text/html 一律改为 application/xhtml+xml 。
    2. +
    3. 校正几个其实已经没在用的旧网页。
    4. +
    + +
    + +
    + +
    +
    日期: 10.6.’05.
    + +
      +
    1. 修改其它 Selima 网站,全面改为 XHTML ,使用 HTTP/1.1 Content-Negotiation ,网页加上 .xhtml 附档名并做 .html 连结,文件类别由 text/html 改为 application/xhtml+xml 与 text/html 并存。
    2. +
    + +
    + +
    + +
    +
    日期: 10.5.’05.
    + +
      +
    1. 旅舍全面改为 XHTML ,使用 HTTP/1.1 Content-Negotiation ,网页加上 .xhtml 附档名并做 .html 连结,文件类别由 text/html 改为 application/xhtml+xml 与 text/html 并存。
    2. +
    3. 加上回旅舍大厅 (1)直接跳到网页内文区 (2)accesskey
    4. +
    5. 新增 /accsblty.html 无障碍网页设计说明。
    6. +
    + +
    + +
    + +
    +
    日期: 10.4.’05.
    + +
      +
    1. 调整首页样式(谢谢阿光 quity 的建议~ ^_*' )
    2. +
    3. 加上无障碍网页设计的导盲砖。
    4. +
    5. 加上直接跳到网页内文区的设计。
    6. +
    7. 调整导览连结区,把语言切换区放到导览连结区下方。
    8. +
    9. 加上导览连结区、语言切换区和网页内文区的 title="…" 说明。
    10. +
    11. 旅舍电脑笔记、椰子拉子区换上标准导览连结区。
    12. +
    13. 旅舍大厅下方连结码边框的样式,调整为 ridge
    14. +
    15. 恢复留言簿的 <hr />
    16. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 2 | + 3 | + 4 | + 5 | + 6 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0004.html.zh-tw.html b/htdocs/imacat/me/changelog/0004.html.zh-tw.html new file mode 120000 index 0000000..f133609 --- /dev/null +++ b/htdocs/imacat/me/changelog/0004.html.zh-tw.html @@ -0,0 +1 @@ +0004.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0004.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0004.html.zh-tw.xhtml new file mode 100644 index 0000000..a561c29 --- /dev/null +++ b/htdocs/imacat/me/changelog/0004.html.zh-tw.xhtml @@ -0,0 +1,549 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷四 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷四

    + +
    + +
    + +
    +
    日期: 4.1.’06.
    + +
      +
    1. 修正 Selima::AddCol 類別的 addpass() 方法,插入第二個參數 $purge ,以判定是否要寫入空白的無效密碼。
    2. + +
    3. 修正 Selima::Processor::User 類別:加上 _purge_passwd() 方法,判定是否要寫入空白的無效密碼;加上 purge_passwd 屬性,以便從外部設定寫入空白無效密碼;修正原來呼叫 Selima::AddCols::addpass() 處使用的參數。
    4. + +
    5. 修正 Selima::Processor::User 類別,加上 no_set_groups 屬性,以決定是否要設定使用者的群組。
    6. + +
    7. 參考 Monia ,修正 Selima::Processor::User 類別,加上 is_self 屬性,以決定是否為使用者無法登入時,透過會員系統異動自己的資料。
    8. + +
    9. 修正 Selima::AddCol 類別的 addbool() 方法,欄位值的判斷由 defined $val 改為 defined $val && $val ,以方便堆疊呼叫。
    10. +
    + +
    + +
    + +
    +
    日期: 3.29.’06.
    + +
      +
    1. PHP Monica ,修正 Selima::Processor::LinkCatSelima::Processor::Links 類別,將 _shown_files() 方法、 curfiles 屬性及 newfiles 屬性分別改名為 _shown_parts()curshownnewshown ,以便日後維持方法名稱一致性。
    2. + +
    3. PHP Monica ,加上 %Selima::DataVars::REQUEST ,儲存使用者請求;修正 Selima::Processor ,新增儲存 %Selima::DataVars::REQUEST 備日後使用。
    4. + +
    5. 修正 Selima::Processor::_update_cols() 方法,加上執行前先檢查是否曾定義 sn 屬性。
    6. + +
    7. 修正 Selima::Processor ,把 _update_others() 方法改名為 _other_tasks()
    8. +
    + +
    + +
    + +
    +
    日期: 3.28.’06.
    + +
      +
    1. 加上一條新的擋廣告留言規則。
    2. + +
    3. 修正 Selima::MkAllDir::rmoldfile() ,將測試 -f 改為測試 -f || -l ,以正確刪除符號連結。
    4. +
    + +
    + +
    + +
    +
    日期: 3.25.’06.
    + +
      +
    1. 修改 Selima::Form::* ,加上自動縮寫標示。
    2. + +
    3. 修改 Selima::List::* ,把常用的欄位標籤集中到 Selima::List ,減少各別類別需設定的欄位標籤。
    4. +
    + +
    + +
    + +
    +
    日期: 3.24.’06.
    + +
      +
    1. 加上 Selima::MarkAbbr ,作簡單的自動縮寫標示。
    2. + +
    3. 修改 Selima::List::* ,加上自動縮寫標示。
    4. +
    + +
    + +
    + +
    +
    日期: 3.23.’06.
    + +
      +
    1. 整理 Selima::Processor::* ,將 modified()save_cols()rebuild_partial_pages() 改為私有方法。(雖然 Perl 其實沒有什麼真正的私有方法。 ^^; )
    2. + +
    3. 修改 Selima::Processor ,加上 _actlog() 方法,與 _log_message() 分開,以便子類別不需引用 Selima::Guestgactlog() 即可設定記錄訊息,並方便 Selima::Processor::ListPref 重載 _actlog() ,改變記錄方式。
    4. + +
    5. 修改 Selima::Processor::UserPref::_log_message() 方法,以更複雜的方式判定使用者名稱與適用範圍,以便 Selima::Processor::ListPref 堆疊引用,表單沒有 everyoneeverywhere 欄位時,亦可以取得使用者名稱與適用範圍。
    6. +
    + +
    + +
    + +
    +
    日期: 3.22.’06.
    + +
      +
    1. 加上 Selima::Processor::ListPref ,處理列表偏好。
    2. + +
    3. PHP Monica 改寫 Selima::ListPref ,由原來的函式處理改用物件類別處理,並刪除 process_form() 的處理方式(真的是最後一個了 ^^; ),改用 Selima::Processor::ListPref 處理。
    4. + +
    5. Selima::List 加上 set_listpref() 方法。
    6. + +
    7. 修正 Selima::Init ,原來處理列表偏好時,呼叫 Selima::ListPref::main_listpref() 函式,改呼叫 Selima::List::*set_listpref() 方法,或 Selima::ListPrefmain() 方法。
    8. + +
    9. 修正 Selima::*::RebuildSelima::*::Processor::Public::Guestbook 中,使用 use encoding qw(Big5); 未加上 no encoding; 的錯誤。
    10. + +
    11. 修正 Selima::DBD::Pgcols() 方法,去除所得到的欄位名稱的引號。
    12. +
    + +
    + +
    + +
    +
    日期: 3.21.’06.
    + +
      +
    1. 加上 Selima::List::CategorySelima::List::Categorz ,作為 Selima::List::LinkCatSelima::List::LinkCatz 的基礎類別,以便日後共用程式訊息。
    2. +
    + +
    + +
    + +
    +
    日期: 3.20.’06.
    + +
      +
    1. 加上 Selima::*::Processor::Public::GuestbookSelima::imacat::Processor::Public::Guestbook ;更新 guestbook.cgigarbage.cgi ,刪掉 process_form()
    2. +
    + +

    至此,資料儲存處理方式已全面改寫,全面改用新的 Selima::Processor::* 處理器物件,停用原來的 process_form() 處理函式。

    + +
    + +
    + +
    +
    日期: 3.19.’06.
    + +
      +
    1. 加上 Selima::wov::Processor::NewsletSelima::wov::Processor::NLArt ;更新 newslets.cginlarts.cgi ,刪掉 process_form()
    2. + +
    3. 修正 Selima::wov::Rebuild::rebuild_newslets() ,將參數由 SQL 查詢式改為電子報的序號,更便於重建網頁。
    4. +
    + +
    + +
    + +
    +
    日期: 3.19.’06.
    + +
      +
    1. 加上 Selima::imacat::Processor::DiarySelima::imacat::Processor::ChangeLog ;更新 diary.cgichangelog.cgi ,刪掉 process_form()
    2. + +
    3. 修正 Selima:*:Rebuild ,將 -e $linkfile 修正為 -l $linkfile
    4. +
    + +
    + +
    + +
    +
    日期: 3.19.’06.
    + +
      +
    1. SQL 定義檔加上標準檔頭(檔名、說明、作者及日期)。
    2. + +
    3. 修正 SQL 定義檔中的函數定義,以確保可自動匯入匯出無誤。
    4. + +
    5. 修正單語網站的 SQL 資料表定義,將多語資料表定義修正為單語定義。
    6. + +
    7. 修正單語網站的 Selima::*::HTMLSelima::*::Rebuild 及各個 *.cgi 程式檔,改用單語資料表定義。
    8. + +
    9. 修正 Selima::Links ,加上單語資料表的相容性處理。
    10. + +
    11. 修正 Selima::Lists ,加上單語 VIEW 的支援。
    12. + +
    13. Selima::Processor::BaseCat 改名為 Selima::Processor::CategorySelima::Processor::BaseCatz 改名為 Selima::Processor::Categorz ,避免使用不必要的 Selima::Processor::Base* 名稱。
    14. + +
    15. 新增 Selima::Processor::LogOut ;更新 logout.cgi ,刪掉 process_form()
    16. +
    + +
    + +
    + +
    +
    日期: 3.18.’06.
    + +
      +
    1. 加上 Selima::Processor::BaseCatSelima::Processor::BaseCatzSelima::Processor::LinkCatSelima::Processor::LinkSelima::Processor::LinkCatz ,以處理相關連結資料。
    2. + +
    3. 更新 links.cgilinkcat.cgilinkcatz.cgi ,刪掉 process_form()rebuild_partial_pages()remove_curfile()
    4. + +
    5. Selima::Processor::_ret_message() 方法中分出 Selima::Processor::_log_message() 方法,專門處理記錄訊息,以便將回傳的文字訊息與譯文集中管理。
    6. + +
    7. 新增 Selima::Processor::_zhsync() 方法,處理內文繁轉簡的工作。
    8. + +
    9. 更新 Selima::MkAllDir::rmoldfile() ,加上刪除各種語言、 HTML/XHTML 版本檔案的能力。
    10. +
    + +
    + +
    + +
    +
    日期: 3.17.’06.
    + +
      +
    1. PHP Monica 的程式碼,寫出一年前計劃未完成的 Selima::Processor ,加上 Selima::Processor::DeleteSelima::Processor::UserSelima::Processor::GroupSelima::Processor::UserMemSelima::Processor::GroupMemSelima::Processor::UserPrefSelima::Processor::ScptPriv ,以替代 process_form() 處理表單。
    2. + +
    3. 刪掉 users.cgigroups.cgiusermem.cgigroupmem.cgiuserpref.cgiscptpriv.cgi 中的 process_form()
    4. + +
    5. 更新 Selima::DBD::mysql::support() , MySQL 自 5.0 起支援 VIEW 了。
    6. +
    + +
    + +
    + +
    +
    日期: 3.15.’06.
    + +
      +
    1. 修改 links.cgiusers.cgigroups.cgi ,加入計數以便作英文單複數處理。
    2. + +
    3. 加上 Selima::Form::_delcolcount() 方法,以傳回表單欄位子項目的數目。
    4. + +
    5. 修改 Selima::Form::LinksSelima::Form::UsersSelima::Form::Groups ,正確處理表單的英文單複數標嵌。
    6. +
    + +
    + +
    + +
    +
    日期: 3.15.’06.
    + +
      +
    1. 新增兩個擋廣告留言的規則。
    2. + +
    3. 修改 Selima::Form::LinkCatlinkcat.cgi ,正確顯示子項目的單複數英文訊息。
    4. + +
    5. PHP Monica 修正 Selima::Form 的子項目英文訊息。
    6. + +
    7. 修改 Selima::Form ,將 prefmsg 屬性由單一訊息改為 +陣列,以同時顯示多個表單前置訊息。
    8. +
    + +
    + +
    + +
    +
    日期: 2.18.’06.
    + +
      +
    1. 加上自己寫的 Selima::Unicode::all_to_trad()Selima::Unicode::all_to_simp() ,取代原先使用的 Encode::HanConvert::simp_to_trad()Encode::HanConvert::trad_to_simp() ,以作旅人留言簿的自動繁簡轉換。 Encode::HanConvert 的轉換,若將繁體傳給 simp_to_trad() ,或將簡體傳給 trad_to_simp() ,會變成亂碼,無法處理繁簡混合的文字,而且需事先知道是繁是簡才能傳進去轉換,無法處理旅人留言簿混合中文的情形。
    2. + +
    3. 加上 all2trad.dball2simp.db 兩個 GDBM 資料庫。
    4. +
    + +
    + +
    + +
    +
    日期: 2.3.’06.
    + +
      +
    1. 網站程式登入資料庫的密碼,原先直接存在 Selima::DBD::PgSelima::DBD::mysql ,改存在只有 root 可讀的另一個檔案裏,啟動 Apache 時,以 root 權限讀進環境變數中使用。如此不需要把密碼存在網站的權限 nobody 可讀取的檔案中,又可以讓 nobody 可以取得登入資料庫的密碼,登入資料庫。
    2. + +
    3. 加上 Salima::DBILogin 模組,以解譯、取得存於環境變數中的資料庫登入密碼。
    4. +
    + +

    這樣會比較安全,密碼會保護得比較好嗎?嗯嗯,再想想。

    + +
    + +
    + +
    +
    日期: 1.28.’06.
    + +
      +
    1. 加上留言顯示繁簡自動轉換功能。
    2. +
    + +
    + +
    + +
    +
    日期: 1.27.’06.
    + +
      +
    1. 更新 MySQL server ,由 4.1.16 昇級為 5.0.18 。
    2. +
    + +
    + +
    + +
    +
    日期: 1.23.’06.
    + +
      +
    1. 更新 MySQL server ,由 4.0.26 昇級為 4.1.16 。
    2. +
    + +
    + +
    + +
    +
    日期: 1.15.’06.
    + +
      +
    1. 將所有的 Mailman mailing lists 統一置於 rinse HTTPS 下。
    2. +
    + +
    + +
    + +
    +
    日期: 1.3.’06.
    + +
      +
    1. Selima::Checker::Public::Guestbook 新增 _check_spam() 方法,統合原先分散的數個廣告過濾程式。
    2. +
    + +
    + +
    + +
    +
    日期: 10.13.’05.
    + +
      +
    1. 旅舍伺服器作業系統由 Debian GNU/Linux 3.0 Woody 昇級為 Debian GNU/Linux 3.1 Sarge 。
    2. +
    + +
    + +
    + +
    +
    日期: 10.9.’05.
    + +
      +
    1. 修改網頁標頭中的 Content-Type 設定,由 text/html 一律改為 application/xhtml+xml 。
    2. +
    3. 校正幾個其實已經沒在用的舊網頁。
    4. +
    + +
    + +
    + +
    +
    日期: 10.6.’05.
    + +
      +
    1. 修改其它 Selima 網站,全面改為 XHTML ,使用 HTTP/1.1 Content-Negotiation ,網頁加上 .xhtml 附檔名並做 .html 連結,文件類別由 text/html 改為 application/xhtml+xml 與 text/html 並存。
    2. +
    + +
    + +
    + +
    +
    日期: 10.5.’05.
    + +
      +
    1. 旅舍全面改為 XHTML ,使用 HTTP/1.1 Content-Negotiation ,網頁加上 .xhtml 附檔名並做 .html 連結,文件類別由 text/html 改為 application/xhtml+xml 與 text/html 並存。
    2. +
    3. 加上回旅舍大廳 (1)直接跳到網頁內文區 (2)accesskey
    4. +
    5. 新增 /accsblty.html 無障礙網頁設計說明。
    6. +
    + +
    + +
    + +
    +
    日期: 10.4.’05.
    + +
      +
    1. 調整首頁樣式(謝謝阿光 quity 的建議~ ^_*' )
    2. +
    3. 加上無障礙網頁設計的導盲磚。
    4. +
    5. 加上直接跳到網頁內文區的設計。
    6. +
    7. 調整導覽連結區,把語言切換區放到導覽連結區下方。
    8. +
    9. 加上導覽連結區、語言切換區和網頁內文區的 title="…" 說明。
    10. +
    11. 旅舍電腦筆記、椰子拉子區換上標準導覽連結區。
    12. +
    13. 旅舍大廳下方連結碼邊框的樣式,調整為 ridge
    14. +
    15. 恢復留言簿的 <hr />
    16. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 2 | + 3 | + 4 | + 5 | + 6 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0005.html.en.html b/htdocs/imacat/me/changelog/0005.html.en.html new file mode 120000 index 0000000..96ea422 --- /dev/null +++ b/htdocs/imacat/me/changelog/0005.html.en.html @@ -0,0 +1 @@ +0005.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0005.html.en.xhtml b/htdocs/imacat/me/changelog/0005.html.en.xhtml new file mode 100644 index 0000000..4df2d70 --- /dev/null +++ b/htdocs/imacat/me/changelog/0005.html.en.xhtml @@ -0,0 +1,404 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 5 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 5

    + +
    + +
    + +
    +
    Date: 4.11.’06.
    + +
      +
    1. 修正 Selima::HTTP 模組,加上廣告陷阱信箱反編碼的功能。
    2. + +
    3. 修正 Selima::Page2Rel::Converter 類別的 cnvtattr() 方法,刪掉信箱編碼的程式碼。反正之後會處理。
    4. + +
    5. 修正 Selima::Guest 模組,刪掉 gxfupdate_template()gmkalldir() 兩個函式。現在用不到了,已由 goutpage() 處理。
    6. +
    + +
    + +
    + +
    +
    Date: 4.11.’06.
    + +
      +
    1. 旅舍全文檢索加上簡體中文檢索功能。
    2. + +
    3. Selima::emily 加上全文檢索功能。
    4. +
    + +
    + +
    + +
    +
    Date: 4.10.’06.
    + +
      +
    1. 旅舍加上全文檢索。
    2. + +
    3. 將女聲女網牽手加進女聲全文檢索中。
    4. + +
    5. Selima 系統版本號碼更新為 2.20 版。
    6. + +
    7. 修正 Selima::LogOut ,在登出前存下使用者帳號;修正 Selima::Logging::actlog()Selima::Guest::gactlog() ,加上第二個參數使用者帳號。
    8. +
    + +
    + +
    + +
    +
    Date: 4.10.’06.
    + +
      +
    1. 把旅舍的電腦筆記,存進資料庫中。
    2. + +
    3. 修正女聲全文檢索,將普通網頁也加進全文檢索中;修正檢索結果顯示的樣示,不同區域以不同樣式顯示。
    4. +
    + +
    + +
    + +
    +
    Date: 4.9.’06.
    + +
      +
    1. 修正 Selima::Listquery_abstract() 方法,一開始 HTML::Strip 後加上 dh() 處理,後面 $$union{"marked"} 加上 h() 標示。
    2. + +
    3. 修正女聲全文檢索,將女聲留言本加進全文檢索中。
    4. +
    + +
    + +
    + +
    +
    Date: 4.8.’06.
    + +
      +
    1. 修正 Selima::ReqURI ,將取得 $REQUEST_PATH 的來源由 Apache->request->uri 改由 Apache->request->the_requestApache->request->protocolApache->request->method 三個來取得,以取得使用者原始請求的路徑內容。
    2. + +
    3. 修正 Selima::Init ,過濾掉路徑含 .. 或查詢內容含 &amp; 者,以擋掉笨拙、無法正確處理路逕的抓 E-mail 程式造成系統超載的問題。
    4. + +
    5. 修正 Selima::HTTPhttp_400() ,若傳入參數 0 時,不顯示錯誤訊息,以避免抓 E-mail 程式繼續從錯誤訊息頁面中抓取網址。
    6. + +
    7. 加上 Selima::Preview 模組,以處理預覽功能;修正 Selima::Form::Page ,加上預覽的設定;修正 page.cgi ,加上網頁預覽的功能。
    8. + +
    9. 修正 Selima::*::HTML 類別,加上設定 HTML 類別的功能;修正 Selima::*::Rebuild ,重製相關連結網頁時,設定 HTML 類別為 links
    10. + +
    11. 修正旅舍網頁資料表,加上 HTML 類別欄位,以供特例的網頁使用。
    12. + +
    13. 將幾頁原本隱藏起來的舊網頁(賀年卡、履歷表、離職信、女人的性等)放進資料表,並刪除網頁檔案。
    14. + +
    15. 修正 Selima::*::HTML 類別的 html_header() 函式:停用 reluri() 轉相對網址,反正網頁輸出前還會整頁再轉一次;預先對 $author$keywords$copypage$favicon 等變數作 h() 處理,並依此簡化後面引用的部份;停用 $csname ,直接用 $charset 變數顯示, $charset 現在沒有其它用途了。
    16. + +
    17. 修正 Selima::imacat::HTML 類別的 html_links_register() 函式、 Selima::wov::HTML 類別的 html_links_register() 函式及 html_nl_index() 函式,依 html_header() 的作法設定 $charset ;修正 Selima::imacat::HTML 類別的 html_links_register() 函式,原先引用 getlang(LN_CHARSET) 的地方,改用 ln($charset, LN_CHARSET)
    18. + +
    19. 修正 Selima::*::HTML 類別,停止引用 Selima::GetLang 模組。
    20. + +
    21. 修正 Selima::LogOut 類別,加上忘記引用的 Selima::Guest 模組。
    22. +
    + +
    + +
    + +
    +
    Date: 4.6.’06.
    + +
      +
    1. 修正 Selima::Processor::* 類別,將 _col() 方法改名為 _form() 方法,以與 $cur 變數清楚區別。
    2. +
    + +
    + +
    + +
    +
    Date: 4.6.’06.
    + +
      +
    1. 修正 Selima::*::HTML :加上 @ADMIN_SCRIPTS 列出網站管理系統的相關資訊;修正 html_nav_admin() ,改依 @ADMIN_SCRIPTSis_script_permitted() 的權限判斷結果顯示網站管理系統選單;取消原來使用 @navibars 的方式。
    2. + +
    3. 加上 include/header.htmlinclude/footer.html ;修正 Selima::*::HTMLhtml_nav() 函式及 html_footer() 函式,改由這兩個檔案取得頁首及頁尾;加上 %HEADER%FOOTER 快取頁首及頁尾。因不需要每次配置變數做 maketext() ,重製網頁的速度快了很多。
    4. + +
    5. 恢復使用 <hr /> :內文區塊正確標示後,雖然視障者看不到 <hr /> ,也不會對瀏覽有任何不便;反而對於明眼人,在視覺上有簡單清楚的區分效果;修正 Selima::*::HTMLhtml_nav() 函式,分別取得各個導覽區塊後,在導覽區塊之間加上 <hr /> ,並在最後加上 <hr /> ;修正尚未納入資料庫的網頁,加上需要的 <hr /> ;修正樣式表中導覽連結區和頁尾區的樣式。
    6. + +
    7. 頁尾區的 idclassfooters 改名為 footer :修正 footer.html ;修正尚未納入資料庫的網頁;修正樣式表中的頁尾區。
    8. + +
    9. 修正 Selima::emily::HTML ,加上無障礙導盲磚設計。
    10. + +
    11. 修正女聲網站的資料表結構,加上 tile_en 欄位以儲存英文頁面標題;修正 Selima::wov::HTMLhtml_header()html_title() ,插入第二個參數 $title_en ,設定英文標題;修正 guestbook.cgiSelima::wov::Rebuild 引用的地方。
    12. + +
    13. 修正 Selima::PageFunc ,加上 outpage() 處理網頁輸出的一些固定工作,以簡化網頁輸出工作;修正 Selima::Guest ,加上 goutpage() 過濾訪客的網頁輸出處理;修正 Selima::*::Rebuild ,把複雜的網頁輸出工作都交給 goutpage() 處理,大幅簡化;在 outpage() 中加上信箱編碼的工作。
    14. + +
    15. 修正 Selima::Destroy ,加上信箱編碼及絕對路徑轉相對路徑的工作。
    16. + +
    17. 修正 Selima::*::Rebuildrebuild_links() ,把重製相關連結分類頁面的工作也交給 compose_page() 處理。
    18. +
    + +
    + +
    + +
    +
    Date: 4.4.’06.
    + +
      +
    1. 各 Selima 網站資料庫加上 pages 資料表;修正 Selima::*::HTML ,加上 html_body() 函式;修正 Selima::*::Rebuild ,加上 rebuild_pages() 函式。
    2. + +
    3. HTTP 錯誤訊息網頁匯入資料庫中,並重製出網頁。
    4. + +
    5. 修正 Selima::*::HTMLhtml_title() 函式,使之接受未經 h() 過濾過的訊息,並改用 Selima::MarkAbbrh_abbr() 過濾。
    6. + +
    7. 修正 Selima::imacat::HTML ,將 html_mtitle()html_title() 二合一。
    8. + +
    9. 修正 Selima::*::HTMLhtml_message() 函式,改用 h_abbr() 過濾。
    10. + +
    11. 修正 Selima::Unicode 模組,加上 page_encode() 函式,停用 page_from_to()hcref_from_to() 函式。
    12. + +
    13. 修正 Selima::HTTP ,內部全部改用萬國碼作業: get_custom_status_message() 讀得錯誤訊息網頁後,先做 hcref_decode() 再回傳;讀取得之錯誤訊息網頁,加上 page2rel() 及信箱編碼兩道手續再行輸出;輸出時, to_iso88591() 原先用 page_from_to() ,改用 page_encode()CGI 的部份則由 hcref_encode() 編碼後再輸出。
    14. + +
    15. 加上 Selima::Form::Rebuild 類別、 Selima::Checker::Rebuild 類別、 Selima::Processor::Rebuild 類別、rebuild.cgi 程式及 %REBUILD_LABELS 資料,處理網頁重製工作。
    16. +
    + +
    + +
    + +
    +
    Date: 4.3.’06.
    + +
      +
    1. 修正 Selima::Processor::Page 類別,加上初步的 _rebuild_partial_pages()_remove_curfile() 方法。
    2. + +
    3. 修正 Selima::MkAllDir 模組,加上 rmoldpage() 方法。
    4. + +
    5. 修正 Selima::Guest 模組,加上 grmoldpage()grmoldfile() 函式。
    6. + +
    7. 修正 Selima::Processor::LinkCatSelima::Processor::LinkSelima::Processor::LinkCatzSelima::wov::Processor::NewsletSelima::imacat::Processor::DiarySelima::imacat::Processor::ChangeLog 類別,原來 _remove_curfile() 方法使用 rmoldfile() ,改用 grmoldpage()
    8. + +
    9. 修正 Selima::Processor::* ,將 _log_message() 方法併回 _actlog() 中,並新增引用 Selima::Guest ,以使用 gactlog 。處理訪客的問題,本來就是 Processor 的工作。
    10. + +
    11. 修正 Selima::Processor::LogOut ,原來用 gactlog() 記錄,改用 actlog() 。訪客登出要記錄。
    12. + +
    13. 修正 Selima::Processor::* ,將 _ret_message() 方法改名為 _ret_status() ,以符合實際情況。有時候處理完不一定會回傳文字訊息,而是回傳其它資訊。
    14. +
    + +
    + +
    + +
    +
    Date: 4.3.’06.
    + +
      +
    1. 修正 page.cgi ,暫時取消上傳圖片的功能。
    2. + +
    3. 修正 Selima::Form::Page ,暫時取消圖檔上傳的部份。
    4. + +
    5. 加上 Selima::Processor::Page
    6. + +
    7. 修正 Selima::*::HTML ,加上 html_body() 函式。
    8. + +
    9. 修正 Selima::imacat::Rebuild ,加上 rebuild_pages() 函式。
    10. + +
    11. 修正 Selima::PageFunc ,把之前其實一直留白的 page_all_linguas() 寫出來。
    12. + +
    13. 修正 Selima::imacat::HTML ,把可用的語言清單,由 @ALL_LINGUAS 改為 $$args{"all_linguas"}
    14. + +
    15. 修正 Selima::imacat::Rebuildcompose_page() 函式,取消 $ALT_PAGE_PARAM 路徑中加上的語言檔尾。
    16. +
    + +

    終於製作出第一個網頁了! Yes !只要暫時不做圖檔上傳就好了。之前怎麼從來沒有想到過呢? ^_*' Perl CGI.pm 的檔案上傳做法,本來就和 PHP 的檔案上傳差很多了,硬要把 PHP Monica 的程式碼搬過來,是行不通的。嗯嗯。

    + +

    看著去年三月一日寫的更新日誌,覺得有點啞然。嗯, Selima 的圖檔上傳,就另起爐灶吧。 ^_*' 不過也不急就是了。

    + +
    + +
    + +
    +
    Date: 4.2.’06.
    + +
      +
    1. 修正 Selima::wov::Processor::Public::GuestbookSelima::wov::Processor::Public::NewsletSelima::wov::Processor::Public::NLArt ,加上忘記引用的 Selima::ShortCut 模組。
    2. + +
    3. 修正 Selima::Logging::actlog() ,在寫入記錄檔前前檢查並作必要的 encode()
    4. + +
    5. 修正相關連結分類的資料表定義,次序容許零值。
    6. +
    + +
    + +
    + +
    +
    Date: 4.2.’06.
    + +
      +
    1. 修正 Selima::Processor::LinkSelima::Processor::LinkCatSelima::Processor::LinkCatz 類別,將 _shown_parts() 方法內的程式碼移回 Selima::Links::links_shown_parts() 函式, _shown_parts() 方法改傳回 links_shown_parts() 函式的結果,以便三個類別共用程式碼。
    2. + +
    3. 修正 Selima::Processor::LinkSelima::Processor::UserSelima::Processor::Group 類別,將迴圈取得子項目的方式由 defined $cur->param("*$_" . "sn") 改為 $_ < $cur->param("*count") ,使用現在用的 *count 參數。
    4. + +
    5. 修正 Selima::Links::links_shown_parts() 函式,加上 ORDER BY linkcat_fullord(parent, ord) 排序。
    6. + +
    7. 修正 Selima::Processor::LinkCatz 類別,加上 _rebuild_partial_pages()_remove_curfile() 方法。
    8. + +
    9. 修正 Selima::Processor::LinkCat 類別的 _shown_parts() 方法,加上檢查連結分類本身有沒有顯示,以決定要不要重建網頁。
    10. + +
    11. 修正 Selima::Processor 類別,將 _col() 方法移到可重載方法區。
    12. + +
    13. 修正 Selima::Processor::* 類別,將 Selima::AddCol::add*() 方法的參數由 scalar $form->param(*) 改用 $self->_col(*) ,以便後續處理。
    14. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 3 | + 4 | + 5 | + 6 | + 7 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0005.html.zh-cn.html b/htdocs/imacat/me/changelog/0005.html.zh-cn.html new file mode 120000 index 0000000..5c8fdb2 --- /dev/null +++ b/htdocs/imacat/me/changelog/0005.html.zh-cn.html @@ -0,0 +1 @@ +0005.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0005.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0005.html.zh-cn.xhtml new file mode 100644 index 0000000..552fc16 --- /dev/null +++ b/htdocs/imacat/me/changelog/0005.html.zh-cn.xhtml @@ -0,0 +1,403 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷五 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷五

    + +
    + +
    + +
    +
    日期: 4.11.’06.
    + +
      +
    1. 修正 Selima::HTTP 模组,加上广告陷阱信箱反编码的功能。
    2. + +
    3. 修正 Selima::Page2Rel::Converter 类别的 cnvtattr() 方法,删掉信箱编码的程式码。反正之后会处理。
    4. + +
    5. 修正 Selima::Guest 模组,删掉 gxfupdate_template()gmkalldir() 两个函式。现在用不到了,已由 goutpage() 处理。
    6. +
    + +
    + +
    + +
    +
    日期: 4.11.’06.
    + +
      +
    1. 旅舍全文检索加上简体中文检索功能。
    2. + +
    3. Selima::emily 加上全文检索功能。
    4. +
    + +
    + +
    + +
    +
    日期: 4.10.’06.
    + +
      +
    1. 旅舍加上全文检索。
    2. + +
    3. 将女声女网牵手加进女声全文检索中。
    4. + +
    5. Selima 系统版本号码更新为 2.20 版。
    6. + +
    7. 修正 Selima::LogOut ,在登出前存下使用者帐号;修正 Selima::Logging::actlog()Selima::Guest::gactlog() ,加上第二个参数使用者帐号。
    8. +
    + +
    + +
    + +
    +
    日期: 4.10.’06.
    + +
      +
    1. 把旅舍的电脑笔记,存进资料库中。
    2. + +
    3. 修正女声全文检索,将普通网页也加进全文检索中;修正检索结果显示的样示,不同区域以不同样式显示。
    4. +
    + +
    + +
    + +
    +
    日期: 4.9.’06.
    + +
      +
    1. 修正 Selima::Listquery_abstract() 方法,一开始 HTML::Strip 后加上 dh() 处理,后面 $$union{"marked"} 加上 h() 标示。
    2. + +
    3. 修正女声全文检索,将女声留言本加进全文检索中。
    4. +
    + +
    + +
    + +
    +
    日期: 4.8.’06.
    + +
      +
    1. 修正 Selima::ReqURI ,将取得 $REQUEST_PATH 的来源由 Apache->request->uri 改由 Apache->request->the_requestApache->request->protocolApache->request->method 三个来取得,以取得使用者原始请求的路径内容。
    2. + +
    3. 修正 Selima::Init ,过滤掉路径含 .. 或查询内容含 &amp; 者,以挡掉笨拙、无法正确处理路迳的抓 E-mail 程式造成系统超载的问题。
    4. + +
    5. 修正 Selima::HTTPhttp_400() ,若传入参数 0 时,不显示错误讯息,以避免抓 E-mail 程式继续从错误讯息页面中抓取网址。
    6. + +
    7. 加上 Selima::Preview 模组,以处理预览功能;修正 Selima::Form::Page ,加上预览的设定;修正 page.cgi ,加上网页预览的功能。
    8. + +
    9. 修正 Selima::*::HTML 类别,加上设定 HTML 类别的功能;修正 Selima::*::Rebuild ,重制相关连结网页时,设定 HTML 类别为 links
    10. + +
    11. 修正旅舍网页资料表,加上 HTML 类别栏位,以供特例的网页使用。
    12. + +
    13. 将几页原本隐藏起来的旧网页(贺年卡、履历表、离职信、女人的性等)放进资料表,并删除网页档案。
    14. + +
    15. 修正 Selima::*::HTML 类别的 html_header() 函式:停用 reluri() 转相对网址,反正网页输出前还会整页再转一次;预先对 $author$keywords$copypage$favicon 等变数作 h() 处理,并依此简化后面引用的部份;停用 $csname ,直接用 $charset 变数显示, $charset 现在没有其它用途了。
    16. + +
    17. 修正 Selima::imacat::HTML 类别的 html_links_register() 函式、 Selima::wov::HTML 类别的 html_links_register() 函式及 html_nl_index() 函式,依 html_header() 的作法设定 $charset ;修正 Selima::imacat::HTML 类别的 html_links_register() 函式,原先引用 getlang(LN_CHARSET) 的地方,改用 ln($charset, LN_CHARSET)
    18. + +
    19. 修正 Selima::*::HTML 类别,停止引用 Selima::GetLang 模组。
    20. + +
    21. 修正 Selima::LogOut 类别,加上忘记引用的 Selima::Guest 模组。
    22. +
    + +
    + +
    + +
    +
    日期: 4.6.’06.
    + +
      +
    1. 修正 Selima::Processor::* 类别,将 _col() 方法改名为 _form() 方法,以与 $cur 变数清楚区别。
    2. +
    + +
    + +
    + +
    +
    日期: 4.6.’06.
    + +
      +
    1. 修正 Selima::*::HTML :加上 @ADMIN_SCRIPTS 列出网站管理系统的相关资讯;修正 html_nav_admin() ,改依 @ADMIN_SCRIPTSis_script_permitted() 的权限判断结果显示网站管理系统选单;取消原来使用 @navibars 的方式。
    2. + +
    3. 加上 include/header.htmlinclude/footer.html ;修正 Selima::*::HTMLhtml_nav() 函式及 html_footer() 函式,改由这两个档案取得页首及页尾;加上 %HEADER%FOOTER 快取页首及页尾。因不需要每次配置变数做 maketext() ,重制网页的速度快了很多。
    4. + +
    5. 恢复使用 <hr /> :内文区块正确标示后,虽然视障者看不到 <hr /> ,也不会对浏览有任何不便;反而对於明眼人,在视觉上有简单清楚的区分效果;修正 Selima::*::HTMLhtml_nav() 函式,分别取得各个导览区块后,在导览区块之间加上 <hr /> ,并在最后加上 <hr /> ;修正尚未纳入资料库的网页,加上需要的 <hr /> ;修正样式表中导览连结区和页尾区的样式。
    6. + +
    7. 页尾区的 idclassfooters 改名为 footer :修正 footer.html ;修正尚未纳入资料库的网页;修正样式表中的页尾区。
    8. + +
    9. 修正 Selima::emily::HTML ,加上无障碍导盲砖设计。
    10. + +
    11. 修正女声网站的资料表结构,加上 tile_en 栏位以储存英文页面标题;修正 Selima::wov::HTMLhtml_header()html_title() ,插入第二个参数 $title_en ,设定英文标题;修正 guestbook.cgiSelima::wov::Rebuild 引用的地方。
    12. + +
    13. 修正 Selima::PageFunc ,加上 outpage() 处理网页输出的一些固定工作,以简化网页输出工作;修正 Selima::Guest ,加上 goutpage() 过滤访客的网页输出处理;修正 Selima::*::Rebuild ,把复杂的网页输出工作都交给 goutpage() 处理,大幅简化;在 outpage() 中加上信箱编码的工作。
    14. + +
    15. 修正 Selima::Destroy ,加上信箱编码及绝对路径转相对路径的工作。
    16. + +
    17. 修正 Selima::*::Rebuildrebuild_links() ,把重制相关连结分类页面的工作也交给 compose_page() 处理。
    18. +
    + +
    + +
    + +
    +
    日期: 4.4.’06.
    + +
      +
    1. 各 Selima 网站资料库加上 pages 资料表;修正 Selima::*::HTML ,加上 html_body() 函式;修正 Selima::*::Rebuild ,加上 rebuild_pages() 函式。
    2. + +
    3. HTTP 错误讯息网页汇入资料库中,并重制出网页。
    4. + +
    5. 修正 Selima::*::HTMLhtml_title() 函式,使之接受未经 h() 过滤过的讯息,并改用 Selima::MarkAbbrh_abbr() 过滤。
    6. + +
    7. 修正 Selima::imacat::HTML ,将 html_mtitle()html_title() 二合一。
    8. + +
    9. 修正 Selima::*::HTMLhtml_message() 函式,改用 h_abbr() 过滤。
    10. + +
    11. 修正 Selima::Unicode 模组,加上 page_encode() 函式,停用 page_from_to()hcref_from_to() 函式。
    12. + +
    13. 修正 Selima::HTTP ,内部全部改用万国码作业: get_custom_status_message() 读得错误讯息网页后,先做 hcref_decode() 再回传;读取得之错误讯息网页,加上 page2rel() 及信箱编码两道手续再行输出;输出时, to_iso88591() 原先用 page_from_to() ,改用 page_encode()CGI 的部份则由 hcref_encode() 编码后再输出。
    14. + +
    15. 加上 Selima::Form::Rebuild 类别、 Selima::Checker::Rebuild 类别、 Selima::Processor::Rebuild 类别、rebuild.cgi 程式及 %REBUILD_LABELS 资料,处理网页重制工作。
    16. +
    + +
    + +
    + +
    +
    日期: 4.3.’06.
    + +
      +
    1. 修正 Selima::Processor::Page 类别,加上初步的 _rebuild_partial_pages()_remove_curfile() 方法。
    2. + +
    3. 修正 Selima::MkAllDir 模组,加上 rmoldpage() 方法。
    4. + +
    5. 修正 Selima::Guest 模组,加上 grmoldpage()grmoldfile() 函式。
    6. + +
    7. 修正 Selima::Processor::LinkCatSelima::Processor::LinkSelima::Processor::LinkCatzSelima::wov::Processor::NewsletSelima::imacat::Processor::DiarySelima::imacat::Processor::ChangeLog 类别,原来 _remove_curfile() 方法使用 rmoldfile() ,改用 grmoldpage()
    8. + +
    9. 修正 Selima::Processor::* ,将 _log_message() 方法并回 _actlog() 中,并新增引用 Selima::Guest ,以使用 gactlog 。处理访客的问题,本来就是 Processor 的工作。
    10. + +
    11. 修正 Selima::Processor::LogOut ,原来用 gactlog() 记录,改用 actlog() 。访客登出要记录。
    12. + +
    13. 修正 Selima::Processor::* ,将 _ret_message() 方法改名为 _ret_status() ,以符合实际情况。有时候处理完不一定会回传文字讯息,而是回传其它资讯。
    14. +
    + +
    + +
    + +
    +
    日期: 4.3.’06.
    + +
      +
    1. 修正 page.cgi ,暂时取消上传图片的功能。
    2. + +
    3. 修正 Selima::Form::Page ,暂时取消图档上传的部份。
    4. + +
    5. 加上 Selima::Processor::Page
    6. + +
    7. 修正 Selima::*::HTML ,加上 html_body() 函式。
    8. + +
    9. 修正 Selima::imacat::Rebuild ,加上 rebuild_pages() 函式。
    10. + +
    11. 修正 Selima::PageFunc ,把之前其实一直留白的 page_all_linguas() 写出来。
    12. + +
    13. 修正 Selima::imacat::HTML ,把可用的语言清单,由 @ALL_LINGUAS 改为 $$args{"all_linguas"}
    14. + +
    15. 修正 Selima::imacat::Rebuildcompose_page() 函式,取消 $ALT_PAGE_PARAM 路径中加上的语言档尾。
    16. +
    + +

    终於制作出第一个网页了! Yes !只要暂时不做图档上传就好了。之前怎么从来没有想到过呢? ^_*' Perl CGI.pm 的档案上传做法,本来就和 PHP 的档案上传差很多了,硬要把 PHP Monica 的程式码搬过来,是行不通的。嗯嗯。

    + +

    看著去年三月一日写的更新日志,觉得有点哑然。嗯, Selima 的图档上传,就另起炉灶吧。 ^_*' 不过也不急就是了。

    + +
    + +
    + +
    +
    日期: 4.2.’06.
    + +
      +
    1. 修正 Selima::wov::Processor::Public::GuestbookSelima::wov::Processor::Public::NewsletSelima::wov::Processor::Public::NLArt ,加上忘记引用的 Selima::ShortCut 模组。
    2. + +
    3. 修正 Selima::Logging::actlog() ,在写入记录档前前检查并作必要的 encode()
    4. + +
    5. 修正相关连结分类的资料表定义,次序容许零值。
    6. +
    + +
    + +
    + +
    +
    日期: 4.2.’06.
    + +
      +
    1. 修正 Selima::Processor::LinkSelima::Processor::LinkCatSelima::Processor::LinkCatz 类别,将 _shown_parts() 方法内的程式码移回 Selima::Links::links_shown_parts() 函式, _shown_parts() 方法改传回 links_shown_parts() 函式的结果,以便三个类别共用程式码。
    2. + +
    3. 修正 Selima::Processor::LinkSelima::Processor::UserSelima::Processor::Group 类别,将回圈取得子项目的方式由 defined $cur->param("*$_" . "sn") 改为 $_ < $cur->param("*count") ,使用现在用的 *count 参数。
    4. + +
    5. 修正 Selima::Links::links_shown_parts() 函式,加上 ORDER BY linkcat_fullord(parent, ord) 排序。
    6. + +
    7. 修正 Selima::Processor::LinkCatz 类别,加上 _rebuild_partial_pages()_remove_curfile() 方法。
    8. + +
    9. 修正 Selima::Processor::LinkCat 类别的 _shown_parts() 方法,加上检查连结分类本身有没有显示,以决定要不要重建网页。
    10. + +
    11. 修正 Selima::Processor 类别,将 _col() 方法移到可重载方法区。
    12. + +
    13. 修正 Selima::Processor::* 类别,将 Selima::AddCol::add*() 方法的参数由 scalar $form->param(*) 改用 $self->_col(*) ,以便后续处理。
    14. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0005.html.zh-tw.html b/htdocs/imacat/me/changelog/0005.html.zh-tw.html new file mode 120000 index 0000000..7cf395f --- /dev/null +++ b/htdocs/imacat/me/changelog/0005.html.zh-tw.html @@ -0,0 +1 @@ +0005.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0005.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0005.html.zh-tw.xhtml new file mode 100644 index 0000000..072ff0e --- /dev/null +++ b/htdocs/imacat/me/changelog/0005.html.zh-tw.xhtml @@ -0,0 +1,403 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷五 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷五

    + +
    + +
    + +
    +
    日期: 4.11.’06.
    + +
      +
    1. 修正 Selima::HTTP 模組,加上廣告陷阱信箱反編碼的功能。
    2. + +
    3. 修正 Selima::Page2Rel::Converter 類別的 cnvtattr() 方法,刪掉信箱編碼的程式碼。反正之後會處理。
    4. + +
    5. 修正 Selima::Guest 模組,刪掉 gxfupdate_template()gmkalldir() 兩個函式。現在用不到了,已由 goutpage() 處理。
    6. +
    + +
    + +
    + +
    +
    日期: 4.11.’06.
    + +
      +
    1. 旅舍全文檢索加上簡體中文檢索功能。
    2. + +
    3. Selima::emily 加上全文檢索功能。
    4. +
    + +
    + +
    + +
    +
    日期: 4.10.’06.
    + +
      +
    1. 旅舍加上全文檢索。
    2. + +
    3. 將女聲女網牽手加進女聲全文檢索中。
    4. + +
    5. Selima 系統版本號碼更新為 2.20 版。
    6. + +
    7. 修正 Selima::LogOut ,在登出前存下使用者帳號;修正 Selima::Logging::actlog()Selima::Guest::gactlog() ,加上第二個參數使用者帳號。
    8. +
    + +
    + +
    + +
    +
    日期: 4.10.’06.
    + +
      +
    1. 把旅舍的電腦筆記,存進資料庫中。
    2. + +
    3. 修正女聲全文檢索,將普通網頁也加進全文檢索中;修正檢索結果顯示的樣示,不同區域以不同樣式顯示。
    4. +
    + +
    + +
    + +
    +
    日期: 4.9.’06.
    + +
      +
    1. 修正 Selima::Listquery_abstract() 方法,一開始 HTML::Strip 後加上 dh() 處理,後面 $$union{"marked"} 加上 h() 標示。
    2. + +
    3. 修正女聲全文檢索,將女聲留言本加進全文檢索中。
    4. +
    + +
    + +
    + +
    +
    日期: 4.8.’06.
    + +
      +
    1. 修正 Selima::ReqURI ,將取得 $REQUEST_PATH 的來源由 Apache->request->uri 改由 Apache->request->the_requestApache->request->protocolApache->request->method 三個來取得,以取得使用者原始請求的路徑內容。
    2. + +
    3. 修正 Selima::Init ,過濾掉路徑含 .. 或查詢內容含 &amp; 者,以擋掉笨拙、無法正確處理路逕的抓 E-mail 程式造成系統超載的問題。
    4. + +
    5. 修正 Selima::HTTPhttp_400() ,若傳入參數 0 時,不顯示錯誤訊息,以避免抓 E-mail 程式繼續從錯誤訊息頁面中抓取網址。
    6. + +
    7. 加上 Selima::Preview 模組,以處理預覽功能;修正 Selima::Form::Page ,加上預覽的設定;修正 page.cgi ,加上網頁預覽的功能。
    8. + +
    9. 修正 Selima::*::HTML 類別,加上設定 HTML 類別的功能;修正 Selima::*::Rebuild ,重製相關連結網頁時,設定 HTML 類別為 links
    10. + +
    11. 修正旅舍網頁資料表,加上 HTML 類別欄位,以供特例的網頁使用。
    12. + +
    13. 將幾頁原本隱藏起來的舊網頁(賀年卡、履歷表、離職信、女人的性等)放進資料表,並刪除網頁檔案。
    14. + +
    15. 修正 Selima::*::HTML 類別的 html_header() 函式:停用 reluri() 轉相對網址,反正網頁輸出前還會整頁再轉一次;預先對 $author$keywords$copypage$favicon 等變數作 h() 處理,並依此簡化後面引用的部份;停用 $csname ,直接用 $charset 變數顯示, $charset 現在沒有其它用途了。
    16. + +
    17. 修正 Selima::imacat::HTML 類別的 html_links_register() 函式、 Selima::wov::HTML 類別的 html_links_register() 函式及 html_nl_index() 函式,依 html_header() 的作法設定 $charset ;修正 Selima::imacat::HTML 類別的 html_links_register() 函式,原先引用 getlang(LN_CHARSET) 的地方,改用 ln($charset, LN_CHARSET)
    18. + +
    19. 修正 Selima::*::HTML 類別,停止引用 Selima::GetLang 模組。
    20. + +
    21. 修正 Selima::LogOut 類別,加上忘記引用的 Selima::Guest 模組。
    22. +
    + +
    + +
    + +
    +
    日期: 4.6.’06.
    + +
      +
    1. 修正 Selima::Processor::* 類別,將 _col() 方法改名為 _form() 方法,以與 $cur 變數清楚區別。
    2. +
    + +
    + +
    + +
    +
    日期: 4.6.’06.
    + +
      +
    1. 修正 Selima::*::HTML :加上 @ADMIN_SCRIPTS 列出網站管理系統的相關資訊;修正 html_nav_admin() ,改依 @ADMIN_SCRIPTSis_script_permitted() 的權限判斷結果顯示網站管理系統選單;取消原來使用 @navibars 的方式。
    2. + +
    3. 加上 include/header.htmlinclude/footer.html ;修正 Selima::*::HTMLhtml_nav() 函式及 html_footer() 函式,改由這兩個檔案取得頁首及頁尾;加上 %HEADER%FOOTER 快取頁首及頁尾。因不需要每次配置變數做 maketext() ,重製網頁的速度快了很多。
    4. + +
    5. 恢復使用 <hr /> :內文區塊正確標示後,雖然視障者看不到 <hr /> ,也不會對瀏覽有任何不便;反而對於明眼人,在視覺上有簡單清楚的區分效果;修正 Selima::*::HTMLhtml_nav() 函式,分別取得各個導覽區塊後,在導覽區塊之間加上 <hr /> ,並在最後加上 <hr /> ;修正尚未納入資料庫的網頁,加上需要的 <hr /> ;修正樣式表中導覽連結區和頁尾區的樣式。
    6. + +
    7. 頁尾區的 idclassfooters 改名為 footer :修正 footer.html ;修正尚未納入資料庫的網頁;修正樣式表中的頁尾區。
    8. + +
    9. 修正 Selima::emily::HTML ,加上無障礙導盲磚設計。
    10. + +
    11. 修正女聲網站的資料表結構,加上 tile_en 欄位以儲存英文頁面標題;修正 Selima::wov::HTMLhtml_header()html_title() ,插入第二個參數 $title_en ,設定英文標題;修正 guestbook.cgiSelima::wov::Rebuild 引用的地方。
    12. + +
    13. 修正 Selima::PageFunc ,加上 outpage() 處理網頁輸出的一些固定工作,以簡化網頁輸出工作;修正 Selima::Guest ,加上 goutpage() 過濾訪客的網頁輸出處理;修正 Selima::*::Rebuild ,把複雜的網頁輸出工作都交給 goutpage() 處理,大幅簡化;在 outpage() 中加上信箱編碼的工作。
    14. + +
    15. 修正 Selima::Destroy ,加上信箱編碼及絕對路徑轉相對路徑的工作。
    16. + +
    17. 修正 Selima::*::Rebuildrebuild_links() ,把重製相關連結分類頁面的工作也交給 compose_page() 處理。
    18. +
    + +
    + +
    + +
    +
    日期: 4.4.’06.
    + +
      +
    1. 各 Selima 網站資料庫加上 pages 資料表;修正 Selima::*::HTML ,加上 html_body() 函式;修正 Selima::*::Rebuild ,加上 rebuild_pages() 函式。
    2. + +
    3. HTTP 錯誤訊息網頁匯入資料庫中,並重製出網頁。
    4. + +
    5. 修正 Selima::*::HTMLhtml_title() 函式,使之接受未經 h() 過濾過的訊息,並改用 Selima::MarkAbbrh_abbr() 過濾。
    6. + +
    7. 修正 Selima::imacat::HTML ,將 html_mtitle()html_title() 二合一。
    8. + +
    9. 修正 Selima::*::HTMLhtml_message() 函式,改用 h_abbr() 過濾。
    10. + +
    11. 修正 Selima::Unicode 模組,加上 page_encode() 函式,停用 page_from_to()hcref_from_to() 函式。
    12. + +
    13. 修正 Selima::HTTP ,內部全部改用萬國碼作業: get_custom_status_message() 讀得錯誤訊息網頁後,先做 hcref_decode() 再回傳;讀取得之錯誤訊息網頁,加上 page2rel() 及信箱編碼兩道手續再行輸出;輸出時, to_iso88591() 原先用 page_from_to() ,改用 page_encode()CGI 的部份則由 hcref_encode() 編碼後再輸出。
    14. + +
    15. 加上 Selima::Form::Rebuild 類別、 Selima::Checker::Rebuild 類別、 Selima::Processor::Rebuild 類別、rebuild.cgi 程式及 %REBUILD_LABELS 資料,處理網頁重製工作。
    16. +
    + +
    + +
    + +
    +
    日期: 4.3.’06.
    + +
      +
    1. 修正 Selima::Processor::Page 類別,加上初步的 _rebuild_partial_pages()_remove_curfile() 方法。
    2. + +
    3. 修正 Selima::MkAllDir 模組,加上 rmoldpage() 方法。
    4. + +
    5. 修正 Selima::Guest 模組,加上 grmoldpage()grmoldfile() 函式。
    6. + +
    7. 修正 Selima::Processor::LinkCatSelima::Processor::LinkSelima::Processor::LinkCatzSelima::wov::Processor::NewsletSelima::imacat::Processor::DiarySelima::imacat::Processor::ChangeLog 類別,原來 _remove_curfile() 方法使用 rmoldfile() ,改用 grmoldpage()
    8. + +
    9. 修正 Selima::Processor::* ,將 _log_message() 方法併回 _actlog() 中,並新增引用 Selima::Guest ,以使用 gactlog 。處理訪客的問題,本來就是 Processor 的工作。
    10. + +
    11. 修正 Selima::Processor::LogOut ,原來用 gactlog() 記錄,改用 actlog() 。訪客登出要記錄。
    12. + +
    13. 修正 Selima::Processor::* ,將 _ret_message() 方法改名為 _ret_status() ,以符合實際情況。有時候處理完不一定會回傳文字訊息,而是回傳其它資訊。
    14. +
    + +
    + +
    + +
    +
    日期: 4.3.’06.
    + +
      +
    1. 修正 page.cgi ,暫時取消上傳圖片的功能。
    2. + +
    3. 修正 Selima::Form::Page ,暫時取消圖檔上傳的部份。
    4. + +
    5. 加上 Selima::Processor::Page
    6. + +
    7. 修正 Selima::*::HTML ,加上 html_body() 函式。
    8. + +
    9. 修正 Selima::imacat::Rebuild ,加上 rebuild_pages() 函式。
    10. + +
    11. 修正 Selima::PageFunc ,把之前其實一直留白的 page_all_linguas() 寫出來。
    12. + +
    13. 修正 Selima::imacat::HTML ,把可用的語言清單,由 @ALL_LINGUAS 改為 $$args{"all_linguas"}
    14. + +
    15. 修正 Selima::imacat::Rebuildcompose_page() 函式,取消 $ALT_PAGE_PARAM 路徑中加上的語言檔尾。
    16. +
    + +

    終於製作出第一個網頁了! Yes !只要暫時不做圖檔上傳就好了。之前怎麼從來沒有想到過呢? ^_*' Perl CGI.pm 的檔案上傳做法,本來就和 PHP 的檔案上傳差很多了,硬要把 PHP Monica 的程式碼搬過來,是行不通的。嗯嗯。

    + +

    看著去年三月一日寫的更新日誌,覺得有點啞然。嗯, Selima 的圖檔上傳,就另起爐灶吧。 ^_*' 不過也不急就是了。

    + +
    + +
    + +
    +
    日期: 4.2.’06.
    + +
      +
    1. 修正 Selima::wov::Processor::Public::GuestbookSelima::wov::Processor::Public::NewsletSelima::wov::Processor::Public::NLArt ,加上忘記引用的 Selima::ShortCut 模組。
    2. + +
    3. 修正 Selima::Logging::actlog() ,在寫入記錄檔前前檢查並作必要的 encode()
    4. + +
    5. 修正相關連結分類的資料表定義,次序容許零值。
    6. +
    + +
    + +
    + +
    +
    日期: 4.2.’06.
    + +
      +
    1. 修正 Selima::Processor::LinkSelima::Processor::LinkCatSelima::Processor::LinkCatz 類別,將 _shown_parts() 方法內的程式碼移回 Selima::Links::links_shown_parts() 函式, _shown_parts() 方法改傳回 links_shown_parts() 函式的結果,以便三個類別共用程式碼。
    2. + +
    3. 修正 Selima::Processor::LinkSelima::Processor::UserSelima::Processor::Group 類別,將迴圈取得子項目的方式由 defined $cur->param("*$_" . "sn") 改為 $_ < $cur->param("*count") ,使用現在用的 *count 參數。
    4. + +
    5. 修正 Selima::Links::links_shown_parts() 函式,加上 ORDER BY linkcat_fullord(parent, ord) 排序。
    6. + +
    7. 修正 Selima::Processor::LinkCatz 類別,加上 _rebuild_partial_pages()_remove_curfile() 方法。
    8. + +
    9. 修正 Selima::Processor::LinkCat 類別的 _shown_parts() 方法,加上檢查連結分類本身有沒有顯示,以決定要不要重建網頁。
    10. + +
    11. 修正 Selima::Processor 類別,將 _col() 方法移到可重載方法區。
    12. + +
    13. 修正 Selima::Processor::* 類別,將 Selima::AddCol::add*() 方法的參數由 scalar $form->param(*) 改用 $self->_col(*) ,以便後續處理。
    14. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0006.html.en.html b/htdocs/imacat/me/changelog/0006.html.en.html new file mode 120000 index 0000000..22c7298 --- /dev/null +++ b/htdocs/imacat/me/changelog/0006.html.en.html @@ -0,0 +1 @@ +0006.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0006.html.en.xhtml b/htdocs/imacat/me/changelog/0006.html.en.xhtml new file mode 100644 index 0000000..9d16650 --- /dev/null +++ b/htdocs/imacat/me/changelog/0006.html.en.xhtml @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 6 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 6

    + +
    + +
    + +
    +
    Date: 4.21.’06.
    + +
      +
    1. 修正 Selima::FormFunc 模組,移除不用的 select_url()select_text() 函式,及不用的引用 URI::EscapeSelima::HTTPSSelima::RelURISelima::ShortCutSelima::DataVars:requri
    2. + +
    3. 修正 Selima::wov::HTML::html_title() 函式,移除不必要的 alt=title= 文字代換。
    4. + +
    5. 修正 logout.cgi ,將 login.php 改正為 login.cgi (雖然現在其實還沒有 login.cgi 就是了。)
    6. + +
    7. 修正 Selima::HTTP::http_400() 函式,當傳入值 0 時,當成網址格式錯亂,改依 Apache 記錄的格式記錄。
    8. + +
    9. 因為現在輸出最後都會使用 page2rel() 轉換,所以不需要在輸出中途用 reluri() 了:修正 Selima::*::HTMLSelima::*::List::Searchlogout.cgiSelima::ListSelima::FormSelima::Form::LinkCatSelima::List::Public::GuestbookSelima::AltLangSelima::Picture ,移除使用 reluri() 的地方,及對 Selima::RelURI 的引用。
    10. + +
    11. 修正 Selima::Page2Rel::Converter 類別的 cnvtattr() 方法中,引用 absuri() 未加括弧的地方,加上括弧。
    12. + +
    13. 修正 Selima::HTTP 模組,加上 http_410()http_503() 兩個函式,調整統一記錄訊息。
    14. + +
    15. 更新 Selima::imacat::List::LiteralZhSelima::imacat::List::LtZhPoem 類別,加上 $self->{"COLS_BRIEF"}
    16. + +
    17. 加上 Selima::imacat::Form::LiteralZhSelima::imacat::Form::LtZhPoemSelima::imacat::Checker::LiteralZhSelima::imacat::Checker::LtZhPoemSelima::imacat::Processor::LiteralZhSelima::imacat::Processor::LtZhPoem
    18. + +
    19. 修正 Selima::wov::Form::Newslet ,移除 $coltitle$colauthor 不必要的 h_abbr()
    20. + +
    21. 修正 Selima::Form::MetaCols 類別的 _out_attrs() 方法,在檢查 $$_{"name"} 是否為 charset 前先檢查 $$_{"name"} 的值是否已定義。
    22. +
    + +
    + +
    + +
    +
    Date: 4.20.’06.
    + +
      +
    1. 停用 $MULTILINGUAL 變數,改用 @ALL_LINGUAS 變數判斷多語與否;修正 Selima::ProcessorSelima::PageFuncSelima::DestroySelima::UserNameSelima::CheckerSelima::ListSelima::LinksSelima::DataVarsSelima::LastModfSelima::HTTPSelima::GetLangSelima::InitSelima::imacat::HTML
    2. + +
    3. literlzh 改名為 literalzh :修正資料庫, literlzh 資料表改名為 literalzhliterlzh.cgi 程式改名為 literalzh.cgi 程式; Selima::imacat::List::LiterlZh 類別改名為 Selima::imacat::List::LiteralZh
    4. + +
    5. 修正女聲電子報管理,移除使用 arts 陣列,改用 artcount 變數:修正 newslets.cgi ,移除 $CURRENT{"arts"} ;修正 Selima::wov::Form::Newslet 類別的 _html_col_arts() 方法,使用 $current->param("artcount") ;修正 Selima::wov::Checker::Newslet 類別的 _check_arts() 方法,移除加上 $form->param("arts") 的部份。
    6. + +
    7. 修正 Selima::A2HTML ,加上行首空白的正確處理。
    8. + +
    9. 修正 Selima::HTTP::http_500() 函式,直接使用 @callers 依所處情況處理:停用 $trace@callers 存入整個呼叫環境;剔除沒意義的 /dev/nullApache::Registry ;網頁顯示時以 <samp>…</samp> 標示顯示;郵寄通知時加上換行;錯誤記錄時不加上換行。
    10. + +
    11. 修正 Selima::HTTP::http_400()Selima::HTTP::http_403() 函式,改用 <!-- errmsg --> ;可能的話加記錄錯誤原因。
    12. + +
    13. 修正 Selima::HTTP::http_3??() 函式,停用 $url_r$url_h ,改統一用 h($url) 代換,反正後來還需要作 page2rel() ,沒有太大的差別;將連結文字原來的網址改為有意義的文字,以符合無障礙網頁規範。
    14. + +
    15. 修正 Selima::HTTP::http_405() 函式,停用 $allowd$allowed_h ,改統一用 join() 及常規表示法代換,並正確標示 <samp>…</samp>
    16. + +
    17. 修正 Selima::HTTP::http_???() 函式,將 if (defined $html) 簡化為 if (!defined $html) 。現在已經沒有必要特別代換了。
    18. + +
    19. 修正 Selima::PageFunc::outpage() ,原用 hcref_encode() 改用 page_encode()
    20. + +
    21. 修正 Selima::*::HTML::html_links_register() 函式,取消 E-mail 編碼。
    22. + +
    23. 修正 Selima::wov::HTML::html_nl_index() 函式,全文檢索程式的路徑改為絕對路徑。
    24. + +
    25. 修正 Selima::XHTML ,移除 set_xhtml_content_type() 函式,將 check_xhtml_content_type() 函式改名為 xhtml_content_type() ;修正 Selima::HTTPSelima::Destroy 中引用 check_xhtml_content_type() 的地方。
    26. + +
    27. 修正 Selima::HTTP ,停用不必要的 $charset 變數,直接取得檔案類型及字集。
    28. + +
    29. 字集改由輸出時再代換:修正 Selima::*::HTMLSelima::ListSelima::FormSelima::List::ActLog ,停用 $charset 變數,改為 <!--selima:charset--> ;修正 Selima::Destroy ,輸出時 hcref_encode() 改用 page_encode() ;修正 Selima::Form::MetaCols 類別的 _out_attrs() 方法,欄位名稱為 charset 時,作特殊處理。
    30. +
    + +
    + +
    + +
    +
    Date: 4.19.’06.
    + +
      +
    1. 修正 Selima::Unicode::is_charset()Selima::Mail::b64hdr_encode() ,在 eval {} 中加上 local $SIG{"__DIE__"}; ,以避免呼叫 http_500()
    2. +
    + +
    + +
    + +
    +
    Date: 4.19.’06.
    + +
      +
    1. 修正 Selima::HTTP 處理字集的方式,內部全部將字集代換成代號,以便輸出時統一設定字集:修正 get_custom_status_message() ,將頁面出現的字集部份代換為 <!--selima:charset--> ,以備後續代換工作;修正 Selima::Unicode::page_encode() ,加上把 <!--selima:charset--> 代換為字集名稱;修正 http_???() ,將使用 to_iso88591()hcref_encode() 之處改用 page_encode() ;移除 to_iso88591()
    2. + +
    3. 解決 Big5Big5-Common 兩個名字間轉換的問題:修正 Selima::SetL10N ,用 Encode::Alias::define_alias()Big5 重訂為 Big5-Common ;修正 Selima::*::HTMLSelima::imacat::Processor::Public::GuestbookSelima::SetL10NSelima::DestroySelima::List::ActLogSelima::FormSelima::DecFormSelima::ListSelima::HTTPSelima::UnicodeSelima::LnInfoSelima::GetLang ,移除不必要的 Big5-Common 轉換程式碼。
    4. + +
    5. 修正 Selima::DecForm 整理候選字集的部份,用較正確的方式剔除重複的字集,在 Big5 字集加上 Big5-ETen ,並將 Big5-HKSCS 分開處理。
    6. + +
    7. 解決每次異動翻譯文字,都要重開 Apache 的問題:修正 Selima::SetL10N ,加上自動按 MO 檔的修改時間,判斷呼叫 reload_text() 重讀 MO 檔的功能;修正 Selima::Cache ,加上 %SetL10N_checked
    8. +
    + +
    + +
    + +
    +
    Date: 4.18.’06.
    + +
      +
    1. 加上 literlzhltzhpoem 兩個資料表;加上 Selima::imacat::List::LiterlZhSelima::imacat::List::LtZhPoem 兩個類別,及 literlzh.cgiltzhpoem.cgi 兩支程式,以處理中文詩。
    2. + +
    3. 修正錯誤處理函式的設計:在每個程式最前方加上 local $SIG{"__DIE__"} = \&http_500; ,以在 mod_perl 每一次執行做 eval() ,都會設定區域性的錯誤處理函式;修正 startup.pl ,取消沒有用處的 local $SIG{"__DIE__"} = \&http_500;
    4. + +
    5. 修正 Selima::HTTP ,用 caller() 顯示每一層呼叫的位置,以利偵錯。
    6. +
    + +
    + +
    + +
    +
    Date: 4.13.’06.
    + +
      +
    1. 修正 Selima::PageFunc 模組的 rebuildtype_options() 函式,改用 Devel::Symdump 取得重製網頁的函式清單,並改用 map()grep()sort() 函式簡化一次處理。
    2. + +
    3. 修正 Selima::XHTML 模組,加上 check_xhtml_content_type() 函式,以替代 set_xhtml_content_type() 函式,由使用者的瀏覽器資料,判斷應送出的 MIME 格式;停用 set_xhtml_content_type() 函式;修正 Selima::Destroy 模組,改用 check_xhtml_content_type() 函式,並依純文字或 HTML 做出較細緻的輸出前後置處理;修正 Selima::HTTP 模組,改用 check_xhtml_content_type() 函式。
    4. +
    + +
    + +
    + +
    +
    Date: 4.13.’06.
    + +
      +
    1. 修正 Selima::List 模組,加上 html_title() 方法以備用。
    2. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 4 | + 5 | + 6 | + 7 | + 8 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0006.html.zh-cn.html b/htdocs/imacat/me/changelog/0006.html.zh-cn.html new file mode 120000 index 0000000..6c40b6e --- /dev/null +++ b/htdocs/imacat/me/changelog/0006.html.zh-cn.html @@ -0,0 +1 @@ +0006.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0006.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0006.html.zh-cn.xhtml new file mode 100644 index 0000000..81efafc --- /dev/null +++ b/htdocs/imacat/me/changelog/0006.html.zh-cn.xhtml @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷六 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷六

    + +
    + +
    + +
    +
    日期: 4.21.’06.
    + +
      +
    1. 修正 Selima::FormFunc 模组,移除不用的 select_url()select_text() 函式,及不用的引用 URI::EscapeSelima::HTTPSSelima::RelURISelima::ShortCutSelima::DataVars:requri
    2. + +
    3. 修正 Selima::wov::HTML::html_title() 函式,移除不必要的 alt=title= 文字代换。
    4. + +
    5. 修正 logout.cgi ,将 login.php 改正为 login.cgi (虽然现在其实还没有 login.cgi 就是了。)
    6. + +
    7. 修正 Selima::HTTP::http_400() 函式,当传入值 0 时,当成网址格式错乱,改依 Apache 记录的格式记录。
    8. + +
    9. 因为现在输出最后都会使用 page2rel() 转换,所以不需要在输出中途用 reluri() 了:修正 Selima::*::HTMLSelima::*::List::Searchlogout.cgiSelima::ListSelima::FormSelima::Form::LinkCatSelima::List::Public::GuestbookSelima::AltLangSelima::Picture ,移除使用 reluri() 的地方,及对 Selima::RelURI 的引用。
    10. + +
    11. 修正 Selima::Page2Rel::Converter 类别的 cnvtattr() 方法中,引用 absuri() 未加括弧的地方,加上括弧。
    12. + +
    13. 修正 Selima::HTTP 模组,加上 http_410()http_503() 两个函式,调整统一记录讯息。
    14. + +
    15. 更新 Selima::imacat::List::LiteralZhSelima::imacat::List::LtZhPoem 类别,加上 $self->{"COLS_BRIEF"}
    16. + +
    17. 加上 Selima::imacat::Form::LiteralZhSelima::imacat::Form::LtZhPoemSelima::imacat::Checker::LiteralZhSelima::imacat::Checker::LtZhPoemSelima::imacat::Processor::LiteralZhSelima::imacat::Processor::LtZhPoem
    18. + +
    19. 修正 Selima::wov::Form::Newslet ,移除 $coltitle$colauthor 不必要的 h_abbr()
    20. + +
    21. 修正 Selima::Form::MetaCols 类别的 _out_attrs() 方法,在检查 $$_{"name"} 是否为 charset 前先检查 $$_{"name"} 的值是否已定义。
    22. +
    + +
    + +
    + +
    +
    日期: 4.20.’06.
    + +
      +
    1. 停用 $MULTILINGUAL 变数,改用 @ALL_LINGUAS 变数判断多语与否;修正 Selima::ProcessorSelima::PageFuncSelima::DestroySelima::UserNameSelima::CheckerSelima::ListSelima::LinksSelima::DataVarsSelima::LastModfSelima::HTTPSelima::GetLangSelima::InitSelima::imacat::HTML
    2. + +
    3. literlzh 改名为 literalzh :修正资料库, literlzh 资料表改名为 literalzhliterlzh.cgi 程式改名为 literalzh.cgi 程式; Selima::imacat::List::LiterlZh 类别改名为 Selima::imacat::List::LiteralZh
    4. + +
    5. 修正女声电子报管理,移除使用 arts 阵列,改用 artcount 变数:修正 newslets.cgi ,移除 $CURRENT{"arts"} ;修正 Selima::wov::Form::Newslet 类别的 _html_col_arts() 方法,使用 $current->param("artcount") ;修正 Selima::wov::Checker::Newslet 类别的 _check_arts() 方法,移除加上 $form->param("arts") 的部份。
    6. + +
    7. 修正 Selima::A2HTML ,加上行首空白的正确处理。
    8. + +
    9. 修正 Selima::HTTP::http_500() 函式,直接使用 @callers 依所处情况处理:停用 $trace@callers 存入整个呼叫环境;剔除没意义的 /dev/nullApache::Registry ;网页显示时以 <samp>…</samp> 标示显示;邮寄通知时加上换行;错误记录时不加上换行。
    10. + +
    11. 修正 Selima::HTTP::http_400()Selima::HTTP::http_403() 函式,改用 <!-- errmsg --> ;可能的话加记录错误原因。
    12. + +
    13. 修正 Selima::HTTP::http_3??() 函式,停用 $url_r$url_h ,改统一用 h($url) 代换,反正后来还需要作 page2rel() ,没有太大的差别;将连结文字原来的网址改为有意义的文字,以符合无障碍网页规范。
    14. + +
    15. 修正 Selima::HTTP::http_405() 函式,停用 $allowd$allowed_h ,改统一用 join() 及常规表示法代换,并正确标示 <samp>…</samp>
    16. + +
    17. 修正 Selima::HTTP::http_???() 函式,将 if (defined $html) 简化为 if (!defined $html) 。现在已经没有必要特别代换了。
    18. + +
    19. 修正 Selima::PageFunc::outpage() ,原用 hcref_encode() 改用 page_encode()
    20. + +
    21. 修正 Selima::*::HTML::html_links_register() 函式,取消 E-mail 编码。
    22. + +
    23. 修正 Selima::wov::HTML::html_nl_index() 函式,全文检索程式的路径改为绝对路径。
    24. + +
    25. 修正 Selima::XHTML ,移除 set_xhtml_content_type() 函式,将 check_xhtml_content_type() 函式改名为 xhtml_content_type() ;修正 Selima::HTTPSelima::Destroy 中引用 check_xhtml_content_type() 的地方。
    26. + +
    27. 修正 Selima::HTTP ,停用不必要的 $charset 变数,直接取得档案类型及字集。
    28. + +
    29. 字集改由输出时再代换:修正 Selima::*::HTMLSelima::ListSelima::FormSelima::List::ActLog ,停用 $charset 变数,改为 <!--selima:charset--> ;修正 Selima::Destroy ,输出时 hcref_encode() 改用 page_encode() ;修正 Selima::Form::MetaCols 类别的 _out_attrs() 方法,栏位名称为 charset 时,作特殊处理。
    30. +
    + +
    + +
    + +
    +
    日期: 4.19.’06.
    + +
      +
    1. 修正 Selima::Unicode::is_charset()Selima::Mail::b64hdr_encode() ,在 eval {} 中加上 local $SIG{"__DIE__"}; ,以避免呼叫 http_500()
    2. +
    + +
    + +
    + +
    +
    日期: 4.19.’06.
    + +
      +
    1. 修正 Selima::HTTP 处理字集的方式,内部全部将字集代换成代号,以便输出时统一设定字集:修正 get_custom_status_message() ,将页面出现的字集部份代换为 <!--selima:charset--> ,以备后续代换工作;修正 Selima::Unicode::page_encode() ,加上把 <!--selima:charset--> 代换为字集名称;修正 http_???() ,将使用 to_iso88591()hcref_encode() 之处改用 page_encode() ;移除 to_iso88591()
    2. + +
    3. 解决 Big5Big5-Common 两个名字间转换的问题:修正 Selima::SetL10N ,用 Encode::Alias::define_alias()Big5 重订为 Big5-Common ;修正 Selima::*::HTMLSelima::imacat::Processor::Public::GuestbookSelima::SetL10NSelima::DestroySelima::List::ActLogSelima::FormSelima::DecFormSelima::ListSelima::HTTPSelima::UnicodeSelima::LnInfoSelima::GetLang ,移除不必要的 Big5-Common 转换程式码。
    4. + +
    5. 修正 Selima::DecForm 整理候选字集的部份,用较正确的方式剔除重复的字集,在 Big5 字集加上 Big5-ETen ,并将 Big5-HKSCS 分开处理。
    6. + +
    7. 解决每次异动翻译文字,都要重开 Apache 的问题:修正 Selima::SetL10N ,加上自动按 MO 档的修改时间,判断呼叫 reload_text() 重读 MO 档的功能;修正 Selima::Cache ,加上 %SetL10N_checked
    8. +
    + +
    + +
    + +
    +
    日期: 4.18.’06.
    + +
      +
    1. 加上 literlzhltzhpoem 两个资料表;加上 Selima::imacat::List::LiterlZhSelima::imacat::List::LtZhPoem 两个类别,及 literlzh.cgiltzhpoem.cgi 两支程式,以处理中文诗。
    2. + +
    3. 修正错误处理函式的设计:在每个程式最前方加上 local $SIG{"__DIE__"} = \&http_500; ,以在 mod_perl 每一次执行做 eval() ,都会设定区域性的错误处理函式;修正 startup.pl ,取消没有用处的 local $SIG{"__DIE__"} = \&http_500;
    4. + +
    5. 修正 Selima::HTTP ,用 caller() 显示每一层呼叫的位置,以利侦错。
    6. +
    + +
    + +
    + +
    +
    日期: 4.13.’06.
    + +
      +
    1. 修正 Selima::PageFunc 模组的 rebuildtype_options() 函式,改用 Devel::Symdump 取得重制网页的函式清单,并改用 map()grep()sort() 函式简化一次处理。
    2. + +
    3. 修正 Selima::XHTML 模组,加上 check_xhtml_content_type() 函式,以替代 set_xhtml_content_type() 函式,由使用者的浏览器资料,判断应送出的 MIME 格式;停用 set_xhtml_content_type() 函式;修正 Selima::Destroy 模组,改用 check_xhtml_content_type() 函式,并依纯文字或 HTML 做出较细致的输出前后置处理;修正 Selima::HTTP 模组,改用 check_xhtml_content_type() 函式。
    4. +
    + +
    + +
    + +
    +
    日期: 4.13.’06.
    + +
      +
    1. 修正 Selima::List 模组,加上 html_title() 方法以备用。
    2. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 4 | + 5 | + 6 | + 7 | + 8 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0006.html.zh-tw.html b/htdocs/imacat/me/changelog/0006.html.zh-tw.html new file mode 120000 index 0000000..6afacba --- /dev/null +++ b/htdocs/imacat/me/changelog/0006.html.zh-tw.html @@ -0,0 +1 @@ +0006.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0006.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0006.html.zh-tw.xhtml new file mode 100644 index 0000000..103ff5f --- /dev/null +++ b/htdocs/imacat/me/changelog/0006.html.zh-tw.xhtml @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷六 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷六

    + +
    + +
    + +
    +
    日期: 4.21.’06.
    + +
      +
    1. 修正 Selima::FormFunc 模組,移除不用的 select_url()select_text() 函式,及不用的引用 URI::EscapeSelima::HTTPSSelima::RelURISelima::ShortCutSelima::DataVars:requri
    2. + +
    3. 修正 Selima::wov::HTML::html_title() 函式,移除不必要的 alt=title= 文字代換。
    4. + +
    5. 修正 logout.cgi ,將 login.php 改正為 login.cgi (雖然現在其實還沒有 login.cgi 就是了。)
    6. + +
    7. 修正 Selima::HTTP::http_400() 函式,當傳入值 0 時,當成網址格式錯亂,改依 Apache 記錄的格式記錄。
    8. + +
    9. 因為現在輸出最後都會使用 page2rel() 轉換,所以不需要在輸出中途用 reluri() 了:修正 Selima::*::HTMLSelima::*::List::Searchlogout.cgiSelima::ListSelima::FormSelima::Form::LinkCatSelima::List::Public::GuestbookSelima::AltLangSelima::Picture ,移除使用 reluri() 的地方,及對 Selima::RelURI 的引用。
    10. + +
    11. 修正 Selima::Page2Rel::Converter 類別的 cnvtattr() 方法中,引用 absuri() 未加括弧的地方,加上括弧。
    12. + +
    13. 修正 Selima::HTTP 模組,加上 http_410()http_503() 兩個函式,調整統一記錄訊息。
    14. + +
    15. 更新 Selima::imacat::List::LiteralZhSelima::imacat::List::LtZhPoem 類別,加上 $self->{"COLS_BRIEF"}
    16. + +
    17. 加上 Selima::imacat::Form::LiteralZhSelima::imacat::Form::LtZhPoemSelima::imacat::Checker::LiteralZhSelima::imacat::Checker::LtZhPoemSelima::imacat::Processor::LiteralZhSelima::imacat::Processor::LtZhPoem
    18. + +
    19. 修正 Selima::wov::Form::Newslet ,移除 $coltitle$colauthor 不必要的 h_abbr()
    20. + +
    21. 修正 Selima::Form::MetaCols 類別的 _out_attrs() 方法,在檢查 $$_{"name"} 是否為 charset 前先檢查 $$_{"name"} 的值是否已定義。
    22. +
    + +
    + +
    + +
    +
    日期: 4.20.’06.
    + +
      +
    1. 停用 $MULTILINGUAL 變數,改用 @ALL_LINGUAS 變數判斷多語與否;修正 Selima::ProcessorSelima::PageFuncSelima::DestroySelima::UserNameSelima::CheckerSelima::ListSelima::LinksSelima::DataVarsSelima::LastModfSelima::HTTPSelima::GetLangSelima::InitSelima::imacat::HTML
    2. + +
    3. literlzh 改名為 literalzh :修正資料庫, literlzh 資料表改名為 literalzhliterlzh.cgi 程式改名為 literalzh.cgi 程式; Selima::imacat::List::LiterlZh 類別改名為 Selima::imacat::List::LiteralZh
    4. + +
    5. 修正女聲電子報管理,移除使用 arts 陣列,改用 artcount 變數:修正 newslets.cgi ,移除 $CURRENT{"arts"} ;修正 Selima::wov::Form::Newslet 類別的 _html_col_arts() 方法,使用 $current->param("artcount") ;修正 Selima::wov::Checker::Newslet 類別的 _check_arts() 方法,移除加上 $form->param("arts") 的部份。
    6. + +
    7. 修正 Selima::A2HTML ,加上行首空白的正確處理。
    8. + +
    9. 修正 Selima::HTTP::http_500() 函式,直接使用 @callers 依所處情況處理:停用 $trace@callers 存入整個呼叫環境;剔除沒意義的 /dev/nullApache::Registry ;網頁顯示時以 <samp>…</samp> 標示顯示;郵寄通知時加上換行;錯誤記錄時不加上換行。
    10. + +
    11. 修正 Selima::HTTP::http_400()Selima::HTTP::http_403() 函式,改用 <!-- errmsg --> ;可能的話加記錄錯誤原因。
    12. + +
    13. 修正 Selima::HTTP::http_3??() 函式,停用 $url_r$url_h ,改統一用 h($url) 代換,反正後來還需要作 page2rel() ,沒有太大的差別;將連結文字原來的網址改為有意義的文字,以符合無障礙網頁規範。
    14. + +
    15. 修正 Selima::HTTP::http_405() 函式,停用 $allowd$allowed_h ,改統一用 join() 及常規表示法代換,並正確標示 <samp>…</samp>
    16. + +
    17. 修正 Selima::HTTP::http_???() 函式,將 if (defined $html) 簡化為 if (!defined $html) 。現在已經沒有必要特別代換了。
    18. + +
    19. 修正 Selima::PageFunc::outpage() ,原用 hcref_encode() 改用 page_encode()
    20. + +
    21. 修正 Selima::*::HTML::html_links_register() 函式,取消 E-mail 編碼。
    22. + +
    23. 修正 Selima::wov::HTML::html_nl_index() 函式,全文檢索程式的路徑改為絕對路徑。
    24. + +
    25. 修正 Selima::XHTML ,移除 set_xhtml_content_type() 函式,將 check_xhtml_content_type() 函式改名為 xhtml_content_type() ;修正 Selima::HTTPSelima::Destroy 中引用 check_xhtml_content_type() 的地方。
    26. + +
    27. 修正 Selima::HTTP ,停用不必要的 $charset 變數,直接取得檔案類型及字集。
    28. + +
    29. 字集改由輸出時再代換:修正 Selima::*::HTMLSelima::ListSelima::FormSelima::List::ActLog ,停用 $charset 變數,改為 <!--selima:charset--> ;修正 Selima::Destroy ,輸出時 hcref_encode() 改用 page_encode() ;修正 Selima::Form::MetaCols 類別的 _out_attrs() 方法,欄位名稱為 charset 時,作特殊處理。
    30. +
    + +
    + +
    + +
    +
    日期: 4.19.’06.
    + +
      +
    1. 修正 Selima::Unicode::is_charset()Selima::Mail::b64hdr_encode() ,在 eval {} 中加上 local $SIG{"__DIE__"}; ,以避免呼叫 http_500()
    2. +
    + +
    + +
    + +
    +
    日期: 4.19.’06.
    + +
      +
    1. 修正 Selima::HTTP 處理字集的方式,內部全部將字集代換成代號,以便輸出時統一設定字集:修正 get_custom_status_message() ,將頁面出現的字集部份代換為 <!--selima:charset--> ,以備後續代換工作;修正 Selima::Unicode::page_encode() ,加上把 <!--selima:charset--> 代換為字集名稱;修正 http_???() ,將使用 to_iso88591()hcref_encode() 之處改用 page_encode() ;移除 to_iso88591()
    2. + +
    3. 解決 Big5Big5-Common 兩個名字間轉換的問題:修正 Selima::SetL10N ,用 Encode::Alias::define_alias()Big5 重訂為 Big5-Common ;修正 Selima::*::HTMLSelima::imacat::Processor::Public::GuestbookSelima::SetL10NSelima::DestroySelima::List::ActLogSelima::FormSelima::DecFormSelima::ListSelima::HTTPSelima::UnicodeSelima::LnInfoSelima::GetLang ,移除不必要的 Big5-Common 轉換程式碼。
    4. + +
    5. 修正 Selima::DecForm 整理候選字集的部份,用較正確的方式剔除重複的字集,在 Big5 字集加上 Big5-ETen ,並將 Big5-HKSCS 分開處理。
    6. + +
    7. 解決每次異動翻譯文字,都要重開 Apache 的問題:修正 Selima::SetL10N ,加上自動按 MO 檔的修改時間,判斷呼叫 reload_text() 重讀 MO 檔的功能;修正 Selima::Cache ,加上 %SetL10N_checked
    8. +
    + +
    + +
    + +
    +
    日期: 4.18.’06.
    + +
      +
    1. 加上 literlzhltzhpoem 兩個資料表;加上 Selima::imacat::List::LiterlZhSelima::imacat::List::LtZhPoem 兩個類別,及 literlzh.cgiltzhpoem.cgi 兩支程式,以處理中文詩。
    2. + +
    3. 修正錯誤處理函式的設計:在每個程式最前方加上 local $SIG{"__DIE__"} = \&http_500; ,以在 mod_perl 每一次執行做 eval() ,都會設定區域性的錯誤處理函式;修正 startup.pl ,取消沒有用處的 local $SIG{"__DIE__"} = \&http_500;
    4. + +
    5. 修正 Selima::HTTP ,用 caller() 顯示每一層呼叫的位置,以利偵錯。
    6. +
    + +
    + +
    + +
    +
    日期: 4.13.’06.
    + +
      +
    1. 修正 Selima::PageFunc 模組的 rebuildtype_options() 函式,改用 Devel::Symdump 取得重製網頁的函式清單,並改用 map()grep()sort() 函式簡化一次處理。
    2. + +
    3. 修正 Selima::XHTML 模組,加上 check_xhtml_content_type() 函式,以替代 set_xhtml_content_type() 函式,由使用者的瀏覽器資料,判斷應送出的 MIME 格式;停用 set_xhtml_content_type() 函式;修正 Selima::Destroy 模組,改用 check_xhtml_content_type() 函式,並依純文字或 HTML 做出較細緻的輸出前後置處理;修正 Selima::HTTP 模組,改用 check_xhtml_content_type() 函式。
    4. +
    + +
    + +
    + +
    +
    日期: 4.13.’06.
    + +
      +
    1. 修正 Selima::List 模組,加上 html_title() 方法以備用。
    2. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 4 | + 5 | + 6 | + 7 | + 8 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0007.html.en.html b/htdocs/imacat/me/changelog/0007.html.en.html new file mode 120000 index 0000000..268f15d --- /dev/null +++ b/htdocs/imacat/me/changelog/0007.html.en.html @@ -0,0 +1 @@ +0007.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0007.html.en.xhtml b/htdocs/imacat/me/changelog/0007.html.en.xhtml new file mode 100644 index 0000000..3ceabe4 --- /dev/null +++ b/htdocs/imacat/me/changelog/0007.html.en.xhtml @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 7 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 7

    + +
    + +
    + +
    +
    Date: 4.25.’06.
    + +
      +
    1. 修正 Selima::wov::HTML 模組的 html_newslet()html_nl_index() 函式,將 id="credit"id="index" 分別改為 class="credit"class="index"
    2. + +
    3. 修正 Selima::wov::HTML 模組的 html_nl_index() 函式, @$newslets == 0 時加上 return 直接回傳;製作目錄時, $textno 加上 h()$date 改用 myfmtdate() 並加上 h()$arts 改用 map() 簡潔處理,並改用 <ul>…</ul>
    4. + +
    5. 修正 Selima::wov::Rebuild 模組的 rebuild_newslets() 函式,移除建立目錄時錯誤的設定 no_auto_title ,移除引用 newsletters.css ,加上 class => "newsletters" 。所有 newsletters.css 的設定移至 common.css 。移除 newsletters.css
    6. + +
    7. 修正 Selima::imacat::HTML::html_ltzh_body() 函式,取得預覽詩時, my $i 改用 $_
    8. + +
    9. 修正 Selima::imacat::Form::LiteralZh 類別的 _html_col_poems() 方法,宣告 $label*$mark* 變數時,作適當換行。
    10. + +
    11. 女聲電子報,加上隱藏單篇文章的功能:修正 nlarts 資料表,加上 hid 欄位;修正 newslets.cgi 程式、 search_list 檢視、 Selima::wov::Form::NLArt 類別、 Selima::wov::Form::Newslet 類別、 Selima::wov::Processor::NLArt 類別、 Selima::wov::Processor::Newslet 類別、 Selima::wov::Rebuild 模組、 Selima::wov::HTML 模組,加上隱藏單篇文章功能的相關修正。
    12. + +
    13. 女聲電子報,網頁版的引號改用 <q>…</q>
    14. + +
    15. 女聲電子報加上預覽的功能:修正 newslets.cgiSelima::wov::Rebuild::compose_page()Selima::wov::HTML::html_newslet() ,將電子報網頁組建的程式碼加進 compose_page() ,並修正 html_newslets() 以配合預覽。
    16. +
    + +
    + +
    + +
    +
    Date: 4.24.’06.
    + +
      +
    1. 修正 Selima::MnglMail ,移除不用的 mangle_email_hcref() 函式,修正 mangle_email_at()unmangle_email_at()mangle_email_span() ,移除不必要的編碼,及符號前的斜線。現在信箱輸出前會再編碼,不需要重複做。
    2. + +
    3. 修正 literalzh.cgicheck_post() 函式,移除檢查 zhsync 的重導向。這不是多語的資料表,不需要中文繁簡轉換的功能。
    4. + +
    5. 修正 Selima::imacat::Checker::LiteralZh 的註解,程式說明中,中文詩應為中文寫作
    6. + +
    7. 加上 Selima::imacat::Form::LiteralZhSelima::imacat::Checker::LiteralZhSelima::imacat::Processor::LiteralZh ,處理英文寫作。
    8. + +
    9. 修正 Selima::imacat::Processor::ChangeLogSelima::imacat::Processor::DiarySelima::imacat::Processor::LiteralEnSelima::imacat::Processor::LtZhPoemSelima::imacat::Processor::LiteralZhSelima::wov::Processor::NLArtSelima::wov::Processor::Newslet ,刪除已不再需要的引用符號集 :scptconf 。各別網站下的程式,其實可以直接引用自己的重製網頁模組及函式,不需要再使用 $MAIN 來尋找重製網頁函式。
    10. +
    + +
    + +
    + +
    +
    Date: 4.24.’06.
    + +
      +
    1. 更新 Selima::imacat::Processor::LtZhPoem 類別,加上 _rebuild_partial_pages() 方法。
    2. +
    + +
    + +
    + +
    +
    Date: 4.23.’06.
    + +
      +
    1. 更新 newslets.cgiliteralzh.cgiSelima::AddColSelima::wov::Checker::NewsletSelima::imacat::Checker::LiteralZhSelima::imacat::Processor::LiteralZhSelima::AddCol ,日期輸入操作原用 EPOCH 秒數,改用 ISO 標準日期格式。
    2. + +
    3. 加上 Selima::wov::Items::newslet_no() 函式;更新 Selima::wov::Processor::NLArts ,記錄加上電子報期數。
    4. + +
    5. 修正 Selima::imacat::HTML 模組, html_literalzh() 函式改名為 html_ltzh_body()html_literalzh_index() 函式改名為 html_ltzh_index() ,縮短名稱;修正 Selima::imacat::Rebuild 引用的地方。
    6. + +
    7. 修正 Selima::Processor::LinkCat 類別,直接引用 linkcat 資料表的地方,改用 $DBH->quote_identifier($self->{"table"})
    8. + +
    9. 修正 Selima::imacat::Checker::LiteralZh::_check_poems()Selima::wov::Checker::Newslet::_check_arts() ,加上 _trim()_trimtext() 。在子檢查類別中無法做這兩件事。不處理的話,文字區塊會傳回 \r 字元。
    10. + +
    11. 修正 Selima::*::Processor::* 類別的 _rebuild_partial_pages() 方法,直接呼叫 rebuild_*() 函式重製網頁,停用 $MAIL->can("rebuild_*") 找出重製網頁的函式。各網站自己知道自己的重製網頁程式。
    12. + +
    13. 將網頁使用單引號的地方,改為右單引號 &rsquo; 。
    14. + +
    15. 修正 Selima::*::List::Search 類別,加上 actlog() 記錄網站檢索。
    16. + +
    17. 全文檢索加上中文詩。
    18. + +
    19. 更新 search_list ,日期改採 ISO 標準格式,將雜類欄位合併簡化為 kw ;修正 Selima::emily::List::Search 註解的程式說明,網站名稱錯誤更正;修正 Selima::imacat::List::Search 類別的 html_list() 方法,新加 ltzhpoem 類, literalzh 類標題改由顯示時再處理;修正 Selima::wov::List::Search::fetch() 類別的 fetch() 方法,呼叫母方法時名稱原誤為 SUPER::FETCH() ,更正為 SUPER::fetch()
    20. + +
    21. 加上 literalen 資料表。
    22. + +
    23. 比對同步梅姬首頁和 Selima:*::HTML@ADMIN_SCRIPTS 選單; Selima:wov::HTML@ADMIN_SCRIPTS 加上電子報管理的連結(目前權限系統還沒有辦法處理)。
    24. +
    + +
    + +
    + +
    +
    Date: 4.22.’06.
    + +
      +
    1. 修正 Selima::List::Public::Guestbook 類別的 html_list() 方法,移除不正確的 <var>…</var> 標示,網址和信箱加上 <samp>…</samp> 標示;網址格式不正確時,原先顯示 $$current{"location"} ,修正為顯示 $$current{"url"} ;時間視語言加上 xml:lang="en" 標示;修正時間的字型為 Times New Roman ;修正留言簽名的字型,繁體為華康瘦金體(P),簡體為仿宋_GB2312,英文為 Viner Hand ITC ,並去除斜體;修正信箱顯示的方式,將連結圖檔移到後方。
    2. + +
    3. 修正 Selima::imacat::List::Public::Garbage 類別的 html_list() 方法, id="entries" 修正為 class="entries" ;留言資料其實只有時間,故簡化留言資料的標示為一行,並視語言加上 xml:lang="en" 標示;移除不必要的信箱表格節尾條件碼;修正留言資料的字型為 Times New Roman
    4. + +
    5. 修正 Selima::A2HTML ,網址加以 <samp>…</samp> 標示,移除連結時不必要的 mangle_email_hcref() ,連結文字部份改用 mangle_email_span() ,文字部份以 h_abbr() 標示縮寫。
    6. + +
    7. 修正 Selima::MarkAbbr ,網站擴充設定移到最後,以避免如 CPAN 遞迴標示的問題。
    8. + +
    9. 加上 Selima::imacat::Items 模組,加上 markabbr_site() 縮寫標示網站擴充函式,並加上三個縮寫標示: CPANPEARSARS
    10. + +
    11. Selima::wov::Newslets 模組改名為 Selima::wov::Items ;修正 Selima::wovSelima::wov::Checker::NewsletSelima::wov::Form::NewsletSelima::wov::Rebuild 引用的地方;修正 Selima::wov::Form::NLArt ,加上引用 Selima::wov::Items
    12. + +
    13. 修正 Selima::wov::Items 模組,改用 use utf8; ,減少不必要的 decode() ;修正 newslet_textno() 函式,直接傳回,不再作 decode() 。修正 newslet_title() 函式,期數原直接以 || 運算子,改以 $DBH->strcat() 處理;移除不用的變數 $row$col 變數改用 $_ 並移除;移除 decode()encode()UTF-8 絕不會有問題,故移除 FB_CROAK
    14. + +
    15. 修正 Selima::Format 模組,使用 use utf8; ;修正 myfmtdate()myfmttime() 兩個函式,原來年份用的單引號,改用右單引號( &rsquo; )。
    16. + +
    17. 修正 Selima::ReqURI::init_request_uri() 函式, $REQUEST_URI 取的參數,改取未移除 langcharset 前的原始參數;修正 Selima::Init::initenv() 函式,阻擋機器人碼的部份原先以 $REQUEST_PATH$ENV{"QUERY_STRING"} ,改以 $REQUEST_URI 判斷;修正 Selima::HTTP ,作 page2rel() 時原用 $REQUEST_URI ,改用 $REQUEST_PATH ;記錄時原用 $0 ,改用 $REQUEST_URI
    18. + +
    19. 修正 Selima::imacat::Items 模組,加上 literalzh_title() 函式;修正 ltzhpoem.cgi 程式,加上 import_selset() 函式;修正 Selima::imacat::Checker::LtZhPoem 類別的 _check_set() ,檢查的資料表由 newslets 改正為 ltzhpoem ;修正 Selima::imacat::Checker::LtZhPoem ,加上引用 Selima::imacat::Items
    20. + +
    21. 修正 Selima::wov::Check::NLArts 類別 _check_newslet() 方法的註解, groups 應為 newsletters
    22. + +
    23. 修正 Selima::Form::* 類別,加上對於刪除表格的判斷。並不是所有的表格都只有三種類型,而且變異的情形其實非常普遍。
    24. + +
    25. 修正 Selima::Form::* 類別,把三種表格判斷式的註解文字統一。
    26. + +
    27. 修正 Selima::*::Rebuild 模組,原來 next if !defined $html 改為 goutpage() if defined $html
    28. + +
    29. 修正 Selima::PageFunc::page_all_linguas() 函式,讓網頁可以強制設定所有語言。
    30. + +
    31. 修正 Selima::Unicode 模組,加上漏掉的 all_to_trad()all_to_simp() 的原型宣告。
    32. + +
    33. 修正 Selima::imacat::Rebuild::compose_page() 函式的註解,原為 We need a copy, a reference to the same things ,應為 We need a copy, not a reference to the same thing
    34. + +
    35. 修正 seach.cgiguestbook.cgi ,將關鍵字統一設為多語格式;修正 Selima::Init::initenv() 函式,對關鍵字不論是否為多語網站,一律作多語處理。
    36. + +
    37. 修正 Selima::*::List::SearchSelima::*::RebuildSelima::*::HTMLsearch.cgiguestbook.cgi ,移除不需要的 use encoding(Big5)
    38. + +
    39. use encoding(Big5) 全部改作 use utf8 :修正 guestbook.cgiSelima::*::ConfigSelima::*::Processor::GuestbookSelima::imacat::Processor::GarbageSelima::imacat::HTMLSelima::wov::HTMLSelima::wov::RebuildSelima::wov::List::SearchSelima::wov::Form::Public::Guestbook
    40. + +
    41. 加上 Selima::imacat::Rebuild::rebuild_literalzh()Selima::imacat::HTML::html_literalzh()Selima::imacat::HTML::html_literalzh_index() 函式,製作中文詩的網頁。
    42. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 5 | + 6 | + 7 | + 8 | + 9 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0007.html.zh-cn.html b/htdocs/imacat/me/changelog/0007.html.zh-cn.html new file mode 120000 index 0000000..abb7df8 --- /dev/null +++ b/htdocs/imacat/me/changelog/0007.html.zh-cn.html @@ -0,0 +1 @@ +0007.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0007.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0007.html.zh-cn.xhtml new file mode 100644 index 0000000..1923832 --- /dev/null +++ b/htdocs/imacat/me/changelog/0007.html.zh-cn.xhtml @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷七 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷七

    + +
    + +
    + +
    +
    日期: 4.25.’06.
    + +
      +
    1. 修正 Selima::wov::HTML 模组的 html_newslet()html_nl_index() 函式,将 id="credit"id="index" 分别改为 class="credit"class="index"
    2. + +
    3. 修正 Selima::wov::HTML 模组的 html_nl_index() 函式, @$newslets == 0 时加上 return 直接回传;制作目录时, $textno 加上 h()$date 改用 myfmtdate() 并加上 h()$arts 改用 map() 简洁处理,并改用 <ul>…</ul>
    4. + +
    5. 修正 Selima::wov::Rebuild 模组的 rebuild_newslets() 函式,移除建立目录时错误的设定 no_auto_title ,移除引用 newsletters.css ,加上 class => "newsletters" 。所有 newsletters.css 的设定移至 common.css 。移除 newsletters.css
    6. + +
    7. 修正 Selima::imacat::HTML::html_ltzh_body() 函式,取得预览诗时, my $i 改用 $_
    8. + +
    9. 修正 Selima::imacat::Form::LiteralZh 类别的 _html_col_poems() 方法,宣告 $label*$mark* 变数时,作适当换行。
    10. + +
    11. 女声电子报,加上隐藏单篇文章的功能:修正 nlarts 资料表,加上 hid 栏位;修正 newslets.cgi 程式、 search_list 检视、 Selima::wov::Form::NLArt 类别、 Selima::wov::Form::Newslet 类别、 Selima::wov::Processor::NLArt 类别、 Selima::wov::Processor::Newslet 类别、 Selima::wov::Rebuild 模组、 Selima::wov::HTML 模组,加上隐藏单篇文章功能的相关修正。
    12. + +
    13. 女声电子报,网页版的引号改用 <q>…</q>
    14. + +
    15. 女声电子报加上预览的功能:修正 newslets.cgiSelima::wov::Rebuild::compose_page()Selima::wov::HTML::html_newslet() ,将电子报网页组建的程式码加进 compose_page() ,并修正 html_newslets() 以配合预览。
    16. +
    + +
    + +
    + +
    +
    日期: 4.24.’06.
    + +
      +
    1. 修正 Selima::MnglMail ,移除不用的 mangle_email_hcref() 函式,修正 mangle_email_at()unmangle_email_at()mangle_email_span() ,移除不必要的编码,及符号前的斜线。现在信箱输出前会再编码,不需要重复做。
    2. + +
    3. 修正 literalzh.cgicheck_post() 函式,移除检查 zhsync 的重导向。这不是多语的资料表,不需要中文繁简转换的功能。
    4. + +
    5. 修正 Selima::imacat::Checker::LiteralZh 的注解,程式说明中,中文诗应为中文写作
    6. + +
    7. 加上 Selima::imacat::Form::LiteralZhSelima::imacat::Checker::LiteralZhSelima::imacat::Processor::LiteralZh ,处理英文写作。
    8. + +
    9. 修正 Selima::imacat::Processor::ChangeLogSelima::imacat::Processor::DiarySelima::imacat::Processor::LiteralEnSelima::imacat::Processor::LtZhPoemSelima::imacat::Processor::LiteralZhSelima::wov::Processor::NLArtSelima::wov::Processor::Newslet ,删除已不再需要的引用符号集 :scptconf 。各别网站下的程式,其实可以直接引用自己的重制网页模组及函式,不需要再使用 $MAIN 来寻找重制网页函式。
    10. +
    + +
    + +
    + +
    +
    日期: 4.24.’06.
    + +
      +
    1. 更新 Selima::imacat::Processor::LtZhPoem 类别,加上 _rebuild_partial_pages() 方法。
    2. +
    + +
    + +
    + +
    +
    日期: 4.23.’06.
    + +
      +
    1. 更新 newslets.cgiliteralzh.cgiSelima::AddColSelima::wov::Checker::NewsletSelima::imacat::Checker::LiteralZhSelima::imacat::Processor::LiteralZhSelima::AddCol ,日期输入操作原用 EPOCH 秒数,改用 ISO 标准日期格式。
    2. + +
    3. 加上 Selima::wov::Items::newslet_no() 函式;更新 Selima::wov::Processor::NLArts ,记录加上电子报期数。
    4. + +
    5. 修正 Selima::imacat::HTML 模组, html_literalzh() 函式改名为 html_ltzh_body()html_literalzh_index() 函式改名为 html_ltzh_index() ,缩短名称;修正 Selima::imacat::Rebuild 引用的地方。
    6. + +
    7. 修正 Selima::Processor::LinkCat 类别,直接引用 linkcat 资料表的地方,改用 $DBH->quote_identifier($self->{"table"})
    8. + +
    9. 修正 Selima::imacat::Checker::LiteralZh::_check_poems()Selima::wov::Checker::Newslet::_check_arts() ,加上 _trim()_trimtext() 。在子检查类别中无法做这两件事。不处理的话,文字区块会传回 \r 字元。
    10. + +
    11. 修正 Selima::*::Processor::* 类别的 _rebuild_partial_pages() 方法,直接呼叫 rebuild_*() 函式重制网页,停用 $MAIL->can("rebuild_*") 找出重制网页的函式。各网站自己知道自己的重制网页程式。
    12. + +
    13. 将网页使用单引号的地方,改为右单引号 &rsquo; 。
    14. + +
    15. 修正 Selima::*::List::Search 类别,加上 actlog() 记录网站检索。
    16. + +
    17. 全文检索加上中文诗。
    18. + +
    19. 更新 search_list ,日期改采 ISO 标准格式,将杂类栏位合并简化为 kw ;修正 Selima::emily::List::Search 注解的程式说明,网站名称错误更正;修正 Selima::imacat::List::Search 类别的 html_list() 方法,新加 ltzhpoem 类, literalzh 类标题改由显示时再处理;修正 Selima::wov::List::Search::fetch() 类别的 fetch() 方法,呼叫母方法时名称原误为 SUPER::FETCH() ,更正为 SUPER::fetch()
    20. + +
    21. 加上 literalen 资料表。
    22. + +
    23. 比对同步梅姬首页和 Selima:*::HTML@ADMIN_SCRIPTS 选单; Selima:wov::HTML@ADMIN_SCRIPTS 加上电子报管理的连结(目前权限系统还没有办法处理)。
    24. +
    + +
    + +
    + +
    +
    日期: 4.22.’06.
    + +
      +
    1. 修正 Selima::List::Public::Guestbook 类别的 html_list() 方法,移除不正确的 <var>…</var> 标示,网址和信箱加上 <samp>…</samp> 标示;网址格式不正确时,原先显示 $$current{"location"} ,修正为显示 $$current{"url"} ;时间视语言加上 xml:lang="en" 标示;修正时间的字型为 Times New Roman ;修正留言签名的字型,繁体为华康瘦金体(P),简体为仿宋_GB2312,英文为 Viner Hand ITC ,并去除斜体;修正信箱显示的方式,将连结图档移到后方。
    2. + +
    3. 修正 Selima::imacat::List::Public::Garbage 类别的 html_list() 方法, id="entries" 修正为 class="entries" ;留言资料其实只有时间,故简化留言资料的标示为一行,并视语言加上 xml:lang="en" 标示;移除不必要的信箱表格节尾条件码;修正留言资料的字型为 Times New Roman
    4. + +
    5. 修正 Selima::A2HTML ,网址加以 <samp>…</samp> 标示,移除连结时不必要的 mangle_email_hcref() ,连结文字部份改用 mangle_email_span() ,文字部份以 h_abbr() 标示缩写。
    6. + +
    7. 修正 Selima::MarkAbbr ,网站扩充设定移到最后,以避免如 CPAN 递回标示的问题。
    8. + +
    9. 加上 Selima::imacat::Items 模组,加上 markabbr_site() 缩写标示网站扩充函式,并加上三个缩写标示: CPANPEARSARS
    10. + +
    11. Selima::wov::Newslets 模组改名为 Selima::wov::Items ;修正 Selima::wovSelima::wov::Checker::NewsletSelima::wov::Form::NewsletSelima::wov::Rebuild 引用的地方;修正 Selima::wov::Form::NLArt ,加上引用 Selima::wov::Items
    12. + +
    13. 修正 Selima::wov::Items 模组,改用 use utf8; ,减少不必要的 decode() ;修正 newslet_textno() 函式,直接传回,不再作 decode() 。修正 newslet_title() 函式,期数原直接以 || 运算子,改以 $DBH->strcat() 处理;移除不用的变数 $row$col 变数改用 $_ 并移除;移除 decode()encode()UTF-8 绝不会有问题,故移除 FB_CROAK
    14. + +
    15. 修正 Selima::Format 模组,使用 use utf8; ;修正 myfmtdate()myfmttime() 两个函式,原来年份用的单引号,改用右单引号( &rsquo; )。
    16. + +
    17. 修正 Selima::ReqURI::init_request_uri() 函式, $REQUEST_URI 取的参数,改取未移除 langcharset 前的原始参数;修正 Selima::Init::initenv() 函式,阻挡机器人码的部份原先以 $REQUEST_PATH$ENV{"QUERY_STRING"} ,改以 $REQUEST_URI 判断;修正 Selima::HTTP ,作 page2rel() 时原用 $REQUEST_URI ,改用 $REQUEST_PATH ;记录时原用 $0 ,改用 $REQUEST_URI
    18. + +
    19. 修正 Selima::imacat::Items 模组,加上 literalzh_title() 函式;修正 ltzhpoem.cgi 程式,加上 import_selset() 函式;修正 Selima::imacat::Checker::LtZhPoem 类别的 _check_set() ,检查的资料表由 newslets 改正为 ltzhpoem ;修正 Selima::imacat::Checker::LtZhPoem ,加上引用 Selima::imacat::Items
    20. + +
    21. 修正 Selima::wov::Check::NLArts 类别 _check_newslet() 方法的注解, groups 应为 newsletters
    22. + +
    23. 修正 Selima::Form::* 类别,加上对於删除表格的判断。并不是所有的表格都只有三种类型,而且变异的情形其实非常普遍。
    24. + +
    25. 修正 Selima::Form::* 类别,把三种表格判断式的注解文字统一。
    26. + +
    27. 修正 Selima::*::Rebuild 模组,原来 next if !defined $html 改为 goutpage() if defined $html
    28. + +
    29. 修正 Selima::PageFunc::page_all_linguas() 函式,让网页可以强制设定所有语言。
    30. + +
    31. 修正 Selima::Unicode 模组,加上漏掉的 all_to_trad()all_to_simp() 的原型宣告。
    32. + +
    33. 修正 Selima::imacat::Rebuild::compose_page() 函式的注解,原为 We need a copy, a reference to the same things ,应为 We need a copy, not a reference to the same thing
    34. + +
    35. 修正 seach.cgiguestbook.cgi ,将关键字统一设为多语格式;修正 Selima::Init::initenv() 函式,对关键字不论是否为多语网站,一律作多语处理。
    36. + +
    37. 修正 Selima::*::List::SearchSelima::*::RebuildSelima::*::HTMLsearch.cgiguestbook.cgi ,移除不需要的 use encoding(Big5)
    38. + +
    39. use encoding(Big5) 全部改作 use utf8 :修正 guestbook.cgiSelima::*::ConfigSelima::*::Processor::GuestbookSelima::imacat::Processor::GarbageSelima::imacat::HTMLSelima::wov::HTMLSelima::wov::RebuildSelima::wov::List::SearchSelima::wov::Form::Public::Guestbook
    40. + +
    41. 加上 Selima::imacat::Rebuild::rebuild_literalzh()Selima::imacat::HTML::html_literalzh()Selima::imacat::HTML::html_literalzh_index() 函式,制作中文诗的网页。
    42. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 5 | + 6 | + 7 | + 8 | + 9 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0007.html.zh-tw.html b/htdocs/imacat/me/changelog/0007.html.zh-tw.html new file mode 120000 index 0000000..bfcc7b0 --- /dev/null +++ b/htdocs/imacat/me/changelog/0007.html.zh-tw.html @@ -0,0 +1 @@ +0007.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0007.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0007.html.zh-tw.xhtml new file mode 100644 index 0000000..91d92ad --- /dev/null +++ b/htdocs/imacat/me/changelog/0007.html.zh-tw.xhtml @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷七 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷七

    + +
    + +
    + +
    +
    日期: 4.25.’06.
    + +
      +
    1. 修正 Selima::wov::HTML 模組的 html_newslet()html_nl_index() 函式,將 id="credit"id="index" 分別改為 class="credit"class="index"
    2. + +
    3. 修正 Selima::wov::HTML 模組的 html_nl_index() 函式, @$newslets == 0 時加上 return 直接回傳;製作目錄時, $textno 加上 h()$date 改用 myfmtdate() 並加上 h()$arts 改用 map() 簡潔處理,並改用 <ul>…</ul>
    4. + +
    5. 修正 Selima::wov::Rebuild 模組的 rebuild_newslets() 函式,移除建立目錄時錯誤的設定 no_auto_title ,移除引用 newsletters.css ,加上 class => "newsletters" 。所有 newsletters.css 的設定移至 common.css 。移除 newsletters.css
    6. + +
    7. 修正 Selima::imacat::HTML::html_ltzh_body() 函式,取得預覽詩時, my $i 改用 $_
    8. + +
    9. 修正 Selima::imacat::Form::LiteralZh 類別的 _html_col_poems() 方法,宣告 $label*$mark* 變數時,作適當換行。
    10. + +
    11. 女聲電子報,加上隱藏單篇文章的功能:修正 nlarts 資料表,加上 hid 欄位;修正 newslets.cgi 程式、 search_list 檢視、 Selima::wov::Form::NLArt 類別、 Selima::wov::Form::Newslet 類別、 Selima::wov::Processor::NLArt 類別、 Selima::wov::Processor::Newslet 類別、 Selima::wov::Rebuild 模組、 Selima::wov::HTML 模組,加上隱藏單篇文章功能的相關修正。
    12. + +
    13. 女聲電子報,網頁版的引號改用 <q>…</q>
    14. + +
    15. 女聲電子報加上預覽的功能:修正 newslets.cgiSelima::wov::Rebuild::compose_page()Selima::wov::HTML::html_newslet() ,將電子報網頁組建的程式碼加進 compose_page() ,並修正 html_newslets() 以配合預覽。
    16. +
    + +
    + +
    + +
    +
    日期: 4.24.’06.
    + +
      +
    1. 修正 Selima::MnglMail ,移除不用的 mangle_email_hcref() 函式,修正 mangle_email_at()unmangle_email_at()mangle_email_span() ,移除不必要的編碼,及符號前的斜線。現在信箱輸出前會再編碼,不需要重複做。
    2. + +
    3. 修正 literalzh.cgicheck_post() 函式,移除檢查 zhsync 的重導向。這不是多語的資料表,不需要中文繁簡轉換的功能。
    4. + +
    5. 修正 Selima::imacat::Checker::LiteralZh 的註解,程式說明中,中文詩應為中文寫作
    6. + +
    7. 加上 Selima::imacat::Form::LiteralZhSelima::imacat::Checker::LiteralZhSelima::imacat::Processor::LiteralZh ,處理英文寫作。
    8. + +
    9. 修正 Selima::imacat::Processor::ChangeLogSelima::imacat::Processor::DiarySelima::imacat::Processor::LiteralEnSelima::imacat::Processor::LtZhPoemSelima::imacat::Processor::LiteralZhSelima::wov::Processor::NLArtSelima::wov::Processor::Newslet ,刪除已不再需要的引用符號集 :scptconf 。各別網站下的程式,其實可以直接引用自己的重製網頁模組及函式,不需要再使用 $MAIN 來尋找重製網頁函式。
    10. +
    + +
    + +
    + +
    +
    日期: 4.24.’06.
    + +
      +
    1. 更新 Selima::imacat::Processor::LtZhPoem 類別,加上 _rebuild_partial_pages() 方法。
    2. +
    + +
    + +
    + +
    +
    日期: 4.23.’06.
    + +
      +
    1. 更新 newslets.cgiliteralzh.cgiSelima::AddColSelima::wov::Checker::NewsletSelima::imacat::Checker::LiteralZhSelima::imacat::Processor::LiteralZhSelima::AddCol ,日期輸入操作原用 EPOCH 秒數,改用 ISO 標準日期格式。
    2. + +
    3. 加上 Selima::wov::Items::newslet_no() 函式;更新 Selima::wov::Processor::NLArts ,記錄加上電子報期數。
    4. + +
    5. 修正 Selima::imacat::HTML 模組, html_literalzh() 函式改名為 html_ltzh_body()html_literalzh_index() 函式改名為 html_ltzh_index() ,縮短名稱;修正 Selima::imacat::Rebuild 引用的地方。
    6. + +
    7. 修正 Selima::Processor::LinkCat 類別,直接引用 linkcat 資料表的地方,改用 $DBH->quote_identifier($self->{"table"})
    8. + +
    9. 修正 Selima::imacat::Checker::LiteralZh::_check_poems()Selima::wov::Checker::Newslet::_check_arts() ,加上 _trim()_trimtext() 。在子檢查類別中無法做這兩件事。不處理的話,文字區塊會傳回 \r 字元。
    10. + +
    11. 修正 Selima::*::Processor::* 類別的 _rebuild_partial_pages() 方法,直接呼叫 rebuild_*() 函式重製網頁,停用 $MAIL->can("rebuild_*") 找出重製網頁的函式。各網站自己知道自己的重製網頁程式。
    12. + +
    13. 將網頁使用單引號的地方,改為右單引號 &rsquo; 。
    14. + +
    15. 修正 Selima::*::List::Search 類別,加上 actlog() 記錄網站檢索。
    16. + +
    17. 全文檢索加上中文詩。
    18. + +
    19. 更新 search_list ,日期改採 ISO 標準格式,將雜類欄位合併簡化為 kw ;修正 Selima::emily::List::Search 註解的程式說明,網站名稱錯誤更正;修正 Selima::imacat::List::Search 類別的 html_list() 方法,新加 ltzhpoem 類, literalzh 類標題改由顯示時再處理;修正 Selima::wov::List::Search::fetch() 類別的 fetch() 方法,呼叫母方法時名稱原誤為 SUPER::FETCH() ,更正為 SUPER::fetch()
    20. + +
    21. 加上 literalen 資料表。
    22. + +
    23. 比對同步梅姬首頁和 Selima:*::HTML@ADMIN_SCRIPTS 選單; Selima:wov::HTML@ADMIN_SCRIPTS 加上電子報管理的連結(目前權限系統還沒有辦法處理)。
    24. +
    + +
    + +
    + +
    +
    日期: 4.22.’06.
    + +
      +
    1. 修正 Selima::List::Public::Guestbook 類別的 html_list() 方法,移除不正確的 <var>…</var> 標示,網址和信箱加上 <samp>…</samp> 標示;網址格式不正確時,原先顯示 $$current{"location"} ,修正為顯示 $$current{"url"} ;時間視語言加上 xml:lang="en" 標示;修正時間的字型為 Times New Roman ;修正留言簽名的字型,繁體為華康瘦金體(P),簡體為仿宋_GB2312,英文為 Viner Hand ITC ,並去除斜體;修正信箱顯示的方式,將連結圖檔移到後方。
    2. + +
    3. 修正 Selima::imacat::List::Public::Garbage 類別的 html_list() 方法, id="entries" 修正為 class="entries" ;留言資料其實只有時間,故簡化留言資料的標示為一行,並視語言加上 xml:lang="en" 標示;移除不必要的信箱表格節尾條件碼;修正留言資料的字型為 Times New Roman
    4. + +
    5. 修正 Selima::A2HTML ,網址加以 <samp>…</samp> 標示,移除連結時不必要的 mangle_email_hcref() ,連結文字部份改用 mangle_email_span() ,文字部份以 h_abbr() 標示縮寫。
    6. + +
    7. 修正 Selima::MarkAbbr ,網站擴充設定移到最後,以避免如 CPAN 遞迴標示的問題。
    8. + +
    9. 加上 Selima::imacat::Items 模組,加上 markabbr_site() 縮寫標示網站擴充函式,並加上三個縮寫標示: CPANPEARSARS
    10. + +
    11. Selima::wov::Newslets 模組改名為 Selima::wov::Items ;修正 Selima::wovSelima::wov::Checker::NewsletSelima::wov::Form::NewsletSelima::wov::Rebuild 引用的地方;修正 Selima::wov::Form::NLArt ,加上引用 Selima::wov::Items
    12. + +
    13. 修正 Selima::wov::Items 模組,改用 use utf8; ,減少不必要的 decode() ;修正 newslet_textno() 函式,直接傳回,不再作 decode() 。修正 newslet_title() 函式,期數原直接以 || 運算子,改以 $DBH->strcat() 處理;移除不用的變數 $row$col 變數改用 $_ 並移除;移除 decode()encode()UTF-8 絕不會有問題,故移除 FB_CROAK
    14. + +
    15. 修正 Selima::Format 模組,使用 use utf8; ;修正 myfmtdate()myfmttime() 兩個函式,原來年份用的單引號,改用右單引號( &rsquo; )。
    16. + +
    17. 修正 Selima::ReqURI::init_request_uri() 函式, $REQUEST_URI 取的參數,改取未移除 langcharset 前的原始參數;修正 Selima::Init::initenv() 函式,阻擋機器人碼的部份原先以 $REQUEST_PATH$ENV{"QUERY_STRING"} ,改以 $REQUEST_URI 判斷;修正 Selima::HTTP ,作 page2rel() 時原用 $REQUEST_URI ,改用 $REQUEST_PATH ;記錄時原用 $0 ,改用 $REQUEST_URI
    18. + +
    19. 修正 Selima::imacat::Items 模組,加上 literalzh_title() 函式;修正 ltzhpoem.cgi 程式,加上 import_selset() 函式;修正 Selima::imacat::Checker::LtZhPoem 類別的 _check_set() ,檢查的資料表由 newslets 改正為 ltzhpoem ;修正 Selima::imacat::Checker::LtZhPoem ,加上引用 Selima::imacat::Items
    20. + +
    21. 修正 Selima::wov::Check::NLArts 類別 _check_newslet() 方法的註解, groups 應為 newsletters
    22. + +
    23. 修正 Selima::Form::* 類別,加上對於刪除表格的判斷。並不是所有的表格都只有三種類型,而且變異的情形其實非常普遍。
    24. + +
    25. 修正 Selima::Form::* 類別,把三種表格判斷式的註解文字統一。
    26. + +
    27. 修正 Selima::*::Rebuild 模組,原來 next if !defined $html 改為 goutpage() if defined $html
    28. + +
    29. 修正 Selima::PageFunc::page_all_linguas() 函式,讓網頁可以強制設定所有語言。
    30. + +
    31. 修正 Selima::Unicode 模組,加上漏掉的 all_to_trad()all_to_simp() 的原型宣告。
    32. + +
    33. 修正 Selima::imacat::Rebuild::compose_page() 函式的註解,原為 We need a copy, a reference to the same things ,應為 We need a copy, not a reference to the same thing
    34. + +
    35. 修正 seach.cgiguestbook.cgi ,將關鍵字統一設為多語格式;修正 Selima::Init::initenv() 函式,對關鍵字不論是否為多語網站,一律作多語處理。
    36. + +
    37. 修正 Selima::*::List::SearchSelima::*::RebuildSelima::*::HTMLsearch.cgiguestbook.cgi ,移除不需要的 use encoding(Big5)
    38. + +
    39. use encoding(Big5) 全部改作 use utf8 :修正 guestbook.cgiSelima::*::ConfigSelima::*::Processor::GuestbookSelima::imacat::Processor::GarbageSelima::imacat::HTMLSelima::wov::HTMLSelima::wov::RebuildSelima::wov::List::SearchSelima::wov::Form::Public::Guestbook
    40. + +
    41. 加上 Selima::imacat::Rebuild::rebuild_literalzh()Selima::imacat::HTML::html_literalzh()Selima::imacat::HTML::html_literalzh_index() 函式,製作中文詩的網頁。
    42. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 5 | + 6 | + 7 | + 8 | + 9 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0008.html.en.html b/htdocs/imacat/me/changelog/0008.html.en.html new file mode 120000 index 0000000..90a43b5 --- /dev/null +++ b/htdocs/imacat/me/changelog/0008.html.en.html @@ -0,0 +1 @@ +0008.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0008.html.en.xhtml b/htdocs/imacat/me/changelog/0008.html.en.xhtml new file mode 100644 index 0000000..b553ba4 --- /dev/null +++ b/htdocs/imacat/me/changelog/0008.html.en.xhtml @@ -0,0 +1,365 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 8 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 8

    + +
    + +
    + +
    +
    Date: 5.2.’06.
    + +
      +
    1. PHP Monica ,修正 Selima::GetLang 模組,加上 getlang_filename() 函式,由檔名判斷所請求的語言。
    2. + +
    3. 修正 Selima::Init::block_bad_robots() 函式,加上處理 Opera 的情形,排除兩種網頁程式的一般請求,並在通訊協定上用較窄的定義。
    4. + +
    5. 修正 Selima::htc::Form::Newslet 類別的 _html_col_articles() 方法,在 <ol> 後漏寫一個換行 \n 。
    6. +
    + +
    + +
    + +
    +
    Date: 5.1.’06.
    + +
      +
    1. 修正 Selima::Form 類別的 _html_coltmpl_select_multi() 方法及 _html_col_scats() 方法,子項目列表原用 <br /> ,改用 <ul>…</ul>
    2. + +
    3. 修正 header.html ,字集處改為 <!--selima:charset--> ,以便於頁面輸出時統一代換。
    4. + +
    5. 修正 Selima::Init 模組的 initenv() 函式,將 HTTP 405 Method Not Allowed 的檢查移至 block_bad_robots() 之前,使 search.cgi 的阻擋效果優先使用;修正 HTTP 405 Method Not Allowed 檢查,不符合時原先傳入 @{$param{"-allowed"}} ,改傳入 @$_ ,以符合未設定 -allowed 時的預設處理模式;加上檢查 $param{"-allowed"} 的值是否定義,以支援不檢查的設定。
    6. + +
    7. 修正 Selima::Init 的擋廣告留言函式,加上新的規則。
    8. +
    + +
    + +
    + +
    +
    Date: 4.30.’06.
    + +
      +
    1. 修正 Selima::wov::Processor::NLArt 類別,將電子報期號的記錄由 no. 改為大寫 No.
    2. + +
    3. 修正 Selima::List::Guestbook 類別及 Selima::List::Links 類別, COLS_BRIEF 的設定改用 push() ,以便重載可以重複利用。
    4. + +
    5. 修正 Selima::List::Pages 類別,原先 COLS_BRIEFdsc ,改正為 body ,並改用 push()
    6. + +
    7. 修正 Selima::wov::List::NewsletsSelima::wov::List::NLArtsSelima::htc::List::NewsletsSelima::htc::List::NLArts 類別,加上 COLS_BRIEF 的設定。
    8. + +
    9. 修正 nlarts 資料表,加上布林欄位 html 及文字欄位 authors
    10. + +
    11. 加上 Selima::htc::Form::NLArtSelima::htc::Checker::NLArtSelima::htc::Processor::NLArt 類別。
    12. + +
    13. 修正 nlindex 資料表,加上 article 欄位;修正 title 欄位的規則,若有 article 欄位時,可以留白;修正 nlarts_list 檢視及 nlindex_fulltitle() 函式、 Selima::htc::Items::nlindex_title() 函式,標題以 nlindex.titlenlarts.title 依序顯示。
    14. + +
    15. 修正 nlarts 資料表,作者以 authorsauthor 依序顯示。
    16. + +
    17. 修正 Selima::htc::Form::NLIndex 模組,加上顯示 subitems 欄位。
    18. + +
    19. 修正 Selima::Form::Groups 類別、 Selima::Form::LinkCat 類別及 Selima::Form::Users 類別,子項目列表原用 <br /> ,改用 <ul>…</ul>
    20. + +
    21. 復原 Selima::Form 的因縮排對齊所需的行尾空白。
    22. +
    + +
    + +
    + +
    +
    Date: 4.29.’06.
    + +
      +
    1. 將擋廣告留言移至 Selima::Init 模組,在最前面資料庫初始化之前執行,以將垃圾廣告商對系統的負荷降至最低。擋垃圾廣告留言的規則不需要資料庫。
    2. + +
    3. 修正 Selima::DBI 類別的 disconnect() 方法,停用 park_handle() 方法,程式結束後資料庫斷線,以免途留無謂的資料庫連線,影響系統效能。
    4. + +
    5. 修正 Selima::List 類別的 html_list() 方法,沒有 $$current{"_viewurl"} 時原顯示沒有連結的文字,改顯示空欄位。
    6. + +
    7. 修正女聲的 po 檔,原先專案名稱誤為 emily ,改正為 wov
    8. + +
    9. 修正 Selima::htc::Items 模組, newslet_textno() 函式原用簡單 sprintf() 函式回傳,改用 Lingua::ZH::Numbers 回傳;修正 newslet_title() 函式,改用 newslet_textno() 回傳,並加上標題;加上 nlindex_title() 函式;修正 Selima::htc 模組,加上引用 Selima::htc::Items 模組。
    10. + +
    11. 加上 Selima::htc::DataVars 模組,加上 FORM_NEWSLETSFORM_NLINDEXFORM_NLARTS 三個常數;修正 Selima::htc 模組,加上引用 Selima::htc::DataVars 模組。
    12. + +
    13. 修正 Selima::Checker::Public::Guestbook 類別的 _block_spam() 方法,加上 $DBH->disconnect ,先關閉資料庫連線,節省系統資源。
    14. + +
    15. 修正 Selima::Form 類別,刪掉行尾空白。
    16. + +
    17. 修正 Selima::Processor::LinkCat 類別,設定 topmost 處加上對是否收到 topmost 變數的檢查。
    18. + +
    19. 加上 nlindex 資料表,處理通訊目錄;加上 nlindex.cgi 程式、 Selima::htc::List::NLIndex 模組、 Selima::htc::Form::NLIndex 模組、 Selima::htc::Checker::NLIndex 模組及 Selima::htc::Processor::NLIndex 模組。
    20. + +
    21. 修正 nlarts.cgiSelima::wov::List::NLArtsSelima::wov::Form::NLArtsSelima::wov::Processor::NLArts ,簡化文字訊息 newsletter articlearticle
    22. + +
    23. 修正單語網站的管理程式 groups.cgilinkcat.cgipages.cginlindex.cgi ,移除對是否由預設語言建新資料的檢查。單語網站沒有預設語言的問題。
    24. + +
    25. 修正單語網站的管理程式 groups.cgilinkcat.cgipages.cgi ,移除繁簡中文同步的檢查。單語網站沒有繁簡中文的問題。
    26. + +
    27. 加上 nlarts.cgi 程式及 Selima::htc::List::NLArts 類別。
    28. +
    + +
    + +
    + +
    +
    Date: 4.28.’06.
    + +
      +
    1. 修正 Selima::Checker 類別,原在 check() 方法中以 sn 參數初始化 iscursn ,改在 new() 方法就先初始化 iscursn 。原先是很久以前 Monica/Selima 還未成熟時的笨方法,那時候我對物件導向不熟,才會那樣寫。現在這樣做才對。
    2. + +
    3. 修正 Selima::Init 模組,擋掉路徑含 .. 笨拙、無法正確處理路逕的抓 E-mail 程式時,原用 $REQUEST_URI ,改用 $REQUEST_PATH ,以免誤擋查詢的辭彙。
    4. + +
    5. 修正 Selima::Init 模組,刪掉早已停用的 set_locale() 函數的原型宣告。
    6. + +
    7. 修正 Selima::Init 模組,加上 block_bad_robots() 函式,以早期預警,減少伺服器要連上資料庫的負擔。
    8. + +
    9. 修正 Selima::Checker::Public::Guestbook 類別,在 _checkspam_reqheads() 方法中加上一個擋廣告留言的規則。
    10. + +
    11. 刪除 2006-04-24 更新時,有記在更新日誌,實際上卻忘記更新的,刪除 Selima::*::Processor::* 引用的 :scptconf 符號集。
    12. + +
    13. 加上 Selima::htc::Processor::Newslet 類別。
    14. + +
    15. 修正 Selima::wov::Rebuild 模組,將 rebuild_newslets() 函式移到 rebuild_links() 函式後面。
    16. +
    + +
    + +
    + +
    +
    Date: 4.28.’06.
    + +
      +
    1. 修正 Selima::emily::List::Search 類別,刪掉不需引用的 $DBH 變數。
    2. + +
    3. 修正 Selima::emily 的版權文字年份至 2006 年。
    4. + +
    5. 修正 Selima::*::HTML::html_footer() 函式, $$args{"footer_html_nav"} 不再以 <div class="nav">…</div> 圍繞。樣式表現在直接針對 .navibar 設定,目前不需要了。
    6. + +
    7. 加上 Selima::htc::List::Search 類別及 search.cgi 程式。目前尚未公開。
    8. + +
    9. 修正 Selima::List 類別,使用統一的萬國碼刪節號:修正 query_abstract() 方法, $andsoon 改為直接用 "…" ;修正 colval() 方法中顯示欄位摘要, t_andsoon() 改直接用 "…"
    10. + +
    11. 修正 Selima::CommText 模組,移除已不使用的 t_ddd()t_andsoon()
    12. + +
    13. 修正 Selima::wov::Items 模組,刪除已不需要引用的 Selima::GetLangSelima::DataVars:lninfo: ,改單獨引用 $Selima::DataVars::DBH 變數。
    14. + +
    15. 加上 newslets 資料表、 newslets.cgi 程式、 Selima::htc::List::Newslets 類別及 Selima::htc::Form::Newslet 類別。
    16. +
    + +
    + +
    + +
    +
    Date: 4.27.’06.
    + +
      +
    1. 修正 Selima::emily::HTML 模組的 html_header() 函式,加上 /copying.html 版權頁。
    2. +
    + +
    + +
    + +
    +
    Date: 4.27.’06.
    + +
      +
    1. 將舊旅舍日記,存進旅舍日記資料表最前面。因卷數計算標準不同,原有六卷變成兩卷。現有的旅舍日記卷數往後移。
    2. + +
    3. 修正旅舍全文檢索,繼續旅行的英文內容檢索部份,加上只有有英文簡介才會搜尋的限制。
    4. + +
    5. 加上 htcsearch_list
    6. + +
    7. PHP Monica ,修正 Selima::List ,加上對 _selurl 欄位的支援。
    8. +
    + +

    沒想到用這個簡單的方式,輕鬆就把舊旅舍日記給解決掉了。 ^^; 終於把整個旅舍依瑪網站全部存進資料庫了。可喜可賀~! ^_*'

    + +
    + +
    + +
    +
    Date: 4.26.’06.
    + +
      +
    1. 修正 Selima::Preview 模組的 html_preview() 函式,加上設定語言的功能,以便中文寫作和英文寫作正確處理。
    2. + +
    3. 修正 Selima::imacat::Processor::LiteralZh 類別 _rebuild_partial_pages() 方法的註解,由 An existing page 更改為 An existing page that keeps existing
    4. + +
    5. 加上重製英文寫作的網頁:修正 Selima::imacat::Rebuild 模組,加上 rebuild_literalen() 函式;修正 compose_page() 函式,加上英文寫作網頁的特殊規則;修正 Selima::imacat::HTML 模組,加上 html_lten_pagebar()html_lten_index() 函式;修正 literalen.cgi 程式,加上預覽;修正 Selima::imacat::Processor::LiteralEn 類別,加上 _rebuild_partial_pages() 方法及 _remove_curfile() 方法。
    6. + +
    7. 修正 Selima::imacat::Processor::LiteralZh 類別的 _rebuild_partial_pages() 方法,改用 @conds 取得 SQL 條件式,邊緣小於六頁時不加條件設限,以處理頁數為零的情形。
    8. + +
    9. 將英文寫作的樣式表 writings-en.css 併入 common.css ,刪除 writings-en.css
    10. + +
    11. 修正樣式表,將英文的引號樣式改為左雙引號 &ldquo; 、右雙引號 &rdquo; 、左單引號 &lsquo; 及右單引號 &rsquo; 。
    12. + +
    13. 全文檢索加入英文寫作,修正 search_listSelima::imacat::List::Search
    14. +
    + +

    英文寫作也存進資料庫了。剩下舊旅舍日記。加油加油!

    + +
    + +
    + +
    +
    Date: 4.26.’06.
    + +
      +
    1. 修正 Selima::wov::Rebuild 模組的 rebuild_newslets() 函式,電子報部份原來自己組合網頁,改集中用 compose_page() 組合網頁。
    2. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 6 | + 7 | + 8 | + 9 | + 10 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0008.html.zh-cn.html b/htdocs/imacat/me/changelog/0008.html.zh-cn.html new file mode 120000 index 0000000..02b39ac --- /dev/null +++ b/htdocs/imacat/me/changelog/0008.html.zh-cn.html @@ -0,0 +1 @@ +0008.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0008.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0008.html.zh-cn.xhtml new file mode 100644 index 0000000..4f01bd9 --- /dev/null +++ b/htdocs/imacat/me/changelog/0008.html.zh-cn.xhtml @@ -0,0 +1,364 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷八 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷八

    + +
    + +
    + +
    +
    日期: 5.2.’06.
    + +
      +
    1. PHP Monica ,修正 Selima::GetLang 模组,加上 getlang_filename() 函式,由档名判断所请求的语言。
    2. + +
    3. 修正 Selima::Init::block_bad_robots() 函式,加上处理 Opera 的情形,排除两种网页程式的一般请求,并在通讯协定上用较窄的定义。
    4. + +
    5. 修正 Selima::htc::Form::Newslet 类别的 _html_col_articles() 方法,在 <ol> 后漏写一个换行 \n 。
    6. +
    + +
    + +
    + +
    +
    日期: 5.1.’06.
    + +
      +
    1. 修正 Selima::Form 类别的 _html_coltmpl_select_multi() 方法及 _html_col_scats() 方法,子项目列表原用 <br /> ,改用 <ul>…</ul>
    2. + +
    3. 修正 header.html ,字集处改为 <!--selima:charset--> ,以便於页面输出时统一代换。
    4. + +
    5. 修正 Selima::Init 模组的 initenv() 函式,将 HTTP 405 Method Not Allowed 的检查移至 block_bad_robots() 之前,使 search.cgi 的阻挡效果优先使用;修正 HTTP 405 Method Not Allowed 检查,不符合时原先传入 @{$param{"-allowed"}} ,改传入 @$_ ,以符合未设定 -allowed 时的预设处理模式;加上检查 $param{"-allowed"} 的值是否定义,以支援不检查的设定。
    6. + +
    7. 修正 Selima::Init 的挡广告留言函式,加上新的规则。
    8. +
    + +
    + +
    + +
    +
    日期: 4.30.’06.
    + +
      +
    1. 修正 Selima::wov::Processor::NLArt 类别,将电子报期号的记录由 no. 改为大写 No.
    2. + +
    3. 修正 Selima::List::Guestbook 类别及 Selima::List::Links 类别, COLS_BRIEF 的设定改用 push() ,以便重载可以重复利用。
    4. + +
    5. 修正 Selima::List::Pages 类别,原先 COLS_BRIEFdsc ,改正为 body ,并改用 push()
    6. + +
    7. 修正 Selima::wov::List::NewsletsSelima::wov::List::NLArtsSelima::htc::List::NewsletsSelima::htc::List::NLArts 类别,加上 COLS_BRIEF 的设定。
    8. + +
    9. 修正 nlarts 资料表,加上布林栏位 html 及文字栏位 authors
    10. + +
    11. 加上 Selima::htc::Form::NLArtSelima::htc::Checker::NLArtSelima::htc::Processor::NLArt 类别。
    12. + +
    13. 修正 nlindex 资料表,加上 article 栏位;修正 title 栏位的规则,若有 article 栏位时,可以留白;修正 nlarts_list 检视及 nlindex_fulltitle() 函式、 Selima::htc::Items::nlindex_title() 函式,标题以 nlindex.titlenlarts.title 依序显示。
    14. + +
    15. 修正 nlarts 资料表,作者以 authorsauthor 依序显示。
    16. + +
    17. 修正 Selima::htc::Form::NLIndex 模组,加上显示 subitems 栏位。
    18. + +
    19. 修正 Selima::Form::Groups 类别、 Selima::Form::LinkCat 类别及 Selima::Form::Users 类别,子项目列表原用 <br /> ,改用 <ul>…</ul>
    20. + +
    21. 复原 Selima::Form 的因缩排对齐所需的行尾空白。
    22. +
    + +
    + +
    + +
    +
    日期: 4.29.’06.
    + +
      +
    1. 将挡广告留言移至 Selima::Init 模组,在最前面资料库初始化之前执行,以将垃圾广告商对系统的负荷降至最低。挡垃圾广告留言的规则不需要资料库。
    2. + +
    3. 修正 Selima::DBI 类别的 disconnect() 方法,停用 park_handle() 方法,程式结束后资料库断线,以免途留无谓的资料库连线,影响系统效能。
    4. + +
    5. 修正 Selima::List 类别的 html_list() 方法,没有 $$current{"_viewurl"} 时原显示没有连结的文字,改显示空栏位。
    6. + +
    7. 修正女声的 po 档,原先专案名称误为 emily ,改正为 wov
    8. + +
    9. 修正 Selima::htc::Items 模组, newslet_textno() 函式原用简单 sprintf() 函式回传,改用 Lingua::ZH::Numbers 回传;修正 newslet_title() 函式,改用 newslet_textno() 回传,并加上标题;加上 nlindex_title() 函式;修正 Selima::htc 模组,加上引用 Selima::htc::Items 模组。
    10. + +
    11. 加上 Selima::htc::DataVars 模组,加上 FORM_NEWSLETSFORM_NLINDEXFORM_NLARTS 三个常数;修正 Selima::htc 模组,加上引用 Selima::htc::DataVars 模组。
    12. + +
    13. 修正 Selima::Checker::Public::Guestbook 类别的 _block_spam() 方法,加上 $DBH->disconnect ,先关闭资料库连线,节省系统资源。
    14. + +
    15. 修正 Selima::Form 类别,删掉行尾空白。
    16. + +
    17. 修正 Selima::Processor::LinkCat 类别,设定 topmost 处加上对是否收到 topmost 变数的检查。
    18. + +
    19. 加上 nlindex 资料表,处理通讯目录;加上 nlindex.cgi 程式、 Selima::htc::List::NLIndex 模组、 Selima::htc::Form::NLIndex 模组、 Selima::htc::Checker::NLIndex 模组及 Selima::htc::Processor::NLIndex 模组。
    20. + +
    21. 修正 nlarts.cgiSelima::wov::List::NLArtsSelima::wov::Form::NLArtsSelima::wov::Processor::NLArts ,简化文字讯息 newsletter articlearticle
    22. + +
    23. 修正单语网站的管理程式 groups.cgilinkcat.cgipages.cginlindex.cgi ,移除对是否由预设语言建新资料的检查。单语网站没有预设语言的问题。
    24. + +
    25. 修正单语网站的管理程式 groups.cgilinkcat.cgipages.cgi ,移除繁简中文同步的检查。单语网站没有繁简中文的问题。
    26. + +
    27. 加上 nlarts.cgi 程式及 Selima::htc::List::NLArts 类别。
    28. +
    + +
    + +
    + +
    +
    日期: 4.28.’06.
    + +
      +
    1. 修正 Selima::Checker 类别,原在 check() 方法中以 sn 参数初始化 iscursn ,改在 new() 方法就先初始化 iscursn 。原先是很久以前 Monica/Selima 还未成熟时的笨方法,那时候我对物件导向不熟,才会那样写。现在这样做才对。
    2. + +
    3. 修正 Selima::Init 模组,挡掉路径含 .. 笨拙、无法正确处理路迳的抓 E-mail 程式时,原用 $REQUEST_URI ,改用 $REQUEST_PATH ,以免误挡查询的辞汇。
    4. + +
    5. 修正 Selima::Init 模组,删掉早已停用的 set_locale() 函数的原型宣告。
    6. + +
    7. 修正 Selima::Init 模组,加上 block_bad_robots() 函式,以早期预警,减少伺服器要连上资料库的负担。
    8. + +
    9. 修正 Selima::Checker::Public::Guestbook 类别,在 _checkspam_reqheads() 方法中加上一个挡广告留言的规则。
    10. + +
    11. 删除 2006-04-24 更新时,有记在更新日志,实际上却忘记更新的,删除 Selima::*::Processor::* 引用的 :scptconf 符号集。
    12. + +
    13. 加上 Selima::htc::Processor::Newslet 类别。
    14. + +
    15. 修正 Selima::wov::Rebuild 模组,将 rebuild_newslets() 函式移到 rebuild_links() 函式后面。
    16. +
    + +
    + +
    + +
    +
    日期: 4.28.’06.
    + +
      +
    1. 修正 Selima::emily::List::Search 类别,删掉不需引用的 $DBH 变数。
    2. + +
    3. 修正 Selima::emily 的版权文字年份至 2006 年。
    4. + +
    5. 修正 Selima::*::HTML::html_footer() 函式, $$args{"footer_html_nav"} 不再以 <div class="nav">…</div> 围绕。样式表现在直接针对 .navibar 设定,目前不需要了。
    6. + +
    7. 加上 Selima::htc::List::Search 类别及 search.cgi 程式。目前尚未公开。
    8. + +
    9. 修正 Selima::List 类别,使用统一的万国码删节号:修正 query_abstract() 方法, $andsoon 改为直接用 "…" ;修正 colval() 方法中显示栏位摘要, t_andsoon() 改直接用 "…"
    10. + +
    11. 修正 Selima::CommText 模组,移除已不使用的 t_ddd()t_andsoon()
    12. + +
    13. 修正 Selima::wov::Items 模组,删除已不需要引用的 Selima::GetLangSelima::DataVars:lninfo: ,改单独引用 $Selima::DataVars::DBH 变数。
    14. + +
    15. 加上 newslets 资料表、 newslets.cgi 程式、 Selima::htc::List::Newslets 类别及 Selima::htc::Form::Newslet 类别。
    16. +
    + +
    + +
    + +
    +
    日期: 4.27.’06.
    + +
      +
    1. 修正 Selima::emily::HTML 模组的 html_header() 函式,加上 /copying.html 版权页。
    2. +
    + +
    + +
    + +
    +
    日期: 4.27.’06.
    + +
      +
    1. 将旧旅舍日记,存进旅舍日记资料表最前面。因卷数计算标准不同,原有六卷变成两卷。现有的旅舍日记卷数往后移。
    2. + +
    3. 修正旅舍全文检索,继续旅行的英文内容检索部份,加上只有有英文简介才会搜寻的限制。
    4. + +
    5. 加上 htcsearch_list
    6. + +
    7. PHP Monica ,修正 Selima::List ,加上对 _selurl 栏位的支援。
    8. +
    + +

    没想到用这个简单的方式,轻松就把旧旅舍日记给解决掉了。 ^^; 终於把整个旅舍依玛网站全部存进资料库了。可喜可贺~! ^_*'

    + +
    + +
    + +
    +
    日期: 4.26.’06.
    + +
      +
    1. 修正 Selima::Preview 模组的 html_preview() 函式,加上设定语言的功能,以便中文写作和英文写作正确处理。
    2. + +
    3. 修正 Selima::imacat::Processor::LiteralZh 类别 _rebuild_partial_pages() 方法的注解,由 An existing page 更改为 An existing page that keeps existing
    4. + +
    5. 加上重制英文写作的网页:修正 Selima::imacat::Rebuild 模组,加上 rebuild_literalen() 函式;修正 compose_page() 函式,加上英文写作网页的特殊规则;修正 Selima::imacat::HTML 模组,加上 html_lten_pagebar()html_lten_index() 函式;修正 literalen.cgi 程式,加上预览;修正 Selima::imacat::Processor::LiteralEn 类别,加上 _rebuild_partial_pages() 方法及 _remove_curfile() 方法。
    6. + +
    7. 修正 Selima::imacat::Processor::LiteralZh 类别的 _rebuild_partial_pages() 方法,改用 @conds 取得 SQL 条件式,边缘小於六页时不加条件设限,以处理页数为零的情形。
    8. + +
    9. 将英文写作的样式表 writings-en.css 并入 common.css ,删除 writings-en.css
    10. + +
    11. 修正样式表,将英文的引号样式改为左双引号 &ldquo; 、右双引号 &rdquo; 、左单引号 &lsquo; 及右单引号 &rsquo; 。
    12. + +
    13. 全文检索加入英文写作,修正 search_listSelima::imacat::List::Search
    14. +
    + +

    英文写作也存进资料库了。剩下旧旅舍日记。加油加油!

    + +
    + +
    + +
    +
    日期: 4.26.’06.
    + +
      +
    1. 修正 Selima::wov::Rebuild 模组的 rebuild_newslets() 函式,电子报部份原来自己组合网页,改集中用 compose_page() 组合网页。
    2. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 6 | + 7 | + 8 | + 9 | + 10 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0008.html.zh-tw.html b/htdocs/imacat/me/changelog/0008.html.zh-tw.html new file mode 120000 index 0000000..2c025c9 --- /dev/null +++ b/htdocs/imacat/me/changelog/0008.html.zh-tw.html @@ -0,0 +1 @@ +0008.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0008.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0008.html.zh-tw.xhtml new file mode 100644 index 0000000..0791263 --- /dev/null +++ b/htdocs/imacat/me/changelog/0008.html.zh-tw.xhtml @@ -0,0 +1,364 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷八 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷八

    + +
    + +
    + +
    +
    日期: 5.2.’06.
    + +
      +
    1. PHP Monica ,修正 Selima::GetLang 模組,加上 getlang_filename() 函式,由檔名判斷所請求的語言。
    2. + +
    3. 修正 Selima::Init::block_bad_robots() 函式,加上處理 Opera 的情形,排除兩種網頁程式的一般請求,並在通訊協定上用較窄的定義。
    4. + +
    5. 修正 Selima::htc::Form::Newslet 類別的 _html_col_articles() 方法,在 <ol> 後漏寫一個換行 \n 。
    6. +
    + +
    + +
    + +
    +
    日期: 5.1.’06.
    + +
      +
    1. 修正 Selima::Form 類別的 _html_coltmpl_select_multi() 方法及 _html_col_scats() 方法,子項目列表原用 <br /> ,改用 <ul>…</ul>
    2. + +
    3. 修正 header.html ,字集處改為 <!--selima:charset--> ,以便於頁面輸出時統一代換。
    4. + +
    5. 修正 Selima::Init 模組的 initenv() 函式,將 HTTP 405 Method Not Allowed 的檢查移至 block_bad_robots() 之前,使 search.cgi 的阻擋效果優先使用;修正 HTTP 405 Method Not Allowed 檢查,不符合時原先傳入 @{$param{"-allowed"}} ,改傳入 @$_ ,以符合未設定 -allowed 時的預設處理模式;加上檢查 $param{"-allowed"} 的值是否定義,以支援不檢查的設定。
    6. + +
    7. 修正 Selima::Init 的擋廣告留言函式,加上新的規則。
    8. +
    + +
    + +
    + +
    +
    日期: 4.30.’06.
    + +
      +
    1. 修正 Selima::wov::Processor::NLArt 類別,將電子報期號的記錄由 no. 改為大寫 No.
    2. + +
    3. 修正 Selima::List::Guestbook 類別及 Selima::List::Links 類別, COLS_BRIEF 的設定改用 push() ,以便重載可以重複利用。
    4. + +
    5. 修正 Selima::List::Pages 類別,原先 COLS_BRIEFdsc ,改正為 body ,並改用 push()
    6. + +
    7. 修正 Selima::wov::List::NewsletsSelima::wov::List::NLArtsSelima::htc::List::NewsletsSelima::htc::List::NLArts 類別,加上 COLS_BRIEF 的設定。
    8. + +
    9. 修正 nlarts 資料表,加上布林欄位 html 及文字欄位 authors
    10. + +
    11. 加上 Selima::htc::Form::NLArtSelima::htc::Checker::NLArtSelima::htc::Processor::NLArt 類別。
    12. + +
    13. 修正 nlindex 資料表,加上 article 欄位;修正 title 欄位的規則,若有 article 欄位時,可以留白;修正 nlarts_list 檢視及 nlindex_fulltitle() 函式、 Selima::htc::Items::nlindex_title() 函式,標題以 nlindex.titlenlarts.title 依序顯示。
    14. + +
    15. 修正 nlarts 資料表,作者以 authorsauthor 依序顯示。
    16. + +
    17. 修正 Selima::htc::Form::NLIndex 模組,加上顯示 subitems 欄位。
    18. + +
    19. 修正 Selima::Form::Groups 類別、 Selima::Form::LinkCat 類別及 Selima::Form::Users 類別,子項目列表原用 <br /> ,改用 <ul>…</ul>
    20. + +
    21. 復原 Selima::Form 的因縮排對齊所需的行尾空白。
    22. +
    + +
    + +
    + +
    +
    日期: 4.29.’06.
    + +
      +
    1. 將擋廣告留言移至 Selima::Init 模組,在最前面資料庫初始化之前執行,以將垃圾廣告商對系統的負荷降至最低。擋垃圾廣告留言的規則不需要資料庫。
    2. + +
    3. 修正 Selima::DBI 類別的 disconnect() 方法,停用 park_handle() 方法,程式結束後資料庫斷線,以免途留無謂的資料庫連線,影響系統效能。
    4. + +
    5. 修正 Selima::List 類別的 html_list() 方法,沒有 $$current{"_viewurl"} 時原顯示沒有連結的文字,改顯示空欄位。
    6. + +
    7. 修正女聲的 po 檔,原先專案名稱誤為 emily ,改正為 wov
    8. + +
    9. 修正 Selima::htc::Items 模組, newslet_textno() 函式原用簡單 sprintf() 函式回傳,改用 Lingua::ZH::Numbers 回傳;修正 newslet_title() 函式,改用 newslet_textno() 回傳,並加上標題;加上 nlindex_title() 函式;修正 Selima::htc 模組,加上引用 Selima::htc::Items 模組。
    10. + +
    11. 加上 Selima::htc::DataVars 模組,加上 FORM_NEWSLETSFORM_NLINDEXFORM_NLARTS 三個常數;修正 Selima::htc 模組,加上引用 Selima::htc::DataVars 模組。
    12. + +
    13. 修正 Selima::Checker::Public::Guestbook 類別的 _block_spam() 方法,加上 $DBH->disconnect ,先關閉資料庫連線,節省系統資源。
    14. + +
    15. 修正 Selima::Form 類別,刪掉行尾空白。
    16. + +
    17. 修正 Selima::Processor::LinkCat 類別,設定 topmost 處加上對是否收到 topmost 變數的檢查。
    18. + +
    19. 加上 nlindex 資料表,處理通訊目錄;加上 nlindex.cgi 程式、 Selima::htc::List::NLIndex 模組、 Selima::htc::Form::NLIndex 模組、 Selima::htc::Checker::NLIndex 模組及 Selima::htc::Processor::NLIndex 模組。
    20. + +
    21. 修正 nlarts.cgiSelima::wov::List::NLArtsSelima::wov::Form::NLArtsSelima::wov::Processor::NLArts ,簡化文字訊息 newsletter articlearticle
    22. + +
    23. 修正單語網站的管理程式 groups.cgilinkcat.cgipages.cginlindex.cgi ,移除對是否由預設語言建新資料的檢查。單語網站沒有預設語言的問題。
    24. + +
    25. 修正單語網站的管理程式 groups.cgilinkcat.cgipages.cgi ,移除繁簡中文同步的檢查。單語網站沒有繁簡中文的問題。
    26. + +
    27. 加上 nlarts.cgi 程式及 Selima::htc::List::NLArts 類別。
    28. +
    + +
    + +
    + +
    +
    日期: 4.28.’06.
    + +
      +
    1. 修正 Selima::Checker 類別,原在 check() 方法中以 sn 參數初始化 iscursn ,改在 new() 方法就先初始化 iscursn 。原先是很久以前 Monica/Selima 還未成熟時的笨方法,那時候我對物件導向不熟,才會那樣寫。現在這樣做才對。
    2. + +
    3. 修正 Selima::Init 模組,擋掉路徑含 .. 笨拙、無法正確處理路逕的抓 E-mail 程式時,原用 $REQUEST_URI ,改用 $REQUEST_PATH ,以免誤擋查詢的辭彙。
    4. + +
    5. 修正 Selima::Init 模組,刪掉早已停用的 set_locale() 函數的原型宣告。
    6. + +
    7. 修正 Selima::Init 模組,加上 block_bad_robots() 函式,以早期預警,減少伺服器要連上資料庫的負擔。
    8. + +
    9. 修正 Selima::Checker::Public::Guestbook 類別,在 _checkspam_reqheads() 方法中加上一個擋廣告留言的規則。
    10. + +
    11. 刪除 2006-04-24 更新時,有記在更新日誌,實際上卻忘記更新的,刪除 Selima::*::Processor::* 引用的 :scptconf 符號集。
    12. + +
    13. 加上 Selima::htc::Processor::Newslet 類別。
    14. + +
    15. 修正 Selima::wov::Rebuild 模組,將 rebuild_newslets() 函式移到 rebuild_links() 函式後面。
    16. +
    + +
    + +
    + +
    +
    日期: 4.28.’06.
    + +
      +
    1. 修正 Selima::emily::List::Search 類別,刪掉不需引用的 $DBH 變數。
    2. + +
    3. 修正 Selima::emily 的版權文字年份至 2006 年。
    4. + +
    5. 修正 Selima::*::HTML::html_footer() 函式, $$args{"footer_html_nav"} 不再以 <div class="nav">…</div> 圍繞。樣式表現在直接針對 .navibar 設定,目前不需要了。
    6. + +
    7. 加上 Selima::htc::List::Search 類別及 search.cgi 程式。目前尚未公開。
    8. + +
    9. 修正 Selima::List 類別,使用統一的萬國碼刪節號:修正 query_abstract() 方法, $andsoon 改為直接用 "…" ;修正 colval() 方法中顯示欄位摘要, t_andsoon() 改直接用 "…"
    10. + +
    11. 修正 Selima::CommText 模組,移除已不使用的 t_ddd()t_andsoon()
    12. + +
    13. 修正 Selima::wov::Items 模組,刪除已不需要引用的 Selima::GetLangSelima::DataVars:lninfo: ,改單獨引用 $Selima::DataVars::DBH 變數。
    14. + +
    15. 加上 newslets 資料表、 newslets.cgi 程式、 Selima::htc::List::Newslets 類別及 Selima::htc::Form::Newslet 類別。
    16. +
    + +
    + +
    + +
    +
    日期: 4.27.’06.
    + +
      +
    1. 修正 Selima::emily::HTML 模組的 html_header() 函式,加上 /copying.html 版權頁。
    2. +
    + +
    + +
    + +
    +
    日期: 4.27.’06.
    + +
      +
    1. 將舊旅舍日記,存進旅舍日記資料表最前面。因卷數計算標準不同,原有六卷變成兩卷。現有的旅舍日記卷數往後移。
    2. + +
    3. 修正旅舍全文檢索,繼續旅行的英文內容檢索部份,加上只有有英文簡介才會搜尋的限制。
    4. + +
    5. 加上 htcsearch_list
    6. + +
    7. PHP Monica ,修正 Selima::List ,加上對 _selurl 欄位的支援。
    8. +
    + +

    沒想到用這個簡單的方式,輕鬆就把舊旅舍日記給解決掉了。 ^^; 終於把整個旅舍依瑪網站全部存進資料庫了。可喜可賀~! ^_*'

    + +
    + +
    + +
    +
    日期: 4.26.’06.
    + +
      +
    1. 修正 Selima::Preview 模組的 html_preview() 函式,加上設定語言的功能,以便中文寫作和英文寫作正確處理。
    2. + +
    3. 修正 Selima::imacat::Processor::LiteralZh 類別 _rebuild_partial_pages() 方法的註解,由 An existing page 更改為 An existing page that keeps existing
    4. + +
    5. 加上重製英文寫作的網頁:修正 Selima::imacat::Rebuild 模組,加上 rebuild_literalen() 函式;修正 compose_page() 函式,加上英文寫作網頁的特殊規則;修正 Selima::imacat::HTML 模組,加上 html_lten_pagebar()html_lten_index() 函式;修正 literalen.cgi 程式,加上預覽;修正 Selima::imacat::Processor::LiteralEn 類別,加上 _rebuild_partial_pages() 方法及 _remove_curfile() 方法。
    6. + +
    7. 修正 Selima::imacat::Processor::LiteralZh 類別的 _rebuild_partial_pages() 方法,改用 @conds 取得 SQL 條件式,邊緣小於六頁時不加條件設限,以處理頁數為零的情形。
    8. + +
    9. 將英文寫作的樣式表 writings-en.css 併入 common.css ,刪除 writings-en.css
    10. + +
    11. 修正樣式表,將英文的引號樣式改為左雙引號 &ldquo; 、右雙引號 &rdquo; 、左單引號 &lsquo; 及右單引號 &rsquo; 。
    12. + +
    13. 全文檢索加入英文寫作,修正 search_listSelima::imacat::List::Search
    14. +
    + +

    英文寫作也存進資料庫了。剩下舊旅舍日記。加油加油!

    + +
    + +
    + +
    +
    日期: 4.26.’06.
    + +
      +
    1. 修正 Selima::wov::Rebuild 模組的 rebuild_newslets() 函式,電子報部份原來自己組合網頁,改集中用 compose_page() 組合網頁。
    2. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 6 | + 7 | + 8 | + 9 | + 10 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0009.html.en.html b/htdocs/imacat/me/changelog/0009.html.en.html new file mode 120000 index 0000000..a35fd72 --- /dev/null +++ b/htdocs/imacat/me/changelog/0009.html.en.html @@ -0,0 +1 @@ +0009.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0009.html.en.xhtml b/htdocs/imacat/me/changelog/0009.html.en.xhtml new file mode 100644 index 0000000..d06a10b --- /dev/null +++ b/htdocs/imacat/me/changelog/0009.html.en.xhtml @@ -0,0 +1,457 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 9 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 9

    + +
    + +
    + +
    +
    Date: 11.17.’06.
    + +
      +
    1. 修正 Selima::Cache 模組與 Selima::FormFunc 模組,將 form 類快取更正為 formfunc ,快取變數 $Form_get_or_post$Form_curform$Form_isform$Form_formtype 分別更正為 $FormFunc_get_or_post$FormFunc_curform$FormFunc_isform$FormFunc_formtype
    2. +
    3. 修正 Selima::Cache 模組,加上變數類別 listfunc ,及快取變數 $ListFunc_listtype
    4. +
    5. 加上 Selima::ListFunc 模組,及 list_type() 函式。
    6. +
    7. 修正 books 資料表,加上 toborrow 欄位及 lib 欄位;修正 Selima::emandy::List::Books 類別,加上 toborrow 欄位及 lib 欄位的標籤;修正 Selima::emandy::Form::Books 類別,加上 _html_col_toborrow() 函式及 _html_col_lib() 函式;修正 Selima::emandy::Checker::Books 類別,加上 _check_lib() 函式;修正 Selima::emandy::Processor::Books 類別,加上儲存 toborrow 欄位及 lib 欄位;修正 books.cgi 程式,加上檢查 lib 欄位。
    8. +
    9. 加上 Selima::emandy::List::Books::ToBorrow 類別及 Selima::emandy::List::Books::NotToBorrow 類別;修正 Selima::emandy::List::Books 類別,加上 $self->{"lists_switch"} ;修正 books.cgi 程式,依 list_type() 顯示三種列表。
    10. +
    + +
    + +
    + +
    +
    Date: 11.16.’06.
    + +
      +
    1. 加上 emandy 網站的 books 資料表、 Selima::emandy::List::Books 類別、 Selima::emandy::Form::Book 類別、 Selima::emandy::Checker::Book 類別、 Selima::emandy::Processor::Book 類別及、 books.cgi 程式。
    2. +
    3. 修正 Selima::emandy::List::Public::Legend 類別,刪除用不到的引用 Selima::LnInfo 模組、 Selima::PageFunc 模組與 :lninfo 類變數。
    4. +
    5. 修正 Selima::emandy::Checker::Legend 類別,加上註解 _check_title() 方法和 _check_body() 方法。
    6. +
    + +
    + +
    + +
    +
    Date: 11.15.’06.
    + +
      +
    1. 加上 emandy 網站的搜尋。
    2. +
    3. 修正 Selima::emandy::List::Search 類別的 html_list() 方法,加上 legend 類的處理。
    4. +
    5. 加上 emandy 資料庫的 country 資料表內容。
    6. +
    7. 修正 country 資料表,加上簡體中文的國名。
    8. +
    9. 修正 country 資料表,英文國名中 ’s 大寫的錯誤,並改單引號為右單引號。
    10. +
    + +
    + +
    + +
    +
    Date: 11.15.’06.
    + +
      +
    1. 加上 emandy 網站。
    2. +
    3. 修正 users 資料表,加上主機名稱 host 與國家 ct 記錄欄位;修正 Selima::LogIn 模組的 upd_login_info() 函式,加上記錄主機名稱與國家;修正 Selima::List::Users 類別的 new() 方法,加上 host 欄位與 ct 欄位的標籤;修正 Selima::Form::User 類別的 new() 方法,加上顯示 host 欄位與 ct 欄位,並加上 _html_col_ct() 方法。
    4. +
    5. 修正 Selima::List::Guestbook 類別的 new() 方法,將 host 欄位的標籤由 Hostname 改為 Host ;修正 Selima::Form 類別的 _html_col_host() 方法,將欄位的標籤由 Hostname: 改為 Host:
    6. +
    + +
    + +
    + +
    +
    Date: 11.4.’06.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_masslinks() 函式。
    2. +
    + +
    + +
    + +
    +
    Date: 10.30.’06.
    + +
      +
    1. 新增 funds 資料表、 Selima::imacat::List::Funds 類別及 funds.cgi 程式。
    2. +
    + +
    + +
    + +
    +
    Date: 10.20.’06.
    + +
      +
    1. 修正 Selima::DecForm 模組,刪掉已未引用的 GDBM_File 模組。
    2. +
    + +
    + +
    + +
    +
    Date: 10.7.’06.
    + +
      +
    1. 修正 Selima::Mail 類別的 _out_trace() 方法, From-domain 原輸出使用者端的 IP ,改輸出 webclient ,比較適當,且避免 From IP 時 SpamAssassin 的高分數。
    2. +
    + +
    + +
    + +
    +
    Date: 9.13.’06.
    + +
      +
    1. 修正 Selima::DecForm 模組的 try_decode_form() 函式,去除表格值的零值 (\x00) 。
    2. +
    + +
    + +
    + +
    +
    Date: 8.27.’06.
    + +
      +
    1. 修正 lang.zh-cn.csscommon.zh-cn.css ,簡體中文的引號改為全形的美式雙、單引號(“…”與‘…’)。
    2. +
    + +
    + +
    + +
    +
    Date: 8.6.’06.
    + +
      +
    1. 修正 Selima::Checker 類別的 new() 方法, $$form{"sn"} 改正為 $form->param("sn")
    2. +
    + +
    + +
    + +
    +
    Date: 7.28.’06.
    + +
      +
    1. 修正 Selima::ReqURI 模組的 init_request_uri() 函式, $REQUEST_URI 不去掉前面的 $ROOT_DIFF$REQUEST_FULLURI 不用 $REQUEST_HOSTPORT ,改用 $REQUEST_SCHEME . "://" . $REQUEST_HOST . $port ,以避免重複加計 $ROOT_DIFF
    2. +
    + +
    + +
    + +
    +
    Date: 7.25.’06.
    + +
      +
    1. 修正 Selima::ReqURI 模組的 init_request_uri() 函式, $REQUEST_URI 在 mod_perl 或 Apache 下取得的值,去除前面的 $ROOT_DIFF
    2. + +
    3. 把百度搜尋引擎擋掉。百度太惡劣了!
    4. +
    + +
    + +
    + +
    +
    Date: 7.14.’06.
    + +
      +
    1. 修正 Selima::Form 類別的 new() 方法,依 PHP Monica ,原由 %CURRENT ,改由 $$form 取得 $checker->{"sn"}
    2. +
    + +
    + +
    + +
    +
    Date: 7.13.’06.
    + +
      +
    1. 修正 Selima::Form 類別,依 PHP Monica ,新增 _html_coltmpl_ro_textarea()_html_coltmpl_ro_date()_html_coltmpl_ro_title()_html_coltmpl_ro_radio() 方法;修正 _html_coltmpl_ro_*() 方法,加上 $prompt 提示訊息參數;修正 _html_coltmpl_*() 方法,提示訊息原用 <samp>…</samp> 標示,改用 <p>…</p> 標示。
    2. +
    + +
    + +
    + +
    +
    Date: 7.4.’06.
    + +
      +
    1. 修正 Selima::Encrypt 模組, Crypt::Blowfish 改用 Crypt::Rijndael_PPCrypt::Blowfish 只能加解密八個位元長度的資料,無法使用。 Crypt::Rijndael_PPCrypt::Rijndael 的純 Perl 版本,以 Perl 實作 AES Rijndael 加解密演算法。這樣就解決了 Crypt::Rijndael 尚不支援 x86_64 平台的問題。(謹向 Crypt::Rijndael_PP 作者 Christian Lackas 致謝。)
    2. + +
    3. 修正 Selima::Checker::User 類別,停用 fascist_check() 檢查。 fascist_check() 的檢查早已因停用 Crypt::Cracklib 而無法使用了。
    4. +
    + +
    + +
    + +
    +
    Date: 6.29.’06.
    + +
      +
    1. 修正 Selima::Mail 類別,加上 _out_trace() 方法,在寄信前,加上 Received: 郵件標頭,以便追蹤發信者。
    2. + +
    3. 修正 Selima::HTTP 模組的 http_500() 函式,偵錯通知內容加上 POST 的表單及登入使用者的資訊。停用中文站名 $PACKAGE_TITLE$SITENAME_ABBR 改用英文,以免輸出郵件時編碼混亂。
    4. +
    + +
    + +
    + +
    +
    Date: 6.5.’06.
    + +
      +
    1. 修正 Selima::DBD::mysql ,把 ${$_} 簡化為 $$_
    2. +
    + +
    + +
    + +
    +
    Date: 5.31.’06.
    + +
      +
    1. 修正 Selima::Unicode::hcref2char() 函式,若字元不需解碼時,多加上分號的錯誤。
    2. +
    + +
    + +
    + +
    +
    Date: 5.23.’06.
    + +
      +
    1. 修正 Selima::imacat::Processor::Public::Garbage 類別,寄出通知信的網址應為 garbage.cgi ,誤記為 guestbook.cgi
    2. +
    + +
    + +
    + +
    +
    Date: 5.19.’06.
    + +
      +
    1. 旅人留言簿變更檔名,以迴避自動貼文程式。
    2. + +
    3. 修正 Selima::InitSelima::Checker::Public::Guestbook ,回復對垃圾廣告留言的延遲。
    4. +
    + +
    + +
    + +
    +
    Date: 5.15.’06.
    + +
      +
    1. 實驗變更女聲留言本名稱,以躲避廣告留言攻擊。
    2. + +
    3. 修正 Selima::*::Processor::Public::Guestbook 類別,寄發通知信時,原用 $THIS_FILE 取得編修留言的檔名,改直接設定檔名。
    4. +
    + +
    + +
    + +
    +
    Date: 5.14.’06.
    + +
      +
    1. 更換伺服器。原伺服器為 Pentium III Coppermine 800MHz 、 220MB HD 、 896 MB SD RAM ,新伺服器為 Pentium D 3.2GHz Dual core 64 位元雙核心、 250MB SATA2 HD 、 1024MB DDR-533 RAM 。
    2. + +
    3. 修正 Selima::Encrypt 模組,原用 Crypt::Rijndael (即 AES )加密,因 Crypt::Rijndael 久未更新,在 x86_64 下無法執行,改用 Crypt::Blowfish
    4. + +
    5. 修正 Selima::Checker::User 類別,暫時停用 Crypt::CracklibCrypt::Cracklib 久未更新,在 x86_64 下無法執行。
    6. + +
    7. %HTML::Entities::entity2char 的符號原先不含末尾的分號,現在含分號。修正 Selima::Unicode 模組的 hcref2char() 函式,以配合其修正。
    8. + +
    9. all2trad.dball2simp.db 兩個資料庫檔,依不同平台( i386 及 x86_64 )分成兩組不同的檔案,分別存到不同的目錄下。修正 Selima::Unicode 模組的 $ALL2TRAD$ALL2SIMP 兩個檔案檔名,使用 File::Spec::Functionssplitdir()catdir()$Config{";myarchname";} 平台名稱組合檔名,以便跨平台相容。
    10. +
    + +
    + +
    + +
    +
    Date: 5.5.’06.
    + +
      +
    1. 修正 nlindex 資料表, article 欄位改名為 art ;修正 Selima::htc::List::NLIndex 類別的 new() 方法、 Selima::htc::Form::NLIndex 類別的 new() 方法、 Selima::htc::Processor::NLIndex 類別的 _save_cols() 方法及 nlindex.cgi 程式的 check_post() 函式;修正 Selima::htc::Form::NLIndex 類別的 _html_col_article() 方法並改名為 _html_col_art() ;修正 Selima::htc::Checker::NLIndex 類別的 _check_article() 方法並改名為 _check_art()
    2. + +
    3. 修正 Selima::Form 類別的 _html_coltmpl_call() 方法及 _html_coltmpl_call_null() 方法,加上刪除欄位值的按鈕。
    4. + +
    5. 修正 Selima::Checker 類別,加上 _redir_delgrp() 方法;修正 Selima::Checker::UserPref 類別,加上 _redir_delusr() 方法;修正 Selima::Checker::GroupMem 類別及 Selima::Checker::UserMem 類別,加上 _redir_delmember() 方法;修正 Selima::Checker::LinkCatz 類別,加上 _redir_delcat() 方法及 _redir_dellink() 方法;修正 Selima::htc::Checker::NLIndex 類別,加上 _redir_delnewslet() 方法、 _redir_delparent() 方法及 _redir_delart() 方法;修正 Selima::htc::Checker::NLArt 類別及 Selima::wov::Checker::NLArt 類別,加上 _redir_delnewslet() 方法;修正 Selima::imacat::Checker::LtZhPoem 類別,加上 _redir_delset() 方法。
    6. + +
    7. 修正 Selima::UserName() 模組的 groupdsc() 函式, title_* 欄位改正為 dsc_* 欄位。
    8. + +
    9. 修正 usermem.cgi 程式及 groupmem.cgi 程式的 check_post() 函式,加上 delgrp 欄位及 delmember 欄位的重導向檢查;修正 userpref.cgi 程式的 check_post() 函式,加上 delusr 欄位的重導向檢查;修正 scptpriv.cgi 程式的 check_post() 函式,加上 delgrp 欄位的重導向檢查;修正 linkcatz.cgi 程式的 check_post() 函式,加上 delcat 欄位及 dellink 欄位的重導向檢查;修正 nlindex.cgi 程式的 check_post() 函式,加上 delnewslet 欄位、 delparent 欄位及 delart 欄位的重導向檢查;修正 nlarts.cgi 程式的 check_post() 函式,加上 delnewslet 欄位的重導向檢查;修正 ltzhpoem.cgi 程式的 check_post() 函式,現有表單加上 delset 欄位的重導向檢查,新表單加上原來漏掉的 selset 欄位及 delset 欄位的重導向檢查。
    10. + +
    11. 修正 Selima::htc::Form::Newslet 類別,加上 _html_col_index() 方法、 __html_col_index_cur() 方法及 __html_col_index_form() 方法,以遞迴呼叫顯示書目表格。
    12. + +
    13. 修正 Selima::htc::Checker::Newslet 類別,加上 _redir_selndxart() 方法及 _redir_delndxart() 方法。
    14. + +
    15. 修正 newslet.cgi 程式,加上 import_selndxart() 函式。
    16. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 7 | + 8 | + 9 | + 10 | + 11 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0009.html.zh-cn.html b/htdocs/imacat/me/changelog/0009.html.zh-cn.html new file mode 120000 index 0000000..f5e54b4 --- /dev/null +++ b/htdocs/imacat/me/changelog/0009.html.zh-cn.html @@ -0,0 +1 @@ +0009.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0009.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0009.html.zh-cn.xhtml new file mode 100644 index 0000000..07e9507 --- /dev/null +++ b/htdocs/imacat/me/changelog/0009.html.zh-cn.xhtml @@ -0,0 +1,456 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷九 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷九

    + +
    + +
    + +
    +
    日期: 11.17.’06.
    + +
      +
    1. 修正 Selima::Cache 模组与 Selima::FormFunc 模组,将 form 类快取更正为 formfunc ,快取变数 $Form_get_or_post$Form_curform$Form_isform$Form_formtype 分别更正为 $FormFunc_get_or_post$FormFunc_curform$FormFunc_isform$FormFunc_formtype
    2. +
    3. 修正 Selima::Cache 模组,加上变数类别 listfunc ,及快取变数 $ListFunc_listtype
    4. +
    5. 加上 Selima::ListFunc 模组,及 list_type() 函式。
    6. +
    7. 修正 books 资料表,加上 toborrow 栏位及 lib 栏位;修正 Selima::emandy::List::Books 类别,加上 toborrow 栏位及 lib 栏位的标签;修正 Selima::emandy::Form::Books 类别,加上 _html_col_toborrow() 函式及 _html_col_lib() 函式;修正 Selima::emandy::Checker::Books 类别,加上 _check_lib() 函式;修正 Selima::emandy::Processor::Books 类别,加上储存 toborrow 栏位及 lib 栏位;修正 books.cgi 程式,加上检查 lib 栏位。
    8. +
    9. 加上 Selima::emandy::List::Books::ToBorrow 类别及 Selima::emandy::List::Books::NotToBorrow 类别;修正 Selima::emandy::List::Books 类别,加上 $self->{"lists_switch"} ;修正 books.cgi 程式,依 list_type() 显示三种列表。
    10. +
    + +
    + +
    + +
    +
    日期: 11.16.’06.
    + +
      +
    1. 加上 emandy 网站的 books 资料表、 Selima::emandy::List::Books 类别、 Selima::emandy::Form::Book 类别、 Selima::emandy::Checker::Book 类别、 Selima::emandy::Processor::Book 类别及、 books.cgi 程式。
    2. +
    3. 修正 Selima::emandy::List::Public::Legend 类别,删除用不到的引用 Selima::LnInfo 模组、 Selima::PageFunc 模组与 :lninfo 类变数。
    4. +
    5. 修正 Selima::emandy::Checker::Legend 类别,加上注解 _check_title() 方法和 _check_body() 方法。
    6. +
    + +
    + +
    + +
    +
    日期: 11.15.’06.
    + +
      +
    1. 加上 emandy 网站的搜寻。
    2. +
    3. 修正 Selima::emandy::List::Search 类别的 html_list() 方法,加上 legend 类的处理。
    4. +
    5. 加上 emandy 资料库的 country 资料表内容。
    6. +
    7. 修正 country 资料表,加上简体中文的国名。
    8. +
    9. 修正 country 资料表,英文国名中 ’s 大写的错误,并改单引号为右单引号。
    10. +
    + +
    + +
    + +
    +
    日期: 11.15.’06.
    + +
      +
    1. 加上 emandy 网站。
    2. +
    3. 修正 users 资料表,加上主机名称 host 与国家 ct 记录栏位;修正 Selima::LogIn 模组的 upd_login_info() 函式,加上记录主机名称与国家;修正 Selima::List::Users 类别的 new() 方法,加上 host 栏位与 ct 栏位的标签;修正 Selima::Form::User 类别的 new() 方法,加上显示 host 栏位与 ct 栏位,并加上 _html_col_ct() 方法。
    4. +
    5. 修正 Selima::List::Guestbook 类别的 new() 方法,将 host 栏位的标签由 Hostname 改为 Host ;修正 Selima::Form 类别的 _html_col_host() 方法,将栏位的标签由 Hostname: 改为 Host:
    6. +
    + +
    + +
    + +
    +
    日期: 11.4.’06.
    + +
      +
    1. 修正 Selima::Init 模组的 checkspam_masslinks() 函式。
    2. +
    + +
    + +
    + +
    +
    日期: 10.30.’06.
    + +
      +
    1. 新增 funds 资料表、 Selima::imacat::List::Funds 类别及 funds.cgi 程式。
    2. +
    + +
    + +
    + +
    +
    日期: 10.20.’06.
    + +
      +
    1. 修正 Selima::DecForm 模组,删掉已未引用的 GDBM_File 模组。
    2. +
    + +
    + +
    + +
    +
    日期: 10.7.’06.
    + +
      +
    1. 修正 Selima::Mail 类别的 _out_trace() 方法, From-domain 原输出使用者端的 IP ,改输出 webclient ,比较适当,且避免 From IP 时 SpamAssassin 的高分数。
    2. +
    + +
    + +
    + +
    +
    日期: 9.13.’06.
    + +
      +
    1. 修正 Selima::DecForm 模组的 try_decode_form() 函式,去除表格值的零值 (\x00) 。
    2. +
    + +
    + +
    + +
    +
    日期: 8.27.’06.
    + +
      +
    1. 修正 lang.zh-cn.csscommon.zh-cn.css ,简体中文的引号改为全形的美式双、单引号(“…”与‘…’)。
    2. +
    + +
    + +
    + +
    +
    日期: 8.6.’06.
    + +
      +
    1. 修正 Selima::Checker 类别的 new() 方法, $$form{"sn"} 改正为 $form->param("sn")
    2. +
    + +
    + +
    + +
    +
    日期: 7.28.’06.
    + +
      +
    1. 修正 Selima::ReqURI 模组的 init_request_uri() 函式, $REQUEST_URI 不去掉前面的 $ROOT_DIFF$REQUEST_FULLURI 不用 $REQUEST_HOSTPORT ,改用 $REQUEST_SCHEME . "://" . $REQUEST_HOST . $port ,以避免重复加计 $ROOT_DIFF
    2. +
    + +
    + +
    + +
    +
    日期: 7.25.’06.
    + +
      +
    1. 修正 Selima::ReqURI 模组的 init_request_uri() 函式, $REQUEST_URI 在 mod_perl 或 Apache 下取得的值,去除前面的 $ROOT_DIFF
    2. + +
    3. 把百度搜寻引擎挡掉。百度太恶劣了!
    4. +
    + +
    + +
    + +
    +
    日期: 7.14.’06.
    + +
      +
    1. 修正 Selima::Form 类别的 new() 方法,依 PHP Monica ,原由 %CURRENT ,改由 $$form 取得 $checker->{"sn"}
    2. +
    + +
    + +
    + +
    +
    日期: 7.13.’06.
    + +
      +
    1. 修正 Selima::Form 类别,依 PHP Monica ,新增 _html_coltmpl_ro_textarea()_html_coltmpl_ro_date()_html_coltmpl_ro_title()_html_coltmpl_ro_radio() 方法;修正 _html_coltmpl_ro_*() 方法,加上 $prompt 提示讯息参数;修正 _html_coltmpl_*() 方法,提示讯息原用 <samp>…</samp> 标示,改用 <p>…</p> 标示。
    2. +
    + +
    + +
    + +
    +
    日期: 7.4.’06.
    + +
      +
    1. 修正 Selima::Encrypt 模组, Crypt::Blowfish 改用 Crypt::Rijndael_PPCrypt::Blowfish 只能加解密八个位元长度的资料,无法使用。 Crypt::Rijndael_PPCrypt::Rijndael 的纯 Perl 版本,以 Perl 实作 AES Rijndael 加解密演算法。这样就解决了 Crypt::Rijndael 尚不支援 x86_64 平台的问题。(谨向 Crypt::Rijndael_PP 作者 Christian Lackas 致谢。)
    2. + +
    3. 修正 Selima::Checker::User 类别,停用 fascist_check() 检查。 fascist_check() 的检查早已因停用 Crypt::Cracklib 而无法使用了。
    4. +
    + +
    + +
    + +
    +
    日期: 6.29.’06.
    + +
      +
    1. 修正 Selima::Mail 类别,加上 _out_trace() 方法,在寄信前,加上 Received: 邮件标头,以便追踪发信者。
    2. + +
    3. 修正 Selima::HTTP 模组的 http_500() 函式,侦错通知内容加上 POST 的表单及登入使用者的资讯。停用中文站名 $PACKAGE_TITLE$SITENAME_ABBR 改用英文,以免输出邮件时编码混乱。
    4. +
    + +
    + +
    + +
    +
    日期: 6.5.’06.
    + +
      +
    1. 修正 Selima::DBD::mysql ,把 ${$_} 简化为 $$_
    2. +
    + +
    + +
    + +
    +
    日期: 5.31.’06.
    + +
      +
    1. 修正 Selima::Unicode::hcref2char() 函式,若字元不需解码时,多加上分号的错误。
    2. +
    + +
    + +
    + +
    +
    日期: 5.23.’06.
    + +
      +
    1. 修正 Selima::imacat::Processor::Public::Garbage 类别,寄出通知信的网址应为 garbage.cgi ,误记为 guestbook.cgi
    2. +
    + +
    + +
    + +
    +
    日期: 5.19.’06.
    + +
      +
    1. 旅人留言簿变更档名,以回避自动贴文程式。
    2. + +
    3. 修正 Selima::InitSelima::Checker::Public::Guestbook ,回复对垃圾广告留言的延迟。
    4. +
    + +
    + +
    + +
    +
    日期: 5.15.’06.
    + +
      +
    1. 实验变更女声留言本名称,以躲避广告留言攻击。
    2. + +
    3. 修正 Selima::*::Processor::Public::Guestbook 类别,寄发通知信时,原用 $THIS_FILE 取得编修留言的档名,改直接设定档名。
    4. +
    + +
    + +
    + +
    +
    日期: 5.14.’06.
    + +
      +
    1. 更换伺服器。原伺服器为 Pentium III Coppermine 800MHz 、 220MB HD 、 896 MB SD RAM ,新伺服器为 Pentium D 3.2GHz Dual core 64 位元双核心、 250MB SATA2 HD 、 1024MB DDR-533 RAM 。
    2. + +
    3. 修正 Selima::Encrypt 模组,原用 Crypt::Rijndael (即 AES )加密,因 Crypt::Rijndael 久未更新,在 x86_64 下无法执行,改用 Crypt::Blowfish
    4. + +
    5. 修正 Selima::Checker::User 类别,暂时停用 Crypt::CracklibCrypt::Cracklib 久未更新,在 x86_64 下无法执行。
    6. + +
    7. %HTML::Entities::entity2char 的符号原先不含末尾的分号,现在含分号。修正 Selima::Unicode 模组的 hcref2char() 函式,以配合其修正。
    8. + +
    9. all2trad.dball2simp.db 两个资料库档,依不同平台( i386 及 x86_64 )分成两组不同的档案,分别存到不同的目录下。修正 Selima::Unicode 模组的 $ALL2TRAD$ALL2SIMP 两个档案档名,使用 File::Spec::Functionssplitdir()catdir()$Config{";myarchname";} 平台名称组合档名,以便跨平台相容。
    10. +
    + +
    + +
    + +
    +
    日期: 5.5.’06.
    + +
      +
    1. 修正 nlindex 资料表, article 栏位改名为 art ;修正 Selima::htc::List::NLIndex 类别的 new() 方法、 Selima::htc::Form::NLIndex 类别的 new() 方法、 Selima::htc::Processor::NLIndex 类别的 _save_cols() 方法及 nlindex.cgi 程式的 check_post() 函式;修正 Selima::htc::Form::NLIndex 类别的 _html_col_article() 方法并改名为 _html_col_art() ;修正 Selima::htc::Checker::NLIndex 类别的 _check_article() 方法并改名为 _check_art()
    2. + +
    3. 修正 Selima::Form 类别的 _html_coltmpl_call() 方法及 _html_coltmpl_call_null() 方法,加上删除栏位值的按钮。
    4. + +
    5. 修正 Selima::Checker 类别,加上 _redir_delgrp() 方法;修正 Selima::Checker::UserPref 类别,加上 _redir_delusr() 方法;修正 Selima::Checker::GroupMem 类别及 Selima::Checker::UserMem 类别,加上 _redir_delmember() 方法;修正 Selima::Checker::LinkCatz 类别,加上 _redir_delcat() 方法及 _redir_dellink() 方法;修正 Selima::htc::Checker::NLIndex 类别,加上 _redir_delnewslet() 方法、 _redir_delparent() 方法及 _redir_delart() 方法;修正 Selima::htc::Checker::NLArt 类别及 Selima::wov::Checker::NLArt 类别,加上 _redir_delnewslet() 方法;修正 Selima::imacat::Checker::LtZhPoem 类别,加上 _redir_delset() 方法。
    6. + +
    7. 修正 Selima::UserName() 模组的 groupdsc() 函式, title_* 栏位改正为 dsc_* 栏位。
    8. + +
    9. 修正 usermem.cgi 程式及 groupmem.cgi 程式的 check_post() 函式,加上 delgrp 栏位及 delmember 栏位的重导向检查;修正 userpref.cgi 程式的 check_post() 函式,加上 delusr 栏位的重导向检查;修正 scptpriv.cgi 程式的 check_post() 函式,加上 delgrp 栏位的重导向检查;修正 linkcatz.cgi 程式的 check_post() 函式,加上 delcat 栏位及 dellink 栏位的重导向检查;修正 nlindex.cgi 程式的 check_post() 函式,加上 delnewslet 栏位、 delparent 栏位及 delart 栏位的重导向检查;修正 nlarts.cgi 程式的 check_post() 函式,加上 delnewslet 栏位的重导向检查;修正 ltzhpoem.cgi 程式的 check_post() 函式,现有表单加上 delset 栏位的重导向检查,新表单加上原来漏掉的 selset 栏位及 delset 栏位的重导向检查。
    10. + +
    11. 修正 Selima::htc::Form::Newslet 类别,加上 _html_col_index() 方法、 __html_col_index_cur() 方法及 __html_col_index_form() 方法,以递回呼叫显示书目表格。
    12. + +
    13. 修正 Selima::htc::Checker::Newslet 类别,加上 _redir_selndxart() 方法及 _redir_delndxart() 方法。
    14. + +
    15. 修正 newslet.cgi 程式,加上 import_selndxart() 函式。
    16. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 7 | + 8 | + 9 | + 10 | + 11 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0009.html.zh-tw.html b/htdocs/imacat/me/changelog/0009.html.zh-tw.html new file mode 120000 index 0000000..fe6eec4 --- /dev/null +++ b/htdocs/imacat/me/changelog/0009.html.zh-tw.html @@ -0,0 +1 @@ +0009.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0009.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0009.html.zh-tw.xhtml new file mode 100644 index 0000000..9704fc0 --- /dev/null +++ b/htdocs/imacat/me/changelog/0009.html.zh-tw.xhtml @@ -0,0 +1,456 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷九 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷九

    + +
    + +
    + +
    +
    日期: 11.17.’06.
    + +
      +
    1. 修正 Selima::Cache 模組與 Selima::FormFunc 模組,將 form 類快取更正為 formfunc ,快取變數 $Form_get_or_post$Form_curform$Form_isform$Form_formtype 分別更正為 $FormFunc_get_or_post$FormFunc_curform$FormFunc_isform$FormFunc_formtype
    2. +
    3. 修正 Selima::Cache 模組,加上變數類別 listfunc ,及快取變數 $ListFunc_listtype
    4. +
    5. 加上 Selima::ListFunc 模組,及 list_type() 函式。
    6. +
    7. 修正 books 資料表,加上 toborrow 欄位及 lib 欄位;修正 Selima::emandy::List::Books 類別,加上 toborrow 欄位及 lib 欄位的標籤;修正 Selima::emandy::Form::Books 類別,加上 _html_col_toborrow() 函式及 _html_col_lib() 函式;修正 Selima::emandy::Checker::Books 類別,加上 _check_lib() 函式;修正 Selima::emandy::Processor::Books 類別,加上儲存 toborrow 欄位及 lib 欄位;修正 books.cgi 程式,加上檢查 lib 欄位。
    8. +
    9. 加上 Selima::emandy::List::Books::ToBorrow 類別及 Selima::emandy::List::Books::NotToBorrow 類別;修正 Selima::emandy::List::Books 類別,加上 $self->{"lists_switch"} ;修正 books.cgi 程式,依 list_type() 顯示三種列表。
    10. +
    + +
    + +
    + +
    +
    日期: 11.16.’06.
    + +
      +
    1. 加上 emandy 網站的 books 資料表、 Selima::emandy::List::Books 類別、 Selima::emandy::Form::Book 類別、 Selima::emandy::Checker::Book 類別、 Selima::emandy::Processor::Book 類別及、 books.cgi 程式。
    2. +
    3. 修正 Selima::emandy::List::Public::Legend 類別,刪除用不到的引用 Selima::LnInfo 模組、 Selima::PageFunc 模組與 :lninfo 類變數。
    4. +
    5. 修正 Selima::emandy::Checker::Legend 類別,加上註解 _check_title() 方法和 _check_body() 方法。
    6. +
    + +
    + +
    + +
    +
    日期: 11.15.’06.
    + +
      +
    1. 加上 emandy 網站的搜尋。
    2. +
    3. 修正 Selima::emandy::List::Search 類別的 html_list() 方法,加上 legend 類的處理。
    4. +
    5. 加上 emandy 資料庫的 country 資料表內容。
    6. +
    7. 修正 country 資料表,加上簡體中文的國名。
    8. +
    9. 修正 country 資料表,英文國名中 ’s 大寫的錯誤,並改單引號為右單引號。
    10. +
    + +
    + +
    + +
    +
    日期: 11.15.’06.
    + +
      +
    1. 加上 emandy 網站。
    2. +
    3. 修正 users 資料表,加上主機名稱 host 與國家 ct 記錄欄位;修正 Selima::LogIn 模組的 upd_login_info() 函式,加上記錄主機名稱與國家;修正 Selima::List::Users 類別的 new() 方法,加上 host 欄位與 ct 欄位的標籤;修正 Selima::Form::User 類別的 new() 方法,加上顯示 host 欄位與 ct 欄位,並加上 _html_col_ct() 方法。
    4. +
    5. 修正 Selima::List::Guestbook 類別的 new() 方法,將 host 欄位的標籤由 Hostname 改為 Host ;修正 Selima::Form 類別的 _html_col_host() 方法,將欄位的標籤由 Hostname: 改為 Host:
    6. +
    + +
    + +
    + +
    +
    日期: 11.4.’06.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_masslinks() 函式。
    2. +
    + +
    + +
    + +
    +
    日期: 10.30.’06.
    + +
      +
    1. 新增 funds 資料表、 Selima::imacat::List::Funds 類別及 funds.cgi 程式。
    2. +
    + +
    + +
    + +
    +
    日期: 10.20.’06.
    + +
      +
    1. 修正 Selima::DecForm 模組,刪掉已未引用的 GDBM_File 模組。
    2. +
    + +
    + +
    + +
    +
    日期: 10.7.’06.
    + +
      +
    1. 修正 Selima::Mail 類別的 _out_trace() 方法, From-domain 原輸出使用者端的 IP ,改輸出 webclient ,比較適當,且避免 From IP 時 SpamAssassin 的高分數。
    2. +
    + +
    + +
    + +
    +
    日期: 9.13.’06.
    + +
      +
    1. 修正 Selima::DecForm 模組的 try_decode_form() 函式,去除表格值的零值 (\x00) 。
    2. +
    + +
    + +
    + +
    +
    日期: 8.27.’06.
    + +
      +
    1. 修正 lang.zh-cn.csscommon.zh-cn.css ,簡體中文的引號改為全形的美式雙、單引號(“…”與‘…’)。
    2. +
    + +
    + +
    + +
    +
    日期: 8.6.’06.
    + +
      +
    1. 修正 Selima::Checker 類別的 new() 方法, $$form{"sn"} 改正為 $form->param("sn")
    2. +
    + +
    + +
    + +
    +
    日期: 7.28.’06.
    + +
      +
    1. 修正 Selima::ReqURI 模組的 init_request_uri() 函式, $REQUEST_URI 不去掉前面的 $ROOT_DIFF$REQUEST_FULLURI 不用 $REQUEST_HOSTPORT ,改用 $REQUEST_SCHEME . "://" . $REQUEST_HOST . $port ,以避免重複加計 $ROOT_DIFF
    2. +
    + +
    + +
    + +
    +
    日期: 7.25.’06.
    + +
      +
    1. 修正 Selima::ReqURI 模組的 init_request_uri() 函式, $REQUEST_URI 在 mod_perl 或 Apache 下取得的值,去除前面的 $ROOT_DIFF
    2. + +
    3. 把百度搜尋引擎擋掉。百度太惡劣了!
    4. +
    + +
    + +
    + +
    +
    日期: 7.14.’06.
    + +
      +
    1. 修正 Selima::Form 類別的 new() 方法,依 PHP Monica ,原由 %CURRENT ,改由 $$form 取得 $checker->{"sn"}
    2. +
    + +
    + +
    + +
    +
    日期: 7.13.’06.
    + +
      +
    1. 修正 Selima::Form 類別,依 PHP Monica ,新增 _html_coltmpl_ro_textarea()_html_coltmpl_ro_date()_html_coltmpl_ro_title()_html_coltmpl_ro_radio() 方法;修正 _html_coltmpl_ro_*() 方法,加上 $prompt 提示訊息參數;修正 _html_coltmpl_*() 方法,提示訊息原用 <samp>…</samp> 標示,改用 <p>…</p> 標示。
    2. +
    + +
    + +
    + +
    +
    日期: 7.4.’06.
    + +
      +
    1. 修正 Selima::Encrypt 模組, Crypt::Blowfish 改用 Crypt::Rijndael_PPCrypt::Blowfish 只能加解密八個位元長度的資料,無法使用。 Crypt::Rijndael_PPCrypt::Rijndael 的純 Perl 版本,以 Perl 實作 AES Rijndael 加解密演算法。這樣就解決了 Crypt::Rijndael 尚不支援 x86_64 平台的問題。(謹向 Crypt::Rijndael_PP 作者 Christian Lackas 致謝。)
    2. + +
    3. 修正 Selima::Checker::User 類別,停用 fascist_check() 檢查。 fascist_check() 的檢查早已因停用 Crypt::Cracklib 而無法使用了。
    4. +
    + +
    + +
    + +
    +
    日期: 6.29.’06.
    + +
      +
    1. 修正 Selima::Mail 類別,加上 _out_trace() 方法,在寄信前,加上 Received: 郵件標頭,以便追蹤發信者。
    2. + +
    3. 修正 Selima::HTTP 模組的 http_500() 函式,偵錯通知內容加上 POST 的表單及登入使用者的資訊。停用中文站名 $PACKAGE_TITLE$SITENAME_ABBR 改用英文,以免輸出郵件時編碼混亂。
    4. +
    + +
    + +
    + +
    +
    日期: 6.5.’06.
    + +
      +
    1. 修正 Selima::DBD::mysql ,把 ${$_} 簡化為 $$_
    2. +
    + +
    + +
    + +
    +
    日期: 5.31.’06.
    + +
      +
    1. 修正 Selima::Unicode::hcref2char() 函式,若字元不需解碼時,多加上分號的錯誤。
    2. +
    + +
    + +
    + +
    +
    日期: 5.23.’06.
    + +
      +
    1. 修正 Selima::imacat::Processor::Public::Garbage 類別,寄出通知信的網址應為 garbage.cgi ,誤記為 guestbook.cgi
    2. +
    + +
    + +
    + +
    +
    日期: 5.19.’06.
    + +
      +
    1. 旅人留言簿變更檔名,以迴避自動貼文程式。
    2. + +
    3. 修正 Selima::InitSelima::Checker::Public::Guestbook ,回復對垃圾廣告留言的延遲。
    4. +
    + +
    + +
    + +
    +
    日期: 5.15.’06.
    + +
      +
    1. 實驗變更女聲留言本名稱,以躲避廣告留言攻擊。
    2. + +
    3. 修正 Selima::*::Processor::Public::Guestbook 類別,寄發通知信時,原用 $THIS_FILE 取得編修留言的檔名,改直接設定檔名。
    4. +
    + +
    + +
    + +
    +
    日期: 5.14.’06.
    + +
      +
    1. 更換伺服器。原伺服器為 Pentium III Coppermine 800MHz 、 220MB HD 、 896 MB SD RAM ,新伺服器為 Pentium D 3.2GHz Dual core 64 位元雙核心、 250MB SATA2 HD 、 1024MB DDR-533 RAM 。
    2. + +
    3. 修正 Selima::Encrypt 模組,原用 Crypt::Rijndael (即 AES )加密,因 Crypt::Rijndael 久未更新,在 x86_64 下無法執行,改用 Crypt::Blowfish
    4. + +
    5. 修正 Selima::Checker::User 類別,暫時停用 Crypt::CracklibCrypt::Cracklib 久未更新,在 x86_64 下無法執行。
    6. + +
    7. %HTML::Entities::entity2char 的符號原先不含末尾的分號,現在含分號。修正 Selima::Unicode 模組的 hcref2char() 函式,以配合其修正。
    8. + +
    9. all2trad.dball2simp.db 兩個資料庫檔,依不同平台( i386 及 x86_64 )分成兩組不同的檔案,分別存到不同的目錄下。修正 Selima::Unicode 模組的 $ALL2TRAD$ALL2SIMP 兩個檔案檔名,使用 File::Spec::Functionssplitdir()catdir()$Config{";myarchname";} 平台名稱組合檔名,以便跨平台相容。
    10. +
    + +
    + +
    + +
    +
    日期: 5.5.’06.
    + +
      +
    1. 修正 nlindex 資料表, article 欄位改名為 art ;修正 Selima::htc::List::NLIndex 類別的 new() 方法、 Selima::htc::Form::NLIndex 類別的 new() 方法、 Selima::htc::Processor::NLIndex 類別的 _save_cols() 方法及 nlindex.cgi 程式的 check_post() 函式;修正 Selima::htc::Form::NLIndex 類別的 _html_col_article() 方法並改名為 _html_col_art() ;修正 Selima::htc::Checker::NLIndex 類別的 _check_article() 方法並改名為 _check_art()
    2. + +
    3. 修正 Selima::Form 類別的 _html_coltmpl_call() 方法及 _html_coltmpl_call_null() 方法,加上刪除欄位值的按鈕。
    4. + +
    5. 修正 Selima::Checker 類別,加上 _redir_delgrp() 方法;修正 Selima::Checker::UserPref 類別,加上 _redir_delusr() 方法;修正 Selima::Checker::GroupMem 類別及 Selima::Checker::UserMem 類別,加上 _redir_delmember() 方法;修正 Selima::Checker::LinkCatz 類別,加上 _redir_delcat() 方法及 _redir_dellink() 方法;修正 Selima::htc::Checker::NLIndex 類別,加上 _redir_delnewslet() 方法、 _redir_delparent() 方法及 _redir_delart() 方法;修正 Selima::htc::Checker::NLArt 類別及 Selima::wov::Checker::NLArt 類別,加上 _redir_delnewslet() 方法;修正 Selima::imacat::Checker::LtZhPoem 類別,加上 _redir_delset() 方法。
    6. + +
    7. 修正 Selima::UserName() 模組的 groupdsc() 函式, title_* 欄位改正為 dsc_* 欄位。
    8. + +
    9. 修正 usermem.cgi 程式及 groupmem.cgi 程式的 check_post() 函式,加上 delgrp 欄位及 delmember 欄位的重導向檢查;修正 userpref.cgi 程式的 check_post() 函式,加上 delusr 欄位的重導向檢查;修正 scptpriv.cgi 程式的 check_post() 函式,加上 delgrp 欄位的重導向檢查;修正 linkcatz.cgi 程式的 check_post() 函式,加上 delcat 欄位及 dellink 欄位的重導向檢查;修正 nlindex.cgi 程式的 check_post() 函式,加上 delnewslet 欄位、 delparent 欄位及 delart 欄位的重導向檢查;修正 nlarts.cgi 程式的 check_post() 函式,加上 delnewslet 欄位的重導向檢查;修正 ltzhpoem.cgi 程式的 check_post() 函式,現有表單加上 delset 欄位的重導向檢查,新表單加上原來漏掉的 selset 欄位及 delset 欄位的重導向檢查。
    10. + +
    11. 修正 Selima::htc::Form::Newslet 類別,加上 _html_col_index() 方法、 __html_col_index_cur() 方法及 __html_col_index_form() 方法,以遞迴呼叫顯示書目表格。
    12. + +
    13. 修正 Selima::htc::Checker::Newslet 類別,加上 _redir_selndxart() 方法及 _redir_delndxart() 方法。
    14. + +
    15. 修正 newslet.cgi 程式,加上 import_selndxart() 函式。
    16. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 7 | + 8 | + 9 | + 10 | + 11 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0010.html.en.html b/htdocs/imacat/me/changelog/0010.html.en.html new file mode 120000 index 0000000..bf86cc6 --- /dev/null +++ b/htdocs/imacat/me/changelog/0010.html.en.html @@ -0,0 +1 @@ +0010.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0010.html.en.xhtml b/htdocs/imacat/me/changelog/0010.html.en.xhtml new file mode 100644 index 0000000..d077cbb --- /dev/null +++ b/htdocs/imacat/me/changelog/0010.html.en.xhtml @@ -0,0 +1,346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 10 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 10

    + +
    + +
    + +
    +
    Date: 3.11.’07.
    + +

    預備昇級 Apache 2 + mod_perl 2 。

    + +
      +
    1. 修正 Selima::DataVars 模組,加上 $IS_MP2 ,偵測 mod_perl 的版本是否為第二版。
    2. +
    3. 修正 Selima::HTTP 模組和 Selima::AuthDig 類別,原先由 Apache::Constants 匯入常數,改依 $IS_MP2 判斷,由 Apache::ConstantsApache2::Const 匯入常數。
    4. +
    5. 修正 Selima::CallForm 模組、 Selima::DecForm 模組、 Selima::FormFunc 模組、 Selima::GeoIP 模組、 Selima::HTTP 模組、 Selima::Init 模組、 Selima::LogIn 模組、 Selima::LogOut 模組、 Selima::Logging 模組、 Selima::RemoHost 模組、 Selima::ReqURI 模組、 Selima::XHTML 模組、 Selima::Destroy 類別、 Selima::List 類別、 Selima::ListPref 類別、 Selima::Mail 類別、 Selima::Session 類別、 Selima::*::Processor::Public::Guestbook 類別和 Selima::imacat::Processor::Public::Garbage 類別,原先使用 Apache->request() 物件,改依 $IS_MP2 判斷,使用 Apache->request()Apache2::RequestUtil->request() 物件。
    6. +
    7. 修正 startup.pl 程式,只在 mod_perl 1 下載入 Selima::AuthDig 類別。我暫時找不到 mod_perl 2 下用的 Digest 登入模組,暫時回歸使用密碼檔的舊方式。
    8. +
    9. 修正 Selima::GeoIP 模組、 Selima::HTTP 模組、 Selima::LogIn 模組、 Selima::Logging 模組、 Selima::RemoHost 模組、 Selima::Mail 類、 Selima::Session 類別及showenv.cgi 程式,若在 mod_perl 2 下,則載入 Apache2::Connection 類別。
    10. +
    11. 修正 Selima::DecForm 模組、 Selima::Init 模組、 Selima::LogOut 模組、 Selima::XHTML 模組及 Selima::ListPref 類別,原用 $r->header_in() 方法,改用 $r->headers_in()->get() 方法、 $r->headers_in()->add() 方法及 $r->headers_in()->set() 方法。
    12. +
    13. 修正 showenv.cgi 程式,加上在 mod_perl 2 下載入 Apache2::ServerRec 類別,並修正在 mod_perl 2 下時,顯示的 $r->connection()$r->server() 下的方法名稱;顯示方法名稱時,顯示的方法符號 -> 修正為 -&gt;
    14. +
    15. 修正 Selima::RemoHost 模組,原用 $r->get_remote_host() 方法,修正為依 $IS_MP2 判斷,使用 $r->connection()->get_remote_host() 方法或 $r->get_remote_host() 方法。
    16. +
    + +
    + +
    + +
    +
    Date: 3.10.’07.
    + +
      +
    1. 修正 Selima::ReqURI 模組的 init_request_uri() 函式,計算 $REQUEST_URI$REQUEST_PATH 碰到絕對網址時,移除通訊協定和主機名稱。
    2. +
    + +
    + +
    + +
    +
    Date: 2.12.’07.
    + +
      +
    1. Selima::MnglMail 模組改名為 Selima::MungAddr 模組;修正 Selima 模組、 Selima::A2HTML 模組、 Selima::List::Public::Guestbook 類別、 Selima::Checker::MailTo 類別及 Selima::*::HTML 模組,將 mangle_* 函數更名為 mung_* 函數,註解中的 mangle 更正為 mung
    2. +
    + +
    + +
    + +
    +
    Date: 2.4.’07.
    + +
      +
    1. 修正 Selima::Init 模組,修正 checkspam_reqheads() 函式,加上新的規則;加上 checkspam_escurl() 函式。
    2. +
    + +
    + +
    + +
    +
    Date: 2.1.’07.
    + +
      +
    1. 修正 Selima::Process 類別的 process() 方法,未確認表單時,原未傳回任何值,改傳回 {"preview"=>1} ,以使其後的表單得知可否預覽;修正 Selima::Form 類別的 _html_preview_link() 方法,原檢查 ${$self->{"status"}}{"error"} ,改檢查 ${$self->{"status"}}{"preview"} ,以得知可否預覽。
    2. +
    3. 修正 Selima::Form 類別的 _html_preview_link() 方法的註解, Bounce when not preview 改為 Bounce when preview is not available for this form
    4. +
    + +
    + +
    + +
    +
    Date: 1.23.’07.
    + +
      +
    1. 修正 Selima::Preview 模組,加上 html_preview_mark() 函式,預覽時顯示預覽標印;加上引用 Selima::HTTP 模組、 Selima::PageFunc 模組、 Selima::ReqURI 模組;修正 Selima::*::HTML 模組的 html_footer() 函式,加上呼叫 html_preview_mark() 函式;修正 common.css 樣式表,加上 .previewmark 預覽標印的樣式。
    2. +
    + +
    + +
    + +
    +
    Date: 1.21.’07.
    + +
      +
    1. 修正Selima::emandy::Processor::Legend 類別、 Selima::imacat::Processor::ChangeLog 類別、 Selima::imacat::Processor::Diary 類別、 Selima::imacat::Processor::LiteralEn 類別、 Selima::imacat::Processor::LiteralZh 類別、 Selima::wov::Processor::Newslet 類別 _rebuild_partial_pages() 方法的註解, Check if there are shown parts affected 修正為 Check if there is any shown part affected
    2. +
    3. 修正 Selima::Format 模組 fmtsize() 函式的註解, Bounce if there are less than 3 digits in the rounded result 修正為 Bounce if there are fewer than 3 digits in the rounded result
    4. +
    5. 修正 Selima::List 類別、 Selima::List::* 類別與 Selima::*::List::* 類別 liststat_message() 方法的註解, Result more than 1 page 修正為 More than one pageResult less than 1 page 修正為 Fit in one page
    6. +
    7. 修正 Selima::imacat::HTML 模組與 Selima::wov::HTML 模組 html_*_pagebar() 函式的註解, No more than 1 page - no page bar is needed 修正為 Fit in one page - paging is not neededLess than 7 pages 修正為 Fewer than 7 pages ;修正 Selima::List 類別 html_pagebar() 方法的註解, Less than 1 page - no page bar is needed 修正為 Fit in one page - paging is not neededLess than 5 pages 修正為 Fewer than 5 pagesNear the END 修正為 Near the end
    8. +
    9. 修正 Selima::imacat::Processor::LiteralEn 模組與 Selima::imacat::Processor::LiteralZh 模組 _rebuild_partial_pages() 函式的註解, We have 6 more to the first -- rebuild the previous 3 修正為 We have 6 more pages to the first - rebuild the previous 3 pagesIf less than 6, start from the first for page bar sliding 修正為 If fewer than 6 pages, start from the first for page bar slidingWe have 6 more to the end -- rebuild the next 3 修正為 We have 6 more pages to the end - rebuild the next 3 pagesIf less than 6, build to the end for page bar sliding 修正為 If fewer than 6 pages, build to the end for page bar sliding
    10. +
    + +
    + +
    + +
    +
    Date: 1.21.’07.
    + +
      +
    1. 修正 Selima::Links 模組、 Selima::UserName 模組、 Selima::Country 模組、 Selima::*::Items 模組的註解, Bounce if there is problem with … 修正為 Bounce if there is any problem with …
    2. +
    3. 修正 Selima::List 類別,將 colval() 方法移至可重載方法區。
    4. +
    + +
    + +
    + +
    +
    Date: 1.10.’07.
    + +
      +
    1. 修正 Selima::*::List::Funds 類別,重寫 html_search() 方法,加上進階篩選條件欄位;修正 pre_filter() 方法,改傳回進階篩選條件欄位;修正 new() 方法, $self->{"pre_filter"} 改列預先定義的進階篩選條件;修正 funds.cgi ,移除對 $LIST->{"pre_filter"} 的預先定義。
    2. +
    + +
    + +
    + +
    +
    Date: 1.9.’07.
    + +
      +
    1. 修正 Selima::Checker::User 類別,加回之前暫時取消的 Crypt::Cracklib 密碼檢查,並根據 cracklib/fscist.c 中各種檢查結果,回傳適當的錯誤訊息,並加上中譯。
    2. +
    + +
    + +
    + +
    +
    Date: 1.1.’07.
    + +
      +
    1. 修正 funds_list* 檢視, m*ranky*rank 改顯示排名/同類基金數;加上 _m*rank_y*rank 顯示原來的數字排名;修正 Selima::*::List::Funds 類別,加上覆寫 sql_filter() 方法和 sql_orderby() 方法,將排名欄位前置 _ ,以數字排名為基準瀏覽資料;修正 new() 方法,加上 $self->{"COLS_NO_DISPLAY"} ,不顯示數字排名,只顯示排名/同類基金數
    2. +
    3. 修正 funds 資料表,將 majcatmincat 欄位改為 cat0cat1cat2cat3 欄位;修正 Selima::*::List::Funds 類別的 new() 方法, col_labels 加上 cat0cat1cat2cat3 欄位。
    4. +
    + +
    + +
    + +
    +
    Date: 12.30.’06.
    + +
      +
    1. emily 加上 funds 資料表、 Selima::emily::List::Funds 類別與 funds.cgi 程式。
    2. +
    3. 修正 Selima::imacat::List::Funds 類別的註解,移除程式說明多餘的旅舍兩個字。
    4. +
    + +
    + +
    + +
    +
    Date: 12.1.’06.
    + +
      +
    1. 修正 material 資料表、 Selima::emandy::List::Material 類別、Selima::emandy::Form::Material 類別、Selima::emandy::Checker::Material 類別、Selima::emandy::Processor::Material 類別及 material.cgi 程式,加上 author 欄位。
    2. +
    + +
    + +
    + +
    +
    Date: 11.23.’06.
    + +
      +
    1. 修正 Selima::emandy::Form::Book 類別的 new() 方法,資料表名誤植為 legend ,修正為 books
    2. +
    3. 修正許多程式的 fetch_curitem() 函式,移除沒有用到的 $error 變數及 $count 變數。
    4. +
    5. 修正 legend.cgi 程式與 books.cgi 程式,移除未引用的 Encode::HanConvert 類別,及未使用的 zhsync 重導向檢查。
    6. +
    7. 修正 Selima::emandy::Items 模組,所有的函式都是之前 htc 網站用,複製後未整理移除,移除之;加上 mtrltype_options() 函式。
    8. +
    9. 修正 Selima::Form::LinkCat 類別與 Selima::htc::Form::NLIndex 類別的 new() 方法,原用 $CURRENT{"*count"} ,改用 $self->{"cur"}->param("*count") ,取得項目數;移除不需要的引用 dataman 類變數。
    10. +
    + +
    + +
    + +
    +
    Date: 11.22.’06.
    + +
      +
    1. 加上 mtrltype 資料表及 material 資料表。
    2. +
    + +
    + +
    + +
    +
    Date: 11.17.’06.
    + +
      +
    1. 修正 Selima::Form 模組的 _html_coltmpl_call()_html_coltmpl_call_null() 方法,修正顯示刪除鈕的邏輯,將刪除鈕和選擇鈕接在一起。
    2. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 8 | + 9 | + 10 | + 11 | + 12 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0010.html.zh-cn.html b/htdocs/imacat/me/changelog/0010.html.zh-cn.html new file mode 120000 index 0000000..5b21356 --- /dev/null +++ b/htdocs/imacat/me/changelog/0010.html.zh-cn.html @@ -0,0 +1 @@ +0010.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0010.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0010.html.zh-cn.xhtml new file mode 100644 index 0000000..8fd4ce7 --- /dev/null +++ b/htdocs/imacat/me/changelog/0010.html.zh-cn.xhtml @@ -0,0 +1,345 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷十 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷十

    + +
    + +
    + +
    +
    日期: 3.11.’07.
    + +

    预备升级 Apache 2 + mod_perl 2 。

    + +
      +
    1. 修正 Selima::DataVars 模组,加上 $IS_MP2 ,侦测 mod_perl 的版本是否为第二版。
    2. +
    3. 修正 Selima::HTTP 模组和 Selima::AuthDig 类别,原先由 Apache::Constants 汇入常数,改依 $IS_MP2 判断,由 Apache::ConstantsApache2::Const 汇入常数。
    4. +
    5. 修正 Selima::CallForm 模组、 Selima::DecForm 模组、 Selima::FormFunc 模组、 Selima::GeoIP 模组、 Selima::HTTP 模组、 Selima::Init 模组、 Selima::LogIn 模组、 Selima::LogOut 模组、 Selima::Logging 模组、 Selima::RemoHost 模组、 Selima::ReqURI 模组、 Selima::XHTML 模组、 Selima::Destroy 类别、 Selima::List 类别、 Selima::ListPref 类别、 Selima::Mail 类别、 Selima::Session 类别、 Selima::*::Processor::Public::Guestbook 类别和 Selima::imacat::Processor::Public::Garbage 类别,原先使用 Apache->request() 物件,改依 $IS_MP2 判断,使用 Apache->request()Apache2::RequestUtil->request() 物件。
    6. +
    7. 修正 startup.pl 程式,只在 mod_perl 1 下载入 Selima::AuthDig 类别。我暂时找不到 mod_perl 2 下用的 Digest 登入模组,暂时回归使用密码档的旧方式。
    8. +
    9. 修正 Selima::GeoIP 模组、 Selima::HTTP 模组、 Selima::LogIn 模组、 Selima::Logging 模组、 Selima::RemoHost 模组、 Selima::Mail 类、 Selima::Session 类别及showenv.cgi 程式,若在 mod_perl 2 下,则载入 Apache2::Connection 类别。
    10. +
    11. 修正 Selima::DecForm 模组、 Selima::Init 模组、 Selima::LogOut 模组、 Selima::XHTML 模组及 Selima::ListPref 类别,原用 $r->header_in() 方法,改用 $r->headers_in()->get() 方法、 $r->headers_in()->add() 方法及 $r->headers_in()->set() 方法。
    12. +
    13. 修正 showenv.cgi 程式,加上在 mod_perl 2 下载入 Apache2::ServerRec 类别,并修正在 mod_perl 2 下时,显示的 $r->connection()$r->server() 下的方法名称;显示方法名称时,显示的方法符号 -> 修正为 -&gt;
    14. +
    15. 修正 Selima::RemoHost 模组,原用 $r->get_remote_host() 方法,修正为依 $IS_MP2 判断,使用 $r->connection()->get_remote_host() 方法或 $r->get_remote_host() 方法。
    16. +
    + +
    + +
    + +
    +
    日期: 3.10.’07.
    + +
      +
    1. 修正 Selima::ReqURI 模组的 init_request_uri() 函式,计算 $REQUEST_URI$REQUEST_PATH 碰到绝对网址时,移除通讯协定和主机名称。
    2. +
    + +
    + +
    + +
    +
    日期: 2.12.’07.
    + +
      +
    1. Selima::MnglMail 模组改名为 Selima::MungAddr 模组;修正 Selima 模组、 Selima::A2HTML 模组、 Selima::List::Public::Guestbook 类别、 Selima::Checker::MailTo 类别及 Selima::*::HTML 模组,将 mangle_* 函数更名为 mung_* 函数,注解中的 mangle 更正为 mung
    2. +
    + +
    + +
    + +
    +
    日期: 2.4.’07.
    + +
      +
    1. 修正 Selima::Init 模组,修正 checkspam_reqheads() 函式,加上新的规则;加上 checkspam_escurl() 函式。
    2. +
    + +
    + +
    + +
    +
    日期: 2.1.’07.
    + +
      +
    1. 修正 Selima::Process 类别的 process() 方法,未确认表单时,原未传回任何值,改传回 {"preview"=>1} ,以使其后的表单得知可否预览;修正 Selima::Form 类别的 _html_preview_link() 方法,原检查 ${$self->{"status"}}{"error"} ,改检查 ${$self->{"status"}}{"preview"} ,以得知可否预览。
    2. +
    3. 修正 Selima::Form 类别的 _html_preview_link() 方法的注解, Bounce when not preview 改为 Bounce when preview is not available for this form
    4. +
    + +
    + +
    + +
    +
    日期: 1.23.’07.
    + +
      +
    1. 修正 Selima::Preview 模组,加上 html_preview_mark() 函式,预览时显示预览标印;加上引用 Selima::HTTP 模组、 Selima::PageFunc 模组、 Selima::ReqURI 模组;修正 Selima::*::HTML 模组的 html_footer() 函式,加上呼叫 html_preview_mark() 函式;修正 common.css 样式表,加上 .previewmark 预览标印的样式。
    2. +
    + +
    + +
    + +
    +
    日期: 1.21.’07.
    + +
      +
    1. 修正Selima::emandy::Processor::Legend 类别、 Selima::imacat::Processor::ChangeLog 类别、 Selima::imacat::Processor::Diary 类别、 Selima::imacat::Processor::LiteralEn 类别、 Selima::imacat::Processor::LiteralZh 类别、 Selima::wov::Processor::Newslet 类别 _rebuild_partial_pages() 方法的注解, Check if there are shown parts affected 修正为 Check if there is any shown part affected
    2. +
    3. 修正 Selima::Format 模组 fmtsize() 函式的注解, Bounce if there are less than 3 digits in the rounded result 修正为 Bounce if there are fewer than 3 digits in the rounded result
    4. +
    5. 修正 Selima::List 类别、 Selima::List::* 类别与 Selima::*::List::* 类别 liststat_message() 方法的注解, Result more than 1 page 修正为 More than one pageResult less than 1 page 修正为 Fit in one page
    6. +
    7. 修正 Selima::imacat::HTML 模组与 Selima::wov::HTML 模组 html_*_pagebar() 函式的注解, No more than 1 page - no page bar is needed 修正为 Fit in one page - paging is not neededLess than 7 pages 修正为 Fewer than 7 pages ;修正 Selima::List 类别 html_pagebar() 方法的注解, Less than 1 page - no page bar is needed 修正为 Fit in one page - paging is not neededLess than 5 pages 修正为 Fewer than 5 pagesNear the END 修正为 Near the end
    8. +
    9. 修正 Selima::imacat::Processor::LiteralEn 模组与 Selima::imacat::Processor::LiteralZh 模组 _rebuild_partial_pages() 函式的注解, We have 6 more to the first -- rebuild the previous 3 修正为 We have 6 more pages to the first - rebuild the previous 3 pagesIf less than 6, start from the first for page bar sliding 修正为 If fewer than 6 pages, start from the first for page bar slidingWe have 6 more to the end -- rebuild the next 3 修正为 We have 6 more pages to the end - rebuild the next 3 pagesIf less than 6, build to the end for page bar sliding 修正为 If fewer than 6 pages, build to the end for page bar sliding
    10. +
    + +
    + +
    + +
    +
    日期: 1.21.’07.
    + +
      +
    1. 修正 Selima::Links 模组、 Selima::UserName 模组、 Selima::Country 模组、 Selima::*::Items 模组的注解, Bounce if there is problem with … 修正为 Bounce if there is any problem with …
    2. +
    3. 修正 Selima::List 类别,将 colval() 方法移至可重载方法区。
    4. +
    + +
    + +
    + +
    +
    日期: 1.10.’07.
    + +
      +
    1. 修正 Selima::*::List::Funds 类别,重写 html_search() 方法,加上进阶筛选条件栏位;修正 pre_filter() 方法,改传回进阶筛选条件栏位;修正 new() 方法, $self->{"pre_filter"} 改列预先定义的进阶筛选条件;修正 funds.cgi ,移除对 $LIST->{"pre_filter"} 的预先定义。
    2. +
    + +
    + +
    + +
    +
    日期: 1.9.’07.
    + +
      +
    1. 修正 Selima::Checker::User 类别,加回之前暂时取消的 Crypt::Cracklib 密码检查,并根据 cracklib/fscist.c 中各种检查结果,回传适当的错误讯息,并加上中译。
    2. +
    + +
    + +
    + +
    +
    日期: 1.1.’07.
    + +
      +
    1. 修正 funds_list* 检视, m*ranky*rank 改显示排名/同类基金数;加上 _m*rank_y*rank 显示原来的数字排名;修正 Selima::*::List::Funds 类别,加上覆写 sql_filter() 方法和 sql_orderby() 方法,将排名栏位前置 _ ,以数字排名为基准浏览资料;修正 new() 方法,加上 $self->{"COLS_NO_DISPLAY"} ,不显示数字排名,只显示排名/同类基金数
    2. +
    3. 修正 funds 资料表,将 majcatmincat 栏位改为 cat0cat1cat2cat3 栏位;修正 Selima::*::List::Funds 类别的 new() 方法, col_labels 加上 cat0cat1cat2cat3 栏位。
    4. +
    + +
    + +
    + +
    +
    日期: 12.30.’06.
    + +
      +
    1. emily 加上 funds 资料表、 Selima::emily::List::Funds 类别与 funds.cgi 程式。
    2. +
    3. 修正 Selima::imacat::List::Funds 类别的注解,移除程式说明多余的旅舍两个字。
    4. +
    + +
    + +
    + +
    +
    日期: 12.1.’06.
    + +
      +
    1. 修正 material 资料表、 Selima::emandy::List::Material 类别、Selima::emandy::Form::Material 类别、Selima::emandy::Checker::Material 类别、Selima::emandy::Processor::Material 类别及 material.cgi 程式,加上 author 栏位。
    2. +
    + +
    + +
    + +
    +
    日期: 11.23.’06.
    + +
      +
    1. 修正 Selima::emandy::Form::Book 类别的 new() 方法,资料表名误植为 legend ,修正为 books
    2. +
    3. 修正许多程式的 fetch_curitem() 函式,移除没有用到的 $error 变数及 $count 变数。
    4. +
    5. 修正 legend.cgi 程式与 books.cgi 程式,移除未引用的 Encode::HanConvert 类别,及未使用的 zhsync 重导向检查。
    6. +
    7. 修正 Selima::emandy::Items 模组,所有的函式都是之前 htc 网站用,复制后未整理移除,移除之;加上 mtrltype_options() 函式。
    8. +
    9. 修正 Selima::Form::LinkCat 类别与 Selima::htc::Form::NLIndex 类别的 new() 方法,原用 $CURRENT{"*count"} ,改用 $self->{"cur"}->param("*count") ,取得项目数;移除不需要的引用 dataman 类变数。
    10. +
    + +
    + +
    + +
    +
    日期: 11.22.’06.
    + +
      +
    1. 加上 mtrltype 资料表及 material 资料表。
    2. +
    + +
    + +
    + +
    +
    日期: 11.17.’06.
    + +
      +
    1. 修正 Selima::Form 模组的 _html_coltmpl_call()_html_coltmpl_call_null() 方法,修正显示删除钮的逻辑,将删除钮和选择钮接在一起。
    2. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 8 | + 9 | + 10 | + 11 | + 12 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0010.html.zh-tw.html b/htdocs/imacat/me/changelog/0010.html.zh-tw.html new file mode 120000 index 0000000..61f46bc --- /dev/null +++ b/htdocs/imacat/me/changelog/0010.html.zh-tw.html @@ -0,0 +1 @@ +0010.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0010.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0010.html.zh-tw.xhtml new file mode 100644 index 0000000..40cd23c --- /dev/null +++ b/htdocs/imacat/me/changelog/0010.html.zh-tw.xhtml @@ -0,0 +1,345 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷十 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷十

    + +
    + +
    + +
    +
    日期: 3.11.’07.
    + +

    預備昇級 Apache 2 + mod_perl 2 。

    + +
      +
    1. 修正 Selima::DataVars 模組,加上 $IS_MP2 ,偵測 mod_perl 的版本是否為第二版。
    2. +
    3. 修正 Selima::HTTP 模組和 Selima::AuthDig 類別,原先由 Apache::Constants 匯入常數,改依 $IS_MP2 判斷,由 Apache::ConstantsApache2::Const 匯入常數。
    4. +
    5. 修正 Selima::CallForm 模組、 Selima::DecForm 模組、 Selima::FormFunc 模組、 Selima::GeoIP 模組、 Selima::HTTP 模組、 Selima::Init 模組、 Selima::LogIn 模組、 Selima::LogOut 模組、 Selima::Logging 模組、 Selima::RemoHost 模組、 Selima::ReqURI 模組、 Selima::XHTML 模組、 Selima::Destroy 類別、 Selima::List 類別、 Selima::ListPref 類別、 Selima::Mail 類別、 Selima::Session 類別、 Selima::*::Processor::Public::Guestbook 類別和 Selima::imacat::Processor::Public::Garbage 類別,原先使用 Apache->request() 物件,改依 $IS_MP2 判斷,使用 Apache->request()Apache2::RequestUtil->request() 物件。
    6. +
    7. 修正 startup.pl 程式,只在 mod_perl 1 下載入 Selima::AuthDig 類別。我暫時找不到 mod_perl 2 下用的 Digest 登入模組,暫時回歸使用密碼檔的舊方式。
    8. +
    9. 修正 Selima::GeoIP 模組、 Selima::HTTP 模組、 Selima::LogIn 模組、 Selima::Logging 模組、 Selima::RemoHost 模組、 Selima::Mail 類、 Selima::Session 類別及showenv.cgi 程式,若在 mod_perl 2 下,則載入 Apache2::Connection 類別。
    10. +
    11. 修正 Selima::DecForm 模組、 Selima::Init 模組、 Selima::LogOut 模組、 Selima::XHTML 模組及 Selima::ListPref 類別,原用 $r->header_in() 方法,改用 $r->headers_in()->get() 方法、 $r->headers_in()->add() 方法及 $r->headers_in()->set() 方法。
    12. +
    13. 修正 showenv.cgi 程式,加上在 mod_perl 2 下載入 Apache2::ServerRec 類別,並修正在 mod_perl 2 下時,顯示的 $r->connection()$r->server() 下的方法名稱;顯示方法名稱時,顯示的方法符號 -> 修正為 -&gt;
    14. +
    15. 修正 Selima::RemoHost 模組,原用 $r->get_remote_host() 方法,修正為依 $IS_MP2 判斷,使用 $r->connection()->get_remote_host() 方法或 $r->get_remote_host() 方法。
    16. +
    + +
    + +
    + +
    +
    日期: 3.10.’07.
    + +
      +
    1. 修正 Selima::ReqURI 模組的 init_request_uri() 函式,計算 $REQUEST_URI$REQUEST_PATH 碰到絕對網址時,移除通訊協定和主機名稱。
    2. +
    + +
    + +
    + +
    +
    日期: 2.12.’07.
    + +
      +
    1. Selima::MnglMail 模組改名為 Selima::MungAddr 模組;修正 Selima 模組、 Selima::A2HTML 模組、 Selima::List::Public::Guestbook 類別、 Selima::Checker::MailTo 類別及 Selima::*::HTML 模組,將 mangle_* 函數更名為 mung_* 函數,註解中的 mangle 更正為 mung
    2. +
    + +
    + +
    + +
    +
    日期: 2.4.’07.
    + +
      +
    1. 修正 Selima::Init 模組,修正 checkspam_reqheads() 函式,加上新的規則;加上 checkspam_escurl() 函式。
    2. +
    + +
    + +
    + +
    +
    日期: 2.1.’07.
    + +
      +
    1. 修正 Selima::Process 類別的 process() 方法,未確認表單時,原未傳回任何值,改傳回 {"preview"=>1} ,以使其後的表單得知可否預覽;修正 Selima::Form 類別的 _html_preview_link() 方法,原檢查 ${$self->{"status"}}{"error"} ,改檢查 ${$self->{"status"}}{"preview"} ,以得知可否預覽。
    2. +
    3. 修正 Selima::Form 類別的 _html_preview_link() 方法的註解, Bounce when not preview 改為 Bounce when preview is not available for this form
    4. +
    + +
    + +
    + +
    +
    日期: 1.23.’07.
    + +
      +
    1. 修正 Selima::Preview 模組,加上 html_preview_mark() 函式,預覽時顯示預覽標印;加上引用 Selima::HTTP 模組、 Selima::PageFunc 模組、 Selima::ReqURI 模組;修正 Selima::*::HTML 模組的 html_footer() 函式,加上呼叫 html_preview_mark() 函式;修正 common.css 樣式表,加上 .previewmark 預覽標印的樣式。
    2. +
    + +
    + +
    + +
    +
    日期: 1.21.’07.
    + +
      +
    1. 修正Selima::emandy::Processor::Legend 類別、 Selima::imacat::Processor::ChangeLog 類別、 Selima::imacat::Processor::Diary 類別、 Selima::imacat::Processor::LiteralEn 類別、 Selima::imacat::Processor::LiteralZh 類別、 Selima::wov::Processor::Newslet 類別 _rebuild_partial_pages() 方法的註解, Check if there are shown parts affected 修正為 Check if there is any shown part affected
    2. +
    3. 修正 Selima::Format 模組 fmtsize() 函式的註解, Bounce if there are less than 3 digits in the rounded result 修正為 Bounce if there are fewer than 3 digits in the rounded result
    4. +
    5. 修正 Selima::List 類別、 Selima::List::* 類別與 Selima::*::List::* 類別 liststat_message() 方法的註解, Result more than 1 page 修正為 More than one pageResult less than 1 page 修正為 Fit in one page
    6. +
    7. 修正 Selima::imacat::HTML 模組與 Selima::wov::HTML 模組 html_*_pagebar() 函式的註解, No more than 1 page - no page bar is needed 修正為 Fit in one page - paging is not neededLess than 7 pages 修正為 Fewer than 7 pages ;修正 Selima::List 類別 html_pagebar() 方法的註解, Less than 1 page - no page bar is needed 修正為 Fit in one page - paging is not neededLess than 5 pages 修正為 Fewer than 5 pagesNear the END 修正為 Near the end
    8. +
    9. 修正 Selima::imacat::Processor::LiteralEn 模組與 Selima::imacat::Processor::LiteralZh 模組 _rebuild_partial_pages() 函式的註解, We have 6 more to the first -- rebuild the previous 3 修正為 We have 6 more pages to the first - rebuild the previous 3 pagesIf less than 6, start from the first for page bar sliding 修正為 If fewer than 6 pages, start from the first for page bar slidingWe have 6 more to the end -- rebuild the next 3 修正為 We have 6 more pages to the end - rebuild the next 3 pagesIf less than 6, build to the end for page bar sliding 修正為 If fewer than 6 pages, build to the end for page bar sliding
    10. +
    + +
    + +
    + +
    +
    日期: 1.21.’07.
    + +
      +
    1. 修正 Selima::Links 模組、 Selima::UserName 模組、 Selima::Country 模組、 Selima::*::Items 模組的註解, Bounce if there is problem with … 修正為 Bounce if there is any problem with …
    2. +
    3. 修正 Selima::List 類別,將 colval() 方法移至可重載方法區。
    4. +
    + +
    + +
    + +
    +
    日期: 1.10.’07.
    + +
      +
    1. 修正 Selima::*::List::Funds 類別,重寫 html_search() 方法,加上進階篩選條件欄位;修正 pre_filter() 方法,改傳回進階篩選條件欄位;修正 new() 方法, $self->{"pre_filter"} 改列預先定義的進階篩選條件;修正 funds.cgi ,移除對 $LIST->{"pre_filter"} 的預先定義。
    2. +
    + +
    + +
    + +
    +
    日期: 1.9.’07.
    + +
      +
    1. 修正 Selima::Checker::User 類別,加回之前暫時取消的 Crypt::Cracklib 密碼檢查,並根據 cracklib/fscist.c 中各種檢查結果,回傳適當的錯誤訊息,並加上中譯。
    2. +
    + +
    + +
    + +
    +
    日期: 1.1.’07.
    + +
      +
    1. 修正 funds_list* 檢視, m*ranky*rank 改顯示排名/同類基金數;加上 _m*rank_y*rank 顯示原來的數字排名;修正 Selima::*::List::Funds 類別,加上覆寫 sql_filter() 方法和 sql_orderby() 方法,將排名欄位前置 _ ,以數字排名為基準瀏覽資料;修正 new() 方法,加上 $self->{"COLS_NO_DISPLAY"} ,不顯示數字排名,只顯示排名/同類基金數
    2. +
    3. 修正 funds 資料表,將 majcatmincat 欄位改為 cat0cat1cat2cat3 欄位;修正 Selima::*::List::Funds 類別的 new() 方法, col_labels 加上 cat0cat1cat2cat3 欄位。
    4. +
    + +
    + +
    + +
    +
    日期: 12.30.’06.
    + +
      +
    1. emily 加上 funds 資料表、 Selima::emily::List::Funds 類別與 funds.cgi 程式。
    2. +
    3. 修正 Selima::imacat::List::Funds 類別的註解,移除程式說明多餘的旅舍兩個字。
    4. +
    + +
    + +
    + +
    +
    日期: 12.1.’06.
    + +
      +
    1. 修正 material 資料表、 Selima::emandy::List::Material 類別、Selima::emandy::Form::Material 類別、Selima::emandy::Checker::Material 類別、Selima::emandy::Processor::Material 類別及 material.cgi 程式,加上 author 欄位。
    2. +
    + +
    + +
    + +
    +
    日期: 11.23.’06.
    + +
      +
    1. 修正 Selima::emandy::Form::Book 類別的 new() 方法,資料表名誤植為 legend ,修正為 books
    2. +
    3. 修正許多程式的 fetch_curitem() 函式,移除沒有用到的 $error 變數及 $count 變數。
    4. +
    5. 修正 legend.cgi 程式與 books.cgi 程式,移除未引用的 Encode::HanConvert 類別,及未使用的 zhsync 重導向檢查。
    6. +
    7. 修正 Selima::emandy::Items 模組,所有的函式都是之前 htc 網站用,複製後未整理移除,移除之;加上 mtrltype_options() 函式。
    8. +
    9. 修正 Selima::Form::LinkCat 類別與 Selima::htc::Form::NLIndex 類別的 new() 方法,原用 $CURRENT{"*count"} ,改用 $self->{"cur"}->param("*count") ,取得項目數;移除不需要的引用 dataman 類變數。
    10. +
    + +
    + +
    + +
    +
    日期: 11.22.’06.
    + +
      +
    1. 加上 mtrltype 資料表及 material 資料表。
    2. +
    + +
    + +
    + +
    +
    日期: 11.17.’06.
    + +
      +
    1. 修正 Selima::Form 模組的 _html_coltmpl_call()_html_coltmpl_call_null() 方法,修正顯示刪除鈕的邏輯,將刪除鈕和選擇鈕接在一起。
    2. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 8 | + 9 | + 10 | + 11 | + 12 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0011.html.en.html b/htdocs/imacat/me/changelog/0011.html.en.html new file mode 120000 index 0000000..3fbb0db --- /dev/null +++ b/htdocs/imacat/me/changelog/0011.html.en.html @@ -0,0 +1 @@ +0011.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0011.html.en.xhtml b/htdocs/imacat/me/changelog/0011.html.en.xhtml new file mode 100644 index 0000000..da1cab8 --- /dev/null +++ b/htdocs/imacat/me/changelog/0011.html.en.xhtml @@ -0,0 +1,373 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 11 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 11

    + +
    + +
    + +
    +
    Date: 8.23.’07.
    + +
      +
    1. 修正 imacat 資料庫定義, LPAD() 函數的第三個參數應為文字,原使用數字 0 ,修正為文字 '0'
    2. +
    3. 修正 imacat 資料庫定義,加上 acctsubjaccttrxacctrecs 三個資料表,與 acctsubj_ischild() 函式。
    4. +
    5. 加上 Selima::imacat::List::AcctSubj 類別、 Selima::imacat::Form::AcctSubj 類別與 Selima::imacat::Checker::AcctSubj 類別,加上 acctsubj.cgi 程式。
    6. +
    7. 修正 Selima::imacat::HTML 模組的 @ADMIN_SCRIPTS 變數,加上 acctsubj.cgiaccttrx.cgiacctrecs.cgi 三個程式。
    8. +
    + +
    + +
    + +
    +
    Date: 8.20.’07.
    + +
      +
    1. 修正 Selima::*::List::Funds 類別的 new() 方法,移除不再用到的 cat0cat1cat2cat3 欄位標題;修正 $self->{"pre_filter"} 屬性的進階篩選條件,排名前三分之一、四分之一的條件原用小於或等於 <= ,改用小於 < ,以避免排名 1/2 時,因取該分區中位數正為 0.25 ,而被誤列入排名前四分之一的問題。
    2. +
    + +
    + +
    + +
    +
    Date: 8.18.’07.
    + +
      +
    1. 修正 funds 資料表, *rank 欄位由 smallint 改為 numeric(4, 4) ,原儲存基金排名名次,改儲存排名佔該類基金的百分比位置,並加上 *rnkdsc 排名的敘述。如此得以基金表現百分比位置排名,而非單以名次排名,以減少特殊類形基金因同類基金只有一二種,故很容易同類排名第一第二,單按名次排名沒有意義的問題。於匯入基金績效資料時自行計算排名,避免基金績效資料排名有誤時匯入錯誤的問題。並於匯入時同時寫入基金排名的敘述,以減少列表時,即時計算該類基金數以顯示排名敘述,效率過低的問題。
    2. +
    3. 修正 funds_list_* 瀏覽,使用 *rnkdsc 欄位顯示排名,不再即時計算排名,以避免無謂的耗時低效率;將 cat0cat1cat2cat3 合為一欄 cat 顯示,以簡化列表。
    4. +
    5. 修正 Selima::*::List::Funds 類別的 new() 方法、 pre_filter() 方法及 html_search() 方法, $self->{"pre_filter"} 屬性原為進階篩選條件的字串數列,改為進階篩選條件的選項數列的數列,每一選項數列包含篩選條件和文字敘述。如此可加上類似4433 法則等廣為人知 ,有特定名字的篩選條件。去除 free 條件,自訂任意條件改為內建,不需列於 $self->{"pre_filter"} 屬性進階篩選條件清單中。內建加上 none 無進階篩選條件。
    6. +
    + +
    + +
    + +
    +
    Date: 6.23.’07.
    + +
      +
    1. 修正 Selima::emandy::HTML 模組的 html_nav() 方法,加上需要時顯示 $$args{"header_html_nav"}
    2. +
    + +
    + +
    + +
    +
    Date: 6.8.’07.
    + +
      +
    1. 修正 Selima::Destroy 類別的 DESTROY() 方法及 Selima::HTTP 模組的 http_*() 函式,原先用 eval {} 迴圈清理 IO::NestedCapture ,改用 IO::NestedCapture->instance->{"STDOUT_current"} 作迴圈判斷,以避免 eval {} 失敗有時會導致程式不正常中斷的問題。
    2. +
    3. 修正 Selima::GetLang 模組的 getlang_env() 函式,先檢查 $GET$POST 設定沒,以避免尚未設定 $GET$POST 即呼叫時,產生的警告。
    4. +
    5. 修正 Selima::GetLang 模組的 getlang_filename() 函式,先檢查 $REQUEST_PATH 設定沒,以避免尚未設定 $REQUEST_PATH 即呼叫時,產生的警告。
    6. +
    7. 修正 Selima::Init 模組的 checkspam_spammers() 函式,修正檢查 $POST->param("url") 前未檢查有沒有 $POST->param("url") 的錯誤。
    8. +
    + +
    + +
    + +
    +
    Date: 5.26.’07.
    + +
      +
    1. 修正 Selima::Init 模組、 Selima::DataVars 模組、 Selima::Destroy 類別、 Selima::List 類別、 Selima::List::* 類別、 Selima::Form 類別、 Selima::Form::* 類別、 Selima::Preview 模組、 Selima::*::HTML 模組、 Selima::*::Rebuild 模組、 Selima::*::List::* 類別、 Selima::*::Form::* 類別、 guestbook.cgi 程式、 garbage.cgi 程式、 logout.cgi 程式、 saveform.cgi 程式、 showenv.cgi 程式、 test.cgi 程式、 counter.cgi 程式、 last_update.cgi 程式及 subs_counter.cgi 程式,原來自己另存輸出,改用 IO::NestedCapture 抓標準輸出,以類似 PHP 輸出入緩衝區的方式,處理網頁輸出,以簡化網頁輸出處理。移除 Selima::DataVars 模組的 $HTML 變數。
    2. +
    3. 修正 Selima::List::Guestbook 類別、 Selima::Form::UserMem 類別、 Selima::Form::GroupMem 類別、 Selima::Form::UserPref 類別、 Selima::Form::Guestbook 類別、 Selima::Form::LinkCatz 類別、 Selima::htc::Form::NLArt 類別、 Selima::imacat::Form::LtZhPoem 類別及 Selima::wov::Form::NLArt 類別,移除不用的 :output 類變數引用。
    4. +
    5. 修正 Selima::HTTP 模組的 http_*() 函式,處理前先清空 IO::NestedCapture 的輸出轉向。
    6. +
    7. Selima 系統版本更新為 3.10 。改用 IO::NestedCapture 作網頁輸出控制後,所有的網頁輸出處理都要修正,異動檔案很多。
    8. +
    + +
    + +
    + +
    +
    Date: 5.24.’07.
    + +
      +
    1. 修正 counter.cgi 程式,移除不該存在的 in_our_network() 函式。 in_our_network() 函式使用早已移除宣告的 @OUR_NETWORKS 陣列及 Net::IPv4Addr 模組的 ipv4_in_network() 函式,造成程式錯誤無法執行。從 Net::IPv4Addr 模組改用 Net::CIDR::Lite 模組已經兩個多星期了了,才發現這個問題,這段期間程式都無法作用,我卻完全不知道,實在是很不應該。
    2. +
    + +
    + +
    + +
    +
    Date: 5.23.’07.
    + +
      +
    1. 修正 Selima::Encrypt 模組的 encrypt() 函式, ASCII 可列印字元從 31 開始有誤,修正為 32 。
    2. +
    + +
    + +
    + +
    +
    Date: 5.23.’07.
    + +
      +
    1. 修正 Selima::Encrypt 模組,因 Crypt::Rijndael 已於 2007-02-23 發行 1.04 新版,已支援 x86_64 平台,故捨 Crypt::Rijndael_PP ,改回用 Crypt::Rijndael
    2. +
    + +
    + +
    + +
    +
    Date: 5.8.’07.
    + +
      +
    1. 修正 Selima::GeoIP 模組,原用 Net::IPv4Addr 模組,改用 Net::CIDR::Lite 模組,移除 is_private_ip() 函式,改用 $PRIVATE_NETWORKS 物件。 Net::CIDR::Lite 模組效能好像比 Net::IPv4Addr 模組好。
    2. +
    3. 修正 counter.cgi 程式,移除未用到的 Geo::IP 模組,原用 Net::IPv4Addr 模組,改用 Net::CIDR::Lite 模組,移除 in_our_network() 函式、 @OUR_NETWORKS 陣列及 $IN_OUR_NETWORK 變數,改用 $OUR_NETWORKS 物件。
    4. +
    + +
    + +
    + +
    +
    Date: 4.8.’07.
    + +
      +
    1. 修正 Selima::Init 模組,修正 checkspam_reqheads() 函式,加上兩個新的規則;修正 checkspam_spammers() 函式,加上一個新的規則。
    2. +
    + +
    + +
    + +
    +
    Date: 4.3.’07.
    + +
      +
    1. 修正 Selima::Checker 類別的 _check_path() 方法,將移除 index.html 的部份前移到 _trim() 後,以便正確檢查,並避免後來重複路徑檢查時產生的錯誤。
    2. +
    + +
    + +
    + +
    +
    Date: 3.18.’07.
    + +
      +
    1. 修正各站的首頁,計數器和上次更新日期,回復用 mod_perl GD 的計數器。 GD 造成記憶體區段錯誤 Segmentation fault 的原因找到了,也解決了。 PHP 中也有 gd 模組,但 PHP 的 gd 用的是內附的 gd 函式庫, Perl 的 GD 用的是系統的 gd 函式庫,同時載入 mod_perl.solibphp5.so 時,兩者版本不同互衝所致。解決方法,只要重新編譯 PHP ,原參數 with-gd=shared 改為 --with-gd=shared,/usr ,改連結系統的 gd 函式庫即可。
    2. +
    + +
    + +
    + +
    +
    Date: 3.16.’07.
    + +
      +
    1. 運用新版 Apache 2 的內容協調功能,新的 prefer-language 環境參數, SetEnvIf CookieHeader add Set-Cookie 設定,終於解決了旅舍的理想,所選的語言可以一直持續下去!過去如果網站語言沒有自動選到自己習慣的語言,切到該語言頁後,再看下一頁,又會回到之前錯誤的語言中。現在利用新版 Apache 2 的語言協調選擇功能,終於可以把語言固定下來了!耶! ^_*'
    2. +
    + +
    + +
    + +
    +
    Date: 3.15.’07.
    + +
      +
    1. 修正各站的首頁,最近更新日期暫時改用 CGI 的圖型。 GD 在 mod_perl 2 下會 crash , bug 尚待回報。
    2. +
    + +
    + +
    + +
    +
    Date: 3.14.’07.
    + +
      +
    1. 修正 Selima::imacat::Rebuild 模組的 rebuild_links() 函式、 rebuild_diary() 函式、 rebuild_changelog() 函式和 rebuild_literalzh() 函式,取消製作預設語言的符號連結。 Apache 2 有 ForceLanguagePriority 設定,不需要另外製作預設語言的符號連結。
    2. +
    + +
    + +
    + +
    +
    Date: 3.13.’07.
    + +

    昇級為 Apache 2 + mod_perl 2 。

    + +
      +
    1. 修正各站的首頁,計數器暫時改用 CGI 的計數器。 GD 在 mod_perl 2 下會 crash ,原因待查。
    2. +
    3. 伺服器版本昇級為 Apache 2 (2.0.59) + mod_perl 2 (2.0.3) 。
    4. +
    5. Selima 系統版本更新為 3.00 。由 mod_perl 1 昇級到 mod_perl 2 ,為配合 mod_perl 2 的新處理方式,系統程式大範圍重寫,異動非常大。
    6. +
    + +
    + +
    + +
    +
    Date: 3.13.’07.
    + +
      +
    1. 修正 Selima::HTTP 模組及 Selima::Destroy 類別,原用 $r->header_out() 方法,改用 $r->headers_out()->set() 方法。
    2. +
    3. 修正 Selima::Login 模組 upd_login_info() 函式的註解,原 Logged-in from Apache/mod_perl HTTP Authentication 改為 Logged-in from Selima::AuthDig Digest Authentication
    4. +
    5. 修正 Selima::Init 模組的 initenv() 函式,原先直接檢查 Selima::AuthDig 傳回的 $AUTHINFO ,改為依是否載入 $INC{"Apache/AuthDigest/API.pm"} ,而檢查 $AUTHINFO$ENV{"REMOTE_USER"} ,來決定 unauth()upd_login_info() 。雖然用 mod_auth_digest 登入,程式本身無法和登入過程一體化,但是應該可以相信 Apache 的登入資訊,不會有安全問題吧~
    6. +
    7. 修正 showenv.cgi 程式,修正在 mod_perl 2 下時,顯示的方法名稱。
    8. +
    9. 修正 Selima::DataVars 模組,原先以 $ENV{"GATEWAY_INTERFACE"} 檢查 $IS_CGI ,因 mod_perl 2 下載入這個模組的時候還沒有 $ENV{"GATEWAY_INTERFACE"} ,改為以 $ENV{"GATEWAY_INTERFACE"}$ENV{"MOD_PERL"} 檢查。
    10. +
    11. 修正 Selima::Destroy 模組的 DESTROY() 方法,原先在 mod_perl 下自動執行 $r->send_http_header() ,改為檢查只有 mod_perl 1 下才會執行 $r->send_http_header()
    12. +
    13. 修正 Selima::Init 模組的 initvars() 方法,原用 $r->headers_in()->add() 方法,改用 $r->headers_in()->set() 方法。
    14. +
    15. 修正 Selima::Init 模組的 initenv() 函式,先執行 $MAIN->can("siteconf") ,以取得 $PACKAGE ,以便傳給 initvars() ;修正 initvars() 原型,由 initvars(;$) 改為 initvars($) ,因為現在一定會傳入參數,不可能省略。
    16. +
    17. 修正 Selima::DecForm 模組的 init_forms() 函式,原先由 $rawpost = $r->content 取得 POST 表單的內容,改依 $IS_MP2 判斷,由 $r->read($rawpost, $r->headers_in->get("Content-Length"))$rawpost = $r->content 取得 POST 表單的內容。
    18. +
    19. 修正 Selima::HTTP 模組的 http_*() 函式,原用 $r->err_header_out() 方法,改用 $r->err_headers_out()->set() 方法;加上引用 Apache2::Response;
    20. +
    21. 修正 Selima::Destroy 類別的 DESTROY() 方法,原用 $r->headers_out->set("Content-Length"=>length $HTML); 方法,改用 $r->set_content_length(length $HTML); 方法。
    22. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 9 | + 10 | + 11 | + 12 | + 13 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0011.html.zh-cn.html b/htdocs/imacat/me/changelog/0011.html.zh-cn.html new file mode 120000 index 0000000..e64f62e --- /dev/null +++ b/htdocs/imacat/me/changelog/0011.html.zh-cn.html @@ -0,0 +1 @@ +0011.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0011.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0011.html.zh-cn.xhtml new file mode 100644 index 0000000..f5fc788 --- /dev/null +++ b/htdocs/imacat/me/changelog/0011.html.zh-cn.xhtml @@ -0,0 +1,372 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷十一 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷十一

    + +
    + +
    + +
    +
    日期: 8.23.’07.
    + +
      +
    1. 修正 imacat 资料库定义, LPAD() 函数的第三个参数应为文字,原使用数字 0 ,修正为文字 '0'
    2. +
    3. 修正 imacat 资料库定义,加上 acctsubjaccttrxacctrecs 三个资料表,与 acctsubj_ischild() 函式。
    4. +
    5. 加上 Selima::imacat::List::AcctSubj 类别、 Selima::imacat::Form::AcctSubj 类别与 Selima::imacat::Checker::AcctSubj 类别,加上 acctsubj.cgi 程式。
    6. +
    7. 修正 Selima::imacat::HTML 模组的 @ADMIN_SCRIPTS 变数,加上 acctsubj.cgiaccttrx.cgiacctrecs.cgi 三个程式。
    8. +
    + +
    + +
    + +
    +
    日期: 8.20.’07.
    + +
      +
    1. 修正 Selima::*::List::Funds 类别的 new() 方法,移除不再用到的 cat0cat1cat2cat3 栏位标题;修正 $self->{"pre_filter"} 属性的进阶筛选条件,排名前三分之一、四分之一的条件原用小於或等於 <= ,改用小於 < ,以避免排名 1/2 时,因取该分区中位数正为 0.25 ,而被误列入排名前四分之一的问题。
    2. +
    + +
    + +
    + +
    +
    日期: 8.18.’07.
    + +
      +
    1. 修正 funds 资料表, *rank 栏位由 smallint 改为 numeric(4, 4) ,原储存基金排名名次,改储存排名占该类基金的百分比位置,并加上 *rnkdsc 排名的叙述。如此得以基金表现百分比位置排名,而非单以名次排名,以减少特殊类形基金因同类基金只有一二种,故很容易同类排名第一第二,单按名次排名没有意义的问题。於汇入基金绩效资料时自行计算排名,避免基金绩效资料排名有误时汇入错误的问题。并於汇入时同时写入基金排名的叙述,以减少列表时,即时计算该类基金数以显示排名叙述,效率过低的问题。
    2. +
    3. 修正 funds_list_* 浏览,使用 *rnkdsc 栏位显示排名,不再即时计算排名,以避免无谓的耗时低效率;将 cat0cat1cat2cat3 合为一栏 cat 显示,以简化列表。
    4. +
    5. 修正 Selima::*::List::Funds 类别的 new() 方法、 pre_filter() 方法及 html_search() 方法, $self->{"pre_filter"} 属性原为进阶筛选条件的字串数列,改为进阶筛选条件的选项数列的数列,每一选项数列包含筛选条件和文字叙述。如此可加上类似4433 法则等广为人知 ,有特定名字的筛选条件。去除 free 条件,自订任意条件改为内建,不需列於 $self->{"pre_filter"} 属性进阶筛选条件清单中。内建加上 none 无进阶筛选条件。
    6. +
    + +
    + +
    + +
    +
    日期: 6.23.’07.
    + +
      +
    1. 修正 Selima::emandy::HTML 模组的 html_nav() 方法,加上需要时显示 $$args{"header_html_nav"}
    2. +
    + +
    + +
    + +
    +
    日期: 6.8.’07.
    + +
      +
    1. 修正 Selima::Destroy 类别的 DESTROY() 方法及 Selima::HTTP 模组的 http_*() 函式,原先用 eval {} 回圈清理 IO::NestedCapture ,改用 IO::NestedCapture->instance->{"STDOUT_current"} 作回圈判断,以避免 eval {} 失败有时会导致程式不正常中断的问题。
    2. +
    3. 修正 Selima::GetLang 模组的 getlang_env() 函式,先检查 $GET$POST 设定没,以避免尚未设定 $GET$POST 即呼叫时,产生的警告。
    4. +
    5. 修正 Selima::GetLang 模组的 getlang_filename() 函式,先检查 $REQUEST_PATH 设定没,以避免尚未设定 $REQUEST_PATH 即呼叫时,产生的警告。
    6. +
    7. 修正 Selima::Init 模组的 checkspam_spammers() 函式,修正检查 $POST->param("url") 前未检查有没有 $POST->param("url") 的错误。
    8. +
    + +
    + +
    + +
    +
    日期: 5.26.’07.
    + +
      +
    1. 修正 Selima::Init 模组、 Selima::DataVars 模组、 Selima::Destroy 类别、 Selima::List 类别、 Selima::List::* 类别、 Selima::Form 类别、 Selima::Form::* 类别、 Selima::Preview 模组、 Selima::*::HTML 模组、 Selima::*::Rebuild 模组、 Selima::*::List::* 类别、 Selima::*::Form::* 类别、 guestbook.cgi 程式、 garbage.cgi 程式、 logout.cgi 程式、 saveform.cgi 程式、 showenv.cgi 程式、 test.cgi 程式、 counter.cgi 程式、 last_update.cgi 程式及 subs_counter.cgi 程式,原来自己另存输出,改用 IO::NestedCapture 抓标准输出,以类似 PHP 输出入缓冲区的方式,处理网页输出,以简化网页输出处理。移除 Selima::DataVars 模组的 $HTML 变数。
    2. +
    3. 修正 Selima::List::Guestbook 类别、 Selima::Form::UserMem 类别、 Selima::Form::GroupMem 类别、 Selima::Form::UserPref 类别、 Selima::Form::Guestbook 类别、 Selima::Form::LinkCatz 类别、 Selima::htc::Form::NLArt 类别、 Selima::imacat::Form::LtZhPoem 类别及 Selima::wov::Form::NLArt 类别,移除不用的 :output 类变数引用。
    4. +
    5. 修正 Selima::HTTP 模组的 http_*() 函式,处理前先清空 IO::NestedCapture 的输出转向。
    6. +
    7. Selima 系统版本更新为 3.10 。改用 IO::NestedCapture 作网页输出控制后,所有的网页输出处理都要修正,异动档案很多。
    8. +
    + +
    + +
    + +
    +
    日期: 5.24.’07.
    + +
      +
    1. 修正 counter.cgi 程式,移除不该存在的 in_our_network() 函式。 in_our_network() 函式使用早已移除宣告的 @OUR_NETWORKS 阵列及 Net::IPv4Addr 模组的 ipv4_in_network() 函式,造成程式错误无法执行。从 Net::IPv4Addr 模组改用 Net::CIDR::Lite 模组已经两个多星期了了,才发现这个问题,这段期间程式都无法作用,我却完全不知道,实在是很不应该。
    2. +
    + +
    + +
    + +
    +
    日期: 5.23.’07.
    + +
      +
    1. 修正 Selima::Encrypt 模组的 encrypt() 函式, ASCII 可列印字元从 31 开始有误,修正为 32 。
    2. +
    + +
    + +
    + +
    +
    日期: 5.23.’07.
    + +
      +
    1. 修正 Selima::Encrypt 模组,因 Crypt::Rijndael 已於 2007-02-23 发行 1.04 新版,已支援 x86_64 平台,故舍 Crypt::Rijndael_PP ,改回用 Crypt::Rijndael
    2. +
    + +
    + +
    + +
    +
    日期: 5.8.’07.
    + +
      +
    1. 修正 Selima::GeoIP 模组,原用 Net::IPv4Addr 模组,改用 Net::CIDR::Lite 模组,移除 is_private_ip() 函式,改用 $PRIVATE_NETWORKS 物件。 Net::CIDR::Lite 模组效能好像比 Net::IPv4Addr 模组好。
    2. +
    3. 修正 counter.cgi 程式,移除未用到的 Geo::IP 模组,原用 Net::IPv4Addr 模组,改用 Net::CIDR::Lite 模组,移除 in_our_network() 函式、 @OUR_NETWORKS 阵列及 $IN_OUR_NETWORK 变数,改用 $OUR_NETWORKS 物件。
    4. +
    + +
    + +
    + +
    +
    日期: 4.8.’07.
    + +
      +
    1. 修正 Selima::Init 模组,修正 checkspam_reqheads() 函式,加上两个新的规则;修正 checkspam_spammers() 函式,加上一个新的规则。
    2. +
    + +
    + +
    + +
    +
    日期: 4.3.’07.
    + +
      +
    1. 修正 Selima::Checker 类别的 _check_path() 方法,将移除 index.html 的部份前移到 _trim() 后,以便正确检查,并避免后来重复路径检查时产生的错误。
    2. +
    + +
    + +
    + +
    +
    日期: 3.18.’07.
    + +
      +
    1. 修正各站的首页,计数器和上次更新日期,回复用 mod_perl GD 的计数器。 GD 造成记忆体区段错误 Segmentation fault 的原因找到了,也解决了。 PHP 中也有 gd 模组,但 PHP 的 gd 用的是内附的 gd 函式库, Perl 的 GD 用的是系统的 gd 函式库,同时载入 mod_perl.solibphp5.so 时,两者版本不同互冲所致。解决方法,只要重新编译 PHP ,原参数 with-gd=shared 改为 --with-gd=shared,/usr ,改连结系统的 gd 函式库即可。
    2. +
    + +
    + +
    + +
    +
    日期: 3.16.’07.
    + +
      +
    1. 运用新版 Apache 2 的内容协调功能,新的 prefer-language 环境参数, SetEnvIf CookieHeader add Set-Cookie 设定,终於解决了旅舍的理想,所选的语言可以一直持续下去!过去如果网站语言没有自动选到自己习惯的语言,切到该语言页后,再看下一页,又会回到之前错误的语言中。现在利用新版 Apache 2 的语言协调选择功能,终於可以把语言固定下来了!耶! ^_*'
    2. +
    + +
    + +
    + +
    +
    日期: 3.15.’07.
    + +
      +
    1. 修正各站的首页,最近更新日期暂时改用 CGI 的图型。 GD 在 mod_perl 2 下会 crash , bug 尚待回报。
    2. +
    + +
    + +
    + +
    +
    日期: 3.14.’07.
    + +
      +
    1. 修正 Selima::imacat::Rebuild 模组的 rebuild_links() 函式、 rebuild_diary() 函式、 rebuild_changelog() 函式和 rebuild_literalzh() 函式,取消制作预设语言的符号连结。 Apache 2 有 ForceLanguagePriority 设定,不需要另外制作预设语言的符号连结。
    2. +
    + +
    + +
    + +
    +
    日期: 3.13.’07.
    + +

    升级为 Apache 2 + mod_perl 2 。

    + +
      +
    1. 修正各站的首页,计数器暂时改用 CGI 的计数器。 GD 在 mod_perl 2 下会 crash ,原因待查。
    2. +
    3. 伺服器版本升级为 Apache 2 (2.0.59) + mod_perl 2 (2.0.3) 。
    4. +
    5. Selima 系统版本更新为 3.00 。由 mod_perl 1 升级到 mod_perl 2 ,为配合 mod_perl 2 的新处理方式,系统程式大范围重写,异动非常大。
    6. +
    + +
    + +
    + +
    +
    日期: 3.13.’07.
    + +
      +
    1. 修正 Selima::HTTP 模组及 Selima::Destroy 类别,原用 $r->header_out() 方法,改用 $r->headers_out()->set() 方法。
    2. +
    3. 修正 Selima::Login 模组 upd_login_info() 函式的注解,原 Logged-in from Apache/mod_perl HTTP Authentication 改为 Logged-in from Selima::AuthDig Digest Authentication
    4. +
    5. 修正 Selima::Init 模组的 initenv() 函式,原先直接检查 Selima::AuthDig 传回的 $AUTHINFO ,改为依是否载入 $INC{"Apache/AuthDigest/API.pm"} ,而检查 $AUTHINFO$ENV{"REMOTE_USER"} ,来决定 unauth()upd_login_info() 。虽然用 mod_auth_digest 登入,程式本身无法和登入过程一体化,但是应该可以相信 Apache 的登入资讯,不会有安全问题吧~
    6. +
    7. 修正 showenv.cgi 程式,修正在 mod_perl 2 下时,显示的方法名称。
    8. +
    9. 修正 Selima::DataVars 模组,原先以 $ENV{"GATEWAY_INTERFACE"} 检查 $IS_CGI ,因 mod_perl 2 下载入这个模组的时候还没有 $ENV{"GATEWAY_INTERFACE"} ,改为以 $ENV{"GATEWAY_INTERFACE"}$ENV{"MOD_PERL"} 检查。
    10. +
    11. 修正 Selima::Destroy 模组的 DESTROY() 方法,原先在 mod_perl 下自动执行 $r->send_http_header() ,改为检查只有 mod_perl 1 下才会执行 $r->send_http_header()
    12. +
    13. 修正 Selima::Init 模组的 initvars() 方法,原用 $r->headers_in()->add() 方法,改用 $r->headers_in()->set() 方法。
    14. +
    15. 修正 Selima::Init 模组的 initenv() 函式,先执行 $MAIN->can("siteconf") ,以取得 $PACKAGE ,以便传给 initvars() ;修正 initvars() 原型,由 initvars(;$) 改为 initvars($) ,因为现在一定会传入参数,不可能省略。
    16. +
    17. 修正 Selima::DecForm 模组的 init_forms() 函式,原先由 $rawpost = $r->content 取得 POST 表单的内容,改依 $IS_MP2 判断,由 $r->read($rawpost, $r->headers_in->get("Content-Length"))$rawpost = $r->content 取得 POST 表单的内容。
    18. +
    19. 修正 Selima::HTTP 模组的 http_*() 函式,原用 $r->err_header_out() 方法,改用 $r->err_headers_out()->set() 方法;加上引用 Apache2::Response;
    20. +
    21. 修正 Selima::Destroy 类别的 DESTROY() 方法,原用 $r->headers_out->set("Content-Length"=>length $HTML); 方法,改用 $r->set_content_length(length $HTML); 方法。
    22. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 9 | + 10 | + 11 | + 12 | + 13 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0011.html.zh-tw.html b/htdocs/imacat/me/changelog/0011.html.zh-tw.html new file mode 120000 index 0000000..7882a54 --- /dev/null +++ b/htdocs/imacat/me/changelog/0011.html.zh-tw.html @@ -0,0 +1 @@ +0011.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0011.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0011.html.zh-tw.xhtml new file mode 100644 index 0000000..4a52017 --- /dev/null +++ b/htdocs/imacat/me/changelog/0011.html.zh-tw.xhtml @@ -0,0 +1,372 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷十一 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷十一

    + +
    + +
    + +
    +
    日期: 8.23.’07.
    + +
      +
    1. 修正 imacat 資料庫定義, LPAD() 函數的第三個參數應為文字,原使用數字 0 ,修正為文字 '0'
    2. +
    3. 修正 imacat 資料庫定義,加上 acctsubjaccttrxacctrecs 三個資料表,與 acctsubj_ischild() 函式。
    4. +
    5. 加上 Selima::imacat::List::AcctSubj 類別、 Selima::imacat::Form::AcctSubj 類別與 Selima::imacat::Checker::AcctSubj 類別,加上 acctsubj.cgi 程式。
    6. +
    7. 修正 Selima::imacat::HTML 模組的 @ADMIN_SCRIPTS 變數,加上 acctsubj.cgiaccttrx.cgiacctrecs.cgi 三個程式。
    8. +
    + +
    + +
    + +
    +
    日期: 8.20.’07.
    + +
      +
    1. 修正 Selima::*::List::Funds 類別的 new() 方法,移除不再用到的 cat0cat1cat2cat3 欄位標題;修正 $self->{"pre_filter"} 屬性的進階篩選條件,排名前三分之一、四分之一的條件原用小於或等於 <= ,改用小於 < ,以避免排名 1/2 時,因取該分區中位數正為 0.25 ,而被誤列入排名前四分之一的問題。
    2. +
    + +
    + +
    + +
    +
    日期: 8.18.’07.
    + +
      +
    1. 修正 funds 資料表, *rank 欄位由 smallint 改為 numeric(4, 4) ,原儲存基金排名名次,改儲存排名佔該類基金的百分比位置,並加上 *rnkdsc 排名的敘述。如此得以基金表現百分比位置排名,而非單以名次排名,以減少特殊類形基金因同類基金只有一二種,故很容易同類排名第一第二,單按名次排名沒有意義的問題。於匯入基金績效資料時自行計算排名,避免基金績效資料排名有誤時匯入錯誤的問題。並於匯入時同時寫入基金排名的敘述,以減少列表時,即時計算該類基金數以顯示排名敘述,效率過低的問題。
    2. +
    3. 修正 funds_list_* 瀏覽,使用 *rnkdsc 欄位顯示排名,不再即時計算排名,以避免無謂的耗時低效率;將 cat0cat1cat2cat3 合為一欄 cat 顯示,以簡化列表。
    4. +
    5. 修正 Selima::*::List::Funds 類別的 new() 方法、 pre_filter() 方法及 html_search() 方法, $self->{"pre_filter"} 屬性原為進階篩選條件的字串數列,改為進階篩選條件的選項數列的數列,每一選項數列包含篩選條件和文字敘述。如此可加上類似4433 法則等廣為人知 ,有特定名字的篩選條件。去除 free 條件,自訂任意條件改為內建,不需列於 $self->{"pre_filter"} 屬性進階篩選條件清單中。內建加上 none 無進階篩選條件。
    6. +
    + +
    + +
    + +
    +
    日期: 6.23.’07.
    + +
      +
    1. 修正 Selima::emandy::HTML 模組的 html_nav() 方法,加上需要時顯示 $$args{"header_html_nav"}
    2. +
    + +
    + +
    + +
    +
    日期: 6.8.’07.
    + +
      +
    1. 修正 Selima::Destroy 類別的 DESTROY() 方法及 Selima::HTTP 模組的 http_*() 函式,原先用 eval {} 迴圈清理 IO::NestedCapture ,改用 IO::NestedCapture->instance->{"STDOUT_current"} 作迴圈判斷,以避免 eval {} 失敗有時會導致程式不正常中斷的問題。
    2. +
    3. 修正 Selima::GetLang 模組的 getlang_env() 函式,先檢查 $GET$POST 設定沒,以避免尚未設定 $GET$POST 即呼叫時,產生的警告。
    4. +
    5. 修正 Selima::GetLang 模組的 getlang_filename() 函式,先檢查 $REQUEST_PATH 設定沒,以避免尚未設定 $REQUEST_PATH 即呼叫時,產生的警告。
    6. +
    7. 修正 Selima::Init 模組的 checkspam_spammers() 函式,修正檢查 $POST->param("url") 前未檢查有沒有 $POST->param("url") 的錯誤。
    8. +
    + +
    + +
    + +
    +
    日期: 5.26.’07.
    + +
      +
    1. 修正 Selima::Init 模組、 Selima::DataVars 模組、 Selima::Destroy 類別、 Selima::List 類別、 Selima::List::* 類別、 Selima::Form 類別、 Selima::Form::* 類別、 Selima::Preview 模組、 Selima::*::HTML 模組、 Selima::*::Rebuild 模組、 Selima::*::List::* 類別、 Selima::*::Form::* 類別、 guestbook.cgi 程式、 garbage.cgi 程式、 logout.cgi 程式、 saveform.cgi 程式、 showenv.cgi 程式、 test.cgi 程式、 counter.cgi 程式、 last_update.cgi 程式及 subs_counter.cgi 程式,原來自己另存輸出,改用 IO::NestedCapture 抓標準輸出,以類似 PHP 輸出入緩衝區的方式,處理網頁輸出,以簡化網頁輸出處理。移除 Selima::DataVars 模組的 $HTML 變數。
    2. +
    3. 修正 Selima::List::Guestbook 類別、 Selima::Form::UserMem 類別、 Selima::Form::GroupMem 類別、 Selima::Form::UserPref 類別、 Selima::Form::Guestbook 類別、 Selima::Form::LinkCatz 類別、 Selima::htc::Form::NLArt 類別、 Selima::imacat::Form::LtZhPoem 類別及 Selima::wov::Form::NLArt 類別,移除不用的 :output 類變數引用。
    4. +
    5. 修正 Selima::HTTP 模組的 http_*() 函式,處理前先清空 IO::NestedCapture 的輸出轉向。
    6. +
    7. Selima 系統版本更新為 3.10 。改用 IO::NestedCapture 作網頁輸出控制後,所有的網頁輸出處理都要修正,異動檔案很多。
    8. +
    + +
    + +
    + +
    +
    日期: 5.24.’07.
    + +
      +
    1. 修正 counter.cgi 程式,移除不該存在的 in_our_network() 函式。 in_our_network() 函式使用早已移除宣告的 @OUR_NETWORKS 陣列及 Net::IPv4Addr 模組的 ipv4_in_network() 函式,造成程式錯誤無法執行。從 Net::IPv4Addr 模組改用 Net::CIDR::Lite 模組已經兩個多星期了了,才發現這個問題,這段期間程式都無法作用,我卻完全不知道,實在是很不應該。
    2. +
    + +
    + +
    + +
    +
    日期: 5.23.’07.
    + +
      +
    1. 修正 Selima::Encrypt 模組的 encrypt() 函式, ASCII 可列印字元從 31 開始有誤,修正為 32 。
    2. +
    + +
    + +
    + +
    +
    日期: 5.23.’07.
    + +
      +
    1. 修正 Selima::Encrypt 模組,因 Crypt::Rijndael 已於 2007-02-23 發行 1.04 新版,已支援 x86_64 平台,故捨 Crypt::Rijndael_PP ,改回用 Crypt::Rijndael
    2. +
    + +
    + +
    + +
    +
    日期: 5.8.’07.
    + +
      +
    1. 修正 Selima::GeoIP 模組,原用 Net::IPv4Addr 模組,改用 Net::CIDR::Lite 模組,移除 is_private_ip() 函式,改用 $PRIVATE_NETWORKS 物件。 Net::CIDR::Lite 模組效能好像比 Net::IPv4Addr 模組好。
    2. +
    3. 修正 counter.cgi 程式,移除未用到的 Geo::IP 模組,原用 Net::IPv4Addr 模組,改用 Net::CIDR::Lite 模組,移除 in_our_network() 函式、 @OUR_NETWORKS 陣列及 $IN_OUR_NETWORK 變數,改用 $OUR_NETWORKS 物件。
    4. +
    + +
    + +
    + +
    +
    日期: 4.8.’07.
    + +
      +
    1. 修正 Selima::Init 模組,修正 checkspam_reqheads() 函式,加上兩個新的規則;修正 checkspam_spammers() 函式,加上一個新的規則。
    2. +
    + +
    + +
    + +
    +
    日期: 4.3.’07.
    + +
      +
    1. 修正 Selima::Checker 類別的 _check_path() 方法,將移除 index.html 的部份前移到 _trim() 後,以便正確檢查,並避免後來重複路徑檢查時產生的錯誤。
    2. +
    + +
    + +
    + +
    +
    日期: 3.18.’07.
    + +
      +
    1. 修正各站的首頁,計數器和上次更新日期,回復用 mod_perl GD 的計數器。 GD 造成記憶體區段錯誤 Segmentation fault 的原因找到了,也解決了。 PHP 中也有 gd 模組,但 PHP 的 gd 用的是內附的 gd 函式庫, Perl 的 GD 用的是系統的 gd 函式庫,同時載入 mod_perl.solibphp5.so 時,兩者版本不同互衝所致。解決方法,只要重新編譯 PHP ,原參數 with-gd=shared 改為 --with-gd=shared,/usr ,改連結系統的 gd 函式庫即可。
    2. +
    + +
    + +
    + +
    +
    日期: 3.16.’07.
    + +
      +
    1. 運用新版 Apache 2 的內容協調功能,新的 prefer-language 環境參數, SetEnvIf CookieHeader add Set-Cookie 設定,終於解決了旅舍的理想,所選的語言可以一直持續下去!過去如果網站語言沒有自動選到自己習慣的語言,切到該語言頁後,再看下一頁,又會回到之前錯誤的語言中。現在利用新版 Apache 2 的語言協調選擇功能,終於可以把語言固定下來了!耶! ^_*'
    2. +
    + +
    + +
    + +
    +
    日期: 3.15.’07.
    + +
      +
    1. 修正各站的首頁,最近更新日期暫時改用 CGI 的圖型。 GD 在 mod_perl 2 下會 crash , bug 尚待回報。
    2. +
    + +
    + +
    + +
    +
    日期: 3.14.’07.
    + +
      +
    1. 修正 Selima::imacat::Rebuild 模組的 rebuild_links() 函式、 rebuild_diary() 函式、 rebuild_changelog() 函式和 rebuild_literalzh() 函式,取消製作預設語言的符號連結。 Apache 2 有 ForceLanguagePriority 設定,不需要另外製作預設語言的符號連結。
    2. +
    + +
    + +
    + +
    +
    日期: 3.13.’07.
    + +

    昇級為 Apache 2 + mod_perl 2 。

    + +
      +
    1. 修正各站的首頁,計數器暫時改用 CGI 的計數器。 GD 在 mod_perl 2 下會 crash ,原因待查。
    2. +
    3. 伺服器版本昇級為 Apache 2 (2.0.59) + mod_perl 2 (2.0.3) 。
    4. +
    5. Selima 系統版本更新為 3.00 。由 mod_perl 1 昇級到 mod_perl 2 ,為配合 mod_perl 2 的新處理方式,系統程式大範圍重寫,異動非常大。
    6. +
    + +
    + +
    + +
    +
    日期: 3.13.’07.
    + +
      +
    1. 修正 Selima::HTTP 模組及 Selima::Destroy 類別,原用 $r->header_out() 方法,改用 $r->headers_out()->set() 方法。
    2. +
    3. 修正 Selima::Login 模組 upd_login_info() 函式的註解,原 Logged-in from Apache/mod_perl HTTP Authentication 改為 Logged-in from Selima::AuthDig Digest Authentication
    4. +
    5. 修正 Selima::Init 模組的 initenv() 函式,原先直接檢查 Selima::AuthDig 傳回的 $AUTHINFO ,改為依是否載入 $INC{"Apache/AuthDigest/API.pm"} ,而檢查 $AUTHINFO$ENV{"REMOTE_USER"} ,來決定 unauth()upd_login_info() 。雖然用 mod_auth_digest 登入,程式本身無法和登入過程一體化,但是應該可以相信 Apache 的登入資訊,不會有安全問題吧~
    6. +
    7. 修正 showenv.cgi 程式,修正在 mod_perl 2 下時,顯示的方法名稱。
    8. +
    9. 修正 Selima::DataVars 模組,原先以 $ENV{"GATEWAY_INTERFACE"} 檢查 $IS_CGI ,因 mod_perl 2 下載入這個模組的時候還沒有 $ENV{"GATEWAY_INTERFACE"} ,改為以 $ENV{"GATEWAY_INTERFACE"}$ENV{"MOD_PERL"} 檢查。
    10. +
    11. 修正 Selima::Destroy 模組的 DESTROY() 方法,原先在 mod_perl 下自動執行 $r->send_http_header() ,改為檢查只有 mod_perl 1 下才會執行 $r->send_http_header()
    12. +
    13. 修正 Selima::Init 模組的 initvars() 方法,原用 $r->headers_in()->add() 方法,改用 $r->headers_in()->set() 方法。
    14. +
    15. 修正 Selima::Init 模組的 initenv() 函式,先執行 $MAIN->can("siteconf") ,以取得 $PACKAGE ,以便傳給 initvars() ;修正 initvars() 原型,由 initvars(;$) 改為 initvars($) ,因為現在一定會傳入參數,不可能省略。
    16. +
    17. 修正 Selima::DecForm 模組的 init_forms() 函式,原先由 $rawpost = $r->content 取得 POST 表單的內容,改依 $IS_MP2 判斷,由 $r->read($rawpost, $r->headers_in->get("Content-Length"))$rawpost = $r->content 取得 POST 表單的內容。
    18. +
    19. 修正 Selima::HTTP 模組的 http_*() 函式,原用 $r->err_header_out() 方法,改用 $r->err_headers_out()->set() 方法;加上引用 Apache2::Response;
    20. +
    21. 修正 Selima::Destroy 類別的 DESTROY() 方法,原用 $r->headers_out->set("Content-Length"=>length $HTML); 方法,改用 $r->set_content_length(length $HTML); 方法。
    22. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 9 | + 10 | + 11 | + 12 | + 13 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0012.html.en.html b/htdocs/imacat/me/changelog/0012.html.en.html new file mode 120000 index 0000000..6d499fd --- /dev/null +++ b/htdocs/imacat/me/changelog/0012.html.en.html @@ -0,0 +1 @@ +0012.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0012.html.en.xhtml b/htdocs/imacat/me/changelog/0012.html.en.xhtml new file mode 100644 index 0000000..4da2c2a --- /dev/null +++ b/htdocs/imacat/me/changelog/0012.html.en.xhtml @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 12 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 12

    + +
    + +
    + +
    +
    Date: 9.22.’07.
    + +
      +
    1. 將所有 *::Public::* 類別改名為 *::*::Public 類別,以符合 Perl 的命名慣例。
    2. +
    3. 新增 acctsubj_lastlv_list_* 資料庫瀏覽;新增 Selima::List::AcctSubj::LastLv 類別;修正 acctsubj.cgi 程式,依需要改用 Selima::List::AcctSubj::LastLv 的列表類別。
    4. +
    5. 修正 Selima::imacat::Items 模組,刪除已搬到 Selima::Account 的重覆 acctsubj_title() 函數。
    6. +
    7. 修正 Selima::Form::AcctTrx 類別的 new() 方法,更正 $$args{"cols"} 的欄位。
    8. +
    9. 修正 Selima::Cache 模組,加上 %Account_acctsubj_code 快取變數;修正 Selima::Account 模組,新增 acctsubj_code() 函式。
    10. +
    11. 修正 accttrx.cgi 程式的 fetch_curitem() 函式,加上判別應為何種傳票。
    12. +
    13. 修正 Selima::imacat::Form::LiteralZh 類別的 _html_col_poems() 方法,加上刪除表格的條件判別。
    14. +
    15. 修正 Selima::Form::AcctTrx 類別的 new() 方法,加上 $self->{"colspan"}
    16. +
    17. 修正 Selima::List::AcctSubj 類別最前面的註解的檔名。
    18. +
    19. 修正 Selima::Checker::AcctSubj 類別、 Selima::List::AcctTrx 類別、 Selima::List::AcctSubj 類別、 Selima::List::Guestbook::Public 類別、 Selima::Form::AcctTrx 類別,更正訊息文字的領域為共用領域。
    20. +
    21. 修正 Selima::Checker::AcctSubj 類別、 Selima::Form::AcctSubj 類別的名稱宣告,移除多餘的空白。
    22. +
    23. 修正 Selima::imacat::Form::LtZhPoem 類別的 _html_col_ord() 方法,修正錯誤的註解。
    24. +
    25. 修正 Selima::Form::AcctTrx 類別,加上 _html_coltmpl_ro_loop_rec() 方法、 _html_col_ord() 方法和 _html_col_recs() 方法;修正 new() 方法,加上 ${$self->{"maxlens"}}{"ord"}
    26. +
    27. 修正 accttrx.cgi 程式的 check_post() 函式,更正要檢查的欄位。
    28. +
    29. 修正 Selima::Checker::AcctSubj 類別,加上繼承 _check_title() 方法的註解。
    30. +
    31. 修正 Selima::DataVars 模組,加上 FORM_ACCTTRX 常數;修正 Selima::Init 模組,加上 FORM_ACCTTRX 程式的位置。
    32. +
    33. 修正 Selima::Checker 類別,加上 _check_date() 方法。
    34. +
    35. 新增 Selima::Checker::AcctTrx 類別與 Selima::Checker::AcctRec 類別。
    36. +
    37. 修正 Selima::Processor::AcctSubj 類別的 new() 方法,移除多餘的 $self->{"form_cols"} 屬性
    38. +
    39. 修正 Selima::Form::AcctTrx 類別,加上 formsub 子表單類型的隱藏欄位;將網頁標題 title 移到判別子表單傳票類型 subtype 之後再決定,並依傳票不同等設定不同的標題;修正 _html_coltmpl_loop_rec() 函式,因表格內格標題有直有橫,原先在標題格用 scope="ro" ,改在內格加上 headers="…" 設定標題格,並加上 $rowhdrs 變數,依表格類型決定是不是要加上 thnew 標題格;修正不同子表單的註解文字;修正 _html_coltmpl_loop_rec() 函式中轉帳傳票的計算順序,先計算借方,以取得前後一致性,並修正轉帳傳票表格中借貸混亂的問題;加上 _html_col_dsc() 方法。
    40. +
    + +
    + +
    + +
    +
    Date: 9.20.’07.
    + +
      +
    1. 修正 Selima::List::AcctTrx 類別的 html_newlink() 方法,傳票類別的參數 formcat 改名為 formsub
    2. +
    3. 修正 Selima::Form 類別的 _html_coltmpl_select() 方法,移除未使用的 $val 變數。
    4. +
    5. 修正 Selima::Cache 模組,新增 %Account_acctsubj_title 快取變數。
    6. +
    7. 修正資料庫定義,新增 acctsubj_fullcodetitle() 函式、 acctsubj_recent() 函式與 acctsubj_islastlv() 函式。
    8. +
    9. 新增 Selima::Account 模組。
    10. +
    11. 新增 Selima::Form::AcctTrx 模組。
    12. +
    + +
    + +
    + +
    +
    Date: 9.13.’07.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_spammers() 函式,新增一個擋廣告留言的規則。
    2. +
    + +
    + +
    + +
    +
    Date: 9.11.’07.
    + +
      +
    1. 修正資料庫定義的各函式,參數名稱 *_here 改名為 *_arg ,以更易解。
    2. +
    3. 修正 acctsubj_ischild() 函式,找不到大類時原傳回假,改傳回真。大類是否存在由外鍵檢查確認即可。改傳回真雖有點不自然,但可避免資料庫匯出匯入時,匯入資料順序不定,所可能導致找不到大類的問題。
    4. +
    + +
    + +
    + +
    +
    Date: 9.10.’07.
    + +
      +
    1. 修正資料庫定義的 *_ischild() 函式,第二個參數名稱 child 改成 child_here
    2. +
    + +
    + +
    + +
    +
    Date: 9.2.’07.
    + +
      +
    1. 修正 Selima::HTTP 模組的 http_*() 函式,在非 CGI 下,原先完全沒有顯示訊息,現已修正。
    2. +
    3. 修正 Selima::LogIn 模組的 upd_login_info() ,加上在終端機下,以終端機使用者名稱模擬作為登入名稱,由資料庫取得程式登入資訊;加上設定 usersn
    4. +
    5. 修正 Selima::Session 模組,在終端機下, session 改存暫存目錄;修正 Selima::Init 模組的 initenv() 函式,取消終端機下不用 session 的限制。
    6. +
    7. 修正 Selima::Init 模組的 initenv() 函式,加上在終端機執行時亦要執行 upd_login_info() 模擬取得使用者登入資訊;加上在終端機下,不提早依 get_login_sn() 結果判斷 unauth()
    8. +
    + +
    + +
    + +
    +
    Date: 9.1.’07.
    + +
      +
    1. 修正 Selima::DBD::Pg 類別和 Selima::DBD::mysql 類別的 new() 方法,加上在命令列執行時,提示輸入資料庫密碼以登入資料庫的功能。
    2. +
    + +
    + +
    + +
    +
    Date: 8.31.’07.
    + +
      +
    1. Selima::imacat::Acct* 類別改名為 Selima::Acct* 類別;修正 Selima::Checker 類別、 Selima::Form 類別、 Selima::List 類別、 Selima::Processor 類別、 Selima::imacat 模組、 Selima::imacat::DataVars 模組、 Selima::imacat::Config 模組、 Selima::DataVars 模組、 Selima::Init 模組、 accttrx.cgi 程式, acctsubj.cgi 程式,以配合上述變更。
    2. +
    + +
    + +
    + +
    +
    Date: 8.30.’07.
    + +
      +
    1. 修正 Selima::Checker::LinkCat 類別、 Selima::imacat::Checker::AcctSubj 類別、 Selima::htc::Checker::NLIndex 類別與 Selima::Checker 類別,將 _redir_selparent() 方法和 _redir_delparent() 方法由子類別移到 Selima::Checker 類別作為基礎方法,並將移轉對象改為 FORM_THIS()
    2. +
    3. 刪除資料庫各語言的 *_fulltitle_*() 函式,改寫為 *_fulltitle() 函式,統一處理各語言的標題,減少資料庫定義的複雜度。
    4. +
    5. 修正 links.cgi 程式及 linkcat.cgi 程式的 fetch_curitem() 函式,改自動依單語或多語切換查詢語法,以統一程式碼,並改原用 *_fulltitle_*() 函式為 *_fulltitle() 函式。
    6. +
    7. 修正 Selima::Links 模組的 linkcat_title() 函式及 linkcat_options() 函式,改原用 *_fulltitle_*() 函式為 *_fulltitle() 函式。
    8. +
    + +
    + +
    + +
    +
    Date: 8.28.’07.
    + +
      +
    1. 修正 Selima::imacat::Checker::AcctSubj 類別,修正 _check_parent() 方法,簡化大科目和科目本身是否重複的檢查;修正 _check_code() 英文錯誤訊息 does not exists 動詞時態的錯誤。
    2. +
    3. 修正 saveform.cgi 程式,修正 check_get() 英文錯誤訊息 does not exists 動詞時態的錯誤。
    4. +
    + +
    + +
    + +
    +
    Date: 8.24.’07.
    + +
      +
    1. 加上 acctsubj_fulltitle_*() 資料庫函數,修正 acctsubj_list_* 列表定義,加上 parent 欄位。
    2. +
    3. 修正 Selima::imacat::List::AcctSubj 類別的 new() 方法,欄位標題加上 parent 欄位。
    4. +
    5. 修正 accttrx 資料表定義,加上 dsc 欄位。
    6. +
    7. 修正 Selima::imacat::List::AcctTrx 類別,修正 new() 方法,移除不用的 code 欄位標籤;修正 html_newlink() 方法,改自行顯示現金支出、現金收入與轉帳傳票的三種新建連節。
    8. +
    + +
    + +
    + +
    +
    Date: 8.24.’07.
    + +
      +
    1. 修正各資料庫定義,函數 LPAD() 改用小寫名稱 lpad()lpad() 函數的第三個參數應為文字,原使用數字 0 ,修正為文字 '0' ;修正 acctrecs_list_* 列表,將過長的 subj 欄位定義折行。
    2. +
    3. 修正 Selima::Checker::LinkCat 類別,加上 _redir_delparent() 方法。
    4. +
    5. 修正 linkcat.cgi 程式,加上檢查 delparent 的重導向。
    6. +
    7. 修正 Selima::imacat::List::AcctSubj 類別,修正程式說明;加上 html_newlink() 方法、 html_search() 方法與 liststat_message() 方法。
    8. +
    9. 修正 Selima::imacat::Form::AcctSubj 類別, new() 方法的 $$args{"cols"} 加上 parent 欄位,以方便追蹤、記錄科目層級間的關係;加上 _html_col_parent() 方法。
    10. +
    11. 修正 Selima::imacat::Checker::AcctSubj 類別,錯誤的基本類別 Selima::Checker::Page 類別改正為 Selima::Checker 類別;修正 _check_code() 方法,加上檢查上層科目存不存在;加上 new() 方法、 _check_parent() 方法、 _redir_selparent() 方法與 _redir_delparent() 方法。
    12. +
    13. 加上 Selima::imacat::Processor::AcctSubj 類別。
    14. +
    15. 修正 acctsubj.cgi 程式,修正程式說明、日期與版權年份;移除不需引用的 Encode::HanConvert 模組;修正 $checker 檢查的欄位,加上檢查 selparentdelparent 的重導向;加上 import_selparent() 函式。
    16. +
    17. 修正 Selima::imacat::DataVars 模組,加上 FORM_ACCTSUBJ 常數, clear() 函式加上刪除 $SCRIPTS{FORM_ACCTSUBJ()} ;修正 Selima::imacat::Config 模組的 siteconf() 函式,加上設定 $SCRIPTS{FORM_ACCTSUBJ()}
    18. +
    19. 修正 Selima::imacat::Items 模組,加上 acctsubj_title() 函式。
    20. +
    21. 修正 acctsubj.cgi 程式,修正 fetch_curitem() 函式,加上取得子科目;修正 check_get() 函式及 check_post() 函式,加上刪除時檢查是否有子科目;修正 fetch_curitem() 函式,檢查分錄數時只選 sn 以減少不必要的處理;修正 Selima::imacat::Form::AcctSubj 類別,修正 new() 方法,加上顯示子科目欄位 ssubs ,並當有子科目或引用的分錄時,不顯示刪除的按鈕並說明;加上 _html_col_ssubs() 方法。
    22. +
    23. 加上 Selima::imacat::List::AcctTrx 類別,加上 accttrx.cgi 程式。
    24. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 10 | + 11 | + 12 | + 13 | + 14 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0012.html.zh-cn.html b/htdocs/imacat/me/changelog/0012.html.zh-cn.html new file mode 120000 index 0000000..f5e7fff --- /dev/null +++ b/htdocs/imacat/me/changelog/0012.html.zh-cn.html @@ -0,0 +1 @@ +0012.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0012.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0012.html.zh-cn.xhtml new file mode 100644 index 0000000..e174a5f --- /dev/null +++ b/htdocs/imacat/me/changelog/0012.html.zh-cn.xhtml @@ -0,0 +1,326 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷十二 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷十二

    + +
    + +
    + +
    +
    日期: 9.22.’07.
    + +
      +
    1. 将所有 *::Public::* 类别改名为 *::*::Public 类别,以符合 Perl 的命名惯例。
    2. +
    3. 新增 acctsubj_lastlv_list_* 资料库浏览;新增 Selima::List::AcctSubj::LastLv 类别;修正 acctsubj.cgi 程式,依需要改用 Selima::List::AcctSubj::LastLv 的列表类别。
    4. +
    5. 修正 Selima::imacat::Items 模组,删除已搬到 Selima::Account 的重覆 acctsubj_title() 函数。
    6. +
    7. 修正 Selima::Form::AcctTrx 类别的 new() 方法,更正 $$args{"cols"} 的栏位。
    8. +
    9. 修正 Selima::Cache 模组,加上 %Account_acctsubj_code 快取变数;修正 Selima::Account 模组,新增 acctsubj_code() 函式。
    10. +
    11. 修正 accttrx.cgi 程式的 fetch_curitem() 函式,加上判别应为何种传票。
    12. +
    13. 修正 Selima::imacat::Form::LiteralZh 类别的 _html_col_poems() 方法,加上删除表格的条件判别。
    14. +
    15. 修正 Selima::Form::AcctTrx 类别的 new() 方法,加上 $self->{"colspan"}
    16. +
    17. 修正 Selima::List::AcctSubj 类别最前面的注解的档名。
    18. +
    19. 修正 Selima::Checker::AcctSubj 类别、 Selima::List::AcctTrx 类别、 Selima::List::AcctSubj 类别、 Selima::List::Guestbook::Public 类别、 Selima::Form::AcctTrx 类别,更正讯息文字的领域为共用领域。
    20. +
    21. 修正 Selima::Checker::AcctSubj 类别、 Selima::Form::AcctSubj 类别的名称宣告,移除多余的空白。
    22. +
    23. 修正 Selima::imacat::Form::LtZhPoem 类别的 _html_col_ord() 方法,修正错误的注解。
    24. +
    25. 修正 Selima::Form::AcctTrx 类别,加上 _html_coltmpl_ro_loop_rec() 方法、 _html_col_ord() 方法和 _html_col_recs() 方法;修正 new() 方法,加上 ${$self->{"maxlens"}}{"ord"}
    26. +
    27. 修正 accttrx.cgi 程式的 check_post() 函式,更正要检查的栏位。
    28. +
    29. 修正 Selima::Checker::AcctSubj 类别,加上继承 _check_title() 方法的注解。
    30. +
    31. 修正 Selima::DataVars 模组,加上 FORM_ACCTTRX 常数;修正 Selima::Init 模组,加上 FORM_ACCTTRX 程式的位置。
    32. +
    33. 修正 Selima::Checker 类别,加上 _check_date() 方法。
    34. +
    35. 新增 Selima::Checker::AcctTrx 类别与 Selima::Checker::AcctRec 类别。
    36. +
    37. 修正 Selima::Processor::AcctSubj 类别的 new() 方法,移除多余的 $self->{"form_cols"} 属性
    38. +
    39. 修正 Selima::Form::AcctTrx 类别,加上 formsub 子表单类型的隐藏栏位;将网页标题 title 移到判别子表单传票类型 subtype 之后再决定,并依传票不同等设定不同的标题;修正 _html_coltmpl_loop_rec() 函式,因表格内格标题有直有横,原先在标题格用 scope="ro" ,改在内格加上 headers="…" 设定标题格,并加上 $rowhdrs 变数,依表格类型决定是不是要加上 thnew 标题格;修正不同子表单的注解文字;修正 _html_coltmpl_loop_rec() 函式中转帐传票的计算顺序,先计算借方,以取得前后一致性,并修正转帐传票表格中借贷混乱的问题;加上 _html_col_dsc() 方法。
    40. +
    + +
    + +
    + +
    +
    日期: 9.20.’07.
    + +
      +
    1. 修正 Selima::List::AcctTrx 类别的 html_newlink() 方法,传票类别的参数 formcat 改名为 formsub
    2. +
    3. 修正 Selima::Form 类别的 _html_coltmpl_select() 方法,移除未使用的 $val 变数。
    4. +
    5. 修正 Selima::Cache 模组,新增 %Account_acctsubj_title 快取变数。
    6. +
    7. 修正资料库定义,新增 acctsubj_fullcodetitle() 函式、 acctsubj_recent() 函式与 acctsubj_islastlv() 函式。
    8. +
    9. 新增 Selima::Account 模组。
    10. +
    11. 新增 Selima::Form::AcctTrx 模组。
    12. +
    + +
    + +
    + +
    +
    日期: 9.13.’07.
    + +
      +
    1. 修正 Selima::Init 模组的 checkspam_spammers() 函式,新增一个挡广告留言的规则。
    2. +
    + +
    + +
    + +
    +
    日期: 9.11.’07.
    + +
      +
    1. 修正资料库定义的各函式,参数名称 *_here 改名为 *_arg ,以更易解。
    2. +
    3. 修正 acctsubj_ischild() 函式,找不到大类时原传回假,改传回真。大类是否存在由外键检查确认即可。改传回真虽有点不自然,但可避免资料库汇出汇入时,汇入资料顺序不定,所可能导致找不到大类的问题。
    4. +
    + +
    + +
    + +
    +
    日期: 9.10.’07.
    + +
      +
    1. 修正资料库定义的 *_ischild() 函式,第二个参数名称 child 改成 child_here
    2. +
    + +
    + +
    + +
    +
    日期: 9.2.’07.
    + +
      +
    1. 修正 Selima::HTTP 模组的 http_*() 函式,在非 CGI 下,原先完全没有显示讯息,现已修正。
    2. +
    3. 修正 Selima::LogIn 模组的 upd_login_info() ,加上在终端机下,以终端机使用者名称模拟作为登入名称,由资料库取得程式登入资讯;加上设定 usersn
    4. +
    5. 修正 Selima::Session 模组,在终端机下, session 改存暂存目录;修正 Selima::Init 模组的 initenv() 函式,取消终端机下不用 session 的限制。
    6. +
    7. 修正 Selima::Init 模组的 initenv() 函式,加上在终端机执行时亦要执行 upd_login_info() 模拟取得使用者登入资讯;加上在终端机下,不提早依 get_login_sn() 结果判断 unauth()
    8. +
    + +
    + +
    + +
    +
    日期: 9.1.’07.
    + +
      +
    1. 修正 Selima::DBD::Pg 类别和 Selima::DBD::mysql 类别的 new() 方法,加上在命令列执行时,提示输入资料库密码以登入资料库的功能。
    2. +
    + +
    + +
    + +
    +
    日期: 8.31.’07.
    + +
      +
    1. Selima::imacat::Acct* 类别改名为 Selima::Acct* 类别;修正 Selima::Checker 类别、 Selima::Form 类别、 Selima::List 类别、 Selima::Processor 类别、 Selima::imacat 模组、 Selima::imacat::DataVars 模组、 Selima::imacat::Config 模组、 Selima::DataVars 模组、 Selima::Init 模组、 accttrx.cgi 程式, acctsubj.cgi 程式,以配合上述变更。
    2. +
    + +
    + +
    + +
    +
    日期: 8.30.’07.
    + +
      +
    1. 修正 Selima::Checker::LinkCat 类别、 Selima::imacat::Checker::AcctSubj 类别、 Selima::htc::Checker::NLIndex 类别与 Selima::Checker 类别,将 _redir_selparent() 方法和 _redir_delparent() 方法由子类别移到 Selima::Checker 类别作为基础方法,并将移转对象改为 FORM_THIS()
    2. +
    3. 删除资料库各语言的 *_fulltitle_*() 函式,改写为 *_fulltitle() 函式,统一处理各语言的标题,减少资料库定义的复杂度。
    4. +
    5. 修正 links.cgi 程式及 linkcat.cgi 程式的 fetch_curitem() 函式,改自动依单语或多语切换查询语法,以统一程式码,并改原用 *_fulltitle_*() 函式为 *_fulltitle() 函式。
    6. +
    7. 修正 Selima::Links 模组的 linkcat_title() 函式及 linkcat_options() 函式,改原用 *_fulltitle_*() 函式为 *_fulltitle() 函式。
    8. +
    + +
    + +
    + +
    +
    日期: 8.28.’07.
    + +
      +
    1. 修正 Selima::imacat::Checker::AcctSubj 类别,修正 _check_parent() 方法,简化大科目和科目本身是否重复的检查;修正 _check_code() 英文错误讯息 does not exists 动词时态的错误。
    2. +
    3. 修正 saveform.cgi 程式,修正 check_get() 英文错误讯息 does not exists 动词时态的错误。
    4. +
    + +
    + +
    + +
    +
    日期: 8.24.’07.
    + +
      +
    1. 加上 acctsubj_fulltitle_*() 资料库函数,修正 acctsubj_list_* 列表定义,加上 parent 栏位。
    2. +
    3. 修正 Selima::imacat::List::AcctSubj 类别的 new() 方法,栏位标题加上 parent 栏位。
    4. +
    5. 修正 accttrx 资料表定义,加上 dsc 栏位。
    6. +
    7. 修正 Selima::imacat::List::AcctTrx 类别,修正 new() 方法,移除不用的 code 栏位标签;修正 html_newlink() 方法,改自行显示现金支出、现金收入与转帐传票的三种新建连节。
    8. +
    + +
    + +
    + +
    +
    日期: 8.24.’07.
    + +
      +
    1. 修正各资料库定义,函数 LPAD() 改用小写名称 lpad()lpad() 函数的第三个参数应为文字,原使用数字 0 ,修正为文字 '0' ;修正 acctrecs_list_* 列表,将过长的 subj 栏位定义折行。
    2. +
    3. 修正 Selima::Checker::LinkCat 类别,加上 _redir_delparent() 方法。
    4. +
    5. 修正 linkcat.cgi 程式,加上检查 delparent 的重导向。
    6. +
    7. 修正 Selima::imacat::List::AcctSubj 类别,修正程式说明;加上 html_newlink() 方法、 html_search() 方法与 liststat_message() 方法。
    8. +
    9. 修正 Selima::imacat::Form::AcctSubj 类别, new() 方法的 $$args{"cols"} 加上 parent 栏位,以方便追踪、记录科目层级间的关系;加上 _html_col_parent() 方法。
    10. +
    11. 修正 Selima::imacat::Checker::AcctSubj 类别,错误的基本类别 Selima::Checker::Page 类别改正为 Selima::Checker 类别;修正 _check_code() 方法,加上检查上层科目存不存在;加上 new() 方法、 _check_parent() 方法、 _redir_selparent() 方法与 _redir_delparent() 方法。
    12. +
    13. 加上 Selima::imacat::Processor::AcctSubj 类别。
    14. +
    15. 修正 acctsubj.cgi 程式,修正程式说明、日期与版权年份;移除不需引用的 Encode::HanConvert 模组;修正 $checker 检查的栏位,加上检查 selparentdelparent 的重导向;加上 import_selparent() 函式。
    16. +
    17. 修正 Selima::imacat::DataVars 模组,加上 FORM_ACCTSUBJ 常数, clear() 函式加上删除 $SCRIPTS{FORM_ACCTSUBJ()} ;修正 Selima::imacat::Config 模组的 siteconf() 函式,加上设定 $SCRIPTS{FORM_ACCTSUBJ()}
    18. +
    19. 修正 Selima::imacat::Items 模组,加上 acctsubj_title() 函式。
    20. +
    21. 修正 acctsubj.cgi 程式,修正 fetch_curitem() 函式,加上取得子科目;修正 check_get() 函式及 check_post() 函式,加上删除时检查是否有子科目;修正 fetch_curitem() 函式,检查分录数时只选 sn 以减少不必要的处理;修正 Selima::imacat::Form::AcctSubj 类别,修正 new() 方法,加上显示子科目栏位 ssubs ,并当有子科目或引用的分录时,不显示删除的按钮并说明;加上 _html_col_ssubs() 方法。
    22. +
    23. 加上 Selima::imacat::List::AcctTrx 类别,加上 accttrx.cgi 程式。
    24. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 10 | + 11 | + 12 | + 13 | + 14 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0012.html.zh-tw.html b/htdocs/imacat/me/changelog/0012.html.zh-tw.html new file mode 120000 index 0000000..72c8a75 --- /dev/null +++ b/htdocs/imacat/me/changelog/0012.html.zh-tw.html @@ -0,0 +1 @@ +0012.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0012.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0012.html.zh-tw.xhtml new file mode 100644 index 0000000..bb9f70d --- /dev/null +++ b/htdocs/imacat/me/changelog/0012.html.zh-tw.xhtml @@ -0,0 +1,326 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷十二 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷十二

    + +
    + +
    + +
    +
    日期: 9.22.’07.
    + +
      +
    1. 將所有 *::Public::* 類別改名為 *::*::Public 類別,以符合 Perl 的命名慣例。
    2. +
    3. 新增 acctsubj_lastlv_list_* 資料庫瀏覽;新增 Selima::List::AcctSubj::LastLv 類別;修正 acctsubj.cgi 程式,依需要改用 Selima::List::AcctSubj::LastLv 的列表類別。
    4. +
    5. 修正 Selima::imacat::Items 模組,刪除已搬到 Selima::Account 的重覆 acctsubj_title() 函數。
    6. +
    7. 修正 Selima::Form::AcctTrx 類別的 new() 方法,更正 $$args{"cols"} 的欄位。
    8. +
    9. 修正 Selima::Cache 模組,加上 %Account_acctsubj_code 快取變數;修正 Selima::Account 模組,新增 acctsubj_code() 函式。
    10. +
    11. 修正 accttrx.cgi 程式的 fetch_curitem() 函式,加上判別應為何種傳票。
    12. +
    13. 修正 Selima::imacat::Form::LiteralZh 類別的 _html_col_poems() 方法,加上刪除表格的條件判別。
    14. +
    15. 修正 Selima::Form::AcctTrx 類別的 new() 方法,加上 $self->{"colspan"}
    16. +
    17. 修正 Selima::List::AcctSubj 類別最前面的註解的檔名。
    18. +
    19. 修正 Selima::Checker::AcctSubj 類別、 Selima::List::AcctTrx 類別、 Selima::List::AcctSubj 類別、 Selima::List::Guestbook::Public 類別、 Selima::Form::AcctTrx 類別,更正訊息文字的領域為共用領域。
    20. +
    21. 修正 Selima::Checker::AcctSubj 類別、 Selima::Form::AcctSubj 類別的名稱宣告,移除多餘的空白。
    22. +
    23. 修正 Selima::imacat::Form::LtZhPoem 類別的 _html_col_ord() 方法,修正錯誤的註解。
    24. +
    25. 修正 Selima::Form::AcctTrx 類別,加上 _html_coltmpl_ro_loop_rec() 方法、 _html_col_ord() 方法和 _html_col_recs() 方法;修正 new() 方法,加上 ${$self->{"maxlens"}}{"ord"}
    26. +
    27. 修正 accttrx.cgi 程式的 check_post() 函式,更正要檢查的欄位。
    28. +
    29. 修正 Selima::Checker::AcctSubj 類別,加上繼承 _check_title() 方法的註解。
    30. +
    31. 修正 Selima::DataVars 模組,加上 FORM_ACCTTRX 常數;修正 Selima::Init 模組,加上 FORM_ACCTTRX 程式的位置。
    32. +
    33. 修正 Selima::Checker 類別,加上 _check_date() 方法。
    34. +
    35. 新增 Selima::Checker::AcctTrx 類別與 Selima::Checker::AcctRec 類別。
    36. +
    37. 修正 Selima::Processor::AcctSubj 類別的 new() 方法,移除多餘的 $self->{"form_cols"} 屬性
    38. +
    39. 修正 Selima::Form::AcctTrx 類別,加上 formsub 子表單類型的隱藏欄位;將網頁標題 title 移到判別子表單傳票類型 subtype 之後再決定,並依傳票不同等設定不同的標題;修正 _html_coltmpl_loop_rec() 函式,因表格內格標題有直有橫,原先在標題格用 scope="ro" ,改在內格加上 headers="…" 設定標題格,並加上 $rowhdrs 變數,依表格類型決定是不是要加上 thnew 標題格;修正不同子表單的註解文字;修正 _html_coltmpl_loop_rec() 函式中轉帳傳票的計算順序,先計算借方,以取得前後一致性,並修正轉帳傳票表格中借貸混亂的問題;加上 _html_col_dsc() 方法。
    40. +
    + +
    + +
    + +
    +
    日期: 9.20.’07.
    + +
      +
    1. 修正 Selima::List::AcctTrx 類別的 html_newlink() 方法,傳票類別的參數 formcat 改名為 formsub
    2. +
    3. 修正 Selima::Form 類別的 _html_coltmpl_select() 方法,移除未使用的 $val 變數。
    4. +
    5. 修正 Selima::Cache 模組,新增 %Account_acctsubj_title 快取變數。
    6. +
    7. 修正資料庫定義,新增 acctsubj_fullcodetitle() 函式、 acctsubj_recent() 函式與 acctsubj_islastlv() 函式。
    8. +
    9. 新增 Selima::Account 模組。
    10. +
    11. 新增 Selima::Form::AcctTrx 模組。
    12. +
    + +
    + +
    + +
    +
    日期: 9.13.’07.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_spammers() 函式,新增一個擋廣告留言的規則。
    2. +
    + +
    + +
    + +
    +
    日期: 9.11.’07.
    + +
      +
    1. 修正資料庫定義的各函式,參數名稱 *_here 改名為 *_arg ,以更易解。
    2. +
    3. 修正 acctsubj_ischild() 函式,找不到大類時原傳回假,改傳回真。大類是否存在由外鍵檢查確認即可。改傳回真雖有點不自然,但可避免資料庫匯出匯入時,匯入資料順序不定,所可能導致找不到大類的問題。
    4. +
    + +
    + +
    + +
    +
    日期: 9.10.’07.
    + +
      +
    1. 修正資料庫定義的 *_ischild() 函式,第二個參數名稱 child 改成 child_here
    2. +
    + +
    + +
    + +
    +
    日期: 9.2.’07.
    + +
      +
    1. 修正 Selima::HTTP 模組的 http_*() 函式,在非 CGI 下,原先完全沒有顯示訊息,現已修正。
    2. +
    3. 修正 Selima::LogIn 模組的 upd_login_info() ,加上在終端機下,以終端機使用者名稱模擬作為登入名稱,由資料庫取得程式登入資訊;加上設定 usersn
    4. +
    5. 修正 Selima::Session 模組,在終端機下, session 改存暫存目錄;修正 Selima::Init 模組的 initenv() 函式,取消終端機下不用 session 的限制。
    6. +
    7. 修正 Selima::Init 模組的 initenv() 函式,加上在終端機執行時亦要執行 upd_login_info() 模擬取得使用者登入資訊;加上在終端機下,不提早依 get_login_sn() 結果判斷 unauth()
    8. +
    + +
    + +
    + +
    +
    日期: 9.1.’07.
    + +
      +
    1. 修正 Selima::DBD::Pg 類別和 Selima::DBD::mysql 類別的 new() 方法,加上在命令列執行時,提示輸入資料庫密碼以登入資料庫的功能。
    2. +
    + +
    + +
    + +
    +
    日期: 8.31.’07.
    + +
      +
    1. Selima::imacat::Acct* 類別改名為 Selima::Acct* 類別;修正 Selima::Checker 類別、 Selima::Form 類別、 Selima::List 類別、 Selima::Processor 類別、 Selima::imacat 模組、 Selima::imacat::DataVars 模組、 Selima::imacat::Config 模組、 Selima::DataVars 模組、 Selima::Init 模組、 accttrx.cgi 程式, acctsubj.cgi 程式,以配合上述變更。
    2. +
    + +
    + +
    + +
    +
    日期: 8.30.’07.
    + +
      +
    1. 修正 Selima::Checker::LinkCat 類別、 Selima::imacat::Checker::AcctSubj 類別、 Selima::htc::Checker::NLIndex 類別與 Selima::Checker 類別,將 _redir_selparent() 方法和 _redir_delparent() 方法由子類別移到 Selima::Checker 類別作為基礎方法,並將移轉對象改為 FORM_THIS()
    2. +
    3. 刪除資料庫各語言的 *_fulltitle_*() 函式,改寫為 *_fulltitle() 函式,統一處理各語言的標題,減少資料庫定義的複雜度。
    4. +
    5. 修正 links.cgi 程式及 linkcat.cgi 程式的 fetch_curitem() 函式,改自動依單語或多語切換查詢語法,以統一程式碼,並改原用 *_fulltitle_*() 函式為 *_fulltitle() 函式。
    6. +
    7. 修正 Selima::Links 模組的 linkcat_title() 函式及 linkcat_options() 函式,改原用 *_fulltitle_*() 函式為 *_fulltitle() 函式。
    8. +
    + +
    + +
    + +
    +
    日期: 8.28.’07.
    + +
      +
    1. 修正 Selima::imacat::Checker::AcctSubj 類別,修正 _check_parent() 方法,簡化大科目和科目本身是否重複的檢查;修正 _check_code() 英文錯誤訊息 does not exists 動詞時態的錯誤。
    2. +
    3. 修正 saveform.cgi 程式,修正 check_get() 英文錯誤訊息 does not exists 動詞時態的錯誤。
    4. +
    + +
    + +
    + +
    +
    日期: 8.24.’07.
    + +
      +
    1. 加上 acctsubj_fulltitle_*() 資料庫函數,修正 acctsubj_list_* 列表定義,加上 parent 欄位。
    2. +
    3. 修正 Selima::imacat::List::AcctSubj 類別的 new() 方法,欄位標題加上 parent 欄位。
    4. +
    5. 修正 accttrx 資料表定義,加上 dsc 欄位。
    6. +
    7. 修正 Selima::imacat::List::AcctTrx 類別,修正 new() 方法,移除不用的 code 欄位標籤;修正 html_newlink() 方法,改自行顯示現金支出、現金收入與轉帳傳票的三種新建連節。
    8. +
    + +
    + +
    + +
    +
    日期: 8.24.’07.
    + +
      +
    1. 修正各資料庫定義,函數 LPAD() 改用小寫名稱 lpad()lpad() 函數的第三個參數應為文字,原使用數字 0 ,修正為文字 '0' ;修正 acctrecs_list_* 列表,將過長的 subj 欄位定義折行。
    2. +
    3. 修正 Selima::Checker::LinkCat 類別,加上 _redir_delparent() 方法。
    4. +
    5. 修正 linkcat.cgi 程式,加上檢查 delparent 的重導向。
    6. +
    7. 修正 Selima::imacat::List::AcctSubj 類別,修正程式說明;加上 html_newlink() 方法、 html_search() 方法與 liststat_message() 方法。
    8. +
    9. 修正 Selima::imacat::Form::AcctSubj 類別, new() 方法的 $$args{"cols"} 加上 parent 欄位,以方便追蹤、記錄科目層級間的關係;加上 _html_col_parent() 方法。
    10. +
    11. 修正 Selima::imacat::Checker::AcctSubj 類別,錯誤的基本類別 Selima::Checker::Page 類別改正為 Selima::Checker 類別;修正 _check_code() 方法,加上檢查上層科目存不存在;加上 new() 方法、 _check_parent() 方法、 _redir_selparent() 方法與 _redir_delparent() 方法。
    12. +
    13. 加上 Selima::imacat::Processor::AcctSubj 類別。
    14. +
    15. 修正 acctsubj.cgi 程式,修正程式說明、日期與版權年份;移除不需引用的 Encode::HanConvert 模組;修正 $checker 檢查的欄位,加上檢查 selparentdelparent 的重導向;加上 import_selparent() 函式。
    16. +
    17. 修正 Selima::imacat::DataVars 模組,加上 FORM_ACCTSUBJ 常數, clear() 函式加上刪除 $SCRIPTS{FORM_ACCTSUBJ()} ;修正 Selima::imacat::Config 模組的 siteconf() 函式,加上設定 $SCRIPTS{FORM_ACCTSUBJ()}
    18. +
    19. 修正 Selima::imacat::Items 模組,加上 acctsubj_title() 函式。
    20. +
    21. 修正 acctsubj.cgi 程式,修正 fetch_curitem() 函式,加上取得子科目;修正 check_get() 函式及 check_post() 函式,加上刪除時檢查是否有子科目;修正 fetch_curitem() 函式,檢查分錄數時只選 sn 以減少不必要的處理;修正 Selima::imacat::Form::AcctSubj 類別,修正 new() 方法,加上顯示子科目欄位 ssubs ,並當有子科目或引用的分錄時,不顯示刪除的按鈕並說明;加上 _html_col_ssubs() 方法。
    22. +
    23. 加上 Selima::imacat::List::AcctTrx 類別,加上 accttrx.cgi 程式。
    24. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 10 | + 11 | + 12 | + 13 | + 14 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0013.html.en.html b/htdocs/imacat/me/changelog/0013.html.en.html new file mode 120000 index 0000000..79e5d2f --- /dev/null +++ b/htdocs/imacat/me/changelog/0013.html.en.html @@ -0,0 +1 @@ +0013.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0013.html.en.xhtml b/htdocs/imacat/me/changelog/0013.html.en.xhtml new file mode 100644 index 0000000..7c8d7f0 --- /dev/null +++ b/htdocs/imacat/me/changelog/0013.html.en.xhtml @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 13 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 13

    + +
    + +
    + +
    +
    Date: 9.27.’07.
    + +
      +
    1. 修正 Selima::List 類別的 html() 方法,將 html_lists_switch() 方法移到 html_newlink() 方法之後。同樣調動兩個方法程式碼在程式檔中出現的順序。
    2. +
    3. 修正 Selima::List::Accounting::Reports::Subject 類別的 方法,移除不必要的變數,將 @conds 改用 @_ ,並加上漏掉的條件初始化。
    4. +
    5. 修正 acct*.cgi 程式,限於加密時執行。
    6. +
    7. 修正 acctreps.cgi 程式,修正 check_get() 函式,移除未用到的變數 $error ;修正 main() 函式,加上對要求限為 GET 方法的限制,以便仍能處理列表的使用者偏好。
    8. +
    9. 修正 Selima::List::Accounting::Reports::Cash 類別,並新增 Selima::List::Accounting::Reports::CashSum 類別,將現金摘要分離出來作為獨立類別。
    10. +
    + +
    + +
    + +
    +
    Date: 9.27.’07.
    + +
      +
    1. 修正 common.js 指令檔的 isDate() 函式, parasInt(dateText.substr(*,*)) 改用 dateText.substr(*,*) * 1 ,以解決 parseInt 碰到 09 會變成 0 的問題。
    2. +
    3. 修正 accounting.js 指令檔的 setAutoSummary() 函式,原先一一核對科目選項,改用 selectedIndex 屬性。
    4. +
    5. 修正 accounting.js 指令檔與 Selima::List::Accounting::Reports 類別,查詢表格加上 id ,將 disableNoUseRanges() 函式改名為 acctRepQueryDisableNoUseRanges() 函式,並取消接受的表格參數,改由 id 取得文件中的表格,以便應用在 onload 事件中。
    6. +
    7. 修正 List 類別的 page_param() 方法,增加若有 onload 屬性時回傳,並修正回傳值,不論有沒有結果一律回傳。
    8. +
    9. 修正 Selima::List::Accounting::Reports 類別,修正 new() 方法,預先儲存日期範圍;修正 pre_filter() 方法和 html_search() 方法,改用預先儲存的日期範圍。
    10. +
    11. 刪除 acctrep_cashsum_list 資料瀏覽;修正 Selima::List::Accounting::Reports::Cash 類別的 new() 方法、 fetch() 方法和 pre_filter() 方法,加上分月現金總覽。分月現金總覽應該獨立一個類別處理,但是目前暫時這樣就好。
    12. +
    + +
    + +
    + +
    +
    Date: 9.26.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports 類別,加上建新傳票的連結,以便單一窗口可以記帳、查帳。
    2. +
    3. 修正 Selima::*::HTML 函式的 @ADMIN_SCRIPTS 變數,將報表移到最前面。
    4. +
    5. 修正樣式表中預覽標誌樣式的筆誤 backgrounc-color
    6. +
    7. 修正 acct*.cgi 程式,加上載入 JavaScript 程式檔;加上 accounting.js 指令檔。
    8. +
    9. 修正 Selima::Form::AcctTrx 類別的 _html_coltmpl_loop_rec() ,加上某些特定科目異動時,自動設定摘要的功能,以自動設定摘要中的月份,統一摘要文字。
    10. +
    11. 加上 emandycommon.js 指令檔與 lang.zh-tw.js 指令檔。
    12. +
    13. 修正 common.js 指令檔,加上 isDate() 日期檢查函式。
    14. +
    15. 修正 Selima::List::Accounting::Reports 類別的 html_search() 方法,將報表類型設定方式,由原來的查詢表單改成超連結,並且在未決定報表類型時,不顯示查詢表單,以解決報表類型與查詢表單在同一個表格內,切換報表類型時查詢結果的大混亂。
    16. +
    17. 修正 Selima::List::Accounting::Reports 類別的 html_search() 方法,將科目移到日期範圍之前,並增加程式區塊的註解。
    18. +
    19. 修正 Selima::List::Accounting::Reports 類別的 html_search() 方法,變更日期範圍選項時呼叫 disableNoUseRanges() 函式;修正 accounting.js 指令檔,增加 disableNoUseRanges() 函式。
    20. +
    + +
    + +
    + +
    +
    Date: 9.25.’07.
    + +
      +
    1. 修正 Selima::Processor::AcctTrx 類別的 _save_cols() 方法, fmtdate() 比較日期是否異動時加上括弧,以免因運算優先次序誤判。
    2. +
    3. 修正 Selima::Form::AcctTrx 類別,修正 new() 方法,檢查傳票類別是否合法。。
    4. +
    5. 修正 Selima::Checker::AcctTrx 類別,移除多餘的 _redir_delsubj() 方法;修正 new() 方法與 _check_recs() 方法,事先於 new() 方法儲存與處理傳票類別,以便其它方法也可以取得傳票類別。
    6. +
    7. 修正 Selima::Form::AcctTrx 類別,當現有傳票為現金支出或收入傳票時,加上轉為轉帳傳票的按鈕;修正 accttrx.cgi 程式,加上是否按下轉為轉帳傳票按鈕的檢查;修正 Selima::Checker::AcctTrx 類別,加上 _redir_cnvttrans() 方法,檢查並轉為轉帳傳票。
    8. +
    9. 修正 Selima::Processor::AcctTrx 類別,當現金收入或支出傳票存檔時,保留現金原有的摘要不動。
    10. +
    11. 修正資料表定義,加上 sum_cash_income() 函式、 sum_cash_expense() 函式、 sum_cash_balance() 函式及 accttrep_cashsum_list 瀏覽。
    12. +
    + +
    + +
    + +
    +
    Date: 9.24.’07.
    + +
      +
    1. Selima::List::Acct* 類別更名為 Selima::List::Accounting::* ,以便擴充功能。
    2. +
    3. Selima::Account 模組更名為 Selima::Accounting 模組。
    4. +
    5. 修正 acctrecs.cgi 程式,加上 import_seltrx() 函式和 import_selsubj() 函式的原型宣告;修正 accttrx.cgi 程式,加上 import_selsubj() 函式的原型宣告;修正 acctsubj.cgi 程式,加上 import_selparent() 函式的原型宣告。
    6. +
    7. 修正 Selima::List::Accounting::Records 類別,移除用不到的引用 Selima::AddGet 模組和 Selima::DataVars 模組。
    8. +
    9. 修正 acctrecs_list_* 資料瀏覽的定義, accttrx.created 欄位更正為 accttrx.date 欄位。
    10. +
    11. 修正 Selima::List::Accounting::Records 類別 new() 方法的預設排序。
    12. +
    13. 修正 Selima::Format 模組,新增 fmtntamount() 函式。
    14. +
    15. 新增 acctrep_subj_list 資料表瀏覽、 Selima::List::Accounting::Reports 類別、 Selima::List::Accounting::Reports::Subject 類別與 acctreps.cgi 程式。
    16. +
    17. 修正 Selima::Session 模組,加上 DEFAUTL_DIR 常數,只有當目錄是預設目錄時,才會淘汰舊檔。
    18. +
    19. 修正資料表定義,移除用不到的 acctsubj_fullcodetitle() 資料庫函式。
    20. +
    21. 修正 acctrecs_list_* 資料瀏覽定義和 accttrx_list_* 資料瀏覽定義,加上日期欄位;修正 acctrecs_list_zhcn 資料瀏覽定義,加上漏掉的 sn 欄位。
    22. +
    23. 修正 Selima::List::Accounting::Records 類別,加上 colval() 方法,以正確顯示金額。
    24. +
    25. 修正 Selima::*::HTML 模組的 @ADMIN_SCRIPTS 變數,將傳票與報表移到前面。
    26. +
    27. 新增 Selima::Accounting::Reports::Cash 類別顯示現金帳。
    28. +
    29. 修正 Selima::List::Accounting::Subjects::LastLv 類別的 new() 方法,依資料庫是否多語選擇不同的 view 名稱。
    30. +
    31. 修正 Selima::Form::AcctTrx 類別的 _html_col_ord() 方法,預設值改為 99 。
    32. +
    33. 修正 Selima::Processor::AcctTrx 類別的 _save_cols() 方法,移除要刪除的分錄不小心被歸零的錯誤。
    34. +
    35. 修正 Selima::Checker::AcctRec 類別的 _check_amount() 方法,接受金額的數字格式並修整,以便調整帳目時剪貼方便;修正 Selima::Checker::AcctTrx 類別的 _check_recs() 方法,將子表單檢查完後的欄位存回來,以便儲存使用修整後的金額數字。
    36. +
    + +
    + +
    + +
    +
    Date: 9.23.’07.
    + +
      +
    1. 修正 Selima::Processor::AcctSubj 類別的 _save_cols() 方法,儲存 parent 欄位原用 addstr() 方法,改正為 addnum() 方法;移除無關的 pageno 欄位。
    2. +
    3. 修正 Selima::Checker::AcctRec 類別,加上 _check_type() 方法。
    4. +
    5. 修正 Selima::Cache 模組,加上 %Account_accttrx_id 快取變數、 %Account_acctsubj_sn 快取變數和 %Account_accttrx_maxord 快取變數;修正 Selima::Account 模組,加上 accttrx_id() 函式、 accttrxid_compose() 函式、 acctsubj_sn() 函式和 accttrx_maxord() 函式。
    6. +
    7. 修正 Selima::Account 模組的 acctsubj_code() 函式,移除未用到的 $lang 變數。
    8. +
    9. 修正 accttrx.cgi 程式的 fetch_curitem() 函式,現金收入和支出原用 1112 零用金,改為 1111 庫存現金。
    10. +
    11. 修正 acctrecs 資料表的定義中 summary 欄位的錯誤定義。
    12. +
    13. 修正 Selima::List::AcctTrx 類別,加上 num 欄位的標題。
    14. +
    15. 修正 accttrx 資料表, dsc 欄位改名為 note ,並更正錯誤的欄位條件;修正 Selima::List::AcctTrx 類別,加上 note 欄位的標題;修正 accttrx.cgi 程式,更正要檢查的欄位;修正 Selima::Form::AcctTrx 類別,更正 new() 方法中要顯示的欄位,將 _html_col_dsc() 方法改名為 _html_col_note() 方法,並將預設文字中 notes 更正為 note ;修正 Selima::Checker::AcctTrx 類別, _check_dsc() 方法更名為 _check_note() 方法;修正 Selima::Processor::AcctTrx 類別的 _save_cols() 方法, dsc 欄位改為 note 欄位。
    16. +
    17. 修正 Selima::Processor 類別的 new() 方法、 _update_cols() 方法和 _modified() 方法,增加前置處理的子處理物件 $self->{"pres"}
    18. +
    19. 修正 Selima::Checker::AcctRec 類別的 new() 方法,處理資料表名稱更正為 acctrecs
    20. +
    21. 修正 Selima::imacat::HTML 模組的 @ADMIN_SCRIPTS 變數, acctrec.cgi 程式更正為 acctrects.cgi
    22. +
    23. 新增 Selima::Processor::AcctTrx 類别和 Selima::Processor::AcctRec 類別。
    24. +
    25. 修正 accttrx 資料表的定義,移除日期和次序唯一的限制,以方便調整次序。
    26. +
    27. 修正 Selima::Form::AcctTrx 類別的 new() 方法,刪除表格時,改由 $self->{"cur"} 取得子表單類型。
    28. +
    29. 修正 Selima::Form 類別的 _html_coltmpl_date() 方法,目前的值更正由 fmtdate() 格式化後再輸出。
    30. +
    31. 修正 Selima::Account模組的 acctsubj_recent_options() 函式,判斷 $hascur 時加上 $value 是否有定義值的判別。
    32. +
    33. 修正 showenv.cgi 程式,移除多餘的 f
    34. +
    35. 修正 Selima::List::AcctTrx 類別與 Selima::List::AcctSubj 類別的訊息,加上 accounting 以資區別。
    36. +
    37. 修正 Selima::List::AcctTrx 類別的 new() 方法, $self->{"DEFAULT_SORTBY"} 更正為 -date,-ord
    38. +
    39. 新增 Selima::List::AcctRecs 類別。
    40. +
    41. 修正 Selima::Form::AcctTrx 類別的 _html_col_recs() 方法,欄位標籤 Subject 改為 Accounting subject 以資識別。
    42. +
    43. 修正 Selima::Checker::AcctRec 類別、 Selima::Checker::AcctSubj 類別、 Selima::Checker::AcctTrx 類別、 Selima::Processor::AcctRec 類別、 Selima::Processor::AcctSubj 類別、 Selima::Processor::AcctTrx 類別、 Selima::Form::AcctSubj 類別、 Selima::Form::AcctTrx 類別、 acctsubj.cgi 程式、 accttrx.cgi 程式的程式訊息,加上 accounting 以資識別。
    44. +
    45. 修正 Selima::Form 類別的 _html_coltmpl_select_multi() 方法,移除未用到的變數 $html
    46. +
    47. 修正 Selima::Form 類別,加上 _html_coltmpl_radio() 方法。
    48. +
    49. 修正 Selima::Form::AcctTrx 類別的 _html_coltmpl_loop_rec() 方法,移除未用到的 $size 變數。
    50. +
    51. 新增 Selima::Form::AcctRec 類別與 acctrecs.cgi 程式。
    52. +
    53. 修正 acctsubj 資料表的定義, code 欄位加一個位數。
    54. +
    55. 修正 acctrecs 資料表的定義, summary 欄位長度限制放寬到 32 。
    56. +
    57. 修正 accttrx_list_* 資料瀏覽的定義,編號用 accttrx.created 欄位更正為 date 欄位。
    58. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 11 | + 12 | + 13 | + 14 | + 15 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0013.html.zh-cn.html b/htdocs/imacat/me/changelog/0013.html.zh-cn.html new file mode 120000 index 0000000..0305381 --- /dev/null +++ b/htdocs/imacat/me/changelog/0013.html.zh-cn.html @@ -0,0 +1 @@ +0013.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0013.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0013.html.zh-cn.xhtml new file mode 100644 index 0000000..1d3088e --- /dev/null +++ b/htdocs/imacat/me/changelog/0013.html.zh-cn.xhtml @@ -0,0 +1,282 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷十三 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷十三

    + +
    + +
    + +
    +
    日期: 9.27.’07.
    + +
      +
    1. 修正 Selima::List 类别的 html() 方法,将 html_lists_switch() 方法移到 html_newlink() 方法之后。同样调动两个方法程式码在程式档中出现的顺序。
    2. +
    3. 修正 Selima::List::Accounting::Reports::Subject 类别的 方法,移除不必要的变数,将 @conds 改用 @_ ,并加上漏掉的条件初始化。
    4. +
    5. 修正 acct*.cgi 程式,限於加密时执行。
    6. +
    7. 修正 acctreps.cgi 程式,修正 check_get() 函式,移除未用到的变数 $error ;修正 main() 函式,加上对要求限为 GET 方法的限制,以便仍能处理列表的使用者偏好。
    8. +
    9. 修正 Selima::List::Accounting::Reports::Cash 类别,并新增 Selima::List::Accounting::Reports::CashSum 类别,将现金摘要分离出来作为独立类别。
    10. +
    + +
    + +
    + +
    +
    日期: 9.27.’07.
    + +
      +
    1. 修正 common.js 指令档的 isDate() 函式, parasInt(dateText.substr(*,*)) 改用 dateText.substr(*,*) * 1 ,以解决 parseInt 碰到 09 会变成 0 的问题。
    2. +
    3. 修正 accounting.js 指令档的 setAutoSummary() 函式,原先一一核对科目选项,改用 selectedIndex 属性。
    4. +
    5. 修正 accounting.js 指令档与 Selima::List::Accounting::Reports 类别,查询表格加上 id ,将 disableNoUseRanges() 函式改名为 acctRepQueryDisableNoUseRanges() 函式,并取消接受的表格参数,改由 id 取得文件中的表格,以便应用在 onload 事件中。
    6. +
    7. 修正 List 类别的 page_param() 方法,增加若有 onload 属性时回传,并修正回传值,不论有没有结果一律回传。
    8. +
    9. 修正 Selima::List::Accounting::Reports 类别,修正 new() 方法,预先储存日期范围;修正 pre_filter() 方法和 html_search() 方法,改用预先储存的日期范围。
    10. +
    11. 删除 acctrep_cashsum_list 资料浏览;修正 Selima::List::Accounting::Reports::Cash 类别的 new() 方法、 fetch() 方法和 pre_filter() 方法,加上分月现金总览。分月现金总览应该独立一个类别处理,但是目前暂时这样就好。
    12. +
    + +
    + +
    + +
    +
    日期: 9.26.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports 类别,加上建新传票的连结,以便单一窗口可以记帐、查帐。
    2. +
    3. 修正 Selima::*::HTML 函式的 @ADMIN_SCRIPTS 变数,将报表移到最前面。
    4. +
    5. 修正样式表中预览标志样式的笔误 backgrounc-color
    6. +
    7. 修正 acct*.cgi 程式,加上载入 JavaScript 程式档;加上 accounting.js 指令档。
    8. +
    9. 修正 Selima::Form::AcctTrx 类别的 _html_coltmpl_loop_rec() ,加上某些特定科目异动时,自动设定摘要的功能,以自动设定摘要中的月份,统一摘要文字。
    10. +
    11. 加上 emandycommon.js 指令档与 lang.zh-tw.js 指令档。
    12. +
    13. 修正 common.js 指令档,加上 isDate() 日期检查函式。
    14. +
    15. 修正 Selima::List::Accounting::Reports 类别的 html_search() 方法,将报表类型设定方式,由原来的查询表单改成超连结,并且在未决定报表类型时,不显示查询表单,以解决报表类型与查询表单在同一个表格内,切换报表类型时查询结果的大混乱。
    16. +
    17. 修正 Selima::List::Accounting::Reports 类别的 html_search() 方法,将科目移到日期范围之前,并增加程式区块的注解。
    18. +
    19. 修正 Selima::List::Accounting::Reports 类别的 html_search() 方法,变更日期范围选项时呼叫 disableNoUseRanges() 函式;修正 accounting.js 指令档,增加 disableNoUseRanges() 函式。
    20. +
    + +
    + +
    + +
    +
    日期: 9.25.’07.
    + +
      +
    1. 修正 Selima::Processor::AcctTrx 类别的 _save_cols() 方法, fmtdate() 比较日期是否异动时加上括弧,以免因运算优先次序误判。
    2. +
    3. 修正 Selima::Form::AcctTrx 类别,修正 new() 方法,检查传票类别是否合法。。
    4. +
    5. 修正 Selima::Checker::AcctTrx 类别,移除多余的 _redir_delsubj() 方法;修正 new() 方法与 _check_recs() 方法,事先於 new() 方法储存与处理传票类别,以便其它方法也可以取得传票类别。
    6. +
    7. 修正 Selima::Form::AcctTrx 类别,当现有传票为现金支出或收入传票时,加上转为转帐传票的按钮;修正 accttrx.cgi 程式,加上是否按下转为转帐传票按钮的检查;修正 Selima::Checker::AcctTrx 类别,加上 _redir_cnvttrans() 方法,检查并转为转帐传票。
    8. +
    9. 修正 Selima::Processor::AcctTrx 类别,当现金收入或支出传票存档时,保留现金原有的摘要不动。
    10. +
    11. 修正资料表定义,加上 sum_cash_income() 函式、 sum_cash_expense() 函式、 sum_cash_balance() 函式及 accttrep_cashsum_list 浏览。
    12. +
    + +
    + +
    + +
    +
    日期: 9.24.’07.
    + +
      +
    1. Selima::List::Acct* 类别更名为 Selima::List::Accounting::* ,以便扩充功能。
    2. +
    3. Selima::Account 模组更名为 Selima::Accounting 模组。
    4. +
    5. 修正 acctrecs.cgi 程式,加上 import_seltrx() 函式和 import_selsubj() 函式的原型宣告;修正 accttrx.cgi 程式,加上 import_selsubj() 函式的原型宣告;修正 acctsubj.cgi 程式,加上 import_selparent() 函式的原型宣告。
    6. +
    7. 修正 Selima::List::Accounting::Records 类别,移除用不到的引用 Selima::AddGet 模组和 Selima::DataVars 模组。
    8. +
    9. 修正 acctrecs_list_* 资料浏览的定义, accttrx.created 栏位更正为 accttrx.date 栏位。
    10. +
    11. 修正 Selima::List::Accounting::Records 类别 new() 方法的预设排序。
    12. +
    13. 修正 Selima::Format 模组,新增 fmtntamount() 函式。
    14. +
    15. 新增 acctrep_subj_list 资料表浏览、 Selima::List::Accounting::Reports 类别、 Selima::List::Accounting::Reports::Subject 类别与 acctreps.cgi 程式。
    16. +
    17. 修正 Selima::Session 模组,加上 DEFAUTL_DIR 常数,只有当目录是预设目录时,才会淘汰旧档。
    18. +
    19. 修正资料表定义,移除用不到的 acctsubj_fullcodetitle() 资料库函式。
    20. +
    21. 修正 acctrecs_list_* 资料浏览定义和 accttrx_list_* 资料浏览定义,加上日期栏位;修正 acctrecs_list_zhcn 资料浏览定义,加上漏掉的 sn 栏位。
    22. +
    23. 修正 Selima::List::Accounting::Records 类别,加上 colval() 方法,以正确显示金额。
    24. +
    25. 修正 Selima::*::HTML 模组的 @ADMIN_SCRIPTS 变数,将传票与报表移到前面。
    26. +
    27. 新增 Selima::Accounting::Reports::Cash 类别显示现金帐。
    28. +
    29. 修正 Selima::List::Accounting::Subjects::LastLv 类别的 new() 方法,依资料库是否多语选择不同的 view 名称。
    30. +
    31. 修正 Selima::Form::AcctTrx 类别的 _html_col_ord() 方法,预设值改为 99 。
    32. +
    33. 修正 Selima::Processor::AcctTrx 类别的 _save_cols() 方法,移除要删除的分录不小心被归零的错误。
    34. +
    35. 修正 Selima::Checker::AcctRec 类别的 _check_amount() 方法,接受金额的数字格式并修整,以便调整帐目时剪贴方便;修正 Selima::Checker::AcctTrx 类别的 _check_recs() 方法,将子表单检查完后的栏位存回来,以便储存使用修整后的金额数字。
    36. +
    + +
    + +
    + +
    +
    日期: 9.23.’07.
    + +
      +
    1. 修正 Selima::Processor::AcctSubj 类别的 _save_cols() 方法,储存 parent 栏位原用 addstr() 方法,改正为 addnum() 方法;移除无关的 pageno 栏位。
    2. +
    3. 修正 Selima::Checker::AcctRec 类别,加上 _check_type() 方法。
    4. +
    5. 修正 Selima::Cache 模组,加上 %Account_accttrx_id 快取变数、 %Account_acctsubj_sn 快取变数和 %Account_accttrx_maxord 快取变数;修正 Selima::Account 模组,加上 accttrx_id() 函式、 accttrxid_compose() 函式、 acctsubj_sn() 函式和 accttrx_maxord() 函式。
    6. +
    7. 修正 Selima::Account 模组的 acctsubj_code() 函式,移除未用到的 $lang 变数。
    8. +
    9. 修正 accttrx.cgi 程式的 fetch_curitem() 函式,现金收入和支出原用 1112 零用金,改为 1111 库存现金。
    10. +
    11. 修正 acctrecs 资料表的定义中 summary 栏位的错误定义。
    12. +
    13. 修正 Selima::List::AcctTrx 类别,加上 num 栏位的标题。
    14. +
    15. 修正 accttrx 资料表, dsc 栏位改名为 note ,并更正错误的栏位条件;修正 Selima::List::AcctTrx 类别,加上 note 栏位的标题;修正 accttrx.cgi 程式,更正要检查的栏位;修正 Selima::Form::AcctTrx 类别,更正 new() 方法中要显示的栏位,将 _html_col_dsc() 方法改名为 _html_col_note() 方法,并将预设文字中 notes 更正为 note ;修正 Selima::Checker::AcctTrx 类别, _check_dsc() 方法更名为 _check_note() 方法;修正 Selima::Processor::AcctTrx 类别的 _save_cols() 方法, dsc 栏位改为 note 栏位。
    16. +
    17. 修正 Selima::Processor 类别的 new() 方法、 _update_cols() 方法和 _modified() 方法,增加前置处理的子处理物件 $self->{"pres"}
    18. +
    19. 修正 Selima::Checker::AcctRec 类别的 new() 方法,处理资料表名称更正为 acctrecs
    20. +
    21. 修正 Selima::imacat::HTML 模组的 @ADMIN_SCRIPTS 变数, acctrec.cgi 程式更正为 acctrects.cgi
    22. +
    23. 新增 Selima::Processor::AcctTrx 类别和 Selima::Processor::AcctRec 类别。
    24. +
    25. 修正 accttrx 资料表的定义,移除日期和次序唯一的限制,以方便调整次序。
    26. +
    27. 修正 Selima::Form::AcctTrx 类别的 new() 方法,删除表格时,改由 $self->{"cur"} 取得子表单类型。
    28. +
    29. 修正 Selima::Form 类别的 _html_coltmpl_date() 方法,目前的值更正由 fmtdate() 格式化后再输出。
    30. +
    31. 修正 Selima::Account模组的 acctsubj_recent_options() 函式,判断 $hascur 时加上 $value 是否有定义值的判别。
    32. +
    33. 修正 showenv.cgi 程式,移除多余的 f
    34. +
    35. 修正 Selima::List::AcctTrx 类别与 Selima::List::AcctSubj 类别的讯息,加上 accounting 以资区别。
    36. +
    37. 修正 Selima::List::AcctTrx 类别的 new() 方法, $self->{"DEFAULT_SORTBY"} 更正为 -date,-ord
    38. +
    39. 新增 Selima::List::AcctRecs 类别。
    40. +
    41. 修正 Selima::Form::AcctTrx 类别的 _html_col_recs() 方法,栏位标签 Subject 改为 Accounting subject 以资识别。
    42. +
    43. 修正 Selima::Checker::AcctRec 类别、 Selima::Checker::AcctSubj 类别、 Selima::Checker::AcctTrx 类别、 Selima::Processor::AcctRec 类别、 Selima::Processor::AcctSubj 类别、 Selima::Processor::AcctTrx 类别、 Selima::Form::AcctSubj 类别、 Selima::Form::AcctTrx 类别、 acctsubj.cgi 程式、 accttrx.cgi 程式的程式讯息,加上 accounting 以资识别。
    44. +
    45. 修正 Selima::Form 类别的 _html_coltmpl_select_multi() 方法,移除未用到的变数 $html
    46. +
    47. 修正 Selima::Form 类别,加上 _html_coltmpl_radio() 方法。
    48. +
    49. 修正 Selima::Form::AcctTrx 类别的 _html_coltmpl_loop_rec() 方法,移除未用到的 $size 变数。
    50. +
    51. 新增 Selima::Form::AcctRec 类别与 acctrecs.cgi 程式。
    52. +
    53. 修正 acctsubj 资料表的定义, code 栏位加一个位数。
    54. +
    55. 修正 acctrecs 资料表的定义, summary 栏位长度限制放宽到 32 。
    56. +
    57. 修正 accttrx_list_* 资料浏览的定义,编号用 accttrx.created 栏位更正为 date 栏位。
    58. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 11 | + 12 | + 13 | + 14 | + 15 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0013.html.zh-tw.html b/htdocs/imacat/me/changelog/0013.html.zh-tw.html new file mode 120000 index 0000000..8b961dd --- /dev/null +++ b/htdocs/imacat/me/changelog/0013.html.zh-tw.html @@ -0,0 +1 @@ +0013.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0013.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0013.html.zh-tw.xhtml new file mode 100644 index 0000000..9f225a2 --- /dev/null +++ b/htdocs/imacat/me/changelog/0013.html.zh-tw.xhtml @@ -0,0 +1,282 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷十三 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷十三

    + +
    + +
    + +
    +
    日期: 9.27.’07.
    + +
      +
    1. 修正 Selima::List 類別的 html() 方法,將 html_lists_switch() 方法移到 html_newlink() 方法之後。同樣調動兩個方法程式碼在程式檔中出現的順序。
    2. +
    3. 修正 Selima::List::Accounting::Reports::Subject 類別的 方法,移除不必要的變數,將 @conds 改用 @_ ,並加上漏掉的條件初始化。
    4. +
    5. 修正 acct*.cgi 程式,限於加密時執行。
    6. +
    7. 修正 acctreps.cgi 程式,修正 check_get() 函式,移除未用到的變數 $error ;修正 main() 函式,加上對要求限為 GET 方法的限制,以便仍能處理列表的使用者偏好。
    8. +
    9. 修正 Selima::List::Accounting::Reports::Cash 類別,並新增 Selima::List::Accounting::Reports::CashSum 類別,將現金摘要分離出來作為獨立類別。
    10. +
    + +
    + +
    + +
    +
    日期: 9.27.’07.
    + +
      +
    1. 修正 common.js 指令檔的 isDate() 函式, parasInt(dateText.substr(*,*)) 改用 dateText.substr(*,*) * 1 ,以解決 parseInt 碰到 09 會變成 0 的問題。
    2. +
    3. 修正 accounting.js 指令檔的 setAutoSummary() 函式,原先一一核對科目選項,改用 selectedIndex 屬性。
    4. +
    5. 修正 accounting.js 指令檔與 Selima::List::Accounting::Reports 類別,查詢表格加上 id ,將 disableNoUseRanges() 函式改名為 acctRepQueryDisableNoUseRanges() 函式,並取消接受的表格參數,改由 id 取得文件中的表格,以便應用在 onload 事件中。
    6. +
    7. 修正 List 類別的 page_param() 方法,增加若有 onload 屬性時回傳,並修正回傳值,不論有沒有結果一律回傳。
    8. +
    9. 修正 Selima::List::Accounting::Reports 類別,修正 new() 方法,預先儲存日期範圍;修正 pre_filter() 方法和 html_search() 方法,改用預先儲存的日期範圍。
    10. +
    11. 刪除 acctrep_cashsum_list 資料瀏覽;修正 Selima::List::Accounting::Reports::Cash 類別的 new() 方法、 fetch() 方法和 pre_filter() 方法,加上分月現金總覽。分月現金總覽應該獨立一個類別處理,但是目前暫時這樣就好。
    12. +
    + +
    + +
    + +
    +
    日期: 9.26.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports 類別,加上建新傳票的連結,以便單一窗口可以記帳、查帳。
    2. +
    3. 修正 Selima::*::HTML 函式的 @ADMIN_SCRIPTS 變數,將報表移到最前面。
    4. +
    5. 修正樣式表中預覽標誌樣式的筆誤 backgrounc-color
    6. +
    7. 修正 acct*.cgi 程式,加上載入 JavaScript 程式檔;加上 accounting.js 指令檔。
    8. +
    9. 修正 Selima::Form::AcctTrx 類別的 _html_coltmpl_loop_rec() ,加上某些特定科目異動時,自動設定摘要的功能,以自動設定摘要中的月份,統一摘要文字。
    10. +
    11. 加上 emandycommon.js 指令檔與 lang.zh-tw.js 指令檔。
    12. +
    13. 修正 common.js 指令檔,加上 isDate() 日期檢查函式。
    14. +
    15. 修正 Selima::List::Accounting::Reports 類別的 html_search() 方法,將報表類型設定方式,由原來的查詢表單改成超連結,並且在未決定報表類型時,不顯示查詢表單,以解決報表類型與查詢表單在同一個表格內,切換報表類型時查詢結果的大混亂。
    16. +
    17. 修正 Selima::List::Accounting::Reports 類別的 html_search() 方法,將科目移到日期範圍之前,並增加程式區塊的註解。
    18. +
    19. 修正 Selima::List::Accounting::Reports 類別的 html_search() 方法,變更日期範圍選項時呼叫 disableNoUseRanges() 函式;修正 accounting.js 指令檔,增加 disableNoUseRanges() 函式。
    20. +
    + +
    + +
    + +
    +
    日期: 9.25.’07.
    + +
      +
    1. 修正 Selima::Processor::AcctTrx 類別的 _save_cols() 方法, fmtdate() 比較日期是否異動時加上括弧,以免因運算優先次序誤判。
    2. +
    3. 修正 Selima::Form::AcctTrx 類別,修正 new() 方法,檢查傳票類別是否合法。。
    4. +
    5. 修正 Selima::Checker::AcctTrx 類別,移除多餘的 _redir_delsubj() 方法;修正 new() 方法與 _check_recs() 方法,事先於 new() 方法儲存與處理傳票類別,以便其它方法也可以取得傳票類別。
    6. +
    7. 修正 Selima::Form::AcctTrx 類別,當現有傳票為現金支出或收入傳票時,加上轉為轉帳傳票的按鈕;修正 accttrx.cgi 程式,加上是否按下轉為轉帳傳票按鈕的檢查;修正 Selima::Checker::AcctTrx 類別,加上 _redir_cnvttrans() 方法,檢查並轉為轉帳傳票。
    8. +
    9. 修正 Selima::Processor::AcctTrx 類別,當現金收入或支出傳票存檔時,保留現金原有的摘要不動。
    10. +
    11. 修正資料表定義,加上 sum_cash_income() 函式、 sum_cash_expense() 函式、 sum_cash_balance() 函式及 accttrep_cashsum_list 瀏覽。
    12. +
    + +
    + +
    + +
    +
    日期: 9.24.’07.
    + +
      +
    1. Selima::List::Acct* 類別更名為 Selima::List::Accounting::* ,以便擴充功能。
    2. +
    3. Selima::Account 模組更名為 Selima::Accounting 模組。
    4. +
    5. 修正 acctrecs.cgi 程式,加上 import_seltrx() 函式和 import_selsubj() 函式的原型宣告;修正 accttrx.cgi 程式,加上 import_selsubj() 函式的原型宣告;修正 acctsubj.cgi 程式,加上 import_selparent() 函式的原型宣告。
    6. +
    7. 修正 Selima::List::Accounting::Records 類別,移除用不到的引用 Selima::AddGet 模組和 Selima::DataVars 模組。
    8. +
    9. 修正 acctrecs_list_* 資料瀏覽的定義, accttrx.created 欄位更正為 accttrx.date 欄位。
    10. +
    11. 修正 Selima::List::Accounting::Records 類別 new() 方法的預設排序。
    12. +
    13. 修正 Selima::Format 模組,新增 fmtntamount() 函式。
    14. +
    15. 新增 acctrep_subj_list 資料表瀏覽、 Selima::List::Accounting::Reports 類別、 Selima::List::Accounting::Reports::Subject 類別與 acctreps.cgi 程式。
    16. +
    17. 修正 Selima::Session 模組,加上 DEFAUTL_DIR 常數,只有當目錄是預設目錄時,才會淘汰舊檔。
    18. +
    19. 修正資料表定義,移除用不到的 acctsubj_fullcodetitle() 資料庫函式。
    20. +
    21. 修正 acctrecs_list_* 資料瀏覽定義和 accttrx_list_* 資料瀏覽定義,加上日期欄位;修正 acctrecs_list_zhcn 資料瀏覽定義,加上漏掉的 sn 欄位。
    22. +
    23. 修正 Selima::List::Accounting::Records 類別,加上 colval() 方法,以正確顯示金額。
    24. +
    25. 修正 Selima::*::HTML 模組的 @ADMIN_SCRIPTS 變數,將傳票與報表移到前面。
    26. +
    27. 新增 Selima::Accounting::Reports::Cash 類別顯示現金帳。
    28. +
    29. 修正 Selima::List::Accounting::Subjects::LastLv 類別的 new() 方法,依資料庫是否多語選擇不同的 view 名稱。
    30. +
    31. 修正 Selima::Form::AcctTrx 類別的 _html_col_ord() 方法,預設值改為 99 。
    32. +
    33. 修正 Selima::Processor::AcctTrx 類別的 _save_cols() 方法,移除要刪除的分錄不小心被歸零的錯誤。
    34. +
    35. 修正 Selima::Checker::AcctRec 類別的 _check_amount() 方法,接受金額的數字格式並修整,以便調整帳目時剪貼方便;修正 Selima::Checker::AcctTrx 類別的 _check_recs() 方法,將子表單檢查完後的欄位存回來,以便儲存使用修整後的金額數字。
    36. +
    + +
    + +
    + +
    +
    日期: 9.23.’07.
    + +
      +
    1. 修正 Selima::Processor::AcctSubj 類別的 _save_cols() 方法,儲存 parent 欄位原用 addstr() 方法,改正為 addnum() 方法;移除無關的 pageno 欄位。
    2. +
    3. 修正 Selima::Checker::AcctRec 類別,加上 _check_type() 方法。
    4. +
    5. 修正 Selima::Cache 模組,加上 %Account_accttrx_id 快取變數、 %Account_acctsubj_sn 快取變數和 %Account_accttrx_maxord 快取變數;修正 Selima::Account 模組,加上 accttrx_id() 函式、 accttrxid_compose() 函式、 acctsubj_sn() 函式和 accttrx_maxord() 函式。
    6. +
    7. 修正 Selima::Account 模組的 acctsubj_code() 函式,移除未用到的 $lang 變數。
    8. +
    9. 修正 accttrx.cgi 程式的 fetch_curitem() 函式,現金收入和支出原用 1112 零用金,改為 1111 庫存現金。
    10. +
    11. 修正 acctrecs 資料表的定義中 summary 欄位的錯誤定義。
    12. +
    13. 修正 Selima::List::AcctTrx 類別,加上 num 欄位的標題。
    14. +
    15. 修正 accttrx 資料表, dsc 欄位改名為 note ,並更正錯誤的欄位條件;修正 Selima::List::AcctTrx 類別,加上 note 欄位的標題;修正 accttrx.cgi 程式,更正要檢查的欄位;修正 Selima::Form::AcctTrx 類別,更正 new() 方法中要顯示的欄位,將 _html_col_dsc() 方法改名為 _html_col_note() 方法,並將預設文字中 notes 更正為 note ;修正 Selima::Checker::AcctTrx 類別, _check_dsc() 方法更名為 _check_note() 方法;修正 Selima::Processor::AcctTrx 類別的 _save_cols() 方法, dsc 欄位改為 note 欄位。
    16. +
    17. 修正 Selima::Processor 類別的 new() 方法、 _update_cols() 方法和 _modified() 方法,增加前置處理的子處理物件 $self->{"pres"}
    18. +
    19. 修正 Selima::Checker::AcctRec 類別的 new() 方法,處理資料表名稱更正為 acctrecs
    20. +
    21. 修正 Selima::imacat::HTML 模組的 @ADMIN_SCRIPTS 變數, acctrec.cgi 程式更正為 acctrects.cgi
    22. +
    23. 新增 Selima::Processor::AcctTrx 類别和 Selima::Processor::AcctRec 類別。
    24. +
    25. 修正 accttrx 資料表的定義,移除日期和次序唯一的限制,以方便調整次序。
    26. +
    27. 修正 Selima::Form::AcctTrx 類別的 new() 方法,刪除表格時,改由 $self->{"cur"} 取得子表單類型。
    28. +
    29. 修正 Selima::Form 類別的 _html_coltmpl_date() 方法,目前的值更正由 fmtdate() 格式化後再輸出。
    30. +
    31. 修正 Selima::Account模組的 acctsubj_recent_options() 函式,判斷 $hascur 時加上 $value 是否有定義值的判別。
    32. +
    33. 修正 showenv.cgi 程式,移除多餘的 f
    34. +
    35. 修正 Selima::List::AcctTrx 類別與 Selima::List::AcctSubj 類別的訊息,加上 accounting 以資區別。
    36. +
    37. 修正 Selima::List::AcctTrx 類別的 new() 方法, $self->{"DEFAULT_SORTBY"} 更正為 -date,-ord
    38. +
    39. 新增 Selima::List::AcctRecs 類別。
    40. +
    41. 修正 Selima::Form::AcctTrx 類別的 _html_col_recs() 方法,欄位標籤 Subject 改為 Accounting subject 以資識別。
    42. +
    43. 修正 Selima::Checker::AcctRec 類別、 Selima::Checker::AcctSubj 類別、 Selima::Checker::AcctTrx 類別、 Selima::Processor::AcctRec 類別、 Selima::Processor::AcctSubj 類別、 Selima::Processor::AcctTrx 類別、 Selima::Form::AcctSubj 類別、 Selima::Form::AcctTrx 類別、 acctsubj.cgi 程式、 accttrx.cgi 程式的程式訊息,加上 accounting 以資識別。
    44. +
    45. 修正 Selima::Form 類別的 _html_coltmpl_select_multi() 方法,移除未用到的變數 $html
    46. +
    47. 修正 Selima::Form 類別,加上 _html_coltmpl_radio() 方法。
    48. +
    49. 修正 Selima::Form::AcctTrx 類別的 _html_coltmpl_loop_rec() 方法,移除未用到的 $size 變數。
    50. +
    51. 新增 Selima::Form::AcctRec 類別與 acctrecs.cgi 程式。
    52. +
    53. 修正 acctsubj 資料表的定義, code 欄位加一個位數。
    54. +
    55. 修正 acctrecs 資料表的定義, summary 欄位長度限制放寬到 32 。
    56. +
    57. 修正 accttrx_list_* 資料瀏覽的定義,編號用 accttrx.created 欄位更正為 date 欄位。
    58. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 11 | + 12 | + 13 | + 14 | + 15 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0014.html.en.html b/htdocs/imacat/me/changelog/0014.html.en.html new file mode 120000 index 0000000..438a039 --- /dev/null +++ b/htdocs/imacat/me/changelog/0014.html.en.html @@ -0,0 +1 @@ +0014.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0014.html.en.xhtml b/htdocs/imacat/me/changelog/0014.html.en.xhtml new file mode 100644 index 0000000..a173a6c --- /dev/null +++ b/htdocs/imacat/me/changelog/0014.html.en.xhtml @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 14 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 14

    + +
    + +
    + +
    +
    Date: 10.3.’07.
    + +
      +
    1. 新增 Selima::List::Accounting::Reports::IncmStat 類別顯示損益表。
    2. +
    3. 新增 Selima::List::Accounting::Reports::BlncShet 類別顯示資產負債表。
    4. +
    5. 修正 Selima::Form::AcctTrx 類別,目前傳票內容加上合計列。
    6. +
    + +
    + +
    + +
    +
    Date: 10.3.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::* 類別,上期結轉代號由 3711 改為 3712 。
    2. +
    + +
    + +
    + +
    +
    Date: 10.2.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Journal 類別的 fetch() 方法,分開記算並記錄上期結轉分錄的正、負餘額,並分別分配到借貸兩邊,以更正餘額為負的上期轉入分錄金額問題。
    2. +
    3. 修正 Selima::List::Accounting::Reports 類別的 new() 方法,將所有報表的所有欄位都加入 COLS_NO_SORT_BY ,取消欄位排序功能。會計報表有制序的排序法,按欄位排序的功能沒有意義。
    4. +
    5. 修正 Selima::List::Accounting::Reports::* 類別的 fetch() 方法,強制設定顯示的欄位,不再向使用者偏好表查詢顯示的欄位。會計報表有制式的欄位,而且之前已取消使用者偏好設定,預設值存在使用者偏好表沒有意義。
    6. +
    7. 修正 Selima::List::Accounting::Reports 類別的 pre_filter() 方法,加上 enddate ,妥善計算 startdateenddate ,並以這些日期做計算;修正 Selima::List::Accounting::Reports::Cash 類別的 fetch() 方法,設定上期結轉和合計的日期。
    8. +
    9. 修正 Selima::List::Accounting::Reports::Cash 類別的 fetch() 方法,正確顯示上期結轉科目。
    10. +
    11. 修正 Selima::List::Accounting::Reports 類別,修正 new() 方法,加上 nodata 表示沒有資料;修正 pre_filter() 方法、 html_lists_switch() 方法和 html_search() 方法,無資料時不執行;修正 Selima::List::Accounting::Reports::* 類別的 fetch() 方法,無資料時不執行。
    12. +
    13. 修正 acctrep_ledger_list* 資料表瀏覽,加上 _sel 欄位;修正 Selima::List::Accounting::Reports::Ledger 類別的 fetch() 方法,插入上期轉入分錄;修正 Selima::List::Accounting::Reports::Ledger 類別的 colval() 方法,修正正確的借貸方向。
    14. +
    15. 新增 Selima::List::Accounting::Reports::TriBlnc 類別,顯示試算表。
    16. +
    17. 修正 Selima::List::Accounting::Reports 類別,預設 startdateenddate 的計算由 pre_filter() 方法移到 new() 方法。帳冊有效期間每一個帳冊報告都會用到。
    18. +
    19. 修正 Selima::List::Accounting::Reports 類別,新增 html_liststat() 方法,在顯示列表統計前,先顯示報告期間。
    20. +
    + +
    + +
    + +
    +
    Date: 10.2.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Cash 類別的 fetch() 方法,加上 AS sum 以確定欄位名稱。
    2. +
    3. 修正 Selima::List::Accounting::Reports::Journal 類別,新增 page_param() 方法和 html_pagebar() 方法,以正確處理頁數切換。
    4. +
    5. 修正 Selima::List::Accounting::Reports::Journal 類別的 fetch() 方法,加上期初上期轉入分錄。
    6. +
    + +
    + +
    + +
    +
    Date: 9.30.’07.
    + +
      +
    1. 將所有的 lend 改名為 debitborrow 改名為 credit 。這才是正確的會計辭彙。 ^^;
    2. +
    3. 將資料表 sum_*() 函式改名為 acctsum_*() 函式。
    4. +
    5. 修正 Selima::List::Accounting::Reports::Cash* 類別,加上負債科目,並加上流動性資產與負債的合計帳目。
    6. +
    7. 修正 sum_*() 資料表函式,當傳回值為 NULL 時傳回 0 ,以便運算;修正 Selima::List::Accounting::Reports::*::Summary 類別的 fetch() 方法,刪掉對於空值 undef 的特別處理。
    8. +
    9. 修正 Selima::List::Accounting::Reports 類別的 html_lists_switch() 方法,及 Selima::List::Accounting::Reports::* 類別的 new() 方法中的標題,帳目名稱現金明細改名為現金帳現金摘要改名為現金帳摘要分科明細改名為分類帳分科摘要改名為分類帳摘要
    10. +
    11. 修正 Selima::List::Accounting::Reports::* 類別的 new() 方法中的標題,在帳目名稱後加上會計科目名稱,並用 Text::Capitalize 調整為標題用的大寫式樣。
    12. +
    13. Selima::List::Accounting::Reports::Subject* 類別改名為 Selima::List::Accounting::Reports::Ledger* 類別。
    14. +
    15. Selima::List::Accounting::Reports::All 類別改名為 Selima::List::Accounting::Reports::Journal 類別。
    16. +
    17. 資料表 acctrep_subj_list* 資料瀏覽改名為 acctrep_ledger_list* 資料瀏覽;修正 Selima::List::Accounting::Reports::Cash::Summary 類別的 new() 方法, acctrep_cashsum_list 資料瀏覽改名為 acctrep_cash_summary_list 資料瀏覽;修正 Selima::List::Accounting::Reports::Ledger::Summary 類別的 new() 方法, acctrep_subjsum_list 資料瀏覽改名為 acctrep_ledger_summary_list 資料瀏覽。
    18. +
    19. 修正 Selima::List::Accounting::Reports::Journal 類別,加上 colval() 方法,貸方的記錄科目名稱空兩格,空白摘要顯示空字串。
    20. +
    21. 新增 Selima::ListPref::AcctReps 類別與 Selima::Processor::ListPref::AcctReps 類別;修正 Selima::List::Accounting::Reports 類別,加上 html_listprefform() 方法,會計報表只可設定偏好的每頁筆數,不設定顯示的欄位;加上 set_listpref() 方法,以 Selima::ListPref::AcctReps 類別處理報表偏好設定。
    22. +
    23. 更正借貸方向,改借為貸,改貸為借。原先資料匯入和系統設計的借貸方向完全反了,真是非常丟臉的事。 ^^;
    24. +
    25. 修正 acctsum_balance() 資料庫函式,原先以 credit 決定 1 或 -1 ,改以 credit 決定 amount-amount
    26. +
    27. 新增 Selima::List::Accounting::Reports::TriBlnc 類別顯示試算表。
    28. +
    + +
    + +
    + +
    +
    Date: 9.30.’07.
    + +
      +
    1. 修正資料表函數, sum_cash_income() 函式改名為 sum_borrowing() 函式, sum_cash_expense() 函式改名為 sum_lending() 函式, sum_cash_balance() 函式改名為 sum_balance() 函式,以便製作分科摘要。
    2. +
    3. 修正 Selima::List::Accounting::Reports 類別的 html_lists_switch() 方法與 Selima::List::Accounting::Reports::Subject 類別的 new() 方法,分類帳改名為分科明細
    4. +
    5. Selima::List::Accounting::Reports::CashSum 類別改名為Selima::List::Accounting::Reports::Cash::Summary 類別。
    6. +
    7. 新增 Selima::List::Accounting::Reports::Subject::Summary 類別。
    8. +
    + +
    + +
    + +
    +
    Date: 9.29.’07.
    + +
      +
    1. 修正 Selima::*::HTML 類別的 html_nav_admin() 方法,將會計管理程式轉為加密執行。
    2. +
    3. 修正 Selima::*::HTML 類別的 html_nav_admin() 方法,當採用不同的 cgi-* 程式目錄時,將連結也變更到該程式目錄下。
    4. +
    5. 修正 Selima::List::Accounting::Reports* 類別的方法次序,以符合基本類別的方法次序。
    6. +
    7. 修正 Selima::List::Accounting::Reports* 類別,將 html_search_subject() 方法改名為 html_select_subjec() 方法,以便編輯區別。
    8. +
    9. 修正 Selima::List::Accounting::Reports 類別與 Selima::List::Accounting::Reports::CashSum 類別,將 html_search() 方法改名為 html_report_query() 方法,以方便繼承通用的 html_search() 方法。
    10. +
    11. 加上 acctrep_search_list* 資料瀏覽與 Selima::List::Accounting::Reports::Search 類別,以檢索帳目資料;修正 acctreps.cgi 程式的 html() 函式,加上帳目檢索的列表;修正 Selima::List::Accounting::Reports 類別,加上 html_search() 方法以檢索帳目資料。
    12. +
        + +
      1. 修正 Selima::*::HTML 類別的 html_nav_admin() 方法,將會計管理程式轉為加密執行。
      2. + +
      3. 修正 Selima::*::HTML 類別的 html_nav_admin() 方法,當採用不同的 cgi-* 程式目錄時,將連結也變更到該程式目錄下。
      4. + +
      5. 修正 Selima::List::Accounting::Reports* 類別的方法次序,以符合基本類別的方法次序。
      6. + +
      7. 修正 Selima::List::Accounting::Reports* 類別,將 html_search_subject() 方法改名為 html_select_subjec() 方法,以便編輯區別。
      8. + +
      9. 修正 Selima::List::Accounting::Reports 類別與 Selima::List::Accounting::Reports::CashSum 類別,將 html_search() 方法改名為 html_report_query() 方法,以方便繼承通用的 html_search() 方法。
      10. +
      11. 加上 Selima::List::Accounting::Reports::All 類別,以列出全部帳目資料;修正 acctreps.cgi 程式的 html() 函式,加上全部帳目的列表。
      12. +
      +
    + +
    + +
    + +
    +
    Date: 9.28.’07.
    + +
      +
    1. html() 方法由 Selima::List::Accounting::Reports::CashSum 類別移到 Selima::List::Accounting::Reports 類別,以便其它報表也可以利用,並加上是否有定義 html_csv() 方法的檢查。
    2. +
    3. 修正 Selima::List::Accounting::Reports 類別的 pre_filter() 方法,加上忘記初始化 @conds ;當未設定期間時,預設期間為當月,並加上 actrange 屬性,以記錄目前顯示的期間參數。
    4. +
    5. 修正 Selima::List::Accounting::Reports::Cash 類別和 Selima::List::Accounting::Reports::Subject 類別,加上 html_data_download() 方法和 html_csv() 方法,並修正 fetch() 方法,以便這兩個報表的資料也可以以 CSV 檔下載。
    6. +
    7. 修正 Selima::MarkAbbr 模組的 markabbr() 函式,加上 CSV 的縮寫說明。
    8. +
    9. 修正 Selima::List::Accounting::Reports::CashSum 類別,新增空的 pre_filter() 方法,以抵消 Selima::List::Accounting::Reports 類別 pre_filter() 方法的預設期間條件。
    10. +
    11. 修正 acctreps.cgi 程式的 html_page() 函式,預設列表改為當月現金明細,以減少系統負荷並增加實用性;修正 Selima::List::Accounting::Reports 類別的 html_lists_switch() 方法,將現金明細移到現金摘要之前。
    12. +
    13. 修正 Selima::wov::List::Search 類別,刪掉多餘的空白。
    14. +
    + +
    + +
    + +
    +
    Date: 9.28.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::CashSum 類別的 fetch() 方法,當查無資料時跳出迴圈,並且不計算合計金額。
    2. +
    3. 修正 Selima::List 類別,增加空的 html_data_download() 方法,並在 html() 方法中加上顯示 html_data_download() 方法,以顯示資料下載連結。
    4. +
    5. 修正 Selima::DataVars ,加上自訂 HTTP 標頭 %HTTP_HEADERS ;修正 Selima::Destroy 類別的 DESTROY() 方法,加上顯示自訂的 %HTTP_HEADERS 標頭,並將 text/csv 也加入純文字類型中。
    6. +
    7. 修正 Selima::List::Accounting::Reports 類別,加上 iscsv 屬性,判斷是否將資料以 CSV 回傳。
    8. +
    9. 修正 Selima::List::Accounting::Reports::CashSum 類別,當資料要以 CSV 回傳時,不分頁頡取資料;新增 html_data_download() 方法,顯示以 CSV 下載資料的連結;新增 html_csv() 方法,將資料以 CSV 格式回傳;新增 html() 方法,當要以 csv 回傳時,改直接呼叫 html_data_download() 方法,不再呼叫其它方法顯示列表;修正 acctreps.cgi 程式,當資料以 CSV 格式回傳時,不再呼叫顯示頁面的其它部份,直接傳回資料。
    10. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 12 | + 13 | + 14 | + 15 | + 16 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0014.html.zh-cn.html b/htdocs/imacat/me/changelog/0014.html.zh-cn.html new file mode 120000 index 0000000..eba3939 --- /dev/null +++ b/htdocs/imacat/me/changelog/0014.html.zh-cn.html @@ -0,0 +1 @@ +0014.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0014.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0014.html.zh-cn.xhtml new file mode 100644 index 0000000..60a20c1 --- /dev/null +++ b/htdocs/imacat/me/changelog/0014.html.zh-cn.xhtml @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷十四 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷十四

    + +
    + +
    + +
    +
    日期: 10.3.’07.
    + +
      +
    1. 新增 Selima::List::Accounting::Reports::IncmStat 类别显示损益表。
    2. +
    3. 新增 Selima::List::Accounting::Reports::BlncShet 类别显示资产负债表。
    4. +
    5. 修正 Selima::Form::AcctTrx 类别,目前传票内容加上合计列。
    6. +
    + +
    + +
    + +
    +
    日期: 10.3.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::* 类别,上期结转代号由 3711 改为 3712 。
    2. +
    + +
    + +
    + +
    +
    日期: 10.2.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Journal 类别的 fetch() 方法,分开记算并记录上期结转分录的正、负余额,并分别分配到借贷两边,以更正余额为负的上期转入分录金额问题。
    2. +
    3. 修正 Selima::List::Accounting::Reports 类别的 new() 方法,将所有报表的所有栏位都加入 COLS_NO_SORT_BY ,取消栏位排序功能。会计报表有制序的排序法,按栏位排序的功能没有意义。
    4. +
    5. 修正 Selima::List::Accounting::Reports::* 类别的 fetch() 方法,强制设定显示的栏位,不再向使用者偏好表查询显示的栏位。会计报表有制式的栏位,而且之前已取消使用者偏好设定,预设值存在使用者偏好表没有意义。
    6. +
    7. 修正 Selima::List::Accounting::Reports 类别的 pre_filter() 方法,加上 enddate ,妥善计算 startdateenddate ,并以这些日期做计算;修正 Selima::List::Accounting::Reports::Cash 类别的 fetch() 方法,设定上期结转和合计的日期。
    8. +
    9. 修正 Selima::List::Accounting::Reports::Cash 类别的 fetch() 方法,正确显示上期结转科目。
    10. +
    11. 修正 Selima::List::Accounting::Reports 类别,修正 new() 方法,加上 nodata 表示没有资料;修正 pre_filter() 方法、 html_lists_switch() 方法和 html_search() 方法,无资料时不执行;修正 Selima::List::Accounting::Reports::* 类别的 fetch() 方法,无资料时不执行。
    12. +
    13. 修正 acctrep_ledger_list* 资料表浏览,加上 _sel 栏位;修正 Selima::List::Accounting::Reports::Ledger 类别的 fetch() 方法,插入上期转入分录;修正 Selima::List::Accounting::Reports::Ledger 类别的 colval() 方法,修正正确的借贷方向。
    14. +
    15. 新增 Selima::List::Accounting::Reports::TriBlnc 类别,显示试算表。
    16. +
    17. 修正 Selima::List::Accounting::Reports 类别,预设 startdateenddate 的计算由 pre_filter() 方法移到 new() 方法。帐册有效期间每一个帐册报告都会用到。
    18. +
    19. 修正 Selima::List::Accounting::Reports 类别,新增 html_liststat() 方法,在显示列表统计前,先显示报告期间。
    20. +
    + +
    + +
    + +
    +
    日期: 10.2.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Cash 类别的 fetch() 方法,加上 AS sum 以确定栏位名称。
    2. +
    3. 修正 Selima::List::Accounting::Reports::Journal 类别,新增 page_param() 方法和 html_pagebar() 方法,以正确处理页数切换。
    4. +
    5. 修正 Selima::List::Accounting::Reports::Journal 类别的 fetch() 方法,加上期初上期转入分录。
    6. +
    + +
    + +
    + +
    +
    日期: 9.30.’07.
    + +
      +
    1. 将所有的 lend 改名为 debitborrow 改名为 credit 。这才是正确的会计辞汇。 ^^;
    2. +
    3. 将资料表 sum_*() 函式改名为 acctsum_*() 函式。
    4. +
    5. 修正 Selima::List::Accounting::Reports::Cash* 类别,加上负债科目,并加上流动性资产与负债的合计帐目。
    6. +
    7. 修正 sum_*() 资料表函式,当传回值为 NULL 时传回 0 ,以便运算;修正 Selima::List::Accounting::Reports::*::Summary 类别的 fetch() 方法,删掉对於空值 undef 的特别处理。
    8. +
    9. 修正 Selima::List::Accounting::Reports 类别的 html_lists_switch() 方法,及 Selima::List::Accounting::Reports::* 类别的 new() 方法中的标题,帐目名称现金明细改名为现金帐现金摘要改名为现金帐摘要分科明细改名为分类帐分科摘要改名为分类帐摘要
    10. +
    11. 修正 Selima::List::Accounting::Reports::* 类别的 new() 方法中的标题,在帐目名称后加上会计科目名称,并用 Text::Capitalize 调整为标题用的大写式样。
    12. +
    13. Selima::List::Accounting::Reports::Subject* 类别改名为 Selima::List::Accounting::Reports::Ledger* 类别。
    14. +
    15. Selima::List::Accounting::Reports::All 类别改名为 Selima::List::Accounting::Reports::Journal 类别。
    16. +
    17. 资料表 acctrep_subj_list* 资料浏览改名为 acctrep_ledger_list* 资料浏览;修正 Selima::List::Accounting::Reports::Cash::Summary 类别的 new() 方法, acctrep_cashsum_list 资料浏览改名为 acctrep_cash_summary_list 资料浏览;修正 Selima::List::Accounting::Reports::Ledger::Summary 类别的 new() 方法, acctrep_subjsum_list 资料浏览改名为 acctrep_ledger_summary_list 资料浏览。
    18. +
    19. 修正 Selima::List::Accounting::Reports::Journal 类别,加上 colval() 方法,贷方的记录科目名称空两格,空白摘要显示空字串。
    20. +
    21. 新增 Selima::ListPref::AcctReps 类别与 Selima::Processor::ListPref::AcctReps 类别;修正 Selima::List::Accounting::Reports 类别,加上 html_listprefform() 方法,会计报表只可设定偏好的每页笔数,不设定显示的栏位;加上 set_listpref() 方法,以 Selima::ListPref::AcctReps 类别处理报表偏好设定。
    22. +
    23. 更正借贷方向,改借为贷,改贷为借。原先资料汇入和系统设计的借贷方向完全反了,真是非常丢脸的事。 ^^;
    24. +
    25. 修正 acctsum_balance() 资料库函式,原先以 credit 决定 1 或 -1 ,改以 credit 决定 amount-amount
    26. +
    27. 新增 Selima::List::Accounting::Reports::TriBlnc 类别显示试算表。
    28. +
    + +
    + +
    + +
    +
    日期: 9.30.’07.
    + +
      +
    1. 修正资料表函数, sum_cash_income() 函式改名为 sum_borrowing() 函式, sum_cash_expense() 函式改名为 sum_lending() 函式, sum_cash_balance() 函式改名为 sum_balance() 函式,以便制作分科摘要。
    2. +
    3. 修正 Selima::List::Accounting::Reports 类别的 html_lists_switch() 方法与 Selima::List::Accounting::Reports::Subject 类别的 new() 方法,分类帐改名为分科明细
    4. +
    5. Selima::List::Accounting::Reports::CashSum 类别改名为Selima::List::Accounting::Reports::Cash::Summary 类别。
    6. +
    7. 新增 Selima::List::Accounting::Reports::Subject::Summary 类别。
    8. +
    + +
    + +
    + +
    +
    日期: 9.29.’07.
    + +
      +
    1. 修正 Selima::*::HTML 类别的 html_nav_admin() 方法,将会计管理程式转为加密执行。
    2. +
    3. 修正 Selima::*::HTML 类别的 html_nav_admin() 方法,当采用不同的 cgi-* 程式目录时,将连结也变更到该程式目录下。
    4. +
    5. 修正 Selima::List::Accounting::Reports* 类别的方法次序,以符合基本类别的方法次序。
    6. +
    7. 修正 Selima::List::Accounting::Reports* 类别,将 html_search_subject() 方法改名为 html_select_subjec() 方法,以便编辑区别。
    8. +
    9. 修正 Selima::List::Accounting::Reports 类别与 Selima::List::Accounting::Reports::CashSum 类别,将 html_search() 方法改名为 html_report_query() 方法,以方便继承通用的 html_search() 方法。
    10. +
    11. 加上 acctrep_search_list* 资料浏览与 Selima::List::Accounting::Reports::Search 类别,以检索帐目资料;修正 acctreps.cgi 程式的 html() 函式,加上帐目检索的列表;修正 Selima::List::Accounting::Reports 类别,加上 html_search() 方法以检索帐目资料。
    12. +
        + +
      1. 修正 Selima::*::HTML 类别的 html_nav_admin() 方法,将会计管理程式转为加密执行。
      2. + +
      3. 修正 Selima::*::HTML 类别的 html_nav_admin() 方法,当采用不同的 cgi-* 程式目录时,将连结也变更到该程式目录下。
      4. + +
      5. 修正 Selima::List::Accounting::Reports* 类别的方法次序,以符合基本类别的方法次序。
      6. + +
      7. 修正 Selima::List::Accounting::Reports* 类别,将 html_search_subject() 方法改名为 html_select_subjec() 方法,以便编辑区别。
      8. + +
      9. 修正 Selima::List::Accounting::Reports 类别与 Selima::List::Accounting::Reports::CashSum 类别,将 html_search() 方法改名为 html_report_query() 方法,以方便继承通用的 html_search() 方法。
      10. +
      11. 加上 Selima::List::Accounting::Reports::All 类别,以列出全部帐目资料;修正 acctreps.cgi 程式的 html() 函式,加上全部帐目的列表。
      12. +
      +
    + +
    + +
    + +
    +
    日期: 9.28.’07.
    + +
      +
    1. html() 方法由 Selima::List::Accounting::Reports::CashSum 类别移到 Selima::List::Accounting::Reports 类别,以便其它报表也可以利用,并加上是否有定义 html_csv() 方法的检查。
    2. +
    3. 修正 Selima::List::Accounting::Reports 类别的 pre_filter() 方法,加上忘记初始化 @conds ;当未设定期间时,预设期间为当月,并加上 actrange 属性,以记录目前显示的期间参数。
    4. +
    5. 修正 Selima::List::Accounting::Reports::Cash 类别和 Selima::List::Accounting::Reports::Subject 类别,加上 html_data_download() 方法和 html_csv() 方法,并修正 fetch() 方法,以便这两个报表的资料也可以以 CSV 档下载。
    6. +
    7. 修正 Selima::MarkAbbr 模组的 markabbr() 函式,加上 CSV 的缩写说明。
    8. +
    9. 修正 Selima::List::Accounting::Reports::CashSum 类别,新增空的 pre_filter() 方法,以抵消 Selima::List::Accounting::Reports 类别 pre_filter() 方法的预设期间条件。
    10. +
    11. 修正 acctreps.cgi 程式的 html_page() 函式,预设列表改为当月现金明细,以减少系统负荷并增加实用性;修正 Selima::List::Accounting::Reports 类别的 html_lists_switch() 方法,将现金明细移到现金摘要之前。
    12. +
    13. 修正 Selima::wov::List::Search 类别,删掉多余的空白。
    14. +
    + +
    + +
    + +
    +
    日期: 9.28.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::CashSum 类别的 fetch() 方法,当查无资料时跳出回圈,并且不计算合计金额。
    2. +
    3. 修正 Selima::List 类别,增加空的 html_data_download() 方法,并在 html() 方法中加上显示 html_data_download() 方法,以显示资料下载连结。
    4. +
    5. 修正 Selima::DataVars ,加上自订 HTTP 标头 %HTTP_HEADERS ;修正 Selima::Destroy 类别的 DESTROY() 方法,加上显示自订的 %HTTP_HEADERS 标头,并将 text/csv 也加入纯文字类型中。
    6. +
    7. 修正 Selima::List::Accounting::Reports 类别,加上 iscsv 属性,判断是否将资料以 CSV 回传。
    8. +
    9. 修正 Selima::List::Accounting::Reports::CashSum 类别,当资料要以 CSV 回传时,不分页颉取资料;新增 html_data_download() 方法,显示以 CSV 下载资料的连结;新增 html_csv() 方法,将资料以 CSV 格式回传;新增 html() 方法,当要以 csv 回传时,改直接呼叫 html_data_download() 方法,不再呼叫其它方法显示列表;修正 acctreps.cgi 程式,当资料以 CSV 格式回传时,不再呼叫显示页面的其它部份,直接传回资料。
    10. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 12 | + 13 | + 14 | + 15 | + 16 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0014.html.zh-tw.html b/htdocs/imacat/me/changelog/0014.html.zh-tw.html new file mode 120000 index 0000000..5903d68 --- /dev/null +++ b/htdocs/imacat/me/changelog/0014.html.zh-tw.html @@ -0,0 +1 @@ +0014.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0014.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0014.html.zh-tw.xhtml new file mode 100644 index 0000000..8eb24f8 --- /dev/null +++ b/htdocs/imacat/me/changelog/0014.html.zh-tw.xhtml @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷十四 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷十四

    + +
    + +
    + +
    +
    日期: 10.3.’07.
    + +
      +
    1. 新增 Selima::List::Accounting::Reports::IncmStat 類別顯示損益表。
    2. +
    3. 新增 Selima::List::Accounting::Reports::BlncShet 類別顯示資產負債表。
    4. +
    5. 修正 Selima::Form::AcctTrx 類別,目前傳票內容加上合計列。
    6. +
    + +
    + +
    + +
    +
    日期: 10.3.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::* 類別,上期結轉代號由 3711 改為 3712 。
    2. +
    + +
    + +
    + +
    +
    日期: 10.2.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Journal 類別的 fetch() 方法,分開記算並記錄上期結轉分錄的正、負餘額,並分別分配到借貸兩邊,以更正餘額為負的上期轉入分錄金額問題。
    2. +
    3. 修正 Selima::List::Accounting::Reports 類別的 new() 方法,將所有報表的所有欄位都加入 COLS_NO_SORT_BY ,取消欄位排序功能。會計報表有制序的排序法,按欄位排序的功能沒有意義。
    4. +
    5. 修正 Selima::List::Accounting::Reports::* 類別的 fetch() 方法,強制設定顯示的欄位,不再向使用者偏好表查詢顯示的欄位。會計報表有制式的欄位,而且之前已取消使用者偏好設定,預設值存在使用者偏好表沒有意義。
    6. +
    7. 修正 Selima::List::Accounting::Reports 類別的 pre_filter() 方法,加上 enddate ,妥善計算 startdateenddate ,並以這些日期做計算;修正 Selima::List::Accounting::Reports::Cash 類別的 fetch() 方法,設定上期結轉和合計的日期。
    8. +
    9. 修正 Selima::List::Accounting::Reports::Cash 類別的 fetch() 方法,正確顯示上期結轉科目。
    10. +
    11. 修正 Selima::List::Accounting::Reports 類別,修正 new() 方法,加上 nodata 表示沒有資料;修正 pre_filter() 方法、 html_lists_switch() 方法和 html_search() 方法,無資料時不執行;修正 Selima::List::Accounting::Reports::* 類別的 fetch() 方法,無資料時不執行。
    12. +
    13. 修正 acctrep_ledger_list* 資料表瀏覽,加上 _sel 欄位;修正 Selima::List::Accounting::Reports::Ledger 類別的 fetch() 方法,插入上期轉入分錄;修正 Selima::List::Accounting::Reports::Ledger 類別的 colval() 方法,修正正確的借貸方向。
    14. +
    15. 新增 Selima::List::Accounting::Reports::TriBlnc 類別,顯示試算表。
    16. +
    17. 修正 Selima::List::Accounting::Reports 類別,預設 startdateenddate 的計算由 pre_filter() 方法移到 new() 方法。帳冊有效期間每一個帳冊報告都會用到。
    18. +
    19. 修正 Selima::List::Accounting::Reports 類別,新增 html_liststat() 方法,在顯示列表統計前,先顯示報告期間。
    20. +
    + +
    + +
    + +
    +
    日期: 10.2.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Cash 類別的 fetch() 方法,加上 AS sum 以確定欄位名稱。
    2. +
    3. 修正 Selima::List::Accounting::Reports::Journal 類別,新增 page_param() 方法和 html_pagebar() 方法,以正確處理頁數切換。
    4. +
    5. 修正 Selima::List::Accounting::Reports::Journal 類別的 fetch() 方法,加上期初上期轉入分錄。
    6. +
    + +
    + +
    + +
    +
    日期: 9.30.’07.
    + +
      +
    1. 將所有的 lend 改名為 debitborrow 改名為 credit 。這才是正確的會計辭彙。 ^^;
    2. +
    3. 將資料表 sum_*() 函式改名為 acctsum_*() 函式。
    4. +
    5. 修正 Selima::List::Accounting::Reports::Cash* 類別,加上負債科目,並加上流動性資產與負債的合計帳目。
    6. +
    7. 修正 sum_*() 資料表函式,當傳回值為 NULL 時傳回 0 ,以便運算;修正 Selima::List::Accounting::Reports::*::Summary 類別的 fetch() 方法,刪掉對於空值 undef 的特別處理。
    8. +
    9. 修正 Selima::List::Accounting::Reports 類別的 html_lists_switch() 方法,及 Selima::List::Accounting::Reports::* 類別的 new() 方法中的標題,帳目名稱現金明細改名為現金帳現金摘要改名為現金帳摘要分科明細改名為分類帳分科摘要改名為分類帳摘要
    10. +
    11. 修正 Selima::List::Accounting::Reports::* 類別的 new() 方法中的標題,在帳目名稱後加上會計科目名稱,並用 Text::Capitalize 調整為標題用的大寫式樣。
    12. +
    13. Selima::List::Accounting::Reports::Subject* 類別改名為 Selima::List::Accounting::Reports::Ledger* 類別。
    14. +
    15. Selima::List::Accounting::Reports::All 類別改名為 Selima::List::Accounting::Reports::Journal 類別。
    16. +
    17. 資料表 acctrep_subj_list* 資料瀏覽改名為 acctrep_ledger_list* 資料瀏覽;修正 Selima::List::Accounting::Reports::Cash::Summary 類別的 new() 方法, acctrep_cashsum_list 資料瀏覽改名為 acctrep_cash_summary_list 資料瀏覽;修正 Selima::List::Accounting::Reports::Ledger::Summary 類別的 new() 方法, acctrep_subjsum_list 資料瀏覽改名為 acctrep_ledger_summary_list 資料瀏覽。
    18. +
    19. 修正 Selima::List::Accounting::Reports::Journal 類別,加上 colval() 方法,貸方的記錄科目名稱空兩格,空白摘要顯示空字串。
    20. +
    21. 新增 Selima::ListPref::AcctReps 類別與 Selima::Processor::ListPref::AcctReps 類別;修正 Selima::List::Accounting::Reports 類別,加上 html_listprefform() 方法,會計報表只可設定偏好的每頁筆數,不設定顯示的欄位;加上 set_listpref() 方法,以 Selima::ListPref::AcctReps 類別處理報表偏好設定。
    22. +
    23. 更正借貸方向,改借為貸,改貸為借。原先資料匯入和系統設計的借貸方向完全反了,真是非常丟臉的事。 ^^;
    24. +
    25. 修正 acctsum_balance() 資料庫函式,原先以 credit 決定 1 或 -1 ,改以 credit 決定 amount-amount
    26. +
    27. 新增 Selima::List::Accounting::Reports::TriBlnc 類別顯示試算表。
    28. +
    + +
    + +
    + +
    +
    日期: 9.30.’07.
    + +
      +
    1. 修正資料表函數, sum_cash_income() 函式改名為 sum_borrowing() 函式, sum_cash_expense() 函式改名為 sum_lending() 函式, sum_cash_balance() 函式改名為 sum_balance() 函式,以便製作分科摘要。
    2. +
    3. 修正 Selima::List::Accounting::Reports 類別的 html_lists_switch() 方法與 Selima::List::Accounting::Reports::Subject 類別的 new() 方法,分類帳改名為分科明細
    4. +
    5. Selima::List::Accounting::Reports::CashSum 類別改名為Selima::List::Accounting::Reports::Cash::Summary 類別。
    6. +
    7. 新增 Selima::List::Accounting::Reports::Subject::Summary 類別。
    8. +
    + +
    + +
    + +
    +
    日期: 9.29.’07.
    + +
      +
    1. 修正 Selima::*::HTML 類別的 html_nav_admin() 方法,將會計管理程式轉為加密執行。
    2. +
    3. 修正 Selima::*::HTML 類別的 html_nav_admin() 方法,當採用不同的 cgi-* 程式目錄時,將連結也變更到該程式目錄下。
    4. +
    5. 修正 Selima::List::Accounting::Reports* 類別的方法次序,以符合基本類別的方法次序。
    6. +
    7. 修正 Selima::List::Accounting::Reports* 類別,將 html_search_subject() 方法改名為 html_select_subjec() 方法,以便編輯區別。
    8. +
    9. 修正 Selima::List::Accounting::Reports 類別與 Selima::List::Accounting::Reports::CashSum 類別,將 html_search() 方法改名為 html_report_query() 方法,以方便繼承通用的 html_search() 方法。
    10. +
    11. 加上 acctrep_search_list* 資料瀏覽與 Selima::List::Accounting::Reports::Search 類別,以檢索帳目資料;修正 acctreps.cgi 程式的 html() 函式,加上帳目檢索的列表;修正 Selima::List::Accounting::Reports 類別,加上 html_search() 方法以檢索帳目資料。
    12. +
        + +
      1. 修正 Selima::*::HTML 類別的 html_nav_admin() 方法,將會計管理程式轉為加密執行。
      2. + +
      3. 修正 Selima::*::HTML 類別的 html_nav_admin() 方法,當採用不同的 cgi-* 程式目錄時,將連結也變更到該程式目錄下。
      4. + +
      5. 修正 Selima::List::Accounting::Reports* 類別的方法次序,以符合基本類別的方法次序。
      6. + +
      7. 修正 Selima::List::Accounting::Reports* 類別,將 html_search_subject() 方法改名為 html_select_subjec() 方法,以便編輯區別。
      8. + +
      9. 修正 Selima::List::Accounting::Reports 類別與 Selima::List::Accounting::Reports::CashSum 類別,將 html_search() 方法改名為 html_report_query() 方法,以方便繼承通用的 html_search() 方法。
      10. +
      11. 加上 Selima::List::Accounting::Reports::All 類別,以列出全部帳目資料;修正 acctreps.cgi 程式的 html() 函式,加上全部帳目的列表。
      12. +
      +
    + +
    + +
    + +
    +
    日期: 9.28.’07.
    + +
      +
    1. html() 方法由 Selima::List::Accounting::Reports::CashSum 類別移到 Selima::List::Accounting::Reports 類別,以便其它報表也可以利用,並加上是否有定義 html_csv() 方法的檢查。
    2. +
    3. 修正 Selima::List::Accounting::Reports 類別的 pre_filter() 方法,加上忘記初始化 @conds ;當未設定期間時,預設期間為當月,並加上 actrange 屬性,以記錄目前顯示的期間參數。
    4. +
    5. 修正 Selima::List::Accounting::Reports::Cash 類別和 Selima::List::Accounting::Reports::Subject 類別,加上 html_data_download() 方法和 html_csv() 方法,並修正 fetch() 方法,以便這兩個報表的資料也可以以 CSV 檔下載。
    6. +
    7. 修正 Selima::MarkAbbr 模組的 markabbr() 函式,加上 CSV 的縮寫說明。
    8. +
    9. 修正 Selima::List::Accounting::Reports::CashSum 類別,新增空的 pre_filter() 方法,以抵消 Selima::List::Accounting::Reports 類別 pre_filter() 方法的預設期間條件。
    10. +
    11. 修正 acctreps.cgi 程式的 html_page() 函式,預設列表改為當月現金明細,以減少系統負荷並增加實用性;修正 Selima::List::Accounting::Reports 類別的 html_lists_switch() 方法,將現金明細移到現金摘要之前。
    12. +
    13. 修正 Selima::wov::List::Search 類別,刪掉多餘的空白。
    14. +
    + +
    + +
    + +
    +
    日期: 9.28.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::CashSum 類別的 fetch() 方法,當查無資料時跳出迴圈,並且不計算合計金額。
    2. +
    3. 修正 Selima::List 類別,增加空的 html_data_download() 方法,並在 html() 方法中加上顯示 html_data_download() 方法,以顯示資料下載連結。
    4. +
    5. 修正 Selima::DataVars ,加上自訂 HTTP 標頭 %HTTP_HEADERS ;修正 Selima::Destroy 類別的 DESTROY() 方法,加上顯示自訂的 %HTTP_HEADERS 標頭,並將 text/csv 也加入純文字類型中。
    6. +
    7. 修正 Selima::List::Accounting::Reports 類別,加上 iscsv 屬性,判斷是否將資料以 CSV 回傳。
    8. +
    9. 修正 Selima::List::Accounting::Reports::CashSum 類別,當資料要以 CSV 回傳時,不分頁頡取資料;新增 html_data_download() 方法,顯示以 CSV 下載資料的連結;新增 html_csv() 方法,將資料以 CSV 格式回傳;新增 html() 方法,當要以 csv 回傳時,改直接呼叫 html_data_download() 方法,不再呼叫其它方法顯示列表;修正 acctreps.cgi 程式,當資料以 CSV 格式回傳時,不再呼叫顯示頁面的其它部份,直接傳回資料。
    10. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 12 | + 13 | + 14 | + 15 | + 16 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0015.html.en.html b/htdocs/imacat/me/changelog/0015.html.en.html new file mode 120000 index 0000000..6ab92a3 --- /dev/null +++ b/htdocs/imacat/me/changelog/0015.html.en.html @@ -0,0 +1 @@ +0015.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0015.html.en.xhtml b/htdocs/imacat/me/changelog/0015.html.en.xhtml new file mode 100644 index 0000000..9cef765 --- /dev/null +++ b/htdocs/imacat/me/changelog/0015.html.en.xhtml @@ -0,0 +1,428 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 15 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 15

    + +
    + +
    + +
    +
    Date: 2.17.’09.
    + +
      +
    1. 修正 Selima::Form::AcctTrx 類別,檔頭的說明科目更正為傳票
    2. +
    3. 修正 Selima::Form::AcctTrx 類別的 _html_col_recs() 方法,新傳票計算應預留的空白記錄列時,記錄序數由 0 起算, 0 亦為合法序數,故判斷式 >0 修正為 >=0 ;只有前表單有記錄時,記錄總數才需由最後記錄的序數加 1 ,同時修正。
    4. +
    + +
    + +
    + +
    +
    Date: 2.5.’09.
    + +

    Google 廣告效果不彰(網站太冷門了?),且破壞版面整體感,停止並移除 Google 廣告。 + +

      +
    1. 修正 Selima::*::Rebuild 模組,移除 Google 廣告的設定。
    2. +
    3. 修正 Selima::*::HTML 模組,移除 html_googlead() 函式;修正 html_header() 函式,移除呼叫 html_googlead() 函式。
    4. +
    5. 修正 gb*.cgi 程式,加上 Google 廣告的設定。
    6. +
    7. 移除 googlead.js 指令程式。
    8. +
    9. 修正 common.css 樣式表,移除 Google 廣告的樣式設計。
    10. +
        + +
    + +
    + +
    +
    Date: 12.19.’08.
    + +
      +
    1. 修正 accttrx.cgi 程式,修正 fetch_curitem() 函式,只有在借方或貸方摘要留白時,才會視為現金支出或現金收入傳票。
    2. +
    + +
    + +
    + +
    +
    Date: 12.17.’08.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::BlncShet 類別, DOS 換行修正為 Unix 換行。
    2. +
    + +
    + +
    + +
    +
    Date: 10.13.’08.
    + +
      +
    1. 修正 Selima::htc::HTML 模組,加上 html_googlead() 函式;修正 html_header() 函式,加上呼叫 html_googlead() 函式。
    2. +
    3. 修正 gb*.cgi 程式,加上 Google 廣告的設定。
    4. +
    5. 加上 googlead.js 指令程式。
    6. +
    + +
    + +
    + +
    +
    Date: 4.20.’08.
    + +
      +
    1. 修正 Selima::Form::AcctTrx 類別的 _html_col_recs() 方法,計算表格最後一筆記錄編號時,原用 && 改用 || ,以避免表格由目前值直接轉用時,中間有一筆資料摘要未填,被當成資料結束。
    2. +
    3. 修正 Selima::List 類別的 page_param() 方法,不換頁時直接跳回,不往下計算頁數關係。
    4. +
    + +
    + +
    + +
    +
    Date: 3.20.’08.
    + +
      +
    1. 修正 Selima::Page 類別、 Selima::ReqURI 模組、 Selima::htc::HTML 模組與 nlindex.cgi 程式,英文 index 的複數應為 indices ,不是 indexes
    2. +
    + +
    + +
    + +
    +
    Date: 2.26.’08.
    + +
      +
    1. 修正 Selima::Init 模組的與 checkspam_spammers() 函式,新增一個擋廣告留言的規則。
    2. +
    + +
    + +
    + +
    +
    Date: 2.17.’08.
    + +
      +
    1. 修正 Selima::List 類別與 Selima::imacat::List::Search 類別的 sql_filter() 方法,搜尋條件加上 cast() 型別轉換,以符合 PostgreSQL 8.3.0 的需求。
    2. +
    + +
    + +
    + +
    +
    Date: 2.12.’08.
    + +
      +
    1. 修正 Selima::wov::Items 模組的 newslet_title() 函式,資料庫函式名稱改小寫。
    2. +
    3. 修正 Selima::wov::Items 模組、 Selima::List::Accounting::Reports::Cash::Summary 類別與 Selima::List::Accounting::Reports::Ledger::Summary 類別,資料庫函式 lpad() 的參數加上 cast() 型別轉換,以符合 PostgreSQL 8.3.0 的需求。
    4. +
    5. 修正資料庫定義,資料庫函式 lpad() 的參數加上 cast() 型別轉換,以符合 PostgreSQL 8.3.0 的需求。
    6. +
    7. 修正 Selima::List::Accounting::Reports::Ledger::Summary 類別、 Selima::List::Accounting::Reports::Cash::Summary 類別與 Selima::Checker::Guestbook::Public 類別,資料庫函式 CAST() 改用小寫,以統一程式碼風格。
    8. +
    9. 修正 Selima::imacat::Items 模組、 Selima::wov::Items 模組、 Selima::List::Accounting::Reports::Cash::Summary 類別、 Selima::List::Accounting::Reports::Ledger::Summary 類別與 Selima::List::Accounting::Reports 類別,資料庫函式 EXTRACT() 改用小寫,以統一程式碼風格。
    10. +
    11. 修正資料庫定義,資料庫函式 CAST() 和資料庫函式 EXTRACT() 改用小寫,以統一程式碼風格。
    12. +
    13. 修正 Selima::imacat::Items 模組的 literalzh_title() 函式,資料庫函式 SUBSTRING() 改用小寫,以統一程式碼風格。
    14. +
    + +
    + +
    + +
    +
    Date: 1.31.’08.
    + +
      +
    1. 修正 Selima::imacat::Checker::Diary 模組的 new() 方法,將旅舍日記長度限制延長到 30720 字元。
    2. +
    + +
    + +
    + +
    +
    Date: 12.2.’07.
    + +
      +
    1. 修正 Selima::A2HTML 模組、 Selima::LogOut 模組、 Selima::Session 模組、 Selima::NewSN 模組、 Selima::CallForm 模組、 Selima::Processor 模組與 Selima::Mail 模組, do { … } while … 改用 do { … } until !… 以使程式碼更易讀。
    2. +
    + +
    + +
    + +
    +
    Date: 11.18.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Journal 類別的 fetch() 方法,計算上期結轉時,排除掉上期科目為上期結轉的科目。
    2. +
    + +
    + +
    + +
    +
    Date: 11.4.’07.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_reqheads() 函式,調整一個擋廣告留言規則的適用範圍。
    2. +
    3. 修正 Selima::Init 模組,加上一個新的擋廣告留言規則。
    4. +
    + +
    + +
    + +
    +
    Date: 10.15.’07.
    + +
      +
    1. 修正 Selima::Init 模組,將新加入的擋廣告留言規則和另一規則合併,並加上新的規則。
    2. +
    3. 修正 Selima::Init 模組的 checkspam_*() 函式,回傳訊息前面加上函式名稱以資辨別,並便了解各規則的擋廣告信效能;加上沒問題時回傳空值。
    4. +
    5. 修正 Selima::Checker::*::Guestbook::Public 類別的 _checkspam_local() 方法,回傳訊息前面加上函式名稱以資辨別。
    6. +
    7. 修正 Selima::Logging 模組,加上 spamlog() 函式與 sub check_spamlog_file() 函式,將擋廣告留言分開記錄,以保持活動記錄擋簡潔易讀;修正 Selima::Init 模組的 block_spam() 函式與 Selima::Checker::Guestbook::Public 類別的 _block_spam() 方法,改用 spamlog 記錄到擋廣告留言記錄。
    8. +
    + +
    + +
    + +
    +
    Date: 10.15.’07.
    + +
      +
    1. 修正 Selima::Init 模組,新增一個擋廣告留言的規則。
    2. +
    3. 修正 Selima::Init 模組的各 checkspam_*() 函式,改接受表格為參數,並回傳擋留言的訊息,不直接擋掉留言,而改由 check_spam() 依各 checkspam_*() 函式的回傳值擋掉留言,以便可以另寫程式,測試各 checkspam_*() 函式的規則。
    4. +
    5. 修正 Selima::*::HTML 模組的 html_nav_admin() 函式,調整路徑時,另用 $path 複製路徑後再調整,以免在 mod_perl 下重複調整路徑。
    6. +
    7. 修正 Selima::*::HTML 模組的 html_nav_admin() 函式,刪掉輸出時重複的權限檢查。
    8. +
    9. 修正 Selima::*::HTML 模組,修正 @ADMIN_SCRIPTS 變數,新增 https 屬性設定是否需加密處理;修正 html_nav_admin() 函式,移除針對會計程式的特殊處理,改針對新的 https 屬性決定是否需調整路徑加密處理。
    10. +
    + +
    + +
    + +
    +
    Date: 10.11.’07.
    + +
      +
    1. 依最新的 ISO 3166-1 (2006-09-26) 、 CNS 12842 (2006-04-19) 及 GB/T 2659-2000 ,更新資料庫中的國家資料。
    2. +
    3. 修正 Selima::imacat::List::Guestbook 類別,加上 lang 欄位的標題。
    4. +
    5. 修正 guestbook.cgi 程式,修正 fetch_curitem() 函式,將 lang 設為 lang0 ;修正 check_post() 函式,加上檢查 lang 欄位。
    6. +
    7. 修正 Selima::imacat::Form::Guestbook 類別,加上 new() 方法與 _html_col_lang() 方法,以顯示語言欄位。
    8. +
    9. 修正 Selima::imacat::Checker::Guestbook 類別,加上 _check_lang() 方法,以檢查語言設定。
    10. +
    11. 新增 Selima::imacat::Processor::Guestbook 類別;修正 guestbook.cgi 程式的 main() 函式,改用 Selima::imacat::Processor::Guestbook 類別。
    12. +
    13. 修正 Selima::Checker::AcctTrx 類別的 _check_recs() 方法,依現金收入或現金支出傳票計算列數時,之前借貸方向弄反了未修正。
    14. +
    15. 修正 Selima::Form::AcctTrx 類別的 _html_col_recs() 方法,顯示目前合計金額時誤用 $count_cur ,修正為 $count_new
    16. +
    17. 修正 Selima::Processor::AcctTrx 類別的 _save_cols() 方法,刪傳票調整現有傳票次序時,設定 ISO 格式的日期值,以避免比對錯誤。
    18. +
    + +
    + +
    + +
    +
    Date: 10.10.’07.
    + +
      +
    1. 修正旅舍的 guestbook 資料表,加上 lang 欄位記錄留言的語言,以解決繁簡自動轉換的錯誤。
    2. +
    3. 修正 Selima::List::Guestbook::Public 類別的 html_list() 方法,當留言標示為繁體時,不再轉繁;當留言標示為簡體時,不再轉簡,以免自動繁簡轉換把對的字轉錯掉。
    4. +
    5. 修正 users_list* 資料瀏覽,加上西班牙文。
    6. +
    + +
    + +
    + +
    +
    Date: 10.10.’07.
    + +
      +
    1. 修正 Selima::GeoIP 模組,私有網路代號改為 AA ,未知代號改為 ZZ ,以符合 ISO 3166 User-assigned code elements 的規定。
    2. +
    + +
    + +
    + +
    +
    Date: 10.5.’07.
    + +
      +
    1. 修正 Selima::AddCol 類別的 adddate() 方法,比較新舊日期時,新日期先轉換成 epoch 秒數,才能跟原日期正確比較。
    2. +
    3. 修正 Selima::Form::AcctTrx 類別的 _html_col_recs() 方法,計算目前有資料的列數時,列數更正最後一列的編號加一,以正確預留五列空白列。
    4. +
    5. 修正 Selima::Processor::AcctTrx 類別的 _save_cols() 方法,調整次序時,子處理器的新日期以 fmtdate() 轉為標準日期格式,以便 Selima::AddCol 類別正確處理。
    6. +
    7. 修正 accttrx 資料表,註記的長度加大為 128 。
    8. +
    + +
    + +
    + +
    +
    Date: 10.3.’07.
    + +
      +
    1. 修正 Selima::Form::AcctTrx 類別的 _html_coltmpl_ro_loop_rec() 方法與 _html_col_recs() 方法,目前值與合計的金額用金額格式顯示,並將空的欄位以空字串顯示,不以未設定顯示,讓傳票看起來比較正常。
    2. +
    3. 修正 acctsubj.cgi 程式的 fetch_current() 函式,單語時正確取得子科目的清單。
    4. +
    5. 修正 Selima::List::Accounting::Reports::** 類別,3711 上期結轉改用3351 累積盈虧,並刪除不必要的自建科目37 上期結轉(或結轉下期)371 上期結轉(或結轉下期)3711 結轉下期3712 上期結轉
    6. +
    7. 修正 Selima::List::Accounting::Reports::TriBlnc 類別的 fetch() 方法,分類帳連結網址由 subj 更正為 ldgr
    8. +
    9. 修正 Selima::Form::AcctTrx 類別的 _html_coltmpl_loop_rec() 方法,金額欄位向右對齊。
    10. +
    11. 修正 Selima::Form::AcctTrx 類別的 _html_col_recs() 方法,加上新值的合計列,並為新值的金額欄位加上 onchange 處理器;修正 accounting.js 指令檔,加上 calcTotal() 函式,以即時修正、反映新金額值的合計。
    12. +
    13. 修正 Selima::Accounting 模組,加上 ACCT_SUBJ_CASH 常數;修正 accttrx.cgi 程式、 Selima::Checker::AcctTrx 模組、 Selima::Processor::AcctTrx 模組、 Selima::List::Accounting::Reports::Ledger 模組和 Selima::List::Accounting::Reports::Ledger::Summary 模組,現金科目代號改用 ACCT_SUBJ_CASH 常數。
    14. +
    15. 修正 Selima::Accounting 模組,加上 ACCTSUBJ_CASH 常數;修正 accttrx.cgi 程式、 Selima::Checker::AcctTrx 類別、 Selima::Processor::AcctTrx 類別、 Selima::List::Accounting::Reports::Ledger 類別和 Selima::List::Accounting::Reports::Ledger::Summary 類別,現金科目代號改用 ACCTSUBJ_CASH 常數。
    16. +
    17. 修正 Selima::Accounting 模組,加上 ACCTSUBJ_INCOME_CUR 常數;修正Selima::List::Accounting::Reports::IncmStat 類別和 Selima::List::Accounting::Reports::BlncShet 類別,本期損益代號改用 ACCTSUBJ_INCOME_CUR 常數。
    18. +
    19. 修正 Selima::Accounting 模組,加上 ACCTSUBJ_INCOME_ACUM 常數;修正Selima::List::Accounting::Reports::Cash 類別、 Selima::List::Accounting::Reports::Journal 類別、 Selima::List::Accounting::Reports::TriBlnc 類別和 Selima::List::Accounting::Reports::BlncShet 類別,累積盈虧代號改用 ACCTSUBJ_INCOME_ACUM 常數。
    20. +
    21. 修正 Selima::List::Accounting::Reports::Cash 類別的 fetch() 方法,第一期時不插入上期結轉分錄。
    22. +
    23. 修正 acctrep_cash_list* 資料表瀏覽的定義,排序時將借方列於貸方之前。這是之前借貸錯亂沒修好的遺留物。
    24. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 13 | + 14 | + 15 | + 16 | + 17 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0015.html.zh-cn.html b/htdocs/imacat/me/changelog/0015.html.zh-cn.html new file mode 120000 index 0000000..8e8b66b --- /dev/null +++ b/htdocs/imacat/me/changelog/0015.html.zh-cn.html @@ -0,0 +1 @@ +0015.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0015.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0015.html.zh-cn.xhtml new file mode 100644 index 0000000..b09eb4f --- /dev/null +++ b/htdocs/imacat/me/changelog/0015.html.zh-cn.xhtml @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷十五 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷十五

    + +
    + +
    + +
    +
    日期: 2.17.’09.
    + +
      +
    1. 修正 Selima::Form::AcctTrx 类别,档头的说明科目更正为传票
    2. +
    3. 修正 Selima::Form::AcctTrx 类别的 _html_col_recs() 方法,新传票计算应预留的空白记录列时,记录序数由 0 起算, 0 亦为合法序数,故判断式 >0 修正为 >=0 ;只有前表单有记录时,记录总数才需由最后记录的序数加 1 ,同时修正。
    4. +
    + +
    + +
    + +
    +
    日期: 2.5.’09.
    + +

    Google 广告效果不彰(网站太冷门了?),且破坏版面整体感,停止并移除 Google 广告。 + +

      +
    1. 修正 Selima::*::Rebuild 模组,移除 Google 广告的设定。
    2. +
    3. 修正 Selima::*::HTML 模组,移除 html_googlead() 函式;修正 html_header() 函式,移除呼叫 html_googlead() 函式。
    4. +
    5. 修正 gb*.cgi 程式,加上 Google 广告的设定。
    6. +
    7. 移除 googlead.js 指令程式。
    8. +
    9. 修正 common.css 样式表,移除 Google 广告的样式设计。
    10. +
        + +
    + +
    + +
    +
    日期: 12.19.’08.
    + +
      +
    1. 修正 accttrx.cgi 程式,修正 fetch_curitem() 函式,只有在借方或贷方摘要留白时,才会视为现金支出或现金收入传票。
    2. +
    + +
    + +
    + +
    +
    日期: 12.17.’08.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::BlncShet 类别, DOS 换行修正为 Unix 换行。
    2. +
    + +
    + +
    + +
    +
    日期: 10.13.’08.
    + +
      +
    1. 修正 Selima::htc::HTML 模组,加上 html_googlead() 函式;修正 html_header() 函式,加上呼叫 html_googlead() 函式。
    2. +
    3. 修正 gb*.cgi 程式,加上 Google 广告的设定。
    4. +
    5. 加上 googlead.js 指令程式。
    6. +
    + +
    + +
    + +
    +
    日期: 4.20.’08.
    + +
      +
    1. 修正 Selima::Form::AcctTrx 类别的 _html_col_recs() 方法,计算表格最后一笔记录编号时,原用 && 改用 || ,以避免表格由目前值直接转用时,中间有一笔资料摘要未填,被当成资料结束。
    2. +
    3. 修正 Selima::List 类别的 page_param() 方法,不换页时直接跳回,不往下计算页数关系。
    4. +
    + +
    + +
    + +
    +
    日期: 3.20.’08.
    + +
      +
    1. 修正 Selima::Page 类别、 Selima::ReqURI 模组、 Selima::htc::HTML 模组与 nlindex.cgi 程式,英文 index 的复数应为 indices ,不是 indexes
    2. +
    + +
    + +
    + +
    +
    日期: 2.26.’08.
    + +
      +
    1. 修正 Selima::Init 模组的与 checkspam_spammers() 函式,新增一个挡广告留言的规则。
    2. +
    + +
    + +
    + +
    +
    日期: 2.17.’08.
    + +
      +
    1. 修正 Selima::List 类别与 Selima::imacat::List::Search 类别的 sql_filter() 方法,搜寻条件加上 cast() 型别转换,以符合 PostgreSQL 8.3.0 的需求。
    2. +
    + +
    + +
    + +
    +
    日期: 2.12.’08.
    + +
      +
    1. 修正 Selima::wov::Items 模组的 newslet_title() 函式,资料库函式名称改小写。
    2. +
    3. 修正 Selima::wov::Items 模组、 Selima::List::Accounting::Reports::Cash::Summary 类别与 Selima::List::Accounting::Reports::Ledger::Summary 类别,资料库函式 lpad() 的参数加上 cast() 型别转换,以符合 PostgreSQL 8.3.0 的需求。
    4. +
    5. 修正资料库定义,资料库函式 lpad() 的参数加上 cast() 型别转换,以符合 PostgreSQL 8.3.0 的需求。
    6. +
    7. 修正 Selima::List::Accounting::Reports::Ledger::Summary 类别、 Selima::List::Accounting::Reports::Cash::Summary 类别与 Selima::Checker::Guestbook::Public 类别,资料库函式 CAST() 改用小写,以统一程式码风格。
    8. +
    9. 修正 Selima::imacat::Items 模组、 Selima::wov::Items 模组、 Selima::List::Accounting::Reports::Cash::Summary 类别、 Selima::List::Accounting::Reports::Ledger::Summary 类别与 Selima::List::Accounting::Reports 类别,资料库函式 EXTRACT() 改用小写,以统一程式码风格。
    10. +
    11. 修正资料库定义,资料库函式 CAST() 和资料库函式 EXTRACT() 改用小写,以统一程式码风格。
    12. +
    13. 修正 Selima::imacat::Items 模组的 literalzh_title() 函式,资料库函式 SUBSTRING() 改用小写,以统一程式码风格。
    14. +
    + +
    + +
    + +
    +
    日期: 1.31.’08.
    + +
      +
    1. 修正 Selima::imacat::Checker::Diary 模组的 new() 方法,将旅舍日记长度限制延长到 30720 字元。
    2. +
    + +
    + +
    + +
    +
    日期: 12.2.’07.
    + +
      +
    1. 修正 Selima::A2HTML 模组、 Selima::LogOut 模组、 Selima::Session 模组、 Selima::NewSN 模组、 Selima::CallForm 模组、 Selima::Processor 模组与 Selima::Mail 模组, do { … } while … 改用 do { … } until !… 以使程式码更易读。
    2. +
    + +
    + +
    + +
    +
    日期: 11.18.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Journal 类别的 fetch() 方法,计算上期结转时,排除掉上期科目为上期结转的科目。
    2. +
    + +
    + +
    + +
    +
    日期: 11.4.’07.
    + +
      +
    1. 修正 Selima::Init 模组的 checkspam_reqheads() 函式,调整一个挡广告留言规则的适用范围。
    2. +
    3. 修正 Selima::Init 模组,加上一个新的挡广告留言规则。
    4. +
    + +
    + +
    + +
    +
    日期: 10.15.’07.
    + +
      +
    1. 修正 Selima::Init 模组,将新加入的挡广告留言规则和另一规则合并,并加上新的规则。
    2. +
    3. 修正 Selima::Init 模组的 checkspam_*() 函式,回传讯息前面加上函式名称以资辨别,并便了解各规则的挡广告信效能;加上没问题时回传空值。
    4. +
    5. 修正 Selima::Checker::*::Guestbook::Public 类别的 _checkspam_local() 方法,回传讯息前面加上函式名称以资辨别。
    6. +
    7. 修正 Selima::Logging 模组,加上 spamlog() 函式与 sub check_spamlog_file() 函式,将挡广告留言分开记录,以保持活动记录挡简洁易读;修正 Selima::Init 模组的 block_spam() 函式与 Selima::Checker::Guestbook::Public 类别的 _block_spam() 方法,改用 spamlog 记录到挡广告留言记录。
    8. +
    + +
    + +
    + +
    +
    日期: 10.15.’07.
    + +
      +
    1. 修正 Selima::Init 模组,新增一个挡广告留言的规则。
    2. +
    3. 修正 Selima::Init 模组的各 checkspam_*() 函式,改接受表格为参数,并回传挡留言的讯息,不直接挡掉留言,而改由 check_spam() 依各 checkspam_*() 函式的回传值挡掉留言,以便可以另写程式,测试各 checkspam_*() 函式的规则。
    4. +
    5. 修正 Selima::*::HTML 模组的 html_nav_admin() 函式,调整路径时,另用 $path 复制路径后再调整,以免在 mod_perl 下重复调整路径。
    6. +
    7. 修正 Selima::*::HTML 模组的 html_nav_admin() 函式,删掉输出时重复的权限检查。
    8. +
    9. 修正 Selima::*::HTML 模组,修正 @ADMIN_SCRIPTS 变数,新增 https 属性设定是否需加密处理;修正 html_nav_admin() 函式,移除针对会计程式的特殊处理,改针对新的 https 属性决定是否需调整路径加密处理。
    10. +
    + +
    + +
    + +
    +
    日期: 10.11.’07.
    + +
      +
    1. 依最新的 ISO 3166-1 (2006-09-26) 、 CNS 12842 (2006-04-19) 及 GB/T 2659-2000 ,更新资料库中的国家资料。
    2. +
    3. 修正 Selima::imacat::List::Guestbook 类别,加上 lang 栏位的标题。
    4. +
    5. 修正 guestbook.cgi 程式,修正 fetch_curitem() 函式,将 lang 设为 lang0 ;修正 check_post() 函式,加上检查 lang 栏位。
    6. +
    7. 修正 Selima::imacat::Form::Guestbook 类别,加上 new() 方法与 _html_col_lang() 方法,以显示语言栏位。
    8. +
    9. 修正 Selima::imacat::Checker::Guestbook 类别,加上 _check_lang() 方法,以检查语言设定。
    10. +
    11. 新增 Selima::imacat::Processor::Guestbook 类别;修正 guestbook.cgi 程式的 main() 函式,改用 Selima::imacat::Processor::Guestbook 类别。
    12. +
    13. 修正 Selima::Checker::AcctTrx 类别的 _check_recs() 方法,依现金收入或现金支出传票计算列数时,之前借贷方向弄反了未修正。
    14. +
    15. 修正 Selima::Form::AcctTrx 类别的 _html_col_recs() 方法,显示目前合计金额时误用 $count_cur ,修正为 $count_new
    16. +
    17. 修正 Selima::Processor::AcctTrx 类别的 _save_cols() 方法,删传票调整现有传票次序时,设定 ISO 格式的日期值,以避免比对错误。
    18. +
    + +
    + +
    + +
    +
    日期: 10.10.’07.
    + +
      +
    1. 修正旅舍的 guestbook 资料表,加上 lang 栏位记录留言的语言,以解决繁简自动转换的错误。
    2. +
    3. 修正 Selima::List::Guestbook::Public 类别的 html_list() 方法,当留言标示为繁体时,不再转繁;当留言标示为简体时,不再转简,以免自动繁简转换把对的字转错掉。
    4. +
    5. 修正 users_list* 资料浏览,加上西班牙文。
    6. +
    + +
    + +
    + +
    +
    日期: 10.10.’07.
    + +
      +
    1. 修正 Selima::GeoIP 模组,私有网路代号改为 AA ,未知代号改为 ZZ ,以符合 ISO 3166 User-assigned code elements 的规定。
    2. +
    + +
    + +
    + +
    +
    日期: 10.5.’07.
    + +
      +
    1. 修正 Selima::AddCol 类别的 adddate() 方法,比较新旧日期时,新日期先转换成 epoch 秒数,才能跟原日期正确比较。
    2. +
    3. 修正 Selima::Form::AcctTrx 类别的 _html_col_recs() 方法,计算目前有资料的列数时,列数更正最后一列的编号加一,以正确预留五列空白列。
    4. +
    5. 修正 Selima::Processor::AcctTrx 类别的 _save_cols() 方法,调整次序时,子处理器的新日期以 fmtdate() 转为标准日期格式,以便 Selima::AddCol 类别正确处理。
    6. +
    7. 修正 accttrx 资料表,注记的长度加大为 128 。
    8. +
    + +
    + +
    + +
    +
    日期: 10.3.’07.
    + +
      +
    1. 修正 Selima::Form::AcctTrx 类别的 _html_coltmpl_ro_loop_rec() 方法与 _html_col_recs() 方法,目前值与合计的金额用金额格式显示,并将空的栏位以空字串显示,不以未设定显示,让传票看起来比较正常。
    2. +
    3. 修正 acctsubj.cgi 程式的 fetch_current() 函式,单语时正确取得子科目的清单。
    4. +
    5. 修正 Selima::List::Accounting::Reports::** 类别,3711 上期结转改用3351 累积盈亏,并删除不必要的自建科目37 上期结转(或结转下期)371 上期结转(或结转下期)3711 结转下期3712 上期结转
    6. +
    7. 修正 Selima::List::Accounting::Reports::TriBlnc 类别的 fetch() 方法,分类帐连结网址由 subj 更正为 ldgr
    8. +
    9. 修正 Selima::Form::AcctTrx 类别的 _html_coltmpl_loop_rec() 方法,金额栏位向右对齐。
    10. +
    11. 修正 Selima::Form::AcctTrx 类别的 _html_col_recs() 方法,加上新值的合计列,并为新值的金额栏位加上 onchange 处理器;修正 accounting.js 指令档,加上 calcTotal() 函式,以即时修正、反映新金额值的合计。
    12. +
    13. 修正 Selima::Accounting 模组,加上 ACCT_SUBJ_CASH 常数;修正 accttrx.cgi 程式、 Selima::Checker::AcctTrx 模组、 Selima::Processor::AcctTrx 模组、 Selima::List::Accounting::Reports::Ledger 模组和 Selima::List::Accounting::Reports::Ledger::Summary 模组,现金科目代号改用 ACCT_SUBJ_CASH 常数。
    14. +
    15. 修正 Selima::Accounting 模组,加上 ACCTSUBJ_CASH 常数;修正 accttrx.cgi 程式、 Selima::Checker::AcctTrx 类别、 Selima::Processor::AcctTrx 类别、 Selima::List::Accounting::Reports::Ledger 类别和 Selima::List::Accounting::Reports::Ledger::Summary 类别,现金科目代号改用 ACCTSUBJ_CASH 常数。
    16. +
    17. 修正 Selima::Accounting 模组,加上 ACCTSUBJ_INCOME_CUR 常数;修正Selima::List::Accounting::Reports::IncmStat 类别和 Selima::List::Accounting::Reports::BlncShet 类别,本期损益代号改用 ACCTSUBJ_INCOME_CUR 常数。
    18. +
    19. 修正 Selima::Accounting 模组,加上 ACCTSUBJ_INCOME_ACUM 常数;修正Selima::List::Accounting::Reports::Cash 类别、 Selima::List::Accounting::Reports::Journal 类别、 Selima::List::Accounting::Reports::TriBlnc 类别和 Selima::List::Accounting::Reports::BlncShet 类别,累积盈亏代号改用 ACCTSUBJ_INCOME_ACUM 常数。
    20. +
    21. 修正 Selima::List::Accounting::Reports::Cash 类别的 fetch() 方法,第一期时不插入上期结转分录。
    22. +
    23. 修正 acctrep_cash_list* 资料表浏览的定义,排序时将借方列於贷方之前。这是之前借贷错乱没修好的遗留物。
    24. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 13 | + 14 | + 15 | + 16 | + 17 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0015.html.zh-tw.html b/htdocs/imacat/me/changelog/0015.html.zh-tw.html new file mode 120000 index 0000000..2c20c70 --- /dev/null +++ b/htdocs/imacat/me/changelog/0015.html.zh-tw.html @@ -0,0 +1 @@ +0015.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0015.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0015.html.zh-tw.xhtml new file mode 100644 index 0000000..e9ca019 --- /dev/null +++ b/htdocs/imacat/me/changelog/0015.html.zh-tw.xhtml @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷十五 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷十五

    + +
    + +
    + +
    +
    日期: 2.17.’09.
    + +
      +
    1. 修正 Selima::Form::AcctTrx 類別,檔頭的說明科目更正為傳票
    2. +
    3. 修正 Selima::Form::AcctTrx 類別的 _html_col_recs() 方法,新傳票計算應預留的空白記錄列時,記錄序數由 0 起算, 0 亦為合法序數,故判斷式 >0 修正為 >=0 ;只有前表單有記錄時,記錄總數才需由最後記錄的序數加 1 ,同時修正。
    4. +
    + +
    + +
    + +
    +
    日期: 2.5.’09.
    + +

    Google 廣告效果不彰(網站太冷門了?),且破壞版面整體感,停止並移除 Google 廣告。 + +

      +
    1. 修正 Selima::*::Rebuild 模組,移除 Google 廣告的設定。
    2. +
    3. 修正 Selima::*::HTML 模組,移除 html_googlead() 函式;修正 html_header() 函式,移除呼叫 html_googlead() 函式。
    4. +
    5. 修正 gb*.cgi 程式,加上 Google 廣告的設定。
    6. +
    7. 移除 googlead.js 指令程式。
    8. +
    9. 修正 common.css 樣式表,移除 Google 廣告的樣式設計。
    10. +
        + +
    + +
    + +
    +
    日期: 12.19.’08.
    + +
      +
    1. 修正 accttrx.cgi 程式,修正 fetch_curitem() 函式,只有在借方或貸方摘要留白時,才會視為現金支出或現金收入傳票。
    2. +
    + +
    + +
    + +
    +
    日期: 12.17.’08.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::BlncShet 類別, DOS 換行修正為 Unix 換行。
    2. +
    + +
    + +
    + +
    +
    日期: 10.13.’08.
    + +
      +
    1. 修正 Selima::htc::HTML 模組,加上 html_googlead() 函式;修正 html_header() 函式,加上呼叫 html_googlead() 函式。
    2. +
    3. 修正 gb*.cgi 程式,加上 Google 廣告的設定。
    4. +
    5. 加上 googlead.js 指令程式。
    6. +
    + +
    + +
    + +
    +
    日期: 4.20.’08.
    + +
      +
    1. 修正 Selima::Form::AcctTrx 類別的 _html_col_recs() 方法,計算表格最後一筆記錄編號時,原用 && 改用 || ,以避免表格由目前值直接轉用時,中間有一筆資料摘要未填,被當成資料結束。
    2. +
    3. 修正 Selima::List 類別的 page_param() 方法,不換頁時直接跳回,不往下計算頁數關係。
    4. +
    + +
    + +
    + +
    +
    日期: 3.20.’08.
    + +
      +
    1. 修正 Selima::Page 類別、 Selima::ReqURI 模組、 Selima::htc::HTML 模組與 nlindex.cgi 程式,英文 index 的複數應為 indices ,不是 indexes
    2. +
    + +
    + +
    + +
    +
    日期: 2.26.’08.
    + +
      +
    1. 修正 Selima::Init 模組的與 checkspam_spammers() 函式,新增一個擋廣告留言的規則。
    2. +
    + +
    + +
    + +
    +
    日期: 2.17.’08.
    + +
      +
    1. 修正 Selima::List 類別與 Selima::imacat::List::Search 類別的 sql_filter() 方法,搜尋條件加上 cast() 型別轉換,以符合 PostgreSQL 8.3.0 的需求。
    2. +
    + +
    + +
    + +
    +
    日期: 2.12.’08.
    + +
      +
    1. 修正 Selima::wov::Items 模組的 newslet_title() 函式,資料庫函式名稱改小寫。
    2. +
    3. 修正 Selima::wov::Items 模組、 Selima::List::Accounting::Reports::Cash::Summary 類別與 Selima::List::Accounting::Reports::Ledger::Summary 類別,資料庫函式 lpad() 的參數加上 cast() 型別轉換,以符合 PostgreSQL 8.3.0 的需求。
    4. +
    5. 修正資料庫定義,資料庫函式 lpad() 的參數加上 cast() 型別轉換,以符合 PostgreSQL 8.3.0 的需求。
    6. +
    7. 修正 Selima::List::Accounting::Reports::Ledger::Summary 類別、 Selima::List::Accounting::Reports::Cash::Summary 類別與 Selima::Checker::Guestbook::Public 類別,資料庫函式 CAST() 改用小寫,以統一程式碼風格。
    8. +
    9. 修正 Selima::imacat::Items 模組、 Selima::wov::Items 模組、 Selima::List::Accounting::Reports::Cash::Summary 類別、 Selima::List::Accounting::Reports::Ledger::Summary 類別與 Selima::List::Accounting::Reports 類別,資料庫函式 EXTRACT() 改用小寫,以統一程式碼風格。
    10. +
    11. 修正資料庫定義,資料庫函式 CAST() 和資料庫函式 EXTRACT() 改用小寫,以統一程式碼風格。
    12. +
    13. 修正 Selima::imacat::Items 模組的 literalzh_title() 函式,資料庫函式 SUBSTRING() 改用小寫,以統一程式碼風格。
    14. +
    + +
    + +
    + +
    +
    日期: 1.31.’08.
    + +
      +
    1. 修正 Selima::imacat::Checker::Diary 模組的 new() 方法,將旅舍日記長度限制延長到 30720 字元。
    2. +
    + +
    + +
    + +
    +
    日期: 12.2.’07.
    + +
      +
    1. 修正 Selima::A2HTML 模組、 Selima::LogOut 模組、 Selima::Session 模組、 Selima::NewSN 模組、 Selima::CallForm 模組、 Selima::Processor 模組與 Selima::Mail 模組, do { … } while … 改用 do { … } until !… 以使程式碼更易讀。
    2. +
    + +
    + +
    + +
    +
    日期: 11.18.’07.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Journal 類別的 fetch() 方法,計算上期結轉時,排除掉上期科目為上期結轉的科目。
    2. +
    + +
    + +
    + +
    +
    日期: 11.4.’07.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_reqheads() 函式,調整一個擋廣告留言規則的適用範圍。
    2. +
    3. 修正 Selima::Init 模組,加上一個新的擋廣告留言規則。
    4. +
    + +
    + +
    + +
    +
    日期: 10.15.’07.
    + +
      +
    1. 修正 Selima::Init 模組,將新加入的擋廣告留言規則和另一規則合併,並加上新的規則。
    2. +
    3. 修正 Selima::Init 模組的 checkspam_*() 函式,回傳訊息前面加上函式名稱以資辨別,並便了解各規則的擋廣告信效能;加上沒問題時回傳空值。
    4. +
    5. 修正 Selima::Checker::*::Guestbook::Public 類別的 _checkspam_local() 方法,回傳訊息前面加上函式名稱以資辨別。
    6. +
    7. 修正 Selima::Logging 模組,加上 spamlog() 函式與 sub check_spamlog_file() 函式,將擋廣告留言分開記錄,以保持活動記錄擋簡潔易讀;修正 Selima::Init 模組的 block_spam() 函式與 Selima::Checker::Guestbook::Public 類別的 _block_spam() 方法,改用 spamlog 記錄到擋廣告留言記錄。
    8. +
    + +
    + +
    + +
    +
    日期: 10.15.’07.
    + +
      +
    1. 修正 Selima::Init 模組,新增一個擋廣告留言的規則。
    2. +
    3. 修正 Selima::Init 模組的各 checkspam_*() 函式,改接受表格為參數,並回傳擋留言的訊息,不直接擋掉留言,而改由 check_spam() 依各 checkspam_*() 函式的回傳值擋掉留言,以便可以另寫程式,測試各 checkspam_*() 函式的規則。
    4. +
    5. 修正 Selima::*::HTML 模組的 html_nav_admin() 函式,調整路徑時,另用 $path 複製路徑後再調整,以免在 mod_perl 下重複調整路徑。
    6. +
    7. 修正 Selima::*::HTML 模組的 html_nav_admin() 函式,刪掉輸出時重複的權限檢查。
    8. +
    9. 修正 Selima::*::HTML 模組,修正 @ADMIN_SCRIPTS 變數,新增 https 屬性設定是否需加密處理;修正 html_nav_admin() 函式,移除針對會計程式的特殊處理,改針對新的 https 屬性決定是否需調整路徑加密處理。
    10. +
    + +
    + +
    + +
    +
    日期: 10.11.’07.
    + +
      +
    1. 依最新的 ISO 3166-1 (2006-09-26) 、 CNS 12842 (2006-04-19) 及 GB/T 2659-2000 ,更新資料庫中的國家資料。
    2. +
    3. 修正 Selima::imacat::List::Guestbook 類別,加上 lang 欄位的標題。
    4. +
    5. 修正 guestbook.cgi 程式,修正 fetch_curitem() 函式,將 lang 設為 lang0 ;修正 check_post() 函式,加上檢查 lang 欄位。
    6. +
    7. 修正 Selima::imacat::Form::Guestbook 類別,加上 new() 方法與 _html_col_lang() 方法,以顯示語言欄位。
    8. +
    9. 修正 Selima::imacat::Checker::Guestbook 類別,加上 _check_lang() 方法,以檢查語言設定。
    10. +
    11. 新增 Selima::imacat::Processor::Guestbook 類別;修正 guestbook.cgi 程式的 main() 函式,改用 Selima::imacat::Processor::Guestbook 類別。
    12. +
    13. 修正 Selima::Checker::AcctTrx 類別的 _check_recs() 方法,依現金收入或現金支出傳票計算列數時,之前借貸方向弄反了未修正。
    14. +
    15. 修正 Selima::Form::AcctTrx 類別的 _html_col_recs() 方法,顯示目前合計金額時誤用 $count_cur ,修正為 $count_new
    16. +
    17. 修正 Selima::Processor::AcctTrx 類別的 _save_cols() 方法,刪傳票調整現有傳票次序時,設定 ISO 格式的日期值,以避免比對錯誤。
    18. +
    + +
    + +
    + +
    +
    日期: 10.10.’07.
    + +
      +
    1. 修正旅舍的 guestbook 資料表,加上 lang 欄位記錄留言的語言,以解決繁簡自動轉換的錯誤。
    2. +
    3. 修正 Selima::List::Guestbook::Public 類別的 html_list() 方法,當留言標示為繁體時,不再轉繁;當留言標示為簡體時,不再轉簡,以免自動繁簡轉換把對的字轉錯掉。
    4. +
    5. 修正 users_list* 資料瀏覽,加上西班牙文。
    6. +
    + +
    + +
    + +
    +
    日期: 10.10.’07.
    + +
      +
    1. 修正 Selima::GeoIP 模組,私有網路代號改為 AA ,未知代號改為 ZZ ,以符合 ISO 3166 User-assigned code elements 的規定。
    2. +
    + +
    + +
    + +
    +
    日期: 10.5.’07.
    + +
      +
    1. 修正 Selima::AddCol 類別的 adddate() 方法,比較新舊日期時,新日期先轉換成 epoch 秒數,才能跟原日期正確比較。
    2. +
    3. 修正 Selima::Form::AcctTrx 類別的 _html_col_recs() 方法,計算目前有資料的列數時,列數更正最後一列的編號加一,以正確預留五列空白列。
    4. +
    5. 修正 Selima::Processor::AcctTrx 類別的 _save_cols() 方法,調整次序時,子處理器的新日期以 fmtdate() 轉為標準日期格式,以便 Selima::AddCol 類別正確處理。
    6. +
    7. 修正 accttrx 資料表,註記的長度加大為 128 。
    8. +
    + +
    + +
    + +
    +
    日期: 10.3.’07.
    + +
      +
    1. 修正 Selima::Form::AcctTrx 類別的 _html_coltmpl_ro_loop_rec() 方法與 _html_col_recs() 方法,目前值與合計的金額用金額格式顯示,並將空的欄位以空字串顯示,不以未設定顯示,讓傳票看起來比較正常。
    2. +
    3. 修正 acctsubj.cgi 程式的 fetch_current() 函式,單語時正確取得子科目的清單。
    4. +
    5. 修正 Selima::List::Accounting::Reports::** 類別,3711 上期結轉改用3351 累積盈虧,並刪除不必要的自建科目37 上期結轉(或結轉下期)371 上期結轉(或結轉下期)3711 結轉下期3712 上期結轉
    6. +
    7. 修正 Selima::List::Accounting::Reports::TriBlnc 類別的 fetch() 方法,分類帳連結網址由 subj 更正為 ldgr
    8. +
    9. 修正 Selima::Form::AcctTrx 類別的 _html_coltmpl_loop_rec() 方法,金額欄位向右對齊。
    10. +
    11. 修正 Selima::Form::AcctTrx 類別的 _html_col_recs() 方法,加上新值的合計列,並為新值的金額欄位加上 onchange 處理器;修正 accounting.js 指令檔,加上 calcTotal() 函式,以即時修正、反映新金額值的合計。
    12. +
    13. 修正 Selima::Accounting 模組,加上 ACCT_SUBJ_CASH 常數;修正 accttrx.cgi 程式、 Selima::Checker::AcctTrx 模組、 Selima::Processor::AcctTrx 模組、 Selima::List::Accounting::Reports::Ledger 模組和 Selima::List::Accounting::Reports::Ledger::Summary 模組,現金科目代號改用 ACCT_SUBJ_CASH 常數。
    14. +
    15. 修正 Selima::Accounting 模組,加上 ACCTSUBJ_CASH 常數;修正 accttrx.cgi 程式、 Selima::Checker::AcctTrx 類別、 Selima::Processor::AcctTrx 類別、 Selima::List::Accounting::Reports::Ledger 類別和 Selima::List::Accounting::Reports::Ledger::Summary 類別,現金科目代號改用 ACCTSUBJ_CASH 常數。
    16. +
    17. 修正 Selima::Accounting 模組,加上 ACCTSUBJ_INCOME_CUR 常數;修正Selima::List::Accounting::Reports::IncmStat 類別和 Selima::List::Accounting::Reports::BlncShet 類別,本期損益代號改用 ACCTSUBJ_INCOME_CUR 常數。
    18. +
    19. 修正 Selima::Accounting 模組,加上 ACCTSUBJ_INCOME_ACUM 常數;修正Selima::List::Accounting::Reports::Cash 類別、 Selima::List::Accounting::Reports::Journal 類別、 Selima::List::Accounting::Reports::TriBlnc 類別和 Selima::List::Accounting::Reports::BlncShet 類別,累積盈虧代號改用 ACCTSUBJ_INCOME_ACUM 常數。
    20. +
    21. 修正 Selima::List::Accounting::Reports::Cash 類別的 fetch() 方法,第一期時不插入上期結轉分錄。
    22. +
    23. 修正 acctrep_cash_list* 資料表瀏覽的定義,排序時將借方列於貸方之前。這是之前借貸錯亂沒修好的遺留物。
    24. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 13 | + 14 | + 15 | + 16 | + 17 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0016.html.en.html b/htdocs/imacat/me/changelog/0016.html.en.html new file mode 120000 index 0000000..497d373 --- /dev/null +++ b/htdocs/imacat/me/changelog/0016.html.en.html @@ -0,0 +1 @@ +0016.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0016.html.en.xhtml b/htdocs/imacat/me/changelog/0016.html.en.xhtml new file mode 100644 index 0000000..d3edab3 --- /dev/null +++ b/htdocs/imacat/me/changelog/0016.html.en.xhtml @@ -0,0 +1,364 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 16 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 16

    + +
    + +
    + +
    +
    Date: 5.19.’12.
    + +
      +
    • Selima::imacat::List::Papers::Papers 類別改名為 Selima::imacat::List::Papers 類別; Selima::imacat::Form::Papers::Paper 類別改名為 Selima::imacat::Form::Paper 類別; Selima::imacat::Checker::Papers::Paper 類別改名為 Selima::imacat::Checker::Paper 類別; Selima::imacat::Processor::Papers::Paper 類別改名為 Selima::imacat::Processor::Paper 類別。
    • +
    • pprrschr 資料表改名為 resrcher 資料表;pprrschr.cgi 程式改名為 resrcher.cgi 程式; Selima::imacat::List::Papers::Researchers 類別改名為 Selima::imacat::List::Researchers 類別; Selima::imacat::Form::Papers::Researcher 類別改名為 Selima::imacat::Form::Researcher 類別; Selima::imacat::Checker::Papers::Researcher 類別改名為 Selima::imacat::Checker::Researcher 類別; Selima::imacat::Processor::Papers::Researcher 類別改名為 Selima::imacat::Processor::Researcher 類別; FORM_PPRRSCHR 常數改名為 FORM_RESRCHER 常數。
    • +
    • Selima::imacat::List::Papers::Authors 類別改名為 Selima::imacat::List::Paper::Authors 類別; Selima::imacat::Form::Papers::Author 類別改名為 Selima::imacat::Form::Paper::Author 類別; Selima::imacat::Checker::Papers::Author 類別改名為 Selima::imacat::Checker::Paper::Author 類別; Selima::imacat::Processor::Papers::Author 類別改名為 Selima::imacat::Processor::Paper::Author 類別。
    • +
    • 修正 Selima::Form 類別,加上 _html_coltmpl_tags() 方法。
    • +
    • 修正 Selima::imacat::Form::Paper 類別、 Selima::imacat::Checker::Paper 類別及 Selima::imacat::Processor::Paper 類別,作者欄位改用標籤法。
    • +
    • 修正 Selima::imacat::Items 模組,加上 abbreviate_name() 函式。
    • +
    • 修正 papers 資料表、 Selima::imacat::Form::Paper 類別、 Selima::imacat::Checker::Paper 類別、 Selima::imacat::Processor::Paper 類別,刪除 emp 欄位及 body 欄位。
    • +
    • 加上 tags 資料表、 pprtags 資料表、 Selima::imacat::List::Tags 類別、Selima::imacat::List::Paper::Tags 類別、 Selima::imacat::Form::Tag 類別、Selima::imacat::Form::Paper::Tag 類別、 Selima::imacat::Checker::Tag 類別、Selima::imacat::Checker::Paper::Tag 類別、 Selima::imacat::Processor::Tag 類別及Selima::imacat::Processor::Paper::Tag 類別,以處理標籤。
    • +
    • 修正 papers.cgi 程式、 Selima::imacat::List::Papers 類別、 Selima::imacat::Form::Paper 類別、 Selima::imacat::Checker::Paper 類別及 Selima::imacat::Processor::Paper 類別,加上標籤欄位。
    • +
    + +
    + +
    + +
    +
    Date: 5.16.’12.
    + +
      +
    • 加上 pprtypes.cgi 程式、 pprrschr.cgi 程式、 papers.cgi 程式及 pprauthr.cgi 程式,加上 Selima::imacat::List::Papers::Types 類別、 Selima::imacat::List::Papers::Researchers 類別、 Selima::imacat::List::Papers::Papers 類別及 Selima::imacat::List::Papers::Authors 類別,加上 Selima::imacat::Form::Papers::Type 類別、 Selima::imacat::Form::Papers::Researcher 類別、 Selima::imacat::Form::Papers::Paper 類別及 Selima::imacat::Form::Papers::Author 類別,加上 Selima::imacat::Checker::Papers::Type 類別、 Selima::imacat::Checker::Papers::Researcher 類別、 Selima::imacat::Checker::Papers::Paper 類別及 Selima::imacat::Checker::Papers::Author 類別,加上 Selima::imacat::Processor::Papers::Type 類別、 Selima::imacat::Processor::Papers::Researcher 類別、 Selima::imacat::Processor::Papers::Paper 類別及 Selima::imacat::Processor::Papers::Author 類別,以整理閱讀的論文。
    • +
    • 修正 Selima::imacat::HTML 模組的 @ADMIN_SCRIPTS 陣列,加上 pprtypes.cgi 程式、 pprrschr.cgi 程式、 papers.cgi 程式及 pprauthr.cgi 程式。
    • +
    • 修正 Selima::imacat::DataVars 模組,加上 FORM_PAPERS 常數及 FORM_PPRRSCHR 常數;加上匯出 FORM_PAPERS 常數及 FORM_PPRRSCHR 常數;修正 clear() 函式,加上清除 FORM_PAPERS 常數及 FORM_PPRRSCHR 常數。
    • +
    • 修正 Selima::imacat::Config 模組,修正 siteconf() 函式,加上 FORM_PAPERS 常數及 FORM_PPRRSCHR 常數。
    • +
    + +
    + +
    + +
    +
    Date: 5.16.’12.
    + +
      +
    • 修正 Selima::Checker::LinkCatz 類別的 _redir_dellink() 方法,檢查欄位由 sellink 修正為 dellink ;修正 _check_link() 方法的註解, user 修正為 link
    • +
    + +
    + +
    + +
    +
    Date: 5.16.’12.
    + +
      +
    • 修正 Selima::Checker::Link 類別的 _check_url() 方法,欄位空白檢查欄位由 title 修正為 url ,並加上值為 http:// 的檢查。
    • +
    + +
    + +
    + +
    +
    Date: 2.21.’12.
    + +
      +
    • 修正 Selima::Init 模組, check_spambots() 函式的記錄訊息由 block_spambots 修正為 check_spambots ;註解掉 block_spam_robots() 函式、 check_spam() 函式和 checkspam_*() 函式,新的 CAPTCHA 簡單又效果良好,舊的複雜規則已經不用了,註解掉減少系統資源。
    • +
    + +
    + +
    + +
    +
    Date: 2.21.’12.
    + +
      +
    • 修正 Selima::Init 模組,將 block_spambots() 函式更名為 check_spambots() 函式,以和 block_spam() 函式區隔;修正 check_spambots() 函式,檢查 CAPTCHA 欄位前先取得欄位名稱,以便錯誤檢查空欄位;修正 check_spambots() 函式,錯誤訊息字串 + 改正為 . ,以記錄正確的錯誤訊息,修正之前記錄內容都是 0 的錯誤;將 block_spam() 函式移到前面,以和後面已不用的 check_spam() 函式、 checkspam_*() 函式區隔 。
    • +
    • 修正 Selima::Checker 類別的 _check_captcha() 方法,錯誤訊息字串 + 改正為 . ,以記錄正確的錯誤訊息,修正之前記錄內容都是 0 的錯誤 。
    • +
    + +
    + +
    + +
    +
    Date: 2.18.’12.
    + +
      +
    1. 修正 Selima::Init 模組,加上 block_spambots() 函式;修正 initenv() 函式,加上呼叫 block_spambots() 函式。
    2. +
    + +
    + +
    + +
    +
    Date: 2.17.’12.
    + +
      +
    1. 修正 Selima::DataVars 模組,加上 FORM_CAPTCHA 常數。
    2. +
    3. 修正 Selima::Form 類別,加上引入 FORM_CAPTCHA 常數;加上 _html_col_captcha() 方法,以顯示 CAPTCHA 欄位。
    4. +
    5. 修正 Selima::Form::Guestbook::Public 類別的 new() 方法,加上顯示 CAPTCHA 欄位。
    6. +
    7. 修正 Selima::Checker::Guestbook::Public 類別,將 _check_spam() 方法和 _block_spam() 方法移到 Selima::Checker 類別。
    8. +
    9. 修正 Selima::Checker 類別,加上 Selima::Checker::Guestbook::Public 類別移來的 _check_spam() 方法和 _block_spam() 方法;加上引入 FORM_CAPTCHA 常數;加上 _check_captcha() 方法,以檢查 CAPTCHA 欄位;修正 _check_spam() 方法,加上呼叫 _check_captcha() 方法檢查。
    10. +
    11. 修正 Selima::Init 模組的 initenv()函式,暫停執行 block_bad_robots() 方法,改用新的 CAPTCHA 檢查。
    12. +
    13. 修正 Selima::imacat::Form::Garbage::Public 類別,加上引入 FORM_CAPTCHA 常數;加上 _html_col_captcha() 方法,以顯示 CAPTCHA 欄位:修正 new() 方法,加上顯示 CAPTCHA 欄位。
    14. +
    15. gb*.cgi 程式改名回 guestbook.cgi 。採用 CAPTCHA 後,已無必要使用亂數檔名,原先的做法也沒什麼用。
    16. +
    17. 修正 *.sql 資料庫定義,留言簿網址由 gb*.cgi 改為 guestbook.cgi
    18. +
    19. 修正 Selima::*::List::Search 類別的 html_list() 方法,留言簿網址由 gb*.cgi 改為 guestbook.cgi
    20. +
    21. 修正 header*.html 檔,留言簿網址由 gb*.cgi 改為 guestbook.cgi
    22. +
    23. 修正首頁 index*.html 檔,留言簿網址由 gb*.cgi 改為 guestbook.cgi
    24. +
    + +
    + +
    + +
    +
    Date: 6.30.’11.
    + +
      +
    1. 修正 Selima::ListPref 類別的 _check_post() 方法,qw(…) 加上括弧,以符合 Perl 5.14.1 。
    2. +
    3. 修正 Selima::ListPref::AcctReps 類別的 _check_post() 方法,qw(…) 加上括弧,以符合 Perl 5.14.1 。
    4. +
    + +
    + +
    + +
    +
    Date: 1.29.’11.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Ledger 類別的 html_data_download() 方法, list=subj 修正為 list=ldgr
    2. +
    + +
    + +
    + +
    +
    Date: 12.3.’10.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_spammers() 函式,在擋清濤命理研究中心的規則上,加註清濤蔡東楓騙財騙色被抓的事。抓得好!哇哈哈哈哈,太爽了。。
    2. +
    + +
    + +
    + +
    +
    Date: 9.2.’10.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::BlncShet 類別的 fetch 方法,略掉餘額為零的科目。
    2. +
    + +
    + +
    + +
    +
    Date: 9.20.’09.
    + +
      +
    1. 修正 Selima::List 類別的 check_pageno 方法,把 0 加進無效頁碼的條件中。
    2. +
    + +
    + +
    + +
    +
    Date: 6.14.’09.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Cash 類別、 Selima::List::Accounting::Reports::Ledger::SummarySelima::List::Accounting::Reports::Cash::Summary 類別,加上 use Selima::LnInfo; ,以解決在非預設語言下無法執行,找不到 ln() 函式的問題。
    2. +
    3. 修正 Selima::List::Accounting::Reports::Cash::Summary 類別的 new() 方法,建立暫用檢視時, extract(cast(month FROM date) AS text) 的錯誤修正為 cast(extract(month FROM date) AS text)
    4. +
    5. 修正 Selima::List::Accounting::Reports::Journal 類別的 fetch() 方法,科目代碼 ACCTSUBJ_INCOME_ACUM 改用 $DBH->quote(ACCTSUBJ_INCOME_ACUM) ,以符合 PostgreSQL 8.3.0 取消自動型別轉換的做法。
    6. +
    7. 修正資料庫定義中的 acctrep_search_list* 檢視,為使檢索結果能依時間由新到舊排序,排序依時間次序由前到後,改由由後到前。
    8. +
    9. 修正 Selima::List::Accounting::Reports::Search 類別,為使檢索結果能依時間由新到舊排序,修正 new() 方法,加上 $self->{"reverse"} = 1; 設定結果由後到先顯示;修正 fetch() 方法,將取得資料反過來排列;加上 html_list() 方法,同一頁面的資料,改以由舊到新排列,以符合帳簿閱讀的習慣。
    10. +
    + +
    + +
    + +
    +
    Date: 6.13.’09.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_masslinks() 函式。
    2. +
    + +
    + +
    + +
    +
    Date: 4.27.’09.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_reqheads() 函式,加上新的擋廣告留言規則;修正原有的擋廣告信規則,以便 CGI 和 mod_perl 模式一體適用。
    2. +
    + +
    + +
    + +
    +
    Date: 4.9.’09.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_reqheads() 函式,加上新的擋廣告留言規則。
    2. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 13 | + 14 | + 15 | + 16 | + 17 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0016.html.zh-cn.html b/htdocs/imacat/me/changelog/0016.html.zh-cn.html new file mode 120000 index 0000000..9771072 --- /dev/null +++ b/htdocs/imacat/me/changelog/0016.html.zh-cn.html @@ -0,0 +1 @@ +0016.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0016.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0016.html.zh-cn.xhtml new file mode 100644 index 0000000..6fe6e41 --- /dev/null +++ b/htdocs/imacat/me/changelog/0016.html.zh-cn.xhtml @@ -0,0 +1,363 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷十六 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷十六

    + +
    + +
    + +
    +
    日期: 5.19.’12.
    + +
      +
    • Selima::imacat::List::Papers::Papers 类别改名为 Selima::imacat::List::Papers 类别; Selima::imacat::Form::Papers::Paper 类别改名为 Selima::imacat::Form::Paper 类别; Selima::imacat::Checker::Papers::Paper 类别改名为 Selima::imacat::Checker::Paper 类别; Selima::imacat::Processor::Papers::Paper 类别改名为 Selima::imacat::Processor::Paper 类别。
    • +
    • pprrschr 资料表改名为 resrcher 资料表;pprrschr.cgi 程式改名为 resrcher.cgi 程式; Selima::imacat::List::Papers::Researchers 类别改名为 Selima::imacat::List::Researchers 类别; Selima::imacat::Form::Papers::Researcher 类别改名为 Selima::imacat::Form::Researcher 类别; Selima::imacat::Checker::Papers::Researcher 类别改名为 Selima::imacat::Checker::Researcher 类别; Selima::imacat::Processor::Papers::Researcher 类别改名为 Selima::imacat::Processor::Researcher 类别; FORM_PPRRSCHR 常数改名为 FORM_RESRCHER 常数。
    • +
    • Selima::imacat::List::Papers::Authors 类别改名为 Selima::imacat::List::Paper::Authors 类别; Selima::imacat::Form::Papers::Author 类别改名为 Selima::imacat::Form::Paper::Author 类别; Selima::imacat::Checker::Papers::Author 类别改名为 Selima::imacat::Checker::Paper::Author 类别; Selima::imacat::Processor::Papers::Author 类别改名为 Selima::imacat::Processor::Paper::Author 类别。
    • +
    • 修正 Selima::Form 类别,加上 _html_coltmpl_tags() 方法。
    • +
    • 修正 Selima::imacat::Form::Paper 类别、 Selima::imacat::Checker::Paper 类别及 Selima::imacat::Processor::Paper 类别,作者栏位改用标签法。
    • +
    • 修正 Selima::imacat::Items 模组,加上 abbreviate_name() 函式。
    • +
    • 修正 papers 资料表、 Selima::imacat::Form::Paper 类别、 Selima::imacat::Checker::Paper 类别、 Selima::imacat::Processor::Paper 类别,删除 emp 栏位及 body 栏位。
    • +
    • 加上 tags 资料表、 pprtags 资料表、 Selima::imacat::List::Tags 类别、Selima::imacat::List::Paper::Tags 类别、 Selima::imacat::Form::Tag 类别、Selima::imacat::Form::Paper::Tag 类别、 Selima::imacat::Checker::Tag 类别、Selima::imacat::Checker::Paper::Tag 类别、 Selima::imacat::Processor::Tag 类别及Selima::imacat::Processor::Paper::Tag 类别,以处理标签。
    • +
    • 修正 papers.cgi 程式、 Selima::imacat::List::Papers 类别、 Selima::imacat::Form::Paper 类别、 Selima::imacat::Checker::Paper 类别及 Selima::imacat::Processor::Paper 类别,加上标签栏位。
    • +
    + +
    + +
    + +
    +
    日期: 5.16.’12.
    + +
      +
    • 加上 pprtypes.cgi 程式、 pprrschr.cgi 程式、 papers.cgi 程式及 pprauthr.cgi 程式,加上 Selima::imacat::List::Papers::Types 类别、 Selima::imacat::List::Papers::Researchers 类别、 Selima::imacat::List::Papers::Papers 类别及 Selima::imacat::List::Papers::Authors 类别,加上 Selima::imacat::Form::Papers::Type 类别、 Selima::imacat::Form::Papers::Researcher 类别、 Selima::imacat::Form::Papers::Paper 类别及 Selima::imacat::Form::Papers::Author 类别,加上 Selima::imacat::Checker::Papers::Type 类别、 Selima::imacat::Checker::Papers::Researcher 类别、 Selima::imacat::Checker::Papers::Paper 类别及 Selima::imacat::Checker::Papers::Author 类别,加上 Selima::imacat::Processor::Papers::Type 类别、 Selima::imacat::Processor::Papers::Researcher 类别、 Selima::imacat::Processor::Papers::Paper 类别及 Selima::imacat::Processor::Papers::Author 类别,以整理阅读的论文。
    • +
    • 修正 Selima::imacat::HTML 模组的 @ADMIN_SCRIPTS 阵列,加上 pprtypes.cgi 程式、 pprrschr.cgi 程式、 papers.cgi 程式及 pprauthr.cgi 程式。
    • +
    • 修正 Selima::imacat::DataVars 模组,加上 FORM_PAPERS 常数及 FORM_PPRRSCHR 常数;加上汇出 FORM_PAPERS 常数及 FORM_PPRRSCHR 常数;修正 clear() 函式,加上清除 FORM_PAPERS 常数及 FORM_PPRRSCHR 常数。
    • +
    • 修正 Selima::imacat::Config 模组,修正 siteconf() 函式,加上 FORM_PAPERS 常数及 FORM_PPRRSCHR 常数。
    • +
    + +
    + +
    + +
    +
    日期: 5.16.’12.
    + +
      +
    • 修正 Selima::Checker::LinkCatz 类别的 _redir_dellink() 方法,检查栏位由 sellink 修正为 dellink ;修正 _check_link() 方法的注解, user 修正为 link
    • +
    + +
    + +
    + +
    +
    日期: 5.16.’12.
    + +
      +
    • 修正 Selima::Checker::Link 类别的 _check_url() 方法,栏位空白检查栏位由 title 修正为 url ,并加上值为 http:// 的检查。
    • +
    + +
    + +
    + +
    +
    日期: 2.21.’12.
    + +
      +
    • 修正 Selima::Init 模组, check_spambots() 函式的记录讯息由 block_spambots 修正为 check_spambots ;注解掉 block_spam_robots() 函式、 check_spam() 函式和 checkspam_*() 函式,新的 CAPTCHA 简单又效果良好,旧的复杂规则已经不用了,注解掉减少系统资源。
    • +
    + +
    + +
    + +
    +
    日期: 2.21.’12.
    + +
      +
    • 修正 Selima::Init 模组,将 block_spambots() 函式更名为 check_spambots() 函式,以和 block_spam() 函式区隔;修正 check_spambots() 函式,检查 CAPTCHA 栏位前先取得栏位名称,以便错误检查空栏位;修正 check_spambots() 函式,错误讯息字串 + 改正为 . ,以记录正确的错误讯息,修正之前记录内容都是 0 的错误;将 block_spam() 函式移到前面,以和后面已不用的 check_spam() 函式、 checkspam_*() 函式区隔 。
    • +
    • 修正 Selima::Checker 类别的 _check_captcha() 方法,错误讯息字串 + 改正为 . ,以记录正确的错误讯息,修正之前记录内容都是 0 的错误 。
    • +
    + +
    + +
    + +
    +
    日期: 2.18.’12.
    + +
      +
    1. 修正 Selima::Init 模组,加上 block_spambots() 函式;修正 initenv() 函式,加上呼叫 block_spambots() 函式。
    2. +
    + +
    + +
    + +
    +
    日期: 2.17.’12.
    + +
      +
    1. 修正 Selima::DataVars 模组,加上 FORM_CAPTCHA 常数。
    2. +
    3. 修正 Selima::Form 类别,加上引入 FORM_CAPTCHA 常数;加上 _html_col_captcha() 方法,以显示 CAPTCHA 栏位。
    4. +
    5. 修正 Selima::Form::Guestbook::Public 类别的 new() 方法,加上显示 CAPTCHA 栏位。
    6. +
    7. 修正 Selima::Checker::Guestbook::Public 类别,将 _check_spam() 方法和 _block_spam() 方法移到 Selima::Checker 类别。
    8. +
    9. 修正 Selima::Checker 类别,加上 Selima::Checker::Guestbook::Public 类别移来的 _check_spam() 方法和 _block_spam() 方法;加上引入 FORM_CAPTCHA 常数;加上 _check_captcha() 方法,以检查 CAPTCHA 栏位;修正 _check_spam() 方法,加上呼叫 _check_captcha() 方法检查。
    10. +
    11. 修正 Selima::Init 模组的 initenv()函式,暂停执行 block_bad_robots() 方法,改用新的 CAPTCHA 检查。
    12. +
    13. 修正 Selima::imacat::Form::Garbage::Public 类别,加上引入 FORM_CAPTCHA 常数;加上 _html_col_captcha() 方法,以显示 CAPTCHA 栏位:修正 new() 方法,加上显示 CAPTCHA 栏位。
    14. +
    15. gb*.cgi 程式改名回 guestbook.cgi 。采用 CAPTCHA 后,已无必要使用乱数档名,原先的做法也没什么用。
    16. +
    17. 修正 *.sql 资料库定义,留言簿网址由 gb*.cgi 改为 guestbook.cgi
    18. +
    19. 修正 Selima::*::List::Search 类别的 html_list() 方法,留言簿网址由 gb*.cgi 改为 guestbook.cgi
    20. +
    21. 修正 header*.html 档,留言簿网址由 gb*.cgi 改为 guestbook.cgi
    22. +
    23. 修正首页 index*.html 档,留言簿网址由 gb*.cgi 改为 guestbook.cgi
    24. +
    + +
    + +
    + +
    +
    日期: 6.30.’11.
    + +
      +
    1. 修正 Selima::ListPref 类别的 _check_post() 方法,qw(…) 加上括弧,以符合 Perl 5.14.1 。
    2. +
    3. 修正 Selima::ListPref::AcctReps 类别的 _check_post() 方法,qw(…) 加上括弧,以符合 Perl 5.14.1 。
    4. +
    + +
    + +
    + +
    +
    日期: 1.29.’11.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Ledger 类别的 html_data_download() 方法, list=subj 修正为 list=ldgr
    2. +
    + +
    + +
    + +
    +
    日期: 12.3.’10.
    + +
      +
    1. 修正 Selima::Init 模组的 checkspam_spammers() 函式,在挡清涛命理研究中心的规则上,加注清涛蔡东枫骗财骗色被抓的事。抓得好!哇哈哈哈哈,太爽了。。
    2. +
    + +
    + +
    + +
    +
    日期: 9.2.’10.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::BlncShet 类别的 fetch 方法,略掉余额为零的科目。
    2. +
    + +
    + +
    + +
    +
    日期: 9.20.’09.
    + +
      +
    1. 修正 Selima::List 类别的 check_pageno 方法,把 0 加进无效页码的条件中。
    2. +
    + +
    + +
    + +
    +
    日期: 6.14.’09.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Cash 类别、 Selima::List::Accounting::Reports::Ledger::SummarySelima::List::Accounting::Reports::Cash::Summary 类别,加上 use Selima::LnInfo; ,以解决在非预设语言下无法执行,找不到 ln() 函式的问题。
    2. +
    3. 修正 Selima::List::Accounting::Reports::Cash::Summary 类别的 new() 方法,建立暂用检视时, extract(cast(month FROM date) AS text) 的错误修正为 cast(extract(month FROM date) AS text)
    4. +
    5. 修正 Selima::List::Accounting::Reports::Journal 类别的 fetch() 方法,科目代码 ACCTSUBJ_INCOME_ACUM 改用 $DBH->quote(ACCTSUBJ_INCOME_ACUM) ,以符合 PostgreSQL 8.3.0 取消自动型别转换的做法。
    6. +
    7. 修正资料库定义中的 acctrep_search_list* 检视,为使检索结果能依时间由新到旧排序,排序依时间次序由前到后,改由由后到前。
    8. +
    9. 修正 Selima::List::Accounting::Reports::Search 类别,为使检索结果能依时间由新到旧排序,修正 new() 方法,加上 $self->{"reverse"} = 1; 设定结果由后到先显示;修正 fetch() 方法,将取得资料反过来排列;加上 html_list() 方法,同一页面的资料,改以由旧到新排列,以符合帐簿阅读的习惯。
    10. +
    + +
    + +
    + +
    +
    日期: 6.13.’09.
    + +
      +
    1. 修正 Selima::Init 模组的 checkspam_masslinks() 函式。
    2. +
    + +
    + +
    + +
    +
    日期: 4.27.’09.
    + +
      +
    1. 修正 Selima::Init 模组的 checkspam_reqheads() 函式,加上新的挡广告留言规则;修正原有的挡广告信规则,以便 CGI 和 mod_perl 模式一体适用。
    2. +
    + +
    + +
    + +
    +
    日期: 4.9.’09.
    + +
      +
    1. 修正 Selima::Init 模组的 checkspam_reqheads() 函式,加上新的挡广告留言规则。
    2. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 13 | + 14 | + 15 | + 16 | + 17 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0016.html.zh-tw.html b/htdocs/imacat/me/changelog/0016.html.zh-tw.html new file mode 120000 index 0000000..1c2cac3 --- /dev/null +++ b/htdocs/imacat/me/changelog/0016.html.zh-tw.html @@ -0,0 +1 @@ +0016.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0016.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0016.html.zh-tw.xhtml new file mode 100644 index 0000000..e2d79b0 --- /dev/null +++ b/htdocs/imacat/me/changelog/0016.html.zh-tw.xhtml @@ -0,0 +1,363 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷十六 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷十六

    + +
    + +
    + +
    +
    日期: 5.19.’12.
    + +
      +
    • Selima::imacat::List::Papers::Papers 類別改名為 Selima::imacat::List::Papers 類別; Selima::imacat::Form::Papers::Paper 類別改名為 Selima::imacat::Form::Paper 類別; Selima::imacat::Checker::Papers::Paper 類別改名為 Selima::imacat::Checker::Paper 類別; Selima::imacat::Processor::Papers::Paper 類別改名為 Selima::imacat::Processor::Paper 類別。
    • +
    • pprrschr 資料表改名為 resrcher 資料表;pprrschr.cgi 程式改名為 resrcher.cgi 程式; Selima::imacat::List::Papers::Researchers 類別改名為 Selima::imacat::List::Researchers 類別; Selima::imacat::Form::Papers::Researcher 類別改名為 Selima::imacat::Form::Researcher 類別; Selima::imacat::Checker::Papers::Researcher 類別改名為 Selima::imacat::Checker::Researcher 類別; Selima::imacat::Processor::Papers::Researcher 類別改名為 Selima::imacat::Processor::Researcher 類別; FORM_PPRRSCHR 常數改名為 FORM_RESRCHER 常數。
    • +
    • Selima::imacat::List::Papers::Authors 類別改名為 Selima::imacat::List::Paper::Authors 類別; Selima::imacat::Form::Papers::Author 類別改名為 Selima::imacat::Form::Paper::Author 類別; Selima::imacat::Checker::Papers::Author 類別改名為 Selima::imacat::Checker::Paper::Author 類別; Selima::imacat::Processor::Papers::Author 類別改名為 Selima::imacat::Processor::Paper::Author 類別。
    • +
    • 修正 Selima::Form 類別,加上 _html_coltmpl_tags() 方法。
    • +
    • 修正 Selima::imacat::Form::Paper 類別、 Selima::imacat::Checker::Paper 類別及 Selima::imacat::Processor::Paper 類別,作者欄位改用標籤法。
    • +
    • 修正 Selima::imacat::Items 模組,加上 abbreviate_name() 函式。
    • +
    • 修正 papers 資料表、 Selima::imacat::Form::Paper 類別、 Selima::imacat::Checker::Paper 類別、 Selima::imacat::Processor::Paper 類別,刪除 emp 欄位及 body 欄位。
    • +
    • 加上 tags 資料表、 pprtags 資料表、 Selima::imacat::List::Tags 類別、Selima::imacat::List::Paper::Tags 類別、 Selima::imacat::Form::Tag 類別、Selima::imacat::Form::Paper::Tag 類別、 Selima::imacat::Checker::Tag 類別、Selima::imacat::Checker::Paper::Tag 類別、 Selima::imacat::Processor::Tag 類別及Selima::imacat::Processor::Paper::Tag 類別,以處理標籤。
    • +
    • 修正 papers.cgi 程式、 Selima::imacat::List::Papers 類別、 Selima::imacat::Form::Paper 類別、 Selima::imacat::Checker::Paper 類別及 Selima::imacat::Processor::Paper 類別,加上標籤欄位。
    • +
    + +
    + +
    + +
    +
    日期: 5.16.’12.
    + +
      +
    • 加上 pprtypes.cgi 程式、 pprrschr.cgi 程式、 papers.cgi 程式及 pprauthr.cgi 程式,加上 Selima::imacat::List::Papers::Types 類別、 Selima::imacat::List::Papers::Researchers 類別、 Selima::imacat::List::Papers::Papers 類別及 Selima::imacat::List::Papers::Authors 類別,加上 Selima::imacat::Form::Papers::Type 類別、 Selima::imacat::Form::Papers::Researcher 類別、 Selima::imacat::Form::Papers::Paper 類別及 Selima::imacat::Form::Papers::Author 類別,加上 Selima::imacat::Checker::Papers::Type 類別、 Selima::imacat::Checker::Papers::Researcher 類別、 Selima::imacat::Checker::Papers::Paper 類別及 Selima::imacat::Checker::Papers::Author 類別,加上 Selima::imacat::Processor::Papers::Type 類別、 Selima::imacat::Processor::Papers::Researcher 類別、 Selima::imacat::Processor::Papers::Paper 類別及 Selima::imacat::Processor::Papers::Author 類別,以整理閱讀的論文。
    • +
    • 修正 Selima::imacat::HTML 模組的 @ADMIN_SCRIPTS 陣列,加上 pprtypes.cgi 程式、 pprrschr.cgi 程式、 papers.cgi 程式及 pprauthr.cgi 程式。
    • +
    • 修正 Selima::imacat::DataVars 模組,加上 FORM_PAPERS 常數及 FORM_PPRRSCHR 常數;加上匯出 FORM_PAPERS 常數及 FORM_PPRRSCHR 常數;修正 clear() 函式,加上清除 FORM_PAPERS 常數及 FORM_PPRRSCHR 常數。
    • +
    • 修正 Selima::imacat::Config 模組,修正 siteconf() 函式,加上 FORM_PAPERS 常數及 FORM_PPRRSCHR 常數。
    • +
    + +
    + +
    + +
    +
    日期: 5.16.’12.
    + +
      +
    • 修正 Selima::Checker::LinkCatz 類別的 _redir_dellink() 方法,檢查欄位由 sellink 修正為 dellink ;修正 _check_link() 方法的註解, user 修正為 link
    • +
    + +
    + +
    + +
    +
    日期: 5.16.’12.
    + +
      +
    • 修正 Selima::Checker::Link 類別的 _check_url() 方法,欄位空白檢查欄位由 title 修正為 url ,並加上值為 http:// 的檢查。
    • +
    + +
    + +
    + +
    +
    日期: 2.21.’12.
    + +
      +
    • 修正 Selima::Init 模組, check_spambots() 函式的記錄訊息由 block_spambots 修正為 check_spambots ;註解掉 block_spam_robots() 函式、 check_spam() 函式和 checkspam_*() 函式,新的 CAPTCHA 簡單又效果良好,舊的複雜規則已經不用了,註解掉減少系統資源。
    • +
    + +
    + +
    + +
    +
    日期: 2.21.’12.
    + +
      +
    • 修正 Selima::Init 模組,將 block_spambots() 函式更名為 check_spambots() 函式,以和 block_spam() 函式區隔;修正 check_spambots() 函式,檢查 CAPTCHA 欄位前先取得欄位名稱,以便錯誤檢查空欄位;修正 check_spambots() 函式,錯誤訊息字串 + 改正為 . ,以記錄正確的錯誤訊息,修正之前記錄內容都是 0 的錯誤;將 block_spam() 函式移到前面,以和後面已不用的 check_spam() 函式、 checkspam_*() 函式區隔 。
    • +
    • 修正 Selima::Checker 類別的 _check_captcha() 方法,錯誤訊息字串 + 改正為 . ,以記錄正確的錯誤訊息,修正之前記錄內容都是 0 的錯誤 。
    • +
    + +
    + +
    + +
    +
    日期: 2.18.’12.
    + +
      +
    1. 修正 Selima::Init 模組,加上 block_spambots() 函式;修正 initenv() 函式,加上呼叫 block_spambots() 函式。
    2. +
    + +
    + +
    + +
    +
    日期: 2.17.’12.
    + +
      +
    1. 修正 Selima::DataVars 模組,加上 FORM_CAPTCHA 常數。
    2. +
    3. 修正 Selima::Form 類別,加上引入 FORM_CAPTCHA 常數;加上 _html_col_captcha() 方法,以顯示 CAPTCHA 欄位。
    4. +
    5. 修正 Selima::Form::Guestbook::Public 類別的 new() 方法,加上顯示 CAPTCHA 欄位。
    6. +
    7. 修正 Selima::Checker::Guestbook::Public 類別,將 _check_spam() 方法和 _block_spam() 方法移到 Selima::Checker 類別。
    8. +
    9. 修正 Selima::Checker 類別,加上 Selima::Checker::Guestbook::Public 類別移來的 _check_spam() 方法和 _block_spam() 方法;加上引入 FORM_CAPTCHA 常數;加上 _check_captcha() 方法,以檢查 CAPTCHA 欄位;修正 _check_spam() 方法,加上呼叫 _check_captcha() 方法檢查。
    10. +
    11. 修正 Selima::Init 模組的 initenv()函式,暫停執行 block_bad_robots() 方法,改用新的 CAPTCHA 檢查。
    12. +
    13. 修正 Selima::imacat::Form::Garbage::Public 類別,加上引入 FORM_CAPTCHA 常數;加上 _html_col_captcha() 方法,以顯示 CAPTCHA 欄位:修正 new() 方法,加上顯示 CAPTCHA 欄位。
    14. +
    15. gb*.cgi 程式改名回 guestbook.cgi 。採用 CAPTCHA 後,已無必要使用亂數檔名,原先的做法也沒什麼用。
    16. +
    17. 修正 *.sql 資料庫定義,留言簿網址由 gb*.cgi 改為 guestbook.cgi
    18. +
    19. 修正 Selima::*::List::Search 類別的 html_list() 方法,留言簿網址由 gb*.cgi 改為 guestbook.cgi
    20. +
    21. 修正 header*.html 檔,留言簿網址由 gb*.cgi 改為 guestbook.cgi
    22. +
    23. 修正首頁 index*.html 檔,留言簿網址由 gb*.cgi 改為 guestbook.cgi
    24. +
    + +
    + +
    + +
    +
    日期: 6.30.’11.
    + +
      +
    1. 修正 Selima::ListPref 類別的 _check_post() 方法,qw(…) 加上括弧,以符合 Perl 5.14.1 。
    2. +
    3. 修正 Selima::ListPref::AcctReps 類別的 _check_post() 方法,qw(…) 加上括弧,以符合 Perl 5.14.1 。
    4. +
    + +
    + +
    + +
    +
    日期: 1.29.’11.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Ledger 類別的 html_data_download() 方法, list=subj 修正為 list=ldgr
    2. +
    + +
    + +
    + +
    +
    日期: 12.3.’10.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_spammers() 函式,在擋清濤命理研究中心的規則上,加註清濤蔡東楓騙財騙色被抓的事。抓得好!哇哈哈哈哈,太爽了。。
    2. +
    + +
    + +
    + +
    +
    日期: 9.2.’10.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::BlncShet 類別的 fetch 方法,略掉餘額為零的科目。
    2. +
    + +
    + +
    + +
    +
    日期: 9.20.’09.
    + +
      +
    1. 修正 Selima::List 類別的 check_pageno 方法,把 0 加進無效頁碼的條件中。
    2. +
    + +
    + +
    + +
    +
    日期: 6.14.’09.
    + +
      +
    1. 修正 Selima::List::Accounting::Reports::Cash 類別、 Selima::List::Accounting::Reports::Ledger::SummarySelima::List::Accounting::Reports::Cash::Summary 類別,加上 use Selima::LnInfo; ,以解決在非預設語言下無法執行,找不到 ln() 函式的問題。
    2. +
    3. 修正 Selima::List::Accounting::Reports::Cash::Summary 類別的 new() 方法,建立暫用檢視時, extract(cast(month FROM date) AS text) 的錯誤修正為 cast(extract(month FROM date) AS text)
    4. +
    5. 修正 Selima::List::Accounting::Reports::Journal 類別的 fetch() 方法,科目代碼 ACCTSUBJ_INCOME_ACUM 改用 $DBH->quote(ACCTSUBJ_INCOME_ACUM) ,以符合 PostgreSQL 8.3.0 取消自動型別轉換的做法。
    6. +
    7. 修正資料庫定義中的 acctrep_search_list* 檢視,為使檢索結果能依時間由新到舊排序,排序依時間次序由前到後,改由由後到前。
    8. +
    9. 修正 Selima::List::Accounting::Reports::Search 類別,為使檢索結果能依時間由新到舊排序,修正 new() 方法,加上 $self->{"reverse"} = 1; 設定結果由後到先顯示;修正 fetch() 方法,將取得資料反過來排列;加上 html_list() 方法,同一頁面的資料,改以由舊到新排列,以符合帳簿閱讀的習慣。
    10. +
    + +
    + +
    + +
    +
    日期: 6.13.’09.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_masslinks() 函式。
    2. +
    + +
    + +
    + +
    +
    日期: 4.27.’09.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_reqheads() 函式,加上新的擋廣告留言規則;修正原有的擋廣告信規則,以便 CGI 和 mod_perl 模式一體適用。
    2. +
    + +
    + +
    + +
    +
    日期: 4.9.’09.
    + +
      +
    1. 修正 Selima::Init 模組的 checkspam_reqheads() 函式,加上新的擋廣告留言規則。
    2. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 13 | + 14 | + 15 | + 16 | + 17 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0017.html.en.html b/htdocs/imacat/me/changelog/0017.html.en.html new file mode 120000 index 0000000..ebef7cf --- /dev/null +++ b/htdocs/imacat/me/changelog/0017.html.en.html @@ -0,0 +1 @@ +0017.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0017.html.en.xhtml b/htdocs/imacat/me/changelog/0017.html.en.xhtml new file mode 100644 index 0000000..106ce2c --- /dev/null +++ b/htdocs/imacat/me/changelog/0017.html.en.xhtml @@ -0,0 +1,326 @@ + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log Volume 17 + + + + + + + +
    + +
    + + +

    Tavern Change Log Volume 17

    + +
    + +
    + +
    +
    Date: 11.14.’18.
    + +
      +
    • 網站編碼由Big5轉為UTF-8。
    • +
    • 修正網站檔頭為英文,依一般原始碼格式修正,並加上APLv2授權條款。
    • +
    • page path改為breadcrumb。
    • +
    + +
    + +
    + +
    +
    Date: 3.10.’14.
    + +
      +
    • 修正 Selima::List::Accounting::Reports::Search 類別,修正 new() 方法,刪除設定為反向排列;加上 check_pageno() 方法和 html_pagebar() 方法,預設為最後一頁;刪除 html_list() 方法,因為不再以反向排列,故不需再校正資料編號順序。
    • +
    • 修正 Selima::List 類別,把 check_pageno() 方法,移到可覆寫方法區。
    • +
    + +
    + +
    + +
    +
    Date: 3.10.’14.
    + +
      +
    • 修正 acctrep_search_list_* 檢視,日期、序號改以正向排序,以符合正常記帳顯示順序。
    • +
    • 修正 Selima::List::Accounting::Reports::Journal 類別的檔案,編碼改為 UTF-8
    • +
    • 修正 Selima::List::Accounting::Reports::Journal 類別的 new() 方法,加上 reverse ,使頁數反向顯示。
    • +
    • 修正 Selima::List::Accounting::Reports::Journal 類別,刪除 page_param() 方法和 html_pagebar() 方法,還原 2007/10/02 的錯誤。
    • +
    • 修正 Selima::List::Accounting::Reports::Journal 類別,加上 html_list() 方法,校正資料的編號順序。
    • +
    • 修正 Selima::List::Accounting::Reports::Search 類別的檔案,編碼改為 UTF-8
    • +
    • 修正 Selima::List::Accounting::Reports::Search 類別的 fetch() 方法,刪除反向排列結果。
    • +
    • 修正 Selima::List::Accounting::Reports::Search 類別,加上 html_list() 方法,校正資料的編號順序。
    • +
    + +
    + +
    + +
    +
    Date: 2.16.’14.
    + +
      +
    1. 修改 Selima::DBI 類別的 fetch() 方法和 fetchrow_hashref() 方法,用 is_utf8 檢查是不是需要 decode()
    2. +
    3. 修改 Selima::DBI 類別檔案,更新為 UTF-8 編碼。
    4. +
    + +
    + +
    + +
    +
    Date: 7.23.’13.
    + +
      +
    1. 修改 Selima::imacat::Checker::Paper 類別的 _check_year() 方法,將年份下限降為 1930 年。
    2. +
    3. 修改 papers 資料表的 year 欄位規則,將年份下限降為 1930 年。
    4. +
    + +
    + +
    + +
    +
    Date: 6.27.’13.
    + +
      +
    1. 修改 Selima::Format 模組的 myfmtdate() 函式和 myfmttime 函式,原用 localtime 改用 gmtime 。其實應該要把資料庫裏的欄位類型由 timestamp 改為 timestamp with time zone 才對的,不過那樣改茲事體大,現在在趕論文沒有時間測試,就算了,暫時先這樣。
    2. +
    + +
    + +
    + +
    +
    Date: 2.6.’13.
    + +
      +
    1. 修正 Selima::imacat::Checker::Paper 類別的 _check_year() 方法,可用年份擴展到 2013 。應該使用今年的,不過暫時沒力氣去改正。
    2. +
    + +
    + +
    + +
    +
    Date: 1.30.’13.
    + +
      +
    1. 修正 Selima::imacat::Form::Paper 類別的 _html_col_cite() 方法,引用書目加上 h_abbr() ,後恢復原狀。這裏應該加上 h_abbr() 嗎?為什麼一開始沒有加呢?
    2. +
    3. 修正 Selima::Session 模組,目錄不存在時,自動建立目錄。
    4. +
    + +
    + +
    + +
    +
    Date: 12.8.’12.
    + +
      +
    1. 修正 Selima::DBI::db 類別的 cols_ml() 方法,儲存的欄位由 cols_ml 修正為 private_cols_ml ,以符合 Perl 5.16 的新版更新。
    2. +
    + +
    + +
    + +
    +
    Date: 8.30.’12.
    + +
      +
    1. 修正 papers 資料表,刪掉 url 欄位的 UNIQUE
    2. +
    + +
    + +
    + +
    +
    Date: 6.7.’12.
    + +
      +
    1. 修正 Selima::imacat::Checker::Paper 類別的 _check_pages() 方法,允許單頁。
    2. +
    3. 修正 Selima::imacat::Checker::Paper 類別的 _check_month() 方法,允許季節。
    4. +
    5. 修正 Selima::imacat::Checker::Paper 類別的 _check_pub() 方法,允許刊物留白;修正 papers 資料表,允許刊物留白。
    6. +
    7. 修正 Selima::imacat::Checker::Paper 類別的 _check_url() 方法,不檢查網址連不連得上。
    8. +
    + +
    + +
    + +
    +
    Date: 6.7.’12.
    + +
      +
    1. 修正 Selima::imacat::Checker::Tag 類別的 _check_title 方法的註解。
    2. +
    3. 修正 papers.cgi 程式,最後更新檢查加上 papers 資料表;修正 fetch_curitem() 函式,加上取得作者的縮寫。
    4. +
    5. 修正 Selima::imacat::Checker::Researcher 類別,加上引用 Selima::ShortCut 模組。
    6. +
    7. 修正 Selima::imacat::Form::Paper 類別,修正 new() 方法,加上顯示 cite 欄位;加上 _html_col_cite() 方法,顯示 APA 引用格式。
    8. +
    9. 修正 Selima::imacat::Items 模組的 abbreviate_name() 方法。
    10. +
    11. 修正 papers 資料表,加上 month 欄位;修正 Selima::imacat::List::Papers 類別,加上 month 欄位;修正 Selima::imacat::Form::Paper 類別, new() 方法加上 month 欄位,加上 _html_col_month() 方法;修正 Selima::imacat::Checker::Paper 類別,加上 _check_month() 方法;修正 Selima::imacat::Processor::Paper 類別的 _save_cols() 方法,加上 month 欄位;修正 papers.cgi 程式的 check_post() 函式,加上檢查 month 欄位。
    12. +
    + +
    + +
    + +
    +
    Date: 6.3.’12.
    + +
      +
    1. 變更 Selima::DataVars 模組的 FORM_CAPTCHA 值。
    2. +
    + +
    + +
    + +
    +
    Date: 5.20.’12.
    + +
      +
    • 修正 Selima::Form 類別,加上引用 Selima::ChkFunc 模組,以便在 _html_coltmpl_tags() 方法使用 check_sn_in() 函式;修正 _html_coltmpl_tags() 方法,去掉原來註解掉使用 check_sn_in() 函式判斷的地方。
    • +
    • 修正 Selima::Form 類別的 _html_coltmpl_tags() 方法,加上 $table 參數,以便 check_sn_in() 函式檢查;修正 Selima::imacat::Form::Paper 類別的 _html_col_authors() 方法和 _html_col_tags 方法,加上傳入資料表名稱。
    • +
    • 修正 Selima::Form 類別的 _html_coltmpl_tags() 方法,現有資料改用一行顯示。
    • +
    • 修正 Selima::Form 類別,修正 _html_coltmpl_radio() 方法,加上原來沒寫的, $onelineclass 名稱的判斷和插入;修正 _html_coltmpl_tags() 方法,加上 $oneline 參數的處理;修正 Selima::imacat::Form::Paper 類別的 _html_col_authors() 方法和 _html_col_tags 方法,加上 $oneline 參數。
    • +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 13 | + 14 | + 15 | + 16 | + 17 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0017.html.zh-cn.html b/htdocs/imacat/me/changelog/0017.html.zh-cn.html new file mode 120000 index 0000000..7bb441f --- /dev/null +++ b/htdocs/imacat/me/changelog/0017.html.zh-cn.html @@ -0,0 +1 @@ +0017.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0017.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/0017.html.zh-cn.xhtml new file mode 100644 index 0000000..2f6b3ef --- /dev/null +++ b/htdocs/imacat/me/changelog/0017.html.zh-cn.xhtml @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 卷十七 + + + + + + + +
    + +
    + + +

    旅舍更新日志 卷十七

    + +
    + +
    + +
    +
    日期: 11.14.’18.
    + +
      +
    • 网站编码由Big5转为UTF-8。
    • +
    • 修正网站档头为英文,依一般原始码格式修正,并加上APLv2授权条款。
    • +
    • page path改为breadcrumb。
    • +
    + +
    + +
    + +
    +
    日期: 3.10.’14.
    + +
      +
    • 修正 Selima::List::Accounting::Reports::Search 类别,修正 new() 方法,删除设定为反向排列;加上 check_pageno() 方法和 html_pagebar() 方法,预设为最后一页;删除 html_list() 方法,因为不再以反向排列,故不需再校正资料编号顺序。
    • +
    • 修正 Selima::List 类别,把 check_pageno() 方法,移到可覆写方法区。
    • +
    + +
    + +
    + +
    +
    日期: 3.10.’14.
    + +
      +
    • 修正 acctrep_search_list_* 检视,日期、序号改以正向排序,以符合正常记帐显示顺序。
    • +
    • 修正 Selima::List::Accounting::Reports::Journal 类别的档案,编码改为 UTF-8
    • +
    • 修正 Selima::List::Accounting::Reports::Journal 类别的 new() 方法,加上 reverse ,使页数反向显示。
    • +
    • 修正 Selima::List::Accounting::Reports::Journal 类别,删除 page_param() 方法和 html_pagebar() 方法,还原 2007/10/02 的错误。
    • +
    • 修正 Selima::List::Accounting::Reports::Journal 类别,加上 html_list() 方法,校正资料的编号顺序。
    • +
    • 修正 Selima::List::Accounting::Reports::Search 类别的档案,编码改为 UTF-8
    • +
    • 修正 Selima::List::Accounting::Reports::Search 类别的 fetch() 方法,删除反向排列结果。
    • +
    • 修正 Selima::List::Accounting::Reports::Search 类别,加上 html_list() 方法,校正资料的编号顺序。
    • +
    + +
    + +
    + +
    +
    日期: 2.16.’14.
    + +
      +
    1. 修改 Selima::DBI 类别的 fetch() 方法和 fetchrow_hashref() 方法,用 is_utf8 检查是不是需要 decode()
    2. +
    3. 修改 Selima::DBI 类别档案,更新为 UTF-8 编码。
    4. +
    + +
    + +
    + +
    +
    日期: 7.23.’13.
    + +
      +
    1. 修改 Selima::imacat::Checker::Paper 类别的 _check_year() 方法,将年份下限降为 1930 年。
    2. +
    3. 修改 papers 资料表的 year 栏位规则,将年份下限降为 1930 年。
    4. +
    + +
    + +
    + +
    +
    日期: 6.27.’13.
    + +
      +
    1. 修改 Selima::Format 模组的 myfmtdate() 函式和 myfmttime 函式,原用 localtime 改用 gmtime 。其实应该要把资料库里的栏位类型由 timestamp 改为 timestamp with time zone 才对的,不过那样改兹事体大,现在在赶论文没有时间测试,就算了,暂时先这样。
    2. +
    + +
    + +
    + +
    +
    日期: 2.6.’13.
    + +
      +
    1. 修正 Selima::imacat::Checker::Paper 类别的 _check_year() 方法,可用年份扩展到 2013 。应该使用今年的,不过暂时没力气去改正。
    2. +
    + +
    + +
    + +
    +
    日期: 1.30.’13.
    + +
      +
    1. 修正 Selima::imacat::Form::Paper 类别的 _html_col_cite() 方法,引用书目加上 h_abbr() ,后恢复原状。这里应该加上 h_abbr() 吗?为什么一开始没有加呢?
    2. +
    3. 修正 Selima::Session 模组,目录不存在时,自动建立目录。
    4. +
    + +
    + +
    + +
    +
    日期: 12.8.’12.
    + +
      +
    1. 修正 Selima::DBI::db 类别的 cols_ml() 方法,储存的栏位由 cols_ml 修正为 private_cols_ml ,以符合 Perl 5.16 的新版更新。
    2. +
    + +
    + +
    + +
    +
    日期: 8.30.’12.
    + +
      +
    1. 修正 papers 资料表,删掉 url 栏位的 UNIQUE
    2. +
    + +
    + +
    + +
    +
    日期: 6.7.’12.
    + +
      +
    1. 修正 Selima::imacat::Checker::Paper 类别的 _check_pages() 方法,允许单页。
    2. +
    3. 修正 Selima::imacat::Checker::Paper 类别的 _check_month() 方法,允许季节。
    4. +
    5. 修正 Selima::imacat::Checker::Paper 类别的 _check_pub() 方法,允许刊物留白;修正 papers 资料表,允许刊物留白。
    6. +
    7. 修正 Selima::imacat::Checker::Paper 类别的 _check_url() 方法,不检查网址连不连得上。
    8. +
    + +
    + +
    + +
    +
    日期: 6.7.’12.
    + +
      +
    1. 修正 Selima::imacat::Checker::Tag 类别的 _check_title 方法的注解。
    2. +
    3. 修正 papers.cgi 程式,最后更新检查加上 papers 资料表;修正 fetch_curitem() 函式,加上取得作者的缩写。
    4. +
    5. 修正 Selima::imacat::Checker::Researcher 类别,加上引用 Selima::ShortCut 模组。
    6. +
    7. 修正 Selima::imacat::Form::Paper 类别,修正 new() 方法,加上显示 cite 栏位;加上 _html_col_cite() 方法,显示 APA 引用格式。
    8. +
    9. 修正 Selima::imacat::Items 模组的 abbreviate_name() 方法。
    10. +
    11. 修正 papers 资料表,加上 month 栏位;修正 Selima::imacat::List::Papers 类别,加上 month 栏位;修正 Selima::imacat::Form::Paper 类别, new() 方法加上 month 栏位,加上 _html_col_month() 方法;修正 Selima::imacat::Checker::Paper 类别,加上 _check_month() 方法;修正 Selima::imacat::Processor::Paper 类别的 _save_cols() 方法,加上 month 栏位;修正 papers.cgi 程式的 check_post() 函式,加上检查 month 栏位。
    12. +
    + +
    + +
    + +
    +
    日期: 6.3.’12.
    + +
      +
    1. 变更 Selima::DataVars 模组的 FORM_CAPTCHA 值。
    2. +
    + +
    + +
    + +
    +
    日期: 5.20.’12.
    + +
      +
    • 修正 Selima::Form 类别,加上引用 Selima::ChkFunc 模组,以便在 _html_coltmpl_tags() 方法使用 check_sn_in() 函式;修正 _html_coltmpl_tags() 方法,去掉原来注解掉使用 check_sn_in() 函式判断的地方。
    • +
    • 修正 Selima::Form 类别的 _html_coltmpl_tags() 方法,加上 $table 参数,以便 check_sn_in() 函式检查;修正 Selima::imacat::Form::Paper 类别的 _html_col_authors() 方法和 _html_col_tags 方法,加上传入资料表名称。
    • +
    • 修正 Selima::Form 类别的 _html_coltmpl_tags() 方法,现有资料改用一行显示。
    • +
    • 修正 Selima::Form 类别,修正 _html_coltmpl_radio() 方法,加上原来没写的, $onelineclass 名称的判断和插入;修正 _html_coltmpl_tags() 方法,加上 $oneline 参数的处理;修正 Selima::imacat::Form::Paper 类别的 _html_col_authors() 方法和 _html_col_tags 方法,加上 $oneline 参数。
    • +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 13 | + 14 | + 15 | + 16 | + 17 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/0017.html.zh-tw.html b/htdocs/imacat/me/changelog/0017.html.zh-tw.html new file mode 120000 index 0000000..0a30e86 --- /dev/null +++ b/htdocs/imacat/me/changelog/0017.html.zh-tw.html @@ -0,0 +1 @@ +0017.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/0017.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/0017.html.zh-tw.xhtml new file mode 100644 index 0000000..e098b4d --- /dev/null +++ b/htdocs/imacat/me/changelog/0017.html.zh-tw.xhtml @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 卷十七 + + + + + + + +
    + +
    + + +

    旅舍更新日誌 卷十七

    + +
    + +
    + +
    +
    日期: 11.14.’18.
    + +
      +
    • 網站編碼由Big5轉為UTF-8。
    • +
    • 修正網站檔頭為英文,依一般原始碼格式修正,並加上APLv2授權條款。
    • +
    • page path改為breadcrumb。
    • +
    + +
    + +
    + +
    +
    日期: 3.10.’14.
    + +
      +
    • 修正 Selima::List::Accounting::Reports::Search 類別,修正 new() 方法,刪除設定為反向排列;加上 check_pageno() 方法和 html_pagebar() 方法,預設為最後一頁;刪除 html_list() 方法,因為不再以反向排列,故不需再校正資料編號順序。
    • +
    • 修正 Selima::List 類別,把 check_pageno() 方法,移到可覆寫方法區。
    • +
    + +
    + +
    + +
    +
    日期: 3.10.’14.
    + +
      +
    • 修正 acctrep_search_list_* 檢視,日期、序號改以正向排序,以符合正常記帳顯示順序。
    • +
    • 修正 Selima::List::Accounting::Reports::Journal 類別的檔案,編碼改為 UTF-8
    • +
    • 修正 Selima::List::Accounting::Reports::Journal 類別的 new() 方法,加上 reverse ,使頁數反向顯示。
    • +
    • 修正 Selima::List::Accounting::Reports::Journal 類別,刪除 page_param() 方法和 html_pagebar() 方法,還原 2007/10/02 的錯誤。
    • +
    • 修正 Selima::List::Accounting::Reports::Journal 類別,加上 html_list() 方法,校正資料的編號順序。
    • +
    • 修正 Selima::List::Accounting::Reports::Search 類別的檔案,編碼改為 UTF-8
    • +
    • 修正 Selima::List::Accounting::Reports::Search 類別的 fetch() 方法,刪除反向排列結果。
    • +
    • 修正 Selima::List::Accounting::Reports::Search 類別,加上 html_list() 方法,校正資料的編號順序。
    • +
    + +
    + +
    + +
    +
    日期: 2.16.’14.
    + +
      +
    1. 修改 Selima::DBI 類別的 fetch() 方法和 fetchrow_hashref() 方法,用 is_utf8 檢查是不是需要 decode()
    2. +
    3. 修改 Selima::DBI 類別檔案,更新為 UTF-8 編碼。
    4. +
    + +
    + +
    + +
    +
    日期: 7.23.’13.
    + +
      +
    1. 修改 Selima::imacat::Checker::Paper 類別的 _check_year() 方法,將年份下限降為 1930 年。
    2. +
    3. 修改 papers 資料表的 year 欄位規則,將年份下限降為 1930 年。
    4. +
    + +
    + +
    + +
    +
    日期: 6.27.’13.
    + +
      +
    1. 修改 Selima::Format 模組的 myfmtdate() 函式和 myfmttime 函式,原用 localtime 改用 gmtime 。其實應該要把資料庫裏的欄位類型由 timestamp 改為 timestamp with time zone 才對的,不過那樣改茲事體大,現在在趕論文沒有時間測試,就算了,暫時先這樣。
    2. +
    + +
    + +
    + +
    +
    日期: 2.6.’13.
    + +
      +
    1. 修正 Selima::imacat::Checker::Paper 類別的 _check_year() 方法,可用年份擴展到 2013 。應該使用今年的,不過暫時沒力氣去改正。
    2. +
    + +
    + +
    + +
    +
    日期: 1.30.’13.
    + +
      +
    1. 修正 Selima::imacat::Form::Paper 類別的 _html_col_cite() 方法,引用書目加上 h_abbr() ,後恢復原狀。這裏應該加上 h_abbr() 嗎?為什麼一開始沒有加呢?
    2. +
    3. 修正 Selima::Session 模組,目錄不存在時,自動建立目錄。
    4. +
    + +
    + +
    + +
    +
    日期: 12.8.’12.
    + +
      +
    1. 修正 Selima::DBI::db 類別的 cols_ml() 方法,儲存的欄位由 cols_ml 修正為 private_cols_ml ,以符合 Perl 5.16 的新版更新。
    2. +
    + +
    + +
    + +
    +
    日期: 8.30.’12.
    + +
      +
    1. 修正 papers 資料表,刪掉 url 欄位的 UNIQUE
    2. +
    + +
    + +
    + +
    +
    日期: 6.7.’12.
    + +
      +
    1. 修正 Selima::imacat::Checker::Paper 類別的 _check_pages() 方法,允許單頁。
    2. +
    3. 修正 Selima::imacat::Checker::Paper 類別的 _check_month() 方法,允許季節。
    4. +
    5. 修正 Selima::imacat::Checker::Paper 類別的 _check_pub() 方法,允許刊物留白;修正 papers 資料表,允許刊物留白。
    6. +
    7. 修正 Selima::imacat::Checker::Paper 類別的 _check_url() 方法,不檢查網址連不連得上。
    8. +
    + +
    + +
    + +
    +
    日期: 6.7.’12.
    + +
      +
    1. 修正 Selima::imacat::Checker::Tag 類別的 _check_title 方法的註解。
    2. +
    3. 修正 papers.cgi 程式,最後更新檢查加上 papers 資料表;修正 fetch_curitem() 函式,加上取得作者的縮寫。
    4. +
    5. 修正 Selima::imacat::Checker::Researcher 類別,加上引用 Selima::ShortCut 模組。
    6. +
    7. 修正 Selima::imacat::Form::Paper 類別,修正 new() 方法,加上顯示 cite 欄位;加上 _html_col_cite() 方法,顯示 APA 引用格式。
    8. +
    9. 修正 Selima::imacat::Items 模組的 abbreviate_name() 方法。
    10. +
    11. 修正 papers 資料表,加上 month 欄位;修正 Selima::imacat::List::Papers 類別,加上 month 欄位;修正 Selima::imacat::Form::Paper 類別, new() 方法加上 month 欄位,加上 _html_col_month() 方法;修正 Selima::imacat::Checker::Paper 類別,加上 _check_month() 方法;修正 Selima::imacat::Processor::Paper 類別的 _save_cols() 方法,加上 month 欄位;修正 papers.cgi 程式的 check_post() 函式,加上檢查 month 欄位。
    12. +
    + +
    + +
    + +
    +
    日期: 6.3.’12.
    + +
      +
    1. 變更 Selima::DataVars 模組的 FORM_CAPTCHA 值。
    2. +
    + +
    + +
    + +
    +
    日期: 5.20.’12.
    + +
      +
    • 修正 Selima::Form 類別,加上引用 Selima::ChkFunc 模組,以便在 _html_coltmpl_tags() 方法使用 check_sn_in() 函式;修正 _html_coltmpl_tags() 方法,去掉原來註解掉使用 check_sn_in() 函式判斷的地方。
    • +
    • 修正 Selima::Form 類別的 _html_coltmpl_tags() 方法,加上 $table 參數,以便 check_sn_in() 函式檢查;修正 Selima::imacat::Form::Paper 類別的 _html_col_authors() 方法和 _html_col_tags 方法,加上傳入資料表名稱。
    • +
    • 修正 Selima::Form 類別的 _html_coltmpl_tags() 方法,現有資料改用一行顯示。
    • +
    • 修正 Selima::Form 類別,修正 _html_coltmpl_radio() 方法,加上原來沒寫的, $onelineclass 名稱的判斷和插入;修正 _html_coltmpl_tags() 方法,加上 $oneline 參數的處理;修正 Selima::imacat::Form::Paper 類別的 _html_col_authors() 方法和 _html_col_tags 方法,加上 $oneline 參數。
    • +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 13 | + 14 | + 15 | + 16 | + 17 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/index.html.en.html b/htdocs/imacat/me/changelog/index.html.en.html new file mode 120000 index 0000000..08fc4ee --- /dev/null +++ b/htdocs/imacat/me/changelog/index.html.en.html @@ -0,0 +1 @@ +index.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/index.html.en.xhtml b/htdocs/imacat/me/changelog/index.html.en.xhtml new file mode 100644 index 0000000..8c88163 --- /dev/null +++ b/htdocs/imacat/me/changelog/index.html.en.xhtml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Change Log + + + + + + + +
    + +
    + + +

    Tavern Change Log

    + + + +

    Index

    + +
      +
    1. Tavern Change Log Volume 17

      +
      5.20.’12. - 11.13.’18.
    2. + +
    3. Tavern Change Log Volume 16

      +
      4.8.’09. - 5.19.’12.
    4. + +
    5. Tavern Change Log Volume 15

      +
      10.3.’07. - 2.17.’09.
    6. + +
    7. Tavern Change Log Volume 14

      +
      9.27.’07. - 10.3.’07.
    8. + +
    9. Tavern Change Log Volume 13

      +
      9.23.’07. - 9.27.’07.
    10. + +
    11. Tavern Change Log Volume 12

      +
      8.23.’07. - 9.22.’07.
    12. + +
    13. Tavern Change Log Volume 11

      +
      3.12.’07. - 8.22.’07.
    14. + +
    15. Tavern Change Log Volume 10

      +
      11.17.’06. - 3.11.’07.
    16. + +
    17. Tavern Change Log Volume 9

      +
      5.4.’06. - 11.16.’06.
    18. + +
    19. Tavern Change Log Volume 8

      +
      4.26.’06. - 5.2.’06.
    20. + +
    21. Tavern Change Log Volume 7

      +
      4.22.’06. - 4.25.’06.
    22. + +
    23. Tavern Change Log Volume 6

      +
      4.12.’06. - 4.20.’06.
    24. + +
    25. Tavern Change Log Volume 5

      +
      4.1.’06. - 4.11.’06.
    26. + +
    27. Tavern Change Log Volume 4

      +
      10.4.’05. - 3.31.’06.
    28. + +
    29. Tavern Change Log Volume 3

      +
      4.9.’03. - 10.2.’05.
    30. + +
    31. Tavern Change Log Volume 2

      +
      11.4.’00. - 3.30.’03.
    32. + +
    33. Tavern Change Log Volume 1

      +
      5.3.’98. - 7.2.’00.
    34. + +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/index.html.zh-cn.html b/htdocs/imacat/me/changelog/index.html.zh-cn.html new file mode 120000 index 0000000..5ee9c39 --- /dev/null +++ b/htdocs/imacat/me/changelog/index.html.zh-cn.html @@ -0,0 +1 @@ +index.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/index.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/index.html.zh-cn.xhtml new file mode 100644 index 0000000..8d91c40 --- /dev/null +++ b/htdocs/imacat/me/changelog/index.html.zh-cn.xhtml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日志 + + + + + + + +
    + +
    + + +

    旅舍更新日志

    + + + +

    目录

    + +
      +
    1. 旅舍更新日志 卷十七

      +
      5.20.’12. - 11.13.’18.
    2. + +
    3. 旅舍更新日志 卷十六

      +
      4.8.’09. - 5.19.’12.
    4. + +
    5. 旅舍更新日志 卷十五

      +
      10.3.’07. - 2.17.’09.
    6. + +
    7. 旅舍更新日志 卷十四

      +
      9.27.’07. - 10.3.’07.
    8. + +
    9. 旅舍更新日志 卷十三

      +
      9.23.’07. - 9.27.’07.
    10. + +
    11. 旅舍更新日志 卷十二

      +
      8.23.’07. - 9.22.’07.
    12. + +
    13. 旅舍更新日志 卷十一

      +
      3.12.’07. - 8.22.’07.
    14. + +
    15. 旅舍更新日志 卷十

      +
      11.17.’06. - 3.11.’07.
    16. + +
    17. 旅舍更新日志 卷九

      +
      5.4.’06. - 11.16.’06.
    18. + +
    19. 旅舍更新日志 卷八

      +
      4.26.’06. - 5.2.’06.
    20. + +
    21. 旅舍更新日志 卷七

      +
      4.22.’06. - 4.25.’06.
    22. + +
    23. 旅舍更新日志 卷六

      +
      4.12.’06. - 4.20.’06.
    24. + +
    25. 旅舍更新日志 卷五

      +
      4.1.’06. - 4.11.’06.
    26. + +
    27. 旅舍更新日志 卷四

      +
      10.4.’05. - 3.31.’06.
    28. + +
    29. 旅舍更新日志 卷三

      +
      4.9.’03. - 10.2.’05.
    30. + +
    31. 旅舍更新日志 卷二

      +
      11.4.’00. - 3.30.’03.
    32. + +
    33. 旅舍更新日志 卷一

      +
      5.3.’98. - 7.2.’00.
    34. + +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/index.html.zh-tw.html b/htdocs/imacat/me/changelog/index.html.zh-tw.html new file mode 120000 index 0000000..6c1b76e --- /dev/null +++ b/htdocs/imacat/me/changelog/index.html.zh-tw.html @@ -0,0 +1 @@ +index.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/index.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/index.html.zh-tw.xhtml new file mode 100644 index 0000000..d4ab59a --- /dev/null +++ b/htdocs/imacat/me/changelog/index.html.zh-tw.xhtml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + +旅舍更新日誌 + + + + + + + +
    + +
    + + +

    旅舍更新日誌

    + + + +

    目錄

    + +
      +
    1. 旅舍更新日誌 卷十七

      +
      5.20.’12. - 11.13.’18.
    2. + +
    3. 旅舍更新日誌 卷十六

      +
      4.8.’09. - 5.19.’12.
    4. + +
    5. 旅舍更新日誌 卷十五

      +
      10.3.’07. - 2.17.’09.
    6. + +
    7. 旅舍更新日誌 卷十四

      +
      9.27.’07. - 10.3.’07.
    8. + +
    9. 旅舍更新日誌 卷十三

      +
      9.23.’07. - 9.27.’07.
    10. + +
    11. 旅舍更新日誌 卷十二

      +
      8.23.’07. - 9.22.’07.
    12. + +
    13. 旅舍更新日誌 卷十一

      +
      3.12.’07. - 8.22.’07.
    14. + +
    15. 旅舍更新日誌 卷十

      +
      11.17.’06. - 3.11.’07.
    16. + +
    17. 旅舍更新日誌 卷九

      +
      5.4.’06. - 11.16.’06.
    18. + +
    19. 旅舍更新日誌 卷八

      +
      4.26.’06. - 5.2.’06.
    20. + +
    21. 旅舍更新日誌 卷七

      +
      4.22.’06. - 4.25.’06.
    22. + +
    23. 旅舍更新日誌 卷六

      +
      4.12.’06. - 4.20.’06.
    24. + +
    25. 旅舍更新日誌 卷五

      +
      4.1.’06. - 4.11.’06.
    26. + +
    27. 旅舍更新日誌 卷四

      +
      10.4.’05. - 3.31.’06.
    28. + +
    29. 旅舍更新日誌 卷三

      +
      4.9.’03. - 10.2.’05.
    30. + +
    31. 旅舍更新日誌 卷二

      +
      11.4.’00. - 3.30.’03.
    32. + +
    33. 旅舍更新日誌 卷一

      +
      5.3.’98. - 7.2.’00.
    34. + +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/me/changelog/latest.html.en.html b/htdocs/imacat/me/changelog/latest.html.en.html new file mode 120000 index 0000000..d6f911c --- /dev/null +++ b/htdocs/imacat/me/changelog/latest.html.en.html @@ -0,0 +1 @@ +latest.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/latest.html.en.xhtml b/htdocs/imacat/me/changelog/latest.html.en.xhtml new file mode 120000 index 0000000..ebef7cf --- /dev/null +++ b/htdocs/imacat/me/changelog/latest.html.en.xhtml @@ -0,0 +1 @@ +0017.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/latest.html.zh-cn.html b/htdocs/imacat/me/changelog/latest.html.zh-cn.html new file mode 120000 index 0000000..7be458a --- /dev/null +++ b/htdocs/imacat/me/changelog/latest.html.zh-cn.html @@ -0,0 +1 @@ +latest.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/latest.html.zh-cn.xhtml b/htdocs/imacat/me/changelog/latest.html.zh-cn.xhtml new file mode 120000 index 0000000..7bb441f --- /dev/null +++ b/htdocs/imacat/me/changelog/latest.html.zh-cn.xhtml @@ -0,0 +1 @@ +0017.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/latest.html.zh-tw.html b/htdocs/imacat/me/changelog/latest.html.zh-tw.html new file mode 120000 index 0000000..f642bdf --- /dev/null +++ b/htdocs/imacat/me/changelog/latest.html.zh-tw.html @@ -0,0 +1 @@ +latest.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/changelog/latest.html.zh-tw.xhtml b/htdocs/imacat/me/changelog/latest.html.zh-tw.xhtml new file mode 120000 index 0000000..0a30e86 --- /dev/null +++ b/htdocs/imacat/me/changelog/latest.html.zh-tw.xhtml @@ -0,0 +1 @@ +0017.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0001.html.en.html b/htdocs/imacat/me/diary/0001.html.en.html new file mode 120000 index 0000000..57710c1 --- /dev/null +++ b/htdocs/imacat/me/diary/0001.html.en.html @@ -0,0 +1 @@ +0001.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0001.html.en.xhtml b/htdocs/imacat/me/diary/0001.html.en.xhtml new file mode 100644 index 0000000..8f0cd61 --- /dev/null +++ b/htdocs/imacat/me/diary/0001.html.en.xhtml @@ -0,0 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 1 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 1

    + +
    + +
    + +
    +
    4.23.’98. 0:00am.
    + +
    +It’s April 23, ’98 today,
    +morn than one month after my last diary.
    +I was -so- busy for the past one month.
    +I started to rebuild Tavern with many new graphics:
    +My own icon has done.
    +Tavern is no more stable and symmetrical
    +with many new unbalanced spacing.
    +The 24×48 black cat was the starting
    +that brought the consequence graphics
    +and the consistent style.
    +There’re still many not done,
    +I’m working now.
    +
    +I don’t know why,
    +but news seems to become the main part of this tavern.
    +That is not what I supposed to do.
    +I supposed to make a homepage of literature and discourse,
    +but it still became a homepage of news at last.
    +It is too hard for a Dalu Society member to make a homepage of literature, I think.
    +There’re about 10 people watching the tavern now.
    +That makes the pressure.
    +I have to be running forward and forward,
    +gathering new informations, making them on-line.
    +It’s very tiring, but it’s worthy.
    +I feel I’ve really done something important.
    +Someone is watching me.
    +
    +Another largest change is in the
    +“Women’s Net Resource” session.
    +I’ve put in many female and lesbian websites which I was thinking.
    +I also put in many websites of organizations of social movements.
    +Some of them are not favored by me,
    +but there’re still posibilities for cooperation.
    +But not for those like Democratic and Prograssive Party,
    +State Building Party, State Building Associations
    +that I would never make cooperation with them.
    +
    +Hey! I found I forgot to put in local feminism websites.
    +But some of them (just like TAPWER) are so disgusting!
    +
    +I’ve reinstalled Windows 95 once tonignt.
    +The night I faxed the news inform
    +for the activities of protest against high-tuition fee inside NTU,
    +God dammed MS-Word suddenly downed.
    +I stayed all night finding the cause,
    +reinstalling Windows 95 once and once,
    +till 5:00am the first fax was made.
    +
    +I’ve got another case these days
    +to be a translator in an international conference
    +for Solidarity Front of Wemon Workers.
    +But I can’t speak too much here.
    +I have to translate articles and write English mails.
    +I also planned to translate some articles from GAATW.
    +It’s so busy!
    +
    +There’s a parade protesting against nuclear power,
    +but I haven’t put in the News session yet.
    +
    +I hate the HEF (Humanistic Education Foundation).
    +Although they stood against High-Tuition fee policy too,
    +they promoted for the liberalization of private colleges.
    +What’s the difference between that and those economics scholars?
    +They always say, let the education run itself by marketing.
    +But where is the market?
    +The supply decides the prize arbitrarily,
    +and the demanding student can just pay.
    +Where is the regulation between demand and supply?
    +The main point is that:
    +Can Education be treated as goods selling in the free market?
    +Education is the important conduct to promote social streaming,
    +and social streaming is the most important thing of social justice.
    +Shouldn’t that be protected by the state?
    +
    +I was planning for an article to fight the HEF,
    +but not done yet, too.
    +
    +So many things undone, but so less time.
    +
    +Wishing to make this place bigger.
    +Wishing to make a E-Mail Newspaper of social movements.
    +But all these require money.
    +It’s a little hard that I’m doing all by myself now.
    +And I have no job, no income.
    +I started to consider seriously about raising the fund.
    +I talked with Kathie a couple of days ago
    +about a long-time support network for student movement.
    +But that needs money, too.
    +Tavern has too strong my style,
    +not a good place to turned into a support network directly.
    +If I decide to raise the fund,
    +I’ll have to give up my personal style in this tavern.
    +Or should I make a whole new student support network?
    +
    +One of my friend in TNT called me tonight.
    +They’ve got their precise URL.
    +That’s so releasing!
    +I shall have a fixed income from now on.
    +That’s the agreement between me and TNT for the writing and maintaining of TNT’s homepage.
    +Not too much, but it works.
    +
    +Would you like to contribute to me? ^_*'
    +
    +Ah, I have my personal BBS board at TKU ERA BBS now:
    +telnet 140.13.196.103, paperrose board,
    +or http://era.stat.tku.edu.tw:9999/boards/paperrose.
    +Please come visit me! ^_*' +
    + +
    + +
    + +
    +
    3.16.’98. 0:00am.
    + +
    +Today is Mar.16.’98, exactly 10 days after I rented this place in GeoCities.
    +After several days of decadence without writing a word, I’m back.
    +
    +I thought it is easy to write a short self-introduction.
    +That was before I wrote this page.
    +Finally I found its difficulty — I had NO idea what to write.
    +I was forced to face my inside emptiness and my past lacerations.
    +I deserted myself in the world of computer games
    +Without knowing what I want…
    +
    +Yesterday I was tired.  I picked up ULTIMA VII again.
    +While watching the staff introduction alone with the moving soundtrack,
    +I was reminded the passions forgotten for so long…
    +I was so deeply in loved with the ULTIMA series before,
    +Believing it is the best game in the world.
    +There would never be a better one.
    +Accompanied with its moving soundtrack,
    +I was so impressed not by its cool graphic effect,
    +But the humanism attempt by the author, Richard Garriott.
    +From ULTIMA IV,
    +ULTIMA series had got rid of the tradition of Role-Playing Games (RPG) — to fight drakes and the big bad king,
    +Attempting to put philosophy and social questions inside,
    +Such as racism, collectivism, fascism… etc.
    +As Garriott said, he was not writing a game.
    +He was creating a world named “Britannia”
    +With its own self-satisfied economic and value system.
    +Then he laid the game screenplay into it.
    +
    +I was so moved by such an attempt at that time…
    +“I’m creating a world, not just a game.”
    +…to create a world…
    +How long have I forgotten such passions?
    +From the moment I decided to rebel against the paternity tradition in Dalu Society,
    +For several years in Movements and in Net
    +I’d lost all the helping hands and fought all alone till now.
    +Now I have many younger schoolmates in Dalu Society.
    +I tell them time and time: Just do what you want.
    +Don’t be restricted by the tradition of this society.
    +I shall always be your company.
    +But I’ve never noticed I’m gradually exhausted from within.
    +When I’m saying I shall always be your company,
    +I’ve never have company of my own…
    +
    +So I decided to restart from here,
    +To create a brand new world. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 1 | + 2 | + 3 | + 4 | + 5 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0001.html.zh-cn.html b/htdocs/imacat/me/diary/0001.html.zh-cn.html new file mode 120000 index 0000000..2940024 --- /dev/null +++ b/htdocs/imacat/me/diary/0001.html.zh-cn.html @@ -0,0 +1 @@ +0001.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0001.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0001.html.zh-cn.xhtml new file mode 100644 index 0000000..49f06d7 --- /dev/null +++ b/htdocs/imacat/me/diary/0001.html.zh-cn.xhtml @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一

    + +
    + +
    + +
    +
    4.23.’98. 0:00am.
    + +
    +今天是 87 年 4 月 23 日,
    +离我上一篇日记已有一个多月。
    +这一个多月期间,好忙。
    +开始大幅度更动这整个旅舍。
    +最大的变动是加进了许多图,
    +把自己的小 icon 也画出来了,
    +旅舍的空间配置也不再四平八稳左右对称,
    +有了不小的空间感变化。
    +画出了那只 24×48 的小黑猫是重心,
    +把后来所有图形的基本调性都带了出来,
    +风格也开始有了一致感。
    +虽然还有很多图还没有画出来,
    +可是仍然在持续努力当中。
    +请多多包涵。
    +
    +不知道为什么,
    +旅舍竟然变成了新闻性的网页。
    +我原先的预设不是这个样子的。
    +原先希望做成一个文艺性与论述性的综合网页,
    +不知道为什么,
    +做著做著就变成了新闻性的网页了。
    +毕竟大陆社出身的要做文艺网页还是有点困难。
    +现在每天约有十个人在看著旅舍,
    +有点压力,
    +好像变得骑虎难下,不得不向前一直跑了。
    +得要不断地去搜集新的资讯,并把它们上网,
    +虽然很累,可是却很充实。
    +觉得自己真的做了什么,有人在看。
    +
    +另一个最大的改变则是在女性网路资源的部份,
    +放进了我一直想加进去的更多女运网,
    +还有社运团体的网站。
    +虽然有些社运团体我不大喜欢,
    +可是毕竟还是有在运动上结盟的希望和可能的。
    +至於民进党、建国党、建国会
    +这种死也不愿和他们在运动上结盟的
    +我就不放了。
    +
    +突然发现好像忘了放了国内的妇运团体网站了,
    +可我现在实在对妇女新知和女权会很杜烂。
    +
    +今晚刚刚重灌了一次 Windows 95 。
    +为反高学费台大活动传真新闻稿的那晚,
    + Word 突然就这样不动了,
    +整晚没睡在找原因。
    +后来一直重灌 Windows 95 ,
    +直到早上五点才发出第一份新闻稿。
    +
    +这两天又接下了另一个工作,
    +帮女工团结生产线当一场国际会议的翻译。
    +不过内容还不能说。
    +这两天要翻好几篇文章,又要写些英文信的,
    +我还计划要把 GAATW 的几篇文章翻译出来的,
    +又是变得好忙。
    +
    +星期日有一场反核大游行,
    +可是我还没有去把它弄上新闻版面。
    +
    +讨厌的人本,
    +表面上支持反高学费,
    +却又说了个「私校自由化」来扯大学生的后腿。
    +这不就和有钱的高希钧说的一样了吗?
    +大人总是说要让大学教育由市场供需决定,
    +却没有想过到底市场在哪里?
    +供给者任意决定价位,
    +需求面的大学生只能被予取予求,
    +哪里有供需的调节了?
    +更重要的是,
    +教育可以被当成商品来看待,
    +放在自由市场运作吗?
    +教育是社会流动的重要管道,
    +社会流动是保障社会公平最重要的事,
    +不是应由国家来保障吗?
    +
    +计划要写篇文章去和人本吵架的,
    +结果也还没写出来。
    +
    +要做的事好多,拥有的时间好少。
    +
    +想把这个地方弄大,
    +希望做出一份社运电子报来。
    +可是那要钱。
    +我现在是一个人在做,
    +做得有点辛苦。
    +而且我没有收入,没有工作。
    +开始认真在想募款的事。
    +前几天和 Kathie 聊天,
    +聊到成立一个长期的学运支持网路,
    +可是那也要钱来支撑。
    +现在的旅舍有我自己很强烈的个人风格,
    +不大适合直接做成学运支持网路。
    +一但要去募款
    +势必要放弃很多旅舍里的个人风格。
    +那究竟是放弃现在的旅舍,
    +还是另外重做一个新的学运网呢?
    +这也是我所犹豫的。
    +
    +今晚矜怀打电话来,
    + TNT 的网址终於确定了。
    +真好。
    +这样以后就可以每个月固定有一笔小收入了。
    +这是我帮 TNT 写网页并维护网页的小小约定。
    +虽然不多,可是不无小补。
    +
    +还是有人要认捐我吗? ^_*'
    +
    +对了,我也有自己的个人 BBS 板了,
    +在淡江网路世代站,
    +telnet 140.13.196.103 , paperrose 纸做的玫瑰板,
    +或 http://era.stat.tku.edu.tw:9999/boards/paperrose
    +大家要去灌水喔! ^_*' +
    + +
    + +
    + +
    +
    3.16.’98. 0:00am.
    + +
    +今天是 87 年 3 月 16 日,离我在 GeoCities 租下这个地方刚好十天。
    +荒废了几天未动笔写 HomePage 以后,我回来了。
    +
    +原本以为写自我介绍是件例行性的轻松工作,
    +直到写到这一页才发现它的困难――我不知道要写些什么。
    +我被迫重新面对自己的旧伤痕和我的空虚,
    +於是我把 HomePage 进度停了下来,把自己放逐在电脑游戏的世界里,
    +找不到我想要的是什么…
    +
    +昨天玩到倦了,把 创世纪七代 ULTIMA Ⅶ 翻出来重玩,
    +看著作者群介绍,听著那悠扬动人的配乐,
    +突然想起一些遗忘了好久的心情…
    +曾经如此地深爱著 ULTIMA 系列,
    +坚定地以为那就是我心目中最好的 RPG 角色扮演游戏,
    +再也找不到更好的了。
    +在悠扬动人的音乐中,
    +令我向往的不是它炫目的动画效果,
    +而是作者 Richard Garriott 在游戏中强烈的人文企图。
    +从 创世纪四代 ULTIMA IV 开始,
    + ULTIMA 系列摆脱 RPG 传统杀龙、杀魔王的模式,
    +企图在游戏里放入更深的哲学、社会问题,
    +如:种族主义、集体主义、法西斯… 等。
    + Richard Garriott 说,他已不再是在写一个游戏,
    +他在创造一个世界 Britannia ,
    +在 Britannia 里有完整自足的经济体系和价值体系,
    +他只是把游戏剧情融入 Britannia 大陆而已。
    +
    +曾经如此强烈地被这样的企图和理想所感动,
    +“I’m creating a world, not just a game.”
    +…to creat a world…
    +我对这样的感动已经遗忘了多久了呢?
    +这几年来在学运、社运界,在网路上,
    +从决定在大陆社打垮父权传统开始,
    +一直都是一个人奋战到现在,没有学长姊可以依靠。
    +到现在学妹一大票,个个都对生命充满了活力和新的想像。
    +我每次都跟她们说,想做什么就尽管放手去做,
    +不要被社团传统限制住,学长有意见我给你们靠,
    +可是却忘记了我的内在自我早已渐渐地枯干了…
    +当我说著,有什么事我给你们靠的时候,
    +我却没有一个人可以靠…
    +
    +於是我决定回到这里重新开始,
    +创造一个世界 +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 1 | + 2 | + 3 | + 4 | + 5 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0001.html.zh-tw.html b/htdocs/imacat/me/diary/0001.html.zh-tw.html new file mode 120000 index 0000000..2fca0e8 --- /dev/null +++ b/htdocs/imacat/me/diary/0001.html.zh-tw.html @@ -0,0 +1 @@ +0001.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0001.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0001.html.zh-tw.xhtml new file mode 100644 index 0000000..7e6a7c9 --- /dev/null +++ b/htdocs/imacat/me/diary/0001.html.zh-tw.xhtml @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一

    + +
    + +
    + +
    +
    4.23.’98. 0:00am.
    + +
    +今天是 87 年 4 月 23 日,
    +離我上一篇日記已有一個多月。
    +這一個多月期間,好忙。
    +開始大幅度更動這整個旅舍。
    +最大的變動是加進了許多圖,
    +把自己的小 icon 也畫出來了,
    +旅舍的空間配置也不再四平八穩左右對稱,
    +有了不小的空間感變化。
    +畫出了那隻 24×48 的小黑貓是重心,
    +把後來所有圖形的基本調性都帶了出來,
    +風格也開始有了一致感。
    +雖然還有很多圖還沒有畫出來,
    +可是仍然在持續努力當中。
    +請多多包涵。
    +
    +不知道為什麼,
    +旅舍竟然變成了新聞性的網頁。
    +我原先的預設不是這個樣子的。
    +原先希望做成一個文藝性與論述性的綜合網頁,
    +不知道為什麼,
    +做著做著就變成了新聞性的網頁了。
    +畢竟大陸社出身的要做文藝網頁還是有點困難。
    +現在每天約有十個人在看著旅舍,
    +有點壓力,
    +好像變得騎虎難下,不得不向前一直跑了。
    +得要不斷地去蒐集新的資訊,並把它們上網,
    +雖然很累,可是卻很充實。
    +覺得自己真的做了什麼,有人在看。
    +
    +另一個最大的改變則是在女性網路資源的部份,
    +放進了我一直想加進去的更多女運網,
    +還有社運團體的網站。
    +雖然有些社運團體我不大喜歡,
    +可是畢竟還是有在運動上結盟的希望和可能的。
    +至於民進黨、建國黨、建國會
    +這種死也不願和他們在運動上結盟的
    +我就不放了。
    +
    +突然發現好像忘了放了國內的婦運團體網站了,
    +可我現在實在對婦女新知和女權會很杜爛。
    +
    +今晚剛剛重灌了一次 Windows 95 。
    +為反高學費臺大活動傳真新聞稿的那晚,
    + Word 突然就這樣不動了,
    +整晚沒睡在找原因。
    +後來一直重灌 Windows 95 ,
    +直到早上五點才發出第一份新聞稿。
    +
    +這兩天又接下了另一個工作,
    +幫女工團結生產線當一場國際會議的翻譯。
    +不過內容還不能說。
    +這兩天要翻好幾篇文章,又要寫些英文信的,
    +我還計劃要把 GAATW 的幾篇文章翻譯出來的,
    +又是變得好忙。
    +
    +星期日有一場反核大遊行,
    +可是我還沒有去把它弄上新聞版面。
    +
    +討厭的人本,
    +表面上支持反高學費,
    +卻又說了個「私校自由化」來扯大學生的後腿。
    +這不就和有錢的高希鈞說的一樣了嗎?
    +大人總是說要讓大學教育由市場供需決定,
    +卻沒有想過到底市場在哪裡?
    +供給者任意決定價位,
    +需求面的大學生只能被予取予求,
    +哪裡有供需的調節了?
    +更重要的是,
    +教育可以被當成商品來看待,
    +放在自由市場運作嗎?
    +教育是社會流動的重要管道,
    +社會流動是保障社會公平最重要的事,
    +不是應由國家來保障嗎?
    +
    +計劃要寫篇文章去和人本吵架的,
    +結果也還沒寫出來。
    +
    +要做的事好多,擁有的時間好少。
    +
    +想把這個地方弄大,
    +希望做出一份社運電子報來。
    +可是那要錢。
    +我現在是一個人在做,
    +做得有點辛苦。
    +而且我沒有收入,沒有工作。
    +開始認真在想募款的事。
    +前幾天和 Kathie 聊天,
    +聊到成立一個長期的學運支持網路,
    +可是那也要錢來支撐。
    +現在的旅舍有我自己很強烈的個人風格,
    +不大適合直接做成學運支持網路。
    +一但要去募款
    +勢必要放棄很多旅舍裡的個人風格。
    +那究竟是放棄現在的旅舍,
    +還是另外重做一個新的學運網呢?
    +這也是我所猶豫的。
    +
    +今晚矜懷打電話來,
    + TNT 的網址終於確定了。
    +真好。
    +這樣以後就可以每個月固定有一筆小收入了。
    +這是我幫 TNT 寫網頁並維護網頁的小小約定。
    +雖然不多,可是不無小補。
    +
    +還是有人要認捐我嗎? ^_*'
    +
    +對了,我也有自己的個人 BBS 板了,
    +在淡江網路世代站,
    +telnet 140.13.196.103 , paperrose 紙做的玫瑰板,
    +或 http://era.stat.tku.edu.tw:9999/boards/paperrose
    +大家要去灌水喔! ^_*' +
    + +
    + +
    + +
    +
    3.16.’98. 0:00am.
    + +
    +今天是 87 年 3 月 16 日,離我在 GeoCities 租下這個地方剛好十天。
    +荒廢了幾天未動筆寫 HomePage 以後,我回來了。
    +
    +原本以為寫自我介紹是件例行性的輕鬆工作,
    +直到寫到這一頁才發現它的困難──我不知道要寫些什麼。
    +我被迫重新面對自己的舊傷痕和我的空虛,
    +於是我把 HomePage 進度停了下來,把自己放逐在電腦遊戲的世界裡,
    +找不到我想要的是什麼…
    +
    +昨天玩到倦了,把 創世紀七代 ULTIMA Ⅶ 翻出來重玩,
    +看著作者群介紹,聽著那悠揚動人的配樂,
    +突然想起一些遺忘了好久的心情…
    +曾經如此地深愛著 ULTIMA 系列,
    +堅定地以為那就是我心目中最好的 RPG 角色扮演遊戲,
    +再也找不到更好的了。
    +在悠揚動人的音樂中,
    +令我嚮往的不是它炫目的動畫效果,
    +而是作者 Richard Garriott 在遊戲中強烈的人文企圖。
    +從 創世紀四代 ULTIMA IV 開始,
    + ULTIMA 系列擺脫 RPG 傳統殺龍、殺魔王的模式,
    +企圖在遊戲裡放入更深的哲學、社會問題,
    +如:種族主義、集體主義、法西斯… 等。
    + Richard Garriott 說,他已不再是在寫一個遊戲,
    +他在創造一個世界 Britannia ,
    +在 Britannia 裡有完整自足的經濟體系和價值體系,
    +他只是把遊戲劇情融入 Britannia 大陸而已。
    +
    +曾經如此強烈地被這樣的企圖和理想所感動,
    +“I’m creating a world, not just a game.”
    +…to creat a world…
    +我對這樣的感動已經遺忘了多久了呢?
    +這幾年來在學運、社運界,在網路上,
    +從決定在大陸社打垮父權傳統開始,
    +一直都是一個人奮戰到現在,沒有學長姊可以依靠。
    +到現在學妹一大票,個個都對生命充滿了活力和新的想像。
    +我每次都跟她們說,想做什麼就儘管放手去做,
    +不要被社團傳統限制住,學長有意見我給妳們靠,
    +可是卻忘記了我的內在自我早已漸漸地枯乾了…
    +當我說著,有什麼事我給妳們靠的時候,
    +我卻沒有一個人可以靠…
    +
    +於是我決定回到這裡重新開始,
    +創造一個世界 +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 1 | + 2 | + 3 | + 4 | + 5 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0002.html.en.html b/htdocs/imacat/me/diary/0002.html.en.html new file mode 120000 index 0000000..4e8a442 --- /dev/null +++ b/htdocs/imacat/me/diary/0002.html.en.html @@ -0,0 +1 @@ +0002.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0002.html.en.xhtml b/htdocs/imacat/me/diary/0002.html.en.xhtml new file mode 100644 index 0000000..73ab079 --- /dev/null +++ b/htdocs/imacat/me/diary/0002.html.en.xhtml @@ -0,0 +1,443 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 2 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 2

    + +
    + +
    + +
    +
    2.14.’00. 0:00am.
    + +
    +It’s 2.14.’00, Saint Valentine’s Day.
    +The sky is clear.
    +It looks like that I write Tavern Diary
    +only when Tavern reversion.
    +
    +Anyway, the sky is clear.
    +Although a little cloudy,
    +a little tired,
    +a little sleepy… ah…
    +
    +I keep working for about 2 months.
    +From before Chinese New Year,
    +till after Chinese New Year,
    +to save unix databases
    +and to write ASP pages of Tavern and WOV.
    +I was tired out,
    +wishing to catch a nice sleep…
    +
    +My life is full of exciting things these times.
    +WOV website has finally reopened,
    +with subscribers’ list completedly saved,
    +which means WOV will continue publishing soon.
    +Tavern has reopened, too.
    +Mandy and I have sign a contract for a new column with YAM.
    +The new column should be named as “Woman’s Speech”
    +with NT$1 per word.
    +The argument with ramm will finally be dissolved, too.
    +Sysop should charge in a few days.
    +
    +Furthormore, the total number of WOV’s subscribers
    +broke the number of 3,000.
    +Plus the millennium and the Chinese New Year.
    +What a gift, isn’t it? ^_*'
    +
    +It’s about time to start writing.
    +I owe YAM 2 articles.
    +And the reopen noticification of WOV.
    +There should also be something new
    +for the New Tavern, too…
    +
    +So I’d better start working by now. ^_*' +
    + +
    + +
    + +
    +
    8.8.’99. 0:00am.
    + +
    +October 8th., 1999. Sunny.
    +Tavern is in the 4th reversion process.
    +
    +It’s been almost one year since last Tavern Diary.
    +While I read my last diary, I found it very funny.
    +I’ve wrote “I’d completely re-decorated this Tavern,”
    +while in fact I stopped in the middle of it.
    +I left it desolated in a mess for almost a year.
    +
    +The reason is that:
    +I found IE and Nescape’s page analysing differ largely,
    +not to say all other browsers.
    +There’s no way to make a “Best View With AnyBrowser” homepage.
    +After moving to SCCID this problem is partially solved.
    +With CGI, I can send different HTML for different browser.
    +Although it’s not “Best View”, but it’s acceptable.
    +
    +Other stuffs are no way to make them, too.
    +
    +I’m an translator in sun movie channel.
    +Though I’ll resign, and keep unemployed.
    +But the “internet magazine” in my former diary has come true:
    +“Woman’s Voice” E-Mail News has gone 4 periods,
    +with more and more feedback.
    +We’ll work with YAM.  Even SeedNet is asking.
    +Not to say over 1,000 of increasing subscribers.
    +If I have money,
    +I want to make an independant host and publishing.
    +
    +That’s not trivial bullshit.
    +That’s a wonderful big thing.
    +I’m advancing towards my dream:
    +To devote my self in feminism / women libration.
    +
    +Yeah, It’s wonderful.
    +I’m the Board Manager of NTU Palm BBS Les Board now.
    +I’d never thought of that one day I’ll have the chance
    +to really do something for the lesbian society.
    +But now it’s true.  I’m working on it.
    +I’m working on a virtual internet lesbian community.
    +I see so many young faces that’re strong and powerful,
    +so many young faces that’re are full of hope and faith,
    +who’ll difinitely become the next generation of
    +feminists and lesbian activists.
    +
    +I’ve learned the most important thing in a compaign:
    +To organize the crowd, and to develope their class idealogy.
    +But not to fight with pen and sword.
    +Develope People’s Power, Let people fight for themself.
    +“People’s Power”.
    +That’s what was said by Corazon Cojuangco Aquino,
    +the former president of Phillipines.
    +which is the practice of “Empower” theory.
    +
    +That’s all.
    +I wish this reversion not stop in the middle of it.
    +I wish this time I can find a better job and earn better salary.
    +I wish I can be happier.
    +Women Libration never ends. +
    + +
    + +
    + +
    +
    11.8.’98. 0:00am.
    + +
    +Nov. 8th, 1998.  Sunny.
    +I’d completely re-decorated this Tavern.
    +
    +There’re lots to talk about.
    +I’ve fount the newly-released
    +HTML 4.0 recommendationson on the
    +internet about 2 months ago.
    +3 weeks ago, after I resigned from
    +the previous job as an accounter,
    +I started reading this document.
    +I downloaded and read CSS1 standard
    +from the internet later.
    +Then I started rewriting Tavern
    +completely.
    +I’d met lots of difficulties trying,
    +and understood quite a lot about
    +CSS1 and HTML 4.0.
    +This results what you see now.
    +
    +You probally would not like to hear of
    +all these trivial and boring stuffs.
    +Good.  I don’t want to talk, either.
    +
    +But, what else can I say?
    +I’m unemployed,
    +The deposit can save me
    +only till the end of this month.
    +I even don’t know why I rewrote
    +this homepage.
    +Homepage desiner?
    +Several days ago I went interview
    +for a homepage desiner .
    +They should inform me today,
    +but they hadn’t yet.
    +It must be over.
    +Maybe I should actively
    +look for clients myself.
    +But people are asking JavaScript now.
    +I have to spend 2 more weeks
    +learning JavaScript.
    +Do I have 2 more weeks now?
    +
    +Though it’s so tiring,
    +but there’re still good things.
    +Do you know there’re about 30
    +people passing by Tavern per day?
    +Even at the time I were busy
    +without updating for 3 months,
    +there’re still about 20 people
    +passing by per day.
    +Consider the fact that there’re
    +millions of non-commercial personal
    +homepages on the internet!
    +Not many people can make it!
    +
    +It’s true that there’s too much
    +information flowing on the internet.
    +It’s true that the internet is
    +gradually bought by those capitalist.
    +It’s also true that besides those big
    +capitalists’ websites like China Times,
    +FTV, or those who offer special
    +service like software downloading,
    +most personal or commercial websites
    +are rarely visited.
    +If these are all true,
    +what will a personal non-commercial
    +website with more than 20 people
    +visited per day means?
    +Is it possible to advancedly develop
    +this place to an internet magazine
    +operating independently?
    +
    +This is just a dream.
    +A magazine needs sponsers,
    +but GeoCities where this homepage
    +resides does not allowed to.
    +To rent an independence vertual
    +machine needs quite a lot money.
    +It’s another problem if there’s anyone
    +wanting to sponser a homepage that
    +only 700-800 visited per month.
    +Sponser banners needs JavaScript,
    +and that’s a problem, too. :~~~~
    +
    +But it is still quite a dream!
    +Earlier today while I was reorganizing
    +old Tavern Diaries,
    +I saw the first Diary on 3.8.’98
    +that mentioned about those dreamings
    +while I was building Tavern.
    +The Tavern started from a dream, and
    +it shall go along with all these dreams.
    +I wish these dreams will come true! ^_*' +
    + +
    + +
    + +
    +
    10.12.’98. 0:00am.
    + +
    +It’s October 12, ’98 today.
    +
    +Being with this dizzying head
    +in the brand new midnight
    +with whole new spacing and timing,
    +I’m writing this diary now
    +in a completely different place.
    +The white wall has changed,
    +The desk and chair has changed,
    +The view of the window has changed,
    +and so do the life.
    +
    +The OS has updated to Windows 98.
    +I’m using Netscape now.
    +I’ve learned to compose a computer.
    +There’s a new girl now beside me:
    +What has really changed on me
    +during these days?
    +I don’t know.
    +After 2 months of an accounter,
    +everything has started over again.
    +I had thought that I shall
    +gain something for these busy days.
    +But I seemed to be wrong.
    +
    +Oh, yes!
    +I’ve learned accounting at last.
    +
    +Why I have to go though
    +all of these shits?
    +It’s SO ridiculous!
    +Getting alone with gangs of
    +nonsense nationalists,
    +seeing the evening news show be planned
    +not until that very afternoon.
    +Actually they should not be blamed.
    +The time pressure is too heavy
    +for them to read and think.
    +But that’s the most critical
    +underground radio station in Taiwan!
    +You can endure no reading
    +and making poor programs,
    +but not me!
    +I want to keep reading, thinking, writing.
    +I want to keep myself progressing!
    +
    +So I quit!
    +I was thinking that maybe I will
    +change my opinion toward nationalists,
    +but I was wrong.
    +Everything has started over again:
    +UNEMPLOYMENT.
    +It seemed to be a conservative ending.
    +Some things seemed to be changed
    +or not.
    +
    +I’m back again.
    +At least I try to be myself,
    +and make myself better,
    +until the next advanture. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 1 | + 2 | + 3 | + 4 | + 5 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0002.html.zh-cn.html b/htdocs/imacat/me/diary/0002.html.zh-cn.html new file mode 120000 index 0000000..f6628e3 --- /dev/null +++ b/htdocs/imacat/me/diary/0002.html.zh-cn.html @@ -0,0 +1 @@ +0002.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0002.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0002.html.zh-cn.xhtml new file mode 100644 index 0000000..cea3f8d --- /dev/null +++ b/htdocs/imacat/me/diary/0002.html.zh-cn.xhtml @@ -0,0 +1,411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷二

    + +
    + +
    + +
    +
    2.14.’00. 0:00am.
    + +
    +今天是 2000 年 2 月 14 日,情人节。
    +天气晴。
    +我好像只有在旅舍改版时才会写旅舍日记…
    +
    +Anyway,天气晴,
    +虽然有一点点云。
    +眼皮有一点点沉重,
    +有一点点疲倦,
    +有一点点想睡…呵…
    +
    +连著赶工赶了一两个月,
    +从过年前赶到过年后,
    +硬是把 UNIX 的资料库救回来,
    +硬是把旅舍和女声的 ASP 程式写出来,
    +耗掉我太多力气了。
    +好想好好地睡一觉,呵…
    +
    +这一阵子,其实是充实的。
    +《女声》终於复站了,
    +订户名单完全救回来了,
    +要继续出刊了。
    +旅舍也终於复站了。
    +我和小招和蕃薯藤签了专栏稿约,
    +专栏名称叫「女话」,一个字一块钱。
    +和黑羊的问题也终将告一段落,
    +站方应该会在最近裁决。
    +
    +更何况,《女声》的读者数破三千了,
    +再加上刚刚过去的千禧年,还有新年,
    +可喜可贺,可喜可贺。 ^_*'
    +
    +我也差不多开始要继续动笔了。
    +这个月还欠蕃薯藤两篇稿子要赶,
    +还有女声的复刊词,
    +旅舍复站了,也要有些新东东的…
    +
    +加油加油罗~ ^_*' +
    + +
    + +
    + +
    +
    8.8.’99. 0:00am.
    + +
    +88 年 8 月 8 日,晴。
    +旅舍第四次改版,还在进行中。
    +
    +离上一篇旅舍日记将近一年,
    +回头翻翻上一篇旅舍日记,觉得好可笑。
    +我写「我把旅舍完全重新装修」,
    +其实做到一半就停手了。
    +留下施工中的一团乱,就这样荒废了半年多。
    +
    +上次改版到一半中断的原因是:
    +我发现 IE 和 Netscape 排版差很多,
    +更不用说其它的浏览器。
    +要做一个可用任何浏览器浏览的网页简直是天方夜谭。
    +搬到南方后,部份问题解决了。
    +用 CGI 的结果,可以针对不同的浏览器送出不同的页面,
    +虽然无法都达到最佳效果,但亦可以接受了。
    +
    +除此以外的事,也像天方夜谭一样。
    +
    +我去了 sun movie 春晖电影台当翻译,
    +不过就要辞了,继续失业。
    +但前一篇日记提到的「网路杂志」已经成真:
    +《女声》电子报已经发行到第四期,
    +回响越来越大,
    +不但要与蕃薯藤合作,
    +连 SeedNet 也来打探消息。
    +更不用说一千多个订户,而且持续增加中。
    +要是存够钱,甚至可能做独立的主机,
    +独立发行。
    +
    +这不是琐碎的无聊事,
    +这是很棒很棒的大事。
    +我在朝我的梦想前进:
    +做一辈子的女性主义∕妇运。
    +
    +真的很棒。
    +我现在是椰林拉子天堂板的板主。
    +我从没想过有一天真的会有机会为拉子们做点什么。
    +但这一切成真了,
    +我在组织一个虚拟网路拉子社区。
    +我身边有好多好多双坚强有力的双手,
    +好多双自信闪亮的眼神。
    +她们会是我们下一代的女性主义者,
    +下一代的妇运领袖。
    +
    +我学到了做妇运∕社运最重要的事:
    +组织群众,培养阶级意识,
    +而不是去笔战。
    +要培养人民的力量,让人民自己去反抗。
    +「人民的力量」这是菲律宾前总统柯拉蓉说的,
    +也是 EMPOWER 原则的实践。
    +
    +就这样。
    +希望这次改版不会半途而废,
    +希望这次找到更好的工作,赚更多的钱,
    +希望我会快乐些,
    +希望妇运的路走得更长些。 +
    + +
    + +
    + +
    +
    11.8.’98. 0:00am.
    + +
    +87 年 11 月 8 日。天气晴。
    +我把旅舍完全重新装修。
    +
    +想说的话有很多。
    +大约两个月前,
    +我在网路上发现了
    +新公布的 HTML 4.0 标准。
    +三个星期前,我辞掉会计的工作后,
    +开始读这份英文文件。
    +后来我再上网把 CSS1 的标准传下来看。
    +然后就开始全面重写整个旅舍的网页。
    +在重写的尝试中碰到了许多的困难,
    +也更了解了 CSS1 和 HTML 4.0 的精神。
    +现在你们看到的这些,
    +就是成果。
    +
    +你大概不想听这些琐碎的无聊事。
    +我也不想谈。
    +
    +可是,我还有什么可以说的呢?
    +我无业,
    +存款只够用到这个月底。
    +我不知道重写这些网页要做什么?
    +网页设计?
    +前几天应徵一个网页设计师的工作,
    +今天该给我消息的,可是还没有,
    +大概是没有希望了。
    +又或者,
    +我应该主动积极去寻找客户的。
    +可是现在要写网页的,
    +大家都嘛要会写 JavaScript 。
    +JavaScript…
    +又要再花两个星期的时间学。
    +我有两个星期的时间吗?
    +
    +好累,
    +可是还是有很多很高兴的事。
    +旅舍一天有三十几个人在看耶!
    +即使前一阵子忙,
    +完全没有更新的期间,
    +一天还是有二十个人在看。
    +放眼整个网际网路上
    +成千上万的非商业个人网页,
    +有几个有这种实力? ^_*'
    +
    +网路资讯太多是现实;
    +网路逐渐被资本家吃掉是现实;
    +除了少数大资本家如中时、民视,
    +或提供软体下传等特殊服务的网站外,
    +大多数个人或商业网站,
    +每年看网的人只有个位数,
    +网站门可罗雀、乏人问津是事实。
    +如果这些都是事实,
    +那一个个人、非商业网页
    +每个月有二、三十个人看,
    +意味著什么?
    +是不是有可能将这个地方
    +进一步发展下去,
    +成为一本网路杂志,独立经营呢?
    +
    +这大概只是梦想吧!
    +一份独立经营的杂志需要卖广告生存,
    +这个网页所在的免费网站
    +GeoCities 不允许卖广告,
    +而租一个独立的虚拟主机要钱;
    +一份每个月只有七八百人看的网页,
    +广告商愿意不愿意支持也是问题;
    +要卖广告的话要先学会写 JavaScript ,
    +这当然也是问题… :~~~~~
    +
    +可是这仍然是我的一个梦想吧!
    +今天在整理旅舍日记的时候,
    +看到了 3.8.’98 第一篇旅舍日记,
    +里面提到了建造这个旅舍时的梦想。
    +以梦想开始,也以梦想走下去,
    +希望梦想有一天会成真! ^_*' +
    + +
    + +
    + +
    +
    10.12.’98. 0:00am.
    + +
    +今天是 87 年 10 月 12 日。
    +
    +醉倒在新的深夜中。
    +全新的深夜,全新的空间、时间。
    +再一次写网路上的日记,
    +我身在完全不同的地方。
    +不一样的墙,不一样的桌椅,
    +不一样的巷景,不一样的生活。
    +
    +也许是作业系统换了 Windows 98 ;
    +也许是我装了 Netscape ;
    +也许是我学会了怎么组电脑;
    +也许是身边多了一个人。
    +我到底真正改变了什么?
    +我不知道。
    +当了两个月的会计,又辞职,
    +一切又回到了起点。
    +以为两个月忙下来总有点收获的,
    +到头来却又发现,
    +对这个世界的看法又回到最初。
    +
    +对了,
    +我还学会了会计。
    +
    +我为什么要去走这一遭?
    +我不知道。想起来就好荒谬。
    +成天和一群无聊又无知的
    +民族主义者混在一起,
    +看著听著下午才准备
    +当天晚上的新闻评论节目。
    +其实也怪不得它们,
    +工作压力压得它们根本没有时间思考读书。
    +而这竟然是台湾最有水准的地下电台!
    +你们可以不读书,
    +可以持续做烂的节目下去,
    +我可不要。
    +我想念书,我想思考,我想写作,
    +我想继续充实自己。
    +
    +於是我辞职了。
    +原以为这一趟下来可以改变我一些
    +对民族主义者的看法,
    +可是我错了。
    +一切又回到原点:
    +失业。
    +这样的结局似乎过於保守了。
    +好像有改变一些什么,
    +却又没有。
    +
    +我又回来了。
    +至少,我又想开始做我自己,
    +让我自己更好,
    +直到下次冒险出发之前。 +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 1 | + 2 | + 3 | + 4 | + 5 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0002.html.zh-tw.html b/htdocs/imacat/me/diary/0002.html.zh-tw.html new file mode 120000 index 0000000..66ffd54 --- /dev/null +++ b/htdocs/imacat/me/diary/0002.html.zh-tw.html @@ -0,0 +1 @@ +0002.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0002.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0002.html.zh-tw.xhtml new file mode 100644 index 0000000..63a7855 --- /dev/null +++ b/htdocs/imacat/me/diary/0002.html.zh-tw.xhtml @@ -0,0 +1,411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷二

    + +
    + +
    + +
    +
    2.14.’00. 0:00am.
    + +
    +今天是 2000 年 2 月 14 日,情人節。
    +天氣晴。
    +我好像只有在旅舍改版時才會寫旅舍日記…
    +
    +Anyway,天氣晴,
    +雖然有一點點雲。
    +眼皮有一點點沉重,
    +有一點點疲倦,
    +有一點點想睡…呵…
    +
    +連著趕工趕了一兩個月,
    +從過年前趕到過年後,
    +硬是把 UNIX 的資料庫救回來,
    +硬是把旅舍和女聲的 ASP 程式寫出來,
    +耗掉我太多力氣了。
    +好想好好地睡一覺,呵…
    +
    +這一陣子,其實是充實的。
    +《女聲》終於復站了,
    +訂戶名單完全救回來了,
    +要繼續出刊了。
    +旅舍也終於復站了。
    +我和小招和蕃薯藤簽了專欄稿約,
    +專欄名稱叫「女話」,一個字一塊錢。
    +和黑羊的問題也終將告一段落,
    +站方應該會在最近裁決。
    +
    +更何況,《女聲》的讀者數破三千了,
    +再加上剛剛過去的千禧年,還有新年,
    +可喜可賀,可喜可賀。 ^_*'
    +
    +我也差不多開始要繼續動筆了。
    +這個月還欠蕃薯藤兩篇稿子要趕,
    +還有女聲的復刊詞,
    +旅舍復站了,也要有些新東東的…
    +
    +加油加油囉~ ^_*' +
    + +
    + +
    + +
    +
    8.8.’99. 0:00am.
    + +
    +88 年 8 月 8 日,晴。
    +旅舍第四次改版,還在進行中。
    +
    +離上一篇旅舍日記將近一年,
    +回頭翻翻上一篇旅舍日記,覺得好可笑。
    +我寫「我把旅舍完全重新裝修」,
    +其實做到一半就停手了。
    +留下施工中的一團亂,就這樣荒廢了半年多。
    +
    +上次改版到一半中斷的原因是:
    +我發現 IE 和 Netscape 排版差很多,
    +更不用說其它的瀏覽器。
    +要做一個可用任何瀏覽器瀏覽的網頁簡直是天方夜譚。
    +搬到南方後,部份問題解決了。
    +用 CGI 的結果,可以針對不同的瀏覽器送出不同的頁面,
    +雖然無法都達到最佳效果,但亦可以接受了。
    +
    +除此以外的事,也像天方夜譚一樣。
    +
    +我去了 sun movie 春暉電影台當翻譯,
    +不過就要辭了,繼續失業。
    +但前一篇日記提到的「網路雜誌」已經成真:
    +《女聲》電子報已經發行到第四期,
    +迴響越來越大,
    +不但要與蕃薯藤合作,
    +連 SeedNet 也來打探消息。
    +更不用說一千多個訂戶,而且持續增加中。
    +要是存夠錢,甚至可能做獨立的主機,
    +獨立發行。
    +
    +這不是瑣碎的無聊事,
    +這是很棒很棒的大事。
    +我在朝我的夢想前進:
    +做一輩子的女性主義∕婦運。
    +
    +真的很棒。
    +我現在是椰林拉子天堂板的板主。
    +我從沒想過有一天真的會有機會為拉子們做點什麼。
    +但這一切成真了,
    +我在組織一個虛擬網路拉子社區。
    +我身邊有好多好多雙堅強有力的雙手,
    +好多雙自信閃亮的眼神。
    +她們會是我們下一代的女性主義者,
    +下一代的婦運領袖。
    +
    +我學到了做婦運∕社運最重要的事:
    +組織群眾,培養階級意識,
    +而不是去筆戰。
    +要培養人民的力量,讓人民自己去反抗。
    +「人民的力量」這是菲律賓前總統柯拉蓉說的,
    +也是 EMPOWER 原則的實踐。
    +
    +就這樣。
    +希望這次改版不會半途而廢,
    +希望這次找到更好的工作,賺更多的錢,
    +希望我會快樂些,
    +希望婦運的路走得更長些。 +
    + +
    + +
    + +
    +
    11.8.’98. 0:00am.
    + +
    +87 年 11 月 8 日。天氣晴。
    +我把旅舍完全重新裝修。
    +
    +想說的話有很多。
    +大約兩個月前,
    +我在網路上發現了
    +新公佈的 HTML 4.0 標準。
    +三個星期前,我辭掉會計的工作後,
    +開始讀這份英文文件。
    +後來我再上網把 CSS1 的標準傳下來看。
    +然後就開始全面重寫整個旅舍的網頁。
    +在重寫的嚐試中碰到了許多的困難,
    +也更了解了 CSS1 和 HTML 4.0 的精神。
    +現在妳們看到的這些,
    +就是成果。
    +
    +妳大概不想聽這些瑣碎的無聊事。
    +我也不想談。
    +
    +可是,我還有什麼可以說的呢?
    +我無業,
    +存款只夠用到這個月底。
    +我不知道重寫這些網頁要做什麼?
    +網頁設計?
    +前幾天應徵一個網頁設計師的工作,
    +今天該給我消息的,可是還沒有,
    +大概是沒有希望了。
    +又或者,
    +我應該主動積極去尋找客戶的。
    +可是現在要寫網頁的,
    +大家都嘛要會寫 JavaScript 。
    +JavaScript…
    +又要再花兩個星期的時間學。
    +我有兩個星期的時間嗎?
    +
    +好累,
    +可是還是有很多很高興的事。
    +旅舍一天有三十幾個人在看耶!
    +即使前一陣子忙,
    +完全沒有更新的期間,
    +一天還是有二十個人在看。
    +放眼整個網際網路上
    +成千上萬的非商業個人網頁,
    +有幾個有這種實力? ^_*'
    +
    +網路資訊太多是現實;
    +網路逐漸被資本家吃掉是現實;
    +除了少數大資本家如中時、民視,
    +或提供軟體下傳等特殊服務的網站外,
    +大多數個人或商業網站,
    +每年看網的人只有個位數,
    +網站門可羅雀、乏人問津是事實。
    +如果這些都是事實,
    +那一個個人、非商業網頁
    +每個月有二、三十個人看,
    +意味著什麼?
    +是不是有可能將這個地方
    +進一步發展下去,
    +成為一本網路雜誌,獨立經營呢?
    +
    +這大概只是夢想吧!
    +一份獨立經營的雜誌需要賣廣告生存,
    +這個網頁所在的免費網站
    +GeoCities 不允許賣廣告,
    +而租一個獨立的虛擬主機要錢;
    +一份每個月只有七八百人看的網頁,
    +廣告商願意不願意支持也是問題;
    +要賣廣告的話要先學會寫 JavaScript ,
    +這當然也是問題… :~~~~~
    +
    +可是這仍然是我的一個夢想吧!
    +今天在整理旅舍日記的時候,
    +看到了 3.8.’98 第一篇旅舍日記,
    +裡面提到了建造這個旅舍時的夢想。
    +以夢想開始,也以夢想走下去,
    +希望夢想有一天會成真! ^_*' +
    + +
    + +
    + +
    +
    10.12.’98. 0:00am.
    + +
    +今天是 87 年 10 月 12 日。
    +
    +醉倒在新的深夜中。
    +全新的深夜,全新的空間、時間。
    +再一次寫網路上的日記,
    +我身在完全不同的地方。
    +不一樣的牆,不一樣的桌椅,
    +不一樣的巷景,不一樣的生活。
    +
    +也許是作業系統換了 Windows 98 ;
    +也許是我裝了 Netscape ;
    +也許是我學會了怎麼組電腦;
    +也許是身邊多了一個人。
    +我到底真正改變了什麼?
    +我不知道。
    +當了兩個月的會計,又辭職,
    +一切又回到了起點。
    +以為兩個月忙下來總有點收獲的,
    +到頭來卻又發現,
    +對這個世界的看法又回到最初。
    +
    +對了,
    +我還學會了會計。
    +
    +我為什麼要去走這一遭?
    +我不知道。想起來就好荒謬。
    +成天和一群無聊又無知的
    +民族主義者混在一起,
    +看著聽著下午才準備
    +當天晚上的新聞評論節目。
    +其實也怪不得它們,
    +工作壓力壓得它們根本沒有時間思考讀書。
    +而這竟然是臺灣最有水準的地下電臺!
    +妳們可以不讀書,
    +可以持續做爛的節目下去,
    +我可不要。
    +我想唸書,我想思考,我想寫作,
    +我想繼續充實自己。
    +
    +於是我辭職了。
    +原以為這一趟下來可以改變我一些
    +對民族主義者的看法,
    +可是我錯了。
    +一切又回到原點:
    +失業。
    +這樣的結局似乎過於保守了。
    +好像有改變一些什麼,
    +卻又沒有。
    +
    +我又回來了。
    +至少,我又想開始做我自己,
    +讓我自己更好,
    +直到下次冒險出發之前。 +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 1 | + 2 | + 3 | + 4 | + 5 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0003.html.en.html b/htdocs/imacat/me/diary/0003.html.en.html new file mode 120000 index 0000000..32127b2 --- /dev/null +++ b/htdocs/imacat/me/diary/0003.html.en.html @@ -0,0 +1 @@ +0003.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0003.html.en.xhtml b/htdocs/imacat/me/diary/0003.html.en.xhtml new file mode 100644 index 0000000..323e7b3 --- /dev/null +++ b/htdocs/imacat/me/diary/0003.html.en.xhtml @@ -0,0 +1,505 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 3 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 3

    + +
    + +
    + +
    +
    8.20.’00. 11:42pm.
    + +
    +I've finally finished my dream
    +to circle the whole Taiwan by motorcycle.
    +While I opened the front door of my home
    +today 8:00 pm.,
    +I was all slacked off.
    +
    +It was like a long, long dream.
    +So tiring.
    +I was all exhausted.
    +I know I can't go lying down,
    +for I know,
    +once I lie down, I can't get up anymore.
    +
    +There're plenty of things awaiting.
    +messages in the answering machine,
    +emails from friends,
    +new situations on those interviews.
    +They all caused me headache.
    +I felt fainted while I reviewed them.
    +I couldn't deal with them now,
    +but I had to.
    +
    +There're 5 interviews tomorrow.
    +I don't know if I have enough strength
    +to deal with them.
    +All of a sudden,
    +I found myself not having vacations now.
    +Things are piled up like hills.
    +I cannot get them done.
    +
    +But anyway,
    +I've accomplished my long dream
    +to cycle the whole Taiwan island
    +with my motorcycle.
    +Although I have not even the strength
    +to be joyful,
    +It's really, really a wonderful thing. ^_*' +
    + +
    + +
    + +
    +
    8.15.’00. 11:58pm.
    + +
    +I've finally successfully quit.
    +It's so nice.
    +
    +I was hoping to quit clearly,
    +easy come and easy go.
    +I couldn't expect
    +that pig boss had done that shit:
    +Call for a total meeting,
    +point at nobody but abuse me.
    +He's so cheap!
    +
    +I was thinking while I leave the office:
    +I was lucky to leave that hell. Or,
    +I couldn't expect what worse
    +will be happened.
    +
    +Anyway, I was finally left.
    +It's a new beginning.
    +Someone has asked me to join them,
    +and I'm looking for a new job, too.
    +I hope I won't be cheat from now on.
    +Now I will have myself a nice vacation.
    +Hoping it's a nice weather tomorrow. ^_*' +
    + +
    + +
    + +
    +
    7.30.’00. 1:40am.
    + +
    +I’ve stayed online too long,
    +feeling unwell… +
    + +
    + +
    + +
    +
    7.24.’00. 1:54am.
    + +
    +Yes!
    +I've finally got the ADSL
    +fixed connection installed.
    +And the Tavern website has
    +finally moved home.
    +The configurations were much easier
    +than I've expected.
    +Yes! ^_*'
    +
    +But, in the future, the phone bill
    +will increase by about NT$4000 per month.
    +It's harder for me.
    +And There seems to be a nice job,
    +I would like to try it.
    +
    +Will it be too wasteful
    +to play MUD by this costly ADSL? :p +
    + +
    + +
    + +
    +
    7.14.’00. 11:55am.
    + +
    +last evening I was in a sudden fever till 103F.
    +I lay on the bed after office work,
    +feeling myself burning out.
    +
    +I was too tired these days.
    +The company’s combination, redecoration,
    +and personnel troubles,
    +computer installations, printer problems,
    +the reversion of WOV and Tavern,
    +distributing the new WOV,
    +purchasing the washer and dryer…
    +It’s tiring me.  I feel dead,
    +and would take down in any moment.
    +
    +I would like to take a full rest… +
    + +
    + +
    + +
    +
    7.10.’00. 11:32pm.
    + +
    +Yes! This revision of Tavern
    +has finally totally been finished. *^_^*
    +And then is the revision of the company's website.
    +cry~~ :~~
    +
    +I should be happy,
    +but a few days ago Palm SYSOP has finally
    +dismiss me from lesbian board board
    +manager for being away too long.
    +
    +I just can't rejoice,
    +while such a thing happens.
    +
    +I still feel sad.
    +I cannot help to drop the tears,
    +for all I've suffered at Palm.
    +I'm not the kind of person that can set it free,
    +Though I should be so.
    +
    +These days several friends
    +come asking me if I'm alright.
    +Well, no. But what else should I be?
    +I have not bother on it for such a long time.
    +It's time to give away.
    +
    +So I went for a cafe tonight.
    +I kept thinking.
    +I was reminded some things long ago,
    +while I knew B.C, pendulum.
    +Then I thought,
    +maybe I could return to TKU BBS les board
    +to be a newbie again.
    +Maybe I'll meet some more
    +interesting newbies,
    +just like B.C. and pendulum.
    +
    +And I started to make clear
    +what I should do in this period.
    +I feel more practical, then. +
    + +
    + +
    + +
    +
    7.3.’00. 11:02pm.
    + +
    +I was almost hang up,
    +while Mandy is playing
    +an internet card game beside me.
    +She'll kill me if I do hang up.
    +It's so close.
    +
    +I feel very bad.
    +There's a new vice-president in the company
    +who regular customs at the first week.
    +Fuck you!
    +My cloths depends only on my mood.
    +Who cares that shit?
    +
    +In the meeting this noon,
    +the boss regulars lots of bullshit meetings
    +from now on.
    +I'm fainting.
    +Who kind of stupid person
    +would have so much time for that?
    +
    +I'm fainting.
    +Lot's of prolems while setting up windows.
    +I was unable to write something all day long.
    +Not until I was back home
    +that I could peacefully sit and do programming
    +and finish the HyperText Playground.
    +
    +But anyway,
    +I've finished the HyperText Playground.
    +And done JavaScript and Perl versions together.
    +And, also, made it available for English,
    +and available for Netscape!
    +It's so~~ cool! Hahahaha~~!
    +I cannot help to adore myself~~! Yeah~~! ^_*'
    +
    +The reversion of Tavern has only 3 last parts,
    +Chinese Poetry, English Poetry and Women's Sex.
    +Yeah~~ +
    + +
    + +
    + +
    +
    7.1.’00. 10:59pm.
    + +
    +Ah ha…
    +I’ve finally finished the new Tavern Diary.
    +The new Tavern Diary has
    +fullfilled my previous plan:
    +It has become my personal guestbook.
    +Now I write on this diary
    +just like write on a guestbook.
    +That’s better.
    +It’s easier to write Tavern Diary now.
    +I shall write Tavern Diary more often.
    +
    +It’s weekend today.
    +The company was a mess in the morning.
    +They were changing the ceiling around me.
    +I was surounded by dust.
    +I couldn’t write anything the whole morning.
    +I was gonna faint.
    +
    +I don’t know if it’s a good thing.
    +The whole company is a mess now.
    +My plan is a mess, too.
    +I was having a chance to ask the boss
    +to buy some good things.
    +Now there’s an “intranet working company”.
    +It distores my plan.
    +It has to take one week to decide
    +if we’re using windows 98 or 95.
    +Although there're still some advantages.
    +The network is constructed
    +according to the standards now.
    +The equipment of computer department will
    +be partially according to the standards, too.
    +
    +Anyway, I cannot like this job.
    +Lowly paid with lots of works,
    +defected system, illegal working condition.
    +It’s sick.
    +Although I met several cute girls here,
    +it still makes me sick.
    +
    +Let’s wait.
    +I'm waiting for the set up of
    +HiNet ADSL fixed line.
    +Then I can move Tavern and WOV home.
    +I’ll have no scruples.
    +I applied HiNet ADSL this April.
    +and was originally scheduled to set up
    +about June or July.
    +But ADSL modems are in short supply
    +from last month.
    +The shortage will prolong until September.
    +So my ADSL will not set up until September.
    +That’s 2 more months.
    +So bad news.
    +
    +However, I’ll set up multiple servers
    +in one domain for the company.
    +I’ve never try multiple servers before.
    +It would be a good learning chance.
    +And computer dep. will have our own room.
    +Then I can try UNIX. It’s not that bad.
    +
    +Anyway,
    +I’ll have no scruples, then.
    +I can negotiate my salary with my boss,
    +or have other plans.
    +
    +That’s it.
    +Mixed with some personnel problems,
    +the boss' concept problems.
    +A mess situation with a mess future.
    +I don't like to bother on these everyday.
    +I would like to bother more on
    +more meaningful things.
    +<<WOV>> mailing daemon is done.
    +It should restart now.
    +I would like to prepair for the
    +graduate school entrance exam next year,
    +if possible.
    +
    +And thanks god I have my own domain now.
    +“imacat.idv.tw”
    +This was the dream I'd made 2 years ago
    +when Tavern was just started
    +for a few months.
    +It has finally come true!
    +Then I can do lots of things:
    +A www website, an e-mail server.
    +Maybe a BBS, or more different sites.
    +It makes me so happy. ^_*'
    +
    +Let’s cheer for the dream come true! +
    + +
    + +
    + +
    +
    7.1.’00. 10:52am.
    + +
    +This is a test diary entry.
    +The second line.
    +The third line. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 1 | + 2 | + 3 | + 4 | + 5 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0003.html.zh-cn.html b/htdocs/imacat/me/diary/0003.html.zh-cn.html new file mode 120000 index 0000000..eb8c5f2 --- /dev/null +++ b/htdocs/imacat/me/diary/0003.html.zh-cn.html @@ -0,0 +1 @@ +0003.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0003.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0003.html.zh-cn.xhtml new file mode 100644 index 0000000..9507e8d --- /dev/null +++ b/htdocs/imacat/me/diary/0003.html.zh-cn.xhtml @@ -0,0 +1,468 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷三

    + +
    + +
    + +
    +
    8.20.’00. 11:42pm.
    + +
    +终于完成机车环岛的梦想了,
    +今天晚上八点,
    +打开家里大门的瞬间,
    +整个人松了一口气。
    +
    +好像做了一场长长的梦一样,
    +好累。
    +全身都垮了,
    +不敢太早去睡,
    +因为我知道,
    +一旦躺下来就爬不起来了。
    +
    +回到家,
    +事情堆得像山一样高。
    +答录机的留言,朋友的信件,
    +应徵工作的新状况,
    +让人头大。
    +看著看著,
    +整个人晕了起来。
    +累得无法应付,却又得要去处理。
    +
    +明天有五场面试,
    +不知道自己有没有力气应付。
    +突然发现到最后还是没有休到假,
    +事情多得像山一样。
    +忙不完。
    +
    +无论如何,
    +多年以来机车环岛的梦想终于实现罗!
    +虽然现在连高兴的力气都没有,
    +但真的是一件很棒的事呢~! ^_*' +
    + +
    + +
    + +
    +
    8.15.’00. 11:58pm.
    + +
    +终于离职成功了,
    +心情真好。
    +
    +本来想说好聚好散,
    +走得清清楚楚,
    +没想到临走之前,
    +老板那只猪竟然来这一套,
    +召集全公司开会,
    +指桑骂槐地当众骂我。
    +真是贱!
    +
    +走出办公室的时候,心里想:
    +还好我走了,不然的话,
    +还不知道会发生什么更恶劣的事。
    +
    +不论如何,终于走掉了。
    +这总是一个新的开始。
    +有人向我挖角,我也在找新工作中。
    +希望以后不会再被骗钱了。
    +但我想好好放自己半个月的假。
    +希望明天是个好天气。 ^_*' +
    + +
    + +
    + +
    +
    7.30.’00. 1:40am.
    + +
    +上网上得太久了,
    +有点恶心反胃… +
    + +
    + +
    + +
    +
    7.24.’00. 1:54am.
    + +
    +呵呵,万岁~!
    +ADSL 宽频专线终于牵好了,
    +旅舍网站也终于搬回家里罗! ^_*'
    +一切设定比想像中轻松
    +耶耶耶~! ^_*'
    +
    +只是,以后每个月帐单会多出 4000 多,
    +要辛苦些了。
    +似乎有个不错的工作,
    +我想去试试看。
    +
    +拿这么贵的 ADSL 玩 MUD ,
    +是不是太奢侈了? :p +
    + +
    + +
    + +
    +
    7.14.’00. 11:55am.
    + +
    +昨天傍晚突然急性发烧发到 39.5 度,
    +回家后躺在床上,
    +整个人像快烧掉一样。
    +
    +这一阵子实在是太累了,
    +公司合并、重新装璜、人事纷争,
    +电脑组装、印表问题,
    +女声和旅舍改版,女声发刊,
    +家里买洗衣机和烘衣机…
    +我快累死了。
    +一不小心,就病倒了。
    +
    +我好想休息… +
    + +
    + +
    + +
    +
    7.10.’00. 11:32pm.
    + +
    +呵…旅舍改版终於全部完成罗~! *^_^*
    +接下来还有公司的网站要改版,
    +呜呜呜… :~~
    +
    +本来应该是件高兴的事的,
    +但这两天椰林站方
    +终於因为我太久没上站,
    +解除我的拉子板板主了。
    +
    +碰到这种事,
    +我实在高兴不起来。
    +
    +还是很难过,
    +一不小心,眼泪就会掉下来。
    +为这一年来在椰林所遭受的事。
    +我不是个很放得开的人,
    +虽然早该放手的。
    +
    +这两天,几个朋友都来问我还好吧。
    +不好,可是还能怎么办呢?
    +我早就不管事已久,
    +是该放手了。
    +
    +今晚去喝咖啡,想了想,
    +想到之前的路,
    +想到那时认识了 B.C. ,认识了 pendulum ,
    +突然想到,也许我可以回去蛋卷,
    +回去当个新人,慢慢来,
    +也许又会碰到更多有趣的新人,
    +像 B.C. ,像 pendulum 一样。
    +
    +我开始清楚我在这段空窗期要做什么了。
    +心里也踏实多了。 +
    + +
    + +
    + +
    +
    7.3.’00. 11:02pm.
    + +
    +呵…刚刚差点就要断线,
    +小招正在旁边玩网路连线大老二,
    +要是我断线她会把我宰了… :p
    +好险。
    +
    +心情不大好,
    +公司来了个副总,
    +上任第一个星期就要规定服装。
    +去你的咧!
    +老娘穿衣服全凭心情,
    +谁要跟你穿窄裙裤装啊?
    +
    +中午开会,
    +老板规定以后要开一大堆有的没有的会。
    +去你的咧,
    +光听了就想昏倒,
    +谁那么闲整天开会啊?
    +
    +真是快昏倒了。
    +装机不顺利,
    +整天不能坐下来好好写点东西。
    +只有熬到回家,
    +才能静下心来好好写写程式,
    +把超文字游乐场赶出来。
    +
    +不过,终於把超文字游乐场做出来罗!
    +而且还一次做出 JavaScript 和 Perl 的版本,
    +还成功地英文化,还做出 Netscape 的版本,
    +真是太炫罗,哦呵呵呵呵~!
    +我真是太~佩服自己罗~耶~ ^_*'
    +
    +旅舍改版终於只剩三个部份,
    +中文诗、英文诗和女人的性罗!
    +耶~! +
    + +
    + +
    + +
    +
    7.1.’00. 10:59pm.
    + +
    +哦呵…新的旅舍日记终於完成罗~!
    +新的旅舍日记实现了我之前的计划,
    +成了我的个人留言本,
    +用留言本的方式记日记。
    +这样比较好,记日记比较方便,
    +也会更常记日记了吧。
    +
    +今天是周末,
    +早上公司一片混乱,
    +换天花板换到我头上来,
    +弄得我的座位周围都是灰,
    +完全没有办法静下来好好写点东西,
    +快昏倒了。
    +
    +这样的事是好是坏呢?
    +不知道。
    +整个公司大混乱,
    +我的计划也一片混乱。
    +本来有机会叫公司采购点好东西的,
    +半路杀出了一个企业内部网路规划公司,
    +打乱掉我很多盘算。
    +现在光是决定要买 98 还是 95
    +就可以搞掉一个礼拜,
    +虽然也有不少好处就是了。
    +例如公司网路线比照标准规格施工,
    +电脑室的设备也可望部份按照标准建置。
    +
    +总之,我实在是很不喜欢现在这样,
    +钱少事多,
    +公司制度不健全,不合劳基法。
    +这很讨厌。
    +虽然在这里认识了不少可爱的美眉,
    +有点舍不得,
    +可是还是很讨厌。
    +
    +等著吧。
    +我在等 HiNet 的 ADSL 宽频专线装机,
    +然后旅舍和女声网站就可以迁回家里,
    +我就没有顾虑了。
    +今年四月向 HiNet 申请的 ADSL 专线,
    +原本排队排到六、七月就可以装机了,
    +结果上个月底开始 ADSL 数据机缺货,
    +听说最快要到九月份才会正常供货,
    +所以最快也要到九月份才会来装机。
    +这一拖又是两个月,
    +好烦。
    +
    +不过,接下来公司要架多 server 的网域,
    +我没碰过多 server 的网域,
    +这是个很好的学习机会。
    +而且,以后电脑室有独立的空间,
    +还可以自己架 UNIX 来玩,也算蛮不错的。
    +
    +不论如何,
    +到时候就没有顾虑了,
    +我就可以再跟老板好好重谈薪水,
    +或是做其它盘算。
    +
    +就像这样,
    +夹杂著一些公司的人事问题,
    +老板的观念问题,
    +有点混乱的状况,有点混乱的未来。
    +我不喜欢每天烦这些事。
    +我想烦一些比较有营养的事。
    +《女声》发报机都做好了,
    +也该复刊了。
    +如果可以的话,我想今年好好准备,
    +明年去考研究所,走回学术的路。
    +
    +还有,我终於有自己的网域罗~!
    +“imacat.idv.tw”
    +这是两年前旅舍刚架好不久,
    +我就在梦想的计划,
    +现在终於实现罗!
    +接下来可以做更多的事:
    +架个网站,自己的 E-mail
    +还有 BBS ,还可以架更多不同的网站。
    +真是太棒罗~! ^_*'
    +
    +为梦想成真干杯吧! +
    + +
    + +
    + +
    +
    7.1.’00. 10:52am.
    + +
    +这是测试日记。
    +第二行。
    +第三行。 +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 1 | + 2 | + 3 | + 4 | + 5 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0003.html.zh-tw.html b/htdocs/imacat/me/diary/0003.html.zh-tw.html new file mode 120000 index 0000000..5ea98f4 --- /dev/null +++ b/htdocs/imacat/me/diary/0003.html.zh-tw.html @@ -0,0 +1 @@ +0003.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0003.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0003.html.zh-tw.xhtml new file mode 100644 index 0000000..7fddd6f --- /dev/null +++ b/htdocs/imacat/me/diary/0003.html.zh-tw.xhtml @@ -0,0 +1,468 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷三

    + +
    + +
    + +
    +
    8.20.’00. 11:42pm.
    + +
    +終於完成機車環島的夢想了,
    +今天晚上八點,
    +打開家裏大門的瞬間,
    +整個人鬆了一口氣。
    +
    +好像做了一場長長的夢一樣,
    +好累。
    +全身都垮了,
    +不敢太早去睡,
    +因為我知道,
    +一旦躺下來就爬不起來了。
    +
    +回到家,
    +事情堆得像山一樣高。
    +答錄機的留言,朋友的信件,
    +應徵工作的新狀況,
    +讓人頭大。
    +看著看著,
    +整個人暈了起來。
    +累得無法應付,卻又得要去處理。
    +
    +明天有五場面試,
    +不知道自己有沒有力氣應付。
    +突然發現到最後還是沒有休到假,
    +事情多得像山一樣。
    +忙不完。
    +
    +無論如何,
    +多年以來機車環島的夢想終於實現囉!
    +雖然現在連高興的力氣都沒有,
    +但真的是一件很棒的事呢~! ^_*' +
    + +
    + +
    + +
    +
    8.15.’00. 11:58pm.
    + +
    +終於離職成功了,
    +心情真好。
    +
    +本來想說好聚好散,
    +走得清清楚楚,
    +沒想到臨走之前,
    +老闆那隻豬竟然來這一套,
    +召集全公司開會,
    +指桑罵槐地當眾罵我。
    +真是賤!
    +
    +走出辦公室的時候,心裏想:
    +還好我走了,不然的話,
    +還不知道會發生什麼更惡劣的事。
    +
    +不論如何,終於走掉了。
    +這總是一個新的開始。
    +有人向我挖角,我也在找新工作中。
    +希望以後不會再被騙錢了。
    +但我想好好放自己半個月的假。
    +希望明天是個好天氣。 ^_*' +
    + +
    + +
    + +
    +
    7.30.’00. 1:40am.
    + +
    +上網上得太久了,
    +有點噁心反胃… +
    + +
    + +
    + +
    +
    7.24.’00. 1:54am.
    + +
    +呵呵,萬歲~!
    +ADSL 寬頻專線終於牽好了,
    +旅舍網站也終於搬回家裏囉! ^_*'
    +一切設定比想像中輕鬆
    +耶耶耶~! ^_*'
    +
    +只是,以後每個月帳單會多出 4000 多,
    +要辛苦些了。
    +似乎有個不錯的工作,
    +我想去試試看。
    +
    +拿這麼貴的 ADSL 玩 MUD ,
    +是不是太奢侈了? :p +
    + +
    + +
    + +
    +
    7.14.’00. 11:55am.
    + +
    +昨天傍晚突然急性發燒發到 39.5 度,
    +回家後躺在床上,
    +整個人像快燒掉一樣。
    +
    +這一陣子實在是太累了,
    +公司合併、重新裝璜、人事紛爭,
    +電腦組裝、印表問題,
    +女聲和旅舍改版,女聲發刊,
    +家裏買洗衣機和烘衣機…
    +我快累死了。
    +一不小心,就病倒了。
    +
    +我好想休息… +
    + +
    + +
    + +
    +
    7.10.’00. 11:32pm.
    + +
    +呵…旅舍改版終於全部完成囉~! *^_^*
    +接下來還有公司的網站要改版,
    +嗚嗚嗚… :~~
    +
    +本來應該是件高興的事的,
    +但這兩天椰林站方
    +終於因為我太久沒上站,
    +解除我的拉子板板主了。
    +
    +碰到這種事,
    +我實在高興不起來。
    +
    +還是很難過,
    +一不小心,眼淚就會掉下來。
    +為這一年來在椰林所遭受的事。
    +我不是個很放得開的人,
    +雖然早該放手的。
    +
    +這兩天,幾個朋友都來問我還好吧。
    +不好,可是還能怎麼辦呢?
    +我早就不管事已久,
    +是該放手了。
    +
    +今晚去喝咖啡,想了想,
    +想到之前的路,
    +想到那時認識了 B.C. ,認識了 pendulum ,
    +突然想到,也許我可以回去蛋捲,
    +回去當個新人,慢慢來,
    +也許又會碰到更多有趣的新人,
    +像 B.C. ,像 pendulum 一樣。
    +
    +我開始清楚我在這段空窗期要做什麼了。
    +心裏也踏實多了。 +
    + +
    + +
    + +
    +
    7.3.’00. 11:02pm.
    + +
    +呵…剛剛差點就要斷線,
    +小招正在旁邊玩網路連線大老二,
    +要是我斷線她會把我宰了… :p
    +好險。
    +
    +心情不大好,
    +公司來了個副總,
    +上任第一個星期就要規定服裝。
    +去妳的咧!
    +老娘穿衣服全憑心情,
    +誰要跟妳穿窄裙褲裝啊?
    +
    +中午開會,
    +老闆規定以後要開一大堆有的沒有的會。
    +去妳的咧,
    +光聽了就想昏倒,
    +誰那麼閒整天開會啊?
    +
    +真是快昏倒了。
    +裝機不順利,
    +整天不能坐下來好好寫點東西。
    +只有熬到回家,
    +才能靜下心來好好寫寫程式,
    +把超文字遊樂場趕出來。
    +
    +不過,終於把超文字遊樂場做出來囉!
    +而且還一次做出 JavaScript 和 Perl 的版本,
    +還成功地英文化,還做出 Netscape 的版本,
    +真是太炫囉,哦呵呵呵呵~!
    +我真是太~佩服自己囉~耶~ ^_*'
    +
    +旅舍改版終於只剩三個部份,
    +中文詩、英文詩和女人的性囉!
    +耶~! +
    + +
    + +
    + +
    +
    7.1.’00. 10:59pm.
    + +
    +哦呵…新的旅舍日記終於完成囉~!
    +新的旅舍日記實現了我之前的計劃,
    +成了我的個人留言本,
    +用留言本的方式記日記。
    +這樣比較好,記日記比較方便,
    +也會更常記日記了吧。
    +
    +今天是週末,
    +早上公司一片混亂,
    +換天花板換到我頭上來,
    +弄得我的座位周圍都是灰,
    +完全沒有辦法靜下來好好寫點東西,
    +快昏倒了。
    +
    +這樣的事是好是壞呢?
    +不知道。
    +整個公司大混亂,
    +我的計劃也一片混亂。
    +本來有機會叫公司採購點好東西的,
    +半路殺出了一個企業內部網路規劃公司,
    +打亂掉我很多盤算。
    +現在光是決定要買 98 還是 95
    +就可以搞掉一個禮拜,
    +雖然也有不少好處就是了。
    +例如公司網路線比照標準規格施工,
    +電腦室的設備也可望部份按照標準建置。
    +
    +總之,我實在是很不喜歡現在這樣,
    +錢少事多,
    +公司制度不健全,不合勞基法。
    +這很討厭。
    +雖然在這裏認識了不少可愛的美眉,
    +有點捨不得,
    +可是還是很討厭。
    +
    +等著吧。
    +我在等 HiNet 的 ADSL 寬頻專線裝機,
    +然後旅舍和女聲網站就可以遷回家裏,
    +我就沒有顧慮了。
    +今年四月向 HiNet 申請的 ADSL 專線,
    +原本排隊排到六、七月就可以裝機了,
    +結果上個月底開始 ADSL 數據機缺貨,
    +聽說最快要到九月份才會正常供貨,
    +所以最快也要到九月份才會來裝機。
    +這一拖又是兩個月,
    +好煩。
    +
    +不過,接下來公司要架多 server 的網域,
    +我沒碰過多 server 的網域,
    +這是個很好的學習機會。
    +而且,以後電腦室有獨立的空間,
    +還可以自己架 UNIX 來玩,也算蠻不錯的。
    +
    +不論如何,
    +到時候就沒有顧慮了,
    +我就可以再跟老闆好好重談薪水,
    +或是做其它盤算。
    +
    +就像這樣,
    +夾雜著一些公司的人事問題,
    +老闆的觀念問題,
    +有點混亂的狀況,有點混亂的未來。
    +我不喜歡每天煩這些事。
    +我想煩一些比較有營養的事。
    +《女聲》發報機都做好了,
    +也該復刊了。
    +如果可以的話,我想今年好好準備,
    +明年去考研究所,走回學術的路。
    +
    +還有,我終於有自己的網域囉~!
    +“imacat.idv.tw”
    +這是兩年前旅舍剛架好不久,
    +我就在夢想的計劃,
    +現在終於實現囉!
    +接下來可以做更多的事:
    +架個網站,自己的 E-mail
    +還有 BBS ,還可以架更多不同的網站。
    +真是太棒囉~! ^_*'
    +
    +為夢想成真乾杯吧! +
    + +
    + +
    + +
    +
    7.1.’00. 10:52am.
    + +
    +這是測試日記。
    +第二行。
    +第三行。 +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 1 | + 2 | + 3 | + 4 | + 5 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0004.html.en.html b/htdocs/imacat/me/diary/0004.html.en.html new file mode 120000 index 0000000..72c30d8 --- /dev/null +++ b/htdocs/imacat/me/diary/0004.html.en.html @@ -0,0 +1 @@ +0004.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0004.html.en.xhtml b/htdocs/imacat/me/diary/0004.html.en.xhtml new file mode 100644 index 0000000..e8a2676 --- /dev/null +++ b/htdocs/imacat/me/diary/0004.html.en.xhtml @@ -0,0 +1,525 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 4 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 4

    + +
    + +
    + +
    +
    2.22.’05. 2:51am.
    + +
    +I have finished AriesDog's book short novals collection "握手" (shaking hands).
    +Well, very nice.
    +It's very simple and funny.
    +No wander it has a good sales record.
    +
    +But, well, a noval is a noval.
    +
    +I can't explain.
    +I stopped writing for years.  It's not suitable for me to say that.
    +Maybe becaused I've aged a little.
    +I'm not quite easy with too-simple comics stories now.
    +Carrying some weight of day-to-day life.
    +I suppose that's much closer to my current situation.
    +
    +I listen to more medium-heavy rock-n-roll than pop music recently, too.
    +
    +I sounds like a staled intellectual now. ^^;
    +
    +Anyway, AD's "握手" is very good.
    +After all, a noval should look like a noval.
    +I suggest everyone here to read it. ^_*' +
    + +
    + +
    + +
    +
    2.20.’05. 6:19pm.
    + +
    +Today I went to the Taipei International Books Exibition.
    +It's the last day of the exibition, but is not crowded as expected.
    +I went to the Must Muster Publisher, but did not see the boss.  It's a pity.
    +But I say Way-Way, finally, after so many years.  That's really a surprise.
    +
    +Also I bought the legendary lesbian martial noval "Feng-Hsiang Lock Store".
    +I may write some review after I read it.
    +He he~ ^_*' +
    + +
    + +
    + +
    +
    2.20.’05. 5:11am.
    + +
    +2005-02-20, rainy
    +Tavern Diary is done, as Selima 2.12
    +
    +The last attempt is 2004-01-29
    +The previous manual-written diary entry is 2001-04-10
    +It's almost 4 years for this to be done.
    +
    +There's no need to write everything on the guestbook anymore.
    +What a good thing~ ^_*' +
    + +
    + +
    + +
    +
    2.20.’05. 4:33am.
    + +
    +Tavern Diary Testing with Selima 2.12. +
    + +
    + +
    + +
    +
    1.29.’04. 1:16am.
    + +
    +Testing +
    + +
    + +
    + +
    +
    4.10.’01. 0:00am.
    + +
    +I don't know if this is happy or not.
    +I've played computer games for 2 weeks.
    +I don't know why.
    +I don't know what I'm bothering,
    +or what I'm escaping.
    +
    +Don't think I'm happy.
    +Please don't.
    +Sometimes I don't know where could I stay.
    +Sometimes I feel like there's no way to go.
    +Don't envy me.
    +I'm suffering, too.
    +
    +They say, "Be yourself."
    +That's the subject of my twenties.
    +Now I'm twenty-nine.
    +It means nothing anymore.
    +So boring!
    +What can make me better
    +besides to be myself?
    +
    +Or, we are destined to live our live
    +with these garbages all alone.
    +That's it.
    +What else can we do?
    +Nothing?
    +
    +I hate them.
    +No fresh things.
    +No exciting future.
    +All are deadly lying there
    +day after day.
    +
    +Please,
    +change the world.
    +Make this world a little bit different.
    +Please. +
    + +
    + +
    + +
    +
    2.21.’01. 4:01am.
    + +
    +Isn't it very stupid
    +when you love someone
    +but let go all the chances?
    +
    +I was watching the Japanese TV series
    +"Long Vacation" recently.
    +Some romantic feelings quietly
    +slipped inside of me.
    +
    +It's all nonsense. +
    + +
    + +
    + +
    +
    2.21.’01. 3:48am.
    + +
    +The annotation on the guestbook, the counter
    +and the last update has been finished.
    +The guestbook script was largely modified.
    +Most of the settings were moved to the front,
    +to enable others easy to modify and use.
    +
    +If you need a guestbook or a counter,
    +or if you want to learn about
    +how to write a guestbook or a counter,
    +You are welcome to review and
    +use them freely.
    +If you have any questions,
    +feel free to ask me, too.
    +
    +Now, I can be responsible to the term:
    +"open source".
    +If others have to take one month
    +to read and understand,
    +that's not open source. That's shit.
    +
    +It's tiring.
    +I hope I can take a long vacation.
    +The "Hyper TextPlayground"
    +and the common module are not done yet.
    +But I'm quite tired.
    +I haven't slept well for several days.
    +The eyes are aching and fainting.
    +
    +Next, I'll work on the "Technology Ring".
    +It was a unfinised plan long time ago.
    +I try to discuss something about the internet
    +without the e-business or so.
    +I wish I can work it out now. +
    + +
    + +
    + +
    +
    1.29.’01. 4:34am.
    + +
    +I had written a short essay
    +without the start and the end.
    +
    +I'd saddenly realized.
    +Thank you, quity.
    +The sunshine haven't come yet,
    +but the clouds have gone.
    +
    +It's fate to be together.
    +It just happened.
    +That's the way it is.
    +It cannot be enforced,
    +nor can it be explained.
    +
    +Isn't it also fate
    +to be apart?
    +
    +The story has its own way.
    +Just feel free
    +and let it be. +
    + +
    + +
    + +
    +
    12.17.’00. 11:18pm.
    + +
    +Thinking.
    +Writing.
    +
    +BBS testing has finally ended last week.
    +I plan to build a BBS in this year.
    +Learning to build linux,
    +to build apache/sendmail, and BBS.
    +Now I've achieved my promise:
    +To finish all the engineering
    +before the end of this year.
    +
    +Then I can put them aside
    +and start reading and writing.
    +
    +I feel really very easy,
    +very happy.
    +I can write something again.
    +There're so many to read, so much to do.
    +They were put aside for a long time.
    +I can't figure them out in a hush.
    +But I'm not worrying.
    +They shall be figured out very soon.
    +
    +Then,
    +Let's start moving now! ^_*' +
    + +
    + +
    + +
    +
    11.8.’00. 7:22pm.
    + +
    +I was hasten to make som documents
    +for the open source codes of Tavern
    +in the past 2 days.
    +The plan to release source codes
    +had eventually come to an end.
    +It was tiring. +
    + +
    + +
    + +
    +
    11.6.’00. 1:56am.
    + +
    +It's still inadequate yet,
    +but I'd released the source of Tavern.
    +No documentations or annotations yet
    +No release notes
    +and authority announcements yet, too.
    +I'll finish them A.S.A.P.
    +
    +It should be v6.3 .
    +I've tested on the following platforms:
    +Linux / Apache / CGI Perl
    +Linux / Apache / mod_perl
    +Microsoft IIS 5.0 / CGI Perl (ActivePerl)
    +Microsoft IIS 5.0 / ISAPI PerlIS
    +As for the copyright, it is ok, basically,
    +if not for the commercial purpose.
    +I'll write the detail in a couple of days.
    +
    +You can refer to "About Tavern"
    +for more details.
    +If you have any questions,
    +feel free to discuss with me. +
    + +
    + +
    + +
    +
    9.28.’00. 7:19pm.
    + +
    +I was sick.
    +A serious fever.
    +
    +I've bought a new Linux Server.
    +and have finally fullfilled my dream.
    +I was busying moving the websites,
    +learning to setup Linux/Apache server,
    +doing tests, fixes, mendings.
    +If you experience any problem
    +surfing this new website,
    +please tell me.
    +
    +The new Linux server kills me.
    +I learn Linux at the company at day time,
    +while I learn again at home at the night time.
    +I'm tiring out.
    +I've never thought of it so tiring.
    +I was still thinking all about the website,
    +while I was sick and layed on the bed.
    +
    +There're still plenty of things to do.
    +I wish I could get through all this nightmare
    +A.S.A.P. +
    + +
    + +
    + +
    +
    8.26.’00. 4:44am.
    + +
    +I've changed my monitor
    +to a new ViewSonic 17" monitor.
    +I've changed my keyboard
    +to a new Acer keyboard.
    +I've bought a new computer.
    +I'll take it back tomorrow.
    +
    +Watching at this unfamiliar big screen,
    +typing on this unfamiliar new keyboard,
    +feeling the unfamiliarness.
    +
    +Alright.
    +I'm tired.
    +On this rare vacation,
    +putting plenty of files and programs
    +in their order.
    +Watching lots of familiar but foreign e-mails,
    +feeling tired inside.
    +
    +Then,
    +I'd better go to bed now. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 2 | + 3 | + 4 | + 5 | + 6 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0004.html.zh-cn.html b/htdocs/imacat/me/diary/0004.html.zh-cn.html new file mode 120000 index 0000000..522d949 --- /dev/null +++ b/htdocs/imacat/me/diary/0004.html.zh-cn.html @@ -0,0 +1 @@ +0004.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0004.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0004.html.zh-cn.xhtml new file mode 100644 index 0000000..06dbc26 --- /dev/null +++ b/htdocs/imacat/me/diary/0004.html.zh-cn.xhtml @@ -0,0 +1,510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷四

    + +
    + +
    + +
    +
    2.22.’05. 2:51am.
    + +
    +看完了 AD 的「握手」
    +嗯,蛮好看的
    +文字很容易读,内容也很轻松平实有趣
    +难怪会卖得很好
    +诚心推荐~ ^_*'
    +
    +不过,小说还是小说吧
    +
    +很难说自己为什么这样说
    +其实已经多年不写的我,没什么立场这样说的
    +或许是年纪大了,对像漫画一样的情节已经疲乏了
    +像以前那样「对太白痴的情节没有抵抗力」的天真时代已经慢慢过去了
    +在日常生活日复一日的磨练中,背负著一些重量的真实感
    +才比较接近我现在的样子
    +
    +最近听的音乐
    +也从比较轻的流行音乐转向比较重的摇滚乐了
    +嗯
    +
    +突然觉得自己的读书人酸气好重 ^^;
    +
    +可是 AD 的「握手」还是很好看
    +小说本来就是小说~
    +诚心推荐哦~ ^_*' +
    + +
    + +
    + +
    +
    2.20.’05. 6:19pm.
    + +
    +今天去台北国际书展
    +最后一天,除了动漫区外,没有预计中的人潮
    +去集合出版社的摊位,没有看到传说中的集合小玉,甚憾
    +不过竟然意外见到了慕名以久的维维,非常地惊喜 ^_*'
    +
    +买了传说中的女同志武侠小说「凤祥锁铺」
    +有空慢慢看,再来写心得罗
    +呵呵~ ^_*' +
    + +
    + +
    + +
    +
    2.20.’05. 5:11am.
    + +
    +2005 年 2 月 20 日清晨 大雨
    +旅舍日记做出来了, Selima 2.12
    +
    +上一次尝试是 2004 年 1 月 29 日
    +再上一次手写的日记是 2001 年 4 月 10 日
    +等了大约四年吧,嗯
    +
    +以后自己想写什么,不用再通通写在留言板上了
    +真是令人高兴的事呢~ ^_*' +
    + +
    + +
    + +
    +
    2.20.’05. 4:33am.
    + +
    +Selima 2.12 旅舍日记测试。 +
    + +
    + +
    + +
    +
    1.29.’04. 1:16am.
    + +
    +测试 +
    + +
    + +
    + +
    +
    4.10.’01. 0:00am.
    + +
    +原则上,我不知道这样算不算快乐。
    +我连著打了两个多星期的电动,
    +不知道为什么,
    +不知道在烦什么,
    +也不知道在逃避什么。
    +
    +别以为我这样很快乐。
    +有时候,我不知道我有哪里可以容身;
    +有时候,我觉得什么路都走不下去。
    +别羡慕我,
    +其实我也很痛苦。
    +
    +我们常常说,做自己最快乐,
    +这是我二十岁时的课题,
    +现在我已经二十九岁了,
    +对这句话已经没有感觉了。
    +好无聊,
    +除了做自己以外,
    +还有没有别的方法可以让自己快乐?
    +
    +或是,我们注定百无聊赖地过完这一生,
    +赖死赖活,
    +也不过就是这样。
    +除了这些,
    +我们还能做什么?
    +还有什么可以做?
    +或是,什么都做不到?
    +
    +烦,
    +看不到让人耳目一新的事物,
    +看不到让人兴奋的未来,
    +一切都是那么死寂,
    +日复一日。
    +
    +让这个世界改变吧,
    +让这个世界变得比较不同吧,
    +神啊,
    +我求求你。 +
    + +
    + +
    + +
    +
    2.21.’01. 4:01am.
    + +
    +喜欢一个人,
    +却眼看著许多机会错失掉,
    +是不是很呆呢?
    +
    +最近一个人在看日剧「长假」,
    +心情也莫名地变得浪漫。
    +
    +胡思乱想。 +
    + +
    + +
    + +
    +
    2.21.’01. 3:48am.
    + +
    +留言板、计数器和上次更新日期的注解,
    +总算大致上完成了。
    +留言板的程式码也作了大幅度的修改,
    +把所有的设定都移到了最前面,
    +以便其她人修改使用。
    +
    +如果你需要留言板、计数器,
    +或想学怎么写留言板、计数器,
    +欢迎自由参观使用。
    +若有任何疑问,
    +也欢迎不吝指教。
    +
    +做到这样清清楚楚,
    +才算对「开放原始码」这句话交差。
    +否则,如果别人要花一个月才看得懂,
    +实在算不上是「开放原始码」。
    +
    +好累,想给自己放个长假。
    +「超文字游乐场」和「共用模组」
    +都还没改。
    +可是我累了。
    +好几天没睡好,眼睛好痛好昏。
    +
    +接下来,我想好好做「网路人文通讯」。
    +这是很久以前的计划,后来却搁置了。
    +我希望能够在网路商机外,
    +尝试一些对网路的人文思考。
    +我想把它做出来。 +
    + +
    + +
    + +
    +
    1.29.’01. 4:34am.
    + +
    +写了一篇没头没尾的小短文。
    +
    +突然想通了,
    +光,真的谢谢你。
    +虽然心头没有暖起来,
    +可是却失了烦恼。
    +
    +能聚在一起,是缘,
    +两个人就这么在一起了,
    +就是这样。
    +无法强求,
    +也无法解释。
    +
    +会不会分开,
    +又何尝不是缘呢?
    +
    +聚既已随缘,
    +散亦也随缘,
    +不需强求。 +
    + +
    + +
    + +
    +
    12.17.’00. 11:18pm.
    + +
    +想想,
    +写写。
    +
    +上个星期, BBS 架站测试告一段落,
    +今年计划要架 BBS ,
    +从学 Linux 架设,
    +学 apache / sendmail ,学 BBS 架设,
    +我也实现了我对自己的承诺,
    +在年底前完成所有的技术工作。
    +
    +然后,我可以放下所有的网站工程,
    +开始念书,写些东西了。
    +
    +真的很轻松,
    +真的很开心。
    +我又开始写得出东西。
    +想念的东西好多,想做的事好多,
    +都一直搁著,
    +一时间也整理不出来。
    +可是这不是大问题,
    +总会整理出来的。
    +
    +那就,
    +开始上工罗~! ^_*' +
    + +
    + +
    + +
    +
    11.8.’00. 7:22pm.
    + +
    +这两天日夜赶工,
    +写一些开放程式码的相关文件。
    +释出原始码的计划,
    +总算稍告一段落。
    +好累。 +
    + +
    + +
    + +
    +
    11.6.’00. 1:56am.
    + +
    +虽然有点勉强,
    +可是还是释出了旅舍的程式码。
    +该有的说明、注解都没有,
    +也没有版本说明和版权声明。
    +我会尽快把这些完成的。
    +
    +版本上该算是 6.3 版吧,
    +测试过的平台有:
    +Linux / Apache / CGI Perl
    +Linux / Apache / mod_perl
    +Microsoft IIS 5.0 / CGI Perl (ActivePerl)
    +Microsoft IIS 5.0 / ISAPI PerlIS
    +版权问题方面,原则上,
    +只要不是商业用途,应该都无所谓。
    +我会再写详细细节。
    +
    +细节可以参考「关于旅舍」中的说明。
    +若有任何疑问,
    +欢迎写信告诉我。 +
    + +
    + +
    + +
    +
    9.28.’00. 7:19pm.
    + +
    +病倒了,
    +严重发烧。
    +
    +新买了一架 Linux 伺服器,
    +终于实现了我的梦想,
    +这一阵子忙著把网站搬过去,
    +学在 Linux/Apache 上架网站,
    +做测试、修改,补强。
    +若新的网站有任何的问题,
    +请大家帮忙告诉我。
    +
    +新买的 Linux 伺服器,真的很折腾人。
    +白天在公司学 Linux ,
    +晚上在家里也赶著学架 Linux ,
    +我已经快不行了。
    +从来没想过有这么累,
    +累到病倒了,还一直想著网站的事。
    +
    +还要做的事好多,
    +希望这段恶梦早点过去。 +
    + +
    + +
    + +
    +
    8.26.’00. 4:44am.
    + +
    +换了 ViewSonic 的 17 寸萤幕,
    +换了一个宏碁的新键盘,
    +买了一部新电脑,明天要搬回来,
    +
    +看著不熟悉的大萤幕,
    +敲著不熟悉的新键盘,
    +有著不熟悉的生疏感。
    +
    +不知道,
    +疲倦。
    +难得的假期,
    +整理了一大堆平常东存西放的档案,
    +看著一堆又熟悉又陌生的 E-mail
    +心里倦倦的,
    +麻麻的。
    +
    +那,
    +我还是去睡觉好了。 +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 2 | + 3 | + 4 | + 5 | + 6 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0004.html.zh-tw.html b/htdocs/imacat/me/diary/0004.html.zh-tw.html new file mode 120000 index 0000000..f133609 --- /dev/null +++ b/htdocs/imacat/me/diary/0004.html.zh-tw.html @@ -0,0 +1 @@ +0004.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0004.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0004.html.zh-tw.xhtml new file mode 100644 index 0000000..261cb34 --- /dev/null +++ b/htdocs/imacat/me/diary/0004.html.zh-tw.xhtml @@ -0,0 +1,510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷四

    + +
    + +
    + +
    +
    2.22.’05. 2:51am.
    + +
    +看完了 AD 的「握手」
    +嗯,蠻好看的
    +文字很容易讀,內容也很輕鬆平實有趣
    +難怪會賣得很好
    +誠心推薦~ ^_*'
    +
    +不過,小說還是小說吧
    +
    +很難說自己為什麼這樣說
    +其實已經多年不寫的我,沒什麼立場這樣說的
    +或許是年紀大了,對像漫畫一樣的情節已經疲乏了
    +像以前那樣「對太白癡的情節沒有抵抗力」的天真時代已經慢慢過去了
    +在日常生活日復一日的磨練中,背負著一些重量的真實感
    +才比較接近我現在的樣子
    +
    +最近聽的音樂
    +也從比較輕的流行音樂轉向比較重的搖滾樂了
    +嗯
    +
    +突然覺得自己的讀書人酸氣好重 ^^;
    +
    +可是 AD 的「握手」還是很好看
    +小說本來就是小說~
    +誠心推薦哦~ ^_*' +
    + +
    + +
    + +
    +
    2.20.’05. 6:19pm.
    + +
    +今天去台北國際書展
    +最後一天,除了動漫區外,沒有預計中的人潮
    +去集合出版社的攤位,沒有看到傳說中的集合小玉,甚憾
    +不過竟然意外見到了慕名以久的維維,非常地驚喜 ^_*'
    +
    +買了傳說中的女同志武俠小說「鳳祥鎖舖」
    +有空慢慢看,再來寫心得囉
    +呵呵~ ^_*' +
    + +
    + +
    + +
    +
    2.20.’05. 5:11am.
    + +
    +2005 年 2 月 20 日清晨 大雨
    +旅舍日記做出來了, Selima 2.12
    +
    +上一次嚐試是 2004 年 1 月 29 日
    +再上一次手寫的日記是 2001 年 4 月 10 日
    +等了大約四年吧,嗯
    +
    +以後自己想寫什麼,不用再通通寫在留言板上了
    +真是令人高興的事呢~ ^_*' +
    + +
    + +
    + +
    +
    2.20.’05. 4:33am.
    + +
    +Selima 2.12 旅舍日記測試。 +
    + +
    + +
    + +
    +
    1.29.’04. 1:16am.
    + +
    +測試 +
    + +
    + +
    + +
    +
    4.10.’01. 0:00am.
    + +
    +原則上,我不知道這樣算不算快樂。
    +我連著打了兩個多星期的電動,
    +不知道為什麼,
    +不知道在煩什麼,
    +也不知道在逃避什麼。
    +
    +別以為我這樣很快樂。
    +有時候,我不知道我有哪裏可以容身;
    +有時候,我覺得什麼路都走不下去。
    +別羨慕我,
    +其實我也很痛苦。
    +
    +我們常常說,做自己最快樂,
    +這是我二十歲時的課題,
    +現在我已經二十九歲了,
    +對這句話已經沒有感覺了。
    +好無聊,
    +除了做自己以外,
    +還有沒有別的方法可以讓自己快樂?
    +
    +或是,我們註定百無聊賴地過完這一生,
    +賴死賴活,
    +也不過就是這樣。
    +除了這些,
    +我們還能做什麼?
    +還有什麼可以做?
    +或是,什麼都做不到?
    +
    +煩,
    +看不到讓人耳目一新的事物,
    +看不到讓人興奮的未來,
    +一切都是那麼死寂,
    +日復一日。
    +
    +讓這個世界改變吧,
    +讓這個世界變得比較不同吧,
    +神啊,
    +我求求妳。 +
    + +
    + +
    + +
    +
    2.21.’01. 4:01am.
    + +
    +喜歡一個人,
    +卻眼看著許多機會錯失掉,
    +是不是很呆呢?
    +
    +最近一個人在看日劇「長假」,
    +心情也莫名地變得浪漫。
    +
    +胡思亂想。 +
    + +
    + +
    + +
    +
    2.21.’01. 3:48am.
    + +
    +留言板、計數器和上次更新日期的註解,
    +總算大致上完成了。
    +留言板的程式碼也作了大幅度的修改,
    +把所有的設定都移到了最前面,
    +以便其她人修改使用。
    +
    +如果妳需要留言板、計數器,
    +或想學怎麼寫留言板、計數器,
    +歡迎自由參觀使用。
    +若有任何疑問,
    +也歡迎不吝指教。
    +
    +做到這樣清清楚楚,
    +才算對「開放原始碼」這句話交差。
    +否則,如果別人要花一個月才看得懂,
    +實在算不上是「開放原始碼」。
    +
    +好累,想給自己放個長假。
    +「超文字遊樂場」和「共用模組」
    +都還沒改。
    +可是我累了。
    +好幾天沒睡好,眼睛好痛好昏。
    +
    +接下來,我想好好做「網路人文通訊」。
    +這是很久以前的計劃,後來卻擱置了。
    +我希望能夠在網路商機外,
    +嚐試一些對網路的人文思考。
    +我想把它做出來。 +
    + +
    + +
    + +
    +
    1.29.’01. 4:34am.
    + +
    +寫了一篇沒頭沒尾的小短文。
    +
    +突然想通了,
    +光,真的謝謝妳。
    +雖然心頭沒有暖起來,
    +可是卻失了煩惱。
    +
    +能聚在一起,是緣,
    +兩個人就這麼在一起了,
    +就是這樣。
    +無法強求,
    +也無法解釋。
    +
    +會不會分開,
    +又何嘗不是緣呢?
    +
    +聚既已隨緣,
    +散亦也隨緣,
    +不需強求。 +
    + +
    + +
    + +
    +
    12.17.’00. 11:18pm.
    + +
    +想想,
    +寫寫。
    +
    +上個星期, BBS 架站測試告一段落,
    +今年計劃要架 BBS ,
    +從學 Linux 架設,
    +學 apache / sendmail ,學 BBS 架設,
    +我也實現了我對自己的承諾,
    +在年底前完成所有的技術工作。
    +
    +然後,我可以放下所有的網站工程,
    +開始唸書,寫些東西了。
    +
    +真的很輕鬆,
    +真的很開心。
    +我又開始寫得出東西。
    +想唸的東西好多,想做的事好多,
    +都一直擱著,
    +一時間也整理不出來。
    +可是這不是大問題,
    +總會整理出來的。
    +
    +那就,
    +開始上工囉~! ^_*' +
    + +
    + +
    + +
    +
    11.8.’00. 7:22pm.
    + +
    +這兩天日夜趕工,
    +寫一些開放程式碼的相關文件。
    +釋出原始碼的計劃,
    +總算稍告一段落。
    +好累。 +
    + +
    + +
    + +
    +
    11.6.’00. 1:56am.
    + +
    +雖然有點勉強,
    +可是還是釋出了旅舍的程式碼。
    +該有的說明、註解都沒有,
    +也沒有版本說明和版權聲明。
    +我會儘快把這些完成的。
    +
    +版本上該算是 6.3 版吧,
    +測試過的平台有:
    +Linux / Apache / CGI Perl
    +Linux / Apache / mod_perl
    +Microsoft IIS 5.0 / CGI Perl (ActivePerl)
    +Microsoft IIS 5.0 / ISAPI PerlIS
    +版權問題方面,原則上,
    +只要不是商業用途,應該都無所謂。
    +我會再寫詳細細節。
    +
    +細節可以參考「關於旅舍」中的說明。
    +若有任何疑問,
    +歡迎寫信告訴我。 +
    + +
    + +
    + +
    +
    9.28.’00. 7:19pm.
    + +
    +病倒了,
    +嚴重發燒。
    +
    +新買了一架 Linux 伺服器,
    +終於實現了我的夢想,
    +這一陣子忙著把網站搬過去,
    +學在 Linux/Apache 上架網站,
    +做測試、修改,補強。
    +若新的網站有任何的問題,
    +請大家幫忙告訴我。
    +
    +新買的 Linux 伺服器,真的很折騰人。
    +白天在公司學 Linux ,
    +晚上在家裏也趕著學架 Linux ,
    +我已經快不行了。
    +從來沒想過有這麼累,
    +累到病倒了,還一直想著網站的事。
    +
    +還要做的事好多,
    +希望這段惡夢早點過去。 +
    + +
    + +
    + +
    +
    8.26.’00. 4:44am.
    + +
    +換了 ViewSonic 的 17 吋螢幕,
    +換了一個宏碁的新鍵盤,
    +買了一部新電腦,明天要搬回來,
    +
    +看著不熟悉的大螢幕,
    +敲著不熟悉的新鍵盤,
    +有著不熟悉的生疏感。
    +
    +不知道,
    +疲倦。
    +難得的假期,
    +整理了一大堆平常東存西放的檔案,
    +看著一堆又熟悉又陌生的 E-mail
    +心裏倦倦的,
    +麻麻的。
    +
    +那,
    +我還是去睡覺好了。 +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 2 | + 3 | + 4 | + 5 | + 6 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0005.html.en.html b/htdocs/imacat/me/diary/0005.html.en.html new file mode 120000 index 0000000..96ea422 --- /dev/null +++ b/htdocs/imacat/me/diary/0005.html.en.html @@ -0,0 +1 @@ +0005.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0005.html.en.xhtml b/htdocs/imacat/me/diary/0005.html.en.xhtml new file mode 100644 index 0000000..1c0506b --- /dev/null +++ b/htdocs/imacat/me/diary/0005.html.en.xhtml @@ -0,0 +1,364 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 5 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 5

    + +
    + +
    + +
    +
    2.24.’05. 2:11am.
    + +
    +I'm listening to one of my favorite songs,
    +Olivia Newton John's "Physical".
    +
    +I was only grade 3 in the elementary school when this sone was on the billboard (1981).
    +I was too little to listen to POP music at time.
    +But my high school was in the 80's.
    +I heard this song here and there occationally.
    +
    +Not until recently had I start to notice this song.
    +One day I was listening to BBC.  They are introducing classic disco songs in the 80's.
    +"Physical" was one of them.
    +The hot, direct lyrics and the light, pleasant rhythm got popular in a short time and spreads all over the world, introducing lots of disputes.
    +
    +Well,
    +I start to like it
    +while they are playing this light and pleasant classic disco.
    +
    +It's lyrics is really very hot and direct.  It's very funny.
    +
    +==========
    +I'm saying all the things that I know you'll like
    +Making good conversation
    +I gotta handle you just right
    +You know what I mean
    +I took you to an intimate restaurant
    +Then to a suggestive movie
    +There's nothing left to talk about
    +Unless it's horizontally
    +
    +Let's get physical, physical
    +I wanna get physical
    +Let's get into physical
    +Let me hear your body talk, your body talk
    +Let me hear your body talk
    +
    +I've been patient, I've been good
    +Tried to keep my hands on the table
    +It's gettin' hard this holdin' back
    +If you know what I mean
    +
    +I'm sure you'll understand my point of view
    +We know each other mentally
    +You gotta know that you're bringin' out
    +The animal in me
    +
    +Let's get physical, physical
    +I wanna get physical
    +Let's get into physical
    +Let me hear your body talk, your body talk
    +Let me hear your body talk
    +
    +Let's get physical, physical
    +I wanna get physical
    +Let's get into physical
    +Let me hear your body talk, your body talk
    +Let me hear your body talk
    +
    +Let's get physical, physical
    +I wanna get physical
    +Let's get into physical
    +Let me hear your body talk, your body talk
    +Let me hear your body talk
    +
    +Let's get animal, animal
    +I wanna get animal
    +Let's get into animal
    +Let me hear your body talk
    +Let me hear your body talk +
    + +
    + +
    + +
    +
    2.23.’05. 11:09pm.
    + +
    +I'd like to make a book recommendation here:
    +利格拉樂‧阿[女烏]'s "Mulidan".
    +This is another book bought at Taipei International Books Exibition.
    +(Visit the Fembooks' stall with purple clothes to have a 40%-off discount! :p)
    +
    +利格拉樂‧阿[女烏] is from the Paiwan.  She had been devoted to aboriginal and women's movement for many years.
    +Her husband is Wa-li-ssu Yu-kan (瓦歷斯‧尤幹) from the Atayal, a famous aboriginal activist and poet.
    +This is an essay collection.
    +Most stories are about her daily life,
    +within you may find some thought on the situation of the aboriginals, of the women, of the education problems in the tribes,
    +of the aboriginal policies,
    +of even critics to the aboriginal movements from the point of view of a women,
    +critics to the women movements from the point of view of an aboriginal,
    +critics to the racial and social problems of Taiwan.
    +You can find both essays on daily stories and pure critics.
    +
    +I think this is an book that's quite easy to read,
    +but still have it's weight inside.
    +It inspired lots of introspection on me.
    +In order to name her child with an aboriginal name following the mother's people,
    +she had to bring up the "Aboriginal Naming Regulation", "Revision on Civil Law Domestic Relations".
    +This drove the everyone in the household registration office crazy.
    +And they still failed at last.
    +This is an experience that I, as one of the Han people, can hardly imagine.
    +A thing as simple as one's "name"
    +can bring so much difficulty on the aboriginals.
    +Our current household registration system are specially made for us the dominant Han people.
    +Everything is so simple and natural to us Han people,
    +but not to the aboriginals.
    +
    +I wonder how many advantages do we Han people still held over the aboriginals
    +that we are not aware of yet?
    +
    +I then tell myself,
    +next time I made a name column, it must not be limited to 5 characters.
    +Not only Han people are living on this island.
    +But I know this is not enough.  This is just a small piece of help. +
    + +
    + +
    + +
    +
    2.23.’05. 1:20pm.
    + +
    +I try to have myself more leasure time recently.
    +
    +Here is the story:
    +In the past few years, I either wrote programs or played computer games.
    +When projects finished, I turned to games completely.  When tired playing, having too much work deferred, I turn to work again.
    +I was always tired, working or playing, having too less leasure.
    +Now I'm attending to Open University classes.  This cycle becomes "work--play--study".
    +I have lesser leasure time.
    +
    +This winter vacation, several major projects have finished together with my final exam.
    +This time I don't want to play computer games anymore.
    +I'd like to watch some movies.
    +I searched, downloaded, tested, burned and watched several movies,
    +while the winter vacation passed silently.
    +I found I was too busy for everyhing:  Busy working, busy playing, etc.
    +Though I did made something in the past few years.
    +But I like to live my life in my current way:
    +Reading books, reading others' websites, listening to my favorite music, watching my favorite movies,
    +(I watched so many movies in the past few weeks!)
    +and writing some stuff.
    +Life is richer this way.
    +
    +I still have some plan on Tavern:
    +A Tavern change log, a fullly-functional content-management system, etc.
    +Keep going. ^_*' +
    + +
    + +
    + +
    +
    2.23.’05. 12:12pm.
    + +
    +I stayed up late last night, spending a whole day finishing the whole 103 articles on quity's blog yesterday.
    +It's a sort of expiation.
    +
    +I makes a living on the internet.  I'd applied numerous memberships on different websites.
    +In order to manage my passwords, I wrote a file and have records on where I applied memberships.
    +Since my job is security-critical, I changed my password every 6 months.
    +At that time I visits all those website to change my password.
    +I have a chance to review them and see if they are still working.
    +
    +It was time for me again to change my passwords in the beginning of this 2005.
    +When I finally visited quity's Xoops site, I found that it had temporarily shut down.
    +So I asked her on the ICQ.
    +"It'd shut down for long=.=  You never care for it."
    +Ah… ^^;
    +Suddenly I found I'm without conscience.
    +I only care for myself.
    +Many people are caring for me, but I never fed back.
    +
    +Recently I had finished the Tavern Diary program.
    +Thinking about how to promote it,
    +I was reminded of this issue.
    +I want people to read my diary,
    +but I do not read theirs.
    +It's not fair.
    +
    +That's the whole story.
    +
    +So, I spent a whole day on quity's blog,
    +reading her whole 103 articles yesterday.
    +
    +Well,
    +I suddenly found that
    +my knowledge to her is still very limited.
    +She is striving on places I never know.
    +I believe this is an endless path.
    +(“Endless?  No…”)
    +A hundred day is only a promise to oneself.
    +
    +I’m so moved
    +to see her striving to grow up this way.
    +I have no idea how she will becomes,
    +but it must be better than ever.
    +
    +I have to strive harder, too,
    +or I'll be left behind soon. ^_*' +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 3 | + 4 | + 5 | + 6 | + 7 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0005.html.zh-cn.html b/htdocs/imacat/me/diary/0005.html.zh-cn.html new file mode 120000 index 0000000..5c8fdb2 --- /dev/null +++ b/htdocs/imacat/me/diary/0005.html.zh-cn.html @@ -0,0 +1 @@ +0005.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0005.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0005.html.zh-cn.xhtml new file mode 100644 index 0000000..4af1529 --- /dev/null +++ b/htdocs/imacat/me/diary/0005.html.zh-cn.xhtml @@ -0,0 +1,372 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷五

    + +
    + +
    + +
    +
    2.24.’05. 2:11am.
    + +
    +现在在听著一首我很喜欢的歌
    +奥莉薇亚纽顿强 (Olivia Newton John) 的「肉体 (Physical) 」
    +
    +这首歌当红的时候 (1981) ,我只有小学三年级
    +那时候根本不懂流行音乐
    +只是我的国高中是在 1980 的迪斯可年代
    +或多或少都会听到这一首歌,一直都有印象
    +
    +真正开始注意这首歌,是这几年的事
    +有一次听到中广流行网,介绍 80 年代迪斯可时代重要的歌
    +其中便有介绍到这首「肉体 (Physical) 」
    +火辣露骨的歌词,轻快好听的旋律,在当时非常轰动,也引起非常大的争议
    +
    +嗯
    +听著这首已经开始归类於「怀念老歌」的 80 年代经典
    +我开始喜欢上这首旋律轻快优美的迪斯可
    +
    +它的歌词还真的很露骨,也很好玩
    +
    +==========
    +I’m saying all the things that I know you’ll like
    +我说了一堆你爱听的话
    +Making good conversation
    +保持讲话气氛融洽
    +I gotta handle you just right
    +小心翼翼捧著你
    +You know what I mean
    +这样你懂我的企图吧
    +I took you to an intimate restaurant
    +带你去气氛好的餐厅吃饭
    +Then to a suggestive movie
    +再去看场色色的电影
    +There’s nothing left to talk about
    +再不躺下来的话
    +Unless its horizontally
    +就要没话题了
    +
    +Let’s get physical, physical
    +I wanna get physical
    +Let’s get into physical
    +Let me hear your body talk, your body talk
    +Let me hear your body talk
    +
    +I’ve been patient, I’ve been good
    +我拼命忍耐,努力做乖小孩
    +Tried to keep my hands on the table
    +规规矩矩把手放在桌上
    +It’s gettin' hard this holdin’ back
    +不过再装下去越来越难受了
    +If you know what I mean
    +你懂我的意思吧
    +
    +I’m sure you’ll understand my point of view
    +你当然懂我是什么意思
    +We know each other mentally
    +我们心灵相通嘛
    +You gotta know that you’re bringin’ out
    +那你想必也知道
    +The animal in me
    +你已经挑起我的兽性了
    +
    +Let’s get physical, physical
    +I wanna get physical
    +Let’s get into physical
    +Let me hear your body talk, your body talk
    +Let me hear your body talk
    +
    +Let’s get animal, animal
    +I wanna get animal
    +Let’s get into animal
    +Let me hear your body talk
    +Let me hear your body talk +
    + +
    + +
    + +
    +
    2.23.’05. 11:09pm.
    + +
    +我想推荐一本书
    +利格拉乐・阿[女乌]的「穆莉淡部落手札」
    +这是另一本,我在台北国际书展的战利品
    +(来女书店摊位,穿紫色衣服打六折。 :p )
    +
    +利格拉乐・阿[女乌]是排湾族,长期投入原住民运动、女性运动
    +她先生是泰雅族的瓦历斯・尤干,有名的原住民运动者、原住民诗人
    +这是一本短文集
    +大多是作者自己的生活记事
    +夹杂著对原住民处境、女性处境的反省,部落儿童教育问题的反省
    +原住民政策的反省
    +甚至从原住民女性的角色对妇运的反省,从女性的角色对原住民运动的反省
    +对台湾族群、社会问题的反省
    +有很生活化的短记,也有很单纯的批判
    +
    +我觉得这是一本很容易读的书
    +却又不失它应有的重量
    +边阅读,边让我这个汉人反省了很多事
    +为了一个孩子想为登记为原住民姓名,从母姓,归母族
    +动用了立法一年多却从没有人去使用的「原住民姓名条例」、「民法亲属篇修正」
    +在户政事务所弄得所有办事员鸡飞狗跳
    +最后还是功败垂成
    +这是我一个汉人很难想像的经验
    +连「姓名」这样简单的事
    +对原住民却要遇到这么多重重险阻
    +只因为目前所有户政系统,都是为了优势的汉人姓名文化量身打造的
    +在汉人而言理所当然的事
    +在原住民身上却不是如此
    +
    +日常生活中,我们汉人到底还占有多少的社会优势而不自知
    +视为理所当然呢?
    +
    +我心底暗想
    +以后我设计姓名的栏位时
    +一定要记得上限不可以只有五个中文字
    +在这块土地上生活的,不只有汉人
    +虽然我想这样还是不够的,这只是一小点皮毛而已 +
    + +
    + +
    + +
    +
    2.23.’05. 1:20pm.
    + +
    +最近在给自己一些空闲时间
    +
    +事情是这样的
    +过去几年来,我的生活不是写程式,就是玩电动
    +工作告一段落就疯狂玩电动,玩累了,工作积到不行了,就工作
    +结果玩也累,工作也累,总之都不得安闲
    +开始上空大后
    +就变成「工作--电动--课程作业」
    +更不得安闲
    +
    +今年寒假,期末考完,正好公司几件大案子也结案了
    +完全闲了下来
    +突然不想玩电动,想把几部想看的电影看完
    +开始上网找、网路下载、下载后测试、烧录、看
    +不知不觉间,一个寒假就这样过去了
    +突然发现,以前做什么事总是匆匆忙忙,玩也很匆忙,工作也很匆忙
    +虽然也做出了不少事
    +可是我还是比较喜欢像现在这样
    +没有压力,看看书、看看别人的网站、听听自己喜欢的音乐、看看自己想看的电影
    +(这一阵子看了好多电影)
    +写写东西
    +像这样过日子,充实得多了
    +
    +旅舍还有很多东西想做
    +包括旅舍更新记录、一个真正的内容管理系统
    +嗯
    +加油加油~ ^_*' +
    + +
    + +
    + +
    +
    2.23.’05. 12:12pm.
    + +
    +昨天花了一整天,把阿光的部落格上一百零三篇文章都看完了
    +看到半夜
    +算是为了赎罪吧... ^^;
    +
    +我因为靠网路生活,申请的网路会员多到数不清
    +所以写了一个档案来管理密码,顺便也提醒我自己在哪里申请过会员
    +身为重要的网管,为安全起见,密码每半年我会更换一次
    +每半年我拜访这些大大小小网站,去改密码
    +顺便也知道这些网站还在不在,还有没有运作
    +
    +今年 2005 年年初,又到了例行性改密码的时候
    +逛到阿光的 Xoops 站,才发现阿光的 Xoops 站暂时关闭了
    +于是在 ICQ 上问问阿光
    +「关很久了呢=.=  你都没给人家关心」
    +啊... ^^;
    +突然发现自己也是很没良心的那种人,只关心自己的事
    +都是别人在关心我,我没有在关心别人
    +
    +这两天终于把旅舍日记的程式写出来了
    +在想著让人家更容易阅读的同时
    +也想到这个问题
    +我只想要人家来看我的日记
    +也不会想到要去看看人家的日记
    +似乎说不过去~ ^^;
    +
    +这就是所有的故事
    +
    +于是昨天就狠下心来
    +花了一整个晚上
    +好好把阿光的部落格,一百零三篇记事读完了
    +
    +嗯
    +看完后
    +突然觉得
    +我不了解的阿光,有好大好大的一块
    +看著阿光大大小小的成长记事
    +发现阿光在我看不到的地方,很努力地在长大
    +我相信这个过程是永远没有止境的
    +(「没有止境?不要吧~~」)
    +一百天只是给自己的一个承诺,一个段落
    +
    +看到阿光这样很努力地成长
    +打从心底觉得很高兴说~ ^_*'
    +我也不知道阿光以后会变成什么样子
    +但我相信一定会越来越好~
    +
    +我也要更加努力
    +不然会追不上年轻人的脚步呢~ ^_*' +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0005.html.zh-tw.html b/htdocs/imacat/me/diary/0005.html.zh-tw.html new file mode 120000 index 0000000..7cf395f --- /dev/null +++ b/htdocs/imacat/me/diary/0005.html.zh-tw.html @@ -0,0 +1 @@ +0005.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0005.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0005.html.zh-tw.xhtml new file mode 100644 index 0000000..24c9de2 --- /dev/null +++ b/htdocs/imacat/me/diary/0005.html.zh-tw.xhtml @@ -0,0 +1,372 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷五

    + +
    + +
    + +
    +
    2.24.’05. 2:11am.
    + +
    +現在在聽著一首我很喜歡的歌
    +奧莉薇亞紐頓強 (Olivia Newton John) 的「肉體 (Physical) 」
    +
    +這首歌當紅的時候 (1981) ,我只有小學三年級
    +那時候根本不懂流行音樂
    +只是我的國高中是在 1980 的迪斯可年代
    +或多或少都會聽到這一首歌,一直都有印象
    +
    +真正開始注意這首歌,是這幾年的事
    +有一次聽到中廣流行網,介紹 80 年代迪斯可時代重要的歌
    +其中便有介紹到這首「肉體 (Physical) 」
    +火辣露骨的歌詞,輕快好聽的旋律,在當時非常轟動,也引起非常大的爭議
    +
    +嗯
    +聽著這首已經開始歸類於「懷念老歌」的 80 年代經典
    +我開始喜歡上這首旋律輕快優美的迪斯可
    +
    +它的歌詞還真的很露骨,也很好玩
    +
    +==========
    +I’m saying all the things that I know you’ll like
    +我說了一堆妳愛聽的話
    +Making good conversation
    +保持講話氣氛融洽
    +I gotta handle you just right
    +小心翼翼捧著妳
    +You know what I mean
    +這樣妳懂我的企圖吧
    +I took you to an intimate restaurant
    +帶妳去氣氛好的餐廳吃飯
    +Then to a suggestive movie
    +再去看場色色的電影
    +There’s nothing left to talk about
    +再不躺下來的話
    +Unless its horizontally
    +就要沒話題了
    +
    +Let’s get physical, physical
    +I wanna get physical
    +Let’s get into physical
    +Let me hear your body talk, your body talk
    +Let me hear your body talk
    +
    +I’ve been patient, I’ve been good
    +我拼命忍耐,努力做乖小孩
    +Tried to keep my hands on the table
    +規規矩矩把手放在桌上
    +It’s gettin' hard this holdin’ back
    +不過再裝下去越來越難受了
    +If you know what I mean
    +妳懂我的意思吧
    +
    +I’m sure you’ll understand my point of view
    +妳當然懂我是什麼意思
    +We know each other mentally
    +我們心靈相通嘛
    +You gotta know that you’re bringin’ out
    +那妳想必也知道
    +The animal in me
    +妳已經挑起我的獸性了
    +
    +Let’s get physical, physical
    +I wanna get physical
    +Let’s get into physical
    +Let me hear your body talk, your body talk
    +Let me hear your body talk
    +
    +Let’s get animal, animal
    +I wanna get animal
    +Let’s get into animal
    +Let me hear your body talk
    +Let me hear your body talk +
    + +
    + +
    + +
    +
    2.23.’05. 11:09pm.
    + +
    +我想推薦一本書
    +利格拉樂‧阿[女烏]的「穆莉淡部落手札」
    +這是另一本,我在台北國際書展的戰利品
    +(來女書店攤位,穿紫色衣服打六折。 :p )
    +
    +利格拉樂‧阿[女烏]是排灣族,長期投入原住民運動、女性運動
    +她先生是泰雅族的瓦歷斯‧尤幹,有名的原住民運動者、原住民詩人
    +這是一本短文集
    +大多是作者自己的生活記事
    +夾雜著對原住民處境、女性處境的反省,部落兒童教育問題的反省
    +原住民政策的反省
    +甚至從原住民女性的角色對婦運的反省,從女性的角色對原住民運動的反省
    +對台灣族群、社會問題的反省
    +有很生活化的短記,也有很單純的批判
    +
    +我覺得這是一本很容易讀的書
    +卻又不失它應有的重量
    +邊閱讀,邊讓我這個漢人反省了很多事
    +為了一個孩子想為登記為原住民姓名,從母姓,歸母族
    +動用了立法一年多卻從沒有人去使用的「原住民姓名條例」、「民法親屬篇修正」
    +在戶政事務所弄得所有辦事員雞飛狗跳
    +最後還是功敗垂成
    +這是我一個漢人很難想像的經驗
    +連「姓名」這樣簡單的事
    +對原住民卻要遇到這麼多重重險阻
    +只因為目前所有戶政系統,都是為了優勢的漢人姓名文化量身打造的
    +在漢人而言理所當然的事
    +在原住民身上卻不是如此
    +
    +日常生活中,我們漢人到底還佔有多少的社會優勢而不自知
    +視為理所當然呢?
    +
    +我心底暗想
    +以後我設計姓名的欄位時
    +一定要記得上限不可以只有五個中文字
    +在這塊土地上生活的,不只有漢人
    +雖然我想這樣還是不夠的,這只是一小點皮毛而已 +
    + +
    + +
    + +
    +
    2.23.’05. 1:20pm.
    + +
    +最近在給自己一些空閒時間
    +
    +事情是這樣的
    +過去幾年來,我的生活不是寫程式,就是玩電動
    +工作告一段落就瘋狂玩電動,玩累了,工作積到不行了,就工作
    +結果玩也累,工作也累,總之都不得安閒
    +開始上空大後
    +就變成「工作--電動--課程作業」
    +更不得安閒
    +
    +今年寒假,期末考完,正好公司幾件大案子也結案了
    +完全閒了下來
    +突然不想玩電動,想把幾部想看的電影看完
    +開始上網找、網路下載、下載後測試、燒錄、看
    +不知不覺間,一個寒假就這樣過去了
    +突然發現,以前做什麼事總是匆匆忙忙,玩也很匆忙,工作也很匆忙
    +雖然也做出了不少事
    +可是我還是比較喜歡像現在這樣
    +沒有壓力,看看書、看看別人的網站、聽聽自己喜歡的音樂、看看自己想看的電影
    +(這一陣子看了好多電影)
    +寫寫東西
    +像這樣過日子,充實得多了
    +
    +旅舍還有很多東西想做
    +包括旅舍更新記錄、一個真正的內容管理系統
    +嗯
    +加油加油~ ^_*' +
    + +
    + +
    + +
    +
    2.23.’05. 12:12pm.
    + +
    +昨天花了一整天,把阿光的部落格上一百零三篇文章都看完了
    +看到半夜
    +算是為了贖罪吧... ^^;
    +
    +我因為靠網路生活,申請的網路會員多到數不清
    +所以寫了一個檔案來管理密碼,順便也提醒我自己在哪裏申請過會員
    +身為重要的網管,為安全起見,密碼每半年我會更換一次
    +每半年我拜訪這些大大小小網站,去改密碼
    +順便也知道這些網站還在不在,還有沒有運作
    +
    +今年 2005 年年初,又到了例行性改密碼的時候
    +逛到阿光的 Xoops 站,才發現阿光的 Xoops 站暫時關閉了
    +於是在 ICQ 上問問阿光
    +「關很久了呢=.=  你都沒給人家關心」
    +啊... ^^;
    +突然發現自己也是很沒良心的那種人,只關心自己的事
    +都是別人在關心我,我沒有在關心別人
    +
    +這兩天終於把旅舍日記的程式寫出來了
    +在想著讓人家更容易閱讀的同時
    +也想到這個問題
    +我只想要人家來看我的日記
    +也不會想到要去看看人家的日記
    +似乎說不過去~ ^^;
    +
    +這就是所有的故事
    +
    +於是昨天就狠下心來
    +花了一整個晚上
    +好好把阿光的部落格,一百零三篇記事讀完了
    +
    +嗯
    +看完後
    +突然覺得
    +我不瞭解的阿光,有好大好大的一塊
    +看著阿光大大小小的成長記事
    +發現阿光在我看不到的地方,很努力地在長大
    +我相信這個過程是永遠沒有止境的
    +(「沒有止境?不要吧~~」)
    +一百天只是給自己的一個承諾,一個段落
    +
    +看到阿光這樣很努力地成長
    +打從心底覺得很高興說~ ^_*'
    +我也不知道阿光以後會變成什麼樣子
    +但我相信一定會越來越好~
    +
    +我也要更加努力
    +不然會追不上年輕人的腳步呢~ ^_*' +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0006.html.en.html b/htdocs/imacat/me/diary/0006.html.en.html new file mode 120000 index 0000000..22c7298 --- /dev/null +++ b/htdocs/imacat/me/diary/0006.html.en.html @@ -0,0 +1 @@ +0006.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0006.html.en.xhtml b/htdocs/imacat/me/diary/0006.html.en.xhtml new file mode 100644 index 0000000..caad32a --- /dev/null +++ b/htdocs/imacat/me/diary/0006.html.en.xhtml @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 6 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 6

    + +
    + +
    + +
    +
    4.28.’05. 8:43am.
    + +
    +最近兩個程式出了新版
    +Locale::Maketext::Gettext
    +reslog
    +其中 reslog 是從頭重寫,好累
    +不過很有成就感,呵呵
    +
    +其實 arclog 和 chklinks 也該跟著出新版的
    +不過接下來要寫作業了
    +恐怕沒時間了 ^^;
    +
    +剛想到很久沒寫旅舍日記了
    +沒想到光就上來問候了
    +呵呵... ^^;
    +這兩個禮拜忙著自由台灣的管理,還有寫程式,
    +忘記記點事情了
    +這兩天看新聞看得有點火
    +才想到可以來旅舍日記寫
    +旅舍日記本來就是設計給我看看事情的
    +
    +不過系統還是有稍微更新
    +加上了一個簡單的功能,擋某種類型的廣告
    +「繁體中文」也改成「正體中文」了 +
    + +
    + +
    + +
    +
    4.28.’05. 8:35am.
    + +
    +看了今天的蘋果日報
    +痛快
    +
    +黃明才帶關刀進國際機場,朱家訓帶竹聯幫進去打人
    +就算是平時都不可以的事,更何況是昨天的情況
    +丟臉丟到全世界,航警局真是太離譜了
    +
    +不過這些都還是小角色
    +辦了這些小角色,上面煽動暴力的民代、名嘴,卻一個也不敢動
    +辦大不辦小,太可惡了
    +
    +像王世堅、汪笨湖這些大頭目
    +該辦就通通辦起來吧~ +
    + +
    + +
    + +
    +
    3.27.’05. 6:08am.
    + +
    +這兩天,在想一個問題
    +如果醫生的天職是救人,老師的天職是教育學生的話
    +那工程師的天職是什麼?
    +如果工程師也有它的天職的話,那大概就是死守崗位吧
    +在自己職責範圍內的事
    +無論如何都要維持它運作正常
    +因為如果沒有守住,會造成難以想像的危害
    +就像疾駛的火車頭上,一顆小螺絲釘一樣
    +螺絲釘雖小雖不起眼
    +但如果鬆掉了,會造成無數生命的死傷
    +
    +身為一個工程師
    +身為一個一但鬆開就會造成無數死傷的螺絲釘
    +對自己的工作,所掌管事情的重大
    +我懷著誠惶誠恐,戒慎恐懼的心情謹守著 +
    + +
    + +
    + +
    +
    3.23.’05. 0:46am.
    + +
    +終於把公司新網站, Monica 系統上線了
    +了了一樁心願 +
    + +
    + +
    + +
    +
    3.20.’05. 5:21pm.
    + +
    +終於把身邊的 MySQL 4.0 都昇級為 MySQL 4.1 了 +
    + +
    + +
    + +
    +
    3.17.’05. 11:38pm.
    + +
    +終於把身邊的網站都從 PHP 4 昇級到 PHP 5 了
    +Yes! +
    + +
    + +
    + +
    +
    3.16.’05. 9:36pm.
    + +
    +前兩天看完 PHP 4 昇級到 PHP 5 要注意的事項
    +花了好大的功夫檢查、除錯,才把一堆網站昇級上去
    +今天晚上在看 MySQL 4.0 昇級到 MySQL 4.1 要注意的事項
    +看得好累....
    +
    +還累積了:
    +1. Linux 2.4 昇級到 Linux 2.6 要注意的事項
    +2. Debian 3.0 昇級到 Debian 3.1 要注意的事項
    +3. Apache 1 昇級到 Apache 2 要注意的事項
    +4. mod_perl 1 昇級到 mod_perl 2 要注意的事項
    +還沒看......
    +
    +我的媽呀~~ +
    + +
    + +
    + +
    +
    3.13.’05. 12:51pm.
    + +
    +KMT is really asshole.
    +Putting Taiwan into split halves.
    +The China's anti-separation law is hitting us now.
    +They are still blaming internally.
    +Are they really Taiwanese or not?
    +
    +If they don't want be be a Taiwanese, that's fine.
    +Just migrate to China as they wish.
    +Don't making disorder in this island.
    +No one is forcing them to be a Taiwanese. +
    + +
    + +
    + +
    +
    3.13.’05. 3:31am.
    + +
    +Our company's website project has finally come to an end.
    +Programming is done.  It now only waits others' tests and review.
    +It took almost 2 weeks working day and night.
    +It feels so long.
    +
    +But, comparing to the past 4 years of Monica's formation,
    +2 weeks is quite short.
    +The last 4 years have passed so fast.
    +
    +I enter this company on 2000.
    +August 2001, my first company web site, built upon my own ideas, went live.
    +A couple of months later I found serious problems on my programs there.
    +And it's almost impossible to fix that.
    +Then I started to think of writing a brand new content management system from the beginning.
    +It was just an primitive idea.  I had no clue how to make it.
    +How much time I need?  Will it success or fail?  I had no idea.
    +It was too uncertain to tell the boss.  I could only do this privately.
    +To have a seperate development space from our live website,
    +I named it as "Monica", one of my favorite lovely names.
    +
    +4 years has passed since then.  So many things happened.
    +In the beginning I had totally no idea to answer when the boss found it and asked me how much time I need,
    +But now PHP Monica is running on 5 live large and small scaled web sites,
    +with its descendant Selima of mod_perl running on 4 live sites.
    +Now I spent only the last 2 weeks to build the company's web site and its going to go live.
    +Monica finally reaches its target.
    +
    +I feel so great.
    +
    +From now on Monica shall be off the stage.
    +It shall become a powerful running core like Selima.
    +I still have a couple of ideas to work with.
    +All these 26,000 lines of core system and 15,000 lines of web site program
    +are written by myself line by line, character by character.
    +Monica is like my own child.
    +She is my pride. +
    + +
    + +
    + +
    +
    3.4.’05. 4:34am.
    + +
    +I have finished vol. one of "Feng-Shiang lock store"
    +It's really wonderful
    +The author's Chinese skill is excellent.
    +The characters, terms she used, the stage she drew are so beautiful.
    +The situation and problems of lesbians are described detailed and delicately.
    +
    +It's really a good noval.
    +I like it~ ^_*' +
    + +
    + +
    + +
    +
    3.3.’05. 9:05am.
    + +
    +I was checking the spam mails in January and Feburary.
    +They were not checked for 2 months.
    +52,853 mails were checked in 2 nights.
    +It makes me so dizzy. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 4 | + 5 | + 6 | + 7 | + 8 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0006.html.zh-cn.html b/htdocs/imacat/me/diary/0006.html.zh-cn.html new file mode 120000 index 0000000..6c40b6e --- /dev/null +++ b/htdocs/imacat/me/diary/0006.html.zh-cn.html @@ -0,0 +1 @@ +0006.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0006.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0006.html.zh-cn.xhtml new file mode 100644 index 0000000..08b85ee --- /dev/null +++ b/htdocs/imacat/me/diary/0006.html.zh-cn.xhtml @@ -0,0 +1,389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷六

    + +
    + +
    + +
    +
    4.28.’05. 8:43am.
    + +
    +最近两个程式出了新版
    +Locale::Maketext::Gettext
    +reslog
    +其中 reslog 是从头重写,好累
    +不过很有成就感,呵呵
    +
    +其实 arclog 和 chklinks 也该跟著出新版的
    +不过接下来要写作业了
    +恐怕没时间了 ^^;
    +
    +刚想到很久没写旅舍日记了
    +没想到光就上来问候了
    +呵呵... ^^;
    +这两个礼拜忙著自由台湾的管理,还有写程式,
    +忘记记点事情了
    +这两天看新闻看得有点火
    +才想到可以来旅舍日记写
    +旅舍日记本来就是设计给我看看事情的
    +
    +不过系统还是有稍微更新
    +加上了一个简单的功能,挡某种类型的广告
    +「繁体中文」也改成「正体中文」了 +
    + +
    + +
    + +
    +
    4.28.’05. 8:35am.
    + +
    +看了今天的蘋果日報
    +痛快
    +
    +黃明才帶關刀進國際機場,朱家訓帶竹聯幫進去打人
    +就算是平時都不可以的事,更何況是昨天的情況
    +丟臉丟到全世界,航警局真是太離譜了
    +
    +不過這些都還是小角色
    +辦了這些小角色,上面煽動暴力的民代、名嘴,卻一個也不敢動
    +辦大不辦小,太可惡了
    +
    +像王世堅、汪笨湖這些大頭目
    +該辦就通通辦起來吧~ +
    + +
    + +
    + +
    +
    3.27.’05. 6:08am.
    + +
    +这两天,在想一个问题
    +如果医生的天职是救人,老师的天职是教育学生的话
    +那工程师的天职是什么?
    +如果工程师也有它的天职的话,那大概就是死守岗位吧
    +在自己职责范围内的事
    +无论如何都要维持它运作正常
    +因为如果没有守住,会造成难以想像的危害
    +就像疾驶的火车头上,一颗小螺丝钉一样
    +螺丝钉虽小虽不起眼
    +但如果松掉了,会造成无数生命的死伤
    +
    +身为一个工程师
    +身为一个一但松开就会造成无数死伤的螺丝钉
    +对自己的工作,所掌管事情的重大
    +我怀著诚惶诚恐,戒慎恐惧的心情谨守著 +
    + +
    + +
    + +
    +
    3.23.’05. 0:46am.
    + +
    +终于把公司新网站, Monica 系统上线了
    +了了一桩心愿 +
    + +
    + +
    + +
    +
    3.20.’05. 5:21pm.
    + +
    +终于把身边的 MySQL 4.0 都升级为 MySQL 4.1 了 +
    + +
    + +
    + +
    +
    3.17.’05. 11:38pm.
    + +
    +终于把身边的网站都从 PHP 4 升级到 PHP 5 了
    +Yes! +
    + +
    + +
    + +
    +
    3.16.’05. 9:36pm.
    + +
    +前两天看完 PHP 4 升级到 PHP 5 要注意的事项
    +花了好大的功夫检查、除错,才把一堆网站升级上去
    +今天晚上在看 MySQL 4.0 升级到 MySQL 4.1 要注意的事项
    +看得好累....
    +
    +还累积了:
    +1. Linux 2.4 升级到 Linux 2.6 要注意的事项
    +2. Debian 3.0 升级到 Debian 3.1 要注意的事项
    +3. Apache 1 升级到 Apache 2 要注意的事项
    +4. mod_perl 1 升级到 mod_perl 2 要注意的事项
    +还没看......
    +
    +我的妈呀~~ +
    + +
    + +
    + +
    +
    3.13.’05. 12:51pm.
    + +
    +觉得国民党真的很混蛋
    +把台湾搞得这么分裂
    +人家对我们制定反分裂法,都打到我们头上来了
    +他们还是炮口对内轰
    +搞不清楚他们到底还是不是台湾人
    +
    +这么不想当台湾人的话
    +乾脆移民到中国去好了
    +不要在台湾乱
    +没有人强迫他们一定要当台湾人 +
    + +
    + +
    + +
    +
    3.13.’05. 3:31am.
    + +
    +公司新网站的事,终于告一段落
    +我的程式部份都完成了,剩下的只是同事的测试、复核工作
    +算算有两个星期了吧
    +不眠不休,马拉松式的赶工
    +好长的一段时间
    +
    +不过,比起过去这四年,写 PHP Monica 的时间
    +两个星期算很短了
    +想想,一转眼,四年的时间都过去了
    +
    +2000 年我进公司
    +2001 年 8 月时,我按自己的想法,写的第一个公司网站,上线了
    +几个月后,我开始发现,我写的那个网站程式,问题很大
    +而且很难改写,不能动弹
    +于是我开始想,我要另起炉灶,从头写一个全新的网站管理系统
    +那时候只是一个初步的想法,我自己都不大清楚要怎么做
    +更不知道要花多少时间,搞不好还会失败
    +在这种什么都不确定的情况下,我不敢跟老板讲,只能私下自己写
    +为了跟公司网站开发的专案分开
    +我另取了一个名字,叫 Monica ,一个我觉得很可爱的名字
    +
    +从那时到现在,四年了
    +中间经历了好多事
    +从老板发现后,问多久可以写出来,完全没有概念
    +到现在, PHP Monica 系统已经用在五个大、小型网站上
    +还衍生出了 mod_perl 的 Selima 系统,用在四个网站上
    +到过去短短两个星期之内, Monica 架好公司的网站,即将要上线
    +Monica 终于用上了它一当初设计要用上的地方
    +
    +好高兴~
    +
    +从此之后, Monica 终于要从幕前退下
    +像 Selima 一样,成为核心系统,继续运作
    +Monica 计划还没有结束
    +我现在至少还有两三个构想,想把它做出来
    +两万六千行核心程式,一万五千行网站程式
    +都是我一行一行自己一个人写出来的
    +Monica 就像我生的小孩一样
    +是我的骄傲 +
    + +
    + +
    + +
    +
    3.4.’05. 4:34am.
    + +
    +看完了凤祥锁铺的第一集
    +嗯,真的很好看呢
    +作者的中文底子好强,工夫好深
    +光看用字遣词,文字铺陈就觉得很美
    +情节具体而微地把女同志的处境和问题都写了进去
    +
    +嗯
    +真的好棒
    +好好看~ ^_*' +
    + +
    + +
    + +
    +
    3.3.’05. 9:05am.
    + +
    +这两天在整理一、二月份的广告信
    +积了两个月没整理
    +两个晚上翻了 52,853 封信
    +眼睛都花了
    +好累 +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 4 | + 5 | + 6 | + 7 | + 8 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0006.html.zh-tw.html b/htdocs/imacat/me/diary/0006.html.zh-tw.html new file mode 120000 index 0000000..6afacba --- /dev/null +++ b/htdocs/imacat/me/diary/0006.html.zh-tw.html @@ -0,0 +1 @@ +0006.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0006.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0006.html.zh-tw.xhtml new file mode 100644 index 0000000..c8da22a --- /dev/null +++ b/htdocs/imacat/me/diary/0006.html.zh-tw.xhtml @@ -0,0 +1,389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷六

    + +
    + +
    + +
    +
    4.28.’05. 8:43am.
    + +
    +最近兩個程式出了新版
    +Locale::Maketext::Gettext
    +reslog
    +其中 reslog 是從頭重寫,好累
    +不過很有成就感,呵呵
    +
    +其實 arclog 和 chklinks 也該跟著出新版的
    +不過接下來要寫作業了
    +恐怕沒時間了 ^^;
    +
    +剛想到很久沒寫旅舍日記了
    +沒想到光就上來問候了
    +呵呵... ^^;
    +這兩個禮拜忙著自由台灣的管理,還有寫程式,
    +忘記記點事情了
    +這兩天看新聞看得有點火
    +才想到可以來旅舍日記寫
    +旅舍日記本來就是設計給我看看事情的
    +
    +不過系統還是有稍微更新
    +加上了一個簡單的功能,擋某種類型的廣告
    +「繁體中文」也改成「正體中文」了 +
    + +
    + +
    + +
    +
    4.28.’05. 8:35am.
    + +
    +看了今天的蘋果日報
    +痛快
    +
    +黃明才帶關刀進國際機場,朱家訓帶竹聯幫進去打人
    +就算是平時都不可以的事,更何況是昨天的情況
    +丟臉丟到全世界,航警局真是太離譜了
    +
    +不過這些都還是小角色
    +辦了這些小角色,上面煽動暴力的民代、名嘴,卻一個也不敢動
    +辦大不辦小,太可惡了
    +
    +像王世堅、汪笨湖這些大頭目
    +該辦就通通辦起來吧~ +
    + +
    + +
    + +
    +
    3.27.’05. 6:08am.
    + +
    +這兩天,在想一個問題
    +如果醫生的天職是救人,老師的天職是教育學生的話
    +那工程師的天職是什麼?
    +如果工程師也有它的天職的話,那大概就是死守崗位吧
    +在自己職責範圍內的事
    +無論如何都要維持它運作正常
    +因為如果沒有守住,會造成難以想像的危害
    +就像疾駛的火車頭上,一顆小螺絲釘一樣
    +螺絲釘雖小雖不起眼
    +但如果鬆掉了,會造成無數生命的死傷
    +
    +身為一個工程師
    +身為一個一但鬆開就會造成無數死傷的螺絲釘
    +對自己的工作,所掌管事情的重大
    +我懷著誠惶誠恐,戒慎恐懼的心情謹守著 +
    + +
    + +
    + +
    +
    3.23.’05. 0:46am.
    + +
    +終於把公司新網站, Monica 系統上線了
    +了了一樁心願 +
    + +
    + +
    + +
    +
    3.20.’05. 5:21pm.
    + +
    +終於把身邊的 MySQL 4.0 都昇級為 MySQL 4.1 了 +
    + +
    + +
    + +
    +
    3.17.’05. 11:38pm.
    + +
    +終於把身邊的網站都從 PHP 4 昇級到 PHP 5 了
    +Yes! +
    + +
    + +
    + +
    +
    3.16.’05. 9:36pm.
    + +
    +前兩天看完 PHP 4 昇級到 PHP 5 要注意的事項
    +花了好大的功夫檢查、除錯,才把一堆網站昇級上去
    +今天晚上在看 MySQL 4.0 昇級到 MySQL 4.1 要注意的事項
    +看得好累....
    +
    +還累積了:
    +1. Linux 2.4 昇級到 Linux 2.6 要注意的事項
    +2. Debian 3.0 昇級到 Debian 3.1 要注意的事項
    +3. Apache 1 昇級到 Apache 2 要注意的事項
    +4. mod_perl 1 昇級到 mod_perl 2 要注意的事項
    +還沒看......
    +
    +我的媽呀~~ +
    + +
    + +
    + +
    +
    3.13.’05. 12:51pm.
    + +
    +覺得國民黨真的很混蛋
    +把台灣搞得這麼分裂
    +人家對我們制定反分裂法,都打到我們頭上來了
    +他們還是砲口對內轟
    +搞不清楚他們到底還是不是台灣人
    +
    +這麼不想當台灣人的話
    +乾脆移民到中國去好了
    +不要在台灣亂
    +沒有人強迫他們一定要當台灣人 +
    + +
    + +
    + +
    +
    3.13.’05. 3:31am.
    + +
    +公司新網站的事,終於告一段落
    +我的程式部份都完成了,剩下的只是同事的測試、複核工作
    +算算有兩個星期了吧
    +不眠不休,馬拉松式的趕工
    +好長的一段時間
    +
    +不過,比起過去這四年,寫 PHP Monica 的時間
    +兩個星期算很短了
    +想想,一轉眼,四年的時間都過去了
    +
    +2000 年我進公司
    +2001 年 8 月時,我按自己的想法,寫的第一個公司網站,上線了
    +幾個月後,我開始發現,我寫的那個網站程式,問題很大
    +而且很難改寫,不能動彈
    +於是我開始想,我要另起爐灶,從頭寫一個全新的網站管理系統
    +那時候只是一個初步的想法,我自己都不大清楚要怎麼做
    +更不知道要花多少時間,搞不好還會失敗
    +在這種什麼都不確定的情況下,我不敢跟老闆講,只能私下自己寫
    +為了跟公司網站開發的專案分開
    +我另取了一個名字,叫 Monica ,一個我覺得很可愛的名字
    +
    +從那時到現在,四年了
    +中間經歷了好多事
    +從老闆發現後,問多久可以寫出來,完全沒有概念
    +到現在, PHP Monica 系統已經用在五個大、小型網站上
    +還衍生出了 mod_perl 的 Selima 系統,用在四個網站上
    +到過去短短兩個星期之內, Monica 架好公司的網站,即將要上線
    +Monica 終於用上了它一當初設計要用上的地方
    +
    +好高興~
    +
    +從此之後, Monica 終於要從幕前退下
    +像 Selima 一樣,成為核心系統,繼續運作
    +Monica 計劃還沒有結束
    +我現在至少還有兩三個構想,想把它做出來
    +兩萬六千行核心程式,一萬五千行網站程式
    +都是我一行一行自己一個人寫出來的
    +Monica 就像我生的小孩一樣
    +是我的驕傲 +
    + +
    + +
    + +
    +
    3.4.’05. 4:34am.
    + +
    +看完了鳳祥鎖舖的第一集
    +嗯,真的很好看呢
    +作者的中文底子好強,工夫好深
    +光看用字遣詞,文字鋪陳就覺得很美
    +情節具體而微地把女同志的處境和問題都寫了進去
    +
    +嗯
    +真的好棒
    +好好看~ ^_*' +
    + +
    + +
    + +
    +
    3.3.’05. 9:05am.
    + +
    +這兩天在整理一、二月份的廣告信
    +積了兩個月沒整理
    +兩個晚上翻了 52,853 封信
    +眼睛都花了
    +好累 +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 4 | + 5 | + 6 | + 7 | + 8 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0007.html.en.html b/htdocs/imacat/me/diary/0007.html.en.html new file mode 120000 index 0000000..268f15d --- /dev/null +++ b/htdocs/imacat/me/diary/0007.html.en.html @@ -0,0 +1 @@ +0007.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0007.html.en.xhtml b/htdocs/imacat/me/diary/0007.html.en.xhtml new file mode 100644 index 0000000..df7813e --- /dev/null +++ b/htdocs/imacat/me/diary/0007.html.en.xhtml @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 7 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 7

    + +
    + +
    + +
    +
    5.27.’05. 11:00am.
    + +
    +今天怡客買早餐時,看到桌邊放的徵文徵照片活動
    +等得無聊,把傳單拿來一看
    +好....好誇張~覺得快昏倒了
    +=============
    +活動一:在咖啡館遇見愛情 徵文活動
    +
    +5. 入圍初選之文章,稿件所有權及其所含之一切著作權等相關智慧財產全,參加者同意以怡客咖啡股份有限公司為著作人,享有著作人格權&著作財產權,。
    +6. 投稿者同意怡客咖啡股份有限公司將入圍初選之作品依業務需求,有刪除整理並無限期、不限次數、範圍作為宣傳、展示、刊登、報導之用,無須再另行支付費用。
    +=============
    +活動二: Summer Love Kiss 徵相片活動
    +
    +5. 參加者須同意免費提供其相片予主辦單位複製存檔,並有刪除整理並無限期、不限次數、範圍作為宣傳、展示、刊登、報導之用,無須再另行支付費用,入選者並同意不主張個人肖像權&著作人格權,但會註明相片&文章之姓名等相關個人資料。
    +=============
    +哪有這種事,簡直是賣身契嘛
    +報紙副刊專欄供稿都沒有這種事
    +更何況參加還不一定會入選,不一定拿得到獎金獎品這些稿酬
    +沒有確定稿酬還要人家簽賣身契,真是太野蠻了
    +誰要參加這種活動啊? +
    + +
    + +
    + +
    +
    5.26.’05. 4:40pm.
    + +
    +竟然有人下跪請連戰續任
    +邊跪還邊罵馬英九是歷史罪人
    +真... 讓人不敢相信 +
    + +
    + +
    + +
    +
    5.26.’05. 0:21am.
    + +
    +今天晚上和一個老朋友喝咖啡
    +講了很久的話
    +講到最後
    +我平常在勸別人的話,其實我自己就是那個最做不到的人
    +
    +希望下次還有機會跟朋友喝咖啡
    +在我 *有錢* 的時候
    +唉 +
    + +
    + +
    + +
    +
    5.7.’05. 11:56pm.
    + +
    +有點無聊
    +東摸摸西摸摸
    +是該專心寫作業的時候
    +嗯嗯嗯 +
    + +
    + +
    + +
    +
    5.3.’05. 0:27am.
    + +

    這兩天花了一些功夫,研究 CPAN testers 測試系統怎麼玩,怎麼加入 CPAN 套件測試工作,怎麼用最省力的方式,用我自己的環境,協助半自動測試每天三、四十個新版的 CPAN 套件,並上傳測試結果。這個過程蠻有趣的。我想,對開放原始碼環境,除了貢獻我花心思寫的程式以外,還可以貢獻我花心思幫忙別人做的程式品管工作。就像我自己寫的 Locale::Maketext::Gettext ,別人幫我測試,讓我找出我寫的程式的問題一樣,我也可以幫忙做同樣的事,大家互相幫助、回饋。

    + +

    這兩天,開始有人寫信問我測試的細節,想瞭解他們寫的模組的問題,開始有一些互動。我覺得很開心。有人為了他們寫的東西,主動跑來問我。感覺真的很好。呵呵~

    + +

    在這個過程中,我也開始去學操作 ActivePerl 的細節。我用了 ActivePerl 這麼久,從來都沒有仔細注意過 ActivePerl 到底怎麼用,新套件怎麼安裝,環境怎麼設定。真的蠻有趣的。為了多瞭解 PerlMS-Windows 下的運作細節,我也試著去裝 cygwin 。 Cygwin 真的好神奇,竟然把 MS-Windows 變成 UNIX 了!真的好厲害!我現在也慢慢熟悉了 cygwin 下的 Perl 如何操作了。

    + +

    還有 CPANCPANPLUS 。我以前從來都不屑去使用這麼高階的東西,現在為了省力,大量半自動測試 CPAN 套件,只好乖乖來學了。還蠻有趣的。我想我正式安裝的套件不會用 CPANCPANPLUS 吧,一句老話,太高階了,出錯的時候頗麻煩。這兩天也的確出過很多次錯。不過那麼半自動的套件整合安裝系統,真的很神奇。嗯嗯。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 5 | + 6 | + 7 | + 8 | + 9 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0007.html.zh-cn.html b/htdocs/imacat/me/diary/0007.html.zh-cn.html new file mode 120000 index 0000000..abb7df8 --- /dev/null +++ b/htdocs/imacat/me/diary/0007.html.zh-cn.html @@ -0,0 +1 @@ +0007.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0007.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0007.html.zh-cn.xhtml new file mode 100644 index 0000000..706a281 --- /dev/null +++ b/htdocs/imacat/me/diary/0007.html.zh-cn.xhtml @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷七

    + +
    + +
    + +
    +
    5.27.’05. 11:00am.
    + +
    +今天怡客买早餐时,看到桌边放的徵文徵照片活动
    +等得无聊,把传单拿来一看
    +好....好夸张~觉得快昏倒了
    +=============
    +活动一:在咖啡馆遇见爱情 徵文活动
    +
    +5. 入围初选之文章,稿件所有权及其所含之一切著作权等相关智慧财产全,参加者同意以怡客咖啡股份有限公司为著作人,享有著作人格权&著作财产权,。
    +6. 投稿者同意怡客咖啡股份有限公司将入围初选之作品依业务需求,有删除整理并无限期、不限次数、范围作为宣传、展示、刊登、报导之用,无须再另行支付费用。
    +=============
    +活动二: Summer Love Kiss 徵相片活动
    +
    +5. 参加者须同意免费提供其相片予主办单位复制存档,并有删除整理并无限期、不限次数、范围作为宣传、展示、刊登、报导之用,无须再另行支付费用,入选者并同意不主张个人肖像权&著作人格权,但会注明相片&文章之姓名等相关个人资料。
    +=============
    +哪有这种事,简直是卖身契嘛
    +报纸副刊专栏供稿都没有这种事
    +更何况参加还不一定会入选,不一定拿得到奖金奖品这些稿酬
    +没有确定稿酬还要人家签卖身契,真是太野蛮了
    +谁要参加这种活动啊? +
    + +
    + +
    + +
    +
    5.26.’05. 4:40pm.
    + +
    +竟然有人下跪请连战续任
    +边跪还边骂马英九是历史罪人
    +真... 让人不敢相信 +
    + +
    + +
    + +
    +
    5.26.’05. 0:21am.
    + +
    +今天晚上和一个老朋友喝咖啡
    +讲了很久的话
    +讲到最后
    +我平常在劝别人的话,其实我自己就是那个最做不到的人
    +
    +希望下次还有机会跟朋友喝咖啡
    +在我 *有钱* 的时候
    +唉 +
    + +
    + +
    + +
    +
    5.7.’05. 11:56pm.
    + +
    +有点无聊
    +东摸摸西摸摸
    +是该专心写作业的时候
    +嗯嗯嗯 +
    + +
    + +
    + +
    +
    5.3.’05. 0:27am.
    + +

    这两天花了一些功夫,研究 CPAN testers 测试系统怎么玩,怎么加入 CPAN 套件测试工作,怎么用最省力的方式,用我自己的环境,协助半自动测试每天三、四十个新版的 CPAN 套件,并上传测试结果。这个过程蛮有趣的。我想,对开放原始码环境,除了贡献我花心思写的程式以外,还可以贡献我花心思帮忙别人做的程式品管工作。就像我自己写的 Locale::Maketext::Gettext ,别人帮我测试,让我找出我写的程式的问题一样,我也可以帮忙做同样的事,大家互相帮助、回馈。

    + +

    这两天,开始有人写信问我测试的细节,想了解他们写的模组的问题,开始有一些互动。我觉得很开心。有人为了他们写的东西,主动跑来问我。感觉真的很好。呵呵~

    + +

    在这个过程中,我也开始去学操作 ActivePerl 的细节。我用了 ActivePerl 这么久,从来都没有仔细注意过 ActivePerl 到底怎么用,新套件怎么安装,环境怎么设定。真的蛮有趣的。为了多了解 PerlMS-Windows 下的运作细节,我也试著去装 cygwin 。 Cygwin 真的好神奇,竟然把 MS-Windows 变成 UNIX 了!真的好厉害!我现在也慢慢熟悉了 cygwin 下的 Perl 如何操作了。

    + +

    还有 CPANCPANPLUS 。我以前从来都不屑去使用这么高阶的东西,现在为了省力,大量半自动测试 CPAN 套件,只好乖乖来学了。还蛮有趣的。我想我正式安装的套件不会用 CPANCPANPLUS 吧,一句老话,太高阶了,出错的时候颇麻烦。这两天也的确出过很多次错。不过那么半自动的套件整合安装系统,真的很神奇。嗯嗯。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 5 | + 6 | + 7 | + 8 | + 9 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0007.html.zh-tw.html b/htdocs/imacat/me/diary/0007.html.zh-tw.html new file mode 120000 index 0000000..bfcc7b0 --- /dev/null +++ b/htdocs/imacat/me/diary/0007.html.zh-tw.html @@ -0,0 +1 @@ +0007.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0007.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0007.html.zh-tw.xhtml new file mode 100644 index 0000000..4865e4e --- /dev/null +++ b/htdocs/imacat/me/diary/0007.html.zh-tw.xhtml @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷七

    + +
    + +
    + +
    +
    5.27.’05. 11:00am.
    + +
    +今天怡客買早餐時,看到桌邊放的徵文徵照片活動
    +等得無聊,把傳單拿來一看
    +好....好誇張~覺得快昏倒了
    +=============
    +活動一:在咖啡館遇見愛情 徵文活動
    +
    +5. 入圍初選之文章,稿件所有權及其所含之一切著作權等相關智慧財產全,參加者同意以怡客咖啡股份有限公司為著作人,享有著作人格權&著作財產權,。
    +6. 投稿者同意怡客咖啡股份有限公司將入圍初選之作品依業務需求,有刪除整理並無限期、不限次數、範圍作為宣傳、展示、刊登、報導之用,無須再另行支付費用。
    +=============
    +活動二: Summer Love Kiss 徵相片活動
    +
    +5. 參加者須同意免費提供其相片予主辦單位複製存檔,並有刪除整理並無限期、不限次數、範圍作為宣傳、展示、刊登、報導之用,無須再另行支付費用,入選者並同意不主張個人肖像權&著作人格權,但會註明相片&文章之姓名等相關個人資料。
    +=============
    +哪有這種事,簡直是賣身契嘛
    +報紙副刊專欄供稿都沒有這種事
    +更何況參加還不一定會入選,不一定拿得到獎金獎品這些稿酬
    +沒有確定稿酬還要人家簽賣身契,真是太野蠻了
    +誰要參加這種活動啊? +
    + +
    + +
    + +
    +
    5.26.’05. 4:40pm.
    + +
    +竟然有人下跪請連戰續任
    +邊跪還邊罵馬英九是歷史罪人
    +真... 讓人不敢相信 +
    + +
    + +
    + +
    +
    5.26.’05. 0:21am.
    + +
    +今天晚上和一個老朋友喝咖啡
    +講了很久的話
    +講到最後
    +我平常在勸別人的話,其實我自己就是那個最做不到的人
    +
    +希望下次還有機會跟朋友喝咖啡
    +在我 *有錢* 的時候
    +唉 +
    + +
    + +
    + +
    +
    5.7.’05. 11:56pm.
    + +
    +有點無聊
    +東摸摸西摸摸
    +是該專心寫作業的時候
    +嗯嗯嗯 +
    + +
    + +
    + +
    +
    5.3.’05. 0:27am.
    + +

    這兩天花了一些功夫,研究 CPAN testers 測試系統怎麼玩,怎麼加入 CPAN 套件測試工作,怎麼用最省力的方式,用我自己的環境,協助半自動測試每天三、四十個新版的 CPAN 套件,並上傳測試結果。這個過程蠻有趣的。我想,對開放原始碼環境,除了貢獻我花心思寫的程式以外,還可以貢獻我花心思幫忙別人做的程式品管工作。就像我自己寫的 Locale::Maketext::Gettext ,別人幫我測試,讓我找出我寫的程式的問題一樣,我也可以幫忙做同樣的事,大家互相幫助、回饋。

    + +

    這兩天,開始有人寫信問我測試的細節,想瞭解他們寫的模組的問題,開始有一些互動。我覺得很開心。有人為了他們寫的東西,主動跑來問我。感覺真的很好。呵呵~

    + +

    在這個過程中,我也開始去學操作 ActivePerl 的細節。我用了 ActivePerl 這麼久,從來都沒有仔細注意過 ActivePerl 到底怎麼用,新套件怎麼安裝,環境怎麼設定。真的蠻有趣的。為了多瞭解 PerlMS-Windows 下的運作細節,我也試著去裝 cygwin 。 Cygwin 真的好神奇,竟然把 MS-Windows 變成 UNIX 了!真的好厲害!我現在也慢慢熟悉了 cygwin 下的 Perl 如何操作了。

    + +

    還有 CPANCPANPLUS 。我以前從來都不屑去使用這麼高階的東西,現在為了省力,大量半自動測試 CPAN 套件,只好乖乖來學了。還蠻有趣的。我想我正式安裝的套件不會用 CPANCPANPLUS 吧,一句老話,太高階了,出錯的時候頗麻煩。這兩天也的確出過很多次錯。不過那麼半自動的套件整合安裝系統,真的很神奇。嗯嗯。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 5 | + 6 | + 7 | + 8 | + 9 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0008.html.en.html b/htdocs/imacat/me/diary/0008.html.en.html new file mode 120000 index 0000000..90a43b5 --- /dev/null +++ b/htdocs/imacat/me/diary/0008.html.en.html @@ -0,0 +1 @@ +0008.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0008.html.en.xhtml b/htdocs/imacat/me/diary/0008.html.en.xhtml new file mode 100644 index 0000000..0cdbfaa --- /dev/null +++ b/htdocs/imacat/me/diary/0008.html.en.xhtml @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 8 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 8

    + +
    + +
    + +
    +
    6.1.’05. 6:23pm.
    + +
    +在自由時報上看到 Yahoo! 奇摩交友要被告了
    +交友檔案規則太嚴苛,改來改去
    +好奇上去看一看
    +頗...好笑
    +
    +付費交友,等於 Yahoo! 和付費的網友訂契約
    +契約卻可以片面改來改去
    +在法理上,怎麼說都不合理
    +
    +而且自我介紹沒寫,寫得少,抄歌詞
    +照片放團體照,放和狗狗的合照,放和小孩的合照
    +都是個人的事
    +交友檔案做得不好,自然就沒有人會去看
    +這種事交給市場機制就可以了
    +交友是個人的私事
    +Yahoo! 未免也管得太多了
    +
    +非 VIP 的日記限 150 個字以內
    +150 個字能寫什麼有意義的東西? ^^;
    +
    +還是旅舍日記比較好
    +愛怎麼寫,愛寫什麼隨我高興~ ^_*' +
    + +
    + +
    + +
    +
    5.30.’05. 11:30am.
    + +
    +朱木炎案,民間司改會要檢舉警察
    +http://www.libertytimes.com.tw/2005/new/may/30/today-so1.htm
    +違反偵察不公開原則,侵犯個人隱私
    +
    +做得好
    +哪有這種事?
    +朱木炎今天去警察局做筆錄,隔天筆錄內容就上電視、報紙了
    +被害人尊嚴何在?以後誰還敢報警?
    +碰到犯罪事件,誰能保證過程每一個細節,都不會有難以啟齒的事?
    +像這樣,今天給警察的側錄錄音帶,明天電視上就開始播
    +今天跟警查筆錄交代的細節,明天全國都看得到
    +太離譜了
    +
    +警察這樣搞,真的太離譜了 +
    + +
    + +
    + +
    +
    5.29.’05. 1:31am.
    + +
    +剛看完「科倫拜校園殺人事件」
    +有「美國最後的良心」之稱的麥克‧摩爾的前一部電影
    +嗯 深有所感
    +
    +恐懼是最好的賣點
    +我想開始戒看新聞了
    +不想讓被誇大的恐懼支配我的生活
    +
    +美國真是一個可怕的國家
    +比較起來,加拿大真像是天堂一樣
    +可惜台灣越來越像美國,不像加拿大
    +仇恨同性戀,仇恨不同主張的人
    +到處有人在散佈、誇大無謂的恐懼和仇恨 +
    + +
    + +
    + +
    +
    5.27.’05. 4:44pm.
    + +

    依瑪貓中英語教室 (1)

    + +

    今天我們要教的是這一句:

    + +
    I perfect the drink
    +within your drink.
    +咖啡宛如藝術
    +而我 完美了它
    + +
    +I perfect the drink within your drink. 咖啡宛如藝術 而我 完美了它
    +

    I perfect the drink within your drink. 咖啡宛如藝術 而我 完美了它

    +
    + +

    這一句中英文,出現在我們公司樓下的統一星巴克咖啡店門口印得非常精緻的布旗上,大約有一個月了。看樣子這是統一星巴客行銷部,某個廣告 AD 的得意之作,做為這一季星巴克咖啡的促銷宣傳詞。

    + +
    +統一星巴客羅斯福門市
    +

    統一星巴客羅斯福門市

    +
    + +

    我們來看看這句中英文,有什麼問題。

    + +

    首先,來看英文: perfect 可以當動詞用,所以 I perfect the drink 雖然一般很少聽到,可是沒有問題。問題在後面的 within your drink 上。什麼叫做 within your drink ?我問過所有我認識的外國人,沒有人知道這句話在講什麼。我想了很久,作者可能想說的是類似 within your lips 或是 while you drink it 之類的,透過飲者的行為,讓一杯咖啡畫下最後一個完美的句點。可是那也不是 within your drinkdrink 當名詞時是飲料的意思,沒有的動作的意思。 I perfect the drink within your drink 作者可能想藉著連用兩個不同意義 drink ,創造類似中文雙關語的語言趣味。這句用中文雙關語趣味的思考模式寫出的英文,應了一句話:中式英文,不倫不類,沒有一個以英語為母語的民族看得懂。

    + +

    再來看它的中文,更荒謬了:而我 完美了它很明顯是英文 I perfect the drink 的直譯。問題是,英文裏的 perfect 可以作動詞用,可是中文的完美不能作動詞用。我完美了它這句中文,完全狗屁不通,是標準的美式中文,直接把英文逐字譯成中文的結果。

    + +

    於是,我們得到一個結論:這一個本季統一星巴客咖啡的宣傳促銷詞

    + +
    I perfect the drink within your drink.
    +咖啡宛如藝術 而我 完美了它
    + +

    它的英文狗屁不通,是標準的中式英文;它的中文也狗屁不通,是標種的美式中文。外國人看不懂,台灣人也看不懂。那它到底是寫給誰看的呢?我不知道~~ :p 這句話,榮登本週每週一句經典笑話的榜首~~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 6 | + 7 | + 8 | + 9 | + 10 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0008.html.zh-cn.html b/htdocs/imacat/me/diary/0008.html.zh-cn.html new file mode 120000 index 0000000..02b39ac --- /dev/null +++ b/htdocs/imacat/me/diary/0008.html.zh-cn.html @@ -0,0 +1 @@ +0008.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0008.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0008.html.zh-cn.xhtml new file mode 100644 index 0000000..7be2a18 --- /dev/null +++ b/htdocs/imacat/me/diary/0008.html.zh-cn.xhtml @@ -0,0 +1,272 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷八

    + +
    + +
    + +
    +
    6.1.’05. 6:23pm.
    + +
    +在自由时报上看到 Yahoo! 奇摩交友要被告了
    +交友档案规则太严苛,改来改去
    +好奇上去看一看
    +颇...好笑
    +
    +付费交友,等于 Yahoo! 和付费的网友订契约
    +契约却可以片面改来改去
    +在法理上,怎么说都不合理
    +
    +而且自我介绍没写,写得少,抄歌词
    +照片放团体照,放和狗狗的合照,放和小孩的合照
    +都是个人的事
    +交友档案做得不好,自然就没有人会去看
    +这种事交给市场机制就可以了
    +交友是个人的私事
    +Yahoo! 未免也管得太多了
    +
    +非 VIP 的日记限 150 个字以内
    +150 个字能写什么有意义的东西? ^^;
    +
    +还是旅舍日记比较好
    +爱怎么写,爱写什么随我高兴~ ^_*' +
    + +
    + +
    + +
    +
    5.30.’05. 11:30am.
    + +
    +朱木炎案,民间司改会要检举警察
    +http://www.libertytimes.com.tw/2005/new/may/30/today-so1.htm
    +违反侦察不公开原则,侵犯个人隐私
    +
    +做得好
    +哪有这种事?
    +朱木炎今天去警察局做笔录,隔天笔录内容就上电视、报纸了
    +被害人尊严何在?以后谁还敢报警?
    +碰到犯罪事件,谁能保证过程每一个细节,都不会有难以启齿的事?
    +像这样,今天给警察的侧录录音带,明天电视上就开始播
    +今天跟警查笔录交代的细节,明天全国都看得到
    +太离谱了
    +
    +警察这样搞,真的太离谱了 +
    + +
    + +
    + +
    +
    5.29.’05. 1:31am.
    + +
    +刚看完「科伦拜校园杀人事件」
    +有「美国最后的良心」之称的麦克·摩尔的前一部电影
    +嗯 深有所感
    +
    +恐惧是最好的卖点
    +我想开始戒看新闻了
    +不想让被夸大的恐惧支配我的生活
    +
    +美国真是一个可怕的国家
    +比较起来,加拿大真像是天堂一样
    +可惜台湾越来越像美国,不像加拿大
    +仇恨同性恋,仇恨不同主张的人
    +到处有人在散布、夸大无谓的恐惧和仇恨 +
    + +
    + +
    + +
    +
    5.27.’05. 4:44pm.
    + +

    依玛猫中英语教室 (1)

    + +

    今天我们要教的是这一句:

    + +
    I perfect the drink
    +within your drink.
    +咖啡宛如艺术
    +而我 完美了它
    + +
    +I perfect the drink within your drink. 咖啡宛如艺术 而我 完美了它
    +

    I perfect the drink within your drink. 咖啡宛如艺术 而我 完美了它

    +
    + +

    这一句中英文,出现在我们公司楼下的统一星巴克咖啡店门口印得非常精致的布旗上,大约有一个月了。看样子这是统一星巴客行销部,某个广告 AD 的得意之作,做为这一季星巴克咖啡的促销宣传词。

    + +
    +统一星巴客罗斯福门市
    +

    统一星巴客罗斯福门市

    +
    + +

    我们来看看这句中英文,有什么问题。

    + +

    首先,来看英文: perfect 可以当动词用,所以 I perfect the drink 虽然一般很少听到,可是没有问题。问题在后面的 within your drink 上。什么叫做 within your drink ?我问过所有我认识的外国人,没有人知道这句话在讲什么。我想了很久,作者可能想说的是类似 within your lips 或是 while you drink it 之类的,透过饮者的行为,让一杯咖啡画下最后一个完美的句点。可是那也不是 within your drinkdrink 当名词时是饮料的意思,没有的动作的意思。 I perfect the drink within your drink 作者可能想藉著连用两个不同意义 drink ,创造类似中文双关语的语言趣味。这句用中文双关语趣味的思考模式写出的英文,应了一句话:中式英文,不伦不类,没有一个以英语为母语的民族看得懂。

    + +

    再来看它的中文,更荒谬了:而我 完美了它很明显是英文 I perfect the drink 的直译。问题是,英文里的 perfect 可以作动词用,可是中文的完美不能作动词用。我完美了它这句中文,完全狗屁不通,是标准的美式中文,直接把英文逐字译成中文的结果。

    + +

    於是,我们得到一个结论:这一个本季统一星巴客咖啡的宣传促销词

    + +
    I perfect the drink within your drink.
    +咖啡宛如艺术 而我 完美了它
    + +

    它的英文狗屁不通,是标准的中式英文;它的中文也狗屁不通,是标种的美式中文。外国人看不懂,台湾人也看不懂。那它到底是写给谁看的呢?我不知道~~ :p 这句话,荣登本周每周一句经典笑话的榜首~~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 6 | + 7 | + 8 | + 9 | + 10 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0008.html.zh-tw.html b/htdocs/imacat/me/diary/0008.html.zh-tw.html new file mode 120000 index 0000000..2c025c9 --- /dev/null +++ b/htdocs/imacat/me/diary/0008.html.zh-tw.html @@ -0,0 +1 @@ +0008.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0008.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0008.html.zh-tw.xhtml new file mode 100644 index 0000000..58b44a7 --- /dev/null +++ b/htdocs/imacat/me/diary/0008.html.zh-tw.xhtml @@ -0,0 +1,272 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷八

    + +
    + +
    + +
    +
    6.1.’05. 6:23pm.
    + +
    +在自由時報上看到 Yahoo! 奇摩交友要被告了
    +交友檔案規則太嚴苛,改來改去
    +好奇上去看一看
    +頗...好笑
    +
    +付費交友,等於 Yahoo! 和付費的網友訂契約
    +契約卻可以片面改來改去
    +在法理上,怎麼說都不合理
    +
    +而且自我介紹沒寫,寫得少,抄歌詞
    +照片放團體照,放和狗狗的合照,放和小孩的合照
    +都是個人的事
    +交友檔案做得不好,自然就沒有人會去看
    +這種事交給市場機制就可以了
    +交友是個人的私事
    +Yahoo! 未免也管得太多了
    +
    +非 VIP 的日記限 150 個字以內
    +150 個字能寫什麼有意義的東西? ^^;
    +
    +還是旅舍日記比較好
    +愛怎麼寫,愛寫什麼隨我高興~ ^_*' +
    + +
    + +
    + +
    +
    5.30.’05. 11:30am.
    + +
    +朱木炎案,民間司改會要檢舉警察
    +http://www.libertytimes.com.tw/2005/new/may/30/today-so1.htm
    +違反偵察不公開原則,侵犯個人隱私
    +
    +做得好
    +哪有這種事?
    +朱木炎今天去警察局做筆錄,隔天筆錄內容就上電視、報紙了
    +被害人尊嚴何在?以後誰還敢報警?
    +碰到犯罪事件,誰能保證過程每一個細節,都不會有難以啟齒的事?
    +像這樣,今天給警察的側錄錄音帶,明天電視上就開始播
    +今天跟警查筆錄交代的細節,明天全國都看得到
    +太離譜了
    +
    +警察這樣搞,真的太離譜了 +
    + +
    + +
    + +
    +
    5.29.’05. 1:31am.
    + +
    +剛看完「科倫拜校園殺人事件」
    +有「美國最後的良心」之稱的麥克‧摩爾的前一部電影
    +嗯 深有所感
    +
    +恐懼是最好的賣點
    +我想開始戒看新聞了
    +不想讓被誇大的恐懼支配我的生活
    +
    +美國真是一個可怕的國家
    +比較起來,加拿大真像是天堂一樣
    +可惜台灣越來越像美國,不像加拿大
    +仇恨同性戀,仇恨不同主張的人
    +到處有人在散佈、誇大無謂的恐懼和仇恨 +
    + +
    + +
    + +
    +
    5.27.’05. 4:44pm.
    + +

    依瑪貓中英語教室 (1)

    + +

    今天我們要教的是這一句:

    + +
    I perfect the drink
    +within your drink.
    +咖啡宛如藝術
    +而我 完美了它
    + +
    +I perfect the drink within your drink. 咖啡宛如藝術 而我 完美了它
    +

    I perfect the drink within your drink. 咖啡宛如藝術 而我 完美了它

    +
    + +

    這一句中英文,出現在我們公司樓下的統一星巴克咖啡店門口印得非常精緻的布旗上,大約有一個月了。看樣子這是統一星巴客行銷部,某個廣告 AD 的得意之作,做為這一季星巴克咖啡的促銷宣傳詞。

    + +
    +統一星巴客羅斯福門市
    +

    統一星巴客羅斯福門市

    +
    + +

    我們來看看這句中英文,有什麼問題。

    + +

    首先,來看英文: perfect 可以當動詞用,所以 I perfect the drink 雖然一般很少聽到,可是沒有問題。問題在後面的 within your drink 上。什麼叫做 within your drink ?我問過所有我認識的外國人,沒有人知道這句話在講什麼。我想了很久,作者可能想說的是類似 within your lips 或是 while you drink it 之類的,透過飲者的行為,讓一杯咖啡畫下最後一個完美的句點。可是那也不是 within your drinkdrink 當名詞時是飲料的意思,沒有的動作的意思。 I perfect the drink within your drink 作者可能想藉著連用兩個不同意義 drink ,創造類似中文雙關語的語言趣味。這句用中文雙關語趣味的思考模式寫出的英文,應了一句話:中式英文,不倫不類,沒有一個以英語為母語的民族看得懂。

    + +

    再來看它的中文,更荒謬了:而我 完美了它很明顯是英文 I perfect the drink 的直譯。問題是,英文裏的 perfect 可以作動詞用,可是中文的完美不能作動詞用。我完美了它這句中文,完全狗屁不通,是標準的美式中文,直接把英文逐字譯成中文的結果。

    + +

    於是,我們得到一個結論:這一個本季統一星巴客咖啡的宣傳促銷詞

    + +
    I perfect the drink within your drink.
    +咖啡宛如藝術 而我 完美了它
    + +

    它的英文狗屁不通,是標準的中式英文;它的中文也狗屁不通,是標種的美式中文。外國人看不懂,台灣人也看不懂。那它到底是寫給誰看的呢?我不知道~~ :p 這句話,榮登本週每週一句經典笑話的榜首~~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 6 | + 7 | + 8 | + 9 | + 10 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0009.html.en.html b/htdocs/imacat/me/diary/0009.html.en.html new file mode 120000 index 0000000..a35fd72 --- /dev/null +++ b/htdocs/imacat/me/diary/0009.html.en.html @@ -0,0 +1 @@ +0009.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0009.html.en.xhtml b/htdocs/imacat/me/diary/0009.html.en.xhtml new file mode 100644 index 0000000..a367476 --- /dev/null +++ b/htdocs/imacat/me/diary/0009.html.en.xhtml @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 9 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 9

    + +
    + +
    + +
    +
    6.10.’05. 0:06am.
    + +

    依瑪貓國語教室 照樣造句

    + +

    引文出處:蘋果日報 2005-06-09 《社會追緝令》也多模擬演出 東森一度力挺王 突宣布節目腰斬 + +

    +

    …另名離職員工也表示,當記者質疑模擬新聞時,王育誠都會強調:它真的有發生,只是我們沒拍到!

    +
    + +

    照樣造句:

    + +
      +
    • 我昨天在我家頂樓看到外星人:它真的有發生,只是我們沒拍到!
    • + +
    • 昨天半夜鄧麗君的鬼魂顯靈,跟我說話:它真的有發生,只是我們沒拍到!
    • + +
    • 王育誠趁老婆出差,帶酒店小姐回家過夜:它真的有發生,只是我們沒拍到!
    • + +
    • 腳尾飯事件,王育誠不但從頭到尾知情,說謊,其實根本就是主使者:它真的有發生,只是我們沒拍到!
    • +
    + +

    嗯,通通都真的有發生,只是我們沒拍到。

    + +
    + +
    + +
    +
    6.5.’05. 11:44am.
    + +

    奇文共賞

    + +

    這一篇真的讓我看傻了。中時是國內數一數二的媒體大頭目。國內數一數二的媒體大頭目,反省媒體亂象,本來應該算是好事。不過,整篇文章,充滿著對媒體亂象的無力感。如果連國內數一數二的媒體大頭目,都充滿著對媒體的無力感的話,那我們這些升斗小民,還能說什麼呢?對一個媒體大頭目,一個真正的掌權者,我們期待的是自我檢討,甚至是宣示新的編輯政策,而不是像無力改變現狀的升斗小民一樣,虛無地哀聲嘆氣。因為他,就是那個最有能力改變現狀的人。

    + +

    看到郭大總輯哀聲嘆氣,讓我有種角色錯置的感覺。怎麼寫得事情和自己無關一樣?你,不就是你自己在抱怨的那個媒體嗎?

    + +
    +
    2005/06/03
    +

    懷疑的年代,冰封的信心

    +
    中時電子報總編輯 郭至禎
    + +

    --媒體的自醒--

    + +

    最近在這一期的天下雜誌中讀到了一篇為什麼現在信任這麼紅!

    + +

    文中提到,大家都說這是新一波的信任危機,全球企業、政治、社會正進入一個誰也不相信誰的新時代,從企業到專業團體與媒體,公信力紛紛大幅下降的新信任危機。

    + +

    誰說不是呢?如今上自人民與政府間,領導與被領導的信任度越來越薄弱;政黨與政黨間,協商與合作的任信基礎越來越不可信;下至公司企業的經營誠信也遭踐踏至已成昨日黃花;而更令人難過的是,乃至於一般民間人與人最基本的互信原則似乎也已遭破壞,在現今的社會中,要取得相對的信任幾乎已經是一件難上加難的事了,如此一來我們又該以什麼準則來做為人與人之間互動往來,合作交易的基準點呢?

    + +

    從1985年的十信事件、1998年國揚以及新巨群等大型地雷股事件,一直到2004年博達掏空案,這一些大型企業一再的在侵蝕民眾的血汗,同時也不斷的在動搖人民對這些企業的信任。

    + +

    在經歷遭受SARS衝擊的時候,而台灣護理人員卻在第一時間拒絕看護隔離病患,而另一位生命垂危的邱小妹卻被鬆散的醫療體系與喪失醫德的醫療人員當成人球轉運,甚或是對嬰兒打錯針;對女研究生割錯卵巢等等事件,實在是已經讓台灣民眾開始對於這些所謂的專業的信任大大的打了一個折扣。

    + +

    至於我們的政府呢!信任絕非只是兩人象徵性的握握手或是送幅書法,在上面書寫著真誠二字便可以此為憑,日月可鑑!

    + +

    也絕非今天告訴人民說我們要提升台灣國際間的競爭力,讓台灣走出去,但是明天卻又必須基於政黨利益的考量,又將台灣閉鎖於國際局勢之外。

    + +

    然而另一個讓人感到難過卻也最感無力的是,台灣的媒體卻是上述這些問題的伴隨者,甚或是效果擴散的催化者,全世界尚未看到有任何一個國家在此小小的島嶼上密佈著如此驚人的各式媒體,新聞充斥到令人感到難受,不論是什麼樣形式的媒體,當天真正有用且值得閱讀的新聞可能僅有1/2而已,其他1/2不是追逐社會血腥八卦,便是漫無邊際的口水政治,媒體為了創造收視率可以不斷的重播渲染,同時向下刨根,因此不論是璩美鳳或是薛凱莉;不論是妃鴻戀還是倪夏事件,不僅讓當事人體無完膚,更讓我們的社會感到面目可憎。

    + +

    其實在我們的腦海中依稀還印存著,當年還僅有三台電視兩份報紙的時代,畫面雖然是黑白的,但是黑白分明,那個年代的新聞媒體雖然還是相當受控閉鎖,但是卻多了一點人性的感動,如過您還記得民國58年台視首播八點檔的連續劇晶晶,或是當年台灣金龍少棒隊遠赴美國賓州威廉波特參加世界少棒賽一舉贏得冠軍,從此掀起台灣棒球運動的熱潮,這些種種的畫面都記錄著那個時代下的感動,對於當年的媒體來說,所能傳遞的資訊或許是單薄了許多,但是所能留下的記憶內容卻是深刻多了。

    + +

    當年的人們對於媒體或許無知,也或許不可知,更或許是不得而知,但是基本上所得到的卻是相對的單純與可信任。只是隨著時光的流轉,經濟的成長,民智的開放,科技的日新與政治的解禁,當一切似乎都朝著陽光般的目標前進發展時,我們卻漸漸的失去了從前那一份單純的信任與快樂。

    + +

    最近由公共電視與中映電影聯合製播了一支紀錄台灣農村生活與環境的紀錄片無米樂,片中的架構以台灣在即將面對WTO入會之後,台灣的農業將面臨自由貿易的衝擊,以及這一群一生以農為生,以稻米為生命的老農民們,他們又該怎麼默然以對…

    + +

    剎那間令人覺得再一次看到了台灣人民最樸實、善良與真誠的一面,看到了這一群可愛的台灣農民對於這一片土地長期以來的依賴與信任,對於這樣深刻紀錄大地、人物與生命的影片,其真誠的感動不禁油然而生,而對於能夠如此真誠的呈現,感動人心,卻也是媒體獨天獨厚得以創造的優勢。

    + +

    借一句德國管理大師 Reinhard k.Sprenger所說的銘言,信心如蜜,凡流過處必然甜美

    + +

    台灣的媒體!我們還剩下多少信任的存款,可供留傳給下一代的子孫,自省與再付出,該是對於這一片土地與人民最佳的回饋。

    +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 7 | + 8 | + 9 | + 10 | + 11 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0009.html.zh-cn.html b/htdocs/imacat/me/diary/0009.html.zh-cn.html new file mode 120000 index 0000000..f5e54b4 --- /dev/null +++ b/htdocs/imacat/me/diary/0009.html.zh-cn.html @@ -0,0 +1 @@ +0009.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0009.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0009.html.zh-cn.xhtml new file mode 100644 index 0000000..2a90b7c --- /dev/null +++ b/htdocs/imacat/me/diary/0009.html.zh-cn.xhtml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷九

    + +
    + +
    + +
    +
    6.10.’05. 0:06am.
    + +

    依玛猫国语教室 照样造句

    + +

    引文出处:苹果日报 2005-06-09 《社会追缉令》也多模拟演出 东森一度力挺王 突宣布节目腰斩 + +

    +

    …另名离职员工也表示,当记者质疑模拟新闻时,王育诚都会强调:它真的有发生,只是我们没拍到!

    +
    + +

    照样造句:

    + +
      +
    • 我昨天在我家顶楼看到外星人:它真的有发生,只是我们没拍到!
    • + +
    • 昨天半夜邓丽君的鬼魂显灵,跟我说话:它真的有发生,只是我们没拍到!
    • + +
    • 王育诚趁老婆出差,带酒店小姐回家过夜:它真的有发生,只是我们没拍到!
    • + +
    • 脚尾饭事件,王育诚不但从头到尾知情,说谎,其实根本就是主使者:它真的有发生,只是我们没拍到!
    • +
    + +

    嗯,通通都真的有发生,只是我们没拍到。

    + +
    + +
    + +
    +
    6.5.’05. 11:44am.
    + +

    奇文共赏

    + +

    这一篇真的让我看傻了。中时是国内数一数二的媒体大头目。国内数一数二的媒体大头目,反省媒体乱象,本来应该算是好事。不过,整篇文章,充满著对媒体乱象的无力感。如果连国内数一数二的媒体大头目,都充满著对媒体的无力感的话,那我们这些升斗小民,还能说什么呢?对一个媒体大头目,一个真正的掌权者,我们期待的是自我检讨,甚至是宣示新的编辑政策,而不是像无力改变现状的升斗小民一样,虚无地哀声叹气。因为他,就是那个最有能力改变现状的人。

    + +

    看到郭大总辑哀声叹气,让我有种角色错置的感觉。怎么写得事情和自己无关一样?你,不就是你自己在抱怨的那个媒体吗?

    + +
    +
    2005/06/03
    +

    怀疑的年代,冰封的信心

    +
    中时电子报总编辑 郭至祯
    + +

    --媒体的自醒--

    + +

    最近在这一期的天下杂志中读到了一篇为什么现在信任这么红!

    + +

    文中提到,大家都说这是新一波的信任危机,全球企业、政治、社会正进入一个谁也不相信谁的新时代,从企业到专业团体与媒体,公信力纷纷大幅下降的新信任危机。

    + +

    谁说不是呢?如今上自人民与政府间,领导与被领导的信任度越来越薄弱;政党与政党间,协商与合作的任信基础越来越不可信;下至公司企业的经营诚信也遭践踏至已成昨日黄花;而更令人难过的是,乃至于一般民间人与人最基本的互信原则似乎也已遭破坏,在现今的社会中,要取得相对的信任几乎已经是一件难上加难的事了,如此一来我们又该以什么准则来做为人与人之间互动往来,合作交易的基准点呢?

    + +

    从1985年的十信事件、1998年国扬以及新巨群等大型地雷股事件,一直到2004年博达掏空案,这一些大型企业一再的在侵蚀民众的血汗,同时也不断的在动摇人民对这些企业的信任。

    + +

    在经历遭受SARS冲击的时候,而台湾护理人员却在第一时间拒绝看护隔离病患,而另一位生命垂危的邱小妹却被松散的医疗体系与丧失医德的医疗人员当成人球转运,甚或是对婴儿打错针;对女研究生割错卵巢等等事件,实在是已经让台湾民众开始对于这些所谓的专业的信任大大的打了一个折扣。

    + +

    至于我们的政府呢!信任绝非只是两人象徵性的握握手或是送幅书法,在上面书写著真诚二字便可以此为凭,日月可鉴!

    + +

    也绝非今天告诉人民说我们要提升台湾国际间的竞争力,让台湾走出去,但是明天却又必须基于政党利益的考量,又将台湾闭锁于国际局势之外。

    + +

    然而另一个让人感到难过却也最感无力的是,台湾的媒体却是上述这些问题的伴随者,甚或是效果扩散的催化者,全世界尚未看到有任何一个国家在此小小的岛屿上密布著如此惊人的各式媒体,新闻充斥到令人感到难受,不论是什么样形式的媒体,当天真正有用且值得阅读的新闻可能仅有1/2而已,其他1/2不是追逐社会血腥八卦,便是漫无边际的口水政治,媒体为了创造收视率可以不断的重播渲染,同时向下刨根,因此不论是璩美凤或是薛凯莉;不论是妃鸿恋还是倪夏事件,不仅让当事人体无完肤,更让我们的社会感到面目可憎。

    + +

    其实在我们的脑海中依稀还印存著,当年还仅有三台电视两份报纸的时代,画面虽然是黑白的,但是黑白分明,那个年代的新闻媒体虽然还是相当受控闭锁,但是却多了一点人性的感动,如过您还记得民国58年台视首播八点档的连续剧晶晶,或是当年台湾金龙少棒队远赴美国宾州威廉波特参加世界少棒赛一举赢得冠军,从此掀起台湾棒球运动的热潮,这些种种的画面都记录著那个时代下的感动,对于当年的媒体来说,所能传递的资讯或许是单薄了许多,但是所能留下的记忆内容却是深刻多了。

    + +

    当年的人们对于媒体或许无知,也或许不可知,更或许是不得而知,但是基本上所得到的却是相对的单纯与可信任。只是随著时光的流转,经济的成长,民智的开放,科技的日新与政治的解禁,当一切似乎都朝著阳光般的目标前进发展时,我们却渐渐的失去了从前那一份单纯的信任与快乐。

    + +

    最近由公共电视与中映电影联合制播了一支纪录台湾农村生活与环境的纪录片无米乐,片中的架构以台湾在即将面对WTO入会之后,台湾的农业将面临自由贸易的冲击,以及这一群一生以农为生,以稻米为生命的老农民们,他们又该怎么默然以对…

    + +

    刹那间令人觉得再一次看到了台湾人民最朴实、善良与真诚的一面,看到了这一群可爱的台湾农民对于这一片土地长期以来的依赖与信任,对于这样深刻纪录大地、人物与生命的影片,其真诚的感动不禁油然而生,而对于能够如此真诚的呈现,感动人心,却也是媒体独天独厚得以创造的优势。

    + +

    借一句德国管理大师 Reinhard k.Sprenger所说的铭言,信心如蜜,凡流过处必然甜美

    + +

    台湾的媒体!我们还剩下多少信任的存款,可供留传给下一代的子孙,自省与再付出,该是对于这一片土地与人民最佳的回馈。

    +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 7 | + 8 | + 9 | + 10 | + 11 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0009.html.zh-tw.html b/htdocs/imacat/me/diary/0009.html.zh-tw.html new file mode 120000 index 0000000..fe6eec4 --- /dev/null +++ b/htdocs/imacat/me/diary/0009.html.zh-tw.html @@ -0,0 +1 @@ +0009.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0009.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0009.html.zh-tw.xhtml new file mode 100644 index 0000000..5292020 --- /dev/null +++ b/htdocs/imacat/me/diary/0009.html.zh-tw.xhtml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷九

    + +
    + +
    + +
    +
    6.10.’05. 0:06am.
    + +

    依瑪貓國語教室 照樣造句

    + +

    引文出處:蘋果日報 2005-06-09 《社會追緝令》也多模擬演出 東森一度力挺王 突宣布節目腰斬 + +

    +

    …另名離職員工也表示,當記者質疑模擬新聞時,王育誠都會強調:它真的有發生,只是我們沒拍到!

    +
    + +

    照樣造句:

    + +
      +
    • 我昨天在我家頂樓看到外星人:它真的有發生,只是我們沒拍到!
    • + +
    • 昨天半夜鄧麗君的鬼魂顯靈,跟我說話:它真的有發生,只是我們沒拍到!
    • + +
    • 王育誠趁老婆出差,帶酒店小姐回家過夜:它真的有發生,只是我們沒拍到!
    • + +
    • 腳尾飯事件,王育誠不但從頭到尾知情,說謊,其實根本就是主使者:它真的有發生,只是我們沒拍到!
    • +
    + +

    嗯,通通都真的有發生,只是我們沒拍到。

    + +
    + +
    + +
    +
    6.5.’05. 11:44am.
    + +

    奇文共賞

    + +

    這一篇真的讓我看傻了。中時是國內數一數二的媒體大頭目。國內數一數二的媒體大頭目,反省媒體亂象,本來應該算是好事。不過,整篇文章,充滿著對媒體亂象的無力感。如果連國內數一數二的媒體大頭目,都充滿著對媒體的無力感的話,那我們這些升斗小民,還能說什麼呢?對一個媒體大頭目,一個真正的掌權者,我們期待的是自我檢討,甚至是宣示新的編輯政策,而不是像無力改變現狀的升斗小民一樣,虛無地哀聲嘆氣。因為他,就是那個最有能力改變現狀的人。

    + +

    看到郭大總輯哀聲嘆氣,讓我有種角色錯置的感覺。怎麼寫得事情和自己無關一樣?你,不就是你自己在抱怨的那個媒體嗎?

    + +
    +
    2005/06/03
    +

    懷疑的年代,冰封的信心

    +
    中時電子報總編輯 郭至禎
    + +

    --媒體的自醒--

    + +

    最近在這一期的天下雜誌中讀到了一篇為什麼現在信任這麼紅!

    + +

    文中提到,大家都說這是新一波的信任危機,全球企業、政治、社會正進入一個誰也不相信誰的新時代,從企業到專業團體與媒體,公信力紛紛大幅下降的新信任危機。

    + +

    誰說不是呢?如今上自人民與政府間,領導與被領導的信任度越來越薄弱;政黨與政黨間,協商與合作的任信基礎越來越不可信;下至公司企業的經營誠信也遭踐踏至已成昨日黃花;而更令人難過的是,乃至於一般民間人與人最基本的互信原則似乎也已遭破壞,在現今的社會中,要取得相對的信任幾乎已經是一件難上加難的事了,如此一來我們又該以什麼準則來做為人與人之間互動往來,合作交易的基準點呢?

    + +

    從1985年的十信事件、1998年國揚以及新巨群等大型地雷股事件,一直到2004年博達掏空案,這一些大型企業一再的在侵蝕民眾的血汗,同時也不斷的在動搖人民對這些企業的信任。

    + +

    在經歷遭受SARS衝擊的時候,而台灣護理人員卻在第一時間拒絕看護隔離病患,而另一位生命垂危的邱小妹卻被鬆散的醫療體系與喪失醫德的醫療人員當成人球轉運,甚或是對嬰兒打錯針;對女研究生割錯卵巢等等事件,實在是已經讓台灣民眾開始對於這些所謂的專業的信任大大的打了一個折扣。

    + +

    至於我們的政府呢!信任絕非只是兩人象徵性的握握手或是送幅書法,在上面書寫著真誠二字便可以此為憑,日月可鑑!

    + +

    也絕非今天告訴人民說我們要提升台灣國際間的競爭力,讓台灣走出去,但是明天卻又必須基於政黨利益的考量,又將台灣閉鎖於國際局勢之外。

    + +

    然而另一個讓人感到難過卻也最感無力的是,台灣的媒體卻是上述這些問題的伴隨者,甚或是效果擴散的催化者,全世界尚未看到有任何一個國家在此小小的島嶼上密佈著如此驚人的各式媒體,新聞充斥到令人感到難受,不論是什麼樣形式的媒體,當天真正有用且值得閱讀的新聞可能僅有1/2而已,其他1/2不是追逐社會血腥八卦,便是漫無邊際的口水政治,媒體為了創造收視率可以不斷的重播渲染,同時向下刨根,因此不論是璩美鳳或是薛凱莉;不論是妃鴻戀還是倪夏事件,不僅讓當事人體無完膚,更讓我們的社會感到面目可憎。

    + +

    其實在我們的腦海中依稀還印存著,當年還僅有三台電視兩份報紙的時代,畫面雖然是黑白的,但是黑白分明,那個年代的新聞媒體雖然還是相當受控閉鎖,但是卻多了一點人性的感動,如過您還記得民國58年台視首播八點檔的連續劇晶晶,或是當年台灣金龍少棒隊遠赴美國賓州威廉波特參加世界少棒賽一舉贏得冠軍,從此掀起台灣棒球運動的熱潮,這些種種的畫面都記錄著那個時代下的感動,對於當年的媒體來說,所能傳遞的資訊或許是單薄了許多,但是所能留下的記憶內容卻是深刻多了。

    + +

    當年的人們對於媒體或許無知,也或許不可知,更或許是不得而知,但是基本上所得到的卻是相對的單純與可信任。只是隨著時光的流轉,經濟的成長,民智的開放,科技的日新與政治的解禁,當一切似乎都朝著陽光般的目標前進發展時,我們卻漸漸的失去了從前那一份單純的信任與快樂。

    + +

    最近由公共電視與中映電影聯合製播了一支紀錄台灣農村生活與環境的紀錄片無米樂,片中的架構以台灣在即將面對WTO入會之後,台灣的農業將面臨自由貿易的衝擊,以及這一群一生以農為生,以稻米為生命的老農民們,他們又該怎麼默然以對…

    + +

    剎那間令人覺得再一次看到了台灣人民最樸實、善良與真誠的一面,看到了這一群可愛的台灣農民對於這一片土地長期以來的依賴與信任,對於這樣深刻紀錄大地、人物與生命的影片,其真誠的感動不禁油然而生,而對於能夠如此真誠的呈現,感動人心,卻也是媒體獨天獨厚得以創造的優勢。

    + +

    借一句德國管理大師 Reinhard k.Sprenger所說的銘言,信心如蜜,凡流過處必然甜美

    + +

    台灣的媒體!我們還剩下多少信任的存款,可供留傳給下一代的子孫,自省與再付出,該是對於這一片土地與人民最佳的回饋。

    +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 7 | + 8 | + 9 | + 10 | + 11 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0010.html.en.html b/htdocs/imacat/me/diary/0010.html.en.html new file mode 120000 index 0000000..bf86cc6 --- /dev/null +++ b/htdocs/imacat/me/diary/0010.html.en.html @@ -0,0 +1 @@ +0010.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0010.html.en.xhtml b/htdocs/imacat/me/diary/0010.html.en.xhtml new file mode 100644 index 0000000..9b3666c --- /dev/null +++ b/htdocs/imacat/me/diary/0010.html.en.xhtml @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 10 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 10

    + +
    + +
    + +
    +
    8.17.’05. 0:08am.
    + +
    +這兩天在讀這個暑假修的「政黨政治與民主發展」,稍為回顧了一下台灣民主發展的過程
    +正好馬英九的幕僚在推動國民黨中常委直選
    +
    +突然發現一個有趣的對比
    +十五年前, 1990 年前後,國民黨的第十四屆臨時中全會中
    +黨主席李登輝為了推動總統直選,推動台灣人民的民主改革
    +和李煥為首的非主流派鬥得如火如荼
    +當時馬英九只是一個法務部長
    +十五年後的今天,馬英九終於登上黨主席的位置
    +為了推動國民黨中常委直選,推動國民黨內的民主改革
    +與李煥為首的擁王派也是鬥得如火如荼
    +
    +馬英九不約而同,走上了李登輝民主改革的路
    +只不過李登輝上次推動的是台灣人民的政治民主
    +這次馬英九推動的是國民黨的黨內民主
    +
    +國民黨的黨內民主化,對台灣社會是很好的發展
    +對馬英九改革的決心,我也只能抱以熱烈的掌聲
    +然而,令人感嘆的是
    +國民黨內部,竟然比台灣社會落後了十五年 +
    + +
    + +
    + +
    +
    8.11.’05. 12:06pm.
    + +

    我果然還是沒有辦法玩 3D 遊戲。 ^^;

    + +

    昨天晚上試玩了全方位戰士 Full Spectrum Warrior ,聽說是由美軍正規訓練教材移植過來的,真的非常真實。不過玩了一個晚上,就頭暈、噁心。我是方向感很好的人,像 3D 遊戲那樣旋轉來旋轉去,很容易失去平衡,身體非常難過。

    + +

    現在的線上遊戲都是 3D 的,不知道為什麼有那麼多人都能一泡就泡好幾個月。這些人都是路癡,所以繞來繞去也沒有感覺嗎? ^^;

    + +

    祝大家情人節快樂~ *^_^*

    + +
    + +
    + +
    +
    7.26.’05. 6:35pm.
    + +
    +忘記她忘記她放棄她放棄她
    +你心裡只有我 不再有她
    +不想她不想她 不等她不等她
    +你已經愛上我了 不再愛她
    +
    +你醒來以後 就會看著我
    +眼神不再那麼空洞 像回憶什麼
    +你會有笑容 快樂輕鬆
    +想不起來曾經有人 讓你還再心痛
    +
    +你一看見我 會覺得感動
    +想要彌補冷落過我 努力更愛我
    +你會很溫柔 深情吻我
    +並且擦乾我的眼角 問我哭什麼
    +
    +不是她不是她 誰是她誰是她
    +你愛的就是我 哪來的她
    +沒有她沒有她 哪有她哪有她
    +你生命根本就不曾有她
    +
    +每一天對你說一遍
    +會不會真的就實現~~~~~ +
    + +
    + +
    + +
    +
    7.11.’05. 12:23pm.
    + +

    剛剛看新聞,看到一半喝的水差點噴出來。

    + +

    干他屁事?邱毅這個人真的太閒了。大概是太久沒上新聞了。上次上新聞是他離婚後,帶小孩去立法院上班開會。

    + +

    原文出處:蘋果日報 2005-07-11 娛樂版。若有版權問題,請隨時告知。

    + +
    +

    邱毅插嘴指王有預謀

    + +

    【李淑華.丁維莉╱台北報導】對王靜瑩擬訴諸離婚,也曾離婚的無黨籍立委邱毅昨質疑王靜瑩訴請離婚的手法設計的痕跡太深,自導自演簡直可比電影《史密斯任務》(Mr.&Mrs. Smith)。王靜瑩經紀公司昨怒斥邱毅所說,強調將保留法律追訴權。

    + +

    以《史密斯任務》比喻

    + +

    昨邱毅對於王靜瑩家暴事件突然有感而發,他表示王靜瑩事後錄音和接受媒體採訪的行徑,顯示她早有離婚密謀。

    + +

    他甚至質疑她故意以比小指的挑釁行為挑起吵架話題,自導自演討打,布局離婚。

    + +

    邱毅說,男女之間、夫妻之間,十年修得同船渡,百年修得共枕眠,不應該搞得像電影《史密斯任務》劇情一樣鬥來鬥去。

    + +

    邱毅今年三月才與第二任前妻謝京叡簽字離婚,期間雙方不但諜對諜,還傳出曾因為信用卡帳款互相拳打腳踢,對照他昨的陰謀論姻緣論,似乎是將心比心

    + +

    王靜瑩經紀人蔣承縉昨不悅地說:被打的人是王靜瑩,不是其他人,沒有人有資格替她發言,對於任何不實、中傷她的言論,我們都會保留法律追訴權。

    +
    + +
    + +
    + +
    +
    6.28.’05. 12:23pm.
    + +
    +想起一件往事
    +
    +我開始做旅舍的時候,那時候還是 Netscape 和 IE 的大戰
    +網路上到處都是
    +  Best Viewed with Netscape 3.0 建議用 Netscape 3.0 以上瀏覽器
    +  Best Viewed with Microsoft Internet Explorer 4.0 建議用 Microsoft Internet Explorer 4.0 以上瀏覽器
    +  ...
    +的標誌
    +我看到有人放了一個標誌,上面寫的是
    +  Best Viewed with Any Browser 建議使用各種瀏覽器
    +於是很高興地決定用這個
    +並且在我手上的那本 HTML 教材中
    +儘量避開用特定瀏覽器特有的 HTML 語法,只用共通的 HTML
    +我對我做的結果,非常滿意
    +
    +直到大約一年後,我才想到
    +「那就裝 Netscape 來玩玩看吧~」
    +裝上去以後,連上那時候的旅舍
    +我的臉整個綠了
    +完~全~亂七八糟
    +那時候的震憾,真的很大,久久無法言語
    +根本做不到 Best View with Any Browser 的網頁,我竟然把那個標誌掛了一年之久
    +我才發現,簡單一句 Best View with Any Browser
    +是那麼難的事
    +
    +我只好從零開始,慢慢摸索 Netscape 網頁顯示的性能
    +放下那本粗淺的 HTML 教材
    +到處去找 HTML 的標準在哪裏?網頁製作的標準又在哪裏?
    +心裏的一個問題不敢去想,卻又揮之不去
    +「除了 IE 和 Netscape 外,其它的瀏覽器呢?
    + 我到底有沒有資格稱 Best View with Any Browser 」
    +那個時候,才開始感覺到
    +世界之大,自己之渺小
    +
    +從那時候到現在,七、八年了
    +網頁標準的進步,不可同日而語
    +這幾年 CSS 普及了,要做 Best View with Any Browser 再也不是難事
    +我也快忘記這件往事了
    +
    +如果不是光提起的話~ ^_*' +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 8 | + 9 | + 10 | + 11 | + 12 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0010.html.zh-cn.html b/htdocs/imacat/me/diary/0010.html.zh-cn.html new file mode 120000 index 0000000..5b21356 --- /dev/null +++ b/htdocs/imacat/me/diary/0010.html.zh-cn.html @@ -0,0 +1 @@ +0010.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0010.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0010.html.zh-cn.xhtml new file mode 100644 index 0000000..22cf3ad --- /dev/null +++ b/htdocs/imacat/me/diary/0010.html.zh-cn.xhtml @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷十

    + +
    + +
    + +
    +
    8.17.’05. 0:08am.
    + +
    +这两天在读这个暑假修的「政党政治与民主发展」,稍为回顾了一下台湾民主发展的过程
    +正好马英九的幕僚在推动国民党中常委直选
    +
    +突然发现一个有趣的对比
    +十五年前, 1990 年前后,国民党的第十四届临时中全会中
    +党主席李登辉为了推动总统直选,推动台湾人民的民主改革
    +和李焕为首的非主流派斗得如火如荼
    +当时马英九只是一个法务部长
    +十五年后的今天,马英九终于登上党主席的位置
    +为了推动国民党中常委直选,推动国民党内的民主改革
    +与李焕为首的拥王派也是斗得如火如荼
    +
    +马英九不约而同,走上了李登辉民主改革的路
    +只不过李登辉上次推动的是台湾人民的政治民主
    +这次马英九推动的是国民党的党内民主
    +
    +国民党的党内民主化,对台湾社会是很好的发展
    +对马英九改革的决心,我也只能抱以热烈的掌声
    +然而,令人感叹的是
    +国民党内部,竟然比台湾社会落后了十五年 +
    + +
    + +
    + +
    +
    8.11.’05. 12:06pm.
    + +

    我果然还是没有办法玩 3D 游戏。 ^^;

    + +

    昨天晚上试玩了全方位战士 Full Spectrum Warrior ,听说是由美军正规训练教材移植过来的,真的非常真实。不过玩了一个晚上,就头晕、恶心。我是方向感很好的人,像 3D 游戏那样旋转来旋转去,很容易失去平衡,身体非常难过。

    + +

    现在的线上游戏都是 3D 的,不知道为什么有那么多人都能一泡就泡好几个月。这些人都是路痴,所以绕来绕去也没有感觉吗? ^^;

    + +

    祝大家情人节快乐~ *^_^*

    + +
    + +
    + +
    +
    7.26.’05. 6:35pm.
    + +
    +忘记她忘记她放弃她放弃她
    +你心里只有我 不再有她
    +不想她不想她 不等她不等她
    +你已经爱上我了 不再爱她
    +
    +你醒来以后 就会看著我
    +眼神不再那么空洞 像回忆什么
    +你会有笑容 快乐轻松
    +想不起来曾经有人 让你还再心痛
    +
    +你一看见我 会觉得感动
    +想要弥补冷落过我 努力更爱我
    +你会很温柔 深情吻我
    +并且擦乾我的眼角 问我哭什么
    +
    +不是她不是她 谁是她谁是她
    +你爱的就是我 哪来的她
    +没有她没有她 哪有她哪有她
    +你生命根本就不曾有她
    +
    +每一天对你说一遍
    +会不会真的就实现~~~~~ +
    + +
    + +
    + +
    +
    7.11.’05. 12:23pm.
    + +

    刚刚看新闻,看到一半喝的水差点喷出来。

    + +

    干他屁事?邱毅这个人真的太闲了。大概是太久没上新闻了。上次上新闻是他离婚后,带小孩去立法院上班开会。

    + +

    原文出处:苹果日报 2005-07-11 娱乐版。若有版权问题,请随时告知。

    + +
    +

    邱毅插嘴指王有预谋

    + +

    【李淑华.丁维莉╱台北报导】对王静莹拟诉诸离婚,也曾离婚的无党籍立委邱毅昨质疑王静莹诉请离婚的手法设计的痕迹太深,自导自演简直可比电影《史密斯任务》(Mr.&Mrs. Smith)。王静莹经纪公司昨怒斥邱毅所说,强调将保留法律追诉权。

    + +

    以《史密斯任务》比喻

    + +

    昨邱毅对于王静莹家暴事件突然有感而发,他表示王静莹事后录音和接受媒体采访的行径,显示她早有离婚密谋。

    + +

    他甚至质疑她故意以比小指的挑衅行为挑起吵架话题,自导自演讨打,布局离婚。

    + +

    邱毅说,男女之间、夫妻之间,十年修得同船渡,百年修得共枕眠,不应该搞得像电影《史密斯任务》剧情一样斗来斗去。

    + +

    邱毅今年三月才与第二任前妻谢京睿签字离婚,期间双方不但谍对谍,还传出曾因为信用卡帐款互相拳打脚踢,对照他昨的阴谋论姻缘论,似乎是将心比心

    + +

    王静莹经纪人蒋承缙昨不悦地说:被打的人是王静莹,不是其他人,没有人有资格替她发言,对于任何不实、中伤她的言论,我们都会保留法律追诉权。

    +
    + +
    + +
    + +
    +
    6.28.’05. 12:23pm.
    + +
    +想起一件往事
    +
    +我开始做旅舍的时候,那时候还是 Netscape 和 IE 的大战
    +网路上到处都是
    +  Best Viewed with Netscape 3.0 建议用 Netscape 3.0 以上浏览器
    +  Best Viewed with Microsoft Internet Explorer 4.0 建议用 Microsoft Internet Explorer 4.0 以上浏览器
    +  ...
    +的标志
    +我看到有人放了一个标志,上面写的是
    +  Best Viewed with Any Browser 建议使用各种浏览器
    +于是很高兴地决定用这个
    +并且在我手上的那本 HTML 教材中
    +尽量避开用特定浏览器特有的 HTML 语法,只用共通的 HTML
    +我对我做的结果,非常满意
    +
    +直到大约一年后,我才想到
    +「那就装 Netscape 来玩玩看吧~」
    +装上去以后,连上那时候的旅舍
    +我的脸整个绿了
    +完~全~乱七八糟
    +那时候的震憾,真的很大,久久无法言语
    +根本做不到 Best View with Any Browser 的网页,我竟然把那个标志挂了一年之久
    +我才发现,简单一句 Best View with Any Browser
    +是那么难的事
    +
    +我只好从零开始,慢慢摸索 Netscape 网页显示的性能
    +放下那本粗浅的 HTML 教材
    +到处去找 HTML 的标准在哪里?网页制作的标准又在哪里?
    +心里的一个问题不敢去想,却又挥之不去
    +「除了 IE 和 Netscape 外,其它的浏览器呢?
    + 我到底有没有资格称 Best View with Any Browser 」
    +那个时候,才开始感觉到
    +世界之大,自己之渺小
    +
    +从那时候到现在,七、八年了
    +网页标准的进步,不可同日而语
    +这几年 CSS 普及了,要做 Best View with Any Browser 再也不是难事
    +我也快忘记这件往事了
    +
    +如果不是光提起的话~ ^_*' +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 8 | + 9 | + 10 | + 11 | + 12 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0010.html.zh-tw.html b/htdocs/imacat/me/diary/0010.html.zh-tw.html new file mode 120000 index 0000000..61f46bc --- /dev/null +++ b/htdocs/imacat/me/diary/0010.html.zh-tw.html @@ -0,0 +1 @@ +0010.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0010.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0010.html.zh-tw.xhtml new file mode 100644 index 0000000..bf35272 --- /dev/null +++ b/htdocs/imacat/me/diary/0010.html.zh-tw.xhtml @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷十

    + +
    + +
    + +
    +
    8.17.’05. 0:08am.
    + +
    +這兩天在讀這個暑假修的「政黨政治與民主發展」,稍為回顧了一下台灣民主發展的過程
    +正好馬英九的幕僚在推動國民黨中常委直選
    +
    +突然發現一個有趣的對比
    +十五年前, 1990 年前後,國民黨的第十四屆臨時中全會中
    +黨主席李登輝為了推動總統直選,推動台灣人民的民主改革
    +和李煥為首的非主流派鬥得如火如荼
    +當時馬英九只是一個法務部長
    +十五年後的今天,馬英九終於登上黨主席的位置
    +為了推動國民黨中常委直選,推動國民黨內的民主改革
    +與李煥為首的擁王派也是鬥得如火如荼
    +
    +馬英九不約而同,走上了李登輝民主改革的路
    +只不過李登輝上次推動的是台灣人民的政治民主
    +這次馬英九推動的是國民黨的黨內民主
    +
    +國民黨的黨內民主化,對台灣社會是很好的發展
    +對馬英九改革的決心,我也只能抱以熱烈的掌聲
    +然而,令人感嘆的是
    +國民黨內部,竟然比台灣社會落後了十五年 +
    + +
    + +
    + +
    +
    8.11.’05. 12:06pm.
    + +

    我果然還是沒有辦法玩 3D 遊戲。 ^^;

    + +

    昨天晚上試玩了全方位戰士 Full Spectrum Warrior ,聽說是由美軍正規訓練教材移植過來的,真的非常真實。不過玩了一個晚上,就頭暈、噁心。我是方向感很好的人,像 3D 遊戲那樣旋轉來旋轉去,很容易失去平衡,身體非常難過。

    + +

    現在的線上遊戲都是 3D 的,不知道為什麼有那麼多人都能一泡就泡好幾個月。這些人都是路癡,所以繞來繞去也沒有感覺嗎? ^^;

    + +

    祝大家情人節快樂~ *^_^*

    + +
    + +
    + +
    +
    7.26.’05. 6:35pm.
    + +
    +忘記她忘記她放棄她放棄她
    +你心裡只有我 不再有她
    +不想她不想她 不等她不等她
    +你已經愛上我了 不再愛她
    +
    +你醒來以後 就會看著我
    +眼神不再那麼空洞 像回憶什麼
    +你會有笑容 快樂輕鬆
    +想不起來曾經有人 讓你還再心痛
    +
    +你一看見我 會覺得感動
    +想要彌補冷落過我 努力更愛我
    +你會很溫柔 深情吻我
    +並且擦乾我的眼角 問我哭什麼
    +
    +不是她不是她 誰是她誰是她
    +你愛的就是我 哪來的她
    +沒有她沒有她 哪有她哪有她
    +你生命根本就不曾有她
    +
    +每一天對你說一遍
    +會不會真的就實現~~~~~ +
    + +
    + +
    + +
    +
    7.11.’05. 12:23pm.
    + +

    剛剛看新聞,看到一半喝的水差點噴出來。

    + +

    干他屁事?邱毅這個人真的太閒了。大概是太久沒上新聞了。上次上新聞是他離婚後,帶小孩去立法院上班開會。

    + +

    原文出處:蘋果日報 2005-07-11 娛樂版。若有版權問題,請隨時告知。

    + +
    +

    邱毅插嘴指王有預謀

    + +

    【李淑華.丁維莉╱台北報導】對王靜瑩擬訴諸離婚,也曾離婚的無黨籍立委邱毅昨質疑王靜瑩訴請離婚的手法設計的痕跡太深,自導自演簡直可比電影《史密斯任務》(Mr.&Mrs. Smith)。王靜瑩經紀公司昨怒斥邱毅所說,強調將保留法律追訴權。

    + +

    以《史密斯任務》比喻

    + +

    昨邱毅對於王靜瑩家暴事件突然有感而發,他表示王靜瑩事後錄音和接受媒體採訪的行徑,顯示她早有離婚密謀。

    + +

    他甚至質疑她故意以比小指的挑釁行為挑起吵架話題,自導自演討打,布局離婚。

    + +

    邱毅說,男女之間、夫妻之間,十年修得同船渡,百年修得共枕眠,不應該搞得像電影《史密斯任務》劇情一樣鬥來鬥去。

    + +

    邱毅今年三月才與第二任前妻謝京叡簽字離婚,期間雙方不但諜對諜,還傳出曾因為信用卡帳款互相拳打腳踢,對照他昨的陰謀論姻緣論,似乎是將心比心

    + +

    王靜瑩經紀人蔣承縉昨不悅地說:被打的人是王靜瑩,不是其他人,沒有人有資格替她發言,對於任何不實、中傷她的言論,我們都會保留法律追訴權。

    +
    + +
    + +
    + +
    +
    6.28.’05. 12:23pm.
    + +
    +想起一件往事
    +
    +我開始做旅舍的時候,那時候還是 Netscape 和 IE 的大戰
    +網路上到處都是
    +  Best Viewed with Netscape 3.0 建議用 Netscape 3.0 以上瀏覽器
    +  Best Viewed with Microsoft Internet Explorer 4.0 建議用 Microsoft Internet Explorer 4.0 以上瀏覽器
    +  ...
    +的標誌
    +我看到有人放了一個標誌,上面寫的是
    +  Best Viewed with Any Browser 建議使用各種瀏覽器
    +於是很高興地決定用這個
    +並且在我手上的那本 HTML 教材中
    +儘量避開用特定瀏覽器特有的 HTML 語法,只用共通的 HTML
    +我對我做的結果,非常滿意
    +
    +直到大約一年後,我才想到
    +「那就裝 Netscape 來玩玩看吧~」
    +裝上去以後,連上那時候的旅舍
    +我的臉整個綠了
    +完~全~亂七八糟
    +那時候的震憾,真的很大,久久無法言語
    +根本做不到 Best View with Any Browser 的網頁,我竟然把那個標誌掛了一年之久
    +我才發現,簡單一句 Best View with Any Browser
    +是那麼難的事
    +
    +我只好從零開始,慢慢摸索 Netscape 網頁顯示的性能
    +放下那本粗淺的 HTML 教材
    +到處去找 HTML 的標準在哪裏?網頁製作的標準又在哪裏?
    +心裏的一個問題不敢去想,卻又揮之不去
    +「除了 IE 和 Netscape 外,其它的瀏覽器呢?
    + 我到底有沒有資格稱 Best View with Any Browser 」
    +那個時候,才開始感覺到
    +世界之大,自己之渺小
    +
    +從那時候到現在,七、八年了
    +網頁標準的進步,不可同日而語
    +這幾年 CSS 普及了,要做 Best View with Any Browser 再也不是難事
    +我也快忘記這件往事了
    +
    +如果不是光提起的話~ ^_*' +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 8 | + 9 | + 10 | + 11 | + 12 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0011.html.en.html b/htdocs/imacat/me/diary/0011.html.en.html new file mode 120000 index 0000000..3fbb0db --- /dev/null +++ b/htdocs/imacat/me/diary/0011.html.en.html @@ -0,0 +1 @@ +0011.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0011.html.en.xhtml b/htdocs/imacat/me/diary/0011.html.en.xhtml new file mode 100644 index 0000000..82dbcf9 --- /dev/null +++ b/htdocs/imacat/me/diary/0011.html.en.xhtml @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 11 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 11

    + +
    + +
    + +
    +
    8.27.’05. 1:44pm.
    + +

    台灣的兩兆雙星計劃(兩個產值可達一兆的產業:半導體和 LCD ,以及兩個明日之星產業:數位內容和生物科技),繼前兩年 LCD 產業在全球大紅大紫後,現在生物科技產業也已經開花結果了~~ ^_^

    + +

    獨步全球的生物科技技術耶~台灣加油加油~ *^_^*

    + +

    原文轉自蘋果日報 2005-08-27。若有版權問題,請隨時告知

    + +
    +

    我複製經濟動物大突破
    +可穩定複製下一代 總統9月宣布

    + +

    【鄭智仁╱台北報導】台灣複製動物技術可望出現突破性進展,農委會主委李金龍昨說,經多年努力,已成功研發兼具經濟價值與醫學功能的動物複製技術;但該項成果必須等到九月初,由陳水扁總統親自宣布。

    + +

    七月即有具體成果

    + +

    據了解這項研究大約在七月就有具體成果,但因事涉重大,有可能成為獨步全球新技術,相關人士在未正式發表前,一律封口。就農委會畜產試驗所過去的研究紀錄看,該成果可能與牛隻或羊隻可穩定複製下一代技術有關。

    + +

    負責該項計劃的屏東科技大學畜產系助理教授沈朋志受訪時坦承,屆時將列席發表成果,但不適合提前曝光;他是去年五月畜試所發表國內首個複製牛如意家族的關鍵人物。李金龍口中所謂的重大突破經濟動物極可能為乳牛或乳羊。

    + +

    國內過去已成功複製豬、羊及乳牛。其中,去年公開亮相的乳牛如意三號是以冷凍的複製胚經解凍後,再進行移植胚而完成,成功突破複製只能採新鮮胚的困境;透過液化氮冷凍技術,種原細胞保存期限可無限延長,等於有一個取之不盡的複製寶庫

    + +

    沈朋志說,種原保存技術已臻成熟,但問題在於:什麼樣的種原值得繼續保存下去?李金龍說,複製親代沒問題,但繼續繁衍或複製下一代,就可能會有優良性狀表現不盡如意或不完整的現象;據了解這次的突破,即與可成功複製下一代優良品系有關。

    + +

    優良品性得以保留

    + +

    李金龍舉例說,若是高泌乳量的親代乳牛,繁衍或複製子代時,高泌乳量依舊存在,就是一個重大突破,因為這樣一來,只要保存好一頭超完美乳牛,未來的每一隻複製牛,優良的品性都得以重複出現。

    + +

    畜試所副所長李善男說,複製技術未來的遠景在於可利用複製動物作為技術平台;也就是說,未來可以作為生產人類醫用蛋白質的生物工廠,還可用於人類胚幹細胞的研究,生產個人專屬的胚幹細胞庫,提供基因治療或器官移植所需的細胞來源。李金龍舉例:可把抗乳鐵蛋白、抗白血病基因植入,大量複製,當然有其重大意義

    + + +

    台灣複製動物事件簿

    + +
    +
    2002/02/15 豬
    + +
    利用乳鐵蛋白及人類凝血第九因子的雙基因轉殖,為全球第一頭雙基因轉殖複製豬,命名為酷比豬
    + +
    2002/07/05 羊
    + +
    以阿爾拜因乳羊耳朵細胞為供核源,由代孕母羊產雙胎複製羊。
    + +
    2003/08/12 牛
    + +
    牛耳朵細胞複製,以黃牛為代理孕母產下複製牛名為如意
    +
    + +

    資料來源:農委會、中華民國科學技術年鑑

    +
    + +
    + +
    + +
    +
    8.27.’05. 1:30pm.
    + +
    +2000-09-13 ,景文高中陳同學,下雨天背著罹瘓玻璃娃娃症的顏同學上體育課
    +結果不慎跌跤,顏同學因此死亡
    +顏家因此告上景文高中和熱心助人的陳同學
    +五年後 2005-08-24 ,法院判決景文高中和熱心助人的陳同學敗訴
    +「法官認為,如何妥適照顧殘障人士,是相當專業的工作,陳姓學生並不是專業工作者,未量力而為」
    +須賠償顏父192萬3528元、顏母141萬4508元
    +引起社會譁然
    +
    +顏家事後說,本來只是要告景文高中,可是一審敗訴
    +律師認為是因沒有當事人之故,要連當事人一起告才有勝訴希望
    +於是把陳同學和老師一起連帶提出告訴
    +
    +這個理由真的太扯了
    +就算顏家說的是真的
    +再怎麼說,律師只是協助當事人,提出建議
    +最後做決定的還是當事人,不是律師
    +就以這個案子來說,陳家還是可以決定
    +選擇執意追求死去的顏同學的正義,甚至不惜牽連無辜的陳同學
    +或是選擇為了避免殃及無辜,而放棄自己的正義?
    +
    +律師只是做出專業的法律建議,提出最適於勝訴的策略
    +但要不要採納該建議,要不要禍及無辜的老師同學,還是當事人顏家的決定
    +把禍及無辜的責任推給律師,推給司法制度
    +顏家完全是不負責任的態度 +
    + +
    + +
    + +
    +
    8.25.’05. 8:17am.
    + +
    +發現一個很酷的網站,之前好像是在蘋果日報上看到的
    +SuicideGirls 自殺女孩 http://suicidegirls.com/
    +不只是個色情網站,還是一種很酷的生活方式~
    +
    +不過好像是要收費的
    +等我有空仔細逛了,再寫介紹吧~ ^_*' +
    + +
    + +
    + +
    +
    8.22.’05. 5:46am.
    + +
    +昨天花了一整天,看了一堆電腦遊戲業界的八卦
    +《柏德之門》金三角 Interplay 、 Black Isle 和 Bioware 間的聚散浮沉
    +《創世紀》系列作者 Richard Garriot 目前的最新動態
    +
    +原來《柏德之門》、《冰風之谷》的背後,有這麼一段不為人道的故事
    +《柏德之門》的系列作品已經畫下休止符了
    +覺得有點可惜
    +Richard Garriot 目前投身在《天堂》的公司 NCSoft 下,做另一款 3D 網路遊戲《 Tabula Rasa 》
    +可惜我不玩 3D ,也不玩網路遊戲
    +所以大概無緣吧
    +
    +這一陣子在蒐集 AD&D SSI 金盒子系列的老遊戲
    +1988 光芒之池 Pool of Radiance
    +1989 青色枷的詛咒 Curse of the Azure Bonds
    +1990 銀色匕首之謎 Secret of the Silver Blades
    +...
    +
    +之前已經蒐集到完整的創世紀系列了
    +Akalabet + Ultima 1-9
    +我現在只玩到 Akalabet + Ultima 1-3
    +不知道什麼時候才有時間玩完
    +不過我想能蒐集到完整全套創世紀,還是很值得炫耀的事吧~ *^_^* +
    + +
    + +
    + +
    +
    8.20.’05. 11:42pm.
    + +
    +花了一天半整理了一堆下載下來的檔案
    +虛擬光碟啦, Mac 模擬器啦,有的沒有的
    +好可怕... 我不知不覺中下載了那麼多東西
    +呵呵 ^^; +
    + +
    + +
    + +
    +
    8.20.’05. 1:21pm.
    + +
    +我覺得馬英九真的會完蛋
    +
    +就看著好了
    +這兩天為了接任國民黨主席,台北市政都放著不管
    +華陰街變電所光氣外洩,光氣是二戰時期的劇毒毒氣,光氣外洩是多嚴重的一件事
    +可是他只說了一句「依法辦理」,就跑掉了
    +留著衛生局和捷運局,惡搞可憐的小老百姓
    +現在又是台北市警局警員花錢買績效
    +市府路封路塞車的事,他承諾再也不為了辦活動封路,結果還是封路了,他也沒出來說句話
    +
    +他再把台北市政放著不管看看嘛
    +這些事情累積下來
    +我看他年底怎麼選
    +
    +有點小火大 +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 9 | + 10 | + 11 | + 12 | + 13 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0011.html.zh-cn.html b/htdocs/imacat/me/diary/0011.html.zh-cn.html new file mode 120000 index 0000000..e64f62e --- /dev/null +++ b/htdocs/imacat/me/diary/0011.html.zh-cn.html @@ -0,0 +1 @@ +0011.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0011.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0011.html.zh-cn.xhtml new file mode 100644 index 0000000..a6392b7 --- /dev/null +++ b/htdocs/imacat/me/diary/0011.html.zh-cn.xhtml @@ -0,0 +1,324 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷十一

    + +
    + +
    + +
    +
    8.27.’05. 1:44pm.
    + +

    台湾的两兆双星计划(两个产值可达一兆的产业:半导体和 LCD ,以及两个明日之星产业:数位内容和生物科技),继前两年 LCD 产业在全球大红大紫后,现在生物科技产业也已经开花结果了~~ ^_^

    + +

    独步全球的生物科技技术耶~台湾加油加油~ *^_^*

    + +

    原文转自苹果日报 2005-08-27。若有版权问题,请随时告知

    + +
    +

    我复制经济动物大突破
    +可稳定复制下一代 总统9月宣布

    + +

    【郑智仁╱台北报导】台湾复制动物技术可望出现突破性进展,农委会主委李金龙昨说,经多年努力,已成功研发兼具经济价值与医学功能的动物复制技术;但该项成果必须等到九月初,由陈水扁总统亲自宣布。

    + +

    七月即有具体成果

    + +

    据了解这项研究大约在七月就有具体成果,但因事涉重大,有可能成为独步全球新技术,相关人士在未正式发表前,一律封口。就农委会畜产试验所过去的研究纪录看,该成果可能与牛只或羊只可稳定复制下一代技术有关。

    + +

    负责该项计划的屏东科技大学畜产系助理教授沈朋志受访时坦承,届时将列席发表成果,但不适合提前曝光;他是去年五月畜试所发表国内首个复制牛如意家族的关键人物。李金龙口中所谓的重大突破经济动物极可能为乳牛或乳羊。

    + +

    国内过去已成功复制猪、羊及乳牛。其中,去年公开亮相的乳牛如意三号是以冷冻的复制胚经解冻后,再进行移植胚而完成,成功突破复制只能采新鲜胚的困境;透过液化氮冷冻技术,种原细胞保存期限可无限延长,等于有一个取之不尽的复制宝库

    + +

    沈朋志说,种原保存技术已臻成熟,但问题在于:什么样的种原值得继续保存下去?李金龙说,复制亲代没问题,但继续繁衍或复制下一代,就可能会有优良性状表现不尽如意或不完整的现象;据了解这次的突破,即与可成功复制下一代优良品系有关。

    + +

    优良品性得以保留

    + +

    李金龙举例说,若是高泌乳量的亲代乳牛,繁衍或复制子代时,高泌乳量依旧存在,就是一个重大突破,因为这样一来,只要保存好一头超完美乳牛,未来的每一只复制牛,优良的品性都得以重复出现。

    + +

    畜试所副所长李善男说,复制技术未来的远景在于可利用复制动物作为技术平台;也就是说,未来可以作为生产人类医用蛋白质的生物工厂,还可用于人类胚干细胞的研究,生产个人专属的胚干细胞库,提供基因治疗或器官移植所需的细胞来源。李金龙举例:可把抗乳铁蛋白、抗白血病基因植入,大量复制,当然有其重大意义

    + + +

    台湾复制动物事件簿

    + +
    +
    2002/02/15 猪
    + +
    利用乳铁蛋白及人类凝血第九因子的双基因转殖,为全球第一头双基因转殖复制猪,命名为酷比猪
    + +
    2002/07/05 羊
    + +
    以阿尔拜因乳羊耳朵细胞为供核源,由代孕母羊产双胎复制羊。
    + +
    2003/08/12 牛
    + +
    牛耳朵细胞复制,以黄牛为代理孕母产下复制牛名为如意
    +
    + +

    资料来源:农委会、中华民国科学技术年鉴

    +
    + +
    + +
    + +
    +
    8.27.’05. 1:30pm.
    + +
    +2000-09-13 ,景文高中陈同学,下雨天背著罹痪玻璃娃娃症的颜同学上体育课
    +结果不慎跌跤,颜同学因此死亡
    +颜家因此告上景文高中和热心助人的陈同学
    +五年后 2005-08-24 ,法院判决景文高中和热心助人的陈同学败诉
    +「法官认为,如何妥适照顾残障人士,是相当专业的工作,陈姓学生并不是专业工作者,未量力而为」
    +须赔偿颜父192万3528元、颜母141万4508元
    +引起社会哗然
    +
    +颜家事后说,本来只是要告景文高中,可是一审败诉
    +律师认为是因没有当事人之故,要连当事人一起告才有胜诉希望
    +于是把陈同学和老师一起连带提出告诉
    +
    +这个理由真的太扯了
    +就算颜家说的是真的
    +再怎么说,律师只是协助当事人,提出建议
    +最后做决定的还是当事人,不是律师
    +就以这个案子来说,陈家还是可以决定
    +选择执意追求死去的颜同学的正义,甚至不惜牵连无辜的陈同学
    +或是选择为了避免殃及无辜,而放弃自己的正义?
    +
    +律师只是做出专业的法律建议,提出最适于胜诉的策略
    +但要不要采纳该建议,要不要祸及无辜的老师同学,还是当事人颜家的决定
    +把祸及无辜的责任推给律师,推给司法制度
    +颜家完全是不负责任的态度 +
    + +
    + +
    + +
    +
    8.25.’05. 8:17am.
    + +
    +发现一个很酷的网站,之前好像是在苹果日报上看到的
    +SuicideGirls 自杀女孩 http://suicidegirls.com/
    +不只是个色情网站,还是一种很酷的生活方式~
    +
    +不过好像是要收费的
    +等我有空仔细逛了,再写介绍吧~ ^_*' +
    + +
    + +
    + +
    +
    8.22.’05. 5:46am.
    + +
    +昨天花了一整天,看了一堆电脑游戏业界的八卦
    +《柏德之门》金三角 Interplay 、 Black Isle 和 Bioware 间的聚散浮沉
    +《创世纪》系列作者 Richard Garriot 目前的最新动态
    +
    +原来《柏德之门》、《冰风之谷》的背后,有这么一段不为人道的故事
    +《柏德之门》的系列作品已经画下休止符了
    +觉得有点可惜
    +Richard Garriot 目前投身在《天堂》的公司 NCSoft 下,做另一款 3D 网路游戏《 Tabula Rasa 》
    +可惜我不玩 3D ,也不玩网路游戏
    +所以大概无缘吧
    +
    +这一阵子在蒐集 AD&D SSI 金盒子系列的老游戏
    +1988 光芒之池 Pool of Radiance
    +1989 青色枷的诅咒 Curse of the Azure Bonds
    +1990 银色匕首之谜 Secret of the Silver Blades
    +...
    +
    +之前已经蒐集到完整的创世纪系列了
    +Akalabet + Ultima 1-9
    +我现在只玩到 Akalabet + Ultima 1-3
    +不知道什么时候才有时间玩完
    +不过我想能蒐集到完整全套创世纪,还是很值得炫耀的事吧~ *^_^* +
    + +
    + +
    + +
    +
    8.20.’05. 11:42pm.
    + +
    +花了一天半整理了一堆下载下来的档案
    +虚拟光碟啦, Mac 模拟器啦,有的没有的
    +好可怕... 我不知不觉中下载了那么多东西
    +呵呵 ^^; +
    + +
    + +
    + +
    +
    8.20.’05. 1:21pm.
    + +
    +我觉得马英九真的会完蛋
    +
    +就看著好了
    +这两天为了接任国民党主席,台北市政都放著不管
    +华阴街变电所光气外泄,光气是二战时期的剧毒毒气,光气外泄是多严重的一件事
    +可是他只说了一句「依法办理」,就跑掉了
    +留著卫生局和捷运局,恶搞可怜的小老百姓
    +现在又是台北市警局警员花钱买绩效
    +市府路封路塞车的事,他承诺再也不为了办活动封路,结果还是封路了,他也没出来说句话
    +
    +他再把台北市政放著不管看看嘛
    +这些事情累积下来
    +我看他年底怎么选
    +
    +有点小火大 +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 9 | + 10 | + 11 | + 12 | + 13 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0011.html.zh-tw.html b/htdocs/imacat/me/diary/0011.html.zh-tw.html new file mode 120000 index 0000000..7882a54 --- /dev/null +++ b/htdocs/imacat/me/diary/0011.html.zh-tw.html @@ -0,0 +1 @@ +0011.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0011.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0011.html.zh-tw.xhtml new file mode 100644 index 0000000..2a33602 --- /dev/null +++ b/htdocs/imacat/me/diary/0011.html.zh-tw.xhtml @@ -0,0 +1,324 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷十一

    + +
    + +
    + +
    +
    8.27.’05. 1:44pm.
    + +

    台灣的兩兆雙星計劃(兩個產值可達一兆的產業:半導體和 LCD ,以及兩個明日之星產業:數位內容和生物科技),繼前兩年 LCD 產業在全球大紅大紫後,現在生物科技產業也已經開花結果了~~ ^_^

    + +

    獨步全球的生物科技技術耶~台灣加油加油~ *^_^*

    + +

    原文轉自蘋果日報 2005-08-27。若有版權問題,請隨時告知

    + +
    +

    我複製經濟動物大突破
    +可穩定複製下一代 總統9月宣布

    + +

    【鄭智仁╱台北報導】台灣複製動物技術可望出現突破性進展,農委會主委李金龍昨說,經多年努力,已成功研發兼具經濟價值與醫學功能的動物複製技術;但該項成果必須等到九月初,由陳水扁總統親自宣布。

    + +

    七月即有具體成果

    + +

    據了解這項研究大約在七月就有具體成果,但因事涉重大,有可能成為獨步全球新技術,相關人士在未正式發表前,一律封口。就農委會畜產試驗所過去的研究紀錄看,該成果可能與牛隻或羊隻可穩定複製下一代技術有關。

    + +

    負責該項計劃的屏東科技大學畜產系助理教授沈朋志受訪時坦承,屆時將列席發表成果,但不適合提前曝光;他是去年五月畜試所發表國內首個複製牛如意家族的關鍵人物。李金龍口中所謂的重大突破經濟動物極可能為乳牛或乳羊。

    + +

    國內過去已成功複製豬、羊及乳牛。其中,去年公開亮相的乳牛如意三號是以冷凍的複製胚經解凍後,再進行移植胚而完成,成功突破複製只能採新鮮胚的困境;透過液化氮冷凍技術,種原細胞保存期限可無限延長,等於有一個取之不盡的複製寶庫

    + +

    沈朋志說,種原保存技術已臻成熟,但問題在於:什麼樣的種原值得繼續保存下去?李金龍說,複製親代沒問題,但繼續繁衍或複製下一代,就可能會有優良性狀表現不盡如意或不完整的現象;據了解這次的突破,即與可成功複製下一代優良品系有關。

    + +

    優良品性得以保留

    + +

    李金龍舉例說,若是高泌乳量的親代乳牛,繁衍或複製子代時,高泌乳量依舊存在,就是一個重大突破,因為這樣一來,只要保存好一頭超完美乳牛,未來的每一隻複製牛,優良的品性都得以重複出現。

    + +

    畜試所副所長李善男說,複製技術未來的遠景在於可利用複製動物作為技術平台;也就是說,未來可以作為生產人類醫用蛋白質的生物工廠,還可用於人類胚幹細胞的研究,生產個人專屬的胚幹細胞庫,提供基因治療或器官移植所需的細胞來源。李金龍舉例:可把抗乳鐵蛋白、抗白血病基因植入,大量複製,當然有其重大意義

    + + +

    台灣複製動物事件簿

    + +
    +
    2002/02/15 豬
    + +
    利用乳鐵蛋白及人類凝血第九因子的雙基因轉殖,為全球第一頭雙基因轉殖複製豬,命名為酷比豬
    + +
    2002/07/05 羊
    + +
    以阿爾拜因乳羊耳朵細胞為供核源,由代孕母羊產雙胎複製羊。
    + +
    2003/08/12 牛
    + +
    牛耳朵細胞複製,以黃牛為代理孕母產下複製牛名為如意
    +
    + +

    資料來源:農委會、中華民國科學技術年鑑

    +
    + +
    + +
    + +
    +
    8.27.’05. 1:30pm.
    + +
    +2000-09-13 ,景文高中陳同學,下雨天背著罹瘓玻璃娃娃症的顏同學上體育課
    +結果不慎跌跤,顏同學因此死亡
    +顏家因此告上景文高中和熱心助人的陳同學
    +五年後 2005-08-24 ,法院判決景文高中和熱心助人的陳同學敗訴
    +「法官認為,如何妥適照顧殘障人士,是相當專業的工作,陳姓學生並不是專業工作者,未量力而為」
    +須賠償顏父192萬3528元、顏母141萬4508元
    +引起社會譁然
    +
    +顏家事後說,本來只是要告景文高中,可是一審敗訴
    +律師認為是因沒有當事人之故,要連當事人一起告才有勝訴希望
    +於是把陳同學和老師一起連帶提出告訴
    +
    +這個理由真的太扯了
    +就算顏家說的是真的
    +再怎麼說,律師只是協助當事人,提出建議
    +最後做決定的還是當事人,不是律師
    +就以這個案子來說,陳家還是可以決定
    +選擇執意追求死去的顏同學的正義,甚至不惜牽連無辜的陳同學
    +或是選擇為了避免殃及無辜,而放棄自己的正義?
    +
    +律師只是做出專業的法律建議,提出最適於勝訴的策略
    +但要不要採納該建議,要不要禍及無辜的老師同學,還是當事人顏家的決定
    +把禍及無辜的責任推給律師,推給司法制度
    +顏家完全是不負責任的態度 +
    + +
    + +
    + +
    +
    8.25.’05. 8:17am.
    + +
    +發現一個很酷的網站,之前好像是在蘋果日報上看到的
    +SuicideGirls 自殺女孩 http://suicidegirls.com/
    +不只是個色情網站,還是一種很酷的生活方式~
    +
    +不過好像是要收費的
    +等我有空仔細逛了,再寫介紹吧~ ^_*' +
    + +
    + +
    + +
    +
    8.22.’05. 5:46am.
    + +
    +昨天花了一整天,看了一堆電腦遊戲業界的八卦
    +《柏德之門》金三角 Interplay 、 Black Isle 和 Bioware 間的聚散浮沉
    +《創世紀》系列作者 Richard Garriot 目前的最新動態
    +
    +原來《柏德之門》、《冰風之谷》的背後,有這麼一段不為人道的故事
    +《柏德之門》的系列作品已經畫下休止符了
    +覺得有點可惜
    +Richard Garriot 目前投身在《天堂》的公司 NCSoft 下,做另一款 3D 網路遊戲《 Tabula Rasa 》
    +可惜我不玩 3D ,也不玩網路遊戲
    +所以大概無緣吧
    +
    +這一陣子在蒐集 AD&D SSI 金盒子系列的老遊戲
    +1988 光芒之池 Pool of Radiance
    +1989 青色枷的詛咒 Curse of the Azure Bonds
    +1990 銀色匕首之謎 Secret of the Silver Blades
    +...
    +
    +之前已經蒐集到完整的創世紀系列了
    +Akalabet + Ultima 1-9
    +我現在只玩到 Akalabet + Ultima 1-3
    +不知道什麼時候才有時間玩完
    +不過我想能蒐集到完整全套創世紀,還是很值得炫耀的事吧~ *^_^* +
    + +
    + +
    + +
    +
    8.20.’05. 11:42pm.
    + +
    +花了一天半整理了一堆下載下來的檔案
    +虛擬光碟啦, Mac 模擬器啦,有的沒有的
    +好可怕... 我不知不覺中下載了那麼多東西
    +呵呵 ^^; +
    + +
    + +
    + +
    +
    8.20.’05. 1:21pm.
    + +
    +我覺得馬英九真的會完蛋
    +
    +就看著好了
    +這兩天為了接任國民黨主席,台北市政都放著不管
    +華陰街變電所光氣外洩,光氣是二戰時期的劇毒毒氣,光氣外洩是多嚴重的一件事
    +可是他只說了一句「依法辦理」,就跑掉了
    +留著衛生局和捷運局,惡搞可憐的小老百姓
    +現在又是台北市警局警員花錢買績效
    +市府路封路塞車的事,他承諾再也不為了辦活動封路,結果還是封路了,他也沒出來說句話
    +
    +他再把台北市政放著不管看看嘛
    +這些事情累積下來
    +我看他年底怎麼選
    +
    +有點小火大 +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 9 | + 10 | + 11 | + 12 | + 13 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0012.html.en.html b/htdocs/imacat/me/diary/0012.html.en.html new file mode 120000 index 0000000..6d499fd --- /dev/null +++ b/htdocs/imacat/me/diary/0012.html.en.html @@ -0,0 +1 @@ +0012.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0012.html.en.xhtml b/htdocs/imacat/me/diary/0012.html.en.xhtml new file mode 100644 index 0000000..e5310ea --- /dev/null +++ b/htdocs/imacat/me/diary/0012.html.en.xhtml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 12 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 12

    + +
    + +
    + +
    +
    8.31.’05. 1:06pm.
    + +

    最近發瘋了,卯起來蒐集古董遊戲。

    + +

    其實我很窮,看到舊舊的絕版包裝、說明書、光碟,也只能乾瞪眼、流口水。我能蒐集的,只有透過 eMule 、網路搜尋,蒐集不大花錢的舊遊戲的檔案。偶爾有點閒錢,才能東買一點、西買一點。

    + +

    可是光是這樣,就已經夠難了。我是創世紀 (Ultima) 的迷。前兩年在 eBay 上,買了一套台灣沒有上市的創世紀的大合輯。賣家不願寄到美國以外的地址,只好拜託我在紐約的妹妹先收,再轉寄過來。本來以為這樣已經齊全了,可是前幾天逛舊遊戲網站,發現創世紀還有兩套外傳流落在外:洪荒帝國 (The Savage Empire) 和火星之旅 (Martian Dreams) 。於是只好上 eMule 找,把能找到的版本都找來,互相比對,整理出最原始的版本。即使如此,創世紀七代第二部巨蛇之島 (Serpent Isle) ,我只找到加上資料片銀色種子 (The Silver Seed) 後的版本。未加資料片前的巨蛇之島原始版本,和資料片銀色種子獨立的安裝程式,卻是怎麼樣也找不到。

    + +

    前一陣子終於把五年前買的遊戲柏德之門 (Baldur's Gate) 破關了。回味劇情的同時,也上網找找發行商 Interplay 、製作小組黑島工作室 (Black Isle Studio) 和 Bioware 的最新消息,看有沒有後續的作品。沒想到意外發現 Black Isle Studio 和 Interplay 已經分別在 2001 年和 2004 年倒了!這麼好的遊戲,真是讓人難過的消息。在網上讀了幾篇來龍去脈,感嘆的同時,也起意尋找十年前龍與地下城 (Advance Dragons and Dungeons, AD&D) SSI 被遺忘的國度 (Forgotten Realms) 系列的舊作,和 Black Isle Studio 過去得獎無數的作品異塵餘生 (Fallout) 系列和異域鎮魂曲 (Planescape: Torment) 等。蒐集的過程中,我發現 1997 年 Interplay 剛取得 AD&D 授權的時候,曾經重新出版了一套過去 SSI 被遺忘的國度系列十二個遊戲大合輯。找了半天,才在 eBay 上找到一個英國二手遊戲商,手上有舊的說明書和光碟(包裝已經沒了),而且願意寄到亞洲來。只要弄到那套大合輯,就一口氣找齊十二個遊戲了。我趕緊刷卡刷了 24 塊錢英磅買下來,現在還在郵寄途中。

    + +

    我雖然是創世紀的迷,但其實是從創世紀七代黑月之門 (The Black Gate) 才開始認識、迷上創世紀的。我最早開始玩的角色扮演遊戲 RPG 其實不是創世紀,而是 AD&D 龍與地下城系列,從 1989 年的青色枷的詛咒 (Curse of the Azure Bonds) 開始玩。我最近想想,龍與地下城系列,也許比創世紀系列,對我有更多的回憶。

    + +

    一般公認史上最偉大的三大 RPG 為:創世紀系列 (UItima) 、巫術系列 (Wizardry) 和魔法門系列 (Might & Magic) 。不過我覺得應該把 AD&D 龍與地下城系列一起算進來,合稱史上最偉大的四大 RPG 才對。這四大 RPG ,除了巫術 (Wizardry) 以外,我都玩過了。可能是因為巫術在台灣沒有發行吧,我一直都只聞其名,未逢其盛。不過這四大 RPG 除了創世紀以線上創世紀 (Ultima Online) 網路遊戲存留下來, AD&D 的版權由 Infograms 買下來, Bioware 投靠 Infograms 繼續創作外,傳統的三大 RPG 創世紀系列、魔法門系列和巫術系列,都已經禁不住時間的考驗,一一倒下來了,讓人不勝欷噓。

    + +

    我不敢奢求有本事可以弄到那些舊舊的原始包裝、說明書、磁片和光碟。下載得到遊戲檔案,我就心滿意足了。存了這麼多,我也不知道什麼時候才有時間去玩。大概要等到我老了、退休了,當無聊老太婆的時候,才有空一個一個去玩吧。到那時候的未來電腦,還能跑這些舊遊戲嗎?我也不知道。不過光是弄到得來不易的遊戲檔案,就覺得好感動。我想這就是蒐集的樂趣吧~ ^_*'

    + +
    + +
    + +
    +
    8.28.’05. 7:35pm.
    + +

    不知道還有沒有人記得 Game & Watch ?

    + +

    不知道那是什麼嗎?就是小時候朋友會帶去學校互相交換,小小可以放在胸前口袋,形狀像名片一樣,用一個小圓電池,中間一個螢幕,兩旁兩個或四個按鈕,旁邊還有 A B 鈕的掌上型電動玩具。

    + +

    還是不知道那是什麼嗎?那看看骨灰集散地的這張照片:

    + +
    +Game & Watch
    + +

    想起來了嗎?

    + +

    今天逛骨灰集散地的時候,偶然注意到左邊的 Menu 有一張熟悉又陌生的照片。一點進去...

    + +

    不…會…吧…這…這不是…

    + +

    我都已經完全忘記這些東西了。原來這種掌上型電玩叫做 Game & Watch ,我從來不知道;原來我小時候的那一台米老鼠接雞蛋,機種叫做 Wide Screen ;原來這是任天堂生產的;原來還有人在搜集這些老玩具…

    + +

    下載了模擬版來玩:米老鼠接雞蛋、大章魚、大金剛。好…感動~上網查 Game & Watch ,發現竟然有玩家專門在蒐集古董 Game & Watch ,真的是太感動了~!

    + +

    這是我小時候玩的第一種電動玩具:米老鼠接雞蛋, 1981 年 10 月發行。比電腦遊戲還要早,幾乎遺忘的感動。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 10 | + 11 | + 12 | + 13 | + 14 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0012.html.zh-cn.html b/htdocs/imacat/me/diary/0012.html.zh-cn.html new file mode 120000 index 0000000..f5e7fff --- /dev/null +++ b/htdocs/imacat/me/diary/0012.html.zh-cn.html @@ -0,0 +1 @@ +0012.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0012.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0012.html.zh-cn.xhtml new file mode 100644 index 0000000..e28288c --- /dev/null +++ b/htdocs/imacat/me/diary/0012.html.zh-cn.xhtml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷十二

    + +
    + +
    + +
    +
    8.31.’05. 1:06pm.
    + +

    最近发疯了,卯起来蒐集古董游戏。

    + +

    其实我很穷,看到旧旧的绝版包装、说明书、光碟,也只能乾瞪眼、流口水。我能蒐集的,只有透过 eMule 、网路搜寻,蒐集不大花钱的旧游戏的档案。偶尔有点闲钱,才能东买一点、西买一点。

    + +

    可是光是这样,就已经够难了。我是创世纪 (Ultima) 的迷。前两年在 eBay 上,买了一套台湾没有上市的创世纪的大合辑。卖家不愿寄到美国以外的地址,只好拜托我在纽约的妹妹先收,再转寄过来。本来以为这样已经齐全了,可是前几天逛旧游戏网站,发现创世纪还有两套外传流落在外:洪荒帝国 (The Savage Empire) 和火星之旅 (Martian Dreams) 。于是只好上 eMule 找,把能找到的版本都找来,互相比对,整理出最原始的版本。即使如此,创世纪七代第二部巨蛇之岛 (Serpent Isle) ,我只找到加上资料片银色种子 (The Silver Seed) 后的版本。未加资料片前的巨蛇之岛原始版本,和资料片银色种子独立的安装程式,却是怎么样也找不到。

    + +

    前一阵子终于把五年前买的游戏柏德之门 (Baldur's Gate) 破关了。回味剧情的同时,也上网找找发行商 Interplay 、制作小组黑岛工作室 (Black Isle Studio) 和 Bioware 的最新消息,看有没有后续的作品。没想到意外发现 Black Isle Studio 和 Interplay 已经分别在 2001 年和 2004 年倒了!这么好的游戏,真是让人难过的消息。在网上读了几篇来龙去脉,感叹的同时,也起意寻找十年前龙与地下城 (Advance Dragons and Dungeons, AD&D) SSI 被遗忘的国度 (Forgotten Realms) 系列的旧作,和 Black Isle Studio 过去得奖无数的作品异尘馀生 (Fallout) 系列和异域镇魂曲 (Planescape: Torment) 等。蒐集的过程中,我发现 1997 年 Interplay 刚取得 AD&D 授权的时候,曾经重新出版了一套过去 SSI 被遗忘的国度系列十二个游戏大合辑。找了半天,才在 eBay 上找到一个英国二手游戏商,手上有旧的说明书和光碟(包装已经没了),而且愿意寄到亚洲来。只要弄到那套大合辑,就一口气找齐十二个游戏了。我赶紧刷卡刷了 24 块钱英磅买下来,现在还在邮寄途中。

    + +

    我虽然是创世纪的迷,但其实是从创世纪七代黑月之门 (The Black Gate) 才开始认识、迷上创世纪的。我最早开始玩的角色扮演游戏 RPG 其实不是创世纪,而是 AD&D 龙与地下城系列,从 1989 年的青色枷的诅咒 (Curse of the Azure Bonds) 开始玩。我最近想想,龙与地下城系列,也许比创世纪系列,对我有更多的回忆。

    + +

    一般公认史上最伟大的三大 RPG 为:创世纪系列 (UItima) 、巫术系列 (Wizardry) 和魔法门系列 (Might & Magic) 。不过我觉得应该把 AD&D 龙与地下城系列一起算进来,合称史上最伟大的四大 RPG 才对。这四大 RPG ,除了巫术 (Wizardry) 以外,我都玩过了。可能是因为巫术在台湾没有发行吧,我一直都只闻其名,未逢其盛。不过这四大 RPG 除了创世纪以线上创世纪 (Ultima Online) 网路游戏存留下来, AD&D 的版权由 Infograms 买下来, Bioware 投靠 Infograms 继续创作外,传统的三大 RPG 创世纪系列、魔法门系列和巫术系列,都已经禁不住时间的考验,一一倒下来了,让人不胜欷嘘。

    + +

    我不敢奢求有本事可以弄到那些旧旧的原始包装、说明书、磁片和光碟。下载得到游戏档案,我就心满意足了。存了这么多,我也不知道什么时候才有时间去玩。大概要等到我老了、退休了,当无聊老太婆的时候,才有空一个一个去玩吧。到那时候的未来电脑,还能跑这些旧游戏吗?我也不知道。不过光是弄到得来不易的游戏档案,就觉得好感动。我想这就是蒐集的乐趣吧~ ^_*'

    + +
    + +
    + +
    +
    8.28.’05. 7:35pm.
    + +

    不知道还有没有人记得 Game & Watch ?

    + +

    不知道那是什么吗?就是小时候朋友会带去学校互相交换,小小可以放在胸前口袋,形状像名片一样,用一个小圆电池,中间一个萤幕,两旁两个或四个按钮,旁边还有 A B 钮的掌上型电动玩具。

    + +

    还是不知道那是什么吗?那看看骨灰集散地的这张照片:

    + +
    +Game & Watch
    + +

    想起来了吗?

    + +

    今天逛骨灰集散地的时候,偶然注意到左边的 Menu 有一张熟悉又陌生的照片。一点进去...

    + +

    不…会…吧…这…这不是…

    + +

    我都已经完全忘记这些东西了。原来这种掌上型电玩叫做 Game & Watch ,我从来不知道;原来我小时候的那一台米老鼠接鸡蛋,机种叫做 Wide Screen ;原来这是任天堂生产的;原来还有人在搜集这些老玩具…

    + +

    下载了模拟版来玩:米老鼠接鸡蛋、大章鱼、大金刚。好…感动~上网查 Game & Watch ,发现竟然有玩家专门在搜集古董 Game & Watch ,真的是太感动了~!

    + +

    这是我小时候玩的第一种电动玩具:米老鼠接鸡蛋, 1981 年 10 月发行。比电脑游戏还要早,几乎遗忘的感动。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 10 | + 11 | + 12 | + 13 | + 14 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0012.html.zh-tw.html b/htdocs/imacat/me/diary/0012.html.zh-tw.html new file mode 120000 index 0000000..72c8a75 --- /dev/null +++ b/htdocs/imacat/me/diary/0012.html.zh-tw.html @@ -0,0 +1 @@ +0012.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0012.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0012.html.zh-tw.xhtml new file mode 100644 index 0000000..1d824f0 --- /dev/null +++ b/htdocs/imacat/me/diary/0012.html.zh-tw.xhtml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷十二

    + +
    + +
    + +
    +
    8.31.’05. 1:06pm.
    + +

    最近發瘋了,卯起來蒐集古董遊戲。

    + +

    其實我很窮,看到舊舊的絕版包裝、說明書、光碟,也只能乾瞪眼、流口水。我能蒐集的,只有透過 eMule 、網路搜尋,蒐集不大花錢的舊遊戲的檔案。偶爾有點閒錢,才能東買一點、西買一點。

    + +

    可是光是這樣,就已經夠難了。我是創世紀 (Ultima) 的迷。前兩年在 eBay 上,買了一套台灣沒有上市的創世紀的大合輯。賣家不願寄到美國以外的地址,只好拜託我在紐約的妹妹先收,再轉寄過來。本來以為這樣已經齊全了,可是前幾天逛舊遊戲網站,發現創世紀還有兩套外傳流落在外:洪荒帝國 (The Savage Empire) 和火星之旅 (Martian Dreams) 。於是只好上 eMule 找,把能找到的版本都找來,互相比對,整理出最原始的版本。即使如此,創世紀七代第二部巨蛇之島 (Serpent Isle) ,我只找到加上資料片銀色種子 (The Silver Seed) 後的版本。未加資料片前的巨蛇之島原始版本,和資料片銀色種子獨立的安裝程式,卻是怎麼樣也找不到。

    + +

    前一陣子終於把五年前買的遊戲柏德之門 (Baldur's Gate) 破關了。回味劇情的同時,也上網找找發行商 Interplay 、製作小組黑島工作室 (Black Isle Studio) 和 Bioware 的最新消息,看有沒有後續的作品。沒想到意外發現 Black Isle Studio 和 Interplay 已經分別在 2001 年和 2004 年倒了!這麼好的遊戲,真是讓人難過的消息。在網上讀了幾篇來龍去脈,感嘆的同時,也起意尋找十年前龍與地下城 (Advance Dragons and Dungeons, AD&D) SSI 被遺忘的國度 (Forgotten Realms) 系列的舊作,和 Black Isle Studio 過去得獎無數的作品異塵餘生 (Fallout) 系列和異域鎮魂曲 (Planescape: Torment) 等。蒐集的過程中,我發現 1997 年 Interplay 剛取得 AD&D 授權的時候,曾經重新出版了一套過去 SSI 被遺忘的國度系列十二個遊戲大合輯。找了半天,才在 eBay 上找到一個英國二手遊戲商,手上有舊的說明書和光碟(包裝已經沒了),而且願意寄到亞洲來。只要弄到那套大合輯,就一口氣找齊十二個遊戲了。我趕緊刷卡刷了 24 塊錢英磅買下來,現在還在郵寄途中。

    + +

    我雖然是創世紀的迷,但其實是從創世紀七代黑月之門 (The Black Gate) 才開始認識、迷上創世紀的。我最早開始玩的角色扮演遊戲 RPG 其實不是創世紀,而是 AD&D 龍與地下城系列,從 1989 年的青色枷的詛咒 (Curse of the Azure Bonds) 開始玩。我最近想想,龍與地下城系列,也許比創世紀系列,對我有更多的回憶。

    + +

    一般公認史上最偉大的三大 RPG 為:創世紀系列 (UItima) 、巫術系列 (Wizardry) 和魔法門系列 (Might & Magic) 。不過我覺得應該把 AD&D 龍與地下城系列一起算進來,合稱史上最偉大的四大 RPG 才對。這四大 RPG ,除了巫術 (Wizardry) 以外,我都玩過了。可能是因為巫術在台灣沒有發行吧,我一直都只聞其名,未逢其盛。不過這四大 RPG 除了創世紀以線上創世紀 (Ultima Online) 網路遊戲存留下來, AD&D 的版權由 Infograms 買下來, Bioware 投靠 Infograms 繼續創作外,傳統的三大 RPG 創世紀系列、魔法門系列和巫術系列,都已經禁不住時間的考驗,一一倒下來了,讓人不勝欷噓。

    + +

    我不敢奢求有本事可以弄到那些舊舊的原始包裝、說明書、磁片和光碟。下載得到遊戲檔案,我就心滿意足了。存了這麼多,我也不知道什麼時候才有時間去玩。大概要等到我老了、退休了,當無聊老太婆的時候,才有空一個一個去玩吧。到那時候的未來電腦,還能跑這些舊遊戲嗎?我也不知道。不過光是弄到得來不易的遊戲檔案,就覺得好感動。我想這就是蒐集的樂趣吧~ ^_*'

    + +
    + +
    + +
    +
    8.28.’05. 7:35pm.
    + +

    不知道還有沒有人記得 Game & Watch ?

    + +

    不知道那是什麼嗎?就是小時候朋友會帶去學校互相交換,小小可以放在胸前口袋,形狀像名片一樣,用一個小圓電池,中間一個螢幕,兩旁兩個或四個按鈕,旁邊還有 A B 鈕的掌上型電動玩具。

    + +

    還是不知道那是什麼嗎?那看看骨灰集散地的這張照片:

    + +
    +Game & Watch
    + +

    想起來了嗎?

    + +

    今天逛骨灰集散地的時候,偶然注意到左邊的 Menu 有一張熟悉又陌生的照片。一點進去...

    + +

    不…會…吧…這…這不是…

    + +

    我都已經完全忘記這些東西了。原來這種掌上型電玩叫做 Game & Watch ,我從來不知道;原來我小時候的那一台米老鼠接雞蛋,機種叫做 Wide Screen ;原來這是任天堂生產的;原來還有人在搜集這些老玩具…

    + +

    下載了模擬版來玩:米老鼠接雞蛋、大章魚、大金剛。好…感動~上網查 Game & Watch ,發現竟然有玩家專門在蒐集古董 Game & Watch ,真的是太感動了~!

    + +

    這是我小時候玩的第一種電動玩具:米老鼠接雞蛋, 1981 年 10 月發行。比電腦遊戲還要早,幾乎遺忘的感動。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 10 | + 11 | + 12 | + 13 | + 14 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0013.html.en.html b/htdocs/imacat/me/diary/0013.html.en.html new file mode 120000 index 0000000..79e5d2f --- /dev/null +++ b/htdocs/imacat/me/diary/0013.html.en.html @@ -0,0 +1 @@ +0013.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0013.html.en.xhtml b/htdocs/imacat/me/diary/0013.html.en.xhtml new file mode 100644 index 0000000..f365d36 --- /dev/null +++ b/htdocs/imacat/me/diary/0013.html.en.xhtml @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 13 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 13

    + +
    + +
    + +
    +
    9.30.’05. 10:20pm.
    + +

    最近在試用各種 Norton AntiVirus 以外的防毒程式,包括了:

    + +
      +
    1. Kaspersky 卡巴斯基
    2. +
    3. AntiVir
    4. +
    5. ClamWin
    6. +
    7. F-Secure AntiVirus
    8. +
    + +
    +
    Kaspersky 卡巴斯基
    + +
    +

    Kaspersky 卡巴斯基是 2004 年 www.virus.gr 評選最佳防毒軟體的第一名。這是俄國人寫的防毒軟體。授權方式是線上下載軟體,購買授權後,會給一份啟動用的授權金鑰檔,用該金鑰檔啟用。金鑰檔有期限,過期就會失效不能用,啟用後有效期限一年。整體來講效能比較快。未附防火牆。安裝後第一次重開機會當機 (Virtual PC) 。無法掃描 .eml 郵件檔,不過郵件附件存檔、執行的時候,病毒還是會攔截到。含 POP3/SMTP 收發信攔截病毒功能。

    + +

    卡巴斯基發現病毒的時候,會發出殺豬一樣難聽的警告音。是故意要彰顯病毒的恐怖嗎? ^^;

    +
    + +
    AntiVir
    + +
    +

    AntiVir 是免費的防毒軟體,網路上風評很高,在 www.virus.gr 上排名第 24 。風評好是因免費而且表現不差。無任何授權更新年限限制,掃描時會掃 .eml 郵件檔。病毒被包在壓縮檔中時,無法清除。不過執行時還是會攔截到。未附防火牆,無 POP3/SMTP 收發信攔截功能。某些中文檔名、目錄名稱(如:複製.scr 、 C:\TEMP\複製 - virus\Netskey.scr )無法掃瞄。免費版更新病毒碼頻寬很小,更新很慢。

    + +

    AntiVir 有另一件有趣的事。它的付費個人版, 2006 年起,每購買一份二十歐元,作者會捐出五歐元,給一個由他妻子掌管的公益文教基金會。自己妻子掌管的基金會?嗯,好像很難監督金錢流向的感覺。不過反正這本來就是跟他們買軟體的錢了,就算挪作它用,也沒什麼說不過去的。

    +
    + +
    ClamWin
    + +
    +

    ClamWin 是 GNU 自由軟體 Clam AntiVirus 的 Windows 版,採用 GNU 公共授權,在 www.virus.gr 上排名第 36 。 Clam AntiVirus 原是專為 Unix 郵件伺服器掃毒用的防毒程式。 ClamWin 須手動掃毒,完全不會在存檔、執行時自動掃毒。因此雖是 GNU 自由軟體,但實在讓人無法安心,除了在伺服器上用之外,還是不要用的好。

    +
    + +
    F-Secure AntiVirus
    + +
    +

    F-Secure AntiVirus 在 www.virus.gr 上排名第 2 ,是芬蘭人寫的防毒軟體,歷史攸久頗富盛名,。 F-Secure 可掃 .eml 郵件檔。病毒被包在郵件檔或壓縮檔中存檔時,不會自動掃毒,手動掃描時也無法清除。不過執行時還是會攔截到。未附防火牆。含 POP3/SMTP 收發信攔截病毒功能。

    +
    +
    + +

    總結來說, AntiVir 因為還沒有辦法處理中文檔名,雖然免費而且效能不錯,還是暫時不要用比較好。 ^^; 卡巴斯基和 F-Secure 也不錯,卡巴斯基的效能比較高一些,只是警告音真的很難聽。

    + +
    + +
    + +
    +
    9.24.’05. 9:50pm.
    + +
    +今天又重做了一份日常工作用的 Windows Me 開機工具片
    +還有開機工具光碟片
    +本來還在傷腦筋做開機光碟片時
    +沒有 2.88 磁碟機,該怎麼模擬 2.88 開機磁碟影像檔
    +沒想到用 WinImage 就可以把 1.44 磁碟影像檔,直接轉成 2.88 磁碟影像檔了
    +而且不會破壞開機磁區,一樣可以開機
    +把日常所需的工具程式,整理一遍重新放進去
    +
    +就像到了週末把棉被拿出來曬一樣
    +趁不忙的假日整理整理,感覺日子懶懶地在身邊流逝 +
    + +
    + +
    + +
    +
    9.22.’05. 4:38am.
    + +

    沒想到真的被我找到了「未加資料片的創世紀七第二部巨蛇之島」和「創世紀七第二部巨蛇之島資料片銀色種子的獨立安裝程式」,兩個都是在 eMule 上找到的。謝謝不知名的分享的朋友。真是太神奇了~!好高興,呵呵~ *^_^*

    + +
    + +
    + +
    +
    9.18.’05. 5:57pm.
    + +
    +剛剛在收綿被的時候,胡思亂想了一些事
    +
    +如果說現在的女同志比以前的女同志幸福,也沒有錯
    +現代社會開放了,選擇多了
    +比起進入婚姻體制來說,不結婚,也成為了一種可選的選擇
    +因此婚姻體制雖然不公平,婚姻體制雖然還是異姓戀中心,兩個相愛的女人無法步入結婚禮堂
    +與其選擇繼續跟體制抗爭,辛苦爭取結婚權
    +女同志也可以選擇終身不婚,和所愛的人一輩子同居,甚至更自由選擇單身
    +即使不挑戰體制,也還是可以過得下去
    +
    +那麼,整體來說,挑戰體制的動機,就沒有那麼強烈了
    +雖然還是有不少女同志渴望結婚,希望取得法律的認可
    +可是爭取的過程越來越無力
    +與其歸責於女同志不團結
    +不如說是社會開放,選擇多了
    +連異性戀都不結婚了,婚姻本身的社會象徵日趨式微了
    +
    +可是,婚姻作為社會最重要的基本制度,還是擁有相當多的法律地位、權益保障等等
    +對想長久共組家庭的女同志來說,還是非常重要
    +我們還能從哪裏切入,爭取女同志對婚姻制度的認同
    +團結爭取女同志的結婚權呢? +
    + +
    + +
    + +
    +
    9.8.’05. 3:35pm.
    + +
    +妳
    +
    +閉上眼睛 想的都是妳
    +張開眼睛 看的都是妳
    +轉過頭來 看到的是妳
    +回過頭去 看不到的是妳
    +
    +為什麼妳是妳
    +為什麼妳不是妳
    +
    +開口閉口 説的都是妳
    +心裏夢裏 想的都是妳
    +在我身邊 陪我的是妳
    +魂牽夢縈 等不到的是妳
    +
    +為什麼妳是妳
    +為什麼妳不是妳
    +
    +夢不到的妳
    +不能說出口的妳 +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 11 | + 12 | + 13 | + 14 | + 15 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0013.html.zh-cn.html b/htdocs/imacat/me/diary/0013.html.zh-cn.html new file mode 120000 index 0000000..0305381 --- /dev/null +++ b/htdocs/imacat/me/diary/0013.html.zh-cn.html @@ -0,0 +1 @@ +0013.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0013.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0013.html.zh-cn.xhtml new file mode 100644 index 0000000..daee830 --- /dev/null +++ b/htdocs/imacat/me/diary/0013.html.zh-cn.xhtml @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷十三

    + +
    + +
    + +
    +
    9.30.’05. 10:20pm.
    + +

    最近在试用各种 Norton AntiVirus 以外的防毒程式,包括了:

    + +
      +
    1. Kaspersky 卡巴斯基
    2. +
    3. AntiVir
    4. +
    5. ClamWin
    6. +
    7. F-Secure AntiVirus
    8. +
    + +
    +
    Kaspersky 卡巴斯基
    + +
    +

    Kaspersky 卡巴斯基是 2004 年 www.virus.gr 评选最佳防毒软体的第一名。这是俄国人写的防毒软体。授权方式是线上下载软体,购买授权后,会给一份启动用的授权金钥档,用该金钥档启用。金钥档有期限,过期就会失效不能用,启用后有效期限一年。整体来讲效能比较快。未附防火墙。安装后第一次重开机会当机 (Virtual PC) 。无法扫描 .eml 邮件档,不过邮件附件存档、执行的时候,病毒还是会拦截到。含 POP3/SMTP 收发信拦截病毒功能。

    + +

    卡巴斯基发现病毒的时候,会发出杀猪一样难听的警告音。是故意要彰显病毒的恐怖吗? ^^;

    +
    + +
    AntiVir
    + +
    +

    AntiVir 是免费的防毒软体,网路上风评很高,在 www.virus.gr 上排名第 24 。风评好是因免费而且表现不差。无任何授权更新年限限制,扫描时会扫 .eml 邮件档。病毒被包在压缩档中时,无法清除。不过执行时还是会拦截到。未附防火墙,无 POP3/SMTP 收发信拦截功能。某些中文档名、目录名称(如:复制.scr 、 C:\TEMP\复制 - virus\Netskey.scr )无法扫瞄。免费版更新病毒码频宽很小,更新很慢。

    + +

    AntiVir 有另一件有趣的事。它的付费个人版, 2006 年起,每购买一份二十欧元,作者会捐出五欧元,给一个由他妻子掌管的公益文教基金会。自己妻子掌管的基金会?嗯,好像很难监督金钱流向的感觉。不过反正这本来就是跟他们买软体的钱了,就算挪作它用,也没什么说不过去的。

    +
    + +
    ClamWin
    + +
    +

    ClamWin 是 GNU 自由软体 Clam AntiVirus 的 Windows 版,采用 GNU 公共授权,在 www.virus.gr 上排名第 36 。 Clam AntiVirus 原是专为 Unix 邮件伺服器扫毒用的防毒程式。 ClamWin 须手动扫毒,完全不会在存档、执行时自动扫毒。因此虽是 GNU 自由软体,但实在让人无法安心,除了在伺服器上用之外,还是不要用的好。

    +
    + +
    F-Secure AntiVirus
    + +
    +

    F-Secure AntiVirus 在 www.virus.gr 上排名第 2 ,是芬兰人写的防毒软体,历史攸久颇富盛名,。 F-Secure 可扫 .eml 邮件档。病毒被包在邮件档或压缩档中存档时,不会自动扫毒,手动扫描时也无法清除。不过执行时还是会拦截到。未附防火墙。含 POP3/SMTP 收发信拦截病毒功能。

    +
    +
    + +

    总结来说, AntiVir 因为还没有办法处理中文档名,虽然免费而且效能不错,还是暂时不要用比较好。 ^^; 卡巴斯基和 F-Secure 也不错,卡巴斯基的效能比较高一些,只是警告音真的很难听。

    + +
    + +
    + +
    +
    9.24.’05. 9:50pm.
    + +
    +今天又重做了一份日常工作用的 Windows Me 开机工具片
    +还有开机工具光碟片
    +本来还在伤脑筋做开机光碟片时
    +没有 2.88 磁碟机,该怎么模拟 2.88 开机磁碟影像档
    +没想到用 WinImage 就可以把 1.44 磁碟影像档,直接转成 2.88 磁碟影像档了
    +而且不会破坏开机磁区,一样可以开机
    +把日常所需的工具程式,整理一遍重新放进去
    +
    +就像到了周末把棉被拿出来晒一样
    +趁不忙的假日整理整理,感觉日子懒懒地在身边流逝 +
    + +
    + +
    + +
    +
    9.22.’05. 4:38am.
    + +

    没想到真的被我找到了「未加资料片的创世纪七第二部巨蛇之岛」和「创世纪七第二部巨蛇之岛资料片银色种子的独立安装程式」,两个都是在 eMule 上找到的。谢谢不知名的分享的朋友。真是太神奇了~!好高兴,呵呵~ *^_^*

    + +
    + +
    + +
    +
    9.18.’05. 5:57pm.
    + +
    +刚刚在收绵被的时候,胡思乱想了一些事
    +
    +如果说现在的女同志比以前的女同志幸福,也没有错
    +现代社会开放了,选择多了
    +比起进入婚姻体制来说,不结婚,也成为了一种可选的选择
    +因此婚姻体制虽然不公平,婚姻体制虽然还是异姓恋中心,两个相爱的女人无法步入结婚礼堂
    +与其选择继续跟体制抗争,辛苦争取结婚权
    +女同志也可以选择终身不婚,和所爱的人一辈子同居,甚至更自由选择单身
    +即使不挑战体制,也还是可以过得下去
    +
    +那么,整体来说,挑战体制的动机,就没有那么强烈了
    +虽然还是有不少女同志渴望结婚,希望取得法律的认可
    +可是争取的过程越来越无力
    +与其归责于女同志不团结
    +不如说是社会开放,选择多了
    +连异性恋都不结婚了,婚姻本身的社会象徵日趋式微了
    +
    +可是,婚姻作为社会最重要的基本制度,还是拥有相当多的法律地位、权益保障等等
    +对想长久共组家庭的女同志来说,还是非常重要
    +我们还能从哪里切入,争取女同志对婚姻制度的认同
    +团结争取女同志的结婚权呢? +
    + +
    + +
    + +
    +
    9.8.’05. 3:35pm.
    + +
    +你
    +
    +闭上眼睛 想的都是你
    +张开眼睛 看的都是你
    +转过头来 看到的是你
    +回过头去 看不到的是你
    +
    +为什么你是你
    +为什么你不是你
    +
    +开口闭口 ���的都是你
    +心里梦里 想的都是你
    +在我身边 陪我的是你
    +魂牵梦萦 等不到的是你
    +
    +为什么你是你
    +为什么你不是你
    +
    +梦不到的你
    +不能说出口的你 +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 11 | + 12 | + 13 | + 14 | + 15 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0013.html.zh-tw.html b/htdocs/imacat/me/diary/0013.html.zh-tw.html new file mode 120000 index 0000000..8b961dd --- /dev/null +++ b/htdocs/imacat/me/diary/0013.html.zh-tw.html @@ -0,0 +1 @@ +0013.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0013.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0013.html.zh-tw.xhtml new file mode 100644 index 0000000..b4e9cbb --- /dev/null +++ b/htdocs/imacat/me/diary/0013.html.zh-tw.xhtml @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷十三

    + +
    + +
    + +
    +
    9.30.’05. 10:20pm.
    + +

    最近在試用各種 Norton AntiVirus 以外的防毒程式,包括了:

    + +
      +
    1. Kaspersky 卡巴斯基
    2. +
    3. AntiVir
    4. +
    5. ClamWin
    6. +
    7. F-Secure AntiVirus
    8. +
    + +
    +
    Kaspersky 卡巴斯基
    + +
    +

    Kaspersky 卡巴斯基是 2004 年 www.virus.gr 評選最佳防毒軟體的第一名。這是俄國人寫的防毒軟體。授權方式是線上下載軟體,購買授權後,會給一份啟動用的授權金鑰檔,用該金鑰檔啟用。金鑰檔有期限,過期就會失效不能用,啟用後有效期限一年。整體來講效能比較快。未附防火牆。安裝後第一次重開機會當機 (Virtual PC) 。無法掃描 .eml 郵件檔,不過郵件附件存檔、執行的時候,病毒還是會攔截到。含 POP3/SMTP 收發信攔截病毒功能。

    + +

    卡巴斯基發現病毒的時候,會發出殺豬一樣難聽的警告音。是故意要彰顯病毒的恐怖嗎? ^^;

    +
    + +
    AntiVir
    + +
    +

    AntiVir 是免費的防毒軟體,網路上風評很高,在 www.virus.gr 上排名第 24 。風評好是因免費而且表現不差。無任何授權更新年限限制,掃描時會掃 .eml 郵件檔。病毒被包在壓縮檔中時,無法清除。不過執行時還是會攔截到。未附防火牆,無 POP3/SMTP 收發信攔截功能。某些中文檔名、目錄名稱(如:複製.scr 、 C:\TEMP\複製 - virus\Netskey.scr )無法掃瞄。免費版更新病毒碼頻寬很小,更新很慢。

    + +

    AntiVir 有另一件有趣的事。它的付費個人版, 2006 年起,每購買一份二十歐元,作者會捐出五歐元,給一個由他妻子掌管的公益文教基金會。自己妻子掌管的基金會?嗯,好像很難監督金錢流向的感覺。不過反正這本來就是跟他們買軟體的錢了,就算挪作它用,也沒什麼說不過去的。

    +
    + +
    ClamWin
    + +
    +

    ClamWin 是 GNU 自由軟體 Clam AntiVirus 的 Windows 版,採用 GNU 公共授權,在 www.virus.gr 上排名第 36 。 Clam AntiVirus 原是專為 Unix 郵件伺服器掃毒用的防毒程式。 ClamWin 須手動掃毒,完全不會在存檔、執行時自動掃毒。因此雖是 GNU 自由軟體,但實在讓人無法安心,除了在伺服器上用之外,還是不要用的好。

    +
    + +
    F-Secure AntiVirus
    + +
    +

    F-Secure AntiVirus 在 www.virus.gr 上排名第 2 ,是芬蘭人寫的防毒軟體,歷史攸久頗富盛名,。 F-Secure 可掃 .eml 郵件檔。病毒被包在郵件檔或壓縮檔中存檔時,不會自動掃毒,手動掃描時也無法清除。不過執行時還是會攔截到。未附防火牆。含 POP3/SMTP 收發信攔截病毒功能。

    +
    +
    + +

    總結來說, AntiVir 因為還沒有辦法處理中文檔名,雖然免費而且效能不錯,還是暫時不要用比較好。 ^^; 卡巴斯基和 F-Secure 也不錯,卡巴斯基的效能比較高一些,只是警告音真的很難聽。

    + +
    + +
    + +
    +
    9.24.’05. 9:50pm.
    + +
    +今天又重做了一份日常工作用的 Windows Me 開機工具片
    +還有開機工具光碟片
    +本來還在傷腦筋做開機光碟片時
    +沒有 2.88 磁碟機,該怎麼模擬 2.88 開機磁碟影像檔
    +沒想到用 WinImage 就可以把 1.44 磁碟影像檔,直接轉成 2.88 磁碟影像檔了
    +而且不會破壞開機磁區,一樣可以開機
    +把日常所需的工具程式,整理一遍重新放進去
    +
    +就像到了週末把棉被拿出來曬一樣
    +趁不忙的假日整理整理,感覺日子懶懶地在身邊流逝 +
    + +
    + +
    + +
    +
    9.22.’05. 4:38am.
    + +

    沒想到真的被我找到了「未加資料片的創世紀七第二部巨蛇之島」和「創世紀七第二部巨蛇之島資料片銀色種子的獨立安裝程式」,兩個都是在 eMule 上找到的。謝謝不知名的分享的朋友。真是太神奇了~!好高興,呵呵~ *^_^*

    + +
    + +
    + +
    +
    9.18.’05. 5:57pm.
    + +
    +剛剛在收綿被的時候,胡思亂想了一些事
    +
    +如果說現在的女同志比以前的女同志幸福,也沒有錯
    +現代社會開放了,選擇多了
    +比起進入婚姻體制來說,不結婚,也成為了一種可選的選擇
    +因此婚姻體制雖然不公平,婚姻體制雖然還是異姓戀中心,兩個相愛的女人無法步入結婚禮堂
    +與其選擇繼續跟體制抗爭,辛苦爭取結婚權
    +女同志也可以選擇終身不婚,和所愛的人一輩子同居,甚至更自由選擇單身
    +即使不挑戰體制,也還是可以過得下去
    +
    +那麼,整體來說,挑戰體制的動機,就沒有那麼強烈了
    +雖然還是有不少女同志渴望結婚,希望取得法律的認可
    +可是爭取的過程越來越無力
    +與其歸責於女同志不團結
    +不如說是社會開放,選擇多了
    +連異性戀都不結婚了,婚姻本身的社會象徵日趨式微了
    +
    +可是,婚姻作為社會最重要的基本制度,還是擁有相當多的法律地位、權益保障等等
    +對想長久共組家庭的女同志來說,還是非常重要
    +我們還能從哪裏切入,爭取女同志對婚姻制度的認同
    +團結爭取女同志的結婚權呢? +
    + +
    + +
    + +
    +
    9.8.’05. 3:35pm.
    + +
    +妳
    +
    +閉上眼睛 想的都是妳
    +張開眼睛 看的都是妳
    +轉過頭來 看到的是妳
    +回過頭去 看不到的是妳
    +
    +為什麼妳是妳
    +為什麼妳不是妳
    +
    +開口閉口 説的都是妳
    +心裏夢裏 想的都是妳
    +在我身邊 陪我的是妳
    +魂牽夢縈 等不到的是妳
    +
    +為什麼妳是妳
    +為什麼妳不是妳
    +
    +夢不到的妳
    +不能說出口的妳 +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 11 | + 12 | + 13 | + 14 | + 15 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0014.html.en.html b/htdocs/imacat/me/diary/0014.html.en.html new file mode 120000 index 0000000..438a039 --- /dev/null +++ b/htdocs/imacat/me/diary/0014.html.en.html @@ -0,0 +1 @@ +0014.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0014.html.en.xhtml b/htdocs/imacat/me/diary/0014.html.en.xhtml new file mode 100644 index 0000000..e89ae90 --- /dev/null +++ b/htdocs/imacat/me/diary/0014.html.en.xhtml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 14 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 14

    + +
    + +
    + +
    +
    10.11.’05. 2:30am.
    + +

    剛剛在網路上逛時,發現我的名字出現在 2005-09-26 發表的一份奇怪的中國泛藍聯盟台湾各大院校强烈声援夏智来冤假錯案抵制前往山东旅游连署名单連署書中。仔細一看,不只是我,包括許多朋友,都疑被盜用名義加入連署。我已經在該文文後,回覆張貼我個人的正式聲明。

    + +
    +

    我在此正式聲明,我依瑪貓本人從未參與連署該聲明。該單位盜用我的名義加進連署,我完全不知情,已經對我造成很嚴重的困擾。對該單位擅自盜用我的名義的行為,我至感憤怒。請自即刻起刪除我的名字,否則法律後果自負。請自重。

    +
    + +

    這不是該訴求正當性的問題,不是藍綠的問題,而是連署行動的原則。沒有參加連署,而擅自盜用他人的名義,非常惡質。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 12 | + 13 | + 14 | + 15 | + 16 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0014.html.zh-cn.html b/htdocs/imacat/me/diary/0014.html.zh-cn.html new file mode 120000 index 0000000..eba3939 --- /dev/null +++ b/htdocs/imacat/me/diary/0014.html.zh-cn.html @@ -0,0 +1 @@ +0014.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0014.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0014.html.zh-cn.xhtml new file mode 100644 index 0000000..5dccaac --- /dev/null +++ b/htdocs/imacat/me/diary/0014.html.zh-cn.xhtml @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷十四

    + +
    + +
    + +
    +
    10.11.’05. 2:30am.
    + +

    刚刚在网路上逛时,发现我的名字出现在 2005-09-26 发表的一份奇怪的中国泛蓝联盟台���各大院校���烈���援夏智��冤假错案抵制前往山��œ旅游��ž署名�•连署书中。仔细一看,不只是我,包括许多朋友,都疑被盗用名义加入连署。我已经在该文文后,回覆张贴我个人的正式声明。

    + +
    +

    我在此正式声明,我依玛猫本人从未参与连署该声明。该单位盗用我的名义加进连署,我完全不知情,已经对我造成很严重的困扰。对该单位擅自盗用我的名义的行为,我至感愤怒。请自即刻起删除我的名字,否则法律后果自负。请自重。

    +
    + +

    这不是该诉求正当性的问题,不是蓝绿的问题,而是连署行动的原则。没有参加连署,而擅自盗用他人的名义,非常恶质。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 12 | + 13 | + 14 | + 15 | + 16 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0014.html.zh-tw.html b/htdocs/imacat/me/diary/0014.html.zh-tw.html new file mode 120000 index 0000000..5903d68 --- /dev/null +++ b/htdocs/imacat/me/diary/0014.html.zh-tw.html @@ -0,0 +1 @@ +0014.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0014.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0014.html.zh-tw.xhtml new file mode 100644 index 0000000..7943966 --- /dev/null +++ b/htdocs/imacat/me/diary/0014.html.zh-tw.xhtml @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷十四

    + +
    + +
    + +
    +
    10.11.’05. 2:30am.
    + +

    剛剛在網路上逛時,發現我的名字出現在 2005-09-26 發表的一份奇怪的中國泛藍聯盟台湾各大院校强烈声援夏智来冤假錯案抵制前往山东旅游连署名单連署書中。仔細一看,不只是我,包括許多朋友,都疑被盜用名義加入連署。我已經在該文文後,回覆張貼我個人的正式聲明。

    + +
    +

    我在此正式聲明,我依瑪貓本人從未參與連署該聲明。該單位盜用我的名義加進連署,我完全不知情,已經對我造成很嚴重的困擾。對該單位擅自盜用我的名義的行為,我至感憤怒。請自即刻起刪除我的名字,否則法律後果自負。請自重。

    +
    + +

    這不是該訴求正當性的問題,不是藍綠的問題,而是連署行動的原則。沒有參加連署,而擅自盜用他人的名義,非常惡質。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 12 | + 13 | + 14 | + 15 | + 16 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0015.html.en.html b/htdocs/imacat/me/diary/0015.html.en.html new file mode 120000 index 0000000..6ab92a3 --- /dev/null +++ b/htdocs/imacat/me/diary/0015.html.en.html @@ -0,0 +1 @@ +0015.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0015.html.en.xhtml b/htdocs/imacat/me/diary/0015.html.en.xhtml new file mode 100644 index 0000000..36665ce --- /dev/null +++ b/htdocs/imacat/me/diary/0015.html.en.xhtml @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 15 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 15

    + +
    + +
    + +
    +
    10.13.’05. 2:39am.
    + +

    今天看了蘋果 (2005-10-12) 的頭版頭條,一排紅色大字看!這就是我們國會!感到非常震憾!回頭看看其它三大報:中時、聯合、自由,竟然完全沒有提到這件事,彷彿已經把立法院打架當成理所當然,司空習慣了一樣。只有蘋果,對這些垃圾立委發出了憤怒之聲,真是振聾發瞶!為什麼可以把立法院打架當成理所當然呢?為什麼可以習慣這種事呢?我們納稅人每個月花二十幾萬給這些立委,還辛辛苦苦去投票把他們選出來,就是請他們來打架的嗎?

    + +

    回頭反省,自己本來也把立法院打架當成司空見慣了。對這樣麻木不仁的自己,感到非常汗顏。

    + +

    蘋果社論說得好,這些立委打死一個少一個,乾脆在立法院裝機關槍和火藥,讓他們自相殘殺死光光算了。

    + +

    原文轉載自 2005-10-12 蘋果日報,若有版權問題請不吝告知。

    + +
    +

    看!這就是我們國會

    + +

    【綜合報導】全國最高議事殿堂立法院昨天的代名詞是民主之恥!立法院院會在審議國家通訊傳播委員會(National Communications Commission,NCC)組織法草案時,竟然不數人頭卻數拳頭,爆發開議以來最嚴重的流血衝突。國民黨立委張碩文、民進黨立委李明憲雙雙掛彩。雙方互控對方先動手,卻毫不自省這場國會全武行已讓台灣在國際蒙羞,並為全體國民做了最壞的民主示範。

    + +

    民主蒙羞

    + +

    目前國親泛藍立委有一百一十五席,無黨籍和無盟九席傾泛藍,民進黨加台聯的泛綠是一百零一席,局勢是朝小野大,若表決,泛綠一定敗北。昨天血濺議場的成果是議事幾近停擺,僅在下午表決通過國親版本的法案名稱及第一條條文就散會,若加上九月二十七日第一次審查草案時立院同樣空轉,兩次院會更浪費五千五百多萬元人民血汗錢。

    + +

    據《蘋果》語音民調結果顯示,二成二受訪者認為立院是台灣亂源,其次是媒體、黑道,四成七認為以上三者都是亂源;而朝野打得頭破血流的NCC草案,有高達五成六受訪者根本不清楚內容為何。

    + +

    藍綠混戰兩人掛彩

    + +

    昨天朝野都有備而來,綠軍製作大量標語牌,藍軍拿擴音器嗆聲反制。製作標語的長水管及木桿、立委的二哥大,甚至議場內的水杯,全成了打架的工具。

    + +

    院會昨天上午約十一時進入實質審議,親民黨立委李永萍要求停止討論、進入逐條審查議程,引發民進黨不滿,主席雖裁示暫時休息;由於情緒已點燃,繼續開會後爆發流血衝突。

    + +

    會議進行時,為免主席台再被佔領,藍軍立委張碩文、周守訓、費鴻泰等組成捍衛隊守在主席台下,綠軍也向主席台聚集,兩軍推擠、叫陣,場面失控。

    + +

    混亂中,張碩文揮拳,但也在拉扯中跌倒,他左眼受傷、滿臉是血,手還拿著沾滿血的手機,他指控李明憲打他。李明憲則是眼鏡被打掉,嘴角流血,痛斥遭張碩文毆打。兩人都送台大醫院治療,張碩文左上眼瞼有二處撕裂傷,另有輕微出血,縫合九針。

    + +

    李明憲有頭暈、頸痛、嘔吐感等症狀,右下眼皮有瘀傷,左膝蓋有兩處擦傷,左膝蓋韌帶也受傷。兩人均未向立院警衛隊報案。

    + +

    國民黨團成員昨晚探視張碩文,都建議他應提告訴,但張碩文因身體不適,未明確表達意向,與張碩文友好的無黨籍立委張麗善認為,他應該會提告訴。國民黨團並建議,應將打人者送交紀律委員會議處。李明憲昨晚表示,未打算提出告訴。

    + +

    互控對方早有預謀

    + +

    國民黨團指民進黨前幾天就放話不惜血戰,是預謀的。民進黨團則回擊,泛藍早安排張碩文等當打手,泛藍應負最大責任。

    + +

    發生流血衝突,國親兩黨團對主席王金平不動用警察權頗有怨言,國民黨主席馬英九說:如果有人動粗,一定要有公權力制止,絕不能縱容。王金平卻說,要如何動用警察權不是馬英九怎麼要求,就怎麼做,議會是自主的。

    + +

    紀律委員會如虛設

    + +

    對於這起流血衝突事件,東海大學政治系副教授傅恆德批評,立委打架凸顯個人素養不好,國會暴力只有在民主政治發展初期的社會才出現,立委不應用暴力凸顯議題,任何暴力行為都應在國會消失!

    + +

    東吳大學政治系副教授羅致政則認為,民進黨不應阻擋NCC草案,畢竟國親佔多數,擋得了一時,也擋不了整個會期,尤其面對高度爭議性法案,政黨領袖應發揮智慧,尋求妥協,而不是採非零即一的零和策略。

    + +

    事實上,暴力衝突、攜帶危險物品、杯葛議事等行為,都違反立院內規《立法委員行為法》,要送交紀律委員會議處,但紀委會功能不彰,形同虛設,因此立院每隔一段時間,總會重演暴力殿堂違紀事件

    +
    + +
    +

    蘋論 打死一個少一個

    + +

    看到立法院打得頭破血流,民眾既難過又痛快。難過的是什麼年頭了還打架,台灣真是丟臉落後啊。痛快的是立委作為社會亂源第一名,打死一個少一個。

    + +

    一對老夫妻同時彌留,子女問他倆有何遺願。老爸爸說死前要加入民進黨;老媽媽說死前要加入國民黨。兒女大奇,問理由,二老說入黨成為黨員,死一個少一個。為了社會安寧祥和,我們建議政府在立院會期發給立委機槍手榴彈,讓他們互殺個痛快。

    + +

    打架非臨時起意

    + +

    立委不是臨時起意打架的,而是預謀。看他們前天就準備軍裝、跆拳裝、迷彩裝,還頭戴鋼盔就知道是準備好大打出手的。國會議員竟以身著打架裝為榮,其孩童般幼稚令人啼笑皆非。國會的設置的目的,就是為了取代打架打仗的方式分享權力,沒想到台灣還是靠拳頭議事,完全背反國會設立的精神。

    + +

    往樂觀面看,這是民主的陣痛和過程。美國在19世紀和20世紀初,國會也是比武擂台。1838年眾議員席立和葛瑞夫決鬥,席立被殺。

    + +

    國會特別委員會要求開除葛氏,但國會不理,那時決鬥是司空見慣之行為。

    + +

    1850 年,參議員福特正在發言,參議員班頓做出威脅狀,福特掏出手槍上膛,被他人攔阻才沒出事。1856年,參議員桑納在會場內遭眾議員布魯克斯持手杖打得頭破血流。1902年,參議員提耳曼發言質疑麥勞倫的操守,麥則指責提惡意中傷。兩人扭打在地。事後院會通過決議譴責兩人。20世紀中葉以後美國國會絕少有打架的事例,大家已經獲得共識:由數人頭代替出拳頭。國會的文明因而建立。

    + +

    把對方看成異己

    + +

    台灣國會要走向文明比美國難,因為台灣認同分裂,而認同連結血緣,生殖器決定大腦,就把對方看成異己和敵人,便會恨之欲其死了。

    + +

    當初美國並無難解的認同分裂,頂多是理念和利益的對立,妥協即可解決。認同分裂的對抗是無法妥協的,非至你死我活不可。這就是台灣今日的困境,會因泛藍日益偏向中國、泛綠日益偏向台獨而更加水火不容。所以不發給他們武器互殺怎麼解恨呢?

    + +

    此時政黨領袖和意見領袖不可護短並發表煽動情緒的言語,那是無恥政客的作風─火上加油;政治家此時要呼籲冷靜,譴責暴力,向對方伸出友善的手,以社會責任為優先,而非以一黨之私為優先。現在就看扁、馬、宋誰是政客、誰是政治家了。

    +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 13 | + 14 | + 15 | + 16 | + 17 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0015.html.zh-cn.html b/htdocs/imacat/me/diary/0015.html.zh-cn.html new file mode 120000 index 0000000..8e8b66b --- /dev/null +++ b/htdocs/imacat/me/diary/0015.html.zh-cn.html @@ -0,0 +1 @@ +0015.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0015.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0015.html.zh-cn.xhtml new file mode 100644 index 0000000..1257247 --- /dev/null +++ b/htdocs/imacat/me/diary/0015.html.zh-cn.xhtml @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷十五

    + +
    + +
    + +
    +
    10.13.’05. 2:39am.
    + +

    今天看了苹果 (2005-10-12) 的头版头条,一排红色大字看!这就是我们国会!感到非常震憾!回头看看其它三大报:中时、联合、自由,竟然完全没有提到这件事,彷佛已经把立法院打架当成理所当然,司空习惯了一样。只有苹果,对这些垃圾立委发出了愤怒之声,真是振聋发瞶!为什么可以把立法院打架当成理所当然呢?为什么可以习惯这种事呢?我们纳税人每个月花二十几万给这些立委,还辛辛苦苦去投票把他们选出来,就是请他们来打架的吗?

    + +

    回头反省,自己本来也把立法院打架当成司空见惯了。对这样麻木不仁的自己,感到非常汗颜。

    + +

    苹果社论说得好,这些立委打死一个少一个,乾脆在立法院装机关枪和火药,让他们自相残杀死光光算了。

    + +

    原文转载自 2005-10-12 苹果日报,若有版权问题请不吝告知。

    + +
    +

    看!这就是我们国会

    + +

    【综合报导】全国最高议事殿堂立法院昨天的代名词是民主之耻!立法院院会在审议国家通讯传播委员会(National Communications Commission,NCC)组织法草案时,竟然不数人头却数拳头,爆发开议以来最严重的流血冲突。国民党立委张硕文、民进党立委李明宪双双挂彩。双方互控对方先动手,却毫不自省这场国会全武行已让台湾在国际蒙羞,并为全体国民做了最坏的民主示范。

    + +

    民主蒙羞

    + +

    目前国亲泛蓝立委有一百一十五席,无党籍和无盟九席倾泛蓝,民进党加台联的泛绿是一百零一席,局势是朝小野大,若表决,泛绿一定败北。昨天血溅议场的成果是议事几近停摆,仅在下午表决通过国亲版本的法案名称及第一条条文就散会,若加上九月二十七日第一次审查草案时立院同样空转,两次院会更浪费五千五百多万元人民血汗钱。

    + +

    据《苹果》语音民调结果显示,二成二受访者认为立院是台湾乱源,其次是媒体、黑道,四成七认为以上三者都是乱源;而朝野打得头破血流的NCC草案,有高达五成六受访者根本不清楚内容为何。

    + +

    蓝绿混战两人挂彩

    + +

    昨天朝野都有备而来,绿军制作大量标语牌,蓝军拿扩音器呛声反制。制作标语的长水管及木杆、立委的二哥大,甚至议场内的水杯,全成了打架的工具。

    + +

    院会昨天上午约十一时进入实质审议,亲民党立委李永萍要求停止讨论、进入逐条审查议程,引发民进党不满,主席虽裁示暂时休息;由于情绪已点燃,继续开会后爆发流血冲突。

    + +

    会议进行时,为免主席台再被占领,蓝军立委张硕文、周守训、费鸿泰等组成捍卫队守在主席台下,绿军也向主席台聚集,两军推挤、叫阵,场面失控。

    + +

    混乱中,张硕文挥拳,但也在拉扯中跌倒,他左眼受伤、满脸是血,手还拿著沾满血的手机,他指控李明宪打他。李明宪则是眼镜被打掉,嘴角流血,痛斥遭张硕文殴打。两人都送台大医院治疗,张硕文左上眼睑有二处撕裂伤,另有轻微出血,缝合九针。

    + +

    李明宪有头晕、颈痛、呕吐感等症状,右下眼皮有瘀伤,左膝盖有两处擦伤,左膝盖韧带也受伤。两人均未向立院警卫队报案。

    + +

    国民党团成员昨晚探视张硕文,都建议他应提告诉,但张硕文因身体不适,未明确表达意向,与张硕文友好的无党籍立委张丽善认为,他应该会提告诉。国民党团并建议,应将打人者送交纪律委员会议处。李明宪昨晚表示,未打算提出告诉。

    + +

    互控对方早有预谋

    + +

    国民党团指民进党前几天就放话不惜血战,是预谋的。民进党团则回击,泛蓝早安排张硕文等当打手,泛蓝应负最大责任。

    + +

    发生流血冲突,国亲两党团对主席王金平不动用警察权颇有怨言,国民党主席马英九说:如果有人动粗,一定要有公权力制止,绝不能纵容。王金平却说,要如何动用警察权不是马英九怎么要求,就怎么做,议会是自主的。

    + +

    纪律委员会如虚设

    + +

    对于这起流血冲突事件,东海大学政治系副教授傅恒德批评,立委打架凸显个人素养不好,国会暴力只有在民主政治发展初期的社会才出现,立委不应用暴力凸显议题,任何暴力行为都应在国会消失!

    + +

    东吴大学政治系副教授罗致政则认为,民进党不应阻挡NCC草案,毕竟国亲占多数,挡得了一时,也挡不了整个会期,尤其面对高度争议性法案,政党领袖应发挥智慧,寻求妥协,而不是采非零即一的零和策略。

    + +

    事实上,暴力冲突、携带危险物品、杯葛议事等行为,都违反立院内规《立法委员行为法》,要送交纪律委员会议处,但纪委会功能不彰,形同虚设,因此立院每隔一段时间,总会重演暴力殿堂违纪事件

    +
    + +
    +

    苹论 打死一个少一个

    + +

    看到立法院打得头破血流,民众既难过又痛快。难过的是什么年头了还打架,台湾真是丢脸落后啊。痛快的是立委作为社会乱源第一名,打死一个少一个。

    + +

    一对老夫妻同时弥留,子女问他俩有何遗愿。老爸爸说死前要加入民进党;老妈妈说死前要加入国民党。儿女大奇,问理由,二老说入党成为党员,死一个少一个。为了社会安宁祥和,我们建议政府在立院会期发给立委机枪手榴弹,让他们互杀个痛快。

    + +

    打架非临时起意

    + +

    立委不是临时起意打架的,而是预谋。看他们前天就准备军装、跆拳装、迷彩装,还头戴钢盔就知道是准备好大打出手的。国会议员竟以身著打架装为荣,其孩童般幼稚令人啼笑皆非。国会的设置的目的,就是为了取代打架打仗的方式分享权力,没想到台湾还是靠拳头议事,完全背反国会设立的精神。

    + +

    往乐观面看,这是民主的阵痛和过程。美国在19世纪和20世纪初,国会也是比武擂台。1838年众议员席立和葛瑞夫决斗,席立被杀。

    + +

    国会特别委员会要求开除葛氏,但国会不理,那时决斗是司空见惯之行为。

    + +

    1850 年,参议员福特正在发言,参议员班顿做出威胁状,福特掏出手枪上膛,被他人拦阻才没出事。1856年,参议员桑纳在会场内遭众议员布鲁克斯持手杖打得头破血流。1902年,参议员提耳曼发言质疑麦劳伦的操守,麦则指责提恶意中伤。两人扭打在地。事后院会通过决议谴责两人。20世纪中叶以后美国国会绝少有打架的事例,大家已经获得共识:由数人头代替出拳头。国会的文明因而建立。

    + +

    把对方看成异己

    + +

    台湾国会要走向文明比美国难,因为台湾认同分裂,而认同连结血缘,生殖器决定大脑,就把对方看成异己和敌人,便会恨之欲其死了。

    + +

    当初美国并无难解的认同分裂,顶多是理念和利益的对立,妥协即可解决。认同分裂的对抗是无法妥协的,非至你死我活不可。这就是台湾今日的困境,会因泛蓝日益偏向中国、泛绿日益偏向台独而更加水火不容。所以不发给他们武器互杀怎么解恨呢?

    + +

    此时政党领袖和意见领袖不可护短并发表煽动情绪的言语,那是无耻政客的作风─火上加油;政治家此时要呼吁冷静,谴责暴力,向对方伸出友善的手,以社会责任为优先,而非以一党之私为优先。现在就看扁、马、宋谁是政客、谁是政治家了。

    +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 13 | + 14 | + 15 | + 16 | + 17 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0015.html.zh-tw.html b/htdocs/imacat/me/diary/0015.html.zh-tw.html new file mode 120000 index 0000000..2c20c70 --- /dev/null +++ b/htdocs/imacat/me/diary/0015.html.zh-tw.html @@ -0,0 +1 @@ +0015.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0015.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0015.html.zh-tw.xhtml new file mode 100644 index 0000000..168c01a --- /dev/null +++ b/htdocs/imacat/me/diary/0015.html.zh-tw.xhtml @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷十五

    + +
    + +
    + +
    +
    10.13.’05. 2:39am.
    + +

    今天看了蘋果 (2005-10-12) 的頭版頭條,一排紅色大字看!這就是我們國會!感到非常震憾!回頭看看其它三大報:中時、聯合、自由,竟然完全沒有提到這件事,彷彿已經把立法院打架當成理所當然,司空習慣了一樣。只有蘋果,對這些垃圾立委發出了憤怒之聲,真是振聾發瞶!為什麼可以把立法院打架當成理所當然呢?為什麼可以習慣這種事呢?我們納稅人每個月花二十幾萬給這些立委,還辛辛苦苦去投票把他們選出來,就是請他們來打架的嗎?

    + +

    回頭反省,自己本來也把立法院打架當成司空見慣了。對這樣麻木不仁的自己,感到非常汗顏。

    + +

    蘋果社論說得好,這些立委打死一個少一個,乾脆在立法院裝機關槍和火藥,讓他們自相殘殺死光光算了。

    + +

    原文轉載自 2005-10-12 蘋果日報,若有版權問題請不吝告知。

    + +
    +

    看!這就是我們國會

    + +

    【綜合報導】全國最高議事殿堂立法院昨天的代名詞是民主之恥!立法院院會在審議國家通訊傳播委員會(National Communications Commission,NCC)組織法草案時,竟然不數人頭卻數拳頭,爆發開議以來最嚴重的流血衝突。國民黨立委張碩文、民進黨立委李明憲雙雙掛彩。雙方互控對方先動手,卻毫不自省這場國會全武行已讓台灣在國際蒙羞,並為全體國民做了最壞的民主示範。

    + +

    民主蒙羞

    + +

    目前國親泛藍立委有一百一十五席,無黨籍和無盟九席傾泛藍,民進黨加台聯的泛綠是一百零一席,局勢是朝小野大,若表決,泛綠一定敗北。昨天血濺議場的成果是議事幾近停擺,僅在下午表決通過國親版本的法案名稱及第一條條文就散會,若加上九月二十七日第一次審查草案時立院同樣空轉,兩次院會更浪費五千五百多萬元人民血汗錢。

    + +

    據《蘋果》語音民調結果顯示,二成二受訪者認為立院是台灣亂源,其次是媒體、黑道,四成七認為以上三者都是亂源;而朝野打得頭破血流的NCC草案,有高達五成六受訪者根本不清楚內容為何。

    + +

    藍綠混戰兩人掛彩

    + +

    昨天朝野都有備而來,綠軍製作大量標語牌,藍軍拿擴音器嗆聲反制。製作標語的長水管及木桿、立委的二哥大,甚至議場內的水杯,全成了打架的工具。

    + +

    院會昨天上午約十一時進入實質審議,親民黨立委李永萍要求停止討論、進入逐條審查議程,引發民進黨不滿,主席雖裁示暫時休息;由於情緒已點燃,繼續開會後爆發流血衝突。

    + +

    會議進行時,為免主席台再被佔領,藍軍立委張碩文、周守訓、費鴻泰等組成捍衛隊守在主席台下,綠軍也向主席台聚集,兩軍推擠、叫陣,場面失控。

    + +

    混亂中,張碩文揮拳,但也在拉扯中跌倒,他左眼受傷、滿臉是血,手還拿著沾滿血的手機,他指控李明憲打他。李明憲則是眼鏡被打掉,嘴角流血,痛斥遭張碩文毆打。兩人都送台大醫院治療,張碩文左上眼瞼有二處撕裂傷,另有輕微出血,縫合九針。

    + +

    李明憲有頭暈、頸痛、嘔吐感等症狀,右下眼皮有瘀傷,左膝蓋有兩處擦傷,左膝蓋韌帶也受傷。兩人均未向立院警衛隊報案。

    + +

    國民黨團成員昨晚探視張碩文,都建議他應提告訴,但張碩文因身體不適,未明確表達意向,與張碩文友好的無黨籍立委張麗善認為,他應該會提告訴。國民黨團並建議,應將打人者送交紀律委員會議處。李明憲昨晚表示,未打算提出告訴。

    + +

    互控對方早有預謀

    + +

    國民黨團指民進黨前幾天就放話不惜血戰,是預謀的。民進黨團則回擊,泛藍早安排張碩文等當打手,泛藍應負最大責任。

    + +

    發生流血衝突,國親兩黨團對主席王金平不動用警察權頗有怨言,國民黨主席馬英九說:如果有人動粗,一定要有公權力制止,絕不能縱容。王金平卻說,要如何動用警察權不是馬英九怎麼要求,就怎麼做,議會是自主的。

    + +

    紀律委員會如虛設

    + +

    對於這起流血衝突事件,東海大學政治系副教授傅恆德批評,立委打架凸顯個人素養不好,國會暴力只有在民主政治發展初期的社會才出現,立委不應用暴力凸顯議題,任何暴力行為都應在國會消失!

    + +

    東吳大學政治系副教授羅致政則認為,民進黨不應阻擋NCC草案,畢竟國親佔多數,擋得了一時,也擋不了整個會期,尤其面對高度爭議性法案,政黨領袖應發揮智慧,尋求妥協,而不是採非零即一的零和策略。

    + +

    事實上,暴力衝突、攜帶危險物品、杯葛議事等行為,都違反立院內規《立法委員行為法》,要送交紀律委員會議處,但紀委會功能不彰,形同虛設,因此立院每隔一段時間,總會重演暴力殿堂違紀事件

    +
    + +
    +

    蘋論 打死一個少一個

    + +

    看到立法院打得頭破血流,民眾既難過又痛快。難過的是什麼年頭了還打架,台灣真是丟臉落後啊。痛快的是立委作為社會亂源第一名,打死一個少一個。

    + +

    一對老夫妻同時彌留,子女問他倆有何遺願。老爸爸說死前要加入民進黨;老媽媽說死前要加入國民黨。兒女大奇,問理由,二老說入黨成為黨員,死一個少一個。為了社會安寧祥和,我們建議政府在立院會期發給立委機槍手榴彈,讓他們互殺個痛快。

    + +

    打架非臨時起意

    + +

    立委不是臨時起意打架的,而是預謀。看他們前天就準備軍裝、跆拳裝、迷彩裝,還頭戴鋼盔就知道是準備好大打出手的。國會議員竟以身著打架裝為榮,其孩童般幼稚令人啼笑皆非。國會的設置的目的,就是為了取代打架打仗的方式分享權力,沒想到台灣還是靠拳頭議事,完全背反國會設立的精神。

    + +

    往樂觀面看,這是民主的陣痛和過程。美國在19世紀和20世紀初,國會也是比武擂台。1838年眾議員席立和葛瑞夫決鬥,席立被殺。

    + +

    國會特別委員會要求開除葛氏,但國會不理,那時決鬥是司空見慣之行為。

    + +

    1850 年,參議員福特正在發言,參議員班頓做出威脅狀,福特掏出手槍上膛,被他人攔阻才沒出事。1856年,參議員桑納在會場內遭眾議員布魯克斯持手杖打得頭破血流。1902年,參議員提耳曼發言質疑麥勞倫的操守,麥則指責提惡意中傷。兩人扭打在地。事後院會通過決議譴責兩人。20世紀中葉以後美國國會絕少有打架的事例,大家已經獲得共識:由數人頭代替出拳頭。國會的文明因而建立。

    + +

    把對方看成異己

    + +

    台灣國會要走向文明比美國難,因為台灣認同分裂,而認同連結血緣,生殖器決定大腦,就把對方看成異己和敵人,便會恨之欲其死了。

    + +

    當初美國並無難解的認同分裂,頂多是理念和利益的對立,妥協即可解決。認同分裂的對抗是無法妥協的,非至你死我活不可。這就是台灣今日的困境,會因泛藍日益偏向中國、泛綠日益偏向台獨而更加水火不容。所以不發給他們武器互殺怎麼解恨呢?

    + +

    此時政黨領袖和意見領袖不可護短並發表煽動情緒的言語,那是無恥政客的作風─火上加油;政治家此時要呼籲冷靜,譴責暴力,向對方伸出友善的手,以社會責任為優先,而非以一黨之私為優先。現在就看扁、馬、宋誰是政客、誰是政治家了。

    +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 13 | + 14 | + 15 | + 16 | + 17 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0016.html.en.html b/htdocs/imacat/me/diary/0016.html.en.html new file mode 120000 index 0000000..497d373 --- /dev/null +++ b/htdocs/imacat/me/diary/0016.html.en.html @@ -0,0 +1 @@ +0016.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0016.html.en.xhtml b/htdocs/imacat/me/diary/0016.html.en.xhtml new file mode 100644 index 0000000..58cbc5a --- /dev/null +++ b/htdocs/imacat/me/diary/0016.html.en.xhtml @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 16 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 16

    + +
    + +
    + +
    +
    11.21.’05. 4:35pm.
    + +
    +終於把身邊的所有伺服器
    +通通都從 Linux kernel 2.4 昇級到 2.6 了
    +可喜可賀~ *^_^*
    +
    +整整兩個星期熬夜摸索
    +每天下班回來,一直做到深夜
    +一個一個查看 2.6 的新選項,一次一次編譯、失敗、找答案
    +檢查硬體規格,各主機板的說明文件,檢閱系統訊息
    +直到各個硬體趨動程式都逐漸順利載入,系統功能逐漸恢復,慢慢穩定下來
    +前兩天大約穩定了下來,對 Linux kernel 2.6 比較有信心了
    +開始更新身邊的所有 Linux 電腦
    +我管的全部九台伺服器加上兩台電腦,一起把它們昇級上去
    +
    +如果把之前的前置作業
    +為 Debian 3.0 Woody 昇級為 Debian 3.1 Sarge
    +及為 Mandrake 10.1 昇級為 Mandriva 2006.0
    +半個月左右的準備工作通通加起來
    +前前後後,不眠不休地忙了一個月的時間
    +
    +終於結束了,鬆了一口氣
    +可喜可賀~ *^_^* +
    + +
    + +
    + +
    +
    11.14.’05. 4:01am.
    + +
    +今晚看了金馬獎搬獎典禮
    +好幾年沒看了
    +
    +沒想到周星馳的「功夫」是最大贏家
    +一共抱走了五個獎項
    +之前最被看好,入圍十一項的杜琪峰的「黑社會」
    +只得了兩個獎
    +
    +不過功夫那五個獎,可以說是實至名歸了
    +尤其是元秋飾演的包租婆小龍女
    +不管是造型或是演技,都沒有話說
    +呵呵~ ^_*' +
    + +
    + +
    + +
    +
    11.10.’05. 5:45pm.
    + +
    +昨天早上去參加了一個朋友母親的告別式
    +
    +前幾年一個朋友的父親過世了
    +陪著她走完所有的儀禮
    +前天,坐在我旁邊的同事接到一通電話,她一個好朋友的母親住院幾個星期後,就這樣走了
    +然後昨天早上,去參加了這場朋友母親的告別式
    +
    +回來的路上一直想
    +覺得自己已經到了一個年紀
    +我們身邊的親長輩,開始會慢慢地走掉,或是退休、老了的年紀
    +慢慢我們開始成為家裏的主幹,要獨立撐起家庭的年紀
    +
    +嗯
    +這就是步入中年的感覺嗎 +
    + +
    + +
    + +
    +
    11.4.’05. 2:57pm.
    + +
    +加註一下前面的肯德基薄皮嫩雞事件
    +那個肯德基薄皮嫩雞,真的不好吃
    +炸皮口感像是比斯吉一樣
    +(還有人記得嗎?以前肯德基賣一種叫做比斯吉的小點心)
    +酥酥軟軟的,隨便一捏就碎得整個手都是
    +噁心死了
    +哪有心情去品嚐那什麼入味直達骨髓的雞肉
    +
    +我不知道肯德基怎麼有臉自吹自擂說是什麼「內行人的炸雞」
    +絕對不是什麼就算丟盡臉也非吃不可的好吃炸雞 +
    + +
    + +
    + +
    +
    11.1.’05. 11:15pm.
    + +
    +最近在看森左智的「特攻女神隊」
    +一部以女暴走族幫派為主題的漫畫
    +真的很好看~ *^_^*
    +
    +上網查了一下,有些人把森左智歸為男漫畫家
    +ㄟ,森左智的畫風雖然不大像少女漫畫,不大美形
    +不過她本人可是貨真價實的女生!
    +
    +她在漫畫扉頁中自述,她自己年輕時也曾經叛逆,到處打架過
    +所以一直很畫一部以青少女暴走族為主題的漫畫
    +
    +嗯
    +真的很酷很好看呢~ ^_*' +
    + +
    + +
    + +
    +
    10.26.’05. 5:26pm.
    + +
    +今天中午,我做了一件這幾年來最後悔的事
    +
    +今天午餐走到肯德基旁邊
    +想到最近電視廣告的肯德雞「您真內行」的薄皮嫩雞
    +雖然我不敢自稱美食家,而且我不喜歡肯德基,幾年來一步也沒有踏進去過
    +不過真正好吃又吃得起的東西,我也不想錯過
    +既然肯德雞廣告吹噓薄皮嫩雞多好吃多好吃,還說是內行人的炸雞
    +想起今天沒吃早餐,就走進去了
    +
    +走進去,櫃檯小姐問我要吃什麼,順便跟我推薦薄皮嫩雞餐
    +我本來就是進來吃薄皮嫩雞餐了,就說好
    +然後就... 發生了足以讓我後悔好幾年的事...
    +
    +小姐向櫃台後大聲重覆了一句「薄皮嫩雞餐」
    +然後按了一下旁邊那時候我不知道做什麼用的鈴
    +用盡生平的力氣,對我大聲喊了一句
    +「您真內行!!」
    +瞬間,整個廚房的工讀生一呼百應,響轍雲霄:「您真內行!!」
    +
    +那一瞬間,我整個人凍結成冰塊,無法動彈
    +嘴角開始抽筋,臉上佈滿斜線
    +腦袋裏只想趕快挖個地洞鑽進去
    +偏偏櫃台打工的小姐,就是剛剛對我大喊「您真內行!!」的小姐
    +還用一副天真無邪的微笑,問我要可樂還是要汽水
    +那副天真無邪的眼神,彷彿是在問我
    +「為什麼不說話呢?是因為我太可愛而呆住了嗎?」
    +
    +我發誓
    +我再也不踏進肯德基一步 +
    + +
    + +
    + +
    +
    10.19.’05. 1:02am.
    + +
    +想起一件之前發生的事
    +
    +上個月某一天,我中午休息時間,去遠傳繳手機話費
    +(永和竹林門市,永和市竹林路 222 號,別說我不指明道姓無從查證起)
    +這本來是和信的門市,遠傳購併和信後,變成遠傳的門市
    +門市小小的,坪數不大,四個櫃台都有人
    +進去看到有些人已經在排隊了
    +抽了號碼牌, 272 號,等候號數有 9 號,叫號叫到 262 號
    +門市天花板有吊一個電視機,上面持續播著遠傳的廣告
    +反正還要等,我就隨便看看,打發時間
    +
    +看著看著,看到遠傳電信的企業形象廣告
    +遠傳董事長徐旭東說一段偉大的話,然後一個老外執行長也說了另一段偉大的話
    +然後用生動的 3D 動畫,營業額如何如何上昇, 2000 年幾億, 2001 年幾億
    +接下來是用戶人數,也是直線上昇, 2000 年幾百萬, 2001 年幾百萬
    +然後是客服的成就
    +某某年成立全國最大的客服中心,某某年客服人數達到多少人,某某年多少人,某某年票選客服第一名
    +.........
    +
    +看到這裏,突然一股無名火起
    +
    +為什麼一肚子火?
    +因為在那個時候,我已經等了 *半個小時* 了
    +叫號還是叫到 262 號,我前面還是有 9 號,一動也不動
    +不過現在等候號數已經到了 26 號,小小的門市滿滿都是人
    +四個櫃台好像都是在新辦門號挑手機,幾支手機挑來挑去,填表也只填到一半
    +櫃台服務人員熱心地穿梭、拿表格,介紹手機
    +我只是要繳個費,繳費單也補好了,錢也拿在手上
    +到櫃台用條碼機一掃,錢點一點,等印表機印收據,蓋個經辦章,前後不需要 20 秒
    +為了辦一件 20 秒可以完成的事,我足足等了 *半個小時* ,等四個櫃台慢慢游說新用戶挑手機
    +
    +過了好久,一號櫃台終於空下來了
    +櫃台服務人員喊了一句:有要繳費的嗎?可以先過去
    +我趕快搶過去繳,後面跟了一大票
    +掃條碼,付錢,蓋印章,拿收據,走人,前後只花了十來秒
    +幾乎所有人都接在我後面, 小小的門市幾乎一下子就清空了
    +
    +我中午是趁午休出來辦事的,辦完事還要回公司,時間不多,不可能一直在那邊耗
    +二十幾組人在排隊,全都是去繳費,花二十秒繳完費就要走人的
    +結果所有人一起在那邊等了半個多小時,就為了四組新用戶慢慢在挑手機
    +為什麼不設個繳費專用櫃台?
    +中華電信有繳費專用櫃台,以前的和信也有
    +這件事我前個月跟遠傳竹林門市抗議過,門市服務人員還說會反映
    +反映完就沒有下文了,過了一個月,還是一模一樣
    +
    +遠傳電信比較重視拉新用戶,勝於服務繳費的舊用戶嗎?
    +賣東西第一優先,後續服務就可以無所謂了嗎?
    +新用戶會創造新收入,舊用戶就跑不掉了是嗎?
    +
    +這兩天遠傳在電視上大打形象廣告
    +又讓我想起這一件幾個星期前發生的事
    +超大型客服中心?客服人數最多?客服滿意度第一名?
    +邊看這些自吹自捧的廣告,邊等得怒火直燒 +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 14 | + 15 | + 16 | + 17 | + 18 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0016.html.zh-cn.html b/htdocs/imacat/me/diary/0016.html.zh-cn.html new file mode 120000 index 0000000..9771072 --- /dev/null +++ b/htdocs/imacat/me/diary/0016.html.zh-cn.html @@ -0,0 +1 @@ +0016.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0016.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0016.html.zh-cn.xhtml new file mode 100644 index 0000000..e5b71eb --- /dev/null +++ b/htdocs/imacat/me/diary/0016.html.zh-cn.xhtml @@ -0,0 +1,370 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷十六

    + +
    + +
    + +
    +
    11.21.’05. 4:35pm.
    + +
    +终于把身边的所有伺服器
    +通通都从 Linux kernel 2.4 升级到 2.6 了
    +可喜可贺~ *^_^*
    +
    +整整两个星期熬夜摸索
    +每天下班回来,一直做到深夜
    +一个一个查看 2.6 的新选项,一次一次编译、失败、找答案
    +检查硬体规格,各主机板的说明文件,检阅系统讯息
    +直到各个硬体趋动程式都逐渐顺利载入,系统功能逐渐恢复,慢慢稳定下来
    +前两天大约稳定了下来,对 Linux kernel 2.6 比较有信心了
    +开始更新身边的所有 Linux 电脑
    +我管的全部九台伺服器加上两台电脑,一起把它们升级上去
    +
    +如果把之前的前置作业
    +为 Debian 3.0 Woody 升级为 Debian 3.1 Sarge
    +及为 Mandrake 10.1 升级为 Mandriva 2006.0
    +半个月左右的准备工作通通加起来
    +前前后后,不眠不休地忙了一个月的时间
    +
    +终于结束了,松了一口气
    +可喜可贺~ *^_^* +
    + +
    + +
    + +
    +
    11.14.’05. 4:01am.
    + +
    +今晚看了金马奖搬奖典礼
    +好几年没看了
    +
    +没想到周星驰的「功夫」是最大赢家
    +一共抱走了五个奖项
    +之前最被看好,入围十一项的杜琪峰的「黑社会」
    +只得了两个奖
    +
    +不过功夫那五个奖,可以说是实至名归了
    +尤其是元秋饰演的包租婆小龙女
    +不管是造型或是演技,都没有话说
    +呵呵~ ^_*' +
    + +
    + +
    + +
    +
    11.10.’05. 5:45pm.
    + +
    +昨天早上去参加了一个朋友母亲的告别式
    +
    +前几年一个朋友的父亲过世了
    +陪著她走完所有的仪礼
    +前天,坐在我旁边的同事接到一通电话,她一个好朋友的母亲住院几个星期后,就这样走了
    +然后昨天早上,去参加了这场朋友母亲的告别式
    +
    +回来的路上一直想
    +觉得自己已经到了一个年纪
    +我们身边的亲长辈,开始会慢慢地走掉,或是退休、老了的年纪
    +慢慢我们开始成为家里的主干,要独立撑起家庭的年纪
    +
    +嗯
    +这就是步入中年的感觉吗 +
    + +
    + +
    + +
    +
    11.4.’05. 2:57pm.
    + +
    +加注一下前面的肯德基薄皮嫩鸡事件
    +那个肯德基薄皮嫩鸡,真的不好吃
    +炸皮口感像是比斯吉一样
    +(还有人记得吗?以前肯德基卖一种叫做比斯吉的小点心)
    +酥酥软软的,随便一捏就碎得整个手都是
    +恶心死了
    +哪有心情去品尝那什么入味直达骨髓的鸡肉
    +
    +我不知道肯德基怎么有脸自吹自擂说是什么「内行人的炸鸡」
    +绝对不是什么就算丢尽脸也非吃不可的好吃炸鸡 +
    + +
    + +
    + +
    +
    11.1.’05. 11:15pm.
    + +
    +最近在看森左智的「特攻女神队」
    +一部以女暴走族帮派为主题的漫画
    +真的很好看~ *^_^*
    +
    +上网查了一下,有些人把森左智归为男漫画家
    +ㄟ,森左智的画风虽然不大像少女漫画,不大美形
    +不过她本人可是货真价实的女生!
    +
    +她在漫画扉页中自述,她自己年轻时也曾经叛逆,到处打架过
    +所以一直很画一部以青少女暴走族为主题的漫画
    +
    +嗯
    +真的很酷很好看呢~ ^_*' +
    + +
    + +
    + +
    +
    10.26.’05. 5:26pm.
    + +
    +今天中午,我做了一件这几年来最后悔的事
    +
    +今天午餐走到肯德基旁边
    +想到最近电视广告的肯德鸡「您真内行」的薄皮嫩鸡
    +虽然我不敢自称美食家,而且我不喜欢肯德基,几年来一步也没有踏进去过
    +不过真正好吃又吃得起的东西,我也不想错过
    +既然肯德鸡广告吹嘘薄皮嫩鸡多好吃多好吃,还说是内行人的炸鸡
    +想起今天没吃早餐,就走进去了
    +
    +走进去,柜台小姐问我要吃什么,顺便跟我推荐薄皮嫩鸡餐
    +我本来就是进来吃薄皮嫩鸡餐了,就说好
    +然后就... 发生了足以让我后悔好几年的事...
    +
    +小姐向柜台后大声重覆了一句「薄皮嫩鸡餐」
    +然后按了一下旁边那时候我不知道做什么用的铃
    +用尽生平的力气,对我大声喊了一句
    +「您真内行!!」
    +瞬间,整个厨房的工读生一呼百应,响辙云霄:「您真内行!!」
    +
    +那一瞬间,我整个人冻结成冰块,无法动弹
    +嘴角开始抽筋,脸上布满斜线
    +脑袋里只想赶快挖个地洞钻进去
    +偏偏柜台打工的小姐,就是刚刚对我大喊「您真内行!!」的小姐
    +还用一副天真无邪的微笑,问我要可乐还是要汽水
    +那副天真无邪的眼神,彷佛是在问我
    +「为什么不说话呢?是因为我太可爱而呆住了吗?」
    +
    +我发誓
    +我再也不踏进肯德基一步 +
    + +
    + +
    + +
    +
    10.19.’05. 1:02am.
    + +
    +想起一件之前发生的事
    +
    +上个月某一天,我中午休息时间,去远传缴手机话费
    +(永和竹林门市,永和市竹林路 222 号,别说我不指明道姓无从查证起)
    +这本来是和信的门市,远传购并和信后,变成远传的门市
    +门市小小的,坪数不大,四个柜台都有人
    +进去看到有些人已经在排队了
    +抽了号码牌, 272 号,等候号数有 9 号,叫号叫到 262 号
    +门市天花板有吊一个电视机,上面持续播著远传的广告
    +反正还要等,我就随便看看,打发时间
    +
    +看著看著,看到远传电信的企业形象广告
    +远传董事长徐旭东说一段伟大的话,然后一个老外执行长也说了另一段伟大的话
    +然后用生动的 3D 动画,营业额如何如何上升, 2000 年几亿, 2001 年几亿
    +接下来是用户人数,也是直线上升, 2000 年几百万, 2001 年几百万
    +然后是客服的成就
    +某某年成立全国最大的客服中心,某某年客服人数达到多少人,某某年多少人,某某年票选客服第一名
    +.........
    +
    +看到这里,突然一股无名火起
    +
    +为什么一肚子火?
    +因为在那个时候,我已经等了 *半个小时* 了
    +叫号还是叫到 262 号,我前面还是有 9 号,一动也不动
    +不过现在等候号数已经到了 26 号,小小的门市满满都是人
    +四个柜台好像都是在新办门号挑手机,几支手机挑来挑去,填表也只填到一半
    +柜台服务人员热心地穿梭、拿表格,介绍手机
    +我只是要缴个费,缴费单也补好了,钱也拿在手上
    +到柜台用条码机一扫,钱点一点,等印表机印收据,盖个经办章,前后不需要 20 秒
    +为了办一件 20 秒可以完成的事,我足足等了 *半个小时* ,等四个柜台慢慢游说新用户挑手机
    +
    +过了好久,一号柜台终于空下来了
    +柜台服务人员喊了一句:有要缴费的吗?可以先过去
    +我赶快抢过去缴,后面跟了一大票
    +扫条码,付钱,盖印章,拿收据,走人,前后只花了十来秒
    +几乎所有人都接在我后面, 小小的门市几乎一下子就清空了
    +
    +我中午是趁午休出来办事的,办完事还要回公司,时间不多,不可能一直在那边耗
    +二十几组人在排队,全都是去缴费,花二十秒缴完费就要走人的
    +结果所有人一起在那边等了半个多小时,就为了四组新用户慢慢在挑手机
    +为什么不设个缴费专用柜台?
    +中华电信有缴费专用柜台,以前的和信也有
    +这件事我前个月跟远传竹林门市抗议过,门市服务人员还说会反映
    +反映完就没有下文了,过了一个月,还是一模一样
    +
    +远传电信比较重视拉新用户,胜于服务缴费的旧用户吗?
    +卖东西第一优先,后续服务就可以无所谓了吗?
    +新用户会创造新收入,旧用户就跑不掉了是吗?
    +
    +这两天远传在电视上大打形象广告
    +又让我想起这一件几个星期前发生的事
    +超大型客服中心?客服人数最多?客服满意度第一名?
    +边看这些自吹自捧的广告,边等得怒火直烧 +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 14 | + 15 | + 16 | + 17 | + 18 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0016.html.zh-tw.html b/htdocs/imacat/me/diary/0016.html.zh-tw.html new file mode 120000 index 0000000..1c2cac3 --- /dev/null +++ b/htdocs/imacat/me/diary/0016.html.zh-tw.html @@ -0,0 +1 @@ +0016.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0016.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0016.html.zh-tw.xhtml new file mode 100644 index 0000000..7c61eba --- /dev/null +++ b/htdocs/imacat/me/diary/0016.html.zh-tw.xhtml @@ -0,0 +1,370 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷十六

    + +
    + +
    + +
    +
    11.21.’05. 4:35pm.
    + +
    +終於把身邊的所有伺服器
    +通通都從 Linux kernel 2.4 昇級到 2.6 了
    +可喜可賀~ *^_^*
    +
    +整整兩個星期熬夜摸索
    +每天下班回來,一直做到深夜
    +一個一個查看 2.6 的新選項,一次一次編譯、失敗、找答案
    +檢查硬體規格,各主機板的說明文件,檢閱系統訊息
    +直到各個硬體趨動程式都逐漸順利載入,系統功能逐漸恢復,慢慢穩定下來
    +前兩天大約穩定了下來,對 Linux kernel 2.6 比較有信心了
    +開始更新身邊的所有 Linux 電腦
    +我管的全部九台伺服器加上兩台電腦,一起把它們昇級上去
    +
    +如果把之前的前置作業
    +為 Debian 3.0 Woody 昇級為 Debian 3.1 Sarge
    +及為 Mandrake 10.1 昇級為 Mandriva 2006.0
    +半個月左右的準備工作通通加起來
    +前前後後,不眠不休地忙了一個月的時間
    +
    +終於結束了,鬆了一口氣
    +可喜可賀~ *^_^* +
    + +
    + +
    + +
    +
    11.14.’05. 4:01am.
    + +
    +今晚看了金馬獎搬獎典禮
    +好幾年沒看了
    +
    +沒想到周星馳的「功夫」是最大贏家
    +一共抱走了五個獎項
    +之前最被看好,入圍十一項的杜琪峰的「黑社會」
    +只得了兩個獎
    +
    +不過功夫那五個獎,可以說是實至名歸了
    +尤其是元秋飾演的包租婆小龍女
    +不管是造型或是演技,都沒有話說
    +呵呵~ ^_*' +
    + +
    + +
    + +
    +
    11.10.’05. 5:45pm.
    + +
    +昨天早上去參加了一個朋友母親的告別式
    +
    +前幾年一個朋友的父親過世了
    +陪著她走完所有的儀禮
    +前天,坐在我旁邊的同事接到一通電話,她一個好朋友的母親住院幾個星期後,就這樣走了
    +然後昨天早上,去參加了這場朋友母親的告別式
    +
    +回來的路上一直想
    +覺得自己已經到了一個年紀
    +我們身邊的親長輩,開始會慢慢地走掉,或是退休、老了的年紀
    +慢慢我們開始成為家裏的主幹,要獨立撐起家庭的年紀
    +
    +嗯
    +這就是步入中年的感覺嗎 +
    + +
    + +
    + +
    +
    11.4.’05. 2:57pm.
    + +
    +加註一下前面的肯德基薄皮嫩雞事件
    +那個肯德基薄皮嫩雞,真的不好吃
    +炸皮口感像是比斯吉一樣
    +(還有人記得嗎?以前肯德基賣一種叫做比斯吉的小點心)
    +酥酥軟軟的,隨便一捏就碎得整個手都是
    +噁心死了
    +哪有心情去品嚐那什麼入味直達骨髓的雞肉
    +
    +我不知道肯德基怎麼有臉自吹自擂說是什麼「內行人的炸雞」
    +絕對不是什麼就算丟盡臉也非吃不可的好吃炸雞 +
    + +
    + +
    + +
    +
    11.1.’05. 11:15pm.
    + +
    +最近在看森左智的「特攻女神隊」
    +一部以女暴走族幫派為主題的漫畫
    +真的很好看~ *^_^*
    +
    +上網查了一下,有些人把森左智歸為男漫畫家
    +ㄟ,森左智的畫風雖然不大像少女漫畫,不大美形
    +不過她本人可是貨真價實的女生!
    +
    +她在漫畫扉頁中自述,她自己年輕時也曾經叛逆,到處打架過
    +所以一直很畫一部以青少女暴走族為主題的漫畫
    +
    +嗯
    +真的很酷很好看呢~ ^_*' +
    + +
    + +
    + +
    +
    10.26.’05. 5:26pm.
    + +
    +今天中午,我做了一件這幾年來最後悔的事
    +
    +今天午餐走到肯德基旁邊
    +想到最近電視廣告的肯德雞「您真內行」的薄皮嫩雞
    +雖然我不敢自稱美食家,而且我不喜歡肯德基,幾年來一步也沒有踏進去過
    +不過真正好吃又吃得起的東西,我也不想錯過
    +既然肯德雞廣告吹噓薄皮嫩雞多好吃多好吃,還說是內行人的炸雞
    +想起今天沒吃早餐,就走進去了
    +
    +走進去,櫃檯小姐問我要吃什麼,順便跟我推薦薄皮嫩雞餐
    +我本來就是進來吃薄皮嫩雞餐了,就說好
    +然後就... 發生了足以讓我後悔好幾年的事...
    +
    +小姐向櫃台後大聲重覆了一句「薄皮嫩雞餐」
    +然後按了一下旁邊那時候我不知道做什麼用的鈴
    +用盡生平的力氣,對我大聲喊了一句
    +「您真內行!!」
    +瞬間,整個廚房的工讀生一呼百應,響轍雲霄:「您真內行!!」
    +
    +那一瞬間,我整個人凍結成冰塊,無法動彈
    +嘴角開始抽筋,臉上佈滿斜線
    +腦袋裏只想趕快挖個地洞鑽進去
    +偏偏櫃台打工的小姐,就是剛剛對我大喊「您真內行!!」的小姐
    +還用一副天真無邪的微笑,問我要可樂還是要汽水
    +那副天真無邪的眼神,彷彿是在問我
    +「為什麼不說話呢?是因為我太可愛而呆住了嗎?」
    +
    +我發誓
    +我再也不踏進肯德基一步 +
    + +
    + +
    + +
    +
    10.19.’05. 1:02am.
    + +
    +想起一件之前發生的事
    +
    +上個月某一天,我中午休息時間,去遠傳繳手機話費
    +(永和竹林門市,永和市竹林路 222 號,別說我不指明道姓無從查證起)
    +這本來是和信的門市,遠傳購併和信後,變成遠傳的門市
    +門市小小的,坪數不大,四個櫃台都有人
    +進去看到有些人已經在排隊了
    +抽了號碼牌, 272 號,等候號數有 9 號,叫號叫到 262 號
    +門市天花板有吊一個電視機,上面持續播著遠傳的廣告
    +反正還要等,我就隨便看看,打發時間
    +
    +看著看著,看到遠傳電信的企業形象廣告
    +遠傳董事長徐旭東說一段偉大的話,然後一個老外執行長也說了另一段偉大的話
    +然後用生動的 3D 動畫,營業額如何如何上昇, 2000 年幾億, 2001 年幾億
    +接下來是用戶人數,也是直線上昇, 2000 年幾百萬, 2001 年幾百萬
    +然後是客服的成就
    +某某年成立全國最大的客服中心,某某年客服人數達到多少人,某某年多少人,某某年票選客服第一名
    +.........
    +
    +看到這裏,突然一股無名火起
    +
    +為什麼一肚子火?
    +因為在那個時候,我已經等了 *半個小時* 了
    +叫號還是叫到 262 號,我前面還是有 9 號,一動也不動
    +不過現在等候號數已經到了 26 號,小小的門市滿滿都是人
    +四個櫃台好像都是在新辦門號挑手機,幾支手機挑來挑去,填表也只填到一半
    +櫃台服務人員熱心地穿梭、拿表格,介紹手機
    +我只是要繳個費,繳費單也補好了,錢也拿在手上
    +到櫃台用條碼機一掃,錢點一點,等印表機印收據,蓋個經辦章,前後不需要 20 秒
    +為了辦一件 20 秒可以完成的事,我足足等了 *半個小時* ,等四個櫃台慢慢游說新用戶挑手機
    +
    +過了好久,一號櫃台終於空下來了
    +櫃台服務人員喊了一句:有要繳費的嗎?可以先過去
    +我趕快搶過去繳,後面跟了一大票
    +掃條碼,付錢,蓋印章,拿收據,走人,前後只花了十來秒
    +幾乎所有人都接在我後面, 小小的門市幾乎一下子就清空了
    +
    +我中午是趁午休出來辦事的,辦完事還要回公司,時間不多,不可能一直在那邊耗
    +二十幾組人在排隊,全都是去繳費,花二十秒繳完費就要走人的
    +結果所有人一起在那邊等了半個多小時,就為了四組新用戶慢慢在挑手機
    +為什麼不設個繳費專用櫃台?
    +中華電信有繳費專用櫃台,以前的和信也有
    +這件事我前個月跟遠傳竹林門市抗議過,門市服務人員還說會反映
    +反映完就沒有下文了,過了一個月,還是一模一樣
    +
    +遠傳電信比較重視拉新用戶,勝於服務繳費的舊用戶嗎?
    +賣東西第一優先,後續服務就可以無所謂了嗎?
    +新用戶會創造新收入,舊用戶就跑不掉了是嗎?
    +
    +這兩天遠傳在電視上大打形象廣告
    +又讓我想起這一件幾個星期前發生的事
    +超大型客服中心?客服人數最多?客服滿意度第一名?
    +邊看這些自吹自捧的廣告,邊等得怒火直燒 +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 14 | + 15 | + 16 | + 17 | + 18 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0017.html.en.html b/htdocs/imacat/me/diary/0017.html.en.html new file mode 120000 index 0000000..ebef7cf --- /dev/null +++ b/htdocs/imacat/me/diary/0017.html.en.html @@ -0,0 +1 @@ +0017.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0017.html.en.xhtml b/htdocs/imacat/me/diary/0017.html.en.xhtml new file mode 100644 index 0000000..83d4b59 --- /dev/null +++ b/htdocs/imacat/me/diary/0017.html.en.xhtml @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 17 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 17

    + +
    + +
    + +
    +
    1.27.’06. 5:19am.
    + +

    終於把 MySQL server 昇級到 5.0 了。又是一個星期過去了。天已經快亮了,總算了卻一樁心事。

    + +

    我公司的案子怎麼辦哪~~ ^^;

    + +
    + +
    + +
    +
    1.23.’06. 3:53am.
    + +

    終於昇級了 MySQL server ,從 4.0 昇級到 4.1 。

    + +

    原本以為是兩天左右的工作,沒想到搞了一個星期。好累。雖然我的身邊環境已經沒有什麼在用 MySQL 了,可是我還是很不喜歡放一個很舊版很舊版的 server 在那邊,更何況 MySQL 現在已經是 5.0 了,中間還隔了一個 4.1 , 4.0 在 MySQL 網站上已經找不到了。

    + +

    仔細讀完昇級說明,測試新版的功能,一筆一筆檢查、找出有問題的資料,加以更正,檢查、更正舊網站程式的相容性。沒想到會做得這麼辛苦。

    + +

    還要昇級到 5.0 。嗯嗯。

    + +
    + +
    + +
    +
    1.2.’06. 5:06pm.
    + +
    +看著 Windows XP 視窗下的工作列
    +完成一個工作後,關掉一窗
    +以為可以喘口氣了
    +其它窗馬上又自動放大,把工作列填滿了
    +
    +好像我的生活一樣
    +
    +多開一窗,關掉一窗,工作列都是滿的
    +好像也沒有什麼分別 +
    + +
    + +
    + +
    +
    12.19.’05. 11:58pm.
    + +
    +昔人已乘黃鶴去 此地空餘黃鶴樓
    +黃鶴一去不復返 白雲千載空悠悠
    +晴川歷歷漢陽樹 芳草萋萋鸚鵡洲
    +日幕鄉關何處是 煙波江上使人愁 +
    + +
    + +
    + +
    +
    12.7.’05. 12:27pm.
    + +

    這一陣子系統昇級,心頭最後一塊大石— glibc 的新線程模式 TLS/NPTL ,終於完成了編譯與安裝實驗,並且成功安裝到七台伺服器上了。

    + +

    好累,累到快瘋了。在虛擬電腦伺服器上,不斷重複新編譯—安裝—修正參數—重新編譯的循環。虛擬電腦很慢,編譯一次就要半天,安裝一次要一個小時,一但失敗,就要去到處找原因,修正參數以後,一切重來。如果是安裝失敗,系統就毀了,還要趕緊找出救援開機光碟,把被蓋掉的檔案一個一個 copy 回去,才能繼續下一個實驗。

    + +

    就這樣,連著快一個星期,失敗了十幾次,才慢慢實驗出正確的系統參數,和安全的安裝昇級步驟。昨晚覺得安裝、昇級步驟差不多沒有問題了,而且我也累垮了,決定不等虛擬伺服器的最後一次編譯(可能還要一天半),直接裝到 rinse 上去試試看。結果非常順利!接下來遠端把剩下來的五台伺服器一一安裝上去、重開機,沒想到公司的主伺服器竟然沒有開機開出來,只好在寒冷的半夜十一點半穿上大衣,騎摩托車飆去公司,把它開起來。回來已經十二點了。

    + +

    心頭一塊大石總算放了下來。一切結束以後,累得眼睛都花了,看東西看不清楚,整個人精神都散了下來。

    + +
    + +
    + +
    +
    12.6.’05. 4:46am.
    + +

    等實驗跑的時候,來寫一本不久前看的漫畫:岩明均的歷史之眼(ヒストリエ,即 History 的片仮名,日本講談社,台灣授權東立代理)。

    + +

    岩明均的成名作是寄生獸,寄生獸並獲得第 17 回講談社漫画賞。平淡寫實的線條,伴著惡夢似的殘酷感,有如難分虛實的夢靨一般,直鑽入精神意識底層,擾亂夢境和真實的界線,讓人不禁神為之奪。即使合上書本,仍然久久無法擺脫夢靨般的感受。

    + +

    歷史之眼是很特殊的題材(至少是我不曾看過的漫畫題材)。岩明均以接近寫實的角度,描述亞歷山大大帝身邊的私人秘書卡地亞的尤米尼斯(カルディアのエウメネス, Eumenes of Cardia ,較常見譯為歐邁尼斯,亦有譯為攸梅尼斯尤美尼斯優美尼斯優門尼斯者,都是同一個人,惜未見正式中文譯名),手上的王宮日誌 (Royal Diary) 中,所記載的事。王宮日誌由 Eumenes 所撰記,是研究亞歷山大大帝的重要參考史料。藉由王宮日誌敘述 Eumenes 的故事,原先的說故事的人,轉而成為岩明均故事的內容對象。

    + +

    我沒有看過這樣的題材,一部以平淡、寫實的角度,繪製的歷史漫畫,沒有如三國志、日本戰國時代般浮誇的幻想情節,沒有如陳某的不是人般的激情和重訂歷史的強烈企圖,岩明均以平鋪直述,卻又不可逼視的歷史現實的殘酷,引人入勝。

    + +

    歷史之眼目前台灣出版到第一、二集,日本已經出版到第三集了。我很期待續集的出版。有興趣深入瞭解的人,可以查閱 Wikipedia 關於 Eumenes of Cardia 的簡傳

    + +
    + +
    + +
    +
    12.1.’05. 2:31am.
    + +
    +最近在看新世紀福音戰士
    +
    +一直沒有機會看
    +可能是一直不曾在漫畫出租店看到過吧
    +這兩天看完了幾部長篇,沒什麼特別要看的漫畫
    +中午在出租店隨便亂逛
    +竟然被我找到這一篇好幾年前很轟動的漫畫
    +
    +看完了幾集,覺得
    +嗯
    +難怪會成為經典
    +一開始就被巨大的虛無感和絕望感給壓垮
    +「除了拯救世界以外,我什麼都不會做。」
    +
    +要怎麼樣的心境,才寫得出這樣震憾的台詞呢?
    +空間中充斥著的其實是這個時代的巨大虛無感
    +不知道自己能做什麼,不知道自己想做什麼,不知道自己做什麼有什麼意義
    +作者自述他在畫新世紀福音戰士之前
    +整整四年的時間,像行屍走肉一樣,沒有工作
    +這就是那種巨大的虛無感的來源嗎?
    +
    +我已經漸漸脫離了那個被虛無感壓垮年紀了
    +可是看到這樣的作品,這樣的畫面和這樣的故事情節
    +像是內心深處被勾動了一般
    +還是感到無比的震憾 +
    + +
    + +
    + +
    +
    11.24.’05. 3:19am.
    + +
    +突然發現
    +周錫瑋的競選口號是「瑋哥」
    +諧音就是「偉哥」,就是香港粵語中的威爾剛
    +
    +幹
    +那不就跟李應元選台北市長時的「讓台北 In 起來」
    +一樣了嗎?
    +超低級的政客 +
    + +
    + +
    + +
    +
    11.24.’05. 2:42am.
    + +
    +國民黨是瘋了嗎?一點長進也沒有嗎?
    +
    +變成了在野黨,視野竟然和執政黨一模一樣
    +別人選舉招數稍微花俏一點就通通抓起來
    +要求事先審查還沒上市的政論光碟,要求查禁對手的政論性網站
    +以為自己還在專制獨裁時代,可以隨意操控政治言論嗎?
    +
    +幹
    +十幾年前解嚴前的奧步,現在還在搞
    +到底是什麼時代的人啊?走回頭路啊?腦袋和十幾年前一模一樣 +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 15 | + 16 | + 17 | + 18 | + 19 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0017.html.zh-cn.html b/htdocs/imacat/me/diary/0017.html.zh-cn.html new file mode 120000 index 0000000..7bb441f --- /dev/null +++ b/htdocs/imacat/me/diary/0017.html.zh-cn.html @@ -0,0 +1 @@ +0017.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0017.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0017.html.zh-cn.xhtml new file mode 100644 index 0000000..cc44713 --- /dev/null +++ b/htdocs/imacat/me/diary/0017.html.zh-cn.xhtml @@ -0,0 +1,312 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷十七

    + +
    + +
    + +
    +
    1.27.’06. 5:19am.
    + +

    终于把 MySQL server 升级到 5.0 了。又是一个星期过去了。天已经快亮了,总算了却一桩心事。

    + +

    我公司的案子怎么办哪~~ ^^;

    + +
    + +
    + +
    +
    1.23.’06. 3:53am.
    + +

    终于升级了 MySQL server ,从 4.0 升级到 4.1 。

    + +

    原本以为是两天左右的工作,没想到搞了一个星期。好累。虽然我的身边环境已经没有什么在用 MySQL 了,可是我还是很不喜欢放一个很旧版很旧版的 server 在那边,更何况 MySQL 现在已经是 5.0 了,中间还隔了一个 4.1 , 4.0 在 MySQL 网站上已经找不到了。

    + +

    仔细读完升级说明,测试新版的功能,一笔一笔检查、找出有问题的资料,加以更正,检查、更正旧网站程式的相容性。没想到会做得这么辛苦。

    + +

    还要升级到 5.0 。嗯嗯。

    + +
    + +
    + +
    +
    1.2.’06. 5:06pm.
    + +
    +看著 Windows XP 视窗下的工作列
    +完成一个工作后,关掉一窗
    +以为可以喘口气了
    +其它窗马上又自动放大,把工作列填满了
    +
    +好像我的生活一样
    +
    +多开一窗,关掉一窗,工作列都是满的
    +好像也没有什么分别 +
    + +
    + +
    + +
    +
    12.19.’05. 11:58pm.
    + +
    +昔人已乘黄鹤去 此地空馀黄鹤楼
    +黄鹤一去不复返 白云千载空悠悠
    +晴川历历汉阳树 芳草萋萋鹦鹉洲
    +日幕乡关何处是 烟波江上使人愁 +
    + +
    + +
    + +
    +
    12.7.’05. 12:27pm.
    + +

    这一阵子系统升级,心头最后一块大石— glibc 的新线程模式 TLS/NPTL ,终于完成了编译与安装实验,并且成功安装到七台伺服器上了。

    + +

    好累,累到快疯了。在虚拟电脑伺服器上,不断重复新编译—安装—修正参数—重新编译的循环。虚拟电脑很慢,编译一次就要半天,安装一次要一个小时,一但失败,就要去到处找原因,修正参数以后,一切重来。如果是安装失败,系统就毁了,还要赶紧找出救援开机光碟,把被盖掉的档案一个一个 copy 回去,才能继续下一个实验。

    + +

    就这样,连著快一个星期,失败了十几次,才慢慢实验出正确的系统参数,和安全的安装升级步骤。昨晚觉得安装、升级步骤差不多没有问题了,而且我也累垮了,决定不等虚拟伺服器的最后一次编译(可能还要一天半),直接装到 rinse 上去试试看。结果非常顺利!接下来远端把剩下来的五台伺服器一一安装上去、重开机,没想到公司的主伺服器竟然没有开机开出来,只好在寒冷的半夜十一点半穿上大衣,骑摩托车飙去公司,把它开起来。回来已经十二点了。

    + +

    心头一块大石总算放了下来。一切结束以后,累得眼睛都花了,看东西看不清楚,整个人精神都散了下来。

    + +
    + +
    + +
    +
    12.6.’05. 4:46am.
    + +

    等实验跑的时候,来写一本不久前看的漫画:岩明均的历史之眼(ヒストリエ,即 History 的片���名,日本讲谈社,台湾授权东立代理)。

    + +

    岩明均的成名作是寄生兽,寄生兽并获得第 17 回讲谈社漫�”�赏。平淡写实的线条,伴著恶梦似的残酷感,有如难分虚实的梦靥一般,直钻入精神意识底层,扰乱梦境和真实的界线,让人不禁神为之夺。即使合上书本,仍然久久无法摆脱梦靥般的感受。

    + +

    历史之眼是很特殊的题材(至少是我不曾看过的漫画题材)。岩明均以接近写实的角度,描述亚历山大大帝身边的私人秘书卡地亚的尤米尼斯(カルディアのエウメネス, Eumenes of Cardia ,较常见译为欧迈尼斯,亦有译为攸梅尼斯尤美尼斯优美尼斯优门尼斯者,都是同一个人,惜未见正式中文译名),手上的王宫日志 (Royal Diary) 中,所记载的事。王宫日志由 Eumenes 所撰记,是研究亚历山大大帝的重要参考史料。藉由王宫日志叙述 Eumenes 的故事,原先的说故事的人,转而成为岩明均故事的内容对象。

    + +

    我没有看过这样的题材,一部以平淡、写实的角度,绘制的历史漫画,没有如三国志、日本战国时代般浮夸的幻想情节,没有如陈某的不是人般的激情和重订历史的强烈企图,岩明均以平铺直述,却又不可逼视的历史现实的残酷,引人入胜。

    + +

    历史之眼目前台湾出版到第一、二集,日本已经出版到第三集了。我很期待续集的出版。有兴趣深入了解的人,可以查阅 Wikipedia 关于 Eumenes of Cardia 的简传

    + +
    + +
    + +
    +
    12.1.’05. 2:31am.
    + +
    +最近在看新世纪福音战士
    +
    +一直没有机会看
    +可能是一直不曾在漫画出租店看到过吧
    +这两天看完了几部长篇,没什么特别要看的漫画
    +中午在出租店随便乱逛
    +竟然被我找到这一篇好几年前很轰动的漫画
    +
    +看完了几集,觉得
    +嗯
    +难怪会成为经典
    +一开始就被巨大的虚无感和绝望感给压垮
    +「除了拯救世界以外,我什么都不会做。」
    +
    +要怎么样的心境,才写得出这样震憾的台词呢?
    +空间中充斥著的其实是这个时代的巨大虚无感
    +不知道自己能做什么,不知道自己想做什么,不知道自己做什么有什么意义
    +作者自述他在画新世纪福音战士之前
    +整整四年的时间,像行尸走肉一样,没有工作
    +这就是那种巨大的虚无感的来源吗?
    +
    +我已经渐渐脱离了那个被虚无感压垮年纪了
    +可是看到这样的作品,这样的画面和这样的故事情节
    +像是内心深处被勾动了一般
    +还是感到无比的震憾 +
    + +
    + +
    + +
    +
    11.24.’05. 3:19am.
    + +
    +突然发现
    +周锡玮的竞选口号是「玮哥」
    +谐音就是「伟哥」,就是香港粤语中的威尔刚
    +
    +干
    +那不就跟李应元选台北市长时的「让台北 In 起来」
    +一样了吗?
    +超低级的政客 +
    + +
    + +
    + +
    +
    11.24.’05. 2:42am.
    + +
    +国民党是疯了吗?一点长进也没有吗?
    +
    +变成了在野党,视野竟然和执政党一模一样
    +别人选举招数稍微花俏一点就通通抓起来
    +要求事先审查还没上市的政论光碟,要求查禁对手的政论性网站
    +以为自己还在专制独裁时代,可以随意操控政治言论吗?
    +
    +干
    +十几年前解严前的奥步,现在还在搞
    +到底是什么时代的人啊?走回头路啊?脑袋和十几年前一模一样 +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 15 | + 16 | + 17 | + 18 | + 19 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0017.html.zh-tw.html b/htdocs/imacat/me/diary/0017.html.zh-tw.html new file mode 120000 index 0000000..0a30e86 --- /dev/null +++ b/htdocs/imacat/me/diary/0017.html.zh-tw.html @@ -0,0 +1 @@ +0017.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0017.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0017.html.zh-tw.xhtml new file mode 100644 index 0000000..9faa4f8 --- /dev/null +++ b/htdocs/imacat/me/diary/0017.html.zh-tw.xhtml @@ -0,0 +1,312 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷十七

    + +
    + +
    + +
    +
    1.27.’06. 5:19am.
    + +

    終於把 MySQL server 昇級到 5.0 了。又是一個星期過去了。天已經快亮了,總算了卻一樁心事。

    + +

    我公司的案子怎麼辦哪~~ ^^;

    + +
    + +
    + +
    +
    1.23.’06. 3:53am.
    + +

    終於昇級了 MySQL server ,從 4.0 昇級到 4.1 。

    + +

    原本以為是兩天左右的工作,沒想到搞了一個星期。好累。雖然我的身邊環境已經沒有什麼在用 MySQL 了,可是我還是很不喜歡放一個很舊版很舊版的 server 在那邊,更何況 MySQL 現在已經是 5.0 了,中間還隔了一個 4.1 , 4.0 在 MySQL 網站上已經找不到了。

    + +

    仔細讀完昇級說明,測試新版的功能,一筆一筆檢查、找出有問題的資料,加以更正,檢查、更正舊網站程式的相容性。沒想到會做得這麼辛苦。

    + +

    還要昇級到 5.0 。嗯嗯。

    + +
    + +
    + +
    +
    1.2.’06. 5:06pm.
    + +
    +看著 Windows XP 視窗下的工作列
    +完成一個工作後,關掉一窗
    +以為可以喘口氣了
    +其它窗馬上又自動放大,把工作列填滿了
    +
    +好像我的生活一樣
    +
    +多開一窗,關掉一窗,工作列都是滿的
    +好像也沒有什麼分別 +
    + +
    + +
    + +
    +
    12.19.’05. 11:58pm.
    + +
    +昔人已乘黃鶴去 此地空餘黃鶴樓
    +黃鶴一去不復返 白雲千載空悠悠
    +晴川歷歷漢陽樹 芳草萋萋鸚鵡洲
    +日幕鄉關何處是 煙波江上使人愁 +
    + +
    + +
    + +
    +
    12.7.’05. 12:27pm.
    + +

    這一陣子系統昇級,心頭最後一塊大石— glibc 的新線程模式 TLS/NPTL ,終於完成了編譯與安裝實驗,並且成功安裝到七台伺服器上了。

    + +

    好累,累到快瘋了。在虛擬電腦伺服器上,不斷重複新編譯—安裝—修正參數—重新編譯的循環。虛擬電腦很慢,編譯一次就要半天,安裝一次要一個小時,一但失敗,就要去到處找原因,修正參數以後,一切重來。如果是安裝失敗,系統就毀了,還要趕緊找出救援開機光碟,把被蓋掉的檔案一個一個 copy 回去,才能繼續下一個實驗。

    + +

    就這樣,連著快一個星期,失敗了十幾次,才慢慢實驗出正確的系統參數,和安全的安裝昇級步驟。昨晚覺得安裝、昇級步驟差不多沒有問題了,而且我也累垮了,決定不等虛擬伺服器的最後一次編譯(可能還要一天半),直接裝到 rinse 上去試試看。結果非常順利!接下來遠端把剩下來的五台伺服器一一安裝上去、重開機,沒想到公司的主伺服器竟然沒有開機開出來,只好在寒冷的半夜十一點半穿上大衣,騎摩托車飆去公司,把它開起來。回來已經十二點了。

    + +

    心頭一塊大石總算放了下來。一切結束以後,累得眼睛都花了,看東西看不清楚,整個人精神都散了下來。

    + +
    + +
    + +
    +
    12.6.’05. 4:46am.
    + +

    等實驗跑的時候,來寫一本不久前看的漫畫:岩明均的歷史之眼(ヒストリエ,即 History 的片仮名,日本講談社,台灣授權東立代理)。

    + +

    岩明均的成名作是寄生獸,寄生獸並獲得第 17 回講談社漫画賞。平淡寫實的線條,伴著惡夢似的殘酷感,有如難分虛實的夢靨一般,直鑽入精神意識底層,擾亂夢境和真實的界線,讓人不禁神為之奪。即使合上書本,仍然久久無法擺脫夢靨般的感受。

    + +

    歷史之眼是很特殊的題材(至少是我不曾看過的漫畫題材)。岩明均以接近寫實的角度,描述亞歷山大大帝身邊的私人秘書卡地亞的尤米尼斯(カルディアのエウメネス, Eumenes of Cardia ,較常見譯為歐邁尼斯,亦有譯為攸梅尼斯尤美尼斯優美尼斯優門尼斯者,都是同一個人,惜未見正式中文譯名),手上的王宮日誌 (Royal Diary) 中,所記載的事。王宮日誌由 Eumenes 所撰記,是研究亞歷山大大帝的重要參考史料。藉由王宮日誌敘述 Eumenes 的故事,原先的說故事的人,轉而成為岩明均故事的內容對象。

    + +

    我沒有看過這樣的題材,一部以平淡、寫實的角度,繪製的歷史漫畫,沒有如三國志、日本戰國時代般浮誇的幻想情節,沒有如陳某的不是人般的激情和重訂歷史的強烈企圖,岩明均以平鋪直述,卻又不可逼視的歷史現實的殘酷,引人入勝。

    + +

    歷史之眼目前台灣出版到第一、二集,日本已經出版到第三集了。我很期待續集的出版。有興趣深入瞭解的人,可以查閱 Wikipedia 關於 Eumenes of Cardia 的簡傳

    + +
    + +
    + +
    +
    12.1.’05. 2:31am.
    + +
    +最近在看新世紀福音戰士
    +
    +一直沒有機會看
    +可能是一直不曾在漫畫出租店看到過吧
    +這兩天看完了幾部長篇,沒什麼特別要看的漫畫
    +中午在出租店隨便亂逛
    +竟然被我找到這一篇好幾年前很轟動的漫畫
    +
    +看完了幾集,覺得
    +嗯
    +難怪會成為經典
    +一開始就被巨大的虛無感和絕望感給壓垮
    +「除了拯救世界以外,我什麼都不會做。」
    +
    +要怎麼樣的心境,才寫得出這樣震憾的台詞呢?
    +空間中充斥著的其實是這個時代的巨大虛無感
    +不知道自己能做什麼,不知道自己想做什麼,不知道自己做什麼有什麼意義
    +作者自述他在畫新世紀福音戰士之前
    +整整四年的時間,像行屍走肉一樣,沒有工作
    +這就是那種巨大的虛無感的來源嗎?
    +
    +我已經漸漸脫離了那個被虛無感壓垮年紀了
    +可是看到這樣的作品,這樣的畫面和這樣的故事情節
    +像是內心深處被勾動了一般
    +還是感到無比的震憾 +
    + +
    + +
    + +
    +
    11.24.’05. 3:19am.
    + +
    +突然發現
    +周錫瑋的競選口號是「瑋哥」
    +諧音就是「偉哥」,就是香港粵語中的威爾剛
    +
    +幹
    +那不就跟李應元選台北市長時的「讓台北 In 起來」
    +一樣了嗎?
    +超低級的政客 +
    + +
    + +
    + +
    +
    11.24.’05. 2:42am.
    + +
    +國民黨是瘋了嗎?一點長進也沒有嗎?
    +
    +變成了在野黨,視野竟然和執政黨一模一樣
    +別人選舉招數稍微花俏一點就通通抓起來
    +要求事先審查還沒上市的政論光碟,要求查禁對手的政論性網站
    +以為自己還在專制獨裁時代,可以隨意操控政治言論嗎?
    +
    +幹
    +十幾年前解嚴前的奧步,現在還在搞
    +到底是什麼時代的人啊?走回頭路啊?腦袋和十幾年前一模一樣 +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 15 | + 16 | + 17 | + 18 | + 19 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0018.html.en.html b/htdocs/imacat/me/diary/0018.html.en.html new file mode 120000 index 0000000..98a22a4 --- /dev/null +++ b/htdocs/imacat/me/diary/0018.html.en.html @@ -0,0 +1 @@ +0018.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0018.html.en.xhtml b/htdocs/imacat/me/diary/0018.html.en.xhtml new file mode 100644 index 0000000..82d9739 --- /dev/null +++ b/htdocs/imacat/me/diary/0018.html.en.xhtml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 18 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 18

    + +
    + +
    + +
    +
    2.5.’06. 4:57am.
    + +

    Ulitma Ⅶ: The Black Gate

    + +

    Fellowship Bombing

    + +
    — So the game is over, huh?
    + +

    It's nine thirty in the evening. Half of the citizens in Britain gather at the Fellowship National Branch as usual, concentrating to the speech of their mentor, the great Batlin. Knowing nothing to the danger hidden beneath the peace…

    + +
      +
    1. +"Worthiness precedes reward!" +

      Worthiness precedes reward!

      +
    2. + +
    3. +"I'm worthy!" "Boom!" +

      I'm worthy! Boom!

      +
    4. + +
    5. +(Thy reward?) +

      (Thy reward?)

      +
    6. +
    + +

    The National Branch of the Fellowship, is gone. Dismissed. Although Batlin is still alive (why?), it cannot continue, for all the foolish followers, but Nanna, that are in Britain, are die. Poor Nanna. Thou wert such a nice old lady. Thy sacrifice saved the whole Britannia. May thou rest in peace.

    + +
    + +
    + +
    +
    1.30.’06. 1:25am.
    + +

    糜爛生活日記

    + +
      +
    1. 第一天(除夕):下午去百貨公司美食街吃了一份韓國烤肉,添了兩碗飯。順便逛街。好久沒逛街了,刷了一件還不錯看的外套,兩千六百四。半夜玩遊戲玩到一半餓了,出去 7-11 買了一堆零食:我最愛吃的蜜汁腰果、不知道什麼的鱈魚片(後來才知道是炸鱈魚片,不好吃)、花生糖、仙楂餅、溫泉蛋、每日 C 果汁。抱著沒有預算,想買什麼就買什麼的心情亂買亂吃。
    2. + +
    3. 第二天(初一):一整個下午都不餓,所以沒吃。半夜又出去亂買零食,計有:魷魚絲、軟鐵蛋、烤布丁、每日 C 果汁、紅茶、梅酒。繼續過著亂買亂吃,沒有目標的糜爛日子。
    4. + +
    5. 第三天(初二):待續…。
    6. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 16 | + 17 | + 18 | + 19 | + 20 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0018.html.zh-cn.html b/htdocs/imacat/me/diary/0018.html.zh-cn.html new file mode 120000 index 0000000..9feb348 --- /dev/null +++ b/htdocs/imacat/me/diary/0018.html.zh-cn.html @@ -0,0 +1 @@ +0018.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0018.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0018.html.zh-cn.xhtml new file mode 100644 index 0000000..98b8a7b --- /dev/null +++ b/htdocs/imacat/me/diary/0018.html.zh-cn.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷十八

    + +
    + +
    + +
    +
    2.5.’06. 4:57am.
    + +

    创世纪七·黑月之门

    + +

    友谊会总会爆炸案

    + +
    —游戏就这样结束了?
    + +

    晚上九点半,不列颠王城里一半的市民,如往常一般聚在友谊会会所,听巴特林布道,浑然不知他们已经落入了一个死·亡·陷·阱…

    + +
      +
    1. +「价值先行于报偿!」 +

      价值先行于报偿!

      +
    2. + +
    3. +「我有我的价值!」「碰!」 +

      我有我的价值!碰!

      +
    4. + +
    5. +(报偿?) +

      (报偿?)

      +
    6. +
    + +

    友谊会全国总会,就此烟·消·云·散。虽然巴特林没死(啊?哪有可能?),但是他在不列颠王城中的愚蠢信徒都死光光了,他大概也玩不下去了,友谊会将就此瓦解。可怜的善良老太太 Nanna 也被连累了。呜呼!汝一人之性命,救万民于水火。呜呼!黄泉有路,汝可安去!

    + +
    + +
    + +
    +
    1.30.’06. 1:25am.
    + +

    糜烂生活日记

    + +
      +
    1. 第一天(除夕):下午去百货公司美食街吃了一份韩国烤肉,添了两碗饭。顺便逛街。好久没逛街了,刷了一件还不错看的外套,两千六百四。半夜玩游戏玩到一半饿了,出去 7-11 买了一堆零食:我最爱吃的蜜汁腰果、不知道什么的鳕鱼片(后来才知道是炸鳕鱼片,不好吃)、花生糖、仙楂饼、温泉蛋、每日 C 果汁。抱著没有预算,想买什么就买什么的心情乱买乱吃。
    2. + +
    3. 第二天(初一):一整个下午都不饿,所以没吃。半夜又出去乱买零食,计有:鱿鱼丝、软铁蛋、烤布丁、每日 C 果汁、红茶、梅酒。继续过著乱买乱吃,没有目标的糜烂日子。
    4. + +
    5. 第三天(初二):待续…。
    6. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 16 | + 17 | + 18 | + 19 | + 20 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0018.html.zh-tw.html b/htdocs/imacat/me/diary/0018.html.zh-tw.html new file mode 120000 index 0000000..0c60fa7 --- /dev/null +++ b/htdocs/imacat/me/diary/0018.html.zh-tw.html @@ -0,0 +1 @@ +0018.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0018.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0018.html.zh-tw.xhtml new file mode 100644 index 0000000..1a420a8 --- /dev/null +++ b/htdocs/imacat/me/diary/0018.html.zh-tw.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷十八

    + +
    + +
    + +
    +
    2.5.’06. 4:57am.
    + +

    創世紀七‧黑月之門

    + +

    友誼會總會爆炸案

    + +
    —遊戲就這樣結束了?
    + +

    晚上九點半,不列顛王城裏一半的市民,如往常一般聚在友誼會會所,聽巴特林佈道,渾然不知他們已經落入了一個死‧亡‧陷‧阱…

    + +
      +
    1. +「價值先行於報償!」 +

      價值先行於報償!

      +
    2. + +
    3. +「我有我的價值!」「碰!」 +

      我有我的價值!碰!

      +
    4. + +
    5. +(報償?) +

      (報償?)

      +
    6. +
    + +

    友誼會全國總會,就此煙‧消‧雲‧散。雖然巴特林沒死(啊?哪有可能?),但是他在不列顛王城中的愚蠢信徒都死光光了,他大概也玩不下去了,友誼會將就此瓦解。可憐的善良老太太 Nanna 也被連累了。嗚呼!汝一人之性命,救萬民於水火。嗚呼!黃泉有路,汝可安去!

    + +
    + +
    + +
    +
    1.30.’06. 1:25am.
    + +

    糜爛生活日記

    + +
      +
    1. 第一天(除夕):下午去百貨公司美食街吃了一份韓國烤肉,添了兩碗飯。順便逛街。好久沒逛街了,刷了一件還不錯看的外套,兩千六百四。半夜玩遊戲玩到一半餓了,出去 7-11 買了一堆零食:我最愛吃的蜜汁腰果、不知道什麼的鱈魚片(後來才知道是炸鱈魚片,不好吃)、花生糖、仙楂餅、溫泉蛋、每日 C 果汁。抱著沒有預算,想買什麼就買什麼的心情亂買亂吃。
    2. + +
    3. 第二天(初一):一整個下午都不餓,所以沒吃。半夜又出去亂買零食,計有:魷魚絲、軟鐵蛋、烤布丁、每日 C 果汁、紅茶、梅酒。繼續過著亂買亂吃,沒有目標的糜爛日子。
    4. + +
    5. 第三天(初二):待續…。
    6. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 16 | + 17 | + 18 | + 19 | + 20 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0019.html.en.html b/htdocs/imacat/me/diary/0019.html.en.html new file mode 120000 index 0000000..1c1bd1a --- /dev/null +++ b/htdocs/imacat/me/diary/0019.html.en.html @@ -0,0 +1 @@ +0019.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0019.html.en.xhtml b/htdocs/imacat/me/diary/0019.html.en.xhtml new file mode 100644 index 0000000..9dac403 --- /dev/null +++ b/htdocs/imacat/me/diary/0019.html.en.xhtml @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 19 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 19

    + +
    + +
    + +
    +
    2.7.’06. 3:30am.
    + +

    創世紀七‧黑月之門 聖者 imacat 的奇幻冒險故事

    + +

    豪門恩怨‧兄妹生死情

    + +
    —多管閒事!人家兄妹根本就是妳殺死的吧!
    + +

    那天,和往常一般,帶著我的冒險隊友,在紫衫城外的大森林裏走著。突然間,在山邊看到一個打扮得很像山賊的人,遠遠走過去。不過看他好像還可以談的樣子,於是趕緊追上去,打個招呼,看能不能得到什麼情報…

    + +

    你好,天氣真熱哪!請問怎麼稱呼?

    + +

    他轉過頭來,看了我一眼,突然怒目圓瞪,抽出腰間的開山刀,一刀就劈過來:友誼會的賤人!我劈,我劈死你!友誼會的都得死!

    + +

    我嚇了一跳,手上的劍反射性地抽出來,擋下他的刀,旁邊隊友紛紛吆喝著,拔出武器來救我。等我反應過來的時候,他的頭已經被 Shamino 的毀滅之鋤一鋤打爛,胸口插著兩支 Tseramed 的箭,倒在血泊當中,變成一具死屍,沒氣了。

    + +

    驚魂未定間,大家你看看我,我看看你。 Dupre 指著我胸口的友誼會項鍊。啊,原來是這個東西惹的禍。為了深入瞭解友誼會的內部運作情形,昨晚在巴特林的引薦之下,在不列顛城友誼會總會所加入友誼會,巴特林把這條鍊子,鄭重地掛在我的脖子上。之後,我就忘記拿下來了。我趕緊把鍊子拿下來收好。看看地上的死屍,嘆了一口氣。這傢伙也死得頗冤枉的,不知道受了什麼冤屈。我轉向身邊的隨隊醫生 Jaana 。

    + +

    Jaana ,可不可以幫忙讓他復活?

    + +

    沒問題。 Jaana 笑著回答。接著,她從背包拿出隨身的醫療器材,忙著拔箭,清創、包紮,塗藥。等傷口通通都處理好了,開始推拿活血。慢慢地,他開始醒轉過來。

    + +

    不好意思,我叫 imacat ,不知道你怎麼稱呼?

    + +

    他搖搖晃晃地站起來,打量著我:我叫 Thad ,妳是友誼會的人嗎?

    + +

    看他好像已經不記得剛剛發生什麼事了,好險好險。我趕緊否認:不是不是,我不是友誼會的人。請問友誼會怎麼了嗎?

    + +

    友誼會…那個邪教!他們強擄了我妹 Millie ,不知道用了什麼妖法,把她騙得迷迷糊糊的,成天跟著他們在不列顛城閒晃,已經幾年沒回紫衫城的老家了!我發誓一定要把我妹救出來。除非他們把我妹交出來,否則只要是友誼會的,我見一個砍一個!

    + +
    +「友誼會…那個邪教!他們強擄了我妹 Millie ,不知道用了什麼妖法,把她騙得迷迷糊糊的。」 +

    友誼會…那個邪教!他們強擄了我妹 Millie ,不知道用了什麼妖法,把她騙得迷迷糊糊的。

    +
    + +

    原來如此。不過這個哥哥未免也有點太偏激了,雖然他愛護妹妹的心也不是完全無法理解。 Millie 啊…我開始搜尋腦中的記憶…好像有點印象,記得在不列顛城的街坊見過她,自稱自己的職業是在幫友誼會拉人,整天無所事事,在街坊串門子拉人進友誼會,見人就佈道傳教。是不討人厭,不過我也不是很想見到那個女人。

    + +

    說!你是不是也跟我一樣,跟友誼會誓不兩立?

    + +

    Thad 的一句話,把我拉回現實。呃,這怎麼回答呢?我昨晚才剛加入友誼會啊。

    + +

    呃…這個…不好意思,我目前還沒有想到那麼多。

    + +

    唔…他的口氣有點失望,不過眼中的堅定意志不改:那妳要不要考慮追隨我,消滅那個邪教,救出我妹?

    + +

    我感覺到他眼中帶著的殺氣。嗯,好,好吧。

    + +

    好,同志,你走吧。記住,友誼會的王八羔子,見一個殺一個!

    + +

    我揮揮手。回頭仔細想想這件事。 Millie 平常閒晃的街坊我知道,離我在不列顛城標記的傳送點 Wayferer's 旅店不遠。這件事搞不好不到五分鐘就搞定了。

    + +

    我拿出 Shamino 背包裏的美德石,先拿藍色那顆標記傳送點,以便等等傳送回來:

    + +

    KAL POR YLEM

    + +

    接著,拿出原先標記著 Wayferer's 旅店的白色美德石,口中唸起咒語:

    + +

    KAL ORT POR

    + +

    咻!的一聲,我已經出現在不列顛城內了。趕緊出門去找 Millie 。果然,不到兩分鐘,就找到了。她跟往常一樣,在街坊閒晃,跟人傳教。她看到我,非常高興地走過來:嗨, imacat ,今天晚上九點會去會所聚會吧?一定要記得喔!

    + +

    喔…好…對了, Millie ,我這次來找妳,是有一件事要跟妳說。

    + +

    什麼事呢? Millie 張大了眼睛,笑著看我。

    + +

    是這樣的,我剛剛在紫衫城的山裏,碰到了妳哥 Thad…

    + +

    Millie 的臉色突然一沉,Thad…提那個渾蛋老哥做什麼?他根本就是有病!他老是把我當成長不大的小孩,什麼都要管,其實他自己才像小孩子一樣。媽老是說他衝動得要命,做事情都不顧後果。…我跟他講過幾百次了,我神志清醒,我參加友誼會是自願的,沒有人逼我,沒有人給我下什麼妖法!…我在友誼會找到我人生的意義!…不要說了,我是不會回去的!…哇啦哇啦,一口氣數落老哥數落了二十幾分鐘。我原本打算五分鐘解決這件事的盤算,看來是落空了。

    + +
    +Millie 的臉色突然一沉,「Thad…提那個渾蛋老哥做什麼?他根本就是有病!」 +

    Millie 的臉色突然一沉,Thad…提那個渾蛋老哥做什麼?他根本就是有病!

    +
    + +

    唔,好吧。信仰這種事,也勉強不得。我只好硬著頭皮,回去勸 Thad ,希望他能看開一點。

    + +

    KAL ORT POR

    + +

    Thad , Thad ,我跟你說,我剛剛已經找到你妹了。幸好 Thad 還沒有走遠,我趕緊叫住他,把 Millie 的意思,轉述給他聽。

    + +

    胡說!她一定是中了友誼會的妖法,才會這樣滿口胡言亂語。妳不要說了。妳不幫我就算了,我就算殺光整個友誼會,也要把她救出來。說完,掉頭就走。

    + +

    這怎麼辦?兄妹吵架,就算是聖者也沒有辦法。可是也不能放著他這樣在山裏亂砍人吧?啊,不管了,硬把 Millie 帶來,兄妹倆的事,讓他們兄妹自己去解決吧。

    + +

    KAL ORT POR

    + +

    嗨, imacat ,妳又來啦!要多幫我拉幾個會員喔! Millie 看到我,笑臉迎來。

    + +

    喔…好好,沒問題沒問題…我嘴裏答應,心裏咕噥:我又不像妳,無所事事。左右看看附近沒有警衛,我偷偷唸起了霹靂閃電法術:

    + +

    ORT GRAV

    + +

    碰!爆炸結束後, Millie 變成了一具血肉模糊的死屍。我左右看看,還沒有警衛發現,趕緊扛起 Millie 的屍首,唸起傳送法術:

    + +

    KAL ORT POR

    + +

    咻!的一聲,我又回到了大森林裏。我把 Millie 的屍首放下,轉身向 Jaana : Janna ,可以幫我把她復活嗎?

    + +

    聖者殿下,不好意思,殿下也知道,我一天只能免費幫隊伍醫療一次… Janna 露出為難的表情。

    + +

    好啦好啦,四百個金幣是吧,拿去啦!我掏出 Iolo 身上的錢包,點一點,還好身上帶的錢還夠,拿了四把金幣塞給她。 Janna 這個現實鬼,人長得那麼漂亮,那麼愛錢幹嘛?唉,誰叫我要沒事捲入人家兄妹吵架?

    + +

    謝了。 Jaana 笑著收下金幣,拿出她的醫療器材,開始熟練地忙碌起來。不一會兒工夫, Millie 開始悠悠醒轉。這…這裏是哪裏?我為什麼會在這個地方?

    + +

    我不理她,拉著她的手,遠遠地叫住 Thad :Thad ,我把你妹帶來了,你們倆個自己談談吧。

    + +

    就這樣,我把 Millie 硬塞給她,然後頭也不回地走了。我仿彿聽到身後傳來大聲吵架的聲音。啊,不管了,隨這對白癡兄妹去吧!這件事說起來,也實在是哥哥不對,雖然說想保護妹妹的心情可以理解,但也要適可而止吧。妹妹有妹妹的人生,總不能保護她一輩子吧?反正友誼會供她生活所需,活得好好的就好了。而且亂砍人是不對的,我阻止他到處亂砍人,也算是功德一件。不過這個妹妹也真是的,要加入友誼會是無妨,不過不要只顧著自己要講的話,偶爾也要聽聽人家怎麼說嘛!更何況,偶爾回家看看家人,也是應該的。說起來,妳哥到處亂砍人,也是因妳而起,妳也要負點責任吧?我帶妳回紫衫城老家,妳還應該謝謝我才是。唉,誰叫我是關心不列顛人民的聖者呢?話說回來,這件事之中,我到底得到了什麼情報呢?友誼會到底是會妖法,還是不會妖法?嗯嗯,想來想去,好像還是無解。

    + +

    我一面心裏碎碎念,一面越走越遠。

    + +
    +Thad 和 Millie 對質 +

    我硬把 Millie 帶到紫衫城深山裏塞給 Thad ,然後頭也不回地離開。

    +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 17 | + 18 | + 19 | + 20 | + 21 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0019.html.zh-cn.html b/htdocs/imacat/me/diary/0019.html.zh-cn.html new file mode 120000 index 0000000..548cd6b --- /dev/null +++ b/htdocs/imacat/me/diary/0019.html.zh-cn.html @@ -0,0 +1 @@ +0019.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0019.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0019.html.zh-cn.xhtml new file mode 100644 index 0000000..e71b360 --- /dev/null +++ b/htdocs/imacat/me/diary/0019.html.zh-cn.xhtml @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷十九

    + +
    + +
    + +
    +
    2.7.’06. 3:30am.
    + +

    创世纪七·黑月之门 圣者 imacat 的奇幻冒险故事

    + +

    豪门恩怨·兄妹生死情

    + +
    —多管闲事!人家兄妹根本就是你杀死的吧!
    + +

    那天,和往常一般,带著我的冒险队友,在紫衫城外的大森林里走著。突然间,在山边看到一个打扮得很像山贼的人,远远走过去。不过看他好像还可以谈的样子,于是赶紧追上去,打个招呼,看能不能得到什么情报…

    + +

    你好,天气真热哪!请问怎么称呼?

    + +

    他转过头来,看了我一眼,突然怒目圆瞪,抽出腰间的开山刀,一刀就劈过来:友谊会的贱人!我劈,我劈死你!友谊会的都得死!

    + +

    我吓了一跳,手上的剑反射性地抽出来,挡下他的刀,旁边队友纷纷吆喝著,拔出武器来救我。等我反应过来的时候,他的头已经被 Shamino 的毁灭之锄一锄打烂,胸口插著两支 Tseramed 的箭,倒在血泊当中,变成一具死尸,没气了。

    + +

    惊魂未定间,大家你看看我,我看看你。 Dupre 指著我胸口的友谊会项鍊。啊,原来是这个东西惹的祸。为了深入了解友谊会的内部运作情形,昨晚在巴特林的引荐之下,在不列颠城友谊会总会所加入友谊会,巴特林把这条鍊子,郑重地挂在我的脖子上。之后,我就忘记拿下来了。我赶紧把鍊子拿下来收好。看看地上的死尸,叹了一口气。这家伙也死得颇冤枉的,不知道受了什么冤屈。我转向身边的随队医生 Jaana 。

    + +

    Jaana ,可不可以帮忙让他复活?

    + +

    没问题。 Jaana 笑著回答。接著,她从背包拿出随身的医疗器材,忙著拔箭,清创、包扎,涂药。等伤口通通都处理好了,开始推拿活血。慢慢地,他开始醒转过来。

    + +

    不好意思,我叫 imacat ,不知道你怎么称呼?

    + +

    他摇摇晃晃地站起来,打量著我:我叫 Thad ,你是友谊会的人吗?

    + +

    看他好像已经不记得刚刚发生什么事了,好险好险。我赶紧否认:不是不是,我不是友谊会的人。请问友谊会怎么了吗?

    + +

    友谊会…那个邪教!他们强掳了我妹 Millie ,不知道用了什么妖法,把她骗得迷迷糊糊的,成天跟著他们在不列颠城闲晃,已经几年没回紫衫城的老家了!我发誓一定要把我妹救出来。除非他们把我妹交出来,否则只要是友谊会的,我见一个砍一个!

    + +
    +「友谊会…那个邪教!他们强掳了我妹 Millie ,不知道用了什么妖法,把她骗得迷迷糊糊的。」 +

    友谊会…那个邪教!他们强掳了我妹 Millie ,不知道用了什么妖法,把她骗得迷迷糊糊的。

    +
    + +

    原来如此。不过这个哥哥未免也有点太偏激了,虽然他爱护妹妹的心也不是完全无法理解。 Millie 啊…我开始搜寻脑中的记忆…好像有点印象,记得在不列颠城的街坊见过她,自称自己的职业是在帮友谊会拉人,整天无所事事,在街坊串门子拉人进友谊会,见人就布道传教。是不讨人厌,不过我也不是很想见到那个女人。

    + +

    说!你是不是也跟我一样,跟友谊会誓不两立?

    + +

    Thad 的一句话,把我拉回现实。呃,这怎么回答呢?我昨晚才刚加入友谊会啊。

    + +

    呃…这个…不好意思,我目前还没有想到那么多。

    + +

    唔…他的口气有点失望,不过眼中的坚定意志不改:那你要不要考虑追随我,消灭那个邪教,救出我妹?

    + +

    我感觉到他眼中带著的杀气。嗯,好,好吧。

    + +

    好,同志,你走吧。记住,友谊会的王八羔子,见一个杀一个!

    + +

    我挥挥手。回头仔细想想这件事。 Millie 平常闲晃的街坊我知道,离我在不列颠城标记的传送点 Wayferer's 旅店不远。这件事搞不好不到五分钟就搞定了。

    + +

    我拿出 Shamino 背包里的美德石,先拿蓝色那颗标记传送点,以便等等传送回来:

    + +

    KAL POR YLEM

    + +

    接著,拿出原先标记著 Wayferer's 旅店的白色美德石,口中念起咒语:

    + +

    KAL ORT POR

    + +

    咻!的一声,我已经出现在不列颠城内了。赶紧出门去找 Millie 。果然,不到两分钟,就找到了。她跟往常一样,在街坊闲晃,跟人传教。她看到我,非常高兴地走过来:嗨, imacat ,今天晚上九点会去会所聚会吧?一定要记得喔!

    + +

    喔…好…对了, Millie ,我这次来找你,是有一件事要跟你说。

    + +

    什么事呢? Millie 张大了眼睛,笑著看我。

    + +

    是这样的,我刚刚在紫衫城的山里,碰到了你哥 Thad…

    + +

    Millie 的脸色突然一沉,Thad…提那个浑蛋老哥做什么?他根本就是有病!他老是把我当成长不大的小孩,什么都要管,其实他自己才像小孩子一样。妈老是说他冲动得要命,做事情都不顾后果。…我跟他讲过几百次了,我神志清醒,我参加友谊会是自愿的,没有人逼我,没有人给我下什么妖法!…我在友谊会找到我人生的意义!…不要说了,我是不会回去的!…哇啦哇啦,一口气数落老哥数落了二十几分钟。我原本打算五分钟解决这件事的盘算,看来是落空了。

    + +
    +Millie 的脸色突然一沉,「Thad…提那个浑蛋老哥做什么?他根本就是有病!」 +

    Millie 的脸色突然一沉,Thad…提那个浑蛋老哥做什么?他根本就是有病!

    +
    + +

    唔,好吧。信仰这种事,也勉强不得。我只好硬著头皮,回去劝 Thad ,希望他能看开一点。

    + +

    KAL ORT POR

    + +

    Thad , Thad ,我跟你说,我刚刚已经找到你妹了。幸好 Thad 还没有走远,我赶紧叫住他,把 Millie 的意思,转述给他听。

    + +

    胡说!她一定是中了友谊会的妖法,才会这样满口胡言乱语。你不要说了。你不帮我就算了,我就算杀光整个友谊会,也要把她救出来。说完,掉头就走。

    + +

    这怎么办?兄妹吵架,就算是圣者也没有办法。可是也不能放著他这样在山里乱砍人吧?啊,不管了,硬把 Millie 带来,兄妹俩的事,让他们兄妹自己去解决吧。

    + +

    KAL ORT POR

    + +

    嗨, imacat ,你又来啦!要多帮我拉几个会员喔! Millie 看到我,笑脸迎来。

    + +

    喔…好好,没问题没问题…我嘴里答应,心里咕哝:我又不像你,无所事事。左右看看附近没有警卫,我偷偷念起了霹雳闪电法术:

    + +

    ORT GRAV

    + +

    碰!爆炸结束后, Millie 变成了一具血肉模糊的死尸。我左右看看,还没有警卫发现,赶紧扛起 Millie 的尸首,念起传送法术:

    + +

    KAL ORT POR

    + +

    咻!的一声,我又回到了大森林里。我把 Millie 的尸首放下,转身向 Jaana : Janna ,可以帮我把她复活吗?

    + +

    圣者殿下,不好意思,殿下也知道,我一天只能免费帮队伍医疗一次… Janna 露出为难的表情。

    + +

    好啦好啦,四百个金币是吧,拿去啦!我掏出 Iolo 身上的钱包,点一点,还好身上带的钱还够,拿了四把金币塞给她。 Janna 这个现实鬼,人长得那么漂亮,那么爱钱干嘛?唉,谁叫我要没事卷入人家兄妹吵架?

    + +

    谢了。 Jaana 笑著收下金币,拿出她的医疗器材,开始熟练地忙碌起来。不一会儿工夫, Millie 开始悠悠醒转。这…这里是哪里?我为什么会在这个地方?

    + +

    我不理她,拉著她的手,远远地叫住 Thad :Thad ,我把你妹带来了,你们俩个自己谈谈吧。

    + +

    就这样,我把 Millie 硬塞给她,然后头也不回地走了。我仿佛听到身后传来大声吵架的声音。啊,不管了,随这对白痴兄妹去吧!这件事说起来,也实在是哥哥不对,虽然说想保护妹妹的心情可以理解,但也要适可而止吧。妹妹有妹妹的人生,总不能保护她一辈子吧?反正友谊会供她生活所需,活得好好的就好了。而且乱砍人是不对的,我阻止他到处乱砍人,也算是功德一件。不过这个妹妹也真是的,要加入友谊会是无妨,不过不要只顾著自己要讲的话,偶尔也要听听人家怎么说嘛!更何况,偶尔回家看看家人,也是应该的。说起来,你哥到处乱砍人,也是因你而起,你也要负点责任吧?我带你回紫衫城老家,你还应该谢谢我才是。唉,谁叫我是关心不列颠人民的圣者呢?话说回来,这件事之中,我到底得到了什么情报呢?友谊会到底是会妖法,还是不会妖法?嗯嗯,想来想去,好像还是无解。

    + +

    我一面心里碎碎念,一面越走越远。

    + +
    +Thad 和 Millie 对质 +

    我硬把 Millie 带到紫衫城深山里塞给 Thad ,然后头也不回地离开。

    +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 17 | + 18 | + 19 | + 20 | + 21 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0019.html.zh-tw.html b/htdocs/imacat/me/diary/0019.html.zh-tw.html new file mode 120000 index 0000000..88a2799 --- /dev/null +++ b/htdocs/imacat/me/diary/0019.html.zh-tw.html @@ -0,0 +1 @@ +0019.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0019.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0019.html.zh-tw.xhtml new file mode 100644 index 0000000..470e2eb --- /dev/null +++ b/htdocs/imacat/me/diary/0019.html.zh-tw.xhtml @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷十九

    + +
    + +
    + +
    +
    2.7.’06. 3:30am.
    + +

    創世紀七‧黑月之門 聖者 imacat 的奇幻冒險故事

    + +

    豪門恩怨‧兄妹生死情

    + +
    —多管閒事!人家兄妹根本就是妳殺死的吧!
    + +

    那天,和往常一般,帶著我的冒險隊友,在紫衫城外的大森林裏走著。突然間,在山邊看到一個打扮得很像山賊的人,遠遠走過去。不過看他好像還可以談的樣子,於是趕緊追上去,打個招呼,看能不能得到什麼情報…

    + +

    你好,天氣真熱哪!請問怎麼稱呼?

    + +

    他轉過頭來,看了我一眼,突然怒目圓瞪,抽出腰間的開山刀,一刀就劈過來:友誼會的賤人!我劈,我劈死你!友誼會的都得死!

    + +

    我嚇了一跳,手上的劍反射性地抽出來,擋下他的刀,旁邊隊友紛紛吆喝著,拔出武器來救我。等我反應過來的時候,他的頭已經被 Shamino 的毀滅之鋤一鋤打爛,胸口插著兩支 Tseramed 的箭,倒在血泊當中,變成一具死屍,沒氣了。

    + +

    驚魂未定間,大家你看看我,我看看你。 Dupre 指著我胸口的友誼會項鍊。啊,原來是這個東西惹的禍。為了深入瞭解友誼會的內部運作情形,昨晚在巴特林的引薦之下,在不列顛城友誼會總會所加入友誼會,巴特林把這條鍊子,鄭重地掛在我的脖子上。之後,我就忘記拿下來了。我趕緊把鍊子拿下來收好。看看地上的死屍,嘆了一口氣。這傢伙也死得頗冤枉的,不知道受了什麼冤屈。我轉向身邊的隨隊醫生 Jaana 。

    + +

    Jaana ,可不可以幫忙讓他復活?

    + +

    沒問題。 Jaana 笑著回答。接著,她從背包拿出隨身的醫療器材,忙著拔箭,清創、包紮,塗藥。等傷口通通都處理好了,開始推拿活血。慢慢地,他開始醒轉過來。

    + +

    不好意思,我叫 imacat ,不知道你怎麼稱呼?

    + +

    他搖搖晃晃地站起來,打量著我:我叫 Thad ,妳是友誼會的人嗎?

    + +

    看他好像已經不記得剛剛發生什麼事了,好險好險。我趕緊否認:不是不是,我不是友誼會的人。請問友誼會怎麼了嗎?

    + +

    友誼會…那個邪教!他們強擄了我妹 Millie ,不知道用了什麼妖法,把她騙得迷迷糊糊的,成天跟著他們在不列顛城閒晃,已經幾年沒回紫衫城的老家了!我發誓一定要把我妹救出來。除非他們把我妹交出來,否則只要是友誼會的,我見一個砍一個!

    + +
    +「友誼會…那個邪教!他們強擄了我妹 Millie ,不知道用了什麼妖法,把她騙得迷迷糊糊的。」 +

    友誼會…那個邪教!他們強擄了我妹 Millie ,不知道用了什麼妖法,把她騙得迷迷糊糊的。

    +
    + +

    原來如此。不過這個哥哥未免也有點太偏激了,雖然他愛護妹妹的心也不是完全無法理解。 Millie 啊…我開始搜尋腦中的記憶…好像有點印象,記得在不列顛城的街坊見過她,自稱自己的職業是在幫友誼會拉人,整天無所事事,在街坊串門子拉人進友誼會,見人就佈道傳教。是不討人厭,不過我也不是很想見到那個女人。

    + +

    說!你是不是也跟我一樣,跟友誼會誓不兩立?

    + +

    Thad 的一句話,把我拉回現實。呃,這怎麼回答呢?我昨晚才剛加入友誼會啊。

    + +

    呃…這個…不好意思,我目前還沒有想到那麼多。

    + +

    唔…他的口氣有點失望,不過眼中的堅定意志不改:那妳要不要考慮追隨我,消滅那個邪教,救出我妹?

    + +

    我感覺到他眼中帶著的殺氣。嗯,好,好吧。

    + +

    好,同志,你走吧。記住,友誼會的王八羔子,見一個殺一個!

    + +

    我揮揮手。回頭仔細想想這件事。 Millie 平常閒晃的街坊我知道,離我在不列顛城標記的傳送點 Wayferer's 旅店不遠。這件事搞不好不到五分鐘就搞定了。

    + +

    我拿出 Shamino 背包裏的美德石,先拿藍色那顆標記傳送點,以便等等傳送回來:

    + +

    KAL POR YLEM

    + +

    接著,拿出原先標記著 Wayferer's 旅店的白色美德石,口中唸起咒語:

    + +

    KAL ORT POR

    + +

    咻!的一聲,我已經出現在不列顛城內了。趕緊出門去找 Millie 。果然,不到兩分鐘,就找到了。她跟往常一樣,在街坊閒晃,跟人傳教。她看到我,非常高興地走過來:嗨, imacat ,今天晚上九點會去會所聚會吧?一定要記得喔!

    + +

    喔…好…對了, Millie ,我這次來找妳,是有一件事要跟妳說。

    + +

    什麼事呢? Millie 張大了眼睛,笑著看我。

    + +

    是這樣的,我剛剛在紫衫城的山裏,碰到了妳哥 Thad…

    + +

    Millie 的臉色突然一沉,Thad…提那個渾蛋老哥做什麼?他根本就是有病!他老是把我當成長不大的小孩,什麼都要管,其實他自己才像小孩子一樣。媽老是說他衝動得要命,做事情都不顧後果。…我跟他講過幾百次了,我神志清醒,我參加友誼會是自願的,沒有人逼我,沒有人給我下什麼妖法!…我在友誼會找到我人生的意義!…不要說了,我是不會回去的!…哇啦哇啦,一口氣數落老哥數落了二十幾分鐘。我原本打算五分鐘解決這件事的盤算,看來是落空了。

    + +
    +Millie 的臉色突然一沉,「Thad…提那個渾蛋老哥做什麼?他根本就是有病!」 +

    Millie 的臉色突然一沉,Thad…提那個渾蛋老哥做什麼?他根本就是有病!

    +
    + +

    唔,好吧。信仰這種事,也勉強不得。我只好硬著頭皮,回去勸 Thad ,希望他能看開一點。

    + +

    KAL ORT POR

    + +

    Thad , Thad ,我跟你說,我剛剛已經找到你妹了。幸好 Thad 還沒有走遠,我趕緊叫住他,把 Millie 的意思,轉述給他聽。

    + +

    胡說!她一定是中了友誼會的妖法,才會這樣滿口胡言亂語。妳不要說了。妳不幫我就算了,我就算殺光整個友誼會,也要把她救出來。說完,掉頭就走。

    + +

    這怎麼辦?兄妹吵架,就算是聖者也沒有辦法。可是也不能放著他這樣在山裏亂砍人吧?啊,不管了,硬把 Millie 帶來,兄妹倆的事,讓他們兄妹自己去解決吧。

    + +

    KAL ORT POR

    + +

    嗨, imacat ,妳又來啦!要多幫我拉幾個會員喔! Millie 看到我,笑臉迎來。

    + +

    喔…好好,沒問題沒問題…我嘴裏答應,心裏咕噥:我又不像妳,無所事事。左右看看附近沒有警衛,我偷偷唸起了霹靂閃電法術:

    + +

    ORT GRAV

    + +

    碰!爆炸結束後, Millie 變成了一具血肉模糊的死屍。我左右看看,還沒有警衛發現,趕緊扛起 Millie 的屍首,唸起傳送法術:

    + +

    KAL ORT POR

    + +

    咻!的一聲,我又回到了大森林裏。我把 Millie 的屍首放下,轉身向 Jaana : Janna ,可以幫我把她復活嗎?

    + +

    聖者殿下,不好意思,殿下也知道,我一天只能免費幫隊伍醫療一次… Janna 露出為難的表情。

    + +

    好啦好啦,四百個金幣是吧,拿去啦!我掏出 Iolo 身上的錢包,點一點,還好身上帶的錢還夠,拿了四把金幣塞給她。 Janna 這個現實鬼,人長得那麼漂亮,那麼愛錢幹嘛?唉,誰叫我要沒事捲入人家兄妹吵架?

    + +

    謝了。 Jaana 笑著收下金幣,拿出她的醫療器材,開始熟練地忙碌起來。不一會兒工夫, Millie 開始悠悠醒轉。這…這裏是哪裏?我為什麼會在這個地方?

    + +

    我不理她,拉著她的手,遠遠地叫住 Thad :Thad ,我把你妹帶來了,你們倆個自己談談吧。

    + +

    就這樣,我把 Millie 硬塞給她,然後頭也不回地走了。我仿彿聽到身後傳來大聲吵架的聲音。啊,不管了,隨這對白癡兄妹去吧!這件事說起來,也實在是哥哥不對,雖然說想保護妹妹的心情可以理解,但也要適可而止吧。妹妹有妹妹的人生,總不能保護她一輩子吧?反正友誼會供她生活所需,活得好好的就好了。而且亂砍人是不對的,我阻止他到處亂砍人,也算是功德一件。不過這個妹妹也真是的,要加入友誼會是無妨,不過不要只顧著自己要講的話,偶爾也要聽聽人家怎麼說嘛!更何況,偶爾回家看看家人,也是應該的。說起來,妳哥到處亂砍人,也是因妳而起,妳也要負點責任吧?我帶妳回紫衫城老家,妳還應該謝謝我才是。唉,誰叫我是關心不列顛人民的聖者呢?話說回來,這件事之中,我到底得到了什麼情報呢?友誼會到底是會妖法,還是不會妖法?嗯嗯,想來想去,好像還是無解。

    + +

    我一面心裏碎碎念,一面越走越遠。

    + +
    +Thad 和 Millie 對質 +

    我硬把 Millie 帶到紫衫城深山裏塞給 Thad ,然後頭也不回地離開。

    +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 17 | + 18 | + 19 | + 20 | + 21 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0020.html.en.html b/htdocs/imacat/me/diary/0020.html.en.html new file mode 120000 index 0000000..3c68ee9 --- /dev/null +++ b/htdocs/imacat/me/diary/0020.html.en.html @@ -0,0 +1 @@ +0020.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0020.html.en.xhtml b/htdocs/imacat/me/diary/0020.html.en.xhtml new file mode 100644 index 0000000..facb212 --- /dev/null +++ b/htdocs/imacat/me/diary/0020.html.en.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 20 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 20

    + +
    + +
    + +
    +
    2.26.’06. 12:10pm.
    + +

    終於玩完了創世紀七‧黑月之門創世紀七資料片‧美德試煉場,一套 1992 年的經典 RPG 角色扮演遊戲,玩了十四年才玩完。

    + +

    謝謝 SourceForge 上的 Exult 小組。 Exult 是一個創世紀七遊戲引擎,讓這套十四年前的、使用特殊記憶體管理程式的遊戲,可以在現代的 Linux/Windows 上玩。

    + +

    使用 Exult 引擎的還有創世紀七第二部‧巨蛇之島創世紀七第二部資料片‧銀色種子。不過不像我十幾年錢曾經掏錢買的黑月之門巨蛇之島我已經沒有說明書和地圖了,只能看創世紀合輯光碟片上的英文說明書。不知道有沒有機會玩完。

    + +

    剛剛一查 SourceForge ,上面與創世紀系列有關的專案有上百個,各代的遊戲引擎幾乎都有,令人嘆為觀止。 ^_*'

    + +
    + +
    + +
    +
    2.23.’06. 10:33pm.
    + +

    Bradman of Yew charge half price (15 gold) for training Iolo or Tseramed.

    + +
    + +
    + +
    +
    2.19.’06. 7:29am.
    + +

    終於玩完了創世紀七‧黑月之門,一個等了 14 年的遊戲結局。

    + +
    + +
    + +
    +
    2.11.’06. 3:36pm.
    + +

    I received a mail from cpan-testers, in response to one of my failure reports, started with Your testing system is broken. After a while, I decided to reply with: I'm not replying to rude mails like this.

    + +

    I decided to stop replying rude mails anymore. I wonder why so many people are writing mails with such a rude attitude. For example:

    + +
      +
    • No body text. Everything is in the subject.
    • + +
    • Attachment without body text, or with only a few words like See attachment.
    • + +
    • No greetings like Hi, Hello, Sorry for bothering, Thank you for your time.
    • + +
    • I'm wrong. The possibility of her/his mistake or external factors are none.
    • +
    + +

    I wonder why these people are so rude and uneducated. I'll not response to their mails anymore.

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 18 | + 19 | + 20 | + 21 | + 22 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0020.html.zh-cn.html b/htdocs/imacat/me/diary/0020.html.zh-cn.html new file mode 120000 index 0000000..9abc21f --- /dev/null +++ b/htdocs/imacat/me/diary/0020.html.zh-cn.html @@ -0,0 +1 @@ +0020.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0020.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0020.html.zh-cn.xhtml new file mode 100644 index 0000000..afc0d4e --- /dev/null +++ b/htdocs/imacat/me/diary/0020.html.zh-cn.xhtml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷二十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷二十

    + +
    + +
    + +
    +
    2.26.’06. 12:10pm.
    + +

    终于玩完了创世纪七·黑月之门创世纪七资料片·美德试炼场,一套 1992 年的经典 RPG 角色扮演游戏,玩了十四年才玩完。

    + +

    谢谢 SourceForge 上的 Exult 小组。 Exult 是一个创世纪七游戏引擎,让这套十四年前的、使用特殊记忆体管理程式的游戏,可以在现代的 Linux/Windows 上玩。

    + +

    使用 Exult 引擎的还有创世纪七第二部·巨蛇之岛创世纪七第二部资料片·银色种子。不过不像我十几年钱曾经掏钱买的黑月之门巨蛇之岛我已经没有说明书和地图了,只能看创世纪合辑光碟片上的英文说明书。不知道有没有机会玩完。

    + +

    刚刚一查 SourceForge ,上面与创世纪系列有关的专案有上百个,各代的游戏引擎几乎都有,令人叹为观止。 ^_*'

    + +
    + +
    + +
    +
    2.23.’06. 10:33pm.
    + +

    Bradman of Yew charge half price (15 gold) for training Iolo or Tseramed.

    + +
    + +
    + +
    +
    2.19.’06. 7:29am.
    + +

    终于玩完了创世纪七·黑月之门,一个等了 14 年的游戏结局。

    + +
    + +
    + +
    +
    2.11.’06. 3:36pm.
    + +

    今天收到一封 cpan-tester 的信,回应我的失败测试报告,劈头就说你的电脑设定有问题。想了一会,我回给他:恕不回应无礼来信。

    + +

    我决定以后,不再回覆无礼的信。不知道为什么,很多人写信教养真的很差。例如:

    + +
      +
    • 没有内文,要讲的话都在主旨。
    • + +
    • 只有附件档没有内文,或是内文只有见附件几个字。
    • + +
    • 没有你好抱歉打扰之类的问候语。
    • + +
    • 直指我错,不考虑自己错误或外在因素的可能性。
    • +
    + +

    大家都是人生父母养的,实在不知道为什么有些人就是没有教养。我以后不会再回,就这样。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 18 | + 19 | + 20 | + 21 | + 22 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0020.html.zh-tw.html b/htdocs/imacat/me/diary/0020.html.zh-tw.html new file mode 120000 index 0000000..195ef69 --- /dev/null +++ b/htdocs/imacat/me/diary/0020.html.zh-tw.html @@ -0,0 +1 @@ +0020.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0020.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0020.html.zh-tw.xhtml new file mode 100644 index 0000000..ccbf75c --- /dev/null +++ b/htdocs/imacat/me/diary/0020.html.zh-tw.xhtml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷二十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷二十

    + +
    + +
    + +
    +
    2.26.’06. 12:10pm.
    + +

    終於玩完了創世紀七‧黑月之門創世紀七資料片‧美德試煉場,一套 1992 年的經典 RPG 角色扮演遊戲,玩了十四年才玩完。

    + +

    謝謝 SourceForge 上的 Exult 小組。 Exult 是一個創世紀七遊戲引擎,讓這套十四年前的、使用特殊記憶體管理程式的遊戲,可以在現代的 Linux/Windows 上玩。

    + +

    使用 Exult 引擎的還有創世紀七第二部‧巨蛇之島創世紀七第二部資料片‧銀色種子。不過不像我十幾年錢曾經掏錢買的黑月之門巨蛇之島我已經沒有說明書和地圖了,只能看創世紀合輯光碟片上的英文說明書。不知道有沒有機會玩完。

    + +

    剛剛一查 SourceForge ,上面與創世紀系列有關的專案有上百個,各代的遊戲引擎幾乎都有,令人嘆為觀止。 ^_*'

    + +
    + +
    + +
    +
    2.23.’06. 10:33pm.
    + +

    Bradman of Yew charge half price (15 gold) for training Iolo or Tseramed.

    + +
    + +
    + +
    +
    2.19.’06. 7:29am.
    + +

    終於玩完了創世紀七‧黑月之門,一個等了 14 年的遊戲結局。

    + +
    + +
    + +
    +
    2.11.’06. 3:36pm.
    + +

    今天收到一封 cpan-tester 的信,回應我的失敗測試報告,劈頭就說妳的電腦設定有問題。想了一會,我回給他:恕不回應無禮來信。

    + +

    我決定以後,不再回覆無禮的信。不知道為什麼,很多人寫信教養真的很差。例如:

    + +
      +
    • 沒有內文,要講的話都在主旨。
    • + +
    • 只有附件檔沒有內文,或是內文只有見附件幾個字。
    • + +
    • 沒有你好抱歉打擾之類的問候語。
    • + +
    • 直指我錯,不考慮自己錯誤或外在因素的可能性。
    • +
    + +

    大家都是人生父母養的,實在不知道為什麼有些人就是沒有教養。我以後不會再回,就這樣。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 18 | + 19 | + 20 | + 21 | + 22 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0021.html.en.html b/htdocs/imacat/me/diary/0021.html.en.html new file mode 120000 index 0000000..8d61d23 --- /dev/null +++ b/htdocs/imacat/me/diary/0021.html.en.html @@ -0,0 +1 @@ +0021.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0021.html.en.xhtml b/htdocs/imacat/me/diary/0021.html.en.xhtml new file mode 100644 index 0000000..1268552 --- /dev/null +++ b/htdocs/imacat/me/diary/0021.html.en.xhtml @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 21 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 21

    + +
    + +
    + +
    +
    3.26.’06. 1:48am.
    + +

    來寫幾篇漫畫短評吧,一個月沒寫日記了。

    + +

    中午休息時間,我都會去附近的漫畫出租店窩個一個半小時。最近幾個喜歡的畫家的作品看完了,開始亂看一些漫畫。把一些出租店意外找到的經典,卻不怎麼想看的漫畫拿出來翻。這兩天連這些不想看的經典都看完了,開始亂看一些有的沒有的:

    + +
      +
    1. 暗黒の破壊神 BASTARD!! (暗黑破壞神)( 1–23 未完)

      + +
      荻原一至
      + +

      曾經轟動一時的經典漫畫,不過超爛。有點理解為什麼會紅:好色自大個性超級差又超級強大的無敵男主角達克.修耐達,女人見一個上一個,可是又莫名奇妙地每個人都認為他其實本性還不錯。實在是不知道那個本性還不錯所為何來。好像個性超差的爛男人到處亂搞擺爛以後,總是可以回過頭來自我安慰其實自己本性還不錯

      + +

      裏面每個女人,不管是勇敢的女主角迪亞.諾特.洋子,純潔的希拉公主,厲害的雷帝亞協斯.妮,還是聖潔的天使米加勒,都穿成兩條布拉下來在腰間圍著。這樣看起來,蕭淑慎在金鐘獎穿的拉低胸爆乳裝,還有白靈最常穿的薄紗裝,好像也沒什麼,因為在少年漫畫裏,大家都這麼穿。而且女生動不動就會衣服碎裂,常常光著身子到處跑,其實很像 A 書。

      + +

      忍耐了很久,才看到最新一集。(雖然不大知道自己為什麼要忍耐這種事。)十幾年了還沒畫完,不知道荻原一至還畫不畫得畫下去。少年漫畫最噁爛的元素(超強無敵的男主角,每個女生都愛上他,其實大家都知道他本性善良),一應俱全。真的很爛。

      +
    2. + +
    3. 頭文字D(イニシャルディー)( 1–32 未完)

      + +
      しげの秀一(重野秀一)
      + +

      這也是部經典漫畫。我是先看了電影以後,才去看的。看完了覺得不怎麼樣。男主角藤原拓海,的確很適合周杰倫。不過一口氣從頭看到尾了以後,覺得很倦。拓海怎麼比都一定會贏。有一回連老爸文太都覺得他應該輸一輸來磨練心志,可是還是贏了。反正怎麼樣都會贏就是了,現代的漫畫還來這一套的已經不多了。

      + +

      還有一個非常老掉牙的場景:主角和對手拼死拼活比賽到快結束時,會有人躲在樹叢裏奸笑,嘲笑這是小學生程度的比賽,不過那些人還是會被藤原拓海打敗。好像古龍的武俠小說,本來很厲害的壞人甲,等到新壞人乙要上場時,突然就被壞人乙一招殺死了,然後壞人丙要上場時,壞人乙又被壞人丙半招殺掉了。前後對手的強弱落差誇張到不合理,不過主角一定能夠克服。

      +
    4. + +
    5. 東京カルメン(東京卡門)( 1–7 全)、名探偵マダム・ホームズ(名偵探福爾摩斯夫人)(1全)

      + +
      原作/鍋島雅治 作画/花小路ゆみ(花小路小町)
      + +

      花小路ゆみ的畫風很細,很喜歡畫中式的盤髮(就是那種不用髮簪無法固定的複雜髮式)。這兩部都是以非常美豔的神秘女人為主角,一個是詐欺師,一個是偵探,解決各式各樣的事件,內容頗煽情。應該算是社會寫實類的漫畫,可是在社會寫實漫畫中,卻又是少有的細緻畫風。

      + +

      比較值得一提的是東京卡門。乍看之下,是滿足男生對神秘美女誘惑性幻想的典型漫畫(也是我平常不會去看的典型,所以才說最近亂看漫畫),不過仔細讀下去,會感覺到內容透著一股人情味,而且不做作。不管對手是詐騙老人安養金的時代劇演員,還是被金錢迷惑的超級業務員,打倒他們,讓他們付出應付的代價後,還是給他們一個重新開始的機會,讓他們重生。少年漫畫常見的劇情是,以殺死壞人來實現正義,不把人命當一回事,或是殺人魔王莫名奇妙就成了有悲情過去的陰暗角色,在與主角的死鬥中建立人性與友情,就漂白掉了,之前傷天害理、殺人如麻的壞事都不算了。(最典型的就是北斗神拳的拳王。)比較起來,東京卡門的人情味,在為自己做的壞事負責之外,又予人痛悔、重生的餘地。這樣的人情味,讓整部漫畫很溫暖,很有味道。

      +
    6. + +
    7. デスノート DEATH NOTE (死亡筆記本)( 1–10 未完)

      + +
      小畑健
      + +

      會注意到這部漫畫,是因為它上了 7–11 的貨架。這是一部很糟的漫畫。死神在人間掉了一本筆記本,只要擁有筆記本,寫上別人的名字、死亡時間和方式,對方就會按該時間方式死亡。主角高中優等生夜神月檢到了筆記本,用筆記本制裁警方無力制裁的罪犯,企圖建立無犯罪的理想國;注意到罪犯大量暴斃的世界偵探 L 則聯合警方,企圖找出真相和代號奇樂的兇手。於是夜神月和 L 之間,展開了一連串的鬥法。雙方像在下棋,以筆記本的規則為遊戲規則,誰先被對方抓到弱點,誰就輸了,棋盤上的棋子是人命,輸了的代價是死亡。

      + +

      我無法茍同這種人命遊戲。雙方都不把人命當一回事!怎麼可以這樣子呢? L 雖誓言抓到奇樂,可是卻從未討論奇樂這樣殺掉罪犯到底有什麼錯,甚至還找罪犯給奇樂殺,以測試奇樂的行動狀態;夜神月則以不同手段殺人,來欺敵擾敵; L 的後繼者之一梅洛則收服一群黑幫,以他們的性命作棋子跟奇樂鬥法。人命,不過是主角棋盤上的籌碼而已,毫無重量。沒有人覺得,任由他人的人命大量、隨意流失,有什麼不妥。每個人似乎都認為,自己有權依自己的慾望(建立理想社會/抓到奇樂),任意處置他人生死。虛無至此,令人噁心反胃。

      + +

      爛!

      +
    8. + +
    9. D.Gray-man ディーグレイマン(驅魔少年)( 1–7 未完)

      + +
      星野桂
      + +

      驅魔少年蠻好看的,雖然書背看起來跟死亡筆記本那套爛書很像,不過完全不一樣。書中的惡魔其實是一種人造的殺人機器人,驅魔師其實是在對抗機器人。男主角亞連.沃克雖然常常面對生死戰鬥,可是還是牢記在心自己是要救人,不是要殺人,常為了人死而痛哭。後來惡魔陣營加入了幾個人類,加上產生感情的惡魔,使人性的感情牽扯張力更強。

      + +

      另一個有趣的地方是後來加入的兩個驅魔師:個性陰暗自閉自卑的米蘭達.羅德 Miranda Loto ,和害怕人群的吸血鬼亞歷斯特.柯洛利 Areist Krouli 三世。尤其是米蘭達,一般的漫畫裏,個性陰暗自卑的人多半是不重要的丑角,或是主角幫助的對象,很少成為正義陣營的主要角色。讓這樣的角色一躍成為主角,我覺得非常有意思,很有正面的價值。據作者說,這個發展不在一開始的劇情計畫內。

      + +

      另外,柯洛利原本以為自己是吸血鬼,害怕自己無意識下殺人,非常自責,把自己關在在城堡內,後來證實自己殺死的、以為是普通村民的人們才是惡魔機器人,自己在無意識中驅魔,而身邊唯一陪伴自己的情人艾莉蒂其實是惡魔,被迫跟艾莉蒂決鬥那一段故事,讓人非常感動。

      +
    10. + +
    11. 17歳。女子高生監禁殺人( 1–3 未完)

      + +
      原作/藤井誠二 作画/鎌田洋次
      + +

      一部探討青少年犯罪的漫畫。原本只是幾個成群結黨的小鬼,無聊抓了一個路上的高中女生,卻因為害怕、膽怯等等各種原因,越陷越深,演變成集體輪姦、長期監禁、虐待,最後甚至殺害,無法回頭的一樁悲劇。過程中曾有許多次機會,可是沒有人跳出來阻止。一切事情的演變,都進展得那麼自然,筆直朝向毀滅的終點。為什麼會這樣呢?為什麼無法阻止這樣的悲劇?作者透過畫筆,提出非常深刻的疑問。

      + +

      一部很沉重、深刻的漫畫。看了這部漫畫,會讓我想去找藤井誠二鎌田洋次的其它作品。

      +
    12. + +
    13. 極楽青春ホッケー部(極樂青春曲棍球社)( 1–2 未完)

      + +
      森永あい(森永愛)
      + +

      貧窮貴公子作者森永愛的最新作品,非常爆笑。女主角鈴木小花是高一新生,最大的興趣是睡覺,為了能夠睡到上課前三分鐘起床,國中原本成績後段的她,拼死唸書(一天只睡十小時?)考上家門口不到五十公尺的明星高中。沒想到上高中的第一天,莫名奇妙之下,進了要晨練的運動性社團曲棍球社,自此從天堂墜落地獄。劇情不是很複雜,輕鬆爆笑的漫畫。

      +
    14. + +
    15. キャットストリート Cat Street (貓街)( 1–2 未完)

      + +
      神尾葉子
      + +

      流星花園的作者神尾葉子的最新作品。女主角青山惠都小時候是個閃亮的童星,卻因為一次演出失敗承受不了打擊,開始封閉自己,整整六年不再去上學上課,直到一次偶然間發現自由學校,找到一群跟自己一樣遭遇的同伴,才慢慢走出自己的圈圈。我也曾經有過很相近的過去,看到這樣深刻刻劃的故事,讓我很感動。希望以後的劇情發展,不要像流星花園一樣惡搞。真的是非常棒的故事。

      +
    16. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 19 | + 20 | + 21 | + 22 | + 23 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0021.html.zh-cn.html b/htdocs/imacat/me/diary/0021.html.zh-cn.html new file mode 120000 index 0000000..d32cbbb --- /dev/null +++ b/htdocs/imacat/me/diary/0021.html.zh-cn.html @@ -0,0 +1 @@ +0021.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0021.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0021.html.zh-cn.xhtml new file mode 100644 index 0000000..7f71600 --- /dev/null +++ b/htdocs/imacat/me/diary/0021.html.zh-cn.xhtml @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷二十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷二十一

    + +
    + +
    + +
    +
    3.26.’06. 1:48am.
    + +

    来写几篇漫画短评吧,一个月没写日记了。

    + +

    中午休息时间,我都会去附近的漫画出租店窝个一个半小时。最近几个喜欢的画家的作品看完了,开始乱看一些漫画。把一些出租店意外找到的经典,却不怎么想看的漫画拿出来翻。这两天连这些不想看的经典都看完了,开始乱看一些有的没有的:

    + +
      +
    1. 暗黒の破壊神 BASTARD!! (暗黑破坏神)( 1–23 未完)

      + +
      荻原一至
      + +

      曾经轰动一时的经典漫画,不过超烂。有点理解为什么会红:好色自大个性超级差又超级强大的无敌男主角达克.修耐达,女人见一个上一个,可是又莫名奇妙地每个人都认为他其实本性还不错。实在是不知道那个本性还不错所为何来。好像个性超差的烂男人到处乱搞摆烂以后,总是可以回过头来自我安慰其实自己本性还不错

      + +

      里面每个女人,不管是勇敢的女主角迪亚.诺特.洋子,纯洁的希拉公主,厉害的雷帝亚协斯.妮,还是圣洁的天使米加勒,都穿成两条布拉下来在腰间围著。这样看起来,萧淑慎在金钟奖穿的拉低胸爆乳装,还有白灵最常穿的薄纱装,好像也没什么,因为在少年漫画里,大家都这么穿。而且女生动不动就会衣服碎裂,常常光著身子到处跑,其实很像 A 书。

      + +

      忍耐了很久,才看到最新一集。(虽然不大知道自己为什么要忍耐这种事。)十几年了还没画完,不知道荻原一至还画不画得画下去。少年漫画最恶烂的元素(超强无敌的男主角,每个女生都爱上他,其实大家都知道他本性善良),一应俱全。真的很烂。

      +
    2. + +
    3. 头文字D(イニシャルディー)( 1–32 未完)

      + +
      しげの秀一(重野秀一)
      + +

      这也是部经典漫画。我是先看了电影以后,才去看的。看完了觉得不怎么样。男主角藤原拓海,的确很适合周杰伦。不过一口气从头看到尾了以后,觉得很倦。拓海怎么比都一定会赢。有一回连老爸文太都觉得他应该输一输来磨练心志,可是还是赢了。反正怎么样都会赢就是了,现代的漫画还来这一套的已经不多了。

      + +

      还有一个非常老掉牙的场景:主角和对手拼死拼活比赛到快结束时,会有人躲在树丛里奸笑,嘲笑这是小学生程度的比赛,不过那些人还是会被藤原拓海打败。好像古龙的武侠小说,本来很厉害的坏人甲,等到新坏人乙要上场时,突然就被坏人乙一招杀死了,然后坏人丙要上场时,坏人乙又被坏人丙半招杀掉了。前后对手的强弱落差夸张到不合理,不过主角一定能够克服。

      +
    4. + +
    5. 东京カルメン(东京卡门)( 1–7 全)、名探侦マダム・ホームズ(名侦探福尔摩斯夫人)(1全)

      + +
      原作/锅岛雅治 作画/花小路ゆみ(花小路小町)
      + +

      花小路ゆみ的画风很细,很喜欢画中式的盘发(就是那种不用发簪无法固定的复杂发式)。这两部都是以非常美艳的神秘女人为主角,一个是诈欺师,一个是侦探,解决各式各样的事件,内容颇煽情。应该算是社会写实类的漫画,可是在社会写实漫画中,却又是少有的细致画风。

      + +

      比较值得一提的是东京卡门。乍看之下,是满足男生对神秘美女诱惑性幻想的典型漫画(也是我平常不会去看的典型,所以才说最近乱看漫画),不过仔细读下去,会感觉到内容透著一股人情味,而且不做作。不管对手是诈骗老人安养金的时代剧演员,还是被金钱迷惑的超级业务员,打倒他们,让他们付出应付的代价后,还是给他们一个重新开始的机会,让他们重生。少年漫画常见的剧情是,以杀死坏人来实现正义,不把人命当一回事,或是杀人魔王莫名奇妙就成了有悲情过去的阴暗角色,在与主角的死斗中建立人性与友情,就漂白掉了,之前伤天害理、杀人如麻的坏事都不算了。(最典型的就是北斗神拳的拳王。)比较起来,东京卡门的人情味,在为自己做的坏事负责之外,又予人痛悔、重生的余地。这样的人情味,让整部漫画很温暖,很有味道。

      +
    6. + +
    7. デスノート DEATH NOTE (死亡笔记本)( 1–10 未完)

      + +
      小畑健
      + +

      会注意到这部漫画,是因为它上了 7–11 的货架。这是一部很糟的漫画。死神在人间掉了一本笔记本,只要拥有笔记本,写上别人的名字、死亡时间和方式,对方就会按该时间方式死亡。主角高中优等生夜神月检到了笔记本,用笔记本制裁警方无力制裁的罪犯,企图建立无犯罪的理想国;注意到罪犯大量暴毙的世界侦探 L 则联合警方,企图找出真相和代号奇乐的凶手。於是夜神月和 L 之间,展开了一连串的斗法。双方像在下棋,以笔记本的规则为游戏规则,谁先被对方抓到弱点,谁就输了,棋盘上的棋子是人命,输了的代价是死亡。

      + +

      我无法苟同这种人命游戏。双方都不把人命当一回事!怎么可以这样子呢? L 虽誓言抓到奇乐,可是却从未讨论奇乐这样杀掉罪犯到底有什么错,甚至还找罪犯给奇乐杀,以测试奇乐的行动状态;夜神月则以不同手段杀人,来欺敌扰敌; L 的后继者之一梅洛则收服一群黑帮,以他们的性命作棋子跟奇乐斗法。人命,不过是主角棋盘上的筹码而已,毫无重量。没有人觉得,任由他人的人命大量、随意流失,有什么不妥。每个人似乎都认为,自己有权依自己的欲望(建立理想社会/抓到奇乐),任意处置他人生死。虚无至此,令人恶心反胃。

      + +

      烂!

      +
    8. + +
    9. D.Gray-man ディーグレイマン(驱魔少年)( 1–7 未完)

      + +
      星野桂
      + +

      驱魔少年蛮好看的,虽然书背看起来跟死亡笔记本那套烂书很像,不过完全不一样。书中的恶魔其实是一种人造的杀人机器人,驱魔师其实是在对抗机器人。男主角亚连.沃克虽然常常面对生死战斗,可是还是牢记在心自己是要救人,不是要杀人,常为了人死而痛哭。后来恶魔阵营加入了几个人类,加上产生感情的恶魔,使人性的感情牵扯张力更强。

      + +

      另一个有趣的地方是后来加入的两个驱魔师:个性阴暗自闭自卑的米兰达.罗德 Miranda Loto ,和害怕人群的吸血鬼亚历斯特.柯洛利 Areist Krouli 三世。尤其是米兰达,一般的漫画里,个性阴暗自卑的人多半是不重要的丑角,或是主角帮助的对象,很少成为正义阵营的主要角色。让这样的角色一跃成为主角,我觉得非常有意思,很有正面的价值。据作者说,这个发展不在一开始的剧情计画内。

      + +

      另外,柯洛利原本以为自己是吸血鬼,害怕自己无意识下杀人,非常自责,把自己关在在城堡内,后来证实自己杀死的、以为是普通村民的人们才是恶魔机器人,自己在无意识中驱魔,而身边唯一陪伴自己的情人艾莉蒂其实是恶魔,被迫跟艾莉蒂决斗那一段故事,让人非常感动。

      +
    10. + +
    11. 17歳。女子高生监禁杀人( 1–3 未完)

      + +
      原作/藤井诚二 作画/镰田洋次
      + +

      一部探讨青少年犯罪的漫画。原本只是几个成群结党的小鬼,无聊抓了一个路上的高中女生,却因为害怕、胆怯等等各种原因,越陷越深,演变成集体轮奸、长期监禁、虐待,最后甚至杀害,无法回头的一桩悲剧。过程中曾有许多次机会,可是没有人跳出来阻止。一切事情的演变,都进展得那么自然,笔直朝向毁灭的终点。为什么会这样呢?为什么无法阻止这样的悲剧?作者透过画笔,提出非常深刻的疑问。

      + +

      一部很沉重、深刻的漫画。看了这部漫画,会让我想去找藤井诚二镰田洋次的其它作品。

      +
    12. + +
    13. 极楽青春ホッケー部(极乐青春曲棍球社)( 1–2 未完)

      + +
      森永あい(森永爱)
      + +

      贫穷贵公子作者森永爱的最新作品,非常爆笑。女主角铃木小花是高一新生,最大的兴趣是睡觉,为了能够睡到上课前三分钟起床,国中原本成绩后段的她,拼死念书(一天只睡十小时?)考上家门口不到五十公尺的明星高中。没想到上高中的第一天,莫名奇妙之下,进了要晨练的运动性社团曲棍球社,自此从天堂坠落地狱。剧情不是很复杂,轻松爆笑的漫画。

      +
    14. + +
    15. キャットストリート Cat Street (猫街)( 1–2 未完)

      + +
      神尾叶子
      + +

      流星花园的作者神尾叶子的最新作品。女主角青山惠都小时候是个闪亮的童星,却因为一次演出失败承受不了打击,开始封闭自己,整整六年不再去上学上课,直到一次偶然间发现自由学校,找到一群跟自己一样遭遇的同伴,才慢慢走出自己的圈圈。我也曾经有过很相近的过去,看到这样深刻刻划的故事,让我很感动。希望以后的剧情发展,不要像流星花园一样恶搞。真的是非常棒的故事。

      +
    16. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 19 | + 20 | + 21 | + 22 | + 23 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0021.html.zh-tw.html b/htdocs/imacat/me/diary/0021.html.zh-tw.html new file mode 120000 index 0000000..3d7bec5 --- /dev/null +++ b/htdocs/imacat/me/diary/0021.html.zh-tw.html @@ -0,0 +1 @@ +0021.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0021.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0021.html.zh-tw.xhtml new file mode 100644 index 0000000..bb51bd3 --- /dev/null +++ b/htdocs/imacat/me/diary/0021.html.zh-tw.xhtml @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷二十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷二十一

    + +
    + +
    + +
    +
    3.26.’06. 1:48am.
    + +

    來寫幾篇漫畫短評吧,一個月沒寫日記了。

    + +

    中午休息時間,我都會去附近的漫畫出租店窩個一個半小時。最近幾個喜歡的畫家的作品看完了,開始亂看一些漫畫。把一些出租店意外找到的經典,卻不怎麼想看的漫畫拿出來翻。這兩天連這些不想看的經典都看完了,開始亂看一些有的沒有的:

    + +
      +
    1. 暗黒の破壊神 BASTARD!! (暗黑破壞神)( 1–23 未完)

      + +
      荻原一至
      + +

      曾經轟動一時的經典漫畫,不過超爛。有點理解為什麼會紅:好色自大個性超級差又超級強大的無敵男主角達克.修耐達,女人見一個上一個,可是又莫名奇妙地每個人都認為他其實本性還不錯。實在是不知道那個本性還不錯所為何來。好像個性超差的爛男人到處亂搞擺爛以後,總是可以回過頭來自我安慰其實自己本性還不錯

      + +

      裏面每個女人,不管是勇敢的女主角迪亞.諾特.洋子,純潔的希拉公主,厲害的雷帝亞協斯.妮,還是聖潔的天使米加勒,都穿成兩條布拉下來在腰間圍著。這樣看起來,蕭淑慎在金鐘獎穿的拉低胸爆乳裝,還有白靈最常穿的薄紗裝,好像也沒什麼,因為在少年漫畫裏,大家都這麼穿。而且女生動不動就會衣服碎裂,常常光著身子到處跑,其實很像 A 書。

      + +

      忍耐了很久,才看到最新一集。(雖然不大知道自己為什麼要忍耐這種事。)十幾年了還沒畫完,不知道荻原一至還畫不畫得畫下去。少年漫畫最噁爛的元素(超強無敵的男主角,每個女生都愛上他,其實大家都知道他本性善良),一應俱全。真的很爛。

      +
    2. + +
    3. 頭文字D(イニシャルディー)( 1–32 未完)

      + +
      しげの秀一(重野秀一)
      + +

      這也是部經典漫畫。我是先看了電影以後,才去看的。看完了覺得不怎麼樣。男主角藤原拓海,的確很適合周杰倫。不過一口氣從頭看到尾了以後,覺得很倦。拓海怎麼比都一定會贏。有一回連老爸文太都覺得他應該輸一輸來磨練心志,可是還是贏了。反正怎麼樣都會贏就是了,現代的漫畫還來這一套的已經不多了。

      + +

      還有一個非常老掉牙的場景:主角和對手拼死拼活比賽到快結束時,會有人躲在樹叢裏奸笑,嘲笑這是小學生程度的比賽,不過那些人還是會被藤原拓海打敗。好像古龍的武俠小說,本來很厲害的壞人甲,等到新壞人乙要上場時,突然就被壞人乙一招殺死了,然後壞人丙要上場時,壞人乙又被壞人丙半招殺掉了。前後對手的強弱落差誇張到不合理,不過主角一定能夠克服。

      +
    4. + +
    5. 東京カルメン(東京卡門)( 1–7 全)、名探偵マダム・ホームズ(名偵探福爾摩斯夫人)(1全)

      + +
      原作/鍋島雅治 作画/花小路ゆみ(花小路小町)
      + +

      花小路ゆみ的畫風很細,很喜歡畫中式的盤髮(就是那種不用髮簪無法固定的複雜髮式)。這兩部都是以非常美豔的神秘女人為主角,一個是詐欺師,一個是偵探,解決各式各樣的事件,內容頗煽情。應該算是社會寫實類的漫畫,可是在社會寫實漫畫中,卻又是少有的細緻畫風。

      + +

      比較值得一提的是東京卡門。乍看之下,是滿足男生對神秘美女誘惑性幻想的典型漫畫(也是我平常不會去看的典型,所以才說最近亂看漫畫),不過仔細讀下去,會感覺到內容透著一股人情味,而且不做作。不管對手是詐騙老人安養金的時代劇演員,還是被金錢迷惑的超級業務員,打倒他們,讓他們付出應付的代價後,還是給他們一個重新開始的機會,讓他們重生。少年漫畫常見的劇情是,以殺死壞人來實現正義,不把人命當一回事,或是殺人魔王莫名奇妙就成了有悲情過去的陰暗角色,在與主角的死鬥中建立人性與友情,就漂白掉了,之前傷天害理、殺人如麻的壞事都不算了。(最典型的就是北斗神拳的拳王。)比較起來,東京卡門的人情味,在為自己做的壞事負責之外,又予人痛悔、重生的餘地。這樣的人情味,讓整部漫畫很溫暖,很有味道。

      +
    6. + +
    7. デスノート DEATH NOTE (死亡筆記本)( 1–10 未完)

      + +
      小畑健
      + +

      會注意到這部漫畫,是因為它上了 7–11 的貨架。這是一部很糟的漫畫。死神在人間掉了一本筆記本,只要擁有筆記本,寫上別人的名字、死亡時間和方式,對方就會按該時間方式死亡。主角高中優等生夜神月檢到了筆記本,用筆記本制裁警方無力制裁的罪犯,企圖建立無犯罪的理想國;注意到罪犯大量暴斃的世界偵探 L 則聯合警方,企圖找出真相和代號奇樂的兇手。於是夜神月和 L 之間,展開了一連串的鬥法。雙方像在下棋,以筆記本的規則為遊戲規則,誰先被對方抓到弱點,誰就輸了,棋盤上的棋子是人命,輸了的代價是死亡。

      + +

      我無法茍同這種人命遊戲。雙方都不把人命當一回事!怎麼可以這樣子呢? L 雖誓言抓到奇樂,可是卻從未討論奇樂這樣殺掉罪犯到底有什麼錯,甚至還找罪犯給奇樂殺,以測試奇樂的行動狀態;夜神月則以不同手段殺人,來欺敵擾敵; L 的後繼者之一梅洛則收服一群黑幫,以他們的性命作棋子跟奇樂鬥法。人命,不過是主角棋盤上的籌碼而已,毫無重量。沒有人覺得,任由他人的人命大量、隨意流失,有什麼不妥。每個人似乎都認為,自己有權依自己的慾望(建立理想社會/抓到奇樂),任意處置他人生死。虛無至此,令人噁心反胃。

      + +

      爛!

      +
    8. + +
    9. D.Gray-man ディーグレイマン(驅魔少年)( 1–7 未完)

      + +
      星野桂
      + +

      驅魔少年蠻好看的,雖然書背看起來跟死亡筆記本那套爛書很像,不過完全不一樣。書中的惡魔其實是一種人造的殺人機器人,驅魔師其實是在對抗機器人。男主角亞連.沃克雖然常常面對生死戰鬥,可是還是牢記在心自己是要救人,不是要殺人,常為了人死而痛哭。後來惡魔陣營加入了幾個人類,加上產生感情的惡魔,使人性的感情牽扯張力更強。

      + +

      另一個有趣的地方是後來加入的兩個驅魔師:個性陰暗自閉自卑的米蘭達.羅德 Miranda Loto ,和害怕人群的吸血鬼亞歷斯特.柯洛利 Areist Krouli 三世。尤其是米蘭達,一般的漫畫裏,個性陰暗自卑的人多半是不重要的丑角,或是主角幫助的對象,很少成為正義陣營的主要角色。讓這樣的角色一躍成為主角,我覺得非常有意思,很有正面的價值。據作者說,這個發展不在一開始的劇情計畫內。

      + +

      另外,柯洛利原本以為自己是吸血鬼,害怕自己無意識下殺人,非常自責,把自己關在在城堡內,後來證實自己殺死的、以為是普通村民的人們才是惡魔機器人,自己在無意識中驅魔,而身邊唯一陪伴自己的情人艾莉蒂其實是惡魔,被迫跟艾莉蒂決鬥那一段故事,讓人非常感動。

      +
    10. + +
    11. 17歳。女子高生監禁殺人( 1–3 未完)

      + +
      原作/藤井誠二 作画/鎌田洋次
      + +

      一部探討青少年犯罪的漫畫。原本只是幾個成群結黨的小鬼,無聊抓了一個路上的高中女生,卻因為害怕、膽怯等等各種原因,越陷越深,演變成集體輪姦、長期監禁、虐待,最後甚至殺害,無法回頭的一樁悲劇。過程中曾有許多次機會,可是沒有人跳出來阻止。一切事情的演變,都進展得那麼自然,筆直朝向毀滅的終點。為什麼會這樣呢?為什麼無法阻止這樣的悲劇?作者透過畫筆,提出非常深刻的疑問。

      + +

      一部很沉重、深刻的漫畫。看了這部漫畫,會讓我想去找藤井誠二鎌田洋次的其它作品。

      +
    12. + +
    13. 極楽青春ホッケー部(極樂青春曲棍球社)( 1–2 未完)

      + +
      森永あい(森永愛)
      + +

      貧窮貴公子作者森永愛的最新作品,非常爆笑。女主角鈴木小花是高一新生,最大的興趣是睡覺,為了能夠睡到上課前三分鐘起床,國中原本成績後段的她,拼死唸書(一天只睡十小時?)考上家門口不到五十公尺的明星高中。沒想到上高中的第一天,莫名奇妙之下,進了要晨練的運動性社團曲棍球社,自此從天堂墜落地獄。劇情不是很複雜,輕鬆爆笑的漫畫。

      +
    14. + +
    15. キャットストリート Cat Street (貓街)( 1–2 未完)

      + +
      神尾葉子
      + +

      流星花園的作者神尾葉子的最新作品。女主角青山惠都小時候是個閃亮的童星,卻因為一次演出失敗承受不了打擊,開始封閉自己,整整六年不再去上學上課,直到一次偶然間發現自由學校,找到一群跟自己一樣遭遇的同伴,才慢慢走出自己的圈圈。我也曾經有過很相近的過去,看到這樣深刻刻劃的故事,讓我很感動。希望以後的劇情發展,不要像流星花園一樣惡搞。真的是非常棒的故事。

      +
    16. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 19 | + 20 | + 21 | + 22 | + 23 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0022.html.en.html b/htdocs/imacat/me/diary/0022.html.en.html new file mode 120000 index 0000000..fda95bc --- /dev/null +++ b/htdocs/imacat/me/diary/0022.html.en.html @@ -0,0 +1 @@ +0022.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0022.html.en.xhtml b/htdocs/imacat/me/diary/0022.html.en.xhtml new file mode 100644 index 0000000..12fe009 --- /dev/null +++ b/htdocs/imacat/me/diary/0022.html.en.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 22 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 22

    + +
    + +
    + +
    +
    4.13.’06. 3:01am.
    + +

    剛剛閒逛 Wikipedia ,才發現原來 SourceForgeFreeBSD 的網站,在中國是被封鎖的!真是太扯了,中國政府是神經病啊?

    + +

    喔,剛剛發現PHP 的網站也被中國政府封鎖掉了。那中國的網路系統發展完蛋了,嗯嗯。

    + +

    鎖國是不好的事哪~日本明治維新前的德川幕府,可為殷鑑。

    + +
    + +
    + +
    +
    4.10.’06. 11:57pm.
    + +

    Finally we've got a full text search in Tavern now. Though there are still 28 pages not in the database yet, most of the content can be searched now. Yeah! ^_*'

    + +
    + +
    + +
    +
    4.9.’06. 9:42pm.
    + +

    I feel so moved that there are really some people using vsntp! But why didn't they come to me for their problem?

    + +
    + +
    + +
    +
    4.2.’06. 3:04am.
    + +

    花了兩個星期,結束了一個 Monica/Selima 核心的改造計劃。

    + +

    這是一個去年的構想,源自於寫 Julie 網站計劃時碰到的瓶頸: Monica 系統的資料異動更新處理,沿用七年前亞太糧肥舊網站使用 process.php 的架構,使用一個 process_form() 函式來處理。然而,處理複式的資料時(一筆資料引用其她資料,例如公司檔案會有不同的聯絡人),當資料間的交互關聯越來越複雜,使用 process_form() 函式,便顯得捉襟見肘。於是我想,是不是可以改用物件類別的方式,一個資料表的處理器可以引用另一個資料表的處理器,這樣就不需要去管另一個資料表的處理器的處理細節,程式碼亦可重複利用。這就是現在的 Monica ProcessorSelima::Processor::* 類別。

    + +

    去年想到這個構想時,覺得有點害怕。一個原因是 Monica 已經長得太大了:十一個網站,四百七十七個程式檔,十三萬多行。要全部改掉,還要一個一個測試,真的是要命。另外一個原因則是,每個網站的瀏覽架構都不大一樣,部份重製網頁時,相依性追蹤是不是做得來,我實在是沒有把握。於是,初步寫了不牽涉到網頁相依性的帳號管理子系統,確定原先的構想大致可行了後,就擱著了。一擱擱了快一年,一直到去年底的兩個新網站的案子,才又重起爐灶。兩個新網站處理資料的部份,就全部改用新的 Processor 物件界面了。

    + +

    今年年初,創世紀玩告一段落以後,我又回過頭來改寫 Selima ,把原先檔案空白的 Selima::Processor::* ,參考 Monica Processor 類別的帳號管理子系統,改寫出來。接著,又著手撰寫 Selima::Processor::* 的內容管理子系統,試著把網頁相依性追蹤、部份網頁重製的執行模式標準化。經過一年來的沉澱,寫得頗為順利。寫出來了以後,回過頭來改寫 Monica 的內容管理子系統的部份,花了兩個星期的時間,改寫一百多個程式檔、一一追蹤、測試。除了一個無可救藥的舊 FTP 帳號管理程式外,終於全部改寫完畢了。

    + +

    Monica/Selima 系統的資料處理架構上,有五大部門:資料列表、資料取得、顯示表格、表格檢查、異動更新。資料列表由 List 物件處理,資料取得由 fetch_curitem() 函式負責,顯示表格由 Form 物件負責,表格檢查由 Checker 物件負責,異動更新由 Processor 物件負責。目前,只剩下資料取得的部份,尚未物件化。因為每個表格都依賴某種資料格式才能正常顯示,一旦資料取得物件化,對後面的三個動作 FormCheckerProcessor 影響非常大。很多複式資料,應該取得給後面用的格式非常複雜,我沒有把握這些 Fetcher 物件能夠互相引用。然而,只要資料取得的動作還未物件化的一天, Monica/Selima 要處理複雜的複式資料,就會非常困難,而且無法處理兩層以上的複式資料。

    + +

    不過, Fetcher 暫時不是急迫的問題。而且去年 Julie 計劃碰到的瓶頸,我已經找到解答了,不需要用到三層以上的複式資料來處理,而可以利用資料表自己引用自己的方式解決。其實在之前連結分類的處理時,我就已經做過了。去年 PostgreSQL 的權限控管改採 role-based 系統,不再區分使用者和群組,每一個角色都可以包含別的角色。我從來沒想過可以這樣做,茅塞頓開。我想, Julie 的問題,應該可以用同樣的方法來解決。

    + +

    Monica/Selima 還有一個龐大的改造工程: Page 物件,用以追蹤網頁的相依性、製作瀏覽選單及網站地圖。這其實也是去年的構想,因為無障礙網頁規範要求網站要有網站地圖,目前 Monica 使用 page_tree() 函式回傳一個龐大的樹狀網頁資料,可是沒有方法,難以作更複雜的應用。我目前只有初步的想法而已。可能會先在 Selima 上實作吧,畢竟 Selima 還沒有正式的內容管理系統,包袱比較小。希望不需要用到一年。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 20 | + 21 | + 22 | + 23 | + 24 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0022.html.zh-cn.html b/htdocs/imacat/me/diary/0022.html.zh-cn.html new file mode 120000 index 0000000..a208d16 --- /dev/null +++ b/htdocs/imacat/me/diary/0022.html.zh-cn.html @@ -0,0 +1 @@ +0022.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0022.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0022.html.zh-cn.xhtml new file mode 100644 index 0000000..77b81c8 --- /dev/null +++ b/htdocs/imacat/me/diary/0022.html.zh-cn.xhtml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷二十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷二十二

    + +
    + +
    + +
    +
    4.13.’06. 3:01am.
    + +

    刚刚闲逛 Wikipedia ,才发现原来 SourceForgeFreeBSD 的网站,在中国是被封锁的!真是太扯了,中国政府是神经病啊?

    + +

    喔,刚刚发现PHP 的网站也被中国政府封锁掉了。那中国的网路系统发展完蛋了,嗯嗯。

    + +

    锁国是不好的事哪~日本明治维新前的德川幕府,可为殷鉴。

    + +
    + +
    + +
    +
    4.10.’06. 11:57pm.
    + +

    旅舍终於有了全文检索了。虽然现在所有网页还没有全部建档(还有 28 页左右),不过大部份的内容都已经放上去了。耶~! ^_*'

    + +
    + +
    + +
    +
    4.9.’06. 9:42pm.
    + +

    我发现真的有人在用 vsntp 耶,好感动喔~ :~~ 可是有问题怎么不来问我呢?嗯嗯。

    + +
    + +
    + +
    +
    4.2.’06. 3:04am.
    + +

    花了两个星期,结束了一个 Monica/Selima 核心的改造计划。

    + +

    这是一个去年的构想,源自於写 Julie 网站计划时碰到的瓶颈: Monica 系统的资料异动更新处理,沿用七年前亚太粮肥旧网站使用 process.php 的架构,使用一个 process_form() 函式来处理。然而,处理复式的资料时(一笔资料引用其她资料,例如公司档案会有不同的联络人),当资料间的交互关联越来越复杂,使用 process_form() 函式,便显得捉襟见肘。於是我想,是不是可以改用物件类别的方式,一个资料表的处理器可以引用另一个资料表的处理器,这样就不需要去管另一个资料表的处理器的处理细节,程式码亦可重复利用。这就是现在的 Monica ProcessorSelima::Processor::* 类别。

    + +

    去年想到这个构想时,觉得有点害怕。一个原因是 Monica 已经长得太大了:十一个网站,四百七十七个程式档,十三万多行。要全部改掉,还要一个一个测试,真的是要命。另外一个原因则是,每个网站的浏览架构都不大一样,部份重制网页时,相依性追踪是不是做得来,我实在是没有把握。於是,初步写了不牵涉到网页相依性的帐号管理子系统,确定原先的构想大致可行了后,就搁著了。一搁搁了快一年,一直到去年底的两个新网站的案子,才又重起炉灶。两个新网站处理资料的部份,就全部改用新的 Processor 物件界面了。

    + +

    今年年初,创世纪玩告一段落以后,我又回过头来改写 Selima ,把原先档案空白的 Selima::Processor::* ,参考 Monica Processor 类别的帐号管理子系统,改写出来。接著,又著手撰写 Selima::Processor::* 的内容管理子系统,试著把网页相依性追踪、部份网页重制的执行模式标准化。经过一年来的沉淀,写得颇为顺利。写出来了以后,回过头来改写 Monica 的内容管理子系统的部份,花了两个星期的时间,改写一百多个程式档、一一追踪、测试。除了一个无可救药的旧 FTP 帐号管理程式外,终於全部改写完毕了。

    + +

    Monica/Selima 系统的资料处理架构上,有五大部门:资料列表、资料取得、显示表格、表格检查、异动更新。资料列表由 List 物件处理,资料取得由 fetch_curitem() 函式负责,显示表格由 Form 物件负责,表格检查由 Checker 物件负责,异动更新由 Processor 物件负责。目前,只剩下资料取得的部份,尚未物件化。因为每个表格都依赖某种资料格式才能正常显示,一旦资料取得物件化,对后面的三个动作 FormCheckerProcessor 影响非常大。很多复式资料,应该取得给后面用的格式非常复杂,我没有把握这些 Fetcher 物件能够互相引用。然而,只要资料取得的动作还未物件化的一天, Monica/Selima 要处理复杂的复式资料,就会非常困难,而且无法处理两层以上的复式资料。

    + +

    不过, Fetcher 暂时不是急迫的问题。而且去年 Julie 计划碰到的瓶颈,我已经找到解答了,不需要用到三层以上的复式资料来处理,而可以利用资料表自己引用自己的方式解决。其实在之前连结分类的处理时,我就已经做过了。去年 PostgreSQL 的权限控管改采 role-based 系统,不再区分使用者和群组,每一个角色都可以包含别的角色。我从来没想过可以这样做,茅塞顿开。我想, Julie 的问题,应该可以用同样的方法来解决。

    + +

    Monica/Selima 还有一个庞大的改造工程: Page 物件,用以追踪网页的相依性、制作浏览选单及网站地图。这其实也是去年的构想,因为无障碍网页规范要求网站要有网站地图,目前 Monica 使用 page_tree() 函式回传一个庞大的树状网页资料,可是没有方法,难以作更复杂的应用。我目前只有初步的想法而已。可能会先在 Selima 上实作吧,毕竟 Selima 还没有正式的内容管理系统,包袱比较小。希望不需要用到一年。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 20 | + 21 | + 22 | + 23 | + 24 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0022.html.zh-tw.html b/htdocs/imacat/me/diary/0022.html.zh-tw.html new file mode 120000 index 0000000..6bba4d8 --- /dev/null +++ b/htdocs/imacat/me/diary/0022.html.zh-tw.html @@ -0,0 +1 @@ +0022.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0022.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0022.html.zh-tw.xhtml new file mode 100644 index 0000000..a9c30e8 --- /dev/null +++ b/htdocs/imacat/me/diary/0022.html.zh-tw.xhtml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷二十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷二十二

    + +
    + +
    + +
    +
    4.13.’06. 3:01am.
    + +

    剛剛閒逛 Wikipedia ,才發現原來 SourceForgeFreeBSD 的網站,在中國是被封鎖的!真是太扯了,中國政府是神經病啊?

    + +

    喔,剛剛發現PHP 的網站也被中國政府封鎖掉了。那中國的網路系統發展完蛋了,嗯嗯。

    + +

    鎖國是不好的事哪~日本明治維新前的德川幕府,可為殷鑑。

    + +
    + +
    + +
    +
    4.10.’06. 11:57pm.
    + +

    旅舍終於有了全文檢索了。雖然現在所有網頁還沒有全部建檔(還有 28 頁左右),不過大部份的內容都已經放上去了。耶~! ^_*'

    + +
    + +
    + +
    +
    4.9.’06. 9:42pm.
    + +

    我發現真的有人在用 vsntp 耶,好感動喔~ :~~ 可是有問題怎麼不來問我呢?嗯嗯。

    + +
    + +
    + +
    +
    4.2.’06. 3:04am.
    + +

    花了兩個星期,結束了一個 Monica/Selima 核心的改造計劃。

    + +

    這是一個去年的構想,源自於寫 Julie 網站計劃時碰到的瓶頸: Monica 系統的資料異動更新處理,沿用七年前亞太糧肥舊網站使用 process.php 的架構,使用一個 process_form() 函式來處理。然而,處理複式的資料時(一筆資料引用其她資料,例如公司檔案會有不同的聯絡人),當資料間的交互關聯越來越複雜,使用 process_form() 函式,便顯得捉襟見肘。於是我想,是不是可以改用物件類別的方式,一個資料表的處理器可以引用另一個資料表的處理器,這樣就不需要去管另一個資料表的處理器的處理細節,程式碼亦可重複利用。這就是現在的 Monica ProcessorSelima::Processor::* 類別。

    + +

    去年想到這個構想時,覺得有點害怕。一個原因是 Monica 已經長得太大了:十一個網站,四百七十七個程式檔,十三萬多行。要全部改掉,還要一個一個測試,真的是要命。另外一個原因則是,每個網站的瀏覽架構都不大一樣,部份重製網頁時,相依性追蹤是不是做得來,我實在是沒有把握。於是,初步寫了不牽涉到網頁相依性的帳號管理子系統,確定原先的構想大致可行了後,就擱著了。一擱擱了快一年,一直到去年底的兩個新網站的案子,才又重起爐灶。兩個新網站處理資料的部份,就全部改用新的 Processor 物件界面了。

    + +

    今年年初,創世紀玩告一段落以後,我又回過頭來改寫 Selima ,把原先檔案空白的 Selima::Processor::* ,參考 Monica Processor 類別的帳號管理子系統,改寫出來。接著,又著手撰寫 Selima::Processor::* 的內容管理子系統,試著把網頁相依性追蹤、部份網頁重製的執行模式標準化。經過一年來的沉澱,寫得頗為順利。寫出來了以後,回過頭來改寫 Monica 的內容管理子系統的部份,花了兩個星期的時間,改寫一百多個程式檔、一一追蹤、測試。除了一個無可救藥的舊 FTP 帳號管理程式外,終於全部改寫完畢了。

    + +

    Monica/Selima 系統的資料處理架構上,有五大部門:資料列表、資料取得、顯示表格、表格檢查、異動更新。資料列表由 List 物件處理,資料取得由 fetch_curitem() 函式負責,顯示表格由 Form 物件負責,表格檢查由 Checker 物件負責,異動更新由 Processor 物件負責。目前,只剩下資料取得的部份,尚未物件化。因為每個表格都依賴某種資料格式才能正常顯示,一旦資料取得物件化,對後面的三個動作 FormCheckerProcessor 影響非常大。很多複式資料,應該取得給後面用的格式非常複雜,我沒有把握這些 Fetcher 物件能夠互相引用。然而,只要資料取得的動作還未物件化的一天, Monica/Selima 要處理複雜的複式資料,就會非常困難,而且無法處理兩層以上的複式資料。

    + +

    不過, Fetcher 暫時不是急迫的問題。而且去年 Julie 計劃碰到的瓶頸,我已經找到解答了,不需要用到三層以上的複式資料來處理,而可以利用資料表自己引用自己的方式解決。其實在之前連結分類的處理時,我就已經做過了。去年 PostgreSQL 的權限控管改採 role-based 系統,不再區分使用者和群組,每一個角色都可以包含別的角色。我從來沒想過可以這樣做,茅塞頓開。我想, Julie 的問題,應該可以用同樣的方法來解決。

    + +

    Monica/Selima 還有一個龐大的改造工程: Page 物件,用以追蹤網頁的相依性、製作瀏覽選單及網站地圖。這其實也是去年的構想,因為無障礙網頁規範要求網站要有網站地圖,目前 Monica 使用 page_tree() 函式回傳一個龐大的樹狀網頁資料,可是沒有方法,難以作更複雜的應用。我目前只有初步的想法而已。可能會先在 Selima 上實作吧,畢竟 Selima 還沒有正式的內容管理系統,包袱比較小。希望不需要用到一年。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 20 | + 21 | + 22 | + 23 | + 24 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0023.html.en.html b/htdocs/imacat/me/diary/0023.html.en.html new file mode 120000 index 0000000..3f08033 --- /dev/null +++ b/htdocs/imacat/me/diary/0023.html.en.html @@ -0,0 +1 @@ +0023.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0023.html.en.xhtml b/htdocs/imacat/me/diary/0023.html.en.xhtml new file mode 100644 index 0000000..a9e9747 --- /dev/null +++ b/htdocs/imacat/me/diary/0023.html.en.xhtml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 23 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 23

    + +
    + +
    + +
    +
    4.23.’06. 9:21pm.
    + +

    終於把自己的中文詩,存進資料庫了。

    + +

    中文詩,一直是整個旅舍依瑪中,我最不願意去面對的部份。裏面有太多的不堪,夾雜糾結的感動、自負、自卑。我其實沒有資格被叫做詩人。我從來也沒有出過一本詩集,只是在最脆弱的時候,靈魂沒有出口,只能靠寫字來發洩、自我治療;有時候覺得自己太久沒寫東西,舔稱為詩人,於是就開始憑空瞎掰、亂寫。這樣亂七八糟的我,竟然也會被人稱為網路詩人。每每在網路上看到人家給我這樣的稱號,就很汗顏、害怕。

    + +

    把自己的網站資料庫化的過程中,不免又要碰及這一部份的自我。然而,奇怪地,這一次回頭看,心情卻出奇地平靜。只覺得眼前是一堆平凡的文字而已,既不好,也不壞。說是詩有點過譽,不過所謂到處稱詩人的名人,寫的東西也不怎麼樣,所以稱我這些文字為詩,也不至於過譽。

    + +

    為什麼會這麼平靜呢?我也不清楚。

    + +

    從最後一篇到現在,事隔五年了。這五年來,我有什麼成長? MonicaSelima ,兩個完全自己寫出來的龐大網站管理系統,五個自由軟體專案。上網晃晃,偶爾會有人叫住我:鼎鼎大名的依瑪貓,久仰久仰。我除了答:過譽過譽外,也不知道要答什麼。我也不知道我到底做了什麼大事,大名在哪裏。 Selima 寫了這麼多年才稍微有個樣子,想做的椰子拉子也沒做出來,想加入的 TLDP 計劃也無聲無息, X.509 憑證教學英譯了那麼多年也譯不出來,刊登要找兼差到現在也沒有什麼適合的,還到研考會的網站上去和人家吵架。用一事無成來形容,其實所去不遠。

    + +

    回頭看看五年前的自己,似乎可以好好看待那個不好也不壞的自己了。沒有了糾結的感動、自負、自卑、羞愧的情感交雜。連感動也消失無蹤了。反正就是這樣。嗯。

    + +

    唔,好吧,說實話,其實是覺得還不錯啦,呵呵。 ^_*'

    + +
    + +
    + +
    +
    4.14.’06. 11:03pm.
    + +

    關於活期儲蓄存款

    + +

    有一個問題我一直很疑惑:活期儲蓄存款既然和活期存款一樣,有完全的流動性,可以直接轉為通貨,那為什麼活期存款列入 M1A (狹義貨幣)的計算,活期儲蓄存款不列入?

    + +

    剛剛看了中国人民大学财政金融学院蔡如海的一篇关于我国货币层次划分的几点看法,才恍然大悟。

    + +

    活期存款和活期儲蓄存款的差別在哪裏?主要差別有三:

    + +
      +
    1. 活期儲蓄存款的利息,比活期存款高,幾近短期定存的水準。
    2. +
    3. 活期儲蓄存款大多有存款餘額上限(依銀行不同),約為一百萬左右,活期存款沒有上限。
    4. +
    5. 活期儲蓄存款限自然人(個人)或非營利組織開戶,活期存款不限,營利法人也可以開戶。
    6. +
    + +

    簡單來說,活期儲蓄存款的目的是鼓勵個人儲蓄,因此利息較高,也因此限制開戶的資格和存款上限。

    + +

    那活期儲蓄存款為什麼不像活期存款一樣,列入 M1A 呢?難道是因為其目的是在儲蓄,所以不是用在流通嗎?可是那只是設立目的,要拿來流通也並無不可,而且同樣沒有成本啊(雖然有機會成本:損失的高利息)?

    + +

    拜讀了蔡如海的文章後,我才恍然大悟:因為活期存款常用於公司法人間的直接交易,公司和公司間經常直接以活期存款支付交易款項(轉帳匯款),而活期儲蓄存款大多是個人使用,個人很少用存款來直接交易,而是領出現金後再交易。最近的網路拍賣匯款交易和轉帳卡算是例外,不過比例上還是偏低。存款戶大多為個人的活期儲蓄存款主要功能為價值儲藏,雖有交易支付的功能,但交易支付功能使用率低。所以在計算市面上流通用以交易支付的貨幣上, M1A 去掉活期儲蓄存款,以求得實際上用以交易的貨幣總數,是有道理的。

    + +

    從貨幣學的角度來看,實際上是否用於直接交易支付,才是活期存款和活期儲蓄存款,最關鍵的差別。

    + +

    不過若要計算可用以交易的貨幣總數,只考慮其支付交易和流通能力,不考慮實際上的低使用率,那就可以加上活期儲蓄存款,成為 M1B

    + +

    同理,郵匯儲金連轉帳匯款支付的功能都沒有,雖有完全的流動性,可完全變現,但沒有直接交易能力,所以不列入 M1B ,不算狹義貨幣,歸類於準貨幣而列於 M2 中。

    + +
    + +
    + +
    +
    4.14.’06. 6:12pm.
    + +

    自由真好。中國網路封鎖得非常嚴密,而且近來變本加厲。最近發現幾個重要網站如自由軟體的網站 SourceForge.net 、 FreeBSD.org 、網路程式語言的網站 PHP.net 及自由百科全書 Wikipedia.org 都被封鎖掉了。 Wikipedia 是因為標榜中立,必需要中立的陳述爭議各方的意見,裏面自然包含對台灣有利的意見,而被封鎖了。 SourceForge.net 則是因為上面有人建置破解封鎖的軟體,而遭到封鎖。封鎖 SourceForge.net ,只會讓中國在全世界自由軟體的發展上缺席。 PHP 是現在最熱門的網站程式語言, PHP 的網站被封鎖無法下載,對中國的網路軟體業發展只有壞處,沒有好處。

    + +

    我的網站(旅舍以及其它網站)偶有從中國來的朋友,詢問如何連絡某人、某團體。我給對方網址後,對方也連不上去。我想應該是封鎖住了。對這種事,身為外國人,我愛莫能助。

    + +

    我好像看到天草之亂後到明治維新前,畏懼外國人的不良影響,實行鎖國政策的德川幕府。鎖國的結果,對於一個國家的長期發展,只有壞處沒有好處。就如 Wikipedia 所說的,封鎖 Wikipedia ,只會讓 Wikipedia 上爭議辭條的解釋,對台灣傾斜。鎖國只會讓自己在世界上缺席。這對長期處在中國競爭陰影下的台灣而言,是一個機會。 ^_*'

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 21 | + 22 | + 23 | + 24 | + 25 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0023.html.zh-cn.html b/htdocs/imacat/me/diary/0023.html.zh-cn.html new file mode 120000 index 0000000..545f987 --- /dev/null +++ b/htdocs/imacat/me/diary/0023.html.zh-cn.html @@ -0,0 +1 @@ +0023.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0023.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0023.html.zh-cn.xhtml new file mode 100644 index 0000000..9942d52 --- /dev/null +++ b/htdocs/imacat/me/diary/0023.html.zh-cn.xhtml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷二十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷二十三

    + +
    + +
    + +
    +
    4.23.’06. 9:21pm.
    + +

    终於把自己的中文诗,存进资料库了。

    + +

    中文诗,一直是整个旅舍依玛中,我最不愿意去面对的部份。里面有太多的不堪,夹杂纠结的感动、自负、自卑。我其实没有资格被叫做诗人。我从来也没有出过一本诗集,只是在最脆弱的时候,灵魂没有出口,只能靠写字来发泄、自我治疗;有时候觉得自己太久没写东西,舔称为诗人,於是就开始凭空瞎掰、乱写。这样乱七八糟的我,竟然也会被人称为网路诗人。每每在网路上看到人家给我这样的称号,就很汗颜、害怕。

    + +

    把自己的网站资料库化的过程中,不免又要碰及这一部份的自我。然而,奇怪地,这一次回头看,心情却出奇地平静。只觉得眼前是一堆平凡的文字而已,既不好,也不坏。说是诗有点过誉,不过所谓到处称诗人的名人,写的东西也不怎么样,所以称我这些文字为诗,也不至於过誉。

    + +

    为什么会这么平静呢?我也不清楚。

    + +

    从最后一篇到现在,事隔五年了。这五年来,我有什么成长? MonicaSelima ,两个完全自己写出来的庞大网站管理系统,五个自由软体专案。上网晃晃,偶尔会有人叫住我:鼎鼎大名的依玛猫,久仰久仰。我除了答:过誉过誉外,也不知道要答什么。我也不知道我到底做了什么大事,大名在哪里。 Selima 写了这么多年才稍微有个样子,想做的椰子拉子也没做出来,想加入的 TLDP 计划也无声无息, X.509 凭证教学英译了那么多年也译不出来,刊登要找兼差到现在也没有什么适合的,还到研考会的网站上去和人家吵架。用一事无成来形容,其实所去不远。

    + +

    回头看看五年前的自己,似乎可以好好看待那个不好也不坏的自己了。没有了纠结的感动、自负、自卑、羞愧的情感交杂。连感动也消失无踪了。反正就是这样。嗯。

    + +

    唔,好吧,说实话,其实是觉得还不错啦,呵呵。 ^_*'

    + +
    + +
    + +
    +
    4.14.’06. 11:03pm.
    + +

    关於活期储蓄存款

    + +

    有一个问题我一直很疑惑:活期储蓄存款既然和活期存款一样,有完全的流动性,可以直接转为通货,那为什么活期存款列入 M1A (狭义货币)的计算,活期储蓄存款不列入?

    + +

    刚刚看了中国人民大学财政金融学院蔡如海的一篇关于我国货币层次划分的几点看法,才恍然大悟。

    + +

    活期存款和活期储蓄存款的差别在哪里?主要差别有三:

    + +
      +
    1. 活期储蓄存款的利息,比活期存款高,几近短期定存的水准。
    2. +
    3. 活期储蓄存款大多有存款余额上限(依银行不同),约为一百万左右,活期存款没有上限。
    4. +
    5. 活期储蓄存款限自然人(个人)或非营利组织开户,活期存款不限,营利法人也可以开户。
    6. +
    + +

    简单来说,活期储蓄存款的目的是鼓励个人储蓄,因此利息较高,也因此限制开户的资格和存款上限。

    + +

    那活期储蓄存款为什么不像活期存款一样,列入 M1A 呢?难道是因为其目的是在储蓄,所以不是用在流通吗?可是那只是设立目的,要拿来流通也并无不可,而且同样没有成本啊(虽然有机会成本:损失的高利息)?

    + +

    拜读了蔡如海的文章后,我才恍然大悟:因为活期存款常用於公司法人间的直接交易,公司和公司间经常直接以活期存款支付交易款项(转帐汇款),而活期储蓄存款大多是个人使用,个人很少用存款来直接交易,而是领出现金后再交易。最近的网路拍卖汇款交易和转帐卡算是例外,不过比例上还是偏低。存款户大多为个人的活期储蓄存款主要功能为价值储藏,虽有交易支付的功能,但交易支付功能使用率低。所以在计算市面上流通用以交易支付的货币上, M1A 去掉活期储蓄存款,以求得实际上用以交易的货币总数,是有道理的。

    + +

    从货币学的角度来看,实际上是否用於直接交易支付,才是活期存款和活期储蓄存款,最关键的差别。

    + +

    不过若要计算可用以交易的货币总数,只考虑其支付交易和流通能力,不考虑实际上的低使用率,那就可以加上活期储蓄存款,成为 M1B

    + +

    同理,邮汇储金连转帐汇款支付的功能都没有,虽有完全的流动性,可完全变现,但没有直接交易能力,所以不列入 M1B ,不算狭义货币,归类於准货币而列於 M2 中。

    + +
    + +
    + +
    +
    4.14.’06. 6:12pm.
    + +

    自由真好。中国网路封锁得非常严密,而且近来变本加厉。最近发现几个重要网站如自由软体的网站 SourceForge.net 、 FreeBSD.org 、网路程式语言的网站 PHP.net 及自由百科全书 Wikipedia.org 都被封锁掉了。 Wikipedia 是因为标榜中立,必需要中立的陈述争议各方的意见,里面自然包含对台湾有利的意见,而被封锁了。 SourceForge.net 则是因为上面有人建置破解封锁的软体,而遭到封锁。封锁 SourceForge.net ,只会让中国在全世界自由软体的发展上缺席。 PHP 是现在最热门的网站程式语言, PHP 的网站被封锁无法下载,对中国的网路软体业发展只有坏处,没有好处。

    + +

    我的网站(旅舍以及其它网站)偶有从中国来的朋友,询问如何连络某人、某团体。我给对方网址后,对方也连不上去。我想应该是封锁住了。对这种事,身为外国人,我爱莫能助。

    + +

    我好像看到天草之乱后到明治维新前,畏惧外国人的不良影响,实行锁国政策的德川幕府。锁国的结果,对於一个国家的长期发展,只有坏处没有好处。就如 Wikipedia 所说的,封锁 Wikipedia ,只会让 Wikipedia 上争议辞条的解释,对台湾倾斜。锁国只会让自己在世界上缺席。这对长期处在中国竞争阴影下的台湾而言,是一个机会。 ^_*'

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 21 | + 22 | + 23 | + 24 | + 25 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0023.html.zh-tw.html b/htdocs/imacat/me/diary/0023.html.zh-tw.html new file mode 120000 index 0000000..f3a7248 --- /dev/null +++ b/htdocs/imacat/me/diary/0023.html.zh-tw.html @@ -0,0 +1 @@ +0023.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0023.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0023.html.zh-tw.xhtml new file mode 100644 index 0000000..f2bf3d8 --- /dev/null +++ b/htdocs/imacat/me/diary/0023.html.zh-tw.xhtml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷二十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷二十三

    + +
    + +
    + +
    +
    4.23.’06. 9:21pm.
    + +

    終於把自己的中文詩,存進資料庫了。

    + +

    中文詩,一直是整個旅舍依瑪中,我最不願意去面對的部份。裏面有太多的不堪,夾雜糾結的感動、自負、自卑。我其實沒有資格被叫做詩人。我從來也沒有出過一本詩集,只是在最脆弱的時候,靈魂沒有出口,只能靠寫字來發洩、自我治療;有時候覺得自己太久沒寫東西,舔稱為詩人,於是就開始憑空瞎掰、亂寫。這樣亂七八糟的我,竟然也會被人稱為網路詩人。每每在網路上看到人家給我這樣的稱號,就很汗顏、害怕。

    + +

    把自己的網站資料庫化的過程中,不免又要碰及這一部份的自我。然而,奇怪地,這一次回頭看,心情卻出奇地平靜。只覺得眼前是一堆平凡的文字而已,既不好,也不壞。說是詩有點過譽,不過所謂到處稱詩人的名人,寫的東西也不怎麼樣,所以稱我這些文字為詩,也不至於過譽。

    + +

    為什麼會這麼平靜呢?我也不清楚。

    + +

    從最後一篇到現在,事隔五年了。這五年來,我有什麼成長? MonicaSelima ,兩個完全自己寫出來的龐大網站管理系統,五個自由軟體專案。上網晃晃,偶爾會有人叫住我:鼎鼎大名的依瑪貓,久仰久仰。我除了答:過譽過譽外,也不知道要答什麼。我也不知道我到底做了什麼大事,大名在哪裏。 Selima 寫了這麼多年才稍微有個樣子,想做的椰子拉子也沒做出來,想加入的 TLDP 計劃也無聲無息, X.509 憑證教學英譯了那麼多年也譯不出來,刊登要找兼差到現在也沒有什麼適合的,還到研考會的網站上去和人家吵架。用一事無成來形容,其實所去不遠。

    + +

    回頭看看五年前的自己,似乎可以好好看待那個不好也不壞的自己了。沒有了糾結的感動、自負、自卑、羞愧的情感交雜。連感動也消失無蹤了。反正就是這樣。嗯。

    + +

    唔,好吧,說實話,其實是覺得還不錯啦,呵呵。 ^_*'

    + +
    + +
    + +
    +
    4.14.’06. 11:03pm.
    + +

    關於活期儲蓄存款

    + +

    有一個問題我一直很疑惑:活期儲蓄存款既然和活期存款一樣,有完全的流動性,可以直接轉為通貨,那為什麼活期存款列入 M1A (狹義貨幣)的計算,活期儲蓄存款不列入?

    + +

    剛剛看了中国人民大学财政金融学院蔡如海的一篇关于我国货币层次划分的几点看法,才恍然大悟。

    + +

    活期存款和活期儲蓄存款的差別在哪裏?主要差別有三:

    + +
      +
    1. 活期儲蓄存款的利息,比活期存款高,幾近短期定存的水準。
    2. +
    3. 活期儲蓄存款大多有存款餘額上限(依銀行不同),約為一百萬左右,活期存款沒有上限。
    4. +
    5. 活期儲蓄存款限自然人(個人)或非營利組織開戶,活期存款不限,營利法人也可以開戶。
    6. +
    + +

    簡單來說,活期儲蓄存款的目的是鼓勵個人儲蓄,因此利息較高,也因此限制開戶的資格和存款上限。

    + +

    那活期儲蓄存款為什麼不像活期存款一樣,列入 M1A 呢?難道是因為其目的是在儲蓄,所以不是用在流通嗎?可是那只是設立目的,要拿來流通也並無不可,而且同樣沒有成本啊(雖然有機會成本:損失的高利息)?

    + +

    拜讀了蔡如海的文章後,我才恍然大悟:因為活期存款常用於公司法人間的直接交易,公司和公司間經常直接以活期存款支付交易款項(轉帳匯款),而活期儲蓄存款大多是個人使用,個人很少用存款來直接交易,而是領出現金後再交易。最近的網路拍賣匯款交易和轉帳卡算是例外,不過比例上還是偏低。存款戶大多為個人的活期儲蓄存款主要功能為價值儲藏,雖有交易支付的功能,但交易支付功能使用率低。所以在計算市面上流通用以交易支付的貨幣上, M1A 去掉活期儲蓄存款,以求得實際上用以交易的貨幣總數,是有道理的。

    + +

    從貨幣學的角度來看,實際上是否用於直接交易支付,才是活期存款和活期儲蓄存款,最關鍵的差別。

    + +

    不過若要計算可用以交易的貨幣總數,只考慮其支付交易和流通能力,不考慮實際上的低使用率,那就可以加上活期儲蓄存款,成為 M1B

    + +

    同理,郵匯儲金連轉帳匯款支付的功能都沒有,雖有完全的流動性,可完全變現,但沒有直接交易能力,所以不列入 M1B ,不算狹義貨幣,歸類於準貨幣而列於 M2 中。

    + +
    + +
    + +
    +
    4.14.’06. 6:12pm.
    + +

    自由真好。中國網路封鎖得非常嚴密,而且近來變本加厲。最近發現幾個重要網站如自由軟體的網站 SourceForge.net 、 FreeBSD.org 、網路程式語言的網站 PHP.net 及自由百科全書 Wikipedia.org 都被封鎖掉了。 Wikipedia 是因為標榜中立,必需要中立的陳述爭議各方的意見,裏面自然包含對台灣有利的意見,而被封鎖了。 SourceForge.net 則是因為上面有人建置破解封鎖的軟體,而遭到封鎖。封鎖 SourceForge.net ,只會讓中國在全世界自由軟體的發展上缺席。 PHP 是現在最熱門的網站程式語言, PHP 的網站被封鎖無法下載,對中國的網路軟體業發展只有壞處,沒有好處。

    + +

    我的網站(旅舍以及其它網站)偶有從中國來的朋友,詢問如何連絡某人、某團體。我給對方網址後,對方也連不上去。我想應該是封鎖住了。對這種事,身為外國人,我愛莫能助。

    + +

    我好像看到天草之亂後到明治維新前,畏懼外國人的不良影響,實行鎖國政策的德川幕府。鎖國的結果,對於一個國家的長期發展,只有壞處沒有好處。就如 Wikipedia 所說的,封鎖 Wikipedia ,只會讓 Wikipedia 上爭議辭條的解釋,對台灣傾斜。鎖國只會讓自己在世界上缺席。這對長期處在中國競爭陰影下的台灣而言,是一個機會。 ^_*'

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 21 | + 22 | + 23 | + 24 | + 25 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0024.html.en.html b/htdocs/imacat/me/diary/0024.html.en.html new file mode 120000 index 0000000..7464338 --- /dev/null +++ b/htdocs/imacat/me/diary/0024.html.en.html @@ -0,0 +1 @@ +0024.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0024.html.en.xhtml b/htdocs/imacat/me/diary/0024.html.en.xhtml new file mode 100644 index 0000000..1343ca6 --- /dev/null +++ b/htdocs/imacat/me/diary/0024.html.en.xhtml @@ -0,0 +1,296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 24 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 24

    + +
    + +
    + +
    +
    5.14.’06. 2:50am.
    + +

    好不容易新的伺服器上線了,可是 ADSL Modem 壞掉了。 ^^; 而且公司撥接也停掉了,完全連不出去。

    + +

    這篇日記現在大概不會有人看到吧。雖然記日記也不是給別人看的。

    + +

    好多問題都沒辦法查,好麻煩。

    + +
    + +
    + +
    +
    5.13.’06. 10:55pm.
    + +

    旅舍 64 位元新伺服器測試。

    + +

    一,二,三…咳咳。

    + +
    + +
    + +
    +
    5.10.’06. 3:00am.
    + +

    剛才終於親眼見到了,做夢都會夢到的雙核心、雙 CPU 的威力…

    + +
    +
      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    +19281 imacat    25   0  185m 168m 4160 R 95.0 16.8   0:02.85 cc1plus
    +19265 root      16   0 53084  23m 2476 R 71.0  2.4   0:02.99 spamd
    +19279 imacat    17   0 20856 1424 1040 S  0.3  0.1   0:00.01 sh
    +    1 root      16   0  2652  536  456 S  0.0  0.1   0:00.79 init
    +
    + +

    95% + 71% … 同一時間 CPU 工作量總和超過 100% !好~酷~ *^___^*

    + +
    + +
    + +
    +
    5.8.’06. 4:54am.
    + +

    全 64 位元的系統,果然是很大的挑戰。

    + +
    + +
    + +
    +
    5.7.’06. 4:24pm.
    + +

    現金如滾滾長江東去不復返…

    + +

    怎麼會花錢花得這麼快呢?我想想…星期五晚上去內湖修伺服器,看到好久沒看到的元氣迴轉壽司,測記憶體的時候進去晃了一圈,四百四就這樣沒去了。記憶中吃了一個很新鮮的鮮蝦壽司。星期六晚上不知道吃什麼,想起永和永福橋下有一家從沒去過的鐵板燒餐廳,好像是中價位的,就跑進去。結果忍不住草蝦鮮魚的誘惑,點了一個沙朗牛排主廚特餐,三百八就去了。今天凌晨無端突然鼻子痛,痛到睡不著,跑去掛急診,七百塊錢就去了。

    + +

    嗯嗯。美食好像是我很大的罩門。不過怎麼都吃不胖呢?傷腦筋。

    + +
    + +
    + +
    +
    5.6.’06. 7:10pm.
    + +

    星期三一領到錢,就去光華商場買了新的伺服器,花掉了兩萬零六百九十塊錢: Intel Pentium D 3.2GHz Dual Core 雙核心,記憶體 Kingston DDR533 1024MB ,硬碟 Maxtor SATA2 250MB 。回來測了兩晚:第一個晚上用 badblocks 測硬碟,第二個晚上用 memtest86+ 測記憶體,燒了兩天沒有問題了,到星期六晚上,才真的開始安裝。

    + +

    這大概是一般市面組裝 Intel 電腦,拿得到最頂級的配備了。 SATA2 的速度真的好可怕!以往用 badblocks -svw 燒一顆 80GB 的硬碟,在 IDE/ATA 下,大概要兩天半,現在三倍的容量 250GB , SATA2 只花了十個小時。 DDR533 也很可怕, 1GB SD-RAM 跑 memtest86+ ,跑一輪要兩個半小時,現在一天可以跑一百八十輪,跑一輪不到十分鐘。

    + +

    不過最可怕的應該還是這顆64 位元的雙核心 CPU 。現在剛剛開始安裝。之前完全沒有 64 位元環境的經驗,不知道會怎麼樣。會比較快嗎?軟體都可以編譯嗎?都是未知數。雙核心也頗讓人期待。之前碰過 HyperThreading 超線程的 Pentium 4 Xeon ,那是模擬雙 CPU 。不過至少也有過多 CPU 的經驗了。現在這顆 Pentium D 除了共用匯流排外,裏面是真的雙 CPU 了。不知道效能會變得如何?期待中。呵呵~ ^_*'

    + +

    邊期待,下午 rinse 就又垮了一次。唉~不過前兩天系統負荷降下來了,心裏揪得緊緊的。好怕在這個手頭還很緊的時候,把大筆現金花在不是很急需的事情上。不過 rinse 又垮了一次,雖然伺服器垮了覺得很嘔,那至少證明了,買這台新的伺服器,是迫切急需的事,我不是在浪費現金。嗯嗯。

    + +

    新的伺服器,我暫時取名叫 yuki ,雪。我好喜歡這個名字,呵呵。

    + +

    乾脆我日本名字取叫 yuki 好了。 ^_*'

    + +
    + +
    + +
    +
    4.29.’06. 4:43pm.
    + +
    +有些事情,當事情發生的那幾年,我們以為它對我們的生命很重要
    +等到五年、十年以後再回過頭來看
    +才會發現,其實那件事的重要性,並沒有我們想像的那麼大
    +其實生命還有其它的力量在轉動
    +只是那幾年間,我們看不到那些力量,變得盲目了 +
    + +
    + +
    + +
    +
    4.28.’06. 9:52pm.
    + +

    我要認真考慮 rinse 昇級的事了。

    + +
    +
    load average: 56.86, 38.19, 25.54
    +
    + +

    這個負載數字也…太誇張了吧… ^^;

    + +

    很想哭。我好不容易有一點存款的。 :~~

    + +
    + +
    + +
    +
    4.27.’06. 12:42pm.
    + +

    前兩天,要整理英文寫作,又把那篇 The Drunk 長文從頭再看了一遍。看完了以後,深深地吁了一口氣。覺得自己好厲害,竟然可以用英文,寫得出那種浪漫主義風格的中篇小說。雖然說杜斯妥也夫斯基的風格陰影很重,可是可以這樣鋪陳故事情節,還是覺得自己很了不起。

    + +

    因為如此,裏面很多英文語法有問題,有些情節細節有問題的,我就不去改了。這是我十年前寫的作品,還是保留原來的味道吧。 ^_*'

    + +
    + +
    + +
    +
    4.27.’06. 2:33am.
    + +

    旅舍網站終於整個存進資料庫了。可喜可賀~ *^_^* 剛剛把最後一部份—舊旅舍日記—存進了旅舍日記的最前面,簡單解決了舊旅舍日記的問題。旅舍全文檢索以後可以檢索得到整個旅舍囉~ ^_*' 呵呵。

    + +
    + +
    + +
    +
    4.25.’06. 7:58pm.
    + +

    每次聽到 AXN 的節目廣告:今晚九點, Lost 檔案,全新第二季,全台首映!就覺得很好笑。 Lost 檔案只有一台在播吧! :p 廢話當然是全台首映。

    + +

    怎麼,以為 Lost 檔案是和 CSI 犯罪現場一樣搶手的影集嗎?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 22 | + 23 | + 24 | + 25 | + 26 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0024.html.zh-cn.html b/htdocs/imacat/me/diary/0024.html.zh-cn.html new file mode 120000 index 0000000..86fd32a --- /dev/null +++ b/htdocs/imacat/me/diary/0024.html.zh-cn.html @@ -0,0 +1 @@ +0024.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0024.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0024.html.zh-cn.xhtml new file mode 100644 index 0000000..4d71f21 --- /dev/null +++ b/htdocs/imacat/me/diary/0024.html.zh-cn.xhtml @@ -0,0 +1,295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷二十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷二十四

    + +
    + +
    + +
    +
    5.14.’06. 2:50am.
    + +

    好不容易新的伺服器上线了,可是 ADSL Modem 坏掉了。 ^^; 而且公司拨接也停掉了,完全连不出去。

    + +

    这篇日记现在大概不会有人看到吧。虽然记日记也不是给别人看的。

    + +

    好多问题都没办法查,好麻烦。

    + +
    + +
    + +
    +
    5.13.’06. 10:55pm.
    + +

    旅舍 64 位元新伺服器测试。

    + +

    一,二,三…咳咳。

    + +
    + +
    + +
    +
    5.10.’06. 3:00am.
    + +

    刚才终於亲眼见到了,做梦都会梦到的双核心、双 CPU 的威力…

    + +
    +
      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    +19281 imacat    25   0  185m 168m 4160 R 95.0 16.8   0:02.85 cc1plus
    +19265 root      16   0 53084  23m 2476 R 71.0  2.4   0:02.99 spamd
    +19279 imacat    17   0 20856 1424 1040 S  0.3  0.1   0:00.01 sh
    +    1 root      16   0  2652  536  456 S  0.0  0.1   0:00.79 init
    +
    + +

    95% + 71% … 同一时间 CPU 工作量总和超过 100% !好~酷~ *^___^*

    + +
    + +
    + +
    +
    5.8.’06. 4:54am.
    + +

    全 64 位元的系统,果然是很大的挑战。

    + +
    + +
    + +
    +
    5.7.’06. 4:24pm.
    + +

    现金如滚滚长江东去不复返…

    + +

    怎么会花钱花得这么快呢?我想想…星期五晚上去内湖修伺服器,看到好久没看到的元气回转寿司,测记忆体的时候进去晃了一圈,四百四就这样没去了。记忆中吃了一个很新鲜的鲜虾寿司。星期六晚上不知道吃什么,想起永和永福桥下有一家从没去过的铁板烧餐厅,好像是中价位的,就跑进去。结果忍不住草虾鲜鱼的诱惑,点了一个沙朗牛排主厨特餐,三百八就去了。今天凌晨无端突然鼻子痛,痛到睡不著,跑去挂急诊,七百块钱就去了。

    + +

    嗯嗯。美食好像是我很大的罩门。不过怎么都吃不胖呢?伤脑筋。

    + +
    + +
    + +
    +
    5.6.’06. 7:10pm.
    + +

    星期三一领到钱,就去光华商场买了新的伺服器,花掉了两万零六百九十块钱: Intel Pentium D 3.2GHz Dual Core 双核心,记忆体 Kingston DDR533 1024MB ,硬碟 Maxtor SATA2 250MB 。回来测了两晚:第一个晚上用 badblocks 测硬碟,第二个晚上用 memtest86+ 测记忆体,烧了两天没有问题了,到星期六晚上,才真的开始安装。

    + +

    这大概是一般市面组装 Intel 电脑,拿得到最顶级的配备了。 SATA2 的速度真的好可怕!以往用 badblocks -svw 烧一颗 80GB 的硬碟,在 IDE/ATA 下,大概要两天半,现在三倍的容量 250GB , SATA2 只花了十个小时。 DDR533 也很可怕, 1GB SD-RAM 跑 memtest86+ ,跑一轮要两个半小时,现在一天可以跑一百八十轮,跑一轮不到十分钟。

    + +

    不过最可怕的应该还是这颗64 位元的双核心 CPU 。现在刚刚开始安装。之前完全没有 64 位元环境的经验,不知道会怎么样。会比较快吗?软体都可以编译吗?都是未知数。双核心也颇让人期待。之前碰过 HyperThreading 超线程的 Pentium 4 Xeon ,那是模拟双 CPU 。不过至少也有过多 CPU 的经验了。现在这颗 Pentium D 除了共用汇流排外,里面是真的双 CPU 了。不知道效能会变得如何?期待中。呵呵~ ^_*'

    + +

    边期待,下午 rinse 就又垮了一次。唉~不过前两天系统负荷降下来了,心里揪得紧紧的。好怕在这个手头还很紧的时候,把大笔现金花在不是很急需的事情上。不过 rinse 又垮了一次,虽然伺服器垮了觉得很呕,那至少证明了,买这台新的伺服器,是迫切急需的事,我不是在浪费现金。嗯嗯。

    + +

    新的伺服器,我暂时取名叫 yuki ,雪。我好喜欢这个名字,呵呵。

    + +

    干脆我日本名字取叫 yuki 好了。 ^_*'

    + +
    + +
    + +
    +
    4.29.’06. 4:43pm.
    + +
    +有些事情,当事情发生的那几年,我们以为它对我们的生命很重要
    +等到五年、十年以后再回过头来看
    +才会发现,其实那件事的重要性,并没有我们想像的那么大
    +其实生命还有其它的力量在转动
    +只是那几年间,我们看不到那些力量,变得盲目了 +
    + +
    + +
    + +
    +
    4.28.’06. 9:52pm.
    + +

    我要认真考虑 rinse 升级的事了。

    + +
    +
    load average: 56.86, 38.19, 25.54
    +
    + +

    这个负载数字也…太夸张了吧… ^^;

    + +

    很想哭。我好不容易有一点存款的。 :~~

    + +
    + +
    + +
    +
    4.27.’06. 12:42pm.
    + +

    前两天,要整理英文写作,又把那篇 The Drunk 长文从头再看了一遍。看完了以后,深深地吁了一口气。觉得自己好厉害,竟然可以用英文,写得出那种浪漫主义风格的中篇小说。虽然说杜斯妥也夫斯基的风格阴影很重,可是可以这样铺陈故事情节,还是觉得自己很了不起。

    + +

    因为如此,里面很多英文语法有问题,有些情节细节有问题的,我就不去改了。这是我十年前写的作品,还是保留原来的味道吧。 ^_*'

    + +
    + +
    + +
    +
    4.27.’06. 2:33am.
    + +

    旅舍网站终於整个存进资料库了。可喜可贺~ *^_^* 刚刚把最后一部份—旧旅舍日记—存进了旅舍日记的最前面,简单解决了旧旅舍日记的问题。旅舍全文检索以后可以检索得到整个旅舍罗~ ^_*' 呵呵。

    + +
    + +
    + +
    +
    4.25.’06. 7:58pm.
    + +

    每次听到 AXN 的节目广告:今晚九点, Lost 档案,全新第二季,全台首映!就觉得很好笑。 Lost 档案只有一台在播吧! :p 废话当然是全台首映。

    + +

    怎么,以为 Lost 档案是和 CSI 犯罪现场一样抢手的影集吗?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 22 | + 23 | + 24 | + 25 | + 26 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0024.html.zh-tw.html b/htdocs/imacat/me/diary/0024.html.zh-tw.html new file mode 120000 index 0000000..feca964 --- /dev/null +++ b/htdocs/imacat/me/diary/0024.html.zh-tw.html @@ -0,0 +1 @@ +0024.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0024.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0024.html.zh-tw.xhtml new file mode 100644 index 0000000..170f441 --- /dev/null +++ b/htdocs/imacat/me/diary/0024.html.zh-tw.xhtml @@ -0,0 +1,295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷二十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷二十四

    + +
    + +
    + +
    +
    5.14.’06. 2:50am.
    + +

    好不容易新的伺服器上線了,可是 ADSL Modem 壞掉了。 ^^; 而且公司撥接也停掉了,完全連不出去。

    + +

    這篇日記現在大概不會有人看到吧。雖然記日記也不是給別人看的。

    + +

    好多問題都沒辦法查,好麻煩。

    + +
    + +
    + +
    +
    5.13.’06. 10:55pm.
    + +

    旅舍 64 位元新伺服器測試。

    + +

    一,二,三…咳咳。

    + +
    + +
    + +
    +
    5.10.’06. 3:00am.
    + +

    剛才終於親眼見到了,做夢都會夢到的雙核心、雙 CPU 的威力…

    + +
    +
      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    +19281 imacat    25   0  185m 168m 4160 R 95.0 16.8   0:02.85 cc1plus
    +19265 root      16   0 53084  23m 2476 R 71.0  2.4   0:02.99 spamd
    +19279 imacat    17   0 20856 1424 1040 S  0.3  0.1   0:00.01 sh
    +    1 root      16   0  2652  536  456 S  0.0  0.1   0:00.79 init
    +
    + +

    95% + 71% … 同一時間 CPU 工作量總和超過 100% !好~酷~ *^___^*

    + +
    + +
    + +
    +
    5.8.’06. 4:54am.
    + +

    全 64 位元的系統,果然是很大的挑戰。

    + +
    + +
    + +
    +
    5.7.’06. 4:24pm.
    + +

    現金如滾滾長江東去不復返…

    + +

    怎麼會花錢花得這麼快呢?我想想…星期五晚上去內湖修伺服器,看到好久沒看到的元氣迴轉壽司,測記憶體的時候進去晃了一圈,四百四就這樣沒去了。記憶中吃了一個很新鮮的鮮蝦壽司。星期六晚上不知道吃什麼,想起永和永福橋下有一家從沒去過的鐵板燒餐廳,好像是中價位的,就跑進去。結果忍不住草蝦鮮魚的誘惑,點了一個沙朗牛排主廚特餐,三百八就去了。今天凌晨無端突然鼻子痛,痛到睡不著,跑去掛急診,七百塊錢就去了。

    + +

    嗯嗯。美食好像是我很大的罩門。不過怎麼都吃不胖呢?傷腦筋。

    + +
    + +
    + +
    +
    5.6.’06. 7:10pm.
    + +

    星期三一領到錢,就去光華商場買了新的伺服器,花掉了兩萬零六百九十塊錢: Intel Pentium D 3.2GHz Dual Core 雙核心,記憶體 Kingston DDR533 1024MB ,硬碟 Maxtor SATA2 250MB 。回來測了兩晚:第一個晚上用 badblocks 測硬碟,第二個晚上用 memtest86+ 測記憶體,燒了兩天沒有問題了,到星期六晚上,才真的開始安裝。

    + +

    這大概是一般市面組裝 Intel 電腦,拿得到最頂級的配備了。 SATA2 的速度真的好可怕!以往用 badblocks -svw 燒一顆 80GB 的硬碟,在 IDE/ATA 下,大概要兩天半,現在三倍的容量 250GB , SATA2 只花了十個小時。 DDR533 也很可怕, 1GB SD-RAM 跑 memtest86+ ,跑一輪要兩個半小時,現在一天可以跑一百八十輪,跑一輪不到十分鐘。

    + +

    不過最可怕的應該還是這顆64 位元的雙核心 CPU 。現在剛剛開始安裝。之前完全沒有 64 位元環境的經驗,不知道會怎麼樣。會比較快嗎?軟體都可以編譯嗎?都是未知數。雙核心也頗讓人期待。之前碰過 HyperThreading 超線程的 Pentium 4 Xeon ,那是模擬雙 CPU 。不過至少也有過多 CPU 的經驗了。現在這顆 Pentium D 除了共用匯流排外,裏面是真的雙 CPU 了。不知道效能會變得如何?期待中。呵呵~ ^_*'

    + +

    邊期待,下午 rinse 就又垮了一次。唉~不過前兩天系統負荷降下來了,心裏揪得緊緊的。好怕在這個手頭還很緊的時候,把大筆現金花在不是很急需的事情上。不過 rinse 又垮了一次,雖然伺服器垮了覺得很嘔,那至少證明了,買這台新的伺服器,是迫切急需的事,我不是在浪費現金。嗯嗯。

    + +

    新的伺服器,我暫時取名叫 yuki ,雪。我好喜歡這個名字,呵呵。

    + +

    乾脆我日本名字取叫 yuki 好了。 ^_*'

    + +
    + +
    + +
    +
    4.29.’06. 4:43pm.
    + +
    +有些事情,當事情發生的那幾年,我們以為它對我們的生命很重要
    +等到五年、十年以後再回過頭來看
    +才會發現,其實那件事的重要性,並沒有我們想像的那麼大
    +其實生命還有其它的力量在轉動
    +只是那幾年間,我們看不到那些力量,變得盲目了 +
    + +
    + +
    + +
    +
    4.28.’06. 9:52pm.
    + +

    我要認真考慮 rinse 昇級的事了。

    + +
    +
    load average: 56.86, 38.19, 25.54
    +
    + +

    這個負載數字也…太誇張了吧… ^^;

    + +

    很想哭。我好不容易有一點存款的。 :~~

    + +
    + +
    + +
    +
    4.27.’06. 12:42pm.
    + +

    前兩天,要整理英文寫作,又把那篇 The Drunk 長文從頭再看了一遍。看完了以後,深深地吁了一口氣。覺得自己好厲害,竟然可以用英文,寫得出那種浪漫主義風格的中篇小說。雖然說杜斯妥也夫斯基的風格陰影很重,可是可以這樣鋪陳故事情節,還是覺得自己很了不起。

    + +

    因為如此,裏面很多英文語法有問題,有些情節細節有問題的,我就不去改了。這是我十年前寫的作品,還是保留原來的味道吧。 ^_*'

    + +
    + +
    + +
    +
    4.27.’06. 2:33am.
    + +

    旅舍網站終於整個存進資料庫了。可喜可賀~ *^_^* 剛剛把最後一部份—舊旅舍日記—存進了旅舍日記的最前面,簡單解決了舊旅舍日記的問題。旅舍全文檢索以後可以檢索得到整個旅舍囉~ ^_*' 呵呵。

    + +
    + +
    + +
    +
    4.25.’06. 7:58pm.
    + +

    每次聽到 AXN 的節目廣告:今晚九點, Lost 檔案,全新第二季,全台首映!就覺得很好笑。 Lost 檔案只有一台在播吧! :p 廢話當然是全台首映。

    + +

    怎麼,以為 Lost 檔案是和 CSI 犯罪現場一樣搶手的影集嗎?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 22 | + 23 | + 24 | + 25 | + 26 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0025.html.en.html b/htdocs/imacat/me/diary/0025.html.en.html new file mode 120000 index 0000000..b5e337d --- /dev/null +++ b/htdocs/imacat/me/diary/0025.html.en.html @@ -0,0 +1 @@ +0025.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0025.html.en.xhtml b/htdocs/imacat/me/diary/0025.html.en.xhtml new file mode 100644 index 0000000..207d4bc --- /dev/null +++ b/htdocs/imacat/me/diary/0025.html.en.xhtml @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 25 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 25

    + +
    + +
    + +
    +
    6.4.’06. 3:33pm.
    + +

    A little more on the previous spam thing.

    + +

    I review my spam box quickly every day, in case there is any good mail mistaken. I often found several self-advertising mails from several major spammers, like cigi, green world, on their e-mail marketing business. They amused me: Even your own spam can't get into my inbox! Why do you think there is anyone willing to commission you on this? But, its funny, that there are still so many people commissioning them on e-mail marketing every day.

    + +

    It seems that many people like to throw their money into the trash can. They like to listen to these attractive stories from these e-mail marketor, throwing lots of money on this worthless and coorporate-image-hurting marketing thing.

    + +
    + +
    + +
    +
    6.3.’06. 4:58am.
    + +

    I found an interesting thing when I was reviewing my spam a couple of days ago.

    + +

    With the most popular anti-spam technology nowadays Bayesian Analysis, we can filtered 98.5% of the spams. That means about 15 are getting into our inbox for every 1000 spams. For an ordinary person that receives 300 spams, about 5 will get into the inbox, with the rest go to the spam box. It is very annoying to see 5 spam in the inbox every morning, though.

    + +

    But, that’s the point of view from us that are spammed. From the point of view from those that are spamming, the hit rate is only 1.5%. And, in the 1.5% that get into the inbox, about 99% are deleted at once. Only 1.5% × 1% = 0.015% of the spam may get read. From marketing perspective, a hit rate of 0.015%, that is, 150 in 1,000,000 marketing targets, is low enough! And how many in these 150 will really go to buy the product? We never know. But the side effect of the coorporate image lose as a spammer is uncountable!

    + +

    This kind of low hit rate, low efficiency, bad side effect marketing tool, from the marketing point of view, is worthless. And to think that so many companies are involved in such a worthless marketing tool everyday! That’s beyond imagination.

    + +
    + +
    + +
    +
    5.31.’06. 12:58pm.
    + +

    The new chklinks version is finally done. *^_^*

    + +
    + +
    + +
    +
    5.27.’06. 9:56pm.
    + +

    花了一個星期的時間,研究 MRTGSNMP ,如何用它來監控各種重要的系統指標:網路流量、系統負載、 CPU 耗用率、記憶體耗用率、郵件收發、網路速度等等,建立各種早期監控圖表,以便對各種潛在的問題早期預警,早期防範。

    + +

    我不想再發生之前的悲劇了。伺服器負載跑到 54 ,我竟然毫不知情,直到系統整個連續掛了好幾次,開都開不了機才知道!作為一個網管,真是太不合格了。深以為恥。

    + +

    看樣子 rinse 還有一個潛在的問題:記憶體不大夠用。嗯。最近有錢的話,要加記憶體。

    + +
    + +
    + +
    +
    5.17.’06. 8:30am.
    + +

    這兩天收到台灣網路資訊中心 TWNIC 的網域名稱帳單,準備去繳費。仔細看一看帳單上的繳費方式,心中有氣。

    + +

    現在繳費方式有三種:一種是轉帳匯款,一種是線上信用卡繳費,一種是超商繳費。不考慮超商繳費,單看前兩種:

    + +
      +
    1. 轉帳匯款,支付的是現款。我手頭現金要馬上支付出去,比較不划算;對方馬上收現,資金成本較低,比較有利。然而不管是臨櫃轉帳、匯款,還是提款機轉帳,我都要額外支付一筆轉帳手續費。
    2. + +
    3. 信用卡繳費,支付的是信用額度,月底結帳請款才付現款。我延遲付款,不用付出手頭的現金,資金成本較低;對方要到月底才能請款,資金成本較高,而且還有拒付倒帳的風險。可是反而不用扣任何抽傭、手續費。
    4. +
    + +

    這不是很荒謬嗎?付現無利息,延遲付款還要加計利息才對。為什麼現況反而相反?信用卡繳款,收付銀行要跟商家收取 2% 比例抽傭,禁止轉嫁到消費者身上;轉匯付款手續費是定額,反而要消費者自行負擔。這到底是什麼道理?

    + +

    我在決定要付現還是刷卡時,著實想了很久很久。

    + +
    + +
    + +
    +
    5.17.’06. 6:37am.
    + +

    刪掉了好多篇過去的垃圾留言和廣告留言。嗯。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 23 | + 24 | + 25 | + 26 | + 27 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0025.html.zh-cn.html b/htdocs/imacat/me/diary/0025.html.zh-cn.html new file mode 120000 index 0000000..82ecbcc --- /dev/null +++ b/htdocs/imacat/me/diary/0025.html.zh-cn.html @@ -0,0 +1 @@ +0025.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0025.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0025.html.zh-cn.xhtml new file mode 100644 index 0000000..b94198f --- /dev/null +++ b/htdocs/imacat/me/diary/0025.html.zh-cn.xhtml @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷二十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷二十五

    + +
    + +
    + +
    +
    6.4.’06. 3:33pm.
    + +

    补充一下前面关於垃圾信的事。

    + +

    我每天都会快速浏览垃圾信夹,检查是否有误判。我会开始想这个问题,是因为我在浏览时,常常看到几家台湾知名的垃圾广告信商,像是骐骥、绿界等等,自我宣传邮件行销业务的广告信。我觉得好气又好笑:连你们自家的信都会被过滤掉了,为什么别人还会来委托你们发呢?耐人寻味的是,找他们发信的人,好像还是每日络绎不绝。

    + +

    好像有很多人都喜欢把钱丢到垃圾筒里,听信邮件行销商五花乱坠的宣传,花大钱找这种没有价值,还有损企业形象的行销方式。

    + +
    + +
    + +
    +
    6.3.’06. 4:58am.
    + +

    前几天重审垃圾广告信的时候,突然注意到一个耐人寻味的问题。

    + +

    依现行最常见的挡广告信技术贝氏分析法来说,垃圾广告信判别率可以达到 98.5% 。也就是说,发 1000 封垃圾广告信,有 15 封会进来我们的收件夹。一般人每天收 300 封垃圾广告信,大约有 5 封左右会掉进收件夹,其它都掉进垃圾信夹中。每天起床在收件夹中看到 5 封垃圾广告信,还是很多很烦。

    + +

    可是,这是从我们收垃圾信的人的角度而言,很多很烦。就发垃圾信的人的角度,曝光率只有 5% 。而这 1.5% 进入收件夹的信里面,大概 99% ,看都不看就直接删掉,或是看了一眼就直接删掉。真正会看的,只有 1.5% × 1% = 0.015% 。从行销的角度来看, 0.015% 的曝光率,对一百万人行销,只命中 150 人,效率低得离谱。这 150 个看广告信的人中,有几个会真正去购买?没有人知道。可是因为看到广告信,对这家企业感到厌恶,而使企业形象蒙受的损失,是难以估计的。

    + +

    从行销的角度来说,这种超低曝光率,超低行销效率,又会让企业形象蒙受严重损害的行销方式,一点价值都没有。而这种超级没有效率的行销方式,竟然每天还是这么多人在做,真是非常不可思议的事。

    + +
    + +
    + +
    +
    5.31.’06. 12:58pm.
    + +

    chklinks 新版终於写好了。可喜可贺。 *^_^*

    + +
    + +
    + +
    +
    5.27.’06. 9:56pm.
    + +

    花了一个星期的时间,研究 MRTGSNMP ,如何用它来监控各种重要的系统指标:网路流量、系统负载、 CPU 耗用率、记忆体耗用率、邮件收发、网路速度等等,建立各种早期监控图表,以便对各种潜在的问题早期预警,早期防范。

    + +

    我不想再发生之前的悲剧了。伺服器负载跑到 54 ,我竟然毫不知情,直到系统整个连续挂了好几次,开都开不了机才知道!作为一个网管,真是太不合格了。深以为耻。

    + +

    看样子 rinse 还有一个潜在的问题:记忆体不大够用。嗯。最近有钱的话,要加记忆体。

    + +
    + +
    + +
    +
    5.17.’06. 8:30am.
    + +

    这两天收到台湾网路资讯中心 TWNIC 的网域名称帐单,准备去缴费。仔细看一看帐单上的缴费方式,心中有气。

    + +

    现在缴费方式有三种:一种是转帐汇款,一种是线上信用卡缴费,一种是超商缴费。不考虑超商缴费,单看前两种:

    + +
      +
    1. 转帐汇款,支付的是现款。我手头现金要马上支付出去,比较不划算;对方马上收现,资金成本较低,比较有利。然而不管是临柜转帐、汇款,还是提款机转帐,我都要额外支付一笔转帐手续费。
    2. + +
    3. 信用卡缴费,支付的是信用额度,月底结帐请款才付现款。我延迟付款,不用付出手头的现金,资金成本较低;对方要到月底才能请款,资金成本较高,而且还有拒付倒帐的风险。可是反而不用扣任何抽佣、手续费。
    4. +
    + +

    这不是很荒谬吗?付现无利息,延迟付款还要加计利息才对。为什么现况反而相反?信用卡缴款,收付银行要跟商家收取 2% 比例抽佣,禁止转嫁到消费者身上;转汇付款手续费是定额,反而要消费者自行负担。这到底是什么道理?

    + +

    我在决定要付现还是刷卡时,著实想了很久很久。

    + +
    + +
    + +
    +
    5.17.’06. 6:37am.
    + +

    删掉了好多篇过去的垃圾留言和广告留言。嗯。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 23 | + 24 | + 25 | + 26 | + 27 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0025.html.zh-tw.html b/htdocs/imacat/me/diary/0025.html.zh-tw.html new file mode 120000 index 0000000..49f999b --- /dev/null +++ b/htdocs/imacat/me/diary/0025.html.zh-tw.html @@ -0,0 +1 @@ +0025.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0025.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0025.html.zh-tw.xhtml new file mode 100644 index 0000000..23d80ee --- /dev/null +++ b/htdocs/imacat/me/diary/0025.html.zh-tw.xhtml @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷二十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷二十五

    + +
    + +
    + +
    +
    6.4.’06. 3:33pm.
    + +

    補充一下前面關於垃圾信的事。

    + +

    我每天都會快速瀏覽垃圾信夾,檢查是否有誤判。我會開始想這個問題,是因為我在瀏覽時,常常看到幾家台灣知名的垃圾廣告信商,像是騏驥、綠界等等,自我宣傳郵件行銷業務的廣告信。我覺得好氣又好笑:連妳們自家的信都會被過濾掉了,為什麼別人還會來委託妳們發呢?耐人尋味的是,找他們發信的人,好像還是每日絡繹不絕。

    + +

    好像有很多人都喜歡把錢丟到垃圾筒裏,聽信郵件行銷商五花亂墜的宣傳,花大錢找這種沒有價值,還有損企業形象的行銷方式。

    + +
    + +
    + +
    +
    6.3.’06. 4:58am.
    + +

    前幾天重審垃圾廣告信的時候,突然注意到一個耐人尋味的問題。

    + +

    依現行最常見的擋廣告信技術貝氏分析法來說,垃圾廣告信判別率可以達到 98.5% 。也就是說,發 1000 封垃圾廣告信,有 15 封會進來我們的收件夾。一般人每天收 300 封垃圾廣告信,大約有 5 封左右會掉進收件夾,其它都掉進垃圾信夾中。每天起床在收件夾中看到 5 封垃圾廣告信,還是很多很煩。

    + +

    可是,這是從我們收垃圾信的人的角度而言,很多很煩。就發垃圾信的人的角度,曝光率只有 5% 。而這 1.5% 進入收件夾的信裏面,大概 99% ,看都不看就直接刪掉,或是看了一眼就直接刪掉。真正會看的,只有 1.5% × 1% = 0.015% 。從行銷的角度來看, 0.015% 的曝光率,對一百萬人行銷,只命中 150 人,效率低得離譜。這 150 個看廣告信的人中,有幾個會真正去購買?沒有人知道。可是因為看到廣告信,對這家企業感到厭惡,而使企業形象蒙受的損失,是難以估計的。

    + +

    從行銷的角度來說,這種超低曝光率,超低行銷效率,又會讓企業形象蒙受嚴重損害的行銷方式,一點價值都沒有。而這種超級沒有效率的行銷方式,竟然每天還是這麼多人在做,真是非常不可思議的事。

    + +
    + +
    + +
    +
    5.31.’06. 12:58pm.
    + +

    chklinks 新版終於寫好了。可喜可賀。 *^_^*

    + +
    + +
    + +
    +
    5.27.’06. 9:56pm.
    + +

    花了一個星期的時間,研究 MRTGSNMP ,如何用它來監控各種重要的系統指標:網路流量、系統負載、 CPU 耗用率、記憶體耗用率、郵件收發、網路速度等等,建立各種早期監控圖表,以便對各種潛在的問題早期預警,早期防範。

    + +

    我不想再發生之前的悲劇了。伺服器負載跑到 54 ,我竟然毫不知情,直到系統整個連續掛了好幾次,開都開不了機才知道!作為一個網管,真是太不合格了。深以為恥。

    + +

    看樣子 rinse 還有一個潛在的問題:記憶體不大夠用。嗯。最近有錢的話,要加記憶體。

    + +
    + +
    + +
    +
    5.17.’06. 8:30am.
    + +

    這兩天收到台灣網路資訊中心 TWNIC 的網域名稱帳單,準備去繳費。仔細看一看帳單上的繳費方式,心中有氣。

    + +

    現在繳費方式有三種:一種是轉帳匯款,一種是線上信用卡繳費,一種是超商繳費。不考慮超商繳費,單看前兩種:

    + +
      +
    1. 轉帳匯款,支付的是現款。我手頭現金要馬上支付出去,比較不划算;對方馬上收現,資金成本較低,比較有利。然而不管是臨櫃轉帳、匯款,還是提款機轉帳,我都要額外支付一筆轉帳手續費。
    2. + +
    3. 信用卡繳費,支付的是信用額度,月底結帳請款才付現款。我延遲付款,不用付出手頭的現金,資金成本較低;對方要到月底才能請款,資金成本較高,而且還有拒付倒帳的風險。可是反而不用扣任何抽傭、手續費。
    4. +
    + +

    這不是很荒謬嗎?付現無利息,延遲付款還要加計利息才對。為什麼現況反而相反?信用卡繳款,收付銀行要跟商家收取 2% 比例抽傭,禁止轉嫁到消費者身上;轉匯付款手續費是定額,反而要消費者自行負擔。這到底是什麼道理?

    + +

    我在決定要付現還是刷卡時,著實想了很久很久。

    + +
    + +
    + +
    +
    5.17.’06. 6:37am.
    + +

    刪掉了好多篇過去的垃圾留言和廣告留言。嗯。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 23 | + 24 | + 25 | + 26 | + 27 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0026.html.en.html b/htdocs/imacat/me/diary/0026.html.en.html new file mode 120000 index 0000000..6baebf6 --- /dev/null +++ b/htdocs/imacat/me/diary/0026.html.en.html @@ -0,0 +1 @@ +0026.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0026.html.en.xhtml b/htdocs/imacat/me/diary/0026.html.en.xhtml new file mode 100644 index 0000000..9b7316b --- /dev/null +++ b/htdocs/imacat/me/diary/0026.html.en.xhtml @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 26 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 26

    + +
    + +
    + +
    +
    6.10.’06. 2:54am.
    + +

    新‧世說新語

    + +

    伊索寓言中,有一段父子騎驢的故事。

    + +
    +

    從前有個父親袋子兒子要去市場賣驢子,驢子走在前頭,父子兩隨行在後,村裡的小姐看了都覺得很可笑。真傻啊!騎著驢子去多好,卻在這沙塵滾滾的路上漫步。

    + +

    對啊!說的對啊!父親突然覺得很有道理。孩子,騎上驢子吧!我會跟在旁邊,不會讓你掉下來的!父親讓孩子騎在驢子上,自己則跟在旁邊走著。

    + +

    這時,對面走來二個父親的朋友。

    + +

    喂!喂!讓孩子騎驢,自己卻徒步,算什麼!現在就這麼寵孩子將來還得了!為了孩子的健康,應該叫他走路才對,讓他走路,讓他走路!

    + +

    噢!對呀!是有道理。於是父親讓孩子下來,自己則騎上驢背。孩子跟在驢子前面,蹣跚的走著。走著走著,碰見一個擠牛奶的女孩。女孩用責備的口吻說:哎唷!世間竟有這麼殘酷的父親,自己輕輕鬆鬆的騎在驢背上,卻讓那麼小的孩子走路,真可憐。瞧,那孩子多痛苦,東倒西歪的跟在後頭,實在可憐啊!

    + +

    是啊!你說的有理!父親點頭贊同。於是,父親叫孩子也騎到驢背上,朝著市場的方向前進。驢子同時要載兩個人,漸漸的舉步非常吃力,呼吸急促,角搖搖晃晃的發抖。可是父親並沒有發覺,還輕輕鬆鬆的哼著歌曲,一邊在驢背上搖晃呢!

    + +

    驢子好不容易的走到教堂前,喘了一大口氣,休息、休息。教堂前面正站了一位牧師,叫住了他們。喂!喂!請等一下,讓那麼弱小的動物在兩個人,驢子太可憐了。你們要去那裡呢?

    + +

    我們正要帶這匹驢子去市場賣呀!

    + +

    哦!這更有問題。我看你們還沒走進市場,驢子就先累死了,恐怕還賣不出去呢!信不信由你。

    + +

    那麼,該怎麼辦呢?

    + +

    把驢子扛著去吧!

    + +

    好!有道理。

    + +

    父子兩立刻從驢背上跳下來,然後把驢子的角綁起來,再用棍子扛著驢子。這樣扛著,當然非常重,所以父子兩脹紅了臉,搖搖晃晃的喊著:怎麼這麼重呢!

    + +

    看見這情景的人都呆住了。真是奇怪的人啊!

    + +

    扛著驢子的父子不久走到一座橋上。孩子,市場快到了,再忍耐一會兒吧!父親雖然這麼說,可是自己和孩子都已經累的精疲力盡了。

    + +

    驢子畢竟是驢子,被倒吊著反而痛苦得不得了,不但口吐白沫,還粗暴的扭動起來。

    + +

    嘿!乖一點啊!父親嚴厲的斥罵著,可是驢子不聽,扭動的更厲害,結果,棍子啪的一聲折斷了。繩子也弄斷了,驢子倒栽蔥似的掉進河裡。很不湊巧,雨後河水暴漲,驢子就在那瞬間,被急流吞沒,看不見蹤影了。

    + +

    啊!怎麼會這樣呢?這都是一位聽別人的意見,而產生最嚴重的後果啊!父子兩只好垂頭喪氣的走回家。

    +
    + +

    放到現代來看:

    + +
      +
    1. 趙建銘上手銬:這是陳水扁授意檢調單位,用以博取同情的技倆!
    2. + +
    3. 趙建銘不上手銬:這是檢調單位的特權禮遇,趙建銘坐牢還享受特權!
    4. +
    + +

    這些電視新聞真是太閒了,閒到沒空去報真正的新聞了。檢察官真是裡外不是人。唉。

    + +
    + +
    + +
    +
    6.6.’06. 1:48pm.
    + +

    辦公室白癡對話錄

    + +

    某日,枯燥的辦公室中…

    + +
    +

    M: …一年有幾季?一季有幾個月?

    +

    I: 啊?嗯…一年有五季,一季有兩個月。

    +

    M: …亂講,少呼弄我好嗎?

    +

    I: 唔…妳問這種問題,我很難不呼弄妳好嗎?喂喂, M 麻煩妳振作點好嗎?

    +

    M: 啊哈哈哈哈…

    +
    + +
    + +
    + +
    +
    6.4.’06. 10:39pm.
    + +

    好幾年沒去爬山了,今天早早出門(早上九點? ^^; ),去爬了睽違已久的七星山。

    + +

    我按著熟悉的路線,從苗圃登山口進去,往七星山主峰、東峰出發,預計到了峰頂後,由小油坑或冷水坑下山。天氣陰陰的,原本以為像昨天一樣,陰陰的又不會下雨,是爬山的好天氣。沒想到到了山腰,就開始下毛毛雨了,我只好把雨傘撐起來。越往上走,雨勢越大。好不容易走到峰頂附近。我盤算著先走東峰,再回主峰,由小油坑下山好了。

    + +

    沒想到到了東峰峰頂,峰頂沒人,而且連一點遮避物都沒有,山頂風大雨大,我撐著爬到峰頂的大石坐下,全身縮在雨傘下面喘息。新拆封的折疊傘一下子就被吹壞了,傘骨斷的斷折的折。我從來沒遇過這種情況,不知道該怎麼辦才好。心裏想著應該早點下山才對,可是山頂上風大雨大又光禿禿的,雙腳好痠,身體不聽使喚。一收起雨傘,撲面而來的大雨,打得滿臉生痛。眼睛睜不開,視線也模糊不清。

    + +

    好不容易鼓起勇氣,收起雨傘。也不敢從主峰或冷水坑下山了,摸著石頭壓低身形,由依稀可認的原路回去。才一下峰頂,一陣狂風吹來,把眼鏡給吹飛了。我嚇壞了。沒有眼鏡,我視線模糊,沒有辦法找眼鏡。沒想到來爬個山,竟然賠上一付眼鏡!還好掉在身後的芒草堆中,沒被吹跑,趕緊把它檢回來。不過這一來我眼鏡也不敢戴了。把傘和眼鏡收進提袋裏,憑著近視度數不深,一步一步摸著山石下山。反正,遠一點的山路,風雨加上濃霧,就算戴上眼鏡也看不清楚。

    + +

    心裏覺得有點嘔。原路上山原路下山,這種事我從來沒有做過。好像鍛羽而歸的感覺。我以前一直覺得,就是要從山的這一頭上去,那一頭下去,才叫走完一趟。不過原路下山其實不見得比較輕鬆,因為苗圃到峰頂這一段,長 2.1 公里,比起小油坑或冷水坑下山的路,都長得多。不過我車停在苗圃,要是從小油坑或冷水坑下山,還要一路走回苗圃,也是一段不短的路,而我剛剛嚇壞了,只想早點回家。更何況,短的路線比較陡,加上天雨路滑,其實蠻危險的。

    + +

    一路上,碰到上山的朋友,都不忘了提醒一句:山頂現在風雨很大,有點危險。我很喜歡登山的一個原因,就是像這樣:平常都市裏,陌生人根本不會打招呼,大家都低頭猛走,好冷漠。可是登山的時候,山友都很親切,雖然彼此都不認識,一個點頭一個微笑,一句早安,一句加油,甚至走在一起就互相聊了起來,感覺真的很熱絡、很快樂。

    + +

    聽到我的提醒,大多數人都跟我點頭說謝謝。有幾個人停下來跟我打探路況,我也不厭其煩的多描繪幾句。反正腳走得痛死了,我也不介意走走停停喘口氣。下山的路,比較不費力,可是比較危險,而且腳要支撐全身的重量,階梯一頓一頓的,走久了會很痛。不過最神奇的,是一個人的回答:

    + +
    +

    山頂現在風雨很大,有點危險喔。

    +

    我知道,我剛剛從山頂下來,現在是回程。

    +
    + +

    啊?那,那種山頂,那種風雨,他剛剛從山頂下來,回程還要上去一趟?我突然有種我好遜的感覺,很恨剛剛為什麼沒有死命撐著,從主峰上去,從小油坑走下來。

    + +

    算了,現在說這些,也來不及了。下了山,才發現山下也下大雨了。雙腳又酸又痛,一心只想回家休息。冒著雨騎了好一段路,才回到家。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 24 | + 25 | + 26 | + 27 | + 28 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0026.html.zh-cn.html b/htdocs/imacat/me/diary/0026.html.zh-cn.html new file mode 120000 index 0000000..eef2196 --- /dev/null +++ b/htdocs/imacat/me/diary/0026.html.zh-cn.html @@ -0,0 +1 @@ +0026.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0026.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0026.html.zh-cn.xhtml new file mode 100644 index 0000000..8786b49 --- /dev/null +++ b/htdocs/imacat/me/diary/0026.html.zh-cn.xhtml @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷二十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷二十六

    + +
    + +
    + +
    +
    6.10.’06. 2:54am.
    + +

    新・世说新语

    + +

    伊索寓言中,有一段父子骑驴的故事。

    + +
    +

    从前有个父亲袋子儿子要去市场卖驴子,驴子走在前头,父子两随行在后,村里的小姐看了都觉得很可笑。真傻啊!骑著驴子去多好,却在这沙尘滚滚的路上漫步。

    + +

    对啊!说的对啊!父亲突然觉得很有道理。孩子,骑上驴子吧!我会跟在旁边,不会让你掉下来的!父亲让孩子骑在驴子上,自己则跟在旁边走著。

    + +

    这时,对面走来二个父亲的朋友。

    + +

    喂!喂!让孩子骑驴,自己却徒步,算什么!现在就这么宠孩子将来还得了!为了孩子的健康,应该叫他走路才对,让他走路,让他走路!

    + +

    噢!对呀!是有道理。於是父亲让孩子下来,自己则骑上驴背。孩子跟在驴子前面,蹒跚的走著。走著走著,碰见一个挤牛奶的女孩。女孩用责备的口吻说:哎唷!世间竟有这么残酷的父亲,自己轻轻松松的骑在驴背上,却让那么小的孩子走路,真可怜。瞧,那孩子多痛苦,东倒西歪的跟在后头,实在可怜啊!

    + +

    是啊!你说的有理!父亲点头赞同。於是,父亲叫孩子也骑到驴背上,朝著市场的方向前进。驴子同时要载两个人,渐渐的举步非常吃力,呼吸急促,角摇摇晃晃的发抖。可是父亲并没有发觉,还轻轻松松的哼著歌曲,一边在驴背上摇晃呢!

    + +

    驴子好不容易的走到教堂前,喘了一大口气,休息、休息。教堂前面正站了一位牧师,叫住了他们。喂!喂!请等一下,让那么弱小的动物在两个人,驴子太可怜了。你们要去那里呢?

    + +

    我们正要带这匹驴子去市场卖呀!

    + +

    哦!这更有问题。我看你们还没走进市场,驴子就先累死了,恐怕还卖不出去呢!信不信由你。

    + +

    那么,该怎么办呢?

    + +

    把驴子扛著去吧!

    + +

    好!有道理。

    + +

    父子两立刻从驴背上跳下来,然后把驴子的角绑起来,再用棍子扛著驴子。这样扛著,当然非常重,所以父子两胀红了脸,摇摇晃晃的喊著:怎么这么重呢!

    + +

    看见这情景的人都呆住了。真是奇怪的人啊!

    + +

    扛著驴子的父子不久走到一座桥上。孩子,市场快到了,再忍耐一会儿吧!父亲虽然这么说,可是自己和孩子都已经累的精疲力尽了。

    + +

    驴子毕竟是驴子,被倒吊著反而痛苦得不得了,不但口吐白沫,还粗暴的扭动起来。

    + +

    嘿!乖一点啊!父亲严厉的斥骂著,可是驴子不听,扭动的更厉害,结果,棍子啪的一声折断了。绳子也弄断了,驴子倒栽葱似的掉进河里。很不凑巧,雨后河水暴涨,驴子就在那瞬间,被急流吞没,看不见踪影了。

    + +

    啊!怎么会这样呢?这都是一位听别人的意见,而产生最严重的后果啊!父子两只好垂头丧气的走回家。

    +
    + +

    放到现代来看:

    + +
      +
    1. 赵建铭上手铐:这是陈水扁授意检调单位,用以博取同情的技俩!
    2. + +
    3. 赵建铭不上手铐:这是检调单位的特权礼遇,赵建铭坐牢还享受特权!
    4. +
    + +

    这些电视新闻真是太闲了,闲到没空去报真正的新闻了。检察官真是里外不是人。唉。

    + +
    + +
    + +
    +
    6.6.’06. 1:48pm.
    + +

    办公室白痴对话录

    + +

    某日,枯燥的办公室中…

    + +
    +

    M: …一年有几季?一季有几个月?

    +

    I: 啊?嗯…一年有五季,一季有两个月。

    +

    M: …乱讲,少呼弄我好吗?

    +

    I: 唔…你问这种问题,我很难不呼弄你好吗?喂喂, M 麻烦你振作点好吗?

    +

    M: 啊哈哈哈哈…

    +
    + +
    + +
    + +
    +
    6.4.’06. 10:39pm.
    + +

    好几年没去爬山了,今天早早出门(早上九点? ^^; ),去爬了睽违已久的七星山。

    + +

    我按著熟悉的路线,从苗圃登山口进去,往七星山主峰、东峰出发,预计到了峰顶后,由小油坑或冷水坑下山。天气阴阴的,原本以为像昨天一样,阴阴的又不会下雨,是爬山的好天气。没想到到了山腰,就开始下毛毛雨了,我只好把雨伞撑起来。越往上走,雨势越大。好不容易走到峰顶附近。我盘算著先走东峰,再回主峰,由小油坑下山好了。

    + +

    没想到到了东峰峰顶,峰顶没人,而且连一点遮避物都没有,山顶风大雨大,我撑著爬到峰顶的大石坐下,全身缩在雨伞下面喘息。新拆封的折叠伞一下子就被吹坏了,伞骨断的断折的折。我从来没遇过这种情况,不知道该怎么办才好。心里想著应该早点下山才对,可是山顶上风大雨大又光秃秃的,双脚好酸,身体不听使唤。一收起雨伞,扑面而来的大雨,打得满脸生痛。眼睛睁不开,视线也模糊不清。

    + +

    好不容易鼓起勇气,收起雨伞。也不敢从主峰或冷水坑下山了,摸著石头压低身形,由依稀可认的原路回去。才一下峰顶,一阵狂风吹来,把眼镜给吹飞了。我吓坏了。没有眼镜,我视线模糊,没有办法找眼镜。没想到来爬个山,竟然赔上一付眼镜!还好掉在身后的芒草堆中,没被吹跑,赶紧把它检回来。不过这一来我眼镜也不敢戴了。把伞和眼镜收进提袋里,凭著近视度数不深,一步一步摸著山石下山。反正,远一点的山路,风雨加上浓雾,就算戴上眼镜也看不清楚。

    + +

    心里觉得有点呕。原路上山原路下山,这种事我从来没有做过。好像锻羽而归的感觉。我以前一直觉得,就是要从山的这一头上去,那一头下去,才叫走完一趟。不过原路下山其实不见得比较轻松,因为苗圃到峰顶这一段,长 2.1 公里,比起小油坑或冷水坑下山的路,都长得多。不过我车停在苗圃,要是从小油坑或冷水坑下山,还要一路走回苗圃,也是一段不短的路,而我刚刚吓坏了,只想早点回家。更何况,短的路线比较陡,加上天雨路滑,其实蛮危险的。

    + +

    一路上,碰到上山的朋友,都不忘了提醒一句:山顶现在风雨很大,有点危险。我很喜欢登山的一个原因,就是像这样:平常都市里,陌生人根本不会打招呼,大家都低头猛走,好冷漠。可是登山的时候,山友都很亲切,虽然彼此都不认识,一个点头一个微笑,一句早安,一句加油,甚至走在一起就互相聊了起来,感觉真的很热络、很快乐。

    + +

    听到我的提醒,大多数人都跟我点头说谢谢。有几个人停下来跟我打探路况,我也不厌其烦的多描绘几句。反正脚走得痛死了,我也不介意走走停停喘口气。下山的路,比较不费力,可是比较危险,而且脚要支撑全身的重量,阶梯一顿一顿的,走久了会很痛。不过最神奇的,是一个人的回答:

    + +
    +

    山顶现在风雨很大,有点危险喔。

    +

    我知道,我刚刚从山顶下来,现在是回程。

    +
    + +

    啊?那,那种山顶,那种风雨,他刚刚从山顶下来,回程还要上去一趟?我突然有种我好逊的感觉,很恨刚刚为什么没有死命撑著,从主峰上去,从小油坑走下来。

    + +

    算了,现在说这些,也来不及了。下了山,才发现山下也下大雨了。双脚又酸又痛,一心只想回家休息。冒著雨骑了好一段路,才回到家。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 24 | + 25 | + 26 | + 27 | + 28 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0026.html.zh-tw.html b/htdocs/imacat/me/diary/0026.html.zh-tw.html new file mode 120000 index 0000000..2a94ad4 --- /dev/null +++ b/htdocs/imacat/me/diary/0026.html.zh-tw.html @@ -0,0 +1 @@ +0026.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0026.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0026.html.zh-tw.xhtml new file mode 100644 index 0000000..30914a4 --- /dev/null +++ b/htdocs/imacat/me/diary/0026.html.zh-tw.xhtml @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷二十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷二十六

    + +
    + +
    + +
    +
    6.10.’06. 2:54am.
    + +

    新‧世說新語

    + +

    伊索寓言中,有一段父子騎驢的故事。

    + +
    +

    從前有個父親袋子兒子要去市場賣驢子,驢子走在前頭,父子兩隨行在後,村裡的小姐看了都覺得很可笑。真傻啊!騎著驢子去多好,卻在這沙塵滾滾的路上漫步。

    + +

    對啊!說的對啊!父親突然覺得很有道理。孩子,騎上驢子吧!我會跟在旁邊,不會讓你掉下來的!父親讓孩子騎在驢子上,自己則跟在旁邊走著。

    + +

    這時,對面走來二個父親的朋友。

    + +

    喂!喂!讓孩子騎驢,自己卻徒步,算什麼!現在就這麼寵孩子將來還得了!為了孩子的健康,應該叫他走路才對,讓他走路,讓他走路!

    + +

    噢!對呀!是有道理。於是父親讓孩子下來,自己則騎上驢背。孩子跟在驢子前面,蹣跚的走著。走著走著,碰見一個擠牛奶的女孩。女孩用責備的口吻說:哎唷!世間竟有這麼殘酷的父親,自己輕輕鬆鬆的騎在驢背上,卻讓那麼小的孩子走路,真可憐。瞧,那孩子多痛苦,東倒西歪的跟在後頭,實在可憐啊!

    + +

    是啊!你說的有理!父親點頭贊同。於是,父親叫孩子也騎到驢背上,朝著市場的方向前進。驢子同時要載兩個人,漸漸的舉步非常吃力,呼吸急促,角搖搖晃晃的發抖。可是父親並沒有發覺,還輕輕鬆鬆的哼著歌曲,一邊在驢背上搖晃呢!

    + +

    驢子好不容易的走到教堂前,喘了一大口氣,休息、休息。教堂前面正站了一位牧師,叫住了他們。喂!喂!請等一下,讓那麼弱小的動物在兩個人,驢子太可憐了。你們要去那裡呢?

    + +

    我們正要帶這匹驢子去市場賣呀!

    + +

    哦!這更有問題。我看你們還沒走進市場,驢子就先累死了,恐怕還賣不出去呢!信不信由你。

    + +

    那麼,該怎麼辦呢?

    + +

    把驢子扛著去吧!

    + +

    好!有道理。

    + +

    父子兩立刻從驢背上跳下來,然後把驢子的角綁起來,再用棍子扛著驢子。這樣扛著,當然非常重,所以父子兩脹紅了臉,搖搖晃晃的喊著:怎麼這麼重呢!

    + +

    看見這情景的人都呆住了。真是奇怪的人啊!

    + +

    扛著驢子的父子不久走到一座橋上。孩子,市場快到了,再忍耐一會兒吧!父親雖然這麼說,可是自己和孩子都已經累的精疲力盡了。

    + +

    驢子畢竟是驢子,被倒吊著反而痛苦得不得了,不但口吐白沫,還粗暴的扭動起來。

    + +

    嘿!乖一點啊!父親嚴厲的斥罵著,可是驢子不聽,扭動的更厲害,結果,棍子啪的一聲折斷了。繩子也弄斷了,驢子倒栽蔥似的掉進河裡。很不湊巧,雨後河水暴漲,驢子就在那瞬間,被急流吞沒,看不見蹤影了。

    + +

    啊!怎麼會這樣呢?這都是一位聽別人的意見,而產生最嚴重的後果啊!父子兩只好垂頭喪氣的走回家。

    +
    + +

    放到現代來看:

    + +
      +
    1. 趙建銘上手銬:這是陳水扁授意檢調單位,用以博取同情的技倆!
    2. + +
    3. 趙建銘不上手銬:這是檢調單位的特權禮遇,趙建銘坐牢還享受特權!
    4. +
    + +

    這些電視新聞真是太閒了,閒到沒空去報真正的新聞了。檢察官真是裡外不是人。唉。

    + +
    + +
    + +
    +
    6.6.’06. 1:48pm.
    + +

    辦公室白癡對話錄

    + +

    某日,枯燥的辦公室中…

    + +
    +

    M: …一年有幾季?一季有幾個月?

    +

    I: 啊?嗯…一年有五季,一季有兩個月。

    +

    M: …亂講,少呼弄我好嗎?

    +

    I: 唔…妳問這種問題,我很難不呼弄妳好嗎?喂喂, M 麻煩妳振作點好嗎?

    +

    M: 啊哈哈哈哈…

    +
    + +
    + +
    + +
    +
    6.4.’06. 10:39pm.
    + +

    好幾年沒去爬山了,今天早早出門(早上九點? ^^; ),去爬了睽違已久的七星山。

    + +

    我按著熟悉的路線,從苗圃登山口進去,往七星山主峰、東峰出發,預計到了峰頂後,由小油坑或冷水坑下山。天氣陰陰的,原本以為像昨天一樣,陰陰的又不會下雨,是爬山的好天氣。沒想到到了山腰,就開始下毛毛雨了,我只好把雨傘撐起來。越往上走,雨勢越大。好不容易走到峰頂附近。我盤算著先走東峰,再回主峰,由小油坑下山好了。

    + +

    沒想到到了東峰峰頂,峰頂沒人,而且連一點遮避物都沒有,山頂風大雨大,我撐著爬到峰頂的大石坐下,全身縮在雨傘下面喘息。新拆封的折疊傘一下子就被吹壞了,傘骨斷的斷折的折。我從來沒遇過這種情況,不知道該怎麼辦才好。心裏想著應該早點下山才對,可是山頂上風大雨大又光禿禿的,雙腳好痠,身體不聽使喚。一收起雨傘,撲面而來的大雨,打得滿臉生痛。眼睛睜不開,視線也模糊不清。

    + +

    好不容易鼓起勇氣,收起雨傘。也不敢從主峰或冷水坑下山了,摸著石頭壓低身形,由依稀可認的原路回去。才一下峰頂,一陣狂風吹來,把眼鏡給吹飛了。我嚇壞了。沒有眼鏡,我視線模糊,沒有辦法找眼鏡。沒想到來爬個山,竟然賠上一付眼鏡!還好掉在身後的芒草堆中,沒被吹跑,趕緊把它檢回來。不過這一來我眼鏡也不敢戴了。把傘和眼鏡收進提袋裏,憑著近視度數不深,一步一步摸著山石下山。反正,遠一點的山路,風雨加上濃霧,就算戴上眼鏡也看不清楚。

    + +

    心裏覺得有點嘔。原路上山原路下山,這種事我從來沒有做過。好像鍛羽而歸的感覺。我以前一直覺得,就是要從山的這一頭上去,那一頭下去,才叫走完一趟。不過原路下山其實不見得比較輕鬆,因為苗圃到峰頂這一段,長 2.1 公里,比起小油坑或冷水坑下山的路,都長得多。不過我車停在苗圃,要是從小油坑或冷水坑下山,還要一路走回苗圃,也是一段不短的路,而我剛剛嚇壞了,只想早點回家。更何況,短的路線比較陡,加上天雨路滑,其實蠻危險的。

    + +

    一路上,碰到上山的朋友,都不忘了提醒一句:山頂現在風雨很大,有點危險。我很喜歡登山的一個原因,就是像這樣:平常都市裏,陌生人根本不會打招呼,大家都低頭猛走,好冷漠。可是登山的時候,山友都很親切,雖然彼此都不認識,一個點頭一個微笑,一句早安,一句加油,甚至走在一起就互相聊了起來,感覺真的很熱絡、很快樂。

    + +

    聽到我的提醒,大多數人都跟我點頭說謝謝。有幾個人停下來跟我打探路況,我也不厭其煩的多描繪幾句。反正腳走得痛死了,我也不介意走走停停喘口氣。下山的路,比較不費力,可是比較危險,而且腳要支撐全身的重量,階梯一頓一頓的,走久了會很痛。不過最神奇的,是一個人的回答:

    + +
    +

    山頂現在風雨很大,有點危險喔。

    +

    我知道,我剛剛從山頂下來,現在是回程。

    +
    + +

    啊?那,那種山頂,那種風雨,他剛剛從山頂下來,回程還要上去一趟?我突然有種我好遜的感覺,很恨剛剛為什麼沒有死命撐著,從主峰上去,從小油坑走下來。

    + +

    算了,現在說這些,也來不及了。下了山,才發現山下也下大雨了。雙腳又酸又痛,一心只想回家休息。冒著雨騎了好一段路,才回到家。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 24 | + 25 | + 26 | + 27 | + 28 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0027.html.en.html b/htdocs/imacat/me/diary/0027.html.en.html new file mode 120000 index 0000000..d45cb88 --- /dev/null +++ b/htdocs/imacat/me/diary/0027.html.en.html @@ -0,0 +1 @@ +0027.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0027.html.en.xhtml b/htdocs/imacat/me/diary/0027.html.en.xhtml new file mode 100644 index 0000000..646e23e --- /dev/null +++ b/htdocs/imacat/me/diary/0027.html.en.xhtml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 27 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 27

    + +
    + +
    + +
    +
    6.30.’06. 6:23pm.
    + +

    超線程的威力

    + +

    這是一台兩年前買的伺服器。其實那時候買的超線程,就可以做到 CPU 到 200% 了,一顆 CPU 當兩顆來用。真的很酷。 ^_*'

    + +
    +  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    +31802 imacat    25   0  8928 7788  360 R 99.3  0.8   0:37.22 bzip2
    +31793 imacat    25   0  9184 4848 1832 R 98.7  0.5   0:49.62 find_idic_email
    +
    + +
    + +
    + +
    +
    6.27.’06. 3:12am.
    + +

    色彩學

    + +

    那天坐捷運,車上邊晃邊讀著車上廣告,看到香港設計學院來台招生的廣告,課程項目,看到一個項目色彩學。剎那間,這個不甚醒目的詞彙,塞滿了我整個頭腦:我,我想學色彩學!

    + +

    我是一個網站工程師,大學是唸數學的。其實我以前很會畫圖。我小時候很會畫畫,曾經想要當過畫家,也參加過繪畫班,得過國小的繪畫獎。我對美術的興趣,一直到了高中,因為一件事,而中斷了。

    + +

    忘了是高中哪一年。那時我跟班上一個好朋友,我自認為我們兩個是畫得最好的。那一次美術課,老師要我們畫學校的景物。我選了一棟新蓋的大樓。我畫得很仔細,不斷比對幾何比例,甚至拿鐵尺去量,畫出了我覺得最完美的作品。可是完成以後,我怎麼看,都覺得不滿意,總覺得少了點什麼。直到看到我那個朋友的畫。她選的是一快小林地,其實很稀梳,沒幾棵樹,可是她的樹畫得很密,感覺很豐富很溫暖。她畫的樹,不論間距、幾何比例都不對。可是,我第一眼就告訴我,她畫得好,我畫得不好。

    + +

    那一瞬間,我明白了一件事:我沒有美術的才能。一個好畫家,畫筆要畫的,是心中看到的景象,而不是實際的景物。她畫出了心中的溫暖,而我畫不出來。我只有理性科學工藝的才能,沒有藝術表達的才能。我畫的是建築結構圖,不是美術繪畫。

    + +

    那以後,我就放棄了繪畫,專心唸數學。這麼多年來,我棄絕畫筆,專心投入數學、電腦科技。認識我的朋友都知道,我是一個網路程式高手,但我絕不碰網頁美術設計。旅舍依瑪,我挑了幾個暖色系的顏色作底,就放上來了。我白紙黑字昭告天下,旅舍依瑪後面有個超強大、穩定的 Selima 網站內容管理系統,可是沒有好看的網站。如果覺得很醜礙眼,請自便。

    + +

    幾年前,我進了現在這家公司。那時有一個跟我同時進去的美術設計。那時候為了設計公司的新網站,他把公司網站用的色表標準印下來,貼在牆上。看到那個色表,我覺得很新奇。那是我從來不懂的陌生世界。驚豔、讚嘆。但除了這些以外,我卻無法再說些什麼。是我自己要放棄這條路的,這是我自己的選擇。每個人都要按著自己要走的路努力向前,過程必然會有所取捨,可是生命只有一次,沒有太多時間可以讓自己左顧右盼。

    + +

    直到前幾天,在捷運上,我看到了香港設計學院來台招生的廣告,課程規劃中,有一個項目色彩學。突然間,我心裏有一股幾乎無法壓抑的衝動,告訴我,我想學色彩學。我不想改行走服裝設計,也不想改行走商業廣告設計,不想走廣告動畫。但至少,我想學色彩學。我想要知道每個顏色的故事,我想要知道不同顏色的不同心情。我想要在我想給人溫暖感覺的時候,挑出給人溫暖感覺的顏色;想給人明亮耀眼的感覺的時候,挑出給人明亮耀眼的顏色;想給人自由自在的感覺的時候,挑出給人自由自在感覺的顏色。我想知道熱情的顏色,想知道妒火的顏色,想知道寂寞的顏色,想知道幸福的顏色。我希望能有有一天,我能夠用顏色,帶給周圍的人幸福。

    + +

    不過現在色彩學,單修半年專業的課程,大概要一兩萬吧。嗯嗯。不是太大的數目。加油,努力存錢中。 *^_^*

    + +
    + +
    + +
    +
    6.20.’06. 10:09pm.
    + +

    今天中午,因為幫朋友回學校買一包茶葉,走進了許久未進門的大陸社。

    + +

    平日的中午,沒想到竟然坐滿了學弟妹。人好多,好感動。大概是要準備期末考了吧。詳細問了學弟妹們社團的近況、學校的近況、最近讀什麼書、辦什麼活動等等。

    + +

    沒想到他們說起唸的東西,我不只都聽得懂,而且還知道這些東西的程度很初級!說起來雖然我比他們多了十四屆,空大也不過第三年,也跟他們一樣算是大學生。而且以前聽到同樣的東西,我都一知半解,霧裏看花。沒想到現在,竟然能夠居高下望。看來,我也已經有所成長了。這到底是什麼原因呢?

    + +
      +
    • 是年歲較長,心境較成熟了嗎?
    • +
    • 是我多年前唸的東西,終於消化了嗎?
    • +
    • 是這兩年空大修課廣泛涉獵,所以視野和變深變廣了嗎?
    • +
    • 是我還算蠻聰明的嗎?
    • +
    + +

    嗯嗯。居高下望的感覺,自己格局變大了的感覺,有點小高興呢。 *^_^*

    + +
    + +
    + +
    +
    6.13.’06. 8:51pm.
    + +

    公司有一件工作,延宕了一個星期,一直沒時間處理好。今天不知為何,處理事情超有效率,總算把它完成了。

    + +

    處理好了已經傍晚了。回頭一看才嚇然發現,今天一整天都沒有收信。難怪完全沒有雜事分心,做起事來超順心。看一看收件匣,發現一整天下來,積了四件要處理的事。可是看看也要下班了。我趕緊把最緊急的事先處理好,另外幾件應該今天要處理的事記下來,記好明天優先處理,才匆匆下班。

    + +

    覺得 E-mail 真是可怕的東西。收了信,往往一整天就耗上去了,下班時回想,什麼事都沒做。忘了收信,反而能夠專心做事,把事情做好。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 25 | + 26 | + 27 | + 28 | + 29 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0027.html.zh-cn.html b/htdocs/imacat/me/diary/0027.html.zh-cn.html new file mode 120000 index 0000000..9edaf8d --- /dev/null +++ b/htdocs/imacat/me/diary/0027.html.zh-cn.html @@ -0,0 +1 @@ +0027.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0027.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0027.html.zh-cn.xhtml new file mode 100644 index 0000000..2472587 --- /dev/null +++ b/htdocs/imacat/me/diary/0027.html.zh-cn.xhtml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷二十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷二十七

    + +
    + +
    + +
    +
    6.30.’06. 6:23pm.
    + +

    超线程的威力

    + +

    这是一台两年前买的伺服器。其实那时候买的超线程,就可以做到 CPU 到 200% 了,一颗 CPU 当两颗来用。真的很酷。 ^_*'

    + +
    +  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    +31802 imacat    25   0  8928 7788  360 R 99.3  0.8   0:37.22 bzip2
    +31793 imacat    25   0  9184 4848 1832 R 98.7  0.5   0:49.62 find_idic_email
    +
    + +
    + +
    + +
    +
    6.27.’06. 3:12am.
    + +

    色彩学

    + +

    那天坐捷运,车上边晃边读著车上广告,看到香港设计学院来台招生的广告,课程项目,看到一个项目色彩学。刹那间,这个不甚醒目的词汇,塞满了我整个头脑:我,我想学色彩学!

    + +

    我是一个网站工程师,大学是念数学的。其实我以前很会画图。我小时候很会画画,曾经想要当过画家,也参加过绘画班,得过国小的绘画奖。我对美术的兴趣,一直到了高中,因为一件事,而中断了。

    + +

    忘了是高中哪一年。那时我跟班上一个好朋友,我自认为我们两个是画得最好的。那一次美术课,老师要我们画学校的景物。我选了一栋新盖的大楼。我画得很仔细,不断比对几何比例,甚至拿铁尺去量,画出了我觉得最完美的作品。可是完成以后,我怎么看,都觉得不满意,总觉得少了点什么。直到看到我那个朋友的画。她选的是一快小林地,其实很稀梳,没几棵树,可是她的树画得很密,感觉很丰富很温暖。她画的树,不论间距、几何比例都不对。可是,我第一眼就告诉我,她画得好,我画得不好。

    + +

    那一瞬间,我明白了一件事:我没有美术的才能。一个好画家,画笔要画的,是心中看到的景象,而不是实际的景物。她画出了心中的温暖,而我画不出来。我只有理性科学工艺的才能,没有艺术表达的才能。我画的是建筑结构图,不是美术绘画。

    + +

    那以后,我就放弃了绘画,专心念数学。这么多年来,我弃绝画笔,专心投入数学、电脑科技。认识我的朋友都知道,我是一个网路程式高手,但我绝不碰网页美术设计。旅舍依玛,我挑了几个暖色系的颜色作底,就放上来了。我白纸黑字昭告天下,旅舍依玛后面有个超强大、稳定的 Selima 网站内容管理系统,可是没有好看的网站。如果觉得很丑碍眼,请自便。

    + +

    几年前,我进了现在这家公司。那时有一个跟我同时进去的美术设计。那时候为了设计公司的新网站,他把公司网站用的色表标准印下来,贴在墙上。看到那个色表,我觉得很新奇。那是我从来不懂的陌生世界。惊艳、赞叹。但除了这些以外,我却无法再说些什么。是我自己要放弃这条路的,这是我自己的选择。每个人都要按著自己要走的路努力向前,过程必然会有所取舍,可是生命只有一次,没有太多时间可以让自己左顾右盼。

    + +

    直到前几天,在捷运上,我看到了香港设计学院来台招生的广告,课程规划中,有一个项目色彩学。突然间,我心里有一股几乎无法压抑的冲动,告诉我,我想学色彩学。我不想改行走服装设计,也不想改行走商业广告设计,不想走广告动画。但至少,我想学色彩学。我想要知道每个颜色的故事,我想要知道不同颜色的不同心情。我想要在我想给人温暖感觉的时候,挑出给人温暖感觉的颜色;想给人明亮耀眼的感觉的时候,挑出给人明亮耀眼的颜色;想给人自由自在的感觉的时候,挑出给人自由自在感觉的颜色。我想知道热情的颜色,想知道妒火的颜色,想知道寂寞的颜色,想知道幸福的颜色。我希望能有有一天,我能够用颜色,带给周围的人幸福。

    + +

    不过现在色彩学,单修半年专业的课程,大概要一两万吧。嗯嗯。不是太大的数目。加油,努力存钱中。 *^_^*

    + +
    + +
    + +
    +
    6.20.’06. 10:09pm.
    + +

    今天中午,因为帮朋友回学校买一包茶叶,走进了许久未进门的大陆社。

    + +

    平日的中午,没想到竟然坐满了学弟妹。人好多,好感动。大概是要准备期末考了吧。详细问了学弟妹们社团的近况、学校的近况、最近读什么书、办什么活动等等。

    + +

    没想到他们说起念的东西,我不只都听得懂,而且还知道这些东西的程度很初级!说起来虽然我比他们多了十四届,空大也不过第三年,也跟他们一样算是大学生。而且以前听到同样的东西,我都一知半解,雾里看花。没想到现在,竟然能够居高下望。看来,我也已经有所成长了。这到底是什么原因呢?

    + +
      +
    • 是年岁较长,心境较成熟了吗?
    • +
    • 是我多年前念的东西,终於消化了吗?
    • +
    • 是这两年空大修课广泛涉猎,所以视野和变深变广了吗?
    • +
    • 是我还算蛮聪明的吗?
    • +
    + +

    嗯嗯。居高下望的感觉,自己格局变大了的感觉,有点小高兴呢。 *^_^*

    + +
    + +
    + +
    +
    6.13.’06. 8:51pm.
    + +

    公司有一件工作,延宕了一个星期,一直没时间处理好。今天不知为何,处理事情超有效率,总算把它完成了。

    + +

    处理好了已经傍晚了。回头一看才吓然发现,今天一整天都没有收信。难怪完全没有杂事分心,做起事来超顺心。看一看收件匣,发现一整天下来,积了四件要处理的事。可是看看也要下班了。我赶紧把最紧急的事先处理好,另外几件应该今天要处理的事记下来,记好明天优先处理,才匆匆下班。

    + +

    觉得 E-mail 真是可怕的东西。收了信,往往一整天就耗上去了,下班时回想,什么事都没做。忘了收信,反而能够专心做事,把事情做好。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 25 | + 26 | + 27 | + 28 | + 29 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0027.html.zh-tw.html b/htdocs/imacat/me/diary/0027.html.zh-tw.html new file mode 120000 index 0000000..46bf013 --- /dev/null +++ b/htdocs/imacat/me/diary/0027.html.zh-tw.html @@ -0,0 +1 @@ +0027.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0027.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0027.html.zh-tw.xhtml new file mode 100644 index 0000000..db3e5d9 --- /dev/null +++ b/htdocs/imacat/me/diary/0027.html.zh-tw.xhtml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷二十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷二十七

    + +
    + +
    + +
    +
    6.30.’06. 6:23pm.
    + +

    超線程的威力

    + +

    這是一台兩年前買的伺服器。其實那時候買的超線程,就可以做到 CPU 到 200% 了,一顆 CPU 當兩顆來用。真的很酷。 ^_*'

    + +
    +  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    +31802 imacat    25   0  8928 7788  360 R 99.3  0.8   0:37.22 bzip2
    +31793 imacat    25   0  9184 4848 1832 R 98.7  0.5   0:49.62 find_idic_email
    +
    + +
    + +
    + +
    +
    6.27.’06. 3:12am.
    + +

    色彩學

    + +

    那天坐捷運,車上邊晃邊讀著車上廣告,看到香港設計學院來台招生的廣告,課程項目,看到一個項目色彩學。剎那間,這個不甚醒目的詞彙,塞滿了我整個頭腦:我,我想學色彩學!

    + +

    我是一個網站工程師,大學是唸數學的。其實我以前很會畫圖。我小時候很會畫畫,曾經想要當過畫家,也參加過繪畫班,得過國小的繪畫獎。我對美術的興趣,一直到了高中,因為一件事,而中斷了。

    + +

    忘了是高中哪一年。那時我跟班上一個好朋友,我自認為我們兩個是畫得最好的。那一次美術課,老師要我們畫學校的景物。我選了一棟新蓋的大樓。我畫得很仔細,不斷比對幾何比例,甚至拿鐵尺去量,畫出了我覺得最完美的作品。可是完成以後,我怎麼看,都覺得不滿意,總覺得少了點什麼。直到看到我那個朋友的畫。她選的是一快小林地,其實很稀梳,沒幾棵樹,可是她的樹畫得很密,感覺很豐富很溫暖。她畫的樹,不論間距、幾何比例都不對。可是,我第一眼就告訴我,她畫得好,我畫得不好。

    + +

    那一瞬間,我明白了一件事:我沒有美術的才能。一個好畫家,畫筆要畫的,是心中看到的景象,而不是實際的景物。她畫出了心中的溫暖,而我畫不出來。我只有理性科學工藝的才能,沒有藝術表達的才能。我畫的是建築結構圖,不是美術繪畫。

    + +

    那以後,我就放棄了繪畫,專心唸數學。這麼多年來,我棄絕畫筆,專心投入數學、電腦科技。認識我的朋友都知道,我是一個網路程式高手,但我絕不碰網頁美術設計。旅舍依瑪,我挑了幾個暖色系的顏色作底,就放上來了。我白紙黑字昭告天下,旅舍依瑪後面有個超強大、穩定的 Selima 網站內容管理系統,可是沒有好看的網站。如果覺得很醜礙眼,請自便。

    + +

    幾年前,我進了現在這家公司。那時有一個跟我同時進去的美術設計。那時候為了設計公司的新網站,他把公司網站用的色表標準印下來,貼在牆上。看到那個色表,我覺得很新奇。那是我從來不懂的陌生世界。驚豔、讚嘆。但除了這些以外,我卻無法再說些什麼。是我自己要放棄這條路的,這是我自己的選擇。每個人都要按著自己要走的路努力向前,過程必然會有所取捨,可是生命只有一次,沒有太多時間可以讓自己左顧右盼。

    + +

    直到前幾天,在捷運上,我看到了香港設計學院來台招生的廣告,課程規劃中,有一個項目色彩學。突然間,我心裏有一股幾乎無法壓抑的衝動,告訴我,我想學色彩學。我不想改行走服裝設計,也不想改行走商業廣告設計,不想走廣告動畫。但至少,我想學色彩學。我想要知道每個顏色的故事,我想要知道不同顏色的不同心情。我想要在我想給人溫暖感覺的時候,挑出給人溫暖感覺的顏色;想給人明亮耀眼的感覺的時候,挑出給人明亮耀眼的顏色;想給人自由自在的感覺的時候,挑出給人自由自在感覺的顏色。我想知道熱情的顏色,想知道妒火的顏色,想知道寂寞的顏色,想知道幸福的顏色。我希望能有有一天,我能夠用顏色,帶給周圍的人幸福。

    + +

    不過現在色彩學,單修半年專業的課程,大概要一兩萬吧。嗯嗯。不是太大的數目。加油,努力存錢中。 *^_^*

    + +
    + +
    + +
    +
    6.20.’06. 10:09pm.
    + +

    今天中午,因為幫朋友回學校買一包茶葉,走進了許久未進門的大陸社。

    + +

    平日的中午,沒想到竟然坐滿了學弟妹。人好多,好感動。大概是要準備期末考了吧。詳細問了學弟妹們社團的近況、學校的近況、最近讀什麼書、辦什麼活動等等。

    + +

    沒想到他們說起唸的東西,我不只都聽得懂,而且還知道這些東西的程度很初級!說起來雖然我比他們多了十四屆,空大也不過第三年,也跟他們一樣算是大學生。而且以前聽到同樣的東西,我都一知半解,霧裏看花。沒想到現在,竟然能夠居高下望。看來,我也已經有所成長了。這到底是什麼原因呢?

    + +
      +
    • 是年歲較長,心境較成熟了嗎?
    • +
    • 是我多年前唸的東西,終於消化了嗎?
    • +
    • 是這兩年空大修課廣泛涉獵,所以視野和變深變廣了嗎?
    • +
    • 是我還算蠻聰明的嗎?
    • +
    + +

    嗯嗯。居高下望的感覺,自己格局變大了的感覺,有點小高興呢。 *^_^*

    + +
    + +
    + +
    +
    6.13.’06. 8:51pm.
    + +

    公司有一件工作,延宕了一個星期,一直沒時間處理好。今天不知為何,處理事情超有效率,總算把它完成了。

    + +

    處理好了已經傍晚了。回頭一看才嚇然發現,今天一整天都沒有收信。難怪完全沒有雜事分心,做起事來超順心。看一看收件匣,發現一整天下來,積了四件要處理的事。可是看看也要下班了。我趕緊把最緊急的事先處理好,另外幾件應該今天要處理的事記下來,記好明天優先處理,才匆匆下班。

    + +

    覺得 E-mail 真是可怕的東西。收了信,往往一整天就耗上去了,下班時回想,什麼事都沒做。忘了收信,反而能夠專心做事,把事情做好。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 25 | + 26 | + 27 | + 28 | + 29 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0028.html.en.html b/htdocs/imacat/me/diary/0028.html.en.html new file mode 120000 index 0000000..b9bdb5d --- /dev/null +++ b/htdocs/imacat/me/diary/0028.html.en.html @@ -0,0 +1 @@ +0028.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0028.html.en.xhtml b/htdocs/imacat/me/diary/0028.html.en.xhtml new file mode 100644 index 0000000..3838e82 --- /dev/null +++ b/htdocs/imacat/me/diary/0028.html.en.xhtml @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 28 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 28

    + +
    + +
    + +
    +
    7.15.’06. 10:13pm.
    + +

    依瑪貓中英語教室 (2)

    + +

    今天我們要教的是這一句:

    + +
    Foreappoint a bright life for the children
    +預約孩子亮麗人生
    + +
    +預約孩子亮麗人生
    +

    預約孩子亮麗人生

    +
    + +
    +Foreappoint a bright life for the children
    +

    Foreappoint a bright life for the children

    +
    + +

    這一句中英文,出現在我家附近一家叫耕讀園 Gan Du Yan的補習班附設的兒童美語班,外牆的廣告上,大概一兩年了。

    + +
    +永和保福路上的耕讀園‧牛頓美語
    +

    永和保福路上的耕讀園‧牛頓美語

    +
    + +

    這句話的中文很通順,意思也很清楚明確,沒有什麼問題。問題是英文。

    + +

    預約孩子亮麗人生Foreappoint a bright life for the children

    + +
      +
    • 預約foreappoint
    • +
    • 孩子children
    • +
    • 亮麗bright
    • +
    • 人生life
    • +
    + +

    嗯,翻譯得真是非常工整。真是標準的逐字翻譯。問題是:

    + +
      +
    • 這世界上,哪有 foreappoint 這個字? appoint約定預約預先約定,所以前置 fore- ,成為 foreappoint 。這種英文,真的讓人昏倒。 appoint 本身就是約定預約的意思了。約定也一定是約定未來的事。哪有什麼約定過去的事?所以約定就是預約。以為是約就要前置 fore- ,這是英文一知半解者的自作聰明。
    • + +
    • 什麼叫作 bright life生命發亮亮麗人生是中文的形容方式,表示前途一片光明,生活非常好。不過英文根本沒有這種說法。 bright life 聽起來像是深海發光生物一樣。要形容未來生活得非常好,英文通常是說 bright future
    • + +
    • 應該是 your children ,不是 the children 吧?這是一家補習班,對象不是泛稱廣大的全世界兒童,而是讀到這篇廣告的家長,自己家的小孩吧?
    • + +
    • 即使改正了前三點,預約孩子亮麗人生Appoint a bright future for your children ,還是不對。中文的預約人生,是從類似像訂做一個完美情人的概念延伸的,是指幫孩子準備好一個很光明的未來。可是在英文裏, appoint 一定會有具體的約定對象,不能跟空無一物做約定。預約孩子亮麗人生,跟誰預約?神嗎?上帝嗎?未來嗎?怎麼約?依文意脈絡來看,想表達的是為未來做準備,應該是用 prepare ,打造或準備。Prepare a bright future for your children ,才是正確的英文用法。
    • +
    + +

    結論: Foreappoint a bright life for the children 這句英文真的非常扯,純粹是對英文一知半解者,從中文逐字逐句譯過去的。從這句話,就可以看出撰寫者的英文有多糟糕。問題是:這是一家美語補習班的廣告耶!我真的無法想像,讓小孩子去這種補習班學英文,長大以後我們的下一代,會講出什麼樣的英文!光想到就非常害怕。

    + +
    + +
    + +
    +
    7.4.’06. 5:05pm.
    + +

    兩種美味

    + +

    我覺得,這個世界上,有兩種美味。

    + +

    第一種是,妳需要放空心思,閉起眼睛,繃緊神經,把全部精神集中到舌頭上。當食物入口的一瞬間,用全部的心神,感受口腔內泛起的每一個感覺,口感、香味、味道等。等細細咀嚼,食物入喉後,張開眼睛點點頭,讚嘆:嗯,好吃。

    + +

    第二種是,買的時候心不在焉,諸事煩心,一邊工作、唸書、看電視或想事情,一邊把食物塞進口中。可是沒料到入口瞬間美味無比,五味紛呈,剎時腦袋一片空白,只剩口腔中食物的美味,過了一會,才勉強大嘆一句:好…好吃!

    + +

    哪一種比較好吃呢?不知道。感覺上好像第二種比較好吃。美味應該是沒有界限的。要集中精神品嚐才能享受的美味,總覺得做作,味道會受心理期望影響,而過度美化失真。不過有些食物的美味是細膩的,沒有專心品嚐,細嚼慢嚥的話,就好像垃圾入肚一樣,浪費掉了,對不起用心準備美味料理的廚師。

    + +

    至於像槙村さとる(槙村怜)おいしい関係(美味的關係)裏所形容的,放鬆心情,用全部的身心去品嚐的美味,我還沒有感受過。我好像永遠都在盤算東盤算西,神經永遠繃得緊緊的。什麼時候我才能夠有放鬆的心情,來用全部的身心,品嚐美味呢?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 26 | + 27 | + 28 | + 29 | + 30 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0028.html.zh-cn.html b/htdocs/imacat/me/diary/0028.html.zh-cn.html new file mode 120000 index 0000000..d981c84 --- /dev/null +++ b/htdocs/imacat/me/diary/0028.html.zh-cn.html @@ -0,0 +1 @@ +0028.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0028.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0028.html.zh-cn.xhtml new file mode 100644 index 0000000..9731858 --- /dev/null +++ b/htdocs/imacat/me/diary/0028.html.zh-cn.xhtml @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷二十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷二十八

    + +
    + +
    + +
    +
    7.15.’06. 10:13pm.
    + +

    依玛猫中英语教室 (2)

    + +

    今天我们要教的是这一句:

    + +
    Foreappoint a bright life for the children
    +预约孩子亮丽人生
    + +
    +预约孩子亮丽人生
    +

    预约孩子亮丽人生

    +
    + +
    +Foreappoint a bright life for the children
    +

    Foreappoint a bright life for the children

    +
    + +

    这一句中英文,出现在我家附近一家叫耕读园 Gan Du Yan的补习班附设的儿童美语班,外墙的广告上,大概一两年了。

    + +
    +永和保福路上的耕读园・牛顿美语
    +

    永和保福路上的耕读园・牛顿美语

    +
    + +

    这句话的中文很通顺,意思也很清楚明确,没有什么问题。问题是英文。

    + +

    预约孩子亮丽人生Foreappoint a bright life for the children

    + +
      +
    • 预约foreappoint
    • +
    • 孩子children
    • +
    • 亮丽bright
    • +
    • 人生life
    • +
    + +

    嗯,翻译得真是非常工整。真是标准的逐字翻译。问题是:

    + +
      +
    • 这世界上,哪有 foreappoint 这个字? appoint约定预约预先约定,所以前置 fore- ,成为 foreappoint 。这种英文,真的让人昏倒。 appoint 本身就是约定预约的意思了。约定也一定是约定未来的事。哪有什么约定过去的事?所以约定就是预约。以为是约就要前置 fore- ,这是英文一知半解者的自作聪明。
    • + +
    • 什么叫作 bright life生命发亮亮丽人生是中文的形容方式,表示前途一片光明,生活非常好。不过英文根本没有这种说法。 bright life 听起来像是深海发光生物一样。要形容未来生活得非常好,英文通常是说 bright future
    • + +
    • 应该是 your children ,不是 the children 吧?这是一家补习班,对象不是泛称广大的全世界儿童,而是读到这篇广告的家长,自己家的小孩吧?
    • + +
    • 即使改正了前三点,预约孩子亮丽人生Appoint a bright future for your children ,还是不对。中文的预约人生,是从类似像订做一个完美情人的概念延伸的,是指帮孩子准备好一个很光明的未来。可是在英文里, appoint 一定会有具体的约定对象,不能跟空无一物做约定。预约孩子亮丽人生,跟谁预约?神吗?上帝吗?未来吗?怎么约?依文意脉络来看,想表达的是为未来做准备,应该是用 prepare ,打造或准备。Prepare a bright future for your children ,才是正确的英文用法。
    • +
    + +

    结论: Foreappoint a bright life for the children 这句英文真的非常扯,纯粹是对英文一知半解者,从中文逐字逐句译过去的。从这句话,就可以看出撰写者的英文有多糟糕。问题是:这是一家美语补习班的广告耶!我真的无法想像,让小孩子去这种补习班学英文,长大以后我们的下一代,会讲出什么样的英文!光想到就非常害怕。

    + +
    + +
    + +
    +
    7.4.’06. 5:05pm.
    + +

    两种美味

    + +

    我觉得,这个世界上,有两种美味。

    + +

    第一种是,你需要放空心思,闭起眼睛,绷紧神经,把全部精神集中到舌头上。当食物入口的一瞬间,用全部的心神,感受口腔内泛起的每一个感觉,口感、香味、味道等。等细细咀嚼,食物入喉后,张开眼睛点点头,赞叹:嗯,好吃。

    + +

    第二种是,买的时候心不在焉,诸事烦心,一边工作、念书、看电视或想事情,一边把食物塞进口中。可是没料到入口瞬间美味无比,五味纷呈,刹时脑袋一片空白,只剩口腔中食物的美味,过了一会,才勉强大叹一句:好…好吃!

    + +

    哪一种比较好吃呢?不知道。感觉上好像第二种比较好吃。美味应该是没有界限的。要集中精神品尝才能享受的美味,总觉得做作,味道会受心理期望影响,而过度美化失真。不过有些食物的美味是细腻的,没有专心品尝,细嚼慢咽的话,就好像垃圾入肚一样,浪费掉了,对不起用心准备美味料理的厨师。

    + +

    至於像槙村さとる(槙村怜)おいしい関系(美味的关系)里所形容的,放松心情,用全部的身心去品尝的美味,我还没有感受过。我好像永远都在盘算东盘算西,神经永远绷得紧紧的。什么时候我才能够有放松的心情,来用全部的身心,品尝美味呢?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 26 | + 27 | + 28 | + 29 | + 30 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0028.html.zh-tw.html b/htdocs/imacat/me/diary/0028.html.zh-tw.html new file mode 120000 index 0000000..3a3ca75 --- /dev/null +++ b/htdocs/imacat/me/diary/0028.html.zh-tw.html @@ -0,0 +1 @@ +0028.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0028.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0028.html.zh-tw.xhtml new file mode 100644 index 0000000..da680e2 --- /dev/null +++ b/htdocs/imacat/me/diary/0028.html.zh-tw.xhtml @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷二十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷二十八

    + +
    + +
    + +
    +
    7.15.’06. 10:13pm.
    + +

    依瑪貓中英語教室 (2)

    + +

    今天我們要教的是這一句:

    + +
    Foreappoint a bright life for the children
    +預約孩子亮麗人生
    + +
    +預約孩子亮麗人生
    +

    預約孩子亮麗人生

    +
    + +
    +Foreappoint a bright life for the children
    +

    Foreappoint a bright life for the children

    +
    + +

    這一句中英文,出現在我家附近一家叫耕讀園 Gan Du Yan的補習班附設的兒童美語班,外牆的廣告上,大概一兩年了。

    + +
    +永和保福路上的耕讀園‧牛頓美語
    +

    永和保福路上的耕讀園‧牛頓美語

    +
    + +

    這句話的中文很通順,意思也很清楚明確,沒有什麼問題。問題是英文。

    + +

    預約孩子亮麗人生Foreappoint a bright life for the children

    + +
      +
    • 預約foreappoint
    • +
    • 孩子children
    • +
    • 亮麗bright
    • +
    • 人生life
    • +
    + +

    嗯,翻譯得真是非常工整。真是標準的逐字翻譯。問題是:

    + +
      +
    • 這世界上,哪有 foreappoint 這個字? appoint約定預約預先約定,所以前置 fore- ,成為 foreappoint 。這種英文,真的讓人昏倒。 appoint 本身就是約定預約的意思了。約定也一定是約定未來的事。哪有什麼約定過去的事?所以約定就是預約。以為是約就要前置 fore- ,這是英文一知半解者的自作聰明。
    • + +
    • 什麼叫作 bright life生命發亮亮麗人生是中文的形容方式,表示前途一片光明,生活非常好。不過英文根本沒有這種說法。 bright life 聽起來像是深海發光生物一樣。要形容未來生活得非常好,英文通常是說 bright future
    • + +
    • 應該是 your children ,不是 the children 吧?這是一家補習班,對象不是泛稱廣大的全世界兒童,而是讀到這篇廣告的家長,自己家的小孩吧?
    • + +
    • 即使改正了前三點,預約孩子亮麗人生Appoint a bright future for your children ,還是不對。中文的預約人生,是從類似像訂做一個完美情人的概念延伸的,是指幫孩子準備好一個很光明的未來。可是在英文裏, appoint 一定會有具體的約定對象,不能跟空無一物做約定。預約孩子亮麗人生,跟誰預約?神嗎?上帝嗎?未來嗎?怎麼約?依文意脈絡來看,想表達的是為未來做準備,應該是用 prepare ,打造或準備。Prepare a bright future for your children ,才是正確的英文用法。
    • +
    + +

    結論: Foreappoint a bright life for the children 這句英文真的非常扯,純粹是對英文一知半解者,從中文逐字逐句譯過去的。從這句話,就可以看出撰寫者的英文有多糟糕。問題是:這是一家美語補習班的廣告耶!我真的無法想像,讓小孩子去這種補習班學英文,長大以後我們的下一代,會講出什麼樣的英文!光想到就非常害怕。

    + +
    + +
    + +
    +
    7.4.’06. 5:05pm.
    + +

    兩種美味

    + +

    我覺得,這個世界上,有兩種美味。

    + +

    第一種是,妳需要放空心思,閉起眼睛,繃緊神經,把全部精神集中到舌頭上。當食物入口的一瞬間,用全部的心神,感受口腔內泛起的每一個感覺,口感、香味、味道等。等細細咀嚼,食物入喉後,張開眼睛點點頭,讚嘆:嗯,好吃。

    + +

    第二種是,買的時候心不在焉,諸事煩心,一邊工作、唸書、看電視或想事情,一邊把食物塞進口中。可是沒料到入口瞬間美味無比,五味紛呈,剎時腦袋一片空白,只剩口腔中食物的美味,過了一會,才勉強大嘆一句:好…好吃!

    + +

    哪一種比較好吃呢?不知道。感覺上好像第二種比較好吃。美味應該是沒有界限的。要集中精神品嚐才能享受的美味,總覺得做作,味道會受心理期望影響,而過度美化失真。不過有些食物的美味是細膩的,沒有專心品嚐,細嚼慢嚥的話,就好像垃圾入肚一樣,浪費掉了,對不起用心準備美味料理的廚師。

    + +

    至於像槙村さとる(槙村怜)おいしい関係(美味的關係)裏所形容的,放鬆心情,用全部的身心去品嚐的美味,我還沒有感受過。我好像永遠都在盤算東盤算西,神經永遠繃得緊緊的。什麼時候我才能夠有放鬆的心情,來用全部的身心,品嚐美味呢?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 26 | + 27 | + 28 | + 29 | + 30 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0029.html.en.html b/htdocs/imacat/me/diary/0029.html.en.html new file mode 120000 index 0000000..bdfbe22 --- /dev/null +++ b/htdocs/imacat/me/diary/0029.html.en.html @@ -0,0 +1 @@ +0029.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0029.html.en.xhtml b/htdocs/imacat/me/diary/0029.html.en.xhtml new file mode 100644 index 0000000..6d02778 --- /dev/null +++ b/htdocs/imacat/me/diary/0029.html.en.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 29 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 29

    + +
    + +
    + +
    +
    7.23.’06. 4:29pm.
    + +

    關於獨立生活的能力

    + +

    小時候,我對於生活,就有一種很特別的看法。

    + +

    我希望我自己,能像魯濱遜漂流記一樣,即使被丟到一個無人荒島上,也能靠自己的雙手,一個人活下來。所以我從小就很迷野外求生知識,很迷百戰天龍裏的馬蓋先,能就地取材,用周遭的物品,製作各式各樣所需的工具,像利用殺蟲劑製作小型炸彈等等。用殺蟲劑做炸彈,威力不大,可以用來爆破鎖死的門,讓小時候的我大開眼界,印象深刻。

    + +

    我忘了其實我有沒有讀過魯濱遜漂流記了。搞不好根本沒有,我只是幻想那樣的生活理念而已。

    + +

    可是這樣的想法,一直成為我的信條。我希望我是這樣的一個人,可以在萬一有一天失去周遭所有人的幫助,例如山難、溺水,或到一個陌生的城市裏,也能夠一個人活下來。我覺得一個人的基本生活食衣住行,像是飲食、清潔、打掃、洗衣、出門行動等等,要有能力自己打理。自己的基本生活要自己顧好,一直是我生活的一個基本信念。

    + +

    相對地,我對於做不到的人,很不以為然。像那種明明手腳健在,耳聰目明,不殘不缺,可是一定要請個菲傭打掃、洗衣、煮飯,茶來伸手、飯來張口,或是大言不慚,說要娶個漂亮、賢慧的婆回家做家事,認為別人幫他打理基本生活是理所當然的傢伙,不管是 T 還是男的,我都覺得很幼稚,非常不恥。

    + +

    前兩年不知何故,在 ICQ 上認識了這麼一個 T :跟我同齡,比我大幾個月,收入比我少,卻一定要請菲傭打掃、洗衣、煮飯,成天哭著要娶個漂亮、賢慧的婆回家給她做家事。真是超級幼稚!我本來耐著性子陪她說話,反正沒事有人陪我說話也好,只要不把腦子動到我頭上就好了。她三天兩頭跟我抱怨,要是我賢慧一點,就是她的理想對象了!沒兩個月我的耐性就磨完了,大吵一架,就切了,比我預期得快。印象中和朋友切已經是小學時候的事了,長這麼大竟然還會跟朋友切,真是莫名奇妙。

    + +

    想想不對,大學時也曾經跟一個怪學妹切。那件事更是莫名奇妙。不過這是題外話。

    + +

    人要能夠自己打理自己的基本生活,自己照顧好自己。如果好手好腳,不會自己打掃、洗衣、煮飯,不會自己照顧自己,那不如把手腳筋自己斷了。反正留著好手好腳,也沒什麼用處。我是真的這樣想的。

    + +
    + +
    + +
    +
    7.16.’06. 1:28am.
    + +

    這個星期開始,我開始改用一種新的方法做事,效率超高。

    + +

    事情起因是上個星期的一件事。我原本五月底選好了空大暑修的課,六月底選好了空大 95 上的課。暑修選課時,因為我 94 下終於把管資的課選完了,可以擺脫管資的課了,高興之餘,一心只想選管資以外的課,所以隨手亂選了一堆課。六月底選好 95 上的課時,回頭看看暑修選的課,才發現選了一門生死哲學概論。生死學既不是本科必修,我也沒有興趣,對未來也沒有幫助。我看看課本,發現有一門資訊倫理與法律。我想乾脆改選一門對本科有助益的課好了,於是就跑到空大台北中心辦加退選。沒想到填表時才發現,資訊倫理與法律與我選的另一科政府與工會期考衝堂。我只好再看看有什麼不衝堂的課可選。看著看著,我看到了會計學概要。我一直都很想學點初等會計學,有個基本的會計概念,瞭解應收帳款、應付帳款、折舊等等的,對日常生活和寫帳務系統很有幫助。於是我就選了。

    + +

    問題來了: 95 上我原本就有選會計學。那個時候一直猶豫要選會計學還是台灣史重要文獻導讀。兩者我都有興趣。前面提過,我一直很想學點會計學基礎。可是我也一直都很想唸台灣史。畢業以後,我大概就沒有什麼機會特別去唸台灣史了。後來我選了實用性高的會計學。不過現在既然暑修就修了會計學,那我 95 上就可以改修台灣史了。真是一個完美的結局!

    + +

    於是我唸茲在茲,記得一定要在選課結束前,網路選課上改選台灣史。可是連著兩天事情太多太忙,每天騎車、買東西排隊時想到,可是一坐上椅子,面對一大堆事情,就又通通都忘了。第三天 7/6 早上買早餐時終於又想起來,於是我不敢再忘,嘴上一直輕唸著直到辦公室,打開電腦,立刻連上空大網站一看:網路選課到昨天截止!天哪!就差十個小時!我趕緊打個電話去台北中心問,電話那一端回答我:真的很抱歉,可是電腦系統已經關起來了,我們也幫不上忙。妳可以在 7/25–7/27 到台北中心加退選,加退選手續費 200 元。

    + +

    昏倒!兩百元是小事,可是就差了十個小時,結局就變成要大老遠跑到台北中心去,而且限那三天才能辦理!忘了差一天,代價竟然這麼高!

    + +

    於是我開始改用一個新的方法做事。我電腦桌面上原本就有一個便條紙檔案,供我隨手記筆記,記下一些事情備忘。我現在每想到要做的事,不管是就要著手去做,還是暫未決定該怎麼做,不管急或不急,重不重要,好不好做,隨時只要想到,就通通都記下來。做完了,再一一刪掉,然後看看清單,挑下一件事來做。這樣一來,強迫自己面對所有還沒做的事,做出一直懸而未決的決定。不用每次一件事情做完,開始發呆,慢慢回憶,盤算接下來要做哪件事,結果漏東漏西。

    + +

    一個星期下來,效率超高。幾年前拍的該整理的照片、伺服器程式該昇級的、該安全檢查的、該做 bug report 的、該整理的檔案、該訂閱的新版通知,通通都做完了。我從來沒有像這個星期,做事情這麼有效率過!一大堆幾年來懸而未決的事,通通都搞定了。

    + +

    就像這個耕讀園的可笑英文 Foreappoint a bright life for the children 。這三張照片其實是去年年初拍攝,打算寫上來的,可是直到這兩天,才整理好,把事情寫上來。還有 Starbucks 的可笑廣告詞 I perfect the drink within your drink. 咖啡宛如藝術 而我 完美了它,也是去年拍的照片,直到現在才附上來。

    + +

    可是一個星期下來,我卻感到前所未有的累。以超高效率做事的代價,就是超累。原本一件事情做完,我會發個呆,看兩則新聞,盤算接下來該做哪件事,也讓自己的腦袋休息一下。可是現在這個休息沒有了。強迫自己一直不斷地做決定、做決定、做決定,不給自己任何拖延的藉口,結果是把自己累垮。我陷入前所未有的疲倦中,無法休息,找不到出路。

    + +

    真的好累。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 27 | + 28 | + 29 | + 30 | + 31 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0029.html.zh-cn.html b/htdocs/imacat/me/diary/0029.html.zh-cn.html new file mode 120000 index 0000000..e018eb8 --- /dev/null +++ b/htdocs/imacat/me/diary/0029.html.zh-cn.html @@ -0,0 +1 @@ +0029.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0029.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0029.html.zh-cn.xhtml new file mode 100644 index 0000000..17dd69d --- /dev/null +++ b/htdocs/imacat/me/diary/0029.html.zh-cn.xhtml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷二十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷二十九

    + +
    + +
    + +
    +
    7.23.’06. 4:29pm.
    + +

    关於独立生活的能力

    + +

    小时候,我对於生活,就有一种很特别的看法。

    + +

    我希望我自己,能像鲁滨逊漂流记一样,即使被丢到一个无人荒岛上,也能靠自己的双手,一个人活下来。所以我从小就很迷野外求生知识,很迷百战天龙里的马盖先,能就地取材,用周遭的物品,制作各式各样所需的工具,像利用杀虫剂制作小型炸弹等等。用杀虫剂做炸弹,威力不大,可以用来爆破锁死的门,让小时候的我大开眼界,印象深刻。

    + +

    我忘了其实我有没有读过鲁滨逊漂流记了。搞不好根本没有,我只是幻想那样的生活理念而已。

    + +

    可是这样的想法,一直成为我的信条。我希望我是这样的一个人,可以在万一有一天失去周遭所有人的帮助,例如山难、溺水,或到一个陌生的城市里,也能够一个人活下来。我觉得一个人的基本生活食衣住行,像是饮食、清洁、打扫、洗衣、出门行动等等,要有能力自己打理。自己的基本生活要自己顾好,一直是我生活的一个基本信念。

    + +

    相对地,我对於做不到的人,很不以为然。像那种明明手脚健在,耳聪目明,不残不缺,可是一定要请个菲佣打扫、洗衣、煮饭,茶来伸手、饭来张口,或是大言不惭,说要娶个漂亮、贤慧的婆回家做家事,认为别人帮他打理基本生活是理所当然的家伙,不管是 T 还是男的,我都觉得很幼稚,非常不耻。

    + +

    前两年不知何故,在 ICQ 上认识了这么一个 T :跟我同龄,比我大几个月,收入比我少,却一定要请菲佣打扫、洗衣、煮饭,成天哭著要娶个漂亮、贤慧的婆回家给她做家事。真是超级幼稚!我本来耐著性子陪她说话,反正没事有人陪我说话也好,只要不把脑子动到我头上就好了。她三天两头跟我抱怨,要是我贤慧一点,就是她的理想对象了!没两个月我的耐性就磨完了,大吵一架,就切了,比我预期得快。印象中和朋友切已经是小学时候的事了,长这么大竟然还会跟朋友切,真是莫名奇妙。

    + +

    想想不对,大学时也曾经跟一个怪学妹切。那件事更是莫名奇妙。不过这是题外话。

    + +

    人要能够自己打理自己的基本生活,自己照顾好自己。如果好手好脚,不会自己打扫、洗衣、煮饭,不会自己照顾自己,那不如把手脚筋自己断了。反正留著好手好脚,也没什么用处。我是真的这样想的。

    + +
    + +
    + +
    +
    7.16.’06. 1:28am.
    + +

    这个星期开始,我开始改用一种新的方法做事,效率超高。

    + +

    事情起因是上个星期的一件事。我原本五月底选好了空大暑修的课,六月底选好了空大 95 上的课。暑修选课时,因为我 94 下终於把管资的课选完了,可以摆脱管资的课了,高兴之余,一心只想选管资以外的课,所以随手乱选了一堆课。六月底选好 95 上的课时,回头看看暑修选的课,才发现选了一门生死哲学概论。生死学既不是本科必修,我也没有兴趣,对未来也没有帮助。我看看课本,发现有一门资讯伦理与法律。我想干脆改选一门对本科有助益的课好了,於是就跑到空大台北中心办加退选。没想到填表时才发现,资讯伦理与法律与我选的另一科政府与工会期考冲堂。我只好再看看有什么不冲堂的课可选。看著看著,我看到了会计学概要。我一直都很想学点初等会计学,有个基本的会计概念,了解应收帐款、应付帐款、折旧等等的,对日常生活和写帐务系统很有帮助。於是我就选了。

    + +

    问题来了: 95 上我原本就有选会计学。那个时候一直犹豫要选会计学还是台湾史重要文献导读。两者我都有兴趣。前面提过,我一直很想学点会计学基础。可是我也一直都很想念台湾史。毕业以后,我大概就没有什么机会特别去念台湾史了。后来我选了实用性高的会计学。不过现在既然暑修就修了会计学,那我 95 上就可以改修台湾史了。真是一个完美的结局!

    + +

    於是我念兹在兹,记得一定要在选课结束前,网路选课上改选台湾史。可是连著两天事情太多太忙,每天骑车、买东西排队时想到,可是一坐上椅子,面对一大堆事情,就又通通都忘了。第三天 7/6 早上买早餐时终於又想起来,於是我不敢再忘,嘴上一直轻念著直到办公室,打开电脑,立刻连上空大网站一看:网路选课到昨天截止!天哪!就差十个小时!我赶紧打个电话去台北中心问,电话那一端回答我:真的很抱歉,可是电脑系统已经关起来了,我们也帮不上忙。你可以在 7/25–7/27 到台北中心加退选,加退选手续费 200 元。

    + +

    昏倒!两百元是小事,可是就差了十个小时,结局就变成要大老远跑到台北中心去,而且限那三天才能办理!忘了差一天,代价竟然这么高!

    + +

    於是我开始改用一个新的方法做事。我电脑桌面上原本就有一个便条纸档案,供我随手记笔记,记下一些事情备忘。我现在每想到要做的事,不管是就要著手去做,还是暂未决定该怎么做,不管急或不急,重不重要,好不好做,随时只要想到,就通通都记下来。做完了,再一一删掉,然后看看清单,挑下一件事来做。这样一来,强迫自己面对所有还没做的事,做出一直悬而未决的决定。不用每次一件事情做完,开始发呆,慢慢回忆,盘算接下来要做哪件事,结果漏东漏西。

    + +

    一个星期下来,效率超高。几年前拍的该整理的照片、伺服器程式该升级的、该安全检查的、该做 bug report 的、该整理的档案、该订阅的新版通知,通通都做完了。我从来没有像这个星期,做事情这么有效率过!一大堆几年来悬而未决的事,通通都搞定了。

    + +

    就像这个耕读园的可笑英文 Foreappoint a bright life for the children 。这三张照片其实是去年年初拍摄,打算写上来的,可是直到这两天,才整理好,把事情写上来。还有 Starbucks 的可笑广告词 I perfect the drink within your drink. 咖啡宛如艺术 而我 完美了它,也是去年拍的照片,直到现在才附上来。

    + +

    可是一个星期下来,我却感到前所未有的累。以超高效率做事的代价,就是超累。原本一件事情做完,我会发个呆,看两则新闻,盘算接下来该做哪件事,也让自己的脑袋休息一下。可是现在这个休息没有了。强迫自己一直不断地做决定、做决定、做决定,不给自己任何拖延的藉口,结果是把自己累垮。我陷入前所未有的疲倦中,无法休息,找不到出路。

    + +

    真的好累。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 27 | + 28 | + 29 | + 30 | + 31 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0029.html.zh-tw.html b/htdocs/imacat/me/diary/0029.html.zh-tw.html new file mode 120000 index 0000000..6d29788 --- /dev/null +++ b/htdocs/imacat/me/diary/0029.html.zh-tw.html @@ -0,0 +1 @@ +0029.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0029.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0029.html.zh-tw.xhtml new file mode 100644 index 0000000..99193a9 --- /dev/null +++ b/htdocs/imacat/me/diary/0029.html.zh-tw.xhtml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷二十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷二十九

    + +
    + +
    + +
    +
    7.23.’06. 4:29pm.
    + +

    關於獨立生活的能力

    + +

    小時候,我對於生活,就有一種很特別的看法。

    + +

    我希望我自己,能像魯濱遜漂流記一樣,即使被丟到一個無人荒島上,也能靠自己的雙手,一個人活下來。所以我從小就很迷野外求生知識,很迷百戰天龍裏的馬蓋先,能就地取材,用周遭的物品,製作各式各樣所需的工具,像利用殺蟲劑製作小型炸彈等等。用殺蟲劑做炸彈,威力不大,可以用來爆破鎖死的門,讓小時候的我大開眼界,印象深刻。

    + +

    我忘了其實我有沒有讀過魯濱遜漂流記了。搞不好根本沒有,我只是幻想那樣的生活理念而已。

    + +

    可是這樣的想法,一直成為我的信條。我希望我是這樣的一個人,可以在萬一有一天失去周遭所有人的幫助,例如山難、溺水,或到一個陌生的城市裏,也能夠一個人活下來。我覺得一個人的基本生活食衣住行,像是飲食、清潔、打掃、洗衣、出門行動等等,要有能力自己打理。自己的基本生活要自己顧好,一直是我生活的一個基本信念。

    + +

    相對地,我對於做不到的人,很不以為然。像那種明明手腳健在,耳聰目明,不殘不缺,可是一定要請個菲傭打掃、洗衣、煮飯,茶來伸手、飯來張口,或是大言不慚,說要娶個漂亮、賢慧的婆回家做家事,認為別人幫他打理基本生活是理所當然的傢伙,不管是 T 還是男的,我都覺得很幼稚,非常不恥。

    + +

    前兩年不知何故,在 ICQ 上認識了這麼一個 T :跟我同齡,比我大幾個月,收入比我少,卻一定要請菲傭打掃、洗衣、煮飯,成天哭著要娶個漂亮、賢慧的婆回家給她做家事。真是超級幼稚!我本來耐著性子陪她說話,反正沒事有人陪我說話也好,只要不把腦子動到我頭上就好了。她三天兩頭跟我抱怨,要是我賢慧一點,就是她的理想對象了!沒兩個月我的耐性就磨完了,大吵一架,就切了,比我預期得快。印象中和朋友切已經是小學時候的事了,長這麼大竟然還會跟朋友切,真是莫名奇妙。

    + +

    想想不對,大學時也曾經跟一個怪學妹切。那件事更是莫名奇妙。不過這是題外話。

    + +

    人要能夠自己打理自己的基本生活,自己照顧好自己。如果好手好腳,不會自己打掃、洗衣、煮飯,不會自己照顧自己,那不如把手腳筋自己斷了。反正留著好手好腳,也沒什麼用處。我是真的這樣想的。

    + +
    + +
    + +
    +
    7.16.’06. 1:28am.
    + +

    這個星期開始,我開始改用一種新的方法做事,效率超高。

    + +

    事情起因是上個星期的一件事。我原本五月底選好了空大暑修的課,六月底選好了空大 95 上的課。暑修選課時,因為我 94 下終於把管資的課選完了,可以擺脫管資的課了,高興之餘,一心只想選管資以外的課,所以隨手亂選了一堆課。六月底選好 95 上的課時,回頭看看暑修選的課,才發現選了一門生死哲學概論。生死學既不是本科必修,我也沒有興趣,對未來也沒有幫助。我看看課本,發現有一門資訊倫理與法律。我想乾脆改選一門對本科有助益的課好了,於是就跑到空大台北中心辦加退選。沒想到填表時才發現,資訊倫理與法律與我選的另一科政府與工會期考衝堂。我只好再看看有什麼不衝堂的課可選。看著看著,我看到了會計學概要。我一直都很想學點初等會計學,有個基本的會計概念,瞭解應收帳款、應付帳款、折舊等等的,對日常生活和寫帳務系統很有幫助。於是我就選了。

    + +

    問題來了: 95 上我原本就有選會計學。那個時候一直猶豫要選會計學還是台灣史重要文獻導讀。兩者我都有興趣。前面提過,我一直很想學點會計學基礎。可是我也一直都很想唸台灣史。畢業以後,我大概就沒有什麼機會特別去唸台灣史了。後來我選了實用性高的會計學。不過現在既然暑修就修了會計學,那我 95 上就可以改修台灣史了。真是一個完美的結局!

    + +

    於是我唸茲在茲,記得一定要在選課結束前,網路選課上改選台灣史。可是連著兩天事情太多太忙,每天騎車、買東西排隊時想到,可是一坐上椅子,面對一大堆事情,就又通通都忘了。第三天 7/6 早上買早餐時終於又想起來,於是我不敢再忘,嘴上一直輕唸著直到辦公室,打開電腦,立刻連上空大網站一看:網路選課到昨天截止!天哪!就差十個小時!我趕緊打個電話去台北中心問,電話那一端回答我:真的很抱歉,可是電腦系統已經關起來了,我們也幫不上忙。妳可以在 7/25–7/27 到台北中心加退選,加退選手續費 200 元。

    + +

    昏倒!兩百元是小事,可是就差了十個小時,結局就變成要大老遠跑到台北中心去,而且限那三天才能辦理!忘了差一天,代價竟然這麼高!

    + +

    於是我開始改用一個新的方法做事。我電腦桌面上原本就有一個便條紙檔案,供我隨手記筆記,記下一些事情備忘。我現在每想到要做的事,不管是就要著手去做,還是暫未決定該怎麼做,不管急或不急,重不重要,好不好做,隨時只要想到,就通通都記下來。做完了,再一一刪掉,然後看看清單,挑下一件事來做。這樣一來,強迫自己面對所有還沒做的事,做出一直懸而未決的決定。不用每次一件事情做完,開始發呆,慢慢回憶,盤算接下來要做哪件事,結果漏東漏西。

    + +

    一個星期下來,效率超高。幾年前拍的該整理的照片、伺服器程式該昇級的、該安全檢查的、該做 bug report 的、該整理的檔案、該訂閱的新版通知,通通都做完了。我從來沒有像這個星期,做事情這麼有效率過!一大堆幾年來懸而未決的事,通通都搞定了。

    + +

    就像這個耕讀園的可笑英文 Foreappoint a bright life for the children 。這三張照片其實是去年年初拍攝,打算寫上來的,可是直到這兩天,才整理好,把事情寫上來。還有 Starbucks 的可笑廣告詞 I perfect the drink within your drink. 咖啡宛如藝術 而我 完美了它,也是去年拍的照片,直到現在才附上來。

    + +

    可是一個星期下來,我卻感到前所未有的累。以超高效率做事的代價,就是超累。原本一件事情做完,我會發個呆,看兩則新聞,盤算接下來該做哪件事,也讓自己的腦袋休息一下。可是現在這個休息沒有了。強迫自己一直不斷地做決定、做決定、做決定,不給自己任何拖延的藉口,結果是把自己累垮。我陷入前所未有的疲倦中,無法休息,找不到出路。

    + +

    真的好累。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 27 | + 28 | + 29 | + 30 | + 31 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0030.html.en.html b/htdocs/imacat/me/diary/0030.html.en.html new file mode 120000 index 0000000..12691b6 --- /dev/null +++ b/htdocs/imacat/me/diary/0030.html.en.html @@ -0,0 +1 @@ +0030.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0030.html.en.xhtml b/htdocs/imacat/me/diary/0030.html.en.xhtml new file mode 100644 index 0000000..e650a8a --- /dev/null +++ b/htdocs/imacat/me/diary/0030.html.en.xhtml @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 30 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 30

    + +
    + +
    + +
    +
    7.25.’06. 10:07pm.
    + +

    昨天查真‧三國無雙的資料時,看到另一款遊戲,也是很類似的操作界面和畫面:萬夫莫敵‧聖女傳 Wars and Warriors: Joan of Arc ,以聖女貞德為主角,可以用搖桿,在戰場上跑來跑去。可是它的硬體要求比真‧三國無雙低得多了,只要 Pentium Ⅲ 800 !因為是舊遊戲了,出清價只要 320 !今天趕快去光華商場找,真的被我找到了! Yes! 希望不要讓我失望,呵呵~ ^_*'

    + +
    + +
    + +
    +
    7.25.’06. 9:55pm.
    + +

    小千

    + +

    小千是我的新跟班。

    + +

    小千的全名是千千袋,是我新買的背包。我之前花一百塊,在勝利買的提袋艾蜜莉的魔女袋,雖然魔女艾蜜莉超可愛的,可是沒幾個月內襯就裂開了,原來一個暗袋變成兩個暗袋;又再過一個月,提帶就斷掉了。果然便宜沒好貨。唉!

    + +
    +小魔女艾蜜莉
    +

    小魔女艾蜜莉

    +
    + +

    雖然我個性節檢,東西能用就用,不愛亂買東西,可是東西不能用了,不換也不行。前兩天公館逛著,心裏盤算幾個目標:

    + +
      +
    1. 背包,走路兩手空下來,行動才方便。而且爬山時,側背的提袋會重心不穩,背包空出兩隻手,也比較不會重心不穩。
    2. + +
    3. 至少要放得下五本書,上課、考試可以用。
    4. + +
    5. 堅固耐用。
    6. + +
    7. 可愛,不會太大。這是最重要的
    8. +
    + +

    後來我在一家包包店,找到了小千,花了 399 買下來。小千雖然是背包,可是黑色的牛仔布配上白色的縫線,真得很可愛,不像其它的背包一樣醜。而且背帶上有護墊,還有扣環可以把兩條背帶扣在一起,這樣旅行時被小偷硬拉也拉不掉。唯一的缺點就是拉鍊,小千的開口是拉鍊,要拿東西一定要用兩隻手拉開拉鍊,有時候手上拿東西空不出來,不大方便。

    + +

    不過這都不是小千最神奇的地方。這兩天我逐漸發現一件無敵神奇的事:每當我閒下來,無聊翻翻小千時,都會發現新的暗袋!真是太神奇了!怎麼會有這麼多暗袋呢?好像暗袋永遠翻不完一樣。因為暗袋太多了,我給她取了個名字:千千袋,意指一千個暗袋的意思,暱稱就是小千了~ ^_*'

    + +

    不過這樣想來也挺可怕的。哪一天印章、存摺放進去,結果找不出來怎麼辦?唔,好像是有點嚴重的問題呢。

    + +
    + +
    + +
    +
    7.23.’06. 11:59pm.
    + +

    有一次,去光華商場買東西,買完順便逛逛。逛到一家電視遊樂器店,看到一款遊戲,整個人都被震懾住了。 3D 戰場上有好幾百個士兵正在大混戰,每個士兵都有不同的位置、 3D 動作、人工智慧,主角則拿著長武器到處穿梭,完成使命。好酷的 3D 戰場!這就是真‧三國無雙 4

    + +

    我原本對電視遊樂器的欲望已經冷卻了。畢竟存一萬元買一台 PS2 ,對日常生活這麼忙碌,其實沒什麼時間玩遊戲的我來說,是不大實際的事。真‧三國無雙 4 重新燃起我對電視遊樂器的欲望。如果我真的花錢去買了 PS2 ,一定是為了真‧三國無雙 4 。

    + +

    前一陣子逛電腦商場,看到真‧三國無雙 4 出了 PC 版了。哇哇哇!不過 CPU 基本配備要 1.6GHz ,我想要跑得順的話至少要 2.8GHz ,我現在這台 1.8GHz 的電腦大概沒辦法吧。嗚嗚嗚~

    + +

    好想玩真‧三國無雙 4 啊~~

    + +
    + +
    + +
    +
    7.23.’06. 7:09pm.
    + +

    剛剛想到,今天忘了做一件事:曬綿被。難得天氣這麼好,太陽這麼大,竟然忘了曬綿被!睡到中午,醒來後一直忙著清理廚房、洗刷油污、換壁紙,忙完了都四、五點了,太陽也快下山了。想到明天颱風要登陸,接下來天氣又不知道什麼時候才會轉好轉穩定下來。唉~

    + +
    + +
    + +
    +
    7.23.’06. 6:38pm.
    + +

    一籃三百萬的菜

    + +

    剛電話聽我爸說,各家媒體派 SNG 車, 24 小時日夜守候在民生東路趙建銘邸,阿卿嫂白天市場買菜回來,被媒體團團圍著,問說買了什麼菜。就這樣報了一整天。

    + +

    我記得很久以前,曾經看過一篇報導:一台 SNG 車外派一天,要花掉一百萬元,主要是人造衛星傳輸的租金。假設有三家媒體,三台 SNG 車,就要三百萬。這三百萬用來報導阿卿嫂那一籃菜買了什麼,從企業家精神將本求利的角度來看,表示對媒體老闆來講,那一籃菜有三百萬以上的新聞價值。阿卿嫂原本花了五百塊錢買的菜,創造了三百萬的附加價值。嗯,真是太神奇了。

    + +

    媒體真是神經病。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 28 | + 29 | + 30 | + 31 | + 32 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0030.html.zh-cn.html b/htdocs/imacat/me/diary/0030.html.zh-cn.html new file mode 120000 index 0000000..09812df --- /dev/null +++ b/htdocs/imacat/me/diary/0030.html.zh-cn.html @@ -0,0 +1 @@ +0030.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0030.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0030.html.zh-cn.xhtml new file mode 100644 index 0000000..713a962 --- /dev/null +++ b/htdocs/imacat/me/diary/0030.html.zh-cn.xhtml @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷三十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷三十

    + +
    + +
    + +
    +
    7.25.’06. 10:07pm.
    + +

    昨天查真・三国无双的资料时,看到另一款游戏,也是很类似的操作界面和画面:万夫莫敌・圣女传 Wars and Warriors: Joan of Arc ,以圣女贞德为主角,可以用摇杆,在战场上跑来跑去。可是它的硬体要求比真・三国无双低得多了,只要 Pentium Ⅲ 800 !因为是旧游戏了,出清价只要 320 !今天赶快去光华商场找,真的被我找到了! Yes! 希望不要让我失望,呵呵~ ^_*'

    + +
    + +
    + +
    +
    7.25.’06. 9:55pm.
    + +

    小千

    + +

    小千是我的新跟班。

    + +

    小千的全名是千千袋,是我新买的背包。我之前花一百块,在胜利买的提袋艾蜜莉的魔女袋,虽然魔女艾蜜莉超可爱的,可是没几个月内衬就裂开了,原来一个暗袋变成两个暗袋;又再过一个月,提带就断掉了。果然便宜没好货。唉!

    + +
    +小魔女艾蜜莉
    +

    小魔女艾蜜莉

    +
    + +

    虽然我个性节检,东西能用就用,不爱乱买东西,可是东西不能用了,不换也不行。前两天公馆逛著,心里盘算几个目标:

    + +
      +
    1. 背包,走路两手空下来,行动才方便。而且爬山时,侧背的提袋会重心不稳,背包空出两只手,也比较不会重心不稳。
    2. + +
    3. 至少要放得下五本书,上课、考试可以用。
    4. + +
    5. 坚固耐用。
    6. + +
    7. 可爱,不会太大。这是最重要的
    8. +
    + +

    后来我在一家包包店,找到了小千,花了 399 买下来。小千虽然是背包,可是黑色的牛仔布配上白色的缝线,真得很可爱,不像其它的背包一样丑。而且背带上有护垫,还有扣环可以把两条背带扣在一起,这样旅行时被小偷硬拉也拉不掉。唯一的缺点就是拉炼,小千的开口是拉炼,要拿东西一定要用两只手拉开拉炼,有时候手上拿东西空不出来,不大方便。

    + +

    不过这都不是小千最神奇的地方。这两天我逐渐发现一件无敌神奇的事:每当我闲下来,无聊翻翻小千时,都会发现新的暗袋!真是太神奇了!怎么会有这么多暗袋呢?好像暗袋永远翻不完一样。因为暗袋太多了,我给她取了个名字:千千袋,意指一千个暗袋的意思,昵称就是小千了~ ^_*'

    + +

    不过这样想来也挺可怕的。哪一天印章、存摺放进去,结果找不出来怎么办?唔,好像是有点严重的问题呢。

    + +
    + +
    + +
    +
    7.23.’06. 11:59pm.
    + +

    有一次,去光华商场买东西,买完顺便逛逛。逛到一家电视游乐器店,看到一款游戏,整个人都被震慑住了。 3D 战场上有好几百个士兵正在大混战,每个士兵都有不同的位置、 3D 动作、人工智慧,主角则拿著长武器到处穿梭,完成使命。好酷的 3D 战场!这就是真・三国无双 4

    + +

    我原本对电视游乐器的欲望已经冷却了。毕竟存一万元买一台 PS2 ,对日常生活这么忙碌,其实没什么时间玩游戏的我来说,是不大实际的事。真・三国无双 4 重新燃起我对电视游乐器的欲望。如果我真的花钱去买了 PS2 ,一定是为了真・三国无双 4 。

    + +

    前一阵子逛电脑商场,看到真・三国无双 4 出了 PC 版了。哇哇哇!不过 CPU 基本配备要 1.6GHz ,我想要跑得顺的话至少要 2.8GHz ,我现在这台 1.8GHz 的电脑大概没办法吧。呜呜呜~

    + +

    好想玩真・三国无双 4 啊~~

    + +
    + +
    + +
    +
    7.23.’06. 7:09pm.
    + +

    刚刚想到,今天忘了做一件事:晒绵被。难得天气这么好,太阳这么大,竟然忘了晒绵被!睡到中午,醒来后一直忙著清理厨房、洗刷油污、换壁纸,忙完了都四、五点了,太阳也快下山了。想到明天台风要登陆,接下来天气又不知道什么时候才会转好转稳定下来。唉~

    + +
    + +
    + +
    +
    7.23.’06. 6:38pm.
    + +

    一篮三百万的菜

    + +

    刚电话听我爸说,各家媒体派 SNG 车, 24 小时日夜守候在民生东路赵建铭邸,阿卿嫂白天市场买菜回来,被媒体团团围著,问说买了什么菜。就这样报了一整天。

    + +

    我记得很久以前,曾经看过一篇报导:一台 SNG 车外派一天,要花掉一百万元,主要是人造卫星传输的租金。假设有三家媒体,三台 SNG 车,就要三百万。这三百万用来报导阿卿嫂那一篮菜买了什么,从企业家精神将本求利的角度来看,表示对媒体老板来讲,那一篮菜有三百万以上的新闻价值。阿卿嫂原本花了五百块钱买的菜,创造了三百万的附加价值。嗯,真是太神奇了。

    + +

    媒体真是神经病。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 28 | + 29 | + 30 | + 31 | + 32 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0030.html.zh-tw.html b/htdocs/imacat/me/diary/0030.html.zh-tw.html new file mode 120000 index 0000000..147b939 --- /dev/null +++ b/htdocs/imacat/me/diary/0030.html.zh-tw.html @@ -0,0 +1 @@ +0030.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0030.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0030.html.zh-tw.xhtml new file mode 100644 index 0000000..16715a0 --- /dev/null +++ b/htdocs/imacat/me/diary/0030.html.zh-tw.xhtml @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷三十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷三十

    + +
    + +
    + +
    +
    7.25.’06. 10:07pm.
    + +

    昨天查真‧三國無雙的資料時,看到另一款遊戲,也是很類似的操作界面和畫面:萬夫莫敵‧聖女傳 Wars and Warriors: Joan of Arc ,以聖女貞德為主角,可以用搖桿,在戰場上跑來跑去。可是它的硬體要求比真‧三國無雙低得多了,只要 Pentium Ⅲ 800 !因為是舊遊戲了,出清價只要 320 !今天趕快去光華商場找,真的被我找到了! Yes! 希望不要讓我失望,呵呵~ ^_*'

    + +
    + +
    + +
    +
    7.25.’06. 9:55pm.
    + +

    小千

    + +

    小千是我的新跟班。

    + +

    小千的全名是千千袋,是我新買的背包。我之前花一百塊,在勝利買的提袋艾蜜莉的魔女袋,雖然魔女艾蜜莉超可愛的,可是沒幾個月內襯就裂開了,原來一個暗袋變成兩個暗袋;又再過一個月,提帶就斷掉了。果然便宜沒好貨。唉!

    + +
    +小魔女艾蜜莉
    +

    小魔女艾蜜莉

    +
    + +

    雖然我個性節檢,東西能用就用,不愛亂買東西,可是東西不能用了,不換也不行。前兩天公館逛著,心裏盤算幾個目標:

    + +
      +
    1. 背包,走路兩手空下來,行動才方便。而且爬山時,側背的提袋會重心不穩,背包空出兩隻手,也比較不會重心不穩。
    2. + +
    3. 至少要放得下五本書,上課、考試可以用。
    4. + +
    5. 堅固耐用。
    6. + +
    7. 可愛,不會太大。這是最重要的
    8. +
    + +

    後來我在一家包包店,找到了小千,花了 399 買下來。小千雖然是背包,可是黑色的牛仔布配上白色的縫線,真得很可愛,不像其它的背包一樣醜。而且背帶上有護墊,還有扣環可以把兩條背帶扣在一起,這樣旅行時被小偷硬拉也拉不掉。唯一的缺點就是拉鍊,小千的開口是拉鍊,要拿東西一定要用兩隻手拉開拉鍊,有時候手上拿東西空不出來,不大方便。

    + +

    不過這都不是小千最神奇的地方。這兩天我逐漸發現一件無敵神奇的事:每當我閒下來,無聊翻翻小千時,都會發現新的暗袋!真是太神奇了!怎麼會有這麼多暗袋呢?好像暗袋永遠翻不完一樣。因為暗袋太多了,我給她取了個名字:千千袋,意指一千個暗袋的意思,暱稱就是小千了~ ^_*'

    + +

    不過這樣想來也挺可怕的。哪一天印章、存摺放進去,結果找不出來怎麼辦?唔,好像是有點嚴重的問題呢。

    + +
    + +
    + +
    +
    7.23.’06. 11:59pm.
    + +

    有一次,去光華商場買東西,買完順便逛逛。逛到一家電視遊樂器店,看到一款遊戲,整個人都被震懾住了。 3D 戰場上有好幾百個士兵正在大混戰,每個士兵都有不同的位置、 3D 動作、人工智慧,主角則拿著長武器到處穿梭,完成使命。好酷的 3D 戰場!這就是真‧三國無雙 4

    + +

    我原本對電視遊樂器的欲望已經冷卻了。畢竟存一萬元買一台 PS2 ,對日常生活這麼忙碌,其實沒什麼時間玩遊戲的我來說,是不大實際的事。真‧三國無雙 4 重新燃起我對電視遊樂器的欲望。如果我真的花錢去買了 PS2 ,一定是為了真‧三國無雙 4 。

    + +

    前一陣子逛電腦商場,看到真‧三國無雙 4 出了 PC 版了。哇哇哇!不過 CPU 基本配備要 1.6GHz ,我想要跑得順的話至少要 2.8GHz ,我現在這台 1.8GHz 的電腦大概沒辦法吧。嗚嗚嗚~

    + +

    好想玩真‧三國無雙 4 啊~~

    + +
    + +
    + +
    +
    7.23.’06. 7:09pm.
    + +

    剛剛想到,今天忘了做一件事:曬綿被。難得天氣這麼好,太陽這麼大,竟然忘了曬綿被!睡到中午,醒來後一直忙著清理廚房、洗刷油污、換壁紙,忙完了都四、五點了,太陽也快下山了。想到明天颱風要登陸,接下來天氣又不知道什麼時候才會轉好轉穩定下來。唉~

    + +
    + +
    + +
    +
    7.23.’06. 6:38pm.
    + +

    一籃三百萬的菜

    + +

    剛電話聽我爸說,各家媒體派 SNG 車, 24 小時日夜守候在民生東路趙建銘邸,阿卿嫂白天市場買菜回來,被媒體團團圍著,問說買了什麼菜。就這樣報了一整天。

    + +

    我記得很久以前,曾經看過一篇報導:一台 SNG 車外派一天,要花掉一百萬元,主要是人造衛星傳輸的租金。假設有三家媒體,三台 SNG 車,就要三百萬。這三百萬用來報導阿卿嫂那一籃菜買了什麼,從企業家精神將本求利的角度來看,表示對媒體老闆來講,那一籃菜有三百萬以上的新聞價值。阿卿嫂原本花了五百塊錢買的菜,創造了三百萬的附加價值。嗯,真是太神奇了。

    + +

    媒體真是神經病。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 28 | + 29 | + 30 | + 31 | + 32 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0031.html.en.html b/htdocs/imacat/me/diary/0031.html.en.html new file mode 120000 index 0000000..a6f5f80 --- /dev/null +++ b/htdocs/imacat/me/diary/0031.html.en.html @@ -0,0 +1 @@ +0031.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0031.html.en.xhtml b/htdocs/imacat/me/diary/0031.html.en.xhtml new file mode 100644 index 0000000..65d9d04 --- /dev/null +++ b/htdocs/imacat/me/diary/0031.html.en.xhtml @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 31 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 31

    + +
    + +
    + +
    +
    8.2.’06. 11:35pm.
    + +

    沙漠之鷹

    + +

    我是一個武器迷,從小就著迷於各種槍械刀劍。喜歡刀劍,多過槍械一些。

    + +

    今天讀到自由時報社會版的維安特勤 終極武器,提到維安特勤隊的新武器 AWP 狙擊槍。為了瞭解這是什麼槍,我上網搜尋了一下。找到了一個Counter-Strike 反恐精英的網頁,提到了沙漠之鷹。想到這把傳說中的巨槍,興之所至,我又上網找了一些沙漠之鷹的資料。

    + +
    +沙漠之鷹 Desert Eagle
    +

    沙漠之鷹 Desert Eagle

    +
    + +

    以色列麥格儂出品的沙漠之鷹 Desert Eagle,是現在世界上體型最大、威力也最大的巨型手槍,在漫畫、電影中常常可以看得到,只要提到威力強大的手槍,一定就是沙漠之鷹。在漫畫中常常提到,它的後座力很強,一定要兩手握槍,若不是手臂特別孔武有力,或是受過專業訓練者,根本就無法使用,只要開一槍就足以讓手臂脫臼。至於能單手擊發沙漠之鷹者,則是腕力強勁、神乎其技的象徵。

    + +

    印象中,日本漫畫裏有兩個女生,能夠單手擊發沙漠之鷹:一個是GTO 麻辣教師的作者藤沢亨最近的作品麻辣野玫瑰 ROSE HIP裏的女主角,是一個以高中生為主的恐怖份子團體,退出該團體而加入反恐特勤隊的精英,因為曾在恐怖組織受過地獄訓練,雖然是高中生,卻能夠單手擊發沙漠之鷹;另一個是城市獵人 CITY HUNTER シティーハンター的作者北條司的新作天使心 Angel Heart エンジェルハート裏,女主角冴羽獠的乾女兒香瑩,之前是台灣黑道正道會的頭號殺手,受過嚴酷的殺手訓練,所以能夠單手擊發沙漠之鷹。

    + +

    雖然感覺上是很酷的一把巨型手槍,不管體積還是威力都是超級的。可是現實上應該沒有那麼好用吧。一把那麼大的槍,衣服裏藏不下;後座力那麼強,光擊發就要花很大的力氣。除了超強的威力外,其它的性能平平。會真的著迷到一定要用這種槍的人,應該是有很強的陽具情結吧。嗯嗯。

    + +
    + +
    + +
    +
    7.29.’06. 2:52pm.
    + +

    小千的照片

    + +

    小千的照片。數數看光從外表看,可以看得到幾個夾層和暗袋?

    + +
    +小千—一千個暗袋的可愛背包
    +

    小千—一千個暗袋的可愛背包

    +
    + +
    +小千的無敵神奇裝置—耳機線孔
    +

    小千的無敵神奇裝置—耳機線孔

    +
    + +
    + +
    + +
    +
    7.27.’06. 11:48pm.
    + +

    我下載了百戰天龍的第一集,發現什麼馬蓋先由於在小孩時代的一次槍走火的事故,從此不喜歡帶任何的槍,根本就是騙人的。馬蓋先第一集一開始就開過槍了,雖然只有短短幾秒,不過開過槍就開過槍,根本不是什麼兒時陰影。哼哼。

    + +
    + +
    + +
    +
    7.27.’06. 2:19am.
    + +

    今天又發現小千一件超神奇的事。

    + +

    中午走進附近的餐館,點了菜,等待的時候,我又拿起小千來玩。我注意到右上方有一個小破洞。切口非常整齊,像是裁縫剪刀剪的。我心想:難怪只賣 399 ,這麼便宜,原來是不小心剪破的暇疵品。不過有點奇怪,破口上用了個橡膠環套起來。為什麼要做這種事?這是什麼意思?想了一會還是想不通。直到後來,我注意到橡膠環上的耳機圖案—原來如此!這是耳機洞,把隨身聽放進背包裏,耳機可以穿過這個洞,把隨身聽或 MP3 接出來聽!

    + +

    竟然還有這種特別的設計,真是太神奇了~! ^_*'

    + +
    + +
    + +
    +
    7.26.’06. 12:23pm.
    + +

    玩了一晚的萬夫莫敵‧聖女傳,忘了我最討厭的就是 3D 遊戲。方向感混亂,噁心、心悸了一整晚。心裏想著這是我特地去買來玩的,一定要想辦法克服。忍到了一點半,終於受不了,跑去睡了。

    + +

    不過還是覺得好酷~!真的有英軍攻城,在奧爾良市區巷戰耶!比起末日危城龐大得多的場面,好酷~ ^_*'

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 29 | + 30 | + 31 | + 32 | + 33 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0031.html.zh-cn.html b/htdocs/imacat/me/diary/0031.html.zh-cn.html new file mode 120000 index 0000000..2557500 --- /dev/null +++ b/htdocs/imacat/me/diary/0031.html.zh-cn.html @@ -0,0 +1 @@ +0031.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0031.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0031.html.zh-cn.xhtml new file mode 100644 index 0000000..66ed9d6 --- /dev/null +++ b/htdocs/imacat/me/diary/0031.html.zh-cn.xhtml @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷三十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷三十一

    + +
    + +
    + +
    +
    8.2.’06. 11:35pm.
    + +

    沙漠之鹰

    + +

    我是一个武器迷,从小就著迷於各种枪械刀剑。喜欢刀剑,多过枪械一些。

    + +

    今天读到自由时报社会版的维安特勤 终极武器,提到维安特勤队的新武器 AWP 狙击枪。为了了解这是什么枪,我上网搜寻了一下。找到了一个Counter-Strike 反恐精英的网页,提到了沙漠之鹰。想到这把传说中的巨枪,兴之所至,我又上网找了一些沙漠之鹰的资料。

    + +
    +沙漠之鹰 Desert Eagle
    +

    沙漠之鹰 Desert Eagle

    +
    + +

    以色列麦格侬出品的沙漠之鹰 Desert Eagle,是现在世界上体型最大、威力也最大的巨型手枪,在漫画、电影中常常可以看得到,只要提到威力强大的手枪,一定就是沙漠之鹰。在漫画中常常提到,它的后座力很强,一定要两手握枪,若不是手臂特别孔武有力,或是受过专业训练者,根本就无法使用,只要开一枪就足以让手臂脱臼。至於能单手击发沙漠之鹰者,则是腕力强劲、神乎其技的象徵。

    + +

    印象中,日本漫画里有两个女生,能够单手击发沙漠之鹰:一个是GTO 麻辣教师的作者藤沢亨最近的作品麻辣野玫瑰 ROSE HIP里的女主角,是一个以高中生为主的恐怖份子团体,退出该团体而加入反恐特勤队的精英,因为曾在恐怖组织受过地狱训练,虽然是高中生,却能够单手击发沙漠之鹰;另一个是城市猎人 CITY HUNTER シティーハンター的作者北条司的新作天使心 Angel Heart エンジェルハート里,女主角冴羽獠的干女儿香莹,之前是台湾黑道正道会的头号杀手,受过严酷的杀手训练,所以能够单手击发沙漠之鹰。

    + +

    虽然感觉上是很酷的一把巨型手枪,不管体积还是威力都是超级的。可是现实上应该没有那么好用吧。一把那么大的枪,衣服里藏不下;后座力那么强,光击发就要花很大的力气。除了超强的威力外,其它的性能平平。会真的著迷到一定要用这种枪的人,应该是有很强的阳具情结吧。嗯嗯。

    + +
    + +
    + +
    +
    7.29.’06. 2:52pm.
    + +

    小千的照片

    + +

    小千的照片。数数看光从外表看,可以看得到几个夹层和暗袋?

    + +
    +小千—一千个暗袋的可爱背包
    +

    小千—一千个暗袋的可爱背包

    +
    + +
    +小千的无敌神奇装置—耳机线孔
    +

    小千的无敌神奇装置—耳机线孔

    +
    + +
    + +
    + +
    +
    7.27.’06. 11:48pm.
    + +

    我下载了百战天龙的第一集,发现什么马盖先由於在小孩时代的一次枪走火的事故,从此不喜欢带任何的枪,根本就是骗人的。马盖先第一集一开始就开过枪了,虽然只有短短几秒,不过开过枪就开过枪,根本不是什么儿时阴影。哼哼。

    + +
    + +
    + +
    +
    7.27.’06. 2:19am.
    + +

    今天又发现小千一件超神奇的事。

    + +

    中午走进附近的餐馆,点了菜,等待的时候,我又拿起小千来玩。我注意到右上方有一个小破洞。切口非常整齐,像是裁缝剪刀剪的。我心想:难怪只卖 399 ,这么便宜,原来是不小心剪破的暇疵品。不过有点奇怪,破口上用了个橡胶环套起来。为什么要做这种事?这是什么意思?想了一会还是想不通。直到后来,我注意到橡胶环上的耳机图案—原来如此!这是耳机洞,把随身听放进背包里,耳机可以穿过这个洞,把随身听或 MP3 接出来听!

    + +

    竟然还有这种特别的设计,真是太神奇了~! ^_*'

    + +
    + +
    + +
    +
    7.26.’06. 12:23pm.
    + +

    玩了一晚的万夫莫敌・圣女传,忘了我最讨厌的就是 3D 游戏。方向感混乱,恶心、心悸了一整晚。心里想著这是我特地去买来玩的,一定要想办法克服。忍到了一点半,终於受不了,跑去睡了。

    + +

    不过还是觉得好酷~!真的有英军攻城,在奥尔良市区巷战耶!比起末日危城庞大得多的场面,好酷~ ^_*'

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 29 | + 30 | + 31 | + 32 | + 33 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0031.html.zh-tw.html b/htdocs/imacat/me/diary/0031.html.zh-tw.html new file mode 120000 index 0000000..2cb1030 --- /dev/null +++ b/htdocs/imacat/me/diary/0031.html.zh-tw.html @@ -0,0 +1 @@ +0031.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0031.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0031.html.zh-tw.xhtml new file mode 100644 index 0000000..a1e2745 --- /dev/null +++ b/htdocs/imacat/me/diary/0031.html.zh-tw.xhtml @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷三十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷三十一

    + +
    + +
    + +
    +
    8.2.’06. 11:35pm.
    + +

    沙漠之鷹

    + +

    我是一個武器迷,從小就著迷於各種槍械刀劍。喜歡刀劍,多過槍械一些。

    + +

    今天讀到自由時報社會版的維安特勤 終極武器,提到維安特勤隊的新武器 AWP 狙擊槍。為了瞭解這是什麼槍,我上網搜尋了一下。找到了一個Counter-Strike 反恐精英的網頁,提到了沙漠之鷹。想到這把傳說中的巨槍,興之所至,我又上網找了一些沙漠之鷹的資料。

    + +
    +沙漠之鷹 Desert Eagle
    +

    沙漠之鷹 Desert Eagle

    +
    + +

    以色列麥格儂出品的沙漠之鷹 Desert Eagle,是現在世界上體型最大、威力也最大的巨型手槍,在漫畫、電影中常常可以看得到,只要提到威力強大的手槍,一定就是沙漠之鷹。在漫畫中常常提到,它的後座力很強,一定要兩手握槍,若不是手臂特別孔武有力,或是受過專業訓練者,根本就無法使用,只要開一槍就足以讓手臂脫臼。至於能單手擊發沙漠之鷹者,則是腕力強勁、神乎其技的象徵。

    + +

    印象中,日本漫畫裏有兩個女生,能夠單手擊發沙漠之鷹:一個是GTO 麻辣教師的作者藤沢亨最近的作品麻辣野玫瑰 ROSE HIP裏的女主角,是一個以高中生為主的恐怖份子團體,退出該團體而加入反恐特勤隊的精英,因為曾在恐怖組織受過地獄訓練,雖然是高中生,卻能夠單手擊發沙漠之鷹;另一個是城市獵人 CITY HUNTER シティーハンター的作者北條司的新作天使心 Angel Heart エンジェルハート裏,女主角冴羽獠的乾女兒香瑩,之前是台灣黑道正道會的頭號殺手,受過嚴酷的殺手訓練,所以能夠單手擊發沙漠之鷹。

    + +

    雖然感覺上是很酷的一把巨型手槍,不管體積還是威力都是超級的。可是現實上應該沒有那麼好用吧。一把那麼大的槍,衣服裏藏不下;後座力那麼強,光擊發就要花很大的力氣。除了超強的威力外,其它的性能平平。會真的著迷到一定要用這種槍的人,應該是有很強的陽具情結吧。嗯嗯。

    + +
    + +
    + +
    +
    7.29.’06. 2:52pm.
    + +

    小千的照片

    + +

    小千的照片。數數看光從外表看,可以看得到幾個夾層和暗袋?

    + +
    +小千—一千個暗袋的可愛背包
    +

    小千—一千個暗袋的可愛背包

    +
    + +
    +小千的無敵神奇裝置—耳機線孔
    +

    小千的無敵神奇裝置—耳機線孔

    +
    + +
    + +
    + +
    +
    7.27.’06. 11:48pm.
    + +

    我下載了百戰天龍的第一集,發現什麼馬蓋先由於在小孩時代的一次槍走火的事故,從此不喜歡帶任何的槍,根本就是騙人的。馬蓋先第一集一開始就開過槍了,雖然只有短短幾秒,不過開過槍就開過槍,根本不是什麼兒時陰影。哼哼。

    + +
    + +
    + +
    +
    7.27.’06. 2:19am.
    + +

    今天又發現小千一件超神奇的事。

    + +

    中午走進附近的餐館,點了菜,等待的時候,我又拿起小千來玩。我注意到右上方有一個小破洞。切口非常整齊,像是裁縫剪刀剪的。我心想:難怪只賣 399 ,這麼便宜,原來是不小心剪破的暇疵品。不過有點奇怪,破口上用了個橡膠環套起來。為什麼要做這種事?這是什麼意思?想了一會還是想不通。直到後來,我注意到橡膠環上的耳機圖案—原來如此!這是耳機洞,把隨身聽放進背包裏,耳機可以穿過這個洞,把隨身聽或 MP3 接出來聽!

    + +

    竟然還有這種特別的設計,真是太神奇了~! ^_*'

    + +
    + +
    + +
    +
    7.26.’06. 12:23pm.
    + +

    玩了一晚的萬夫莫敵‧聖女傳,忘了我最討厭的就是 3D 遊戲。方向感混亂,噁心、心悸了一整晚。心裏想著這是我特地去買來玩的,一定要想辦法克服。忍到了一點半,終於受不了,跑去睡了。

    + +

    不過還是覺得好酷~!真的有英軍攻城,在奧爾良市區巷戰耶!比起末日危城龐大得多的場面,好酷~ ^_*'

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 29 | + 30 | + 31 | + 32 | + 33 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0032.html.en.html b/htdocs/imacat/me/diary/0032.html.en.html new file mode 120000 index 0000000..7ae8fe6 --- /dev/null +++ b/htdocs/imacat/me/diary/0032.html.en.html @@ -0,0 +1 @@ +0032.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0032.html.en.xhtml b/htdocs/imacat/me/diary/0032.html.en.xhtml new file mode 100644 index 0000000..79de9b3 --- /dev/null +++ b/htdocs/imacat/me/diary/0032.html.en.xhtml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 32 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 32

    + +
    + +
    + +
    +
    8.3.’06. 0:12am.
    + +

    O記三合會檔案—香港黑幫史詩

    + +
    +O記三合會檔案
    +

    O記三合會檔案

    +
    + +
      +
    • 片名:O記三合會檔案
    • +
    • 英文片名: The HK Triad
    • +
    • 發行年份: 1999
    • +
    • 製作公司:最佳拍檔有限公司 BOB & Partners Co. Ltd.
    • +
    • 編劇、製作:王晶
    • +
    • 導演:霍耀良
    • +
    • 演員: +
        +
      • 劉青雲:阿豪
      • +
      • 吳鎮宇:阿樂
      • +
      • 朱茵:阿樂之妻菲菲
      • +
      • 彭丹:阿豪之妻阿英
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    前兩天,跟朋友聊天聊到香港六、七零年代的四大探長,興之所至,上網找了一些香港六、七零年代四大探長時代的相關資料。讀了一些討論與介紹,注意到了兩部電影:一個字頭的誕生O記三合會檔案。我感到有點好奇,於是就想辦法,上網找來看。

    + +

    我還沒看一個字頭的誕生,不過已經看完了O記三合會檔案了。O記三合會檔案,這個片名對我完全沒有吸引力,看到就不想看。大概是我不懂粵語O記是什麼意思吧。

    + +

    可是看完了以後,真的超感動的。O記三合會檔案像一部史詩。兩個主角阿豪和阿樂,名字影射那個時代香港黑道和警界的兩個大亨—黑道梟雄跛豪和四大探長之首呂樂,不過僅止於此。他們兩個人的故事,和跛豪和呂樂的生平豪不相關,而是當時整個香港黑道和警界的縮影。兩個情同手足的兄弟,阿豪進入黑社會,當了老大;阿樂進了警隊,當了探長。兩人聯手,在九龍呼風喚雨,隻手遮天。以阿豪象徵當時香港的黑社會,阿樂象徵當時的警察,兩個情同手足,一起隻手遮天的兄弟,來象徵當時香港的黑社會和警察的關係。而兩個人呼風喚雨的日子,也因七零年代初廉政公署的成立而告終。片末一人死亡,一人落敗,曲終人散,象徵一個時代的終結。

    + +

    整部電影象徵的意象非常強烈清晰,像史詩一樣,輕緩的節奏,陳述著五零年代到七零年代香港九龍城寨的歷史。真的好棒的一部電影。

    + +

    補充

    + +
    8.13.’06. 0:52am.
    + +

    剛剛上網查,原來O記三合會檔案O記,是有組織罪案及三合會調查科的簡稱。 O 應該是 Organizational 有組織的意思吧。

    + +
    8.14.’06. 1:58am.
    + +

    我必須誠懇地說,王晶的O記三合會檔案,比杜琪峰的黑社會,好看得多。王晶的O記三合會檔案擁有像史詩一樣的架構,讓人看完後仍不住低吟一個傳奇的時代;而杜琪峰的黑社會,不過是滿足不瞭解中式黑社會的西方人,偷窺神秘東方三合會真面目的好奇心而已。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 30 | + 31 | + 32 | + 33 | + 34 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0032.html.zh-cn.html b/htdocs/imacat/me/diary/0032.html.zh-cn.html new file mode 120000 index 0000000..8ddcb8c --- /dev/null +++ b/htdocs/imacat/me/diary/0032.html.zh-cn.html @@ -0,0 +1 @@ +0032.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0032.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0032.html.zh-cn.xhtml new file mode 100644 index 0000000..4d2d497 --- /dev/null +++ b/htdocs/imacat/me/diary/0032.html.zh-cn.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷三十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷三十二

    + +
    + +
    + +
    +
    8.3.’06. 0:12am.
    + +

    O记三合会档案—香港黑帮史诗

    + +
    +O记三合会档案
    +

    O记三合会档案

    +
    + +
      +
    • 片名:O记三合会档案
    • +
    • 英文片名: The HK Triad
    • +
    • 发行年份: 1999
    • +
    • 制作公司:最佳拍档有限公司 BOB & Partners Co. Ltd.
    • +
    • 编剧、制作:王晶
    • +
    • 导演:霍耀良
    • +
    • 演员: +
        +
      • 刘青云:阿豪
      • +
      • 吴镇宇:阿乐
      • +
      • 朱茵:阿乐之妻菲菲
      • +
      • 彭丹:阿豪之妻阿英
      • +
      +
    • +
    • 推荐影评: + +
    • +
    + +

    前两天,跟朋友聊天聊到香港六、七零年代的四大探长,兴之所至,上网找了一些香港六、七零年代四大探长时代的相关资料。读了一些讨论与介绍,注意到了两部电影:一个字头的诞生O记三合会档案。我感到有点好奇,於是就想办法,上网找来看。

    + +

    我还没看一个字头的诞生,不过已经看完了O记三合会档案了。O记三合会档案,这个片名对我完全没有吸引力,看到就不想看。大概是我不懂粤语O记是什么意思吧。

    + +

    可是看完了以后,真的超感动的。O记三合会档案像一部史诗。两个主角阿豪和阿乐,名字影射那个时代香港黑道和警界的两个大亨—黑道枭雄跛豪和四大探长之首吕乐,不过仅止於此。他们两个人的故事,和跛豪和吕乐的生平豪不相关,而是当时整个香港黑道和警界的缩影。两个情同手足的兄弟,阿豪进入黑社会,当了老大;阿乐进了警队,当了探长。两人联手,在九龙呼风唤雨,只手遮天。以阿豪象徵当时香港的黑社会,阿乐象徵当时的警察,两个情同手足,一起只手遮天的兄弟,来象徵当时香港的黑社会和警察的关系。而两个人呼风唤雨的日子,也因七零年代初廉政公署的成立而告终。片末一人死亡,一人落败,曲终人散,象徵一个时代的终结。

    + +

    整部电影象徵的意象非常强烈清晰,像史诗一样,轻缓的节奏,陈述著五零年代到七零年代香港九龙城寨的历史。真的好棒的一部电影。

    + +

    补充

    + +
    8.13.’06. 0:52am.
    + +

    刚刚上网查,原来O记三合会档案O记,是有组织罪案及三合会调查科的简称。 O 应该是 Organizational 有组织的意思吧。

    + +
    8.14.’06. 1:58am.
    + +

    我必须诚恳地说,王晶的O记三合会档案,比杜琪峰的黑社会,好看得多。王晶的O记三合会档案拥有像史诗一样的架构,让人看完后仍不住低吟一个传奇的时代;而杜琪峰的黑社会,不过是满足不了解中式黑社会的西方人,偷窥神秘东方三合会真面目的好奇心而已。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 30 | + 31 | + 32 | + 33 | + 34 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0032.html.zh-tw.html b/htdocs/imacat/me/diary/0032.html.zh-tw.html new file mode 120000 index 0000000..1e00ff4 --- /dev/null +++ b/htdocs/imacat/me/diary/0032.html.zh-tw.html @@ -0,0 +1 @@ +0032.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0032.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0032.html.zh-tw.xhtml new file mode 100644 index 0000000..3c040e4 --- /dev/null +++ b/htdocs/imacat/me/diary/0032.html.zh-tw.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷三十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷三十二

    + +
    + +
    + +
    +
    8.3.’06. 0:12am.
    + +

    O記三合會檔案—香港黑幫史詩

    + +
    +O記三合會檔案
    +

    O記三合會檔案

    +
    + +
      +
    • 片名:O記三合會檔案
    • +
    • 英文片名: The HK Triad
    • +
    • 發行年份: 1999
    • +
    • 製作公司:最佳拍檔有限公司 BOB & Partners Co. Ltd.
    • +
    • 編劇、製作:王晶
    • +
    • 導演:霍耀良
    • +
    • 演員: +
        +
      • 劉青雲:阿豪
      • +
      • 吳鎮宇:阿樂
      • +
      • 朱茵:阿樂之妻菲菲
      • +
      • 彭丹:阿豪之妻阿英
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    前兩天,跟朋友聊天聊到香港六、七零年代的四大探長,興之所至,上網找了一些香港六、七零年代四大探長時代的相關資料。讀了一些討論與介紹,注意到了兩部電影:一個字頭的誕生O記三合會檔案。我感到有點好奇,於是就想辦法,上網找來看。

    + +

    我還沒看一個字頭的誕生,不過已經看完了O記三合會檔案了。O記三合會檔案,這個片名對我完全沒有吸引力,看到就不想看。大概是我不懂粵語O記是什麼意思吧。

    + +

    可是看完了以後,真的超感動的。O記三合會檔案像一部史詩。兩個主角阿豪和阿樂,名字影射那個時代香港黑道和警界的兩個大亨—黑道梟雄跛豪和四大探長之首呂樂,不過僅止於此。他們兩個人的故事,和跛豪和呂樂的生平豪不相關,而是當時整個香港黑道和警界的縮影。兩個情同手足的兄弟,阿豪進入黑社會,當了老大;阿樂進了警隊,當了探長。兩人聯手,在九龍呼風喚雨,隻手遮天。以阿豪象徵當時香港的黑社會,阿樂象徵當時的警察,兩個情同手足,一起隻手遮天的兄弟,來象徵當時香港的黑社會和警察的關係。而兩個人呼風喚雨的日子,也因七零年代初廉政公署的成立而告終。片末一人死亡,一人落敗,曲終人散,象徵一個時代的終結。

    + +

    整部電影象徵的意象非常強烈清晰,像史詩一樣,輕緩的節奏,陳述著五零年代到七零年代香港九龍城寨的歷史。真的好棒的一部電影。

    + +

    補充

    + +
    8.13.’06. 0:52am.
    + +

    剛剛上網查,原來O記三合會檔案O記,是有組織罪案及三合會調查科的簡稱。 O 應該是 Organizational 有組織的意思吧。

    + +
    8.14.’06. 1:58am.
    + +

    我必須誠懇地說,王晶的O記三合會檔案,比杜琪峰的黑社會,好看得多。王晶的O記三合會檔案擁有像史詩一樣的架構,讓人看完後仍不住低吟一個傳奇的時代;而杜琪峰的黑社會,不過是滿足不瞭解中式黑社會的西方人,偷窺神秘東方三合會真面目的好奇心而已。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 30 | + 31 | + 32 | + 33 | + 34 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0033.html.en.html b/htdocs/imacat/me/diary/0033.html.en.html new file mode 120000 index 0000000..80df183 --- /dev/null +++ b/htdocs/imacat/me/diary/0033.html.en.html @@ -0,0 +1 @@ +0033.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0033.html.en.xhtml b/htdocs/imacat/me/diary/0033.html.en.xhtml new file mode 100644 index 0000000..dd3932f --- /dev/null +++ b/htdocs/imacat/me/diary/0033.html.en.xhtml @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 33 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 33

    + +
    + +
    + +
    +
    8.4.’06. 3:10pm.
    + +

    UPS 不斷電系統

    + +

    家裏有網路。有網路就會想要 UPS 不斷電系統。總不會希望夏天電力時好時壞,偶爾就來個瞬斷,硬碟讀寫頭重重敲上磁盤,壽命都減了一半。

    + +

    很久以前剛架好家裏網路時,我買了飛瑞的不斷電系統 A-500A-1000 。飛瑞是台灣的公司,在不斷電系統市場上,走低價位的路線,連光華商場都買得到,算是便宜的選擇。其間斷電過幾次,不到兩、三年就壞了。而且壞掉以後,警報器還一直吵個不停,吵得我不能睡覺,直到我把它電源拔掉,所有電線重新插換為止。這種關鍵時刻完全沒有用的便宜貨,我完全死心了。那以後好一段時間,我沒有再管 UPS 的事。

    + +

    公司用的 UPSAPCSmart UPS 3000 。聽老闆說十年前買的時候很貴,而且在台灣從來沒有看過這個牌子,我猜可能是頂級網路環境專用的,要有門道才買得到,所以雖然很想買,可是連價錢都不知道,不得其門而入。

    + +

    這兩天公司的 UPS 電池壞了,為了換電池上網找了找,發現 APC 現在不只有正體中文網站,連台灣分公司都有了(美商艾比希)。上網查了查,有幾家公司有賣。以家裏網路總用電量 700 瓦來說, 800 瓦的 SUA1000XL ,市價要一萬二; 980 瓦的 SUA1500 ,市價要兩萬;附加的 SNMP 監控網路卡 AP9617 ,要一萬二。

    + +

    唔,還是好貴。 ^^; 可是應該還是需要吧。什麼時候才買得起呢?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 31 | + 32 | + 33 | + 34 | + 35 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0033.html.zh-cn.html b/htdocs/imacat/me/diary/0033.html.zh-cn.html new file mode 120000 index 0000000..e64c368 --- /dev/null +++ b/htdocs/imacat/me/diary/0033.html.zh-cn.html @@ -0,0 +1 @@ +0033.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0033.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0033.html.zh-cn.xhtml new file mode 100644 index 0000000..f7827db --- /dev/null +++ b/htdocs/imacat/me/diary/0033.html.zh-cn.xhtml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷三十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷三十三

    + +
    + +
    + +
    +
    8.4.’06. 3:10pm.
    + +

    UPS 不断电系统

    + +

    家里有网路。有网路就会想要 UPS 不断电系统。总不会希望夏天电力时好时坏,偶尔就来个瞬断,硬碟读写头重重敲上磁盘,寿命都减了一半。

    + +

    很久以前刚架好家里网路时,我买了飞瑞的不断电系统 A-500A-1000 。飞瑞是台湾的公司,在不断电系统市场上,走低价位的路线,连光华商场都买得到,算是便宜的选择。其间断电过几次,不到两、三年就坏了。而且坏掉以后,警报器还一直吵个不停,吵得我不能睡觉,直到我把它电源拔掉,所有电线重新插换为止。这种关键时刻完全没有用的便宜货,我完全死心了。那以后好一段时间,我没有再管 UPS 的事。

    + +

    公司用的 UPSAPCSmart UPS 3000 。听老板说十年前买的时候很贵,而且在台湾从来没有看过这个牌子,我猜可能是顶级网路环境专用的,要有门道才买得到,所以虽然很想买,可是连价钱都不知道,不得其门而入。

    + +

    这两天公司的 UPS 电池坏了,为了换电池上网找了找,发现 APC 现在不只有正体中文网站,连台湾分公司都有了(美商艾比希)。上网查了查,有几家公司有卖。以家里网路总用电量 700 瓦来说, 800 瓦的 SUA1000XL ,市价要一万二; 980 瓦的 SUA1500 ,市价要两万;附加的 SNMP 监控网路卡 AP9617 ,要一万二。

    + +

    唔,还是好贵。 ^^; 可是应该还是需要吧。什么时候才买得起呢?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 31 | + 32 | + 33 | + 34 | + 35 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0033.html.zh-tw.html b/htdocs/imacat/me/diary/0033.html.zh-tw.html new file mode 120000 index 0000000..44c640d --- /dev/null +++ b/htdocs/imacat/me/diary/0033.html.zh-tw.html @@ -0,0 +1 @@ +0033.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0033.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0033.html.zh-tw.xhtml new file mode 100644 index 0000000..ebe5b74 --- /dev/null +++ b/htdocs/imacat/me/diary/0033.html.zh-tw.xhtml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷三十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷三十三

    + +
    + +
    + +
    +
    8.4.’06. 3:10pm.
    + +

    UPS 不斷電系統

    + +

    家裏有網路。有網路就會想要 UPS 不斷電系統。總不會希望夏天電力時好時壞,偶爾就來個瞬斷,硬碟讀寫頭重重敲上磁盤,壽命都減了一半。

    + +

    很久以前剛架好家裏網路時,我買了飛瑞的不斷電系統 A-500A-1000 。飛瑞是台灣的公司,在不斷電系統市場上,走低價位的路線,連光華商場都買得到,算是便宜的選擇。其間斷電過幾次,不到兩、三年就壞了。而且壞掉以後,警報器還一直吵個不停,吵得我不能睡覺,直到我把它電源拔掉,所有電線重新插換為止。這種關鍵時刻完全沒有用的便宜貨,我完全死心了。那以後好一段時間,我沒有再管 UPS 的事。

    + +

    公司用的 UPSAPCSmart UPS 3000 。聽老闆說十年前買的時候很貴,而且在台灣從來沒有看過這個牌子,我猜可能是頂級網路環境專用的,要有門道才買得到,所以雖然很想買,可是連價錢都不知道,不得其門而入。

    + +

    這兩天公司的 UPS 電池壞了,為了換電池上網找了找,發現 APC 現在不只有正體中文網站,連台灣分公司都有了(美商艾比希)。上網查了查,有幾家公司有賣。以家裏網路總用電量 700 瓦來說, 800 瓦的 SUA1000XL ,市價要一萬二; 980 瓦的 SUA1500 ,市價要兩萬;附加的 SNMP 監控網路卡 AP9617 ,要一萬二。

    + +

    唔,還是好貴。 ^^; 可是應該還是需要吧。什麼時候才買得起呢?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 31 | + 32 | + 33 | + 34 | + 35 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0034.html.en.html b/htdocs/imacat/me/diary/0034.html.en.html new file mode 120000 index 0000000..a51323b --- /dev/null +++ b/htdocs/imacat/me/diary/0034.html.en.html @@ -0,0 +1 @@ +0034.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0034.html.en.xhtml b/htdocs/imacat/me/diary/0034.html.en.xhtml new file mode 100644 index 0000000..2aeeec8 --- /dev/null +++ b/htdocs/imacat/me/diary/0034.html.en.xhtml @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 34 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 34

    + +
    + +
    + +
    +
    8.10.’06. 3:03am.
    + +

    關於有價和無價

    + +

    我一直覺得,我平常花錢,有點衝動。手頭上的現金,常常一下子就不見了。每次去沒去過的餐廳吃飯,想到可能這輩子不會去第二次,到最後總是會點吃得起的菜色中,最想吃或是最招牌的菜,往往不是最貴的就是次貴的。事後反省不免覺得,是不是我只要買得起,只要我想要,我不在乎價格?這時候,經濟學所學到的價格彈性,價格低會增加消費,價格高會減少消費,對我來講,好像不大適用。雖然我不負債消費,但我買東西不在乎價格,所以錢還是花光光。對這樣的自己,不免感到很沮喪。

    + +

    昨天回家的路上,經過嵐迪義大利麵,看到對街兩家一模一樣的店,用餐環境不同,就差了二十元。我邊走邊想。我不會怪老闆,畢竟大家都希望提高附加價值,增加收入。可是就算我二十元花得起,也不一定會去消費。這二十元的價值對我而言,就是可以放在天平上衡量的了。

    + +

    想到這裏,突然覺得,我也不見得會只要我想要,不在乎價格。我還是會有當一個理性的經濟人,做理性選擇的時候。一想到此,對自己總算有點信心。嗯,我還是可以存錢的。呵呵。 ^_*'

    + +
    + +
    + +
    +
    8.8.’06. 11:00pm.
    + +

    有價與無價

    + +
    我自己的小小個體經濟學
    + +

    在我心目中,商品的價值,有兩種:

    + +

    一種是無價的,譬如小時候玩的第一個電腦遊戲。二十年前,一百多塊錢買的軟體世界版遊戲,現在要買古董版或經典合輯,可能要一千多塊錢,還要加上好幾百塊的海外運費。即使如此,只要我手上有閒置的一千多塊錢,我還是會去買。它的價格不重要,即使要一萬、十萬,只要我手上有足夠的閒置資金,就會去買下來。當然,我還是不會去刷信用卡、現金卡、借貸來買。

    + +

    一種是有價的。我家附近開了一家嵐迪義大利麵,價格八十元起,比西餐廳便宜又好吃,又因為店不大,開在頂溪捷運站旁邊,每天都擠滿了人。小小的店面,擠滿的小桌子坐滿了顧客,走道上還擠著一大堆等著外帶的人。後來嵐迪在對面開了另一家店,同樣的店名,同樣賣義大利麵,價格一百元起。菜色多了一點配菜,店面清爽很多,桌椅漂亮不少,也沒有擠在一起,還有落地玻璃門。多二十元,可享有比較清爽的用餐環境。這時候就要衡量,比較清爽的用餐環境,對我來說,值不值得這二十元。如果要外帶回家吃,當然不需要;如果要內用,就看心情:如果當天很疲倦煩悶,想在舒適的環境放鬆一下,手頭又不緊,二十元就值得;如果無所謂,或是手頭緊,那就不用了。

    + +

    兩種商品,買不買的標準,是不一樣的。第一種商品,我買不買,只和我的所得有關,和價格高低無關,所得彈性是正數,價格彈性無限大。第二種商品,我心中有一個我願意付出的價格,可以拿來跟商品價格比較:商品價格比我心中的價格低,就會購買,商品價格比我心中的價格高,就不會購買。價格的高低,會影響我的購買意願,而不是所得。所得彈性無限大,價格彈性是負數。

    + +

    這是我一個人的個體經濟學,消費行為的兩種模式。

    + +
    + +
    + +
    +
    8.8.’06. 10:13pm.
    + +

    今天下午不忙,上阿光的部落格逛逛,看到這篇工作之餘,不禁想到一件幾個星期前發生的事。

    + +

    那天,跟朋友在怡客喝咖啡,喝完正要離開,朋友上個洗手間,我坐在座位等。無聊的時候,聽到背後那一桌一男一女的對話:

    + +

    (其實不算對話,那個男的一個人一直講,那個女的一直聽沒講話。)

    + +
    +

    …像現在最熱的,就是老二哲學。譬如說,像 Intel 和賽揚,兩邊是競爭對手,賽揚它就不做老大,只做老二,凡事比 Intel 強一點點就好。譬如說,人家 Intel CPU 是 32 位元,賽揚就做多一點點 48 位元;人家 Intel 只好做到 64 位元,賽揚就又做多一點點,譬如說, 70 位元;這時候 Intel 只好再上去一個等級,做到 128 位元,賽揚又做多一點點,做 130 位元就好。它就這樣,永遠比 Intell 多一點點就好…

    +
    + +

    唔…我忍了很久,努力不要轉頭過去吐他的嘈。以上的話,至少有以下事實錯誤:

    + +
      +
    1. Intel 英特爾的對手不是賽揚 Celeron ,是 AMD 美商超微。賽揚不可能是 Intel 的對手,因為賽揚屬於是 Intel 的產品。
    2. + +
    3. CPU 的位元數,是位元組的大小,一定是二的整數次方: 8, 16, 32, 64, 128 等等,不可能有 48 位元、 70 位元、 130 位元這種蠢事。
    4. + +
    5. 32 位元系統,從上市到現在,至少經過了十年以上的歷史,才逐漸要被 64 位元系統取代; 64 位元系統現在還不普及,而且目前看起來,使用上幾近沒有極限,整數上限大到不會用到,指令集也填不完,即使再十年,也很難想像要用到 128 位元系統。現在就講 128 位元系統,就算是比喻也太誇張了。
    6. + +
    7. 即使是 AMD 超微,也沒有抱持老二哲學。 AMD 一直在等待機會超越 Intel ,這兩年一超越,就一口氣急著大幅拉開差距。說 AMD 抱持老二哲學,根本是無稽之談。
    8. + +
    9. 即使是 AMD 和 Intel 的競爭,競爭的主要也是 CPU 時脈頻率,不是位元數。
    10. +
    + +

    整個聽下來,那個男的根本就在胡說八道。他可能是某個對資訊外行的業務,去參加某一場商業管理研討會,台上的講師不知道講了什麼商場哲學,他聽了以後一知半解,回來就跟想泡的女生炫耀。我也很佩服那個女生,竟然一直靜靜地聽他天馬行空,自顧自口沫橫飛地炫耀自己一知半解的事,沒有起身就走。可能她從小就被訓練要當乖乖女,靜靜聽人說話,不要反駁吧。如果是我,就算聽不懂資訊業的事,碰到這種只顧著自己一個人口沫橫飛講爽的傢伙,也會掉頭就走吧。

    + +

    我偶爾學到一些新東西,也會跟身邊的人說,一部份也是為了消化吸收,順便整理整理。至於像那樣,一股腦地炫耀自己很有知識,我做不出來。

    + +

    不久朋友洗手間出來,我們離開咖啡廳。她一劈頭,就抱怨那個愛炫耀的傢伙很討厭。嗯。英雌所見略同。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 32 | + 33 | + 34 | + 35 | + 36 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0034.html.zh-cn.html b/htdocs/imacat/me/diary/0034.html.zh-cn.html new file mode 120000 index 0000000..d6ab6a9 --- /dev/null +++ b/htdocs/imacat/me/diary/0034.html.zh-cn.html @@ -0,0 +1 @@ +0034.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0034.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0034.html.zh-cn.xhtml new file mode 100644 index 0000000..8550e8f --- /dev/null +++ b/htdocs/imacat/me/diary/0034.html.zh-cn.xhtml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷三十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷三十四

    + +
    + +
    + +
    +
    8.10.’06. 3:03am.
    + +

    关於有价和无价

    + +

    我一直觉得,我平常花钱,有点冲动。手头上的现金,常常一下子就不见了。每次去没去过的餐厅吃饭,想到可能这辈子不会去第二次,到最后总是会点吃得起的菜色中,最想吃或是最招牌的菜,往往不是最贵的就是次贵的。事后反省不免觉得,是不是我只要买得起,只要我想要,我不在乎价格?这时候,经济学所学到的价格弹性,价格低会增加消费,价格高会减少消费,对我来讲,好像不大适用。虽然我不负债消费,但我买东西不在乎价格,所以钱还是花光光。对这样的自己,不免感到很沮丧。

    + +

    昨天回家的路上,经过岚迪义大利面,看到对街两家一模一样的店,用餐环境不同,就差了二十元。我边走边想。我不会怪老板,毕竟大家都希望提高附加价值,增加收入。可是就算我二十元花得起,也不一定会去消费。这二十元的价值对我而言,就是可以放在天平上衡量的了。

    + +

    想到这里,突然觉得,我也不见得会只要我想要,不在乎价格。我还是会有当一个理性的经济人,做理性选择的时候。一想到此,对自己总算有点信心。嗯,我还是可以存钱的。呵呵。 ^_*'

    + +
    + +
    + +
    +
    8.8.’06. 11:00pm.
    + +

    有价与无价

    + +
    我自己的小小个体经济学
    + +

    在我心目中,商品的价值,有两种:

    + +

    一种是无价的,譬如小时候玩的第一个电脑游戏。二十年前,一百多块钱买的软体世界版游戏,现在要买古董版或经典合辑,可能要一千多块钱,还要加上好几百块的海外运费。即使如此,只要我手上有闲置的一千多块钱,我还是会去买。它的价格不重要,即使要一万、十万,只要我手上有足够的闲置资金,就会去买下来。当然,我还是不会去刷信用卡、现金卡、借贷来买。

    + +

    一种是有价的。我家附近开了一家岚迪义大利面,价格八十元起,比西餐厅便宜又好吃,又因为店不大,开在顶溪捷运站旁边,每天都挤满了人。小小的店面,挤满的小桌子坐满了顾客,走道上还挤著一大堆等著外带的人。后来岚迪在对面开了另一家店,同样的店名,同样卖义大利面,价格一百元起。菜色多了一点配菜,店面清爽很多,桌椅漂亮不少,也没有挤在一起,还有落地玻璃门。多二十元,可享有比较清爽的用餐环境。这时候就要衡量,比较清爽的用餐环境,对我来说,值不值得这二十元。如果要外带回家吃,当然不需要;如果要内用,就看心情:如果当天很疲倦烦闷,想在舒适的环境放松一下,手头又不紧,二十元就值得;如果无所谓,或是手头紧,那就不用了。

    + +

    两种商品,买不买的标准,是不一样的。第一种商品,我买不买,只和我的所得有关,和价格高低无关,所得弹性是正数,价格弹性无限大。第二种商品,我心中有一个我愿意付出的价格,可以拿来跟商品价格比较:商品价格比我心中的价格低,就会购买,商品价格比我心中的价格高,就不会购买。价格的高低,会影响我的购买意愿,而不是所得。所得弹性无限大,价格弹性是负数。

    + +

    这是我一个人的个体经济学,消费行为的两种模式。

    + +
    + +
    + +
    +
    8.8.’06. 10:13pm.
    + +

    今天下午不忙,上阿光的部落格逛逛,看到这篇工作之余,不禁想到一件几个星期前发生的事。

    + +

    那天,跟朋友在怡客喝咖啡,喝完正要离开,朋友上个洗手间,我坐在座位等。无聊的时候,听到背后那一桌一男一女的对话:

    + +

    (其实不算对话,那个男的一个人一直讲,那个女的一直听没讲话。)

    + +
    +

    …像现在最热的,就是老二哲学。譬如说,像 Intel 和赛扬,两边是竞争对手,赛扬它就不做老大,只做老二,凡事比 Intel 强一点点就好。譬如说,人家 Intel CPU 是 32 位元,赛扬就做多一点点 48 位元;人家 Intel 只好做到 64 位元,赛扬就又做多一点点,譬如说, 70 位元;这时候 Intel 只好再上去一个等级,做到 128 位元,赛扬又做多一点点,做 130 位元就好。它就这样,永远比 Intell 多一点点就好…

    +
    + +

    唔…我忍了很久,努力不要转头过去吐他的嘈。以上的话,至少有以下事实错误:

    + +
      +
    1. Intel 英特尔的对手不是赛扬 Celeron ,是 AMD 美商超微。赛扬不可能是 Intel 的对手,因为赛扬属於是 Intel 的产品。
    2. + +
    3. CPU 的位元数,是位元组的大小,一定是二的整数次方: 8, 16, 32, 64, 128 等等,不可能有 48 位元、 70 位元、 130 位元这种蠢事。
    4. + +
    5. 32 位元系统,从上市到现在,至少经过了十年以上的历史,才逐渐要被 64 位元系统取代; 64 位元系统现在还不普及,而且目前看起来,使用上几近没有极限,整数上限大到不会用到,指令集也填不完,即使再十年,也很难想像要用到 128 位元系统。现在就讲 128 位元系统,就算是比喻也太夸张了。
    6. + +
    7. 即使是 AMD 超微,也没有抱持老二哲学。 AMD 一直在等待机会超越 Intel ,这两年一超越,就一口气急著大幅拉开差距。说 AMD 抱持老二哲学,根本是无稽之谈。
    8. + +
    9. 即使是 AMD 和 Intel 的竞争,竞争的主要也是 CPU 时脉频率,不是位元数。
    10. +
    + +

    整个听下来,那个男的根本就在胡说八道。他可能是某个对资讯外行的业务,去参加某一场商业管理研讨会,台上的讲师不知道讲了什么商场哲学,他听了以后一知半解,回来就跟想泡的女生炫耀。我也很佩服那个女生,竟然一直静静地听他天马行空,自顾自口沫横飞地炫耀自己一知半解的事,没有起身就走。可能她从小就被训练要当乖乖女,静静听人说话,不要反驳吧。如果是我,就算听不懂资讯业的事,碰到这种只顾著自己一个人口沫横飞讲爽的家伙,也会掉头就走吧。

    + +

    我偶尔学到一些新东西,也会跟身边的人说,一部份也是为了消化吸收,顺便整理整理。至於像那样,一股脑地炫耀自己很有知识,我做不出来。

    + +

    不久朋友洗手间出来,我们离开咖啡厅。她一劈头,就抱怨那个爱炫耀的家伙很讨厌。嗯。英雌所见略同。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 32 | + 33 | + 34 | + 35 | + 36 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0034.html.zh-tw.html b/htdocs/imacat/me/diary/0034.html.zh-tw.html new file mode 120000 index 0000000..f33bf99 --- /dev/null +++ b/htdocs/imacat/me/diary/0034.html.zh-tw.html @@ -0,0 +1 @@ +0034.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0034.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0034.html.zh-tw.xhtml new file mode 100644 index 0000000..fc0cdb1 --- /dev/null +++ b/htdocs/imacat/me/diary/0034.html.zh-tw.xhtml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷三十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷三十四

    + +
    + +
    + +
    +
    8.10.’06. 3:03am.
    + +

    關於有價和無價

    + +

    我一直覺得,我平常花錢,有點衝動。手頭上的現金,常常一下子就不見了。每次去沒去過的餐廳吃飯,想到可能這輩子不會去第二次,到最後總是會點吃得起的菜色中,最想吃或是最招牌的菜,往往不是最貴的就是次貴的。事後反省不免覺得,是不是我只要買得起,只要我想要,我不在乎價格?這時候,經濟學所學到的價格彈性,價格低會增加消費,價格高會減少消費,對我來講,好像不大適用。雖然我不負債消費,但我買東西不在乎價格,所以錢還是花光光。對這樣的自己,不免感到很沮喪。

    + +

    昨天回家的路上,經過嵐迪義大利麵,看到對街兩家一模一樣的店,用餐環境不同,就差了二十元。我邊走邊想。我不會怪老闆,畢竟大家都希望提高附加價值,增加收入。可是就算我二十元花得起,也不一定會去消費。這二十元的價值對我而言,就是可以放在天平上衡量的了。

    + +

    想到這裏,突然覺得,我也不見得會只要我想要,不在乎價格。我還是會有當一個理性的經濟人,做理性選擇的時候。一想到此,對自己總算有點信心。嗯,我還是可以存錢的。呵呵。 ^_*'

    + +
    + +
    + +
    +
    8.8.’06. 11:00pm.
    + +

    有價與無價

    + +
    我自己的小小個體經濟學
    + +

    在我心目中,商品的價值,有兩種:

    + +

    一種是無價的,譬如小時候玩的第一個電腦遊戲。二十年前,一百多塊錢買的軟體世界版遊戲,現在要買古董版或經典合輯,可能要一千多塊錢,還要加上好幾百塊的海外運費。即使如此,只要我手上有閒置的一千多塊錢,我還是會去買。它的價格不重要,即使要一萬、十萬,只要我手上有足夠的閒置資金,就會去買下來。當然,我還是不會去刷信用卡、現金卡、借貸來買。

    + +

    一種是有價的。我家附近開了一家嵐迪義大利麵,價格八十元起,比西餐廳便宜又好吃,又因為店不大,開在頂溪捷運站旁邊,每天都擠滿了人。小小的店面,擠滿的小桌子坐滿了顧客,走道上還擠著一大堆等著外帶的人。後來嵐迪在對面開了另一家店,同樣的店名,同樣賣義大利麵,價格一百元起。菜色多了一點配菜,店面清爽很多,桌椅漂亮不少,也沒有擠在一起,還有落地玻璃門。多二十元,可享有比較清爽的用餐環境。這時候就要衡量,比較清爽的用餐環境,對我來說,值不值得這二十元。如果要外帶回家吃,當然不需要;如果要內用,就看心情:如果當天很疲倦煩悶,想在舒適的環境放鬆一下,手頭又不緊,二十元就值得;如果無所謂,或是手頭緊,那就不用了。

    + +

    兩種商品,買不買的標準,是不一樣的。第一種商品,我買不買,只和我的所得有關,和價格高低無關,所得彈性是正數,價格彈性無限大。第二種商品,我心中有一個我願意付出的價格,可以拿來跟商品價格比較:商品價格比我心中的價格低,就會購買,商品價格比我心中的價格高,就不會購買。價格的高低,會影響我的購買意願,而不是所得。所得彈性無限大,價格彈性是負數。

    + +

    這是我一個人的個體經濟學,消費行為的兩種模式。

    + +
    + +
    + +
    +
    8.8.’06. 10:13pm.
    + +

    今天下午不忙,上阿光的部落格逛逛,看到這篇工作之餘,不禁想到一件幾個星期前發生的事。

    + +

    那天,跟朋友在怡客喝咖啡,喝完正要離開,朋友上個洗手間,我坐在座位等。無聊的時候,聽到背後那一桌一男一女的對話:

    + +

    (其實不算對話,那個男的一個人一直講,那個女的一直聽沒講話。)

    + +
    +

    …像現在最熱的,就是老二哲學。譬如說,像 Intel 和賽揚,兩邊是競爭對手,賽揚它就不做老大,只做老二,凡事比 Intel 強一點點就好。譬如說,人家 Intel CPU 是 32 位元,賽揚就做多一點點 48 位元;人家 Intel 只好做到 64 位元,賽揚就又做多一點點,譬如說, 70 位元;這時候 Intel 只好再上去一個等級,做到 128 位元,賽揚又做多一點點,做 130 位元就好。它就這樣,永遠比 Intell 多一點點就好…

    +
    + +

    唔…我忍了很久,努力不要轉頭過去吐他的嘈。以上的話,至少有以下事實錯誤:

    + +
      +
    1. Intel 英特爾的對手不是賽揚 Celeron ,是 AMD 美商超微。賽揚不可能是 Intel 的對手,因為賽揚屬於是 Intel 的產品。
    2. + +
    3. CPU 的位元數,是位元組的大小,一定是二的整數次方: 8, 16, 32, 64, 128 等等,不可能有 48 位元、 70 位元、 130 位元這種蠢事。
    4. + +
    5. 32 位元系統,從上市到現在,至少經過了十年以上的歷史,才逐漸要被 64 位元系統取代; 64 位元系統現在還不普及,而且目前看起來,使用上幾近沒有極限,整數上限大到不會用到,指令集也填不完,即使再十年,也很難想像要用到 128 位元系統。現在就講 128 位元系統,就算是比喻也太誇張了。
    6. + +
    7. 即使是 AMD 超微,也沒有抱持老二哲學。 AMD 一直在等待機會超越 Intel ,這兩年一超越,就一口氣急著大幅拉開差距。說 AMD 抱持老二哲學,根本是無稽之談。
    8. + +
    9. 即使是 AMD 和 Intel 的競爭,競爭的主要也是 CPU 時脈頻率,不是位元數。
    10. +
    + +

    整個聽下來,那個男的根本就在胡說八道。他可能是某個對資訊外行的業務,去參加某一場商業管理研討會,台上的講師不知道講了什麼商場哲學,他聽了以後一知半解,回來就跟想泡的女生炫耀。我也很佩服那個女生,竟然一直靜靜地聽他天馬行空,自顧自口沫橫飛地炫耀自己一知半解的事,沒有起身就走。可能她從小就被訓練要當乖乖女,靜靜聽人說話,不要反駁吧。如果是我,就算聽不懂資訊業的事,碰到這種只顧著自己一個人口沫橫飛講爽的傢伙,也會掉頭就走吧。

    + +

    我偶爾學到一些新東西,也會跟身邊的人說,一部份也是為了消化吸收,順便整理整理。至於像那樣,一股腦地炫耀自己很有知識,我做不出來。

    + +

    不久朋友洗手間出來,我們離開咖啡廳。她一劈頭,就抱怨那個愛炫耀的傢伙很討厭。嗯。英雌所見略同。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 32 | + 33 | + 34 | + 35 | + 36 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0035.html.en.html b/htdocs/imacat/me/diary/0035.html.en.html new file mode 120000 index 0000000..f4732f0 --- /dev/null +++ b/htdocs/imacat/me/diary/0035.html.en.html @@ -0,0 +1 @@ +0035.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0035.html.en.xhtml b/htdocs/imacat/me/diary/0035.html.en.xhtml new file mode 100644 index 0000000..9eedc48 --- /dev/null +++ b/htdocs/imacat/me/diary/0035.html.en.xhtml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 35 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 35

    + +
    + +
    + +
    +
    8.10.’06. 4:16am.
    + +

    NANA ナナ

    + +
    +«NANA» 第九集封面
    +

    NANA 第九集封面

    +
    + +

    最近為了 NANA ,超感動中。可是一直不知道該怎麼寫。

    + +

    看完矢沢あい(矢澤愛)的原著漫畫 NANA ナナ 後很感動,跑去買了電影 DVD ;看完電影後超感動,又跑去買了電影原聲帶。現在則很想要一張日本多位藝人、樂團專為漫畫 NANA 出的搖滾專輯 LOVE for NANA 。今天又發現了土屋アンナ(土屋安娜)和混血兒 OLIVIA ,各自扮演漫畫 NANA 裏兩個對手樂團 Black Stones (BLAST) 主唱大崎ナナ(大崎娜娜),和 TRAPNEST 主唱 REIRA 芹澤レイラ,一起發行的一黑一白兩首單曲 rosea little pain ,都超好聽的。我早先甚至還想去買 PS2PSP ,因為 KONAMI 有發行 NANAPS2PSP 的遊戲

    + +
    +電影 «NANA»
    +

    電影 NANA

    +
    + +
    +«Love for NANA» 的 BLAST
    +

    LOVE for NANABLAST

    +
    + +
    +«Love for NANA» TRAPNEST
    +

    LOVE for NANATRAPNEST

    +
    + +
    +土屋アンナ的ナナ
    +

    土屋アンナナナ

    +
    + +
    +OLIVIA 的 REIRA
    +

    OLIVIAREIRA

    +
    + +
    +KONAMI 發行的 «NANA» PS2 遊戲,兩個 NANA 看起來好像拉一樣~
    +

    KONAMI 發行的 NANA PS2 遊戲,兩個 NANA 看起來好像拉一樣~

    +
    + +
    +KONAMI 發行的 NANA PSP 掌上遊戲
    +

    KONAMI 發行的 NANA PSP 掌上遊戲

    +
    + +

    看著電影裏,演ハチ子(小八)小松奈々(小松奈奈)的宮崎あおい(宮崎葵),和漫畫裏奈々一模一樣,傻傻的燦爛笑臉;失戀時,整張臉哭得醜不拉幾的,跟漫畫裏奈々的哭相竟然也一模一樣,感動到眼淚都快流出來了!還有悠揚的配樂,把漫畫的原味一點不漏地完整表現出來的兩首主題曲:扮演 BLAST 主唱ナナ中島美嘉唱的 GLAMOROUS SKY ,和扮演 TRAPNEST 主唱 REIRA伊藤由奈唱的 ENDLESS STORY ,都非常好聽。

    + +

    不過電影裏,還是有些瑕疵。聽說還要拍續集,兩位主角的演員可能會換人。換人我覺得沒關係,拍電影牽涉到的人、事都太多了,遠比漫畫複雜,很多事本來就很難面面俱到。只要能夠把漫畫的原味拍出來就好了。不過電影裏演岡崎真一松山ケンイチ(松山健一),怎麼看都不像只有十六歲,如果這一點沒交待的話,後來真一賣春的事及他和 REIRA 的情慾糾葛,就不知道怎麼演了。還有奈々唸唸不忘的大魔王,電影一直沒有提到,後來ナナ巡迴演唱的時候,還特地為奈々帶回來一瓶名為魔王的吟釀,也不知道要怎麼拍。而且電影裏的奈々超級純真無邪,可是原著漫畫裏的奈々是一見鍾情大王,傻傻地見一個愛一個,才唸高中就惹上不倫戀,死心塌地陷入一段有性無愛的婚外情。如果這一段奈々的感情態度沒有交待好的話,後來和寺島伸夫複雜情慾糾葛,也不知道怎麼演下去。這些都是避不掉的問題。

    + +

    可是即使有這些缺點,還是覺得漫畫和電影超級感動的。

    + +

    不過到底感動什麼?我也說不上來。所以一直不知道該怎麼寫。 ^^;

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 33 | + 34 | + 35 | + 36 | + 37 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0035.html.zh-cn.html b/htdocs/imacat/me/diary/0035.html.zh-cn.html new file mode 120000 index 0000000..79543ed --- /dev/null +++ b/htdocs/imacat/me/diary/0035.html.zh-cn.html @@ -0,0 +1 @@ +0035.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0035.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0035.html.zh-cn.xhtml new file mode 100644 index 0000000..88746fc --- /dev/null +++ b/htdocs/imacat/me/diary/0035.html.zh-cn.xhtml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷三十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷三十五

    + +
    + +
    + +
    +
    8.10.’06. 4:16am.
    + +

    NANA ナナ

    + +
    +«NANA» 第九集封面
    +

    NANA 第九集封面

    +
    + +

    最近为了 NANA ,超感动中。可是一直不知道该怎么写。

    + +

    看完矢沢あい(矢泽爱)的原著漫画 NANA ナナ 后很感动,跑去买了电影 DVD ;看完电影后超感动,又跑去买了电影原声带。现在则很想要一张日本多位艺人、乐团专为漫画 NANA 出的摇滚专辑 LOVE for NANA 。今天又发现了土屋アンナ(土屋安娜)和混血儿 OLIVIA ,各自扮演漫画 NANA 里两个对手乐团 Black Stones (BLAST) 主唱大崎ナナ(大崎娜娜),和 TRAPNEST 主唱 REIRA 芹泽レイラ,一起发行的一黑一白两首单曲 rosea little pain ,都超好听的。我早先甚至还想去买 PS2PSP ,因为 KONAMI 有发行 NANAPS2PSP 的游戏

    + +
    +电影 «NANA»
    +

    电影 NANA

    +
    + +
    +«Love for NANA» 的 BLAST
    +

    LOVE for NANABLAST

    +
    + +
    +«Love for NANA» TRAPNEST
    +

    LOVE for NANATRAPNEST

    +
    + +
    +土屋アンナ的ナナ
    +

    土屋アンナナナ

    +
    + +
    +OLIVIA 的 REIRA
    +

    OLIVIAREIRA

    +
    + +
    +KONAMI 发行的 «NANA» PS2 游戏,两个 NANA 看起来好像拉一样~
    +

    KONAMI 发行的 NANA PS2 游戏,两个 NANA 看起来好像拉一样~

    +
    + +
    +KONAMI 发行的 NANA PSP 掌上游戏
    +

    KONAMI 发行的 NANA PSP 掌上游戏

    +
    + +

    看著电影里,演ハチ子(小八)小松奈々(小松奈奈)的宫崎あおい(宫崎葵),和漫画里奈々一模一样,傻傻的灿烂笑脸;失恋时,整张脸哭得丑不拉几的,跟漫画里奈々的哭相竟然也一模一样,感动到眼泪都快流出来了!还有悠扬的配乐,把漫画的原味一点不漏地完整表现出来的两首主题曲:扮演 BLAST 主唱ナナ中岛美嘉唱的 GLAMOROUS SKY ,和扮演 TRAPNEST 主唱 REIRA伊藤由奈唱的 ENDLESS STORY ,都非常好听。

    + +

    不过电影里,还是有些瑕疵。听说还要拍续集,两位主角的演员可能会换人。换人我觉得没关系,拍电影牵涉到的人、事都太多了,远比漫画复杂,很多事本来就很难面面俱到。只要能够把漫画的原味拍出来就好了。不过电影里演冈崎真一松山ケンイチ(松山健一),怎么看都不像只有十六岁,如果这一点没交待的话,后来真一卖春的事及他和 REIRA 的情欲纠葛,就不知道怎么演了。还有奈々念念不忘的大魔王,电影一直没有提到,后来ナナ巡回演唱的时候,还特地为奈々带回来一瓶名为魔王的吟酿,也不知道要怎么拍。而且电影里的奈々超级纯真无邪,可是原著漫画里的奈々是一见钟情大王,傻傻地见一个爱一个,才念高中就惹上不伦恋,死心塌地陷入一段有性无爱的婚外情。如果这一段奈々的感情态度没有交待好的话,后来和寺岛伸夫复杂情欲纠葛,也不知道怎么演下去。这些都是避不掉的问题。

    + +

    可是即使有这些缺点,还是觉得漫画和电影超级感动的。

    + +

    不过到底感动什么?我也说不上来。所以一直不知道该怎么写。 ^^;

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 33 | + 34 | + 35 | + 36 | + 37 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0035.html.zh-tw.html b/htdocs/imacat/me/diary/0035.html.zh-tw.html new file mode 120000 index 0000000..5f84982 --- /dev/null +++ b/htdocs/imacat/me/diary/0035.html.zh-tw.html @@ -0,0 +1 @@ +0035.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0035.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0035.html.zh-tw.xhtml new file mode 100644 index 0000000..5aead32 --- /dev/null +++ b/htdocs/imacat/me/diary/0035.html.zh-tw.xhtml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷三十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷三十五

    + +
    + +
    + +
    +
    8.10.’06. 4:16am.
    + +

    NANA ナナ

    + +
    +«NANA» 第九集封面
    +

    NANA 第九集封面

    +
    + +

    最近為了 NANA ,超感動中。可是一直不知道該怎麼寫。

    + +

    看完矢沢あい(矢澤愛)的原著漫畫 NANA ナナ 後很感動,跑去買了電影 DVD ;看完電影後超感動,又跑去買了電影原聲帶。現在則很想要一張日本多位藝人、樂團專為漫畫 NANA 出的搖滾專輯 LOVE for NANA 。今天又發現了土屋アンナ(土屋安娜)和混血兒 OLIVIA ,各自扮演漫畫 NANA 裏兩個對手樂團 Black Stones (BLAST) 主唱大崎ナナ(大崎娜娜),和 TRAPNEST 主唱 REIRA 芹澤レイラ,一起發行的一黑一白兩首單曲 rosea little pain ,都超好聽的。我早先甚至還想去買 PS2PSP ,因為 KONAMI 有發行 NANAPS2PSP 的遊戲

    + +
    +電影 «NANA»
    +

    電影 NANA

    +
    + +
    +«Love for NANA» 的 BLAST
    +

    LOVE for NANABLAST

    +
    + +
    +«Love for NANA» TRAPNEST
    +

    LOVE for NANATRAPNEST

    +
    + +
    +土屋アンナ的ナナ
    +

    土屋アンナナナ

    +
    + +
    +OLIVIA 的 REIRA
    +

    OLIVIAREIRA

    +
    + +
    +KONAMI 發行的 «NANA» PS2 遊戲,兩個 NANA 看起來好像拉一樣~
    +

    KONAMI 發行的 NANA PS2 遊戲,兩個 NANA 看起來好像拉一樣~

    +
    + +
    +KONAMI 發行的 NANA PSP 掌上遊戲
    +

    KONAMI 發行的 NANA PSP 掌上遊戲

    +
    + +

    看著電影裏,演ハチ子(小八)小松奈々(小松奈奈)的宮崎あおい(宮崎葵),和漫畫裏奈々一模一樣,傻傻的燦爛笑臉;失戀時,整張臉哭得醜不拉幾的,跟漫畫裏奈々的哭相竟然也一模一樣,感動到眼淚都快流出來了!還有悠揚的配樂,把漫畫的原味一點不漏地完整表現出來的兩首主題曲:扮演 BLAST 主唱ナナ中島美嘉唱的 GLAMOROUS SKY ,和扮演 TRAPNEST 主唱 REIRA伊藤由奈唱的 ENDLESS STORY ,都非常好聽。

    + +

    不過電影裏,還是有些瑕疵。聽說還要拍續集,兩位主角的演員可能會換人。換人我覺得沒關係,拍電影牽涉到的人、事都太多了,遠比漫畫複雜,很多事本來就很難面面俱到。只要能夠把漫畫的原味拍出來就好了。不過電影裏演岡崎真一松山ケンイチ(松山健一),怎麼看都不像只有十六歲,如果這一點沒交待的話,後來真一賣春的事及他和 REIRA 的情慾糾葛,就不知道怎麼演了。還有奈々唸唸不忘的大魔王,電影一直沒有提到,後來ナナ巡迴演唱的時候,還特地為奈々帶回來一瓶名為魔王的吟釀,也不知道要怎麼拍。而且電影裏的奈々超級純真無邪,可是原著漫畫裏的奈々是一見鍾情大王,傻傻地見一個愛一個,才唸高中就惹上不倫戀,死心塌地陷入一段有性無愛的婚外情。如果這一段奈々的感情態度沒有交待好的話,後來和寺島伸夫複雜情慾糾葛,也不知道怎麼演下去。這些都是避不掉的問題。

    + +

    可是即使有這些缺點,還是覺得漫畫和電影超級感動的。

    + +

    不過到底感動什麼?我也說不上來。所以一直不知道該怎麼寫。 ^^;

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 33 | + 34 | + 35 | + 36 | + 37 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0036.html.en.html b/htdocs/imacat/me/diary/0036.html.en.html new file mode 120000 index 0000000..1b10ef0 --- /dev/null +++ b/htdocs/imacat/me/diary/0036.html.en.html @@ -0,0 +1 @@ +0036.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0036.html.en.xhtml b/htdocs/imacat/me/diary/0036.html.en.xhtml new file mode 100644 index 0000000..ce6780c --- /dev/null +++ b/htdocs/imacat/me/diary/0036.html.en.xhtml @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 36 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 36

    + +
    + +
    + +
    +
    8.10.’06. 6:35pm.
    + +

    最近寫日記,寫得蠻勤的。

    + +

    其實我平常就常胡思亂想。一旦一個人靜下來,就會開始想東想西。有時是在騎車,有時是候餐的空檔,有時是走路間。想的事情很多,不過往往很片段很瑣碎,當時會想到要記下來,可是往往過一下子就忘了。

    + +

    最近因為改變做事的方法,一有空坐在電腦前面,就會把剛剛想的事先簡記一行,再慢慢詳細記下來。因為事情沒有忘記,記錄的事,一下子變多了起來。一把槍,一部電影,一部漫畫,一點消費習慣的反省。

    + +

    不過這樣記,也是蠻累的。想的事很瑣碎,而且都是亂想,一下子聯想到這個那個的,沒有什麼系統脈絡。可是文字是有章法的。寫成文字的時候,我努力要把思緒整理得有條理一點,想辦法清楚表達這些亂七八糟的胡思亂想,就會變得很辛苦。即使如此,回過頭來看一看這些努力記下來的東西,還是覺得很雜亂。外人看到,可能不知道我在寫些什麼。

    + +

    那晚寫完有價和無價後,隔天回想,好像只顧著整理思緒條理,寫了一堆書上就看得到的知識,沒有真正寫出自己心裏所感,於是又補寫了關於有價和無價。後來那篇,或是說兩篇加起來,才是我在想的事吧。

    + +

    話說回來,日記到底是給自己看的,還是給別人看的?這是一個很吊詭的問題。我現在,也不知道該怎麼回答。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 34 | + 35 | + 36 | + 37 | + 38 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0036.html.zh-cn.html b/htdocs/imacat/me/diary/0036.html.zh-cn.html new file mode 120000 index 0000000..09f2f6d --- /dev/null +++ b/htdocs/imacat/me/diary/0036.html.zh-cn.html @@ -0,0 +1 @@ +0036.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0036.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0036.html.zh-cn.xhtml new file mode 100644 index 0000000..6be510d --- /dev/null +++ b/htdocs/imacat/me/diary/0036.html.zh-cn.xhtml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷三十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷三十六

    + +
    + +
    + +
    +
    8.10.’06. 6:35pm.
    + +

    最近写日记,写得蛮勤的。

    + +

    其实我平常就常胡思乱想。一旦一个人静下来,就会开始想东想西。有时是在骑车,有时是候餐的空档,有时是走路间。想的事情很多,不过往往很片段很琐碎,当时会想到要记下来,可是往往过一下子就忘了。

    + +

    最近因为改变做事的方法,一有空坐在电脑前面,就会把刚刚想的事先简记一行,再慢慢详细记下来。因为事情没有忘记,记录的事,一下子变多了起来。一把枪,一部电影,一部漫画,一点消费习惯的反省。

    + +

    不过这样记,也是蛮累的。想的事很琐碎,而且都是乱想,一下子联想到这个那个的,没有什么系统脉络。可是文字是有章法的。写成文字的时候,我努力要把思绪整理得有条理一点,想办法清楚表达这些乱七八糟的胡思乱想,就会变得很辛苦。即使如此,回过头来看一看这些努力记下来的东西,还是觉得很杂乱。外人看到,可能不知道我在写些什么。

    + +

    那晚写完有价和无价后,隔天回想,好像只顾著整理思绪条理,写了一堆书上就看得到的知识,没有真正写出自己心里所感,於是又补写了关於有价和无价。后来那篇,或是说两篇加起来,才是我在想的事吧。

    + +

    话说回来,日记到底是给自己看的,还是给别人看的?这是一个很吊诡的问题。我现在,也不知道该怎么回答。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 34 | + 35 | + 36 | + 37 | + 38 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0036.html.zh-tw.html b/htdocs/imacat/me/diary/0036.html.zh-tw.html new file mode 120000 index 0000000..2e65d11 --- /dev/null +++ b/htdocs/imacat/me/diary/0036.html.zh-tw.html @@ -0,0 +1 @@ +0036.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0036.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0036.html.zh-tw.xhtml new file mode 100644 index 0000000..60d0c9a --- /dev/null +++ b/htdocs/imacat/me/diary/0036.html.zh-tw.xhtml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷三十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷三十六

    + +
    + +
    + +
    +
    8.10.’06. 6:35pm.
    + +

    最近寫日記,寫得蠻勤的。

    + +

    其實我平常就常胡思亂想。一旦一個人靜下來,就會開始想東想西。有時是在騎車,有時是候餐的空檔,有時是走路間。想的事情很多,不過往往很片段很瑣碎,當時會想到要記下來,可是往往過一下子就忘了。

    + +

    最近因為改變做事的方法,一有空坐在電腦前面,就會把剛剛想的事先簡記一行,再慢慢詳細記下來。因為事情沒有忘記,記錄的事,一下子變多了起來。一把槍,一部電影,一部漫畫,一點消費習慣的反省。

    + +

    不過這樣記,也是蠻累的。想的事很瑣碎,而且都是亂想,一下子聯想到這個那個的,沒有什麼系統脈絡。可是文字是有章法的。寫成文字的時候,我努力要把思緒整理得有條理一點,想辦法清楚表達這些亂七八糟的胡思亂想,就會變得很辛苦。即使如此,回過頭來看一看這些努力記下來的東西,還是覺得很雜亂。外人看到,可能不知道我在寫些什麼。

    + +

    那晚寫完有價和無價後,隔天回想,好像只顧著整理思緒條理,寫了一堆書上就看得到的知識,沒有真正寫出自己心裏所感,於是又補寫了關於有價和無價。後來那篇,或是說兩篇加起來,才是我在想的事吧。

    + +

    話說回來,日記到底是給自己看的,還是給別人看的?這是一個很吊詭的問題。我現在,也不知道該怎麼回答。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 34 | + 35 | + 36 | + 37 | + 38 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0037.html.en.html b/htdocs/imacat/me/diary/0037.html.en.html new file mode 120000 index 0000000..4a7e93b --- /dev/null +++ b/htdocs/imacat/me/diary/0037.html.en.html @@ -0,0 +1 @@ +0037.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0037.html.en.xhtml b/htdocs/imacat/me/diary/0037.html.en.xhtml new file mode 100644 index 0000000..84cca64 --- /dev/null +++ b/htdocs/imacat/me/diary/0037.html.en.xhtml @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 37 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 37

    + +
    + +
    + +
    +
    8.10.’06. 9:35pm.
    + +

    NANA 7.8

    + +

    今天下午,在漫畫書店看了 NANA 7.8

    + +
    +NANA 7.8
    +

    NANA 7.8

    +
    + +

    乍看這個名字,很奇怪也很有趣。第七點八集?這是在 NANA 第七集單行本發行後,第八集前,發行的特別篇,包括人物設定、作者矢沢あい專訪、番外篇淳子的房間等等。ナナ是七,ハチ子奈々)是八,合起來就叫七點八。

    + +

    讀完以後,又勾起對漫畫的一些回憶。

    + +

    奈々大魔王信仰,來自諾斯特拉達姆士 Nostradamus 五百年前的世界末日大預言: 1999 年 7 月,恐怖大魔王從天而降…。 1999 年連載開始時,當時高中生都在瘋狂熱衷諾斯特拉達姆士的大預言,高中生小松奈々也是其中之一。奈々非常相信大魔王,把日常生活中所有不如意的事,都推給大魔王的詛咒,到處跟人家開口閉口大魔王。到後來,連她身邊的人,也感染了大魔王教。大魔王的詛咒真是可怕~好可怕啊~

    + +

    本城蓮脖子上的荷包鎖,來自龐克搖滾始祖 Sex Pistols 的後期貝斯手 Sid Vicious 脖子上的荷包鎖。雖然作者矢沢あい否認,個性上也差很多,但其實的造型,跟 Sid Vicious 一模一樣:衝天的黑髮、削瘦、上半身赤裸、吸毒,脖子上掛著一個荷包鎖。 Sid 是一個悲劇性、毀滅性的樂手,衝動、粗暴、滿口髒話,不會彈貝斯,常常唱到一半衝下台跟樂迷幹架。原本只是 Sex Pistols 瘋狂樂迷、根本不會彈貝斯的 Sid , 1977 年被 Sex Pistols 經紀人 Malcolm McLaren 欽點加入 Sex Pistols , 1978 年吸毒恍惚中刺死女朋友 Nancy Spungen 被補, Sex Pistols 因此解散, 1979 年假釋出獄隔天,就因吸食海洛因過量死亡。(這段故事拍成了電影 Sid and Nancy (1986) 。)不過漫畫中的,貝斯彈得非常好,個性溫和,和 Sid 不大一樣。可是還是不禁讓人想到,性格壓抑、帶有毀滅性的,最後會不會跟 Sid 一樣下場,刺死女友ナナ,自毀而亡呢?

    + +
    +TRAPNEST 的本城蓮
    +

    TRAPNEST本城蓮

    +
    + +
    +Sid Vicious ,跟蓮幾乎一模一樣。注意脖子上的荷包鎖!
    +

    Sid Vicious ,跟幾乎一模一樣。注意脖子上的荷包鎖!

    +
    + +
    +Sid 和 Nancy ,搖滾史上的悲劇情侶
    +

    SidNancy ,搖滾史上的悲劇情侶

    +
    + +
    +電影 «Sid & Nancy»
    +

    電影 Sid & Nancy

    +
    + +

    想到這裏,不禁讓人打了個寒顫。

    + +

    BLASTSex Pistols 的關係,不只有Sid 之間。矢沢あい最喜歡服裝設計師 Vivienne Westwood 的衣服,給 BLAST 每個團員都穿上 Vivienne Westwood ,尤其是ナナ更是全身都是 Vivienne WestwoodVivienne Westwood 是誰?她正是發掘 Sex Pistols 的經紀人 Malcolm McLaren 當時的女朋友! 1975 年,英國藝術學院出身 Malcolm McLaren ,在幫女朋友 Vivienne Westwood 顧服裝店 Sex 時,幫幾個常來店裏晃的小鬼,依店名 Sex 組了留名青史的 Sex Pistols 。可以說龐克始祖 Sex Pistols ,就是在 Vivienne Westwood 店裏誕生的!後來 Vivienne Westwood 提供好幾個龐克團的服裝,成為龐克服飾的教祖。 Vivienne Westwood 的服裝店迄今仍開在倫敦 Davies Street 上,有機會去英國,可以去朝聖一下。

    + +
    +龐克教母 Vivienne Westwood
    +

    龐克教母 Vivienne Westwood

    +
    + +

    剛剛發現, Vivienne Westwood 在台灣也有好幾家分店,西門町武昌街 77 號 1 樓。有空可以去逛一逛。

    + +

    看了作者矢沢あい專訪,我才確定,漫畫 NANA 的故事其實是倒敘,奈々以輕柔的嘆息,細細述說自己和ナナ的回憶。既然是倒敘,故事的結局,從一開始就已經註定了。 NANA 的故事,述說的是無法改變的命運。雖然結局還是可能隨著劇情鋪陳,而有所改變(所有的故事都是如此),但是想到真實世界 Sex Pistols 貝斯手 Sid 的結局,想到走向毀滅之路的,想到在偶爾出現的現在中,一直缺席的ナナ,不禁讓人覺得好可怕!ナナ到最後會死嗎?不要吧~嗚~ :~~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 35 | + 36 | + 37 | + 38 | + 39 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0037.html.zh-cn.html b/htdocs/imacat/me/diary/0037.html.zh-cn.html new file mode 120000 index 0000000..b5c8124 --- /dev/null +++ b/htdocs/imacat/me/diary/0037.html.zh-cn.html @@ -0,0 +1 @@ +0037.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0037.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0037.html.zh-cn.xhtml new file mode 100644 index 0000000..2ae4783 --- /dev/null +++ b/htdocs/imacat/me/diary/0037.html.zh-cn.xhtml @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷三十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷三十七

    + +
    + +
    + +
    +
    8.10.’06. 9:35pm.
    + +

    NANA 7.8

    + +

    今天下午,在漫画书店看了 NANA 7.8

    + +
    +NANA 7.8
    +

    NANA 7.8

    +
    + +

    乍看这个名字,很奇怪也很有趣。第七点八集?这是在 NANA 第七集单行本发行后,第八集前,发行的特别篇,包括人物设定、作者矢沢あい专访、番外篇淳子的房间等等。ナナ是七,ハチ子奈々)是八,合起来就叫七点八。

    + +

    读完以后,又勾起对漫画的一些回忆。

    + +

    奈々大魔王信仰,来自诺斯特拉达姆士 Nostradamus 五百年前的世界末日大预言: 1999 年 7 月,恐怖大魔王从天而降…。 1999 年连载开始时,当时高中生都在疯狂热衷诺斯特拉达姆士的大预言,高中生小松奈々也是其中之一。奈々非常相信大魔王,把日常生活中所有不如意的事,都推给大魔王的诅咒,到处跟人家开口闭口大魔王。到后来,连她身边的人,也感染了大魔王教。大魔王的诅咒真是可怕~好可怕啊~

    + +

    本城莲脖子上的荷包锁,来自庞克摇滚始祖 Sex Pistols 的后期贝斯手 Sid Vicious 脖子上的荷包锁。虽然作者矢沢あい否认,个性上也差很多,但其实的造型,跟 Sid Vicious 一模一样:冲天的黑发、削瘦、上半身赤裸、吸毒,脖子上挂著一个荷包锁。 Sid 是一个悲剧性、毁灭性的乐手,冲动、粗暴、满口脏话,不会弹贝斯,常常唱到一半冲下台跟乐迷干架。原本只是 Sex Pistols 疯狂乐迷、根本不会弹贝斯的 Sid , 1977 年被 Sex Pistols 经纪人 Malcolm McLaren 钦点加入 Sex Pistols , 1978 年吸毒恍惚中刺死女朋友 Nancy Spungen 被补, Sex Pistols 因此解散, 1979 年假释出狱隔天,就因吸食海洛因过量死亡。(这段故事拍成了电影 Sid and Nancy (1986) 。)不过漫画中的,贝斯弹得非常好,个性温和,和 Sid 不大一样。可是还是不禁让人想到,性格压抑、带有毁灭性的,最后会不会跟 Sid 一样下场,刺死女友ナナ,自毁而亡呢?

    + +
    +TRAPNEST 的本城莲
    +

    TRAPNEST本城莲

    +
    + +
    +Sid Vicious ,跟莲几乎一模一样。注意脖子上的荷包锁!
    +

    Sid Vicious ,跟几乎一模一样。注意脖子上的荷包锁!

    +
    + +
    +Sid 和 Nancy ,摇滚史上的悲剧情侣
    +

    SidNancy ,摇滚史上的悲剧情侣

    +
    + +
    +电影 «Sid & Nancy»
    +

    电影 Sid & Nancy

    +
    + +

    想到这里,不禁让人打了个寒颤。

    + +

    BLASTSex Pistols 的关系,不只有Sid 之间。矢沢あい最喜欢服装设计师 Vivienne Westwood 的衣服,给 BLAST 每个团员都穿上 Vivienne Westwood ,尤其是ナナ更是全身都是 Vivienne WestwoodVivienne Westwood 是谁?她正是发掘 Sex Pistols 的经纪人 Malcolm McLaren 当时的女朋友! 1975 年,英国艺术学院出身 Malcolm McLaren ,在帮女朋友 Vivienne Westwood 顾服装店 Sex 时,帮几个常来店里晃的小鬼,依店名 Sex 组了留名青史的 Sex Pistols 。可以说庞克始祖 Sex Pistols ,就是在 Vivienne Westwood 店里诞生的!后来 Vivienne Westwood 提供好几个庞克团的服装,成为庞克服饰的教祖。 Vivienne Westwood 的服装店迄今仍开在伦敦 Davies Street 上,有机会去英国,可以去朝圣一下。

    + +
    +庞克教母 Vivienne Westwood
    +

    庞克教母 Vivienne Westwood

    +
    + +

    刚刚发现, Vivienne Westwood 在台湾也有好几家分店,西门町武昌街 77 号 1 楼。有空可以去逛一逛。

    + +

    看了作者矢沢あい专访,我才确定,漫画 NANA 的故事其实是倒叙,奈々以轻柔的叹息,细细述说自己和ナナ的回忆。既然是倒叙,故事的结局,从一开始就已经注定了。 NANA 的故事,述说的是无法改变的命运。虽然结局还是可能随著剧情铺陈,而有所改变(所有的故事都是如此),但是想到真实世界 Sex Pistols 贝斯手 Sid 的结局,想到走向毁灭之路的,想到在偶尔出现的现在中,一直缺席的ナナ,不禁让人觉得好可怕!ナナ到最后会死吗?不要吧~呜~ :~~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 35 | + 36 | + 37 | + 38 | + 39 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0037.html.zh-tw.html b/htdocs/imacat/me/diary/0037.html.zh-tw.html new file mode 120000 index 0000000..b9a90b7 --- /dev/null +++ b/htdocs/imacat/me/diary/0037.html.zh-tw.html @@ -0,0 +1 @@ +0037.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0037.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0037.html.zh-tw.xhtml new file mode 100644 index 0000000..b067792 --- /dev/null +++ b/htdocs/imacat/me/diary/0037.html.zh-tw.xhtml @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷三十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷三十七

    + +
    + +
    + +
    +
    8.10.’06. 9:35pm.
    + +

    NANA 7.8

    + +

    今天下午,在漫畫書店看了 NANA 7.8

    + +
    +NANA 7.8
    +

    NANA 7.8

    +
    + +

    乍看這個名字,很奇怪也很有趣。第七點八集?這是在 NANA 第七集單行本發行後,第八集前,發行的特別篇,包括人物設定、作者矢沢あい專訪、番外篇淳子的房間等等。ナナ是七,ハチ子奈々)是八,合起來就叫七點八。

    + +

    讀完以後,又勾起對漫畫的一些回憶。

    + +

    奈々大魔王信仰,來自諾斯特拉達姆士 Nostradamus 五百年前的世界末日大預言: 1999 年 7 月,恐怖大魔王從天而降…。 1999 年連載開始時,當時高中生都在瘋狂熱衷諾斯特拉達姆士的大預言,高中生小松奈々也是其中之一。奈々非常相信大魔王,把日常生活中所有不如意的事,都推給大魔王的詛咒,到處跟人家開口閉口大魔王。到後來,連她身邊的人,也感染了大魔王教。大魔王的詛咒真是可怕~好可怕啊~

    + +

    本城蓮脖子上的荷包鎖,來自龐克搖滾始祖 Sex Pistols 的後期貝斯手 Sid Vicious 脖子上的荷包鎖。雖然作者矢沢あい否認,個性上也差很多,但其實的造型,跟 Sid Vicious 一模一樣:衝天的黑髮、削瘦、上半身赤裸、吸毒,脖子上掛著一個荷包鎖。 Sid 是一個悲劇性、毀滅性的樂手,衝動、粗暴、滿口髒話,不會彈貝斯,常常唱到一半衝下台跟樂迷幹架。原本只是 Sex Pistols 瘋狂樂迷、根本不會彈貝斯的 Sid , 1977 年被 Sex Pistols 經紀人 Malcolm McLaren 欽點加入 Sex Pistols , 1978 年吸毒恍惚中刺死女朋友 Nancy Spungen 被補, Sex Pistols 因此解散, 1979 年假釋出獄隔天,就因吸食海洛因過量死亡。(這段故事拍成了電影 Sid and Nancy (1986) 。)不過漫畫中的,貝斯彈得非常好,個性溫和,和 Sid 不大一樣。可是還是不禁讓人想到,性格壓抑、帶有毀滅性的,最後會不會跟 Sid 一樣下場,刺死女友ナナ,自毀而亡呢?

    + +
    +TRAPNEST 的本城蓮
    +

    TRAPNEST本城蓮

    +
    + +
    +Sid Vicious ,跟蓮幾乎一模一樣。注意脖子上的荷包鎖!
    +

    Sid Vicious ,跟幾乎一模一樣。注意脖子上的荷包鎖!

    +
    + +
    +Sid 和 Nancy ,搖滾史上的悲劇情侶
    +

    SidNancy ,搖滾史上的悲劇情侶

    +
    + +
    +電影 «Sid & Nancy»
    +

    電影 Sid & Nancy

    +
    + +

    想到這裏,不禁讓人打了個寒顫。

    + +

    BLASTSex Pistols 的關係,不只有Sid 之間。矢沢あい最喜歡服裝設計師 Vivienne Westwood 的衣服,給 BLAST 每個團員都穿上 Vivienne Westwood ,尤其是ナナ更是全身都是 Vivienne WestwoodVivienne Westwood 是誰?她正是發掘 Sex Pistols 的經紀人 Malcolm McLaren 當時的女朋友! 1975 年,英國藝術學院出身 Malcolm McLaren ,在幫女朋友 Vivienne Westwood 顧服裝店 Sex 時,幫幾個常來店裏晃的小鬼,依店名 Sex 組了留名青史的 Sex Pistols 。可以說龐克始祖 Sex Pistols ,就是在 Vivienne Westwood 店裏誕生的!後來 Vivienne Westwood 提供好幾個龐克團的服裝,成為龐克服飾的教祖。 Vivienne Westwood 的服裝店迄今仍開在倫敦 Davies Street 上,有機會去英國,可以去朝聖一下。

    + +
    +龐克教母 Vivienne Westwood
    +

    龐克教母 Vivienne Westwood

    +
    + +

    剛剛發現, Vivienne Westwood 在台灣也有好幾家分店,西門町武昌街 77 號 1 樓。有空可以去逛一逛。

    + +

    看了作者矢沢あい專訪,我才確定,漫畫 NANA 的故事其實是倒敘,奈々以輕柔的嘆息,細細述說自己和ナナ的回憶。既然是倒敘,故事的結局,從一開始就已經註定了。 NANA 的故事,述說的是無法改變的命運。雖然結局還是可能隨著劇情鋪陳,而有所改變(所有的故事都是如此),但是想到真實世界 Sex Pistols 貝斯手 Sid 的結局,想到走向毀滅之路的,想到在偶爾出現的現在中,一直缺席的ナナ,不禁讓人覺得好可怕!ナナ到最後會死嗎?不要吧~嗚~ :~~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 35 | + 36 | + 37 | + 38 | + 39 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0038.html.en.html b/htdocs/imacat/me/diary/0038.html.en.html new file mode 120000 index 0000000..cc192e1 --- /dev/null +++ b/htdocs/imacat/me/diary/0038.html.en.html @@ -0,0 +1 @@ +0038.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0038.html.en.xhtml b/htdocs/imacat/me/diary/0038.html.en.xhtml new file mode 100644 index 0000000..18b9af7 --- /dev/null +++ b/htdocs/imacat/me/diary/0038.html.en.xhtml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 38 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 38

    + +
    + +
    + +
    +
    8.11.’06. 2:23am.
    + +

    我發現我新的做事方法,就是想到要做什麼就馬上簡單記一下,然後再從這個清單上把事情一一解決掉的做法,有一個很大的問題。

    + +

    這樣的做法,其實對做瑣碎的小事比較有利,效率比較高。反過來說,對於需要花長時間去研究、學習、創寫的東西,就很不利了。有很多事情可能需要三、五天,甚至三、五個星期才能完成。這些事就會一直懸在那裏。它們比起其它事情,看起來永遠都比較難。和其它事項比較,那些比較好著手、立竿見影的瑣事,我往往會優先去做,以便很快就能減少清單的大小。

    + +

    這樣的確很糟糕。很多重要、需要花長時間的事都延宕掉了。

    + +

    而且我發現,我的清單減少的速度,永遠比不上增加的速度。清單越來越長,而且已經長得有點離譜了。那也就是說,我給自己的工作量,超出我自己時間體力的負荷太多了。這是一個嚴重的問題。也許我應該改變一下,不要那麼嚴苛要求自己吧。

    + +
    + +
    + +
    +
    8.11.’06. 2:18am.
    + +

    日記是寫給自己看的,還是寫給別人看的?

    + +

    為什麼我會問:日記是寫給自己看的,還是寫給別人看的?

    + +

    如果日記是寫給自己看的,那別人看不看得懂,其實不重要。不需要把思緒整理得有條理,不需要起承轉合,不需要詳細說明,不需要字句流暢。只要把想到的事記下來就好。寫下來的東西,也許很差,沒頭沒尾,片斷跳躍,甚至有辱自己的名聲。可是管它的,這些都不重要。我只要把想到的什麼都記下來,這樣就夠了。

    + +

    所以,把什麼有價和無價消費和所得、價格的彈性關係寫清楚,其實不重要。重要的是我在想什麼,為什麼會想到這些事。

    + +

    那麼,記這種漫無章法的東西,做什麼呢?也許當個資料筆記,日後做個參考。例如 KONAMINANA PS2 電玩的網址,要是突然中了樂透,就可以買下來;或是小松奈々宮崎あおい等人的日語原名,說不定以後寫東西找資料會再用到。也許以後會回頭翻,檢閱過去的心情、想法,對當時的事件,會有更深一層的體會和成長,而不會什麼事都像船過水無痕,一過去就忘了。

    + +

    這些或許,以後都會成為我的資產。誰知道呢?又或許,真的只是一堆無意義的垃圾而已。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 36 | + 37 | + 38 | + 39 | + 40 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0038.html.zh-cn.html b/htdocs/imacat/me/diary/0038.html.zh-cn.html new file mode 120000 index 0000000..e6707c0 --- /dev/null +++ b/htdocs/imacat/me/diary/0038.html.zh-cn.html @@ -0,0 +1 @@ +0038.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0038.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0038.html.zh-cn.xhtml new file mode 100644 index 0000000..98afd8f --- /dev/null +++ b/htdocs/imacat/me/diary/0038.html.zh-cn.xhtml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷三十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷三十八

    + +
    + +
    + +
    +
    8.11.’06. 2:23am.
    + +

    我发现我新的做事方法,就是想到要做什么就马上简单记一下,然后再从这个清单上把事情一一解决掉的做法,有一个很大的问题。

    + +

    这样的做法,其实对做琐碎的小事比较有利,效率比较高。反过来说,对於需要花长时间去研究、学习、创写的东西,就很不利了。有很多事情可能需要三、五天,甚至三、五个星期才能完成。这些事就会一直悬在那里。它们比起其它事情,看起来永远都比较难。和其它事项比较,那些比较好著手、立竿见影的琐事,我往往会优先去做,以便很快就能减少清单的大小。

    + +

    这样的确很糟糕。很多重要、需要花长时间的事都延宕掉了。

    + +

    而且我发现,我的清单减少的速度,永远比不上增加的速度。清单越来越长,而且已经长得有点离谱了。那也就是说,我给自己的工作量,超出我自己时间体力的负荷太多了。这是一个严重的问题。也许我应该改变一下,不要那么严苛要求自己吧。

    + +
    + +
    + +
    +
    8.11.’06. 2:18am.
    + +

    日记是写给自己看的,还是写给别人看的?

    + +

    为什么我会问:日记是写给自己看的,还是写给别人看的?

    + +

    如果日记是写给自己看的,那别人看不看得懂,其实不重要。不需要把思绪整理得有条理,不需要起承转合,不需要详细说明,不需要字句流畅。只要把想到的事记下来就好。写下来的东西,也许很差,没头没尾,片断跳跃,甚至有辱自己的名声。可是管它的,这些都不重要。我只要把想到的什么都记下来,这样就够了。

    + +

    所以,把什么有价和无价消费和所得、价格的弹性关系写清楚,其实不重要。重要的是我在想什么,为什么会想到这些事。

    + +

    那么,记这种漫无章法的东西,做什么呢?也许当个资料笔记,日后做个参考。例如 KONAMINANA PS2 电玩的网址,要是突然中了乐透,就可以买下来;或是小松奈々宫崎あおい等人的日语原名,说不定以后写东西找资料会再用到。也许以后会回头翻,检阅过去的心情、想法,对当时的事件,会有更深一层的体会和成长,而不会什么事都像船过水无痕,一过去就忘了。

    + +

    这些或许,以后都会成为我的资产。谁知道呢?又或许,真的只是一堆无意义的垃圾而已。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 36 | + 37 | + 38 | + 39 | + 40 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0038.html.zh-tw.html b/htdocs/imacat/me/diary/0038.html.zh-tw.html new file mode 120000 index 0000000..6f3e8ab --- /dev/null +++ b/htdocs/imacat/me/diary/0038.html.zh-tw.html @@ -0,0 +1 @@ +0038.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0038.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0038.html.zh-tw.xhtml new file mode 100644 index 0000000..55ac819 --- /dev/null +++ b/htdocs/imacat/me/diary/0038.html.zh-tw.xhtml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷三十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷三十八

    + +
    + +
    + +
    +
    8.11.’06. 2:23am.
    + +

    我發現我新的做事方法,就是想到要做什麼就馬上簡單記一下,然後再從這個清單上把事情一一解決掉的做法,有一個很大的問題。

    + +

    這樣的做法,其實對做瑣碎的小事比較有利,效率比較高。反過來說,對於需要花長時間去研究、學習、創寫的東西,就很不利了。有很多事情可能需要三、五天,甚至三、五個星期才能完成。這些事就會一直懸在那裏。它們比起其它事情,看起來永遠都比較難。和其它事項比較,那些比較好著手、立竿見影的瑣事,我往往會優先去做,以便很快就能減少清單的大小。

    + +

    這樣的確很糟糕。很多重要、需要花長時間的事都延宕掉了。

    + +

    而且我發現,我的清單減少的速度,永遠比不上增加的速度。清單越來越長,而且已經長得有點離譜了。那也就是說,我給自己的工作量,超出我自己時間體力的負荷太多了。這是一個嚴重的問題。也許我應該改變一下,不要那麼嚴苛要求自己吧。

    + +
    + +
    + +
    +
    8.11.’06. 2:18am.
    + +

    日記是寫給自己看的,還是寫給別人看的?

    + +

    為什麼我會問:日記是寫給自己看的,還是寫給別人看的?

    + +

    如果日記是寫給自己看的,那別人看不看得懂,其實不重要。不需要把思緒整理得有條理,不需要起承轉合,不需要詳細說明,不需要字句流暢。只要把想到的事記下來就好。寫下來的東西,也許很差,沒頭沒尾,片斷跳躍,甚至有辱自己的名聲。可是管它的,這些都不重要。我只要把想到的什麼都記下來,這樣就夠了。

    + +

    所以,把什麼有價和無價消費和所得、價格的彈性關係寫清楚,其實不重要。重要的是我在想什麼,為什麼會想到這些事。

    + +

    那麼,記這種漫無章法的東西,做什麼呢?也許當個資料筆記,日後做個參考。例如 KONAMINANA PS2 電玩的網址,要是突然中了樂透,就可以買下來;或是小松奈々宮崎あおい等人的日語原名,說不定以後寫東西找資料會再用到。也許以後會回頭翻,檢閱過去的心情、想法,對當時的事件,會有更深一層的體會和成長,而不會什麼事都像船過水無痕,一過去就忘了。

    + +

    這些或許,以後都會成為我的資產。誰知道呢?又或許,真的只是一堆無意義的垃圾而已。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 36 | + 37 | + 38 | + 39 | + 40 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0039.html.en.html b/htdocs/imacat/me/diary/0039.html.en.html new file mode 120000 index 0000000..63d90e4 --- /dev/null +++ b/htdocs/imacat/me/diary/0039.html.en.html @@ -0,0 +1 @@ +0039.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0039.html.en.xhtml b/htdocs/imacat/me/diary/0039.html.en.xhtml new file mode 100644 index 0000000..50ceaac --- /dev/null +++ b/htdocs/imacat/me/diary/0039.html.en.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 39 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 39

    + +
    + +
    + +
    +
    8.11.’06. 2:32pm.
    + +

    わざとだよ?(如果我是故意的呢?)

    + +

    わざとだよ?(如果我是故意的呢?)

    + +

    這是在 NANA 漫畫原著裏,最經典的台詞之一。羅馬拼音作: wazatodayo?

    + +

    第二集奈々上京後,生活沒有目標,整天閒晃;可是男朋友遠藤章司白天上美術大學,晚上在餐廳打工,忙得沒什麼時間陪她。閒到發慌又愛幻想的奈々,開始幻想章司一定是在東京認識了一個性感美豔的幸子(好俗氣的名字 :p ),夜夜需索無度,才冷落了她。每次和章司僅有的短暫約會,都會吵著吃虛擬幸子的醋。久了以後,原本受不了的章司也被同化了,跟著一搭一唱,幸子又如何愛好名牌、需索無度等等。

    + +
    +「虛擬幸子,別坐在章司上面!」
    +

    虛擬幸子,別坐在章司上面!

    +
    + +

    誰知道弄假成真!第三集第六話有一天晚上,章司打工的餐廳,來了一個新工讀生,個子很小的可愛短髮女生(不是性感美豔喔 :p )。店長要章司負責帶她。嬌小白皙,正好就是章司喜歡的類型。自我介紹時:我叫川村幸子章司震驚到無言以對。命運的相逢,果然是大魔王的詛咒啊~~一聊之下,才知道幸子是系上的同學,連打工下班,回家也是同一個方向,搭同一班電車。

    + +
    +「我叫川村幸子,請多多指教!」
    +

    我叫川村幸子,請多多指教!

    +
    + +

    章司幸子,就這樣每天白天一起上課,晚上一起打工,一起趕最後一班電車。一晚打工結束後,兩個人又在趕地鐵。跑到一半,幸子的高跟涼鞋掉了,要章司先走。章司不忍心,也停下來等她。眼看電車走掉了,章司忍不住抱怨:明知道每天都要趕電車,為什麼還要穿這種鞋子呢?

    + +

    幸子沉默了一會,抬頭說:

    + +

    わざとだよ?(如果我是故意的呢?)

    + +
    +「わざとだよ?(如果我是故意的呢?)」
    +

    わざとだよ?(如果我是故意的呢?)

    +
    + +

    一瞬間,周圍的空氣凝住了。這時,章司的手機響起,是奈々奈々上京的存款亂花光了,盤算打工的復古傢俱店 Sabrina 帥哥店長水越誠一,即將要發薪水時,帥哥水越突然決定結束營業,奈々陷入空前的財務危機,打電話來哭窮…

    + +

    故意?唔…故意什麼?故意穿不好跑步的高跟鞋,哪個晚上不小心掉鞋子,趕不上電車,就有機會可以跟章司獨處過夜了嗎?還是故意什麼?一句話,就讓章司寢食難安。要不是不識相的奈々挑時間打電話來哭窮,章司就上手了,不用再拖兩話三十頁了。真是告白的經典,一定要學起來!

    + +

    不過,大魔王的詛咒,畢竟是不可違逆的。才過了兩話,章司就上手了;再過兩話,章司就和奈々分手了。嗯嗯。

    + +

    香港中譯本 NANA 譯為我故意的!電影對白改為:我是故意的!但日文漫畫原著わざとだよ?就是問句,用反問代替回答,把球又丟回給章司,比起鼓起勇氣直接認了的直述句,感覺有味道得多。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 37 | + 38 | + 39 | + 40 | + 41 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0039.html.zh-cn.html b/htdocs/imacat/me/diary/0039.html.zh-cn.html new file mode 120000 index 0000000..307cec9 --- /dev/null +++ b/htdocs/imacat/me/diary/0039.html.zh-cn.html @@ -0,0 +1 @@ +0039.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0039.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0039.html.zh-cn.xhtml new file mode 100644 index 0000000..f38353d --- /dev/null +++ b/htdocs/imacat/me/diary/0039.html.zh-cn.xhtml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷三十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷三十九

    + +
    + +
    + +
    +
    8.11.’06. 2:32pm.
    + +

    わざとだよ?(如果我是故意的呢?)

    + +

    わざとだよ?(如果我是故意的呢?)

    + +

    这是在 NANA 漫画原著里,最经典的台词之一。罗马拼音作: wazatodayo?

    + +

    第二集奈々上京后,生活没有目标,整天闲晃;可是男朋友远藤章司白天上美术大学,晚上在餐厅打工,忙得没什么时间陪她。闲到发慌又爱幻想的奈々,开始幻想章司一定是在东京认识了一个性感美艳的幸子(好俗气的名字 :p ),夜夜需索无度,才冷落了她。每次和章司仅有的短暂约会,都会吵著吃虚拟幸子的醋。久了以后,原本受不了的章司也被同化了,跟著一搭一唱,幸子又如何爱好名牌、需索无度等等。

    + +
    +「虚拟幸子,别坐在章司上面!」
    +

    虚拟幸子,别坐在章司上面!

    +
    + +

    谁知道弄假成真!第三集第六话有一天晚上,章司打工的餐厅,来了一个新工读生,个子很小的可爱短发女生(不是性感美艳喔 :p )。店长要章司负责带她。娇小白皙,正好就是章司喜欢的类型。自我介绍时:我叫川村幸子章司震惊到无言以对。命运的相逢,果然是大魔王的诅咒啊~~一聊之下,才知道幸子是系上的同学,连打工下班,回家也是同一个方向,搭同一班电车。

    + +
    +「我叫川村幸子,请多多指教!」
    +

    我叫川村幸子,请多多指教!

    +
    + +

    章司幸子,就这样每天白天一起上课,晚上一起打工,一起赶最后一班电车。一晚打工结束后,两个人又在赶地铁。跑到一半,幸子的高跟凉鞋掉了,要章司先走。章司不忍心,也停下来等她。眼看电车走掉了,章司忍不住抱怨:明知道每天都要赶电车,为什么还要穿这种鞋子呢?

    + +

    幸子沉默了一会,抬头说:

    + +

    わざとだよ?(如果我是故意的呢?)

    + +
    +「わざとだよ?(如果我是故意的呢?)」
    +

    わざとだよ?(如果我是故意的呢?)

    +
    + +

    一瞬间,周围的空气凝住了。这时,章司的手机响起,是奈々奈々上京的存款乱花光了,盘算打工的复古家俱店 Sabrina 帅哥店长水越诚一,即将要发薪水时,帅哥水越突然决定结束营业,奈々陷入空前的财务危机,打电话来哭穷…

    + +

    故意?唔…故意什么?故意穿不好跑步的高跟鞋,哪个晚上不小心掉鞋子,赶不上电车,就有机会可以跟章司独处过夜了吗?还是故意什么?一句话,就让章司寝食难安。要不是不识相的奈々挑时间打电话来哭穷,章司就上手了,不用再拖两话三十页了。真是告白的经典,一定要学起来!

    + +

    不过,大魔王的诅咒,毕竟是不可违逆的。才过了两话,章司就上手了;再过两话,章司就和奈々分手了。嗯嗯。

    + +

    香港中译本 NANA 译为我故意的!电影对白改为:我是故意的!但日文漫画原著わざとだよ?就是问句,用反问代替回答,把球又丢回给章司,比起鼓起勇气直接认了的直述句,感觉有味道得多。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 37 | + 38 | + 39 | + 40 | + 41 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0039.html.zh-tw.html b/htdocs/imacat/me/diary/0039.html.zh-tw.html new file mode 120000 index 0000000..192c3f1 --- /dev/null +++ b/htdocs/imacat/me/diary/0039.html.zh-tw.html @@ -0,0 +1 @@ +0039.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0039.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0039.html.zh-tw.xhtml new file mode 100644 index 0000000..47f92ee --- /dev/null +++ b/htdocs/imacat/me/diary/0039.html.zh-tw.xhtml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷三十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷三十九

    + +
    + +
    + +
    +
    8.11.’06. 2:32pm.
    + +

    わざとだよ?(如果我是故意的呢?)

    + +

    わざとだよ?(如果我是故意的呢?)

    + +

    這是在 NANA 漫畫原著裏,最經典的台詞之一。羅馬拼音作: wazatodayo?

    + +

    第二集奈々上京後,生活沒有目標,整天閒晃;可是男朋友遠藤章司白天上美術大學,晚上在餐廳打工,忙得沒什麼時間陪她。閒到發慌又愛幻想的奈々,開始幻想章司一定是在東京認識了一個性感美豔的幸子(好俗氣的名字 :p ),夜夜需索無度,才冷落了她。每次和章司僅有的短暫約會,都會吵著吃虛擬幸子的醋。久了以後,原本受不了的章司也被同化了,跟著一搭一唱,幸子又如何愛好名牌、需索無度等等。

    + +
    +「虛擬幸子,別坐在章司上面!」
    +

    虛擬幸子,別坐在章司上面!

    +
    + +

    誰知道弄假成真!第三集第六話有一天晚上,章司打工的餐廳,來了一個新工讀生,個子很小的可愛短髮女生(不是性感美豔喔 :p )。店長要章司負責帶她。嬌小白皙,正好就是章司喜歡的類型。自我介紹時:我叫川村幸子章司震驚到無言以對。命運的相逢,果然是大魔王的詛咒啊~~一聊之下,才知道幸子是系上的同學,連打工下班,回家也是同一個方向,搭同一班電車。

    + +
    +「我叫川村幸子,請多多指教!」
    +

    我叫川村幸子,請多多指教!

    +
    + +

    章司幸子,就這樣每天白天一起上課,晚上一起打工,一起趕最後一班電車。一晚打工結束後,兩個人又在趕地鐵。跑到一半,幸子的高跟涼鞋掉了,要章司先走。章司不忍心,也停下來等她。眼看電車走掉了,章司忍不住抱怨:明知道每天都要趕電車,為什麼還要穿這種鞋子呢?

    + +

    幸子沉默了一會,抬頭說:

    + +

    わざとだよ?(如果我是故意的呢?)

    + +
    +「わざとだよ?(如果我是故意的呢?)」
    +

    わざとだよ?(如果我是故意的呢?)

    +
    + +

    一瞬間,周圍的空氣凝住了。這時,章司的手機響起,是奈々奈々上京的存款亂花光了,盤算打工的復古傢俱店 Sabrina 帥哥店長水越誠一,即將要發薪水時,帥哥水越突然決定結束營業,奈々陷入空前的財務危機,打電話來哭窮…

    + +

    故意?唔…故意什麼?故意穿不好跑步的高跟鞋,哪個晚上不小心掉鞋子,趕不上電車,就有機會可以跟章司獨處過夜了嗎?還是故意什麼?一句話,就讓章司寢食難安。要不是不識相的奈々挑時間打電話來哭窮,章司就上手了,不用再拖兩話三十頁了。真是告白的經典,一定要學起來!

    + +

    不過,大魔王的詛咒,畢竟是不可違逆的。才過了兩話,章司就上手了;再過兩話,章司就和奈々分手了。嗯嗯。

    + +

    香港中譯本 NANA 譯為我故意的!電影對白改為:我是故意的!但日文漫畫原著わざとだよ?就是問句,用反問代替回答,把球又丟回給章司,比起鼓起勇氣直接認了的直述句,感覺有味道得多。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 37 | + 38 | + 39 | + 40 | + 41 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0040.html.en.html b/htdocs/imacat/me/diary/0040.html.en.html new file mode 120000 index 0000000..3c16748 --- /dev/null +++ b/htdocs/imacat/me/diary/0040.html.en.html @@ -0,0 +1 @@ +0040.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0040.html.en.xhtml b/htdocs/imacat/me/diary/0040.html.en.xhtml new file mode 100644 index 0000000..25a7563 --- /dev/null +++ b/htdocs/imacat/me/diary/0040.html.en.xhtml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 40 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 40

    + +
    + +
    + +
    +
    8.11.’06. 5:41pm.
    + +

    佐藤公一Jackson Hole

    + +

    漫畫 NANA 中,有個很特別的人物:佐藤公一和他的餐廳 Jackson Hole

    + +

    很特別的是,漫畫裏的人互相稱呼,都單叫名字或外號。只有佐藤公一,也不知道為什麼,所有人都是全名佐藤公一佐藤公一地叫。

    + +

    佐藤公一是誰?他是 NANA 漫畫中人物住家附近一家叫做 Jackson Hole 的餐廳店長。因為 Jackson Hole 的漢堡太好吃了(全世界最好吃的漢堡?),離家、學校、打工地點又近,大家常常去晃,吃 Jackson Hole 的漢堡當午晚餐。很多劇情,也都在 Jackson Hole 店裏發生。章司變心,跟幸子在一起,痛失男主角寶座後,沒臉見一起上京唸書的高中同學淳子京助,就很少登場了。可是他還是習慣性去 Jackson Hole 吃飯,偶爾尷尬地碰到淳子京助,偶爾外帶漢堡回去給幸子。不過最尷尬的,還是第十一集多摩川煙火大會,碰到奈々那一次。佐藤公一是唯一一個奈々沒有一見鍾情愛上的帥哥店長。

    + +

    不過最特別的是:佐藤公一是實際存在的人物,而 Jackson Hole 則是實際存在的餐廳!現實生活中,佐藤公一就是 Jackson Hole 的店長。作者矢沢あい因為覺得 Jackson Hole 的漢堡超級好吃,就把 Jackson Hole 和店長佐藤公一畫進漫畫去了。店裏的擺設和漫畫一模一樣。不過兩個佐藤公一不一樣:漫畫佐藤公一梳黑人頭,真人佐藤公一沒有。這是 NANA 中唯一真實存在的事物。

    + +
    +漫畫第二集登場的 Jackson Hole 餐廳
    +

    漫畫第二集登場的 Jackson Hole 餐廳

    +
    + +
    +現實中東京調布的 Jackson Hole 餐廳
    +

    現實中東京調布的 Jackson Hole 餐廳

    +
    + +
    +漫畫第二集登場的 Jackson Hole 黑人頭帥哥店長佐藤公一
    +

    漫畫第二集登場的 Jackson Hole 黑人頭帥哥店長佐藤公一

    +
    + +
    +真人 Jackson Hole 店長佐藤公一,沒有黑人頭喔~
    +

    真人 Jackson Hole 店長佐藤公一,沒有黑人頭喔~

    +
    + +

    託漫畫 NANA 的福, Jackson Hole 現在生意好得不得了。很多 NANA 迷專程跑去,就是為了朝聖。地址在東京都調布市小島町 2-45-26 ,調布站出口走一小段路就到了。有機會,我也要去朝聖一下!

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 38 | + 39 | + 40 | + 41 | + 42 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0040.html.zh-cn.html b/htdocs/imacat/me/diary/0040.html.zh-cn.html new file mode 120000 index 0000000..2b19b40 --- /dev/null +++ b/htdocs/imacat/me/diary/0040.html.zh-cn.html @@ -0,0 +1 @@ +0040.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0040.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0040.html.zh-cn.xhtml new file mode 100644 index 0000000..ab65228 --- /dev/null +++ b/htdocs/imacat/me/diary/0040.html.zh-cn.xhtml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷四十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷四十

    + +
    + +
    + +
    +
    8.11.’06. 5:41pm.
    + +

    佐藤公一Jackson Hole

    + +

    漫画 NANA 中,有个很特别的人物:佐藤公一和他的餐厅 Jackson Hole

    + +

    很特别的是,漫画里的人互相称呼,都单叫名字或外号。只有佐藤公一,也不知道为什么,所有人都是全名佐藤公一佐藤公一地叫。

    + +

    佐藤公一是谁?他是 NANA 漫画中人物住家附近一家叫做 Jackson Hole 的餐厅店长。因为 Jackson Hole 的汉堡太好吃了(全世界最好吃的汉堡?),离家、学校、打工地点又近,大家常常去晃,吃 Jackson Hole 的汉堡当午晚餐。很多剧情,也都在 Jackson Hole 店里发生。章司变心,跟幸子在一起,痛失男主角宝座后,没脸见一起上京念书的高中同学淳子京助,就很少登场了。可是他还是习惯性去 Jackson Hole 吃饭,偶尔尴尬地碰到淳子京助,偶尔外带汉堡回去给幸子。不过最尴尬的,还是第十一集多摩川烟火大会,碰到奈々那一次。佐藤公一是唯一一个奈々没有一见钟情爱上的帅哥店长。

    + +

    不过最特别的是:佐藤公一是实际存在的人物,而 Jackson Hole 则是实际存在的餐厅!现实生活中,佐藤公一就是 Jackson Hole 的店长。作者矢沢あい因为觉得 Jackson Hole 的汉堡超级好吃,就把 Jackson Hole 和店长佐藤公一画进漫画去了。店里的摆设和漫画一模一样。不过两个佐藤公一不一样:漫画佐藤公一梳黑人头,真人佐藤公一没有。这是 NANA 中唯一真实存在的事物。

    + +
    +漫画第二集登场的 Jackson Hole 餐厅
    +

    漫画第二集登场的 Jackson Hole 餐厅

    +
    + +
    +现实中东京调布的 Jackson Hole 餐厅
    +

    现实中东京调布的 Jackson Hole 餐厅

    +
    + +
    +漫画第二集登场的 Jackson Hole 黑人头帅哥店长佐藤公一
    +

    漫画第二集登场的 Jackson Hole 黑人头帅哥店长佐藤公一

    +
    + +
    +真人 Jackson Hole 店长佐藤公一,没有黑人头喔~
    +

    真人 Jackson Hole 店长佐藤公一,没有黑人头喔~

    +
    + +

    托漫画 NANA 的福, Jackson Hole 现在生意好得不得了。很多 NANA 迷专程跑去,就是为了朝圣。地址在东京都调布市小岛町 2-45-26 ,调布站出口走一小段路就到了。有机会,我也要去朝圣一下!

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 38 | + 39 | + 40 | + 41 | + 42 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0040.html.zh-tw.html b/htdocs/imacat/me/diary/0040.html.zh-tw.html new file mode 120000 index 0000000..3388ce6 --- /dev/null +++ b/htdocs/imacat/me/diary/0040.html.zh-tw.html @@ -0,0 +1 @@ +0040.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0040.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0040.html.zh-tw.xhtml new file mode 100644 index 0000000..1247c42 --- /dev/null +++ b/htdocs/imacat/me/diary/0040.html.zh-tw.xhtml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷四十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷四十

    + +
    + +
    + +
    +
    8.11.’06. 5:41pm.
    + +

    佐藤公一Jackson Hole

    + +

    漫畫 NANA 中,有個很特別的人物:佐藤公一和他的餐廳 Jackson Hole

    + +

    很特別的是,漫畫裏的人互相稱呼,都單叫名字或外號。只有佐藤公一,也不知道為什麼,所有人都是全名佐藤公一佐藤公一地叫。

    + +

    佐藤公一是誰?他是 NANA 漫畫中人物住家附近一家叫做 Jackson Hole 的餐廳店長。因為 Jackson Hole 的漢堡太好吃了(全世界最好吃的漢堡?),離家、學校、打工地點又近,大家常常去晃,吃 Jackson Hole 的漢堡當午晚餐。很多劇情,也都在 Jackson Hole 店裏發生。章司變心,跟幸子在一起,痛失男主角寶座後,沒臉見一起上京唸書的高中同學淳子京助,就很少登場了。可是他還是習慣性去 Jackson Hole 吃飯,偶爾尷尬地碰到淳子京助,偶爾外帶漢堡回去給幸子。不過最尷尬的,還是第十一集多摩川煙火大會,碰到奈々那一次。佐藤公一是唯一一個奈々沒有一見鍾情愛上的帥哥店長。

    + +

    不過最特別的是:佐藤公一是實際存在的人物,而 Jackson Hole 則是實際存在的餐廳!現實生活中,佐藤公一就是 Jackson Hole 的店長。作者矢沢あい因為覺得 Jackson Hole 的漢堡超級好吃,就把 Jackson Hole 和店長佐藤公一畫進漫畫去了。店裏的擺設和漫畫一模一樣。不過兩個佐藤公一不一樣:漫畫佐藤公一梳黑人頭,真人佐藤公一沒有。這是 NANA 中唯一真實存在的事物。

    + +
    +漫畫第二集登場的 Jackson Hole 餐廳
    +

    漫畫第二集登場的 Jackson Hole 餐廳

    +
    + +
    +現實中東京調布的 Jackson Hole 餐廳
    +

    現實中東京調布的 Jackson Hole 餐廳

    +
    + +
    +漫畫第二集登場的 Jackson Hole 黑人頭帥哥店長佐藤公一
    +

    漫畫第二集登場的 Jackson Hole 黑人頭帥哥店長佐藤公一

    +
    + +
    +真人 Jackson Hole 店長佐藤公一,沒有黑人頭喔~
    +

    真人 Jackson Hole 店長佐藤公一,沒有黑人頭喔~

    +
    + +

    託漫畫 NANA 的福, Jackson Hole 現在生意好得不得了。很多 NANA 迷專程跑去,就是為了朝聖。地址在東京都調布市小島町 2-45-26 ,調布站出口走一小段路就到了。有機會,我也要去朝聖一下!

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 38 | + 39 | + 40 | + 41 | + 42 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0041.html.en.html b/htdocs/imacat/me/diary/0041.html.en.html new file mode 120000 index 0000000..4a4e997 --- /dev/null +++ b/htdocs/imacat/me/diary/0041.html.en.html @@ -0,0 +1 @@ +0041.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0041.html.en.xhtml b/htdocs/imacat/me/diary/0041.html.en.xhtml new file mode 100644 index 0000000..9126096 --- /dev/null +++ b/htdocs/imacat/me/diary/0041.html.en.xhtml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 41 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 41

    + +
    + +
    + +
    +
    8.12.’06. 5:08am.
    + +

    上原美里

    + +

    原著漫畫 NANA ,有一個重要角色,電影中完全沒有出現,就是從 BLAST 北海道剛成團,一直追隨到著ナナ到東京的瘋狂歌迷上原美里

    + +
    +上原美里
    +

    上原美里

    +
    + +

    我在 Google 一查上原美里,就查到ナナ可能會被美里殺死的謠言。不會吧?ナナ要死,也是被殺死才對,這樣才能完成 SidNancy 龐克搖滾的悲劇傳奇!

    + +

    唔…不對,ナナ還是別死的好。管它什麼龐克搖滾悲劇傳奇!哼哼!

    + +

    永遠一身可愛 lorita 裝,燙金捲髮的上原美里,是ナナ的瘋狂歌迷,一路追隨ナナ從北海道到東京,只要ナナ有演唱會,馬上從北海道飛撲而來,每次都會送ナナ最喜歡的 Vivienne Westwoodナナ也從不虧待這個忠實歌迷,除了以吻回報外(真方便啊, Vivienne Westwood 耶~),東京初唱還特地通知美里(撐場面? :p )第四集ナナBLAST 在東京的初唱,奈々興沖沖去捧場,意外碰到美里,沒想到還有別人比自己更貼近ナナ,不禁開始吃醋。後來第三次現場演唱的慶功宴,ナナ失約沒回家,還要奈々把電話轉給美里奈々心中一酸,打電話給 TAKUMI 一ノ瀬巧,使得劇情開始脫軌,打亂了作者矢沢あい的計劃。奈々TAKUMI 搞在一起,就是美里害的。別看美里毫不起眼,連電影版都省略掉,其實是個邪惡可怕的女人!說不定美里的真正身份,就是大魔王的使者!

    + +
    +上原美里突然出現對ナナ獻花,讓奈々不知所措
    +

    上原美里突然出現對ナナ獻花,讓奈々不知所措

    +
    + +

    不過上原美里,似乎不像表面上那麼簡單。高木泰士(阿泰)最早看出,上原美里是假名。美里高中畢業後,為了追隨 BLAST 也上京了,到 BLAST 所屬的四海經紀公司應徵,當上了 BLAST 的助理,因為寫履歷表、報稅,大家才知道她的本名是都築舞。詭異的是, BLAST 成名以後,在八卦雜誌挖掘下,發現ナナ似乎有一個同母異父的妹妹,名字就叫作上原美里!而歌迷美里卻像從頭到尾都知道這件事一樣。真是太詭異了~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 39 | + 40 | + 41 | + 42 | + 43 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0041.html.zh-cn.html b/htdocs/imacat/me/diary/0041.html.zh-cn.html new file mode 120000 index 0000000..0a38621 --- /dev/null +++ b/htdocs/imacat/me/diary/0041.html.zh-cn.html @@ -0,0 +1 @@ +0041.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0041.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0041.html.zh-cn.xhtml new file mode 100644 index 0000000..26901f4 --- /dev/null +++ b/htdocs/imacat/me/diary/0041.html.zh-cn.xhtml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷四十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷四十一

    + +
    + +
    + +
    +
    8.12.’06. 5:08am.
    + +

    上原美里

    + +

    原著漫画 NANA ,有一个重要角色,电影中完全没有出现,就是从 BLAST 北海道刚成团,一直追随到著ナナ到东京的疯狂歌迷上原美里

    + +
    +上原美里
    +

    上原美里

    +
    + +

    我在 Google 一查上原美里,就查到ナナ可能会被美里杀死的谣言。不会吧?ナナ要死,也是被杀死才对,这样才能完成 SidNancy 庞克摇滚的悲剧传奇!

    + +

    唔…不对,ナナ还是别死的好。管它什么庞克摇滚悲剧传奇!哼哼!

    + +

    永远一身可爱 lorita 装,烫金卷发的上原美里,是ナナ的疯狂歌迷,一路追随ナナ从北海道到东京,只要ナナ有演唱会,马上从北海道飞扑而来,每次都会送ナナ最喜欢的 Vivienne Westwoodナナ也从不亏待这个忠实歌迷,除了以吻回报外(真方便啊, Vivienne Westwood 耶~),东京初唱还特地通知美里(撑场面? :p )第四集ナナBLAST 在东京的初唱,奈々兴冲冲去捧场,意外碰到美里,没想到还有别人比自己更贴近ナナ,不禁开始吃醋。后来第三次现场演唱的庆功宴,ナナ失约没回家,还要奈々把电话转给美里奈々心中一酸,打电话给 TAKUMI 一ノ瀬巧,使得剧情开始脱轨,打乱了作者矢沢あい的计划。奈々TAKUMI 搞在一起,就是美里害的。别看美里毫不起眼,连电影版都省略掉,其实是个邪恶可怕的女人!说不定美里的真正身份,就是大魔王的使者!

    + +
    +上原美里突然出现对ナナ献花,让奈々不知所措
    +

    上原美里突然出现对ナナ献花,让奈々不知所措

    +
    + +

    不过上原美里,似乎不像表面上那么简单。高木泰士(阿泰)最早看出,上原美里是假名。美里高中毕业后,为了追随 BLAST 也上京了,到 BLAST 所属的四海经纪公司应徵,当上了 BLAST 的助理,因为写履历表、报税,大家才知道她的本名是都筑舞。诡异的是, BLAST 成名以后,在八卦杂志挖掘下,发现ナナ似乎有一个同母异父的妹妹,名字就叫作上原美里!而歌迷美里却像从头到尾都知道这件事一样。真是太诡异了~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 39 | + 40 | + 41 | + 42 | + 43 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0041.html.zh-tw.html b/htdocs/imacat/me/diary/0041.html.zh-tw.html new file mode 120000 index 0000000..65a3b60 --- /dev/null +++ b/htdocs/imacat/me/diary/0041.html.zh-tw.html @@ -0,0 +1 @@ +0041.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0041.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0041.html.zh-tw.xhtml new file mode 100644 index 0000000..b46ce59 --- /dev/null +++ b/htdocs/imacat/me/diary/0041.html.zh-tw.xhtml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷四十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷四十一

    + +
    + +
    + +
    +
    8.12.’06. 5:08am.
    + +

    上原美里

    + +

    原著漫畫 NANA ,有一個重要角色,電影中完全沒有出現,就是從 BLAST 北海道剛成團,一直追隨到著ナナ到東京的瘋狂歌迷上原美里

    + +
    +上原美里
    +

    上原美里

    +
    + +

    我在 Google 一查上原美里,就查到ナナ可能會被美里殺死的謠言。不會吧?ナナ要死,也是被殺死才對,這樣才能完成 SidNancy 龐克搖滾的悲劇傳奇!

    + +

    唔…不對,ナナ還是別死的好。管它什麼龐克搖滾悲劇傳奇!哼哼!

    + +

    永遠一身可愛 lorita 裝,燙金捲髮的上原美里,是ナナ的瘋狂歌迷,一路追隨ナナ從北海道到東京,只要ナナ有演唱會,馬上從北海道飛撲而來,每次都會送ナナ最喜歡的 Vivienne Westwoodナナ也從不虧待這個忠實歌迷,除了以吻回報外(真方便啊, Vivienne Westwood 耶~),東京初唱還特地通知美里(撐場面? :p )第四集ナナBLAST 在東京的初唱,奈々興沖沖去捧場,意外碰到美里,沒想到還有別人比自己更貼近ナナ,不禁開始吃醋。後來第三次現場演唱的慶功宴,ナナ失約沒回家,還要奈々把電話轉給美里奈々心中一酸,打電話給 TAKUMI 一ノ瀬巧,使得劇情開始脫軌,打亂了作者矢沢あい的計劃。奈々TAKUMI 搞在一起,就是美里害的。別看美里毫不起眼,連電影版都省略掉,其實是個邪惡可怕的女人!說不定美里的真正身份,就是大魔王的使者!

    + +
    +上原美里突然出現對ナナ獻花,讓奈々不知所措
    +

    上原美里突然出現對ナナ獻花,讓奈々不知所措

    +
    + +

    不過上原美里,似乎不像表面上那麼簡單。高木泰士(阿泰)最早看出,上原美里是假名。美里高中畢業後,為了追隨 BLAST 也上京了,到 BLAST 所屬的四海經紀公司應徵,當上了 BLAST 的助理,因為寫履歷表、報稅,大家才知道她的本名是都築舞。詭異的是, BLAST 成名以後,在八卦雜誌挖掘下,發現ナナ似乎有一個同母異父的妹妹,名字就叫作上原美里!而歌迷美里卻像從頭到尾都知道這件事一樣。真是太詭異了~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 39 | + 40 | + 41 | + 42 | + 43 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0042.html.en.html b/htdocs/imacat/me/diary/0042.html.en.html new file mode 120000 index 0000000..2526246 --- /dev/null +++ b/htdocs/imacat/me/diary/0042.html.en.html @@ -0,0 +1 @@ +0042.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0042.html.en.xhtml b/htdocs/imacat/me/diary/0042.html.en.xhtml new file mode 100644 index 0000000..9ad87b2 --- /dev/null +++ b/htdocs/imacat/me/diary/0042.html.en.xhtml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 42 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 42

    + +
    + +
    + +
    +
    8.13.’06. 1:28am.
    + +

    Ultraviolet 紫光任務—穿過身體的水晶玻璃

    + +
    +Ultraviolet 紫光任務
    +

    Ultraviolet 紫光任務

    +
    + + + +

    紫光任務真的很難看。我是衝著 DVD 外盒上蜜拉喬娃維琪超酷的表情,加上我又喜歡看動作片,喜歡看女生打架,才去看的。看之前,就已經讀到了幾篇負面的影評。看完之後,我實在是笑不出來。

    + +

    如果妳像我一樣,喜歡看女生打架,看女子摔角,那妳可以看一看,就當作是多加一筆看女子動作電影的記錄。否則就免了。真的免了。就算是從網路下載,沒浪費到錢,也是浪費時間。

    + +

    裏面的武打動作,完全沒有說服力。紫光和血幫在頂樓戰鬥那一場,一群血幫雜魚站八掛方位,人人手握手槍,把紫光圍在中間。怎麼可能笨到這種地步!手槍耶!又不是刀劍,怎麼可以圍成一圈?不怕對射打到自己人嗎?果然,紫光閃來閃去,一群人自己射自己,一下子就全死光了。

    + +

    另一個場景:一群警察端著手槍圍著紫光,逐漸齊步走近,直到槍口端在紫光鼻子前面的距離,紫光迴身一圈,所有警察就被劈成兩半。笨蛋啊?警察的目的不就是去殺紫光嗎?槍不是遠距離武器嗎?就算要逮補,也可以先射傷紫光再說啊,也可以一個人走近,其它人遠遠監視啊!到底走近幹嘛?

    + +

    還有一個場景:最後大戰,紫光殺入衛生署。最後一個房間裏,一群警察握劍,和紫光以劍相搏。打到最後,紫光用腿把最後一個警察鎖在地上,手握著一把斷劍的劍鋒,一劍刺下去。結束後,紫光喘著氣,看著自己掌心好幾道劍傷,血染紅了白衣服,索性把衣服切換成血紅色的(紫光穿的衣服是可以變色的)。這時候紫光已經傷痕累累,不過總算打到最後一關,衛生署長的辦公室前了。

    + +

    可是,她幹嘛讓自己受傷啊?她已經以腿鎖死那個警察了。以她的拳力,一拳不夠,多補一拳,一定可以殺了他。說起來她完全沒有被警察砍到,所有的傷都是自己赤手握劍鋒造成的。幹嘛一定要赤手握劍鋒?廢話當然會割傷。紫光可以全身無傷打到最後一關,卻一定要自己傷到自己。做這種怪事到底幹嘛?

    + +

    還有一開始那場飛車追逐戰,一看就知道不是真的在騎車,蜜拉喬娃維琪只是在藍幕前演騎車的樣子,剩下的全是電腦加上去的。其實這也不是什麼新鮮事,人本來就不可能違反重力,在大樓牆上騎車了。不過飛濺的碎玻璃,晶螢剔透得像水晶一樣,還可以從紫光身上穿過去,而且不會因重力往下掉,也未免太扯了。電影特效看這麼多年,破綻這麼多,假到讓人不忍卒睹的畫面,還是第一次看到。

    + +

    還有片中的紫光,一腳可以踢死一個穿防彈衣的警察。可是像那樣隨便踢一踢,要一腳踢死一個穿防彈衣的警察,實在是太沒有說服力了。我不要求要像李小龍、李連杰、楊紫瓊一樣真功夫,但至少也要做到像奇諾李維 Keanu Reeves駭客任務 The Matrix (1999)一樣,才有說服力吧。

    + +

    像這樣愚蠢的場景,不勝其數。

    + +

    劇情就更不用提了,網路上已經罵翻了。我是事後補看幾篇影評,才知道紫光的是職業殺手。哦~難怪她殺人如麻,卻拼死要救一個小男孩,還說是小男孩救了她。我一直搞不懂紫光到底是幹嘛的,為什麼殺那麼多人,只為救一個人。我還以為這是因為漫畫改編,把一些細緻的劇情都刪掉了,所以才不清不楚。上網一查,才知道是寇特威莫的原創作品,拍得像漫畫一樣。那麼…這種背景不交待誰知道啊!

    + +

    還有,紫光到底是怎麼對小六,產生母子之情的呢?整部戲只有交待一點點,給我感覺太牽強了。

    + +

    除此以外,沒有別的劇情。

    + +

    這部電影唯一不錯的地方,在於劇情架構(不是劇情喔!)可以想像得出,寇特威莫想拍的題裁,其實很棒。不過劇情很爛,沒拍出什麼劇情;動作場景很扯,特效也很沒有說服力。不管從哪個角度來看,毋庸置疑,都是一部大爛片。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 40 | + 41 | + 42 | + 43 | + 44 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0042.html.zh-cn.html b/htdocs/imacat/me/diary/0042.html.zh-cn.html new file mode 120000 index 0000000..21d3b8b --- /dev/null +++ b/htdocs/imacat/me/diary/0042.html.zh-cn.html @@ -0,0 +1 @@ +0042.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0042.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0042.html.zh-cn.xhtml new file mode 100644 index 0000000..908ccd7 --- /dev/null +++ b/htdocs/imacat/me/diary/0042.html.zh-cn.xhtml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷四十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷四十二

    + +
    + +
    + +
    +
    8.13.’06. 1:28am.
    + +

    Ultraviolet 紫光任务—穿过身体的水晶玻璃

    + +
    +Ultraviolet 紫光任务
    +

    Ultraviolet 紫光任务

    +
    + + + +

    紫光任务真的很难看。我是冲著 DVD 外盒上蜜拉乔娃维琪超酷的表情,加上我又喜欢看动作片,喜欢看女生打架,才去看的。看之前,就已经读到了几篇负面的影评。看完之后,我实在是笑不出来。

    + +

    如果你像我一样,喜欢看女生打架,看女子摔角,那你可以看一看,就当作是多加一笔看女子动作电影的记录。否则就免了。真的免了。就算是从网路下载,没浪费到钱,也是浪费时间。

    + +

    里面的武打动作,完全没有说服力。紫光和血帮在顶楼战斗那一场,一群血帮杂鱼站八挂方位,人人手握手枪,把紫光围在中间。怎么可能笨到这种地步!手枪耶!又不是刀剑,怎么可以围成一圈?不怕对射打到自己人吗?果然,紫光闪来闪去,一群人自己射自己,一下子就全死光了。

    + +

    另一个场景:一群警察端著手枪围著紫光,逐渐齐步走近,直到枪口端在紫光鼻子前面的距离,紫光回身一圈,所有警察就被劈成两半。笨蛋啊?警察的目的不就是去杀紫光吗?枪不是远距离武器吗?就算要逮补,也可以先射伤紫光再说啊,也可以一个人走近,其它人远远监视啊!到底走近干嘛?

    + +

    还有一个场景:最后大战,紫光杀入卫生署。最后一个房间里,一群警察握剑,和紫光以剑相搏。打到最后,紫光用腿把最后一个警察锁在地上,手握著一把断剑的剑锋,一剑刺下去。结束后,紫光喘著气,看著自己掌心好几道剑伤,血染红了白衣服,索性把衣服切换成血红色的(紫光穿的衣服是可以变色的)。这时候紫光已经伤痕累累,不过总算打到最后一关,卫生署长的办公室前了。

    + +

    可是,她干嘛让自己受伤啊?她已经以腿锁死那个警察了。以她的拳力,一拳不够,多补一拳,一定可以杀了他。说起来她完全没有被警察砍到,所有的伤都是自己赤手握剑锋造成的。干嘛一定要赤手握剑锋?废话当然会割伤。紫光可以全身无伤打到最后一关,却一定要自己伤到自己。做这种怪事到底干嘛?

    + +

    还有一开始那场飞车追逐战,一看就知道不是真的在骑车,蜜拉乔娃维琪只是在蓝幕前演骑车的样子,剩下的全是电脑加上去的。其实这也不是什么新鲜事,人本来就不可能违反重力,在大楼墙上骑车了。不过飞溅的碎玻璃,晶萤剔透得像水晶一样,还可以从紫光身上穿过去,而且不会因重力往下掉,也未免太扯了。电影特效看这么多年,破绽这么多,假到让人不忍卒睹的画面,还是第一次看到。

    + +

    还有片中的紫光,一脚可以踢死一个穿防弹衣的警察。可是像那样随便踢一踢,要一脚踢死一个穿防弹衣的警察,实在是太没有说服力了。我不要求要像李小龙、李连杰、杨紫琼一样真功夫,但至少也要做到像奇诺李维 Keanu Reeves骇客任务 The Matrix (1999)一样,才有说服力吧。

    + +

    像这样愚蠢的场景,不胜其数。

    + +

    剧情就更不用提了,网路上已经骂翻了。我是事后补看几篇影评,才知道紫光的是职业杀手。哦~难怪她杀人如麻,却拼死要救一个小男孩,还说是小男孩救了她。我一直搞不懂紫光到底是干嘛的,为什么杀那么多人,只为救一个人。我还以为这是因为漫画改编,把一些细致的剧情都删掉了,所以才不清不楚。上网一查,才知道是寇特威莫的原创作品,拍得像漫画一样。那么…这种背景不交待谁知道啊!

    + +

    还有,紫光到底是怎么对小六,产生母子之情的呢?整部戏只有交待一点点,给我感觉太牵强了。

    + +

    除此以外,没有别的剧情。

    + +

    这部电影唯一不错的地方,在於剧情架构(不是剧情喔!)可以想像得出,寇特威莫想拍的题裁,其实很棒。不过剧情很烂,没拍出什么剧情;动作场景很扯,特效也很没有说服力。不管从哪个角度来看,毋庸置疑,都是一部大烂片。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 40 | + 41 | + 42 | + 43 | + 44 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0042.html.zh-tw.html b/htdocs/imacat/me/diary/0042.html.zh-tw.html new file mode 120000 index 0000000..779968f --- /dev/null +++ b/htdocs/imacat/me/diary/0042.html.zh-tw.html @@ -0,0 +1 @@ +0042.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0042.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0042.html.zh-tw.xhtml new file mode 100644 index 0000000..e57efa9 --- /dev/null +++ b/htdocs/imacat/me/diary/0042.html.zh-tw.xhtml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷四十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷四十二

    + +
    + +
    + +
    +
    8.13.’06. 1:28am.
    + +

    Ultraviolet 紫光任務—穿過身體的水晶玻璃

    + +
    +Ultraviolet 紫光任務
    +

    Ultraviolet 紫光任務

    +
    + + + +

    紫光任務真的很難看。我是衝著 DVD 外盒上蜜拉喬娃維琪超酷的表情,加上我又喜歡看動作片,喜歡看女生打架,才去看的。看之前,就已經讀到了幾篇負面的影評。看完之後,我實在是笑不出來。

    + +

    如果妳像我一樣,喜歡看女生打架,看女子摔角,那妳可以看一看,就當作是多加一筆看女子動作電影的記錄。否則就免了。真的免了。就算是從網路下載,沒浪費到錢,也是浪費時間。

    + +

    裏面的武打動作,完全沒有說服力。紫光和血幫在頂樓戰鬥那一場,一群血幫雜魚站八掛方位,人人手握手槍,把紫光圍在中間。怎麼可能笨到這種地步!手槍耶!又不是刀劍,怎麼可以圍成一圈?不怕對射打到自己人嗎?果然,紫光閃來閃去,一群人自己射自己,一下子就全死光了。

    + +

    另一個場景:一群警察端著手槍圍著紫光,逐漸齊步走近,直到槍口端在紫光鼻子前面的距離,紫光迴身一圈,所有警察就被劈成兩半。笨蛋啊?警察的目的不就是去殺紫光嗎?槍不是遠距離武器嗎?就算要逮補,也可以先射傷紫光再說啊,也可以一個人走近,其它人遠遠監視啊!到底走近幹嘛?

    + +

    還有一個場景:最後大戰,紫光殺入衛生署。最後一個房間裏,一群警察握劍,和紫光以劍相搏。打到最後,紫光用腿把最後一個警察鎖在地上,手握著一把斷劍的劍鋒,一劍刺下去。結束後,紫光喘著氣,看著自己掌心好幾道劍傷,血染紅了白衣服,索性把衣服切換成血紅色的(紫光穿的衣服是可以變色的)。這時候紫光已經傷痕累累,不過總算打到最後一關,衛生署長的辦公室前了。

    + +

    可是,她幹嘛讓自己受傷啊?她已經以腿鎖死那個警察了。以她的拳力,一拳不夠,多補一拳,一定可以殺了他。說起來她完全沒有被警察砍到,所有的傷都是自己赤手握劍鋒造成的。幹嘛一定要赤手握劍鋒?廢話當然會割傷。紫光可以全身無傷打到最後一關,卻一定要自己傷到自己。做這種怪事到底幹嘛?

    + +

    還有一開始那場飛車追逐戰,一看就知道不是真的在騎車,蜜拉喬娃維琪只是在藍幕前演騎車的樣子,剩下的全是電腦加上去的。其實這也不是什麼新鮮事,人本來就不可能違反重力,在大樓牆上騎車了。不過飛濺的碎玻璃,晶螢剔透得像水晶一樣,還可以從紫光身上穿過去,而且不會因重力往下掉,也未免太扯了。電影特效看這麼多年,破綻這麼多,假到讓人不忍卒睹的畫面,還是第一次看到。

    + +

    還有片中的紫光,一腳可以踢死一個穿防彈衣的警察。可是像那樣隨便踢一踢,要一腳踢死一個穿防彈衣的警察,實在是太沒有說服力了。我不要求要像李小龍、李連杰、楊紫瓊一樣真功夫,但至少也要做到像奇諾李維 Keanu Reeves駭客任務 The Matrix (1999)一樣,才有說服力吧。

    + +

    像這樣愚蠢的場景,不勝其數。

    + +

    劇情就更不用提了,網路上已經罵翻了。我是事後補看幾篇影評,才知道紫光的是職業殺手。哦~難怪她殺人如麻,卻拼死要救一個小男孩,還說是小男孩救了她。我一直搞不懂紫光到底是幹嘛的,為什麼殺那麼多人,只為救一個人。我還以為這是因為漫畫改編,把一些細緻的劇情都刪掉了,所以才不清不楚。上網一查,才知道是寇特威莫的原創作品,拍得像漫畫一樣。那麼…這種背景不交待誰知道啊!

    + +

    還有,紫光到底是怎麼對小六,產生母子之情的呢?整部戲只有交待一點點,給我感覺太牽強了。

    + +

    除此以外,沒有別的劇情。

    + +

    這部電影唯一不錯的地方,在於劇情架構(不是劇情喔!)可以想像得出,寇特威莫想拍的題裁,其實很棒。不過劇情很爛,沒拍出什麼劇情;動作場景很扯,特效也很沒有說服力。不管從哪個角度來看,毋庸置疑,都是一部大爛片。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 40 | + 41 | + 42 | + 43 | + 44 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0043.html.en.html b/htdocs/imacat/me/diary/0043.html.en.html new file mode 120000 index 0000000..f1aaf37 --- /dev/null +++ b/htdocs/imacat/me/diary/0043.html.en.html @@ -0,0 +1 @@ +0043.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0043.html.en.xhtml b/htdocs/imacat/me/diary/0043.html.en.xhtml new file mode 100644 index 0000000..69f8221 --- /dev/null +++ b/htdocs/imacat/me/diary/0043.html.en.xhtml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 43 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 43

    + +
    + +
    + +
    +
    8.13.’06. 5:16am.
    + +

    Æon Flux 倩影刺客

    + +
    +Æon Flux 倩影刺客
    +

    Æon Flux 倩影刺客

    +
    + + + +

    我也是衝著 DVD 外盒上莎莉賽隆超酷的表情,加上又是女生打架的科幻動作片,才來看的。我覺得蠻好看的,比紫光任務好看得多了。網路上有些批評的聲音,主要是中文影評,不過我不大能體會。也許是我剛看過紫光任務,比下有餘吧;又或是台灣人愛看光怪陸離的電腦繪製武打,不喜歡看比較紮實的武打動作,或比較有深度的劇情架構。不過我覺得倩影刺客既有劇情,又有不錯的架構,特效合理,武打動作紮實。我實在想不出有什麼好批評的。

    + +

    IMDB 上的英文影評,對紫光任務的評論蠻正面的。我也認同。

    + +

    莎莉賽隆在倩影刺客武打動作,比蜜拉喬娃維琪在紫光任務中,紮實多了。雖然比不上李小龍、李連杰、楊紫瓊(怎麼可能?),可是也有達到水準以上。看來宣傳上說莎莉賽隆為倩影刺客苦練體能練了很久,並無虛言。至於影后莎莉賽隆的演技,當然更沒有話說。她的一舉一動,都具有強烈的說服力和感染力。主角伊恩芙拉斯的徒弟兼伙伴瑟珊卓,也讓人印象深刻。蘇菲歐克妮多紮實的動作,決絕與掙扎的表情,同樣非常搶眼。配角的戲份沒有主角多,角色也比較平面。若沒有搶眼的演出,是沒有辦法讓觀眾留下深刻的印象的。這點,蘇菲歐克妮多就發揮得淋漓盡至。男主角(其實是第一男配角吧,我覺得倩影刺客只有一個主角)馬頓裘克西,曾演過魔戒的精靈王凱勒鵬 Celeborn ,本身就有一股脫俗出塵的氣質,詮釋憂心人類未來,卻看不到了眼前危機的崔佛古德契,也相當不錯。

    + +

    聽說倩影刺客是從 MTV 音樂台熱門卡通改編而成的。不過沒有看影評的話,幾乎看不出來。我沒有看過卡通原著。不過電影的劇情相當合理,該鋪陳、交待的地方,都交待得非常清楚,劇情感覺上沒有瑕疵,即使沒看過卡通原著,也不會有不明白的地方。

    + +
    +卡通 Æon Flux
    +

    卡通 Æon Flux

    +
    + +

    複製人在科幻電影中,已經成了必備的元素了。這也沒什麼不好。就像網際網路在人類的生活中,已經成了像水電瓦斯的必需品了一樣。如何從複製人的基本元素上,創造新的世界,做更深刻的社會、哲學反省,才是科幻片可以著力之處。就這一點而言,倩影刺客的哲學反省:大自然自己找到出路的確是有點薄弱。感覺上像是嚮往神秘東方世界的西方人,隨便抓了一句道家的話來炫耀一樣,騙騙西方人也許可以,在像我們一樣受盡道家哲學燻陶的東方人來說,略嫌幼稚。

    + +

    整體而言,平均 5 分,我會給它打 5.6 分。雖然不是什麼驚世鉅片,也沒有非看不可的理由,但基本上還是蠻不錯看的電影。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 41 | + 42 | + 43 | + 44 | + 45 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0043.html.zh-cn.html b/htdocs/imacat/me/diary/0043.html.zh-cn.html new file mode 120000 index 0000000..570b505 --- /dev/null +++ b/htdocs/imacat/me/diary/0043.html.zh-cn.html @@ -0,0 +1 @@ +0043.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0043.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0043.html.zh-cn.xhtml new file mode 100644 index 0000000..fa00461 --- /dev/null +++ b/htdocs/imacat/me/diary/0043.html.zh-cn.xhtml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷四十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷四十三

    + +
    + +
    + +
    +
    8.13.’06. 5:16am.
    + +

    Æon Flux 倩影刺客

    + +
    +Æon Flux 倩影刺客
    +

    Æon Flux 倩影刺客

    +
    + + + +

    我也是冲著 DVD 外盒上莎莉赛隆超酷的表情,加上又是女生打架的科幻动作片,才来看的。我觉得蛮好看的,比紫光任务好看得多了。网路上有些批评的声音,主要是中文影评,不过我不大能体会。也许是我刚看过紫光任务,比下有余吧;又或是台湾人爱看光怪陆离的电脑绘制武打,不喜欢看比较扎实的武打动作,或比较有深度的剧情架构。不过我觉得倩影刺客既有剧情,又有不错的架构,特效合理,武打动作扎实。我实在想不出有什么好批评的。

    + +

    IMDB 上的英文影评,对紫光任务的评论蛮正面的。我也认同。

    + +

    莎莉赛隆在倩影刺客武打动作,比蜜拉乔娃维琪在紫光任务中,扎实多了。虽然比不上李小龙、李连杰、杨紫琼(怎么可能?),可是也有达到水准以上。看来宣传上说莎莉赛隆为倩影刺客苦练体能练了很久,并无虚言。至於影后莎莉赛隆的演技,当然更没有话说。她的一举一动,都具有强烈的说服力和感染力。主角伊恩芙拉斯的徒弟兼伙伴瑟珊卓,也让人印象深刻。苏菲欧克妮多扎实的动作,决绝与挣扎的表情,同样非常抢眼。配角的戏份没有主角多,角色也比较平面。若没有抢眼的演出,是没有办法让观众留下深刻的印象的。这点,苏菲欧克妮多就发挥得淋漓尽至。男主角(其实是第一男配角吧,我觉得倩影刺客只有一个主角)马顿裘克西,曾演过魔戒的精灵王凯勒鹏 Celeborn ,本身就有一股脱俗出尘的气质,诠释忧心人类未来,却看不到了眼前危机的崔佛古德契,也相当不错。

    + +

    听说倩影刺客是从 MTV 音乐台热门卡通改编而成的。不过没有看影评的话,几乎看不出来。我没有看过卡通原著。不过电影的剧情相当合理,该铺陈、交待的地方,都交待得非常清楚,剧情感觉上没有瑕疵,即使没看过卡通原著,也不会有不明白的地方。

    + +
    +卡通 Æon Flux
    +

    卡通 Æon Flux

    +
    + +

    复制人在科幻电影中,已经成了必备的元素了。这也没什么不好。就像网际网路在人类的生活中,已经成了像水电瓦斯的必需品了一样。如何从复制人的基本元素上,创造新的世界,做更深刻的社会、哲学反省,才是科幻片可以著力之处。就这一点而言,倩影刺客的哲学反省:大自然自己找到出路的确是有点薄弱。感觉上像是向往神秘东方世界的西方人,随便抓了一句道家的话来炫耀一样,骗骗西方人也许可以,在像我们一样受尽道家哲学熏陶的东方人来说,略嫌幼稚。

    + +

    整体而言,平均 5 分,我会给它打 5.6 分。虽然不是什么惊世巨片,也没有非看不可的理由,但基本上还是蛮不错看的电影。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 41 | + 42 | + 43 | + 44 | + 45 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0043.html.zh-tw.html b/htdocs/imacat/me/diary/0043.html.zh-tw.html new file mode 120000 index 0000000..abc49a2 --- /dev/null +++ b/htdocs/imacat/me/diary/0043.html.zh-tw.html @@ -0,0 +1 @@ +0043.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0043.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0043.html.zh-tw.xhtml new file mode 100644 index 0000000..37de30f --- /dev/null +++ b/htdocs/imacat/me/diary/0043.html.zh-tw.xhtml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷四十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷四十三

    + +
    + +
    + +
    +
    8.13.’06. 5:16am.
    + +

    Æon Flux 倩影刺客

    + +
    +Æon Flux 倩影刺客
    +

    Æon Flux 倩影刺客

    +
    + + + +

    我也是衝著 DVD 外盒上莎莉賽隆超酷的表情,加上又是女生打架的科幻動作片,才來看的。我覺得蠻好看的,比紫光任務好看得多了。網路上有些批評的聲音,主要是中文影評,不過我不大能體會。也許是我剛看過紫光任務,比下有餘吧;又或是台灣人愛看光怪陸離的電腦繪製武打,不喜歡看比較紮實的武打動作,或比較有深度的劇情架構。不過我覺得倩影刺客既有劇情,又有不錯的架構,特效合理,武打動作紮實。我實在想不出有什麼好批評的。

    + +

    IMDB 上的英文影評,對紫光任務的評論蠻正面的。我也認同。

    + +

    莎莉賽隆在倩影刺客武打動作,比蜜拉喬娃維琪在紫光任務中,紮實多了。雖然比不上李小龍、李連杰、楊紫瓊(怎麼可能?),可是也有達到水準以上。看來宣傳上說莎莉賽隆為倩影刺客苦練體能練了很久,並無虛言。至於影后莎莉賽隆的演技,當然更沒有話說。她的一舉一動,都具有強烈的說服力和感染力。主角伊恩芙拉斯的徒弟兼伙伴瑟珊卓,也讓人印象深刻。蘇菲歐克妮多紮實的動作,決絕與掙扎的表情,同樣非常搶眼。配角的戲份沒有主角多,角色也比較平面。若沒有搶眼的演出,是沒有辦法讓觀眾留下深刻的印象的。這點,蘇菲歐克妮多就發揮得淋漓盡至。男主角(其實是第一男配角吧,我覺得倩影刺客只有一個主角)馬頓裘克西,曾演過魔戒的精靈王凱勒鵬 Celeborn ,本身就有一股脫俗出塵的氣質,詮釋憂心人類未來,卻看不到了眼前危機的崔佛古德契,也相當不錯。

    + +

    聽說倩影刺客是從 MTV 音樂台熱門卡通改編而成的。不過沒有看影評的話,幾乎看不出來。我沒有看過卡通原著。不過電影的劇情相當合理,該鋪陳、交待的地方,都交待得非常清楚,劇情感覺上沒有瑕疵,即使沒看過卡通原著,也不會有不明白的地方。

    + +
    +卡通 Æon Flux
    +

    卡通 Æon Flux

    +
    + +

    複製人在科幻電影中,已經成了必備的元素了。這也沒什麼不好。就像網際網路在人類的生活中,已經成了像水電瓦斯的必需品了一樣。如何從複製人的基本元素上,創造新的世界,做更深刻的社會、哲學反省,才是科幻片可以著力之處。就這一點而言,倩影刺客的哲學反省:大自然自己找到出路的確是有點薄弱。感覺上像是嚮往神秘東方世界的西方人,隨便抓了一句道家的話來炫耀一樣,騙騙西方人也許可以,在像我們一樣受盡道家哲學燻陶的東方人來說,略嫌幼稚。

    + +

    整體而言,平均 5 分,我會給它打 5.6 分。雖然不是什麼驚世鉅片,也沒有非看不可的理由,但基本上還是蠻不錯看的電影。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 41 | + 42 | + 43 | + 44 | + 45 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0044.html.en.html b/htdocs/imacat/me/diary/0044.html.en.html new file mode 120000 index 0000000..7fc477c --- /dev/null +++ b/htdocs/imacat/me/diary/0044.html.en.html @@ -0,0 +1 @@ +0044.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0044.html.en.xhtml b/htdocs/imacat/me/diary/0044.html.en.xhtml new file mode 100644 index 0000000..a41ac3b --- /dev/null +++ b/htdocs/imacat/me/diary/0044.html.en.xhtml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 44 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 44

    + +
    + +
    + +
    +
    8.14.’06. 1:23am.
    + +

    NANA ナナ 卡通(二)

    + +

    一口氣看了十九集 NANA 卡通,快七個小時。哇~!真是~大~滿足~

    + +

    果然,卡通還是比較接近漫畫原味。比電影好看得多了。 *^_^*

    + +

    原來 OLIVIA 扮演 REIRA 唱的 a little pain ,是用在片尾曲,撘配土屋アンナ唱的片頭曲 rose 。而且 a little pain 還有用在第一次 TRAPNEST 演唱會上, REIRA 唱的曲子。

    + +

    嗯嗯,真是好看。太好看了~好期待台灣電視台什麼時候會買進來播呢~ *^_^*

    + +

    我知道網路上很多人比較喜歡ナナ。不過我喜歡奈々的程度,不下於ナナ小松奈々的確在很多地方,超級蠢的。可是,我們在某個時候,不都是這個樣子的人嗎?會完全否認自己這一面的,大概只有還不懂愛情滋味的小孩子吧。

    + +

    奈々會背離伸夫,投向 TAKUMI 的懷抱,很多人都無法諒解。我也是其中之一。可是仔細想想,也不是那麼難理解。雖然不是最好的選擇,甚至根本就是錯誤的決定,但是誰能真正在奈々最脆弱的關鍵時刻,給她溫柔的擁抱呢?想到這裏,甚至會覺得,每個人在愛情上的抉擇,往往不一定會做出最好、最正確的決定,或甚至會做出明知是錯誤的決定。我們只能做出在每一個當下最好的決定,即使明知道這是日後會讓我們後悔一輩子的決定。但事情往往就是那個樣子了。人生原本不是由完美的決定組成的,而是一連串愚蠢的決定、行動,逐漸成長的。這不就是我們最真實的樣子嗎?

    + +
    + +
    + +
    +
    8.13.’06. 5:03pm.
    + +

    NANA ナナ 卡通

    + +

    上次循土屋アンナ這條線追查下去,才發現土屋アンナ扮唱ナナ的原因,是因為 NANA 出動畫,找土屋アンナ唱主題曲。 NANA 出動畫了!耶!而且已經播了十九集了喔!

    + +

    我找到了土屋アンナ唱的主題曲 rose ,和 OLIVIA 唱的 a little pain土屋アンナ唱的 rose 真的很好聽,不輸中島美嘉唱的 GLAMOROUS SKY 。真的很難想像,土屋アンナ是模特兒出身,轉職演戲,再轉唱歌,沒有音樂背景的人,竟能唱出這麼棒的音樂!比較可惜的是,原著漫畫裏混血兒 REIRA 的聲音沉厚,音域寬廣,無人能敵,遠在ナナ之上,是ナナ的目標與假想敵,可是同樣是混血兒的 OLIVIA ,聲音就差一大截,太薄弱了。

    + +

    有些迫不及待的朋友,已經側錄日本電視,自己中譯、打字幕,放到網路上了。我當然也迫不及待趕快下載來搶先看囉~! ^_*' 看完再來寫評論吧~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 42 | + 43 | + 44 | + 45 | + 46 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0044.html.zh-cn.html b/htdocs/imacat/me/diary/0044.html.zh-cn.html new file mode 120000 index 0000000..ccd2931 --- /dev/null +++ b/htdocs/imacat/me/diary/0044.html.zh-cn.html @@ -0,0 +1 @@ +0044.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0044.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0044.html.zh-cn.xhtml new file mode 100644 index 0000000..d9ec286 --- /dev/null +++ b/htdocs/imacat/me/diary/0044.html.zh-cn.xhtml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷四十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷四十四

    + +
    + +
    + +
    +
    8.14.’06. 1:23am.
    + +

    NANA ナナ 卡通(二)

    + +

    一口气看了十九集 NANA 卡通,快七个小时。哇~!真是~大~满足~

    + +

    果然,卡通还是比较接近漫画原味。比电影好看得多了。 *^_^*

    + +

    原来 OLIVIA 扮演 REIRA 唱的 a little pain ,是用在片尾曲,撘配土屋アンナ唱的片头曲 rose 。而且 a little pain 还有用在第一次 TRAPNEST 演唱会上, REIRA 唱的曲子。

    + +

    嗯嗯,真是好看。太好看了~好期待台湾电视台什么时候会买进来播呢~ *^_^*

    + +

    我知道网路上很多人比较喜欢ナナ。不过我喜欢奈々的程度,不下於ナナ小松奈々的确在很多地方,超级蠢的。可是,我们在某个时候,不都是这个样子的人吗?会完全否认自己这一面的,大概只有还不懂爱情滋味的小孩子吧。

    + +

    奈々会背离伸夫,投向 TAKUMI 的怀抱,很多人都无法谅解。我也是其中之一。可是仔细想想,也不是那么难理解。虽然不是最好的选择,甚至根本就是错误的决定,但是谁能真正在奈々最脆弱的关键时刻,给她温柔的拥抱呢?想到这里,甚至会觉得,每个人在爱情上的抉择,往往不一定会做出最好、最正确的决定,或甚至会做出明知是错误的决定。我们只能做出在每一个当下最好的决定,即使明知道这是日后会让我们后悔一辈子的决定。但事情往往就是那个样子了。人生原本不是由完美的决定组成的,而是一连串愚蠢的决定、行动,逐渐成长的。这不就是我们最真实的样子吗?

    + +
    + +
    + +
    +
    8.13.’06. 5:03pm.
    + +

    NANA ナナ 卡通

    + +

    上次循土屋アンナ这条线追查下去,才发现土屋アンナ扮唱ナナ的原因,是因为 NANA 出动画,找土屋アンナ唱主题曲。 NANA 出动画了!耶!而且已经播了十九集了喔!

    + +

    我找到了土屋アンナ唱的主题曲 rose ,和 OLIVIA 唱的 a little pain土屋アンナ唱的 rose 真的很好听,不输中岛美嘉唱的 GLAMOROUS SKY 。真的很难想像,土屋アンナ是模特儿出身,转职演戏,再转唱歌,没有音乐背景的人,竟能唱出这么棒的音乐!比较可惜的是,原著漫画里混血儿 REIRA 的声音沉厚,音域宽广,无人能敌,远在ナナ之上,是ナナ的目标与假想敌,可是同样是混血儿的 OLIVIA ,声音就差一大截,太薄弱了。

    + +

    有些迫不及待的朋友,已经侧录日本电视,自己中译、打字幕,放到网路上了。我当然也迫不及待赶快下载来抢先看罗~! ^_*' 看完再来写评论吧~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 42 | + 43 | + 44 | + 45 | + 46 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0044.html.zh-tw.html b/htdocs/imacat/me/diary/0044.html.zh-tw.html new file mode 120000 index 0000000..6c16398 --- /dev/null +++ b/htdocs/imacat/me/diary/0044.html.zh-tw.html @@ -0,0 +1 @@ +0044.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0044.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0044.html.zh-tw.xhtml new file mode 100644 index 0000000..d544e50 --- /dev/null +++ b/htdocs/imacat/me/diary/0044.html.zh-tw.xhtml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷四十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷四十四

    + +
    + +
    + +
    +
    8.14.’06. 1:23am.
    + +

    NANA ナナ 卡通(二)

    + +

    一口氣看了十九集 NANA 卡通,快七個小時。哇~!真是~大~滿足~

    + +

    果然,卡通還是比較接近漫畫原味。比電影好看得多了。 *^_^*

    + +

    原來 OLIVIA 扮演 REIRA 唱的 a little pain ,是用在片尾曲,撘配土屋アンナ唱的片頭曲 rose 。而且 a little pain 還有用在第一次 TRAPNEST 演唱會上, REIRA 唱的曲子。

    + +

    嗯嗯,真是好看。太好看了~好期待台灣電視台什麼時候會買進來播呢~ *^_^*

    + +

    我知道網路上很多人比較喜歡ナナ。不過我喜歡奈々的程度,不下於ナナ小松奈々的確在很多地方,超級蠢的。可是,我們在某個時候,不都是這個樣子的人嗎?會完全否認自己這一面的,大概只有還不懂愛情滋味的小孩子吧。

    + +

    奈々會背離伸夫,投向 TAKUMI 的懷抱,很多人都無法諒解。我也是其中之一。可是仔細想想,也不是那麼難理解。雖然不是最好的選擇,甚至根本就是錯誤的決定,但是誰能真正在奈々最脆弱的關鍵時刻,給她溫柔的擁抱呢?想到這裏,甚至會覺得,每個人在愛情上的抉擇,往往不一定會做出最好、最正確的決定,或甚至會做出明知是錯誤的決定。我們只能做出在每一個當下最好的決定,即使明知道這是日後會讓我們後悔一輩子的決定。但事情往往就是那個樣子了。人生原本不是由完美的決定組成的,而是一連串愚蠢的決定、行動,逐漸成長的。這不就是我們最真實的樣子嗎?

    + +
    + +
    + +
    +
    8.13.’06. 5:03pm.
    + +

    NANA ナナ 卡通

    + +

    上次循土屋アンナ這條線追查下去,才發現土屋アンナ扮唱ナナ的原因,是因為 NANA 出動畫,找土屋アンナ唱主題曲。 NANA 出動畫了!耶!而且已經播了十九集了喔!

    + +

    我找到了土屋アンナ唱的主題曲 rose ,和 OLIVIA 唱的 a little pain土屋アンナ唱的 rose 真的很好聽,不輸中島美嘉唱的 GLAMOROUS SKY 。真的很難想像,土屋アンナ是模特兒出身,轉職演戲,再轉唱歌,沒有音樂背景的人,竟能唱出這麼棒的音樂!比較可惜的是,原著漫畫裏混血兒 REIRA 的聲音沉厚,音域寬廣,無人能敵,遠在ナナ之上,是ナナ的目標與假想敵,可是同樣是混血兒的 OLIVIA ,聲音就差一大截,太薄弱了。

    + +

    有些迫不及待的朋友,已經側錄日本電視,自己中譯、打字幕,放到網路上了。我當然也迫不及待趕快下載來搶先看囉~! ^_*' 看完再來寫評論吧~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 42 | + 43 | + 44 | + 45 | + 46 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0045.html.en.html b/htdocs/imacat/me/diary/0045.html.en.html new file mode 120000 index 0000000..98a6d0b --- /dev/null +++ b/htdocs/imacat/me/diary/0045.html.en.html @@ -0,0 +1 @@ +0045.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0045.html.en.xhtml b/htdocs/imacat/me/diary/0045.html.en.xhtml new file mode 100644 index 0000000..528feed --- /dev/null +++ b/htdocs/imacat/me/diary/0045.html.en.xhtml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 45 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 45

    + +
    + +
    + +
    +
    8.17.’06. 11:47am.
    + +

    NANA ナナ 2 的最新消息

    + +

    台灣大紀元的最新消息。如有版權問題,請隨時告知。原文出處:娜娜續集將開拍 宮崎葵辭演 中島美嘉留任

    + +

    嗯, NANA 2 終於有下文了!除了兩個人外,包括中島美嘉在內的全部班底都留任喔~ ^_*' 雖然不知道市川由一和姜暢雄是誰(不好意思… ^^; ),不過還是希望能夠拍出很好看的電影呢~ *^_^*

    + +
    +

    娜娜續集將開拍 宮崎葵辭演 中島美嘉留任

    + +
    2006-08-09
    + +

    東方網 8 月 9 日消息:去年在日本獲得超高票房並掀起流行風潮的漫畫改編電影娜娜 (Nana) 近日確認開拍續集。 8 月 3 日,東寶公司公佈了演員名單,此前被炒得沸沸揚揚的傳言被證實了一半,即上集中小松奈奈的扮演者宮崎葵辭演,接替她的確實是市川由衣,不過,中島美嘉並未如傳聞中所說因不滿新搭檔而同時辭演,她將繼續扮演人氣極高的女歌手娜娜。

    + +

    娜娜拍續集的計劃從去年就開始籌備,雖然製作方有意保留獲得認可的原班人馬,但幾位主演都是眼下日本炙手可熱的新生代,日程安排相當難以協調,尤其是宮崎葵無意繼續接演,於是角色分配問題一度困擾電影公司,被迫延期開拍。

    + +

    影片導演大谷健太郎最終提攜了主演自己新作障礙區域的市川由衣來演出這部極受關注的續集,同時扮演娜娜戀人的松田龍平也被新人姜暢雄接替。現年 20 歲的市川由衣在電影領域沒有宮崎葵豐富的表演經歷,只不過有日本較大的經紀公司研音力撐,今年先後參演了日劇輪舞曲欺詐獵人

    + +

    據悉,影片將前往倫敦拍攝外景,提高製作規模,暫定以娜娜樂隊的出道和小松奈奈懷孕為主線,預計於 12 月 9 日公映。

    +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 43 | + 44 | + 45 | + 46 | + 47 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0045.html.zh-cn.html b/htdocs/imacat/me/diary/0045.html.zh-cn.html new file mode 120000 index 0000000..c87d120 --- /dev/null +++ b/htdocs/imacat/me/diary/0045.html.zh-cn.html @@ -0,0 +1 @@ +0045.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0045.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0045.html.zh-cn.xhtml new file mode 100644 index 0000000..0717826 --- /dev/null +++ b/htdocs/imacat/me/diary/0045.html.zh-cn.xhtml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷四十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷四十五

    + +
    + +
    + +
    +
    8.17.’06. 11:47am.
    + +

    NANA ナナ 2 的最新消息

    + +

    台湾大纪元的最新消息。如有版权问题,请随时告知。原文出处:娜娜续集将开拍 宫崎葵辞演 中岛美嘉留任

    + +

    嗯, NANA 2 终於有下文了!除了两个人外,包括中岛美嘉在内的全部班底都留任喔~ ^_*' 虽然不知道市川由一和姜畅雄是谁(不好意思… ^^; ),不过还是希望能够拍出很好看的电影呢~ *^_^*

    + +
    +

    娜娜续集将开拍 宫崎葵辞演 中岛美嘉留任

    + +
    2006-08-09
    + +

    东方网 8 月 9 日消息:去年在日本获得超高票房并掀起流行风潮的漫画改编电影娜娜 (Nana) 近日确认开拍续集。 8 月 3 日,东宝公司公布了演员名单,此前被炒得沸沸扬扬的传言被证实了一半,即上集中小松奈奈的扮演者宫崎葵辞演,接替她的确实是市川由衣,不过,中岛美嘉并未如传闻中所说因不满新搭档而同时辞演,她将继续扮演人气极高的女歌手娜娜。

    + +

    娜娜拍续集的计划从去年就开始筹备,虽然制作方有意保留获得认可的原班人马,但几位主演都是眼下日本炙手可热的新生代,日程安排相当难以协调,尤其是宫崎葵无意继续接演,於是角色分配问题一度困扰电影公司,被迫延期开拍。

    + +

    影片导演大谷健太郎最终提携了主演自己新作障碍区域的市川由衣来演出这部极受关注的续集,同时扮演娜娜恋人的松田龙平也被新人姜畅雄接替。现年 20 岁的市川由衣在电影领域没有宫崎葵丰富的表演经历,只不过有日本较大的经纪公司研音力撑,今年先后参演了日剧轮舞曲欺诈猎人

    + +

    据悉,影片将前往伦敦拍摄外景,提高制作规模,暂定以娜娜乐队的出道和小松奈奈怀孕为主线,预计於 12 月 9 日公映。

    +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 43 | + 44 | + 45 | + 46 | + 47 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0045.html.zh-tw.html b/htdocs/imacat/me/diary/0045.html.zh-tw.html new file mode 120000 index 0000000..29b63e0 --- /dev/null +++ b/htdocs/imacat/me/diary/0045.html.zh-tw.html @@ -0,0 +1 @@ +0045.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0045.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0045.html.zh-tw.xhtml new file mode 100644 index 0000000..36b8d36 --- /dev/null +++ b/htdocs/imacat/me/diary/0045.html.zh-tw.xhtml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷四十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷四十五

    + +
    + +
    + +
    +
    8.17.’06. 11:47am.
    + +

    NANA ナナ 2 的最新消息

    + +

    台灣大紀元的最新消息。如有版權問題,請隨時告知。原文出處:娜娜續集將開拍 宮崎葵辭演 中島美嘉留任

    + +

    嗯, NANA 2 終於有下文了!除了兩個人外,包括中島美嘉在內的全部班底都留任喔~ ^_*' 雖然不知道市川由一和姜暢雄是誰(不好意思… ^^; ),不過還是希望能夠拍出很好看的電影呢~ *^_^*

    + +
    +

    娜娜續集將開拍 宮崎葵辭演 中島美嘉留任

    + +
    2006-08-09
    + +

    東方網 8 月 9 日消息:去年在日本獲得超高票房並掀起流行風潮的漫畫改編電影娜娜 (Nana) 近日確認開拍續集。 8 月 3 日,東寶公司公佈了演員名單,此前被炒得沸沸揚揚的傳言被證實了一半,即上集中小松奈奈的扮演者宮崎葵辭演,接替她的確實是市川由衣,不過,中島美嘉並未如傳聞中所說因不滿新搭檔而同時辭演,她將繼續扮演人氣極高的女歌手娜娜。

    + +

    娜娜拍續集的計劃從去年就開始籌備,雖然製作方有意保留獲得認可的原班人馬,但幾位主演都是眼下日本炙手可熱的新生代,日程安排相當難以協調,尤其是宮崎葵無意繼續接演,於是角色分配問題一度困擾電影公司,被迫延期開拍。

    + +

    影片導演大谷健太郎最終提攜了主演自己新作障礙區域的市川由衣來演出這部極受關注的續集,同時扮演娜娜戀人的松田龍平也被新人姜暢雄接替。現年 20 歲的市川由衣在電影領域沒有宮崎葵豐富的表演經歷,只不過有日本較大的經紀公司研音力撐,今年先後參演了日劇輪舞曲欺詐獵人

    + +

    據悉,影片將前往倫敦拍攝外景,提高製作規模,暫定以娜娜樂隊的出道和小松奈奈懷孕為主線,預計於 12 月 9 日公映。

    +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 43 | + 44 | + 45 | + 46 | + 47 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0046.html.en.html b/htdocs/imacat/me/diary/0046.html.en.html new file mode 120000 index 0000000..d1d0a22 --- /dev/null +++ b/htdocs/imacat/me/diary/0046.html.en.html @@ -0,0 +1 @@ +0046.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0046.html.en.xhtml b/htdocs/imacat/me/diary/0046.html.en.xhtml new file mode 100644 index 0000000..2cdfe8e --- /dev/null +++ b/htdocs/imacat/me/diary/0046.html.en.xhtml @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 46 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 46

    + +
    + +
    + +
    +
    8.17.’06. 12:27pm.
    + +

    下弦の月~ラスト・クォーター(下弦之月 Last Quarterご近所物語(芳鄰同盟會)

    + +

    唔,我已經變成矢沢あい(矢澤愛)的信徒了。 ^^;

    + +

    沒想到下弦の月也拍成了電影了,真是太厲害了~我也要快點找來看~前年上映的電影,不知道現在還找不找得到。在電影 NANA 中演 BLAST 吉他手寺島伸夫成宮寛貴,原來之前就在電影下弦の月演過女主角望月美月的男朋友安西知己了。成宮寛貴看來很有可能成為矢沢教的御用演員喔~ *^_^*

    + +

    下弦の月是一個調性非常冷酷的故事,一看就是短篇的結構。看完了覺得好棒,可是調性這麼冷的故事,大概很難商業化吧。沒想到我錯了,呵呵~ *^_^*

    + +

    ご近所物語好可愛~好像拍成卡通了說。不知道現在還找不找得到~而且還有專屬網站呢~和 NANA 一樣是有很多角色的故事。不過因為是在 RIBBON 上連載, RIBBON 設定的讀者群是小學生,所以故事比較單純,色彩非常豐富,而且男女主角一定會在一起,遵守少女漫畫的基本公式。 NANA下弦の月就不遵守這個公式了。矢沢あいNANA 7.8 中自己說,成人的愛情不是這個樣子,給高中生看的漫畫,她希望能夠表達一種比較成熟的愛情觀。

    + +

    我覺得矢沢あい的漫畫很棒的地方在於:佛斯特 (E. M. Forster) 在他的小說理論小說面面觀 Aspects of the Novel中,將,將小說人物分為圓形人物扁平形人物兩種類型。一般而言,故事的主角有圓形人物也有扁平形人物,但除了主角以外,大多都是扁平形人物:個性清楚直接,從頭到尾都不會有心境的轉折變化。扁平形的配角,成為陪襯主角成長、思考,固定不變的外在環境。然而矢沢あい的漫畫中,很少有扁平形人物的角色。即使是配角,也有他們的心境轉折、成長、痛苦。這使得矢沢あい的漫畫人物關係變得非常複雜,每個人都有可能暗戀每一個人,也有可能隨時跟另一個人產生意外的關係,發展出意外的戀情。

    + +

    就如 NANA 中,奈々懷孕後,伸夫痛苦得不知道該怎麼辦,這時候身邊出現了對他非常積極的 AV 女優香坂百合,和性格冷靜的二線女演員美雨,兩個人都對伸夫有好感。在一陣誘惑後,伸夫終於跟百合搞上了。感覺上很像扁平形人物的百合,在和伸夫發生關係後,積極地到處宣告自己是伸夫的女朋友,也對伸夫還忘不了的奈々產生了敵對意識。後來百合崩潰了,對伸夫哭著說:你大概認為我是很不要臉的女人吧~伸夫回答:沒有這回事。是妳救了我。百合瞬間感動得哭了出來,跟伸夫抱在一起。我原本比較喜歡美雨的。但看到這一幕,我也感動得好想哭。表面上非常積極的百合,也有她強裝出來的堅強剝裂,渴望被溫柔對待的一面。

    + +

    有個日本的 Wiki 網站矢沢あい少女漫画界の女王。唔,真的嗎?女王耶,好厲害。我也開始相信了~沒辦法,誰教我也成了矢沢教的信徒了呢~呵呵呵~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 44 | + 45 | + 46 | + 47 | + 48 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0046.html.zh-cn.html b/htdocs/imacat/me/diary/0046.html.zh-cn.html new file mode 120000 index 0000000..9402e66 --- /dev/null +++ b/htdocs/imacat/me/diary/0046.html.zh-cn.html @@ -0,0 +1 @@ +0046.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0046.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0046.html.zh-cn.xhtml new file mode 100644 index 0000000..aacbc13 --- /dev/null +++ b/htdocs/imacat/me/diary/0046.html.zh-cn.xhtml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷四十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷四十六

    + +
    + +
    + +
    +
    8.17.’06. 12:27pm.
    + +

    下弦の月~ラスト・クォーター(下弦之月 Last Quarterご近所物语(芳邻同盟会)

    + +

    唔,我已经变成矢沢あい(矢泽爱)的信徒了。 ^^;

    + +

    没想到下弦の月也拍成了电影了,真是太厉害了~我也要快点找来看~前年上映的电影,不知道现在还找不找得到。在电影 NANA 中演 BLAST 吉他手寺岛伸夫成宫寛贵,原来之前就在电影下弦の月演过女主角望月美月的男朋友安西知己了。成宫寛贵看来很有可能成为矢沢教的御用演员喔~ *^_^*

    + +

    下弦の月是一个调性非常冷酷的故事,一看就是短篇的结构。看完了觉得好棒,可是调性这么冷的故事,大概很难商业化吧。没想到我错了,呵呵~ *^_^*

    + +

    ご近所物语好可爱~好像拍成卡通了说。不知道现在还找不找得到~而且还有专属网站呢~和 NANA 一样是有很多角色的故事。不过因为是在 RIBBON 上连载, RIBBON 设定的读者群是小学生,所以故事比较单纯,色彩非常丰富,而且男女主角一定会在一起,遵守少女漫画的基本公式。 NANA下弦の月就不遵守这个公式了。矢沢あいNANA 7.8 中自己说,成人的爱情不是这个样子,给高中生看的漫画,她希望能够表达一种比较成熟的爱情观。

    + +

    我觉得矢沢あい的漫画很棒的地方在於:佛斯特 (E. M. Forster) 在他的小说理论小说面面观 Aspects of the Novel中,将,将小说人物分为圆形人物扁平形人物两种类型。一般而言,故事的主角有圆形人物也有扁平形人物,但除了主角以外,大多都是扁平形人物:个性清楚直接,从头到尾都不会有心境的转折变化。扁平形的配角,成为陪衬主角成长、思考,固定不变的外在环境。然而矢沢あい的漫画中,很少有扁平形人物的角色。即使是配角,也有他们的心境转折、成长、痛苦。这使得矢沢あい的漫画人物关系变得非常复杂,每个人都有可能暗恋每一个人,也有可能随时跟另一个人产生意外的关系,发展出意外的恋情。

    + +

    就如 NANA 中,奈々怀孕后,伸夫痛苦得不知道该怎么办,这时候身边出现了对他非常积极的 AV 女优香坂百合,和性格冷静的二线女演员美雨,两个人都对伸夫有好感。在一阵诱惑后,伸夫终於跟百合搞上了。感觉上很像扁平形人物的百合,在和伸夫发生关系后,积极地到处宣告自己是伸夫的女朋友,也对伸夫还忘不了的奈々产生了敌对意识。后来百合崩溃了,对伸夫哭著说:你大概认为我是很不要脸的女人吧~伸夫回答:没有这回事。是你救了我。百合瞬间感动得哭了出来,跟伸夫抱在一起。我原本比较喜欢美雨的。但看到这一幕,我也感动得好想哭。表面上非常积极的百合,也有她强装出来的坚强剥裂,渴望被温柔对待的一面。

    + +

    有个日本的 Wiki 网站矢沢あい少女漫画界の女王。唔,真的吗?女王耶,好厉害。我也开始相信了~没办法,谁教我也成了矢沢教的信徒了呢~呵呵呵~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 44 | + 45 | + 46 | + 47 | + 48 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0046.html.zh-tw.html b/htdocs/imacat/me/diary/0046.html.zh-tw.html new file mode 120000 index 0000000..36d1b5d --- /dev/null +++ b/htdocs/imacat/me/diary/0046.html.zh-tw.html @@ -0,0 +1 @@ +0046.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0046.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0046.html.zh-tw.xhtml new file mode 100644 index 0000000..3210272 --- /dev/null +++ b/htdocs/imacat/me/diary/0046.html.zh-tw.xhtml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷四十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷四十六

    + +
    + +
    + +
    +
    8.17.’06. 12:27pm.
    + +

    下弦の月~ラスト・クォーター(下弦之月 Last Quarterご近所物語(芳鄰同盟會)

    + +

    唔,我已經變成矢沢あい(矢澤愛)的信徒了。 ^^;

    + +

    沒想到下弦の月也拍成了電影了,真是太厲害了~我也要快點找來看~前年上映的電影,不知道現在還找不找得到。在電影 NANA 中演 BLAST 吉他手寺島伸夫成宮寛貴,原來之前就在電影下弦の月演過女主角望月美月的男朋友安西知己了。成宮寛貴看來很有可能成為矢沢教的御用演員喔~ *^_^*

    + +

    下弦の月是一個調性非常冷酷的故事,一看就是短篇的結構。看完了覺得好棒,可是調性這麼冷的故事,大概很難商業化吧。沒想到我錯了,呵呵~ *^_^*

    + +

    ご近所物語好可愛~好像拍成卡通了說。不知道現在還找不找得到~而且還有專屬網站呢~和 NANA 一樣是有很多角色的故事。不過因為是在 RIBBON 上連載, RIBBON 設定的讀者群是小學生,所以故事比較單純,色彩非常豐富,而且男女主角一定會在一起,遵守少女漫畫的基本公式。 NANA下弦の月就不遵守這個公式了。矢沢あいNANA 7.8 中自己說,成人的愛情不是這個樣子,給高中生看的漫畫,她希望能夠表達一種比較成熟的愛情觀。

    + +

    我覺得矢沢あい的漫畫很棒的地方在於:佛斯特 (E. M. Forster) 在他的小說理論小說面面觀 Aspects of the Novel中,將,將小說人物分為圓形人物扁平形人物兩種類型。一般而言,故事的主角有圓形人物也有扁平形人物,但除了主角以外,大多都是扁平形人物:個性清楚直接,從頭到尾都不會有心境的轉折變化。扁平形的配角,成為陪襯主角成長、思考,固定不變的外在環境。然而矢沢あい的漫畫中,很少有扁平形人物的角色。即使是配角,也有他們的心境轉折、成長、痛苦。這使得矢沢あい的漫畫人物關係變得非常複雜,每個人都有可能暗戀每一個人,也有可能隨時跟另一個人產生意外的關係,發展出意外的戀情。

    + +

    就如 NANA 中,奈々懷孕後,伸夫痛苦得不知道該怎麼辦,這時候身邊出現了對他非常積極的 AV 女優香坂百合,和性格冷靜的二線女演員美雨,兩個人都對伸夫有好感。在一陣誘惑後,伸夫終於跟百合搞上了。感覺上很像扁平形人物的百合,在和伸夫發生關係後,積極地到處宣告自己是伸夫的女朋友,也對伸夫還忘不了的奈々產生了敵對意識。後來百合崩潰了,對伸夫哭著說:你大概認為我是很不要臉的女人吧~伸夫回答:沒有這回事。是妳救了我。百合瞬間感動得哭了出來,跟伸夫抱在一起。我原本比較喜歡美雨的。但看到這一幕,我也感動得好想哭。表面上非常積極的百合,也有她強裝出來的堅強剝裂,渴望被溫柔對待的一面。

    + +

    有個日本的 Wiki 網站矢沢あい少女漫画界の女王。唔,真的嗎?女王耶,好厲害。我也開始相信了~沒辦法,誰教我也成了矢沢教的信徒了呢~呵呵呵~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 44 | + 45 | + 46 | + 47 | + 48 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0047.html.en.html b/htdocs/imacat/me/diary/0047.html.en.html new file mode 120000 index 0000000..c976ccc --- /dev/null +++ b/htdocs/imacat/me/diary/0047.html.en.html @@ -0,0 +1 @@ +0047.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0047.html.en.xhtml b/htdocs/imacat/me/diary/0047.html.en.xhtml new file mode 100644 index 0000000..c025dd2 --- /dev/null +++ b/htdocs/imacat/me/diary/0047.html.en.xhtml @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 47 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 47

    + +
    + +
    + +
    +
    8.18.’06. 8:13pm.
    + +

    心機

    + +

    我發現,我其實也是個心機很重的人。

    + +

    在漫畫 NANA 第四集第九話,一群人在章司打工的餐廳外等打烊。ナナ要回家等或回餐聽裏等,不了解為什麼要在外面大馬路上等。奈々說:讓他以為走了,等他出來發現我一直在外面等他,不是會讓他很感動嗎?ナナ氣得說:我最討厭像妳這種會耍心機的女人了!沉默了一會,奈々才坦承說,因為章司剛剛說有話要說的表情很奇怪,心裏放心不下,就算回家也無法安心等。

    + +

    赫然發現,我也是這樣的人。

    + +

    我心底老是在算計很多事:這樣說好不好?那樣說好不好?這樣說別人有什麼反應?怎樣講周圍的人才不會不高興?才會對我有好感?怕被別人拒絕,老是拿很多無關緊要的藉口,來掩飾自己真正的動機。想想,我其實也是個不坦白,而且有點讓人火大的傢伙呢~

    + +
    + +
    + +
    +
    8.18.’06. 8:58am.
    + +

    ご近所物語(芳鄰同盟會)的結局好棒~好感動~

    + +
    + +
    + +
    +
    8.18.’06. 8:46am.
    + +

    RAP 與噪音

    + +

    星期一晚上,趕空大生活科學概論作業時,在課本讀到這一段:

    + +
    +

    …例如十來歲的青少年子女認為最美的音樂是 RAP ,但父母可能無法認同而認為是噪音…

    + +
    杜正榮等(民 91 ),生活科學概論,國立空中大學,第 181 頁。
    +
    + +

    RAP 是噪音?不好意思,我完全無法認同這句話。

    + +

    噪音 Noise是一種反音樂,是一種音樂的基進對抗形式,對於固定音樂形式的反抗,在地下樂團的現場演唱會上,偶爾會遇上噪音樂團。噪音樂團會用特殊的方式來製造聲音,從用簡單的金屬、木塊作不規則的撞擊、刮擦,到自己製作數位噪音發聲器。我曾經在地下樂團的現場觀看過,雖然不能說覺得感動,但也覺得噪音企圖去衝撞既有的固定音樂形式,蠻了不起的。

    + +

    RAP 是噪音?對不起, RAP 不夠格稱為噪音。 RAP 是非常商業化的,根本沒資格進入反音樂的陣線。但 RAP 也沒資格稱為音樂。音樂有旋律,有節奏,但 RAP 只有節奏,沒有旋律。 RAP 充其量只是有節奏的講話聲音。講話算哪門子音樂?

    + +

    RAP 不是噪音,它不夠格稱為噪音;不是音樂,不夠格稱為音樂;不是反音樂,不夠格稱為反音樂;不是垃圾,不夠格稱為垃圾;不是什麼都不是,不夠格稱為什麼都不是RAP 充其量就是講話。講話跟音樂是兩碼子事。像這種明明不是音樂又自居為音樂,不知所謂的東西,竟然成為這個時代的主流,街上每家店都在放,連把耳朵摀起來都聽得到,真讓人噁心得想吐。

    + +
    + +
    + +
    +
    8.18.’06. 8:01am.
    + +

    矢沢永吉

    + +
    +矢沢永吉
    +

    矢沢永吉

    +
    + +

    剛剛上網查,發現矢沢あい(矢澤愛)筆名的由來,是因為她很喜歡歌星矢沢永吉(矢澤永吉),所以給自己取筆名為矢沢あいあい漢字作,就是喜愛的意思。矢沢あい就是喜愛矢沢永吉的意思。

    + +
    + +
    + +
    +
    8.17.’06. 11:02pm.
    + +

    矢沢あい(矢澤愛)作品

    + +
      +
    1. 天使なんかじゃない(聖學園天使)
    2. + +
    3. ご近所物語(芳鄰同盟會)
    4. + +
    5. 下弦の月 ラスト・クォーター(下弦之月 Last Quarter
    6. + +
    7. Paradise Kiss (天國之吻)
    8. + +
    9. NANA ナナ(娜娜)
    10. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 45 | + 46 | + 47 | + 48 | + 49 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0047.html.zh-cn.html b/htdocs/imacat/me/diary/0047.html.zh-cn.html new file mode 120000 index 0000000..d03c0b3 --- /dev/null +++ b/htdocs/imacat/me/diary/0047.html.zh-cn.html @@ -0,0 +1 @@ +0047.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0047.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0047.html.zh-cn.xhtml new file mode 100644 index 0000000..5acc4ef --- /dev/null +++ b/htdocs/imacat/me/diary/0047.html.zh-cn.xhtml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷四十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷四十七

    + +
    + +
    + +
    +
    8.18.’06. 8:13pm.
    + +

    心机

    + +

    我发现,我其实也是个心机很重的人。

    + +

    在漫画 NANA 第四集第九话,一群人在章司打工的餐厅外等打烊。ナナ要回家等或回餐听里等,不了解为什么要在外面大马路上等。奈々说:让他以为走了,等他出来发现我一直在外面等他,不是会让他很感动吗?ナナ气得说:我最讨厌像你这种会耍心机的女人了!沉默了一会,奈々才坦承说,因为章司刚刚说有话要说的表情很奇怪,心里放心不下,就算回家也无法安心等。

    + +

    赫然发现,我也是这样的人。

    + +

    我心底老是在算计很多事:这样说好不好?那样说好不好?这样说别人有什么反应?怎样讲周围的人才不会不高兴?才会对我有好感?怕被别人拒绝,老是拿很多无关紧要的藉口,来掩饰自己真正的动机。想想,我其实也是个不坦白,而且有点让人火大的家伙呢~

    + +
    + +
    + +
    +
    8.18.’06. 8:58am.
    + +

    ご近所物语(芳邻同盟会)的结局好棒~好感动~

    + +
    + +
    + +
    +
    8.18.’06. 8:46am.
    + +

    RAP 与噪音

    + +

    星期一晚上,赶空大生活科学概论作业时,在课本读到这一段:

    + +
    +

    …例如十来岁的青少年子女认为最美的音乐是 RAP ,但父母可能无法认同而认为是噪音…

    + +
    杜正荣等(民 91 ),生活科学概论,国立空中大学,第 181 页。
    +
    + +

    RAP 是噪音?不好意思,我完全无法认同这句话。

    + +

    噪音 Noise是一种反音乐,是一种音乐的基进对抗形式,对於固定音乐形式的反抗,在地下乐团的现场演唱会上,偶尔会遇上噪音乐团。噪音乐团会用特殊的方式来制造声音,从用简单的金属、木块作不规则的撞击、刮擦,到自己制作数位噪音发声器。我曾经在地下乐团的现场观看过,虽然不能说觉得感动,但也觉得噪音企图去冲撞既有的固定音乐形式,蛮了不起的。

    + +

    RAP 是噪音?对不起, RAP 不够格称为噪音。 RAP 是非常商业化的,根本没资格进入反音乐的阵线。但 RAP 也没资格称为音乐。音乐有旋律,有节奏,但 RAP 只有节奏,没有旋律。 RAP 充其量只是有节奏的讲话声音。讲话算哪门子音乐?

    + +

    RAP 不是噪音,它不够格称为噪音;不是音乐,不够格称为音乐;不是反音乐,不够格称为反音乐;不是垃圾,不够格称为垃圾;不是什么都不是,不够格称为什么都不是RAP 充其量就是讲话。讲话跟音乐是两码子事。像这种明明不是音乐又自居为音乐,不知所谓的东西,竟然成为这个时代的主流,街上每家店都在放,连把耳朵捂起来都听得到,真让人恶心得想吐。

    + +
    + +
    + +
    +
    8.18.’06. 8:01am.
    + +

    矢沢永吉

    + +
    +矢沢永吉
    +

    矢沢永吉

    +
    + +

    刚刚上网查,发现矢沢あい(矢泽爱)笔名的由来,是因为她很喜欢歌星矢沢永吉(矢泽永吉),所以给自己取笔名为矢沢あいあい汉字作,就是喜爱的意思。矢沢あい就是喜爱矢沢永吉的意思。

    + +
    + +
    + +
    +
    8.17.’06. 11:02pm.
    + +

    矢沢あい(矢泽爱)作品

    + +
      +
    1. 天使なんかじゃない(圣学园天使)
    2. + +
    3. ご近所物语(芳邻同盟会)
    4. + +
    5. 下弦の月 ラスト・クォーター(下弦之月 Last Quarter
    6. + +
    7. Paradise Kiss (天国之吻)
    8. + +
    9. NANA ナナ(娜娜)
    10. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 45 | + 46 | + 47 | + 48 | + 49 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0047.html.zh-tw.html b/htdocs/imacat/me/diary/0047.html.zh-tw.html new file mode 120000 index 0000000..5a0e4f1 --- /dev/null +++ b/htdocs/imacat/me/diary/0047.html.zh-tw.html @@ -0,0 +1 @@ +0047.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0047.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0047.html.zh-tw.xhtml new file mode 100644 index 0000000..c025d89 --- /dev/null +++ b/htdocs/imacat/me/diary/0047.html.zh-tw.xhtml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷四十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷四十七

    + +
    + +
    + +
    +
    8.18.’06. 8:13pm.
    + +

    心機

    + +

    我發現,我其實也是個心機很重的人。

    + +

    在漫畫 NANA 第四集第九話,一群人在章司打工的餐廳外等打烊。ナナ要回家等或回餐聽裏等,不了解為什麼要在外面大馬路上等。奈々說:讓他以為走了,等他出來發現我一直在外面等他,不是會讓他很感動嗎?ナナ氣得說:我最討厭像妳這種會耍心機的女人了!沉默了一會,奈々才坦承說,因為章司剛剛說有話要說的表情很奇怪,心裏放心不下,就算回家也無法安心等。

    + +

    赫然發現,我也是這樣的人。

    + +

    我心底老是在算計很多事:這樣說好不好?那樣說好不好?這樣說別人有什麼反應?怎樣講周圍的人才不會不高興?才會對我有好感?怕被別人拒絕,老是拿很多無關緊要的藉口,來掩飾自己真正的動機。想想,我其實也是個不坦白,而且有點讓人火大的傢伙呢~

    + +
    + +
    + +
    +
    8.18.’06. 8:58am.
    + +

    ご近所物語(芳鄰同盟會)的結局好棒~好感動~

    + +
    + +
    + +
    +
    8.18.’06. 8:46am.
    + +

    RAP 與噪音

    + +

    星期一晚上,趕空大生活科學概論作業時,在課本讀到這一段:

    + +
    +

    …例如十來歲的青少年子女認為最美的音樂是 RAP ,但父母可能無法認同而認為是噪音…

    + +
    杜正榮等(民 91 ),生活科學概論,國立空中大學,第 181 頁。
    +
    + +

    RAP 是噪音?不好意思,我完全無法認同這句話。

    + +

    噪音 Noise是一種反音樂,是一種音樂的基進對抗形式,對於固定音樂形式的反抗,在地下樂團的現場演唱會上,偶爾會遇上噪音樂團。噪音樂團會用特殊的方式來製造聲音,從用簡單的金屬、木塊作不規則的撞擊、刮擦,到自己製作數位噪音發聲器。我曾經在地下樂團的現場觀看過,雖然不能說覺得感動,但也覺得噪音企圖去衝撞既有的固定音樂形式,蠻了不起的。

    + +

    RAP 是噪音?對不起, RAP 不夠格稱為噪音。 RAP 是非常商業化的,根本沒資格進入反音樂的陣線。但 RAP 也沒資格稱為音樂。音樂有旋律,有節奏,但 RAP 只有節奏,沒有旋律。 RAP 充其量只是有節奏的講話聲音。講話算哪門子音樂?

    + +

    RAP 不是噪音,它不夠格稱為噪音;不是音樂,不夠格稱為音樂;不是反音樂,不夠格稱為反音樂;不是垃圾,不夠格稱為垃圾;不是什麼都不是,不夠格稱為什麼都不是RAP 充其量就是講話。講話跟音樂是兩碼子事。像這種明明不是音樂又自居為音樂,不知所謂的東西,竟然成為這個時代的主流,街上每家店都在放,連把耳朵摀起來都聽得到,真讓人噁心得想吐。

    + +
    + +
    + +
    +
    8.18.’06. 8:01am.
    + +

    矢沢永吉

    + +
    +矢沢永吉
    +

    矢沢永吉

    +
    + +

    剛剛上網查,發現矢沢あい(矢澤愛)筆名的由來,是因為她很喜歡歌星矢沢永吉(矢澤永吉),所以給自己取筆名為矢沢あいあい漢字作,就是喜愛的意思。矢沢あい就是喜愛矢沢永吉的意思。

    + +
    + +
    + +
    +
    8.17.’06. 11:02pm.
    + +

    矢沢あい(矢澤愛)作品

    + +
      +
    1. 天使なんかじゃない(聖學園天使)
    2. + +
    3. ご近所物語(芳鄰同盟會)
    4. + +
    5. 下弦の月 ラスト・クォーター(下弦之月 Last Quarter
    6. + +
    7. Paradise Kiss (天國之吻)
    8. + +
    9. NANA ナナ(娜娜)
    10. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 45 | + 46 | + 47 | + 48 | + 49 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0048.html.en.html b/htdocs/imacat/me/diary/0048.html.en.html new file mode 120000 index 0000000..3621227 --- /dev/null +++ b/htdocs/imacat/me/diary/0048.html.en.html @@ -0,0 +1 @@ +0048.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0048.html.en.xhtml b/htdocs/imacat/me/diary/0048.html.en.xhtml new file mode 100644 index 0000000..7247c52 --- /dev/null +++ b/htdocs/imacat/me/diary/0048.html.en.xhtml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 48 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 48

    + +
    + +
    + +
    +
    8.18.’06. 11:12pm.
    + +

    星期二晚上趕政府與工會作業時,唸到課本下面這一段:

    + +
    +

    正如 Perrow 所言:組織公開宣示的目標對組織行為而言,經常是最不重要的規約。組織往往在極有限範圍內才做為其所宣示目標 (announced goals) 的理性工具。它們有其它更重要的事情要做。相反地,組織是做為組織內外各種團體利益的資源;它們為眾多不同利益所使用。而在絕大多數的情況,公開宣示的目標都只是做為合法化這些利益的圖案,或掩蓋事實真相的煙幕。 (Perrow, 1978: 333–341) 台灣地區的工會組織正驗證上述的觀點。台灣各級產業工會所標示的宗旨不外是:爭取勞工權益、改善勞工生活、增進勞工知識及發展生產事業等。但實際上,工會一旦變成國家機關積極掌握的重要團體,則工會組織乃成為工會之內部幹部職位升遷、獲取利益的資源;同時也成為工會之外黨政機關宣導法令、動員社會的管道。而真正能替勞工爭取權益、改善條件的自主性工會之地位與力量卻反而喪失。這正是台灣工會面臨困境的癥結所在。

    + +
    李允傑(民 95 ),政府與工會,國立空中大學,第 154–155 頁。
    +
    + +

    嗯。真是寫得太好了~

    + +
    + +
    + +
    +
    8.18.’06. 10:56pm.
    + +

    草莓厚片土司與善變

    + +

    公司樓下,是一家怡客咖啡店

    + +

    怡客早餐中,最便宜的是 49 元的厚片土司早餐,厚片土司加綜合咖啡 49 元。雖然比美而美貴不少,可是咖啡店空氣清新,還有好聽的音樂,而且也不是太貴,所以我每天早上都會去買外帶,享受一點咖啡店早餐的高級感。

    + +

    一開始,我最常帶的,是草莓口味。我愛吃甜食,草莓果醬很甜,很合我的胃口。好一陣子,熟識的店員早上看我報到,都會直接問我:今天要外帶草莓厚片嗎?

    + +

    久了以後,我開始感覺無趣,想耍耍任性,換點口味。有幾次店員問我:今天要外帶草莓厚片嗎?我會突然改變心意:不,我今天要花生厚片。我開始看心情外帶,點餐時當場看想吃哪種口味,沒走到櫃台前,自己也不確定。久了以後,熟識的店員也發現我隨心情變來變去了,不再問:今天要外帶草莓厚片嗎?改問今天要外帶什麼口味?

    + +

    就這樣又過了一陣子,我又開始感覺不是滋味。我喜歡人家熟悉我的喜好,甚至預先幫我準備好的感覺,那讓我感覺很親切。現在這樣沒人抓得準我的喜好,感覺好疏離。於是我挑定了我最愛吃的草莓果醬,恢復固定只點草莓厚片。只是不知道要到什麼時候,才能夠恢復人家對我的喜好的信任感。

    + +

    我覺得這樣的我,蠻善變的。好像有點可惡,欺負人家嘛。 :p

    + +
    + +
    + +
    +
    8.18.’06. 10:39pm.
    + +

    心機(續)

    + +

    矢沢あい(矢澤愛)漫畫ご近所物語(芳鄰同盟會)中,幸田実果子(幸田實果子)的青梅竹馬山口ツトム(山口薰)和學姐中須茉莉子分手以後,実果子問他為什麼,ツトム回答說:因為我們都另外有喜歡的人了。実果子追問是誰,ツトム死都不說。事後実果子越來越在意,鼓起勇氣抓著ツトム的好朋友田代勇介問:ツトム有喜歡的人了,你知道是誰嗎?勇介想都不想就回答:妳!一瞬間,実果子整個人都傻了。

    + +

    其實很簡單的事,越是在意,就越是看不清楚。

    + +

    很多時候我們都是這樣:如果是不喜歡、不在意的人,人家喜不喜歡我,就看得很清楚;可是越喜歡,越在意,就越看不清楚。從外人的角度來看,明明是再清楚不過的事,可是如果自己就是當事人,就會想很多,費盡心思,連百分之一不是的可能性都不放過,放大成很可怕的事,反而看不清楚百分之九十九是的可能性。

    + +

    我其實也是個心機很重,有點讓人火大的傢伙。不過,費盡心機,不也就是真心喜歡一個人的證明嗎?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 46 | + 47 | + 48 | + 49 | + 50 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0048.html.zh-cn.html b/htdocs/imacat/me/diary/0048.html.zh-cn.html new file mode 120000 index 0000000..2650a56 --- /dev/null +++ b/htdocs/imacat/me/diary/0048.html.zh-cn.html @@ -0,0 +1 @@ +0048.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0048.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0048.html.zh-cn.xhtml new file mode 100644 index 0000000..367c3e5 --- /dev/null +++ b/htdocs/imacat/me/diary/0048.html.zh-cn.xhtml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷四十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷四十八

    + +
    + +
    + +
    +
    8.18.’06. 11:12pm.
    + +

    星期二晚上赶政府与工会作业时,念到课本下面这一段:

    + +
    +

    正如 Perrow 所言:组织公开宣示的目标对组织行为而言,经常是最不重要的规约。组织往往在极有限范围内才做为其所宣示目标 (announced goals) 的理性工具。它们有其它更重要的事情要做。相反地,组织是做为组织内外各种团体利益的资源;它们为众多不同利益所使用。而在绝大多数的情况,公开宣示的目标都只是做为合法化这些利益的图案,或掩盖事实真相的烟幕。 (Perrow, 1978: 333–341) 台湾地区的工会组织正验证上述的观点。台湾各级产业工会所标示的宗旨不外是:争取劳工权益、改善劳工生活、增进劳工知识及发展生产事业等。但实际上,工会一旦变成国家机关积极掌握的重要团体,则工会组织乃成为工会之内部干部职位升迁、获取利益的资源;同时也成为工会之外党政机关宣导法令、动员社会的管道。而真正能替劳工争取权益、改善条件的自主性工会之地位与力量却反而丧失。这正是台湾工会面临困境的症结所在。

    + +
    李允杰(民 95 ),政府与工会,国立空中大学,第 154–155 页。
    +
    + +

    嗯。真是写得太好了~

    + +
    + +
    + +
    +
    8.18.’06. 10:56pm.
    + +

    草莓厚片土司与善变

    + +

    公司楼下,是一家怡客咖啡店

    + +

    怡客早餐中,最便宜的是 49 元的厚片土司早餐,厚片土司加综合咖啡 49 元。虽然比美而美贵不少,可是咖啡店空气清新,还有好听的音乐,而且也不是太贵,所以我每天早上都会去买外带,享受一点咖啡店早餐的高级感。

    + +

    一开始,我最常带的,是草莓口味。我爱吃甜食,草莓果酱很甜,很合我的胃口。好一阵子,熟识的店员早上看我报到,都会直接问我:今天要外带草莓厚片吗?

    + +

    久了以后,我开始感觉无趣,想耍耍任性,换点口味。有几次店员问我:今天要外带草莓厚片吗?我会突然改变心意:不,我今天要花生厚片。我开始看心情外带,点餐时当场看想吃哪种口味,没走到柜台前,自己也不确定。久了以后,熟识的店员也发现我随心情变来变去了,不再问:今天要外带草莓厚片吗?改问今天要外带什么口味?

    + +

    就这样又过了一阵子,我又开始感觉不是滋味。我喜欢人家熟悉我的喜好,甚至预先帮我准备好的感觉,那让我感觉很亲切。现在这样没人抓得准我的喜好,感觉好疏离。於是我挑定了我最爱吃的草莓果酱,恢复固定只点草莓厚片。只是不知道要到什么时候,才能够恢复人家对我的喜好的信任感。

    + +

    我觉得这样的我,蛮善变的。好像有点可恶,欺负人家嘛。 :p

    + +
    + +
    + +
    +
    8.18.’06. 10:39pm.
    + +

    心机(续)

    + +

    矢沢あい(矢泽爱)漫画ご近所物语(芳邻同盟会)中,幸田実果子(幸田实果子)的青梅竹马山口ツトム(山口薰)和学姐中须茉莉子分手以后,実果子问他为什么,ツトム回答说:因为我们都另外有喜欢的人了。実果子追问是谁,ツトム死都不说。事后実果子越来越在意,鼓起勇气抓著ツトム的好朋友田代勇介问:ツトム有喜欢的人了,你知道是谁吗?勇介想都不想就回答:你!一瞬间,実果子整个人都傻了。

    + +

    其实很简单的事,越是在意,就越是看不清楚。

    + +

    很多时候我们都是这样:如果是不喜欢、不在意的人,人家喜不喜欢我,就看得很清楚;可是越喜欢,越在意,就越看不清楚。从外人的角度来看,明明是再清楚不过的事,可是如果自己就是当事人,就会想很多,费尽心思,连百分之一不是的可能性都不放过,放大成很可怕的事,反而看不清楚百分之九十九是的可能性。

    + +

    我其实也是个心机很重,有点让人火大的家伙。不过,费尽心机,不也就是真心喜欢一个人的证明吗?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 46 | + 47 | + 48 | + 49 | + 50 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0048.html.zh-tw.html b/htdocs/imacat/me/diary/0048.html.zh-tw.html new file mode 120000 index 0000000..e1579a2 --- /dev/null +++ b/htdocs/imacat/me/diary/0048.html.zh-tw.html @@ -0,0 +1 @@ +0048.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0048.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0048.html.zh-tw.xhtml new file mode 100644 index 0000000..cdc088f --- /dev/null +++ b/htdocs/imacat/me/diary/0048.html.zh-tw.xhtml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷四十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷四十八

    + +
    + +
    + +
    +
    8.18.’06. 11:12pm.
    + +

    星期二晚上趕政府與工會作業時,唸到課本下面這一段:

    + +
    +

    正如 Perrow 所言:組織公開宣示的目標對組織行為而言,經常是最不重要的規約。組織往往在極有限範圍內才做為其所宣示目標 (announced goals) 的理性工具。它們有其它更重要的事情要做。相反地,組織是做為組織內外各種團體利益的資源;它們為眾多不同利益所使用。而在絕大多數的情況,公開宣示的目標都只是做為合法化這些利益的圖案,或掩蓋事實真相的煙幕。 (Perrow, 1978: 333–341) 台灣地區的工會組織正驗證上述的觀點。台灣各級產業工會所標示的宗旨不外是:爭取勞工權益、改善勞工生活、增進勞工知識及發展生產事業等。但實際上,工會一旦變成國家機關積極掌握的重要團體,則工會組織乃成為工會之內部幹部職位升遷、獲取利益的資源;同時也成為工會之外黨政機關宣導法令、動員社會的管道。而真正能替勞工爭取權益、改善條件的自主性工會之地位與力量卻反而喪失。這正是台灣工會面臨困境的癥結所在。

    + +
    李允傑(民 95 ),政府與工會,國立空中大學,第 154–155 頁。
    +
    + +

    嗯。真是寫得太好了~

    + +
    + +
    + +
    +
    8.18.’06. 10:56pm.
    + +

    草莓厚片土司與善變

    + +

    公司樓下,是一家怡客咖啡店

    + +

    怡客早餐中,最便宜的是 49 元的厚片土司早餐,厚片土司加綜合咖啡 49 元。雖然比美而美貴不少,可是咖啡店空氣清新,還有好聽的音樂,而且也不是太貴,所以我每天早上都會去買外帶,享受一點咖啡店早餐的高級感。

    + +

    一開始,我最常帶的,是草莓口味。我愛吃甜食,草莓果醬很甜,很合我的胃口。好一陣子,熟識的店員早上看我報到,都會直接問我:今天要外帶草莓厚片嗎?

    + +

    久了以後,我開始感覺無趣,想耍耍任性,換點口味。有幾次店員問我:今天要外帶草莓厚片嗎?我會突然改變心意:不,我今天要花生厚片。我開始看心情外帶,點餐時當場看想吃哪種口味,沒走到櫃台前,自己也不確定。久了以後,熟識的店員也發現我隨心情變來變去了,不再問:今天要外帶草莓厚片嗎?改問今天要外帶什麼口味?

    + +

    就這樣又過了一陣子,我又開始感覺不是滋味。我喜歡人家熟悉我的喜好,甚至預先幫我準備好的感覺,那讓我感覺很親切。現在這樣沒人抓得準我的喜好,感覺好疏離。於是我挑定了我最愛吃的草莓果醬,恢復固定只點草莓厚片。只是不知道要到什麼時候,才能夠恢復人家對我的喜好的信任感。

    + +

    我覺得這樣的我,蠻善變的。好像有點可惡,欺負人家嘛。 :p

    + +
    + +
    + +
    +
    8.18.’06. 10:39pm.
    + +

    心機(續)

    + +

    矢沢あい(矢澤愛)漫畫ご近所物語(芳鄰同盟會)中,幸田実果子(幸田實果子)的青梅竹馬山口ツトム(山口薰)和學姐中須茉莉子分手以後,実果子問他為什麼,ツトム回答說:因為我們都另外有喜歡的人了。実果子追問是誰,ツトム死都不說。事後実果子越來越在意,鼓起勇氣抓著ツトム的好朋友田代勇介問:ツトム有喜歡的人了,你知道是誰嗎?勇介想都不想就回答:妳!一瞬間,実果子整個人都傻了。

    + +

    其實很簡單的事,越是在意,就越是看不清楚。

    + +

    很多時候我們都是這樣:如果是不喜歡、不在意的人,人家喜不喜歡我,就看得很清楚;可是越喜歡,越在意,就越看不清楚。從外人的角度來看,明明是再清楚不過的事,可是如果自己就是當事人,就會想很多,費盡心思,連百分之一不是的可能性都不放過,放大成很可怕的事,反而看不清楚百分之九十九是的可能性。

    + +

    我其實也是個心機很重,有點讓人火大的傢伙。不過,費盡心機,不也就是真心喜歡一個人的證明嗎?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 46 | + 47 | + 48 | + 49 | + 50 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0049.html.en.html b/htdocs/imacat/me/diary/0049.html.en.html new file mode 120000 index 0000000..02b0a72 --- /dev/null +++ b/htdocs/imacat/me/diary/0049.html.en.html @@ -0,0 +1 @@ +0049.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0049.html.en.xhtml b/htdocs/imacat/me/diary/0049.html.en.xhtml new file mode 100644 index 0000000..2b7279c --- /dev/null +++ b/htdocs/imacat/me/diary/0049.html.en.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 49 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 49

    + +
    + +
    + +
    +
    8.19.’06. 1:57am.
    + +

    一個字頭的誕生—一個人生,兩段命運

    + +
    +一個字頭的誕生
    +

    一個字頭的誕生

    +
    + + + +

    一個字頭的誕生真的太好看了!當我之前看到影評最鐘愛的電影之一個字頭的誕生時,看到有人評得這麼好,我相信了一半。看語氣應該不假,但總覺得應該是個人喜好吧。直到自己看了電影以後,才大呼過癮。

    + +

    同一組人物時空,兩個故事,兩種結局。在香港的人生面臨一個重大關卡,往中國或是往台灣,是生是死在此決定。 1997 年香港回歸時拍的這部電影,借喻時勢的意味不言而喻。然而,雖然是黑幫片,這部電影還是讓我從頭笑到尾,笑到肚子痛。讓我想起昆汀塔倫提諾早期黑色追緝令的黑色幽默。搶劫忘了拿錢,藏屍忘記扣機,當黑社會不會開車。精明的阿 Matt 碰上糊塗的阿狗,所有亂七八遭的倒楣事全都撞在一起,最後被當成運鈔車搶匪全部打死。如果人生重來一次呢?如果當時選了另一條路,結果會不會不一樣?為一夜情不認識的女人送機送到了台灣,當殺手忘了帶地址,同時接下敵對兄弟的殺手案。糊塗的阿 Matt 和精明的阿狗,重來一次,性格也反過來了。雖然還是亂七八糟的倒楣事一堆,但還是半身不遂地當上了台灣的老大。到底是福還是禍?人生真的可以重來嗎?命運真的是註定的嗎?

    + +

    劉青雲和吳鎮宇,兩個人劇中的角色性格竟然能夠交換來演,演一段人生後,彼此角色設定反過來,再演一次。演技收放自如到這種境界,實在叫人太過癮了。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 47 | + 48 | + 49 | + 50 | + 51 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0049.html.zh-cn.html b/htdocs/imacat/me/diary/0049.html.zh-cn.html new file mode 120000 index 0000000..c2f5d1f --- /dev/null +++ b/htdocs/imacat/me/diary/0049.html.zh-cn.html @@ -0,0 +1 @@ +0049.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0049.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0049.html.zh-cn.xhtml new file mode 100644 index 0000000..980b129 --- /dev/null +++ b/htdocs/imacat/me/diary/0049.html.zh-cn.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷四十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷四十九

    + +
    + +
    + +
    +
    8.19.’06. 1:57am.
    + +

    一个字头的诞生—一个人生,两段命运

    + +
    +一个字头的诞生
    +

    一个字头的诞生

    +
    + + + +

    一个字头的诞生真的太好看了!当我之前看到影评最钟爱的电影之一个字头的诞生时,看到有人评得这么好,我相信了一半。看语气应该不假,但总觉得应该是个人喜好吧。直到自己看了电影以后,才大呼过瘾。

    + +

    同一组人物时空,两个故事,两种结局。在香港的人生面临一个重大关卡,往中国或是往台湾,是生是死在此决定。 1997 年香港回归时拍的这部电影,借喻时势的意味不言而喻。然而,虽然是黑帮片,这部电影还是让我从头笑到尾,笑到肚子痛。让我想起昆汀塔伦提诺早期黑色追缉令的黑色幽默。抢劫忘了拿钱,藏尸忘记扣机,当黑社会不会开车。精明的阿 Matt 碰上糊涂的阿狗,所有乱七八遭的倒楣事全都撞在一起,最后被当成运钞车抢匪全部打死。如果人生重来一次呢?如果当时选了另一条路,结果会不会不一样?为一夜情不认识的女人送机送到了台湾,当杀手忘了带地址,同时接下敌对兄弟的杀手案。糊涂的阿 Matt 和精明的阿狗,重来一次,性格也反过来了。虽然还是乱七八糟的倒楣事一堆,但还是半身不遂地当上了台湾的老大。到底是福还是祸?人生真的可以重来吗?命运真的是注定的吗?

    + +

    刘青云和吴镇宇,两个人剧中的角色性格竟然能够交换来演,演一段人生后,彼此角色设定反过来,再演一次。演技收放自如到这种境界,实在叫人太过瘾了。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 47 | + 48 | + 49 | + 50 | + 51 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0049.html.zh-tw.html b/htdocs/imacat/me/diary/0049.html.zh-tw.html new file mode 120000 index 0000000..0bb9169 --- /dev/null +++ b/htdocs/imacat/me/diary/0049.html.zh-tw.html @@ -0,0 +1 @@ +0049.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0049.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0049.html.zh-tw.xhtml new file mode 100644 index 0000000..c39fd99 --- /dev/null +++ b/htdocs/imacat/me/diary/0049.html.zh-tw.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷四十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷四十九

    + +
    + +
    + +
    +
    8.19.’06. 1:57am.
    + +

    一個字頭的誕生—一個人生,兩段命運

    + +
    +一個字頭的誕生
    +

    一個字頭的誕生

    +
    + + + +

    一個字頭的誕生真的太好看了!當我之前看到影評最鐘愛的電影之一個字頭的誕生時,看到有人評得這麼好,我相信了一半。看語氣應該不假,但總覺得應該是個人喜好吧。直到自己看了電影以後,才大呼過癮。

    + +

    同一組人物時空,兩個故事,兩種結局。在香港的人生面臨一個重大關卡,往中國或是往台灣,是生是死在此決定。 1997 年香港回歸時拍的這部電影,借喻時勢的意味不言而喻。然而,雖然是黑幫片,這部電影還是讓我從頭笑到尾,笑到肚子痛。讓我想起昆汀塔倫提諾早期黑色追緝令的黑色幽默。搶劫忘了拿錢,藏屍忘記扣機,當黑社會不會開車。精明的阿 Matt 碰上糊塗的阿狗,所有亂七八遭的倒楣事全都撞在一起,最後被當成運鈔車搶匪全部打死。如果人生重來一次呢?如果當時選了另一條路,結果會不會不一樣?為一夜情不認識的女人送機送到了台灣,當殺手忘了帶地址,同時接下敵對兄弟的殺手案。糊塗的阿 Matt 和精明的阿狗,重來一次,性格也反過來了。雖然還是亂七八糟的倒楣事一堆,但還是半身不遂地當上了台灣的老大。到底是福還是禍?人生真的可以重來嗎?命運真的是註定的嗎?

    + +

    劉青雲和吳鎮宇,兩個人劇中的角色性格竟然能夠交換來演,演一段人生後,彼此角色設定反過來,再演一次。演技收放自如到這種境界,實在叫人太過癮了。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 47 | + 48 | + 49 | + 50 | + 51 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0050.html.en.html b/htdocs/imacat/me/diary/0050.html.en.html new file mode 120000 index 0000000..be528e7 --- /dev/null +++ b/htdocs/imacat/me/diary/0050.html.en.html @@ -0,0 +1 @@ +0050.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0050.html.en.xhtml b/htdocs/imacat/me/diary/0050.html.en.xhtml new file mode 100644 index 0000000..7d438c0 --- /dev/null +++ b/htdocs/imacat/me/diary/0050.html.en.xhtml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 50 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 50

    + +
    + +
    + +
    +
    8.19.’06. 4:39am.
    + +

    下弦の月~ラスト・クォーター—一開場就掀底牌的推理劇

    + +
    +下弦の月~ラスト・クォーター
    +

    下弦の月~ラスト・クォーター

    +
    + +
      +
    • 片名:下弦の月~ラスト・クォーター
    • +
    • 中譯片名:下弦之月 Last Quarter
    • +
    • 發行年份: 2004
    • +
    • 製作公司:松竹映画
    • +
    • 導演:二階健
    • +
    • 原作:矢沢あい下弦の月(集英社刊)
    • +
    • 演員: +
        +
      • 栗山千明:望月美月(バトル・ロワイアル大逃殺 Battle Royale (2000) 、Kill Bill 追殺比爾 (2003,2004) )
      • +
      • 伊藤歩:上條さやか(上條沙也加)
      • +
      • HYDE :アダムAdam 亞當)(歌手)
      • +
      • 成宮寛貴:安西知己(ごくせん 極道鮮師 (2002, 2003) 、 高校教師 2003 )
      • +
      • 黒川智花:白石蛍
      • +
      • 落合扶樹:三浦正輝
      • +
      +
    • +
    + +

    本來找到的是沒有字幕的版本,我快哭了說~雖然也找到了字幕,可是我是要看電影的,不是要壓電影的。又不可能邊看電影邊對字幕。唉。還好找到暴風影音,可以直接把字幕和影片組起來,才能看。真是太感動了。

    + +

    先看過漫畫,會忍不住一直和漫畫相比,感覺差了些。劇情主線沒有變,不過改編的小節也不少。如果我沒看過漫畫的話,可能會覺得更好吧~

    + +

    節奏不夠緊湊。原作是短篇,應該很適合拍成節奏緊湊的電影。原來四個小孩子,變成兩個中孩子;原來一個英國人,變成日英混血;原來前奏很短,所有的謎都是四個小孩子慢慢解開的,變成前奏很長,把所有情節交待清楚了,中間就沒什麼好看了。關鍵歌 Evil Eye 聽不大清楚。唉。

    + +

    我可以說不好看嗎?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 48 | + 49 | + 50 | + 51 | + 52 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0050.html.zh-cn.html b/htdocs/imacat/me/diary/0050.html.zh-cn.html new file mode 120000 index 0000000..16913cb --- /dev/null +++ b/htdocs/imacat/me/diary/0050.html.zh-cn.html @@ -0,0 +1 @@ +0050.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0050.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0050.html.zh-cn.xhtml new file mode 100644 index 0000000..f349226 --- /dev/null +++ b/htdocs/imacat/me/diary/0050.html.zh-cn.xhtml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷五十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷五十

    + +
    + +
    + +
    +
    8.19.’06. 4:39am.
    + +

    下弦の月~ラスト・クォーター—一开场就掀底牌的推理剧

    + +
    +下弦の月~ラスト・クォーター
    +

    下弦の月~ラスト・クォーター

    +
    + +
      +
    • 片名:下弦の月~ラスト・クォーター
    • +
    • 中译片名:下弦之月 Last Quarter
    • +
    • 发行年份: 2004
    • +
    • 制作公司:松竹映画
    • +
    • 导演:二阶健
    • +
    • 原作:矢沢あい下弦の月(集英社刊)
    • +
    • 演员: +
        +
      • 栗山千明:望月美月(バトル・ロワイアル大逃杀 Battle Royale (2000) 、Kill Bill 追杀比尔 (2003,2004) )
      • +
      • 伊藤歩:上条さやか(上条沙也加)
      • +
      • HYDE :アダムAdam 亚当)(歌手)
      • +
      • 成宫寛贵:安西知己(ごくせん 极道鲜师 (2002, 2003) 、 高校教师 2003 )
      • +
      • 黒川智花:白石蛍
      • +
      • 落合扶树:三浦正辉
      • +
      +
    • +
    + +

    本来找到的是没有字幕的版本,我快哭了说~虽然也找到了字幕,可是我是要看电影的,不是要压电影的。又不可能边看电影边对字幕。唉。还好找到暴风影音,可以直接把字幕和影片组起来,才能看。真是太感动了。

    + +

    先看过漫画,会忍不住一直和漫画相比,感觉差了些。剧情主线没有变,不过改编的小节也不少。如果我没看过漫画的话,可能会觉得更好吧~

    + +

    节奏不够紧凑。原作是短篇,应该很适合拍成节奏紧凑的电影。原来四个小孩子,变成两个中孩子;原来一个英国人,变成日英混血;原来前奏很短,所有的谜都是四个小孩子慢慢解开的,变成前奏很长,把所有情节交待清楚了,中间就没什么好看了。关键歌 Evil Eye 听不大清楚。唉。

    + +

    我可以说不好看吗?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 48 | + 49 | + 50 | + 51 | + 52 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0050.html.zh-tw.html b/htdocs/imacat/me/diary/0050.html.zh-tw.html new file mode 120000 index 0000000..290682d --- /dev/null +++ b/htdocs/imacat/me/diary/0050.html.zh-tw.html @@ -0,0 +1 @@ +0050.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0050.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0050.html.zh-tw.xhtml new file mode 100644 index 0000000..9bd0b10 --- /dev/null +++ b/htdocs/imacat/me/diary/0050.html.zh-tw.xhtml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷五十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷五十

    + +
    + +
    + +
    +
    8.19.’06. 4:39am.
    + +

    下弦の月~ラスト・クォーター—一開場就掀底牌的推理劇

    + +
    +下弦の月~ラスト・クォーター
    +

    下弦の月~ラスト・クォーター

    +
    + +
      +
    • 片名:下弦の月~ラスト・クォーター
    • +
    • 中譯片名:下弦之月 Last Quarter
    • +
    • 發行年份: 2004
    • +
    • 製作公司:松竹映画
    • +
    • 導演:二階健
    • +
    • 原作:矢沢あい下弦の月(集英社刊)
    • +
    • 演員: +
        +
      • 栗山千明:望月美月(バトル・ロワイアル大逃殺 Battle Royale (2000) 、Kill Bill 追殺比爾 (2003,2004) )
      • +
      • 伊藤歩:上條さやか(上條沙也加)
      • +
      • HYDE :アダムAdam 亞當)(歌手)
      • +
      • 成宮寛貴:安西知己(ごくせん 極道鮮師 (2002, 2003) 、 高校教師 2003 )
      • +
      • 黒川智花:白石蛍
      • +
      • 落合扶樹:三浦正輝
      • +
      +
    • +
    + +

    本來找到的是沒有字幕的版本,我快哭了說~雖然也找到了字幕,可是我是要看電影的,不是要壓電影的。又不可能邊看電影邊對字幕。唉。還好找到暴風影音,可以直接把字幕和影片組起來,才能看。真是太感動了。

    + +

    先看過漫畫,會忍不住一直和漫畫相比,感覺差了些。劇情主線沒有變,不過改編的小節也不少。如果我沒看過漫畫的話,可能會覺得更好吧~

    + +

    節奏不夠緊湊。原作是短篇,應該很適合拍成節奏緊湊的電影。原來四個小孩子,變成兩個中孩子;原來一個英國人,變成日英混血;原來前奏很短,所有的謎都是四個小孩子慢慢解開的,變成前奏很長,把所有情節交待清楚了,中間就沒什麼好看了。關鍵歌 Evil Eye 聽不大清楚。唉。

    + +

    我可以說不好看嗎?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 48 | + 49 | + 50 | + 51 | + 52 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0051.html.en.html b/htdocs/imacat/me/diary/0051.html.en.html new file mode 120000 index 0000000..9128ceb --- /dev/null +++ b/htdocs/imacat/me/diary/0051.html.en.html @@ -0,0 +1 @@ +0051.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0051.html.en.xhtml b/htdocs/imacat/me/diary/0051.html.en.xhtml new file mode 100644 index 0000000..99f2274 --- /dev/null +++ b/htdocs/imacat/me/diary/0051.html.en.xhtml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 51 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 51

    + +
    + +
    + +
    +
    8.20.’06. 1:20am.
    + +

    Underworld 決戰異世界羅密歐與茱麗葉科幻動作版

    + +
    +Underworld 決戰異世界
    +

    Underworld 決戰異世界

    +
    + + + +

    決戰異世界很好看。以隔代的羅密歐與茱麗葉式愛情為骨幹,不過沒有羅密歐與茱麗葉的劇情,主角也換成女人。世仇的吸血鬼與狼人族,吸血鬼女殺手席琳愛上了剛被狼人咬傷、即將成為狼人的人類麥可,在席琳契而不捨的探索下,發現世仇來自上一代的愛怨。夾雜兩代愛怨、謊言、權力、私慾的真相,一步步被揭開。最後兩個人雖然活了下來,卻成了兩族追殺的目標,為續集鋪路。

    + +

    緊湊的故事,既有史詩般的架構,也有強大的劇情張力。在地底不為人知的世界,遠望有兩大家族的世仇血鬥史,近看除了非現實的元素外,仍是人類世界的權力鬥爭、慾望、謊言。除了主角凱特貝琴薩外,配角蘇菲亞梅爾的表現也非常搶眼,女人不是套死在好萊塢個性公式的肉彈花瓶,而是有動機、有心機、有所為有所不為的活生生的角色。

    + +

    作為一部科幻動作片,特效也很完美。不管是吸血鬼和狼人的超強運動力、狼人變身、硝酸銀滲入血管、震憾的音效,都令人驚嘆。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 49 | + 50 | + 51 | + 52 | + 53 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0051.html.zh-cn.html b/htdocs/imacat/me/diary/0051.html.zh-cn.html new file mode 120000 index 0000000..eedb98d --- /dev/null +++ b/htdocs/imacat/me/diary/0051.html.zh-cn.html @@ -0,0 +1 @@ +0051.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0051.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0051.html.zh-cn.xhtml new file mode 100644 index 0000000..d689df9 --- /dev/null +++ b/htdocs/imacat/me/diary/0051.html.zh-cn.xhtml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷五十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷五十一

    + +
    + +
    + +
    +
    8.20.’06. 1:20am.
    + +

    Underworld 决战异世界罗密欧与茱丽叶科幻动作版

    + +
    +Underworld 决战异世界
    +

    Underworld 决战异世界

    +
    + + + +

    决战异世界很好看。以隔代的罗密欧与茱丽叶式爱情为骨干,不过没有罗密欧与茱丽叶的剧情,主角也换成女人。世仇的吸血鬼与狼人族,吸血鬼女杀手席琳爱上了刚被狼人咬伤、即将成为狼人的人类麦可,在席琳契而不舍的探索下,发现世仇来自上一代的爱怨。夹杂两代爱怨、谎言、权力、私欲的真相,一步步被揭开。最后两个人虽然活了下来,却成了两族追杀的目标,为续集铺路。

    + +

    紧凑的故事,既有史诗般的架构,也有强大的剧情张力。在地底不为人知的世界,远望有两大家族的世仇血斗史,近看除了非现实的元素外,仍是人类世界的权力斗争、欲望、谎言。除了主角凯特贝琴萨外,配角苏菲亚梅尔的表现也非常抢眼,女人不是套死在好莱坞个性公式的肉弹花瓶,而是有动机、有心机、有所为有所不为的活生生的角色。

    + +

    作为一部科幻动作片,特效也很完美。不管是吸血鬼和狼人的超强运动力、狼人变身、硝酸银渗入血管、震憾的音效,都令人惊叹。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 49 | + 50 | + 51 | + 52 | + 53 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0051.html.zh-tw.html b/htdocs/imacat/me/diary/0051.html.zh-tw.html new file mode 120000 index 0000000..96db36b --- /dev/null +++ b/htdocs/imacat/me/diary/0051.html.zh-tw.html @@ -0,0 +1 @@ +0051.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0051.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0051.html.zh-tw.xhtml new file mode 100644 index 0000000..dfed649 --- /dev/null +++ b/htdocs/imacat/me/diary/0051.html.zh-tw.xhtml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷五十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷五十一

    + +
    + +
    + +
    +
    8.20.’06. 1:20am.
    + +

    Underworld 決戰異世界羅密歐與茱麗葉科幻動作版

    + +
    +Underworld 決戰異世界
    +

    Underworld 決戰異世界

    +
    + + + +

    決戰異世界很好看。以隔代的羅密歐與茱麗葉式愛情為骨幹,不過沒有羅密歐與茱麗葉的劇情,主角也換成女人。世仇的吸血鬼與狼人族,吸血鬼女殺手席琳愛上了剛被狼人咬傷、即將成為狼人的人類麥可,在席琳契而不捨的探索下,發現世仇來自上一代的愛怨。夾雜兩代愛怨、謊言、權力、私慾的真相,一步步被揭開。最後兩個人雖然活了下來,卻成了兩族追殺的目標,為續集鋪路。

    + +

    緊湊的故事,既有史詩般的架構,也有強大的劇情張力。在地底不為人知的世界,遠望有兩大家族的世仇血鬥史,近看除了非現實的元素外,仍是人類世界的權力鬥爭、慾望、謊言。除了主角凱特貝琴薩外,配角蘇菲亞梅爾的表現也非常搶眼,女人不是套死在好萊塢個性公式的肉彈花瓶,而是有動機、有心機、有所為有所不為的活生生的角色。

    + +

    作為一部科幻動作片,特效也很完美。不管是吸血鬼和狼人的超強運動力、狼人變身、硝酸銀滲入血管、震憾的音效,都令人驚嘆。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 49 | + 50 | + 51 | + 52 | + 53 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0052.html.en.html b/htdocs/imacat/me/diary/0052.html.en.html new file mode 120000 index 0000000..069969e --- /dev/null +++ b/htdocs/imacat/me/diary/0052.html.en.html @@ -0,0 +1 @@ +0052.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0052.html.en.xhtml b/htdocs/imacat/me/diary/0052.html.en.xhtml new file mode 100644 index 0000000..5bca5d9 --- /dev/null +++ b/htdocs/imacat/me/diary/0052.html.en.xhtml @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 52 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 52

    + +
    + +
    + +
    +
    8.20.’06. 5:28pm.
    + +

    最好的時光 Three Times—回憶,才是最好的時光

    + +
    +最好的時光 Three Times
    +

    最好的時光 Three Times

    +
    + +
      +
    • 片名:最好的時光
    • +
    • 英文片名: Three Times
    • +
    • 發行年份: 2005
    • +
    • 製作公司:三視多媒體
    • +
    • 導演:侯孝賢
    • +
    • 編劇:朱天文
    • +
    • 演員: +
        +
      • 舒淇:秀美(戀愛夢)、藝旦姐(自由夢)、陳靖(青春夢)
      • +
      • 張震:少年(戀愛夢)、男子(自由夢)、震(青春夢)
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +
    +

    …最好的時光。最好,不是因為最好所以我們眷念不已,而是倒過來,是因為永遠失落了,我們只能用懷念召喚它們,所以才成為最好。

    + +
    侯孝賢台北 2005.4
    +
    + +

    這段話說得太好了,好到再加任何的添補,都屬多餘。

    + +

    三段故事,三段最好的時光,從 1911 ,到 1966 ,到 2005 。什麼是最好的時光?三段故事,其實都是過去,都是倒敘中的回憶,都不是現在的真實。如果要我們捫心自問,對自己而言,最好的時光是哪一段,我們會怎麼回答呢?不是激情的愛慾,不是生死的誓言,而是在歲月流轉中,不段流瀉點點滴滴的瑣事,累積起來的情感:整理撞球檯,兩人之間沒有意義的對話遊戲,身邊姊妹的終身,一來一回的簡訊。所有當時不覺得什麼的點點滴滴情感,二十年、五十年後回憶,想到的儘是這些。

    + +

    看完了,感動得眼淚要流下來。

    + +
    + +
    + +
    +
    8.20.’06. 4:18am.
    + +

    天邊一朵雲 The Wayward Cloud—苦無歸處的乾渴慾望

    + +
    +天邊一朵雲 The Wayward Cloud
    +

    天邊一朵雲 The Wayward Cloud

    +
    + +
      +
    • 片名:天邊一朵雲
    • +
    • 英文片名: The Wayward Cloud
    • +
    • 發行年份: 2005
    • +
    • 製作公司: Arena Films
    • +
    • 導演:蔡明亮
    • +
    • 演員: +
        +
      • 李康生
      • +
      • 陳湘琪
      • +
      • 夜桜すもも(夜櫻李子)
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    終於看了天邊一朵雲了。真的很好看。說看不懂,大概是看電影的資歷還短,又或者只習慣看商業片吧。

    + +

    片中的象徵符號很豐富,西瓜、水、鑰匙…西瓜就像慾望,又比慾望豐富、有趣,可以大口大口地吃,可以解渴,也會破裂。因為停水所以乾渴,然而渴的不只水,還有慾望。男主角的慾望乾渴了,工作上看似勇猛的性慾,在現實中卻再也提不起興緻;女主角渴望享受性愛,但怎麼挑逗,男主角還是沒有反應。人的情感和慾望,就像天邊的一朵雲,就算有了愛情,也還是寂寞,還是沒有歸處,還是無根地飄浮在空中。(這是我最後聽到片尾曲才弄懂的。)

    + +

    電影有一個很有趣的構圖是:一個畫面從中間分開,兩邊分隔成兩個空間,兩個空間在中間連起來。兩邊的人彼此看不見對方,各自有各自的行動,有各自的盤算和心機。就像男主角第一次去女主角家裏修皮箱,右邊在修皮箱,左邊在切西瓜,彼此又在偷看對方。作為觀眾,可以同時看到兩邊的情形。像這樣的鏡頭運用了很多次,非常有趣。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 50 | + 51 | + 52 | + 53 | + 54 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0052.html.zh-cn.html b/htdocs/imacat/me/diary/0052.html.zh-cn.html new file mode 120000 index 0000000..717c174 --- /dev/null +++ b/htdocs/imacat/me/diary/0052.html.zh-cn.html @@ -0,0 +1 @@ +0052.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0052.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0052.html.zh-cn.xhtml new file mode 100644 index 0000000..c9a032a --- /dev/null +++ b/htdocs/imacat/me/diary/0052.html.zh-cn.xhtml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷五十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷五十二

    + +
    + +
    + +
    +
    8.20.’06. 5:28pm.
    + +

    最好的时光 Three Times—回忆,才是最好的时光

    + +
    +最好的时光 Three Times
    +

    最好的时光 Three Times

    +
    + +
      +
    • 片名:最好的时光
    • +
    • 英文片名: Three Times
    • +
    • 发行年份: 2005
    • +
    • 制作公司:三视多媒体
    • +
    • 导演:侯孝贤
    • +
    • 编剧:朱天文
    • +
    • 演员: +
        +
      • 舒淇:秀美(恋爱梦)、艺旦姐(自由梦)、陈靖(青春梦)
      • +
      • 张震:少年(恋爱梦)、男子(自由梦)、震(青春梦)
      • +
      +
    • +
    • 推荐影评: + +
    • +
    + +
    +

    …最好的时光。最好,不是因为最好所以我们眷念不已,而是倒过来,是因为永远失落了,我们只能用怀念召唤它们,所以才成为最好。

    + +
    侯孝贤台北 2005.4
    +
    + +

    这段话说得太好了,好到再加任何的添补,都属多余。

    + +

    三段故事,三段最好的时光,从 1911 ,到 1966 ,到 2005 。什么是最好的时光?三段故事,其实都是过去,都是倒叙中的回忆,都不是现在的真实。如果要我们扪心自问,对自己而言,最好的时光是哪一段,我们会怎么回答呢?不是激情的爱欲,不是生死的誓言,而是在岁月流转中,不段流泻点点滴滴的琐事,累积起来的情感:整理撞球台,两人之间没有意义的对话游戏,身边姊妹的终身,一来一回的简讯。所有当时不觉得什么的点点滴滴情感,二十年、五十年后回忆,想到的尽是这些。

    + +

    看完了,感动得眼泪要流下来。

    + +
    + +
    + +
    +
    8.20.’06. 4:18am.
    + +

    天边一朵云 The Wayward Cloud—苦无归处的干渴欲望

    + +
    +天边一朵云 The Wayward Cloud
    +

    天边一朵云 The Wayward Cloud

    +
    + +
      +
    • 片名:天边一朵云
    • +
    • 英文片名: The Wayward Cloud
    • +
    • 发行年份: 2005
    • +
    • 制作公司: Arena Films
    • +
    • 导演:蔡明亮
    • +
    • 演员: +
        +
      • 李康生
      • +
      • 陈湘琪
      • +
      • 夜桜すもも(夜樱李子)
      • +
      +
    • +
    • 推荐影评: + +
    • +
    + +

    终於看了天边一朵云了。真的很好看。说看不懂,大概是看电影的资历还短,又或者只习惯看商业片吧。

    + +

    片中的象徵符号很丰富,西瓜、水、钥匙…西瓜就像欲望,又比欲望丰富、有趣,可以大口大口地吃,可以解渴,也会破裂。因为停水所以干渴,然而渴的不只水,还有欲望。男主角的欲望干渴了,工作上看似勇猛的性欲,在现实中却再也提不起兴致;女主角渴望享受性爱,但怎么挑逗,男主角还是没有反应。人的情感和欲望,就像天边的一朵云,就算有了爱情,也还是寂寞,还是没有归处,还是无根地飘浮在空中。(这是我最后听到片尾曲才弄懂的。)

    + +

    电影有一个很有趣的构图是:一个画面从中间分开,两边分隔成两个空间,两个空间在中间连起来。两边的人彼此看不见对方,各自有各自的行动,有各自的盘算和心机。就像男主角第一次去女主角家里修皮箱,右边在修皮箱,左边在切西瓜,彼此又在偷看对方。作为观众,可以同时看到两边的情形。像这样的镜头运用了很多次,非常有趣。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 50 | + 51 | + 52 | + 53 | + 54 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0052.html.zh-tw.html b/htdocs/imacat/me/diary/0052.html.zh-tw.html new file mode 120000 index 0000000..3e68c10 --- /dev/null +++ b/htdocs/imacat/me/diary/0052.html.zh-tw.html @@ -0,0 +1 @@ +0052.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0052.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0052.html.zh-tw.xhtml new file mode 100644 index 0000000..94e4f56 --- /dev/null +++ b/htdocs/imacat/me/diary/0052.html.zh-tw.xhtml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷五十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷五十二

    + +
    + +
    + +
    +
    8.20.’06. 5:28pm.
    + +

    最好的時光 Three Times—回憶,才是最好的時光

    + +
    +最好的時光 Three Times
    +

    最好的時光 Three Times

    +
    + +
      +
    • 片名:最好的時光
    • +
    • 英文片名: Three Times
    • +
    • 發行年份: 2005
    • +
    • 製作公司:三視多媒體
    • +
    • 導演:侯孝賢
    • +
    • 編劇:朱天文
    • +
    • 演員: +
        +
      • 舒淇:秀美(戀愛夢)、藝旦姐(自由夢)、陳靖(青春夢)
      • +
      • 張震:少年(戀愛夢)、男子(自由夢)、震(青春夢)
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +
    +

    …最好的時光。最好,不是因為最好所以我們眷念不已,而是倒過來,是因為永遠失落了,我們只能用懷念召喚它們,所以才成為最好。

    + +
    侯孝賢台北 2005.4
    +
    + +

    這段話說得太好了,好到再加任何的添補,都屬多餘。

    + +

    三段故事,三段最好的時光,從 1911 ,到 1966 ,到 2005 。什麼是最好的時光?三段故事,其實都是過去,都是倒敘中的回憶,都不是現在的真實。如果要我們捫心自問,對自己而言,最好的時光是哪一段,我們會怎麼回答呢?不是激情的愛慾,不是生死的誓言,而是在歲月流轉中,不段流瀉點點滴滴的瑣事,累積起來的情感:整理撞球檯,兩人之間沒有意義的對話遊戲,身邊姊妹的終身,一來一回的簡訊。所有當時不覺得什麼的點點滴滴情感,二十年、五十年後回憶,想到的儘是這些。

    + +

    看完了,感動得眼淚要流下來。

    + +
    + +
    + +
    +
    8.20.’06. 4:18am.
    + +

    天邊一朵雲 The Wayward Cloud—苦無歸處的乾渴慾望

    + +
    +天邊一朵雲 The Wayward Cloud
    +

    天邊一朵雲 The Wayward Cloud

    +
    + +
      +
    • 片名:天邊一朵雲
    • +
    • 英文片名: The Wayward Cloud
    • +
    • 發行年份: 2005
    • +
    • 製作公司: Arena Films
    • +
    • 導演:蔡明亮
    • +
    • 演員: +
        +
      • 李康生
      • +
      • 陳湘琪
      • +
      • 夜桜すもも(夜櫻李子)
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    終於看了天邊一朵雲了。真的很好看。說看不懂,大概是看電影的資歷還短,又或者只習慣看商業片吧。

    + +

    片中的象徵符號很豐富,西瓜、水、鑰匙…西瓜就像慾望,又比慾望豐富、有趣,可以大口大口地吃,可以解渴,也會破裂。因為停水所以乾渴,然而渴的不只水,還有慾望。男主角的慾望乾渴了,工作上看似勇猛的性慾,在現實中卻再也提不起興緻;女主角渴望享受性愛,但怎麼挑逗,男主角還是沒有反應。人的情感和慾望,就像天邊的一朵雲,就算有了愛情,也還是寂寞,還是沒有歸處,還是無根地飄浮在空中。(這是我最後聽到片尾曲才弄懂的。)

    + +

    電影有一個很有趣的構圖是:一個畫面從中間分開,兩邊分隔成兩個空間,兩個空間在中間連起來。兩邊的人彼此看不見對方,各自有各自的行動,有各自的盤算和心機。就像男主角第一次去女主角家裏修皮箱,右邊在修皮箱,左邊在切西瓜,彼此又在偷看對方。作為觀眾,可以同時看到兩邊的情形。像這樣的鏡頭運用了很多次,非常有趣。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 50 | + 51 | + 52 | + 53 | + 54 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0053.html.en.html b/htdocs/imacat/me/diary/0053.html.en.html new file mode 120000 index 0000000..753f6c2 --- /dev/null +++ b/htdocs/imacat/me/diary/0053.html.en.html @@ -0,0 +1 @@ +0053.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0053.html.en.xhtml b/htdocs/imacat/me/diary/0053.html.en.xhtml new file mode 100644 index 0000000..9207503 --- /dev/null +++ b/htdocs/imacat/me/diary/0053.html.en.xhtml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 53 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 53

    + +
    + +
    + +
    +
    8.21.’06. 1:32am.
    + +

    Underworld: Evolution 決戰異世界:進化時代羅密歐與茱麗葉血腥暴力科幻動作版

    + +
    +Underworld: Evolution 決戰異世界:進化時代
    +

    Underworld: Evolution 決戰異世界:進化時代

    +
    + + + +

    延續前集的劇情,席琳和麥可殺了長老維多後,為求生存,希望找到最後的長老馬可士祈求原諒。但馬可士早已洞悉一切,不介意他們殺了維多。但馬可士有自己的野心,而野心之鑰又落在席琳身上。終究,席琳和麥可還是逃不了變成獵物的命運。在逃竄撕殺中,更多的真相一一浮現。

    + +

    比第一集更暴力更血腥,更多斷肢殘塊飛來飛去。超乎想像的超強力量獸人,隨手不停撕裂人類和其它同類的軀體。如果心臟不夠好,不習慣恐怖片或暴力的電腦遊戲,可能不要看比較好。

    + +

    可是,撇開高度暴力血腥的畫面不談:動作畫面流暢,特效張力十足。不論是更細緻的變身過程,前集未出現的吸血鬼變身,都更勝前集。都市老舊公寓、廢棄鐵工場、荒廢的古堡,處處充滿頹廢的場景,為中世紀式的史詩背景作出最完美的詮釋。吸血鬼和狼人的傳說原本就很血腥。然而,要將這樣的血腥傳說,以現代的科學角度詮釋,拍得具有強大的說服力,成為兼具歷史感與科學感的史詩,就相當高竿了。

    + +

    凱特貝琴薩在片中飾演的席琳,讓人驚豔。許多人一再談論劇中性感的全裸床戲。但我覺得床戲裸不裸,就專業的演員而言,也沒什麼,反而是我們這些在意的人比較奇怪。比較引我注意的是她的眼神:從頭到尾,席琳充滿殺氣的肅殺眼神,似乎被她多看一眼就會被殺掉,讓人打從心底發起寒顫。雖然這一部份可以歸功於後製作,一部份可以歸功於新的瞳膜變色鏡片科技,但從頭到尾的肅殺眼神,全身散發出的騰騰殺氣,我還是很少看得到,非常引人注意。光這一點,就讓我對她的演技刮目相看。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 51 | + 52 | + 53 | + 54 | + 55 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0053.html.zh-cn.html b/htdocs/imacat/me/diary/0053.html.zh-cn.html new file mode 120000 index 0000000..f9cd75e --- /dev/null +++ b/htdocs/imacat/me/diary/0053.html.zh-cn.html @@ -0,0 +1 @@ +0053.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0053.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0053.html.zh-cn.xhtml new file mode 100644 index 0000000..25c8caa --- /dev/null +++ b/htdocs/imacat/me/diary/0053.html.zh-cn.xhtml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷五十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷五十三

    + +
    + +
    + +
    +
    8.21.’06. 1:32am.
    + +

    Underworld: Evolution 决战异世界:进化时代罗密欧与茱丽叶血腥暴力科幻动作版

    + +
    +Underworld: Evolution 决战异世界:进化时代
    +

    Underworld: Evolution 决战异世界:进化时代

    +
    + + + +

    延续前集的剧情,席琳和麦可杀了长老维多后,为求生存,希望找到最后的长老马可士祈求原谅。但马可士早已洞悉一切,不介意他们杀了维多。但马可士有自己的野心,而野心之钥又落在席琳身上。终究,席琳和麦可还是逃不了变成猎物的命运。在逃窜撕杀中,更多的真相一一浮现。

    + +

    比第一集更暴力更血腥,更多断肢残块飞来飞去。超乎想像的超强力量兽人,随手不停撕裂人类和其它同类的躯体。如果心脏不够好,不习惯恐怖片或暴力的电脑游戏,可能不要看比较好。

    + +

    可是,撇开高度暴力血腥的画面不谈:动作画面流畅,特效张力十足。不论是更细致的变身过程,前集未出现的吸血鬼变身,都更胜前集。都市老旧公寓、废弃铁工场、荒废的古堡,处处充满颓废的场景,为中世纪式的史诗背景作出最完美的诠释。吸血鬼和狼人的传说原本就很血腥。然而,要将这样的血腥传说,以现代的科学角度诠释,拍得具有强大的说服力,成为兼具历史感与科学感的史诗,就相当高竿了。

    + +

    凯特贝琴萨在片中饰演的席琳,让人惊艳。许多人一再谈论剧中性感的全裸床戏。但我觉得床戏裸不裸,就专业的演员而言,也没什么,反而是我们这些在意的人比较奇怪。比较引我注意的是她的眼神:从头到尾,席琳充满杀气的肃杀眼神,似乎被她多看一眼就会被杀掉,让人打从心底发起寒颤。虽然这一部份可以归功於后制作,一部份可以归功於新的瞳膜变色镜片科技,但从头到尾的肃杀眼神,全身散发出的腾腾杀气,我还是很少看得到,非常引人注意。光这一点,就让我对她的演技刮目相看。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 51 | + 52 | + 53 | + 54 | + 55 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0053.html.zh-tw.html b/htdocs/imacat/me/diary/0053.html.zh-tw.html new file mode 120000 index 0000000..6ac70f3 --- /dev/null +++ b/htdocs/imacat/me/diary/0053.html.zh-tw.html @@ -0,0 +1 @@ +0053.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0053.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0053.html.zh-tw.xhtml new file mode 100644 index 0000000..a11b480 --- /dev/null +++ b/htdocs/imacat/me/diary/0053.html.zh-tw.xhtml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷五十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷五十三

    + +
    + +
    + +
    +
    8.21.’06. 1:32am.
    + +

    Underworld: Evolution 決戰異世界:進化時代羅密歐與茱麗葉血腥暴力科幻動作版

    + +
    +Underworld: Evolution 決戰異世界:進化時代
    +

    Underworld: Evolution 決戰異世界:進化時代

    +
    + + + +

    延續前集的劇情,席琳和麥可殺了長老維多後,為求生存,希望找到最後的長老馬可士祈求原諒。但馬可士早已洞悉一切,不介意他們殺了維多。但馬可士有自己的野心,而野心之鑰又落在席琳身上。終究,席琳和麥可還是逃不了變成獵物的命運。在逃竄撕殺中,更多的真相一一浮現。

    + +

    比第一集更暴力更血腥,更多斷肢殘塊飛來飛去。超乎想像的超強力量獸人,隨手不停撕裂人類和其它同類的軀體。如果心臟不夠好,不習慣恐怖片或暴力的電腦遊戲,可能不要看比較好。

    + +

    可是,撇開高度暴力血腥的畫面不談:動作畫面流暢,特效張力十足。不論是更細緻的變身過程,前集未出現的吸血鬼變身,都更勝前集。都市老舊公寓、廢棄鐵工場、荒廢的古堡,處處充滿頹廢的場景,為中世紀式的史詩背景作出最完美的詮釋。吸血鬼和狼人的傳說原本就很血腥。然而,要將這樣的血腥傳說,以現代的科學角度詮釋,拍得具有強大的說服力,成為兼具歷史感與科學感的史詩,就相當高竿了。

    + +

    凱特貝琴薩在片中飾演的席琳,讓人驚豔。許多人一再談論劇中性感的全裸床戲。但我覺得床戲裸不裸,就專業的演員而言,也沒什麼,反而是我們這些在意的人比較奇怪。比較引我注意的是她的眼神:從頭到尾,席琳充滿殺氣的肅殺眼神,似乎被她多看一眼就會被殺掉,讓人打從心底發起寒顫。雖然這一部份可以歸功於後製作,一部份可以歸功於新的瞳膜變色鏡片科技,但從頭到尾的肅殺眼神,全身散發出的騰騰殺氣,我還是很少看得到,非常引人注意。光這一點,就讓我對她的演技刮目相看。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 51 | + 52 | + 53 | + 54 | + 55 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0054.html.en.html b/htdocs/imacat/me/diary/0054.html.en.html new file mode 120000 index 0000000..03183ed --- /dev/null +++ b/htdocs/imacat/me/diary/0054.html.en.html @@ -0,0 +1 @@ +0054.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0054.html.en.xhtml b/htdocs/imacat/me/diary/0054.html.en.xhtml new file mode 100644 index 0000000..6627d63 --- /dev/null +++ b/htdocs/imacat/me/diary/0054.html.en.xhtml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 54 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 54

    + +
    + +
    + +
    +
    8.21.’06. 4:20am.
    + +

    下妻物語lorita 少女眼中的奇幻世界

    + +
    +下妻物語
    +

    下妻物語

    +
    + +
      +
    • 片名:下妻物語
    • +
    • 英譯片名: Kamikaze GirlsShimotsuma Monogatari
    • +
    • 發行年份: 2004
    • +
    • 製作公司:東宝映画
    • +
    • 導演:中島哲也
    • +
    • 原作:嶽本野ばら(嶽本野薔薇)下妻物語(小学館)
    • +
    • 演員: +
        +
      • 深田恭子:竜ヶ崎桃子(龍崎桃子)
      • +
      • 土屋アンナ(土屋安娜):白百合イチゴ(白百合草莓)
      • +
      +
    • +
    + +

    我因為追土屋アンナ的新聞,追到這一部好評不斷的電影。下妻物語真的很好看,很讓人感動。 lorita 夢幻少女竜ヶ崎桃子和飆車族白百合イチゴ,兩個個性完全相反的女生,卻發展出超乎想像的友情。在這個過程中,兩個人也各自逐漸改變、成長。

    + +

    導演中島哲也主要是拍攝廣告。他擅長超現實的表現方式。之前曾拍攝過一部非常暴笑的短片 Rolling Bomber Special ,由香取慎吾主演,曾經在SMAP×SMAP節目中放映。下妻物語整部影片由桃子第一人稱,敘述由她眼中看出的 lorita 世界,像漫畫一樣的超現實表現方式,非常滑稽,也非常有趣。

    + +

    深田恭子的演技讓人驚嘆!原本我看慣了她在富豪刑事中,和現實脫節的白癡富家女的形象,所以一直沒有強烈的感覺。直到片尾,她為了救朋友,個性大轉彎,瞬間全身散發出飆車女一樣的氣魄,讓人折服。難怪深田恭子能以下妻物語登上影后,奪得第 26 回ヨコハマ映画祭(橫濱電影節)、第 59 回毎日映画コンクール(每日電影大獎)、第 14 回東スポ映画大賞(東京體育電影大獎)主演女優賞(最佳女主角),真是實至名歸。

    + +

    土屋アンナ的表現也很搶眼。模特兒出身的土屋アンナ,雖然是第一部電影,但是耍狠、耍無賴、對桃子死纏爛打,都讓人覺得非常可愛,演技很有說服力。她也以此片獲得26 回ヨコハマ映画祭(橫濱電影節)助演女優賞(最佳女配角)、第 29 回報知映画賞(報知電影獎)、第 78 回キネマ旬報ベストテン(電影半月刊十大排行)、第 59 回毎日映画コンクール(每日電影大獎)、第 47 回ブルーリボン賞(藍絲帶獎)、第 28 回日本アカデミー賞(日本學院獎)新人賞(新人獎)

    + +

    下妻物語中,イチゴ(草莓)所參加的飆車族舗爾威帝劉,應該是片仮名吧,但我看了很久,還是猜不出這是什麼意思。上網查才知道,舗爾威帝劉片仮名ポニーテール,英文是 ponytail馬尾辮子的意思。威風的飆車族隊名竟然取馬尾辮子這麼可愛的名字,可愛度不輸飆車女草莓,哈哈哈哈。

    + +

    最讓我感動的有兩幕:イチゴ為了陪心情不好的桃子說話,翹掉族隊的聚會,要接受私刑處罰時,對著族隊夥伴怒吼:桃子那樣不需要伙伴,一個人努力地生活著,比起你們這些要有同伴才敢飆車,哭哭啼啼的傢伙強得太多了!觀眾這時才和剛趕到的桃子一起發現,雖然イチゴ常常惹桃子很生氣,但原來心底這麼崇拜桃子自以為是的生活態度。

    + +

    另一幕也是最後的地方:桃子發現イチゴ既然一開始就知道妃魅姬傳說是假的,那為什麼還硬拉她去找傳說中妃魅姬為男朋友繡字的的刺繡店?イチゴ才不好意思地說,那只是想找桃子去逛街的藉口。這一幕真是超感動的~ *^_^*

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 52 | + 53 | + 54 | + 55 | + 56 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0054.html.zh-cn.html b/htdocs/imacat/me/diary/0054.html.zh-cn.html new file mode 120000 index 0000000..1143054 --- /dev/null +++ b/htdocs/imacat/me/diary/0054.html.zh-cn.html @@ -0,0 +1 @@ +0054.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0054.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0054.html.zh-cn.xhtml new file mode 100644 index 0000000..abf1c9d --- /dev/null +++ b/htdocs/imacat/me/diary/0054.html.zh-cn.xhtml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷五十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷五十四

    + +
    + +
    + +
    +
    8.21.’06. 4:20am.
    + +

    下妻物语lorita 少女眼中的奇幻世界

    + +
    +下妻物语
    +

    下妻物语

    +
    + +
      +
    • 片名:下妻物语
    • +
    • 英译片名: Kamikaze GirlsShimotsuma Monogatari
    • +
    • 发行年份: 2004
    • +
    • 制作公司:东宝映画
    • +
    • 导演:中岛哲也
    • +
    • 原作:岳本野ばら(岳本野蔷薇)下妻物语(小学馆)
    • +
    • 演员: +
        +
      • 深田恭子:竜ヶ崎桃子(龙崎桃子)
      • +
      • 土屋アンナ(土屋安娜):白百合イチゴ(白百合草莓)
      • +
      +
    • +
    + +

    我因为追土屋アンナ的新闻,追到这一部好评不断的电影。下妻物语真的很好看,很让人感动。 lorita 梦幻少女竜ヶ崎桃子和飙车族白百合イチゴ,两个个性完全相反的女生,却发展出超乎想像的友情。在这个过程中,两个人也各自逐渐改变、成长。

    + +

    导演中岛哲也主要是拍摄广告。他擅长超现实的表现方式。之前曾拍摄过一部非常暴笑的短片 Rolling Bomber Special ,由香取慎吾主演,曾经在SMAP×SMAP节目中放映。下妻物语整部影片由桃子第一人称,叙述由她眼中看出的 lorita 世界,像漫画一样的超现实表现方式,非常滑稽,也非常有趣。

    + +

    深田恭子的演技让人惊叹!原本我看惯了她在富豪刑事中,和现实脱节的白痴富家女的形象,所以一直没有强烈的感觉。直到片尾,她为了救朋友,个性大转弯,瞬间全身散发出飙车女一样的气魄,让人折服。难怪深田恭子能以下妻物语登上影后,夺得第 26 回ヨコハマ映画祭(横滨电影节)、第 59 回毎日映画コンクール(每日电影大奖)、第 14 回东スポ映画大赏(东京体育电影大奖)主演女优赏(最佳女主角),真是实至名归。

    + +

    土屋アンナ的表现也很抢眼。模特儿出身的土屋アンナ,虽然是第一部电影,但是耍狠、耍无赖、对桃子死缠烂打,都让人觉得非常可爱,演技很有说服力。她也以此片获得26 回ヨコハマ映画祭(横滨电影节)助演女优赏(最佳女配角)、第 29 回报知映画赏(报知电影奖)、第 78 回キネマ旬报ベストテン(电影半月刊十大排行)、第 59 回毎日映画コンクール(每日电影大奖)、第 47 回ブルーリボン赏(蓝丝带奖)、第 28 回日本アカデミー赏(日本学院奖)新人赏(新人奖)

    + +

    下妻物语中,イチゴ(草莓)所参加的飙车族舗尔威帝刘,应该是片仮名吧,但我看了很久,还是猜不出这是什么意思。上网查才知道,舗尔威帝刘片仮名ポニーテール,英文是 ponytail马尾辫子的意思。威风的飙车族队名竟然取马尾辫子这么可爱的名字,可爱度不输飙车女草莓,哈哈哈哈。

    + +

    最让我感动的有两幕:イチゴ为了陪心情不好的桃子说话,翘掉族队的聚会,要接受私刑处罚时,对著族队伙伴怒吼:桃子那样不需要伙伴,一个人努力地生活著,比起你们这些要有同伴才敢飙车,哭哭啼啼的家伙强得太多了!观众这时才和刚赶到的桃子一起发现,虽然イチゴ常常惹桃子很生气,但原来心底这么崇拜桃子自以为是的生活态度。

    + +

    另一幕也是最后的地方:桃子发现イチゴ既然一开始就知道妃魅姬传说是假的,那为什么还硬拉她去找传说中妃魅姬为男朋友绣字的的刺绣店?イチゴ才不好意思地说,那只是想找桃子去逛街的藉口。这一幕真是超感动的~ *^_^*

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 52 | + 53 | + 54 | + 55 | + 56 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0054.html.zh-tw.html b/htdocs/imacat/me/diary/0054.html.zh-tw.html new file mode 120000 index 0000000..1beeb2d --- /dev/null +++ b/htdocs/imacat/me/diary/0054.html.zh-tw.html @@ -0,0 +1 @@ +0054.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0054.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0054.html.zh-tw.xhtml new file mode 100644 index 0000000..1059ade --- /dev/null +++ b/htdocs/imacat/me/diary/0054.html.zh-tw.xhtml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷五十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷五十四

    + +
    + +
    + +
    +
    8.21.’06. 4:20am.
    + +

    下妻物語lorita 少女眼中的奇幻世界

    + +
    +下妻物語
    +

    下妻物語

    +
    + +
      +
    • 片名:下妻物語
    • +
    • 英譯片名: Kamikaze GirlsShimotsuma Monogatari
    • +
    • 發行年份: 2004
    • +
    • 製作公司:東宝映画
    • +
    • 導演:中島哲也
    • +
    • 原作:嶽本野ばら(嶽本野薔薇)下妻物語(小学館)
    • +
    • 演員: +
        +
      • 深田恭子:竜ヶ崎桃子(龍崎桃子)
      • +
      • 土屋アンナ(土屋安娜):白百合イチゴ(白百合草莓)
      • +
      +
    • +
    + +

    我因為追土屋アンナ的新聞,追到這一部好評不斷的電影。下妻物語真的很好看,很讓人感動。 lorita 夢幻少女竜ヶ崎桃子和飆車族白百合イチゴ,兩個個性完全相反的女生,卻發展出超乎想像的友情。在這個過程中,兩個人也各自逐漸改變、成長。

    + +

    導演中島哲也主要是拍攝廣告。他擅長超現實的表現方式。之前曾拍攝過一部非常暴笑的短片 Rolling Bomber Special ,由香取慎吾主演,曾經在SMAP×SMAP節目中放映。下妻物語整部影片由桃子第一人稱,敘述由她眼中看出的 lorita 世界,像漫畫一樣的超現實表現方式,非常滑稽,也非常有趣。

    + +

    深田恭子的演技讓人驚嘆!原本我看慣了她在富豪刑事中,和現實脫節的白癡富家女的形象,所以一直沒有強烈的感覺。直到片尾,她為了救朋友,個性大轉彎,瞬間全身散發出飆車女一樣的氣魄,讓人折服。難怪深田恭子能以下妻物語登上影后,奪得第 26 回ヨコハマ映画祭(橫濱電影節)、第 59 回毎日映画コンクール(每日電影大獎)、第 14 回東スポ映画大賞(東京體育電影大獎)主演女優賞(最佳女主角),真是實至名歸。

    + +

    土屋アンナ的表現也很搶眼。模特兒出身的土屋アンナ,雖然是第一部電影,但是耍狠、耍無賴、對桃子死纏爛打,都讓人覺得非常可愛,演技很有說服力。她也以此片獲得26 回ヨコハマ映画祭(橫濱電影節)助演女優賞(最佳女配角)、第 29 回報知映画賞(報知電影獎)、第 78 回キネマ旬報ベストテン(電影半月刊十大排行)、第 59 回毎日映画コンクール(每日電影大獎)、第 47 回ブルーリボン賞(藍絲帶獎)、第 28 回日本アカデミー賞(日本學院獎)新人賞(新人獎)

    + +

    下妻物語中,イチゴ(草莓)所參加的飆車族舗爾威帝劉,應該是片仮名吧,但我看了很久,還是猜不出這是什麼意思。上網查才知道,舗爾威帝劉片仮名ポニーテール,英文是 ponytail馬尾辮子的意思。威風的飆車族隊名竟然取馬尾辮子這麼可愛的名字,可愛度不輸飆車女草莓,哈哈哈哈。

    + +

    最讓我感動的有兩幕:イチゴ為了陪心情不好的桃子說話,翹掉族隊的聚會,要接受私刑處罰時,對著族隊夥伴怒吼:桃子那樣不需要伙伴,一個人努力地生活著,比起你們這些要有同伴才敢飆車,哭哭啼啼的傢伙強得太多了!觀眾這時才和剛趕到的桃子一起發現,雖然イチゴ常常惹桃子很生氣,但原來心底這麼崇拜桃子自以為是的生活態度。

    + +

    另一幕也是最後的地方:桃子發現イチゴ既然一開始就知道妃魅姬傳說是假的,那為什麼還硬拉她去找傳說中妃魅姬為男朋友繡字的的刺繡店?イチゴ才不好意思地說,那只是想找桃子去逛街的藉口。這一幕真是超感動的~ *^_^*

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 52 | + 53 | + 54 | + 55 | + 56 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0055.html.en.html b/htdocs/imacat/me/diary/0055.html.en.html new file mode 120000 index 0000000..33fe6e2 --- /dev/null +++ b/htdocs/imacat/me/diary/0055.html.en.html @@ -0,0 +1 @@ +0055.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0055.html.en.xhtml b/htdocs/imacat/me/diary/0055.html.en.xhtml new file mode 100644 index 0000000..895c69d --- /dev/null +++ b/htdocs/imacat/me/diary/0055.html.en.xhtml @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 55 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 55

    + +
    + +
    + +
    +
    8.22.’06. 5:10am.
    + +

    暗花—古龍小說現代黑社會版

    + +
    +暗花
    +

    暗花

    +
    + +
      +
    • 片名:暗花
    • +
    • 英文片名: The Longest Nite
    • +
    • 台灣上映片名:暗花之殺人條件
    • +
    • 發行年份: 1997
    • +
    • 製作公司:銀河映像公司
    • +
    • 導演:游達志
    • +
    • 編劇:司徒錦源、游乃海
    • +
    • 演員: +
        +
      • 梁朝偉:警探阿深
      • +
      • 劉青雲:殺手耀東
      • +
      • 邵美琪:殺手阿鳳
      • +
      • 方剛:基哥
      • +
      • 龍方:佐治
      • +
      • 鄭浩南:基哥之子阿榮
      • +
      • 盧海鵬:佐治的酒店店長大聲公
      • +
      • 王天林:祥叔
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    暗花很好看。廣東話裏的暗花指來路不明的賞金,英文片名 The Longest Nite 則是最長的一夜。所有一個半小時的故事都在一夜裏發生。澳門最大的兩大幫派要談和,這時突然出現一筆號稱基哥拿五百萬要殺佐治的不明暗花。警探阿深受背後靠山基哥所託,在清晨四點雙方見面前,盡力排除所有被假暗花引來的殺手,保護雙方談和,卻不知前面還有一場場死亡的陷阱。

    + +

    整個劇情非常緊湊。一個夜晚,表面單純的任務,背後的疑問卻一個一個浮現上來,疑問的解答又帶來更多疑問。的確很像古龍的小說,從頭到尾拼命在動腦推理,跟時間賽跑,一局後有一局。而也跟古龍小說一樣,某些陷阱不大合邏輯,太過詭蹫,成局所賴偶然性太高了。耀東手袋裏一直裝著基哥人頭,那表示耀東出場前,也就是基哥和阿深見面後,就被幹掉了。以阿深和基哥之間關係這麼深,如果這之間阿深打了一通電話回去,不就破局了嗎?又或是有一場耀東被臨檢攔下,阿深踢飛耀東手袋後把他趕跑,事後耀東再想辦法回來拿手袋。這是在人來人往的大街上。如果手袋被流浪漢、小偷撿走了呢?如果阿深把手袋撿回來呢?如果阿深不放心,多看一眼手袋的內容呢?殺手的手袋中就算沒有人頭,應該也有槍,以阿深那麼精明,在這麼緊繃的時刻,怎麼可能對那個手袋看都不看,就這樣回去?只要阿深撿回手袋,多看一眼,死局就破了。最重要的是,如果洪先生真的這麼神通廣大,除了幾個主角外,都是他的人,那幹嘛大費周章設這麼詭蹫又破綻很多的局?直接拿回老大位置就好了。簡直像是為設局而設局一樣。

    + +

    不過,如果覺得古龍小說還不錯看的話,那暗花其實也還不錯啦~ ^_*'

    + +
    + +
    + +
    +
    8.22.’06. 1:52am.
    + +

    記日記是一件很累人的事

    + +

    記日記是一件很累人的事。

    + +

    我以前從來沒有這樣想過,因為我以前記日記沒有記得這麼勤,把想到的事通通都記下來。每天胡思亂想的事,日積月累下來成千上萬,實際記上的不到百分之一。

    + +

    最近,我把每件想到的大小瑣事,通通都記下來。雖然能夠把自己所想所感,不論大小,留下記錄,是很好的事,可是我還是發現很累。光是記這些,就耗費了我好多時間精力。畢竟沒有責任地天馬行空胡思亂想,是一點都不費工夫的事。但是要記下來就不一樣了。

    + +

    嗯。怎麼辦呢?

    + +
    + +
    + +
    +
    8.22.’06. 1:31am.
    + +

    徐錦江

    + +

    一直覺得徐錦江是一個很特別的人。

    + +

    其實原本,我並沒有很注意他。因為他總是演配角。不過一個個子高大的傢伙,頂著一頭光頭,粗魯的演技,還是讓人印象深刻。直到有一次,看報紙報導,徐錦江戲下其實是個個性很好,內向害羞,而且非常愛老婆的人。我感覺非常震憾。印象中徐錦江的演技,總是很粗魯。而且他拍很多三級片,戲裏沒有曹查理的淫踐下流,可是粗猛好色的樣子,深入人心。徐錦江的形象,怎麼樣,都讓人沒有辦法跟內向害羞四個字連在一起。

    + +

    之後,我的眼界變得更寬廣了。看到演技外放的演員,總是不免會去想,他私下是不是反而是個內向害羞的人?看到人家演技內歛,不免多想他私下是不是多話外向?看到人家嚴肅正直,不免多想戲下是不是惡形惡狀?看到人家惡形惡狀,不免多想人家戲下是不是善良可親?看到人家清純可愛,不免多想戲下是不是縱慾放浪?看到人家美豔誘人,不免多想戲下是不是保守難近?

    + +

    戲裏戲外的人生,可以有多大的距離?每次在有線電影台上看到徐錦江,我都忍不住這樣想。

    + +
    + +
    + +
    +
    8.22.’06. 0:59am.
    + +

    Rolling Bomber Special

    + +
    我是誰?
    + +

    下載了中島哲也的暴笑短片 Rolling Bomber Special ,反覆看了幾次,除了不住的笑外,突然有很深的感覺。

    + +

    …但是就算不曉得自己是誰 只要有音樂一樣能跳舞 只要有遊戲機就能玩遊戲 只要有行動電話 就能聊上好幾個小時 能吃到吉野家的大碗牛肉蓋飯 就覺得很幸福了 若真有新型炸彈 可能真會毀滅地球也說不定

    + +

    我是誰?一個老掉牙的哲學問題,怎麼也想不到看這部短片越多遍,越有很深的感覺。我到底是誰?有音樂就能跳舞,有遊戲機就能玩遊戲,有電腦就能寫程式,有網站就能寫日記。聲音好聽就能唱歌,會畫圖就能當畫家,手指靈巧就能彈鋼琴,身體柔軟就能跳舞。這就是我嗎?有新型炸彈,說不定我也會毀滅地球。那我是大魔王嗎?

    + +

    如果說,人是由其行動決定的,那麼我只要有好的嗓子就能上電視唱歌,所以我是歌星嗎?只要畫圖畫得好就能開畫展,所以我是畫家嗎?利用環境、才能去發揮,拿身邊的工具去使用,也不過是每個人都會做的事。這就是我嗎?那麼我跟別人,有什麼分別?說不定我真的是大魔王,真的會毀滅地球呢!

    + +

    我,到底是誰?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 53 | + 54 | + 55 | + 56 | + 57 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0055.html.zh-cn.html b/htdocs/imacat/me/diary/0055.html.zh-cn.html new file mode 120000 index 0000000..044b012 --- /dev/null +++ b/htdocs/imacat/me/diary/0055.html.zh-cn.html @@ -0,0 +1 @@ +0055.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0055.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0055.html.zh-cn.xhtml new file mode 100644 index 0000000..bebe770 --- /dev/null +++ b/htdocs/imacat/me/diary/0055.html.zh-cn.xhtml @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷五十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷五十五

    + +
    + +
    + +
    +
    8.22.’06. 5:10am.
    + +

    暗花—古龙小说现代黑社会版

    + +
    +暗花
    +

    暗花

    +
    + +
      +
    • 片名:暗花
    • +
    • 英文片名: The Longest Nite
    • +
    • 台湾上映片名:暗花之杀人条件
    • +
    • 发行年份: 1997
    • +
    • 制作公司:银河映像公司
    • +
    • 导演:游达志
    • +
    • 编剧:司徒锦源、游乃海
    • +
    • 演员: +
        +
      • 梁朝伟:警探阿深
      • +
      • 刘青云:杀手耀东
      • +
      • 邵美琪:杀手阿凤
      • +
      • 方刚:基哥
      • +
      • 龙方:佐治
      • +
      • 郑浩南:基哥之子阿荣
      • +
      • 卢海鹏:佐治的酒店店长大声公
      • +
      • 王天林:祥叔
      • +
      +
    • +
    • 推荐影评: + +
    • +
    + +

    暗花很好看。广东话里的暗花指来路不明的赏金,英文片名 The Longest Nite 则是最长的一夜。所有一个半小时的故事都在一夜里发生。澳门最大的两大帮派要谈和,这时突然出现一笔号称基哥拿五百万要杀佐治的不明暗花。警探阿深受背后靠山基哥所托,在清晨四点双方见面前,尽力排除所有被假暗花引来的杀手,保护双方谈和,却不知前面还有一场场死亡的陷阱。

    + +

    整个剧情非常紧凑。一个夜晚,表面单纯的任务,背后的疑问却一个一个浮现上来,疑问的解答又带来更多疑问。的确很像古龙的小说,从头到尾拼命在动脑推理,跟时间赛跑,一局后有一局。而也跟古龙小说一样,某些陷阱不大合逻辑,太过诡蹫,成局所赖偶然性太高了。耀东手袋里一直装著基哥人头,那表示耀东出场前,也就是基哥和阿深见面后,就被干掉了。以阿深和基哥之间关系这么深,如果这之间阿深打了一通电话回去,不就破局了吗?又或是有一场耀东被临检拦下,阿深踢飞耀东手袋后把他赶跑,事后耀东再想办法回来拿手袋。这是在人来人往的大街上。如果手袋被流浪汉、小偷捡走了呢?如果阿深把手袋捡回来呢?如果阿深不放心,多看一眼手袋的内容呢?杀手的手袋中就算没有人头,应该也有枪,以阿深那么精明,在这么紧绷的时刻,怎么可能对那个手袋看都不看,就这样回去?只要阿深捡回手袋,多看一眼,死局就破了。最重要的是,如果洪先生真的这么神通广大,除了几个主角外,都是他的人,那干嘛大费周章设这么诡蹫又破绽很多的局?直接拿回老大位置就好了。简直像是为设局而设局一样。

    + +

    不过,如果觉得古龙小说还不错看的话,那暗花其实也还不错啦~ ^_*'

    + +
    + +
    + +
    +
    8.22.’06. 1:52am.
    + +

    记日记是一件很累人的事

    + +

    记日记是一件很累人的事。

    + +

    我以前从来没有这样想过,因为我以前记日记没有记得这么勤,把想到的事通通都记下来。每天胡思乱想的事,日积月累下来成千上万,实际记上的不到百分之一。

    + +

    最近,我把每件想到的大小琐事,通通都记下来。虽然能够把自己所想所感,不论大小,留下记录,是很好的事,可是我还是发现很累。光是记这些,就耗费了我好多时间精力。毕竟没有责任地天马行空胡思乱想,是一点都不费工夫的事。但是要记下来就不一样了。

    + +

    嗯。怎么办呢?

    + +
    + +
    + +
    +
    8.22.’06. 1:31am.
    + +

    徐锦江

    + +

    一直觉得徐锦江是一个很特别的人。

    + +

    其实原本,我并没有很注意他。因为他总是演配角。不过一个个子高大的家伙,顶著一头光头,粗鲁的演技,还是让人印象深刻。直到有一次,看报纸报导,徐锦江戏下其实是个个性很好,内向害羞,而且非常爱老婆的人。我感觉非常震憾。印象中徐锦江的演技,总是很粗鲁。而且他拍很多三级片,戏里没有曹查理的淫践下流,可是粗猛好色的样子,深入人心。徐锦江的形象,怎么样,都让人没有办法跟内向害羞四个字连在一起。

    + +

    之后,我的眼界变得更宽广了。看到演技外放的演员,总是不免会去想,他私下是不是反而是个内向害羞的人?看到人家演技内歛,不免多想他私下是不是多话外向?看到人家严肃正直,不免多想戏下是不是恶形恶状?看到人家恶形恶状,不免多想人家戏下是不是善良可亲?看到人家清纯可爱,不免多想戏下是不是纵欲放浪?看到人家美艳诱人,不免多想戏下是不是保守难近?

    + +

    戏里戏外的人生,可以有多大的距离?每次在有线电影台上看到徐锦江,我都忍不住这样想。

    + +
    + +
    + +
    +
    8.22.’06. 0:59am.
    + +

    Rolling Bomber Special

    + +
    我是谁?
    + +

    下载了中岛哲也的暴笑短片 Rolling Bomber Special ,反覆看了几次,除了不住的笑外,突然有很深的感觉。

    + +

    …但是就算不晓得自己是谁 只要有音乐一样能跳舞 只要有游戏机就能玩游戏 只要有行动电话 就能聊上好几个小时 能吃到吉野家的大碗牛肉盖饭 就觉得很幸福了 若真有新型炸弹 可能真会毁灭地球也说不定

    + +

    我是谁?一个老掉牙的哲学问题,怎么也想不到看这部短片越多遍,越有很深的感觉。我到底是谁?有音乐就能跳舞,有游戏机就能玩游戏,有电脑就能写程式,有网站就能写日记。声音好听就能唱歌,会画图就能当画家,手指灵巧就能弹钢琴,身体柔软就能跳舞。这就是我吗?有新型炸弹,说不定我也会毁灭地球。那我是大魔王吗?

    + +

    如果说,人是由其行动决定的,那么我只要有好的嗓子就能上电视唱歌,所以我是歌星吗?只要画图画得好就能开画展,所以我是画家吗?利用环境、才能去发挥,拿身边的工具去使用,也不过是每个人都会做的事。这就是我吗?那么我跟别人,有什么分别?说不定我真的是大魔王,真的会毁灭地球呢!

    + +

    我,到底是谁?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 53 | + 54 | + 55 | + 56 | + 57 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0055.html.zh-tw.html b/htdocs/imacat/me/diary/0055.html.zh-tw.html new file mode 120000 index 0000000..d99b294 --- /dev/null +++ b/htdocs/imacat/me/diary/0055.html.zh-tw.html @@ -0,0 +1 @@ +0055.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0055.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0055.html.zh-tw.xhtml new file mode 100644 index 0000000..b2825fc --- /dev/null +++ b/htdocs/imacat/me/diary/0055.html.zh-tw.xhtml @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷五十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷五十五

    + +
    + +
    + +
    +
    8.22.’06. 5:10am.
    + +

    暗花—古龍小說現代黑社會版

    + +
    +暗花
    +

    暗花

    +
    + +
      +
    • 片名:暗花
    • +
    • 英文片名: The Longest Nite
    • +
    • 台灣上映片名:暗花之殺人條件
    • +
    • 發行年份: 1997
    • +
    • 製作公司:銀河映像公司
    • +
    • 導演:游達志
    • +
    • 編劇:司徒錦源、游乃海
    • +
    • 演員: +
        +
      • 梁朝偉:警探阿深
      • +
      • 劉青雲:殺手耀東
      • +
      • 邵美琪:殺手阿鳳
      • +
      • 方剛:基哥
      • +
      • 龍方:佐治
      • +
      • 鄭浩南:基哥之子阿榮
      • +
      • 盧海鵬:佐治的酒店店長大聲公
      • +
      • 王天林:祥叔
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    暗花很好看。廣東話裏的暗花指來路不明的賞金,英文片名 The Longest Nite 則是最長的一夜。所有一個半小時的故事都在一夜裏發生。澳門最大的兩大幫派要談和,這時突然出現一筆號稱基哥拿五百萬要殺佐治的不明暗花。警探阿深受背後靠山基哥所託,在清晨四點雙方見面前,盡力排除所有被假暗花引來的殺手,保護雙方談和,卻不知前面還有一場場死亡的陷阱。

    + +

    整個劇情非常緊湊。一個夜晚,表面單純的任務,背後的疑問卻一個一個浮現上來,疑問的解答又帶來更多疑問。的確很像古龍的小說,從頭到尾拼命在動腦推理,跟時間賽跑,一局後有一局。而也跟古龍小說一樣,某些陷阱不大合邏輯,太過詭蹫,成局所賴偶然性太高了。耀東手袋裏一直裝著基哥人頭,那表示耀東出場前,也就是基哥和阿深見面後,就被幹掉了。以阿深和基哥之間關係這麼深,如果這之間阿深打了一通電話回去,不就破局了嗎?又或是有一場耀東被臨檢攔下,阿深踢飛耀東手袋後把他趕跑,事後耀東再想辦法回來拿手袋。這是在人來人往的大街上。如果手袋被流浪漢、小偷撿走了呢?如果阿深把手袋撿回來呢?如果阿深不放心,多看一眼手袋的內容呢?殺手的手袋中就算沒有人頭,應該也有槍,以阿深那麼精明,在這麼緊繃的時刻,怎麼可能對那個手袋看都不看,就這樣回去?只要阿深撿回手袋,多看一眼,死局就破了。最重要的是,如果洪先生真的這麼神通廣大,除了幾個主角外,都是他的人,那幹嘛大費周章設這麼詭蹫又破綻很多的局?直接拿回老大位置就好了。簡直像是為設局而設局一樣。

    + +

    不過,如果覺得古龍小說還不錯看的話,那暗花其實也還不錯啦~ ^_*'

    + +
    + +
    + +
    +
    8.22.’06. 1:52am.
    + +

    記日記是一件很累人的事

    + +

    記日記是一件很累人的事。

    + +

    我以前從來沒有這樣想過,因為我以前記日記沒有記得這麼勤,把想到的事通通都記下來。每天胡思亂想的事,日積月累下來成千上萬,實際記上的不到百分之一。

    + +

    最近,我把每件想到的大小瑣事,通通都記下來。雖然能夠把自己所想所感,不論大小,留下記錄,是很好的事,可是我還是發現很累。光是記這些,就耗費了我好多時間精力。畢竟沒有責任地天馬行空胡思亂想,是一點都不費工夫的事。但是要記下來就不一樣了。

    + +

    嗯。怎麼辦呢?

    + +
    + +
    + +
    +
    8.22.’06. 1:31am.
    + +

    徐錦江

    + +

    一直覺得徐錦江是一個很特別的人。

    + +

    其實原本,我並沒有很注意他。因為他總是演配角。不過一個個子高大的傢伙,頂著一頭光頭,粗魯的演技,還是讓人印象深刻。直到有一次,看報紙報導,徐錦江戲下其實是個個性很好,內向害羞,而且非常愛老婆的人。我感覺非常震憾。印象中徐錦江的演技,總是很粗魯。而且他拍很多三級片,戲裏沒有曹查理的淫踐下流,可是粗猛好色的樣子,深入人心。徐錦江的形象,怎麼樣,都讓人沒有辦法跟內向害羞四個字連在一起。

    + +

    之後,我的眼界變得更寬廣了。看到演技外放的演員,總是不免會去想,他私下是不是反而是個內向害羞的人?看到人家演技內歛,不免多想他私下是不是多話外向?看到人家嚴肅正直,不免多想戲下是不是惡形惡狀?看到人家惡形惡狀,不免多想人家戲下是不是善良可親?看到人家清純可愛,不免多想戲下是不是縱慾放浪?看到人家美豔誘人,不免多想戲下是不是保守難近?

    + +

    戲裏戲外的人生,可以有多大的距離?每次在有線電影台上看到徐錦江,我都忍不住這樣想。

    + +
    + +
    + +
    +
    8.22.’06. 0:59am.
    + +

    Rolling Bomber Special

    + +
    我是誰?
    + +

    下載了中島哲也的暴笑短片 Rolling Bomber Special ,反覆看了幾次,除了不住的笑外,突然有很深的感覺。

    + +

    …但是就算不曉得自己是誰 只要有音樂一樣能跳舞 只要有遊戲機就能玩遊戲 只要有行動電話 就能聊上好幾個小時 能吃到吉野家的大碗牛肉蓋飯 就覺得很幸福了 若真有新型炸彈 可能真會毀滅地球也說不定

    + +

    我是誰?一個老掉牙的哲學問題,怎麼也想不到看這部短片越多遍,越有很深的感覺。我到底是誰?有音樂就能跳舞,有遊戲機就能玩遊戲,有電腦就能寫程式,有網站就能寫日記。聲音好聽就能唱歌,會畫圖就能當畫家,手指靈巧就能彈鋼琴,身體柔軟就能跳舞。這就是我嗎?有新型炸彈,說不定我也會毀滅地球。那我是大魔王嗎?

    + +

    如果說,人是由其行動決定的,那麼我只要有好的嗓子就能上電視唱歌,所以我是歌星嗎?只要畫圖畫得好就能開畫展,所以我是畫家嗎?利用環境、才能去發揮,拿身邊的工具去使用,也不過是每個人都會做的事。這就是我嗎?那麼我跟別人,有什麼分別?說不定我真的是大魔王,真的會毀滅地球呢!

    + +

    我,到底是誰?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 53 | + 54 | + 55 | + 56 | + 57 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0056.html.en.html b/htdocs/imacat/me/diary/0056.html.en.html new file mode 120000 index 0000000..67ff72e --- /dev/null +++ b/htdocs/imacat/me/diary/0056.html.en.html @@ -0,0 +1 @@ +0056.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0056.html.en.xhtml b/htdocs/imacat/me/diary/0056.html.en.xhtml new file mode 100644 index 0000000..56f3042 --- /dev/null +++ b/htdocs/imacat/me/diary/0056.html.en.xhtml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 56 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 56

    + +
    + +
    + +
    +
    8.22.’06. 6:26pm.
    + +

    Veronica’s Veil 聖帕

    + +

    Veronica’s Veil 是基督宗教的傳說。聖經紀載,耶穌背負十字架的途中,聖婦勿洛尼加 Veronica 呈獻與耶穌拭面,耶穌受苦難的聖容就神奇地印在帕上。和杜林屍衣,同為瞭解耶穌長相的重要線索。

    + +

    有趣的故事。

    + +
    + +
    + +
    +
    8.22.’06. 1:52pm.
    + +

    浪子回頭、模特兒

    + +

    前一陣子讀到一則新聞:竹聯幫虎鳳隊隊長范媛媛,改行走模特兒。范媛媛是王蘭的乾女兒,西門町的大姊大。幾年前曾經教訓其它少女,把人家衣服脫光繞西門町一圈。算是個狠角色。

    + +

    既然要出道,不免又是歹路不可行奉勸青少女勿踏幫派路的公式。每個要漂白的幫派人物,都一定要講這句話,不管是不是真心話。更何況演藝圈以後就是公眾人物了,一言一行會成為人家的榜樣,一開始沒講清楚,誰還敢把工作交給你?雖然公式八股,但大家都在求生計,我也不會苛責。更何況,也不見得不是真心話。

    + +

    只是,如果所有的事情,都能夠有這樣事後的智慧,那人世間就美滿無缺了。像這種事後的智慧,在年少苦悶艱澀的時期,是不管用的。

    + +

    看幾張公開宣傳照,老實說,范媛媛身材和臉蛋都還不錯。不過,我曾經應徵商業雜誌編輯,看過幾本小經紀公司的模特兒名錄,像這樣的臉蛋和身材,說實話,整本相本塞得滿滿的。如果再考慮台北有多少家這樣的小經紀公司,那麼光靠漂亮的臉蛋和身材,一個月能接多少案子?相本上密密麻麻的模特兒,為了出道,有多少人還要辛苦靠超商打工養活自己,等待機緣呢?

    + +

    想想,這則新聞也是宣傳吧,看能不能利用以前的背景當話題,讓自己的名字給大家留下印象,在幾百個默默無名的少女中顯眼一點,多接幾個案子,混口飯吃。模特兒這一行,要能溫飽三餐,真的不容易。

    + +

    我把我的感想跟朋友說,朋友告訴我,那真是糟糕。黑道大姊走進模特兒圈,搞不好下個月一堆電視廣告就換人了,很多女生就要丟掉工作了。想想也是蠻有道理的。黑道的勢力,還是很可怕的。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 54 | + 55 | + 56 | + 57 | + 58 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0056.html.zh-cn.html b/htdocs/imacat/me/diary/0056.html.zh-cn.html new file mode 120000 index 0000000..203fdf8 --- /dev/null +++ b/htdocs/imacat/me/diary/0056.html.zh-cn.html @@ -0,0 +1 @@ +0056.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0056.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0056.html.zh-cn.xhtml new file mode 100644 index 0000000..1ac224f --- /dev/null +++ b/htdocs/imacat/me/diary/0056.html.zh-cn.xhtml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷五十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷五十六

    + +
    + +
    + +
    +
    8.22.’06. 6:26pm.
    + +

    Veronica’s Veil 圣帕

    + +

    Veronica’s Veil 是基督宗教的传说。圣经纪载,耶稣背负十字架的途中,圣妇勿洛尼加 Veronica 呈献与耶稣拭面,耶稣受苦难的圣容就神奇地印在帕上。和杜林尸衣,同为了解耶稣长相的重要线索。

    + +

    有趣的故事。

    + +
    + +
    + +
    +
    8.22.’06. 1:52pm.
    + +

    浪子回头、模特儿

    + +

    前一阵子读到一则新闻:竹联帮虎凤队队长范媛媛,改行走模特儿。范媛媛是王兰的干女儿,西门町的大姊大。几年前曾经教训其它少女,把人家衣服脱光绕西门町一圈。算是个狠角色。

    + +

    既然要出道,不免又是歹路不可行奉劝青少女勿踏帮派路的公式。每个要漂白的帮派人物,都一定要讲这句话,不管是不是真心话。更何况演艺圈以后就是公众人物了,一言一行会成为人家的榜样,一开始没讲清楚,谁还敢把工作交给你?虽然公式八股,但大家都在求生计,我也不会苛责。更何况,也不见得不是真心话。

    + +

    只是,如果所有的事情,都能够有这样事后的智慧,那人世间就美满无缺了。像这种事后的智慧,在年少苦闷艰涩的时期,是不管用的。

    + +

    看几张公开宣传照,老实说,范媛媛身材和脸蛋都还不错。不过,我曾经应徵商业杂志编辑,看过几本小经纪公司的模特儿名录,像这样的脸蛋和身材,说实话,整本相本塞得满满的。如果再考虑台北有多少家这样的小经纪公司,那么光靠漂亮的脸蛋和身材,一个月能接多少案子?相本上密密麻麻的模特儿,为了出道,有多少人还要辛苦靠超商打工养活自己,等待机缘呢?

    + +

    想想,这则新闻也是宣传吧,看能不能利用以前的背景当话题,让自己的名字给大家留下印象,在几百个默默无名的少女中显眼一点,多接几个案子,混口饭吃。模特儿这一行,要能温饱三餐,真的不容易。

    + +

    我把我的感想跟朋友说,朋友告诉我,那真是糟糕。黑道大姊走进模特儿圈,搞不好下个月一堆电视广告就换人了,很多女生就要丢掉工作了。想想也是蛮有道理的。黑道的势力,还是很可怕的。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 54 | + 55 | + 56 | + 57 | + 58 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0056.html.zh-tw.html b/htdocs/imacat/me/diary/0056.html.zh-tw.html new file mode 120000 index 0000000..1d365ed --- /dev/null +++ b/htdocs/imacat/me/diary/0056.html.zh-tw.html @@ -0,0 +1 @@ +0056.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0056.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0056.html.zh-tw.xhtml new file mode 100644 index 0000000..d665053 --- /dev/null +++ b/htdocs/imacat/me/diary/0056.html.zh-tw.xhtml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷五十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷五十六

    + +
    + +
    + +
    +
    8.22.’06. 6:26pm.
    + +

    Veronica’s Veil 聖帕

    + +

    Veronica’s Veil 是基督宗教的傳說。聖經紀載,耶穌背負十字架的途中,聖婦勿洛尼加 Veronica 呈獻與耶穌拭面,耶穌受苦難的聖容就神奇地印在帕上。和杜林屍衣,同為瞭解耶穌長相的重要線索。

    + +

    有趣的故事。

    + +
    + +
    + +
    +
    8.22.’06. 1:52pm.
    + +

    浪子回頭、模特兒

    + +

    前一陣子讀到一則新聞:竹聯幫虎鳳隊隊長范媛媛,改行走模特兒。范媛媛是王蘭的乾女兒,西門町的大姊大。幾年前曾經教訓其它少女,把人家衣服脫光繞西門町一圈。算是個狠角色。

    + +

    既然要出道,不免又是歹路不可行奉勸青少女勿踏幫派路的公式。每個要漂白的幫派人物,都一定要講這句話,不管是不是真心話。更何況演藝圈以後就是公眾人物了,一言一行會成為人家的榜樣,一開始沒講清楚,誰還敢把工作交給你?雖然公式八股,但大家都在求生計,我也不會苛責。更何況,也不見得不是真心話。

    + +

    只是,如果所有的事情,都能夠有這樣事後的智慧,那人世間就美滿無缺了。像這種事後的智慧,在年少苦悶艱澀的時期,是不管用的。

    + +

    看幾張公開宣傳照,老實說,范媛媛身材和臉蛋都還不錯。不過,我曾經應徵商業雜誌編輯,看過幾本小經紀公司的模特兒名錄,像這樣的臉蛋和身材,說實話,整本相本塞得滿滿的。如果再考慮台北有多少家這樣的小經紀公司,那麼光靠漂亮的臉蛋和身材,一個月能接多少案子?相本上密密麻麻的模特兒,為了出道,有多少人還要辛苦靠超商打工養活自己,等待機緣呢?

    + +

    想想,這則新聞也是宣傳吧,看能不能利用以前的背景當話題,讓自己的名字給大家留下印象,在幾百個默默無名的少女中顯眼一點,多接幾個案子,混口飯吃。模特兒這一行,要能溫飽三餐,真的不容易。

    + +

    我把我的感想跟朋友說,朋友告訴我,那真是糟糕。黑道大姊走進模特兒圈,搞不好下個月一堆電視廣告就換人了,很多女生就要丟掉工作了。想想也是蠻有道理的。黑道的勢力,還是很可怕的。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 54 | + 55 | + 56 | + 57 | + 58 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0057.html.en.html b/htdocs/imacat/me/diary/0057.html.en.html new file mode 120000 index 0000000..db859a9 --- /dev/null +++ b/htdocs/imacat/me/diary/0057.html.en.html @@ -0,0 +1 @@ +0057.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0057.html.en.xhtml b/htdocs/imacat/me/diary/0057.html.en.xhtml new file mode 100644 index 0000000..eed38f8 --- /dev/null +++ b/htdocs/imacat/me/diary/0057.html.en.xhtml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 57 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 57

    + +
    + +
    + +
    +
    8.23.’06. 0:24am.
    + +

    鎗火鎗火無眼,人間有情

    + +
    +鎗火
    +

    鎗火

    +
    + +
      +
    • 片名:鎗火
    • +
    • 英文片名: The Mission
    • +
    • 發行年份: 1999
    • +
    • 製作公司:銀河映像公司
    • +
    • 導演:杜琪峰
    • +
    • 導演:游乃海
    • +
    • 演員: +
        +
      • 黃秋生:阿鬼
      • +
      • 吳鎮宇:阿來
      • +
      • 呂頌賢:阿信
      • +
      • 張耀揚:阿 Mike
      • +
      • 林雪:阿肥
      • +
      • 佐藤佳次:殺手頭子
      • +
      • 高雄:文哥
      • +
      • 任達華:南哥
      • +
      • 王天林:肥祥
      • +
      • 施綺蓮:文嫂
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    鎗火真的很好看。大哥文哥遭到狙擊,其弟阿南為保護其兄,找了五個最頂尖的高手做大哥保鏢:阿鬼多年跟隨文哥,早年外號鬼見愁,狠辣老練,退隱後當髮型設計師;阿肥是槍械專家,退隱後流連在遊樂場;阿來是新興角頭老大,比阿鬼低一輩,但行事幹練;阿信是阿來最得力的小弟,年輕精明敢衝;阿 Mike 是神槍手,神準勇猛,平日是泊車小弟。各有背景、輩份亦不等的五個人,從互不認識,一起出生入死,建立起兄弟之情。可是背後,還有一個更大的危機,等著他們。

    + +

    鎗火不似暗花,賣弄無聊的兄弟背叛和詭局。五個人的任務是當保鑣,面對不知何時會出現在何處的敵人。劇情的張力,充斥在這個不知何時何處的緊張感中,隨時隨地都可能爆發的槍戰,眼觀四面、耳聽八方,神經永遠繃在最緊的地方。所以偶一處在比較安全的地方,像是回到大哥家裏,或是在辦公室,精神鬆弛下來,就開始拿身邊的東西,耍無聊的遊戲。像香煙塞火柴作弄人,或是辦公室紙團當球踢。然而一旦回復工作狀態,又立即恢復眼觀四面、耳聽八方的的緊張感,充份表現出專業高手的風範,讓人覺得非常痛快。

    + +

    影片一開始,用輕快高昂、略帶滑稽的小喇吧,揭開序曲,讓人完全無法連結到,這是一部嚴素的黑幫電影。然而小喇吧的聲音一直迴盪耳際,同時一一帶出每個角色平日的生活時,展現了一種很強烈的對比感:滑稽的小喇吧帶出嚴肅的保鑣任務,頂尖高手隱身理髮師、泊車小弟,專業高手鬆懈下來在玩廢紙團。人生其實充滿這些有趣的對比,就像一開始阿肥從遊樂場出來,哼著歌,搖著身子走過大街小巷。

    + +

    鎗火的死亡場景,非常輕快隨意。肥祥正在吃意大利麵,拒絕去見文哥,開始訴說心中的不平,然後說自己唯一嗜好就是吃。阿南道別後,前腳踏出,手下掏出槍,碰碰兩聲就結束了。肥祥中槍後,還繼續吃了兩口才死去。五個人看著落網的殺手頭子,阿來無聊點煙,還問殺手要不要抽,殺手拿了一根,點了煙。又等了五分鐘,阿南來電說處理好了,阿鬼闔上手機,只說走了!拿出懷裏的槍,碰碰兩聲,就結束了,五人起身回去。文嫂出軌,像平常一樣帶上車後座,殺手從旁站出,碰碰兩聲就結束了。鎗火的死亡輕快隨意,就像生活中抽煙、吃意大利麵、搭車一樣。

    + +

    作為反派角色,佐藤佳次飾演的殺手頭子雖沒有幾句台詞,可是表現十分搶眼,讓人印象深刻。整部電影氣氛十分緊繃,不知道他何時會出現。戲份雖少,連名字都沒有,但存在感非常強烈。

    + +

    有一幕讓我印象很深:五個人組合後,第一個展現實力的,是為大家準備槍枝的阿肥。他邊哼著歌,邊熟練地調整每一支槍、清槍管,熟練靈敏令人咋舌。調整好發配下去,阿 Mike 一拿起槍,瞬間換上另一副專業面孔,反覆收放滑膛,體驗彈簧的力道,一直重複同一個動作,直到引起觀眾很強烈的印象,然後把槍放在阿肥桌上,簡單說一句:加兩磅。阿肥拾起槍,訝異地抬起頭來,重新打量這個之前還在陪笑遞煙、自己看不上眼的金髮小輩。這一幕兩人的對手戲,真是有趣極了。

    + +

    另一場很棒的是百貨公司的狙擊。在開放的中庭手扶梯上遭到狙擊後,眾人快速掩護文哥下手扶梯。然而手扶梯出口離大門還有一段距離。一下手扶梯,殿後的阿 Mike 一個人守住手扶梯,槍口對準梯頂,四個人各自找到位置防守,緊盯著負責的方位。這時候時間好像靜止了一樣,鏡頭也跟著不動了,空盪盪的樓層,只聽得到阿 Mike 間歇性的槍聲,可以感覺到有殺手一直試圖從手扶梯上攻下來。可是觀眾和其他四個人一樣,看不見阿 Mike 向誰開槍。即使如此,四個人還是動也不動,沒有人前去幫忙,亂了陣腳。間歇性槍聲靜止一段時間後,四個人才各自補位,掩護阿 Mike 撤退。這一場五個人展現出的高度協調性與一體感,隨眾人靜止的鏡頭,觀眾也融入五個人的一體感之中,讓人大呼過癮。

    + +

    吳鎮宇以鎗火贏得金馬獎影帝。他飾演的阿來原先是手腕高段的一方之主;被南哥叫去,在文哥面前變成唯唯諾諾、不見經傳的小輩;當了保鏢,從話事的老大變成火線上的槍手,當保鏢大多時候沒有動靜,自己地盤還常常有事急電,要他拿主意,角色錯亂又分身乏術,讓他非常煩燥;在巷弄被狙擊,槍聲稍歇時,他一個人往前衝,不見人影,阿鬼要眾人先行撤退,回來阿來氣得揪住輩份比他高的阿鬼就好幾巴掌;阿鬼為表歉意,私下幫他幹掉他地盤上的敵人,他知道後很感動,就只是一直遞煙,說謝謝;發現阿信搞上文嫂,他從找上阿鬼求情,發狠話一定要護著這個小弟,寄望能用空包彈騙過去,最後絕望地開空槍發洩。吳鎮宇在鎗火裏的表現,不斷地轉折,峰起雲湧,真的非常精彩。

    + +

    任達華客串的南哥也讓人印象深刻。南哥每次出現,都先聲奪人,或是邊大聲講手機邊開門,或是遠遠一開口就是明星的八卦,五分鐘的說話全都是不著邊際的閒磕牙,只有最後一句:明天,兩點,在公司。講到自己的目的。並存的強烈張弛感,刻意表現的親切,卻讓人無法拒絕。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 55 | + 56 | + 57 | + 58 | + 59 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0057.html.zh-cn.html b/htdocs/imacat/me/diary/0057.html.zh-cn.html new file mode 120000 index 0000000..5a76b06 --- /dev/null +++ b/htdocs/imacat/me/diary/0057.html.zh-cn.html @@ -0,0 +1 @@ +0057.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0057.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0057.html.zh-cn.xhtml new file mode 100644 index 0000000..9d109b8 --- /dev/null +++ b/htdocs/imacat/me/diary/0057.html.zh-cn.xhtml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷五十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷五十七

    + +
    + +
    + +
    +
    8.23.’06. 0:24am.
    + +

    枪火枪火无眼,人间有情

    + +
    +枪火
    +

    枪火

    +
    + +
      +
    • 片名:枪火
    • +
    • 英文片名: The Mission
    • +
    • 发行年份: 1999
    • +
    • 制作公司:银河映像公司
    • +
    • 导演:杜琪峰
    • +
    • 导演:游乃海
    • +
    • 演员: +
        +
      • 黄秋生:阿鬼
      • +
      • 吴镇宇:阿来
      • +
      • 吕颂贤:阿信
      • +
      • 张耀扬:阿 Mike
      • +
      • 林雪:阿肥
      • +
      • 佐藤佳次:杀手头子
      • +
      • 高雄:文哥
      • +
      • 任达华:南哥
      • +
      • 王天林:肥祥
      • +
      • 施绮莲:文嫂
      • +
      +
    • +
    • 推荐影评: + +
    • +
    + +

    枪火真的很好看。大哥文哥遭到狙击,其弟阿南为保护其兄,找了五个最顶尖的高手做大哥保镖:阿鬼多年跟随文哥,早年外号鬼见愁,狠辣老练,退隐后当发型设计师;阿肥是枪械专家,退隐后流连在游乐场;阿来是新兴角头老大,比阿鬼低一辈,但行事干练;阿信是阿来最得力的小弟,年轻精明敢冲;阿 Mike 是神枪手,神准勇猛,平日是泊车小弟。各有背景、辈份亦不等的五个人,从互不认识,一起出生入死,建立起兄弟之情。可是背后,还有一个更大的危机,等著他们。

    + +

    枪火不似暗花,卖弄无聊的兄弟背叛和诡局。五个人的任务是当保镳,面对不知何时会出现在何处的敌人。剧情的张力,充斥在这个不知何时何处的紧张感中,随时随地都可能爆发的枪战,眼观四面、耳听八方,神经永远绷在最紧的地方。所以偶一处在比较安全的地方,像是回到大哥家里,或是在办公室,精神松弛下来,就开始拿身边的东西,耍无聊的游戏。像香烟塞火柴作弄人,或是办公室纸团当球踢。然而一旦回复工作状态,又立即恢复眼观四面、耳听八方的的紧张感,充份表现出专业高手的风范,让人觉得非常痛快。

    + +

    影片一开始,用轻快高昂、略带滑稽的小喇吧,揭开序曲,让人完全无法连结到,这是一部严素的黑帮电影。然而小喇吧的声音一直回荡耳际,同时一一带出每个角色平日的生活时,展现了一种很强烈的对比感:滑稽的小喇吧带出严肃的保镳任务,顶尖高手隐身理发师、泊车小弟,专业高手松懈下来在玩废纸团。人生其实充满这些有趣的对比,就像一开始阿肥从游乐场出来,哼著歌,摇著身子走过大街小巷。

    + +

    枪火的死亡场景,非常轻快随意。肥祥正在吃意大利面,拒绝去见文哥,开始诉说心中的不平,然后说自己唯一嗜好就是吃。阿南道别后,前脚踏出,手下掏出枪,碰碰两声就结束了。肥祥中枪后,还继续吃了两口才死去。五个人看著落网的杀手头子,阿来无聊点烟,还问杀手要不要抽,杀手拿了一根,点了烟。又等了五分钟,阿南来电说处理好了,阿鬼阖上手机,只说走了!拿出怀里的枪,碰碰两声,就结束了,五人起身回去。文嫂出轨,像平常一样带上车后座,杀手从旁站出,碰碰两声就结束了。枪火的死亡轻快随意,就像生活中抽烟、吃意大利面、搭车一样。

    + +

    作为反派角色,佐藤佳次饰演的杀手头子虽没有几句台词,可是表现十分抢眼,让人印象深刻。整部电影气氛十分紧绷,不知道他何时会出现。戏份虽少,连名字都没有,但存在感非常强烈。

    + +

    有一幕让我印象很深:五个人组合后,第一个展现实力的,是为大家准备枪枝的阿肥。他边哼著歌,边熟练地调整每一支枪、清枪管,熟练灵敏令人咋舌。调整好发配下去,阿 Mike 一拿起枪,瞬间换上另一副专业面孔,反覆收放滑膛,体验弹簧的力道,一直重复同一个动作,直到引起观众很强烈的印象,然后把枪放在阿肥桌上,简单说一句:加两磅。阿肥拾起枪,讶异地抬起头来,重新打量这个之前还在陪笑递烟、自己看不上眼的金发小辈。这一幕两人的对手戏,真是有趣极了。

    + +

    另一场很棒的是百货公司的狙击。在开放的中庭手扶梯上遭到狙击后,众人快速掩护文哥下手扶梯。然而手扶梯出口离大门还有一段距离。一下手扶梯,殿后的阿 Mike 一个人守住手扶梯,枪口对准梯顶,四个人各自找到位置防守,紧盯著负责的方位。这时候时间好像静止了一样,镜头也跟著不动了,空荡荡的楼层,只听得到阿 Mike 间歇性的枪声,可以感觉到有杀手一直试图从手扶梯上攻下来。可是观众和其他四个人一样,看不见阿 Mike 向谁开枪。即使如此,四个人还是动也不动,没有人前去帮忙,乱了阵脚。间歇性枪声静止一段时间后,四个人才各自补位,掩护阿 Mike 撤退。这一场五个人展现出的高度协调性与一体感,随众人静止的镜头,观众也融入五个人的一体感之中,让人大呼过瘾。

    + +

    吴镇宇以枪火赢得金马奖影帝。他饰演的阿来原先是手腕高段的一方之主;被南哥叫去,在文哥面前变成唯唯诺诺、不见经传的小辈;当了保镖,从话事的老大变成火线上的枪手,当保镖大多时候没有动静,自己地盘还常常有事急电,要他拿主意,角色错乱又分身乏术,让他非常烦燥;在巷弄被狙击,枪声稍歇时,他一个人往前冲,不见人影,阿鬼要众人先行撤退,回来阿来气得揪住辈份比他高的阿鬼就好几巴掌;阿鬼为表歉意,私下帮他干掉他地盘上的敌人,他知道后很感动,就只是一直递烟,说谢谢;发现阿信搞上文嫂,他从找上阿鬼求情,发狠话一定要护著这个小弟,寄望能用空包弹骗过去,最后绝望地开空枪发泄。吴镇宇在枪火里的表现,不断地转折,峰起云涌,真的非常精彩。

    + +

    任达华客串的南哥也让人印象深刻。南哥每次出现,都先声夺人,或是边大声讲手机边开门,或是远远一开口就是明星的八卦,五分钟的说话全都是不著边际的闲磕牙,只有最后一句:明天,两点,在公司。讲到自己的目的。并存的强烈张弛感,刻意表现的亲切,却让人无法拒绝。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 55 | + 56 | + 57 | + 58 | + 59 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0057.html.zh-tw.html b/htdocs/imacat/me/diary/0057.html.zh-tw.html new file mode 120000 index 0000000..9a2e640 --- /dev/null +++ b/htdocs/imacat/me/diary/0057.html.zh-tw.html @@ -0,0 +1 @@ +0057.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0057.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0057.html.zh-tw.xhtml new file mode 100644 index 0000000..e2e6a38 --- /dev/null +++ b/htdocs/imacat/me/diary/0057.html.zh-tw.xhtml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷五十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷五十七

    + +
    + +
    + +
    +
    8.23.’06. 0:24am.
    + +

    鎗火鎗火無眼,人間有情

    + +
    +鎗火
    +

    鎗火

    +
    + +
      +
    • 片名:鎗火
    • +
    • 英文片名: The Mission
    • +
    • 發行年份: 1999
    • +
    • 製作公司:銀河映像公司
    • +
    • 導演:杜琪峰
    • +
    • 導演:游乃海
    • +
    • 演員: +
        +
      • 黃秋生:阿鬼
      • +
      • 吳鎮宇:阿來
      • +
      • 呂頌賢:阿信
      • +
      • 張耀揚:阿 Mike
      • +
      • 林雪:阿肥
      • +
      • 佐藤佳次:殺手頭子
      • +
      • 高雄:文哥
      • +
      • 任達華:南哥
      • +
      • 王天林:肥祥
      • +
      • 施綺蓮:文嫂
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    鎗火真的很好看。大哥文哥遭到狙擊,其弟阿南為保護其兄,找了五個最頂尖的高手做大哥保鏢:阿鬼多年跟隨文哥,早年外號鬼見愁,狠辣老練,退隱後當髮型設計師;阿肥是槍械專家,退隱後流連在遊樂場;阿來是新興角頭老大,比阿鬼低一輩,但行事幹練;阿信是阿來最得力的小弟,年輕精明敢衝;阿 Mike 是神槍手,神準勇猛,平日是泊車小弟。各有背景、輩份亦不等的五個人,從互不認識,一起出生入死,建立起兄弟之情。可是背後,還有一個更大的危機,等著他們。

    + +

    鎗火不似暗花,賣弄無聊的兄弟背叛和詭局。五個人的任務是當保鑣,面對不知何時會出現在何處的敵人。劇情的張力,充斥在這個不知何時何處的緊張感中,隨時隨地都可能爆發的槍戰,眼觀四面、耳聽八方,神經永遠繃在最緊的地方。所以偶一處在比較安全的地方,像是回到大哥家裏,或是在辦公室,精神鬆弛下來,就開始拿身邊的東西,耍無聊的遊戲。像香煙塞火柴作弄人,或是辦公室紙團當球踢。然而一旦回復工作狀態,又立即恢復眼觀四面、耳聽八方的的緊張感,充份表現出專業高手的風範,讓人覺得非常痛快。

    + +

    影片一開始,用輕快高昂、略帶滑稽的小喇吧,揭開序曲,讓人完全無法連結到,這是一部嚴素的黑幫電影。然而小喇吧的聲音一直迴盪耳際,同時一一帶出每個角色平日的生活時,展現了一種很強烈的對比感:滑稽的小喇吧帶出嚴肅的保鑣任務,頂尖高手隱身理髮師、泊車小弟,專業高手鬆懈下來在玩廢紙團。人生其實充滿這些有趣的對比,就像一開始阿肥從遊樂場出來,哼著歌,搖著身子走過大街小巷。

    + +

    鎗火的死亡場景,非常輕快隨意。肥祥正在吃意大利麵,拒絕去見文哥,開始訴說心中的不平,然後說自己唯一嗜好就是吃。阿南道別後,前腳踏出,手下掏出槍,碰碰兩聲就結束了。肥祥中槍後,還繼續吃了兩口才死去。五個人看著落網的殺手頭子,阿來無聊點煙,還問殺手要不要抽,殺手拿了一根,點了煙。又等了五分鐘,阿南來電說處理好了,阿鬼闔上手機,只說走了!拿出懷裏的槍,碰碰兩聲,就結束了,五人起身回去。文嫂出軌,像平常一樣帶上車後座,殺手從旁站出,碰碰兩聲就結束了。鎗火的死亡輕快隨意,就像生活中抽煙、吃意大利麵、搭車一樣。

    + +

    作為反派角色,佐藤佳次飾演的殺手頭子雖沒有幾句台詞,可是表現十分搶眼,讓人印象深刻。整部電影氣氛十分緊繃,不知道他何時會出現。戲份雖少,連名字都沒有,但存在感非常強烈。

    + +

    有一幕讓我印象很深:五個人組合後,第一個展現實力的,是為大家準備槍枝的阿肥。他邊哼著歌,邊熟練地調整每一支槍、清槍管,熟練靈敏令人咋舌。調整好發配下去,阿 Mike 一拿起槍,瞬間換上另一副專業面孔,反覆收放滑膛,體驗彈簧的力道,一直重複同一個動作,直到引起觀眾很強烈的印象,然後把槍放在阿肥桌上,簡單說一句:加兩磅。阿肥拾起槍,訝異地抬起頭來,重新打量這個之前還在陪笑遞煙、自己看不上眼的金髮小輩。這一幕兩人的對手戲,真是有趣極了。

    + +

    另一場很棒的是百貨公司的狙擊。在開放的中庭手扶梯上遭到狙擊後,眾人快速掩護文哥下手扶梯。然而手扶梯出口離大門還有一段距離。一下手扶梯,殿後的阿 Mike 一個人守住手扶梯,槍口對準梯頂,四個人各自找到位置防守,緊盯著負責的方位。這時候時間好像靜止了一樣,鏡頭也跟著不動了,空盪盪的樓層,只聽得到阿 Mike 間歇性的槍聲,可以感覺到有殺手一直試圖從手扶梯上攻下來。可是觀眾和其他四個人一樣,看不見阿 Mike 向誰開槍。即使如此,四個人還是動也不動,沒有人前去幫忙,亂了陣腳。間歇性槍聲靜止一段時間後,四個人才各自補位,掩護阿 Mike 撤退。這一場五個人展現出的高度協調性與一體感,隨眾人靜止的鏡頭,觀眾也融入五個人的一體感之中,讓人大呼過癮。

    + +

    吳鎮宇以鎗火贏得金馬獎影帝。他飾演的阿來原先是手腕高段的一方之主;被南哥叫去,在文哥面前變成唯唯諾諾、不見經傳的小輩;當了保鏢,從話事的老大變成火線上的槍手,當保鏢大多時候沒有動靜,自己地盤還常常有事急電,要他拿主意,角色錯亂又分身乏術,讓他非常煩燥;在巷弄被狙擊,槍聲稍歇時,他一個人往前衝,不見人影,阿鬼要眾人先行撤退,回來阿來氣得揪住輩份比他高的阿鬼就好幾巴掌;阿鬼為表歉意,私下幫他幹掉他地盤上的敵人,他知道後很感動,就只是一直遞煙,說謝謝;發現阿信搞上文嫂,他從找上阿鬼求情,發狠話一定要護著這個小弟,寄望能用空包彈騙過去,最後絕望地開空槍發洩。吳鎮宇在鎗火裏的表現,不斷地轉折,峰起雲湧,真的非常精彩。

    + +

    任達華客串的南哥也讓人印象深刻。南哥每次出現,都先聲奪人,或是邊大聲講手機邊開門,或是遠遠一開口就是明星的八卦,五分鐘的說話全都是不著邊際的閒磕牙,只有最後一句:明天,兩點,在公司。講到自己的目的。並存的強烈張弛感,刻意表現的親切,卻讓人無法拒絕。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 55 | + 56 | + 57 | + 58 | + 59 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0058.html.en.html b/htdocs/imacat/me/diary/0058.html.en.html new file mode 120000 index 0000000..84376fd --- /dev/null +++ b/htdocs/imacat/me/diary/0058.html.en.html @@ -0,0 +1 @@ +0058.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0058.html.en.xhtml b/htdocs/imacat/me/diary/0058.html.en.xhtml new file mode 100644 index 0000000..ae9a208 --- /dev/null +++ b/htdocs/imacat/me/diary/0058.html.en.xhtml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 58 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 58

    + +
    + +
    + +
    +
    8.23.’06. 3:56am.
    + +

    暗戰—時間沒了

    + +
    +暗戰
    +

    暗戰

    +
    + +
      +
    • 片名:暗戰
    • +
    • 英文片名: Running Out of Time
    • +
    • 台灣上映片名:談判專家
    • +
    • 發行年份: 1999
    • +
    • 製作公司:銀河映像公司
    • +
    • 出品人:向華強
    • +
    • 導演:杜琪峰
    • +
    • 編劇:游乃海、 Laurent CourtiaudJulien Carbon
    • +
    • 演員: +
        +
      • 劉德華:張彼德之子
      • +
      • 劉青雲:何尚生督察
      • +
      • 蒙嘉慧:梁婉婷
      • +
      • 許紹雄:黃啟法總督察
      • +
      • 黃卓玲:國際刑警主管
      • +
      • 李子雄:運輸公司老闆陳先生(光頭佬)
      • +
      • 林雪:陳先生的糊塗手下
      • +
      +
    • +
    + +

    暗戰蠻好看的。癌症末期的張,對由飛虎隊轉調文職,警隊最幹練的新任督察何尚生設了一個局,等待何督察一步步揭開真相。

    + +

    英文片名 Running Out of Time時間沒了,點出暗戰的主題:時間。一場限時 72 小時的遊戲,時間一到,不管你高不高興,不管身後還有幾百個警察、飛虎隊、總督察,遊戲就要結束,主角就要落幕退場了。主角退場後,人在哪裏,死在哪裏,已經是旁人無法干涉的事了。

    + +

    片尾為電影加上一點餘韻:何督察在公車上發現梁婉婷帶著項鍊,雖然還是不見主角,但至少知道主角遊戲落幕後,還是做了些什麼的一點點音訊。

    + +

    沒有血腥,從頭鬥智到尾,非常緊湊。一開始的一小段,引出背後的一個大段,符合香港標準商業警匪片格式。沒有血腥、過於暴力的場景,難怪可以在有線電影台播出。

    + +

    劉德華以暗戰拿到香港電影金像獎影帝。過往對劉德華的批評都在於他不會演戲,永遠只是偶像天王。但在暗戰中,他一下扮老生,一下扮女相,緊繃的嘴唇帶著淺笑,準備自己人生的最後一場大秀,邊忍痛邊算計,躲在監視器後偷笑何督察,一下嚴肅一下搞怪,偶爾忍不住突然吐血。收放自如,真的很精彩,很有感染力。

    + +

    劉青雲的演技實力原已備受肯定,在暗戰中和張兩人鬥智鬥力,表現得也非常精彩。蒙嘉慧很不顯眼,不大有女主角的架勢。不過戲份本就不多,應該只能算是女配角,不是女主角。暗戰應該算是兩個男主角,加一個女配角的電影。黃卓玲演的國際刑警主管,毫無存在感,讓人完全忘了她的存在。只有兩場戲,我回想了很久,才想起這個角色。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 56 | + 57 | + 58 | + 59 | + 60 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0058.html.zh-cn.html b/htdocs/imacat/me/diary/0058.html.zh-cn.html new file mode 120000 index 0000000..5df69f2 --- /dev/null +++ b/htdocs/imacat/me/diary/0058.html.zh-cn.html @@ -0,0 +1 @@ +0058.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0058.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0058.html.zh-cn.xhtml new file mode 100644 index 0000000..bf8e03a --- /dev/null +++ b/htdocs/imacat/me/diary/0058.html.zh-cn.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷五十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷五十八

    + +
    + +
    + +
    +
    8.23.’06. 3:56am.
    + +

    暗战—时间没了

    + +
    +暗战
    +

    暗战

    +
    + +
      +
    • 片名:暗战
    • +
    • 英文片名: Running Out of Time
    • +
    • 台湾上映片名:谈判专家
    • +
    • 发行年份: 1999
    • +
    • 制作公司:银河映像公司
    • +
    • 出品人:向华强
    • +
    • 导演:杜琪峰
    • +
    • 编剧:游乃海、 Laurent CourtiaudJulien Carbon
    • +
    • 演员: +
        +
      • 刘德华:张彼德之子
      • +
      • 刘青云:何尚生督察
      • +
      • 蒙嘉慧:梁婉婷
      • +
      • 许绍雄:黄启法总督察
      • +
      • 黄卓玲:国际刑警主管
      • +
      • 李子雄:运输公司老板陈先生(光头佬)
      • +
      • 林雪:陈先生的糊涂手下
      • +
      +
    • +
    + +

    暗战蛮好看的。癌症末期的张,对由飞虎队转调文职,警队最干练的新任督察何尚生设了一个局,等待何督察一步步揭开真相。

    + +

    英文片名 Running Out of Time时间没了,点出暗战的主题:时间。一场限时 72 小时的游戏,时间一到,不管你高不高兴,不管身后还有几百个警察、飞虎队、总督察,游戏就要结束,主角就要落幕退场了。主角退场后,人在哪里,死在哪里,已经是旁人无法干涉的事了。

    + +

    片尾为电影加上一点余韵:何督察在公车上发现梁婉婷带著项炼,虽然还是不见主角,但至少知道主角游戏落幕后,还是做了些什么的一点点音讯。

    + +

    没有血腥,从头斗智到尾,非常紧凑。一开始的一小段,引出背后的一个大段,符合香港标准商业警匪片格式。没有血腥、过於暴力的场景,难怪可以在有线电影台播出。

    + +

    刘德华以暗战拿到香港电影金像奖影帝。过往对刘德华的批评都在於他不会演戏,永远只是偶像天王。但在暗战中,他一下扮老生,一下扮女相,紧绷的嘴唇带著浅笑,准备自己人生的最后一场大秀,边忍痛边算计,躲在监视器后偷笑何督察,一下严肃一下搞怪,偶尔忍不住突然吐血。收放自如,真的很精彩,很有感染力。

    + +

    刘青云的演技实力原已备受肯定,在暗战中和张两人斗智斗力,表现得也非常精彩。蒙嘉慧很不显眼,不大有女主角的架势。不过戏份本就不多,应该只能算是女配角,不是女主角。暗战应该算是两个男主角,加一个女配角的电影。黄卓玲演的国际刑警主管,毫无存在感,让人完全忘了她的存在。只有两场戏,我回想了很久,才想起这个角色。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 56 | + 57 | + 58 | + 59 | + 60 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0058.html.zh-tw.html b/htdocs/imacat/me/diary/0058.html.zh-tw.html new file mode 120000 index 0000000..1cd93cf --- /dev/null +++ b/htdocs/imacat/me/diary/0058.html.zh-tw.html @@ -0,0 +1 @@ +0058.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0058.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0058.html.zh-tw.xhtml new file mode 100644 index 0000000..1786fc9 --- /dev/null +++ b/htdocs/imacat/me/diary/0058.html.zh-tw.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷五十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷五十八

    + +
    + +
    + +
    +
    8.23.’06. 3:56am.
    + +

    暗戰—時間沒了

    + +
    +暗戰
    +

    暗戰

    +
    + +
      +
    • 片名:暗戰
    • +
    • 英文片名: Running Out of Time
    • +
    • 台灣上映片名:談判專家
    • +
    • 發行年份: 1999
    • +
    • 製作公司:銀河映像公司
    • +
    • 出品人:向華強
    • +
    • 導演:杜琪峰
    • +
    • 編劇:游乃海、 Laurent CourtiaudJulien Carbon
    • +
    • 演員: +
        +
      • 劉德華:張彼德之子
      • +
      • 劉青雲:何尚生督察
      • +
      • 蒙嘉慧:梁婉婷
      • +
      • 許紹雄:黃啟法總督察
      • +
      • 黃卓玲:國際刑警主管
      • +
      • 李子雄:運輸公司老闆陳先生(光頭佬)
      • +
      • 林雪:陳先生的糊塗手下
      • +
      +
    • +
    + +

    暗戰蠻好看的。癌症末期的張,對由飛虎隊轉調文職,警隊最幹練的新任督察何尚生設了一個局,等待何督察一步步揭開真相。

    + +

    英文片名 Running Out of Time時間沒了,點出暗戰的主題:時間。一場限時 72 小時的遊戲,時間一到,不管你高不高興,不管身後還有幾百個警察、飛虎隊、總督察,遊戲就要結束,主角就要落幕退場了。主角退場後,人在哪裏,死在哪裏,已經是旁人無法干涉的事了。

    + +

    片尾為電影加上一點餘韻:何督察在公車上發現梁婉婷帶著項鍊,雖然還是不見主角,但至少知道主角遊戲落幕後,還是做了些什麼的一點點音訊。

    + +

    沒有血腥,從頭鬥智到尾,非常緊湊。一開始的一小段,引出背後的一個大段,符合香港標準商業警匪片格式。沒有血腥、過於暴力的場景,難怪可以在有線電影台播出。

    + +

    劉德華以暗戰拿到香港電影金像獎影帝。過往對劉德華的批評都在於他不會演戲,永遠只是偶像天王。但在暗戰中,他一下扮老生,一下扮女相,緊繃的嘴唇帶著淺笑,準備自己人生的最後一場大秀,邊忍痛邊算計,躲在監視器後偷笑何督察,一下嚴肅一下搞怪,偶爾忍不住突然吐血。收放自如,真的很精彩,很有感染力。

    + +

    劉青雲的演技實力原已備受肯定,在暗戰中和張兩人鬥智鬥力,表現得也非常精彩。蒙嘉慧很不顯眼,不大有女主角的架勢。不過戲份本就不多,應該只能算是女配角,不是女主角。暗戰應該算是兩個男主角,加一個女配角的電影。黃卓玲演的國際刑警主管,毫無存在感,讓人完全忘了她的存在。只有兩場戲,我回想了很久,才想起這個角色。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 56 | + 57 | + 58 | + 59 | + 60 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0059.html.en.html b/htdocs/imacat/me/diary/0059.html.en.html new file mode 120000 index 0000000..39931b4 --- /dev/null +++ b/htdocs/imacat/me/diary/0059.html.en.html @@ -0,0 +1 @@ +0059.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0059.html.en.xhtml b/htdocs/imacat/me/diary/0059.html.en.xhtml new file mode 100644 index 0000000..67d865f --- /dev/null +++ b/htdocs/imacat/me/diary/0059.html.en.xhtml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 59 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 59

    + +
    + +
    + +
    +
    8.24.’06. 1:06am.
    + +

    濠江風雲—一部自吹自擂的狂妄自傳

    + +
    +濠江風雲
    +

    濠江風雲

    +
    + +
      +
    • 片名:濠江風雲
    • +
    • 英文片名: Casino
    • +
    • 別名:駒哥傳、滴血追擊
    • +
    • 發行年份: 1998
    • +
    • 製作公司:天洪電影製作公司
    • +
    • 出品人:尹國駒
    • +
    • 導演: 鄧衍成
    • +
    • 演員: +
        +
      • 任達華:尹志巨
      • +
      • 郭可盈:記者方穎寧
      • +
      • 方中信:小廖
      • +
      • 鄭則仕:石歧杜警官
      • +
      • 陳惠敏:漁欄燦
      • +
      • 吳志雄:羅炳(嚤囉炳)
      • +
      • 蔡少芬:尹志巨妻
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +
    本片故事 純屬虛構 如有雷同 實屬巧合
    + +

    本片故事 純屬虛構 如有雷同 實屬巧合片尾這句註記,是這部片最大的諷刺。濠江風雲是澳門最大幫派 14K (也曾一度是全世界最大的幫派)老大,綽號崩牙駒的尹國駒,在最風光的時候,自掏腰包,拿一千四百萬港幣,請任達華演的自傳。濠江風雲的出品人,就是尹國駒本人。既然是自傳,裏面的情節,除了自吹自擂者外,大多都是真人真事。

    + +

    濠江風雲又名駒哥傳,上映不久即遭禁演。直到 2005 年,才又改以新名滴血追擊,重新發行 VCD 。網路上有些資料寫滴血追擊是任達華的 2005 新作,是錯誤的。這只是等崩牙駒下獄多年,罵聲稍歇後,舊片新裝,重新發行而已。

    + +

    因為有上述背景,濠江風雲是很特殊的一部電影。我是衝著這一點特殊性,才找來看的。

    + +

    故事敘述崩牙駒年輕時和小廖一起闖天下,打出名堂後,被當時澳門大哥漁欄燦延攬管賭場,制衡另一個的手下嚤囉炳。崩牙駒和嚤囉炳一直衝突,直到雙方全面開戰,崩牙駒把嚤囉炳打得落花流水。這時漁欄燦又拉攏嚤囉炳以制衡崩牙駒,賭場全交給嚤囉炳。崩牙駒反擊,鬧遍所有嚤囉炳的賭場,嚤囉炳生意一落千丈。片尾嚤囉炳全面潰敗,崩牙駒放他一馬,仁俠義風。但此時小廖絕症末期,妻子離去,英雄孤寂一生。

    + +

    一如所料,電影並不怎麼好看。濠江風雲透過一個女記者的專訪,回憶倒敘自己發跡的故事。內容大多都是崩牙駒自己自吹自擂,把自己講成英雄,對手都是狗雄,忠奸分明。加上一堆打打殺殺,砍來砍去。還有一堆事後諸葛,當時就知道誰是壞蛋、誰有問題。然而過份英雄化、美化黑社會,再加上滿場打打殺殺,暴力過頭,會被禁演是理所當然的事。

    + +

    某個程度上來說,也是可以接受。畢竟這是一個訪談的個人回憶錄,既是回憶,過度美化、自吹自擂、忠奸分明、事後諸葛,都是可以接受的。不過中後段夾著一段現在進行中的最後對決,還在自吹自擂,就無法自圓其說了。

    + +

    在網路上幾乎找不到濠江風雲滴血追擊的影評。想來這部電影,大多人都覺得不值一評吧。果真如此,我大概是第一個寫感想的。

    + +

    粵語嚤囉印度仔的意思,常用作別人的綽號。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 57 | + 58 | + 59 | + 60 | + 61 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0059.html.zh-cn.html b/htdocs/imacat/me/diary/0059.html.zh-cn.html new file mode 120000 index 0000000..122c256 --- /dev/null +++ b/htdocs/imacat/me/diary/0059.html.zh-cn.html @@ -0,0 +1 @@ +0059.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0059.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0059.html.zh-cn.xhtml new file mode 100644 index 0000000..8c4af69 --- /dev/null +++ b/htdocs/imacat/me/diary/0059.html.zh-cn.xhtml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷五十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷五十九

    + +
    + +
    + +
    +
    8.24.’06. 1:06am.
    + +

    濠江风云—一部自吹自擂的狂妄自传

    + +
    +濠江风云
    +

    濠江风云

    +
    + +
      +
    • 片名:濠江风云
    • +
    • 英文片名: Casino
    • +
    • 别名:驹哥传、滴血追击
    • +
    • 发行年份: 1998
    • +
    • 制作公司:天洪电影制作公司
    • +
    • 出品人:尹国驹
    • +
    • 导演: 邓衍成
    • +
    • 演员: +
        +
      • 任达华:尹志巨
      • +
      • 郭可盈:记者方颖宁
      • +
      • 方中信:小廖
      • +
      • 郑则仕:石歧杜警官
      • +
      • 陈惠敏:渔栏灿
      • +
      • 吴志雄:罗炳(嚤罗炳)
      • +
      • 蔡少芬:尹志巨妻
      • +
      +
    • +
    • 推荐影评: + +
    • +
    + +
    本片故事 纯属虚构 如有雷同 实属巧合
    + +

    本片故事 纯属虚构 如有雷同 实属巧合片尾这句注记,是这部片最大的讽刺。濠江风云是澳门最大帮派 14K (也曾一度是全世界最大的帮派)老大,绰号崩牙驹的尹国驹,在最风光的时候,自掏腰包,拿一千四百万港币,请任达华演的自传。濠江风云的出品人,就是尹国驹本人。既然是自传,里面的情节,除了自吹自擂者外,大多都是真人真事。

    + +

    濠江风云又名驹哥传,上映不久即遭禁演。直到 2005 年,才又改以新名滴血追击,重新发行 VCD 。网路上有些资料写滴血追击是任达华的 2005 新作,是错误的。这只是等崩牙驹下狱多年,骂声稍歇后,旧片新装,重新发行而已。

    + +

    因为有上述背景,濠江风云是很特殊的一部电影。我是冲著这一点特殊性,才找来看的。

    + +

    故事叙述崩牙驹年轻时和小廖一起闯天下,打出名堂后,被当时澳门大哥渔栏灿延揽管赌场,制衡另一个的手下嚤罗炳。崩牙驹和嚤罗炳一直冲突,直到双方全面开战,崩牙驹把嚤罗炳打得落花流水。这时渔栏灿又拉拢嚤罗炳以制衡崩牙驹,赌场全交给嚤罗炳。崩牙驹反击,闹遍所有嚤罗炳的赌场,嚤罗炳生意一落千丈。片尾嚤罗炳全面溃败,崩牙驹放他一马,仁侠义风。但此时小廖绝症末期,妻子离去,英雄孤寂一生。

    + +

    一如所料,电影并不怎么好看。濠江风云透过一个女记者的专访,回忆倒叙自己发迹的故事。内容大多都是崩牙驹自己自吹自擂,把自己讲成英雄,对手都是狗雄,忠奸分明。加上一堆打打杀杀,砍来砍去。还有一堆事后诸葛,当时就知道谁是坏蛋、谁有问题。然而过份英雄化、美化黑社会,再加上满场打打杀杀,暴力过头,会被禁演是理所当然的事。

    + +

    某个程度上来说,也是可以接受。毕竟这是一个访谈的个人回忆录,既是回忆,过度美化、自吹自擂、忠奸分明、事后诸葛,都是可以接受的。不过中后段夹著一段现在进行中的最后对决,还在自吹自擂,就无法自圆其说了。

    + +

    在网路上几乎找不到濠江风云滴血追击的影评。想来这部电影,大多人都觉得不值一评吧。果真如此,我大概是第一个写感想的。

    + +

    粤语嚤罗印度仔的意思,常用作别人的绰号。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 57 | + 58 | + 59 | + 60 | + 61 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0059.html.zh-tw.html b/htdocs/imacat/me/diary/0059.html.zh-tw.html new file mode 120000 index 0000000..6b7bef8 --- /dev/null +++ b/htdocs/imacat/me/diary/0059.html.zh-tw.html @@ -0,0 +1 @@ +0059.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0059.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0059.html.zh-tw.xhtml new file mode 100644 index 0000000..297284a --- /dev/null +++ b/htdocs/imacat/me/diary/0059.html.zh-tw.xhtml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷五十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷五十九

    + +
    + +
    + +
    +
    8.24.’06. 1:06am.
    + +

    濠江風雲—一部自吹自擂的狂妄自傳

    + +
    +濠江風雲
    +

    濠江風雲

    +
    + +
      +
    • 片名:濠江風雲
    • +
    • 英文片名: Casino
    • +
    • 別名:駒哥傳、滴血追擊
    • +
    • 發行年份: 1998
    • +
    • 製作公司:天洪電影製作公司
    • +
    • 出品人:尹國駒
    • +
    • 導演: 鄧衍成
    • +
    • 演員: +
        +
      • 任達華:尹志巨
      • +
      • 郭可盈:記者方穎寧
      • +
      • 方中信:小廖
      • +
      • 鄭則仕:石歧杜警官
      • +
      • 陳惠敏:漁欄燦
      • +
      • 吳志雄:羅炳(嚤囉炳)
      • +
      • 蔡少芬:尹志巨妻
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +
    本片故事 純屬虛構 如有雷同 實屬巧合
    + +

    本片故事 純屬虛構 如有雷同 實屬巧合片尾這句註記,是這部片最大的諷刺。濠江風雲是澳門最大幫派 14K (也曾一度是全世界最大的幫派)老大,綽號崩牙駒的尹國駒,在最風光的時候,自掏腰包,拿一千四百萬港幣,請任達華演的自傳。濠江風雲的出品人,就是尹國駒本人。既然是自傳,裏面的情節,除了自吹自擂者外,大多都是真人真事。

    + +

    濠江風雲又名駒哥傳,上映不久即遭禁演。直到 2005 年,才又改以新名滴血追擊,重新發行 VCD 。網路上有些資料寫滴血追擊是任達華的 2005 新作,是錯誤的。這只是等崩牙駒下獄多年,罵聲稍歇後,舊片新裝,重新發行而已。

    + +

    因為有上述背景,濠江風雲是很特殊的一部電影。我是衝著這一點特殊性,才找來看的。

    + +

    故事敘述崩牙駒年輕時和小廖一起闖天下,打出名堂後,被當時澳門大哥漁欄燦延攬管賭場,制衡另一個的手下嚤囉炳。崩牙駒和嚤囉炳一直衝突,直到雙方全面開戰,崩牙駒把嚤囉炳打得落花流水。這時漁欄燦又拉攏嚤囉炳以制衡崩牙駒,賭場全交給嚤囉炳。崩牙駒反擊,鬧遍所有嚤囉炳的賭場,嚤囉炳生意一落千丈。片尾嚤囉炳全面潰敗,崩牙駒放他一馬,仁俠義風。但此時小廖絕症末期,妻子離去,英雄孤寂一生。

    + +

    一如所料,電影並不怎麼好看。濠江風雲透過一個女記者的專訪,回憶倒敘自己發跡的故事。內容大多都是崩牙駒自己自吹自擂,把自己講成英雄,對手都是狗雄,忠奸分明。加上一堆打打殺殺,砍來砍去。還有一堆事後諸葛,當時就知道誰是壞蛋、誰有問題。然而過份英雄化、美化黑社會,再加上滿場打打殺殺,暴力過頭,會被禁演是理所當然的事。

    + +

    某個程度上來說,也是可以接受。畢竟這是一個訪談的個人回憶錄,既是回憶,過度美化、自吹自擂、忠奸分明、事後諸葛,都是可以接受的。不過中後段夾著一段現在進行中的最後對決,還在自吹自擂,就無法自圓其說了。

    + +

    在網路上幾乎找不到濠江風雲滴血追擊的影評。想來這部電影,大多人都覺得不值一評吧。果真如此,我大概是第一個寫感想的。

    + +

    粵語嚤囉印度仔的意思,常用作別人的綽號。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 57 | + 58 | + 59 | + 60 | + 61 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0060.html.en.html b/htdocs/imacat/me/diary/0060.html.en.html new file mode 120000 index 0000000..0dac102 --- /dev/null +++ b/htdocs/imacat/me/diary/0060.html.en.html @@ -0,0 +1 @@ +0060.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0060.html.en.xhtml b/htdocs/imacat/me/diary/0060.html.en.xhtml new file mode 100644 index 0000000..66c2a61 --- /dev/null +++ b/htdocs/imacat/me/diary/0060.html.en.xhtml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 60 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 60

    + +
    + +
    + +
    +
    8.24.’06. 4:38am.
    + +

    黑社會以和為貴—令人顫慄、不可逼視的

    + +
    +黑社會以和為貴
    +

    黑社會以和為貴

    +
    + +
      +
    • 片名:黑社會以和為貴
    • +
    • 英文片名: Election 2
    • +
    • 發行年份: 2006
    • +
    • 製作公司:銀河映像公司
    • +
    • 出品人:向華強
    • +
    • 導演:杜琪峰
    • +
    • 編劇:游乃海、葉天成
    • +
    • 演員: +
        +
      • 任達華:林懷樂(樂少)
      • +
      • 古天樂:李家源(吉米)
      • +
      • 張家輝:飛機
      • +
      • 林家棟:東莞仔
      • +
      • 林雪:大頭
      • +
      • 鄭浩南:號碼幫武哥
      • +
      • 王天林:鄧伯
      • +
      • 安志杰:鄭志力(阿力)
      • +
      +
    • +
    + +
    黑社會也有愛國的
    + +

    黑社會以和為貴很好看。延續黑社會的劇情,描述接下來兩年後話事人選舉,引發的新鬥爭。不過這次比上次更沉穩,更平靜。以和為貴!少數幾場殺人場景,都殺得很安靜,沒有震天的槍響,沒有漫天的火花,沒有殺人者壯膽的嘶吼,沒有被殺者痛苦的哀嚎,只有持續悠揚的小提琴。殺人不像動作片般,緊湊、隱喻地殺,而伴著無止盡的小提琴聲,緩慢地直接逼視整個殺人、裝袋、肢解的過程。黑社會裏東莞仔頭上插著刀,淋著白油漆和血,在敵人包圍中,像受傷野獸狂吼的場景不見了。取而代之的是,吉米找人把自己小弟阿力做掉時,打了兩下,丟下一句:來世小心做人阿力還在惶惑不定,就被綁起來套上膠帶,畫面緩慢地帶著眾人捆綁、裝袋、棄海的過程。樂少做掉鄧伯時,長長的旋轉樓梯,骨嚕骨嚕的聲音,從梯頂慢慢地滾下來,一層樓不夠,再滾一層。東莞仔和武哥對決時,只看到東莞仔和手下被鎖進武哥的貨櫃裏,好一段時間,貨櫃裏沉悶的刀砍聲若有似無,直到貨櫃開啟,勝利者染血走出。吉米肢解樂少手下時,對方已經奄奄一息了,吉米把他拖進別的房間,一刀一刀剁,鏡頭遠遠地跟,所有人沉默不語,只剩下剁刀聲,直到師爺蘇忍不住吐出來。樂少被做掉時,一槌一槌敲下,但車內的樂少眼中只剩下越跑越遠的兒子林致遠,其他什麼也看不到、聽不到了。緩慢的過程直視,令人難堪的沉默,比起槍火快速毫不經意的殺,更令人顫慄。

    + +

    以和為貴不是真的安穩,而是令人顫慄、不可逼視的強烈存在。影片不時強烈地透露這個訊息。吉米最後終於打通跟中國政府的關係,把生意做進中國廣大的市場,和政府、公安和平相處,以和為貴。最不想做和聯勝話事人、最不想一輩子打打殺殺的吉米,不僅要當一輩子和聯勝的話事人,還被賦與終結選舉制度的任務。和聯勝從今天起,就是你李家的了。字背後所蘊涵的恐怖存在,令吉米不禁顫慄得崩潰。然而就算崩潰,也還是逃不出它的掌控。

    + +

    謝謝合作!

    + +

    像這樣的道理,對比台灣的白色恐怖時期,感覺更是深刻。我們中小學時的教科書上,常常宣傳國民黨威權時期四十年的安定繁榮。然而安定不是真的安穩,而是不知道多少人就這樣消失、失蹤了。大家都知道發生了什麼事,可是沒有人能說。以和為貴。背後所蘊涵的恐怖存在,白色恐怖結束二十年後的現在,還是讓很多人顫慄不已。

    + +

    那麼,香港現時的安定呢?

    + +

    吉米肢解樂少手下,絞肉餵狗後,樂少其它手下嚇得五膽俱裂,終於屈服了。吉米請所有人吃火鍋,敬酒說:謝謝大家!但所有人眼中只看得見那些染血的鈔票。雙方終於講定了。以和為貴。

    + +

    的吉米貴了,上位了;的飛機呢?失去了樂少做靠山,所有以前打打殺殺結下的仇家都找上來了,淪落到日日夜夜在街上東奔西逃。以和為貴。

    + +

    黑社會也有愛國的。沒錯。即使你是黑社會,你也不能沒有國家。你還是要愛國,還是逃不出國家嚴密的掌控。國家無所不在,你無路可走。在黑社會中,眾人爭得你死我活的龍頭杖,到了黑社會以和為貴,卻只有驚鴻一撇,樂少從靈骨塔中拿出來,然後就消失了,沒有人再提起。正當片尾吉米當上話事人,所有人都忘了這根龍頭杖的存在時,龍頭杖又出現了,從石副廳長手中交給吉米。眾人這才恍然大悟,真正從頭到尾在背後操縱一切的,是國家:龍頭杖,是國家交給你的;選舉,是國家給你的試煉。你以為你可以有你自己的秩序,可以有你自己的選舉,其實都是表相的謊言。

    + +

    這,不就是香港今時今日的寫照嗎?片末,吉米把龍頭杖放入鄧伯棺木時,和聯勝的話事人選舉制,終於在這一代,隨著鄧伯的死而長眠。那香港的立法議員民主選舉,還能夠選多久?那香港五十年不變的特區法制,還能夠持續多久?

    + +

    黑社會以和為貴也不是沒有破綻。吉米把樂少手下剁碎,絞肉餵狗時,絞肉的顏色是粉紅色的。只有不帶血的肉才是粉紅色,像屠宰場放過血的豬肉。吉米找空屋空地隨便剁,不可能是放過血、不帶血的漂亮粉紅色。至少應該要找帶血豬肉來演才對。不過今時今日,除非找溫體豬肉屠宰場特別商量,否則很難找到未放血的豬肉了吧。我這樣講,大概很噁心吧。哈哈。 ^^; 形象全沒了。

    + +

    小慧 不要懷疑 解開所有的煩惱 成就心中蓮花開放 這才是最高智慧我覺得 我還是先回老家好一點這是黑社會以和為貴,最無俚頭的一句台詞。哇哈哈哈。這是大頭的女朋友小慧打電話來要離開,大頭對小慧說的話。不知道這是林雪即興耍的寶,還是杜琪峰的主意。

    + +

    古天樂穿上筆挺西裝,梳起西裝頭,收起不正經的笑臉,看起來很像鄭少秋。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 58 | + 59 | + 60 | + 61 | + 62 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0060.html.zh-cn.html b/htdocs/imacat/me/diary/0060.html.zh-cn.html new file mode 120000 index 0000000..7aa6947 --- /dev/null +++ b/htdocs/imacat/me/diary/0060.html.zh-cn.html @@ -0,0 +1 @@ +0060.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0060.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0060.html.zh-cn.xhtml new file mode 100644 index 0000000..ad93776 --- /dev/null +++ b/htdocs/imacat/me/diary/0060.html.zh-cn.xhtml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷六十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷六十

    + +
    + +
    + +
    +
    8.24.’06. 4:38am.
    + +

    黑社会以和为贵—令人颤栗、不可逼视的

    + +
    +黑社会以和为贵
    +

    黑社会以和为贵

    +
    + +
      +
    • 片名:黑社会以和为贵
    • +
    • 英文片名: Election 2
    • +
    • 发行年份: 2006
    • +
    • 制作公司:银河映像公司
    • +
    • 出品人:向华强
    • +
    • 导演:杜琪峰
    • +
    • 编剧:游乃海、叶天成
    • +
    • 演员: +
        +
      • 任达华:林怀乐(乐少)
      • +
      • 古天乐:李家源(吉米)
      • +
      • 张家辉:飞机
      • +
      • 林家栋:东莞仔
      • +
      • 林雪:大头
      • +
      • 郑浩南:号码帮武哥
      • +
      • 王天林:邓伯
      • +
      • 安志杰:郑志力(阿力)
      • +
      +
    • +
    + +
    黑社会也有爱国的
    + +

    黑社会以和为贵很好看。延续黑社会的剧情,描述接下来两年后话事人选举,引发的新斗争。不过这次比上次更沉稳,更平静。以和为贵!少数几场杀人场景,都杀得很安静,没有震天的枪响,没有漫天的火花,没有杀人者壮胆的嘶吼,没有被杀者痛苦的哀嚎,只有持续悠扬的小提琴。杀人不像动作片般,紧凑、隐喻地杀,而伴著无止尽的小提琴声,缓慢地直接逼视整个杀人、装袋、肢解的过程。黑社会里东莞仔头上插著刀,淋著白油漆和血,在敌人包围中,像受伤野兽狂吼的场景不见了。取而代之的是,吉米找人把自己小弟阿力做掉时,打了两下,丢下一句:来世小心做人阿力还在惶惑不定,就被绑起来套上胶带,画面缓慢地带著众人捆绑、装袋、弃海的过程。乐少做掉邓伯时,长长的旋转楼梯,骨噜骨噜的声音,从梯顶慢慢地滚下来,一层楼不够,再滚一层。东莞仔和武哥对决时,只看到东莞仔和手下被锁进武哥的货柜里,好一段时间,货柜里沉闷的刀砍声若有似无,直到货柜开启,胜利者染血走出。吉米肢解乐少手下时,对方已经奄奄一息了,吉米把他拖进别的房间,一刀一刀剁,镜头远远地跟,所有人沉默不语,只剩下剁刀声,直到师爷苏忍不住吐出来。乐少被做掉时,一槌一槌敲下,但车内的乐少眼中只剩下越跑越远的儿子林致远,其他什么也看不到、听不到了。缓慢的过程直视,令人难堪的沉默,比起枪火快速毫不经意的杀,更令人颤栗。

    + +

    以和为贵不是真的安稳,而是令人颤栗、不可逼视的强烈存在。影片不时强烈地透露这个讯息。吉米最后终於打通跟中国政府的关系,把生意做进中国广大的市场,和政府、公安和平相处,以和为贵。最不想做和联胜话事人、最不想一辈子打打杀杀的吉米,不仅要当一辈子和联胜的话事人,还被赋与终结选举制度的任务。和联胜从今天起,就是你李家的了。字背后所蕴涵的恐怖存在,令吉米不禁颤栗得崩溃。然而就算崩溃,也还是逃不出它的掌控。

    + +

    谢谢合作!

    + +

    像这样的道理,对比台湾的白色恐怖时期,感觉更是深刻。我们中小学时的教科书上,常常宣传国民党威权时期四十年的安定繁荣。然而安定不是真的安稳,而是不知道多少人就这样消失、失踪了。大家都知道发生了什么事,可是没有人能说。以和为贵。背后所蕴涵的恐怖存在,白色恐怖结束二十年后的现在,还是让很多人颤栗不已。

    + +

    那么,香港现时的安定呢?

    + +

    吉米肢解乐少手下,绞肉喂狗后,乐少其它手下吓得五胆俱裂,终於屈服了。吉米请所有人吃火锅,敬酒说:谢谢大家!但所有人眼中只看得见那些染血的钞票。双方终於讲定了。以和为贵。

    + +

    的吉米贵了,上位了;的飞机呢?失去了乐少做靠山,所有以前打打杀杀结下的仇家都找上来了,沦落到日日夜夜在街上东奔西逃。以和为贵。

    + +

    黑社会也有爱国的。没错。即使你是黑社会,你也不能没有国家。你还是要爱国,还是逃不出国家严密的掌控。国家无所不在,你无路可走。在黑社会中,众人争得你死我活的龙头杖,到了黑社会以和为贵,却只有惊鸿一撇,乐少从灵骨塔中拿出来,然后就消失了,没有人再提起。正当片尾吉米当上话事人,所有人都忘了这根龙头杖的存在时,龙头杖又出现了,从石副厅长手中交给吉米。众人这才恍然大悟,真正从头到尾在背后操纵一切的,是国家:龙头杖,是国家交给你的;选举,是国家给你的试炼。你以为你可以有你自己的秩序,可以有你自己的选举,其实都是表相的谎言。

    + +

    这,不就是香港今时今日的写照吗?片末,吉米把龙头杖放入邓伯棺木时,和联胜的话事人选举制,终於在这一代,随著邓伯的死而长眠。那香港的立法议员民主选举,还能够选多久?那香港五十年不变的特区法制,还能够持续多久?

    + +

    黑社会以和为贵也不是没有破绽。吉米把乐少手下剁碎,绞肉喂狗时,绞肉的颜色是粉红色的。只有不带血的肉才是粉红色,像屠宰场放过血的猪肉。吉米找空屋空地随便剁,不可能是放过血、不带血的漂亮粉红色。至少应该要找带血猪肉来演才对。不过今时今日,除非找温体猪肉屠宰场特别商量,否则很难找到未放血的猪肉了吧。我这样讲,大概很恶心吧。哈哈。 ^^; 形象全没了。

    + +

    小慧 不要怀疑 解开所有的烦恼 成就心中莲花开放 这才是最高智慧我觉得 我还是先回老家好一点这是黑社会以和为贵,最无俚头的一句台词。哇哈哈哈。这是大头的女朋友小慧打电话来要离开,大头对小慧说的话。不知道这是林雪即兴耍的宝,还是杜琪峰的主意。

    + +

    古天乐穿上笔挺西装,梳起西装头,收起不正经的笑脸,看起来很像郑少秋。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 58 | + 59 | + 60 | + 61 | + 62 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0060.html.zh-tw.html b/htdocs/imacat/me/diary/0060.html.zh-tw.html new file mode 120000 index 0000000..f92d33e --- /dev/null +++ b/htdocs/imacat/me/diary/0060.html.zh-tw.html @@ -0,0 +1 @@ +0060.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0060.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0060.html.zh-tw.xhtml new file mode 100644 index 0000000..8993668 --- /dev/null +++ b/htdocs/imacat/me/diary/0060.html.zh-tw.xhtml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷六十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷六十

    + +
    + +
    + +
    +
    8.24.’06. 4:38am.
    + +

    黑社會以和為貴—令人顫慄、不可逼視的

    + +
    +黑社會以和為貴
    +

    黑社會以和為貴

    +
    + +
      +
    • 片名:黑社會以和為貴
    • +
    • 英文片名: Election 2
    • +
    • 發行年份: 2006
    • +
    • 製作公司:銀河映像公司
    • +
    • 出品人:向華強
    • +
    • 導演:杜琪峰
    • +
    • 編劇:游乃海、葉天成
    • +
    • 演員: +
        +
      • 任達華:林懷樂(樂少)
      • +
      • 古天樂:李家源(吉米)
      • +
      • 張家輝:飛機
      • +
      • 林家棟:東莞仔
      • +
      • 林雪:大頭
      • +
      • 鄭浩南:號碼幫武哥
      • +
      • 王天林:鄧伯
      • +
      • 安志杰:鄭志力(阿力)
      • +
      +
    • +
    + +
    黑社會也有愛國的
    + +

    黑社會以和為貴很好看。延續黑社會的劇情,描述接下來兩年後話事人選舉,引發的新鬥爭。不過這次比上次更沉穩,更平靜。以和為貴!少數幾場殺人場景,都殺得很安靜,沒有震天的槍響,沒有漫天的火花,沒有殺人者壯膽的嘶吼,沒有被殺者痛苦的哀嚎,只有持續悠揚的小提琴。殺人不像動作片般,緊湊、隱喻地殺,而伴著無止盡的小提琴聲,緩慢地直接逼視整個殺人、裝袋、肢解的過程。黑社會裏東莞仔頭上插著刀,淋著白油漆和血,在敵人包圍中,像受傷野獸狂吼的場景不見了。取而代之的是,吉米找人把自己小弟阿力做掉時,打了兩下,丟下一句:來世小心做人阿力還在惶惑不定,就被綁起來套上膠帶,畫面緩慢地帶著眾人捆綁、裝袋、棄海的過程。樂少做掉鄧伯時,長長的旋轉樓梯,骨嚕骨嚕的聲音,從梯頂慢慢地滾下來,一層樓不夠,再滾一層。東莞仔和武哥對決時,只看到東莞仔和手下被鎖進武哥的貨櫃裏,好一段時間,貨櫃裏沉悶的刀砍聲若有似無,直到貨櫃開啟,勝利者染血走出。吉米肢解樂少手下時,對方已經奄奄一息了,吉米把他拖進別的房間,一刀一刀剁,鏡頭遠遠地跟,所有人沉默不語,只剩下剁刀聲,直到師爺蘇忍不住吐出來。樂少被做掉時,一槌一槌敲下,但車內的樂少眼中只剩下越跑越遠的兒子林致遠,其他什麼也看不到、聽不到了。緩慢的過程直視,令人難堪的沉默,比起槍火快速毫不經意的殺,更令人顫慄。

    + +

    以和為貴不是真的安穩,而是令人顫慄、不可逼視的強烈存在。影片不時強烈地透露這個訊息。吉米最後終於打通跟中國政府的關係,把生意做進中國廣大的市場,和政府、公安和平相處,以和為貴。最不想做和聯勝話事人、最不想一輩子打打殺殺的吉米,不僅要當一輩子和聯勝的話事人,還被賦與終結選舉制度的任務。和聯勝從今天起,就是你李家的了。字背後所蘊涵的恐怖存在,令吉米不禁顫慄得崩潰。然而就算崩潰,也還是逃不出它的掌控。

    + +

    謝謝合作!

    + +

    像這樣的道理,對比台灣的白色恐怖時期,感覺更是深刻。我們中小學時的教科書上,常常宣傳國民黨威權時期四十年的安定繁榮。然而安定不是真的安穩,而是不知道多少人就這樣消失、失蹤了。大家都知道發生了什麼事,可是沒有人能說。以和為貴。背後所蘊涵的恐怖存在,白色恐怖結束二十年後的現在,還是讓很多人顫慄不已。

    + +

    那麼,香港現時的安定呢?

    + +

    吉米肢解樂少手下,絞肉餵狗後,樂少其它手下嚇得五膽俱裂,終於屈服了。吉米請所有人吃火鍋,敬酒說:謝謝大家!但所有人眼中只看得見那些染血的鈔票。雙方終於講定了。以和為貴。

    + +

    的吉米貴了,上位了;的飛機呢?失去了樂少做靠山,所有以前打打殺殺結下的仇家都找上來了,淪落到日日夜夜在街上東奔西逃。以和為貴。

    + +

    黑社會也有愛國的。沒錯。即使你是黑社會,你也不能沒有國家。你還是要愛國,還是逃不出國家嚴密的掌控。國家無所不在,你無路可走。在黑社會中,眾人爭得你死我活的龍頭杖,到了黑社會以和為貴,卻只有驚鴻一撇,樂少從靈骨塔中拿出來,然後就消失了,沒有人再提起。正當片尾吉米當上話事人,所有人都忘了這根龍頭杖的存在時,龍頭杖又出現了,從石副廳長手中交給吉米。眾人這才恍然大悟,真正從頭到尾在背後操縱一切的,是國家:龍頭杖,是國家交給你的;選舉,是國家給你的試煉。你以為你可以有你自己的秩序,可以有你自己的選舉,其實都是表相的謊言。

    + +

    這,不就是香港今時今日的寫照嗎?片末,吉米把龍頭杖放入鄧伯棺木時,和聯勝的話事人選舉制,終於在這一代,隨著鄧伯的死而長眠。那香港的立法議員民主選舉,還能夠選多久?那香港五十年不變的特區法制,還能夠持續多久?

    + +

    黑社會以和為貴也不是沒有破綻。吉米把樂少手下剁碎,絞肉餵狗時,絞肉的顏色是粉紅色的。只有不帶血的肉才是粉紅色,像屠宰場放過血的豬肉。吉米找空屋空地隨便剁,不可能是放過血、不帶血的漂亮粉紅色。至少應該要找帶血豬肉來演才對。不過今時今日,除非找溫體豬肉屠宰場特別商量,否則很難找到未放血的豬肉了吧。我這樣講,大概很噁心吧。哈哈。 ^^; 形象全沒了。

    + +

    小慧 不要懷疑 解開所有的煩惱 成就心中蓮花開放 這才是最高智慧我覺得 我還是先回老家好一點這是黑社會以和為貴,最無俚頭的一句台詞。哇哈哈哈。這是大頭的女朋友小慧打電話來要離開,大頭對小慧說的話。不知道這是林雪即興耍的寶,還是杜琪峰的主意。

    + +

    古天樂穿上筆挺西裝,梳起西裝頭,收起不正經的笑臉,看起來很像鄭少秋。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 58 | + 59 | + 60 | + 61 | + 62 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0061.html.en.html b/htdocs/imacat/me/diary/0061.html.en.html new file mode 120000 index 0000000..3092857 --- /dev/null +++ b/htdocs/imacat/me/diary/0061.html.en.html @@ -0,0 +1 @@ +0061.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0061.html.en.xhtml b/htdocs/imacat/me/diary/0061.html.en.xhtml new file mode 100644 index 0000000..7780fd1 --- /dev/null +++ b/htdocs/imacat/me/diary/0061.html.en.xhtml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 61 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 61

    + +
    + +
    + +
    +
    8.25.’06. 1:50am.
    + +

    + +

    說實話,我不喜歡賭。

    + +

    這樣講好像在自我吹噓。不知道是不是處女座行事保守的關係,我不喜歡不確定性高的事,喜歡像機械一樣規律的事。例如賭,機率性高,就沒什麼興趣,像賭馬、百家樂、梭哈、樂透,甚至麻將、百貨公司抽獎,都沒有興趣。之前出國玩時,飯店二樓有個百家樂小賭檯,我從來沒見過,抱著增廣見識的心態走進去看看,沒幾分鐘無聊走出來了。前年去香港,酒店旁有賭馬站,我也抱著增廣見識的心態進去晃了晃,也是連一張馬票都沒買,就走出來了。至於整夜坐在四方桌打麻將,我無法理解。

    + +

    怎麼練習都無法越做越好的事,或是要靠運氣、氣勢這種虛幻事物的事,我很難有興趣。

    + +

    反過來說,確定性高、像機械一樣規律的事,例如寫電腦程式、玩電腦遊戲,我就很容易入迷。電腦遊戲有其機率性,但我知道多試幾次,一定會成功,還有很多種方法可以提高成功率,而且失敗我也沒有損失。寫電腦程式則是絕對確定規律的事,怎麼寫一定會怎麼跑,沒有照那樣跑就一定是我哪裏寫錯了。

    + +

    我真的就是不喜歡賭。可以說我沒有冒險心吧,可是就是沒有辦法。

    + +
    + +
    + +
    +
    8.24.’06. 11:41pm.
    + +

    恐怖片

    + +

    我原來不敢看恐怖片,也覺得沒必要看。

    + +

    第一次和人討論恐怖片,是國中時候有一個朋友,拉著我跟我說,他都把恐怖片當成喜劇看,看到斧頭砍下去,頭手斷掉,鮮血亂噴,就覺得好笑得不得了。我那時覺得很不可思議。就算不害怕,無論如何,有人被殺,都是很嚴肅的事。怎麼會好笑呢?

    + +

    第一次看恐怖片,是 1998 年的リング 七夜怪談 The Ring。那時七夜怪談佳評如潮,每天電視上都在講,又叫好又叫座。如果真是這麼好的電影,雖然會怕,還是不想放過。可是下定決心去看的時候,周圍敢看的朋友都看過了,剩下的朋友都不敢看。我只好一個人硬著頭皮進電影院。那時已經放映好幾個月,都快下片了,電影院裏人不多。我硬是壯著膽子,雙手緊緊抱胸把整部電影看完。看完以後完全心服口服,心裏只有一個字。可是恐怖的感覺,在接下來的三天,都揮之不去;接下來好幾個月,一看到電視機,就有莫名的恐懼。

    + +

    1999 年中,我去春暉電影台當影視編譯。時至七月,電視台要做鬼月專題,要趕譯好幾部鬼片。那幾部都是低成本廉價鬼片,血噴來噴去,假人頭整排飛出去,還在地上排成一排,可笑到不行。加上我為了校對,反覆倒轉、放慢動作、定格看,影片為求恐怖感特意安排的節奏全沒了,看到完全麻木。

    + +

    有了上面兩個經驗,我就好像對恐怖片免疫了。第一次看恐怖片就是看七夜怪談這種經典,此後任何恐怖片,我都不自覺拿來跟七夜怪談相比,看不上眼。七夜怪談不見血又不見鬼,卻給人直透心底的恐懼,意境極高;相比之下,血噴來噴去,頭手腳飛來飛去,層次就差一大截了。らせん 七夜怪談二—復活之路 The Spiral一開始就見血,大片血淹滿馬路。還有被解剖掏空內臟的屍體坐起來說話,身體是空的,那個畫面讓我頗震憾,有點新意,不過也沒什麼。

    + +

    對了,Scream 驚聲尖叫也不錯。最會灑狗血的好萊塢,久未出現沒有怪力亂神的恐怖片,還對當時恐怖片的標準公式做了一番嘲諷。後來就出現一種新的電影類型叫驚悚片,來指這種不算恐怖片,但還是很可怕的電影。Bride of Chucky 鬼娃新娘也讓我印象比較深,不過是我不喜歡的風格,把殺人兇手捧成英雄,雖然兩個邪惡洋娃娃蠻可愛的,不過我不會買回來擺家裏。我知道外面有在賣,電影看看可愛就好,當成家裏擺飾有點噁心。

    + +

    如果真有像七夜怪談一樣好的恐怖片,我一定會去看。只是我部部都拿去跟七夜怪談比,以七夜怪談為標準來衡量別的恐怖片,那大概沒有什麼能符合我的標準吧。可是就算重看七夜怪談,也不會有當年的恐怖感了,唉。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 59 | + 60 | + 61 | + 62 | + 63 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0061.html.zh-cn.html b/htdocs/imacat/me/diary/0061.html.zh-cn.html new file mode 120000 index 0000000..7f02327 --- /dev/null +++ b/htdocs/imacat/me/diary/0061.html.zh-cn.html @@ -0,0 +1 @@ +0061.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0061.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0061.html.zh-cn.xhtml new file mode 100644 index 0000000..4d2a023 --- /dev/null +++ b/htdocs/imacat/me/diary/0061.html.zh-cn.xhtml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷六十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷六十一

    + +
    + +
    + +
    +
    8.25.’06. 1:50am.
    + +

    + +

    说实话,我不喜欢赌。

    + +

    这样讲好像在自我吹嘘。不知道是不是处女座行事保守的关系,我不喜欢不确定性高的事,喜欢像机械一样规律的事。例如赌,机率性高,就没什么兴趣,像赌马、百家乐、梭哈、乐透,甚至麻将、百货公司抽奖,都没有兴趣。之前出国玩时,饭店二楼有个百家乐小赌台,我从来没见过,抱著增广见识的心态走进去看看,没几分钟无聊走出来了。前年去香港,酒店旁有赌马站,我也抱著增广见识的心态进去晃了晃,也是连一张马票都没买,就走出来了。至於整夜坐在四方桌打麻将,我无法理解。

    + +

    怎么练习都无法越做越好的事,或是要靠运气、气势这种虚幻事物的事,我很难有兴趣。

    + +

    反过来说,确定性高、像机械一样规律的事,例如写电脑程式、玩电脑游戏,我就很容易入迷。电脑游戏有其机率性,但我知道多试几次,一定会成功,还有很多种方法可以提高成功率,而且失败我也没有损失。写电脑程式则是绝对确定规律的事,怎么写一定会怎么跑,没有照那样跑就一定是我哪里写错了。

    + +

    我真的就是不喜欢赌。可以说我没有冒险心吧,可是就是没有办法。

    + +
    + +
    + +
    +
    8.24.’06. 11:41pm.
    + +

    恐怖片

    + +

    我原来不敢看恐怖片,也觉得没必要看。

    + +

    第一次和人讨论恐怖片,是国中时候有一个朋友,拉著我跟我说,他都把恐怖片当成喜剧看,看到斧头砍下去,头手断掉,鲜血乱喷,就觉得好笑得不得了。我那时觉得很不可思议。就算不害怕,无论如何,有人被杀,都是很严肃的事。怎么会好笑呢?

    + +

    第一次看恐怖片,是 1998 年的リング 七夜怪谈 The Ring。那时七夜怪谈佳评如潮,每天电视上都在讲,又叫好又叫座。如果真是这么好的电影,虽然会怕,还是不想放过。可是下定决心去看的时候,周围敢看的朋友都看过了,剩下的朋友都不敢看。我只好一个人硬著头皮进电影院。那时已经放映好几个月,都快下片了,电影院里人不多。我硬是壮著胆子,双手紧紧抱胸把整部电影看完。看完以后完全心服口服,心里只有一个字。可是恐怖的感觉,在接下来的三天,都挥之不去;接下来好几个月,一看到电视机,就有莫名的恐惧。

    + +

    1999 年中,我去春晖电影台当影视编译。时至七月,电视台要做鬼月专题,要赶译好几部鬼片。那几部都是低成本廉价鬼片,血喷来喷去,假人头整排飞出去,还在地上排成一排,可笑到不行。加上我为了校对,反覆倒转、放慢动作、定格看,影片为求恐怖感特意安排的节奏全没了,看到完全麻木。

    + +

    有了上面两个经验,我就好像对恐怖片免疫了。第一次看恐怖片就是看七夜怪谈这种经典,此后任何恐怖片,我都不自觉拿来跟七夜怪谈相比,看不上眼。七夜怪谈不见血又不见鬼,却给人直透心底的恐惧,意境极高;相比之下,血喷来喷去,头手脚飞来飞去,层次就差一大截了。らせん 七夜怪谈二—复活之路 The Spiral一开始就见血,大片血淹满马路。还有被解剖掏空内脏的尸体坐起来说话,身体是空的,那个画面让我颇震憾,有点新意,不过也没什么。

    + +

    对了,Scream 惊声尖叫也不错。最会洒狗血的好莱坞,久未出现没有怪力乱神的恐怖片,还对当时恐怖片的标准公式做了一番嘲讽。后来就出现一种新的电影类型叫惊悚片,来指这种不算恐怖片,但还是很可怕的电影。Bride of Chucky 鬼娃新娘也让我印象比较深,不过是我不喜欢的风格,把杀人凶手捧成英雄,虽然两个邪恶洋娃娃蛮可爱的,不过我不会买回来摆家里。我知道外面有在卖,电影看看可爱就好,当成家里摆饰有点恶心。

    + +

    如果真有像七夜怪谈一样好的恐怖片,我一定会去看。只是我部部都拿去跟七夜怪谈比,以七夜怪谈为标准来衡量别的恐怖片,那大概没有什么能符合我的标准吧。可是就算重看七夜怪谈,也不会有当年的恐怖感了,唉。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 59 | + 60 | + 61 | + 62 | + 63 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0061.html.zh-tw.html b/htdocs/imacat/me/diary/0061.html.zh-tw.html new file mode 120000 index 0000000..3fba8bf --- /dev/null +++ b/htdocs/imacat/me/diary/0061.html.zh-tw.html @@ -0,0 +1 @@ +0061.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0061.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0061.html.zh-tw.xhtml new file mode 100644 index 0000000..3294957 --- /dev/null +++ b/htdocs/imacat/me/diary/0061.html.zh-tw.xhtml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷六十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷六十一

    + +
    + +
    + +
    +
    8.25.’06. 1:50am.
    + +

    + +

    說實話,我不喜歡賭。

    + +

    這樣講好像在自我吹噓。不知道是不是處女座行事保守的關係,我不喜歡不確定性高的事,喜歡像機械一樣規律的事。例如賭,機率性高,就沒什麼興趣,像賭馬、百家樂、梭哈、樂透,甚至麻將、百貨公司抽獎,都沒有興趣。之前出國玩時,飯店二樓有個百家樂小賭檯,我從來沒見過,抱著增廣見識的心態走進去看看,沒幾分鐘無聊走出來了。前年去香港,酒店旁有賭馬站,我也抱著增廣見識的心態進去晃了晃,也是連一張馬票都沒買,就走出來了。至於整夜坐在四方桌打麻將,我無法理解。

    + +

    怎麼練習都無法越做越好的事,或是要靠運氣、氣勢這種虛幻事物的事,我很難有興趣。

    + +

    反過來說,確定性高、像機械一樣規律的事,例如寫電腦程式、玩電腦遊戲,我就很容易入迷。電腦遊戲有其機率性,但我知道多試幾次,一定會成功,還有很多種方法可以提高成功率,而且失敗我也沒有損失。寫電腦程式則是絕對確定規律的事,怎麼寫一定會怎麼跑,沒有照那樣跑就一定是我哪裏寫錯了。

    + +

    我真的就是不喜歡賭。可以說我沒有冒險心吧,可是就是沒有辦法。

    + +
    + +
    + +
    +
    8.24.’06. 11:41pm.
    + +

    恐怖片

    + +

    我原來不敢看恐怖片,也覺得沒必要看。

    + +

    第一次和人討論恐怖片,是國中時候有一個朋友,拉著我跟我說,他都把恐怖片當成喜劇看,看到斧頭砍下去,頭手斷掉,鮮血亂噴,就覺得好笑得不得了。我那時覺得很不可思議。就算不害怕,無論如何,有人被殺,都是很嚴肅的事。怎麼會好笑呢?

    + +

    第一次看恐怖片,是 1998 年的リング 七夜怪談 The Ring。那時七夜怪談佳評如潮,每天電視上都在講,又叫好又叫座。如果真是這麼好的電影,雖然會怕,還是不想放過。可是下定決心去看的時候,周圍敢看的朋友都看過了,剩下的朋友都不敢看。我只好一個人硬著頭皮進電影院。那時已經放映好幾個月,都快下片了,電影院裏人不多。我硬是壯著膽子,雙手緊緊抱胸把整部電影看完。看完以後完全心服口服,心裏只有一個字。可是恐怖的感覺,在接下來的三天,都揮之不去;接下來好幾個月,一看到電視機,就有莫名的恐懼。

    + +

    1999 年中,我去春暉電影台當影視編譯。時至七月,電視台要做鬼月專題,要趕譯好幾部鬼片。那幾部都是低成本廉價鬼片,血噴來噴去,假人頭整排飛出去,還在地上排成一排,可笑到不行。加上我為了校對,反覆倒轉、放慢動作、定格看,影片為求恐怖感特意安排的節奏全沒了,看到完全麻木。

    + +

    有了上面兩個經驗,我就好像對恐怖片免疫了。第一次看恐怖片就是看七夜怪談這種經典,此後任何恐怖片,我都不自覺拿來跟七夜怪談相比,看不上眼。七夜怪談不見血又不見鬼,卻給人直透心底的恐懼,意境極高;相比之下,血噴來噴去,頭手腳飛來飛去,層次就差一大截了。らせん 七夜怪談二—復活之路 The Spiral一開始就見血,大片血淹滿馬路。還有被解剖掏空內臟的屍體坐起來說話,身體是空的,那個畫面讓我頗震憾,有點新意,不過也沒什麼。

    + +

    對了,Scream 驚聲尖叫也不錯。最會灑狗血的好萊塢,久未出現沒有怪力亂神的恐怖片,還對當時恐怖片的標準公式做了一番嘲諷。後來就出現一種新的電影類型叫驚悚片,來指這種不算恐怖片,但還是很可怕的電影。Bride of Chucky 鬼娃新娘也讓我印象比較深,不過是我不喜歡的風格,把殺人兇手捧成英雄,雖然兩個邪惡洋娃娃蠻可愛的,不過我不會買回來擺家裏。我知道外面有在賣,電影看看可愛就好,當成家裏擺飾有點噁心。

    + +

    如果真有像七夜怪談一樣好的恐怖片,我一定會去看。只是我部部都拿去跟七夜怪談比,以七夜怪談為標準來衡量別的恐怖片,那大概沒有什麼能符合我的標準吧。可是就算重看七夜怪談,也不會有當年的恐怖感了,唉。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 59 | + 60 | + 61 | + 62 | + 63 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0062.html.en.html b/htdocs/imacat/me/diary/0062.html.en.html new file mode 120000 index 0000000..0b5dbf5 --- /dev/null +++ b/htdocs/imacat/me/diary/0062.html.en.html @@ -0,0 +1 @@ +0062.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0062.html.en.xhtml b/htdocs/imacat/me/diary/0062.html.en.xhtml new file mode 100644 index 0000000..cfd456a --- /dev/null +++ b/htdocs/imacat/me/diary/0062.html.en.xhtml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 62 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 62

    + +
    + +
    + +
    +
    8.25.’06. 4:17am.
    + +

    省港旗兵—敢衝不怕死

    + +
    +省港旗兵
    +

    省港旗兵

    +
    + + + +

    看了一部舊片。 1984 年麥當雄拍的省港旗兵,至今仍是經典。電影中後段眾人逃入的九龍寨城已於 1993 年拆除,我 2004 年遊港時,已經完全看不出原來的樣子了。

    + +

    電影敘述一群廣東窮鄉大圈仔,在被香港通緝的同鄉大東聳恿下,計劃偷渡香港大幹一票當日返回。眾人原計劃隔天幫阿泰搶珠寶店,立刻拿錢走人,誰知珠寶店剛被搶,警察盤桓不去,只好多等三天。這三天產生了很多變數。首先大家沒來過香港玩,大哥阿東為了玩樂費,多接阿泰一個殺手案,原以是小案,殺了才知道對方是警察,引起警方總動員緝兇。李警司馬上約談被殺警察肥狗的線民阿泰,眾人也憤恨阿泰騙他們殺警,並懷疑阿泰出賣他們,跟阿泰翻臉。阿泰眼見自己步入死局,自己小弟也袖手旁觀,只好投靠李警司。搶完珠寶交貨時,一場殺局等著所有的人。

    + +

    當時香港大陸相鄰,生活水準落差卻很大,形成很大的誘惑,偷渡客很多。黑幫亦會雇用大圈仔犯案,價錢不高,敢衝不怕死,事後隨即送回大陸,不留痕跡,難以追查,非常好用。省港旗兵中描述的大圈仔,成為香港治安很大的問題。這個問題直到今日仍在。 2001 年 5 月 22 日的旺角轟警案,兩名警察遭到四名大圈仔當街槍擊,涉案的季炳雄犯罪集團,事後多次犯案,分別於同年 7 月 17 日及兩年後 2003 年 12 月 24 日落網,至今仍在審理中。而且大圈仔的問題不只香港,日本、美國、台灣也都深受其害。語言相近、隔海相鄰的台灣, 93 年 12 月 22 日蘆洲大陸偷渡客綁架雇主案, 94 年 6 月間沙鹿計程車司機陳錦成命案,皆為大圈仔所為。

    + +

    片中的大圈仔,雖然兇狠,燒殺搶毫不猶豫,但另一面也是做著發財夢,單純、粗勇的鄉下人。八中有年少純情的女友嫦女,早一步偷渡到香港做酒女,烏蠅頭老婆小孩交待要去香港買一堆東西,肥姑家裏有老奶奶掛念。但香港是個燈紅酒綠的大染缸,嚐過甜頭,大家都不想回去了,沒想到也回不去了。

    + +

    殺死警察肥狗的場面,觸目驚心:肥狗中槍後從樓上飛下中庭,中庭是一個很大的溜冰場,屍體落下後在冰上滑行、碰牆反彈,血跡在冰上劃成一個血紅的大叉(╳)。二十年前的舊電影,很多當時觸目驚心的場景,街頭槍戰、手榴彈、大東燒車私刑,今日已屬常見。唯有這一個血紅大叉,從二十年後的今天來看,仍讓人震憾無比,炫目而駭人,無人能及。

    + +

    片末眾人受傷被鎖在閣樓,摒息閉氣冀能逃過一劫,沒想到閣樓鼠叫引起李警司注意,對天花板一陣亂槍。亂槍過後,李警司看到天花板掉下的死老鼠,喘了口氣走開,但其實眾人已死,無人知道。想追緝追緝不到,卻在不知道的地方通通打死了,非常諷刺。

    + +

    後段九龍寨城巷弄的槍戰,以手提攝影,將狹窄、九拐十八彎、四通八達的九龍寨城巷弄,展現得淋漓盡至,讓人悠然神往。在九龍寨城業已消失的現在,這一段影片彌足珍貴。

    + +

    這是麥當雄第一部執導的電影,片中起用的全都是第一次演戲的非演員。麥當雄從在三百多個大圈仔中試鏡挑選演員,再為不會演戲的他們,量身打造劇中角色,使得電影寫實性極高。第一次執導的麥當雄得了香港電影金像獎最佳導演,第一次演戲的林威則得到最佳男配角,成績斐然。林威扮演行事狠辣,卻對兄弟有情有義的通緝犯大東,讓人感覺非常精彩。

    + +
    9.26.’06. 3:52am.
    + +

    我一直不知道省港旗兵四個字是什麼意思,剛剛才解開這個謎。省港是指廣東省香港,這兩個地方是分不開的,所以合稱省港旗兵則是指紅旗紅衛兵。合起來就是省港旗兵

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 60 | + 61 | + 62 | + 63 | + 64 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0062.html.zh-cn.html b/htdocs/imacat/me/diary/0062.html.zh-cn.html new file mode 120000 index 0000000..4a52378 --- /dev/null +++ b/htdocs/imacat/me/diary/0062.html.zh-cn.html @@ -0,0 +1 @@ +0062.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0062.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0062.html.zh-cn.xhtml new file mode 100644 index 0000000..8a7c271 --- /dev/null +++ b/htdocs/imacat/me/diary/0062.html.zh-cn.xhtml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷六十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷六十二

    + +
    + +
    + +
    +
    8.25.’06. 4:17am.
    + +

    省港旗兵—敢冲不怕死

    + +
    +省港旗兵
    +

    省港旗兵

    +
    + + + +

    看了一部旧片。 1984 年麦当雄拍的省港旗兵,至今仍是经典。电影中后段众人逃入的九龙寨城已於 1993 年拆除,我 2004 年游港时,已经完全看不出原来的样子了。

    + +

    电影叙述一群广东穷乡大圈仔,在被香港通缉的同乡大东耸恿下,计划偷渡香港大干一票当日返回。众人原计划隔天帮阿泰抢珠宝店,立刻拿钱走人,谁知珠宝店刚被抢,警察盘桓不去,只好多等三天。这三天产生了很多变数。首先大家没来过香港玩,大哥阿东为了玩乐费,多接阿泰一个杀手案,原以是小案,杀了才知道对方是警察,引起警方总动员缉凶。李警司马上约谈被杀警察肥狗的线民阿泰,众人也愤恨阿泰骗他们杀警,并怀疑阿泰出卖他们,跟阿泰翻脸。阿泰眼见自己步入死局,自己小弟也袖手旁观,只好投靠李警司。抢完珠宝交货时,一场杀局等著所有的人。

    + +

    当时香港大陆相邻,生活水准落差却很大,形成很大的诱惑,偷渡客很多。黑帮亦会雇用大圈仔犯案,价钱不高,敢冲不怕死,事后随即送回大陆,不留痕迹,难以追查,非常好用。省港旗兵中描述的大圈仔,成为香港治安很大的问题。这个问题直到今日仍在。 2001 年 5 月 22 日的旺角轰警案,两名警察遭到四名大圈仔当街枪击,涉案的季炳雄犯罪集团,事后多次犯案,分别於同年 7 月 17 日及两年后 2003 年 12 月 24 日落网,至今仍在审理中。而且大圈仔的问题不只香港,日本、美国、台湾也都深受其害。语言相近、隔海相邻的台湾, 93 年 12 月 22 日芦洲大陆偷渡客绑架雇主案, 94 年 6 月间沙鹿计程车司机陈锦成命案,皆为大圈仔所为。

    + +

    片中的大圈仔,虽然凶狠,烧杀抢毫不犹豫,但另一面也是做著发财梦,单纯、粗勇的乡下人。八中有年少纯情的女友嫦女,早一步偷渡到香港做酒女,乌蝇头老婆小孩交待要去香港买一堆东西,肥姑家里有老奶奶挂念。但香港是个灯红酒绿的大染缸,尝过甜头,大家都不想回去了,没想到也回不去了。

    + +

    杀死警察肥狗的场面,触目惊心:肥狗中枪后从楼上飞下中庭,中庭是一个很大的溜冰场,尸体落下后在冰上滑行、碰墙反弹,血迹在冰上划成一个血红的大叉(╳)。二十年前的旧电影,很多当时触目惊心的场景,街头枪战、手榴弹、大东烧车私刑,今日已属常见。唯有这一个血红大叉,从二十年后的今天来看,仍让人震憾无比,炫目而骇人,无人能及。

    + +

    片末众人受伤被锁在阁楼,摒息闭气冀能逃过一劫,没想到阁楼鼠叫引起李警司注意,对天花板一阵乱枪。乱枪过后,李警司看到天花板掉下的死老鼠,喘了口气走开,但其实众人已死,无人知道。想追缉追缉不到,却在不知道的地方通通打死了,非常讽刺。

    + +

    后段九龙寨城巷弄的枪战,以手提摄影,将狭窄、九拐十八弯、四通八达的九龙寨城巷弄,展现得淋漓尽至,让人悠然神往。在九龙寨城业已消失的现在,这一段影片弥足珍贵。

    + +

    这是麦当雄第一部执导的电影,片中起用的全都是第一次演戏的非演员。麦当雄从在三百多个大圈仔中试镜挑选演员,再为不会演戏的他们,量身打造剧中角色,使得电影写实性极高。第一次执导的麦当雄得了香港电影金像奖最佳导演,第一次演戏的林威则得到最佳男配角,成绩斐然。林威扮演行事狠辣,却对兄弟有情有义的通缉犯大东,让人感觉非常精彩。

    + +
    9.26.’06. 3:52am.
    + +

    我一直不知道省港旗兵四个字是什么意思,刚刚才解开这个谜。省港是指广东省香港,这两个地方是分不开的,所以合称省港旗兵则是指红旗红卫兵。合起来就是省港旗兵

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 60 | + 61 | + 62 | + 63 | + 64 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0062.html.zh-tw.html b/htdocs/imacat/me/diary/0062.html.zh-tw.html new file mode 120000 index 0000000..b35ea83 --- /dev/null +++ b/htdocs/imacat/me/diary/0062.html.zh-tw.html @@ -0,0 +1 @@ +0062.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0062.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0062.html.zh-tw.xhtml new file mode 100644 index 0000000..5739411 --- /dev/null +++ b/htdocs/imacat/me/diary/0062.html.zh-tw.xhtml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷六十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷六十二

    + +
    + +
    + +
    +
    8.25.’06. 4:17am.
    + +

    省港旗兵—敢衝不怕死

    + +
    +省港旗兵
    +

    省港旗兵

    +
    + + + +

    看了一部舊片。 1984 年麥當雄拍的省港旗兵,至今仍是經典。電影中後段眾人逃入的九龍寨城已於 1993 年拆除,我 2004 年遊港時,已經完全看不出原來的樣子了。

    + +

    電影敘述一群廣東窮鄉大圈仔,在被香港通緝的同鄉大東聳恿下,計劃偷渡香港大幹一票當日返回。眾人原計劃隔天幫阿泰搶珠寶店,立刻拿錢走人,誰知珠寶店剛被搶,警察盤桓不去,只好多等三天。這三天產生了很多變數。首先大家沒來過香港玩,大哥阿東為了玩樂費,多接阿泰一個殺手案,原以是小案,殺了才知道對方是警察,引起警方總動員緝兇。李警司馬上約談被殺警察肥狗的線民阿泰,眾人也憤恨阿泰騙他們殺警,並懷疑阿泰出賣他們,跟阿泰翻臉。阿泰眼見自己步入死局,自己小弟也袖手旁觀,只好投靠李警司。搶完珠寶交貨時,一場殺局等著所有的人。

    + +

    當時香港大陸相鄰,生活水準落差卻很大,形成很大的誘惑,偷渡客很多。黑幫亦會雇用大圈仔犯案,價錢不高,敢衝不怕死,事後隨即送回大陸,不留痕跡,難以追查,非常好用。省港旗兵中描述的大圈仔,成為香港治安很大的問題。這個問題直到今日仍在。 2001 年 5 月 22 日的旺角轟警案,兩名警察遭到四名大圈仔當街槍擊,涉案的季炳雄犯罪集團,事後多次犯案,分別於同年 7 月 17 日及兩年後 2003 年 12 月 24 日落網,至今仍在審理中。而且大圈仔的問題不只香港,日本、美國、台灣也都深受其害。語言相近、隔海相鄰的台灣, 93 年 12 月 22 日蘆洲大陸偷渡客綁架雇主案, 94 年 6 月間沙鹿計程車司機陳錦成命案,皆為大圈仔所為。

    + +

    片中的大圈仔,雖然兇狠,燒殺搶毫不猶豫,但另一面也是做著發財夢,單純、粗勇的鄉下人。八中有年少純情的女友嫦女,早一步偷渡到香港做酒女,烏蠅頭老婆小孩交待要去香港買一堆東西,肥姑家裏有老奶奶掛念。但香港是個燈紅酒綠的大染缸,嚐過甜頭,大家都不想回去了,沒想到也回不去了。

    + +

    殺死警察肥狗的場面,觸目驚心:肥狗中槍後從樓上飛下中庭,中庭是一個很大的溜冰場,屍體落下後在冰上滑行、碰牆反彈,血跡在冰上劃成一個血紅的大叉(╳)。二十年前的舊電影,很多當時觸目驚心的場景,街頭槍戰、手榴彈、大東燒車私刑,今日已屬常見。唯有這一個血紅大叉,從二十年後的今天來看,仍讓人震憾無比,炫目而駭人,無人能及。

    + +

    片末眾人受傷被鎖在閣樓,摒息閉氣冀能逃過一劫,沒想到閣樓鼠叫引起李警司注意,對天花板一陣亂槍。亂槍過後,李警司看到天花板掉下的死老鼠,喘了口氣走開,但其實眾人已死,無人知道。想追緝追緝不到,卻在不知道的地方通通打死了,非常諷刺。

    + +

    後段九龍寨城巷弄的槍戰,以手提攝影,將狹窄、九拐十八彎、四通八達的九龍寨城巷弄,展現得淋漓盡至,讓人悠然神往。在九龍寨城業已消失的現在,這一段影片彌足珍貴。

    + +

    這是麥當雄第一部執導的電影,片中起用的全都是第一次演戲的非演員。麥當雄從在三百多個大圈仔中試鏡挑選演員,再為不會演戲的他們,量身打造劇中角色,使得電影寫實性極高。第一次執導的麥當雄得了香港電影金像獎最佳導演,第一次演戲的林威則得到最佳男配角,成績斐然。林威扮演行事狠辣,卻對兄弟有情有義的通緝犯大東,讓人感覺非常精彩。

    + +
    9.26.’06. 3:52am.
    + +

    我一直不知道省港旗兵四個字是什麼意思,剛剛才解開這個謎。省港是指廣東省香港,這兩個地方是分不開的,所以合稱省港旗兵則是指紅旗紅衛兵。合起來就是省港旗兵

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 60 | + 61 | + 62 | + 63 | + 64 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0063.html.en.html b/htdocs/imacat/me/diary/0063.html.en.html new file mode 120000 index 0000000..2bbd494 --- /dev/null +++ b/htdocs/imacat/me/diary/0063.html.en.html @@ -0,0 +1 @@ +0063.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0063.html.en.xhtml b/htdocs/imacat/me/diary/0063.html.en.xhtml new file mode 100644 index 0000000..5f57a50 --- /dev/null +++ b/htdocs/imacat/me/diary/0063.html.en.xhtml @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 63 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 63

    + +
    + +
    + +
    +
    8.26.’06. 7:42am.
    + +

    Sid & Nancy—毀滅的龐克搖滾愛情之旅

    + +
    +Sid & Nancy
    +

    Sid & Nancy

    +
    + + + +

    終於看了 Sid & Nancy

    + +

    這是一趟毀滅之旅。主角是龐克搖滾史上最有名的一對戀人 Sid ViciousNancy Spungen 。瘋瘋巔巔的 Sex Pistols 性手槍樂團貝斯手 Sid Vicious ,遇上吸毒的妓女 Nancy Spungen ,兩人性格裏毀滅的因子一拍即合,陷入無法自拔的迷幻狂戀。原本就不會彈貝斯的 Sid ,和 Nancy 在一起後,陷入瘋狂的兩人迷幻世界,無法練團。 Sex Pistols 經紀人 Malcolm McLaren 安排巡迴演出,強迫兩個人分開,希望情況好轉。誰知道 Sid 過於思念 Nancy 使情況更惡劣,吸毒吸得昏天暗地,甚至在巡迴演出途中倒下,導致不滿的其它團員相繼離開,樂團瓦解。樂團瓦解後 Sid 回去找 Nancy ,兩人得不到親友的支持,努力爭取到的同伴和演出機會,也因 Sid 吸毒吸到神智不清,無法正常表演而告吹。失去音樂的兩人只能投靠紐約的朋友接濟,提供旅館和廉價的毒品。此時相愛的兩個戀人已經沒有出路了,只剩下最後的毀滅。

    + +

    我不清楚 Sex Pistols 的歷史,不過電影主要情節應該是忠於史實。部份有導演自己的詮釋,例如兩人相處的細節、 Nancy 死亡的真正原因等,部份可能為了方便電影拍攝而稍作修改。 Sid Vicious 被補後昏昏沉沉,對 Nancy 之死完全沒有記憶。到今天為止,還無法知道 Nancy 是自殺,或是被 Sid 所殺。

    + +

    Sid & Nancy 曾經因為描述吸毒太過露骨寫實,而被禁演。不過電影本身並沒有美化吸毒,或是英雄化吸毒的行為。兩個人到後來住處髒亂不堪,神智不清,無法正常生活。任何人看了 Sid & Nancy ,都會覺得毒品很可怕。

    + +

    電影裏面完全沒有出現 Vivienne Westwood 。我找了半天還是沒有,覺得有點遺憾。

    + +

    很久以前,我也曾經陷入同樣毀滅性的狂戀中,雖沒有毒品,兩個人的世界除了做愛還是做愛,走到哪裏都要抱在一起,像兩個泥人混在一起分不開,一分開就好像會死掉一樣。好像還讓周圍的朋友很困擾,哈。 ^^; 那是很久很久以前的事了。看著 Sid & Nancy ,有種懷念的哀愁感。

    + +
    + +
    + +
    +
    8.25.’06. 5:47pm.
    + +

    省港、香江、濠江

    + +

    省港廣東省香港。我到今天才弄懂。 ^^;

    + +

    香江是香港的別名,濠江則是澳門的舊名。

    + +
    + +
    + +
    +
    8.25.’06. 4:49am.
    + +

    電影感想/影評

    + +

    其實我原來完全沒有想寫影評的,只是看完電影,想把想到的事、感想、感動記下來,像日記一樣,日後可以回來翻。不過最近我覺得自己越寫越好。寫之前找幾篇別人的影評閱讀,回想是不是有什麼電影有趣的地方沒有注意到,再來回找。這個過程,也會讓我試著以我以前沒注意到的角度來看電影,發現有趣的地方。越寫,發現越不需要依賴別人的影評,甚至有時自己的感想,還會自己覺得比別人的影評好,注意到更多有意思的細節。

    + +

    越寫越有樣子了。嗯。 *^_^*

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 61 | + 62 | + 63 | + 64 | + 65 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0063.html.zh-cn.html b/htdocs/imacat/me/diary/0063.html.zh-cn.html new file mode 120000 index 0000000..4cdffc9 --- /dev/null +++ b/htdocs/imacat/me/diary/0063.html.zh-cn.html @@ -0,0 +1 @@ +0063.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0063.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0063.html.zh-cn.xhtml new file mode 100644 index 0000000..cd28162 --- /dev/null +++ b/htdocs/imacat/me/diary/0063.html.zh-cn.xhtml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷六十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷六十三

    + +
    + +
    + +
    +
    8.26.’06. 7:42am.
    + +

    Sid & Nancy—毁灭的庞克摇滚爱情之旅

    + +
    +Sid & Nancy
    +

    Sid & Nancy

    +
    + + + +

    终於看了 Sid & Nancy

    + +

    这是一趟毁灭之旅。主角是庞克摇滚史上最有名的一对恋人 Sid ViciousNancy Spungen 。疯疯巅巅的 Sex Pistols 性手枪乐团贝斯手 Sid Vicious ,遇上吸毒的妓女 Nancy Spungen ,两人性格里毁灭的因子一拍即合,陷入无法自拔的迷幻狂恋。原本就不会弹贝斯的 Sid ,和 Nancy 在一起后,陷入疯狂的两人迷幻世界,无法练团。 Sex Pistols 经纪人 Malcolm McLaren 安排巡回演出,强迫两个人分开,希望情况好转。谁知道 Sid 过於思念 Nancy 使情况更恶劣,吸毒吸得昏天暗地,甚至在巡回演出途中倒下,导致不满的其它团员相继离开,乐团瓦解。乐团瓦解后 Sid 回去找 Nancy ,两人得不到亲友的支持,努力争取到的同伴和演出机会,也因 Sid 吸毒吸到神智不清,无法正常表演而告吹。失去音乐的两人只能投靠纽约的朋友接济,提供旅馆和廉价的毒品。此时相爱的两个恋人已经没有出路了,只剩下最后的毁灭。

    + +

    我不清楚 Sex Pistols 的历史,不过电影主要情节应该是忠於史实。部份有导演自己的诠释,例如两人相处的细节、 Nancy 死亡的真正原因等,部份可能为了方便电影拍摄而稍作修改。 Sid Vicious 被补后昏昏沉沉,对 Nancy 之死完全没有记忆。到今天为止,还无法知道 Nancy 是自杀,或是被 Sid 所杀。

    + +

    Sid & Nancy 曾经因为描述吸毒太过露骨写实,而被禁演。不过电影本身并没有美化吸毒,或是英雄化吸毒的行为。两个人到后来住处脏乱不堪,神智不清,无法正常生活。任何人看了 Sid & Nancy ,都会觉得毒品很可怕。

    + +

    电影里面完全没有出现 Vivienne Westwood 。我找了半天还是没有,觉得有点遗憾。

    + +

    很久以前,我也曾经陷入同样毁灭性的狂恋中,虽没有毒品,两个人的世界除了做爱还是做爱,走到哪里都要抱在一起,像两个泥人混在一起分不开,一分开就好像会死掉一样。好像还让周围的朋友很困扰,哈。 ^^; 那是很久很久以前的事了。看著 Sid & Nancy ,有种怀念的哀愁感。

    + +
    + +
    + +
    +
    8.25.’06. 5:47pm.
    + +

    省港、香江、濠江

    + +

    省港广东省香港。我到今天才弄懂。 ^^;

    + +

    香江是香港的别名,濠江则是澳门的旧名。

    + +
    + +
    + +
    +
    8.25.’06. 4:49am.
    + +

    电影感想/影评

    + +

    其实我原来完全没有想写影评的,只是看完电影,想把想到的事、感想、感动记下来,像日记一样,日后可以回来翻。不过最近我觉得自己越写越好。写之前找几篇别人的影评阅读,回想是不是有什么电影有趣的地方没有注意到,再来回找。这个过程,也会让我试著以我以前没注意到的角度来看电影,发现有趣的地方。越写,发现越不需要依赖别人的影评,甚至有时自己的感想,还会自己觉得比别人的影评好,注意到更多有意思的细节。

    + +

    越写越有样子了。嗯。 *^_^*

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 61 | + 62 | + 63 | + 64 | + 65 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0063.html.zh-tw.html b/htdocs/imacat/me/diary/0063.html.zh-tw.html new file mode 120000 index 0000000..d700aab --- /dev/null +++ b/htdocs/imacat/me/diary/0063.html.zh-tw.html @@ -0,0 +1 @@ +0063.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0063.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0063.html.zh-tw.xhtml new file mode 100644 index 0000000..b085184 --- /dev/null +++ b/htdocs/imacat/me/diary/0063.html.zh-tw.xhtml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷六十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷六十三

    + +
    + +
    + +
    +
    8.26.’06. 7:42am.
    + +

    Sid & Nancy—毀滅的龐克搖滾愛情之旅

    + +
    +Sid & Nancy
    +

    Sid & Nancy

    +
    + + + +

    終於看了 Sid & Nancy

    + +

    這是一趟毀滅之旅。主角是龐克搖滾史上最有名的一對戀人 Sid ViciousNancy Spungen 。瘋瘋巔巔的 Sex Pistols 性手槍樂團貝斯手 Sid Vicious ,遇上吸毒的妓女 Nancy Spungen ,兩人性格裏毀滅的因子一拍即合,陷入無法自拔的迷幻狂戀。原本就不會彈貝斯的 Sid ,和 Nancy 在一起後,陷入瘋狂的兩人迷幻世界,無法練團。 Sex Pistols 經紀人 Malcolm McLaren 安排巡迴演出,強迫兩個人分開,希望情況好轉。誰知道 Sid 過於思念 Nancy 使情況更惡劣,吸毒吸得昏天暗地,甚至在巡迴演出途中倒下,導致不滿的其它團員相繼離開,樂團瓦解。樂團瓦解後 Sid 回去找 Nancy ,兩人得不到親友的支持,努力爭取到的同伴和演出機會,也因 Sid 吸毒吸到神智不清,無法正常表演而告吹。失去音樂的兩人只能投靠紐約的朋友接濟,提供旅館和廉價的毒品。此時相愛的兩個戀人已經沒有出路了,只剩下最後的毀滅。

    + +

    我不清楚 Sex Pistols 的歷史,不過電影主要情節應該是忠於史實。部份有導演自己的詮釋,例如兩人相處的細節、 Nancy 死亡的真正原因等,部份可能為了方便電影拍攝而稍作修改。 Sid Vicious 被補後昏昏沉沉,對 Nancy 之死完全沒有記憶。到今天為止,還無法知道 Nancy 是自殺,或是被 Sid 所殺。

    + +

    Sid & Nancy 曾經因為描述吸毒太過露骨寫實,而被禁演。不過電影本身並沒有美化吸毒,或是英雄化吸毒的行為。兩個人到後來住處髒亂不堪,神智不清,無法正常生活。任何人看了 Sid & Nancy ,都會覺得毒品很可怕。

    + +

    電影裏面完全沒有出現 Vivienne Westwood 。我找了半天還是沒有,覺得有點遺憾。

    + +

    很久以前,我也曾經陷入同樣毀滅性的狂戀中,雖沒有毒品,兩個人的世界除了做愛還是做愛,走到哪裏都要抱在一起,像兩個泥人混在一起分不開,一分開就好像會死掉一樣。好像還讓周圍的朋友很困擾,哈。 ^^; 那是很久很久以前的事了。看著 Sid & Nancy ,有種懷念的哀愁感。

    + +
    + +
    + +
    +
    8.25.’06. 5:47pm.
    + +

    省港、香江、濠江

    + +

    省港廣東省香港。我到今天才弄懂。 ^^;

    + +

    香江是香港的別名,濠江則是澳門的舊名。

    + +
    + +
    + +
    +
    8.25.’06. 4:49am.
    + +

    電影感想/影評

    + +

    其實我原來完全沒有想寫影評的,只是看完電影,想把想到的事、感想、感動記下來,像日記一樣,日後可以回來翻。不過最近我覺得自己越寫越好。寫之前找幾篇別人的影評閱讀,回想是不是有什麼電影有趣的地方沒有注意到,再來回找。這個過程,也會讓我試著以我以前沒注意到的角度來看電影,發現有趣的地方。越寫,發現越不需要依賴別人的影評,甚至有時自己的感想,還會自己覺得比別人的影評好,注意到更多有意思的細節。

    + +

    越寫越有樣子了。嗯。 *^_^*

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 61 | + 62 | + 63 | + 64 | + 65 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0064.html.en.html b/htdocs/imacat/me/diary/0064.html.en.html new file mode 120000 index 0000000..d8e7d77 --- /dev/null +++ b/htdocs/imacat/me/diary/0064.html.en.html @@ -0,0 +1 @@ +0064.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0064.html.en.xhtml b/htdocs/imacat/me/diary/0064.html.en.xhtml new file mode 100644 index 0000000..d1f2e47 --- /dev/null +++ b/htdocs/imacat/me/diary/0064.html.en.xhtml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 64 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 64

    + +
    + +
    + +
    +
    8.27.’06. 0:52am.
    + +

    電影觀感的標題

    + +

    前兩天,決定把電影觀感,都加上標題。之前沒加的,也補加上去。

    + +

    可是其實不好加。有時候,要為一部電影下一段適當的註腳,真的很難。在這裏決定註腳的重點,不是點出客觀的電影主旨,而是我個人對電影的主觀感覺。怎麼樣能夠一句話,總結我對這整部電影的感覺,有時候真的蠻困難的。下得不好的話,自己也覺得很糟糕。

    + +

    可是我還是想加。之前引用別人的影評時就注意到了,有些人寫影評、寫觀影心得,直接就以片名做標題。這樣我引用起來多少有點困擾,因為不是很容易清楚哪篇是哪篇。如果我自己有做個標題,總結我的感覺得話,那如果別人要引用,就方便得多了。

    + +

    可是這是有點自大的想法啦。 ^^; 我寫得又不好,也不專業,誰會來引用我的觀影心得呢?呵呵~

    + +
    + +
    + +
    +
    8.26.’06. 11:31pm.
    + +

    Sex Pistols MTV

    + +

    在網路上找到了一段 Sex Pistols MTV 合輯。沒想到 1977 年就有 MTV 了。影片裏包括了 Sid Vicious 有名的獨唱 My Way

    + +

    上面的是 Ed2K 連結,可以用 eMule 下載。

    + +

    難怪有人說,蓋瑞歐德曼 Gary OldmanSid Vicious 演得入木三分,讓人錯以為 Sid 復活了。 Sid & NancySid 那個神韻,那個歪嘴的招牌表情,都抓得太好了。

    + +

    不過 MTV 裏當貝斯手的 Sid ,並未像電影中一樣在樂團中特別瘋巔,和其他人差不多。不過他單飛後的兩三首歌,就好像猥褻的瘋子了。 ^^; 雖然這樣也很酷就是了。

    + +

    看完以後才晃然大悟,為什麼電影 NANA 裏的要找松田龍平來演。松田龍平的黑眼圈、蒼白的臉和空洞的眼神,像的不是,而是 Sid Vicious

    + +

    看著 MTV 。我很久以前,也曾現場參加過這樣的地下音樂演唱會。那時候認為自己也可以懂,也可以成為那群人的一份子。現在我覺得我並不大懂。我想不是我變老或變笨了,而是我變誠實了。

    + +
    + +
    + +
    +
    8.26.’06. 10:36pm.
    + +

    刑偵一號案

    + +

    今天在網路上看了一本閒書:刑偵一號案,講的是十年前中國新疆白寶山殺人搶劫案。作者採訪很多人,分別從不同的角度來看全部犯案的過程,有白寶山的角度,有公安的角度,也夾雜了白寶山過去的倒敘。因為有時候不同角度看的是同一件事,所以時空會有交錯的時候。要把這麼多不同的角度,融在一個故事中,作者也蠻了不起的。寫得還蠻精彩的。

    + +

    記得上一次看這種社會寫實傳奇八卦閒書,是小時候的事了。偶爾看看這種閒書,也不錯。

    + +

    白寶山案在中國拍成電視連續劇了,叫末路。我是覺得這樣不大好啦,雖然整個事件蠻傳奇的。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 62 | + 63 | + 64 | + 65 | + 66 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0064.html.zh-cn.html b/htdocs/imacat/me/diary/0064.html.zh-cn.html new file mode 120000 index 0000000..e3f1e94 --- /dev/null +++ b/htdocs/imacat/me/diary/0064.html.zh-cn.html @@ -0,0 +1 @@ +0064.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0064.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0064.html.zh-cn.xhtml new file mode 100644 index 0000000..d911f1b --- /dev/null +++ b/htdocs/imacat/me/diary/0064.html.zh-cn.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷六十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷六十四

    + +
    + +
    + +
    +
    8.27.’06. 0:52am.
    + +

    电影观感的标题

    + +

    前两天,决定把电影观感,都加上标题。之前没加的,也补加上去。

    + +

    可是其实不好加。有时候,要为一部电影下一段适当的注脚,真的很难。在这里决定注脚的重点,不是点出客观的电影主旨,而是我个人对电影的主观感觉。怎么样能够一句话,总结我对这整部电影的感觉,有时候真的蛮困难的。下得不好的话,自己也觉得很糟糕。

    + +

    可是我还是想加。之前引用别人的影评时就注意到了,有些人写影评、写观影心得,直接就以片名做标题。这样我引用起来多少有点困扰,因为不是很容易清楚哪篇是哪篇。如果我自己有做个标题,总结我的感觉得话,那如果别人要引用,就方便得多了。

    + +

    可是这是有点自大的想法啦。 ^^; 我写得又不好,也不专业,谁会来引用我的观影心得呢?呵呵~

    + +
    + +
    + +
    +
    8.26.’06. 11:31pm.
    + +

    Sex Pistols MTV

    + +

    在网路上找到了一段 Sex Pistols MTV 合辑。没想到 1977 年就有 MTV 了。影片里包括了 Sid Vicious 有名的独唱 My Way

    + +

    上面的是 Ed2K 连结,可以用 eMule 下载。

    + +

    难怪有人说,盖瑞欧德曼 Gary OldmanSid Vicious 演得入木三分,让人错以为 Sid 复活了。 Sid & NancySid 那个神韵,那个歪嘴的招牌表情,都抓得太好了。

    + +

    不过 MTV 里当贝斯手的 Sid ,并未像电影中一样在乐团中特别疯巅,和其他人差不多。不过他单飞后的两三首歌,就好像猥亵的疯子了。 ^^; 虽然这样也很酷就是了。

    + +

    看完以后才晃然大悟,为什么电影 NANA 里的要找松田龙平来演。松田龙平的黑眼圈、苍白的脸和空洞的眼神,像的不是,而是 Sid Vicious

    + +

    看著 MTV 。我很久以前,也曾现场参加过这样的地下音乐演唱会。那时候认为自己也可以懂,也可以成为那群人的一份子。现在我觉得我并不大懂。我想不是我变老或变笨了,而是我变诚实了。

    + +
    + +
    + +
    +
    8.26.’06. 10:36pm.
    + +

    刑侦一号案

    + +

    今天在网路上看了一本闲书:刑侦一号案,讲的是十年前中国新疆白宝山杀人抢劫案。作者采访很多人,分别从不同的角度来看全部犯案的过程,有白宝山的角度,有公安的角度,也夹杂了白宝山过去的倒叙。因为有时候不同角度看的是同一件事,所以时空会有交错的时候。要把这么多不同的角度,融在一个故事中,作者也蛮了不起的。写得还蛮精彩的。

    + +

    记得上一次看这种社会写实传奇八卦闲书,是小时候的事了。偶尔看看这种闲书,也不错。

    + +

    白宝山案在中国拍成电视连续剧了,叫末路。我是觉得这样不大好啦,虽然整个事件蛮传奇的。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 62 | + 63 | + 64 | + 65 | + 66 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0064.html.zh-tw.html b/htdocs/imacat/me/diary/0064.html.zh-tw.html new file mode 120000 index 0000000..c696933 --- /dev/null +++ b/htdocs/imacat/me/diary/0064.html.zh-tw.html @@ -0,0 +1 @@ +0064.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0064.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0064.html.zh-tw.xhtml new file mode 100644 index 0000000..e880b27 --- /dev/null +++ b/htdocs/imacat/me/diary/0064.html.zh-tw.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷六十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷六十四

    + +
    + +
    + +
    +
    8.27.’06. 0:52am.
    + +

    電影觀感的標題

    + +

    前兩天,決定把電影觀感,都加上標題。之前沒加的,也補加上去。

    + +

    可是其實不好加。有時候,要為一部電影下一段適當的註腳,真的很難。在這裏決定註腳的重點,不是點出客觀的電影主旨,而是我個人對電影的主觀感覺。怎麼樣能夠一句話,總結我對這整部電影的感覺,有時候真的蠻困難的。下得不好的話,自己也覺得很糟糕。

    + +

    可是我還是想加。之前引用別人的影評時就注意到了,有些人寫影評、寫觀影心得,直接就以片名做標題。這樣我引用起來多少有點困擾,因為不是很容易清楚哪篇是哪篇。如果我自己有做個標題,總結我的感覺得話,那如果別人要引用,就方便得多了。

    + +

    可是這是有點自大的想法啦。 ^^; 我寫得又不好,也不專業,誰會來引用我的觀影心得呢?呵呵~

    + +
    + +
    + +
    +
    8.26.’06. 11:31pm.
    + +

    Sex Pistols MTV

    + +

    在網路上找到了一段 Sex Pistols MTV 合輯。沒想到 1977 年就有 MTV 了。影片裏包括了 Sid Vicious 有名的獨唱 My Way

    + +

    上面的是 Ed2K 連結,可以用 eMule 下載。

    + +

    難怪有人說,蓋瑞歐德曼 Gary OldmanSid Vicious 演得入木三分,讓人錯以為 Sid 復活了。 Sid & NancySid 那個神韻,那個歪嘴的招牌表情,都抓得太好了。

    + +

    不過 MTV 裏當貝斯手的 Sid ,並未像電影中一樣在樂團中特別瘋巔,和其他人差不多。不過他單飛後的兩三首歌,就好像猥褻的瘋子了。 ^^; 雖然這樣也很酷就是了。

    + +

    看完以後才晃然大悟,為什麼電影 NANA 裏的要找松田龍平來演。松田龍平的黑眼圈、蒼白的臉和空洞的眼神,像的不是,而是 Sid Vicious

    + +

    看著 MTV 。我很久以前,也曾現場參加過這樣的地下音樂演唱會。那時候認為自己也可以懂,也可以成為那群人的一份子。現在我覺得我並不大懂。我想不是我變老或變笨了,而是我變誠實了。

    + +
    + +
    + +
    +
    8.26.’06. 10:36pm.
    + +

    刑偵一號案

    + +

    今天在網路上看了一本閒書:刑偵一號案,講的是十年前中國新疆白寶山殺人搶劫案。作者採訪很多人,分別從不同的角度來看全部犯案的過程,有白寶山的角度,有公安的角度,也夾雜了白寶山過去的倒敘。因為有時候不同角度看的是同一件事,所以時空會有交錯的時候。要把這麼多不同的角度,融在一個故事中,作者也蠻了不起的。寫得還蠻精彩的。

    + +

    記得上一次看這種社會寫實傳奇八卦閒書,是小時候的事了。偶爾看看這種閒書,也不錯。

    + +

    白寶山案在中國拍成電視連續劇了,叫末路。我是覺得這樣不大好啦,雖然整個事件蠻傳奇的。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 62 | + 63 | + 64 | + 65 | + 66 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0065.html.en.html b/htdocs/imacat/me/diary/0065.html.en.html new file mode 120000 index 0000000..0ef2712 --- /dev/null +++ b/htdocs/imacat/me/diary/0065.html.en.html @@ -0,0 +1 @@ +0065.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0065.html.en.xhtml b/htdocs/imacat/me/diary/0065.html.en.xhtml new file mode 100644 index 0000000..e892ce3 --- /dev/null +++ b/htdocs/imacat/me/diary/0065.html.en.xhtml @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 65 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 65

    + +
    + +
    + +
    +
    8.27.’06. 3:26pm.
    + +

    女打仔

    + +

    好來塢過去幾年女打仔當道,拍了一大堆女生當主角的動作片,像Ultraviolet 紫光任務 (2006)Æon Flux 倩影刺客 (2005)Underworld 決戰異世界 (2003,2006)等。其中也有很多爛片,像紫光任務

    + +

    前幾天在漫畫出租店看到,連法國製片盧貝松的TAXI 終極殺陣 (1998)也出女生版了,美國人找女生重拍,叫做Taxi 計程車女王 (2004)。真是太扯了。這種爛片就不用重拍了吧~

    + +
    + +
    + +
    +
    8.27.’06. 1:38pm.
    + +

    絕品好茶

    + +
    +

    試試這瓶茶吧。

    + +

    這種茶不都差不多嗎?竟然叫絕品好茶,太誇張了吧!

    + +

    + +

    入口茶香,入喉回韻,不止回甘…絕品!

    + +

    好茶!

    +
    + +

    衝著黃秋生讓我流口水的演技,明知道會受騙,我也還是去買了一瓶來喝。喝了以後…

    + +

    …這種茶不都差不多嗎?

    + +
    + +
    + +
    +
    8.27.’06. 1:35pm.
    + +

    新警察故事

    + +

    剛才牽機車去換機油時,在機車行看了一小段東森電影台播放的成龍新警察故事 (2004)

    + +

    新警察故事過於濫情,網路上已經罵很多了。我看了一小段,只想說,如果打不死的警察很扯的話,那打不死的匪徒,是不是也很扯?

    + +

    那一小段是匪徒剛搶完銀行,在街頭的遭遇戰。匪徒在大街上擺好陣式,手拿長槍等待,警察一來,雙方一陣駁火,警察死傷慘重,匪徒大笑揚身而去。很扯的是,匪徒也是拿車身做掩蔽,掩蔽不比警察好,還有人根本不找掩蔽。就算長槍比短槍強,但雙方距離在短槍射程內,差別沒有那麼大。匪徒怎麼可能毫髮無傷?太扯了。

    + +

    本來第一次看到第四台片段時,會想找來從頭看。不過多看幾次後冷靜下來,就不想了。

    + +
    + +
    + +
    +
    8.27.’06. 3:36am.
    + +

    努力與天份

    + +

    以前在好幾本勵志書中,都看到過這一句話:成功是 99% 的努力,加上 1% 的天份。

    + +

    這是勵志的書,這樣講的目的,當然是要勉勵讀者勤奮努力,不要因天份過人而自傲,也不要因天份不及人自卑。

    + +

    不過活到現在,經歷這麼多事後,說實話,我覺得應該是:成功是七成的努力,加上三成的天份。才對。

    + +

    任何事,如果沒有天份,光憑努力,大概能做到七十分。不要小看七十分,七十分其實已經很好了。這個世界上,只有三、四十分實力就出來亂闖的,滿街都是。譬如說廚藝,滿街都是隨便學點做煮麵煮米粉就出來擺攤的,東西都做得很隨便,三、四十分左右。只要用心去做,努力去學,比別人認真,同樣一碗麵,就能做到七十分左右,有口碑的美味。能做到七十分,就已經是人群中的佼佼者,足已自傲於世了。

    + +

    但是七十分以上,就不是靠努力就可以達成的。要有天份:對食物的敏銳感,對數字的敏銳感,對邏輯的敏銳感,對音樂的敏銳感,對色彩的敏銳感,對文字的敏銳感。要有這些天生的敏銳感,才能拿到八、九十分以上,做到別人做不到的事,寫出傳頌千古的詩句,唱出繞樑三日的歌聲。還是要有天份,才有可能踏入最後三十分那個一般人再怎麼努力也達不到的領域。

    + +

    不過若是以為只要靠天份就可以了,那就大錯特錯了。若只知依賴天份不知努力,那也不過只有一、二十分,還不及普通人開的麵攤。如果依賴天份和普通人程度的努力,那也只有五、六十分,還是不及沒有天份卻拼命努力向上的人。

    + +

    努力的七十分,只要拼命努力就可以拿到滿分;而天份的三十分,就不是每個人都能夠拿到多少分的了。

    + +
    + +
    + +
    +
    8.27.’06. 1:33am.
    + +

    劉青雲和任達華

    + +

    劉青雲的演技實力,備受肯定。從連續劇大時代 (1992)開始受到注目到現在,收放自如,既可以在大時代背負復仇怒火,在一個字頭的誕生 (1997)同時演糊塗和精明的混混,在暗戰 (1999)裏演聰明正直的警官,在O記三合會檔案 (1999)裏演放蕩不稽的梟雄。這樣利害的演員,竟然從來沒有拿到過影帝?我前幾天從 Wikipedia 上的劉青雲讀到這裏時,訝異得不敢相信。

    + +

    另一個讓我不敢相信的,演技渾熟,卻又從未拿過影帝的,是任達華。前幾天讀到一篇任達華的評論與任達華共舞:兼談舞男系列電影,才知道他也沒拿過影帝。任達華接戲是有點爛,老接一些不入流的三級黑道片,像濠江風雲,使得他的形象多少受到影響,被定位定死了。他自己也承認,他接戲接那麼多是為了賺錢。但他的演技真的沒有話說,收放自如,好人壞人都入木三分,不管要張狂如濠江風雲 (1998)鎗火 (1999)的外弛內張,還是古惑仔 (1996–1999)系列的蔣天生長而有威,演什麼像什麼。這樣的人,竟然沒有拿過影帝,我也不敢相信。

    + +

    任達華在古惑仔 (1996–1999)系列裏演的蔣天生,長而有威,有很獨特的韻味,我差點認不出是他來。他可以演的角色多樣性,讓人非常讚嘆。

    + +

    任達華和徐錦江一樣,是另一個我所知道,螢幕形象和私下個性完全相反的例子。任達華螢幕形象多半殘忍兇狠,但螢幕下是超愛老婆的溫和好人。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 63 | + 64 | + 65 | + 66 | + 67 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0065.html.zh-cn.html b/htdocs/imacat/me/diary/0065.html.zh-cn.html new file mode 120000 index 0000000..89fde5a --- /dev/null +++ b/htdocs/imacat/me/diary/0065.html.zh-cn.html @@ -0,0 +1 @@ +0065.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0065.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0065.html.zh-cn.xhtml new file mode 100644 index 0000000..4907a4f --- /dev/null +++ b/htdocs/imacat/me/diary/0065.html.zh-cn.xhtml @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷六十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷六十五

    + +
    + +
    + +
    +
    8.27.’06. 3:26pm.
    + +

    女打仔

    + +

    好来坞过去几年女打仔当道,拍了一大堆女生当主角的动作片,像Ultraviolet 紫光任务 (2006)Æon Flux 倩影刺客 (2005)Underworld 决战异世界 (2003,2006)等。其中也有很多烂片,像紫光任务

    + +

    前几天在漫画出租店看到,连法国制片卢贝松的TAXI 终极杀阵 (1998)也出女生版了,美国人找女生重拍,叫做Taxi 计程车女王 (2004)。真是太扯了。这种烂片就不用重拍了吧~

    + +
    + +
    + +
    +
    8.27.’06. 1:38pm.
    + +

    绝品好茶

    + +
    +

    试试这瓶茶吧。

    + +

    这种茶不都差不多吗?竟然叫绝品好茶,太夸张了吧!

    + +

    + +

    入口茶香,入喉回韵,不止回甘…绝品!

    + +

    好茶!

    +
    + +

    冲著黄秋生让我流口水的演技,明知道会受骗,我也还是去买了一瓶来喝。喝了以后…

    + +

    …这种茶不都差不多吗?

    + +
    + +
    + +
    +
    8.27.’06. 1:35pm.
    + +

    新警察故事

    + +

    刚才牵机车去换机油时,在机车行看了一小段东森电影台播放的成龙新警察故事 (2004)

    + +

    新警察故事过於滥情,网路上已经骂很多了。我看了一小段,只想说,如果打不死的警察很扯的话,那打不死的匪徒,是不是也很扯?

    + +

    那一小段是匪徒刚抢完银行,在街头的遭遇战。匪徒在大街上摆好阵式,手拿长枪等待,警察一来,双方一阵驳火,警察死伤惨重,匪徒大笑扬身而去。很扯的是,匪徒也是拿车身做掩蔽,掩蔽不比警察好,还有人根本不找掩蔽。就算长枪比短枪强,但双方距离在短枪射程内,差别没有那么大。匪徒怎么可能毫发无伤?太扯了。

    + +

    本来第一次看到第四台片段时,会想找来从头看。不过多看几次后冷静下来,就不想了。

    + +
    + +
    + +
    +
    8.27.’06. 3:36am.
    + +

    努力与天份

    + +

    以前在好几本励志书中,都看到过这一句话:成功是 99% 的努力,加上 1% 的天份。

    + +

    这是励志的书,这样讲的目的,当然是要勉励读者勤奋努力,不要因天份过人而自傲,也不要因天份不及人自卑。

    + +

    不过活到现在,经历这么多事后,说实话,我觉得应该是:成功是七成的努力,加上三成的天份。才对。

    + +

    任何事,如果没有天份,光凭努力,大概能做到七十分。不要小看七十分,七十分其实已经很好了。这个世界上,只有三、四十分实力就出来乱闯的,满街都是。譬如说厨艺,满街都是随便学点做煮面煮米粉就出来摆摊的,东西都做得很随便,三、四十分左右。只要用心去做,努力去学,比别人认真,同样一碗面,就能做到七十分左右,有口碑的美味。能做到七十分,就已经是人群中的佼佼者,足已自傲於世了。

    + +

    但是七十分以上,就不是靠努力就可以达成的。要有天份:对食物的敏锐感,对数字的敏锐感,对逻辑的敏锐感,对音乐的敏锐感,对色彩的敏锐感,对文字的敏锐感。要有这些天生的敏锐感,才能拿到八、九十分以上,做到别人做不到的事,写出传颂千古的诗句,唱出绕梁三日的歌声。还是要有天份,才有可能踏入最后三十分那个一般人再怎么努力也达不到的领域。

    + +

    不过若是以为只要靠天份就可以了,那就大错特错了。若只知依赖天份不知努力,那也不过只有一、二十分,还不及普通人开的面摊。如果依赖天份和普通人程度的努力,那也只有五、六十分,还是不及没有天份却拼命努力向上的人。

    + +

    努力的七十分,只要拼命努力就可以拿到满分;而天份的三十分,就不是每个人都能够拿到多少分的了。

    + +
    + +
    + +
    +
    8.27.’06. 1:33am.
    + +

    刘青云和任达华

    + +

    刘青云的演技实力,备受肯定。从连续剧大时代 (1992)开始受到注目到现在,收放自如,既可以在大时代背负复仇怒火,在一个字头的诞生 (1997)同时演糊涂和精明的混混,在暗战 (1999)里演聪明正直的警官,在O记三合会档案 (1999)里演放荡不稽的枭雄。这样利害的演员,竟然从来没有拿到过影帝?我前几天从 Wikipedia 上的刘青云读到这里时,讶异得不敢相信。

    + +

    另一个让我不敢相信的,演技浑熟,却又从未拿过影帝的,是任达华。前几天读到一篇任达华的评论与任达华共舞:兼谈舞男系列电影,才知道他也没拿过影帝。任达华接戏是有点烂,老接一些不入流的三级黑道片,像濠江风云,使得他的形象多少受到影响,被定位定死了。他自己也承认,他接戏接那么多是为了赚钱。但他的演技真的没有话说,收放自如,好人坏人都入木三分,不管要张狂如濠江风云 (1998)枪火 (1999)的外弛内张,还是古惑仔 (1996–1999)系列的蒋天生长而有威,演什么像什么。这样的人,竟然没有拿过影帝,我也不敢相信。

    + +

    任达华在古惑仔 (1996–1999)系列里演的蒋天生,长而有威,有很独特的韵味,我差点认不出是他来。他可以演的角色多样性,让人非常赞叹。

    + +

    任达华和徐锦江一样,是另一个我所知道,萤幕形象和私下个性完全相反的例子。任达华萤幕形象多半残忍凶狠,但萤幕下是超爱老婆的温和好人。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 63 | + 64 | + 65 | + 66 | + 67 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0065.html.zh-tw.html b/htdocs/imacat/me/diary/0065.html.zh-tw.html new file mode 120000 index 0000000..6baf989 --- /dev/null +++ b/htdocs/imacat/me/diary/0065.html.zh-tw.html @@ -0,0 +1 @@ +0065.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0065.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0065.html.zh-tw.xhtml new file mode 100644 index 0000000..ee57fb4 --- /dev/null +++ b/htdocs/imacat/me/diary/0065.html.zh-tw.xhtml @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷六十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷六十五

    + +
    + +
    + +
    +
    8.27.’06. 3:26pm.
    + +

    女打仔

    + +

    好來塢過去幾年女打仔當道,拍了一大堆女生當主角的動作片,像Ultraviolet 紫光任務 (2006)Æon Flux 倩影刺客 (2005)Underworld 決戰異世界 (2003,2006)等。其中也有很多爛片,像紫光任務

    + +

    前幾天在漫畫出租店看到,連法國製片盧貝松的TAXI 終極殺陣 (1998)也出女生版了,美國人找女生重拍,叫做Taxi 計程車女王 (2004)。真是太扯了。這種爛片就不用重拍了吧~

    + +
    + +
    + +
    +
    8.27.’06. 1:38pm.
    + +

    絕品好茶

    + +
    +

    試試這瓶茶吧。

    + +

    這種茶不都差不多嗎?竟然叫絕品好茶,太誇張了吧!

    + +

    + +

    入口茶香,入喉回韻,不止回甘…絕品!

    + +

    好茶!

    +
    + +

    衝著黃秋生讓我流口水的演技,明知道會受騙,我也還是去買了一瓶來喝。喝了以後…

    + +

    …這種茶不都差不多嗎?

    + +
    + +
    + +
    +
    8.27.’06. 1:35pm.
    + +

    新警察故事

    + +

    剛才牽機車去換機油時,在機車行看了一小段東森電影台播放的成龍新警察故事 (2004)

    + +

    新警察故事過於濫情,網路上已經罵很多了。我看了一小段,只想說,如果打不死的警察很扯的話,那打不死的匪徒,是不是也很扯?

    + +

    那一小段是匪徒剛搶完銀行,在街頭的遭遇戰。匪徒在大街上擺好陣式,手拿長槍等待,警察一來,雙方一陣駁火,警察死傷慘重,匪徒大笑揚身而去。很扯的是,匪徒也是拿車身做掩蔽,掩蔽不比警察好,還有人根本不找掩蔽。就算長槍比短槍強,但雙方距離在短槍射程內,差別沒有那麼大。匪徒怎麼可能毫髮無傷?太扯了。

    + +

    本來第一次看到第四台片段時,會想找來從頭看。不過多看幾次後冷靜下來,就不想了。

    + +
    + +
    + +
    +
    8.27.’06. 3:36am.
    + +

    努力與天份

    + +

    以前在好幾本勵志書中,都看到過這一句話:成功是 99% 的努力,加上 1% 的天份。

    + +

    這是勵志的書,這樣講的目的,當然是要勉勵讀者勤奮努力,不要因天份過人而自傲,也不要因天份不及人自卑。

    + +

    不過活到現在,經歷這麼多事後,說實話,我覺得應該是:成功是七成的努力,加上三成的天份。才對。

    + +

    任何事,如果沒有天份,光憑努力,大概能做到七十分。不要小看七十分,七十分其實已經很好了。這個世界上,只有三、四十分實力就出來亂闖的,滿街都是。譬如說廚藝,滿街都是隨便學點做煮麵煮米粉就出來擺攤的,東西都做得很隨便,三、四十分左右。只要用心去做,努力去學,比別人認真,同樣一碗麵,就能做到七十分左右,有口碑的美味。能做到七十分,就已經是人群中的佼佼者,足已自傲於世了。

    + +

    但是七十分以上,就不是靠努力就可以達成的。要有天份:對食物的敏銳感,對數字的敏銳感,對邏輯的敏銳感,對音樂的敏銳感,對色彩的敏銳感,對文字的敏銳感。要有這些天生的敏銳感,才能拿到八、九十分以上,做到別人做不到的事,寫出傳頌千古的詩句,唱出繞樑三日的歌聲。還是要有天份,才有可能踏入最後三十分那個一般人再怎麼努力也達不到的領域。

    + +

    不過若是以為只要靠天份就可以了,那就大錯特錯了。若只知依賴天份不知努力,那也不過只有一、二十分,還不及普通人開的麵攤。如果依賴天份和普通人程度的努力,那也只有五、六十分,還是不及沒有天份卻拼命努力向上的人。

    + +

    努力的七十分,只要拼命努力就可以拿到滿分;而天份的三十分,就不是每個人都能夠拿到多少分的了。

    + +
    + +
    + +
    +
    8.27.’06. 1:33am.
    + +

    劉青雲和任達華

    + +

    劉青雲的演技實力,備受肯定。從連續劇大時代 (1992)開始受到注目到現在,收放自如,既可以在大時代背負復仇怒火,在一個字頭的誕生 (1997)同時演糊塗和精明的混混,在暗戰 (1999)裏演聰明正直的警官,在O記三合會檔案 (1999)裏演放蕩不稽的梟雄。這樣利害的演員,竟然從來沒有拿到過影帝?我前幾天從 Wikipedia 上的劉青雲讀到這裏時,訝異得不敢相信。

    + +

    另一個讓我不敢相信的,演技渾熟,卻又從未拿過影帝的,是任達華。前幾天讀到一篇任達華的評論與任達華共舞:兼談舞男系列電影,才知道他也沒拿過影帝。任達華接戲是有點爛,老接一些不入流的三級黑道片,像濠江風雲,使得他的形象多少受到影響,被定位定死了。他自己也承認,他接戲接那麼多是為了賺錢。但他的演技真的沒有話說,收放自如,好人壞人都入木三分,不管要張狂如濠江風雲 (1998)鎗火 (1999)的外弛內張,還是古惑仔 (1996–1999)系列的蔣天生長而有威,演什麼像什麼。這樣的人,竟然沒有拿過影帝,我也不敢相信。

    + +

    任達華在古惑仔 (1996–1999)系列裏演的蔣天生,長而有威,有很獨特的韻味,我差點認不出是他來。他可以演的角色多樣性,讓人非常讚嘆。

    + +

    任達華和徐錦江一樣,是另一個我所知道,螢幕形象和私下個性完全相反的例子。任達華螢幕形象多半殘忍兇狠,但螢幕下是超愛老婆的溫和好人。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 63 | + 64 | + 65 | + 66 | + 67 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0066.html.en.html b/htdocs/imacat/me/diary/0066.html.en.html new file mode 120000 index 0000000..017a63a --- /dev/null +++ b/htdocs/imacat/me/diary/0066.html.en.html @@ -0,0 +1 @@ +0066.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0066.html.en.xhtml b/htdocs/imacat/me/diary/0066.html.en.xhtml new file mode 100644 index 0000000..a25bfd8 --- /dev/null +++ b/htdocs/imacat/me/diary/0066.html.en.xhtml @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 66 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 66

    + +
    + +
    + +
    +
    8.27.’06. 3:55pm.
    + +

    電影與英文

    + +

    找到了Kill Bill 追殺比爾 (2003),可是字幕很差,隨便亂譯,和對話對不起來。不得已,只好跑去漫畫店租來看。

    + +

    專業的影視翻譯就是不一樣,網路上隨便的翻譯小隊亂譯的,真是差太多了。

    + +

    我發覺我已經習慣了,看電影的時候,會一邊對照英語對話和中文字幕。如果聽到的英語跟看到的中文,兩邊對不起來,我就會很錯亂。

    + +

    這應該不算炫耀吧~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 64 | + 65 | + 66 | + 67 | + 68 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0066.html.zh-cn.html b/htdocs/imacat/me/diary/0066.html.zh-cn.html new file mode 120000 index 0000000..087c38c --- /dev/null +++ b/htdocs/imacat/me/diary/0066.html.zh-cn.html @@ -0,0 +1 @@ +0066.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0066.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0066.html.zh-cn.xhtml new file mode 100644 index 0000000..befdd1b --- /dev/null +++ b/htdocs/imacat/me/diary/0066.html.zh-cn.xhtml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷六十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷六十六

    + +
    + +
    + +
    +
    8.27.’06. 3:55pm.
    + +

    电影与英文

    + +

    找到了Kill Bill 追杀比尔 (2003),可是字幕很差,随便乱译,和对话对不起来。不得已,只好跑去漫画店租来看。

    + +

    专业的影视翻译就是不一样,网路上随便的翻译小队乱译的,真是差太多了。

    + +

    我发觉我已经习惯了,看电影的时候,会一边对照英语对话和中文字幕。如果听到的英语跟看到的中文,两边对不起来,我就会很错乱。

    + +

    这应该不算炫耀吧~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 64 | + 65 | + 66 | + 67 | + 68 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0066.html.zh-tw.html b/htdocs/imacat/me/diary/0066.html.zh-tw.html new file mode 120000 index 0000000..138a029 --- /dev/null +++ b/htdocs/imacat/me/diary/0066.html.zh-tw.html @@ -0,0 +1 @@ +0066.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0066.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0066.html.zh-tw.xhtml new file mode 100644 index 0000000..0fa7198 --- /dev/null +++ b/htdocs/imacat/me/diary/0066.html.zh-tw.xhtml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷六十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷六十六

    + +
    + +
    + +
    +
    8.27.’06. 3:55pm.
    + +

    電影與英文

    + +

    找到了Kill Bill 追殺比爾 (2003),可是字幕很差,隨便亂譯,和對話對不起來。不得已,只好跑去漫畫店租來看。

    + +

    專業的影視翻譯就是不一樣,網路上隨便的翻譯小隊亂譯的,真是差太多了。

    + +

    我發覺我已經習慣了,看電影的時候,會一邊對照英語對話和中文字幕。如果聽到的英語跟看到的中文,兩邊對不起來,我就會很錯亂。

    + +

    這應該不算炫耀吧~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 64 | + 65 | + 66 | + 67 | + 68 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0067.html.en.html b/htdocs/imacat/me/diary/0067.html.en.html new file mode 120000 index 0000000..b415bdb --- /dev/null +++ b/htdocs/imacat/me/diary/0067.html.en.html @@ -0,0 +1 @@ +0067.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0067.html.en.xhtml b/htdocs/imacat/me/diary/0067.html.en.xhtml new file mode 100644 index 0000000..528d175 --- /dev/null +++ b/htdocs/imacat/me/diary/0067.html.en.xhtml @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 67 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 67

    + +
    + +
    + +
    +
    8.27.’06. 10:40pm.
    + +

    Kill Bill 追殺比爾—中西日大雜燴之超血腥萬里復仇記

    + +
    +Kill Bill Vol. 1 追殺比爾
    +

    Kill Bill Vol. 1 追殺比爾

    +
    + +
    +Kill Bill Vol. 2 追殺比爾二
    +

    Kill Bill Vol. 2 追殺比爾二

    +
    + + + +
    +

    Revenge is a dish best served cold.

    + +
    — Old Kingon Proverb
    +
    + +

    追殺比爾的一和二其實是同一部,因為拍完後片長太長了,到四個多小時,只好切成兩部,分成上下兩集,隔半年分別推出。追殺比爾是昆丁塔倫提諾的第四部電影,前三部分別是:霸道橫行 Reservoir Dogs (1992)黑色追緝令 Pulp Fiction (1994)黑色終結令 Jackie Brown (1997)

    + +

    追殺比爾是一篇長篇復仇記,在復仇記中,又加入每個殺手的深入描寫。女主角碧翠絲原本是致命毒蛇暗殺組織 Deadly Viper Assassination Squad 的殺手,脫離組織想隱姓埋名結婚生子,可是組織還是找上門來,殺了她和教堂所有的人。失去一切的碧翠絲大難不死,昏迷四年醒來後,決定向當年在場所有的組織殺手復仇:百步蛇御蓮、銅頭蛇薇妮塔、小響尾蛇邦德、加州山毒山蛇艾兒和組織頭目比爾。四年後人事已非:御蓮成了東京黑幫瘋狂 88 的大姐大,薇妮塔和她當年一樣隱姓埋名結婚生子,邦德成為酗酒的酒吧保鑣。但不論人事如何變化,血海深仇不能不報。昆丁塔倫提諾試圖表現東方的宿命論,可惜整部戲的喜感,讓人覺得宿命感有所不足。

    + +

    追殺比爾是一部大雜燴,混合了中國功夫、日本刀術、西部風格。就像一鍋什錦火鍋,把昆丁塔倫提諾自己個人最喜歡的元素:李小龍、白眉道長、寸勁、五步穿心指、服部半藏、日本刀、奇門兵器、西部片的音樂、宿命論、極度血腥四肢亂飛,通通丟進去攪一攪,就變成了追殺比爾。也不是說這樣不好,畢竟攪一攪產生了一些特殊的喜感。什錦火鍋也很好吃。可是大雜燴畢竟還是大雜燴,很多東西亂混就走味了,這是避不了的問題。

    + +

    追殺比爾極為血腥。酷好暴力美學的昆丁塔倫提諾用日本刀,把血腥場面發揮到極致。第五章青葉屋的生死決戰,碧翠絲一個人闖入瘋狂 88 宴客的青葉屋,在青葉屋大廳瘋狂砍殺,頭手腳血四處橫飛,全部殺完從二樓一看,整個大廳一片血海,不論是屍體還是僥倖不死的人,全都四肢殘缺不全。這一場戲實在是太瘋狂了,很讓人震懾。這一場的瘋狂 88 嘍囉全都是袁家班的。畫面從碧翠絲在僵持中把對方眼睛挖出來,開始轉成黑白,就這樣直到大戰結束才恢復彩色。聽說轉黑白的原因是太血腥了,可是在日本放映時則為彩色的,不知道是真是假。網路上有人瘋狂在尋找彩色版。不過我覺得黑白也不錯,倒不是怕太血腥,而是黑白效果比較好。有人說黑白是在重塑李小龍功夫舊片的感覺,應該蠻可信的,從碧翠絲一身李小龍的招牌黃色功夫裝就看得出來。昆丁塔倫提諾很明顯是個李小龍迷,很可能會做出這種事。而且轉黑白前的畫面,就已經夠血腥了,轉黑白後的畫面,並沒有比之前更血腥。

    + +

    有人說鄔瑪舒曼在片中素臉上鏡。我覺得這是胡扯。滿臉的擦傷、鮮血、灰土,就是妝了。電影裏並不只有漂漂亮亮的粉才是妝。這是電影,電影的效果都是做出來的,不可能不上妝。

    + +

    碧翠絲坐飛機,千里來去東京那兩幕有點扯。她的刀就放在身邊。坐飛機怎麼可能隨身帶刀?不要講九一一後機場管制加嚴,九一一前就不行了。連行李託運刀具都不行。

    + +

    白眉教碧翠絲的,是李小龍截拳道上的寸勁,也就是詠春的長橋發力。詠春拳在香港流傳甚廣,香港早期功夫片,李小龍、成家班、袁家班打的都是詠春拳。詠春拳的祖師嚴詠春是個女子,為對抗少林拳法,而衍生出一套適合女子練的拳。為對抗少林以長拳為主的拳法,詠春拳以埋身短打為主,重視近距離的互博,而產生出像寸勁一樣的特殊功夫,在極短距離也可以發勁。詳情可參考中國詠春拳學總會網站關於詠春拳拳理的說明。由講廣東話的師父教詠春拳的寸勁,還算蠻合理的。不過除此以外,其它少數出現的拳法,例如碧翠絲和薇妮塔對打,就大多是長拳了。長拳拍起電影比較好看,九七回歸以後,少林長拳也往南影響到袁家班了吧。

    + +

    詠春黐手打起來其實非常好看。兩個人在拳頭可以彼此打得到的近距離高速互搏,像在搶旗一樣快速攻防,真的非常精彩。

    + +

    第一集中,不知道為什麼,一講到女主角的名字,都刻意消音,還很響亮地一長聲,提醒大家主角名字被消音了。直到第二集才清楚女主角叫碧翠絲。有人說這是在塑造東方隱姓埋名的感覺,不過我有點存疑,因為這樣消音不會有半點隱姓埋名的感覺。

    + +

    日本刀和中國刀劍最大的不同處,在於日本刀多用精鋼鑄,除了小太刀外,刀身沉實,重的是一刀斷嶽,每一刀都要集中最大精神和力量,務求一刀斬骨,把對方連劍斬斷。因為太過耗力,交手兩三招就要退下來喘口氣,重新集中精神,無法連續揮個好幾百下。這種刀法發揮到極致就是拔刀術,拔刀的瞬間就要殺敵,沒有第二刀。這和中國劍譜動輒一、二十招,一打起來鏘鏘鏘地打個一兩百招,三百回合才分勝負,是完全不一樣的。每次看武俠漫畫,或武俠電影,中國刀客和日本刀客對決,鏘鏘鏘個三百回合,或是像漫畫中華英雄裏華英雄和無敵一樣打得昏天暗地,連打三天,就覺得很好笑。(如果算連載時間,聽說華英雄和無敵打了快一年。)宮本武藏和佐佐木小次郎在巖流島的決鬥打了一天一夜,不過這是兩個人都集中精神,等待對方的破綻,耗了一天一夜,最後一刀決勝負,而不是鏘鏘鏘打了幾百、幾千招。

    + +

    這一點,碧翠絲攻入青葉屋,三個手下從二樓樓梯下來,碧翠絲四刀三個,清脆俐落,我以為袁家班終於進步了,比較像日本刀法了。可是後來大混戰,和御蓮的決鬥,以及其它場決鬥,就又恢復鏘鏘鏘的中國刀劍打法了,一點都不像日本刀法。致命毒蛇暗殺組織學的是日本刀法,電影理應用日本刀法。像這些細節,可能還是要請日本武師做武術指導,才能夠做得好。多看看日本時代劇,或是學學劍道,對瞭解日本刀法是什麼樣子,也有幫助。

    + +

    不過,鏘鏘鏘的電影視覺效果可能比較好。這就像詠春黐手,逐漸輸給少林長拳一樣。這不是功夫好不好的問題,是娛樂效果的問題。不過這也只是我的猜測啦~又或者是昆丁塔倫提諾分不出來。東方人都長得一模一樣,就像我們也覺得金毛老外都長得差不多一樣。

    + +

    栗山千明演的 GOGO 真的非常突出。瘋狂冷血的十七歲美少女殺手,眼神陰騭冷酷簡直像會殺死人一樣,令人驚豔。我沒想到她會以鍊球做武器。日本的奇門兵器有鎖鍊鐮刀、鍊球…等,都不多見,一般都是長相奇怪的角色在用的。十七歲美少女使鍊球,讓我很意外。不過她使得很漂亮,把鍊球殺傷力強、角度刁鑽、出其不意的特點表現得非常好。不過使得這麼漂亮,也變得不像日本武術,像中國奇門兵器的使法了。她最後被克難狼牙棒釘上,七孔流血的畫面,有點恐怖。雖然七孔流血也不是什麼特別的事,搞不好其它人也有七孔流血,可是其它人被殺都是中長鏡頭,突然換成臉部大特寫,有點突兀。七孔流血是頭部重擊腦內出血的結果,刀殺說起來也不會七孔流血。慢動作看的話,栗山千明好像有張了一下眼皮,算是破綻吧。在眼睛裏化妝塗紅色顏料,大概很辛苦吧。或者這是故意的,死後神經反射,眼皮睜大呢?

    + +

    栗山千明一出場,就非常瘋狂懾人: GOGO 一個人在酒吧喝酒,隔座的中年男子搭訕:

    + +
    +

    妳喜歡法拉利嗎?

    + +

    法拉利?只不過是意大利垃圾。…你想上我是吧?

    + +

    …呵…

    + +

    不准笑,你想上我嗎?想不想?

    + +

    …想。

    + +

    + +

    現在就來吧。怎樣,還想插入我身體?…呵…但你好像…反而被我插進去了耶?

    + +

    刀一拔,鮮血狂噴。

    +
    + +

    懂我的意思了嗎?

    + +

    碧翠絲每殺掉一個仇家,劃掉一個名字,就會出現西部片的配樂。重要的場面,拿出五人名單等等,背景都是西部片的配樂。只有御蓮被殺,背景音樂是日本演歌。

    + +

    不大看得出五步穿心指 Five-Point Palm Exploding Heart Technique的威力。好像是連點心口周圍三個穴道,對心口發一個寸勁,再對心口一個鶴啄。因為這是很早之前的伏筆,後來一直都沒有提,來得很突然,感覺不出它的威力。鶴啄同時就響起西部片的配樂了。觀眾感覺不出威力,算是失敗吧。

    + +

    一開始碧翠絲殺掉薇妮塔後,出來開車,從後面看過去,卡車車尾寫著 Pussy Wagon 。好下流的名字!怎麼主角車子會取這種名字呢?後來看到,醫院下流醫護人員巴克開的卡車,鑰匙圈上就刻著 Pussy Wagon 。原來如此。碧翠絲一看到 Pussy Wagon 的鑰匙圈,就氣得罵一聲爛人,用門重重撞了他的頭。爛人取爛名字。什麼名字嘛!

    + +

    片尾的演員表非常特別,每個演員附上一小段角色的片段,演員名字和劇中的角色名字。平常電影小配角大家都不重視,不仔細看分不出誰是誰。西片還會有演員和角色的名字對照,中片常常沒有對照表,直接一排演員名單就完了。如果覺得哪不認識的演員角色很突出,就要查個老半天。追殺比爾的演員表,感覺很重視每一個大小演員,戲份再少都受尊重。不過反過來說,像一些只有兩個鏡頭的角色,在別的電影根本不會取名字,追殺比爾都取了全名了。取這麼多用不到的名字,不知道會不會很辛苦?還是配角角色的名字丟給演員自己取?

    + +

    碧翠絲的小女兒碧碧好可愛,笑起來真的超甜的。薇妮塔的女兒妮琪也好可愛好漂亮~ *^_^*

    + +

    鑄刀師的名字中譯不對。原文是 Hattori Hanzo ,中譯為八取大師,其實應該是服部半蔵才對。不過有趣的是,服部半蔵德川家康身邊隨扈忍者的名字。日本史上的名鑄刀師應該是村正一族的人。把服部半蔵變身成鑄刀師,有點錯置的感覺,像是昆丁塔倫提諾把自己喜歡的名字任意拿來用一樣。

    + +

    片尾有一個很特別的字幕:

    + +
    Based on the Character
    +The Bride
    +Created by
    +Q&U
    + +

    這裏應該是指新娘這個角色的原創者。但是 Q&U 我看不懂。上網找了以後才知道, Q&U 是指 Quentin Tarantino and Uma Thurman ,新娘碧翠絲這個角色是昆丁塔倫提諾和鄔瑪舒曼,兩個人共同創作的。雖然本來就是如此,角色本來就是編導和演員共同創造出來的,但是這樣強調演員在角色創造過程中扮演的角色,還是讓人覺得很好玩。 ^_*' 有點小曖昧喔,呵呵~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 65 | + 66 | + 67 | + 68 | + 69 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0067.html.zh-cn.html b/htdocs/imacat/me/diary/0067.html.zh-cn.html new file mode 120000 index 0000000..02ac0ce --- /dev/null +++ b/htdocs/imacat/me/diary/0067.html.zh-cn.html @@ -0,0 +1 @@ +0067.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0067.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0067.html.zh-cn.xhtml new file mode 100644 index 0000000..0748932 --- /dev/null +++ b/htdocs/imacat/me/diary/0067.html.zh-cn.xhtml @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷六十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷六十七

    + +
    + +
    + +
    +
    8.27.’06. 10:40pm.
    + +

    Kill Bill 追杀比尔—中西日大杂烩之超血腥万里复仇记

    + +
    +Kill Bill Vol. 1 追杀比尔
    +

    Kill Bill Vol. 1 追杀比尔

    +
    + +
    +Kill Bill Vol. 2 追杀比尔二
    +

    Kill Bill Vol. 2 追杀比尔二

    +
    + + + +
    +

    Revenge is a dish best served cold.

    + +
    — Old Kingon Proverb
    +
    + +

    追杀比尔的一和二其实是同一部,因为拍完后片长太长了,到四个多小时,只好切成两部,分成上下两集,隔半年分别推出。追杀比尔是昆丁塔伦提诺的第四部电影,前三部分别是:霸道横行 Reservoir Dogs (1992)黑色追缉令 Pulp Fiction (1994)黑色终结令 Jackie Brown (1997)

    + +

    追杀比尔是一篇长篇复仇记,在复仇记中,又加入每个杀手的深入描写。女主角碧翠丝原本是致命毒蛇暗杀组织 Deadly Viper Assassination Squad 的杀手,脱离组织想隐姓埋名结婚生子,可是组织还是找上门来,杀了她和教堂所有的人。失去一切的碧翠丝大难不死,昏迷四年醒来后,决定向当年在场所有的组织杀手复仇:百步蛇御莲、铜头蛇薇妮塔、小响尾蛇邦德、加州山毒山蛇艾儿和组织头目比尔。四年后人事已非:御莲成了东京黑帮疯狂 88 的大姐大,薇妮塔和她当年一样隐姓埋名结婚生子,邦德成为酗酒的酒吧保镳。但不论人事如何变化,血海深仇不能不报。昆丁塔伦提诺试图表现东方的宿命论,可惜整部戏的喜感,让人觉得宿命感有所不足。

    + +

    追杀比尔是一部大杂烩,混合了中国功夫、日本刀术、西部风格。就像一锅什锦火锅,把昆丁塔伦提诺自己个人最喜欢的元素:李小龙、白眉道长、寸劲、五步穿心指、服部半藏、日本刀、奇门兵器、西部片的音乐、宿命论、极度血腥四肢乱飞,通通丢进去搅一搅,就变成了追杀比尔。也不是说这样不好,毕竟搅一搅产生了一些特殊的喜感。什锦火锅也很好吃。可是大杂烩毕竟还是大杂烩,很多东西乱混就走味了,这是避不了的问题。

    + +

    追杀比尔极为血腥。酷好暴力美学的昆丁塔伦提诺用日本刀,把血腥场面发挥到极致。第五章青叶屋的生死决战,碧翠丝一个人闯入疯狂 88 宴客的青叶屋,在青叶屋大厅疯狂砍杀,头手脚血四处横飞,全部杀完从二楼一看,整个大厅一片血海,不论是尸体还是侥幸不死的人,全都四肢残缺不全。这一场戏实在是太疯狂了,很让人震慑。这一场的疯狂 88 喽罗全都是袁家班的。画面从碧翠丝在僵持中把对方眼睛挖出来,开始转成黑白,就这样直到大战结束才恢复彩色。听说转黑白的原因是太血腥了,可是在日本放映时则为彩色的,不知道是真是假。网路上有人疯狂在寻找彩色版。不过我觉得黑白也不错,倒不是怕太血腥,而是黑白效果比较好。有人说黑白是在重塑李小龙功夫旧片的感觉,应该蛮可信的,从碧翠丝一身李小龙的招牌黄色功夫装就看得出来。昆丁塔伦提诺很明显是个李小龙迷,很可能会做出这种事。而且转黑白前的画面,就已经够血腥了,转黑白后的画面,并没有比之前更血腥。

    + +

    有人说邬玛舒曼在片中素脸上镜。我觉得这是胡扯。满脸的擦伤、鲜血、灰土,就是妆了。电影里并不只有漂漂亮亮的粉才是妆。这是电影,电影的效果都是做出来的,不可能不上妆。

    + +

    碧翠丝坐飞机,千里来去东京那两幕有点扯。她的刀就放在身边。坐飞机怎么可能随身带刀?不要讲九一一后机场管制加严,九一一前就不行了。连行李托运刀具都不行。

    + +

    白眉教碧翠丝的,是李小龙截拳道上的寸劲,也就是咏春的长桥发力。咏春拳在香港流传甚广,香港早期功夫片,李小龙、成家班、袁家班打的都是咏春拳。咏春拳的祖师严咏春是个女子,为对抗少林拳法,而衍生出一套适合女子练的拳。为对抗少林以长拳为主的拳法,咏春拳以埋身短打为主,重视近距离的互博,而产生出像寸劲一样的特殊功夫,在极短距离也可以发劲。详情可参考中国咏春拳学总会网站关於咏春拳拳理的说明。由讲广东话的师父教咏春拳的寸劲,还算蛮合理的。不过除此以外,其它少数出现的拳法,例如碧翠丝和薇妮塔对打,就大多是长拳了。长拳拍起电影比较好看,九七回归以后,少林长拳也往南影响到袁家班了吧。

    + +

    咏春黐手打起来其实非常好看。两个人在拳头可以彼此打得到的近距离高速互搏,像在抢旗一样快速攻防,真的非常精彩。

    + +

    第一集中,不知道为什么,一讲到女主角的名字,都刻意消音,还很响亮地一长声,提醒大家主角名字被消音了。直到第二集才清楚女主角叫碧翠丝。有人说这是在塑造东方隐姓埋名的感觉,不过我有点存疑,因为这样消音不会有半点隐姓埋名的感觉。

    + +

    日本刀和中国刀剑最大的不同处,在於日本刀多用精钢铸,除了小太刀外,刀身沉实,重的是一刀断岳,每一刀都要集中最大精神和力量,务求一刀斩骨,把对方连剑斩断。因为太过耗力,交手两三招就要退下来喘口气,重新集中精神,无法连续挥个好几百下。这种刀法发挥到极致就是拔刀术,拔刀的瞬间就要杀敌,没有第二刀。这和中国剑谱动辄一、二十招,一打起来锵锵锵地打个一两百招,三百回合才分胜负,是完全不一样的。每次看武侠漫画,或武侠电影,中国刀客和日本刀客对决,锵锵锵个三百回合,或是像漫画中华英雄里华英雄和无敌一样打得昏天暗地,连打三天,就觉得很好笑。(如果算连载时间,听说华英雄和无敌打了快一年。)宫本武藏和佐佐木小次郎在岩流岛的决斗打了一天一夜,不过这是两个人都集中精神,等待对方的破绽,耗了一天一夜,最后一刀决胜负,而不是锵锵锵打了几百、几千招。

    + +

    这一点,碧翠丝攻入青叶屋,三个手下从二楼楼梯下来,碧翠丝四刀三个,清脆俐落,我以为袁家班终於进步了,比较像日本刀法了。可是后来大混战,和御莲的决斗,以及其它场决斗,就又恢复锵锵锵的中国刀剑打法了,一点都不像日本刀法。致命毒蛇暗杀组织学的是日本刀法,电影理应用日本刀法。像这些细节,可能还是要请日本武师做武术指导,才能够做得好。多看看日本时代剧,或是学学剑道,对了解日本刀法是什么样子,也有帮助。

    + +

    不过,锵锵锵的电影视觉效果可能比较好。这就像咏春黐手,逐渐输给少林长拳一样。这不是功夫好不好的问题,是娱乐效果的问题。不过这也只是我的猜测啦~又或者是昆丁塔伦提诺分不出来。东方人都长得一模一样,就像我们也觉得金毛老外都长得差不多一样。

    + +

    栗山千明演的 GOGO 真的非常突出。疯狂冷血的十七岁美少女杀手,眼神阴骘冷酷简直像会杀死人一样,令人惊艳。我没想到她会以炼球做武器。日本的奇门兵器有锁炼镰刀、炼球…等,都不多见,一般都是长相奇怪的角色在用的。十七岁美少女使炼球,让我很意外。不过她使得很漂亮,把炼球杀伤力强、角度刁钻、出其不意的特点表现得非常好。不过使得这么漂亮,也变得不像日本武术,像中国奇门兵器的使法了。她最后被克难狼牙棒钉上,七孔流血的画面,有点恐怖。虽然七孔流血也不是什么特别的事,搞不好其它人也有七孔流血,可是其它人被杀都是中长镜头,突然换成脸部大特写,有点突兀。七孔流血是头部重击脑内出血的结果,刀杀说起来也不会七孔流血。慢动作看的话,栗山千明好像有张了一下眼皮,算是破绽吧。在眼睛里化妆涂红色颜料,大概很辛苦吧。或者这是故意的,死后神经反射,眼皮睁大呢?

    + +

    栗山千明一出场,就非常疯狂慑人: GOGO 一个人在酒吧喝酒,隔座的中年男子搭讪:

    + +
    +

    你喜欢法拉利吗?

    + +

    法拉利?只不过是意大利垃圾。…你想上我是吧?

    + +

    …呵…

    + +

    不准笑,你想上我吗?想不想?

    + +

    …想。

    + +

    + +

    现在就来吧。怎样,还想插入我身体?…呵…但你好像…反而被我插进去了耶?

    + +

    刀一拔,鲜血狂喷。

    +
    + +

    懂我的意思了吗?

    + +

    碧翠丝每杀掉一个仇家,划掉一个名字,就会出现西部片的配乐。重要的场面,拿出五人名单等等,背景都是西部片的配乐。只有御莲被杀,背景音乐是日本演歌。

    + +

    不大看得出五步穿心指 Five-Point Palm Exploding Heart Technique的威力。好像是连点心口周围三个穴道,对心口发一个寸劲,再对心口一个鹤啄。因为这是很早之前的伏笔,后来一直都没有提,来得很突然,感觉不出它的威力。鹤啄同时就响起西部片的配乐了。观众感觉不出威力,算是失败吧。

    + +

    一开始碧翠丝杀掉薇妮塔后,出来开车,从后面看过去,卡车车尾写著 Pussy Wagon 。好下流的名字!怎么主角车子会取这种名字呢?后来看到,医院下流医护人员巴克开的卡车,钥匙圈上就刻著 Pussy Wagon 。原来如此。碧翠丝一看到 Pussy Wagon 的钥匙圈,就气得骂一声烂人,用门重重撞了他的头。烂人取烂名字。什么名字嘛!

    + +

    片尾的演员表非常特别,每个演员附上一小段角色的片段,演员名字和剧中的角色名字。平常电影小配角大家都不重视,不仔细看分不出谁是谁。西片还会有演员和角色的名字对照,中片常常没有对照表,直接一排演员名单就完了。如果觉得哪不认识的演员角色很突出,就要查个老半天。追杀比尔的演员表,感觉很重视每一个大小演员,戏份再少都受尊重。不过反过来说,像一些只有两个镜头的角色,在别的电影根本不会取名字,追杀比尔都取了全名了。取这么多用不到的名字,不知道会不会很辛苦?还是配角角色的名字丢给演员自己取?

    + +

    碧翠丝的小女儿碧碧好可爱,笑起来真的超甜的。薇妮塔的女儿妮琪也好可爱好漂亮~ *^_^*

    + +

    铸刀师的名字中译不对。原文是 Hattori Hanzo ,中译为八取大师,其实应该是服部半蔵才对。不过有趣的是,服部半蔵德川家康身边随扈忍者的名字。日本史上的名铸刀师应该是村正一族的人。把服部半蔵变身成铸刀师,有点错置的感觉,像是昆丁塔伦提诺把自己喜欢的名字任意拿来用一样。

    + +

    片尾有一个很特别的字幕:

    + +
    Based on the Character
    +The Bride
    +Created by
    +Q&U
    + +

    这里应该是指新娘这个角色的原创者。但是 Q&U 我看不懂。上网找了以后才知道, Q&U 是指 Quentin Tarantino and Uma Thurman ,新娘碧翠丝这个角色是昆丁塔伦提诺和邬玛舒曼,两个人共同创作的。虽然本来就是如此,角色本来就是编导和演员共同创造出来的,但是这样强调演员在角色创造过程中扮演的角色,还是让人觉得很好玩。 ^_*' 有点小暧昧喔,呵呵~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 65 | + 66 | + 67 | + 68 | + 69 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0067.html.zh-tw.html b/htdocs/imacat/me/diary/0067.html.zh-tw.html new file mode 120000 index 0000000..0f672ce --- /dev/null +++ b/htdocs/imacat/me/diary/0067.html.zh-tw.html @@ -0,0 +1 @@ +0067.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0067.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0067.html.zh-tw.xhtml new file mode 100644 index 0000000..6b4d6c5 --- /dev/null +++ b/htdocs/imacat/me/diary/0067.html.zh-tw.xhtml @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷六十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷六十七

    + +
    + +
    + +
    +
    8.27.’06. 10:40pm.
    + +

    Kill Bill 追殺比爾—中西日大雜燴之超血腥萬里復仇記

    + +
    +Kill Bill Vol. 1 追殺比爾
    +

    Kill Bill Vol. 1 追殺比爾

    +
    + +
    +Kill Bill Vol. 2 追殺比爾二
    +

    Kill Bill Vol. 2 追殺比爾二

    +
    + + + +
    +

    Revenge is a dish best served cold.

    + +
    — Old Kingon Proverb
    +
    + +

    追殺比爾的一和二其實是同一部,因為拍完後片長太長了,到四個多小時,只好切成兩部,分成上下兩集,隔半年分別推出。追殺比爾是昆丁塔倫提諾的第四部電影,前三部分別是:霸道橫行 Reservoir Dogs (1992)黑色追緝令 Pulp Fiction (1994)黑色終結令 Jackie Brown (1997)

    + +

    追殺比爾是一篇長篇復仇記,在復仇記中,又加入每個殺手的深入描寫。女主角碧翠絲原本是致命毒蛇暗殺組織 Deadly Viper Assassination Squad 的殺手,脫離組織想隱姓埋名結婚生子,可是組織還是找上門來,殺了她和教堂所有的人。失去一切的碧翠絲大難不死,昏迷四年醒來後,決定向當年在場所有的組織殺手復仇:百步蛇御蓮、銅頭蛇薇妮塔、小響尾蛇邦德、加州山毒山蛇艾兒和組織頭目比爾。四年後人事已非:御蓮成了東京黑幫瘋狂 88 的大姐大,薇妮塔和她當年一樣隱姓埋名結婚生子,邦德成為酗酒的酒吧保鑣。但不論人事如何變化,血海深仇不能不報。昆丁塔倫提諾試圖表現東方的宿命論,可惜整部戲的喜感,讓人覺得宿命感有所不足。

    + +

    追殺比爾是一部大雜燴,混合了中國功夫、日本刀術、西部風格。就像一鍋什錦火鍋,把昆丁塔倫提諾自己個人最喜歡的元素:李小龍、白眉道長、寸勁、五步穿心指、服部半藏、日本刀、奇門兵器、西部片的音樂、宿命論、極度血腥四肢亂飛,通通丟進去攪一攪,就變成了追殺比爾。也不是說這樣不好,畢竟攪一攪產生了一些特殊的喜感。什錦火鍋也很好吃。可是大雜燴畢竟還是大雜燴,很多東西亂混就走味了,這是避不了的問題。

    + +

    追殺比爾極為血腥。酷好暴力美學的昆丁塔倫提諾用日本刀,把血腥場面發揮到極致。第五章青葉屋的生死決戰,碧翠絲一個人闖入瘋狂 88 宴客的青葉屋,在青葉屋大廳瘋狂砍殺,頭手腳血四處橫飛,全部殺完從二樓一看,整個大廳一片血海,不論是屍體還是僥倖不死的人,全都四肢殘缺不全。這一場戲實在是太瘋狂了,很讓人震懾。這一場的瘋狂 88 嘍囉全都是袁家班的。畫面從碧翠絲在僵持中把對方眼睛挖出來,開始轉成黑白,就這樣直到大戰結束才恢復彩色。聽說轉黑白的原因是太血腥了,可是在日本放映時則為彩色的,不知道是真是假。網路上有人瘋狂在尋找彩色版。不過我覺得黑白也不錯,倒不是怕太血腥,而是黑白效果比較好。有人說黑白是在重塑李小龍功夫舊片的感覺,應該蠻可信的,從碧翠絲一身李小龍的招牌黃色功夫裝就看得出來。昆丁塔倫提諾很明顯是個李小龍迷,很可能會做出這種事。而且轉黑白前的畫面,就已經夠血腥了,轉黑白後的畫面,並沒有比之前更血腥。

    + +

    有人說鄔瑪舒曼在片中素臉上鏡。我覺得這是胡扯。滿臉的擦傷、鮮血、灰土,就是妝了。電影裏並不只有漂漂亮亮的粉才是妝。這是電影,電影的效果都是做出來的,不可能不上妝。

    + +

    碧翠絲坐飛機,千里來去東京那兩幕有點扯。她的刀就放在身邊。坐飛機怎麼可能隨身帶刀?不要講九一一後機場管制加嚴,九一一前就不行了。連行李託運刀具都不行。

    + +

    白眉教碧翠絲的,是李小龍截拳道上的寸勁,也就是詠春的長橋發力。詠春拳在香港流傳甚廣,香港早期功夫片,李小龍、成家班、袁家班打的都是詠春拳。詠春拳的祖師嚴詠春是個女子,為對抗少林拳法,而衍生出一套適合女子練的拳。為對抗少林以長拳為主的拳法,詠春拳以埋身短打為主,重視近距離的互博,而產生出像寸勁一樣的特殊功夫,在極短距離也可以發勁。詳情可參考中國詠春拳學總會網站關於詠春拳拳理的說明。由講廣東話的師父教詠春拳的寸勁,還算蠻合理的。不過除此以外,其它少數出現的拳法,例如碧翠絲和薇妮塔對打,就大多是長拳了。長拳拍起電影比較好看,九七回歸以後,少林長拳也往南影響到袁家班了吧。

    + +

    詠春黐手打起來其實非常好看。兩個人在拳頭可以彼此打得到的近距離高速互搏,像在搶旗一樣快速攻防,真的非常精彩。

    + +

    第一集中,不知道為什麼,一講到女主角的名字,都刻意消音,還很響亮地一長聲,提醒大家主角名字被消音了。直到第二集才清楚女主角叫碧翠絲。有人說這是在塑造東方隱姓埋名的感覺,不過我有點存疑,因為這樣消音不會有半點隱姓埋名的感覺。

    + +

    日本刀和中國刀劍最大的不同處,在於日本刀多用精鋼鑄,除了小太刀外,刀身沉實,重的是一刀斷嶽,每一刀都要集中最大精神和力量,務求一刀斬骨,把對方連劍斬斷。因為太過耗力,交手兩三招就要退下來喘口氣,重新集中精神,無法連續揮個好幾百下。這種刀法發揮到極致就是拔刀術,拔刀的瞬間就要殺敵,沒有第二刀。這和中國劍譜動輒一、二十招,一打起來鏘鏘鏘地打個一兩百招,三百回合才分勝負,是完全不一樣的。每次看武俠漫畫,或武俠電影,中國刀客和日本刀客對決,鏘鏘鏘個三百回合,或是像漫畫中華英雄裏華英雄和無敵一樣打得昏天暗地,連打三天,就覺得很好笑。(如果算連載時間,聽說華英雄和無敵打了快一年。)宮本武藏和佐佐木小次郎在巖流島的決鬥打了一天一夜,不過這是兩個人都集中精神,等待對方的破綻,耗了一天一夜,最後一刀決勝負,而不是鏘鏘鏘打了幾百、幾千招。

    + +

    這一點,碧翠絲攻入青葉屋,三個手下從二樓樓梯下來,碧翠絲四刀三個,清脆俐落,我以為袁家班終於進步了,比較像日本刀法了。可是後來大混戰,和御蓮的決鬥,以及其它場決鬥,就又恢復鏘鏘鏘的中國刀劍打法了,一點都不像日本刀法。致命毒蛇暗殺組織學的是日本刀法,電影理應用日本刀法。像這些細節,可能還是要請日本武師做武術指導,才能夠做得好。多看看日本時代劇,或是學學劍道,對瞭解日本刀法是什麼樣子,也有幫助。

    + +

    不過,鏘鏘鏘的電影視覺效果可能比較好。這就像詠春黐手,逐漸輸給少林長拳一樣。這不是功夫好不好的問題,是娛樂效果的問題。不過這也只是我的猜測啦~又或者是昆丁塔倫提諾分不出來。東方人都長得一模一樣,就像我們也覺得金毛老外都長得差不多一樣。

    + +

    栗山千明演的 GOGO 真的非常突出。瘋狂冷血的十七歲美少女殺手,眼神陰騭冷酷簡直像會殺死人一樣,令人驚豔。我沒想到她會以鍊球做武器。日本的奇門兵器有鎖鍊鐮刀、鍊球…等,都不多見,一般都是長相奇怪的角色在用的。十七歲美少女使鍊球,讓我很意外。不過她使得很漂亮,把鍊球殺傷力強、角度刁鑽、出其不意的特點表現得非常好。不過使得這麼漂亮,也變得不像日本武術,像中國奇門兵器的使法了。她最後被克難狼牙棒釘上,七孔流血的畫面,有點恐怖。雖然七孔流血也不是什麼特別的事,搞不好其它人也有七孔流血,可是其它人被殺都是中長鏡頭,突然換成臉部大特寫,有點突兀。七孔流血是頭部重擊腦內出血的結果,刀殺說起來也不會七孔流血。慢動作看的話,栗山千明好像有張了一下眼皮,算是破綻吧。在眼睛裏化妝塗紅色顏料,大概很辛苦吧。或者這是故意的,死後神經反射,眼皮睜大呢?

    + +

    栗山千明一出場,就非常瘋狂懾人: GOGO 一個人在酒吧喝酒,隔座的中年男子搭訕:

    + +
    +

    妳喜歡法拉利嗎?

    + +

    法拉利?只不過是意大利垃圾。…你想上我是吧?

    + +

    …呵…

    + +

    不准笑,你想上我嗎?想不想?

    + +

    …想。

    + +

    + +

    現在就來吧。怎樣,還想插入我身體?…呵…但你好像…反而被我插進去了耶?

    + +

    刀一拔,鮮血狂噴。

    +
    + +

    懂我的意思了嗎?

    + +

    碧翠絲每殺掉一個仇家,劃掉一個名字,就會出現西部片的配樂。重要的場面,拿出五人名單等等,背景都是西部片的配樂。只有御蓮被殺,背景音樂是日本演歌。

    + +

    不大看得出五步穿心指 Five-Point Palm Exploding Heart Technique的威力。好像是連點心口周圍三個穴道,對心口發一個寸勁,再對心口一個鶴啄。因為這是很早之前的伏筆,後來一直都沒有提,來得很突然,感覺不出它的威力。鶴啄同時就響起西部片的配樂了。觀眾感覺不出威力,算是失敗吧。

    + +

    一開始碧翠絲殺掉薇妮塔後,出來開車,從後面看過去,卡車車尾寫著 Pussy Wagon 。好下流的名字!怎麼主角車子會取這種名字呢?後來看到,醫院下流醫護人員巴克開的卡車,鑰匙圈上就刻著 Pussy Wagon 。原來如此。碧翠絲一看到 Pussy Wagon 的鑰匙圈,就氣得罵一聲爛人,用門重重撞了他的頭。爛人取爛名字。什麼名字嘛!

    + +

    片尾的演員表非常特別,每個演員附上一小段角色的片段,演員名字和劇中的角色名字。平常電影小配角大家都不重視,不仔細看分不出誰是誰。西片還會有演員和角色的名字對照,中片常常沒有對照表,直接一排演員名單就完了。如果覺得哪不認識的演員角色很突出,就要查個老半天。追殺比爾的演員表,感覺很重視每一個大小演員,戲份再少都受尊重。不過反過來說,像一些只有兩個鏡頭的角色,在別的電影根本不會取名字,追殺比爾都取了全名了。取這麼多用不到的名字,不知道會不會很辛苦?還是配角角色的名字丟給演員自己取?

    + +

    碧翠絲的小女兒碧碧好可愛,笑起來真的超甜的。薇妮塔的女兒妮琪也好可愛好漂亮~ *^_^*

    + +

    鑄刀師的名字中譯不對。原文是 Hattori Hanzo ,中譯為八取大師,其實應該是服部半蔵才對。不過有趣的是,服部半蔵德川家康身邊隨扈忍者的名字。日本史上的名鑄刀師應該是村正一族的人。把服部半蔵變身成鑄刀師,有點錯置的感覺,像是昆丁塔倫提諾把自己喜歡的名字任意拿來用一樣。

    + +

    片尾有一個很特別的字幕:

    + +
    Based on the Character
    +The Bride
    +Created by
    +Q&U
    + +

    這裏應該是指新娘這個角色的原創者。但是 Q&U 我看不懂。上網找了以後才知道, Q&U 是指 Quentin Tarantino and Uma Thurman ,新娘碧翠絲這個角色是昆丁塔倫提諾和鄔瑪舒曼,兩個人共同創作的。雖然本來就是如此,角色本來就是編導和演員共同創造出來的,但是這樣強調演員在角色創造過程中扮演的角色,還是讓人覺得很好玩。 ^_*' 有點小曖昧喔,呵呵~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 65 | + 66 | + 67 | + 68 | + 69 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0068.html.en.html b/htdocs/imacat/me/diary/0068.html.en.html new file mode 120000 index 0000000..599ee56 --- /dev/null +++ b/htdocs/imacat/me/diary/0068.html.en.html @@ -0,0 +1 @@ +0068.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0068.html.en.xhtml b/htdocs/imacat/me/diary/0068.html.en.xhtml new file mode 100644 index 0000000..278de63 --- /dev/null +++ b/htdocs/imacat/me/diary/0068.html.en.xhtml @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 68 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 68

    + +
    + +
    + +
    +
    8.31.’06. 12:49pm.
    + +

    電影 NANAENDLESS STORY 的鋼琴

    + +

    這幾天我上班時,耳機音樂都聽電影 NANA 的主題曲,中島美嘉唱的 GLAMOROUS SKY伊藤由奈唱的 ENDLESS STORY 。今天突然心血來潮,把耳機音量調大,閉起眼睛仔細聆聽全部的音樂:歌聲、吉他、貝斯、鼓、鋼琴、編曲…鋼琴? ^^;

    + +

    唔,這真是好大的一個問題~ ENDLESS STORY 的主旋律是鋼琴,可是 ENDLESS STORYTRAPNEST 主唱 REIRA 的歌, TRAPNEST 是流行搖滾樂團,和一般搖滾樂團一樣,只有吉他手、貝斯手跟鼓手。哪裏來的鋼琴? ^^; 而且還是主旋律耶。沒有鋼琴手的樂團,怎麼可能寫出一首以鋼琴作主旋律的曲子?

    + +

    仔細聽,伴奏好像是低音提琴。低音提琴? ^^;

    + +

    好離譜的破綻。怎麼都沒有人注意到這個問題呢?

    + +
    + +
    + +
    +
    8.30.’06. 5:10pm.
    + +

    半途而廢

    + +

    最近,總覺得事情不順,很煩。是生理期嗎? :p

    + +

    想看的電影清單,至少還有 15 部沒有看。可是週末要期考了,只好停下來。考玩接下來要回家,全家出國旅遊一週,回頭看至少也是兩個星期以後的事了。 15 部電影,大約也要十天才看得完。

    + +

    除了電影,遊戲也一樣。柏德之門資料片劍灣傳奇萬夫莫敵—聖女傳,都玩到一半,接下來不知道什麼時候才玩得完。創世紀七第二部巨蛇之島也是,上學期玩到期末考停下來,不知道何時才會再開始。再往前看,歷史理論與文化網站期刊管理系統、旅舍網頁管理的圖片上傳、 SSL 教學的英譯、 arclog 的改版…這麼多事,都做到一半,不知道什麼時候,才會做完,完工遙遙無期。

    + +

    很討厭這樣,什麼事情都做一半,沒有辦法好好把一件事做好。每件事都留個尾,留個遺憾。我不想要半途而廢。可是,光是不想半途而廢,已經是很奢侈、遙不可及的願望了。我只是不想當半調子,想把一件事好好做好,有始有終。求的不過是有始有終四個字,真的那麼難嗎?

    + +
    + +
    + +
    +
    8.30.’06. 5:02pm.
    + +

    看電影的速度

    + +

    很久很久以前,我曾經有過一天看六部電影的記錄。

    + +

    那時候一天看六部電影,看得昏天暗地的,頭也開始痛。那時候看的電影,現在已經不記得了。

    + +

    最近看電影,就算放假在家,我頂多只能看三部。我開始覺得是不是我老了看不動了。不過現在看電影,我還會記錄看了什麼片,做自己的筆記,整理自己看的心得。多了這層消化吸收的時間,看得比較慢也不會奇怪。反過來說,以前那樣拼命看,很多感想都來不及消化吸收,也許浪費了不少好電影。

    + +
    + +
    + +
    +
    8.28.’06. 2:34pm.
    + +

    會讓我轉台時停下來看的演員

    + +

    有幾個人的演技,是讓我隨手轉第四台電影台時,看到他們的臉,就會停下來看的:

    + +
      +
    • 劉青雲
    • + +
    • 黃秋生
    • + +
    • 吳鎮宇
    • +
    + +

    光看他們演戲,就是一種享受。他們的臉對我而言,就是演技好看的最佳保證。

    + +

    昨天半夜打開電視,隨手看到吳鎮宇的神經俠侶 (2005),忍不住又停下來看。吳鎮宇演一個離過婚、失業、有點精神分裂的王成,認識同樣離過婚的按摩女菲菲,展開一段新的關係,努力想跟菲菲從頭開始做好日子。一個有點精神分裂又很拼命努力過日子的失業漢,又讓我看到吳鎮宇演技的另一面,讓我覺得好酷,也好感動。

    + +

    任達華演技也很好,不過他演的電影八成是爛片,所以就不會想看了。

    + +
    + +
    + +
    +
    8.28.’06. 4:20am.
    + +

    安全別針穿孔

    + +

    想想,真的有人像漫畫 NANA 裏的真一,或是天堂之吻裏的一樣,在嘴唇上用安全別針穿孔的嗎?

    + +

    沒實地看過照片,很難想像說。

    + +
    + +
    + +
    +
    8.28.’06. 4:07am.
    + +

    暫停看電影

    + +

    下週末暑修要期末考,電影看樣子沒辦法繼續看下去了。雖然還找到好幾部電影,待看清單還很長,不過要暫停下來好一陣子了。

    + +

    唉,每次都這樣。不管做什麼事,都很難有始有終,常常半途而廢。感覺超不好的~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 66 | + 67 | + 68 | + 69 | + 70 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0068.html.zh-cn.html b/htdocs/imacat/me/diary/0068.html.zh-cn.html new file mode 120000 index 0000000..e21adef --- /dev/null +++ b/htdocs/imacat/me/diary/0068.html.zh-cn.html @@ -0,0 +1 @@ +0068.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0068.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0068.html.zh-cn.xhtml new file mode 100644 index 0000000..b098941 --- /dev/null +++ b/htdocs/imacat/me/diary/0068.html.zh-cn.xhtml @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷六十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷六十八

    + +
    + +
    + +
    +
    8.31.’06. 12:49pm.
    + +

    电影 NANAENDLESS STORY 的钢琴

    + +

    这几天我上班时,耳机音乐都听电影 NANA 的主题曲,中岛美嘉唱的 GLAMOROUS SKY伊藤由奈唱的 ENDLESS STORY 。今天突然心血来潮,把耳机音量调大,闭起眼睛仔细聆听全部的音乐:歌声、吉他、贝斯、鼓、钢琴、编曲…钢琴? ^^;

    + +

    唔,这真是好大的一个问题~ ENDLESS STORY 的主旋律是钢琴,可是 ENDLESS STORYTRAPNEST 主唱 REIRA 的歌, TRAPNEST 是流行摇滚乐团,和一般摇滚乐团一样,只有吉他手、贝斯手跟鼓手。哪里来的钢琴? ^^; 而且还是主旋律耶。没有钢琴手的乐团,怎么可能写出一首以钢琴作主旋律的曲子?

    + +

    仔细听,伴奏好像是低音提琴。低音提琴? ^^;

    + +

    好离谱的破绽。怎么都没有人注意到这个问题呢?

    + +
    + +
    + +
    +
    8.30.’06. 5:10pm.
    + +

    半途而废

    + +

    最近,总觉得事情不顺,很烦。是生理期吗? :p

    + +

    想看的电影清单,至少还有 15 部没有看。可是周末要期考了,只好停下来。考玩接下来要回家,全家出国旅游一周,回头看至少也是两个星期以后的事了。 15 部电影,大约也要十天才看得完。

    + +

    除了电影,游戏也一样。柏德之门资料片剑湾传奇万夫莫敌—圣女传,都玩到一半,接下来不知道什么时候才玩得完。创世纪七第二部巨蛇之岛也是,上学期玩到期末考停下来,不知道何时才会再开始。再往前看,历史理论与文化网站期刊管理系统、旅舍网页管理的图片上传、 SSL 教学的英译、 arclog 的改版…这么多事,都做到一半,不知道什么时候,才会做完,完工遥遥无期。

    + +

    很讨厌这样,什么事情都做一半,没有办法好好把一件事做好。每件事都留个尾,留个遗憾。我不想要半途而废。可是,光是不想半途而废,已经是很奢侈、遥不可及的愿望了。我只是不想当半调子,想把一件事好好做好,有始有终。求的不过是有始有终四个字,真的那么难吗?

    + +
    + +
    + +
    +
    8.30.’06. 5:02pm.
    + +

    看电影的速度

    + +

    很久很久以前,我曾经有过一天看六部电影的记录。

    + +

    那时候一天看六部电影,看得昏天暗地的,头也开始痛。那时候看的电影,现在已经不记得了。

    + +

    最近看电影,就算放假在家,我顶多只能看三部。我开始觉得是不是我老了看不动了。不过现在看电影,我还会记录看了什么片,做自己的笔记,整理自己看的心得。多了这层消化吸收的时间,看得比较慢也不会奇怪。反过来说,以前那样拼命看,很多感想都来不及消化吸收,也许浪费了不少好电影。

    + +
    + +
    + +
    +
    8.28.’06. 2:34pm.
    + +

    会让我转台时停下来看的演员

    + +

    有几个人的演技,是让我随手转第四台电影台时,看到他们的脸,就会停下来看的:

    + +
      +
    • 刘青云
    • + +
    • 黄秋生
    • + +
    • 吴镇宇
    • +
    + +

    光看他们演戏,就是一种享受。他们的脸对我而言,就是演技好看的最佳保证。

    + +

    昨天半夜打开电视,随手看到吴镇宇的神经侠侣 (2005),忍不住又停下来看。吴镇宇演一个离过婚、失业、有点精神分裂的王成,认识同样离过婚的按摩女菲菲,展开一段新的关系,努力想跟菲菲从头开始做好日子。一个有点精神分裂又很拼命努力过日子的失业汉,又让我看到吴镇宇演技的另一面,让我觉得好酷,也好感动。

    + +

    任达华演技也很好,不过他演的电影八成是烂片,所以就不会想看了。

    + +
    + +
    + +
    +
    8.28.’06. 4:20am.
    + +

    安全别针穿孔

    + +

    想想,真的有人像漫画 NANA 里的真一,或是天堂之吻里的一样,在嘴唇上用安全别针穿孔的吗?

    + +

    没实地看过照片,很难想像说。

    + +
    + +
    + +
    +
    8.28.’06. 4:07am.
    + +

    暂停看电影

    + +

    下周末暑修要期末考,电影看样子没办法继续看下去了。虽然还找到好几部电影,待看清单还很长,不过要暂停下来好一阵子了。

    + +

    唉,每次都这样。不管做什么事,都很难有始有终,常常半途而废。感觉超不好的~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 66 | + 67 | + 68 | + 69 | + 70 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0068.html.zh-tw.html b/htdocs/imacat/me/diary/0068.html.zh-tw.html new file mode 120000 index 0000000..296b812 --- /dev/null +++ b/htdocs/imacat/me/diary/0068.html.zh-tw.html @@ -0,0 +1 @@ +0068.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0068.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0068.html.zh-tw.xhtml new file mode 100644 index 0000000..7ad7299 --- /dev/null +++ b/htdocs/imacat/me/diary/0068.html.zh-tw.xhtml @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷六十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷六十八

    + +
    + +
    + +
    +
    8.31.’06. 12:49pm.
    + +

    電影 NANAENDLESS STORY 的鋼琴

    + +

    這幾天我上班時,耳機音樂都聽電影 NANA 的主題曲,中島美嘉唱的 GLAMOROUS SKY伊藤由奈唱的 ENDLESS STORY 。今天突然心血來潮,把耳機音量調大,閉起眼睛仔細聆聽全部的音樂:歌聲、吉他、貝斯、鼓、鋼琴、編曲…鋼琴? ^^;

    + +

    唔,這真是好大的一個問題~ ENDLESS STORY 的主旋律是鋼琴,可是 ENDLESS STORYTRAPNEST 主唱 REIRA 的歌, TRAPNEST 是流行搖滾樂團,和一般搖滾樂團一樣,只有吉他手、貝斯手跟鼓手。哪裏來的鋼琴? ^^; 而且還是主旋律耶。沒有鋼琴手的樂團,怎麼可能寫出一首以鋼琴作主旋律的曲子?

    + +

    仔細聽,伴奏好像是低音提琴。低音提琴? ^^;

    + +

    好離譜的破綻。怎麼都沒有人注意到這個問題呢?

    + +
    + +
    + +
    +
    8.30.’06. 5:10pm.
    + +

    半途而廢

    + +

    最近,總覺得事情不順,很煩。是生理期嗎? :p

    + +

    想看的電影清單,至少還有 15 部沒有看。可是週末要期考了,只好停下來。考玩接下來要回家,全家出國旅遊一週,回頭看至少也是兩個星期以後的事了。 15 部電影,大約也要十天才看得完。

    + +

    除了電影,遊戲也一樣。柏德之門資料片劍灣傳奇萬夫莫敵—聖女傳,都玩到一半,接下來不知道什麼時候才玩得完。創世紀七第二部巨蛇之島也是,上學期玩到期末考停下來,不知道何時才會再開始。再往前看,歷史理論與文化網站期刊管理系統、旅舍網頁管理的圖片上傳、 SSL 教學的英譯、 arclog 的改版…這麼多事,都做到一半,不知道什麼時候,才會做完,完工遙遙無期。

    + +

    很討厭這樣,什麼事情都做一半,沒有辦法好好把一件事做好。每件事都留個尾,留個遺憾。我不想要半途而廢。可是,光是不想半途而廢,已經是很奢侈、遙不可及的願望了。我只是不想當半調子,想把一件事好好做好,有始有終。求的不過是有始有終四個字,真的那麼難嗎?

    + +
    + +
    + +
    +
    8.30.’06. 5:02pm.
    + +

    看電影的速度

    + +

    很久很久以前,我曾經有過一天看六部電影的記錄。

    + +

    那時候一天看六部電影,看得昏天暗地的,頭也開始痛。那時候看的電影,現在已經不記得了。

    + +

    最近看電影,就算放假在家,我頂多只能看三部。我開始覺得是不是我老了看不動了。不過現在看電影,我還會記錄看了什麼片,做自己的筆記,整理自己看的心得。多了這層消化吸收的時間,看得比較慢也不會奇怪。反過來說,以前那樣拼命看,很多感想都來不及消化吸收,也許浪費了不少好電影。

    + +
    + +
    + +
    +
    8.28.’06. 2:34pm.
    + +

    會讓我轉台時停下來看的演員

    + +

    有幾個人的演技,是讓我隨手轉第四台電影台時,看到他們的臉,就會停下來看的:

    + +
      +
    • 劉青雲
    • + +
    • 黃秋生
    • + +
    • 吳鎮宇
    • +
    + +

    光看他們演戲,就是一種享受。他們的臉對我而言,就是演技好看的最佳保證。

    + +

    昨天半夜打開電視,隨手看到吳鎮宇的神經俠侶 (2005),忍不住又停下來看。吳鎮宇演一個離過婚、失業、有點精神分裂的王成,認識同樣離過婚的按摩女菲菲,展開一段新的關係,努力想跟菲菲從頭開始做好日子。一個有點精神分裂又很拼命努力過日子的失業漢,又讓我看到吳鎮宇演技的另一面,讓我覺得好酷,也好感動。

    + +

    任達華演技也很好,不過他演的電影八成是爛片,所以就不會想看了。

    + +
    + +
    + +
    +
    8.28.’06. 4:20am.
    + +

    安全別針穿孔

    + +

    想想,真的有人像漫畫 NANA 裏的真一,或是天堂之吻裏的一樣,在嘴唇上用安全別針穿孔的嗎?

    + +

    沒實地看過照片,很難想像說。

    + +
    + +
    + +
    +
    8.28.’06. 4:07am.
    + +

    暫停看電影

    + +

    下週末暑修要期末考,電影看樣子沒辦法繼續看下去了。雖然還找到好幾部電影,待看清單還很長,不過要暫停下來好一陣子了。

    + +

    唉,每次都這樣。不管做什麼事,都很難有始有終,常常半途而廢。感覺超不好的~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 66 | + 67 | + 68 | + 69 | + 70 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0069.html.en.html b/htdocs/imacat/me/diary/0069.html.en.html new file mode 120000 index 0000000..185fc9f --- /dev/null +++ b/htdocs/imacat/me/diary/0069.html.en.html @@ -0,0 +1 @@ +0069.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0069.html.en.xhtml b/htdocs/imacat/me/diary/0069.html.en.xhtml new file mode 100644 index 0000000..a926af6 --- /dev/null +++ b/htdocs/imacat/me/diary/0069.html.en.xhtml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 69 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 69

    + +
    + +
    + +
    +
    9.13.’06. 4:25am.
    + +

    タッチ Touch 鄰家女孩—大螢幕上的あだち充(安達充)

    + +
    +タッチ Touch 鄰家女孩
    +

    タッチ Touch 鄰家女孩

    +
    + +
      +
    • 片名:タッチ
    • +
    • 英文片名: Touch
    • +
    • 中譯片名:鄰家女孩
    • +
    • 發行年份: 2005
    • +
    • 製作公司:東宝映画
    • +
    • 導演:犬童一心
    • +
    • 原作:あだち充(安達充)タッチ(小学館)
    • +
    • 演員: +
        +
      • 浅倉南:長澤まさみ(長澤雅美)(在世界中心呼喊愛情)
      • +
      • 上杉達也:斉藤祥太(孩子們的戰爭)
      • +
      • 上杉和也:斉藤慶太(孩子們的戰爭)
      • +
      • 原田正平: RIKIYA
      • +
      • 松平孝太郎:平塚真介
      • +
      +
    • +
    + +

    我已經幾乎忘了原著漫畫鄰家女孩的劇情了。去租的 DVD ,沒想到竟然是簡體中文的字幕,很多用詞都看不習慣。真討厭。

    + +

    上杉達也上杉和也是一對雙胞胎,和隔壁家的浅倉南從小三個人一起長大。兩家大人感情很好,愛看棒球。從小耳濡目染,三人也把甲子園當成目標。可是浅倉南是女生無法進去甲子園,因此把希望寄托在兩兄弟身上。上了高中,進了棒球隊當經理,弟弟達也也進棒球隊,努力成為王牌投手,哥哥和也卻仍然吊兒啷噹,一天到晚換社團,做什麼都半途而廢。三個人的感情關係,也隨著悄悄地產生變化。

    + +

    在幾乎不記得原著劇情的情況下,還蠻好看的。あだち充特有的宿命與無常,小人物面對命運的掙札,故作輕鬆的姿態,都表達得非常完美。兩個小時的電影,要演出三十幾集的劇情,本來就會有所刪節。有一部份沒有忠於原著漫畫,略為修改,不過仍然把あだち充的味道表現得很好。

    + +

    有一幕兩兄弟在搶電視遊樂器,畫面中出現的 3D 的戰鬥畫面。二十年前あだち充鄰家女孩時,電視遊樂器裏的遊戲應該不是這個樣子的吧,哈~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 67 | + 68 | + 69 | + 70 | + 71 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0069.html.zh-cn.html b/htdocs/imacat/me/diary/0069.html.zh-cn.html new file mode 120000 index 0000000..57931e5 --- /dev/null +++ b/htdocs/imacat/me/diary/0069.html.zh-cn.html @@ -0,0 +1 @@ +0069.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0069.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0069.html.zh-cn.xhtml new file mode 100644 index 0000000..2f83147 --- /dev/null +++ b/htdocs/imacat/me/diary/0069.html.zh-cn.xhtml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷六十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷六十九

    + +
    + +
    + +
    +
    9.13.’06. 4:25am.
    + +

    タッチ Touch 邻家女孩—大萤幕上的あだち充(安达充)

    + +
    +タッチ Touch 邻家女孩
    +

    タッチ Touch 邻家女孩

    +
    + +
      +
    • 片名:タッチ
    • +
    • 英文片名: Touch
    • +
    • 中译片名:邻家女孩
    • +
    • 发行年份: 2005
    • +
    • 制作公司:东宝映画
    • +
    • 导演:犬童一心
    • +
    • 原作:あだち充(安达充)タッチ(小学馆)
    • +
    • 演员: +
        +
      • 浅仓南:长泽まさみ(长泽雅美)(在世界中心呼喊爱情)
      • +
      • 上杉达也:斉藤祥太(孩子们的战争)
      • +
      • 上杉和也:斉藤庆太(孩子们的战争)
      • +
      • 原田正平: RIKIYA
      • +
      • 松平孝太郎:平冢真介
      • +
      +
    • +
    + +

    我已经几乎忘了原著漫画邻家女孩的剧情了。去租的 DVD ,没想到竟然是简体中文的字幕,很多用词都看不习惯。真讨厌。

    + +

    上杉达也上杉和也是一对双胞胎,和隔壁家的浅仓南从小三个人一起长大。两家大人感情很好,爱看棒球。从小耳濡目染,三人也把甲子园当成目标。可是浅仓南是女生无法进去甲子园,因此把希望寄托在两兄弟身上。上了高中,进了棒球队当经理,弟弟达也也进棒球队,努力成为王牌投手,哥哥和也却仍然吊儿啷当,一天到晚换社团,做什么都半途而废。三个人的感情关系,也随著悄悄地产生变化。

    + +

    在几乎不记得原著剧情的情况下,还蛮好看的。あだち充特有的宿命与无常,小人物面对命运的挣札,故作轻松的姿态,都表达得非常完美。两个小时的电影,要演出三十几集的剧情,本来就会有所删节。有一部份没有忠於原著漫画,略为修改,不过仍然把あだち充的味道表现得很好。

    + +

    有一幕两兄弟在抢电视游乐器,画面中出现的 3D 的战斗画面。二十年前あだち充邻家女孩时,电视游乐器里的游戏应该不是这个样子的吧,哈~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 67 | + 68 | + 69 | + 70 | + 71 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0069.html.zh-tw.html b/htdocs/imacat/me/diary/0069.html.zh-tw.html new file mode 120000 index 0000000..363f25b --- /dev/null +++ b/htdocs/imacat/me/diary/0069.html.zh-tw.html @@ -0,0 +1 @@ +0069.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0069.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0069.html.zh-tw.xhtml new file mode 100644 index 0000000..39987bc --- /dev/null +++ b/htdocs/imacat/me/diary/0069.html.zh-tw.xhtml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷六十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷六十九

    + +
    + +
    + +
    +
    9.13.’06. 4:25am.
    + +

    タッチ Touch 鄰家女孩—大螢幕上的あだち充(安達充)

    + +
    +タッチ Touch 鄰家女孩
    +

    タッチ Touch 鄰家女孩

    +
    + +
      +
    • 片名:タッチ
    • +
    • 英文片名: Touch
    • +
    • 中譯片名:鄰家女孩
    • +
    • 發行年份: 2005
    • +
    • 製作公司:東宝映画
    • +
    • 導演:犬童一心
    • +
    • 原作:あだち充(安達充)タッチ(小学館)
    • +
    • 演員: +
        +
      • 浅倉南:長澤まさみ(長澤雅美)(在世界中心呼喊愛情)
      • +
      • 上杉達也:斉藤祥太(孩子們的戰爭)
      • +
      • 上杉和也:斉藤慶太(孩子們的戰爭)
      • +
      • 原田正平: RIKIYA
      • +
      • 松平孝太郎:平塚真介
      • +
      +
    • +
    + +

    我已經幾乎忘了原著漫畫鄰家女孩的劇情了。去租的 DVD ,沒想到竟然是簡體中文的字幕,很多用詞都看不習慣。真討厭。

    + +

    上杉達也上杉和也是一對雙胞胎,和隔壁家的浅倉南從小三個人一起長大。兩家大人感情很好,愛看棒球。從小耳濡目染,三人也把甲子園當成目標。可是浅倉南是女生無法進去甲子園,因此把希望寄托在兩兄弟身上。上了高中,進了棒球隊當經理,弟弟達也也進棒球隊,努力成為王牌投手,哥哥和也卻仍然吊兒啷噹,一天到晚換社團,做什麼都半途而廢。三個人的感情關係,也隨著悄悄地產生變化。

    + +

    在幾乎不記得原著劇情的情況下,還蠻好看的。あだち充特有的宿命與無常,小人物面對命運的掙札,故作輕鬆的姿態,都表達得非常完美。兩個小時的電影,要演出三十幾集的劇情,本來就會有所刪節。有一部份沒有忠於原著漫畫,略為修改,不過仍然把あだち充的味道表現得很好。

    + +

    有一幕兩兄弟在搶電視遊樂器,畫面中出現的 3D 的戰鬥畫面。二十年前あだち充鄰家女孩時,電視遊樂器裏的遊戲應該不是這個樣子的吧,哈~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 67 | + 68 | + 69 | + 70 | + 71 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0070.html.en.html b/htdocs/imacat/me/diary/0070.html.en.html new file mode 120000 index 0000000..884681c --- /dev/null +++ b/htdocs/imacat/me/diary/0070.html.en.html @@ -0,0 +1 @@ +0070.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0070.html.en.xhtml b/htdocs/imacat/me/diary/0070.html.en.xhtml new file mode 100644 index 0000000..d1ad7aa --- /dev/null +++ b/htdocs/imacat/me/diary/0070.html.en.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 70 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 70

    + +
    + +
    + +
    +
    9.17.’06. 2:10am.
    + +

    vigigi 音樂專輯

    + +

    之前發現電影 NANAENDLESS STORY 的鋼琴的問題時,想知道是不是有別人發現同樣的問題,於是上網找了一圈,意外發現一個很可愛的網站:vigigi 音樂專輯

    + +

    vigigi 是一個住在台中,擁有中級教師資格的水瓶女子。她不定期把自己演奏錄下的鋼琴曲,放到網站上分享。她之前錄過ENDLESS STORY 的鋼琴獨奏,我循線找到了她的這首曲子,下載來聽了以後,覺得蠻好聽的,很訝異也有像這樣的人,把自己的鋼琴練習曲,及在古典音樂上的成長心情,放到網路上和大家分享,而且還擁有一群喜歡她的音樂的網友支持著。像這樣的事,我覺得好酷~

    + +

    我覺得可以專注在一件事上,把一件事練到很厲害,像 vigigi 彈鋼琴一樣,真的是很了不起的一件事~我小時候對很多事有興趣,鋼琴也是其中之一。我現在知道屬於我的領域在哪裏了。可是碰到會彈鋼琴,彈得很不錯的人,還是忍不住覺得很羨慕~

    + +
    + +
    + +
    +
    9.16.’06. 2:04am.
    + +

    Mr. & Mrs. Smith 史密斯任務—帥哥美女動作愛情喜劇

    + +
    +Mr. & Mrs. Smith 史密斯任務
    +

    Mr. & Mrs. Smith 史密斯任務

    +
    + + + +

    史密斯任務是一部精彩的娛樂片:帥哥加美女、動作、槍戰、飛車、爆破、愛情、喜劇…所有娛樂片應具備的要素都齊了,而且結合得非常完美。沒有什麼深度的劇情,不過作為一部娛樂片,倒是滿分的選擇。

    + +

    擔任建築工程師的約翰史密斯( John Smith ,一聽就知道是假名)和電腦工程師珍史密斯( Jane Smith ,也很像假名)是一對平凡的中產夫妻,結婚六年,婚姻漸漸陷入瓶頸,無法彼此坦然相對。但事實上兩個人的確有不可告訴對方的秘密,他們的職業只是掩護,真實身份是頂尖殺手。某天雙方都接到組織命令,在不知情下,要暗殺同一個人。雙方不期然破壞對方的暗殺計劃,任務失敗,才知道彼此的真正身份。驚撼之餘,他們也必須殺掉對方滅口。然而,幕後還有一個更大的局,在等著他們。

    + +

    基本上蠻好看的。我最近頗累,想輕鬆一下,才選擇這部電影的。最後一場在百貨商場內,背對背的槍戰戲,有點浪漫得過火了,稍嫌假假的。 :p 不過整體來說,兩夫妻邊求生邊吵嘴,還不時耍賤招算計對方,真的很可愛很好笑。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 68 | + 69 | + 70 | + 71 | + 72 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0070.html.zh-cn.html b/htdocs/imacat/me/diary/0070.html.zh-cn.html new file mode 120000 index 0000000..0e77bf8 --- /dev/null +++ b/htdocs/imacat/me/diary/0070.html.zh-cn.html @@ -0,0 +1 @@ +0070.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0070.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0070.html.zh-cn.xhtml new file mode 100644 index 0000000..b14de85 --- /dev/null +++ b/htdocs/imacat/me/diary/0070.html.zh-cn.xhtml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷七十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷七十

    + +
    + +
    + +
    +
    9.17.’06. 2:10am.
    + +

    vigigi 音乐专辑

    + +

    之前发现电影 NANAENDLESS STORY 的钢琴的问题时,想知道是不是有别人发现同样的问题,於是上网找了一圈,意外发现一个很可爱的网站:vigigi 音乐专辑

    + +

    vigigi 是一个住在台中,拥有中级教师资格的水瓶女子。她不定期把自己演奏录下的钢琴曲,放到网站上分享。她之前录过ENDLESS STORY 的钢琴独奏,我循线找到了她的这首曲子,下载来听了以后,觉得蛮好听的,很讶异也有像这样的人,把自己的钢琴练习曲,及在古典音乐上的成长心情,放到网路上和大家分享,而且还拥有一群喜欢她的音乐的网友支持著。像这样的事,我觉得好酷~

    + +

    我觉得可以专注在一件事上,把一件事练到很厉害,像 vigigi 弹钢琴一样,真的是很了不起的一件事~我小时候对很多事有兴趣,钢琴也是其中之一。我现在知道属於我的领域在哪里了。可是碰到会弹钢琴,弹得很不错的人,还是忍不住觉得很羡慕~

    + +
    + +
    + +
    +
    9.16.’06. 2:04am.
    + +

    Mr. & Mrs. Smith 史密斯任务—帅哥美女动作爱情喜剧

    + +
    +Mr. & Mrs. Smith 史密斯任务
    +

    Mr. & Mrs. Smith 史密斯任务

    +
    + + + +

    史密斯任务是一部精彩的娱乐片:帅哥加美女、动作、枪战、飞车、爆破、爱情、喜剧…所有娱乐片应具备的要素都齐了,而且结合得非常完美。没有什么深度的剧情,不过作为一部娱乐片,倒是满分的选择。

    + +

    担任建筑工程师的约翰史密斯( John Smith ,一听就知道是假名)和电脑工程师珍史密斯( Jane Smith ,也很像假名)是一对平凡的中产夫妻,结婚六年,婚姻渐渐陷入瓶颈,无法彼此坦然相对。但事实上两个人的确有不可告诉对方的秘密,他们的职业只是掩护,真实身份是顶尖杀手。某天双方都接到组织命令,在不知情下,要暗杀同一个人。双方不期然破坏对方的暗杀计划,任务失败,才知道彼此的真正身份。惊撼之余,他们也必须杀掉对方灭口。然而,幕后还有一个更大的局,在等著他们。

    + +

    基本上蛮好看的。我最近颇累,想轻松一下,才选择这部电影的。最后一场在百货商场内,背对背的枪战戏,有点浪漫得过火了,稍嫌假假的。 :p 不过整体来说,两夫妻边求生边吵嘴,还不时耍贱招算计对方,真的很可爱很好笑。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 68 | + 69 | + 70 | + 71 | + 72 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0070.html.zh-tw.html b/htdocs/imacat/me/diary/0070.html.zh-tw.html new file mode 120000 index 0000000..cbf0464 --- /dev/null +++ b/htdocs/imacat/me/diary/0070.html.zh-tw.html @@ -0,0 +1 @@ +0070.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0070.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0070.html.zh-tw.xhtml new file mode 100644 index 0000000..99d618a --- /dev/null +++ b/htdocs/imacat/me/diary/0070.html.zh-tw.xhtml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷七十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷七十

    + +
    + +
    + +
    +
    9.17.’06. 2:10am.
    + +

    vigigi 音樂專輯

    + +

    之前發現電影 NANAENDLESS STORY 的鋼琴的問題時,想知道是不是有別人發現同樣的問題,於是上網找了一圈,意外發現一個很可愛的網站:vigigi 音樂專輯

    + +

    vigigi 是一個住在台中,擁有中級教師資格的水瓶女子。她不定期把自己演奏錄下的鋼琴曲,放到網站上分享。她之前錄過ENDLESS STORY 的鋼琴獨奏,我循線找到了她的這首曲子,下載來聽了以後,覺得蠻好聽的,很訝異也有像這樣的人,把自己的鋼琴練習曲,及在古典音樂上的成長心情,放到網路上和大家分享,而且還擁有一群喜歡她的音樂的網友支持著。像這樣的事,我覺得好酷~

    + +

    我覺得可以專注在一件事上,把一件事練到很厲害,像 vigigi 彈鋼琴一樣,真的是很了不起的一件事~我小時候對很多事有興趣,鋼琴也是其中之一。我現在知道屬於我的領域在哪裏了。可是碰到會彈鋼琴,彈得很不錯的人,還是忍不住覺得很羨慕~

    + +
    + +
    + +
    +
    9.16.’06. 2:04am.
    + +

    Mr. & Mrs. Smith 史密斯任務—帥哥美女動作愛情喜劇

    + +
    +Mr. & Mrs. Smith 史密斯任務
    +

    Mr. & Mrs. Smith 史密斯任務

    +
    + + + +

    史密斯任務是一部精彩的娛樂片:帥哥加美女、動作、槍戰、飛車、爆破、愛情、喜劇…所有娛樂片應具備的要素都齊了,而且結合得非常完美。沒有什麼深度的劇情,不過作為一部娛樂片,倒是滿分的選擇。

    + +

    擔任建築工程師的約翰史密斯( John Smith ,一聽就知道是假名)和電腦工程師珍史密斯( Jane Smith ,也很像假名)是一對平凡的中產夫妻,結婚六年,婚姻漸漸陷入瓶頸,無法彼此坦然相對。但事實上兩個人的確有不可告訴對方的秘密,他們的職業只是掩護,真實身份是頂尖殺手。某天雙方都接到組織命令,在不知情下,要暗殺同一個人。雙方不期然破壞對方的暗殺計劃,任務失敗,才知道彼此的真正身份。驚撼之餘,他們也必須殺掉對方滅口。然而,幕後還有一個更大的局,在等著他們。

    + +

    基本上蠻好看的。我最近頗累,想輕鬆一下,才選擇這部電影的。最後一場在百貨商場內,背對背的槍戰戲,有點浪漫得過火了,稍嫌假假的。 :p 不過整體來說,兩夫妻邊求生邊吵嘴,還不時耍賤招算計對方,真的很可愛很好笑。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 68 | + 69 | + 70 | + 71 | + 72 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0071.html.en.html b/htdocs/imacat/me/diary/0071.html.en.html new file mode 120000 index 0000000..40aa9e0 --- /dev/null +++ b/htdocs/imacat/me/diary/0071.html.en.html @@ -0,0 +1 @@ +0071.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0071.html.en.xhtml b/htdocs/imacat/me/diary/0071.html.en.xhtml new file mode 100644 index 0000000..d9b340a --- /dev/null +++ b/htdocs/imacat/me/diary/0071.html.en.xhtml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 71 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 71

    + +
    + +
    + +
    +
    9.17.’06. 5:12am.
    + +

    婦好

    + +
    +婦好鉞,飾雙虎噬人紋(左右兩隻老虎合咬中間的人頭)
    +

    婦好鉞,飾雙虎噬人紋(左右兩隻老虎合咬中間的人頭)

    +
    + +

    暑修修中國文字,讀到關於中國文字和武器的關係,課本提到了商朝女將婦好用的鉞商朝女將婦好用的鉞?這句話初看不大懂,反覆看了幾次,我猜想應該是說商朝有個女將,名叫婦好,使用武器

    + +

    婦好?以前國高中課本沒讀過,第一次聽到這個名字。不過以前好像曾經聽人提起過。女的武將,讓我更感好奇。趕緊上網找找看,這是什麼人。找到的結果,很有趣。

    + +

    婦好是商王武丁的一個妻子,受武丁寵信,任將軍,多次帶兵出征,最多曾一次帶兵一萬三千人,經常主持祭祀,並有封地,是商朝重要的武將也是政治家。是稱謂,父姓的甲骨文字應尚未辨出,氏名。廟號,後世尊稱母辛。武丁占卜的甲骨中,有數百片與婦好有關,死後並令其與己葬同穴,可見其寵愛程度。婦好是中國歷史上最早的女武將。

    + +

    1976 年河南省安陽市小屯村西北殷墟的婦好墓出土,共出土 1928 件文物,是現存商代墓室中最完整的。出土文物中有一個青銅鉞,無柄,上刻婦好二字,飾雙虎噬人紋,應該是婦好的武器。婦好享堂前有一尊漢白玉婦好雕像,右手持鉞,依造型看,應該是最近幾十年雕塑的。

    + +
    +漢白玉婦好雕像
    +

    漢白玉婦好雕像

    +
    + +

    嗯。女人是很了不起的呢~ ^_*'

    + +

    鉞以現在的說法,可以說是雙手持的長柄大斧,和矛、戟同樣屬於長武器。比較重,要力氣相當大的人才能揮舞。和戟一樣看起來頗有威嚴,是將領權力的象徵。

    + +

    參考資料:

    + + + +
    + +
    + +
    +
    9.17.’06. 2:47am.
    + +

    JerryCCanon Rock 搖滾卡農

    + +

    上星期四 2006-09-14 讀蘋果日報,看到一則 JerryC 的報導改曲 台學生暴紅全球 《搖滾卡農》電吉他激起熱潮。我之前從未聽過 JerryC ,忍不住好奇,上了他的網站,找到Canon Rock 搖滾卡農下載下來聽。原本覺得個人放上網路,受人注目的音樂作品,應該會很好聽吧。誰知道聽了兩分鐘,讓我震憾無比:這不是很好聽,根本是超水準的作品!

    + +

    卡農是鋼琴的基礎練習曲,各聲部反覆輪唱,原本就相當好聽。搖滾卡農的變奏,由 JerryC 自己編曲、彈奏。不論編曲還是彈奏,都遠超過一般的水準,很難想像這是一個人獨立製作,而不是在商業環境下,製作出來的。一開始是單調的古典鋼琴錄音,主旋律跑過一遍了以後,開始漸次加入電吉他和鼓聲,越來越熱鬧,每一次反覆,都出現更複雜、更華麗的和弦。聽了以後,除了讚嘆,說不出其它的言語。

    + +

    擁有這樣的音樂才能,真是叫人嫉妒不已~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 69 | + 70 | + 71 | + 72 | + 73 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0071.html.zh-cn.html b/htdocs/imacat/me/diary/0071.html.zh-cn.html new file mode 120000 index 0000000..12c5e94 --- /dev/null +++ b/htdocs/imacat/me/diary/0071.html.zh-cn.html @@ -0,0 +1 @@ +0071.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0071.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0071.html.zh-cn.xhtml new file mode 100644 index 0000000..c825fc8 --- /dev/null +++ b/htdocs/imacat/me/diary/0071.html.zh-cn.xhtml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷七十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷七十一

    + +
    + +
    + +
    +
    9.17.’06. 5:12am.
    + +

    妇好

    + +
    +妇好钺,饰双虎噬人纹(左右两只老虎合咬中间的人头)
    +

    妇好钺,饰双虎噬人纹(左右两只老虎合咬中间的人头)

    +
    + +

    暑修修中国文字,读到关於中国文字和武器的关系,课本提到了商朝女将妇好用的钺商朝女将妇好用的钺?这句话初看不大懂,反覆看了几次,我猜想应该是说商朝有个女将,名叫妇好,使用武器

    + +

    妇好?以前国高中课本没读过,第一次听到这个名字。不过以前好像曾经听人提起过。女的武将,让我更感好奇。赶紧上网找找看,这是什么人。找到的结果,很有趣。

    + +

    妇好是商王武丁的一个妻子,受武丁宠信,任将军,多次带兵出征,最多曾一次带兵一万三千人,经常主持祭祀,并有封地,是商朝重要的武将也是政治家。是称谓,父姓的甲骨文字应尚未辨出,氏名。庙号,后世尊称母辛。武丁占卜的甲骨中,有数百片与妇好有关,死后并令其与己葬同穴,可见其宠爱程度。妇好是中国历史上最早的女武将。

    + +

    1976 年河南省安阳市小屯村西北殷墟的妇好墓出土,共出土 1928 件文物,是现存商代墓室中最完整的。出土文物中有一个青铜钺,无柄,上刻妇好二字,饰双虎噬人纹,应该是妇好的武器。妇好享堂前有一尊汉白玉妇好雕像,右手持钺,依造型看,应该是最近几十年雕塑的。

    + +
    +汉白玉妇好雕像
    +

    汉白玉妇好雕像

    +
    + +

    嗯。女人是很了不起的呢~ ^_*'

    + +

    钺以现在的说法,可以说是双手持的长柄大斧,和矛、戟同样属於长武器。比较重,要力气相当大的人才能挥舞。和戟一样看起来颇有威严,是将领权力的象徵。

    + +

    参考资料:

    + + + +
    + +
    + +
    +
    9.17.’06. 2:47am.
    + +

    JerryCCanon Rock 摇滚卡农

    + +

    上星期四 2006-09-14 读苹果日报,看到一则 JerryC 的报导改曲 台学生暴红全球 《摇滚卡农》电吉他激起热潮。我之前从未听过 JerryC ,忍不住好奇,上了他的网站,找到Canon Rock 摇滚卡农下载下来听。原本觉得个人放上网路,受人注目的音乐作品,应该会很好听吧。谁知道听了两分钟,让我震憾无比:这不是很好听,根本是超水准的作品!

    + +

    卡农是钢琴的基础练习曲,各声部反覆轮唱,原本就相当好听。摇滚卡农的变奏,由 JerryC 自己编曲、弹奏。不论编曲还是弹奏,都远超过一般的水准,很难想像这是一个人独立制作,而不是在商业环境下,制作出来的。一开始是单调的古典钢琴录音,主旋律跑过一遍了以后,开始渐次加入电吉他和鼓声,越来越热闹,每一次反覆,都出现更复杂、更华丽的和弦。听了以后,除了赞叹,说不出其它的言语。

    + +

    拥有这样的音乐才能,真是叫人嫉妒不已~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 69 | + 70 | + 71 | + 72 | + 73 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0071.html.zh-tw.html b/htdocs/imacat/me/diary/0071.html.zh-tw.html new file mode 120000 index 0000000..9b4eda2 --- /dev/null +++ b/htdocs/imacat/me/diary/0071.html.zh-tw.html @@ -0,0 +1 @@ +0071.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0071.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0071.html.zh-tw.xhtml new file mode 100644 index 0000000..b25994c --- /dev/null +++ b/htdocs/imacat/me/diary/0071.html.zh-tw.xhtml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷七十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷七十一

    + +
    + +
    + +
    +
    9.17.’06. 5:12am.
    + +

    婦好

    + +
    +婦好鉞,飾雙虎噬人紋(左右兩隻老虎合咬中間的人頭)
    +

    婦好鉞,飾雙虎噬人紋(左右兩隻老虎合咬中間的人頭)

    +
    + +

    暑修修中國文字,讀到關於中國文字和武器的關係,課本提到了商朝女將婦好用的鉞商朝女將婦好用的鉞?這句話初看不大懂,反覆看了幾次,我猜想應該是說商朝有個女將,名叫婦好,使用武器

    + +

    婦好?以前國高中課本沒讀過,第一次聽到這個名字。不過以前好像曾經聽人提起過。女的武將,讓我更感好奇。趕緊上網找找看,這是什麼人。找到的結果,很有趣。

    + +

    婦好是商王武丁的一個妻子,受武丁寵信,任將軍,多次帶兵出征,最多曾一次帶兵一萬三千人,經常主持祭祀,並有封地,是商朝重要的武將也是政治家。是稱謂,父姓的甲骨文字應尚未辨出,氏名。廟號,後世尊稱母辛。武丁占卜的甲骨中,有數百片與婦好有關,死後並令其與己葬同穴,可見其寵愛程度。婦好是中國歷史上最早的女武將。

    + +

    1976 年河南省安陽市小屯村西北殷墟的婦好墓出土,共出土 1928 件文物,是現存商代墓室中最完整的。出土文物中有一個青銅鉞,無柄,上刻婦好二字,飾雙虎噬人紋,應該是婦好的武器。婦好享堂前有一尊漢白玉婦好雕像,右手持鉞,依造型看,應該是最近幾十年雕塑的。

    + +
    +漢白玉婦好雕像
    +

    漢白玉婦好雕像

    +
    + +

    嗯。女人是很了不起的呢~ ^_*'

    + +

    鉞以現在的說法,可以說是雙手持的長柄大斧,和矛、戟同樣屬於長武器。比較重,要力氣相當大的人才能揮舞。和戟一樣看起來頗有威嚴,是將領權力的象徵。

    + +

    參考資料:

    + + + +
    + +
    + +
    +
    9.17.’06. 2:47am.
    + +

    JerryCCanon Rock 搖滾卡農

    + +

    上星期四 2006-09-14 讀蘋果日報,看到一則 JerryC 的報導改曲 台學生暴紅全球 《搖滾卡農》電吉他激起熱潮。我之前從未聽過 JerryC ,忍不住好奇,上了他的網站,找到Canon Rock 搖滾卡農下載下來聽。原本覺得個人放上網路,受人注目的音樂作品,應該會很好聽吧。誰知道聽了兩分鐘,讓我震憾無比:這不是很好聽,根本是超水準的作品!

    + +

    卡農是鋼琴的基礎練習曲,各聲部反覆輪唱,原本就相當好聽。搖滾卡農的變奏,由 JerryC 自己編曲、彈奏。不論編曲還是彈奏,都遠超過一般的水準,很難想像這是一個人獨立製作,而不是在商業環境下,製作出來的。一開始是單調的古典鋼琴錄音,主旋律跑過一遍了以後,開始漸次加入電吉他和鼓聲,越來越熱鬧,每一次反覆,都出現更複雜、更華麗的和弦。聽了以後,除了讚嘆,說不出其它的言語。

    + +

    擁有這樣的音樂才能,真是叫人嫉妒不已~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 69 | + 70 | + 71 | + 72 | + 73 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0072.html.en.html b/htdocs/imacat/me/diary/0072.html.en.html new file mode 120000 index 0000000..7442feb --- /dev/null +++ b/htdocs/imacat/me/diary/0072.html.en.html @@ -0,0 +1 @@ +0072.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0072.html.en.xhtml b/htdocs/imacat/me/diary/0072.html.en.xhtml new file mode 100644 index 0000000..98b1ae0 --- /dev/null +++ b/htdocs/imacat/me/diary/0072.html.en.xhtml @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 72 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 72

    + +
    + +
    + +
    +
    9.17.’06. 5:37am.
    + +

    楓糖

    + +

    常常聽到楓糖。這幾年咖啡店賣的,幾乎什麼都可以加楓糖:楓糖卡布奇諾、楓糖布丁、楓糖鬆餅、楓糖蛋糕。我已經忘了是從什麼時候,開始讀到楓糖這個詞的了。不過愛吃甜的我,每次讀到,腦子裏都會開始產生甜美的幻覺。

    + +

    可是楓糖到底是什麼?從小到大我習慣了吃蔗糖,紅糖、白糖、冰糖,甚至果糖、代糖、糖霜、蜂蜜,都非常熟悉。其味道微妙的差異,我都可以如數家珍。只有楓糖,不知道是哪裏冒出來的,既沒有看過,也沒有吃過純粹的楓糖,也沒有自己用楓糖做過什麼調味。楓糖好像就這樣出現在生活中了,莫名其妙。

    + +

    前兩個星期有一天早上,咖啡店點完早餐等候時,突然想,我何不上網去查清楚這倒底是什麼呢?

    + +
    +

    加拿大…是楓樹及楓糖最多的地方。…楓樹在落葉之前﹐會製造含糖份的汁液﹐儲存於根部﹐初春時﹐楓汁流回樹枝﹐供應幼枝新葉發育所需的養份。因此一年中﹐只有初春時節是楓汁的採收季節。農人將楓樹皮割開﹐收集汁液﹐再加熱讓水份蒸發﹐即成為具獨特風味的楓糖漿。

    + +
    各種糖類
    +
    + +

    嗯,原來如此。楓糖漿甜度不高,不過看樣子別有風味。加拿大來的舶來品,難怪沒有什麼機會吃到純粹的楓糖漿。有機會,再來試試看吧~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 70 | + 71 | + 72 | + 73 | + 74 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0072.html.zh-cn.html b/htdocs/imacat/me/diary/0072.html.zh-cn.html new file mode 120000 index 0000000..ecd88ea --- /dev/null +++ b/htdocs/imacat/me/diary/0072.html.zh-cn.html @@ -0,0 +1 @@ +0072.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0072.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0072.html.zh-cn.xhtml new file mode 100644 index 0000000..7a6d1e2 --- /dev/null +++ b/htdocs/imacat/me/diary/0072.html.zh-cn.xhtml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷七十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷七十二

    + +
    + +
    + +
    +
    9.17.’06. 5:37am.
    + +

    枫糖

    + +

    常常听到枫糖。这几年咖啡店卖的,几乎什么都可以加枫糖:枫糖卡布奇诺、枫糖布丁、枫糖松饼、枫糖蛋糕。我已经忘了是从什么时候,开始读到枫糖这个词的了。不过爱吃甜的我,每次读到,脑子里都会开始产生甜美的幻觉。

    + +

    可是枫糖到底是什么?从小到大我习惯了吃蔗糖,红糖、白糖、冰糖,甚至果糖、代糖、糖霜、蜂蜜,都非常熟悉。其味道微妙的差异,我都可以如数家珍。只有枫糖,不知道是哪里冒出来的,既没有看过,也没有吃过纯粹的枫糖,也没有自己用枫糖做过什么调味。枫糖好像就这样出现在生活中了,莫名其妙。

    + +

    前两个星期有一天早上,咖啡店点完早餐等候时,突然想,我何不上网去查清楚这倒底是什么呢?

    + +
    +

    加拿大…是枫树及枫糖最多的地方。…枫树在落叶之前,会制造含糖份的汁液,储存於根部,初春时,枫汁流回树枝,供应幼枝新叶发育所需的养份。因此一年中,只有初春时节是枫汁的采收季节。农人将枫树皮割开,收集汁液,再加热让水份蒸发,即成为具独特风味的枫糖浆。

    + +
    各种糖类
    +
    + +

    嗯,原来如此。枫糖浆甜度不高,不过看样子别有风味。加拿大来的舶来品,难怪没有什么机会吃到纯粹的枫糖浆。有机会,再来试试看吧~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 70 | + 71 | + 72 | + 73 | + 74 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0072.html.zh-tw.html b/htdocs/imacat/me/diary/0072.html.zh-tw.html new file mode 120000 index 0000000..9f6e916 --- /dev/null +++ b/htdocs/imacat/me/diary/0072.html.zh-tw.html @@ -0,0 +1 @@ +0072.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0072.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0072.html.zh-tw.xhtml new file mode 100644 index 0000000..3514662 --- /dev/null +++ b/htdocs/imacat/me/diary/0072.html.zh-tw.xhtml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷七十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷七十二

    + +
    + +
    + +
    +
    9.17.’06. 5:37am.
    + +

    楓糖

    + +

    常常聽到楓糖。這幾年咖啡店賣的,幾乎什麼都可以加楓糖:楓糖卡布奇諾、楓糖布丁、楓糖鬆餅、楓糖蛋糕。我已經忘了是從什麼時候,開始讀到楓糖這個詞的了。不過愛吃甜的我,每次讀到,腦子裏都會開始產生甜美的幻覺。

    + +

    可是楓糖到底是什麼?從小到大我習慣了吃蔗糖,紅糖、白糖、冰糖,甚至果糖、代糖、糖霜、蜂蜜,都非常熟悉。其味道微妙的差異,我都可以如數家珍。只有楓糖,不知道是哪裏冒出來的,既沒有看過,也沒有吃過純粹的楓糖,也沒有自己用楓糖做過什麼調味。楓糖好像就這樣出現在生活中了,莫名其妙。

    + +

    前兩個星期有一天早上,咖啡店點完早餐等候時,突然想,我何不上網去查清楚這倒底是什麼呢?

    + +
    +

    加拿大…是楓樹及楓糖最多的地方。…楓樹在落葉之前﹐會製造含糖份的汁液﹐儲存於根部﹐初春時﹐楓汁流回樹枝﹐供應幼枝新葉發育所需的養份。因此一年中﹐只有初春時節是楓汁的採收季節。農人將楓樹皮割開﹐收集汁液﹐再加熱讓水份蒸發﹐即成為具獨特風味的楓糖漿。

    + +
    各種糖類
    +
    + +

    嗯,原來如此。楓糖漿甜度不高,不過看樣子別有風味。加拿大來的舶來品,難怪沒有什麼機會吃到純粹的楓糖漿。有機會,再來試試看吧~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 70 | + 71 | + 72 | + 73 | + 74 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0073.html.en.html b/htdocs/imacat/me/diary/0073.html.en.html new file mode 120000 index 0000000..26f10b8 --- /dev/null +++ b/htdocs/imacat/me/diary/0073.html.en.html @@ -0,0 +1 @@ +0073.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0073.html.en.xhtml b/htdocs/imacat/me/diary/0073.html.en.xhtml new file mode 100644 index 0000000..5f10f1d --- /dev/null +++ b/htdocs/imacat/me/diary/0073.html.en.xhtml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 73 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 73

    + +
    + +
    + +
    +
    9.17.’06. 11:48am.
    + +

    Courtney Love 寇特妮洛芙

    + +
    +Courtney Love 寇特妮洛芙
    +

    Courtney Love 寇特妮洛芙

    +
    + +

    會注意到 Courtney Love ,是因為之前在查電影 Sid & Nancy (1986) 的演員表時,有一個網站誤把 Courtney Love 列為飾演 Nancy Spungen 的演員,和別人寫的不同,讓我搞了好久才搞清楚。飾演 Nancy 的應該是 Chloe WebbCourtney Love 也有在 Sid & Nancy 中演出,不過是演 Nancy 在美國的朋友 Gretchen ,有兩場戲,分別是 81:14 Nancy 去找她買毒品,及 90:05 SidNancy 等毒販時和她聊天。那時兩個人脫離 Sex Pistols ,對毒品越陷越深了。 Courtney Love 原先試鏡時想應試的是 Nancy 的角色。

    + +

    我上網查了 Courtney Love 的資料,發覺她還蠻酷的。她似乎緋聞和是非很多,生活放蕩不稽,網路上有很多她很酷的露點桌面。 Courtney LoveHole 樂團的主唱, 1992 年和 Nirvana 樂團主唱 Kurt Cobain 結婚。 Kurt Cobain 1994 年死於毒品過量,她繼承了幾乎 Nirvana 所有音樂的版權。 Hole 於 1989 年於洛衫磯成團, 2002 年解散。 2004 年 Courtney Love 發行了單飛後的首張專輯 America’s Sweetheart 美國甜心 。除了音樂外, Courtney Love 也拍了幾部電影,如 Sid & Nancy 席德與南茜 (1986)Straight to Hell (1987)The People vs. Larry Flynt 1999 情色風暴 (1996) 等。 Courtney Love 也曾於 2000 年發言力挺 Napster

    + +
    +America’s Sweetheart 美國甜心專輯
    +

    America’s Sweetheart 美國甜心專輯

    +
    + +

    圍繞在 Courtney Love 身上的事情太多了,我還在試著瞭解這個人。大多數人對她的褒貶不一:有人認為 Hole 會紅都是靠她的緋聞和大膽的作風,靠她和 Nirvana 主唱 Kurt Cobain 的婚姻拉抬名聲;有人說她只會炒作新聞,音樂爛得毫無是處;但也有人(如 Chicks On Speed )將她視為偶像與精神指標,或視為 grunge 搖滾的靈魂人物。她這幾年似乎上法庭的頻率比寫歌還高,也曾數次因吸毒被拘補,判罰社區服務。 2006 年 5 月 Courtney Love 賣掉手上擁有的Nirvana 樂曲版權的 25% ,引起很大的爭議。

    + +

    參考資料:

    + + + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 71 | + 72 | + 73 | + 74 | + 75 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0073.html.zh-cn.html b/htdocs/imacat/me/diary/0073.html.zh-cn.html new file mode 120000 index 0000000..79f572f --- /dev/null +++ b/htdocs/imacat/me/diary/0073.html.zh-cn.html @@ -0,0 +1 @@ +0073.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0073.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0073.html.zh-cn.xhtml new file mode 100644 index 0000000..79b404a --- /dev/null +++ b/htdocs/imacat/me/diary/0073.html.zh-cn.xhtml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷七十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷七十三

    + +
    + +
    + +
    +
    9.17.’06. 11:48am.
    + +

    Courtney Love 寇特妮洛芙

    + +
    +Courtney Love 寇特妮洛芙
    +

    Courtney Love 寇特妮洛芙

    +
    + +

    会注意到 Courtney Love ,是因为之前在查电影 Sid & Nancy (1986) 的演员表时,有一个网站误把 Courtney Love 列为饰演 Nancy Spungen 的演员,和别人写的不同,让我搞了好久才搞清楚。饰演 Nancy 的应该是 Chloe WebbCourtney Love 也有在 Sid & Nancy 中演出,不过是演 Nancy 在美国的朋友 Gretchen ,有两场戏,分别是 81:14 Nancy 去找她买毒品,及 90:05 SidNancy 等毒贩时和她聊天。那时两个人脱离 Sex Pistols ,对毒品越陷越深了。 Courtney Love 原先试镜时想应试的是 Nancy 的角色。

    + +

    我上网查了 Courtney Love 的资料,发觉她还蛮酷的。她似乎绯闻和是非很多,生活放荡不稽,网路上有很多她很酷的露点桌面。 Courtney LoveHole 乐团的主唱, 1992 年和 Nirvana 乐团主唱 Kurt Cobain 结婚。 Kurt Cobain 1994 年死於毒品过量,她继承了几乎 Nirvana 所有音乐的版权。 Hole 於 1989 年於洛衫矶成团, 2002 年解散。 2004 年 Courtney Love 发行了单飞后的首张专辑 America’s Sweetheart 美国甜心 。除了音乐外, Courtney Love 也拍了几部电影,如 Sid & Nancy 席德与南茜 (1986)Straight to Hell (1987)The People vs. Larry Flynt 1999 情色风暴 (1996) 等。 Courtney Love 也曾於 2000 年发言力挺 Napster

    + +
    +America’s Sweetheart 美国甜心专辑
    +

    America’s Sweetheart 美国甜心专辑

    +
    + +

    围绕在 Courtney Love 身上的事情太多了,我还在试著了解这个人。大多数人对她的褒贬不一:有人认为 Hole 会红都是靠她的绯闻和大胆的作风,靠她和 Nirvana 主唱 Kurt Cobain 的婚姻拉抬名声;有人说她只会炒作新闻,音乐烂得毫无是处;但也有人(如 Chicks On Speed )将她视为偶像与精神指标,或视为 grunge 摇滚的灵魂人物。她这几年似乎上法庭的频率比写歌还高,也曾数次因吸毒被拘补,判罚社区服务。 2006 年 5 月 Courtney Love 卖掉手上拥有的Nirvana 乐曲版权的 25% ,引起很大的争议。

    + +

    参考资料:

    + + + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 71 | + 72 | + 73 | + 74 | + 75 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0073.html.zh-tw.html b/htdocs/imacat/me/diary/0073.html.zh-tw.html new file mode 120000 index 0000000..53c323e --- /dev/null +++ b/htdocs/imacat/me/diary/0073.html.zh-tw.html @@ -0,0 +1 @@ +0073.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0073.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0073.html.zh-tw.xhtml new file mode 100644 index 0000000..45338e3 --- /dev/null +++ b/htdocs/imacat/me/diary/0073.html.zh-tw.xhtml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷七十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷七十三

    + +
    + +
    + +
    +
    9.17.’06. 11:48am.
    + +

    Courtney Love 寇特妮洛芙

    + +
    +Courtney Love 寇特妮洛芙
    +

    Courtney Love 寇特妮洛芙

    +
    + +

    會注意到 Courtney Love ,是因為之前在查電影 Sid & Nancy (1986) 的演員表時,有一個網站誤把 Courtney Love 列為飾演 Nancy Spungen 的演員,和別人寫的不同,讓我搞了好久才搞清楚。飾演 Nancy 的應該是 Chloe WebbCourtney Love 也有在 Sid & Nancy 中演出,不過是演 Nancy 在美國的朋友 Gretchen ,有兩場戲,分別是 81:14 Nancy 去找她買毒品,及 90:05 SidNancy 等毒販時和她聊天。那時兩個人脫離 Sex Pistols ,對毒品越陷越深了。 Courtney Love 原先試鏡時想應試的是 Nancy 的角色。

    + +

    我上網查了 Courtney Love 的資料,發覺她還蠻酷的。她似乎緋聞和是非很多,生活放蕩不稽,網路上有很多她很酷的露點桌面。 Courtney LoveHole 樂團的主唱, 1992 年和 Nirvana 樂團主唱 Kurt Cobain 結婚。 Kurt Cobain 1994 年死於毒品過量,她繼承了幾乎 Nirvana 所有音樂的版權。 Hole 於 1989 年於洛衫磯成團, 2002 年解散。 2004 年 Courtney Love 發行了單飛後的首張專輯 America’s Sweetheart 美國甜心 。除了音樂外, Courtney Love 也拍了幾部電影,如 Sid & Nancy 席德與南茜 (1986)Straight to Hell (1987)The People vs. Larry Flynt 1999 情色風暴 (1996) 等。 Courtney Love 也曾於 2000 年發言力挺 Napster

    + +
    +America’s Sweetheart 美國甜心專輯
    +

    America’s Sweetheart 美國甜心專輯

    +
    + +

    圍繞在 Courtney Love 身上的事情太多了,我還在試著瞭解這個人。大多數人對她的褒貶不一:有人認為 Hole 會紅都是靠她的緋聞和大膽的作風,靠她和 Nirvana 主唱 Kurt Cobain 的婚姻拉抬名聲;有人說她只會炒作新聞,音樂爛得毫無是處;但也有人(如 Chicks On Speed )將她視為偶像與精神指標,或視為 grunge 搖滾的靈魂人物。她這幾年似乎上法庭的頻率比寫歌還高,也曾數次因吸毒被拘補,判罰社區服務。 2006 年 5 月 Courtney Love 賣掉手上擁有的Nirvana 樂曲版權的 25% ,引起很大的爭議。

    + +

    參考資料:

    + + + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 71 | + 72 | + 73 | + 74 | + 75 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0074.html.en.html b/htdocs/imacat/me/diary/0074.html.en.html new file mode 120000 index 0000000..0959d39 --- /dev/null +++ b/htdocs/imacat/me/diary/0074.html.en.html @@ -0,0 +1 @@ +0074.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0074.html.en.xhtml b/htdocs/imacat/me/diary/0074.html.en.xhtml new file mode 100644 index 0000000..33f2e2c --- /dev/null +++ b/htdocs/imacat/me/diary/0074.html.en.xhtml @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 74 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 74

    + +
    + +
    + +
    +
    9.17.’06. 11:19pm.
    + +

    E 化萬歲 e-Everything

    + +

    台灣有一個很特殊的現象,就是很喜歡 Ee-maile-Businesse-Commercee-Marketing E 行銷 、 e-Shop E 商店、 e-Bank E 銀行、 e-Government E 政府、 e-School E 學校、 e-Map E 地圖、 e-Restaurant E 餐廳、 e-Museum E 博物館…只要你想像得到的,都可以給它 E 一下。這叫做 E 化, E-ize

    + +

    這麼多 E ,看得讓人眼花撩亂。彷彿多 E 個幾下,才跟得上全世界網際網路的腳步。可笑的是,所謂的 E,其實國外沒有這種說法。我問過很多外國人,尤其是講英語為主的美國人。對外國人來說,像 e-Shope-Government ,他們看到字大概可以瞭解是什麼意思,不過他們不這樣講。商店就是商店,上了網還是商店;政府就是政府,上了網還是政府。不會一個政府上了網就變成了 E 政府,一家商店上了網就變成了 E 商店。喜歡 EE 去,似乎成了台灣人的專利。

    + +

    每次看到滿街 E 這個 E 那個的文宣、廣告,就讓人很頭痛。唉~

    + +
    + +
    + +
    +
    9.17.’06. 12:18pm.
    + +

    文言文

    + +

    這個學期是我在空大最後一個學期了。只剩下六個學分就畢業了,不需要像之前一樣一學期趕五門課,面授從早上到晚滿滿十個小時。

    + +

    我修了三門課:台灣史重要文獻導讀中國社會史古典短篇小說選讀。應該可以輕鬆一些。暑修修過了會計學概要,於是我選了我剩下最想修的課台灣史。

    + +

    前兩天去買課本,中國社會史暫時沒書,我先拿了台灣史重要文獻導讀古典短篇小說選讀。拿到課本翻了翻,有點臉綠掉了:文言文!我早該想到的,史料文獻當然是文言文,古典小說自然更一定是文言文。這下慘了,大概沒辦法像之前修的課,讀得那麼輕鬆了。唉~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 72 | + 73 | + 74 | + 75 | + 76 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0074.html.zh-cn.html b/htdocs/imacat/me/diary/0074.html.zh-cn.html new file mode 120000 index 0000000..208fe42 --- /dev/null +++ b/htdocs/imacat/me/diary/0074.html.zh-cn.html @@ -0,0 +1 @@ +0074.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0074.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0074.html.zh-cn.xhtml new file mode 100644 index 0000000..c5c8e7e --- /dev/null +++ b/htdocs/imacat/me/diary/0074.html.zh-cn.xhtml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷七十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷七十四

    + +
    + +
    + +
    +
    9.17.’06. 11:19pm.
    + +

    E 化万岁 e-Everything

    + +

    台湾有一个很特殊的现象,就是很喜欢 Ee-maile-Businesse-Commercee-Marketing E 行销 、 e-Shop E 商店、 e-Bank E 银行、 e-Government E 政府、 e-School E 学校、 e-Map E 地图、 e-Restaurant E 餐厅、 e-Museum E 博物馆…只要你想像得到的,都可以给它 E 一下。这叫做 E 化, E-ize

    + +

    这么多 E ,看得让人眼花撩乱。彷佛多 E 个几下,才跟得上全世界网际网路的脚步。可笑的是,所谓的 E,其实国外没有这种说法。我问过很多外国人,尤其是讲英语为主的美国人。对外国人来说,像 e-Shope-Government ,他们看到字大概可以了解是什么意思,不过他们不这样讲。商店就是商店,上了网还是商店;政府就是政府,上了网还是政府。不会一个政府上了网就变成了 E 政府,一家商店上了网就变成了 E 商店。喜欢 EE 去,似乎成了台湾人的专利。

    + +

    每次看到满街 E 这个 E 那个的文宣、广告,就让人很头痛。唉~

    + +
    + +
    + +
    +
    9.17.’06. 12:18pm.
    + +

    文言文

    + +

    这个学期是我在空大最后一个学期了。只剩下六个学分就毕业了,不需要像之前一样一学期赶五门课,面授从早上到晚满满十个小时。

    + +

    我修了三门课:台湾史重要文献导读中国社会史古典短篇小说选读。应该可以轻松一些。暑修修过了会计学概要,於是我选了我剩下最想修的课台湾史。

    + +

    前两天去买课本,中国社会史暂时没书,我先拿了台湾史重要文献导读古典短篇小说选读。拿到课本翻了翻,有点脸绿掉了:文言文!我早该想到的,史料文献当然是文言文,古典小说自然更一定是文言文。这下惨了,大概没办法像之前修的课,读得那么轻松了。唉~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 72 | + 73 | + 74 | + 75 | + 76 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0074.html.zh-tw.html b/htdocs/imacat/me/diary/0074.html.zh-tw.html new file mode 120000 index 0000000..3ed5d75 --- /dev/null +++ b/htdocs/imacat/me/diary/0074.html.zh-tw.html @@ -0,0 +1 @@ +0074.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0074.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0074.html.zh-tw.xhtml new file mode 100644 index 0000000..0dab161 --- /dev/null +++ b/htdocs/imacat/me/diary/0074.html.zh-tw.xhtml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷七十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷七十四

    + +
    + +
    + +
    +
    9.17.’06. 11:19pm.
    + +

    E 化萬歲 e-Everything

    + +

    台灣有一個很特殊的現象,就是很喜歡 Ee-maile-Businesse-Commercee-Marketing E 行銷 、 e-Shop E 商店、 e-Bank E 銀行、 e-Government E 政府、 e-School E 學校、 e-Map E 地圖、 e-Restaurant E 餐廳、 e-Museum E 博物館…只要你想像得到的,都可以給它 E 一下。這叫做 E 化, E-ize

    + +

    這麼多 E ,看得讓人眼花撩亂。彷彿多 E 個幾下,才跟得上全世界網際網路的腳步。可笑的是,所謂的 E,其實國外沒有這種說法。我問過很多外國人,尤其是講英語為主的美國人。對外國人來說,像 e-Shope-Government ,他們看到字大概可以瞭解是什麼意思,不過他們不這樣講。商店就是商店,上了網還是商店;政府就是政府,上了網還是政府。不會一個政府上了網就變成了 E 政府,一家商店上了網就變成了 E 商店。喜歡 EE 去,似乎成了台灣人的專利。

    + +

    每次看到滿街 E 這個 E 那個的文宣、廣告,就讓人很頭痛。唉~

    + +
    + +
    + +
    +
    9.17.’06. 12:18pm.
    + +

    文言文

    + +

    這個學期是我在空大最後一個學期了。只剩下六個學分就畢業了,不需要像之前一樣一學期趕五門課,面授從早上到晚滿滿十個小時。

    + +

    我修了三門課:台灣史重要文獻導讀中國社會史古典短篇小說選讀。應該可以輕鬆一些。暑修修過了會計學概要,於是我選了我剩下最想修的課台灣史。

    + +

    前兩天去買課本,中國社會史暫時沒書,我先拿了台灣史重要文獻導讀古典短篇小說選讀。拿到課本翻了翻,有點臉綠掉了:文言文!我早該想到的,史料文獻當然是文言文,古典小說自然更一定是文言文。這下慘了,大概沒辦法像之前修的課,讀得那麼輕鬆了。唉~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 72 | + 73 | + 74 | + 75 | + 76 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0075.html.en.html b/htdocs/imacat/me/diary/0075.html.en.html new file mode 120000 index 0000000..88a320d --- /dev/null +++ b/htdocs/imacat/me/diary/0075.html.en.html @@ -0,0 +1 @@ +0075.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0075.html.en.xhtml b/htdocs/imacat/me/diary/0075.html.en.xhtml new file mode 100644 index 0000000..531151f --- /dev/null +++ b/htdocs/imacat/me/diary/0075.html.en.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 75 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 75

    + +
    + +
    + +
    +
    9.18.’06. 0:17am.
    + +

    樸克牌算命

    + +

    高中時候的我,不知道為什麼,很迷樸克牌算命。那時候我每天都會用樸克牌算一次命;我還有特別保留一副樸克牌,專門用來算命用的,不能夠拿來玩,以免不敬。

    + +

    不知道為什麼,到底是怎麼個算法,那時候每天做的事,現在一點都想不起來。有點小小難過。

    + +
    + +
    + +
    +
    9.18.’06. 0:05am.
    + +

    樹枝狀關聯式學習線

    + +

    我發現,像這樣很有趣:一開始是原著漫畫 NANA ,覺得很有趣,試著去追電影 NANA (2005) 。這裏產生一個分枝點:一條追著作者矢沢あい(矢澤愛)的所有作品看,看到了連載的周刊 Cookie,然後又看到了周刊 Cookie最新連載中的漫畫林檎と蜂蜜;另一條則從電影下弦の月~ラスト・クォーター (2004)起,追到了栗山千明,然後追著去看追殺比爾 (2003,2004);原來的分歧點則從 NANA本城蓮 Sid Vicious 的形象,追到電影 Sid & Nancy (1986) ,然後追到 Courtney Love ,到 Hole 樂團。

    + +

    好奇心的探索,知識的追尋,就像這樣,從一件事追到另一件事,想窮盡自己想知道的所有事,可是在追尋的旅途上每一點都有可能分叉出去,進入好幾條知識主題。

    + +

    這樣好像給自己太累了,不過也真的很有趣呢~ ^_*'

    + +
    + +
    + +
    +
    9.17.’06. 11:45pm.
    + +

    奈米萬歲 nano-Everything

    + +

    除了 E 以外,台灣還有另外一個非常神奇的東西,叫做奈米

    + +

    回想起來,從 SARS 疫情的時候,廠商推出、大家搶購奈米光觸媒開始,奈米兩個字就一砲而紅。之後奈米兩個字就無孔不入地侵入我們的生活,不管賣什麼,所有妳想得到的東西,都一定要冠上奈米:奈米冰箱、奈米電視、奈米洗衣機、奈米馬桶、奈米抗菌被、奈米內衣、奈米襪、奈米胸罩、奈米減肥療法、奈米大樓、奈米汽車…舉凡食、衣、住、行,奈米通通都全包了。

    + +

    上個星期,上班的路上,看到一家新的店,賣奈米水泥漆。連水泥漆也可以奈米一下,真是太厲害了~

    + +

    奈米是什麼?奈米 nano 是百萬分之一米(公尺),是極細微的長度單位。奈米科技,就是指在百萬分之一米大小的範圍內操作的科技,也就是比以前所稱的顯微科技更細微百倍。如果可以把光碟的儲存單位劃分得這麼小,那同樣大小的光碟,就可以比原來存更多的資料。這就是奈米科技的最大好處。

    + +

    那麼,這樣的細微科技,跟冰箱什麼關係?跟電視什麼關係?跟內衣什麼關係?跟襪子什麼關係?跟水泥漆什麼關係?冰箱怎麼個奈米法?汽車怎麼個奈米法?奈米汽車時速百萬分之一米嗎?襪子一條五奈米長嗎?馬桶只能塞得下五十奈米長的大便嗎?這些奈米來奈米去無限奈米的東西,到底跟奈米有什麼關係?

    + +

    食衣住行以後是育樂,接下來應該是奈米補習班、奈米雲宵飛車、奈米新聞、奈米綜藝秀…台灣人真是瘋了~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 73 | + 74 | + 75 | + 76 | + 77 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0075.html.zh-cn.html b/htdocs/imacat/me/diary/0075.html.zh-cn.html new file mode 120000 index 0000000..9f23479 --- /dev/null +++ b/htdocs/imacat/me/diary/0075.html.zh-cn.html @@ -0,0 +1 @@ +0075.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0075.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0075.html.zh-cn.xhtml new file mode 100644 index 0000000..88457e7 --- /dev/null +++ b/htdocs/imacat/me/diary/0075.html.zh-cn.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷七十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷七十五

    + +
    + +
    + +
    +
    9.18.’06. 0:17am.
    + +

    朴克牌算命

    + +

    高中时候的我,不知道为什么,很迷朴克牌算命。那时候我每天都会用朴克牌算一次命;我还有特别保留一副朴克牌,专门用来算命用的,不能够拿来玩,以免不敬。

    + +

    不知道为什么,到底是怎么个算法,那时候每天做的事,现在一点都想不起来。有点小小难过。

    + +
    + +
    + +
    +
    9.18.’06. 0:05am.
    + +

    树枝状关联式学习线

    + +

    我发现,像这样很有趣:一开始是原著漫画 NANA ,觉得很有趣,试著去追电影 NANA (2005) 。这里产生一个分枝点:一条追著作者矢沢あい(矢泽爱)的所有作品看,看到了连载的周刊 Cookie,然后又看到了周刊 Cookie最新连载中的漫画林檎と蜂蜜;另一条则从电影下弦の月~ラスト・クォーター (2004)起,追到了栗山千明,然后追著去看追杀比尔 (2003,2004);原来的分歧点则从 NANA本城莲 Sid Vicious 的形象,追到电影 Sid & Nancy (1986) ,然后追到 Courtney Love ,到 Hole 乐团。

    + +

    好奇心的探索,知识的追寻,就像这样,从一件事追到另一件事,想穷尽自己想知道的所有事,可是在追寻的旅途上每一点都有可能分叉出去,进入好几条知识主题。

    + +

    这样好像给自己太累了,不过也真的很有趣呢~ ^_*'

    + +
    + +
    + +
    +
    9.17.’06. 11:45pm.
    + +

    奈米万岁 nano-Everything

    + +

    除了 E 以外,台湾还有另外一个非常神奇的东西,叫做奈米

    + +

    回想起来,从 SARS 疫情的时候,厂商推出、大家抢购奈米光触媒开始,奈米两个字就一炮而红。之后奈米两个字就无孔不入地侵入我们的生活,不管卖什么,所有你想得到的东西,都一定要冠上奈米:奈米冰箱、奈米电视、奈米洗衣机、奈米马桶、奈米抗菌被、奈米内衣、奈米袜、奈米胸罩、奈米减肥疗法、奈米大楼、奈米汽车…举凡食、衣、住、行,奈米通通都全包了。

    + +

    上个星期,上班的路上,看到一家新的店,卖奈米水泥漆。连水泥漆也可以奈米一下,真是太厉害了~

    + +

    奈米是什么?奈米 nano 是百万分之一米(公尺),是极细微的长度单位。奈米科技,就是指在百万分之一米大小的范围内操作的科技,也就是比以前所称的显微科技更细微百倍。如果可以把光碟的储存单位划分得这么小,那同样大小的光碟,就可以比原来存更多的资料。这就是奈米科技的最大好处。

    + +

    那么,这样的细微科技,跟冰箱什么关系?跟电视什么关系?跟内衣什么关系?跟袜子什么关系?跟水泥漆什么关系?冰箱怎么个奈米法?汽车怎么个奈米法?奈米汽车时速百万分之一米吗?袜子一条五奈米长吗?马桶只能塞得下五十奈米长的大便吗?这些奈米来奈米去无限奈米的东西,到底跟奈米有什么关系?

    + +

    食衣住行以后是育乐,接下来应该是奈米补习班、奈米云宵飞车、奈米新闻、奈米综艺秀…台湾人真是疯了~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 73 | + 74 | + 75 | + 76 | + 77 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0075.html.zh-tw.html b/htdocs/imacat/me/diary/0075.html.zh-tw.html new file mode 120000 index 0000000..f8392a3 --- /dev/null +++ b/htdocs/imacat/me/diary/0075.html.zh-tw.html @@ -0,0 +1 @@ +0075.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0075.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0075.html.zh-tw.xhtml new file mode 100644 index 0000000..ffd60a3 --- /dev/null +++ b/htdocs/imacat/me/diary/0075.html.zh-tw.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷七十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷七十五

    + +
    + +
    + +
    +
    9.18.’06. 0:17am.
    + +

    樸克牌算命

    + +

    高中時候的我,不知道為什麼,很迷樸克牌算命。那時候我每天都會用樸克牌算一次命;我還有特別保留一副樸克牌,專門用來算命用的,不能夠拿來玩,以免不敬。

    + +

    不知道為什麼,到底是怎麼個算法,那時候每天做的事,現在一點都想不起來。有點小小難過。

    + +
    + +
    + +
    +
    9.18.’06. 0:05am.
    + +

    樹枝狀關聯式學習線

    + +

    我發現,像這樣很有趣:一開始是原著漫畫 NANA ,覺得很有趣,試著去追電影 NANA (2005) 。這裏產生一個分枝點:一條追著作者矢沢あい(矢澤愛)的所有作品看,看到了連載的周刊 Cookie,然後又看到了周刊 Cookie最新連載中的漫畫林檎と蜂蜜;另一條則從電影下弦の月~ラスト・クォーター (2004)起,追到了栗山千明,然後追著去看追殺比爾 (2003,2004);原來的分歧點則從 NANA本城蓮 Sid Vicious 的形象,追到電影 Sid & Nancy (1986) ,然後追到 Courtney Love ,到 Hole 樂團。

    + +

    好奇心的探索,知識的追尋,就像這樣,從一件事追到另一件事,想窮盡自己想知道的所有事,可是在追尋的旅途上每一點都有可能分叉出去,進入好幾條知識主題。

    + +

    這樣好像給自己太累了,不過也真的很有趣呢~ ^_*'

    + +
    + +
    + +
    +
    9.17.’06. 11:45pm.
    + +

    奈米萬歲 nano-Everything

    + +

    除了 E 以外,台灣還有另外一個非常神奇的東西,叫做奈米

    + +

    回想起來,從 SARS 疫情的時候,廠商推出、大家搶購奈米光觸媒開始,奈米兩個字就一砲而紅。之後奈米兩個字就無孔不入地侵入我們的生活,不管賣什麼,所有妳想得到的東西,都一定要冠上奈米:奈米冰箱、奈米電視、奈米洗衣機、奈米馬桶、奈米抗菌被、奈米內衣、奈米襪、奈米胸罩、奈米減肥療法、奈米大樓、奈米汽車…舉凡食、衣、住、行,奈米通通都全包了。

    + +

    上個星期,上班的路上,看到一家新的店,賣奈米水泥漆。連水泥漆也可以奈米一下,真是太厲害了~

    + +

    奈米是什麼?奈米 nano 是百萬分之一米(公尺),是極細微的長度單位。奈米科技,就是指在百萬分之一米大小的範圍內操作的科技,也就是比以前所稱的顯微科技更細微百倍。如果可以把光碟的儲存單位劃分得這麼小,那同樣大小的光碟,就可以比原來存更多的資料。這就是奈米科技的最大好處。

    + +

    那麼,這樣的細微科技,跟冰箱什麼關係?跟電視什麼關係?跟內衣什麼關係?跟襪子什麼關係?跟水泥漆什麼關係?冰箱怎麼個奈米法?汽車怎麼個奈米法?奈米汽車時速百萬分之一米嗎?襪子一條五奈米長嗎?馬桶只能塞得下五十奈米長的大便嗎?這些奈米來奈米去無限奈米的東西,到底跟奈米有什麼關係?

    + +

    食衣住行以後是育樂,接下來應該是奈米補習班、奈米雲宵飛車、奈米新聞、奈米綜藝秀…台灣人真是瘋了~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 73 | + 74 | + 75 | + 76 | + 77 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0076.html.en.html b/htdocs/imacat/me/diary/0076.html.en.html new file mode 120000 index 0000000..a56c36c --- /dev/null +++ b/htdocs/imacat/me/diary/0076.html.en.html @@ -0,0 +1 @@ +0076.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0076.html.en.xhtml b/htdocs/imacat/me/diary/0076.html.en.xhtml new file mode 100644 index 0000000..d4cfa85 --- /dev/null +++ b/htdocs/imacat/me/diary/0076.html.en.xhtml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 76 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 76

    + +
    + +
    + +
    +
    9.18.’06. 1:19am.
    + +

    X-Men: The Last Stand X 戰警:最後戰役—超人大雜燴

    + +
    +X-Men: The Last Stand X 戰警:最後戰役
    +

    X-Men: The Last Stand X 戰警:最後戰役

    +
    + + + +

    這是我在 2006-09-04 高雄飛北海道的華航包機上看的。

    + +

    X 戰警:最後戰役故事敘述人類發明了一種藥,能夠抑制變種人的基因,達成治癒變種人的效果。這種藥使變種人內部分裂成兩派,一派由萬磁王率領,堅信這種藥只是把人類要把變種人病態化,藉以消滅變種人的陰謀,主張消滅這種藥;另一派則由 X 教授率領,試圖視若無睹。兩派衝突越演越烈,最後導致萬磁王率領變種人,向人類全面進攻。最後的勝敗關鍵,取決於精神瀕臨崩潰邊緣的鳳凰女身上。

    + +

    我沒有看過之前的 X 戰警。不知道是不是漫畫改編的, X 戰警像一部超人大雜燴,把各種各樣的超人都集在一起了:閃電俠、狼人、冰人、火人…讓你一次看個夠!感覺有點扯。

    + +

    網路上有人覺得第三集比第一集強,劇情有深度得多:抑制變種人的基因的藥,倒底是賦與變種人自主決定權,還是要消滅變種人?想想倒也是不錯。美國工會法規定罷工禁止設立糾察隊,阻止工人上工,表面上是賦與工人工作自主權,實際上無強制動員力的工會,造成工會長期積弱不振。道理是一樣的。不過從電影到最後選擇溫馴的變種人勝利來看,導演的立場,其實也非常清楚。

    + +

    無論如何,超人大雜燴,還是讓我覺得可笑莫名。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 74 | + 75 | + 76 | + 77 | + 78 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0076.html.zh-cn.html b/htdocs/imacat/me/diary/0076.html.zh-cn.html new file mode 120000 index 0000000..82fdd47 --- /dev/null +++ b/htdocs/imacat/me/diary/0076.html.zh-cn.html @@ -0,0 +1 @@ +0076.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0076.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0076.html.zh-cn.xhtml new file mode 100644 index 0000000..029210b --- /dev/null +++ b/htdocs/imacat/me/diary/0076.html.zh-cn.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷七十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷七十六

    + +
    + +
    + +
    +
    9.18.’06. 1:19am.
    + +

    X-Men: The Last Stand X 战警:最后战役—超人大杂烩

    + +
    +X-Men: The Last Stand X 战警:最后战役
    +

    X-Men: The Last Stand X 战警:最后战役

    +
    + + + +

    这是我在 2006-09-04 高雄飞北海道的华航包机上看的。

    + +

    X 战警:最后战役故事叙述人类发明了一种药,能够抑制变种人的基因,达成治愈变种人的效果。这种药使变种人内部分裂成两派,一派由万磁王率领,坚信这种药只是把人类要把变种人病态化,藉以消灭变种人的阴谋,主张消灭这种药;另一派则由 X 教授率领,试图视若无睹。两派冲突越演越烈,最后导致万磁王率领变种人,向人类全面进攻。最后的胜败关键,取决於精神濒临崩溃边缘的凤凰女身上。

    + +

    我没有看过之前的 X 战警。不知道是不是漫画改编的, X 战警像一部超人大杂烩,把各种各样的超人都集在一起了:闪电侠、狼人、冰人、火人…让你一次看个够!感觉有点扯。

    + +

    网路上有人觉得第三集比第一集强,剧情有深度得多:抑制变种人的基因的药,倒底是赋与变种人自主决定权,还是要消灭变种人?想想倒也是不错。美国工会法规定罢工禁止设立纠察队,阻止工人上工,表面上是赋与工人工作自主权,实际上无强制动员力的工会,造成工会长期积弱不振。道理是一样的。不过从电影到最后选择温驯的变种人胜利来看,导演的立场,其实也非常清楚。

    + +

    无论如何,超人大杂烩,还是让我觉得可笑莫名。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 74 | + 75 | + 76 | + 77 | + 78 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0076.html.zh-tw.html b/htdocs/imacat/me/diary/0076.html.zh-tw.html new file mode 120000 index 0000000..2910c60 --- /dev/null +++ b/htdocs/imacat/me/diary/0076.html.zh-tw.html @@ -0,0 +1 @@ +0076.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0076.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0076.html.zh-tw.xhtml new file mode 100644 index 0000000..99a729c --- /dev/null +++ b/htdocs/imacat/me/diary/0076.html.zh-tw.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷七十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷七十六

    + +
    + +
    + +
    +
    9.18.’06. 1:19am.
    + +

    X-Men: The Last Stand X 戰警:最後戰役—超人大雜燴

    + +
    +X-Men: The Last Stand X 戰警:最後戰役
    +

    X-Men: The Last Stand X 戰警:最後戰役

    +
    + + + +

    這是我在 2006-09-04 高雄飛北海道的華航包機上看的。

    + +

    X 戰警:最後戰役故事敘述人類發明了一種藥,能夠抑制變種人的基因,達成治癒變種人的效果。這種藥使變種人內部分裂成兩派,一派由萬磁王率領,堅信這種藥只是把人類要把變種人病態化,藉以消滅變種人的陰謀,主張消滅這種藥;另一派則由 X 教授率領,試圖視若無睹。兩派衝突越演越烈,最後導致萬磁王率領變種人,向人類全面進攻。最後的勝敗關鍵,取決於精神瀕臨崩潰邊緣的鳳凰女身上。

    + +

    我沒有看過之前的 X 戰警。不知道是不是漫畫改編的, X 戰警像一部超人大雜燴,把各種各樣的超人都集在一起了:閃電俠、狼人、冰人、火人…讓你一次看個夠!感覺有點扯。

    + +

    網路上有人覺得第三集比第一集強,劇情有深度得多:抑制變種人的基因的藥,倒底是賦與變種人自主決定權,還是要消滅變種人?想想倒也是不錯。美國工會法規定罷工禁止設立糾察隊,阻止工人上工,表面上是賦與工人工作自主權,實際上無強制動員力的工會,造成工會長期積弱不振。道理是一樣的。不過從電影到最後選擇溫馴的變種人勝利來看,導演的立場,其實也非常清楚。

    + +

    無論如何,超人大雜燴,還是讓我覺得可笑莫名。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 74 | + 75 | + 76 | + 77 | + 78 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0077.html.en.html b/htdocs/imacat/me/diary/0077.html.en.html new file mode 120000 index 0000000..b252d31 --- /dev/null +++ b/htdocs/imacat/me/diary/0077.html.en.html @@ -0,0 +1 @@ +0077.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0077.html.en.xhtml b/htdocs/imacat/me/diary/0077.html.en.xhtml new file mode 100644 index 0000000..dd7cc14 --- /dev/null +++ b/htdocs/imacat/me/diary/0077.html.en.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 77 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 77

    + +
    + +
    + +
    +
    9.18.’06. 11:38pm.
    + +

    Maximum Velocity 極速任務—又一部自然災難片

    + +
    +Maximum Velocity 極速任務
    +

    Maximum Velocity 極速任務

    +
    + + + +

    極速任務敘述布里格博士四年前與妻子凱倫共同參加安柏森將軍的機密軍事計劃颶風計劃,企圖製造人造颶風作武器。凱倫在操作獨立操作艙,消滅人造颶風的過程中,不幸失敗喪生。失控的人造颶風造成沿海地區災害,計劃密封,成員被迫解散。痛失愛妻的布里格博士從此心灰意冷。四年後,因為突如其來的隕石,造成地球氣候混亂,產生史上最大的颶風,在一天內會毀滅半個美國。奈特莉博士接下這個任務,強迫安柏森將軍把計劃解凍,以取得消滅颶風的裝置,並力邀心灰意冷的布里格博士回來解救危機。奈特莉博士同樣要操作獨立操作艙。面對超級巨大的自然力量,緊迫的時間,滿腹私心的安柏森將軍,四年前的悲劇,眼看就要重演。

    + +

    我是在 2006-09-10 統聯高雄回台北的車上,看到極速任務極速任務是一部很普通的災難電影,說不上是好是壞。中文片名譯得很爛。

    + +

    那晚在統聯車上看的,還有火山高校。不過火山高校我沒有看完整。等完整重看一遍了以後再寫吧~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 75 | + 76 | + 77 | + 78 | + 79 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0077.html.zh-cn.html b/htdocs/imacat/me/diary/0077.html.zh-cn.html new file mode 120000 index 0000000..c02e09f --- /dev/null +++ b/htdocs/imacat/me/diary/0077.html.zh-cn.html @@ -0,0 +1 @@ +0077.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0077.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0077.html.zh-cn.xhtml new file mode 100644 index 0000000..4ae65ff --- /dev/null +++ b/htdocs/imacat/me/diary/0077.html.zh-cn.xhtml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷七十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷七十七

    + +
    + +
    + +
    +
    9.18.’06. 11:38pm.
    + +

    Maximum Velocity 极速任务—又一部自然灾难片

    + +
    +Maximum Velocity 极速任务
    +

    Maximum Velocity 极速任务

    +
    + + + +

    极速任务叙述布里格博士四年前与妻子凯伦共同参加安柏森将军的机密军事计划飓风计划,企图制造人造飓风作武器。凯伦在操作独立操作舱,消灭人造飓风的过程中,不幸失败丧生。失控的人造飓风造成沿海地区灾害,计划密封,成员被迫解散。痛失爱妻的布里格博士从此心灰意冷。四年后,因为突如其来的陨石,造成地球气候混乱,产生史上最大的飓风,在一天内会毁灭半个美国。奈特莉博士接下这个任务,强迫安柏森将军把计划解冻,以取得消灭飓风的装置,并力邀心灰意冷的布里格博士回来解救危机。奈特莉博士同样要操作独立操作舱。面对超级巨大的自然力量,紧迫的时间,满腹私心的安柏森将军,四年前的悲剧,眼看就要重演。

    + +

    我是在 2006-09-10 统联高雄回台北的车上,看到极速任务极速任务是一部很普通的灾难电影,说不上是好是坏。中文片名译得很烂。

    + +

    那晚在统联车上看的,还有火山高校。不过火山高校我没有看完整。等完整重看一遍了以后再写吧~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 75 | + 76 | + 77 | + 78 | + 79 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0077.html.zh-tw.html b/htdocs/imacat/me/diary/0077.html.zh-tw.html new file mode 120000 index 0000000..66eae12 --- /dev/null +++ b/htdocs/imacat/me/diary/0077.html.zh-tw.html @@ -0,0 +1 @@ +0077.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0077.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0077.html.zh-tw.xhtml new file mode 100644 index 0000000..026b9a1 --- /dev/null +++ b/htdocs/imacat/me/diary/0077.html.zh-tw.xhtml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷七十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷七十七

    + +
    + +
    + +
    +
    9.18.’06. 11:38pm.
    + +

    Maximum Velocity 極速任務—又一部自然災難片

    + +
    +Maximum Velocity 極速任務
    +

    Maximum Velocity 極速任務

    +
    + + + +

    極速任務敘述布里格博士四年前與妻子凱倫共同參加安柏森將軍的機密軍事計劃颶風計劃,企圖製造人造颶風作武器。凱倫在操作獨立操作艙,消滅人造颶風的過程中,不幸失敗喪生。失控的人造颶風造成沿海地區災害,計劃密封,成員被迫解散。痛失愛妻的布里格博士從此心灰意冷。四年後,因為突如其來的隕石,造成地球氣候混亂,產生史上最大的颶風,在一天內會毀滅半個美國。奈特莉博士接下這個任務,強迫安柏森將軍把計劃解凍,以取得消滅颶風的裝置,並力邀心灰意冷的布里格博士回來解救危機。奈特莉博士同樣要操作獨立操作艙。面對超級巨大的自然力量,緊迫的時間,滿腹私心的安柏森將軍,四年前的悲劇,眼看就要重演。

    + +

    我是在 2006-09-10 統聯高雄回台北的車上,看到極速任務極速任務是一部很普通的災難電影,說不上是好是壞。中文片名譯得很爛。

    + +

    那晚在統聯車上看的,還有火山高校。不過火山高校我沒有看完整。等完整重看一遍了以後再寫吧~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 75 | + 76 | + 77 | + 78 | + 79 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0078.html.en.html b/htdocs/imacat/me/diary/0078.html.en.html new file mode 120000 index 0000000..ec2506b --- /dev/null +++ b/htdocs/imacat/me/diary/0078.html.en.html @@ -0,0 +1 @@ +0078.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0078.html.en.xhtml b/htdocs/imacat/me/diary/0078.html.en.xhtml new file mode 100644 index 0000000..9fbadcc --- /dev/null +++ b/htdocs/imacat/me/diary/0078.html.en.xhtml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 78 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 78

    + +
    + +
    + +
    +
    9.23.’06. 1:57am.
    + +

    省港旗兵續集—大圈仔打打殺殺好可怕

    + +
    +省港旗兵續集
    +

    省港旗兵續集

    +
    + +
      +
    • 片名:省港旗兵續集
    • +
    • 英文片名: Long Arm of the Law — Sage Ⅱ
    • +
    • 發行年份: 1987
    • +
    • 製作公司:麥當雄製作有限公司
    • +
    • 出品人:鄒文懷
    • +
    • 監製:麥當雄
    • +
    • 導演:麥當傑
    • +
    • 演員: +
        +
      • 萬梓良:大大
      • +
      • 徐錦江:李向東
      • +
      • 林國斌:戚京生
      • +
      • 袁日初:郭學軍
      • +
      • 王小鳳:黛安娜
      • +
      • 江龍:阿虎
      • +
      • 葉晨:阿虎妹
      • +
      • 韓義生:黑鬼唐
      • +
      • 黃志強:興仔
      • +
      • 成奎安:江氏四兄弟之一
      • +
      • 陳敬:江氏四兄弟之一
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    省港旗兵續集延續第一集的背景,香港治安被大圈仔搞得越來越敗壞,程警官決定以圈治圈,由偷渡客中挑出有公安背景的李向東、戚京生、郭學軍三人,誘以香港永久拘留權,以作臥底協助破案,並指派臥底十三年的警察大大接應。大大原瞧不起三人,帶三人買私槍時,撞見仇家,被三人所救,與三人結為莫逆。大大安排三人接買賣:珠寶商為騙取保險金僱黑道興仔搶劫,興仔反以珠寶勒索,四人在其母壽宴上立威,名動黑道。做賊贓買賣的長洲與江姓兄弟買賣糾紛,僱三人作保鑣,沒想江姓兄弟是向東多年前逮補過的罪犯,被認出曾是公安,混戰中殺了對方,事情越鬧越大。京生從前戰友阿虎也移民到了香港,京生會面時,發現對方正是此次逮補的對象,無奈阿虎曾救己一命,且已愛上其妹。阿虎邀請京生三人一起搶劫銀行。然阿虎兄弟楊才是江姓兄弟的朋友,亟欲替友復仇,阿虎等人未知是三人所為,找上大大逼供三人身份,逼供不成殺了大大。學軍愛上長洲乾妹舞女黛安娜,黛安娜鼓動學軍,偷竊執勤公款,以假護照兩人遠走高飛,誰知黛安娜暗中透過另一小白臉,在機場檢舉學軍持假護照,學軍發現後大鬧機場,向小白臉開槍後逃逸。機場風波輿論猛烈抨擊,上級打算趁老虎和向東的銀行搶案,一舉滅口,阿虎同伙也逐漸發現三人身份。三人至此已四面楚歌,窮途末路。

    + +

    省港旗兵續集好像有個副標兵分兩路。我不知道這個副標是哪裏來的,找到的電影封面、海報都沒有這個副標。從劇情來看,也看不出哪裏有什麼兵分兩路

    + +

    省港旗兵續集起,麥當雄就又放下導演座,由其弟麥當傑執導。麥當傑和其哥不同,是有經驗的專業導演,也一改前集全部起用無經驗的非專業演員的作法,改找許多有經驗的專業演員,如萬梓良、徐錦江、王小鳳等主演。

    + +

    省港旗兵續集因為製作班底都是專業電影人,戲感強,劇情結構玄奇繁複得多,娛樂性高。但我覺得整體上來說,省港旗兵續集不如省港旗兵。從導演到演員都是有經驗的專業電影人,少了一份樸實的寫實震憾力。省港旗兵簡單樸實的劇情,簡單樸實的演出,簡單樸實的運鏡,寫實的震憾力,是續集所無法比擬的。省港旗兵在九龍寨城的巷弄槍戰,手提攝影機帶來的寫實緊張感,四人每一分鐘都逐漸邁入窮途末路的絕望感,都無可比擬。相對來說,省港旗兵續集在出租公寓的巷戰運鏡較成熟商業化,最後結局則沒有太大的說服力。只要程警官一念良心發現,或是向東現實一點,挾程警官作人質求生,就不會全軍覆沒了。太多個人戲劇化的偶然決定,失去了第一集令人窒息的宿命感。省港旗兵續集劇情過於繁複(從上面的劇情記要就可以看得出來),使得很多很深刻的社會矛盾,都沒有辦法呈現出來。看完後除了覺得大圈仔打打殺殺好可怕以外,沒有什麼感覺。

    + +

    徐錦江原來拍電影浮浮沉沉,在省港旗兵續集裏有很搶眼的表現,從此受到注目。林國斌因省港旗兵續集得到香港電影金像獎最佳新人獎。第一集的大圈仔新人演員中,只有江龍和陳敬繼續演出。江龍改演反派老虎一角,有點八中復活的感覺,不過江龍感覺很清秀,演反派眼神不夠兇惡。陳敬出場沒幾秒就死了,看得不是很清楚。

    + +

    大大被殺一幕,被倒吊蒙頭,用斧頭把頭硬斫下來,頗為觸目驚心。

    + +

    林國斌以戚京生一角,得到香港電影金像獎最佳新人獎。

    + +

    阿虎的妹妹應該是葉晨演的吧。網路上找不到葉晨的照片資料,不知道要到哪裏求證。很搶眼、戲份很多的角色,不知道為什麼在演員表上排得很後面。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 76 | + 77 | + 78 | + 79 | + 80 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0078.html.zh-cn.html b/htdocs/imacat/me/diary/0078.html.zh-cn.html new file mode 120000 index 0000000..0924aa2 --- /dev/null +++ b/htdocs/imacat/me/diary/0078.html.zh-cn.html @@ -0,0 +1 @@ +0078.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0078.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0078.html.zh-cn.xhtml new file mode 100644 index 0000000..aac97bb --- /dev/null +++ b/htdocs/imacat/me/diary/0078.html.zh-cn.xhtml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷七十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷七十八

    + +
    + +
    + +
    +
    9.23.’06. 1:57am.
    + +

    省港旗兵续集—大圈仔打打杀杀好可怕

    + +
    +省港旗兵续集
    +

    省港旗兵续集

    +
    + +
      +
    • 片名:省港旗兵续集
    • +
    • 英文片名: Long Arm of the Law — Sage Ⅱ
    • +
    • 发行年份: 1987
    • +
    • 制作公司:麦当雄制作有限公司
    • +
    • 出品人:邹文怀
    • +
    • 监制:麦当雄
    • +
    • 导演:麦当杰
    • +
    • 演员: +
        +
      • 万梓良:大大
      • +
      • 徐锦江:李向东
      • +
      • 林国斌:戚京生
      • +
      • 袁日初:郭学军
      • +
      • 王小凤:黛安娜
      • +
      • 江龙:阿虎
      • +
      • 叶晨:阿虎妹
      • +
      • 韩义生:黑鬼唐
      • +
      • 黄志强:兴仔
      • +
      • 成奎安:江氏四兄弟之一
      • +
      • 陈敬:江氏四兄弟之一
      • +
      +
    • +
    • 推荐影评: + +
    • +
    + +

    省港旗兵续集延续第一集的背景,香港治安被大圈仔搞得越来越败坏,程警官决定以圈治圈,由偷渡客中挑出有公安背景的李向东、戚京生、郭学军三人,诱以香港永久拘留权,以作卧底协助破案,并指派卧底十三年的警察大大接应。大大原瞧不起三人,带三人买私枪时,撞见仇家,被三人所救,与三人结为莫逆。大大安排三人接买卖:珠宝商为骗取保险金雇黑道兴仔抢劫,兴仔反以珠宝勒索,四人在其母寿宴上立威,名动黑道。做贼赃买卖的长洲与江姓兄弟买卖纠纷,雇三人作保镳,没想江姓兄弟是向东多年前逮补过的罪犯,被认出曾是公安,混战中杀了对方,事情越闹越大。京生从前战友阿虎也移民到了香港,京生会面时,发现对方正是此次逮补的对象,无奈阿虎曾救己一命,且已爱上其妹。阿虎邀请京生三人一起抢劫银行。然阿虎兄弟杨才是江姓兄弟的朋友,亟欲替友复仇,阿虎等人未知是三人所为,找上大大逼供三人身份,逼供不成杀了大大。学军爱上长洲干妹舞女黛安娜,黛安娜鼓动学军,偷窃执勤公款,以假护照两人远走高飞,谁知黛安娜暗中透过另一小白脸,在机场检举学军持假护照,学军发现后大闹机场,向小白脸开枪后逃逸。机场风波舆论猛烈抨击,上级打算趁老虎和向东的银行抢案,一举灭口,阿虎同伙也逐渐发现三人身份。三人至此已四面楚歌,穷途末路。

    + +

    省港旗兵续集好像有个副标兵分两路。我不知道这个副标是哪里来的,找到的电影封面、海报都没有这个副标。从剧情来看,也看不出哪里有什么兵分两路

    + +

    省港旗兵续集起,麦当雄就又放下导演座,由其弟麦当杰执导。麦当杰和其哥不同,是有经验的专业导演,也一改前集全部起用无经验的非专业演员的作法,改找许多有经验的专业演员,如万梓良、徐锦江、王小凤等主演。

    + +

    省港旗兵续集因为制作班底都是专业电影人,戏感强,剧情结构玄奇繁复得多,娱乐性高。但我觉得整体上来说,省港旗兵续集不如省港旗兵。从导演到演员都是有经验的专业电影人,少了一份朴实的写实震憾力。省港旗兵简单朴实的剧情,简单朴实的演出,简单朴实的运镜,写实的震憾力,是续集所无法比拟的。省港旗兵在九龙寨城的巷弄枪战,手提摄影机带来的写实紧张感,四人每一分钟都逐渐迈入穷途末路的绝望感,都无可比拟。相对来说,省港旗兵续集在出租公寓的巷战运镜较成熟商业化,最后结局则没有太大的说服力。只要程警官一念良心发现,或是向东现实一点,挟程警官作人质求生,就不会全军覆没了。太多个人戏剧化的偶然决定,失去了第一集令人窒息的宿命感。省港旗兵续集剧情过於繁复(从上面的剧情记要就可以看得出来),使得很多很深刻的社会矛盾,都没有办法呈现出来。看完后除了觉得大圈仔打打杀杀好可怕以外,没有什么感觉。

    + +

    徐锦江原来拍电影浮浮沉沉,在省港旗兵续集里有很抢眼的表现,从此受到注目。林国斌因省港旗兵续集得到香港电影金像奖最佳新人奖。第一集的大圈仔新人演员中,只有江龙和陈敬继续演出。江龙改演反派老虎一角,有点八中复活的感觉,不过江龙感觉很清秀,演反派眼神不够凶恶。陈敬出场没几秒就死了,看得不是很清楚。

    + +

    大大被杀一幕,被倒吊蒙头,用斧头把头硬斫下来,颇为触目惊心。

    + +

    林国斌以戚京生一角,得到香港电影金像奖最佳新人奖。

    + +

    阿虎的妹妹应该是叶晨演的吧。网路上找不到叶晨的照片资料,不知道要到哪里求证。很抢眼、戏份很多的角色,不知道为什么在演员表上排得很后面。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 76 | + 77 | + 78 | + 79 | + 80 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0078.html.zh-tw.html b/htdocs/imacat/me/diary/0078.html.zh-tw.html new file mode 120000 index 0000000..e88b9a3 --- /dev/null +++ b/htdocs/imacat/me/diary/0078.html.zh-tw.html @@ -0,0 +1 @@ +0078.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0078.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0078.html.zh-tw.xhtml new file mode 100644 index 0000000..fde1e28 --- /dev/null +++ b/htdocs/imacat/me/diary/0078.html.zh-tw.xhtml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷七十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷七十八

    + +
    + +
    + +
    +
    9.23.’06. 1:57am.
    + +

    省港旗兵續集—大圈仔打打殺殺好可怕

    + +
    +省港旗兵續集
    +

    省港旗兵續集

    +
    + +
      +
    • 片名:省港旗兵續集
    • +
    • 英文片名: Long Arm of the Law — Sage Ⅱ
    • +
    • 發行年份: 1987
    • +
    • 製作公司:麥當雄製作有限公司
    • +
    • 出品人:鄒文懷
    • +
    • 監製:麥當雄
    • +
    • 導演:麥當傑
    • +
    • 演員: +
        +
      • 萬梓良:大大
      • +
      • 徐錦江:李向東
      • +
      • 林國斌:戚京生
      • +
      • 袁日初:郭學軍
      • +
      • 王小鳳:黛安娜
      • +
      • 江龍:阿虎
      • +
      • 葉晨:阿虎妹
      • +
      • 韓義生:黑鬼唐
      • +
      • 黃志強:興仔
      • +
      • 成奎安:江氏四兄弟之一
      • +
      • 陳敬:江氏四兄弟之一
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    省港旗兵續集延續第一集的背景,香港治安被大圈仔搞得越來越敗壞,程警官決定以圈治圈,由偷渡客中挑出有公安背景的李向東、戚京生、郭學軍三人,誘以香港永久拘留權,以作臥底協助破案,並指派臥底十三年的警察大大接應。大大原瞧不起三人,帶三人買私槍時,撞見仇家,被三人所救,與三人結為莫逆。大大安排三人接買賣:珠寶商為騙取保險金僱黑道興仔搶劫,興仔反以珠寶勒索,四人在其母壽宴上立威,名動黑道。做賊贓買賣的長洲與江姓兄弟買賣糾紛,僱三人作保鑣,沒想江姓兄弟是向東多年前逮補過的罪犯,被認出曾是公安,混戰中殺了對方,事情越鬧越大。京生從前戰友阿虎也移民到了香港,京生會面時,發現對方正是此次逮補的對象,無奈阿虎曾救己一命,且已愛上其妹。阿虎邀請京生三人一起搶劫銀行。然阿虎兄弟楊才是江姓兄弟的朋友,亟欲替友復仇,阿虎等人未知是三人所為,找上大大逼供三人身份,逼供不成殺了大大。學軍愛上長洲乾妹舞女黛安娜,黛安娜鼓動學軍,偷竊執勤公款,以假護照兩人遠走高飛,誰知黛安娜暗中透過另一小白臉,在機場檢舉學軍持假護照,學軍發現後大鬧機場,向小白臉開槍後逃逸。機場風波輿論猛烈抨擊,上級打算趁老虎和向東的銀行搶案,一舉滅口,阿虎同伙也逐漸發現三人身份。三人至此已四面楚歌,窮途末路。

    + +

    省港旗兵續集好像有個副標兵分兩路。我不知道這個副標是哪裏來的,找到的電影封面、海報都沒有這個副標。從劇情來看,也看不出哪裏有什麼兵分兩路

    + +

    省港旗兵續集起,麥當雄就又放下導演座,由其弟麥當傑執導。麥當傑和其哥不同,是有經驗的專業導演,也一改前集全部起用無經驗的非專業演員的作法,改找許多有經驗的專業演員,如萬梓良、徐錦江、王小鳳等主演。

    + +

    省港旗兵續集因為製作班底都是專業電影人,戲感強,劇情結構玄奇繁複得多,娛樂性高。但我覺得整體上來說,省港旗兵續集不如省港旗兵。從導演到演員都是有經驗的專業電影人,少了一份樸實的寫實震憾力。省港旗兵簡單樸實的劇情,簡單樸實的演出,簡單樸實的運鏡,寫實的震憾力,是續集所無法比擬的。省港旗兵在九龍寨城的巷弄槍戰,手提攝影機帶來的寫實緊張感,四人每一分鐘都逐漸邁入窮途末路的絕望感,都無可比擬。相對來說,省港旗兵續集在出租公寓的巷戰運鏡較成熟商業化,最後結局則沒有太大的說服力。只要程警官一念良心發現,或是向東現實一點,挾程警官作人質求生,就不會全軍覆沒了。太多個人戲劇化的偶然決定,失去了第一集令人窒息的宿命感。省港旗兵續集劇情過於繁複(從上面的劇情記要就可以看得出來),使得很多很深刻的社會矛盾,都沒有辦法呈現出來。看完後除了覺得大圈仔打打殺殺好可怕以外,沒有什麼感覺。

    + +

    徐錦江原來拍電影浮浮沉沉,在省港旗兵續集裏有很搶眼的表現,從此受到注目。林國斌因省港旗兵續集得到香港電影金像獎最佳新人獎。第一集的大圈仔新人演員中,只有江龍和陳敬繼續演出。江龍改演反派老虎一角,有點八中復活的感覺,不過江龍感覺很清秀,演反派眼神不夠兇惡。陳敬出場沒幾秒就死了,看得不是很清楚。

    + +

    大大被殺一幕,被倒吊蒙頭,用斧頭把頭硬斫下來,頗為觸目驚心。

    + +

    林國斌以戚京生一角,得到香港電影金像獎最佳新人獎。

    + +

    阿虎的妹妹應該是葉晨演的吧。網路上找不到葉晨的照片資料,不知道要到哪裏求證。很搶眼、戲份很多的角色,不知道為什麼在演員表上排得很後面。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 76 | + 77 | + 78 | + 79 | + 80 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0079.html.en.html b/htdocs/imacat/me/diary/0079.html.en.html new file mode 120000 index 0000000..7d2ab61 --- /dev/null +++ b/htdocs/imacat/me/diary/0079.html.en.html @@ -0,0 +1 @@ +0079.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0079.html.en.xhtml b/htdocs/imacat/me/diary/0079.html.en.xhtml new file mode 100644 index 0000000..27c566a --- /dev/null +++ b/htdocs/imacat/me/diary/0079.html.en.xhtml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 79 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 79

    + +
    + +
    + +
    +
    9.24.’06. 5:00pm.
    + +

    North Country 北國性騷擾—爭取平等工作環境的血淚故事

    + +
    +North Country 北國性騷擾
    +

    North Country 北國性騷擾

    +
    + + + +

    北國性騷擾根據小說 Class Action 改編, Class Action 則是根據美國第一起集體性騷擾訴訟的真實故事改編,敘述明尼蘇達州的皮爾森鋼鐵公司況場,女工長期遭受各式各樣的性騷擾:言語、性攻擊、衣櫃惡作劇、噴漆、屎尿塗鴉,憤而提起訴訟的故事。影片從法院辯論庭開始,然後逐步倒敘回曾經發生的一連串事件。原案從 1985 年提起告訴到 1998 年判決原告勝訴,纏訟了十四年。這一點電影裏面看不出來,全部濃縮成一場辯論庭。

    + +

    北國性騷擾看完讓人很感動。八零、九零年代,性騷擾問題開始為世人所注目。每一起事件,都是血與淚的故事。劇中主角裘絲面對的,不只是公司同事的性騷擾:當她告訴家人她要做礦工時,父親無法接受她和他做同樣的工作;當她向老闆控訴時,老闆完全沒聽她說就有了定見;當她向女同事求援時,女同事則怨恨她只會害她們更被作弄。當她一踩到體制的界限,體制反撲的壓力漫天而來,從男同事,從家人,從同樣處境的女同事,從整個小鎮所有人的閒言閒語,甚至從自己的兒子,鋪天蓋地,無所不在。

    + +

    片中男性礦工作弄女性同事的舉動,很大的一部份類似於欺負行為 (Bully) 。欺負是男性社群中常見的行為,男人不只用以對待異性,也用以對待同性,普遍存在學校、軍營的學長學弟間。欺負人的人,以惡意、攻擊性的言語,惡作劇的行為,或甚至攻擊性的行為,來對待被欺負的人。對欺負人的人而言,這只是惡作劇而已,絲毫不覺其惡;但對被欺負的人,則往往是無處可逃、痛不欲生的經驗。欺負人的人,往往指責被欺負的人過於敏感,要求他們像男人一樣忍下來;而第三者、仲裁者則往往覺得惡作劇不是什麼大事,刻意忽略;這使得被欺負者常常陷於孤立無援、無處可逃的處境中。

    + +

    不過單就電影而言,北國性騷擾有很多部份,有待加強。電影請了三位影后主演:女魔頭的莎莉賽隆、冰血暴的法蘭西絲麥朵曼及礦工的女兒的西西史派克。不過電影中的每個角色都很平面,除了老爸漢克艾米斯最後改變立場支持女兒外,沒有什麼角色的轉折,也沒有機會讓演員有特出的表現。電影的角色性格顯得頗為薄弱,無法讓人有深刻的印象。就這點而言, HBO女權天使 Iron Jawed Angels (2004) 就好得多,雖然有很多角色,但都份量十足。

    + +

    原著小說 Class Action 書名的意思是集體訴訟

    + +

    電影裏有好幾次,畫面帶到電視上正播出的 Anita Hill 的訴訟。 Anita Hill 案是 1991 年著名的性騷擾案: Anita Hill 原為奧克拉荷馬州立大學的法律教授 Clarence Thomas 的助理,當時老布希總統正預備提名 Clarence Thomas 為大法官, Anita Hill 出面控告 Clarence Thomas 性騷擾,被媒體大肆報導,引起很大的關注。

    + +

    製片公司 Participant Productions 是 2004 年新成立的電影公司,拍攝了一系列具深刻社會意識的電影,如:晚安,祝你好運 Good Night, and Good Luck (2005)謀殺球 Murderball (2005)阿娜的孩子 Arna’s Children (2003)諜對諜 Syriana (2005) 等,都是值得一看的好片。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 77 | + 78 | + 79 | + 80 | + 81 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0079.html.zh-cn.html b/htdocs/imacat/me/diary/0079.html.zh-cn.html new file mode 120000 index 0000000..757fe5a --- /dev/null +++ b/htdocs/imacat/me/diary/0079.html.zh-cn.html @@ -0,0 +1 @@ +0079.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0079.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0079.html.zh-cn.xhtml new file mode 100644 index 0000000..aa9c300 --- /dev/null +++ b/htdocs/imacat/me/diary/0079.html.zh-cn.xhtml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷七十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷七十九

    + +
    + +
    + +
    +
    9.24.’06. 5:00pm.
    + +

    North Country 北国性骚扰—争取平等工作环境的血泪故事

    + +
    +North Country 北国性骚扰
    +

    North Country 北国性骚扰

    +
    + + + +

    北国性骚扰根据小说 Class Action 改编, Class Action 则是根据美国第一起集体性骚扰诉讼的真实故事改编,叙述明尼苏达州的皮尔森钢铁公司况场,女工长期遭受各式各样的性骚扰:言语、性攻击、衣柜恶作剧、喷漆、屎尿涂鸦,愤而提起诉讼的故事。影片从法院辩论庭开始,然后逐步倒叙回曾经发生的一连串事件。原案从 1985 年提起告诉到 1998 年判决原告胜诉,缠讼了十四年。这一点电影里面看不出来,全部浓缩成一场辩论庭。

    + +

    北国性骚扰看完让人很感动。八零、九零年代,性骚扰问题开始为世人所注目。每一起事件,都是血与泪的故事。剧中主角裘丝面对的,不只是公司同事的性骚扰:当她告诉家人她要做矿工时,父亲无法接受她和他做同样的工作;当她向老板控诉时,老板完全没听她说就有了定见;当她向女同事求援时,女同事则怨恨她只会害她们更被作弄。当她一踩到体制的界限,体制反扑的压力漫天而来,从男同事,从家人,从同样处境的女同事,从整个小镇所有人的闲言闲语,甚至从自己的儿子,铺天盖地,无所不在。

    + +

    片中男性矿工作弄女性同事的举动,很大的一部份类似於欺负行为 (Bully) 。欺负是男性社群中常见的行为,男人不只用以对待异性,也用以对待同性,普遍存在学校、军营的学长学弟间。欺负人的人,以恶意、攻击性的言语,恶作剧的行为,或甚至攻击性的行为,来对待被欺负的人。对欺负人的人而言,这只是恶作剧而已,丝毫不觉其恶;但对被欺负的人,则往往是无处可逃、痛不欲生的经验。欺负人的人,往往指责被欺负的人过於敏感,要求他们像男人一样忍下来;而第三者、仲裁者则往往觉得恶作剧不是什么大事,刻意忽略;这使得被欺负者常常陷於孤立无援、无处可逃的处境中。

    + +

    不过单就电影而言,北国性骚扰有很多部份,有待加强。电影请了三位影后主演:女魔头的莎莉赛隆、冰血暴的法兰西丝麦朵曼及矿工的女儿的西西史派克。不过电影中的每个角色都很平面,除了老爸汉克艾米斯最后改变立场支持女儿外,没有什么角色的转折,也没有机会让演员有特出的表现。电影的角色性格显得颇为薄弱,无法让人有深刻的印象。就这点而言, HBO女权天使 Iron Jawed Angels (2004) 就好得多,虽然有很多角色,但都份量十足。

    + +

    原著小说 Class Action 书名的意思是集体诉讼

    + +

    电影里有好几次,画面带到电视上正播出的 Anita Hill 的诉讼。 Anita Hill 案是 1991 年著名的性骚扰案: Anita Hill 原为奥克拉荷马州立大学的法律教授 Clarence Thomas 的助理,当时老布希总统正预备提名 Clarence Thomas 为大法官, Anita Hill 出面控告 Clarence Thomas 性骚扰,被媒体大肆报导,引起很大的关注。

    + +

    制片公司 Participant Productions 是 2004 年新成立的电影公司,拍摄了一系列具深刻社会意识的电影,如:晚安,祝你好运 Good Night, and Good Luck (2005)谋杀球 Murderball (2005)阿娜的孩子 Arna’s Children (2003)谍对谍 Syriana (2005) 等,都是值得一看的好片。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 77 | + 78 | + 79 | + 80 | + 81 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0079.html.zh-tw.html b/htdocs/imacat/me/diary/0079.html.zh-tw.html new file mode 120000 index 0000000..1c9893c --- /dev/null +++ b/htdocs/imacat/me/diary/0079.html.zh-tw.html @@ -0,0 +1 @@ +0079.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0079.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0079.html.zh-tw.xhtml new file mode 100644 index 0000000..72b0850 --- /dev/null +++ b/htdocs/imacat/me/diary/0079.html.zh-tw.xhtml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷七十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷七十九

    + +
    + +
    + +
    +
    9.24.’06. 5:00pm.
    + +

    North Country 北國性騷擾—爭取平等工作環境的血淚故事

    + +
    +North Country 北國性騷擾
    +

    North Country 北國性騷擾

    +
    + + + +

    北國性騷擾根據小說 Class Action 改編, Class Action 則是根據美國第一起集體性騷擾訴訟的真實故事改編,敘述明尼蘇達州的皮爾森鋼鐵公司況場,女工長期遭受各式各樣的性騷擾:言語、性攻擊、衣櫃惡作劇、噴漆、屎尿塗鴉,憤而提起訴訟的故事。影片從法院辯論庭開始,然後逐步倒敘回曾經發生的一連串事件。原案從 1985 年提起告訴到 1998 年判決原告勝訴,纏訟了十四年。這一點電影裏面看不出來,全部濃縮成一場辯論庭。

    + +

    北國性騷擾看完讓人很感動。八零、九零年代,性騷擾問題開始為世人所注目。每一起事件,都是血與淚的故事。劇中主角裘絲面對的,不只是公司同事的性騷擾:當她告訴家人她要做礦工時,父親無法接受她和他做同樣的工作;當她向老闆控訴時,老闆完全沒聽她說就有了定見;當她向女同事求援時,女同事則怨恨她只會害她們更被作弄。當她一踩到體制的界限,體制反撲的壓力漫天而來,從男同事,從家人,從同樣處境的女同事,從整個小鎮所有人的閒言閒語,甚至從自己的兒子,鋪天蓋地,無所不在。

    + +

    片中男性礦工作弄女性同事的舉動,很大的一部份類似於欺負行為 (Bully) 。欺負是男性社群中常見的行為,男人不只用以對待異性,也用以對待同性,普遍存在學校、軍營的學長學弟間。欺負人的人,以惡意、攻擊性的言語,惡作劇的行為,或甚至攻擊性的行為,來對待被欺負的人。對欺負人的人而言,這只是惡作劇而已,絲毫不覺其惡;但對被欺負的人,則往往是無處可逃、痛不欲生的經驗。欺負人的人,往往指責被欺負的人過於敏感,要求他們像男人一樣忍下來;而第三者、仲裁者則往往覺得惡作劇不是什麼大事,刻意忽略;這使得被欺負者常常陷於孤立無援、無處可逃的處境中。

    + +

    不過單就電影而言,北國性騷擾有很多部份,有待加強。電影請了三位影后主演:女魔頭的莎莉賽隆、冰血暴的法蘭西絲麥朵曼及礦工的女兒的西西史派克。不過電影中的每個角色都很平面,除了老爸漢克艾米斯最後改變立場支持女兒外,沒有什麼角色的轉折,也沒有機會讓演員有特出的表現。電影的角色性格顯得頗為薄弱,無法讓人有深刻的印象。就這點而言, HBO女權天使 Iron Jawed Angels (2004) 就好得多,雖然有很多角色,但都份量十足。

    + +

    原著小說 Class Action 書名的意思是集體訴訟

    + +

    電影裏有好幾次,畫面帶到電視上正播出的 Anita Hill 的訴訟。 Anita Hill 案是 1991 年著名的性騷擾案: Anita Hill 原為奧克拉荷馬州立大學的法律教授 Clarence Thomas 的助理,當時老布希總統正預備提名 Clarence Thomas 為大法官, Anita Hill 出面控告 Clarence Thomas 性騷擾,被媒體大肆報導,引起很大的關注。

    + +

    製片公司 Participant Productions 是 2004 年新成立的電影公司,拍攝了一系列具深刻社會意識的電影,如:晚安,祝你好運 Good Night, and Good Luck (2005)謀殺球 Murderball (2005)阿娜的孩子 Arna’s Children (2003)諜對諜 Syriana (2005) 等,都是值得一看的好片。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 77 | + 78 | + 79 | + 80 | + 81 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0080.html.en.html b/htdocs/imacat/me/diary/0080.html.en.html new file mode 120000 index 0000000..79d98e7 --- /dev/null +++ b/htdocs/imacat/me/diary/0080.html.en.html @@ -0,0 +1 @@ +0080.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0080.html.en.xhtml b/htdocs/imacat/me/diary/0080.html.en.xhtml new file mode 100644 index 0000000..80c8b34 --- /dev/null +++ b/htdocs/imacat/me/diary/0080.html.en.xhtml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 80 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 80

    + +
    + +
    + +
    +
    9.26.’06. 3:50am.
    + +

    省港旗兵四個字的意思

    + +

    我一直不知道省港旗兵四個字是什麼意思,剛剛終於解開這個謎了。

    + +

    省港是指廣東省香港,這兩個地方是分不開的,所以合稱省港旗兵則是指紅旗紅衛兵。合起來就是省港旗兵

    + +
    + +
    + +
    +
    9.25.’06. 11:52pm.
    + +

    省港旗兵第三集省港旗兵浪漫武打商業版

    + +
    +省港旗兵第三集
    +

    省港旗兵第三集

    +
    + +
      +
    • 片名:省港旗兵第三集
    • +
    • 英文片名: Long Arm of the Law Part 3
    • +
    • 發行年份: 1989
    • +
    • 製作公司:麥當雄製作有限公司
    • +
    • 出品人:麥當雄、蕭若元
    • +
    • 編劇:麥當雄、蕭若元
    • +
    • 導演:麥當傑
    • +
    • 演員: +
        +
      • 劉德華:李長江
      • +
      • 李美鳳:常滿
      • +
      • 莫少聰:雞心
      • +
      • 徐錦江:毛向陽
      • +
      • 黃志強:良哥
      • +
      • 仇雲波: 966
      • +
      • 韓義生:老爺車
      • +
      +
    • +
    • 推薦影評: +
    • 省港旗兵第三集之逃出香港—三區港版
    • + +
    + +

    省港旗兵第三集敘述因朋友搶劫牽連,被毛向陽逮補判死刑的李長江,在刑場逃脫往香港。遇上同路偷渡的常滿和雞心,和常滿滋生感情。到香港後,常滿被人口販子接走,雞心被匪幫卓哥接走,長江找叔叔接應被拒絕,付不出偷渡費,得良哥相助,在良哥下工作。良哥和卓哥本為一夥,兩人一唱黑臉一唱白臉。長江得知常滿被賣至老爺車旗下做妓,殺入救人未果,跟隨卓哥做案,以交換常滿自由。良哥安排兩人在一起,但夥卓哥續以常滿性命相脅,脅迫長江繼續做案。同時雞心分贓款亦不斷被苛扣。長江和雞心逐漸看穿良哥真面目,準備最後一次做案後,與常滿三人偷渡遠走巴拿馬。但良哥和卓哥亦準備要滅口。此時來到香港查緝長江的向陽,亦逐步逼近眾人。

    + +

    省港旗兵第三集沒有副標。和省港旗兵續集一樣,沒有承接前集的劇情,而且也有死而復活的人物。省港旗兵續集死掉的大圈仔李向東,這次變成公安頭子毛向陽了。縱觀三集以來,商業味越來越重。原先樸實沉重的省港旗兵省港旗兵續集加入了大量的複雜劇情和專業的電影演出,到了省港旗兵第三集則滲入了濃濃的商業味,不但加入了前兩集沒有的武打動作,愛情戲比重加深很多,加進了偶像劉德華做主角,大圈仔由前兩集一群團結的人改為兩人獨行,而且結局一改前集全軍覆沒的悲劇性宿命,改為討喜的喜劇結局。省港旗兵續集過於繁複的劇情,在省港旗兵第三集也改進簡化了,比較清楚明瞭,脈絡清晰。前兩集特有的驚心動魄的殺人場面,省港旗兵第三集則被拿掉了。省港旗兵眾人的角色都是量身打造,演得剛剛好;省港旗兵續集萬梓良、徐錦江和林國斌也演得不錯;但省港旗兵第三集的演技則有明顯缺陷,太帥氣輕佻的劉德華,不夠詮釋角色應有的憨直。動作追逐的場面,省港旗兵在巷弄狹窄四通八達的九龍寨城,省港旗兵續集在老舊公寓,省港旗兵第三集則到了海上的船戶。大圈仔的形象也有很大的轉變,從省港旗兵窮苦人為求生存敢衝不怕死,省港旗兵續集只知道打打殺殺,到省港旗兵第三集成為被奸詐的香港人欺負的可憐老實人。

    + +

    整體而言,第三集比續集成功。不過我還是覺得,比不上樸實沉重的第一集。第一集真的是經典。

    + +

    我在一直想找出卓哥(沙皮卓)是誰演的。他在續集也有演出,演的是阿虎的兄弟楊才。可是網路上查了很久,還是查不出他是誰。

    + +
    2007-08-27
    + +

    謝謝秀仁在旅人留言簿告知,沙皮卓的演員是陳德光,詠春師傅,去年被控白嫖勒索案。雖然目前判決無罪,可是捲入這種事,還被搜出一大本嫖妓筆記,真的好難看~ ^^;

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 78 | + 79 | + 80 | + 81 | + 82 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0080.html.zh-cn.html b/htdocs/imacat/me/diary/0080.html.zh-cn.html new file mode 120000 index 0000000..e548c07 --- /dev/null +++ b/htdocs/imacat/me/diary/0080.html.zh-cn.html @@ -0,0 +1 @@ +0080.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0080.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0080.html.zh-cn.xhtml new file mode 100644 index 0000000..12eecc4 --- /dev/null +++ b/htdocs/imacat/me/diary/0080.html.zh-cn.xhtml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷八十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷八十

    + +
    + +
    + +
    +
    9.26.’06. 3:50am.
    + +

    省港旗兵四个字的意思

    + +

    我一直不知道省港旗兵四个字是什么意思,刚刚终於解开这个谜了。

    + +

    省港是指广东省香港,这两个地方是分不开的,所以合称省港旗兵则是指红旗红卫兵。合起来就是省港旗兵

    + +
    + +
    + +
    +
    9.25.’06. 11:52pm.
    + +

    省港旗兵第三集省港旗兵浪漫武打商业版

    + +
    +省港旗兵第三集
    +

    省港旗兵第三集

    +
    + +
      +
    • 片名:省港旗兵第三集
    • +
    • 英文片名: Long Arm of the Law Part 3
    • +
    • 发行年份: 1989
    • +
    • 制作公司:麦当雄制作有限公司
    • +
    • 出品人:麦当雄、萧若元
    • +
    • 编剧:麦当雄、萧若元
    • +
    • 导演:麦当杰
    • +
    • 演员: +
        +
      • 刘德华:李长江
      • +
      • 李美凤:常满
      • +
      • 莫少聪:鸡心
      • +
      • 徐锦江:毛向阳
      • +
      • 黄志强:良哥
      • +
      • 仇云波: 966
      • +
      • 韩义生:老爷车
      • +
      +
    • +
    • 推荐影评: +
    • 省港旗兵第三集之逃出香港—三区港版
    • + +
    + +

    省港旗兵第三集叙述因朋友抢劫牵连,被毛向阳逮补判死刑的李长江,在刑场逃脱往香港。遇上同路偷渡的常满和鸡心,和常满滋生感情。到香港后,常满被人口贩子接走,鸡心被匪帮卓哥接走,长江找叔叔接应被拒绝,付不出偷渡费,得良哥相助,在良哥下工作。良哥和卓哥本为一伙,两人一唱黑脸一唱白脸。长江得知常满被卖至老爷车旗下做妓,杀入救人未果,跟随卓哥做案,以交换常满自由。良哥安排两人在一起,但伙卓哥续以常满性命相胁,胁迫长江继续做案。同时鸡心分赃款亦不断被苛扣。长江和鸡心逐渐看穿良哥真面目,准备最后一次做案后,与常满三人偷渡远走巴拿马。但良哥和卓哥亦准备要灭口。此时来到香港查缉长江的向阳,亦逐步逼近众人。

    + +

    省港旗兵第三集没有副标。和省港旗兵续集一样,没有承接前集的剧情,而且也有死而复活的人物。省港旗兵续集死掉的大圈仔李向东,这次变成公安头子毛向阳了。纵观三集以来,商业味越来越重。原先朴实沉重的省港旗兵省港旗兵续集加入了大量的复杂剧情和专业的电影演出,到了省港旗兵第三集则渗入了浓浓的商业味,不但加入了前两集没有的武打动作,爱情戏比重加深很多,加进了偶像刘德华做主角,大圈仔由前两集一群团结的人改为两人独行,而且结局一改前集全军覆没的悲剧性宿命,改为讨喜的喜剧结局。省港旗兵续集过於繁复的剧情,在省港旗兵第三集也改进简化了,比较清楚明了,脉络清晰。前两集特有的惊心动魄的杀人场面,省港旗兵第三集则被拿掉了。省港旗兵众人的角色都是量身打造,演得刚刚好;省港旗兵续集万梓良、徐锦江和林国斌也演得不错;但省港旗兵第三集的演技则有明显缺陷,太帅气轻佻的刘德华,不够诠释角色应有的憨直。动作追逐的场面,省港旗兵在巷弄狭窄四通八达的九龙寨城,省港旗兵续集在老旧公寓,省港旗兵第三集则到了海上的船户。大圈仔的形象也有很大的转变,从省港旗兵穷苦人为求生存敢冲不怕死,省港旗兵续集只知道打打杀杀,到省港旗兵第三集成为被奸诈的香港人欺负的可怜老实人。

    + +

    整体而言,第三集比续集成功。不过我还是觉得,比不上朴实沉重的第一集。第一集真的是经典。

    + +

    我在一直想找出卓哥(沙皮卓)是谁演的。他在续集也有演出,演的是阿虎的兄弟杨才。可是网路上查了很久,还是查不出他是谁。

    + +
    2007-08-27
    + +

    谢谢秀仁在旅人留言簿告知,沙皮卓的演员是陈德光,咏春师傅,去年被控白嫖勒索案。虽然目前判决无罪,可是卷入这种事,还被搜出一大本嫖妓笔记,真的好难看~ ^^;

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 78 | + 79 | + 80 | + 81 | + 82 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0080.html.zh-tw.html b/htdocs/imacat/me/diary/0080.html.zh-tw.html new file mode 120000 index 0000000..ab0bb16 --- /dev/null +++ b/htdocs/imacat/me/diary/0080.html.zh-tw.html @@ -0,0 +1 @@ +0080.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0080.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0080.html.zh-tw.xhtml new file mode 100644 index 0000000..c191111 --- /dev/null +++ b/htdocs/imacat/me/diary/0080.html.zh-tw.xhtml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷八十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷八十

    + +
    + +
    + +
    +
    9.26.’06. 3:50am.
    + +

    省港旗兵四個字的意思

    + +

    我一直不知道省港旗兵四個字是什麼意思,剛剛終於解開這個謎了。

    + +

    省港是指廣東省香港,這兩個地方是分不開的,所以合稱省港旗兵則是指紅旗紅衛兵。合起來就是省港旗兵

    + +
    + +
    + +
    +
    9.25.’06. 11:52pm.
    + +

    省港旗兵第三集省港旗兵浪漫武打商業版

    + +
    +省港旗兵第三集
    +

    省港旗兵第三集

    +
    + +
      +
    • 片名:省港旗兵第三集
    • +
    • 英文片名: Long Arm of the Law Part 3
    • +
    • 發行年份: 1989
    • +
    • 製作公司:麥當雄製作有限公司
    • +
    • 出品人:麥當雄、蕭若元
    • +
    • 編劇:麥當雄、蕭若元
    • +
    • 導演:麥當傑
    • +
    • 演員: +
        +
      • 劉德華:李長江
      • +
      • 李美鳳:常滿
      • +
      • 莫少聰:雞心
      • +
      • 徐錦江:毛向陽
      • +
      • 黃志強:良哥
      • +
      • 仇雲波: 966
      • +
      • 韓義生:老爺車
      • +
      +
    • +
    • 推薦影評: +
    • 省港旗兵第三集之逃出香港—三區港版
    • + +
    + +

    省港旗兵第三集敘述因朋友搶劫牽連,被毛向陽逮補判死刑的李長江,在刑場逃脫往香港。遇上同路偷渡的常滿和雞心,和常滿滋生感情。到香港後,常滿被人口販子接走,雞心被匪幫卓哥接走,長江找叔叔接應被拒絕,付不出偷渡費,得良哥相助,在良哥下工作。良哥和卓哥本為一夥,兩人一唱黑臉一唱白臉。長江得知常滿被賣至老爺車旗下做妓,殺入救人未果,跟隨卓哥做案,以交換常滿自由。良哥安排兩人在一起,但夥卓哥續以常滿性命相脅,脅迫長江繼續做案。同時雞心分贓款亦不斷被苛扣。長江和雞心逐漸看穿良哥真面目,準備最後一次做案後,與常滿三人偷渡遠走巴拿馬。但良哥和卓哥亦準備要滅口。此時來到香港查緝長江的向陽,亦逐步逼近眾人。

    + +

    省港旗兵第三集沒有副標。和省港旗兵續集一樣,沒有承接前集的劇情,而且也有死而復活的人物。省港旗兵續集死掉的大圈仔李向東,這次變成公安頭子毛向陽了。縱觀三集以來,商業味越來越重。原先樸實沉重的省港旗兵省港旗兵續集加入了大量的複雜劇情和專業的電影演出,到了省港旗兵第三集則滲入了濃濃的商業味,不但加入了前兩集沒有的武打動作,愛情戲比重加深很多,加進了偶像劉德華做主角,大圈仔由前兩集一群團結的人改為兩人獨行,而且結局一改前集全軍覆沒的悲劇性宿命,改為討喜的喜劇結局。省港旗兵續集過於繁複的劇情,在省港旗兵第三集也改進簡化了,比較清楚明瞭,脈絡清晰。前兩集特有的驚心動魄的殺人場面,省港旗兵第三集則被拿掉了。省港旗兵眾人的角色都是量身打造,演得剛剛好;省港旗兵續集萬梓良、徐錦江和林國斌也演得不錯;但省港旗兵第三集的演技則有明顯缺陷,太帥氣輕佻的劉德華,不夠詮釋角色應有的憨直。動作追逐的場面,省港旗兵在巷弄狹窄四通八達的九龍寨城,省港旗兵續集在老舊公寓,省港旗兵第三集則到了海上的船戶。大圈仔的形象也有很大的轉變,從省港旗兵窮苦人為求生存敢衝不怕死,省港旗兵續集只知道打打殺殺,到省港旗兵第三集成為被奸詐的香港人欺負的可憐老實人。

    + +

    整體而言,第三集比續集成功。不過我還是覺得,比不上樸實沉重的第一集。第一集真的是經典。

    + +

    我在一直想找出卓哥(沙皮卓)是誰演的。他在續集也有演出,演的是阿虎的兄弟楊才。可是網路上查了很久,還是查不出他是誰。

    + +
    2007-08-27
    + +

    謝謝秀仁在旅人留言簿告知,沙皮卓的演員是陳德光,詠春師傅,去年被控白嫖勒索案。雖然目前判決無罪,可是捲入這種事,還被搜出一大本嫖妓筆記,真的好難看~ ^^;

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 78 | + 79 | + 80 | + 81 | + 82 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0081.html.en.html b/htdocs/imacat/me/diary/0081.html.en.html new file mode 120000 index 0000000..b044349 --- /dev/null +++ b/htdocs/imacat/me/diary/0081.html.en.html @@ -0,0 +1 @@ +0081.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0081.html.en.xhtml b/htdocs/imacat/me/diary/0081.html.en.xhtml new file mode 100644 index 0000000..550970e --- /dev/null +++ b/htdocs/imacat/me/diary/0081.html.en.xhtml @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 81 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 81

    + +
    + +
    + +
    +
    10.2.’06. 4:34am.
    + +

    沒去同志大遊行…嗚嗚嗚…

    + +

    今年的同志大遊行,因為之前太忙了,加上當天空大要上一整個下午的課,所以沒有去,也忘了找朋友去。現在回想起來,應該找阿光去的。

    + +

    下了課趕去跟去遊行的朋友吃飯,看起來好像很好玩,覺得好遺憾。

    + +

    剛剛整理九月份的信,看到集合小玉寄來的好幾份遊行的宣傳。哇哇哇,沒看到小玉~去年去遊行,碰到小玉,就覺得好喜歡小玉這個人,吱吱喳喳地,超有活力的感覺,連平常吵鬧的我都給比下去了。今年沒看到小玉,好遺憾~

    + +

    真希望明年同志大遊行的時候不會有事,可以去遊行~ *^_^*

    + +

    小玉剛剛出了一本書,我想買來看。不過我現在要看的東西太多了,清單一長列,好像有點奢侈,買了也不知道要排到什麼時候。唔。 ^^;

    + +

    吃飯的時候,認識了一個很可愛的 Amy 。可以認識可愛的朋友,真好~我也是人來瘋呢~

    + +
    + +
    + +
    +
    9.30.’06. 0:23am.
    + +

    省港旗兵第四集 地下通道—看不到終點的偷渡路

    + +
    +省港旗兵第四集 地下通道
    +

    省港旗兵第四集 地下通道

    +
    + +
      +
    • 片名:省港旗兵第四集 地下通道
    • +
    • 英文片名: Underground Express
    • +
    • 發行年份: 1990
    • +
    • 製作公司:麥當雄製作有限公司
    • +
    • 出品人:麥當雄、蕭若元
    • +
    • 編劇:麥當雄、蕭若元
    • +
    • 導演:麥當傑
    • +
    • 演員: +
        +
      • 徐錦江:王兵
      • +
      • 吳雪雯:王小惠
      • +
      • 陳敬:狗公
      • +
      • 程小龍:大石
      • +
      • 陳治良:小石
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    這是我 9/25 晚上看的電影。

    + +

    中國發生了六四天安門事件,香港聲援會主席歐陽卓為協助學生領袖王小惠、陳英、洪韻音逃出,欲聘請王兵為首的大圈仔犯罪集團協助偷渡。王兵集團原計劃趁聲援示威遊行時打劫,因遊行臨時取消而中止,因而答應接下任務。王兵到廣州後,王小惠認其為民主愛國人士冒死相救,萬般推崇,令其深受感動,決心鼎力相助。然而,中國政治保衛局的袁樹已經盯上了王兵一群人,風聲鶴唳,逃亡的路上險阻重重。

    + +

    省港旗兵第四集與前三集最大的不同,在於前三集中,描繪的都是大圈仔偷渡後,在香港掙扎求生的故事,是偷渡後的事;而省港旗兵第四集,描繪的則是偷渡的過程本身。不穩定的政治局勢,讓偷渡的過程加倍的兇險。這樣的兇險,使得一行人即使偷渡到了香港,逃亡也無法結束。港英政府不願開罪中方,也不願激起同情學運的一般民眾的反感。一行人無法留在香港,只得繼續偷渡、逃亡,航向不可知的危險汪洋。偷渡、逃亡的過程本身,就是主題。偷渡、逃亡的漫漫長路沒有終點,片末模模糊糊交待兩人相約美國再見,然而相見無期,安定的幸福在永遠看不到的彼岸。

    + +

    很明顯可以看得出,麥當雄拍省港旗兵第四集,想以一個電影人的身份,為六四盡一點心力。這使得省港旗兵第四集和前集比起來有很大的特色。省港旗兵具有很強的社會意識,省港旗兵第四集則具有相當濃的政治意識。

    + +

    徐錦江演得很不錯,從匪徒到仗義挺身,又要面對兄弟生死的威脅,又要向兄弟交待,又惦記著不知道收不收得到的酬勞,還有彼此有情意的案主王小惠,其間的轉折與掙扎,很微妙也很複雜,徐錦江表現得非常傑出。我看徐錦江演戲看得蠻多的了,不過很少看到這麼精彩的表現。陳敬也很不錯,已經從省港旗兵第一次拍戲的生澀新手,進步為心裏只惦著錢,不斷小心翼翼邊陪笑邊提醒老大酬勞問題,甚至後來不惜舉槍相向,直到最後才豁出去的匪徒,可以演複雜戲碼的稱職配角了。比較起來,吳雪雯的王小惠則演得平平。另兩位女配角,則幾乎看不到什麼演出。

    + +

    我在網路上查詢了一會,中國有部份網友,將省港旗兵第四集列為香港十大反動電影之首。我想這樣扣反動的大帽子,也太偏激了。任何社會都有各種各樣的人,像這樣偏激的人,我想當然也有。我覺得公開在網路上散佈這樣偏激的意見不大好,不過,我也不會因此就覺得,所有中國網友都這樣想。

    + +

    省港旗兵第四集裏面有些人命,感覺蠻輕的。王兵的同夥兄弟陣亡時,每一個都倍極哀傷;可是飛虎隊和偷渡的袁樹人馬開戰,死傷慘重時,卻只是輕輕帶過,一句三個死亡,英國警察罵幾句髒話,要求嚴格看管袁樹,就交待過去了,感覺上很奇怪。飛虎隊的命好像不大值錢,也不需要跟遺眷交待一樣。袁樹的人馬也是一樣。這一點有點說不過去。警察在槍戰中犧牲,應該是更嚴重的事才對。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 79 | + 80 | + 81 | + 82 | + 83 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0081.html.zh-cn.html b/htdocs/imacat/me/diary/0081.html.zh-cn.html new file mode 120000 index 0000000..8fbf3d2 --- /dev/null +++ b/htdocs/imacat/me/diary/0081.html.zh-cn.html @@ -0,0 +1 @@ +0081.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0081.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0081.html.zh-cn.xhtml new file mode 100644 index 0000000..82b1c91 --- /dev/null +++ b/htdocs/imacat/me/diary/0081.html.zh-cn.xhtml @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷八十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷八十一

    + +
    + +
    + +
    +
    10.2.’06. 4:34am.
    + +

    没去同志大游行…呜呜呜…

    + +

    今年的同志大游行,因为之前太忙了,加上当天空大要上一整个下午的课,所以没有去,也忘了找朋友去。现在回想起来,应该找阿光去的。

    + +

    下了课赶去跟去游行的朋友吃饭,看起来好像很好玩,觉得好遗憾。

    + +

    刚刚整理九月份的信,看到集合小玉寄来的好几份游行的宣传。哇哇哇,没看到小玉~去年去游行,碰到小玉,就觉得好喜欢小玉这个人,吱吱喳喳地,超有活力的感觉,连平常吵闹的我都给比下去了。今年没看到小玉,好遗憾~

    + +

    真希望明年同志大游行的时候不会有事,可以去游行~ *^_^*

    + +

    小玉刚刚出了一本书,我想买来看。不过我现在要看的东西太多了,清单一长列,好像有点奢侈,买了也不知道要排到什么时候。唔。 ^^;

    + +

    吃饭的时候,认识了一个很可爱的 Amy 。可以认识可爱的朋友,真好~我也是人来疯呢~

    + +
    + +
    + +
    +
    9.30.’06. 0:23am.
    + +

    省港旗兵第四集 地下通道—看不到终点的偷渡路

    + +
    +省港旗兵第四集 地下通道
    +

    省港旗兵第四集 地下通道

    +
    + +
      +
    • 片名:省港旗兵第四集 地下通道
    • +
    • 英文片名: Underground Express
    • +
    • 发行年份: 1990
    • +
    • 制作公司:麦当雄制作有限公司
    • +
    • 出品人:麦当雄、萧若元
    • +
    • 编剧:麦当雄、萧若元
    • +
    • 导演:麦当杰
    • +
    • 演员: +
        +
      • 徐锦江:王兵
      • +
      • 吴雪雯:王小惠
      • +
      • 陈敬:狗公
      • +
      • 程小龙:大石
      • +
      • 陈治良:小石
      • +
      +
    • +
    • 推荐影评: + +
    • +
    + +

    这是我 9/25 晚上看的电影。

    + +

    中国发生了六四天安门事件,香港声援会主席欧阳卓为协助学生领袖王小惠、陈英、洪韵音逃出,欲聘请王兵为首的大圈仔犯罪集团协助偷渡。王兵集团原计划趁声援示威游行时打劫,因游行临时取消而中止,因而答应接下任务。王兵到广州后,王小惠认其为民主爱国人士冒死相救,万般推崇,令其深受感动,决心鼎力相助。然而,中国政治保卫局的袁树已经盯上了王兵一群人,风声鹤唳,逃亡的路上险阻重重。

    + +

    省港旗兵第四集与前三集最大的不同,在於前三集中,描绘的都是大圈仔偷渡后,在香港挣扎求生的故事,是偷渡后的事;而省港旗兵第四集,描绘的则是偷渡的过程本身。不稳定的政治局势,让偷渡的过程加倍的凶险。这样的凶险,使得一行人即使偷渡到了香港,逃亡也无法结束。港英政府不愿开罪中方,也不愿激起同情学运的一般民众的反感。一行人无法留在香港,只得继续偷渡、逃亡,航向不可知的危险汪洋。偷渡、逃亡的过程本身,就是主题。偷渡、逃亡的漫漫长路没有终点,片末模模糊糊交待两人相约美国再见,然而相见无期,安定的幸福在永远看不到的彼岸。

    + +

    很明显可以看得出,麦当雄拍省港旗兵第四集,想以一个电影人的身份,为六四尽一点心力。这使得省港旗兵第四集和前集比起来有很大的特色。省港旗兵具有很强的社会意识,省港旗兵第四集则具有相当浓的政治意识。

    + +

    徐锦江演得很不错,从匪徒到仗义挺身,又要面对兄弟生死的威胁,又要向兄弟交待,又惦记著不知道收不收得到的酬劳,还有彼此有情意的案主王小惠,其间的转折与挣扎,很微妙也很复杂,徐锦江表现得非常杰出。我看徐锦江演戏看得蛮多的了,不过很少看到这么精彩的表现。陈敬也很不错,已经从省港旗兵第一次拍戏的生涩新手,进步为心里只惦著钱,不断小心翼翼边陪笑边提醒老大酬劳问题,甚至后来不惜举枪相向,直到最后才豁出去的匪徒,可以演复杂戏码的称职配角了。比较起来,吴雪雯的王小惠则演得平平。另两位女配角,则几乎看不到什么演出。

    + +

    我在网路上查询了一会,中国有部份网友,将省港旗兵第四集列为香港十大反动电影之首。我想这样扣反动的大帽子,也太偏激了。任何社会都有各种各样的人,像这样偏激的人,我想当然也有。我觉得公开在网路上散布这样偏激的意见不大好,不过,我也不会因此就觉得,所有中国网友都这样想。

    + +

    省港旗兵第四集里面有些人命,感觉蛮轻的。王兵的同伙兄弟阵亡时,每一个都倍极哀伤;可是飞虎队和偷渡的袁树人马开战,死伤惨重时,却只是轻轻带过,一句三个死亡,英国警察骂几句脏话,要求严格看管袁树,就交待过去了,感觉上很奇怪。飞虎队的命好像不大值钱,也不需要跟遗眷交待一样。袁树的人马也是一样。这一点有点说不过去。警察在枪战中牺牲,应该是更严重的事才对。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 79 | + 80 | + 81 | + 82 | + 83 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0081.html.zh-tw.html b/htdocs/imacat/me/diary/0081.html.zh-tw.html new file mode 120000 index 0000000..668b47e --- /dev/null +++ b/htdocs/imacat/me/diary/0081.html.zh-tw.html @@ -0,0 +1 @@ +0081.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0081.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0081.html.zh-tw.xhtml new file mode 100644 index 0000000..43ab886 --- /dev/null +++ b/htdocs/imacat/me/diary/0081.html.zh-tw.xhtml @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷八十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷八十一

    + +
    + +
    + +
    +
    10.2.’06. 4:34am.
    + +

    沒去同志大遊行…嗚嗚嗚…

    + +

    今年的同志大遊行,因為之前太忙了,加上當天空大要上一整個下午的課,所以沒有去,也忘了找朋友去。現在回想起來,應該找阿光去的。

    + +

    下了課趕去跟去遊行的朋友吃飯,看起來好像很好玩,覺得好遺憾。

    + +

    剛剛整理九月份的信,看到集合小玉寄來的好幾份遊行的宣傳。哇哇哇,沒看到小玉~去年去遊行,碰到小玉,就覺得好喜歡小玉這個人,吱吱喳喳地,超有活力的感覺,連平常吵鬧的我都給比下去了。今年沒看到小玉,好遺憾~

    + +

    真希望明年同志大遊行的時候不會有事,可以去遊行~ *^_^*

    + +

    小玉剛剛出了一本書,我想買來看。不過我現在要看的東西太多了,清單一長列,好像有點奢侈,買了也不知道要排到什麼時候。唔。 ^^;

    + +

    吃飯的時候,認識了一個很可愛的 Amy 。可以認識可愛的朋友,真好~我也是人來瘋呢~

    + +
    + +
    + +
    +
    9.30.’06. 0:23am.
    + +

    省港旗兵第四集 地下通道—看不到終點的偷渡路

    + +
    +省港旗兵第四集 地下通道
    +

    省港旗兵第四集 地下通道

    +
    + +
      +
    • 片名:省港旗兵第四集 地下通道
    • +
    • 英文片名: Underground Express
    • +
    • 發行年份: 1990
    • +
    • 製作公司:麥當雄製作有限公司
    • +
    • 出品人:麥當雄、蕭若元
    • +
    • 編劇:麥當雄、蕭若元
    • +
    • 導演:麥當傑
    • +
    • 演員: +
        +
      • 徐錦江:王兵
      • +
      • 吳雪雯:王小惠
      • +
      • 陳敬:狗公
      • +
      • 程小龍:大石
      • +
      • 陳治良:小石
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    這是我 9/25 晚上看的電影。

    + +

    中國發生了六四天安門事件,香港聲援會主席歐陽卓為協助學生領袖王小惠、陳英、洪韻音逃出,欲聘請王兵為首的大圈仔犯罪集團協助偷渡。王兵集團原計劃趁聲援示威遊行時打劫,因遊行臨時取消而中止,因而答應接下任務。王兵到廣州後,王小惠認其為民主愛國人士冒死相救,萬般推崇,令其深受感動,決心鼎力相助。然而,中國政治保衛局的袁樹已經盯上了王兵一群人,風聲鶴唳,逃亡的路上險阻重重。

    + +

    省港旗兵第四集與前三集最大的不同,在於前三集中,描繪的都是大圈仔偷渡後,在香港掙扎求生的故事,是偷渡後的事;而省港旗兵第四集,描繪的則是偷渡的過程本身。不穩定的政治局勢,讓偷渡的過程加倍的兇險。這樣的兇險,使得一行人即使偷渡到了香港,逃亡也無法結束。港英政府不願開罪中方,也不願激起同情學運的一般民眾的反感。一行人無法留在香港,只得繼續偷渡、逃亡,航向不可知的危險汪洋。偷渡、逃亡的過程本身,就是主題。偷渡、逃亡的漫漫長路沒有終點,片末模模糊糊交待兩人相約美國再見,然而相見無期,安定的幸福在永遠看不到的彼岸。

    + +

    很明顯可以看得出,麥當雄拍省港旗兵第四集,想以一個電影人的身份,為六四盡一點心力。這使得省港旗兵第四集和前集比起來有很大的特色。省港旗兵具有很強的社會意識,省港旗兵第四集則具有相當濃的政治意識。

    + +

    徐錦江演得很不錯,從匪徒到仗義挺身,又要面對兄弟生死的威脅,又要向兄弟交待,又惦記著不知道收不收得到的酬勞,還有彼此有情意的案主王小惠,其間的轉折與掙扎,很微妙也很複雜,徐錦江表現得非常傑出。我看徐錦江演戲看得蠻多的了,不過很少看到這麼精彩的表現。陳敬也很不錯,已經從省港旗兵第一次拍戲的生澀新手,進步為心裏只惦著錢,不斷小心翼翼邊陪笑邊提醒老大酬勞問題,甚至後來不惜舉槍相向,直到最後才豁出去的匪徒,可以演複雜戲碼的稱職配角了。比較起來,吳雪雯的王小惠則演得平平。另兩位女配角,則幾乎看不到什麼演出。

    + +

    我在網路上查詢了一會,中國有部份網友,將省港旗兵第四集列為香港十大反動電影之首。我想這樣扣反動的大帽子,也太偏激了。任何社會都有各種各樣的人,像這樣偏激的人,我想當然也有。我覺得公開在網路上散佈這樣偏激的意見不大好,不過,我也不會因此就覺得,所有中國網友都這樣想。

    + +

    省港旗兵第四集裏面有些人命,感覺蠻輕的。王兵的同夥兄弟陣亡時,每一個都倍極哀傷;可是飛虎隊和偷渡的袁樹人馬開戰,死傷慘重時,卻只是輕輕帶過,一句三個死亡,英國警察罵幾句髒話,要求嚴格看管袁樹,就交待過去了,感覺上很奇怪。飛虎隊的命好像不大值錢,也不需要跟遺眷交待一樣。袁樹的人馬也是一樣。這一點有點說不過去。警察在槍戰中犧牲,應該是更嚴重的事才對。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 79 | + 80 | + 81 | + 82 | + 83 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0082.html.en.html b/htdocs/imacat/me/diary/0082.html.en.html new file mode 120000 index 0000000..445d9fc --- /dev/null +++ b/htdocs/imacat/me/diary/0082.html.en.html @@ -0,0 +1 @@ +0082.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0082.html.en.xhtml b/htdocs/imacat/me/diary/0082.html.en.xhtml new file mode 100644 index 0000000..f7de09a --- /dev/null +++ b/htdocs/imacat/me/diary/0082.html.en.xhtml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 82 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 82

    + +
    + +
    + +
    +
    10.4.’06. 5:00am.
    + +

    國士無雙—濃濃台灣味、好看又好笑的商業動作娛樂片

    + +
    +國士無雙
    +

    國士無雙

    +
    + +
      +
    • 片名:國士無雙
    • +
    • 英文片名: Catch
    • +
    • 發行年份: 2006
    • +
    • 製作公司:三和國際娛樂有限公司
    • +
    • 導演:陳映蓉(十七歲的天空 (2004) )
    • +
    • 演員: +
        +
      • 楊祐寧:臨時演員吳樂極、吳懷一
      • +
      • 天心:專案組特派組組長劉星
      • +
      • 李振冬:專案組特派組副組長 5269 王子
      • +
      • 葉羿君:朝代新聞主播張知其
      • +
      • 金勤:詐騙集團創意總監安守信
      • +
      • 林孟謹:詐騙集團總管小敏
      • +
      • 葛西健二:聲優關世音(觀音)
      • +
      • 歐陽雄:中央刑事警察局長歐陽雄
      • +
      • 黃泰安:偽卡專家車九(打鬼)
      • +
      • 阿 Ken :電信專家葉家兵(拉 B )
      • +
      • 陳奧良:詐騙菜鳥林光遠
      • +
      • 林美秀:唯一見過十一哥的證人六根
      • +
      • 夏靖庭:拍到十一哥照片的證人金貴
      • +
      • 鄧安寧:詐騙集團主任
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    這是我 9/28 上星期四晚上看的電影。

    + +

    國士無雙是導演陳映蓉繼十七歲的天空 (2004)後的第二部電影:傳說中的詐騙之神十一哥重出江湖。警方接到線報,誓要一網成擒,請回留美警官劉星,並找來沒沒無名的臨時演員吳樂極,潛入詐騙集團臥底。詐騙集團新星安守信收到消息,招兵買馬,並找沒有存在感的新人吳樂極,扮演縱橫國際董事長吳懷一,企圖向旭日集團李東昇海削一筆,以求上面的十一哥青睞。吳樂極夾在警方和詐騙集團間扮演雙重角色,還有心儀的朝代新聞主播張知其不時攪局。而神秘莫測的十一哥,到底在哪裏?

    + +

    國士無雙原指國內獨一無二的傑出人才,是史記中張良稱讚韓信的用語:諸將易得耳,至如信者,國士無雙。國士無雙官方網站上所述,日本人稱香港十三張麻將的十三么國士無雙。十三么是東、南、西、北、中、發、白、一萬、九萬、一筒、九筒、一索、九索十三張牌的牌型,完全沒有成雙對(故稱無雙),原為最爛、最難胡的牌型,反而算滿貫十三番。電影國士無雙中,三個警察(劉星、王子、歐陽雄)、六個詐騙集團成員(安守信、小敏、觀音、打鬼、拉 B 、林光遠)、一個媒體(張知其)、兩個關鍵證人(六根、金貴))加上臨時演員吳樂極,組成了國士無雙牌型不可或缺的十三個角色。

    + +

    國士無雙超級好看。計謀極具巧思,劇情節奏緊湊,笑點很多,而且很有台灣味。很多笑點,即使看過一遍、知道結局後,再回過頭來看,多回味幾遍,還是覺得很好看。

    + +

    看完國士無雙,讓我聯想起同屬騙計電影的瞞天過海 Ocean’s Eleven (2001) 。不過國士無雙的情節,我覺得更勝瞞天過海 。看完後,覺得瞞天過海之所以大賣,不過是用錢堆積出來的。國士無雙回頭看時,不少穿插的意外事件,讓計謀橫生變數,都有點勉強。可是再仔細看,意外能化險為夷,正展現出十一哥隨機應變的高超能力。這點,反而比完美無瑕的計劃還要有看頭。

    + +

    拉 B 、打鬼和觀音三人,沒有展現他們特殊長才的橋段,的確是比較可惜的地方。

    + +

    天心演的警官,我覺得味道有出來。雖然我以前不喜歡天心,不過我覺得她在國士無雙演得還蠻不錯的,很有說服力。金勤演得非常棒,一張臉的神經像是完全解放了一樣,可以隨意繃緊、扭曲,表現出了一個氣質非常特別的安守信。

    + +

    其實還有一個很顯眼的角色:鄧安寧演的詐騙集團主任。好久沒看到鄧安寧,鄧安寧頭頂好像禿了。鄧安寧是電視上的老牌硬底子喜劇演員,即使是大配角還是非常自然搶眼,演技一流。大概是因為要湊十三么,所以被犧牲掉了。每次看到他邊跺步邊說話,邊嚼洋芋片邊掉,一旁的潔癖狂安守信氣得直跳腳,又不能發作,就覺得好好笑,張力十足。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 80 | + 81 | + 82 | + 83 | + 84 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0082.html.zh-cn.html b/htdocs/imacat/me/diary/0082.html.zh-cn.html new file mode 120000 index 0000000..891b69b --- /dev/null +++ b/htdocs/imacat/me/diary/0082.html.zh-cn.html @@ -0,0 +1 @@ +0082.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0082.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0082.html.zh-cn.xhtml new file mode 100644 index 0000000..93ca9db --- /dev/null +++ b/htdocs/imacat/me/diary/0082.html.zh-cn.xhtml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷八十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷八十二

    + +
    + +
    + +
    +
    10.4.’06. 5:00am.
    + +

    国士无双—浓浓台湾味、好看又好笑的商业动作娱乐片

    + +
    +国士无双
    +

    国士无双

    +
    + +
      +
    • 片名:国士无双
    • +
    • 英文片名: Catch
    • +
    • 发行年份: 2006
    • +
    • 制作公司:三和国际娱乐有限公司
    • +
    • 导演:陈映蓉(十七岁的天空 (2004) )
    • +
    • 演员: +
        +
      • 杨佑宁:临时演员吴乐极、吴怀一
      • +
      • 天心:专案组特派组组长刘星
      • +
      • 李振冬:专案组特派组副组长 5269 王子
      • +
      • 叶羿君:朝代新闻主播张知其
      • +
      • 金勤:诈骗集团创意总监安守信
      • +
      • 林孟谨:诈骗集团总管小敏
      • +
      • 葛西健二:声优关世音(观音)
      • +
      • 欧阳雄:中央刑事警察局长欧阳雄
      • +
      • 黄泰安:伪卡专家车九(打鬼)
      • +
      • 阿 Ken :电信专家叶家兵(拉 B )
      • +
      • 陈奥良:诈骗菜鸟林光远
      • +
      • 林美秀:唯一见过十一哥的证人六根
      • +
      • 夏靖庭:拍到十一哥照片的证人金贵
      • +
      • 邓安宁:诈骗集团主任
      • +
      +
    • +
    • 推荐影评: + +
    • +
    + +

    这是我 9/28 上星期四晚上看的电影。

    + +

    国士无双是导演陈映蓉继十七岁的天空 (2004)后的第二部电影:传说中的诈骗之神十一哥重出江湖。警方接到线报,誓要一网成擒,请回留美警官刘星,并找来没没无名的临时演员吴乐极,潜入诈骗集团卧底。诈骗集团新星安守信收到消息,招兵买马,并找没有存在感的新人吴乐极,扮演纵横国际董事长吴怀一,企图向旭日集团李东升海削一笔,以求上面的十一哥青睐。吴乐极夹在警方和诈骗集团间扮演双重角色,还有心仪的朝代新闻主播张知其不时搅局。而神秘莫测的十一哥,到底在哪里?

    + +

    国士无双原指国内独一无二的杰出人才,是史记中张良称赞韩信的用语:诸将易得耳,至如信者,国士无双。国士无双官方网站上所述,日本人称香港十三张麻将的十三么国士无双。十三么是东、南、西、北、中、发、白、一万、九万、一筒、九筒、一索、九索十三张牌的牌型,完全没有成双对(故称无双),原为最烂、最难胡的牌型,反而算满贯十三番。电影国士无双中,三个警察(刘星、王子、欧阳雄)、六个诈骗集团成员(安守信、小敏、观音、打鬼、拉 B 、林光远)、一个媒体(张知其)、两个关键证人(六根、金贵))加上临时演员吴乐极,组成了国士无双牌型不可或缺的十三个角色。

    + +

    国士无双超级好看。计谋极具巧思,剧情节奏紧凑,笑点很多,而且很有台湾味。很多笑点,即使看过一遍、知道结局后,再回过头来看,多回味几遍,还是觉得很好看。

    + +

    看完国士无双,让我联想起同属骗计电影的瞒天过海 Ocean’s Eleven (2001) 。不过国士无双的情节,我觉得更胜瞒天过海 。看完后,觉得瞒天过海之所以大卖,不过是用钱堆积出来的。国士无双回头看时,不少穿插的意外事件,让计谋横生变数,都有点勉强。可是再仔细看,意外能化险为夷,正展现出十一哥随机应变的高超能力。这点,反而比完美无瑕的计划还要有看头。

    + +

    拉 B 、打鬼和观音三人,没有展现他们特殊长才的桥段,的确是比较可惜的地方。

    + +

    天心演的警官,我觉得味道有出来。虽然我以前不喜欢天心,不过我觉得她在国士无双演得还蛮不错的,很有说服力。金勤演得非常棒,一张脸的神经像是完全解放了一样,可以随意绷紧、扭曲,表现出了一个气质非常特别的安守信。

    + +

    其实还有一个很显眼的角色:邓安宁演的诈骗集团主任。好久没看到邓安宁,邓安宁头顶好像秃了。邓安宁是电视上的老牌硬底子喜剧演员,即使是大配角还是非常自然抢眼,演技一流。大概是因为要凑十三么,所以被牺牲掉了。每次看到他边跺步边说话,边嚼洋芋片边掉,一旁的洁癖狂安守信气得直跳脚,又不能发作,就觉得好好笑,张力十足。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 80 | + 81 | + 82 | + 83 | + 84 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0082.html.zh-tw.html b/htdocs/imacat/me/diary/0082.html.zh-tw.html new file mode 120000 index 0000000..df416e3 --- /dev/null +++ b/htdocs/imacat/me/diary/0082.html.zh-tw.html @@ -0,0 +1 @@ +0082.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0082.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0082.html.zh-tw.xhtml new file mode 100644 index 0000000..a4cf175 --- /dev/null +++ b/htdocs/imacat/me/diary/0082.html.zh-tw.xhtml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷八十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷八十二

    + +
    + +
    + +
    +
    10.4.’06. 5:00am.
    + +

    國士無雙—濃濃台灣味、好看又好笑的商業動作娛樂片

    + +
    +國士無雙
    +

    國士無雙

    +
    + +
      +
    • 片名:國士無雙
    • +
    • 英文片名: Catch
    • +
    • 發行年份: 2006
    • +
    • 製作公司:三和國際娛樂有限公司
    • +
    • 導演:陳映蓉(十七歲的天空 (2004) )
    • +
    • 演員: +
        +
      • 楊祐寧:臨時演員吳樂極、吳懷一
      • +
      • 天心:專案組特派組組長劉星
      • +
      • 李振冬:專案組特派組副組長 5269 王子
      • +
      • 葉羿君:朝代新聞主播張知其
      • +
      • 金勤:詐騙集團創意總監安守信
      • +
      • 林孟謹:詐騙集團總管小敏
      • +
      • 葛西健二:聲優關世音(觀音)
      • +
      • 歐陽雄:中央刑事警察局長歐陽雄
      • +
      • 黃泰安:偽卡專家車九(打鬼)
      • +
      • 阿 Ken :電信專家葉家兵(拉 B )
      • +
      • 陳奧良:詐騙菜鳥林光遠
      • +
      • 林美秀:唯一見過十一哥的證人六根
      • +
      • 夏靖庭:拍到十一哥照片的證人金貴
      • +
      • 鄧安寧:詐騙集團主任
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    這是我 9/28 上星期四晚上看的電影。

    + +

    國士無雙是導演陳映蓉繼十七歲的天空 (2004)後的第二部電影:傳說中的詐騙之神十一哥重出江湖。警方接到線報,誓要一網成擒,請回留美警官劉星,並找來沒沒無名的臨時演員吳樂極,潛入詐騙集團臥底。詐騙集團新星安守信收到消息,招兵買馬,並找沒有存在感的新人吳樂極,扮演縱橫國際董事長吳懷一,企圖向旭日集團李東昇海削一筆,以求上面的十一哥青睞。吳樂極夾在警方和詐騙集團間扮演雙重角色,還有心儀的朝代新聞主播張知其不時攪局。而神秘莫測的十一哥,到底在哪裏?

    + +

    國士無雙原指國內獨一無二的傑出人才,是史記中張良稱讚韓信的用語:諸將易得耳,至如信者,國士無雙。國士無雙官方網站上所述,日本人稱香港十三張麻將的十三么國士無雙。十三么是東、南、西、北、中、發、白、一萬、九萬、一筒、九筒、一索、九索十三張牌的牌型,完全沒有成雙對(故稱無雙),原為最爛、最難胡的牌型,反而算滿貫十三番。電影國士無雙中,三個警察(劉星、王子、歐陽雄)、六個詐騙集團成員(安守信、小敏、觀音、打鬼、拉 B 、林光遠)、一個媒體(張知其)、兩個關鍵證人(六根、金貴))加上臨時演員吳樂極,組成了國士無雙牌型不可或缺的十三個角色。

    + +

    國士無雙超級好看。計謀極具巧思,劇情節奏緊湊,笑點很多,而且很有台灣味。很多笑點,即使看過一遍、知道結局後,再回過頭來看,多回味幾遍,還是覺得很好看。

    + +

    看完國士無雙,讓我聯想起同屬騙計電影的瞞天過海 Ocean’s Eleven (2001) 。不過國士無雙的情節,我覺得更勝瞞天過海 。看完後,覺得瞞天過海之所以大賣,不過是用錢堆積出來的。國士無雙回頭看時,不少穿插的意外事件,讓計謀橫生變數,都有點勉強。可是再仔細看,意外能化險為夷,正展現出十一哥隨機應變的高超能力。這點,反而比完美無瑕的計劃還要有看頭。

    + +

    拉 B 、打鬼和觀音三人,沒有展現他們特殊長才的橋段,的確是比較可惜的地方。

    + +

    天心演的警官,我覺得味道有出來。雖然我以前不喜歡天心,不過我覺得她在國士無雙演得還蠻不錯的,很有說服力。金勤演得非常棒,一張臉的神經像是完全解放了一樣,可以隨意繃緊、扭曲,表現出了一個氣質非常特別的安守信。

    + +

    其實還有一個很顯眼的角色:鄧安寧演的詐騙集團主任。好久沒看到鄧安寧,鄧安寧頭頂好像禿了。鄧安寧是電視上的老牌硬底子喜劇演員,即使是大配角還是非常自然搶眼,演技一流。大概是因為要湊十三么,所以被犧牲掉了。每次看到他邊跺步邊說話,邊嚼洋芋片邊掉,一旁的潔癖狂安守信氣得直跳腳,又不能發作,就覺得好好笑,張力十足。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 80 | + 81 | + 82 | + 83 | + 84 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0083.html.en.html b/htdocs/imacat/me/diary/0083.html.en.html new file mode 120000 index 0000000..59b168b --- /dev/null +++ b/htdocs/imacat/me/diary/0083.html.en.html @@ -0,0 +1 @@ +0083.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0083.html.en.xhtml b/htdocs/imacat/me/diary/0083.html.en.xhtml new file mode 100644 index 0000000..70e3f5f --- /dev/null +++ b/htdocs/imacat/me/diary/0083.html.en.xhtml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 83 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 83

    + +
    + +
    + +
    +
    10.7.’06. 2:56am.
    + +

    暗戰 2—被魔術師耍著玩的高級督察

    + +
    +暗戰 2
    +

    暗戰 2

    +
    + +
      +
    • 片名:暗戰 2
    • +
    • 英文片名: Running Out of Time 2
    • +
    • 台灣上映片名:暗戰—談判專家Ⅱ
    • +
    • 發行年份: 2001
    • +
    • 製作公司:銀河映像公司
    • +
    • 出品人:向華強
    • +
    • 導演:杜琪峰
    • +
    • 編劇:游乃海、歐健兒、銀河創作組
    • +
    • 演員: +
        +
      • 劉青雲:何尚生督察
      • +
      • 鄭伊健:竊賊
      • +
      • 林熙蕾: Teresa 何麗花
      • +
      • 許紹雄:黃啟法總督察
      • +
      • 林雪:談判專家陳勁威
      • +
      • 黃卓玲:國際刑警主管
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    暗戰 2敘述保險公司何麗花正要購併一家中國內地的保險公司,擴張企業版圖,此時公司受理保險的三件藝術品被同一人所竊,竊賊看準保險公司不願在購併的關鍵時刻,爆出投保品特別容易被竊的負面傳聞,欲勒贖保險公司。何麗花原欲付贖私了,不願警方介入,但何尚生督察早已盯上該保險公司。於是,警方和竊賊的大鬥法,一步一步展開。

    + +

    暗戰 2沒有暗戰好看。英文片名 Running Out of Time 2 ,可是劇情卻完全看不出跟 Running Out of Time 有什麼關係。第一集的竊賊是求死,第二集則是要救世。我之前看了關於銀河映像,談到鄭伊健的對手是第一集的劉德華,還說是救人的天使,以為會把劉德華救回來。可是不然,要救的是非洲的肌餓兒童。可是我看不大懂,把一億港幣贖金拿來買糖果,送給非洲肌餓兒童,有什麼意義。就如同片尾,何尚生讀到報紙頭條,竊賊用自己名義,在聖誕節捐了一億的糖果,輕哼了一句:飯都沒得吃,吃糖果?我也是這種感覺。

    + +

    暗戰 2完全沒有交待竊賊的動機和背景。竊賊到底為什麼要花這麼大精力佈這個局,來買糖果送非洲肌餓兒童?竊賊的動機為何?交待得不清不楚,很沒有說服力。竊賊的背景,也是一團謎霧,連姓都沒有了。

    + +

    暗戰 2裏,何尚生督察和竊賊,其實沒有什麼鬥智。賽局幾乎都是一面倒,何督察被竊賊任意玩弄,牽著鼻子走。只有最後,何督察用假贖金騙了竊賊一次而已。比起第一集兩人鬥智鬥力,感覺差了很多,劉青雲演的何尚生督察,變得很蠢很容易被耍。何尚生變蠢,黃啟法就更蠢了。竊賊佈的局,在關鍵時刻,幾乎都是靠黃啟法出的鎚,才能成功。黃啟法除了履履幫竊賊成局以外,在劇中幾乎沒有功能。

    + +

    暗戰 2比較有趣的,是林雪演的談判專家陳勁威的旁枝劇情。陳勁威本來是警察,可是欠了一屁股債,走投無路。這時在天台碰到了竊賊,欲勸其下樓時,在竊賊挑釁下,陷入猜硬幣的遊戲,每次都固執地猜人頭,履猜履輸。後來在路上偶遇竊賊,跟著進入餐館,要求看硬幣是否造假,發現沒有造假,可是猜人頭還是猜輸。最後一億元的交贖日,陳勁威被債主打得鼻青臉腫,走進竊賊常去的餐館,要求繼續猜硬幣。他還是固執地猜人頭,還是履猜履輸。竊賊邊陪他玩邊打電話換地點,還勸他吃過午飯再繼續。吃完飯竊賊正要繼續猜,他突然詢問猜了幾次了。知道連猜了 372 次後,喃喃自語:我輸了 372 次,為什麼還要猜下去?想開了的陳勁威,拿了竊賊給他的兩元硬幣,就走了。路上碰到勸募的小朋友,捐掉了那個兩元硬幣,換來了一玫感謝胸章,非常開心。

    + +

    我覺得這一段故事,比起劇情主線還要好看。意象非常清晰,象徵性很豐富,還有很濃的禪意。林雪的演出表現,也非常搶眼。

    + +

    林熙蕾的演出,也很搶眼。我一開始幾乎認不出林熙蕾。擺脫了帶邪氣的性感美女形象,變身成為全身套裝、頭髮梳理整齊的幹練女強人。只是對於這樣的角色,演技還是有待加強。在指揮公司幹部、交待業務的時候,感覺還是有點薄弱,沒有女強人對白中應有的氣勢。

    + +

    竊賊一開始寄給何尚生督察三個神秘物品:塑膠蓋、鑰匙和笛子。塑膠蓋是警局的垃圾筒蓋,鑰匙是黃啟法置物櫃的鑰匙,分別在第一次、第二次付贖時發揮作用。可是笛子就完全不知道是什麼用途了。我一直沒有印象那隻笛子用在哪裏,反覆看了幾次後,才看到在劇尾聖誕夜,何尚生在街上看到竊賊的北美洲白頭禿鷹時,把笛子拿出來一吹,禿鷹就飛走了。唔,原來是鳥笛。不過這個鳥笛,在劇情中發揮的作用也太小了,根本無關緊要。

    + +

    那隻北美洲白頭禿鷹到底有什麼含義?我看完了還是滿頭霧水。

    + +

    網路上有些暗戰 2的劇情本事,根本是胡說八道,和電影中的劇情差了十萬八千里。雖然說電影介紹中的本事,和實際劇情有點小落差,是常有的事。但差到這種程度,也真的很少見。

    + +

    鄭伊健演的竊賊,自稱為魔術師。原來是個魔術師啊!難怪可以在何尚生駕駛,行駛中的計程車上,沒開車門,放個煙人就不見了;可以走鋼索跨越兩棟大樓;可以從大樓天台邊緣,外套一蓋就把何尚生銬的手銬解開了,再一往下跳就這樣消失了;也可以讓談判專家陳勁威連猜 372 次人頭都猜輸?簡直是胡說八道!魔術基本上都是造假、有機關的,除了猜硬幣遊戲外,計程車是何尚生開來的,手銬是何尚生銬上的,這兩件事怎麼設機關、造假法,我完全無法想像。真是太沒有說服力了。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 81 | + 82 | + 83 | + 84 | + 85 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0083.html.zh-cn.html b/htdocs/imacat/me/diary/0083.html.zh-cn.html new file mode 120000 index 0000000..b726cfa --- /dev/null +++ b/htdocs/imacat/me/diary/0083.html.zh-cn.html @@ -0,0 +1 @@ +0083.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0083.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0083.html.zh-cn.xhtml new file mode 100644 index 0000000..a68b7b8 --- /dev/null +++ b/htdocs/imacat/me/diary/0083.html.zh-cn.xhtml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷八十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷八十三

    + +
    + +
    + +
    +
    10.7.’06. 2:56am.
    + +

    暗战 2—被魔术师耍著玩的高级督察

    + +
    +暗战 2
    +

    暗战 2

    +
    + +
      +
    • 片名:暗战 2
    • +
    • 英文片名: Running Out of Time 2
    • +
    • 台湾上映片名:暗战—谈判专家Ⅱ
    • +
    • 发行年份: 2001
    • +
    • 制作公司:银河映像公司
    • +
    • 出品人:向华强
    • +
    • 导演:杜琪峰
    • +
    • 编剧:游乃海、欧健儿、银河创作组
    • +
    • 演员: +
        +
      • 刘青云:何尚生督察
      • +
      • 郑伊健:窃贼
      • +
      • 林熙蕾: Teresa 何丽花
      • +
      • 许绍雄:黄启法总督察
      • +
      • 林雪:谈判专家陈劲威
      • +
      • 黄卓玲:国际刑警主管
      • +
      +
    • +
    • 推荐影评: + +
    • +
    + +

    暗战 2叙述保险公司何丽花正要购并一家中国内地的保险公司,扩张企业版图,此时公司受理保险的三件艺术品被同一人所窃,窃贼看准保险公司不愿在购并的关键时刻,爆出投保品特别容易被窃的负面传闻,欲勒赎保险公司。何丽花原欲付赎私了,不愿警方介入,但何尚生督察早已盯上该保险公司。於是,警方和窃贼的大斗法,一步一步展开。

    + +

    暗战 2没有暗战好看。英文片名 Running Out of Time 2 ,可是剧情却完全看不出跟 Running Out of Time 有什么关系。第一集的窃贼是求死,第二集则是要救世。我之前看了关於银河映像,谈到郑伊健的对手是第一集的刘德华,还说是救人的天使,以为会把刘德华救回来。可是不然,要救的是非洲的肌饿儿童。可是我看不大懂,把一亿港币赎金拿来买糖果,送给非洲肌饿儿童,有什么意义。就如同片尾,何尚生读到报纸头条,窃贼用自己名义,在圣诞节捐了一亿的糖果,轻哼了一句:饭都没得吃,吃糖果?我也是这种感觉。

    + +

    暗战 2完全没有交待窃贼的动机和背景。窃贼到底为什么要花这么大精力布这个局,来买糖果送非洲肌饿儿童?窃贼的动机为何?交待得不清不楚,很没有说服力。窃贼的背景,也是一团谜雾,连姓都没有了。

    + +

    暗战 2里,何尚生督察和窃贼,其实没有什么斗智。赛局几乎都是一面倒,何督察被窃贼任意玩弄,牵著鼻子走。只有最后,何督察用假赎金骗了窃贼一次而已。比起第一集两人斗智斗力,感觉差了很多,刘青云演的何尚生督察,变得很蠢很容易被耍。何尚生变蠢,黄启法就更蠢了。窃贼布的局,在关键时刻,几乎都是靠黄启法出的锤,才能成功。黄启法除了履履帮窃贼成局以外,在剧中几乎没有功能。

    + +

    暗战 2比较有趣的,是林雪演的谈判专家陈劲威的旁枝剧情。陈劲威本来是警察,可是欠了一屁股债,走投无路。这时在天台碰到了窃贼,欲劝其下楼时,在窃贼挑衅下,陷入猜硬币的游戏,每次都固执地猜人头,履猜履输。后来在路上偶遇窃贼,跟著进入餐馆,要求看硬币是否造假,发现没有造假,可是猜人头还是猜输。最后一亿元的交赎日,陈劲威被债主打得鼻青脸肿,走进窃贼常去的餐馆,要求继续猜硬币。他还是固执地猜人头,还是履猜履输。窃贼边陪他玩边打电话换地点,还劝他吃过午饭再继续。吃完饭窃贼正要继续猜,他突然询问猜了几次了。知道连猜了 372 次后,喃喃自语:我输了 372 次,为什么还要猜下去?想开了的陈劲威,拿了窃贼给他的两元硬币,就走了。路上碰到劝募的小朋友,捐掉了那个两元硬币,换来了一玫感谢胸章,非常开心。

    + +

    我觉得这一段故事,比起剧情主线还要好看。意象非常清晰,象徵性很丰富,还有很浓的禅意。林雪的演出表现,也非常抢眼。

    + +

    林熙蕾的演出,也很抢眼。我一开始几乎认不出林熙蕾。摆脱了带邪气的性感美女形象,变身成为全身套装、头发梳理整齐的干练女强人。只是对於这样的角色,演技还是有待加强。在指挥公司干部、交待业务的时候,感觉还是有点薄弱,没有女强人对白中应有的气势。

    + +

    窃贼一开始寄给何尚生督察三个神秘物品:塑胶盖、钥匙和笛子。塑胶盖是警局的垃圾筒盖,钥匙是黄启法置物柜的钥匙,分别在第一次、第二次付赎时发挥作用。可是笛子就完全不知道是什么用途了。我一直没有印象那只笛子用在哪里,反覆看了几次后,才看到在剧尾圣诞夜,何尚生在街上看到窃贼的北美洲白头秃鹰时,把笛子拿出来一吹,秃鹰就飞走了。唔,原来是鸟笛。不过这个鸟笛,在剧情中发挥的作用也太小了,根本无关紧要。

    + +

    那只北美洲白头秃鹰到底有什么含义?我看完了还是满头雾水。

    + +

    网路上有些暗战 2的剧情本事,根本是胡说八道,和电影中的剧情差了十万八千里。虽然说电影介绍中的本事,和实际剧情有点小落差,是常有的事。但差到这种程度,也真的很少见。

    + +

    郑伊健演的窃贼,自称为魔术师。原来是个魔术师啊!难怪可以在何尚生驾驶,行驶中的计程车上,没开车门,放个烟人就不见了;可以走钢索跨越两栋大楼;可以从大楼天台边缘,外套一盖就把何尚生铐的手铐解开了,再一往下跳就这样消失了;也可以让谈判专家陈劲威连猜 372 次人头都猜输?简直是胡说八道!魔术基本上都是造假、有机关的,除了猜硬币游戏外,计程车是何尚生开来的,手铐是何尚生铐上的,这两件事怎么设机关、造假法,我完全无法想像。真是太没有说服力了。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 81 | + 82 | + 83 | + 84 | + 85 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0083.html.zh-tw.html b/htdocs/imacat/me/diary/0083.html.zh-tw.html new file mode 120000 index 0000000..56522de --- /dev/null +++ b/htdocs/imacat/me/diary/0083.html.zh-tw.html @@ -0,0 +1 @@ +0083.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0083.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0083.html.zh-tw.xhtml new file mode 100644 index 0000000..3c478e5 --- /dev/null +++ b/htdocs/imacat/me/diary/0083.html.zh-tw.xhtml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷八十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷八十三

    + +
    + +
    + +
    +
    10.7.’06. 2:56am.
    + +

    暗戰 2—被魔術師耍著玩的高級督察

    + +
    +暗戰 2
    +

    暗戰 2

    +
    + +
      +
    • 片名:暗戰 2
    • +
    • 英文片名: Running Out of Time 2
    • +
    • 台灣上映片名:暗戰—談判專家Ⅱ
    • +
    • 發行年份: 2001
    • +
    • 製作公司:銀河映像公司
    • +
    • 出品人:向華強
    • +
    • 導演:杜琪峰
    • +
    • 編劇:游乃海、歐健兒、銀河創作組
    • +
    • 演員: +
        +
      • 劉青雲:何尚生督察
      • +
      • 鄭伊健:竊賊
      • +
      • 林熙蕾: Teresa 何麗花
      • +
      • 許紹雄:黃啟法總督察
      • +
      • 林雪:談判專家陳勁威
      • +
      • 黃卓玲:國際刑警主管
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    暗戰 2敘述保險公司何麗花正要購併一家中國內地的保險公司,擴張企業版圖,此時公司受理保險的三件藝術品被同一人所竊,竊賊看準保險公司不願在購併的關鍵時刻,爆出投保品特別容易被竊的負面傳聞,欲勒贖保險公司。何麗花原欲付贖私了,不願警方介入,但何尚生督察早已盯上該保險公司。於是,警方和竊賊的大鬥法,一步一步展開。

    + +

    暗戰 2沒有暗戰好看。英文片名 Running Out of Time 2 ,可是劇情卻完全看不出跟 Running Out of Time 有什麼關係。第一集的竊賊是求死,第二集則是要救世。我之前看了關於銀河映像,談到鄭伊健的對手是第一集的劉德華,還說是救人的天使,以為會把劉德華救回來。可是不然,要救的是非洲的肌餓兒童。可是我看不大懂,把一億港幣贖金拿來買糖果,送給非洲肌餓兒童,有什麼意義。就如同片尾,何尚生讀到報紙頭條,竊賊用自己名義,在聖誕節捐了一億的糖果,輕哼了一句:飯都沒得吃,吃糖果?我也是這種感覺。

    + +

    暗戰 2完全沒有交待竊賊的動機和背景。竊賊到底為什麼要花這麼大精力佈這個局,來買糖果送非洲肌餓兒童?竊賊的動機為何?交待得不清不楚,很沒有說服力。竊賊的背景,也是一團謎霧,連姓都沒有了。

    + +

    暗戰 2裏,何尚生督察和竊賊,其實沒有什麼鬥智。賽局幾乎都是一面倒,何督察被竊賊任意玩弄,牽著鼻子走。只有最後,何督察用假贖金騙了竊賊一次而已。比起第一集兩人鬥智鬥力,感覺差了很多,劉青雲演的何尚生督察,變得很蠢很容易被耍。何尚生變蠢,黃啟法就更蠢了。竊賊佈的局,在關鍵時刻,幾乎都是靠黃啟法出的鎚,才能成功。黃啟法除了履履幫竊賊成局以外,在劇中幾乎沒有功能。

    + +

    暗戰 2比較有趣的,是林雪演的談判專家陳勁威的旁枝劇情。陳勁威本來是警察,可是欠了一屁股債,走投無路。這時在天台碰到了竊賊,欲勸其下樓時,在竊賊挑釁下,陷入猜硬幣的遊戲,每次都固執地猜人頭,履猜履輸。後來在路上偶遇竊賊,跟著進入餐館,要求看硬幣是否造假,發現沒有造假,可是猜人頭還是猜輸。最後一億元的交贖日,陳勁威被債主打得鼻青臉腫,走進竊賊常去的餐館,要求繼續猜硬幣。他還是固執地猜人頭,還是履猜履輸。竊賊邊陪他玩邊打電話換地點,還勸他吃過午飯再繼續。吃完飯竊賊正要繼續猜,他突然詢問猜了幾次了。知道連猜了 372 次後,喃喃自語:我輸了 372 次,為什麼還要猜下去?想開了的陳勁威,拿了竊賊給他的兩元硬幣,就走了。路上碰到勸募的小朋友,捐掉了那個兩元硬幣,換來了一玫感謝胸章,非常開心。

    + +

    我覺得這一段故事,比起劇情主線還要好看。意象非常清晰,象徵性很豐富,還有很濃的禪意。林雪的演出表現,也非常搶眼。

    + +

    林熙蕾的演出,也很搶眼。我一開始幾乎認不出林熙蕾。擺脫了帶邪氣的性感美女形象,變身成為全身套裝、頭髮梳理整齊的幹練女強人。只是對於這樣的角色,演技還是有待加強。在指揮公司幹部、交待業務的時候,感覺還是有點薄弱,沒有女強人對白中應有的氣勢。

    + +

    竊賊一開始寄給何尚生督察三個神秘物品:塑膠蓋、鑰匙和笛子。塑膠蓋是警局的垃圾筒蓋,鑰匙是黃啟法置物櫃的鑰匙,分別在第一次、第二次付贖時發揮作用。可是笛子就完全不知道是什麼用途了。我一直沒有印象那隻笛子用在哪裏,反覆看了幾次後,才看到在劇尾聖誕夜,何尚生在街上看到竊賊的北美洲白頭禿鷹時,把笛子拿出來一吹,禿鷹就飛走了。唔,原來是鳥笛。不過這個鳥笛,在劇情中發揮的作用也太小了,根本無關緊要。

    + +

    那隻北美洲白頭禿鷹到底有什麼含義?我看完了還是滿頭霧水。

    + +

    網路上有些暗戰 2的劇情本事,根本是胡說八道,和電影中的劇情差了十萬八千里。雖然說電影介紹中的本事,和實際劇情有點小落差,是常有的事。但差到這種程度,也真的很少見。

    + +

    鄭伊健演的竊賊,自稱為魔術師。原來是個魔術師啊!難怪可以在何尚生駕駛,行駛中的計程車上,沒開車門,放個煙人就不見了;可以走鋼索跨越兩棟大樓;可以從大樓天台邊緣,外套一蓋就把何尚生銬的手銬解開了,再一往下跳就這樣消失了;也可以讓談判專家陳勁威連猜 372 次人頭都猜輸?簡直是胡說八道!魔術基本上都是造假、有機關的,除了猜硬幣遊戲外,計程車是何尚生開來的,手銬是何尚生銬上的,這兩件事怎麼設機關、造假法,我完全無法想像。真是太沒有說服力了。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 81 | + 82 | + 83 | + 84 | + 85 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0084.html.en.html b/htdocs/imacat/me/diary/0084.html.en.html new file mode 120000 index 0000000..f93a715 --- /dev/null +++ b/htdocs/imacat/me/diary/0084.html.en.html @@ -0,0 +1 @@ +0084.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0084.html.en.xhtml b/htdocs/imacat/me/diary/0084.html.en.xhtml new file mode 100644 index 0000000..ad3b042 --- /dev/null +++ b/htdocs/imacat/me/diary/0084.html.en.xhtml @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 84 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 84

    + +
    + +
    + +
    +
    10.7.’06. 5:17pm.
    + +

    殺破狼—殺氣騰騰的父親節

    + +
    +殺破狼
    +

    殺破狼

    +
    + +
      +
    • 片名:殺破狼
    • +
    • 英文片名: SPL
    • +
    • 發行年份: 2005
    • +
    • 製作公司: 1618 Action Limited
    • +
    • 出品人:陳達志、黃柏高
    • +
    • 導演:葉偉信
    • +
    • 編劇:葉偉信
    • +
    • 演員: +
        +
      • 甄子丹:督察馬軍
      • +
      • 任達華:督察陳國忠
      • +
      • 洪金寶:王寶
      • +
      • 吳京:殺手阿積
      • +
      • 廖啟智:警探華哥(陸冠華)
      • +
      • 夏韶聲:警探阿琛(郭子琛)
      • +
      • 智堯:警探阿樂(李偉樂)
      • +
      • 陳達志:警察寶叔( BA 叔)
      • +
      • 惠天賜:警察主管張傳僖
      • +
      • 洪天明:被打成白癡的毒販
      • +
      • 梁鏡珂:王寶妻子
      • +
      • 施祖男:臥底警探陳偉
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    殺破狼敘述作風剽悍的重案組督察陳國忠,得知自己得了腦瘤不久人世,決心在退休前,不擇手段也要逮捕兇殘狠惡的黑社會老大王寶歸案。接任的督察馬軍交接期間,發覺重案組已逐步失控,甚至欲栽贓嫁禍起訴王寶,陷入兩難。被多次掃蕩的王寶,亦決心狠下殺手。三人之間的博命戰爭,一觸即發。

    + +

    殺破狼還蠻好看的。武打很精彩。電影中有三個有紮實武打根底的演員:洪金寶、甄子丹和王京。武打實力之間的落差非常明顯。

    + +

    洪金寶的演技非常突出。我已經完全沒有洪金寶之前演出嚴肅的角色的印象了。喜劇果然是戲劇之母,喜劇根底紮實的人,眉宇神情變化自然,感染力強烈,演什麼都入木三分。之前無間道 (2002,2003)的曾志偉是如此,殺破狼的洪金寶亦復如此。隨手就可以折斷你的手,像猛虎一般,氣勢懾人;亦可以隨手執起電話,變身成溫柔的爸爸。

    + +

    王京演的殺手阿積,雖然沒有什麼戲份,但非常搶眼。原本就帶著邪氣的王京,反手握短刀,更添一股傲邪之氣。王京原有武打根底,用長拳的打法打短刀,讓人耳目一新。劇中他主要有兩場武打戲,一場是高架橋墩殺阿樂,一場是和馬軍對決。我之前有看過高架橋墩殺阿樂的那一場,非常流暢暢快。不過比起和馬軍對決那一場,還是略遜一籌。一個巴掌拍不響,要武打,還是兩個都同樣有武打根底的人,打起來才好看。

    + +

    甄子丹和王京的最後對決,非常有趣。王京用短刀使長拳,對甄子丹用警棍使短打,長短武器反配短長拳,形成有趣的對比。甄子丹不斷欺近王京,在中距離攻防,讓王京的長拳施展不開。這是專剋少林長拳的詠春黐手,最基本的打法。最後甄子丹對洪金寶,非常精彩,一下子黐手,一下子柔道,一下子摔角,一下子擒拿,讓人目不暇給。摔角柔道那一段,真的讓人印象深刻。第一段的黐手對打後,就進入柔道技:甄子丹衝到洪金寶懷裏,用一個小外刈加體落把洪金寶摔出,洪金寶則以巴投甩開甄子丹,雙方再戰,甄子丹用山嵐洪金寶把摔出,洪金寶用單手背負投,甄子丹也使出單手背負投,再一記小外刈加大腰,然後用縱四方固鎖住洪金寶,一陣亂打,直到洪金寶再以巴投甩開甄子丹。然後就是甄子丹有名的三段飛踢。接下來換摔角技,洪金寶欺近後用肩車加身體撲擊壓制甄子丹,甄子丹使出大蛇絞,洪金寶看掙脫不開,索性立起來迴旋(這裏不知道為什麼,甄子丹的大蛇絞變成剪刀腳),摔出去時變成剪刀脚迴旋,洪金寶失去平衡,兩個人都摔飛出去。這時候電話鈴響,洪金寶接起愛妻電話,甄子丹趁機飛踢偷襲,再用鎖頸固定住洪金寶。講完一段溫馨電話後,洪金寶奮力掙脫鎖頸。接下來一小段擒拿手對打,甄子丹站姿黏上腕挫十字固,洪金寶失去平衡倒下,手被甄子丹折斷。最後一個大山嵐,就把大魔王打死了。場面溫馨感人。 *^_^*

    + +

    唔,仔細把動作分解來看以後,發現不合理的地方還真多哪~最不合理的就是那個大蛇絞變身剪刀腳了,如果王寶沒有被剪刀腳迴旋重創,就不會被偷襲,也就不一定會敗;反過來說,被迴旋重創的馬軍必死。王寶好像無心取勝一樣,一直在見招拆招,任由馬軍一直打。久守必失,無心取勝者,被打死也是活該。真是太奇怪了。

    + +

    我之前看港漫天下時,看到破軍使出一招殺破狼,一直不知道是什麼意思。直到後來看到電影殺破狼的宣傳才知道,殺破狼是指紫微斗數裏的七殺破軍貪狼三顆星。七殺是南斗第六星,古書名將星,化氣為將星破軍是北斗第七星,古書名耗星,化氣為貪狼是北斗第一星,古書名桃花星殺星,化氣為桃花,除桃花外,殺氣也很強。這三顆星都屬凶星,若具有殺破狼格,則是大凶。電影殺破狼似乎以三個人來詮釋三凶交會,可是除了督察馬軍一句(我是)破軍坐命,為兵必劫外,另兩個人(哪兩個人?王寶和督察陳國忠?還是王寶和殺手阿積?還是另有其人?)是什麼命格,完全沒有交待。

    + +

    督察馬軍果然是破軍坐命,為兵必劫。接手重案組,還在交接,還沒正式上任,重案組就已經傷亡殆盡了。

    + +

    殺破狼有一個很強烈的意象:父親節。主線故事圍繞在父親節前夕:妻子流產兩次的王寶,終於要渡過自己第一次的父親節,妻子頻頻打電話催促;陳國忠領養三年前被王寶殺害的證人孤女,腦癌末期日子無多,最惦記的是乾女兒日後無依;重案組警探華哥、阿琛和阿樂偷偷槓走王寶的贓款,想給陳國忠乾女兒日後一個依靠;警探阿琛和妻女離婚多年,女兒長大後終於回來找他,興奮期待跟女兒一起過多年以來的第一個父親節;華哥和父親形同陌路,受阿琛和女兒重逢所感,打個電話回家,才知父親早已過世月餘,悵然若失;馬軍年幼時父親被匪徒所殺,一生立志剷奸除惡。每個人都在過自己的父親節,都有自己的故事和結局。

    + +

    父親節的味道,很柔軟溫馨。可是配上殺破狼從頭到尾殺氣騰騰的氣氛,多少格格不入,不大協調。

    + +

    殺破狼父親節意象非常強烈。有人說是父權意象,但其實不對,應該是父親節殺破狼裏對父權幾乎完全沒有著墨。

    + +

    相對於父親節,片中的女性角色少得可憐。只有三個若有似無的女性角色:王寶的妻子,阿琛多年不見的女兒,和陳國忠領養的乾女兒。

    + +

    任達華的演技原就爐火純青,演來非常自然,沒有話說;喜劇經驗豐富的的洪金寶演的老大嶽峙如虎,氣勢懾人;王京的殺手雖搶眼,但其實沒什麼真正的演出;甄子丹功夫紮實,但演技只能算中等;廖啟智、夏韶聲和智堯三人劇中角色原本就設計得很搶演,三人也演得非常出色。洪金寶之子洪天明演的白癡,讓人印象蠻深的。惠天賜是名演員,廣告宣傳一定會列出他的名字,可是其實戲份很少,也不顯眼。整體來說,好像在看兩組人馬演出:一組是以演技吸引目光者(任達華、洪金寶、廖啟智、夏韶聲和智堯),一組是以武打取勝者(洪金寶、甄子丹、王京),兩組感覺都不大協調,但武打組感覺不協調者更甚。唯一兩者兼具者,只有洪金寶而已。

    + +

    其實,我不同意甄子丹因為長得不夠帥,所以上不了一線的說法。這種說法大多是拿甄子丹和李連杰比,過份簡化問題。長得不夠帥,還可以以演技彌補。黃秋生、吳鎮宇都是如此。甄子丹演技不足是事實。如果努力磨練演技,其實還是大有可為。而且帥不帥,一半是天生,一半是演技的感染力,造就出來的。像吳鎮宇,我原本也覺得他形容猥瑣,但他在O記三合會檔案 (1999)裏,卻又可以化身為一個文質彬彬的警官,令人驚豔。

    + +

    殺破狼有一幕很精彩:王寶正在清水灣山路開車,督察陳國忠從後面追上,就直接撞上去。王寶停下,發狠,往前開一小段,就倒車直接撞回去。督察陳國忠又倒車,再加速撞上去。最後兩個人下車,王寶從後座檢起兩根高爾夫球桿,丟給陳國忠一根,兩個人就這樣在山路上對峙。這裏是接到一開始王寶的殺手阿積故意撞車,殺了陳國忠車上的證人夫婦。陳國忠於是回來復仇,同樣用車撞回去。兩個人在山路上互不相讓,用車撞來撞去。碰撞的張力,十分強烈。

    + +

    殺破狼的出品人陳達志,香港演藝圈人稱BA 叔,在劇中也客串了警察寶叔( BA 叔)一角,就是一開始深夜取締打架被古惑仔包圍時,被陳國忠和馬軍所救的老警察;後來陳國忠栽贓東窗事發,主管張傳僖抓人時,偷偷掩護陳國忠逃走。殺破狼投資的公司 ABBA Movies ,也是陳達志擁有的電影公司,公司的名稱,就是以他自己的外號為名。

    + +

    片尾演員表有一個小小的錯誤:惠天賜演的警察主管張傳僖,英文名字打 Cheung Chun Fei 。中文名字第三個字我怎麼看都是,廣東話發音應該是 Hei 不是 FeiCheung Chun Fei 應該是 Cheung Chun Hei ,演員表英文打錯了。這個筆誤,傳到了 IMDB ,還是延用下去,有點好笑。不過張傳僖這個名字,整部戲從頭到尾,也壓根沒出現過。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 82 | + 83 | + 84 | + 85 | + 86 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0084.html.zh-cn.html b/htdocs/imacat/me/diary/0084.html.zh-cn.html new file mode 120000 index 0000000..7a8ee90 --- /dev/null +++ b/htdocs/imacat/me/diary/0084.html.zh-cn.html @@ -0,0 +1 @@ +0084.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0084.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0084.html.zh-cn.xhtml new file mode 100644 index 0000000..1f2249b --- /dev/null +++ b/htdocs/imacat/me/diary/0084.html.zh-cn.xhtml @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷八十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷八十四

    + +
    + +
    + +
    +
    10.7.’06. 5:17pm.
    + +

    杀破狼—杀气腾腾的父亲节

    + +
    +杀破狼
    +

    杀破狼

    +
    + +
      +
    • 片名:杀破狼
    • +
    • 英文片名: SPL
    • +
    • 发行年份: 2005
    • +
    • 制作公司: 1618 Action Limited
    • +
    • 出品人:陈达志、黄柏高
    • +
    • 导演:叶伟信
    • +
    • 编剧:叶伟信
    • +
    • 演员: +
        +
      • 甄子丹:督察马军
      • +
      • 任达华:督察陈国忠
      • +
      • 洪金宝:王宝
      • +
      • 吴京:杀手阿积
      • +
      • 廖启智:警探华哥(陆冠华)
      • +
      • 夏韶声:警探阿琛(郭子琛)
      • +
      • 智尧:警探阿乐(李伟乐)
      • +
      • 陈达志:警察宝叔( BA 叔)
      • +
      • 惠天赐:警察主管张传僖
      • +
      • 洪天明:被打成白痴的毒贩
      • +
      • 梁镜珂:王宝妻子
      • +
      • 施祖男:卧底警探陈伟
      • +
      +
    • +
    • 推荐影评: + +
    • +
    + +

    杀破狼叙述作风剽悍的重案组督察陈国忠,得知自己得了脑瘤不久人世,决心在退休前,不择手段也要逮捕凶残狠恶的黑社会老大王宝归案。接任的督察马军交接期间,发觉重案组已逐步失控,甚至欲栽赃嫁祸起诉王宝,陷入两难。被多次扫荡的王宝,亦决心狠下杀手。三人之间的博命战争,一触即发。

    + +

    杀破狼还蛮好看的。武打很精彩。电影中有三个有扎实武打根底的演员:洪金宝、甄子丹和王京。武打实力之间的落差非常明显。

    + +

    洪金宝的演技非常突出。我已经完全没有洪金宝之前演出严肃的角色的印象了。喜剧果然是戏剧之母,喜剧根底扎实的人,眉宇神情变化自然,感染力强烈,演什么都入木三分。之前无间道 (2002,2003)的曾志伟是如此,杀破狼的洪金宝亦复如此。随手就可以折断你的手,像猛虎一般,气势慑人;亦可以随手执起电话,变身成温柔的爸爸。

    + +

    王京演的杀手阿积,虽然没有什么戏份,但非常抢眼。原本就带著邪气的王京,反手握短刀,更添一股傲邪之气。王京原有武打根底,用长拳的打法打短刀,让人耳目一新。剧中他主要有两场武打戏,一场是高架桥墩杀阿乐,一场是和马军对决。我之前有看过高架桥墩杀阿乐的那一场,非常流畅畅快。不过比起和马军对决那一场,还是略逊一筹。一个巴掌拍不响,要武打,还是两个都同样有武打根底的人,打起来才好看。

    + +

    甄子丹和王京的最后对决,非常有趣。王京用短刀使长拳,对甄子丹用警棍使短打,长短武器反配短长拳,形成有趣的对比。甄子丹不断欺近王京,在中距离攻防,让王京的长拳施展不开。这是专克少林长拳的咏春黐手,最基本的打法。最后甄子丹对洪金宝,非常精彩,一下子黐手,一下子柔道,一下子摔角,一下子擒拿,让人目不暇给。摔角柔道那一段,真的让人印象深刻。第一段的黐手对打后,就进入柔道技:甄子丹冲到洪金宝怀里,用一个小外刈加体落把洪金宝摔出,洪金宝则以巴投甩开甄子丹,双方再战,甄子丹用山岚洪金宝把摔出,洪金宝用单手背负投,甄子丹也使出单手背负投,再一记小外刈加大腰,然后用纵四方固锁住洪金宝,一阵乱打,直到洪金宝再以巴投甩开甄子丹。然后就是甄子丹有名的三段飞踢。接下来换摔角技,洪金宝欺近后用肩车加身体扑击压制甄子丹,甄子丹使出大蛇绞,洪金宝看挣脱不开,索性立起来回旋(这里不知道为什么,甄子丹的大蛇绞变成剪刀脚),摔出去时变成剪刀脚回旋,洪金宝失去平衡,两个人都摔飞出去。这时候电话铃响,洪金宝接起爱妻电话,甄子丹趁机飞踢偷袭,再用锁颈固定住洪金宝。讲完一段温馨电话后,洪金宝奋力挣脱锁颈。接下来一小段擒拿手对打,甄子丹站姿黏上腕挫十字固,洪金宝失去平衡倒下,手被甄子丹折断。最后一个大山岚,就把大魔王打死了。场面温馨感人。 *^_^*

    + +

    唔,仔细把动作分解来看以后,发现不合理的地方还真多哪~最不合理的就是那个大蛇绞变身剪刀脚了,如果王宝没有被剪刀脚回旋重创,就不会被偷袭,也就不一定会败;反过来说,被回旋重创的马军必死。王宝好像无心取胜一样,一直在见招拆招,任由马军一直打。久守必失,无心取胜者,被打死也是活该。真是太奇怪了。

    + +

    我之前看港漫天下时,看到破军使出一招杀破狼,一直不知道是什么意思。直到后来看到电影杀破狼的宣传才知道,杀破狼是指紫微斗数里的七杀破军贪狼三颗星。七杀是南斗第六星,古书名将星,化气为将星破军是北斗第七星,古书名耗星,化气为贪狼是北斗第一星,古书名桃花星杀星,化气为桃花,除桃花外,杀气也很强。这三颗星都属凶星,若具有杀破狼格,则是大凶。电影杀破狼似乎以三个人来诠释三凶交会,可是除了督察马军一句(我是)破军坐命,为兵必劫外,另两个人(哪两个人?王宝和督察陈国忠?还是王宝和杀手阿积?还是另有其人?)是什么命格,完全没有交待。

    + +

    督察马军果然是破军坐命,为兵必劫。接手重案组,还在交接,还没正式上任,重案组就已经伤亡殆尽了。

    + +

    杀破狼有一个很强烈的意象:父亲节。主线故事围绕在父亲节前夕:妻子流产两次的王宝,终於要渡过自己第一次的父亲节,妻子频频打电话催促;陈国忠领养三年前被王宝杀害的证人孤女,脑癌末期日子无多,最惦记的是干女儿日后无依;重案组警探华哥、阿琛和阿乐偷偷杠走王宝的赃款,想给陈国忠干女儿日后一个依靠;警探阿琛和妻女离婚多年,女儿长大后终於回来找他,兴奋期待跟女儿一起过多年以来的第一个父亲节;华哥和父亲形同陌路,受阿琛和女儿重逢所感,打个电话回家,才知父亲早已过世月余,怅然若失;马军年幼时父亲被匪徒所杀,一生立志铲奸除恶。每个人都在过自己的父亲节,都有自己的故事和结局。

    + +

    父亲节的味道,很柔软温馨。可是配上杀破狼从头到尾杀气腾腾的气氛,多少格格不入,不大协调。

    + +

    杀破狼父亲节意象非常强烈。有人说是父权意象,但其实不对,应该是父亲节杀破狼里对父权几乎完全没有著墨。

    + +

    相对於父亲节,片中的女性角色少得可怜。只有三个若有似无的女性角色:王宝的妻子,阿琛多年不见的女儿,和陈国忠领养的干女儿。

    + +

    任达华的演技原就炉火纯青,演来非常自然,没有话说;喜剧经验丰富的的洪金宝演的老大岳峙如虎,气势慑人;王京的杀手虽抢眼,但其实没什么真正的演出;甄子丹功夫扎实,但演技只能算中等;廖启智、夏韶声和智尧三人剧中角色原本就设计得很抢演,三人也演得非常出色。洪金宝之子洪天明演的白痴,让人印象蛮深的。惠天赐是名演员,广告宣传一定会列出他的名字,可是其实戏份很少,也不显眼。整体来说,好像在看两组人马演出:一组是以演技吸引目光者(任达华、洪金宝、廖启智、夏韶声和智尧),一组是以武打取胜者(洪金宝、甄子丹、王京),两组感觉都不大协调,但武打组感觉不协调者更甚。唯一两者兼具者,只有洪金宝而已。

    + +

    其实,我不同意甄子丹因为长得不够帅,所以上不了一线的说法。这种说法大多是拿甄子丹和李连杰比,过份简化问题。长得不够帅,还可以以演技弥补。黄秋生、吴镇宇都是如此。甄子丹演技不足是事实。如果努力磨练演技,其实还是大有可为。而且帅不帅,一半是天生,一半是演技的感染力,造就出来的。像吴镇宇,我原本也觉得他形容猥琐,但他在O记三合会档案 (1999)里,却又可以化身为一个文质彬彬的警官,令人惊艳。

    + +

    杀破狼有一幕很精彩:王宝正在清水湾山路开车,督察陈国忠从后面追上,就直接撞上去。王宝停下,发狠,往前开一小段,就倒车直接撞回去。督察陈国忠又倒车,再加速撞上去。最后两个人下车,王宝从后座检起两根高尔夫球杆,丢给陈国忠一根,两个人就这样在山路上对峙。这里是接到一开始王宝的杀手阿积故意撞车,杀了陈国忠车上的证人夫妇。陈国忠於是回来复仇,同样用车撞回去。两个人在山路上互不相让,用车撞来撞去。碰撞的张力,十分强烈。

    + +

    杀破狼的出品人陈达志,香港演艺圈人称BA 叔,在剧中也客串了警察宝叔( BA 叔)一角,就是一开始深夜取缔打架被古惑仔包围时,被陈国忠和马军所救的老警察;后来陈国忠栽赃东窗事发,主管张传僖抓人时,偷偷掩护陈国忠逃走。杀破狼投资的公司 ABBA Movies ,也是陈达志拥有的电影公司,公司的名称,就是以他自己的外号为名。

    + +

    片尾演员表有一个小小的错误:惠天赐演的警察主管张传僖,英文名字打 Cheung Chun Fei 。中文名字第三个字我怎么看都是,广东话发音应该是 Hei 不是 FeiCheung Chun Fei 应该是 Cheung Chun Hei ,演员表英文打错了。这个笔误,传到了 IMDB ,还是延用下去,有点好笑。不过张传僖这个名字,整部戏从头到尾,也压根没出现过。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 82 | + 83 | + 84 | + 85 | + 86 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0084.html.zh-tw.html b/htdocs/imacat/me/diary/0084.html.zh-tw.html new file mode 120000 index 0000000..0507ea0 --- /dev/null +++ b/htdocs/imacat/me/diary/0084.html.zh-tw.html @@ -0,0 +1 @@ +0084.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0084.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0084.html.zh-tw.xhtml new file mode 100644 index 0000000..0a79905 --- /dev/null +++ b/htdocs/imacat/me/diary/0084.html.zh-tw.xhtml @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷八十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷八十四

    + +
    + +
    + +
    +
    10.7.’06. 5:17pm.
    + +

    殺破狼—殺氣騰騰的父親節

    + +
    +殺破狼
    +

    殺破狼

    +
    + +
      +
    • 片名:殺破狼
    • +
    • 英文片名: SPL
    • +
    • 發行年份: 2005
    • +
    • 製作公司: 1618 Action Limited
    • +
    • 出品人:陳達志、黃柏高
    • +
    • 導演:葉偉信
    • +
    • 編劇:葉偉信
    • +
    • 演員: +
        +
      • 甄子丹:督察馬軍
      • +
      • 任達華:督察陳國忠
      • +
      • 洪金寶:王寶
      • +
      • 吳京:殺手阿積
      • +
      • 廖啟智:警探華哥(陸冠華)
      • +
      • 夏韶聲:警探阿琛(郭子琛)
      • +
      • 智堯:警探阿樂(李偉樂)
      • +
      • 陳達志:警察寶叔( BA 叔)
      • +
      • 惠天賜:警察主管張傳僖
      • +
      • 洪天明:被打成白癡的毒販
      • +
      • 梁鏡珂:王寶妻子
      • +
      • 施祖男:臥底警探陳偉
      • +
      +
    • +
    • 推薦影評: + +
    • +
    + +

    殺破狼敘述作風剽悍的重案組督察陳國忠,得知自己得了腦瘤不久人世,決心在退休前,不擇手段也要逮捕兇殘狠惡的黑社會老大王寶歸案。接任的督察馬軍交接期間,發覺重案組已逐步失控,甚至欲栽贓嫁禍起訴王寶,陷入兩難。被多次掃蕩的王寶,亦決心狠下殺手。三人之間的博命戰爭,一觸即發。

    + +

    殺破狼還蠻好看的。武打很精彩。電影中有三個有紮實武打根底的演員:洪金寶、甄子丹和王京。武打實力之間的落差非常明顯。

    + +

    洪金寶的演技非常突出。我已經完全沒有洪金寶之前演出嚴肅的角色的印象了。喜劇果然是戲劇之母,喜劇根底紮實的人,眉宇神情變化自然,感染力強烈,演什麼都入木三分。之前無間道 (2002,2003)的曾志偉是如此,殺破狼的洪金寶亦復如此。隨手就可以折斷你的手,像猛虎一般,氣勢懾人;亦可以隨手執起電話,變身成溫柔的爸爸。

    + +

    王京演的殺手阿積,雖然沒有什麼戲份,但非常搶眼。原本就帶著邪氣的王京,反手握短刀,更添一股傲邪之氣。王京原有武打根底,用長拳的打法打短刀,讓人耳目一新。劇中他主要有兩場武打戲,一場是高架橋墩殺阿樂,一場是和馬軍對決。我之前有看過高架橋墩殺阿樂的那一場,非常流暢暢快。不過比起和馬軍對決那一場,還是略遜一籌。一個巴掌拍不響,要武打,還是兩個都同樣有武打根底的人,打起來才好看。

    + +

    甄子丹和王京的最後對決,非常有趣。王京用短刀使長拳,對甄子丹用警棍使短打,長短武器反配短長拳,形成有趣的對比。甄子丹不斷欺近王京,在中距離攻防,讓王京的長拳施展不開。這是專剋少林長拳的詠春黐手,最基本的打法。最後甄子丹對洪金寶,非常精彩,一下子黐手,一下子柔道,一下子摔角,一下子擒拿,讓人目不暇給。摔角柔道那一段,真的讓人印象深刻。第一段的黐手對打後,就進入柔道技:甄子丹衝到洪金寶懷裏,用一個小外刈加體落把洪金寶摔出,洪金寶則以巴投甩開甄子丹,雙方再戰,甄子丹用山嵐洪金寶把摔出,洪金寶用單手背負投,甄子丹也使出單手背負投,再一記小外刈加大腰,然後用縱四方固鎖住洪金寶,一陣亂打,直到洪金寶再以巴投甩開甄子丹。然後就是甄子丹有名的三段飛踢。接下來換摔角技,洪金寶欺近後用肩車加身體撲擊壓制甄子丹,甄子丹使出大蛇絞,洪金寶看掙脫不開,索性立起來迴旋(這裏不知道為什麼,甄子丹的大蛇絞變成剪刀腳),摔出去時變成剪刀脚迴旋,洪金寶失去平衡,兩個人都摔飛出去。這時候電話鈴響,洪金寶接起愛妻電話,甄子丹趁機飛踢偷襲,再用鎖頸固定住洪金寶。講完一段溫馨電話後,洪金寶奮力掙脫鎖頸。接下來一小段擒拿手對打,甄子丹站姿黏上腕挫十字固,洪金寶失去平衡倒下,手被甄子丹折斷。最後一個大山嵐,就把大魔王打死了。場面溫馨感人。 *^_^*

    + +

    唔,仔細把動作分解來看以後,發現不合理的地方還真多哪~最不合理的就是那個大蛇絞變身剪刀腳了,如果王寶沒有被剪刀腳迴旋重創,就不會被偷襲,也就不一定會敗;反過來說,被迴旋重創的馬軍必死。王寶好像無心取勝一樣,一直在見招拆招,任由馬軍一直打。久守必失,無心取勝者,被打死也是活該。真是太奇怪了。

    + +

    我之前看港漫天下時,看到破軍使出一招殺破狼,一直不知道是什麼意思。直到後來看到電影殺破狼的宣傳才知道,殺破狼是指紫微斗數裏的七殺破軍貪狼三顆星。七殺是南斗第六星,古書名將星,化氣為將星破軍是北斗第七星,古書名耗星,化氣為貪狼是北斗第一星,古書名桃花星殺星,化氣為桃花,除桃花外,殺氣也很強。這三顆星都屬凶星,若具有殺破狼格,則是大凶。電影殺破狼似乎以三個人來詮釋三凶交會,可是除了督察馬軍一句(我是)破軍坐命,為兵必劫外,另兩個人(哪兩個人?王寶和督察陳國忠?還是王寶和殺手阿積?還是另有其人?)是什麼命格,完全沒有交待。

    + +

    督察馬軍果然是破軍坐命,為兵必劫。接手重案組,還在交接,還沒正式上任,重案組就已經傷亡殆盡了。

    + +

    殺破狼有一個很強烈的意象:父親節。主線故事圍繞在父親節前夕:妻子流產兩次的王寶,終於要渡過自己第一次的父親節,妻子頻頻打電話催促;陳國忠領養三年前被王寶殺害的證人孤女,腦癌末期日子無多,最惦記的是乾女兒日後無依;重案組警探華哥、阿琛和阿樂偷偷槓走王寶的贓款,想給陳國忠乾女兒日後一個依靠;警探阿琛和妻女離婚多年,女兒長大後終於回來找他,興奮期待跟女兒一起過多年以來的第一個父親節;華哥和父親形同陌路,受阿琛和女兒重逢所感,打個電話回家,才知父親早已過世月餘,悵然若失;馬軍年幼時父親被匪徒所殺,一生立志剷奸除惡。每個人都在過自己的父親節,都有自己的故事和結局。

    + +

    父親節的味道,很柔軟溫馨。可是配上殺破狼從頭到尾殺氣騰騰的氣氛,多少格格不入,不大協調。

    + +

    殺破狼父親節意象非常強烈。有人說是父權意象,但其實不對,應該是父親節殺破狼裏對父權幾乎完全沒有著墨。

    + +

    相對於父親節,片中的女性角色少得可憐。只有三個若有似無的女性角色:王寶的妻子,阿琛多年不見的女兒,和陳國忠領養的乾女兒。

    + +

    任達華的演技原就爐火純青,演來非常自然,沒有話說;喜劇經驗豐富的的洪金寶演的老大嶽峙如虎,氣勢懾人;王京的殺手雖搶眼,但其實沒什麼真正的演出;甄子丹功夫紮實,但演技只能算中等;廖啟智、夏韶聲和智堯三人劇中角色原本就設計得很搶演,三人也演得非常出色。洪金寶之子洪天明演的白癡,讓人印象蠻深的。惠天賜是名演員,廣告宣傳一定會列出他的名字,可是其實戲份很少,也不顯眼。整體來說,好像在看兩組人馬演出:一組是以演技吸引目光者(任達華、洪金寶、廖啟智、夏韶聲和智堯),一組是以武打取勝者(洪金寶、甄子丹、王京),兩組感覺都不大協調,但武打組感覺不協調者更甚。唯一兩者兼具者,只有洪金寶而已。

    + +

    其實,我不同意甄子丹因為長得不夠帥,所以上不了一線的說法。這種說法大多是拿甄子丹和李連杰比,過份簡化問題。長得不夠帥,還可以以演技彌補。黃秋生、吳鎮宇都是如此。甄子丹演技不足是事實。如果努力磨練演技,其實還是大有可為。而且帥不帥,一半是天生,一半是演技的感染力,造就出來的。像吳鎮宇,我原本也覺得他形容猥瑣,但他在O記三合會檔案 (1999)裏,卻又可以化身為一個文質彬彬的警官,令人驚豔。

    + +

    殺破狼有一幕很精彩:王寶正在清水灣山路開車,督察陳國忠從後面追上,就直接撞上去。王寶停下,發狠,往前開一小段,就倒車直接撞回去。督察陳國忠又倒車,再加速撞上去。最後兩個人下車,王寶從後座檢起兩根高爾夫球桿,丟給陳國忠一根,兩個人就這樣在山路上對峙。這裏是接到一開始王寶的殺手阿積故意撞車,殺了陳國忠車上的證人夫婦。陳國忠於是回來復仇,同樣用車撞回去。兩個人在山路上互不相讓,用車撞來撞去。碰撞的張力,十分強烈。

    + +

    殺破狼的出品人陳達志,香港演藝圈人稱BA 叔,在劇中也客串了警察寶叔( BA 叔)一角,就是一開始深夜取締打架被古惑仔包圍時,被陳國忠和馬軍所救的老警察;後來陳國忠栽贓東窗事發,主管張傳僖抓人時,偷偷掩護陳國忠逃走。殺破狼投資的公司 ABBA Movies ,也是陳達志擁有的電影公司,公司的名稱,就是以他自己的外號為名。

    + +

    片尾演員表有一個小小的錯誤:惠天賜演的警察主管張傳僖,英文名字打 Cheung Chun Fei 。中文名字第三個字我怎麼看都是,廣東話發音應該是 Hei 不是 FeiCheung Chun Fei 應該是 Cheung Chun Hei ,演員表英文打錯了。這個筆誤,傳到了 IMDB ,還是延用下去,有點好笑。不過張傳僖這個名字,整部戲從頭到尾,也壓根沒出現過。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 82 | + 83 | + 84 | + 85 | + 86 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0085.html.en.html b/htdocs/imacat/me/diary/0085.html.en.html new file mode 120000 index 0000000..cad7271 --- /dev/null +++ b/htdocs/imacat/me/diary/0085.html.en.html @@ -0,0 +1 @@ +0085.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0085.html.en.xhtml b/htdocs/imacat/me/diary/0085.html.en.xhtml new file mode 100644 index 0000000..3f1705e --- /dev/null +++ b/htdocs/imacat/me/diary/0085.html.en.xhtml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 85 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 85

    + +
    + +
    + +
    +
    10.13.’06. 2:33am.
    + +

    藤田和日郎瞬撃の虚空

    + +

    藤田和日郎瞬撃の虚空,收錄在短篇集暁の歌裏。

    + +

    うしおととら(魔力小馬)起,我就迷上了藤田和日郎。在略顯雜亂的扭曲肢體中,有暗不見底的扭曲心靈,也有讓人感動的人情趣味。暁の歌藤田和日郎的短篇集,收錄了一些早期的短篇。其中一篇讓我感動很久,無法自已的,就是瞬撃の虚空

    + +

    瞬撃の虚空描寫一個三代同堂的平凡家庭,少年是典型的戰後新生代,面對衣食無虞的生活,瞧不起退休後整天看電視的癡呆爺爺和平凡的父母,又沒有能力改變環境,苦悶無處宣洩。爺爺看著苦悶的少年,想幫忙卻有心無力。直到有一天,美國三角洲特種部隊軍官,突然造訪這個平凡的三代同堂家庭,請爺爺協助解決一件嚴重的破壞案。爺爺堅持要帶少年同行。莫名其妙的少年才逐漸發現,深藏不露的爺爺二戰時因武藝高強,被稱為瞬撃,戰後曾被美軍聘用,以研究人體能力的極限。而破壞案的主犯,就是當年研究瞬撃的成員。少年面對衝擊性的事實,從不相信,覺得好酷,看著爺爺拼著一把老骨頭戰鬥,開始思考勇氣的真義。事件解決後,一家人回復平靜的平凡生活。看著每天看電視,逐漸癡呆的爺爺,少年的心,已經成長了。

    + +

    這是一篇讓我感動很久的故事,最讓我感動的一句話是:真正的勇氣,是和平凡的每一天戰鬥。

    + +

    真正的勇氣是什麼?短短的故事裏,沒有答案,只有一個又一個的問號:是為了解救全人類挺身而出?是為了保護重視的家人挺身而出?是在戰後物資缺乏中,身為武道家,卻向敵軍低頭出賣自己的武藝,以求家人溫飽?是少年為了救爺爺衝出去,平凡人挺身去做自己做不到的事?還是當一個平凡人,和平凡的每一天戰鬥?

    + +
    + +
    + +
    +
    10.8.’06. 11:32pm.
    + +

    摔角圖書館

    + +

    今天為了要弄清楚殺破狼裏使用的摔角招式,循線找到一個摔角圖書館的網站,讀了好多日本職業摔角界分分合合的八掛,日本 PRO 、新日本、全日本、 UWF 、 PANCRASE 、 NOAH 、 鬥魂三槍士等等。

    + +

    放長假沒什麼時間壓力,看這些閒東西,蠻好玩的。

    + +
    + +
    + +
    +
    10.8.’06. 8:16am.
    + +

    可爾必思沙瓦

    + +

    剛剛回家的路上,又去 7-11 買了一瓶可爾必思沙瓦カルピスサワー Calpis Sour (檸檬 & 柳橙風味)。我想我真的是沒救了。愛上可爾必思的味道,無法自拔。

    + +

    可爾必思沙瓦,大概是我現在唯一能喝的酒精飲料吧~

    + +

    我真的醉了,開始胡言亂語了。

    + +
    + +
    + +
    +
    10.8.’06. 8:08am.
    + +

    咖啡店的第一個客人

    + +

    凌晨三四點,整理完這個學期修的課的期考考古題,仗著自己有公司的鑰匙,趁著連假半夜公司沒人,車子騎著就殺去公司,借公司雷射印表機印考古題,也順便趁公司沒人,調整幾個伺服器的小問題:檢查主機板、光碟機廠牌型號,換上好的光碟機, lilo 換成 grub 等等。

    + +

    弄了半天,結束已經是早上七點半,天大亮了。雖然昨天睡了一天,可是工作了一晚,頭腦也開始昏昏沉沉,眼皮開始重了。心裏想著去咖啡店吃個早餐,提提神好騎車,就準備回家了。

    + +

    走進怡客咖啡,點了巧克力厚片吐司,加水蜜桃可爾必思,都是我最喜歡的甜味。拿到號碼牌: 1 號,再定神一看:店裏還沒有半個人。想起現在是連假星期天一大早,問了問店員:

    + +
    +

    我是第一個客人嗎?

    + +

    嗯,對呀!

    +
    + +

    呵,我天天跑咖啡店買早餐,可是還沒有當過咖啡店的第一個客人。怡客好像是七點開門的吧,到現在半個多小時,整個店面都是空蕩蕩的。空蕩蕩的咖啡店,現在是我一個人獨佔的~耶~

    + +

    邊想,邊喝了一大口水蜜桃可爾必思。真是奇異的感覺~

    + +
    + +
    + +
    +
    10.8.’06. 2:38am.
    + +

    寺沢大介ミスター味っ子(妙手小廚師)料理真實重現

    + +

    今天傍晚去看寺沢大介的漫畫喰いタン(美食偵探王)的時候,在封面扉頁,寺沢大介提到有個漫畫迷,把ミスター味っ子(妙手小廚師)裏的料理真實重現,並放到網站上。

    + +

    看到這麼好玩的事,我趕緊抄下網址,回家連上去看:哇~真的耶~而且每一樣看起來都好~好吃喔~口水都流到地上了~

    + +

    寺沢大介開玩笑說,不知道這個讀者會不會把喰いタン(美食偵探王)的料理也都原味重現呢?嗯嗯,這麼一說,我也好期待~不過喰いタン(美食偵探王)主角的食量是常人的好幾百倍,要真實重現的話,成本大概很高吧~

    + +

    真的是太酷了~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 83 | + 84 | + 85 | + 86 | + 87 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0085.html.zh-cn.html b/htdocs/imacat/me/diary/0085.html.zh-cn.html new file mode 120000 index 0000000..8d503b8 --- /dev/null +++ b/htdocs/imacat/me/diary/0085.html.zh-cn.html @@ -0,0 +1 @@ +0085.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0085.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0085.html.zh-cn.xhtml new file mode 100644 index 0000000..281d0c4 --- /dev/null +++ b/htdocs/imacat/me/diary/0085.html.zh-cn.xhtml @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷八十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷八十五

    + +
    + +
    + +
    +
    10.13.’06. 2:33am.
    + +

    藤田和日郎瞬撃の虚空

    + +

    藤田和日郎瞬撃の虚空,收录在短篇集暁の歌里。

    + +

    うしおととら(魔力小马)起,我就迷上了藤田和日郎。在略显杂乱的扭曲肢体中,有暗不见底的扭曲心灵,也有让人感动的人情趣味。暁の歌藤田和日郎的短篇集,收录了一些早期的短篇。其中一篇让我感动很久,无法自已的,就是瞬撃の虚空

    + +

    瞬撃の虚空描写一个三代同堂的平凡家庭,少年是典型的战后新生代,面对衣食无虞的生活,瞧不起退休后整天看电视的痴呆爷爷和平凡的父母,又没有能力改变环境,苦闷无处宣泄。爷爷看著苦闷的少年,想帮忙却有心无力。直到有一天,美国三角洲特种部队军官,突然造访这个平凡的三代同堂家庭,请爷爷协助解决一件严重的破坏案。爷爷坚持要带少年同行。莫名其妙的少年才逐渐发现,深藏不露的爷爷二战时因武艺高强,被称为瞬撃,战后曾被美军聘用,以研究人体能力的极限。而破坏案的主犯,就是当年研究瞬撃的成员。少年面对冲击性的事实,从不相信,觉得好酷,看著爷爷拼著一把老骨头战斗,开始思考勇气的真义。事件解决后,一家人回复平静的平凡生活。看著每天看电视,逐渐痴呆的爷爷,少年的心,已经成长了。

    + +

    这是一篇让我感动很久的故事,最让我感动的一句话是:真正的勇气,是和平凡的每一天战斗。

    + +

    真正的勇气是什么?短短的故事里,没有答案,只有一个又一个的问号:是为了解救全人类挺身而出?是为了保护重视的家人挺身而出?是在战后物资缺乏中,身为武道家,却向敌军低头出卖自己的武艺,以求家人温饱?是少年为了救爷爷冲出去,平凡人挺身去做自己做不到的事?还是当一个平凡人,和平凡的每一天战斗?

    + +
    + +
    + +
    +
    10.8.’06. 11:32pm.
    + +

    摔角图书馆

    + +

    今天为了要弄清楚杀破狼里使用的摔角招式,循线找到一个摔角图书馆的网站,读了好多日本职业摔角界分分合合的八挂,日本 PRO 、新日本、全日本、 UWF 、 PANCRASE 、 NOAH 、 斗魂三枪士等等。

    + +

    放长假没什么时间压力,看这些闲东西,蛮好玩的。

    + +
    + +
    + +
    +
    10.8.’06. 8:16am.
    + +

    可尔必思沙瓦

    + +

    刚刚回家的路上,又去 7-11 买了一瓶可尔必思沙瓦カルピスサワー Calpis Sour (柠檬 & 柳橙风味)。我想我真的是没救了。爱上可尔必思的味道,无法自拔。

    + +

    可尔必思沙瓦,大概是我现在唯一能喝的酒精饮料吧~

    + +

    我真的醉了,开始胡言乱语了。

    + +
    + +
    + +
    +
    10.8.’06. 8:08am.
    + +

    咖啡店的第一个客人

    + +

    凌晨三四点,整理完这个学期修的课的期考考古题,仗著自己有公司的钥匙,趁著连假半夜公司没人,车子骑著就杀去公司,借公司雷射印表机印考古题,也顺便趁公司没人,调整几个伺服器的小问题:检查主机板、光碟机厂牌型号,换上好的光碟机, lilo 换成 grub 等等。

    + +

    弄了半天,结束已经是早上七点半,天大亮了。虽然昨天睡了一天,可是工作了一晚,头脑也开始昏昏沉沉,眼皮开始重了。心里想著去咖啡店吃个早餐,提提神好骑车,就准备回家了。

    + +

    走进怡客咖啡,点了巧克力厚片吐司,加水蜜桃可尔必思,都是我最喜欢的甜味。拿到号码牌: 1 号,再定神一看:店里还没有半个人。想起现在是连假星期天一大早,问了问店员:

    + +
    +

    我是第一个客人吗?

    + +

    嗯,对呀!

    +
    + +

    呵,我天天跑咖啡店买早餐,可是还没有当过咖啡店的第一个客人。怡客好像是七点开门的吧,到现在半个多小时,整个店面都是空荡荡的。空荡荡的咖啡店,现在是我一个人独占的~耶~

    + +

    边想,边喝了一大口水蜜桃可尔必思。真是奇异的感觉~

    + +
    + +
    + +
    +
    10.8.’06. 2:38am.
    + +

    寺沢大介ミスター味っ子(妙手小厨师)料理真实重现

    + +

    今天傍晚去看寺沢大介的漫画喰いタン(美食侦探王)的时候,在封面扉页,寺沢大介提到有个漫画迷,把ミスター味っ子(妙手小厨师)里的料理真实重现,并放到网站上。

    + +

    看到这么好玩的事,我赶紧抄下网址,回家连上去看:哇~真的耶~而且每一样看起来都好~好吃喔~口水都流到地上了~

    + +

    寺沢大介开玩笑说,不知道这个读者会不会把喰いタン(美食侦探王)的料理也都原味重现呢?嗯嗯,这么一说,我也好期待~不过喰いタン(美食侦探王)主角的食量是常人的好几百倍,要真实重现的话,成本大概很高吧~

    + +

    真的是太酷了~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 83 | + 84 | + 85 | + 86 | + 87 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0085.html.zh-tw.html b/htdocs/imacat/me/diary/0085.html.zh-tw.html new file mode 120000 index 0000000..8175db5 --- /dev/null +++ b/htdocs/imacat/me/diary/0085.html.zh-tw.html @@ -0,0 +1 @@ +0085.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0085.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0085.html.zh-tw.xhtml new file mode 100644 index 0000000..ffcdeb7 --- /dev/null +++ b/htdocs/imacat/me/diary/0085.html.zh-tw.xhtml @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷八十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷八十五

    + +
    + +
    + +
    +
    10.13.’06. 2:33am.
    + +

    藤田和日郎瞬撃の虚空

    + +

    藤田和日郎瞬撃の虚空,收錄在短篇集暁の歌裏。

    + +

    うしおととら(魔力小馬)起,我就迷上了藤田和日郎。在略顯雜亂的扭曲肢體中,有暗不見底的扭曲心靈,也有讓人感動的人情趣味。暁の歌藤田和日郎的短篇集,收錄了一些早期的短篇。其中一篇讓我感動很久,無法自已的,就是瞬撃の虚空

    + +

    瞬撃の虚空描寫一個三代同堂的平凡家庭,少年是典型的戰後新生代,面對衣食無虞的生活,瞧不起退休後整天看電視的癡呆爺爺和平凡的父母,又沒有能力改變環境,苦悶無處宣洩。爺爺看著苦悶的少年,想幫忙卻有心無力。直到有一天,美國三角洲特種部隊軍官,突然造訪這個平凡的三代同堂家庭,請爺爺協助解決一件嚴重的破壞案。爺爺堅持要帶少年同行。莫名其妙的少年才逐漸發現,深藏不露的爺爺二戰時因武藝高強,被稱為瞬撃,戰後曾被美軍聘用,以研究人體能力的極限。而破壞案的主犯,就是當年研究瞬撃的成員。少年面對衝擊性的事實,從不相信,覺得好酷,看著爺爺拼著一把老骨頭戰鬥,開始思考勇氣的真義。事件解決後,一家人回復平靜的平凡生活。看著每天看電視,逐漸癡呆的爺爺,少年的心,已經成長了。

    + +

    這是一篇讓我感動很久的故事,最讓我感動的一句話是:真正的勇氣,是和平凡的每一天戰鬥。

    + +

    真正的勇氣是什麼?短短的故事裏,沒有答案,只有一個又一個的問號:是為了解救全人類挺身而出?是為了保護重視的家人挺身而出?是在戰後物資缺乏中,身為武道家,卻向敵軍低頭出賣自己的武藝,以求家人溫飽?是少年為了救爺爺衝出去,平凡人挺身去做自己做不到的事?還是當一個平凡人,和平凡的每一天戰鬥?

    + +
    + +
    + +
    +
    10.8.’06. 11:32pm.
    + +

    摔角圖書館

    + +

    今天為了要弄清楚殺破狼裏使用的摔角招式,循線找到一個摔角圖書館的網站,讀了好多日本職業摔角界分分合合的八掛,日本 PRO 、新日本、全日本、 UWF 、 PANCRASE 、 NOAH 、 鬥魂三槍士等等。

    + +

    放長假沒什麼時間壓力,看這些閒東西,蠻好玩的。

    + +
    + +
    + +
    +
    10.8.’06. 8:16am.
    + +

    可爾必思沙瓦

    + +

    剛剛回家的路上,又去 7-11 買了一瓶可爾必思沙瓦カルピスサワー Calpis Sour (檸檬 & 柳橙風味)。我想我真的是沒救了。愛上可爾必思的味道,無法自拔。

    + +

    可爾必思沙瓦,大概是我現在唯一能喝的酒精飲料吧~

    + +

    我真的醉了,開始胡言亂語了。

    + +
    + +
    + +
    +
    10.8.’06. 8:08am.
    + +

    咖啡店的第一個客人

    + +

    凌晨三四點,整理完這個學期修的課的期考考古題,仗著自己有公司的鑰匙,趁著連假半夜公司沒人,車子騎著就殺去公司,借公司雷射印表機印考古題,也順便趁公司沒人,調整幾個伺服器的小問題:檢查主機板、光碟機廠牌型號,換上好的光碟機, lilo 換成 grub 等等。

    + +

    弄了半天,結束已經是早上七點半,天大亮了。雖然昨天睡了一天,可是工作了一晚,頭腦也開始昏昏沉沉,眼皮開始重了。心裏想著去咖啡店吃個早餐,提提神好騎車,就準備回家了。

    + +

    走進怡客咖啡,點了巧克力厚片吐司,加水蜜桃可爾必思,都是我最喜歡的甜味。拿到號碼牌: 1 號,再定神一看:店裏還沒有半個人。想起現在是連假星期天一大早,問了問店員:

    + +
    +

    我是第一個客人嗎?

    + +

    嗯,對呀!

    +
    + +

    呵,我天天跑咖啡店買早餐,可是還沒有當過咖啡店的第一個客人。怡客好像是七點開門的吧,到現在半個多小時,整個店面都是空蕩蕩的。空蕩蕩的咖啡店,現在是我一個人獨佔的~耶~

    + +

    邊想,邊喝了一大口水蜜桃可爾必思。真是奇異的感覺~

    + +
    + +
    + +
    +
    10.8.’06. 2:38am.
    + +

    寺沢大介ミスター味っ子(妙手小廚師)料理真實重現

    + +

    今天傍晚去看寺沢大介的漫畫喰いタン(美食偵探王)的時候,在封面扉頁,寺沢大介提到有個漫畫迷,把ミスター味っ子(妙手小廚師)裏的料理真實重現,並放到網站上。

    + +

    看到這麼好玩的事,我趕緊抄下網址,回家連上去看:哇~真的耶~而且每一樣看起來都好~好吃喔~口水都流到地上了~

    + +

    寺沢大介開玩笑說,不知道這個讀者會不會把喰いタン(美食偵探王)的料理也都原味重現呢?嗯嗯,這麼一說,我也好期待~不過喰いタン(美食偵探王)主角的食量是常人的好幾百倍,要真實重現的話,成本大概很高吧~

    + +

    真的是太酷了~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 83 | + 84 | + 85 | + 86 | + 87 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0086.html.en.html b/htdocs/imacat/me/diary/0086.html.en.html new file mode 120000 index 0000000..4e1afc0 --- /dev/null +++ b/htdocs/imacat/me/diary/0086.html.en.html @@ -0,0 +1 @@ +0086.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0086.html.en.xhtml b/htdocs/imacat/me/diary/0086.html.en.xhtml new file mode 100644 index 0000000..5693358 --- /dev/null +++ b/htdocs/imacat/me/diary/0086.html.en.xhtml @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 86 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 86

    + +
    + +
    + +
    +
    10.21.’06. 1:03pm.
    + +

    轉貼:維基百科創辦人 另創市民論壇

    + +

    沒想到維基百科的前核心,也感受得到維基百科的沉痾。過去維基百科的核心部門,只不斷對外宣稱維基百科的政治正確性,卻鮮少願意面對維基百科的內容正確性問題。只是,由所謂專家撰寫的百科,如何能夠保有其自由與開放的作風?如何避免政治力的介入?和傳統百科(如大英百科)又有什麼不同?

    + +

    原文新聞稿 Co-Founder to Launch Edited Version of Wikipedia 。中文譯稿轉貼自自由時報 2006-10-19 國際新聞維基百科創辦人 另創市民論壇,若有版權問題請隨時告知。

    + +
    + +

    維基百科創辦人 另創市民論壇

    + +

    〔編譯胡立宗/綜合報導〕線上百科全書維基百科 (Wikipedia) 飽受惡意竄改、駭客攻擊、錯誤資訊等困擾,原始創辦人拉瑞.桑格十八日宣布,他將創立一個新的網站 Citizendium (暫譯市民論壇),邀請專家負責撰稿、提供正確資訊。

    + +

    桑格說,他二00一年創立的維基百科,現在已是一個非常需要爬梳整理的龐大怪物,市民論壇將不再有類似的問題。他宣布,市民論壇在幾天內就會開始運作,並將雇用一批專家學者,針對維基上與他們專業領域相關的文章展開徹底清查,然後把正確的內容公布在市民論壇

    + +

    桑格強調,論壇會是一個合理的社群:那些終其一生專研某些問題的人,才能獲得相對應的權限這就像古代村落的長老可以在市集上閒逛,偶爾給人們一些意見,或是約束一下一些害群之馬

    + +

    過於開放 遭惡意利用

    + +

    維基百科在創設後,已成為網路公民自由發言權的表率,任何人都可以為這部自由開放的百科全書貢獻文章。但正因為過於開放,反倒使維基成為惡意者利用及攻擊的對象,如美國總統布希跟英國首相布雷爾的條文就曾經被惡意攻擊過,而某些政治人物也雇用打手刪除不利於己的內容。

    + +
    + +
    + +
    + +
    +
    10.17.’06. 5:58pm.
    + +

    轉貼:罵人被 T 上 判拘 40 天

    + +

    今天蘋果日報有一則奇特的新聞:罵人被 T 上 判拘 40 天

    + +
    + +

    罵人被 T 上 判拘 40 天

    + +

    【張欽╱台北報導】網路留言版主ooo,不滿遭網友xxx在留言版上公開辱罵被 T (指女同性戀中的男性角色)上過等言論,憤而控告x女誹謗,台北地方法院審理後依誹謗罪判x女拘役四十天,得易科罰金,折合新台幣三萬六千元。

    + +

    辯稱為反擊

    + +

    判決指出,xxx(三十五歲)不滿ooo在其註冊的網路留言版上用言語攻擊她,憤而以以暱稱 KKLes 名義,自 KKCity 網路城邦,進入o女開設的 Feeling 留言版,發表版主到處說自己的姦情史被男人上過不算什麼,但娘 T 給 T 上,怪耶,她不是自己是鐵錚錚的一條 T 。

    + +

    xxx雖辯稱是反擊ooo才發表o女與他人發生三角關係等,但法官審理認為,o女之前留言內容並無毀損x女名譽,x女的言論已使網友產生o女性關係隨便的印象。

    + +
    + +

    唔…不大能夠理解。其實我也不大想去理解這種事。我越來越覺得,人跟人之間,有什麼不爽就直接講。幹嘛扯這種爛污?搞匿名,講一堆亂七八糟的難聽話詆燬人家。這樣很好玩嗎?總覺得很幼稚。這種無意義的話,不過是在造自己的口業,傷的其實是自己。為什麼有人會去做這麼幼稚的事呢?無法理解。

    + +
    + +
    + +
    +
    10.13.’06. 3:36am.
    + +

    古典短篇小說選讀

    + +

    空大這學期最後一個學期了,該修的管資系的學分數都修滿了,也沒有學分壓力,選了幾門自己喜歡的課。其中一門,就是古典短篇小說選讀

    + +

    這兩天拿起來唸,凡是課本有提到的,都上網找來看:馮燕傳李寄斬蛇虬髯客傳等等。唐以前的短篇小說,主要都收錄在宋人編的太平廣記裏。至於宋以後的話本,則主要收錄在馮夢龍、凌濛初的三言二拍中。

    + +

    唸文言文,多少有點吃力。唸唐以前的小說時,我都儘可能找白話譯文來看,比較省力。當唸到三言二拍裏的故事時,我原本也想找白話譯文,卻很訝異地發現,話本的原文就已經非常白話了,根本無須譯文。話本是說話人(說書人)說故事的腳本,為求讓一般聽眾也聽得懂,原本就寫得很白話。可是我沒想到會白話到這種程度!即使以千年後的今天來看,還是非常白話。

    + +

    三言二拍裏的話本小說,蠻好玩的。果然是民間說話人講故事的腳本,故事內容多講做人處事的小道理,像是拾金不昧、兄友弟恭、為善行惡等等,劇情則曲折離奇,很像現在電視上常看到的中國民間故事,不是什麼了不起的偉大故事,卻也曲折離奇,頗有趣味。我這樣講,不是說電視劇中國民間故事改編自三言二拍的話本,而是兩者的創作環境、目標對象很類似,因此產生的作品也非常相像。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 84 | + 85 | + 86 | + 87 | + 88 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0086.html.zh-cn.html b/htdocs/imacat/me/diary/0086.html.zh-cn.html new file mode 120000 index 0000000..a043357 --- /dev/null +++ b/htdocs/imacat/me/diary/0086.html.zh-cn.html @@ -0,0 +1 @@ +0086.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0086.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0086.html.zh-cn.xhtml new file mode 100644 index 0000000..255ab27 --- /dev/null +++ b/htdocs/imacat/me/diary/0086.html.zh-cn.xhtml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷八十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷八十六

    + +
    + +
    + +
    +
    10.21.’06. 1:03pm.
    + +

    转贴:维基百科创办人 另创市民论坛

    + +

    没想到维基百科的前核心,也感受得到维基百科的沉疴。过去维基百科的核心部门,只不断对外宣称维基百科的政治正确性,却鲜少愿意面对维基百科的内容正确性问题。只是,由所谓专家撰写的百科,如何能够保有其自由与开放的作风?如何避免政治力的介入?和传统百科(如大英百科)又有什么不同?

    + +

    原文新闻稿 Co-Founder to Launch Edited Version of Wikipedia 。中文译稿转贴自自由时报 2006-10-19 国际新闻维基百科创办人 另创市民论坛,若有版权问题请随时告知。

    + +
    + +

    维基百科创办人 另创市民论坛

    + +

    〔编译胡立宗/综合报导〕线上百科全书维基百科 (Wikipedia) 饱受恶意窜改、骇客攻击、错误资讯等困扰,原始创办人拉瑞.桑格十八日宣布,他将创立一个新的网站 Citizendium (暂译市民论坛),邀请专家负责撰稿、提供正确资讯。

    + +

    桑格说,他二00一年创立的维基百科,现在已是一个非常需要爬梳整理的庞大怪物,市民论坛将不再有类似的问题。他宣布,市民论坛在几天内就会开始运作,并将雇用一批专家学者,针对维基上与他们专业领域相关的文章展开彻底清查,然后把正确的内容公布在市民论坛

    + +

    桑格强调,论坛会是一个合理的社群:那些终其一生专研某些问题的人,才能获得相对应的权限这就像古代村落的长老可以在市集上闲逛,偶尔给人们一些意见,或是约束一下一些害群之马

    + +

    过於开放 遭恶意利用

    + +

    维基百科在创设后,已成为网路公民自由发言权的表率,任何人都可以为这部自由开放的百科全书贡献文章。但正因为过於开放,反倒使维基成为恶意者利用及攻击的对象,如美国总统布希跟英国首相布雷尔的条文就曾经被恶意攻击过,而某些政治人物也雇用打手删除不利於己的内容。

    + +
    + +
    + +
    + +
    +
    10.17.’06. 5:58pm.
    + +

    转贴:骂人被 T 上 判拘 40 天

    + +

    今天苹果日报有一则奇特的新闻:骂人被 T 上 判拘 40 天

    + +
    + +

    骂人被 T 上 判拘 40 天

    + +

    【张钦/台北报导】网路留言版主ooo,不满遭网友xxx在留言版上公开辱骂被 T (指女同性恋中的男性角色)上过等言论,愤而控告x女诽谤,台北地方法院审理后依诽谤罪判x女拘役四十天,得易科罚金,折合新台币三万六千元。

    + +

    辩称为反击

    + +

    判决指出,xxx(三十五岁)不满ooo在其注册的网路留言版上用言语攻击她,愤而以以昵称 KKLes 名义,自 KKCity 网路城邦,进入o女开设的 Feeling 留言版,发表版主到处说自己的奸情史被男人上过不算什么,但娘 T 给 T 上,怪耶,她不是自己是铁铮铮的一条 T 。

    + +

    xxx虽辩称是反击ooo才发表o女与他人发生三角关系等,但法官审理认为,o女之前留言内容并无毁损x女名誉,x女的言论已使网友产生o女性关系随便的印象。

    + +
    + +

    唔…不大能够理解。其实我也不大想去理解这种事。我越来越觉得,人跟人之间,有什么不爽就直接讲。干嘛扯这种烂污?搞匿名,讲一堆乱七八糟的难听话诋毁人家。这样很好玩吗?总觉得很幼稚。这种无意义的话,不过是在造自己的口业,伤的其实是自己。为什么有人会去做这么幼稚的事呢?无法理解。

    + +
    + +
    + +
    +
    10.13.’06. 3:36am.
    + +

    古典短篇小说选读

    + +

    空大这学期最后一个学期了,该修的管资系的学分数都修满了,也没有学分压力,选了几门自己喜欢的课。其中一门,就是古典短篇小说选读

    + +

    这两天拿起来念,凡是课本有提到的,都上网找来看:冯燕传李寄斩蛇虬髯客传等等。唐以前的短篇小说,主要都收录在宋人编的太平广记里。至於宋以后的话本,则主要收录在冯梦龙、凌蒙初的三言二拍中。

    + +

    念文言文,多少有点吃力。念唐以前的小说时,我都尽可能找白话译文来看,比较省力。当念到三言二拍里的故事时,我原本也想找白话译文,却很讶异地发现,话本的原文就已经非常白话了,根本无须译文。话本是说话人(说书人)说故事的脚本,为求让一般听众也听得懂,原本就写得很白话。可是我没想到会白话到这种程度!即使以千年后的今天来看,还是非常白话。

    + +

    三言二拍里的话本小说,蛮好玩的。果然是民间说话人讲故事的脚本,故事内容多讲做人处事的小道理,像是拾金不昧、兄友弟恭、为善行恶等等,剧情则曲折离奇,很像现在电视上常看到的中国民间故事,不是什么了不起的伟大故事,却也曲折离奇,颇有趣味。我这样讲,不是说电视剧中国民间故事改编自三言二拍的话本,而是两者的创作环境、目标对象很类似,因此产生的作品也非常相像。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 84 | + 85 | + 86 | + 87 | + 88 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0086.html.zh-tw.html b/htdocs/imacat/me/diary/0086.html.zh-tw.html new file mode 120000 index 0000000..4959e3f --- /dev/null +++ b/htdocs/imacat/me/diary/0086.html.zh-tw.html @@ -0,0 +1 @@ +0086.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0086.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0086.html.zh-tw.xhtml new file mode 100644 index 0000000..1e29f4f --- /dev/null +++ b/htdocs/imacat/me/diary/0086.html.zh-tw.xhtml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷八十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷八十六

    + +
    + +
    + +
    +
    10.21.’06. 1:03pm.
    + +

    轉貼:維基百科創辦人 另創市民論壇

    + +

    沒想到維基百科的前核心,也感受得到維基百科的沉痾。過去維基百科的核心部門,只不斷對外宣稱維基百科的政治正確性,卻鮮少願意面對維基百科的內容正確性問題。只是,由所謂專家撰寫的百科,如何能夠保有其自由與開放的作風?如何避免政治力的介入?和傳統百科(如大英百科)又有什麼不同?

    + +

    原文新聞稿 Co-Founder to Launch Edited Version of Wikipedia 。中文譯稿轉貼自自由時報 2006-10-19 國際新聞維基百科創辦人 另創市民論壇,若有版權問題請隨時告知。

    + +
    + +

    維基百科創辦人 另創市民論壇

    + +

    〔編譯胡立宗/綜合報導〕線上百科全書維基百科 (Wikipedia) 飽受惡意竄改、駭客攻擊、錯誤資訊等困擾,原始創辦人拉瑞.桑格十八日宣布,他將創立一個新的網站 Citizendium (暫譯市民論壇),邀請專家負責撰稿、提供正確資訊。

    + +

    桑格說,他二00一年創立的維基百科,現在已是一個非常需要爬梳整理的龐大怪物,市民論壇將不再有類似的問題。他宣布,市民論壇在幾天內就會開始運作,並將雇用一批專家學者,針對維基上與他們專業領域相關的文章展開徹底清查,然後把正確的內容公布在市民論壇

    + +

    桑格強調,論壇會是一個合理的社群:那些終其一生專研某些問題的人,才能獲得相對應的權限這就像古代村落的長老可以在市集上閒逛,偶爾給人們一些意見,或是約束一下一些害群之馬

    + +

    過於開放 遭惡意利用

    + +

    維基百科在創設後,已成為網路公民自由發言權的表率,任何人都可以為這部自由開放的百科全書貢獻文章。但正因為過於開放,反倒使維基成為惡意者利用及攻擊的對象,如美國總統布希跟英國首相布雷爾的條文就曾經被惡意攻擊過,而某些政治人物也雇用打手刪除不利於己的內容。

    + +
    + +
    + +
    + +
    +
    10.17.’06. 5:58pm.
    + +

    轉貼:罵人被 T 上 判拘 40 天

    + +

    今天蘋果日報有一則奇特的新聞:罵人被 T 上 判拘 40 天

    + +
    + +

    罵人被 T 上 判拘 40 天

    + +

    【張欽╱台北報導】網路留言版主ooo,不滿遭網友xxx在留言版上公開辱罵被 T (指女同性戀中的男性角色)上過等言論,憤而控告x女誹謗,台北地方法院審理後依誹謗罪判x女拘役四十天,得易科罰金,折合新台幣三萬六千元。

    + +

    辯稱為反擊

    + +

    判決指出,xxx(三十五歲)不滿ooo在其註冊的網路留言版上用言語攻擊她,憤而以以暱稱 KKLes 名義,自 KKCity 網路城邦,進入o女開設的 Feeling 留言版,發表版主到處說自己的姦情史被男人上過不算什麼,但娘 T 給 T 上,怪耶,她不是自己是鐵錚錚的一條 T 。

    + +

    xxx雖辯稱是反擊ooo才發表o女與他人發生三角關係等,但法官審理認為,o女之前留言內容並無毀損x女名譽,x女的言論已使網友產生o女性關係隨便的印象。

    + +
    + +

    唔…不大能夠理解。其實我也不大想去理解這種事。我越來越覺得,人跟人之間,有什麼不爽就直接講。幹嘛扯這種爛污?搞匿名,講一堆亂七八糟的難聽話詆燬人家。這樣很好玩嗎?總覺得很幼稚。這種無意義的話,不過是在造自己的口業,傷的其實是自己。為什麼有人會去做這麼幼稚的事呢?無法理解。

    + +
    + +
    + +
    +
    10.13.’06. 3:36am.
    + +

    古典短篇小說選讀

    + +

    空大這學期最後一個學期了,該修的管資系的學分數都修滿了,也沒有學分壓力,選了幾門自己喜歡的課。其中一門,就是古典短篇小說選讀

    + +

    這兩天拿起來唸,凡是課本有提到的,都上網找來看:馮燕傳李寄斬蛇虬髯客傳等等。唐以前的短篇小說,主要都收錄在宋人編的太平廣記裏。至於宋以後的話本,則主要收錄在馮夢龍、凌濛初的三言二拍中。

    + +

    唸文言文,多少有點吃力。唸唐以前的小說時,我都儘可能找白話譯文來看,比較省力。當唸到三言二拍裏的故事時,我原本也想找白話譯文,卻很訝異地發現,話本的原文就已經非常白話了,根本無須譯文。話本是說話人(說書人)說故事的腳本,為求讓一般聽眾也聽得懂,原本就寫得很白話。可是我沒想到會白話到這種程度!即使以千年後的今天來看,還是非常白話。

    + +

    三言二拍裏的話本小說,蠻好玩的。果然是民間說話人講故事的腳本,故事內容多講做人處事的小道理,像是拾金不昧、兄友弟恭、為善行惡等等,劇情則曲折離奇,很像現在電視上常看到的中國民間故事,不是什麼了不起的偉大故事,卻也曲折離奇,頗有趣味。我這樣講,不是說電視劇中國民間故事改編自三言二拍的話本,而是兩者的創作環境、目標對象很類似,因此產生的作品也非常相像。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 84 | + 85 | + 86 | + 87 | + 88 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0087.html.en.html b/htdocs/imacat/me/diary/0087.html.en.html new file mode 120000 index 0000000..ebe8f90 --- /dev/null +++ b/htdocs/imacat/me/diary/0087.html.en.html @@ -0,0 +1 @@ +0087.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0087.html.en.xhtml b/htdocs/imacat/me/diary/0087.html.en.xhtml new file mode 100644 index 0000000..c8c9818 --- /dev/null +++ b/htdocs/imacat/me/diary/0087.html.en.xhtml @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 87 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 87

    + +
    + +
    + +
    +
    10.31.’06. 2:29am.
    + +

    I’ve Never Been To Me 與女性主義的反挫

    + +

    I’ve Never Been To Me 是一首很好聽的老歌,我想很多人應該都很愛聽。

    + +

    我原先也很喜歡這首歌,歌詞大概聽得懂六、七分,每次聽每次都很感動。 S.H.E. 的專輯青春株式會社專輯中有翻唱這首歌,我也很喜歡 S.H.E. 翻唱的版本。臺灣最早翻唱的是黃鶯鶯。除了翻唱外,用它來作主題曲的電影,更是不計其數。

    + +

    不過 I’ve Never Been To Me 到底是一首什麼歌?今天突然心血來潮,上網去找了它的完整歌詞(我用聽的只聽得懂六、七分),並讀了不少它的演唱背景。

    + +

    I’ve Never Been To Me 的原主唱為 Charlene (夏琳)Charlene 是典型一曲歌手,生平就只有這一首暢銷曲,其它的曲子都平凡無奇。 Charlene 原名 Charlene Marilynn D’Angelo 於 1950 年出生, 1973 年和 Motown 唱片公司簽約。 Motown 唱片公司原本主打黑人鄉村音樂,但有意朝白人音樂發展,因此簽下了 Charlene 。同年以藝名 Charlene Duncan 推出首張單曲 All That Love Went to Waste 。但由於唱片公司此時正忙著 Edwin StarrAin’t It Hell Up in HarlemJackson FiveDancing Machine 的宣傳,無暇顧及,因此並未受到多少注意。 Jackson Five 即流行樂之王麥可傑克森 Michael Jackson 、珍娜傑克森 Janet Jackson 及其兄弟姐妹五人,小時候成名發跡的五人樂團。

    + +

    1976 年,唱片公司改以藝名 Charlene ,為她發行新單曲 It Ain’t Easy Comin’ Down 與第二張同名專輯 CharleneI’ve Never Been to Me 即收錄在這張專輯中。但這次除了單曲進榜第九十七名外,專輯則全軍覆沒。 1977 年 Motown 將專輯重新包裝,改名為 Songs of Love ,並改以 I’ve Never Been to Me 為主打單曲重新發行,還是慘敗。重新錄製 I’ve Never Been to Me 的過程中,還不小心剪掉了口白。 1980 年在另一張單曲失敗以後, Motown 唱片公司跟 Charlene 解約了, Charlene 也遠赴英國,在一家小店當店員。 1970 年代,正是女性主義最高峰的年代。

    + +

    1980 年代,保守勢力開始反撲。 1984 年雷根當選美國總統,通過多項法案,婦運受到重挫。 1983 年,一個地方小電台的 DJ 在電台節目中播了 I’ve Never Been to Me ,一夕之間,這首歌開始紅透半邊天。所有人都在問,這是誰唱的? Motown 唱片公司看到這樣的態勢,當然知道要把握,立刻重新剪輯當年的單曲,接回口白重新發行,立刻爬上排行綁第三名。於是 Motown 唱片公司又把 Charlene 請回來,並發行了專輯 I’ve Never Been to Me ,廣受好評。可惜接下來就後繼無力了。專輯連續慘敗以後, 1985 年退出 Motown 唱片公司,從此消失了。

    + +

    I’ve Never Been to Me ,和婦運的反挫,和新保守主義的興起,有什麼關係?

    + +

    有很多人認為, I’ve Never Been to Me 講的是女人追尋自我的過程。對於這一點,我完全不同意。

    + +

    我找來 I’ve Never Been to Me 的歌詞,完整讀過一遍。其中幾段讀不懂的,上網查了不少典故。歌詞的大意是:一個前半生放蕩、歷盡蒼桑的女人,向另一個不甘寂寞、思春的少婦,以自身經歷說出的建言:她曾經不顧一切追尋自由,曾見過世間繁華,曾有過純情浪漫的愛,也曾與王公貴族縱慾狂歡。但一心只顧自由享樂,傷害了許多人,落得現在孑然一身。於是她勸告思春的少婦:不要嫌我囉唆,所謂的自由、天堂都是謊言,只有懷中的嬰兒,還有枕邊拌嘴爭吵的丈夫,這些平凡的一切,才是女人真正的幸福歸宿。

    + +

    仔細讀完了歌詞,實在很難讓人喜歡這首歌。 I’ve Never Been to Me 力勸女人放棄外面繁華的花花世界,放棄自由,回歸丈夫子女所在的平凡家庭小宇宙。外面的自由世界沒有自我,只有在家庭裏才有女人的自我。高唱女人回歸家庭,難怪無法在婦運高漲的 1970 年代受青睞,卻能在保守勢力反撲的 1980 年代爆紅。

    + +

    I’ve Never Been to Me 甚至反墮胎。 Sometimes I’ve been to crying for unborn children that might have made me complete 這一句,我原來怎麼讀都讀不懂,上網找了許多中譯,也都譯得不清不楚。後來找到一份比較好的譯文,才看懂了。這裏應該譯為有時候我曾經為了那我從未生過、或許可以讓我成為完整女人的孩子而哭泣,因為沒有生下小孩,所以我無法成為完整的女人,成為了不完整的女人。如果生下了那個小孩,可以讓我從不完整的女人變成完整的女人。這裏指的是自己的小孩,加上整首歌從頭到尾對自己年輕縱慾悔恨的氣氛,指的應該就是墮掉的小孩。

    + +

    另外一句有點難解的是 I’ve moved like Harlow in Monte Carlo and showed ’em what I’ve gotHarlow in Monte Carlo 是什麼? Monte Carlo 是指蒙地卡羅,奢華之都。 Harlow 則是指 Jean Harlow 珍哈露, 1920 年代紅極一時的性感女神,生於 1911 年,因為感情不順遂,長期酗酒縱慾狂歡,於 1937 年因膽囊炎病逝。提到 Jean Harlow ,應該是指像 Jean Harlow 一樣縱慾狂歡的行徑。

    + +

    像這樣,要說這是女性自覺的歌曲,真是讓人難以茍同。標題找不到自我,高舉追尋自我這樣女性主義慣用的口號,骨子裏卻要女人回歸家庭。用女性主義的語言打擊女性主義,這正是 1980 年代新保守主義的主要手法。 I’ve Never Been to Me 的紅極一時,象徵的是新保守的興起,與婦運反挫時代的來臨。

    + +

    以下參考中譯來自銀河西洋音樂城,簡介部份則整理自銀河西洋音樂城及其它中英相關網站的介紹。

    + +
    + +I’Ve Never Been To Me
    +我從未找到過自我
    +(Written by Ken Kirsch and Ronald Miller)
    +
    +Hey lady, you lady, cursing at your life
    +嘿,這位太太,你這對自己的生命充滿怨恨的太太
    +You’re a discontented mother and a regimented wife
    +你是個不滿現實的母親,是個失去自由的妻子
    +I’ve no doubt you dream about the things you’ll never do
    +我深信你夢想著那些你永遠無法作的事
    +But I wish someone had talked to me like I wanna talk to you
    +但我真希望有人曾經對我說過現在我想告訴你的事
    +
    +Oh, I’ve been to Georgia and California and anywhere I could run
    +啊,我曾到過喬治亞、到過加州,還有任何我可以去到的地方
    +I took the hand of a preacher man and we made love in the sun
    +我牽過一個神職男人的手,一起在陽光下纏綿
    +But I ran out of places and friendly faces because I had to be free
    +但如今我已無處可去、也沒有朋友,只因為當初我非得自由
    +I’ve been to paradise but I’ve never been to me
    +我曾經到過天堂,但我從未找到過自我
    +
    +Please lady, please lady, don’t just walk away
    +求求你,這位太太,求求你,別就這樣走開
    +’Cause I have this need to tell you why I’m all alone today
    +因為我希望能告訴你,為什麼今天我會如此孤獨
    +I can see so much of me still living in your eyes
    +我可以在你的眼中看到太多過去的我
    +Won’t you share a part of a weary heart that has lived a million lies....
    +可否請你分享一些我這曾經活在千萬謊言中的疲倦心情
    +
    +Oh, I’ve been to Niece and the Isle of Greece while I’ve sipped champagne on a yacht
    +啊,我曾到過尼斯和希臘的島嶼,坐在遊艇上啜飲著香檳
    +I’ve moved like Harlow in Monte Carlo and showed ’em what I’ve got
    +我曾像是珍哈露般的款擺在蒙地卡羅,秀著我的本錢
    +I’ve been undressed by kings and I’ve seen some things that a woman ain’t supposed to see
    +我曾被王侯寬衣解帶,看過好些普通女人看不到的事情
    +I’ve been to paradise, but I’ve never been to me
    +我曾經到過天堂,但我從未找到過自我
    +
    +[Spoken]
    +(口白)
    +Hey, you know what paradise is? It’s a lie
    +嘿,你知道天堂是什麼?那是個謊言
    +A fantasy we create about people and places as we’d like them to be
    +一種我們創造出來,所有人和所有地方都盡如我們期望的幻想
    +But you know what truth is?
    +但你知道真實是什麼嗎?
    +It’s that little baby you’re holding
    +那就是那個你懷抱中的小寶寶
    +It’s that man you fought with this morning
    +那就是那個今天早上你跟他吵架
    +The same one you’re going to make love with tonight
    +而今晚又將與他纏綿的同一個男人
    +That’s truth, that’s love
    +那就是真實,那就是愛
    +
    +Sometimes I’ve been to crying for unborn children that might have made me complete
    +有時候我曾經為了那我從未生過、或許可以讓我成為完整女人的孩子而哭泣
    +But I took the sweet life, I never knew I’d be bitter from the sweet
    +但我選擇了甜蜜的生活,我從不知道有一天我會由甜轉為苦
    +I’ve spent my life exploring the subtle whoring that costs too much to be free
    +我曾浪費我的生命,探索著那種讓我付出太高代價的、人盡可夫的自由生活
    +Hey lady, I’ve been to paradise, but I’ve never been to me
    +我曾經到過天堂,但我從未找到過自我
    + +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 85 | + 86 | + 87 | + 88 | + 89 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0087.html.zh-cn.html b/htdocs/imacat/me/diary/0087.html.zh-cn.html new file mode 120000 index 0000000..23b1212 --- /dev/null +++ b/htdocs/imacat/me/diary/0087.html.zh-cn.html @@ -0,0 +1 @@ +0087.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0087.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0087.html.zh-cn.xhtml new file mode 100644 index 0000000..d72756b --- /dev/null +++ b/htdocs/imacat/me/diary/0087.html.zh-cn.xhtml @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷八十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷八十七

    + +
    + +
    + +
    +
    10.31.’06. 2:29am.
    + +

    I’ve Never Been To Me 与女性主义的反挫

    + +

    I’ve Never Been To Me 是一首很好听的老歌,我想很多人应该都很爱听。

    + +

    我原先也很喜欢这首歌,歌词大概听得懂六、七分,每次听每次都很感动。 S.H.E. 的专辑青春株式会社专辑中有翻唱这首歌,我也很喜欢 S.H.E. 翻唱的版本。台湾最早翻唱的是黄莺莺。除了翻唱外,用它来作主题曲的电影,更是不计其数。

    + +

    不过 I’ve Never Been To Me 到底是一首什么歌?今天突然心血来潮,上网去找了它的完整歌词(我用听的只听得懂六、七分),并读了不少它的演唱背景。

    + +

    I’ve Never Been To Me 的原主唱为 Charlene (夏琳)Charlene 是典型一曲歌手,生平就只有这一首畅销曲,其它的曲子都平凡无奇。 Charlene 原名 Charlene Marilynn D’Angelo 於 1950 年出生, 1973 年和 Motown 唱片公司签约。 Motown 唱片公司原本主打黑人乡村音乐,但有意朝白人音乐发展,因此签下了 Charlene 。同年以艺名 Charlene Duncan 推出首张单曲 All That Love Went to Waste 。但由於唱片公司此时正忙著 Edwin StarrAin’t It Hell Up in HarlemJackson FiveDancing Machine 的宣传,无暇顾及,因此并未受到多少注意。 Jackson Five 即流行乐之王麦可杰克森 Michael Jackson 、珍娜杰克森 Janet Jackson 及其兄弟姐妹五人,小时候成名发迹的五人乐团。

    + +

    1976 年,唱片公司改以艺名 Charlene ,为她发行新单曲 It Ain’t Easy Comin’ Down 与第二张同名专辑 CharleneI’ve Never Been to Me 即收录在这张专辑中。但这次除了单曲进榜第九十七名外,专辑则全军覆没。 1977 年 Motown 将专辑重新包装,改名为 Songs of Love ,并改以 I’ve Never Been to Me 为主打单曲重新发行,还是惨败。重新录制 I’ve Never Been to Me 的过程中,还不小心剪掉了口白。 1980 年在另一张单曲失败以后, Motown 唱片公司跟 Charlene 解约了, Charlene 也远赴英国,在一家小店当店员。 1970 年代,正是女性主义最高峰的年代。

    + +

    1980 年代,保守势力开始反扑。 1984 年雷根当选美国总统,通过多项法案,妇运受到重挫。 1983 年,一个地方小电台的 DJ 在电台节目中播了 I’ve Never Been to Me ,一夕之间,这首歌开始红透半边天。所有人都在问,这是谁唱的? Motown 唱片公司看到这样的态势,当然知道要把握,立刻重新剪辑当年的单曲,接回口白重新发行,立刻爬上排行绑第三名。於是 Motown 唱片公司又把 Charlene 请回来,并发行了专辑 I’ve Never Been to Me ,广受好评。可惜接下来就后继无力了。专辑连续惨败以后, 1985 年退出 Motown 唱片公司,从此消失了。

    + +

    I’ve Never Been to Me ,和妇运的反挫,和新保守主义的兴起,有什么关系?

    + +

    有很多人认为, I’ve Never Been to Me 讲的是女人追寻自我的过程。对於这一点,我完全不同意。

    + +

    我找来 I’ve Never Been to Me 的歌词,完整读过一遍。其中几段读不懂的,上网查了不少典故。歌词的大意是:一个前半生放荡、历尽苍桑的女人,向另一个不甘寂寞、思春的少妇,以自身经历说出的建言:她曾经不顾一切追寻自由,曾见过世间繁华,曾有过纯情浪漫的爱,也曾与王公贵族纵欲狂欢。但一心只顾自由享乐,伤害了许多人,落得现在孑然一身。於是她劝告思春的少妇:不要嫌我罗唆,所谓的自由、天堂都是谎言,只有怀中的婴儿,还有枕边拌嘴争吵的丈夫,这些平凡的一切,才是女人真正的幸福归宿。

    + +

    仔细读完了歌词,实在很难让人喜欢这首歌。 I’ve Never Been to Me 力劝女人放弃外面繁华的花花世界,放弃自由,回归丈夫子女所在的平凡家庭小宇宙。外面的自由世界没有自我,只有在家庭里才有女人的自我。高唱女人回归家庭,难怪无法在妇运高涨的 1970 年代受青睐,却能在保守势力反扑的 1980 年代爆红。

    + +

    I’ve Never Been to Me 甚至反堕胎。 Sometimes I’ve been to crying for unborn children that might have made me complete 这一句,我原来怎么读都读不懂,上网找了许多中译,也都译得不清不楚。后来找到一份比较好的译文,才看懂了。这里应该译为有时候我曾经为了那我从未生过、或许可以让我成为完整女人的孩子而哭泣,因为没有生下小孩,所以我无法成为完整的女人,成为了不完整的女人。如果生下了那个小孩,可以让我从不完整的女人变成完整的女人。这里指的是自己的小孩,加上整首歌从头到尾对自己年轻纵欲悔恨的气氛,指的应该就是堕掉的小孩。

    + +

    另外一句有点难解的是 I’ve moved like Harlow in Monte Carlo and showed ’em what I’ve gotHarlow in Monte Carlo 是什么? Monte Carlo 是指蒙地卡罗,奢华之都。 Harlow 则是指 Jean Harlow 珍哈露, 1920 年代红极一时的性感女神,生於 1911 年,因为感情不顺遂,长期酗酒纵欲狂欢,於 1937 年因胆囊炎病逝。提到 Jean Harlow ,应该是指像 Jean Harlow 一样纵欲狂欢的行径。

    + +

    像这样,要说这是女性自觉的歌曲,真是让人难以苟同。标题找不到自我,高举追寻自我这样女性主义惯用的口号,骨子里却要女人回归家庭。用女性主义的语言打击女性主义,这正是 1980 年代新保守主义的主要手法。 I’ve Never Been to Me 的红极一时,象徵的是新保守的兴起,与妇运反挫时代的来临。

    + +

    以下参考中译来自银河西洋音乐城,简介部份则整理自银河西洋音乐城及其它中英相关网站的介绍。

    + +
    + +I’Ve Never Been To Me
    +我从未找到过自我
    +(Written by Ken Kirsch and Ronald Miller)
    +
    +Hey lady, you lady, cursing at your life
    +嘿,这位太太,你这对自己的生命充满怨恨的太太
    +You’re a discontented mother and a regimented wife
    +你是个不满现实的母亲,是个失去自由的妻子
    +I’ve no doubt you dream about the things you’ll never do
    +我深信你梦想著那些你永远无法作的事
    +But I wish someone had talked to me like I wanna talk to you
    +但我真希望有人曾经对我说过现在我想告诉你的事
    +
    +Oh, I’ve been to Georgia and California and anywhere I could run
    +啊,我曾到过乔治亚、到过加州,还有任何我可以去到的地方
    +I took the hand of a preacher man and we made love in the sun
    +我牵过一个神职男人的手,一起在阳光下缠绵
    +But I ran out of places and friendly faces because I had to be free
    +但如今我已无处可去、也没有朋友,只因为当初我非得自由
    +I’ve been to paradise but I’ve never been to me
    +我曾经到过天堂,但我从未找到过自我
    +
    +Please lady, please lady, don’t just walk away
    +求求你,这位太太,求求你,别就这样走开
    +’Cause I have this need to tell you why I’m all alone today
    +因为我希望能告诉你,为什么今天我会如此孤独
    +I can see so much of me still living in your eyes
    +我可以在你的眼中看到太多过去的我
    +Won’t you share a part of a weary heart that has lived a million lies....
    +可否请你分享一些我这曾经活在千万谎言中的疲倦心情
    +
    +Oh, I’ve been to Niece and the Isle of Greece while I’ve sipped champagne on a yacht
    +啊,我曾到过尼斯和希腊的岛屿,坐在游艇上啜饮著香槟
    +I’ve moved like Harlow in Monte Carlo and showed ’em what I’ve got
    +我曾像是珍哈露般的款摆在蒙地卡罗,秀著我的本钱
    +I’ve been undressed by kings and I’ve seen some things that a woman ain’t supposed to see
    +我曾被王侯宽衣解带,看过好些普通女人看不到的事情
    +I’ve been to paradise, but I’ve never been to me
    +我曾经到过天堂,但我从未找到过自我
    +
    +[Spoken]
    +(口白)
    +Hey, you know what paradise is? It’s a lie
    +嘿,你知道天堂是什么?那是个谎言
    +A fantasy we create about people and places as we’d like them to be
    +一种我们创造出来,所有人和所有地方都尽如我们期望的幻想
    +But you know what truth is?
    +但你知道真实是什么吗?
    +It’s that little baby you’re holding
    +那就是那个你怀抱中的小宝宝
    +It’s that man you fought with this morning
    +那就是那个今天早上你跟他吵架
    +The same one you’re going to make love with tonight
    +而今晚又将与他缠绵的同一个男人
    +That’s truth, that’s love
    +那就是真实,那就是爱
    +
    +Sometimes I’ve been to crying for unborn children that might have made me complete
    +有时候我曾经为了那我从未生过、或许可以让我成为完整女人的孩子而哭泣
    +But I took the sweet life, I never knew I’d be bitter from the sweet
    +但我选择了甜蜜的生活,我从不知道有一天我会由甜转为苦
    +I’ve spent my life exploring the subtle whoring that costs too much to be free
    +我曾浪费我的生命,探索著那种让我付出太高代价的、人尽可夫的自由生活
    +Hey lady, I’ve been to paradise, but I’ve never been to me
    +我曾经到过天堂,但我从未找到过自我
    + +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 85 | + 86 | + 87 | + 88 | + 89 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0087.html.zh-tw.html b/htdocs/imacat/me/diary/0087.html.zh-tw.html new file mode 120000 index 0000000..19c7e5d --- /dev/null +++ b/htdocs/imacat/me/diary/0087.html.zh-tw.html @@ -0,0 +1 @@ +0087.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0087.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0087.html.zh-tw.xhtml new file mode 100644 index 0000000..284e138 --- /dev/null +++ b/htdocs/imacat/me/diary/0087.html.zh-tw.xhtml @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷八十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷八十七

    + +
    + +
    + +
    +
    10.31.’06. 2:29am.
    + +

    I’ve Never Been To Me 與女性主義的反挫

    + +

    I’ve Never Been To Me 是一首很好聽的老歌,我想很多人應該都很愛聽。

    + +

    我原先也很喜歡這首歌,歌詞大概聽得懂六、七分,每次聽每次都很感動。 S.H.E. 的專輯青春株式會社專輯中有翻唱這首歌,我也很喜歡 S.H.E. 翻唱的版本。臺灣最早翻唱的是黃鶯鶯。除了翻唱外,用它來作主題曲的電影,更是不計其數。

    + +

    不過 I’ve Never Been To Me 到底是一首什麼歌?今天突然心血來潮,上網去找了它的完整歌詞(我用聽的只聽得懂六、七分),並讀了不少它的演唱背景。

    + +

    I’ve Never Been To Me 的原主唱為 Charlene (夏琳)Charlene 是典型一曲歌手,生平就只有這一首暢銷曲,其它的曲子都平凡無奇。 Charlene 原名 Charlene Marilynn D’Angelo 於 1950 年出生, 1973 年和 Motown 唱片公司簽約。 Motown 唱片公司原本主打黑人鄉村音樂,但有意朝白人音樂發展,因此簽下了 Charlene 。同年以藝名 Charlene Duncan 推出首張單曲 All That Love Went to Waste 。但由於唱片公司此時正忙著 Edwin StarrAin’t It Hell Up in HarlemJackson FiveDancing Machine 的宣傳,無暇顧及,因此並未受到多少注意。 Jackson Five 即流行樂之王麥可傑克森 Michael Jackson 、珍娜傑克森 Janet Jackson 及其兄弟姐妹五人,小時候成名發跡的五人樂團。

    + +

    1976 年,唱片公司改以藝名 Charlene ,為她發行新單曲 It Ain’t Easy Comin’ Down 與第二張同名專輯 CharleneI’ve Never Been to Me 即收錄在這張專輯中。但這次除了單曲進榜第九十七名外,專輯則全軍覆沒。 1977 年 Motown 將專輯重新包裝,改名為 Songs of Love ,並改以 I’ve Never Been to Me 為主打單曲重新發行,還是慘敗。重新錄製 I’ve Never Been to Me 的過程中,還不小心剪掉了口白。 1980 年在另一張單曲失敗以後, Motown 唱片公司跟 Charlene 解約了, Charlene 也遠赴英國,在一家小店當店員。 1970 年代,正是女性主義最高峰的年代。

    + +

    1980 年代,保守勢力開始反撲。 1984 年雷根當選美國總統,通過多項法案,婦運受到重挫。 1983 年,一個地方小電台的 DJ 在電台節目中播了 I’ve Never Been to Me ,一夕之間,這首歌開始紅透半邊天。所有人都在問,這是誰唱的? Motown 唱片公司看到這樣的態勢,當然知道要把握,立刻重新剪輯當年的單曲,接回口白重新發行,立刻爬上排行綁第三名。於是 Motown 唱片公司又把 Charlene 請回來,並發行了專輯 I’ve Never Been to Me ,廣受好評。可惜接下來就後繼無力了。專輯連續慘敗以後, 1985 年退出 Motown 唱片公司,從此消失了。

    + +

    I’ve Never Been to Me ,和婦運的反挫,和新保守主義的興起,有什麼關係?

    + +

    有很多人認為, I’ve Never Been to Me 講的是女人追尋自我的過程。對於這一點,我完全不同意。

    + +

    我找來 I’ve Never Been to Me 的歌詞,完整讀過一遍。其中幾段讀不懂的,上網查了不少典故。歌詞的大意是:一個前半生放蕩、歷盡蒼桑的女人,向另一個不甘寂寞、思春的少婦,以自身經歷說出的建言:她曾經不顧一切追尋自由,曾見過世間繁華,曾有過純情浪漫的愛,也曾與王公貴族縱慾狂歡。但一心只顧自由享樂,傷害了許多人,落得現在孑然一身。於是她勸告思春的少婦:不要嫌我囉唆,所謂的自由、天堂都是謊言,只有懷中的嬰兒,還有枕邊拌嘴爭吵的丈夫,這些平凡的一切,才是女人真正的幸福歸宿。

    + +

    仔細讀完了歌詞,實在很難讓人喜歡這首歌。 I’ve Never Been to Me 力勸女人放棄外面繁華的花花世界,放棄自由,回歸丈夫子女所在的平凡家庭小宇宙。外面的自由世界沒有自我,只有在家庭裏才有女人的自我。高唱女人回歸家庭,難怪無法在婦運高漲的 1970 年代受青睞,卻能在保守勢力反撲的 1980 年代爆紅。

    + +

    I’ve Never Been to Me 甚至反墮胎。 Sometimes I’ve been to crying for unborn children that might have made me complete 這一句,我原來怎麼讀都讀不懂,上網找了許多中譯,也都譯得不清不楚。後來找到一份比較好的譯文,才看懂了。這裏應該譯為有時候我曾經為了那我從未生過、或許可以讓我成為完整女人的孩子而哭泣,因為沒有生下小孩,所以我無法成為完整的女人,成為了不完整的女人。如果生下了那個小孩,可以讓我從不完整的女人變成完整的女人。這裏指的是自己的小孩,加上整首歌從頭到尾對自己年輕縱慾悔恨的氣氛,指的應該就是墮掉的小孩。

    + +

    另外一句有點難解的是 I’ve moved like Harlow in Monte Carlo and showed ’em what I’ve gotHarlow in Monte Carlo 是什麼? Monte Carlo 是指蒙地卡羅,奢華之都。 Harlow 則是指 Jean Harlow 珍哈露, 1920 年代紅極一時的性感女神,生於 1911 年,因為感情不順遂,長期酗酒縱慾狂歡,於 1937 年因膽囊炎病逝。提到 Jean Harlow ,應該是指像 Jean Harlow 一樣縱慾狂歡的行徑。

    + +

    像這樣,要說這是女性自覺的歌曲,真是讓人難以茍同。標題找不到自我,高舉追尋自我這樣女性主義慣用的口號,骨子裏卻要女人回歸家庭。用女性主義的語言打擊女性主義,這正是 1980 年代新保守主義的主要手法。 I’ve Never Been to Me 的紅極一時,象徵的是新保守的興起,與婦運反挫時代的來臨。

    + +

    以下參考中譯來自銀河西洋音樂城,簡介部份則整理自銀河西洋音樂城及其它中英相關網站的介紹。

    + +
    + +I’Ve Never Been To Me
    +我從未找到過自我
    +(Written by Ken Kirsch and Ronald Miller)
    +
    +Hey lady, you lady, cursing at your life
    +嘿,這位太太,你這對自己的生命充滿怨恨的太太
    +You’re a discontented mother and a regimented wife
    +你是個不滿現實的母親,是個失去自由的妻子
    +I’ve no doubt you dream about the things you’ll never do
    +我深信你夢想著那些你永遠無法作的事
    +But I wish someone had talked to me like I wanna talk to you
    +但我真希望有人曾經對我說過現在我想告訴你的事
    +
    +Oh, I’ve been to Georgia and California and anywhere I could run
    +啊,我曾到過喬治亞、到過加州,還有任何我可以去到的地方
    +I took the hand of a preacher man and we made love in the sun
    +我牽過一個神職男人的手,一起在陽光下纏綿
    +But I ran out of places and friendly faces because I had to be free
    +但如今我已無處可去、也沒有朋友,只因為當初我非得自由
    +I’ve been to paradise but I’ve never been to me
    +我曾經到過天堂,但我從未找到過自我
    +
    +Please lady, please lady, don’t just walk away
    +求求你,這位太太,求求你,別就這樣走開
    +’Cause I have this need to tell you why I’m all alone today
    +因為我希望能告訴你,為什麼今天我會如此孤獨
    +I can see so much of me still living in your eyes
    +我可以在你的眼中看到太多過去的我
    +Won’t you share a part of a weary heart that has lived a million lies....
    +可否請你分享一些我這曾經活在千萬謊言中的疲倦心情
    +
    +Oh, I’ve been to Niece and the Isle of Greece while I’ve sipped champagne on a yacht
    +啊,我曾到過尼斯和希臘的島嶼,坐在遊艇上啜飲著香檳
    +I’ve moved like Harlow in Monte Carlo and showed ’em what I’ve got
    +我曾像是珍哈露般的款擺在蒙地卡羅,秀著我的本錢
    +I’ve been undressed by kings and I’ve seen some things that a woman ain’t supposed to see
    +我曾被王侯寬衣解帶,看過好些普通女人看不到的事情
    +I’ve been to paradise, but I’ve never been to me
    +我曾經到過天堂,但我從未找到過自我
    +
    +[Spoken]
    +(口白)
    +Hey, you know what paradise is? It’s a lie
    +嘿,你知道天堂是什麼?那是個謊言
    +A fantasy we create about people and places as we’d like them to be
    +一種我們創造出來,所有人和所有地方都盡如我們期望的幻想
    +But you know what truth is?
    +但你知道真實是什麼嗎?
    +It’s that little baby you’re holding
    +那就是那個你懷抱中的小寶寶
    +It’s that man you fought with this morning
    +那就是那個今天早上你跟他吵架
    +The same one you’re going to make love with tonight
    +而今晚又將與他纏綿的同一個男人
    +That’s truth, that’s love
    +那就是真實,那就是愛
    +
    +Sometimes I’ve been to crying for unborn children that might have made me complete
    +有時候我曾經為了那我從未生過、或許可以讓我成為完整女人的孩子而哭泣
    +But I took the sweet life, I never knew I’d be bitter from the sweet
    +但我選擇了甜蜜的生活,我從不知道有一天我會由甜轉為苦
    +I’ve spent my life exploring the subtle whoring that costs too much to be free
    +我曾浪費我的生命,探索著那種讓我付出太高代價的、人盡可夫的自由生活
    +Hey lady, I’ve been to paradise, but I’ve never been to me
    +我曾經到過天堂,但我從未找到過自我
    + +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 85 | + 86 | + 87 | + 88 | + 89 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0088.html.en.html b/htdocs/imacat/me/diary/0088.html.en.html new file mode 120000 index 0000000..f1d67dd --- /dev/null +++ b/htdocs/imacat/me/diary/0088.html.en.html @@ -0,0 +1 @@ +0088.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0088.html.en.xhtml b/htdocs/imacat/me/diary/0088.html.en.xhtml new file mode 100644 index 0000000..2114680 --- /dev/null +++ b/htdocs/imacat/me/diary/0088.html.en.xhtml @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 88 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 88

    + +
    + +
    + +
    +
    11.2.’06. 2:27pm.
    + +

    我的新手機 Nokia 6070

    + +
    +我的 Nokia 6070 ,加上果凍套和我喜歡的佈景主題
    +

    我的 Nokia 6070 ,加上果凍套和我喜歡的佈景主題

    +
    + +

    我原來用的手機是 Nokia 3315 ,那時候買空機,沒有綁約,買了三千塊錢左右,用了四、五年了。半年多前數字鍵 6 壞了,很難按,開機 PIN 碼、通訊錄輸入中文、按號碼等等的,都變得很難操作。那時候就想要換一隻新的手機。希望有照相功能。貝殼機也不錯,我因為是 Nokia 黨的,從沒用過貝殼機。可是因為照相手機基本上也不便宜,手頭很緊,所以一直沒有如願,只能將就著用數字鍵 6 壞掉的 3315 。

    + +

    上個星期一筆錢下來,我趕緊去跑和信。我開的條件是:

    + +
      +
    1. Nokia。
    2. +
    3. 有照相功能。
    4. +
    5. 上面兩個條件下,便宜的。
    6. +
    + +

    我去和信的永和門市,也上了和信的網站,看看門號綁手機的優惠,有哪幾支手機。看到了 2100 元的貝殼機 Nokia 6101 ,和 3400 元的貝殼機 Nokia 6103 。詳細了解、比較規格、網路評價後,我決定要買 6103 。

    + +

    上星期五晚上,我領了三千六,跑去和信的館前旗艦門市。問了門市小姐有哪幾支優惠手機後,她拿給我 6101, 6103 和 6070 。

    + +

    我有點愣住了。處女座個性有比較保守的地方,做決定時會猶豫、反復很久,所以喜歡事前先蒐集資料、盤算,給自己比較充裕的時間判斷。要是現場突然出現未預料到的新狀況,會讓我非常恐慌。突然出現的 6070 ,就是這樣。 1500 的價錢,遠低於我的預算。可是我事前完全不了解 6070 、規格、網路評價等,所以完全不知道該怎麼辦。而且 6070 不是貝殼機, Nokia 出的貝殼機不多,要是沒買 6101 或 6103 ,我就跟貝殼機絕緣了。

    + +

    幾經考慮,我還是買下了 6070 。

    + +

    買下了以後,發現還蠻不錯的。其實我以前用的手機 3315 ,就現在來看非常陽春:沒有和絃鈴聲,沒有彩色螢幕,沒有照相功能,沒有桌面背景、螢幕保護。所以光是基本功能的 6070 ,就已經夠多東西可以讓我玩了。而且這樣,我還省下了兩千塊錢。我唯一的遺憾,就只有沒用過貝殼機而已。

    + +

    不過省下兩千塊錢的事,好像不全然是如此。買下了以後才發現,有了照相功能,就一定要傳輸線。而且傳輸線不但不便宜,還很麻煩! 6070 用的是 CA-42 ,為了這條 CA-42 我跑到快瘋了:一開始不知道要找 CA-42 ,在 Nova 找了一圈,有一家店拿 DKU-5 試出訊號,就 450 要我拿回去了。可是我拿回去,怎麼裝都裝不起來,在網路上找了一整晚,才發現說明書上就有說要用 CA-42 。隔天星期六,跑回 Nova 把 DKU-5 換成神腦資詠 MOMEX 的 CA-42 ,拿回去還是裝不起來,而且手機上還有不相容的訊息。這次我找到了 Nokia 客服專線, Nokia 專線說,相容的傳輸線,接上去不會有任何相不相容的訊息,而且 Nokia PC Suite 內建驅動程式,原廠傳輸線不需另外安裝任何驅動程式。那也就是說,我這條盒子上寫 CA-42 的線不是 CA-42 。這真是太扯了。我又拿回去 Nova 換。這次現場試,換了一條接上去沒有訊息的。拿回來,終於可以用了,雖然不知道為什麼只能固定用一個 USB 接孔,還不大穩,常常當機。備份了一些資料後,弄了一個晚上,深夜當機後,我就放著不管,先去睡了。

    + +

    星期天一起床,整台電腦都當機了。重開機後,完全不能用了。我解安裝再重新安裝,刪乾淨前次安裝的所有檔案,試了七八次,搞了一整天,都不能用。我想起刪檔前有注意到, CA-42 有新增一個 Turbo8088 的 USB-to-COM 轉成的 COM3 連接埠,好像要用一個 ser120.sys 。可是 Turbo8088 的驅動程式是從 DKU-5 的驅動程式光碟上找到的,那是我星期六沒刪乾淨的結果, MOMEX 的 CA-42 根本沒附驅動程式光碟,依包裝上的網址下載資詠的 CA-42 驅動程式,也裝不起來。找不到 ser120.sys ,搞了兩天搞不定,我快哭了。上 eMule 找 ser120.sys ,找到的是 OTi 6858 的,找不到 Turbo8088 的,而且驅動程式是裝上去了, Nokia PC Suite 還是抓不到。我下定決心,不管這條 MOMEX 的 CA-42 了,要去買 Nokia 原廠的。當天晚上我騎著車,到家裏附近的通訊行找找不到,到遠一點之前中華電信營業處附近有很多通訊行的地方找,也找不到,到公館有很多通訊行的地方找,也找不到,殺回 Nova 找,誰知道這次原先跟我說有原廠傳輸線的店家,真的要買才都發現沒貨,殺到光華商場,也還是沒有。我不知道一條 Nokia 原廠 CA-42 這麼難找,找遍半個台北都找不到!我想到 Nokia 客服專線,打電話去問,轉到 Nokia 台北維修服務中心,終於有現貨了,不過一條要— 1600 元!

    + +

    我心涼了。我已經有步想到沒步了。我不可能花比手機貴的錢去買傳輸線。回家的路上,左想右想,還有兩條路:

    + +
      +
    1. 上網找網路上賣的 Nokia 原廠 CA-42 ,說不定有店家便宜賣。
    2. +
    3. 找神腦負責這條不能動的 MOMEX CA-42 。
    4. +
    + +

    回家上網找,竟然在網拍上找到有店家賣原廠 CA-42 ,而且只賣 400 。我趕緊打電話去問,約好去看。可是賣得那麼便宜,怎麼想都覺得有問題。隔天星期一我還是暫時跟他取消了。星期一晚上,我依 MOMEX CA-42 包裝上的電話 (02) 2976-8818 打過去,電話那頭聽我找神腦,好像有點困惑。(這個電話號碼,網路上查是耀鴻國際。耀鴻又是什麼?神腦代理商的代理商?)不過他們答應我星期二晚上拿一條傳輸線來跟我換。晚上我再上網找,有人提到有一套 LogoManagerMobiMB Mobile Media Browser ,還不錯用。我下載來裝上去,發現這次可以連上手機,還可以傳輸檔案了!耶~!試了一個晚上沒有問題,隔天我趕緊跟神腦取消,請他們不用再多跑一趟了。

    + +

    MobiMB 用了兩三天了,都沒什麼問題。我發現 MobiMB 還真的很好用,比 Nokia 的 PC Suite 好用得多了,穩定得多,而且中文好像也可以支援。 Nokia 果然是做手機的,說到電腦程式,真的就不行了。我現在裝的是這樣:

    + +
      +
    1. 手機傳輸線是神腦資詠 MOMEX 的 CA-42 ,用 OTiser120.sys 驅動程式,把 USB 模擬為 COM3 來接。
    2. +
    3. 傳輸程式用 LogoManagerMobiMB Mobile Media Browser
    4. +
    + +

    USB 模擬為 COM 來用,把新的東西模擬成舊的來用,聽起來是蠻蠢的做法。好像是在 Nokia 對 USB 還不熟悉時,才會想到的笨方法。唉,誰叫 6070 是舊規格的便宜手機呢!

    + +

    這麼看來,這條 MOMEX CA-42 傳輸線裏的晶片真的是 OTi 瀚邦的。原來傳輸線裏還可以有晶片,這我是第一次看到,也算是上了一課。各家不同傳輸線可能會用不同的晶片,要用不同的驅動程式。這大概就是 Nokia PC Suite 一直跑不起來的原因。

    + +

    其實 MobiMB 功能還不完全,無法傳輸簡訊和通訊錄。要傳輸簡訊和通訊錄,要用另一套 LogoManagerMobius/PX 才行。不過我現在還沒有辦法裝上可以用的 Mobius/PX

    + +

    星期二晚上,又花了一個晚上,上網找手機的佈景主題,在 ZonaNokia.com / .org 找到很多很漂亮、很有現代感的佈景主題。下載了以後發現不能用,發現 Nokia 的佈景主題 .nth 檔只是單純的 zip 壓縮檔,解壓縮後,刪掉 6070 用不到的符號圖,修改 XML 檔,再重新壓縮,把檔案縮小,就可以用了。鈴聲,我則是去找了整首安室奈美恵Can You Celebrate?伊藤由奈Endless StoryQueenWe Will Rock You ,還有很久以前下載的百戰天龍 MacGyver 的主題曲的 MIDI 檔。我喜歡的歌,只要找得到能在 6070 上播的 MIDI 檔,都放上去了。可惜找不到 Olivia Newton JohnPhysical 可以在 6070 手機上播放的版本。

    + +

    我還買了一個果凍套。我之前只知道手機膠套,不知道有果凍套這種東西。星期天經過家裏附近的通訊行,想到還沒有買膠套保護,也還沒有貼螢幕護膜,走進去看,老闆就跟我介紹果凍套。我看了覺得很新奇。可是套上去手機原本的顏色就看不到了,而且果凍套一個要一百五,我已經花夠多錢在這支手機上了,螢幕護膜也還要一百五,想想就算了,買普通的膠套。誰知道買回去以後, 6070 的中間鍵是凹下去的,四周有四個突起來的方向按鍵,膠套不夠貼,就很難按到中間鍵了。這樣,裝了膠套,手機幾乎無法使用。熬了兩三天,星期二晚上終於受不了了,下班路上跑去通訊行問果凍套。沒想到果凍套雖然厚,套起來卻非常貼,比膠套操作起來靈敏很多。原先中間鍵按不到的問題迎刃而解。高興之餘,我買了一個貴一點的,防塵材質的果凍套,兩百塊錢。老闆一臉:看,我早跟妳說過了吧~妳就不相信我吧~的表情。

    + +

    總計,手機 1540 元,傳輸線 450 元,多買兩個旅充 200×2=400 元,螢幕護膜 150 ,膠套 30 ,果凍套 200 ,加起來花了 2770 。配件的花費,比我想的還要多很多。時間的花費,則是數不清了。

    + +

    不過花了一個星期,終於有一支漂亮的新手機了!耶~! ^_*'

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 86 | + 87 | + 88 | + 89 | + 90 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0088.html.zh-cn.html b/htdocs/imacat/me/diary/0088.html.zh-cn.html new file mode 120000 index 0000000..81b223a --- /dev/null +++ b/htdocs/imacat/me/diary/0088.html.zh-cn.html @@ -0,0 +1 @@ +0088.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0088.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0088.html.zh-cn.xhtml new file mode 100644 index 0000000..82adf8c --- /dev/null +++ b/htdocs/imacat/me/diary/0088.html.zh-cn.xhtml @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷八十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷八十八

    + +
    + +
    + +
    +
    11.2.’06. 2:27pm.
    + +

    我的新手机 Nokia 6070

    + +
    +我的 Nokia 6070 ,加上果冻套和我喜欢的布景主题
    +

    我的 Nokia 6070 ,加上果冻套和我喜欢的布景主题

    +
    + +

    我原来用的手机是 Nokia 3315 ,那时候买空机,没有绑约,买了三千块钱左右,用了四、五年了。半年多前数字键 6 坏了,很难按,开机 PIN 码、通讯录输入中文、按号码等等的,都变得很难操作。那时候就想要换一只新的手机。希望有照相功能。贝壳机也不错,我因为是 Nokia 党的,从没用过贝壳机。可是因为照相手机基本上也不便宜,手头很紧,所以一直没有如愿,只能将就著用数字键 6 坏掉的 3315 。

    + +

    上个星期一笔钱下来,我赶紧去跑和信。我开的条件是:

    + +
      +
    1. Nokia。
    2. +
    3. 有照相功能。
    4. +
    5. 上面两个条件下,便宜的。
    6. +
    + +

    我去和信的永和门市,也上了和信的网站,看看门号绑手机的优惠,有哪几支手机。看到了 2100 元的贝壳机 Nokia 6101 ,和 3400 元的贝壳机 Nokia 6103 。详细了解、比较规格、网路评价后,我决定要买 6103 。

    + +

    上星期五晚上,我领了三千六,跑去和信的馆前旗舰门市。问了门市小姐有哪几支优惠手机后,她拿给我 6101, 6103 和 6070 。

    + +

    我有点愣住了。处女座个性有比较保守的地方,做决定时会犹豫、反复很久,所以喜欢事前先搜集资料、盘算,给自己比较充裕的时间判断。要是现场突然出现未预料到的新状况,会让我非常恐慌。突然出现的 6070 ,就是这样。 1500 的价钱,远低於我的预算。可是我事前完全不了解 6070 、规格、网路评价等,所以完全不知道该怎么办。而且 6070 不是贝壳机, Nokia 出的贝壳机不多,要是没买 6101 或 6103 ,我就跟贝壳机绝缘了。

    + +

    几经考虑,我还是买下了 6070 。

    + +

    买下了以后,发现还蛮不错的。其实我以前用的手机 3315 ,就现在来看非常阳春:没有和弦铃声,没有彩色萤幕,没有照相功能,没有桌面背景、萤幕保护。所以光是基本功能的 6070 ,就已经够多东西可以让我玩了。而且这样,我还省下了两千块钱。我唯一的遗憾,就只有没用过贝壳机而已。

    + +

    不过省下两千块钱的事,好像不全然是如此。买下了以后才发现,有了照相功能,就一定要传输线。而且传输线不但不便宜,还很麻烦! 6070 用的是 CA-42 ,为了这条 CA-42 我跑到快疯了:一开始不知道要找 CA-42 ,在 Nova 找了一圈,有一家店拿 DKU-5 试出讯号,就 450 要我拿回去了。可是我拿回去,怎么装都装不起来,在网路上找了一整晚,才发现说明书上就有说要用 CA-42 。隔天星期六,跑回 Nova 把 DKU-5 换成神脑资咏 MOMEX 的 CA-42 ,拿回去还是装不起来,而且手机上还有不相容的讯息。这次我找到了 Nokia 客服专线, Nokia 专线说,相容的传输线,接上去不会有任何相不相容的讯息,而且 Nokia PC Suite 内建驱动程式,原厂传输线不需另外安装任何驱动程式。那也就是说,我这条盒子上写 CA-42 的线不是 CA-42 。这真是太扯了。我又拿回去 Nova 换。这次现场试,换了一条接上去没有讯息的。拿回来,终於可以用了,虽然不知道为什么只能固定用一个 USB 接孔,还不大稳,常常当机。备份了一些资料后,弄了一个晚上,深夜当机后,我就放著不管,先去睡了。

    + +

    星期天一起床,整台电脑都当机了。重开机后,完全不能用了。我解安装再重新安装,删干净前次安装的所有档案,试了七八次,搞了一整天,都不能用。我想起删档前有注意到, CA-42 有新增一个 Turbo8088 的 USB-to-COM 转成的 COM3 连接埠,好像要用一个 ser120.sys 。可是 Turbo8088 的驱动程式是从 DKU-5 的驱动程式光碟上找到的,那是我星期六没删干净的结果, MOMEX 的 CA-42 根本没附驱动程式光碟,依包装上的网址下载资咏的 CA-42 驱动程式,也装不起来。找不到 ser120.sys ,搞了两天搞不定,我快哭了。上 eMule 找 ser120.sys ,找到的是 OTi 6858 的,找不到 Turbo8088 的,而且驱动程式是装上去了, Nokia PC Suite 还是抓不到。我下定决心,不管这条 MOMEX 的 CA-42 了,要去买 Nokia 原厂的。当天晚上我骑著车,到家里附近的通讯行找找不到,到远一点之前中华电信营业处附近有很多通讯行的地方找,也找不到,到公馆有很多通讯行的地方找,也找不到,杀回 Nova 找,谁知道这次原先跟我说有原厂传输线的店家,真的要买才都发现没货,杀到光华商场,也还是没有。我不知道一条 Nokia 原厂 CA-42 这么难找,找遍半个台北都找不到!我想到 Nokia 客服专线,打电话去问,转到 Nokia 台北维修服务中心,终於有现货了,不过一条要— 1600 元!

    + +

    我心凉了。我已经有步想到没步了。我不可能花比手机贵的钱去买传输线。回家的路上,左想右想,还有两条路:

    + +
      +
    1. 上网找网路上卖的 Nokia 原厂 CA-42 ,说不定有店家便宜卖。
    2. +
    3. 找神脑负责这条不能动的 MOMEX CA-42 。
    4. +
    + +

    回家上网找,竟然在网拍上找到有店家卖原厂 CA-42 ,而且只卖 400 。我赶紧打电话去问,约好去看。可是卖得那么便宜,怎么想都觉得有问题。隔天星期一我还是暂时跟他取消了。星期一晚上,我依 MOMEX CA-42 包装上的电话 (02) 2976-8818 打过去,电话那头听我找神脑,好像有点困惑。(这个电话号码,网路上查是耀鸿国际。耀鸿又是什么?神脑代理商的代理商?)不过他们答应我星期二晚上拿一条传输线来跟我换。晚上我再上网找,有人提到有一套 LogoManagerMobiMB Mobile Media Browser ,还不错用。我下载来装上去,发现这次可以连上手机,还可以传输档案了!耶~!试了一个晚上没有问题,隔天我赶紧跟神脑取消,请他们不用再多跑一趟了。

    + +

    MobiMB 用了两三天了,都没什么问题。我发现 MobiMB 还真的很好用,比 Nokia 的 PC Suite 好用得多了,稳定得多,而且中文好像也可以支援。 Nokia 果然是做手机的,说到电脑程式,真的就不行了。我现在装的是这样:

    + +
      +
    1. 手机传输线是神脑资咏 MOMEX 的 CA-42 ,用 OTiser120.sys 驱动程式,把 USB 模拟为 COM3 来接。
    2. +
    3. 传输程式用 LogoManagerMobiMB Mobile Media Browser
    4. +
    + +

    USB 模拟为 COM 来用,把新的东西模拟成旧的来用,听起来是蛮蠢的做法。好像是在 Nokia 对 USB 还不熟悉时,才会想到的笨方法。唉,谁叫 6070 是旧规格的便宜手机呢!

    + +

    这么看来,这条 MOMEX CA-42 传输线里的晶片真的是 OTi 瀚邦的。原来传输线里还可以有晶片,这我是第一次看到,也算是上了一课。各家不同传输线可能会用不同的晶片,要用不同的驱动程式。这大概就是 Nokia PC Suite 一直跑不起来的原因。

    + +

    其实 MobiMB 功能还不完全,无法传输简讯和通讯录。要传输简讯和通讯录,要用另一套 LogoManagerMobius/PX 才行。不过我现在还没有办法装上可以用的 Mobius/PX

    + +

    星期二晚上,又花了一个晚上,上网找手机的布景主题,在 ZonaNokia.com / .org 找到很多很漂亮、很有现代感的布景主题。下载了以后发现不能用,发现 Nokia 的布景主题 .nth 档只是单纯的 zip 压缩档,解压缩后,删掉 6070 用不到的符号图,修改 XML 档,再重新压缩,把档案缩小,就可以用了。铃声,我则是去找了整首安室奈美恵Can You Celebrate?伊藤由奈Endless StoryQueenWe Will Rock You ,还有很久以前下载的百战天龙 MacGyver 的主题曲的 MIDI 档。我喜欢的歌,只要找得到能在 6070 上播的 MIDI 档,都放上去了。可惜找不到 Olivia Newton JohnPhysical 可以在 6070 手机上播放的版本。

    + +

    我还买了一个果冻套。我之前只知道手机胶套,不知道有果冻套这种东西。星期天经过家里附近的通讯行,想到还没有买胶套保护,也还没有贴萤幕护膜,走进去看,老板就跟我介绍果冻套。我看了觉得很新奇。可是套上去手机原本的颜色就看不到了,而且果冻套一个要一百五,我已经花够多钱在这支手机上了,萤幕护膜也还要一百五,想想就算了,买普通的胶套。谁知道买回去以后, 6070 的中间键是凹下去的,四周有四个突起来的方向按键,胶套不够贴,就很难按到中间键了。这样,装了胶套,手机几乎无法使用。熬了两三天,星期二晚上终於受不了了,下班路上跑去通讯行问果冻套。没想到果冻套虽然厚,套起来却非常贴,比胶套操作起来灵敏很多。原先中间键按不到的问题迎刃而解。高兴之余,我买了一个贵一点的,防尘材质的果冻套,两百块钱。老板一脸:看,我早跟你说过了吧~你就不相信我吧~的表情。

    + +

    总计,手机 1540 元,传输线 450 元,多买两个旅充 200×2=400 元,萤幕护膜 150 ,胶套 30 ,果冻套 200 ,加起来花了 2770 。配件的花费,比我想的还要多很多。时间的花费,则是数不清了。

    + +

    不过花了一个星期,终於有一支漂亮的新手机了!耶~! ^_*'

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 86 | + 87 | + 88 | + 89 | + 90 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0088.html.zh-tw.html b/htdocs/imacat/me/diary/0088.html.zh-tw.html new file mode 120000 index 0000000..727152a --- /dev/null +++ b/htdocs/imacat/me/diary/0088.html.zh-tw.html @@ -0,0 +1 @@ +0088.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0088.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0088.html.zh-tw.xhtml new file mode 100644 index 0000000..c65a3b2 --- /dev/null +++ b/htdocs/imacat/me/diary/0088.html.zh-tw.xhtml @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷八十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷八十八

    + +
    + +
    + +
    +
    11.2.’06. 2:27pm.
    + +

    我的新手機 Nokia 6070

    + +
    +我的 Nokia 6070 ,加上果凍套和我喜歡的佈景主題
    +

    我的 Nokia 6070 ,加上果凍套和我喜歡的佈景主題

    +
    + +

    我原來用的手機是 Nokia 3315 ,那時候買空機,沒有綁約,買了三千塊錢左右,用了四、五年了。半年多前數字鍵 6 壞了,很難按,開機 PIN 碼、通訊錄輸入中文、按號碼等等的,都變得很難操作。那時候就想要換一隻新的手機。希望有照相功能。貝殼機也不錯,我因為是 Nokia 黨的,從沒用過貝殼機。可是因為照相手機基本上也不便宜,手頭很緊,所以一直沒有如願,只能將就著用數字鍵 6 壞掉的 3315 。

    + +

    上個星期一筆錢下來,我趕緊去跑和信。我開的條件是:

    + +
      +
    1. Nokia。
    2. +
    3. 有照相功能。
    4. +
    5. 上面兩個條件下,便宜的。
    6. +
    + +

    我去和信的永和門市,也上了和信的網站,看看門號綁手機的優惠,有哪幾支手機。看到了 2100 元的貝殼機 Nokia 6101 ,和 3400 元的貝殼機 Nokia 6103 。詳細了解、比較規格、網路評價後,我決定要買 6103 。

    + +

    上星期五晚上,我領了三千六,跑去和信的館前旗艦門市。問了門市小姐有哪幾支優惠手機後,她拿給我 6101, 6103 和 6070 。

    + +

    我有點愣住了。處女座個性有比較保守的地方,做決定時會猶豫、反復很久,所以喜歡事前先蒐集資料、盤算,給自己比較充裕的時間判斷。要是現場突然出現未預料到的新狀況,會讓我非常恐慌。突然出現的 6070 ,就是這樣。 1500 的價錢,遠低於我的預算。可是我事前完全不了解 6070 、規格、網路評價等,所以完全不知道該怎麼辦。而且 6070 不是貝殼機, Nokia 出的貝殼機不多,要是沒買 6101 或 6103 ,我就跟貝殼機絕緣了。

    + +

    幾經考慮,我還是買下了 6070 。

    + +

    買下了以後,發現還蠻不錯的。其實我以前用的手機 3315 ,就現在來看非常陽春:沒有和絃鈴聲,沒有彩色螢幕,沒有照相功能,沒有桌面背景、螢幕保護。所以光是基本功能的 6070 ,就已經夠多東西可以讓我玩了。而且這樣,我還省下了兩千塊錢。我唯一的遺憾,就只有沒用過貝殼機而已。

    + +

    不過省下兩千塊錢的事,好像不全然是如此。買下了以後才發現,有了照相功能,就一定要傳輸線。而且傳輸線不但不便宜,還很麻煩! 6070 用的是 CA-42 ,為了這條 CA-42 我跑到快瘋了:一開始不知道要找 CA-42 ,在 Nova 找了一圈,有一家店拿 DKU-5 試出訊號,就 450 要我拿回去了。可是我拿回去,怎麼裝都裝不起來,在網路上找了一整晚,才發現說明書上就有說要用 CA-42 。隔天星期六,跑回 Nova 把 DKU-5 換成神腦資詠 MOMEX 的 CA-42 ,拿回去還是裝不起來,而且手機上還有不相容的訊息。這次我找到了 Nokia 客服專線, Nokia 專線說,相容的傳輸線,接上去不會有任何相不相容的訊息,而且 Nokia PC Suite 內建驅動程式,原廠傳輸線不需另外安裝任何驅動程式。那也就是說,我這條盒子上寫 CA-42 的線不是 CA-42 。這真是太扯了。我又拿回去 Nova 換。這次現場試,換了一條接上去沒有訊息的。拿回來,終於可以用了,雖然不知道為什麼只能固定用一個 USB 接孔,還不大穩,常常當機。備份了一些資料後,弄了一個晚上,深夜當機後,我就放著不管,先去睡了。

    + +

    星期天一起床,整台電腦都當機了。重開機後,完全不能用了。我解安裝再重新安裝,刪乾淨前次安裝的所有檔案,試了七八次,搞了一整天,都不能用。我想起刪檔前有注意到, CA-42 有新增一個 Turbo8088 的 USB-to-COM 轉成的 COM3 連接埠,好像要用一個 ser120.sys 。可是 Turbo8088 的驅動程式是從 DKU-5 的驅動程式光碟上找到的,那是我星期六沒刪乾淨的結果, MOMEX 的 CA-42 根本沒附驅動程式光碟,依包裝上的網址下載資詠的 CA-42 驅動程式,也裝不起來。找不到 ser120.sys ,搞了兩天搞不定,我快哭了。上 eMule 找 ser120.sys ,找到的是 OTi 6858 的,找不到 Turbo8088 的,而且驅動程式是裝上去了, Nokia PC Suite 還是抓不到。我下定決心,不管這條 MOMEX 的 CA-42 了,要去買 Nokia 原廠的。當天晚上我騎著車,到家裏附近的通訊行找找不到,到遠一點之前中華電信營業處附近有很多通訊行的地方找,也找不到,到公館有很多通訊行的地方找,也找不到,殺回 Nova 找,誰知道這次原先跟我說有原廠傳輸線的店家,真的要買才都發現沒貨,殺到光華商場,也還是沒有。我不知道一條 Nokia 原廠 CA-42 這麼難找,找遍半個台北都找不到!我想到 Nokia 客服專線,打電話去問,轉到 Nokia 台北維修服務中心,終於有現貨了,不過一條要— 1600 元!

    + +

    我心涼了。我已經有步想到沒步了。我不可能花比手機貴的錢去買傳輸線。回家的路上,左想右想,還有兩條路:

    + +
      +
    1. 上網找網路上賣的 Nokia 原廠 CA-42 ,說不定有店家便宜賣。
    2. +
    3. 找神腦負責這條不能動的 MOMEX CA-42 。
    4. +
    + +

    回家上網找,竟然在網拍上找到有店家賣原廠 CA-42 ,而且只賣 400 。我趕緊打電話去問,約好去看。可是賣得那麼便宜,怎麼想都覺得有問題。隔天星期一我還是暫時跟他取消了。星期一晚上,我依 MOMEX CA-42 包裝上的電話 (02) 2976-8818 打過去,電話那頭聽我找神腦,好像有點困惑。(這個電話號碼,網路上查是耀鴻國際。耀鴻又是什麼?神腦代理商的代理商?)不過他們答應我星期二晚上拿一條傳輸線來跟我換。晚上我再上網找,有人提到有一套 LogoManagerMobiMB Mobile Media Browser ,還不錯用。我下載來裝上去,發現這次可以連上手機,還可以傳輸檔案了!耶~!試了一個晚上沒有問題,隔天我趕緊跟神腦取消,請他們不用再多跑一趟了。

    + +

    MobiMB 用了兩三天了,都沒什麼問題。我發現 MobiMB 還真的很好用,比 Nokia 的 PC Suite 好用得多了,穩定得多,而且中文好像也可以支援。 Nokia 果然是做手機的,說到電腦程式,真的就不行了。我現在裝的是這樣:

    + +
      +
    1. 手機傳輸線是神腦資詠 MOMEX 的 CA-42 ,用 OTiser120.sys 驅動程式,把 USB 模擬為 COM3 來接。
    2. +
    3. 傳輸程式用 LogoManagerMobiMB Mobile Media Browser
    4. +
    + +

    USB 模擬為 COM 來用,把新的東西模擬成舊的來用,聽起來是蠻蠢的做法。好像是在 Nokia 對 USB 還不熟悉時,才會想到的笨方法。唉,誰叫 6070 是舊規格的便宜手機呢!

    + +

    這麼看來,這條 MOMEX CA-42 傳輸線裏的晶片真的是 OTi 瀚邦的。原來傳輸線裏還可以有晶片,這我是第一次看到,也算是上了一課。各家不同傳輸線可能會用不同的晶片,要用不同的驅動程式。這大概就是 Nokia PC Suite 一直跑不起來的原因。

    + +

    其實 MobiMB 功能還不完全,無法傳輸簡訊和通訊錄。要傳輸簡訊和通訊錄,要用另一套 LogoManagerMobius/PX 才行。不過我現在還沒有辦法裝上可以用的 Mobius/PX

    + +

    星期二晚上,又花了一個晚上,上網找手機的佈景主題,在 ZonaNokia.com / .org 找到很多很漂亮、很有現代感的佈景主題。下載了以後發現不能用,發現 Nokia 的佈景主題 .nth 檔只是單純的 zip 壓縮檔,解壓縮後,刪掉 6070 用不到的符號圖,修改 XML 檔,再重新壓縮,把檔案縮小,就可以用了。鈴聲,我則是去找了整首安室奈美恵Can You Celebrate?伊藤由奈Endless StoryQueenWe Will Rock You ,還有很久以前下載的百戰天龍 MacGyver 的主題曲的 MIDI 檔。我喜歡的歌,只要找得到能在 6070 上播的 MIDI 檔,都放上去了。可惜找不到 Olivia Newton JohnPhysical 可以在 6070 手機上播放的版本。

    + +

    我還買了一個果凍套。我之前只知道手機膠套,不知道有果凍套這種東西。星期天經過家裏附近的通訊行,想到還沒有買膠套保護,也還沒有貼螢幕護膜,走進去看,老闆就跟我介紹果凍套。我看了覺得很新奇。可是套上去手機原本的顏色就看不到了,而且果凍套一個要一百五,我已經花夠多錢在這支手機上了,螢幕護膜也還要一百五,想想就算了,買普通的膠套。誰知道買回去以後, 6070 的中間鍵是凹下去的,四周有四個突起來的方向按鍵,膠套不夠貼,就很難按到中間鍵了。這樣,裝了膠套,手機幾乎無法使用。熬了兩三天,星期二晚上終於受不了了,下班路上跑去通訊行問果凍套。沒想到果凍套雖然厚,套起來卻非常貼,比膠套操作起來靈敏很多。原先中間鍵按不到的問題迎刃而解。高興之餘,我買了一個貴一點的,防塵材質的果凍套,兩百塊錢。老闆一臉:看,我早跟妳說過了吧~妳就不相信我吧~的表情。

    + +

    總計,手機 1540 元,傳輸線 450 元,多買兩個旅充 200×2=400 元,螢幕護膜 150 ,膠套 30 ,果凍套 200 ,加起來花了 2770 。配件的花費,比我想的還要多很多。時間的花費,則是數不清了。

    + +

    不過花了一個星期,終於有一支漂亮的新手機了!耶~! ^_*'

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 86 | + 87 | + 88 | + 89 | + 90 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0089.html.en.html b/htdocs/imacat/me/diary/0089.html.en.html new file mode 120000 index 0000000..dd0c8b0 --- /dev/null +++ b/htdocs/imacat/me/diary/0089.html.en.html @@ -0,0 +1 @@ +0089.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0089.html.en.xhtml b/htdocs/imacat/me/diary/0089.html.en.xhtml new file mode 100644 index 0000000..88bfe73 --- /dev/null +++ b/htdocs/imacat/me/diary/0089.html.en.xhtml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 89 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 89

    + +
    + +
    + +
    +
    11.3.’06. 5:25am.
    + +

    我的第一筆投資—盛華 2000 高科技基金

    + +

    上個月多下來一些錢,付了該付的帳單、買了該買的東西以後,剩下的錢,就想要存起來。

    + +

    上個學期空大修了一門課:個人投資規劃,學了一些基本的投資知識。我想,像我這樣不是財經專業的人,沒有時間整天盯著市場行情看,共同基金,是最適合我的方式。付一筆經理費,請專業操盤手幫我操盤,比起我一個人花時間摸索,還要有效益。而且共同基金集合眾人資金,總金額大,可以一次買幾十檔,分散風險。我對金錢保守,每天看著賺賠上下,真的對我心臟不好。最好是做長線,拜託專業經理人操盤,半年幾個月再評估一次就好了。

    + +

    上個星期,我便開始看共同基金。中華民國證券投資信託暨顧問商業同業公會,委託台灣大學財務金融學系,每個月定期整理台灣共同基金績效評比。上面的資料非常詳盡,針對 510 檔各國內、外股、債市基金,依公開的經營資料,進行統計、評比,詳列其報酬率、排名、周轉率、各種指數等。我下載了 2006 年 9 月的當月資料,看了一整晚,挑了四檔表現比較好的共同基金:

    + + + +

    幾經比較,我決定買國泰中小成長基金。它的五年報酬率高達 253.00% ,在同類型基金中,一年、兩年、三年、五年排名都在十名以內,經營很穩定,而且一年週轉率只有 24.45% ,殺進殺出的頻率很低,少做短線,風險也低。看它的公開說明書,投資策略也很清楚。日盛上選雖然五年報酬率高達 261.09% ,可是近一年排名落到 50 名,好像不大穩定。群益創新科技報酬率低一些,一年週轉率高達 433.42% ,頻繁進出,太短線了,風險也高。盛華 2000 高科技也不錯,不過還是比不上國泰中小成長基金。

    + +

    於是我星期五一早趕在上班前,拿了存褶,就跑去華南銀行的理財櫃台去了。我從來沒有去過理財櫃台,這是第一次。理財櫃台的專員也不認識我,不過看我投資目標很清楚,也很樂於幫我承做。填幾張表,一下子就好了。他叫我星期一再去拿華銀的信託同意書即可。我沒想到這麼簡單,就高高興興地回去了。

    + +

    誰知道到了下午,他突然打電話來。說國泰中小成長基金額滿了,沒幫我敲到。他請我再自己看看,決定好了的話,星期一再去找他。電話一頭一直跟我道歉,說自己也沒有碰過基金額滿這種情形。

    + +

    這也難怪,經營績效那麼好,大家一定會搶著買。覺得有點可惜之下,我又回頭看基金評比表。不過前一晚看了一整晚,全部 510 檔基金,光看就已經看到昏頭了。我寫了一個小程式,把 Excel 的評比表轉存成 CSV 表後,匯入 PostgreSQL 資料庫,方便篩選、排比。我定了兩個篩選條件:

    + +
      +
    • 五年報酬率在 190% 以上。
    • +
    • 在同類型基金中,一年、兩年、三年、五年排名都在十五名以內。
    • +
    + +

    得出了幾檔基金。再拿標準普爾 2006 台灣基金獎選出的得獎基金比較,重新選出了四檔基金,再排出購買的優先順序。其實,因為基金的經營都是公開資訊,所以不管怎麼評比,得到的結果,大致上都會差不多。

    + +
      +
    1. 科技類:盛華 2000 高科技基金
    2. +
    3. 科技類:建弘電子基金
    4. +
    5. 中小型類:保誠中小型基金
    6. +
    + +

    盛華 2000 高科技基金和建弘電子基金,分別獲得標準普爾 2006 台灣基金獎,科技類的三年期、五年期評比第一名,五年報酬率分別為 227.04% 和 241.65% ,都相當高。不過盛華 2000 高科技基金的排名,比較穩定一些。保誠中小型基金則是標準普爾 2006 台灣基金獎,小型類的五年期評比第一名,五年報酬率 205.13% ,稍低一些。小型類的三年期第一名,是我沒買到的國泰中小成長基金。

    + +

    這次我學聰明了,依優先順序挑了三個,以免額滿又灰頭土臉回來。星期一早上出門有點晚,於是下午才去銀行。不過這次就很順利了,理財顧問幫我順利敲到了盛華 2000 高科技基金,當場就轉帳轉過去了。果然額滿是極少數的特例。離開後順便刷個褶,看著存褶上剩下一萬多,心裏有點興奮。這是我這輩子買的第一筆基金,雖然盛華 2000 高科技基金過去記錄不錯,但未來說不定會賺會賠。

    + +

    星期三晚上,手機的事忙告一段落後,我記得之前小招說過,盛華是國民黨的黨營企業,我就上網查一查相關資訊。盛華投信的主要股東是光華投資,光華投資的主要股東是國民黨,盛華投信算起來跟國民黨是間接的關係。不過經營上倒是蠻獨立的。不過無論如何,重點是基金經理人做得好不好,賺不賺錢,會賺錢比較重要,跟政治其實沒什麼關係。不過看著看著,竟然看到一則讓我有點嚇一跳的新聞:光華投資在今年九月十四日,剛把盛華投信賣給大眾投信。大眾投信的背後是陳田錨的大眾銀行。這個比較可怕一點。換了企業,企業文化改變,說不定會影響基金經理人的操作,過度干涉等等。我竟然之前沒有算到這一層,頗為失算,有點心驚膽跳。希望是我想太多了。基金經理人沒變,基本面沒有變化,不應該被無關的消息動搖信心才對。嗯。

    + +

    說起來蠻有趣的。共同基金和證券不同,集中市場的證券會隨著買賣撮合,而價格變化,買的人多價格就會上揚,賣的人多價格就會下跌。可是共同基金的價格不會隨申購、贖回而變化,只隨它本身操作的證券而變化。就算很多人申購,也不會變貴。不過基金這種東西,淨值價格只是贖回時的憑據,其實變貴也沒有什麼意義。

    + +

    希望能賺大錢。嗯。加油加油~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 87 | + 88 | + 89 | + 90 | + 91 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0089.html.zh-cn.html b/htdocs/imacat/me/diary/0089.html.zh-cn.html new file mode 120000 index 0000000..a14baa1 --- /dev/null +++ b/htdocs/imacat/me/diary/0089.html.zh-cn.html @@ -0,0 +1 @@ +0089.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0089.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0089.html.zh-cn.xhtml new file mode 100644 index 0000000..a33c7da --- /dev/null +++ b/htdocs/imacat/me/diary/0089.html.zh-cn.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷八十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷八十九

    + +
    + +
    + +
    +
    11.3.’06. 5:25am.
    + +

    我的第一笔投资—盛华 2000 高科技基金

    + +

    上个月多下来一些钱,付了该付的帐单、买了该买的东西以后,剩下的钱,就想要存起来。

    + +

    上个学期空大修了一门课:个人投资规划,学了一些基本的投资知识。我想,像我这样不是财经专业的人,没有时间整天盯著市场行情看,共同基金,是最适合我的方式。付一笔经理费,请专业操盘手帮我操盘,比起我一个人花时间摸索,还要有效益。而且共同基金集合众人资金,总金额大,可以一次买几十档,分散风险。我对金钱保守,每天看著赚赔上下,真的对我心脏不好。最好是做长线,拜托专业经理人操盘,半年几个月再评估一次就好了。

    + +

    上个星期,我便开始看共同基金。中华民国证券投资信托暨顾问商业同业公会,委托台湾大学财务金融学系,每个月定期整理台湾共同基金绩效评比。上面的资料非常详尽,针对 510 档各国内、外股、债市基金,依公开的经营资料,进行统计、评比,详列其报酬率、排名、周转率、各种指数等。我下载了 2006 年 9 月的当月资料,看了一整晚,挑了四档表现比较好的共同基金:

    + + + +

    几经比较,我决定买国泰中小成长基金。它的五年报酬率高达 253.00% ,在同类型基金中,一年、两年、三年、五年排名都在十名以内,经营很稳定,而且一年周转率只有 24.45% ,杀进杀出的频率很低,少做短线,风险也低。看它的公开说明书,投资策略也很清楚。日盛上选虽然五年报酬率高达 261.09% ,可是近一年排名落到 50 名,好像不大稳定。群益创新科技报酬率低一些,一年周转率高达 433.42% ,频繁进出,太短线了,风险也高。盛华 2000 高科技也不错,不过还是比不上国泰中小成长基金。

    + +

    於是我星期五一早赶在上班前,拿了存褶,就跑去华南银行的理财柜台去了。我从来没有去过理财柜台,这是第一次。理财柜台的专员也不认识我,不过看我投资目标很清楚,也很乐於帮我承做。填几张表,一下子就好了。他叫我星期一再去拿华银的信托同意书即可。我没想到这么简单,就高高兴兴地回去了。

    + +

    谁知道到了下午,他突然打电话来。说国泰中小成长基金额满了,没帮我敲到。他请我再自己看看,决定好了的话,星期一再去找他。电话一头一直跟我道歉,说自己也没有碰过基金额满这种情形。

    + +

    这也难怪,经营绩效那么好,大家一定会抢著买。觉得有点可惜之下,我又回头看基金评比表。不过前一晚看了一整晚,全部 510 档基金,光看就已经看到昏头了。我写了一个小程式,把 Excel 的评比表转存成 CSV 表后,汇入 PostgreSQL 资料库,方便筛选、排比。我定了两个筛选条件:

    + +
      +
    • 五年报酬率在 190% 以上。
    • +
    • 在同类型基金中,一年、两年、三年、五年排名都在十五名以内。
    • +
    + +

    得出了几档基金。再拿标准普尔 2006 台湾基金奖选出的得奖基金比较,重新选出了四档基金,再排出购买的优先顺序。其实,因为基金的经营都是公开资讯,所以不管怎么评比,得到的结果,大致上都会差不多。

    + +
      +
    1. 科技类:盛华 2000 高科技基金
    2. +
    3. 科技类:建弘电子基金
    4. +
    5. 中小型类:保诚中小型基金
    6. +
    + +

    盛华 2000 高科技基金和建弘电子基金,分别获得标准普尔 2006 台湾基金奖,科技类的三年期、五年期评比第一名,五年报酬率分别为 227.04% 和 241.65% ,都相当高。不过盛华 2000 高科技基金的排名,比较稳定一些。保诚中小型基金则是标准普尔 2006 台湾基金奖,小型类的五年期评比第一名,五年报酬率 205.13% ,稍低一些。小型类的三年期第一名,是我没买到的国泰中小成长基金。

    + +

    这次我学聪明了,依优先顺序挑了三个,以免额满又灰头土脸回来。星期一早上出门有点晚,於是下午才去银行。不过这次就很顺利了,理财顾问帮我顺利敲到了盛华 2000 高科技基金,当场就转帐转过去了。果然额满是极少数的特例。离开后顺便刷个褶,看著存褶上剩下一万多,心里有点兴奋。这是我这辈子买的第一笔基金,虽然盛华 2000 高科技基金过去记录不错,但未来说不定会赚会赔。

    + +

    星期三晚上,手机的事忙告一段落后,我记得之前小招说过,盛华是国民党的党营企业,我就上网查一查相关资讯。盛华投信的主要股东是光华投资,光华投资的主要股东是国民党,盛华投信算起来跟国民党是间接的关系。不过经营上倒是蛮独立的。不过无论如何,重点是基金经理人做得好不好,赚不赚钱,会赚钱比较重要,跟政治其实没什么关系。不过看著看著,竟然看到一则让我有点吓一跳的新闻:光华投资在今年九月十四日,刚把盛华投信卖给大众投信。大众投信的背后是陈田锚的大众银行。这个比较可怕一点。换了企业,企业文化改变,说不定会影响基金经理人的操作,过度干涉等等。我竟然之前没有算到这一层,颇为失算,有点心惊胆跳。希望是我想太多了。基金经理人没变,基本面没有变化,不应该被无关的消息动摇信心才对。嗯。

    + +

    说起来蛮有趣的。共同基金和证券不同,集中市场的证券会随著买卖撮合,而价格变化,买的人多价格就会上扬,卖的人多价格就会下跌。可是共同基金的价格不会随申购、赎回而变化,只随它本身操作的证券而变化。就算很多人申购,也不会变贵。不过基金这种东西,净值价格只是赎回时的凭据,其实变贵也没有什么意义。

    + +

    希望能赚大钱。嗯。加油加油~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 87 | + 88 | + 89 | + 90 | + 91 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0089.html.zh-tw.html b/htdocs/imacat/me/diary/0089.html.zh-tw.html new file mode 120000 index 0000000..1433b3b --- /dev/null +++ b/htdocs/imacat/me/diary/0089.html.zh-tw.html @@ -0,0 +1 @@ +0089.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0089.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0089.html.zh-tw.xhtml new file mode 100644 index 0000000..a7a9752 --- /dev/null +++ b/htdocs/imacat/me/diary/0089.html.zh-tw.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷八十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷八十九

    + +
    + +
    + +
    +
    11.3.’06. 5:25am.
    + +

    我的第一筆投資—盛華 2000 高科技基金

    + +

    上個月多下來一些錢,付了該付的帳單、買了該買的東西以後,剩下的錢,就想要存起來。

    + +

    上個學期空大修了一門課:個人投資規劃,學了一些基本的投資知識。我想,像我這樣不是財經專業的人,沒有時間整天盯著市場行情看,共同基金,是最適合我的方式。付一筆經理費,請專業操盤手幫我操盤,比起我一個人花時間摸索,還要有效益。而且共同基金集合眾人資金,總金額大,可以一次買幾十檔,分散風險。我對金錢保守,每天看著賺賠上下,真的對我心臟不好。最好是做長線,拜託專業經理人操盤,半年幾個月再評估一次就好了。

    + +

    上個星期,我便開始看共同基金。中華民國證券投資信託暨顧問商業同業公會,委託台灣大學財務金融學系,每個月定期整理台灣共同基金績效評比。上面的資料非常詳盡,針對 510 檔各國內、外股、債市基金,依公開的經營資料,進行統計、評比,詳列其報酬率、排名、周轉率、各種指數等。我下載了 2006 年 9 月的當月資料,看了一整晚,挑了四檔表現比較好的共同基金:

    + + + +

    幾經比較,我決定買國泰中小成長基金。它的五年報酬率高達 253.00% ,在同類型基金中,一年、兩年、三年、五年排名都在十名以內,經營很穩定,而且一年週轉率只有 24.45% ,殺進殺出的頻率很低,少做短線,風險也低。看它的公開說明書,投資策略也很清楚。日盛上選雖然五年報酬率高達 261.09% ,可是近一年排名落到 50 名,好像不大穩定。群益創新科技報酬率低一些,一年週轉率高達 433.42% ,頻繁進出,太短線了,風險也高。盛華 2000 高科技也不錯,不過還是比不上國泰中小成長基金。

    + +

    於是我星期五一早趕在上班前,拿了存褶,就跑去華南銀行的理財櫃台去了。我從來沒有去過理財櫃台,這是第一次。理財櫃台的專員也不認識我,不過看我投資目標很清楚,也很樂於幫我承做。填幾張表,一下子就好了。他叫我星期一再去拿華銀的信託同意書即可。我沒想到這麼簡單,就高高興興地回去了。

    + +

    誰知道到了下午,他突然打電話來。說國泰中小成長基金額滿了,沒幫我敲到。他請我再自己看看,決定好了的話,星期一再去找他。電話一頭一直跟我道歉,說自己也沒有碰過基金額滿這種情形。

    + +

    這也難怪,經營績效那麼好,大家一定會搶著買。覺得有點可惜之下,我又回頭看基金評比表。不過前一晚看了一整晚,全部 510 檔基金,光看就已經看到昏頭了。我寫了一個小程式,把 Excel 的評比表轉存成 CSV 表後,匯入 PostgreSQL 資料庫,方便篩選、排比。我定了兩個篩選條件:

    + +
      +
    • 五年報酬率在 190% 以上。
    • +
    • 在同類型基金中,一年、兩年、三年、五年排名都在十五名以內。
    • +
    + +

    得出了幾檔基金。再拿標準普爾 2006 台灣基金獎選出的得獎基金比較,重新選出了四檔基金,再排出購買的優先順序。其實,因為基金的經營都是公開資訊,所以不管怎麼評比,得到的結果,大致上都會差不多。

    + +
      +
    1. 科技類:盛華 2000 高科技基金
    2. +
    3. 科技類:建弘電子基金
    4. +
    5. 中小型類:保誠中小型基金
    6. +
    + +

    盛華 2000 高科技基金和建弘電子基金,分別獲得標準普爾 2006 台灣基金獎,科技類的三年期、五年期評比第一名,五年報酬率分別為 227.04% 和 241.65% ,都相當高。不過盛華 2000 高科技基金的排名,比較穩定一些。保誠中小型基金則是標準普爾 2006 台灣基金獎,小型類的五年期評比第一名,五年報酬率 205.13% ,稍低一些。小型類的三年期第一名,是我沒買到的國泰中小成長基金。

    + +

    這次我學聰明了,依優先順序挑了三個,以免額滿又灰頭土臉回來。星期一早上出門有點晚,於是下午才去銀行。不過這次就很順利了,理財顧問幫我順利敲到了盛華 2000 高科技基金,當場就轉帳轉過去了。果然額滿是極少數的特例。離開後順便刷個褶,看著存褶上剩下一萬多,心裏有點興奮。這是我這輩子買的第一筆基金,雖然盛華 2000 高科技基金過去記錄不錯,但未來說不定會賺會賠。

    + +

    星期三晚上,手機的事忙告一段落後,我記得之前小招說過,盛華是國民黨的黨營企業,我就上網查一查相關資訊。盛華投信的主要股東是光華投資,光華投資的主要股東是國民黨,盛華投信算起來跟國民黨是間接的關係。不過經營上倒是蠻獨立的。不過無論如何,重點是基金經理人做得好不好,賺不賺錢,會賺錢比較重要,跟政治其實沒什麼關係。不過看著看著,竟然看到一則讓我有點嚇一跳的新聞:光華投資在今年九月十四日,剛把盛華投信賣給大眾投信。大眾投信的背後是陳田錨的大眾銀行。這個比較可怕一點。換了企業,企業文化改變,說不定會影響基金經理人的操作,過度干涉等等。我竟然之前沒有算到這一層,頗為失算,有點心驚膽跳。希望是我想太多了。基金經理人沒變,基本面沒有變化,不應該被無關的消息動搖信心才對。嗯。

    + +

    說起來蠻有趣的。共同基金和證券不同,集中市場的證券會隨著買賣撮合,而價格變化,買的人多價格就會上揚,賣的人多價格就會下跌。可是共同基金的價格不會隨申購、贖回而變化,只隨它本身操作的證券而變化。就算很多人申購,也不會變貴。不過基金這種東西,淨值價格只是贖回時的憑據,其實變貴也沒有什麼意義。

    + +

    希望能賺大錢。嗯。加油加油~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 87 | + 88 | + 89 | + 90 | + 91 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0090.html.en.html b/htdocs/imacat/me/diary/0090.html.en.html new file mode 120000 index 0000000..f9e64cd --- /dev/null +++ b/htdocs/imacat/me/diary/0090.html.en.html @@ -0,0 +1 @@ +0090.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0090.html.en.xhtml b/htdocs/imacat/me/diary/0090.html.en.xhtml new file mode 100644 index 0000000..9ee8eb6 --- /dev/null +++ b/htdocs/imacat/me/diary/0090.html.en.xhtml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 90 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 90

    + +
    + +
    + +
    +
    11.4.’06. 6:32am.
    + +

    基金的淨值價格與申購、贖回

    + +

    我讀了一些關於去年金管會處理結構債的問題,發現我的認知好像有點錯誤。基金的淨值價格,不見得完全不會隨客戶的申購、贖回而波動。一般而言,基金不會百分之百都買入證券,會有大約十分之一的流動現金以備用(買進證券、贖回或剛申購尚未操作等等)。若只是平常零散的申購、贖回,不會有什麼影響。碰到大量申購時,依公開說明書投資比例規定,需要大量補足證券時,淨值就會上揚。不過大量申購比較少見。但如果碰到大量贖回,流動現金不足因應時,就需要拋售手中持有證券還給客戶,這時候淨值就會下滑了。這會發生在投資人信心不足的時候。像債券類,因市場利率上揚,導致債券價格下跌,就會發生大量贖回的慘劇。這就是結構債的問題。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 88 | + 89 | + 90 | + 91 | + 92 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0090.html.zh-cn.html b/htdocs/imacat/me/diary/0090.html.zh-cn.html new file mode 120000 index 0000000..6afdc58 --- /dev/null +++ b/htdocs/imacat/me/diary/0090.html.zh-cn.html @@ -0,0 +1 @@ +0090.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0090.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0090.html.zh-cn.xhtml new file mode 100644 index 0000000..49a424a --- /dev/null +++ b/htdocs/imacat/me/diary/0090.html.zh-cn.xhtml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷九十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷九十

    + +
    + +
    + +
    +
    11.4.’06. 6:32am.
    + +

    基金的净值价格与申购、赎回

    + +

    我读了一些关於去年金管会处理结构债的问题,发现我的认知好像有点错误。基金的净值价格,不见得完全不会随客户的申购、赎回而波动。一般而言,基金不会百分之百都买入证券,会有大约十分之一的流动现金以备用(买进证券、赎回或刚申购尚未操作等等)。若只是平常零散的申购、赎回,不会有什么影响。碰到大量申购时,依公开说明书投资比例规定,需要大量补足证券时,净值就会上扬。不过大量申购比较少见。但如果碰到大量赎回,流动现金不足因应时,就需要抛售手中持有证券还给客户,这时候净值就会下滑了。这会发生在投资人信心不足的时候。像债券类,因市场利率上扬,导致债券价格下跌,就会发生大量赎回的惨剧。这就是结构债的问题。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 88 | + 89 | + 90 | + 91 | + 92 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0090.html.zh-tw.html b/htdocs/imacat/me/diary/0090.html.zh-tw.html new file mode 120000 index 0000000..7d0421a --- /dev/null +++ b/htdocs/imacat/me/diary/0090.html.zh-tw.html @@ -0,0 +1 @@ +0090.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0090.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0090.html.zh-tw.xhtml new file mode 100644 index 0000000..cbdfa33 --- /dev/null +++ b/htdocs/imacat/me/diary/0090.html.zh-tw.xhtml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷九十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷九十

    + +
    + +
    + +
    +
    11.4.’06. 6:32am.
    + +

    基金的淨值價格與申購、贖回

    + +

    我讀了一些關於去年金管會處理結構債的問題,發現我的認知好像有點錯誤。基金的淨值價格,不見得完全不會隨客戶的申購、贖回而波動。一般而言,基金不會百分之百都買入證券,會有大約十分之一的流動現金以備用(買進證券、贖回或剛申購尚未操作等等)。若只是平常零散的申購、贖回,不會有什麼影響。碰到大量申購時,依公開說明書投資比例規定,需要大量補足證券時,淨值就會上揚。不過大量申購比較少見。但如果碰到大量贖回,流動現金不足因應時,就需要拋售手中持有證券還給客戶,這時候淨值就會下滑了。這會發生在投資人信心不足的時候。像債券類,因市場利率上揚,導致債券價格下跌,就會發生大量贖回的慘劇。這就是結構債的問題。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 88 | + 89 | + 90 | + 91 | + 92 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0091.html.en.html b/htdocs/imacat/me/diary/0091.html.en.html new file mode 120000 index 0000000..90aea65 --- /dev/null +++ b/htdocs/imacat/me/diary/0091.html.en.html @@ -0,0 +1 @@ +0091.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0091.html.en.xhtml b/htdocs/imacat/me/diary/0091.html.en.xhtml new file mode 100644 index 0000000..815f23c --- /dev/null +++ b/htdocs/imacat/me/diary/0091.html.en.xhtml @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 91 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 91

    + +
    + +
    + +
    +
    11.7.’06. 4:04am.
    + +

    指定用途信託

    + +

    因為我的主要往來銀行是華南銀行,不想到處開戶、到處留資料。之前在摸索基金知識時,想知道該怎麼申購?能不能從華南銀行申購?閱讀各家基金的公開說明書,發現大多數的代銷機構都沒有華南銀行,多少有點失望。可是看到還有一個指定用途信託機構中有列出華南銀行。指定用途信託機構是什麼?這表示可以在華南銀行買得到嗎?上學期學個人投資規劃時沒有學到,上網查也看不出個所以然來。不過華南好像是可以買的吧~我看他們有賣很多基金,完全不像是很少做別人代銷機構的樣子。

    + +

    在華南買下盛華 2000 高科技基金那天,晚上回家突然想到,於是不查指定用途信託機構,改查指定用途信託。這下終於有點眉目了:

    + +
    +
    資料來源:MoneyDJ 理財網
    + +

    指投資人交存給銀行的資金,銀行除依照投資人的契約指定代為處理。投資人將信託資金交給銀行,由銀行依照信託人的指示,代為買賣指定之國外股票、債券或共同基金等有價證券,透過銀行的指定用途資金業務辦理投資事宜,還可以享受它們所提供的各項國際金融投資諮詢服務,是一種較為便利及具效益的投資方式。

    +
    + + +
    +
    資料來源:犇華投信
    + +

    指定用途信託代理收付有何不同?

    + +

    國內金融機構都有基金申辦的業務,而申購方式大致可分為代理收付指定用途信託,這兩者的區別如下:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    代理收付和指定用途信託的區別
    項目代理收付指定用途信託
    客戶群客戶群屬於投信公司客戶群屬於銀行
    資料建檔由銷售機構代轉至投信公司建檔由銀行自行建置客戶資料
    申購名義各投資人自己的名義向投資公司申購基金 由銀行名義向基金公司申購基金
    受益權單位由投信公司依各投資人申購額分配受益權單位數 銀行依據投信公司各基金總分配數,再行分配受益權單位數給各投資人
    投資證明客戶收到投信公司製發之保管條或受益憑證(有價證券) 客戶收到銀行製發之信託資金通知書
    諮詢服務投信公司提供 銀行提供
    + +
    + +

    原來如此。我透過華銀買,所以是用指定用途信託購買。華銀用它的名義申購,再分賣給我。盛華的客戶是華銀,不是我。我是華銀的客戶,不是盛華的客戶。盛華並不對我負責,華銀才對我負責。所以盛華不會每月寄給我對帳單,華銀才會寄給我對帳單。

    + +

    可是這樣,基金已經是找人代理操盤了,中間又隔了一層中間代理人買基金,感覺總是怪怪的。而且我查盛華 2000 高科技基金的公開說明書,上面寫申購手續費是 2% ,可是華銀只跟我收 0.75% 。這是怎麼回事?會不會哪天又跟我跑來要差價 1.25% ?而且銀行幹嘛要做這種事?銀行賺什麼?銀行會不會還要再跟我扣個什麼費用?指定用途信託還會衍生哪些費用

    + +

    於是,我又回頭看看華銀給我的信託契約,又上網找,又打電話去華銀問,才大致上弄清楚。

    + +
      +
    • 華銀之所以可以給我比盛華更低的申購手續費,是因為他們集眾客戶之力買基金,等於是盛華下的大盤,依公開說明書所說,申購金額大時,申購手續費會有優惠。申購 500 萬以上時,手續費只有 15% 。華銀理財專員說,基金手續費目前有五折的優惠,所以是 7.5% 。這可能是盛華和華銀談的代銷條件。不過其實盛華實際跟華銀拿的錢可能更低。所以,透過指定用途信託申購基金,等於是跟盤商買,手續費會比自己申購還要優惠。
    • + +
    • 透過華銀指定用途信託,定時定額轉帳申購,由於轉帳都是轉給華銀,所以轉帳手續費為零。
    • + +
    • 透過華銀指定用途信託,定時定額轉帳申購,每個月的申購手續費一樣是 3000 元的 7.5% 。
    • +
    + +

    我在信託契約上看到另一個扣除費用,叫作通路服務費,怎麼看都看不懂。既然是透過華銀買,那通路自然是指華銀。那這是盛華給華銀銷售的退佣嗎?退佣不是應該是盛華付的嗎?為什麼是要跟我扣呢?而且看我的單筆申購指示單,上面也沒有扣到通路服務費。那這筆是什麼錢?什麼時候會扣到呢?

    + +

    上網查了查,才恍然大悟:通路服務費是海外基金特有的做法,從基金的總資產中撥出一筆給代銷的信託機構,作為退佣,美其名為通路服務費(我看是故意創造新名詞,讓消費者看不懂比較好騙吧~)。通路服務費分為單筆的和每個月固定的費用,其費用是從基金的總資產下去扣。也就是說,一個募集四十億的基金,每個月從四十億中固定扣給代銷的銀行。這是海外基金特有的做法,國內的基金沒有這種做法,所以我沒有扣到這筆錢。

    + +

    海外基金因為有這筆通路服務費,所以國內的銀行理財專員,賣海外基金賣得特別賣力。這也就是為什麼海外基金明明手續費比較高,而且績效也不怎麼樣,可是台灣人還是迷信海外基金迷信得半死;國內基金的經理人做得戰戰兢兢,績效比海外基金好得多,基金還是賣不出去。因為國人多是透過銀行信託購買基金,因此購買時會受理財專員的理財顧問影響很大,理財專員建議海外基金,說海外市場多麼看好,國內市場多亂,大家就都去買海外基金去了。

    + +

    弄清楚了以後,我覺得這真的很黑暗,很惡劣。理財專員提供的理財顧問服務,應該是以客戶利益為前提,協助客戶如何獲取最大投資利益。可是通路服務費的做法,使得理財專員實質上,建議顧客買的是績效不佳、手續費高很多、還要從基金總值中,自己掏腰包給成功哄騙妳的銀行退佣的基金。可是基金的經營績效都是公開資訊,每個月還有績效評比,其實大家都可以上網自己看,自己找經營績效比較好的基金,不需要讓理財專員哄騙。我就是這樣的人,自己找資料、比較,所以沒有犯這種錯。像這樣以自己的理財專業來哄騙人,真的讓人覺得非常黑暗、惡劣。

    + +

    哪有自己掏腰包給騙自己的人,支付給他騙自己的服務的費用的啊?真是可惡!

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 89 | + 90 | + 91 | + 92 | + 93 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0091.html.zh-cn.html b/htdocs/imacat/me/diary/0091.html.zh-cn.html new file mode 120000 index 0000000..3d4c5fc --- /dev/null +++ b/htdocs/imacat/me/diary/0091.html.zh-cn.html @@ -0,0 +1 @@ +0091.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0091.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0091.html.zh-cn.xhtml new file mode 100644 index 0000000..68d8df4 --- /dev/null +++ b/htdocs/imacat/me/diary/0091.html.zh-cn.xhtml @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷九十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷九十一

    + +
    + +
    + +
    +
    11.7.’06. 4:04am.
    + +

    指定用途信托

    + +

    因为我的主要往来银行是华南银行,不想到处开户、到处留资料。之前在摸索基金知识时,想知道该怎么申购?能不能从华南银行申购?阅读各家基金的公开说明书,发现大多数的代销机构都没有华南银行,多少有点失望。可是看到还有一个指定用途信托机构中有列出华南银行。指定用途信托机构是什么?这表示可以在华南银行买得到吗?上学期学个人投资规划时没有学到,上网查也看不出个所以然来。不过华南好像是可以买的吧~我看他们有卖很多基金,完全不像是很少做别人代销机构的样子。

    + +

    在华南买下盛华 2000 高科技基金那天,晚上回家突然想到,於是不查指定用途信托机构,改查指定用途信托。这下终於有点眉目了:

    + +
    +
    资料来源:MoneyDJ 理财网
    + +

    指投资人交存给银行的资金,银行除依照投资人的契约指定代为处理。投资人将信托资金交给银行,由银行依照信托人的指示,代为买卖指定之国外股票、债券或共同基金等有价证券,透过银行的指定用途资金业务办理投资事宜,还可以享受它们所提供的各项国际金融投资谘询服务,是一种较为便利及具效益的投资方式。

    +
    + + +
    +
    资料来源:犇华投信
    + +

    指定用途信托代理收付有何不同?

    + +

    国内金融机构都有基金申办的业务,而申购方式大致可分为代理收付指定用途信托,这两者的区别如下:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    代理收付和指定用途信托的区别
    项目代理收付指定用途信托
    客户群客户群属於投信公司客户群属於银行
    资料建档由销售机构代转至投信公司建档由银行自行建置客户资料
    申购名义各投资人自己的名义向投资公司申购基金 由银行名义向基金公司申购基金
    受益权单位由投信公司依各投资人申购额分配受益权单位数 银行依据投信公司各基金总分配数,再行分配受益权单位数给各投资人
    投资证明客户收到投信公司制发之保管条或受益凭证(有价证券) 客户收到银行制发之信托资金通知书
    谘询服务投信公司提供 银行提供
    + +
    + +

    原来如此。我透过华银买,所以是用指定用途信托购买。华银用它的名义申购,再分卖给我。盛华的客户是华银,不是我。我是华银的客户,不是盛华的客户。盛华并不对我负责,华银才对我负责。所以盛华不会每月寄给我对帐单,华银才会寄给我对帐单。

    + +

    可是这样,基金已经是找人代理操盘了,中间又隔了一层中间代理人买基金,感觉总是怪怪的。而且我查盛华 2000 高科技基金的公开说明书,上面写申购手续费是 2% ,可是华银只跟我收 0.75% 。这是怎么回事?会不会哪天又跟我跑来要差价 1.25% ?而且银行干嘛要做这种事?银行赚什么?银行会不会还要再跟我扣个什么费用?指定用途信托还会衍生哪些费用

    + +

    於是,我又回头看看华银给我的信托契约,又上网找,又打电话去华银问,才大致上弄清楚。

    + +
      +
    • 华银之所以可以给我比盛华更低的申购手续费,是因为他们集众客户之力买基金,等於是盛华下的大盘,依公开说明书所说,申购金额大时,申购手续费会有优惠。申购 500 万以上时,手续费只有 15% 。华银理财专员说,基金手续费目前有五折的优惠,所以是 7.5% 。这可能是盛华和华银谈的代销条件。不过其实盛华实际跟华银拿的钱可能更低。所以,透过指定用途信托申购基金,等於是跟盘商买,手续费会比自己申购还要优惠。
    • + +
    • 透过华银指定用途信托,定时定额转帐申购,由於转帐都是转给华银,所以转帐手续费为零。
    • + +
    • 透过华银指定用途信托,定时定额转帐申购,每个月的申购手续费一样是 3000 元的 7.5% 。
    • +
    + +

    我在信托契约上看到另一个扣除费用,叫作通路服务费,怎么看都看不懂。既然是透过华银买,那通路自然是指华银。那这是盛华给华银销售的退佣吗?退佣不是应该是盛华付的吗?为什么是要跟我扣呢?而且看我的单笔申购指示单,上面也没有扣到通路服务费。那这笔是什么钱?什么时候会扣到呢?

    + +

    上网查了查,才恍然大悟:通路服务费是海外基金特有的做法,从基金的总资产中拨出一笔给代销的信托机构,作为退佣,美其名为通路服务费(我看是故意创造新名词,让消费者看不懂比较好骗吧~)。通路服务费分为单笔的和每个月固定的费用,其费用是从基金的总资产下去扣。也就是说,一个募集四十亿的基金,每个月从四十亿中固定扣给代销的银行。这是海外基金特有的做法,国内的基金没有这种做法,所以我没有扣到这笔钱。

    + +

    海外基金因为有这笔通路服务费,所以国内的银行理财专员,卖海外基金卖得特别卖力。这也就是为什么海外基金明明手续费比较高,而且绩效也不怎么样,可是台湾人还是迷信海外基金迷信得半死;国内基金的经理人做得战战兢兢,绩效比海外基金好得多,基金还是卖不出去。因为国人多是透过银行信托购买基金,因此购买时会受理财专员的理财顾问影响很大,理财专员建议海外基金,说海外市场多么看好,国内市场多乱,大家就都去买海外基金去了。

    + +

    弄清楚了以后,我觉得这真的很黑暗,很恶劣。理财专员提供的理财顾问服务,应该是以客户利益为前提,协助客户如何获取最大投资利益。可是通路服务费的做法,使得理财专员实质上,建议顾客买的是绩效不佳、手续费高很多、还要从基金总值中,自己掏腰包给成功哄骗你的银行退佣的基金。可是基金的经营绩效都是公开资讯,每个月还有绩效评比,其实大家都可以上网自己看,自己找经营绩效比较好的基金,不需要让理财专员哄骗。我就是这样的人,自己找资料、比较,所以没有犯这种错。像这样以自己的理财专业来哄骗人,真的让人觉得非常黑暗、恶劣。

    + +

    哪有自己掏腰包给骗自己的人,支付给他骗自己的服务的费用的啊?真是可恶!

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 89 | + 90 | + 91 | + 92 | + 93 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0091.html.zh-tw.html b/htdocs/imacat/me/diary/0091.html.zh-tw.html new file mode 120000 index 0000000..b446295 --- /dev/null +++ b/htdocs/imacat/me/diary/0091.html.zh-tw.html @@ -0,0 +1 @@ +0091.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0091.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0091.html.zh-tw.xhtml new file mode 100644 index 0000000..8d9e51c --- /dev/null +++ b/htdocs/imacat/me/diary/0091.html.zh-tw.xhtml @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷九十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷九十一

    + +
    + +
    + +
    +
    11.7.’06. 4:04am.
    + +

    指定用途信託

    + +

    因為我的主要往來銀行是華南銀行,不想到處開戶、到處留資料。之前在摸索基金知識時,想知道該怎麼申購?能不能從華南銀行申購?閱讀各家基金的公開說明書,發現大多數的代銷機構都沒有華南銀行,多少有點失望。可是看到還有一個指定用途信託機構中有列出華南銀行。指定用途信託機構是什麼?這表示可以在華南銀行買得到嗎?上學期學個人投資規劃時沒有學到,上網查也看不出個所以然來。不過華南好像是可以買的吧~我看他們有賣很多基金,完全不像是很少做別人代銷機構的樣子。

    + +

    在華南買下盛華 2000 高科技基金那天,晚上回家突然想到,於是不查指定用途信託機構,改查指定用途信託。這下終於有點眉目了:

    + +
    +
    資料來源:MoneyDJ 理財網
    + +

    指投資人交存給銀行的資金,銀行除依照投資人的契約指定代為處理。投資人將信託資金交給銀行,由銀行依照信託人的指示,代為買賣指定之國外股票、債券或共同基金等有價證券,透過銀行的指定用途資金業務辦理投資事宜,還可以享受它們所提供的各項國際金融投資諮詢服務,是一種較為便利及具效益的投資方式。

    +
    + + +
    +
    資料來源:犇華投信
    + +

    指定用途信託代理收付有何不同?

    + +

    國內金融機構都有基金申辦的業務,而申購方式大致可分為代理收付指定用途信託,這兩者的區別如下:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    代理收付和指定用途信託的區別
    項目代理收付指定用途信託
    客戶群客戶群屬於投信公司客戶群屬於銀行
    資料建檔由銷售機構代轉至投信公司建檔由銀行自行建置客戶資料
    申購名義各投資人自己的名義向投資公司申購基金 由銀行名義向基金公司申購基金
    受益權單位由投信公司依各投資人申購額分配受益權單位數 銀行依據投信公司各基金總分配數,再行分配受益權單位數給各投資人
    投資證明客戶收到投信公司製發之保管條或受益憑證(有價證券) 客戶收到銀行製發之信託資金通知書
    諮詢服務投信公司提供 銀行提供
    + +
    + +

    原來如此。我透過華銀買,所以是用指定用途信託購買。華銀用它的名義申購,再分賣給我。盛華的客戶是華銀,不是我。我是華銀的客戶,不是盛華的客戶。盛華並不對我負責,華銀才對我負責。所以盛華不會每月寄給我對帳單,華銀才會寄給我對帳單。

    + +

    可是這樣,基金已經是找人代理操盤了,中間又隔了一層中間代理人買基金,感覺總是怪怪的。而且我查盛華 2000 高科技基金的公開說明書,上面寫申購手續費是 2% ,可是華銀只跟我收 0.75% 。這是怎麼回事?會不會哪天又跟我跑來要差價 1.25% ?而且銀行幹嘛要做這種事?銀行賺什麼?銀行會不會還要再跟我扣個什麼費用?指定用途信託還會衍生哪些費用

    + +

    於是,我又回頭看看華銀給我的信託契約,又上網找,又打電話去華銀問,才大致上弄清楚。

    + +
      +
    • 華銀之所以可以給我比盛華更低的申購手續費,是因為他們集眾客戶之力買基金,等於是盛華下的大盤,依公開說明書所說,申購金額大時,申購手續費會有優惠。申購 500 萬以上時,手續費只有 15% 。華銀理財專員說,基金手續費目前有五折的優惠,所以是 7.5% 。這可能是盛華和華銀談的代銷條件。不過其實盛華實際跟華銀拿的錢可能更低。所以,透過指定用途信託申購基金,等於是跟盤商買,手續費會比自己申購還要優惠。
    • + +
    • 透過華銀指定用途信託,定時定額轉帳申購,由於轉帳都是轉給華銀,所以轉帳手續費為零。
    • + +
    • 透過華銀指定用途信託,定時定額轉帳申購,每個月的申購手續費一樣是 3000 元的 7.5% 。
    • +
    + +

    我在信託契約上看到另一個扣除費用,叫作通路服務費,怎麼看都看不懂。既然是透過華銀買,那通路自然是指華銀。那這是盛華給華銀銷售的退佣嗎?退佣不是應該是盛華付的嗎?為什麼是要跟我扣呢?而且看我的單筆申購指示單,上面也沒有扣到通路服務費。那這筆是什麼錢?什麼時候會扣到呢?

    + +

    上網查了查,才恍然大悟:通路服務費是海外基金特有的做法,從基金的總資產中撥出一筆給代銷的信託機構,作為退佣,美其名為通路服務費(我看是故意創造新名詞,讓消費者看不懂比較好騙吧~)。通路服務費分為單筆的和每個月固定的費用,其費用是從基金的總資產下去扣。也就是說,一個募集四十億的基金,每個月從四十億中固定扣給代銷的銀行。這是海外基金特有的做法,國內的基金沒有這種做法,所以我沒有扣到這筆錢。

    + +

    海外基金因為有這筆通路服務費,所以國內的銀行理財專員,賣海外基金賣得特別賣力。這也就是為什麼海外基金明明手續費比較高,而且績效也不怎麼樣,可是台灣人還是迷信海外基金迷信得半死;國內基金的經理人做得戰戰兢兢,績效比海外基金好得多,基金還是賣不出去。因為國人多是透過銀行信託購買基金,因此購買時會受理財專員的理財顧問影響很大,理財專員建議海外基金,說海外市場多麼看好,國內市場多亂,大家就都去買海外基金去了。

    + +

    弄清楚了以後,我覺得這真的很黑暗,很惡劣。理財專員提供的理財顧問服務,應該是以客戶利益為前提,協助客戶如何獲取最大投資利益。可是通路服務費的做法,使得理財專員實質上,建議顧客買的是績效不佳、手續費高很多、還要從基金總值中,自己掏腰包給成功哄騙妳的銀行退佣的基金。可是基金的經營績效都是公開資訊,每個月還有績效評比,其實大家都可以上網自己看,自己找經營績效比較好的基金,不需要讓理財專員哄騙。我就是這樣的人,自己找資料、比較,所以沒有犯這種錯。像這樣以自己的理財專業來哄騙人,真的讓人覺得非常黑暗、惡劣。

    + +

    哪有自己掏腰包給騙自己的人,支付給他騙自己的服務的費用的啊?真是可惡!

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 89 | + 90 | + 91 | + 92 | + 93 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0092.html.en.html b/htdocs/imacat/me/diary/0092.html.en.html new file mode 120000 index 0000000..94c7074 --- /dev/null +++ b/htdocs/imacat/me/diary/0092.html.en.html @@ -0,0 +1 @@ +0092.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0092.html.en.xhtml b/htdocs/imacat/me/diary/0092.html.en.xhtml new file mode 100644 index 0000000..9194f1f --- /dev/null +++ b/htdocs/imacat/me/diary/0092.html.en.xhtml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 92 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 92

    + +
    + +
    + +
    +
    11.7.’06. 5:31am.
    + +

    我的新印表機 HP PSC 1510

    + +
    +我的 HP PSC 1510
    +

    我的 HP PSC 1510

    +
    + +

    家裏的印表機,壞掉已經很久了。我上台北最早買的印表機是 HP DeskJet 670C 彩色噴墨式印表機,用了很久才壞掉。後來買的第二台是 Epson Stylus-Color 670 彩色噴墨式印表機。那時候因為人情,而且想多嚐試不同的品牌,所以買了 Epson 。誰知道買了沒幾年,列印頭就糊掉了,需要一直清理,好像怎麼清都清不乾淨。到後來印出來花成一片,滾輪上都是髒油墨,印出來根本不能看。碰到這種事,多少對 Epson 不大滿意,可是當時人家是給我人情特價,也不好說什麼。而且手上很緊,一直也沒錢換一台。只好把要印的東西,偷偷帶到公司,用公司的雷射印表機印。老闆是不會很介意,而且反正老闆也還欠我不少。不過老是這樣,印個作業、資料都要跑來跑去,總是很不方便。而且整天偷偷摸摸,無法專心上班,也很不好。

    + +

    上個月底一筆錢下來,印表機的問題,也是我優先要解決的問題。買手機的時候,我也順便在 NOVA 看看印表機。手機搞定了以後,我再上網找找,心裏也有個底了。

    + +

    因為是學生,印的量比一般人多,所以一直想買一台雷射印表機,每張列印的成本比較省,速度比較快,比較安靜,效果比較好,又不怕水。而且研究 LPRng 的 Linux 列印以後,我才知道原來 HP 的雷射印表機才是王道,其它都是小道。雷射印表機中, HP LaserJet 1020 是最基本的機種,只要 4,999 。不過印表速度很慢,比噴墨印表機還慢,只有單色,上方進紙比較不穩。而這個價錢的噴墨,不只彩色,連多功能事務機都有了。

    + +

    如果考慮雷射多功能事務機,能夠影印、傳真,表現專業一點的話,再上一級, HP LaserJet 3050 要 9,999 ,可是是從上方進紙。再上一級的 HP LaserJet 3055 ,平面進紙,穩定多了,可是要 19,999 。這兩個價錢,就算電腦展大幅降價,對我而言,也還是頗遙遠。。

    + +

    不過考慮噴墨多功能事務機的話,選擇就多了: HP PSC 1410 要 2,499 , HP PSC 1510 要 3,499 ;或是單純噴墨印表機的話, HP DeskJet D2360 要 1,999 , HP DeskJet D4160 要 2,499 。

    + +

    至於 Epson , Epson Stylus CX2900 相片複合機,專利魔珠墨水,鮮豔防水,風評不錯。可是之前 Epson Stylus Color 670 的經驗不是很好,我想儘量避開。

    + +

    我把各款的功能,和我重視的性能表現,列了一個表:我希望能夠安靜,半夜印也不會吵到人;快速,因為我印的量不少;平均每張紙列印成本低。我幾乎不需要掃描,但偶爾會臨時需要影印,如果能夠影印會非常方便。這幾台都在我預算內。首先考慮影印功能,剩下 HP PSC 1410 和 HP PSC 1510 。兩台的噪音差不多,只有四十幾分貝。列印速度 HP PSC 1410 略差。平均列印成本, HP PSC 1510 搭配 HP 94 C8765WA 高容量墨水匣,平均印一張要 1.6 元,接近雷射的 1.2 元;而 HP PSC 1410 用 HP 21 C9351AA 墨水匣則高達 3 元。再比較雷射印表機 HP LaserJet 1020 , HP LaserJet 1020 速度慢,無彩色,無影印,明顯差一大截,只有平均列印成本 1.2 元較省錢勝出,而且碳粉不怕水。盤算的結果,我還是決定買 HP PSC 1510 。我怕停產,還先上網查,確定還有商家在賣,大致了解商家的賣價。

    + +

    我順便上網查了查 HP PSC 1510 的評價,一般來講還不錯。有一篇HP PSC 1510,寫得很仔細的。裏面正好提到 Epson 的列印頭為什麼壽命比較短的原因。原來如此。 HP 的列印頭做在墨水匣上,所以墨水匣比較貴,可是這樣就永遠有新的列印頭,沒有列印頭耗損的問題; Epson 的列印頭做在印表機上,墨水匣上沒有列印頭,所以墨水匣比較便宜,可是這樣列印頭用久了就會耗損了。想想的確是這樣。這種事其實我也應該要注意到,是我沒注意到的地方。

    + +

    星期天下午天氣不錯,出去散散步後,領個五千塊錢,就去光華商場,打算買下印表機,還有一組 HP 94 C8765WA 單色、 HP 95 C8766WA 彩色高容量墨水匣。沒想到真的停產了,逛了兩、三排店家,只有一家有賣。還好價錢還不錯,只開 3,200 ,我就高高興興搬回家去了。

    + +

    回家以後,花了一段時間,才把它裝上 Samba 。我本來怕會像買新手機那樣,花了好幾個天,把其它事都耽擱掉了。不過沒想到比預計的簡單。這是我第一次用 USB 的印表機。它的驅動程式原本只限裝在本機上,無法遠端安裝到 Samba 上。我先接到 Windows 的本機上,裝上去以後,再連線到 Samba 上,指定剛剛的型號,遠端安裝驅動程式上去。確定驅動程式檔案都複製到 Samba 上以後,移除本機的驅動程式應用軟體,然後重新連線到 Samba 上的印表機。這樣才算裝上去了。只是,因為接在 Linux 伺服器上,所以就無法掃描了,有點可惜。不過反正我也不大需要掃描,我要的是影印的功能。

    + +

    裝好了以後,試印了幾張,都蠻漂亮的,很安靜,也很快。大致上瞭解了 Linux USB 印表機的工作方式:用 udev ,每次接上去,就會自動產生 /dev/usb/lp0 ,電源關掉或斷線,就會自動移除掉。這樣也不錯。我又試了影印下午散步拿到的扇子,印起來很漂亮。我現在有彩色影印機了耶,好酷~ ^_*'

    + +

    只是,我一直不懂 PSC 是什麼意思,上網查了很久才查到。 PSCPrint-Scan-Copy列印-掃描-影印的意思。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 90 | + 91 | + 92 | + 93 | + 94 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0092.html.zh-cn.html b/htdocs/imacat/me/diary/0092.html.zh-cn.html new file mode 120000 index 0000000..f763ca7 --- /dev/null +++ b/htdocs/imacat/me/diary/0092.html.zh-cn.html @@ -0,0 +1 @@ +0092.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0092.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0092.html.zh-cn.xhtml new file mode 100644 index 0000000..c48a0e1 --- /dev/null +++ b/htdocs/imacat/me/diary/0092.html.zh-cn.xhtml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷九十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷九十二

    + +
    + +
    + +
    +
    11.7.’06. 5:31am.
    + +

    我的新印表机 HP PSC 1510

    + +
    +我的 HP PSC 1510
    +

    我的 HP PSC 1510

    +
    + +

    家里的印表机,坏掉已经很久了。我上台北最早买的印表机是 HP DeskJet 670C 彩色喷墨式印表机,用了很久才坏掉。后来买的第二台是 Epson Stylus-Color 670 彩色喷墨式印表机。那时候因为人情,而且想多尝试不同的品牌,所以买了 Epson 。谁知道买了没几年,列印头就糊掉了,需要一直清理,好像怎么清都清不干净。到后来印出来花成一片,滚轮上都是脏油墨,印出来根本不能看。碰到这种事,多少对 Epson 不大满意,可是当时人家是给我人情特价,也不好说什么。而且手上很紧,一直也没钱换一台。只好把要印的东西,偷偷带到公司,用公司的雷射印表机印。老板是不会很介意,而且反正老板也还欠我不少。不过老是这样,印个作业、资料都要跑来跑去,总是很不方便。而且整天偷偷摸摸,无法专心上班,也很不好。

    + +

    上个月底一笔钱下来,印表机的问题,也是我优先要解决的问题。买手机的时候,我也顺便在 NOVA 看看印表机。手机搞定了以后,我再上网找找,心里也有个底了。

    + +

    因为是学生,印的量比一般人多,所以一直想买一台雷射印表机,每张列印的成本比较省,速度比较快,比较安静,效果比较好,又不怕水。而且研究 LPRng 的 Linux 列印以后,我才知道原来 HP 的雷射印表机才是王道,其它都是小道。雷射印表机中, HP LaserJet 1020 是最基本的机种,只要 4,999 。不过印表速度很慢,比喷墨印表机还慢,只有单色,上方进纸比较不稳。而这个价钱的喷墨,不只彩色,连多功能事务机都有了。

    + +

    如果考虑雷射多功能事务机,能够影印、传真,表现专业一点的话,再上一级, HP LaserJet 3050 要 9,999 ,可是是从上方进纸。再上一级的 HP LaserJet 3055 ,平面进纸,稳定多了,可是要 19,999 。这两个价钱,就算电脑展大幅降价,对我而言,也还是颇遥远。。

    + +

    不过考虑喷墨多功能事务机的话,选择就多了: HP PSC 1410 要 2,499 , HP PSC 1510 要 3,499 ;或是单纯喷墨印表机的话, HP DeskJet D2360 要 1,999 , HP DeskJet D4160 要 2,499 。

    + +

    至於 Epson , Epson Stylus CX2900 相片复合机,专利魔珠墨水,鲜艳防水,风评不错。可是之前 Epson Stylus Color 670 的经验不是很好,我想尽量避开。

    + +

    我把各款的功能,和我重视的性能表现,列了一个表:我希望能够安静,半夜印也不会吵到人;快速,因为我印的量不少;平均每张纸列印成本低。我几乎不需要扫描,但偶尔会临时需要影印,如果能够影印会非常方便。这几台都在我预算内。首先考虑影印功能,剩下 HP PSC 1410 和 HP PSC 1510 。两台的噪音差不多,只有四十几分贝。列印速度 HP PSC 1410 略差。平均列印成本, HP PSC 1510 搭配 HP 94 C8765WA 高容量墨水匣,平均印一张要 1.6 元,接近雷射的 1.2 元;而 HP PSC 1410 用 HP 21 C9351AA 墨水匣则高达 3 元。再比较雷射印表机 HP LaserJet 1020 , HP LaserJet 1020 速度慢,无彩色,无影印,明显差一大截,只有平均列印成本 1.2 元较省钱胜出,而且碳粉不怕水。盘算的结果,我还是决定买 HP PSC 1510 。我怕停产,还先上网查,确定还有商家在卖,大致了解商家的卖价。

    + +

    我顺便上网查了查 HP PSC 1510 的评价,一般来讲还不错。有一篇HP PSC 1510,写得很仔细的。里面正好提到 Epson 的列印头为什么寿命比较短的原因。原来如此。 HP 的列印头做在墨水匣上,所以墨水匣比较贵,可是这样就永远有新的列印头,没有列印头耗损的问题; Epson 的列印头做在印表机上,墨水匣上没有列印头,所以墨水匣比较便宜,可是这样列印头用久了就会耗损了。想想的确是这样。这种事其实我也应该要注意到,是我没注意到的地方。

    + +

    星期天下午天气不错,出去散散步后,领个五千块钱,就去光华商场,打算买下印表机,还有一组 HP 94 C8765WA 单色、 HP 95 C8766WA 彩色高容量墨水匣。没想到真的停产了,逛了两、三排店家,只有一家有卖。还好价钱还不错,只开 3,200 ,我就高高兴兴搬回家去了。

    + +

    回家以后,花了一段时间,才把它装上 Samba 。我本来怕会像买新手机那样,花了好几个天,把其它事都耽搁掉了。不过没想到比预计的简单。这是我第一次用 USB 的印表机。它的驱动程式原本只限装在本机上,无法远端安装到 Samba 上。我先接到 Windows 的本机上,装上去以后,再连线到 Samba 上,指定刚刚的型号,远端安装驱动程式上去。确定驱动程式档案都复制到 Samba 上以后,移除本机的驱动程式应用软体,然后重新连线到 Samba 上的印表机。这样才算装上去了。只是,因为接在 Linux 伺服器上,所以就无法扫描了,有点可惜。不过反正我也不大需要扫描,我要的是影印的功能。

    + +

    装好了以后,试印了几张,都蛮漂亮的,很安静,也很快。大致上了解了 Linux USB 印表机的工作方式:用 udev ,每次接上去,就会自动产生 /dev/usb/lp0 ,电源关掉或断线,就会自动移除掉。这样也不错。我又试了影印下午散步拿到的扇子,印起来很漂亮。我现在有彩色影印机了耶,好酷~ ^_*'

    + +

    只是,我一直不懂 PSC 是什么意思,上网查了很久才查到。 PSCPrint-Scan-Copy列印-扫描-影印的意思。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 90 | + 91 | + 92 | + 93 | + 94 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0092.html.zh-tw.html b/htdocs/imacat/me/diary/0092.html.zh-tw.html new file mode 120000 index 0000000..a756799 --- /dev/null +++ b/htdocs/imacat/me/diary/0092.html.zh-tw.html @@ -0,0 +1 @@ +0092.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0092.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0092.html.zh-tw.xhtml new file mode 100644 index 0000000..4ae1c74 --- /dev/null +++ b/htdocs/imacat/me/diary/0092.html.zh-tw.xhtml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷九十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷九十二

    + +
    + +
    + +
    +
    11.7.’06. 5:31am.
    + +

    我的新印表機 HP PSC 1510

    + +
    +我的 HP PSC 1510
    +

    我的 HP PSC 1510

    +
    + +

    家裏的印表機,壞掉已經很久了。我上台北最早買的印表機是 HP DeskJet 670C 彩色噴墨式印表機,用了很久才壞掉。後來買的第二台是 Epson Stylus-Color 670 彩色噴墨式印表機。那時候因為人情,而且想多嚐試不同的品牌,所以買了 Epson 。誰知道買了沒幾年,列印頭就糊掉了,需要一直清理,好像怎麼清都清不乾淨。到後來印出來花成一片,滾輪上都是髒油墨,印出來根本不能看。碰到這種事,多少對 Epson 不大滿意,可是當時人家是給我人情特價,也不好說什麼。而且手上很緊,一直也沒錢換一台。只好把要印的東西,偷偷帶到公司,用公司的雷射印表機印。老闆是不會很介意,而且反正老闆也還欠我不少。不過老是這樣,印個作業、資料都要跑來跑去,總是很不方便。而且整天偷偷摸摸,無法專心上班,也很不好。

    + +

    上個月底一筆錢下來,印表機的問題,也是我優先要解決的問題。買手機的時候,我也順便在 NOVA 看看印表機。手機搞定了以後,我再上網找找,心裏也有個底了。

    + +

    因為是學生,印的量比一般人多,所以一直想買一台雷射印表機,每張列印的成本比較省,速度比較快,比較安靜,效果比較好,又不怕水。而且研究 LPRng 的 Linux 列印以後,我才知道原來 HP 的雷射印表機才是王道,其它都是小道。雷射印表機中, HP LaserJet 1020 是最基本的機種,只要 4,999 。不過印表速度很慢,比噴墨印表機還慢,只有單色,上方進紙比較不穩。而這個價錢的噴墨,不只彩色,連多功能事務機都有了。

    + +

    如果考慮雷射多功能事務機,能夠影印、傳真,表現專業一點的話,再上一級, HP LaserJet 3050 要 9,999 ,可是是從上方進紙。再上一級的 HP LaserJet 3055 ,平面進紙,穩定多了,可是要 19,999 。這兩個價錢,就算電腦展大幅降價,對我而言,也還是頗遙遠。。

    + +

    不過考慮噴墨多功能事務機的話,選擇就多了: HP PSC 1410 要 2,499 , HP PSC 1510 要 3,499 ;或是單純噴墨印表機的話, HP DeskJet D2360 要 1,999 , HP DeskJet D4160 要 2,499 。

    + +

    至於 Epson , Epson Stylus CX2900 相片複合機,專利魔珠墨水,鮮豔防水,風評不錯。可是之前 Epson Stylus Color 670 的經驗不是很好,我想儘量避開。

    + +

    我把各款的功能,和我重視的性能表現,列了一個表:我希望能夠安靜,半夜印也不會吵到人;快速,因為我印的量不少;平均每張紙列印成本低。我幾乎不需要掃描,但偶爾會臨時需要影印,如果能夠影印會非常方便。這幾台都在我預算內。首先考慮影印功能,剩下 HP PSC 1410 和 HP PSC 1510 。兩台的噪音差不多,只有四十幾分貝。列印速度 HP PSC 1410 略差。平均列印成本, HP PSC 1510 搭配 HP 94 C8765WA 高容量墨水匣,平均印一張要 1.6 元,接近雷射的 1.2 元;而 HP PSC 1410 用 HP 21 C9351AA 墨水匣則高達 3 元。再比較雷射印表機 HP LaserJet 1020 , HP LaserJet 1020 速度慢,無彩色,無影印,明顯差一大截,只有平均列印成本 1.2 元較省錢勝出,而且碳粉不怕水。盤算的結果,我還是決定買 HP PSC 1510 。我怕停產,還先上網查,確定還有商家在賣,大致了解商家的賣價。

    + +

    我順便上網查了查 HP PSC 1510 的評價,一般來講還不錯。有一篇HP PSC 1510,寫得很仔細的。裏面正好提到 Epson 的列印頭為什麼壽命比較短的原因。原來如此。 HP 的列印頭做在墨水匣上,所以墨水匣比較貴,可是這樣就永遠有新的列印頭,沒有列印頭耗損的問題; Epson 的列印頭做在印表機上,墨水匣上沒有列印頭,所以墨水匣比較便宜,可是這樣列印頭用久了就會耗損了。想想的確是這樣。這種事其實我也應該要注意到,是我沒注意到的地方。

    + +

    星期天下午天氣不錯,出去散散步後,領個五千塊錢,就去光華商場,打算買下印表機,還有一組 HP 94 C8765WA 單色、 HP 95 C8766WA 彩色高容量墨水匣。沒想到真的停產了,逛了兩、三排店家,只有一家有賣。還好價錢還不錯,只開 3,200 ,我就高高興興搬回家去了。

    + +

    回家以後,花了一段時間,才把它裝上 Samba 。我本來怕會像買新手機那樣,花了好幾個天,把其它事都耽擱掉了。不過沒想到比預計的簡單。這是我第一次用 USB 的印表機。它的驅動程式原本只限裝在本機上,無法遠端安裝到 Samba 上。我先接到 Windows 的本機上,裝上去以後,再連線到 Samba 上,指定剛剛的型號,遠端安裝驅動程式上去。確定驅動程式檔案都複製到 Samba 上以後,移除本機的驅動程式應用軟體,然後重新連線到 Samba 上的印表機。這樣才算裝上去了。只是,因為接在 Linux 伺服器上,所以就無法掃描了,有點可惜。不過反正我也不大需要掃描,我要的是影印的功能。

    + +

    裝好了以後,試印了幾張,都蠻漂亮的,很安靜,也很快。大致上瞭解了 Linux USB 印表機的工作方式:用 udev ,每次接上去,就會自動產生 /dev/usb/lp0 ,電源關掉或斷線,就會自動移除掉。這樣也不錯。我又試了影印下午散步拿到的扇子,印起來很漂亮。我現在有彩色影印機了耶,好酷~ ^_*'

    + +

    只是,我一直不懂 PSC 是什麼意思,上網查了很久才查到。 PSCPrint-Scan-Copy列印-掃描-影印的意思。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 90 | + 91 | + 92 | + 93 | + 94 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0093.html.en.html b/htdocs/imacat/me/diary/0093.html.en.html new file mode 120000 index 0000000..dbdcb44 --- /dev/null +++ b/htdocs/imacat/me/diary/0093.html.en.html @@ -0,0 +1 @@ +0093.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0093.html.en.xhtml b/htdocs/imacat/me/diary/0093.html.en.xhtml new file mode 100644 index 0000000..7ce5dc7 --- /dev/null +++ b/htdocs/imacat/me/diary/0093.html.en.xhtml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 93 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 93

    + +
    + +
    + +
    +
    11.13.’06. 6:42pm.
    + +

    期中考

    + +

    星期天考完期中考。

    + +

    這是我唸空大,最後一個學期的期中考了。剩下沒幾個學分,之前每個學期都修滿上限五科,這個學期只有修三科。我選的三科古典短篇小說選讀台灣史重要文獻導讀中國社會史,都是我喜歡的人文科,而且是札實的科目。三科中,只有中國社會史有考古題,其它兩科都是新開設課程。雖然課程札實,但我想之前五科都能應付得來,這學期只有三科,要好好唸,應該可以游刃有餘。

    + +

    星期六先考古典短篇小說選讀,然後考台灣史重要文獻導讀,星期天才考中國社會史。考前先唸古典短篇小說選讀,然後唸了一遍中國社會史,最後才唸台灣史重要文獻導讀台灣史重要文獻導讀差一點就唸不完。

    + +

    星期六考試之前,兩科都只讀了一遍,未曾熟讀,心裏虛虛的。還好考得還不錯,都會寫。古典短篇小說選讀考了一題舉例說明小說反映社會現實的藝術功能,我有唸到小說的四大功能,但下面的舉例太繁,沒有細唸。於是左想右想,前一陣子看了那麼多小說,總該記得一些吧!想了半天,想起幾個記得比較全的故事,像是杜十娘怒沉百寶箱賣油郎獨佔花魁等等,應該可以寫它們裏面對反映時人對愛情的態度,對風月女子的岐視等等。可是這樣要說是反映社會現實還是很勉強。想了半天,想起有個故事在講北宋人南逃時家破,女兒和父母被官兵沖散,好像後來被賣到妓院。三言二拍中那麼多風月的故事,到底是哪一個呢?想了很久,慢慢把前因後果勾勒出來,應該沒錯,就是賣油郎獨佔花魁。於是我把它寫下來,被官兵衝散後,最後不意父女團圓,反映宋人南遷家破人亡,對重新團圓的渴望。

    + +

    考完後非常在意,馬上打電話,問人賣油郎獨佔花魁的劇情是不是真的有講到北人南遷、家破人亡的事。沒想到真的沒錯!呵呵~!還好我唸得熟,課本提到的小說,都去讀了一遍。看看課本,反映社會現實那一段,沒有舉賣油郎獨佔花魁的例子。我朋友也跟我提醒,宋以後言論禁忌頗多,宋代話本多為明代所作,明代時誰還知道什麼宋人南遷的事?那只是想像的,不可能反映什麼社會現實。想想沒錯。希望老師不要太認真了。

    + +

    星期六回家後只剩一科中國社會史。之前已經先唸過一遍了,還有一個晚上。這次我下了苦功,既然有時間,決心把它讀熟。課本翻開,看看後面的自我評量,把不明的觀念多讀了幾遍,讀到不懂的地方,又上網查字典,關於晉、唐間的世家大族的演化,八王之亂、五胡十六國、侯景之亂、白馬繹之變、王謝家的興衰、科舉制度的演變、太學、國子監的演變等等。這一科是唯一有考古題的,隔天早上,又把考古題唸了唸。比起前兩科考前虛虛的,這一科我可是信心滿滿。

    + +

    誰知道考出來,臉都綠了。第一題問家族的四大要素,考前知道這是重點的,又硬是多背了幾遍,誰知道就這樣硬生生忘了四大要素第二項。第四題問清代興洋學後成效不彰,刑部尚書李端棻的檢討,以及自己的看法。我有讀到清代大興洋學的四大措施,可是沒看到後面的檢討,所以只能寫自己的看法,李端棻的檢討完全不會寫。第二題家族祭祀的幾種形式,還有祭祀對凝聚家族向心力的影響,影響我知道,但祭祀的幾種形式我也完全不會。加起來扣一扣,大概六十幾吧。

    + +

    沒唸熟的科目考得好,花時間唸得很熟的科目反而一塌糊塗。唉~

    + +
    + +
    + +
    +
    11.13.’06. 4:14pm.
    + +

    駁選擇相信論

    + +

    爾來論者有所謂選擇相信說,其可笑也至。

    + +

    概所謂選擇相信者,其矛盾也甚。選擇者,或二擇一,或三擇一,或多擇一,有多項可選,才有選擇。論者謂選擇相信陳水扁者,有何可選?不計其科學,不計其證據,可選唯一。雖貪贓枉法,雖雌黃反復,雖證據羅列,雖十萬禮券收受,雖百萬珠寶入袋,不作二想。雖美其名為選擇,有何可選者?唯一字而已。

    + +

    所謂選擇相信論,以自由選擇之名,掩其盲信之實。唯主君之言為是,蒙眼封口,視證據於不聞。負民主自由之名,其封建遺毒也甚!悲乎士人淪落至此,不復可言。

    + +
    + +
    + +
    +
    11.9.’06. 12:26pm.
    + +

    Firefox 2.0

    + +

    剛剛換上了 Firefox 2.0 。

    + +

    嗯,還好。界面有點小小的不一樣,主要是圖示的圖案,而且邊框格線很清楚,像漫畫一樣。不過選單內容本身沒有什麼差別,選項也差不多。但還是看起來怪怪的。用久應該會習慣吧~

    + +

    新同文堂還沒有 Firefox 2.0 的版本。嗯。

    + +
    + +
    + +
    +
    11.8.’06. 1:27pm.
    + +

    保本型基金

    + +

    這幾年有一種基金,叫保本型基金

    + +

    任何投資都有風險,都可能虧損。保本型基金不一樣之處,在於它保證還本。就算虧本,基金公司也會賠給你,保證你絕對、絕對還得了本。依保本率的不同,又分成保 90% 本、保 80% 本、保 70% 本等等不同等級。當然,基金公司也不想賠給你,所以投資自然比較保守,獲利力比較低。

    + +

    像這樣在契約中載明保證還本,我一開始也很心動。畢竟誰想賠錢?如果保證投資不會賠錢,即使犧牲利潤少賺一點,誰不心動。可是後來評估績效時,看到國內股票型基金亮麗的成績,我還是買了國內股票型基金。

    + +

    前兩天心血來潮,查了查國內保本型基金的績效如何。一看,真的傻了:統計的四家,不論是一年、兩年、三年報酬率,沒有一家賺賠上下超過 1.5% ,而一般股票型基金,一年報酬率可以到 40% 。果然是非常保守!我還不如去存定存,不,不如去存活存算了。不要講定存,連活存利率都比這個高。這真的是太誇張了。

    + +

    後來用經濟學的模型想想,也難怪:保本型基金有一個風險的陷阱:它定了一個價格的下限。這就跟政府價格管制一樣,一旦市場價格低於保證價格,那會造成市場的混亂。舉例來說,假如我是在淨值 10 元時買入保本 90% 的基金,一旦淨值跌到 8 元,那我趕緊用保證贖回價 9 元贖回,拿去買同等值的證券,或是立刻再買入,就可以現賺一筆差價 1 元。因此,一但價格下跌到某個價格以上,就會引發贖回潮。而基金面對贖回潮資金不足時,被迫賣出手中持有證券以供孰回,又會造成持有證券價格下滑,淨值也跟著下跌,引發更嚴重的贖回潮。整個基金就會短時間內崩盤。保本型基金因為有這個陷阱,所以絕對不能賠,投資策略就超級保守,以不賠為唯一目標,其它都不重要。

    + +

    仔細弄清楚以後,我得到一個結論:保本型基金其實是一個陷阱。要買保本型基金,那還不如去銀行存定存、活存算了。保本型基金雖然保證不賠 90% ,但一旦崩盤,基金公司倒了,投資人還是求助無門。而活存、定存不只保 100% 本,比保本型基金安穩,利息還比保本型基金的報酬率高很多。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 91 | + 92 | + 93 | + 94 | + 95 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0093.html.zh-cn.html b/htdocs/imacat/me/diary/0093.html.zh-cn.html new file mode 120000 index 0000000..b06b6f8 --- /dev/null +++ b/htdocs/imacat/me/diary/0093.html.zh-cn.html @@ -0,0 +1 @@ +0093.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0093.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0093.html.zh-cn.xhtml new file mode 100644 index 0000000..30cc748 --- /dev/null +++ b/htdocs/imacat/me/diary/0093.html.zh-cn.xhtml @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷九十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷九十三

    + +
    + +
    + +
    +
    11.13.’06. 6:42pm.
    + +

    期中考

    + +

    星期天考完期中考。

    + +

    这是我念空大,最后一个学期的期中考了。剩下没几个学分,之前每个学期都修满上限五科,这个学期只有修三科。我选的三科古典短篇小说选读台湾史重要文献导读中国社会史,都是我喜欢的人文科,而且是札实的科目。三科中,只有中国社会史有考古题,其它两科都是新开设课程。虽然课程札实,但我想之前五科都能应付得来,这学期只有三科,要好好念,应该可以游刃有余。

    + +

    星期六先考古典短篇小说选读,然后考台湾史重要文献导读,星期天才考中国社会史。考前先念古典短篇小说选读,然后念了一遍中国社会史,最后才念台湾史重要文献导读台湾史重要文献导读差一点就念不完。

    + +

    星期六考试之前,两科都只读了一遍,未曾熟读,心里虚虚的。还好考得还不错,都会写。古典短篇小说选读考了一题举例说明小说反映社会现实的艺术功能,我有念到小说的四大功能,但下面的举例太繁,没有细念。於是左想右想,前一阵子看了那么多小说,总该记得一些吧!想了半天,想起几个记得比较全的故事,像是杜十娘怒沉百宝箱卖油郎独占花魁等等,应该可以写它们里面对反映时人对爱情的态度,对风月女子的岐视等等。可是这样要说是反映社会现实还是很勉强。想了半天,想起有个故事在讲北宋人南逃时家破,女儿和父母被官兵冲散,好像后来被卖到妓院。三言二拍中那么多风月的故事,到底是哪一个呢?想了很久,慢慢把前因后果勾勒出来,应该没错,就是卖油郎独占花魁。於是我把它写下来,被官兵冲散后,最后不意父女团圆,反映宋人南迁家破人亡,对重新团圆的渴望。

    + +

    考完后非常在意,马上打电话,问人卖油郎独占花魁的剧情是不是真的有讲到北人南迁、家破人亡的事。没想到真的没错!呵呵~!还好我念得熟,课本提到的小说,都去读了一遍。看看课本,反映社会现实那一段,没有举卖油郎独占花魁的例子。我朋友也跟我提醒,宋以后言论禁忌颇多,宋代话本多为明代所作,明代时谁还知道什么宋人南迁的事?那只是想像的,不可能反映什么社会现实。想想没错。希望老师不要太认真了。

    + +

    星期六回家后只剩一科中国社会史。之前已经先念过一遍了,还有一个晚上。这次我下了苦功,既然有时间,决心把它读熟。课本翻开,看看后面的自我评量,把不明的观念多读了几遍,读到不懂的地方,又上网查字典,关於晋、唐间的世家大族的演化,八王之乱、五胡十六国、侯景之乱、白马绎之变、王谢家的兴衰、科举制度的演变、太学、国子监的演变等等。这一科是唯一有考古题的,隔天早上,又把考古题念了念。比起前两科考前虚虚的,这一科我可是信心满满。

    + +

    谁知道考出来,脸都绿了。第一题问家族的四大要素,考前知道这是重点的,又硬是多背了几遍,谁知道就这样硬生生忘了四大要素第二项。第四题问清代兴洋学后成效不彰,刑部尚书李端棻的检讨,以及自己的看法。我有读到清代大兴洋学的四大措施,可是没看到后面的检讨,所以只能写自己的看法,李端棻的检讨完全不会写。第二题家族祭祀的几种形式,还有祭祀对凝聚家族向心力的影响,影响我知道,但祭祀的几种形式我也完全不会。加起来扣一扣,大概六十几吧。

    + +

    没念熟的科目考得好,花时间念得很熟的科目反而一塌糊涂。唉~

    + +
    + +
    + +
    +
    11.13.’06. 4:14pm.
    + +

    驳选择相信论

    + +

    尔来论者有所谓选择相信说,其可笑也至。

    + +

    概所谓选择相信者,其矛盾也甚。选择者,或二择一,或三择一,或多择一,有多项可选,才有选择。论者谓选择相信陈水扁者,有何可选?不计其科学,不计其证据,可选唯一。虽贪赃枉法,虽雌黄反复,虽证据罗列,虽十万礼券收受,虽百万珠宝入袋,不作二想。虽美其名为选择,有何可选者?唯一字而已。

    + +

    所谓选择相信论,以自由选择之名,掩其盲信之实。唯主君之言为是,蒙眼封口,视证据於不闻。负民主自由之名,其封建遗毒也甚!悲乎士人沦落至此,不复可言。

    + +
    + +
    + +
    +
    11.9.’06. 12:26pm.
    + +

    Firefox 2.0

    + +

    刚刚换上了 Firefox 2.0 。

    + +

    嗯,还好。界面有点小小的不一样,主要是图示的图案,而且边框格线很清楚,像漫画一样。不过选单内容本身没有什么差别,选项也差不多。但还是看起来怪怪的。用久应该会习惯吧~

    + +

    新同文堂还没有 Firefox 2.0 的版本。嗯。

    + +
    + +
    + +
    +
    11.8.’06. 1:27pm.
    + +

    保本型基金

    + +

    这几年有一种基金,叫保本型基金

    + +

    任何投资都有风险,都可能亏损。保本型基金不一样之处,在於它保证还本。就算亏本,基金公司也会赔给你,保证你绝对、绝对还得了本。依保本率的不同,又分成保 90% 本、保 80% 本、保 70% 本等等不同等级。当然,基金公司也不想赔给你,所以投资自然比较保守,获利力比较低。

    + +

    像这样在契约中载明保证还本,我一开始也很心动。毕竟谁想赔钱?如果保证投资不会赔钱,即使牺牲利润少赚一点,谁不心动。可是后来评估绩效时,看到国内股票型基金亮丽的成绩,我还是买了国内股票型基金。

    + +

    前两天心血来潮,查了查国内保本型基金的绩效如何。一看,真的傻了:统计的四家,不论是一年、两年、三年报酬率,没有一家赚赔上下超过 1.5% ,而一般股票型基金,一年报酬率可以到 40% 。果然是非常保守!我还不如去存定存,不,不如去存活存算了。不要讲定存,连活存利率都比这个高。这真的是太夸张了。

    + +

    后来用经济学的模型想想,也难怪:保本型基金有一个风险的陷阱:它定了一个价格的下限。这就跟政府价格管制一样,一旦市场价格低於保证价格,那会造成市场的混乱。举例来说,假如我是在净值 10 元时买入保本 90% 的基金,一旦净值跌到 8 元,那我赶紧用保证赎回价 9 元赎回,拿去买同等值的证券,或是立刻再买入,就可以现赚一笔差价 1 元。因此,一但价格下跌到某个价格以上,就会引发赎回潮。而基金面对赎回潮资金不足时,被迫卖出手中持有证券以供孰回,又会造成持有证券价格下滑,净值也跟著下跌,引发更严重的赎回潮。整个基金就会短时间内崩盘。保本型基金因为有这个陷阱,所以绝对不能赔,投资策略就超级保守,以不赔为唯一目标,其它都不重要。

    + +

    仔细弄清楚以后,我得到一个结论:保本型基金其实是一个陷阱。要买保本型基金,那还不如去银行存定存、活存算了。保本型基金虽然保证不赔 90% ,但一旦崩盘,基金公司倒了,投资人还是求助无门。而活存、定存不只保 100% 本,比保本型基金安稳,利息还比保本型基金的报酬率高很多。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 91 | + 92 | + 93 | + 94 | + 95 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0093.html.zh-tw.html b/htdocs/imacat/me/diary/0093.html.zh-tw.html new file mode 120000 index 0000000..2ed45aa --- /dev/null +++ b/htdocs/imacat/me/diary/0093.html.zh-tw.html @@ -0,0 +1 @@ +0093.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0093.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0093.html.zh-tw.xhtml new file mode 100644 index 0000000..29fa535 --- /dev/null +++ b/htdocs/imacat/me/diary/0093.html.zh-tw.xhtml @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷九十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷九十三

    + +
    + +
    + +
    +
    11.13.’06. 6:42pm.
    + +

    期中考

    + +

    星期天考完期中考。

    + +

    這是我唸空大,最後一個學期的期中考了。剩下沒幾個學分,之前每個學期都修滿上限五科,這個學期只有修三科。我選的三科古典短篇小說選讀台灣史重要文獻導讀中國社會史,都是我喜歡的人文科,而且是札實的科目。三科中,只有中國社會史有考古題,其它兩科都是新開設課程。雖然課程札實,但我想之前五科都能應付得來,這學期只有三科,要好好唸,應該可以游刃有餘。

    + +

    星期六先考古典短篇小說選讀,然後考台灣史重要文獻導讀,星期天才考中國社會史。考前先唸古典短篇小說選讀,然後唸了一遍中國社會史,最後才唸台灣史重要文獻導讀台灣史重要文獻導讀差一點就唸不完。

    + +

    星期六考試之前,兩科都只讀了一遍,未曾熟讀,心裏虛虛的。還好考得還不錯,都會寫。古典短篇小說選讀考了一題舉例說明小說反映社會現實的藝術功能,我有唸到小說的四大功能,但下面的舉例太繁,沒有細唸。於是左想右想,前一陣子看了那麼多小說,總該記得一些吧!想了半天,想起幾個記得比較全的故事,像是杜十娘怒沉百寶箱賣油郎獨佔花魁等等,應該可以寫它們裏面對反映時人對愛情的態度,對風月女子的岐視等等。可是這樣要說是反映社會現實還是很勉強。想了半天,想起有個故事在講北宋人南逃時家破,女兒和父母被官兵沖散,好像後來被賣到妓院。三言二拍中那麼多風月的故事,到底是哪一個呢?想了很久,慢慢把前因後果勾勒出來,應該沒錯,就是賣油郎獨佔花魁。於是我把它寫下來,被官兵衝散後,最後不意父女團圓,反映宋人南遷家破人亡,對重新團圓的渴望。

    + +

    考完後非常在意,馬上打電話,問人賣油郎獨佔花魁的劇情是不是真的有講到北人南遷、家破人亡的事。沒想到真的沒錯!呵呵~!還好我唸得熟,課本提到的小說,都去讀了一遍。看看課本,反映社會現實那一段,沒有舉賣油郎獨佔花魁的例子。我朋友也跟我提醒,宋以後言論禁忌頗多,宋代話本多為明代所作,明代時誰還知道什麼宋人南遷的事?那只是想像的,不可能反映什麼社會現實。想想沒錯。希望老師不要太認真了。

    + +

    星期六回家後只剩一科中國社會史。之前已經先唸過一遍了,還有一個晚上。這次我下了苦功,既然有時間,決心把它讀熟。課本翻開,看看後面的自我評量,把不明的觀念多讀了幾遍,讀到不懂的地方,又上網查字典,關於晉、唐間的世家大族的演化,八王之亂、五胡十六國、侯景之亂、白馬繹之變、王謝家的興衰、科舉制度的演變、太學、國子監的演變等等。這一科是唯一有考古題的,隔天早上,又把考古題唸了唸。比起前兩科考前虛虛的,這一科我可是信心滿滿。

    + +

    誰知道考出來,臉都綠了。第一題問家族的四大要素,考前知道這是重點的,又硬是多背了幾遍,誰知道就這樣硬生生忘了四大要素第二項。第四題問清代興洋學後成效不彰,刑部尚書李端棻的檢討,以及自己的看法。我有讀到清代大興洋學的四大措施,可是沒看到後面的檢討,所以只能寫自己的看法,李端棻的檢討完全不會寫。第二題家族祭祀的幾種形式,還有祭祀對凝聚家族向心力的影響,影響我知道,但祭祀的幾種形式我也完全不會。加起來扣一扣,大概六十幾吧。

    + +

    沒唸熟的科目考得好,花時間唸得很熟的科目反而一塌糊塗。唉~

    + +
    + +
    + +
    +
    11.13.’06. 4:14pm.
    + +

    駁選擇相信論

    + +

    爾來論者有所謂選擇相信說,其可笑也至。

    + +

    概所謂選擇相信者,其矛盾也甚。選擇者,或二擇一,或三擇一,或多擇一,有多項可選,才有選擇。論者謂選擇相信陳水扁者,有何可選?不計其科學,不計其證據,可選唯一。雖貪贓枉法,雖雌黃反復,雖證據羅列,雖十萬禮券收受,雖百萬珠寶入袋,不作二想。雖美其名為選擇,有何可選者?唯一字而已。

    + +

    所謂選擇相信論,以自由選擇之名,掩其盲信之實。唯主君之言為是,蒙眼封口,視證據於不聞。負民主自由之名,其封建遺毒也甚!悲乎士人淪落至此,不復可言。

    + +
    + +
    + +
    +
    11.9.’06. 12:26pm.
    + +

    Firefox 2.0

    + +

    剛剛換上了 Firefox 2.0 。

    + +

    嗯,還好。界面有點小小的不一樣,主要是圖示的圖案,而且邊框格線很清楚,像漫畫一樣。不過選單內容本身沒有什麼差別,選項也差不多。但還是看起來怪怪的。用久應該會習慣吧~

    + +

    新同文堂還沒有 Firefox 2.0 的版本。嗯。

    + +
    + +
    + +
    +
    11.8.’06. 1:27pm.
    + +

    保本型基金

    + +

    這幾年有一種基金,叫保本型基金

    + +

    任何投資都有風險,都可能虧損。保本型基金不一樣之處,在於它保證還本。就算虧本,基金公司也會賠給你,保證你絕對、絕對還得了本。依保本率的不同,又分成保 90% 本、保 80% 本、保 70% 本等等不同等級。當然,基金公司也不想賠給你,所以投資自然比較保守,獲利力比較低。

    + +

    像這樣在契約中載明保證還本,我一開始也很心動。畢竟誰想賠錢?如果保證投資不會賠錢,即使犧牲利潤少賺一點,誰不心動。可是後來評估績效時,看到國內股票型基金亮麗的成績,我還是買了國內股票型基金。

    + +

    前兩天心血來潮,查了查國內保本型基金的績效如何。一看,真的傻了:統計的四家,不論是一年、兩年、三年報酬率,沒有一家賺賠上下超過 1.5% ,而一般股票型基金,一年報酬率可以到 40% 。果然是非常保守!我還不如去存定存,不,不如去存活存算了。不要講定存,連活存利率都比這個高。這真的是太誇張了。

    + +

    後來用經濟學的模型想想,也難怪:保本型基金有一個風險的陷阱:它定了一個價格的下限。這就跟政府價格管制一樣,一旦市場價格低於保證價格,那會造成市場的混亂。舉例來說,假如我是在淨值 10 元時買入保本 90% 的基金,一旦淨值跌到 8 元,那我趕緊用保證贖回價 9 元贖回,拿去買同等值的證券,或是立刻再買入,就可以現賺一筆差價 1 元。因此,一但價格下跌到某個價格以上,就會引發贖回潮。而基金面對贖回潮資金不足時,被迫賣出手中持有證券以供孰回,又會造成持有證券價格下滑,淨值也跟著下跌,引發更嚴重的贖回潮。整個基金就會短時間內崩盤。保本型基金因為有這個陷阱,所以絕對不能賠,投資策略就超級保守,以不賠為唯一目標,其它都不重要。

    + +

    仔細弄清楚以後,我得到一個結論:保本型基金其實是一個陷阱。要買保本型基金,那還不如去銀行存定存、活存算了。保本型基金雖然保證不賠 90% ,但一旦崩盤,基金公司倒了,投資人還是求助無門。而活存、定存不只保 100% 本,比保本型基金安穩,利息還比保本型基金的報酬率高很多。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 91 | + 92 | + 93 | + 94 | + 95 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0094.html.en.html b/htdocs/imacat/me/diary/0094.html.en.html new file mode 120000 index 0000000..8dd6cee --- /dev/null +++ b/htdocs/imacat/me/diary/0094.html.en.html @@ -0,0 +1 @@ +0094.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0094.html.en.xhtml b/htdocs/imacat/me/diary/0094.html.en.xhtml new file mode 100644 index 0000000..4d50105 --- /dev/null +++ b/htdocs/imacat/me/diary/0094.html.en.xhtml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 94 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 94

    + +
    + +
    + +
    +
    11.25.’06. 3:25am.
    + +

    萬夫莫敵:聖女傳 Wars and Warriors: Joan of Arc

    + +

    終於玩完了萬夫莫敵:聖女傳 Wars and Warriors: Joan of Arc

    + +

    聖女傳躺在我的硬碟,躺了四個月。全部只有八關,其實也不是多大的遊戲。七月底買來,以為一天可以破一關的,玩到第六關後面的城堡卡住了,怎麼樣也打不下城牆上的弓兵,加上空大暑假的課實在忙不過來了,只好停手。這一停就停了三個多月。兩個星期前期中考完,下定決心把它打完。

    + +

    其實比我以為的簡單。聖女傳除了可以以動作角色扮演模式玩以外,還可以戰略模式帶兵指揮。大概是因為這樣先入為主的成見吧,後來兵越帶越多,第五關、第六關打得很辛苦。一個人最多可以帶二十個小兵,小兵受傷也需要補血,所以補血的物品常常短缺,要為了物資東奔西跑;加上人多雜亂,城裏巷弄狹小,一百多人在城裏進進出出,光帶隊、整隊,等待迷路的小兵,就花了很長的時間。

    + +

    深深體會了宋襄公的敗因:大軍笨重,光是移動、整隊,就足夠弄成人踩人的大混亂,而吃了大敗仗。

    + +

    重拾遊戲後,找到缺口上了城牆,破了牆上的弓箭手,解決了第六關。第七關開始,我突發奇想,於是把兵力全部交給同伴帶領,然後單槍匹馬殺出去。果然所向無敵:不但不用集合、整隊等得半死,上牆下牆、巷弄來去、殺進殺出都沒有顧忌,也不用為了消耗飛快的軍糧煩惱,東徵西調。結果,單槍匹馬,就把第七關、第八關破了,一下子就破完了整個遊戲。

    + +

    呵,真是當局者迷。抱著成見,就很容易看不清事情。

    + +

    玩完趕快移除遊戲,清掉了 1GB 的硬碟空間。我還有柏德之門資料片:劍灣傳奇創世紀七第二部:巨蛇之島兩部遊戲,玩到一半躺在那裏。加油加油~

    + +
    + +
    + +
    +
    11.18.’06. 3:39pm.
    + +

    包龍圖

    + +

    看了周星馳的威龍闖天關,我聯想到另一部周星馳演的古裝法庭喜劇九品芝麻官九品芝麻官中的包龍星,同樣讓人印象深刻。劇中包龍星說是包龍圖後代,與名狀師方唐鏡大鬥法。那麼包龍圖是誰?

    + +

    我查了查:原來包龍圖就是開封府知府包拯包青天,因為他當過龍圖閣直學士,所以世稱包龍圖。章回小說龍圖公案,就是以包拯為主角的虛構故事。

    + +
    + +
    + +
    +
    11.18.’06. 3:46am.
    + +

    威龍闖天關與宋世傑

    + +

    今天晚上看龍祥電影台,又看了一遍周星馳的威龍闖天關。這部片我看到快要會背了,也很愛看。跟朋友討論劇中的宋世傑。我記得宋世傑是所謂廣東四大狀師之一,可是朋友跟我說那是小說虛構的人物。我為了要弄清楚,上網仔細查了宋世傑這個人。

    + +

    查到一個民初的革命黨人宋世傑,不過我想不是我要找的那個人。

    + +

    我查了查,弄清楚,比較可信的資料如下:

    + +

    威龍闖天關香港原片名審死官,由杜琪峰導演,周星馳、梅豔芳主演。故事是改編自同名粵劇審死官,粵劇審死官則是改編自京劇四進士,京劇四進士則是改編自鼓詞紫金鐲。我找不到原文的紫金鐲鼓詞。不過找到了京劇四進士的劇本。讀完後,很過癮。原來的宋世傑是個老頭。所以宋世傑真的是虛構的小說人物,不是什麼廣東四大狀師。

    + +

    所謂的廣東四大狀師:陳夢吉、方唐鏡、劉華東、宋世傑(或何淡如),裏面有幾個是真實人物呢?嗯嗯,頗奈人尋味。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 92 | + 93 | + 94 | + 95 | + 96 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0094.html.zh-cn.html b/htdocs/imacat/me/diary/0094.html.zh-cn.html new file mode 120000 index 0000000..25fef45 --- /dev/null +++ b/htdocs/imacat/me/diary/0094.html.zh-cn.html @@ -0,0 +1 @@ +0094.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0094.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0094.html.zh-cn.xhtml new file mode 100644 index 0000000..8f19c6e --- /dev/null +++ b/htdocs/imacat/me/diary/0094.html.zh-cn.xhtml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷九十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷九十四

    + +
    + +
    + +
    +
    11.25.’06. 3:25am.
    + +

    万夫莫敌:圣女传 Wars and Warriors: Joan of Arc

    + +

    终於玩完了万夫莫敌:圣女传 Wars and Warriors: Joan of Arc

    + +

    圣女传躺在我的硬碟,躺了四个月。全部只有八关,其实也不是多大的游戏。七月底买来,以为一天可以破一关的,玩到第六关后面的城堡卡住了,怎么样也打不下城墙上的弓兵,加上空大暑假的课实在忙不过来了,只好停手。这一停就停了三个多月。两个星期前期中考完,下定决心把它打完。

    + +

    其实比我以为的简单。圣女传除了可以以动作角色扮演模式玩以外,还可以战略模式带兵指挥。大概是因为这样先入为主的成见吧,后来兵越带越多,第五关、第六关打得很辛苦。一个人最多可以带二十个小兵,小兵受伤也需要补血,所以补血的物品常常短缺,要为了物资东奔西跑;加上人多杂乱,城里巷弄狭小,一百多人在城里进进出出,光带队、整队,等待迷路的小兵,就花了很长的时间。

    + +

    深深体会了宋襄公的败因:大军笨重,光是移动、整队,就足够弄成人踩人的大混乱,而吃了大败仗。

    + +

    重拾游戏后,找到缺口上了城墙,破了墙上的弓箭手,解决了第六关。第七关开始,我突发奇想,於是把兵力全部交给同伴带领,然后单枪匹马杀出去。果然所向无敌:不但不用集合、整队等得半死,上墙下墙、巷弄来去、杀进杀出都没有顾忌,也不用为了消耗飞快的军粮烦恼,东徵西调。结果,单枪匹马,就把第七关、第八关破了,一下子就破完了整个游戏。

    + +

    呵,真是当局者迷。抱著成见,就很容易看不清事情。

    + +

    玩完赶快移除游戏,清掉了 1GB 的硬碟空间。我还有柏德之门资料片:剑湾传奇创世纪七第二部:巨蛇之岛两部游戏,玩到一半躺在那里。加油加油~

    + +
    + +
    + +
    +
    11.18.’06. 3:39pm.
    + +

    包龙图

    + +

    看了周星驰的威龙闯天关,我联想到另一部周星驰演的古装法庭喜剧九品芝麻官九品芝麻官中的包龙星,同样让人印象深刻。剧中包龙星说是包龙图后代,与名状师方唐镜大斗法。那么包龙图是谁?

    + +

    我查了查:原来包龙图就是开封府知府包拯包青天,因为他当过龙图阁直学士,所以世称包龙图。章回小说龙图公案,就是以包拯为主角的虚构故事。

    + +
    + +
    + +
    +
    11.18.’06. 3:46am.
    + +

    威龙闯天关与宋世杰

    + +

    今天晚上看龙祥电影台,又看了一遍周星驰的威龙闯天关。这部片我看到快要会背了,也很爱看。跟朋友讨论剧中的宋世杰。我记得宋世杰是所谓广东四大状师之一,可是朋友跟我说那是小说虚构的人物。我为了要弄清楚,上网仔细查了宋世杰这个人。

    + +

    查到一个民初的革命党人宋世杰,不过我想不是我要找的那个人。

    + +

    我查了查,弄清楚,比较可信的资料如下:

    + +

    威龙闯天关香港原片名审死官,由杜琪峰导演,周星驰、梅艳芳主演。故事是改编自同名粤剧审死官,粤剧审死官则是改编自京剧四进士,京剧四进士则是改编自鼓词紫金镯。我找不到原文的紫金镯鼓词。不过找到了京剧四进士的剧本。读完后,很过瘾。原来的宋世杰是个老头。所以宋世杰真的是虚构的小说人物,不是什么广东四大状师。

    + +

    所谓的广东四大状师:陈梦吉、方唐镜、刘华东、宋世杰(或何淡如),里面有几个是真实人物呢?嗯嗯,颇奈人寻味。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 92 | + 93 | + 94 | + 95 | + 96 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0094.html.zh-tw.html b/htdocs/imacat/me/diary/0094.html.zh-tw.html new file mode 120000 index 0000000..cbb913b --- /dev/null +++ b/htdocs/imacat/me/diary/0094.html.zh-tw.html @@ -0,0 +1 @@ +0094.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0094.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0094.html.zh-tw.xhtml new file mode 100644 index 0000000..cf1fd64 --- /dev/null +++ b/htdocs/imacat/me/diary/0094.html.zh-tw.xhtml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷九十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷九十四

    + +
    + +
    + +
    +
    11.25.’06. 3:25am.
    + +

    萬夫莫敵:聖女傳 Wars and Warriors: Joan of Arc

    + +

    終於玩完了萬夫莫敵:聖女傳 Wars and Warriors: Joan of Arc

    + +

    聖女傳躺在我的硬碟,躺了四個月。全部只有八關,其實也不是多大的遊戲。七月底買來,以為一天可以破一關的,玩到第六關後面的城堡卡住了,怎麼樣也打不下城牆上的弓兵,加上空大暑假的課實在忙不過來了,只好停手。這一停就停了三個多月。兩個星期前期中考完,下定決心把它打完。

    + +

    其實比我以為的簡單。聖女傳除了可以以動作角色扮演模式玩以外,還可以戰略模式帶兵指揮。大概是因為這樣先入為主的成見吧,後來兵越帶越多,第五關、第六關打得很辛苦。一個人最多可以帶二十個小兵,小兵受傷也需要補血,所以補血的物品常常短缺,要為了物資東奔西跑;加上人多雜亂,城裏巷弄狹小,一百多人在城裏進進出出,光帶隊、整隊,等待迷路的小兵,就花了很長的時間。

    + +

    深深體會了宋襄公的敗因:大軍笨重,光是移動、整隊,就足夠弄成人踩人的大混亂,而吃了大敗仗。

    + +

    重拾遊戲後,找到缺口上了城牆,破了牆上的弓箭手,解決了第六關。第七關開始,我突發奇想,於是把兵力全部交給同伴帶領,然後單槍匹馬殺出去。果然所向無敵:不但不用集合、整隊等得半死,上牆下牆、巷弄來去、殺進殺出都沒有顧忌,也不用為了消耗飛快的軍糧煩惱,東徵西調。結果,單槍匹馬,就把第七關、第八關破了,一下子就破完了整個遊戲。

    + +

    呵,真是當局者迷。抱著成見,就很容易看不清事情。

    + +

    玩完趕快移除遊戲,清掉了 1GB 的硬碟空間。我還有柏德之門資料片:劍灣傳奇創世紀七第二部:巨蛇之島兩部遊戲,玩到一半躺在那裏。加油加油~

    + +
    + +
    + +
    +
    11.18.’06. 3:39pm.
    + +

    包龍圖

    + +

    看了周星馳的威龍闖天關,我聯想到另一部周星馳演的古裝法庭喜劇九品芝麻官九品芝麻官中的包龍星,同樣讓人印象深刻。劇中包龍星說是包龍圖後代,與名狀師方唐鏡大鬥法。那麼包龍圖是誰?

    + +

    我查了查:原來包龍圖就是開封府知府包拯包青天,因為他當過龍圖閣直學士,所以世稱包龍圖。章回小說龍圖公案,就是以包拯為主角的虛構故事。

    + +
    + +
    + +
    +
    11.18.’06. 3:46am.
    + +

    威龍闖天關與宋世傑

    + +

    今天晚上看龍祥電影台,又看了一遍周星馳的威龍闖天關。這部片我看到快要會背了,也很愛看。跟朋友討論劇中的宋世傑。我記得宋世傑是所謂廣東四大狀師之一,可是朋友跟我說那是小說虛構的人物。我為了要弄清楚,上網仔細查了宋世傑這個人。

    + +

    查到一個民初的革命黨人宋世傑,不過我想不是我要找的那個人。

    + +

    我查了查,弄清楚,比較可信的資料如下:

    + +

    威龍闖天關香港原片名審死官,由杜琪峰導演,周星馳、梅豔芳主演。故事是改編自同名粵劇審死官,粵劇審死官則是改編自京劇四進士,京劇四進士則是改編自鼓詞紫金鐲。我找不到原文的紫金鐲鼓詞。不過找到了京劇四進士的劇本。讀完後,很過癮。原來的宋世傑是個老頭。所以宋世傑真的是虛構的小說人物,不是什麼廣東四大狀師。

    + +

    所謂的廣東四大狀師:陳夢吉、方唐鏡、劉華東、宋世傑(或何淡如),裏面有幾個是真實人物呢?嗯嗯,頗奈人尋味。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 92 | + 93 | + 94 | + 95 | + 96 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0095.html.en.html b/htdocs/imacat/me/diary/0095.html.en.html new file mode 120000 index 0000000..5e2babc --- /dev/null +++ b/htdocs/imacat/me/diary/0095.html.en.html @@ -0,0 +1 @@ +0095.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0095.html.en.xhtml b/htdocs/imacat/me/diary/0095.html.en.xhtml new file mode 100644 index 0000000..05b24ee --- /dev/null +++ b/htdocs/imacat/me/diary/0095.html.en.xhtml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 95 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 95

    + +
    + +
    + +
    +
    12.6.’06. 2:32am.
    + +

    名探偵コナン 探偵たちの鎮魂歌 名偵探柯南 偵探們的鎮魂歌 Detective Conan The Private Eye’s Requiem—案件本身就是謎題的後設案件

    + +
    +名探偵コナン 探偵たちの鎮魂歌
    +

    名探偵コナン 探偵たちの鎮魂歌

    +
    + +
      +
    • 片名:名探偵コナン 探偵たちの鎮魂歌
    • +
    • 中譯片名:名偵探柯南 偵探們的鎮魂歌 Detective Conan The Private Eye’s Requiem
    • +
    • 發行年份: 2006
    • +
    • 製作公司: 名探偵コナン製作委員会
    • +
    • 導演:山本泰一郎
    • +
    • 編劇:柏原寛司
    • +
    • 原作:青山剛昌名探偵コナン(週刊少年サンデー)
    • +
    + +

    名探偵コナン 探偵たちの鎮魂歌名探偵コナン的第十部電影。劇情描述毛利小五郎接到案件委託,可是委託人交待一定要帶小蘭及少年偵探團同行。到了以後才發現目的地是新開幕的大型休閒旅館遊樂場。小蘭帶少年偵探團接受委託人招待,進遊樂場玩後,柯南和小五郎才發現他們成了人質,如果沒有達成委託,小蘭和所有人都會同歸於盡,而之前未破案的偵探,都已經死於非命了。更詭異的是,神祕的委託人,似乎知道柯南真正的身份。到底委託人要委託的是什麼案件呢?不知道!這是柯南和小五郎第一個要解開的謎。

    + +

    這是我 2006 年 10 月 11 日看的電影,一直沒空寫感想,忙到現在。作為名探偵コナン的例行年度電影,拍到第十部,已經看得有點麻木了。場景很多都是拿真實的場景來描畫的,加上很多 3D 的技術,如光影、層次等等,讓畫面感覺真實感很強烈。可是真實感這麼強烈,也失去了部份動畫應有的趣味。片尾換成真人實景,非現實感強烈的泛黃畫面,一個女生在台場的建築物間來去,突然跟劇中的關鍵人物麗子,影像重疊在一起,產生一種真實和動畫交錯嵌入的奇特感覺。

    + +

    劇情的部份,連案件本身都不知道是什麼的案件,第一件事就是要解出這到底是什麼案件。案件的內容本身就是迷題,後設的作法,的確很有新意。呢看到結局的時候,倒是有點失望。這樣的謎底劇情安排頗為老套了。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 93 | + 94 | + 95 | + 96 | + 97 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0095.html.zh-cn.html b/htdocs/imacat/me/diary/0095.html.zh-cn.html new file mode 120000 index 0000000..c15d17e --- /dev/null +++ b/htdocs/imacat/me/diary/0095.html.zh-cn.html @@ -0,0 +1 @@ +0095.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0095.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0095.html.zh-cn.xhtml new file mode 100644 index 0000000..aae5560 --- /dev/null +++ b/htdocs/imacat/me/diary/0095.html.zh-cn.xhtml @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷九十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷九十五

    + +
    + +
    + +
    +
    12.6.’06. 2:32am.
    + +

    名探侦コナン 探侦たちの镇魂歌 名侦探柯南 侦探们的镇魂歌 Detective Conan The Private Eye’s Requiem—案件本身就是谜题的后设案件

    + +
    +名探侦コナン 探侦たちの镇魂歌
    +

    名探侦コナン 探侦たちの镇魂歌

    +
    + +
      +
    • 片名:名探侦コナン 探侦たちの镇魂歌
    • +
    • 中译片名:名侦探柯南 侦探们的镇魂歌 Detective Conan The Private Eye’s Requiem
    • +
    • 发行年份: 2006
    • +
    • 制作公司: 名探侦コナン制作委员会
    • +
    • 导演:山本泰一郎
    • +
    • 编剧:柏原寛司
    • +
    • 原作:青山刚昌名探侦コナン(周刊少年サンデー)
    • +
    + +

    名探侦コナン 探侦たちの镇魂歌名探侦コナン的第十部电影。剧情描述毛利小五郎接到案件委托,可是委托人交待一定要带小兰及少年侦探团同行。到了以后才发现目的地是新开幕的大型休闲旅馆游乐场。小兰带少年侦探团接受委托人招待,进游乐场玩后,柯南和小五郎才发现他们成了人质,如果没有达成委托,小兰和所有人都会同归於尽,而之前未破案的侦探,都已经死於非命了。更诡异的是,神秘的委托人,似乎知道柯南真正的身份。到底委托人要委托的是什么案件呢?不知道!这是柯南和小五郎第一个要解开的谜。

    + +

    这是我 2006 年 10 月 11 日看的电影,一直没空写感想,忙到现在。作为名探侦コナン的例行年度电影,拍到第十部,已经看得有点麻木了。场景很多都是拿真实的场景来描画的,加上很多 3D 的技术,如光影、层次等等,让画面感觉真实感很强烈。可是真实感这么强烈,也失去了部份动画应有的趣味。片尾换成真人实景,非现实感强烈的泛黄画面,一个女生在台场的建筑物间来去,突然跟剧中的关键人物丽子,影像重叠在一起,产生一种真实和动画交错嵌入的奇特感觉。

    + +

    剧情的部份,连案件本身都不知道是什么的案件,第一件事就是要解出这到底是什么案件。案件的内容本身就是迷题,后设的作法,的确很有新意。呢看到结局的时候,倒是有点失望。这样的谜底剧情安排颇为老套了。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 93 | + 94 | + 95 | + 96 | + 97 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0095.html.zh-tw.html b/htdocs/imacat/me/diary/0095.html.zh-tw.html new file mode 120000 index 0000000..dc060e5 --- /dev/null +++ b/htdocs/imacat/me/diary/0095.html.zh-tw.html @@ -0,0 +1 @@ +0095.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0095.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0095.html.zh-tw.xhtml new file mode 100644 index 0000000..5adb71b --- /dev/null +++ b/htdocs/imacat/me/diary/0095.html.zh-tw.xhtml @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷九十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷九十五

    + +
    + +
    + +
    +
    12.6.’06. 2:32am.
    + +

    名探偵コナン 探偵たちの鎮魂歌 名偵探柯南 偵探們的鎮魂歌 Detective Conan The Private Eye’s Requiem—案件本身就是謎題的後設案件

    + +
    +名探偵コナン 探偵たちの鎮魂歌
    +

    名探偵コナン 探偵たちの鎮魂歌

    +
    + +
      +
    • 片名:名探偵コナン 探偵たちの鎮魂歌
    • +
    • 中譯片名:名偵探柯南 偵探們的鎮魂歌 Detective Conan The Private Eye’s Requiem
    • +
    • 發行年份: 2006
    • +
    • 製作公司: 名探偵コナン製作委員会
    • +
    • 導演:山本泰一郎
    • +
    • 編劇:柏原寛司
    • +
    • 原作:青山剛昌名探偵コナン(週刊少年サンデー)
    • +
    + +

    名探偵コナン 探偵たちの鎮魂歌名探偵コナン的第十部電影。劇情描述毛利小五郎接到案件委託,可是委託人交待一定要帶小蘭及少年偵探團同行。到了以後才發現目的地是新開幕的大型休閒旅館遊樂場。小蘭帶少年偵探團接受委託人招待,進遊樂場玩後,柯南和小五郎才發現他們成了人質,如果沒有達成委託,小蘭和所有人都會同歸於盡,而之前未破案的偵探,都已經死於非命了。更詭異的是,神祕的委託人,似乎知道柯南真正的身份。到底委託人要委託的是什麼案件呢?不知道!這是柯南和小五郎第一個要解開的謎。

    + +

    這是我 2006 年 10 月 11 日看的電影,一直沒空寫感想,忙到現在。作為名探偵コナン的例行年度電影,拍到第十部,已經看得有點麻木了。場景很多都是拿真實的場景來描畫的,加上很多 3D 的技術,如光影、層次等等,讓畫面感覺真實感很強烈。可是真實感這麼強烈,也失去了部份動畫應有的趣味。片尾換成真人實景,非現實感強烈的泛黃畫面,一個女生在台場的建築物間來去,突然跟劇中的關鍵人物麗子,影像重疊在一起,產生一種真實和動畫交錯嵌入的奇特感覺。

    + +

    劇情的部份,連案件本身都不知道是什麼的案件,第一件事就是要解出這到底是什麼案件。案件的內容本身就是迷題,後設的作法,的確很有新意。呢看到結局的時候,倒是有點失望。這樣的謎底劇情安排頗為老套了。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 93 | + 94 | + 95 | + 96 | + 97 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0096.html.en.html b/htdocs/imacat/me/diary/0096.html.en.html new file mode 120000 index 0000000..72a91a6 --- /dev/null +++ b/htdocs/imacat/me/diary/0096.html.en.html @@ -0,0 +1 @@ +0096.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0096.html.en.xhtml b/htdocs/imacat/me/diary/0096.html.en.xhtml new file mode 100644 index 0000000..4d56bcb --- /dev/null +++ b/htdocs/imacat/me/diary/0096.html.en.xhtml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 96 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 96

    + +
    + +
    + +
    +
    12.6.’06. 4:11am.
    + +

    Fun With Dick And Jane 我愛上流—員工眼中的恩隆案

    + +
    +Fun With Dick And Jane 我愛上流
    +

    Fun With Dick And Jane 我愛上流

    +
    + + + +

    我愛上流也是我在 2006 年 10 月 11 日看的電影,一直忙,拖到現在才寫感想,距今已兩個月了。

    + +

    我愛上流敘述一個中產家庭的夫婦迪克和珍,迪克是公司的中層經理,珍在旅行社工作,收入不錯,像一般中產階級過著優渥的生活,並努力向上爬。有一天迪克突然蒙大老闆傑克和財務長法蘭克召見,陞為媒體副總。沖昏頭的迪克說服工作不順的珍辭職。沒想到這才是惡夢的開始。原來大老闆傑克聯同法蘭克做假帳掏空公司,正要捲款潛逃,找迪克當替死鬼面對股東,揹黑鍋收拾殘局。公司無預警倒閉,員工退休基金也被私吞,上千人生活無著。迪克和珍連著幾個月找不到工作,付不出房貸、車貸、房屋整修費、傭人薪水,裝修公司挖走草皮,銀行一樣樣來查封,搬走豪華傢俱電器,原先的生活一樣樣被剝奪掉。最後兩人受不了了挺而走險,開始蒙面搶劫。剛開始一切都很順利,電視、冰箱、草皮一樣樣回來了,他們似乎回到優渥的中產生活。直到有一次搶銀行時,正好碰到前同事同時搶劫被逮,才停止。這時候碰巧碰上法蘭克,法蘭克被大老闆傑克一腳踢開,過著流浪的生活。法蘭克告訴迪克,大老闆傑克把從公司污來的錢藏在秘密帳戶,並說服迪克和珍,計劃騙取該秘密帳戶的錢以報復。於是,一場員工對黑心老闆的復仇計,即將展開。

    + +

    我愛上流描寫的故事,很像轟動一時的恩隆案。 2001 年底爆發恩隆 Enron 案,企業主夥同會計師事務所做假帳,坑騙投資大眾的錢,引發華爾街的大震蕩。投資人對會計師專業的信任一瞬間掃地,當時全球四大會計師事務所之一的百年老店安達信 Arthur Andersen 一瞬間瓦解。事隔多年,關於恩隆案,已有非常多的討論。但多為由投資大眾、市場公正、商業道德來探討,很少有人針對員工的立場,探討在企業主刻意詐騙、掏空之下,瞬間失卻依靠的員工何去何從。我愛上流裏的迪克和珍,原來的人生財務規劃付之一炬,付不出房貸、車貸,眼看即將流落街頭,只好挺而走險。電影雖然描寫得趣味橫生,但現實生活中的上班族,遇上黑心老闆掏空、捲款潛逃時,又要怎麼活下去?

    + +

    台灣的勞工制度很特別,由政府勞工法令鉅細靡遺地規定下來,由政府來保障勞工權益。這在全世界絕無僅有。美國企業的員工退休基金,是由企業自行提撥管理,但台灣的員工退休基金,是企業提撥後由是政府管理。因此,我愛上流裏企業主捲走員工退休金潛逃,在台灣不會發生。

    + +

    從這個角度來看,其實電影裏把員工失去依靠後的生活,描寫得太卡通化了。於是,原本是很沉重的失業問題,變得輕飄飄地,沒有份量。在輕飄飄地喜劇感下,迪克與珍為了滿足兒子的哭鬧,為了家門口的草皮,挺而走險去搶劫,就顯得很突兀,不大有說服力。劇情中段從搶劫轉為設局詐騙,轉彎得太大,也感覺很生硬。

    + +

    劇尾的喜劇結局,沉重地打了企業主一記悶棍。只是,現實世界中,像這樣的好事,似乎不大可能發生。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 94 | + 95 | + 96 | + 97 | + 98 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0096.html.zh-cn.html b/htdocs/imacat/me/diary/0096.html.zh-cn.html new file mode 120000 index 0000000..00cc9c5 --- /dev/null +++ b/htdocs/imacat/me/diary/0096.html.zh-cn.html @@ -0,0 +1 @@ +0096.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0096.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0096.html.zh-cn.xhtml new file mode 100644 index 0000000..2ad337e --- /dev/null +++ b/htdocs/imacat/me/diary/0096.html.zh-cn.xhtml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷九十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷九十六

    + +
    + +
    + +
    +
    12.6.’06. 4:11am.
    + +

    Fun With Dick And Jane 我爱上流—员工眼中的恩隆案

    + +
    +Fun With Dick And Jane 我爱上流
    +

    Fun With Dick And Jane 我爱上流

    +
    + + + +

    我爱上流也是我在 2006 年 10 月 11 日看的电影,一直忙,拖到现在才写感想,距今已两个月了。

    + +

    我爱上流叙述一个中产家庭的夫妇迪克和珍,迪克是公司的中层经理,珍在旅行社工作,收入不错,像一般中产阶级过著优渥的生活,并努力向上爬。有一天迪克突然蒙大老板杰克和财务长法兰克召见,升为媒体副总。冲昏头的迪克说服工作不顺的珍辞职。没想到这才是恶梦的开始。原来大老板杰克联同法兰克做假帐掏空公司,正要卷款潜逃,找迪克当替死鬼面对股东,背黑锅收拾残局。公司无预警倒闭,员工退休基金也被私吞,上千人生活无著。迪克和珍连著几个月找不到工作,付不出房贷、车贷、房屋整修费、佣人薪水,装修公司挖走草皮,银行一样样来查封,搬走豪华家俱电器,原先的生活一样样被剥夺掉。最后两人受不了了挺而走险,开始蒙面抢劫。刚开始一切都很顺利,电视、冰箱、草皮一样样回来了,他们似乎回到优渥的中产生活。直到有一次抢银行时,正好碰到前同事同时抢劫被逮,才停止。这时候碰巧碰上法兰克,法兰克被大老板杰克一脚踢开,过著流浪的生活。法兰克告诉迪克,大老板杰克把从公司污来的钱藏在秘密帐户,并说服迪克和珍,计划骗取该秘密帐户的钱以报复。於是,一场员工对黑心老板的复仇计,即将展开。

    + +

    我爱上流描写的故事,很像轰动一时的恩隆案。 2001 年底爆发恩隆 Enron 案,企业主伙同会计师事务所做假帐,坑骗投资大众的钱,引发华尔街的大震荡。投资人对会计师专业的信任一瞬间扫地,当时全球四大会计师事务所之一的百年老店安达信 Arthur Andersen 一瞬间瓦解。事隔多年,关於恩隆案,已有非常多的讨论。但多为由投资大众、市场公正、商业道德来探讨,很少有人针对员工的立场,探讨在企业主刻意诈骗、掏空之下,瞬间失却依靠的员工何去何从。我爱上流里的迪克和珍,原来的人生财务规划付之一炬,付不出房贷、车贷,眼看即将流落街头,只好挺而走险。电影虽然描写得趣味横生,但现实生活中的上班族,遇上黑心老板掏空、卷款潜逃时,又要怎么活下去?

    + +

    台湾的劳工制度很特别,由政府劳工法令巨细靡遗地规定下来,由政府来保障劳工权益。这在全世界绝无仅有。美国企业的员工退休基金,是由企业自行提拨管理,但台湾的员工退休基金,是企业提拨后由是政府管理。因此,我爱上流里企业主卷走员工退休金潜逃,在台湾不会发生。

    + +

    从这个角度来看,其实电影里把员工失去依靠后的生活,描写得太卡通化了。於是,原本是很沉重的失业问题,变得轻飘飘地,没有份量。在轻飘飘地喜剧感下,迪克与珍为了满足儿子的哭闹,为了家门口的草皮,挺而走险去抢劫,就显得很突兀,不大有说服力。剧情中段从抢劫转为设局诈骗,转弯得太大,也感觉很生硬。

    + +

    剧尾的喜剧结局,沉重地打了企业主一记闷棍。只是,现实世界中,像这样的好事,似乎不大可能发生。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 94 | + 95 | + 96 | + 97 | + 98 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0096.html.zh-tw.html b/htdocs/imacat/me/diary/0096.html.zh-tw.html new file mode 120000 index 0000000..032668c --- /dev/null +++ b/htdocs/imacat/me/diary/0096.html.zh-tw.html @@ -0,0 +1 @@ +0096.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0096.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0096.html.zh-tw.xhtml new file mode 100644 index 0000000..d7d1a7a --- /dev/null +++ b/htdocs/imacat/me/diary/0096.html.zh-tw.xhtml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷九十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷九十六

    + +
    + +
    + +
    +
    12.6.’06. 4:11am.
    + +

    Fun With Dick And Jane 我愛上流—員工眼中的恩隆案

    + +
    +Fun With Dick And Jane 我愛上流
    +

    Fun With Dick And Jane 我愛上流

    +
    + + + +

    我愛上流也是我在 2006 年 10 月 11 日看的電影,一直忙,拖到現在才寫感想,距今已兩個月了。

    + +

    我愛上流敘述一個中產家庭的夫婦迪克和珍,迪克是公司的中層經理,珍在旅行社工作,收入不錯,像一般中產階級過著優渥的生活,並努力向上爬。有一天迪克突然蒙大老闆傑克和財務長法蘭克召見,陞為媒體副總。沖昏頭的迪克說服工作不順的珍辭職。沒想到這才是惡夢的開始。原來大老闆傑克聯同法蘭克做假帳掏空公司,正要捲款潛逃,找迪克當替死鬼面對股東,揹黑鍋收拾殘局。公司無預警倒閉,員工退休基金也被私吞,上千人生活無著。迪克和珍連著幾個月找不到工作,付不出房貸、車貸、房屋整修費、傭人薪水,裝修公司挖走草皮,銀行一樣樣來查封,搬走豪華傢俱電器,原先的生活一樣樣被剝奪掉。最後兩人受不了了挺而走險,開始蒙面搶劫。剛開始一切都很順利,電視、冰箱、草皮一樣樣回來了,他們似乎回到優渥的中產生活。直到有一次搶銀行時,正好碰到前同事同時搶劫被逮,才停止。這時候碰巧碰上法蘭克,法蘭克被大老闆傑克一腳踢開,過著流浪的生活。法蘭克告訴迪克,大老闆傑克把從公司污來的錢藏在秘密帳戶,並說服迪克和珍,計劃騙取該秘密帳戶的錢以報復。於是,一場員工對黑心老闆的復仇計,即將展開。

    + +

    我愛上流描寫的故事,很像轟動一時的恩隆案。 2001 年底爆發恩隆 Enron 案,企業主夥同會計師事務所做假帳,坑騙投資大眾的錢,引發華爾街的大震蕩。投資人對會計師專業的信任一瞬間掃地,當時全球四大會計師事務所之一的百年老店安達信 Arthur Andersen 一瞬間瓦解。事隔多年,關於恩隆案,已有非常多的討論。但多為由投資大眾、市場公正、商業道德來探討,很少有人針對員工的立場,探討在企業主刻意詐騙、掏空之下,瞬間失卻依靠的員工何去何從。我愛上流裏的迪克和珍,原來的人生財務規劃付之一炬,付不出房貸、車貸,眼看即將流落街頭,只好挺而走險。電影雖然描寫得趣味橫生,但現實生活中的上班族,遇上黑心老闆掏空、捲款潛逃時,又要怎麼活下去?

    + +

    台灣的勞工制度很特別,由政府勞工法令鉅細靡遺地規定下來,由政府來保障勞工權益。這在全世界絕無僅有。美國企業的員工退休基金,是由企業自行提撥管理,但台灣的員工退休基金,是企業提撥後由是政府管理。因此,我愛上流裏企業主捲走員工退休金潛逃,在台灣不會發生。

    + +

    從這個角度來看,其實電影裏把員工失去依靠後的生活,描寫得太卡通化了。於是,原本是很沉重的失業問題,變得輕飄飄地,沒有份量。在輕飄飄地喜劇感下,迪克與珍為了滿足兒子的哭鬧,為了家門口的草皮,挺而走險去搶劫,就顯得很突兀,不大有說服力。劇情中段從搶劫轉為設局詐騙,轉彎得太大,也感覺很生硬。

    + +

    劇尾的喜劇結局,沉重地打了企業主一記悶棍。只是,現實世界中,像這樣的好事,似乎不大可能發生。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 94 | + 95 | + 96 | + 97 | + 98 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0097.html.en.html b/htdocs/imacat/me/diary/0097.html.en.html new file mode 120000 index 0000000..f2a4d5e --- /dev/null +++ b/htdocs/imacat/me/diary/0097.html.en.html @@ -0,0 +1 @@ +0097.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0097.html.en.xhtml b/htdocs/imacat/me/diary/0097.html.en.xhtml new file mode 100644 index 0000000..f10dffa --- /dev/null +++ b/htdocs/imacat/me/diary/0097.html.en.xhtml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 97 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 97

    + +
    + +
    + +
    +
    12.9.’06. 9:48pm.
    + +

    名探偵コナン 水平線上の陰謀 名偵探柯南 水平線上的陰謀 Detective Conan Strategy Above The Depth—假犯罪背後隱藏的真正犯人

    + +
    +名探偵コナン 水平線上の陰謀
    +

    名探偵コナン 水平線上の陰謀

    +
    + +
      +
    • 片名:名探偵コナン 水平線上の陰謀
    • +
    • 中譯片名:名偵探柯南 水平線上的陰謀 Detective Conan Strategy Above The Depth
    • +
    • 發行年份: 2005
    • +
    • 製作公司: 名探偵コナン製作委員会
    • +
    • 導演:山本泰一郎
    • +
    • 編劇:古内一成
    • +
    • 原作:青山剛昌名探偵コナン(週刊少年サンデー)
    • +
    + +

    名探偵コナン 水平線上の陰謀名探偵コナン的第九部電影。柯南、小蘭、小五郎、阿笠博士和少年偵探團,陪同應邀鈴木財團千金的園子,共同參加八代財團新豪華遊輪アフロディーテ号 Aphrodite 的處女首航,在船上結識了欲撰寫以豪華郵輪為題財的連續劇,而上船取材的電視台編劇日下ひろなり(日下祐成),及遊輪設計團隊副組長秋吉美波子。然而,就在首航前半個月,主設計師、秋吉美波子的老師、八代財團入贅女婿八代英人車禍墜崖死亡。而十五年前,八代財團的第一八代丸撞冰山沉船事件,壟罩著層層謎霧,當年倖存的副船長海藤渡,成了今日アフロディーテ号的船長。出海第一天上午,還沒來得及開始歡迎晚宴,園子就被攻擊,八代客船社長、會長長女八代貴江被殺,八代財團會長八代延太郎離奇失蹤。而這一連串的事件幕後的陰謀,還在一步步展開。

    + +

    名探偵コナン 水平線上の陰謀最特別的地方,是隱藏在假兇手背後的真兇。兇手是誰其實一開始就很明顯,破綻不少,故意讓觀眾知道。一切也非常合理。可是一直到最後,才突然發現,事件還有真正的兇手,掌握到的都不是真相。這種故意用假兇手做晃子,隱藏真兇手的設計,算是這一集的特色。

    + +

    然而,就算是假兇手,從頭到尾兇手就很明顯、非常合理的推理故事,讓人提不起勁。後來冒出來的真兇,也只能給人啊?怎麼會這樣?的感覺,因為之前太合情合理了,後來冒出來的真兇就十分牽強,柯南和小五郎的推理疑點,只有一點說得過去而已。

    + +

    柯南開快艇追上去,從正面額頭射入麻醉針那一幕,很亂來。那樣是會死人的,柯南就成了殺人現行犯了。

    + +

    劇情還賣弄了一段鐵達尼號的翻版。船上的旅客非富即貴,都是超級有錢人,是不是幾年後,會有人去打撈沉船發財呢?

    + +

    最後柯南感謝那串貝殼手鍊救了他。其實若不是那串貝殼手鍊,他和小蘭、小五郎根本就不會陷入險境才對。其實是害了他,不是救了他。

    + +
    + +
    + +
    +
    12.6.’06. 4:29am.
    + +

    捨本逐末

    + +

    今天坐計程車,前座椅背上貼著台灣大車隊賣書的廣告,賣的是一本叫我受夠了的書。廣告下標示是超越極限行銷顧問有限公司做的。我看了半天,還是看不大懂。

    + +

    廣告上不大的空間,寫著幾個大字:非買本書不可的理由:暢銷排行榜第一名、憂鬱症看了就痊癒了、賣書款捐公益等等。剩下的就是書名、照片。看了半天,這本書到底在寫什麼?還是不清楚。根本不知道是什麼書,只列出所謂非買不可的理由,不是捨本逐末嗎?

    + +

    這個社會上,充斥著這種捨本逐末的事:賣書不介紹內容,而是吹捧它排行榜第幾名。我們到底是為了自己的興趣、需要買書,還是為了怕別人看了我沒看而買書呢?街上充斥的廣告,不見它介紹商品本身,卻大幅強調贈品多有價值。就算看了十遍二十遍,也還不知道它要賣什麼。

    + +

    會不會我自己也犯是捨本逐末的毛病呢?跟人家說明事情的時候,會不會也花很多時間強調事物的附加價值,而很少提及事物本身的內容,以致人家花很多時間、精神聽我說完話,還是一團迷霧呢?

    + +

    對此,深自警惕。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 95 | + 96 | + 97 | + 98 | + 99 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0097.html.zh-cn.html b/htdocs/imacat/me/diary/0097.html.zh-cn.html new file mode 120000 index 0000000..07324bd --- /dev/null +++ b/htdocs/imacat/me/diary/0097.html.zh-cn.html @@ -0,0 +1 @@ +0097.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0097.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0097.html.zh-cn.xhtml new file mode 100644 index 0000000..6922ec3 --- /dev/null +++ b/htdocs/imacat/me/diary/0097.html.zh-cn.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷九十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷九十七

    + +
    + +
    + +
    +
    12.9.’06. 9:48pm.
    + +

    名探侦コナン 水平线上の阴谋 名侦探柯南 水平线上的阴谋 Detective Conan Strategy Above The Depth—假犯罪背后隐藏的真正犯人

    + +
    +名探侦コナン 水平线上の阴谋
    +

    名探侦コナン 水平线上の阴谋

    +
    + +
      +
    • 片名:名探侦コナン 水平线上の阴谋
    • +
    • 中译片名:名侦探柯南 水平线上的阴谋 Detective Conan Strategy Above The Depth
    • +
    • 发行年份: 2005
    • +
    • 制作公司: 名探侦コナン制作委员会
    • +
    • 导演:山本泰一郎
    • +
    • 编剧:古内一成
    • +
    • 原作:青山刚昌名探侦コナン(周刊少年サンデー)
    • +
    + +

    名探侦コナン 水平线上の阴谋名探侦コナン的第九部电影。柯南、小兰、小五郎、阿笠博士和少年侦探团,陪同应邀铃木财团千金的园子,共同参加八代财团新豪华游轮アフロディーテ号 Aphrodite 的处女首航,在船上结识了欲撰写以豪华邮轮为题财的连续剧,而上船取材的电视台编剧日下ひろなり(日下佑成),及游轮设计团队副组长秋吉美波子。然而,就在首航前半个月,主设计师、秋吉美波子的老师、八代财团入赘女婿八代英人车祸坠崖死亡。而十五年前,八代财团的第一八代丸撞冰山沉船事件,垄罩著层层谜雾,当年幸存的副船长海藤渡,成了今日アフロディーテ号的船长。出海第一天上午,还没来得及开始欢迎晚宴,园子就被攻击,八代客船社长、会长长女八代贵江被杀,八代财团会长八代延太郎离奇失踪。而这一连串的事件幕后的阴谋,还在一步步展开。

    + +

    名探侦コナン 水平线上の阴谋最特别的地方,是隐藏在假凶手背后的真凶。凶手是谁其实一开始就很明显,破绽不少,故意让观众知道。一切也非常合理。可是一直到最后,才突然发现,事件还有真正的凶手,掌握到的都不是真相。这种故意用假凶手做晃子,隐藏真凶手的设计,算是这一集的特色。

    + +

    然而,就算是假凶手,从头到尾凶手就很明显、非常合理的推理故事,让人提不起劲。后来冒出来的真凶,也只能给人啊?怎么会这样?的感觉,因为之前太合情合理了,后来冒出来的真凶就十分牵强,柯南和小五郎的推理疑点,只有一点说得过去而已。

    + +

    柯南开快艇追上去,从正面额头射入麻醉针那一幕,很乱来。那样是会死人的,柯南就成了杀人现行犯了。

    + +

    剧情还卖弄了一段铁达尼号的翻版。船上的旅客非富即贵,都是超级有钱人,是不是几年后,会有人去打捞沉船发财呢?

    + +

    最后柯南感谢那串贝壳手炼救了他。其实若不是那串贝壳手炼,他和小兰、小五郎根本就不会陷入险境才对。其实是害了他,不是救了他。

    + +
    + +
    + +
    +
    12.6.’06. 4:29am.
    + +

    舍本逐末

    + +

    今天坐计程车,前座椅背上贴著台湾大车队卖书的广告,卖的是一本叫我受够了的书。广告下标示是超越极限行销顾问有限公司做的。我看了半天,还是看不大懂。

    + +

    广告上不大的空间,写著几个大字:非买本书不可的理由:畅销排行榜第一名、忧郁症看了就痊愈了、卖书款捐公益等等。剩下的就是书名、照片。看了半天,这本书到底在写什么?还是不清楚。根本不知道是什么书,只列出所谓非买不可的理由,不是舍本逐末吗?

    + +

    这个社会上,充斥著这种舍本逐末的事:卖书不介绍内容,而是吹捧它排行榜第几名。我们到底是为了自己的兴趣、需要买书,还是为了怕别人看了我没看而买书呢?街上充斥的广告,不见它介绍商品本身,却大幅强调赠品多有价值。就算看了十遍二十遍,也还不知道它要卖什么。

    + +

    会不会我自己也犯是舍本逐末的毛病呢?跟人家说明事情的时候,会不会也花很多时间强调事物的附加价值,而很少提及事物本身的内容,以致人家花很多时间、精神听我说完话,还是一团迷雾呢?

    + +

    对此,深自警惕。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 95 | + 96 | + 97 | + 98 | + 99 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0097.html.zh-tw.html b/htdocs/imacat/me/diary/0097.html.zh-tw.html new file mode 120000 index 0000000..1c75e4a --- /dev/null +++ b/htdocs/imacat/me/diary/0097.html.zh-tw.html @@ -0,0 +1 @@ +0097.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0097.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0097.html.zh-tw.xhtml new file mode 100644 index 0000000..32c6ee2 --- /dev/null +++ b/htdocs/imacat/me/diary/0097.html.zh-tw.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷九十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷九十七

    + +
    + +
    + +
    +
    12.9.’06. 9:48pm.
    + +

    名探偵コナン 水平線上の陰謀 名偵探柯南 水平線上的陰謀 Detective Conan Strategy Above The Depth—假犯罪背後隱藏的真正犯人

    + +
    +名探偵コナン 水平線上の陰謀
    +

    名探偵コナン 水平線上の陰謀

    +
    + +
      +
    • 片名:名探偵コナン 水平線上の陰謀
    • +
    • 中譯片名:名偵探柯南 水平線上的陰謀 Detective Conan Strategy Above The Depth
    • +
    • 發行年份: 2005
    • +
    • 製作公司: 名探偵コナン製作委員会
    • +
    • 導演:山本泰一郎
    • +
    • 編劇:古内一成
    • +
    • 原作:青山剛昌名探偵コナン(週刊少年サンデー)
    • +
    + +

    名探偵コナン 水平線上の陰謀名探偵コナン的第九部電影。柯南、小蘭、小五郎、阿笠博士和少年偵探團,陪同應邀鈴木財團千金的園子,共同參加八代財團新豪華遊輪アフロディーテ号 Aphrodite 的處女首航,在船上結識了欲撰寫以豪華郵輪為題財的連續劇,而上船取材的電視台編劇日下ひろなり(日下祐成),及遊輪設計團隊副組長秋吉美波子。然而,就在首航前半個月,主設計師、秋吉美波子的老師、八代財團入贅女婿八代英人車禍墜崖死亡。而十五年前,八代財團的第一八代丸撞冰山沉船事件,壟罩著層層謎霧,當年倖存的副船長海藤渡,成了今日アフロディーテ号的船長。出海第一天上午,還沒來得及開始歡迎晚宴,園子就被攻擊,八代客船社長、會長長女八代貴江被殺,八代財團會長八代延太郎離奇失蹤。而這一連串的事件幕後的陰謀,還在一步步展開。

    + +

    名探偵コナン 水平線上の陰謀最特別的地方,是隱藏在假兇手背後的真兇。兇手是誰其實一開始就很明顯,破綻不少,故意讓觀眾知道。一切也非常合理。可是一直到最後,才突然發現,事件還有真正的兇手,掌握到的都不是真相。這種故意用假兇手做晃子,隱藏真兇手的設計,算是這一集的特色。

    + +

    然而,就算是假兇手,從頭到尾兇手就很明顯、非常合理的推理故事,讓人提不起勁。後來冒出來的真兇,也只能給人啊?怎麼會這樣?的感覺,因為之前太合情合理了,後來冒出來的真兇就十分牽強,柯南和小五郎的推理疑點,只有一點說得過去而已。

    + +

    柯南開快艇追上去,從正面額頭射入麻醉針那一幕,很亂來。那樣是會死人的,柯南就成了殺人現行犯了。

    + +

    劇情還賣弄了一段鐵達尼號的翻版。船上的旅客非富即貴,都是超級有錢人,是不是幾年後,會有人去打撈沉船發財呢?

    + +

    最後柯南感謝那串貝殼手鍊救了他。其實若不是那串貝殼手鍊,他和小蘭、小五郎根本就不會陷入險境才對。其實是害了他,不是救了他。

    + +
    + +
    + +
    +
    12.6.’06. 4:29am.
    + +

    捨本逐末

    + +

    今天坐計程車,前座椅背上貼著台灣大車隊賣書的廣告,賣的是一本叫我受夠了的書。廣告下標示是超越極限行銷顧問有限公司做的。我看了半天,還是看不大懂。

    + +

    廣告上不大的空間,寫著幾個大字:非買本書不可的理由:暢銷排行榜第一名、憂鬱症看了就痊癒了、賣書款捐公益等等。剩下的就是書名、照片。看了半天,這本書到底在寫什麼?還是不清楚。根本不知道是什麼書,只列出所謂非買不可的理由,不是捨本逐末嗎?

    + +

    這個社會上,充斥著這種捨本逐末的事:賣書不介紹內容,而是吹捧它排行榜第幾名。我們到底是為了自己的興趣、需要買書,還是為了怕別人看了我沒看而買書呢?街上充斥的廣告,不見它介紹商品本身,卻大幅強調贈品多有價值。就算看了十遍二十遍,也還不知道它要賣什麼。

    + +

    會不會我自己也犯是捨本逐末的毛病呢?跟人家說明事情的時候,會不會也花很多時間強調事物的附加價值,而很少提及事物本身的內容,以致人家花很多時間、精神聽我說完話,還是一團迷霧呢?

    + +

    對此,深自警惕。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 95 | + 96 | + 97 | + 98 | + 99 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0098.html.en.html b/htdocs/imacat/me/diary/0098.html.en.html new file mode 120000 index 0000000..9628c77 --- /dev/null +++ b/htdocs/imacat/me/diary/0098.html.en.html @@ -0,0 +1 @@ +0098.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0098.html.en.xhtml b/htdocs/imacat/me/diary/0098.html.en.xhtml new file mode 100644 index 0000000..81965ce --- /dev/null +++ b/htdocs/imacat/me/diary/0098.html.en.xhtml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 98 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 98

    + +
    + +
    + +
    +
    12.25.’06. 1:28pm.
    + +

    聖誕節

    + +

    今天是聖誕節,公司空空蕩蕩的。

    + +

    聖誕節對西方人來說,跟華人正月過年一樣。沒有人大過年的還要工作的。就像華人過年一過就是五六天一樣,西方人聖誕節,一休息就是一個禮拜,直到元旦。當然,旅居臺灣,沒有聖誕節的法定假期,就沒辦法像家鄉一樣,休息到元旦。可是,聖誕節就這一天,還是要過的。積了年假,也要休這一天;就算不夠年假,請假扣薪,也要休這一天。

    + +

    沒辦法,過年嘛~

    + +

    在美僑商公司上班,今天是人家的過年,連著老闆,大家都請假光光了,空蕩蕩的。唉,人家過年,也不好跟人家抱怨什麼。公司有幾個臺灣人,乾脆也跟著請假掉了。只剩下我,一個老先生,和一個美籍華裔的公司模範生。美國人到底為什麼大過年的還來上班呢?只能說人家實在是太乖了。

    + +

    說起來,臺灣人過聖誕節,還真是不倫不類。有一年聖誕節前,我問我們老闆,聖誕節打算怎麼過:

    + +
    +
    I: Do you have any plan on Christmas? Any party, or something? (聖誕節有什麼計劃?有要去參加什麼派對嗎?)
    + +
    T: No! 聖誕節是我們的過年,是全家聚在一起安靜渡過的平安夜。我們不會有什麼計劃。
    +
    + +

    我好像被敲了一記悶棍,恍然大悟。西方人過聖誕節像在過年。既然是過年,當然是全家慶團圓,旅居在外的家人也要回家,全家高高興興在家吃年夜飯,大人小孩親朋好友聯絡感情,休養生息,非常溫馨。就算萬里離鄉來臺灣,沒辦法團圓,也要好好在家休息,打個長途電話親友問安。沒有人聖誕節還出去狂歡的!大過年的,不待在家裏跑出去狂歡,像什麼樣子?

    + +

    傳到臺灣來,聖誕夜,有情侶的就去約會,沒情侶的就到處大開派對,餐廳、酒吧、旅館,人擠人擠得滿滿滿,沒有人回家。華人沒有聖誕節的傳統,搞成這樣不倫不類。看在西方人眼裏,神聖的傳統過年,傳到東方變成狂歡墮落夜;西方人全家團聚,傳到東方變成全家人各自出去鬼混。真是欲哭無淚,相對無言。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 96 | + 97 | + 98 | + 99 | + 100 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0098.html.zh-cn.html b/htdocs/imacat/me/diary/0098.html.zh-cn.html new file mode 120000 index 0000000..f677759 --- /dev/null +++ b/htdocs/imacat/me/diary/0098.html.zh-cn.html @@ -0,0 +1 @@ +0098.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0098.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0098.html.zh-cn.xhtml new file mode 100644 index 0000000..02dc67c --- /dev/null +++ b/htdocs/imacat/me/diary/0098.html.zh-cn.xhtml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷九十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷九十八

    + +
    + +
    + +
    +
    12.25.’06. 1:28pm.
    + +

    圣诞节

    + +

    今天是圣诞节,公司空空荡荡的。

    + +

    圣诞节对西方人来说,跟华人正月过年一样。没有人大过年的还要工作的。就像华人过年一过就是五六天一样,西方人圣诞节,一休息就是一个礼拜,直到元旦。当然,旅居台湾,没有圣诞节的法定假期,就没办法像家乡一样,休息到元旦。可是,圣诞节就这一天,还是要过的。积了年假,也要休这一天;就算不够年假,请假扣薪,也要休这一天。

    + +

    没办法,过年嘛~

    + +

    在美侨商公司上班,今天是人家的过年,连著老板,大家都请假光光了,空荡荡的。唉,人家过年,也不好跟人家抱怨什么。公司有几个台湾人,干脆也跟著请假掉了。只剩下我,一个老先生,和一个美籍华裔的公司模范生。美国人到底为什么大过年的还来上班呢?只能说人家实在是太乖了。

    + +

    说起来,台湾人过圣诞节,还真是不伦不类。有一年圣诞节前,我问我们老板,圣诞节打算怎么过:

    + +
    +
    I: Do you have any plan on Christmas? Any party, or something? (圣诞节有什么计划?有要去参加什么派对吗?)
    + +
    T: No! 圣诞节是我们的过年,是全家聚在一起安静渡过的平安夜。我们不会有什么计划。
    +
    + +

    我好像被敲了一记闷棍,恍然大悟。西方人过圣诞节像在过年。既然是过年,当然是全家庆团圆,旅居在外的家人也要回家,全家高高兴兴在家吃年夜饭,大人小孩亲朋好友联络感情,休养生息,非常温馨。就算万里离乡来台湾,没办法团圆,也要好好在家休息,打个长途电话亲友问安。没有人圣诞节还出去狂欢的!大过年的,不待在家里跑出去狂欢,像什么样子?

    + +

    传到台湾来,圣诞夜,有情侣的就去约会,没情侣的就到处大开派对,餐厅、酒吧、旅馆,人挤人挤得满满满,没有人回家。华人没有圣诞节的传统,搞成这样不伦不类。看在西方人眼里,神圣的传统过年,传到东方变成狂欢堕落夜;西方人全家团聚,传到东方变成全家人各自出去鬼混。真是欲哭无泪,相对无言。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 96 | + 97 | + 98 | + 99 | + 100 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0098.html.zh-tw.html b/htdocs/imacat/me/diary/0098.html.zh-tw.html new file mode 120000 index 0000000..1fff188 --- /dev/null +++ b/htdocs/imacat/me/diary/0098.html.zh-tw.html @@ -0,0 +1 @@ +0098.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0098.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0098.html.zh-tw.xhtml new file mode 100644 index 0000000..dd69810 --- /dev/null +++ b/htdocs/imacat/me/diary/0098.html.zh-tw.xhtml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷九十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷九十八

    + +
    + +
    + +
    +
    12.25.’06. 1:28pm.
    + +

    聖誕節

    + +

    今天是聖誕節,公司空空蕩蕩的。

    + +

    聖誕節對西方人來說,跟華人正月過年一樣。沒有人大過年的還要工作的。就像華人過年一過就是五六天一樣,西方人聖誕節,一休息就是一個禮拜,直到元旦。當然,旅居臺灣,沒有聖誕節的法定假期,就沒辦法像家鄉一樣,休息到元旦。可是,聖誕節就這一天,還是要過的。積了年假,也要休這一天;就算不夠年假,請假扣薪,也要休這一天。

    + +

    沒辦法,過年嘛~

    + +

    在美僑商公司上班,今天是人家的過年,連著老闆,大家都請假光光了,空蕩蕩的。唉,人家過年,也不好跟人家抱怨什麼。公司有幾個臺灣人,乾脆也跟著請假掉了。只剩下我,一個老先生,和一個美籍華裔的公司模範生。美國人到底為什麼大過年的還來上班呢?只能說人家實在是太乖了。

    + +

    說起來,臺灣人過聖誕節,還真是不倫不類。有一年聖誕節前,我問我們老闆,聖誕節打算怎麼過:

    + +
    +
    I: Do you have any plan on Christmas? Any party, or something? (聖誕節有什麼計劃?有要去參加什麼派對嗎?)
    + +
    T: No! 聖誕節是我們的過年,是全家聚在一起安靜渡過的平安夜。我們不會有什麼計劃。
    +
    + +

    我好像被敲了一記悶棍,恍然大悟。西方人過聖誕節像在過年。既然是過年,當然是全家慶團圓,旅居在外的家人也要回家,全家高高興興在家吃年夜飯,大人小孩親朋好友聯絡感情,休養生息,非常溫馨。就算萬里離鄉來臺灣,沒辦法團圓,也要好好在家休息,打個長途電話親友問安。沒有人聖誕節還出去狂歡的!大過年的,不待在家裏跑出去狂歡,像什麼樣子?

    + +

    傳到臺灣來,聖誕夜,有情侶的就去約會,沒情侶的就到處大開派對,餐廳、酒吧、旅館,人擠人擠得滿滿滿,沒有人回家。華人沒有聖誕節的傳統,搞成這樣不倫不類。看在西方人眼裏,神聖的傳統過年,傳到東方變成狂歡墮落夜;西方人全家團聚,傳到東方變成全家人各自出去鬼混。真是欲哭無淚,相對無言。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 96 | + 97 | + 98 | + 99 | + 100 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0099.html.en.html b/htdocs/imacat/me/diary/0099.html.en.html new file mode 120000 index 0000000..dd385c5 --- /dev/null +++ b/htdocs/imacat/me/diary/0099.html.en.html @@ -0,0 +1 @@ +0099.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0099.html.en.xhtml b/htdocs/imacat/me/diary/0099.html.en.xhtml new file mode 100644 index 0000000..145dfb6 --- /dev/null +++ b/htdocs/imacat/me/diary/0099.html.en.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 99 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 99

    + +
    + +
    + +
    +
    12.26.’06. 12:14pm.
    + +

    XmasX’mas

    + +

    今天看蘋果,看到這一則新聞,才知道:天哪!原來 X’mas 是錯的!我從小用 X’mas 用到大,用了那麼多年。幾年前還曾經用 X’mas 寄過 E-mail 聖誕卡。真是太丟臉了~

    + +

    原文轉貼自蘋果日報 2006-12-26 Xmas 遭華人誤用為 X’mas ,若有版權問題請不吝告知。

    + +
    +

    Xmas 遭華人誤用為 X’mas
    +有辭典解釋錯誤 牧師指簡寫不敬

    + +

    【綜合報導】聖誕節才過,但昨有許多網友上網正名指國人慣用的 X’mas 是錯的。蘋果昨連結各國網站,發現僅英語系網站未出現此寫法。英語老師指出要表達聖誕快樂 (Merry Christmas) 可用 XmasX-mas ,就是不能用 X’mas ,但台灣或許是約定俗成,錯誤的使用反而成為慣用。

    + + +

    約定俗成

    + +

    基督教福音協進會秘書長夏忠堅牧師更解釋, ChristmasChrist 代表基督,縮寫或簡寫都是錯誤且不敬,基督徒不會使用。

    + +

    X 等於 Christ

    + +

    蘋果昨走訪坊間商品,發現不少聖誕卡印製 X’mas 字樣外,連遠東百貨、微風商場最近印製的聖誕促銷文宣,甚至是萬人出版社出版的圖解小哈佛英漢辭典,當中對 X’mas 也做錯誤的聖誕快樂解釋,且強調該辭典專門為小孩子及小學生學習英語所使用

    + +

    輔英科技大學應用外文系主任陳英輝說, X 在希臘文等於 Christ ,是基督的意思,不需要用 縮寫,但在台灣 X’mas 已成通俗寫法。不過英語語法常尊重各地多元需求,不必吹毛求疵。在世新大學開新聞英語的新聞系講師林紫玉也說用 X’mas 的國人很多,已約定俗成。

    + +

    卡片沿用多年

    + +

    獲悉印製錯誤文宣的遠東、微風商場昨均表示錯愕,遠東百貨協理林彰豐表示,壓根不曉得 X’mas 是錯的,也不知會對基督徒不敬。百合卡片紙品公司外銷部門吳姓負責人則說,卡片業者多年來沿用 X’mas ,沒有人特別注意這是錯的。民眾蕭錦宣說,從不知 X’mas 是錯的。

    + +

    蘋果追查 X’mas 源由,找到日文版維基百科記載,一九四五年聖誕節聯合國總司令部正面玄關曾掛排成 Merry X’mas 字樣的霓虹燈飾,另英和辭典則指是日本人創造的誤用字,來源到底為何,國內學者昨均指無法證實。

    + +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 97 | + 98 | + 99 | + 100 | + 101 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0099.html.zh-cn.html b/htdocs/imacat/me/diary/0099.html.zh-cn.html new file mode 120000 index 0000000..ce1947c --- /dev/null +++ b/htdocs/imacat/me/diary/0099.html.zh-cn.html @@ -0,0 +1 @@ +0099.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0099.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0099.html.zh-cn.xhtml new file mode 100644 index 0000000..7e20690 --- /dev/null +++ b/htdocs/imacat/me/diary/0099.html.zh-cn.xhtml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷九十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷九十九

    + +
    + +
    + +
    +
    12.26.’06. 12:14pm.
    + +

    XmasX’mas

    + +

    今天看苹果,看到这一则新闻,才知道:天哪!原来 X’mas 是错的!我从小用 X’mas 用到大,用了那么多年。几年前还曾经用 X’mas 寄过 E-mail 圣诞卡。真是太丢脸了~

    + +

    原文转贴自苹果日报 2006-12-26 Xmas 遭华人误用为 X’mas ,若有版权问题请不吝告知。

    + +
    +

    Xmas 遭华人误用为 X’mas
    +有辞典解释错误 牧师指简写不敬

    + +

    【综合报导】圣诞节才过,但昨有许多网友上网正名指国人惯用的 X’mas 是错的。苹果昨连结各国网站,发现仅英语系网站未出现此写法。英语老师指出要表达圣诞快乐 (Merry Christmas) 可用 XmasX-mas ,就是不能用 X’mas ,但台湾或许是约定俗成,错误的使用反而成为惯用。

    + + +

    约定俗成

    + +

    基督教福音协进会秘书长夏忠坚牧师更解释, ChristmasChrist 代表基督,缩写或简写都是错误且不敬,基督徒不会使用。

    + +

    X 等於 Christ

    + +

    苹果昨走访坊间商品,发现不少圣诞卡印制 X’mas 字样外,连远东百货、微风商场最近印制的圣诞促销文宣,甚至是万人出版社出版的图解小哈佛英汉辞典,当中对 X’mas 也做错误的圣诞快乐解释,且强调该辞典专门为小孩子及小学生学习英语所使用

    + +

    辅英科技大学应用外文系主任陈英辉说, X 在希腊文等於 Christ ,是基督的意思,不需要用 缩写,但在台湾 X’mas 已成通俗写法。不过英语语法常尊重各地多元需求,不必吹毛求疵。在世新大学开新闻英语的新闻系讲师林紫玉也说用 X’mas 的国人很多,已约定俗成。

    + +

    卡片沿用多年

    + +

    获悉印制错误文宣的远东、微风商场昨均表示错愕,远东百货协理林彰丰表示,压根不晓得 X’mas 是错的,也不知会对基督徒不敬。百合卡片纸品公司外销部门吴姓负责人则说,卡片业者多年来沿用 X’mas ,没有人特别注意这是错的。民众萧锦宣说,从不知 X’mas 是错的。

    + +

    苹果追查 X’mas 源由,找到日文版维基百科记载,一九四五年圣诞节联合国总司令部正面玄关曾挂排成 Merry X’mas 字样的霓虹灯饰,另英和辞典则指是日本人创造的误用字,来源到底为何,国内学者昨均指无法证实。

    + +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 97 | + 98 | + 99 | + 100 | + 101 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0099.html.zh-tw.html b/htdocs/imacat/me/diary/0099.html.zh-tw.html new file mode 120000 index 0000000..6ce7114 --- /dev/null +++ b/htdocs/imacat/me/diary/0099.html.zh-tw.html @@ -0,0 +1 @@ +0099.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0099.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0099.html.zh-tw.xhtml new file mode 100644 index 0000000..eece6e6 --- /dev/null +++ b/htdocs/imacat/me/diary/0099.html.zh-tw.xhtml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷九十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷九十九

    + +
    + +
    + +
    +
    12.26.’06. 12:14pm.
    + +

    XmasX’mas

    + +

    今天看蘋果,看到這一則新聞,才知道:天哪!原來 X’mas 是錯的!我從小用 X’mas 用到大,用了那麼多年。幾年前還曾經用 X’mas 寄過 E-mail 聖誕卡。真是太丟臉了~

    + +

    原文轉貼自蘋果日報 2006-12-26 Xmas 遭華人誤用為 X’mas ,若有版權問題請不吝告知。

    + +
    +

    Xmas 遭華人誤用為 X’mas
    +有辭典解釋錯誤 牧師指簡寫不敬

    + +

    【綜合報導】聖誕節才過,但昨有許多網友上網正名指國人慣用的 X’mas 是錯的。蘋果昨連結各國網站,發現僅英語系網站未出現此寫法。英語老師指出要表達聖誕快樂 (Merry Christmas) 可用 XmasX-mas ,就是不能用 X’mas ,但台灣或許是約定俗成,錯誤的使用反而成為慣用。

    + + +

    約定俗成

    + +

    基督教福音協進會秘書長夏忠堅牧師更解釋, ChristmasChrist 代表基督,縮寫或簡寫都是錯誤且不敬,基督徒不會使用。

    + +

    X 等於 Christ

    + +

    蘋果昨走訪坊間商品,發現不少聖誕卡印製 X’mas 字樣外,連遠東百貨、微風商場最近印製的聖誕促銷文宣,甚至是萬人出版社出版的圖解小哈佛英漢辭典,當中對 X’mas 也做錯誤的聖誕快樂解釋,且強調該辭典專門為小孩子及小學生學習英語所使用

    + +

    輔英科技大學應用外文系主任陳英輝說, X 在希臘文等於 Christ ,是基督的意思,不需要用 縮寫,但在台灣 X’mas 已成通俗寫法。不過英語語法常尊重各地多元需求,不必吹毛求疵。在世新大學開新聞英語的新聞系講師林紫玉也說用 X’mas 的國人很多,已約定俗成。

    + +

    卡片沿用多年

    + +

    獲悉印製錯誤文宣的遠東、微風商場昨均表示錯愕,遠東百貨協理林彰豐表示,壓根不曉得 X’mas 是錯的,也不知會對基督徒不敬。百合卡片紙品公司外銷部門吳姓負責人則說,卡片業者多年來沿用 X’mas ,沒有人特別注意這是錯的。民眾蕭錦宣說,從不知 X’mas 是錯的。

    + +

    蘋果追查 X’mas 源由,找到日文版維基百科記載,一九四五年聖誕節聯合國總司令部正面玄關曾掛排成 Merry X’mas 字樣的霓虹燈飾,另英和辭典則指是日本人創造的誤用字,來源到底為何,國內學者昨均指無法證實。

    + +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 97 | + 98 | + 99 | + 100 | + 101 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0100.html.en.html b/htdocs/imacat/me/diary/0100.html.en.html new file mode 120000 index 0000000..59a076c --- /dev/null +++ b/htdocs/imacat/me/diary/0100.html.en.html @@ -0,0 +1 @@ +0100.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0100.html.en.xhtml b/htdocs/imacat/me/diary/0100.html.en.xhtml new file mode 100644 index 0000000..2c134b5 --- /dev/null +++ b/htdocs/imacat/me/diary/0100.html.en.xhtml @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 100 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 100

    + +
    + +
    + +
    +
    1.8.’07. 4:09pm.
    + +

    拔牙後記

    + +

    其實我也不是想寫這麼恐怖噁心的事的。不過這件事悶了一整天,也沒人可講。我想得到的朋友,都討厭噁心恐怖的事,跟她們講這件恐怖噁心的事都很不道德,十成十都會被罵被打。悶了一整天,自己一個人胡思亂想,越想越怕。還是在日記記下來好了,話說出來,心裏比較平安些。

    + +

    沒事沒事。本來就是醫療行為嘛~醫院開刀其實也不過如此,有什麼好怕的~

    + +
    + +
    + +
    +
    1.7.’07. 1:42pm.
    + +

    拔牙

    + +

    說實話,我沒拔過牙。

    + +

    長這麼大,沒拔過牙。不是自豪牙齒好,也不是怕拔牙,只是人比較懶,而且很會忍痛,所以牙痛常常忍一忍就過去了。也因為沒拔過牙,聽人家講怕拔牙怕成那樣,不免可笑。我很會忍痛,總覺得又不是小鬼怕痛,什麼事忍一忍就過去了。

    + +

    我的嘴裏右上方有一顆蛀牙,非常麻煩:十幾年前蛀到鬆掉,搖搖晃晃很不舒服。我有點手賤,一個人的時候,就用指甲去挖。挖久了,竟然被我敲下一塊來。剩下的半截斷在裏面,斷面是削尖的,會刮舌頭,更不舒服。

    + +

    大概十三、四年前,一個牙醫系的學長突然打電話給我,問我要不要看牙,他免費幫我看。那時候還沒有健保。想想也沒什麼不好,就去了。後來才知道他要湊實習病例數。第一次坐在牙醫椅上。因為是大教學醫院,設備齊全,還有那種把嘴撐開固定的儀器。我的嘴就這樣被硬撐開,前前後後花了快一個半小時。說話當然不能說了。痛是還好,只是整整一個半小時嘴合不上,臉痠得要命,真的很難受。

    + +

    學長告訴我,他抽了那顆蛀牙旁邊的神經。(所以我以後那附近都不會痛了。 ^^; )可是那顆牙蛀到太脆弱了,他試了幾次,牙齒一直折斷,最後剩下一小截外露,連夾子都上不去。他也沒辦法了,只好放棄。叫我去正式掛號,看比較有經驗的牙醫生。

    + +

    唔,好吧,反正以後不會牙痛了,也不是不好的事。而且人家也盡力了,用掉了那麼多一次性器材,也沒跟我收錢。那些一次性器材應該很貴吧。搖搖晃晃的半截都不見了,剩下的一小截也磨平不會刮舌頭,讓我難過的問題也算解決了。

    + +

    這幾年來幾次去牙醫診所洗牙,每次都會順便問到那截斷牙的事。每次醫生看一看,外露的那麼小截,都不大敢去碰,都叫我去大醫院看。這幾年來,臺灣也從沒有健保,變成有健保。

    + +

    上星期三晚上去巷子口的牙醫診所洗牙。健保後,小診所為了跟醫院競爭,都做得非常漂亮,環境優雅。一進去感覺就非常好,加上碰到了個笑得很甜很可愛的牙醫助理,洗牙時還一直主動幫我擦臉(雖然我洗牙時沒有張開眼睛看到。聽到有東西在鑽的聲音,眼不見為淨。 :p )好吧,我也算是被美色迷惑了。而且是年輕的帥哥診所院長幫我看診,非常慇勤。離開時,他還叮嚀我:

    + +

    妳有一些蛀牙…

    + +

    是上排對嗎?我打斷他的話。洗牙的時候會痠,我也有感覺到。對了,醫生,我右上方有一顆斷牙,可以處理嗎?

    + +

    可以呀。

    + +

    …真的嗎?我有點不敢置信。可是我那顆斷牙只剩下非常小一小截,很難拔。

    + +

    可以可以,沒有問題。

    + +

    那要花多久?

    + +

    大概二十分鐘吧。

    + +

    竟然可以拔掉。雖然這一小截斷牙這幾年不大困擾我了,可是還是想把它處理掉。我不知道院長是不是像學長一樣在騙我,不過在年輕帥哥院長的信心保證,可愛甜美助理的笑容,還有可以拔掉這四個字的誘惑下,我還是預約了,星期六早上十點拔牙,可以趕上十二點吃飯,下午空大上課。

    + +

    星期六早上,天氣冷得要死。我昨晚又趕案子到清晨,不小心就睡過頭了。可愛助理打電話來問我,害我非常不好意思,道完歉後,趕緊就出門了。就在巷子口,走路五分鐘。

    + +

    進門,又道了一次歉。等了一會,醫生忙完了,就輪到我了。我說清楚後,躺上病床,照舊開始裝死,五感皆空:什麼甜甜可愛牙醫助理,什麼帥哥醫生,什麼奇怪的聲音,什麼軟手幫我擦臉,我通通都看不見、聽不見、感覺不到。開始後悔沒背過金剛經,臨陣派不上用場。醫生一下子叫我頭偏這邊,一下子把我頭轉過去。我只感覺到有東西在我嘴裏刺呀刺,我通通都把它想像成是麻醉針。雖然麻醉針應該不需要打那麼多針,針頭應該也不需要用力左拐右彎,而且我抽過神經了,應該不大需要麻醉。

    + +

    果然比較難拔。過了半個多小時,醫生說好了。我睜開眼一看,旁邊盛著一個大的 L 型牙根,和幾片小斷牙,沾滿血。我知道牙根埋得很深很長,可是 L 型?有點難以理解。不過這是人家牙醫的專業,我本來就不懂了。這顆斷牙困擾我困擾了十年了,想想,就跟甜甜助理討回去做記念。甜甜助理小姐幫我用水盛了,還叮嚀我回家要用清水洗。下星期二約複診看傷口,綿花要咬一小時,麻醉退了才能吃東西之類的,一一叮嚀。

    + +

    看看時間才十一點,下午上課還早,就先回家。回家把牙齒拿出來洗,看看為什麼沾那麼多血,順便觀察一下 L 型的牙根構造。一摸,軟的,心涼了一半:側邊勾出來的不是牙,是肉。難怪外觀血紅一片。唔。裝著沒事,把我自己的肉用指甲挑掉,丟進垃圾筒,把牙洗乾淨,晾好準備出門上課。

    + +

    下午上課,上課無聊時,我都在想那塊牙根連肉的事。天氣又冷,整天整個人都很不舒服。我想也有一部份是因為剛拔牙,嘴裏有外傷,所以有點發燒吧。雖然我有按指示定時吃消炎止痛藥,可是多少還是會有點不舒服。

    + +

    原來如此。那在我嘴裏刺呀刺的,是在勾囉?牙醫拔牙都會連肉拔掉嗎?還是醫生技術不好才會這樣?我從沒吃過人肉,如果那小塊肉我沒丟掉,就可以吃吃看了。不知道是不是鹹的。吃自己的肉應該不犯法吧?可是搞不好上了什麼藥,也不能吃。想想怪噁心一把的。大概是外傷發燒吧,一直在胡思亂想這些事。

    + +

    開始瞭解牙醫恐怖之處了。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 98 | + 99 | + 100 | + 101 | + 102 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0100.html.zh-cn.html b/htdocs/imacat/me/diary/0100.html.zh-cn.html new file mode 120000 index 0000000..6ecaa5a --- /dev/null +++ b/htdocs/imacat/me/diary/0100.html.zh-cn.html @@ -0,0 +1 @@ +0100.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0100.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0100.html.zh-cn.xhtml new file mode 100644 index 0000000..d023087 --- /dev/null +++ b/htdocs/imacat/me/diary/0100.html.zh-cn.xhtml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百

    + +
    + +
    + +
    +
    1.8.’07. 4:09pm.
    + +

    拔牙后记

    + +

    其实我也不是想写这么恐怖恶心的事的。不过这件事闷了一整天,也没人可讲。我想得到的朋友,都讨厌恶心恐怖的事,跟她们讲这件恐怖恶心的事都很不道德,十成十都会被骂被打。闷了一整天,自己一个人胡思乱想,越想越怕。还是在日记记下来好了,话说出来,心里比较平安些。

    + +

    没事没事。本来就是医疗行为嘛~医院开刀其实也不过如此,有什么好怕的~

    + +
    + +
    + +
    +
    1.7.’07. 1:42pm.
    + +

    拔牙

    + +

    说实话,我没拔过牙。

    + +

    长这么大,没拔过牙。不是自豪牙齿好,也不是怕拔牙,只是人比较懒,而且很会忍痛,所以牙痛常常忍一忍就过去了。也因为没拔过牙,听人家讲怕拔牙怕成那样,不免可笑。我很会忍痛,总觉得又不是小鬼怕痛,什么事忍一忍就过去了。

    + +

    我的嘴里右上方有一颗蛀牙,非常麻烦:十几年前蛀到松掉,摇摇晃晃很不舒服。我有点手贱,一个人的时候,就用指甲去挖。挖久了,竟然被我敲下一块来。剩下的半截断在里面,断面是削尖的,会刮舌头,更不舒服。

    + +

    大概十三、四年前,一个牙医系的学长突然打电话给我,问我要不要看牙,他免费帮我看。那时候还没有健保。想想也没什么不好,就去了。后来才知道他要凑实习病例数。第一次坐在牙医椅上。因为是大教学医院,设备齐全,还有那种把嘴撑开固定的仪器。我的嘴就这样被硬撑开,前前后后花了快一个半小时。说话当然不能说了。痛是还好,只是整整一个半小时嘴合不上,脸酸得要命,真的很难受。

    + +

    学长告诉我,他抽了那颗蛀牙旁边的神经。(所以我以后那附近都不会痛了。 ^^; )可是那颗牙蛀到太脆弱了,他试了几次,牙齿一直折断,最后剩下一小截外露,连夹子都上不去。他也没办法了,只好放弃。叫我去正式挂号,看比较有经验的牙医生。

    + +

    唔,好吧,反正以后不会牙痛了,也不是不好的事。而且人家也尽力了,用掉了那么多一次性器材,也没跟我收钱。那些一次性器材应该很贵吧。摇摇晃晃的半截都不见了,剩下的一小截也磨平不会刮舌头,让我难过的问题也算解决了。

    + +

    这几年来几次去牙医诊所洗牙,每次都会顺便问到那截断牙的事。每次医生看一看,外露的那么小截,都不大敢去碰,都叫我去大医院看。这几年来,台湾也从没有健保,变成有健保。

    + +

    上星期三晚上去巷子口的牙医诊所洗牙。健保后,小诊所为了跟医院竞争,都做得非常漂亮,环境优雅。一进去感觉就非常好,加上碰到了个笑得很甜很可爱的牙医助理,洗牙时还一直主动帮我擦脸(虽然我洗牙时没有张开眼睛看到。听到有东西在钻的声音,眼不见为净。 :p )好吧,我也算是被美色迷惑了。而且是年轻的帅哥诊所院长帮我看诊,非常殷勤。离开时,他还叮咛我:

    + +

    你有一些蛀牙…

    + +

    是上排对吗?我打断他的话。洗牙的时候会酸,我也有感觉到。对了,医生,我右上方有一颗断牙,可以处理吗?

    + +

    可以呀。

    + +

    …真的吗?我有点不敢置信。可是我那颗断牙只剩下非常小一小截,很难拔。

    + +

    可以可以,没有问题。

    + +

    那要花多久?

    + +

    大概二十分钟吧。

    + +

    竟然可以拔掉。虽然这一小截断牙这几年不大困扰我了,可是还是想把它处理掉。我不知道院长是不是像学长一样在骗我,不过在年轻帅哥院长的信心保证,可爱甜美助理的笑容,还有可以拔掉这四个字的诱惑下,我还是预约了,星期六早上十点拔牙,可以赶上十二点吃饭,下午空大上课。

    + +

    星期六早上,天气冷得要死。我昨晚又赶案子到清晨,不小心就睡过头了。可爱助理打电话来问我,害我非常不好意思,道完歉后,赶紧就出门了。就在巷子口,走路五分钟。

    + +

    进门,又道了一次歉。等了一会,医生忙完了,就轮到我了。我说清楚后,躺上病床,照旧开始装死,五感皆空:什么甜甜可爱牙医助理,什么帅哥医生,什么奇怪的声音,什么软手帮我擦脸,我通通都看不见、听不见、感觉不到。开始后悔没背过金刚经,临阵派不上用场。医生一下子叫我头偏这边,一下子把我头转过去。我只感觉到有东西在我嘴里刺呀刺,我通通都把它想像成是麻醉针。虽然麻醉针应该不需要打那么多针,针头应该也不需要用力左拐右弯,而且我抽过神经了,应该不大需要麻醉。

    + +

    果然比较难拔。过了半个多小时,医生说好了。我睁开眼一看,旁边盛著一个大的 L 型牙根,和几片小断牙,沾满血。我知道牙根埋得很深很长,可是 L 型?有点难以理解。不过这是人家牙医的专业,我本来就不懂了。这颗断牙困扰我困扰了十年了,想想,就跟甜甜助理讨回去做记念。甜甜助理小姐帮我用水盛了,还叮咛我回家要用清水洗。下星期二约复诊看伤口,绵花要咬一小时,麻醉退了才能吃东西之类的,一一叮咛。

    + +

    看看时间才十一点,下午上课还早,就先回家。回家把牙齿拿出来洗,看看为什么沾那么多血,顺便观察一下 L 型的牙根构造。一摸,软的,心凉了一半:侧边勾出来的不是牙,是肉。难怪外观血红一片。唔。装著没事,把我自己的肉用指甲挑掉,丢进垃圾筒,把牙洗干净,晾好准备出门上课。

    + +

    下午上课,上课无聊时,我都在想那块牙根连肉的事。天气又冷,整天整个人都很不舒服。我想也有一部份是因为刚拔牙,嘴里有外伤,所以有点发烧吧。虽然我有按指示定时吃消炎止痛药,可是多少还是会有点不舒服。

    + +

    原来如此。那在我嘴里刺呀刺的,是在勾罗?牙医拔牙都会连肉拔掉吗?还是医生技术不好才会这样?我从没吃过人肉,如果那小块肉我没丢掉,就可以吃吃看了。不知道是不是咸的。吃自己的肉应该不犯法吧?可是搞不好上了什么药,也不能吃。想想怪恶心一把的。大概是外伤发烧吧,一直在胡思乱想这些事。

    + +

    开始了解牙医恐怖之处了。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 98 | + 99 | + 100 | + 101 | + 102 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0100.html.zh-tw.html b/htdocs/imacat/me/diary/0100.html.zh-tw.html new file mode 120000 index 0000000..2728121 --- /dev/null +++ b/htdocs/imacat/me/diary/0100.html.zh-tw.html @@ -0,0 +1 @@ +0100.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0100.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0100.html.zh-tw.xhtml new file mode 100644 index 0000000..30ee094 --- /dev/null +++ b/htdocs/imacat/me/diary/0100.html.zh-tw.xhtml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百

    + +
    + +
    + +
    +
    1.8.’07. 4:09pm.
    + +

    拔牙後記

    + +

    其實我也不是想寫這麼恐怖噁心的事的。不過這件事悶了一整天,也沒人可講。我想得到的朋友,都討厭噁心恐怖的事,跟她們講這件恐怖噁心的事都很不道德,十成十都會被罵被打。悶了一整天,自己一個人胡思亂想,越想越怕。還是在日記記下來好了,話說出來,心裏比較平安些。

    + +

    沒事沒事。本來就是醫療行為嘛~醫院開刀其實也不過如此,有什麼好怕的~

    + +
    + +
    + +
    +
    1.7.’07. 1:42pm.
    + +

    拔牙

    + +

    說實話,我沒拔過牙。

    + +

    長這麼大,沒拔過牙。不是自豪牙齒好,也不是怕拔牙,只是人比較懶,而且很會忍痛,所以牙痛常常忍一忍就過去了。也因為沒拔過牙,聽人家講怕拔牙怕成那樣,不免可笑。我很會忍痛,總覺得又不是小鬼怕痛,什麼事忍一忍就過去了。

    + +

    我的嘴裏右上方有一顆蛀牙,非常麻煩:十幾年前蛀到鬆掉,搖搖晃晃很不舒服。我有點手賤,一個人的時候,就用指甲去挖。挖久了,竟然被我敲下一塊來。剩下的半截斷在裏面,斷面是削尖的,會刮舌頭,更不舒服。

    + +

    大概十三、四年前,一個牙醫系的學長突然打電話給我,問我要不要看牙,他免費幫我看。那時候還沒有健保。想想也沒什麼不好,就去了。後來才知道他要湊實習病例數。第一次坐在牙醫椅上。因為是大教學醫院,設備齊全,還有那種把嘴撐開固定的儀器。我的嘴就這樣被硬撐開,前前後後花了快一個半小時。說話當然不能說了。痛是還好,只是整整一個半小時嘴合不上,臉痠得要命,真的很難受。

    + +

    學長告訴我,他抽了那顆蛀牙旁邊的神經。(所以我以後那附近都不會痛了。 ^^; )可是那顆牙蛀到太脆弱了,他試了幾次,牙齒一直折斷,最後剩下一小截外露,連夾子都上不去。他也沒辦法了,只好放棄。叫我去正式掛號,看比較有經驗的牙醫生。

    + +

    唔,好吧,反正以後不會牙痛了,也不是不好的事。而且人家也盡力了,用掉了那麼多一次性器材,也沒跟我收錢。那些一次性器材應該很貴吧。搖搖晃晃的半截都不見了,剩下的一小截也磨平不會刮舌頭,讓我難過的問題也算解決了。

    + +

    這幾年來幾次去牙醫診所洗牙,每次都會順便問到那截斷牙的事。每次醫生看一看,外露的那麼小截,都不大敢去碰,都叫我去大醫院看。這幾年來,臺灣也從沒有健保,變成有健保。

    + +

    上星期三晚上去巷子口的牙醫診所洗牙。健保後,小診所為了跟醫院競爭,都做得非常漂亮,環境優雅。一進去感覺就非常好,加上碰到了個笑得很甜很可愛的牙醫助理,洗牙時還一直主動幫我擦臉(雖然我洗牙時沒有張開眼睛看到。聽到有東西在鑽的聲音,眼不見為淨。 :p )好吧,我也算是被美色迷惑了。而且是年輕的帥哥診所院長幫我看診,非常慇勤。離開時,他還叮嚀我:

    + +

    妳有一些蛀牙…

    + +

    是上排對嗎?我打斷他的話。洗牙的時候會痠,我也有感覺到。對了,醫生,我右上方有一顆斷牙,可以處理嗎?

    + +

    可以呀。

    + +

    …真的嗎?我有點不敢置信。可是我那顆斷牙只剩下非常小一小截,很難拔。

    + +

    可以可以,沒有問題。

    + +

    那要花多久?

    + +

    大概二十分鐘吧。

    + +

    竟然可以拔掉。雖然這一小截斷牙這幾年不大困擾我了,可是還是想把它處理掉。我不知道院長是不是像學長一樣在騙我,不過在年輕帥哥院長的信心保證,可愛甜美助理的笑容,還有可以拔掉這四個字的誘惑下,我還是預約了,星期六早上十點拔牙,可以趕上十二點吃飯,下午空大上課。

    + +

    星期六早上,天氣冷得要死。我昨晚又趕案子到清晨,不小心就睡過頭了。可愛助理打電話來問我,害我非常不好意思,道完歉後,趕緊就出門了。就在巷子口,走路五分鐘。

    + +

    進門,又道了一次歉。等了一會,醫生忙完了,就輪到我了。我說清楚後,躺上病床,照舊開始裝死,五感皆空:什麼甜甜可愛牙醫助理,什麼帥哥醫生,什麼奇怪的聲音,什麼軟手幫我擦臉,我通通都看不見、聽不見、感覺不到。開始後悔沒背過金剛經,臨陣派不上用場。醫生一下子叫我頭偏這邊,一下子把我頭轉過去。我只感覺到有東西在我嘴裏刺呀刺,我通通都把它想像成是麻醉針。雖然麻醉針應該不需要打那麼多針,針頭應該也不需要用力左拐右彎,而且我抽過神經了,應該不大需要麻醉。

    + +

    果然比較難拔。過了半個多小時,醫生說好了。我睜開眼一看,旁邊盛著一個大的 L 型牙根,和幾片小斷牙,沾滿血。我知道牙根埋得很深很長,可是 L 型?有點難以理解。不過這是人家牙醫的專業,我本來就不懂了。這顆斷牙困擾我困擾了十年了,想想,就跟甜甜助理討回去做記念。甜甜助理小姐幫我用水盛了,還叮嚀我回家要用清水洗。下星期二約複診看傷口,綿花要咬一小時,麻醉退了才能吃東西之類的,一一叮嚀。

    + +

    看看時間才十一點,下午上課還早,就先回家。回家把牙齒拿出來洗,看看為什麼沾那麼多血,順便觀察一下 L 型的牙根構造。一摸,軟的,心涼了一半:側邊勾出來的不是牙,是肉。難怪外觀血紅一片。唔。裝著沒事,把我自己的肉用指甲挑掉,丟進垃圾筒,把牙洗乾淨,晾好準備出門上課。

    + +

    下午上課,上課無聊時,我都在想那塊牙根連肉的事。天氣又冷,整天整個人都很不舒服。我想也有一部份是因為剛拔牙,嘴裏有外傷,所以有點發燒吧。雖然我有按指示定時吃消炎止痛藥,可是多少還是會有點不舒服。

    + +

    原來如此。那在我嘴裏刺呀刺的,是在勾囉?牙醫拔牙都會連肉拔掉嗎?還是醫生技術不好才會這樣?我從沒吃過人肉,如果那小塊肉我沒丟掉,就可以吃吃看了。不知道是不是鹹的。吃自己的肉應該不犯法吧?可是搞不好上了什麼藥,也不能吃。想想怪噁心一把的。大概是外傷發燒吧,一直在胡思亂想這些事。

    + +

    開始瞭解牙醫恐怖之處了。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 98 | + 99 | + 100 | + 101 | + 102 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0101.html.en.html b/htdocs/imacat/me/diary/0101.html.en.html new file mode 120000 index 0000000..e374af1 --- /dev/null +++ b/htdocs/imacat/me/diary/0101.html.en.html @@ -0,0 +1 @@ +0101.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0101.html.en.xhtml b/htdocs/imacat/me/diary/0101.html.en.xhtml new file mode 100644 index 0000000..a311f82 --- /dev/null +++ b/htdocs/imacat/me/diary/0101.html.en.xhtml @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 101 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 101

    + +
    + +
    + +
    +
    1.15.’07. 4:44am.
    + +

    空大 古典小說導讀 課本勘誤

    + +

    因為是我在空大最後一個學期了,修的課少,所以課本讀得比之前幾個學期用心一些。古典小說選讀,雖說是選讀,但我把第一章概說引到的小說,大概都找來看過了。對照之下,發現有下列問題:

    + +
      +
    1. 第一章 第二節 三、愛情婚姻 2.離魂、鬼魂以求愛情 P.13–14 聶小倩

      + +

      …後來,精通法術的燕赤霞,適時伸出援手,殺了老妖,救了小倩和寧采臣。

      + +

      但參照聶小倩原文,燕赤霞並未殺老妖,是燕赤霞遺留的劍袋,收了老妖。燕赤霞殺老妖,是電影情節,不是小說情節:

      + +

      …次日,又命移懸戶上。夜對燭坐,約甯勿寢。歘有一物,如飛鳥墮。女驚匿夾幙間。甯視之,物如夜叉狀,電目血舌,睒閃攫拏而前。至門卻步﹔逡巡久之,漸近革囊,以爪摘取,似將抓裂。囊忽格然一響,大可合簣﹔恍惚有鬼物,突出半身,揪夜叉入,聲遂寂然,囊亦頓縮如故。甯駭詫。女亦出,大喜曰:無恙矣!共視囊中,清水數斗而已。

      +
    2. + +
    3. 第一章 第二節 三、愛情婚姻 2.離魂、鬼魂以求愛情 P.14 連城

      + +

      …經過生死相從,兩個有情人在陰司完成了自主婚姻。

      + +

      但參照連城原文,根本沒有提到兩人在陰司完婚。在陰司只有重會,相偕回陽,回陽前委身而已。完婚是回陽以後的事:

      + +

      …方舁入室,視之已醒。告父曰:兒已委身喬郎矣,更無歸理。如有變動,但仍一死!史歸,遣婢往役給奉。

      +
    4. + +
    5. 第一章 第二節 三、無知迷信 P.11 假神仙大鬧華興廟

      + +

      應該是假神仙大鬧華光廟,是華光廟,不是華興廟。

      +
    6. + +
    7. 第一章 第二節 三、愛情婚姻 2.離魂、鬼魂以求愛情 P.13 金明池吳清逢爱爱

      + +

      不是應該是金明池吳清逢愛愛嗎?爱爱是簡體字,原文是愛愛吧?

      +
    8. + +
    9. 第一章 第二節 五、神怪幻異 P.19

      + +

      搜神記卷十三裏的老婦在浴中變成了大鼈,後入水中遁去。

      + +

      應該是卷十四,不是卷十三:

      + +

      漢靈帝時,江夏黃氏之母浴盤水中,久而不起,變為鼋矣。婢驚走告。比家人來,鼋轉入深淵。其後時時出見。初,浴,簪一銀釵,猶在其首。於是黃氏累世不敢食鼋肉。

      +
    10. + +
    11. 第一章 第四節 P.28

      + +

      世說新語言語中記載了王述的兒子勸他把尚書令的職務…

      + +

      經查該篇應在世說新語方正第五的第四十七篇,不在言語第二

      + +

      王述轉尚書令,事行便拜。文度曰:故應讓杜許。藍田云:汝謂我堪此不?文度曰:何為不堪,但克讓是美事,恐不可闕。藍田慨然曰:既云堪,何為復讓?人言汝勝我,定不如我。

      +
    12. + +
    13. 第一章 第四節 P.29

      + +

      世說新語賢媛中…她丟下刀,抱著李氏道:我見猶憐,何況老奴!這也就是我見猶憐這句成語的由來。

      + +

      經查世說新語賢媛第十九第二十一篇,原文並無我見猶憐一句,而是出於其後南朝梁劉孝標注,引南朝宋虞通妒記。原文:

      + +

      桓宣武平蜀,以李勢妹為妾,甚有寵,常著齋後。主始不知,既聞,與數十婢拔白刃襲之。正值李梳頭,發委藉地,膚色玉曜,不為動容。徐曰:國破家亡,無心至此;今日若能見殺,乃是本懷。主慚而退。

      + +

      劉孝標注:妒記曰:溫平蜀,以李勢女為妾,郡主兇妒,不即知之。後知,乃拔刃往李所,因欲斫之。見李在窗梳頭,姿貌端麗,徐徐結髮,斂手向主,神色閑正,辭甚悽惋。主於是擲刀前抱之曰:阿子,我見汝亦憐,何況老奴。遂善之。

      +
    14. +
    + +
    + +
    + +
    +
    1.12.’07. 2:08pm.
    + +

    霍小玉傳

    + +

    唐傳奇霍小玉傳,收錄在太平廣記卷第四百八十七雜傳記四,作者蔣防,是很有名的故事。霍小玉傳講負心薄倖的文人李益,結識霍小玉,始亂終棄,奉母命娶盧氏,避而不見。霍小玉悲憤而死,死前詛咒李益妻妾不安。後李益家中時常出現不明人影,李益疑妻出牆,猜忌虐妻,數娶數離,終為不安。

    + +

    霍小玉傳是有名的負心漢遭報應的故事。後人講到負心薄倖,皆不免想到霍小玉的故事。既憐霍小玉年輕薄命,又恨李益負心薄情。

    + +

    我查了查李益,真有其人,是唐時名詩人。除了詩名外,李益另一件有名的就是對妻妾善妒疑忌,當時人因此將男子善妒妻者,稱為李益疾

    + +

    這樣看來,或許霍小玉傳是當時妒忌李益功名的蔣防的詆燬之作。這又和唐代牛李黨爭有關。唐時牛李黨爭,蔣防被李黨的元稹、李紳薦為翰林學士,後被貶為汀州刺史,數年間連貶數處,輾轉流離。牛黨的李益則是進士科舉出身。可能是揭發李益早年醜事,又或是附會李益妒妻之名,杜撰早年始亂終棄八掛故事醜化李益。牛黨的蔣防藉霍小玉傳攻詰李黨的李益,霍小玉傳可視為牛李黨爭下的其中一環。

    + +

    從這個角度看,讓我對霍小玉傳的意義,除了講負心薄倖的故事外,又多了一層認識。

    + +

    雖然,即便不知這些真實的時事背景,單讀小說霍小玉傳,也非常精彩。霍小玉傳原為附會李益善妒,八掛其早年不堪的醜事。流傳久了,李益時人時事已不復為人所知,而霍小玉的深情怨屈,引人嗟嘆。明人湯顯祖依霍小玉傳改寫成戲曲紫蕭記,後又改寫成戲曲紫釵記霍小玉傳中霍小玉典當的紫玉釵,成為兩人相識、定情之物,後李益被盧太守逼婚,霍小玉吞釵不嫁,最後兩人終成眷屬。順應觀眾盼望,薄情的李益成了為強豪逼迫的李益,最後還得了喜劇結尾。但和李益時人時事,已相去甚遠。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 99 | + 100 | + 101 | + 102 | + 103 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0101.html.zh-cn.html b/htdocs/imacat/me/diary/0101.html.zh-cn.html new file mode 120000 index 0000000..11f9199 --- /dev/null +++ b/htdocs/imacat/me/diary/0101.html.zh-cn.html @@ -0,0 +1 @@ +0101.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0101.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0101.html.zh-cn.xhtml new file mode 100644 index 0000000..7ac9b3d --- /dev/null +++ b/htdocs/imacat/me/diary/0101.html.zh-cn.xhtml @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百零一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百零一

    + +
    + +
    + +
    +
    1.15.’07. 4:44am.
    + +

    空大 古典小说导读 课本勘误

    + +

    因为是我在空大最后一个学期了,修的课少,所以课本读得比之前几个学期用心一些。古典小说选读,虽说是选读,但我把第一章概说引到的小说,大概都找来看过了。对照之下,发现有下列问题:

    + +
      +
    1. 第一章 第二节 三、爱情婚姻 2.离魂、鬼魂以求爱情 P.13–14 聂小倩

      + +

      …后来,精通法术的燕赤霞,适时伸出援手,杀了老妖,救了小倩和宁采臣。

      + +

      但参照聂小倩原文,燕赤霞并未杀老妖,是燕赤霞遗留的剑袋,收了老妖。燕赤霞杀老妖,是电影情节,不是小说情节:

      + +

      …次日,又命移悬户上。夜对烛坐,约宁勿寝。歘有一物,如飞鸟堕。女惊匿夹幙间。宁视之,物如夜叉状,电目血舌,睒闪攫拏而前。至门却步;逡巡久之,渐近革囊,以爪摘取,似将抓裂。囊忽格然一响,大可合篑;恍惚有鬼物,突出半身,揪夜叉入,声遂寂然,囊亦顿缩如故。宁骇诧。女亦出,大喜曰:无恙矣!共视囊中,清水数斗而已。

      +
    2. + +
    3. 第一章 第二节 三、爱情婚姻 2.离魂、鬼魂以求爱情 P.14 连城

      + +

      …经过生死相从,两个有情人在阴司完成了自主婚姻。

      + +

      但参照连城原文,根本没有提到两人在阴司完婚。在阴司只有重会,相偕回阳,回阳前委身而已。完婚是回阳以后的事:

      + +

      …方舁入室,视之已醒。告父曰:儿已委身乔郎矣,更无归理。如有变动,但仍一死!史归,遣婢往役给奉。

      +
    4. + +
    5. 第一章 第二节 三、无知迷信 P.11 假神仙大闹华兴庙

      + +

      应该是假神仙大闹华光庙,是华光庙,不是华兴庙。

      +
    6. + +
    7. 第一章 第二节 三、爱情婚姻 2.离魂、鬼魂以求爱情 P.13 金明池吴清逢爱爱

      + +

      不是应该是金明池吴清逢爱爱吗?爱爱是简体字,原文是爱爱吧?

      +
    8. + +
    9. 第一章 第二节 五、神怪幻异 P.19

      + +

      搜神记卷十三里的老妇在浴中变成了大鼈,后入水中遁去。

      + +

      应该是卷十四,不是卷十三:

      + +

      汉灵帝时,江夏黄氏之母浴盘水中,久而不起,变为鼋矣。婢惊走告。比家人来,鼋转入深渊。其后时时出见。初,浴,簪一银钗,犹在其首。於是黄氏累世不敢食鼋肉。

      +
    10. + +
    11. 第一章 第四节 P.28

      + +

      世说新语言语中记载了王述的儿子劝他把尚书令的职务…

      + +

      经查该篇应在世说新语方正第五的第四十七篇,不在言语第二

      + +

      王述转尚书令,事行便拜。文度曰:故应让杜许。蓝田云:汝谓我堪此不?文度曰:何为不堪,但克让是美事,恐不可阙。蓝田慨然曰:既云堪,何为复让?人言汝胜我,定不如我。

      +
    12. + +
    13. 第一章 第四节 P.29

      + +

      世说新语贤媛中…她丢下刀,抱著李氏道:我见犹怜,何况老奴!这也就是我见犹怜这句成语的由来。

      + +

      经查世说新语贤媛第十九第二十一篇,原文并无我见犹怜一句,而是出於其后南朝梁刘孝标注,引南朝宋虞通妒记。原文:

      + +

      桓宣武平蜀,以李势妹为妾,甚有宠,常著斋后。主始不知,既闻,与数十婢拔白刃袭之。正值李梳头,发委藉地,肤色玉曜,不为动容。徐曰:国破家亡,无心至此;今日若能见杀,乃是本怀。主惭而退。

      + +

      刘孝标注:妒记曰:温平蜀,以李势女为妾,郡主凶妒,不即知之。后知,乃拔刃往李所,因欲斫之。见李在窗梳头,姿貌端丽,徐徐结发,敛手向主,神色闲正,辞甚凄惋。主於是掷刀前抱之曰:阿子,我见汝亦怜,何况老奴。遂善之。

      +
    14. +
    + +
    + +
    + +
    +
    1.12.’07. 2:08pm.
    + +

    霍小玉传

    + +

    唐传奇霍小玉传,收录在太平广记卷第四百八十七杂传记四,作者蒋防,是很有名的故事。霍小玉传讲负心薄幸的文人李益,结识霍小玉,始乱终弃,奉母命娶卢氏,避而不见。霍小玉悲愤而死,死前诅咒李益妻妾不安。后李益家中时常出现不明人影,李益疑妻出墙,猜忌虐妻,数娶数离,终为不安。

    + +

    霍小玉传是有名的负心汉遭报应的故事。后人讲到负心薄幸,皆不免想到霍小玉的故事。既怜霍小玉年轻薄命,又恨李益负心薄情。

    + +

    我查了查李益,真有其人,是唐时名诗人。除了诗名外,李益另一件有名的就是对妻妾善妒疑忌,当时人因此将男子善妒妻者,称为李益疾

    + +

    这样看来,或许霍小玉传是当时妒忌李益功名的蒋防的诋毁之作。这又和唐代牛李党争有关。唐时牛李党争,蒋防被李党的元稹、李绅荐为翰林学士,后被贬为汀州刺史,数年间连贬数处,辗转流离。牛党的李益则是进士科举出身。可能是揭发李益早年丑事,又或是附会李益妒妻之名,杜撰早年始乱终弃八挂故事丑化李益。牛党的蒋防藉霍小玉传攻诘李党的李益,霍小玉传可视为牛李党争下的其中一环。

    + +

    从这个角度看,让我对霍小玉传的意义,除了讲负心薄幸的故事外,又多了一层认识。

    + +

    虽然,即便不知这些真实的时事背景,单读小说霍小玉传,也非常精彩。霍小玉传原为附会李益善妒,八挂其早年不堪的丑事。流传久了,李益时人时事已不复为人所知,而霍小玉的深情怨屈,引人嗟叹。明人汤显祖依霍小玉传改写成戏曲紫萧记,后又改写成戏曲紫钗记霍小玉传中霍小玉典当的紫玉钗,成为两人相识、定情之物,后李益被卢太守逼婚,霍小玉吞钗不嫁,最后两人终成眷属。顺应观众盼望,薄情的李益成了为强豪逼迫的李益,最后还得了喜剧结尾。但和李益时人时事,已相去甚远。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 99 | + 100 | + 101 | + 102 | + 103 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0101.html.zh-tw.html b/htdocs/imacat/me/diary/0101.html.zh-tw.html new file mode 120000 index 0000000..a40ec42 --- /dev/null +++ b/htdocs/imacat/me/diary/0101.html.zh-tw.html @@ -0,0 +1 @@ +0101.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0101.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0101.html.zh-tw.xhtml new file mode 100644 index 0000000..bc8af4d --- /dev/null +++ b/htdocs/imacat/me/diary/0101.html.zh-tw.xhtml @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百零一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百零一

    + +
    + +
    + +
    +
    1.15.’07. 4:44am.
    + +

    空大 古典小說導讀 課本勘誤

    + +

    因為是我在空大最後一個學期了,修的課少,所以課本讀得比之前幾個學期用心一些。古典小說選讀,雖說是選讀,但我把第一章概說引到的小說,大概都找來看過了。對照之下,發現有下列問題:

    + +
      +
    1. 第一章 第二節 三、愛情婚姻 2.離魂、鬼魂以求愛情 P.13–14 聶小倩

      + +

      …後來,精通法術的燕赤霞,適時伸出援手,殺了老妖,救了小倩和寧采臣。

      + +

      但參照聶小倩原文,燕赤霞並未殺老妖,是燕赤霞遺留的劍袋,收了老妖。燕赤霞殺老妖,是電影情節,不是小說情節:

      + +

      …次日,又命移懸戶上。夜對燭坐,約甯勿寢。歘有一物,如飛鳥墮。女驚匿夾幙間。甯視之,物如夜叉狀,電目血舌,睒閃攫拏而前。至門卻步﹔逡巡久之,漸近革囊,以爪摘取,似將抓裂。囊忽格然一響,大可合簣﹔恍惚有鬼物,突出半身,揪夜叉入,聲遂寂然,囊亦頓縮如故。甯駭詫。女亦出,大喜曰:無恙矣!共視囊中,清水數斗而已。

      +
    2. + +
    3. 第一章 第二節 三、愛情婚姻 2.離魂、鬼魂以求愛情 P.14 連城

      + +

      …經過生死相從,兩個有情人在陰司完成了自主婚姻。

      + +

      但參照連城原文,根本沒有提到兩人在陰司完婚。在陰司只有重會,相偕回陽,回陽前委身而已。完婚是回陽以後的事:

      + +

      …方舁入室,視之已醒。告父曰:兒已委身喬郎矣,更無歸理。如有變動,但仍一死!史歸,遣婢往役給奉。

      +
    4. + +
    5. 第一章 第二節 三、無知迷信 P.11 假神仙大鬧華興廟

      + +

      應該是假神仙大鬧華光廟,是華光廟,不是華興廟。

      +
    6. + +
    7. 第一章 第二節 三、愛情婚姻 2.離魂、鬼魂以求愛情 P.13 金明池吳清逢爱爱

      + +

      不是應該是金明池吳清逢愛愛嗎?爱爱是簡體字,原文是愛愛吧?

      +
    8. + +
    9. 第一章 第二節 五、神怪幻異 P.19

      + +

      搜神記卷十三裏的老婦在浴中變成了大鼈,後入水中遁去。

      + +

      應該是卷十四,不是卷十三:

      + +

      漢靈帝時,江夏黃氏之母浴盤水中,久而不起,變為鼋矣。婢驚走告。比家人來,鼋轉入深淵。其後時時出見。初,浴,簪一銀釵,猶在其首。於是黃氏累世不敢食鼋肉。

      +
    10. + +
    11. 第一章 第四節 P.28

      + +

      世說新語言語中記載了王述的兒子勸他把尚書令的職務…

      + +

      經查該篇應在世說新語方正第五的第四十七篇,不在言語第二

      + +

      王述轉尚書令,事行便拜。文度曰:故應讓杜許。藍田云:汝謂我堪此不?文度曰:何為不堪,但克讓是美事,恐不可闕。藍田慨然曰:既云堪,何為復讓?人言汝勝我,定不如我。

      +
    12. + +
    13. 第一章 第四節 P.29

      + +

      世說新語賢媛中…她丟下刀,抱著李氏道:我見猶憐,何況老奴!這也就是我見猶憐這句成語的由來。

      + +

      經查世說新語賢媛第十九第二十一篇,原文並無我見猶憐一句,而是出於其後南朝梁劉孝標注,引南朝宋虞通妒記。原文:

      + +

      桓宣武平蜀,以李勢妹為妾,甚有寵,常著齋後。主始不知,既聞,與數十婢拔白刃襲之。正值李梳頭,發委藉地,膚色玉曜,不為動容。徐曰:國破家亡,無心至此;今日若能見殺,乃是本懷。主慚而退。

      + +

      劉孝標注:妒記曰:溫平蜀,以李勢女為妾,郡主兇妒,不即知之。後知,乃拔刃往李所,因欲斫之。見李在窗梳頭,姿貌端麗,徐徐結髮,斂手向主,神色閑正,辭甚悽惋。主於是擲刀前抱之曰:阿子,我見汝亦憐,何況老奴。遂善之。

      +
    14. +
    + +
    + +
    + +
    +
    1.12.’07. 2:08pm.
    + +

    霍小玉傳

    + +

    唐傳奇霍小玉傳,收錄在太平廣記卷第四百八十七雜傳記四,作者蔣防,是很有名的故事。霍小玉傳講負心薄倖的文人李益,結識霍小玉,始亂終棄,奉母命娶盧氏,避而不見。霍小玉悲憤而死,死前詛咒李益妻妾不安。後李益家中時常出現不明人影,李益疑妻出牆,猜忌虐妻,數娶數離,終為不安。

    + +

    霍小玉傳是有名的負心漢遭報應的故事。後人講到負心薄倖,皆不免想到霍小玉的故事。既憐霍小玉年輕薄命,又恨李益負心薄情。

    + +

    我查了查李益,真有其人,是唐時名詩人。除了詩名外,李益另一件有名的就是對妻妾善妒疑忌,當時人因此將男子善妒妻者,稱為李益疾

    + +

    這樣看來,或許霍小玉傳是當時妒忌李益功名的蔣防的詆燬之作。這又和唐代牛李黨爭有關。唐時牛李黨爭,蔣防被李黨的元稹、李紳薦為翰林學士,後被貶為汀州刺史,數年間連貶數處,輾轉流離。牛黨的李益則是進士科舉出身。可能是揭發李益早年醜事,又或是附會李益妒妻之名,杜撰早年始亂終棄八掛故事醜化李益。牛黨的蔣防藉霍小玉傳攻詰李黨的李益,霍小玉傳可視為牛李黨爭下的其中一環。

    + +

    從這個角度看,讓我對霍小玉傳的意義,除了講負心薄倖的故事外,又多了一層認識。

    + +

    雖然,即便不知這些真實的時事背景,單讀小說霍小玉傳,也非常精彩。霍小玉傳原為附會李益善妒,八掛其早年不堪的醜事。流傳久了,李益時人時事已不復為人所知,而霍小玉的深情怨屈,引人嗟嘆。明人湯顯祖依霍小玉傳改寫成戲曲紫蕭記,後又改寫成戲曲紫釵記霍小玉傳中霍小玉典當的紫玉釵,成為兩人相識、定情之物,後李益被盧太守逼婚,霍小玉吞釵不嫁,最後兩人終成眷屬。順應觀眾盼望,薄情的李益成了為強豪逼迫的李益,最後還得了喜劇結尾。但和李益時人時事,已相去甚遠。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 99 | + 100 | + 101 | + 102 | + 103 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0102.html.en.html b/htdocs/imacat/me/diary/0102.html.en.html new file mode 120000 index 0000000..086e867 --- /dev/null +++ b/htdocs/imacat/me/diary/0102.html.en.html @@ -0,0 +1 @@ +0102.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0102.html.en.xhtml b/htdocs/imacat/me/diary/0102.html.en.xhtml new file mode 100644 index 0000000..992808c --- /dev/null +++ b/htdocs/imacat/me/diary/0102.html.en.xhtml @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 102 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 102

    + +
    + +
    + +
    +
    2.1.’07. 12:17pm.
    + +

    許瑋倫與明星的部落格

    + +

    這兩天上網,看幾個明星的部落格,不管跟許瑋倫熟不熟,講的都是許瑋倫車禍死亡的事。

    + +

    說幾個明星的部落格,其實也只是潘慧如葉全真而已。

    + +

    也難怪。演藝人員平常也不一定有空寫部落格。這幾天演藝圈比較大的事就是許瑋倫的車禍,不管熟不熟,多少都會想到。

    + +

    令人遺憾的事。

    + +
    + +
    + +
    +
    1.15.’07. 5:40am.
    + +

    考完最後一節課

    + +

    考完最後一節課,空大的所有課程,亦到此為止。

    + +

    之前每個學期都修五堂課,這個學期所剩學分不多,只修三堂。修得比較少,就有比較多的時間,可以唸書,也唸得比較仔細。考試,也輕鬆得多。

    + +

    接下來,要準備研究所了。

    + +
    + +
    + +
    +
    1.15.’07. 5:11am.
    + +

    網路時代的快捷與便利

    + +

    很多人很喜歡說,現在網路時代多麼便利,一封信咻一聲就到了,事情做得又快又好。對此,我很不以為然。

    + +

    網路時代,效率變高了,可是工作量並沒有因此變輕鬆,反而是加重了。記得以前高中時代,最迷筆友的時候,星期六寫信,隔了一個週末,人家星期一收到,星期二回信,我星期四收到,星期五回信,人家星期一收到。一個星期一封信。碰到期考忙,週末收到信,拖到隔週末回信,兩個星期一封信,信上百般道歉,人家也可以接受。這還是我寫信最多的時候。

    + +

    現在有了電腦,一切都不一樣了。我現在每天要回五、六封信,人家信寄出去,兩個小時之內沒收到回信,就會打電話來催問,像催命一樣。以前的時代,根本沒有辦法想像一天要回五、六封信。真是好可怕,不可思議。

    + +

    前一陣子看到一個 HiNet 的電視廣告:一個老闆得意地說,以前的時代,員工每天加班加到晚上八、九點,事情都做不完,現在有了 HiNet 8M 寬頻網路,四、五點就下班了。

    + +

    才怪,見鬼。有了寬頻網路,還是一樣每天加班加到晚上八、九點,只是現在一天,要趕以前四、五天工作的份量而已。工作量不但沒有變輕了,反而變重了好幾倍。現代人的網路生活,苦不堪言。

    + +

    噫,不如歸去。

    + +
    + +
    + +
    +
    1.15.’07. 4:51am.
    + +

    空大 中國社會史 課本勘誤

    + +

    臨畢業前,中國社會史,我也花了比之前幾個學期用心去讀。課本提到的事件,我也跟著去深入閱讀。詳讀對照之下,發現有下列問題:

    + +
      +
    1. 第六章 第一節 P.215

      + +

      …春秋時,宋國國主閔公與大夫南宮萬在六博時發生爭吵,連瘡疤也揭了起來,做臣子的不甘受辱,拿起博盤便砸過去,失手打死了國主,引起一場大亂…

      + +

      宋閔公應不是南宮萬失手打死的,而是有計劃設計殺死的。按史記卷三十八:

      + +

      十一年秋,湣公與南宮萬獵,因博爭行,湣公怒,辱之,曰:始吾敬若;今若,魯虜也。萬有力,病此言,遂以局殺湣公於蒙澤。

      + +

      看起來好像是拿殺死的,但再按左傳莊公十一年:

      + +

      乘丘之役,公之金僕姑射南宮長萬,公右遄孫生搏之。宋人請之,宋公靳之,曰:始吾敬子,今子,魯囚也。吾弗敬子矣。病之。

      + +

      左傳莊公十二年:

      + +

      十二年秋,宋萬弒閔公於蒙澤。遇仇牧於門,批而殺之。遇大宰督於東宮之西,又殺之。立子游。群公子奔蕭。公子御說奔亳。南宮牛、猛獲帥師圍亳。

      + +

      宋閔公羞辱南宮長萬於莊公十一年秋,南宮長萬弒宋閔公於莊公十二年秋,兩件事差了一年,分明是處心報復,怎麼能說是不甘受辱,失手打死呢?

      +
    2. + +
    3. 第二章 第二節 P.218

      + +

      …前述的劉毅沒有什麼家資,但每賭必是一擲百萬,後來與桓溫交兵,連桓溫也被他這種不要命的賭法弄得憂慮無復為記

      + +

      和劉毅三人交戰,發出此語的應該是桓玄,不是桓玄的父親桓溫。按宋書本記第一武帝上:

      + +

      玄自聞軍起,憂懼無復為計。或曰:劉諱等眾力甚弱,豈辦之有成,陛下何慮之甚!玄曰:劉諱足為一世之雄,劉毅家無擔石之儲,摴蒲一擲百萬;何無忌,劉牢之甥,酷似其舅。共舉大事,何謂無成。

      +
    4. + +
    5. 第二章 第二節 P.218

      + +

      …粱朝的朱異十來歲便好賭,而且是群賭,頗為鄉里所患

      + +

      所引文應為頗為鄉黨所患鄉里應為鄉黨。按梁書列傳第三十二朱異:

      + +

      …異年數歲,外祖顧歡撫之,謂異祖昭之曰:此兒非常器,當成卿門戶。年十餘,好群眾蒱博,頗為鄉黨所患。

      + +

      南史卷六十二列傳第五十二,文同上。

      +
    6. + +
    7. 第六章第二節 P.220

      + +

      …又如賈昌,主管雞坊,帶著雞籠三百隨玄宗封泰山…

      + +

      經遍閱新、舊唐史,並無賈昌此人。賈昌其人其事,出自唐陳鴻祖著傳奇小說東城老父傳,是小說虛構的人物,並非真有其人。這一堂課是中國社會史,談的是而不是小說。當然東城老父傳反映了玄宗時社會氣氛,但作為歷史課程,在虛構與史實之間,是不是應該要有更清楚的分際呢?把小說虛構人物當成史實來討論,是不是失當?

      +
    8. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 100 | + 101 | + 102 | + 103 | + 104 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0102.html.zh-cn.html b/htdocs/imacat/me/diary/0102.html.zh-cn.html new file mode 120000 index 0000000..4868166 --- /dev/null +++ b/htdocs/imacat/me/diary/0102.html.zh-cn.html @@ -0,0 +1 @@ +0102.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0102.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0102.html.zh-cn.xhtml new file mode 100644 index 0000000..bb24b4f --- /dev/null +++ b/htdocs/imacat/me/diary/0102.html.zh-cn.xhtml @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百零二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百零二

    + +
    + +
    + +
    +
    2.1.’07. 12:17pm.
    + +

    许玮伦与明星的部落格

    + +

    这两天上网,看几个明星的部落格,不管跟许玮伦熟不熟,讲的都是许玮伦车祸死亡的事。

    + +

    说几个明星的部落格,其实也只是潘慧如叶全真而已。

    + +

    也难怪。演艺人员平常也不一定有空写部落格。这几天演艺圈比较大的事就是许玮伦的车祸,不管熟不熟,多少都会想到。

    + +

    令人遗憾的事。

    + +
    + +
    + +
    +
    1.15.’07. 5:40am.
    + +

    考完最后一节课

    + +

    考完最后一节课,空大的所有课程,亦到此为止。

    + +

    之前每个学期都修五堂课,这个学期所剩学分不多,只修三堂。修得比较少,就有比较多的时间,可以念书,也念得比较仔细。考试,也轻松得多。

    + +

    接下来,要准备研究所了。

    + +
    + +
    + +
    +
    1.15.’07. 5:11am.
    + +

    网路时代的快捷与便利

    + +

    很多人很喜欢说,现在网路时代多么便利,一封信咻一声就到了,事情做得又快又好。对此,我很不以为然。

    + +

    网路时代,效率变高了,可是工作量并没有因此变轻松,反而是加重了。记得以前高中时代,最迷笔友的时候,星期六写信,隔了一个周末,人家星期一收到,星期二回信,我星期四收到,星期五回信,人家星期一收到。一个星期一封信。碰到期考忙,周末收到信,拖到隔周末回信,两个星期一封信,信上百般道歉,人家也可以接受。这还是我写信最多的时候。

    + +

    现在有了电脑,一切都不一样了。我现在每天要回五、六封信,人家信寄出去,两个小时之内没收到回信,就会打电话来催问,像催命一样。以前的时代,根本没有办法想像一天要回五、六封信。真是好可怕,不可思议。

    + +

    前一阵子看到一个 HiNet 的电视广告:一个老板得意地说,以前的时代,员工每天加班加到晚上八、九点,事情都做不完,现在有了 HiNet 8M 宽频网路,四、五点就下班了。

    + +

    才怪,见鬼。有了宽频网路,还是一样每天加班加到晚上八、九点,只是现在一天,要赶以前四、五天工作的份量而已。工作量不但没有变轻了,反而变重了好几倍。现代人的网路生活,苦不堪言。

    + +

    噫,不如归去。

    + +
    + +
    + +
    +
    1.15.’07. 4:51am.
    + +

    空大 中国社会史 课本勘误

    + +

    临毕业前,中国社会史,我也花了比之前几个学期用心去读。课本提到的事件,我也跟著去深入阅读。详读对照之下,发现有下列问题:

    + +
      +
    1. 第六章 第一节 P.215

      + +

      …春秋时,宋国国主闵公与大夫南宫万在六博时发生争吵,连疮疤也揭了起来,做臣子的不甘受辱,拿起博盘便砸过去,失手打死了国主,引起一场大乱…

      + +

      宋闵公应不是南宫万失手打死的,而是有计划设计杀死的。按史记卷三十八:

      + +

      十一年秋,闵公与南宫万猎,因博争行,闵公怒,辱之,曰:始吾敬若;今若,鲁虏也。万有力,病此言,遂以局杀闵公於蒙泽。

      + +

      看起来好像是拿杀死的,但再按左传庄公十一年:

      + +

      乘丘之役,公之金仆姑射南宫长万,公右遄孙生搏之。宋人请之,宋公靳之,曰:始吾敬子,今子,鲁囚也。吾弗敬子矣。病之。

      + +

      左传庄公十二年:

      + +

      十二年秋,宋万弑闵公於蒙泽。遇仇牧於门,批而杀之。遇大宰督於东宫之西,又杀之。立子游。群公子奔萧。公子御说奔亳。南宫牛、猛获帅师围亳。

      + +

      宋闵公羞辱南宫长万於庄公十一年秋,南宫长万弑宋闵公於庄公十二年秋,两件事差了一年,分明是处心报复,怎么能说是不甘受辱,失手打死呢?

      +
    2. + +
    3. 第二章 第二节 P.218

      + +

      …前述的刘毅没有什么家资,但每赌必是一掷百万,后来与桓温交兵,连桓温也被他这种不要命的赌法弄得忧虑无复为记

      + +

      和刘毅三人交战,发出此语的应该是桓玄,不是桓玄的父亲桓温。按宋书本记第一武帝上:

      + +

      玄自闻军起,忧惧无复为计。或曰:刘讳等众力甚弱,岂办之有成,陛下何虑之甚!玄曰:刘讳足为一世之雄,刘毅家无担石之储,摴蒲一掷百万;何无忌,刘牢之甥,酷似其舅。共举大事,何谓无成。

      +
    4. + +
    5. 第二章 第二节 P.218

      + +

      …粱朝的朱异十来岁便好赌,而且是群赌,颇为乡里所患

      + +

      所引文应为颇为乡党所患乡里应为乡党。按梁书列传第三十二朱异:

      + +

      …异年数岁,外祖顾欢抚之,谓异祖昭之曰:此儿非常器,当成卿门户。年十余,好群众蒱博,颇为乡党所患。

      + +

      南史卷六十二列传第五十二,文同上。

      +
    6. + +
    7. 第六章第二节 P.220

      + +

      …又如贾昌,主管鸡坊,带著鸡笼三百随玄宗封泰山…

      + +

      经遍阅新、旧唐史,并无贾昌此人。贾昌其人其事,出自唐陈鸿祖著传奇小说东城老父传,是小说虚构的人物,并非真有其人。这一堂课是中国社会史,谈的是而不是小说。当然东城老父传反映了玄宗时社会气氛,但作为历史课程,在虚构与史实之间,是不是应该要有更清楚的分际呢?把小说虚构人物当成史实来讨论,是不是失当?

      +
    8. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 100 | + 101 | + 102 | + 103 | + 104 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0102.html.zh-tw.html b/htdocs/imacat/me/diary/0102.html.zh-tw.html new file mode 120000 index 0000000..1904f06 --- /dev/null +++ b/htdocs/imacat/me/diary/0102.html.zh-tw.html @@ -0,0 +1 @@ +0102.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0102.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0102.html.zh-tw.xhtml new file mode 100644 index 0000000..cdb3b56 --- /dev/null +++ b/htdocs/imacat/me/diary/0102.html.zh-tw.xhtml @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百零二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百零二

    + +
    + +
    + +
    +
    2.1.’07. 12:17pm.
    + +

    許瑋倫與明星的部落格

    + +

    這兩天上網,看幾個明星的部落格,不管跟許瑋倫熟不熟,講的都是許瑋倫車禍死亡的事。

    + +

    說幾個明星的部落格,其實也只是潘慧如葉全真而已。

    + +

    也難怪。演藝人員平常也不一定有空寫部落格。這幾天演藝圈比較大的事就是許瑋倫的車禍,不管熟不熟,多少都會想到。

    + +

    令人遺憾的事。

    + +
    + +
    + +
    +
    1.15.’07. 5:40am.
    + +

    考完最後一節課

    + +

    考完最後一節課,空大的所有課程,亦到此為止。

    + +

    之前每個學期都修五堂課,這個學期所剩學分不多,只修三堂。修得比較少,就有比較多的時間,可以唸書,也唸得比較仔細。考試,也輕鬆得多。

    + +

    接下來,要準備研究所了。

    + +
    + +
    + +
    +
    1.15.’07. 5:11am.
    + +

    網路時代的快捷與便利

    + +

    很多人很喜歡說,現在網路時代多麼便利,一封信咻一聲就到了,事情做得又快又好。對此,我很不以為然。

    + +

    網路時代,效率變高了,可是工作量並沒有因此變輕鬆,反而是加重了。記得以前高中時代,最迷筆友的時候,星期六寫信,隔了一個週末,人家星期一收到,星期二回信,我星期四收到,星期五回信,人家星期一收到。一個星期一封信。碰到期考忙,週末收到信,拖到隔週末回信,兩個星期一封信,信上百般道歉,人家也可以接受。這還是我寫信最多的時候。

    + +

    現在有了電腦,一切都不一樣了。我現在每天要回五、六封信,人家信寄出去,兩個小時之內沒收到回信,就會打電話來催問,像催命一樣。以前的時代,根本沒有辦法想像一天要回五、六封信。真是好可怕,不可思議。

    + +

    前一陣子看到一個 HiNet 的電視廣告:一個老闆得意地說,以前的時代,員工每天加班加到晚上八、九點,事情都做不完,現在有了 HiNet 8M 寬頻網路,四、五點就下班了。

    + +

    才怪,見鬼。有了寬頻網路,還是一樣每天加班加到晚上八、九點,只是現在一天,要趕以前四、五天工作的份量而已。工作量不但沒有變輕了,反而變重了好幾倍。現代人的網路生活,苦不堪言。

    + +

    噫,不如歸去。

    + +
    + +
    + +
    +
    1.15.’07. 4:51am.
    + +

    空大 中國社會史 課本勘誤

    + +

    臨畢業前,中國社會史,我也花了比之前幾個學期用心去讀。課本提到的事件,我也跟著去深入閱讀。詳讀對照之下,發現有下列問題:

    + +
      +
    1. 第六章 第一節 P.215

      + +

      …春秋時,宋國國主閔公與大夫南宮萬在六博時發生爭吵,連瘡疤也揭了起來,做臣子的不甘受辱,拿起博盤便砸過去,失手打死了國主,引起一場大亂…

      + +

      宋閔公應不是南宮萬失手打死的,而是有計劃設計殺死的。按史記卷三十八:

      + +

      十一年秋,湣公與南宮萬獵,因博爭行,湣公怒,辱之,曰:始吾敬若;今若,魯虜也。萬有力,病此言,遂以局殺湣公於蒙澤。

      + +

      看起來好像是拿殺死的,但再按左傳莊公十一年:

      + +

      乘丘之役,公之金僕姑射南宮長萬,公右遄孫生搏之。宋人請之,宋公靳之,曰:始吾敬子,今子,魯囚也。吾弗敬子矣。病之。

      + +

      左傳莊公十二年:

      + +

      十二年秋,宋萬弒閔公於蒙澤。遇仇牧於門,批而殺之。遇大宰督於東宮之西,又殺之。立子游。群公子奔蕭。公子御說奔亳。南宮牛、猛獲帥師圍亳。

      + +

      宋閔公羞辱南宮長萬於莊公十一年秋,南宮長萬弒宋閔公於莊公十二年秋,兩件事差了一年,分明是處心報復,怎麼能說是不甘受辱,失手打死呢?

      +
    2. + +
    3. 第二章 第二節 P.218

      + +

      …前述的劉毅沒有什麼家資,但每賭必是一擲百萬,後來與桓溫交兵,連桓溫也被他這種不要命的賭法弄得憂慮無復為記

      + +

      和劉毅三人交戰,發出此語的應該是桓玄,不是桓玄的父親桓溫。按宋書本記第一武帝上:

      + +

      玄自聞軍起,憂懼無復為計。或曰:劉諱等眾力甚弱,豈辦之有成,陛下何慮之甚!玄曰:劉諱足為一世之雄,劉毅家無擔石之儲,摴蒲一擲百萬;何無忌,劉牢之甥,酷似其舅。共舉大事,何謂無成。

      +
    4. + +
    5. 第二章 第二節 P.218

      + +

      …粱朝的朱異十來歲便好賭,而且是群賭,頗為鄉里所患

      + +

      所引文應為頗為鄉黨所患鄉里應為鄉黨。按梁書列傳第三十二朱異:

      + +

      …異年數歲,外祖顧歡撫之,謂異祖昭之曰:此兒非常器,當成卿門戶。年十餘,好群眾蒱博,頗為鄉黨所患。

      + +

      南史卷六十二列傳第五十二,文同上。

      +
    6. + +
    7. 第六章第二節 P.220

      + +

      …又如賈昌,主管雞坊,帶著雞籠三百隨玄宗封泰山…

      + +

      經遍閱新、舊唐史,並無賈昌此人。賈昌其人其事,出自唐陳鴻祖著傳奇小說東城老父傳,是小說虛構的人物,並非真有其人。這一堂課是中國社會史,談的是而不是小說。當然東城老父傳反映了玄宗時社會氣氛,但作為歷史課程,在虛構與史實之間,是不是應該要有更清楚的分際呢?把小說虛構人物當成史實來討論,是不是失當?

      +
    8. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 100 | + 101 | + 102 | + 103 | + 104 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0103.html.en.html b/htdocs/imacat/me/diary/0103.html.en.html new file mode 120000 index 0000000..0fdeca5 --- /dev/null +++ b/htdocs/imacat/me/diary/0103.html.en.html @@ -0,0 +1 @@ +0103.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0103.html.en.xhtml b/htdocs/imacat/me/diary/0103.html.en.xhtml new file mode 100644 index 0000000..917bda4 --- /dev/null +++ b/htdocs/imacat/me/diary/0103.html.en.xhtml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 103 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 103

    + +
    + +
    + +
    +
    2.3.’07. 4:41pm.
    + +

    象棋、梭哈與博奕

    + +

    昨晚去開通了 GPRS

    + +

    其實沒什麼重大的理由。 Nokia 6070 不是多好的手機,上網也不方便。我只是想下載幾個手機遊戲,平常排隊等候時可以打發時間。我發現很多手機遊戲都要開通 GPRS 才能下載,無法電腦下載後直接用傳輸線傳輸。其實一般手機遊戲一個不到一百元,我又不是遊戲狂,下載一兩個,我還負擔得起。只是苦無方法下載。

    + +

    之前在中國的捉魚網站,抓了一個梭哈,和一個中國象棋。梭哈是脫衣梭哈,和三個女生對玩:學生妹、 OL 上班族、護士,每次贏光對手,對手會脫一件換籌碼,脫到沒得脫為止,就算破關了。要是對手贏夠了,也會拿籌碼把衣服換回來。有點下流,不過反正手機螢幕很差,也看不到什麼。我很久前也有玩過類似的電腦脫衣梭哈。其實還蠻好玩的。我比較喜歡設計簡單一點。有些脫衣梭哈,脫衣服還要色色地放慢動作,解析度又很高,跑起來很慢。我只是要玩樸克牌,脫衣服就像是小關卡一樣,很有挑戰性,好像跟真人玩一樣,贏了很高興,讓對方把衣服穿回去就會有點生氣。至於色色的設計,就可以免了。簡單的脫衣梭哈,很好玩,不容易沉迷,隨時可以收起來,還會自動存檔,很適合放在手機上。

    + +

    我覺得我玩梭哈,有一部份是在修身養性。我是處女座的,行事真的很保守,怕輸怕犯錯,買基金也要有五年績效才敢買。在俄羅斯我去看過飯店的輪盤,不過看個兩分鐘就覺得無聊離開了,在香港逛賭馬站,本來想難得出國到此,買個馬券也算是個經驗,可是看了半天不知道買什麼,就走掉了。至於馬吊根本不碰。我好像一點賭性都沒有。太過在意輸贏進退,以至裹足不前,不見得是好事。人生本來就有輸有贏,輸贏都要用平常心來看,該看準時機冒險的時候,還是要博上一博。手機梭哈遊戲,雖不是真賭,但還是有輸有贏,對於磨練我的平常心,還是有點幫助。

    + +

    至於中國象棋,是中國的移動互聯做的,玩起來還不錯,不過遊戲開始畫面太長,排隊等候時,好不容易開局,就排到我了。而且象棋本來就要玩比較久,又沒有辦法存檔。我很多年沒玩象棋了,沒接觸過中國人的棋風,電腦走子常常出乎我的意料,感覺很新鮮有趣。棋力不太高,我可以有輸有贏。不過我還是看不慣那個簡體字的,而且遊戲開始畫面太長,還是想找找有沒有其它臺灣的手機象棋程式可以玩。

    + +

    不過臺灣的手機遊戲網站,都要開通 GPRS 才能下載。我其實不大用得到 GPRS ,而且手機沒有多好,也沒辦法怎麼樣上網。昨晚不得已,還是去開通了 GPRS

    + +

    開通以後上網找,才發現手機象棋遊戲,出奇地少。找了好幾家,從 i.Game 手機遊戲館Yahoo! 奇摩大哥大SoMuch 手機娛樂館等等,博奕類遊戲,幾乎找不到一款象棋。不過,相對的,麻將遊戲則是滿滿滿,每一個手機遊戲站,都有幾十款各式各樣的麻將。除了麻將外,就是樸克牌。圍棋也一定會有,不過就是沒有象棋。

    + +

    唔,真的都沒有人玩象棋了嗎?那麼多人打馬吊,都沒有人下象棋嗎?難道這世界上,真的沒有一款正體中文的手機象棋遊戲了嗎?嗚嗚~

    + +

    我上 eMule 找,找到了一款 1990 年 Interplay 出的 Battle Chess 2 Chinese Chess 決戰中國象棋。放到 Virtual PC DOS 下玩,意外發現就是我十幾二十年前玩的立體象棋!真的好高興,呵呵~

    + +

    不過我的棋力,好像只能玩 Level 1 第一級吧~ :p 好慘。以後要是比較有空,希望能夠好好學學象棋。

    + +

    我習慣用中砲開局,一開局就強攻猛打。不過開局只顧用砲、馬窮追猛打,常常到了中局,對手的車都佔好方位了,我的車都還沒有出來。我以前讀過幾局殘局,對殘局的巧變也有點心得。不過中局的陣地攻防,要考慮的盤面比較廣比較大,我就很不拿手了。這就有點月座牡羊的個性了,只懂得橫衝直撞,對於大局思量,我就很頭痛了。

    + +

    有人說學象棋,要從殘局學起。但我其實不擅長的是中局。開局也只普普通通。中砲開局是很粗淺的玩法,只會中砲開局,還是不知道如何取得接下來的優勢。

    + +

    空大中國社會史有讀到,以前象棋是中下階層平民普遍流行的賭具,圍棋在上層階級流行,風雅化以後,賭性比較低。當然昔日的賭具,到今日自不可同日而語。不過平常西門町、公園裏擺象棋盤的人,大概也都是以此為生的職業賭徒。沒什麼賭性的我,卻喜歡過往賭博性強的象棋,也是蠻矛盾的。

    + +

    上次在公園,看到老人下棋。我知道裏面大概有在賭輸贏。不過如果輸贏不大的話,我也在想是不是繳點學費,去跟他們學學棋呢?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 101 | + 102 | + 103 | + 104 | + 105 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0103.html.zh-cn.html b/htdocs/imacat/me/diary/0103.html.zh-cn.html new file mode 120000 index 0000000..f173c42 --- /dev/null +++ b/htdocs/imacat/me/diary/0103.html.zh-cn.html @@ -0,0 +1 @@ +0103.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0103.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0103.html.zh-cn.xhtml new file mode 100644 index 0000000..7344bb2 --- /dev/null +++ b/htdocs/imacat/me/diary/0103.html.zh-cn.xhtml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百零三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百零三

    + +
    + +
    + +
    +
    2.3.’07. 4:41pm.
    + +

    象棋、梭哈与博奕

    + +

    昨晚去开通了 GPRS

    + +

    其实没什么重大的理由。 Nokia 6070 不是多好的手机,上网也不方便。我只是想下载几个手机游戏,平常排队等候时可以打发时间。我发现很多手机游戏都要开通 GPRS 才能下载,无法电脑下载后直接用传输线传输。其实一般手机游戏一个不到一百元,我又不是游戏狂,下载一两个,我还负担得起。只是苦无方法下载。

    + +

    之前在中国的捉鱼网站,抓了一个梭哈,和一个中国象棋。梭哈是脱衣梭哈,和三个女生对玩:学生妹、 OL 上班族、护士,每次赢光对手,对手会脱一件换筹码,脱到没得脱为止,就算破关了。要是对手赢够了,也会拿筹码把衣服换回来。有点下流,不过反正手机萤幕很差,也看不到什么。我很久前也有玩过类似的电脑脱衣梭哈。其实还蛮好玩的。我比较喜欢设计简单一点。有些脱衣梭哈,脱衣服还要色色地放慢动作,解析度又很高,跑起来很慢。我只是要玩朴克牌,脱衣服就像是小关卡一样,很有挑战性,好像跟真人玩一样,赢了很高兴,让对方把衣服穿回去就会有点生气。至於色色的设计,就可以免了。简单的脱衣梭哈,很好玩,不容易沉迷,随时可以收起来,还会自动存档,很适合放在手机上。

    + +

    我觉得我玩梭哈,有一部份是在修身养性。我是处女座的,行事真的很保守,怕输怕犯错,买基金也要有五年绩效才敢买。在俄罗斯我去看过饭店的轮盘,不过看个两分钟就觉得无聊离开了,在香港逛赌马站,本来想难得出国到此,买个马券也算是个经验,可是看了半天不知道买什么,就走掉了。至於马吊根本不碰。我好像一点赌性都没有。太过在意输赢进退,以至裹足不前,不见得是好事。人生本来就有输有赢,输赢都要用平常心来看,该看准时机冒险的时候,还是要博上一博。手机梭哈游戏,虽不是真赌,但还是有输有赢,对於磨练我的平常心,还是有点帮助。

    + +

    至於中国象棋,是中国的移动互联做的,玩起来还不错,不过游戏开始画面太长,排队等候时,好不容易开局,就排到我了。而且象棋本来就要玩比较久,又没有办法存档。我很多年没玩象棋了,没接触过中国人的棋风,电脑走子常常出乎我的意料,感觉很新鲜有趣。棋力不太高,我可以有输有赢。不过我还是看不惯那个简体字的,而且游戏开始画面太长,还是想找找有没有其它台湾的手机象棋程式可以玩。

    + +

    不过台湾的手机游戏网站,都要开通 GPRS 才能下载。我其实不大用得到 GPRS ,而且手机没有多好,也没办法怎么样上网。昨晚不得已,还是去开通了 GPRS

    + +

    开通以后上网找,才发现手机象棋游戏,出奇地少。找了好几家,从 i.Game 手机游戏馆Yahoo! 奇摩大哥大SoMuch 手机娱乐馆等等,博奕类游戏,几乎找不到一款象棋。不过,相对的,麻将游戏则是满满满,每一个手机游戏站,都有几十款各式各样的麻将。除了麻将外,就是朴克牌。围棋也一定会有,不过就是没有象棋。

    + +

    唔,真的都没有人玩象棋了吗?那么多人打马吊,都没有人下象棋吗?难道这世界上,真的没有一款正体中文的手机象棋游戏了吗?呜呜~

    + +

    我上 eMule 找,找到了一款 1990 年 Interplay 出的 Battle Chess 2 Chinese Chess 决战中国象棋。放到 Virtual PC DOS 下玩,意外发现就是我十几二十年前玩的立体象棋!真的好高兴,呵呵~

    + +

    不过我的棋力,好像只能玩 Level 1 第一级吧~ :p 好惨。以后要是比较有空,希望能够好好学学象棋。

    + +

    我习惯用中炮开局,一开局就强攻猛打。不过开局只顾用炮、马穷追猛打,常常到了中局,对手的车都占好方位了,我的车都还没有出来。我以前读过几局残局,对残局的巧变也有点心得。不过中局的阵地攻防,要考虑的盘面比较广比较大,我就很不拿手了。这就有点月座牡羊的个性了,只懂得横冲直撞,对於大局思量,我就很头痛了。

    + +

    有人说学象棋,要从残局学起。但我其实不擅长的是中局。开局也只普普通通。中炮开局是很粗浅的玩法,只会中炮开局,还是不知道如何取得接下来的优势。

    + +

    空大中国社会史有读到,以前象棋是中下阶层平民普遍流行的赌具,围棋在上层阶级流行,风雅化以后,赌性比较低。当然昔日的赌具,到今日自不可同日而语。不过平常西门町、公园里摆象棋盘的人,大概也都是以此为生的职业赌徒。没什么赌性的我,却喜欢过往赌博性强的象棋,也是蛮矛盾的。

    + +

    上次在公园,看到老人下棋。我知道里面大概有在赌输赢。不过如果输赢不大的话,我也在想是不是缴点学费,去跟他们学学棋呢?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 101 | + 102 | + 103 | + 104 | + 105 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0103.html.zh-tw.html b/htdocs/imacat/me/diary/0103.html.zh-tw.html new file mode 120000 index 0000000..9d31059 --- /dev/null +++ b/htdocs/imacat/me/diary/0103.html.zh-tw.html @@ -0,0 +1 @@ +0103.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0103.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0103.html.zh-tw.xhtml new file mode 100644 index 0000000..6d460be --- /dev/null +++ b/htdocs/imacat/me/diary/0103.html.zh-tw.xhtml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百零三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百零三

    + +
    + +
    + +
    +
    2.3.’07. 4:41pm.
    + +

    象棋、梭哈與博奕

    + +

    昨晚去開通了 GPRS

    + +

    其實沒什麼重大的理由。 Nokia 6070 不是多好的手機,上網也不方便。我只是想下載幾個手機遊戲,平常排隊等候時可以打發時間。我發現很多手機遊戲都要開通 GPRS 才能下載,無法電腦下載後直接用傳輸線傳輸。其實一般手機遊戲一個不到一百元,我又不是遊戲狂,下載一兩個,我還負擔得起。只是苦無方法下載。

    + +

    之前在中國的捉魚網站,抓了一個梭哈,和一個中國象棋。梭哈是脫衣梭哈,和三個女生對玩:學生妹、 OL 上班族、護士,每次贏光對手,對手會脫一件換籌碼,脫到沒得脫為止,就算破關了。要是對手贏夠了,也會拿籌碼把衣服換回來。有點下流,不過反正手機螢幕很差,也看不到什麼。我很久前也有玩過類似的電腦脫衣梭哈。其實還蠻好玩的。我比較喜歡設計簡單一點。有些脫衣梭哈,脫衣服還要色色地放慢動作,解析度又很高,跑起來很慢。我只是要玩樸克牌,脫衣服就像是小關卡一樣,很有挑戰性,好像跟真人玩一樣,贏了很高興,讓對方把衣服穿回去就會有點生氣。至於色色的設計,就可以免了。簡單的脫衣梭哈,很好玩,不容易沉迷,隨時可以收起來,還會自動存檔,很適合放在手機上。

    + +

    我覺得我玩梭哈,有一部份是在修身養性。我是處女座的,行事真的很保守,怕輸怕犯錯,買基金也要有五年績效才敢買。在俄羅斯我去看過飯店的輪盤,不過看個兩分鐘就覺得無聊離開了,在香港逛賭馬站,本來想難得出國到此,買個馬券也算是個經驗,可是看了半天不知道買什麼,就走掉了。至於馬吊根本不碰。我好像一點賭性都沒有。太過在意輸贏進退,以至裹足不前,不見得是好事。人生本來就有輸有贏,輸贏都要用平常心來看,該看準時機冒險的時候,還是要博上一博。手機梭哈遊戲,雖不是真賭,但還是有輸有贏,對於磨練我的平常心,還是有點幫助。

    + +

    至於中國象棋,是中國的移動互聯做的,玩起來還不錯,不過遊戲開始畫面太長,排隊等候時,好不容易開局,就排到我了。而且象棋本來就要玩比較久,又沒有辦法存檔。我很多年沒玩象棋了,沒接觸過中國人的棋風,電腦走子常常出乎我的意料,感覺很新鮮有趣。棋力不太高,我可以有輸有贏。不過我還是看不慣那個簡體字的,而且遊戲開始畫面太長,還是想找找有沒有其它臺灣的手機象棋程式可以玩。

    + +

    不過臺灣的手機遊戲網站,都要開通 GPRS 才能下載。我其實不大用得到 GPRS ,而且手機沒有多好,也沒辦法怎麼樣上網。昨晚不得已,還是去開通了 GPRS

    + +

    開通以後上網找,才發現手機象棋遊戲,出奇地少。找了好幾家,從 i.Game 手機遊戲館Yahoo! 奇摩大哥大SoMuch 手機娛樂館等等,博奕類遊戲,幾乎找不到一款象棋。不過,相對的,麻將遊戲則是滿滿滿,每一個手機遊戲站,都有幾十款各式各樣的麻將。除了麻將外,就是樸克牌。圍棋也一定會有,不過就是沒有象棋。

    + +

    唔,真的都沒有人玩象棋了嗎?那麼多人打馬吊,都沒有人下象棋嗎?難道這世界上,真的沒有一款正體中文的手機象棋遊戲了嗎?嗚嗚~

    + +

    我上 eMule 找,找到了一款 1990 年 Interplay 出的 Battle Chess 2 Chinese Chess 決戰中國象棋。放到 Virtual PC DOS 下玩,意外發現就是我十幾二十年前玩的立體象棋!真的好高興,呵呵~

    + +

    不過我的棋力,好像只能玩 Level 1 第一級吧~ :p 好慘。以後要是比較有空,希望能夠好好學學象棋。

    + +

    我習慣用中砲開局,一開局就強攻猛打。不過開局只顧用砲、馬窮追猛打,常常到了中局,對手的車都佔好方位了,我的車都還沒有出來。我以前讀過幾局殘局,對殘局的巧變也有點心得。不過中局的陣地攻防,要考慮的盤面比較廣比較大,我就很不拿手了。這就有點月座牡羊的個性了,只懂得橫衝直撞,對於大局思量,我就很頭痛了。

    + +

    有人說學象棋,要從殘局學起。但我其實不擅長的是中局。開局也只普普通通。中砲開局是很粗淺的玩法,只會中砲開局,還是不知道如何取得接下來的優勢。

    + +

    空大中國社會史有讀到,以前象棋是中下階層平民普遍流行的賭具,圍棋在上層階級流行,風雅化以後,賭性比較低。當然昔日的賭具,到今日自不可同日而語。不過平常西門町、公園裏擺象棋盤的人,大概也都是以此為生的職業賭徒。沒什麼賭性的我,卻喜歡過往賭博性強的象棋,也是蠻矛盾的。

    + +

    上次在公園,看到老人下棋。我知道裏面大概有在賭輸贏。不過如果輸贏不大的話,我也在想是不是繳點學費,去跟他們學學棋呢?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 101 | + 102 | + 103 | + 104 | + 105 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0104.html.en.html b/htdocs/imacat/me/diary/0104.html.en.html new file mode 120000 index 0000000..e7030d7 --- /dev/null +++ b/htdocs/imacat/me/diary/0104.html.en.html @@ -0,0 +1 @@ +0104.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0104.html.en.xhtml b/htdocs/imacat/me/diary/0104.html.en.xhtml new file mode 100644 index 0000000..7d73444 --- /dev/null +++ b/htdocs/imacat/me/diary/0104.html.en.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 104 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 104

    + +
    + +
    + +
    +
    2.3.’07. 6:07pm.
    + +

    潘慧如

    + +
    +潘慧如
    +

    潘慧如

    +
    + +

    其實我本來不知道潘慧如。

    + +

    小招看電視的時候,多少會影響到我。她有幾次看到徐乃麟主持的至尊百家樂。徐乃麟身邊的另一個女主持人,我不認得,可是不知道為什麼,就是很喜歡她的型,覺得很漂亮。雖然我不懂麻將,可是看著她在叫牌,就覺得好可愛。

    + +

    前幾天興之所至,查了一查至尊百家樂的另一個主持人,才知道是潘慧如。潘慧如也是星之國際的人,和臺灣阿誠一哥陳昭榮、葉全真、張鳳書都是同一家公司的,星之國際的老闆是陳昭榮,潘慧如也是陳昭榮旗下的藝人,經紀人則是星之國際有名的經紀人 Amy ,就是之前拍臺灣霹靂火時和演劉文聰的秦楊大吵一架的 Amy 。

    + +

    不過讓我有點失望的,是潘慧如的路線,好像是走性感噴火寫真的路線。雖說藝人的路線形象,很大一部份要接受製作公司安排,也不是自己所能決定的。可是性感噴火寫真女星?我還是不大能夠接受,有點失望。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 102 | + 103 | + 104 | + 105 | + 106 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0104.html.zh-cn.html b/htdocs/imacat/me/diary/0104.html.zh-cn.html new file mode 120000 index 0000000..c647558 --- /dev/null +++ b/htdocs/imacat/me/diary/0104.html.zh-cn.html @@ -0,0 +1 @@ +0104.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0104.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0104.html.zh-cn.xhtml new file mode 100644 index 0000000..f0e7fca --- /dev/null +++ b/htdocs/imacat/me/diary/0104.html.zh-cn.xhtml @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百零四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百零四

    + +
    + +
    + +
    +
    2.3.’07. 6:07pm.
    + +

    潘慧如

    + +
    +潘慧如
    +

    潘慧如

    +
    + +

    其实我本来不知道潘慧如。

    + +

    小招看电视的时候,多少会影响到我。她有几次看到徐乃麟主持的至尊百家乐。徐乃麟身边的另一个女主持人,我不认得,可是不知道为什么,就是很喜欢她的型,觉得很漂亮。虽然我不懂麻将,可是看著她在叫牌,就觉得好可爱。

    + +

    前几天兴之所至,查了一查至尊百家乐的另一个主持人,才知道是潘慧如。潘慧如也是星之国际的人,和台湾阿诚一哥陈昭荣、叶全真、张凤书都是同一家公司的,星之国际的老板是陈昭荣,潘慧如也是陈昭荣旗下的艺人,经纪人则是星之国际有名的经纪人 Amy ,就是之前拍台湾霹雳火时和演刘文聪的秦杨大吵一架的 Amy 。

    + +

    不过让我有点失望的,是潘慧如的路线,好像是走性感喷火写真的路线。虽说艺人的路线形象,很大一部份要接受制作公司安排,也不是自己所能决定的。可是性感喷火写真女星?我还是不大能够接受,有点失望。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 102 | + 103 | + 104 | + 105 | + 106 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0104.html.zh-tw.html b/htdocs/imacat/me/diary/0104.html.zh-tw.html new file mode 120000 index 0000000..2f1f4f3 --- /dev/null +++ b/htdocs/imacat/me/diary/0104.html.zh-tw.html @@ -0,0 +1 @@ +0104.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0104.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0104.html.zh-tw.xhtml new file mode 100644 index 0000000..56dc81a --- /dev/null +++ b/htdocs/imacat/me/diary/0104.html.zh-tw.xhtml @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百零四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百零四

    + +
    + +
    + +
    +
    2.3.’07. 6:07pm.
    + +

    潘慧如

    + +
    +潘慧如
    +

    潘慧如

    +
    + +

    其實我本來不知道潘慧如。

    + +

    小招看電視的時候,多少會影響到我。她有幾次看到徐乃麟主持的至尊百家樂。徐乃麟身邊的另一個女主持人,我不認得,可是不知道為什麼,就是很喜歡她的型,覺得很漂亮。雖然我不懂麻將,可是看著她在叫牌,就覺得好可愛。

    + +

    前幾天興之所至,查了一查至尊百家樂的另一個主持人,才知道是潘慧如。潘慧如也是星之國際的人,和臺灣阿誠一哥陳昭榮、葉全真、張鳳書都是同一家公司的,星之國際的老闆是陳昭榮,潘慧如也是陳昭榮旗下的藝人,經紀人則是星之國際有名的經紀人 Amy ,就是之前拍臺灣霹靂火時和演劉文聰的秦楊大吵一架的 Amy 。

    + +

    不過讓我有點失望的,是潘慧如的路線,好像是走性感噴火寫真的路線。雖說藝人的路線形象,很大一部份要接受製作公司安排,也不是自己所能決定的。可是性感噴火寫真女星?我還是不大能夠接受,有點失望。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 102 | + 103 | + 104 | + 105 | + 106 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0105.html.en.html b/htdocs/imacat/me/diary/0105.html.en.html new file mode 120000 index 0000000..a21a106 --- /dev/null +++ b/htdocs/imacat/me/diary/0105.html.en.html @@ -0,0 +1 @@ +0105.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0105.html.en.xhtml b/htdocs/imacat/me/diary/0105.html.en.xhtml new file mode 100644 index 0000000..91cec09 --- /dev/null +++ b/htdocs/imacat/me/diary/0105.html.en.xhtml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 105 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 105

    + +
    + +
    + +
    +
    2.4.’07. 2:44am.
    + +

    NANA 2—備受考驗的兩人的感情

    + +
    +NANA 2
    +

    NANA 2

    +
    + +
      +
    • 片名: NANA 2
    • +
    • 發行年份: 2006
    • +
    • 製作公司:東宝映画
    • +
    • 導演:大谷健太郎
    • +
    • 原作:矢沢あいNANA(Cookie)
    • +
    • 演員: +
        +
      • 大崎ナナ中島美嘉
      • +
      • 小松奈々市川由衣
      • +
      • 寺島伸夫成宮寛貴
      • +
      • 岡崎真一本郷奏多
      • +
      • 高木泰士丸山智己
      • +
      • 芹澤レイラ伊藤由奈
      • +
      • 本城蓮姜暢雄
      • +
      • 一ノ瀬巧玉山鉄二
      • +
      • 藤枝直樹水谷百輔
      • +
      +
    • +
    + +

    NANA 2 延續第一集的劇情。第一集最後,小松奈々雖然成功撮合大崎ナナ本城蓮,但自己的人生諸事不順,工作被罵到臭頭,男朋友又跟人跑了,一切都跌到谷底時,回到家等待她的,是她的偶像,偶像團體 TRAPNEST 的團長一ノ瀬巧。這份ナナ給她準備的大謝禮,讓她感動到痛哭。

    + +

    沒想到花心又愛跟歌迷亂搞的一ノ瀬巧,一時興起,搞上了奈々。原本跟歌迷亂搞也不在乎的一ノ瀬巧,卻因為這次的對象是 BLACK STONES 團花,ナナ的親密好友、伸夫暗戀的奈々,而掀起了軒然大波。ナナ一氣之下,搬離了 707 室,住進了的公寓,兩個 NANA 之間的距離,一日比一日遙遠。蠻不在意的沒多久就失去音訊。傷心的奈々,在伸夫忍不住告白,及 BLACK STONES ナナ真一眾人的撮合之下,投向了溫柔的伸夫懷裏。就在 BLACK STONES 眾人以為團花奈々終於歸隊,兩位 NANA 言歸於好時,奈々突然發現自己懷孕了。被甩了的回來質問奈々,正巧碰上奈々因懷孕遭受重大打擊,不但代奈々打電話給伸夫,並表明願意和奈々結婚,要奈々搬過去,不在意小孩父親是誰。相對於因為猜疑而發狂的伸夫,受傷無助的奈々,還是跟著果斷冷靜的走了,離開了 707 號房,住進了的豪華公寓。ナナ奈々的關係,也降到了冰點。 BLAST STONES 的出道,也在如火如荼地進行中。這時ナナ和當紅偶像樂團吉他手的關係,突然被八卦媒體挖出來。 BLACK STONES 被迫以緋聞提早曝光,媒體交相指責 BLACK STONES 為了出道炒作新聞,陷入最糟糕的困境,對ナナ和 BLACK STONES 有愧意的奈々,只能躲在的公寓中暗自著急。 BLACK STONES 能夠順利出道嗎?ナナ奈々兩個人互相依賴又遍體鱗傷的關係,到底要到什麼時候,才能言歸於好呢?

    + +

    打從NANA 2的角色定案,決定由市川由衣取代不續演的宮崎あおい,飾演小松奈々,我在看過角色定妝照後,就不預期市川由衣,能夠像前集的宮崎あおい一樣。雖然市川由衣很努力,可是她的氣質還是和宮崎あおい相差了一段距離。因為少了這個期待,所以我能夠以比較平常的心情,看待市川由衣的演出,而不會拿她跟宮崎あおい演的奈々相比較。

    + +

    其實市川由衣演得很不錯。一開始,可能是為了讓觀眾能夠承接前集的氣氛,市川由衣刻意承接宮崎あおい詮釋的奈々,反而讓人覺得很不自然,連帶連中島美嘉飾演的ナナ也很不自然。可是到了中段以後,市川由衣演出越來越自然,讓人覺得很棒,演出了宮崎あおい所無法詮釋的另一個奈々。前集中宮崎あおい詮釋的奈々,其實太過陽光、單純,並沒有演繹出原著漫畫中奈々的複雜心思。原著漫畫中的奈々其實心思很複雜,從高中起就號稱一見鐘情女王,見一個愛一個,還搞上不倫戀,常常沉迷於自己的幻想中,雖然遍體鱗傷,還是很努力追求幸福。宮崎あおい詮釋的奈々,只有奈々可愛的表面,完全看不出她複雜的心思。而市川由衣,則將奈々複雜痛苦的一面,詮釋得非常成功。如果不管NANA 2一開始的演出失敗,市川由衣詮釋的奈々,其實比宮崎あおい成功。

    + +

    受限於電影的片長,原著漫畫很多情節還是無法演出,例如岡崎真一芹澤レイラ的不倫戀,小松奈々岡崎真一的乾媽乾兒子關係, BLACK STONES 後來住進去的演藝公司的宿舍,寺島伸夫的新女朋友 A 片女星香坂百合伸夫ナナ國中時的孽緣等等。如果可以演出的話會更好,不過電影時間有限,也是沒有辦法的事。

    + +

    NANA 2號稱是精彩感動完結篇,但其實原著漫畫還在連載,還沒有結束(雖然矢沢あい自稱快結束了)。沒有結尾的結尾,感覺上很奇怪。如果真的是完結篇的話,後來的劇情沒得演了,有點可惜。

    + +

    我很久沒進戲院看電影了。晚上十點左右出門,去趕百老匯十點四十開始的場次,原本怕太晚去買不到票,沒想到電影院裏冷冷清清,不大的放映廳,只有我和一對情侶,和電影放到一半,後來進來的兩個人而已。一月二十六日上映的電影,到今晚不過一週,就剩下這樣。唉。

    + +

    原本買兩張票送一個 NANA 2 L 型資料夾,我跟百老匯賣票的小姐拜託,她很爽快地給我了。嗯,漂亮又好心的小姐,好心會有好報的~ *^_^*

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 103 | + 104 | + 105 | + 106 | + 107 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0105.html.zh-cn.html b/htdocs/imacat/me/diary/0105.html.zh-cn.html new file mode 120000 index 0000000..7507fe5 --- /dev/null +++ b/htdocs/imacat/me/diary/0105.html.zh-cn.html @@ -0,0 +1 @@ +0105.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0105.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0105.html.zh-cn.xhtml new file mode 100644 index 0000000..c710f37 --- /dev/null +++ b/htdocs/imacat/me/diary/0105.html.zh-cn.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百零五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百零五

    + +
    + +
    + +
    +
    2.4.’07. 2:44am.
    + +

    NANA 2—备受考验的两人的感情

    + +
    +NANA 2
    +

    NANA 2

    +
    + +
      +
    • 片名: NANA 2
    • +
    • 发行年份: 2006
    • +
    • 制作公司:东宝映画
    • +
    • 导演:大谷健太郎
    • +
    • 原作:矢沢あいNANA(Cookie)
    • +
    • 演员: +
        +
      • 大崎ナナ中岛美嘉
      • +
      • 小松奈々市川由衣
      • +
      • 寺岛伸夫成宫寛贵
      • +
      • 冈崎真一本郷奏多
      • +
      • 高木泰士丸山智己
      • +
      • 芹泽レイラ伊藤由奈
      • +
      • 本城莲姜畅雄
      • +
      • 一ノ瀬巧玉山鉄二
      • +
      • 藤枝直树水谷百辅
      • +
      +
    • +
    + +

    NANA 2 延续第一集的剧情。第一集最后,小松奈々虽然成功撮合大崎ナナ本城莲,但自己的人生诸事不顺,工作被骂到臭头,男朋友又跟人跑了,一切都跌到谷底时,回到家等待她的,是她的偶像,偶像团体 TRAPNEST 的团长一ノ瀬巧。这份ナナ给她准备的大谢礼,让她感动到痛哭。

    + +

    没想到花心又爱跟歌迷乱搞的一ノ瀬巧,一时兴起,搞上了奈々。原本跟歌迷乱搞也不在乎的一ノ瀬巧,却因为这次的对象是 BLACK STONES 团花,ナナ的亲密好友、伸夫暗恋的奈々,而掀起了轩然大波。ナナ一气之下,搬离了 707 室,住进了的公寓,两个 NANA 之间的距离,一日比一日遥远。蛮不在意的没多久就失去音讯。伤心的奈々,在伸夫忍不住告白,及 BLACK STONES ナナ真一众人的撮合之下,投向了温柔的伸夫怀里。就在 BLACK STONES 众人以为团花奈々终於归队,两位 NANA 言归於好时,奈々突然发现自己怀孕了。被甩了的回来质问奈々,正巧碰上奈々因怀孕遭受重大打击,不但代奈々打电话给伸夫,并表明愿意和奈々结婚,要奈々搬过去,不在意小孩父亲是谁。相对於因为猜疑而发狂的伸夫,受伤无助的奈々,还是跟著果断冷静的走了,离开了 707 号房,住进了的豪华公寓。ナナ奈々的关系,也降到了冰点。 BLAST STONES 的出道,也在如火如荼地进行中。这时ナナ和当红偶像乐团吉他手的关系,突然被八卦媒体挖出来。 BLACK STONES 被迫以绯闻提早曝光,媒体交相指责 BLACK STONES 为了出道炒作新闻,陷入最糟糕的困境,对ナナ和 BLACK STONES 有愧意的奈々,只能躲在的公寓中暗自著急。 BLACK STONES 能够顺利出道吗?ナナ奈々两个人互相依赖又遍体鳞伤的关系,到底要到什么时候,才能言归於好呢?

    + +

    打从NANA 2的角色定案,决定由市川由衣取代不续演的宫崎あおい,饰演小松奈々,我在看过角色定妆照后,就不预期市川由衣,能够像前集的宫崎あおい一样。虽然市川由衣很努力,可是她的气质还是和宫崎あおい相差了一段距离。因为少了这个期待,所以我能够以比较平常的心情,看待市川由衣的演出,而不会拿她跟宫崎あおい演的奈々相比较。

    + +

    其实市川由衣演得很不错。一开始,可能是为了让观众能够承接前集的气氛,市川由衣刻意承接宫崎あおい诠释的奈々,反而让人觉得很不自然,连带连中岛美嘉饰演的ナナ也很不自然。可是到了中段以后,市川由衣演出越来越自然,让人觉得很棒,演出了宫崎あおい所无法诠释的另一个奈々。前集中宫崎あおい诠释的奈々,其实太过阳光、单纯,并没有演绎出原著漫画中奈々的复杂心思。原著漫画中的奈々其实心思很复杂,从高中起就号称一见钟情女王,见一个爱一个,还搞上不伦恋,常常沉迷於自己的幻想中,虽然遍体鳞伤,还是很努力追求幸福。宫崎あおい诠释的奈々,只有奈々可爱的表面,完全看不出她复杂的心思。而市川由衣,则将奈々复杂痛苦的一面,诠释得非常成功。如果不管NANA 2一开始的演出失败,市川由衣诠释的奈々,其实比宫崎あおい成功。

    + +

    受限於电影的片长,原著漫画很多情节还是无法演出,例如冈崎真一芹泽レイラ的不伦恋,小松奈々冈崎真一的干妈干儿子关系, BLACK STONES 后来住进去的演艺公司的宿舍,寺岛伸夫的新女朋友 A 片女星香坂百合伸夫ナナ国中时的孽缘等等。如果可以演出的话会更好,不过电影时间有限,也是没有办法的事。

    + +

    NANA 2号称是精彩感动完结篇,但其实原著漫画还在连载,还没有结束(虽然矢沢あい自称快结束了)。没有结尾的结尾,感觉上很奇怪。如果真的是完结篇的话,后来的剧情没得演了,有点可惜。

    + +

    我很久没进戏院看电影了。晚上十点左右出门,去赶百老汇十点四十开始的场次,原本怕太晚去买不到票,没想到电影院里冷冷清清,不大的放映厅,只有我和一对情侣,和电影放到一半,后来进来的两个人而已。一月二十六日上映的电影,到今晚不过一周,就剩下这样。唉。

    + +

    原本买两张票送一个 NANA 2 L 型资料夹,我跟百老汇卖票的小姐拜托,她很爽快地给我了。嗯,漂亮又好心的小姐,好心会有好报的~ *^_^*

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 103 | + 104 | + 105 | + 106 | + 107 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0105.html.zh-tw.html b/htdocs/imacat/me/diary/0105.html.zh-tw.html new file mode 120000 index 0000000..ea5861a --- /dev/null +++ b/htdocs/imacat/me/diary/0105.html.zh-tw.html @@ -0,0 +1 @@ +0105.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0105.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0105.html.zh-tw.xhtml new file mode 100644 index 0000000..5b227ed --- /dev/null +++ b/htdocs/imacat/me/diary/0105.html.zh-tw.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百零五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百零五

    + +
    + +
    + +
    +
    2.4.’07. 2:44am.
    + +

    NANA 2—備受考驗的兩人的感情

    + +
    +NANA 2
    +

    NANA 2

    +
    + +
      +
    • 片名: NANA 2
    • +
    • 發行年份: 2006
    • +
    • 製作公司:東宝映画
    • +
    • 導演:大谷健太郎
    • +
    • 原作:矢沢あいNANA(Cookie)
    • +
    • 演員: +
        +
      • 大崎ナナ中島美嘉
      • +
      • 小松奈々市川由衣
      • +
      • 寺島伸夫成宮寛貴
      • +
      • 岡崎真一本郷奏多
      • +
      • 高木泰士丸山智己
      • +
      • 芹澤レイラ伊藤由奈
      • +
      • 本城蓮姜暢雄
      • +
      • 一ノ瀬巧玉山鉄二
      • +
      • 藤枝直樹水谷百輔
      • +
      +
    • +
    + +

    NANA 2 延續第一集的劇情。第一集最後,小松奈々雖然成功撮合大崎ナナ本城蓮,但自己的人生諸事不順,工作被罵到臭頭,男朋友又跟人跑了,一切都跌到谷底時,回到家等待她的,是她的偶像,偶像團體 TRAPNEST 的團長一ノ瀬巧。這份ナナ給她準備的大謝禮,讓她感動到痛哭。

    + +

    沒想到花心又愛跟歌迷亂搞的一ノ瀬巧,一時興起,搞上了奈々。原本跟歌迷亂搞也不在乎的一ノ瀬巧,卻因為這次的對象是 BLACK STONES 團花,ナナ的親密好友、伸夫暗戀的奈々,而掀起了軒然大波。ナナ一氣之下,搬離了 707 室,住進了的公寓,兩個 NANA 之間的距離,一日比一日遙遠。蠻不在意的沒多久就失去音訊。傷心的奈々,在伸夫忍不住告白,及 BLACK STONES ナナ真一眾人的撮合之下,投向了溫柔的伸夫懷裏。就在 BLACK STONES 眾人以為團花奈々終於歸隊,兩位 NANA 言歸於好時,奈々突然發現自己懷孕了。被甩了的回來質問奈々,正巧碰上奈々因懷孕遭受重大打擊,不但代奈々打電話給伸夫,並表明願意和奈々結婚,要奈々搬過去,不在意小孩父親是誰。相對於因為猜疑而發狂的伸夫,受傷無助的奈々,還是跟著果斷冷靜的走了,離開了 707 號房,住進了的豪華公寓。ナナ奈々的關係,也降到了冰點。 BLAST STONES 的出道,也在如火如荼地進行中。這時ナナ和當紅偶像樂團吉他手的關係,突然被八卦媒體挖出來。 BLACK STONES 被迫以緋聞提早曝光,媒體交相指責 BLACK STONES 為了出道炒作新聞,陷入最糟糕的困境,對ナナ和 BLACK STONES 有愧意的奈々,只能躲在的公寓中暗自著急。 BLACK STONES 能夠順利出道嗎?ナナ奈々兩個人互相依賴又遍體鱗傷的關係,到底要到什麼時候,才能言歸於好呢?

    + +

    打從NANA 2的角色定案,決定由市川由衣取代不續演的宮崎あおい,飾演小松奈々,我在看過角色定妝照後,就不預期市川由衣,能夠像前集的宮崎あおい一樣。雖然市川由衣很努力,可是她的氣質還是和宮崎あおい相差了一段距離。因為少了這個期待,所以我能夠以比較平常的心情,看待市川由衣的演出,而不會拿她跟宮崎あおい演的奈々相比較。

    + +

    其實市川由衣演得很不錯。一開始,可能是為了讓觀眾能夠承接前集的氣氛,市川由衣刻意承接宮崎あおい詮釋的奈々,反而讓人覺得很不自然,連帶連中島美嘉飾演的ナナ也很不自然。可是到了中段以後,市川由衣演出越來越自然,讓人覺得很棒,演出了宮崎あおい所無法詮釋的另一個奈々。前集中宮崎あおい詮釋的奈々,其實太過陽光、單純,並沒有演繹出原著漫畫中奈々的複雜心思。原著漫畫中的奈々其實心思很複雜,從高中起就號稱一見鐘情女王,見一個愛一個,還搞上不倫戀,常常沉迷於自己的幻想中,雖然遍體鱗傷,還是很努力追求幸福。宮崎あおい詮釋的奈々,只有奈々可愛的表面,完全看不出她複雜的心思。而市川由衣,則將奈々複雜痛苦的一面,詮釋得非常成功。如果不管NANA 2一開始的演出失敗,市川由衣詮釋的奈々,其實比宮崎あおい成功。

    + +

    受限於電影的片長,原著漫畫很多情節還是無法演出,例如岡崎真一芹澤レイラ的不倫戀,小松奈々岡崎真一的乾媽乾兒子關係, BLACK STONES 後來住進去的演藝公司的宿舍,寺島伸夫的新女朋友 A 片女星香坂百合伸夫ナナ國中時的孽緣等等。如果可以演出的話會更好,不過電影時間有限,也是沒有辦法的事。

    + +

    NANA 2號稱是精彩感動完結篇,但其實原著漫畫還在連載,還沒有結束(雖然矢沢あい自稱快結束了)。沒有結尾的結尾,感覺上很奇怪。如果真的是完結篇的話,後來的劇情沒得演了,有點可惜。

    + +

    我很久沒進戲院看電影了。晚上十點左右出門,去趕百老匯十點四十開始的場次,原本怕太晚去買不到票,沒想到電影院裏冷冷清清,不大的放映廳,只有我和一對情侶,和電影放到一半,後來進來的兩個人而已。一月二十六日上映的電影,到今晚不過一週,就剩下這樣。唉。

    + +

    原本買兩張票送一個 NANA 2 L 型資料夾,我跟百老匯賣票的小姐拜託,她很爽快地給我了。嗯,漂亮又好心的小姐,好心會有好報的~ *^_^*

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 103 | + 104 | + 105 | + 106 | + 107 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0106.html.en.html b/htdocs/imacat/me/diary/0106.html.en.html new file mode 120000 index 0000000..3349a1f --- /dev/null +++ b/htdocs/imacat/me/diary/0106.html.en.html @@ -0,0 +1 @@ +0106.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0106.html.en.xhtml b/htdocs/imacat/me/diary/0106.html.en.xhtml new file mode 100644 index 0000000..35c218c --- /dev/null +++ b/htdocs/imacat/me/diary/0106.html.en.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 106 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 106

    + +
    + +
    + +
    +
    2.4.’07. 5:58am.
    + +

    促織

    + +

    上個學期空大修了古典短篇小說選讀,讀了很多短篇小說,其中感觸最深的,是蒲松齡聊齋誌異裏的促織(蟋蟀),在聊齋誌異第四卷,講的是明宣宗年間的故事:

    + +
    +

    宣德間,宮中尚促織之戲,歲征民間。此物故非西產﹔有華陰令欲媚上官,以一頭進,試使鬥而才,因責常供。令以責之里正。市中游俠兒,得佳者籠養之,昂其直,居為奇貨。里胥猾黠,假此科斂丁口,每責一頭,輒傾數家之產。…

    + +

    + +

    異史氏曰:天子偶用一物,未必不過此已忘﹔而奉行者即為定例。加以官貪吏虐,民日貼婦賣兒,更無休止。故天子一跬步,皆關民命,不可忽也。…

    +
    + +

    明宣宗愛鬥促織(蟋蟀),陜西華陰縣令為巴結皇帝,上貢了一隻善鬥的促織,皇帝很高興,令他年年上貢。縣令則交給里正負責。但陜西不產促織,地痞流氓捉到一頭不錯的,就拿來高價勒索里正,里正也不得不從。若碰到壞的里正,則再藉此苛斂。為了上貢一頭促織,往往就要弄到好幾戶人家傾家盪產。

    + +

    中間的故事敘述一個老實的里正,找不到促織上貢,又傾家蕩產無力外購,被縣令刑求斷腿,還是不得不撐著去抓促織,好不容易抓到一頭,卻又被兒子不小心弄死,兒子害怕病倒,化作促織,解一家之危,更帶來全家榮華富貴。結論時,蒲松齡下注腳:當權者一時喜好,過一陣子就忘了,官吏執行時,卻會形成常規,碰上貪官藉此苛斂,老百姓賣妻鬻子傾家盪產,苦難無休無盡。因此,當權者一言一行,都悠關人民性命,不可不慎啊!

    + +

    這則故事,讓我感觸很深。蒲松齡的文筆,很重社會寫實。聊齋誌異主題雖是神怪誌異,但下筆盡是社會世情。難怪不為當權所容。同在聊齋誌異的第四卷,有一篇公孫九娘,寫的是清初于七亂後,株連甚廣,棲霞、萊陽兩縣盡成死城的悲慘故事。光讀前兩句,其慘狀就足以讓人窒息。

    + +
    +

    于七一案,連坐被誅者,棲霞、萊陽兩縣最多。一日俘數百人,盡戮於演武場中。碧血滿地,白骨撐天。上官慈悲,捐給棺木,濟城工肆,材木一空。…

    +
    + +

    促織的故事,讓我反覆思量,在腦中盤桓不去,吟詠不止,難以忘懷。平常人一時的喜好,突然愛吃甜甜圈、愛吃葡式蛋塔,過一陣子就退燒了,也無傷大雅。但如果是當權者,就不一樣了。即便只是個人私下一時的喜好,周圍的人為討好,竭盡所能,甚而藉此苛徵暴斂,弊端不止。

    + +

    我想到去年吳淑珍的事。對吳淑珍而言,可能真的沒有什麼違法,她只是高興有朋友來看她,高興有人送孫子滿月禮,跟店家殺價而已。平常人喜歡珠寶,跟店家殺價,再普通也不過的事,但因為她是總統夫人,事情就不一樣了。商人藉進出官邸展現實力,逼對手從股權之爭中退出,藉送禮拉關係,連從不打折的 Tiffany 都為她打折。

    + +

    平常人平凡的一言一行,微不足道的小事,當權者做來,卻可能造成嚴重的後果。真是不可不慎啊~

    + +
    + +
    + +
    +
    2.4.’07. 3:13am.
    + +

    潘慧如的部落格

    + +

    剛剛讀了一下潘慧如的部落格,發現她還蠻不喜歡她在至尊百家樂裏穿得那樣單薄的。唔,可是我是因為她在至尊百家樂裏很漂亮,才注意到她的。

    + +

    嗯,好吧,我好像也不應該那樣看她。希望能夠看到她一些比較平實的樣子。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 104 | + 105 | + 106 | + 107 | + 108 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0106.html.zh-cn.html b/htdocs/imacat/me/diary/0106.html.zh-cn.html new file mode 120000 index 0000000..7ee9a09 --- /dev/null +++ b/htdocs/imacat/me/diary/0106.html.zh-cn.html @@ -0,0 +1 @@ +0106.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0106.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0106.html.zh-cn.xhtml new file mode 100644 index 0000000..aaf1f31 --- /dev/null +++ b/htdocs/imacat/me/diary/0106.html.zh-cn.xhtml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百零六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百零六

    + +
    + +
    + +
    +
    2.4.’07. 5:58am.
    + +

    促织

    + +

    上个学期空大修了古典短篇小说选读,读了很多短篇小说,其中感触最深的,是蒲松龄聊斋志异里的促织(蟋蟀),在聊斋志异第四卷,讲的是明宣宗年间的故事:

    + +
    +

    宣德间,宫中尚促织之戏,岁征民间。此物故非西产;有华阴令欲媚上官,以一头进,试使斗而才,因责常供。令以责之里正。市中游侠儿,得佳者笼养之,昂其直,居为奇货。里胥猾黠,假此科敛丁口,每责一头,辄倾数家之产。…

    + +

    + +

    异史氏曰:天子偶用一物,未必不过此已忘;而奉行者即为定例。加以官贪吏虐,民日贴妇卖儿,更无休止。故天子一跬步,皆关民命,不可忽也。…

    +
    + +

    明宣宗爱斗促织(蟋蟀),陜西华阴县令为巴结皇帝,上贡了一只善斗的促织,皇帝很高兴,令他年年上贡。县令则交给里正负责。但陜西不产促织,地痞流氓捉到一头不错的,就拿来高价勒索里正,里正也不得不从。若碰到坏的里正,则再藉此苛敛。为了上贡一头促织,往往就要弄到好几户人家倾家荡产。

    + +

    中间的故事叙述一个老实的里正,找不到促织上贡,又倾家荡产无力外购,被县令刑求断腿,还是不得不撑著去抓促织,好不容易抓到一头,却又被儿子不小心弄死,儿子害怕病倒,化作促织,解一家之危,更带来全家荣华富贵。结论时,蒲松龄下注脚:当权者一时喜好,过一阵子就忘了,官吏执行时,却会形成常规,碰上贪官藉此苛敛,老百姓卖妻鬻子倾家荡产,苦难无休无尽。因此,当权者一言一行,都悠关人民性命,不可不慎啊!

    + +

    这则故事,让我感触很深。蒲松龄的文笔,很重社会写实。聊斋志异主题虽是神怪志异,但下笔尽是社会世情。难怪不为当权所容。同在聊斋志异的第四卷,有一篇公孙九娘,写的是清初于七乱后,株连甚广,栖霞、莱阳两县尽成死城的悲惨故事。光读前两句,其惨状就足以让人窒息。

    + +
    +

    于七一案,连坐被诛者,栖霞、莱阳两县最多。一日俘数百人,尽戮於演武场中。碧血满地,白骨撑天。上官慈悲,捐给棺木,济城工肆,材木一空。…

    +
    + +

    促织的故事,让我反覆思量,在脑中盘桓不去,吟咏不止,难以忘怀。平常人一时的喜好,突然爱吃甜甜圈、爱吃葡式蛋塔,过一阵子就退烧了,也无伤大雅。但如果是当权者,就不一样了。即便只是个人私下一时的喜好,周围的人为讨好,竭尽所能,甚而藉此苛徵暴敛,弊端不止。

    + +

    我想到去年吴淑珍的事。对吴淑珍而言,可能真的没有什么违法,她只是高兴有朋友来看她,高兴有人送孙子满月礼,跟店家杀价而已。平常人喜欢珠宝,跟店家杀价,再普通也不过的事,但因为她是总统夫人,事情就不一样了。商人藉进出官邸展现实力,逼对手从股权之争中退出,藉送礼拉关系,连从不打折的 Tiffany 都为她打折。

    + +

    平常人平凡的一言一行,微不足道的小事,当权者做来,却可能造成严重的后果。真是不可不慎啊~

    + +
    + +
    + +
    +
    2.4.’07. 3:13am.
    + +

    潘慧如的部落格

    + +

    刚刚读了一下潘慧如的部落格,发现她还蛮不喜欢她在至尊百家乐里穿得那样单薄的。唔,可是我是因为她在至尊百家乐里很漂亮,才注意到她的。

    + +

    嗯,好吧,我好像也不应该那样看她。希望能够看到她一些比较平实的样子。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 104 | + 105 | + 106 | + 107 | + 108 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0106.html.zh-tw.html b/htdocs/imacat/me/diary/0106.html.zh-tw.html new file mode 120000 index 0000000..314be89 --- /dev/null +++ b/htdocs/imacat/me/diary/0106.html.zh-tw.html @@ -0,0 +1 @@ +0106.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0106.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0106.html.zh-tw.xhtml new file mode 100644 index 0000000..0d6e6ac --- /dev/null +++ b/htdocs/imacat/me/diary/0106.html.zh-tw.xhtml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百零六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百零六

    + +
    + +
    + +
    +
    2.4.’07. 5:58am.
    + +

    促織

    + +

    上個學期空大修了古典短篇小說選讀,讀了很多短篇小說,其中感觸最深的,是蒲松齡聊齋誌異裏的促織(蟋蟀),在聊齋誌異第四卷,講的是明宣宗年間的故事:

    + +
    +

    宣德間,宮中尚促織之戲,歲征民間。此物故非西產﹔有華陰令欲媚上官,以一頭進,試使鬥而才,因責常供。令以責之里正。市中游俠兒,得佳者籠養之,昂其直,居為奇貨。里胥猾黠,假此科斂丁口,每責一頭,輒傾數家之產。…

    + +

    + +

    異史氏曰:天子偶用一物,未必不過此已忘﹔而奉行者即為定例。加以官貪吏虐,民日貼婦賣兒,更無休止。故天子一跬步,皆關民命,不可忽也。…

    +
    + +

    明宣宗愛鬥促織(蟋蟀),陜西華陰縣令為巴結皇帝,上貢了一隻善鬥的促織,皇帝很高興,令他年年上貢。縣令則交給里正負責。但陜西不產促織,地痞流氓捉到一頭不錯的,就拿來高價勒索里正,里正也不得不從。若碰到壞的里正,則再藉此苛斂。為了上貢一頭促織,往往就要弄到好幾戶人家傾家盪產。

    + +

    中間的故事敘述一個老實的里正,找不到促織上貢,又傾家蕩產無力外購,被縣令刑求斷腿,還是不得不撐著去抓促織,好不容易抓到一頭,卻又被兒子不小心弄死,兒子害怕病倒,化作促織,解一家之危,更帶來全家榮華富貴。結論時,蒲松齡下注腳:當權者一時喜好,過一陣子就忘了,官吏執行時,卻會形成常規,碰上貪官藉此苛斂,老百姓賣妻鬻子傾家盪產,苦難無休無盡。因此,當權者一言一行,都悠關人民性命,不可不慎啊!

    + +

    這則故事,讓我感觸很深。蒲松齡的文筆,很重社會寫實。聊齋誌異主題雖是神怪誌異,但下筆盡是社會世情。難怪不為當權所容。同在聊齋誌異的第四卷,有一篇公孫九娘,寫的是清初于七亂後,株連甚廣,棲霞、萊陽兩縣盡成死城的悲慘故事。光讀前兩句,其慘狀就足以讓人窒息。

    + +
    +

    于七一案,連坐被誅者,棲霞、萊陽兩縣最多。一日俘數百人,盡戮於演武場中。碧血滿地,白骨撐天。上官慈悲,捐給棺木,濟城工肆,材木一空。…

    +
    + +

    促織的故事,讓我反覆思量,在腦中盤桓不去,吟詠不止,難以忘懷。平常人一時的喜好,突然愛吃甜甜圈、愛吃葡式蛋塔,過一陣子就退燒了,也無傷大雅。但如果是當權者,就不一樣了。即便只是個人私下一時的喜好,周圍的人為討好,竭盡所能,甚而藉此苛徵暴斂,弊端不止。

    + +

    我想到去年吳淑珍的事。對吳淑珍而言,可能真的沒有什麼違法,她只是高興有朋友來看她,高興有人送孫子滿月禮,跟店家殺價而已。平常人喜歡珠寶,跟店家殺價,再普通也不過的事,但因為她是總統夫人,事情就不一樣了。商人藉進出官邸展現實力,逼對手從股權之爭中退出,藉送禮拉關係,連從不打折的 Tiffany 都為她打折。

    + +

    平常人平凡的一言一行,微不足道的小事,當權者做來,卻可能造成嚴重的後果。真是不可不慎啊~

    + +
    + +
    + +
    +
    2.4.’07. 3:13am.
    + +

    潘慧如的部落格

    + +

    剛剛讀了一下潘慧如的部落格,發現她還蠻不喜歡她在至尊百家樂裏穿得那樣單薄的。唔,可是我是因為她在至尊百家樂裏很漂亮,才注意到她的。

    + +

    嗯,好吧,我好像也不應該那樣看她。希望能夠看到她一些比較平實的樣子。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 104 | + 105 | + 106 | + 107 | + 108 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0107.html.en.html b/htdocs/imacat/me/diary/0107.html.en.html new file mode 120000 index 0000000..b42195e --- /dev/null +++ b/htdocs/imacat/me/diary/0107.html.en.html @@ -0,0 +1 @@ +0107.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0107.html.en.xhtml b/htdocs/imacat/me/diary/0107.html.en.xhtml new file mode 100644 index 0000000..d527242 --- /dev/null +++ b/htdocs/imacat/me/diary/0107.html.en.xhtml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 107 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 107

    + +
    + +
    + +
    +
    2.5.’07. 10:22pm.
    + +

    研究所考試課本

    + +

    一月十九日報名清大資工所中央資工所,一月二十三日報名臺大資工所後,又一頭鑽進公司的案子裏,忙了兩個星期。明明三月的考試就迫在眉睫了,連課本都還沒有空去買,心裏著急得半死。這兩天天氣轉熱,昨天晚上忙一段落後,開始上網找研究所考試的課本。各校資工所,考的不外是離散數學、線性代數、資料結構、演算法、計算機組織、作業系統這六科。幸好網路上有人寫了考資工所的心得,上面列了不少重要的資料,省去我找各科課本的時間:

    + +
    +
      +
    • 離散數學 +
        +
      • C. L. Liu (劉炯朗), Elements of Discrete Mathematics, 2/e, McGraw Hill
      • +
      • Ralph P. Grimaldi, Discrete Mathematics and Combinatorial Mathematics, 4/e, Addision Wesley
      • +
      • Kenneth H. Rosen, Discrete Mathematics and Its Applications, 5/e, McGraw Hill
      • +
      +
    • +
    • 線性代數 +
        +
      • Steven J. Leon, Linear Algebra with Applications, 6/e, Prentice Hall
      • +
      • Stephen H. Friedberg, Arnold J. Insel and Lawrence E. Spence, Linear Algebra, 3/e, Prentice Hall
      • +
      +
    • +
    • 資料結構 +
        +
      • Ellis Horowitz, Sartaj Sahni and Susan Anderson-freed, Fundamentals of Data Structures in C, An Imprint of W. H. Freeman and Company
      • +
      +
    • +
    • 演算法 +
        +
      • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest and Clifford Stein, Introduction to Algorithms, 2/e, MIT Press
      • +
      • Udi Manber, Introduction to Algorithms — A Creative Approach, Addision Wesley
      • +
      +
    • +
    • 計算機組織 : +
        +
      • David A. Patterson and John L. Hennessy, Computer Organization and Design (俗稱白算盤), 2/e, Morgan Kaufmann
      • +
      +
    • +
    • 作業系統 +
        +
      • Abraham Silberschatz, Peter Baer Galvin and Greg Gagne, Operating System Principles (俗稱恐龍本), 6/e, Wiley
      • +
      +
    • +
    +
    + +

    今天下午帶著這份書單,到許久未去的新生南路找書。上一次買原文教科書已經是十五年前的事了。帶著模糊的記憶往麥當勞樓上走,走到書林,看到都是文史學科的原文書,只後又走下來。想想我已經不大記得要到哪裏買理工科的原文書了,大概還是要上網去確認一下哪裏可以買得到吧。走著走著走到曉園,帶著姑且一試的心情走進去,沒想到就在這裏。滿架子的理工原文書。太久的記憶,真的忘得差不多了。

    + +

    在曉園找到六本書。十五前買書的時代還沒有著作權問題。現在一口氣買六本書,雖然我有預算,可是六千塊的原文書錢,心頭還是緊了一下。那十本買齊的話,大概要一萬吧。好貴。

    + +

    還有四本還沒找到。曉園說可以幫我調得到兩本,調到了再通知我。剛剛回家上網找,在愛因斯坦書店找到另外一本。愛因斯坦書店在麥當勞樓上,不過是另一邊樓梯上去。我果然沒有記錯,只是記不清楚而已。這樣就只剩一本了。

    + +

    算算,離三月中最先考的臺大資工所不到六個星期了。唔,那就是五天要唸完一本嗎?這也未免太誇張了。

    + +

    不過找到了該唸的教科書,前面的路又明亮了一大段。嗯,全身都充滿了幹勁呢~ ^_*' 加油加油~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 105 | + 106 | + 107 | + 108 | + 109 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0107.html.zh-cn.html b/htdocs/imacat/me/diary/0107.html.zh-cn.html new file mode 120000 index 0000000..a684a3e --- /dev/null +++ b/htdocs/imacat/me/diary/0107.html.zh-cn.html @@ -0,0 +1 @@ +0107.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0107.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0107.html.zh-cn.xhtml new file mode 100644 index 0000000..eef2fcc --- /dev/null +++ b/htdocs/imacat/me/diary/0107.html.zh-cn.xhtml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百零七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百零七

    + +
    + +
    + +
    +
    2.5.’07. 10:22pm.
    + +

    研究所考试课本

    + +

    一月十九日报名清大资工所中央资工所,一月二十三日报名台大资工所后,又一头钻进公司的案子里,忙了两个星期。明明三月的考试就迫在眉睫了,连课本都还没有空去买,心里著急得半死。这两天天气转热,昨天晚上忙一段落后,开始上网找研究所考试的课本。各校资工所,考的不外是离散数学、线性代数、资料结构、演算法、计算机组织、作业系统这六科。幸好网路上有人写了考资工所的心得,上面列了不少重要的资料,省去我找各科课本的时间:

    + +
    +
      +
    • 离散数学 +
        +
      • C. L. Liu (刘炯朗), Elements of Discrete Mathematics, 2/e, McGraw Hill
      • +
      • Ralph P. Grimaldi, Discrete Mathematics and Combinatorial Mathematics, 4/e, Addision Wesley
      • +
      • Kenneth H. Rosen, Discrete Mathematics and Its Applications, 5/e, McGraw Hill
      • +
      +
    • +
    • 线性代数 +
        +
      • Steven J. Leon, Linear Algebra with Applications, 6/e, Prentice Hall
      • +
      • Stephen H. Friedberg, Arnold J. Insel and Lawrence E. Spence, Linear Algebra, 3/e, Prentice Hall
      • +
      +
    • +
    • 资料结构 +
        +
      • Ellis Horowitz, Sartaj Sahni and Susan Anderson-freed, Fundamentals of Data Structures in C, An Imprint of W. H. Freeman and Company
      • +
      +
    • +
    • 演算法 +
        +
      • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest and Clifford Stein, Introduction to Algorithms, 2/e, MIT Press
      • +
      • Udi Manber, Introduction to Algorithms — A Creative Approach, Addision Wesley
      • +
      +
    • +
    • 计算机组织 : +
        +
      • David A. Patterson and John L. Hennessy, Computer Organization and Design (俗称白算盘), 2/e, Morgan Kaufmann
      • +
      +
    • +
    • 作业系统 +
        +
      • Abraham Silberschatz, Peter Baer Galvin and Greg Gagne, Operating System Principles (俗称恐龙本), 6/e, Wiley
      • +
      +
    • +
    +
    + +

    今天下午带著这份书单,到许久未去的新生南路找书。上一次买原文教科书已经是十五年前的事了。带著模糊的记忆往麦当劳楼上走,走到书林,看到都是文史学科的原文书,只后又走下来。想想我已经不大记得要到哪里买理工科的原文书了,大概还是要上网去确认一下哪里可以买得到吧。走著走著走到晓园,带著姑且一试的心情走进去,没想到就在这里。满架子的理工原文书。太久的记忆,真的忘得差不多了。

    + +

    在晓园找到六本书。十五前买书的时代还没有著作权问题。现在一口气买六本书,虽然我有预算,可是六千块的原文书钱,心头还是紧了一下。那十本买齐的话,大概要一万吧。好贵。

    + +

    还有四本还没找到。晓园说可以帮我调得到两本,调到了再通知我。刚刚回家上网找,在爱因斯坦书店找到另外一本。爱因斯坦书店在麦当劳楼上,不过是另一边楼梯上去。我果然没有记错,只是记不清楚而已。这样就只剩一本了。

    + +

    算算,离三月中最先考的台大资工所不到六个星期了。唔,那就是五天要念完一本吗?这也未免太夸张了。

    + +

    不过找到了该念的教科书,前面的路又明亮了一大段。嗯,全身都充满了干劲呢~ ^_*' 加油加油~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 105 | + 106 | + 107 | + 108 | + 109 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0107.html.zh-tw.html b/htdocs/imacat/me/diary/0107.html.zh-tw.html new file mode 120000 index 0000000..54603d3 --- /dev/null +++ b/htdocs/imacat/me/diary/0107.html.zh-tw.html @@ -0,0 +1 @@ +0107.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0107.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0107.html.zh-tw.xhtml new file mode 100644 index 0000000..2cd2c85 --- /dev/null +++ b/htdocs/imacat/me/diary/0107.html.zh-tw.xhtml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百零七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百零七

    + +
    + +
    + +
    +
    2.5.’07. 10:22pm.
    + +

    研究所考試課本

    + +

    一月十九日報名清大資工所中央資工所,一月二十三日報名臺大資工所後,又一頭鑽進公司的案子裏,忙了兩個星期。明明三月的考試就迫在眉睫了,連課本都還沒有空去買,心裏著急得半死。這兩天天氣轉熱,昨天晚上忙一段落後,開始上網找研究所考試的課本。各校資工所,考的不外是離散數學、線性代數、資料結構、演算法、計算機組織、作業系統這六科。幸好網路上有人寫了考資工所的心得,上面列了不少重要的資料,省去我找各科課本的時間:

    + +
    +
      +
    • 離散數學 +
        +
      • C. L. Liu (劉炯朗), Elements of Discrete Mathematics, 2/e, McGraw Hill
      • +
      • Ralph P. Grimaldi, Discrete Mathematics and Combinatorial Mathematics, 4/e, Addision Wesley
      • +
      • Kenneth H. Rosen, Discrete Mathematics and Its Applications, 5/e, McGraw Hill
      • +
      +
    • +
    • 線性代數 +
        +
      • Steven J. Leon, Linear Algebra with Applications, 6/e, Prentice Hall
      • +
      • Stephen H. Friedberg, Arnold J. Insel and Lawrence E. Spence, Linear Algebra, 3/e, Prentice Hall
      • +
      +
    • +
    • 資料結構 +
        +
      • Ellis Horowitz, Sartaj Sahni and Susan Anderson-freed, Fundamentals of Data Structures in C, An Imprint of W. H. Freeman and Company
      • +
      +
    • +
    • 演算法 +
        +
      • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest and Clifford Stein, Introduction to Algorithms, 2/e, MIT Press
      • +
      • Udi Manber, Introduction to Algorithms — A Creative Approach, Addision Wesley
      • +
      +
    • +
    • 計算機組織 : +
        +
      • David A. Patterson and John L. Hennessy, Computer Organization and Design (俗稱白算盤), 2/e, Morgan Kaufmann
      • +
      +
    • +
    • 作業系統 +
        +
      • Abraham Silberschatz, Peter Baer Galvin and Greg Gagne, Operating System Principles (俗稱恐龍本), 6/e, Wiley
      • +
      +
    • +
    +
    + +

    今天下午帶著這份書單,到許久未去的新生南路找書。上一次買原文教科書已經是十五年前的事了。帶著模糊的記憶往麥當勞樓上走,走到書林,看到都是文史學科的原文書,只後又走下來。想想我已經不大記得要到哪裏買理工科的原文書了,大概還是要上網去確認一下哪裏可以買得到吧。走著走著走到曉園,帶著姑且一試的心情走進去,沒想到就在這裏。滿架子的理工原文書。太久的記憶,真的忘得差不多了。

    + +

    在曉園找到六本書。十五前買書的時代還沒有著作權問題。現在一口氣買六本書,雖然我有預算,可是六千塊的原文書錢,心頭還是緊了一下。那十本買齊的話,大概要一萬吧。好貴。

    + +

    還有四本還沒找到。曉園說可以幫我調得到兩本,調到了再通知我。剛剛回家上網找,在愛因斯坦書店找到另外一本。愛因斯坦書店在麥當勞樓上,不過是另一邊樓梯上去。我果然沒有記錯,只是記不清楚而已。這樣就只剩一本了。

    + +

    算算,離三月中最先考的臺大資工所不到六個星期了。唔,那就是五天要唸完一本嗎?這也未免太誇張了。

    + +

    不過找到了該唸的教科書,前面的路又明亮了一大段。嗯,全身都充滿了幹勁呢~ ^_*' 加油加油~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 105 | + 106 | + 107 | + 108 | + 109 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0108.html.en.html b/htdocs/imacat/me/diary/0108.html.en.html new file mode 120000 index 0000000..4a77c7b --- /dev/null +++ b/htdocs/imacat/me/diary/0108.html.en.html @@ -0,0 +1 @@ +0108.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0108.html.en.xhtml b/htdocs/imacat/me/diary/0108.html.en.xhtml new file mode 100644 index 0000000..acd2096 --- /dev/null +++ b/htdocs/imacat/me/diary/0108.html.en.xhtml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 108 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 108

    + +
    + +
    + +
    +
    2.9.’07. 0:49am.
    + +

    買書與唸書

    + +

    之前說的原文書,隔天我早上就去了愛因斯坦書店找。沒想到兩本缺的書都找到了。愛因斯坦書店也很神通廣大呢。我看它光是數學的原文書就有三個架子,曉園數學書只有一架。不過我只有買兩本書,也很難說愛因斯坦的書是不是比曉園齊。

    + +

    兩天內,十本原文書書都找齊了,花了九千八左右。好貴。兩天拿出這麼多現金結帳,心頭也有點抽動。

    + +

    離考試只有一個多月,十本書,一本只能看個四、五天。以一本書五百頁來說,平均一天要看一百頁原文書。這根本是不可能的事。不過我也只能拼命唸了。

    + +

    這幾天唸下來,每天唸到清晨四、五點,平均一天只有唸一節,二十頁左右。這一本是線性代數。我覺得我唸得比十五年前大二剛拿到線性代數的時候,唸得還要順。大概是經驗吧。以前唸來唸去,完全不知道為什麼要這樣做,怎麼都看不懂。現在我寫了那麼多程式,再回來看,反而一下子就知道為什麼要演繹這些公式、理論。線性代數果然是電腦計算的基礎,有了電腦程式實務經驗後,再回來看線性代數,反而比起空白摸索,還要清楚它的應用性在哪裏。而且我現在英文也比大二時好很多了,看原文也不吃力。

    + +

    不過一天只唸一節二十頁,要唸完一本,大概要一個月。十本大概要十個月。這還是每天唸書唸到早上五點,把自己逼到極限了的結果,不可能再勉強下去了。而且我也不可能持續十個月每天熬到五點睡,身體不可能撐得住。而現在離考試只剩一個多月,時間上實在是不允許。怎麼辦呢?

    + +
    + +
    + +
    +
    2.9.’07. 0:34am.
    + +

    NANA 卡通

    + +

    之前 MICO 在旅人留言簿問到 NANA 卡通的事,我一陣子沒有追蹤 NANA 的訊息了,上網一查,竟然發現中視從一月十一日起,播 NANA 卡通。哇,正式商業翻譯的 NANA 卡通耶,不是那種卡通同好會翻譯版,讓我非常期待。我怕我一忙就忙忘了,趕緊在電視卡的觀看程式上設定,每星期四晚上九點半到十點半定時啟動錄影,也順便提醒自己。

    + +

    這一陣子忙,果然忙忘了。今天晚上查一個資料時,突然電腦電視卡開啟了,讓我想起 NANA 卡通的事。今天晚上播的是關鍵性的兩集,奈々在 707 室聽到ナナ的單人演唱會,超感動的衝擊。中視播雙語,不過之前看過日語的了,我切成國語配音來聽。還不錯。商業翻譯的水準,果然比卡通同好會高很多。真好看,超感動的。

    + +

    片尾看到亞米可中文字幕幾個字,趕緊記下來,上網去找。原來亞米可是群英社的子公司。再到群英社的網站上找,原來是群英社取得了 NANA 的臺灣代理權,再找中視播。上群英社的線上商店去看,原來 NANA 的中文版卡通 DVD 都已經出來了,而且出到第五部了!不過一部內含三集要 450 ,好貴。買不下手。 ^^;

    + +

    不過我在群英社的線上商店上看到一件 NANA 的 T 恤,很漂亮,而且又不貴。我想去買說。 ^_*'

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 106 | + 107 | + 108 | + 109 | + 110 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0108.html.zh-cn.html b/htdocs/imacat/me/diary/0108.html.zh-cn.html new file mode 120000 index 0000000..f49ecd3 --- /dev/null +++ b/htdocs/imacat/me/diary/0108.html.zh-cn.html @@ -0,0 +1 @@ +0108.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0108.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0108.html.zh-cn.xhtml new file mode 100644 index 0000000..a4d010e --- /dev/null +++ b/htdocs/imacat/me/diary/0108.html.zh-cn.xhtml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百零八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百零八

    + +
    + +
    + +
    +
    2.9.’07. 0:49am.
    + +

    买书与念书

    + +

    之前说的原文书,隔天我早上就去了爱因斯坦书店找。没想到两本缺的书都找到了。爱因斯坦书店也很神通广大呢。我看它光是数学的原文书就有三个架子,晓园数学书只有一架。不过我只有买两本书,也很难说爱因斯坦的书是不是比晓园齐。

    + +

    两天内,十本原文书书都找齐了,花了九千八左右。好贵。两天拿出这么多现金结帐,心头也有点抽动。

    + +

    离考试只有一个多月,十本书,一本只能看个四、五天。以一本书五百页来说,平均一天要看一百页原文书。这根本是不可能的事。不过我也只能拼命念了。

    + +

    这几天念下来,每天念到清晨四、五点,平均一天只有念一节,二十页左右。这一本是线性代数。我觉得我念得比十五年前大二刚拿到线性代数的时候,念得还要顺。大概是经验吧。以前念来念去,完全不知道为什么要这样做,怎么都看不懂。现在我写了那么多程式,再回来看,反而一下子就知道为什么要演绎这些公式、理论。线性代数果然是电脑计算的基础,有了电脑程式实务经验后,再回来看线性代数,反而比起空白摸索,还要清楚它的应用性在哪里。而且我现在英文也比大二时好很多了,看原文也不吃力。

    + +

    不过一天只念一节二十页,要念完一本,大概要一个月。十本大概要十个月。这还是每天念书念到早上五点,把自己逼到极限了的结果,不可能再勉强下去了。而且我也不可能持续十个月每天熬到五点睡,身体不可能撑得住。而现在离考试只剩一个多月,时间上实在是不允许。怎么办呢?

    + +
    + +
    + +
    +
    2.9.’07. 0:34am.
    + +

    NANA 卡通

    + +

    之前 MICO 在旅人留言簿问到 NANA 卡通的事,我一阵子没有追踪 NANA 的讯息了,上网一查,竟然发现中视从一月十一日起,播 NANA 卡通。哇,正式商业翻译的 NANA 卡通耶,不是那种卡通同好会翻译版,让我非常期待。我怕我一忙就忙忘了,赶紧在电视卡的观看程式上设定,每星期四晚上九点半到十点半定时启动录影,也顺便提醒自己。

    + +

    这一阵子忙,果然忙忘了。今天晚上查一个资料时,突然电脑电视卡开启了,让我想起 NANA 卡通的事。今天晚上播的是关键性的两集,奈々在 707 室听到ナナ的单人演唱会,超感动的冲击。中视播双语,不过之前看过日语的了,我切成国语配音来听。还不错。商业翻译的水准,果然比卡通同好会高很多。真好看,超感动的。

    + +

    片尾看到亚米可中文字幕几个字,赶紧记下来,上网去找。原来亚米可是群英社的子公司。再到群英社的网站上找,原来是群英社取得了 NANA 的台湾代理权,再找中视播。上群英社的线上商店去看,原来 NANA 的中文版卡通 DVD 都已经出来了,而且出到第五部了!不过一部内含三集要 450 ,好贵。买不下手。 ^^;

    + +

    不过我在群英社的线上商店上看到一件 NANA 的 T 恤,很漂亮,而且又不贵。我想去买说。 ^_*'

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 106 | + 107 | + 108 | + 109 | + 110 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0108.html.zh-tw.html b/htdocs/imacat/me/diary/0108.html.zh-tw.html new file mode 120000 index 0000000..978520e --- /dev/null +++ b/htdocs/imacat/me/diary/0108.html.zh-tw.html @@ -0,0 +1 @@ +0108.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0108.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0108.html.zh-tw.xhtml new file mode 100644 index 0000000..15f3565 --- /dev/null +++ b/htdocs/imacat/me/diary/0108.html.zh-tw.xhtml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百零八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百零八

    + +
    + +
    + +
    +
    2.9.’07. 0:49am.
    + +

    買書與唸書

    + +

    之前說的原文書,隔天我早上就去了愛因斯坦書店找。沒想到兩本缺的書都找到了。愛因斯坦書店也很神通廣大呢。我看它光是數學的原文書就有三個架子,曉園數學書只有一架。不過我只有買兩本書,也很難說愛因斯坦的書是不是比曉園齊。

    + +

    兩天內,十本原文書書都找齊了,花了九千八左右。好貴。兩天拿出這麼多現金結帳,心頭也有點抽動。

    + +

    離考試只有一個多月,十本書,一本只能看個四、五天。以一本書五百頁來說,平均一天要看一百頁原文書。這根本是不可能的事。不過我也只能拼命唸了。

    + +

    這幾天唸下來,每天唸到清晨四、五點,平均一天只有唸一節,二十頁左右。這一本是線性代數。我覺得我唸得比十五年前大二剛拿到線性代數的時候,唸得還要順。大概是經驗吧。以前唸來唸去,完全不知道為什麼要這樣做,怎麼都看不懂。現在我寫了那麼多程式,再回來看,反而一下子就知道為什麼要演繹這些公式、理論。線性代數果然是電腦計算的基礎,有了電腦程式實務經驗後,再回來看線性代數,反而比起空白摸索,還要清楚它的應用性在哪裏。而且我現在英文也比大二時好很多了,看原文也不吃力。

    + +

    不過一天只唸一節二十頁,要唸完一本,大概要一個月。十本大概要十個月。這還是每天唸書唸到早上五點,把自己逼到極限了的結果,不可能再勉強下去了。而且我也不可能持續十個月每天熬到五點睡,身體不可能撐得住。而現在離考試只剩一個多月,時間上實在是不允許。怎麼辦呢?

    + +
    + +
    + +
    +
    2.9.’07. 0:34am.
    + +

    NANA 卡通

    + +

    之前 MICO 在旅人留言簿問到 NANA 卡通的事,我一陣子沒有追蹤 NANA 的訊息了,上網一查,竟然發現中視從一月十一日起,播 NANA 卡通。哇,正式商業翻譯的 NANA 卡通耶,不是那種卡通同好會翻譯版,讓我非常期待。我怕我一忙就忙忘了,趕緊在電視卡的觀看程式上設定,每星期四晚上九點半到十點半定時啟動錄影,也順便提醒自己。

    + +

    這一陣子忙,果然忙忘了。今天晚上查一個資料時,突然電腦電視卡開啟了,讓我想起 NANA 卡通的事。今天晚上播的是關鍵性的兩集,奈々在 707 室聽到ナナ的單人演唱會,超感動的衝擊。中視播雙語,不過之前看過日語的了,我切成國語配音來聽。還不錯。商業翻譯的水準,果然比卡通同好會高很多。真好看,超感動的。

    + +

    片尾看到亞米可中文字幕幾個字,趕緊記下來,上網去找。原來亞米可是群英社的子公司。再到群英社的網站上找,原來是群英社取得了 NANA 的臺灣代理權,再找中視播。上群英社的線上商店去看,原來 NANA 的中文版卡通 DVD 都已經出來了,而且出到第五部了!不過一部內含三集要 450 ,好貴。買不下手。 ^^;

    + +

    不過我在群英社的線上商店上看到一件 NANA 的 T 恤,很漂亮,而且又不貴。我想去買說。 ^_*'

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 106 | + 107 | + 108 | + 109 | + 110 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0109.html.en.html b/htdocs/imacat/me/diary/0109.html.en.html new file mode 120000 index 0000000..1168178 --- /dev/null +++ b/htdocs/imacat/me/diary/0109.html.en.html @@ -0,0 +1 @@ +0109.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0109.html.en.xhtml b/htdocs/imacat/me/diary/0109.html.en.xhtml new file mode 100644 index 0000000..c5a02cc --- /dev/null +++ b/htdocs/imacat/me/diary/0109.html.en.xhtml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 109 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 109

    + +
    + +
    + +
    +
    2.9.’07. 1:13am.
    + +

    Time Cube 時間方塊

    + +

    今天在 Perl Module Authors 的通訊上,有人丟了一個話題:要求刪除充滿仇恨性字眼的 Time::Cubic 模組。我有點好奇,上網查了查,發現這是一個信奉Time Cube 時間方塊的奇怪宗教。

    + +

    依 Wikipedia 上的說明, Time Cube 時間方塊是由 Gene Ray 創立的宗教。 Gene Ray 是美國人,本來是個水電工,喜歡玩彩色玻璃彈珠 (Marbles) ,曾經想辦全國彈珠大賽。他從彈珠中悟出 Time Cube 時間方塊的道理。 Time Cube 時間方塊的主張大致上為:

    + +
      +
    1. 世界上的一切都是方塊。時間是最高的方塊。地球其實也是方塊,可是邪惡的人欺騙人類,讓人以為地球是圓的。不知道地球是方塊的人,都被騙了。
    2. + +
    3. 地球自轉一圈,同時有四天,但是我們只知道一天,因為邪惡的人欺騙我們,不讓我們知道地球是方的真相,所以我們對另外三天一無所知。
    4. + +
    5. 運動的根源是反力 (Opposite) 。反力推動所有的事物運作,一切人、事、物都是反力。
    6. + +
    7. 上帝是邪惡的人造來騙人的,為了讓我們不知道真相。邪惡的人有很多共犯,包括學校老師、教授等等。所以大多數人都被騙了,變得很笨。老師是邪惡的幫兇。舉例來說,我們常見的數學等式 -1 × -1 = 1 就是騙人的謊言。
    8. +
    + +

    由前面的論點推下去, Gene Ray 主張殺老師不是罪,因為老師是邪惡的鷹犬。雖然他本人否認有這樣的主張,但他的網站上有很多主張殺老師不是罪的話,頗為自相矛盾。他也說了很多仇視同性戀的話,雖然他本人也否認。

    + +

    Gene Ray 曾經在學生信徒的支持下,在麻省理工學院演講過,也曾上報紙電台接受訪問,算是小有名氣。他懸賞美金一萬元給能夠駁倒他的Time Cube 時間方塊理論的學者,不過沒有學者去挑戰過。他的時間方塊理論講得很模糊,很難認真去反駁。他少數比較清楚的主張是反對 -1 × -1 = 1 ,不過這違反基本數學假設,沒有反駁的意義。認真做研究的學者,都不屑去理他。

    + +

    嗯,唔。瘋子。

    + +

    我原則上支持宗教自由,不過像這種瘋子就免了。只因為別人不相信地球是方的,就要殺老師,根本是神經病。

    + +

    Time Cube 時間方塊好像有些信徒,不過因為沒有成立過正式的實體宗教組織,所以信徒數目無從估計。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 107 | + 108 | + 109 | + 110 | + 111 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0109.html.zh-cn.html b/htdocs/imacat/me/diary/0109.html.zh-cn.html new file mode 120000 index 0000000..dd151cb --- /dev/null +++ b/htdocs/imacat/me/diary/0109.html.zh-cn.html @@ -0,0 +1 @@ +0109.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0109.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0109.html.zh-cn.xhtml new file mode 100644 index 0000000..150a444 --- /dev/null +++ b/htdocs/imacat/me/diary/0109.html.zh-cn.xhtml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百零九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百零九

    + +
    + +
    + +
    +
    2.9.’07. 1:13am.
    + +

    Time Cube 时间方块

    + +

    今天在 Perl Module Authors 的通讯上,有人丢了一个话题:要求删除充满仇恨性字眼的 Time::Cubic 模组。我有点好奇,上网查了查,发现这是一个信奉Time Cube 时间方块的奇怪宗教。

    + +

    依 Wikipedia 上的说明, Time Cube 时间方块是由 Gene Ray 创立的宗教。 Gene Ray 是美国人,本来是个水电工,喜欢玩彩色玻璃弹珠 (Marbles) ,曾经想办全国弹珠大赛。他从弹珠中悟出 Time Cube 时间方块的道理。 Time Cube 时间方块的主张大致上为:

    + +
      +
    1. 世界上的一切都是方块。时间是最高的方块。地球其实也是方块,可是邪恶的人欺骗人类,让人以为地球是圆的。不知道地球是方块的人,都被骗了。
    2. + +
    3. 地球自转一圈,同时有四天,但是我们只知道一天,因为邪恶的人欺骗我们,不让我们知道地球是方的真相,所以我们对另外三天一无所知。
    4. + +
    5. 运动的根源是反力 (Opposite) 。反力推动所有的事物运作,一切人、事、物都是反力。
    6. + +
    7. 上帝是邪恶的人造来骗人的,为了让我们不知道真相。邪恶的人有很多共犯,包括学校老师、教授等等。所以大多数人都被骗了,变得很笨。老师是邪恶的帮凶。举例来说,我们常见的数学等式 -1 × -1 = 1 就是骗人的谎言。
    8. +
    + +

    由前面的论点推下去, Gene Ray 主张杀老师不是罪,因为老师是邪恶的鹰犬。虽然他本人否认有这样的主张,但他的网站上有很多主张杀老师不是罪的话,颇为自相矛盾。他也说了很多仇视同性恋的话,虽然他本人也否认。

    + +

    Gene Ray 曾经在学生信徒的支持下,在麻省理工学院演讲过,也曾上报纸电台接受访问,算是小有名气。他悬赏美金一万元给能够驳倒他的Time Cube 时间方块理论的学者,不过没有学者去挑战过。他的时间方块理论讲得很模糊,很难认真去反驳。他少数比较清楚的主张是反对 -1 × -1 = 1 ,不过这违反基本数学假设,没有反驳的意义。认真做研究的学者,都不屑去理他。

    + +

    嗯,唔。疯子。

    + +

    我原则上支持宗教自由,不过像这种疯子就免了。只因为别人不相信地球是方的,就要杀老师,根本是神经病。

    + +

    Time Cube 时间方块好像有些信徒,不过因为没有成立过正式的实体宗教组织,所以信徒数目无从估计。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 107 | + 108 | + 109 | + 110 | + 111 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0109.html.zh-tw.html b/htdocs/imacat/me/diary/0109.html.zh-tw.html new file mode 120000 index 0000000..a58823c --- /dev/null +++ b/htdocs/imacat/me/diary/0109.html.zh-tw.html @@ -0,0 +1 @@ +0109.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0109.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0109.html.zh-tw.xhtml new file mode 100644 index 0000000..e4a945b --- /dev/null +++ b/htdocs/imacat/me/diary/0109.html.zh-tw.xhtml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百零九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百零九

    + +
    + +
    + +
    +
    2.9.’07. 1:13am.
    + +

    Time Cube 時間方塊

    + +

    今天在 Perl Module Authors 的通訊上,有人丟了一個話題:要求刪除充滿仇恨性字眼的 Time::Cubic 模組。我有點好奇,上網查了查,發現這是一個信奉Time Cube 時間方塊的奇怪宗教。

    + +

    依 Wikipedia 上的說明, Time Cube 時間方塊是由 Gene Ray 創立的宗教。 Gene Ray 是美國人,本來是個水電工,喜歡玩彩色玻璃彈珠 (Marbles) ,曾經想辦全國彈珠大賽。他從彈珠中悟出 Time Cube 時間方塊的道理。 Time Cube 時間方塊的主張大致上為:

    + +
      +
    1. 世界上的一切都是方塊。時間是最高的方塊。地球其實也是方塊,可是邪惡的人欺騙人類,讓人以為地球是圓的。不知道地球是方塊的人,都被騙了。
    2. + +
    3. 地球自轉一圈,同時有四天,但是我們只知道一天,因為邪惡的人欺騙我們,不讓我們知道地球是方的真相,所以我們對另外三天一無所知。
    4. + +
    5. 運動的根源是反力 (Opposite) 。反力推動所有的事物運作,一切人、事、物都是反力。
    6. + +
    7. 上帝是邪惡的人造來騙人的,為了讓我們不知道真相。邪惡的人有很多共犯,包括學校老師、教授等等。所以大多數人都被騙了,變得很笨。老師是邪惡的幫兇。舉例來說,我們常見的數學等式 -1 × -1 = 1 就是騙人的謊言。
    8. +
    + +

    由前面的論點推下去, Gene Ray 主張殺老師不是罪,因為老師是邪惡的鷹犬。雖然他本人否認有這樣的主張,但他的網站上有很多主張殺老師不是罪的話,頗為自相矛盾。他也說了很多仇視同性戀的話,雖然他本人也否認。

    + +

    Gene Ray 曾經在學生信徒的支持下,在麻省理工學院演講過,也曾上報紙電台接受訪問,算是小有名氣。他懸賞美金一萬元給能夠駁倒他的Time Cube 時間方塊理論的學者,不過沒有學者去挑戰過。他的時間方塊理論講得很模糊,很難認真去反駁。他少數比較清楚的主張是反對 -1 × -1 = 1 ,不過這違反基本數學假設,沒有反駁的意義。認真做研究的學者,都不屑去理他。

    + +

    嗯,唔。瘋子。

    + +

    我原則上支持宗教自由,不過像這種瘋子就免了。只因為別人不相信地球是方的,就要殺老師,根本是神經病。

    + +

    Time Cube 時間方塊好像有些信徒,不過因為沒有成立過正式的實體宗教組織,所以信徒數目無從估計。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 107 | + 108 | + 109 | + 110 | + 111 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0110.html.en.html b/htdocs/imacat/me/diary/0110.html.en.html new file mode 120000 index 0000000..89ac1a2 --- /dev/null +++ b/htdocs/imacat/me/diary/0110.html.en.html @@ -0,0 +1 @@ +0110.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0110.html.en.xhtml b/htdocs/imacat/me/diary/0110.html.en.xhtml new file mode 100644 index 0000000..c2984a2 --- /dev/null +++ b/htdocs/imacat/me/diary/0110.html.en.xhtml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 110 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 110

    + +
    + +
    + +
    +
    3.15.’07. 2:37am.
    + +

    風扇阻塞

    + +

    去年年初新買的 rinse , CPU 是 Pentium D 3.2 GHz Dual Core 雙核心,應該要跑得很快的。

    + +

    可是跑了半年,開始出現問題。一開始是過熱,過熱時, CPU 會自動調慢速度以降溫。一開始我覺得是不錯的功能。不過在去年年底幫公司買了一台 Intel Core 2 Duo E6400 2.13 GHz 後,比較之下, rinse Pentium D 過熱的問題變得明顯。 Core 2 Duo 省電很多,從來沒有過熱,風扇不需要轉得那麼用力,也很安靜。相比之下, Pentium D 就顯得很吵。到後來,過熱的問題,越來越嚴重,只要 server 做一點事,就會過熱降速。甚至連網站 web server 服務也會造成過熱。一降速下來, 3.2 GHzCPU ,和 850 MHz 的 Pentium Ⅲ Coppermine ,效能差不了多少。

    + +

    我快被這個問題搞瘋了。之前問同事,同事建議我檢查看看風扇。可是一直考試閒不下來,也一直沒有空去注意。晚上網站做一些繁重的測試,竟然搞到當掉,當掉後還無法重開機!這也未免太扯了!在考研究所的考季碰到這種事,真是欲哭無淚。沒辦法,沒有 server 不行,我還是要拆開來檢查。

    + +

    沒想到還沒拆開,就發現問題了。新的 rinse 的側面有一個大風扇,風扇吹久了,上面積了厚厚的一層灰塵。難怪無法散熱,整天在過熱!停下機,徒手把上面的灰塵清乾淨,又用壓縮空氣瓶裏裏外外清一清,到沒有看到灰塵了,才裝回機殼,重新開機。

    + +

    唔,好安靜。而且不再那麼容易過熱了。原來就是這個原因。這麼簡單!第一次碰到風扇散熱出風口,因積塵阻塞,而造成系統過熱不穩。還有這種事。嗯嗯,要好好記下來。

    + +
    + +
    + +
    +
    2.11.’07. 6:48am.
    + +

    象棋

    + +

    星期五晚上,走訪夜市買春聯,逛到電腦遊戲的攤子,看到中國象棋Ⅱ,特價 299 。出版商遊戲海科技,我從來沒聽過。不知道是不是中國寫的。我實在不想再看到簡體的字了。不過上面號稱收錄了橘中秘等等十幾本古今棋書近兩千譜,這些棋譜一本一本買就不只這個價錢了,一時心動,就買下來了。

    + +

    安裝了一下,遊戲很小,只有 2MB 。還好裏面的棋子都是正體字。仔細看看用詞,計算機默認值的,應該還是中國寫的。可能是找中國軟體設計師代工,或是拿中國已經發行的軟體來繁體化。不過看在棋譜真的很豐富,反正字體是正體,就不計較了。 ^_*'

    + +

    玩了一局,發現它的棋力超高。盒子上寫有入門級、簡單級,但其實一點都不簡單,我怎麼樣都下不贏它。仔細想想,大概也理解其中的原因。這套遊戲應該是以 Windows 98 Pentium Ⅱ 的環境作基礎寫的,其棋力高低是以限電腦思考幾秒為準,入門級五秒,簡單級十秒。然而, Pentium Ⅱ 的五秒,和我現在 AMD K7 的五秒,是完全不一樣的兩回事。 Pentium Ⅱ 上要思考三十分鐘的高級計算,跑在 AMD K7 上不需要到一秒吧。所以在我的 AMD K7 上不管限幾秒,電腦計算能達到的複雜度,像我這樣初級的人,都沒有勝算。

    + +

    我覺得橘中秘這個名字很有趣。為什麼象棋棋譜取名橘中秘呢?我查了一下,發現其典故來自唐牛僧孺的誌怪小說玄怪錄第三卷中的巴邛人

    + +
    +

    有巴邛人,不知姓名,家有橘園。因霜後,諸橘盡收,餘有兩大橘,如三斗盎。巴人異之,即令攀摘,輕重亦如常橘。剖開,每橘有二老叟,鬢眉皤然,肌體紅潤,皆相對象戲,身長尺餘,談笑自若,剖開後亦不驚怖,但相與決賭。

    + +

    決賭訖,一叟曰:君輸我海上龍王第七女髲髮十兩,智瓊額黃十二枝,紫絹帔一副,絳臺山霞寶散二庾,瀛洲玉塵九斛,阿母療髓凝酒四鍾,阿母女態盈娘子躋虛龍縞襪八緉,後日於王先生青城草堂還我耳。

    + +

    又有一叟曰:王先生許來,竟待不得,橘中之樂,不減商山,但不得深根固蒂,為愚人摘下耳。

    + +

    又一叟曰:僕饑矣,須龍根脯食之。即於袖中抽出一草根,方圓徑寸,形狀宛轉如龍,毫釐罔不周悉,因削食之,隨削隨滿。

    + +

    食訖,以水噀之,化為一龍,四叟共乘之,足下泄泄雲起。須臾,風雨晦冥,不知所在。

    +

    巴人相傳云:百五十年來如此,似在陳隋之間,但不知的年號耳。

    +
    + +

    後人便把橘中之樂作為象棋的雅稱。橘中秘自然就是指象棋的玄機道理了。

    + +

    原來還有這麼有趣的典故。橘中秘梅花譜並稱是最重要的兩本象棋棋譜。明代的橘中秘很強調當頭炮的重要,詳細分析了當頭炮各種的攻殺法;而後來的清代梅花譜,則以屏風馬來對當頭炮,詳列了許多以屏風馬剋制當頭炮,以守為攻的勝法。這些都對後世影響很深遠。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 108 | + 109 | + 110 | + 111 | + 112 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0110.html.zh-cn.html b/htdocs/imacat/me/diary/0110.html.zh-cn.html new file mode 120000 index 0000000..978f525 --- /dev/null +++ b/htdocs/imacat/me/diary/0110.html.zh-cn.html @@ -0,0 +1 @@ +0110.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0110.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0110.html.zh-cn.xhtml new file mode 100644 index 0000000..30d8505 --- /dev/null +++ b/htdocs/imacat/me/diary/0110.html.zh-cn.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百一十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百一十

    + +
    + +
    + +
    +
    3.15.’07. 2:37am.
    + +

    风扇阻塞

    + +

    去年年初新买的 rinse , CPU 是 Pentium D 3.2 GHz Dual Core 双核心,应该要跑得很快的。

    + +

    可是跑了半年,开始出现问题。一开始是过热,过热时, CPU 会自动调慢速度以降温。一开始我觉得是不错的功能。不过在去年年底帮公司买了一台 Intel Core 2 Duo E6400 2.13 GHz 后,比较之下, rinse Pentium D 过热的问题变得明显。 Core 2 Duo 省电很多,从来没有过热,风扇不需要转得那么用力,也很安静。相比之下, Pentium D 就显得很吵。到后来,过热的问题,越来越严重,只要 server 做一点事,就会过热降速。甚至连网站 web server 服务也会造成过热。一降速下来, 3.2 GHzCPU ,和 850 MHz 的 Pentium Ⅲ Coppermine ,效能差不了多少。

    + +

    我快被这个问题搞疯了。之前问同事,同事建议我检查看看风扇。可是一直考试闲不下来,也一直没有空去注意。晚上网站做一些繁重的测试,竟然搞到当掉,当掉后还无法重开机!这也未免太扯了!在考研究所的考季碰到这种事,真是欲哭无泪。没办法,没有 server 不行,我还是要拆开来检查。

    + +

    没想到还没拆开,就发现问题了。新的 rinse 的侧面有一个大风扇,风扇吹久了,上面积了厚厚的一层灰尘。难怪无法散热,整天在过热!停下机,徒手把上面的灰尘清干净,又用压缩空气瓶里里外外清一清,到没有看到灰尘了,才装回机壳,重新开机。

    + +

    唔,好安静。而且不再那么容易过热了。原来就是这个原因。这么简单!第一次碰到风扇散热出风口,因积尘阻塞,而造成系统过热不稳。还有这种事。嗯嗯,要好好记下来。

    + +
    + +
    + +
    +
    2.11.’07. 6:48am.
    + +

    象棋

    + +

    星期五晚上,走访夜市买春联,逛到电脑游戏的摊子,看到中国象棋Ⅱ,特价 299 。出版商游戏海科技,我从来没听过。不知道是不是中国写的。我实在不想再看到简体的字了。不过上面号称收录了橘中秘等等十几本古今棋书近两千谱,这些棋谱一本一本买就不只这个价钱了,一时心动,就买下来了。

    + +

    安装了一下,游戏很小,只有 2MB 。还好里面的棋子都是正体字。仔细看看用词,计算机默认值的,应该还是中国写的。可能是找中国软体设计师代工,或是拿中国已经发行的软体来繁体化。不过看在棋谱真的很丰富,反正字体是正体,就不计较了。 ^_*'

    + +

    玩了一局,发现它的棋力超高。盒子上写有入门级、简单级,但其实一点都不简单,我怎么样都下不赢它。仔细想想,大概也理解其中的原因。这套游戏应该是以 Windows 98 Pentium Ⅱ 的环境作基础写的,其棋力高低是以限电脑思考几秒为准,入门级五秒,简单级十秒。然而, Pentium Ⅱ 的五秒,和我现在 AMD K7 的五秒,是完全不一样的两回事。 Pentium Ⅱ 上要思考三十分钟的高级计算,跑在 AMD K7 上不需要到一秒吧。所以在我的 AMD K7 上不管限几秒,电脑计算能达到的复杂度,像我这样初级的人,都没有胜算。

    + +

    我觉得橘中秘这个名字很有趣。为什么象棋棋谱取名橘中秘呢?我查了一下,发现其典故来自唐牛僧孺的志怪小说玄怪录第三卷中的巴邛人

    + +
    +

    有巴邛人,不知姓名,家有橘园。因霜后,诸橘尽收,余有两大橘,如三斗盎。巴人异之,即令攀摘,轻重亦如常橘。剖开,每橘有二老叟,鬓眉皤然,肌体红润,皆相对象戏,身长尺余,谈笑自若,剖开后亦不惊怖,但相与决赌。

    + +

    决赌讫,一叟曰:君输我海上龙王第七女髲发十两,智琼额黄十二枝,紫绢帔一副,绛台山霞宝散二庾,瀛洲玉尘九斛,阿母疗髓凝酒四钟,阿母女态盈娘子跻虚龙缟袜八緉,后日於王先生青城草堂还我耳。

    + +

    又有一叟曰:王先生许来,竟待不得,橘中之乐,不减商山,但不得深根固蒂,为愚人摘下耳。

    + +

    又一叟曰:仆饥矣,须龙根脯食之。即於袖中抽出一草根,方圆径寸,形状宛转如龙,毫厘罔不周悉,因削食之,随削随满。

    + +

    食讫,以水噀之,化为一龙,四叟共乘之,足下泄泄云起。须臾,风雨晦冥,不知所在。

    +

    巴人相传云:百五十年来如此,似在陈隋之间,但不知的年号耳。

    +
    + +

    后人便把橘中之乐作为象棋的雅称。橘中秘自然就是指象棋的玄机道理了。

    + +

    原来还有这么有趣的典故。橘中秘梅花谱并称是最重要的两本象棋棋谱。明代的橘中秘很强调当头炮的重要,详细分析了当头炮各种的攻杀法;而后来的清代梅花谱,则以屏风马来对当头炮,详列了许多以屏风马克制当头炮,以守为攻的胜法。这些都对后世影响很深远。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 108 | + 109 | + 110 | + 111 | + 112 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0110.html.zh-tw.html b/htdocs/imacat/me/diary/0110.html.zh-tw.html new file mode 120000 index 0000000..578824f --- /dev/null +++ b/htdocs/imacat/me/diary/0110.html.zh-tw.html @@ -0,0 +1 @@ +0110.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0110.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0110.html.zh-tw.xhtml new file mode 100644 index 0000000..0a9a9e3 --- /dev/null +++ b/htdocs/imacat/me/diary/0110.html.zh-tw.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百一十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百一十

    + +
    + +
    + +
    +
    3.15.’07. 2:37am.
    + +

    風扇阻塞

    + +

    去年年初新買的 rinse , CPU 是 Pentium D 3.2 GHz Dual Core 雙核心,應該要跑得很快的。

    + +

    可是跑了半年,開始出現問題。一開始是過熱,過熱時, CPU 會自動調慢速度以降溫。一開始我覺得是不錯的功能。不過在去年年底幫公司買了一台 Intel Core 2 Duo E6400 2.13 GHz 後,比較之下, rinse Pentium D 過熱的問題變得明顯。 Core 2 Duo 省電很多,從來沒有過熱,風扇不需要轉得那麼用力,也很安靜。相比之下, Pentium D 就顯得很吵。到後來,過熱的問題,越來越嚴重,只要 server 做一點事,就會過熱降速。甚至連網站 web server 服務也會造成過熱。一降速下來, 3.2 GHzCPU ,和 850 MHz 的 Pentium Ⅲ Coppermine ,效能差不了多少。

    + +

    我快被這個問題搞瘋了。之前問同事,同事建議我檢查看看風扇。可是一直考試閒不下來,也一直沒有空去注意。晚上網站做一些繁重的測試,竟然搞到當掉,當掉後還無法重開機!這也未免太扯了!在考研究所的考季碰到這種事,真是欲哭無淚。沒辦法,沒有 server 不行,我還是要拆開來檢查。

    + +

    沒想到還沒拆開,就發現問題了。新的 rinse 的側面有一個大風扇,風扇吹久了,上面積了厚厚的一層灰塵。難怪無法散熱,整天在過熱!停下機,徒手把上面的灰塵清乾淨,又用壓縮空氣瓶裏裏外外清一清,到沒有看到灰塵了,才裝回機殼,重新開機。

    + +

    唔,好安靜。而且不再那麼容易過熱了。原來就是這個原因。這麼簡單!第一次碰到風扇散熱出風口,因積塵阻塞,而造成系統過熱不穩。還有這種事。嗯嗯,要好好記下來。

    + +
    + +
    + +
    +
    2.11.’07. 6:48am.
    + +

    象棋

    + +

    星期五晚上,走訪夜市買春聯,逛到電腦遊戲的攤子,看到中國象棋Ⅱ,特價 299 。出版商遊戲海科技,我從來沒聽過。不知道是不是中國寫的。我實在不想再看到簡體的字了。不過上面號稱收錄了橘中秘等等十幾本古今棋書近兩千譜,這些棋譜一本一本買就不只這個價錢了,一時心動,就買下來了。

    + +

    安裝了一下,遊戲很小,只有 2MB 。還好裏面的棋子都是正體字。仔細看看用詞,計算機默認值的,應該還是中國寫的。可能是找中國軟體設計師代工,或是拿中國已經發行的軟體來繁體化。不過看在棋譜真的很豐富,反正字體是正體,就不計較了。 ^_*'

    + +

    玩了一局,發現它的棋力超高。盒子上寫有入門級、簡單級,但其實一點都不簡單,我怎麼樣都下不贏它。仔細想想,大概也理解其中的原因。這套遊戲應該是以 Windows 98 Pentium Ⅱ 的環境作基礎寫的,其棋力高低是以限電腦思考幾秒為準,入門級五秒,簡單級十秒。然而, Pentium Ⅱ 的五秒,和我現在 AMD K7 的五秒,是完全不一樣的兩回事。 Pentium Ⅱ 上要思考三十分鐘的高級計算,跑在 AMD K7 上不需要到一秒吧。所以在我的 AMD K7 上不管限幾秒,電腦計算能達到的複雜度,像我這樣初級的人,都沒有勝算。

    + +

    我覺得橘中秘這個名字很有趣。為什麼象棋棋譜取名橘中秘呢?我查了一下,發現其典故來自唐牛僧孺的誌怪小說玄怪錄第三卷中的巴邛人

    + +
    +

    有巴邛人,不知姓名,家有橘園。因霜後,諸橘盡收,餘有兩大橘,如三斗盎。巴人異之,即令攀摘,輕重亦如常橘。剖開,每橘有二老叟,鬢眉皤然,肌體紅潤,皆相對象戲,身長尺餘,談笑自若,剖開後亦不驚怖,但相與決賭。

    + +

    決賭訖,一叟曰:君輸我海上龍王第七女髲髮十兩,智瓊額黃十二枝,紫絹帔一副,絳臺山霞寶散二庾,瀛洲玉塵九斛,阿母療髓凝酒四鍾,阿母女態盈娘子躋虛龍縞襪八緉,後日於王先生青城草堂還我耳。

    + +

    又有一叟曰:王先生許來,竟待不得,橘中之樂,不減商山,但不得深根固蒂,為愚人摘下耳。

    + +

    又一叟曰:僕饑矣,須龍根脯食之。即於袖中抽出一草根,方圓徑寸,形狀宛轉如龍,毫釐罔不周悉,因削食之,隨削隨滿。

    + +

    食訖,以水噀之,化為一龍,四叟共乘之,足下泄泄雲起。須臾,風雨晦冥,不知所在。

    +

    巴人相傳云:百五十年來如此,似在陳隋之間,但不知的年號耳。

    +
    + +

    後人便把橘中之樂作為象棋的雅稱。橘中秘自然就是指象棋的玄機道理了。

    + +

    原來還有這麼有趣的典故。橘中秘梅花譜並稱是最重要的兩本象棋棋譜。明代的橘中秘很強調當頭炮的重要,詳細分析了當頭炮各種的攻殺法;而後來的清代梅花譜,則以屏風馬來對當頭炮,詳列了許多以屏風馬剋制當頭炮,以守為攻的勝法。這些都對後世影響很深遠。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 108 | + 109 | + 110 | + 111 | + 112 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0111.html.en.html b/htdocs/imacat/me/diary/0111.html.en.html new file mode 120000 index 0000000..b71b2ed --- /dev/null +++ b/htdocs/imacat/me/diary/0111.html.en.html @@ -0,0 +1 @@ +0111.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0111.html.en.xhtml b/htdocs/imacat/me/diary/0111.html.en.xhtml new file mode 100644 index 0000000..06477a7 --- /dev/null +++ b/htdocs/imacat/me/diary/0111.html.en.xhtml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 111 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 111

    + +
    + +
    + +
    +
    3.31.’07. 1:03am.
    + +

    新版 Locale::Maketext::Gettextvsntp

    + +

    一個星期趕出兩個新版程式,累死我了。

    + +

    Locale::Maketext::Gettext 是因為 Andreas J. König 於去年十二月 (2006-12-16) 回報了一個Locale::Maketext::Gettext 試車測試失敗報告Locale::Maketext::Gettext 上次更新版已經是兩年前的事了,這兩年都沒有問題,突然出現問題,讓我有點訝異。不過那時候忙案子和空大期中期末考,也沒有時間馬上看。這一陣子準備考研究所,唸書唸著唸著有點無聊,隨便看看,發現原來是 Perl 測試版 5.9.5 上的測試, Perl 測試版上的 Locale::Maketext 的錯誤訊息有點異動,導致試車測試組,抓不到該有的錯誤訊息。可是我本來只想在 Perl 正式版下測,根本沒想到要放到 Perl 測試版下測。考完最後一所中央後,我馬上就開始看。才發現原來 Locale::Maketext 一開始就有相當不錯的錯誤處理系統,我一直都不知道,還自己從頭搞一套錯誤處理系統,結果反而破壞了 Locale::Maketext 原有的錯誤處理系統。我馬上重寫,套用 Locale::Maketext 的錯誤處理系統來處理。再把編碼問題整理清楚,修正幾個試車測試組本身的問題,大約花了三天,發行了新版。這點,謝謝 Andreas J. König 協助測試。

    + +

    看信箱地址, Andreas J. König 應該是德國人吧?在 Google 上搜尋了 Andreas J. König ,他好像蠻了不起的。 ^^;

    + +

    vsntp 則是起源於,當我正忙著重寫 Locale::Maketext::Gettext 時, Jean-Alain Le Borgne 於星期一 (2007-03-26) 寄來了一封信,裏面附上vsntp 1.1.1 版問題的檢測說明,和一個修正檔。唔,真的很謝謝,不過也讓我蠻不好意思的。 ^^; 我知道 vsntp 好像有點問題,麥特‧陳在去年四月曾經來信問過,我那時想到 vsntp 好像沒有記多少偵錯訊息,除非出新版才有可能找出問題,加上我因為自己跑得非常順,實在想不出會有什麼問題,我在忙空大的課業,實在沒有心力為了不知道是什麼問題的問題出新版,就一直擱著。 Jean-Alain Le Borgne 信上面提到了在 MS Virtual PC 2007 上,虛擬電腦暫停一段時間後恢復, sleep() 呼叫會無法復原,導致不再繼續校時的問題,並附上了加上 alarm() 定時替代方案的修正檔。唔,前面我看得懂。不過 alarm() 是什麼? ^^; 我本來 C 就不好,看到這樣的信,更覺得汗顏。竟然要讓一位看起來像 C 的專家的人,幫我這個肉腳的作者寫修正檔。忙完了 Locale::Maketext::Gettext ,馬上又投入去看他的修正檔。反覆看了不知道幾遍,參閱了好多資料、說明文件,又自己寫了幾個小程式測試,才逐漸看懂。原來 alarm() 計時是這樣子做的啊!也算是學了一課。我又把 vsntp 的程式碼挖出來,加上 alarm() 的計時器,以作為替代選擇,並加上該加上的偵錯訊息,並附上兩個啟動程式,然後出新版。新版的說明中,我特別提到是由 Jean-Alain Le Borgne 貢獻的修正程式改寫的。不過其實不是。是我自己實驗熟了 alarm() 後,從頭重寫的。這點看程式碼就知道了。可是我不好意思說我沒有用到他的貢獻。不過若沒有他,我也不知道要用 alarm() ,也學不到這些,我不用 MS Virtual PC 2007 ,也不會暫停虛擬電腦,更不可能抓出 sleep() 呼叫可能無法復原的錯誤問題。無論如何,感謝他總是應該的。 ^_*'

    + +

    大略看了一下 Jean-Alain Le Borgne 的網站 ,在 Google 上搜尋了 Jean-Alain Le Borgne ,他是法國人,好像在巴黎第八大學當研究助理,好像也是個很了不起的人。真的是好可怕啊~

    + +

    就這樣,一個星期替兩個程式出新版,研究所考完了也沒得休息,真是累死我了。 ~^ ^~

    + +

    怎麼會短短時間內,跟了不起的德國人和法國人扯上關係呢?唔唔。 ^^; 奇妙的緣份。

    + +

    如果他們反過來在 Google 上搜尋 imacat ,不知道會不會也覺得很可怕? ^^; 唔…

    + +

    前一陣子準備考研究所,唸書唸到無聊,把之前每天跑 CPAN 模組試車測試,出問題到系統當掉,無法回報錯誤,又沒空詳查的套件,又一個一個抓出來,確認問題點,然後上 CPAN 流程系統回報。加上在更新 Locale::Maketext::Gettext 時發現 Locale::Maketext 的問題,也都上去回報。短短幾天內,一口氣在 CPAN 流程系統上回報了十幾個問題。不知道會不會把 CPAN 流程系統淹掉。在人家眼中看來,我大概也很可怕吧~ ^^;

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 109 | + 110 | + 111 | + 112 | + 113 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0111.html.zh-cn.html b/htdocs/imacat/me/diary/0111.html.zh-cn.html new file mode 120000 index 0000000..b0870c8 --- /dev/null +++ b/htdocs/imacat/me/diary/0111.html.zh-cn.html @@ -0,0 +1 @@ +0111.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0111.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0111.html.zh-cn.xhtml new file mode 100644 index 0000000..8890ec5 --- /dev/null +++ b/htdocs/imacat/me/diary/0111.html.zh-cn.xhtml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百一十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百一十一

    + +
    + +
    + +
    +
    3.31.’07. 1:03am.
    + +

    新版 Locale::Maketext::Gettextvsntp

    + +

    一个星期赶出两个新版程式,累死我了。

    + +

    Locale::Maketext::Gettext 是因为 Andreas J. König 於去年十二月 (2006-12-16) 回报了一个Locale::Maketext::Gettext 试车测试失败报告Locale::Maketext::Gettext 上次更新版已经是两年前的事了,这两年都没有问题,突然出现问题,让我有点讶异。不过那时候忙案子和空大期中期末考,也没有时间马上看。这一阵子准备考研究所,念书念著念著有点无聊,随便看看,发现原来是 Perl 测试版 5.9.5 上的测试, Perl 测试版上的 Locale::Maketext 的错误讯息有点异动,导致试车测试组,抓不到该有的错误讯息。可是我本来只想在 Perl 正式版下测,根本没想到要放到 Perl 测试版下测。考完最后一所中央后,我马上就开始看。才发现原来 Locale::Maketext 一开始就有相当不错的错误处理系统,我一直都不知道,还自己从头搞一套错误处理系统,结果反而破坏了 Locale::Maketext 原有的错误处理系统。我马上重写,套用 Locale::Maketext 的错误处理系统来处理。再把编码问题整理清楚,修正几个试车测试组本身的问题,大约花了三天,发行了新版。这点,谢谢 Andreas J. König 协助测试。

    + +

    看信箱地址, Andreas J. König 应该是德国人吧?在 Google 上搜寻了 Andreas J. König ,他好像蛮了不起的。 ^^;

    + +

    vsntp 则是起源於,当我正忙著重写 Locale::Maketext::Gettext 时, Jean-Alain Le Borgne 於星期一 (2007-03-26) 寄来了一封信,里面附上vsntp 1.1.1 版问题的检测说明,和一个修正档。唔,真的很谢谢,不过也让我蛮不好意思的。 ^^; 我知道 vsntp 好像有点问题,麦特・陈在去年四月曾经来信问过,我那时想到 vsntp 好像没有记多少侦错讯息,除非出新版才有可能找出问题,加上我因为自己跑得非常顺,实在想不出会有什么问题,我在忙空大的课业,实在没有心力为了不知道是什么问题的问题出新版,就一直搁著。 Jean-Alain Le Borgne 信上面提到了在 MS Virtual PC 2007 上,虚拟电脑暂停一段时间后恢复, sleep() 呼叫会无法复原,导致不再继续校时的问题,并附上了加上 alarm() 定时替代方案的修正档。唔,前面我看得懂。不过 alarm() 是什么? ^^; 我本来 C 就不好,看到这样的信,更觉得汗颜。竟然要让一位看起来像 C 的专家的人,帮我这个肉脚的作者写修正档。忙完了 Locale::Maketext::Gettext ,马上又投入去看他的修正档。反覆看了不知道几遍,参阅了好多资料、说明文件,又自己写了几个小程式测试,才逐渐看懂。原来 alarm() 计时是这样子做的啊!也算是学了一课。我又把 vsntp 的程式码挖出来,加上 alarm() 的计时器,以作为替代选择,并加上该加上的侦错讯息,并附上两个启动程式,然后出新版。新版的说明中,我特别提到是由 Jean-Alain Le Borgne 贡献的修正程式改写的。不过其实不是。是我自己实验熟了 alarm() 后,从头重写的。这点看程式码就知道了。可是我不好意思说我没有用到他的贡献。不过若没有他,我也不知道要用 alarm() ,也学不到这些,我不用 MS Virtual PC 2007 ,也不会暂停虚拟电脑,更不可能抓出 sleep() 呼叫可能无法复原的错误问题。无论如何,感谢他总是应该的。 ^_*'

    + +

    大略看了一下 Jean-Alain Le Borgne 的网站 ,在 Google 上搜寻了 Jean-Alain Le Borgne ,他是法国人,好像在巴黎第八大学当研究助理,好像也是个很了不起的人。真的是好可怕啊~

    + +

    就这样,一个星期替两个程式出新版,研究所考完了也没得休息,真是累死我了。 ~^ ^~

    + +

    怎么会短短时间内,跟了不起的德国人和法国人扯上关系呢?唔唔。 ^^; 奇妙的缘份。

    + +

    如果他们反过来在 Google 上搜寻 imacat ,不知道会不会也觉得很可怕? ^^; 唔…

    + +

    前一阵子准备考研究所,念书念到无聊,把之前每天跑 CPAN 模组试车测试,出问题到系统当掉,无法回报错误,又没空详查的套件,又一个一个抓出来,确认问题点,然后上 CPAN 流程系统回报。加上在更新 Locale::Maketext::Gettext 时发现 Locale::Maketext 的问题,也都上去回报。短短几天内,一口气在 CPAN 流程系统上回报了十几个问题。不知道会不会把 CPAN 流程系统淹掉。在人家眼中看来,我大概也很可怕吧~ ^^;

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 109 | + 110 | + 111 | + 112 | + 113 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0111.html.zh-tw.html b/htdocs/imacat/me/diary/0111.html.zh-tw.html new file mode 120000 index 0000000..6c47bb7 --- /dev/null +++ b/htdocs/imacat/me/diary/0111.html.zh-tw.html @@ -0,0 +1 @@ +0111.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0111.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0111.html.zh-tw.xhtml new file mode 100644 index 0000000..f8ef9cc --- /dev/null +++ b/htdocs/imacat/me/diary/0111.html.zh-tw.xhtml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百一十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百一十一

    + +
    + +
    + +
    +
    3.31.’07. 1:03am.
    + +

    新版 Locale::Maketext::Gettextvsntp

    + +

    一個星期趕出兩個新版程式,累死我了。

    + +

    Locale::Maketext::Gettext 是因為 Andreas J. König 於去年十二月 (2006-12-16) 回報了一個Locale::Maketext::Gettext 試車測試失敗報告Locale::Maketext::Gettext 上次更新版已經是兩年前的事了,這兩年都沒有問題,突然出現問題,讓我有點訝異。不過那時候忙案子和空大期中期末考,也沒有時間馬上看。這一陣子準備考研究所,唸書唸著唸著有點無聊,隨便看看,發現原來是 Perl 測試版 5.9.5 上的測試, Perl 測試版上的 Locale::Maketext 的錯誤訊息有點異動,導致試車測試組,抓不到該有的錯誤訊息。可是我本來只想在 Perl 正式版下測,根本沒想到要放到 Perl 測試版下測。考完最後一所中央後,我馬上就開始看。才發現原來 Locale::Maketext 一開始就有相當不錯的錯誤處理系統,我一直都不知道,還自己從頭搞一套錯誤處理系統,結果反而破壞了 Locale::Maketext 原有的錯誤處理系統。我馬上重寫,套用 Locale::Maketext 的錯誤處理系統來處理。再把編碼問題整理清楚,修正幾個試車測試組本身的問題,大約花了三天,發行了新版。這點,謝謝 Andreas J. König 協助測試。

    + +

    看信箱地址, Andreas J. König 應該是德國人吧?在 Google 上搜尋了 Andreas J. König ,他好像蠻了不起的。 ^^;

    + +

    vsntp 則是起源於,當我正忙著重寫 Locale::Maketext::Gettext 時, Jean-Alain Le Borgne 於星期一 (2007-03-26) 寄來了一封信,裏面附上vsntp 1.1.1 版問題的檢測說明,和一個修正檔。唔,真的很謝謝,不過也讓我蠻不好意思的。 ^^; 我知道 vsntp 好像有點問題,麥特‧陳在去年四月曾經來信問過,我那時想到 vsntp 好像沒有記多少偵錯訊息,除非出新版才有可能找出問題,加上我因為自己跑得非常順,實在想不出會有什麼問題,我在忙空大的課業,實在沒有心力為了不知道是什麼問題的問題出新版,就一直擱著。 Jean-Alain Le Borgne 信上面提到了在 MS Virtual PC 2007 上,虛擬電腦暫停一段時間後恢復, sleep() 呼叫會無法復原,導致不再繼續校時的問題,並附上了加上 alarm() 定時替代方案的修正檔。唔,前面我看得懂。不過 alarm() 是什麼? ^^; 我本來 C 就不好,看到這樣的信,更覺得汗顏。竟然要讓一位看起來像 C 的專家的人,幫我這個肉腳的作者寫修正檔。忙完了 Locale::Maketext::Gettext ,馬上又投入去看他的修正檔。反覆看了不知道幾遍,參閱了好多資料、說明文件,又自己寫了幾個小程式測試,才逐漸看懂。原來 alarm() 計時是這樣子做的啊!也算是學了一課。我又把 vsntp 的程式碼挖出來,加上 alarm() 的計時器,以作為替代選擇,並加上該加上的偵錯訊息,並附上兩個啟動程式,然後出新版。新版的說明中,我特別提到是由 Jean-Alain Le Borgne 貢獻的修正程式改寫的。不過其實不是。是我自己實驗熟了 alarm() 後,從頭重寫的。這點看程式碼就知道了。可是我不好意思說我沒有用到他的貢獻。不過若沒有他,我也不知道要用 alarm() ,也學不到這些,我不用 MS Virtual PC 2007 ,也不會暫停虛擬電腦,更不可能抓出 sleep() 呼叫可能無法復原的錯誤問題。無論如何,感謝他總是應該的。 ^_*'

    + +

    大略看了一下 Jean-Alain Le Borgne 的網站 ,在 Google 上搜尋了 Jean-Alain Le Borgne ,他是法國人,好像在巴黎第八大學當研究助理,好像也是個很了不起的人。真的是好可怕啊~

    + +

    就這樣,一個星期替兩個程式出新版,研究所考完了也沒得休息,真是累死我了。 ~^ ^~

    + +

    怎麼會短短時間內,跟了不起的德國人和法國人扯上關係呢?唔唔。 ^^; 奇妙的緣份。

    + +

    如果他們反過來在 Google 上搜尋 imacat ,不知道會不會也覺得很可怕? ^^; 唔…

    + +

    前一陣子準備考研究所,唸書唸到無聊,把之前每天跑 CPAN 模組試車測試,出問題到系統當掉,無法回報錯誤,又沒空詳查的套件,又一個一個抓出來,確認問題點,然後上 CPAN 流程系統回報。加上在更新 Locale::Maketext::Gettext 時發現 Locale::Maketext 的問題,也都上去回報。短短幾天內,一口氣在 CPAN 流程系統上回報了十幾個問題。不知道會不會把 CPAN 流程系統淹掉。在人家眼中看來,我大概也很可怕吧~ ^^;

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 109 | + 110 | + 111 | + 112 | + 113 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0112.html.en.html b/htdocs/imacat/me/diary/0112.html.en.html new file mode 120000 index 0000000..4e59774 --- /dev/null +++ b/htdocs/imacat/me/diary/0112.html.en.html @@ -0,0 +1 @@ +0112.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0112.html.en.xhtml b/htdocs/imacat/me/diary/0112.html.en.xhtml new file mode 100644 index 0000000..ffea47b --- /dev/null +++ b/htdocs/imacat/me/diary/0112.html.en.xhtml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 112 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 112

    + +
    + +
    + +
    +
    5.24.’07. 4:38pm.
    + +

    NANA ナナ 17 和尼羅河女兒

    + +

    今天去漫畫店,終於看到期待已久的 NANA ナナ 17 。矢沢あい的漫畫畫得很快,真是讓人欣慰。身為一個讀者,最大的願望,就是作者畫得很快,單行本一直出一直出,而且還能一直保持高水準。不過這兩者往往不可兼得。畫得快的,往往畫到後來越來爛,像高橋留美子的犬夜叉、鳥山明的七龍珠、青山剛昌的名偵探柯南,都是這樣,一開始畫得很好,但到後來越畫越爛,單行本雖然還是出得很快,但讓人越來越不想看。

    + +

    矢沢あい不愧為少女漫畫之王,畫得這麼快,每一集都還一樣好看,真是讀者心中的優良典範。不過要達到這個要求,就要苦了漫畫家了。 ^^; 呵呵~像矢沢あい這麼有地位,賣得這麼好的漫畫家,大概助理群陣容也非常堅強吧~

    + +

    看了 NANA ナナ 17 ,真是開心,鬆了一口氣。看來, 大崎ナナ結局不會死,只是失蹤了而已,而且還可能找得到。真是讓人期待呢~

    + +

    今天還看到另一本令人驚異的單行本:細川智栄子王家の紋章(尼羅河女兒)第五十集。天哪~尼羅河女兒耶!我小時候的年代的漫畫,竟然還在連載。真是太厲害了,呵呵~

    + +
    + +
    + +
    +
    4.2.’07. 0:50am.
    + +

    coLinux

    + +

    前兩天因故登入 Google ,發現我的 Gmail 信箱積了七、八封新聞快遞。我等 Debian Etch 發行已經等很久了(快一年了吧),想早點知道 Debian Etch 的最新狀況,所以訂了 Google 新聞快遞。不過馬上就忘了這件事。 ^^; 而且它是投到我的 Gmail 信箱,可是我沒有在用 Gmail 。不過既然新聞來了,我就一條一條去看看。大多都是安全通報。不過有一條 SuSELinux integrates SWsoft virtualisation 引起我的注意。內容和 Debian Etch 沒有直接關係,是說 Novell 的 SuSE Linux Enterprise Server ,要搭配 SWSoft 的商業虛擬電腦軟體 Virtuozzo 。該則新聞並指出, Debian Etch Etch 、 RHEL 5 、 Solaris 10 也有另一套虛擬電腦軟體 Xen

    + +

    虛擬電腦。唔。我還在用 Connectix Virtual PC ,雖然賣給微軟已經併購 Connectix 多年了。不過我還是習慣用 Connectix 時代的 Virtual PC ,跑起 Linux 比較穩。我也為了它寫了一個 vsntp 校時程式。不過終究是老程式了,難保不會出問題,像是安全漏洞,或是和日後的系統不相容等等。可是虛擬電腦我只知道 Virtual PC 和 VMWare 。 Virtuozzo 又是什麼?

    + +

    基於好奇,我上去查了查 Virtuozzo ,及其它虛擬電腦的資料。沒想到發現還蠻多的。我在 Wikipedia 上發現一長串虛擬電腦軟體總表。原來世界上還有這麼多種虛擬電腦!我都不知道。還依虛擬的層次,分成:硬體層次虛擬、作業系統層次虛擬、應用軟體層次虛擬。唔。硬體層次虛擬是最完整的,可以跑各種作業系統,可是效能也最低。沒錯, Virtual PC 跑起來真是慢得離譜,每次應用軟體昇級,我都搞得快瘋了。

    + +

    我開始看看其它解決方案。有一條引起了我的好奇: coLinux 。它是直接在 Windows 上跑 Linux 核心。因為 coLinux 沒有虛擬所有硬體,而是讓 Linux 核心直接和 Windows 共用硬體,所以效能快很多。

    + +

    唔。好像就是我的問題的答案。其實 Virtual PC 平常做實驗,跑各種作業系統還是很好用。可是日常在跑的備份伺服器就是一定是 Linux ,也不是別的。如果可以省下不需要的虛擬硬體,搞不好可以讓效能加速。

    + +

    於是我下載了下來,花了兩天的時間測試。還真的很酷。安裝蠻容易的。我現在暫時用 coLinux 代替原來 Virtual PC 跑。有一點不穩。網路上傳大量資料時會當,無法安裝為服務執行,不知道為什麼。不過其它方面都還好。速度上,主電腦和虛擬電腦都快很多。之前做什麼事,就會兩邊的慢得半死的問題,好像就解決了。而且因為共用主電腦的硬體時鐘,所以不需要 vsntp 校時,主電腦上校時即可,時間也沒有問題。真好,呵呵。 ^_*'

    + +

    可是這樣,我好像就沒有理由繼續維護 vsntp 了。唔。怎麼辦? ^^;

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 110 | + 111 | + 112 | + 113 | + 114 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0112.html.zh-cn.html b/htdocs/imacat/me/diary/0112.html.zh-cn.html new file mode 120000 index 0000000..67f68bd --- /dev/null +++ b/htdocs/imacat/me/diary/0112.html.zh-cn.html @@ -0,0 +1 @@ +0112.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0112.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0112.html.zh-cn.xhtml new file mode 100644 index 0000000..a23044b --- /dev/null +++ b/htdocs/imacat/me/diary/0112.html.zh-cn.xhtml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百一十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百一十二

    + +
    + +
    + +
    +
    5.24.’07. 4:38pm.
    + +

    NANA ナナ 17 和尼罗河女儿

    + +

    今天去漫画店,终於看到期待已久的 NANA ナナ 17 。矢沢あい的漫画画得很快,真是让人欣慰。身为一个读者,最大的愿望,就是作者画得很快,单行本一直出一直出,而且还能一直保持高水准。不过这两者往往不可兼得。画得快的,往往画到后来越来烂,像高桥留美子的犬夜叉、鸟山明的七龙珠、青山刚昌的名侦探柯南,都是这样,一开始画得很好,但到后来越画越烂,单行本虽然还是出得很快,但让人越来越不想看。

    + +

    矢沢あい不愧为少女漫画之王,画得这么快,每一集都还一样好看,真是读者心中的优良典范。不过要达到这个要求,就要苦了漫画家了。 ^^; 呵呵~像矢沢あい这么有地位,卖得这么好的漫画家,大概助理群阵容也非常坚强吧~

    + +

    看了 NANA ナナ 17 ,真是开心,松了一口气。看来, 大崎ナナ结局不会死,只是失踪了而已,而且还可能找得到。真是让人期待呢~

    + +

    今天还看到另一本令人惊异的单行本:细川智栄子王家の纹章(尼罗河女儿)第五十集。天哪~尼罗河女儿耶!我小时候的年代的漫画,竟然还在连载。真是太厉害了,呵呵~

    + +
    + +
    + +
    +
    4.2.’07. 0:50am.
    + +

    coLinux

    + +

    前两天因故登入 Google ,发现我的 Gmail 信箱积了七、八封新闻快递。我等 Debian Etch 发行已经等很久了(快一年了吧),想早点知道 Debian Etch 的最新状况,所以订了 Google 新闻快递。不过马上就忘了这件事。 ^^; 而且它是投到我的 Gmail 信箱,可是我没有在用 Gmail 。不过既然新闻来了,我就一条一条去看看。大多都是安全通报。不过有一条 SuSELinux integrates SWsoft virtualisation 引起我的注意。内容和 Debian Etch 没有直接关系,是说 Novell 的 SuSE Linux Enterprise Server ,要搭配 SWSoft 的商业虚拟电脑软体 Virtuozzo 。该则新闻并指出, Debian Etch Etch 、 RHEL 5 、 Solaris 10 也有另一套虚拟电脑软体 Xen

    + +

    虚拟电脑。唔。我还在用 Connectix Virtual PC ,虽然卖给微软已经并购 Connectix 多年了。不过我还是习惯用 Connectix 时代的 Virtual PC ,跑起 Linux 比较稳。我也为了它写了一个 vsntp 校时程式。不过终究是老程式了,难保不会出问题,像是安全漏洞,或是和日后的系统不相容等等。可是虚拟电脑我只知道 Virtual PC 和 VMWare 。 Virtuozzo 又是什么?

    + +

    基於好奇,我上去查了查 Virtuozzo ,及其它虚拟电脑的资料。没想到发现还蛮多的。我在 Wikipedia 上发现一长串虚拟电脑软体总表。原来世界上还有这么多种虚拟电脑!我都不知道。还依虚拟的层次,分成:硬体层次虚拟、作业系统层次虚拟、应用软体层次虚拟。唔。硬体层次虚拟是最完整的,可以跑各种作业系统,可是效能也最低。没错, Virtual PC 跑起来真是慢得离谱,每次应用软体升级,我都搞得快疯了。

    + +

    我开始看看其它解决方案。有一条引起了我的好奇: coLinux 。它是直接在 Windows 上跑 Linux 核心。因为 coLinux 没有虚拟所有硬体,而是让 Linux 核心直接和 Windows 共用硬体,所以效能快很多。

    + +

    唔。好像就是我的问题的答案。其实 Virtual PC 平常做实验,跑各种作业系统还是很好用。可是日常在跑的备份伺服器就是一定是 Linux ,也不是别的。如果可以省下不需要的虚拟硬体,搞不好可以让效能加速。

    + +

    於是我下载了下来,花了两天的时间测试。还真的很酷。安装蛮容易的。我现在暂时用 coLinux 代替原来 Virtual PC 跑。有一点不稳。网路上传大量资料时会当,无法安装为服务执行,不知道为什么。不过其它方面都还好。速度上,主电脑和虚拟电脑都快很多。之前做什么事,就会两边的慢得半死的问题,好像就解决了。而且因为共用主电脑的硬体时钟,所以不需要 vsntp 校时,主电脑上校时即可,时间也没有问题。真好,呵呵。 ^_*'

    + +

    可是这样,我好像就没有理由继续维护 vsntp 了。唔。怎么办? ^^;

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 110 | + 111 | + 112 | + 113 | + 114 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0112.html.zh-tw.html b/htdocs/imacat/me/diary/0112.html.zh-tw.html new file mode 120000 index 0000000..0aff83e --- /dev/null +++ b/htdocs/imacat/me/diary/0112.html.zh-tw.html @@ -0,0 +1 @@ +0112.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0112.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0112.html.zh-tw.xhtml new file mode 100644 index 0000000..89aa07c --- /dev/null +++ b/htdocs/imacat/me/diary/0112.html.zh-tw.xhtml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百一十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百一十二

    + +
    + +
    + +
    +
    5.24.’07. 4:38pm.
    + +

    NANA ナナ 17 和尼羅河女兒

    + +

    今天去漫畫店,終於看到期待已久的 NANA ナナ 17 。矢沢あい的漫畫畫得很快,真是讓人欣慰。身為一個讀者,最大的願望,就是作者畫得很快,單行本一直出一直出,而且還能一直保持高水準。不過這兩者往往不可兼得。畫得快的,往往畫到後來越來爛,像高橋留美子的犬夜叉、鳥山明的七龍珠、青山剛昌的名偵探柯南,都是這樣,一開始畫得很好,但到後來越畫越爛,單行本雖然還是出得很快,但讓人越來越不想看。

    + +

    矢沢あい不愧為少女漫畫之王,畫得這麼快,每一集都還一樣好看,真是讀者心中的優良典範。不過要達到這個要求,就要苦了漫畫家了。 ^^; 呵呵~像矢沢あい這麼有地位,賣得這麼好的漫畫家,大概助理群陣容也非常堅強吧~

    + +

    看了 NANA ナナ 17 ,真是開心,鬆了一口氣。看來, 大崎ナナ結局不會死,只是失蹤了而已,而且還可能找得到。真是讓人期待呢~

    + +

    今天還看到另一本令人驚異的單行本:細川智栄子王家の紋章(尼羅河女兒)第五十集。天哪~尼羅河女兒耶!我小時候的年代的漫畫,竟然還在連載。真是太厲害了,呵呵~

    + +
    + +
    + +
    +
    4.2.’07. 0:50am.
    + +

    coLinux

    + +

    前兩天因故登入 Google ,發現我的 Gmail 信箱積了七、八封新聞快遞。我等 Debian Etch 發行已經等很久了(快一年了吧),想早點知道 Debian Etch 的最新狀況,所以訂了 Google 新聞快遞。不過馬上就忘了這件事。 ^^; 而且它是投到我的 Gmail 信箱,可是我沒有在用 Gmail 。不過既然新聞來了,我就一條一條去看看。大多都是安全通報。不過有一條 SuSELinux integrates SWsoft virtualisation 引起我的注意。內容和 Debian Etch 沒有直接關係,是說 Novell 的 SuSE Linux Enterprise Server ,要搭配 SWSoft 的商業虛擬電腦軟體 Virtuozzo 。該則新聞並指出, Debian Etch Etch 、 RHEL 5 、 Solaris 10 也有另一套虛擬電腦軟體 Xen

    + +

    虛擬電腦。唔。我還在用 Connectix Virtual PC ,雖然賣給微軟已經併購 Connectix 多年了。不過我還是習慣用 Connectix 時代的 Virtual PC ,跑起 Linux 比較穩。我也為了它寫了一個 vsntp 校時程式。不過終究是老程式了,難保不會出問題,像是安全漏洞,或是和日後的系統不相容等等。可是虛擬電腦我只知道 Virtual PC 和 VMWare 。 Virtuozzo 又是什麼?

    + +

    基於好奇,我上去查了查 Virtuozzo ,及其它虛擬電腦的資料。沒想到發現還蠻多的。我在 Wikipedia 上發現一長串虛擬電腦軟體總表。原來世界上還有這麼多種虛擬電腦!我都不知道。還依虛擬的層次,分成:硬體層次虛擬、作業系統層次虛擬、應用軟體層次虛擬。唔。硬體層次虛擬是最完整的,可以跑各種作業系統,可是效能也最低。沒錯, Virtual PC 跑起來真是慢得離譜,每次應用軟體昇級,我都搞得快瘋了。

    + +

    我開始看看其它解決方案。有一條引起了我的好奇: coLinux 。它是直接在 Windows 上跑 Linux 核心。因為 coLinux 沒有虛擬所有硬體,而是讓 Linux 核心直接和 Windows 共用硬體,所以效能快很多。

    + +

    唔。好像就是我的問題的答案。其實 Virtual PC 平常做實驗,跑各種作業系統還是很好用。可是日常在跑的備份伺服器就是一定是 Linux ,也不是別的。如果可以省下不需要的虛擬硬體,搞不好可以讓效能加速。

    + +

    於是我下載了下來,花了兩天的時間測試。還真的很酷。安裝蠻容易的。我現在暫時用 coLinux 代替原來 Virtual PC 跑。有一點不穩。網路上傳大量資料時會當,無法安裝為服務執行,不知道為什麼。不過其它方面都還好。速度上,主電腦和虛擬電腦都快很多。之前做什麼事,就會兩邊的慢得半死的問題,好像就解決了。而且因為共用主電腦的硬體時鐘,所以不需要 vsntp 校時,主電腦上校時即可,時間也沒有問題。真好,呵呵。 ^_*'

    + +

    可是這樣,我好像就沒有理由繼續維護 vsntp 了。唔。怎麼辦? ^^;

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 110 | + 111 | + 112 | + 113 | + 114 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0113.html.en.html b/htdocs/imacat/me/diary/0113.html.en.html new file mode 120000 index 0000000..06905f2 --- /dev/null +++ b/htdocs/imacat/me/diary/0113.html.en.html @@ -0,0 +1 @@ +0113.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0113.html.en.xhtml b/htdocs/imacat/me/diary/0113.html.en.xhtml new file mode 100644 index 0000000..3effd85 --- /dev/null +++ b/htdocs/imacat/me/diary/0113.html.en.xhtml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 113 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 113

    + +
    + +
    + +
    +
    6.5.’07. 2:37pm.
    + +

    新冷氣日立 RA-25PL 直流變頻冷暖雙吹窗型冷氣

    + +

    從搬來現在住的永和新生地開始,一直都用好心的房東提供的冷氣。那是一款舊型的日立二手冷氣,型號、年代已經不可考了。雖然還蠻可靠的,可是沒有溫控,一開就冷得要死,不開又熱得要死。每次開一陣子關掉,再開,再關。不然就得要開上冷氣加衣服。忽冷忽熱間,還很容易感冒。這幾年手頭緊,根本不敢奢望新冷氣。加上小招一直主張用電扇就好,反對買冷氣,每次講到換冷氣的事就吵架,就不了了之。

    + +

    不過,我還是都有在留意新冷氣的事。現在夏天這麼熱,不可能真的不用冷氣,臺大公館地下道是臺電認捐認養的,平常走動的時候,看到上面宣導的省電小秘方,第一條就是改用變頻冷氣。前一陣子非法節電器鬧上新聞,蘋果去找了臺電的人,問如何省電,也是說要改用變頻冷氣變頻冷氣,雖然還不知道到底是什麼技術,但就一直這樣記在心裏:買新冷氣時,要買變頻冷氣。

    + +

    幾星期前下定決心,下次領到錢就一定要拿來買冷氣。誰知道沒幾天,公司薪水就又補發一部份下來了。和小招大吵一架後,終於決定買冷氣了。

    + +

    要買,就要買省電的變頻冷氣。我第一個想到的是 Panasonic 潘慧如那個動就冷,不動就省動能偵測器的廣告。雖然那個廣告很蠢,害我這個潘慧如的支持者很難過。 :~~ 可是能夠偵測動能,還是讓我評價非常高。

    + +

    我們家有冷氣窗,也沒有陽台可以擺室外機,所以沒辦法裝分離式,只能買窗型。上了臺灣松下 Panasonic 網站看了幾款後,又到冷氣王牌的臺灣日立網站上看了幾款,發現變頻冷氣大多都是分離式,很少窗型。而日立窗型變頻冷氣,只有一款 RA-25PL 直流變頻冷暖雙吹窗型冷氣。我一看就很喜歡。倒不是因為它的外型,而是它的 EER 高達 3.37 ,業界第一。我依稀記得臺電省電宣導也有提到,改用變頻冷氣, EER 值越高越省電。比較了幾個品牌, Panasonic 的 EER 只有 2.77 , LG 的 EER 最高也只有 3.27 ,日立 EER 3.37 的確是無人能比。加上日立的專利技術渦卷式壓縮機,又比傳統迴轉式壓縮機效能高。比較之後,雖然沒有潘小如的動就冷,不動就省動能偵測器,我還是決定買日立了,比較省電比較環保。

    + +

    確定機型了以後,再上網找有買的商家。可能是我比較傳統吧,不喜歡完全做網路的商家,總覺得沒有保障。我喜歡傳統商家上網刊登型錄,有興趣的話再約去店裏看貨的那種,要實際看到貨的實際狀況,是不是全新品,有沒有刮傷,才能安心買下來,沒辦法單憑型錄、價錢,就叫人家送過來,等到不滿意再退貨或是上網罵。所以 PayEasy 雖然也有賣冷氣,價格也不錯,可是我還是不想跟 PayEasy 買。我搞不懂那些給負評的人:沒看到貨,你們怎麼敢決定買下來呢?沒實際看到的東西,買了以後出問題也不意外。 PayEasy 是不應該出錯,不過消費者一開始就不應該這樣買東西吧?沒見到面,甚至沒通過電話,怎麼把購買的細節溝通清楚呢?真是太奇怪了。

    + +

    看了幾家,一家一家打電話去問。我發現日立 RA-25PL 缺貨缺得很嚴重,四月底第一批貨上市,一下子就斷市,被搶光了,從五月到現在都完全沒貨,日立工廠還在趕工,下一批要六月底以後才生產得出來。不管是 BEST 、全國電子、燦坤、上新聯晴,還是傳統家電行,通通缺貨。我一家一家問,甚至問到高雄、屏東,問到半夜,幾乎絕望了,想說乾脆跟一家有貨的高雄電器行訂,請他們送上來,或是認命等月底算了。

    + +

    就在清晨四點半,我正要絕望時,看到一家新邵電器行好像有現貨。再看看地址:永和永貞路。那不就在家裏附近嗎?真是太好了。價錢也差不多中等價位。可是那時候是周六夜,周日清晨,新邵周日休息。天哪~那我怎麼確認呢?而且好像很多人問說,要是被別人買走怎麼辦?還好網站有留手機。我記下手機,星期天開始死命叩,務必要老闆幫我留下一台。叩到下午,終於接聽了。有現貨! Yes! 。確定價錢 26800 + 安裝費 1200 + 拆舊機 300 = 27300 後,趕緊跟老闆約好星期一早上看冷氣,晚上安裝。

    + +

    昨天晚上,兩個小師傅把冷氣送過來,汗流夾背地裝好。看著他們辛苦施工,又幫我們把舊冷氣,按房東說的,辛苦扛上六樓,覺得他們好厲害。現在的小鬼也有很拼的呢~裝上去以後,開了機,設定 27 °C 。哇~真舒服。 27 °C 果然是最舒服的~新的省電變頻冷氣,真好~ *^_^*

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 111 | + 112 | + 113 | + 114 | + 115 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0113.html.zh-cn.html b/htdocs/imacat/me/diary/0113.html.zh-cn.html new file mode 120000 index 0000000..69955ab --- /dev/null +++ b/htdocs/imacat/me/diary/0113.html.zh-cn.html @@ -0,0 +1 @@ +0113.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0113.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0113.html.zh-cn.xhtml new file mode 100644 index 0000000..dac6738 --- /dev/null +++ b/htdocs/imacat/me/diary/0113.html.zh-cn.xhtml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百一十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百一十三

    + +
    + +
    + +
    +
    6.5.’07. 2:37pm.
    + +

    新冷气日立 RA-25PL 直流变频冷暖双吹窗型冷气

    + +

    从搬来现在住的永和新生地开始,一直都用好心的房东提供的冷气。那是一款旧型的日立二手冷气,型号、年代已经不可考了。虽然还蛮可靠的,可是没有温控,一开就冷得要死,不开又热得要死。每次开一阵子关掉,再开,再关。不然就得要开上冷气加衣服。忽冷忽热间,还很容易感冒。这几年手头紧,根本不敢奢望新冷气。加上小招一直主张用电扇就好,反对买冷气,每次讲到换冷气的事就吵架,就不了了之。

    + +

    不过,我还是都有在留意新冷气的事。现在夏天这么热,不可能真的不用冷气,台大公馆地下道是台电认捐认养的,平常走动的时候,看到上面宣导的省电小秘方,第一条就是改用变频冷气。前一阵子非法节电器闹上新闻,苹果去找了台电的人,问如何省电,也是说要改用变频冷气变频冷气,虽然还不知道到底是什么技术,但就一直这样记在心里:买新冷气时,要买变频冷气。

    + +

    几星期前下定决心,下次领到钱就一定要拿来买冷气。谁知道没几天,公司薪水就又补发一部份下来了。和小招大吵一架后,终於决定买冷气了。

    + +

    要买,就要买省电的变频冷气。我第一个想到的是 Panasonic 潘慧如那个动就冷,不动就省动能侦测器的广告。虽然那个广告很蠢,害我这个潘慧如的支持者很难过。 :~~ 可是能够侦测动能,还是让我评价非常高。

    + +

    我们家有冷气窗,也没有阳台可以摆室外机,所以没办法装分离式,只能买窗型。上了台湾松下 Panasonic 网站看了几款后,又到冷气王牌的台湾日立网站上看了几款,发现变频冷气大多都是分离式,很少窗型。而日立窗型变频冷气,只有一款 RA-25PL 直流变频冷暖双吹窗型冷气。我一看就很喜欢。倒不是因为它的外型,而是它的 EER 高达 3.37 ,业界第一。我依稀记得台电省电宣导也有提到,改用变频冷气, EER 值越高越省电。比较了几个品牌, Panasonic 的 EER 只有 2.77 , LG 的 EER 最高也只有 3.27 ,日立 EER 3.37 的确是无人能比。加上日立的专利技术涡卷式压缩机,又比传统回转式压缩机效能高。比较之后,虽然没有潘小如的动就冷,不动就省动能侦测器,我还是决定买日立了,比较省电比较环保。

    + +

    确定机型了以后,再上网找有买的商家。可能是我比较传统吧,不喜欢完全做网路的商家,总觉得没有保障。我喜欢传统商家上网刊登型录,有兴趣的话再约去店里看货的那种,要实际看到货的实际状况,是不是全新品,有没有刮伤,才能安心买下来,没办法单凭型录、价钱,就叫人家送过来,等到不满意再退货或是上网骂。所以 PayEasy 虽然也有卖冷气,价格也不错,可是我还是不想跟 PayEasy 买。我搞不懂那些给负评的人:没看到货,你们怎么敢决定买下来呢?没实际看到的东西,买了以后出问题也不意外。 PayEasy 是不应该出错,不过消费者一开始就不应该这样买东西吧?没见到面,甚至没通过电话,怎么把购买的细节沟通清楚呢?真是太奇怪了。

    + +

    看了几家,一家一家打电话去问。我发现日立 RA-25PL 缺货缺得很严重,四月底第一批货上市,一下子就断市,被抢光了,从五月到现在都完全没货,日立工厂还在赶工,下一批要六月底以后才生产得出来。不管是 BEST 、全国电子、灿坤、上新联晴,还是传统家电行,通通缺货。我一家一家问,甚至问到高雄、屏东,问到半夜,几乎绝望了,想说干脆跟一家有货的高雄电器行订,请他们送上来,或是认命等月底算了。

    + +

    就在清晨四点半,我正要绝望时,看到一家新邵电器行好像有现货。再看看地址:永和永贞路。那不就在家里附近吗?真是太好了。价钱也差不多中等价位。可是那时候是周六夜,周日清晨,新邵周日休息。天哪~那我怎么确认呢?而且好像很多人问说,要是被别人买走怎么办?还好网站有留手机。我记下手机,星期天开始死命叩,务必要老板帮我留下一台。叩到下午,终於接听了。有现货! Yes! 。确定价钱 26800 + 安装费 1200 + 拆旧机 300 = 27300 后,赶紧跟老板约好星期一早上看冷气,晚上安装。

    + +

    昨天晚上,两个小师傅把冷气送过来,汗流夹背地装好。看著他们辛苦施工,又帮我们把旧冷气,按房东说的,辛苦扛上六楼,觉得他们好厉害。现在的小鬼也有很拼的呢~装上去以后,开了机,设定 27 °C 。哇~真舒服。 27 °C 果然是最舒服的~新的省电变频冷气,真好~ *^_^*

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 111 | + 112 | + 113 | + 114 | + 115 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0113.html.zh-tw.html b/htdocs/imacat/me/diary/0113.html.zh-tw.html new file mode 120000 index 0000000..ba7f88e --- /dev/null +++ b/htdocs/imacat/me/diary/0113.html.zh-tw.html @@ -0,0 +1 @@ +0113.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0113.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0113.html.zh-tw.xhtml new file mode 100644 index 0000000..0c9a927 --- /dev/null +++ b/htdocs/imacat/me/diary/0113.html.zh-tw.xhtml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百一十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百一十三

    + +
    + +
    + +
    +
    6.5.’07. 2:37pm.
    + +

    新冷氣日立 RA-25PL 直流變頻冷暖雙吹窗型冷氣

    + +

    從搬來現在住的永和新生地開始,一直都用好心的房東提供的冷氣。那是一款舊型的日立二手冷氣,型號、年代已經不可考了。雖然還蠻可靠的,可是沒有溫控,一開就冷得要死,不開又熱得要死。每次開一陣子關掉,再開,再關。不然就得要開上冷氣加衣服。忽冷忽熱間,還很容易感冒。這幾年手頭緊,根本不敢奢望新冷氣。加上小招一直主張用電扇就好,反對買冷氣,每次講到換冷氣的事就吵架,就不了了之。

    + +

    不過,我還是都有在留意新冷氣的事。現在夏天這麼熱,不可能真的不用冷氣,臺大公館地下道是臺電認捐認養的,平常走動的時候,看到上面宣導的省電小秘方,第一條就是改用變頻冷氣。前一陣子非法節電器鬧上新聞,蘋果去找了臺電的人,問如何省電,也是說要改用變頻冷氣變頻冷氣,雖然還不知道到底是什麼技術,但就一直這樣記在心裏:買新冷氣時,要買變頻冷氣。

    + +

    幾星期前下定決心,下次領到錢就一定要拿來買冷氣。誰知道沒幾天,公司薪水就又補發一部份下來了。和小招大吵一架後,終於決定買冷氣了。

    + +

    要買,就要買省電的變頻冷氣。我第一個想到的是 Panasonic 潘慧如那個動就冷,不動就省動能偵測器的廣告。雖然那個廣告很蠢,害我這個潘慧如的支持者很難過。 :~~ 可是能夠偵測動能,還是讓我評價非常高。

    + +

    我們家有冷氣窗,也沒有陽台可以擺室外機,所以沒辦法裝分離式,只能買窗型。上了臺灣松下 Panasonic 網站看了幾款後,又到冷氣王牌的臺灣日立網站上看了幾款,發現變頻冷氣大多都是分離式,很少窗型。而日立窗型變頻冷氣,只有一款 RA-25PL 直流變頻冷暖雙吹窗型冷氣。我一看就很喜歡。倒不是因為它的外型,而是它的 EER 高達 3.37 ,業界第一。我依稀記得臺電省電宣導也有提到,改用變頻冷氣, EER 值越高越省電。比較了幾個品牌, Panasonic 的 EER 只有 2.77 , LG 的 EER 最高也只有 3.27 ,日立 EER 3.37 的確是無人能比。加上日立的專利技術渦卷式壓縮機,又比傳統迴轉式壓縮機效能高。比較之後,雖然沒有潘小如的動就冷,不動就省動能偵測器,我還是決定買日立了,比較省電比較環保。

    + +

    確定機型了以後,再上網找有買的商家。可能是我比較傳統吧,不喜歡完全做網路的商家,總覺得沒有保障。我喜歡傳統商家上網刊登型錄,有興趣的話再約去店裏看貨的那種,要實際看到貨的實際狀況,是不是全新品,有沒有刮傷,才能安心買下來,沒辦法單憑型錄、價錢,就叫人家送過來,等到不滿意再退貨或是上網罵。所以 PayEasy 雖然也有賣冷氣,價格也不錯,可是我還是不想跟 PayEasy 買。我搞不懂那些給負評的人:沒看到貨,你們怎麼敢決定買下來呢?沒實際看到的東西,買了以後出問題也不意外。 PayEasy 是不應該出錯,不過消費者一開始就不應該這樣買東西吧?沒見到面,甚至沒通過電話,怎麼把購買的細節溝通清楚呢?真是太奇怪了。

    + +

    看了幾家,一家一家打電話去問。我發現日立 RA-25PL 缺貨缺得很嚴重,四月底第一批貨上市,一下子就斷市,被搶光了,從五月到現在都完全沒貨,日立工廠還在趕工,下一批要六月底以後才生產得出來。不管是 BEST 、全國電子、燦坤、上新聯晴,還是傳統家電行,通通缺貨。我一家一家問,甚至問到高雄、屏東,問到半夜,幾乎絕望了,想說乾脆跟一家有貨的高雄電器行訂,請他們送上來,或是認命等月底算了。

    + +

    就在清晨四點半,我正要絕望時,看到一家新邵電器行好像有現貨。再看看地址:永和永貞路。那不就在家裏附近嗎?真是太好了。價錢也差不多中等價位。可是那時候是周六夜,周日清晨,新邵周日休息。天哪~那我怎麼確認呢?而且好像很多人問說,要是被別人買走怎麼辦?還好網站有留手機。我記下手機,星期天開始死命叩,務必要老闆幫我留下一台。叩到下午,終於接聽了。有現貨! Yes! 。確定價錢 26800 + 安裝費 1200 + 拆舊機 300 = 27300 後,趕緊跟老闆約好星期一早上看冷氣,晚上安裝。

    + +

    昨天晚上,兩個小師傅把冷氣送過來,汗流夾背地裝好。看著他們辛苦施工,又幫我們把舊冷氣,按房東說的,辛苦扛上六樓,覺得他們好厲害。現在的小鬼也有很拼的呢~裝上去以後,開了機,設定 27 °C 。哇~真舒服。 27 °C 果然是最舒服的~新的省電變頻冷氣,真好~ *^_^*

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 111 | + 112 | + 113 | + 114 | + 115 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0114.html.en.html b/htdocs/imacat/me/diary/0114.html.en.html new file mode 120000 index 0000000..4a0d968 --- /dev/null +++ b/htdocs/imacat/me/diary/0114.html.en.html @@ -0,0 +1 @@ +0114.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0114.html.en.xhtml b/htdocs/imacat/me/diary/0114.html.en.xhtml new file mode 100644 index 0000000..c35ac97 --- /dev/null +++ b/htdocs/imacat/me/diary/0114.html.en.xhtml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 114 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 114

    + +
    + +
    + +
    +
    6.11.’07. 4:08pm.
    + +

    Wii

    + +

    做旅行社的媽,不知道怎麼了,去帶了一團 Wii 跑單幫團。全團十幾個人,帶了二十幾台 Wii 回來。在海關,還被扣了好一陣子。

    + +

    她打電話來問我,客人問她要不要買一台。我力勸不要,因為花錢。而且水貨沒保固, Wii 就快在台上市了,不如到時買原廠代理貨,比較有保障。

    + +

    前兩天回家,家裏兩個人都不在。晚上正要開電視看,看到電視機旁邊白白的小盒子:這不是 Wii 嗎?唉,講也講不聽。不過客人的拜託,大概也很難拒絕吧~

    + +

    既然買了,就玩玩看吧。接上去,對著看不懂的日文說明書和日文螢幕,搞了半天,終於把它接上去了。

    + +

    還蠻酷的。我從來沒買過電視遊樂器,雖然以前一直夢想要買 PS2 ,不過也只是想想而已,所以無從比較起。遊戲只有附送的 WiiSports ,裏面有五種運動遊戲:網球、棒球、保齡球、高爾夫球和拳擊。不過, Wii 真是危險的遊戲。才一個晚上,打翻水瓶一次,搖控握把撞牆撞了三次。看來運動的時候,手揮動的前後左右範圍比我想的還要大。到後來,我只敢玩不用前後揮手的拳擊。不過拳擊也不好過。玩了一個晚上,還沒破關,兩隻手臂痠的像要斷掉一樣。都過了兩天了,手臂還在痠痛。

    + +

    不過其實感覺還蠻不錯的。我已經很久沒有運動了,流流汗感覺真好。過度運動的痠痛是因為太久沒動了,要是平常有在運動就不會這樣了。我在想等在台正式上市後,要不要買一台,要是能養成天運動半小時的習慣,每天流流汗,比較健康,也是好事一件。 ^_*'

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 112 | + 113 | + 114 | + 115 | + 116 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0114.html.zh-cn.html b/htdocs/imacat/me/diary/0114.html.zh-cn.html new file mode 120000 index 0000000..16b09bf --- /dev/null +++ b/htdocs/imacat/me/diary/0114.html.zh-cn.html @@ -0,0 +1 @@ +0114.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0114.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0114.html.zh-cn.xhtml new file mode 100644 index 0000000..d036e74 --- /dev/null +++ b/htdocs/imacat/me/diary/0114.html.zh-cn.xhtml @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百一十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百一十四

    + +
    + +
    + +
    +
    6.11.’07. 4:08pm.
    + +

    Wii

    + +

    做旅行社的妈,不知道怎么了,去带了一团 Wii 跑单帮团。全团十几个人,带了二十几台 Wii 回来。在海关,还被扣了好一阵子。

    + +

    她打电话来问我,客人问她要不要买一台。我力劝不要,因为花钱。而且水货没保固, Wii 就快在台上市了,不如到时买原厂代理货,比较有保障。

    + +

    前两天回家,家里两个人都不在。晚上正要开电视看,看到电视机旁边白白的小盒子:这不是 Wii 吗?唉,讲也讲不听。不过客人的拜托,大概也很难拒绝吧~

    + +

    既然买了,就玩玩看吧。接上去,对著看不懂的日文说明书和日文萤幕,搞了半天,终於把它接上去了。

    + +

    还蛮酷的。我从来没买过电视游乐器,虽然以前一直梦想要买 PS2 ,不过也只是想想而已,所以无从比较起。游戏只有附送的 WiiSports ,里面有五种运动游戏:网球、棒球、保龄球、高尔夫球和拳击。不过, Wii 真是危险的游戏。才一个晚上,打翻水瓶一次,摇控握把撞墙撞了三次。看来运动的时候,手挥动的前后左右范围比我想的还要大。到后来,我只敢玩不用前后挥手的拳击。不过拳击也不好过。玩了一个晚上,还没破关,两只手臂酸的像要断掉一样。都过了两天了,手臂还在酸痛。

    + +

    不过其实感觉还蛮不错的。我已经很久没有运动了,流流汗感觉真好。过度运动的酸痛是因为太久没动了,要是平常有在运动就不会这样了。我在想等在台正式上市后,要不要买一台,要是能养成天运动半小时的习惯,每天流流汗,比较健康,也是好事一件。 ^_*'

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 112 | + 113 | + 114 | + 115 | + 116 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0114.html.zh-tw.html b/htdocs/imacat/me/diary/0114.html.zh-tw.html new file mode 120000 index 0000000..a4fafc0 --- /dev/null +++ b/htdocs/imacat/me/diary/0114.html.zh-tw.html @@ -0,0 +1 @@ +0114.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0114.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0114.html.zh-tw.xhtml new file mode 100644 index 0000000..42b3a6d --- /dev/null +++ b/htdocs/imacat/me/diary/0114.html.zh-tw.xhtml @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百一十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百一十四

    + +
    + +
    + +
    +
    6.11.’07. 4:08pm.
    + +

    Wii

    + +

    做旅行社的媽,不知道怎麼了,去帶了一團 Wii 跑單幫團。全團十幾個人,帶了二十幾台 Wii 回來。在海關,還被扣了好一陣子。

    + +

    她打電話來問我,客人問她要不要買一台。我力勸不要,因為花錢。而且水貨沒保固, Wii 就快在台上市了,不如到時買原廠代理貨,比較有保障。

    + +

    前兩天回家,家裏兩個人都不在。晚上正要開電視看,看到電視機旁邊白白的小盒子:這不是 Wii 嗎?唉,講也講不聽。不過客人的拜託,大概也很難拒絕吧~

    + +

    既然買了,就玩玩看吧。接上去,對著看不懂的日文說明書和日文螢幕,搞了半天,終於把它接上去了。

    + +

    還蠻酷的。我從來沒買過電視遊樂器,雖然以前一直夢想要買 PS2 ,不過也只是想想而已,所以無從比較起。遊戲只有附送的 WiiSports ,裏面有五種運動遊戲:網球、棒球、保齡球、高爾夫球和拳擊。不過, Wii 真是危險的遊戲。才一個晚上,打翻水瓶一次,搖控握把撞牆撞了三次。看來運動的時候,手揮動的前後左右範圍比我想的還要大。到後來,我只敢玩不用前後揮手的拳擊。不過拳擊也不好過。玩了一個晚上,還沒破關,兩隻手臂痠的像要斷掉一樣。都過了兩天了,手臂還在痠痛。

    + +

    不過其實感覺還蠻不錯的。我已經很久沒有運動了,流流汗感覺真好。過度運動的痠痛是因為太久沒動了,要是平常有在運動就不會這樣了。我在想等在台正式上市後,要不要買一台,要是能養成天運動半小時的習慣,每天流流汗,比較健康,也是好事一件。 ^_*'

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 112 | + 113 | + 114 | + 115 | + 116 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0115.html.en.html b/htdocs/imacat/me/diary/0115.html.en.html new file mode 120000 index 0000000..9982b1e --- /dev/null +++ b/htdocs/imacat/me/diary/0115.html.en.html @@ -0,0 +1 @@ +0115.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0115.html.en.xhtml b/htdocs/imacat/me/diary/0115.html.en.xhtml new file mode 100644 index 0000000..c1afa8e --- /dev/null +++ b/htdocs/imacat/me/diary/0115.html.en.xhtml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 115 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 115

    + +
    + +
    + +
    +
    6.19.’07. 2:14am.
    + +

    Blade 刀鋒戰士

    + +
    +Blade 刀鋒戰士
    +

    Blade 刀鋒戰士

    +
    + + + +

    刀鋒戰士故事敘述十六年前懷孕女子凡妮莎,被吸血鬼咬死,留下遺腹子艾力克,被魏亞伯收養長大。魏亞伯是對付吸血鬼的戰士,專門製造武器。艾力克長大後,便以刀鋒為號,和魏亞伯合作消滅吸血鬼,為母復仇。某天刀鋒追殺吸血鬼昆恩,昆恩因故未死,在醫院咬傷醫師詹凱琳,原本該殺死詹凱琳以防異變的刀鋒,因詹凱琳很像母親,不忍下手,便留她下來。詹凱琳則利用她血液學的專長,開始研究治療病毒。另一方面,昆恩的老大費斯一心想讓傳說中的血神復活,統治人類,和主張與人類和平相處的吸血鬼長老,衝突一觸即發。而費斯解開血神復活的預言傳說後,發現刀鋒半人半吸血鬼的身體,竟然就是血神復活的關鍵。

    + +

    兩千年前後,開始流行吸血鬼片。吸血鬼暴力血腥日本武士刀,就構成了這部刀鋒戰士。片頭一開始,就出現血浴,畫面非常震憾,也確立了整部片子的基調:血腥,再血腥。刀鋒戰士基本調性非常陽剛,衛斯理史奈普從頭秀肌肉到尾,還有類似第一滴血般自己忍痛療傷的情節。

    + +

    1998 年的刀鋒戰士,其動作、特效與場景不輸給幾年後的同性質電影決戰異世界。然而,刀鋒戰士的劇本非常薄弱。特效技術是可以隨著電腦技術的發展而越來越好的,所以拿前面的刀鋒戰士特效和幾年後的決戰異世界比較,不見得公平。然而,劇本則不大受技術的限制。刀鋒戰士的劇本薄弱,只能說是它自己的問題。刀鋒為什麼不讓詹凱琳醫師加入戰線,詹凱琳醫師為什麼加入戰線,費斯為什麼知道卻一直不反擊刀鋒的巢穴,刀鋒後來弒母的決定,影片的陳述都實在太過薄弱。過多純耍帥的動作,則顯得有點多餘。

    + +

    女主角詹凱琳醫師,在 IMDb 的演員表中排到很後面,和這部陽剛味極重的電影,女主角在劇情中的份量很輕,似乎互相呼應。

    + +

    女吸血鬼 Mercury 雖是配角,但戲份和出現的場景其實不少,如果好好把握,不失為二線翻紅的絕佳機會。可惜 Arly Jover 表現平平,讓人覺得非常可惜。她在片裏只會化濃妝邪笑而已。這大概就是 Arly Jover 實力的底線了吧~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 113 | + 114 | + 115 | + 116 | + 117 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0115.html.zh-cn.html b/htdocs/imacat/me/diary/0115.html.zh-cn.html new file mode 120000 index 0000000..a607771 --- /dev/null +++ b/htdocs/imacat/me/diary/0115.html.zh-cn.html @@ -0,0 +1 @@ +0115.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0115.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0115.html.zh-cn.xhtml new file mode 100644 index 0000000..b8d2f65 --- /dev/null +++ b/htdocs/imacat/me/diary/0115.html.zh-cn.xhtml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百一十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百一十五

    + +
    + +
    + +
    +
    6.19.’07. 2:14am.
    + +

    Blade 刀锋战士

    + +
    +Blade 刀锋战士
    +

    Blade 刀锋战士

    +
    + + + +

    刀锋战士故事叙述十六年前怀孕女子凡妮莎,被吸血鬼咬死,留下遗腹子艾力克,被魏亚伯收养长大。魏亚伯是对付吸血鬼的战士,专门制造武器。艾力克长大后,便以刀锋为号,和魏亚伯合作消灭吸血鬼,为母复仇。某天刀锋追杀吸血鬼昆恩,昆恩因故未死,在医院咬伤医师詹凯琳,原本该杀死詹凯琳以防异变的刀锋,因詹凯琳很像母亲,不忍下手,便留她下来。詹凯琳则利用她血液学的专长,开始研究治疗病毒。另一方面,昆恩的老大费斯一心想让传说中的血神复活,统治人类,和主张与人类和平相处的吸血鬼长老,冲突一触即发。而费斯解开血神复活的预言传说后,发现刀锋半人半吸血鬼的身体,竟然就是血神复活的关键。

    + +

    两千年前后,开始流行吸血鬼片。吸血鬼暴力血腥日本武士刀,就构成了这部刀锋战士。片头一开始,就出现血浴,画面非常震憾,也确立了整部片子的基调:血腥,再血腥。刀锋战士基本调性非常阳刚,卫斯理史奈普从头秀肌肉到尾,还有类似第一滴血般自己忍痛疗伤的情节。

    + +

    1998 年的刀锋战士,其动作、特效与场景不输给几年后的同性质电影决战异世界。然而,刀锋战士的剧本非常薄弱。特效技术是可以随著电脑技术的发展而越来越好的,所以拿前面的刀锋战士特效和几年后的决战异世界比较,不见得公平。然而,剧本则不大受技术的限制。刀锋战士的剧本薄弱,只能说是它自己的问题。刀锋为什么不让詹凯琳医师加入战线,詹凯琳医师为什么加入战线,费斯为什么知道却一直不反击刀锋的巢穴,刀锋后来弑母的决定,影片的陈述都实在太过薄弱。过多纯耍帅的动作,则显得有点多余。

    + +

    女主角詹凯琳医师,在 IMDb 的演员表中排到很后面,和这部阳刚味极重的电影,女主角在剧情中的份量很轻,似乎互相呼应。

    + +

    女吸血鬼 Mercury 虽是配角,但戏份和出现的场景其实不少,如果好好把握,不失为二线翻红的绝佳机会。可惜 Arly Jover 表现平平,让人觉得非常可惜。她在片里只会化浓妆邪笑而已。这大概就是 Arly Jover 实力的底线了吧~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 113 | + 114 | + 115 | + 116 | + 117 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0115.html.zh-tw.html b/htdocs/imacat/me/diary/0115.html.zh-tw.html new file mode 120000 index 0000000..dce7136 --- /dev/null +++ b/htdocs/imacat/me/diary/0115.html.zh-tw.html @@ -0,0 +1 @@ +0115.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0115.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0115.html.zh-tw.xhtml new file mode 100644 index 0000000..c1370a2 --- /dev/null +++ b/htdocs/imacat/me/diary/0115.html.zh-tw.xhtml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百一十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百一十五

    + +
    + +
    + +
    +
    6.19.’07. 2:14am.
    + +

    Blade 刀鋒戰士

    + +
    +Blade 刀鋒戰士
    +

    Blade 刀鋒戰士

    +
    + + + +

    刀鋒戰士故事敘述十六年前懷孕女子凡妮莎,被吸血鬼咬死,留下遺腹子艾力克,被魏亞伯收養長大。魏亞伯是對付吸血鬼的戰士,專門製造武器。艾力克長大後,便以刀鋒為號,和魏亞伯合作消滅吸血鬼,為母復仇。某天刀鋒追殺吸血鬼昆恩,昆恩因故未死,在醫院咬傷醫師詹凱琳,原本該殺死詹凱琳以防異變的刀鋒,因詹凱琳很像母親,不忍下手,便留她下來。詹凱琳則利用她血液學的專長,開始研究治療病毒。另一方面,昆恩的老大費斯一心想讓傳說中的血神復活,統治人類,和主張與人類和平相處的吸血鬼長老,衝突一觸即發。而費斯解開血神復活的預言傳說後,發現刀鋒半人半吸血鬼的身體,竟然就是血神復活的關鍵。

    + +

    兩千年前後,開始流行吸血鬼片。吸血鬼暴力血腥日本武士刀,就構成了這部刀鋒戰士。片頭一開始,就出現血浴,畫面非常震憾,也確立了整部片子的基調:血腥,再血腥。刀鋒戰士基本調性非常陽剛,衛斯理史奈普從頭秀肌肉到尾,還有類似第一滴血般自己忍痛療傷的情節。

    + +

    1998 年的刀鋒戰士,其動作、特效與場景不輸給幾年後的同性質電影決戰異世界。然而,刀鋒戰士的劇本非常薄弱。特效技術是可以隨著電腦技術的發展而越來越好的,所以拿前面的刀鋒戰士特效和幾年後的決戰異世界比較,不見得公平。然而,劇本則不大受技術的限制。刀鋒戰士的劇本薄弱,只能說是它自己的問題。刀鋒為什麼不讓詹凱琳醫師加入戰線,詹凱琳醫師為什麼加入戰線,費斯為什麼知道卻一直不反擊刀鋒的巢穴,刀鋒後來弒母的決定,影片的陳述都實在太過薄弱。過多純耍帥的動作,則顯得有點多餘。

    + +

    女主角詹凱琳醫師,在 IMDb 的演員表中排到很後面,和這部陽剛味極重的電影,女主角在劇情中的份量很輕,似乎互相呼應。

    + +

    女吸血鬼 Mercury 雖是配角,但戲份和出現的場景其實不少,如果好好把握,不失為二線翻紅的絕佳機會。可惜 Arly Jover 表現平平,讓人覺得非常可惜。她在片裏只會化濃妝邪笑而已。這大概就是 Arly Jover 實力的底線了吧~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 113 | + 114 | + 115 | + 116 | + 117 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0116.html.en.html b/htdocs/imacat/me/diary/0116.html.en.html new file mode 120000 index 0000000..581a774 --- /dev/null +++ b/htdocs/imacat/me/diary/0116.html.en.html @@ -0,0 +1 @@ +0116.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0116.html.en.xhtml b/htdocs/imacat/me/diary/0116.html.en.xhtml new file mode 100644 index 0000000..71726e2 --- /dev/null +++ b/htdocs/imacat/me/diary/0116.html.en.xhtml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 116 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 116

    + +
    + +
    + +
    +
    6.19.’07. 5:57am.
    + +

    Blade Ⅱ 刀鋒戰士 2 —背叛個沒完沒了

    + +
    +Blade Ⅱ 刀鋒戰士 2
    +

    Blade Ⅱ 刀鋒戰士 2

    +
    + + + +

    刀鋒戰士 2延續第一集的劇情:在第一集被吸血鬼咬而自殺的惠斯勒,自殺未死而被吸血鬼劫走,下落不明。刀鋒為救他走遍全世界,最後終於在捷克布拉格追到他。此時刀鋒已有新的後援搭檔飛毛腿賈許,惠斯勒和賈許心生嫌隙。此時布拉格本地吸血鬼大公艾里大馬基諾斯,派女兒妮莎送來口信,欲與刀鋒談和。原來和刀鋒一樣,吸血鬼病毒又產生異變,生成的變種吸血鬼 R 變種 (Reapers) 查德諾瑪,不怕銀不怕大蒜不怕陽光,並以原生吸血鬼為食,異常殘忍兇焊。大馬基諾斯大公,派出原先原為狙殺刀鋒組成的護血隊 (Bloodpack) ,欲與刀鋒暫時和平聯手,消滅共同敵人。然而護血隊視刀鋒如仇,刀鋒陣營也視吸血鬼如仇。就在成員彼此的仇視之中,獵殺隊一步步往變種吸血鬼的巢穴進發。而變種吸血鬼諾瑪發現了刀鋒等人的存在,也悄悄準備要狙殺獵殺隊。就在戰爭一觸即發的時候,更大的陰謀,也悄悄落在所有人身上。

    + +

    刀鋒戰士 2感覺上像是無止盡的背叛遊戲。從頭到尾,都在不信任與不信任之間進行,每個人都在提防每個人,到底誰會背叛誰。護血隊不相信刀鋒,隨時準備反噬刀鋒;刀鋒不相信護血隊,隨時準備壓制護血隊;惠斯勒也不相信護血隊,隨時準備犧牲護血隊;飛毛腿不相信曾經被咬傷,被長期強迫餵血的惠斯勒已治好,隨時提醒刀鋒小心;護血隊的光斧被咬傷,卻隱瞞不說,不知何時會異變反噬。背叛的陰影壟罩著所有的人。倒底誰會倒戈?誰會出手?到最後電影果然也不失眾望,真的有人背叛了:大公背叛了兒子和女兒,飛毛腿則背叛了刀鋒。

    + +

    刀鋒戰士 2另一個有趣的地方是獵人和獵物角色不停互換。原本刀鋒是獵人,吸血鬼是他的獵物。沒想到吸血鬼為對付他,訓練了一批專門用來獵殺他的護血隊。這時護血隊變成了獵人,刀鋒變成了獵物。後來刀鋒和護血隊合力討伐 R 變種,他們一起成為獵殺 R 變種的獵人;但 R 變種提早發現了獵人的行蹤,悄悄佈陣準備反獵殺,這時 R 變種搖身一變反成了獵人,反把刀鋒和護血隊變成了獵物。獵人和獵物的角色不停互換。這在後來成龍的新警察故事 (2004) 中,也有出現過同樣的場景。

    + +

    刀鋒戰士 2刀鋒戰士的劇情強得多。加入的三方角力,及各方的猜忌,讓劇情懸疑氣氛大增,張力十足。另外,刀鋒戰士 2的武打動作也好得多。有甄子丹指導,武打的份量和第一集比起來,果然不同凡響,有中片武打動作的水準,非常漂亮有力。

    + +

    R 變種下巴裂開,整個嘴裂成三半,嘴裏再伸出吸食器的咬食方式,感覺蠻酷的,這部份的特效做得不錯。

    + +

    刀鋒戰士 Abraham Whistler 譯為魏亞伯,到了刀鋒戰士 2改譯為惠斯勒刀鋒戰士 Daywalker 譯為日行者,到了刀鋒戰士 2改譯為白晝遊俠。譯名沒有前後統一,是翻譯的大忌。無論之前譯名出現什麼問題,保持譯名的一貫性,是最最重要的事。

    + +

    整體來說,刀鋒戰士 2刀鋒戰士好看得多。續集比第一集好,在電影圈中,真的不容易。 ^_*'

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 114 | + 115 | + 116 | + 117 | + 118 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0116.html.zh-cn.html b/htdocs/imacat/me/diary/0116.html.zh-cn.html new file mode 120000 index 0000000..182592c --- /dev/null +++ b/htdocs/imacat/me/diary/0116.html.zh-cn.html @@ -0,0 +1 @@ +0116.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0116.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0116.html.zh-cn.xhtml new file mode 100644 index 0000000..ce5b68d --- /dev/null +++ b/htdocs/imacat/me/diary/0116.html.zh-cn.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百一十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百一十六

    + +
    + +
    + +
    +
    6.19.’07. 5:57am.
    + +

    Blade Ⅱ 刀锋战士 2 —背叛个没完没了

    + +
    +Blade Ⅱ 刀锋战士 2
    +

    Blade Ⅱ 刀锋战士 2

    +
    + + + +

    刀锋战士 2延续第一集的剧情:在第一集被吸血鬼咬而自杀的惠斯勒,自杀未死而被吸血鬼劫走,下落不明。刀锋为救他走遍全世界,最后终於在捷克布拉格追到他。此时刀锋已有新的后援搭档飞毛腿贾许,惠斯勒和贾许心生嫌隙。此时布拉格本地吸血鬼大公艾里大马基诺斯,派女儿妮莎送来口信,欲与刀锋谈和。原来和刀锋一样,吸血鬼病毒又产生异变,生成的变种吸血鬼 R 变种 (Reapers) 查德诺玛,不怕银不怕大蒜不怕阳光,并以原生吸血鬼为食,异常残忍凶焊。大马基诺斯大公,派出原先原为狙杀刀锋组成的护血队 (Bloodpack) ,欲与刀锋暂时和平联手,消灭共同敌人。然而护血队视刀锋如仇,刀锋阵营也视吸血鬼如仇。就在成员彼此的仇视之中,猎杀队一步步往变种吸血鬼的巢穴进发。而变种吸血鬼诺玛发现了刀锋等人的存在,也悄悄准备要狙杀猎杀队。就在战争一触即发的时候,更大的阴谋,也悄悄落在所有人身上。

    + +

    刀锋战士 2感觉上像是无止尽的背叛游戏。从头到尾,都在不信任与不信任之间进行,每个人都在提防每个人,到底谁会背叛谁。护血队不相信刀锋,随时准备反噬刀锋;刀锋不相信护血队,随时准备压制护血队;惠斯勒也不相信护血队,随时准备牺牲护血队;飞毛腿不相信曾经被咬伤,被长期强迫喂血的惠斯勒已治好,随时提醒刀锋小心;护血队的光斧被咬伤,却隐瞒不说,不知何时会异变反噬。背叛的阴影垄罩著所有的人。倒底谁会倒戈?谁会出手?到最后电影果然也不失众望,真的有人背叛了:大公背叛了儿子和女儿,飞毛腿则背叛了刀锋。

    + +

    刀锋战士 2另一个有趣的地方是猎人和猎物角色不停互换。原本刀锋是猎人,吸血鬼是他的猎物。没想到吸血鬼为对付他,训练了一批专门用来猎杀他的护血队。这时护血队变成了猎人,刀锋变成了猎物。后来刀锋和护血队合力讨伐 R 变种,他们一起成为猎杀 R 变种的猎人;但 R 变种提早发现了猎人的行踪,悄悄布阵准备反猎杀,这时 R 变种摇身一变反成了猎人,反把刀锋和护血队变成了猎物。猎人和猎物的角色不停互换。这在后来成龙的新警察故事 (2004) 中,也有出现过同样的场景。

    + +

    刀锋战士 2刀锋战士的剧情强得多。加入的三方角力,及各方的猜忌,让剧情悬疑气氛大增,张力十足。另外,刀锋战士 2的武打动作也好得多。有甄子丹指导,武打的份量和第一集比起来,果然不同凡响,有中片武打动作的水准,非常漂亮有力。

    + +

    R 变种下巴裂开,整个嘴裂成三半,嘴里再伸出吸食器的咬食方式,感觉蛮酷的,这部份的特效做得不错。

    + +

    刀锋战士 Abraham Whistler 译为魏亚伯,到了刀锋战士 2改译为惠斯勒刀锋战士 Daywalker 译为日行者,到了刀锋战士 2改译为白昼游侠。译名没有前后统一,是翻译的大忌。无论之前译名出现什么问题,保持译名的一贯性,是最最重要的事。

    + +

    整体来说,刀锋战士 2刀锋战士好看得多。续集比第一集好,在电影圈中,真的不容易。 ^_*'

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 114 | + 115 | + 116 | + 117 | + 118 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0116.html.zh-tw.html b/htdocs/imacat/me/diary/0116.html.zh-tw.html new file mode 120000 index 0000000..272c882 --- /dev/null +++ b/htdocs/imacat/me/diary/0116.html.zh-tw.html @@ -0,0 +1 @@ +0116.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0116.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0116.html.zh-tw.xhtml new file mode 100644 index 0000000..57661b1 --- /dev/null +++ b/htdocs/imacat/me/diary/0116.html.zh-tw.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百一十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百一十六

    + +
    + +
    + +
    +
    6.19.’07. 5:57am.
    + +

    Blade Ⅱ 刀鋒戰士 2 —背叛個沒完沒了

    + +
    +Blade Ⅱ 刀鋒戰士 2
    +

    Blade Ⅱ 刀鋒戰士 2

    +
    + + + +

    刀鋒戰士 2延續第一集的劇情:在第一集被吸血鬼咬而自殺的惠斯勒,自殺未死而被吸血鬼劫走,下落不明。刀鋒為救他走遍全世界,最後終於在捷克布拉格追到他。此時刀鋒已有新的後援搭檔飛毛腿賈許,惠斯勒和賈許心生嫌隙。此時布拉格本地吸血鬼大公艾里大馬基諾斯,派女兒妮莎送來口信,欲與刀鋒談和。原來和刀鋒一樣,吸血鬼病毒又產生異變,生成的變種吸血鬼 R 變種 (Reapers) 查德諾瑪,不怕銀不怕大蒜不怕陽光,並以原生吸血鬼為食,異常殘忍兇焊。大馬基諾斯大公,派出原先原為狙殺刀鋒組成的護血隊 (Bloodpack) ,欲與刀鋒暫時和平聯手,消滅共同敵人。然而護血隊視刀鋒如仇,刀鋒陣營也視吸血鬼如仇。就在成員彼此的仇視之中,獵殺隊一步步往變種吸血鬼的巢穴進發。而變種吸血鬼諾瑪發現了刀鋒等人的存在,也悄悄準備要狙殺獵殺隊。就在戰爭一觸即發的時候,更大的陰謀,也悄悄落在所有人身上。

    + +

    刀鋒戰士 2感覺上像是無止盡的背叛遊戲。從頭到尾,都在不信任與不信任之間進行,每個人都在提防每個人,到底誰會背叛誰。護血隊不相信刀鋒,隨時準備反噬刀鋒;刀鋒不相信護血隊,隨時準備壓制護血隊;惠斯勒也不相信護血隊,隨時準備犧牲護血隊;飛毛腿不相信曾經被咬傷,被長期強迫餵血的惠斯勒已治好,隨時提醒刀鋒小心;護血隊的光斧被咬傷,卻隱瞞不說,不知何時會異變反噬。背叛的陰影壟罩著所有的人。倒底誰會倒戈?誰會出手?到最後電影果然也不失眾望,真的有人背叛了:大公背叛了兒子和女兒,飛毛腿則背叛了刀鋒。

    + +

    刀鋒戰士 2另一個有趣的地方是獵人和獵物角色不停互換。原本刀鋒是獵人,吸血鬼是他的獵物。沒想到吸血鬼為對付他,訓練了一批專門用來獵殺他的護血隊。這時護血隊變成了獵人,刀鋒變成了獵物。後來刀鋒和護血隊合力討伐 R 變種,他們一起成為獵殺 R 變種的獵人;但 R 變種提早發現了獵人的行蹤,悄悄佈陣準備反獵殺,這時 R 變種搖身一變反成了獵人,反把刀鋒和護血隊變成了獵物。獵人和獵物的角色不停互換。這在後來成龍的新警察故事 (2004) 中,也有出現過同樣的場景。

    + +

    刀鋒戰士 2刀鋒戰士的劇情強得多。加入的三方角力,及各方的猜忌,讓劇情懸疑氣氛大增,張力十足。另外,刀鋒戰士 2的武打動作也好得多。有甄子丹指導,武打的份量和第一集比起來,果然不同凡響,有中片武打動作的水準,非常漂亮有力。

    + +

    R 變種下巴裂開,整個嘴裂成三半,嘴裏再伸出吸食器的咬食方式,感覺蠻酷的,這部份的特效做得不錯。

    + +

    刀鋒戰士 Abraham Whistler 譯為魏亞伯,到了刀鋒戰士 2改譯為惠斯勒刀鋒戰士 Daywalker 譯為日行者,到了刀鋒戰士 2改譯為白晝遊俠。譯名沒有前後統一,是翻譯的大忌。無論之前譯名出現什麼問題,保持譯名的一貫性,是最最重要的事。

    + +

    整體來說,刀鋒戰士 2刀鋒戰士好看得多。續集比第一集好,在電影圈中,真的不容易。 ^_*'

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 114 | + 115 | + 116 | + 117 | + 118 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0117.html.en.html b/htdocs/imacat/me/diary/0117.html.en.html new file mode 120000 index 0000000..bead6d0 --- /dev/null +++ b/htdocs/imacat/me/diary/0117.html.en.html @@ -0,0 +1 @@ +0117.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0117.html.en.xhtml b/htdocs/imacat/me/diary/0117.html.en.xhtml new file mode 100644 index 0000000..92ff2ce --- /dev/null +++ b/htdocs/imacat/me/diary/0117.html.en.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 117 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 117

    + +
    + +
    + +
    +
    6.20.’07. 4:23am.
    + +

    화산고 火山高校 Volcano High

    + +
    +화산고 火山高校
    +

    화산고 火山高校

    +
    + + + +

    火山高校描寫擁有異能的轉學生金英俊,屢因控制不了自己的力量,被學校退學,退學九次後轉到火山高校,下定決心一定要低調忍耐到底。然而火山高校內暗嘲洶湧,經歷了十七年的勁爆教師爭奪戰方告落幕。校內由愛好和平的校長長悟子主政,學生秩序由學生第一高手松學林維持。此時有謠言指出,校長藏有一部武林密笈,誰得此密笈便可號令天下。謠言引發有野心的各方蠢蠢欲動。副校長主張填鴨式教育,一直與校長教學理念不合,覬覦武林密笈,聯合一直想稱霸校園的舉重隊隊長張良,暗中對校長下毒,陷害唯一有權取得密笈的學生第一高手松學林,剷除兩大阻礙。然而校長中毒麻痺,松學林入獄後,副校長搜遍各處,還是找不到密笈。張良沒有了松學林妨礙,橫行無阻,學生人人自危,少數如心魔等有能力者,又為個人權力陷入無止境的爭吵。副校長一直找不到武林密笈,決商請高校五虎老師出馬。女子劍道部主將柳採怡看不慣張良和五虎老師的橫行,及各社團的爭權奪利,偕同暗戀松學林的副將逍遙仙,入獄中商請松學林出馬。但松學林在獄中沉迷於參悟密笈,對學校毫不關心,更不想出獄。逍遙仙、柳採怡和女子劍道部憤而獨自找上五虎老師決鬥,慘敗收場,逍遙仙被退學。找不到密笈的副校長,終於放棄找密笈,開始協同五虎老師,以密笈之名及填鴨式教育理念整治學校。首先就取消課外活動,拿橫行的新學生老大張良和舉重部開刀。眼看學生快要被老師全面武力壓制,一直低調忍耐不出手的金英俊,終於和失去好友的柳採怡、張良連成同一陣線開戰。

    + +

    終於完整看完了火山高校。真的很好看。之前看的,都是第四台或是阿囉哈客運上,從中間一半開始看。一直都不大搞得懂:為什麼火山高校每個人都會武功?個個都是高手,而且都很厲害?直到完整看過後,才了解了:沒有為什麼,反正就是這樣。 ^_*'

    + +

    反正就是這樣。火山高校完全沒有解釋為什麼這所高中不管學生老師,人人都會武功,成為一群武功高手爭鬥的地方,而直接從這樣的基本設定開始,開展整個科幻的故事情節。不過,仿彿這些武功高手的校園爭鬥是理所當然的事實一樣,不會讓人感到突兀。於是,電影得以全力鋪陳漫畫般的劇情,及漫畫般的武打畫面。火山高校節奏緊湊,充斥著漫畫般的動作畫面,不需要多思考,讓人覺得非常過癮。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 115 | + 116 | + 117 | + 118 | + 119 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0117.html.zh-cn.html b/htdocs/imacat/me/diary/0117.html.zh-cn.html new file mode 120000 index 0000000..140dd9d --- /dev/null +++ b/htdocs/imacat/me/diary/0117.html.zh-cn.html @@ -0,0 +1 @@ +0117.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0117.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0117.html.zh-cn.xhtml new file mode 100644 index 0000000..c46e8e7 --- /dev/null +++ b/htdocs/imacat/me/diary/0117.html.zh-cn.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百一十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百一十七

    + +
    + +
    + +
    +
    6.20.’07. 4:23am.
    + +

    화산고 火山高校 Volcano High

    + +
    +화산고 火山高校
    +

    화산고 火山高校

    +
    + + + +

    火山高校描写拥有异能的转学生金英俊,屡因控制不了自己的力量,被学校退学,退学九次后转到火山高校,下定决心一定要低调忍耐到底。然而火山高校内暗嘲汹涌,经历了十七年的劲爆教师争夺战方告落幕。校内由爱好和平的校长长悟子主政,学生秩序由学生第一高手松学林维持。此时有谣言指出,校长藏有一部武林密笈,谁得此密笈便可号令天下。谣言引发有野心的各方蠢蠢欲动。副校长主张填鸭式教育,一直与校长教学理念不合,觊觎武林密笈,联合一直想称霸校园的举重队队长张良,暗中对校长下毒,陷害唯一有权取得密笈的学生第一高手松学林,铲除两大阻碍。然而校长中毒麻痹,松学林入狱后,副校长搜遍各处,还是找不到密笈。张良没有了松学林妨碍,横行无阻,学生人人自危,少数如心魔等有能力者,又为个人权力陷入无止境的争吵。副校长一直找不到武林密笈,决商请高校五虎老师出马。女子剑道部主将柳采怡看不惯张良和五虎老师的横行,及各社团的争权夺利,偕同暗恋松学林的副将逍遥仙,入狱中商请松学林出马。但松学林在狱中沉迷於参悟密笈,对学校毫不关心,更不想出狱。逍遥仙、柳采怡和女子剑道部愤而独自找上五虎老师决斗,惨败收场,逍遥仙被退学。找不到密笈的副校长,终於放弃找密笈,开始协同五虎老师,以密笈之名及填鸭式教育理念整治学校。首先就取消课外活动,拿横行的新学生老大张良和举重部开刀。眼看学生快要被老师全面武力压制,一直低调忍耐不出手的金英俊,终於和失去好友的柳采怡、张良连成同一阵线开战。

    + +

    终於完整看完了火山高校。真的很好看。之前看的,都是第四台或是阿罗哈客运上,从中间一半开始看。一直都不大搞得懂:为什么火山高校每个人都会武功?个个都是高手,而且都很厉害?直到完整看过后,才了解了:没有为什么,反正就是这样。 ^_*'

    + +

    反正就是这样。火山高校完全没有解释为什么这所高中不管学生老师,人人都会武功,成为一群武功高手争斗的地方,而直接从这样的基本设定开始,开展整个科幻的故事情节。不过,仿佛这些武功高手的校园争斗是理所当然的事实一样,不会让人感到突兀。於是,电影得以全力铺陈漫画般的剧情,及漫画般的武打画面。火山高校节奏紧凑,充斥著漫画般的动作画面,不需要多思考,让人觉得非常过瘾。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 115 | + 116 | + 117 | + 118 | + 119 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0117.html.zh-tw.html b/htdocs/imacat/me/diary/0117.html.zh-tw.html new file mode 120000 index 0000000..6ecd26c --- /dev/null +++ b/htdocs/imacat/me/diary/0117.html.zh-tw.html @@ -0,0 +1 @@ +0117.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0117.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0117.html.zh-tw.xhtml new file mode 100644 index 0000000..4b7f5cf --- /dev/null +++ b/htdocs/imacat/me/diary/0117.html.zh-tw.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百一十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百一十七

    + +
    + +
    + +
    +
    6.20.’07. 4:23am.
    + +

    화산고 火山高校 Volcano High

    + +
    +화산고 火山高校
    +

    화산고 火山高校

    +
    + + + +

    火山高校描寫擁有異能的轉學生金英俊,屢因控制不了自己的力量,被學校退學,退學九次後轉到火山高校,下定決心一定要低調忍耐到底。然而火山高校內暗嘲洶湧,經歷了十七年的勁爆教師爭奪戰方告落幕。校內由愛好和平的校長長悟子主政,學生秩序由學生第一高手松學林維持。此時有謠言指出,校長藏有一部武林密笈,誰得此密笈便可號令天下。謠言引發有野心的各方蠢蠢欲動。副校長主張填鴨式教育,一直與校長教學理念不合,覬覦武林密笈,聯合一直想稱霸校園的舉重隊隊長張良,暗中對校長下毒,陷害唯一有權取得密笈的學生第一高手松學林,剷除兩大阻礙。然而校長中毒麻痺,松學林入獄後,副校長搜遍各處,還是找不到密笈。張良沒有了松學林妨礙,橫行無阻,學生人人自危,少數如心魔等有能力者,又為個人權力陷入無止境的爭吵。副校長一直找不到武林密笈,決商請高校五虎老師出馬。女子劍道部主將柳採怡看不慣張良和五虎老師的橫行,及各社團的爭權奪利,偕同暗戀松學林的副將逍遙仙,入獄中商請松學林出馬。但松學林在獄中沉迷於參悟密笈,對學校毫不關心,更不想出獄。逍遙仙、柳採怡和女子劍道部憤而獨自找上五虎老師決鬥,慘敗收場,逍遙仙被退學。找不到密笈的副校長,終於放棄找密笈,開始協同五虎老師,以密笈之名及填鴨式教育理念整治學校。首先就取消課外活動,拿橫行的新學生老大張良和舉重部開刀。眼看學生快要被老師全面武力壓制,一直低調忍耐不出手的金英俊,終於和失去好友的柳採怡、張良連成同一陣線開戰。

    + +

    終於完整看完了火山高校。真的很好看。之前看的,都是第四台或是阿囉哈客運上,從中間一半開始看。一直都不大搞得懂:為什麼火山高校每個人都會武功?個個都是高手,而且都很厲害?直到完整看過後,才了解了:沒有為什麼,反正就是這樣。 ^_*'

    + +

    反正就是這樣。火山高校完全沒有解釋為什麼這所高中不管學生老師,人人都會武功,成為一群武功高手爭鬥的地方,而直接從這樣的基本設定開始,開展整個科幻的故事情節。不過,仿彿這些武功高手的校園爭鬥是理所當然的事實一樣,不會讓人感到突兀。於是,電影得以全力鋪陳漫畫般的劇情,及漫畫般的武打畫面。火山高校節奏緊湊,充斥著漫畫般的動作畫面,不需要多思考,讓人覺得非常過癮。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 115 | + 116 | + 117 | + 118 | + 119 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0118.html.en.html b/htdocs/imacat/me/diary/0118.html.en.html new file mode 120000 index 0000000..a17e436 --- /dev/null +++ b/htdocs/imacat/me/diary/0118.html.en.html @@ -0,0 +1 @@ +0118.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0118.html.en.xhtml b/htdocs/imacat/me/diary/0118.html.en.xhtml new file mode 100644 index 0000000..8fdc7d3 --- /dev/null +++ b/htdocs/imacat/me/diary/0118.html.en.xhtml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 118 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 118

    + +
    + +
    + +
    +
    6.21.’07. 3:42am.
    + +

    紙娃娃遊戲

    + +

    星期天下午和小招逛街,逛到忠孝東路 SOGO 的玩具部。我最近又迷上了百貨公司玩具部的玩具,不管是鋼彈的組合模型,還是美泰兒的芭比娃娃,都能讓我看得流連忘返。不過,這天,讓我碰到一件非常震憾的事。

    + +

    在玩具部走著走著,看到女生玩具區,有個角落擺了四台電動玩具,有幾個媽媽帶著小女孩聚在那裏。我一時好奇心起,便湊過去看一看。看了一會,好像是紙娃娃遊戲(給娃娃換各式各樣的衣服),不過好像還有一些變化,看不大懂。這時正好有一台空下來,而且好像沒有人要玩,我就湊上試試看。 :p

    + +

    看看說明,看看投幣孔。一次三十塊,蠻貴的。不過只試玩一次,我們還不至於玩不起。和小招湊了三個銅板投進去,繼續看說明。隔壁的媽媽開口提醒我,要拿卡片。我看一看,投幣孔旁邊好像掉出了一張卡片,拿了卡片,沒仔細看,繼續看那個不大看得懂的遊戲說明。這時候,隔壁的媽媽忍不住說了:

    + +
    +

    妳們這個樣子是沒辦法玩的,要有衣服才能玩。

    +
    + +

    衣服?喔。我大概知道。我看得出來這是紙娃娃遊戲,當然要衣服。可是衣服在哪裏呢?去哪裏弄衣服?畫面出現了兩個小女生對話,大意是說,該起床要去參加派對了!可是要參加什麼派對呢?出現五個派對可以選:街舞、 Pub 、偶像明星選秀會…等等。我沒玩過也看不懂,隨便選了街舞。這時隔壁的媽媽再也忍不住了。

    + +
    +

    妳們要有參加街舞的衣服才能玩。我幫妳們看看…

    +
    + +

    接著,她打開一個本子,一本卡片搜集冊,裏面一面四張,一頁雙面八張,大概六七頁,加上一堆零散塞不下的卡片,全部大概六、七十張。裏面全都是各種帽子、衣服、褲子、鞋子的卡片。我和小招睜大雙眼,看傻了。我把手中的卡片翻開來看:一雙高跟鞋。原來如此,我終於懂了。每投一次幣三十元,就可以獲得一張卡片。有適當的衣服卡片,就可以換上適當的衣服。

    + +

    只見隔壁的媽媽,在卡片冊裏翻來翻去:要參加街舞,要穿哪個好呢?

    + +

    這時,隔壁的小女生終於忍不住插嘴:媽,不對啦,街舞要穿這個!說著,在手上的卡片中,迅速找到帽子、衣服、褲子、鞋子拿給我。我偷瞄了一眼,她手上至少有二、三十張卡片。對她們說聲謝謝,拿著借來的卡片,一一刷下去。果然,遊戲的主角就換上了很酷的街舞裝。一上場,光服裝就 157 分,狠狠打敗對手。

    + +

    接下來,就是跳舞機的情節了。順著打節拍,打得好就有高分。託隔壁母女的福,服裝拿到了高分,總分輕易就打敗了對手。不過下一關偶像明星選秀會,就不好意思再跟人家借卡片了。穿了街舞的衣服去參加偶像明星選秀,光服裝就輸了一大截,後來就不用說了。

    + +

    為了答謝她們拔刀相助,我們把手上的高跟鞋卡片送給她們。反正我們大概也不會再玩第二次了。

    + +

    回來的路上,我們越想越可怕。那個媽媽手上的集卡冊,加上女兒手上的卡片,加起來至少有九十張。投三十元才有一張卡片,那個媽媽至少花了兩、三千塊錢,才有這樣的成果。而且這個遊戲要靠集卡才能玩,掉出來的卡片事先無法知道,而且還會碰到重覆。那至少要投入一、兩千塊錢,才有足夠的卡片可以玩。這個遊戲真是太、太可怕了。現在的媽媽也真是太可怕了,為小孩花錢都不心軟的嗎?

    + +

    仔細想想,我們答謝她給她的高跟鞋卡,她大概已經重覆了,不需要吧~

    + +

    小時候我們玩的紙娃娃遊戲,二十塊錢就有一大本,自己按裁切線割下來,就有幾十件衣服、褲子、鞋子、配件,換都換不完。那時候這樣就玩得很高興了。現在玩紙娃娃遊戲,三十塊錢才有一件,可以花上好幾千塊錢搜集衣服,錢花得毫不心軟,真是難以想像。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 116 | + 117 | + 118 | + 119 | + 120 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0118.html.zh-cn.html b/htdocs/imacat/me/diary/0118.html.zh-cn.html new file mode 120000 index 0000000..b2aa233 --- /dev/null +++ b/htdocs/imacat/me/diary/0118.html.zh-cn.html @@ -0,0 +1 @@ +0118.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0118.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0118.html.zh-cn.xhtml new file mode 100644 index 0000000..0ab9b1b --- /dev/null +++ b/htdocs/imacat/me/diary/0118.html.zh-cn.xhtml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百一十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百一十八

    + +
    + +
    + +
    +
    6.21.’07. 3:42am.
    + +

    纸娃娃游戏

    + +

    星期天下午和小招逛街,逛到忠孝东路 SOGO 的玩具部。我最近又迷上了百货公司玩具部的玩具,不管是钢弹的组合模型,还是美泰儿的芭比娃娃,都能让我看得流连忘返。不过,这天,让我碰到一件非常震憾的事。

    + +

    在玩具部走著走著,看到女生玩具区,有个角落摆了四台电动玩具,有几个妈妈带著小女孩聚在那里。我一时好奇心起,便凑过去看一看。看了一会,好像是纸娃娃游戏(给娃娃换各式各样的衣服),不过好像还有一些变化,看不大懂。这时正好有一台空下来,而且好像没有人要玩,我就凑上试试看。 :p

    + +

    看看说明,看看投币孔。一次三十块,蛮贵的。不过只试玩一次,我们还不至於玩不起。和小招凑了三个铜板投进去,继续看说明。隔壁的妈妈开口提醒我,要拿卡片。我看一看,投币孔旁边好像掉出了一张卡片,拿了卡片,没仔细看,继续看那个不大看得懂的游戏说明。这时候,隔壁的妈妈忍不住说了:

    + +
    +

    你们这个样子是没办法玩的,要有衣服才能玩。

    +
    + +

    衣服?喔。我大概知道。我看得出来这是纸娃娃游戏,当然要衣服。可是衣服在哪里呢?去哪里弄衣服?画面出现了两个小女生对话,大意是说,该起床要去参加派对了!可是要参加什么派对呢?出现五个派对可以选:街舞、 Pub 、偶像明星选秀会…等等。我没玩过也看不懂,随便选了街舞。这时隔壁的妈妈再也忍不住了。

    + +
    +

    你们要有参加街舞的衣服才能玩。我帮你们看看…

    +
    + +

    接著,她打开一个本子,一本卡片搜集册,里面一面四张,一页双面八张,大概六七页,加上一堆零散塞不下的卡片,全部大概六、七十张。里面全都是各种帽子、衣服、裤子、鞋子的卡片。我和小招睁大双眼,看傻了。我把手中的卡片翻开来看:一双高跟鞋。原来如此,我终於懂了。每投一次币三十元,就可以获得一张卡片。有适当的衣服卡片,就可以换上适当的衣服。

    + +

    只见隔壁的妈妈,在卡片册里翻来翻去:要参加街舞,要穿哪个好呢?

    + +

    这时,隔壁的小女生终於忍不住插嘴:妈,不对啦,街舞要穿这个!说著,在手上的卡片中,迅速找到帽子、衣服、裤子、鞋子拿给我。我偷瞄了一眼,她手上至少有二、三十张卡片。对她们说声谢谢,拿著借来的卡片,一一刷下去。果然,游戏的主角就换上了很酷的街舞装。一上场,光服装就 157 分,狠狠打败对手。

    + +

    接下来,就是跳舞机的情节了。顺著打节拍,打得好就有高分。托隔壁母女的福,服装拿到了高分,总分轻易就打败了对手。不过下一关偶像明星选秀会,就不好意思再跟人家借卡片了。穿了街舞的衣服去参加偶像明星选秀,光服装就输了一大截,后来就不用说了。

    + +

    为了答谢她们拔刀相助,我们把手上的高跟鞋卡片送给她们。反正我们大概也不会再玩第二次了。

    + +

    回来的路上,我们越想越可怕。那个妈妈手上的集卡册,加上女儿手上的卡片,加起来至少有九十张。投三十元才有一张卡片,那个妈妈至少花了两、三千块钱,才有这样的成果。而且这个游戏要靠集卡才能玩,掉出来的卡片事先无法知道,而且还会碰到重覆。那至少要投入一、两千块钱,才有足够的卡片可以玩。这个游戏真是太、太可怕了。现在的妈妈也真是太可怕了,为小孩花钱都不心软的吗?

    + +

    仔细想想,我们答谢她给她的高跟鞋卡,她大概已经重覆了,不需要吧~

    + +

    小时候我们玩的纸娃娃游戏,二十块钱就有一大本,自己按裁切线割下来,就有几十件衣服、裤子、鞋子、配件,换都换不完。那时候这样就玩得很高兴了。现在玩纸娃娃游戏,三十块钱才有一件,可以花上好几千块钱搜集衣服,钱花得毫不心软,真是难以想像。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 116 | + 117 | + 118 | + 119 | + 120 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0118.html.zh-tw.html b/htdocs/imacat/me/diary/0118.html.zh-tw.html new file mode 120000 index 0000000..02d5bc5 --- /dev/null +++ b/htdocs/imacat/me/diary/0118.html.zh-tw.html @@ -0,0 +1 @@ +0118.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0118.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0118.html.zh-tw.xhtml new file mode 100644 index 0000000..f20e30d --- /dev/null +++ b/htdocs/imacat/me/diary/0118.html.zh-tw.xhtml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百一十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百一十八

    + +
    + +
    + +
    +
    6.21.’07. 3:42am.
    + +

    紙娃娃遊戲

    + +

    星期天下午和小招逛街,逛到忠孝東路 SOGO 的玩具部。我最近又迷上了百貨公司玩具部的玩具,不管是鋼彈的組合模型,還是美泰兒的芭比娃娃,都能讓我看得流連忘返。不過,這天,讓我碰到一件非常震憾的事。

    + +

    在玩具部走著走著,看到女生玩具區,有個角落擺了四台電動玩具,有幾個媽媽帶著小女孩聚在那裏。我一時好奇心起,便湊過去看一看。看了一會,好像是紙娃娃遊戲(給娃娃換各式各樣的衣服),不過好像還有一些變化,看不大懂。這時正好有一台空下來,而且好像沒有人要玩,我就湊上試試看。 :p

    + +

    看看說明,看看投幣孔。一次三十塊,蠻貴的。不過只試玩一次,我們還不至於玩不起。和小招湊了三個銅板投進去,繼續看說明。隔壁的媽媽開口提醒我,要拿卡片。我看一看,投幣孔旁邊好像掉出了一張卡片,拿了卡片,沒仔細看,繼續看那個不大看得懂的遊戲說明。這時候,隔壁的媽媽忍不住說了:

    + +
    +

    妳們這個樣子是沒辦法玩的,要有衣服才能玩。

    +
    + +

    衣服?喔。我大概知道。我看得出來這是紙娃娃遊戲,當然要衣服。可是衣服在哪裏呢?去哪裏弄衣服?畫面出現了兩個小女生對話,大意是說,該起床要去參加派對了!可是要參加什麼派對呢?出現五個派對可以選:街舞、 Pub 、偶像明星選秀會…等等。我沒玩過也看不懂,隨便選了街舞。這時隔壁的媽媽再也忍不住了。

    + +
    +

    妳們要有參加街舞的衣服才能玩。我幫妳們看看…

    +
    + +

    接著,她打開一個本子,一本卡片搜集冊,裏面一面四張,一頁雙面八張,大概六七頁,加上一堆零散塞不下的卡片,全部大概六、七十張。裏面全都是各種帽子、衣服、褲子、鞋子的卡片。我和小招睜大雙眼,看傻了。我把手中的卡片翻開來看:一雙高跟鞋。原來如此,我終於懂了。每投一次幣三十元,就可以獲得一張卡片。有適當的衣服卡片,就可以換上適當的衣服。

    + +

    只見隔壁的媽媽,在卡片冊裏翻來翻去:要參加街舞,要穿哪個好呢?

    + +

    這時,隔壁的小女生終於忍不住插嘴:媽,不對啦,街舞要穿這個!說著,在手上的卡片中,迅速找到帽子、衣服、褲子、鞋子拿給我。我偷瞄了一眼,她手上至少有二、三十張卡片。對她們說聲謝謝,拿著借來的卡片,一一刷下去。果然,遊戲的主角就換上了很酷的街舞裝。一上場,光服裝就 157 分,狠狠打敗對手。

    + +

    接下來,就是跳舞機的情節了。順著打節拍,打得好就有高分。託隔壁母女的福,服裝拿到了高分,總分輕易就打敗了對手。不過下一關偶像明星選秀會,就不好意思再跟人家借卡片了。穿了街舞的衣服去參加偶像明星選秀,光服裝就輸了一大截,後來就不用說了。

    + +

    為了答謝她們拔刀相助,我們把手上的高跟鞋卡片送給她們。反正我們大概也不會再玩第二次了。

    + +

    回來的路上,我們越想越可怕。那個媽媽手上的集卡冊,加上女兒手上的卡片,加起來至少有九十張。投三十元才有一張卡片,那個媽媽至少花了兩、三千塊錢,才有這樣的成果。而且這個遊戲要靠集卡才能玩,掉出來的卡片事先無法知道,而且還會碰到重覆。那至少要投入一、兩千塊錢,才有足夠的卡片可以玩。這個遊戲真是太、太可怕了。現在的媽媽也真是太可怕了,為小孩花錢都不心軟的嗎?

    + +

    仔細想想,我們答謝她給她的高跟鞋卡,她大概已經重覆了,不需要吧~

    + +

    小時候我們玩的紙娃娃遊戲,二十塊錢就有一大本,自己按裁切線割下來,就有幾十件衣服、褲子、鞋子、配件,換都換不完。那時候這樣就玩得很高興了。現在玩紙娃娃遊戲,三十塊錢才有一件,可以花上好幾千塊錢搜集衣服,錢花得毫不心軟,真是難以想像。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 116 | + 117 | + 118 | + 119 | + 120 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0119.html.en.html b/htdocs/imacat/me/diary/0119.html.en.html new file mode 120000 index 0000000..ebc5e2b --- /dev/null +++ b/htdocs/imacat/me/diary/0119.html.en.html @@ -0,0 +1 @@ +0119.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0119.html.en.xhtml b/htdocs/imacat/me/diary/0119.html.en.xhtml new file mode 100644 index 0000000..9e6be72 --- /dev/null +++ b/htdocs/imacat/me/diary/0119.html.en.xhtml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 119 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 119

    + +
    + +
    + +
    +
    6.22.’07. 3:18am.
    + +

    Blade: Trinity 刀鋒戰士 3 三位一體 —出色的演員,薄弱的劇情

    + +
    +Blade: Trinity 刀鋒戰士 3 三位一體
    +

    Blade: Trinity 刀鋒戰士 3 三位一體

    +
    + + + +

    刀鋒戰士 3 三位一體敘敘刀鋒和惠斯勒持續追殺吸血鬼,而追殺吸血鬼引起的大小騷動,卻開始讓市民不滿。媒體上,心理醫生艾嘉文斯和警察局長馬丁維里德不斷討論、抨擊。在一次獵殺中,刀鋒殺死了故意假扮為吸血鬼的人類,過程被側錄並寄到媒體,引起輿論憤怒。警局傾巢而出,圍勦刀鋒和惠斯勒的家,激戰惠斯勒犧牲,刀鋒被捕。警局中,吸血鬼僕人艾嘉文斯醫生、吸血鬼丹妮卡塔蘿、艾許塔蘿、甲哥葛林伍,輪番上陣凌虐刀鋒。就在刀鋒奄奄一息時,一群年輕人突然闖入,救走了刀鋒。原來他們是曾為吸血鬼僕人的漢尼拔、惠斯勒私生女愛碧嘉、德克斯、海吉、盲人女科學家桑莫菲及其小女兒柔伊,組成的夜行幫 (Nightstalkers) 。漢尼拔並告訴刀鋒一個驚人消息:吸血鬼在進行一個終極方案,並因此要喚醒曾為傳說中的吸血鬼德古拉,沉睡在伊拉克,終極的大吸血鬼始祖達克。為求得到更多消息,刀鋒、愛碧嘉、漢尼拔三人闖入吸血鬼僕人艾嘉文斯醫生的診所,不料碰上達克本人,一陣激戰後,漢尼拔受重傷,達克逃逸無蹤。桑莫菲查出吸血鬼的據點生化醫事企業,刀鋒和愛碧嘉闖入後,發現吸血鬼終極方案的真相,竟是大量捕捉沒人關心的流浪漢、落單的人,置入培養液中,作為大規模人血養殖場,以確保吸血鬼食物來源永世無虞。就在刀鋒和愛碧嘉破壞人血養殖場的同時,達克也來到夜行幫的根據地,大肆殺戮,並捉走重傷的漢尼拔與小女孩柔伊。為救漢尼拔和柔依,並為同伴復仇,刀鋒和愛碧嘉,帶著桑莫菲臨終託付的新開發病毒日之星 (DayStar) ,直闖吸血鬼根據地,展開激戰。

    + +

    刀鋒戰士 3 三位一體一開始,就讓人耳目一新:將媒體、輿論的塑造,甚至政治層面拉進來,格局較前兩集大了很多,讓人有像對全民公敵般發展的期待。可惜後來的發展,卻完全不是這個樣子。演了一小段以後,媒體、輿論就又通通都不見了,不管再大的騷動、爆炸,都不見媒體、社會關心。失去了一開始很有發展潛力的格局,淪落為單純的追殺遊戲,讓人頗為失望。

    + +

    刀鋒戰士 3 三位一體的武打動作,則明顯不及刀鋒戰士 2刀鋒戰士 2有甄子丹當武術指導加持,武打動作札實很多,也很好看。可是到了刀鋒戰士 3 三位一體,沒了甄子丹指導,就又全走了樣。仔細看看,會發現武打動作有摔角的影子。尤其是兩個大塊頭甲哥葛林伍和達克的武打動作,更充滿了摔角的招式。查閱過演員名單後,證實了我的猜想:飾演甲哥葛林伍的,是 WWE 的職業摔角手冠軍,綽號 HHH (Triple-H) 的保羅李維斯克。由中國功夫換成職業摔角,武打動作風格的轉變,真的很大。

    + +

    除了拳腳外,刀鋒的日本武士刀和達克的軍刀對打,也讓人不忍卒睹。明明是武士刀和軍刀,好像被當成西洋劍來用一樣,不斷出現挑、撥、刺等等西洋劍特有的使法,讓人很想昏倒。

    + +

    刀鋒戰士 3 三位一體在特效上,吸血鬼灰飛煙滅的方式,遵循前兩集的傳統,不過在細節上,又做得更仔細。前兩集吸血鬼灰飛煙滅後,就沒有了。可是刀鋒戰士 3 三位一體吸血鬼灰飛煙滅後,還會在地上留下餘燼殘灰。同樣的方式,也還能改進得更好。吸血狗的嘴三裂,做得很不錯。尤其是博美狗小精靈,感覺又可愛又可怕,讓人印象深刻。

    + +

    刀鋒戰士 3 三位一體三位一體 (Trinity),好像是指刀鋒、愛碧嘉、漢尼拔三位主角,鼎足而立的樣子。從電影海報上看來,也是如此。

    + +

    刀鋒戰士 3 三位一體裏,愛碧嘉的角色非常搶眼,用弓箭作武器,有一股帥氣的感覺。 ^_*' 愛碧嘉除了一場清洗同伴血跡的沖澡戲以外,沒有什麼賣肉的鏡頭,只有很酷的打鬥,讓人覺得很舒服。尤其出征時一定要帶耳機聽 MP3 的特殊習慣,讓角色的個性非常突出,感覺超酷~ *^_^*

    + +

    不過那場沖澡戲,愛碧嘉身上的血未免太多了吧!漢尼拔真的有那麼多血,沾到愛碧嘉身上嗎?前面的受傷畫面,怎麼看都不像。還是愛碧嘉自己也受傷了?可是更不像啊!

    + +

    刀鋒戰士 3 三位一體劇情明顯有些問題。終極方案人血養殖場,和喚醒達克,到底有什麼關聯?這兩件事,是怎麼湊在一起的?漢尼拔暗示了吸血鬼為了終極方案,需要喚醒達克。但到底關係在哪裏?從頭到尾,都沒有交待。

    + +

    達克從頭到尾都沒有看過惠斯勒,為什麼能變身成惠斯勒的模樣?他是怎麼知道惠斯勒這個人的?又怎麼知道惠斯勒長什麼樣子?

    + +

    桑莫非發現自己會死的時候,死前錄下了一段留言。可是她是在達克突襲時死的,從發現異狀、外出搜索到被達克抓到,怎麼可能有空檔錄下留言?

    + +

    寇德來時,夜行幫基地的自動飛彈防衛系統自動瞄準。有這麼好的東西,為什麼達克突襲時,沒派上用場?

    + +

    而且,為什麼電影都要結束了,夜行幫才突然冒出一個寇德?這也未免太突兀了。

    + +

    刀鋒戰士 3 三位一體整部電影,像是在捧一群年輕新星一樣。這群年輕新星的表現,也確實很不錯:潔西卡碧兒、萊恩雷諾、娜塔夏李歐尼、反派的帕可兒波茜,都非常搶演,演得很有個性。他們其中幾個的是學院或劇團出身的,基本戲劇訓練非常札實。這些年輕演員的亮麗表現,彌補了劇情上的薄弱不足。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 117 | + 118 | + 119 | + 120 | + 121 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0119.html.zh-cn.html b/htdocs/imacat/me/diary/0119.html.zh-cn.html new file mode 120000 index 0000000..097fdfa --- /dev/null +++ b/htdocs/imacat/me/diary/0119.html.zh-cn.html @@ -0,0 +1 @@ +0119.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0119.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0119.html.zh-cn.xhtml new file mode 100644 index 0000000..c0c6d75 --- /dev/null +++ b/htdocs/imacat/me/diary/0119.html.zh-cn.xhtml @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百一十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百一十九

    + +
    + +
    + +
    +
    6.22.’07. 3:18am.
    + +

    Blade: Trinity 刀锋战士 3 三位一体 —出色的演员,薄弱的剧情

    + +
    +Blade: Trinity 刀锋战士 3 三位一体
    +

    Blade: Trinity 刀锋战士 3 三位一体

    +
    + + + +

    刀锋战士 3 三位一体叙叙刀锋和惠斯勒持续追杀吸血鬼,而追杀吸血鬼引起的大小骚动,却开始让市民不满。媒体上,心理医生艾嘉文斯和警察局长马丁维里德不断讨论、抨击。在一次猎杀中,刀锋杀死了故意假扮为吸血鬼的人类,过程被侧录并寄到媒体,引起舆论愤怒。警局倾巢而出,围剿刀锋和惠斯勒的家,激战惠斯勒牺牲,刀锋被捕。警局中,吸血鬼仆人艾嘉文斯医生、吸血鬼丹妮卡塔萝、艾许塔萝、甲哥葛林伍,轮番上阵凌虐刀锋。就在刀锋奄奄一息时,一群年轻人突然闯入,救走了刀锋。原来他们是曾为吸血鬼仆人的汉尼拔、惠斯勒私生女爱碧嘉、德克斯、海吉、盲人女科学家桑莫菲及其小女儿柔伊,组成的夜行帮 (Nightstalkers) 。汉尼拔并告诉刀锋一个惊人消息:吸血鬼在进行一个终极方案,并因此要唤醒曾为传说中的吸血鬼德古拉,沉睡在伊拉克,终极的大吸血鬼始祖达克。为求得到更多消息,刀锋、爱碧嘉、汉尼拔三人闯入吸血鬼仆人艾嘉文斯医生的诊所,不料碰上达克本人,一阵激战后,汉尼拔受重伤,达克逃逸无踪。桑莫菲查出吸血鬼的据点生化医事企业,刀锋和爱碧嘉闯入后,发现吸血鬼终极方案的真相,竟是大量捕捉没人关心的流浪汉、落单的人,置入培养液中,作为大规模人血养殖场,以确保吸血鬼食物来源永世无虞。就在刀锋和爱碧嘉破坏人血养殖场的同时,达克也来到夜行帮的根据地,大肆杀戮,并捉走重伤的汉尼拔与小女孩柔伊。为救汉尼拔和柔依,并为同伴复仇,刀锋和爱碧嘉,带著桑莫菲临终托付的新开发病毒日之星 (DayStar) ,直闯吸血鬼根据地,展开激战。

    + +

    刀锋战士 3 三位一体一开始,就让人耳目一新:将媒体、舆论的塑造,甚至政治层面拉进来,格局较前两集大了很多,让人有像对全民公敌般发展的期待。可惜后来的发展,却完全不是这个样子。演了一小段以后,媒体、舆论就又通通都不见了,不管再大的骚动、爆炸,都不见媒体、社会关心。失去了一开始很有发展潜力的格局,沦落为单纯的追杀游戏,让人颇为失望。

    + +

    刀锋战士 3 三位一体的武打动作,则明显不及刀锋战士 2刀锋战士 2有甄子丹当武术指导加持,武打动作札实很多,也很好看。可是到了刀锋战士 3 三位一体,没了甄子丹指导,就又全走了样。仔细看看,会发现武打动作有摔角的影子。尤其是两个大块头甲哥葛林伍和达克的武打动作,更充满了摔角的招式。查阅过演员名单后,证实了我的猜想:饰演甲哥葛林伍的,是 WWE 的职业摔角手冠军,绰号 HHH (Triple-H) 的保罗李维斯克。由中国功夫换成职业摔角,武打动作风格的转变,真的很大。

    + +

    除了拳脚外,刀锋的日本武士刀和达克的军刀对打,也让人不忍卒睹。明明是武士刀和军刀,好像被当成西洋剑来用一样,不断出现挑、拨、刺等等西洋剑特有的使法,让人很想昏倒。

    + +

    刀锋战士 3 三位一体在特效上,吸血鬼灰飞烟灭的方式,遵循前两集的传统,不过在细节上,又做得更仔细。前两集吸血鬼灰飞烟灭后,就没有了。可是刀锋战士 3 三位一体吸血鬼灰飞烟灭后,还会在地上留下余烬残灰。同样的方式,也还能改进得更好。吸血狗的嘴三裂,做得很不错。尤其是博美狗小精灵,感觉又可爱又可怕,让人印象深刻。

    + +

    刀锋战士 3 三位一体三位一体 (Trinity),好像是指刀锋、爱碧嘉、汉尼拔三位主角,鼎足而立的样子。从电影海报上看来,也是如此。

    + +

    刀锋战士 3 三位一体里,爱碧嘉的角色非常抢眼,用弓箭作武器,有一股帅气的感觉。 ^_*' 爱碧嘉除了一场清洗同伴血迹的冲澡戏以外,没有什么卖肉的镜头,只有很酷的打斗,让人觉得很舒服。尤其出征时一定要带耳机听 MP3 的特殊习惯,让角色的个性非常突出,感觉超酷~ *^_^*

    + +

    不过那场冲澡戏,爱碧嘉身上的血未免太多了吧!汉尼拔真的有那么多血,沾到爱碧嘉身上吗?前面的受伤画面,怎么看都不像。还是爱碧嘉自己也受伤了?可是更不像啊!

    + +

    刀锋战士 3 三位一体剧情明显有些问题。终极方案人血养殖场,和唤醒达克,到底有什么关联?这两件事,是怎么凑在一起的?汉尼拔暗示了吸血鬼为了终极方案,需要唤醒达克。但到底关系在哪里?从头到尾,都没有交待。

    + +

    达克从头到尾都没有看过惠斯勒,为什么能变身成惠斯勒的模样?他是怎么知道惠斯勒这个人的?又怎么知道惠斯勒长什么样子?

    + +

    桑莫非发现自己会死的时候,死前录下了一段留言。可是她是在达克突袭时死的,从发现异状、外出搜索到被达克抓到,怎么可能有空档录下留言?

    + +

    寇德来时,夜行帮基地的自动飞弹防卫系统自动瞄准。有这么好的东西,为什么达克突袭时,没派上用场?

    + +

    而且,为什么电影都要结束了,夜行帮才突然冒出一个寇德?这也未免太突兀了。

    + +

    刀锋战士 3 三位一体整部电影,像是在捧一群年轻新星一样。这群年轻新星的表现,也确实很不错:洁西卡碧儿、莱恩雷诺、娜塔夏李欧尼、反派的帕可儿波茜,都非常抢演,演得很有个性。他们其中几个的是学院或剧团出身的,基本戏剧训练非常札实。这些年轻演员的亮丽表现,弥补了剧情上的薄弱不足。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 117 | + 118 | + 119 | + 120 | + 121 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0119.html.zh-tw.html b/htdocs/imacat/me/diary/0119.html.zh-tw.html new file mode 120000 index 0000000..80c2d89 --- /dev/null +++ b/htdocs/imacat/me/diary/0119.html.zh-tw.html @@ -0,0 +1 @@ +0119.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0119.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0119.html.zh-tw.xhtml new file mode 100644 index 0000000..8fd3cb5 --- /dev/null +++ b/htdocs/imacat/me/diary/0119.html.zh-tw.xhtml @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百一十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百一十九

    + +
    + +
    + +
    +
    6.22.’07. 3:18am.
    + +

    Blade: Trinity 刀鋒戰士 3 三位一體 —出色的演員,薄弱的劇情

    + +
    +Blade: Trinity 刀鋒戰士 3 三位一體
    +

    Blade: Trinity 刀鋒戰士 3 三位一體

    +
    + + + +

    刀鋒戰士 3 三位一體敘敘刀鋒和惠斯勒持續追殺吸血鬼,而追殺吸血鬼引起的大小騷動,卻開始讓市民不滿。媒體上,心理醫生艾嘉文斯和警察局長馬丁維里德不斷討論、抨擊。在一次獵殺中,刀鋒殺死了故意假扮為吸血鬼的人類,過程被側錄並寄到媒體,引起輿論憤怒。警局傾巢而出,圍勦刀鋒和惠斯勒的家,激戰惠斯勒犧牲,刀鋒被捕。警局中,吸血鬼僕人艾嘉文斯醫生、吸血鬼丹妮卡塔蘿、艾許塔蘿、甲哥葛林伍,輪番上陣凌虐刀鋒。就在刀鋒奄奄一息時,一群年輕人突然闖入,救走了刀鋒。原來他們是曾為吸血鬼僕人的漢尼拔、惠斯勒私生女愛碧嘉、德克斯、海吉、盲人女科學家桑莫菲及其小女兒柔伊,組成的夜行幫 (Nightstalkers) 。漢尼拔並告訴刀鋒一個驚人消息:吸血鬼在進行一個終極方案,並因此要喚醒曾為傳說中的吸血鬼德古拉,沉睡在伊拉克,終極的大吸血鬼始祖達克。為求得到更多消息,刀鋒、愛碧嘉、漢尼拔三人闖入吸血鬼僕人艾嘉文斯醫生的診所,不料碰上達克本人,一陣激戰後,漢尼拔受重傷,達克逃逸無蹤。桑莫菲查出吸血鬼的據點生化醫事企業,刀鋒和愛碧嘉闖入後,發現吸血鬼終極方案的真相,竟是大量捕捉沒人關心的流浪漢、落單的人,置入培養液中,作為大規模人血養殖場,以確保吸血鬼食物來源永世無虞。就在刀鋒和愛碧嘉破壞人血養殖場的同時,達克也來到夜行幫的根據地,大肆殺戮,並捉走重傷的漢尼拔與小女孩柔伊。為救漢尼拔和柔依,並為同伴復仇,刀鋒和愛碧嘉,帶著桑莫菲臨終託付的新開發病毒日之星 (DayStar) ,直闖吸血鬼根據地,展開激戰。

    + +

    刀鋒戰士 3 三位一體一開始,就讓人耳目一新:將媒體、輿論的塑造,甚至政治層面拉進來,格局較前兩集大了很多,讓人有像對全民公敵般發展的期待。可惜後來的發展,卻完全不是這個樣子。演了一小段以後,媒體、輿論就又通通都不見了,不管再大的騷動、爆炸,都不見媒體、社會關心。失去了一開始很有發展潛力的格局,淪落為單純的追殺遊戲,讓人頗為失望。

    + +

    刀鋒戰士 3 三位一體的武打動作,則明顯不及刀鋒戰士 2刀鋒戰士 2有甄子丹當武術指導加持,武打動作札實很多,也很好看。可是到了刀鋒戰士 3 三位一體,沒了甄子丹指導,就又全走了樣。仔細看看,會發現武打動作有摔角的影子。尤其是兩個大塊頭甲哥葛林伍和達克的武打動作,更充滿了摔角的招式。查閱過演員名單後,證實了我的猜想:飾演甲哥葛林伍的,是 WWE 的職業摔角手冠軍,綽號 HHH (Triple-H) 的保羅李維斯克。由中國功夫換成職業摔角,武打動作風格的轉變,真的很大。

    + +

    除了拳腳外,刀鋒的日本武士刀和達克的軍刀對打,也讓人不忍卒睹。明明是武士刀和軍刀,好像被當成西洋劍來用一樣,不斷出現挑、撥、刺等等西洋劍特有的使法,讓人很想昏倒。

    + +

    刀鋒戰士 3 三位一體在特效上,吸血鬼灰飛煙滅的方式,遵循前兩集的傳統,不過在細節上,又做得更仔細。前兩集吸血鬼灰飛煙滅後,就沒有了。可是刀鋒戰士 3 三位一體吸血鬼灰飛煙滅後,還會在地上留下餘燼殘灰。同樣的方式,也還能改進得更好。吸血狗的嘴三裂,做得很不錯。尤其是博美狗小精靈,感覺又可愛又可怕,讓人印象深刻。

    + +

    刀鋒戰士 3 三位一體三位一體 (Trinity),好像是指刀鋒、愛碧嘉、漢尼拔三位主角,鼎足而立的樣子。從電影海報上看來,也是如此。

    + +

    刀鋒戰士 3 三位一體裏,愛碧嘉的角色非常搶眼,用弓箭作武器,有一股帥氣的感覺。 ^_*' 愛碧嘉除了一場清洗同伴血跡的沖澡戲以外,沒有什麼賣肉的鏡頭,只有很酷的打鬥,讓人覺得很舒服。尤其出征時一定要帶耳機聽 MP3 的特殊習慣,讓角色的個性非常突出,感覺超酷~ *^_^*

    + +

    不過那場沖澡戲,愛碧嘉身上的血未免太多了吧!漢尼拔真的有那麼多血,沾到愛碧嘉身上嗎?前面的受傷畫面,怎麼看都不像。還是愛碧嘉自己也受傷了?可是更不像啊!

    + +

    刀鋒戰士 3 三位一體劇情明顯有些問題。終極方案人血養殖場,和喚醒達克,到底有什麼關聯?這兩件事,是怎麼湊在一起的?漢尼拔暗示了吸血鬼為了終極方案,需要喚醒達克。但到底關係在哪裏?從頭到尾,都沒有交待。

    + +

    達克從頭到尾都沒有看過惠斯勒,為什麼能變身成惠斯勒的模樣?他是怎麼知道惠斯勒這個人的?又怎麼知道惠斯勒長什麼樣子?

    + +

    桑莫非發現自己會死的時候,死前錄下了一段留言。可是她是在達克突襲時死的,從發現異狀、外出搜索到被達克抓到,怎麼可能有空檔錄下留言?

    + +

    寇德來時,夜行幫基地的自動飛彈防衛系統自動瞄準。有這麼好的東西,為什麼達克突襲時,沒派上用場?

    + +

    而且,為什麼電影都要結束了,夜行幫才突然冒出一個寇德?這也未免太突兀了。

    + +

    刀鋒戰士 3 三位一體整部電影,像是在捧一群年輕新星一樣。這群年輕新星的表現,也確實很不錯:潔西卡碧兒、萊恩雷諾、娜塔夏李歐尼、反派的帕可兒波茜,都非常搶演,演得很有個性。他們其中幾個的是學院或劇團出身的,基本戲劇訓練非常札實。這些年輕演員的亮麗表現,彌補了劇情上的薄弱不足。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 117 | + 118 | + 119 | + 120 | + 121 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0120.html.en.html b/htdocs/imacat/me/diary/0120.html.en.html new file mode 120000 index 0000000..6d1217c --- /dev/null +++ b/htdocs/imacat/me/diary/0120.html.en.html @@ -0,0 +1 @@ +0120.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0120.html.en.xhtml b/htdocs/imacat/me/diary/0120.html.en.xhtml new file mode 100644 index 0000000..3cf942f --- /dev/null +++ b/htdocs/imacat/me/diary/0120.html.en.xhtml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 120 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 120

    + +
    + +
    + +
    +
    6.30.’07. 2:20pm.
    + +

    維基百科偽基百科

    + +

    這兩天在偽基百科上,寫了咕狗餓死咕狗阿桑按兩下等等噹噹噹噹噹噹五個辭條,又在維基百科上寫了DoubleClick辭條。

    + +

    覺得偽基百科雖然有些蠻好笑的,可是不好笑的更多,而且很下流。有很多辭條都看不懂,什麼飛來飛去外星人的,誰有跟誰怎樣怎樣的,看得霧煞煞,亂成一團。好像只是為了充字數而惡搞,寫出來的東西超難看。真正好笑的東西,以事實為基礎,偷渡一些虛構或是嘲諷的觀點,夾雜在虛幻和真實之間,讓知道事實的人,不意間會心一笑。像那種從頭到尾都是胡掰的,明明沒有什麼大事,卻要從盤谷開天闢地開始,洋洋灑灑幾十萬無關的字,為充字數而寫,就真的很難看了。

    + +

    而且偽基百科實在是太下流了。不管什麼辭條都是中出、正太的,看久了很噁心。

    + +
    + +
    + +
    +
    6.24.’07. 1:22am.
    + +

    研究生與漫畫家

    + +

    根據我的研究觀察發現,研究生與漫畫家,其實非常相似。相似之處如下:

    + +
      +
    • 開始動筆的日期,永遠都是交稿期限的最後一天。
    • +
    • 每天都有不同的理由拖稿。
    • +
    • 每天都在取材中。
    • +
    • 一動筆一定會開始頭痛,腰痛,肚子痛,全身不舒服,需要立刻休息。
    • +
    + +

    由上可知,研究生與漫畫家,幾乎是完全相同的生物。兩者唯一的不同處在於,漫畫家有責任編輯,就算被怨恨到死,也會硬押著漫畫家把稿子畫完。研究生沒有責任編輯,沒有人能拿她們有辦法。

    + +
    + +
    + +
    +
    6.23.’07. 3:10am.
    + +

    皇天后土的血腥惡夢

    + +

    小時候,我常常做很血腥的惡夢。印象最深的是,夢到親人拿菜刀把自己的頭切半,鮮血泉湧,邊切還邊跟我說話,我嚇得腿軟,無法逃走。光這個惡夢就做了好幾次。還有其它各式各樣的血腥惡夢,多到記不清楚。

    + +

    我一直不知道我為什麼很容易做這種血腥的惡夢。我從小不愛看恐怖片,電視上看到鬼片、驚悚懸疑鏡頭就轉台。開始看恐怖片是在春暉當影片編譯時,做七月鬼片特輯。但那都是長大以後的事了。從不看恐怖片的我,小時候到底是哪裏得來這種血腥、恐怖的印象,我一直不知道。有好一陣子,我還懷疑自己潛意識裏是不是很血腥變態,害怕自己是不是潛在的變態殺人魔。

    + +

    今晚和小招閒聊,又回阿光的留言,突然發現原因了。我想,應該是電影皇天后土害的。

    + +

    國小一、二年級的時候,我在臺北唸小學。那時候一有政治宣導片,政府就會規定全國各國中、小學要帶全校師生去看,以培養愛國情操。好幾次,學校宣佈今天看電影,然後由老師帶著,全班排著隊,從學校走到電影院,看完電影再排隊走回去,回去還要寫心得報告。記得那時看了碧血黃花 (1979)皇天后土 (1980)等等。小學一年級看的碧血黃花 (1979)講的是黃花崗七十二烈士,小學二年級看的皇天后土 (1980)則是講文化大革命。國小一、二年級的小孩子,哪裏看得懂什麼劇情?不過黃花崗七十二烈士課本有學過,心得就照課本學的寫,一定會寫。交出去的心得,其實和電影沒有什麼關係。

    + +

    碧血黃花還好,看不懂,答答答一堆槍聲就演完了。不過描寫文革的皇天后土就很可怕了。有一場大批鬥的戲,在一個大禮堂裏,幾百人殺成一團。其中一幕,一個人把另一個人的頭往牆上撞去,就撞死了,屍體黏在牆上,慢慢貼著牆滑下來,牆上留下大片的血印。國小二年級的我,嚇都嚇死了,血腥的畫面,留在腦海中揮之不去。好幾年過去了,腦中還是常常會想到那個畫面,血腥恐怖的印象,就這樣深植在記憶深處。

    + +

    我已經不記得皇天后土的劇情了,只有這一幕,到現在我還記得。現在回頭想想,就是那個血腥的恐怖記憶,讓我開始長期做各式各樣的血腥惡夢。

    + +

    當然,我現在不會害怕那種程度的血腥畫面了。再怎麼說,我都是大人了。不過從現在的角度來看,皇天后土裏暴力血腥的畫面,應該列為限制級,怎麼可以給小孩子看?更何況是規定全國的小孩子都要去看!國民政府還真不是普通的變態,竟然叫小孩子去看那種東西。用現代的標準,給小孩子這種看暴力血腥的電影,已經是犯罪行為了。小孩子看不懂劇情,根本沒有學到什麼愛國情操,心靈中留下的,只有揮之不去的血腥惡夢。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 118 | + 119 | + 120 | + 121 | + 122 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0120.html.zh-cn.html b/htdocs/imacat/me/diary/0120.html.zh-cn.html new file mode 120000 index 0000000..38a0ce8 --- /dev/null +++ b/htdocs/imacat/me/diary/0120.html.zh-cn.html @@ -0,0 +1 @@ +0120.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0120.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0120.html.zh-cn.xhtml new file mode 100644 index 0000000..98a18fb --- /dev/null +++ b/htdocs/imacat/me/diary/0120.html.zh-cn.xhtml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百二十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百二十

    + +
    + +
    + +
    +
    6.30.’07. 2:20pm.
    + +

    维基百科伪基百科

    + +

    这两天在伪基百科上,写了咕狗饿死咕狗阿桑按两下等等当当当当当当五个辞条,又在维基百科上写了DoubleClick辞条。

    + +

    觉得伪基百科虽然有些蛮好笑的,可是不好笑的更多,而且很下流。有很多辞条都看不懂,什么飞来飞去外星人的,谁有跟谁怎样怎样的,看得雾煞煞,乱成一团。好像只是为了充字数而恶搞,写出来的东西超难看。真正好笑的东西,以事实为基础,偷渡一些虚构或是嘲讽的观点,夹杂在虚幻和真实之间,让知道事实的人,不意间会心一笑。像那种从头到尾都是胡掰的,明明没有什么大事,却要从盘谷开天辟地开始,洋洋洒洒几十万无关的字,为充字数而写,就真的很难看了。

    + +

    而且伪基百科实在是太下流了。不管什么辞条都是中出、正太的,看久了很恶心。

    + +
    + +
    + +
    +
    6.24.’07. 1:22am.
    + +

    研究生与漫画家

    + +

    根据我的研究观察发现,研究生与漫画家,其实非常相似。相似之处如下:

    + +
      +
    • 开始动笔的日期,永远都是交稿期限的最后一天。
    • +
    • 每天都有不同的理由拖稿。
    • +
    • 每天都在取材中。
    • +
    • 一动笔一定会开始头痛,腰痛,肚子痛,全身不舒服,需要立刻休息。
    • +
    + +

    由上可知,研究生与漫画家,几乎是完全相同的生物。两者唯一的不同处在於,漫画家有责任编辑,就算被怨恨到死,也会硬押著漫画家把稿子画完。研究生没有责任编辑,没有人能拿她们有办法。

    + +
    + +
    + +
    +
    6.23.’07. 3:10am.
    + +

    皇天后土的血腥恶梦

    + +

    小时候,我常常做很血腥的恶梦。印象最深的是,梦到亲人拿菜刀把自己的头切半,鲜血泉涌,边切还边跟我说话,我吓得腿软,无法逃走。光这个恶梦就做了好几次。还有其它各式各样的血腥恶梦,多到记不清楚。

    + +

    我一直不知道我为什么很容易做这种血腥的恶梦。我从小不爱看恐怖片,电视上看到鬼片、惊悚悬疑镜头就转台。开始看恐怖片是在春晖当影片编译时,做七月鬼片特辑。但那都是长大以后的事了。从不看恐怖片的我,小时候到底是哪里得来这种血腥、恐怖的印象,我一直不知道。有好一阵子,我还怀疑自己潜意识里是不是很血腥变态,害怕自己是不是潜在的变态杀人魔。

    + +

    今晚和小招闲聊,又回阿光的留言,突然发现原因了。我想,应该是电影皇天后土害的。

    + +

    国小一、二年级的时候,我在台北念小学。那时候一有政治宣导片,政府就会规定全国各国中、小学要带全校师生去看,以培养爱国情操。好几次,学校宣布今天看电影,然后由老师带著,全班排著队,从学校走到电影院,看完电影再排队走回去,回去还要写心得报告。记得那时看了碧血黄花 (1979)皇天后土 (1980)等等。小学一年级看的碧血黄花 (1979)讲的是黄花岗七十二烈士,小学二年级看的皇天后土 (1980)则是讲文化大革命。国小一、二年级的小孩子,哪里看得懂什么剧情?不过黄花岗七十二烈士课本有学过,心得就照课本学的写,一定会写。交出去的心得,其实和电影没有什么关系。

    + +

    碧血黄花还好,看不懂,答答答一堆枪声就演完了。不过描写文革的皇天后土就很可怕了。有一场大批斗的戏,在一个大礼堂里,几百人杀成一团。其中一幕,一个人把另一个人的头往墙上撞去,就撞死了,尸体黏在墙上,慢慢贴著墙滑下来,墙上留下大片的血印。国小二年级的我,吓都吓死了,血腥的画面,留在脑海中挥之不去。好几年过去了,脑中还是常常会想到那个画面,血腥恐怖的印象,就这样深植在记忆深处。

    + +

    我已经不记得皇天后土的剧情了,只有这一幕,到现在我还记得。现在回头想想,就是那个血腥的恐怖记忆,让我开始长期做各式各样的血腥恶梦。

    + +

    当然,我现在不会害怕那种程度的血腥画面了。再怎么说,我都是大人了。不过从现在的角度来看,皇天后土里暴力血腥的画面,应该列为限制级,怎么可以给小孩子看?更何况是规定全国的小孩子都要去看!国民政府还真不是普通的变态,竟然叫小孩子去看那种东西。用现代的标准,给小孩子这种看暴力血腥的电影,已经是犯罪行为了。小孩子看不懂剧情,根本没有学到什么爱国情操,心灵中留下的,只有挥之不去的血腥恶梦。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 118 | + 119 | + 120 | + 121 | + 122 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0120.html.zh-tw.html b/htdocs/imacat/me/diary/0120.html.zh-tw.html new file mode 120000 index 0000000..507a207 --- /dev/null +++ b/htdocs/imacat/me/diary/0120.html.zh-tw.html @@ -0,0 +1 @@ +0120.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0120.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0120.html.zh-tw.xhtml new file mode 100644 index 0000000..6392c9b --- /dev/null +++ b/htdocs/imacat/me/diary/0120.html.zh-tw.xhtml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百二十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百二十

    + +
    + +
    + +
    +
    6.30.’07. 2:20pm.
    + +

    維基百科偽基百科

    + +

    這兩天在偽基百科上,寫了咕狗餓死咕狗阿桑按兩下等等噹噹噹噹噹噹五個辭條,又在維基百科上寫了DoubleClick辭條。

    + +

    覺得偽基百科雖然有些蠻好笑的,可是不好笑的更多,而且很下流。有很多辭條都看不懂,什麼飛來飛去外星人的,誰有跟誰怎樣怎樣的,看得霧煞煞,亂成一團。好像只是為了充字數而惡搞,寫出來的東西超難看。真正好笑的東西,以事實為基礎,偷渡一些虛構或是嘲諷的觀點,夾雜在虛幻和真實之間,讓知道事實的人,不意間會心一笑。像那種從頭到尾都是胡掰的,明明沒有什麼大事,卻要從盤谷開天闢地開始,洋洋灑灑幾十萬無關的字,為充字數而寫,就真的很難看了。

    + +

    而且偽基百科實在是太下流了。不管什麼辭條都是中出、正太的,看久了很噁心。

    + +
    + +
    + +
    +
    6.24.’07. 1:22am.
    + +

    研究生與漫畫家

    + +

    根據我的研究觀察發現,研究生與漫畫家,其實非常相似。相似之處如下:

    + +
      +
    • 開始動筆的日期,永遠都是交稿期限的最後一天。
    • +
    • 每天都有不同的理由拖稿。
    • +
    • 每天都在取材中。
    • +
    • 一動筆一定會開始頭痛,腰痛,肚子痛,全身不舒服,需要立刻休息。
    • +
    + +

    由上可知,研究生與漫畫家,幾乎是完全相同的生物。兩者唯一的不同處在於,漫畫家有責任編輯,就算被怨恨到死,也會硬押著漫畫家把稿子畫完。研究生沒有責任編輯,沒有人能拿她們有辦法。

    + +
    + +
    + +
    +
    6.23.’07. 3:10am.
    + +

    皇天后土的血腥惡夢

    + +

    小時候,我常常做很血腥的惡夢。印象最深的是,夢到親人拿菜刀把自己的頭切半,鮮血泉湧,邊切還邊跟我說話,我嚇得腿軟,無法逃走。光這個惡夢就做了好幾次。還有其它各式各樣的血腥惡夢,多到記不清楚。

    + +

    我一直不知道我為什麼很容易做這種血腥的惡夢。我從小不愛看恐怖片,電視上看到鬼片、驚悚懸疑鏡頭就轉台。開始看恐怖片是在春暉當影片編譯時,做七月鬼片特輯。但那都是長大以後的事了。從不看恐怖片的我,小時候到底是哪裏得來這種血腥、恐怖的印象,我一直不知道。有好一陣子,我還懷疑自己潛意識裏是不是很血腥變態,害怕自己是不是潛在的變態殺人魔。

    + +

    今晚和小招閒聊,又回阿光的留言,突然發現原因了。我想,應該是電影皇天后土害的。

    + +

    國小一、二年級的時候,我在臺北唸小學。那時候一有政治宣導片,政府就會規定全國各國中、小學要帶全校師生去看,以培養愛國情操。好幾次,學校宣佈今天看電影,然後由老師帶著,全班排著隊,從學校走到電影院,看完電影再排隊走回去,回去還要寫心得報告。記得那時看了碧血黃花 (1979)皇天后土 (1980)等等。小學一年級看的碧血黃花 (1979)講的是黃花崗七十二烈士,小學二年級看的皇天后土 (1980)則是講文化大革命。國小一、二年級的小孩子,哪裏看得懂什麼劇情?不過黃花崗七十二烈士課本有學過,心得就照課本學的寫,一定會寫。交出去的心得,其實和電影沒有什麼關係。

    + +

    碧血黃花還好,看不懂,答答答一堆槍聲就演完了。不過描寫文革的皇天后土就很可怕了。有一場大批鬥的戲,在一個大禮堂裏,幾百人殺成一團。其中一幕,一個人把另一個人的頭往牆上撞去,就撞死了,屍體黏在牆上,慢慢貼著牆滑下來,牆上留下大片的血印。國小二年級的我,嚇都嚇死了,血腥的畫面,留在腦海中揮之不去。好幾年過去了,腦中還是常常會想到那個畫面,血腥恐怖的印象,就這樣深植在記憶深處。

    + +

    我已經不記得皇天后土的劇情了,只有這一幕,到現在我還記得。現在回頭想想,就是那個血腥的恐怖記憶,讓我開始長期做各式各樣的血腥惡夢。

    + +

    當然,我現在不會害怕那種程度的血腥畫面了。再怎麼說,我都是大人了。不過從現在的角度來看,皇天后土裏暴力血腥的畫面,應該列為限制級,怎麼可以給小孩子看?更何況是規定全國的小孩子都要去看!國民政府還真不是普通的變態,竟然叫小孩子去看那種東西。用現代的標準,給小孩子這種看暴力血腥的電影,已經是犯罪行為了。小孩子看不懂劇情,根本沒有學到什麼愛國情操,心靈中留下的,只有揮之不去的血腥惡夢。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 118 | + 119 | + 120 | + 121 | + 122 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0121.html.en.html b/htdocs/imacat/me/diary/0121.html.en.html new file mode 120000 index 0000000..8914cf3 --- /dev/null +++ b/htdocs/imacat/me/diary/0121.html.en.html @@ -0,0 +1 @@ +0121.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0121.html.en.xhtml b/htdocs/imacat/me/diary/0121.html.en.xhtml new file mode 100644 index 0000000..fc060e6 --- /dev/null +++ b/htdocs/imacat/me/diary/0121.html.en.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 121 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 121

    + +
    + +
    + +
    +
    8.3.’07. 1:02pm.
    + +

    Wii

    + +

    旅行社的老媽,去帶了一團 Wii 平行輸入團,全團一人帶三台 Wii 回來。她自己也帶了三台,賣掉了兩台,一台自己留下來玩。不過說自己留下來玩,也只是說說而已。過了三個月了,偶爾回高雄看,除了電源接上外,也沒看到她有動到一點。每次催她花錢買了的東西就要接上去用,不要浪費錢買 Wii 當裝飾品,她也都把我的話當耳邊風。

    + +

    上次回去,她們不在家,我自己動手組來玩,還蠻好玩的,大大改變我的想法。 WiiSport 感覺真的很棒,如果每天玩個半小時,就當是養成運動的習慣,對成天在電腦前面工作,苦無時間去運動的我,是很好的改變。於是手上開始存錢,準備自己也去買一台來玩。

    + +

    幾個月來,看我媽都完全不碰,我乾脆跟她買下來,趁我這兩天回高雄的機會,帶上台北。其實搞不好我該把它留在高雄的。我媽也缺少運動。我需要運動,我媽又何嘗不需要呢?只是留在高雄,沒有我每天開機,搞不好又沒有人會去碰,白白浪費掉。

    + +

    這兩天帶上來後,上網又找了一些順手帶上來的遊戲的資料,才發現原來那個兔子吵得半死的遊戲,是頂頂大名的雷射超人:瘋狂兔子 ラビッツ・パーティー Rayman Raving Rabbids,網路上簡稱雷曼兔。還真的很有趣說。一堆好玩的小遊戲集合,裏面還有我喜歡的跳舞機。主角感覺很普通,不過又醜又可愛又可恨的一群煩死人的兔子,蹦來蹦去的,很可愛又有趣。聽說這是 Wii 上的第一款遊戲。花了幾天把它十五天的牢獄關卡全部破完了,真的很好玩呢~

    + +

    我也找到了電視上說的那款勇者鬥惡龍 神劍 假面女王與鏡之塔 ドラゴンクエストソード 仮面の女王と鏡の塔 Dragon Quest Swords: The Masked Queen and the Tower of Mirrors,想感受一下 Wii 用劍揮砍的快感。不過看不懂日文,在城裏走了半天也找不到地方砍,一下子就感覺到無趣了。我好像應該去找英文版才對,至少看得懂。 ^_*'

    + +

    就這樣,我也成了 Wii 一族了,耶~這是我這輩子的第一台電視遊樂器。我還以為我第一台電視遊樂器會是 PS3 說,沒想到是 Wii 。不知道真・三國無双 3 猛将伝什麼時候會出 Wii 版呢?期待中~

    + +
    + +
    + +
    +
    7.16.’07. 4:13am.
    + +

    亂罵無效

    + +

    讀了昨天 (2007-07-14) 蘋果日報的社論亂罵無效,頗有所感。

    + +

    這一陣子蘋果日報又改版,模仿部落格的格式,把讀者新聞評論接在新聞主文之下。這是好事,讓讀者的討論更熱烈,能見度更高。

    + +

    我追蹤了幾天讀者的蘋論,發現了一些蠻可笑的事。舉例來說,今天 (2007-07-14) 蘋果的社會版頭條性虐女友 打凹鋁球棒,大家不妨猜猜看,讀者認為這件事是誰的錯呢?

    + +
      +
    1. 陳水扁/民進黨
    2. +
    3. 馬英九/國民黨
    4. +
    5. 被打死的女人
    6. +
    + +

    說來說去,怪天怪地怪東怪西,怪政客怪媒體怪被害人,就是不是兇手的錯。

    + +

    我無意為自由主義個人主義辯護。但是為什麼犯罪事件,最大的錯不是兇手,而是政客,而是被害人呢?換個政黨執政,換個政客,犯罪就會消失嗎?現代社會犯罪是不可能消失的。我們可以藉制度的設計來降低犯罪發生的比率和數量。但無論如何,一旦發生了,殺人就是殺人者的錯。這是天經地義的事。沒有人叫兇手去殺人,殺人是兇手自己的自主行動。不管陳水扁、馬英九還是被害者,都不是兇手的藉口。

    + +

    臺灣社會真的很瘋狂。不管什麼事,怪天怪地怪東怪西,不是陳水扁/民進黨的錯,就是馬英九/國民黨的錯,不然就是受害者的錯。什麼事都罵政客,行為人完全沒有責任。彷彿政客真的那麼了不起,要給全世界的所有人把屎把尿通通一把抓一樣,人民真的那麼弱小無助,連撒尿拉屎都是政客的責任和義務一樣。反正行為人就是沒有錯,錯的都是這個萬惡的執政黨,萬惡的在野黨,萬惡的媒體,愚蠢的被害人。真是夠了。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 119 | + 120 | + 121 | + 122 | + 123 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0121.html.zh-cn.html b/htdocs/imacat/me/diary/0121.html.zh-cn.html new file mode 120000 index 0000000..f6364c1 --- /dev/null +++ b/htdocs/imacat/me/diary/0121.html.zh-cn.html @@ -0,0 +1 @@ +0121.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0121.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0121.html.zh-cn.xhtml new file mode 100644 index 0000000..fbe260d --- /dev/null +++ b/htdocs/imacat/me/diary/0121.html.zh-cn.xhtml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百二十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百二十一

    + +
    + +
    + +
    +
    8.3.’07. 1:02pm.
    + +

    Wii

    + +

    旅行社的老妈,去带了一团 Wii 平行输入团,全团一人带三台 Wii 回来。她自己也带了三台,卖掉了两台,一台自己留下来玩。不过说自己留下来玩,也只是说说而已。过了三个月了,偶尔回高雄看,除了电源接上外,也没看到她有动到一点。每次催她花钱买了的东西就要接上去用,不要浪费钱买 Wii 当装饰品,她也都把我的话当耳边风。

    + +

    上次回去,她们不在家,我自己动手组来玩,还蛮好玩的,大大改变我的想法。 WiiSport 感觉真的很棒,如果每天玩个半小时,就当是养成运动的习惯,对成天在电脑前面工作,苦无时间去运动的我,是很好的改变。於是手上开始存钱,准备自己也去买一台来玩。

    + +

    几个月来,看我妈都完全不碰,我干脆跟她买下来,趁我这两天回高雄的机会,带上台北。其实搞不好我该把它留在高雄的。我妈也缺少运动。我需要运动,我妈又何尝不需要呢?只是留在高雄,没有我每天开机,搞不好又没有人会去碰,白白浪费掉。

    + +

    这两天带上来后,上网又找了一些顺手带上来的游戏的资料,才发现原来那个兔子吵得半死的游戏,是顶顶大名的雷射超人:疯狂兔子 ラビッツ・パーティー Rayman Raving Rabbids,网路上简称雷曼兔。还真的很有趣说。一堆好玩的小游戏集合,里面还有我喜欢的跳舞机。主角感觉很普通,不过又丑又可爱又可恨的一群烦死人的兔子,蹦来蹦去的,很可爱又有趣。听说这是 Wii 上的第一款游戏。花了几天把它十五天的牢狱关卡全部破完了,真的很好玩呢~

    + +

    我也找到了电视上说的那款勇者斗恶龙 神剑 假面女王与镜之塔 ドラゴンクエストソード 仮面の女王と镜の塔 Dragon Quest Swords: The Masked Queen and the Tower of Mirrors,想感受一下 Wii 用剑挥砍的快感。不过看不懂日文,在城里走了半天也找不到地方砍,一下子就感觉到无趣了。我好像应该去找英文版才对,至少看得懂。 ^_*'

    + +

    就这样,我也成了 Wii 一族了,耶~这是我这辈子的第一台电视游乐器。我还以为我第一台电视游乐器会是 PS3 说,没想到是 Wii 。不知道真・三国无双 3 猛将伝什么时候会出 Wii 版呢?期待中~

    + +
    + +
    + +
    +
    7.16.’07. 4:13am.
    + +

    乱骂无效

    + +

    读了昨天 (2007-07-14) 苹果日报的社论乱骂无效,颇有所感。

    + +

    这一阵子苹果日报又改版,模仿部落格的格式,把读者新闻评论接在新闻主文之下。这是好事,让读者的讨论更热烈,能见度更高。

    + +

    我追踪了几天读者的苹论,发现了一些蛮可笑的事。举例来说,今天 (2007-07-14) 苹果的社会版头条性虐女友 打凹铝球棒,大家不妨猜猜看,读者认为这件事是谁的错呢?

    + +
      +
    1. 陈水扁/民进党
    2. +
    3. 马英九/国民党
    4. +
    5. 被打死的女人
    6. +
    + +

    说来说去,怪天怪地怪东怪西,怪政客怪媒体怪被害人,就是不是凶手的错。

    + +

    我无意为自由主义个人主义辩护。但是为什么犯罪事件,最大的错不是凶手,而是政客,而是被害人呢?换个政党执政,换个政客,犯罪就会消失吗?现代社会犯罪是不可能消失的。我们可以藉制度的设计来降低犯罪发生的比率和数量。但无论如何,一旦发生了,杀人就是杀人者的错。这是天经地义的事。没有人叫凶手去杀人,杀人是凶手自己的自主行动。不管陈水扁、马英九还是被害者,都不是凶手的藉口。

    + +

    台湾社会真的很疯狂。不管什么事,怪天怪地怪东怪西,不是陈水扁/民进党的错,就是马英九/国民党的错,不然就是受害者的错。什么事都骂政客,行为人完全没有责任。彷佛政客真的那么了不起,要给全世界的所有人把屎把尿通通一把抓一样,人民真的那么弱小无助,连撒尿拉屎都是政客的责任和义务一样。反正行为人就是没有错,错的都是这个万恶的执政党,万恶的在野党,万恶的媒体,愚蠢的被害人。真是够了。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 119 | + 120 | + 121 | + 122 | + 123 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0121.html.zh-tw.html b/htdocs/imacat/me/diary/0121.html.zh-tw.html new file mode 120000 index 0000000..21092e9 --- /dev/null +++ b/htdocs/imacat/me/diary/0121.html.zh-tw.html @@ -0,0 +1 @@ +0121.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0121.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0121.html.zh-tw.xhtml new file mode 100644 index 0000000..57444d1 --- /dev/null +++ b/htdocs/imacat/me/diary/0121.html.zh-tw.xhtml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百二十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百二十一

    + +
    + +
    + +
    +
    8.3.’07. 1:02pm.
    + +

    Wii

    + +

    旅行社的老媽,去帶了一團 Wii 平行輸入團,全團一人帶三台 Wii 回來。她自己也帶了三台,賣掉了兩台,一台自己留下來玩。不過說自己留下來玩,也只是說說而已。過了三個月了,偶爾回高雄看,除了電源接上外,也沒看到她有動到一點。每次催她花錢買了的東西就要接上去用,不要浪費錢買 Wii 當裝飾品,她也都把我的話當耳邊風。

    + +

    上次回去,她們不在家,我自己動手組來玩,還蠻好玩的,大大改變我的想法。 WiiSport 感覺真的很棒,如果每天玩個半小時,就當是養成運動的習慣,對成天在電腦前面工作,苦無時間去運動的我,是很好的改變。於是手上開始存錢,準備自己也去買一台來玩。

    + +

    幾個月來,看我媽都完全不碰,我乾脆跟她買下來,趁我這兩天回高雄的機會,帶上台北。其實搞不好我該把它留在高雄的。我媽也缺少運動。我需要運動,我媽又何嘗不需要呢?只是留在高雄,沒有我每天開機,搞不好又沒有人會去碰,白白浪費掉。

    + +

    這兩天帶上來後,上網又找了一些順手帶上來的遊戲的資料,才發現原來那個兔子吵得半死的遊戲,是頂頂大名的雷射超人:瘋狂兔子 ラビッツ・パーティー Rayman Raving Rabbids,網路上簡稱雷曼兔。還真的很有趣說。一堆好玩的小遊戲集合,裏面還有我喜歡的跳舞機。主角感覺很普通,不過又醜又可愛又可恨的一群煩死人的兔子,蹦來蹦去的,很可愛又有趣。聽說這是 Wii 上的第一款遊戲。花了幾天把它十五天的牢獄關卡全部破完了,真的很好玩呢~

    + +

    我也找到了電視上說的那款勇者鬥惡龍 神劍 假面女王與鏡之塔 ドラゴンクエストソード 仮面の女王と鏡の塔 Dragon Quest Swords: The Masked Queen and the Tower of Mirrors,想感受一下 Wii 用劍揮砍的快感。不過看不懂日文,在城裏走了半天也找不到地方砍,一下子就感覺到無趣了。我好像應該去找英文版才對,至少看得懂。 ^_*'

    + +

    就這樣,我也成了 Wii 一族了,耶~這是我這輩子的第一台電視遊樂器。我還以為我第一台電視遊樂器會是 PS3 說,沒想到是 Wii 。不知道真・三國無双 3 猛将伝什麼時候會出 Wii 版呢?期待中~

    + +
    + +
    + +
    +
    7.16.’07. 4:13am.
    + +

    亂罵無效

    + +

    讀了昨天 (2007-07-14) 蘋果日報的社論亂罵無效,頗有所感。

    + +

    這一陣子蘋果日報又改版,模仿部落格的格式,把讀者新聞評論接在新聞主文之下。這是好事,讓讀者的討論更熱烈,能見度更高。

    + +

    我追蹤了幾天讀者的蘋論,發現了一些蠻可笑的事。舉例來說,今天 (2007-07-14) 蘋果的社會版頭條性虐女友 打凹鋁球棒,大家不妨猜猜看,讀者認為這件事是誰的錯呢?

    + +
      +
    1. 陳水扁/民進黨
    2. +
    3. 馬英九/國民黨
    4. +
    5. 被打死的女人
    6. +
    + +

    說來說去,怪天怪地怪東怪西,怪政客怪媒體怪被害人,就是不是兇手的錯。

    + +

    我無意為自由主義個人主義辯護。但是為什麼犯罪事件,最大的錯不是兇手,而是政客,而是被害人呢?換個政黨執政,換個政客,犯罪就會消失嗎?現代社會犯罪是不可能消失的。我們可以藉制度的設計來降低犯罪發生的比率和數量。但無論如何,一旦發生了,殺人就是殺人者的錯。這是天經地義的事。沒有人叫兇手去殺人,殺人是兇手自己的自主行動。不管陳水扁、馬英九還是被害者,都不是兇手的藉口。

    + +

    臺灣社會真的很瘋狂。不管什麼事,怪天怪地怪東怪西,不是陳水扁/民進黨的錯,就是馬英九/國民黨的錯,不然就是受害者的錯。什麼事都罵政客,行為人完全沒有責任。彷彿政客真的那麼了不起,要給全世界的所有人把屎把尿通通一把抓一樣,人民真的那麼弱小無助,連撒尿拉屎都是政客的責任和義務一樣。反正行為人就是沒有錯,錯的都是這個萬惡的執政黨,萬惡的在野黨,萬惡的媒體,愚蠢的被害人。真是夠了。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 119 | + 120 | + 121 | + 122 | + 123 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0122.html.en.html b/htdocs/imacat/me/diary/0122.html.en.html new file mode 120000 index 0000000..b39a560 --- /dev/null +++ b/htdocs/imacat/me/diary/0122.html.en.html @@ -0,0 +1 @@ +0122.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0122.html.en.xhtml b/htdocs/imacat/me/diary/0122.html.en.xhtml new file mode 100644 index 0000000..fa1faf7 --- /dev/null +++ b/htdocs/imacat/me/diary/0122.html.en.xhtml @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 122 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 122

    + +
    + +
    + +
    +
    8.14.’07. 2:04am.
    + +

    下錯單

    + +

    之前在報紙報導上看過,證券營業員下錯單的事。過去台灣法令規定,投資人要下單買賣股票,要透過證券商中介。然而在電話、委託書聯絡,電腦鍵入資料的時候,偶爾就會發生鍵錯資料、下錯單的事。依法令規定,證券承銷商的錯誤,要自己吃下來。這時候負責的營業員就很慘,金額不大,幾十萬甚至一兩百萬時,往往就要自己吃下來。因為這樣,證券營業員工作壓力非常大。

    + +

    電腦網路流行後,財政部要求證券商都要做到網路下單,讓投資人可以直接透過電腦網路,即時向市場下單買賣,不需再經過中間承銷商。既可以做到即時下單,讓投資人在分秒必爭的股市中更容易掌握投資機會,也減少人為錯誤。相對的,這時候再出錯,因為是投資人自己下的單,就全由投資人自行負責,證券商就沒有責任了。

    + +

    沒想到這樣的故事,今天竟然會發生在我身上。今天幫小招買基金,在網路銀行上下單,密碼打錯,又退回來重打,卻沒注意到,退回前一頁時,所選基金會退回到預設的銀行促銷基金。重打密碼,密碼通過後,馬上按確認。這時候,才注意到上面的基金不是我要買的那一支。可是來不及了。什麼歐洲市場基金的。我對歐洲市場根本沒有概念,整個人都傻了。而且歐洲金融界現在正經歷次級房貸風暴,也不知道會持續多久。就算我隔天馬上殺出,可能也要賠一點,還要加上來回買賣的手續費。沒辦法,是我的錯,這些錢還是得賠給小招。

    + +

    唉,沒想到竟然也讓我碰上下錯單這種事。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 120 | + 121 | + 122 | + 123 | + 124 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0122.html.zh-cn.html b/htdocs/imacat/me/diary/0122.html.zh-cn.html new file mode 120000 index 0000000..95e629c --- /dev/null +++ b/htdocs/imacat/me/diary/0122.html.zh-cn.html @@ -0,0 +1 @@ +0122.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0122.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0122.html.zh-cn.xhtml new file mode 100644 index 0000000..eb4f47d --- /dev/null +++ b/htdocs/imacat/me/diary/0122.html.zh-cn.xhtml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百二十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百二十二

    + +
    + +
    + +
    +
    8.14.’07. 2:04am.
    + +

    下错单

    + +

    之前在报纸报导上看过,证券营业员下错单的事。过去台湾法令规定,投资人要下单买卖股票,要透过证券商中介。然而在电话、委托书联络,电脑键入资料的时候,偶尔就会发生键错资料、下错单的事。依法令规定,证券承销商的错误,要自己吃下来。这时候负责的营业员就很惨,金额不大,几十万甚至一两百万时,往往就要自己吃下来。因为这样,证券营业员工作压力非常大。

    + +

    电脑网路流行后,财政部要求证券商都要做到网路下单,让投资人可以直接透过电脑网路,即时向市场下单买卖,不需再经过中间承销商。既可以做到即时下单,让投资人在分秒必争的股市中更容易掌握投资机会,也减少人为错误。相对的,这时候再出错,因为是投资人自己下的单,就全由投资人自行负责,证券商就没有责任了。

    + +

    没想到这样的故事,今天竟然会发生在我身上。今天帮小招买基金,在网路银行上下单,密码打错,又退回来重打,却没注意到,退回前一页时,所选基金会退回到预设的银行促销基金。重打密码,密码通过后,马上按确认。这时候,才注意到上面的基金不是我要买的那一支。可是来不及了。什么欧洲市场基金的。我对欧洲市场根本没有概念,整个人都傻了。而且欧洲金融界现在正经历次级房贷风暴,也不知道会持续多久。就算我隔天马上杀出,可能也要赔一点,还要加上来回买卖的手续费。没办法,是我的错,这些钱还是得赔给小招。

    + +

    唉,没想到竟然也让我碰上下错单这种事。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 120 | + 121 | + 122 | + 123 | + 124 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0122.html.zh-tw.html b/htdocs/imacat/me/diary/0122.html.zh-tw.html new file mode 120000 index 0000000..e512648 --- /dev/null +++ b/htdocs/imacat/me/diary/0122.html.zh-tw.html @@ -0,0 +1 @@ +0122.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0122.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0122.html.zh-tw.xhtml new file mode 100644 index 0000000..caa4397 --- /dev/null +++ b/htdocs/imacat/me/diary/0122.html.zh-tw.xhtml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百二十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百二十二

    + +
    + +
    + +
    +
    8.14.’07. 2:04am.
    + +

    下錯單

    + +

    之前在報紙報導上看過,證券營業員下錯單的事。過去台灣法令規定,投資人要下單買賣股票,要透過證券商中介。然而在電話、委託書聯絡,電腦鍵入資料的時候,偶爾就會發生鍵錯資料、下錯單的事。依法令規定,證券承銷商的錯誤,要自己吃下來。這時候負責的營業員就很慘,金額不大,幾十萬甚至一兩百萬時,往往就要自己吃下來。因為這樣,證券營業員工作壓力非常大。

    + +

    電腦網路流行後,財政部要求證券商都要做到網路下單,讓投資人可以直接透過電腦網路,即時向市場下單買賣,不需再經過中間承銷商。既可以做到即時下單,讓投資人在分秒必爭的股市中更容易掌握投資機會,也減少人為錯誤。相對的,這時候再出錯,因為是投資人自己下的單,就全由投資人自行負責,證券商就沒有責任了。

    + +

    沒想到這樣的故事,今天竟然會發生在我身上。今天幫小招買基金,在網路銀行上下單,密碼打錯,又退回來重打,卻沒注意到,退回前一頁時,所選基金會退回到預設的銀行促銷基金。重打密碼,密碼通過後,馬上按確認。這時候,才注意到上面的基金不是我要買的那一支。可是來不及了。什麼歐洲市場基金的。我對歐洲市場根本沒有概念,整個人都傻了。而且歐洲金融界現在正經歷次級房貸風暴,也不知道會持續多久。就算我隔天馬上殺出,可能也要賠一點,還要加上來回買賣的手續費。沒辦法,是我的錯,這些錢還是得賠給小招。

    + +

    唉,沒想到竟然也讓我碰上下錯單這種事。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 120 | + 121 | + 122 | + 123 | + 124 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0123.html.en.html b/htdocs/imacat/me/diary/0123.html.en.html new file mode 120000 index 0000000..572c023 --- /dev/null +++ b/htdocs/imacat/me/diary/0123.html.en.html @@ -0,0 +1 @@ +0123.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0123.html.en.xhtml b/htdocs/imacat/me/diary/0123.html.en.xhtml new file mode 100644 index 0000000..d2e4244 --- /dev/null +++ b/htdocs/imacat/me/diary/0123.html.en.xhtml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 123 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 123

    + +
    + +
    + +
    +
    8.14.’07. 1:52pm.
    + +

    次級房貸風暴

    + +

    三個星期前的 7 月 25 日週三,臺股 9740.13 點衝上萬點前夕。當天的新聞,三支臺股基金核准通過,總金額約一百五十億,即將投入股市,資金充裕,所有人一致看好一口氣衝上一萬兩千點。沒想到 7 月 26 日週四突然大跌 173.71 點,跌到 9,566.42 點,跌幅 1.78% 。我本來以為是萬點之前的盤整。沒想到隔天週五跌得更大,一口氣跌了 404.14 點,跌到 9162.28 ,跌幅到 4.22% 。我想想,之前漲得那麼兇,大概有人要趁萬點前獲利了結。看新聞賣出的都是外資法人,我不禁反省只注意到臺資充裕,卻沒有算到外資會趁機收手。注意股市近一年來,還沒看過一天漲跌幅 4% 以上的。嚇都嚇死了。隔週星期一我也趕緊贖回。所幸星期一大盤反彈,我賣了個不錯的價錢。

    + +

    這一陣子以來股市每天起伏震盪都很大,都在 1% 以上。這一陣子來,一直聽到一個名詞:次級房貸風暴。那是什麼呢?上個週末,想想沒什麼事,我便上網查查什麼是次級房貸,盤算台股中長期還有沒有希望。

    + +

    次級房貸 (subprime mortgage) ,是在一般房貸以外的新興業務。因為美國房地產市場飽合,信用好可以申請分期房貸的,能借能賣的都賣了。為了刺激買氣,美國的銀行金融業者開始針對之前信用不好,不能借不能賣的人,以較高的利息核貸,較高的利息就用來補貼風險,作為風險貼水 (risk premium) 。這種借給信用不好的人的高利房貸,稱為次級房貸。次級房貸利息比初級房貸一般高約 2%–3% 。因為利息高,收入高,引起投機的金融業者競相投入,也創造了不少金融新貴。其中有新成立的公司,例如新世紀金融公司 New Century Financial ,也有歷史悠久的投資銀行,如貝爾斯登 Bear Stearns

    + +

    因為次級房貸優厚的利息很吸引人,金融業者又把它包裝成衍生性金融商品,稱為不動產證券化 REITS ,在市場公開發行。而後,更出現了針對 REITS 投資的不動產投資共同基金,吸引一般人去投資。

    + +

    一般認為, REITS 因為有不動產作抵押,比追逐數字的股市有保障。加上利息豐厚,成為許多投資人競相追逐的焦點。

    + +

    然而,次級房貸有什麼潛在的危機?

    + +

    次級房貸有兩個潛在的危機。第一個是違約風險。次級房貸的豐厚利息,是建基在風險貼水上的。也就是說,房貸的貸款人,本身信用評比並不好,不是信用記錄不良,就是收入較低。正派經營的銀行,原本就不應該借錢給這種人,因為容易被倒帳,也就是所謂的違約風險。次級房貸一般都是浮動利率,剛開始流行的時候,美國正處於低利時代,所以這些收入不足的人還繳得起。可是不可能有永遠的低利時代。當經濟過熱,為抑制通貨膨帳,美國聯準會一定會調昇利率,收回熱錢。一但利率調昇,超過這些貸款戶的收入負荷,只好倒帳。因此,一但利率調昇,就會引發全面性的倒帳潮。

    + +

    可是, REITS 就算倒帳,還是有不動產作抵押,有那麼可怕嗎?這就是第二個潛在的風險:不動產不容易變現。不像股市,同一支股票,每天都有很多賣賣交易,價格很容易電腦撮合,買賣容易得多。不動產買賣沒有那麼頻繁,每一件都不一樣,不同的不動產很難比較,很難定價,所以才需要銀行鑑價。市場不熱絡下,一件不動產要售出至少都要好幾個月。如果要立即變現,只能壓低價格拍賣,這樣價格損失就會非常鉅大。簡單地說,繳不起房貸的人,房子被法拍,所得金可能只剩下五分之一。那手上持有 REITS 金融商品的投資人,其淨值也在這一瞬間,縮水為五分之一。

    + +

    因為這樣可怕的潛在風險,一但次級房貸開始產生倒帳潮,就會連帶引發不動產基金投資人搶著贖回。基金有贖回給投資人的義務。當基金沒有那麼多現金以供贖回,抵押的房子只好法拍變現。法拍又造成基金的淨值大縮水。淨值大縮水又會引發贖回潮,變成快速的惡性循環骨牌效應,一下子就倒了。

    + +

    前述提到的兩家以次級房貸為主要業務的銀行和投資公司,新世紀金融公司已於 2007 年 3 月申請破產,貝爾斯登投資銀行日前也有兩支不動產基金倒閉,面臨非常嚴峻的生存危機。

    + +

    這麼可怕的事,原本再怎麼可怕,也只有傷到 REITS 基金,和整個投資市場無關。可是現代的金融市場交易複雜,還有投資基金的基金,可能會投資 REITS 基金,平衡基金也可能會投資 REITS ,金融機構本身也可能投資 REITS ,所以銀行金融機構也要認列投資損失。這些損失都是不容易察覺的。因為這些隱藏性的損失,造成投資人的信心危機,原本 5% 的損失,可能會擴散成整個市場的投資信心危機。投資人大量贖回,造成整個市場的動盪。

    + +

    不過,就算這麼可怕,原本也只是美國的問題,臺灣沒有次級房貸,和臺灣沒有多大關係。可是臺灣股市中有很多是美國來的外資法人基金。一旦美國基金母公司現金不足以應付美國人的贖回,只好在臺股大量殺出求現,以應付美國的贖回。和臺灣無關,可是臺股還是被大量殺出。而且殺出是為了匯回美國賠付投資人,投資公司大量搜購美元,也造成美元大漲。這就突顯了全球化的問題。臺灣的企業還在賺錢,臺灣企業投資美國 REITS 也不多,可是全球化的結果,美國金融業發生的問題,就會連帶影響到臺灣。

    + +

    上星期六,許多國家的中央銀行,提出大量資金,協助銀行渡過次級房貸風暴,穩定金融。此舉被解讀為次級房貸問題比想像中更嚴重,全球股市應聲而倒,臺股也跌了 251.29 點,跌破九千點,到 8,931.31 點。

    + +

    其實,次級房貸的根本問題,在於其高獲利的背後,存在著高度的違約風險。其高獲利原本就是風險貼水,投資人享受高獲利的同時,風險原本就應該自行承受。政府提出全民的錢來協助這些投資銀行,原本就是錯誤的。簡單來說,銀行要借錢給這些高風險、信用不好的人,是銀行自己的決定。一旦倒帳,銀行本就該自行承擔。要是無法承擔,一開始就不要做。借之前,就要想清楚。賺了風險錢,出了事才要政府擦屁股,是不負責任的事。個人這樣做,還可以說不夠成熟,予以同情;銀行有那麼專業的精算和風險控管團隊,還這樣做,一點都不值得同情

    + +

    次級房貸和臺灣之前的雙卡問題,非常類似。全世界的銀行在做的蠢事,其實一模一樣。歷史會不斷重演,說得一點也沒錯。

    + +

    這讓人不禁聯想到三年前的結構債事件。當時盛行債券基金,許多人瘋狂投入,以為債券比股市穩定,雖然收入比較低,但是是固定收益,成為風險低的投資好選擇。可是債券的背後也有違約風險。政府公債不會倒,可是利息很低,所以一般債券基金不會只投資政府公債,而會投資像公司債等利息較高的債券。然而公司債有違約風險,一但像博達事件一樣, 2004 年 3 月底五年期公司債到期還不出來,債券就瞬間變成壁紙了。

    + +

    算一算,這些衍生性金融商品,都有看不到的風險。股市比起來,交易透明,買賣容易,反而實在多了。

    + +

    整體來說,次級房貸只是一部份的問題。它既未衝擊到大多數銀行的正常業務,也沒有衝擊到一般的產業。充其量只是衝擊到美國投資人的信心。臺灣的產業還在賺錢,經濟還在看好,中長期來看,臺股還是大有可為的。 ^_*’

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 121 | + 122 | + 123 | + 124 | + 125 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0123.html.zh-cn.html b/htdocs/imacat/me/diary/0123.html.zh-cn.html new file mode 120000 index 0000000..5f5c194 --- /dev/null +++ b/htdocs/imacat/me/diary/0123.html.zh-cn.html @@ -0,0 +1 @@ +0123.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0123.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0123.html.zh-cn.xhtml new file mode 100644 index 0000000..38a4047 --- /dev/null +++ b/htdocs/imacat/me/diary/0123.html.zh-cn.xhtml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百二十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百二十三

    + +
    + +
    + +
    +
    8.14.’07. 1:52pm.
    + +

    次级房贷风暴

    + +

    三个星期前的 7 月 25 日周三,台股 9740.13 点冲上万点前夕。当天的新闻,三支台股基金核准通过,总金额约一百五十亿,即将投入股市,资金充裕,所有人一致看好一口气冲上一万两千点。没想到 7 月 26 日周四突然大跌 173.71 点,跌到 9,566.42 点,跌幅 1.78% 。我本来以为是万点之前的盘整。没想到隔天周五跌得更大,一口气跌了 404.14 点,跌到 9162.28 ,跌幅到 4.22% 。我想想,之前涨得那么凶,大概有人要趁万点前获利了结。看新闻卖出的都是外资法人,我不禁反省只注意到台资充裕,却没有算到外资会趁机收手。注意股市近一年来,还没看过一天涨跌幅 4% 以上的。吓都吓死了。隔周星期一我也赶紧赎回。所幸星期一大盘反弹,我卖了个不错的价钱。

    + +

    这一阵子以来股市每天起伏震荡都很大,都在 1% 以上。这一阵子来,一直听到一个名词:次级房贷风暴。那是什么呢?上个周末,想想没什么事,我便上网查查什么是次级房贷,盘算台股中长期还有没有希望。

    + +

    次级房贷 (subprime mortgage) ,是在一般房贷以外的新兴业务。因为美国房地产市场饱合,信用好可以申请分期房贷的,能借能卖的都卖了。为了刺激买气,美国的银行金融业者开始针对之前信用不好,不能借不能卖的人,以较高的利息核贷,较高的利息就用来补贴风险,作为风险贴水 (risk premium) 。这种借给信用不好的人的高利房贷,称为次级房贷。次级房贷利息比初级房贷一般高约 2%–3% 。因为利息高,收入高,引起投机的金融业者竞相投入,也创造了不少金融新贵。其中有新成立的公司,例如新世纪金融公司 New Century Financial ,也有历史悠久的投资银行,如贝尔斯登 Bear Stearns

    + +

    因为次级房贷优厚的利息很吸引人,金融业者又把它包装成衍生性金融商品,称为不动产证券化 REITS ,在市场公开发行。而后,更出现了针对 REITS 投资的不动产投资共同基金,吸引一般人去投资。

    + +

    一般认为, REITS 因为有不动产作抵押,比追逐数字的股市有保障。加上利息丰厚,成为许多投资人竞相追逐的焦点。

    + +

    然而,次级房贷有什么潜在的危机?

    + +

    次级房贷有两个潜在的危机。第一个是违约风险。次级房贷的丰厚利息,是建基在风险贴水上的。也就是说,房贷的贷款人,本身信用评比并不好,不是信用记录不良,就是收入较低。正派经营的银行,原本就不应该借钱给这种人,因为容易被倒帐,也就是所谓的违约风险。次级房贷一般都是浮动利率,刚开始流行的时候,美国正处於低利时代,所以这些收入不足的人还缴得起。可是不可能有永远的低利时代。当经济过热,为抑制通货膨帐,美国联准会一定会调升利率,收回热钱。一但利率调升,超过这些贷款户的收入负荷,只好倒帐。因此,一但利率调升,就会引发全面性的倒帐潮。

    + +

    可是, REITS 就算倒帐,还是有不动产作抵押,有那么可怕吗?这就是第二个潜在的风险:不动产不容易变现。不像股市,同一支股票,每天都有很多卖卖交易,价格很容易电脑撮合,买卖容易得多。不动产买卖没有那么频繁,每一件都不一样,不同的不动产很难比较,很难定价,所以才需要银行鉴价。市场不热络下,一件不动产要售出至少都要好几个月。如果要立即变现,只能压低价格拍卖,这样价格损失就会非常巨大。简单地说,缴不起房贷的人,房子被法拍,所得金可能只剩下五分之一。那手上持有 REITS 金融商品的投资人,其净值也在这一瞬间,缩水为五分之一。

    + +

    因为这样可怕的潜在风险,一但次级房贷开始产生倒帐潮,就会连带引发不动产基金投资人抢著赎回。基金有赎回给投资人的义务。当基金没有那么多现金以供赎回,抵押的房子只好法拍变现。法拍又造成基金的净值大缩水。净值大缩水又会引发赎回潮,变成快速的恶性循环骨牌效应,一下子就倒了。

    + +

    前述提到的两家以次级房贷为主要业务的银行和投资公司,新世纪金融公司已於 2007 年 3 月申请破产,贝尔斯登投资银行日前也有两支不动产基金倒闭,面临非常严峻的生存危机。

    + +

    这么可怕的事,原本再怎么可怕,也只有伤到 REITS 基金,和整个投资市场无关。可是现代的金融市场交易复杂,还有投资基金的基金,可能会投资 REITS 基金,平衡基金也可能会投资 REITS ,金融机构本身也可能投资 REITS ,所以银行金融机构也要认列投资损失。这些损失都是不容易察觉的。因为这些隐藏性的损失,造成投资人的信心危机,原本 5% 的损失,可能会扩散成整个市场的投资信心危机。投资人大量赎回,造成整个市场的动荡。

    + +

    不过,就算这么可怕,原本也只是美国的问题,台湾没有次级房贷,和台湾没有多大关系。可是台湾股市中有很多是美国来的外资法人基金。一旦美国基金母公司现金不足以应付美国人的赎回,只好在台股大量杀出求现,以应付美国的赎回。和台湾无关,可是台股还是被大量杀出。而且杀出是为了汇回美国赔付投资人,投资公司大量搜购美元,也造成美元大涨。这就突显了全球化的问题。台湾的企业还在赚钱,台湾企业投资美国 REITS 也不多,可是全球化的结果,美国金融业发生的问题,就会连带影响到台湾。

    + +

    上星期六,许多国家的中央银行,提出大量资金,协助银行渡过次级房贷风暴,稳定金融。此举被解读为次级房贷问题比想像中更严重,全球股市应声而倒,台股也跌了 251.29 点,跌破九千点,到 8,931.31 点。

    + +

    其实,次级房贷的根本问题,在於其高获利的背后,存在著高度的违约风险。其高获利原本就是风险贴水,投资人享受高获利的同时,风险原本就应该自行承受。政府提出全民的钱来协助这些投资银行,原本就是错误的。简单来说,银行要借钱给这些高风险、信用不好的人,是银行自己的决定。一旦倒帐,银行本就该自行承担。要是无法承担,一开始就不要做。借之前,就要想清楚。赚了风险钱,出了事才要政府擦屁股,是不负责任的事。个人这样做,还可以说不够成熟,予以同情;银行有那么专业的精算和风险控管团队,还这样做,一点都不值得同情

    + +

    次级房贷和台湾之前的双卡问题,非常类似。全世界的银行在做的蠢事,其实一模一样。历史会不断重演,说得一点也没错。

    + +

    这让人不禁联想到三年前的结构债事件。当时盛行债券基金,许多人疯狂投入,以为债券比股市稳定,虽然收入比较低,但是是固定收益,成为风险低的投资好选择。可是债券的背后也有违约风险。政府公债不会倒,可是利息很低,所以一般债券基金不会只投资政府公债,而会投资像公司债等利息较高的债券。然而公司债有违约风险,一但像博达事件一样, 2004 年 3 月底五年期公司债到期还不出来,债券就瞬间变成壁纸了。

    + +

    算一算,这些衍生性金融商品,都有看不到的风险。股市比起来,交易透明,买卖容易,反而实在多了。

    + +

    整体来说,次级房贷只是一部份的问题。它既未冲击到大多数银行的正常业务,也没有冲击到一般的产业。充其量只是冲击到美国投资人的信心。台湾的产业还在赚钱,经济还在看好,中长期来看,台股还是大有可为的。 ^_*’

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 121 | + 122 | + 123 | + 124 | + 125 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0123.html.zh-tw.html b/htdocs/imacat/me/diary/0123.html.zh-tw.html new file mode 120000 index 0000000..fb9a2f9 --- /dev/null +++ b/htdocs/imacat/me/diary/0123.html.zh-tw.html @@ -0,0 +1 @@ +0123.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0123.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0123.html.zh-tw.xhtml new file mode 100644 index 0000000..cc72482 --- /dev/null +++ b/htdocs/imacat/me/diary/0123.html.zh-tw.xhtml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百二十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百二十三

    + +
    + +
    + +
    +
    8.14.’07. 1:52pm.
    + +

    次級房貸風暴

    + +

    三個星期前的 7 月 25 日週三,臺股 9740.13 點衝上萬點前夕。當天的新聞,三支臺股基金核准通過,總金額約一百五十億,即將投入股市,資金充裕,所有人一致看好一口氣衝上一萬兩千點。沒想到 7 月 26 日週四突然大跌 173.71 點,跌到 9,566.42 點,跌幅 1.78% 。我本來以為是萬點之前的盤整。沒想到隔天週五跌得更大,一口氣跌了 404.14 點,跌到 9162.28 ,跌幅到 4.22% 。我想想,之前漲得那麼兇,大概有人要趁萬點前獲利了結。看新聞賣出的都是外資法人,我不禁反省只注意到臺資充裕,卻沒有算到外資會趁機收手。注意股市近一年來,還沒看過一天漲跌幅 4% 以上的。嚇都嚇死了。隔週星期一我也趕緊贖回。所幸星期一大盤反彈,我賣了個不錯的價錢。

    + +

    這一陣子以來股市每天起伏震盪都很大,都在 1% 以上。這一陣子來,一直聽到一個名詞:次級房貸風暴。那是什麼呢?上個週末,想想沒什麼事,我便上網查查什麼是次級房貸,盤算台股中長期還有沒有希望。

    + +

    次級房貸 (subprime mortgage) ,是在一般房貸以外的新興業務。因為美國房地產市場飽合,信用好可以申請分期房貸的,能借能賣的都賣了。為了刺激買氣,美國的銀行金融業者開始針對之前信用不好,不能借不能賣的人,以較高的利息核貸,較高的利息就用來補貼風險,作為風險貼水 (risk premium) 。這種借給信用不好的人的高利房貸,稱為次級房貸。次級房貸利息比初級房貸一般高約 2%–3% 。因為利息高,收入高,引起投機的金融業者競相投入,也創造了不少金融新貴。其中有新成立的公司,例如新世紀金融公司 New Century Financial ,也有歷史悠久的投資銀行,如貝爾斯登 Bear Stearns

    + +

    因為次級房貸優厚的利息很吸引人,金融業者又把它包裝成衍生性金融商品,稱為不動產證券化 REITS ,在市場公開發行。而後,更出現了針對 REITS 投資的不動產投資共同基金,吸引一般人去投資。

    + +

    一般認為, REITS 因為有不動產作抵押,比追逐數字的股市有保障。加上利息豐厚,成為許多投資人競相追逐的焦點。

    + +

    然而,次級房貸有什麼潛在的危機?

    + +

    次級房貸有兩個潛在的危機。第一個是違約風險。次級房貸的豐厚利息,是建基在風險貼水上的。也就是說,房貸的貸款人,本身信用評比並不好,不是信用記錄不良,就是收入較低。正派經營的銀行,原本就不應該借錢給這種人,因為容易被倒帳,也就是所謂的違約風險。次級房貸一般都是浮動利率,剛開始流行的時候,美國正處於低利時代,所以這些收入不足的人還繳得起。可是不可能有永遠的低利時代。當經濟過熱,為抑制通貨膨帳,美國聯準會一定會調昇利率,收回熱錢。一但利率調昇,超過這些貸款戶的收入負荷,只好倒帳。因此,一但利率調昇,就會引發全面性的倒帳潮。

    + +

    可是, REITS 就算倒帳,還是有不動產作抵押,有那麼可怕嗎?這就是第二個潛在的風險:不動產不容易變現。不像股市,同一支股票,每天都有很多賣賣交易,價格很容易電腦撮合,買賣容易得多。不動產買賣沒有那麼頻繁,每一件都不一樣,不同的不動產很難比較,很難定價,所以才需要銀行鑑價。市場不熱絡下,一件不動產要售出至少都要好幾個月。如果要立即變現,只能壓低價格拍賣,這樣價格損失就會非常鉅大。簡單地說,繳不起房貸的人,房子被法拍,所得金可能只剩下五分之一。那手上持有 REITS 金融商品的投資人,其淨值也在這一瞬間,縮水為五分之一。

    + +

    因為這樣可怕的潛在風險,一但次級房貸開始產生倒帳潮,就會連帶引發不動產基金投資人搶著贖回。基金有贖回給投資人的義務。當基金沒有那麼多現金以供贖回,抵押的房子只好法拍變現。法拍又造成基金的淨值大縮水。淨值大縮水又會引發贖回潮,變成快速的惡性循環骨牌效應,一下子就倒了。

    + +

    前述提到的兩家以次級房貸為主要業務的銀行和投資公司,新世紀金融公司已於 2007 年 3 月申請破產,貝爾斯登投資銀行日前也有兩支不動產基金倒閉,面臨非常嚴峻的生存危機。

    + +

    這麼可怕的事,原本再怎麼可怕,也只有傷到 REITS 基金,和整個投資市場無關。可是現代的金融市場交易複雜,還有投資基金的基金,可能會投資 REITS 基金,平衡基金也可能會投資 REITS ,金融機構本身也可能投資 REITS ,所以銀行金融機構也要認列投資損失。這些損失都是不容易察覺的。因為這些隱藏性的損失,造成投資人的信心危機,原本 5% 的損失,可能會擴散成整個市場的投資信心危機。投資人大量贖回,造成整個市場的動盪。

    + +

    不過,就算這麼可怕,原本也只是美國的問題,臺灣沒有次級房貸,和臺灣沒有多大關係。可是臺灣股市中有很多是美國來的外資法人基金。一旦美國基金母公司現金不足以應付美國人的贖回,只好在臺股大量殺出求現,以應付美國的贖回。和臺灣無關,可是臺股還是被大量殺出。而且殺出是為了匯回美國賠付投資人,投資公司大量搜購美元,也造成美元大漲。這就突顯了全球化的問題。臺灣的企業還在賺錢,臺灣企業投資美國 REITS 也不多,可是全球化的結果,美國金融業發生的問題,就會連帶影響到臺灣。

    + +

    上星期六,許多國家的中央銀行,提出大量資金,協助銀行渡過次級房貸風暴,穩定金融。此舉被解讀為次級房貸問題比想像中更嚴重,全球股市應聲而倒,臺股也跌了 251.29 點,跌破九千點,到 8,931.31 點。

    + +

    其實,次級房貸的根本問題,在於其高獲利的背後,存在著高度的違約風險。其高獲利原本就是風險貼水,投資人享受高獲利的同時,風險原本就應該自行承受。政府提出全民的錢來協助這些投資銀行,原本就是錯誤的。簡單來說,銀行要借錢給這些高風險、信用不好的人,是銀行自己的決定。一旦倒帳,銀行本就該自行承擔。要是無法承擔,一開始就不要做。借之前,就要想清楚。賺了風險錢,出了事才要政府擦屁股,是不負責任的事。個人這樣做,還可以說不夠成熟,予以同情;銀行有那麼專業的精算和風險控管團隊,還這樣做,一點都不值得同情

    + +

    次級房貸和臺灣之前的雙卡問題,非常類似。全世界的銀行在做的蠢事,其實一模一樣。歷史會不斷重演,說得一點也沒錯。

    + +

    這讓人不禁聯想到三年前的結構債事件。當時盛行債券基金,許多人瘋狂投入,以為債券比股市穩定,雖然收入比較低,但是是固定收益,成為風險低的投資好選擇。可是債券的背後也有違約風險。政府公債不會倒,可是利息很低,所以一般債券基金不會只投資政府公債,而會投資像公司債等利息較高的債券。然而公司債有違約風險,一但像博達事件一樣, 2004 年 3 月底五年期公司債到期還不出來,債券就瞬間變成壁紙了。

    + +

    算一算,這些衍生性金融商品,都有看不到的風險。股市比起來,交易透明,買賣容易,反而實在多了。

    + +

    整體來說,次級房貸只是一部份的問題。它既未衝擊到大多數銀行的正常業務,也沒有衝擊到一般的產業。充其量只是衝擊到美國投資人的信心。臺灣的產業還在賺錢,經濟還在看好,中長期來看,臺股還是大有可為的。 ^_*’

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 121 | + 122 | + 123 | + 124 | + 125 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0124.html.en.html b/htdocs/imacat/me/diary/0124.html.en.html new file mode 120000 index 0000000..96017f6 --- /dev/null +++ b/htdocs/imacat/me/diary/0124.html.en.html @@ -0,0 +1 @@ +0124.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0124.html.en.xhtml b/htdocs/imacat/me/diary/0124.html.en.xhtml new file mode 100644 index 0000000..57cab77 --- /dev/null +++ b/htdocs/imacat/me/diary/0124.html.en.xhtml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 124 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 124

    + +
    + +
    + +
    +
    8.17.’07. 9:54pm.
    + +

    CA-42 傳輸線

    + +

    小招去美國,要換一支三頻手機。上個星期和小招一起去公館汀州路的 Nokia 專賣店錸通通信,買了一支 Nokia 6102 ,隨後又請店員查傳輸線型號,花了 300 買了 Nokia 6102 用的傳輸線 CA-42 。一想到 CA-42 ,不禁聯想到我那條 Nokia 6070 MOMEX OTi 6858 CA-42 的慘痛回憶。

    + +

    這一條 CA-42 是深圳創新微電子 Ark Pioneer Microelectronics 的 0232 。回家後接上,安裝隨附的光碟驅動程式,果然, Nokia PC Suite 不能用,不過 LogoManager 的 MobiMB Mobile Media Browser 完全沒有問題,而且傳得很快,比我的 MOMEX OTi 6858 CA-42 快得多了。

    + +

    看到兩條一模一樣接頭的 CA-42 ,我突發奇想,把我的 Nokia 6070 接到 Ark 0232 CA-42 上。沒想到竟然完全可以通,而且傳輸又穩定,傳輸速度比之前的 MOMEX OTi 6858 CA-42 快了好幾倍!這真是太神奇了!

    + +

    之前的 MOMEX OTi 6858 CA-42 傳輸速度只有 9600 bps 標準 COM 連接埠的速度,傳起來超慢,傳得慢就容易斷線,一張小照片就傳很久,傳到一半斷線,又要一直重傳,搞到我一想到傳輸照片就怕,快瘋了。

    + +

    那條 Ark 0232 CA-42 小招帶去美國了。今天下午,我冒著雨走到公館的錸通通信,再掏了 300 元買了一條 Ark 0232 CA-42 。害怕又搞到無法傳輸,抱著忒忑不安的心情拿回家接上,嗯,可以通,而且速度 115200 bps ,是 MOMEX OTi 6858 CA-42 的 9600 bps 的 12 倍,傳輸又快又穩定。真是太酷了~

    + +

    想到之前花了 450 元買到那條 MOMEX OTi 6858 CA-42 ,現在這條 Ark 0232 CA-42 只花了 300 元。唉,當初真是搞得好辛苦~現在這條舊的 MOMEX OTi 6858 CA-42 大概也只能丟掉了,不過因為換了個好東西,我一點也不覺得可惜呢~ ^_*’

    + +
    + +
    + +
    +
    8.17.’07. 1:28pm.
    + +

    美國

    + +

    忙了一個多月,終於把小招送去美國了。

    + +

    從昨天起,小招要留在伊利諾大學做九個月的訪問研究,要到明年五月底才會回來。

    + +

    這一陣子除了 Wii 、基金以外,都在忙小招要去美國的事。我之前一直沒有空學 Skype ,前一陣子為了聯絡方便,開始試用 Skype ,研究各項功能像是 SkypeOut 、 SkypeIn 、 Skype Pro 、 Webcam 、 VoIP 等等的。然後每天跟小招東跑西跑,採買要帶去美國的東西,去銀行辦事,陪她和她家人吃飯。

    + +

    昨天下午把她送上飛機後,回來還有好多事要收尾:辦保管箱、寄東西給她的家人朋友、備份她台灣電腦的硬碟資料、設定 FTP 等等。然後就等著她到宿舍了以後上網聯絡,測試郵件、 Skype 、 Webcam 、 FTP 等等的功能。

    + +

    查了查, 070 網路電話,下個月速博就要開始接受申請了。聽說速博和 PChome-Skype 合作,如果這樣的話, SkypeIn 就有可能用速博網路做出來。那樣的話就太好了~臺灣的手機門號,用指定轉接轉到 070 網路電話去,然後用 Skype 接聽。這樣臺灣的手機門號還是可以用,又不需要付國際漫遊費,省了一大筆錢。

    + +

    呼,好累。可是其實沒有要分開很久的感覺。看到 Skype Webcam 還可以放大到全螢幕,好大一個臉,就覺得好像也沒有很遠的感覺。

    + +

    可能接下來會比較有感覺吧。很多事都要自己一個人忙了。

    + +
    + +
    + +
    +
    8.17.’07. 4:33am.
    + +

    慘賠出場

    + +

    看來我是低估了全球化的威力了。臺股中的外資法人基金影響力,比我預期的還要大很多,受次級房貸風暴影響,歐美投資人一緊縮抽手,國內熱錢再怎麼多,也撐不住。

    + +

    不過還好。記帳記錯了。原本以為一天賠了一萬五,就算隔天立刻贖回,三天也要賠四、五萬的。後來才發現是記帳記錯了,跌了三天只賠了兩萬而已。全部結算起來,從去年底開始投資,還是賺的。

    + +

    不過這次也算花錢買了個教訓:不應該貪心炒短線。看指數反彈了三天就買,一瀉如注狂賠,也是自己活該。應該等整個局勢回穩了,開始緩慢回溫一兩個星期,市場信心重建以後,再投資的。而且就算臺灣企業還是在賺錢,整體經濟環境不錯,可是有外資法人基金歐美次級房貸風暴,一正一負兩個因素加起來,大約也只是相互抵消的平盤。若只是平盤,實在也不是投資的時機點。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 122 | + 123 | + 124 | + 125 | + 126 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0124.html.zh-cn.html b/htdocs/imacat/me/diary/0124.html.zh-cn.html new file mode 120000 index 0000000..3756dc9 --- /dev/null +++ b/htdocs/imacat/me/diary/0124.html.zh-cn.html @@ -0,0 +1 @@ +0124.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0124.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0124.html.zh-cn.xhtml new file mode 100644 index 0000000..0db5575 --- /dev/null +++ b/htdocs/imacat/me/diary/0124.html.zh-cn.xhtml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百二十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百二十四

    + +
    + +
    + +
    +
    8.17.’07. 9:54pm.
    + +

    CA-42 传输线

    + +

    小招去美国,要换一支三频手机。上个星期和小招一起去公馆汀州路的 Nokia 专卖店铼通通信,买了一支 Nokia 6102 ,随后又请店员查传输线型号,花了 300 买了 Nokia 6102 用的传输线 CA-42 。一想到 CA-42 ,不禁联想到我那条 Nokia 6070 MOMEX OTi 6858 CA-42 的惨痛回忆。

    + +

    这一条 CA-42 是深圳创新微电子 Ark Pioneer Microelectronics 的 0232 。回家后接上,安装随附的光碟驱动程式,果然, Nokia PC Suite 不能用,不过 LogoManager 的 MobiMB Mobile Media Browser 完全没有问题,而且传得很快,比我的 MOMEX OTi 6858 CA-42 快得多了。

    + +

    看到两条一模一样接头的 CA-42 ,我突发奇想,把我的 Nokia 6070 接到 Ark 0232 CA-42 上。没想到竟然完全可以通,而且传输又稳定,传输速度比之前的 MOMEX OTi 6858 CA-42 快了好几倍!这真是太神奇了!

    + +

    之前的 MOMEX OTi 6858 CA-42 传输速度只有 9600 bps 标准 COM 连接埠的速度,传起来超慢,传得慢就容易断线,一张小照片就传很久,传到一半断线,又要一直重传,搞到我一想到传输照片就怕,快疯了。

    + +

    那条 Ark 0232 CA-42 小招带去美国了。今天下午,我冒著雨走到公馆的铼通通信,再掏了 300 元买了一条 Ark 0232 CA-42 。害怕又搞到无法传输,抱著忒忑不安的心情拿回家接上,嗯,可以通,而且速度 115200 bps ,是 MOMEX OTi 6858 CA-42 的 9600 bps 的 12 倍,传输又快又稳定。真是太酷了~

    + +

    想到之前花了 450 元买到那条 MOMEX OTi 6858 CA-42 ,现在这条 Ark 0232 CA-42 只花了 300 元。唉,当初真是搞得好辛苦~现在这条旧的 MOMEX OTi 6858 CA-42 大概也只能丢掉了,不过因为换了个好东西,我一点也不觉得可惜呢~ ^_*’

    + +
    + +
    + +
    +
    8.17.’07. 1:28pm.
    + +

    美国

    + +

    忙了一个多月,终於把小招送去美国了。

    + +

    从昨天起,小招要留在伊利诺大学做九个月的访问研究,要到明年五月底才会回来。

    + +

    这一阵子除了 Wii 、基金以外,都在忙小招要去美国的事。我之前一直没有空学 Skype ,前一阵子为了联络方便,开始试用 Skype ,研究各项功能像是 SkypeOut 、 SkypeIn 、 Skype Pro 、 Webcam 、 VoIP 等等的。然后每天跟小招东跑西跑,采买要带去美国的东西,去银行办事,陪她和她家人吃饭。

    + +

    昨天下午把她送上飞机后,回来还有好多事要收尾:办保管箱、寄东西给她的家人朋友、备份她台湾电脑的硬碟资料、设定 FTP 等等。然后就等著她到宿舍了以后上网联络,测试邮件、 Skype 、 Webcam 、 FTP 等等的功能。

    + +

    查了查, 070 网路电话,下个月速博就要开始接受申请了。听说速博和 PChome-Skype 合作,如果这样的话, SkypeIn 就有可能用速博网路做出来。那样的话就太好了~台湾的手机门号,用指定转接转到 070 网路电话去,然后用 Skype 接听。这样台湾的手机门号还是可以用,又不需要付国际漫游费,省了一大笔钱。

    + +

    呼,好累。可是其实没有要分开很久的感觉。看到 Skype Webcam 还可以放大到全萤幕,好大一个脸,就觉得好像也没有很远的感觉。

    + +

    可能接下来会比较有感觉吧。很多事都要自己一个人忙了。

    + +
    + +
    + +
    +
    8.17.’07. 4:33am.
    + +

    惨赔出场

    + +

    看来我是低估了全球化的威力了。台股中的外资法人基金影响力,比我预期的还要大很多,受次级房贷风暴影响,欧美投资人一紧缩抽手,国内热钱再怎么多,也撑不住。

    + +

    不过还好。记帐记错了。原本以为一天赔了一万五,就算隔天立刻赎回,三天也要赔四、五万的。后来才发现是记帐记错了,跌了三天只赔了两万而已。全部结算起来,从去年底开始投资,还是赚的。

    + +

    不过这次也算花钱买了个教训:不应该贪心炒短线。看指数反弹了三天就买,一泻如注狂赔,也是自己活该。应该等整个局势回稳了,开始缓慢回温一两个星期,市场信心重建以后,再投资的。而且就算台湾企业还是在赚钱,整体经济环境不错,可是有外资法人基金欧美次级房贷风暴,一正一负两个因素加起来,大约也只是相互抵消的平盘。若只是平盘,实在也不是投资的时机点。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 122 | + 123 | + 124 | + 125 | + 126 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0124.html.zh-tw.html b/htdocs/imacat/me/diary/0124.html.zh-tw.html new file mode 120000 index 0000000..0df2541 --- /dev/null +++ b/htdocs/imacat/me/diary/0124.html.zh-tw.html @@ -0,0 +1 @@ +0124.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0124.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0124.html.zh-tw.xhtml new file mode 100644 index 0000000..d740aad --- /dev/null +++ b/htdocs/imacat/me/diary/0124.html.zh-tw.xhtml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百二十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百二十四

    + +
    + +
    + +
    +
    8.17.’07. 9:54pm.
    + +

    CA-42 傳輸線

    + +

    小招去美國,要換一支三頻手機。上個星期和小招一起去公館汀州路的 Nokia 專賣店錸通通信,買了一支 Nokia 6102 ,隨後又請店員查傳輸線型號,花了 300 買了 Nokia 6102 用的傳輸線 CA-42 。一想到 CA-42 ,不禁聯想到我那條 Nokia 6070 MOMEX OTi 6858 CA-42 的慘痛回憶。

    + +

    這一條 CA-42 是深圳創新微電子 Ark Pioneer Microelectronics 的 0232 。回家後接上,安裝隨附的光碟驅動程式,果然, Nokia PC Suite 不能用,不過 LogoManager 的 MobiMB Mobile Media Browser 完全沒有問題,而且傳得很快,比我的 MOMEX OTi 6858 CA-42 快得多了。

    + +

    看到兩條一模一樣接頭的 CA-42 ,我突發奇想,把我的 Nokia 6070 接到 Ark 0232 CA-42 上。沒想到竟然完全可以通,而且傳輸又穩定,傳輸速度比之前的 MOMEX OTi 6858 CA-42 快了好幾倍!這真是太神奇了!

    + +

    之前的 MOMEX OTi 6858 CA-42 傳輸速度只有 9600 bps 標準 COM 連接埠的速度,傳起來超慢,傳得慢就容易斷線,一張小照片就傳很久,傳到一半斷線,又要一直重傳,搞到我一想到傳輸照片就怕,快瘋了。

    + +

    那條 Ark 0232 CA-42 小招帶去美國了。今天下午,我冒著雨走到公館的錸通通信,再掏了 300 元買了一條 Ark 0232 CA-42 。害怕又搞到無法傳輸,抱著忒忑不安的心情拿回家接上,嗯,可以通,而且速度 115200 bps ,是 MOMEX OTi 6858 CA-42 的 9600 bps 的 12 倍,傳輸又快又穩定。真是太酷了~

    + +

    想到之前花了 450 元買到那條 MOMEX OTi 6858 CA-42 ,現在這條 Ark 0232 CA-42 只花了 300 元。唉,當初真是搞得好辛苦~現在這條舊的 MOMEX OTi 6858 CA-42 大概也只能丟掉了,不過因為換了個好東西,我一點也不覺得可惜呢~ ^_*’

    + +
    + +
    + +
    +
    8.17.’07. 1:28pm.
    + +

    美國

    + +

    忙了一個多月,終於把小招送去美國了。

    + +

    從昨天起,小招要留在伊利諾大學做九個月的訪問研究,要到明年五月底才會回來。

    + +

    這一陣子除了 Wii 、基金以外,都在忙小招要去美國的事。我之前一直沒有空學 Skype ,前一陣子為了聯絡方便,開始試用 Skype ,研究各項功能像是 SkypeOut 、 SkypeIn 、 Skype Pro 、 Webcam 、 VoIP 等等的。然後每天跟小招東跑西跑,採買要帶去美國的東西,去銀行辦事,陪她和她家人吃飯。

    + +

    昨天下午把她送上飛機後,回來還有好多事要收尾:辦保管箱、寄東西給她的家人朋友、備份她台灣電腦的硬碟資料、設定 FTP 等等。然後就等著她到宿舍了以後上網聯絡,測試郵件、 Skype 、 Webcam 、 FTP 等等的功能。

    + +

    查了查, 070 網路電話,下個月速博就要開始接受申請了。聽說速博和 PChome-Skype 合作,如果這樣的話, SkypeIn 就有可能用速博網路做出來。那樣的話就太好了~臺灣的手機門號,用指定轉接轉到 070 網路電話去,然後用 Skype 接聽。這樣臺灣的手機門號還是可以用,又不需要付國際漫遊費,省了一大筆錢。

    + +

    呼,好累。可是其實沒有要分開很久的感覺。看到 Skype Webcam 還可以放大到全螢幕,好大一個臉,就覺得好像也沒有很遠的感覺。

    + +

    可能接下來會比較有感覺吧。很多事都要自己一個人忙了。

    + +
    + +
    + +
    +
    8.17.’07. 4:33am.
    + +

    慘賠出場

    + +

    看來我是低估了全球化的威力了。臺股中的外資法人基金影響力,比我預期的還要大很多,受次級房貸風暴影響,歐美投資人一緊縮抽手,國內熱錢再怎麼多,也撐不住。

    + +

    不過還好。記帳記錯了。原本以為一天賠了一萬五,就算隔天立刻贖回,三天也要賠四、五萬的。後來才發現是記帳記錯了,跌了三天只賠了兩萬而已。全部結算起來,從去年底開始投資,還是賺的。

    + +

    不過這次也算花錢買了個教訓:不應該貪心炒短線。看指數反彈了三天就買,一瀉如注狂賠,也是自己活該。應該等整個局勢回穩了,開始緩慢回溫一兩個星期,市場信心重建以後,再投資的。而且就算臺灣企業還是在賺錢,整體經濟環境不錯,可是有外資法人基金歐美次級房貸風暴,一正一負兩個因素加起來,大約也只是相互抵消的平盤。若只是平盤,實在也不是投資的時機點。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 122 | + 123 | + 124 | + 125 | + 126 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0125.html.en.html b/htdocs/imacat/me/diary/0125.html.en.html new file mode 120000 index 0000000..e7a17e5 --- /dev/null +++ b/htdocs/imacat/me/diary/0125.html.en.html @@ -0,0 +1 @@ +0125.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0125.html.en.xhtml b/htdocs/imacat/me/diary/0125.html.en.xhtml new file mode 100644 index 0000000..9252285 --- /dev/null +++ b/htdocs/imacat/me/diary/0125.html.en.xhtml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 125 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 125

    + +
    + +
    + +
    +
    8.22.’07. 5:18pm.
    + +

    教訓

    + +

    這兩天基金贖回的款項陸續入帳,又整理了一次基金帳,把實際贖回金額和和計算的金額一一比對。

    + +

    還好,幫小招買的那筆,贖回日正逢星期一反彈,只賠了三千,從年初算下來還有賺七千,算賠得少。這畢竟不是我的錢,雖說已經跟小招講清楚投資的風險,可是賠了別人的錢,還是比賠自己的還要怕。

    + +

    自己那筆就沒那麼好看了。三天賠了兩萬,近十七萬一下子剩不到十五萬,觸目驚心。

    + +

    在空大上個人投資理財課時,課本有特別教,買基金不是炒短線,要看六個月、兩年以上的長期。不管是哪裏讀的基金文章,也都有特別強調。今天蘋果日報財經版,也有一篇基金炒短線 小心變成拒往戶。帶著沉重的心情,邊唸邊反省。這些我都知道,課本、文章不知道讀過多少次。為什麼還是會犯這種錯?細細咀嚼著其實已經讀過不知道多少次的字句,心中五味雜陳。

    + +

    不只是基金,即使是股市投資,課本也強調過,最戒一個字。要克制欲望,要中長期持有,不要炒短線。讀的時候通通都知道,可是其實那個字是什麼感覺,我其實不懂。知道要戒貪,可是不知道什麼樣叫貪,要戒的是什麼。

    + +

    被一天的強烈反彈沖昏頭,怕搶不到一天的好價格,怕投資沒有早點放進去滾,就叫做貪。

    + +

    我買的是基金,基金是做中長線的,對六個月、兩年的中長線來說,就算漲了兩個星期沒賺到,都不算什麼。更何況是一天的漲跌?為什麼不等它連漲兩個星期,再做決定?為什麼看了一天大漲,就搶著殺進?這就是自己被貪字沖昏頭的樣子嗎?

    + +

    看著三天大賠兩萬的帳目。兩萬不是小錢,也不好賺。這次花了一筆大錢買了教訓,心如刀割之餘,深切反省。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 123 | + 124 | + 125 | + 126 | + 127 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0125.html.zh-cn.html b/htdocs/imacat/me/diary/0125.html.zh-cn.html new file mode 120000 index 0000000..1028e6c --- /dev/null +++ b/htdocs/imacat/me/diary/0125.html.zh-cn.html @@ -0,0 +1 @@ +0125.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0125.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0125.html.zh-cn.xhtml new file mode 100644 index 0000000..03d6d7b --- /dev/null +++ b/htdocs/imacat/me/diary/0125.html.zh-cn.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百二十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百二十五

    + +
    + +
    + +
    +
    8.22.’07. 5:18pm.
    + +

    教训

    + +

    这两天基金赎回的款项陆续入帐,又整理了一次基金帐,把实际赎回金额和和计算的金额一一比对。

    + +

    还好,帮小招买的那笔,赎回日正逢星期一反弹,只赔了三千,从年初算下来还有赚七千,算赔得少。这毕竟不是我的钱,虽说已经跟小招讲清楚投资的风险,可是赔了别人的钱,还是比赔自己的还要怕。

    + +

    自己那笔就没那么好看了。三天赔了两万,近十七万一下子剩不到十五万,触目惊心。

    + +

    在空大上个人投资理财课时,课本有特别教,买基金不是炒短线,要看六个月、两年以上的长期。不管是哪里读的基金文章,也都有特别强调。今天苹果日报财经版,也有一篇基金炒短线 小心变成拒往户。带著沉重的心情,边念边反省。这些我都知道,课本、文章不知道读过多少次。为什么还是会犯这种错?细细咀嚼著其实已经读过不知道多少次的字句,心中五味杂陈。

    + +

    不只是基金,即使是股市投资,课本也强调过,最戒一个字。要克制欲望,要中长期持有,不要炒短线。读的时候通通都知道,可是其实那个字是什么感觉,我其实不懂。知道要戒贪,可是不知道什么样叫贪,要戒的是什么。

    + +

    被一天的强烈反弹冲昏头,怕抢不到一天的好价格,怕投资没有早点放进去滚,就叫做贪。

    + +

    我买的是基金,基金是做中长线的,对六个月、两年的中长线来说,就算涨了两个星期没赚到,都不算什么。更何况是一天的涨跌?为什么不等它连涨两个星期,再做决定?为什么看了一天大涨,就抢著杀进?这就是自己被贪字冲昏头的样子吗?

    + +

    看著三天大赔两万的帐目。两万不是小钱,也不好赚。这次花了一笔大钱买了教训,心如刀割之余,深切反省。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 123 | + 124 | + 125 | + 126 | + 127 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0125.html.zh-tw.html b/htdocs/imacat/me/diary/0125.html.zh-tw.html new file mode 120000 index 0000000..aa30076 --- /dev/null +++ b/htdocs/imacat/me/diary/0125.html.zh-tw.html @@ -0,0 +1 @@ +0125.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0125.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0125.html.zh-tw.xhtml new file mode 100644 index 0000000..c58624e --- /dev/null +++ b/htdocs/imacat/me/diary/0125.html.zh-tw.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百二十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百二十五

    + +
    + +
    + +
    +
    8.22.’07. 5:18pm.
    + +

    教訓

    + +

    這兩天基金贖回的款項陸續入帳,又整理了一次基金帳,把實際贖回金額和和計算的金額一一比對。

    + +

    還好,幫小招買的那筆,贖回日正逢星期一反彈,只賠了三千,從年初算下來還有賺七千,算賠得少。這畢竟不是我的錢,雖說已經跟小招講清楚投資的風險,可是賠了別人的錢,還是比賠自己的還要怕。

    + +

    自己那筆就沒那麼好看了。三天賠了兩萬,近十七萬一下子剩不到十五萬,觸目驚心。

    + +

    在空大上個人投資理財課時,課本有特別教,買基金不是炒短線,要看六個月、兩年以上的長期。不管是哪裏讀的基金文章,也都有特別強調。今天蘋果日報財經版,也有一篇基金炒短線 小心變成拒往戶。帶著沉重的心情,邊唸邊反省。這些我都知道,課本、文章不知道讀過多少次。為什麼還是會犯這種錯?細細咀嚼著其實已經讀過不知道多少次的字句,心中五味雜陳。

    + +

    不只是基金,即使是股市投資,課本也強調過,最戒一個字。要克制欲望,要中長期持有,不要炒短線。讀的時候通通都知道,可是其實那個字是什麼感覺,我其實不懂。知道要戒貪,可是不知道什麼樣叫貪,要戒的是什麼。

    + +

    被一天的強烈反彈沖昏頭,怕搶不到一天的好價格,怕投資沒有早點放進去滾,就叫做貪。

    + +

    我買的是基金,基金是做中長線的,對六個月、兩年的中長線來說,就算漲了兩個星期沒賺到,都不算什麼。更何況是一天的漲跌?為什麼不等它連漲兩個星期,再做決定?為什麼看了一天大漲,就搶著殺進?這就是自己被貪字沖昏頭的樣子嗎?

    + +

    看著三天大賠兩萬的帳目。兩萬不是小錢,也不好賺。這次花了一筆大錢買了教訓,心如刀割之餘,深切反省。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 123 | + 124 | + 125 | + 126 | + 127 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0126.html.en.html b/htdocs/imacat/me/diary/0126.html.en.html new file mode 120000 index 0000000..bf9b37a --- /dev/null +++ b/htdocs/imacat/me/diary/0126.html.en.html @@ -0,0 +1 @@ +0126.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0126.html.en.xhtml b/htdocs/imacat/me/diary/0126.html.en.xhtml new file mode 100644 index 0000000..73569b4 --- /dev/null +++ b/htdocs/imacat/me/diary/0126.html.en.xhtml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 126 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 126

    + +
    + +
    + +
    +
    8.29.’07. 4:26am.
    + +

    レッドスティール Red Steel 赤鉄剣

    + +

    剛剛終於把赤鉄剣破完了。呼。

    + +

    剛剛上遊戲公司 Ubisoft 的 Red Steel 首頁,看到三個漢字赤鉄剣,覺得好丟臉。之前不知道,都學著網路上的通用的中文譯名,叫它赤色鋼鐵,好丟臉。赤色鋼鐵意思不清不楚,我也一直覺得很困惑。赤鉄剣就清楚多了。既然有漢字赤鉄剣,主題又明確,還是叫它赤鉄剣好了。。

    + +

    覺得好像每破完一個 Wii 遊戲,至少就要用掉一組(兩個)三號 AA 鹼性電池。電池是高污染物, Wii 還真是不環保。我開始考慮去買鎳氫充電電池組了。好貴~

    + +

    其實我對這種黑社會寫實風濃厚的遊戲,其實興趣不大。不過我有興趣的是用 Wii 手把玩射擊遊戲。我很喜歡玩射擊遊戲,在大型遊戲機台、夜市空氣槍遊戲或射擊專門遊樂場中,常常能拿到 95% 以上的命中率。聽說 Wii 手把射擊遊戲最經典的是惡靈古堡 4,其次才是赤鉄剣。不過我對恐怖遊戲更沒興趣,而且一開始我還不知道赤鉄剣是哪一類的遊戲,所以還是拿赤鉄剣來玩。

    + +

    整體上來說還不錯。和預期的一樣,電視螢幕沒有內建紅外線接收器(廢話!),光靠放在電視上方的紅外線接收器來接收,果然不能做到用眼睛對手把瞄準。即使去買射擊手槍配件來裝,也沒有用。準星的位置根本不對。所以到最後還是只能看螢幕上顯示的瞄準點射擊。如果可以直接用眼睛對準星瞄準射擊,我可以打得更好,也會更有趣。不過電視遊樂器接的是一般電視,就算 Wii 出了第二代、第三代,也是完全不可能的事,哈哈哈。

    + +

    其次是追求手感。 Wii 遙控器畢竟和手槍不同,握法不同。手槍握在槍柄上,和直接握槍身,握法姿勢、感覺完全不一樣。為此我還特地花了 290 元,去買了射擊手槍配件來裝,看能不能感覺更好。可是裝上去以後才發現,射擊板機是右手把上的 B 鈕,可是裝上手槍配件以後,手槍板機在左手手把 C 紐的位置,而 B 鈕在前面槍管下方。遊戲店老闆說這要用散彈槍的握法,右手拿槍柄操控動作,左手握槍身扣板機。唔,還真是不習慣。我還是習慣空氣槍單手擊發。我試著勉強自己習慣這種散彈槍握法。可是赤鉄剣有刀槍混合戰,碰到用武士刀的敵人,要改用刀,這時候雙手手把要拆開才能揮刀。就這樣拆拆裝裝,而且拆裝的空檔一旦忘記暫停,還會被偷襲。拆拆裝裝一陣子,我就放棄了。看樣子,那個射擊手槍配件,大概會被我冷凍起來吧。

    + +

    我還是喜歡右手單手持空氣槍,單眼擊發的感覺,真是超過癮的。如果換電視就可以解決的話,說不定我也會考慮,呵呵~ ^_*'

    + +

    赤鉄剣描寫在洛杉磯一家餐廳裏,主角美國人 Scott 和日籍未婚妻ミユ,要和準岳父佐藤初次見面時,突然遭到狙擊,準岳父和未婚妻ミユ被擄走。 Scott 趕緊追上去,卻突然被準岳父護衛竜一回擊。原來餐廳狙擊只是煙幕,真正目的是內賊竜一藉護衛之名擄走兩人。救回重傷的準岳父後,才知道準岳父是日本黑道大幫佐藤組的組長。 Scott 繼續追擊竜一,卻被他打敗,把未婚妻ミユ擄回日本,並要 Scott佐藤組信物名刀刀霧交換未婚妻ミユ。準岳父重傷死前,交代 Scott 去日本找自己以前的手下大鳥,救回女兒ミユ,並將刀霧託給 Scott 。去日本找到大鳥後,退出江湖的大鳥現在是劍道館的館主,不願意捲入殺戮,只肯私下暗助,要女兒万里子Scott 刀法,並教 Scott 去找在東京開酒吧,消息靈通的外國人 Harry TannerHarry Tanner 協助 Scott 找到竜一,可是未婚妻ミユ已經被敵對幫派東海組的老大東海綁走了。為救回未婚妻ミユScott 決心瓦解東海組的勢力,闖入被東海組吞併的前佐藤組勢力的四大部門:金融交易公司、藝妓屋、電子遊樂場、漁市,說服各區老大,將這些勢力一一奪回。直搗東海組前,為保萬全,大鳥館主幫 Scott 保管刀霧,並給 Scott 另一把館內的好刀替用。當 ScottHarry Tanner 的酒吧準備出發時,卻發現東海在酒吧樓上會議室好整以待, Scott 不及防範被 Harry Tanner 擊昏。原來 Harry Tanner東海收買了。擊倒 Harry Tanner 後,知道東海Scott 身上找不到刀霧,卻認出 Scott 身上刀上的大鳥家徽,已大軍殺入大鳥道館。 Scott 火速趕回大鳥家,救回部份的學徒,卻還是讓刀霧被搶走,並眼睜睜看著万里子被殺成重傷。從大鳥口中得知,原來東海的父親是佐藤年輕時的兄弟,一起創立佐藤組,卻因武闘派作風太過暴力,而被佐藤下令大鳥處決,事後大鳥也因處決兄弟,心灰意冷退出江湖,原以為江湖恩怨就此平息,卻沒料到東海有個兒子,會在幾十年後掀波起浪,為父報仇,甚至在身上紋上刀霧的刀紋,以示取回幫派信物刀霧的決心。為追擊東海Scott 殺入東海組的據點,救回了四個各區老大,取回了刀霧,卻還是讓東海逃脫。回大鳥家時,大鳥悲憤地告知因殺万里子的刀上餵毒,万里子重傷瀕死,他誓要殺死東海陪葬。 Scott大鳥師傅一起殺入東海家,大鳥師傅被毒刀所傷卻仍不顧生死,最後關頭 Scott 終於見到未婚妻ミユ,打敗東海,阻止憤怒的大鳥師傅殺死東海,並由東海身上取得解毒藥,救回大鳥師傅和万里子,建立新的武士傳說。

    + +

    赤鉄剣遊戲最大的特色,很多人都已經講過了,就是不殺赤鉄剣崇尚不殺,鄙棄子彈亂掃濫殺的打法。遊戲中可以撿得到很多槍彈,不需要太惜子彈,所以要不要浪費子彈亂掃,就是玩家自己的決定。為了鼓勵不要濫殺,除了以命中準確度計分外,還有一個武士精神的額外加分。如果成功降服敵人,而沒有殺死敵人,就可以得到很高的額外加分。降而不殺有兩種:刀決獲勝,敵人束手就死時,玩家可以一刀砍下去,也可以左手把朝下插,收刀入鞘。槍戰則是搶先打落敵人手上的槍枝,方法比較複雜。遊戲中有一種特殊的暫停時間模式, A 鈕平常是集中注意力瞄準,如果按 A 鈕同時手把前刺,高度集中注意力,在短時間內可以同時瞄準好幾個目標,實際上則是時間暫停,脫離瞄準畫面,顯示敵人手上槍枝的位置,供標定射擊點。當時間恢復後,就會對準敵人手上的槍枝快速射擊,擊落對方的武器。這時候只要手把上下搖動,揮手叫對方蹲下,對方就會棄械投降。成功的話會有額外加分,而且因為只有擊發一槍並且擊中目標,所以節省子彈,射擊準確度也大幅提高。而如果降服的對象是該群敵人的頭子,那整群敵人會一起投降,會省下不必要的槍林彈雨之危。有時降而不殺,降服的敵人感謝之餘,會提供額外的幫助,告訴你重要的事,供應槍械彈藥,甚至改變結局。最後的結局沒有殺死東海,才救得回中毒瀕死的大鳥師傅和万里子

    + +

    不過還是不可能完全不殺。遊戲中有各種槍枝,其中附瞄準鏡的狙擊槍,一槍斃命,用到的場合是敵人在肉眼幾乎看不到的距離下。但進入暫停時間模式時會離開瞄準鏡,這時又看不見對手。到最後還是只能一槍一個。就算不用長狙擊槍,對手太遠時,一樣不可能瞄準手上的武器。另外,敵人突然大群湧來,又找不到地方掩蔽時,最好有衝鋒槍掃射,把大群敵人驅散。這時候只能看到誰冒出來就往那邊掃,就算打落槍枝也沒空打投降手勢,也很難要講不殺。而且暫停時間要消耗注意力點數,而注意力點數要靠準確擊中敵人累積,如果注意力點數消耗完了,也只能一槍一槍打補回來,這時候也顧不得不殺了。

    + +

    這讓我想到中後期後只會打對手武器,不殺人的城市獵人。無論如何,能夠儘可能用不殺人的方法解決事情,還是很好的。万里子在主角面前被砍成重傷那一幕,瞬間讓人非常憤怒。沒想到万里子最後還是救回來了,沒有死,結局算不錯的。如果是吳宇森的電影,大概不管主角配角通通都要死吧。

    + +

    我找到的是日版,英語語音對話,日文字幕。我邊聽英語語音對話,邊看日文字幕,再上網對照英文的攻略和劇情,好不容易才弄懂從頭到尾的故事,頗為辛苦。 3D 畫面,瞄準點不小心超出畫面邊緣,畫面就會暈頭轉向,玩久了會心悸噁心,我也花了好一段時間適應。

    + +

    遊戲中的各種槍械,也表現得很不錯。看情況,在敵人如浪堵在前面難以前進時,可以乾脆拿起烏茲衝鋒槍,邊硬衝邊掃射,雖然準確度和威力不足,子彈耗得極快,但也足夠暫阻敵人火力,強行突破了。如果敵人遠在肉眼看不清楚的距離,一般槍枝都打不到,也可以改用狙擊槍,慢慢瞄準。敵人突然出現,猝不及防時,散彈槍不用瞄準,殺傷力也很強。三款長步槍,有可以連續三發點放的自動步槍,足以暫代烏茲衝鋒槍,雖可攜子彈數不及,但威力更大;或是雖無法連續射擊,但威力和射程僅略遜狙擊槍,瞄準後可一槍斃命,子彈也比較好撿的 SCAR 。還有三、四款手槍如柯特自動手槍、左輪等,用慣的話,都不比長槍差。柯特自動手槍一次可裝填 20 發子彈,可攜帶多達 200 發,續戰力很強,小心打再配上降服的話,一槍破一關也不是不可能的事。我愛用的是中後期出現的 MP7 輕機槍,可連續發射,像烏茲一樣彈匣 45 發,可攜彈 240 發,危急時可以像烏茲一樣掃,平常也可以像手槍單擊,雖然子彈不大好撿,但不亂掃滿匣可以用很久。威力和準確度雖然有差,但要擊落對方武器也夠了,近距離瞄準頭胸也可以一槍斃命。遊戲中一次只能帶兩把槍,一把 MP7 輕機槍加一把狙擊槍,長短距離就都可以兼顧了。

    + +

    除了這些外,畫面和配樂也算是蠻不錯的,日美混合黑道風的感覺很強烈。不過我還是沒有很喜歡寫實黑道風就是了。 ^^;

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 124 | + 125 | + 126 | + 127 | + 128 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0126.html.zh-cn.html b/htdocs/imacat/me/diary/0126.html.zh-cn.html new file mode 120000 index 0000000..a3b53f2 --- /dev/null +++ b/htdocs/imacat/me/diary/0126.html.zh-cn.html @@ -0,0 +1 @@ +0126.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0126.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0126.html.zh-cn.xhtml new file mode 100644 index 0000000..c1e793c --- /dev/null +++ b/htdocs/imacat/me/diary/0126.html.zh-cn.xhtml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百二十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百二十六

    + +
    + +
    + +
    +
    8.29.’07. 4:26am.
    + +

    レッドスティール Red Steel 赤鉄剣

    + +

    刚刚终於把赤鉄剣破完了。呼。

    + +

    刚刚上游戏公司 Ubisoft 的 Red Steel 首页,看到三个汉字赤鉄剣,觉得好丢脸。之前不知道,都学著网路上的通用的中文译名,叫它赤色钢铁,好丢脸。赤色钢铁意思不清不楚,我也一直觉得很困惑。赤鉄剣就清楚多了。既然有汉字赤鉄剣,主题又明确,还是叫它赤鉄剣好了。。

    + +

    觉得好像每破完一个 Wii 游戏,至少就要用掉一组(两个)三号 AA 硷性电池。电池是高污染物, Wii 还真是不环保。我开始考虑去买镍氢充电电池组了。好贵~

    + +

    其实我对这种黑社会写实风浓厚的游戏,其实兴趣不大。不过我有兴趣的是用 Wii 手把玩射击游戏。我很喜欢玩射击游戏,在大型游戏机台、夜市空气枪游戏或射击专门游乐场中,常常能拿到 95% 以上的命中率。听说 Wii 手把射击游戏最经典的是恶灵古堡 4,其次才是赤鉄剣。不过我对恐怖游戏更没兴趣,而且一开始我还不知道赤鉄剣是哪一类的游戏,所以还是拿赤鉄剣来玩。

    + +

    整体上来说还不错。和预期的一样,电视萤幕没有内建红外线接收器(废话!),光靠放在电视上方的红外线接收器来接收,果然不能做到用眼睛对手把瞄准。即使去买射击手枪配件来装,也没有用。准星的位置根本不对。所以到最后还是只能看萤幕上显示的瞄准点射击。如果可以直接用眼睛对准星瞄准射击,我可以打得更好,也会更有趣。不过电视游乐器接的是一般电视,就算 Wii 出了第二代、第三代,也是完全不可能的事,哈哈哈。

    + +

    其次是追求手感。 Wii 遥控器毕竟和手枪不同,握法不同。手枪握在枪柄上,和直接握枪身,握法姿势、感觉完全不一样。为此我还特地花了 290 元,去买了射击手枪配件来装,看能不能感觉更好。可是装上去以后才发现,射击板机是右手把上的 B 钮,可是装上手枪配件以后,手枪板机在左手手把 C 纽的位置,而 B 钮在前面枪管下方。游戏店老板说这要用散弹枪的握法,右手拿枪柄操控动作,左手握枪身扣板机。唔,还真是不习惯。我还是习惯空气枪单手击发。我试著勉强自己习惯这种散弹枪握法。可是赤鉄剣有刀枪混合战,碰到用武士刀的敌人,要改用刀,这时候双手手把要拆开才能挥刀。就这样拆拆装装,而且拆装的空档一旦忘记暂停,还会被偷袭。拆拆装装一阵子,我就放弃了。看样子,那个射击手枪配件,大概会被我冷冻起来吧。

    + +

    我还是喜欢右手单手持空气枪,单眼击发的感觉,真是超过瘾的。如果换电视就可以解决的话,说不定我也会考虑,呵呵~ ^_*'

    + +

    赤鉄剣描写在洛杉矶一家餐厅里,主角美国人 Scott 和日籍未婚妻ミユ,要和准岳父佐藤初次见面时,突然遭到狙击,准岳父和未婚妻ミユ被掳走。 Scott 赶紧追上去,却突然被准岳父护卫竜一回击。原来餐厅狙击只是烟幕,真正目的是内贼竜一藉护卫之名掳走两人。救回重伤的准岳父后,才知道准岳父是日本黑道大帮佐藤组的组长。 Scott 继续追击竜一,却被他打败,把未婚妻ミユ掳回日本,并要 Scott佐藤组信物名刀刀雾交换未婚妻ミユ。准岳父重伤死前,交代 Scott 去日本找自己以前的手下大鸟,救回女儿ミユ,并将刀雾托给 Scott 。去日本找到大鸟后,退出江湖的大鸟现在是剑道馆的馆主,不愿意卷入杀戮,只肯私下暗助,要女儿万里子Scott 刀法,并教 Scott 去找在东京开酒吧,消息灵通的外国人 Harry TannerHarry Tanner 协助 Scott 找到竜一,可是未婚妻ミユ已经被敌对帮派东海组的老大东海绑走了。为救回未婚妻ミユScott 决心瓦解东海组的势力,闯入被东海组吞并的前佐藤组势力的四大部门:金融交易公司、艺妓屋、电子游乐场、渔市,说服各区老大,将这些势力一一夺回。直捣东海组前,为保万全,大鸟馆主帮 Scott 保管刀雾,并给 Scott 另一把馆内的好刀替用。当 ScottHarry Tanner 的酒吧准备出发时,却发现东海在酒吧楼上会议室好整以待, Scott 不及防范被 Harry Tanner 击昏。原来 Harry Tanner东海收买了。击倒 Harry Tanner 后,知道东海Scott 身上找不到刀雾,却认出 Scott 身上刀上的大鸟家徽,已大军杀入大鸟道馆。 Scott 火速赶回大鸟家,救回部份的学徒,却还是让刀雾被抢走,并眼睁睁看著万里子被杀成重伤。从大鸟口中得知,原来东海的父亲是佐藤年轻时的兄弟,一起创立佐藤组,却因武闘派作风太过暴力,而被佐藤下令大鸟处决,事后大鸟也因处决兄弟,心灰意冷退出江湖,原以为江湖恩怨就此平息,却没料到东海有个儿子,会在几十年后掀波起浪,为父报仇,甚至在身上纹上刀雾的刀纹,以示取回帮派信物刀雾的决心。为追击东海Scott 杀入东海组的据点,救回了四个各区老大,取回了刀雾,却还是让东海逃脱。回大鸟家时,大鸟悲愤地告知因杀万里子的刀上喂毒,万里子重伤濒死,他誓要杀死东海陪葬。 Scott大鸟师傅一起杀入东海家,大鸟师傅被毒刀所伤却仍不顾生死,最后关头 Scott 终於见到未婚妻ミユ,打败东海,阻止愤怒的大鸟师傅杀死东海,并由东海身上取得解毒药,救回大鸟师傅和万里子,建立新的武士传说。

    + +

    赤鉄剣游戏最大的特色,很多人都已经讲过了,就是不杀赤鉄剣崇尚不杀,鄙弃子弹乱扫滥杀的打法。游戏中可以捡得到很多枪弹,不需要太惜子弹,所以要不要浪费子弹乱扫,就是玩家自己的决定。为了鼓励不要滥杀,除了以命中准确度计分外,还有一个武士精神的额外加分。如果成功降服敌人,而没有杀死敌人,就可以得到很高的额外加分。降而不杀有两种:刀决获胜,敌人束手就死时,玩家可以一刀砍下去,也可以左手把朝下插,收刀入鞘。枪战则是抢先打落敌人手上的枪枝,方法比较复杂。游戏中有一种特殊的暂停时间模式, A 钮平常是集中注意力瞄准,如果按 A 钮同时手把前刺,高度集中注意力,在短时间内可以同时瞄准好几个目标,实际上则是时间暂停,脱离瞄准画面,显示敌人手上枪枝的位置,供标定射击点。当时间恢复后,就会对准敌人手上的枪枝快速射击,击落对方的武器。这时候只要手把上下摇动,挥手叫对方蹲下,对方就会弃械投降。成功的话会有额外加分,而且因为只有击发一枪并且击中目标,所以节省子弹,射击准确度也大幅提高。而如果降服的对象是该群敌人的头子,那整群敌人会一起投降,会省下不必要的枪林弹雨之危。有时降而不杀,降服的敌人感谢之余,会提供额外的帮助,告诉你重要的事,供应枪械弹药,甚至改变结局。最后的结局没有杀死东海,才救得回中毒濒死的大鸟师傅和万里子

    + +

    不过还是不可能完全不杀。游戏中有各种枪枝,其中附瞄准镜的狙击枪,一枪毙命,用到的场合是敌人在肉眼几乎看不到的距离下。但进入暂停时间模式时会离开瞄准镜,这时又看不见对手。到最后还是只能一枪一个。就算不用长狙击枪,对手太远时,一样不可能瞄准手上的武器。另外,敌人突然大群涌来,又找不到地方掩蔽时,最好有冲锋枪扫射,把大群敌人驱散。这时候只能看到谁冒出来就往那边扫,就算打落枪枝也没空打投降手势,也很难要讲不杀。而且暂停时间要消耗注意力点数,而注意力点数要靠准确击中敌人累积,如果注意力点数消耗完了,也只能一枪一枪打补回来,这时候也顾不得不杀了。

    + +

    这让我想到中后期后只会打对手武器,不杀人的城市猎人。无论如何,能够尽可能用不杀人的方法解决事情,还是很好的。万里子在主角面前被砍成重伤那一幕,瞬间让人非常愤怒。没想到万里子最后还是救回来了,没有死,结局算不错的。如果是吴宇森的电影,大概不管主角配角通通都要死吧。

    + +

    我找到的是日版,英语语音对话,日文字幕。我边听英语语音对话,边看日文字幕,再上网对照英文的攻略和剧情,好不容易才弄懂从头到尾的故事,颇为辛苦。 3D 画面,瞄准点不小心超出画面边缘,画面就会晕头转向,玩久了会心悸恶心,我也花了好一段时间适应。

    + +

    游戏中的各种枪械,也表现得很不错。看情况,在敌人如浪堵在前面难以前进时,可以干脆拿起乌兹冲锋枪,边硬冲边扫射,虽然准确度和威力不足,子弹耗得极快,但也足够暂阻敌人火力,强行突破了。如果敌人远在肉眼看不清楚的距离,一般枪枝都打不到,也可以改用狙击枪,慢慢瞄准。敌人突然出现,猝不及防时,散弹枪不用瞄准,杀伤力也很强。三款长步枪,有可以连续三发点放的自动步枪,足以暂代乌兹冲锋枪,虽可携子弹数不及,但威力更大;或是虽无法连续射击,但威力和射程仅略逊狙击枪,瞄准后可一枪毙命,子弹也比较好捡的 SCAR 。还有三、四款手枪如柯特自动手枪、左轮等,用惯的话,都不比长枪差。柯特自动手枪一次可装填 20 发子弹,可携带多达 200 发,续战力很强,小心打再配上降服的话,一枪破一关也不是不可能的事。我爱用的是中后期出现的 MP7 轻机枪,可连续发射,像乌兹一样弹匣 45 发,可携弹 240 发,危急时可以像乌兹一样扫,平常也可以像手枪单击,虽然子弹不大好捡,但不乱扫满匣可以用很久。威力和准确度虽然有差,但要击落对方武器也够了,近距离瞄准头胸也可以一枪毙命。游戏中一次只能带两把枪,一把 MP7 轻机枪加一把狙击枪,长短距离就都可以兼顾了。

    + +

    除了这些外,画面和配乐也算是蛮不错的,日美混合黑道风的感觉很强烈。不过我还是没有很喜欢写实黑道风就是了。 ^^;

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 124 | + 125 | + 126 | + 127 | + 128 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0126.html.zh-tw.html b/htdocs/imacat/me/diary/0126.html.zh-tw.html new file mode 120000 index 0000000..6f38fce --- /dev/null +++ b/htdocs/imacat/me/diary/0126.html.zh-tw.html @@ -0,0 +1 @@ +0126.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0126.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0126.html.zh-tw.xhtml new file mode 100644 index 0000000..225abb7 --- /dev/null +++ b/htdocs/imacat/me/diary/0126.html.zh-tw.xhtml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百二十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百二十六

    + +
    + +
    + +
    +
    8.29.’07. 4:26am.
    + +

    レッドスティール Red Steel 赤鉄剣

    + +

    剛剛終於把赤鉄剣破完了。呼。

    + +

    剛剛上遊戲公司 Ubisoft 的 Red Steel 首頁,看到三個漢字赤鉄剣,覺得好丟臉。之前不知道,都學著網路上的通用的中文譯名,叫它赤色鋼鐵,好丟臉。赤色鋼鐵意思不清不楚,我也一直覺得很困惑。赤鉄剣就清楚多了。既然有漢字赤鉄剣,主題又明確,還是叫它赤鉄剣好了。。

    + +

    覺得好像每破完一個 Wii 遊戲,至少就要用掉一組(兩個)三號 AA 鹼性電池。電池是高污染物, Wii 還真是不環保。我開始考慮去買鎳氫充電電池組了。好貴~

    + +

    其實我對這種黑社會寫實風濃厚的遊戲,其實興趣不大。不過我有興趣的是用 Wii 手把玩射擊遊戲。我很喜歡玩射擊遊戲,在大型遊戲機台、夜市空氣槍遊戲或射擊專門遊樂場中,常常能拿到 95% 以上的命中率。聽說 Wii 手把射擊遊戲最經典的是惡靈古堡 4,其次才是赤鉄剣。不過我對恐怖遊戲更沒興趣,而且一開始我還不知道赤鉄剣是哪一類的遊戲,所以還是拿赤鉄剣來玩。

    + +

    整體上來說還不錯。和預期的一樣,電視螢幕沒有內建紅外線接收器(廢話!),光靠放在電視上方的紅外線接收器來接收,果然不能做到用眼睛對手把瞄準。即使去買射擊手槍配件來裝,也沒有用。準星的位置根本不對。所以到最後還是只能看螢幕上顯示的瞄準點射擊。如果可以直接用眼睛對準星瞄準射擊,我可以打得更好,也會更有趣。不過電視遊樂器接的是一般電視,就算 Wii 出了第二代、第三代,也是完全不可能的事,哈哈哈。

    + +

    其次是追求手感。 Wii 遙控器畢竟和手槍不同,握法不同。手槍握在槍柄上,和直接握槍身,握法姿勢、感覺完全不一樣。為此我還特地花了 290 元,去買了射擊手槍配件來裝,看能不能感覺更好。可是裝上去以後才發現,射擊板機是右手把上的 B 鈕,可是裝上手槍配件以後,手槍板機在左手手把 C 紐的位置,而 B 鈕在前面槍管下方。遊戲店老闆說這要用散彈槍的握法,右手拿槍柄操控動作,左手握槍身扣板機。唔,還真是不習慣。我還是習慣空氣槍單手擊發。我試著勉強自己習慣這種散彈槍握法。可是赤鉄剣有刀槍混合戰,碰到用武士刀的敵人,要改用刀,這時候雙手手把要拆開才能揮刀。就這樣拆拆裝裝,而且拆裝的空檔一旦忘記暫停,還會被偷襲。拆拆裝裝一陣子,我就放棄了。看樣子,那個射擊手槍配件,大概會被我冷凍起來吧。

    + +

    我還是喜歡右手單手持空氣槍,單眼擊發的感覺,真是超過癮的。如果換電視就可以解決的話,說不定我也會考慮,呵呵~ ^_*'

    + +

    赤鉄剣描寫在洛杉磯一家餐廳裏,主角美國人 Scott 和日籍未婚妻ミユ,要和準岳父佐藤初次見面時,突然遭到狙擊,準岳父和未婚妻ミユ被擄走。 Scott 趕緊追上去,卻突然被準岳父護衛竜一回擊。原來餐廳狙擊只是煙幕,真正目的是內賊竜一藉護衛之名擄走兩人。救回重傷的準岳父後,才知道準岳父是日本黑道大幫佐藤組的組長。 Scott 繼續追擊竜一,卻被他打敗,把未婚妻ミユ擄回日本,並要 Scott佐藤組信物名刀刀霧交換未婚妻ミユ。準岳父重傷死前,交代 Scott 去日本找自己以前的手下大鳥,救回女兒ミユ,並將刀霧託給 Scott 。去日本找到大鳥後,退出江湖的大鳥現在是劍道館的館主,不願意捲入殺戮,只肯私下暗助,要女兒万里子Scott 刀法,並教 Scott 去找在東京開酒吧,消息靈通的外國人 Harry TannerHarry Tanner 協助 Scott 找到竜一,可是未婚妻ミユ已經被敵對幫派東海組的老大東海綁走了。為救回未婚妻ミユScott 決心瓦解東海組的勢力,闖入被東海組吞併的前佐藤組勢力的四大部門:金融交易公司、藝妓屋、電子遊樂場、漁市,說服各區老大,將這些勢力一一奪回。直搗東海組前,為保萬全,大鳥館主幫 Scott 保管刀霧,並給 Scott 另一把館內的好刀替用。當 ScottHarry Tanner 的酒吧準備出發時,卻發現東海在酒吧樓上會議室好整以待, Scott 不及防範被 Harry Tanner 擊昏。原來 Harry Tanner東海收買了。擊倒 Harry Tanner 後,知道東海Scott 身上找不到刀霧,卻認出 Scott 身上刀上的大鳥家徽,已大軍殺入大鳥道館。 Scott 火速趕回大鳥家,救回部份的學徒,卻還是讓刀霧被搶走,並眼睜睜看著万里子被殺成重傷。從大鳥口中得知,原來東海的父親是佐藤年輕時的兄弟,一起創立佐藤組,卻因武闘派作風太過暴力,而被佐藤下令大鳥處決,事後大鳥也因處決兄弟,心灰意冷退出江湖,原以為江湖恩怨就此平息,卻沒料到東海有個兒子,會在幾十年後掀波起浪,為父報仇,甚至在身上紋上刀霧的刀紋,以示取回幫派信物刀霧的決心。為追擊東海Scott 殺入東海組的據點,救回了四個各區老大,取回了刀霧,卻還是讓東海逃脫。回大鳥家時,大鳥悲憤地告知因殺万里子的刀上餵毒,万里子重傷瀕死,他誓要殺死東海陪葬。 Scott大鳥師傅一起殺入東海家,大鳥師傅被毒刀所傷卻仍不顧生死,最後關頭 Scott 終於見到未婚妻ミユ,打敗東海,阻止憤怒的大鳥師傅殺死東海,並由東海身上取得解毒藥,救回大鳥師傅和万里子,建立新的武士傳說。

    + +

    赤鉄剣遊戲最大的特色,很多人都已經講過了,就是不殺赤鉄剣崇尚不殺,鄙棄子彈亂掃濫殺的打法。遊戲中可以撿得到很多槍彈,不需要太惜子彈,所以要不要浪費子彈亂掃,就是玩家自己的決定。為了鼓勵不要濫殺,除了以命中準確度計分外,還有一個武士精神的額外加分。如果成功降服敵人,而沒有殺死敵人,就可以得到很高的額外加分。降而不殺有兩種:刀決獲勝,敵人束手就死時,玩家可以一刀砍下去,也可以左手把朝下插,收刀入鞘。槍戰則是搶先打落敵人手上的槍枝,方法比較複雜。遊戲中有一種特殊的暫停時間模式, A 鈕平常是集中注意力瞄準,如果按 A 鈕同時手把前刺,高度集中注意力,在短時間內可以同時瞄準好幾個目標,實際上則是時間暫停,脫離瞄準畫面,顯示敵人手上槍枝的位置,供標定射擊點。當時間恢復後,就會對準敵人手上的槍枝快速射擊,擊落對方的武器。這時候只要手把上下搖動,揮手叫對方蹲下,對方就會棄械投降。成功的話會有額外加分,而且因為只有擊發一槍並且擊中目標,所以節省子彈,射擊準確度也大幅提高。而如果降服的對象是該群敵人的頭子,那整群敵人會一起投降,會省下不必要的槍林彈雨之危。有時降而不殺,降服的敵人感謝之餘,會提供額外的幫助,告訴你重要的事,供應槍械彈藥,甚至改變結局。最後的結局沒有殺死東海,才救得回中毒瀕死的大鳥師傅和万里子

    + +

    不過還是不可能完全不殺。遊戲中有各種槍枝,其中附瞄準鏡的狙擊槍,一槍斃命,用到的場合是敵人在肉眼幾乎看不到的距離下。但進入暫停時間模式時會離開瞄準鏡,這時又看不見對手。到最後還是只能一槍一個。就算不用長狙擊槍,對手太遠時,一樣不可能瞄準手上的武器。另外,敵人突然大群湧來,又找不到地方掩蔽時,最好有衝鋒槍掃射,把大群敵人驅散。這時候只能看到誰冒出來就往那邊掃,就算打落槍枝也沒空打投降手勢,也很難要講不殺。而且暫停時間要消耗注意力點數,而注意力點數要靠準確擊中敵人累積,如果注意力點數消耗完了,也只能一槍一槍打補回來,這時候也顧不得不殺了。

    + +

    這讓我想到中後期後只會打對手武器,不殺人的城市獵人。無論如何,能夠儘可能用不殺人的方法解決事情,還是很好的。万里子在主角面前被砍成重傷那一幕,瞬間讓人非常憤怒。沒想到万里子最後還是救回來了,沒有死,結局算不錯的。如果是吳宇森的電影,大概不管主角配角通通都要死吧。

    + +

    我找到的是日版,英語語音對話,日文字幕。我邊聽英語語音對話,邊看日文字幕,再上網對照英文的攻略和劇情,好不容易才弄懂從頭到尾的故事,頗為辛苦。 3D 畫面,瞄準點不小心超出畫面邊緣,畫面就會暈頭轉向,玩久了會心悸噁心,我也花了好一段時間適應。

    + +

    遊戲中的各種槍械,也表現得很不錯。看情況,在敵人如浪堵在前面難以前進時,可以乾脆拿起烏茲衝鋒槍,邊硬衝邊掃射,雖然準確度和威力不足,子彈耗得極快,但也足夠暫阻敵人火力,強行突破了。如果敵人遠在肉眼看不清楚的距離,一般槍枝都打不到,也可以改用狙擊槍,慢慢瞄準。敵人突然出現,猝不及防時,散彈槍不用瞄準,殺傷力也很強。三款長步槍,有可以連續三發點放的自動步槍,足以暫代烏茲衝鋒槍,雖可攜子彈數不及,但威力更大;或是雖無法連續射擊,但威力和射程僅略遜狙擊槍,瞄準後可一槍斃命,子彈也比較好撿的 SCAR 。還有三、四款手槍如柯特自動手槍、左輪等,用慣的話,都不比長槍差。柯特自動手槍一次可裝填 20 發子彈,可攜帶多達 200 發,續戰力很強,小心打再配上降服的話,一槍破一關也不是不可能的事。我愛用的是中後期出現的 MP7 輕機槍,可連續發射,像烏茲一樣彈匣 45 發,可攜彈 240 發,危急時可以像烏茲一樣掃,平常也可以像手槍單擊,雖然子彈不大好撿,但不亂掃滿匣可以用很久。威力和準確度雖然有差,但要擊落對方武器也夠了,近距離瞄準頭胸也可以一槍斃命。遊戲中一次只能帶兩把槍,一把 MP7 輕機槍加一把狙擊槍,長短距離就都可以兼顧了。

    + +

    除了這些外,畫面和配樂也算是蠻不錯的,日美混合黑道風的感覺很強烈。不過我還是沒有很喜歡寫實黑道風就是了。 ^^;

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 124 | + 125 | + 126 | + 127 | + 128 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0127.html.en.html b/htdocs/imacat/me/diary/0127.html.en.html new file mode 120000 index 0000000..0edb6f1 --- /dev/null +++ b/htdocs/imacat/me/diary/0127.html.en.html @@ -0,0 +1 @@ +0127.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0127.html.en.xhtml b/htdocs/imacat/me/diary/0127.html.en.xhtml new file mode 100644 index 0000000..050549b --- /dev/null +++ b/htdocs/imacat/me/diary/0127.html.en.xhtml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 127 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 127

    + +
    + +
    + +
    +
    9.8.’07. 0:54am.
    + +

    惡靈古堡 4

    + +

    雖然說不喜歡驚悚恐怖類的遊戲,可是不知道為什麼,還是撩落去了。 ^^;

    + +

    最近在玩惡靈古堡 4,還沒玩完。我覺得惡靈古堡 4真的是有夠變態的。驚悚恐怖的部份我還可以接受,我玩的是日版,聽說日版比美版修剪掉不少血腥暴力場景和劇情。不過其實我還可以接受,雖然玩的遊戲內容不完整有點可惜,不過我只找得到日版,找不到美版,也是沒有辦法的事。

    + +

    不過我覺得最變態的不在於此。惡靈古堡 4的難度真的是太~高了。我玩普通級,想說大概不會玩第二次,所以沒有選簡單級和業餘級。可是,裏面的關卡難度真是有夠恐怖的。第二章最後的魔王村長,有兩段變身,我就受不了了,光第一段變身就不知道重打了多少次,還有第二段變身,根本沒有力氣再應付。到最後我狠下心,花大錢買了一支火箭炮,重玩幾十次好不容易打完第一段變身,就不陪牠玩了,第二段變身直接舉起火箭炮用轟的。我現在到第三章古堡,幾乎每一個房間都要重走好幾次,一直死一直死。前面章節的魔王,後面又變成了一般的敵人出現,當魔王打就打得疲於奔命了,現在竟然又一直冒出來,快瘋掉了。

    + +

    武器彈藥醫藥都不多,皮箱空間也不大夠。我覺得最重要的是要節省醫藥,其次是彈藥。碰到敵人被打到哀嚎的瞬間,能砍就砍,能踢就踢,因為你永遠不知道下一個房間,會不會有一大群一起擁上來,只能拼命轟回去。最後是錢。錢還真的蠻難撿的,可是買新武器改造武器,到後來價目表越來越貴,嚇死人了。

    + +
    + +
    + +
    +
    9.5.’07. 9:42pm.
    + +

    屈臣氏

    + +

    我一直都很不喜歡屈臣氏。最主要不喜歡它不誠實的紀錄。 2002 年,屈臣氏在電視上強打我敢發誓的廣告,找了許多明星和員工代言,發誓它賣的商品最便宜,並打出買貴退兩倍差價的保證,一時業績大幅成長。但不久卻被踢爆,屈臣氏的商品並沒有如它自己所發誓的最便宜,而且當消費者要求退兩倍差價時,又百般推託。我覺得一個商家做生意,誠實信譽是最重要的事。像這樣不誠實的商家,我幾年來主動拒買,除非全世界都買不到了,否則絕不踏入屈臣氏一步。

    + +

    可是,這一年來,為了買獅王超軟天然鬃毛牙刷siboley 炭洗顏,這走遍各地超市、商場、藥妝店,都買不到,到最後還是只能踏進屈臣氏。在交涉的過程中,我不得不承認,屈臣氏的服務比較熱心。為了買獅王超軟天然鬃毛牙刷,我打電話問台灣獅王,台灣獅王告訴我他們有出貨給屈臣氏。我走進屈臣氏門市找不到,接著問店員,店員一找架上沒有,就回去查電腦,打電話給總公司,查詢最近有貨的門市,並打電話到這些門市確認,花了半個小時電話往返,最後硬是給了我兩家門市的電話地址。我當然真的買到了。至於超好用又最難買的 siboley 炭洗顏,我上網到處問,還寫信給之前買過的松青超市,上 PChome 商店街問賣洗面乳保養品的店家,還上 Yahoo! 知識去問,到最後,只有屈臣氏給我正面的回覆,還問我住在哪裏,給我六家附近有貨的門市。我一家一家去找,架上沒有,店員就查電腦,回倉庫裏找,到處問,硬是從預備退貨的倉庫中找出來給我。而且不是只有一家門市這樣,幾乎每家門市都這麼熱心。這麼好用又難買的東西,我當然就二話不說,有多少支都全部買下來了。

    + +

    像這樣的服務,我不得不承認,台灣沒有幾家商家肯這樣做。架上看沒有就沒有了,要不要買別的隨便妳,連電腦庫存都不會去查,更不可能進倉庫挖。即使我不喜歡不誠實的商家,但還是不得不承認,屈臣氏的服務真的很好,沒有話說。

    + +
    + +
    + +
    +
    9.4.’07. 2:24pm.
    + +

    基金

    + +

    經過兩個星期穩定觀察後,我終於又投進去買基金了。

    + +

    這段期間,我改寫了基金績效篩選程式,原先秀的是排名名次,改秀排名百分比,篩選也以排名百分比篩選。之前當我在篩選績效排名前十五名的基金時,同類兩檔中第二名的,和同類九十檔第二名的,會排在一起,失去排名篩選的意義。改用排名百分比,就可以搜尋如:同類前四分之一、同類前三分之一等條件,例如基金基礎入門的「四四三三法則」:一年、兩年績效同類排名前四分之一,三個月、六個月績效同類排名前三分之一,也可以做得出來。

    + +

    用這個方法,我選了長期排名表現超穩定的統一大滿貫,還有我熟悉的臺灣工銀2000高科技,以二比一買進去。希望這次,真的能夠一放就放五年,只有新買入,不要去動持有的基金了。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 125 | + 126 | + 127 | + 128 | + 129 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0127.html.zh-cn.html b/htdocs/imacat/me/diary/0127.html.zh-cn.html new file mode 120000 index 0000000..ddc702e --- /dev/null +++ b/htdocs/imacat/me/diary/0127.html.zh-cn.html @@ -0,0 +1 @@ +0127.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0127.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0127.html.zh-cn.xhtml new file mode 100644 index 0000000..ed78292 --- /dev/null +++ b/htdocs/imacat/me/diary/0127.html.zh-cn.xhtml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百二十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百二十七

    + +
    + +
    + +
    +
    9.8.’07. 0:54am.
    + +

    恶灵古堡 4

    + +

    虽然说不喜欢惊悚恐怖类的游戏,可是不知道为什么,还是撩落去了。 ^^;

    + +

    最近在玩恶灵古堡 4,还没玩完。我觉得恶灵古堡 4真的是有够变态的。惊悚恐怖的部份我还可以接受,我玩的是日版,听说日版比美版修剪掉不少血腥暴力场景和剧情。不过其实我还可以接受,虽然玩的游戏内容不完整有点可惜,不过我只找得到日版,找不到美版,也是没有办法的事。

    + +

    不过我觉得最变态的不在於此。恶灵古堡 4的难度真的是太~高了。我玩普通级,想说大概不会玩第二次,所以没有选简单级和业余级。可是,里面的关卡难度真是有够恐怖的。第二章最后的魔王村长,有两段变身,我就受不了了,光第一段变身就不知道重打了多少次,还有第二段变身,根本没有力气再应付。到最后我狠下心,花大钱买了一支火箭炮,重玩几十次好不容易打完第一段变身,就不陪它玩了,第二段变身直接举起火箭炮用轰的。我现在到第三章古堡,几乎每一个房间都要重走好几次,一直死一直死。前面章节的魔王,后面又变成了一般的敌人出现,当魔王打就打得疲於奔命了,现在竟然又一直冒出来,快疯掉了。

    + +

    武器弹药医药都不多,皮箱空间也不大够。我觉得最重要的是要节省医药,其次是弹药。碰到敌人被打到哀嚎的瞬间,能砍就砍,能踢就踢,因为你永远不知道下一个房间,会不会有一大群一起拥上来,只能拼命轰回去。最后是钱。钱还真的蛮难捡的,可是买新武器改造武器,到后来价目表越来越贵,吓死人了。

    + +
    + +
    + +
    +
    9.5.’07. 9:42pm.
    + +

    屈臣氏

    + +

    我一直都很不喜欢屈臣氏。最主要不喜欢它不诚实的纪录。 2002 年,屈臣氏在电视上强打我敢发誓的广告,找了许多明星和员工代言,发誓它卖的商品最便宜,并打出买贵退两倍差价的保证,一时业绩大幅成长。但不久却被踢爆,屈臣氏的商品并没有如它自己所发誓的最便宜,而且当消费者要求退两倍差价时,又百般推托。我觉得一个商家做生意,诚实信誉是最重要的事。像这样不诚实的商家,我几年来主动拒买,除非全世界都买不到了,否则绝不踏入屈臣氏一步。

    + +

    可是,这一年来,为了买狮王超软天然鬃毛牙刷siboley 炭洗颜,这走遍各地超市、商场、药妆店,都买不到,到最后还是只能踏进屈臣氏。在交涉的过程中,我不得不承认,屈臣氏的服务比较热心。为了买狮王超软天然鬃毛牙刷,我打电话问台湾狮王,台湾狮王告诉我他们有出货给屈臣氏。我走进屈臣氏门市找不到,接著问店员,店员一找架上没有,就回去查电脑,打电话给总公司,查询最近有货的门市,并打电话到这些门市确认,花了半个小时电话往返,最后硬是给了我两家门市的电话地址。我当然真的买到了。至於超好用又最难买的 siboley 炭洗颜,我上网到处问,还写信给之前买过的松青超市,上 PChome 商店街问卖洗面乳保养品的店家,还上 Yahoo! 知识去问,到最后,只有屈臣氏给我正面的回覆,还问我住在哪里,给我六家附近有货的门市。我一家一家去找,架上没有,店员就查电脑,回仓库里找,到处问,硬是从预备退货的仓库中找出来给我。而且不是只有一家门市这样,几乎每家门市都这么热心。这么好用又难买的东西,我当然就二话不说,有多少支都全部买下来了。

    + +

    像这样的服务,我不得不承认,台湾没有几家商家肯这样做。架上看没有就没有了,要不要买别的随便你,连电脑库存都不会去查,更不可能进仓库挖。即使我不喜欢不诚实的商家,但还是不得不承认,屈臣氏的服务真的很好,没有话说。

    + +
    + +
    + +
    +
    9.4.’07. 2:24pm.
    + +

    基金

    + +

    经过两个星期稳定观察后,我终於又投进去买基金了。

    + +

    这段期间,我改写了基金绩效筛选程式,原先秀的是排名名次,改秀排名百分比,筛选也以排名百分比筛选。之前当我在筛选绩效排名前十五名的基金时,同类两档中第二名的,和同类九十档第二名的,会排在一起,失去排名筛选的意义。改用排名百分比,就可以搜寻如:同类前四分之一、同类前三分之一等条件,例如基金基础入门的「四四三三法则」:一年、两年绩效同类排名前四分之一,三个月、六个月绩效同类排名前三分之一,也可以做得出来。

    + +

    用这个方法,我选了长期排名表现超稳定的统一大满贯,还有我熟悉的台湾工银2000高科技,以二比一买进去。希望这次,真的能够一放就放五年,只有新买入,不要去动持有的基金了。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 125 | + 126 | + 127 | + 128 | + 129 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0127.html.zh-tw.html b/htdocs/imacat/me/diary/0127.html.zh-tw.html new file mode 120000 index 0000000..a24d2a7 --- /dev/null +++ b/htdocs/imacat/me/diary/0127.html.zh-tw.html @@ -0,0 +1 @@ +0127.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0127.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0127.html.zh-tw.xhtml new file mode 100644 index 0000000..ad31ba9 --- /dev/null +++ b/htdocs/imacat/me/diary/0127.html.zh-tw.xhtml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百二十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百二十七

    + +
    + +
    + +
    +
    9.8.’07. 0:54am.
    + +

    惡靈古堡 4

    + +

    雖然說不喜歡驚悚恐怖類的遊戲,可是不知道為什麼,還是撩落去了。 ^^;

    + +

    最近在玩惡靈古堡 4,還沒玩完。我覺得惡靈古堡 4真的是有夠變態的。驚悚恐怖的部份我還可以接受,我玩的是日版,聽說日版比美版修剪掉不少血腥暴力場景和劇情。不過其實我還可以接受,雖然玩的遊戲內容不完整有點可惜,不過我只找得到日版,找不到美版,也是沒有辦法的事。

    + +

    不過我覺得最變態的不在於此。惡靈古堡 4的難度真的是太~高了。我玩普通級,想說大概不會玩第二次,所以沒有選簡單級和業餘級。可是,裏面的關卡難度真是有夠恐怖的。第二章最後的魔王村長,有兩段變身,我就受不了了,光第一段變身就不知道重打了多少次,還有第二段變身,根本沒有力氣再應付。到最後我狠下心,花大錢買了一支火箭炮,重玩幾十次好不容易打完第一段變身,就不陪牠玩了,第二段變身直接舉起火箭炮用轟的。我現在到第三章古堡,幾乎每一個房間都要重走好幾次,一直死一直死。前面章節的魔王,後面又變成了一般的敵人出現,當魔王打就打得疲於奔命了,現在竟然又一直冒出來,快瘋掉了。

    + +

    武器彈藥醫藥都不多,皮箱空間也不大夠。我覺得最重要的是要節省醫藥,其次是彈藥。碰到敵人被打到哀嚎的瞬間,能砍就砍,能踢就踢,因為你永遠不知道下一個房間,會不會有一大群一起擁上來,只能拼命轟回去。最後是錢。錢還真的蠻難撿的,可是買新武器改造武器,到後來價目表越來越貴,嚇死人了。

    + +
    + +
    + +
    +
    9.5.’07. 9:42pm.
    + +

    屈臣氏

    + +

    我一直都很不喜歡屈臣氏。最主要不喜歡它不誠實的紀錄。 2002 年,屈臣氏在電視上強打我敢發誓的廣告,找了許多明星和員工代言,發誓它賣的商品最便宜,並打出買貴退兩倍差價的保證,一時業績大幅成長。但不久卻被踢爆,屈臣氏的商品並沒有如它自己所發誓的最便宜,而且當消費者要求退兩倍差價時,又百般推託。我覺得一個商家做生意,誠實信譽是最重要的事。像這樣不誠實的商家,我幾年來主動拒買,除非全世界都買不到了,否則絕不踏入屈臣氏一步。

    + +

    可是,這一年來,為了買獅王超軟天然鬃毛牙刷siboley 炭洗顏,這走遍各地超市、商場、藥妝店,都買不到,到最後還是只能踏進屈臣氏。在交涉的過程中,我不得不承認,屈臣氏的服務比較熱心。為了買獅王超軟天然鬃毛牙刷,我打電話問台灣獅王,台灣獅王告訴我他們有出貨給屈臣氏。我走進屈臣氏門市找不到,接著問店員,店員一找架上沒有,就回去查電腦,打電話給總公司,查詢最近有貨的門市,並打電話到這些門市確認,花了半個小時電話往返,最後硬是給了我兩家門市的電話地址。我當然真的買到了。至於超好用又最難買的 siboley 炭洗顏,我上網到處問,還寫信給之前買過的松青超市,上 PChome 商店街問賣洗面乳保養品的店家,還上 Yahoo! 知識去問,到最後,只有屈臣氏給我正面的回覆,還問我住在哪裏,給我六家附近有貨的門市。我一家一家去找,架上沒有,店員就查電腦,回倉庫裏找,到處問,硬是從預備退貨的倉庫中找出來給我。而且不是只有一家門市這樣,幾乎每家門市都這麼熱心。這麼好用又難買的東西,我當然就二話不說,有多少支都全部買下來了。

    + +

    像這樣的服務,我不得不承認,台灣沒有幾家商家肯這樣做。架上看沒有就沒有了,要不要買別的隨便妳,連電腦庫存都不會去查,更不可能進倉庫挖。即使我不喜歡不誠實的商家,但還是不得不承認,屈臣氏的服務真的很好,沒有話說。

    + +
    + +
    + +
    +
    9.4.’07. 2:24pm.
    + +

    基金

    + +

    經過兩個星期穩定觀察後,我終於又投進去買基金了。

    + +

    這段期間,我改寫了基金績效篩選程式,原先秀的是排名名次,改秀排名百分比,篩選也以排名百分比篩選。之前當我在篩選績效排名前十五名的基金時,同類兩檔中第二名的,和同類九十檔第二名的,會排在一起,失去排名篩選的意義。改用排名百分比,就可以搜尋如:同類前四分之一、同類前三分之一等條件,例如基金基礎入門的「四四三三法則」:一年、兩年績效同類排名前四分之一,三個月、六個月績效同類排名前三分之一,也可以做得出來。

    + +

    用這個方法,我選了長期排名表現超穩定的統一大滿貫,還有我熟悉的臺灣工銀2000高科技,以二比一買進去。希望這次,真的能夠一放就放五年,只有新買入,不要去動持有的基金了。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 125 | + 126 | + 127 | + 128 | + 129 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0128.html.en.html b/htdocs/imacat/me/diary/0128.html.en.html new file mode 120000 index 0000000..8c35ead --- /dev/null +++ b/htdocs/imacat/me/diary/0128.html.en.html @@ -0,0 +1 @@ +0128.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0128.html.en.xhtml b/htdocs/imacat/me/diary/0128.html.en.xhtml new file mode 100644 index 0000000..8217b20 --- /dev/null +++ b/htdocs/imacat/me/diary/0128.html.en.xhtml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 128 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 128

    + +
    + +
    + +
    +
    9.11.’07. 6:35pm.
    + +

    惡靈古堡 4

    + +

    昨晚,拼死拼活下,終於一口氣破完 5-3 ,殺掉了 Krauser ,剩下 5-4 和最終章了。終於接近了惡靈古堡的尾聲。

    + +

    稍為瞄了一下攻略, 5-4 很短,看樣子第五章的魔王是 5-3 的 Krauser 。也就是說,剩下第五章收尾,和最終章的大魔王教主 Saddler 了。

    + +

    昨晚拼命一口氣從 5-2 直破到 5-3 結束,累死我了。到後來嘍囉也越來越強,就算用了花大錢改造的超火力槍械,也很難打死。 5-3 甚至一關有兩個魔王,兩個都要打持久戰,附近又沒有儲存點,沒辦法看戰果不錯就跑旁邊休息儲存一下,打 Krauser 甚至還是計時戰。魔王那麼強,動作又超快,還要東跑西跑撿東西破解機關,邊應付隨時隨地的偷襲,過程又複雜又長,一旦失敗就又要從頭重來。真是瘋了。我不想重解難跑的機關,只好拼命往前打,受傷就補血續打。結果,前面拼命存,才存到的超量彈藥,兩個魔王就敗光了。 Krauser 動作超快,看到再瞄準射擊就跑掉了,只能用連發的衝鋒槍追著打。四盒加滿匣的衝鋒槍子彈六百多發,還到處撿了六、七十發來補,打到只剩七十發。接下來只好把可以快速射擊的手槍當衝鋒槍用,八十幾發手槍彈,再加上東撿西撿四、五十發,最後也剩四十發。全滿恢復藥六瓶,還有中途撿的四瓶量,最後只剩一瓶。一開皮箱,彈藥零零落落,接下來都不知道怎麼打,真是可怕。

    + +

    昨晚睡前, 5-4 往前走了幾步看看。看到前面一個大軍營,敵人滿坑滿谷。不過都是嘍囉,可以用點技巧一個一個引出來打,或是用炸藥之類的,再慢慢把彈藥存回來。正預備一場惡戰的時候,突然出現動畫,支援的空中武裝直昇機終於來了,轟轟轟之間,一整個山谷的嘍囉都全滅了。再往前走,碰到機關槍,直昇機也用機關槍回敬,一下子就勦滅了。看樣子這台空中武裝直昇機會一直跟著我支援。好酷~玩了那麼久難度超高的惡靈古堡 4,終於有一種鬆了一口氣的感覺。

    + +

    大魔王教主 Saddler 的末日近了的感覺~

    + +
    + +
    + +
    +
    9.11.’07. 5:56pm.
    + +

    sibolet 希博蕾炭洗顏

    + +
    sibolet 炭洗顏大軍!!! +

    sibolet 炭洗顏大軍!!!

    +
    + +

    上個星期為了人在美國買不到好洗面乳的小招,四處去搜購 siboley 炭洗顏。美國真是個不方便的國家。

    + +

    siboley 希博蕾炭洗顏是由大阪的小化妝品廠 siboley 生產製造,臺灣的百陸達股份有限公司進口。有一次和小招逛街,無意間看到,覺得很特別,就買了回來用。一瓶 180 ,接近別牌的兩倍價。我知道炭會吸油,顆粒很細,有超強的吸附清潔效果,淨水器裏很常見,國中理化有學過,但做成洗面乳,我還是第一次看到。我雖然年紀不小了皮膚沒那麼油,但每天騎車迎面都是黑煙,每天臉都很髒,用了好幾種洗面乳,因為乳霜的關係,不是很油沖不乾淨,就是柔珠會扎眼括臉,或是果酸會傷膚,都不是很滿意。 siboley 炭洗顏擠出來黑黑的,打開一看有點嚇人,可是硬著頭皮實際抹上去後,效果超好,臉上超清爽,超乾淨,既沒有柔珠,也沒有乳霜,也很好沖洗。

    + +

    因為感覺超好,所以逼著看到黑黑會害怕的小招一起用。小招一用,也完全改觀了。因此,我們兩個就都成了 siboley 炭洗顏的擁護者了,家裏幾瓶別牌沒用完的都被丟到一邊。我們也開始介紹朋友用,小招的死黨、唸國中發育期皮膚最油的姪子等等。每個人一用,就都愛上了那種超清爽、超舒適的感覺。

    + +

    這段期間,因為 siboley 炭洗顏風評很好,台灣開始興起一股炭洗面乳熱,各廠都開始仿做炭洗面乳,像雅芳炭洗顏、備長炭、竹炭、醋炭、水平衡元素炭、澎澎元氣炭等等,價格當然都比低的,價格從 100 到 130 ,遠低於 siboley 炭洗顏的 180 。偶爾親友寄來,我用了一下,就不用了。仿的效果真的差很多,不是有怪味,就是加了油,不知道什麼奇怪的成份。用了半天,都還是回到 siboley 炭洗顏上。

    + +

    可是不知道是不是因為炭洗面乳競爭者太多,到後來越來越難買得到價格比人家貴很多的 siboley 炭洗顏。從以前大賣場、超市、康是美、屈臣氏都買得到,一家家減少,到後來, siboley 炭洗顏變成了珍稀逸品。競爭削價的大賣場超市,根本不進 140 以上的洗面乳。偏偏我們介紹很多人用,大家都愛上了 siboley 炭洗顏,這裏寄兩瓶那裏寄三瓶,自己卻快沒得用,不知道到哪裏買。

    + +

    我開始到處找,偶爾看到,就去領錢把架上全部搜購下來。直到到處都找不到了,又上網去找,曾經賣過的廠商,一家一家寫信去問。我怕如果 siboley 原廠停產了,就要開始找替代品了。可是這麼好用的洗面乳,到哪裏找替代品?

    + +

    上網搜尋的時候,我發現竟然有人在 Yahoo! 奇摩知識+ 上詢問siboley炭洗顏哪裡可以買的到?。回答者建議到屈臣氏。於是我也寫信給屈臣氏,就當亂槍打鳥,抱著一點不大的希望。

    + +

    沒想到幾天後,屈臣氏真的回信了,說還有在賣,還問我人在哪裏,給我有貨的門市名單。這在收到好幾封抱歉,我們不賣了的回絕信之後,燃起的希望之光,讓人感動到流淚。照著名單上的門市上去找,找到一家門市,倉庫裏還有還沒退貨的四瓶。我當然二話不說全包了。買回來超高興的。

    + +

    前一陣子小招去美國,美國買不到好用的洗面乳,我只好從台灣寄上去。可是之前送了兩瓶給人,我也只剩兩瓶。我只好再拿之前屈臣氏給我的門市名單,一家一家去跑。那個晚上還下大雨。冒著大雨跑了四家,搜購了四瓶,還有一家門市滿口保證他們會再進貨。全身濕漉漉的,可是買到了超稀逸品,超級開心。連同之前剩的總共六瓶,一字排開,頗為壯觀。

    + +

    於是,就拍了這張頗為白癡的照片。 :p

    + +

    siboley 希博蕾炭洗顏真的超好用,大家可以去屈臣氏買來試試看,保證一用就愛不離手~如果你沒有特別滿意的洗面乳,可以去買來用用看,清爽、乾淨、不油好沖洗,感覺真是超讚的~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 126 | + 127 | + 128 | + 129 | + 130 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0128.html.zh-cn.html b/htdocs/imacat/me/diary/0128.html.zh-cn.html new file mode 120000 index 0000000..93b80fc --- /dev/null +++ b/htdocs/imacat/me/diary/0128.html.zh-cn.html @@ -0,0 +1 @@ +0128.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0128.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0128.html.zh-cn.xhtml new file mode 100644 index 0000000..26d1509 --- /dev/null +++ b/htdocs/imacat/me/diary/0128.html.zh-cn.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百二十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百二十八

    + +
    + +
    + +
    +
    9.11.’07. 6:35pm.
    + +

    恶灵古堡 4

    + +

    昨晚,拼死拼活下,终於一口气破完 5-3 ,杀掉了 Krauser ,剩下 5-4 和最终章了。终於接近了恶灵古堡的尾声。

    + +

    稍为瞄了一下攻略, 5-4 很短,看样子第五章的魔王是 5-3 的 Krauser 。也就是说,剩下第五章收尾,和最终章的大魔王教主 Saddler 了。

    + +

    昨晚拼命一口气从 5-2 直破到 5-3 结束,累死我了。到后来喽罗也越来越强,就算用了花大钱改造的超火力枪械,也很难打死。 5-3 甚至一关有两个魔王,两个都要打持久战,附近又没有储存点,没办法看战果不错就跑旁边休息储存一下,打 Krauser 甚至还是计时战。魔王那么强,动作又超快,还要东跑西跑捡东西破解机关,边应付随时随地的偷袭,过程又复杂又长,一旦失败就又要从头重来。真是疯了。我不想重解难跑的机关,只好拼命往前打,受伤就补血续打。结果,前面拼命存,才存到的超量弹药,两个魔王就败光了。 Krauser 动作超快,看到再瞄准射击就跑掉了,只能用连发的冲锋枪追著打。四盒加满匣的冲锋枪子弹六百多发,还到处捡了六、七十发来补,打到只剩七十发。接下来只好把可以快速射击的手枪当冲锋枪用,八十几发手枪弹,再加上东捡西捡四、五十发,最后也剩四十发。全满恢复药六瓶,还有中途捡的四瓶量,最后只剩一瓶。一开皮箱,弹药零零落落,接下来都不知道怎么打,真是可怕。

    + +

    昨晚睡前, 5-4 往前走了几步看看。看到前面一个大军营,敌人满坑满谷。不过都是喽罗,可以用点技巧一个一个引出来打,或是用炸药之类的,再慢慢把弹药存回来。正预备一场恶战的时候,突然出现动画,支援的空中武装直升机终於来了,轰轰轰之间,一整个山谷的喽罗都全灭了。再往前走,碰到机关枪,直升机也用机关枪回敬,一下子就剿灭了。看样子这台空中武装直升机会一直跟著我支援。好酷~玩了那么久难度超高的恶灵古堡 4,终於有一种松了一口气的感觉。

    + +

    大魔王教主 Saddler 的末日近了的感觉~

    + +
    + +
    + +
    +
    9.11.’07. 5:56pm.
    + +

    sibolet 希博蕾炭洗颜

    + +
    sibolet 炭洗颜大军!!! +

    sibolet 炭洗颜大军!!!

    +
    + +

    上个星期为了人在美国买不到好洗面乳的小招,四处去搜购 siboley 炭洗颜。美国真是个不方便的国家。

    + +

    siboley 希博蕾炭洗颜是由大阪的小化妆品厂 siboley 生产制造,台湾的百陆达股份有限公司进口。有一次和小招逛街,无意间看到,觉得很特别,就买了回来用。一瓶 180 ,接近别牌的两倍价。我知道炭会吸油,颗粒很细,有超强的吸附清洁效果,净水器里很常见,国中理化有学过,但做成洗面乳,我还是第一次看到。我虽然年纪不小了皮肤没那么油,但每天骑车迎面都是黑烟,每天脸都很脏,用了好几种洗面乳,因为乳霜的关系,不是很油冲不干净,就是柔珠会扎眼括脸,或是果酸会伤肤,都不是很满意。 siboley 炭洗颜挤出来黑黑的,打开一看有点吓人,可是硬著头皮实际抹上去后,效果超好,脸上超清爽,超干净,既没有柔珠,也没有乳霜,也很好冲洗。

    + +

    因为感觉超好,所以逼著看到黑黑会害怕的小招一起用。小招一用,也完全改观了。因此,我们两个就都成了 siboley 炭洗颜的拥护者了,家里几瓶别牌没用完的都被丢到一边。我们也开始介绍朋友用,小招的死党、念国中发育期皮肤最油的侄子等等。每个人一用,就都爱上了那种超清爽、超舒适的感觉。

    + +

    这段期间,因为 siboley 炭洗颜风评很好,台湾开始兴起一股炭洗面乳热,各厂都开始仿做炭洗面乳,像雅芳炭洗颜、备长炭、竹炭、醋炭、水平衡元素炭、澎澎元气炭等等,价格当然都比低的,价格从 100 到 130 ,远低於 siboley 炭洗颜的 180 。偶尔亲友寄来,我用了一下,就不用了。仿的效果真的差很多,不是有怪味,就是加了油,不知道什么奇怪的成份。用了半天,都还是回到 siboley 炭洗颜上。

    + +

    可是不知道是不是因为炭洗面乳竞争者太多,到后来越来越难买得到价格比人家贵很多的 siboley 炭洗颜。从以前大卖场、超市、康是美、屈臣氏都买得到,一家家减少,到后来, siboley 炭洗颜变成了珍稀逸品。竞争削价的大卖场超市,根本不进 140 以上的洗面乳。偏偏我们介绍很多人用,大家都爱上了 siboley 炭洗颜,这里寄两瓶那里寄三瓶,自己却快没得用,不知道到哪里买。

    + +

    我开始到处找,偶尔看到,就去领钱把架上全部搜购下来。直到到处都找不到了,又上网去找,曾经卖过的厂商,一家一家写信去问。我怕如果 siboley 原厂停产了,就要开始找替代品了。可是这么好用的洗面乳,到哪里找替代品?

    + +

    上网搜寻的时候,我发现竟然有人在 Yahoo! 奇摩知识+ 上询问siboley炭洗颜哪里可以买的到?。回答者建议到屈臣氏。於是我也写信给屈臣氏,就当乱枪打鸟,抱著一点不大的希望。

    + +

    没想到几天后,屈臣氏真的回信了,说还有在卖,还问我人在哪里,给我有货的门市名单。这在收到好几封抱歉,我们不卖了的回绝信之后,燃起的希望之光,让人感动到流泪。照著名单上的门市上去找,找到一家门市,仓库里还有还没退货的四瓶。我当然二话不说全包了。买回来超高兴的。

    + +

    前一阵子小招去美国,美国买不到好用的洗面乳,我只好从台湾寄上去。可是之前送了两瓶给人,我也只剩两瓶。我只好再拿之前屈臣氏给我的门市名单,一家一家去跑。那个晚上还下大雨。冒著大雨跑了四家,搜购了四瓶,还有一家门市满口保证他们会再进货。全身湿漉漉的,可是买到了超稀逸品,超级开心。连同之前剩的总共六瓶,一字排开,颇为壮观。

    + +

    於是,就拍了这张颇为白痴的照片。 :p

    + +

    siboley 希博蕾炭洗颜真的超好用,大家可以去屈臣氏买来试试看,保证一用就爱不离手~如果你没有特别满意的洗面乳,可以去买来用用看,清爽、干净、不油好冲洗,感觉真是超赞的~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 126 | + 127 | + 128 | + 129 | + 130 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0128.html.zh-tw.html b/htdocs/imacat/me/diary/0128.html.zh-tw.html new file mode 120000 index 0000000..53802ba --- /dev/null +++ b/htdocs/imacat/me/diary/0128.html.zh-tw.html @@ -0,0 +1 @@ +0128.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0128.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0128.html.zh-tw.xhtml new file mode 100644 index 0000000..6063e4b --- /dev/null +++ b/htdocs/imacat/me/diary/0128.html.zh-tw.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百二十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百二十八

    + +
    + +
    + +
    +
    9.11.’07. 6:35pm.
    + +

    惡靈古堡 4

    + +

    昨晚,拼死拼活下,終於一口氣破完 5-3 ,殺掉了 Krauser ,剩下 5-4 和最終章了。終於接近了惡靈古堡的尾聲。

    + +

    稍為瞄了一下攻略, 5-4 很短,看樣子第五章的魔王是 5-3 的 Krauser 。也就是說,剩下第五章收尾,和最終章的大魔王教主 Saddler 了。

    + +

    昨晚拼命一口氣從 5-2 直破到 5-3 結束,累死我了。到後來嘍囉也越來越強,就算用了花大錢改造的超火力槍械,也很難打死。 5-3 甚至一關有兩個魔王,兩個都要打持久戰,附近又沒有儲存點,沒辦法看戰果不錯就跑旁邊休息儲存一下,打 Krauser 甚至還是計時戰。魔王那麼強,動作又超快,還要東跑西跑撿東西破解機關,邊應付隨時隨地的偷襲,過程又複雜又長,一旦失敗就又要從頭重來。真是瘋了。我不想重解難跑的機關,只好拼命往前打,受傷就補血續打。結果,前面拼命存,才存到的超量彈藥,兩個魔王就敗光了。 Krauser 動作超快,看到再瞄準射擊就跑掉了,只能用連發的衝鋒槍追著打。四盒加滿匣的衝鋒槍子彈六百多發,還到處撿了六、七十發來補,打到只剩七十發。接下來只好把可以快速射擊的手槍當衝鋒槍用,八十幾發手槍彈,再加上東撿西撿四、五十發,最後也剩四十發。全滿恢復藥六瓶,還有中途撿的四瓶量,最後只剩一瓶。一開皮箱,彈藥零零落落,接下來都不知道怎麼打,真是可怕。

    + +

    昨晚睡前, 5-4 往前走了幾步看看。看到前面一個大軍營,敵人滿坑滿谷。不過都是嘍囉,可以用點技巧一個一個引出來打,或是用炸藥之類的,再慢慢把彈藥存回來。正預備一場惡戰的時候,突然出現動畫,支援的空中武裝直昇機終於來了,轟轟轟之間,一整個山谷的嘍囉都全滅了。再往前走,碰到機關槍,直昇機也用機關槍回敬,一下子就勦滅了。看樣子這台空中武裝直昇機會一直跟著我支援。好酷~玩了那麼久難度超高的惡靈古堡 4,終於有一種鬆了一口氣的感覺。

    + +

    大魔王教主 Saddler 的末日近了的感覺~

    + +
    + +
    + +
    +
    9.11.’07. 5:56pm.
    + +

    sibolet 希博蕾炭洗顏

    + +
    sibolet 炭洗顏大軍!!! +

    sibolet 炭洗顏大軍!!!

    +
    + +

    上個星期為了人在美國買不到好洗面乳的小招,四處去搜購 siboley 炭洗顏。美國真是個不方便的國家。

    + +

    siboley 希博蕾炭洗顏是由大阪的小化妝品廠 siboley 生產製造,臺灣的百陸達股份有限公司進口。有一次和小招逛街,無意間看到,覺得很特別,就買了回來用。一瓶 180 ,接近別牌的兩倍價。我知道炭會吸油,顆粒很細,有超強的吸附清潔效果,淨水器裏很常見,國中理化有學過,但做成洗面乳,我還是第一次看到。我雖然年紀不小了皮膚沒那麼油,但每天騎車迎面都是黑煙,每天臉都很髒,用了好幾種洗面乳,因為乳霜的關係,不是很油沖不乾淨,就是柔珠會扎眼括臉,或是果酸會傷膚,都不是很滿意。 siboley 炭洗顏擠出來黑黑的,打開一看有點嚇人,可是硬著頭皮實際抹上去後,效果超好,臉上超清爽,超乾淨,既沒有柔珠,也沒有乳霜,也很好沖洗。

    + +

    因為感覺超好,所以逼著看到黑黑會害怕的小招一起用。小招一用,也完全改觀了。因此,我們兩個就都成了 siboley 炭洗顏的擁護者了,家裏幾瓶別牌沒用完的都被丟到一邊。我們也開始介紹朋友用,小招的死黨、唸國中發育期皮膚最油的姪子等等。每個人一用,就都愛上了那種超清爽、超舒適的感覺。

    + +

    這段期間,因為 siboley 炭洗顏風評很好,台灣開始興起一股炭洗面乳熱,各廠都開始仿做炭洗面乳,像雅芳炭洗顏、備長炭、竹炭、醋炭、水平衡元素炭、澎澎元氣炭等等,價格當然都比低的,價格從 100 到 130 ,遠低於 siboley 炭洗顏的 180 。偶爾親友寄來,我用了一下,就不用了。仿的效果真的差很多,不是有怪味,就是加了油,不知道什麼奇怪的成份。用了半天,都還是回到 siboley 炭洗顏上。

    + +

    可是不知道是不是因為炭洗面乳競爭者太多,到後來越來越難買得到價格比人家貴很多的 siboley 炭洗顏。從以前大賣場、超市、康是美、屈臣氏都買得到,一家家減少,到後來, siboley 炭洗顏變成了珍稀逸品。競爭削價的大賣場超市,根本不進 140 以上的洗面乳。偏偏我們介紹很多人用,大家都愛上了 siboley 炭洗顏,這裏寄兩瓶那裏寄三瓶,自己卻快沒得用,不知道到哪裏買。

    + +

    我開始到處找,偶爾看到,就去領錢把架上全部搜購下來。直到到處都找不到了,又上網去找,曾經賣過的廠商,一家一家寫信去問。我怕如果 siboley 原廠停產了,就要開始找替代品了。可是這麼好用的洗面乳,到哪裏找替代品?

    + +

    上網搜尋的時候,我發現竟然有人在 Yahoo! 奇摩知識+ 上詢問siboley炭洗顏哪裡可以買的到?。回答者建議到屈臣氏。於是我也寫信給屈臣氏,就當亂槍打鳥,抱著一點不大的希望。

    + +

    沒想到幾天後,屈臣氏真的回信了,說還有在賣,還問我人在哪裏,給我有貨的門市名單。這在收到好幾封抱歉,我們不賣了的回絕信之後,燃起的希望之光,讓人感動到流淚。照著名單上的門市上去找,找到一家門市,倉庫裏還有還沒退貨的四瓶。我當然二話不說全包了。買回來超高興的。

    + +

    前一陣子小招去美國,美國買不到好用的洗面乳,我只好從台灣寄上去。可是之前送了兩瓶給人,我也只剩兩瓶。我只好再拿之前屈臣氏給我的門市名單,一家一家去跑。那個晚上還下大雨。冒著大雨跑了四家,搜購了四瓶,還有一家門市滿口保證他們會再進貨。全身濕漉漉的,可是買到了超稀逸品,超級開心。連同之前剩的總共六瓶,一字排開,頗為壯觀。

    + +

    於是,就拍了這張頗為白癡的照片。 :p

    + +

    siboley 希博蕾炭洗顏真的超好用,大家可以去屈臣氏買來試試看,保證一用就愛不離手~如果你沒有特別滿意的洗面乳,可以去買來用用看,清爽、乾淨、不油好沖洗,感覺真是超讚的~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 126 | + 127 | + 128 | + 129 | + 130 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0129.html.en.html b/htdocs/imacat/me/diary/0129.html.en.html new file mode 120000 index 0000000..9a178f5 --- /dev/null +++ b/htdocs/imacat/me/diary/0129.html.en.html @@ -0,0 +1 @@ +0129.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0129.html.en.xhtml b/htdocs/imacat/me/diary/0129.html.en.xhtml new file mode 100644 index 0000000..3061988 --- /dev/null +++ b/htdocs/imacat/me/diary/0129.html.en.xhtml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 129 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 129

    + +
    + +
    + +
    +
    9.12.’07. 5:47am.
    + +

    惡靈古堡 4

    + +

    5-4 才沒有比較輕鬆!什麼破直昇機,也不會主動幫我打,嘍囉多火力又超強,到處都是機關槍,儲存點也不多。嚇死人了!

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 127 | + 128 | + 129 | + 130 | + 131 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0129.html.zh-cn.html b/htdocs/imacat/me/diary/0129.html.zh-cn.html new file mode 120000 index 0000000..f09fab7 --- /dev/null +++ b/htdocs/imacat/me/diary/0129.html.zh-cn.html @@ -0,0 +1 @@ +0129.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0129.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0129.html.zh-cn.xhtml new file mode 100644 index 0000000..74335b0 --- /dev/null +++ b/htdocs/imacat/me/diary/0129.html.zh-cn.xhtml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百二十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百二十九

    + +
    + +
    + +
    +
    9.12.’07. 5:47am.
    + +

    恶灵古堡 4

    + +

    5-4 才没有比较轻松!什么破直升机,也不会主动帮我打,喽罗多火力又超强,到处都是机关枪,储存点也不多。吓死人了!

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 127 | + 128 | + 129 | + 130 | + 131 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0129.html.zh-tw.html b/htdocs/imacat/me/diary/0129.html.zh-tw.html new file mode 120000 index 0000000..3abe7ba --- /dev/null +++ b/htdocs/imacat/me/diary/0129.html.zh-tw.html @@ -0,0 +1 @@ +0129.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0129.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0129.html.zh-tw.xhtml new file mode 100644 index 0000000..a4e24ab --- /dev/null +++ b/htdocs/imacat/me/diary/0129.html.zh-tw.xhtml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百二十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百二十九

    + +
    + +
    + +
    +
    9.12.’07. 5:47am.
    + +

    惡靈古堡 4

    + +

    5-4 才沒有比較輕鬆!什麼破直昇機,也不會主動幫我打,嘍囉多火力又超強,到處都是機關槍,儲存點也不多。嚇死人了!

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 127 | + 128 | + 129 | + 130 | + 131 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0130.html.en.html b/htdocs/imacat/me/diary/0130.html.en.html new file mode 120000 index 0000000..7401cf4 --- /dev/null +++ b/htdocs/imacat/me/diary/0130.html.en.html @@ -0,0 +1 @@ +0130.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0130.html.en.xhtml b/htdocs/imacat/me/diary/0130.html.en.xhtml new file mode 100644 index 0000000..ab9bdf6 --- /dev/null +++ b/htdocs/imacat/me/diary/0130.html.en.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 130 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 130

    + +
    + +
    + +
    +
    9.18.’07. 6:35pm.
    + +

    惡靈古堡 4 Wii 版 Biohazard 4 Wii Edition バイオハザード4 ウィー エディション

    + +

    花了近三個星期,終於把惡靈古堡 4破完了。呼。真是浪費生命的事。

    + +

    惡靈古堡,英文版的名字是 Resident Evil ,在日本發行時,則是取另一個英文名字 Biohazard 。所以 Resident EvilBiohazard 是同一個遊戲惡靈古堡,只是日版和美版名字不同而已。

    + +

    我可以瞭解為什麼惡靈古堡 4這麼紅了。以前專做大型機台的遊戲大公司 Capcom 果然不是蓋的。惡靈古堡 4的遊戲規則和操作方式非常簡單,沒有複雜的組合鍵,可是關卡多,又各有特色。每進入一個房間,就要開始估算地型、敵人位置,如何在最少耗彈藥最不會受傷的情況下,消滅掉該關的所有敵人,取得破關的鑰匙。說起來,很像以前大型電玩上的魂斗羅,或是 PC 上的波斯王子,只是遊戲畫面變成 3D 立體的而已,但遊戲的各項要素其實都是一樣的:簡單的操作,繁多的機關關卡,還有每一關最後的大魔王。

    + +

    說到大魔王,惡靈古堡 4其實也是勇者救公主的故事。美國總統的女兒,也算現代的公主吧~

    + +

    台灣有一個做得非常棒的惡靈古堡攻略網站惡靈深淵,另外,在GameFAQs 上的惡靈古堡 4 攻略也有非常多的攻略,其中我覺得寫得最好的,是cvxfreak 寫的惡靈古堡 4攻略DjSiXpAcK14 寫的惡靈古堡 4攻略。 cvxfreak 寫的惡靈古堡 4攻略有不少小錯誤,但整理的完整性是最好的。

    + +

    其實有個小訣竅,各家攻略都沒提到。場景交換的門,就是續玩點,地圖上看,一邊是正在探索的區域,一邊是探索過或是未探索的區域。只要從續玩點重玩,就會從上次經過這些續玩點的地方開始。而且只要從續玩點離開再進來,遊戲中還沒被殺的敵人不管是不是追在你後面,就會通通歸位。這些續玩點當然比存檔打字機還要多很多。關機時沒辦法從這些續玩點開始,只能從存檔點開始,而且一旦死了,從續玩點重玩,會增加一次死亡數,這是無法避免的。雖然如此,但續玩點可以發揮暫時存檔一樣的功能:打不好就從續玩點重打,引出一個敵人打死後就衝回續玩點,讓剩下的敵人歸位,順便暫時存檔以備萬一。好好利用續玩點,遊戲可以容易很多。

    + +

    按照攻略所說的,破完惡靈古堡 4後,破完的存檔叫出來時重啟動第二輪時,就可以買無限火箭筒 Infinite Rocket Launcher 了。不過無限火箭筒還不是很好用。先把破關紅利迷你遊戲 Ada the Spy (Assignment Ada) 破完,並把破關紅利中遊戲 The Another Order (Separate Ways) 破完一輪。 Ada the Spy 完成,並破完一次 The Another OrderThe Another Order 的第二輪起,就可以以 30 萬買芝加哥打字機(湯普森衝鋒槍) Chicago Typewritter (Tompson Submachine Gun) 了。同樣,破完一次 The Another Order 後,把主遊戲第一輪破完存檔叫出來玩第二輪時,就又會多一百萬的芝加哥打字機(湯普森衝鋒槍) Chicago Typewritter (Tompson Submachine Gun) 。遊戲中的湯普森衝鋒槍真的超強,除了每發子彈的火力是基本手槍的十倍外,還可以連發,等於 10 的火力瞬間一直開出來加乘。更恐怖的是它的子彈還是無限,根本不用愛惜子彈。

    + +

    有人說只要一把湯普森衝鋒槍,就可以代替遊戲中所有其它的槍械了。不過我再玩了一輪,不大可能,有些敵人就是遠到衝鋒槍打不到,如果不要留半自動來福槍的話,就要搭配無限火箭筒才行。火箭筒有瞄準鏡可以放大,可以代替半自動來福槍用。 4-1 鐘樓對面的子城,城牆上有三個投石器,那個距離是一般槍枝打不到的距離。換上無限火箭筒,一個火箭轟掉一個投石器,真的超酷的。

    + +

    我這麼拼,就是想拿到湯普森衝鋒槍,一掃之前像地獄一樣,辛苦了玩三個星期的穢氣。我在網路上看到有人第二輪的 3-2 拿到了湯普森衝鋒槍,不過其實不用這麼久。只要第一輪沒有亂花錢,第二輪時身上的東西全部賣掉,也有 97 萬。所以只要再存 3 萬就夠了。我第二輪 1-2 就存到了,把身上的東西全部賣一賣,就買到湯普森衝鋒槍了。至於無限火箭筒,只要有湯普森衝鋒槍,就不再需要彈藥,接下來撿到的彈藥全部都可以變現,很快就可以買得起。同樣的, The Another Order 第一輪只要不亂花錢,第二輪一開始造訪商人,身上的東西賣一賣就有 30 萬,一開始就可以買的起湯普森衝鋒槍了。

    + +

    拿到了湯普森衝鋒槍,真的超過癮的。不管是哪一關,不用再像第一輪般,費盡心計去設計、引誘敵人一個一個出來瞄準解決,直接往前面衝,看到就打,一大群圍上來就掃射。之前花了三個星期破完第一輪,第二輪我只花了一天半。 The Another Order 第一輪花了一天半,第二輪只花了一個晚上,三個多小時。

    + +

    拿到威力這麼大的武器,當然要報仇了。第一輪打得快哭出來了,最後終於受不了去買火箭筒解決的兩段變身的大起士 (Big Cheese, 意同村講, 村長 Village Chief 的諧音) Bitores Mendez ,硬是給它打下去,答答答答,兩段變身,兩下子就解決了。還有那個我怎麼逃都逃不掉,到最後還是只能求助於火箭筒的古城城主 Salazar 右副手 Verdugo ,第二輪一開場就不跑不逃,朝他登場的地點打下去,也不等冰凍變弱,也不瞄準頭部弱點,硬是用湯普森衝鋒槍把他打到爛。第一輪逃到快瘋掉才辛苦打倒的 It ,第二輪也是,等它第一爬上山壁,完全不給它機會鑽地,就用湯普森衝鋒槍硬把它打到爛。剛剛又實驗了一下, 3-3 和盲眼鐵爪人 Garrador 關鐵籠時,有了湯普森衝鋒槍,不需要急著逃出鐵籠。一開始 Garrador 跳下來是側面,看得到背上的寄生蟲,直接用湯普森衝鋒槍把它打到爛,並小心後面的偷襲即可。

    + +

    至於第一輪用一般衝鋒槍邊逃邊跑,打得很辛苦的大魔王教主 Saddler ,則用無限火箭筒解決。一開始打破他左腳上的眼睛,他痛得倒地露出嘴裏的眼睛弱點時,也不理他,搶時間衝去撿各地的物品。撿了兩個後再回頭用無限火箭筒一轟,火箭筒炸開一定會傷到他腳上的眼睛,趁他倒地再去撿第三個。東西都撿完,其實還沒打到 Saddler 半滴血。這時候開始用無限火箭筒轟,轟一下,倒地後再瞄準嘴裏的眼睛弱點轟下去,這樣前半段就結束了。接下來拿到 Ada 丟的特殊火箭筒也不用,用前半段同樣的方法,轟一下,倒地後再瞄準嘴裏的眼睛弱點轟下去。總計轟了六發火箭,兩發真正攻擊到 Saddler ,變得非常好打。真是太過癮了~

    + +

    Saddler 其實是兩段,和兩段變身差不多。商人賣火箭筒的宣傳其實不假,一發可以解決任何敵人,不過如果敵人有好幾段,那每一段要一發,就像大起士 Bitores Mendez 和教主 Saddler 一樣。

    + +

    第二輪從頭到尾,只用到湯普森衝鋒槍、無限火箭筒和閃光彈。閃光彈用來對付一大群烏鴉很好用,可以瞬殺,不然烏鴉一驚嚇就整群飛走了,衝鋒槍派不上用場。還有 3-2 中途碰上光明教儀式,每個教徒身上都有帶寶石,可是一驚動就會全體逃跑時,用閃光彈丟下去,趁所有人驚嚇時,然後跳下去打,才有可能一網成擒。閃光彈也只要留三個就好,除此以外的所有武器都用不到,撿到都可以拿去賣了。還有藥材,黃綠紅組合藥可以賣到一萬,因為第一輪滿血量就已經上昇到最大了,所以撿到的紅黃藥草都拿來做三色藥賣,至於真正的療傷藥,用過剩的綠色藥草,組成三綠恢復藥就可了。遊戲中綠色藥草多到不行,第二輪時連三綠恢復藥都多到可以賣了,不需要珍惜紅藥草。

    + +

    不過第二輪還是有一關無法靠湯普森衝鋒槍從頭衝到尾,就是 3-4 Ashley 逃亡記。 Ashley 一個人逃亡沒有武器,還是得乖乖地左閃右逃慢慢走,和第一輪沒有差別。不過第一輪走過,熟悉了以後,這裏應該不太難。

    + +

    因為這個遊戲,我還特別去查什麼是芝加哥打字機 Chicago Typewritter,原來芝加哥打字機 Chicago Typewritter是有名的湯普森衝鋒槍 Tompson Submachine Gun 的外號之一,湯普森衝鋒槍用標準手槍的 90 釐米子彈,是二、三零年代美國黑道電影常可以看得到的武器,早期是美國警察的愛用配備,也是黑道的愛用配備,火力很強。不過以現代的角度來看,穩定度低,準確性很差。只能拿來嚇阻,逼敵人找掩蔽躲大量流彈,以利自己進攻,至於真的要拿它來對決,是打不到人的。不過遊戲中的湯普森衝鋒槍完全不是這麼回事,威力大到離譜。

    + +

    除了湯普森衝鋒槍和無限火箭筒外,從攻略上看,遊戲中還有兩把吸引人的紅利槍械,一把是使用特殊麥格農子彈的手砲 HandCannon ,改造到極點,子彈無限且每發威力是標準手槍的 99.9 倍。這要小遊戲 Mercenaries 所有角色都拿到五顆星後才會出現。還有一把是生體雷射槍 P.L.R. 42 ,不知道威力如何,這要專業級難度破完一輪後才出現。不過這兩者我都沒有力氣去玩了。 Mercenaries 一個角色要拿到五顆星就超難了。專業級難度要破第一輪要又花一個月,我才沒有那種力氣。 :p

    + +

    剛剛上了惡靈古堡 4 Wii 版官方網站上看,首頁就看到兩個模特兒手持 Wii 搖控器,打扮得像主角 LeonAshley 一樣,就有一點奇怪的預感。果然,看了廣告影片後,笑到不行。一開始女生端咖啡過來,一開口我就爆笑,根本就是 Ashley 的聲音嘛!後來的發展更爆笑了,男生玩到一半,背後傳來女生尖叫,竟然沙發後出現一批村民,女生被村講抓走了!主角手上只有 Wii 搖控器,不知所措地拿起來,沒想到竟然出現準星,試著答答答,竟然真的把村民打死了。最後換上散彈槍,把村講轟跑,解救了女朋友, Wii 畫面上正好也是同樣一幕。真是笑死我了。

    + +

    剛剛也看了惡靈古堡 5的宣傳片,也看了專訪。惡靈古堡 5HDTV 高畫質畫面,雖然惡靈古堡之父三上真司離開了,但繼任者似乎做得不錯。和惡靈古堡 4一樣,同樣訴求集體瘋狂的恐怖感,好像沒有寄生蟲、變種病毒之類的人類變體,但是在非洲感染了民族主義集體瘋狂的純粹人類,不怕死地一大群衝過來,感覺上同樣非常可怕。而且惡靈古堡系列的暗到了惡靈古堡 5轉變成光,極度的太陽光同樣讓人看不清楚,混雜空氣焦灼的飢渴感,感覺很酷。看樣子 2008 、 2009 以後才會上市。不過 HDTV 畫面只能在 PS3 和 Xbox 360 上跑, Wii 上是沒有辦法的。

    + +

    這是最後了。三個星期玩一個遊戲,什麼正事都沒有做,堆積的事如山高,真是有夠墮落的。雖然有找到兩個有趣的遊戲:海賊王:無盡的冒險模擬市民二:寵物當家,可是不可以再玩了,再玩我的人生也完了。呵呵~ ^^;

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 128 | + 129 | + 130 | + 131 | + 132 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0130.html.zh-cn.html b/htdocs/imacat/me/diary/0130.html.zh-cn.html new file mode 120000 index 0000000..2eed736 --- /dev/null +++ b/htdocs/imacat/me/diary/0130.html.zh-cn.html @@ -0,0 +1 @@ +0130.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0130.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0130.html.zh-cn.xhtml new file mode 100644 index 0000000..7c11a9b --- /dev/null +++ b/htdocs/imacat/me/diary/0130.html.zh-cn.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百三十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百三十

    + +
    + +
    + +
    +
    9.18.’07. 6:35pm.
    + +

    恶灵古堡 4 Wii 版 Biohazard 4 Wii Edition バイオハザード4 ウィー エディション

    + +

    花了近三个星期,终於把恶灵古堡 4破完了。呼。真是浪费生命的事。

    + +

    恶灵古堡,英文版的名字是 Resident Evil ,在日本发行时,则是取另一个英文名字 Biohazard 。所以 Resident EvilBiohazard 是同一个游戏恶灵古堡,只是日版和美版名字不同而已。

    + +

    我可以了解为什么恶灵古堡 4这么红了。以前专做大型机台的游戏大公司 Capcom 果然不是盖的。恶灵古堡 4的游戏规则和操作方式非常简单,没有复杂的组合键,可是关卡多,又各有特色。每进入一个房间,就要开始估算地型、敌人位置,如何在最少耗弹药最不会受伤的情况下,消灭掉该关的所有敌人,取得破关的钥匙。说起来,很像以前大型电玩上的魂斗罗,或是 PC 上的波斯王子,只是游戏画面变成 3D 立体的而已,但游戏的各项要素其实都是一样的:简单的操作,繁多的机关关卡,还有每一关最后的大魔王。

    + +

    说到大魔王,恶灵古堡 4其实也是勇者救公主的故事。美国总统的女儿,也算现代的公主吧~

    + +

    台湾有一个做得非常棒的恶灵古堡攻略网站恶灵深渊,另外,在GameFAQs 上的恶灵古堡 4 攻略也有非常多的攻略,其中我觉得写得最好的,是cvxfreak 写的恶灵古堡 4攻略DjSiXpAcK14 写的恶灵古堡 4攻略。 cvxfreak 写的恶灵古堡 4攻略有不少小错误,但整理的完整性是最好的。

    + +

    其实有个小诀窍,各家攻略都没提到。场景交换的门,就是续玩点,地图上看,一边是正在探索的区域,一边是探索过或是未探索的区域。只要从续玩点重玩,就会从上次经过这些续玩点的地方开始。而且只要从续玩点离开再进来,游戏中还没被杀的敌人不管是不是追在你后面,就会通通归位。这些续玩点当然比存档打字机还要多很多。关机时没办法从这些续玩点开始,只能从存档点开始,而且一旦死了,从续玩点重玩,会增加一次死亡数,这是无法避免的。虽然如此,但续玩点可以发挥暂时存档一样的功能:打不好就从续玩点重打,引出一个敌人打死后就冲回续玩点,让剩下的敌人归位,顺便暂时存档以备万一。好好利用续玩点,游戏可以容易很多。

    + +

    按照攻略所说的,破完恶灵古堡 4后,破完的存档叫出来时重启动第二轮时,就可以买无限火箭筒 Infinite Rocket Launcher 了。不过无限火箭筒还不是很好用。先把破关红利迷你游戏 Ada the Spy (Assignment Ada) 破完,并把破关红利中游戏 The Another Order (Separate Ways) 破完一轮。 Ada the Spy 完成,并破完一次 The Another OrderThe Another Order 的第二轮起,就可以以 30 万买芝加哥打字机(汤普森冲锋枪) Chicago Typewritter (Tompson Submachine Gun) 了。同样,破完一次 The Another Order 后,把主游戏第一轮破完存档叫出来玩第二轮时,就又会多一百万的芝加哥打字机(汤普森冲锋枪) Chicago Typewritter (Tompson Submachine Gun) 。游戏中的汤普森冲锋枪真的超强,除了每发子弹的火力是基本手枪的十倍外,还可以连发,等於 10 的火力瞬间一直开出来加乘。更恐怖的是它的子弹还是无限,根本不用爱惜子弹。

    + +

    有人说只要一把汤普森冲锋枪,就可以代替游戏中所有其它的枪械了。不过我再玩了一轮,不大可能,有些敌人就是远到冲锋枪打不到,如果不要留半自动来福枪的话,就要搭配无限火箭筒才行。火箭筒有瞄准镜可以放大,可以代替半自动来福枪用。 4-1 钟楼对面的子城,城墙上有三个投石器,那个距离是一般枪枝打不到的距离。换上无限火箭筒,一个火箭轰掉一个投石器,真的超酷的。

    + +

    我这么拼,就是想拿到汤普森冲锋枪,一扫之前像地狱一样,辛苦了玩三个星期的秽气。我在网路上看到有人第二轮的 3-2 拿到了汤普森冲锋枪,不过其实不用这么久。只要第一轮没有乱花钱,第二轮时身上的东西全部卖掉,也有 97 万。所以只要再存 3 万就够了。我第二轮 1-2 就存到了,把身上的东西全部卖一卖,就买到汤普森冲锋枪了。至於无限火箭筒,只要有汤普森冲锋枪,就不再需要弹药,接下来捡到的弹药全部都可以变现,很快就可以买得起。同样的, The Another Order 第一轮只要不乱花钱,第二轮一开始造访商人,身上的东西卖一卖就有 30 万,一开始就可以买的起汤普森冲锋枪了。

    + +

    拿到了汤普森冲锋枪,真的超过瘾的。不管是哪一关,不用再像第一轮般,费尽心计去设计、引诱敌人一个一个出来瞄准解决,直接往前面冲,看到就打,一大群围上来就扫射。之前花了三个星期破完第一轮,第二轮我只花了一天半。 The Another Order 第一轮花了一天半,第二轮只花了一个晚上,三个多小时。

    + +

    拿到威力这么大的武器,当然要报仇了。第一轮打得快哭出来了,最后终於受不了去买火箭筒解决的两段变身的大起士 (Big Cheese, 意同村讲, 村长 Village Chief 的谐音) Bitores Mendez ,硬是给它打下去,答答答答,两段变身,两下子就解决了。还有那个我怎么逃都逃不掉,到最后还是只能求助於火箭筒的古城城主 Salazar 右副手 Verdugo ,第二轮一开场就不跑不逃,朝他登场的地点打下去,也不等冰冻变弱,也不瞄准头部弱点,硬是用汤普森冲锋枪把他打到烂。第一轮逃到快疯掉才辛苦打倒的 It ,第二轮也是,等它第一爬上山壁,完全不给它机会钻地,就用汤普森冲锋枪硬把它打到烂。刚刚又实验了一下, 3-3 和盲眼铁爪人 Garrador 关铁笼时,有了汤普森冲锋枪,不需要急著逃出铁笼。一开始 Garrador 跳下来是侧面,看得到背上的寄生虫,直接用汤普森冲锋枪把它打到烂,并小心后面的偷袭即可。

    + +

    至於第一轮用一般冲锋枪边逃边跑,打得很辛苦的大魔王教主 Saddler ,则用无限火箭筒解决。一开始打破他左脚上的眼睛,他痛得倒地露出嘴里的眼睛弱点时,也不理他,抢时间冲去捡各地的物品。捡了两个后再回头用无限火箭筒一轰,火箭筒炸开一定会伤到他脚上的眼睛,趁他倒地再去捡第三个。东西都捡完,其实还没打到 Saddler 半滴血。这时候开始用无限火箭筒轰,轰一下,倒地后再瞄准嘴里的眼睛弱点轰下去,这样前半段就结束了。接下来拿到 Ada 丢的特殊火箭筒也不用,用前半段同样的方法,轰一下,倒地后再瞄准嘴里的眼睛弱点轰下去。总计轰了六发火箭,两发真正攻击到 Saddler ,变得非常好打。真是太过瘾了~

    + +

    Saddler 其实是两段,和两段变身差不多。商人卖火箭筒的宣传其实不假,一发可以解决任何敌人,不过如果敌人有好几段,那每一段要一发,就像大起士 Bitores Mendez 和教主 Saddler 一样。

    + +

    第二轮从头到尾,只用到汤普森冲锋枪、无限火箭筒和闪光弹。闪光弹用来对付一大群乌鸦很好用,可以瞬杀,不然乌鸦一惊吓就整群飞走了,冲锋枪派不上用场。还有 3-2 中途碰上光明教仪式,每个教徒身上都有带宝石,可是一惊动就会全体逃跑时,用闪光弹丢下去,趁所有人惊吓时,然后跳下去打,才有可能一网成擒。闪光弹也只要留三个就好,除此以外的所有武器都用不到,捡到都可以拿去卖了。还有药材,黄绿红组合药可以卖到一万,因为第一轮满血量就已经上升到最大了,所以捡到的红黄药草都拿来做三色药卖,至於真正的疗伤药,用过剩的绿色药草,组成三绿恢复药就可了。游戏中绿色药草多到不行,第二轮时连三绿恢复药都多到可以卖了,不需要珍惜红药草。

    + +

    不过第二轮还是有一关无法靠汤普森冲锋枪从头冲到尾,就是 3-4 Ashley 逃亡记。 Ashley 一个人逃亡没有武器,还是得乖乖地左闪右逃慢慢走,和第一轮没有差别。不过第一轮走过,熟悉了以后,这里应该不太难。

    + +

    因为这个游戏,我还特别去查什么是芝加哥打字机 Chicago Typewritter,原来芝加哥打字机 Chicago Typewritter是有名的汤普森冲锋枪 Tompson Submachine Gun 的外号之一,汤普森冲锋枪用标准手枪的 90 厘米子弹,是二、三零年代美国黑道电影常可以看得到的武器,早期是美国警察的爱用配备,也是黑道的爱用配备,火力很强。不过以现代的角度来看,稳定度低,准确性很差。只能拿来吓阻,逼敌人找掩蔽躲大量流弹,以利自己进攻,至於真的要拿它来对决,是打不到人的。不过游戏中的汤普森冲锋枪完全不是这么回事,威力大到离谱。

    + +

    除了汤普森冲锋枪和无限火箭筒外,从攻略上看,游戏中还有两把吸引人的红利枪械,一把是使用特殊麦格农子弹的手炮 HandCannon ,改造到极点,子弹无限且每发威力是标准手枪的 99.9 倍。这要小游戏 Mercenaries 所有角色都拿到五颗星后才会出现。还有一把是生体雷射枪 P.L.R. 42 ,不知道威力如何,这要专业级难度破完一轮后才出现。不过这两者我都没有力气去玩了。 Mercenaries 一个角色要拿到五颗星就超难了。专业级难度要破第一轮要又花一个月,我才没有那种力气。 :p

    + +

    刚刚上了恶灵古堡 4 Wii 版官方网站上看,首页就看到两个模特儿手持 Wii 摇控器,打扮得像主角 LeonAshley 一样,就有一点奇怪的预感。果然,看了广告影片后,笑到不行。一开始女生端咖啡过来,一开口我就爆笑,根本就是 Ashley 的声音嘛!后来的发展更爆笑了,男生玩到一半,背后传来女生尖叫,竟然沙发后出现一批村民,女生被村讲抓走了!主角手上只有 Wii 摇控器,不知所措地拿起来,没想到竟然出现准星,试著答答答,竟然真的把村民打死了。最后换上散弹枪,把村讲轰跑,解救了女朋友, Wii 画面上正好也是同样一幕。真是笑死我了。

    + +

    刚刚也看了恶灵古堡 5的宣传片,也看了专访。恶灵古堡 5HDTV 高画质画面,虽然恶灵古堡之父三上真司离开了,但继任者似乎做得不错。和恶灵古堡 4一样,同样诉求集体疯狂的恐怖感,好像没有寄生虫、变种病毒之类的人类变体,但是在非洲感染了民族主义集体疯狂的纯粹人类,不怕死地一大群冲过来,感觉上同样非常可怕。而且恶灵古堡系列的暗到了恶灵古堡 5转变成光,极度的太阳光同样让人看不清楚,混杂空气焦灼的饥渴感,感觉很酷。看样子 2008 、 2009 以后才会上市。不过 HDTV 画面只能在 PS3 和 Xbox 360 上跑, Wii 上是没有办法的。

    + +

    这是最后了。三个星期玩一个游戏,什么正事都没有做,堆积的事如山高,真是有够堕落的。虽然有找到两个有趣的游戏:海贼王:无尽的冒险模拟市民二:宠物当家,可是不可以再玩了,再玩我的人生也完了。呵呵~ ^^;

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 128 | + 129 | + 130 | + 131 | + 132 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0130.html.zh-tw.html b/htdocs/imacat/me/diary/0130.html.zh-tw.html new file mode 120000 index 0000000..179beee --- /dev/null +++ b/htdocs/imacat/me/diary/0130.html.zh-tw.html @@ -0,0 +1 @@ +0130.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0130.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0130.html.zh-tw.xhtml new file mode 100644 index 0000000..d9b1098 --- /dev/null +++ b/htdocs/imacat/me/diary/0130.html.zh-tw.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百三十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百三十

    + +
    + +
    + +
    +
    9.18.’07. 6:35pm.
    + +

    惡靈古堡 4 Wii 版 Biohazard 4 Wii Edition バイオハザード4 ウィー エディション

    + +

    花了近三個星期,終於把惡靈古堡 4破完了。呼。真是浪費生命的事。

    + +

    惡靈古堡,英文版的名字是 Resident Evil ,在日本發行時,則是取另一個英文名字 Biohazard 。所以 Resident EvilBiohazard 是同一個遊戲惡靈古堡,只是日版和美版名字不同而已。

    + +

    我可以瞭解為什麼惡靈古堡 4這麼紅了。以前專做大型機台的遊戲大公司 Capcom 果然不是蓋的。惡靈古堡 4的遊戲規則和操作方式非常簡單,沒有複雜的組合鍵,可是關卡多,又各有特色。每進入一個房間,就要開始估算地型、敵人位置,如何在最少耗彈藥最不會受傷的情況下,消滅掉該關的所有敵人,取得破關的鑰匙。說起來,很像以前大型電玩上的魂斗羅,或是 PC 上的波斯王子,只是遊戲畫面變成 3D 立體的而已,但遊戲的各項要素其實都是一樣的:簡單的操作,繁多的機關關卡,還有每一關最後的大魔王。

    + +

    說到大魔王,惡靈古堡 4其實也是勇者救公主的故事。美國總統的女兒,也算現代的公主吧~

    + +

    台灣有一個做得非常棒的惡靈古堡攻略網站惡靈深淵,另外,在GameFAQs 上的惡靈古堡 4 攻略也有非常多的攻略,其中我覺得寫得最好的,是cvxfreak 寫的惡靈古堡 4攻略DjSiXpAcK14 寫的惡靈古堡 4攻略。 cvxfreak 寫的惡靈古堡 4攻略有不少小錯誤,但整理的完整性是最好的。

    + +

    其實有個小訣竅,各家攻略都沒提到。場景交換的門,就是續玩點,地圖上看,一邊是正在探索的區域,一邊是探索過或是未探索的區域。只要從續玩點重玩,就會從上次經過這些續玩點的地方開始。而且只要從續玩點離開再進來,遊戲中還沒被殺的敵人不管是不是追在你後面,就會通通歸位。這些續玩點當然比存檔打字機還要多很多。關機時沒辦法從這些續玩點開始,只能從存檔點開始,而且一旦死了,從續玩點重玩,會增加一次死亡數,這是無法避免的。雖然如此,但續玩點可以發揮暫時存檔一樣的功能:打不好就從續玩點重打,引出一個敵人打死後就衝回續玩點,讓剩下的敵人歸位,順便暫時存檔以備萬一。好好利用續玩點,遊戲可以容易很多。

    + +

    按照攻略所說的,破完惡靈古堡 4後,破完的存檔叫出來時重啟動第二輪時,就可以買無限火箭筒 Infinite Rocket Launcher 了。不過無限火箭筒還不是很好用。先把破關紅利迷你遊戲 Ada the Spy (Assignment Ada) 破完,並把破關紅利中遊戲 The Another Order (Separate Ways) 破完一輪。 Ada the Spy 完成,並破完一次 The Another OrderThe Another Order 的第二輪起,就可以以 30 萬買芝加哥打字機(湯普森衝鋒槍) Chicago Typewritter (Tompson Submachine Gun) 了。同樣,破完一次 The Another Order 後,把主遊戲第一輪破完存檔叫出來玩第二輪時,就又會多一百萬的芝加哥打字機(湯普森衝鋒槍) Chicago Typewritter (Tompson Submachine Gun) 。遊戲中的湯普森衝鋒槍真的超強,除了每發子彈的火力是基本手槍的十倍外,還可以連發,等於 10 的火力瞬間一直開出來加乘。更恐怖的是它的子彈還是無限,根本不用愛惜子彈。

    + +

    有人說只要一把湯普森衝鋒槍,就可以代替遊戲中所有其它的槍械了。不過我再玩了一輪,不大可能,有些敵人就是遠到衝鋒槍打不到,如果不要留半自動來福槍的話,就要搭配無限火箭筒才行。火箭筒有瞄準鏡可以放大,可以代替半自動來福槍用。 4-1 鐘樓對面的子城,城牆上有三個投石器,那個距離是一般槍枝打不到的距離。換上無限火箭筒,一個火箭轟掉一個投石器,真的超酷的。

    + +

    我這麼拼,就是想拿到湯普森衝鋒槍,一掃之前像地獄一樣,辛苦了玩三個星期的穢氣。我在網路上看到有人第二輪的 3-2 拿到了湯普森衝鋒槍,不過其實不用這麼久。只要第一輪沒有亂花錢,第二輪時身上的東西全部賣掉,也有 97 萬。所以只要再存 3 萬就夠了。我第二輪 1-2 就存到了,把身上的東西全部賣一賣,就買到湯普森衝鋒槍了。至於無限火箭筒,只要有湯普森衝鋒槍,就不再需要彈藥,接下來撿到的彈藥全部都可以變現,很快就可以買得起。同樣的, The Another Order 第一輪只要不亂花錢,第二輪一開始造訪商人,身上的東西賣一賣就有 30 萬,一開始就可以買的起湯普森衝鋒槍了。

    + +

    拿到了湯普森衝鋒槍,真的超過癮的。不管是哪一關,不用再像第一輪般,費盡心計去設計、引誘敵人一個一個出來瞄準解決,直接往前面衝,看到就打,一大群圍上來就掃射。之前花了三個星期破完第一輪,第二輪我只花了一天半。 The Another Order 第一輪花了一天半,第二輪只花了一個晚上,三個多小時。

    + +

    拿到威力這麼大的武器,當然要報仇了。第一輪打得快哭出來了,最後終於受不了去買火箭筒解決的兩段變身的大起士 (Big Cheese, 意同村講, 村長 Village Chief 的諧音) Bitores Mendez ,硬是給它打下去,答答答答,兩段變身,兩下子就解決了。還有那個我怎麼逃都逃不掉,到最後還是只能求助於火箭筒的古城城主 Salazar 右副手 Verdugo ,第二輪一開場就不跑不逃,朝他登場的地點打下去,也不等冰凍變弱,也不瞄準頭部弱點,硬是用湯普森衝鋒槍把他打到爛。第一輪逃到快瘋掉才辛苦打倒的 It ,第二輪也是,等它第一爬上山壁,完全不給它機會鑽地,就用湯普森衝鋒槍硬把它打到爛。剛剛又實驗了一下, 3-3 和盲眼鐵爪人 Garrador 關鐵籠時,有了湯普森衝鋒槍,不需要急著逃出鐵籠。一開始 Garrador 跳下來是側面,看得到背上的寄生蟲,直接用湯普森衝鋒槍把它打到爛,並小心後面的偷襲即可。

    + +

    至於第一輪用一般衝鋒槍邊逃邊跑,打得很辛苦的大魔王教主 Saddler ,則用無限火箭筒解決。一開始打破他左腳上的眼睛,他痛得倒地露出嘴裏的眼睛弱點時,也不理他,搶時間衝去撿各地的物品。撿了兩個後再回頭用無限火箭筒一轟,火箭筒炸開一定會傷到他腳上的眼睛,趁他倒地再去撿第三個。東西都撿完,其實還沒打到 Saddler 半滴血。這時候開始用無限火箭筒轟,轟一下,倒地後再瞄準嘴裏的眼睛弱點轟下去,這樣前半段就結束了。接下來拿到 Ada 丟的特殊火箭筒也不用,用前半段同樣的方法,轟一下,倒地後再瞄準嘴裏的眼睛弱點轟下去。總計轟了六發火箭,兩發真正攻擊到 Saddler ,變得非常好打。真是太過癮了~

    + +

    Saddler 其實是兩段,和兩段變身差不多。商人賣火箭筒的宣傳其實不假,一發可以解決任何敵人,不過如果敵人有好幾段,那每一段要一發,就像大起士 Bitores Mendez 和教主 Saddler 一樣。

    + +

    第二輪從頭到尾,只用到湯普森衝鋒槍、無限火箭筒和閃光彈。閃光彈用來對付一大群烏鴉很好用,可以瞬殺,不然烏鴉一驚嚇就整群飛走了,衝鋒槍派不上用場。還有 3-2 中途碰上光明教儀式,每個教徒身上都有帶寶石,可是一驚動就會全體逃跑時,用閃光彈丟下去,趁所有人驚嚇時,然後跳下去打,才有可能一網成擒。閃光彈也只要留三個就好,除此以外的所有武器都用不到,撿到都可以拿去賣了。還有藥材,黃綠紅組合藥可以賣到一萬,因為第一輪滿血量就已經上昇到最大了,所以撿到的紅黃藥草都拿來做三色藥賣,至於真正的療傷藥,用過剩的綠色藥草,組成三綠恢復藥就可了。遊戲中綠色藥草多到不行,第二輪時連三綠恢復藥都多到可以賣了,不需要珍惜紅藥草。

    + +

    不過第二輪還是有一關無法靠湯普森衝鋒槍從頭衝到尾,就是 3-4 Ashley 逃亡記。 Ashley 一個人逃亡沒有武器,還是得乖乖地左閃右逃慢慢走,和第一輪沒有差別。不過第一輪走過,熟悉了以後,這裏應該不太難。

    + +

    因為這個遊戲,我還特別去查什麼是芝加哥打字機 Chicago Typewritter,原來芝加哥打字機 Chicago Typewritter是有名的湯普森衝鋒槍 Tompson Submachine Gun 的外號之一,湯普森衝鋒槍用標準手槍的 90 釐米子彈,是二、三零年代美國黑道電影常可以看得到的武器,早期是美國警察的愛用配備,也是黑道的愛用配備,火力很強。不過以現代的角度來看,穩定度低,準確性很差。只能拿來嚇阻,逼敵人找掩蔽躲大量流彈,以利自己進攻,至於真的要拿它來對決,是打不到人的。不過遊戲中的湯普森衝鋒槍完全不是這麼回事,威力大到離譜。

    + +

    除了湯普森衝鋒槍和無限火箭筒外,從攻略上看,遊戲中還有兩把吸引人的紅利槍械,一把是使用特殊麥格農子彈的手砲 HandCannon ,改造到極點,子彈無限且每發威力是標準手槍的 99.9 倍。這要小遊戲 Mercenaries 所有角色都拿到五顆星後才會出現。還有一把是生體雷射槍 P.L.R. 42 ,不知道威力如何,這要專業級難度破完一輪後才出現。不過這兩者我都沒有力氣去玩了。 Mercenaries 一個角色要拿到五顆星就超難了。專業級難度要破第一輪要又花一個月,我才沒有那種力氣。 :p

    + +

    剛剛上了惡靈古堡 4 Wii 版官方網站上看,首頁就看到兩個模特兒手持 Wii 搖控器,打扮得像主角 LeonAshley 一樣,就有一點奇怪的預感。果然,看了廣告影片後,笑到不行。一開始女生端咖啡過來,一開口我就爆笑,根本就是 Ashley 的聲音嘛!後來的發展更爆笑了,男生玩到一半,背後傳來女生尖叫,竟然沙發後出現一批村民,女生被村講抓走了!主角手上只有 Wii 搖控器,不知所措地拿起來,沒想到竟然出現準星,試著答答答,竟然真的把村民打死了。最後換上散彈槍,把村講轟跑,解救了女朋友, Wii 畫面上正好也是同樣一幕。真是笑死我了。

    + +

    剛剛也看了惡靈古堡 5的宣傳片,也看了專訪。惡靈古堡 5HDTV 高畫質畫面,雖然惡靈古堡之父三上真司離開了,但繼任者似乎做得不錯。和惡靈古堡 4一樣,同樣訴求集體瘋狂的恐怖感,好像沒有寄生蟲、變種病毒之類的人類變體,但是在非洲感染了民族主義集體瘋狂的純粹人類,不怕死地一大群衝過來,感覺上同樣非常可怕。而且惡靈古堡系列的暗到了惡靈古堡 5轉變成光,極度的太陽光同樣讓人看不清楚,混雜空氣焦灼的飢渴感,感覺很酷。看樣子 2008 、 2009 以後才會上市。不過 HDTV 畫面只能在 PS3 和 Xbox 360 上跑, Wii 上是沒有辦法的。

    + +

    這是最後了。三個星期玩一個遊戲,什麼正事都沒有做,堆積的事如山高,真是有夠墮落的。雖然有找到兩個有趣的遊戲:海賊王:無盡的冒險模擬市民二:寵物當家,可是不可以再玩了,再玩我的人生也完了。呵呵~ ^^;

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 128 | + 129 | + 130 | + 131 | + 132 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0131.html.en.html b/htdocs/imacat/me/diary/0131.html.en.html new file mode 120000 index 0000000..893ad09 --- /dev/null +++ b/htdocs/imacat/me/diary/0131.html.en.html @@ -0,0 +1 @@ +0131.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0131.html.en.xhtml b/htdocs/imacat/me/diary/0131.html.en.xhtml new file mode 100644 index 0000000..da8bbcb --- /dev/null +++ b/htdocs/imacat/me/diary/0131.html.en.xhtml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 131 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 131

    + +
    + +
    + +
    +
    9.20.’07. 8:39am.
    + +

    美國環球大學

    + +

    前兩天提倡排毒餐的林光常被起訴後,其學歷美國環球大學東方醫學博士被不斷質疑,最後蘋果甚至直擊環球大學校址,發現只是十坪大的辦公室,據管理員說只有看過一個人辦公,而且已因欠稅人去樓空。剛剛沒什麼事之下,就隨便去找一找美國環球大學到底是什麼東東。找到幾個有趣的地方:

    + + + +

    噢,原來這就是野雞大學啊!說來慚愧,我以前都只有聽說過,從來不知道真正的野雞大學長什麼樣子。現在真正見識到了。

    + +

    2004 年有一個和野雞大學有關的著名事件:德州檢察官為了調查這些野雞大學的假學歷問題,用自己養的愛貓 Colby Nolan 去南方三一大學申請線上 MBA 企管博士學位,並在工作經歷上寫:曾在速食店打工、帶小孩、送報。結果南方三一大學回覆說,因為 Colby Nolan 工作經驗符合,可抵扣企管課程學分,因此只要繳交入學學費,即可取得 MBA 企管博士學位。南方三一大學竟然連 Colby Nolan 是一隻貓都沒有發現,而且連打工也能抵扣企管課程學分!結果檢察官收到愛貓的博士學位證書後,當然就以偽造文書起訴了南方三一大學了。

    + +

    類似事件還有幾起。這真的是太好笑了。

    + +

    我上過空大的遠距教學課程。雖然空大的教學品質也不是很好,但要做遠距教學,要找各該科目專業老師來編寫教材,印課本、錄影、燒光碟寄送,還要請老師讓學生問問題,滿足授業解惑解惑的基本要求。我看了一下,美國環球大學有八個學院,每個學院下有四到六種學位課程。這麼多樣的專業科目,真的要做遠距教學,要請多少老師、行政人員才能應付!美國環球大學只有一個校長兼撞鐘。遠距教學?說什麼我都不相信!騙肖ㄟ!

    + +

    林光常的學歷分明就是買來的假學歷!這個人還真有夠不要臉的。

    + +

    不過剛剛稍微查了一下,台灣中醫界擁有美國環球大學東方醫學博士學位的大頭還真不少嘛,呵呵呵~

    + +
    + +
    + +
    +
    9.19.’07. 3:27am.
    + +

    Wiimote 機關槍與電池鏈

    + +
    +Wiimote 機關槍與電池鏈 Wiimote machine gun and battery belt +

    Wiimote 機關槍與電池鏈 Wiimote machine gun and battery belt

    +
    + +
    +消耗掉的電池鏈 +

    消耗掉的電池鏈

    +
    + +

    Wiimote 簡直是電池殺手!真是太可怕了!玩惡靈古堡 4的三個星期來,就消耗掉了兩盒 10 粒裝的金頂 AA 3 號鹼性電池。這是鹼性電池耶!真是有夠恐怖的!

    + +

    消耗掉的電池排起來,簡直就像格林機關槍的子彈鏈一樣。我想應該叫做 Wiimote 機關槍的電池鏈吧!好可怕,嚇死人了。不知道以後會不會像格林機關槍一樣,為了 Wiimote 真的發明電池鏈呢? :p

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 129 | + 130 | + 131 | + 132 | + 133 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0131.html.zh-cn.html b/htdocs/imacat/me/diary/0131.html.zh-cn.html new file mode 120000 index 0000000..38fd578 --- /dev/null +++ b/htdocs/imacat/me/diary/0131.html.zh-cn.html @@ -0,0 +1 @@ +0131.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0131.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0131.html.zh-cn.xhtml new file mode 100644 index 0000000..56c6be8 --- /dev/null +++ b/htdocs/imacat/me/diary/0131.html.zh-cn.xhtml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百三十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百三十一

    + +
    + +
    + +
    +
    9.20.’07. 8:39am.
    + +

    美国环球大学

    + +

    前两天提倡排毒餐的林光常被起诉后,其学历美国环球大学东方医学博士被不断质疑,最后苹果甚至直击环球大学校址,发现只是十坪大的办公室,据管理员说只有看过一个人办公,而且已因欠税人去楼空。刚刚没什么事之下,就随便去找一找美国环球大学到底是什么东东。找到几个有趣的地方:

    + + + +

    噢,原来这就是野鸡大学啊!说来惭愧,我以前都只有听说过,从来不知道真正的野鸡大学长什么样子。现在真正见识到了。

    + +

    2004 年有一个和野鸡大学有关的著名事件:德州检察官为了调查这些野鸡大学的假学历问题,用自己养的爱猫 Colby Nolan 去南方三一大学申请线上 MBA 企管博士学位,并在工作经历上写:曾在速食店打工、带小孩、送报。结果南方三一大学回覆说,因为 Colby Nolan 工作经验符合,可抵扣企管课程学分,因此只要缴交入学学费,即可取得 MBA 企管博士学位。南方三一大学竟然连 Colby Nolan 是一只猫都没有发现,而且连打工也能抵扣企管课程学分!结果检察官收到爱猫的博士学位证书后,当然就以伪造文书起诉了南方三一大学了。

    + +

    类似事件还有几起。这真的是太好笑了。

    + +

    我上过空大的远距教学课程。虽然空大的教学品质也不是很好,但要做远距教学,要找各该科目专业老师来编写教材,印课本、录影、烧光碟寄送,还要请老师让学生问问题,满足授业解惑解惑的基本要求。我看了一下,美国环球大学有八个学院,每个学院下有四到六种学位课程。这么多样的专业科目,真的要做远距教学,要请多少老师、行政人员才能应付!美国环球大学只有一个校长兼撞钟。远距教学?说什么我都不相信!骗肖ㄟ!

    + +

    林光常的学历分明就是买来的假学历!这个人还真有够不要脸的。

    + +

    不过刚刚稍微查了一下,台湾中医界拥有美国环球大学东方医学博士学位的大头还真不少嘛,呵呵呵~

    + +
    + +
    + +
    +
    9.19.’07. 3:27am.
    + +

    Wiimote 机关枪与电池链

    + +
    +Wiimote 机关枪与电池链 Wiimote machine gun and battery belt +

    Wiimote 机关枪与电池链 Wiimote machine gun and battery belt

    +
    + +
    +消耗掉的电池链 +

    消耗掉的电池链

    +
    + +

    Wiimote 简直是电池杀手!真是太可怕了!玩恶灵古堡 4的三个星期来,就消耗掉了两盒 10 粒装的金顶 AA 3 号硷性电池。这是硷性电池耶!真是有够恐怖的!

    + +

    消耗掉的电池排起来,简直就像格林机关枪的子弹链一样。我想应该叫做 Wiimote 机关枪的电池链吧!好可怕,吓死人了。不知道以后会不会像格林机关枪一样,为了 Wiimote 真的发明电池链呢? :p

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 129 | + 130 | + 131 | + 132 | + 133 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0131.html.zh-tw.html b/htdocs/imacat/me/diary/0131.html.zh-tw.html new file mode 120000 index 0000000..efcf880 --- /dev/null +++ b/htdocs/imacat/me/diary/0131.html.zh-tw.html @@ -0,0 +1 @@ +0131.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0131.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0131.html.zh-tw.xhtml new file mode 100644 index 0000000..b9a73a4 --- /dev/null +++ b/htdocs/imacat/me/diary/0131.html.zh-tw.xhtml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百三十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百三十一

    + +
    + +
    + +
    +
    9.20.’07. 8:39am.
    + +

    美國環球大學

    + +

    前兩天提倡排毒餐的林光常被起訴後,其學歷美國環球大學東方醫學博士被不斷質疑,最後蘋果甚至直擊環球大學校址,發現只是十坪大的辦公室,據管理員說只有看過一個人辦公,而且已因欠稅人去樓空。剛剛沒什麼事之下,就隨便去找一找美國環球大學到底是什麼東東。找到幾個有趣的地方:

    + + + +

    噢,原來這就是野雞大學啊!說來慚愧,我以前都只有聽說過,從來不知道真正的野雞大學長什麼樣子。現在真正見識到了。

    + +

    2004 年有一個和野雞大學有關的著名事件:德州檢察官為了調查這些野雞大學的假學歷問題,用自己養的愛貓 Colby Nolan 去南方三一大學申請線上 MBA 企管博士學位,並在工作經歷上寫:曾在速食店打工、帶小孩、送報。結果南方三一大學回覆說,因為 Colby Nolan 工作經驗符合,可抵扣企管課程學分,因此只要繳交入學學費,即可取得 MBA 企管博士學位。南方三一大學竟然連 Colby Nolan 是一隻貓都沒有發現,而且連打工也能抵扣企管課程學分!結果檢察官收到愛貓的博士學位證書後,當然就以偽造文書起訴了南方三一大學了。

    + +

    類似事件還有幾起。這真的是太好笑了。

    + +

    我上過空大的遠距教學課程。雖然空大的教學品質也不是很好,但要做遠距教學,要找各該科目專業老師來編寫教材,印課本、錄影、燒光碟寄送,還要請老師讓學生問問題,滿足授業解惑解惑的基本要求。我看了一下,美國環球大學有八個學院,每個學院下有四到六種學位課程。這麼多樣的專業科目,真的要做遠距教學,要請多少老師、行政人員才能應付!美國環球大學只有一個校長兼撞鐘。遠距教學?說什麼我都不相信!騙肖ㄟ!

    + +

    林光常的學歷分明就是買來的假學歷!這個人還真有夠不要臉的。

    + +

    不過剛剛稍微查了一下,台灣中醫界擁有美國環球大學東方醫學博士學位的大頭還真不少嘛,呵呵呵~

    + +
    + +
    + +
    +
    9.19.’07. 3:27am.
    + +

    Wiimote 機關槍與電池鏈

    + +
    +Wiimote 機關槍與電池鏈 Wiimote machine gun and battery belt +

    Wiimote 機關槍與電池鏈 Wiimote machine gun and battery belt

    +
    + +
    +消耗掉的電池鏈 +

    消耗掉的電池鏈

    +
    + +

    Wiimote 簡直是電池殺手!真是太可怕了!玩惡靈古堡 4的三個星期來,就消耗掉了兩盒 10 粒裝的金頂 AA 3 號鹼性電池。這是鹼性電池耶!真是有夠恐怖的!

    + +

    消耗掉的電池排起來,簡直就像格林機關槍的子彈鏈一樣。我想應該叫做 Wiimote 機關槍的電池鏈吧!好可怕,嚇死人了。不知道以後會不會像格林機關槍一樣,為了 Wiimote 真的發明電池鏈呢? :p

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 129 | + 130 | + 131 | + 132 | + 133 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0132.html.en.html b/htdocs/imacat/me/diary/0132.html.en.html new file mode 120000 index 0000000..210352d --- /dev/null +++ b/htdocs/imacat/me/diary/0132.html.en.html @@ -0,0 +1 @@ +0132.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0132.html.en.xhtml b/htdocs/imacat/me/diary/0132.html.en.xhtml new file mode 100644 index 0000000..ead8704 --- /dev/null +++ b/htdocs/imacat/me/diary/0132.html.en.xhtml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 132 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 132

    + +
    + +
    + +
    +
    9.21.’07. 5:56pm.
    + +

    漫畫

    + +

    昨天晚上一口氣,把桂遊生丸畫的女生愛女生 かしまし~ガール・ミーツ・ガール~一到五集全部看完了。原本是中午看到第五集完結篇,還蠻有意思的,可是店裏沒有前面四集(啊? ^^; ),到別家店找到了,於是從第一集開始看,才發現第一集看過了。晚上回家前,乾脆把剩下四集也一口氣看完了。還蠻好看的。有點刻板,也有點公式化。初戀對象和青梅竹馬間的對決,根本是畫到不要畫的公式了,結局也和公式一樣,青梅竹馬勝出。我好像還沒看過初戀對象勝出的,不管是對青梅竹馬,還是對現在的新戀情,不管是男是女,異性戀或同性戀,初戀對象都一定會敗陣。這是公式。初戀對象好像只有襯托另一個選擇的重要性的價值而已,本身沒什麼可能性。

    + +

    不過有趣的是第三集加入的元素:死亡。因為預知會死,而且每個人都知道會死,所以讓選擇或不選擇,變成一件很沉重的事。雖然也有救贖的方法,可是沒有人有把握。面對死亡的陰影,讓這部以公式開頭的漫畫,變得非常好看,看得讓人很感動。

    + +

    青梅竹馬的小泊(來栖泊来栖とまり)個性真的是超~級可愛的,小提琴美女安菜(神泉安菜神泉やす菜)根本沒得比。這也是另一個原因,看沒多久就知道結局是跟誰在一起了。呵呵~

    + +

    說到感動,

    + +

    妳覺得最好看的漫畫是哪一部?

    + +

    看來看去,我還是覺得北条司天使心 エンジェルハート Angel Heart最好看,每次看完,心中都暖洋洋的,非常溫暖,非常舒服。從城市獵人看到現在,我覺得現在的北条司真的非常成熟。在城市獵人的時期,許多元素開始慢慢蘊釀,從一開始很平面又搞笑,劇情角色卻很刻版公式化,逐步成熟發展,越來越有韻味,到城市獵人的最後十集,已經讓人覺得很棒,很有味道。中間畫的幾個短篇也很不錯。到這部長篇連載的天使心,讓人感覺已經熟透了一樣,隨便一個故事,都非常暖洋洋地,讓讀者心情非常溫暖。

    + +
    + +
    + +
    +
    9.21.’07. 4:53pm.
    + +

    愛說話

    + +

    我小時候,是個愛說話的小孩。因為常常上課跟同學講話,所以常常被老師處罰。可是因為我功課好,所以老師處罰也比其他同學輕。雖然如此,我還是一直跟同學講個不停。因此,我被老師取了一個外號:愛說話

    + +

    很羨慕那個愛說話的自己。很想回到那個時候的自己。

    + +

    為什麼有那麼多話好說呢?工作壓力、每天面對電腦,手上總是有好幾件事在同時做。一睡醒,面對電腦營幕上的待辦工作清單,永遠在清查還有多少事情還要做,盤算要怎麼處理。要我說話,除了一些公式化的無聊哈拉以外,也不知道要說些什麼。到底是什麼時候開始變成這個樣子的呢?為什麼會變成現在這個樣子呢?我不知道。

    + +
    + +
    + +
    +
    9.20.’07. 9:46am.
    + +

    排毒餐

    + +

    假學歷的林光常,賣的是排毒餐,號稱只要三餐照著吃,一個月下來,連化療都可以不用做了。

    + +

    我不相信排毒餐。這並不是說我不相信食療和自然療法。我相信健康的飲食,可促進身體健康,所以我雖不是素食主義者,也不反對素食,偶爾也會去吃素食自助餐。

    + +

    可是健康的飲食,不等於排毒餐。飲食能夠淨化身體,甚至排毒,這是沒有科學根據的事。飲食再怎麼說都是把東西吃進身體裏,不可能把東西吃出身體外。健康的飲食可以補充某些身體缺乏的營養素,可是不可能排除掉身體不需要的所謂毒素(到底是什麼毒素?)。飲食一定是進,不是出,這是飲食的基本常識。吃某些藥可能會讓身體加速排洩,例如利尿劑、瀉藥和汗藥,不過那是藥,要有醫師診斷處方才能服用,不是正常飲食。

    + +

    訴求主張排毒餐的,都幾乎可以確定是詐騙。所謂毒素倒底是什麼?是寄生蟲?是細菌?是病毒?是有機分子?是無機金屬毒?每一樣東西的治療方式都不一樣,清除方式也都不相同。連毒素具體是什麼都不知道,怎麼清除?連毒素是什麼都無法具體說得清楚,就說要排掉,不過是在嚇人以發財而已。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 130 | + 131 | + 132 | + 133 | + 134 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0132.html.zh-cn.html b/htdocs/imacat/me/diary/0132.html.zh-cn.html new file mode 120000 index 0000000..9cbd17c --- /dev/null +++ b/htdocs/imacat/me/diary/0132.html.zh-cn.html @@ -0,0 +1 @@ +0132.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0132.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0132.html.zh-cn.xhtml new file mode 100644 index 0000000..cae8fe6 --- /dev/null +++ b/htdocs/imacat/me/diary/0132.html.zh-cn.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百三十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百三十二

    + +
    + +
    + +
    +
    9.21.’07. 5:56pm.
    + +

    漫画

    + +

    昨天晚上一口气,把桂游生丸画的女生爱女生 かしまし~ガール・ミーツ・ガール~一到五集全部看完了。原本是中午看到第五集完结篇,还蛮有意思的,可是店里没有前面四集(啊? ^^; ),到别家店找到了,於是从第一集开始看,才发现第一集看过了。晚上回家前,干脆把剩下四集也一口气看完了。还蛮好看的。有点刻板,也有点公式化。初恋对象和青梅竹马间的对决,根本是画到不要画的公式了,结局也和公式一样,青梅竹马胜出。我好像还没看过初恋对象胜出的,不管是对青梅竹马,还是对现在的新恋情,不管是男是女,异性恋或同性恋,初恋对象都一定会败阵。这是公式。初恋对象好像只有衬托另一个选择的重要性的价值而已,本身没什么可能性。

    + +

    不过有趣的是第三集加入的元素:死亡。因为预知会死,而且每个人都知道会死,所以让选择或不选择,变成一件很沉重的事。虽然也有救赎的方法,可是没有人有把握。面对死亡的阴影,让这部以公式开头的漫画,变得非常好看,看得让人很感动。

    + +

    青梅竹马的小泊(来栖泊来栖とまり)个性真的是超~级可爱的,小提琴美女安菜(神泉安菜神泉やす菜)根本没得比。这也是另一个原因,看没多久就知道结局是跟谁在一起了。呵呵~

    + +

    说到感动,

    + +

    你觉得最好看的漫画是哪一部?

    + +

    看来看去,我还是觉得北条司天使心 エンジェルハート Angel Heart最好看,每次看完,心中都暖洋洋的,非常温暖,非常舒服。从城市猎人看到现在,我觉得现在的北条司真的非常成熟。在城市猎人的时期,许多元素开始慢慢蕴酿,从一开始很平面又搞笑,剧情角色却很刻版公式化,逐步成熟发展,越来越有韵味,到城市猎人的最后十集,已经让人觉得很棒,很有味道。中间画的几个短篇也很不错。到这部长篇连载的天使心,让人感觉已经熟透了一样,随便一个故事,都非常暖洋洋地,让读者心情非常温暖。

    + +
    + +
    + +
    +
    9.21.’07. 4:53pm.
    + +

    爱说话

    + +

    我小时候,是个爱说话的小孩。因为常常上课跟同学讲话,所以常常被老师处罚。可是因为我功课好,所以老师处罚也比其他同学轻。虽然如此,我还是一直跟同学讲个不停。因此,我被老师取了一个外号:爱说话

    + +

    很羡慕那个爱说话的自己。很想回到那个时候的自己。

    + +

    为什么有那么多话好说呢?工作压力、每天面对电脑,手上总是有好几件事在同时做。一睡醒,面对电脑营幕上的待办工作清单,永远在清查还有多少事情还要做,盘算要怎么处理。要我说话,除了一些公式化的无聊哈拉以外,也不知道要说些什么。到底是什么时候开始变成这个样子的呢?为什么会变成现在这个样子呢?我不知道。

    + +
    + +
    + +
    +
    9.20.’07. 9:46am.
    + +

    排毒餐

    + +

    假学历的林光常,卖的是排毒餐,号称只要三餐照著吃,一个月下来,连化疗都可以不用做了。

    + +

    我不相信排毒餐。这并不是说我不相信食疗和自然疗法。我相信健康的饮食,可促进身体健康,所以我虽不是素食主义者,也不反对素食,偶尔也会去吃素食自助餐。

    + +

    可是健康的饮食,不等於排毒餐。饮食能够净化身体,甚至排毒,这是没有科学根据的事。饮食再怎么说都是把东西吃进身体里,不可能把东西吃出身体外。健康的饮食可以补充某些身体缺乏的营养素,可是不可能排除掉身体不需要的所谓毒素(到底是什么毒素?)。饮食一定是进,不是出,这是饮食的基本常识。吃某些药可能会让身体加速排泄,例如利尿剂、泻药和汗药,不过那是药,要有医师诊断处方才能服用,不是正常饮食。

    + +

    诉求主张排毒餐的,都几乎可以确定是诈骗。所谓毒素倒底是什么?是寄生虫?是细菌?是病毒?是有机分子?是无机金属毒?每一样东西的治疗方式都不一样,清除方式也都不相同。连毒素具体是什么都不知道,怎么清除?连毒素是什么都无法具体说得清楚,就说要排掉,不过是在吓人以发财而已。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 130 | + 131 | + 132 | + 133 | + 134 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0132.html.zh-tw.html b/htdocs/imacat/me/diary/0132.html.zh-tw.html new file mode 120000 index 0000000..6f17bc0 --- /dev/null +++ b/htdocs/imacat/me/diary/0132.html.zh-tw.html @@ -0,0 +1 @@ +0132.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0132.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0132.html.zh-tw.xhtml new file mode 100644 index 0000000..299a1d8 --- /dev/null +++ b/htdocs/imacat/me/diary/0132.html.zh-tw.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百三十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百三十二

    + +
    + +
    + +
    +
    9.21.’07. 5:56pm.
    + +

    漫畫

    + +

    昨天晚上一口氣,把桂遊生丸畫的女生愛女生 かしまし~ガール・ミーツ・ガール~一到五集全部看完了。原本是中午看到第五集完結篇,還蠻有意思的,可是店裏沒有前面四集(啊? ^^; ),到別家店找到了,於是從第一集開始看,才發現第一集看過了。晚上回家前,乾脆把剩下四集也一口氣看完了。還蠻好看的。有點刻板,也有點公式化。初戀對象和青梅竹馬間的對決,根本是畫到不要畫的公式了,結局也和公式一樣,青梅竹馬勝出。我好像還沒看過初戀對象勝出的,不管是對青梅竹馬,還是對現在的新戀情,不管是男是女,異性戀或同性戀,初戀對象都一定會敗陣。這是公式。初戀對象好像只有襯托另一個選擇的重要性的價值而已,本身沒什麼可能性。

    + +

    不過有趣的是第三集加入的元素:死亡。因為預知會死,而且每個人都知道會死,所以讓選擇或不選擇,變成一件很沉重的事。雖然也有救贖的方法,可是沒有人有把握。面對死亡的陰影,讓這部以公式開頭的漫畫,變得非常好看,看得讓人很感動。

    + +

    青梅竹馬的小泊(來栖泊来栖とまり)個性真的是超~級可愛的,小提琴美女安菜(神泉安菜神泉やす菜)根本沒得比。這也是另一個原因,看沒多久就知道結局是跟誰在一起了。呵呵~

    + +

    說到感動,

    + +

    妳覺得最好看的漫畫是哪一部?

    + +

    看來看去,我還是覺得北条司天使心 エンジェルハート Angel Heart最好看,每次看完,心中都暖洋洋的,非常溫暖,非常舒服。從城市獵人看到現在,我覺得現在的北条司真的非常成熟。在城市獵人的時期,許多元素開始慢慢蘊釀,從一開始很平面又搞笑,劇情角色卻很刻版公式化,逐步成熟發展,越來越有韻味,到城市獵人的最後十集,已經讓人覺得很棒,很有味道。中間畫的幾個短篇也很不錯。到這部長篇連載的天使心,讓人感覺已經熟透了一樣,隨便一個故事,都非常暖洋洋地,讓讀者心情非常溫暖。

    + +
    + +
    + +
    +
    9.21.’07. 4:53pm.
    + +

    愛說話

    + +

    我小時候,是個愛說話的小孩。因為常常上課跟同學講話,所以常常被老師處罰。可是因為我功課好,所以老師處罰也比其他同學輕。雖然如此,我還是一直跟同學講個不停。因此,我被老師取了一個外號:愛說話

    + +

    很羨慕那個愛說話的自己。很想回到那個時候的自己。

    + +

    為什麼有那麼多話好說呢?工作壓力、每天面對電腦,手上總是有好幾件事在同時做。一睡醒,面對電腦營幕上的待辦工作清單,永遠在清查還有多少事情還要做,盤算要怎麼處理。要我說話,除了一些公式化的無聊哈拉以外,也不知道要說些什麼。到底是什麼時候開始變成這個樣子的呢?為什麼會變成現在這個樣子呢?我不知道。

    + +
    + +
    + +
    +
    9.20.’07. 9:46am.
    + +

    排毒餐

    + +

    假學歷的林光常,賣的是排毒餐,號稱只要三餐照著吃,一個月下來,連化療都可以不用做了。

    + +

    我不相信排毒餐。這並不是說我不相信食療和自然療法。我相信健康的飲食,可促進身體健康,所以我雖不是素食主義者,也不反對素食,偶爾也會去吃素食自助餐。

    + +

    可是健康的飲食,不等於排毒餐。飲食能夠淨化身體,甚至排毒,這是沒有科學根據的事。飲食再怎麼說都是把東西吃進身體裏,不可能把東西吃出身體外。健康的飲食可以補充某些身體缺乏的營養素,可是不可能排除掉身體不需要的所謂毒素(到底是什麼毒素?)。飲食一定是進,不是出,這是飲食的基本常識。吃某些藥可能會讓身體加速排洩,例如利尿劑、瀉藥和汗藥,不過那是藥,要有醫師診斷處方才能服用,不是正常飲食。

    + +

    訴求主張排毒餐的,都幾乎可以確定是詐騙。所謂毒素倒底是什麼?是寄生蟲?是細菌?是病毒?是有機分子?是無機金屬毒?每一樣東西的治療方式都不一樣,清除方式也都不相同。連毒素具體是什麼都不知道,怎麼清除?連毒素是什麼都無法具體說得清楚,就說要排掉,不過是在嚇人以發財而已。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 130 | + 131 | + 132 | + 133 | + 134 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0133.html.en.html b/htdocs/imacat/me/diary/0133.html.en.html new file mode 120000 index 0000000..387f295 --- /dev/null +++ b/htdocs/imacat/me/diary/0133.html.en.html @@ -0,0 +1 @@ +0133.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0133.html.en.xhtml b/htdocs/imacat/me/diary/0133.html.en.xhtml new file mode 100644 index 0000000..0805491 --- /dev/null +++ b/htdocs/imacat/me/diary/0133.html.en.xhtml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 133 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 133

    + +
    + +
    + +
    +
    9.22.’07. 0:59am.
    + +

    漫畫

    + +

    今天中午,看到高瀬志帆明星小辣媽 あいどる第三集出來了。趕緊把它借來看。翻到最後一頁,突然讀到幾個字:第一部完。什麼?第一部已經完結篇了?翻到書背一看,沒有註明完結篇啊!不過再翻回封面,果然有小小的地方寫第一部完結篇。可是,太奇怪了吧!不是剛剛出道嗎?而且第三集中後段埋了那麼多伏筆,怎麼可能就這樣完結了呢?真是太詭異了。真的還要等第二部嗎?還是因為賣不好提早收攤了呢?

    + +

    我覺得明星小辣媽有好也有壞。明星小辣媽裏有不少像中津賢也桃色魔女裏一樣亂七八糟的場景,常常爆奶、露內褲,還有莫名其妙的 H ,感覺很像一些很糟很色的少年漫畫。可是在這同時,明星小辣媽卻又有不少有深度的內容,像漫畫裏面不是每個人都爆奶,只有主角吉岡愛爆奶,而她爆奶的真正理由是因為哺乳漲奶。作為一個窮困、到處打工碰壁的單親媽媽,為了可愛小孩小櫻的奶粉錢,只好硬著頭皮去參加偶像選拔賺獎金。這樣的角色設定和劇情走向,又比那種莫名其妙的少年漫畫,多了不少深度。使得整體來說,還是有不少好看的地方。

    + +

    晚上,跑去另一家出租店,把あだち充四葉遊戲 クロスゲーム第一到第八集一口氣看完了。到第八集生日禮物才送到十七歲閃亮亮的項鍊,若葉的生日禮物清單到二十歲,看樣子還要連載很久。還蠻好看的,可是就是太會拖戲了。あだち充的漫畫很好看,不過就是太會拖戲了,劇情進展超慢的。如果不是這樣一口氣累積七、八集單行本一起看,真的看不懂,之前的劇情記不起來。

    + +

    前一陣子看完了涼宮春日的憂鬱 涼宮ハルヒの憂鬱漫畫第二集。真是白癡的故事啊!很難能看得到更白癡的故事了。不過白癡之中,也還蠻有味道的。由小說改編的漫畫,都會有一股很深很特別的韻味。像灼眼的夏娜 灼眼のシャナ也是一樣。可能因為原作是文字,文字特有的表現方式,會有一種很深的味道,而這種味道改編成漫畫,當改編的畫家努力忠實呈現原作的感覺時,就會把這種特有的深深的韻味一起帶進來了。感覺很不錯,這是一般的漫畫中少有的呢~

    + +

    涼宮春日的開學自我介紹:我對普通的人類沒有興趣。你們之中要是有外星人、未來人、異世界來的人、超能力者,就儘管來找我吧!以上。

    + +

    …真是有夠白癡的,哇哈哈哈!

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 131 | + 132 | + 133 | + 134 | + 135 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0133.html.zh-cn.html b/htdocs/imacat/me/diary/0133.html.zh-cn.html new file mode 120000 index 0000000..92d9fc8 --- /dev/null +++ b/htdocs/imacat/me/diary/0133.html.zh-cn.html @@ -0,0 +1 @@ +0133.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0133.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0133.html.zh-cn.xhtml new file mode 100644 index 0000000..d8536b2 --- /dev/null +++ b/htdocs/imacat/me/diary/0133.html.zh-cn.xhtml @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百三十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百三十三

    + +
    + +
    + +
    +
    9.22.’07. 0:59am.
    + +

    漫画

    + +

    今天中午,看到高瀬志帆明星小辣妈 あいどる第三集出来了。赶紧把它借来看。翻到最后一页,突然读到几个字:第一部完。什么?第一部已经完结篇了?翻到书背一看,没有注明完结篇啊!不过再翻回封面,果然有小小的地方写第一部完结篇。可是,太奇怪了吧!不是刚刚出道吗?而且第三集中后段埋了那么多伏笔,怎么可能就这样完结了呢?真是太诡异了。真的还要等第二部吗?还是因为卖不好提早收摊了呢?

    + +

    我觉得明星小辣妈有好也有坏。明星小辣妈里有不少像中津贤也桃色魔女里一样乱七八糟的场景,常常爆奶、露内裤,还有莫名其妙的 H ,感觉很像一些很糟很色的少年漫画。可是在这同时,明星小辣妈却又有不少有深度的内容,像漫画里面不是每个人都爆奶,只有主角吉冈爱爆奶,而她爆奶的真正理由是因为哺乳涨奶。作为一个穷困、到处打工碰壁的单亲妈妈,为了可爱小孩小樱的奶粉钱,只好硬著头皮去参加偶像选拔赚奖金。这样的角色设定和剧情走向,又比那种莫名其妙的少年漫画,多了不少深度。使得整体来说,还是有不少好看的地方。

    + +

    晚上,跑去另一家出租店,把あだち充四叶游戏 クロスゲーム第一到第八集一口气看完了。到第八集生日礼物才送到十七岁闪亮亮的项炼,若叶的生日礼物清单到二十岁,看样子还要连载很久。还蛮好看的,可是就是太会拖戏了。あだち充的漫画很好看,不过就是太会拖戏了,剧情进展超慢的。如果不是这样一口气累积七、八集单行本一起看,真的看不懂,之前的剧情记不起来。

    + +

    前一阵子看完了凉宫春日的忧郁 凉宫ハルヒの忧郁漫画第二集。真是白痴的故事啊!很难能看得到更白痴的故事了。不过白痴之中,也还蛮有味道的。由小说改编的漫画,都会有一股很深很特别的韵味。像灼眼的夏娜 灼眼のシャナ也是一样。可能因为原作是文字,文字特有的表现方式,会有一种很深的味道,而这种味道改编成漫画,当改编的画家努力忠实呈现原作的感觉时,就会把这种特有的深深的韵味一起带进来了。感觉很不错,这是一般的漫画中少有的呢~

    + +

    凉宫春日的开学自我介绍:我对普通的人类没有兴趣。你们之中要是有外星人、未来人、异世界来的人、超能力者,就尽管来找我吧!以上。

    + +

    …真是有够白痴的,哇哈哈哈!

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 131 | + 132 | + 133 | + 134 | + 135 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0133.html.zh-tw.html b/htdocs/imacat/me/diary/0133.html.zh-tw.html new file mode 120000 index 0000000..b185dad --- /dev/null +++ b/htdocs/imacat/me/diary/0133.html.zh-tw.html @@ -0,0 +1 @@ +0133.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0133.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0133.html.zh-tw.xhtml new file mode 100644 index 0000000..d904941 --- /dev/null +++ b/htdocs/imacat/me/diary/0133.html.zh-tw.xhtml @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百三十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百三十三

    + +
    + +
    + +
    +
    9.22.’07. 0:59am.
    + +

    漫畫

    + +

    今天中午,看到高瀬志帆明星小辣媽 あいどる第三集出來了。趕緊把它借來看。翻到最後一頁,突然讀到幾個字:第一部完。什麼?第一部已經完結篇了?翻到書背一看,沒有註明完結篇啊!不過再翻回封面,果然有小小的地方寫第一部完結篇。可是,太奇怪了吧!不是剛剛出道嗎?而且第三集中後段埋了那麼多伏筆,怎麼可能就這樣完結了呢?真是太詭異了。真的還要等第二部嗎?還是因為賣不好提早收攤了呢?

    + +

    我覺得明星小辣媽有好也有壞。明星小辣媽裏有不少像中津賢也桃色魔女裏一樣亂七八糟的場景,常常爆奶、露內褲,還有莫名其妙的 H ,感覺很像一些很糟很色的少年漫畫。可是在這同時,明星小辣媽卻又有不少有深度的內容,像漫畫裏面不是每個人都爆奶,只有主角吉岡愛爆奶,而她爆奶的真正理由是因為哺乳漲奶。作為一個窮困、到處打工碰壁的單親媽媽,為了可愛小孩小櫻的奶粉錢,只好硬著頭皮去參加偶像選拔賺獎金。這樣的角色設定和劇情走向,又比那種莫名其妙的少年漫畫,多了不少深度。使得整體來說,還是有不少好看的地方。

    + +

    晚上,跑去另一家出租店,把あだち充四葉遊戲 クロスゲーム第一到第八集一口氣看完了。到第八集生日禮物才送到十七歲閃亮亮的項鍊,若葉的生日禮物清單到二十歲,看樣子還要連載很久。還蠻好看的,可是就是太會拖戲了。あだち充的漫畫很好看,不過就是太會拖戲了,劇情進展超慢的。如果不是這樣一口氣累積七、八集單行本一起看,真的看不懂,之前的劇情記不起來。

    + +

    前一陣子看完了涼宮春日的憂鬱 涼宮ハルヒの憂鬱漫畫第二集。真是白癡的故事啊!很難能看得到更白癡的故事了。不過白癡之中,也還蠻有味道的。由小說改編的漫畫,都會有一股很深很特別的韻味。像灼眼的夏娜 灼眼のシャナ也是一樣。可能因為原作是文字,文字特有的表現方式,會有一種很深的味道,而這種味道改編成漫畫,當改編的畫家努力忠實呈現原作的感覺時,就會把這種特有的深深的韻味一起帶進來了。感覺很不錯,這是一般的漫畫中少有的呢~

    + +

    涼宮春日的開學自我介紹:我對普通的人類沒有興趣。你們之中要是有外星人、未來人、異世界來的人、超能力者,就儘管來找我吧!以上。

    + +

    …真是有夠白癡的,哇哈哈哈!

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 131 | + 132 | + 133 | + 134 | + 135 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0134.html.en.html b/htdocs/imacat/me/diary/0134.html.en.html new file mode 120000 index 0000000..fadefa8 --- /dev/null +++ b/htdocs/imacat/me/diary/0134.html.en.html @@ -0,0 +1 @@ +0134.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0134.html.en.xhtml b/htdocs/imacat/me/diary/0134.html.en.xhtml new file mode 100644 index 0000000..76526d7 --- /dev/null +++ b/htdocs/imacat/me/diary/0134.html.en.xhtml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 134 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 134

    + +
    + +
    + +
    +
    9.28.’07. 5:32am.
    + +

    會計系統

    + +

    這個中秋長假,完成了一件一直掛心的事,用 Selima 系統為基礎,寫出了一個會計程式。這證明了 Selima 網站管理系統不只可以管理網站內容,它可以作為 Web 界面資料管理的基礎系統,管理任何資料。

    + +

    最初家裏在記帳,是我 1998 年起,用一個簡單的 Excel 試算表開始記的。 2000 年為了我前一個工作的 ASP 網站製作,學了 MS VBScript 和 DAO 物件,我摸索 MS Access 的功能,發現它也可以用來寫 VBScript 程式,於是我用 MS Access 加上 VBScript 程式,寫了後來一直延用了七年的共用帳記帳程式。我之前的工作學了一點點會計基礎,學會借貸平衡的觀念,可是日常現金收支記帳不好用,所以我寫共用帳記帳程式的時候,採用了一點折衷的辦法,用程式來計算借貸平衡。其結果還是一個包含銀行存款的收支表。因為簡單好用,從那時候起,就一直延用到現在。

    + +

    舊的記帳程式,雖然簡單好用,但還是有很多問題。最重要的問題,就是那是很久以前寫的 VBScript 程式了。換現在這個工作到現在七年,我已經七年不碰 VBScript ,要再問我什麼 DAO 物件,我完全不懂。從七年前到現在, MS Access 昇級改版了好幾次,電腦每次安裝新版的 MS Access 時,都會問我要不要轉換成新版的資料格式,還會警告可能有些功能會無法運作。幸運的是,從來沒有發生過這種事,一切功能都還運作如常。可是我知道這不是長久之計。現在 VBScript 還用 DAO 物件嗎?我不知道。要進去修程式,依現在的 VBScript 標準更新,我也不會做。要是有哪一次 MS Access 昇級改版,一昇級記帳程式就跑不動了,我也完全沒有辦法解決。

    + +

    其實從七年前到現在,我的能力也進步了很多。七年前我對 SQL 半知半解,用了一堆 DAOSQL 混用的寫法。現在回過頭來看真的很不成熟。我現在當然不可能那樣子寫了,要寫當然要用純 SQL 寫,把資料處理語言和程式語言分開來用,以便程式和資料的可攜性更強。我現在工作上用 PHP ,家裏我個人愛用 Perl ,兩邊資料庫都是用 PostgreSQL ,資料庫設計是一樣的, PerlPHP 都要可以取用。之前還有用 MySQL 的。資料語言和程式語言分開,使用標準的 SQL 語法,以便資料可攜、程式可攜,是我現在工作的常識。

    + +

    當然,還有其它理由。當年寫的時候,認為帳記了就不會刪了,所以只能記帳、改帳,沒有寫刪掉帳目的功能,所以真的記錯帳,只能進去資料表裏面改,很容易出錯、誤刪誤改,造成嚴重後果。最近幾年帳目有點混亂,我一直想花點時間好好整理一下,可是面對這種刪帳非常危險的系統,我一直覺得很棘手。而且當年只有考慮現金和一本存摺,可是現實生活中的帳目根本不可能如此,常會出現暫收、暫付、應收、應付等問題。電話費拖過到下個月才繳,電話費是八月,繳的日期是九月,記八月的話現金會不正確,記九月電話費的月份會不正確。像這種欠費問題,不牽涉到現金、存款的帳,原來的記帳系統就沒有辦法記了。如果沒有真正處理借貸平衡的系統,是不可能處理的。

    + +

    對這些種種問題,我一直盤算了很久。大概有一兩年了吧。去年空大去修了會計學,打好自己會計的基礎,並學會應收、應付、暫收、暫付等等的正確記法,弄清楚各種概念。然後我開始計劃新的會計系統,思考資料庫格式,要怎麼做到借貸平衡,如何兼顧日常現金收支好記,如何利用現有的 Selima 基礎系統修改、增刪。小招去美國後,我開始著手去進行。中間為了惡靈古堡 4停頓了三個多星期。不過我其實也沒完全閒著,邊玩邊思考一些程式邏輯的衝突如何解決。等到惡靈古堡 4結束收心後,把上就投入到之前寫到一半的地方,把這一陣子想到的程式邏輯具體寫出來。就這樣,趕在中秋長假一開始,就完成了新系統的初版,匯入舊的帳目,反覆測試檢查、修正各種問題。系統確認完成,和小招確認過後,就備份、淘汰掉就的 MS Access 帳目,改用 Selima 上的新系統了。

    + +

    原本以為這樣就告一段落了。接著完成我之前一直未完成的心願:整理帳目。整理帳目時,又發現種種新的問題:報表邏輯功能混亂不明,缺乏某些報表,缺乏某些其實很好用的功能。這些都是實際操作時才會切身碰到的問題。於是這兩天又修修改改,好不容易,才把整個系統,改成我覺得好用的樣子,也把很多有問題的帳,通通都更正過來。

    + +

    現在還差損益表和資產負債表,不過對正式學過會計基礎,擁有新系統的我,這兩項都不難。只是目前還不急著要。

    + +

    蠻有成就感的。

    + +

    不過我也因此反省到一件事。這次是因為我就是實際使用者,對操作上碰到的問題切身所感,所以腦筋動得很快,很快就找出應該有的正確執行邏輯,並付諸實現。但平常幫人家寫系統,我好像都不是這樣。別人碰到跟我反映的問題,我常常很難理解,甚至因此跟人家吵架,而且因為沒有對困擾感同身受,所以常常排到工作清單很後面才做,拖了很久,時效性都沒了。這樣好像不大好。是不是我一直很難了解別人在想什麼呢?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 132 | + 133 | + 134 | + 135 | + 136 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0134.html.zh-cn.html b/htdocs/imacat/me/diary/0134.html.zh-cn.html new file mode 120000 index 0000000..56d24ca --- /dev/null +++ b/htdocs/imacat/me/diary/0134.html.zh-cn.html @@ -0,0 +1 @@ +0134.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0134.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0134.html.zh-cn.xhtml new file mode 100644 index 0000000..6eaf671 --- /dev/null +++ b/htdocs/imacat/me/diary/0134.html.zh-cn.xhtml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百三十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百三十四

    + +
    + +
    + +
    +
    9.28.’07. 5:32am.
    + +

    会计系统

    + +

    这个中秋长假,完成了一件一直挂心的事,用 Selima 系统为基础,写出了一个会计程式。这证明了 Selima 网站管理系统不只可以管理网站内容,它可以作为 Web 界面资料管理的基础系统,管理任何资料。

    + +

    最初家里在记帐,是我 1998 年起,用一个简单的 Excel 试算表开始记的。 2000 年为了我前一个工作的 ASP 网站制作,学了 MS VBScript 和 DAO 物件,我摸索 MS Access 的功能,发现它也可以用来写 VBScript 程式,於是我用 MS Access 加上 VBScript 程式,写了后来一直延用了七年的共用帐记帐程式。我之前的工作学了一点点会计基础,学会借贷平衡的观念,可是日常现金收支记帐不好用,所以我写共用帐记帐程式的时候,采用了一点折衷的办法,用程式来计算借贷平衡。其结果还是一个包含银行存款的收支表。因为简单好用,从那时候起,就一直延用到现在。

    + +

    旧的记帐程式,虽然简单好用,但还是有很多问题。最重要的问题,就是那是很久以前写的 VBScript 程式了。换现在这个工作到现在七年,我已经七年不碰 VBScript ,要再问我什么 DAO 物件,我完全不懂。从七年前到现在, MS Access 升级改版了好几次,电脑每次安装新版的 MS Access 时,都会问我要不要转换成新版的资料格式,还会警告可能有些功能会无法运作。幸运的是,从来没有发生过这种事,一切功能都还运作如常。可是我知道这不是长久之计。现在 VBScript 还用 DAO 物件吗?我不知道。要进去修程式,依现在的 VBScript 标准更新,我也不会做。要是有哪一次 MS Access 升级改版,一升级记帐程式就跑不动了,我也完全没有办法解决。

    + +

    其实从七年前到现在,我的能力也进步了很多。七年前我对 SQL 半知半解,用了一堆 DAOSQL 混用的写法。现在回过头来看真的很不成熟。我现在当然不可能那样子写了,要写当然要用纯 SQL 写,把资料处理语言和程式语言分开来用,以便程式和资料的可携性更强。我现在工作上用 PHP ,家里我个人爱用 Perl ,两边资料库都是用 PostgreSQL ,资料库设计是一样的, PerlPHP 都要可以取用。之前还有用 MySQL 的。资料语言和程式语言分开,使用标准的 SQL 语法,以便资料可携、程式可携,是我现在工作的常识。

    + +

    当然,还有其它理由。当年写的时候,认为帐记了就不会删了,所以只能记帐、改帐,没有写删掉帐目的功能,所以真的记错帐,只能进去资料表里面改,很容易出错、误删误改,造成严重后果。最近几年帐目有点混乱,我一直想花点时间好好整理一下,可是面对这种删帐非常危险的系统,我一直觉得很棘手。而且当年只有考虑现金和一本存摺,可是现实生活中的帐目根本不可能如此,常会出现暂收、暂付、应收、应付等问题。电话费拖过到下个月才缴,电话费是八月,缴的日期是九月,记八月的话现金会不正确,记九月电话费的月份会不正确。像这种欠费问题,不牵涉到现金、存款的帐,原来的记帐系统就没有办法记了。如果没有真正处理借贷平衡的系统,是不可能处理的。

    + +

    对这些种种问题,我一直盘算了很久。大概有一两年了吧。去年空大去修了会计学,打好自己会计的基础,并学会应收、应付、暂收、暂付等等的正确记法,弄清楚各种概念。然后我开始计划新的会计系统,思考资料库格式,要怎么做到借贷平衡,如何兼顾日常现金收支好记,如何利用现有的 Selima 基础系统修改、增删。小招去美国后,我开始著手去进行。中间为了恶灵古堡 4停顿了三个多星期。不过我其实也没完全闲著,边玩边思考一些程式逻辑的冲突如何解决。等到恶灵古堡 4结束收心后,把上就投入到之前写到一半的地方,把这一阵子想到的程式逻辑具体写出来。就这样,赶在中秋长假一开始,就完成了新系统的初版,汇入旧的帐目,反覆测试检查、修正各种问题。系统确认完成,和小招确认过后,就备份、淘汰掉就的 MS Access 帐目,改用 Selima 上的新系统了。

    + +

    原本以为这样就告一段落了。接著完成我之前一直未完成的心愿:整理帐目。整理帐目时,又发现种种新的问题:报表逻辑功能混乱不明,缺乏某些报表,缺乏某些其实很好用的功能。这些都是实际操作时才会切身碰到的问题。於是这两天又修修改改,好不容易,才把整个系统,改成我觉得好用的样子,也把很多有问题的帐,通通都更正过来。

    + +

    现在还差损益表和资产负债表,不过对正式学过会计基础,拥有新系统的我,这两项都不难。只是目前还不急著要。

    + +

    蛮有成就感的。

    + +

    不过我也因此反省到一件事。这次是因为我就是实际使用者,对操作上碰到的问题切身所感,所以脑筋动得很快,很快就找出应该有的正确执行逻辑,并付诸实现。但平常帮人家写系统,我好像都不是这样。别人碰到跟我反映的问题,我常常很难理解,甚至因此跟人家吵架,而且因为没有对困扰感同身受,所以常常排到工作清单很后面才做,拖了很久,时效性都没了。这样好像不大好。是不是我一直很难了解别人在想什么呢?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 132 | + 133 | + 134 | + 135 | + 136 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0134.html.zh-tw.html b/htdocs/imacat/me/diary/0134.html.zh-tw.html new file mode 120000 index 0000000..b852172 --- /dev/null +++ b/htdocs/imacat/me/diary/0134.html.zh-tw.html @@ -0,0 +1 @@ +0134.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0134.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0134.html.zh-tw.xhtml new file mode 100644 index 0000000..3c1765e --- /dev/null +++ b/htdocs/imacat/me/diary/0134.html.zh-tw.xhtml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百三十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百三十四

    + +
    + +
    + +
    +
    9.28.’07. 5:32am.
    + +

    會計系統

    + +

    這個中秋長假,完成了一件一直掛心的事,用 Selima 系統為基礎,寫出了一個會計程式。這證明了 Selima 網站管理系統不只可以管理網站內容,它可以作為 Web 界面資料管理的基礎系統,管理任何資料。

    + +

    最初家裏在記帳,是我 1998 年起,用一個簡單的 Excel 試算表開始記的。 2000 年為了我前一個工作的 ASP 網站製作,學了 MS VBScript 和 DAO 物件,我摸索 MS Access 的功能,發現它也可以用來寫 VBScript 程式,於是我用 MS Access 加上 VBScript 程式,寫了後來一直延用了七年的共用帳記帳程式。我之前的工作學了一點點會計基礎,學會借貸平衡的觀念,可是日常現金收支記帳不好用,所以我寫共用帳記帳程式的時候,採用了一點折衷的辦法,用程式來計算借貸平衡。其結果還是一個包含銀行存款的收支表。因為簡單好用,從那時候起,就一直延用到現在。

    + +

    舊的記帳程式,雖然簡單好用,但還是有很多問題。最重要的問題,就是那是很久以前寫的 VBScript 程式了。換現在這個工作到現在七年,我已經七年不碰 VBScript ,要再問我什麼 DAO 物件,我完全不懂。從七年前到現在, MS Access 昇級改版了好幾次,電腦每次安裝新版的 MS Access 時,都會問我要不要轉換成新版的資料格式,還會警告可能有些功能會無法運作。幸運的是,從來沒有發生過這種事,一切功能都還運作如常。可是我知道這不是長久之計。現在 VBScript 還用 DAO 物件嗎?我不知道。要進去修程式,依現在的 VBScript 標準更新,我也不會做。要是有哪一次 MS Access 昇級改版,一昇級記帳程式就跑不動了,我也完全沒有辦法解決。

    + +

    其實從七年前到現在,我的能力也進步了很多。七年前我對 SQL 半知半解,用了一堆 DAOSQL 混用的寫法。現在回過頭來看真的很不成熟。我現在當然不可能那樣子寫了,要寫當然要用純 SQL 寫,把資料處理語言和程式語言分開來用,以便程式和資料的可攜性更強。我現在工作上用 PHP ,家裏我個人愛用 Perl ,兩邊資料庫都是用 PostgreSQL ,資料庫設計是一樣的, PerlPHP 都要可以取用。之前還有用 MySQL 的。資料語言和程式語言分開,使用標準的 SQL 語法,以便資料可攜、程式可攜,是我現在工作的常識。

    + +

    當然,還有其它理由。當年寫的時候,認為帳記了就不會刪了,所以只能記帳、改帳,沒有寫刪掉帳目的功能,所以真的記錯帳,只能進去資料表裏面改,很容易出錯、誤刪誤改,造成嚴重後果。最近幾年帳目有點混亂,我一直想花點時間好好整理一下,可是面對這種刪帳非常危險的系統,我一直覺得很棘手。而且當年只有考慮現金和一本存摺,可是現實生活中的帳目根本不可能如此,常會出現暫收、暫付、應收、應付等問題。電話費拖過到下個月才繳,電話費是八月,繳的日期是九月,記八月的話現金會不正確,記九月電話費的月份會不正確。像這種欠費問題,不牽涉到現金、存款的帳,原來的記帳系統就沒有辦法記了。如果沒有真正處理借貸平衡的系統,是不可能處理的。

    + +

    對這些種種問題,我一直盤算了很久。大概有一兩年了吧。去年空大去修了會計學,打好自己會計的基礎,並學會應收、應付、暫收、暫付等等的正確記法,弄清楚各種概念。然後我開始計劃新的會計系統,思考資料庫格式,要怎麼做到借貸平衡,如何兼顧日常現金收支好記,如何利用現有的 Selima 基礎系統修改、增刪。小招去美國後,我開始著手去進行。中間為了惡靈古堡 4停頓了三個多星期。不過我其實也沒完全閒著,邊玩邊思考一些程式邏輯的衝突如何解決。等到惡靈古堡 4結束收心後,把上就投入到之前寫到一半的地方,把這一陣子想到的程式邏輯具體寫出來。就這樣,趕在中秋長假一開始,就完成了新系統的初版,匯入舊的帳目,反覆測試檢查、修正各種問題。系統確認完成,和小招確認過後,就備份、淘汰掉就的 MS Access 帳目,改用 Selima 上的新系統了。

    + +

    原本以為這樣就告一段落了。接著完成我之前一直未完成的心願:整理帳目。整理帳目時,又發現種種新的問題:報表邏輯功能混亂不明,缺乏某些報表,缺乏某些其實很好用的功能。這些都是實際操作時才會切身碰到的問題。於是這兩天又修修改改,好不容易,才把整個系統,改成我覺得好用的樣子,也把很多有問題的帳,通通都更正過來。

    + +

    現在還差損益表和資產負債表,不過對正式學過會計基礎,擁有新系統的我,這兩項都不難。只是目前還不急著要。

    + +

    蠻有成就感的。

    + +

    不過我也因此反省到一件事。這次是因為我就是實際使用者,對操作上碰到的問題切身所感,所以腦筋動得很快,很快就找出應該有的正確執行邏輯,並付諸實現。但平常幫人家寫系統,我好像都不是這樣。別人碰到跟我反映的問題,我常常很難理解,甚至因此跟人家吵架,而且因為沒有對困擾感同身受,所以常常排到工作清單很後面才做,拖了很久,時效性都沒了。這樣好像不大好。是不是我一直很難了解別人在想什麼呢?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 132 | + 133 | + 134 | + 135 | + 136 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0135.html.en.html b/htdocs/imacat/me/diary/0135.html.en.html new file mode 120000 index 0000000..23122f2 --- /dev/null +++ b/htdocs/imacat/me/diary/0135.html.en.html @@ -0,0 +1 @@ +0135.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0135.html.en.xhtml b/htdocs/imacat/me/diary/0135.html.en.xhtml new file mode 100644 index 0000000..93221fb --- /dev/null +++ b/htdocs/imacat/me/diary/0135.html.en.xhtml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 135 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 135

    + +
    + +
    + +
    +
    10.4.’07. 4:03am.
    + +

    偏財運=0

    + +

    我覺得我自己還真的偏財運很差。

    + +

    其實這一點我早就知道了。我這個人一向不熱衷抽獎、彩券之類的機率遊戲,不是我完全不迷信,也不是我完全不相信運氣這種東西,而是根據從小到大的經驗歸納的結論,就是我沒什麼偏財運。統一發票對獎中獎的機率,比平均中獎率還低;買彩券買了這麼久,別人都中過兩千、四千的,我最多還只是兩百塊錢而已。所以,算了,偏財神不找我,我也懶得去追著偏財神跑。反正我只有正財運,辛辛苦苦賺錢的份,偏財什麼的,就留給別人吧。

    + +

    不過最近,我的感觸特別深。

    + +

    一個月前重新投入基金後,我看好了短、中、長期表現都超優的統一大滿貫基金,和我早已習慣、信任的台灣工銀2000高科技基金。誰知道從我申購開始,就不行了。我還有在追另外兩檔我之前贖回的基金的表現。這一個月來,看著工銀2000和統一大滿貫,臉都有點綠了。反而是之前我覺得表現不佳而贖回的建弘電子和日盛上選,都越操作越好。想著之前也是這樣,年初買建弘電子時,也是看好它長期表現佳,誰知道買了半年下來,別人都賺了兩成半了,建弘電子贖回時勉強打平而已。好像只要我買了哪檔基金,那檔基金就不行了。

    + +

    唉,鬱悶中。

    + +

    事到如今我是不會換的。反正問題是在我的偏財運,不是在這幾檔基金。不管我怎麼換,也不會解決問題。還是不要害人比較好。

    + +

    唉唉唉~ :~~~

    + +
    + +
    + +
    +
    10.4.’07. 3:50am.
    + +

    資產負債表

    + +

    一想起資產負債表,就讓人頭大。雖然說學過會計概要,但有很多地方半知半解,舊有的系統也有很多部份不能套用要蓋掉。不過,還是硬著頭皮,強迫自己去把它寫出來。

    + +

    資產負債表實作起來,才發現會計學唸得半知半解的地方還真不少。課本只有教年底如何結帳,可是年初如何開帳,卻沒有說清楚。照著課本不清不楚的指示做的話,怎麼樣都對不起來。上期結轉到底是一個獨立科目呢?還是現金科目下填的摘要?如果是獨立科目,到底是虛科目,還是實科目?該出現在資產負債表上嗎?還是損益表上?課本只有教年底結帳,沒有教年初開帳,範例只有第一年的報表,沒有第二年的報表,所以不管是損益表還是資產負債表,都找不到上期結轉這個科目。搜尋了我匯入的經濟部的標準會計科目表,裏面也沒有上期結轉這個科目。那是要我自己建嗎?還是怎樣?自己建的話,又該歸於實科目,還是虛科目呢?

    + +

    看來,還是沒辦法直接就這樣把資產負債表做出來,還是要從期末試算表、損益表、資產負債表一步步來做。我上網找別人家試算表是怎麼做的,問身邊的會計,確認上期結轉的性質,先把試算表做出來,然後損益表、資產負債表,一步一步做出來。

    + +

    中途,還發生了因為要計算試算表,突然發現之前所認為的借、貸方向完全弄反了到超級大糗事。還好這目前只是我一個人用,小招用也看不懂。只是這實在是太丟臉了。還有借、貸兩方,我自己給人家亂取英文名稱,後來發現國際會計制度的標準英文名稱時,也覺得超級丟臉的。

    + +

    現在這樣,基本會計報表都做出來了,還會自動關帳、開帳。還蠻有成就感的呢~ ^_*'

    + +
    + +
    + +
    +
    10.2.’07. 7:28am.
    + +

    涼宮春日的憂鬱

    + +

    沒想到我真的把涼宮春日的憂鬱小說讀完了。唔。

    + +

    其實讀起來還算很輕鬆呢~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 133 | + 134 | + 135 | + 136 | + 137 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0135.html.zh-cn.html b/htdocs/imacat/me/diary/0135.html.zh-cn.html new file mode 120000 index 0000000..febe165 --- /dev/null +++ b/htdocs/imacat/me/diary/0135.html.zh-cn.html @@ -0,0 +1 @@ +0135.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0135.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0135.html.zh-cn.xhtml new file mode 100644 index 0000000..7cda254 --- /dev/null +++ b/htdocs/imacat/me/diary/0135.html.zh-cn.xhtml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百三十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百三十五

    + +
    + +
    + +
    +
    10.4.’07. 4:03am.
    + +

    偏财运=0

    + +

    我觉得我自己还真的偏财运很差。

    + +

    其实这一点我早就知道了。我这个人一向不热衷抽奖、彩券之类的机率游戏,不是我完全不迷信,也不是我完全不相信运气这种东西,而是根据从小到大的经验归纳的结论,就是我没什么偏财运。统一发票对奖中奖的机率,比平均中奖率还低;买彩券买了这么久,别人都中过两千、四千的,我最多还只是两百块钱而已。所以,算了,偏财神不找我,我也懒得去追著偏财神跑。反正我只有正财运,辛辛苦苦赚钱的份,偏财什么的,就留给别人吧。

    + +

    不过最近,我的感触特别深。

    + +

    一个月前重新投入基金后,我看好了短、中、长期表现都超优的统一大满贯基金,和我早已习惯、信任的台湾工银2000高科技基金。谁知道从我申购开始,就不行了。我还有在追另外两档我之前赎回的基金的表现。这一个月来,看著工银2000和统一大满贯,脸都有点绿了。反而是之前我觉得表现不佳而赎回的建弘电子和日盛上选,都越操作越好。想著之前也是这样,年初买建弘电子时,也是看好它长期表现佳,谁知道买了半年下来,别人都赚了两成半了,建弘电子赎回时勉强打平而已。好像只要我买了哪档基金,那档基金就不行了。

    + +

    唉,郁闷中。

    + +

    事到如今我是不会换的。反正问题是在我的偏财运,不是在这几档基金。不管我怎么换,也不会解决问题。还是不要害人比较好。

    + +

    唉唉唉~ :~~~

    + +
    + +
    + +
    +
    10.4.’07. 3:50am.
    + +

    资产负债表

    + +

    一想起资产负债表,就让人头大。虽然说学过会计概要,但有很多地方半知半解,旧有的系统也有很多部份不能套用要盖掉。不过,还是硬著头皮,强迫自己去把它写出来。

    + +

    资产负债表实作起来,才发现会计学念得半知半解的地方还真不少。课本只有教年底如何结帐,可是年初如何开帐,却没有说清楚。照著课本不清不楚的指示做的话,怎么样都对不起来。上期结转到底是一个独立科目呢?还是现金科目下填的摘要?如果是独立科目,到底是虚科目,还是实科目?该出现在资产负债表上吗?还是损益表上?课本只有教年底结帐,没有教年初开帐,范例只有第一年的报表,没有第二年的报表,所以不管是损益表还是资产负债表,都找不到上期结转这个科目。搜寻了我汇入的经济部的标准会计科目表,里面也没有上期结转这个科目。那是要我自己建吗?还是怎样?自己建的话,又该归於实科目,还是虚科目呢?

    + +

    看来,还是没办法直接就这样把资产负债表做出来,还是要从期末试算表、损益表、资产负债表一步步来做。我上网找别人家试算表是怎么做的,问身边的会计,确认上期结转的性质,先把试算表做出来,然后损益表、资产负债表,一步一步做出来。

    + +

    中途,还发生了因为要计算试算表,突然发现之前所认为的借、贷方向完全弄反了到超级大糗事。还好这目前只是我一个人用,小招用也看不懂。只是这实在是太丢脸了。还有借、贷两方,我自己给人家乱取英文名称,后来发现国际会计制度的标准英文名称时,也觉得超级丢脸的。

    + +

    现在这样,基本会计报表都做出来了,还会自动关帐、开帐。还蛮有成就感的呢~ ^_*'

    + +
    + +
    + +
    +
    10.2.’07. 7:28am.
    + +

    凉宫春日的忧郁

    + +

    没想到我真的把凉宫春日的忧郁小说读完了。唔。

    + +

    其实读起来还算很轻松呢~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 133 | + 134 | + 135 | + 136 | + 137 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0135.html.zh-tw.html b/htdocs/imacat/me/diary/0135.html.zh-tw.html new file mode 120000 index 0000000..eb42296 --- /dev/null +++ b/htdocs/imacat/me/diary/0135.html.zh-tw.html @@ -0,0 +1 @@ +0135.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0135.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0135.html.zh-tw.xhtml new file mode 100644 index 0000000..63f397a --- /dev/null +++ b/htdocs/imacat/me/diary/0135.html.zh-tw.xhtml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百三十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百三十五

    + +
    + +
    + +
    +
    10.4.’07. 4:03am.
    + +

    偏財運=0

    + +

    我覺得我自己還真的偏財運很差。

    + +

    其實這一點我早就知道了。我這個人一向不熱衷抽獎、彩券之類的機率遊戲,不是我完全不迷信,也不是我完全不相信運氣這種東西,而是根據從小到大的經驗歸納的結論,就是我沒什麼偏財運。統一發票對獎中獎的機率,比平均中獎率還低;買彩券買了這麼久,別人都中過兩千、四千的,我最多還只是兩百塊錢而已。所以,算了,偏財神不找我,我也懶得去追著偏財神跑。反正我只有正財運,辛辛苦苦賺錢的份,偏財什麼的,就留給別人吧。

    + +

    不過最近,我的感觸特別深。

    + +

    一個月前重新投入基金後,我看好了短、中、長期表現都超優的統一大滿貫基金,和我早已習慣、信任的台灣工銀2000高科技基金。誰知道從我申購開始,就不行了。我還有在追另外兩檔我之前贖回的基金的表現。這一個月來,看著工銀2000和統一大滿貫,臉都有點綠了。反而是之前我覺得表現不佳而贖回的建弘電子和日盛上選,都越操作越好。想著之前也是這樣,年初買建弘電子時,也是看好它長期表現佳,誰知道買了半年下來,別人都賺了兩成半了,建弘電子贖回時勉強打平而已。好像只要我買了哪檔基金,那檔基金就不行了。

    + +

    唉,鬱悶中。

    + +

    事到如今我是不會換的。反正問題是在我的偏財運,不是在這幾檔基金。不管我怎麼換,也不會解決問題。還是不要害人比較好。

    + +

    唉唉唉~ :~~~

    + +
    + +
    + +
    +
    10.4.’07. 3:50am.
    + +

    資產負債表

    + +

    一想起資產負債表,就讓人頭大。雖然說學過會計概要,但有很多地方半知半解,舊有的系統也有很多部份不能套用要蓋掉。不過,還是硬著頭皮,強迫自己去把它寫出來。

    + +

    資產負債表實作起來,才發現會計學唸得半知半解的地方還真不少。課本只有教年底如何結帳,可是年初如何開帳,卻沒有說清楚。照著課本不清不楚的指示做的話,怎麼樣都對不起來。上期結轉到底是一個獨立科目呢?還是現金科目下填的摘要?如果是獨立科目,到底是虛科目,還是實科目?該出現在資產負債表上嗎?還是損益表上?課本只有教年底結帳,沒有教年初開帳,範例只有第一年的報表,沒有第二年的報表,所以不管是損益表還是資產負債表,都找不到上期結轉這個科目。搜尋了我匯入的經濟部的標準會計科目表,裏面也沒有上期結轉這個科目。那是要我自己建嗎?還是怎樣?自己建的話,又該歸於實科目,還是虛科目呢?

    + +

    看來,還是沒辦法直接就這樣把資產負債表做出來,還是要從期末試算表、損益表、資產負債表一步步來做。我上網找別人家試算表是怎麼做的,問身邊的會計,確認上期結轉的性質,先把試算表做出來,然後損益表、資產負債表,一步一步做出來。

    + +

    中途,還發生了因為要計算試算表,突然發現之前所認為的借、貸方向完全弄反了到超級大糗事。還好這目前只是我一個人用,小招用也看不懂。只是這實在是太丟臉了。還有借、貸兩方,我自己給人家亂取英文名稱,後來發現國際會計制度的標準英文名稱時,也覺得超級丟臉的。

    + +

    現在這樣,基本會計報表都做出來了,還會自動關帳、開帳。還蠻有成就感的呢~ ^_*'

    + +
    + +
    + +
    +
    10.2.’07. 7:28am.
    + +

    涼宮春日的憂鬱

    + +

    沒想到我真的把涼宮春日的憂鬱小說讀完了。唔。

    + +

    其實讀起來還算很輕鬆呢~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 133 | + 134 | + 135 | + 136 | + 137 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0136.html.en.html b/htdocs/imacat/me/diary/0136.html.en.html new file mode 120000 index 0000000..d18670f --- /dev/null +++ b/htdocs/imacat/me/diary/0136.html.en.html @@ -0,0 +1 @@ +0136.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0136.html.en.xhtml b/htdocs/imacat/me/diary/0136.html.en.xhtml new file mode 100644 index 0000000..59977ac --- /dev/null +++ b/htdocs/imacat/me/diary/0136.html.en.xhtml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 136 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 136

    + +
    + +
    + +
    +
    10.10.’07. 8:35am.
    + +

    戦国無双 KATANA Sengokumusou Katana

    + +

    又破完一個遊戲了,呼。又有一段生命浪費掉了。 ^^;

    + +

    之所以想玩戦国無双 KATANA,完全是因為在 Wii 上玩不到真・三國無双的緣故。聽說 KOEI 目前沒有打算把三國無双系列遊戲移植到 Wii ,維持三國無双系列遊戲為 PS 主機特有遊戲。不過同樣無双類型的另一系列遊戲戦国無双則會移植到 Wii 上來,發行 Wii 版戦国無双 KATANA。玩不到真・三國無双,只好玩戦国無双 KATANA過過乾癮了。

    + +

    整體來說,還不錯。看網路上有些評價說其實和真・三國無双不大一樣,比較像射擊類遊戲,不像無双類遊戲。我沒玩過無双纇遊戲,無法比較。基本上來說,比惡靈古堡 4容易多了。惡靈古堡 4我玩了三個星期,真・三國無双我玩了半個星期。到後來熟悉操作,幾乎成為反射動作,而且所有屬性都練到最高級以後,就很容易了。幾個魔王雖各有特色,不過戰術大致都相同,剛開始還打得很辛苦,可是後來按鈕熟悉到成為反射動作以後,一關連打三、四個魔王不補血都沒問題。

    + +

    中途有一小部份,得力於一個寫得非常仔細的戦国無双 KATANA 攻略。不過只有四節而已,一節是救世の章沼田城防衛戦 曲者探索的限時抓忍者地圖,時限短,忍者不多又閃得很快,一閃神漏掉幾個,就抓不到規定數目了;一節是救世の章雑賀百花繚乱輝きを求めて的限時救人地圖,會拖住時間的敵人超多,在地牢裏多轉幾個彎找路,時限就到了;一節是天下統一の章堺争奪戦民のために的助人地圖,雖然沒有限時,而且不一定要全部幫完也可以破,可是全部幫完有放送任務,而且全部幫完真的很難,沒看攻略很難知道要怎麼樣全部幫完;一節是腕試し藤の間MISSION 4 嘘つきを撃破せよ,邏輯推理推到我投降了。攻略網站也是日文的,邏輯推理直接有答案,其它則有地圖標示,就容易得多了。

    + +

    全破完看到工作人員表的時候,好感動。

    + +

    武器方面,近距離武器我比較愛用,威力強(只輸給巨槌),速度快又準,容易應變;遠距離當然就是鉄砲了,射速快又威力強,只有無法連射這點略遜於而已。我其實也很想努力精通旋刃(溜溜球)和飛去来(迴旋鏢)的,不過努力了幾次就絕望了。忍者的奇門兵器真的不大好用。兩者用起來感覺很像,轉來轉去的。旋刃飛去来單一次攻擊威力不高,不過旋刃可以來回繞圈連打,一次就能把一大群很強的敵人連打打到死,飛去来橫打可以一次打倒一列弓箭手,直打則可以穿過敵人繼續往後打,一次打倒或打暈一個直排。敵人如泉湧至的時候,用起來非常好用。不過就是不好控制,丟出去又不能馬上回來,三、四敵人在眼前正砍過來時,就會左支右絀了。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 134 | + 135 | + 136 | + 137 | + 138 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0136.html.zh-cn.html b/htdocs/imacat/me/diary/0136.html.zh-cn.html new file mode 120000 index 0000000..f02a847 --- /dev/null +++ b/htdocs/imacat/me/diary/0136.html.zh-cn.html @@ -0,0 +1 @@ +0136.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0136.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0136.html.zh-cn.xhtml new file mode 100644 index 0000000..25562d9 --- /dev/null +++ b/htdocs/imacat/me/diary/0136.html.zh-cn.xhtml @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百三十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百三十六

    + +
    + +
    + +
    +
    10.10.’07. 8:35am.
    + +

    戦国无双 KATANA Sengokumusou Katana

    + +

    又破完一个游戏了,呼。又有一段生命浪费掉了。 ^^;

    + +

    之所以想玩戦国无双 KATANA,完全是因为在 Wii 上玩不到真・三国无双的缘故。听说 KOEI 目前没有打算把三国无双系列游戏移植到 Wii ,维持三国无双系列游戏为 PS 主机特有游戏。不过同样无双类型的另一系列游戏戦国无双则会移植到 Wii 上来,发行 Wii 版戦国无双 KATANA。玩不到真・三国无双,只好玩戦国无双 KATANA过过干瘾了。

    + +

    整体来说,还不错。看网路上有些评价说其实和真・三国无双不大一样,比较像射击类游戏,不像无双类游戏。我没玩过无双纇游戏,无法比较。基本上来说,比恶灵古堡 4容易多了。恶灵古堡 4我玩了三个星期,真・三国无双我玩了半个星期。到后来熟悉操作,几乎成为反射动作,而且所有属性都练到最高级以后,就很容易了。几个魔王虽各有特色,不过战术大致都相同,刚开始还打得很辛苦,可是后来按钮熟悉到成为反射动作以后,一关连打三、四个魔王不补血都没问题。

    + +

    中途有一小部份,得力於一个写得非常仔细的戦国无双 KATANA 攻略。不过只有四节而已,一节是救世の章沼田城防卫戦 曲者探索的限时抓忍者地图,时限短,忍者不多又闪得很快,一闪神漏掉几个,就抓不到规定数目了;一节是救世の章雑贺百花缭乱辉きを求めて的限时救人地图,会拖住时间的敌人超多,在地牢里多转几个弯找路,时限就到了;一节是天下统一の章堺争夺戦民のために的助人地图,虽然没有限时,而且不一定要全部帮完也可以破,可是全部帮完有放送任务,而且全部帮完真的很难,没看攻略很难知道要怎么样全部帮完;一节是腕试し藤の间MISSION 4 嘘つきを撃破せよ,逻辑推理推到我投降了。攻略网站也是日文的,逻辑推理直接有答案,其它则有地图标示,就容易得多了。

    + +

    全破完看到工作人员表的时候,好感动。

    + +

    武器方面,近距离武器我比较爱用,威力强(只输给巨槌),速度快又准,容易应变;远距离当然就是鉄炮了,射速快又威力强,只有无法连射这点略逊於而已。我其实也很想努力精通旋刃(溜溜球)和飞去来(回旋镖)的,不过努力了几次就绝望了。忍者的奇门兵器真的不大好用。两者用起来感觉很像,转来转去的。旋刃飞去来单一次攻击威力不高,不过旋刃可以来回绕圈连打,一次就能把一大群很强的敌人连打打到死,飞去来横打可以一次打倒一列弓箭手,直打则可以穿过敌人继续往后打,一次打倒或打晕一个直排。敌人如泉涌至的时候,用起来非常好用。不过就是不好控制,丢出去又不能马上回来,三、四敌人在眼前正砍过来时,就会左支右绌了。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 134 | + 135 | + 136 | + 137 | + 138 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0136.html.zh-tw.html b/htdocs/imacat/me/diary/0136.html.zh-tw.html new file mode 120000 index 0000000..658abda --- /dev/null +++ b/htdocs/imacat/me/diary/0136.html.zh-tw.html @@ -0,0 +1 @@ +0136.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0136.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0136.html.zh-tw.xhtml new file mode 100644 index 0000000..824a523 --- /dev/null +++ b/htdocs/imacat/me/diary/0136.html.zh-tw.xhtml @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百三十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百三十六

    + +
    + +
    + +
    +
    10.10.’07. 8:35am.
    + +

    戦国無双 KATANA Sengokumusou Katana

    + +

    又破完一個遊戲了,呼。又有一段生命浪費掉了。 ^^;

    + +

    之所以想玩戦国無双 KATANA,完全是因為在 Wii 上玩不到真・三國無双的緣故。聽說 KOEI 目前沒有打算把三國無双系列遊戲移植到 Wii ,維持三國無双系列遊戲為 PS 主機特有遊戲。不過同樣無双類型的另一系列遊戲戦国無双則會移植到 Wii 上來,發行 Wii 版戦国無双 KATANA。玩不到真・三國無双,只好玩戦国無双 KATANA過過乾癮了。

    + +

    整體來說,還不錯。看網路上有些評價說其實和真・三國無双不大一樣,比較像射擊類遊戲,不像無双類遊戲。我沒玩過無双纇遊戲,無法比較。基本上來說,比惡靈古堡 4容易多了。惡靈古堡 4我玩了三個星期,真・三國無双我玩了半個星期。到後來熟悉操作,幾乎成為反射動作,而且所有屬性都練到最高級以後,就很容易了。幾個魔王雖各有特色,不過戰術大致都相同,剛開始還打得很辛苦,可是後來按鈕熟悉到成為反射動作以後,一關連打三、四個魔王不補血都沒問題。

    + +

    中途有一小部份,得力於一個寫得非常仔細的戦国無双 KATANA 攻略。不過只有四節而已,一節是救世の章沼田城防衛戦 曲者探索的限時抓忍者地圖,時限短,忍者不多又閃得很快,一閃神漏掉幾個,就抓不到規定數目了;一節是救世の章雑賀百花繚乱輝きを求めて的限時救人地圖,會拖住時間的敵人超多,在地牢裏多轉幾個彎找路,時限就到了;一節是天下統一の章堺争奪戦民のために的助人地圖,雖然沒有限時,而且不一定要全部幫完也可以破,可是全部幫完有放送任務,而且全部幫完真的很難,沒看攻略很難知道要怎麼樣全部幫完;一節是腕試し藤の間MISSION 4 嘘つきを撃破せよ,邏輯推理推到我投降了。攻略網站也是日文的,邏輯推理直接有答案,其它則有地圖標示,就容易得多了。

    + +

    全破完看到工作人員表的時候,好感動。

    + +

    武器方面,近距離武器我比較愛用,威力強(只輸給巨槌),速度快又準,容易應變;遠距離當然就是鉄砲了,射速快又威力強,只有無法連射這點略遜於而已。我其實也很想努力精通旋刃(溜溜球)和飛去来(迴旋鏢)的,不過努力了幾次就絕望了。忍者的奇門兵器真的不大好用。兩者用起來感覺很像,轉來轉去的。旋刃飛去来單一次攻擊威力不高,不過旋刃可以來回繞圈連打,一次就能把一大群很強的敵人連打打到死,飛去来橫打可以一次打倒一列弓箭手,直打則可以穿過敵人繼續往後打,一次打倒或打暈一個直排。敵人如泉湧至的時候,用起來非常好用。不過就是不好控制,丟出去又不能馬上回來,三、四敵人在眼前正砍過來時,就會左支右絀了。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 134 | + 135 | + 136 | + 137 | + 138 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0137.html.en.html b/htdocs/imacat/me/diary/0137.html.en.html new file mode 120000 index 0000000..979961e --- /dev/null +++ b/htdocs/imacat/me/diary/0137.html.en.html @@ -0,0 +1 @@ +0137.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0137.html.en.xhtml b/htdocs/imacat/me/diary/0137.html.en.xhtml new file mode 100644 index 0000000..af860a3 --- /dev/null +++ b/htdocs/imacat/me/diary/0137.html.en.xhtml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 137 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 137

    + +
    + +
    + +
    +
    10.22.’07. 3:27am.
    + +

    涼宮春日系列小說

    + +

    之前,在網路上找到輕小說涼宮春日的憂鬱,並一口氣讀完了。其實那時候找到的不止一部涼宮春日的憂鬱,而是涼宮春日的嘆息涼宮春日的憤慨等一到八集。全部讀起來蠻累人的,加上我還有一些工作要做,只好斷斷續續地看。這個星期工作告一段落,下定決心,硬是把全部一到八集一口氣看完了。

    + +

    呼,真累。而且看到後來越看越慢。是因為越來越沒有那麼好看嗎?嗯…不知道呢。

    + +

    不過到後來,還蠻會拖的就是了。隨便一兩句話,阿虛就要依次看看實玖瑠、長門、古泉等在場所有人的表情反應,然後依次描述一遍。即使人多,加上鶴屋學姊、三味線等等,也絕不馬虎。這樣對比每個人的反應是很有趣啦,而且人物的表情反應一講再講,也讓讀者對各個角色的性格印象深刻。不過一直跑不到主劇情,在這種小事上打轉很長的篇幅,久了也會很膩。

    + +

    看樣子還會出很多的樣子。朝比奈實玖瑠的憂鬱涼宮春日的陰謀犬魔魅影中的伏筆,超能力者、外星人的邪惡聯盟,應該還會搞出很多事來。不知道要到什麼時候,才會有結局。不過我也不知道我有沒有那個命,可以一直看下去。

    + +

    不過整體來說,其實還蠻好看的啦~呵呵~ ^_*'

    + +

    我有時候會想,如果可以的話,我想變成像長門有希一樣,無所不知無所不能,雖然失去了一點跟人溝通的能力,不過也是值得的。

    + +

    唉呀唉呀~

    + +
    + +
    + +
    +
    10.22.’07. 2:28am.
    + +

    女生愛女生 かしまし~ガール・ミーツ・ガール~動畫

    + +

    其實前一陣子,看完女生愛女生的漫畫,上網搜尋女生愛女生的相關訊息,發現女生愛女生有出動畫了以後,就找到女生愛女生的動畫了。那時候找到的是網路上某些字幕組的翻譯版,譯得不大好,從頭到尾看完了以後感覺很不好,於是又到處開始找動畫 DVD 。去找以後才發現,女生愛女生台灣沒有代理,而動畫和日劇不同,台灣沒有代理的話,就沒有人趕自己壓來賣。所以夜市找得到台灣沒代理的日劇,可是找不到台灣沒代理的動畫。

    + +

    我不死心,又上網找。沒想到還真被我找到了。興沖沖看了封面,看樣子至少會譯得比網路上字幕組譯得還好,就下了訂單了。因為一些波折,收到又是一個星期後了。拆封來看,沒想到沒有封面,連字幕也都是某些字幕組的作品。頗為失望。加上之前已經從頭到尾看過一遍了,手上的事又開始忙,就擱著了。這一陣子手上的事暫告一段落,終於下定決心,把涼宮春日系列小說一口氣看完以後,又一口氣把三片動畫 DVD 都看完了。

    + +

    動畫其實之前從頭到尾看過一遍了,劇情都知道了。對動畫的結局真的超驚訝的!沒想到動畫最後竟然是選擇安菜,讓我下巴都要掉下來了。這…結局選擇小泊不是既定事項嗎?說實話,也沒有什麼規則強制規定動畫結局一定要和漫畫一樣啦,而且安菜也是同分的選擇,選擇安菜也是非常好的。我不斷這樣說服自己。看來我這個人也挺沒用的,很能適應環境呢,唉~

    + +

    不過,網路上找到的資料,一直傳說女生愛女生有隱藏的第十三集真正的結局,那是 2006-03-29 東京電視台全部播畢,在 2006-10-27 另外以 DVD 發行的。不過反正兩者台灣都沒有代理。幸運的是,昨天在網路上,找到了隱藏的第十三集。今晚重看動畫,除了重看 DVD 版一到十二集以外,更把第十三集也一口氣看完了。

    + +

    看第十三集前,我給自己做好心理準備:有可能還是跟安菜在一起,安菜也是很好的女生,不要有太多幻想。重看一到十二集的過程中,發現之前都沒有注意到,動畫裏的小泊,到後來越來越可憐。可是看了第十三集,發現真是大驚奇~竟然還是跟小泊在一起了,而且最後畫面美得像魔幻一樣,喜氣洋洋,連我都忍不住讚嘆出聲。雖然大佛彈三心二意的有點可惡,不過還是打從心底覺得:啊,真是太好了,還好有看到第十三集啊~

    + +

    女生愛女生還有出遊戲,不過是 PS2 的,所以和我無緣了,嗚嗚嗚~

    + +

    嗯,真的是很棒呢~ *^_^*

    + +
    + +
    + +
    +
    10.16.’07. 0:20am.
    + +

    台灣工銀 2000 高科技基金

    + +

    剛剛仔細看了九月份的共同基金績效評比。嗯,我大概可以瞭解為什麼台灣工銀 2000 高科技基金這兩個月表現不好了。依台灣工銀七月初的公告(金管證四字第 0960035684 號核准函),八月起台灣工銀 2000 高科技基金合併了台灣工銀 8899 成長基金。台灣工銀 2000 高科技基金和台灣工銀 8899 成長基金原是盛華投信的基金,工銀(盛華) 2000 一直是名列前茅的績優基金,表現遠優於大盤;而工銀(盛華) 8899 則是長期墊底,這幾年台灣股市年年大漲,工銀(盛華) 8899 卻不漲反賠。兩個合併後,工銀(盛華) 2000 必需要吃下工銀(盛華) 8899 原握有的爛股票,也無法短時間內脫手(短時間脫手會牽動股價跌得更慘),於是表現就被平均掉了。

    + +

    唔,這樣子啊。唔。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 135 | + 136 | + 137 | + 138 | + 139 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0137.html.zh-cn.html b/htdocs/imacat/me/diary/0137.html.zh-cn.html new file mode 120000 index 0000000..4f306a1 --- /dev/null +++ b/htdocs/imacat/me/diary/0137.html.zh-cn.html @@ -0,0 +1 @@ +0137.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0137.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0137.html.zh-cn.xhtml new file mode 100644 index 0000000..4092530 --- /dev/null +++ b/htdocs/imacat/me/diary/0137.html.zh-cn.xhtml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百三十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百三十七

    + +
    + +
    + +
    +
    10.22.’07. 3:27am.
    + +

    凉宫春日系列小说

    + +

    之前,在网路上找到轻小说凉宫春日的忧郁,并一口气读完了。其实那时候找到的不止一部凉宫春日的忧郁,而是凉宫春日的叹息凉宫春日的愤慨等一到八集。全部读起来蛮累人的,加上我还有一些工作要做,只好断断续续地看。这个星期工作告一段落,下定决心,硬是把全部一到八集一口气看完了。

    + +

    呼,真累。而且看到后来越看越慢。是因为越来越没有那么好看吗?嗯…不知道呢。

    + +

    不过到后来,还蛮会拖的就是了。随便一两句话,阿虚就要依次看看实玖瑠、长门、古泉等在场所有人的表情反应,然后依次描述一遍。即使人多,加上鹤屋学姊、三味线等等,也绝不马虎。这样对比每个人的反应是很有趣啦,而且人物的表情反应一讲再讲,也让读者对各个角色的性格印象深刻。不过一直跑不到主剧情,在这种小事上打转很长的篇幅,久了也会很腻。

    + +

    看样子还会出很多的样子。朝比奈实玖瑠的忧郁凉宫春日的阴谋犬魔魅影中的伏笔,超能力者、外星人的邪恶联盟,应该还会搞出很多事来。不知道要到什么时候,才会有结局。不过我也不知道我有没有那个命,可以一直看下去。

    + +

    不过整体来说,其实还蛮好看的啦~呵呵~ ^_*'

    + +

    我有时候会想,如果可以的话,我想变成像长门有希一样,无所不知无所不能,虽然失去了一点跟人沟通的能力,不过也是值得的。

    + +

    唉呀唉呀~

    + +
    + +
    + +
    +
    10.22.’07. 2:28am.
    + +

    女生爱女生 かしまし~ガール・ミーツ・ガール~动画

    + +

    其实前一阵子,看完女生爱女生的漫画,上网搜寻女生爱女生的相关讯息,发现女生爱女生有出动画了以后,就找到女生爱女生的动画了。那时候找到的是网路上某些字幕组的翻译版,译得不大好,从头到尾看完了以后感觉很不好,於是又到处开始找动画 DVD 。去找以后才发现,女生爱女生台湾没有代理,而动画和日剧不同,台湾没有代理的话,就没有人赶自己压来卖。所以夜市找得到台湾没代理的日剧,可是找不到台湾没代理的动画。

    + +

    我不死心,又上网找。没想到还真被我找到了。兴冲冲看了封面,看样子至少会译得比网路上字幕组译得还好,就下了订单了。因为一些波折,收到又是一个星期后了。拆封来看,没想到没有封面,连字幕也都是某些字幕组的作品。颇为失望。加上之前已经从头到尾看过一遍了,手上的事又开始忙,就搁著了。这一阵子手上的事暂告一段落,终於下定决心,把凉宫春日系列小说一口气看完以后,又一口气把三片动画 DVD 都看完了。

    + +

    动画其实之前从头到尾看过一遍了,剧情都知道了。对动画的结局真的超惊讶的!没想到动画最后竟然是选择安菜,让我下巴都要掉下来了。这…结局选择小泊不是既定事项吗?说实话,也没有什么规则强制规定动画结局一定要和漫画一样啦,而且安菜也是同分的选择,选择安菜也是非常好的。我不断这样说服自己。看来我这个人也挺没用的,很能适应环境呢,唉~

    + +

    不过,网路上找到的资料,一直传说女生爱女生有隐藏的第十三集真正的结局,那是 2006-03-29 东京电视台全部播毕,在 2006-10-27 另外以 DVD 发行的。不过反正两者台湾都没有代理。幸运的是,昨天在网路上,找到了隐藏的第十三集。今晚重看动画,除了重看 DVD 版一到十二集以外,更把第十三集也一口气看完了。

    + +

    看第十三集前,我给自己做好心理准备:有可能还是跟安菜在一起,安菜也是很好的女生,不要有太多幻想。重看一到十二集的过程中,发现之前都没有注意到,动画里的小泊,到后来越来越可怜。可是看了第十三集,发现真是大惊奇~竟然还是跟小泊在一起了,而且最后画面美得像魔幻一样,喜气洋洋,连我都忍不住赞叹出声。虽然大佛弹三心二意的有点可恶,不过还是打从心底觉得:啊,真是太好了,还好有看到第十三集啊~

    + +

    女生爱女生还有出游戏,不过是 PS2 的,所以和我无缘了,呜呜呜~

    + +

    嗯,真的是很棒呢~ *^_^*

    + +
    + +
    + +
    +
    10.16.’07. 0:20am.
    + +

    台湾工银 2000 高科技基金

    + +

    刚刚仔细看了九月份的共同基金绩效评比。嗯,我大概可以了解为什么台湾工银 2000 高科技基金这两个月表现不好了。依台湾工银七月初的公告(金管证四字第 0960035684 号核准函),八月起台湾工银 2000 高科技基金合并了台湾工银 8899 成长基金。台湾工银 2000 高科技基金和台湾工银 8899 成长基金原是盛华投信的基金,工银(盛华) 2000 一直是名列前茅的绩优基金,表现远优於大盘;而工银(盛华) 8899 则是长期垫底,这几年台湾股市年年大涨,工银(盛华) 8899 却不涨反赔。两个合并后,工银(盛华) 2000 必需要吃下工银(盛华) 8899 原握有的烂股票,也无法短时间内脱手(短时间脱手会牵动股价跌得更惨),於是表现就被平均掉了。

    + +

    唔,这样子啊。唔。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 135 | + 136 | + 137 | + 138 | + 139 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0137.html.zh-tw.html b/htdocs/imacat/me/diary/0137.html.zh-tw.html new file mode 120000 index 0000000..596d171 --- /dev/null +++ b/htdocs/imacat/me/diary/0137.html.zh-tw.html @@ -0,0 +1 @@ +0137.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0137.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0137.html.zh-tw.xhtml new file mode 100644 index 0000000..117b706 --- /dev/null +++ b/htdocs/imacat/me/diary/0137.html.zh-tw.xhtml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百三十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百三十七

    + +
    + +
    + +
    +
    10.22.’07. 3:27am.
    + +

    涼宮春日系列小說

    + +

    之前,在網路上找到輕小說涼宮春日的憂鬱,並一口氣讀完了。其實那時候找到的不止一部涼宮春日的憂鬱,而是涼宮春日的嘆息涼宮春日的憤慨等一到八集。全部讀起來蠻累人的,加上我還有一些工作要做,只好斷斷續續地看。這個星期工作告一段落,下定決心,硬是把全部一到八集一口氣看完了。

    + +

    呼,真累。而且看到後來越看越慢。是因為越來越沒有那麼好看嗎?嗯…不知道呢。

    + +

    不過到後來,還蠻會拖的就是了。隨便一兩句話,阿虛就要依次看看實玖瑠、長門、古泉等在場所有人的表情反應,然後依次描述一遍。即使人多,加上鶴屋學姊、三味線等等,也絕不馬虎。這樣對比每個人的反應是很有趣啦,而且人物的表情反應一講再講,也讓讀者對各個角色的性格印象深刻。不過一直跑不到主劇情,在這種小事上打轉很長的篇幅,久了也會很膩。

    + +

    看樣子還會出很多的樣子。朝比奈實玖瑠的憂鬱涼宮春日的陰謀犬魔魅影中的伏筆,超能力者、外星人的邪惡聯盟,應該還會搞出很多事來。不知道要到什麼時候,才會有結局。不過我也不知道我有沒有那個命,可以一直看下去。

    + +

    不過整體來說,其實還蠻好看的啦~呵呵~ ^_*'

    + +

    我有時候會想,如果可以的話,我想變成像長門有希一樣,無所不知無所不能,雖然失去了一點跟人溝通的能力,不過也是值得的。

    + +

    唉呀唉呀~

    + +
    + +
    + +
    +
    10.22.’07. 2:28am.
    + +

    女生愛女生 かしまし~ガール・ミーツ・ガール~動畫

    + +

    其實前一陣子,看完女生愛女生的漫畫,上網搜尋女生愛女生的相關訊息,發現女生愛女生有出動畫了以後,就找到女生愛女生的動畫了。那時候找到的是網路上某些字幕組的翻譯版,譯得不大好,從頭到尾看完了以後感覺很不好,於是又到處開始找動畫 DVD 。去找以後才發現,女生愛女生台灣沒有代理,而動畫和日劇不同,台灣沒有代理的話,就沒有人趕自己壓來賣。所以夜市找得到台灣沒代理的日劇,可是找不到台灣沒代理的動畫。

    + +

    我不死心,又上網找。沒想到還真被我找到了。興沖沖看了封面,看樣子至少會譯得比網路上字幕組譯得還好,就下了訂單了。因為一些波折,收到又是一個星期後了。拆封來看,沒想到沒有封面,連字幕也都是某些字幕組的作品。頗為失望。加上之前已經從頭到尾看過一遍了,手上的事又開始忙,就擱著了。這一陣子手上的事暫告一段落,終於下定決心,把涼宮春日系列小說一口氣看完以後,又一口氣把三片動畫 DVD 都看完了。

    + +

    動畫其實之前從頭到尾看過一遍了,劇情都知道了。對動畫的結局真的超驚訝的!沒想到動畫最後竟然是選擇安菜,讓我下巴都要掉下來了。這…結局選擇小泊不是既定事項嗎?說實話,也沒有什麼規則強制規定動畫結局一定要和漫畫一樣啦,而且安菜也是同分的選擇,選擇安菜也是非常好的。我不斷這樣說服自己。看來我這個人也挺沒用的,很能適應環境呢,唉~

    + +

    不過,網路上找到的資料,一直傳說女生愛女生有隱藏的第十三集真正的結局,那是 2006-03-29 東京電視台全部播畢,在 2006-10-27 另外以 DVD 發行的。不過反正兩者台灣都沒有代理。幸運的是,昨天在網路上,找到了隱藏的第十三集。今晚重看動畫,除了重看 DVD 版一到十二集以外,更把第十三集也一口氣看完了。

    + +

    看第十三集前,我給自己做好心理準備:有可能還是跟安菜在一起,安菜也是很好的女生,不要有太多幻想。重看一到十二集的過程中,發現之前都沒有注意到,動畫裏的小泊,到後來越來越可憐。可是看了第十三集,發現真是大驚奇~竟然還是跟小泊在一起了,而且最後畫面美得像魔幻一樣,喜氣洋洋,連我都忍不住讚嘆出聲。雖然大佛彈三心二意的有點可惡,不過還是打從心底覺得:啊,真是太好了,還好有看到第十三集啊~

    + +

    女生愛女生還有出遊戲,不過是 PS2 的,所以和我無緣了,嗚嗚嗚~

    + +

    嗯,真的是很棒呢~ *^_^*

    + +
    + +
    + +
    +
    10.16.’07. 0:20am.
    + +

    台灣工銀 2000 高科技基金

    + +

    剛剛仔細看了九月份的共同基金績效評比。嗯,我大概可以瞭解為什麼台灣工銀 2000 高科技基金這兩個月表現不好了。依台灣工銀七月初的公告(金管證四字第 0960035684 號核准函),八月起台灣工銀 2000 高科技基金合併了台灣工銀 8899 成長基金。台灣工銀 2000 高科技基金和台灣工銀 8899 成長基金原是盛華投信的基金,工銀(盛華) 2000 一直是名列前茅的績優基金,表現遠優於大盤;而工銀(盛華) 8899 則是長期墊底,這幾年台灣股市年年大漲,工銀(盛華) 8899 卻不漲反賠。兩個合併後,工銀(盛華) 2000 必需要吃下工銀(盛華) 8899 原握有的爛股票,也無法短時間內脫手(短時間脫手會牽動股價跌得更慘),於是表現就被平均掉了。

    + +

    唔,這樣子啊。唔。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 135 | + 136 | + 137 | + 138 | + 139 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0138.html.en.html b/htdocs/imacat/me/diary/0138.html.en.html new file mode 120000 index 0000000..844c5de --- /dev/null +++ b/htdocs/imacat/me/diary/0138.html.en.html @@ -0,0 +1 @@ +0138.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0138.html.en.xhtml b/htdocs/imacat/me/diary/0138.html.en.xhtml new file mode 100644 index 0000000..29baafb --- /dev/null +++ b/htdocs/imacat/me/diary/0138.html.en.xhtml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 138 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 138

    + +
    + +
    + +
    +
    11.23.’07. 2:42am.
    + +

    Core 2 Duo 的威力(和 Pentium D 相比)

    + +

    星期天晚上把 rinse 從 Pentium D 換成 Core 2 Duo 了以後,房間一下子安靜很多,也可以好好睡了。 Pentium D 是 Intel 早期的雙核心,沒上市多久,又出了第二代的雙核心 Core 2 Duo 。去年三月我買了 Pentium D 作新 rinse ,到了十一月公司買新 server ,上網搜集資料,看到 Core 2 Duo 這個沒看過的新名詞,仔細閱讀下,才知道 Core 2 Duo 是取代 Pentium D 的新雙核心 CPU ,解決了 Pentium D 太吵太耗電的問題,比 Pentium D 安靜省電很多。

    + +

    不過到底安靜省電到多少?除了耳朵聽得到的高頻噪音消失外,實際數據又是如何呢?省電又省了多少呢?這兩天翻看 MRTG 的監控報告,才真的有點被嚇到了。

    + +
    +最近一星期 rinse 的 CPU 溫度監控圖 +

    最近一星期 rinse 的 CPU 溫度監控圖

    +
    + +

    第一張是最近一星期 rinse 的 CPU 溫度監控圖。 CPU 溫度方面,從平均 55–75 度,一下子降到 40 度左右。溫度是耗電運轉產生的熱,降下來的溫度,就是省下來的電。

    + +
    +最近一星期 rinse 的 CPU 風扇轉速監控圖 +

    最近一星期 rinse 的風扇轉速監控圖

    +
    + +

    第二張是最近一星期 rinse 的 CPU 風扇轉速監控圖。 CPU 風扇轉速則從平均每分鐘 4600 轉,一下子降到每分鐘 770 轉左右。風扇是電腦噪音的根源,減少的轉速,就是消失的噪音。

    + +

    感覺上比溫度下降得更誇張,不過那是因為 40 度很接近室溫,所以風扇不需要很用力吹之故。根本的原因還是溫度的大幅降低,只不過參考點不是 0 度,而是三十幾度的室溫。

    + +

    剛開始看到 lm-sensors 回報 CPU 風扇轉速每分鐘 770 轉的時候,覺得大概是 lm-sensors 設定錯了。我管理的電腦,平均 CPU 風扇轉速都在每分鐘 2500–4700 轉左右。每分鐘 770 轉,真的是違反我的常識。不過當我瞭解這真的是真相, CPU 風扇真的轉速每分鐘 770 轉的時候,真的打從心底感到:啊,這真的是太酷了! ^_*'

    + +
    + +
    + +
    +
    11.19.’07. 3:25am.
    + +

    Core 2 Duo

    + +

    今天星期天中午,是被吵醒的。吵醒我的,是 rinse 的風扇聲。 Pentium-D 的高頻噪音,一直吵個不停,吵得我頭痛不已,神經衰若。幾次要坐到桌子前面寫程式,都寫不下去又跑開來。好吵。

    + +

    好吵。傍晚碰到小招,跟她抱怨了一堆。小招點醒我,超支固然不好,但是如果吵到睡都睡不好,什麼事都沒辦法,那死撐只是在浪費自己的時間。

    + +

    一語點醒夢中人。晚上,我就跑去光華商場,買了一顆 Core 2 Duo 的 CPU ,搭主機板,搭顯示卡,回來就把 rinse 換上去。

    + +

    嗯,好安靜啊,真是舒服。忍耐了一年半的噪音消失了。真是舒服啊~ *^_^*

    + +
    + +
    + +
    +
    11.19.’07. 3:18am.
    + +

    殺絕

    + +

    剛剛看緯來電影台,看了 1978 年的邵氏電影殺絕。真是好棒的電影啊!如果是小時候看,可能覺得枯燥吧。可是現在看起來,真的是太好看了。這是講一個一心追求天下第一劍手之名的年青無名劍客,追求的旅程。狄龍的演技,不論是年青人單純完全沒有懷疑的絕對自信、還是後來的恐懼、疑惑、惡夢,都讓人覺得真是太讚了。

    + +

    嗯嗯,好看好看~ *^_^*

    + +
    + +
    + +
    +
    10.22.’07. 4:21am.
    + +

    朝比奈實玖瑠的冒險 Episode00

    + +

    剛剛看了電影朝比奈實玖瑠的冒險 Episode00。哇哈哈哈哈,真是笑死我了。哈哈哈~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 136 | + 137 | + 138 | + 139 | + 140 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0138.html.zh-cn.html b/htdocs/imacat/me/diary/0138.html.zh-cn.html new file mode 120000 index 0000000..4991973 --- /dev/null +++ b/htdocs/imacat/me/diary/0138.html.zh-cn.html @@ -0,0 +1 @@ +0138.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0138.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0138.html.zh-cn.xhtml new file mode 100644 index 0000000..95a2a99 --- /dev/null +++ b/htdocs/imacat/me/diary/0138.html.zh-cn.xhtml @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百三十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百三十八

    + +
    + +
    + +
    +
    11.23.’07. 2:42am.
    + +

    Core 2 Duo 的威力(和 Pentium D 相比)

    + +

    星期天晚上把 rinse 从 Pentium D 换成 Core 2 Duo 了以后,房间一下子安静很多,也可以好好睡了。 Pentium D 是 Intel 早期的双核心,没上市多久,又出了第二代的双核心 Core 2 Duo 。去年三月我买了 Pentium D 作新 rinse ,到了十一月公司买新 server ,上网搜集资料,看到 Core 2 Duo 这个没看过的新名词,仔细阅读下,才知道 Core 2 Duo 是取代 Pentium D 的新双核心 CPU ,解决了 Pentium D 太吵太耗电的问题,比 Pentium D 安静省电很多。

    + +

    不过到底安静省电到多少?除了耳朵听得到的高频噪音消失外,实际数据又是如何呢?省电又省了多少呢?这两天翻看 MRTG 的监控报告,才真的有点被吓到了。

    + +
    +最近一星期 rinse 的 CPU 温度监控图 +

    最近一星期 rinse 的 CPU 温度监控图

    +
    + +

    第一张是最近一星期 rinse 的 CPU 温度监控图。 CPU 温度方面,从平均 55–75 度,一下子降到 40 度左右。温度是耗电运转产生的热,降下来的温度,就是省下来的电。

    + +
    +最近一星期 rinse 的 CPU 风扇转速监控图 +

    最近一星期 rinse 的风扇转速监控图

    +
    + +

    第二张是最近一星期 rinse 的 CPU 风扇转速监控图。 CPU 风扇转速则从平均每分钟 4600 转,一下子降到每分钟 770 转左右。风扇是电脑噪音的根源,减少的转速,就是消失的噪音。

    + +

    感觉上比温度下降得更夸张,不过那是因为 40 度很接近室温,所以风扇不需要很用力吹之故。根本的原因还是温度的大幅降低,只不过参考点不是 0 度,而是三十几度的室温。

    + +

    刚开始看到 lm-sensors 回报 CPU 风扇转速每分钟 770 转的时候,觉得大概是 lm-sensors 设定错了。我管理的电脑,平均 CPU 风扇转速都在每分钟 2500–4700 转左右。每分钟 770 转,真的是违反我的常识。不过当我了解这真的是真相, CPU 风扇真的转速每分钟 770 转的时候,真的打从心底感到:啊,这真的是太酷了! ^_*'

    + +
    + +
    + +
    +
    11.19.’07. 3:25am.
    + +

    Core 2 Duo

    + +

    今天星期天中午,是被吵醒的。吵醒我的,是 rinse 的风扇声。 Pentium-D 的高频噪音,一直吵个不停,吵得我头痛不已,神经衰若。几次要坐到桌子前面写程式,都写不下去又跑开来。好吵。

    + +

    好吵。傍晚碰到小招,跟她抱怨了一堆。小招点醒我,超支固然不好,但是如果吵到睡都睡不好,什么事都没办法,那死撑只是在浪费自己的时间。

    + +

    一语点醒梦中人。晚上,我就跑去光华商场,买了一颗 Core 2 Duo 的 CPU ,搭主机板,搭显示卡,回来就把 rinse 换上去。

    + +

    嗯,好安静啊,真是舒服。忍耐了一年半的噪音消失了。真是舒服啊~ *^_^*

    + +
    + +
    + +
    +
    11.19.’07. 3:18am.
    + +

    杀绝

    + +

    刚刚看纬来电影台,看了 1978 年的邵氏电影杀绝。真是好棒的电影啊!如果是小时候看,可能觉得枯燥吧。可是现在看起来,真的是太好看了。这是讲一个一心追求天下第一剑手之名的年青无名剑客,追求的旅程。狄龙的演技,不论是年青人单纯完全没有怀疑的绝对自信、还是后来的恐惧、疑惑、恶梦,都让人觉得真是太赞了。

    + +

    嗯嗯,好看好看~ *^_^*

    + +
    + +
    + +
    +
    10.22.’07. 4:21am.
    + +

    朝比奈实玖瑠的冒险 Episode00

    + +

    刚刚看了电影朝比奈实玖瑠的冒险 Episode00。哇哈哈哈哈,真是笑死我了。哈哈哈~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 136 | + 137 | + 138 | + 139 | + 140 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0138.html.zh-tw.html b/htdocs/imacat/me/diary/0138.html.zh-tw.html new file mode 120000 index 0000000..3bb99cb --- /dev/null +++ b/htdocs/imacat/me/diary/0138.html.zh-tw.html @@ -0,0 +1 @@ +0138.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0138.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0138.html.zh-tw.xhtml new file mode 100644 index 0000000..8cd957f --- /dev/null +++ b/htdocs/imacat/me/diary/0138.html.zh-tw.xhtml @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百三十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百三十八

    + +
    + +
    + +
    +
    11.23.’07. 2:42am.
    + +

    Core 2 Duo 的威力(和 Pentium D 相比)

    + +

    星期天晚上把 rinse 從 Pentium D 換成 Core 2 Duo 了以後,房間一下子安靜很多,也可以好好睡了。 Pentium D 是 Intel 早期的雙核心,沒上市多久,又出了第二代的雙核心 Core 2 Duo 。去年三月我買了 Pentium D 作新 rinse ,到了十一月公司買新 server ,上網搜集資料,看到 Core 2 Duo 這個沒看過的新名詞,仔細閱讀下,才知道 Core 2 Duo 是取代 Pentium D 的新雙核心 CPU ,解決了 Pentium D 太吵太耗電的問題,比 Pentium D 安靜省電很多。

    + +

    不過到底安靜省電到多少?除了耳朵聽得到的高頻噪音消失外,實際數據又是如何呢?省電又省了多少呢?這兩天翻看 MRTG 的監控報告,才真的有點被嚇到了。

    + +
    +最近一星期 rinse 的 CPU 溫度監控圖 +

    最近一星期 rinse 的 CPU 溫度監控圖

    +
    + +

    第一張是最近一星期 rinse 的 CPU 溫度監控圖。 CPU 溫度方面,從平均 55–75 度,一下子降到 40 度左右。溫度是耗電運轉產生的熱,降下來的溫度,就是省下來的電。

    + +
    +最近一星期 rinse 的 CPU 風扇轉速監控圖 +

    最近一星期 rinse 的風扇轉速監控圖

    +
    + +

    第二張是最近一星期 rinse 的 CPU 風扇轉速監控圖。 CPU 風扇轉速則從平均每分鐘 4600 轉,一下子降到每分鐘 770 轉左右。風扇是電腦噪音的根源,減少的轉速,就是消失的噪音。

    + +

    感覺上比溫度下降得更誇張,不過那是因為 40 度很接近室溫,所以風扇不需要很用力吹之故。根本的原因還是溫度的大幅降低,只不過參考點不是 0 度,而是三十幾度的室溫。

    + +

    剛開始看到 lm-sensors 回報 CPU 風扇轉速每分鐘 770 轉的時候,覺得大概是 lm-sensors 設定錯了。我管理的電腦,平均 CPU 風扇轉速都在每分鐘 2500–4700 轉左右。每分鐘 770 轉,真的是違反我的常識。不過當我瞭解這真的是真相, CPU 風扇真的轉速每分鐘 770 轉的時候,真的打從心底感到:啊,這真的是太酷了! ^_*'

    + +
    + +
    + +
    +
    11.19.’07. 3:25am.
    + +

    Core 2 Duo

    + +

    今天星期天中午,是被吵醒的。吵醒我的,是 rinse 的風扇聲。 Pentium-D 的高頻噪音,一直吵個不停,吵得我頭痛不已,神經衰若。幾次要坐到桌子前面寫程式,都寫不下去又跑開來。好吵。

    + +

    好吵。傍晚碰到小招,跟她抱怨了一堆。小招點醒我,超支固然不好,但是如果吵到睡都睡不好,什麼事都沒辦法,那死撐只是在浪費自己的時間。

    + +

    一語點醒夢中人。晚上,我就跑去光華商場,買了一顆 Core 2 Duo 的 CPU ,搭主機板,搭顯示卡,回來就把 rinse 換上去。

    + +

    嗯,好安靜啊,真是舒服。忍耐了一年半的噪音消失了。真是舒服啊~ *^_^*

    + +
    + +
    + +
    +
    11.19.’07. 3:18am.
    + +

    殺絕

    + +

    剛剛看緯來電影台,看了 1978 年的邵氏電影殺絕。真是好棒的電影啊!如果是小時候看,可能覺得枯燥吧。可是現在看起來,真的是太好看了。這是講一個一心追求天下第一劍手之名的年青無名劍客,追求的旅程。狄龍的演技,不論是年青人單純完全沒有懷疑的絕對自信、還是後來的恐懼、疑惑、惡夢,都讓人覺得真是太讚了。

    + +

    嗯嗯,好看好看~ *^_^*

    + +
    + +
    + +
    +
    10.22.’07. 4:21am.
    + +

    朝比奈實玖瑠的冒險 Episode00

    + +

    剛剛看了電影朝比奈實玖瑠的冒險 Episode00。哇哈哈哈哈,真是笑死我了。哈哈哈~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 136 | + 137 | + 138 | + 139 | + 140 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0139.html.en.html b/htdocs/imacat/me/diary/0139.html.en.html new file mode 120000 index 0000000..11eed4f --- /dev/null +++ b/htdocs/imacat/me/diary/0139.html.en.html @@ -0,0 +1 @@ +0139.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0139.html.en.xhtml b/htdocs/imacat/me/diary/0139.html.en.xhtml new file mode 100644 index 0000000..8ed0f2f --- /dev/null +++ b/htdocs/imacat/me/diary/0139.html.en.xhtml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 139 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 139

    + +
    + +
    + +
    +
    11.24.’07. 6:37pm.
    + +

    單提馬

    + +

    我平常沒事等時間,就是玩手機象棋遊戲。手機的棋力雖然弱,但玩久了,也讓我玩出了一些心得。我的棋力好像其實很弱,和電腦象棋遊戲打很辛苦,常常不知道為什麼就輸掉了,一直輸也學不到什麼東西。就算不要臉靠悔棋贏,因為棋步的計算是死的,下一百次也是那樣下,也不知道贏在哪裏。手機的計算處理能力很低,下棋很隨機,常贏就常玩,還因為電腦反應隨機,可以嘗試不同的戰術,反而讓我玩出了一些心得。

    + +

    之前我一定用當頭炮對屏風馬。這是橘中秘以來的基本佈局。玩久了以後,我發現屏風馬真的很厲害,像銅牆鐵壁一樣。一架起屏風馬,就盯死了前後左右十四個方位,還可以互相奧援,幾乎沒有死角。馬的防守威力很強,也是我玩屏風馬多了以後,才發現的。配合中象的話,更是穩如泰山,對方的車隨便進來都會被鎖死。不換子,很難破解得掉屏風馬。(還是因為手機太弱的源故呢?)

    + +

    不過屏風馬也有缺點。整個局面常常會被鎖死,變成雙方都沒有弱點的濠溝戰,很麻煩。

    + +

    看一些象棋教學教到單提馬,可是一直以來,都不知道幹嘛要用單提馬。屏風馬不是守得比較穩固嗎?把馬提到邊邊幹嘛?守備範圍只剩單兵,又無法相互奧援,敵方強攻中兵時汲汲可危。為什麼要架單提馬?我一直無法理解。

    + +

    上次找到了胡榮華的中國象棋實戰攻防,我只看了開局第一講,就累得看不下去。不過有講到單提馬,看到單提馬之後的演變,有點恍然大悟的感覺。

    + +

    單提馬其實重點不在馬,而是在五七炮。另一支炮可以架在五七位,然後進前兵,就可以強攻對方的屏風馬。到對付五七炮,只能提前上象,或是上巡河車。如果對方中象的位置被中炮佔住了,那就只能上一九象,兩隻象就被隔開了。最好是上巡河車,可是巡河車有兩、三步之遙,不一定來得及。就算對方架上象或巡河車,也還是可以不進兵,改炮打五七兵,接下來掃兵或盯象,一樣可以對對方產生很大的威脅。如果對方真的被拿下屏風馬,那接下來中炮吃中兵,馬上就贏了。

    + +

    像這樣的戰術,也是在手機上試過很多次了以後,才逐漸發現的。單提馬雖沒有銅牆鐵壁的防守,但換來的是五七炮猛烈的進攻火力。之前動輒七十、一百多步才結束,改用單提馬加五七炮後,常常十幾、三十幾步就贏了。

    + +

    畢竟對手是手機,是很弱的啦~這種話就不用明說了,我自己也知道。 ^^;

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 137 | + 138 | + 139 | + 140 | + 141 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0139.html.zh-cn.html b/htdocs/imacat/me/diary/0139.html.zh-cn.html new file mode 120000 index 0000000..a703419 --- /dev/null +++ b/htdocs/imacat/me/diary/0139.html.zh-cn.html @@ -0,0 +1 @@ +0139.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0139.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0139.html.zh-cn.xhtml new file mode 100644 index 0000000..b60feed --- /dev/null +++ b/htdocs/imacat/me/diary/0139.html.zh-cn.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百三十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百三十九

    + +
    + +
    + +
    +
    11.24.’07. 6:37pm.
    + +

    单提马

    + +

    我平常没事等时间,就是玩手机象棋游戏。手机的棋力虽然弱,但玩久了,也让我玩出了一些心得。我的棋力好像其实很弱,和电脑象棋游戏打很辛苦,常常不知道为什么就输掉了,一直输也学不到什么东西。就算不要脸靠悔棋赢,因为棋步的计算是死的,下一百次也是那样下,也不知道赢在哪里。手机的计算处理能力很低,下棋很随机,常赢就常玩,还因为电脑反应随机,可以尝试不同的战术,反而让我玩出了一些心得。

    + +

    之前我一定用当头炮对屏风马。这是橘中秘以来的基本布局。玩久了以后,我发现屏风马真的很厉害,像铜墙铁壁一样。一架起屏风马,就盯死了前后左右十四个方位,还可以互相奥援,几乎没有死角。马的防守威力很强,也是我玩屏风马多了以后,才发现的。配合中象的话,更是稳如泰山,对方的车随便进来都会被锁死。不换子,很难破解得掉屏风马。(还是因为手机太弱的源故呢?)

    + +

    不过屏风马也有缺点。整个局面常常会被锁死,变成双方都没有弱点的濠沟战,很麻烦。

    + +

    看一些象棋教学教到单提马,可是一直以来,都不知道干嘛要用单提马。屏风马不是守得比较稳固吗?把马提到边边干嘛?守备范围只剩单兵,又无法相互奥援,敌方强攻中兵时汲汲可危。为什么要架单提马?我一直无法理解。

    + +

    上次找到了胡荣华的中国象棋实战攻防,我只看了开局第一讲,就累得看不下去。不过有讲到单提马,看到单提马之后的演变,有点恍然大悟的感觉。

    + +

    单提马其实重点不在马,而是在五七炮。另一支炮可以架在五七位,然后进前兵,就可以强攻对方的屏风马。到对付五七炮,只能提前上象,或是上巡河车。如果对方中象的位置被中炮占住了,那就只能上一九象,两只象就被隔开了。最好是上巡河车,可是巡河车有两、三步之遥,不一定来得及。就算对方架上象或巡河车,也还是可以不进兵,改炮打五七兵,接下来扫兵或盯象,一样可以对对方产生很大的威胁。如果对方真的被拿下屏风马,那接下来中炮吃中兵,马上就赢了。

    + +

    像这样的战术,也是在手机上试过很多次了以后,才逐渐发现的。单提马虽没有铜墙铁壁的防守,但换来的是五七炮猛烈的进攻火力。之前动辄七十、一百多步才结束,改用单提马加五七炮后,常常十几、三十几步就赢了。

    + +

    毕竟对手是手机,是很弱的啦~这种话就不用明说了,我自己也知道。 ^^;

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 137 | + 138 | + 139 | + 140 | + 141 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0139.html.zh-tw.html b/htdocs/imacat/me/diary/0139.html.zh-tw.html new file mode 120000 index 0000000..d61a965 --- /dev/null +++ b/htdocs/imacat/me/diary/0139.html.zh-tw.html @@ -0,0 +1 @@ +0139.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0139.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0139.html.zh-tw.xhtml new file mode 100644 index 0000000..3d66609 --- /dev/null +++ b/htdocs/imacat/me/diary/0139.html.zh-tw.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百三十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百三十九

    + +
    + +
    + +
    +
    11.24.’07. 6:37pm.
    + +

    單提馬

    + +

    我平常沒事等時間,就是玩手機象棋遊戲。手機的棋力雖然弱,但玩久了,也讓我玩出了一些心得。我的棋力好像其實很弱,和電腦象棋遊戲打很辛苦,常常不知道為什麼就輸掉了,一直輸也學不到什麼東西。就算不要臉靠悔棋贏,因為棋步的計算是死的,下一百次也是那樣下,也不知道贏在哪裏。手機的計算處理能力很低,下棋很隨機,常贏就常玩,還因為電腦反應隨機,可以嘗試不同的戰術,反而讓我玩出了一些心得。

    + +

    之前我一定用當頭炮對屏風馬。這是橘中秘以來的基本佈局。玩久了以後,我發現屏風馬真的很厲害,像銅牆鐵壁一樣。一架起屏風馬,就盯死了前後左右十四個方位,還可以互相奧援,幾乎沒有死角。馬的防守威力很強,也是我玩屏風馬多了以後,才發現的。配合中象的話,更是穩如泰山,對方的車隨便進來都會被鎖死。不換子,很難破解得掉屏風馬。(還是因為手機太弱的源故呢?)

    + +

    不過屏風馬也有缺點。整個局面常常會被鎖死,變成雙方都沒有弱點的濠溝戰,很麻煩。

    + +

    看一些象棋教學教到單提馬,可是一直以來,都不知道幹嘛要用單提馬。屏風馬不是守得比較穩固嗎?把馬提到邊邊幹嘛?守備範圍只剩單兵,又無法相互奧援,敵方強攻中兵時汲汲可危。為什麼要架單提馬?我一直無法理解。

    + +

    上次找到了胡榮華的中國象棋實戰攻防,我只看了開局第一講,就累得看不下去。不過有講到單提馬,看到單提馬之後的演變,有點恍然大悟的感覺。

    + +

    單提馬其實重點不在馬,而是在五七炮。另一支炮可以架在五七位,然後進前兵,就可以強攻對方的屏風馬。到對付五七炮,只能提前上象,或是上巡河車。如果對方中象的位置被中炮佔住了,那就只能上一九象,兩隻象就被隔開了。最好是上巡河車,可是巡河車有兩、三步之遙,不一定來得及。就算對方架上象或巡河車,也還是可以不進兵,改炮打五七兵,接下來掃兵或盯象,一樣可以對對方產生很大的威脅。如果對方真的被拿下屏風馬,那接下來中炮吃中兵,馬上就贏了。

    + +

    像這樣的戰術,也是在手機上試過很多次了以後,才逐漸發現的。單提馬雖沒有銅牆鐵壁的防守,但換來的是五七炮猛烈的進攻火力。之前動輒七十、一百多步才結束,改用單提馬加五七炮後,常常十幾、三十幾步就贏了。

    + +

    畢竟對手是手機,是很弱的啦~這種話就不用明說了,我自己也知道。 ^^;

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 137 | + 138 | + 139 | + 140 | + 141 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0140.html.en.html b/htdocs/imacat/me/diary/0140.html.en.html new file mode 120000 index 0000000..8951d98 --- /dev/null +++ b/htdocs/imacat/me/diary/0140.html.en.html @@ -0,0 +1 @@ +0140.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0140.html.en.xhtml b/htdocs/imacat/me/diary/0140.html.en.xhtml new file mode 100644 index 0000000..6cc1906 --- /dev/null +++ b/htdocs/imacat/me/diary/0140.html.en.xhtml @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 140 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 140

    + +
    + +
    + +
    +
    11.25.’07. 4:04pm.
    + +

    赤石路代

    + +
    +市長遠山京香 +

    市長遠山京香

    +
    + +
    +天草 X AMAKUSA1637 +

    天草 X AMAKUSA1637

    +
    + +
    +晨光中的詠嘆調 暁のARIA +

    晨光中的詠嘆調 暁のARIA

    +
    + +
    +天之神話地之永遠 天の神話地の永遠 +

    天之神話地之永遠 天の神話地の永遠

    +
    + +
    +P.A替身女孩 VIDEOJ +

    攝影急先鋒 VIDEOJ

    +
    + +
    +P.A替身女孩 P.A. +

    P.A替身女孩 P.A.

    +
    + +
    +姬 100% +

    姬 100%

    +
    + +

    最近,迷上了赤石路代。覺得她畫的漫畫好棒~一開始,不知道是從誰那裏,聽到了人家跟我說姬 100%。把姬 100%翻出來看的時候,覺得是早期的畫風,不過感覺很棒,裏面的女主角非常獨立、強大,男主角必需要很辛苦努力,才能站在和她平等的地位。後來陸續看了好幾部她的漫畫,像P.A替身女孩 P.A.攝影急先鋒 VIDEOJ市長遠山京香天草 X AMAKUSA1637,才知道她還是現役漫畫家。哇,那不就是長壽的作者了嗎?越看,越喜歡她的漫畫。她的故事裏,女主角都非常獨立、強大,男主角不是位居於輔助的地位,就是必需要很辛苦努力,才能站在和她平等的地位。而且,她的作品還有很強烈的正義感和社會意識。

    + +

    市長遠山京香裏,推理小說家遠山京香,接替備受愛戴的前市長的公公、不想從政的老公,出馬選上市長,以自己的理念,積極從事市政。漫畫裏,不斷帶到地方政治生態與女性參政、女性社會參與的問題。一般男性漫畫家畫的政治漫畫,都把焦點放在政黨政治、全日本的未來與日本的世界地位,這些議題眼光遠大,但其實比較流於政治閒談,不但主張本身有爭議,而且實際從政的人其實不大碰得到這些問題。市長遠山京香的目光放在地方政治生態與社區、女性問題,政黨能介入的不多,但其實是民眾迫切需要政府幫助、政治家每天面對的問題。雖然對於問題的描述與解決有點過於簡化,但就關心的議題和呈現的努力態度上,還是讓人非常感動。

    + +

    漫畫家不是從政者,對政治的瞭解本來就不可能貼切了。對於政治問題的描述與解決過於簡化,不管是川口開治、弘兼憲史、倉科遼(DAWN-旭日東昇 DAWN -陽はまた昇る-)、安童夕馬‧朝基勝士朝基まさし王牌至尊 クニミツの政)都是一樣的。

    + +

    天草 X AMAKUSA1637中,天主教教會高中,表現最頂尖的一群死黨,時光倒流回到了天草之亂的時代,女主角代替起義失敗的天草四郎,以現代的科學、歷史知識,帶領薄弱的民兵對抗幕府,企圖扭轉時代的悲劇。這是一部不大像歷史漫畫的歷史漫畫,最後違反了歷史漫畫的最大禁忌,扭轉了歷史。可是這裏面,所呈現的歷史正義,卻讓人非常感動。史實中的天草四郎之亂雖然以幕府平定亂事,天主教徒大屠殺收場。但如果能以漫畫中的方式扭轉歷史,即使日本因此分裂成了南和北兩個國家,也會讓人覺得:啊,如果真的是這樣,也是不錯的呢~

    + +

    最新連載中的晨光中的詠嘆調 暁のARIA中,女主角是大正時代有錢人家的私生女,從小被單獨扶養,有音樂天份。直到考7上音樂學校,才認識同校的同父異母哥哥與妹妹。兩個男主角,都是不能愛,卻已經都愛上的人,一個是親哥哥,一個是已婚的老師。還有一個不滿哥哥、老師、學校的注目目光被搶走,手段陰險的妹妹,到處流言流語的同學。感覺上像是非常危險的漫畫。看封皮說這是長篇連載,不過現在只出到第二集。不知道以後會怎麼發展呢~

    + +

    另一部也是新連載的天之神話地之永遠 天の神話地の永遠則是日本大巫女,和神和一起到處收妖除魔的故事,感覺比較老套的設定,可是還是很好看。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 138 | + 139 | + 140 | + 141 | + 142 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0140.html.zh-cn.html b/htdocs/imacat/me/diary/0140.html.zh-cn.html new file mode 120000 index 0000000..240d5ed --- /dev/null +++ b/htdocs/imacat/me/diary/0140.html.zh-cn.html @@ -0,0 +1 @@ +0140.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0140.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0140.html.zh-cn.xhtml new file mode 100644 index 0000000..37c105e --- /dev/null +++ b/htdocs/imacat/me/diary/0140.html.zh-cn.xhtml @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百四十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百四十

    + +
    + +
    + +
    +
    11.25.’07. 4:04pm.
    + +

    赤石路代

    + +
    +市长远山京香 +

    市长远山京香

    +
    + +
    +天草 X AMAKUSA1637 +

    天草 X AMAKUSA1637

    +
    + +
    +晨光中的咏叹调 暁のARIA +

    晨光中的咏叹调 暁のARIA

    +
    + +
    +天之神话地之永远 天の神话地の永远 +

    天之神话地之永远 天の神话地の永远

    +
    + +
    +P.A替身女孩 VIDEOJ +

    摄影急先锋 VIDEOJ

    +
    + +
    +P.A替身女孩 P.A. +

    P.A替身女孩 P.A.

    +
    + +
    +姬 100% +

    姬 100%

    +
    + +

    最近,迷上了赤石路代。觉得她画的漫画好棒~一开始,不知道是从谁那里,听到了人家跟我说姬 100%。把姬 100%翻出来看的时候,觉得是早期的画风,不过感觉很棒,里面的女主角非常独立、强大,男主角必需要很辛苦努力,才能站在和她平等的地位。后来陆续看了好几部她的漫画,像P.A替身女孩 P.A.摄影急先锋 VIDEOJ市长远山京香天草 X AMAKUSA1637,才知道她还是现役漫画家。哇,那不就是长寿的作者了吗?越看,越喜欢她的漫画。她的故事里,女主角都非常独立、强大,男主角不是位居於辅助的地位,就是必需要很辛苦努力,才能站在和她平等的地位。而且,她的作品还有很强烈的正义感和社会意识。

    + +

    市长远山京香里,推理小说家远山京香,接替备受爱戴的前市长的公公、不想从政的老公,出马选上市长,以自己的理念,积极从事市政。漫画里,不断带到地方政治生态与女性参政、女性社会参与的问题。一般男性漫画家画的政治漫画,都把焦点放在政党政治、全日本的未来与日本的世界地位,这些议题眼光远大,但其实比较流於政治闲谈,不但主张本身有争议,而且实际从政的人其实不大碰得到这些问题。市长远山京香的目光放在地方政治生态与社区、女性问题,政党能介入的不多,但其实是民众迫切需要政府帮助、政治家每天面对的问题。虽然对於问题的描述与解决有点过於简化,但就关心的议题和呈现的努力态度上,还是让人非常感动。

    + +

    漫画家不是从政者,对政治的了解本来就不可能贴切了。对於政治问题的描述与解决过於简化,不管是川口开治、弘兼宪史、仓科辽(DAWN-旭日东升 DAWN -阳はまた升る-)、安童夕马・朝基胜士朝基まさし王牌至尊 クニミツの政)都是一样的。

    + +

    天草 X AMAKUSA1637中,天主教教会高中,表现最顶尖的一群死党,时光倒流回到了天草之乱的时代,女主角代替起义失败的天草四郎,以现代的科学、历史知识,带领薄弱的民兵对抗幕府,企图扭转时代的悲剧。这是一部不大像历史漫画的历史漫画,最后违反了历史漫画的最大禁忌,扭转了历史。可是这里面,所呈现的历史正义,却让人非常感动。史实中的天草四郎之乱虽然以幕府平定乱事,天主教徒大屠杀收场。但如果能以漫画中的方式扭转历史,即使日本因此分裂成了南和北两个国家,也会让人觉得:啊,如果真的是这样,也是不错的呢~

    + +

    最新连载中的晨光中的咏叹调 暁のARIA中,女主角是大正时代有钱人家的私生女,从小被单独扶养,有音乐天份。直到考7上音乐学校,才认识同校的同父异母哥哥与妹妹。两个男主角,都是不能爱,却已经都爱上的人,一个是亲哥哥,一个是已婚的老师。还有一个不满哥哥、老师、学校的注目目光被抢走,手段阴险的妹妹,到处流言流语的同学。感觉上像是非常危险的漫画。看封皮说这是长篇连载,不过现在只出到第二集。不知道以后会怎么发展呢~

    + +

    另一部也是新连载的天之神话地之永远 天の神话地の永远则是日本大巫女,和神和一起到处收妖除魔的故事,感觉比较老套的设定,可是还是很好看。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 138 | + 139 | + 140 | + 141 | + 142 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0140.html.zh-tw.html b/htdocs/imacat/me/diary/0140.html.zh-tw.html new file mode 120000 index 0000000..64be795 --- /dev/null +++ b/htdocs/imacat/me/diary/0140.html.zh-tw.html @@ -0,0 +1 @@ +0140.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0140.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0140.html.zh-tw.xhtml new file mode 100644 index 0000000..e4cd2d4 --- /dev/null +++ b/htdocs/imacat/me/diary/0140.html.zh-tw.xhtml @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百四十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百四十

    + +
    + +
    + +
    +
    11.25.’07. 4:04pm.
    + +

    赤石路代

    + +
    +市長遠山京香 +

    市長遠山京香

    +
    + +
    +天草 X AMAKUSA1637 +

    天草 X AMAKUSA1637

    +
    + +
    +晨光中的詠嘆調 暁のARIA +

    晨光中的詠嘆調 暁のARIA

    +
    + +
    +天之神話地之永遠 天の神話地の永遠 +

    天之神話地之永遠 天の神話地の永遠

    +
    + +
    +P.A替身女孩 VIDEOJ +

    攝影急先鋒 VIDEOJ

    +
    + +
    +P.A替身女孩 P.A. +

    P.A替身女孩 P.A.

    +
    + +
    +姬 100% +

    姬 100%

    +
    + +

    最近,迷上了赤石路代。覺得她畫的漫畫好棒~一開始,不知道是從誰那裏,聽到了人家跟我說姬 100%。把姬 100%翻出來看的時候,覺得是早期的畫風,不過感覺很棒,裏面的女主角非常獨立、強大,男主角必需要很辛苦努力,才能站在和她平等的地位。後來陸續看了好幾部她的漫畫,像P.A替身女孩 P.A.攝影急先鋒 VIDEOJ市長遠山京香天草 X AMAKUSA1637,才知道她還是現役漫畫家。哇,那不就是長壽的作者了嗎?越看,越喜歡她的漫畫。她的故事裏,女主角都非常獨立、強大,男主角不是位居於輔助的地位,就是必需要很辛苦努力,才能站在和她平等的地位。而且,她的作品還有很強烈的正義感和社會意識。

    + +

    市長遠山京香裏,推理小說家遠山京香,接替備受愛戴的前市長的公公、不想從政的老公,出馬選上市長,以自己的理念,積極從事市政。漫畫裏,不斷帶到地方政治生態與女性參政、女性社會參與的問題。一般男性漫畫家畫的政治漫畫,都把焦點放在政黨政治、全日本的未來與日本的世界地位,這些議題眼光遠大,但其實比較流於政治閒談,不但主張本身有爭議,而且實際從政的人其實不大碰得到這些問題。市長遠山京香的目光放在地方政治生態與社區、女性問題,政黨能介入的不多,但其實是民眾迫切需要政府幫助、政治家每天面對的問題。雖然對於問題的描述與解決有點過於簡化,但就關心的議題和呈現的努力態度上,還是讓人非常感動。

    + +

    漫畫家不是從政者,對政治的瞭解本來就不可能貼切了。對於政治問題的描述與解決過於簡化,不管是川口開治、弘兼憲史、倉科遼(DAWN-旭日東昇 DAWN -陽はまた昇る-)、安童夕馬‧朝基勝士朝基まさし王牌至尊 クニミツの政)都是一樣的。

    + +

    天草 X AMAKUSA1637中,天主教教會高中,表現最頂尖的一群死黨,時光倒流回到了天草之亂的時代,女主角代替起義失敗的天草四郎,以現代的科學、歷史知識,帶領薄弱的民兵對抗幕府,企圖扭轉時代的悲劇。這是一部不大像歷史漫畫的歷史漫畫,最後違反了歷史漫畫的最大禁忌,扭轉了歷史。可是這裏面,所呈現的歷史正義,卻讓人非常感動。史實中的天草四郎之亂雖然以幕府平定亂事,天主教徒大屠殺收場。但如果能以漫畫中的方式扭轉歷史,即使日本因此分裂成了南和北兩個國家,也會讓人覺得:啊,如果真的是這樣,也是不錯的呢~

    + +

    最新連載中的晨光中的詠嘆調 暁のARIA中,女主角是大正時代有錢人家的私生女,從小被單獨扶養,有音樂天份。直到考7上音樂學校,才認識同校的同父異母哥哥與妹妹。兩個男主角,都是不能愛,卻已經都愛上的人,一個是親哥哥,一個是已婚的老師。還有一個不滿哥哥、老師、學校的注目目光被搶走,手段陰險的妹妹,到處流言流語的同學。感覺上像是非常危險的漫畫。看封皮說這是長篇連載,不過現在只出到第二集。不知道以後會怎麼發展呢~

    + +

    另一部也是新連載的天之神話地之永遠 天の神話地の永遠則是日本大巫女,和神和一起到處收妖除魔的故事,感覺比較老套的設定,可是還是很好看。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 138 | + 139 | + 140 | + 141 | + 142 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0141.html.en.html b/htdocs/imacat/me/diary/0141.html.en.html new file mode 120000 index 0000000..ce7a2b0 --- /dev/null +++ b/htdocs/imacat/me/diary/0141.html.en.html @@ -0,0 +1 @@ +0141.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0141.html.en.xhtml b/htdocs/imacat/me/diary/0141.html.en.xhtml new file mode 100644 index 0000000..aa87a87 --- /dev/null +++ b/htdocs/imacat/me/diary/0141.html.en.xhtml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 141 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 141

    + +
    + +
    + +
    +
    12.10.’07. 2:04pm.
    + +

    女僕咖啡

    + +

    其實我一直都沒有去過女僕咖啡。說起來,女僕咖啡已經是秋葉原的名產,也是動漫迷的常識了。我之前也聽說台北也開了女僕咖啡,可是一直沒有機會去看。最近想到,就想見識一下,到處去找女僕咖啡店,鎖定還有營業的,一一去逛。

    + +

    昨天順利進去的,是位於萬華龍山寺前的珈琲.可思客。其實前天星期六就有去了,記著大略的地址和地圖方位,就出門了。沒想到從下午四點一直找到六點,遍尋不著。在和平西路三段 109 巷來來去去好幾次,都沒看到。唔。真是可惡。於是隔天星期天,就把地址和地圖列印下來。這次真的找到了,可是沒想到是在之前來來去去好幾趟的 109 巷上。那我昨天地圖沒記錯啊,為什麼就是找不到呢?唔,難道是有魔法障壁嗎?女僕咖啡果然是有神奇魔法的地方~讓我的景仰又更深了一層。

    + +

    進去一看,唔,唔,唔唔唔~先說好,我來這裏純粹只是好奇,之前就有看過貓耳女僕的照片了,也不覺得有什麼好萌的,所以純粹是抱著開開眼界的心情。沒想到推門進去,迎面而來櫃台上的三位貓耳聖誕女僕,讓我差點萌死在門口。原來如此啊,聖誕節快到了呢~不,不對,不是這個感想。天哪~好萌喔~原來如此啊,三次元的果然不一樣~看照片都沒有這麼萌的感覺。真是可愛到會殺死人。真想暈死當場。

    + +
    +可思客 2007 的貓耳聖誕女僕辛苦工作的姿態 +

    可思客 2007 的貓耳聖誕女僕辛苦工作的姿態

    +
    + +

    因為不能照相(應該吧),所以只好用畫的了。我只敢趁女僕別過頭去時偷畫,所以只有背影。畫得不好,請女僕大人們見諒。大概就是這種感覺。我拼命忍住不尖叫,拼命忍住不偷看。要好好保持有風度的好主人的形象,才不會被女僕大人們唾棄。可是還是真的太~萌了,忍耐得好痛苦~

    + +

    原來就是這樣啊。嗯嗯。女僕咖啡真是好地方呢~店裏的擺飾也超可愛的,還有早安少女組的演唱會從早播到晚。感覺是我會非常喜歡的一家店。

    + +

    (唔,依瑪貓也喜歡早安少女組啊?唔,唔,是這樣的嗎?才,才沒有呢!!)

    + +

    話說回來,可思客是個能讓人感覺輕鬆的地方。女僕不會叫客人主人,和想像的不大一樣。價位出乎意料的普通,和公館的普通咖啡、茶店沒有差別,簡餐 170 左右,飲料 60–90 之間。而且還有很多一般的客人,很多去龍山寺拜拜的老先生老太太進來坐。感覺像是隨時一個人都可以進來坐的樣子。雖然沒有被叫主人,可是感覺說不定更輕鬆呢~

    + +

    珈琲.可思客的地址是臺北市和平西路三段 109 巷 3-2 號。嗯嗯,要記住。

    + +

    另外一家 Fatimaid ,我就沒去成了。 Fatimaid 在火車站北邊的台北地下街(不是火車站正下方的台北捷運地下街喔),實施徹底的前日預約制,所以我就被擋在門外了。我打電話去的時候,一開口就是主人,聲音很像答錄機,害我嚇一跳,差點忘了接話。不過我有繞到門口去看過,女僕穿的是傳統的英式女僕裝,店裏也有英式下午茶的感覺,還有不知道是什麼的女僕桌邊特別服務。說起來這說不定才是正統女僕路線。嗯嗯。

    + +

    不過說到台灣的女僕咖啡,應該還是要首推高雄的月讀咖啡吧。自己是高雄人,到現在還沒去過月讀。真想去月讀啊~真的該找一天,回去看看。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 139 | + 140 | + 141 | + 142 | + 143 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0141.html.zh-cn.html b/htdocs/imacat/me/diary/0141.html.zh-cn.html new file mode 120000 index 0000000..ed7a70f --- /dev/null +++ b/htdocs/imacat/me/diary/0141.html.zh-cn.html @@ -0,0 +1 @@ +0141.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0141.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0141.html.zh-cn.xhtml new file mode 100644 index 0000000..7e48459 --- /dev/null +++ b/htdocs/imacat/me/diary/0141.html.zh-cn.xhtml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百四十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百四十一

    + +
    + +
    + +
    +
    12.10.’07. 2:04pm.
    + +

    女仆咖啡

    + +

    其实我一直都没有去过女仆咖啡。说起来,女仆咖啡已经是秋叶原的名产,也是动漫迷的常识了。我之前也听说台北也开了女仆咖啡,可是一直没有机会去看。最近想到,就想见识一下,到处去找女仆咖啡店,锁定还有营业的,一一去逛。

    + +

    昨天顺利进去的,是位於万华龙山寺前的珈琲.可思客。其实前天星期六就有去了,记著大略的地址和地图方位,就出门了。没想到从下午四点一直找到六点,遍寻不著。在和平西路三段 109 巷来来去去好几次,都没看到。唔。真是可恶。於是隔天星期天,就把地址和地图列印下来。这次真的找到了,可是没想到是在之前来来去去好几趟的 109 巷上。那我昨天地图没记错啊,为什么就是找不到呢?唔,难道是有魔法障壁吗?女仆咖啡果然是有神奇魔法的地方~让我的景仰又更深了一层。

    + +

    进去一看,唔,唔,唔唔唔~先说好,我来这里纯粹只是好奇,之前就有看过猫耳女仆的照片了,也不觉得有什么好萌的,所以纯粹是抱著开开眼界的心情。没想到推门进去,迎面而来柜台上的三位猫耳圣诞女仆,让我差点萌死在门口。原来如此啊,圣诞节快到了呢~不,不对,不是这个感想。天哪~好萌喔~原来如此啊,三次元的果然不一样~看照片都没有这么萌的感觉。真是可爱到会杀死人。真想晕死当场。

    + +
    +可思客 2007 的猫耳圣诞女仆辛苦工作的姿态 +

    可思客 2007 的猫耳圣诞女仆辛苦工作的姿态

    +
    + +

    因为不能照相(应该吧),所以只好用画的了。我只敢趁女仆别过头去时偷画,所以只有背影。画得不好,请女仆大人们见谅。大概就是这种感觉。我拼命忍住不尖叫,拼命忍住不偷看。要好好保持有风度的好主人的形象,才不会被女仆大人们唾弃。可是还是真的太~萌了,忍耐得好痛苦~

    + +

    原来就是这样啊。嗯嗯。女仆咖啡真是好地方呢~店里的摆饰也超可爱的,还有早安少女组的演唱会从早播到晚。感觉是我会非常喜欢的一家店。

    + +

    (唔,依玛猫也喜欢早安少女组啊?唔,唔,是这样的吗?才,才没有呢!!)

    + +

    话说回来,可思客是个能让人感觉轻松的地方。女仆不会叫客人主人,和想像的不大一样。价位出乎意料的普通,和公馆的普通咖啡、茶店没有差别,简餐 170 左右,饮料 60–90 之间。而且还有很多一般的客人,很多去龙山寺拜拜的老先生老太太进来坐。感觉像是随时一个人都可以进来坐的样子。虽然没有被叫主人,可是感觉说不定更轻松呢~

    + +

    珈琲.可思客的地址是台北市和平西路三段 109 巷 3-2 号。嗯嗯,要记住。

    + +

    另外一家 Fatimaid ,我就没去成了。 Fatimaid 在火车站北边的台北地下街(不是火车站正下方的台北捷运地下街喔),实施彻底的前日预约制,所以我就被挡在门外了。我打电话去的时候,一开口就是主人,声音很像答录机,害我吓一跳,差点忘了接话。不过我有绕到门口去看过,女仆穿的是传统的英式女仆装,店里也有英式下午茶的感觉,还有不知道是什么的女仆桌边特别服务。说起来这说不定才是正统女仆路线。嗯嗯。

    + +

    不过说到台湾的女仆咖啡,应该还是要首推高雄的月读咖啡吧。自己是高雄人,到现在还没去过月读。真想去月读啊~真的该找一天,回去看看。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 139 | + 140 | + 141 | + 142 | + 143 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0141.html.zh-tw.html b/htdocs/imacat/me/diary/0141.html.zh-tw.html new file mode 120000 index 0000000..4eb8160 --- /dev/null +++ b/htdocs/imacat/me/diary/0141.html.zh-tw.html @@ -0,0 +1 @@ +0141.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0141.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0141.html.zh-tw.xhtml new file mode 100644 index 0000000..ca1a6e8 --- /dev/null +++ b/htdocs/imacat/me/diary/0141.html.zh-tw.xhtml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百四十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百四十一

    + +
    + +
    + +
    +
    12.10.’07. 2:04pm.
    + +

    女僕咖啡

    + +

    其實我一直都沒有去過女僕咖啡。說起來,女僕咖啡已經是秋葉原的名產,也是動漫迷的常識了。我之前也聽說台北也開了女僕咖啡,可是一直沒有機會去看。最近想到,就想見識一下,到處去找女僕咖啡店,鎖定還有營業的,一一去逛。

    + +

    昨天順利進去的,是位於萬華龍山寺前的珈琲.可思客。其實前天星期六就有去了,記著大略的地址和地圖方位,就出門了。沒想到從下午四點一直找到六點,遍尋不著。在和平西路三段 109 巷來來去去好幾次,都沒看到。唔。真是可惡。於是隔天星期天,就把地址和地圖列印下來。這次真的找到了,可是沒想到是在之前來來去去好幾趟的 109 巷上。那我昨天地圖沒記錯啊,為什麼就是找不到呢?唔,難道是有魔法障壁嗎?女僕咖啡果然是有神奇魔法的地方~讓我的景仰又更深了一層。

    + +

    進去一看,唔,唔,唔唔唔~先說好,我來這裏純粹只是好奇,之前就有看過貓耳女僕的照片了,也不覺得有什麼好萌的,所以純粹是抱著開開眼界的心情。沒想到推門進去,迎面而來櫃台上的三位貓耳聖誕女僕,讓我差點萌死在門口。原來如此啊,聖誕節快到了呢~不,不對,不是這個感想。天哪~好萌喔~原來如此啊,三次元的果然不一樣~看照片都沒有這麼萌的感覺。真是可愛到會殺死人。真想暈死當場。

    + +
    +可思客 2007 的貓耳聖誕女僕辛苦工作的姿態 +

    可思客 2007 的貓耳聖誕女僕辛苦工作的姿態

    +
    + +

    因為不能照相(應該吧),所以只好用畫的了。我只敢趁女僕別過頭去時偷畫,所以只有背影。畫得不好,請女僕大人們見諒。大概就是這種感覺。我拼命忍住不尖叫,拼命忍住不偷看。要好好保持有風度的好主人的形象,才不會被女僕大人們唾棄。可是還是真的太~萌了,忍耐得好痛苦~

    + +

    原來就是這樣啊。嗯嗯。女僕咖啡真是好地方呢~店裏的擺飾也超可愛的,還有早安少女組的演唱會從早播到晚。感覺是我會非常喜歡的一家店。

    + +

    (唔,依瑪貓也喜歡早安少女組啊?唔,唔,是這樣的嗎?才,才沒有呢!!)

    + +

    話說回來,可思客是個能讓人感覺輕鬆的地方。女僕不會叫客人主人,和想像的不大一樣。價位出乎意料的普通,和公館的普通咖啡、茶店沒有差別,簡餐 170 左右,飲料 60–90 之間。而且還有很多一般的客人,很多去龍山寺拜拜的老先生老太太進來坐。感覺像是隨時一個人都可以進來坐的樣子。雖然沒有被叫主人,可是感覺說不定更輕鬆呢~

    + +

    珈琲.可思客的地址是臺北市和平西路三段 109 巷 3-2 號。嗯嗯,要記住。

    + +

    另外一家 Fatimaid ,我就沒去成了。 Fatimaid 在火車站北邊的台北地下街(不是火車站正下方的台北捷運地下街喔),實施徹底的前日預約制,所以我就被擋在門外了。我打電話去的時候,一開口就是主人,聲音很像答錄機,害我嚇一跳,差點忘了接話。不過我有繞到門口去看過,女僕穿的是傳統的英式女僕裝,店裏也有英式下午茶的感覺,還有不知道是什麼的女僕桌邊特別服務。說起來這說不定才是正統女僕路線。嗯嗯。

    + +

    不過說到台灣的女僕咖啡,應該還是要首推高雄的月讀咖啡吧。自己是高雄人,到現在還沒去過月讀。真想去月讀啊~真的該找一天,回去看看。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 139 | + 140 | + 141 | + 142 | + 143 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0142.html.en.html b/htdocs/imacat/me/diary/0142.html.en.html new file mode 120000 index 0000000..1a0ceda --- /dev/null +++ b/htdocs/imacat/me/diary/0142.html.en.html @@ -0,0 +1 @@ +0142.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0142.html.en.xhtml b/htdocs/imacat/me/diary/0142.html.en.xhtml new file mode 100644 index 0000000..4ddcef5 --- /dev/null +++ b/htdocs/imacat/me/diary/0142.html.en.xhtml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 142 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 142

    + +
    + +
    + +
    +
    1.30.’08. 6:47pm.
    + +

    賺於賠,得與失

    + +

    很久沒有記日記了。這之間,發生了很多事。不過因為留給自己的時間太少了,於是就一直無法靜心坐下來,把這一陣子發生的事,好好記下來。

    + +

    去年八月中,我投資基金太燥進,看反彈了就跟,結果連著大跌,幾天內申購又贖回的結果,一下子賠了兩萬。其實總體來算我還沒有賠,只是該次賠了兩萬,全部結算還是賺的。不過我吃了苦頭,抱定了決心,要看穩了才跟,長線持有。抱著這種想法,我等股市穩了兩個星期,九月初才申購,也下定決心,要持有六個月以上。

    + +

    去年十一月初,股市又從近萬點開始重創。不過我抱定了決心,要無視短線,所以一直忍著,對股市起落視而不見。忍了幾個星期,股市還是沒有好轉的跡象。加上整個成交量開始下滑,每天成交量從年平均一兆三千多億,下滑到九千多億。根據量跌表示市場走勢下滑的法則,我還是動搖了,終於在十一月底,下定決心停損贖回。這次是真的賠了,從前年年底開始買基金到現在合總結算,賠了兩萬多。

    + +

    不過這次,我對投資暫時死心了。之前股市就算爆跌,每天成交量還在一兆六千億上下,交易非常熱絡。可是現在每天只有九千億,買氣明顯下滑。我讀報紙財經版,每年年底聖誕節假期,外資會抽手,預備聖誕節消費,成交量都會下滑。翻看我的記錄,去年年底每天成交量的確也是一兆左右而已。搞不好現在成交量下滑是正常的。不過我不想冒這個險。聖誕節過後是農曆新年封關,封關前台灣投資人也會抽手,準備現金過年,到時候還會再跌。其實聖誕節也是西方人在過年。買基金不是買短線,兩個月內連著有兩個負面因素,怎麼說,至少也要熬到年後再說。

    + +

    而且,這次成交量下滑,讓我比較嚴肅地看待美國經濟不景氣的問題。美金作為全球貨幣準備,發行量太大,崩盤是遲早的事。要避免美金崩盤,聯準會必須要提高利率,把市場上的美金收回來,以維護美金幣值的穩定性。可是聯準會面對股市爆跌,根本不敢提高利率,還反而一再降低利率以求刺激景氣。這只是在飲鴆止渴,延後該來的景氣循環下滑,讓市場上美金更泛濫,美金幣值更危險。台灣的高科技產業,長期來看雖然營收還是很不錯,可是高科技業收的都是美金,美金崩盤,高科技產業必難倖免。就這點來看,台灣外貿依賴美元太深,除非美國經濟正常渡過景氣循環,真正從谷底回昇,否則都不是時機。

    + +

    換句話說,我覺得上一個景氣循環的上昇階段,差不多到底了。接下來是下滑階段,大概會這樣一路跌到五、六千點左右。對基金長線投資來說,除非下滑到谷底的五、六千點,否則都不是投資的時機。上次景氣下滑持續了兩年半,這次說不定也要熬這麼久。

    + +

    賠了錢,當然心痛。不過,不見得不是好事。

    + +

    其實,這一陣子手頭本來就一直很緊,有時候生活費,還是跟小招周轉的。其實這是很不對的。我有錢投資理財,卻沒有錢應付生活所需。這實在太奇怪了。贖回的時候,我還欠小招一萬多,欠我媽五千。投資理財的法則之一,不可以用可能用到的生活費投資,要用生活費的剩餘投資;投資理財法則之二,不可以借錢投資,要用儲蓄餘錢投資。我一手投資一手欠債,等於是借錢投資。一口氣違反了兩個法則,我這樣做,實在太不應該了。贖回了以後,一拿到現金,馬上開始清償負債,還清欠小招的 rinse 昇級費,還有欠我媽的 Wii 尾款。

    + +

    這兩筆都不是很多錢,還清了以後,手上還餘下不少。

    + +

    手上寬鬆了以後,想起我這幾年一直省吃儉用,有很多想做沒做的事、想買沒買的東西,就這樣放了好幾年。像做牙齒、做全身健康檢查、買一台好的不斷電系統,逛女僕咖啡店,買傘架,買衣服,化妝保養,很多很多。於是,我開始一點一點,依記憶開始列清單,一項一項去跑,去瞭解、比價、購買。

    + +

    開始了以後,才發現這些累積了多年的事,真的要做起來,比想像中還累、還複雜。就像不斷電系統。我要先去接觸不斷電系統的知識,了解不斷電系統有那些種類,選擇最適合自己價位和需求的產品,然後開始找有販賣該產品的商家、比價、下訂付款。買下來也不是結束,還有接下來接線、安裝、設定、維護的種種問題。其中也有像做牙齒一樣,花了兩、三個星期看了七、八家,然後決定還是不要做牙齒好了的。很多事,從事前準備到事後收拾,都要花到將近一個月。畢竟說手頭寬,也不是很多錢,隨便買隨便花,不知節制的話,一下子就花光光了。

    + +

    事前完全沒想到,花錢,也是很累的一件事。

    + +

    就這樣,為了花錢,一直忙到現在。為了花錢東奔西跑,也跑得累了,要買的東西也買得差不多了,只剩幾件而已。剩下的,應該可以好好存起來,準備下次景氣回昇時投資。今年大概沒辦法去考研究所,因為沒有時間唸書。事實上我也沒有報名。

    + +

    雖然賠了錢,卻意外給自己一個機會,可以買很多自己多年來想買沒買的東西,做很多自己想做未做的事,甚至還做了一些可以改變自己一輩子人生的事。可是結果還是為了花錢,忙到沒空唸書。跟人家說我最近在忙著花錢,大概會被當成搞笑吧。這到底是好事呢,還是不好的事呢?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 140 | + 141 | + 142 | + 143 | + 144 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0142.html.zh-cn.html b/htdocs/imacat/me/diary/0142.html.zh-cn.html new file mode 120000 index 0000000..65bdb0f --- /dev/null +++ b/htdocs/imacat/me/diary/0142.html.zh-cn.html @@ -0,0 +1 @@ +0142.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0142.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0142.html.zh-cn.xhtml new file mode 100644 index 0000000..79a8fce --- /dev/null +++ b/htdocs/imacat/me/diary/0142.html.zh-cn.xhtml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百四十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百四十二

    + +
    + +
    + +
    +
    1.30.’08. 6:47pm.
    + +

    赚於赔,得与失

    + +

    很久没有记日记了。这之间,发生了很多事。不过因为留给自己的时间太少了,於是就一直无法静心坐下来,把这一阵子发生的事,好好记下来。

    + +

    去年八月中,我投资基金太燥进,看反弹了就跟,结果连著大跌,几天内申购又赎回的结果,一下子赔了两万。其实总体来算我还没有赔,只是该次赔了两万,全部结算还是赚的。不过我吃了苦头,抱定了决心,要看稳了才跟,长线持有。抱著这种想法,我等股市稳了两个星期,九月初才申购,也下定决心,要持有六个月以上。

    + +

    去年十一月初,股市又从近万点开始重创。不过我抱定了决心,要无视短线,所以一直忍著,对股市起落视而不见。忍了几个星期,股市还是没有好转的迹象。加上整个成交量开始下滑,每天成交量从年平均一兆三千多亿,下滑到九千多亿。根据量跌表示市场走势下滑的法则,我还是动摇了,终於在十一月底,下定决心停损赎回。这次是真的赔了,从前年年底开始买基金到现在合总结算,赔了两万多。

    + +

    不过这次,我对投资暂时死心了。之前股市就算爆跌,每天成交量还在一兆六千亿上下,交易非常热络。可是现在每天只有九千亿,买气明显下滑。我读报纸财经版,每年年底圣诞节假期,外资会抽手,预备圣诞节消费,成交量都会下滑。翻看我的记录,去年年底每天成交量的确也是一兆左右而已。搞不好现在成交量下滑是正常的。不过我不想冒这个险。圣诞节过后是农历新年封关,封关前台湾投资人也会抽手,准备现金过年,到时候还会再跌。其实圣诞节也是西方人在过年。买基金不是买短线,两个月内连著有两个负面因素,怎么说,至少也要熬到年后再说。

    + +

    而且,这次成交量下滑,让我比较严肃地看待美国经济不景气的问题。美金作为全球货币准备,发行量太大,崩盘是迟早的事。要避免美金崩盘,联准会必须要提高利率,把市场上的美金收回来,以维护美金币值的稳定性。可是联准会面对股市爆跌,根本不敢提高利率,还反而一再降低利率以求刺激景气。这只是在饮鸩止渴,延后该来的景气循环下滑,让市场上美金更泛滥,美金币值更危险。台湾的高科技产业,长期来看虽然营收还是很不错,可是高科技业收的都是美金,美金崩盘,高科技产业必难幸免。就这点来看,台湾外贸依赖美元太深,除非美国经济正常渡过景气循环,真正从谷底回升,否则都不是时机。

    + +

    换句话说,我觉得上一个景气循环的上升阶段,差不多到底了。接下来是下滑阶段,大概会这样一路跌到五、六千点左右。对基金长线投资来说,除非下滑到谷底的五、六千点,否则都不是投资的时机。上次景气下滑持续了两年半,这次说不定也要熬这么久。

    + +

    赔了钱,当然心痛。不过,不见得不是好事。

    + +

    其实,这一阵子手头本来就一直很紧,有时候生活费,还是跟小招周转的。其实这是很不对的。我有钱投资理财,却没有钱应付生活所需。这实在太奇怪了。赎回的时候,我还欠小招一万多,欠我妈五千。投资理财的法则之一,不可以用可能用到的生活费投资,要用生活费的剩余投资;投资理财法则之二,不可以借钱投资,要用储蓄余钱投资。我一手投资一手欠债,等於是借钱投资。一口气违反了两个法则,我这样做,实在太不应该了。赎回了以后,一拿到现金,马上开始清偿负债,还清欠小招的 rinse 升级费,还有欠我妈的 Wii 尾款。

    + +

    这两笔都不是很多钱,还清了以后,手上还余下不少。

    + +

    手上宽松了以后,想起我这几年一直省吃俭用,有很多想做没做的事、想买没买的东西,就这样放了好几年。像做牙齿、做全身健康检查、买一台好的不断电系统,逛女仆咖啡店,买伞架,买衣服,化妆保养,很多很多。於是,我开始一点一点,依记忆开始列清单,一项一项去跑,去了解、比价、购买。

    + +

    开始了以后,才发现这些累积了多年的事,真的要做起来,比想像中还累、还复杂。就像不断电系统。我要先去接触不断电系统的知识,了解不断电系统有那些种类,选择最适合自己价位和需求的产品,然后开始找有贩卖该产品的商家、比价、下订付款。买下来也不是结束,还有接下来接线、安装、设定、维护的种种问题。其中也有像做牙齿一样,花了两、三个星期看了七、八家,然后决定还是不要做牙齿好了的。很多事,从事前准备到事后收拾,都要花到将近一个月。毕竟说手头宽,也不是很多钱,随便买随便花,不知节制的话,一下子就花光光了。

    + +

    事前完全没想到,花钱,也是很累的一件事。

    + +

    就这样,为了花钱,一直忙到现在。为了花钱东奔西跑,也跑得累了,要买的东西也买得差不多了,只剩几件而已。剩下的,应该可以好好存起来,准备下次景气回升时投资。今年大概没办法去考研究所,因为没有时间念书。事实上我也没有报名。

    + +

    虽然赔了钱,却意外给自己一个机会,可以买很多自己多年来想买没买的东西,做很多自己想做未做的事,甚至还做了一些可以改变自己一辈子人生的事。可是结果还是为了花钱,忙到没空念书。跟人家说我最近在忙著花钱,大概会被当成搞笑吧。这到底是好事呢,还是不好的事呢?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 140 | + 141 | + 142 | + 143 | + 144 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0142.html.zh-tw.html b/htdocs/imacat/me/diary/0142.html.zh-tw.html new file mode 120000 index 0000000..3aadc68 --- /dev/null +++ b/htdocs/imacat/me/diary/0142.html.zh-tw.html @@ -0,0 +1 @@ +0142.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0142.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0142.html.zh-tw.xhtml new file mode 100644 index 0000000..9f1f586 --- /dev/null +++ b/htdocs/imacat/me/diary/0142.html.zh-tw.xhtml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百四十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百四十二

    + +
    + +
    + +
    +
    1.30.’08. 6:47pm.
    + +

    賺於賠,得與失

    + +

    很久沒有記日記了。這之間,發生了很多事。不過因為留給自己的時間太少了,於是就一直無法靜心坐下來,把這一陣子發生的事,好好記下來。

    + +

    去年八月中,我投資基金太燥進,看反彈了就跟,結果連著大跌,幾天內申購又贖回的結果,一下子賠了兩萬。其實總體來算我還沒有賠,只是該次賠了兩萬,全部結算還是賺的。不過我吃了苦頭,抱定了決心,要看穩了才跟,長線持有。抱著這種想法,我等股市穩了兩個星期,九月初才申購,也下定決心,要持有六個月以上。

    + +

    去年十一月初,股市又從近萬點開始重創。不過我抱定了決心,要無視短線,所以一直忍著,對股市起落視而不見。忍了幾個星期,股市還是沒有好轉的跡象。加上整個成交量開始下滑,每天成交量從年平均一兆三千多億,下滑到九千多億。根據量跌表示市場走勢下滑的法則,我還是動搖了,終於在十一月底,下定決心停損贖回。這次是真的賠了,從前年年底開始買基金到現在合總結算,賠了兩萬多。

    + +

    不過這次,我對投資暫時死心了。之前股市就算爆跌,每天成交量還在一兆六千億上下,交易非常熱絡。可是現在每天只有九千億,買氣明顯下滑。我讀報紙財經版,每年年底聖誕節假期,外資會抽手,預備聖誕節消費,成交量都會下滑。翻看我的記錄,去年年底每天成交量的確也是一兆左右而已。搞不好現在成交量下滑是正常的。不過我不想冒這個險。聖誕節過後是農曆新年封關,封關前台灣投資人也會抽手,準備現金過年,到時候還會再跌。其實聖誕節也是西方人在過年。買基金不是買短線,兩個月內連著有兩個負面因素,怎麼說,至少也要熬到年後再說。

    + +

    而且,這次成交量下滑,讓我比較嚴肅地看待美國經濟不景氣的問題。美金作為全球貨幣準備,發行量太大,崩盤是遲早的事。要避免美金崩盤,聯準會必須要提高利率,把市場上的美金收回來,以維護美金幣值的穩定性。可是聯準會面對股市爆跌,根本不敢提高利率,還反而一再降低利率以求刺激景氣。這只是在飲鴆止渴,延後該來的景氣循環下滑,讓市場上美金更泛濫,美金幣值更危險。台灣的高科技產業,長期來看雖然營收還是很不錯,可是高科技業收的都是美金,美金崩盤,高科技產業必難倖免。就這點來看,台灣外貿依賴美元太深,除非美國經濟正常渡過景氣循環,真正從谷底回昇,否則都不是時機。

    + +

    換句話說,我覺得上一個景氣循環的上昇階段,差不多到底了。接下來是下滑階段,大概會這樣一路跌到五、六千點左右。對基金長線投資來說,除非下滑到谷底的五、六千點,否則都不是投資的時機。上次景氣下滑持續了兩年半,這次說不定也要熬這麼久。

    + +

    賠了錢,當然心痛。不過,不見得不是好事。

    + +

    其實,這一陣子手頭本來就一直很緊,有時候生活費,還是跟小招周轉的。其實這是很不對的。我有錢投資理財,卻沒有錢應付生活所需。這實在太奇怪了。贖回的時候,我還欠小招一萬多,欠我媽五千。投資理財的法則之一,不可以用可能用到的生活費投資,要用生活費的剩餘投資;投資理財法則之二,不可以借錢投資,要用儲蓄餘錢投資。我一手投資一手欠債,等於是借錢投資。一口氣違反了兩個法則,我這樣做,實在太不應該了。贖回了以後,一拿到現金,馬上開始清償負債,還清欠小招的 rinse 昇級費,還有欠我媽的 Wii 尾款。

    + +

    這兩筆都不是很多錢,還清了以後,手上還餘下不少。

    + +

    手上寬鬆了以後,想起我這幾年一直省吃儉用,有很多想做沒做的事、想買沒買的東西,就這樣放了好幾年。像做牙齒、做全身健康檢查、買一台好的不斷電系統,逛女僕咖啡店,買傘架,買衣服,化妝保養,很多很多。於是,我開始一點一點,依記憶開始列清單,一項一項去跑,去瞭解、比價、購買。

    + +

    開始了以後,才發現這些累積了多年的事,真的要做起來,比想像中還累、還複雜。就像不斷電系統。我要先去接觸不斷電系統的知識,了解不斷電系統有那些種類,選擇最適合自己價位和需求的產品,然後開始找有販賣該產品的商家、比價、下訂付款。買下來也不是結束,還有接下來接線、安裝、設定、維護的種種問題。其中也有像做牙齒一樣,花了兩、三個星期看了七、八家,然後決定還是不要做牙齒好了的。很多事,從事前準備到事後收拾,都要花到將近一個月。畢竟說手頭寬,也不是很多錢,隨便買隨便花,不知節制的話,一下子就花光光了。

    + +

    事前完全沒想到,花錢,也是很累的一件事。

    + +

    就這樣,為了花錢,一直忙到現在。為了花錢東奔西跑,也跑得累了,要買的東西也買得差不多了,只剩幾件而已。剩下的,應該可以好好存起來,準備下次景氣回昇時投資。今年大概沒辦法去考研究所,因為沒有時間唸書。事實上我也沒有報名。

    + +

    雖然賠了錢,卻意外給自己一個機會,可以買很多自己多年來想買沒買的東西,做很多自己想做未做的事,甚至還做了一些可以改變自己一輩子人生的事。可是結果還是為了花錢,忙到沒空唸書。跟人家說我最近在忙著花錢,大概會被當成搞笑吧。這到底是好事呢,還是不好的事呢?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 140 | + 141 | + 142 | + 143 | + 144 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0143.html.en.html b/htdocs/imacat/me/diary/0143.html.en.html new file mode 120000 index 0000000..c8155ce --- /dev/null +++ b/htdocs/imacat/me/diary/0143.html.en.html @@ -0,0 +1 @@ +0143.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0143.html.en.xhtml b/htdocs/imacat/me/diary/0143.html.en.xhtml new file mode 100644 index 0000000..2afea37 --- /dev/null +++ b/htdocs/imacat/me/diary/0143.html.en.xhtml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 143 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 143

    + +
    + +
    + +
    +
    1.31.’08. 2:24am.
    + +

    肯德基長江七號掛飾

    + +
    +肯德基長江七號活力掛飾 +

    肯德基長江七號活力掛飾

    +
    + +
    +肯德基長江七號歡樂掛飾 +

    肯德基長江七號歡樂掛飾

    +
    + +
    +肯德基長江七號乖乖掛飾 +

    肯德基長江七號乖乖掛飾

    +
    + +
    +肯德基長江七號開心掛飾 +

    肯德基長江七號開心掛飾

    +
    + +
    +肯德基長江七號四款掛飾大集合 +

    肯德基長江七號四款掛飾大集合

    +
    + +

    我真是瘋了。竟然為了這種事,三天內連吃了四餐肯德基,還趕在 1/31 長江七號上映前,集齊四款長江七號掛飾。

    + +

    不過算了,誰叫小招喜歡長江七號呢?長江七號不是我喜歡的類型啦,不過小招喜歡,我也沒辦法呢~ ^_*'

    + +

    四款的名稱,是按照外包塑膠袋上印的名稱。仔細看起來,四款掛飾其實沒有太大的差別。想想,肯德基在這一點上也真的是蠻賤的。 :p

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 141 | + 142 | + 143 | + 144 | + 145 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0143.html.zh-cn.html b/htdocs/imacat/me/diary/0143.html.zh-cn.html new file mode 120000 index 0000000..e40c01d --- /dev/null +++ b/htdocs/imacat/me/diary/0143.html.zh-cn.html @@ -0,0 +1 @@ +0143.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0143.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0143.html.zh-cn.xhtml new file mode 100644 index 0000000..084d7a6 --- /dev/null +++ b/htdocs/imacat/me/diary/0143.html.zh-cn.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百四十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百四十三

    + +
    + +
    + +
    +
    1.31.’08. 2:24am.
    + +

    肯德基长江七号挂饰

    + +
    +肯德基长江七号活力挂饰 +

    肯德基长江七号活力挂饰

    +
    + +
    +肯德基长江七号欢乐挂饰 +

    肯德基长江七号欢乐挂饰

    +
    + +
    +肯德基长江七号乖乖挂饰 +

    肯德基长江七号乖乖挂饰

    +
    + +
    +肯德基长江七号开心挂饰 +

    肯德基长江七号开心挂饰

    +
    + +
    +肯德基长江七号四款挂饰大集合 +

    肯德基长江七号四款挂饰大集合

    +
    + +

    我真是疯了。竟然为了这种事,三天内连吃了四餐肯德基,还赶在 1/31 长江七号上映前,集齐四款长江七号挂饰。

    + +

    不过算了,谁叫小招喜欢长江七号呢?长江七号不是我喜欢的类型啦,不过小招喜欢,我也没办法呢~ ^_*'

    + +

    四款的名称,是按照外包塑胶袋上印的名称。仔细看起来,四款挂饰其实没有太大的差别。想想,肯德基在这一点上也真的是蛮贱的。 :p

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 141 | + 142 | + 143 | + 144 | + 145 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0143.html.zh-tw.html b/htdocs/imacat/me/diary/0143.html.zh-tw.html new file mode 120000 index 0000000..8fbeb9d --- /dev/null +++ b/htdocs/imacat/me/diary/0143.html.zh-tw.html @@ -0,0 +1 @@ +0143.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0143.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0143.html.zh-tw.xhtml new file mode 100644 index 0000000..0471e56 --- /dev/null +++ b/htdocs/imacat/me/diary/0143.html.zh-tw.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百四十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百四十三

    + +
    + +
    + +
    +
    1.31.’08. 2:24am.
    + +

    肯德基長江七號掛飾

    + +
    +肯德基長江七號活力掛飾 +

    肯德基長江七號活力掛飾

    +
    + +
    +肯德基長江七號歡樂掛飾 +

    肯德基長江七號歡樂掛飾

    +
    + +
    +肯德基長江七號乖乖掛飾 +

    肯德基長江七號乖乖掛飾

    +
    + +
    +肯德基長江七號開心掛飾 +

    肯德基長江七號開心掛飾

    +
    + +
    +肯德基長江七號四款掛飾大集合 +

    肯德基長江七號四款掛飾大集合

    +
    + +

    我真是瘋了。竟然為了這種事,三天內連吃了四餐肯德基,還趕在 1/31 長江七號上映前,集齊四款長江七號掛飾。

    + +

    不過算了,誰叫小招喜歡長江七號呢?長江七號不是我喜歡的類型啦,不過小招喜歡,我也沒辦法呢~ ^_*'

    + +

    四款的名稱,是按照外包塑膠袋上印的名稱。仔細看起來,四款掛飾其實沒有太大的差別。想想,肯德基在這一點上也真的是蠻賤的。 :p

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 141 | + 142 | + 143 | + 144 | + 145 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0144.html.en.html b/htdocs/imacat/me/diary/0144.html.en.html new file mode 120000 index 0000000..b867cda --- /dev/null +++ b/htdocs/imacat/me/diary/0144.html.en.html @@ -0,0 +1 @@ +0144.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0144.html.en.xhtml b/htdocs/imacat/me/diary/0144.html.en.xhtml new file mode 100644 index 0000000..565e3d5 --- /dev/null +++ b/htdocs/imacat/me/diary/0144.html.en.xhtml @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 144 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 144

    + +
    + +
    + +
    +
    1.31.’08. 6:45pm.
    + +

    UPS 不斷電系統

    + +

    我的第一台 UPS ,大約是在 2000 年左右買的。那時候因應我的座位下有 rinse 和 cotton 兩台電腦,小招的座位下有一台,所以買了一台飛瑞 A-1000 給我自己用,一台飛瑞 A-500 給小招用。

    + +

    那時候我不是很懂 UPS 。我唯一知道的,是在公司看到公司用的美商艾比希 APCSmart-UPS 3000VA (SU3000NET) ,用了至少十年以上。不過聽老闆說那一台很貴,花了十幾萬,所以只能流口水。真的要買,還是只能買光華商場買得到的台灣品牌飛瑞,一台兩千的 A-1000 和一台一千的 A-500 廉價 UPS

    + +

    那時候我不是很懂。 rinse 裝的是 Linux ,飛瑞附的監控程式完全派不上用場。而且飛瑞的面板只有一個指示燈,出了問題,還要翻出說明書來看才看得懂它在閃什麼。所以 UPS 接上去以後,就只能聽它嗶嗶嗶地叫,也不知道在幹嘛。停電時會嗶嗶叫幾聲,讓我好好關機,電來了不久,嗶嗶聲就消失了。不過沒停電時,偶爾也會一直嗶嗶地叫,不知道在叫什麼。到後來,整晚嗶嗶嗶嗶地叫個不停,也查不出什麼原因。我實在受不了了,乾脆拔掉 UPS ,直接接插座。不管怎樣,也比被吵得整晚睡不著的好。

    + +

    那時候我就發誓,我下一台 UPS ,哪怕貴一點,絕對絕對不要買飛瑞的。

    + +

    不過因為手上沒有錢,就這樣拖了好幾年過去了。這之間也查過好幾次 APC UPS 的價格,知道依我的需要,其實不需要十幾萬。不過還是要好幾萬,我還是買不起。

    + +

    前年 2006 年,家裏陸陸續續斷電好幾次,台電供電不穩,越來越嚴重。直到去年過年回高雄,突然連不上台北家裏的網路,我以為又是斷電了,台北家裏沒人可以幫忙重開機,我自己一時間也無法馬上回台北處理,心急無焚。後來知道不是斷電,只是中華電信網路斷訊,過了兩天就好了,才鬆了一口氣。不過沒有 UPS 保護的網路,我不在時完全沒辦法,我已經開始感到不安了。直到三月多,一次春雷雷擊,家裏兩台電腦就這樣壞了,緊急買新硬碟、主機板來換。還好資料還抓得出來,沒有損失資料。不過硬體損壞的費用,還是讓我損失慘重。對一台好的 UPS 的需求,也越來越強烈。

    + +

    公司定期都會收到贈閱的 DigiTimes 電子時報。去年 11 月, DigiTimes 電子時報 企業 IT 週報 出了一集專題UPS 採購指南。我一直想多瞭解 UPS ,作為購買的參考,也可以協助日常工作。公司那台 APC Smart-UPS 3000VA 其實我也一直都不大懂,一直想多作瞭解。所以平日隨便看兩頁 DigiTimes 電子時報就送回收的我,特地把那期留下來,把那篇仔細讀完。

    + +

    讀了以後,我才知道主要有三種 UPS :離線式 (standby) ,在線互動式 (line interactive) ,在線式 (on-line) 。以價錢來說,離線式最便宜,在線互動式中等,在線式最貴;以供電保護能力來說,離線式最差,在線互動式稍好一點,只有在線式有完整的保護。不過在線式的太貴了。在線互動式的其實也是離線式的,由市電切到電池中間還是有很短的時間間隔,不過其電路輸出時一律經過電壓轉換,可以保護市電的突波。在線式的保護最完整,電力完全由電池供應,市電直接輸入電池,不管有沒有市電都不影響供電。不過閱讀了 APC 網站上的白皮書一號 The Different Types of UPS Systems ,我才知道,在線式 UPS 平時電力要先轉直流進電池再轉交流輸出,這個轉入轉出過程電力損耗很大,使得在線式 UPS 本身就很耗電。考慮至少要有突波保護,以防範雷擊,並考慮經濟效益及省電的前題下,我鎖定在線互動式 UPS ,作為目標。

    + +

    去年年底基金贖回,手上多了一筆現金,就開始著手購買 UPS 的事。原則上我想買 APCUPSAPCUPS 的第一大品牌,公司的 UPS 我雖然不大懂,但在我之前用了快十年,我進公司後又用了快十年,比起不知道發生什麼事就壞掉了的飛瑞來說,非常穩定。 APC 的網站上有一個非常棒的功能:UPS 選擇器,輸入自己的電腦配備,程式會估計電腦大約的耗電瓦數,然後推薦合用的 UPS 。我用 UPS 選擇器計算過,才知道我的電腦耗電量大約只有一、兩百瓦而已,三台電腦加起來只有 500 瓦。加上預留的瓦數, 800 瓦以上的一定夠用。其實一般的電腦, 250 瓦的電源供應器就夠用了,考慮日後擴充,及電源供應器可能偷工減料不足瓦,頂多買 300 瓦。平常光華商場組裝時,估到電源供應器,店員每每說需要 350 瓦才夠,根本是多餘的。

    + +

    用了 APCUPS 選擇器估算,依其推薦,我鎖定了在線互動式的 APC Smart-UPS 1500VA (SUA1500) ,最大輸出一千瓦,備援時間十分鐘。

    + +

    鎖定了型號,我開始找有誰有賣。我知道光華商場大概買不到。光華商場其實東西很少,因為競爭激烈,大家都在減少庫存,店家只會賣好賣的東西,高檔的、貴的,像 APCUPS ,光華商場往往很難找得到。可是光這樣,我也還是不知道有誰有賣。我又不能上班時間打電話去 APC 問。我只好試著上 Yahoo! 奇摩拍賣找。沒想到真的有人在 Yahoo! 奇摩拍賣上賣 APC Smart-UPS 1500VA (SUA1500) ,還有其它網路電腦商城也有人在賣。不過價格落差很大,從一萬八、一萬三到九千都有人賣。價格落差這麼大,我也嚇了一大跳。依據看報紙社會版的經驗,網路售價太便宜的,貨源可能有問題,搞不好是贓物之類的。於是我先把獨賣九千的那一家劃掉,然後去找一萬三的那兩家。

    + +

    一萬三的那兩家,一家是純網路商城,我不大敢買。另一家則自稱是 3CeGo 網,在光華商場有實體店面,在光華商場做了二十年了,買了的話是去光華商場取貨。有實體店面,我當然比較放心,光華商場我還蠻常走動,雖然不敢說全部店家都背得出來,但很多店只要給我店名,我也知道是在哪一家。不過有一、兩家店之前弄得很不愉快,不怎麼想踏進去。 3CeGo 網是怎麼樣都不肯透露是哪一家,寫信過去也沒有回,我也不知道該怎麼辦。我可不想下訂了以後,到了店面取貨才發現不想走進去,到時候就麻煩了。一愁莫展之際,我試著在網路上找3CeGo,沒想到真的被我找到了。原來是紐頓。光華商場的紐頓我就知道了,常常去買。如果真的是紐頓,那我可以放心了。我寫信去紐頓問,客服人員回答說 Yahoo! 奇摩拍賣上的 3CeGo 網的確就是他們,不過因 Yahoo! 奇摩拍賣的規定,他們不能說。我不知道有什麼不能說實體店名的奇怪規定,我不賣東西也不開店,所以不瞭解。不過如果是紐頓,應該沒有問題。

    + +

    可是一萬三和九千相比,畢竟差了四千。四千塊錢是很多錢。 UPS 是一用就要用十年的東西,就算買二手的也值得。如果九千塊錢的貨源沒有問題,不是贓物,還是應該能省則省。雖然很可疑,我還是去調查看看。

    + +

    九千的這一個,不知道為什麼,上面還加上 DELL OEM 。我不知道那是什麼。不過如果只是上面印上 Dell 的標誌, APC 還是一樣保固的話,我倒沒有意見。那家公司叫做自由度網路科技,公司在高雄,我從來沒聽過。我很久沒回高雄了,沒聽過也是正常的。網路上找一找,它似乎還是微軟經銷商,在 Yahoo! 奇摩上賣三年了,電話地址都是同一家,應該是正派的公司。可是我不是沒待過賣場,正常電腦產品的利潤哪可以壓到三成以上?九千塊的價格怎麼看都不大正派。打電話去問,他說是跟戴爾電腦拿貨的,所以叫 DELL OEM 。不過上面不會有 Dell 的標誌。因為戴爾電腦給他們的價格很優,所以他們才能便宜賣。出貨時,會由戴爾直接出貨,所以不用另加運費。戴爾,嗯。沒關係,我再寫信去戴爾問,看自由度是不是他們的經銷商。感覺上自由度應該不是騙人的公司,加上電話中聊得蠻愉快的,所以我還是先在 Yahoo! 奇摩拍賣上下訂了,等戴爾確認經銷商身份沒問題,再匯款好了。

    + +

    沒想到,接下來,才是故事的開始。

    + +

    寫信給戴爾詢問自由度的經銷商身份時,已經是傍晚準備下班了。我寄出去後,收拾一下就下班了。晚上回家收信,一口氣收到三封來自三個不同的客服人員的不在座位自動回函。我覺得好氣又好笑,像這種網站詢問,如果有一組人一起處理,就不需要每個人都自動回函了吧。隔天早上,接到了戴爾的電話。跟電話對方的客服小姐解釋以後,沒想到她問了我一句:

    + +
    +妳怎麼不直接跟戴爾買呢? +
    + +

    唔…嗯…可是我之前不知道戴爾還有代銷別人的產品啊…

    + +
    +那妳要不要直接跟戴爾買?我可以給妳更優惠的價格。 +
    + +

    啊?唔…嗯…可是我已經下訂了。如果沒有問題的話,我一定要跟他們買。做生意講究誠信,這是買家的信用問題。

    + +

    不,不對,我的問題不是這個吧。我只是要問自由度是不是戴爾的經銷商而已,難道妳們連這點都查不出來嗎?更何況,哪有人跟自己的經銷商搶生意的啊?

    + +

    客服小姐明白了以後,問我自由度網路科技的電話,她願意幫我協調。可能是我給錯名字了吧,下午回電話時,她說她找不到那個人。她再次問我,真的不考慮直接跟戴爾買嗎?她可以給我更優惠的價格。

    + +

    不好意思,我在 Yahoo! 奇摩拍賣上很少買賣東西,評價很少,一個負評都承受不起。更何況,貪個一兩千塊,破壞自己辛苦建立的信用,是很划不來的事。不過,難道戴爾沒辦法在自己的經銷商名單上確認嗎?

    + +

    我這樣問,她才不好意思地告訴我,戴爾沒有經銷商名單。原來如此。戴爾是世界有名的電腦直銷商,以前從不做經銷商的,以直銷壓低價格。去年因為業績滑落,換了新的執行長,才開始改變經營模式,做經銷商。不過看來戴爾很沒有經營經銷商的概念,所謂經銷商也不過就是大量進貨壓低價格的客戶而已,所以也沒有特別建立經銷商名單,而且還會跟經銷商搶生意。所以戴爾不像一般電腦品牌一樣,我去查經銷商,也查不到。

    + +

    不過戴爾可以給我更優惠的價格,那表示自由度開九千塊錢,還是有利潤的。既然有正常利潤,自由度看樣子是正派的公司,我也就比較放心了。婉拒了戴爾客服小姐的好意後,下午吃飯時就去匯錢,跟自由度確認,等戴爾把 UPS 寄過來了。

    + +

    一個禮拜後,我的電話響了。是貨運公司,跟我確認送貨地址。電話那頭給我一個汐止的地址,我跟對方更正為公館的地址。

    + +

    過兩天元旦過後,貨運公司送來了。長型的盒子,有點出乎我意料之外。不過東西送來了,確定不是詐騙,我也安了心。簽收了以後,一拆開來看,傻眼了:這,這是鍵盤吧?為什麼?難道訂單弄錯了嗎?不會就是前天弄錯汐止地址的那件事吧?難道說我把人家正確的汐止地址更正成錯了的嗎?要送到汐止的鍵盤送到這裏來,那我的 UPS 不會送到汐止去了吧!天哪,我已經等了一個星期了,再從汐止搬回來再送過來,還要我等多久?我趕緊打電話去戴爾、去自由度問,戴爾說要我找自由度。也對,我不是戴爾的客戶,自由度才是戴爾的客戶。電話中,自由度那邊也傻眼了,一直跟我道歉。我還是很不安。隔天,貨運公司打電話來,又要確認送貨地址。這次我不敢大意了,先確認收件人名字,確認貨品是不是 APC UPS ,才請他送過來。送過來後,貨運公司說要拿走之前送錯的鍵盤,我也先跟自由度確認過,才把鍵盤交給他。

    + +

    還好,只有汐止的鍵盤送來這裏,我的 UPS 沒有送去汐止,是單向的送錯。仔細看看我簽收的戴爾出貨單,上面收件人地址在汐止,名字不是我的名字,連電話都不是我的電話。唔,那表示到戴爾這一端,出貨單都沒有問題。那為什麼打電話給我,確認送貨地址呢?看樣子是貨運公司看錯電話搞的烏龍。我沒有實際受害。不知道汐止的受害者是誰,唉。

    + +

    Yahoo! 奇摩拍賣評價時,我考慮了一下。雖然不是自由度的錯,也不是戴爾的錯,我也沒有實際受害。不過這種事還是蠻可怕的。這次是汐止的某人受害,搞不好下一次就是我了。自由度賣的東西,整個過程還是要負連帶責任。所以還是寫了一個普通的評價,並且把事情寫清楚。

    + +

    UPS 真的很重。裏面有一顆很大顆的密封鉛酸電池,電池這種東西真的重得不得了。好不容易搬回家,盤算了一下配線怎麼調整後,把舊的兩台飛瑞 UPS 撤掉,把新買的接上去。我再買了一個多孔插座延長線,延長到小招的電腦旁邊,把小招的電腦也一起接過來。 APC 果然不愧是 UPS 老字號第一品牌,不像飛瑞 A-1000/A-500 只有一個指示燈, APC UPS 上面兩三排指示燈,加上旁邊清楚的圖示, UPS 狀況一目瞭然,才不會重蹈覆轍。

    + +

    不過光接上去還不夠。 UPS 還要管理,不然用處不大,就跟以前那台飛瑞差不多了。 APC 有附一套 PowerChute UPS 管理軟體,還有 Linux 版,不過 Linux 版是執行檔,沒有原始程式可自行編譯,所以大概只支援(不是我用的)某某版本的 Linux ,日後系統更新可能就掛了,而且大概還要 X-Windows 在視窗下執行。我試著看 Linux HOWTO 教學,發現了一篇 UPS HOWTO (不斷電系統教學) ,高興地趕快翻出來讀。

    + +

    這篇 UPS HOWTO (不斷電系統教學) ,寫得非常詳盡。我不是學電機的,專長是電腦軟體程式,不是電力配線。我是用手指頭敲鍵盤的師傅,對於鍵盤敲敲打打以外的事真的一知半解。這篇教學針對的是小家庭或小型辦公室,只有幾台個人電腦,使用在線互動式 UPS 的環境,先從家用電力的問題開始說明起,從斷電器、突波保護器到 UPS 所能保護的範圍。接上 UPS 以後的管理,它提到了兩個自由軟體專案:一個是各品牌通用的 UPS 管理程式 Network UPS Tools ,一個是專為 APC UPS 開發的 apcupsd 。一般如果是 APCUPS ,用 apcupsd 就好了; APC 以外的 UPS ,就用 Network UPS Tools

    + +

    看到這裏,我真的很高興。趕快順著這條線索,用 APT 安裝了 apcupsd 。裝起來了以後,發現真的超酷的。接好線後,直接從虛擬終端機就可以看到 UPS 的現況,包括目前負載、目前市電電壓、電池存量、預計可用時間、電池好壞等等,全部一目瞭然。如果用電腦跑比較大的程式, CPU 忙起來,也可以看得到電力負載馬上上昇,預計可用時間也會因而下降。而且所有發生的市電事件,斷電、電壓不足、電池損壞等,也都會記錄到 Syslog 裏,可以隨時追溯監控市電的品質。

    + +

    原來家裏平常的負載,只有 20%–25% 左右,就算加小招的電腦,三台電腦全開,頂多到 40% 。以 APC Smart-UPS 1500VA (SUA1500) 最大負載 980 瓦來說,頂多 400 瓦,一台電腦只有一百多瓦。我卻都買了 350 瓦的電源供應器,買新電腦時,還常常被店員說可能不夠用,想想還真的有點好笑。

    + +

    可是光知道 UPS 的狀況,當然不夠。更重要的,是斷電時,人不在電腦旁時的自動處理。而且電池壽命用盡時,也必需要通知我去更換電池。仔細研究了一下,發現 apcupsd 不只可以隨時監控電力狀況,還可以設定在電力不足,只剩幾分鐘可用時,自動關機。而且 apcupsd 還可以透過網路分享 UPS 的電力資訊。 UPS 監控線接到一台主機,其它主機就由那台主機取得 UPS 的電力數值,以各自關機。這樣一來,只要 UPS 接到一台主機,其它主機就可以跟著動作,實現小型網路的電力管理了。而且 apcupsd 還有 Windows 版,也就是說, Windows 電腦也可以分享 UPS 的電力資訊,跟著自行關機。這真的是超酷的~

    + +

    不過關機後市電恢復,人不在電腦旁邊時,要有人去按開關開機,是另一件讓人頭大的事。這點 UPS HOWTO (不斷電系統教學) 也有提及。我讀了以後才知道,其實現代電腦的 BIOS 裏,都內建有斷電後,電力恢復時自動重開機的功能,不過這個功能預設是關閉的。我以前一直不知道這個功能,趕緊重開機看 BIOS 設定,果然有一個 Restore on AC/Power Loss 的選項,裏面有三種模式: Last StatePower OnPower Off ,預設是 Power Off 。只要改成 Power On ,就可以了。設定好了以後稍為實驗一下,直接拔掉電線,過一會兒再重開,果然自己重開機了。我以前都跟人家說斷電後自動重開機是不可能的,一定是記錯了之類的話,看來我一直都說錯了。

    + +

    這樣,我真的可以回家一、兩個星期,也不用擔心。就算斷電關機,電來了也會自己開機,斷電造成的服務中斷時間可以縮到最短,就算無人在家也可以自行管理。

    + +

    再仔細研究一下,我發現 apcupsd 不只能做到電力自行管理。在像斷電關機這種重要事件時, apcupsd 還會發信通知。所以人不在電腦旁邊的時候,因為斷電自動關機開機,網管也都會清楚得知。會通知的還包括: UPS 斷訊、電池損壞待修等等重大事件。幾乎所有網管需要知道、處理的重大事情,都會發信通知。這樣就不怕像之前那樣, UPS 壞得不明不白了。

    + +

    尤有甚者, apcupsd 還有好幾隻 CGI 程式,可以由網頁瀏覽監控,也就是說,網管從任何地方,即使是出國旅遊無法連線虛擬終端機,也都可以隨時遠端監看包括像目前市電電壓、 UPS 負載、電池電量、剩餘時間等等。

    + +

    這真的是太酷了。幾乎我所有想得到的需求, apcupsd 都可以辦得到。我已經想不到什麼問題了。我不知道 Network UPS Tools 能不能做到這些。不過到這裏我覺得,能夠買 APCUPS ,實在是太幸福了。果然是世界第一品牌啊~雖然九千五確實很貴,但是很值得。

    + +

    不過 Debianapcupsd 套件需要安裝 libsnmp ,會跟我自己安裝的 Net-SNMP 相衝。其實我只有一台用序列埠線管理的 UPS ,沒有用網路 SNMPUPS ,編譯的時候根本不需要連結 SNMP 函式庫。所以我還是捨棄了 Debianapcupsd 套件,移除以後,自己下載原始碼來編譯、安裝。

    + +

    自行編譯的時候,我發現 apcupsdDebian 上編譯時,連接埠自動由 3551 改用 6543 。我不是很瞭解,上網查了一下,發現以前 Debian 確實是用連接埠 6543 跑 apcupsd 。不過這已經是很久以前的事了,在 apcupsd 正式向 IANA 註冊到了連接埠 3551 後, 2004 年有人在 Debian 上提出修正,也已經修正好了。我也寫了一個簡單的修補傳上 apcupsd-users 通訊,取消掉 Debian 自動設定連接簿 6543 。下一版 apcupsd 應該會修正好吧。

    + +

    我自己也寫了一個簡單的程式,取得電壓和負載,給 MRTG 定期搜集、監控、繪圖,以取得長期的電壓和負載變化。

    + +

    安裝了新的 UPS ,並得以監控後,我才知道,家裏的市電真的很不穩定,常常有一、兩秒的瞬斷。只是因為時間很短馬上就恢復,電腦沒有因而斷訊,所以沒有察覺。嚴重時甚至一天兩、三次。電壓也不穩定,常常掉到 105 伏特以下,讓 UPS 切為電池供電穩壓。其實台灣的市電應該是 110 伏特,美國的市電是 120 伏特, APCUPS 也是以 120 伏特電力輸出設計的,中間其實差了 10 伏特。對 120 伏特而言,電力掉到 105 伏特以下等於掉了 15 伏特,的確已經是低電壓的異常狀態了。可是對 110 伏特而言, 105 伏特只掉了 5 伏特,其實還算正常起伏。為避免 UPS 穩壓切得太頻繁,減損 UPS 壽命,我打電話給 APC 後,依照 APC 工程人員的建議,調整 EEPROM 將穩壓下限調到最低值 97 伏特。其實這也可以用 apcupsd 來調整,不需要用到 PowerChute 。這真是太酷了~

    + +

    我也把 apcupsd 裝到公司。畢竟公司的 UPS 其實也一直沒有管理,趁此機會也一併設定好。不過公司的防火牆是用一台很舊的 Pentium MMX 來做的, BIOS 沒有斷電自動重開機的功能,所以斷電了也只能乖乖跑來公司開機。因為它是防火牆,它沒開的話,其它台開機了也沒有太大用處,也連不上外面網路。

    + +

    apcupsd 套件中有一個程式叫 powerflute ,可以在終端機下,以視窗選單模式顯示、調整 UPS 。老闆想到 powerflute 這名字可能和 PowerChute 有關。我沒跑過 PowerChute ,不過如果真是這樣,那 powerflute 可能是 PowerChute 的模擬程式, PowerChute 的畫面可能就像 powerflute 一樣。嗯。

    + +

    軟體管理設定好了以後,我再陸續看了幾篇 UPS 日常管理維護的知識。 UPS 不能接開機瞬間大量吃電的機器,否則可能會瞬間超載燒掉。機瞬間大量吃電的機器,包括雷射印表機,和電感性負載(如馬達等)。嗯,那我以前不就都做錯了。從公司搬家到這裏,雷射印表機放進機房接 UPS 到現都這麼多年了。那麼危險的事,我還做了這麼多年,嚇死我了。 1/5 星期六出門,就順便到公司把線路調整過來。幸好還有一個多餘的市電插座,讓雷射印表機可以直接接上去。

    + +

    除了雷射印表機,家用電器的電感性負載,主要是有馬達。像吹風機、電風扇等,都是禁忌。還有一般吃電瓦數大的,像電視、電冰箱、冷氣、電暖爐、熱水壺、烘衣機、微波爐等等,插上去馬上會超載,當然也是禁忌。最保險的做法,就是完全不要接家用電器。畢竟 UPS 是為電腦設計的,不是為家用電器設計的。

    + +

    一切穩定了以後,我寫了一封信給飛瑞,請他們回收處理報廢的舊 UPSUPS 的本體是密封鉛酸電池,必須要適當回收處理,不能直接丟棄,否則會造成很嚴重的環境污染。飛瑞回信請我把報廢的 UPS 寄回去,我找到原來的箱子,包一包寄過去。

    + +

    最後一個問題,是地線。

    + +

    一般家用市電,當初蓋房子的時候,接線多半是接兩孔的,沒有預留地線。可是沒有地線的話,怎麼看都很危險。最直接的危險就是我最怕的雷擊了。雷一打下來,大量的電無法從地線宣洩掉,再好的 UPS 也會馬上燒壞。雖然保護到後面的電腦,一台九千多塊的 UPS 化成灰,也是損失慘重。光用三孔轉兩孔的轉接頭轉接,只是掩耳盜鈴而已,完全沒有解決問題。我在網路上有看到,在一般公寓大樓沒辦法自行接地線的情況下,可以把地線接到窗框,釘死到窗框上。我問了 APC 的工程師,其實這樣沒有太大作用。因為窗框本身並沒有接地,周圍是水泥牆壁,水泥其實不導電。所以這樣只是把電宣洩到窗框上,能宣洩的電量有限,打雷時幫助不大。到頭來,還是要老老實實去接地線。

    + +

    打電話問學電機的老爸,老爸說一般家庭的總開關,一定都有接地,只要自己拉一條電線,鎖到總開關上就好了。這一點我也不清楚。而且接線我本來就不大擅長。我是敲鍵盤的師傅。所以我還是拜託房東請水電工。水電工來看了以後,證實總開關是一般家庭電源,沒有接地。就算把插頭由兩孔改成三孔,地線還是空的,其實和現在用轉接頭,也沒多大差別。

    + +

    唉。真的是這樣,也沒有辦法。只能祈導 APC UPS 有名的高品質,不會一打個雷就燒掉了。

    + +

    說到 APC UPS 的品質,和說明書放在一起的,有一張保證書,裏面保證如果有任何 APC UPS 保護下的產品,因電力問題而燒壞, APC 願意全額賠償。哇,我從來沒有看過這種保證,真是太酷了。 APC 不愧為 UPS 第一品牌啊~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 142 | + 143 | + 144 | + 145 | + 146 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0144.html.zh-cn.html b/htdocs/imacat/me/diary/0144.html.zh-cn.html new file mode 120000 index 0000000..1d5eabf --- /dev/null +++ b/htdocs/imacat/me/diary/0144.html.zh-cn.html @@ -0,0 +1 @@ +0144.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0144.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0144.html.zh-cn.xhtml new file mode 100644 index 0000000..2286315 --- /dev/null +++ b/htdocs/imacat/me/diary/0144.html.zh-cn.xhtml @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百四十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百四十四

    + +
    + +
    + +
    +
    1.31.’08. 6:45pm.
    + +

    UPS 不断电系统

    + +

    我的第一台 UPS ,大约是在 2000 年左右买的。那时候因应我的座位下有 rinse 和 cotton 两台电脑,小招的座位下有一台,所以买了一台飞瑞 A-1000 给我自己用,一台飞瑞 A-500 给小招用。

    + +

    那时候我不是很懂 UPS 。我唯一知道的,是在公司看到公司用的美商艾比希 APCSmart-UPS 3000VA (SU3000NET) ,用了至少十年以上。不过听老板说那一台很贵,花了十几万,所以只能流口水。真的要买,还是只能买光华商场买得到的台湾品牌飞瑞,一台两千的 A-1000 和一台一千的 A-500 廉价 UPS

    + +

    那时候我不是很懂。 rinse 装的是 Linux ,飞瑞附的监控程式完全派不上用场。而且飞瑞的面板只有一个指示灯,出了问题,还要翻出说明书来看才看得懂它在闪什么。所以 UPS 接上去以后,就只能听它哔哔哔地叫,也不知道在干嘛。停电时会哔哔叫几声,让我好好关机,电来了不久,哔哔声就消失了。不过没停电时,偶尔也会一直哔哔地叫,不知道在叫什么。到后来,整晚哔哔哔哔地叫个不停,也查不出什么原因。我实在受不了了,干脆拔掉 UPS ,直接接插座。不管怎样,也比被吵得整晚睡不著的好。

    + +

    那时候我就发誓,我下一台 UPS ,哪怕贵一点,绝对绝对不要买飞瑞的。

    + +

    不过因为手上没有钱,就这样拖了好几年过去了。这之间也查过好几次 APC UPS 的价格,知道依我的需要,其实不需要十几万。不过还是要好几万,我还是买不起。

    + +

    前年 2006 年,家里陆陆续续断电好几次,台电供电不稳,越来越严重。直到去年过年回高雄,突然连不上台北家里的网路,我以为又是断电了,台北家里没人可以帮忙重开机,我自己一时间也无法马上回台北处理,心急无焚。后来知道不是断电,只是中华电信网路断讯,过了两天就好了,才松了一口气。不过没有 UPS 保护的网路,我不在时完全没办法,我已经开始感到不安了。直到三月多,一次春雷雷击,家里两台电脑就这样坏了,紧急买新硬碟、主机板来换。还好资料还抓得出来,没有损失资料。不过硬体损坏的费用,还是让我损失惨重。对一台好的 UPS 的需求,也越来越强烈。

    + +

    公司定期都会收到赠阅的 DigiTimes 电子时报。去年 11 月, DigiTimes 电子时报 企业 IT 周报 出了一集专题UPS 采购指南。我一直想多了解 UPS ,作为购买的参考,也可以协助日常工作。公司那台 APC Smart-UPS 3000VA 其实我也一直都不大懂,一直想多作了解。所以平日随便看两页 DigiTimes 电子时报就送回收的我,特地把那期留下来,把那篇仔细读完。

    + +

    读了以后,我才知道主要有三种 UPS :离线式 (standby) ,在线互动式 (line interactive) ,在线式 (on-line) 。以价钱来说,离线式最便宜,在线互动式中等,在线式最贵;以供电保护能力来说,离线式最差,在线互动式稍好一点,只有在线式有完整的保护。不过在线式的太贵了。在线互动式的其实也是离线式的,由市电切到电池中间还是有很短的时间间隔,不过其电路输出时一律经过电压转换,可以保护市电的突波。在线式的保护最完整,电力完全由电池供应,市电直接输入电池,不管有没有市电都不影响供电。不过阅读了 APC 网站上的白皮书一号 The Different Types of UPS Systems ,我才知道,在线式 UPS 平时电力要先转直流进电池再转交流输出,这个转入转出过程电力损耗很大,使得在线式 UPS 本身就很耗电。考虑至少要有突波保护,以防范雷击,并考虑经济效益及省电的前题下,我锁定在线互动式 UPS ,作为目标。

    + +

    去年年底基金赎回,手上多了一笔现金,就开始著手购买 UPS 的事。原则上我想买 APCUPSAPCUPS 的第一大品牌,公司的 UPS 我虽然不大懂,但在我之前用了快十年,我进公司后又用了快十年,比起不知道发生什么事就坏掉了的飞瑞来说,非常稳定。 APC 的网站上有一个非常棒的功能:UPS 选择器,输入自己的电脑配备,程式会估计电脑大约的耗电瓦数,然后推荐合用的 UPS 。我用 UPS 选择器计算过,才知道我的电脑耗电量大约只有一、两百瓦而已,三台电脑加起来只有 500 瓦。加上预留的瓦数, 800 瓦以上的一定够用。其实一般的电脑, 250 瓦的电源供应器就够用了,考虑日后扩充,及电源供应器可能偷工减料不足瓦,顶多买 300 瓦。平常光华商场组装时,估到电源供应器,店员每每说需要 350 瓦才够,根本是多余的。

    + +

    用了 APCUPS 选择器估算,依其推荐,我锁定了在线互动式的 APC Smart-UPS 1500VA (SUA1500) ,最大输出一千瓦,备援时间十分钟。

    + +

    锁定了型号,我开始找有谁有卖。我知道光华商场大概买不到。光华商场其实东西很少,因为竞争激烈,大家都在减少库存,店家只会卖好卖的东西,高档的、贵的,像 APCUPS ,光华商场往往很难找得到。可是光这样,我也还是不知道有谁有卖。我又不能上班时间打电话去 APC 问。我只好试著上 Yahoo! 奇摩拍卖找。没想到真的有人在 Yahoo! 奇摩拍卖上卖 APC Smart-UPS 1500VA (SUA1500) ,还有其它网路电脑商城也有人在卖。不过价格落差很大,从一万八、一万三到九千都有人卖。价格落差这么大,我也吓了一大跳。依据看报纸社会版的经验,网路售价太便宜的,货源可能有问题,搞不好是赃物之类的。於是我先把独卖九千的那一家划掉,然后去找一万三的那两家。

    + +

    一万三的那两家,一家是纯网路商城,我不大敢买。另一家则自称是 3CeGo 网,在光华商场有实体店面,在光华商场做了二十年了,买了的话是去光华商场取货。有实体店面,我当然比较放心,光华商场我还蛮常走动,虽然不敢说全部店家都背得出来,但很多店只要给我店名,我也知道是在哪一家。不过有一、两家店之前弄得很不愉快,不怎么想踏进去。 3CeGo 网是怎么样都不肯透露是哪一家,写信过去也没有回,我也不知道该怎么办。我可不想下订了以后,到了店面取货才发现不想走进去,到时候就麻烦了。一愁莫展之际,我试著在网路上找3CeGo,没想到真的被我找到了。原来是纽顿。光华商场的纽顿我就知道了,常常去买。如果真的是纽顿,那我可以放心了。我写信去纽顿问,客服人员回答说 Yahoo! 奇摩拍卖上的 3CeGo 网的确就是他们,不过因 Yahoo! 奇摩拍卖的规定,他们不能说。我不知道有什么不能说实体店名的奇怪规定,我不卖东西也不开店,所以不了解。不过如果是纽顿,应该没有问题。

    + +

    可是一万三和九千相比,毕竟差了四千。四千块钱是很多钱。 UPS 是一用就要用十年的东西,就算买二手的也值得。如果九千块钱的货源没有问题,不是赃物,还是应该能省则省。虽然很可疑,我还是去调查看看。

    + +

    九千的这一个,不知道为什么,上面还加上 DELL OEM 。我不知道那是什么。不过如果只是上面印上 Dell 的标志, APC 还是一样保固的话,我倒没有意见。那家公司叫做自由度网路科技,公司在高雄,我从来没听过。我很久没回高雄了,没听过也是正常的。网路上找一找,它似乎还是微软经销商,在 Yahoo! 奇摩上卖三年了,电话地址都是同一家,应该是正派的公司。可是我不是没待过卖场,正常电脑产品的利润哪可以压到三成以上?九千块的价格怎么看都不大正派。打电话去问,他说是跟戴尔电脑拿货的,所以叫 DELL OEM 。不过上面不会有 Dell 的标志。因为戴尔电脑给他们的价格很优,所以他们才能便宜卖。出货时,会由戴尔直接出货,所以不用另加运费。戴尔,嗯。没关系,我再写信去戴尔问,看自由度是不是他们的经销商。感觉上自由度应该不是骗人的公司,加上电话中聊得蛮愉快的,所以我还是先在 Yahoo! 奇摩拍卖上下订了,等戴尔确认经销商身份没问题,再汇款好了。

    + +

    没想到,接下来,才是故事的开始。

    + +

    写信给戴尔询问自由度的经销商身份时,已经是傍晚准备下班了。我寄出去后,收拾一下就下班了。晚上回家收信,一口气收到三封来自三个不同的客服人员的不在座位自动回函。我觉得好气又好笑,像这种网站询问,如果有一组人一起处理,就不需要每个人都自动回函了吧。隔天早上,接到了戴尔的电话。跟电话对方的客服小姐解释以后,没想到她问了我一句:

    + +
    +你怎么不直接跟戴尔买呢? +
    + +

    唔…嗯…可是我之前不知道戴尔还有代销别人的产品啊…

    + +
    +那你要不要直接跟戴尔买?我可以给你更优惠的价格。 +
    + +

    啊?唔…嗯…可是我已经下订了。如果没有问题的话,我一定要跟他们买。做生意讲究诚信,这是买家的信用问题。

    + +

    不,不对,我的问题不是这个吧。我只是要问自由度是不是戴尔的经销商而已,难道你们连这点都查不出来吗?更何况,哪有人跟自己的经销商抢生意的啊?

    + +

    客服小姐明白了以后,问我自由度网路科技的电话,她愿意帮我协调。可能是我给错名字了吧,下午回电话时,她说她找不到那个人。她再次问我,真的不考虑直接跟戴尔买吗?她可以给我更优惠的价格。

    + +

    不好意思,我在 Yahoo! 奇摩拍卖上很少买卖东西,评价很少,一个负评都承受不起。更何况,贪个一两千块,破坏自己辛苦建立的信用,是很划不来的事。不过,难道戴尔没办法在自己的经销商名单上确认吗?

    + +

    我这样问,她才不好意思地告诉我,戴尔没有经销商名单。原来如此。戴尔是世界有名的电脑直销商,以前从不做经销商的,以直销压低价格。去年因为业绩滑落,换了新的执行长,才开始改变经营模式,做经销商。不过看来戴尔很没有经营经销商的概念,所谓经销商也不过就是大量进货压低价格的客户而已,所以也没有特别建立经销商名单,而且还会跟经销商抢生意。所以戴尔不像一般电脑品牌一样,我去查经销商,也查不到。

    + +

    不过戴尔可以给我更优惠的价格,那表示自由度开九千块钱,还是有利润的。既然有正常利润,自由度看样子是正派的公司,我也就比较放心了。婉拒了戴尔客服小姐的好意后,下午吃饭时就去汇钱,跟自由度确认,等戴尔把 UPS 寄过来了。

    + +

    一个礼拜后,我的电话响了。是货运公司,跟我确认送货地址。电话那头给我一个汐止的地址,我跟对方更正为公馆的地址。

    + +

    过两天元旦过后,货运公司送来了。长型的盒子,有点出乎我意料之外。不过东西送来了,确定不是诈骗,我也安了心。签收了以后,一拆开来看,傻眼了:这,这是键盘吧?为什么?难道订单弄错了吗?不会就是前天弄错汐止地址的那件事吧?难道说我把人家正确的汐止地址更正成错了的吗?要送到汐止的键盘送到这里来,那我的 UPS 不会送到汐止去了吧!天哪,我已经等了一个星期了,再从汐止搬回来再送过来,还要我等多久?我赶紧打电话去戴尔、去自由度问,戴尔说要我找自由度。也对,我不是戴尔的客户,自由度才是戴尔的客户。电话中,自由度那边也傻眼了,一直跟我道歉。我还是很不安。隔天,货运公司打电话来,又要确认送货地址。这次我不敢大意了,先确认收件人名字,确认货品是不是 APC UPS ,才请他送过来。送过来后,货运公司说要拿走之前送错的键盘,我也先跟自由度确认过,才把键盘交给他。

    + +

    还好,只有汐止的键盘送来这里,我的 UPS 没有送去汐止,是单向的送错。仔细看看我签收的戴尔出货单,上面收件人地址在汐止,名字不是我的名字,连电话都不是我的电话。唔,那表示到戴尔这一端,出货单都没有问题。那为什么打电话给我,确认送货地址呢?看样子是货运公司看错电话搞的乌龙。我没有实际受害。不知道汐止的受害者是谁,唉。

    + +

    Yahoo! 奇摩拍卖评价时,我考虑了一下。虽然不是自由度的错,也不是戴尔的错,我也没有实际受害。不过这种事还是蛮可怕的。这次是汐止的某人受害,搞不好下一次就是我了。自由度卖的东西,整个过程还是要负连带责任。所以还是写了一个普通的评价,并且把事情写清楚。

    + +

    UPS 真的很重。里面有一颗很大颗的密封铅酸电池,电池这种东西真的重得不得了。好不容易搬回家,盘算了一下配线怎么调整后,把旧的两台飞瑞 UPS 撤掉,把新买的接上去。我再买了一个多孔插座延长线,延长到小招的电脑旁边,把小招的电脑也一起接过来。 APC 果然不愧是 UPS 老字号第一品牌,不像飞瑞 A-1000/A-500 只有一个指示灯, APC UPS 上面两三排指示灯,加上旁边清楚的图示, UPS 状况一目了然,才不会重蹈覆辙。

    + +

    不过光接上去还不够。 UPS 还要管理,不然用处不大,就跟以前那台飞瑞差不多了。 APC 有附一套 PowerChute UPS 管理软体,还有 Linux 版,不过 Linux 版是执行档,没有原始程式可自行编译,所以大概只支援(不是我用的)某某版本的 Linux ,日后系统更新可能就挂了,而且大概还要 X-Windows 在视窗下执行。我试著看 Linux HOWTO 教学,发现了一篇 UPS HOWTO (不断电系统教学) ,高兴地赶快翻出来读。

    + +

    这篇 UPS HOWTO (不断电系统教学) ,写得非常详尽。我不是学电机的,专长是电脑软体程式,不是电力配线。我是用手指头敲键盘的师傅,对於键盘敲敲打打以外的事真的一知半解。这篇教学针对的是小家庭或小型办公室,只有几台个人电脑,使用在线互动式 UPS 的环境,先从家用电力的问题开始说明起,从断电器、突波保护器到 UPS 所能保护的范围。接上 UPS 以后的管理,它提到了两个自由软体专案:一个是各品牌通用的 UPS 管理程式 Network UPS Tools ,一个是专为 APC UPS 开发的 apcupsd 。一般如果是 APCUPS ,用 apcupsd 就好了; APC 以外的 UPS ,就用 Network UPS Tools

    + +

    看到这里,我真的很高兴。赶快顺著这条线索,用 APT 安装了 apcupsd 。装起来了以后,发现真的超酷的。接好线后,直接从虚拟终端机就可以看到 UPS 的现况,包括目前负载、目前市电电压、电池存量、预计可用时间、电池好坏等等,全部一目了然。如果用电脑跑比较大的程式, CPU 忙起来,也可以看得到电力负载马上上升,预计可用时间也会因而下降。而且所有发生的市电事件,断电、电压不足、电池损坏等,也都会记录到 Syslog 里,可以随时追溯监控市电的品质。

    + +

    原来家里平常的负载,只有 20%–25% 左右,就算加小招的电脑,三台电脑全开,顶多到 40% 。以 APC Smart-UPS 1500VA (SUA1500) 最大负载 980 瓦来说,顶多 400 瓦,一台电脑只有一百多瓦。我却都买了 350 瓦的电源供应器,买新电脑时,还常常被店员说可能不够用,想想还真的有点好笑。

    + +

    可是光知道 UPS 的状况,当然不够。更重要的,是断电时,人不在电脑旁时的自动处理。而且电池寿命用尽时,也必需要通知我去更换电池。仔细研究了一下,发现 apcupsd 不只可以随时监控电力状况,还可以设定在电力不足,只剩几分钟可用时,自动关机。而且 apcupsd 还可以透过网路分享 UPS 的电力资讯。 UPS 监控线接到一台主机,其它主机就由那台主机取得 UPS 的电力数值,以各自关机。这样一来,只要 UPS 接到一台主机,其它主机就可以跟著动作,实现小型网路的电力管理了。而且 apcupsd 还有 Windows 版,也就是说, Windows 电脑也可以分享 UPS 的电力资讯,跟著自行关机。这真的是超酷的~

    + +

    不过关机后市电恢复,人不在电脑旁边时,要有人去按开关开机,是另一件让人头大的事。这点 UPS HOWTO (不断电系统教学) 也有提及。我读了以后才知道,其实现代电脑的 BIOS 里,都内建有断电后,电力恢复时自动重开机的功能,不过这个功能预设是关闭的。我以前一直不知道这个功能,赶紧重开机看 BIOS 设定,果然有一个 Restore on AC/Power Loss 的选项,里面有三种模式: Last StatePower OnPower Off ,预设是 Power Off 。只要改成 Power On ,就可以了。设定好了以后稍为实验一下,直接拔掉电线,过一会儿再重开,果然自己重开机了。我以前都跟人家说断电后自动重开机是不可能的,一定是记错了之类的话,看来我一直都说错了。

    + +

    这样,我真的可以回家一、两个星期,也不用担心。就算断电关机,电来了也会自己开机,断电造成的服务中断时间可以缩到最短,就算无人在家也可以自行管理。

    + +

    再仔细研究一下,我发现 apcupsd 不只能做到电力自行管理。在像断电关机这种重要事件时, apcupsd 还会发信通知。所以人不在电脑旁边的时候,因为断电自动关机开机,网管也都会清楚得知。会通知的还包括: UPS 断讯、电池损坏待修等等重大事件。几乎所有网管需要知道、处理的重大事情,都会发信通知。这样就不怕像之前那样, UPS 坏得不明不白了。

    + +

    尤有甚者, apcupsd 还有好几只 CGI 程式,可以由网页浏览监控,也就是说,网管从任何地方,即使是出国旅游无法连线虚拟终端机,也都可以随时远端监看包括像目前市电电压、 UPS 负载、电池电量、剩余时间等等。

    + +

    这真的是太酷了。几乎我所有想得到的需求, apcupsd 都可以办得到。我已经想不到什么问题了。我不知道 Network UPS Tools 能不能做到这些。不过到这里我觉得,能够买 APCUPS ,实在是太幸福了。果然是世界第一品牌啊~虽然九千五确实很贵,但是很值得。

    + +

    不过 Debianapcupsd 套件需要安装 libsnmp ,会跟我自己安装的 Net-SNMP 相冲。其实我只有一台用序列埠线管理的 UPS ,没有用网路 SNMPUPS ,编译的时候根本不需要连结 SNMP 函式库。所以我还是舍弃了 Debianapcupsd 套件,移除以后,自己下载原始码来编译、安装。

    + +

    自行编译的时候,我发现 apcupsdDebian 上编译时,连接埠自动由 3551 改用 6543 。我不是很了解,上网查了一下,发现以前 Debian 确实是用连接埠 6543 跑 apcupsd 。不过这已经是很久以前的事了,在 apcupsd 正式向 IANA 注册到了连接埠 3551 后, 2004 年有人在 Debian 上提出修正,也已经修正好了。我也写了一个简单的修补传上 apcupsd-users 通讯,取消掉 Debian 自动设定连接簿 6543 。下一版 apcupsd 应该会修正好吧。

    + +

    我自己也写了一个简单的程式,取得电压和负载,给 MRTG 定期搜集、监控、绘图,以取得长期的电压和负载变化。

    + +

    安装了新的 UPS ,并得以监控后,我才知道,家里的市电真的很不稳定,常常有一、两秒的瞬断。只是因为时间很短马上就恢复,电脑没有因而断讯,所以没有察觉。严重时甚至一天两、三次。电压也不稳定,常常掉到 105 伏特以下,让 UPS 切为电池供电稳压。其实台湾的市电应该是 110 伏特,美国的市电是 120 伏特, APCUPS 也是以 120 伏特电力输出设计的,中间其实差了 10 伏特。对 120 伏特而言,电力掉到 105 伏特以下等於掉了 15 伏特,的确已经是低电压的异常状态了。可是对 110 伏特而言, 105 伏特只掉了 5 伏特,其实还算正常起伏。为避免 UPS 稳压切得太频繁,减损 UPS 寿命,我打电话给 APC 后,依照 APC 工程人员的建议,调整 EEPROM 将稳压下限调到最低值 97 伏特。其实这也可以用 apcupsd 来调整,不需要用到 PowerChute 。这真是太酷了~

    + +

    我也把 apcupsd 装到公司。毕竟公司的 UPS 其实也一直没有管理,趁此机会也一并设定好。不过公司的防火墙是用一台很旧的 Pentium MMX 来做的, BIOS 没有断电自动重开机的功能,所以断电了也只能乖乖跑来公司开机。因为它是防火墙,它没开的话,其它台开机了也没有太大用处,也连不上外面网路。

    + +

    apcupsd 套件中有一个程式叫 powerflute ,可以在终端机下,以视窗选单模式显示、调整 UPS 。老板想到 powerflute 这名字可能和 PowerChute 有关。我没跑过 PowerChute ,不过如果真是这样,那 powerflute 可能是 PowerChute 的模拟程式, PowerChute 的画面可能就像 powerflute 一样。嗯。

    + +

    软体管理设定好了以后,我再陆续看了几篇 UPS 日常管理维护的知识。 UPS 不能接开机瞬间大量吃电的机器,否则可能会瞬间超载烧掉。机瞬间大量吃电的机器,包括雷射印表机,和电感性负载(如马达等)。嗯,那我以前不就都做错了。从公司搬家到这里,雷射印表机放进机房接 UPS 到现都这么多年了。那么危险的事,我还做了这么多年,吓死我了。 1/5 星期六出门,就顺便到公司把线路调整过来。幸好还有一个多余的市电插座,让雷射印表机可以直接接上去。

    + +

    除了雷射印表机,家用电器的电感性负载,主要是有马达。像吹风机、电风扇等,都是禁忌。还有一般吃电瓦数大的,像电视、电冰箱、冷气、电暖炉、热水壶、烘衣机、微波炉等等,插上去马上会超载,当然也是禁忌。最保险的做法,就是完全不要接家用电器。毕竟 UPS 是为电脑设计的,不是为家用电器设计的。

    + +

    一切稳定了以后,我写了一封信给飞瑞,请他们回收处理报废的旧 UPSUPS 的本体是密封铅酸电池,必须要适当回收处理,不能直接丢弃,否则会造成很严重的环境污染。飞瑞回信请我把报废的 UPS 寄回去,我找到原来的箱子,包一包寄过去。

    + +

    最后一个问题,是地线。

    + +

    一般家用市电,当初盖房子的时候,接线多半是接两孔的,没有预留地线。可是没有地线的话,怎么看都很危险。最直接的危险就是我最怕的雷击了。雷一打下来,大量的电无法从地线宣泄掉,再好的 UPS 也会马上烧坏。虽然保护到后面的电脑,一台九千多块的 UPS 化成灰,也是损失惨重。光用三孔转两孔的转接头转接,只是掩耳盗铃而已,完全没有解决问题。我在网路上有看到,在一般公寓大楼没办法自行接地线的情况下,可以把地线接到窗框,钉死到窗框上。我问了 APC 的工程师,其实这样没有太大作用。因为窗框本身并没有接地,周围是水泥墙壁,水泥其实不导电。所以这样只是把电宣泄到窗框上,能宣泄的电量有限,打雷时帮助不大。到头来,还是要老老实实去接地线。

    + +

    打电话问学电机的老爸,老爸说一般家庭的总开关,一定都有接地,只要自己拉一条电线,锁到总开关上就好了。这一点我也不清楚。而且接线我本来就不大擅长。我是敲键盘的师傅。所以我还是拜托房东请水电工。水电工来看了以后,证实总开关是一般家庭电源,没有接地。就算把插头由两孔改成三孔,地线还是空的,其实和现在用转接头,也没多大差别。

    + +

    唉。真的是这样,也没有办法。只能祈导 APC UPS 有名的高品质,不会一打个雷就烧掉了。

    + +

    说到 APC UPS 的品质,和说明书放在一起的,有一张保证书,里面保证如果有任何 APC UPS 保护下的产品,因电力问题而烧坏, APC 愿意全额赔偿。哇,我从来没有看过这种保证,真是太酷了。 APC 不愧为 UPS 第一品牌啊~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 142 | + 143 | + 144 | + 145 | + 146 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0144.html.zh-tw.html b/htdocs/imacat/me/diary/0144.html.zh-tw.html new file mode 120000 index 0000000..0942c38 --- /dev/null +++ b/htdocs/imacat/me/diary/0144.html.zh-tw.html @@ -0,0 +1 @@ +0144.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0144.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0144.html.zh-tw.xhtml new file mode 100644 index 0000000..5e38f9c --- /dev/null +++ b/htdocs/imacat/me/diary/0144.html.zh-tw.xhtml @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百四十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百四十四

    + +
    + +
    + +
    +
    1.31.’08. 6:45pm.
    + +

    UPS 不斷電系統

    + +

    我的第一台 UPS ,大約是在 2000 年左右買的。那時候因應我的座位下有 rinse 和 cotton 兩台電腦,小招的座位下有一台,所以買了一台飛瑞 A-1000 給我自己用,一台飛瑞 A-500 給小招用。

    + +

    那時候我不是很懂 UPS 。我唯一知道的,是在公司看到公司用的美商艾比希 APCSmart-UPS 3000VA (SU3000NET) ,用了至少十年以上。不過聽老闆說那一台很貴,花了十幾萬,所以只能流口水。真的要買,還是只能買光華商場買得到的台灣品牌飛瑞,一台兩千的 A-1000 和一台一千的 A-500 廉價 UPS

    + +

    那時候我不是很懂。 rinse 裝的是 Linux ,飛瑞附的監控程式完全派不上用場。而且飛瑞的面板只有一個指示燈,出了問題,還要翻出說明書來看才看得懂它在閃什麼。所以 UPS 接上去以後,就只能聽它嗶嗶嗶地叫,也不知道在幹嘛。停電時會嗶嗶叫幾聲,讓我好好關機,電來了不久,嗶嗶聲就消失了。不過沒停電時,偶爾也會一直嗶嗶地叫,不知道在叫什麼。到後來,整晚嗶嗶嗶嗶地叫個不停,也查不出什麼原因。我實在受不了了,乾脆拔掉 UPS ,直接接插座。不管怎樣,也比被吵得整晚睡不著的好。

    + +

    那時候我就發誓,我下一台 UPS ,哪怕貴一點,絕對絕對不要買飛瑞的。

    + +

    不過因為手上沒有錢,就這樣拖了好幾年過去了。這之間也查過好幾次 APC UPS 的價格,知道依我的需要,其實不需要十幾萬。不過還是要好幾萬,我還是買不起。

    + +

    前年 2006 年,家裏陸陸續續斷電好幾次,台電供電不穩,越來越嚴重。直到去年過年回高雄,突然連不上台北家裏的網路,我以為又是斷電了,台北家裏沒人可以幫忙重開機,我自己一時間也無法馬上回台北處理,心急無焚。後來知道不是斷電,只是中華電信網路斷訊,過了兩天就好了,才鬆了一口氣。不過沒有 UPS 保護的網路,我不在時完全沒辦法,我已經開始感到不安了。直到三月多,一次春雷雷擊,家裏兩台電腦就這樣壞了,緊急買新硬碟、主機板來換。還好資料還抓得出來,沒有損失資料。不過硬體損壞的費用,還是讓我損失慘重。對一台好的 UPS 的需求,也越來越強烈。

    + +

    公司定期都會收到贈閱的 DigiTimes 電子時報。去年 11 月, DigiTimes 電子時報 企業 IT 週報 出了一集專題UPS 採購指南。我一直想多瞭解 UPS ,作為購買的參考,也可以協助日常工作。公司那台 APC Smart-UPS 3000VA 其實我也一直都不大懂,一直想多作瞭解。所以平日隨便看兩頁 DigiTimes 電子時報就送回收的我,特地把那期留下來,把那篇仔細讀完。

    + +

    讀了以後,我才知道主要有三種 UPS :離線式 (standby) ,在線互動式 (line interactive) ,在線式 (on-line) 。以價錢來說,離線式最便宜,在線互動式中等,在線式最貴;以供電保護能力來說,離線式最差,在線互動式稍好一點,只有在線式有完整的保護。不過在線式的太貴了。在線互動式的其實也是離線式的,由市電切到電池中間還是有很短的時間間隔,不過其電路輸出時一律經過電壓轉換,可以保護市電的突波。在線式的保護最完整,電力完全由電池供應,市電直接輸入電池,不管有沒有市電都不影響供電。不過閱讀了 APC 網站上的白皮書一號 The Different Types of UPS Systems ,我才知道,在線式 UPS 平時電力要先轉直流進電池再轉交流輸出,這個轉入轉出過程電力損耗很大,使得在線式 UPS 本身就很耗電。考慮至少要有突波保護,以防範雷擊,並考慮經濟效益及省電的前題下,我鎖定在線互動式 UPS ,作為目標。

    + +

    去年年底基金贖回,手上多了一筆現金,就開始著手購買 UPS 的事。原則上我想買 APCUPSAPCUPS 的第一大品牌,公司的 UPS 我雖然不大懂,但在我之前用了快十年,我進公司後又用了快十年,比起不知道發生什麼事就壞掉了的飛瑞來說,非常穩定。 APC 的網站上有一個非常棒的功能:UPS 選擇器,輸入自己的電腦配備,程式會估計電腦大約的耗電瓦數,然後推薦合用的 UPS 。我用 UPS 選擇器計算過,才知道我的電腦耗電量大約只有一、兩百瓦而已,三台電腦加起來只有 500 瓦。加上預留的瓦數, 800 瓦以上的一定夠用。其實一般的電腦, 250 瓦的電源供應器就夠用了,考慮日後擴充,及電源供應器可能偷工減料不足瓦,頂多買 300 瓦。平常光華商場組裝時,估到電源供應器,店員每每說需要 350 瓦才夠,根本是多餘的。

    + +

    用了 APCUPS 選擇器估算,依其推薦,我鎖定了在線互動式的 APC Smart-UPS 1500VA (SUA1500) ,最大輸出一千瓦,備援時間十分鐘。

    + +

    鎖定了型號,我開始找有誰有賣。我知道光華商場大概買不到。光華商場其實東西很少,因為競爭激烈,大家都在減少庫存,店家只會賣好賣的東西,高檔的、貴的,像 APCUPS ,光華商場往往很難找得到。可是光這樣,我也還是不知道有誰有賣。我又不能上班時間打電話去 APC 問。我只好試著上 Yahoo! 奇摩拍賣找。沒想到真的有人在 Yahoo! 奇摩拍賣上賣 APC Smart-UPS 1500VA (SUA1500) ,還有其它網路電腦商城也有人在賣。不過價格落差很大,從一萬八、一萬三到九千都有人賣。價格落差這麼大,我也嚇了一大跳。依據看報紙社會版的經驗,網路售價太便宜的,貨源可能有問題,搞不好是贓物之類的。於是我先把獨賣九千的那一家劃掉,然後去找一萬三的那兩家。

    + +

    一萬三的那兩家,一家是純網路商城,我不大敢買。另一家則自稱是 3CeGo 網,在光華商場有實體店面,在光華商場做了二十年了,買了的話是去光華商場取貨。有實體店面,我當然比較放心,光華商場我還蠻常走動,雖然不敢說全部店家都背得出來,但很多店只要給我店名,我也知道是在哪一家。不過有一、兩家店之前弄得很不愉快,不怎麼想踏進去。 3CeGo 網是怎麼樣都不肯透露是哪一家,寫信過去也沒有回,我也不知道該怎麼辦。我可不想下訂了以後,到了店面取貨才發現不想走進去,到時候就麻煩了。一愁莫展之際,我試著在網路上找3CeGo,沒想到真的被我找到了。原來是紐頓。光華商場的紐頓我就知道了,常常去買。如果真的是紐頓,那我可以放心了。我寫信去紐頓問,客服人員回答說 Yahoo! 奇摩拍賣上的 3CeGo 網的確就是他們,不過因 Yahoo! 奇摩拍賣的規定,他們不能說。我不知道有什麼不能說實體店名的奇怪規定,我不賣東西也不開店,所以不瞭解。不過如果是紐頓,應該沒有問題。

    + +

    可是一萬三和九千相比,畢竟差了四千。四千塊錢是很多錢。 UPS 是一用就要用十年的東西,就算買二手的也值得。如果九千塊錢的貨源沒有問題,不是贓物,還是應該能省則省。雖然很可疑,我還是去調查看看。

    + +

    九千的這一個,不知道為什麼,上面還加上 DELL OEM 。我不知道那是什麼。不過如果只是上面印上 Dell 的標誌, APC 還是一樣保固的話,我倒沒有意見。那家公司叫做自由度網路科技,公司在高雄,我從來沒聽過。我很久沒回高雄了,沒聽過也是正常的。網路上找一找,它似乎還是微軟經銷商,在 Yahoo! 奇摩上賣三年了,電話地址都是同一家,應該是正派的公司。可是我不是沒待過賣場,正常電腦產品的利潤哪可以壓到三成以上?九千塊的價格怎麼看都不大正派。打電話去問,他說是跟戴爾電腦拿貨的,所以叫 DELL OEM 。不過上面不會有 Dell 的標誌。因為戴爾電腦給他們的價格很優,所以他們才能便宜賣。出貨時,會由戴爾直接出貨,所以不用另加運費。戴爾,嗯。沒關係,我再寫信去戴爾問,看自由度是不是他們的經銷商。感覺上自由度應該不是騙人的公司,加上電話中聊得蠻愉快的,所以我還是先在 Yahoo! 奇摩拍賣上下訂了,等戴爾確認經銷商身份沒問題,再匯款好了。

    + +

    沒想到,接下來,才是故事的開始。

    + +

    寫信給戴爾詢問自由度的經銷商身份時,已經是傍晚準備下班了。我寄出去後,收拾一下就下班了。晚上回家收信,一口氣收到三封來自三個不同的客服人員的不在座位自動回函。我覺得好氣又好笑,像這種網站詢問,如果有一組人一起處理,就不需要每個人都自動回函了吧。隔天早上,接到了戴爾的電話。跟電話對方的客服小姐解釋以後,沒想到她問了我一句:

    + +
    +妳怎麼不直接跟戴爾買呢? +
    + +

    唔…嗯…可是我之前不知道戴爾還有代銷別人的產品啊…

    + +
    +那妳要不要直接跟戴爾買?我可以給妳更優惠的價格。 +
    + +

    啊?唔…嗯…可是我已經下訂了。如果沒有問題的話,我一定要跟他們買。做生意講究誠信,這是買家的信用問題。

    + +

    不,不對,我的問題不是這個吧。我只是要問自由度是不是戴爾的經銷商而已,難道妳們連這點都查不出來嗎?更何況,哪有人跟自己的經銷商搶生意的啊?

    + +

    客服小姐明白了以後,問我自由度網路科技的電話,她願意幫我協調。可能是我給錯名字了吧,下午回電話時,她說她找不到那個人。她再次問我,真的不考慮直接跟戴爾買嗎?她可以給我更優惠的價格。

    + +

    不好意思,我在 Yahoo! 奇摩拍賣上很少買賣東西,評價很少,一個負評都承受不起。更何況,貪個一兩千塊,破壞自己辛苦建立的信用,是很划不來的事。不過,難道戴爾沒辦法在自己的經銷商名單上確認嗎?

    + +

    我這樣問,她才不好意思地告訴我,戴爾沒有經銷商名單。原來如此。戴爾是世界有名的電腦直銷商,以前從不做經銷商的,以直銷壓低價格。去年因為業績滑落,換了新的執行長,才開始改變經營模式,做經銷商。不過看來戴爾很沒有經營經銷商的概念,所謂經銷商也不過就是大量進貨壓低價格的客戶而已,所以也沒有特別建立經銷商名單,而且還會跟經銷商搶生意。所以戴爾不像一般電腦品牌一樣,我去查經銷商,也查不到。

    + +

    不過戴爾可以給我更優惠的價格,那表示自由度開九千塊錢,還是有利潤的。既然有正常利潤,自由度看樣子是正派的公司,我也就比較放心了。婉拒了戴爾客服小姐的好意後,下午吃飯時就去匯錢,跟自由度確認,等戴爾把 UPS 寄過來了。

    + +

    一個禮拜後,我的電話響了。是貨運公司,跟我確認送貨地址。電話那頭給我一個汐止的地址,我跟對方更正為公館的地址。

    + +

    過兩天元旦過後,貨運公司送來了。長型的盒子,有點出乎我意料之外。不過東西送來了,確定不是詐騙,我也安了心。簽收了以後,一拆開來看,傻眼了:這,這是鍵盤吧?為什麼?難道訂單弄錯了嗎?不會就是前天弄錯汐止地址的那件事吧?難道說我把人家正確的汐止地址更正成錯了的嗎?要送到汐止的鍵盤送到這裏來,那我的 UPS 不會送到汐止去了吧!天哪,我已經等了一個星期了,再從汐止搬回來再送過來,還要我等多久?我趕緊打電話去戴爾、去自由度問,戴爾說要我找自由度。也對,我不是戴爾的客戶,自由度才是戴爾的客戶。電話中,自由度那邊也傻眼了,一直跟我道歉。我還是很不安。隔天,貨運公司打電話來,又要確認送貨地址。這次我不敢大意了,先確認收件人名字,確認貨品是不是 APC UPS ,才請他送過來。送過來後,貨運公司說要拿走之前送錯的鍵盤,我也先跟自由度確認過,才把鍵盤交給他。

    + +

    還好,只有汐止的鍵盤送來這裏,我的 UPS 沒有送去汐止,是單向的送錯。仔細看看我簽收的戴爾出貨單,上面收件人地址在汐止,名字不是我的名字,連電話都不是我的電話。唔,那表示到戴爾這一端,出貨單都沒有問題。那為什麼打電話給我,確認送貨地址呢?看樣子是貨運公司看錯電話搞的烏龍。我沒有實際受害。不知道汐止的受害者是誰,唉。

    + +

    Yahoo! 奇摩拍賣評價時,我考慮了一下。雖然不是自由度的錯,也不是戴爾的錯,我也沒有實際受害。不過這種事還是蠻可怕的。這次是汐止的某人受害,搞不好下一次就是我了。自由度賣的東西,整個過程還是要負連帶責任。所以還是寫了一個普通的評價,並且把事情寫清楚。

    + +

    UPS 真的很重。裏面有一顆很大顆的密封鉛酸電池,電池這種東西真的重得不得了。好不容易搬回家,盤算了一下配線怎麼調整後,把舊的兩台飛瑞 UPS 撤掉,把新買的接上去。我再買了一個多孔插座延長線,延長到小招的電腦旁邊,把小招的電腦也一起接過來。 APC 果然不愧是 UPS 老字號第一品牌,不像飛瑞 A-1000/A-500 只有一個指示燈, APC UPS 上面兩三排指示燈,加上旁邊清楚的圖示, UPS 狀況一目瞭然,才不會重蹈覆轍。

    + +

    不過光接上去還不夠。 UPS 還要管理,不然用處不大,就跟以前那台飛瑞差不多了。 APC 有附一套 PowerChute UPS 管理軟體,還有 Linux 版,不過 Linux 版是執行檔,沒有原始程式可自行編譯,所以大概只支援(不是我用的)某某版本的 Linux ,日後系統更新可能就掛了,而且大概還要 X-Windows 在視窗下執行。我試著看 Linux HOWTO 教學,發現了一篇 UPS HOWTO (不斷電系統教學) ,高興地趕快翻出來讀。

    + +

    這篇 UPS HOWTO (不斷電系統教學) ,寫得非常詳盡。我不是學電機的,專長是電腦軟體程式,不是電力配線。我是用手指頭敲鍵盤的師傅,對於鍵盤敲敲打打以外的事真的一知半解。這篇教學針對的是小家庭或小型辦公室,只有幾台個人電腦,使用在線互動式 UPS 的環境,先從家用電力的問題開始說明起,從斷電器、突波保護器到 UPS 所能保護的範圍。接上 UPS 以後的管理,它提到了兩個自由軟體專案:一個是各品牌通用的 UPS 管理程式 Network UPS Tools ,一個是專為 APC UPS 開發的 apcupsd 。一般如果是 APCUPS ,用 apcupsd 就好了; APC 以外的 UPS ,就用 Network UPS Tools

    + +

    看到這裏,我真的很高興。趕快順著這條線索,用 APT 安裝了 apcupsd 。裝起來了以後,發現真的超酷的。接好線後,直接從虛擬終端機就可以看到 UPS 的現況,包括目前負載、目前市電電壓、電池存量、預計可用時間、電池好壞等等,全部一目瞭然。如果用電腦跑比較大的程式, CPU 忙起來,也可以看得到電力負載馬上上昇,預計可用時間也會因而下降。而且所有發生的市電事件,斷電、電壓不足、電池損壞等,也都會記錄到 Syslog 裏,可以隨時追溯監控市電的品質。

    + +

    原來家裏平常的負載,只有 20%–25% 左右,就算加小招的電腦,三台電腦全開,頂多到 40% 。以 APC Smart-UPS 1500VA (SUA1500) 最大負載 980 瓦來說,頂多 400 瓦,一台電腦只有一百多瓦。我卻都買了 350 瓦的電源供應器,買新電腦時,還常常被店員說可能不夠用,想想還真的有點好笑。

    + +

    可是光知道 UPS 的狀況,當然不夠。更重要的,是斷電時,人不在電腦旁時的自動處理。而且電池壽命用盡時,也必需要通知我去更換電池。仔細研究了一下,發現 apcupsd 不只可以隨時監控電力狀況,還可以設定在電力不足,只剩幾分鐘可用時,自動關機。而且 apcupsd 還可以透過網路分享 UPS 的電力資訊。 UPS 監控線接到一台主機,其它主機就由那台主機取得 UPS 的電力數值,以各自關機。這樣一來,只要 UPS 接到一台主機,其它主機就可以跟著動作,實現小型網路的電力管理了。而且 apcupsd 還有 Windows 版,也就是說, Windows 電腦也可以分享 UPS 的電力資訊,跟著自行關機。這真的是超酷的~

    + +

    不過關機後市電恢復,人不在電腦旁邊時,要有人去按開關開機,是另一件讓人頭大的事。這點 UPS HOWTO (不斷電系統教學) 也有提及。我讀了以後才知道,其實現代電腦的 BIOS 裏,都內建有斷電後,電力恢復時自動重開機的功能,不過這個功能預設是關閉的。我以前一直不知道這個功能,趕緊重開機看 BIOS 設定,果然有一個 Restore on AC/Power Loss 的選項,裏面有三種模式: Last StatePower OnPower Off ,預設是 Power Off 。只要改成 Power On ,就可以了。設定好了以後稍為實驗一下,直接拔掉電線,過一會兒再重開,果然自己重開機了。我以前都跟人家說斷電後自動重開機是不可能的,一定是記錯了之類的話,看來我一直都說錯了。

    + +

    這樣,我真的可以回家一、兩個星期,也不用擔心。就算斷電關機,電來了也會自己開機,斷電造成的服務中斷時間可以縮到最短,就算無人在家也可以自行管理。

    + +

    再仔細研究一下,我發現 apcupsd 不只能做到電力自行管理。在像斷電關機這種重要事件時, apcupsd 還會發信通知。所以人不在電腦旁邊的時候,因為斷電自動關機開機,網管也都會清楚得知。會通知的還包括: UPS 斷訊、電池損壞待修等等重大事件。幾乎所有網管需要知道、處理的重大事情,都會發信通知。這樣就不怕像之前那樣, UPS 壞得不明不白了。

    + +

    尤有甚者, apcupsd 還有好幾隻 CGI 程式,可以由網頁瀏覽監控,也就是說,網管從任何地方,即使是出國旅遊無法連線虛擬終端機,也都可以隨時遠端監看包括像目前市電電壓、 UPS 負載、電池電量、剩餘時間等等。

    + +

    這真的是太酷了。幾乎我所有想得到的需求, apcupsd 都可以辦得到。我已經想不到什麼問題了。我不知道 Network UPS Tools 能不能做到這些。不過到這裏我覺得,能夠買 APCUPS ,實在是太幸福了。果然是世界第一品牌啊~雖然九千五確實很貴,但是很值得。

    + +

    不過 Debianapcupsd 套件需要安裝 libsnmp ,會跟我自己安裝的 Net-SNMP 相衝。其實我只有一台用序列埠線管理的 UPS ,沒有用網路 SNMPUPS ,編譯的時候根本不需要連結 SNMP 函式庫。所以我還是捨棄了 Debianapcupsd 套件,移除以後,自己下載原始碼來編譯、安裝。

    + +

    自行編譯的時候,我發現 apcupsdDebian 上編譯時,連接埠自動由 3551 改用 6543 。我不是很瞭解,上網查了一下,發現以前 Debian 確實是用連接埠 6543 跑 apcupsd 。不過這已經是很久以前的事了,在 apcupsd 正式向 IANA 註冊到了連接埠 3551 後, 2004 年有人在 Debian 上提出修正,也已經修正好了。我也寫了一個簡單的修補傳上 apcupsd-users 通訊,取消掉 Debian 自動設定連接簿 6543 。下一版 apcupsd 應該會修正好吧。

    + +

    我自己也寫了一個簡單的程式,取得電壓和負載,給 MRTG 定期搜集、監控、繪圖,以取得長期的電壓和負載變化。

    + +

    安裝了新的 UPS ,並得以監控後,我才知道,家裏的市電真的很不穩定,常常有一、兩秒的瞬斷。只是因為時間很短馬上就恢復,電腦沒有因而斷訊,所以沒有察覺。嚴重時甚至一天兩、三次。電壓也不穩定,常常掉到 105 伏特以下,讓 UPS 切為電池供電穩壓。其實台灣的市電應該是 110 伏特,美國的市電是 120 伏特, APCUPS 也是以 120 伏特電力輸出設計的,中間其實差了 10 伏特。對 120 伏特而言,電力掉到 105 伏特以下等於掉了 15 伏特,的確已經是低電壓的異常狀態了。可是對 110 伏特而言, 105 伏特只掉了 5 伏特,其實還算正常起伏。為避免 UPS 穩壓切得太頻繁,減損 UPS 壽命,我打電話給 APC 後,依照 APC 工程人員的建議,調整 EEPROM 將穩壓下限調到最低值 97 伏特。其實這也可以用 apcupsd 來調整,不需要用到 PowerChute 。這真是太酷了~

    + +

    我也把 apcupsd 裝到公司。畢竟公司的 UPS 其實也一直沒有管理,趁此機會也一併設定好。不過公司的防火牆是用一台很舊的 Pentium MMX 來做的, BIOS 沒有斷電自動重開機的功能,所以斷電了也只能乖乖跑來公司開機。因為它是防火牆,它沒開的話,其它台開機了也沒有太大用處,也連不上外面網路。

    + +

    apcupsd 套件中有一個程式叫 powerflute ,可以在終端機下,以視窗選單模式顯示、調整 UPS 。老闆想到 powerflute 這名字可能和 PowerChute 有關。我沒跑過 PowerChute ,不過如果真是這樣,那 powerflute 可能是 PowerChute 的模擬程式, PowerChute 的畫面可能就像 powerflute 一樣。嗯。

    + +

    軟體管理設定好了以後,我再陸續看了幾篇 UPS 日常管理維護的知識。 UPS 不能接開機瞬間大量吃電的機器,否則可能會瞬間超載燒掉。機瞬間大量吃電的機器,包括雷射印表機,和電感性負載(如馬達等)。嗯,那我以前不就都做錯了。從公司搬家到這裏,雷射印表機放進機房接 UPS 到現都這麼多年了。那麼危險的事,我還做了這麼多年,嚇死我了。 1/5 星期六出門,就順便到公司把線路調整過來。幸好還有一個多餘的市電插座,讓雷射印表機可以直接接上去。

    + +

    除了雷射印表機,家用電器的電感性負載,主要是有馬達。像吹風機、電風扇等,都是禁忌。還有一般吃電瓦數大的,像電視、電冰箱、冷氣、電暖爐、熱水壺、烘衣機、微波爐等等,插上去馬上會超載,當然也是禁忌。最保險的做法,就是完全不要接家用電器。畢竟 UPS 是為電腦設計的,不是為家用電器設計的。

    + +

    一切穩定了以後,我寫了一封信給飛瑞,請他們回收處理報廢的舊 UPSUPS 的本體是密封鉛酸電池,必須要適當回收處理,不能直接丟棄,否則會造成很嚴重的環境污染。飛瑞回信請我把報廢的 UPS 寄回去,我找到原來的箱子,包一包寄過去。

    + +

    最後一個問題,是地線。

    + +

    一般家用市電,當初蓋房子的時候,接線多半是接兩孔的,沒有預留地線。可是沒有地線的話,怎麼看都很危險。最直接的危險就是我最怕的雷擊了。雷一打下來,大量的電無法從地線宣洩掉,再好的 UPS 也會馬上燒壞。雖然保護到後面的電腦,一台九千多塊的 UPS 化成灰,也是損失慘重。光用三孔轉兩孔的轉接頭轉接,只是掩耳盜鈴而已,完全沒有解決問題。我在網路上有看到,在一般公寓大樓沒辦法自行接地線的情況下,可以把地線接到窗框,釘死到窗框上。我問了 APC 的工程師,其實這樣沒有太大作用。因為窗框本身並沒有接地,周圍是水泥牆壁,水泥其實不導電。所以這樣只是把電宣洩到窗框上,能宣洩的電量有限,打雷時幫助不大。到頭來,還是要老老實實去接地線。

    + +

    打電話問學電機的老爸,老爸說一般家庭的總開關,一定都有接地,只要自己拉一條電線,鎖到總開關上就好了。這一點我也不清楚。而且接線我本來就不大擅長。我是敲鍵盤的師傅。所以我還是拜託房東請水電工。水電工來看了以後,證實總開關是一般家庭電源,沒有接地。就算把插頭由兩孔改成三孔,地線還是空的,其實和現在用轉接頭,也沒多大差別。

    + +

    唉。真的是這樣,也沒有辦法。只能祈導 APC UPS 有名的高品質,不會一打個雷就燒掉了。

    + +

    說到 APC UPS 的品質,和說明書放在一起的,有一張保證書,裏面保證如果有任何 APC UPS 保護下的產品,因電力問題而燒壞, APC 願意全額賠償。哇,我從來沒有看過這種保證,真是太酷了。 APC 不愧為 UPS 第一品牌啊~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 142 | + 143 | + 144 | + 145 | + 146 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0145.html.en.html b/htdocs/imacat/me/diary/0145.html.en.html new file mode 120000 index 0000000..8f5fa18 --- /dev/null +++ b/htdocs/imacat/me/diary/0145.html.en.html @@ -0,0 +1 @@ +0145.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0145.html.en.xhtml b/htdocs/imacat/me/diary/0145.html.en.xhtml new file mode 100644 index 0000000..713224f --- /dev/null +++ b/htdocs/imacat/me/diary/0145.html.en.xhtml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 145 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 145

    + +
    + +
    + +
    +
    2.5.’08. 2:48am.
    + +

    馬辣鴛鴦火鍋

    + +

    星期六中午和設計師有約,把前一天沒做好的挑染做完。早上很晚起來,起來後又忙著工作,弄到差一點遲到,沒來得及吃東西。做完頭髮後,一時忘了肚子餓,先去看漫畫。不過漫畫看到一半,就開始餓起來了。我突然想到,公館的馬辣鴛鴦火鍋,從前年 2006 年前開幕到現在,我還沒去吃過。

    + +

    當年馬辣以全世界第一的冰淇淋 Häagen-Dazs 冰淇淋吃到飽為號召,在競爭激烈的公館商圈造成大轟動,每天排隊排滿滿,不一星期前預約絕對吃不到。即使到兩年後的今天,公館滿是 Häagen-Dazs 冰淇淋、 Mövenpick 冰淇淋吃到飽的火鍋燒烤店,馬辣還是大排長龍,沒預約的,現場排隊至少一個半小時。做事總事臨時起意,對預約制沒輒的我,公館那麼多店家,馬辣是唯一我想吃又沒辦法吃得到的。

    + +

    不過今天下午,做完頭髮看完一本漫畫,看看時間下午三點半,肚子又餓。突然想到,現在不是用餐時間,去馬辣的話,應該可以不用排隊,至少不用排很久的隊吧。想著,下了決定,把漫畫塞上書架,就趕往馬辣。跟門口帶位的服務生報上人數以後,果然馬上有位置,終於吃到傳說中的馬辣鴛鴦火鍋了。

    + +

    鴛鴦火鍋

    + +

    沒錯,我不吃辣。正確應該說,我只能接受微辣,而且超討厭辣醬。這樣的我,一直跟麻辣鍋無緣。服務生問我要什麼鍋底的時候,我看著麻辣鍋底以外的三種不辣鍋底:蔬菜、泡菜和膠原蛋白。鴛鴦鍋有兩邊,我要選兩種鍋底。可是蔬菜、泡菜和膠原蛋白,我都沒有興趣,感覺上也不會特別好吃。我想到我吃第一次吃的餐廳的大原則:先吃招牌菜。我又往下看麻辣鍋。上面自傲的文字介紹,看起來馬辣的招牌就是麻辣鍋。唔,嗯。猶豫了半天,好吧,硬著頭皮,麻辣鍋就麻辣鍋吧。搭配比較特別的膠原蛋白鍋。只涮肉不喝湯的話,應該還吃得下吧。

    + +

    這是我第一次一個人吃麻辣鍋。以前都是和小招吃鴛鴦鍋,麻辣那一半給小招,我頂多在麻辣鍋裏涮一片肉試試味道。邊吃邊說話,吃得不專心,也不記得什麼味道。第一次一個人吃,而且還要努力吃。我夾了一塊肉進去涮,吃起來,嗯,一點小辣,不過味道還不錯。再試一片到膠原蛋白鍋。嗯,果然,在白湯裏涮沒有什麼特別的味道。比較起來,麻辣鍋涮起來味道豐富很多。難怪人家那麼愛吃麻辣鍋。我不敢用會吸湯汁的菜下去涮,鍋裏會吸湯汁的豆腐我也不敢吃。話雖如此,不知不覺間,我在麻辣鍋裏涮了一大半的肉。

    + +

    不過,味道豐富的麻辣湯頭,當然也是有缺點的。牛肉涮起來還好,馬辣的招牌肉霜降牛肉和安格斯黑牛肉,麻辣湯頭涮起來都非常好吃,清湯涮起來就什麼味道了。不過其他像小肥牛、小肥羊、豬五花、豬培根,涮了麻辣湯頭,原來的肉味都消失了,吃不出肉的原味來。湯汁味道太重,會把肉原本的美味遮蓋掉,也是一個缺點。

    + +

    吃飽了,當然就要開始吃 Häagen-Dazs 冰淇淋了。當年讓我吃一口就為之瘋狂的 Häagen-Dazs 萊姆葡萄冰淇淋,還有從小吃到大最愛的草莓冰淇淋,萊姆葡萄的味道還是超讚, Häagen-Dazs 的草莓冰淇淋也和杜老爺的不同水準。現在馬辣不只有 Häagen-Dazs 冰淇淋,還有 Mövenpick 冰淇淋,兩家世界第一、第二的冰淇淋吃到飽。不過提供的口味減半,原先提供 Häagen-Dazs 八種口味,現在變成 Häagen-DazsMövenpick 各四種口味。而且冰淇淋超硬,很難挖,用盡力氣去挖,反而沒什麼力氣享受冰淇淋的美味了。現在公館 Häagen-Dazs 冰淇淋、 Mövenpick 冰淇淋吃到飽的店家排排站,吃過好幾家後,感覺上也沒那麼讓人興奮了。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 143 | + 144 | + 145 | + 146 | + 147 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0145.html.zh-cn.html b/htdocs/imacat/me/diary/0145.html.zh-cn.html new file mode 120000 index 0000000..0ce8cf4 --- /dev/null +++ b/htdocs/imacat/me/diary/0145.html.zh-cn.html @@ -0,0 +1 @@ +0145.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0145.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0145.html.zh-cn.xhtml new file mode 100644 index 0000000..0fab51c --- /dev/null +++ b/htdocs/imacat/me/diary/0145.html.zh-cn.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百四十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百四十五

    + +
    + +
    + +
    +
    2.5.’08. 2:48am.
    + +

    马辣鸳鸯火锅

    + +

    星期六中午和设计师有约,把前一天没做好的挑染做完。早上很晚起来,起来后又忙著工作,弄到差一点迟到,没来得及吃东西。做完头发后,一时忘了肚子饿,先去看漫画。不过漫画看到一半,就开始饿起来了。我突然想到,公馆的马辣鸳鸯火锅,从前年 2006 年前开幕到现在,我还没去吃过。

    + +

    当年马辣以全世界第一的冰淇淋 Häagen-Dazs 冰淇淋吃到饱为号召,在竞争激烈的公馆商圈造成大轰动,每天排队排满满,不一星期前预约绝对吃不到。即使到两年后的今天,公馆满是 Häagen-Dazs 冰淇淋、 Mövenpick 冰淇淋吃到饱的火锅烧烤店,马辣还是大排长龙,没预约的,现场排队至少一个半小时。做事总事临时起意,对预约制没辄的我,公馆那么多店家,马辣是唯一我想吃又没办法吃得到的。

    + +

    不过今天下午,做完头发看完一本漫画,看看时间下午三点半,肚子又饿。突然想到,现在不是用餐时间,去马辣的话,应该可以不用排队,至少不用排很久的队吧。想著,下了决定,把漫画塞上书架,就赶往马辣。跟门口带位的服务生报上人数以后,果然马上有位置,终於吃到传说中的马辣鸳鸯火锅了。

    + +

    鸳鸯火锅

    + +

    没错,我不吃辣。正确应该说,我只能接受微辣,而且超讨厌辣酱。这样的我,一直跟麻辣锅无缘。服务生问我要什么锅底的时候,我看著麻辣锅底以外的三种不辣锅底:蔬菜、泡菜和胶原蛋白。鸳鸯锅有两边,我要选两种锅底。可是蔬菜、泡菜和胶原蛋白,我都没有兴趣,感觉上也不会特别好吃。我想到我吃第一次吃的餐厅的大原则:先吃招牌菜。我又往下看麻辣锅。上面自傲的文字介绍,看起来马辣的招牌就是麻辣锅。唔,嗯。犹豫了半天,好吧,硬著头皮,麻辣锅就麻辣锅吧。搭配比较特别的胶原蛋白锅。只涮肉不喝汤的话,应该还吃得下吧。

    + +

    这是我第一次一个人吃麻辣锅。以前都是和小招吃鸳鸯锅,麻辣那一半给小招,我顶多在麻辣锅里涮一片肉试试味道。边吃边说话,吃得不专心,也不记得什么味道。第一次一个人吃,而且还要努力吃。我夹了一块肉进去涮,吃起来,嗯,一点小辣,不过味道还不错。再试一片到胶原蛋白锅。嗯,果然,在白汤里涮没有什么特别的味道。比较起来,麻辣锅涮起来味道丰富很多。难怪人家那么爱吃麻辣锅。我不敢用会吸汤汁的菜下去涮,锅里会吸汤汁的豆腐我也不敢吃。话虽如此,不知不觉间,我在麻辣锅里涮了一大半的肉。

    + +

    不过,味道丰富的麻辣汤头,当然也是有缺点的。牛肉涮起来还好,马辣的招牌肉霜降牛肉和安格斯黑牛肉,麻辣汤头涮起来都非常好吃,清汤涮起来就什么味道了。不过其他像小肥牛、小肥羊、猪五花、猪培根,涮了麻辣汤头,原来的肉味都消失了,吃不出肉的原味来。汤汁味道太重,会把肉原本的美味遮盖掉,也是一个缺点。

    + +

    吃饱了,当然就要开始吃 Häagen-Dazs 冰淇淋了。当年让我吃一口就为之疯狂的 Häagen-Dazs 莱姆葡萄冰淇淋,还有从小吃到大最爱的草莓冰淇淋,莱姆葡萄的味道还是超赞, Häagen-Dazs 的草莓冰淇淋也和杜老爷的不同水准。现在马辣不只有 Häagen-Dazs 冰淇淋,还有 Mövenpick 冰淇淋,两家世界第一、第二的冰淇淋吃到饱。不过提供的口味减半,原先提供 Häagen-Dazs 八种口味,现在变成 Häagen-DazsMövenpick 各四种口味。而且冰淇淋超硬,很难挖,用尽力气去挖,反而没什么力气享受冰淇淋的美味了。现在公馆 Häagen-Dazs 冰淇淋、 Mövenpick 冰淇淋吃到饱的店家排排站,吃过好几家后,感觉上也没那么让人兴奋了。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 143 | + 144 | + 145 | + 146 | + 147 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0145.html.zh-tw.html b/htdocs/imacat/me/diary/0145.html.zh-tw.html new file mode 120000 index 0000000..880b85c --- /dev/null +++ b/htdocs/imacat/me/diary/0145.html.zh-tw.html @@ -0,0 +1 @@ +0145.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0145.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0145.html.zh-tw.xhtml new file mode 100644 index 0000000..960df68 --- /dev/null +++ b/htdocs/imacat/me/diary/0145.html.zh-tw.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百四十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百四十五

    + +
    + +
    + +
    +
    2.5.’08. 2:48am.
    + +

    馬辣鴛鴦火鍋

    + +

    星期六中午和設計師有約,把前一天沒做好的挑染做完。早上很晚起來,起來後又忙著工作,弄到差一點遲到,沒來得及吃東西。做完頭髮後,一時忘了肚子餓,先去看漫畫。不過漫畫看到一半,就開始餓起來了。我突然想到,公館的馬辣鴛鴦火鍋,從前年 2006 年前開幕到現在,我還沒去吃過。

    + +

    當年馬辣以全世界第一的冰淇淋 Häagen-Dazs 冰淇淋吃到飽為號召,在競爭激烈的公館商圈造成大轟動,每天排隊排滿滿,不一星期前預約絕對吃不到。即使到兩年後的今天,公館滿是 Häagen-Dazs 冰淇淋、 Mövenpick 冰淇淋吃到飽的火鍋燒烤店,馬辣還是大排長龍,沒預約的,現場排隊至少一個半小時。做事總事臨時起意,對預約制沒輒的我,公館那麼多店家,馬辣是唯一我想吃又沒辦法吃得到的。

    + +

    不過今天下午,做完頭髮看完一本漫畫,看看時間下午三點半,肚子又餓。突然想到,現在不是用餐時間,去馬辣的話,應該可以不用排隊,至少不用排很久的隊吧。想著,下了決定,把漫畫塞上書架,就趕往馬辣。跟門口帶位的服務生報上人數以後,果然馬上有位置,終於吃到傳說中的馬辣鴛鴦火鍋了。

    + +

    鴛鴦火鍋

    + +

    沒錯,我不吃辣。正確應該說,我只能接受微辣,而且超討厭辣醬。這樣的我,一直跟麻辣鍋無緣。服務生問我要什麼鍋底的時候,我看著麻辣鍋底以外的三種不辣鍋底:蔬菜、泡菜和膠原蛋白。鴛鴦鍋有兩邊,我要選兩種鍋底。可是蔬菜、泡菜和膠原蛋白,我都沒有興趣,感覺上也不會特別好吃。我想到我吃第一次吃的餐廳的大原則:先吃招牌菜。我又往下看麻辣鍋。上面自傲的文字介紹,看起來馬辣的招牌就是麻辣鍋。唔,嗯。猶豫了半天,好吧,硬著頭皮,麻辣鍋就麻辣鍋吧。搭配比較特別的膠原蛋白鍋。只涮肉不喝湯的話,應該還吃得下吧。

    + +

    這是我第一次一個人吃麻辣鍋。以前都是和小招吃鴛鴦鍋,麻辣那一半給小招,我頂多在麻辣鍋裏涮一片肉試試味道。邊吃邊說話,吃得不專心,也不記得什麼味道。第一次一個人吃,而且還要努力吃。我夾了一塊肉進去涮,吃起來,嗯,一點小辣,不過味道還不錯。再試一片到膠原蛋白鍋。嗯,果然,在白湯裏涮沒有什麼特別的味道。比較起來,麻辣鍋涮起來味道豐富很多。難怪人家那麼愛吃麻辣鍋。我不敢用會吸湯汁的菜下去涮,鍋裏會吸湯汁的豆腐我也不敢吃。話雖如此,不知不覺間,我在麻辣鍋裏涮了一大半的肉。

    + +

    不過,味道豐富的麻辣湯頭,當然也是有缺點的。牛肉涮起來還好,馬辣的招牌肉霜降牛肉和安格斯黑牛肉,麻辣湯頭涮起來都非常好吃,清湯涮起來就什麼味道了。不過其他像小肥牛、小肥羊、豬五花、豬培根,涮了麻辣湯頭,原來的肉味都消失了,吃不出肉的原味來。湯汁味道太重,會把肉原本的美味遮蓋掉,也是一個缺點。

    + +

    吃飽了,當然就要開始吃 Häagen-Dazs 冰淇淋了。當年讓我吃一口就為之瘋狂的 Häagen-Dazs 萊姆葡萄冰淇淋,還有從小吃到大最愛的草莓冰淇淋,萊姆葡萄的味道還是超讚, Häagen-Dazs 的草莓冰淇淋也和杜老爺的不同水準。現在馬辣不只有 Häagen-Dazs 冰淇淋,還有 Mövenpick 冰淇淋,兩家世界第一、第二的冰淇淋吃到飽。不過提供的口味減半,原先提供 Häagen-Dazs 八種口味,現在變成 Häagen-DazsMövenpick 各四種口味。而且冰淇淋超硬,很難挖,用盡力氣去挖,反而沒什麼力氣享受冰淇淋的美味了。現在公館 Häagen-Dazs 冰淇淋、 Mövenpick 冰淇淋吃到飽的店家排排站,吃過好幾家後,感覺上也沒那麼讓人興奮了。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 143 | + 144 | + 145 | + 146 | + 147 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0146.html.en.html b/htdocs/imacat/me/diary/0146.html.en.html new file mode 120000 index 0000000..31b5699 --- /dev/null +++ b/htdocs/imacat/me/diary/0146.html.en.html @@ -0,0 +1 @@ +0146.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0146.html.en.xhtml b/htdocs/imacat/me/diary/0146.html.en.xhtml new file mode 100644 index 0000000..f181280 --- /dev/null +++ b/htdocs/imacat/me/diary/0146.html.en.xhtml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 146 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 146

    + +
    + +
    + +
    +
    4.8.’08. 4:41pm.
    + +

    解題

    + +

    最近的我,一直沉迷在 CPAN 模組自動燒機測試之中。

    + +

    原本加入 CPAN 模組燒機測試的理由,是因為前兩年,我寫的 Locale::Maketext::Gettext 上傳到 CPAN 後,突然收到別人的燒機測試錯誤報告。為了瞭解到底是怎麼回事,我試著去重現自動燒機測試的環境,也順便測試別人上傳的 CPAN 模組。兩年下來,這成了我每日的固定工作,一下班,就開始測試今天新上傳的 CPAN 模組,日復一日。也算是在忙碌的工作外,對開放源始碼社群的一點小小的貢獻。

    + +

    最近兩個月,因為公司沒什麼事,加上 Perl 5.10.0 正式版終於出來了,為了讓 Perl 5.10.0 和現有模組間的相容性得到更多測試,我用 CPAN::Reporter 寫了一個新的燒機測試程式,把所有現存 CPAN 上的模組,又重新用 Perl 5.10.0 測試了一遍。邊測試,也邊改進我原來用 CPAN::YACSmoke 寫的測試程式。正好公司也不忙,在此同時,我也把原有測試時碰到的問題,一一處理,上 CPAN RT 回報無法用自動燒機測試回報的問題。

    + +

    摸著摸著,又是兩個月去了。不是忙回報測試,就是在看漫畫。不知道為什麼,就是不大提得起勁唸書。

    + +

    雖然我也從中得益不少:改進自動燒機測試程式,讓我玩出很多機器人程式自我監控的技巧。但我其實也很清楚,這件事本身,意義並沒有太大。終究,這一萬五千個模組,都是別人的模組。回報的過程我也發現,其實很多模組本身,作者都已經失聯經年了,不但信箱無此人,就算錯誤報告寄出去了,也多數石沉大海。就算收到回音,收到感謝,也只是心理滿足而已。這些畢竟是別人的模組,不是自己的成就。我也曾想過,說不定有一天有人會注意到我在做這些事,認可我的成就,邀請我進入開發核心團隊等等。但這畢竟只是自我滿足的妄想。開發系統需要的是創造力。除錯測試需要的是嚴格挑剔的精神,但跟創造力一點關係也沒有。

    + +

    就這樣,做著也不知道有沒有意義的事,虛度了好些日子。

    + +

    昨晚跟好久沒一起吃飯的阿光約吃飯。我也不知道該怎麼跟她提最近這漫無目的的生活。隨口說到我想先考考看 LPI 的證照。只是一直沒去找考古題而已,而且好像一年只有巡迴台灣一次而已。阿光告訴我,一年一次的是中文 LPI 考試,可是我不需要考中文。英文的話,只要上網報名、繳費,隨時都可以考。我好像抓到什麼。反正最近沒動力唸書,以我的能力, LPI 一級應該很好考。就當成考研究所前的短期目標,也比現在漫無目的的生活強。

    + +

    今天早上早起,出門前,順手在網路上查了一下 LPI 一級的考古題。考古題沒那麼好找,不過練習題倒是不少。做著做著,發現有些很簡單的事,我反而不會。像建帳號、刪帳號,我都是手動去改 /etc/passwd/etc/shadow ,從來沒有用過 useradduserdel ,所以這兩個指令完全不會用。一題一題做著、找答案。不過短短十題,卻突然讓我有一種很振奮、很懷念的感覺。

    + +

    突然間,我不想出門上班,想把線性代數課本拿出來唸。

    + +

    為什麼呢? Linux 的指令,和線性代數,和數學,毫無關係。可是做著做著,一股很懷念的振奮感,一口氣全部湧上來。想了一個中午,我才豁然明白。

    + +

    是啊,當初就是因為這樣,我才喜歡數學的。我喜歡解題。超喜歡解題。我喜歡上課的時候,一個人自己唸著老師在教的參考書,解著範例、練習題,和老師拼進度。拼著命催著自己解題。看著各式各樣的題目一題一題解開來,好像在征服著什麼一樣,感覺超棒的。就是這樣,我以為我喜歡數學。上了數學系,大學數學教的是理論,沒有參考書,沒有一堆習題。那是一個我不熟悉,我也無法理解的世界,雖然那才是真正的數學世界,不是高中生、國中生的,由解題堆砌起來的升學數學世界。

    + +

    所以我喜歡程式除錯,因為那也是一個一個的難題,等著我去解開來。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 144 | + 145 | + 146 | + 147 | + 148 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0146.html.zh-cn.html b/htdocs/imacat/me/diary/0146.html.zh-cn.html new file mode 120000 index 0000000..f72293f --- /dev/null +++ b/htdocs/imacat/me/diary/0146.html.zh-cn.html @@ -0,0 +1 @@ +0146.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0146.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0146.html.zh-cn.xhtml new file mode 100644 index 0000000..fbb6038 --- /dev/null +++ b/htdocs/imacat/me/diary/0146.html.zh-cn.xhtml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百四十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百四十六

    + +
    + +
    + +
    +
    4.8.’08. 4:41pm.
    + +

    解题

    + +

    最近的我,一直沉迷在 CPAN 模组自动烧机测试之中。

    + +

    原本加入 CPAN 模组烧机测试的理由,是因为前两年,我写的 Locale::Maketext::Gettext 上传到 CPAN 后,突然收到别人的烧机测试错误报告。为了了解到底是怎么回事,我试著去重现自动烧机测试的环境,也顺便测试别人上传的 CPAN 模组。两年下来,这成了我每日的固定工作,一下班,就开始测试今天新上传的 CPAN 模组,日复一日。也算是在忙碌的工作外,对开放源始码社群的一点小小的贡献。

    + +

    最近两个月,因为公司没什么事,加上 Perl 5.10.0 正式版终於出来了,为了让 Perl 5.10.0 和现有模组间的相容性得到更多测试,我用 CPAN::Reporter 写了一个新的烧机测试程式,把所有现存 CPAN 上的模组,又重新用 Perl 5.10.0 测试了一遍。边测试,也边改进我原来用 CPAN::YACSmoke 写的测试程式。正好公司也不忙,在此同时,我也把原有测试时碰到的问题,一一处理,上 CPAN RT 回报无法用自动烧机测试回报的问题。

    + +

    摸著摸著,又是两个月去了。不是忙回报测试,就是在看漫画。不知道为什么,就是不大提得起劲念书。

    + +

    虽然我也从中得益不少:改进自动烧机测试程式,让我玩出很多机器人程式自我监控的技巧。但我其实也很清楚,这件事本身,意义并没有太大。终究,这一万五千个模组,都是别人的模组。回报的过程我也发现,其实很多模组本身,作者都已经失联经年了,不但信箱无此人,就算错误报告寄出去了,也多数石沉大海。就算收到回音,收到感谢,也只是心理满足而已。这些毕竟是别人的模组,不是自己的成就。我也曾想过,说不定有一天有人会注意到我在做这些事,认可我的成就,邀请我进入开发核心团队等等。但这毕竟只是自我满足的妄想。开发系统需要的是创造力。除错测试需要的是严格挑剔的精神,但跟创造力一点关系也没有。

    + +

    就这样,做著也不知道有没有意义的事,虚度了好些日子。

    + +

    昨晚跟好久没一起吃饭的阿光约吃饭。我也不知道该怎么跟她提最近这漫无目的的生活。随口说到我想先考考看 LPI 的证照。只是一直没去找考古题而已,而且好像一年只有巡回台湾一次而已。阿光告诉我,一年一次的是中文 LPI 考试,可是我不需要考中文。英文的话,只要上网报名、缴费,随时都可以考。我好像抓到什么。反正最近没动力念书,以我的能力, LPI 一级应该很好考。就当成考研究所前的短期目标,也比现在漫无目的的生活强。

    + +

    今天早上早起,出门前,顺手在网路上查了一下 LPI 一级的考古题。考古题没那么好找,不过练习题倒是不少。做著做著,发现有些很简单的事,我反而不会。像建帐号、删帐号,我都是手动去改 /etc/passwd/etc/shadow ,从来没有用过 useradduserdel ,所以这两个指令完全不会用。一题一题做著、找答案。不过短短十题,却突然让我有一种很振奋、很怀念的感觉。

    + +

    突然间,我不想出门上班,想把线性代数课本拿出来念。

    + +

    为什么呢? Linux 的指令,和线性代数,和数学,毫无关系。可是做著做著,一股很怀念的振奋感,一口气全部涌上来。想了一个中午,我才豁然明白。

    + +

    是啊,当初就是因为这样,我才喜欢数学的。我喜欢解题。超喜欢解题。我喜欢上课的时候,一个人自己念著老师在教的参考书,解著范例、练习题,和老师拼进度。拼著命催著自己解题。看著各式各样的题目一题一题解开来,好像在征服著什么一样,感觉超棒的。就是这样,我以为我喜欢数学。上了数学系,大学数学教的是理论,没有参考书,没有一堆习题。那是一个我不熟悉,我也无法理解的世界,虽然那才是真正的数学世界,不是高中生、国中生的,由解题堆砌起来的升学数学世界。

    + +

    所以我喜欢程式除错,因为那也是一个一个的难题,等著我去解开来。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 144 | + 145 | + 146 | + 147 | + 148 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0146.html.zh-tw.html b/htdocs/imacat/me/diary/0146.html.zh-tw.html new file mode 120000 index 0000000..edb9784 --- /dev/null +++ b/htdocs/imacat/me/diary/0146.html.zh-tw.html @@ -0,0 +1 @@ +0146.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0146.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0146.html.zh-tw.xhtml new file mode 100644 index 0000000..ee8d0b7 --- /dev/null +++ b/htdocs/imacat/me/diary/0146.html.zh-tw.xhtml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百四十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百四十六

    + +
    + +
    + +
    +
    4.8.’08. 4:41pm.
    + +

    解題

    + +

    最近的我,一直沉迷在 CPAN 模組自動燒機測試之中。

    + +

    原本加入 CPAN 模組燒機測試的理由,是因為前兩年,我寫的 Locale::Maketext::Gettext 上傳到 CPAN 後,突然收到別人的燒機測試錯誤報告。為了瞭解到底是怎麼回事,我試著去重現自動燒機測試的環境,也順便測試別人上傳的 CPAN 模組。兩年下來,這成了我每日的固定工作,一下班,就開始測試今天新上傳的 CPAN 模組,日復一日。也算是在忙碌的工作外,對開放源始碼社群的一點小小的貢獻。

    + +

    最近兩個月,因為公司沒什麼事,加上 Perl 5.10.0 正式版終於出來了,為了讓 Perl 5.10.0 和現有模組間的相容性得到更多測試,我用 CPAN::Reporter 寫了一個新的燒機測試程式,把所有現存 CPAN 上的模組,又重新用 Perl 5.10.0 測試了一遍。邊測試,也邊改進我原來用 CPAN::YACSmoke 寫的測試程式。正好公司也不忙,在此同時,我也把原有測試時碰到的問題,一一處理,上 CPAN RT 回報無法用自動燒機測試回報的問題。

    + +

    摸著摸著,又是兩個月去了。不是忙回報測試,就是在看漫畫。不知道為什麼,就是不大提得起勁唸書。

    + +

    雖然我也從中得益不少:改進自動燒機測試程式,讓我玩出很多機器人程式自我監控的技巧。但我其實也很清楚,這件事本身,意義並沒有太大。終究,這一萬五千個模組,都是別人的模組。回報的過程我也發現,其實很多模組本身,作者都已經失聯經年了,不但信箱無此人,就算錯誤報告寄出去了,也多數石沉大海。就算收到回音,收到感謝,也只是心理滿足而已。這些畢竟是別人的模組,不是自己的成就。我也曾想過,說不定有一天有人會注意到我在做這些事,認可我的成就,邀請我進入開發核心團隊等等。但這畢竟只是自我滿足的妄想。開發系統需要的是創造力。除錯測試需要的是嚴格挑剔的精神,但跟創造力一點關係也沒有。

    + +

    就這樣,做著也不知道有沒有意義的事,虛度了好些日子。

    + +

    昨晚跟好久沒一起吃飯的阿光約吃飯。我也不知道該怎麼跟她提最近這漫無目的的生活。隨口說到我想先考考看 LPI 的證照。只是一直沒去找考古題而已,而且好像一年只有巡迴台灣一次而已。阿光告訴我,一年一次的是中文 LPI 考試,可是我不需要考中文。英文的話,只要上網報名、繳費,隨時都可以考。我好像抓到什麼。反正最近沒動力唸書,以我的能力, LPI 一級應該很好考。就當成考研究所前的短期目標,也比現在漫無目的的生活強。

    + +

    今天早上早起,出門前,順手在網路上查了一下 LPI 一級的考古題。考古題沒那麼好找,不過練習題倒是不少。做著做著,發現有些很簡單的事,我反而不會。像建帳號、刪帳號,我都是手動去改 /etc/passwd/etc/shadow ,從來沒有用過 useradduserdel ,所以這兩個指令完全不會用。一題一題做著、找答案。不過短短十題,卻突然讓我有一種很振奮、很懷念的感覺。

    + +

    突然間,我不想出門上班,想把線性代數課本拿出來唸。

    + +

    為什麼呢? Linux 的指令,和線性代數,和數學,毫無關係。可是做著做著,一股很懷念的振奮感,一口氣全部湧上來。想了一個中午,我才豁然明白。

    + +

    是啊,當初就是因為這樣,我才喜歡數學的。我喜歡解題。超喜歡解題。我喜歡上課的時候,一個人自己唸著老師在教的參考書,解著範例、練習題,和老師拼進度。拼著命催著自己解題。看著各式各樣的題目一題一題解開來,好像在征服著什麼一樣,感覺超棒的。就是這樣,我以為我喜歡數學。上了數學系,大學數學教的是理論,沒有參考書,沒有一堆習題。那是一個我不熟悉,我也無法理解的世界,雖然那才是真正的數學世界,不是高中生、國中生的,由解題堆砌起來的升學數學世界。

    + +

    所以我喜歡程式除錯,因為那也是一個一個的難題,等著我去解開來。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 144 | + 145 | + 146 | + 147 | + 148 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0147.html.en.html b/htdocs/imacat/me/diary/0147.html.en.html new file mode 120000 index 0000000..7ed8091 --- /dev/null +++ b/htdocs/imacat/me/diary/0147.html.en.html @@ -0,0 +1 @@ +0147.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0147.html.en.xhtml b/htdocs/imacat/me/diary/0147.html.en.xhtml new file mode 100644 index 0000000..8f7f196 --- /dev/null +++ b/htdocs/imacat/me/diary/0147.html.en.xhtml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 147 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 147

    + +
    + +
    + +
    +
    6.22.’08. 7:35am.
    + +

    Apple

    + +

    第一次見到 Apple ,就讓我說不出話。

    + +

    我們公司在公館,台大公館商圈的髮型沙龍,三步一家,五步一店,多到可怕,競爭也非常激烈。每天中午出去吃一趟飯,來回一趟,都要拿到好幾包面紙、折價券。這幾年我陸續去過的,就有:曼都、卿之森、貝詩、 亂剪、 iColorJ-plusA-Salon 等等。雖然都不差,但也沒有特別喜歡的店或設計師。

    + +

    平常為不製造垃圾,像這些面紙、折價券,我都儘量不收,不小心收下了,沒有特別理由,我也就丟了。去年年底,拿到一張誘髮的指定設計師折價券。我從來沒進去過公館誘髮,不過上面的設計師名字,引起我的注意: Nana

    + +

    我超愛矢沢あい,超愛矢沢あい的作品 NANA 。有人給自己取名 Nana ,我開始好奇,取這種名字的,會是什麼樣的人。

    + +

    那天下班,看看沒事,就拿著那張還沒到期的折價券,走進公館誘髮。一問之下,答案讓我扼腕: Nana 已經離職了。怎麼會這樣?店家要幫我介紹另一位設計師。我盤算要不要去 A-Salon 找上次做離子燙的 Dora ,可是現在走人不大好意思,而且上次 Dora 害我中午休息回去遲到,沒理由再回去找她。想著,還是坐下來等好了。等了一會,設計師來跟我打招呼,我一抬頭,驚訝得說不出話來。

    + +

    學‧生‧制‧服

    + +

    我還以為我眼花了。定下神來看,真的是高中學生制服,制服上還繡有名字。這是漫畫裏面才會出現的場景。個子小小的設計師自我介紹,她叫 Apple ,不好意思地說,她剛從學校下課趕來,來不及換衣服。

    + +

    這就是我和 Apple 的第一次接觸。

    + +

    邊洗頭,邊跟 Apple 聊天。小小的 Apple 超可愛,講話很快又很有趣。她今年 18 歲,高一。唔,現在的設計師年紀越來越小了。她一頭堆高、很漂亮的大長髮,讓人印象很深。我公館走過那麼多家髮型沙龍,大多數的設計師,都是彼此做頭髮。因為常常做新造型,大家到最後都被剪成了短髮。我第一次碰到長髮的設計師,長到跟我一樣過腰。而且 Apple 的頭髮是自己做的,做得很漂亮,像自己的活招牌一樣。

    + +

    那天聊得很高興,跟她拿了名片。回去,我就決定:嗯,就是她了。能夠把我的長頭髮弄得很漂亮的設計師,同樣是過腰長髮的 Apple ,大概沒問題吧。

    + +

    過兩個禮拜,我回去找 Apple ,請她幫我染髮。我留長頭髮一部份也是懶。長期不去吹染整,雖然完全沒有變化,但髮質很細很好。雖然想變個樣子,但怕設計師不注意剪短燙壞了,一直不敢下定決心。直到碰到 Apple ,才下定決心給她染。如果給同樣過腰長髮的 Apple 處理,應該沒有問題吧。

    + +

    反正我豁出去了,染壞就算了。我一直想要染頭髮,遲早都得睹一把。

    + +

    坐上椅子,跟 Apple 討論髮色。我一直想染藍色,雖然自己也知道藍色不好染。 Apple 聽完我的想法後想想,跟我建議挑染紅色,她幫我做隱藏式挑染。我猶豫了很久,好吧,通通豁出去了,就完全交給 Apple 吧。我像待宰的羔羊般任憑 Apple 宰割,邊聊天,邊擔心不知道染起來好不好看。

    + +

    染好了,一照鏡子:天哪!真是出乎意料地好看。隱藏的亮紅頭髮從裏面透出來,平常從外面看不到,可是頭髮一擺動就會秀出來。真是太漂亮了!

    + +

    Apple 接著教我護髮。之前燙離子燙,設計師也有教我護髮,不過很麻煩,洗完頭、護完髮還要靜待五分鐘再洗掉,所以做兩個禮拜我就放棄了。 Apple 教我先洗頭、護髮,再洗澡,洗完澡正好差不多五分鐘,可以沖掉護髮。對耶,我怎麼沒想到呢?回家照著做,果然就不麻煩了。 Apple 也教我洗完頭要吹乾。我原來也嫌吹頭髮麻煩,這次我留意 Apple 幫我吹乾的動作,回家摸索了一個禮拜,發現趁頭髮濕的時候梳開,再吹乾,是最好的。吹乾後,頭髮完全不打結,超滑順的~

    + +

    我平常睡覺,頭髮都放左側。也是那一陣子,有一次感冒了,睡醒脖子酸痛很難過,想到睡覺頭不自覺都偏右邊(頭髮的另一邊),改折放頭上。隔天頭痛果然好了,早上去公司,同事問我是不是去洗頭,我才注意到頭髮變得很順很漂亮。原來如此,頭髮放到上面,就不會因為睡覺翻身而打結了。

    + +

    而且,我還發現,頭髮變順、少打結後,就不容易掉頭髮。以前我頭髮很容易掉,家裏到處都是頭髮,被小招笑是髮魔。現在只有剛洗完要梳開時會扯掉一些,平常就很少掉頭髮了。我問 AppleApple 也說,打結會給頭髮壓力,梳開頭髮的壓力會比較小。

    + +

    經過林林總總的改變後,我得到一頭又順又漂亮的頭髮。漂亮的隱藏式紅色挑染,打結不見了,頭髮超柔順,燙髮後受損也沒有很嚴重。真是太高興了。

    + +

    從此,我就信了 Apple 教了。個子小小,整天打扮得超勁爆超可愛的 Apple ,在我眼中,好像有不可思議的魔法一樣。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 145 | + 146 | + 147 | + 148 | + 149 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0147.html.zh-cn.html b/htdocs/imacat/me/diary/0147.html.zh-cn.html new file mode 120000 index 0000000..1b340c8 --- /dev/null +++ b/htdocs/imacat/me/diary/0147.html.zh-cn.html @@ -0,0 +1 @@ +0147.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0147.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0147.html.zh-cn.xhtml new file mode 100644 index 0000000..25ace05 --- /dev/null +++ b/htdocs/imacat/me/diary/0147.html.zh-cn.xhtml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百四十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百四十七

    + +
    + +
    + +
    +
    6.22.’08. 7:35am.
    + +

    Apple

    + +

    第一次见到 Apple ,就让我说不出话。

    + +

    我们公司在公馆,台大公馆商圈的发型沙龙,三步一家,五步一店,多到可怕,竞争也非常激烈。每天中午出去吃一趟饭,来回一趟,都要拿到好几包面纸、折价券。这几年我陆续去过的,就有:曼都、卿之森、贝诗、 乱剪、 iColorJ-plusA-Salon 等等。虽然都不差,但也没有特别喜欢的店或设计师。

    + +

    平常为不制造垃圾,像这些面纸、折价券,我都尽量不收,不小心收下了,没有特别理由,我也就丢了。去年年底,拿到一张诱发的指定设计师折价券。我从来没进去过公馆诱发,不过上面的设计师名字,引起我的注意: Nana

    + +

    我超爱矢沢あい,超爱矢沢あい的作品 NANA 。有人给自己取名 Nana ,我开始好奇,取这种名字的,会是什么样的人。

    + +

    那天下班,看看没事,就拿著那张还没到期的折价券,走进公馆诱发。一问之下,答案让我扼腕: Nana 已经离职了。怎么会这样?店家要帮我介绍另一位设计师。我盘算要不要去 A-Salon 找上次做离子烫的 Dora ,可是现在走人不大好意思,而且上次 Dora 害我中午休息回去迟到,没理由再回去找她。想著,还是坐下来等好了。等了一会,设计师来跟我打招呼,我一抬头,惊讶得说不出话来。

    + +

    学・生・制・服

    + +

    我还以为我眼花了。定下神来看,真的是高中学生制服,制服上还绣有名字。这是漫画里面才会出现的场景。个子小小的设计师自我介绍,她叫 Apple ,不好意思地说,她刚从学校下课赶来,来不及换衣服。

    + +

    这就是我和 Apple 的第一次接触。

    + +

    边洗头,边跟 Apple 聊天。小小的 Apple 超可爱,讲话很快又很有趣。她今年 18 岁,高一。唔,现在的设计师年纪越来越小了。她一头堆高、很漂亮的大长发,让人印象很深。我公馆走过那么多家发型沙龙,大多数的设计师,都是彼此做头发。因为常常做新造型,大家到最后都被剪成了短发。我第一次碰到长发的设计师,长到跟我一样过腰。而且 Apple 的头发是自己做的,做得很漂亮,像自己的活招牌一样。

    + +

    那天聊得很高兴,跟她拿了名片。回去,我就决定:嗯,就是她了。能够把我的长头发弄得很漂亮的设计师,同样是过腰长发的 Apple ,大概没问题吧。

    + +

    过两个礼拜,我回去找 Apple ,请她帮我染发。我留长头发一部份也是懒。长期不去吹染整,虽然完全没有变化,但发质很细很好。虽然想变个样子,但怕设计师不注意剪短烫坏了,一直不敢下定决心。直到碰到 Apple ,才下定决心给她染。如果给同样过腰长发的 Apple 处理,应该没有问题吧。

    + +

    反正我豁出去了,染坏就算了。我一直想要染头发,迟早都得睹一把。

    + +

    坐上椅子,跟 Apple 讨论发色。我一直想染蓝色,虽然自己也知道蓝色不好染。 Apple 听完我的想法后想想,跟我建议挑染红色,她帮我做隐藏式挑染。我犹豫了很久,好吧,通通豁出去了,就完全交给 Apple 吧。我像待宰的羔羊般任凭 Apple 宰割,边聊天,边担心不知道染起来好不好看。

    + +

    染好了,一照镜子:天哪!真是出乎意料地好看。隐藏的亮红头发从里面透出来,平常从外面看不到,可是头发一摆动就会秀出来。真是太漂亮了!

    + +

    Apple 接著教我护发。之前烫离子烫,设计师也有教我护发,不过很麻烦,洗完头、护完发还要静待五分钟再洗掉,所以做两个礼拜我就放弃了。 Apple 教我先洗头、护发,再洗澡,洗完澡正好差不多五分钟,可以冲掉护发。对耶,我怎么没想到呢?回家照著做,果然就不麻烦了。 Apple 也教我洗完头要吹干。我原来也嫌吹头发麻烦,这次我留意 Apple 帮我吹干的动作,回家摸索了一个礼拜,发现趁头发湿的时候梳开,再吹干,是最好的。吹干后,头发完全不打结,超滑顺的~

    + +

    我平常睡觉,头发都放左侧。也是那一阵子,有一次感冒了,睡醒脖子酸痛很难过,想到睡觉头不自觉都偏右边(头发的另一边),改折放头上。隔天头痛果然好了,早上去公司,同事问我是不是去洗头,我才注意到头发变得很顺很漂亮。原来如此,头发放到上面,就不会因为睡觉翻身而打结了。

    + +

    而且,我还发现,头发变顺、少打结后,就不容易掉头发。以前我头发很容易掉,家里到处都是头发,被小招笑是发魔。现在只有刚洗完要梳开时会扯掉一些,平常就很少掉头发了。我问 AppleApple 也说,打结会给头发压力,梳开头发的压力会比较小。

    + +

    经过林林总总的改变后,我得到一头又顺又漂亮的头发。漂亮的隐藏式红色挑染,打结不见了,头发超柔顺,烫发后受损也没有很严重。真是太高兴了。

    + +

    从此,我就信了 Apple 教了。个子小小,整天打扮得超劲爆超可爱的 Apple ,在我眼中,好像有不可思议的魔法一样。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 145 | + 146 | + 147 | + 148 | + 149 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0147.html.zh-tw.html b/htdocs/imacat/me/diary/0147.html.zh-tw.html new file mode 120000 index 0000000..8e691bc --- /dev/null +++ b/htdocs/imacat/me/diary/0147.html.zh-tw.html @@ -0,0 +1 @@ +0147.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0147.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0147.html.zh-tw.xhtml new file mode 100644 index 0000000..16e43db --- /dev/null +++ b/htdocs/imacat/me/diary/0147.html.zh-tw.xhtml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百四十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百四十七

    + +
    + +
    + +
    +
    6.22.’08. 7:35am.
    + +

    Apple

    + +

    第一次見到 Apple ,就讓我說不出話。

    + +

    我們公司在公館,台大公館商圈的髮型沙龍,三步一家,五步一店,多到可怕,競爭也非常激烈。每天中午出去吃一趟飯,來回一趟,都要拿到好幾包面紙、折價券。這幾年我陸續去過的,就有:曼都、卿之森、貝詩、 亂剪、 iColorJ-plusA-Salon 等等。雖然都不差,但也沒有特別喜歡的店或設計師。

    + +

    平常為不製造垃圾,像這些面紙、折價券,我都儘量不收,不小心收下了,沒有特別理由,我也就丟了。去年年底,拿到一張誘髮的指定設計師折價券。我從來沒進去過公館誘髮,不過上面的設計師名字,引起我的注意: Nana

    + +

    我超愛矢沢あい,超愛矢沢あい的作品 NANA 。有人給自己取名 Nana ,我開始好奇,取這種名字的,會是什麼樣的人。

    + +

    那天下班,看看沒事,就拿著那張還沒到期的折價券,走進公館誘髮。一問之下,答案讓我扼腕: Nana 已經離職了。怎麼會這樣?店家要幫我介紹另一位設計師。我盤算要不要去 A-Salon 找上次做離子燙的 Dora ,可是現在走人不大好意思,而且上次 Dora 害我中午休息回去遲到,沒理由再回去找她。想著,還是坐下來等好了。等了一會,設計師來跟我打招呼,我一抬頭,驚訝得說不出話來。

    + +

    學‧生‧制‧服

    + +

    我還以為我眼花了。定下神來看,真的是高中學生制服,制服上還繡有名字。這是漫畫裏面才會出現的場景。個子小小的設計師自我介紹,她叫 Apple ,不好意思地說,她剛從學校下課趕來,來不及換衣服。

    + +

    這就是我和 Apple 的第一次接觸。

    + +

    邊洗頭,邊跟 Apple 聊天。小小的 Apple 超可愛,講話很快又很有趣。她今年 18 歲,高一。唔,現在的設計師年紀越來越小了。她一頭堆高、很漂亮的大長髮,讓人印象很深。我公館走過那麼多家髮型沙龍,大多數的設計師,都是彼此做頭髮。因為常常做新造型,大家到最後都被剪成了短髮。我第一次碰到長髮的設計師,長到跟我一樣過腰。而且 Apple 的頭髮是自己做的,做得很漂亮,像自己的活招牌一樣。

    + +

    那天聊得很高興,跟她拿了名片。回去,我就決定:嗯,就是她了。能夠把我的長頭髮弄得很漂亮的設計師,同樣是過腰長髮的 Apple ,大概沒問題吧。

    + +

    過兩個禮拜,我回去找 Apple ,請她幫我染髮。我留長頭髮一部份也是懶。長期不去吹染整,雖然完全沒有變化,但髮質很細很好。雖然想變個樣子,但怕設計師不注意剪短燙壞了,一直不敢下定決心。直到碰到 Apple ,才下定決心給她染。如果給同樣過腰長髮的 Apple 處理,應該沒有問題吧。

    + +

    反正我豁出去了,染壞就算了。我一直想要染頭髮,遲早都得睹一把。

    + +

    坐上椅子,跟 Apple 討論髮色。我一直想染藍色,雖然自己也知道藍色不好染。 Apple 聽完我的想法後想想,跟我建議挑染紅色,她幫我做隱藏式挑染。我猶豫了很久,好吧,通通豁出去了,就完全交給 Apple 吧。我像待宰的羔羊般任憑 Apple 宰割,邊聊天,邊擔心不知道染起來好不好看。

    + +

    染好了,一照鏡子:天哪!真是出乎意料地好看。隱藏的亮紅頭髮從裏面透出來,平常從外面看不到,可是頭髮一擺動就會秀出來。真是太漂亮了!

    + +

    Apple 接著教我護髮。之前燙離子燙,設計師也有教我護髮,不過很麻煩,洗完頭、護完髮還要靜待五分鐘再洗掉,所以做兩個禮拜我就放棄了。 Apple 教我先洗頭、護髮,再洗澡,洗完澡正好差不多五分鐘,可以沖掉護髮。對耶,我怎麼沒想到呢?回家照著做,果然就不麻煩了。 Apple 也教我洗完頭要吹乾。我原來也嫌吹頭髮麻煩,這次我留意 Apple 幫我吹乾的動作,回家摸索了一個禮拜,發現趁頭髮濕的時候梳開,再吹乾,是最好的。吹乾後,頭髮完全不打結,超滑順的~

    + +

    我平常睡覺,頭髮都放左側。也是那一陣子,有一次感冒了,睡醒脖子酸痛很難過,想到睡覺頭不自覺都偏右邊(頭髮的另一邊),改折放頭上。隔天頭痛果然好了,早上去公司,同事問我是不是去洗頭,我才注意到頭髮變得很順很漂亮。原來如此,頭髮放到上面,就不會因為睡覺翻身而打結了。

    + +

    而且,我還發現,頭髮變順、少打結後,就不容易掉頭髮。以前我頭髮很容易掉,家裏到處都是頭髮,被小招笑是髮魔。現在只有剛洗完要梳開時會扯掉一些,平常就很少掉頭髮了。我問 AppleApple 也說,打結會給頭髮壓力,梳開頭髮的壓力會比較小。

    + +

    經過林林總總的改變後,我得到一頭又順又漂亮的頭髮。漂亮的隱藏式紅色挑染,打結不見了,頭髮超柔順,燙髮後受損也沒有很嚴重。真是太高興了。

    + +

    從此,我就信了 Apple 教了。個子小小,整天打扮得超勁爆超可愛的 Apple ,在我眼中,好像有不可思議的魔法一樣。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 145 | + 146 | + 147 | + 148 | + 149 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0148.html.en.html b/htdocs/imacat/me/diary/0148.html.en.html new file mode 120000 index 0000000..884642f --- /dev/null +++ b/htdocs/imacat/me/diary/0148.html.en.html @@ -0,0 +1 @@ +0148.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0148.html.en.xhtml b/htdocs/imacat/me/diary/0148.html.en.xhtml new file mode 100644 index 0000000..36434f1 --- /dev/null +++ b/htdocs/imacat/me/diary/0148.html.en.xhtml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 148 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 148

    + +
    + +
    + +
    +
    9.9.’08. 5:20pm.
    + +

    暮蟬悲鳴時 ひぐらしのなく頃に

    + +

    昨天終於把暮蟬悲鳴時漫畫借回來看了。借回來看的是外傳鬼曝編

    + +

    之前就有聽說,暮蟬悲鳴時是部很棒的恐怖漫畫。不過好看的漫畫很多,輪著看也不知要到何年何月。昨天下班前去出租店,終於把暮蟬悲鳴時借回來看了。

    + +

    回家後一直忙,而且星期一晚上有CSI犯罪現場,再加上重疊的詐欺遊戲完結篇,忙到可以坐下來看的時候,已經半夜兩點多了。

    + +

    半夜看恐怖漫畫,實在…嗯…

    + +

    我已經很久沒有這種毛骨聳然的感覺了。上一次感到恐怖,是七夜怪談的時候了。自從十多年前在春暉電影台上班兩個月,因為時值鬼月,被強迫連著看了一堆 B 級爛恐怖片以後,我就對恐怖片免疫了。那之前我雖然不怕恐怖片,可是能不要看還是儘量不要看,對心臟不好。可是連看了一個月的 B 級爛片,像假模特兒人頭的塑膠人頭滿天飛,還排成一排放在地上,血亂亂灑,看多這種白癡裝恐怖的爛鏡頭以後,就對恐怖片免疫了。

    + +

    可是,暮蟬悲鳴時實在是…嗯…讓我秋天的半夜裏,感到一股透骨的寒意。像同人誌、養成遊戲般常見的可愛畫風,快樂又平凡的日常生活,卻不知不覺間慢慢崩解的恐怖感。看完之後就跑去睡了,晚上沒有睡不著覺,也沒有做惡夢,早上醒來,卻還是感到一股沉重的寒意壓在心裏。

    + +

    雖然這樣講很奇怪,但真的是太棒了。應該可以稱得上經典吧。即使是恐怖漫畫大師伊藤潤二的經典富江系列,都沒有辦法給我這種透骨發寒的恐怖感。原作是同人遊戲。同人遊戲耶!又是一種我不熟悉、非傳統的創作媒體,同人、非商業的集體創作,創作媒體也不是傳統的小說、漫畫、動畫、電視、電影、廣播劇、舞台劇等等傳統創作媒體,真的是太了不起了。

    + +

    早上跟同事聊,上網查了查,才知道原來我昨天看的是外傳鬼曝編。今天中午去漫畫出租店,看了正篇的祟殺編暮蟬悲鳴時每一篇都是上下兩集,在台灣正篇已經出版了鬼隱編綿流編祟殺編三篇,外傳則出了鬼曝編一篇。今天晚上,應該就可以看完了。

    + +

    還有暮蟬悲鳴時的真人電影版,年中已經出了。好想看,不知道在台灣,找不找得到有中文字幕的版本。原作的同人遊戲,網路上有中文化版,有點期待。

    + +
    + +
    + +
    +
    7.24.’08. 12:04pm.
    + +

    海海人生

    + +

    這兩天又把陳盈潔的海海人生翻出來聽。

    + +

    很久沒唱歌,最近又想起幾首很經典的老歌。細細吟詠歌詞後,有不少新的體會。

    + +

    我之前從來沒有仔細聽過、唱過陳盈潔的海海人生。這兩天不自覺地吟詠起來,於是上網去找它的 MP3 和歌詞。仔細聽了、唱了以後,發現海海人生其實是一首淡淡哀愁的歌,海海人生的開闊背後,是對人生無解的悲歡分合的了悟。海海人生不是開懷笑唱的歌,而是懷抱對人生的深刻體悟,淡淡輕唱的歌。

    + +

    海海人生,說來容易,唱來輕鬆。然而,要唱出阮會歡喜有緣你作伴 要離開笑笑阮沒牽掛,又需要何等的人生領悟呢?

    + +
    +

    海海人生

    + +
    曲︰張國榮 詞︰娃娃
    + +
    人說這心情 罕罕罕罕卡快活
    +不通太陰沈 想著會驚
    +有人真古意 定定嘛是有人變卦
    +這人情怎樣才看會破
    +
    +人說這人生 海海海海路好行
    +不通回頭望 望著會茫
    +有人愛著阮 偏偏阮愛的是別人
    +這情債怎樣計較輸贏
    +
    +輕輕鬆鬆人生路途阮來行
    +無人是應該永遠孤單
    +阮會歡喜有緣你作伴
    +要離開笑笑阮沒牽掛
    +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 146 | + 147 | + 148 | + 149 | + 150 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0148.html.zh-cn.html b/htdocs/imacat/me/diary/0148.html.zh-cn.html new file mode 120000 index 0000000..360b7ad --- /dev/null +++ b/htdocs/imacat/me/diary/0148.html.zh-cn.html @@ -0,0 +1 @@ +0148.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0148.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0148.html.zh-cn.xhtml new file mode 100644 index 0000000..6d5dce0 --- /dev/null +++ b/htdocs/imacat/me/diary/0148.html.zh-cn.xhtml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百四十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百四十八

    + +
    + +
    + +
    +
    9.9.’08. 5:20pm.
    + +

    暮蝉悲鸣时 ひぐらしのなく顷に

    + +

    昨天终於把暮蝉悲鸣时漫画借回来看了。借回来看的是外传鬼曝编

    + +

    之前就有听说,暮蝉悲鸣时是部很棒的恐怖漫画。不过好看的漫画很多,轮著看也不知要到何年何月。昨天下班前去出租店,终於把暮蝉悲鸣时借回来看了。

    + +

    回家后一直忙,而且星期一晚上有CSI犯罪现场,再加上重叠的诈欺游戏完结篇,忙到可以坐下来看的时候,已经半夜两点多了。

    + +

    半夜看恐怖漫画,实在…嗯…

    + +

    我已经很久没有这种毛骨耸然的感觉了。上一次感到恐怖,是七夜怪谈的时候了。自从十多年前在春晖电影台上班两个月,因为时值鬼月,被强迫连著看了一堆 B 级烂恐怖片以后,我就对恐怖片免疫了。那之前我虽然不怕恐怖片,可是能不要看还是尽量不要看,对心脏不好。可是连看了一个月的 B 级烂片,像假模特儿人头的塑胶人头满天飞,还排成一排放在地上,血乱乱洒,看多这种白痴装恐怖的烂镜头以后,就对恐怖片免疫了。

    + +

    可是,暮蝉悲鸣时实在是…嗯…让我秋天的半夜里,感到一股透骨的寒意。像同人志、养成游戏般常见的可爱画风,快乐又平凡的日常生活,却不知不觉间慢慢崩解的恐怖感。看完之后就跑去睡了,晚上没有睡不著觉,也没有做恶梦,早上醒来,却还是感到一股沉重的寒意压在心里。

    + +

    虽然这样讲很奇怪,但真的是太棒了。应该可以称得上经典吧。即使是恐怖漫画大师伊藤润二的经典富江系列,都没有办法给我这种透骨发寒的恐怖感。原作是同人游戏。同人游戏耶!又是一种我不熟悉、非传统的创作媒体,同人、非商业的集体创作,创作媒体也不是传统的小说、漫画、动画、电视、电影、广播剧、舞台剧等等传统创作媒体,真的是太了不起了。

    + +

    早上跟同事聊,上网查了查,才知道原来我昨天看的是外传鬼曝编。今天中午去漫画出租店,看了正篇的祟杀编暮蝉悲鸣时每一篇都是上下两集,在台湾正篇已经出版了鬼隐编绵流编祟杀编三篇,外传则出了鬼曝编一篇。今天晚上,应该就可以看完了。

    + +

    还有暮蝉悲鸣时的真人电影版,年中已经出了。好想看,不知道在台湾,找不找得到有中文字幕的版本。原作的同人游戏,网路上有中文化版,有点期待。

    + +
    + +
    + +
    +
    7.24.’08. 12:04pm.
    + +

    海海人生

    + +

    这两天又把陈盈洁的海海人生翻出来听。

    + +

    很久没唱歌,最近又想起几首很经典的老歌。细细吟咏歌词后,有不少新的体会。

    + +

    我之前从来没有仔细听过、唱过陈盈洁的海海人生。这两天不自觉地吟咏起来,於是上网去找它的 MP3 和歌词。仔细听了、唱了以后,发现海海人生其实是一首淡淡哀愁的歌,海海人生的开阔背后,是对人生无解的悲欢分合的了悟。海海人生不是开怀笑唱的歌,而是怀抱对人生的深刻体悟,淡淡轻唱的歌。

    + +

    海海人生,说来容易,唱来轻松。然而,要唱出阮会欢喜有缘你作伴 要离开笑笑阮没牵挂,又需要何等的人生领悟呢?

    + +
    +

    海海人生

    + +
    曲∶张国荣 词∶娃娃
    + +
    人说这心情 罕罕罕罕卡快活
    +不通太阴沈 想著会惊
    +有人真古意 定定嘛是有人变卦
    +这人情怎样才看会破
    +
    +人说这人生 海海海海路好行
    +不通回头望 望著会茫
    +有人爱著阮 偏偏阮爱的是别人
    +这情债怎样计较输赢
    +
    +轻轻松松人生路途阮来行
    +无人是应该永远孤单
    +阮会欢喜有缘你作伴
    +要离开笑笑阮没牵挂
    +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 146 | + 147 | + 148 | + 149 | + 150 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0148.html.zh-tw.html b/htdocs/imacat/me/diary/0148.html.zh-tw.html new file mode 120000 index 0000000..192719a --- /dev/null +++ b/htdocs/imacat/me/diary/0148.html.zh-tw.html @@ -0,0 +1 @@ +0148.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0148.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0148.html.zh-tw.xhtml new file mode 100644 index 0000000..4f12713 --- /dev/null +++ b/htdocs/imacat/me/diary/0148.html.zh-tw.xhtml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百四十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百四十八

    + +
    + +
    + +
    +
    9.9.’08. 5:20pm.
    + +

    暮蟬悲鳴時 ひぐらしのなく頃に

    + +

    昨天終於把暮蟬悲鳴時漫畫借回來看了。借回來看的是外傳鬼曝編

    + +

    之前就有聽說,暮蟬悲鳴時是部很棒的恐怖漫畫。不過好看的漫畫很多,輪著看也不知要到何年何月。昨天下班前去出租店,終於把暮蟬悲鳴時借回來看了。

    + +

    回家後一直忙,而且星期一晚上有CSI犯罪現場,再加上重疊的詐欺遊戲完結篇,忙到可以坐下來看的時候,已經半夜兩點多了。

    + +

    半夜看恐怖漫畫,實在…嗯…

    + +

    我已經很久沒有這種毛骨聳然的感覺了。上一次感到恐怖,是七夜怪談的時候了。自從十多年前在春暉電影台上班兩個月,因為時值鬼月,被強迫連著看了一堆 B 級爛恐怖片以後,我就對恐怖片免疫了。那之前我雖然不怕恐怖片,可是能不要看還是儘量不要看,對心臟不好。可是連看了一個月的 B 級爛片,像假模特兒人頭的塑膠人頭滿天飛,還排成一排放在地上,血亂亂灑,看多這種白癡裝恐怖的爛鏡頭以後,就對恐怖片免疫了。

    + +

    可是,暮蟬悲鳴時實在是…嗯…讓我秋天的半夜裏,感到一股透骨的寒意。像同人誌、養成遊戲般常見的可愛畫風,快樂又平凡的日常生活,卻不知不覺間慢慢崩解的恐怖感。看完之後就跑去睡了,晚上沒有睡不著覺,也沒有做惡夢,早上醒來,卻還是感到一股沉重的寒意壓在心裏。

    + +

    雖然這樣講很奇怪,但真的是太棒了。應該可以稱得上經典吧。即使是恐怖漫畫大師伊藤潤二的經典富江系列,都沒有辦法給我這種透骨發寒的恐怖感。原作是同人遊戲。同人遊戲耶!又是一種我不熟悉、非傳統的創作媒體,同人、非商業的集體創作,創作媒體也不是傳統的小說、漫畫、動畫、電視、電影、廣播劇、舞台劇等等傳統創作媒體,真的是太了不起了。

    + +

    早上跟同事聊,上網查了查,才知道原來我昨天看的是外傳鬼曝編。今天中午去漫畫出租店,看了正篇的祟殺編暮蟬悲鳴時每一篇都是上下兩集,在台灣正篇已經出版了鬼隱編綿流編祟殺編三篇,外傳則出了鬼曝編一篇。今天晚上,應該就可以看完了。

    + +

    還有暮蟬悲鳴時的真人電影版,年中已經出了。好想看,不知道在台灣,找不找得到有中文字幕的版本。原作的同人遊戲,網路上有中文化版,有點期待。

    + +
    + +
    + +
    +
    7.24.’08. 12:04pm.
    + +

    海海人生

    + +

    這兩天又把陳盈潔的海海人生翻出來聽。

    + +

    很久沒唱歌,最近又想起幾首很經典的老歌。細細吟詠歌詞後,有不少新的體會。

    + +

    我之前從來沒有仔細聽過、唱過陳盈潔的海海人生。這兩天不自覺地吟詠起來,於是上網去找它的 MP3 和歌詞。仔細聽了、唱了以後,發現海海人生其實是一首淡淡哀愁的歌,海海人生的開闊背後,是對人生無解的悲歡分合的了悟。海海人生不是開懷笑唱的歌,而是懷抱對人生的深刻體悟,淡淡輕唱的歌。

    + +

    海海人生,說來容易,唱來輕鬆。然而,要唱出阮會歡喜有緣你作伴 要離開笑笑阮沒牽掛,又需要何等的人生領悟呢?

    + +
    +

    海海人生

    + +
    曲︰張國榮 詞︰娃娃
    + +
    人說這心情 罕罕罕罕卡快活
    +不通太陰沈 想著會驚
    +有人真古意 定定嘛是有人變卦
    +這人情怎樣才看會破
    +
    +人說這人生 海海海海路好行
    +不通回頭望 望著會茫
    +有人愛著阮 偏偏阮愛的是別人
    +這情債怎樣計較輸贏
    +
    +輕輕鬆鬆人生路途阮來行
    +無人是應該永遠孤單
    +阮會歡喜有緣你作伴
    +要離開笑笑阮沒牽掛
    +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 146 | + 147 | + 148 | + 149 | + 150 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0149.html.en.html b/htdocs/imacat/me/diary/0149.html.en.html new file mode 120000 index 0000000..18007a1 --- /dev/null +++ b/htdocs/imacat/me/diary/0149.html.en.html @@ -0,0 +1 @@ +0149.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0149.html.en.xhtml b/htdocs/imacat/me/diary/0149.html.en.xhtml new file mode 100644 index 0000000..012fddf --- /dev/null +++ b/htdocs/imacat/me/diary/0149.html.en.xhtml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 149 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 149

    + +
    + +
    + +
    +
    9.10.’08. 4:58am.
    + +

    暮蟬悲鳴時 ひぐらしのなく頃に

    + +

    晚上,賴在漫畫出租店,把暮蟬悲鳴時鬼隱篇綿流篇一口氣看完了。

    + +

    原來如此,還真的很有趣呢。下午在網路上查暮蟬悲鳴時時,看到什麼平行世界的,不大看得懂。原來是這麼回事啊。

    + +

    鬼隱篇綿流篇祟殺編,其人物、故事背景、死亡的事件大致上都是一樣的,可是劇情內容不同,結局也不同。真是有趣的設定~

    + +

    祟殺編主題是作祟殺人,殺人的犯人是主角前原圭一,女主角是北条沙都子,喜歡設陷阱惡作劇的活力小妹。雖然大致上合理,不過主角圭一殺了沙都子的叔叔之後,伴隨著在跟在身後的腳步聲,就開始發生不可思議的事了:圭一詛咒、希望死掉的人:鷹野三四護士、入江京介醫生、大石蔵人刑警,都各自死掉、失蹤了。直到最後,主角希望整個雛見沢消失,就發生了地底火山毒氣外洩大量死亡事件,雛見沢所有人都死光,就此滅村了。只要是圭一的詛咒,就會實現。這一連串的詛咒殺人事件,真的是御社神作祟嗎?還是人為的?

    + +

    鬼隱篇主題是鬼隱失蹤事件,女主角、殺人的犯人是龍宮怜奈(竜宮レナ),溫柔穩重,但只要碰到可愛的事物,就會瘋狂想帶回家的同年級同學。鬼隱篇中主角圭一勇敢挺身對抗危險,但故事從頭到尾都謎霧重重,在圭一殺了瘋狂的レナ,幾天後自殺結束,還是留下一堆未解之謎:四年前第一個死者工地監工其實沒有死,是真的嗎?是誰把圭一留在鐘後面的證據針管帶走,並撕走一半的死前提示留言?為什麼只撕一半?圭一富竹次郎一樣撕裂自己喉嚨而死,圭一死時還在公共電話上,跟警方說御社神在後面追上來了,又是指什麼?

    + +

    綿流篇主題是綿流祭,鋤頭鋤破綿被、綿花放水流,所象徵的開膛剖腹吃人虐殺,女主角、殺人的犯人是園崎魅音,喜歡自稱老頭、像男生一樣嘻鬧的大姊,其實是村中權力最大園崎家的下任當家。故事原是三篇中最清楚、合乎科學的。可是在事件過後魅音刺殺圭一失敗,才發現驚人的恐怖謎題:園崎魅音早就在事件當時就死了,根本不可能事後回來刺殺圭一。另外,一連串事件的開端、在綿流祭時偷偷帶人潛入神社禁地的鷹野三四,其屍體判定死亡時間也在綿流祭之前。魅音鷹野三四早就死了,後來出現的到底是誰?

    + +

    三篇故事發生在都是同一個背景、同一批角色身上,故事各自不同,卻又互相補足故事的背景事實。三篇故事先讀哪一篇都可以,完全沒有先後順序(而且時序還是同時的),反正都要全部讀過,才能完全知道所有的事實。

    + +

    稍為整理一下,才不會忘記。這些令人發寒的謎,到底是真有御社神的詛咒,還是人為的呢?

    + +

    原著遊戲還有第四篇:暇潰編,不過漫畫還沒有。推算下來,女主角應該就是文靜可愛的小巫女古手梨花了。不知道是什麼故事。如果漫畫不出的話,也就無從得知了。

    + +

    漫畫版還有解答篇,不過台灣還沒有上市,日本也還沒有連載完。真是讓人期待啊~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 147 | + 148 | + 149 | + 150 | + 151 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0149.html.zh-cn.html b/htdocs/imacat/me/diary/0149.html.zh-cn.html new file mode 120000 index 0000000..ebb8aa7 --- /dev/null +++ b/htdocs/imacat/me/diary/0149.html.zh-cn.html @@ -0,0 +1 @@ +0149.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0149.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0149.html.zh-cn.xhtml new file mode 100644 index 0000000..f8cabe1 --- /dev/null +++ b/htdocs/imacat/me/diary/0149.html.zh-cn.xhtml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百四十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百四十九

    + +
    + +
    + +
    +
    9.10.’08. 4:58am.
    + +

    暮蝉悲鸣时 ひぐらしのなく顷に

    + +

    晚上,赖在漫画出租店,把暮蝉悲鸣时鬼隐篇绵流篇一口气看完了。

    + +

    原来如此,还真的很有趣呢。下午在网路上查暮蝉悲鸣时时,看到什么平行世界的,不大看得懂。原来是这么回事啊。

    + +

    鬼隐篇绵流篇祟杀编,其人物、故事背景、死亡的事件大致上都是一样的,可是剧情内容不同,结局也不同。真是有趣的设定~

    + +

    祟杀编主题是作祟杀人,杀人的犯人是主角前原圭一,女主角是北条沙都子,喜欢设陷阱恶作剧的活力小妹。虽然大致上合理,不过主角圭一杀了沙都子的叔叔之后,伴随著在跟在身后的脚步声,就开始发生不可思议的事了:圭一诅咒、希望死掉的人:鹰野三四护士、入江京介医生、大石蔵人刑警,都各自死掉、失踪了。直到最后,主角希望整个雏见沢消失,就发生了地底火山毒气外泄大量死亡事件,雏见沢所有人都死光,就此灭村了。只要是圭一的诅咒,就会实现。这一连串的诅咒杀人事件,真的是御社神作祟吗?还是人为的?

    + +

    鬼隐篇主题是鬼隐失踪事件,女主角、杀人的犯人是龙宫怜奈(竜宫レナ),温柔稳重,但只要碰到可爱的事物,就会疯狂想带回家的同年级同学。鬼隐篇中主角圭一勇敢挺身对抗危险,但故事从头到尾都谜雾重重,在圭一杀了疯狂的レナ,几天后自杀结束,还是留下一堆未解之谜:四年前第一个死者工地监工其实没有死,是真的吗?是谁把圭一留在钟后面的证据针管带走,并撕走一半的死前提示留言?为什么只撕一半?圭一富竹次郎一样撕裂自己喉咙而死,圭一死时还在公共电话上,跟警方说御社神在后面追上来了,又是指什么?

    + +

    绵流篇主题是绵流祭,锄头锄破绵被、绵花放水流,所象徵的开膛剖腹吃人虐杀,女主角、杀人的犯人是园崎魅音,喜欢自称老头、像男生一样嘻闹的大姊,其实是村中权力最大园崎家的下任当家。故事原是三篇中最清楚、合乎科学的。可是在事件过后魅音刺杀圭一失败,才发现惊人的恐怖谜题:园崎魅音早就在事件当时就死了,根本不可能事后回来刺杀圭一。另外,一连串事件的开端、在绵流祭时偷偷带人潜入神社禁地的鹰野三四,其尸体判定死亡时间也在绵流祭之前。魅音鹰野三四早就死了,后来出现的到底是谁?

    + +

    三篇故事发生在都是同一个背景、同一批角色身上,故事各自不同,却又互相补足故事的背景事实。三篇故事先读哪一篇都可以,完全没有先后顺序(而且时序还是同时的),反正都要全部读过,才能完全知道所有的事实。

    + +

    稍为整理一下,才不会忘记。这些令人发寒的谜,到底是真有御社神的诅咒,还是人为的呢?

    + +

    原著游戏还有第四篇:暇溃编,不过漫画还没有。推算下来,女主角应该就是文静可爱的小巫女古手梨花了。不知道是什么故事。如果漫画不出的话,也就无从得知了。

    + +

    漫画版还有解答篇,不过台湾还没有上市,日本也还没有连载完。真是让人期待啊~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 147 | + 148 | + 149 | + 150 | + 151 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0149.html.zh-tw.html b/htdocs/imacat/me/diary/0149.html.zh-tw.html new file mode 120000 index 0000000..47410ee --- /dev/null +++ b/htdocs/imacat/me/diary/0149.html.zh-tw.html @@ -0,0 +1 @@ +0149.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0149.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0149.html.zh-tw.xhtml new file mode 100644 index 0000000..c0d2155 --- /dev/null +++ b/htdocs/imacat/me/diary/0149.html.zh-tw.xhtml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百四十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百四十九

    + +
    + +
    + +
    +
    9.10.’08. 4:58am.
    + +

    暮蟬悲鳴時 ひぐらしのなく頃に

    + +

    晚上,賴在漫畫出租店,把暮蟬悲鳴時鬼隱篇綿流篇一口氣看完了。

    + +

    原來如此,還真的很有趣呢。下午在網路上查暮蟬悲鳴時時,看到什麼平行世界的,不大看得懂。原來是這麼回事啊。

    + +

    鬼隱篇綿流篇祟殺編,其人物、故事背景、死亡的事件大致上都是一樣的,可是劇情內容不同,結局也不同。真是有趣的設定~

    + +

    祟殺編主題是作祟殺人,殺人的犯人是主角前原圭一,女主角是北条沙都子,喜歡設陷阱惡作劇的活力小妹。雖然大致上合理,不過主角圭一殺了沙都子的叔叔之後,伴隨著在跟在身後的腳步聲,就開始發生不可思議的事了:圭一詛咒、希望死掉的人:鷹野三四護士、入江京介醫生、大石蔵人刑警,都各自死掉、失蹤了。直到最後,主角希望整個雛見沢消失,就發生了地底火山毒氣外洩大量死亡事件,雛見沢所有人都死光,就此滅村了。只要是圭一的詛咒,就會實現。這一連串的詛咒殺人事件,真的是御社神作祟嗎?還是人為的?

    + +

    鬼隱篇主題是鬼隱失蹤事件,女主角、殺人的犯人是龍宮怜奈(竜宮レナ),溫柔穩重,但只要碰到可愛的事物,就會瘋狂想帶回家的同年級同學。鬼隱篇中主角圭一勇敢挺身對抗危險,但故事從頭到尾都謎霧重重,在圭一殺了瘋狂的レナ,幾天後自殺結束,還是留下一堆未解之謎:四年前第一個死者工地監工其實沒有死,是真的嗎?是誰把圭一留在鐘後面的證據針管帶走,並撕走一半的死前提示留言?為什麼只撕一半?圭一富竹次郎一樣撕裂自己喉嚨而死,圭一死時還在公共電話上,跟警方說御社神在後面追上來了,又是指什麼?

    + +

    綿流篇主題是綿流祭,鋤頭鋤破綿被、綿花放水流,所象徵的開膛剖腹吃人虐殺,女主角、殺人的犯人是園崎魅音,喜歡自稱老頭、像男生一樣嘻鬧的大姊,其實是村中權力最大園崎家的下任當家。故事原是三篇中最清楚、合乎科學的。可是在事件過後魅音刺殺圭一失敗,才發現驚人的恐怖謎題:園崎魅音早就在事件當時就死了,根本不可能事後回來刺殺圭一。另外,一連串事件的開端、在綿流祭時偷偷帶人潛入神社禁地的鷹野三四,其屍體判定死亡時間也在綿流祭之前。魅音鷹野三四早就死了,後來出現的到底是誰?

    + +

    三篇故事發生在都是同一個背景、同一批角色身上,故事各自不同,卻又互相補足故事的背景事實。三篇故事先讀哪一篇都可以,完全沒有先後順序(而且時序還是同時的),反正都要全部讀過,才能完全知道所有的事實。

    + +

    稍為整理一下,才不會忘記。這些令人發寒的謎,到底是真有御社神的詛咒,還是人為的呢?

    + +

    原著遊戲還有第四篇:暇潰編,不過漫畫還沒有。推算下來,女主角應該就是文靜可愛的小巫女古手梨花了。不知道是什麼故事。如果漫畫不出的話,也就無從得知了。

    + +

    漫畫版還有解答篇,不過台灣還沒有上市,日本也還沒有連載完。真是讓人期待啊~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 147 | + 148 | + 149 | + 150 | + 151 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0150.html.en.html b/htdocs/imacat/me/diary/0150.html.en.html new file mode 120000 index 0000000..a3c9276 --- /dev/null +++ b/htdocs/imacat/me/diary/0150.html.en.html @@ -0,0 +1 @@ +0150.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0150.html.en.xhtml b/htdocs/imacat/me/diary/0150.html.en.xhtml new file mode 100644 index 0000000..1194fe6 --- /dev/null +++ b/htdocs/imacat/me/diary/0150.html.en.xhtml @@ -0,0 +1,309 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 150 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 150

    + +
    + +
    + +
    +
    10.7.’08. 4:04pm.
    + +

    Don’t Cry For Me Argentina

    + +

    今天上班時,挑了 Andrew Lloyd Webber 歌劇精選來聽。聽到了 EvitaDon’t Cry For Me Argentina 和接下來的 Oh What a Circus ,想到最近陳水扁的貪污洗錢案,突然覺得好諷刺。

    + +
    +…
    +When I try to explain how I feel
    +That I still need your love after all that I’ve done
    +…
    +The truth is I never left you
    +All through my wild days
    +My mad existence
    +I kept my promise
    +Don’t keep your distance
    +…
    +And as for fortune, and as for fame
    +I never invited them in
    +Though it seemed to the world they were all I desired
    +…
    +
    + +

    唉,原來是這種感覺呢~

    + +
    +…
    +Oh what a circus, oh what a show
    +Argentina has gone to town
    +Over the death of an actress called Eva Peron
    +…
    +
    + +

    第三世界國家改革開放的英雄,因為貪污腐化晚節不保,卻死不認錯,訴求民族主義想要翻身。原來是這樣的感覺啊~哪一天陳水扁走的時候,不知道又會演出怎麼樣的一場鬧劇呢?

    + +
    +

    Don’t Cry For Me Argentina

    + +
    Julie Covington
    + +
    +It won’t be easy, you’ll think it strange
    +When I try to explain how I feel
    +That I still need your love after all that I’ve done
    +You won’t believe me
    +All you will see is a girl you once knew
    +Although she’s dressed up to the nines
    +At sixes and sevens with you
    +
    +I had to let it happen, I had to change
    +Couldn’t stay all my life down at heel
    +Looking out of the window, staying out of the sun
    +So I chose freedom
    +Running around, trying everything new
    +But nothing impressed me at all
    +I never expected it to
    +
    +Don’t cry for me Argentina
    +The truth is I never left you
    +All through my wild days
    +My mad existence
    +I kept my promise
    +Don’t keep your distance
    +
    +And as for fortune, and as for fame
    +I never invited them in
    +Though it seemed to the world they were all I desired
    +They are illusions
    +They’re not the solutions they promised to be
    +The answer was here all the time
    +I love you and hope you love me
    +
    +Don’t cry for me Argentina
    +
    +Don’t cry for me Argentina
    +The truth is I never left you
    +All through my wild days
    +My mad existence
    +I kept my promise
    +Don’t keep your distance
    +
    +Have I said too much
    +There’s nothing more I can think of to say to you
    +But all you have to do is look at me to know
    +That every word is true
    +
    +
    + +
    +

    Oh What a Circus

    + +
    David Essex
    + +
    +Salve regina mater misericordiae
    +Vita dulcedo et spes nostra
    +Salve salve regina
    +Ad te clamamus exules filii Eva
    +Ad te suspiramus gementes
    +et flentes
    +O clemens o pia
    +
    +(Che:)
    +Oh what a circus, oh what a show
    +Argentina has gone to town
    +Over the death of an actress called Eva Peron
    +We’ve all gone crazy
    +Mourning all day and mourning all night
    +Falling over ourselves to get all of the misery right
    +
    +Oh what an exit, that’s how to go
    +When they’re ringing your curtain down
    +Demand to be buried like Eva Peron
    +It’s quite a sunset
    +And good for the country in a roundabout way
    +We’ve made the front page of all
    +the world’s papers today
    +
    +But who is this Santa Evita?
    +Why all this howling, hysterical sorrow?
    +What kind of goddess has lived among us?
    +How will we ever get by without her?
    +
    +(Crowd:)
    +Salve regina mater misericordiae
    +Vita dulcedo et spes nostra
    +Salve salve regina
    +Ad te clamamus exules filii Eva
    +Ad te suspiramus gementes
    +et flentes o clemens o pia
    +
    +She had her moments, she had some style
    +The best show in town was the crowd
    +Outside the Casa Rosada crying, Eva Peron
    +But that’s all gone now
    +As soon as the smoke from the funeral clears
    +We’re all gonna see and how,
    +she did nothing for years
    +
    +(Che:)
    +You let down your people Evita
    +You were supposed to have been immortal
    +That’s all they wanted, not much to ask for
    +But in the end you could not deliver
    +
    +(Crowd:)
    +Salve regina mater misericordiae
    +Vita dulcedo et spes nostra
    +Salve salve regina
    +Ad te clamamus exules filii Eva
    +Ad te suspiramus gementes et flentes
    +O clemens o pia
    +
    +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 148 | + 149 | + 150 | + 151 | + 152 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0150.html.zh-cn.html b/htdocs/imacat/me/diary/0150.html.zh-cn.html new file mode 120000 index 0000000..501430d --- /dev/null +++ b/htdocs/imacat/me/diary/0150.html.zh-cn.html @@ -0,0 +1 @@ +0150.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0150.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0150.html.zh-cn.xhtml new file mode 100644 index 0000000..959dceb --- /dev/null +++ b/htdocs/imacat/me/diary/0150.html.zh-cn.xhtml @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百五十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百五十

    + +
    + +
    + +
    +
    10.7.’08. 4:04pm.
    + +

    Don’t Cry For Me Argentina

    + +

    今天上班时,挑了 Andrew Lloyd Webber 歌剧精选来听。听到了 EvitaDon’t Cry For Me Argentina 和接下来的 Oh What a Circus ,想到最近陈水扁的贪污洗钱案,突然觉得好讽刺。

    + +
    +…
    +When I try to explain how I feel
    +That I still need your love after all that I’ve done
    +…
    +The truth is I never left you
    +All through my wild days
    +My mad existence
    +I kept my promise
    +Don’t keep your distance
    +…
    +And as for fortune, and as for fame
    +I never invited them in
    +Though it seemed to the world they were all I desired
    +…
    +
    + +

    唉,原来是这种感觉呢~

    + +
    +…
    +Oh what a circus, oh what a show
    +Argentina has gone to town
    +Over the death of an actress called Eva Peron
    +…
    +
    + +

    第三世界国家改革开放的英雄,因为贪污腐化晚节不保,却死不认错,诉求民族主义想要翻身。原来是这样的感觉啊~哪一天陈水扁走的时候,不知道又会演出怎么样的一场闹剧呢?

    + +
    +

    Don’t Cry For Me Argentina

    + +
    Julie Covington
    + +
    +It won’t be easy, you’ll think it strange
    +When I try to explain how I feel
    +That I still need your love after all that I’ve done
    +You won’t believe me
    +All you will see is a girl you once knew
    +Although she’s dressed up to the nines
    +At sixes and sevens with you
    +
    +I had to let it happen, I had to change
    +Couldn’t stay all my life down at heel
    +Looking out of the window, staying out of the sun
    +So I chose freedom
    +Running around, trying everything new
    +But nothing impressed me at all
    +I never expected it to
    +
    +Don’t cry for me Argentina
    +The truth is I never left you
    +All through my wild days
    +My mad existence
    +I kept my promise
    +Don’t keep your distance
    +
    +And as for fortune, and as for fame
    +I never invited them in
    +Though it seemed to the world they were all I desired
    +They are illusions
    +They’re not the solutions they promised to be
    +The answer was here all the time
    +I love you and hope you love me
    +
    +Don’t cry for me Argentina
    +
    +Don’t cry for me Argentina
    +The truth is I never left you
    +All through my wild days
    +My mad existence
    +I kept my promise
    +Don’t keep your distance
    +
    +Have I said too much
    +There’s nothing more I can think of to say to you
    +But all you have to do is look at me to know
    +That every word is true
    +
    +
    + +
    +

    Oh What a Circus

    + +
    David Essex
    + +
    +Salve regina mater misericordiae
    +Vita dulcedo et spes nostra
    +Salve salve regina
    +Ad te clamamus exules filii Eva
    +Ad te suspiramus gementes
    +et flentes
    +O clemens o pia
    +
    +(Che:)
    +Oh what a circus, oh what a show
    +Argentina has gone to town
    +Over the death of an actress called Eva Peron
    +We’ve all gone crazy
    +Mourning all day and mourning all night
    +Falling over ourselves to get all of the misery right
    +
    +Oh what an exit, that’s how to go
    +When they’re ringing your curtain down
    +Demand to be buried like Eva Peron
    +It’s quite a sunset
    +And good for the country in a roundabout way
    +We’ve made the front page of all
    +the world’s papers today
    +
    +But who is this Santa Evita?
    +Why all this howling, hysterical sorrow?
    +What kind of goddess has lived among us?
    +How will we ever get by without her?
    +
    +(Crowd:)
    +Salve regina mater misericordiae
    +Vita dulcedo et spes nostra
    +Salve salve regina
    +Ad te clamamus exules filii Eva
    +Ad te suspiramus gementes
    +et flentes o clemens o pia
    +
    +She had her moments, she had some style
    +The best show in town was the crowd
    +Outside the Casa Rosada crying, Eva Peron
    +But that’s all gone now
    +As soon as the smoke from the funeral clears
    +We’re all gonna see and how,
    +she did nothing for years
    +
    +(Che:)
    +You let down your people Evita
    +You were supposed to have been immortal
    +That’s all they wanted, not much to ask for
    +But in the end you could not deliver
    +
    +(Crowd:)
    +Salve regina mater misericordiae
    +Vita dulcedo et spes nostra
    +Salve salve regina
    +Ad te clamamus exules filii Eva
    +Ad te suspiramus gementes et flentes
    +O clemens o pia
    +
    +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 148 | + 149 | + 150 | + 151 | + 152 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0150.html.zh-tw.html b/htdocs/imacat/me/diary/0150.html.zh-tw.html new file mode 120000 index 0000000..5257751 --- /dev/null +++ b/htdocs/imacat/me/diary/0150.html.zh-tw.html @@ -0,0 +1 @@ +0150.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0150.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0150.html.zh-tw.xhtml new file mode 100644 index 0000000..be6273f --- /dev/null +++ b/htdocs/imacat/me/diary/0150.html.zh-tw.xhtml @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百五十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百五十

    + +
    + +
    + +
    +
    10.7.’08. 4:04pm.
    + +

    Don’t Cry For Me Argentina

    + +

    今天上班時,挑了 Andrew Lloyd Webber 歌劇精選來聽。聽到了 EvitaDon’t Cry For Me Argentina 和接下來的 Oh What a Circus ,想到最近陳水扁的貪污洗錢案,突然覺得好諷刺。

    + +
    +…
    +When I try to explain how I feel
    +That I still need your love after all that I’ve done
    +…
    +The truth is I never left you
    +All through my wild days
    +My mad existence
    +I kept my promise
    +Don’t keep your distance
    +…
    +And as for fortune, and as for fame
    +I never invited them in
    +Though it seemed to the world they were all I desired
    +…
    +
    + +

    唉,原來是這種感覺呢~

    + +
    +…
    +Oh what a circus, oh what a show
    +Argentina has gone to town
    +Over the death of an actress called Eva Peron
    +…
    +
    + +

    第三世界國家改革開放的英雄,因為貪污腐化晚節不保,卻死不認錯,訴求民族主義想要翻身。原來是這樣的感覺啊~哪一天陳水扁走的時候,不知道又會演出怎麼樣的一場鬧劇呢?

    + +
    +

    Don’t Cry For Me Argentina

    + +
    Julie Covington
    + +
    +It won’t be easy, you’ll think it strange
    +When I try to explain how I feel
    +That I still need your love after all that I’ve done
    +You won’t believe me
    +All you will see is a girl you once knew
    +Although she’s dressed up to the nines
    +At sixes and sevens with you
    +
    +I had to let it happen, I had to change
    +Couldn’t stay all my life down at heel
    +Looking out of the window, staying out of the sun
    +So I chose freedom
    +Running around, trying everything new
    +But nothing impressed me at all
    +I never expected it to
    +
    +Don’t cry for me Argentina
    +The truth is I never left you
    +All through my wild days
    +My mad existence
    +I kept my promise
    +Don’t keep your distance
    +
    +And as for fortune, and as for fame
    +I never invited them in
    +Though it seemed to the world they were all I desired
    +They are illusions
    +They’re not the solutions they promised to be
    +The answer was here all the time
    +I love you and hope you love me
    +
    +Don’t cry for me Argentina
    +
    +Don’t cry for me Argentina
    +The truth is I never left you
    +All through my wild days
    +My mad existence
    +I kept my promise
    +Don’t keep your distance
    +
    +Have I said too much
    +There’s nothing more I can think of to say to you
    +But all you have to do is look at me to know
    +That every word is true
    +
    +
    + +
    +

    Oh What a Circus

    + +
    David Essex
    + +
    +Salve regina mater misericordiae
    +Vita dulcedo et spes nostra
    +Salve salve regina
    +Ad te clamamus exules filii Eva
    +Ad te suspiramus gementes
    +et flentes
    +O clemens o pia
    +
    +(Che:)
    +Oh what a circus, oh what a show
    +Argentina has gone to town
    +Over the death of an actress called Eva Peron
    +We’ve all gone crazy
    +Mourning all day and mourning all night
    +Falling over ourselves to get all of the misery right
    +
    +Oh what an exit, that’s how to go
    +When they’re ringing your curtain down
    +Demand to be buried like Eva Peron
    +It’s quite a sunset
    +And good for the country in a roundabout way
    +We’ve made the front page of all
    +the world’s papers today
    +
    +But who is this Santa Evita?
    +Why all this howling, hysterical sorrow?
    +What kind of goddess has lived among us?
    +How will we ever get by without her?
    +
    +(Crowd:)
    +Salve regina mater misericordiae
    +Vita dulcedo et spes nostra
    +Salve salve regina
    +Ad te clamamus exules filii Eva
    +Ad te suspiramus gementes
    +et flentes o clemens o pia
    +
    +She had her moments, she had some style
    +The best show in town was the crowd
    +Outside the Casa Rosada crying, Eva Peron
    +But that’s all gone now
    +As soon as the smoke from the funeral clears
    +We’re all gonna see and how,
    +she did nothing for years
    +
    +(Che:)
    +You let down your people Evita
    +You were supposed to have been immortal
    +That’s all they wanted, not much to ask for
    +But in the end you could not deliver
    +
    +(Crowd:)
    +Salve regina mater misericordiae
    +Vita dulcedo et spes nostra
    +Salve salve regina
    +Ad te clamamus exules filii Eva
    +Ad te suspiramus gementes et flentes
    +O clemens o pia
    +
    +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 148 | + 149 | + 150 | + 151 | + 152 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0151.html.en.html b/htdocs/imacat/me/diary/0151.html.en.html new file mode 120000 index 0000000..820cf12 --- /dev/null +++ b/htdocs/imacat/me/diary/0151.html.en.html @@ -0,0 +1 @@ +0151.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0151.html.en.xhtml b/htdocs/imacat/me/diary/0151.html.en.xhtml new file mode 100644 index 0000000..faee319 --- /dev/null +++ b/htdocs/imacat/me/diary/0151.html.en.xhtml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 151 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 151

    + +
    + +
    + +
    +
    10.7.’08. 7:03pm.
    + +

    Travian

    + +

    脫離了 Travian 的苦海了。

    + +

    其實,現在寫這篇的時候,已經離開 Travian 快一個月了。本來在慢慢淡出時要寫,拖著拖著變成離開時要寫,現在變成離開好一陣子了以後,才完成。

    + +

    我上次玩網路連線遊戲,是十幾年前玩台大的 龍域傳奇 Dragon Realm MUD ,後來因為違規被管理員抓到(詳情不大記得了),人物被永久關起來,就不玩了。這十幾年來網路遊戲興盛,如火如荼。可是我之前在 DR 耗了太多心力,加上天堂負面新聞一大堆,我已經提不起興緻了。

    + +

    會玩 Travian ,是因為四月時阿光聊天,光說她正在玩 Travian 。幾十年沒玩網路遊戲,其實還是覺得自己跟現在的小朋友有點脫節。好奇之下,我也跟著玩了下去。

    + +

    剛開始還好。感覺蠻特別的。 Travian 是第一款(吧?),也是最有名的網頁遊戲,用瀏覽器就可以玩。因此,只要有 FirefoxIE 就可以玩,不需要買新的顯示卡,自然也不需要為了換新顯示卡換電腦了。而且因為是網頁遊戲,只要有瀏覽器就可以玩,不需要花時間下載遊戲程式,所以隨時隨地都可以玩,在公司也能偷偷開,在 Linux 下工作時也可以玩,幾乎是有電腦就可以玩,完全不受時空環境限制。一開始都在建設,感覺很像世紀帝國的。

    + +

    不過好玩歸好玩,心中也有陰影。聽阿光說, Travian 蠻不講理,一天到晚有人來搶,大家打來打去。我聽得戰戰兢兢的。我不喜歡打人,也不喜歡被打。我拼命保持低調,不要引人注意,慢慢發展。我上 Travian 論壇找討論,看新手要怎麼樣保護自己,避免被搶被打。保持低調外,拼命蓋山洞,不做會被打的事,被打就寫訊息低聲下氣去求和,小心翼翼慢慢發展。

    + +

    這樣小心翼翼低調發展,也被我發展出了三個村。不佔九田十五田,不佔綠州。三村相連,不引人注目,被打可以快速聯防,資源可以快速調度。所有米產拿來養防兵。終於,也被我站穩腳步,養出了別人沒辦法輕易來打我的防守力。

    + +

    可是,其實並不好玩。

    + +

    Travian 這個遊戲太奇怪了。玩久了以後,我逐漸摸清了 Travian 的本質。 Travian 的本質是戰爭遊戲,每個人都打來打去、搶來搶去。我堅持不打人,除了我想保持低調,不想不小心打了到某某人的朋友、某某人的多帳,招致戰禍,甚至根本不想名字出現在任何人的戰報上外,更重要的是,我就是不想打人。像我這樣的人,在 Travian 裏根本就是異類。

    + +

    可是,反過來說,我覺得 Travian 根本就是變態極了。不管做什麼都要把頭放低低的,只要不小心稍微抬個頭,就會招致戰禍。九田不能佔,十五田不能佔,就在旁邊的綠州不能佔。在公開市場上一掛買賣就被打,在個人敘述一說自己要養禁衛兵海就被打。本來想說有盟比較不會被打,所以自己組個小盟,不知不覺盟大了,就被打了。不管做什麼都會被打,這個遊戲根本就是瘋了。

    + +

    更扯的是,被打了,我還得要低聲下氣去求和,去求和人家還不一定會回訊,回訊了還常常五四三地奚落。喂,被打是我的錯嗎?為什麼低聲下氣道歉的是我啊?為什麼要被打了還要被對方奚落啊?為什麼要忍辱到這種程度啊?根本是莫名其妙!

    + +

    就這樣,毫無樂趣地玩著。只是因為花了很多精神苦心建設,花了很多錢買金幣才建出來的三個城,所以捨不得放棄不玩。

    + +

    就在越來越沒有目標,好像變成在等世界奇觀開放的時候,我的小盟收到人家的邀請加入盟系。我本來就討厭成群結黨,可是沒找靠山好像很難活下去。正在猶豫時,問了對方世界奇觀什麼時候開。對方說大概明年一月吧。天哪!我還打算考研究所,怎麼可能撐到那個時候?於是我趕緊找盟裏其他人接手盟主,談好加入別人盟系的事,把盟交待出去,就退盟要淡出了。

    + +

    退盟了以後,無事一身輕。沒有了老是煩來煩去的連盟、盟戰、密謀、打來打去的外交問題,開始過閒散種田的日子。偶爾上去偷看一下盟裏狀況好不好,或上論壇看看八掛。幾個禮拜被打一次,六田三村普十四滿滿的禁衛兵、防禦英雄、二十級城牆、二十級盔甲加防禦 PLUS ,也都守得下來。

    + +

    就這樣閒散過了一個多月,我也膩了。 Travian 的本質是戰爭遊戲,不打人,也不被打,那還有什麼好玩?我不知道。幾個禮拜被打一次,被打了再生兵補全損失防兵,再被打,再生兵。永遠都是同樣的輪迴,多兩次,我就膩了。一次被遊戲排名一百多的打,成功守下來以後,想到要再生兵就覺得膩,就砍帳不玩了。

    + +

    不玩,真好。本來就不該玩的。什麼爛遊戲嘛!

    + +

    我後來在 Travian 論壇上,看到有人介紹另一個比較和平很多的網頁遊戲Ikariam 。上去玩,除了介面複雜到有點慢外,真的和平很多呢~ Ikariam 有很多抑制強凌弱,強調合作的遊戲設計。不用怕一掛資源上市場賣就被打,跟人家說話聊天也沒事,不像 Travian 要拼死低調當透明人。玩久了真的覺得很棒呢~

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 149 | + 150 | + 151 | + 152 | + 153 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0151.html.zh-cn.html b/htdocs/imacat/me/diary/0151.html.zh-cn.html new file mode 120000 index 0000000..62307c7 --- /dev/null +++ b/htdocs/imacat/me/diary/0151.html.zh-cn.html @@ -0,0 +1 @@ +0151.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0151.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0151.html.zh-cn.xhtml new file mode 100644 index 0000000..756e7c1 --- /dev/null +++ b/htdocs/imacat/me/diary/0151.html.zh-cn.xhtml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百五十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百五十一

    + +
    + +
    + +
    +
    10.7.’08. 7:03pm.
    + +

    Travian

    + +

    脱离了 Travian 的苦海了。

    + +

    其实,现在写这篇的时候,已经离开 Travian 快一个月了。本来在慢慢淡出时要写,拖著拖著变成离开时要写,现在变成离开好一阵子了以后,才完成。

    + +

    我上次玩网路连线游戏,是十几年前玩台大的 龙域传奇 Dragon Realm MUD ,后来因为违规被管理员抓到(详情不大记得了),人物被永久关起来,就不玩了。这十几年来网路游戏兴盛,如火如荼。可是我之前在 DR 耗了太多心力,加上天堂负面新闻一大堆,我已经提不起兴致了。

    + +

    会玩 Travian ,是因为四月时阿光聊天,光说她正在玩 Travian 。几十年没玩网路游戏,其实还是觉得自己跟现在的小朋友有点脱节。好奇之下,我也跟著玩了下去。

    + +

    刚开始还好。感觉蛮特别的。 Travian 是第一款(吧?),也是最有名的网页游戏,用浏览器就可以玩。因此,只要有 FirefoxIE 就可以玩,不需要买新的显示卡,自然也不需要为了换新显示卡换电脑了。而且因为是网页游戏,只要有浏览器就可以玩,不需要花时间下载游戏程式,所以随时随地都可以玩,在公司也能偷偷开,在 Linux 下工作时也可以玩,几乎是有电脑就可以玩,完全不受时空环境限制。一开始都在建设,感觉很像世纪帝国的。

    + +

    不过好玩归好玩,心中也有阴影。听阿光说, Travian 蛮不讲理,一天到晚有人来抢,大家打来打去。我听得战战兢兢的。我不喜欢打人,也不喜欢被打。我拼命保持低调,不要引人注意,慢慢发展。我上 Travian 论坛找讨论,看新手要怎么样保护自己,避免被抢被打。保持低调外,拼命盖山洞,不做会被打的事,被打就写讯息低声下气去求和,小心翼翼慢慢发展。

    + +

    这样小心翼翼低调发展,也被我发展出了三个村。不占九田十五田,不占绿州。三村相连,不引人注目,被打可以快速联防,资源可以快速调度。所有米产拿来养防兵。终於,也被我站稳脚步,养出了别人没办法轻易来打我的防守力。

    + +

    可是,其实并不好玩。

    + +

    Travian 这个游戏太奇怪了。玩久了以后,我逐渐摸清了 Travian 的本质。 Travian 的本质是战争游戏,每个人都打来打去、抢来抢去。我坚持不打人,除了我想保持低调,不想不小心打了到某某人的朋友、某某人的多帐,招致战祸,甚至根本不想名字出现在任何人的战报上外,更重要的是,我就是不想打人。像我这样的人,在 Travian 里根本就是异类。

    + +

    可是,反过来说,我觉得 Travian 根本就是变态极了。不管做什么都要把头放低低的,只要不小心稍微抬个头,就会招致战祸。九田不能占,十五田不能占,就在旁边的绿州不能占。在公开市场上一挂买卖就被打,在个人叙述一说自己要养禁卫兵海就被打。本来想说有盟比较不会被打,所以自己组个小盟,不知不觉盟大了,就被打了。不管做什么都会被打,这个游戏根本就是疯了。

    + +

    更扯的是,被打了,我还得要低声下气去求和,去求和人家还不一定会回讯,回讯了还常常五四三地奚落。喂,被打是我的错吗?为什么低声下气道歉的是我啊?为什么要被打了还要被对方奚落啊?为什么要忍辱到这种程度啊?根本是莫名其妙!

    + +

    就这样,毫无乐趣地玩著。只是因为花了很多精神苦心建设,花了很多钱买金币才建出来的三个城,所以舍不得放弃不玩。

    + +

    就在越来越没有目标,好像变成在等世界奇观开放的时候,我的小盟收到人家的邀请加入盟系。我本来就讨厌成群结党,可是没找靠山好像很难活下去。正在犹豫时,问了对方世界奇观什么时候开。对方说大概明年一月吧。天哪!我还打算考研究所,怎么可能撑到那个时候?於是我赶紧找盟里其他人接手盟主,谈好加入别人盟系的事,把盟交待出去,就退盟要淡出了。

    + +

    退盟了以后,无事一身轻。没有了老是烦来烦去的连盟、盟战、密谋、打来打去的外交问题,开始过闲散种田的日子。偶尔上去偷看一下盟里状况好不好,或上论坛看看八挂。几个礼拜被打一次,六田三村普十四满满的禁卫兵、防御英雄、二十级城墙、二十级盔甲加防御 PLUS ,也都守得下来。

    + +

    就这样闲散过了一个多月,我也腻了。 Travian 的本质是战争游戏,不打人,也不被打,那还有什么好玩?我不知道。几个礼拜被打一次,被打了再生兵补全损失防兵,再被打,再生兵。永远都是同样的轮回,多两次,我就腻了。一次被游戏排名一百多的打,成功守下来以后,想到要再生兵就觉得腻,就砍帐不玩了。

    + +

    不玩,真好。本来就不该玩的。什么烂游戏嘛!

    + +

    我后来在 Travian 论坛上,看到有人介绍另一个比较和平很多的网页游戏Ikariam 。上去玩,除了介面复杂到有点慢外,真的和平很多呢~ Ikariam 有很多抑制强凌弱,强调合作的游戏设计。不用怕一挂资源上市场卖就被打,跟人家说话聊天也没事,不像 Travian 要拼死低调当透明人。玩久了真的觉得很棒呢~

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 149 | + 150 | + 151 | + 152 | + 153 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0151.html.zh-tw.html b/htdocs/imacat/me/diary/0151.html.zh-tw.html new file mode 120000 index 0000000..92a7af5 --- /dev/null +++ b/htdocs/imacat/me/diary/0151.html.zh-tw.html @@ -0,0 +1 @@ +0151.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0151.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0151.html.zh-tw.xhtml new file mode 100644 index 0000000..2d55718 --- /dev/null +++ b/htdocs/imacat/me/diary/0151.html.zh-tw.xhtml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百五十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百五十一

    + +
    + +
    + +
    +
    10.7.’08. 7:03pm.
    + +

    Travian

    + +

    脫離了 Travian 的苦海了。

    + +

    其實,現在寫這篇的時候,已經離開 Travian 快一個月了。本來在慢慢淡出時要寫,拖著拖著變成離開時要寫,現在變成離開好一陣子了以後,才完成。

    + +

    我上次玩網路連線遊戲,是十幾年前玩台大的 龍域傳奇 Dragon Realm MUD ,後來因為違規被管理員抓到(詳情不大記得了),人物被永久關起來,就不玩了。這十幾年來網路遊戲興盛,如火如荼。可是我之前在 DR 耗了太多心力,加上天堂負面新聞一大堆,我已經提不起興緻了。

    + +

    會玩 Travian ,是因為四月時阿光聊天,光說她正在玩 Travian 。幾十年沒玩網路遊戲,其實還是覺得自己跟現在的小朋友有點脫節。好奇之下,我也跟著玩了下去。

    + +

    剛開始還好。感覺蠻特別的。 Travian 是第一款(吧?),也是最有名的網頁遊戲,用瀏覽器就可以玩。因此,只要有 FirefoxIE 就可以玩,不需要買新的顯示卡,自然也不需要為了換新顯示卡換電腦了。而且因為是網頁遊戲,只要有瀏覽器就可以玩,不需要花時間下載遊戲程式,所以隨時隨地都可以玩,在公司也能偷偷開,在 Linux 下工作時也可以玩,幾乎是有電腦就可以玩,完全不受時空環境限制。一開始都在建設,感覺很像世紀帝國的。

    + +

    不過好玩歸好玩,心中也有陰影。聽阿光說, Travian 蠻不講理,一天到晚有人來搶,大家打來打去。我聽得戰戰兢兢的。我不喜歡打人,也不喜歡被打。我拼命保持低調,不要引人注意,慢慢發展。我上 Travian 論壇找討論,看新手要怎麼樣保護自己,避免被搶被打。保持低調外,拼命蓋山洞,不做會被打的事,被打就寫訊息低聲下氣去求和,小心翼翼慢慢發展。

    + +

    這樣小心翼翼低調發展,也被我發展出了三個村。不佔九田十五田,不佔綠州。三村相連,不引人注目,被打可以快速聯防,資源可以快速調度。所有米產拿來養防兵。終於,也被我站穩腳步,養出了別人沒辦法輕易來打我的防守力。

    + +

    可是,其實並不好玩。

    + +

    Travian 這個遊戲太奇怪了。玩久了以後,我逐漸摸清了 Travian 的本質。 Travian 的本質是戰爭遊戲,每個人都打來打去、搶來搶去。我堅持不打人,除了我想保持低調,不想不小心打了到某某人的朋友、某某人的多帳,招致戰禍,甚至根本不想名字出現在任何人的戰報上外,更重要的是,我就是不想打人。像我這樣的人,在 Travian 裏根本就是異類。

    + +

    可是,反過來說,我覺得 Travian 根本就是變態極了。不管做什麼都要把頭放低低的,只要不小心稍微抬個頭,就會招致戰禍。九田不能佔,十五田不能佔,就在旁邊的綠州不能佔。在公開市場上一掛買賣就被打,在個人敘述一說自己要養禁衛兵海就被打。本來想說有盟比較不會被打,所以自己組個小盟,不知不覺盟大了,就被打了。不管做什麼都會被打,這個遊戲根本就是瘋了。

    + +

    更扯的是,被打了,我還得要低聲下氣去求和,去求和人家還不一定會回訊,回訊了還常常五四三地奚落。喂,被打是我的錯嗎?為什麼低聲下氣道歉的是我啊?為什麼要被打了還要被對方奚落啊?為什麼要忍辱到這種程度啊?根本是莫名其妙!

    + +

    就這樣,毫無樂趣地玩著。只是因為花了很多精神苦心建設,花了很多錢買金幣才建出來的三個城,所以捨不得放棄不玩。

    + +

    就在越來越沒有目標,好像變成在等世界奇觀開放的時候,我的小盟收到人家的邀請加入盟系。我本來就討厭成群結黨,可是沒找靠山好像很難活下去。正在猶豫時,問了對方世界奇觀什麼時候開。對方說大概明年一月吧。天哪!我還打算考研究所,怎麼可能撐到那個時候?於是我趕緊找盟裏其他人接手盟主,談好加入別人盟系的事,把盟交待出去,就退盟要淡出了。

    + +

    退盟了以後,無事一身輕。沒有了老是煩來煩去的連盟、盟戰、密謀、打來打去的外交問題,開始過閒散種田的日子。偶爾上去偷看一下盟裏狀況好不好,或上論壇看看八掛。幾個禮拜被打一次,六田三村普十四滿滿的禁衛兵、防禦英雄、二十級城牆、二十級盔甲加防禦 PLUS ,也都守得下來。

    + +

    就這樣閒散過了一個多月,我也膩了。 Travian 的本質是戰爭遊戲,不打人,也不被打,那還有什麼好玩?我不知道。幾個禮拜被打一次,被打了再生兵補全損失防兵,再被打,再生兵。永遠都是同樣的輪迴,多兩次,我就膩了。一次被遊戲排名一百多的打,成功守下來以後,想到要再生兵就覺得膩,就砍帳不玩了。

    + +

    不玩,真好。本來就不該玩的。什麼爛遊戲嘛!

    + +

    我後來在 Travian 論壇上,看到有人介紹另一個比較和平很多的網頁遊戲Ikariam 。上去玩,除了介面複雜到有點慢外,真的和平很多呢~ Ikariam 有很多抑制強凌弱,強調合作的遊戲設計。不用怕一掛資源上市場賣就被打,跟人家說話聊天也沒事,不像 Travian 要拼死低調當透明人。玩久了真的覺得很棒呢~

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 149 | + 150 | + 151 | + 152 | + 153 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0152.html.en.html b/htdocs/imacat/me/diary/0152.html.en.html new file mode 120000 index 0000000..ae1505d --- /dev/null +++ b/htdocs/imacat/me/diary/0152.html.en.html @@ -0,0 +1 @@ +0152.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0152.html.en.xhtml b/htdocs/imacat/me/diary/0152.html.en.xhtml new file mode 100644 index 0000000..2b04a54 --- /dev/null +++ b/htdocs/imacat/me/diary/0152.html.en.xhtml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 152 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 152

    + +
    + +
    + +
    +
    3.1.’09. 0:11am.
    + +

    OLPCSugar OS

    + +

    我想很多人,應該都聽過這個計劃:One Laptop per Child (OLPC) (給每個孩子一台電腦), a low-cost, connected laptop for the world’s children’s education

    + +

    OLPC 的口號是 give a laptop, change the world 。這是 2005 年麻省理工學院 MIT 教授 Nicholas Negroponte ,在 World Economic Forum 宣佈的計劃:如果我們能將筆記型電腦的價格壓到一台 100 美金,那能不能讓貧窮國家,每個兒童擁有一部電腦呢?

    + +

    這個計劃受到廣泛的注目,也立刻獲得國際大廠的支持: GoogleNews CorporationAMDRed HatBrightstarNortel Networks 立刻宣佈加入 OLPC 計劃,每家公司捐助 200 萬美元,成為 OLPC 創始會員。聯合國開發計劃署 UNDP 隔年也宣佈支持 OLPC

    + +

    OLPC 自行研發軟硬體,硬體委託台灣廣達電腦代工,軟體則由 Linux 改良。 OLPC 限定賣給國家,不賣私人企業,以一百萬台為單位。富有國家如台灣要買,買一台要捐一台給貧窮國家,也就是兩倍價錢。

    + +

    OLPC 後來的進展其實並不順利。原先計劃在 2007 年實現,可是到去年 2008 年底,售價也只能壓到一台 188 美元。(也就是台灣買要近 400 美元,比 Eee PC 貴!)去年底受景氣寒冬影響,裁撤掉了工程部門。工程部門由創始會員 Red Hat 接收,成立新的 Open Source 專案 Sugar OS 維護。不過 OLPC 倒是對電腦產業產生了很深遠的影響。受 OLPC 啟發,華碩推出了 Eee PC ,價格壓到 300 美元,造成了全球旋風,引發了後來的小筆電熱潮,各家業者競相投入市場。

    + +

    OLPC 即使不順利,還是很偉大的計劃。不過,我不是要介紹 OLPC ,而是要介紹 OLPC 的成果 Sugar OS最新版的 Sugar OS 光碟可以由網路下載。下載後,燒成光碟,用光碟開機,就可以了。

    + +

    為什麼要特別介紹 Sugar OS ?與其我在這裏說到說到辭窮,最好還是大家自己試試看。不過,為了不懂科技的大多數人,我還是勉強提一提吧。

    + +

    什麼是作業系統?什麼是電腦?

    + +

    我們都已經習慣了 Windows 左下角的開始,從開始開始,展開一個大選單,逐步拉出所有的程式功能。不只是 WindowsLinux 也一樣。在 Linux Gnome 的桌面下,也是從左上角 Gnome 的大腳丫,拉出所有的分類功能選單。不只如此, KDEMac ,也都差不多。這不是微軟 Windows 的發明,可是不知不覺間,大家都這麼做,使用者也都習慣了,從來沒有人去質疑那個開始,所展開的整個資訊世界。

    + +

    可是,這真的是對的嗎?電腦,可不可能有別的樣子?

    + +

    當你把燒好的 XO Sugar 光碟插入光碟機,一開機,你會面對一個全然不同的畫面:畫面的中心,是 OLPC 象徵兒童的 XO 標誌,環繞在 XO 周圍圍成一圈的,是一個一個稱做 Activity 的圖示。 XO SugarActivity (活動) 的概念取代 Application (應用程式) 。每一個 Activity 點進去,都可以從事不同的活動:畫圖板、記憶力遊戲、數字遊戲、方向遊戲、精簡離線版的 WikiPedia 百科、上網。透過內建的無線網卡, XO Sugar 還有同儕遊戲:可以和旁邊的 XO Sugar 連線,除了互傳簡訊外,還可以測量兩台 OLPC 之間的距離,培養兒童的距離概念。

    + +

    在這麼多的 Activities 、色彩豐富的畫面之中,我急著找那個 Gnome 的大腳丫,那個將整個資訊世界展開的神奇按鈕。可是,沒有。

    + +

    XO Sugar 的桌面,巔覆了一般人對電腦的想像。我們已經太習慣那個開始選單了,忘記了一開始那個面對著空蕩蕩的畫面和左下角的開始按鈕,不知從何開始的自己。太習慣了,變成理所當然,所以當完全沒接觸過電腦的老人、小孩、窮人,面對同樣空蕩蕩的畫面和左下角的開始按鈕,不知所措的時候,我們只剩下不耐煩,廣開免費的電腦職訓課程,希望他們快點學會電腦,快點進入那個開始的資訊世界。

    + +

    會不會其實,我們習以為常的 Windows ,習以為常的 Application ,才是最不人性化的世界?做為一個,我們需要的是什麼樣的電腦?

    + +

    接下來是廣告時間。 ^_^ 雖然 Linux Gnome 桌面還是一個大腳丫,但 Sugar OS ,只有用 Linux 才做得到。因為 Linux 原始碼開放,所以 OLPC 計劃才能自己拿來改,做出和 Linux 完全不同的 Sugar OSOLPC 不可能拿 Windows 來改。 Windows 只有微軟授權讓廠商安裝,廠商無法按照自己的想法去研發、去創造,去發揮想像力。微軟在台灣打的電視廣告,用美麗的聲音說讓想像力無限延伸,這是很諷刺的。結果又回到一個老問題:究竟是開放環境好,還是獨占的封閉環境好呢?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 150 | + 151 | + 152 | + 153 | + 154 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0152.html.zh-cn.html b/htdocs/imacat/me/diary/0152.html.zh-cn.html new file mode 120000 index 0000000..552b3d0 --- /dev/null +++ b/htdocs/imacat/me/diary/0152.html.zh-cn.html @@ -0,0 +1 @@ +0152.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0152.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0152.html.zh-cn.xhtml new file mode 100644 index 0000000..ea80c6e --- /dev/null +++ b/htdocs/imacat/me/diary/0152.html.zh-cn.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百五十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百五十二

    + +
    + +
    + +
    +
    3.1.’09. 0:11am.
    + +

    OLPCSugar OS

    + +

    我想很多人,应该都听过这个计划:One Laptop per Child (OLPC) (给每个孩子一台电脑), a low-cost, connected laptop for the world’s children’s education

    + +

    OLPC 的口号是 give a laptop, change the world 。这是 2005 年麻省理工学院 MIT 教授 Nicholas Negroponte ,在 World Economic Forum 宣布的计划:如果我们能将笔记型电脑的价格压到一台 100 美金,那能不能让贫穷国家,每个儿童拥有一部电脑呢?

    + +

    这个计划受到广泛的注目,也立刻获得国际大厂的支持: GoogleNews CorporationAMDRed HatBrightstarNortel Networks 立刻宣布加入 OLPC 计划,每家公司捐助 200 万美元,成为 OLPC 创始会员。联合国开发计划署 UNDP 隔年也宣布支持 OLPC

    + +

    OLPC 自行研发软硬体,硬体委托台湾广达电脑代工,软体则由 Linux 改良。 OLPC 限定卖给国家,不卖私人企业,以一百万台为单位。富有国家如台湾要买,买一台要捐一台给贫穷国家,也就是两倍价钱。

    + +

    OLPC 后来的进展其实并不顺利。原先计划在 2007 年实现,可是到去年 2008 年底,售价也只能压到一台 188 美元。(也就是台湾买要近 400 美元,比 Eee PC 贵!)去年底受景气寒冬影响,裁撤掉了工程部门。工程部门由创始会员 Red Hat 接收,成立新的 Open Source 专案 Sugar OS 维护。不过 OLPC 倒是对电脑产业产生了很深远的影响。受 OLPC 启发,华硕推出了 Eee PC ,价格压到 300 美元,造成了全球旋风,引发了后来的小笔电热潮,各家业者竞相投入市场。

    + +

    OLPC 即使不顺利,还是很伟大的计划。不过,我不是要介绍 OLPC ,而是要介绍 OLPC 的成果 Sugar OS最新版的 Sugar OS 光碟可以由网路下载。下载后,烧成光碟,用光碟开机,就可以了。

    + +

    为什么要特别介绍 Sugar OS ?与其我在这里说到说到辞穷,最好还是大家自己试试看。不过,为了不懂科技的大多数人,我还是勉强提一提吧。

    + +

    什么是作业系统?什么是电脑?

    + +

    我们都已经习惯了 Windows 左下角的开始,从开始开始,展开一个大选单,逐步拉出所有的程式功能。不只是 WindowsLinux 也一样。在 Linux Gnome 的桌面下,也是从左上角 Gnome 的大脚丫,拉出所有的分类功能选单。不只如此, KDEMac ,也都差不多。这不是微软 Windows 的发明,可是不知不觉间,大家都这么做,使用者也都习惯了,从来没有人去质疑那个开始,所展开的整个资讯世界。

    + +

    可是,这真的是对的吗?电脑,可不可能有别的样子?

    + +

    当你把烧好的 XO Sugar 光碟插入光碟机,一开机,你会面对一个全然不同的画面:画面的中心,是 OLPC 象徵儿童的 XO 标志,环绕在 XO 周围围成一圈的,是一个一个称做 Activity 的图示。 XO SugarActivity (活动) 的概念取代 Application (应用程式) 。每一个 Activity 点进去,都可以从事不同的活动:画图板、记忆力游戏、数字游戏、方向游戏、精简离线版的 WikiPedia 百科、上网。透过内建的无线网卡, XO Sugar 还有同侪游戏:可以和旁边的 XO Sugar 连线,除了互传简讯外,还可以测量两台 OLPC 之间的距离,培养儿童的距离概念。

    + +

    在这么多的 Activities 、色彩丰富的画面之中,我急著找那个 Gnome 的大脚丫,那个将整个资讯世界展开的神奇按钮。可是,没有。

    + +

    XO Sugar 的桌面,巅覆了一般人对电脑的想像。我们已经太习惯那个开始选单了,忘记了一开始那个面对著空荡荡的画面和左下角的开始按钮,不知从何开始的自己。太习惯了,变成理所当然,所以当完全没接触过电脑的老人、小孩、穷人,面对同样空荡荡的画面和左下角的开始按钮,不知所措的时候,我们只剩下不耐烦,广开免费的电脑职训课程,希望他们快点学会电脑,快点进入那个开始的资讯世界。

    + +

    会不会其实,我们习以为常的 Windows ,习以为常的 Application ,才是最不人性化的世界?做为一个,我们需要的是什么样的电脑?

    + +

    接下来是广告时间。 ^_^ 虽然 Linux Gnome 桌面还是一个大脚丫,但 Sugar OS ,只有用 Linux 才做得到。因为 Linux 原始码开放,所以 OLPC 计划才能自己拿来改,做出和 Linux 完全不同的 Sugar OSOLPC 不可能拿 Windows 来改。 Windows 只有微软授权让厂商安装,厂商无法按照自己的想法去研发、去创造,去发挥想像力。微软在台湾打的电视广告,用美丽的声音说让想像力无限延伸,这是很讽刺的。结果又回到一个老问题:究竟是开放环境好,还是独占的封闭环境好呢?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 150 | + 151 | + 152 | + 153 | + 154 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0152.html.zh-tw.html b/htdocs/imacat/me/diary/0152.html.zh-tw.html new file mode 120000 index 0000000..bd1b01a --- /dev/null +++ b/htdocs/imacat/me/diary/0152.html.zh-tw.html @@ -0,0 +1 @@ +0152.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0152.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0152.html.zh-tw.xhtml new file mode 100644 index 0000000..a93cc59 --- /dev/null +++ b/htdocs/imacat/me/diary/0152.html.zh-tw.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百五十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百五十二

    + +
    + +
    + +
    +
    3.1.’09. 0:11am.
    + +

    OLPCSugar OS

    + +

    我想很多人,應該都聽過這個計劃:One Laptop per Child (OLPC) (給每個孩子一台電腦), a low-cost, connected laptop for the world’s children’s education

    + +

    OLPC 的口號是 give a laptop, change the world 。這是 2005 年麻省理工學院 MIT 教授 Nicholas Negroponte ,在 World Economic Forum 宣佈的計劃:如果我們能將筆記型電腦的價格壓到一台 100 美金,那能不能讓貧窮國家,每個兒童擁有一部電腦呢?

    + +

    這個計劃受到廣泛的注目,也立刻獲得國際大廠的支持: GoogleNews CorporationAMDRed HatBrightstarNortel Networks 立刻宣佈加入 OLPC 計劃,每家公司捐助 200 萬美元,成為 OLPC 創始會員。聯合國開發計劃署 UNDP 隔年也宣佈支持 OLPC

    + +

    OLPC 自行研發軟硬體,硬體委託台灣廣達電腦代工,軟體則由 Linux 改良。 OLPC 限定賣給國家,不賣私人企業,以一百萬台為單位。富有國家如台灣要買,買一台要捐一台給貧窮國家,也就是兩倍價錢。

    + +

    OLPC 後來的進展其實並不順利。原先計劃在 2007 年實現,可是到去年 2008 年底,售價也只能壓到一台 188 美元。(也就是台灣買要近 400 美元,比 Eee PC 貴!)去年底受景氣寒冬影響,裁撤掉了工程部門。工程部門由創始會員 Red Hat 接收,成立新的 Open Source 專案 Sugar OS 維護。不過 OLPC 倒是對電腦產業產生了很深遠的影響。受 OLPC 啟發,華碩推出了 Eee PC ,價格壓到 300 美元,造成了全球旋風,引發了後來的小筆電熱潮,各家業者競相投入市場。

    + +

    OLPC 即使不順利,還是很偉大的計劃。不過,我不是要介紹 OLPC ,而是要介紹 OLPC 的成果 Sugar OS最新版的 Sugar OS 光碟可以由網路下載。下載後,燒成光碟,用光碟開機,就可以了。

    + +

    為什麼要特別介紹 Sugar OS ?與其我在這裏說到說到辭窮,最好還是大家自己試試看。不過,為了不懂科技的大多數人,我還是勉強提一提吧。

    + +

    什麼是作業系統?什麼是電腦?

    + +

    我們都已經習慣了 Windows 左下角的開始,從開始開始,展開一個大選單,逐步拉出所有的程式功能。不只是 WindowsLinux 也一樣。在 Linux Gnome 的桌面下,也是從左上角 Gnome 的大腳丫,拉出所有的分類功能選單。不只如此, KDEMac ,也都差不多。這不是微軟 Windows 的發明,可是不知不覺間,大家都這麼做,使用者也都習慣了,從來沒有人去質疑那個開始,所展開的整個資訊世界。

    + +

    可是,這真的是對的嗎?電腦,可不可能有別的樣子?

    + +

    當你把燒好的 XO Sugar 光碟插入光碟機,一開機,你會面對一個全然不同的畫面:畫面的中心,是 OLPC 象徵兒童的 XO 標誌,環繞在 XO 周圍圍成一圈的,是一個一個稱做 Activity 的圖示。 XO SugarActivity (活動) 的概念取代 Application (應用程式) 。每一個 Activity 點進去,都可以從事不同的活動:畫圖板、記憶力遊戲、數字遊戲、方向遊戲、精簡離線版的 WikiPedia 百科、上網。透過內建的無線網卡, XO Sugar 還有同儕遊戲:可以和旁邊的 XO Sugar 連線,除了互傳簡訊外,還可以測量兩台 OLPC 之間的距離,培養兒童的距離概念。

    + +

    在這麼多的 Activities 、色彩豐富的畫面之中,我急著找那個 Gnome 的大腳丫,那個將整個資訊世界展開的神奇按鈕。可是,沒有。

    + +

    XO Sugar 的桌面,巔覆了一般人對電腦的想像。我們已經太習慣那個開始選單了,忘記了一開始那個面對著空蕩蕩的畫面和左下角的開始按鈕,不知從何開始的自己。太習慣了,變成理所當然,所以當完全沒接觸過電腦的老人、小孩、窮人,面對同樣空蕩蕩的畫面和左下角的開始按鈕,不知所措的時候,我們只剩下不耐煩,廣開免費的電腦職訓課程,希望他們快點學會電腦,快點進入那個開始的資訊世界。

    + +

    會不會其實,我們習以為常的 Windows ,習以為常的 Application ,才是最不人性化的世界?做為一個,我們需要的是什麼樣的電腦?

    + +

    接下來是廣告時間。 ^_^ 雖然 Linux Gnome 桌面還是一個大腳丫,但 Sugar OS ,只有用 Linux 才做得到。因為 Linux 原始碼開放,所以 OLPC 計劃才能自己拿來改,做出和 Linux 完全不同的 Sugar OSOLPC 不可能拿 Windows 來改。 Windows 只有微軟授權讓廠商安裝,廠商無法按照自己的想法去研發、去創造,去發揮想像力。微軟在台灣打的電視廣告,用美麗的聲音說讓想像力無限延伸,這是很諷刺的。結果又回到一個老問題:究竟是開放環境好,還是獨占的封閉環境好呢?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 150 | + 151 | + 152 | + 153 | + 154 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0153.html.en.html b/htdocs/imacat/me/diary/0153.html.en.html new file mode 120000 index 0000000..d9856e9 --- /dev/null +++ b/htdocs/imacat/me/diary/0153.html.en.html @@ -0,0 +1 @@ +0153.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0153.html.en.xhtml b/htdocs/imacat/me/diary/0153.html.en.xhtml new file mode 100644 index 0000000..c688079 --- /dev/null +++ b/htdocs/imacat/me/diary/0153.html.en.xhtml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 153 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 153

    + +
    + +
    + +
    +
    10.9.’09. 0:46am.
    + +

    大義…

    + +

    我以為我這麼久以來爭的,是軟體原始碼應不應該自由分享,知識應不應該自由散佈的大義

    + +

    沒想到到頭來,卻栽在 Ubuntu 到底有沒有比 Fedora 好, SLAT 到底是不是好人的這種問題上…

    + +

    唉…

    + +
    + +
    + +
    +
    10.9.’09. 0:03am.
    + +

    不是風動。不是旛動。仁者心動。

    + +
    —拜讀 Fred人之將死其言也善一文有感
    + +
    +

    一日思惟。時當弘法不可終遯。遂出至廣州法性寺。值印宗法師講涅槃經。時有風吹旛動。一僧曰風動。一僧曰旛動。議論不已。惠能進曰。不是風動。不是旛動。仁者心動。一眾駭然。

    + +
    —六祖壇經·行由品第一
    +
    + +

    很久以前聽過一個故事。故事是說,吳越兩國,原本不是世仇,兩國交界河邊有兩個小村,有一對情同姊妹的女子,常常一起結伴去河邊洗衣。有一天,其中一個女子洗衣時不慎弄傷了手。回家後第二天,弄傷手的女子的哥哥就上門興師問罪,打傷了另一個女子。另一個女子的家人非常憤怒,當晚就全家找上門去,把第一個女子的哥哥打死了。隔天,村人聞訊非常憤怒,就跑去把對方全家都殺死了。縣官得知了這件事,非常憤怒,就發兵攻打對岸的村落。從此兩國爭戰不休。

    + +

    現在回頭要找出處,已經找不到了。我以為這是莊子裏的故事,好像也不是。我很喜歡這個故事。如果有朋友知道原典的話,還請告知。

    + +

    我也是三十幾歲的人了,今年要過第三個牛年。經歷過的事,雖比不上白色恐怖坐牢,但大小事也經歷了很多。我曾經把椰林風情站弄到掛站過,成為全站公敵;也曾網路上為了弱勢的公娼和幾百人筆戰,管理過憤青像潮水一樣湧入不息的論壇。對於衝突,看得透了,也倦了。

    + +

    我寧可保持開放的態度,把每個人都當成好人,儘可能與人為善。即使這樣會吃點虧。不像很多人,我不是怕吃虧的人。人與人相處,難免會有誤會和衝突。如果所有的衝突都像我打你一巴掌,你打我一巴掌一樣,無限擴大的話,那永遠也沒完沒了。只要事情能解決,吃點小虧又何妨?為了硬是不吃虧而打到兩敗俱傷,原來的目的完全忘記了,那真是笨到不知如何形容。

    + +

    心中有敵我,每個人看起來都是敵人;心中沒有敵我,每個人都是好人。不是風動。不是旛動。仁者心動。敵人在心中,不在別處。

    + +

    記得前幾年看到日本綜藝節目火焰大對抗的單元小學生幫,小內和小南扮小學生,為了一兩句話,你碰我一下,我打你一下,到最後沒完沒了,可是事情的起頭只是一點小事。

    + +

    我可不想做那種小學生程度的事。這個人那個團體的恩怨,這個 Linux那個 Linux 誰好誰不好,也許在某人眼中,是關乎生死原則的大事。但在我眼中,通通都是極端無聊的小事。我躲了那麼多年,就是想躲開這些無謂的紛爭。沒想到一回頭,還是被捲入和我無關的恩怨中。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 151 | + 152 | + 153 | + 154 | + 155 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0153.html.zh-cn.html b/htdocs/imacat/me/diary/0153.html.zh-cn.html new file mode 120000 index 0000000..925ef0a --- /dev/null +++ b/htdocs/imacat/me/diary/0153.html.zh-cn.html @@ -0,0 +1 @@ +0153.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0153.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0153.html.zh-cn.xhtml new file mode 100644 index 0000000..92b24ca --- /dev/null +++ b/htdocs/imacat/me/diary/0153.html.zh-cn.xhtml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百五十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百五十三

    + +
    + +
    + +
    +
    10.9.’09. 0:46am.
    + +

    大义…

    + +

    我以为我这么久以来争的,是软体原始码应不应该自由分享,知识应不应该自由散布的大义

    + +

    没想到到头来,却栽在 Ubuntu 到底有没有比 Fedora 好, SLAT 到底是不是好人的这种问题上…

    + +

    唉…

    + +
    + +
    + +
    +
    10.9.’09. 0:03am.
    + +

    不是风动。不是幡动。仁者心动。

    + +
    —拜读 Fred人之将死其言也善一文有感
    + +
    +

    一日思惟。时当弘法不可终遯。遂出至广州法性寺。值印宗法师讲涅盘经。时有风吹幡动。一僧曰风动。一僧曰幡动。议论不已。惠能进曰。不是风动。不是幡动。仁者心动。一众骇然。

    + +
    —六祖坛经・行由品第一
    +
    + +

    很久以前听过一个故事。故事是说,吴越两国,原本不是世仇,两国交界河边有两个小村,有一对情同姊妹的女子,常常一起结伴去河边洗衣。有一天,其中一个女子洗衣时不慎弄伤了手。回家后第二天,弄伤手的女子的哥哥就上门兴师问罪,打伤了另一个女子。另一个女子的家人非常愤怒,当晚就全家找上门去,把第一个女子的哥哥打死了。隔天,村人闻讯非常愤怒,就跑去把对方全家都杀死了。县官得知了这件事,非常愤怒,就发兵攻打对岸的村落。从此两国争战不休。

    + +

    现在回头要找出处,已经找不到了。我以为这是庄子里的故事,好像也不是。我很喜欢这个故事。如果有朋友知道原典的话,还请告知。

    + +

    我也是三十几岁的人了,今年要过第三个牛年。经历过的事,虽比不上白色恐怖坐牢,但大小事也经历了很多。我曾经把椰林风情站弄到挂站过,成为全站公敌;也曾网路上为了弱势的公娼和几百人笔战,管理过愤青像潮水一样涌入不息的论坛。对於冲突,看得透了,也倦了。

    + +

    我宁可保持开放的态度,把每个人都当成好人,尽可能与人为善。即使这样会吃点亏。不像很多人,我不是怕吃亏的人。人与人相处,难免会有误会和冲突。如果所有的冲突都像我打你一巴掌,你打我一巴掌一样,无限扩大的话,那永远也没完没了。只要事情能解决,吃点小亏又何妨?为了硬是不吃亏而打到两败俱伤,原来的目的完全忘记了,那真是笨到不知如何形容。

    + +

    心中有敌我,每个人看起来都是敌人;心中没有敌我,每个人都是好人。不是风动。不是幡动。仁者心动。敌人在心中,不在别处。

    + +

    记得前几年看到日本综艺节目火焰大对抗的单元小学生帮,小内和小南扮小学生,为了一两句话,你碰我一下,我打你一下,到最后没完没了,可是事情的起头只是一点小事。

    + +

    我可不想做那种小学生程度的事。这个人那个团体的恩怨,这个 Linux那个 Linux 谁好谁不好,也许在某人眼中,是关乎生死原则的大事。但在我眼中,通通都是极端无聊的小事。我躲了那么多年,就是想躲开这些无谓的纷争。没想到一回头,还是被卷入和我无关的恩怨中。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 151 | + 152 | + 153 | + 154 | + 155 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0153.html.zh-tw.html b/htdocs/imacat/me/diary/0153.html.zh-tw.html new file mode 120000 index 0000000..92135a0 --- /dev/null +++ b/htdocs/imacat/me/diary/0153.html.zh-tw.html @@ -0,0 +1 @@ +0153.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0153.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0153.html.zh-tw.xhtml new file mode 100644 index 0000000..621ccba --- /dev/null +++ b/htdocs/imacat/me/diary/0153.html.zh-tw.xhtml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百五十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百五十三

    + +
    + +
    + +
    +
    10.9.’09. 0:46am.
    + +

    大義…

    + +

    我以為我這麼久以來爭的,是軟體原始碼應不應該自由分享,知識應不應該自由散佈的大義

    + +

    沒想到到頭來,卻栽在 Ubuntu 到底有沒有比 Fedora 好, SLAT 到底是不是好人的這種問題上…

    + +

    唉…

    + +
    + +
    + +
    +
    10.9.’09. 0:03am.
    + +

    不是風動。不是旛動。仁者心動。

    + +
    —拜讀 Fred人之將死其言也善一文有感
    + +
    +

    一日思惟。時當弘法不可終遯。遂出至廣州法性寺。值印宗法師講涅槃經。時有風吹旛動。一僧曰風動。一僧曰旛動。議論不已。惠能進曰。不是風動。不是旛動。仁者心動。一眾駭然。

    + +
    —六祖壇經·行由品第一
    +
    + +

    很久以前聽過一個故事。故事是說,吳越兩國,原本不是世仇,兩國交界河邊有兩個小村,有一對情同姊妹的女子,常常一起結伴去河邊洗衣。有一天,其中一個女子洗衣時不慎弄傷了手。回家後第二天,弄傷手的女子的哥哥就上門興師問罪,打傷了另一個女子。另一個女子的家人非常憤怒,當晚就全家找上門去,把第一個女子的哥哥打死了。隔天,村人聞訊非常憤怒,就跑去把對方全家都殺死了。縣官得知了這件事,非常憤怒,就發兵攻打對岸的村落。從此兩國爭戰不休。

    + +

    現在回頭要找出處,已經找不到了。我以為這是莊子裏的故事,好像也不是。我很喜歡這個故事。如果有朋友知道原典的話,還請告知。

    + +

    我也是三十幾歲的人了,今年要過第三個牛年。經歷過的事,雖比不上白色恐怖坐牢,但大小事也經歷了很多。我曾經把椰林風情站弄到掛站過,成為全站公敵;也曾網路上為了弱勢的公娼和幾百人筆戰,管理過憤青像潮水一樣湧入不息的論壇。對於衝突,看得透了,也倦了。

    + +

    我寧可保持開放的態度,把每個人都當成好人,儘可能與人為善。即使這樣會吃點虧。不像很多人,我不是怕吃虧的人。人與人相處,難免會有誤會和衝突。如果所有的衝突都像我打你一巴掌,你打我一巴掌一樣,無限擴大的話,那永遠也沒完沒了。只要事情能解決,吃點小虧又何妨?為了硬是不吃虧而打到兩敗俱傷,原來的目的完全忘記了,那真是笨到不知如何形容。

    + +

    心中有敵我,每個人看起來都是敵人;心中沒有敵我,每個人都是好人。不是風動。不是旛動。仁者心動。敵人在心中,不在別處。

    + +

    記得前幾年看到日本綜藝節目火焰大對抗的單元小學生幫,小內和小南扮小學生,為了一兩句話,你碰我一下,我打你一下,到最後沒完沒了,可是事情的起頭只是一點小事。

    + +

    我可不想做那種小學生程度的事。這個人那個團體的恩怨,這個 Linux那個 Linux 誰好誰不好,也許在某人眼中,是關乎生死原則的大事。但在我眼中,通通都是極端無聊的小事。我躲了那麼多年,就是想躲開這些無謂的紛爭。沒想到一回頭,還是被捲入和我無關的恩怨中。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 151 | + 152 | + 153 | + 154 | + 155 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0154.html.en.html b/htdocs/imacat/me/diary/0154.html.en.html new file mode 120000 index 0000000..e9015ac --- /dev/null +++ b/htdocs/imacat/me/diary/0154.html.en.html @@ -0,0 +1 @@ +0154.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0154.html.en.xhtml b/htdocs/imacat/me/diary/0154.html.en.xhtml new file mode 100644 index 0000000..54b02fd --- /dev/null +++ b/htdocs/imacat/me/diary/0154.html.en.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 154 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 154

    + +
    + +
    + +
    +
    10.19.’09. 2:06am.
    + +

    Skype 的怪訊息

    + +

    今天晚上收到兩則奇怪的 Skype 訊息:

    + +
    +
      +
    • [98.10.18 11:47:45 am] 總經理 Mr. 江 (icjiang1116): Hi 妳好, 我目前是一個持美國綠卡的台灣人,所以每年都必須往返美國兩次(每6個月必須回去一趟),住在台北市,台中市和美國德州的休士頓市,目前在台中經營餐飲連鎖新事業,長相還算不錯,個性熱情,積極,開放,真誠,率直,有責任感的男人.我正在尋找一位"感情忠誠", "熱愛性生活",以結婚為前提來交往的女友!如果以後結婚的話,或許也可以一起回去美國享受四處旅行的快樂生活.所以,請問妳是否就是我正在尋找的那個對象呢?

    • + +
    • [98.10.18 11:51:31 am] 總經理 Mr. 江 (icjiang1116): 是不想回答還是怎麼樣呢?不回答表示不願意是嗎? 我需要的是熱情的正常女人, 我不需要更不喜歡和放不開和不乾脆且性冷感的女人交往! 反正如果不能彼此信任, 直接乾脆一點的話就不必勉強了~ 既然妳堅持那麼不願意當我女友, 要對妳好和讓妳一起享受幸福生活還這麼龜毛和不珍惜的話就不必勉強了, 那麼不願意珍惜就算了吧, 那麼我就只好真的放棄妳了! 這是我XXX網的官方網站,自己等著看看我的連鎖品牌如何竄紅吧 --> http://somewhere.example

    • +
    +
    + +

    唔,這是詐騙吧? ^^;

    + +

    我那時候剛好開全螢幕玩遊戲去了,錯過了第一則,回來一口氣看到兩則,不是不回答他。不過就算及時看到了,我也不會回答他,會馬上封鎖並回報垃圾訊息。不過,雖然沒有及時看到,我還是封鎖並回報垃圾訊息了。

    + +

    莫名其妙自爆的傢伙。已經不知道從哪裏吐嘈起了。還是說,他的目的其實是宣傳他的網站呢?

    + +
    2013/11/22 更新
    + +

    早上看到學姊的噗,剛好最近在整理舊連結,回想起這件事。順手人肉了一下。原來還有人跟我有同樣的經歷,而且他的姓名、手機號碼、 Email 、出生年月日、照片都被抓出來了。網路真是可怕的地方。

    + +
      +
    1. 感想一:四年前不會人肉,現在已經習慣了。科技使用習慣的改變真可怕。

      +
    2. 感想二:如果是現在的我再碰到,說不定也能套出他的個資拿去報警。

      +
    + + + +
    +icjiang1116 +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 152 | + 153 | + 154 | + 155 | + 156 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0154.html.zh-cn.html b/htdocs/imacat/me/diary/0154.html.zh-cn.html new file mode 120000 index 0000000..c59dc65 --- /dev/null +++ b/htdocs/imacat/me/diary/0154.html.zh-cn.html @@ -0,0 +1 @@ +0154.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0154.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0154.html.zh-cn.xhtml new file mode 100644 index 0000000..157ce93 --- /dev/null +++ b/htdocs/imacat/me/diary/0154.html.zh-cn.xhtml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百五十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百五十四

    + +
    + +
    + +
    +
    10.19.’09. 2:06am.
    + +

    Skype 的怪讯息

    + +

    今天晚上收到两则奇怪的 Skype 讯息:

    + +
    +
      +
    • [98.10.18 11:47:45 am] 总经理 Mr. 江 (icjiang1116): Hi 你好, 我目前是一个持美国绿卡的台湾人,所以每年都必须往返美国两次(每6个月必须回去一趟),住在台北市,台中市和美国德州的休士顿市,目前在台中经营餐饮连锁新事业,长相还算不错,个性热情,积极,开放,真诚,率直,有责任感的男人.我正在寻找一位"感情忠诚", "热爱性生活",以结婚为前提来交往的女友!如果以后结婚的话,或许也可以一起回去美国享受四处旅行的快乐生活.所以,请问你是否就是我正在寻找的那个对象呢?

    • + +
    • [98.10.18 11:51:31 am] 总经理 Mr. 江 (icjiang1116): 是不想回答还是怎么样呢?不回答表示不愿意是吗? 我需要的是热情的正常女人, 我不需要更不喜欢和放不开和不干脆且性冷感的女人交往! 反正如果不能彼此信任, 直接干脆一点的话就不必勉强了~ 既然你坚持那么不愿意当我女友, 要对你好和让你一起享受幸福生活还这么龟毛和不珍惜的话就不必勉强了, 那么不愿意珍惜就算了吧, 那么我就只好真的放弃你了! 这是我XXX网的官方网站,自己等著看看我的连锁品牌如何窜红吧 --> http://somewhere.example

    • +
    +
    + +

    唔,这是诈骗吧? ^^;

    + +

    我那时候刚好开全萤幕玩游戏去了,错过了第一则,回来一口气看到两则,不是不回答他。不过就算及时看到了,我也不会回答他,会马上封锁并回报垃圾讯息。不过,虽然没有及时看到,我还是封锁并回报垃圾讯息了。

    + +

    莫名其妙自爆的家伙。已经不知道从哪里吐嘈起了。还是说,他的目的其实是宣传他的网站呢?

    + +
    2013/11/22 更新
    + +

    早上看到学姊的噗,刚好最近在整理旧连结,回想起这件事。顺手人肉了一下。原来还有人跟我有同样的经历,而且他的姓名、手机号码、 Email 、出生年月日、照片都被抓出来了。网路真是可怕的地方。

    + +
      +
    1. 感想一:四年前不会人肉,现在已经习惯了。科技使用习惯的改变真可怕。

      +
    2. 感想二:如果是现在的我再碰到,说不定也能套出他的个资拿去报警。

      +
    + + + +
    +icjiang1116 +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 152 | + 153 | + 154 | + 155 | + 156 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0154.html.zh-tw.html b/htdocs/imacat/me/diary/0154.html.zh-tw.html new file mode 120000 index 0000000..4978f7a --- /dev/null +++ b/htdocs/imacat/me/diary/0154.html.zh-tw.html @@ -0,0 +1 @@ +0154.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0154.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0154.html.zh-tw.xhtml new file mode 100644 index 0000000..161233e --- /dev/null +++ b/htdocs/imacat/me/diary/0154.html.zh-tw.xhtml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百五十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百五十四

    + +
    + +
    + +
    +
    10.19.’09. 2:06am.
    + +

    Skype 的怪訊息

    + +

    今天晚上收到兩則奇怪的 Skype 訊息:

    + +
    +
      +
    • [98.10.18 11:47:45 am] 總經理 Mr. 江 (icjiang1116): Hi 妳好, 我目前是一個持美國綠卡的台灣人,所以每年都必須往返美國兩次(每6個月必須回去一趟),住在台北市,台中市和美國德州的休士頓市,目前在台中經營餐飲連鎖新事業,長相還算不錯,個性熱情,積極,開放,真誠,率直,有責任感的男人.我正在尋找一位"感情忠誠", "熱愛性生活",以結婚為前提來交往的女友!如果以後結婚的話,或許也可以一起回去美國享受四處旅行的快樂生活.所以,請問妳是否就是我正在尋找的那個對象呢?

    • + +
    • [98.10.18 11:51:31 am] 總經理 Mr. 江 (icjiang1116): 是不想回答還是怎麼樣呢?不回答表示不願意是嗎? 我需要的是熱情的正常女人, 我不需要更不喜歡和放不開和不乾脆且性冷感的女人交往! 反正如果不能彼此信任, 直接乾脆一點的話就不必勉強了~ 既然妳堅持那麼不願意當我女友, 要對妳好和讓妳一起享受幸福生活還這麼龜毛和不珍惜的話就不必勉強了, 那麼不願意珍惜就算了吧, 那麼我就只好真的放棄妳了! 這是我XXX網的官方網站,自己等著看看我的連鎖品牌如何竄紅吧 --> http://somewhere.example

    • +
    +
    + +

    唔,這是詐騙吧? ^^;

    + +

    我那時候剛好開全螢幕玩遊戲去了,錯過了第一則,回來一口氣看到兩則,不是不回答他。不過就算及時看到了,我也不會回答他,會馬上封鎖並回報垃圾訊息。不過,雖然沒有及時看到,我還是封鎖並回報垃圾訊息了。

    + +

    莫名其妙自爆的傢伙。已經不知道從哪裏吐嘈起了。還是說,他的目的其實是宣傳他的網站呢?

    + +
    2013/11/22 更新
    + +

    早上看到學姊的噗,剛好最近在整理舊連結,回想起這件事。順手人肉了一下。原來還有人跟我有同樣的經歷,而且他的姓名、手機號碼、 Email 、出生年月日、照片都被抓出來了。網路真是可怕的地方。

    + +
      +
    1. 感想一:四年前不會人肉,現在已經習慣了。科技使用習慣的改變真可怕。

      +
    2. 感想二:如果是現在的我再碰到,說不定也能套出他的個資拿去報警。

      +
    + + + +
    +icjiang1116 +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 152 | + 153 | + 154 | + 155 | + 156 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0155.html.en.html b/htdocs/imacat/me/diary/0155.html.en.html new file mode 120000 index 0000000..f15b1a0 --- /dev/null +++ b/htdocs/imacat/me/diary/0155.html.en.html @@ -0,0 +1 @@ +0155.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0155.html.en.xhtml b/htdocs/imacat/me/diary/0155.html.en.xhtml new file mode 100644 index 0000000..42edf39 --- /dev/null +++ b/htdocs/imacat/me/diary/0155.html.en.xhtml @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 155 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 155

    + +
    + +
    + +
    +
    1.5.’10. 10:54am.
    + +

    田園將蕪,胡不歸

    + +
    +

    《歸去來辭》

    + +
    陶淵明
    + +歸去來兮,田園將蕪,胡不歸?
    +既自以心為形役,奚惆悵而獨悲?
    +悟已往之不諫,知來者之可追。
    +實迷途其未遠,覺今是而昨非。
    +
    +舟遙遙以輕颺,風飄飄而吹衣,問征夫以前路,恨晨光之希微。
    +乃瞻衡宇,載欣載奔,僮僕歡迎,稚子候門。
    +三徑就荒,松菊猶存。攜幼入室,有酒盈樽。
    +
    +引壺觴以自酌,眄庭柯以怡顏,倚南窗以寄傲,審容膝之易安。
    +園日涉以成趣,門雖設而常關;策扶老以流憩,時翹首而遐觀。
    +雲無心以出岫,鳥倦飛而知還;景翳翳其將入,撫孤松而盤桓。
    +
    +歸去來兮,請息交以絕游,世與我而相遺,復駕言兮焉求!
    +悅親戚之情話,樂琴書以消憂。農人告余以春及,將有事於西疇。
    +或命巾車,或棹孤舟,既窈窕以尋壑,亦崎嶇而經丘。
    +木欣欣以向榮,泉涓涓而始流,善萬物之得時,感吾生之行休。
    +
    +已矣乎!寓形宇內復幾時,曷不委心任去留,胡為乎遑遑欲何之?
    +富貴非吾願,帝鄉不可期。
    +懷良晨以孤往,或植杖而耘耔,登東皋以舒嘯,臨清流而賦詩;
    +聊乘化而歸盡,樂夫天命復奚疑!
    +
    + +

    有一種生活整個荒蕪了好久的感覺。

    + +

    辭掉一整年自己全心投入,還是做得不開心的工作,開始整理生活。回頭看,身後一片荒蕪。

    + +

    開始一點一點重新撿拾起來。

    + +

    新買的電腦,要安裝作業系統。看著以前寫的灌電腦的標準作業程序筆記,覺得好陌生。該安裝的軟體,一點一點下載安裝。筆記中的好多事項,好像都不大適用了。

    + +

    衣架上,掛著該手洗卻沒空手洗的衣服。該手洗的衣服,要一件一件手洗。當作儲藏室的隔壁房間,堆滿待清理的空紙箱,還有壞掉待送回收的舊電視。桌上堆滿了新(?)買未收的電子產品說明書。該讀的報紙和新聞堆了四、五天。該記的帳也幾天沒記了,還有年底設備的折舊計算。幾件幾個月沒處理的工作。信箱裏,則堆了好幾封外國朋友的信件未處理。

    + +

    今天中午要炒菜的肉絲,先拿出來退冰吧。田園將蕪,胡不歸。我回來了。嗯。

    + +
    + +
    + +
    +
    10.31.’09. 12:21pm.
    + +

    炒菠菜

    + +
    +炒菠菜 +

    炒菠菜

    +
    + +

    試吃了一口:好辣!菜太少配料太多了吧。

    + +

    只有一個人又沒有白飯,就炒一把菠菜當午餐吧。

    + +

    好久沒吃菠菜了,也好久沒下廚了呢~ ^_*'

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 153 | + 154 | + 155 | + 156 | + 157 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0155.html.zh-cn.html b/htdocs/imacat/me/diary/0155.html.zh-cn.html new file mode 120000 index 0000000..cf0ef9b --- /dev/null +++ b/htdocs/imacat/me/diary/0155.html.zh-cn.html @@ -0,0 +1 @@ +0155.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0155.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0155.html.zh-cn.xhtml new file mode 100644 index 0000000..5c1be7c --- /dev/null +++ b/htdocs/imacat/me/diary/0155.html.zh-cn.xhtml @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百五十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百五十五

    + +
    + +
    + +
    +
    1.5.’10. 10:54am.
    + +

    田园将芜,胡不归

    + +
    +

    《归去来辞》

    + +
    陶渊明
    + +归去来兮,田园将芜,胡不归?
    +既自以心为形役,奚惆怅而独悲?
    +悟已往之不谏,知来者之可追。
    +实迷途其未远,觉今是而昨非。
    +
    +舟遥遥以轻扬,风飘飘而吹衣,问征夫以前路,恨晨光之希微。
    +乃瞻衡宇,载欣载奔,僮仆欢迎,稚子候门。
    +三径就荒,松菊犹存。携幼入室,有酒盈樽。
    +
    +引壶觞以自酌,眄庭柯以怡颜,倚南窗以寄傲,审容膝之易安。
    +园日涉以成趣,门虽设而常关;策扶老以流憩,时翘首而遐观。
    +云无心以出岫,鸟倦飞而知还;景翳翳其将入,抚孤松而盘桓。
    +
    +归去来兮,请息交以绝游,世与我而相遗,复驾言兮焉求!
    +悦亲戚之情话,乐琴书以消忧。农人告余以春及,将有事於西畴。
    +或命巾车,或棹孤舟,既窈窕以寻壑,亦崎岖而经丘。
    +木欣欣以向荣,泉涓涓而始流,善万物之得时,感吾生之行休。
    +
    +已矣乎!寓形宇内复几时,曷不委心任去留,胡为乎遑遑欲何之?
    +富贵非吾愿,帝乡不可期。
    +怀良晨以孤往,或植杖而耘耔,登东皋以舒啸,临清流而赋诗;
    +聊乘化而归尽,乐夫天命复奚疑!
    +
    + +

    有一种生活整个荒芜了好久的感觉。

    + +

    辞掉一整年自己全心投入,还是做得不开心的工作,开始整理生活。回头看,身后一片荒芜。

    + +

    开始一点一点重新捡拾起来。

    + +

    新买的电脑,要安装作业系统。看著以前写的灌电脑的标准作业程序笔记,觉得好陌生。该安装的软体,一点一点下载安装。笔记中的好多事项,好像都不大适用了。

    + +

    衣架上,挂著该手洗却没空手洗的衣服。该手洗的衣服,要一件一件手洗。当作储藏室的隔壁房间,堆满待清理的空纸箱,还有坏掉待送回收的旧电视。桌上堆满了新(?)买未收的电子产品说明书。该读的报纸和新闻堆了四、五天。该记的帐也几天没记了,还有年底设备的折旧计算。几件几个月没处理的工作。信箱里,则堆了好几封外国朋友的信件未处理。

    + +

    今天中午要炒菜的肉丝,先拿出来退冰吧。田园将芜,胡不归。我回来了。嗯。

    + +
    + +
    + +
    +
    10.31.’09. 12:21pm.
    + +

    炒菠菜

    + +
    +炒菠菜 +

    炒菠菜

    +
    + +

    试吃了一口:好辣!菜太少配料太多了吧。

    + +

    只有一个人又没有白饭,就炒一把菠菜当午餐吧。

    + +

    好久没吃菠菜了,也好久没下厨了呢~ ^_*'

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 153 | + 154 | + 155 | + 156 | + 157 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0155.html.zh-tw.html b/htdocs/imacat/me/diary/0155.html.zh-tw.html new file mode 120000 index 0000000..f1b266c --- /dev/null +++ b/htdocs/imacat/me/diary/0155.html.zh-tw.html @@ -0,0 +1 @@ +0155.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0155.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0155.html.zh-tw.xhtml new file mode 100644 index 0000000..b936184 --- /dev/null +++ b/htdocs/imacat/me/diary/0155.html.zh-tw.xhtml @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百五十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百五十五

    + +
    + +
    + +
    +
    1.5.’10. 10:54am.
    + +

    田園將蕪,胡不歸

    + +
    +

    《歸去來辭》

    + +
    陶淵明
    + +歸去來兮,田園將蕪,胡不歸?
    +既自以心為形役,奚惆悵而獨悲?
    +悟已往之不諫,知來者之可追。
    +實迷途其未遠,覺今是而昨非。
    +
    +舟遙遙以輕颺,風飄飄而吹衣,問征夫以前路,恨晨光之希微。
    +乃瞻衡宇,載欣載奔,僮僕歡迎,稚子候門。
    +三徑就荒,松菊猶存。攜幼入室,有酒盈樽。
    +
    +引壺觴以自酌,眄庭柯以怡顏,倚南窗以寄傲,審容膝之易安。
    +園日涉以成趣,門雖設而常關;策扶老以流憩,時翹首而遐觀。
    +雲無心以出岫,鳥倦飛而知還;景翳翳其將入,撫孤松而盤桓。
    +
    +歸去來兮,請息交以絕游,世與我而相遺,復駕言兮焉求!
    +悅親戚之情話,樂琴書以消憂。農人告余以春及,將有事於西疇。
    +或命巾車,或棹孤舟,既窈窕以尋壑,亦崎嶇而經丘。
    +木欣欣以向榮,泉涓涓而始流,善萬物之得時,感吾生之行休。
    +
    +已矣乎!寓形宇內復幾時,曷不委心任去留,胡為乎遑遑欲何之?
    +富貴非吾願,帝鄉不可期。
    +懷良晨以孤往,或植杖而耘耔,登東皋以舒嘯,臨清流而賦詩;
    +聊乘化而歸盡,樂夫天命復奚疑!
    +
    + +

    有一種生活整個荒蕪了好久的感覺。

    + +

    辭掉一整年自己全心投入,還是做得不開心的工作,開始整理生活。回頭看,身後一片荒蕪。

    + +

    開始一點一點重新撿拾起來。

    + +

    新買的電腦,要安裝作業系統。看著以前寫的灌電腦的標準作業程序筆記,覺得好陌生。該安裝的軟體,一點一點下載安裝。筆記中的好多事項,好像都不大適用了。

    + +

    衣架上,掛著該手洗卻沒空手洗的衣服。該手洗的衣服,要一件一件手洗。當作儲藏室的隔壁房間,堆滿待清理的空紙箱,還有壞掉待送回收的舊電視。桌上堆滿了新(?)買未收的電子產品說明書。該讀的報紙和新聞堆了四、五天。該記的帳也幾天沒記了,還有年底設備的折舊計算。幾件幾個月沒處理的工作。信箱裏,則堆了好幾封外國朋友的信件未處理。

    + +

    今天中午要炒菜的肉絲,先拿出來退冰吧。田園將蕪,胡不歸。我回來了。嗯。

    + +
    + +
    + +
    +
    10.31.’09. 12:21pm.
    + +

    炒菠菜

    + +
    +炒菠菜 +

    炒菠菜

    +
    + +

    試吃了一口:好辣!菜太少配料太多了吧。

    + +

    只有一個人又沒有白飯,就炒一把菠菜當午餐吧。

    + +

    好久沒吃菠菜了,也好久沒下廚了呢~ ^_*'

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 153 | + 154 | + 155 | + 156 | + 157 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0156.html.en.html b/htdocs/imacat/me/diary/0156.html.en.html new file mode 120000 index 0000000..39ff89a --- /dev/null +++ b/htdocs/imacat/me/diary/0156.html.en.html @@ -0,0 +1 @@ +0156.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0156.html.en.xhtml b/htdocs/imacat/me/diary/0156.html.en.xhtml new file mode 100644 index 0000000..682ff12 --- /dev/null +++ b/htdocs/imacat/me/diary/0156.html.en.xhtml @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 156 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 156

    + +
    + +
    + +
    +
    2.3.’10. 8:10am.
    + +

    The Recursive Version of the Magic Square Function

    + +

    From exercise 8 of Chapter 1.4.3 in Fundamentals of Data Structures in C.

    + +
    /* Filename:    exer-1.4.3-8.c
    +   Description: A recursive version of the magic square program (Program 1.22)
    +   Source:      Exercise 8 of 1.4.3 from Fundamentals of Data Structures in C
    +   Version:     1.0.0
    +   Author:      imacat <imacat@mail.imacat.idv.tw>
    +   Date:        2010-02-03
    +   Copyright:   (c) 2010 imacat */
    +
    +/* Headers */
    +#include <stdio.h>
    +#include <stdlib.h>
    +
    +/* Configuration */
    +#define MAX_SIZE  15
    +
    +/* Prototypes */
    +void *xmalloc (size_t size);
    +void gen_magic_square (int **square, int size, int *i, int *j, int index);
    +
    +/* Main program */
    +int
    +main (int argc, char *argv[])
    +{
    +  int **square;
    +  int size, i, j;
    +
    +  while (1) {
    +    printf ("Enter the size of the square: ");
    +    scanf ("%d", &size);
    +    if (size < 1 && size > MAX_SIZE + 1) {
    +      fprintf (stderr, "Please input a size between 1 and %d.\n", MAX_SIZE);
    +    } else if (size % 2 == 0) {
    +      fprintf (stderr, "Please input an odd size.\n");
    +    } else {
    +      break;
    +    }
    +  }
    +
    +  /* Initialize the square */
    +  square = (int **) xmalloc (sizeof (int *) * size);
    +  for (i = 0; i < size; i++) {
    +    square[i] = (int *) xmalloc (sizeof (int) * size);
    +    for (j = 0; j < size; j++) {
    +      square[i][j] = 0;
    +    }
    +  }
    +
    +  i = 0;
    +  j = (size - 1) / 2;
    +  gen_magic_square (square, size, &i, &j, size * size);
    +
    +  /* Output the magic square */
    +  printf ("Magic Squre of size %d:\n\n", size);
    +  for (i = 0; i < size; i++) {
    +    for (j = 0; j < size; j++) {
    +      printf ("%5d", square[i][j]);
    +    }
    +    printf ("\n");
    +  }
    +  printf ("\n");
    +  return 0;
    +}
    +
    +/* xmalloc: malloc() and handles the error.
    +     return: the pointer. */
    +void *
    +xmalloc (size_t size)
    +{
    +  void *p;
    +
    +  p = malloc (size);
    +  if (p == NULL) {
    +    fprintf (stderr, "Failed allocate %ld bytes memory.\n", size);
    +    exit (1);
    +  }
    +  return p;
    +}
    +
    +/* gen_magic_square: Generate the magic square.
    +     return: none. */
    +void
    +gen_magic_square (int **square, int size, int *i, int *j, int count)
    +{
    +  int i1, j1;
    +
    +  if (count == 1) {
    +    square[*i][*j] = count;
    +    return;
    +  }
    +
    +  /* Get into the next number */
    +  gen_magic_square (square, size, i, j, count  - 1);
    +
    +  i1 = (*i > 0)? *i - 1: size - 1;
    +  j1 = (*j > 0)? *j - 1: size - 1;
    +  if (square[i1][j1] != 0) {
    +    j1 = *j;
    +    i1 = *i + 1;
    +    if (i1 >= size) {
    +      i1 = 0;
    +    }
    +  }
    +  *i = i1;
    +  *j = j1;
    +  square[*i][*j] = count;
    +  return;
    +}
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 154 | + 155 | + 156 | + 157 | + 158 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0156.html.zh-cn.html b/htdocs/imacat/me/diary/0156.html.zh-cn.html new file mode 120000 index 0000000..b914710 --- /dev/null +++ b/htdocs/imacat/me/diary/0156.html.zh-cn.html @@ -0,0 +1 @@ +0156.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0156.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0156.html.zh-cn.xhtml new file mode 100644 index 0000000..ef6883b --- /dev/null +++ b/htdocs/imacat/me/diary/0156.html.zh-cn.xhtml @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百五十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百五十六

    + +
    + +
    + +
    +
    2.3.’10. 8:10am.
    + +

    The Recursive Version of the Magic Square Function

    + +

    From exercise 8 of Chapter 1.4.3 in Fundamentals of Data Structures in C.

    + +
    /* Filename:    exer-1.4.3-8.c
    +   Description: A recursive version of the magic square program (Program 1.22)
    +   Source:      Exercise 8 of 1.4.3 from Fundamentals of Data Structures in C
    +   Version:     1.0.0
    +   Author:      imacat <imacat@mail.imacat.idv.tw>
    +   Date:        2010-02-03
    +   Copyright:   (c) 2010 imacat */
    +
    +/* Headers */
    +#include <stdio.h>
    +#include <stdlib.h>
    +
    +/* Configuration */
    +#define MAX_SIZE  15
    +
    +/* Prototypes */
    +void *xmalloc (size_t size);
    +void gen_magic_square (int **square, int size, int *i, int *j, int index);
    +
    +/* Main program */
    +int
    +main (int argc, char *argv[])
    +{
    +  int **square;
    +  int size, i, j;
    +
    +  while (1) {
    +    printf ("Enter the size of the square: ");
    +    scanf ("%d", &size);
    +    if (size < 1 && size > MAX_SIZE + 1) {
    +      fprintf (stderr, "Please input a size between 1 and %d.\n", MAX_SIZE);
    +    } else if (size % 2 == 0) {
    +      fprintf (stderr, "Please input an odd size.\n");
    +    } else {
    +      break;
    +    }
    +  }
    +
    +  /* Initialize the square */
    +  square = (int **) xmalloc (sizeof (int *) * size);
    +  for (i = 0; i < size; i++) {
    +    square[i] = (int *) xmalloc (sizeof (int) * size);
    +    for (j = 0; j < size; j++) {
    +      square[i][j] = 0;
    +    }
    +  }
    +
    +  i = 0;
    +  j = (size - 1) / 2;
    +  gen_magic_square (square, size, &i, &j, size * size);
    +
    +  /* Output the magic square */
    +  printf ("Magic Squre of size %d:\n\n", size);
    +  for (i = 0; i < size; i++) {
    +    for (j = 0; j < size; j++) {
    +      printf ("%5d", square[i][j]);
    +    }
    +    printf ("\n");
    +  }
    +  printf ("\n");
    +  return 0;
    +}
    +
    +/* xmalloc: malloc() and handles the error.
    +     return: the pointer. */
    +void *
    +xmalloc (size_t size)
    +{
    +  void *p;
    +
    +  p = malloc (size);
    +  if (p == NULL) {
    +    fprintf (stderr, "Failed allocate %ld bytes memory.\n", size);
    +    exit (1);
    +  }
    +  return p;
    +}
    +
    +/* gen_magic_square: Generate the magic square.
    +     return: none. */
    +void
    +gen_magic_square (int **square, int size, int *i, int *j, int count)
    +{
    +  int i1, j1;
    +
    +  if (count == 1) {
    +    square[*i][*j] = count;
    +    return;
    +  }
    +
    +  /* Get into the next number */
    +  gen_magic_square (square, size, i, j, count  - 1);
    +
    +  i1 = (*i > 0)? *i - 1: size - 1;
    +  j1 = (*j > 0)? *j - 1: size - 1;
    +  if (square[i1][j1] != 0) {
    +    j1 = *j;
    +    i1 = *i + 1;
    +    if (i1 >= size) {
    +      i1 = 0;
    +    }
    +  }
    +  *i = i1;
    +  *j = j1;
    +  square[*i][*j] = count;
    +  return;
    +}
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 154 | + 155 | + 156 | + 157 | + 158 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0156.html.zh-tw.html b/htdocs/imacat/me/diary/0156.html.zh-tw.html new file mode 120000 index 0000000..128fc6c --- /dev/null +++ b/htdocs/imacat/me/diary/0156.html.zh-tw.html @@ -0,0 +1 @@ +0156.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0156.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0156.html.zh-tw.xhtml new file mode 100644 index 0000000..d8fa488 --- /dev/null +++ b/htdocs/imacat/me/diary/0156.html.zh-tw.xhtml @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百五十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百五十六

    + +
    + +
    + +
    +
    2.3.’10. 8:10am.
    + +

    The Recursive Version of the Magic Square Function

    + +

    From exercise 8 of Chapter 1.4.3 in Fundamentals of Data Structures in C.

    + +
    /* Filename:    exer-1.4.3-8.c
    +   Description: A recursive version of the magic square program (Program 1.22)
    +   Source:      Exercise 8 of 1.4.3 from Fundamentals of Data Structures in C
    +   Version:     1.0.0
    +   Author:      imacat <imacat@mail.imacat.idv.tw>
    +   Date:        2010-02-03
    +   Copyright:   (c) 2010 imacat */
    +
    +/* Headers */
    +#include <stdio.h>
    +#include <stdlib.h>
    +
    +/* Configuration */
    +#define MAX_SIZE  15
    +
    +/* Prototypes */
    +void *xmalloc (size_t size);
    +void gen_magic_square (int **square, int size, int *i, int *j, int index);
    +
    +/* Main program */
    +int
    +main (int argc, char *argv[])
    +{
    +  int **square;
    +  int size, i, j;
    +
    +  while (1) {
    +    printf ("Enter the size of the square: ");
    +    scanf ("%d", &size);
    +    if (size < 1 && size > MAX_SIZE + 1) {
    +      fprintf (stderr, "Please input a size between 1 and %d.\n", MAX_SIZE);
    +    } else if (size % 2 == 0) {
    +      fprintf (stderr, "Please input an odd size.\n");
    +    } else {
    +      break;
    +    }
    +  }
    +
    +  /* Initialize the square */
    +  square = (int **) xmalloc (sizeof (int *) * size);
    +  for (i = 0; i < size; i++) {
    +    square[i] = (int *) xmalloc (sizeof (int) * size);
    +    for (j = 0; j < size; j++) {
    +      square[i][j] = 0;
    +    }
    +  }
    +
    +  i = 0;
    +  j = (size - 1) / 2;
    +  gen_magic_square (square, size, &i, &j, size * size);
    +
    +  /* Output the magic square */
    +  printf ("Magic Squre of size %d:\n\n", size);
    +  for (i = 0; i < size; i++) {
    +    for (j = 0; j < size; j++) {
    +      printf ("%5d", square[i][j]);
    +    }
    +    printf ("\n");
    +  }
    +  printf ("\n");
    +  return 0;
    +}
    +
    +/* xmalloc: malloc() and handles the error.
    +     return: the pointer. */
    +void *
    +xmalloc (size_t size)
    +{
    +  void *p;
    +
    +  p = malloc (size);
    +  if (p == NULL) {
    +    fprintf (stderr, "Failed allocate %ld bytes memory.\n", size);
    +    exit (1);
    +  }
    +  return p;
    +}
    +
    +/* gen_magic_square: Generate the magic square.
    +     return: none. */
    +void
    +gen_magic_square (int **square, int size, int *i, int *j, int count)
    +{
    +  int i1, j1;
    +
    +  if (count == 1) {
    +    square[*i][*j] = count;
    +    return;
    +  }
    +
    +  /* Get into the next number */
    +  gen_magic_square (square, size, i, j, count  - 1);
    +
    +  i1 = (*i > 0)? *i - 1: size - 1;
    +  j1 = (*j > 0)? *j - 1: size - 1;
    +  if (square[i1][j1] != 0) {
    +    j1 = *j;
    +    i1 = *i + 1;
    +    if (i1 >= size) {
    +      i1 = 0;
    +    }
    +  }
    +  *i = i1;
    +  *j = j1;
    +  square[*i][*j] = count;
    +  return;
    +}
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 154 | + 155 | + 156 | + 157 | + 158 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0157.html.en.html b/htdocs/imacat/me/diary/0157.html.en.html new file mode 120000 index 0000000..3e6bf82 --- /dev/null +++ b/htdocs/imacat/me/diary/0157.html.en.html @@ -0,0 +1 @@ +0157.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0157.html.en.xhtml b/htdocs/imacat/me/diary/0157.html.en.xhtml new file mode 100644 index 0000000..04364ec --- /dev/null +++ b/htdocs/imacat/me/diary/0157.html.en.xhtml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 157 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 157

    + +
    + +
    + +
    +
    2.19.’10. 4:32am.
    + +

    美少女戰士 美少女戦士セーラームーン

    + +
    +美少女戰士 +
    + +

    武内直子美少女戰士是我幾部很想找來看完的舊動漫之一。它卡通在播映的1992-1997年,大約是我大學時候到離開大學以後的事,沒什麼機會看到。那時美少女戰士很紅,到處都有人說代替月亮懲罰你,我一直很想知道是什麼意思。因為沒看,所以也不知道原作到底是卡通,還是漫畫。

    + +

    一直到前兩年,才在西門町的萌點女僕咖啡,看到美少女戰士的彩色 TV 版。自此,每次去萌點女僕咖啡坐,都挑美少女戰士來看。可是咖啡店沒辦法常去坐太久,一直看得很慢。

    + +

    初一下午和家人去動物園,晚上去高雄三多路的漫畫國度看看有沒有新漫畫,碰巧讓我看到舊的美少女戰士漫畫原作。這麼難得的機會,想想,就放棄了看新刊的念頭。全部有十八集,漫畫國度缺了第十六和第十八集。我找了一個有電腦的位置,就坐下來看了。感覺真是超棒。不過漫畫國度是計時制的,一分鐘一元,很貴。中間缺的第十六集,我上網補看;第十八集,先結完帳再回家看。即使如此,結帳時還是花了 423 元,等於是七個小時,好貴!

    + +

    月野兔是一個普通的國中生,遇到了黑貓露娜,得到了變身為水手月亮的能力。在經歷了黑暗王國的戰鬥後,月野兔終於知道,自己是月亮上銀千年王國的公主西蕾妮蒂的轉世。而在身邊的的場衛,就是晚禮服假面,也是自己前世的戀人,地球國的王子安迪米歐。而自己的眼淚的結晶,就是銀千年王國最終的寶物幻之銀水晶。而身邊的朋友天才少女水野亞美是水手水星,巫女火野麗是水手火星,怪力女木野真琴是水手木星,原先以為是月亮公主的水手V愛野美奈子,則是水手金星。

    + +

    消滅黑暗王國的野心後,回復平靜生活的水手們,突然出現一個謎樣小女孩小阿兔,又遭到黑色月亮的攻擊,企圖奪取月亮。原來小阿兔是自三十世紀來的,月野兔和的場衛的女兒,月亮王國未來的小公主。回到了三十世紀,也得知了時間之門看守人水手冥王星的存在。

    + +

    消滅黑色月亮的野心,回到現代後,東京海埔新生地無限州的中心大樓,發生異常現象,水手門潛入調查,發現了法老王90所率領的死亡幻影的野心。獨立行動調查的水手天王星,賽車手天王遙,和水手海王星,小提琴家海王滿,及水手冥王星的轉世冥王雪奈。喚醒了擁有毀滅力量的水手土星土萌螢,最後消滅了死亡幻影的野心,月野兔和天王遙、海王滿兩邊合好,轉世的土萌螢由天王遙、海王滿、冥王雪奈一起照顧。

    + +

    死亡月球化身馬戲團及麾下的亞馬遜四人組入侵小鎮。在水手水星、水手火星、水手木星、水手金星等四人逐一領悟變身以後,終於打敗死亡月球馬戲團,亞馬遜四人組,也成了日後三十世紀小阿兔的伙伴。

    + +

    最後,小兔遭到水手凱拉克西亞所率領的水手戰士的攻擊,並接連失去了阿衛、水手水星、水手火星、水手木星、水手金星、水手土星、水手天王星、水手海王星、水手冥王星。在同樣被攻擊,失去水手戰士星光三人組的火球公主,及水手宇宙小小兔和一起並肩戰鬥下,終於打敗了敵人。

    + +

    覺得出場角色越來越多,看到最後好累。我還是最喜歡代表聰明智慧的水手水星亞美,可是到最後角色越來越多,亞美的戲份也被稀釋掉了。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 155 | + 156 | + 157 | + 158 | + 159 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0157.html.zh-cn.html b/htdocs/imacat/me/diary/0157.html.zh-cn.html new file mode 120000 index 0000000..d4f194c --- /dev/null +++ b/htdocs/imacat/me/diary/0157.html.zh-cn.html @@ -0,0 +1 @@ +0157.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0157.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0157.html.zh-cn.xhtml new file mode 100644 index 0000000..cae2105 --- /dev/null +++ b/htdocs/imacat/me/diary/0157.html.zh-cn.xhtml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百五十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百五十七

    + +
    + +
    + +
    +
    2.19.’10. 4:32am.
    + +

    美少女战士 美少女戦士セーラームーン

    + +
    +美少女战士 +
    + +

    武内直子美少女战士是我几部很想找来看完的旧动漫之一。它卡通在播映的1992-1997年,大约是我大学时候到离开大学以后的事,没什么机会看到。那时美少女战士很红,到处都有人说代替月亮惩罚你,我一直很想知道是什么意思。因为没看,所以也不知道原作到底是卡通,还是漫画。

    + +

    一直到前两年,才在西门町的萌点女仆咖啡,看到美少女战士的彩色 TV 版。自此,每次去萌点女仆咖啡坐,都挑美少女战士来看。可是咖啡店没办法常去坐太久,一直看得很慢。

    + +

    初一下午和家人去动物园,晚上去高雄三多路的漫画国度看看有没有新漫画,碰巧让我看到旧的美少女战士漫画原作。这么难得的机会,想想,就放弃了看新刊的念头。全部有十八集,漫画国度缺了第十六和第十八集。我找了一个有电脑的位置,就坐下来看了。感觉真是超棒。不过漫画国度是计时制的,一分钟一元,很贵。中间缺的第十六集,我上网补看;第十八集,先结完帐再回家看。即使如此,结帐时还是花了 423 元,等於是七个小时,好贵!

    + +

    月野兔是一个普通的国中生,遇到了黑猫露娜,得到了变身为水手月亮的能力。在经历了黑暗王国的战斗后,月野兔终於知道,自己是月亮上银千年王国的公主西蕾妮蒂的转世。而在身边的的场卫,就是晚礼服假面,也是自己前世的恋人,地球国的王子安迪米欧。而自己的眼泪的结晶,就是银千年王国最终的宝物幻之银水晶。而身边的朋友天才少女水野亚美是水手水星,巫女火野丽是水手火星,怪力女木野真琴是水手木星,原先以为是月亮公主的水手V爱野美奈子,则是水手金星。

    + +

    消灭黑暗王国的野心后,回复平静生活的水手们,突然出现一个谜样小女孩小阿兔,又遭到黑色月亮的攻击,企图夺取月亮。原来小阿兔是自三十世纪来的,月野兔和的场卫的女儿,月亮王国未来的小公主。回到了三十世纪,也得知了时间之门看守人水手冥王星的存在。

    + +

    消灭黑色月亮的野心,回到现代后,东京海埔新生地无限州的中心大楼,发生异常现象,水手门潜入调查,发现了法老王90所率领的死亡幻影的野心。独立行动调查的水手天王星,赛车手天王遥,和水手海王星,小提琴家海王满,及水手冥王星的转世冥王雪奈。唤醒了拥有毁灭力量的水手土星土萌萤,最后消灭了死亡幻影的野心,月野兔和天王遥、海王满两边合好,转世的土萌萤由天王遥、海王满、冥王雪奈一起照顾。

    + +

    死亡月球化身马戏团及麾下的亚马逊四人组入侵小镇。在水手水星、水手火星、水手木星、水手金星等四人逐一领悟变身以后,终於打败死亡月球马戏团,亚马逊四人组,也成了日后三十世纪小阿兔的伙伴。

    + +

    最后,小兔遭到水手凯拉克西亚所率领的水手战士的攻击,并接连失去了阿卫、水手水星、水手火星、水手木星、水手金星、水手土星、水手天王星、水手海王星、水手冥王星。在同样被攻击,失去水手战士星光三人组的火球公主,及水手宇宙小小兔和一起并肩战斗下,终於打败了敌人。

    + +

    觉得出场角色越来越多,看到最后好累。我还是最喜欢代表聪明智慧的水手水星亚美,可是到最后角色越来越多,亚美的戏份也被稀释掉了。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 155 | + 156 | + 157 | + 158 | + 159 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0157.html.zh-tw.html b/htdocs/imacat/me/diary/0157.html.zh-tw.html new file mode 120000 index 0000000..b32d00c --- /dev/null +++ b/htdocs/imacat/me/diary/0157.html.zh-tw.html @@ -0,0 +1 @@ +0157.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0157.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0157.html.zh-tw.xhtml new file mode 100644 index 0000000..389773e --- /dev/null +++ b/htdocs/imacat/me/diary/0157.html.zh-tw.xhtml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百五十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百五十七

    + +
    + +
    + +
    +
    2.19.’10. 4:32am.
    + +

    美少女戰士 美少女戦士セーラームーン

    + +
    +美少女戰士 +
    + +

    武内直子美少女戰士是我幾部很想找來看完的舊動漫之一。它卡通在播映的1992-1997年,大約是我大學時候到離開大學以後的事,沒什麼機會看到。那時美少女戰士很紅,到處都有人說代替月亮懲罰你,我一直很想知道是什麼意思。因為沒看,所以也不知道原作到底是卡通,還是漫畫。

    + +

    一直到前兩年,才在西門町的萌點女僕咖啡,看到美少女戰士的彩色 TV 版。自此,每次去萌點女僕咖啡坐,都挑美少女戰士來看。可是咖啡店沒辦法常去坐太久,一直看得很慢。

    + +

    初一下午和家人去動物園,晚上去高雄三多路的漫畫國度看看有沒有新漫畫,碰巧讓我看到舊的美少女戰士漫畫原作。這麼難得的機會,想想,就放棄了看新刊的念頭。全部有十八集,漫畫國度缺了第十六和第十八集。我找了一個有電腦的位置,就坐下來看了。感覺真是超棒。不過漫畫國度是計時制的,一分鐘一元,很貴。中間缺的第十六集,我上網補看;第十八集,先結完帳再回家看。即使如此,結帳時還是花了 423 元,等於是七個小時,好貴!

    + +

    月野兔是一個普通的國中生,遇到了黑貓露娜,得到了變身為水手月亮的能力。在經歷了黑暗王國的戰鬥後,月野兔終於知道,自己是月亮上銀千年王國的公主西蕾妮蒂的轉世。而在身邊的的場衛,就是晚禮服假面,也是自己前世的戀人,地球國的王子安迪米歐。而自己的眼淚的結晶,就是銀千年王國最終的寶物幻之銀水晶。而身邊的朋友天才少女水野亞美是水手水星,巫女火野麗是水手火星,怪力女木野真琴是水手木星,原先以為是月亮公主的水手V愛野美奈子,則是水手金星。

    + +

    消滅黑暗王國的野心後,回復平靜生活的水手們,突然出現一個謎樣小女孩小阿兔,又遭到黑色月亮的攻擊,企圖奪取月亮。原來小阿兔是自三十世紀來的,月野兔和的場衛的女兒,月亮王國未來的小公主。回到了三十世紀,也得知了時間之門看守人水手冥王星的存在。

    + +

    消滅黑色月亮的野心,回到現代後,東京海埔新生地無限州的中心大樓,發生異常現象,水手門潛入調查,發現了法老王90所率領的死亡幻影的野心。獨立行動調查的水手天王星,賽車手天王遙,和水手海王星,小提琴家海王滿,及水手冥王星的轉世冥王雪奈。喚醒了擁有毀滅力量的水手土星土萌螢,最後消滅了死亡幻影的野心,月野兔和天王遙、海王滿兩邊合好,轉世的土萌螢由天王遙、海王滿、冥王雪奈一起照顧。

    + +

    死亡月球化身馬戲團及麾下的亞馬遜四人組入侵小鎮。在水手水星、水手火星、水手木星、水手金星等四人逐一領悟變身以後,終於打敗死亡月球馬戲團,亞馬遜四人組,也成了日後三十世紀小阿兔的伙伴。

    + +

    最後,小兔遭到水手凱拉克西亞所率領的水手戰士的攻擊,並接連失去了阿衛、水手水星、水手火星、水手木星、水手金星、水手土星、水手天王星、水手海王星、水手冥王星。在同樣被攻擊,失去水手戰士星光三人組的火球公主,及水手宇宙小小兔和一起並肩戰鬥下,終於打敗了敵人。

    + +

    覺得出場角色越來越多,看到最後好累。我還是最喜歡代表聰明智慧的水手水星亞美,可是到最後角色越來越多,亞美的戲份也被稀釋掉了。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 155 | + 156 | + 157 | + 158 | + 159 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0158.html.en.html b/htdocs/imacat/me/diary/0158.html.en.html new file mode 120000 index 0000000..1077f6b --- /dev/null +++ b/htdocs/imacat/me/diary/0158.html.en.html @@ -0,0 +1 @@ +0158.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0158.html.en.xhtml b/htdocs/imacat/me/diary/0158.html.en.xhtml new file mode 100644 index 0000000..8451ac7 --- /dev/null +++ b/htdocs/imacat/me/diary/0158.html.en.xhtml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 158 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 158

    + +
    + +
    + +
    +
    2.19.’10. 5:31am.
    + +

    聖闘士星矢

    + +
    +聖闘士星矢 +
    + +

    車田正美聖闘士星矢,是在我國高中時代的漫畫。高中的時候我開始看少年快報,那時候聖闘士星矢已經連載到一半了,不大看得懂。高三以後不再追少年快報,就沒看下去了。所以,雖然大致上知道是什麼漫畫,也知道人家說燃燒吧,小宇宙!是什麼意思,可是一直沒有確切清楚劇情內容。

    + +

    前兩天看完美少女戰士後,就發狠找來電子版,把聖闘士星矢也一口氣看完了。全部二十八集,從年初二晚上看到初五。電子版果然比較不方便看,看得好慢。

    + +

    星矢、紫龍、冰河和瞬,是城戶財團從小送到世界各地訓練,培養當聖鬥士的孤兒。當他們長大當上青銅聖鬥士後,被送回日本,在城戶財團繼任主席城戶詩織主持下,進行名為銀河戰爭的聖鬥士死鬥。銀河戰爭被另一率領黑暗聖鬥士的青銅聖鬥士、瞬的哥哥一輝破壞。在打敗黑暗聖鬥士後,希臘聖域派獅子座黃金聖鬥士艾奧里亞,來制裁在銀河戰爭私鬥的青銅聖鬥士們,才揭發了現在的教皇是雙重人格的雙子座黃金聖鬥士薩卡,殺害前任教皇假冒的,薩卡企圖殺害女神雅典娜轉世的女嬰,而被射手座黃金聖鬥士艾奧羅斯發現救出,託給城戶光政撫育。城戶光政將女嬰當作自己孫女,取名城戶詩織撫養長大,並以自己在全世界所生的一百個孩子,送去世界各地訓練為聖鬥士保護詩織。最後星矢等人一一突破了黃道十二宮守衛的黃金聖鬥士,消滅了薩卡的陰謀,也使黃金聖鬥士半數戰死。

    + +

    就在星矢等人療傷期間,海王波士頓藉希臘船王之子朱利安復活,企圖以連續不斷的大雨淹沒全世界。詩織為保護人類,自願承受雨淋,以暫緩人類的滅亡。原來海王波士頓的復活,是雙子座薩卡的雙包胎弟弟卡諾的陰謀。星矢等人為救詩織,一一打破七海柱,打敗卡諾,並打破最後的生命之柱,救出其中的詩織。在詩織重新封印海王波士頓後,終於解救了人類。

    + +

    在詩織休息期間,冥王黑地斯派遣復活的前教皇牡羊座希歐、雙子座薩卡、摩羯座阿修羅和水瓶座卡妙攻來希臘聖域,要殺死詩織。原來冥王黑地斯經歷了243年的沉睡後復活了,要打敗其永遠的對手雅典娜,並以太陽系所有行星連成一線、永遠的日蝕,讓地球陷入永遠的黑暗中。為抵擋三個復活的前黃金聖鬥士,及其後的冥鬥士軍團,僅存的黃金聖鬥士全力抵禦,卻還是讓最強的處女座沙加死亡,詩織自殺。原來沙加和詩織是自願進入冥界暗殺冥王黑地斯。希歐等人則是復活後假意歸順冥王黑地斯,要回希臘聖域告訴詩織雅典娜聖衣的事。希歐臨消失前將雅典娜的聖衣託付給星矢,星矢等人為追上詩織,一一突破地獄各關卡。見到冥王黑地斯後,沒想到純潔善良的瞬,竟然是冥王黑地斯的肉身。一輝好不容易解救瞬,冥王黑地斯又將詩織擄走。星矢等人走到地獄的盡頭,突破嘆息之牆進入天堂,打敗了冥王黑地斯身邊,死亡之神達納特斯與睡眠之神修普諾斯。得到聖衣的詩織,終於在眾人的合力下,打敗了冥王黑地斯,恢復和平。

    + +

    故事很精彩,比原本想像中的細緻很多。很多劇情伏筆轉折都埋得很長,像冥王篇前半,復活的黃金聖鬥士的反叛,處女座沙加和詩織的求死。如果是現在短視的周刊少年Jump的話,這樣大概是不行的吧。兩三集讀者票選排行不在前三名內,就要腰斬,所以每一部漫畫都在炒短線。唉。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 156 | + 157 | + 158 | + 159 | + 160 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0158.html.zh-cn.html b/htdocs/imacat/me/diary/0158.html.zh-cn.html new file mode 120000 index 0000000..2fde688 --- /dev/null +++ b/htdocs/imacat/me/diary/0158.html.zh-cn.html @@ -0,0 +1 @@ +0158.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0158.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0158.html.zh-cn.xhtml new file mode 100644 index 0000000..13ebc22 --- /dev/null +++ b/htdocs/imacat/me/diary/0158.html.zh-cn.xhtml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百五十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百五十八

    + +
    + +
    + +
    +
    2.19.’10. 5:31am.
    + +

    圣闘士星矢

    + +
    +圣闘士星矢 +
    + +

    车田正美圣闘士星矢,是在我国高中时代的漫画。高中的时候我开始看少年快报,那时候圣闘士星矢已经连载到一半了,不大看得懂。高三以后不再追少年快报,就没看下去了。所以,虽然大致上知道是什么漫画,也知道人家说燃烧吧,小宇宙!是什么意思,可是一直没有确切清楚剧情内容。

    + +

    前两天看完美少女战士后,就发狠找来电子版,把圣闘士星矢也一口气看完了。全部二十八集,从年初二晚上看到初五。电子版果然比较不方便看,看得好慢。

    + +

    星矢、紫龙、冰河和瞬,是城户财团从小送到世界各地训练,培养当圣斗士的孤儿。当他们长大当上青铜圣斗士后,被送回日本,在城户财团继任主席城户诗织主持下,进行名为银河战争的圣斗士死斗。银河战争被另一率领黑暗圣斗士的青铜圣斗士、瞬的哥哥一辉破坏。在打败黑暗圣斗士后,希腊圣域派狮子座黄金圣斗士艾奥里亚,来制裁在银河战争私斗的青铜圣斗士们,才揭发了现在的教皇是双重人格的双子座黄金圣斗士萨卡,杀害前任教皇假冒的,萨卡企图杀害女神雅典娜转世的女婴,而被射手座黄金圣斗士艾奥罗斯发现救出,托给城户光政抚育。城户光政将女婴当作自己孙女,取名城户诗织抚养长大,并以自己在全世界所生的一百个孩子,送去世界各地训练为圣斗士保护诗织。最后星矢等人一一突破了黄道十二宫守卫的黄金圣斗士,消灭了萨卡的阴谋,也使黄金圣斗士半数战死。

    + +

    就在星矢等人疗伤期间,海王波士顿藉希腊船王之子朱利安复活,企图以连续不断的大雨淹没全世界。诗织为保护人类,自愿承受雨淋,以暂缓人类的灭亡。原来海王波士顿的复活,是双子座萨卡的双包胎弟弟卡诺的阴谋。星矢等人为救诗织,一一打破七海柱,打败卡诺,并打破最后的生命之柱,救出其中的诗织。在诗织重新封印海王波士顿后,终於解救了人类。

    + +

    在诗织休息期间,冥王黑地斯派遣复活的前教皇牡羊座希欧、双子座萨卡、摩羯座阿修罗和水瓶座卡妙攻来希腊圣域,要杀死诗织。原来冥王黑地斯经历了243年的沉睡后复活了,要打败其永远的对手雅典娜,并以太阳系所有行星连成一线、永远的日蚀,让地球陷入永远的黑暗中。为抵挡三个复活的前黄金圣斗士,及其后的冥斗士军团,仅存的黄金圣斗士全力抵御,却还是让最强的处女座沙加死亡,诗织自杀。原来沙加和诗织是自愿进入冥界暗杀冥王黑地斯。希欧等人则是复活后假意归顺冥王黑地斯,要回希腊圣域告诉诗织雅典娜圣衣的事。希欧临消失前将雅典娜的圣衣托付给星矢,星矢等人为追上诗织,一一突破地狱各关卡。见到冥王黑地斯后,没想到纯洁善良的瞬,竟然是冥王黑地斯的肉身。一辉好不容易解救瞬,冥王黑地斯又将诗织掳走。星矢等人走到地狱的尽头,突破叹息之墙进入天堂,打败了冥王黑地斯身边,死亡之神达纳特斯与睡眠之神修普诺斯。得到圣衣的诗织,终於在众人的合力下,打败了冥王黑地斯,恢复和平。

    + +

    故事很精彩,比原本想像中的细致很多。很多剧情伏笔转折都埋得很长,像冥王篇前半,复活的黄金圣斗士的反叛,处女座沙加和诗织的求死。如果是现在短视的周刊少年Jump的话,这样大概是不行的吧。两三集读者票选排行不在前三名内,就要腰斩,所以每一部漫画都在炒短线。唉。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 156 | + 157 | + 158 | + 159 | + 160 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0158.html.zh-tw.html b/htdocs/imacat/me/diary/0158.html.zh-tw.html new file mode 120000 index 0000000..2ddd778 --- /dev/null +++ b/htdocs/imacat/me/diary/0158.html.zh-tw.html @@ -0,0 +1 @@ +0158.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0158.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0158.html.zh-tw.xhtml new file mode 100644 index 0000000..c180805 --- /dev/null +++ b/htdocs/imacat/me/diary/0158.html.zh-tw.xhtml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百五十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百五十八

    + +
    + +
    + +
    +
    2.19.’10. 5:31am.
    + +

    聖闘士星矢

    + +
    +聖闘士星矢 +
    + +

    車田正美聖闘士星矢,是在我國高中時代的漫畫。高中的時候我開始看少年快報,那時候聖闘士星矢已經連載到一半了,不大看得懂。高三以後不再追少年快報,就沒看下去了。所以,雖然大致上知道是什麼漫畫,也知道人家說燃燒吧,小宇宙!是什麼意思,可是一直沒有確切清楚劇情內容。

    + +

    前兩天看完美少女戰士後,就發狠找來電子版,把聖闘士星矢也一口氣看完了。全部二十八集,從年初二晚上看到初五。電子版果然比較不方便看,看得好慢。

    + +

    星矢、紫龍、冰河和瞬,是城戶財團從小送到世界各地訓練,培養當聖鬥士的孤兒。當他們長大當上青銅聖鬥士後,被送回日本,在城戶財團繼任主席城戶詩織主持下,進行名為銀河戰爭的聖鬥士死鬥。銀河戰爭被另一率領黑暗聖鬥士的青銅聖鬥士、瞬的哥哥一輝破壞。在打敗黑暗聖鬥士後,希臘聖域派獅子座黃金聖鬥士艾奧里亞,來制裁在銀河戰爭私鬥的青銅聖鬥士們,才揭發了現在的教皇是雙重人格的雙子座黃金聖鬥士薩卡,殺害前任教皇假冒的,薩卡企圖殺害女神雅典娜轉世的女嬰,而被射手座黃金聖鬥士艾奧羅斯發現救出,託給城戶光政撫育。城戶光政將女嬰當作自己孫女,取名城戶詩織撫養長大,並以自己在全世界所生的一百個孩子,送去世界各地訓練為聖鬥士保護詩織。最後星矢等人一一突破了黃道十二宮守衛的黃金聖鬥士,消滅了薩卡的陰謀,也使黃金聖鬥士半數戰死。

    + +

    就在星矢等人療傷期間,海王波士頓藉希臘船王之子朱利安復活,企圖以連續不斷的大雨淹沒全世界。詩織為保護人類,自願承受雨淋,以暫緩人類的滅亡。原來海王波士頓的復活,是雙子座薩卡的雙包胎弟弟卡諾的陰謀。星矢等人為救詩織,一一打破七海柱,打敗卡諾,並打破最後的生命之柱,救出其中的詩織。在詩織重新封印海王波士頓後,終於解救了人類。

    + +

    在詩織休息期間,冥王黑地斯派遣復活的前教皇牡羊座希歐、雙子座薩卡、摩羯座阿修羅和水瓶座卡妙攻來希臘聖域,要殺死詩織。原來冥王黑地斯經歷了243年的沉睡後復活了,要打敗其永遠的對手雅典娜,並以太陽系所有行星連成一線、永遠的日蝕,讓地球陷入永遠的黑暗中。為抵擋三個復活的前黃金聖鬥士,及其後的冥鬥士軍團,僅存的黃金聖鬥士全力抵禦,卻還是讓最強的處女座沙加死亡,詩織自殺。原來沙加和詩織是自願進入冥界暗殺冥王黑地斯。希歐等人則是復活後假意歸順冥王黑地斯,要回希臘聖域告訴詩織雅典娜聖衣的事。希歐臨消失前將雅典娜的聖衣託付給星矢,星矢等人為追上詩織,一一突破地獄各關卡。見到冥王黑地斯後,沒想到純潔善良的瞬,竟然是冥王黑地斯的肉身。一輝好不容易解救瞬,冥王黑地斯又將詩織擄走。星矢等人走到地獄的盡頭,突破嘆息之牆進入天堂,打敗了冥王黑地斯身邊,死亡之神達納特斯與睡眠之神修普諾斯。得到聖衣的詩織,終於在眾人的合力下,打敗了冥王黑地斯,恢復和平。

    + +

    故事很精彩,比原本想像中的細緻很多。很多劇情伏筆轉折都埋得很長,像冥王篇前半,復活的黃金聖鬥士的反叛,處女座沙加和詩織的求死。如果是現在短視的周刊少年Jump的話,這樣大概是不行的吧。兩三集讀者票選排行不在前三名內,就要腰斬,所以每一部漫畫都在炒短線。唉。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 156 | + 157 | + 158 | + 159 | + 160 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0159.html.en.html b/htdocs/imacat/me/diary/0159.html.en.html new file mode 120000 index 0000000..91e7603 --- /dev/null +++ b/htdocs/imacat/me/diary/0159.html.en.html @@ -0,0 +1 @@ +0159.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0159.html.en.xhtml b/htdocs/imacat/me/diary/0159.html.en.xhtml new file mode 100644 index 0000000..a2cde54 --- /dev/null +++ b/htdocs/imacat/me/diary/0159.html.en.xhtml @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 159 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 159

    + +
    + +
    + +
    +
    3.4.’10. 10:01am.
    + +

    找房子

    + +

    每年年節,我們都會給房東送禮。房東人很好,我們也樂於當好房客。房東先生是個上海撤退來台的老兵,口音很重,有時候說話得靠猜的,不然就得靠房東太太翻譯給我們聽。

    + +

    今年也不例外。二月初買了一條鹽醃的北海鮭魚,帶去給房東。房東先生一邊稱謝,一邊說他小兒子五月要結婚,他想拜託我們什麼事的。我們聽不清楚,以為是要請喜酒,還是要拜託我們代收什麼東西,好像又不是。直到隔天早上,房東太太打電話來,才知道,房東要娶媳婦,希望我們房子讓出來,當他們兒子新房。

    + +

    這樣事情就麻煩了。畢竟是住了十二年的地方,雖然一直有地方不滿意,但住久了也習慣了。而且家中經濟負擔二月剛轉移,加上過年的花費,正在青黃不接中,搬家費用和新傢俱都要錢。更何況我還在準備研究所考試中。

    + +

    可是,不想搬也得搬。跟房東討論,他們兒子五月結婚,之前需要一個月的時間準備,也就是最晚三月底得把房子還回去。看樣子我也不用準備考試了。於是,過年回台北,忙完一些累積多時的工作,就開始找房子了。

    + +

    上個禮拜一 (2/22) 開始,每天晚上回來,就開始到處跑找房子。一開始我手上的一些工作還沒做完,只能就她印下來的零散資料,和網溪國小前的佈告欄看到的房子,一家一家去看。禮拜三把工作結束後,我開始全心找房子:做了一個 OpenOffice.org 的試算表,從 591 租屋網搜尋符合條件的中、永和的房子,搜尋到的就記錄下來,包括 591 上的編號、網址、地址、租金、聯絡人、電話、 Google 地圖的地址、離捷運的距離、有沒有天然瓦斯等。十二年前租屋找的網溪國小和頂溪國小佈告欄,我也一一去拍照,把照片編號,抄記在試算表中。因為要記要查的很多,記起來很慢,剛開始還邊記邊找。到後來,為求快速整理資料, 591 查到的資料,我改用生產線式,一個步驟一個步驟做完:先記下所有資料的編號和網址,再記下所有資料的房租和坪數,再一一點進去,記下地址、聯絡人和聯絡電話。通通記完後,我才去找 Google 地圖的地點和捷運距離。生產線記錄法果然比較有效率,之前一筆一筆記,永和二十筆資料記錄了四、五個小時,改用生產線記錄法,兩、三個小時就記錄了中和五十五筆資料。

    + +

    記完資料後,就可以利用試算表的自動篩選功能,篩選掉不適合的,像離捷運太遠、沒有天然氣等等。第一欄的註記,不適合的打叉✗,待看的打問號?,喜歡的打心形♥,待聯絡的打☎。最後一欄備註,再記下理由。

    + +

    做筆記很重要:只要搜尋到的,不管符不符合條件,都記下來,並把理由寫再備註。日後要是找不到,要回頭放寬條件時,才有所依據。而且資料要編號,抄錄下來的房子資料很多,不做筆記,電話重複打了都不知道。有些房東刊好幾個地方,有做筆記的話,聯絡電話一比對,就知道了。

    + +

    只要前置資料整理工作做得好,實際聯絡、看房子時就會輕鬆很多。這一點,管理任何資料庫,都是一樣的。最辛苦的還是前置的資料整理工作。

    + +

    聯絡後,就出門看房子了。上個禮拜一開始,平均一天看五、六戶,直到禮拜天,因為前晚資料整理得齊全,所以一口氣看了十幾戶。一個禮拜下來,馬拉松地看了四、五十戶房子。

    + +

    這時候智慧型手機就很好用了,可以打電話,可以查地圖、路線。那個禮拜,如果沒有新買的 iPhone 3GS ,面對幾乎都沒去過的地方,我沒有辦法這樣努力跑。

    + +

    看完房子,要馬上做筆記,不然會忘記。我試了幾種方法:首先,先把試算表上傳到 Google 文件上,結果發現試算表的超連結全部失效了,地圖沒辦法直接點上連結,電話號碼也沒辦法直接點上去打。而且自動篩選功能很混亂,原來設好的自動篩選,上傳上去就消失了。到很後來我才發現, Google 文件的手機版有自動篩選,可是一般版就沒有,還要安裝很慢又佔空間的自動篩選 Gadget 。而且, Google 文件要用來記筆記很難用,隨便不小心點錯,就會啟動網路連線,變成編輯模式,要取消也要網路連線, 3G 網路超耗電,多點錯幾下,手機一下子就沒電了。因為超連結不見了,筆記又不敢直接匯出成試算表下載回來,只能回來再抄。隔天禮拜六,我又回到十二年前的老方法,印出來用紙筆記,回家再抄上去。

    + +

    最後一天禮拜天,我改把資料記到通訊錄中。因為 iPhone 的通訊錄可以和 Outlook 的聯絡人互通,所以我先把資料建到 Outlook 聯絡人中,再同步到 iPhone 上。 iPhone 的通訊錄電話可以直接點選撥號,地址直接點選定位,備註也可以直接打,而且除了地圖定位外,都是離線作業,省電得多,充飽電也可以用比較久。而且房東來電,還會直接顯示。我把聯絡好要看的、待聯絡還沒聯絡上的、之前看了喜歡的,總之就是有可能要聯絡的,都存到手機的通訊錄上。反正回家都要抄到電腦上,記到手機通訊錄真的超好用,比起用 Google 文件好用得多了。

    + +

    就這樣,因為之前資料準備齊全,禮拜天早上出門,看了十幾戶,一直到晚上。中途聯絡上幾個一直聯絡不上的房東,也在四號公園前的看板上臨時抄了一家。中午手機剩一半電時,去景安站旁的Cheers! Cafe' 吉爾思咖啡拜託店家讓我充電(謝謝吉爾思咖啡!),還是把充飽的電全部用光。

    + +

    到傍晚五點多,看完所有的房子,兩個人都累壞了。本來還想找板橋、新店等其它郊區捷運站附近的,也沒力了。去了竹林路上的摩斯漢堡坐下來,翻開手機通訊錄,開始討論打♥號的房子,做第二輪的過濾:把還是有問題的篩選掉,只留下兩個人都喜歡的,打兩個♥號。第二輪選完後,最後留下四家,讓我們商透腦筋。一戶在景安站,離台北有點距離,我以後就沒辦法騎腳踏車來回台北了,就算騎機車也要一段時間,而且還要向樓上五樓收水電;一戶在我們熟悉的頂溪附近,什麼都好,房東還可以配合添購傢俱,可是房租要多三千塊錢,沒辦法殺價;一戶在永安市場站附近,坪數超大,可是打掉浴缸的浴室地板不平,還沒有瓦斯爐和抽油煙機;另外一戶很漂亮,現場一時衝動給了訂金,可是樓梯間堆滿了住戶的鞋子,都堆到梯階上了,我偶爾搬電腦上上下下,腳底下不一定看得清楚,真的很危險。

    + +

    真的好累,我竟然討論到一半睡著了。

    + +

    為了每個月多省三千塊,我還是忍痛決定去景安了。她提醒我,那裏的樓梯地板好像會滑。我們約了房東要付訂金。到了那裏,我在檢查一下樓梯地板,真的有斜度會滑。因為中永和垃圾不落地,常常要拿垃圾追垃圾車,在樓梯間跑很危險,而且我搬電腦來去也很危險,所以想一想,還是算了。

    + +

    所以,最後還是剩下頂溪附近的了。在她提議下,我打電話過去最後殺個一千看看。沒想到真的殺到了!打上三個♥號,馬上把訂金拿去給房東,敲定細節,要添購的傢俱等等,房東也先把鑰匙給我們。

    + +

    這兩天在景安路上來回,常常經過景安路上的丸居食酒屋,招牌很大很誘惑人,一直很想去吃吃看。於是趁著敲定房子慶祝,就去吃了。還蠻好吃的,烤肉串比較一般考得嫩,而且店裏都是包廂,感覺很不錯。可惜雞肉串種類不多,沒有雞肝、雞胗,我也忘了點雞翅。

    + +

    在店裏,我們開始回電話給在等電話的房東,一一回絕,也打電話給之前不小心付訂金的房東,拼命道歉。真是對人家非常抱歉。

    + +

    回來後,還是把白天看房的資料整理一下,整理到深夜,雖然已經沒什麼用了。結果不小心手賤,壓著 Shift 按了一下 Del ,一個星期的苦功,和剛剛的整理,就全部付諸流水了。直到昨晚,突然想到我檔案原先是存在 Dropbox 資料夾中,於是上 Dropbox 找,真的讓我找到了,復原回來。

    + +

    591 真的很好用。最主要的也是資料的整理。市公所在網溪國小和頂溪國小的公告欄,雖然現在有管理,沒像十幾年前那麼雜亂,可是廣告紙還是張貼人自己寫的,沒有統一的格式,裏面甚至有只留電話的,篩選起來很辛苦。相對的, 591 把所有資料格式化了,電話、地址、天然瓦斯等等條件,都存到資料庫,篩選起來輕鬆很多。

    + +

    搜尋的時候,房價上限可以高個兩千塊錢,看滿意再跟房東殺價。大多數房東只要真的喜歡的話,都可以殺價。不過缺點是看到好房子如果殺不動的話,會很心痛。而且殺價談判也是很累的事。

    + +

    當然也有無法殺價的房子。我在永安市場站旁看到一戶,就在永安市場站旁的巷子轉進去,走路一分鐘,屋況也很好。這麼誇張的好地點,房租本應高出很多,如果不是房東本來就降價了,根本不會出現在我搜尋的結果中。所以房東沒辦法再降價了,我們也認了。

    + +

    聯絡好了以後,去現場看,要是喜歡,探探房東殺房租的口風就好,不需要真的殺下去。畢竟還要比較,殺了很兇還說要再看看,很不禮貌,日後就算來租,房東也不會給好臉色看。

    + +

    第一次去現場看,絕對不要喜歡就決定了給訂金。馬上決定了,房東當然高興。不過就像購物一樣,太過依賴一時看漂亮的衝動,日後很容易後悔。住房子是長久的事。忍住衝動,回來再仔細想想,而且至少把手頭上的其它房子看完。我們就不小心看到漂亮的房子,就把訂金給出去了,事後想想,樓下住戶鞋子放到樓梯階上,違反消防法規又很危險,房子緊臨馬路很吵,格局又不好,只好事後拼命跟房東道歉,訂金也付諸流水了。

    + +

    一般都是看第二次的時候才會殺價、決定。當然有可能這段時間房子被租走了,那就當無緣吧。不過,現在這種時機,房子本來就不大好租了,所以也不必太擔心。房東一定會說什麼還有一組人看了多喜歡,聽聽就好,不要在意。

    + +

    第一次看,想看的地方一定要看清楚:熱水爐位置、浴室大小、手機收訊等等。再打電話去問屋況沒關係,但如果再打電話去殺價,或是再到現場看,通常就是要租了。不要抱著再看看的心態,會惹人厭。以後租了,房東也不會給好臉色。就算不租,這個世界很小,總有一天會遇到。所以第二次打電話去殺價的時候,就要想清楚,真的很喜歡想住了。這是做房客的基本誠意。

    + +

    不景氣,房子其實很難租出去,就算租出去,也很難碰到好房客。如果有穩定的工作、之前住很久等等,趁閒聊時跟房東說,房東會列入考慮,也有助於殺價。房子放著租不出去就是賠錢,如果是貸款買的,每個月付的房貸更是可怕。所以房東都會急著想租出去,比房客還急。談判的時候,只要不要太誇張,都可以跟房東說說看。 591 上有刊登時間,從刊登時間可以知道房子已經多久沒租出去了。 591 的編號也是從前到後,現在是 459xxx ,編號 40xxxx 的,都已經好幾個月沒租出去了。越久租不出去的,房東越急著想租出去,談判的空間當然也越大。

    + +

    這一個禮拜來,過濾了中、永和 209 筆招租的資料,實際去看了四、五十戶,還經過三階段決選,才找到現在這個房子。雖然房租貴了些,但是離捷運站近,離台北近,有天然瓦斯,鄰居習慣好樓梯間乾淨,手機收訊佳,採光通風好,房東人好,有臥室,有書房,有客廳,有前後陽台,有沒加蓋的頂樓陽台,樓下有地方停車。和現在的套房雙拼,所有的生活空間全在一起比起來,總算有家的感覺了,也可以帶家人、朋友來坐。

    + +

    這個房租,以我們兩個的固定收入來說是勉強夠,不過就很難存錢了。當然還有一些兼職的收入,可以存下來,不過不穩定的收入無法依賴。不過捷運少個兩站,運費也會少一些吧。我可以騎腳踏車來回台北市中心,不趕時間的話,油錢也省了。就算騎車去台北,油錢也比較少,而且距離沒那麼遠,回來比較不會累,也比較安全。萬一趕時間要坐計程車,車錢也省很多。水、電都是獨立電表,用電省的話,每度電費也會降,努力省電會省更多錢。

    + +

    回頭一查,發現十年前租的租金,只比新家便宜兩千,是後來房東降租,才會感覺差那麼多。感覺好像玩模擬市民,人生隨著職等昇級,生活、房屋也跟著昇級一樣。

    + +

    其實只要同樣地點,同樣房東,同樣鄰居,同樣樓梯間管理,同樣屋況,再少個 10 坪,房租少個兩、三千,就太完美了。現在房子這麼大,多付這兩千房租實在也有點困擾。可惜天底下沒有這麼完美的事。

    + +

    所以,誰說我們的預算太低了呢?這一個禮拜來,被幾個房東、房仲嗆,嗆得有點不愉快。結果租這樣,平均一坪也不到 500 ,離房仲講永和平均一坪 500 也有段距離。我們又沒有要住緊貼捷運站,原來的預算差不多,只是找不到坪數適合的,只好加個兩千租大一點的了。

    + +

    有個在佈告欄看到的房東,打電話去問了是不是有天然氣,房租多少。後來他再打電話追問,我也老實說,我們希望有天然氣,而且房租超出預算,他還硬追問我預算多少。沒想到過了一會,他又打電話來,嗆說我們的預算,只能租小套房,租不到住家。不合適就不合適,幹嘛還特地打電話來嗆聲?真是有點莫名其妙。

    + +

    另一個有公主病的房東也很誇張:打電話去問,她要我乾脆馬上去看。我說我快三點了還沒吃午飯,她竟然說飯可以晚點吃。我說因為是家裏自己煮的沒辦法等,她才悻悻然掛了電話。好可怕,想想就給她簡訊說不去看了。就算租到,以後也很難相處吧。說不定每個月一號凌晨一點,就打電話來催房租了。要是請她修房子,會鬧到天翻地覆吧!

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 157 | + 158 | + 159 | + 160 | + 161 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0159.html.zh-cn.html b/htdocs/imacat/me/diary/0159.html.zh-cn.html new file mode 120000 index 0000000..e0eedc9 --- /dev/null +++ b/htdocs/imacat/me/diary/0159.html.zh-cn.html @@ -0,0 +1 @@ +0159.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0159.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0159.html.zh-cn.xhtml new file mode 100644 index 0000000..7fccce3 --- /dev/null +++ b/htdocs/imacat/me/diary/0159.html.zh-cn.xhtml @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百五十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百五十九

    + +
    + +
    + +
    +
    3.4.’10. 10:01am.
    + +

    找房子

    + +

    每年年节,我们都会给房东送礼。房东人很好,我们也乐於当好房客。房东先生是个上海撤退来台的老兵,口音很重,有时候说话得靠猜的,不然就得靠房东太太翻译给我们听。

    + +

    今年也不例外。二月初买了一条盐腌的北海鲑鱼,带去给房东。房东先生一边称谢,一边说他小儿子五月要结婚,他想拜托我们什么事的。我们听不清楚,以为是要请喜酒,还是要拜托我们代收什么东西,好像又不是。直到隔天早上,房东太太打电话来,才知道,房东要娶媳妇,希望我们房子让出来,当他们儿子新房。

    + +

    这样事情就麻烦了。毕竟是住了十二年的地方,虽然一直有地方不满意,但住久了也习惯了。而且家中经济负担二月刚转移,加上过年的花费,正在青黄不接中,搬家费用和新家俱都要钱。更何况我还在准备研究所考试中。

    + +

    可是,不想搬也得搬。跟房东讨论,他们儿子五月结婚,之前需要一个月的时间准备,也就是最晚三月底得把房子还回去。看样子我也不用准备考试了。於是,过年回台北,忙完一些累积多时的工作,就开始找房子了。

    + +

    上个礼拜一 (2/22) 开始,每天晚上回来,就开始到处跑找房子。一开始我手上的一些工作还没做完,只能就她印下来的零散资料,和网溪国小前的布告栏看到的房子,一家一家去看。礼拜三把工作结束后,我开始全心找房子:做了一个 OpenOffice.org 的试算表,从 591 租屋网搜寻符合条件的中、永和的房子,搜寻到的就记录下来,包括 591 上的编号、网址、地址、租金、联络人、电话、 Google 地图的地址、离捷运的距离、有没有天然瓦斯等。十二年前租屋找的网溪国小和顶溪国小布告栏,我也一一去拍照,把照片编号,抄记在试算表中。因为要记要查的很多,记起来很慢,刚开始还边记边找。到后来,为求快速整理资料, 591 查到的资料,我改用生产线式,一个步骤一个步骤做完:先记下所有资料的编号和网址,再记下所有资料的房租和坪数,再一一点进去,记下地址、联络人和联络电话。通通记完后,我才去找 Google 地图的地点和捷运距离。生产线记录法果然比较有效率,之前一笔一笔记,永和二十笔资料记录了四、五个小时,改用生产线记录法,两、三个小时就记录了中和五十五笔资料。

    + +

    记完资料后,就可以利用试算表的自动筛选功能,筛选掉不适合的,像离捷运太远、没有天然气等等。第一栏的注记,不适合的打叉✗,待看的打问号?,喜欢的打心形♥,待联络的打☎。最后一栏备注,再记下理由。

    + +

    做笔记很重要:只要搜寻到的,不管符不符合条件,都记下来,并把理由写再备注。日后要是找不到,要回头放宽条件时,才有所依据。而且资料要编号,抄录下来的房子资料很多,不做笔记,电话重复打了都不知道。有些房东刊好几个地方,有做笔记的话,联络电话一比对,就知道了。

    + +

    只要前置资料整理工作做得好,实际联络、看房子时就会轻松很多。这一点,管理任何资料库,都是一样的。最辛苦的还是前置的资料整理工作。

    + +

    联络后,就出门看房子了。上个礼拜一开始,平均一天看五、六户,直到礼拜天,因为前晚资料整理得齐全,所以一口气看了十几户。一个礼拜下来,马拉松地看了四、五十户房子。

    + +

    这时候智慧型手机就很好用了,可以打电话,可以查地图、路线。那个礼拜,如果没有新买的 iPhone 3GS ,面对几乎都没去过的地方,我没有办法这样努力跑。

    + +

    看完房子,要马上做笔记,不然会忘记。我试了几种方法:首先,先把试算表上传到 Google 文件上,结果发现试算表的超连结全部失效了,地图没办法直接点上连结,电话号码也没办法直接点上去打。而且自动筛选功能很混乱,原来设好的自动筛选,上传上去就消失了。到很后来我才发现, Google 文件的手机版有自动筛选,可是一般版就没有,还要安装很慢又占空间的自动筛选 Gadget 。而且, Google 文件要用来记笔记很难用,随便不小心点错,就会启动网路连线,变成编辑模式,要取消也要网路连线, 3G 网路超耗电,多点错几下,手机一下子就没电了。因为超连结不见了,笔记又不敢直接汇出成试算表下载回来,只能回来再抄。隔天礼拜六,我又回到十二年前的老方法,印出来用纸笔记,回家再抄上去。

    + +

    最后一天礼拜天,我改把资料记到通讯录中。因为 iPhone 的通讯录可以和 Outlook 的联络人互通,所以我先把资料建到 Outlook 联络人中,再同步到 iPhone 上。 iPhone 的通讯录电话可以直接点选拨号,地址直接点选定位,备注也可以直接打,而且除了地图定位外,都是离线作业,省电得多,充饱电也可以用比较久。而且房东来电,还会直接显示。我把联络好要看的、待联络还没联络上的、之前看了喜欢的,总之就是有可能要联络的,都存到手机的通讯录上。反正回家都要抄到电脑上,记到手机通讯录真的超好用,比起用 Google 文件好用得多了。

    + +

    就这样,因为之前资料准备齐全,礼拜天早上出门,看了十几户,一直到晚上。中途联络上几个一直联络不上的房东,也在四号公园前的看板上临时抄了一家。中午手机剩一半电时,去景安站旁的Cheers! Cafe' 吉尔思咖啡拜托店家让我充电(谢谢吉尔思咖啡!),还是把充饱的电全部用光。

    + +

    到傍晚五点多,看完所有的房子,两个人都累坏了。本来还想找板桥、新店等其它郊区捷运站附近的,也没力了。去了竹林路上的摩斯汉堡坐下来,翻开手机通讯录,开始讨论打♥号的房子,做第二轮的过滤:把还是有问题的筛选掉,只留下两个人都喜欢的,打两个♥号。第二轮选完后,最后留下四家,让我们商透脑筋。一户在景安站,离台北有点距离,我以后就没办法骑脚踏车来回台北了,就算骑机车也要一段时间,而且还要向楼上五楼收水电;一户在我们熟悉的顶溪附近,什么都好,房东还可以配合添购家俱,可是房租要多三千块钱,没办法杀价;一户在永安市场站附近,坪数超大,可是打掉浴缸的浴室地板不平,还没有瓦斯炉和抽油烟机;另外一户很漂亮,现场一时冲动给了订金,可是楼梯间堆满了住户的鞋子,都堆到梯阶上了,我偶尔搬电脑上上下下,脚底下不一定看得清楚,真的很危险。

    + +

    真的好累,我竟然讨论到一半睡著了。

    + +

    为了每个月多省三千块,我还是忍痛决定去景安了。她提醒我,那里的楼梯地板好像会滑。我们约了房东要付订金。到了那里,我在检查一下楼梯地板,真的有斜度会滑。因为中永和垃圾不落地,常常要拿垃圾追垃圾车,在楼梯间跑很危险,而且我搬电脑来去也很危险,所以想一想,还是算了。

    + +

    所以,最后还是剩下顶溪附近的了。在她提议下,我打电话过去最后杀个一千看看。没想到真的杀到了!打上三个♥号,马上把订金拿去给房东,敲定细节,要添购的家俱等等,房东也先把钥匙给我们。

    + +

    这两天在景安路上来回,常常经过景安路上的丸居食酒屋,招牌很大很诱惑人,一直很想去吃吃看。於是趁著敲定房子庆祝,就去吃了。还蛮好吃的,烤肉串比较一般考得嫩,而且店里都是包厢,感觉很不错。可惜鸡肉串种类不多,没有鸡肝、鸡胗,我也忘了点鸡翅。

    + +

    在店里,我们开始回电话给在等电话的房东,一一回绝,也打电话给之前不小心付订金的房东,拼命道歉。真是对人家非常抱歉。

    + +

    回来后,还是把白天看房的资料整理一下,整理到深夜,虽然已经没什么用了。结果不小心手贱,压著 Shift 按了一下 Del ,一个星期的苦功,和刚刚的整理,就全部付诸流水了。直到昨晚,突然想到我档案原先是存在 Dropbox 资料夹中,於是上 Dropbox 找,真的让我找到了,复原回来。

    + +

    591 真的很好用。最主要的也是资料的整理。市公所在网溪国小和顶溪国小的公告栏,虽然现在有管理,没像十几年前那么杂乱,可是广告纸还是张贴人自己写的,没有统一的格式,里面甚至有只留电话的,筛选起来很辛苦。相对的, 591 把所有资料格式化了,电话、地址、天然瓦斯等等条件,都存到资料库,筛选起来轻松很多。

    + +

    搜寻的时候,房价上限可以高个两千块钱,看满意再跟房东杀价。大多数房东只要真的喜欢的话,都可以杀价。不过缺点是看到好房子如果杀不动的话,会很心痛。而且杀价谈判也是很累的事。

    + +

    当然也有无法杀价的房子。我在永安市场站旁看到一户,就在永安市场站旁的巷子转进去,走路一分钟,屋况也很好。这么夸张的好地点,房租本应高出很多,如果不是房东本来就降价了,根本不会出现在我搜寻的结果中。所以房东没办法再降价了,我们也认了。

    + +

    联络好了以后,去现场看,要是喜欢,探探房东杀房租的口风就好,不需要真的杀下去。毕竟还要比较,杀了很凶还说要再看看,很不礼貌,日后就算来租,房东也不会给好脸色看。

    + +

    第一次去现场看,绝对不要喜欢就决定了给订金。马上决定了,房东当然高兴。不过就像购物一样,太过依赖一时看漂亮的冲动,日后很容易后悔。住房子是长久的事。忍住冲动,回来再仔细想想,而且至少把手头上的其它房子看完。我们就不小心看到漂亮的房子,就把订金给出去了,事后想想,楼下住户鞋子放到楼梯阶上,违反消防法规又很危险,房子紧临马路很吵,格局又不好,只好事后拼命跟房东道歉,订金也付诸流水了。

    + +

    一般都是看第二次的时候才会杀价、决定。当然有可能这段时间房子被租走了,那就当无缘吧。不过,现在这种时机,房子本来就不大好租了,所以也不必太担心。房东一定会说什么还有一组人看了多喜欢,听听就好,不要在意。

    + +

    第一次看,想看的地方一定要看清楚:热水炉位置、浴室大小、手机收讯等等。再打电话去问屋况没关系,但如果再打电话去杀价,或是再到现场看,通常就是要租了。不要抱著再看看的心态,会惹人厌。以后租了,房东也不会给好脸色。就算不租,这个世界很小,总有一天会遇到。所以第二次打电话去杀价的时候,就要想清楚,真的很喜欢想住了。这是做房客的基本诚意。

    + +

    不景气,房子其实很难租出去,就算租出去,也很难碰到好房客。如果有稳定的工作、之前住很久等等,趁闲聊时跟房东说,房东会列入考虑,也有助於杀价。房子放著租不出去就是赔钱,如果是贷款买的,每个月付的房贷更是可怕。所以房东都会急著想租出去,比房客还急。谈判的时候,只要不要太夸张,都可以跟房东说说看。 591 上有刊登时间,从刊登时间可以知道房子已经多久没租出去了。 591 的编号也是从前到后,现在是 459xxx ,编号 40xxxx 的,都已经好几个月没租出去了。越久租不出去的,房东越急著想租出去,谈判的空间当然也越大。

    + +

    这一个礼拜来,过滤了中、永和 209 笔招租的资料,实际去看了四、五十户,还经过三阶段决选,才找到现在这个房子。虽然房租贵了些,但是离捷运站近,离台北近,有天然瓦斯,邻居习惯好楼梯间干净,手机收讯佳,采光通风好,房东人好,有卧室,有书房,有客厅,有前后阳台,有没加盖的顶楼阳台,楼下有地方停车。和现在的套房双拼,所有的生活空间全在一起比起来,总算有家的感觉了,也可以带家人、朋友来坐。

    + +

    这个房租,以我们两个的固定收入来说是勉强够,不过就很难存钱了。当然还有一些兼职的收入,可以存下来,不过不稳定的收入无法依赖。不过捷运少个两站,运费也会少一些吧。我可以骑脚踏车来回台北市中心,不赶时间的话,油钱也省了。就算骑车去台北,油钱也比较少,而且距离没那么远,回来比较不会累,也比较安全。万一赶时间要坐计程车,车钱也省很多。水、电都是独立电表,用电省的话,每度电费也会降,努力省电会省更多钱。

    + +

    回头一查,发现十年前租的租金,只比新家便宜两千,是后来房东降租,才会感觉差那么多。感觉好像玩模拟市民,人生随著职等升级,生活、房屋也跟著升级一样。

    + +

    其实只要同样地点,同样房东,同样邻居,同样楼梯间管理,同样屋况,再少个 10 坪,房租少个两、三千,就太完美了。现在房子这么大,多付这两千房租实在也有点困扰。可惜天底下没有这么完美的事。

    + +

    所以,谁说我们的预算太低了呢?这一个礼拜来,被几个房东、房仲呛,呛得有点不愉快。结果租这样,平均一坪也不到 500 ,离房仲讲永和平均一坪 500 也有段距离。我们又没有要住紧贴捷运站,原来的预算差不多,只是找不到坪数适合的,只好加个两千租大一点的了。

    + +

    有个在布告栏看到的房东,打电话去问了是不是有天然气,房租多少。后来他再打电话追问,我也老实说,我们希望有天然气,而且房租超出预算,他还硬追问我预算多少。没想到过了一会,他又打电话来,呛说我们的预算,只能租小套房,租不到住家。不合适就不合适,干嘛还特地打电话来呛声?真是有点莫名其妙。

    + +

    另一个有公主病的房东也很夸张:打电话去问,她要我干脆马上去看。我说我快三点了还没吃午饭,她竟然说饭可以晚点吃。我说因为是家里自己煮的没办法等,她才悻悻然挂了电话。好可怕,想想就给她简讯说不去看了。就算租到,以后也很难相处吧。说不定每个月一号凌晨一点,就打电话来催房租了。要是请她修房子,会闹到天翻地覆吧!

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 157 | + 158 | + 159 | + 160 | + 161 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0159.html.zh-tw.html b/htdocs/imacat/me/diary/0159.html.zh-tw.html new file mode 120000 index 0000000..680f7f4 --- /dev/null +++ b/htdocs/imacat/me/diary/0159.html.zh-tw.html @@ -0,0 +1 @@ +0159.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0159.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0159.html.zh-tw.xhtml new file mode 100644 index 0000000..f4ed463 --- /dev/null +++ b/htdocs/imacat/me/diary/0159.html.zh-tw.xhtml @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百五十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百五十九

    + +
    + +
    + +
    +
    3.4.’10. 10:01am.
    + +

    找房子

    + +

    每年年節,我們都會給房東送禮。房東人很好,我們也樂於當好房客。房東先生是個上海撤退來台的老兵,口音很重,有時候說話得靠猜的,不然就得靠房東太太翻譯給我們聽。

    + +

    今年也不例外。二月初買了一條鹽醃的北海鮭魚,帶去給房東。房東先生一邊稱謝,一邊說他小兒子五月要結婚,他想拜託我們什麼事的。我們聽不清楚,以為是要請喜酒,還是要拜託我們代收什麼東西,好像又不是。直到隔天早上,房東太太打電話來,才知道,房東要娶媳婦,希望我們房子讓出來,當他們兒子新房。

    + +

    這樣事情就麻煩了。畢竟是住了十二年的地方,雖然一直有地方不滿意,但住久了也習慣了。而且家中經濟負擔二月剛轉移,加上過年的花費,正在青黃不接中,搬家費用和新傢俱都要錢。更何況我還在準備研究所考試中。

    + +

    可是,不想搬也得搬。跟房東討論,他們兒子五月結婚,之前需要一個月的時間準備,也就是最晚三月底得把房子還回去。看樣子我也不用準備考試了。於是,過年回台北,忙完一些累積多時的工作,就開始找房子了。

    + +

    上個禮拜一 (2/22) 開始,每天晚上回來,就開始到處跑找房子。一開始我手上的一些工作還沒做完,只能就她印下來的零散資料,和網溪國小前的佈告欄看到的房子,一家一家去看。禮拜三把工作結束後,我開始全心找房子:做了一個 OpenOffice.org 的試算表,從 591 租屋網搜尋符合條件的中、永和的房子,搜尋到的就記錄下來,包括 591 上的編號、網址、地址、租金、聯絡人、電話、 Google 地圖的地址、離捷運的距離、有沒有天然瓦斯等。十二年前租屋找的網溪國小和頂溪國小佈告欄,我也一一去拍照,把照片編號,抄記在試算表中。因為要記要查的很多,記起來很慢,剛開始還邊記邊找。到後來,為求快速整理資料, 591 查到的資料,我改用生產線式,一個步驟一個步驟做完:先記下所有資料的編號和網址,再記下所有資料的房租和坪數,再一一點進去,記下地址、聯絡人和聯絡電話。通通記完後,我才去找 Google 地圖的地點和捷運距離。生產線記錄法果然比較有效率,之前一筆一筆記,永和二十筆資料記錄了四、五個小時,改用生產線記錄法,兩、三個小時就記錄了中和五十五筆資料。

    + +

    記完資料後,就可以利用試算表的自動篩選功能,篩選掉不適合的,像離捷運太遠、沒有天然氣等等。第一欄的註記,不適合的打叉✗,待看的打問號?,喜歡的打心形♥,待聯絡的打☎。最後一欄備註,再記下理由。

    + +

    做筆記很重要:只要搜尋到的,不管符不符合條件,都記下來,並把理由寫再備註。日後要是找不到,要回頭放寬條件時,才有所依據。而且資料要編號,抄錄下來的房子資料很多,不做筆記,電話重複打了都不知道。有些房東刊好幾個地方,有做筆記的話,聯絡電話一比對,就知道了。

    + +

    只要前置資料整理工作做得好,實際聯絡、看房子時就會輕鬆很多。這一點,管理任何資料庫,都是一樣的。最辛苦的還是前置的資料整理工作。

    + +

    聯絡後,就出門看房子了。上個禮拜一開始,平均一天看五、六戶,直到禮拜天,因為前晚資料整理得齊全,所以一口氣看了十幾戶。一個禮拜下來,馬拉松地看了四、五十戶房子。

    + +

    這時候智慧型手機就很好用了,可以打電話,可以查地圖、路線。那個禮拜,如果沒有新買的 iPhone 3GS ,面對幾乎都沒去過的地方,我沒有辦法這樣努力跑。

    + +

    看完房子,要馬上做筆記,不然會忘記。我試了幾種方法:首先,先把試算表上傳到 Google 文件上,結果發現試算表的超連結全部失效了,地圖沒辦法直接點上連結,電話號碼也沒辦法直接點上去打。而且自動篩選功能很混亂,原來設好的自動篩選,上傳上去就消失了。到很後來我才發現, Google 文件的手機版有自動篩選,可是一般版就沒有,還要安裝很慢又佔空間的自動篩選 Gadget 。而且, Google 文件要用來記筆記很難用,隨便不小心點錯,就會啟動網路連線,變成編輯模式,要取消也要網路連線, 3G 網路超耗電,多點錯幾下,手機一下子就沒電了。因為超連結不見了,筆記又不敢直接匯出成試算表下載回來,只能回來再抄。隔天禮拜六,我又回到十二年前的老方法,印出來用紙筆記,回家再抄上去。

    + +

    最後一天禮拜天,我改把資料記到通訊錄中。因為 iPhone 的通訊錄可以和 Outlook 的聯絡人互通,所以我先把資料建到 Outlook 聯絡人中,再同步到 iPhone 上。 iPhone 的通訊錄電話可以直接點選撥號,地址直接點選定位,備註也可以直接打,而且除了地圖定位外,都是離線作業,省電得多,充飽電也可以用比較久。而且房東來電,還會直接顯示。我把聯絡好要看的、待聯絡還沒聯絡上的、之前看了喜歡的,總之就是有可能要聯絡的,都存到手機的通訊錄上。反正回家都要抄到電腦上,記到手機通訊錄真的超好用,比起用 Google 文件好用得多了。

    + +

    就這樣,因為之前資料準備齊全,禮拜天早上出門,看了十幾戶,一直到晚上。中途聯絡上幾個一直聯絡不上的房東,也在四號公園前的看板上臨時抄了一家。中午手機剩一半電時,去景安站旁的Cheers! Cafe' 吉爾思咖啡拜託店家讓我充電(謝謝吉爾思咖啡!),還是把充飽的電全部用光。

    + +

    到傍晚五點多,看完所有的房子,兩個人都累壞了。本來還想找板橋、新店等其它郊區捷運站附近的,也沒力了。去了竹林路上的摩斯漢堡坐下來,翻開手機通訊錄,開始討論打♥號的房子,做第二輪的過濾:把還是有問題的篩選掉,只留下兩個人都喜歡的,打兩個♥號。第二輪選完後,最後留下四家,讓我們商透腦筋。一戶在景安站,離台北有點距離,我以後就沒辦法騎腳踏車來回台北了,就算騎機車也要一段時間,而且還要向樓上五樓收水電;一戶在我們熟悉的頂溪附近,什麼都好,房東還可以配合添購傢俱,可是房租要多三千塊錢,沒辦法殺價;一戶在永安市場站附近,坪數超大,可是打掉浴缸的浴室地板不平,還沒有瓦斯爐和抽油煙機;另外一戶很漂亮,現場一時衝動給了訂金,可是樓梯間堆滿了住戶的鞋子,都堆到梯階上了,我偶爾搬電腦上上下下,腳底下不一定看得清楚,真的很危險。

    + +

    真的好累,我竟然討論到一半睡著了。

    + +

    為了每個月多省三千塊,我還是忍痛決定去景安了。她提醒我,那裏的樓梯地板好像會滑。我們約了房東要付訂金。到了那裏,我在檢查一下樓梯地板,真的有斜度會滑。因為中永和垃圾不落地,常常要拿垃圾追垃圾車,在樓梯間跑很危險,而且我搬電腦來去也很危險,所以想一想,還是算了。

    + +

    所以,最後還是剩下頂溪附近的了。在她提議下,我打電話過去最後殺個一千看看。沒想到真的殺到了!打上三個♥號,馬上把訂金拿去給房東,敲定細節,要添購的傢俱等等,房東也先把鑰匙給我們。

    + +

    這兩天在景安路上來回,常常經過景安路上的丸居食酒屋,招牌很大很誘惑人,一直很想去吃吃看。於是趁著敲定房子慶祝,就去吃了。還蠻好吃的,烤肉串比較一般考得嫩,而且店裏都是包廂,感覺很不錯。可惜雞肉串種類不多,沒有雞肝、雞胗,我也忘了點雞翅。

    + +

    在店裏,我們開始回電話給在等電話的房東,一一回絕,也打電話給之前不小心付訂金的房東,拼命道歉。真是對人家非常抱歉。

    + +

    回來後,還是把白天看房的資料整理一下,整理到深夜,雖然已經沒什麼用了。結果不小心手賤,壓著 Shift 按了一下 Del ,一個星期的苦功,和剛剛的整理,就全部付諸流水了。直到昨晚,突然想到我檔案原先是存在 Dropbox 資料夾中,於是上 Dropbox 找,真的讓我找到了,復原回來。

    + +

    591 真的很好用。最主要的也是資料的整理。市公所在網溪國小和頂溪國小的公告欄,雖然現在有管理,沒像十幾年前那麼雜亂,可是廣告紙還是張貼人自己寫的,沒有統一的格式,裏面甚至有只留電話的,篩選起來很辛苦。相對的, 591 把所有資料格式化了,電話、地址、天然瓦斯等等條件,都存到資料庫,篩選起來輕鬆很多。

    + +

    搜尋的時候,房價上限可以高個兩千塊錢,看滿意再跟房東殺價。大多數房東只要真的喜歡的話,都可以殺價。不過缺點是看到好房子如果殺不動的話,會很心痛。而且殺價談判也是很累的事。

    + +

    當然也有無法殺價的房子。我在永安市場站旁看到一戶,就在永安市場站旁的巷子轉進去,走路一分鐘,屋況也很好。這麼誇張的好地點,房租本應高出很多,如果不是房東本來就降價了,根本不會出現在我搜尋的結果中。所以房東沒辦法再降價了,我們也認了。

    + +

    聯絡好了以後,去現場看,要是喜歡,探探房東殺房租的口風就好,不需要真的殺下去。畢竟還要比較,殺了很兇還說要再看看,很不禮貌,日後就算來租,房東也不會給好臉色看。

    + +

    第一次去現場看,絕對不要喜歡就決定了給訂金。馬上決定了,房東當然高興。不過就像購物一樣,太過依賴一時看漂亮的衝動,日後很容易後悔。住房子是長久的事。忍住衝動,回來再仔細想想,而且至少把手頭上的其它房子看完。我們就不小心看到漂亮的房子,就把訂金給出去了,事後想想,樓下住戶鞋子放到樓梯階上,違反消防法規又很危險,房子緊臨馬路很吵,格局又不好,只好事後拼命跟房東道歉,訂金也付諸流水了。

    + +

    一般都是看第二次的時候才會殺價、決定。當然有可能這段時間房子被租走了,那就當無緣吧。不過,現在這種時機,房子本來就不大好租了,所以也不必太擔心。房東一定會說什麼還有一組人看了多喜歡,聽聽就好,不要在意。

    + +

    第一次看,想看的地方一定要看清楚:熱水爐位置、浴室大小、手機收訊等等。再打電話去問屋況沒關係,但如果再打電話去殺價,或是再到現場看,通常就是要租了。不要抱著再看看的心態,會惹人厭。以後租了,房東也不會給好臉色。就算不租,這個世界很小,總有一天會遇到。所以第二次打電話去殺價的時候,就要想清楚,真的很喜歡想住了。這是做房客的基本誠意。

    + +

    不景氣,房子其實很難租出去,就算租出去,也很難碰到好房客。如果有穩定的工作、之前住很久等等,趁閒聊時跟房東說,房東會列入考慮,也有助於殺價。房子放著租不出去就是賠錢,如果是貸款買的,每個月付的房貸更是可怕。所以房東都會急著想租出去,比房客還急。談判的時候,只要不要太誇張,都可以跟房東說說看。 591 上有刊登時間,從刊登時間可以知道房子已經多久沒租出去了。 591 的編號也是從前到後,現在是 459xxx ,編號 40xxxx 的,都已經好幾個月沒租出去了。越久租不出去的,房東越急著想租出去,談判的空間當然也越大。

    + +

    這一個禮拜來,過濾了中、永和 209 筆招租的資料,實際去看了四、五十戶,還經過三階段決選,才找到現在這個房子。雖然房租貴了些,但是離捷運站近,離台北近,有天然瓦斯,鄰居習慣好樓梯間乾淨,手機收訊佳,採光通風好,房東人好,有臥室,有書房,有客廳,有前後陽台,有沒加蓋的頂樓陽台,樓下有地方停車。和現在的套房雙拼,所有的生活空間全在一起比起來,總算有家的感覺了,也可以帶家人、朋友來坐。

    + +

    這個房租,以我們兩個的固定收入來說是勉強夠,不過就很難存錢了。當然還有一些兼職的收入,可以存下來,不過不穩定的收入無法依賴。不過捷運少個兩站,運費也會少一些吧。我可以騎腳踏車來回台北市中心,不趕時間的話,油錢也省了。就算騎車去台北,油錢也比較少,而且距離沒那麼遠,回來比較不會累,也比較安全。萬一趕時間要坐計程車,車錢也省很多。水、電都是獨立電表,用電省的話,每度電費也會降,努力省電會省更多錢。

    + +

    回頭一查,發現十年前租的租金,只比新家便宜兩千,是後來房東降租,才會感覺差那麼多。感覺好像玩模擬市民,人生隨著職等昇級,生活、房屋也跟著昇級一樣。

    + +

    其實只要同樣地點,同樣房東,同樣鄰居,同樣樓梯間管理,同樣屋況,再少個 10 坪,房租少個兩、三千,就太完美了。現在房子這麼大,多付這兩千房租實在也有點困擾。可惜天底下沒有這麼完美的事。

    + +

    所以,誰說我們的預算太低了呢?這一個禮拜來,被幾個房東、房仲嗆,嗆得有點不愉快。結果租這樣,平均一坪也不到 500 ,離房仲講永和平均一坪 500 也有段距離。我們又沒有要住緊貼捷運站,原來的預算差不多,只是找不到坪數適合的,只好加個兩千租大一點的了。

    + +

    有個在佈告欄看到的房東,打電話去問了是不是有天然氣,房租多少。後來他再打電話追問,我也老實說,我們希望有天然氣,而且房租超出預算,他還硬追問我預算多少。沒想到過了一會,他又打電話來,嗆說我們的預算,只能租小套房,租不到住家。不合適就不合適,幹嘛還特地打電話來嗆聲?真是有點莫名其妙。

    + +

    另一個有公主病的房東也很誇張:打電話去問,她要我乾脆馬上去看。我說我快三點了還沒吃午飯,她竟然說飯可以晚點吃。我說因為是家裏自己煮的沒辦法等,她才悻悻然掛了電話。好可怕,想想就給她簡訊說不去看了。就算租到,以後也很難相處吧。說不定每個月一號凌晨一點,就打電話來催房租了。要是請她修房子,會鬧到天翻地覆吧!

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 157 | + 158 | + 159 | + 160 | + 161 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0160.html.en.html b/htdocs/imacat/me/diary/0160.html.en.html new file mode 120000 index 0000000..9e303ef --- /dev/null +++ b/htdocs/imacat/me/diary/0160.html.en.html @@ -0,0 +1 @@ +0160.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0160.html.en.xhtml b/htdocs/imacat/me/diary/0160.html.en.xhtml new file mode 100644 index 0000000..8f30415 --- /dev/null +++ b/htdocs/imacat/me/diary/0160.html.en.xhtml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 160 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 160

    + +
    + +
    + +
    +
    5.24.’10. 8:34pm.
    + +

    木須肉

    + +
    +木須肉 +

    木須肉

    +
    + +

    今天晚上做的木須肉,味道和外觀都非常完美。好吃!

    + +

    木須肉是我搬出宿舍住外面後,繼青椒牛肉,學的第二道菜。那時候買了一本四川菜食譜,做熟了愛吃的青椒牛肉後,想換換口味。我不吃辣,木須肉看起來不辣,就學了這道。那個時候,我其實還不大清楚木須肉是什麼。 ^^;

    + +

    日前搬家搬到這個有好廚房的新家,而且又沒有上班了,就開始恢復做菜,慢慢學做一些比較耗工夫的食譜菜。花了三個禮拜,失敗了十次左右,才做好青椒牛肉。習慣了比較繁複的菜的料理法,木須肉我做到第二道,就重現了。

    + +

    好啦,我知道青椒牛肉和木須肉都稱不上繁複。可是我是料理新手啊! ^^;

    + + +
    +青椒牛肉 +

    2010/5/7(五)晚上做的青椒牛肉

    +
    + +
    + +
    + +
    +
    5.2.’10. 3:00am.
    + +

    Ubuntu 10.04 Lucid Lynx LTS初感

    + +

    用 Live CD 跑了一下 Ubuntu 10.04 Lucid Lynx LTS ,初步試用感想:

    + +
      +
    • ibus 傳統注音終於可以選字了,可是候選字還是繁簡夾雜,簡體排在繁體前面,和傳統注音選字的習慣次序差很多,很難按注音的習慣選字挑字。這是和 scim 一樣的問題,候選字表是爛的,根本無法使用。不過 ibus 還在維護,不像 scim ,所以或許可以向作者反映修正。但總之, Ubuntu 10.04 我還是得裝回 gcin 或 oxim 才能輸入中文了。
    • + +
    • Ubuntu 10.04 除了 Gnome 、 KDE 更新版外,最大的新功能設計就是 MeMenu 了。這很像是模仿 MacOS 的設計,把所有的東西都綁在一起。 MeMenu 整合進工具列上,用 Empathy 整合了 UbuntuOne 和所有的社交工具: Facebook 、 Twitter 等等,即時更新自己的狀態。然而,台灣人用最多的噗浪,也沒有。只有日本人流行的微網誌 Ameba ,當然也不在裏面。到頭來,這個功能還是只服務西方人。
    • +
    + +

    從把所有的東西綁在一起,來強化整合性和使用感來說, Ubuntu 越來越像 Apple 了。

    + +

    P.S.: 承蒙 BlueT 指正, Empathy 替代的不是郵件功能,而是即時通訊功能。據此修正。感謝指正。

    + +
    + +
    + +
    +
    4.14.’10. 9:22pm.
    + +

    黃飯

    + +
    +黃飯 +

    黃飯

    +
    + +

    好久沒做了。這是我奶奶家傳的黃飯,營養滿分,簡單好做,好吃,顏色鮮豔小孩子喜歡。搭配海苔醬油的日式吃法,去膩更香,一口接一口。

    + +

    好餓喔!我晚上為什麼只煮一碗飯呢?

    + +

    做法

    + +

    (一碗飯)一小塊奶油,一顆蛋黃,一顆蒜頭切末。白飯煮好後,開鍋時立刻倒入,攪拌均勻即可。海苔沾醬油,用筷子捲起黃飯吃。

    + +
    + +
    + +
    +
    3.7.’10. 1:17pm.
    + +

    菜刀

    + +

    看著新磨利的菜刀,一股恐怖感油然而生。

    + +

    小時候很害怕菜刀。曾經做過莫名奇妙的惡夢,夢到家人拿菜刀砍得血肉模糊,同樣的惡夢做了好幾次,不道為什麼。那是完全沒有根據、毫無來由的惡夢。從小看著奶奶用菜刀切人蔘、切薑、切蒜,覺得奶奶很厲害,也覺得很恐怖。

    + +

    恢復耕讀的生活,每天做菜做了兩個多月。菜刀切的,其實也只是蔬菜而已。前幾天看菜刀生鏽,偶然要切肉絲切不開,於是上網找到中、永和僅存的打鐵店永春鐵店,昨天就把菜刀拿去磨。新磨好的菜刀很利很亮,感覺很開心,可是看著閃亮亮的銳利刀鋒,潛意識中的恐怖感,又從心底冒出來。

    + +
    + +
    + +
    +
    3.4.’10. 10:45am.
    + +

    追垃圾車

    + +

    昨晚在廚房發呆,猛一回頭,聽到垃圾車的音樂就在樓下。中、永和實施垃圾不落地,垃圾只能在垃圾車來的時候拿出去丟。盤算一下,雖然大概來不及了,滿溢出來的垃圾和資源回收,還是非丟不可。趕緊包起垃圾往樓下跑,垃圾車已經不見了。騎上腳踏車往平常垃圾車離去的方向追上去,還是看不到蹤影。趕緊拿 iPhone 查垃圾車的路線,也查不到。提出來的垃圾又不可能再拿回家,陷入進退不得的窘境。在永和街頭漫無目標地亂晃一會,下定決心,碰運氣往永和清潔隊總部騎,看清潔隊能不能幫忙。沒想到竟然給我在文化路,碰上迎面而來的垃圾車,倒了垃圾。

    + +

    穿著隨便的家居服,提著垃圾袋,在永和街頭漫無目的地亂晃,我大概很引人側目吧!

    + +

    一路上,開始痛恨起這個讓我進退兩難的垃圾不落地政策。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 158 | + 159 | + 160 | + 161 | + 162 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0160.html.zh-cn.html b/htdocs/imacat/me/diary/0160.html.zh-cn.html new file mode 120000 index 0000000..a231a08 --- /dev/null +++ b/htdocs/imacat/me/diary/0160.html.zh-cn.html @@ -0,0 +1 @@ +0160.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0160.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0160.html.zh-cn.xhtml new file mode 100644 index 0000000..ef0246e --- /dev/null +++ b/htdocs/imacat/me/diary/0160.html.zh-cn.xhtml @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百六十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百六十

    + +
    + +
    + +
    +
    5.24.’10. 8:34pm.
    + +

    木须肉

    + +
    +木须肉 +

    木须肉

    +
    + +

    今天晚上做的木须肉,味道和外观都非常完美。好吃!

    + +

    木须肉是我搬出宿舍住外面后,继青椒牛肉,学的第二道菜。那时候买了一本四川菜食谱,做熟了爱吃的青椒牛肉后,想换换口味。我不吃辣,木须肉看起来不辣,就学了这道。那个时候,我其实还不大清楚木须肉是什么。 ^^;

    + +

    日前搬家搬到这个有好厨房的新家,而且又没有上班了,就开始恢复做菜,慢慢学做一些比较耗工夫的食谱菜。花了三个礼拜,失败了十次左右,才做好青椒牛肉。习惯了比较繁复的菜的料理法,木须肉我做到第二道,就重现了。

    + +

    好啦,我知道青椒牛肉和木须肉都称不上繁复。可是我是料理新手啊! ^^;

    + + +
    +青椒牛肉 +

    2010/5/7(五)晚上做的青椒牛肉

    +
    + +
    + +
    + +
    +
    5.2.’10. 3:00am.
    + +

    Ubuntu 10.04 Lucid Lynx LTS初感

    + +

    用 Live CD 跑了一下 Ubuntu 10.04 Lucid Lynx LTS ,初步试用感想:

    + +
      +
    • ibus 传统注音终於可以选字了,可是候选字还是繁简夹杂,简体排在繁体前面,和传统注音选字的习惯次序差很多,很难按注音的习惯选字挑字。这是和 scim 一样的问题,候选字表是烂的,根本无法使用。不过 ibus 还在维护,不像 scim ,所以或许可以向作者反映修正。但总之, Ubuntu 10.04 我还是得装回 gcin 或 oxim 才能输入中文了。
    • + +
    • Ubuntu 10.04 除了 Gnome 、 KDE 更新版外,最大的新功能设计就是 MeMenu 了。这很像是模仿 MacOS 的设计,把所有的东西都绑在一起。 MeMenu 整合进工具列上,用 Empathy 整合了 UbuntuOne 和所有的社交工具: Facebook 、 Twitter 等等,即时更新自己的状态。然而,台湾人用最多的噗浪,也没有。只有日本人流行的微网志 Ameba ,当然也不在里面。到头来,这个功能还是只服务西方人。
    • +
    + +

    从把所有的东西绑在一起,来强化整合性和使用感来说, Ubuntu 越来越像 Apple 了。

    + +

    P.S.: 承蒙 BlueT 指正, Empathy 替代的不是邮件功能,而是即时通讯功能。据此修正。感谢指正。

    + +
    + +
    + +
    +
    4.14.’10. 9:22pm.
    + +

    黄饭

    + +
    +黄饭 +

    黄饭

    +
    + +

    好久没做了。这是我奶奶家传的黄饭,营养满分,简单好做,好吃,颜色鲜艳小孩子喜欢。搭配海苔酱油的日式吃法,去腻更香,一口接一口。

    + +

    好饿喔!我晚上为什么只煮一碗饭呢?

    + +

    做法

    + +

    (一碗饭)一小块奶油,一颗蛋黄,一颗蒜头切末。白饭煮好后,开锅时立刻倒入,搅拌均匀即可。海苔沾酱油,用筷子卷起黄饭吃。

    + +
    + +
    + +
    +
    3.7.’10. 1:17pm.
    + +

    菜刀

    + +

    看著新磨利的菜刀,一股恐怖感油然而生。

    + +

    小时候很害怕菜刀。曾经做过莫名奇妙的恶梦,梦到家人拿菜刀砍得血肉模糊,同样的恶梦做了好几次,不道为什么。那是完全没有根据、毫无来由的恶梦。从小看著奶奶用菜刀切人蔘、切姜、切蒜,觉得奶奶很厉害,也觉得很恐怖。

    + +

    恢复耕读的生活,每天做菜做了两个多月。菜刀切的,其实也只是蔬菜而已。前几天看菜刀生锈,偶然要切肉丝切不开,於是上网找到中、永和仅存的打铁店永春铁店,昨天就把菜刀拿去磨。新磨好的菜刀很利很亮,感觉很开心,可是看著闪亮亮的锐利刀锋,潜意识中的恐怖感,又从心底冒出来。

    + +
    + +
    + +
    +
    3.4.’10. 10:45am.
    + +

    追垃圾车

    + +

    昨晚在厨房发呆,猛一回头,听到垃圾车的音乐就在楼下。中、永和实施垃圾不落地,垃圾只能在垃圾车来的时候拿出去丢。盘算一下,虽然大概来不及了,满溢出来的垃圾和资源回收,还是非丢不可。赶紧包起垃圾往楼下跑,垃圾车已经不见了。骑上脚踏车往平常垃圾车离去的方向追上去,还是看不到踪影。赶紧拿 iPhone 查垃圾车的路线,也查不到。提出来的垃圾又不可能再拿回家,陷入进退不得的窘境。在永和街头漫无目标地乱晃一会,下定决心,碰运气往永和清洁队总部骑,看清洁队能不能帮忙。没想到竟然给我在文化路,碰上迎面而来的垃圾车,倒了垃圾。

    + +

    穿著随便的家居服,提著垃圾袋,在永和街头漫无目的地乱晃,我大概很引人侧目吧!

    + +

    一路上,开始痛恨起这个让我进退两难的垃圾不落地政策。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 158 | + 159 | + 160 | + 161 | + 162 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0160.html.zh-tw.html b/htdocs/imacat/me/diary/0160.html.zh-tw.html new file mode 120000 index 0000000..2d8fe61 --- /dev/null +++ b/htdocs/imacat/me/diary/0160.html.zh-tw.html @@ -0,0 +1 @@ +0160.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0160.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0160.html.zh-tw.xhtml new file mode 100644 index 0000000..f35fdc7 --- /dev/null +++ b/htdocs/imacat/me/diary/0160.html.zh-tw.xhtml @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百六十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百六十

    + +
    + +
    + +
    +
    5.24.’10. 8:34pm.
    + +

    木須肉

    + +
    +木須肉 +

    木須肉

    +
    + +

    今天晚上做的木須肉,味道和外觀都非常完美。好吃!

    + +

    木須肉是我搬出宿舍住外面後,繼青椒牛肉,學的第二道菜。那時候買了一本四川菜食譜,做熟了愛吃的青椒牛肉後,想換換口味。我不吃辣,木須肉看起來不辣,就學了這道。那個時候,我其實還不大清楚木須肉是什麼。 ^^;

    + +

    日前搬家搬到這個有好廚房的新家,而且又沒有上班了,就開始恢復做菜,慢慢學做一些比較耗工夫的食譜菜。花了三個禮拜,失敗了十次左右,才做好青椒牛肉。習慣了比較繁複的菜的料理法,木須肉我做到第二道,就重現了。

    + +

    好啦,我知道青椒牛肉和木須肉都稱不上繁複。可是我是料理新手啊! ^^;

    + + +
    +青椒牛肉 +

    2010/5/7(五)晚上做的青椒牛肉

    +
    + +
    + +
    + +
    +
    5.2.’10. 3:00am.
    + +

    Ubuntu 10.04 Lucid Lynx LTS初感

    + +

    用 Live CD 跑了一下 Ubuntu 10.04 Lucid Lynx LTS ,初步試用感想:

    + +
      +
    • ibus 傳統注音終於可以選字了,可是候選字還是繁簡夾雜,簡體排在繁體前面,和傳統注音選字的習慣次序差很多,很難按注音的習慣選字挑字。這是和 scim 一樣的問題,候選字表是爛的,根本無法使用。不過 ibus 還在維護,不像 scim ,所以或許可以向作者反映修正。但總之, Ubuntu 10.04 我還是得裝回 gcin 或 oxim 才能輸入中文了。
    • + +
    • Ubuntu 10.04 除了 Gnome 、 KDE 更新版外,最大的新功能設計就是 MeMenu 了。這很像是模仿 MacOS 的設計,把所有的東西都綁在一起。 MeMenu 整合進工具列上,用 Empathy 整合了 UbuntuOne 和所有的社交工具: Facebook 、 Twitter 等等,即時更新自己的狀態。然而,台灣人用最多的噗浪,也沒有。只有日本人流行的微網誌 Ameba ,當然也不在裏面。到頭來,這個功能還是只服務西方人。
    • +
    + +

    從把所有的東西綁在一起,來強化整合性和使用感來說, Ubuntu 越來越像 Apple 了。

    + +

    P.S.: 承蒙 BlueT 指正, Empathy 替代的不是郵件功能,而是即時通訊功能。據此修正。感謝指正。

    + +
    + +
    + +
    +
    4.14.’10. 9:22pm.
    + +

    黃飯

    + +
    +黃飯 +

    黃飯

    +
    + +

    好久沒做了。這是我奶奶家傳的黃飯,營養滿分,簡單好做,好吃,顏色鮮豔小孩子喜歡。搭配海苔醬油的日式吃法,去膩更香,一口接一口。

    + +

    好餓喔!我晚上為什麼只煮一碗飯呢?

    + +

    做法

    + +

    (一碗飯)一小塊奶油,一顆蛋黃,一顆蒜頭切末。白飯煮好後,開鍋時立刻倒入,攪拌均勻即可。海苔沾醬油,用筷子捲起黃飯吃。

    + +
    + +
    + +
    +
    3.7.’10. 1:17pm.
    + +

    菜刀

    + +

    看著新磨利的菜刀,一股恐怖感油然而生。

    + +

    小時候很害怕菜刀。曾經做過莫名奇妙的惡夢,夢到家人拿菜刀砍得血肉模糊,同樣的惡夢做了好幾次,不道為什麼。那是完全沒有根據、毫無來由的惡夢。從小看著奶奶用菜刀切人蔘、切薑、切蒜,覺得奶奶很厲害,也覺得很恐怖。

    + +

    恢復耕讀的生活,每天做菜做了兩個多月。菜刀切的,其實也只是蔬菜而已。前幾天看菜刀生鏽,偶然要切肉絲切不開,於是上網找到中、永和僅存的打鐵店永春鐵店,昨天就把菜刀拿去磨。新磨好的菜刀很利很亮,感覺很開心,可是看著閃亮亮的銳利刀鋒,潛意識中的恐怖感,又從心底冒出來。

    + +
    + +
    + +
    +
    3.4.’10. 10:45am.
    + +

    追垃圾車

    + +

    昨晚在廚房發呆,猛一回頭,聽到垃圾車的音樂就在樓下。中、永和實施垃圾不落地,垃圾只能在垃圾車來的時候拿出去丟。盤算一下,雖然大概來不及了,滿溢出來的垃圾和資源回收,還是非丟不可。趕緊包起垃圾往樓下跑,垃圾車已經不見了。騎上腳踏車往平常垃圾車離去的方向追上去,還是看不到蹤影。趕緊拿 iPhone 查垃圾車的路線,也查不到。提出來的垃圾又不可能再拿回家,陷入進退不得的窘境。在永和街頭漫無目標地亂晃一會,下定決心,碰運氣往永和清潔隊總部騎,看清潔隊能不能幫忙。沒想到竟然給我在文化路,碰上迎面而來的垃圾車,倒了垃圾。

    + +

    穿著隨便的家居服,提著垃圾袋,在永和街頭漫無目的地亂晃,我大概很引人側目吧!

    + +

    一路上,開始痛恨起這個讓我進退兩難的垃圾不落地政策。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 158 | + 159 | + 160 | + 161 | + 162 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0161.html.en.html b/htdocs/imacat/me/diary/0161.html.en.html new file mode 120000 index 0000000..b29c638 --- /dev/null +++ b/htdocs/imacat/me/diary/0161.html.en.html @@ -0,0 +1 @@ +0161.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0161.html.en.xhtml b/htdocs/imacat/me/diary/0161.html.en.xhtml new file mode 100644 index 0000000..09e875a --- /dev/null +++ b/htdocs/imacat/me/diary/0161.html.en.xhtml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 161 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 161

    + +
    + +
    + +
    +
    7.18.’10. 8:13pm.
    + +
    +祭 五穀神農先帝 祭文 +
    + +

    祭 五穀神農先帝

    + +
    +手執清香 敬備五穀 躬身拜請
    +五穀神農 農民於此 今請訴求
    +官欺百姓 奪沃淆地 與奸同污
    +悲憤農民 天地浮游 不仁不義
    +天地不容 唯 上告神農 助輩之力
    +降福予民 庇佑眾生 是德是善
    +五穀豐收
    +
    + +

    敬拜

    + +

    中華民國九十九年七月十八日

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 159 | + 160 | + 161 | + 162 | + 163 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0161.html.zh-cn.html b/htdocs/imacat/me/diary/0161.html.zh-cn.html new file mode 120000 index 0000000..ac1d9a2 --- /dev/null +++ b/htdocs/imacat/me/diary/0161.html.zh-cn.html @@ -0,0 +1 @@ +0161.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0161.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0161.html.zh-cn.xhtml new file mode 100644 index 0000000..8107333 --- /dev/null +++ b/htdocs/imacat/me/diary/0161.html.zh-cn.xhtml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百六十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百六十一

    + +
    + +
    + +
    +
    7.18.’10. 8:13pm.
    + +
    +祭 五谷神农先帝 祭文 +
    + +

    祭 五谷神农先帝

    + +
    +手执清香 敬备五谷 躬身拜请
    +五谷神农 农民於此 今请诉求
    +官欺百姓 夺沃淆地 与奸同污
    +悲愤农民 天地浮游 不仁不义
    +天地不容 唯 上告神农 助辈之力
    +降福予民 庇佑众生 是德是善
    +五谷丰收
    +
    + +

    敬拜

    + +

    中华民国九十九年七月十八日

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 159 | + 160 | + 161 | + 162 | + 163 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0161.html.zh-tw.html b/htdocs/imacat/me/diary/0161.html.zh-tw.html new file mode 120000 index 0000000..4cf3662 --- /dev/null +++ b/htdocs/imacat/me/diary/0161.html.zh-tw.html @@ -0,0 +1 @@ +0161.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0161.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0161.html.zh-tw.xhtml new file mode 100644 index 0000000..2a1d8e4 --- /dev/null +++ b/htdocs/imacat/me/diary/0161.html.zh-tw.xhtml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百六十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百六十一

    + +
    + +
    + +
    +
    7.18.’10. 8:13pm.
    + +
    +祭 五穀神農先帝 祭文 +
    + +

    祭 五穀神農先帝

    + +
    +手執清香 敬備五穀 躬身拜請
    +五穀神農 農民於此 今請訴求
    +官欺百姓 奪沃淆地 與奸同污
    +悲憤農民 天地浮游 不仁不義
    +天地不容 唯 上告神農 助輩之力
    +降福予民 庇佑眾生 是德是善
    +五穀豐收
    +
    + +

    敬拜

    + +

    中華民國九十九年七月十八日

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 159 | + 160 | + 161 | + 162 | + 163 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0162.html.en.html b/htdocs/imacat/me/diary/0162.html.en.html new file mode 120000 index 0000000..f8d3c51 --- /dev/null +++ b/htdocs/imacat/me/diary/0162.html.en.html @@ -0,0 +1 @@ +0162.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0162.html.en.xhtml b/htdocs/imacat/me/diary/0162.html.en.xhtml new file mode 100644 index 0000000..02fdf84 --- /dev/null +++ b/htdocs/imacat/me/diary/0162.html.en.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 162 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 162

    + +
    + +
    + +
    +
    10.26.’10. 9:25pm.
    + +

    The Kids Are All Right 性福拉警報—女同志家庭喜劇

    + +
    +The Kids Are All Right 性福拉警報
    +

    The Kids Are All Right 性福拉警報

    +
    + + + +

    性福拉警報敘述一對相戀結婚二十年的女同志伴侶,從事醫生的妮可與無業的茱兒,各自藉由借同一人的精子生子,育有一女一子瓊妮與雷茲。成績優異的瓊妮申請上了大學,入學前一個月,弟弟雷茲突然說想見親生父親。拗不過弟弟,剛成年的瓊妮透過捐精中心,在取得捐精者保羅的同意後,三人私下見了面。從事地方有機蔬果買賣的保羅,大學未畢業,自由風趣,深得瓊妮和雷茲的喜愛。三人見面之事,被雙親知道了。尷𠆷不已的雙親,還是表現風度,邀請保羅來家裏。聊天之間,得知茱兒想從事園藝設計,保羅請茱兒設計自家後院。幾次在保羅家工作後,茱兒和保羅情慾爆發,每天瘋狂做愛。茱兒還因心虛開除了園丁。妮可眼見家人都心向保羅,自己被排除在外,決定主動示好,提議全家到保羅家做客。荒廢工作的茱兒只好拼命趕工。在保羅家,正當聊到喜愛的音樂,妮可以為自己終於可以和保羅做好朋友時,無意間發現茱兒和保羅上床。妮可回家後和茱兒攤牌,被瓊妮與雷茲聽到,從此家中陷入冷戰。茱兒得不到家人的原諒,和打算趁勢定下來成家的保羅切斷關係。瓊妮上大學前晚,保羅造訪試圖取得子女原諒,得不到正面的回應,還被妮可轟出門。保羅的造訪掀起全家人的傷痕,茱兒當全家人面前,認錯道歉。隔天送瓊妮到宿舍後,瓊妮開始想念家人,妮可與茱兒也在兒子雷茲的促合下,言歸於好。

    + +

    這是一部輕鬆的家庭喜劇。

    + +

    性福拉警報試圖去碰撞兩個禁忌:女同志伴侶中,男性的介入;和借精生子的婚姻中,孩子親生父母的介入。對借精生子的女同志家庭而言,簡直是兩件最討厭的事合而為一了。性福拉警報雖然去碰撞這兩個禁忌,卻以輕鬆詼諧的方式呈現,觀眾在心中越趨發麻的緊張感同時,劇中的角色卻又努力試圖去消除彼此的尷𠆷。到最後紙包不住火,一切攤在陽光下後,觀眾不得不去面對最糟糕的結果。這時候,再次出現的外人,即降離家的成員,使得家庭成員的連繫力量適時出現,把彼此的手再次牽起來。

    + +

    藉由這部電影,導演莉莎蔻洛丹柯試圖將女同志家庭,推入主流社會的家庭價值核心中。有別於前一部電影高檔貨 High Art中,情慾脫軌地竄動,性福拉警報一開始,女同志家庭就高調地出現,和異性戀家庭沒有兩樣,直接融入主流中產階級生活方式的核心中,相愛的雙親和一對子女,彷彿就是那麼自然。即使經歷了使家庭瀕臨破裂的外遇,但最後親情的召喚,還是讓家人團結在一起。這一切,也和異性戀家庭喜劇的結局相同。於是,同志家庭不論是開始或結束,都和異性戀家庭一樣,受到家庭價值的感召與制約,融為一體。導演巧妙地藉由這部電影,讓同志家庭,成為主流社會價值的一份子,讓不論是異性戀或同性戀觀眾,都接受得如此自然。

    + +

    至於現實生活呢?現實生活中,外遇的結果,不一定能夠有這麼完美的結局。畢竟這是電影,是喜劇。但是,性福拉警報還是給同志家庭,帶來正面的想像:同志家庭,和一般的家庭,其實也沒有什麼兩樣。就同志家庭和異性戀家庭其實沒什麼兩樣這個層次而言,它呈現的又是真實,而不是想像。

    + +

    導演安排所有事件,發生在女兒瓊妮要離家上大學前的一個月內。因為家庭成員離開的時限壓力,而觸發了這一連串的事件(弟弟想趁姊姊離開前見生父),也因為家庭成員離開的時限,為所有事件劃下一個必然的停止點。這樣的架構技巧,也是很有趣的。

    + +

    這次因為同志家庭權益促進會與電影公司合作的關係,得以參加試映會。謝謝同家會,也謝謝電影公司。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 160 | + 161 | + 162 | + 163 | + 164 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0162.html.zh-cn.html b/htdocs/imacat/me/diary/0162.html.zh-cn.html new file mode 120000 index 0000000..769415e --- /dev/null +++ b/htdocs/imacat/me/diary/0162.html.zh-cn.html @@ -0,0 +1 @@ +0162.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0162.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0162.html.zh-cn.xhtml new file mode 100644 index 0000000..4661612 --- /dev/null +++ b/htdocs/imacat/me/diary/0162.html.zh-cn.xhtml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百六十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百六十二

    + +
    + +
    + +
    +
    10.26.’10. 9:25pm.
    + +

    The Kids Are All Right 性福拉警报—女同志家庭喜剧

    + +
    +The Kids Are All Right 性福拉警报
    +

    The Kids Are All Right 性福拉警报

    +
    + + + +

    性福拉警报叙述一对相恋结婚二十年的女同志伴侣,从事医生的妮可与无业的茱儿,各自藉由借同一人的精子生子,育有一女一子琼妮与雷兹。成绩优异的琼妮申请上了大学,入学前一个月,弟弟雷兹突然说想见亲生父亲。拗不过弟弟,刚成年的琼妮透过捐精中心,在取得捐精者保罗的同意后,三人私下见了面。从事地方有机蔬果买卖的保罗,大学未毕业,自由风趣,深得琼妮和雷兹的喜爱。三人见面之事,被双亲知道了。尴𠆷不已的双亲,还是表现风度,邀请保罗来家里。聊天之间,得知茱儿想从事园艺设计,保罗请茱儿设计自家后院。几次在保罗家工作后,茱儿和保罗情欲爆发,每天疯狂做爱。茱儿还因心虚开除了园丁。妮可眼见家人都心向保罗,自己被排除在外,决定主动示好,提议全家到保罗家做客。荒废工作的茱儿只好拼命赶工。在保罗家,正当聊到喜爱的音乐,妮可以为自己终於可以和保罗做好朋友时,无意间发现茱儿和保罗上床。妮可回家后和茱儿摊牌,被琼妮与雷兹听到,从此家中陷入冷战。茱儿得不到家人的原谅,和打算趁势定下来成家的保罗切断关系。琼妮上大学前晚,保罗造访试图取得子女原谅,得不到正面的回应,还被妮可轰出门。保罗的造访掀起全家人的伤痕,茱儿当全家人面前,认错道歉。隔天送琼妮到宿舍后,琼妮开始想念家人,妮可与茱儿也在儿子雷兹的促合下,言归於好。

    + +

    这是一部轻松的家庭喜剧。

    + +

    性福拉警报试图去碰撞两个禁忌:女同志伴侣中,男性的介入;和借精生子的婚姻中,孩子亲生父母的介入。对借精生子的女同志家庭而言,简直是两件最讨厌的事合而为一了。性福拉警报虽然去碰撞这两个禁忌,却以轻松诙谐的方式呈现,观众在心中越趋发麻的紧张感同时,剧中的角色却又努力试图去消除彼此的尴𠆷。到最后纸包不住火,一切摊在阳光下后,观众不得不去面对最糟糕的结果。这时候,再次出现的外人,即降离家的成员,使得家庭成员的连系力量适时出现,把彼此的手再次牵起来。

    + +

    藉由这部电影,导演莉莎蔻洛丹柯试图将女同志家庭,推入主流社会的家庭价值核心中。有别於前一部电影高档货 High Art中,情欲脱轨地窜动,性福拉警报一开始,女同志家庭就高调地出现,和异性恋家庭没有两样,直接融入主流中产阶级生活方式的核心中,相爱的双亲和一对子女,彷佛就是那么自然。即使经历了使家庭濒临破裂的外遇,但最后亲情的召唤,还是让家人团结在一起。这一切,也和异性恋家庭喜剧的结局相同。於是,同志家庭不论是开始或结束,都和异性恋家庭一样,受到家庭价值的感召与制约,融为一体。导演巧妙地藉由这部电影,让同志家庭,成为主流社会价值的一份子,让不论是异性恋或同性恋观众,都接受得如此自然。

    + +

    至於现实生活呢?现实生活中,外遇的结果,不一定能够有这么完美的结局。毕竟这是电影,是喜剧。但是,性福拉警报还是给同志家庭,带来正面的想像:同志家庭,和一般的家庭,其实也没有什么两样。就同志家庭和异性恋家庭其实没什么两样这个层次而言,它呈现的又是真实,而不是想像。

    + +

    导演安排所有事件,发生在女儿琼妮要离家上大学前的一个月内。因为家庭成员离开的时限压力,而触发了这一连串的事件(弟弟想趁姊姊离开前见生父),也因为家庭成员离开的时限,为所有事件划下一个必然的停止点。这样的架构技巧,也是很有趣的。

    + +

    这次因为同志家庭权益促进会与电影公司合作的关系,得以参加试映会。谢谢同家会,也谢谢电影公司。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 160 | + 161 | + 162 | + 163 | + 164 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0162.html.zh-tw.html b/htdocs/imacat/me/diary/0162.html.zh-tw.html new file mode 120000 index 0000000..5c9d8ca --- /dev/null +++ b/htdocs/imacat/me/diary/0162.html.zh-tw.html @@ -0,0 +1 @@ +0162.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0162.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0162.html.zh-tw.xhtml new file mode 100644 index 0000000..467f835 --- /dev/null +++ b/htdocs/imacat/me/diary/0162.html.zh-tw.xhtml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百六十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百六十二

    + +
    + +
    + +
    +
    10.26.’10. 9:25pm.
    + +

    The Kids Are All Right 性福拉警報—女同志家庭喜劇

    + +
    +The Kids Are All Right 性福拉警報
    +

    The Kids Are All Right 性福拉警報

    +
    + + + +

    性福拉警報敘述一對相戀結婚二十年的女同志伴侶,從事醫生的妮可與無業的茱兒,各自藉由借同一人的精子生子,育有一女一子瓊妮與雷茲。成績優異的瓊妮申請上了大學,入學前一個月,弟弟雷茲突然說想見親生父親。拗不過弟弟,剛成年的瓊妮透過捐精中心,在取得捐精者保羅的同意後,三人私下見了面。從事地方有機蔬果買賣的保羅,大學未畢業,自由風趣,深得瓊妮和雷茲的喜愛。三人見面之事,被雙親知道了。尷𠆷不已的雙親,還是表現風度,邀請保羅來家裏。聊天之間,得知茱兒想從事園藝設計,保羅請茱兒設計自家後院。幾次在保羅家工作後,茱兒和保羅情慾爆發,每天瘋狂做愛。茱兒還因心虛開除了園丁。妮可眼見家人都心向保羅,自己被排除在外,決定主動示好,提議全家到保羅家做客。荒廢工作的茱兒只好拼命趕工。在保羅家,正當聊到喜愛的音樂,妮可以為自己終於可以和保羅做好朋友時,無意間發現茱兒和保羅上床。妮可回家後和茱兒攤牌,被瓊妮與雷茲聽到,從此家中陷入冷戰。茱兒得不到家人的原諒,和打算趁勢定下來成家的保羅切斷關係。瓊妮上大學前晚,保羅造訪試圖取得子女原諒,得不到正面的回應,還被妮可轟出門。保羅的造訪掀起全家人的傷痕,茱兒當全家人面前,認錯道歉。隔天送瓊妮到宿舍後,瓊妮開始想念家人,妮可與茱兒也在兒子雷茲的促合下,言歸於好。

    + +

    這是一部輕鬆的家庭喜劇。

    + +

    性福拉警報試圖去碰撞兩個禁忌:女同志伴侶中,男性的介入;和借精生子的婚姻中,孩子親生父母的介入。對借精生子的女同志家庭而言,簡直是兩件最討厭的事合而為一了。性福拉警報雖然去碰撞這兩個禁忌,卻以輕鬆詼諧的方式呈現,觀眾在心中越趨發麻的緊張感同時,劇中的角色卻又努力試圖去消除彼此的尷𠆷。到最後紙包不住火,一切攤在陽光下後,觀眾不得不去面對最糟糕的結果。這時候,再次出現的外人,即降離家的成員,使得家庭成員的連繫力量適時出現,把彼此的手再次牽起來。

    + +

    藉由這部電影,導演莉莎蔻洛丹柯試圖將女同志家庭,推入主流社會的家庭價值核心中。有別於前一部電影高檔貨 High Art中,情慾脫軌地竄動,性福拉警報一開始,女同志家庭就高調地出現,和異性戀家庭沒有兩樣,直接融入主流中產階級生活方式的核心中,相愛的雙親和一對子女,彷彿就是那麼自然。即使經歷了使家庭瀕臨破裂的外遇,但最後親情的召喚,還是讓家人團結在一起。這一切,也和異性戀家庭喜劇的結局相同。於是,同志家庭不論是開始或結束,都和異性戀家庭一樣,受到家庭價值的感召與制約,融為一體。導演巧妙地藉由這部電影,讓同志家庭,成為主流社會價值的一份子,讓不論是異性戀或同性戀觀眾,都接受得如此自然。

    + +

    至於現實生活呢?現實生活中,外遇的結果,不一定能夠有這麼完美的結局。畢竟這是電影,是喜劇。但是,性福拉警報還是給同志家庭,帶來正面的想像:同志家庭,和一般的家庭,其實也沒有什麼兩樣。就同志家庭和異性戀家庭其實沒什麼兩樣這個層次而言,它呈現的又是真實,而不是想像。

    + +

    導演安排所有事件,發生在女兒瓊妮要離家上大學前的一個月內。因為家庭成員離開的時限壓力,而觸發了這一連串的事件(弟弟想趁姊姊離開前見生父),也因為家庭成員離開的時限,為所有事件劃下一個必然的停止點。這樣的架構技巧,也是很有趣的。

    + +

    這次因為同志家庭權益促進會與電影公司合作的關係,得以參加試映會。謝謝同家會,也謝謝電影公司。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 160 | + 161 | + 162 | + 163 | + 164 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0163.html.en.html b/htdocs/imacat/me/diary/0163.html.en.html new file mode 120000 index 0000000..770daf6 --- /dev/null +++ b/htdocs/imacat/me/diary/0163.html.en.html @@ -0,0 +1 @@ +0163.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0163.html.en.xhtml b/htdocs/imacat/me/diary/0163.html.en.xhtml new file mode 100644 index 0000000..84e29f7 --- /dev/null +++ b/htdocs/imacat/me/diary/0163.html.en.xhtml @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 163 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 163

    + +
    + +
    + +
    +
    12.3.’10. 10:14am.
    + +

    清濤命理的蔡東楓騙財騙色被抓了

    + +

    清濤命理的蔡東楓,終於因為騙財騙色被抓了,大快人心。我最痛恨的就是濫發廣告垃圾信。就不要給我遇到。2002年左右起,女聲和旅舍依瑪的留言板,就常常接到清濤命理的廣告留言,履刪不去。連上去想抗議,發現已經有很多人抗議了,站方通通推說是被人惡意操作哉贓。非常惡質。用擋留言規則擋掉後,還企圖繞過擋留言規則來張貼。當時還留下擋清濤留言公告。真是太讓人生氣了!

    + +

    往前一查,清濤蔡東楓2007年竟然還在別人的留言板,因為垃圾廣告留言被刪,竟然恐嚇人家站長新聞存檔)。蔡東楓這個人怎麼這麼無恥啊?

    + +

    騙財騙色的清濤命理蔡東楓相關連結:

    + + + +
    +
    自由時報社會版 2010-12-03
    + +

    解符騙財解毒騙色 女子1年被拐500萬

    + +

    女子控蔡東楓騙財色

    + +

    〔記者楊政郡/台中報導〕一女子身體不適,上網找到命理師蔡東楓,蔡竟佯稱她被下符,要求女子每週付5萬8000元解符,還得與他性交解毒,每次12萬元,一年多來人財兩失,共被詐走500多萬元。

    + +

    蔡嫌自稱開辦多個靈異節目,與白冰冰、澎恰恰等知名藝人合作過,他在北縣汐止市設立神壇、網路上成立清濤命理五術研究中心

    + +

    檢警指出,台中市一名未婚女子指控,去年4月間因身體長期欠佳,透過網路得知蔡嫌有能力幫人處理,於是和媽媽北上求助蔡東楓,蔡說她遭人下惡毒符咒,陽氣微弱、生命不保,解符費每次約5萬8000元,幾乎每週一次,每次都有藉口。

    + +
    + +

    男女交媾解毒 1次12萬

    + +

    更離譜的是,蔡某稱女子中毒已深,必須盡快男女交媾解毒,還要付他解毒費一次12萬元,蔡嫌一再恐嚇女子,強調如果不趕快完全解符,她活不過12月底,女子實在很害怕,一年多來付出500多萬元,錢都被騙光了,只好報警處理。

    + +

    檢警昨日到蔡某位於汐止市神壇查扣大批符、法印、帳戶等,帶回蔡某夫妻,蔡某坦承向該女子收錢,但供稱是他應得的,否認詐欺;妨害性自主部分,蔡則稱是女子自願。

    + +

    檢方認為,蔡某藉由神壇、符術而行詐財騙色,罪證明確,聲押獲准,蔡妻周倩如則被限制住居。

    + +

    檢方強調,該被害女子在配合偵辦期間,曾說她生辰八字還在蔡某手上,她好像快死了;不少民眾也PO文表示,遭蔡某詐財騙色。檢方決定以行動破除迷信,希望其他被害人向台中市警局婦幼隊聯繫,電話(04)2327-7772。

    + +

    性交驅邪 迷信母推女入狼室
    命理師燒一張符騙5萬 性侵後再索12萬

    + +

    【鄧玉瑩╱台中報導】北縣命理師蔡東楓聲稱會化解嬰靈厄運,為一名女子驅邪燒一張符五萬元,更恫嚇:這個劫再不解,妳就會死!騙女子與他陰陽合體、雙修驅邪,涉嫌多次性侵女子,每次還向她的母親收費十二萬元,共騙四百萬元。台中地檢署女檢察官與女警前天假扮客人找蔡算命,拘提蔡後向法院聲請羈押獲准。

    + +

    裝神弄鬼

    + +

    台中地檢署襄閱主任檢察官吳祚延表示,蔡在網路上打廣告宣傳,自稱與多名藝人有交情以取信民眾,呼籲其他被害人出面指證,電話是台中市警婦幼隊(04)2327-7772或0939-899-585。 +一年多得手400多萬

    + +

    台中市警婦幼隊接獲報案,指一名未婚女子(三十一歲)長期頭昏、全身不適,求醫不癒,去年四月與母親到台北縣汐止市找蔡算命。第一次諮詢收費八千元,蔡告訴女子身邊有嬰靈,須作法解厄運,蔡燒了一張符咒,收費五萬元。女子返家,果然精神轉好。後來女子病情復發,兩眼翻白、全身抽搐,和母親再去找蔡。蔡稱嬰靈兇惡,須男女性交,借助神力才能化解,收費十二萬元。女子猶豫不決,但她母親相信蔡的療法,竟將女兒推進入蔡的密室,讓女兒與蔡性交。女子因此多次與蔡發生性關係,共花了四百萬元。上個月,蔡貪得無厭,竟要求母女給兩百萬元治療費,女子的母親才驚覺受騙,報警偵辦。最近,這名女子病情復發嚴重,她的母親想再找蔡治療,台中檢警才提前行動。本月一日,女檢察官洪淑姿和婦幼隊女警假扮客人,到汐止市神壇找蔡諮詢化解嬰靈的事。蔡隨即將女警帶進密室會談,女檢察官在外等候。女警在密室確認蔡的身分及掌握現場狀況後,通知守在神壇外的警員進入神壇逮捕蔡東楓,搜索神壇和他的住家查扣大批客戶名單帳冊、符紙、法器。

    + +

    騙財騙色昨遭收押

    + +

    檢方偵訊時蔡妻否認涉案,供稱僅幫忙蔡接聽電話;蔡承認為該女子燒符解厄運,否認性侵女子,但檢察官認為他涉嫌以化解厄運為藉口性侵女子並詐財,昨向法院聲請羈押獲准。命理師江柏樂表示,所有的正神都不會要求身體接觸,其實神棍也知道這點,所以他們會循序漸進,先取得被害人信任再誘騙得逞。他建議,民眾諸事不順想求神,應去大廟許願,切勿找旁門左道化解厄運。

    + +

    命理師詐財騙色示意圖

    + +
      +
    1. 蔡東楓聲稱女子身旁有嬰靈,念咒又燒了一張符,向女子和其母親收費5萬元。
    2. + +
    3. 蔡男誆稱嬰靈兇惡,須男女性交,借助神力才能化解,媽媽竟相信他的說法,將女兒推進密室。
    4. +
    + +

    誆改運性侵案例

    + +
      +
    • 2010/10/30:台北縣市場攤販郭貴振,向女保險業務員謊稱她是他的前世的老婆,有女鬼跑進她下體,用手指插入女保險業務員下體2次把鬼捉出來改運,被板橋地院依強制性交罪判郭男7年徒刑。
    • + +
    • 2010/03/11:神棍高健銘要求自認卡到陰的18歲少女脫衣讓他淨身驅邪,藉機性侵少女得逞,被依強制性交等罪嫌起訴。
    • + +
    • 2010/03/09:北縣羅姓姊妹因失業求改運,神棍林銘海假稱濟公附身降諭借身體辦法事制煞,在汽車旅館性侵妹妹,林被依強制性交罪嫌起訴。
    • + +
    • 2009/10/02:台南縣高職數學老師藉口幫女學生消災解厄,先後帶9名女學生到賓館性侵拍裸照,被台南地院判處28年徒刑。
    • +
    + +

    資料來源:《蘋果》資料室

    + +
    + + +
    +
    聯合報社會新聞 2010-12-03
    + +

    涉騙財色 命理師蔡東楓收押

    + +
    【聯合報╱記者白錫鏗/台中報導】
    + +

    自稱是第一個開創台灣靈異節目的命理師蔡東楓,在網路成立命理五術研究中心,強調專門為人處理嬰靈、解陰煞等,向被害女子謊稱遭人下死符、已中毒,涉嫌向被害人詐財400餘萬,並以陰陽合體解毒為由性侵害,檢察官昨訊後向法院聲押獲准,蔡妻周倩如被限制住居。

    + +

    蔡東楓(46歲)曾在多家電視台主持靈異節目,與多名藝人合作過。檢警查出,蔡嫌光是諮詢即收費1000元,引渡嬰靈收費8000元、作法收費3萬至6萬元。

    + +

    檢警說,未婚的被害女子因身體健康不好,上網見到蔡東楓架設的命理網站後,去年4、5月間,由媽媽陪同前往相命,蔡嫌向被害人佯稱遭人下死符,並稱她的陽氣微弱,身體已中毒,如未經他解符、或陰陽合體解毒,被害人恐將暴斃死亡。

    + +

    被害人從去年5月起,至今年11月下旬,先後到台北縣汐止市蔡東楓的神壇近百次,平均每個月4、5次,由蔡嫌為被害女子作法、解符、蓄魂儀式,甚至還有數次性侵陰陽合體解毒,還付了400餘萬元。

    + +

    數月前,蔡嫌向被害女子佯稱要一次給付更多的款項,否則會在年底前暴斃,嚇得被害人終日不安,身體健康一天比一天差,雖懷疑遭騙財騙色,決定揪出騙財騙色的大神棍。

    + +

    檢察官昨指揮台中市警察局刑警大隊及婦幼隊員警,前往台北縣汐止市蔡嫌營業的神壇、台北市內湖區蔡嫌住處搜索,查扣上千名客戶名冊、符咒、法印等物。

    + +

    檢察官傳訊蔡東楓、周倩如夫婦到案,蔡嫌否認一切犯行;至於周倩如僅是負責接聽電話、安排蔡嫌行程,裁定限制住居。

    + +
    + + +
    +
    中國時報社會新聞 2010-12-03
    + +

    靈異蔡東楓 鬼話騙財色收押

    + +
    【陳界良/台中報導】
    + +

    自稱製作台灣第一個靈異節目的蔡東楓,在網路設命理研究中心,為人處理嬰靈等問題。一名女子因身體不適向他求助,蔡以她遭人下符、即將暴斃為名,涉嫌騙走四百多萬元,並與她發生性關係。台中地檢署昨天將蔡東楓逮捕,並聲押獲准。檢警認為受害者當不止一人,正積極擴大偵辦。

    + +

    檢方偵訊時,蔡東楓雖承認向民眾收費,但認為那是自己應得的報酬,否認騙財騙色。訊後依詐欺、妨害性自主等罪嫌移送並聲押獲准。她的妻子周倩如訊後限制住居。

    + +

    台中地檢署一日指揮台中市刑警大隊、婦幼隊北上,搜索蔡東楓位於北縣汐止市的神壇及台北市內湖區住處,將蔡東楓與妻子周倩如帶回偵訊,並查扣各種符與法印等證物及千筆客戶資料。

    + +

    檢方調查,四十六歲蔡東楓在網路上成立清濤命理五術研究中心,標榜為人處理嬰靈、挽回夫妻、男女感情與解陰煞等問題;台中一名未婚女子因健康欠佳,日前透過網路找上蔡東楓,蔡謊稱她遭人下符,陽氣微弱,身體已中毒,即將暴斃死亡。

    + +

    去年五月起,蔡東楓涉嫌以做法解咒為由,每次向被害女子收取五萬八千元,約每周做一次;另以解毒為由,要求女子與他發生性關係,每次索費十二萬元,女子先後被騙走四百多萬元,蔡最後還要求女子支付一筆鉅款,女子才發覺有異,向警方報案求救。

    + +

    蔡在Facebook自我介紹指出,我以前是靈異節目老師,第一個靈異節目是我做的,第一個合作藝人是白冰冰,合作最久的是馬世莉;還有澎洽洽、賀一航、席曼寧、甄莉、文英阿姨與秦偉等,不勝枚舉。有關嬰靈,感情挽回方面的問題,請盡量到我的官網詢問…

    + +

    還宣稱最巔峰時,同時做八個靈異節目,記錄目前無人能破。也曾擔任〈膽大包天〉、〈穿梭陰陽界〉、〈星期天怕怕〉、〈鬼話連篇〉及〈神出鬼沒〉等節目的主持人或顧問,幫過許多知名藝人、政商名流處理棘手問題。

    + +

    檢方調查,蔡也出過靈異相關書籍。民眾問事須付一千元諮詢費,蔡則乘機介紹服務項目。價碼為處理嬰靈八千元,感情和合上萬元,加強桃花等感情問題甚至要數萬元。

    + +

    檢方並發現,網路上也有網友指責蔡東楓涉嫌騙財騙色,認為應還有其他被害人。但被害人大都因生辰八字落在蔡的手裡,怕被下符、下死咒,擔心會死掉,因而不敢報案。檢方希望透過具體的搜索、拘捕行動,破除被害人疑慮,勇敢出面指證。

    + +
    + + +
    +
    聯合報社會新聞 2007-09-28
    + +

    網上貼廣告被刪 命理師恐嚇版主

    + +
    【聯合報╱記者廖炳棋/台北報導】
    + +

    自稱是第一個開創台灣靈異節目的命理師蔡東楓,因在網站上張貼命理廣告遭刪除,涉嫌恐嚇版主知名投資分析人朱岳中,警方調查後,將蔡東楓依恐嚇罪嫌函送地檢署偵辦。

    + +

    開設清濤命理五術研究中心的蔡東楓(41歲),在個人網站上自稱是中華民國星象學會永久榮譽會員,並歷任東森、三立、八大等電視台靈異節目的主持人及講解老師,曾經合作的對象包括白冰冰、澎恰恰、馬世莉等藝人;網站中還強調專長處理嬰靈、男女感情和合及婚姻外遇。

    + +

    今年八月初,蔡東楓在奇摩網站無責任投資論壇上,以暱稱fdsa414141留言,恐嚇將在網聚時叫人修理版主,還說不要問他理由,總之網聚當天,版主要有心理準備,到時兩人再好好認識一下!

    + +

    無責任投資論壇的版主是南台大學財務金融系專任講師朱岳中,曾多次接受商業雜誌專訪,論文並得到國科會獎勵,他每天都在網站上發表關於金融及投資分析等方面文章,平均每天高達近萬名網友閱覽。由於蔡嫌留言恐嚇的時間,正是朱岳中準備要和高雄網友聚會前夕,因此立刻引起網友恐慌,朱岳中也馬上報警處理。

    + +

    警方追查電腦記錄,發現留言恐嚇的人就是蔡東楓,曾在無責任投資論壇網站張貼命理廣告;但朱岳中認為蔡沒有經過他同意,加上命理廣告和網站調性不合,因此以版主權限刪除廣告,想不到蔡嫌因此心生不滿,才會留言恐嚇。

    + +

    警方約談蔡嫌,他表示並不認識被害人,也沒有糾紛,會留言恐嚇只是因為他也想參加網聚,所以才留言開版主和網友的玩笑。儘管他表示沒有恐嚇犯意,仍依恐嚇罪嫌將他函送法辦。

    + +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 161 | + 162 | + 163 | + 164 | + 165 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0163.html.zh-cn.html b/htdocs/imacat/me/diary/0163.html.zh-cn.html new file mode 120000 index 0000000..b12474e --- /dev/null +++ b/htdocs/imacat/me/diary/0163.html.zh-cn.html @@ -0,0 +1 @@ +0163.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0163.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0163.html.zh-cn.xhtml new file mode 100644 index 0000000..c08677f --- /dev/null +++ b/htdocs/imacat/me/diary/0163.html.zh-cn.xhtml @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百六十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百六十三

    + +
    + +
    + +
    +
    12.3.’10. 10:14am.
    + +

    清涛命理的蔡东枫骗财骗色被抓了

    + +

    清涛命理的蔡东枫,终於因为骗财骗色被抓了,大快人心。我最痛恨的就是滥发广告垃圾信。就不要给我遇到。2002年左右起,女声和旅舍依玛的留言板,就常常接到清涛命理的广告留言,履删不去。连上去想抗议,发现已经有很多人抗议了,站方通通推说是被人恶意操作哉赃。非常恶质。用挡留言规则挡掉后,还企图绕过挡留言规则来张贴。当时还留下挡清涛留言公告。真是太让人生气了!

    + +

    往前一查,清涛蔡东枫2007年竟然还在别人的留言板,因为垃圾广告留言被删,竟然恐吓人家站长新闻存档)。蔡东枫这个人怎么这么无耻啊?

    + +

    骗财骗色的清涛命理蔡东枫相关连结:

    + + + +
    +
    自由时报社会版 2010-12-03
    + +

    解符骗财解毒骗色 女子1年被拐500万

    + +

    女子控蔡东枫骗财色

    + +

    〔记者杨政郡/台中报导〕一女子身体不适,上网找到命理师蔡东枫,蔡竟佯称她被下符,要求女子每周付5万8000元解符,还得与他性交解毒,每次12万元,一年多来人财两失,共被诈走500多万元。

    + +

    蔡嫌自称开办多个灵异节目,与白冰冰、澎恰恰等知名艺人合作过,他在北县汐止市设立神坛、网路上成立清涛命理五术研究中心

    + +

    检警指出,台中市一名未婚女子指控,去年4月间因身体长期欠佳,透过网路得知蔡嫌有能力帮人处理,於是和妈妈北上求助蔡东枫,蔡说她遭人下恶毒符咒,阳气微弱、生命不保,解符费每次约5万8000元,几乎每周一次,每次都有藉口。

    + +
    + +

    男女交媾解毒 1次12万

    + +

    更离谱的是,蔡某称女子中毒已深,必须尽快男女交媾解毒,还要付他解毒费一次12万元,蔡嫌一再恐吓女子,强调如果不赶快完全解符,她活不过12月底,女子实在很害怕,一年多来付出500多万元,钱都被骗光了,只好报警处理。

    + +

    检警昨日到蔡某位於汐止市神坛查扣大批符、法印、帐户等,带回蔡某夫妻,蔡某坦承向该女子收钱,但供称是他应得的,否认诈欺;妨害性自主部分,蔡则称是女子自愿。

    + +

    检方认为,蔡某藉由神坛、符术而行诈财骗色,罪证明确,声押获准,蔡妻周倩如则被限制住居。

    + +

    检方强调,该被害女子在配合侦办期间,曾说她生辰八字还在蔡某手上,她好像快死了;不少民众也PO文表示,遭蔡某诈财骗色。检方决定以行动破除迷信,希望其他被害人向台中市警局妇幼队联系,电话(04)2327-7772。

    + +

    性交驱邪 迷信母推女入狼室
    命理师烧一张符骗5万 性侵后再索12万

    + +

    【邓玉莹/台中报导】北县命理师蔡东枫声称会化解婴灵厄运,为一名女子驱邪烧一张符五万元,更恫吓:这个劫再不解,你就会死!骗女子与他阴阳合体、双修驱邪,涉嫌多次性侵女子,每次还向她的母亲收费十二万元,共骗四百万元。台中地检署女检察官与女警前天假扮客人找蔡算命,拘提蔡后向法院声请羁押获准。

    + +

    装神弄鬼

    + +

    台中地检署襄阅主任检察官吴祚延表示,蔡在网路上打广告宣传,自称与多名艺人有交情以取信民众,呼吁其他被害人出面指证,电话是台中市警妇幼队(04)2327-7772或0939-899-585。 +一年多得手400多万

    + +

    台中市警妇幼队接获报案,指一名未婚女子(三十一岁)长期头昏、全身不适,求医不愈,去年四月与母亲到台北县汐止市找蔡算命。第一次谘询收费八千元,蔡告诉女子身边有婴灵,须作法解厄运,蔡烧了一张符咒,收费五万元。女子返家,果然精神转好。后来女子病情复发,两眼翻白、全身抽搐,和母亲再去找蔡。蔡称婴灵凶恶,须男女性交,借助神力才能化解,收费十二万元。女子犹豫不决,但她母亲相信蔡的疗法,竟将女儿推进入蔡的密室,让女儿与蔡性交。女子因此多次与蔡发生性关系,共花了四百万元。上个月,蔡贪得无厌,竟要求母女给两百万元治疗费,女子的母亲才惊觉受骗,报警侦办。最近,这名女子病情复发严重,她的母亲想再找蔡治疗,台中检警才提前行动。本月一日,女检察官洪淑姿和妇幼队女警假扮客人,到汐止市神坛找蔡谘询化解婴灵的事。蔡随即将女警带进密室会谈,女检察官在外等候。女警在密室确认蔡的身分及掌握现场状况后,通知守在神坛外的警员进入神坛逮捕蔡东枫,搜索神坛和他的住家查扣大批客户名单帐册、符纸、法器。

    + +

    骗财骗色昨遭收押

    + +

    检方侦讯时蔡妻否认涉案,供称仅帮忙蔡接听电话;蔡承认为该女子烧符解厄运,否认性侵女子,但检察官认为他涉嫌以化解厄运为藉口性侵女子并诈财,昨向法院声请羁押获准。命理师江柏乐表示,所有的正神都不会要求身体接触,其实神棍也知道这点,所以他们会循序渐进,先取得被害人信任再诱骗得逞。他建议,民众诸事不顺想求神,应去大庙许愿,切勿找旁门左道化解厄运。

    + +

    命理师诈财骗色示意图

    + +
      +
    1. 蔡东枫声称女子身旁有婴灵,念咒又烧了一张符,向女子和其母亲收费5万元。
    2. + +
    3. 蔡男诓称婴灵凶恶,须男女性交,借助神力才能化解,妈妈竟相信他的说法,将女儿推进密室。
    4. +
    + +

    诓改运性侵案例

    + +
      +
    • 2010/10/30:台北县市场摊贩郭贵振,向女保险业务员谎称她是他的前世的老婆,有女鬼跑进她下体,用手指插入女保险业务员下体2次把鬼捉出来改运,被板桥地院依强制性交罪判郭男7年徒刑。
    • + +
    • 2010/03/11:神棍高健铭要求自认卡到阴的18岁少女脱衣让他净身驱邪,藉机性侵少女得逞,被依强制性交等罪嫌起诉。
    • + +
    • 2010/03/09:北县罗姓姊妹因失业求改运,神棍林铭海假称济公附身降谕借身体办法事制煞,在汽车旅馆性侵妹妹,林被依强制性交罪嫌起诉。
    • + +
    • 2009/10/02:台南县高职数学老师藉口帮女学生消灾解厄,先后带9名女学生到宾馆性侵拍裸照,被台南地院判处28年徒刑。
    • +
    + +

    资料来源:《苹果》资料室

    + +
    + + +
    +
    联合报社会新闻 2010-12-03
    + +

    涉骗财色 命理师蔡东枫收押

    + +
    【联合报/记者白锡铿/台中报导】
    + +

    自称是第一个开创台湾灵异节目的命理师蔡东枫,在网路成立命理五术研究中心,强调专门为人处理婴灵、解阴煞等,向被害女子谎称遭人下死符、已中毒,涉嫌向被害人诈财400余万,并以阴阳合体解毒为由性侵害,检察官昨讯后向法院声押获准,蔡妻周倩如被限制住居。

    + +

    蔡东枫(46岁)曾在多家电视台主持灵异节目,与多名艺人合作过。检警查出,蔡嫌光是谘询即收费1000元,引渡婴灵收费8000元、作法收费3万至6万元。

    + +

    检警说,未婚的被害女子因身体健康不好,上网见到蔡东枫架设的命理网站后,去年4、5月间,由妈妈陪同前往相命,蔡嫌向被害人佯称遭人下死符,并称她的阳气微弱,身体已中毒,如未经他解符、或阴阳合体解毒,被害人恐将暴毙死亡。

    + +

    被害人从去年5月起,至今年11月下旬,先后到台北县汐止市蔡东枫的神坛近百次,平均每个月4、5次,由蔡嫌为被害女子作法、解符、蓄魂仪式,甚至还有数次性侵阴阳合体解毒,还付了400余万元。

    + +

    数月前,蔡嫌向被害女子佯称要一次给付更多的款项,否则会在年底前暴毙,吓得被害人终日不安,身体健康一天比一天差,虽怀疑遭骗财骗色,决定揪出骗财骗色的大神棍。

    + +

    检察官昨指挥台中市警察局刑警大队及妇幼队员警,前往台北县汐止市蔡嫌营业的神坛、台北市内湖区蔡嫌住处搜索,查扣上千名客户名册、符咒、法印等物。

    + +

    检察官传讯蔡东枫、周倩如夫妇到案,蔡嫌否认一切犯行;至於周倩如仅是负责接听电话、安排蔡嫌行程,裁定限制住居。

    + +
    + + +
    +
    中国时报社会新闻 2010-12-03
    + +

    灵异蔡东枫 鬼话骗财色收押

    + +
    【陈界良/台中报导】
    + +

    自称制作台湾第一个灵异节目的蔡东枫,在网路设命理研究中心,为人处理婴灵等问题。一名女子因身体不适向他求助,蔡以她遭人下符、即将暴毙为名,涉嫌骗走四百多万元,并与她发生性关系。台中地检署昨天将蔡东枫逮捕,并声押获准。检警认为受害者当不止一人,正积极扩大侦办。

    + +

    检方侦讯时,蔡东枫虽承认向民众收费,但认为那是自己应得的报酬,否认骗财骗色。讯后依诈欺、妨害性自主等罪嫌移送并声押获准。她的妻子周倩如讯后限制住居。

    + +

    台中地检署一日指挥台中市刑警大队、妇幼队北上,搜索蔡东枫位於北县汐止市的神坛及台北市内湖区住处,将蔡东枫与妻子周倩如带回侦讯,并查扣各种符与法印等证物及千笔客户资料。

    + +

    检方调查,四十六岁蔡东枫在网路上成立清涛命理五术研究中心,标榜为人处理婴灵、挽回夫妻、男女感情与解阴煞等问题;台中一名未婚女子因健康欠佳,日前透过网路找上蔡东枫,蔡谎称她遭人下符,阳气微弱,身体已中毒,即将暴毙死亡。

    + +

    去年五月起,蔡东枫涉嫌以做法解咒为由,每次向被害女子收取五万八千元,约每周做一次;另以解毒为由,要求女子与他发生性关系,每次索费十二万元,女子先后被骗走四百多万元,蔡最后还要求女子支付一笔巨款,女子才发觉有异,向警方报案求救。

    + +

    蔡在Facebook自我介绍指出,我以前是灵异节目老师,第一个灵异节目是我做的,第一个合作艺人是白冰冰,合作最久的是马世莉;还有澎洽洽、贺一航、席曼宁、甄莉、文英阿姨与秦伟等,不胜枚举。有关婴灵,感情挽回方面的问题,请尽量到我的官网询问…

    + +

    还宣称最巅峰时,同时做八个灵异节目,记录目前无人能破。也曾担任〈胆大包天〉、〈穿梭阴阳界〉、〈星期天怕怕〉、〈鬼话连篇〉及〈神出鬼没〉等节目的主持人或顾问,帮过许多知名艺人、政商名流处理棘手问题。

    + +

    检方调查,蔡也出过灵异相关书籍。民众问事须付一千元谘询费,蔡则乘机介绍服务项目。价码为处理婴灵八千元,感情和合上万元,加强桃花等感情问题甚至要数万元。

    + +

    检方并发现,网路上也有网友指责蔡东枫涉嫌骗财骗色,认为应还有其他被害人。但被害人大都因生辰八字落在蔡的手里,怕被下符、下死咒,担心会死掉,因而不敢报案。检方希望透过具体的搜索、拘捕行动,破除被害人疑虑,勇敢出面指证。

    + +
    + + +
    +
    联合报社会新闻 2007-09-28
    + +

    网上贴广告被删 命理师恐吓版主

    + +
    【联合报/记者廖炳棋/台北报导】
    + +

    自称是第一个开创台湾灵异节目的命理师蔡东枫,因在网站上张贴命理广告遭删除,涉嫌恐吓版主知名投资分析人朱岳中,警方调查后,将蔡东枫依恐吓罪嫌函送地检署侦办。

    + +

    开设清涛命理五术研究中心的蔡东枫(41岁),在个人网站上自称是中华民国星象学会永久荣誉会员,并历任东森、三立、八大等电视台灵异节目的主持人及讲解老师,曾经合作的对象包括白冰冰、澎恰恰、马世莉等艺人;网站中还强调专长处理婴灵、男女感情和合及婚姻外遇。

    + +

    今年八月初,蔡东枫在奇摩网站无责任投资论坛上,以昵称fdsa414141留言,恐吓将在网聚时叫人修理版主,还说不要问他理由,总之网聚当天,版主要有心理准备,到时两人再好好认识一下!

    + +

    无责任投资论坛的版主是南台大学财务金融系专任讲师朱岳中,曾多次接受商业杂志专访,论文并得到国科会奖励,他每天都在网站上发表关於金融及投资分析等方面文章,平均每天高达近万名网友阅览。由於蔡嫌留言恐吓的时间,正是朱岳中准备要和高雄网友聚会前夕,因此立刻引起网友恐慌,朱岳中也马上报警处理。

    + +

    警方追查电脑记录,发现留言恐吓的人就是蔡东枫,曾在无责任投资论坛网站张贴命理广告;但朱岳中认为蔡没有经过他同意,加上命理广告和网站调性不合,因此以版主权限删除广告,想不到蔡嫌因此心生不满,才会留言恐吓。

    + +

    警方约谈蔡嫌,他表示并不认识被害人,也没有纠纷,会留言恐吓只是因为他也想参加网聚,所以才留言开版主和网友的玩笑。尽管他表示没有恐吓犯意,仍依恐吓罪嫌将他函送法办。

    + +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 161 | + 162 | + 163 | + 164 | + 165 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0163.html.zh-tw.html b/htdocs/imacat/me/diary/0163.html.zh-tw.html new file mode 120000 index 0000000..0cba9ea --- /dev/null +++ b/htdocs/imacat/me/diary/0163.html.zh-tw.html @@ -0,0 +1 @@ +0163.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0163.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0163.html.zh-tw.xhtml new file mode 100644 index 0000000..ae2fe13 --- /dev/null +++ b/htdocs/imacat/me/diary/0163.html.zh-tw.xhtml @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百六十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百六十三

    + +
    + +
    + +
    +
    12.3.’10. 10:14am.
    + +

    清濤命理的蔡東楓騙財騙色被抓了

    + +

    清濤命理的蔡東楓,終於因為騙財騙色被抓了,大快人心。我最痛恨的就是濫發廣告垃圾信。就不要給我遇到。2002年左右起,女聲和旅舍依瑪的留言板,就常常接到清濤命理的廣告留言,履刪不去。連上去想抗議,發現已經有很多人抗議了,站方通通推說是被人惡意操作哉贓。非常惡質。用擋留言規則擋掉後,還企圖繞過擋留言規則來張貼。當時還留下擋清濤留言公告。真是太讓人生氣了!

    + +

    往前一查,清濤蔡東楓2007年竟然還在別人的留言板,因為垃圾廣告留言被刪,竟然恐嚇人家站長新聞存檔)。蔡東楓這個人怎麼這麼無恥啊?

    + +

    騙財騙色的清濤命理蔡東楓相關連結:

    + + + +
    +
    自由時報社會版 2010-12-03
    + +

    解符騙財解毒騙色 女子1年被拐500萬

    + +

    女子控蔡東楓騙財色

    + +

    〔記者楊政郡/台中報導〕一女子身體不適,上網找到命理師蔡東楓,蔡竟佯稱她被下符,要求女子每週付5萬8000元解符,還得與他性交解毒,每次12萬元,一年多來人財兩失,共被詐走500多萬元。

    + +

    蔡嫌自稱開辦多個靈異節目,與白冰冰、澎恰恰等知名藝人合作過,他在北縣汐止市設立神壇、網路上成立清濤命理五術研究中心

    + +

    檢警指出,台中市一名未婚女子指控,去年4月間因身體長期欠佳,透過網路得知蔡嫌有能力幫人處理,於是和媽媽北上求助蔡東楓,蔡說她遭人下惡毒符咒,陽氣微弱、生命不保,解符費每次約5萬8000元,幾乎每週一次,每次都有藉口。

    + +
    + +

    男女交媾解毒 1次12萬

    + +

    更離譜的是,蔡某稱女子中毒已深,必須盡快男女交媾解毒,還要付他解毒費一次12萬元,蔡嫌一再恐嚇女子,強調如果不趕快完全解符,她活不過12月底,女子實在很害怕,一年多來付出500多萬元,錢都被騙光了,只好報警處理。

    + +

    檢警昨日到蔡某位於汐止市神壇查扣大批符、法印、帳戶等,帶回蔡某夫妻,蔡某坦承向該女子收錢,但供稱是他應得的,否認詐欺;妨害性自主部分,蔡則稱是女子自願。

    + +

    檢方認為,蔡某藉由神壇、符術而行詐財騙色,罪證明確,聲押獲准,蔡妻周倩如則被限制住居。

    + +

    檢方強調,該被害女子在配合偵辦期間,曾說她生辰八字還在蔡某手上,她好像快死了;不少民眾也PO文表示,遭蔡某詐財騙色。檢方決定以行動破除迷信,希望其他被害人向台中市警局婦幼隊聯繫,電話(04)2327-7772。

    + +

    性交驅邪 迷信母推女入狼室
    命理師燒一張符騙5萬 性侵後再索12萬

    + +

    【鄧玉瑩╱台中報導】北縣命理師蔡東楓聲稱會化解嬰靈厄運,為一名女子驅邪燒一張符五萬元,更恫嚇:這個劫再不解,妳就會死!騙女子與他陰陽合體、雙修驅邪,涉嫌多次性侵女子,每次還向她的母親收費十二萬元,共騙四百萬元。台中地檢署女檢察官與女警前天假扮客人找蔡算命,拘提蔡後向法院聲請羈押獲准。

    + +

    裝神弄鬼

    + +

    台中地檢署襄閱主任檢察官吳祚延表示,蔡在網路上打廣告宣傳,自稱與多名藝人有交情以取信民眾,呼籲其他被害人出面指證,電話是台中市警婦幼隊(04)2327-7772或0939-899-585。 +一年多得手400多萬

    + +

    台中市警婦幼隊接獲報案,指一名未婚女子(三十一歲)長期頭昏、全身不適,求醫不癒,去年四月與母親到台北縣汐止市找蔡算命。第一次諮詢收費八千元,蔡告訴女子身邊有嬰靈,須作法解厄運,蔡燒了一張符咒,收費五萬元。女子返家,果然精神轉好。後來女子病情復發,兩眼翻白、全身抽搐,和母親再去找蔡。蔡稱嬰靈兇惡,須男女性交,借助神力才能化解,收費十二萬元。女子猶豫不決,但她母親相信蔡的療法,竟將女兒推進入蔡的密室,讓女兒與蔡性交。女子因此多次與蔡發生性關係,共花了四百萬元。上個月,蔡貪得無厭,竟要求母女給兩百萬元治療費,女子的母親才驚覺受騙,報警偵辦。最近,這名女子病情復發嚴重,她的母親想再找蔡治療,台中檢警才提前行動。本月一日,女檢察官洪淑姿和婦幼隊女警假扮客人,到汐止市神壇找蔡諮詢化解嬰靈的事。蔡隨即將女警帶進密室會談,女檢察官在外等候。女警在密室確認蔡的身分及掌握現場狀況後,通知守在神壇外的警員進入神壇逮捕蔡東楓,搜索神壇和他的住家查扣大批客戶名單帳冊、符紙、法器。

    + +

    騙財騙色昨遭收押

    + +

    檢方偵訊時蔡妻否認涉案,供稱僅幫忙蔡接聽電話;蔡承認為該女子燒符解厄運,否認性侵女子,但檢察官認為他涉嫌以化解厄運為藉口性侵女子並詐財,昨向法院聲請羈押獲准。命理師江柏樂表示,所有的正神都不會要求身體接觸,其實神棍也知道這點,所以他們會循序漸進,先取得被害人信任再誘騙得逞。他建議,民眾諸事不順想求神,應去大廟許願,切勿找旁門左道化解厄運。

    + +

    命理師詐財騙色示意圖

    + +
      +
    1. 蔡東楓聲稱女子身旁有嬰靈,念咒又燒了一張符,向女子和其母親收費5萬元。
    2. + +
    3. 蔡男誆稱嬰靈兇惡,須男女性交,借助神力才能化解,媽媽竟相信他的說法,將女兒推進密室。
    4. +
    + +

    誆改運性侵案例

    + +
      +
    • 2010/10/30:台北縣市場攤販郭貴振,向女保險業務員謊稱她是他的前世的老婆,有女鬼跑進她下體,用手指插入女保險業務員下體2次把鬼捉出來改運,被板橋地院依強制性交罪判郭男7年徒刑。
    • + +
    • 2010/03/11:神棍高健銘要求自認卡到陰的18歲少女脫衣讓他淨身驅邪,藉機性侵少女得逞,被依強制性交等罪嫌起訴。
    • + +
    • 2010/03/09:北縣羅姓姊妹因失業求改運,神棍林銘海假稱濟公附身降諭借身體辦法事制煞,在汽車旅館性侵妹妹,林被依強制性交罪嫌起訴。
    • + +
    • 2009/10/02:台南縣高職數學老師藉口幫女學生消災解厄,先後帶9名女學生到賓館性侵拍裸照,被台南地院判處28年徒刑。
    • +
    + +

    資料來源:《蘋果》資料室

    + +
    + + +
    +
    聯合報社會新聞 2010-12-03
    + +

    涉騙財色 命理師蔡東楓收押

    + +
    【聯合報╱記者白錫鏗/台中報導】
    + +

    自稱是第一個開創台灣靈異節目的命理師蔡東楓,在網路成立命理五術研究中心,強調專門為人處理嬰靈、解陰煞等,向被害女子謊稱遭人下死符、已中毒,涉嫌向被害人詐財400餘萬,並以陰陽合體解毒為由性侵害,檢察官昨訊後向法院聲押獲准,蔡妻周倩如被限制住居。

    + +

    蔡東楓(46歲)曾在多家電視台主持靈異節目,與多名藝人合作過。檢警查出,蔡嫌光是諮詢即收費1000元,引渡嬰靈收費8000元、作法收費3萬至6萬元。

    + +

    檢警說,未婚的被害女子因身體健康不好,上網見到蔡東楓架設的命理網站後,去年4、5月間,由媽媽陪同前往相命,蔡嫌向被害人佯稱遭人下死符,並稱她的陽氣微弱,身體已中毒,如未經他解符、或陰陽合體解毒,被害人恐將暴斃死亡。

    + +

    被害人從去年5月起,至今年11月下旬,先後到台北縣汐止市蔡東楓的神壇近百次,平均每個月4、5次,由蔡嫌為被害女子作法、解符、蓄魂儀式,甚至還有數次性侵陰陽合體解毒,還付了400餘萬元。

    + +

    數月前,蔡嫌向被害女子佯稱要一次給付更多的款項,否則會在年底前暴斃,嚇得被害人終日不安,身體健康一天比一天差,雖懷疑遭騙財騙色,決定揪出騙財騙色的大神棍。

    + +

    檢察官昨指揮台中市警察局刑警大隊及婦幼隊員警,前往台北縣汐止市蔡嫌營業的神壇、台北市內湖區蔡嫌住處搜索,查扣上千名客戶名冊、符咒、法印等物。

    + +

    檢察官傳訊蔡東楓、周倩如夫婦到案,蔡嫌否認一切犯行;至於周倩如僅是負責接聽電話、安排蔡嫌行程,裁定限制住居。

    + +
    + + +
    +
    中國時報社會新聞 2010-12-03
    + +

    靈異蔡東楓 鬼話騙財色收押

    + +
    【陳界良/台中報導】
    + +

    自稱製作台灣第一個靈異節目的蔡東楓,在網路設命理研究中心,為人處理嬰靈等問題。一名女子因身體不適向他求助,蔡以她遭人下符、即將暴斃為名,涉嫌騙走四百多萬元,並與她發生性關係。台中地檢署昨天將蔡東楓逮捕,並聲押獲准。檢警認為受害者當不止一人,正積極擴大偵辦。

    + +

    檢方偵訊時,蔡東楓雖承認向民眾收費,但認為那是自己應得的報酬,否認騙財騙色。訊後依詐欺、妨害性自主等罪嫌移送並聲押獲准。她的妻子周倩如訊後限制住居。

    + +

    台中地檢署一日指揮台中市刑警大隊、婦幼隊北上,搜索蔡東楓位於北縣汐止市的神壇及台北市內湖區住處,將蔡東楓與妻子周倩如帶回偵訊,並查扣各種符與法印等證物及千筆客戶資料。

    + +

    檢方調查,四十六歲蔡東楓在網路上成立清濤命理五術研究中心,標榜為人處理嬰靈、挽回夫妻、男女感情與解陰煞等問題;台中一名未婚女子因健康欠佳,日前透過網路找上蔡東楓,蔡謊稱她遭人下符,陽氣微弱,身體已中毒,即將暴斃死亡。

    + +

    去年五月起,蔡東楓涉嫌以做法解咒為由,每次向被害女子收取五萬八千元,約每周做一次;另以解毒為由,要求女子與他發生性關係,每次索費十二萬元,女子先後被騙走四百多萬元,蔡最後還要求女子支付一筆鉅款,女子才發覺有異,向警方報案求救。

    + +

    蔡在Facebook自我介紹指出,我以前是靈異節目老師,第一個靈異節目是我做的,第一個合作藝人是白冰冰,合作最久的是馬世莉;還有澎洽洽、賀一航、席曼寧、甄莉、文英阿姨與秦偉等,不勝枚舉。有關嬰靈,感情挽回方面的問題,請盡量到我的官網詢問…

    + +

    還宣稱最巔峰時,同時做八個靈異節目,記錄目前無人能破。也曾擔任〈膽大包天〉、〈穿梭陰陽界〉、〈星期天怕怕〉、〈鬼話連篇〉及〈神出鬼沒〉等節目的主持人或顧問,幫過許多知名藝人、政商名流處理棘手問題。

    + +

    檢方調查,蔡也出過靈異相關書籍。民眾問事須付一千元諮詢費,蔡則乘機介紹服務項目。價碼為處理嬰靈八千元,感情和合上萬元,加強桃花等感情問題甚至要數萬元。

    + +

    檢方並發現,網路上也有網友指責蔡東楓涉嫌騙財騙色,認為應還有其他被害人。但被害人大都因生辰八字落在蔡的手裡,怕被下符、下死咒,擔心會死掉,因而不敢報案。檢方希望透過具體的搜索、拘捕行動,破除被害人疑慮,勇敢出面指證。

    + +
    + + +
    +
    聯合報社會新聞 2007-09-28
    + +

    網上貼廣告被刪 命理師恐嚇版主

    + +
    【聯合報╱記者廖炳棋/台北報導】
    + +

    自稱是第一個開創台灣靈異節目的命理師蔡東楓,因在網站上張貼命理廣告遭刪除,涉嫌恐嚇版主知名投資分析人朱岳中,警方調查後,將蔡東楓依恐嚇罪嫌函送地檢署偵辦。

    + +

    開設清濤命理五術研究中心的蔡東楓(41歲),在個人網站上自稱是中華民國星象學會永久榮譽會員,並歷任東森、三立、八大等電視台靈異節目的主持人及講解老師,曾經合作的對象包括白冰冰、澎恰恰、馬世莉等藝人;網站中還強調專長處理嬰靈、男女感情和合及婚姻外遇。

    + +

    今年八月初,蔡東楓在奇摩網站無責任投資論壇上,以暱稱fdsa414141留言,恐嚇將在網聚時叫人修理版主,還說不要問他理由,總之網聚當天,版主要有心理準備,到時兩人再好好認識一下!

    + +

    無責任投資論壇的版主是南台大學財務金融系專任講師朱岳中,曾多次接受商業雜誌專訪,論文並得到國科會獎勵,他每天都在網站上發表關於金融及投資分析等方面文章,平均每天高達近萬名網友閱覽。由於蔡嫌留言恐嚇的時間,正是朱岳中準備要和高雄網友聚會前夕,因此立刻引起網友恐慌,朱岳中也馬上報警處理。

    + +

    警方追查電腦記錄,發現留言恐嚇的人就是蔡東楓,曾在無責任投資論壇網站張貼命理廣告;但朱岳中認為蔡沒有經過他同意,加上命理廣告和網站調性不合,因此以版主權限刪除廣告,想不到蔡嫌因此心生不滿,才會留言恐嚇。

    + +

    警方約談蔡嫌,他表示並不認識被害人,也沒有糾紛,會留言恐嚇只是因為他也想參加網聚,所以才留言開版主和網友的玩笑。儘管他表示沒有恐嚇犯意,仍依恐嚇罪嫌將他函送法辦。

    + +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 161 | + 162 | + 163 | + 164 | + 165 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0164.html.en.html b/htdocs/imacat/me/diary/0164.html.en.html new file mode 120000 index 0000000..c3b8582 --- /dev/null +++ b/htdocs/imacat/me/diary/0164.html.en.html @@ -0,0 +1 @@ +0164.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0164.html.en.xhtml b/htdocs/imacat/me/diary/0164.html.en.xhtml new file mode 100644 index 0000000..8e91c71 --- /dev/null +++ b/htdocs/imacat/me/diary/0164.html.en.xhtml @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 164 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 164

    + +
    + +
    + +
    +
    2.28.’11. 11:09am.
    + +

    討厭小字的網站設計

    + +

    瀏覽網站時,習慣性放大兩級字。Firefox會自動記住,久了我也就忘有放大字體過。偶爾造訪字體較大的網站,恢復原來字體,才想起平常字體有放大。不知道為什麼這些搞網站設計的人,預設字都要做這麼小,比較美觀嗎?難以理解的設計觀,超難閱讀的。

    + +
    + +
    + +
    +
    2.23.’11. 6:09pm.
    + +

    Thank you, Wikipedia

    + +
    Support Wikipedia
    + +
    + +
    + +
    +
    2.10.’11. 0:18am.
    + +

    Plants vs Zombies 的 Blind Faith

    + +

    Plants vs Zombies 的 Blind Faith ,可以在 adventurer mode 的 4-7 拿得到,不需要到 4-9 。 4-7 還看得清三行,比較好拿。

    + +

    使用的植物: puff-shroom 、 sun-shrooom 、 sea-shroom 、 lily pad 、 tangle kelp 、 tall nut 、 split pea 、 repeater 。

    + +
    + +
    + +
    +
    2.7.’11. 0:10am.
    + +

    無雙牛肉與電視美食採訪

    + +

    這兩天過年,晚上不知道吃什麼,隨便走逛,想到樂華夜市的無雙牛肉,因為小招不愛吃,好幾年沒去了,就去吃無雙牛肉,也趁著手頭比較寬鬆,點平常不會點的幾道菜。

    + +

    以前來,都一定會點無雙的招牌,涮牛肉湯。昨天晚上吃的是乾拌牛肉和蒜頭乾麵,150元;今天晚上吃乾拌牛筋和蒜頭乾麵,230元。牛筋不怎麼樣,無雙的招牌果然還是牛肉。

    + +

    沒看到老闆,只剩老闆娘和一個小女生在賣。小女生聽口音像是外籍配偶。打聽了一下,老闆退休了,換老闆娘在做。

    + +

    幾年前每次來,都沒什麼人,牆上寫人多請耐心等候,總覺得好空虛。沒想到這兩天晚上去,店內坐滿滿,今天晚上,甚至還排隊排了半個鐘頭。不知道是不是牛脾氣的老闆,為了做生意的態度和老闆娘吵架,吵一吵不做了。其實脾氣太大不好,有客人比較好,至少不會倒。

    + +

    可是像今天晚上這樣,排隊排了半個鐘頭,會讓我想重新考慮以後來不來吃。雖然我也好幾年沒來了。排隊時,後面的一對中年夫妻跟我打聽招牌是什麼。我當然介紹涮牛肉湯。旁聽他們閒聊,好像是電視有介紹,特地過來看。所以也不知道點什麼。後來就坐後旁聽隔壁桌討論,也是如此,無雙比夜市水準貴一些,他們只吃個味道就好,想必不會點太多錢,也不會來第二次。

    + +

    這讓我想到日本有些老店,老闆謝絕採訪的理由。看電視來的人,多半只是嘗鮮的,試一下味道就好,不會用心吃,吃不出味道,不會點太多,也不會來第二次。接待這樣的客人,沒有辦法好好接待常客。嚐鮮的客人不會來第二次,老客人也流失,反而得不償失。看著無雙牛肉,深有體會。

    + +

    不過,好幾年才來吃一次的我,也沒有立場說這種話就是了。

    + +
    + +
    + +
    +
    1.7.’11. 2:58am.
    + +

    可笑的零和遊戲

    + +

    某些人自以為在競爭激烈的商場上,只要別人沒有讓他贏,沒有讓他整碗捧去,他就覺得別人是要他死。

    + +

    所以他spy別人可以,別人揪出他行為不當的spy,就是破壞他名譽。

    + +

    拜託,別人手上的證據遠比他肯承認的多。他還以為網路時代,公司關起門來,做什麼都不會留下證據嗎?

    + +

    如果不是他心術不正跑來spy別人,事情會鬧得讓他自己這麼難看嗎?別人不想把場面鬧得太難看,已經很給他留面子了。這叫自作自受吧。

    + +

    做生意,可以做得光明正大,廣結善緣,大家開開心心,好來好去。商場競爭激烈六個字,不是讓人可以在社群惡搞的理由。

    + +

    我對這種零和遊戲實在很厭煩了。不要來煩我,滾遠一點可以嗎,先生?最好滾到另一個次元空間去。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 162 | + 163 | + 164 | + 165 | + 166 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0164.html.zh-cn.html b/htdocs/imacat/me/diary/0164.html.zh-cn.html new file mode 120000 index 0000000..eae745e --- /dev/null +++ b/htdocs/imacat/me/diary/0164.html.zh-cn.html @@ -0,0 +1 @@ +0164.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0164.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0164.html.zh-cn.xhtml new file mode 100644 index 0000000..4dc17c4 --- /dev/null +++ b/htdocs/imacat/me/diary/0164.html.zh-cn.xhtml @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百六十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百六十四

    + +
    + +
    + +
    +
    2.28.’11. 11:09am.
    + +

    讨厌小字的网站设计

    + +

    浏览网站时,习惯性放大两级字。Firefox会自动记住,久了我也就忘有放大字体过。偶尔造访字体较大的网站,恢复原来字体,才想起平常字体有放大。不知道为什么这些搞网站设计的人,预设字都要做这么小,比较美观吗?难以理解的设计观,超难阅读的。

    + +
    + +
    + +
    +
    2.23.’11. 6:09pm.
    + +

    Thank you, Wikipedia

    + +
    Support Wikipedia
    + +
    + +
    + +
    +
    2.10.’11. 0:18am.
    + +

    Plants vs Zombies 的 Blind Faith

    + +

    Plants vs Zombies 的 Blind Faith ,可以在 adventurer mode 的 4-7 拿得到,不需要到 4-9 。 4-7 还看得清三行,比较好拿。

    + +

    使用的植物: puff-shroom 、 sun-shrooom 、 sea-shroom 、 lily pad 、 tangle kelp 、 tall nut 、 split pea 、 repeater 。

    + +
    + +
    + +
    +
    2.7.’11. 0:10am.
    + +

    无双牛肉与电视美食采访

    + +

    这两天过年,晚上不知道吃什么,随便走逛,想到乐华夜市的无双牛肉,因为小招不爱吃,好几年没去了,就去吃无双牛肉,也趁著手头比较宽松,点平常不会点的几道菜。

    + +

    以前来,都一定会点无双的招牌,涮牛肉汤。昨天晚上吃的是干拌牛肉和蒜头干面,150元;今天晚上吃干拌牛筋和蒜头干面,230元。牛筋不怎么样,无双的招牌果然还是牛肉。

    + +

    没看到老板,只剩老板娘和一个小女生在卖。小女生听口音像是外籍配偶。打听了一下,老板退休了,换老板娘在做。

    + +

    几年前每次来,都没什么人,墙上写人多请耐心等候,总觉得好空虚。没想到这两天晚上去,店内坐满满,今天晚上,甚至还排队排了半个钟头。不知道是不是牛脾气的老板,为了做生意的态度和老板娘吵架,吵一吵不做了。其实脾气太大不好,有客人比较好,至少不会倒。

    + +

    可是像今天晚上这样,排队排了半个钟头,会让我想重新考虑以后来不来吃。虽然我也好几年没来了。排队时,后面的一对中年夫妻跟我打听招牌是什么。我当然介绍涮牛肉汤。旁听他们闲聊,好像是电视有介绍,特地过来看。所以也不知道点什么。后来就坐后旁听隔壁桌讨论,也是如此,无双比夜市水准贵一些,他们只吃个味道就好,想必不会点太多钱,也不会来第二次。

    + +

    这让我想到日本有些老店,老板谢绝采访的理由。看电视来的人,多半只是尝鲜的,试一下味道就好,不会用心吃,吃不出味道,不会点太多,也不会来第二次。接待这样的客人,没有办法好好接待常客。尝鲜的客人不会来第二次,老客人也流失,反而得不偿失。看著无双牛肉,深有体会。

    + +

    不过,好几年才来吃一次的我,也没有立场说这种话就是了。

    + +
    + +
    + +
    +
    1.7.’11. 2:58am.
    + +

    可笑的零和游戏

    + +

    某些人自以为在竞争激烈的商场上,只要别人没有让他赢,没有让他整碗捧去,他就觉得别人是要他死。

    + +

    所以他spy别人可以,别人揪出他行为不当的spy,就是破坏他名誉。

    + +

    拜托,别人手上的证据远比他肯承认的多。他还以为网路时代,公司关起门来,做什么都不会留下证据吗?

    + +

    如果不是他心术不正跑来spy别人,事情会闹得让他自己这么难看吗?别人不想把场面闹得太难看,已经很给他留面子了。这叫自作自受吧。

    + +

    做生意,可以做得光明正大,广结善缘,大家开开心心,好来好去。商场竞争激烈六个字,不是让人可以在社群恶搞的理由。

    + +

    我对这种零和游戏实在很厌烦了。不要来烦我,滚远一点可以吗,先生?最好滚到另一个次元空间去。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 162 | + 163 | + 164 | + 165 | + 166 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0164.html.zh-tw.html b/htdocs/imacat/me/diary/0164.html.zh-tw.html new file mode 120000 index 0000000..088ecd5 --- /dev/null +++ b/htdocs/imacat/me/diary/0164.html.zh-tw.html @@ -0,0 +1 @@ +0164.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0164.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0164.html.zh-tw.xhtml new file mode 100644 index 0000000..3dcde98 --- /dev/null +++ b/htdocs/imacat/me/diary/0164.html.zh-tw.xhtml @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百六十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百六十四

    + +
    + +
    + +
    +
    2.28.’11. 11:09am.
    + +

    討厭小字的網站設計

    + +

    瀏覽網站時,習慣性放大兩級字。Firefox會自動記住,久了我也就忘有放大字體過。偶爾造訪字體較大的網站,恢復原來字體,才想起平常字體有放大。不知道為什麼這些搞網站設計的人,預設字都要做這麼小,比較美觀嗎?難以理解的設計觀,超難閱讀的。

    + +
    + +
    + +
    +
    2.23.’11. 6:09pm.
    + +

    Thank you, Wikipedia

    + +
    Support Wikipedia
    + +
    + +
    + +
    +
    2.10.’11. 0:18am.
    + +

    Plants vs Zombies 的 Blind Faith

    + +

    Plants vs Zombies 的 Blind Faith ,可以在 adventurer mode 的 4-7 拿得到,不需要到 4-9 。 4-7 還看得清三行,比較好拿。

    + +

    使用的植物: puff-shroom 、 sun-shrooom 、 sea-shroom 、 lily pad 、 tangle kelp 、 tall nut 、 split pea 、 repeater 。

    + +
    + +
    + +
    +
    2.7.’11. 0:10am.
    + +

    無雙牛肉與電視美食採訪

    + +

    這兩天過年,晚上不知道吃什麼,隨便走逛,想到樂華夜市的無雙牛肉,因為小招不愛吃,好幾年沒去了,就去吃無雙牛肉,也趁著手頭比較寬鬆,點平常不會點的幾道菜。

    + +

    以前來,都一定會點無雙的招牌,涮牛肉湯。昨天晚上吃的是乾拌牛肉和蒜頭乾麵,150元;今天晚上吃乾拌牛筋和蒜頭乾麵,230元。牛筋不怎麼樣,無雙的招牌果然還是牛肉。

    + +

    沒看到老闆,只剩老闆娘和一個小女生在賣。小女生聽口音像是外籍配偶。打聽了一下,老闆退休了,換老闆娘在做。

    + +

    幾年前每次來,都沒什麼人,牆上寫人多請耐心等候,總覺得好空虛。沒想到這兩天晚上去,店內坐滿滿,今天晚上,甚至還排隊排了半個鐘頭。不知道是不是牛脾氣的老闆,為了做生意的態度和老闆娘吵架,吵一吵不做了。其實脾氣太大不好,有客人比較好,至少不會倒。

    + +

    可是像今天晚上這樣,排隊排了半個鐘頭,會讓我想重新考慮以後來不來吃。雖然我也好幾年沒來了。排隊時,後面的一對中年夫妻跟我打聽招牌是什麼。我當然介紹涮牛肉湯。旁聽他們閒聊,好像是電視有介紹,特地過來看。所以也不知道點什麼。後來就坐後旁聽隔壁桌討論,也是如此,無雙比夜市水準貴一些,他們只吃個味道就好,想必不會點太多錢,也不會來第二次。

    + +

    這讓我想到日本有些老店,老闆謝絕採訪的理由。看電視來的人,多半只是嘗鮮的,試一下味道就好,不會用心吃,吃不出味道,不會點太多,也不會來第二次。接待這樣的客人,沒有辦法好好接待常客。嚐鮮的客人不會來第二次,老客人也流失,反而得不償失。看著無雙牛肉,深有體會。

    + +

    不過,好幾年才來吃一次的我,也沒有立場說這種話就是了。

    + +
    + +
    + +
    +
    1.7.’11. 2:58am.
    + +

    可笑的零和遊戲

    + +

    某些人自以為在競爭激烈的商場上,只要別人沒有讓他贏,沒有讓他整碗捧去,他就覺得別人是要他死。

    + +

    所以他spy別人可以,別人揪出他行為不當的spy,就是破壞他名譽。

    + +

    拜託,別人手上的證據遠比他肯承認的多。他還以為網路時代,公司關起門來,做什麼都不會留下證據嗎?

    + +

    如果不是他心術不正跑來spy別人,事情會鬧得讓他自己這麼難看嗎?別人不想把場面鬧得太難看,已經很給他留面子了。這叫自作自受吧。

    + +

    做生意,可以做得光明正大,廣結善緣,大家開開心心,好來好去。商場競爭激烈六個字,不是讓人可以在社群惡搞的理由。

    + +

    我對這種零和遊戲實在很厭煩了。不要來煩我,滾遠一點可以嗎,先生?最好滾到另一個次元空間去。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 162 | + 163 | + 164 | + 165 | + 166 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0165.html.en.html b/htdocs/imacat/me/diary/0165.html.en.html new file mode 120000 index 0000000..80e4c1f --- /dev/null +++ b/htdocs/imacat/me/diary/0165.html.en.html @@ -0,0 +1 @@ +0165.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0165.html.en.xhtml b/htdocs/imacat/me/diary/0165.html.en.xhtml new file mode 100644 index 0000000..3864077 --- /dev/null +++ b/htdocs/imacat/me/diary/0165.html.en.xhtml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 165 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 165

    + +
    + +
    + +
    +
    3.25.’11. 0:04am.
    + +

    300 300壯士:斯巴達的逆襲—男性肌肉暴力風的漫畫

    + +
    +300 300壯士:斯巴達的逆襲
    +

    300 300壯士:斯巴達的逆襲

    +
    + + + +

    300壯士:斯巴達的逆襲描寫歷史上最著名的以寡擊眾戰役—溫泉關之戰。斯巴達國王雷奧尼斯面臨百萬波斯大軍侵略,在得不到議會開戰許可下,親自率領三百死士,和雅典人戴索斯率領的雅典部隊前往峽小地形溫泉關死守。利用地形和戰鬥能力優勢,不斷抵抗潮水湧進的各種軍隊:步兵、弓箭、騎兵、犀牛、戰象、幽靈戰士 The Immortals 等,死守了兩天兩夜。同時,在城裏的皇后也努力爭取議會支持出兵,不惜獻身於政敵謝爾議員。然而謝爾反指控皇后品性不端,皇后憤而刺死謝爾,才發現謝爾身上藏著波斯金幣,早已被波斯收買。在戰場上,未獲參戰的畸形人厄菲阿爾特憤而投靠波斯,洩漏溫泉關背後的秘密通道。波斯軍從秘密通道長驅直入,雅典人先行逃走,雷奧尼斯令受傷的狄里歐回去報訊,率三百死士死守,壯烈成仁,阻止了波斯的野心。隔年,狄里歐率三萬斯巴達、雅典軍隊,回到溫泉關,迎擊波斯十萬大軍。

    + +

    這麼多年後,終於看了300壯士:斯巴達的逆襲。這是漫畫改編的電影,所以以漫畫的史觀為主,和史實相差甚遠。當時斯巴達、雅典人口加起來,不可能有三萬大軍。另外,把波斯描繪得像惡魔一樣,有生化畸型人,甚至還有長得像忍者的幽靈戰士 The Immortals 。這裏面,不無對畸型人和同性戀的歧視。

    + +

    除了這些亂七八糟的東西之外,娛樂效果還不錯,蠻讓人血脈噴張的。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 163 | + 164 | + 165 | + 166 | + 167 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0165.html.zh-cn.html b/htdocs/imacat/me/diary/0165.html.zh-cn.html new file mode 120000 index 0000000..c0a2e42 --- /dev/null +++ b/htdocs/imacat/me/diary/0165.html.zh-cn.html @@ -0,0 +1 @@ +0165.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0165.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0165.html.zh-cn.xhtml new file mode 100644 index 0000000..2c5abd0 --- /dev/null +++ b/htdocs/imacat/me/diary/0165.html.zh-cn.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百六十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百六十五

    + +
    + +
    + +
    +
    3.25.’11. 0:04am.
    + +

    300 300壮士:斯巴达的逆袭—男性肌肉暴力风的漫画

    + +
    +300 300壮士:斯巴达的逆袭
    +

    300 300壮士:斯巴达的逆袭

    +
    + + + +

    300壮士:斯巴达的逆袭描写历史上最著名的以寡击众战役—温泉关之战。斯巴达国王雷奥尼斯面临百万波斯大军侵略,在得不到议会开战许可下,亲自率领三百死士,和雅典人戴索斯率领的雅典部队前往峡小地形温泉关死守。利用地形和战斗能力优势,不断抵抗潮水涌进的各种军队:步兵、弓箭、骑兵、犀牛、战象、幽灵战士 The Immortals 等,死守了两天两夜。同时,在城里的皇后也努力争取议会支持出兵,不惜献身於政敌谢尔议员。然而谢尔反指控皇后品性不端,皇后愤而刺死谢尔,才发现谢尔身上藏著波斯金币,早已被波斯收买。在战场上,未获参战的畸形人厄菲阿尔特愤而投靠波斯,泄漏温泉关背后的秘密通道。波斯军从秘密通道长驱直入,雅典人先行逃走,雷奥尼斯令受伤的狄里欧回去报讯,率三百死士死守,壮烈成仁,阻止了波斯的野心。隔年,狄里欧率三万斯巴达、雅典军队,回到温泉关,迎击波斯十万大军。

    + +

    这么多年后,终於看了300壮士:斯巴达的逆袭。这是漫画改编的电影,所以以漫画的史观为主,和史实相差甚远。当时斯巴达、雅典人口加起来,不可能有三万大军。另外,把波斯描绘得像恶魔一样,有生化畸型人,甚至还有长得像忍者的幽灵战士 The Immortals 。这里面,不无对畸型人和同性恋的歧视。

    + +

    除了这些乱七八糟的东西之外,娱乐效果还不错,蛮让人血脉喷张的。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 163 | + 164 | + 165 | + 166 | + 167 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0165.html.zh-tw.html b/htdocs/imacat/me/diary/0165.html.zh-tw.html new file mode 120000 index 0000000..ce5d9a3 --- /dev/null +++ b/htdocs/imacat/me/diary/0165.html.zh-tw.html @@ -0,0 +1 @@ +0165.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0165.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0165.html.zh-tw.xhtml new file mode 100644 index 0000000..44980f0 --- /dev/null +++ b/htdocs/imacat/me/diary/0165.html.zh-tw.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百六十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百六十五

    + +
    + +
    + +
    +
    3.25.’11. 0:04am.
    + +

    300 300壯士:斯巴達的逆襲—男性肌肉暴力風的漫畫

    + +
    +300 300壯士:斯巴達的逆襲
    +

    300 300壯士:斯巴達的逆襲

    +
    + + + +

    300壯士:斯巴達的逆襲描寫歷史上最著名的以寡擊眾戰役—溫泉關之戰。斯巴達國王雷奧尼斯面臨百萬波斯大軍侵略,在得不到議會開戰許可下,親自率領三百死士,和雅典人戴索斯率領的雅典部隊前往峽小地形溫泉關死守。利用地形和戰鬥能力優勢,不斷抵抗潮水湧進的各種軍隊:步兵、弓箭、騎兵、犀牛、戰象、幽靈戰士 The Immortals 等,死守了兩天兩夜。同時,在城裏的皇后也努力爭取議會支持出兵,不惜獻身於政敵謝爾議員。然而謝爾反指控皇后品性不端,皇后憤而刺死謝爾,才發現謝爾身上藏著波斯金幣,早已被波斯收買。在戰場上,未獲參戰的畸形人厄菲阿爾特憤而投靠波斯,洩漏溫泉關背後的秘密通道。波斯軍從秘密通道長驅直入,雅典人先行逃走,雷奧尼斯令受傷的狄里歐回去報訊,率三百死士死守,壯烈成仁,阻止了波斯的野心。隔年,狄里歐率三萬斯巴達、雅典軍隊,回到溫泉關,迎擊波斯十萬大軍。

    + +

    這麼多年後,終於看了300壯士:斯巴達的逆襲。這是漫畫改編的電影,所以以漫畫的史觀為主,和史實相差甚遠。當時斯巴達、雅典人口加起來,不可能有三萬大軍。另外,把波斯描繪得像惡魔一樣,有生化畸型人,甚至還有長得像忍者的幽靈戰士 The Immortals 。這裏面,不無對畸型人和同性戀的歧視。

    + +

    除了這些亂七八糟的東西之外,娛樂效果還不錯,蠻讓人血脈噴張的。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 163 | + 164 | + 165 | + 166 | + 167 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0166.html.en.html b/htdocs/imacat/me/diary/0166.html.en.html new file mode 120000 index 0000000..80360bc --- /dev/null +++ b/htdocs/imacat/me/diary/0166.html.en.html @@ -0,0 +1 @@ +0166.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0166.html.en.xhtml b/htdocs/imacat/me/diary/0166.html.en.xhtml new file mode 100644 index 0000000..7e35eec --- /dev/null +++ b/htdocs/imacat/me/diary/0166.html.en.xhtml @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 166 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 166

    + +
    + +
    + +
    +
    3.25.’11. 2:02am.
    + +

    葉問 Ip Man —內容貧乏、老掉牙的民族主義

    + +
    +葉問 Ip Man
    +

    葉問 Ip Man

    +
    + +
      +
    • 片名:葉問
    • +
    • 英譯片名: Ip Man
    • +
    • 發行年份: 2008
    • +
    • 製作公司:東方電影發行有限公司
    • +
    • 導演:葉偉信
    • +
    • 演員: +
        +
      • 甄子丹:葉問
      • +
      • 任達華:葉問友周清泉
      • +
      • 熊黛林:葉問妻張永成
      • +
      • 樊少皇:金山找
      • +
      • 陳之輝:廖師傅
      • +
      • 釋行宇:武痴林
      • +
      • 池內博之:三浦將軍
      • +
      • 澀谷天馬:佐藤主任
      • +
      • 林家棟:李釗
      • +
      +
    • +
    + +

    葉問描寫佛山武風鼎盛,葉問雖不收徒,閒情寄居於佛山,偶爾和人切磋,先後打敗新來的拳館館主廖師傅和北方來的拳師金山找。日軍攻佔佛山,葉家大屋被佔,無以為繼,只好出來討生活,和許多武師一起在礦場工作。日軍三浦將軍好武,常到礦場以白米為誘,找武師到館內與部隊練武。葉問好友武痴林參加,為了為中國人爭光,逞強挑戰三浦將軍而被打死。葉問本無興趣,但武痴林一去不回,葉問跟去之下,正好目擊廖師傅被打死一幕,自告奮勇上場以一打十出氣,受到三浦將軍注目。三浦將軍開始找葉問,葉問只得遷居躲藏。然而,葉問因協助好友周清泉的棉花廠,打敗流落為寇的金山找,被日軍發現。日軍挾持棉花廠工人,葉問只得現身,接受三浦將軍約鬥。公開決鬥當日,葉問打敗三浦將軍,卻被不忿的佐藤主任開槍重傷,在周清泉的協助下,舉家逃往香港。

    + +

    嗯啊,超熟悉的劇情。李小龍演爛了,成龍演爛了,精武門陳真演過,霍元甲演過,黃飛鴻演過,現在輪到葉問。千篇一律。對手有時候是美國人,有時候是日本人。總之不外乎是:中國人被外國人欺負了,軍事上被佔領,但外國人中有喜好武術的將領,和中國人的chinese kongfu公開公平決鬥,中國武師在決鬥場上打敗外國人,揚眉吐氣。

    + +

    好白癡啊!現代化戰爭中,軍人會有武術訓練,但哪有那麼多武癡?將領需要的是戰爭統率力,哪有將領武功都很高強,而且都是武癡這種事?人家幹嘛跟你決鬥?

    + +

    吐天—要吐嘈的點太多了,那就吐天吧。

    + +

    真的很失望。不過是再一部中國人民族主義自卑感下的自嗨之作。內容貧乏,純粹訴諸民族主義情感。把外國人描繪得很蠢。不知道為什麼,外國人看中國人把他們民族描繪得那麼蠢,那麼邪惡,還看得那麼高興。

    + +

    到什麼時候,中國人才會停止,不要再拍這種沒有內容自爽的蠢電影呢?

    + +
    + +
    + +
    +
    3.25.’11. 1:02am.
    + +

    投名狀 The Warlords —虛偽的正義

    + +
    +投名狀 The Warlords
    +

    投名狀 The Warlords

    +
    + +
      +
    • 片名:投名狀
    • +
    • 英譯片名: The Warlords
    • +
    • 發行年份: 2007
    • +
    • 製作公司:中國電影集團公司
    • +
    • 導演:陳可辛
    • +
    • 演員: +
        +
      • 李連杰:龐青雲
      • +
      • 劉德華:趙二虎
      • +
      • 金城武:姜午陽
      • +
      +
    • +
    + +

    投名狀描述清末太平天國之亂,龐青雲率領的清軍因友軍魁字營袖手旁觀而全軍覆沒,流浪時和蓮生發生一夜情,後加入姜午陽招募的強盜集團,認識強盜大哥趙二虎,發現蓮生是趙二虎的情人。然而所搶糧米還是被魁字營劫去。龐青雲建議趙二虎和姜午陽投軍,並納投名狀結義,兄弟各殺一外人,此後兄弟的命就是命,其他的皆可殺。三人帶村中青年投靠魁字營的政敵軍機處,成立山字營,無糧無槍,靠不要命勇猛殺敵,搶掠補糧,屢下戰功。但朝廷仍不給糧,並派魁字營就近監視。攻到最後揚州圍城近年,士兵無糧快餓死,龐青雲求糧求砲不得,不得已向魁字營低頭求糧求砲,並約定將攻南京戰功給魁字營,但實則盤算早一步進入南京。此時趙二虎潛入揚州城,成功殺死主帥,並答應讓守城四千太平軍歸農,開城迎清。但龐青雲因糧不足,擔心後患,殺盡四千降軍。趙二虎失信於太平軍,悲憤出走,被龐青雲強留。至攻破南京,趙二虎不顧朝廷未令,強行發餉。趙二虎此後鬱鬱寡歡。平定太平軍,龐青雲受封兩江總督,並獲太后同意兩江三年免賦。朝廷要求要處置曾叛走、私自發餉的趙二虎。龐青雲只好派人暗殺趙二虎。姜午陽發現蓮生和龐青雲的姦情,得知龐青雲要殺趙二虎,以為是姦情所致,殺了蓮生,卻救不了趙二虎。於是埋伏在龐青雲就任大典路上,刺殺龐青雲。然而朝廷不欲江山交外人之手,早有意刺殺龐青雲。於是龐青雲被刺死,姜午陽被補,凌遲處死。

    + +

    投名狀改編自真實的清代四大奇案之一刺馬—兩江總督馬新貽被刺死案。馬新貽預刺案真相未明,戲曲故事各有不同揣測。投名狀的故事比較接近電影刺馬,由姦情為導火線引致。不過當年馬新貽不是在就任大典上被刺,而是已就任後被刺,此時已是太平天國之亂平定後數年之事。

    + +

    令人作嘔的是龐青雲的正義觀。龐青雲堅持要取得權力,才能實現他的正義。為取得實現正義所需的權力,他不擇手段,可以殺死趙二虎已承諾保護、欲歸農的四千降軍,甚至是自己的義兄弟趙二虎。戰場上有很多不得已,但若不得已到可以背信忘義,要相信這種人的正義,不敕癡人說夢。如果連過程手段的正義、誠信都做不到,如何能空談這都是為了日後的正義呢?

    + +

    但除了令人作嘔的正義觀外,其它都不錯。野心權謀深算,卻自認為為正義而掙扎痛苦的龐青雲,守信重義的趙二虎,單純直接的姜午陽。劉德華演技向來平平,但他演的趙二虎,在兄弟情義和自己的信念中掙扎,我從來沒有看過他演得這麼好過。不過還是輸給大量內心戲的李連杰。整體來說,還不錯看,難怪這麼多人一致好評,還得到那麼多獎。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 164 | + 165 | + 166 | + 167 | + 168 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0166.html.zh-cn.html b/htdocs/imacat/me/diary/0166.html.zh-cn.html new file mode 120000 index 0000000..c8bafe9 --- /dev/null +++ b/htdocs/imacat/me/diary/0166.html.zh-cn.html @@ -0,0 +1 @@ +0166.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0166.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0166.html.zh-cn.xhtml new file mode 100644 index 0000000..bc17410 --- /dev/null +++ b/htdocs/imacat/me/diary/0166.html.zh-cn.xhtml @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百六十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百六十六

    + +
    + +
    + +
    +
    3.25.’11. 2:02am.
    + +

    叶问 Ip Man —内容贫乏、老掉牙的民族主义

    + +
    +叶问 Ip Man
    +

    叶问 Ip Man

    +
    + +
      +
    • 片名:叶问
    • +
    • 英译片名: Ip Man
    • +
    • 发行年份: 2008
    • +
    • 制作公司:东方电影发行有限公司
    • +
    • 导演:叶伟信
    • +
    • 演员: +
        +
      • 甄子丹:叶问
      • +
      • 任达华:叶问友周清泉
      • +
      • 熊黛林:叶问妻张永成
      • +
      • 樊少皇:金山找
      • +
      • 陈之辉:廖师傅
      • +
      • 释行宇:武痴林
      • +
      • 池内博之:三浦将军
      • +
      • 涩谷天马:佐藤主任
      • +
      • 林家栋:李钊
      • +
      +
    • +
    + +

    叶问描写佛山武风鼎盛,叶问虽不收徒,闲情寄居於佛山,偶尔和人切磋,先后打败新来的拳馆馆主廖师傅和北方来的拳师金山找。日军攻占佛山,叶家大屋被占,无以为继,只好出来讨生活,和许多武师一起在矿场工作。日军三浦将军好武,常到矿场以白米为诱,找武师到馆内与部队练武。叶问好友武痴林参加,为了为中国人争光,逞强挑战三浦将军而被打死。叶问本无兴趣,但武痴林一去不回,叶问跟去之下,正好目击廖师傅被打死一幕,自告奋勇上场以一打十出气,受到三浦将军注目。三浦将军开始找叶问,叶问只得迁居躲藏。然而,叶问因协助好友周清泉的棉花厂,打败流落为寇的金山找,被日军发现。日军挟持棉花厂工人,叶问只得现身,接受三浦将军约斗。公开决斗当日,叶问打败三浦将军,却被不忿的佐藤主任开枪重伤,在周清泉的协助下,举家逃往香港。

    + +

    嗯啊,超熟悉的剧情。李小龙演烂了,成龙演烂了,精武门陈真演过,霍元甲演过,黄飞鸿演过,现在轮到叶问。千篇一律。对手有时候是美国人,有时候是日本人。总之不外乎是:中国人被外国人欺负了,军事上被占领,但外国人中有喜好武术的将领,和中国人的chinese kongfu公开公平决斗,中国武师在决斗场上打败外国人,扬眉吐气。

    + +

    好白痴啊!现代化战争中,军人会有武术训练,但哪有那么多武痴?将领需要的是战争统率力,哪有将领武功都很高强,而且都是武痴这种事?人家干嘛跟你决斗?

    + +

    吐天—要吐嘈的点太多了,那就吐天吧。

    + +

    真的很失望。不过是再一部中国人民族主义自卑感下的自嗨之作。内容贫乏,纯粹诉诸民族主义情感。把外国人描绘得很蠢。不知道为什么,外国人看中国人把他们民族描绘得那么蠢,那么邪恶,还看得那么高兴。

    + +

    到什么时候,中国人才会停止,不要再拍这种没有内容自爽的蠢电影呢?

    + +
    + +
    + +
    +
    3.25.’11. 1:02am.
    + +

    投名状 The Warlords —虚伪的正义

    + +
    +投名状 The Warlords
    +

    投名状 The Warlords

    +
    + +
      +
    • 片名:投名状
    • +
    • 英译片名: The Warlords
    • +
    • 发行年份: 2007
    • +
    • 制作公司:中国电影集团公司
    • +
    • 导演:陈可辛
    • +
    • 演员: +
        +
      • 李连杰:庞青云
      • +
      • 刘德华:赵二虎
      • +
      • 金城武:姜午阳
      • +
      +
    • +
    + +

    投名状描述清末太平天国之乱,庞青云率领的清军因友军魁字营袖手旁观而全军覆没,流浪时和莲生发生一夜情,后加入姜午阳招募的强盗集团,认识强盗大哥赵二虎,发现莲生是赵二虎的情人。然而所抢粮米还是被魁字营劫去。庞青云建议赵二虎和姜午阳投军,并纳投名状结义,兄弟各杀一外人,此后兄弟的命就是命,其他的皆可杀。三人带村中青年投靠魁字营的政敌军机处,成立山字营,无粮无枪,靠不要命勇猛杀敌,抢掠补粮,屡下战功。但朝廷仍不给粮,并派魁字营就近监视。攻到最后扬州围城近年,士兵无粮快饿死,庞青云求粮求炮不得,不得已向魁字营低头求粮求炮,并约定将攻南京战功给魁字营,但实则盘算早一步进入南京。此时赵二虎潜入扬州城,成功杀死主帅,并答应让守城四千太平军归农,开城迎清。但庞青云因粮不足,担心后患,杀尽四千降军。赵二虎失信於太平军,悲愤出走,被庞青云强留。至攻破南京,赵二虎不顾朝廷未令,强行发饷。赵二虎此后郁郁寡欢。平定太平军,庞青云受封两江总督,并获太后同意两江三年免赋。朝廷要求要处置曾叛走、私自发饷的赵二虎。庞青云只好派人暗杀赵二虎。姜午阳发现莲生和庞青云的奸情,得知庞青云要杀赵二虎,以为是奸情所致,杀了莲生,却救不了赵二虎。於是埋伏在庞青云就任大典路上,刺杀庞青云。然而朝廷不欲江山交外人之手,早有意刺杀庞青云。於是庞青云被刺死,姜午阳被补,凌迟处死。

    + +

    投名状改编自真实的清代四大奇案之一刺马—两江总督马新贻被刺死案。马新贻预刺案真相未明,戏曲故事各有不同揣测。投名状的故事比较接近电影刺马,由奸情为导火线引致。不过当年马新贻不是在就任大典上被刺,而是已就任后被刺,此时已是太平天国之乱平定后数年之事。

    + +

    令人作呕的是庞青云的正义观。庞青云坚持要取得权力,才能实现他的正义。为取得实现正义所需的权力,他不择手段,可以杀死赵二虎已承诺保护、欲归农的四千降军,甚至是自己的义兄弟赵二虎。战场上有很多不得已,但若不得已到可以背信忘义,要相信这种人的正义,不敕痴人说梦。如果连过程手段的正义、诚信都做不到,如何能空谈这都是为了日后的正义呢?

    + +

    但除了令人作呕的正义观外,其它都不错。野心权谋深算,却自认为为正义而挣扎痛苦的庞青云,守信重义的赵二虎,单纯直接的姜午阳。刘德华演技向来平平,但他演的赵二虎,在兄弟情义和自己的信念中挣扎,我从来没有看过他演得这么好过。不过还是输给大量内心戏的李连杰。整体来说,还不错看,难怪这么多人一致好评,还得到那么多奖。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 164 | + 165 | + 166 | + 167 | + 168 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0166.html.zh-tw.html b/htdocs/imacat/me/diary/0166.html.zh-tw.html new file mode 120000 index 0000000..32ad672 --- /dev/null +++ b/htdocs/imacat/me/diary/0166.html.zh-tw.html @@ -0,0 +1 @@ +0166.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0166.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0166.html.zh-tw.xhtml new file mode 100644 index 0000000..e3e5f4d --- /dev/null +++ b/htdocs/imacat/me/diary/0166.html.zh-tw.xhtml @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百六十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百六十六

    + +
    + +
    + +
    +
    3.25.’11. 2:02am.
    + +

    葉問 Ip Man —內容貧乏、老掉牙的民族主義

    + +
    +葉問 Ip Man
    +

    葉問 Ip Man

    +
    + +
      +
    • 片名:葉問
    • +
    • 英譯片名: Ip Man
    • +
    • 發行年份: 2008
    • +
    • 製作公司:東方電影發行有限公司
    • +
    • 導演:葉偉信
    • +
    • 演員: +
        +
      • 甄子丹:葉問
      • +
      • 任達華:葉問友周清泉
      • +
      • 熊黛林:葉問妻張永成
      • +
      • 樊少皇:金山找
      • +
      • 陳之輝:廖師傅
      • +
      • 釋行宇:武痴林
      • +
      • 池內博之:三浦將軍
      • +
      • 澀谷天馬:佐藤主任
      • +
      • 林家棟:李釗
      • +
      +
    • +
    + +

    葉問描寫佛山武風鼎盛,葉問雖不收徒,閒情寄居於佛山,偶爾和人切磋,先後打敗新來的拳館館主廖師傅和北方來的拳師金山找。日軍攻佔佛山,葉家大屋被佔,無以為繼,只好出來討生活,和許多武師一起在礦場工作。日軍三浦將軍好武,常到礦場以白米為誘,找武師到館內與部隊練武。葉問好友武痴林參加,為了為中國人爭光,逞強挑戰三浦將軍而被打死。葉問本無興趣,但武痴林一去不回,葉問跟去之下,正好目擊廖師傅被打死一幕,自告奮勇上場以一打十出氣,受到三浦將軍注目。三浦將軍開始找葉問,葉問只得遷居躲藏。然而,葉問因協助好友周清泉的棉花廠,打敗流落為寇的金山找,被日軍發現。日軍挾持棉花廠工人,葉問只得現身,接受三浦將軍約鬥。公開決鬥當日,葉問打敗三浦將軍,卻被不忿的佐藤主任開槍重傷,在周清泉的協助下,舉家逃往香港。

    + +

    嗯啊,超熟悉的劇情。李小龍演爛了,成龍演爛了,精武門陳真演過,霍元甲演過,黃飛鴻演過,現在輪到葉問。千篇一律。對手有時候是美國人,有時候是日本人。總之不外乎是:中國人被外國人欺負了,軍事上被佔領,但外國人中有喜好武術的將領,和中國人的chinese kongfu公開公平決鬥,中國武師在決鬥場上打敗外國人,揚眉吐氣。

    + +

    好白癡啊!現代化戰爭中,軍人會有武術訓練,但哪有那麼多武癡?將領需要的是戰爭統率力,哪有將領武功都很高強,而且都是武癡這種事?人家幹嘛跟你決鬥?

    + +

    吐天—要吐嘈的點太多了,那就吐天吧。

    + +

    真的很失望。不過是再一部中國人民族主義自卑感下的自嗨之作。內容貧乏,純粹訴諸民族主義情感。把外國人描繪得很蠢。不知道為什麼,外國人看中國人把他們民族描繪得那麼蠢,那麼邪惡,還看得那麼高興。

    + +

    到什麼時候,中國人才會停止,不要再拍這種沒有內容自爽的蠢電影呢?

    + +
    + +
    + +
    +
    3.25.’11. 1:02am.
    + +

    投名狀 The Warlords —虛偽的正義

    + +
    +投名狀 The Warlords
    +

    投名狀 The Warlords

    +
    + +
      +
    • 片名:投名狀
    • +
    • 英譯片名: The Warlords
    • +
    • 發行年份: 2007
    • +
    • 製作公司:中國電影集團公司
    • +
    • 導演:陳可辛
    • +
    • 演員: +
        +
      • 李連杰:龐青雲
      • +
      • 劉德華:趙二虎
      • +
      • 金城武:姜午陽
      • +
      +
    • +
    + +

    投名狀描述清末太平天國之亂,龐青雲率領的清軍因友軍魁字營袖手旁觀而全軍覆沒,流浪時和蓮生發生一夜情,後加入姜午陽招募的強盜集團,認識強盜大哥趙二虎,發現蓮生是趙二虎的情人。然而所搶糧米還是被魁字營劫去。龐青雲建議趙二虎和姜午陽投軍,並納投名狀結義,兄弟各殺一外人,此後兄弟的命就是命,其他的皆可殺。三人帶村中青年投靠魁字營的政敵軍機處,成立山字營,無糧無槍,靠不要命勇猛殺敵,搶掠補糧,屢下戰功。但朝廷仍不給糧,並派魁字營就近監視。攻到最後揚州圍城近年,士兵無糧快餓死,龐青雲求糧求砲不得,不得已向魁字營低頭求糧求砲,並約定將攻南京戰功給魁字營,但實則盤算早一步進入南京。此時趙二虎潛入揚州城,成功殺死主帥,並答應讓守城四千太平軍歸農,開城迎清。但龐青雲因糧不足,擔心後患,殺盡四千降軍。趙二虎失信於太平軍,悲憤出走,被龐青雲強留。至攻破南京,趙二虎不顧朝廷未令,強行發餉。趙二虎此後鬱鬱寡歡。平定太平軍,龐青雲受封兩江總督,並獲太后同意兩江三年免賦。朝廷要求要處置曾叛走、私自發餉的趙二虎。龐青雲只好派人暗殺趙二虎。姜午陽發現蓮生和龐青雲的姦情,得知龐青雲要殺趙二虎,以為是姦情所致,殺了蓮生,卻救不了趙二虎。於是埋伏在龐青雲就任大典路上,刺殺龐青雲。然而朝廷不欲江山交外人之手,早有意刺殺龐青雲。於是龐青雲被刺死,姜午陽被補,凌遲處死。

    + +

    投名狀改編自真實的清代四大奇案之一刺馬—兩江總督馬新貽被刺死案。馬新貽預刺案真相未明,戲曲故事各有不同揣測。投名狀的故事比較接近電影刺馬,由姦情為導火線引致。不過當年馬新貽不是在就任大典上被刺,而是已就任後被刺,此時已是太平天國之亂平定後數年之事。

    + +

    令人作嘔的是龐青雲的正義觀。龐青雲堅持要取得權力,才能實現他的正義。為取得實現正義所需的權力,他不擇手段,可以殺死趙二虎已承諾保護、欲歸農的四千降軍,甚至是自己的義兄弟趙二虎。戰場上有很多不得已,但若不得已到可以背信忘義,要相信這種人的正義,不敕癡人說夢。如果連過程手段的正義、誠信都做不到,如何能空談這都是為了日後的正義呢?

    + +

    但除了令人作嘔的正義觀外,其它都不錯。野心權謀深算,卻自認為為正義而掙扎痛苦的龐青雲,守信重義的趙二虎,單純直接的姜午陽。劉德華演技向來平平,但他演的趙二虎,在兄弟情義和自己的信念中掙扎,我從來沒有看過他演得這麼好過。不過還是輸給大量內心戲的李連杰。整體來說,還不錯看,難怪這麼多人一致好評,還得到那麼多獎。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 164 | + 165 | + 166 | + 167 | + 168 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0167.html.en.html b/htdocs/imacat/me/diary/0167.html.en.html new file mode 120000 index 0000000..903bdeb --- /dev/null +++ b/htdocs/imacat/me/diary/0167.html.en.html @@ -0,0 +1 @@ +0167.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0167.html.en.xhtml b/htdocs/imacat/me/diary/0167.html.en.xhtml new file mode 100644 index 0000000..456c7fb --- /dev/null +++ b/htdocs/imacat/me/diary/0167.html.en.xhtml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 167 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 167

    + +
    + +
    + +
    +
    3.25.’11. 2:51am.
    + +

    Resident Evil: Degeneration 惡靈古堡CG動畫—普通

    + +
    +Resident Evil: Degeneration 惡靈古堡CG動畫
    +

    Resident Evil: Degeneration 惡靈古堡CG動畫

    +
    + +
      +
    • 片名: Resident Evil: Degeneration
    • +
    • 中譯片名:惡靈古堡CG動畫
    • +
    • 發行年份: 2008
    • +
    • 製作公司:Sony Pictures Entertainment
    • +
    • 導演:神谷誠
    • +
    + +

    惡靈古堡CG動畫描述 Unbrella 雨傘公司與 Raccoon City 浣熊市的慘劇後五年,一家新的生化製藥廠 WilPharma 威法瑪,承接了政府的反生化恐怖作戰計劃,因為人體實驗的資料曝光,被非營運組織 TerraSave 諦拉席芙抗議要求關閉。在機場內, TerraSave 諦拉席芙的成員 Claire 克蕾兒與支持威法瑪的議員 Ron Davis 朗戴維斯,碰到突然出現的殭屍攻擊,一起躲避待援。機場關閉後,白宮派 Leon ,和 S.R.T. 特殊回應小組的 Angela 安潔拉、 Greg 葛瑞格一起作戰,葛瑞格不幸感染戰死,救出倖存的克蕾兒和朗戴維斯。救出作戰結束後, WilPharma 威法瑪送疫苗來,才知道威法瑪真的是研發疫苗而不是生化武器,他們誤解了朗戴維斯議員和 Frederic Downing 佛瑞德瑞克博士。然而疫苗突然爆炸被毀,眾人開始懷疑有幕後主使者,並追出克蕾兒的哥哥 Curtis Miller 柯提斯米勒妻兒死於浣熊市,認為政府和威法瑪說謊,是發動恐怖攻擊的恐怖份子。里昂、克蕾兒、安琪拉追至威法瑪公司,發現柯提斯竊走使用最危險的 G 疫苗,變身成怪物。打敗柯提斯後,發現議員真的不知情,佛瑞德瑞克博士才是幕後主使,利用柯提斯破壞變身的影象記錄,向恐怖份子兜售病毒。最後逮補博士,恢復和平。

    + +

    諦拉席芙反對威法瑪,其實也沒有反對錯。故事環繞惡靈古堡的主軸:病毒很可怕,但最終在背後操縱的,還是人心的邪惡。

    + +

    內容感覺上像是普通的動作電影。因為太普通了,有點讓人失望。並沒有惡靈古堡的恐怖壓迫感。可是看電影惡靈古堡3D,也同樣沒有恐怖壓迫感。是不是電影版已經自成一格了呢?

    + +

    從葛瑞格一上場,就知道他會死。老套到很好笑。近幾年的殭屍恐怖片老掉牙的段子,死的一定是話多孔武有力的男性。這個話多孔武有力的男性的形象,也很多破綻,像日本搞笑演員一樣,一直自顧自講冷笑話,雖然拼命講英語笑話,但是感覺還是很日式,一點都不美式。如果這個角色真的找美國人來設計,對白找美國人來寫,不知道會不會好一些?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 165 | + 166 | + 167 | + 168 | + 169 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0167.html.zh-cn.html b/htdocs/imacat/me/diary/0167.html.zh-cn.html new file mode 120000 index 0000000..04bed12 --- /dev/null +++ b/htdocs/imacat/me/diary/0167.html.zh-cn.html @@ -0,0 +1 @@ +0167.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0167.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0167.html.zh-cn.xhtml new file mode 100644 index 0000000..224eb9c --- /dev/null +++ b/htdocs/imacat/me/diary/0167.html.zh-cn.xhtml @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百六十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百六十七

    + +
    + +
    + +
    +
    3.25.’11. 2:51am.
    + +

    Resident Evil: Degeneration 恶灵古堡CG动画—普通

    + +
    +Resident Evil: Degeneration 恶灵古堡CG动画
    +

    Resident Evil: Degeneration 恶灵古堡CG动画

    +
    + +
      +
    • 片名: Resident Evil: Degeneration
    • +
    • 中译片名:恶灵古堡CG动画
    • +
    • 发行年份: 2008
    • +
    • 制作公司:Sony Pictures Entertainment
    • +
    • 导演:神谷诚
    • +
    + +

    恶灵古堡CG动画描述 Unbrella 雨伞公司与 Raccoon City 浣熊市的惨剧后五年,一家新的生化制药厂 WilPharma 威法玛,承接了政府的反生化恐怖作战计划,因为人体实验的资料曝光,被非营运组织 TerraSave 谛拉席芙抗议要求关闭。在机场内, TerraSave 谛拉席芙的成员 Claire 克蕾儿与支持威法玛的议员 Ron Davis 朗戴维斯,碰到突然出现的僵尸攻击,一起躲避待援。机场关闭后,白宫派 Leon ,和 S.R.T. 特殊回应小组的 Angela 安洁拉、 Greg 葛瑞格一起作战,葛瑞格不幸感染战死,救出幸存的克蕾儿和朗戴维斯。救出作战结束后, WilPharma 威法玛送疫苗来,才知道威法玛真的是研发疫苗而不是生化武器,他们误解了朗戴维斯议员和 Frederic Downing 佛瑞德瑞克博士。然而疫苗突然爆炸被毁,众人开始怀疑有幕后主使者,并追出克蕾儿的哥哥 Curtis Miller 柯提斯米勒妻儿死於浣熊市,认为政府和威法玛说谎,是发动恐怖攻击的恐怖份子。里昂、克蕾儿、安琪拉追至威法玛公司,发现柯提斯窃走使用最危险的 G 疫苗,变身成怪物。打败柯提斯后,发现议员真的不知情,佛瑞德瑞克博士才是幕后主使,利用柯提斯破坏变身的影象记录,向恐怖份子兜售病毒。最后逮补博士,恢复和平。

    + +

    谛拉席芙反对威法玛,其实也没有反对错。故事环绕恶灵古堡的主轴:病毒很可怕,但最终在背后操纵的,还是人心的邪恶。

    + +

    内容感觉上像是普通的动作电影。因为太普通了,有点让人失望。并没有恶灵古堡的恐怖压迫感。可是看电影恶灵古堡3D,也同样没有恐怖压迫感。是不是电影版已经自成一格了呢?

    + +

    从葛瑞格一上场,就知道他会死。老套到很好笑。近几年的僵尸恐怖片老掉牙的段子,死的一定是话多孔武有力的男性。这个话多孔武有力的男性的形象,也很多破绽,像日本搞笑演员一样,一直自顾自讲冷笑话,虽然拼命讲英语笑话,但是感觉还是很日式,一点都不美式。如果这个角色真的找美国人来设计,对白找美国人来写,不知道会不会好一些?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 165 | + 166 | + 167 | + 168 | + 169 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0167.html.zh-tw.html b/htdocs/imacat/me/diary/0167.html.zh-tw.html new file mode 120000 index 0000000..77e3ee0 --- /dev/null +++ b/htdocs/imacat/me/diary/0167.html.zh-tw.html @@ -0,0 +1 @@ +0167.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0167.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0167.html.zh-tw.xhtml new file mode 100644 index 0000000..6651349 --- /dev/null +++ b/htdocs/imacat/me/diary/0167.html.zh-tw.xhtml @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百六十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百六十七

    + +
    + +
    + +
    +
    3.25.’11. 2:51am.
    + +

    Resident Evil: Degeneration 惡靈古堡CG動畫—普通

    + +
    +Resident Evil: Degeneration 惡靈古堡CG動畫
    +

    Resident Evil: Degeneration 惡靈古堡CG動畫

    +
    + +
      +
    • 片名: Resident Evil: Degeneration
    • +
    • 中譯片名:惡靈古堡CG動畫
    • +
    • 發行年份: 2008
    • +
    • 製作公司:Sony Pictures Entertainment
    • +
    • 導演:神谷誠
    • +
    + +

    惡靈古堡CG動畫描述 Unbrella 雨傘公司與 Raccoon City 浣熊市的慘劇後五年,一家新的生化製藥廠 WilPharma 威法瑪,承接了政府的反生化恐怖作戰計劃,因為人體實驗的資料曝光,被非營運組織 TerraSave 諦拉席芙抗議要求關閉。在機場內, TerraSave 諦拉席芙的成員 Claire 克蕾兒與支持威法瑪的議員 Ron Davis 朗戴維斯,碰到突然出現的殭屍攻擊,一起躲避待援。機場關閉後,白宮派 Leon ,和 S.R.T. 特殊回應小組的 Angela 安潔拉、 Greg 葛瑞格一起作戰,葛瑞格不幸感染戰死,救出倖存的克蕾兒和朗戴維斯。救出作戰結束後, WilPharma 威法瑪送疫苗來,才知道威法瑪真的是研發疫苗而不是生化武器,他們誤解了朗戴維斯議員和 Frederic Downing 佛瑞德瑞克博士。然而疫苗突然爆炸被毀,眾人開始懷疑有幕後主使者,並追出克蕾兒的哥哥 Curtis Miller 柯提斯米勒妻兒死於浣熊市,認為政府和威法瑪說謊,是發動恐怖攻擊的恐怖份子。里昂、克蕾兒、安琪拉追至威法瑪公司,發現柯提斯竊走使用最危險的 G 疫苗,變身成怪物。打敗柯提斯後,發現議員真的不知情,佛瑞德瑞克博士才是幕後主使,利用柯提斯破壞變身的影象記錄,向恐怖份子兜售病毒。最後逮補博士,恢復和平。

    + +

    諦拉席芙反對威法瑪,其實也沒有反對錯。故事環繞惡靈古堡的主軸:病毒很可怕,但最終在背後操縱的,還是人心的邪惡。

    + +

    內容感覺上像是普通的動作電影。因為太普通了,有點讓人失望。並沒有惡靈古堡的恐怖壓迫感。可是看電影惡靈古堡3D,也同樣沒有恐怖壓迫感。是不是電影版已經自成一格了呢?

    + +

    從葛瑞格一上場,就知道他會死。老套到很好笑。近幾年的殭屍恐怖片老掉牙的段子,死的一定是話多孔武有力的男性。這個話多孔武有力的男性的形象,也很多破綻,像日本搞笑演員一樣,一直自顧自講冷笑話,雖然拼命講英語笑話,但是感覺還是很日式,一點都不美式。如果這個角色真的找美國人來設計,對白找美國人來寫,不知道會不會好一些?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 165 | + 166 | + 167 | + 168 | + 169 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0168.html.en.html b/htdocs/imacat/me/diary/0168.html.en.html new file mode 120000 index 0000000..8b82fa2 --- /dev/null +++ b/htdocs/imacat/me/diary/0168.html.en.html @@ -0,0 +1 @@ +0168.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0168.html.en.xhtml b/htdocs/imacat/me/diary/0168.html.en.xhtml new file mode 100644 index 0000000..c1aa928 --- /dev/null +++ b/htdocs/imacat/me/diary/0168.html.en.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 168 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 168

    + +
    + +
    + +
    +
    3.25.’11. 12:28pm.
    + +

    風雲Ⅱ The Storm Warriors —水墨亂噴

    + +
    +風雲Ⅱ The Storm Warriors
    +

    風雲Ⅱ The Storm Warriors

    +
    + +
      +
    • 片名:風雲Ⅱ
    • +
    • 英譯片名: The Storm Warriors
    • +
    • 發行年份: 2009
    • +
    • 製作公司:寰宇
    • +
    • 導演:彭氏兄弟
    • +
    • 演員: +
        +
      • 郭富城:步驚雲
      • +
      • 鄭伊健:聶風
      • +
      • 蔡卓妍:第二夢
      • +
      • 唐嫣:楚楚
      • +
      • 任達華:絕無神
      • +
      • 謝霆鋒:絕心
      • +
      • 何家勁:無名
      • +
      • 黃德斌:邪皇
      • +
      • 林雪:豬皇
      • +
      +
    • +
    + +

    風雲Ⅱ描述絕無神使麻香骨困住無名、風、雲、楚楚及一眾武林高手,意圖酷刑逼降。但鬼虎事先偷來麻香骨解藥給眾人服用。緊要關頭眾人齊力破除枷鎖對抗絕無神,但其實只是製造空隙讓風雲及無名等逃走。無名雖保得一命,但麻香骨毒性未除強行運萬劍歸宗,功力大傷,指示風雲往找邪皇相助。聶風終於見到第二夢。邪皇因曾練魔功走火入魔濫殺無辜村民,自責自斷雙臂,大不如前,但仍願協助風雲入魔,短時間提昇功力。步驚雲對眾武林前輩犧牲生命救他深感有愧,與聶風爭相入魔,但邪皇仍選擇聶風,盼聶風的仁心能在入魔後助自己回歸。步驚雲雖未得入魔,仍獲得無名傾囊相授,並自創出霸劍訣。此時絕無神的部下也找上步驚雲和閉關中之聶風,步驚雲擊退來敵,但聶風閉關中,第二夢不敵來敵,生死關頭,未完全入魔的聶風強行出關救第二夢,並自顧離去不知所蹤。絕無神挾持中原皇帝,欲取得龍脈,最後關頭步驚雲及時出現,大戰絕無神,正不敵間,入魔聶風神秘出現,大戰兩人,並於殺敗絕無神後,取走龍脈,不知所蹤。龍脈被奪,聶風成朝廷欽犯。步驚雲找到躲藏在聶家村,以龍脈強行鎮壓自己魔性的聶風,朝廷趁聶風魔性稍退奪回龍脈。失去龍脈的聶風魔性大熾,與步驚雲大戰,並殺了楚楚。悲憤的步驚雲使出霸劍訣擊敗聶風,洩去聶風一身魔性,但在最後關頭還是為救聶風,捨身葬崖。清醒後的聶風眼見楚楚屍首及為救自己跳崖的步驚雲,悲痛不已。

    + +

    看完後第一個感覺是:水墨好多啊!感覺好像Street Fighter Ⅳ的預告片是抄風雲Ⅱ一樣。聶風的魔氣以潑墨的方式呈現,水墨紛飛。其實整部戲表現,寫意大過寫實,絕心絕無神征服各大派的過程,都是慢動作的剪影。殺人後,則是破成碎塊消失,沒有血腥也沒有屍首。這樣的表現,完全抓緊馬榮成擅長的寫意風格,然而用在電影上是否合適,可以檢討。

    + +

    另一個感想是:郭富城和鄭伊健可以拿一比一的絕世好劍和雪飲刀揮舞,真是讓人超羨慕的啦!我也好想要等比例的絕世好劍和雪飲刀。

    + +

    對第二夢很失望。我很喜歡第二夢,雖然不漂亮,但是有能力又有智慧。所以我很期待第二夢的登場。但是蔡卓妍演來,成了可愛教主了。蔡卓妍本就可愛。但是第二夢穩重成熟智慧的感覺,全部消失了。

    + +

    不過,風雲的演技,都有可看之處。步驚雲由邪轉正的沉默與轉折,聶風由正入魔的張狂魔氣,都非常可看。第一次覺得,找鄭伊健演聶風,找郭富城演步驚雲,是對的。他們兩個,都演得太好了。

    + +

    無名你不要亂造字啊,亂造字電腦打不出來。無名說霸劍訣的霸,是雲和劍組成,可是左邊根本不是雲,是簡體的云,在古代,云根本沒有雲的意思吧!

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 166 | + 167 | + 168 | + 169 | + 170 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0168.html.zh-cn.html b/htdocs/imacat/me/diary/0168.html.zh-cn.html new file mode 120000 index 0000000..5f9e20e --- /dev/null +++ b/htdocs/imacat/me/diary/0168.html.zh-cn.html @@ -0,0 +1 @@ +0168.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0168.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0168.html.zh-cn.xhtml new file mode 100644 index 0000000..89ae62d --- /dev/null +++ b/htdocs/imacat/me/diary/0168.html.zh-cn.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百六十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百六十八

    + +
    + +
    + +
    +
    3.25.’11. 12:28pm.
    + +

    风云Ⅱ The Storm Warriors —水墨乱喷

    + +
    +风云Ⅱ The Storm Warriors
    +

    风云Ⅱ The Storm Warriors

    +
    + +
      +
    • 片名:风云Ⅱ
    • +
    • 英译片名: The Storm Warriors
    • +
    • 发行年份: 2009
    • +
    • 制作公司:寰宇
    • +
    • 导演:彭氏兄弟
    • +
    • 演员: +
        +
      • 郭富城:步惊云
      • +
      • 郑伊健:聂风
      • +
      • 蔡卓妍:第二梦
      • +
      • 唐嫣:楚楚
      • +
      • 任达华:绝无神
      • +
      • 谢霆锋:绝心
      • +
      • 何家劲:无名
      • +
      • 黄德斌:邪皇
      • +
      • 林雪:猪皇
      • +
      +
    • +
    + +

    风云Ⅱ描述绝无神使麻香骨困住无名、风、云、楚楚及一众武林高手,意图酷刑逼降。但鬼虎事先偷来麻香骨解药给众人服用。紧要关头众人齐力破除枷锁对抗绝无神,但其实只是制造空隙让风云及无名等逃走。无名虽保得一命,但麻香骨毒性未除强行运万剑归宗,功力大伤,指示风云往找邪皇相助。聂风终於见到第二梦。邪皇因曾练魔功走火入魔滥杀无辜村民,自责自断双臂,大不如前,但仍愿协助风云入魔,短时间提升功力。步惊云对众武林前辈牺牲生命救他深感有愧,与聂风争相入魔,但邪皇仍选择聂风,盼聂风的仁心能在入魔后助自己回归。步惊云虽未得入魔,仍获得无名倾囊相授,并自创出霸剑诀。此时绝无神的部下也找上步惊云和闭关中之聂风,步惊云击退来敌,但聂风闭关中,第二梦不敌来敌,生死关头,未完全入魔的聂风强行出关救第二梦,并自顾离去不知所踪。绝无神挟持中原皇帝,欲取得龙脉,最后关头步惊云及时出现,大战绝无神,正不敌间,入魔聂风神秘出现,大战两人,并於杀败绝无神后,取走龙脉,不知所踪。龙脉被夺,聂风成朝廷钦犯。步惊云找到躲藏在聂家村,以龙脉强行镇压自己魔性的聂风,朝廷趁聂风魔性稍退夺回龙脉。失去龙脉的聂风魔性大炽,与步惊云大战,并杀了楚楚。悲愤的步惊云使出霸剑诀击败聂风,泄去聂风一身魔性,但在最后关头还是为救聂风,舍身葬崖。清醒后的聂风眼见楚楚尸首及为救自己跳崖的步惊云,悲痛不已。

    + +

    看完后第一个感觉是:水墨好多啊!感觉好像Street Fighter Ⅳ的预告片是抄风云Ⅱ一样。聂风的魔气以泼墨的方式呈现,水墨纷飞。其实整部戏表现,写意大过写实,绝心绝无神征服各大派的过程,都是慢动作的剪影。杀人后,则是破成碎块消失,没有血腥也没有尸首。这样的表现,完全抓紧马荣成擅长的写意风格,然而用在电影上是否合适,可以检讨。

    + +

    另一个感想是:郭富城和郑伊健可以拿一比一的绝世好剑和雪饮刀挥舞,真是让人超羡慕的啦!我也好想要等比例的绝世好剑和雪饮刀。

    + +

    对第二梦很失望。我很喜欢第二梦,虽然不漂亮,但是有能力又有智慧。所以我很期待第二梦的登场。但是蔡卓妍演来,成了可爱教主了。蔡卓妍本就可爱。但是第二梦稳重成熟智慧的感觉,全部消失了。

    + +

    不过,风云的演技,都有可看之处。步惊云由邪转正的沉默与转折,聂风由正入魔的张狂魔气,都非常可看。第一次觉得,找郑伊健演聂风,找郭富城演步惊云,是对的。他们两个,都演得太好了。

    + +

    无名你不要乱造字啊,乱造字电脑打不出来。无名说霸剑诀的霸,是云和剑组成,可是左边根本不是云,是简体的云,在古代,云根本没有云的意思吧!

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 166 | + 167 | + 168 | + 169 | + 170 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0168.html.zh-tw.html b/htdocs/imacat/me/diary/0168.html.zh-tw.html new file mode 120000 index 0000000..1df154a --- /dev/null +++ b/htdocs/imacat/me/diary/0168.html.zh-tw.html @@ -0,0 +1 @@ +0168.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0168.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0168.html.zh-tw.xhtml new file mode 100644 index 0000000..26ca90a --- /dev/null +++ b/htdocs/imacat/me/diary/0168.html.zh-tw.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百六十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百六十八

    + +
    + +
    + +
    +
    3.25.’11. 12:28pm.
    + +

    風雲Ⅱ The Storm Warriors —水墨亂噴

    + +
    +風雲Ⅱ The Storm Warriors
    +

    風雲Ⅱ The Storm Warriors

    +
    + +
      +
    • 片名:風雲Ⅱ
    • +
    • 英譯片名: The Storm Warriors
    • +
    • 發行年份: 2009
    • +
    • 製作公司:寰宇
    • +
    • 導演:彭氏兄弟
    • +
    • 演員: +
        +
      • 郭富城:步驚雲
      • +
      • 鄭伊健:聶風
      • +
      • 蔡卓妍:第二夢
      • +
      • 唐嫣:楚楚
      • +
      • 任達華:絕無神
      • +
      • 謝霆鋒:絕心
      • +
      • 何家勁:無名
      • +
      • 黃德斌:邪皇
      • +
      • 林雪:豬皇
      • +
      +
    • +
    + +

    風雲Ⅱ描述絕無神使麻香骨困住無名、風、雲、楚楚及一眾武林高手,意圖酷刑逼降。但鬼虎事先偷來麻香骨解藥給眾人服用。緊要關頭眾人齊力破除枷鎖對抗絕無神,但其實只是製造空隙讓風雲及無名等逃走。無名雖保得一命,但麻香骨毒性未除強行運萬劍歸宗,功力大傷,指示風雲往找邪皇相助。聶風終於見到第二夢。邪皇因曾練魔功走火入魔濫殺無辜村民,自責自斷雙臂,大不如前,但仍願協助風雲入魔,短時間提昇功力。步驚雲對眾武林前輩犧牲生命救他深感有愧,與聶風爭相入魔,但邪皇仍選擇聶風,盼聶風的仁心能在入魔後助自己回歸。步驚雲雖未得入魔,仍獲得無名傾囊相授,並自創出霸劍訣。此時絕無神的部下也找上步驚雲和閉關中之聶風,步驚雲擊退來敵,但聶風閉關中,第二夢不敵來敵,生死關頭,未完全入魔的聶風強行出關救第二夢,並自顧離去不知所蹤。絕無神挾持中原皇帝,欲取得龍脈,最後關頭步驚雲及時出現,大戰絕無神,正不敵間,入魔聶風神秘出現,大戰兩人,並於殺敗絕無神後,取走龍脈,不知所蹤。龍脈被奪,聶風成朝廷欽犯。步驚雲找到躲藏在聶家村,以龍脈強行鎮壓自己魔性的聶風,朝廷趁聶風魔性稍退奪回龍脈。失去龍脈的聶風魔性大熾,與步驚雲大戰,並殺了楚楚。悲憤的步驚雲使出霸劍訣擊敗聶風,洩去聶風一身魔性,但在最後關頭還是為救聶風,捨身葬崖。清醒後的聶風眼見楚楚屍首及為救自己跳崖的步驚雲,悲痛不已。

    + +

    看完後第一個感覺是:水墨好多啊!感覺好像Street Fighter Ⅳ的預告片是抄風雲Ⅱ一樣。聶風的魔氣以潑墨的方式呈現,水墨紛飛。其實整部戲表現,寫意大過寫實,絕心絕無神征服各大派的過程,都是慢動作的剪影。殺人後,則是破成碎塊消失,沒有血腥也沒有屍首。這樣的表現,完全抓緊馬榮成擅長的寫意風格,然而用在電影上是否合適,可以檢討。

    + +

    另一個感想是:郭富城和鄭伊健可以拿一比一的絕世好劍和雪飲刀揮舞,真是讓人超羨慕的啦!我也好想要等比例的絕世好劍和雪飲刀。

    + +

    對第二夢很失望。我很喜歡第二夢,雖然不漂亮,但是有能力又有智慧。所以我很期待第二夢的登場。但是蔡卓妍演來,成了可愛教主了。蔡卓妍本就可愛。但是第二夢穩重成熟智慧的感覺,全部消失了。

    + +

    不過,風雲的演技,都有可看之處。步驚雲由邪轉正的沉默與轉折,聶風由正入魔的張狂魔氣,都非常可看。第一次覺得,找鄭伊健演聶風,找郭富城演步驚雲,是對的。他們兩個,都演得太好了。

    + +

    無名你不要亂造字啊,亂造字電腦打不出來。無名說霸劍訣的霸,是雲和劍組成,可是左邊根本不是雲,是簡體的云,在古代,云根本沒有雲的意思吧!

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 166 | + 167 | + 168 | + 169 | + 170 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0169.html.en.html b/htdocs/imacat/me/diary/0169.html.en.html new file mode 120000 index 0000000..ea25c62 --- /dev/null +++ b/htdocs/imacat/me/diary/0169.html.en.html @@ -0,0 +1 @@ +0169.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0169.html.en.xhtml b/htdocs/imacat/me/diary/0169.html.en.xhtml new file mode 100644 index 0000000..d823d28 --- /dev/null +++ b/htdocs/imacat/me/diary/0169.html.en.xhtml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 169 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 169

    + +
    + +
    + +
    +
    3.28.’11. 12:11pm.
    + +

    King Kong 金剛—動物特效的視覺饗宴

    + +
    +King Kong 金剛
    +

    King Kong 金剛

    +
    + + + +

    金剛描寫在小雜耍團演出,一心想當女演員的安黛洛,因雜耍團關閉,向電影公司投履歷碰壁而走投無路,在脫衣舞場前掙扎時,碰到同樣因拍電影盜用資金走投無路,急於逃亡又缺女主角的導演卡爾丹漢,在警察來之前,和劇組一起坐上前往新加坡的走私動物貨船,實則欲探求附近的蠻荒無人島。安黛洛在船上,遇上她所崇拜,被困船上不得不一起出航的劇作家卓傑克,兩人墜入情網。在轉向尋求傳說中的島嶼時,船長接到通緝電報本欲回航,卻因濃霧迷失方向,擱淺在礁石上。趁船員修船,卡爾偷偷率領劇組登島,卻碰到蠻荒部落,劇組人員被殺,幸遭不放心的傳長率船員上岸解救。脫困後眾人急於出航,蠻荒部落趁亂摸黑擄走安黛洛,作為祭品獻給金剛。卓傑克發現後急召眾人上岸救人,安黛洛卻早一步被金剛擄走。被擄走後安黛洛裝死逃過一劫,以雜耍團學到的把戲,逗得金剛大笑。眾人上島救人,在峽谷被恐龍追逐,在獨木橋和金剛大戰後掉入河谷,在河古底被昆蟲水蛭攻擊,死傷殆盡,幸得船長率留守的一半船員解救出谷。解救後眾人回船,只剩卓傑克繼續深入救人。安黛洛看到金剛離開,聽到眾人聲響,趁機逃走時,碰上恐龍攻擊,幸得金剛解救,兩人回到金剛在懸崖的窩,一起看高空山景,發展出穩定的情誼。後來卓傑克找到安黛洛,欲逃走時被金剛發現,追逐兩人至島上部落,金剛不敵船長和眾人的麻醉劑攻擊而倒下。將金剛帶回紐約後,導演卡爾一夕翻身,帶領金剛演出馴金剛記。不願同流合污的安黛洛,到小劇場伴舞。公演夜,緩緩甦醒的金剛,看到眼前安的替身大怒,掙脫鎖鍊大鬧。卓傑克以自身引誘金剛,金剛看到卓傑克更怒,瘋狂追逐。就在卓傑克被追上之際,金剛看到聽到騷亂出來找他的安黛洛。兩人愉快地在結冰的公園池中嘻戲時,軍隊趕至砲轟。被追趕的金剛爬上紐約帝國大廈樓頂,一起看高空景致。這時空軍又追擊至,金剛爬至最頂端,不斷反抗,最終不敵而亡。

    + +

    看完後,我又上YouTube,把1933年原版金剛、1976年版金剛的片段看了一遍,作為一部向1933年原版金剛致敬的電影,2005年版金剛的故事、畫面、場景設計幾乎和1933年原版金剛一模一樣,只有特效技術不同。反而1976年版金剛,場景故事改作很大。

    + +

    和1933年原版金剛相比,1933年原版金剛是用布偶定格移動做出的場景,2005年版的金剛則是全部電腦動畫特效。2005年版的金剛是電腦動畫特效的里程碑,電腦動畫特效第一次做出根根分明,隨風搖曳,栩栩如生的動物毛皮,表面的複雜度無出其右。加上其它現代科技才做得到的效果,金剛和恐龍在半空藤蔓間及平原上的大戰、恐龍在山谷中狂奔等、在紐約街頭大鬧等,視覺效果非常震憾。

    + +

    說好看,的確是非常好看。但說比起前作有多感人肺腑,倒言過其實。1933年原版金剛之所以成為經典,金剛的破壞力和震憾力的確是主要的因素,也掩蓋了電影其它的主題。在當時,還沒有過任何類似的巨型動物大破壞的題材,所以非常震憾。但在今天,巨型動物大破壞的題材很常見,從侏儸紀公園、酷斯拉,到魔戒中的噴火龍。因為看慣了巨型動物大破壞,反而讓人能夠注意到電影的其它主題,如金剛的悲劇。但是,金剛的悲劇,原來就已經是1933年原版金剛的重要主題了,而且履履被人提及,不是2005年版的金剛才開始強調。

    + +

    而且,金剛的悲劇是人類,不是美女。這是很好笑的。女主角帶給金剛的是歡笑,不是死亡。殺死金剛的是人類的貪婪,不是女主角。這種紅顏禍水論,作為一部向原作致敬的電影,或許可被理解,但也必須被清楚指出。而且,為什麼金剛就一定是公的呢?這種假定從何而來?卓傑克看到金剛對女主角深情款款,又不知作何感想?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 167 | + 168 | + 169 | + 170 | + 171 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0169.html.zh-cn.html b/htdocs/imacat/me/diary/0169.html.zh-cn.html new file mode 120000 index 0000000..fe176ee --- /dev/null +++ b/htdocs/imacat/me/diary/0169.html.zh-cn.html @@ -0,0 +1 @@ +0169.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0169.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0169.html.zh-cn.xhtml new file mode 100644 index 0000000..4914a28 --- /dev/null +++ b/htdocs/imacat/me/diary/0169.html.zh-cn.xhtml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百六十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百六十九

    + +
    + +
    + +
    +
    3.28.’11. 12:11pm.
    + +

    King Kong 金刚—动物特效的视觉飨宴

    + +
    +King Kong 金刚
    +

    King Kong 金刚

    +
    + + + +

    金刚描写在小杂耍团演出,一心想当女演员的安黛洛,因杂耍团关闭,向电影公司投履历碰壁而走投无路,在脱衣舞场前挣扎时,碰到同样因拍电影盗用资金走投无路,急於逃亡又缺女主角的导演卡尔丹汉,在警察来之前,和剧组一起坐上前往新加坡的走私动物货船,实则欲探求附近的蛮荒无人岛。安黛洛在船上,遇上她所崇拜,被困船上不得不一起出航的剧作家卓杰克,两人坠入情网。在转向寻求传说中的岛屿时,船长接到通缉电报本欲回航,却因浓雾迷失方向,搁浅在礁石上。趁船员修船,卡尔偷偷率领剧组登岛,却碰到蛮荒部落,剧组人员被杀,幸遭不放心的传长率船员上岸解救。脱困后众人急於出航,蛮荒部落趁乱摸黑掳走安黛洛,作为祭品献给金刚。卓杰克发现后急召众人上岸救人,安黛洛却早一步被金刚掳走。被掳走后安黛洛装死逃过一劫,以杂耍团学到的把戏,逗得金刚大笑。众人上岛救人,在峡谷被恐龙追逐,在独木桥和金刚大战后掉入河谷,在河古底被昆虫水蛭攻击,死伤殆尽,幸得船长率留守的一半船员解救出谷。解救后众人回船,只剩卓杰克继续深入救人。安黛洛看到金刚离开,听到众人声响,趁机逃走时,碰上恐龙攻击,幸得金刚解救,两人回到金刚在悬崖的窝,一起看高空山景,发展出稳定的情谊。后来卓杰克找到安黛洛,欲逃走时被金刚发现,追逐两人至岛上部落,金刚不敌船长和众人的麻醉剂攻击而倒下。将金刚带回纽约后,导演卡尔一夕翻身,带领金刚演出驯金刚记。不愿同流合污的安黛洛,到小剧场伴舞。公演夜,缓缓苏醒的金刚,看到眼前安的替身大怒,挣脱锁炼大闹。卓杰克以自身引诱金刚,金刚看到卓杰克更怒,疯狂追逐。就在卓杰克被追上之际,金刚看到听到骚乱出来找他的安黛洛。两人愉快地在结冰的公园池中嘻戏时,军队赶至炮轰。被追赶的金刚爬上纽约帝国大厦楼顶,一起看高空景致。这时空军又追击至,金刚爬至最顶端,不断反抗,最终不敌而亡。

    + +

    看完后,我又上YouTube,把1933年原版金刚、1976年版金刚的片段看了一遍,作为一部向1933年原版金刚致敬的电影,2005年版金刚的故事、画面、场景设计几乎和1933年原版金刚一模一样,只有特效技术不同。反而1976年版金刚,场景故事改作很大。

    + +

    和1933年原版金刚相比,1933年原版金刚是用布偶定格移动做出的场景,2005年版的金刚则是全部电脑动画特效。2005年版的金刚是电脑动画特效的里程碑,电脑动画特效第一次做出根根分明,随风摇曳,栩栩如生的动物毛皮,表面的复杂度无出其右。加上其它现代科技才做得到的效果,金刚和恐龙在半空藤蔓间及平原上的大战、恐龙在山谷中狂奔等、在纽约街头大闹等,视觉效果非常震憾。

    + +

    说好看,的确是非常好看。但说比起前作有多感人肺腑,倒言过其实。1933年原版金刚之所以成为经典,金刚的破坏力和震憾力的确是主要的因素,也掩盖了电影其它的主题。在当时,还没有过任何类似的巨型动物大破坏的题材,所以非常震憾。但在今天,巨型动物大破坏的题材很常见,从侏罗纪公园、酷斯拉,到魔戒中的喷火龙。因为看惯了巨型动物大破坏,反而让人能够注意到电影的其它主题,如金刚的悲剧。但是,金刚的悲剧,原来就已经是1933年原版金刚的重要主题了,而且履履被人提及,不是2005年版的金刚才开始强调。

    + +

    而且,金刚的悲剧是人类,不是美女。这是很好笑的。女主角带给金刚的是欢笑,不是死亡。杀死金刚的是人类的贪婪,不是女主角。这种红颜祸水论,作为一部向原作致敬的电影,或许可被理解,但也必须被清楚指出。而且,为什么金刚就一定是公的呢?这种假定从何而来?卓杰克看到金刚对女主角深情款款,又不知作何感想?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 167 | + 168 | + 169 | + 170 | + 171 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0169.html.zh-tw.html b/htdocs/imacat/me/diary/0169.html.zh-tw.html new file mode 120000 index 0000000..6925a75 --- /dev/null +++ b/htdocs/imacat/me/diary/0169.html.zh-tw.html @@ -0,0 +1 @@ +0169.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0169.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0169.html.zh-tw.xhtml new file mode 100644 index 0000000..a276cb2 --- /dev/null +++ b/htdocs/imacat/me/diary/0169.html.zh-tw.xhtml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百六十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百六十九

    + +
    + +
    + +
    +
    3.28.’11. 12:11pm.
    + +

    King Kong 金剛—動物特效的視覺饗宴

    + +
    +King Kong 金剛
    +

    King Kong 金剛

    +
    + + + +

    金剛描寫在小雜耍團演出,一心想當女演員的安黛洛,因雜耍團關閉,向電影公司投履歷碰壁而走投無路,在脫衣舞場前掙扎時,碰到同樣因拍電影盜用資金走投無路,急於逃亡又缺女主角的導演卡爾丹漢,在警察來之前,和劇組一起坐上前往新加坡的走私動物貨船,實則欲探求附近的蠻荒無人島。安黛洛在船上,遇上她所崇拜,被困船上不得不一起出航的劇作家卓傑克,兩人墜入情網。在轉向尋求傳說中的島嶼時,船長接到通緝電報本欲回航,卻因濃霧迷失方向,擱淺在礁石上。趁船員修船,卡爾偷偷率領劇組登島,卻碰到蠻荒部落,劇組人員被殺,幸遭不放心的傳長率船員上岸解救。脫困後眾人急於出航,蠻荒部落趁亂摸黑擄走安黛洛,作為祭品獻給金剛。卓傑克發現後急召眾人上岸救人,安黛洛卻早一步被金剛擄走。被擄走後安黛洛裝死逃過一劫,以雜耍團學到的把戲,逗得金剛大笑。眾人上島救人,在峽谷被恐龍追逐,在獨木橋和金剛大戰後掉入河谷,在河古底被昆蟲水蛭攻擊,死傷殆盡,幸得船長率留守的一半船員解救出谷。解救後眾人回船,只剩卓傑克繼續深入救人。安黛洛看到金剛離開,聽到眾人聲響,趁機逃走時,碰上恐龍攻擊,幸得金剛解救,兩人回到金剛在懸崖的窩,一起看高空山景,發展出穩定的情誼。後來卓傑克找到安黛洛,欲逃走時被金剛發現,追逐兩人至島上部落,金剛不敵船長和眾人的麻醉劑攻擊而倒下。將金剛帶回紐約後,導演卡爾一夕翻身,帶領金剛演出馴金剛記。不願同流合污的安黛洛,到小劇場伴舞。公演夜,緩緩甦醒的金剛,看到眼前安的替身大怒,掙脫鎖鍊大鬧。卓傑克以自身引誘金剛,金剛看到卓傑克更怒,瘋狂追逐。就在卓傑克被追上之際,金剛看到聽到騷亂出來找他的安黛洛。兩人愉快地在結冰的公園池中嘻戲時,軍隊趕至砲轟。被追趕的金剛爬上紐約帝國大廈樓頂,一起看高空景致。這時空軍又追擊至,金剛爬至最頂端,不斷反抗,最終不敵而亡。

    + +

    看完後,我又上YouTube,把1933年原版金剛、1976年版金剛的片段看了一遍,作為一部向1933年原版金剛致敬的電影,2005年版金剛的故事、畫面、場景設計幾乎和1933年原版金剛一模一樣,只有特效技術不同。反而1976年版金剛,場景故事改作很大。

    + +

    和1933年原版金剛相比,1933年原版金剛是用布偶定格移動做出的場景,2005年版的金剛則是全部電腦動畫特效。2005年版的金剛是電腦動畫特效的里程碑,電腦動畫特效第一次做出根根分明,隨風搖曳,栩栩如生的動物毛皮,表面的複雜度無出其右。加上其它現代科技才做得到的效果,金剛和恐龍在半空藤蔓間及平原上的大戰、恐龍在山谷中狂奔等、在紐約街頭大鬧等,視覺效果非常震憾。

    + +

    說好看,的確是非常好看。但說比起前作有多感人肺腑,倒言過其實。1933年原版金剛之所以成為經典,金剛的破壞力和震憾力的確是主要的因素,也掩蓋了電影其它的主題。在當時,還沒有過任何類似的巨型動物大破壞的題材,所以非常震憾。但在今天,巨型動物大破壞的題材很常見,從侏儸紀公園、酷斯拉,到魔戒中的噴火龍。因為看慣了巨型動物大破壞,反而讓人能夠注意到電影的其它主題,如金剛的悲劇。但是,金剛的悲劇,原來就已經是1933年原版金剛的重要主題了,而且履履被人提及,不是2005年版的金剛才開始強調。

    + +

    而且,金剛的悲劇是人類,不是美女。這是很好笑的。女主角帶給金剛的是歡笑,不是死亡。殺死金剛的是人類的貪婪,不是女主角。這種紅顏禍水論,作為一部向原作致敬的電影,或許可被理解,但也必須被清楚指出。而且,為什麼金剛就一定是公的呢?這種假定從何而來?卓傑克看到金剛對女主角深情款款,又不知作何感想?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 167 | + 168 | + 169 | + 170 | + 171 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0170.html.en.html b/htdocs/imacat/me/diary/0170.html.en.html new file mode 120000 index 0000000..e7d1bd0 --- /dev/null +++ b/htdocs/imacat/me/diary/0170.html.en.html @@ -0,0 +1 @@ +0170.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0170.html.en.xhtml b/htdocs/imacat/me/diary/0170.html.en.xhtml new file mode 100644 index 0000000..1482cd0 --- /dev/null +++ b/htdocs/imacat/me/diary/0170.html.en.xhtml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 170 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 170

    + +
    + +
    + +
    +
    3.28.’11. 7:38pm.
    + +

    Transformers 變形金剛—動物特效的視覺饗宴

    + +
    +Transformers 變形金剛
    +

    Transformers 變形金剛

    +
    + + + +

    變形金剛描述卡達的美軍基地發現已墜毀的直昇機入侵,正調查間,直昇機突然變身成狂派變形金剛黑魔攻擊,催毀了美軍基地。魏山姆存錢想買車,在eBay上以LadiesMan217拍賣爺爺北極探險的遺物,雖然乏人問津,卻因為眼鏡上的記號,引起博派和狂派變形金剛的注意。後來他在爸爸幫助下買了車,沒想到買的其實是博派變形金剛大黃蜂。他靠大黃蜂協助得已接近蜜琪,卻意外發現大黃蜂是變形金剛,並認識博派的其他人:柯博文、爵士、鐵皮、飛輪等人,了解事情的來龍去脈。原來爺爺當年發現了墜落北極的狂派首領密卡登,及變形金剛的能量來源火種源,無意間啟動了被冰凍的密卡登,當地座標被刻畫在眼鏡上,成為狂派和博派爭奪的目標。他決定回家找爺爺的眼鏡。而狂派變形金剛疾瘋化身成收錄音機,潛入空軍一號入侵探查,發現了山姆爺爺眼鏡的秘密。遭到攻擊的美國軍方召集駭客破解卡達基地的錄音,駭客瑪姬抵檔了疾瘋的攻擊後,發現奇怪的資訊,偷偷帶出給駭客朋友葛倫分析,也發現了山姆爺爺的秘密。山姆回家找到爺爺的眼鏡後,全家被神秘的政府第七部門帶走,途中大黃蜂企圖救出山姆,卻失敗被擄。同時卡達基地倖存的部隊在嘗試連絡基地途中又被狂派的蠍子攻擊,所幸及時和部隊取得連絡,在空軍協助下,打敗蠍子。山姆、蜜琪、大黃蜂、瑪姬、葛倫、卡達的殘存部隊全被帶到胡佛水壩下的秘密基地,原來八十年代,密卡登和火種源早已被胡佛總統成立的神秘第七部門秘密移置於此,並在秘密基地上面蓋水壩掩護。這時,狂派和博派的變形金剛,也逐漸聚及於此。秘密潛入第七部門基地的疾瘋破壞了軍方網路,解除了密卡登的冰凍,眼看基地不保,眾人決定帶火種源移至附近的米辛市最後決戰。在米辛市,眾人經過一番激戰,博派不敵,柯博文請山姆把火種源放進自身體內,決定與火種源同歸於盡,山姆臨機一動把火種源放入密卡登體內,密卡登無力承受而死亡。

    + +

    變形金剛的變形特效非常精彩。我查了維基百科,才知道變形金剛就是我高中時候開始出現的變形組合機器人。可是那時候我已經比較少玩機器人玩具了,所以不大瞭解,後來甚至為了配合玩具,而建構出一整套的世界觀和卡通故事。

    + +

    以從遊戲玩具改編的電影而言,變形金剛做得相當不錯。賦與人物個性的同時,又不會顯得太牽強。我這樣說,說不定是因為我沒看過卡通的緣故。看過卡通的人,聽說批評不少。

    + +

    不過,變形的畫面轉得太快,眼睛常常跟不上。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 168 | + 169 | + 170 | + 171 | + 172 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0170.html.zh-cn.html b/htdocs/imacat/me/diary/0170.html.zh-cn.html new file mode 120000 index 0000000..9ee438c --- /dev/null +++ b/htdocs/imacat/me/diary/0170.html.zh-cn.html @@ -0,0 +1 @@ +0170.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0170.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0170.html.zh-cn.xhtml new file mode 100644 index 0000000..404db60 --- /dev/null +++ b/htdocs/imacat/me/diary/0170.html.zh-cn.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百七十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百七十

    + +
    + +
    + +
    +
    3.28.’11. 7:38pm.
    + +

    Transformers 变形金刚—动物特效的视觉飨宴

    + +
    +Transformers 变形金刚
    +

    Transformers 变形金刚

    +
    + + + +

    变形金刚描述卡达的美军基地发现已坠毁的直升机入侵,正调查间,直升机突然变身成狂派变形金刚黑魔攻击,催毁了美军基地。魏山姆存钱想买车,在eBay上以LadiesMan217拍卖爷爷北极探险的遗物,虽然乏人问津,却因为眼镜上的记号,引起博派和狂派变形金刚的注意。后来他在爸爸帮助下买了车,没想到买的其实是博派变形金刚大黄蜂。他靠大黄蜂协助得已接近蜜琪,却意外发现大黄蜂是变形金刚,并认识博派的其他人:柯博文、爵士、铁皮、飞轮等人,了解事情的来龙去脉。原来爷爷当年发现了坠落北极的狂派首领密卡登,及变形金刚的能量来源火种源,无意间启动了被冰冻的密卡登,当地座标被刻画在眼镜上,成为狂派和博派争夺的目标。他决定回家找爷爷的眼镜。而狂派变形金刚疾疯化身成收录音机,潜入空军一号入侵探查,发现了山姆爷爷眼镜的秘密。遭到攻击的美国军方召集骇客破解卡达基地的录音,骇客玛姬抵档了疾疯的攻击后,发现奇怪的资讯,偷偷带出给骇客朋友葛伦分析,也发现了山姆爷爷的秘密。山姆回家找到爷爷的眼镜后,全家被神秘的政府第七部门带走,途中大黄蜂企图救出山姆,却失败被掳。同时卡达基地幸存的部队在尝试连络基地途中又被狂派的蝎子攻击,所幸及时和部队取得连络,在空军协助下,打败蝎子。山姆、蜜琪、大黄蜂、玛姬、葛伦、卡达的残存部队全被带到胡佛水坝下的秘密基地,原来八十年代,密卡登和火种源早已被胡佛总统成立的神秘第七部门秘密移置於此,并在秘密基地上面盖水坝掩护。这时,狂派和博派的变形金刚,也逐渐聚及於此。秘密潜入第七部门基地的疾疯破坏了军方网路,解除了密卡登的冰冻,眼看基地不保,众人决定带火种源移至附近的米辛市最后决战。在米辛市,众人经过一番激战,博派不敌,柯博文请山姆把火种源放进自身体内,决定与火种源同归於尽,山姆临机一动把火种源放入密卡登体内,密卡登无力承受而死亡。

    + +

    变形金刚的变形特效非常精彩。我查了维基百科,才知道变形金刚就是我高中时候开始出现的变形组合机器人。可是那时候我已经比较少玩机器人玩具了,所以不大了解,后来甚至为了配合玩具,而建构出一整套的世界观和卡通故事。

    + +

    以从游戏玩具改编的电影而言,变形金刚做得相当不错。赋与人物个性的同时,又不会显得太牵强。我这样说,说不定是因为我没看过卡通的缘故。看过卡通的人,听说批评不少。

    + +

    不过,变形的画面转得太快,眼睛常常跟不上。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 168 | + 169 | + 170 | + 171 | + 172 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0170.html.zh-tw.html b/htdocs/imacat/me/diary/0170.html.zh-tw.html new file mode 120000 index 0000000..930f72c --- /dev/null +++ b/htdocs/imacat/me/diary/0170.html.zh-tw.html @@ -0,0 +1 @@ +0170.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0170.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0170.html.zh-tw.xhtml new file mode 100644 index 0000000..9157cd2 --- /dev/null +++ b/htdocs/imacat/me/diary/0170.html.zh-tw.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百七十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百七十

    + +
    + +
    + +
    +
    3.28.’11. 7:38pm.
    + +

    Transformers 變形金剛—動物特效的視覺饗宴

    + +
    +Transformers 變形金剛
    +

    Transformers 變形金剛

    +
    + + + +

    變形金剛描述卡達的美軍基地發現已墜毀的直昇機入侵,正調查間,直昇機突然變身成狂派變形金剛黑魔攻擊,催毀了美軍基地。魏山姆存錢想買車,在eBay上以LadiesMan217拍賣爺爺北極探險的遺物,雖然乏人問津,卻因為眼鏡上的記號,引起博派和狂派變形金剛的注意。後來他在爸爸幫助下買了車,沒想到買的其實是博派變形金剛大黃蜂。他靠大黃蜂協助得已接近蜜琪,卻意外發現大黃蜂是變形金剛,並認識博派的其他人:柯博文、爵士、鐵皮、飛輪等人,了解事情的來龍去脈。原來爺爺當年發現了墜落北極的狂派首領密卡登,及變形金剛的能量來源火種源,無意間啟動了被冰凍的密卡登,當地座標被刻畫在眼鏡上,成為狂派和博派爭奪的目標。他決定回家找爺爺的眼鏡。而狂派變形金剛疾瘋化身成收錄音機,潛入空軍一號入侵探查,發現了山姆爺爺眼鏡的秘密。遭到攻擊的美國軍方召集駭客破解卡達基地的錄音,駭客瑪姬抵檔了疾瘋的攻擊後,發現奇怪的資訊,偷偷帶出給駭客朋友葛倫分析,也發現了山姆爺爺的秘密。山姆回家找到爺爺的眼鏡後,全家被神秘的政府第七部門帶走,途中大黃蜂企圖救出山姆,卻失敗被擄。同時卡達基地倖存的部隊在嘗試連絡基地途中又被狂派的蠍子攻擊,所幸及時和部隊取得連絡,在空軍協助下,打敗蠍子。山姆、蜜琪、大黃蜂、瑪姬、葛倫、卡達的殘存部隊全被帶到胡佛水壩下的秘密基地,原來八十年代,密卡登和火種源早已被胡佛總統成立的神秘第七部門秘密移置於此,並在秘密基地上面蓋水壩掩護。這時,狂派和博派的變形金剛,也逐漸聚及於此。秘密潛入第七部門基地的疾瘋破壞了軍方網路,解除了密卡登的冰凍,眼看基地不保,眾人決定帶火種源移至附近的米辛市最後決戰。在米辛市,眾人經過一番激戰,博派不敵,柯博文請山姆把火種源放進自身體內,決定與火種源同歸於盡,山姆臨機一動把火種源放入密卡登體內,密卡登無力承受而死亡。

    + +

    變形金剛的變形特效非常精彩。我查了維基百科,才知道變形金剛就是我高中時候開始出現的變形組合機器人。可是那時候我已經比較少玩機器人玩具了,所以不大瞭解,後來甚至為了配合玩具,而建構出一整套的世界觀和卡通故事。

    + +

    以從遊戲玩具改編的電影而言,變形金剛做得相當不錯。賦與人物個性的同時,又不會顯得太牽強。我這樣說,說不定是因為我沒看過卡通的緣故。看過卡通的人,聽說批評不少。

    + +

    不過,變形的畫面轉得太快,眼睛常常跟不上。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 168 | + 169 | + 170 | + 171 | + 172 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0171.html.en.html b/htdocs/imacat/me/diary/0171.html.en.html new file mode 120000 index 0000000..c4c1b61 --- /dev/null +++ b/htdocs/imacat/me/diary/0171.html.en.html @@ -0,0 +1 @@ +0171.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0171.html.en.xhtml b/htdocs/imacat/me/diary/0171.html.en.xhtml new file mode 100644 index 0000000..ae85945 --- /dev/null +++ b/htdocs/imacat/me/diary/0171.html.en.xhtml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 171 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 171

    + +
    + +
    + +
    +
    3.29.’11. 3:08am.
    + +

    Shortbus 性愛巴士—性、愛和自我的探索

    + +
    +Shortbus 性愛巴士
    +

    Shortbus 性愛巴士

    +
    + + + +

    性愛巴士描述一段段追求性、愛與自我探索的旅程。蘇菲是一個伴侶治療師,在輔導詹米和詹姆斯的時候,意外吐露自己從未高潮過。在詹米和詹姆斯介紹之下,來到性愛巴士俱樂部。詹姆斯曾經是男妓,直到遇見詹米才轉行當救生員,喜歡錄影自拍,詹米是演員,兩人穩定地交往了兩年,詹姆士突然要求嘗試開放關係,兩人在性愛巴士遇到開喜,開始嘗試三人行。獨來獨往的莎莎本名和明星珍妮佛安妮斯頓同名,以SM為生,希望有一天能成為藝術創作者,總是隨身攜帶拍立得,除了客人以外,沒有辦法和人建立關係。某日詹姆斯突然自殺,被對門鄰居救起,才發現已經被偷窺了兩年。詹姆斯才吐露他沒有辦法感受到別人的愛,希望新加入的沙士能讓詹米幸福。蘇菲和莎莎開始交談,傾訴自我,開始用不同的方式嚐試高潮。她才知道其實丈夫羅柏早就知道她在假裝高潮,也帶丈夫羅柏一起進性愛巴士。直到最後,在和性愛房一對情侶的性愛中,達到高潮。

    + +

    明明是限制級的電影,只限成人觀賞了,還噴霧噴得到處都是,感覺超差。新聞局很無聊。觀眾都是成人了,什麼沒有看過,有什麼好噴霧的?

    + +

    即使如此,還是很好看。劇本是演員在拍攝中集體蘊釀出來的。性愛巴士裏,一段段追求性、愛和自我的過程,從困惑、嚐試到獲得。勇敢努力追求嚐試的過程,流下的眼淚中,每個人也都更了解了自己。影片的最後,莎莎還是沒有找到自己的答案,讓人覺得可惜。然而現實生活中,也不一定找得到答案。

    + +

    電影拍攝試鏡時,收到超過五百封以上的應徵影片。這個社會上是不是有更多看不見的人,希望能夠尋找著自己的答案呢?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 169 | + 170 | + 171 | + 172 | + 173 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0171.html.zh-cn.html b/htdocs/imacat/me/diary/0171.html.zh-cn.html new file mode 120000 index 0000000..5fde4e0 --- /dev/null +++ b/htdocs/imacat/me/diary/0171.html.zh-cn.html @@ -0,0 +1 @@ +0171.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0171.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0171.html.zh-cn.xhtml new file mode 100644 index 0000000..362beed --- /dev/null +++ b/htdocs/imacat/me/diary/0171.html.zh-cn.xhtml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百七十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百七十一

    + +
    + +
    + +
    +
    3.29.’11. 3:08am.
    + +

    Shortbus 性爱巴士—性、爱和自我的探索

    + +
    +Shortbus 性爱巴士
    +

    Shortbus 性爱巴士

    +
    + + + +

    性爱巴士描述一段段追求性、爱与自我探索的旅程。苏菲是一个伴侣治疗师,在辅导詹米和詹姆斯的时候,意外吐露自己从未高潮过。在詹米和詹姆斯介绍之下,来到性爱巴士俱乐部。詹姆斯曾经是男妓,直到遇见詹米才转行当救生员,喜欢录影自拍,詹米是演员,两人稳定地交往了两年,詹姆士突然要求尝试开放关系,两人在性爱巴士遇到开喜,开始尝试三人行。独来独往的莎莎本名和明星珍妮佛安妮斯顿同名,以SM为生,希望有一天能成为艺术创作者,总是随身携带拍立得,除了客人以外,没有办法和人建立关系。某日詹姆斯突然自杀,被对门邻居救起,才发现已经被偷窥了两年。詹姆斯才吐露他没有办法感受到别人的爱,希望新加入的沙士能让詹米幸福。苏菲和莎莎开始交谈,倾诉自我,开始用不同的方式尝试高潮。她才知道其实丈夫罗柏早就知道她在假装高潮,也带丈夫罗柏一起进性爱巴士。直到最后,在和性爱房一对情侣的性爱中,达到高潮。

    + +

    明明是限制级的电影,只限成人观赏了,还喷雾喷得到处都是,感觉超差。新闻局很无聊。观众都是成人了,什么没有看过,有什么好喷雾的?

    + +

    即使如此,还是很好看。剧本是演员在拍摄中集体蕴酿出来的。性爱巴士里,一段段追求性、爱和自我的过程,从困惑、尝试到获得。勇敢努力追求尝试的过程,流下的眼泪中,每个人也都更了解了自己。影片的最后,莎莎还是没有找到自己的答案,让人觉得可惜。然而现实生活中,也不一定找得到答案。

    + +

    电影拍摄试镜时,收到超过五百封以上的应徵影片。这个社会上是不是有更多看不见的人,希望能够寻找著自己的答案呢?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 169 | + 170 | + 171 | + 172 | + 173 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0171.html.zh-tw.html b/htdocs/imacat/me/diary/0171.html.zh-tw.html new file mode 120000 index 0000000..c612b3d --- /dev/null +++ b/htdocs/imacat/me/diary/0171.html.zh-tw.html @@ -0,0 +1 @@ +0171.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0171.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0171.html.zh-tw.xhtml new file mode 100644 index 0000000..a56775f --- /dev/null +++ b/htdocs/imacat/me/diary/0171.html.zh-tw.xhtml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百七十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百七十一

    + +
    + +
    + +
    +
    3.29.’11. 3:08am.
    + +

    Shortbus 性愛巴士—性、愛和自我的探索

    + +
    +Shortbus 性愛巴士
    +

    Shortbus 性愛巴士

    +
    + + + +

    性愛巴士描述一段段追求性、愛與自我探索的旅程。蘇菲是一個伴侶治療師,在輔導詹米和詹姆斯的時候,意外吐露自己從未高潮過。在詹米和詹姆斯介紹之下,來到性愛巴士俱樂部。詹姆斯曾經是男妓,直到遇見詹米才轉行當救生員,喜歡錄影自拍,詹米是演員,兩人穩定地交往了兩年,詹姆士突然要求嘗試開放關係,兩人在性愛巴士遇到開喜,開始嘗試三人行。獨來獨往的莎莎本名和明星珍妮佛安妮斯頓同名,以SM為生,希望有一天能成為藝術創作者,總是隨身攜帶拍立得,除了客人以外,沒有辦法和人建立關係。某日詹姆斯突然自殺,被對門鄰居救起,才發現已經被偷窺了兩年。詹姆斯才吐露他沒有辦法感受到別人的愛,希望新加入的沙士能讓詹米幸福。蘇菲和莎莎開始交談,傾訴自我,開始用不同的方式嚐試高潮。她才知道其實丈夫羅柏早就知道她在假裝高潮,也帶丈夫羅柏一起進性愛巴士。直到最後,在和性愛房一對情侶的性愛中,達到高潮。

    + +

    明明是限制級的電影,只限成人觀賞了,還噴霧噴得到處都是,感覺超差。新聞局很無聊。觀眾都是成人了,什麼沒有看過,有什麼好噴霧的?

    + +

    即使如此,還是很好看。劇本是演員在拍攝中集體蘊釀出來的。性愛巴士裏,一段段追求性、愛和自我的過程,從困惑、嚐試到獲得。勇敢努力追求嚐試的過程,流下的眼淚中,每個人也都更了解了自己。影片的最後,莎莎還是沒有找到自己的答案,讓人覺得可惜。然而現實生活中,也不一定找得到答案。

    + +

    電影拍攝試鏡時,收到超過五百封以上的應徵影片。這個社會上是不是有更多看不見的人,希望能夠尋找著自己的答案呢?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 169 | + 170 | + 171 | + 172 | + 173 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0172.html.en.html b/htdocs/imacat/me/diary/0172.html.en.html new file mode 120000 index 0000000..3d3e011 --- /dev/null +++ b/htdocs/imacat/me/diary/0172.html.en.html @@ -0,0 +1 @@ +0172.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0172.html.en.xhtml b/htdocs/imacat/me/diary/0172.html.en.xhtml new file mode 100644 index 0000000..0624b0e --- /dev/null +++ b/htdocs/imacat/me/diary/0172.html.en.xhtml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 172 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 172

    + +
    + +
    + +
    +
    3.30.’11. 1:35am.
    + +

    Slumdog Millionaire 貧民百萬富翁—精彩感人的生命故事

    + +
    +Slumdog Millionaire 貧民百萬富翁
    +

    Slumdog Millionaire 貧民百萬富翁

    +
    + + + +

    貧民百萬富翁描寫貧窮、沒受過教育的電話客服茶水助理傑默,參加百萬大富翁節目,跌破所有人眼鏡,克服到前所未有的最後一關,累積一千萬盧比獎金。沒想到當晚,即被警察以詐欺罪嫌抓走。在警察詢問下,傑默敘述起他自己的故事。原來每一題題目,都正巧是他生命中的血淚故事:傑默小時候為讓大明星簽名而掉進糞坑,母親在教派衝突中被殺害,和哥哥薩林流落街頭,認識同樣無依靠的女孩拉蒂卡,被乞丐集團誘拐,差點被動手術殘障而逃亡,卻無力帶走拉蒂卡。傑默後來和哥哥薩林流落到泰姬瑪哈陵靠詐騙觀光客為生。時時掛記拉蒂卡的傑默,在紅燈區找到拉蒂卡,要逃亡時被乞丐集團老大馬曼發現,薩林殺了馬曼後三人逃亡。為求自保,薩林投靠貧民窟老大札威,並趕走傑默。數年後傑默後來成為電話客服茶水助理,從公司資料庫找到薩林,發現拉蒂卡早已淪為札威禁臠。傑默和拉蒂卡約好私奔,札威得知,派薩林強行帶回拉蒂卡。知道拉蒂卡愛看百萬大富翁,傑默報名參加,希望能讓拉蒂卡看到自己。警察在查無實證下,放了傑默。最後一題之夜,薩林、拉蒂卡看到傑默出場,薩林決定協助拉蒂卡逃亡以贖罪,並將自己手機贈予拉蒂卡。拉蒂卡非奔至電視台的路上塞車,困在路中央。最後一題三劍客的名字,傑默完全不會,使用外撥朋友求助。他想外撥哥哥薩林,卻無意中接通拉蒂卡。欣喜之餘,拉蒂卡同樣也不知道答案。傑默決定賭上全部的運氣。結果證明,上天註定他會完成比賽,也註定能和拉蒂卡重逢相守。

    + +

    貧民百萬富翁的故事敘事手法,非常有趣。隨著問答節目題目的進行,傑默的人生一幕幕展現在眼前。狂歡的現場觀眾和狡獪的主持人間,是傑默沉重得不能再沉重的血淚人生。這一切都是註定的,對幾乎未受教育的傑默,每一題題目,都正正是他的血淚經驗。

    + +

    這樣的敘事方式,前所未有。真的很好看,難怪是2008年最受囑目的電影。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 170 | + 171 | + 172 | + 173 | + 174 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0172.html.zh-cn.html b/htdocs/imacat/me/diary/0172.html.zh-cn.html new file mode 120000 index 0000000..34612b6 --- /dev/null +++ b/htdocs/imacat/me/diary/0172.html.zh-cn.html @@ -0,0 +1 @@ +0172.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0172.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0172.html.zh-cn.xhtml new file mode 100644 index 0000000..e6acfdd --- /dev/null +++ b/htdocs/imacat/me/diary/0172.html.zh-cn.xhtml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百七十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百七十二

    + +
    + +
    + +
    +
    3.30.’11. 1:35am.
    + +

    Slumdog Millionaire 贫民百万富翁—精彩感人的生命故事

    + +
    +Slumdog Millionaire 贫民百万富翁
    +

    Slumdog Millionaire 贫民百万富翁

    +
    + + + +

    贫民百万富翁描写贫穷、没受过教育的电话客服茶水助理杰默,参加百万大富翁节目,跌破所有人眼镜,克服到前所未有的最后一关,累积一千万卢比奖金。没想到当晚,即被警察以诈欺罪嫌抓走。在警察询问下,杰默叙述起他自己的故事。原来每一题题目,都正巧是他生命中的血泪故事:杰默小时候为让大明星签名而掉进粪坑,母亲在教派冲突中被杀害,和哥哥萨林流落街头,认识同样无依靠的女孩拉蒂卡,被乞丐集团诱拐,差点被动手术残障而逃亡,却无力带走拉蒂卡。杰默后来和哥哥萨林流落到泰姬玛哈陵靠诈骗观光客为生。时时挂记拉蒂卡的杰默,在红灯区找到拉蒂卡,要逃亡时被乞丐集团老大马曼发现,萨林杀了马曼后三人逃亡。为求自保,萨林投靠贫民窟老大札威,并赶走杰默。数年后杰默后来成为电话客服茶水助理,从公司资料库找到萨林,发现拉蒂卡早已沦为札威禁脔。杰默和拉蒂卡约好私奔,札威得知,派萨林强行带回拉蒂卡。知道拉蒂卡爱看百万大富翁,杰默报名参加,希望能让拉蒂卡看到自己。警察在查无实证下,放了杰默。最后一题之夜,萨林、拉蒂卡看到杰默出场,萨林决定协助拉蒂卡逃亡以赎罪,并将自己手机赠予拉蒂卡。拉蒂卡非奔至电视台的路上塞车,困在路中央。最后一题三剑客的名字,杰默完全不会,使用外拨朋友求助。他想外拨哥哥萨林,却无意中接通拉蒂卡。欣喜之余,拉蒂卡同样也不知道答案。杰默决定赌上全部的运气。结果证明,上天注定他会完成比赛,也注定能和拉蒂卡重逢相守。

    + +

    贫民百万富翁的故事叙事手法,非常有趣。随著问答节目题目的进行,杰默的人生一幕幕展现在眼前。狂欢的现场观众和狡狯的主持人间,是杰默沉重得不能再沉重的血泪人生。这一切都是注定的,对几乎未受教育的杰默,每一题题目,都正正是他的血泪经验。

    + +

    这样的叙事方式,前所未有。真的很好看,难怪是2008年最受嘱目的电影。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 170 | + 171 | + 172 | + 173 | + 174 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0172.html.zh-tw.html b/htdocs/imacat/me/diary/0172.html.zh-tw.html new file mode 120000 index 0000000..9608cda --- /dev/null +++ b/htdocs/imacat/me/diary/0172.html.zh-tw.html @@ -0,0 +1 @@ +0172.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0172.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0172.html.zh-tw.xhtml new file mode 100644 index 0000000..e7b4a88 --- /dev/null +++ b/htdocs/imacat/me/diary/0172.html.zh-tw.xhtml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百七十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百七十二

    + +
    + +
    + +
    +
    3.30.’11. 1:35am.
    + +

    Slumdog Millionaire 貧民百萬富翁—精彩感人的生命故事

    + +
    +Slumdog Millionaire 貧民百萬富翁
    +

    Slumdog Millionaire 貧民百萬富翁

    +
    + + + +

    貧民百萬富翁描寫貧窮、沒受過教育的電話客服茶水助理傑默,參加百萬大富翁節目,跌破所有人眼鏡,克服到前所未有的最後一關,累積一千萬盧比獎金。沒想到當晚,即被警察以詐欺罪嫌抓走。在警察詢問下,傑默敘述起他自己的故事。原來每一題題目,都正巧是他生命中的血淚故事:傑默小時候為讓大明星簽名而掉進糞坑,母親在教派衝突中被殺害,和哥哥薩林流落街頭,認識同樣無依靠的女孩拉蒂卡,被乞丐集團誘拐,差點被動手術殘障而逃亡,卻無力帶走拉蒂卡。傑默後來和哥哥薩林流落到泰姬瑪哈陵靠詐騙觀光客為生。時時掛記拉蒂卡的傑默,在紅燈區找到拉蒂卡,要逃亡時被乞丐集團老大馬曼發現,薩林殺了馬曼後三人逃亡。為求自保,薩林投靠貧民窟老大札威,並趕走傑默。數年後傑默後來成為電話客服茶水助理,從公司資料庫找到薩林,發現拉蒂卡早已淪為札威禁臠。傑默和拉蒂卡約好私奔,札威得知,派薩林強行帶回拉蒂卡。知道拉蒂卡愛看百萬大富翁,傑默報名參加,希望能讓拉蒂卡看到自己。警察在查無實證下,放了傑默。最後一題之夜,薩林、拉蒂卡看到傑默出場,薩林決定協助拉蒂卡逃亡以贖罪,並將自己手機贈予拉蒂卡。拉蒂卡非奔至電視台的路上塞車,困在路中央。最後一題三劍客的名字,傑默完全不會,使用外撥朋友求助。他想外撥哥哥薩林,卻無意中接通拉蒂卡。欣喜之餘,拉蒂卡同樣也不知道答案。傑默決定賭上全部的運氣。結果證明,上天註定他會完成比賽,也註定能和拉蒂卡重逢相守。

    + +

    貧民百萬富翁的故事敘事手法,非常有趣。隨著問答節目題目的進行,傑默的人生一幕幕展現在眼前。狂歡的現場觀眾和狡獪的主持人間,是傑默沉重得不能再沉重的血淚人生。這一切都是註定的,對幾乎未受教育的傑默,每一題題目,都正正是他的血淚經驗。

    + +

    這樣的敘事方式,前所未有。真的很好看,難怪是2008年最受囑目的電影。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 170 | + 171 | + 172 | + 173 | + 174 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0173.html.en.html b/htdocs/imacat/me/diary/0173.html.en.html new file mode 120000 index 0000000..4a13656 --- /dev/null +++ b/htdocs/imacat/me/diary/0173.html.en.html @@ -0,0 +1 @@ +0173.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0173.html.en.xhtml b/htdocs/imacat/me/diary/0173.html.en.xhtml new file mode 100644 index 0000000..cd778d8 --- /dev/null +++ b/htdocs/imacat/me/diary/0173.html.en.xhtml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 173 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 173

    + +
    + +
    + +
    +
    3.31.’11. 4:24pm.
    + +

    Milk 自由大道—熱血的同志運動史

    + +
    +Milk 自由大道
    +

    Milk 自由大道

    +
    + + + +

    自由大道敘述1978年被刺身亡,美國第一位同志市議員,舊金山市議員哈維米克的故事。故事從被刺身亡前,米克預感自己死期將近,錄音留下自己的一生故事,開始倒敘。故事從1970年,賣保險的米克在地下道搭訕認識史考特,一起搬到舊金山卡斯楚區開照相館。一開始只是列出一張對同志友善與否的商店清單,逐漸擴大成為當地同志的聚會所。後來警察騷擾愈趨頻繁,米克決定參選市議員,改變現況。兩次市議員參選失敗,一次加州州議員參選失敗後,史考特也因米克過於熱衷選舉而離開。史考特繼續從事同志運動,和米克分道揚鑣,但相互呼應。州議員選舉末期,選舉團隊加入了克里夫瓊斯。選後,由前歌手安妮塔布萊恩帶領的反動力量,否決了佛州的同志工作平等居住法。眾人在努力奮鬥後仍不敵保守勢力。終於在1977年,選區調整後對同志社群有利,同志工作平等居住法被廢後的憤怒民氣,和新總幹事女同志安科能堡的共同努力下,擊敗同選區另一位同志候選人史多克,選上舊金山市市議員。選前最後一夜,米克認識了對政治沒有興趣的新男友傑克。選後,米克為了各種法案,和同選區的保守議員丹懷特履生衝突。在舊金山市史上最開明的市議會中,丹懷特幾無立足之地。這時,加州參議員約翰布里格提案公投,開除同志教師。即使在民調幾無勝算下,米克和團隊們仍不斷挑戰,終於推翻開除同志教師的第六號法案。但對政治沒興趣的傑克,卻受不了米克無止盡的政治活動,而在家裏自殺。保守勢力挫敗,各項法案都不被支持的丹懷特辭職,卻又在和警察協會密談後想復職。但是莫斯卡尼市長沒有接受。絕望的丹懷特,帶槍潛入市議會,刺殺了市長和米克。

    + +

    自由大道描述的是一段1970年代,同志運動風起雲湧的歷史。在風起雲湧的同志運動中,充滿的不是偉大、勝利和歡笑的想像,而是血淚。在生命和各種威脅下,米克和團隊們仍不斷努力。而這不過是三十年前的故事。即使到了今天,美國社會仍然保守,面對同志婚姻等等基本人權,天主教會的龐大保守勢力威脅,仍然很難跨出下一步。然而,戰鬥的熱情是不會停止的。

    + +

    面對把保守恐同情結全盤從西方複製來台灣的教會,台灣的同志婚姻權益,也仍然有好長一段路要走。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 171 | + 172 | + 173 | + 174 | + 175 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0173.html.zh-cn.html b/htdocs/imacat/me/diary/0173.html.zh-cn.html new file mode 120000 index 0000000..85d3a78 --- /dev/null +++ b/htdocs/imacat/me/diary/0173.html.zh-cn.html @@ -0,0 +1 @@ +0173.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0173.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0173.html.zh-cn.xhtml new file mode 100644 index 0000000..9558f00 --- /dev/null +++ b/htdocs/imacat/me/diary/0173.html.zh-cn.xhtml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百七十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百七十三

    + +
    + +
    + +
    +
    3.31.’11. 4:24pm.
    + +

    Milk 自由大道—热血的同志运动史

    + +
    +Milk 自由大道
    +

    Milk 自由大道

    +
    + + + +

    自由大道叙述1978年被刺身亡,美国第一位同志市议员,旧金山市议员哈维米克的故事。故事从被刺身亡前,米克预感自己死期将近,录音留下自己的一生故事,开始倒叙。故事从1970年,卖保险的米克在地下道搭讪认识史考特,一起搬到旧金山卡斯楚区开照相馆。一开始只是列出一张对同志友善与否的商店清单,逐渐扩大成为当地同志的聚会所。后来警察骚扰愈趋频繁,米克决定参选市议员,改变现况。两次市议员参选失败,一次加州州议员参选失败后,史考特也因米克过於热衷选举而离开。史考特继续从事同志运动,和米克分道扬镳,但相互呼应。州议员选举末期,选举团队加入了克里夫琼斯。选后,由前歌手安妮塔布莱恩带领的反动力量,否决了佛州的同志工作平等居住法。众人在努力奋斗后仍不敌保守势力。终於在1977年,选区调整后对同志社群有利,同志工作平等居住法被废后的愤怒民气,和新总干事女同志安科能堡的共同努力下,击败同选区另一位同志候选人史多克,选上旧金山市市议员。选前最后一夜,米克认识了对政治没有兴趣的新男友杰克。选后,米克为了各种法案,和同选区的保守议员丹怀特履生冲突。在旧金山市史上最开明的市议会中,丹怀特几无立足之地。这时,加州参议员约翰布里格提案公投,开除同志教师。即使在民调几无胜算下,米克和团队们仍不断挑战,终於推翻开除同志教师的第六号法案。但对政治没兴趣的杰克,却受不了米克无止尽的政治活动,而在家里自杀。保守势力挫败,各项法案都不被支持的丹怀特辞职,却又在和警察协会密谈后想复职。但是莫斯卡尼市长没有接受。绝望的丹怀特,带枪潜入市议会,刺杀了市长和米克。

    + +

    自由大道描述的是一段1970年代,同志运动风起云涌的历史。在风起云涌的同志运动中,充满的不是伟大、胜利和欢笑的想像,而是血泪。在生命和各种威胁下,米克和团队们仍不断努力。而这不过是三十年前的故事。即使到了今天,美国社会仍然保守,面对同志婚姻等等基本人权,天主教会的庞大保守势力威胁,仍然很难跨出下一步。然而,战斗的热情是不会停止的。

    + +

    面对把保守恐同情结全盘从西方复制来台湾的教会,台湾的同志婚姻权益,也仍然有好长一段路要走。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 171 | + 172 | + 173 | + 174 | + 175 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0173.html.zh-tw.html b/htdocs/imacat/me/diary/0173.html.zh-tw.html new file mode 120000 index 0000000..3b7c51c --- /dev/null +++ b/htdocs/imacat/me/diary/0173.html.zh-tw.html @@ -0,0 +1 @@ +0173.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0173.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0173.html.zh-tw.xhtml new file mode 100644 index 0000000..762e237 --- /dev/null +++ b/htdocs/imacat/me/diary/0173.html.zh-tw.xhtml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百七十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百七十三

    + +
    + +
    + +
    +
    3.31.’11. 4:24pm.
    + +

    Milk 自由大道—熱血的同志運動史

    + +
    +Milk 自由大道
    +

    Milk 自由大道

    +
    + + + +

    自由大道敘述1978年被刺身亡,美國第一位同志市議員,舊金山市議員哈維米克的故事。故事從被刺身亡前,米克預感自己死期將近,錄音留下自己的一生故事,開始倒敘。故事從1970年,賣保險的米克在地下道搭訕認識史考特,一起搬到舊金山卡斯楚區開照相館。一開始只是列出一張對同志友善與否的商店清單,逐漸擴大成為當地同志的聚會所。後來警察騷擾愈趨頻繁,米克決定參選市議員,改變現況。兩次市議員參選失敗,一次加州州議員參選失敗後,史考特也因米克過於熱衷選舉而離開。史考特繼續從事同志運動,和米克分道揚鑣,但相互呼應。州議員選舉末期,選舉團隊加入了克里夫瓊斯。選後,由前歌手安妮塔布萊恩帶領的反動力量,否決了佛州的同志工作平等居住法。眾人在努力奮鬥後仍不敵保守勢力。終於在1977年,選區調整後對同志社群有利,同志工作平等居住法被廢後的憤怒民氣,和新總幹事女同志安科能堡的共同努力下,擊敗同選區另一位同志候選人史多克,選上舊金山市市議員。選前最後一夜,米克認識了對政治沒有興趣的新男友傑克。選後,米克為了各種法案,和同選區的保守議員丹懷特履生衝突。在舊金山市史上最開明的市議會中,丹懷特幾無立足之地。這時,加州參議員約翰布里格提案公投,開除同志教師。即使在民調幾無勝算下,米克和團隊們仍不斷挑戰,終於推翻開除同志教師的第六號法案。但對政治沒興趣的傑克,卻受不了米克無止盡的政治活動,而在家裏自殺。保守勢力挫敗,各項法案都不被支持的丹懷特辭職,卻又在和警察協會密談後想復職。但是莫斯卡尼市長沒有接受。絕望的丹懷特,帶槍潛入市議會,刺殺了市長和米克。

    + +

    自由大道描述的是一段1970年代,同志運動風起雲湧的歷史。在風起雲湧的同志運動中,充滿的不是偉大、勝利和歡笑的想像,而是血淚。在生命和各種威脅下,米克和團隊們仍不斷努力。而這不過是三十年前的故事。即使到了今天,美國社會仍然保守,面對同志婚姻等等基本人權,天主教會的龐大保守勢力威脅,仍然很難跨出下一步。然而,戰鬥的熱情是不會停止的。

    + +

    面對把保守恐同情結全盤從西方複製來台灣的教會,台灣的同志婚姻權益,也仍然有好長一段路要走。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 171 | + 172 | + 173 | + 174 | + 175 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0174.html.en.html b/htdocs/imacat/me/diary/0174.html.en.html new file mode 120000 index 0000000..b390ccb --- /dev/null +++ b/htdocs/imacat/me/diary/0174.html.en.html @@ -0,0 +1 @@ +0174.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0174.html.en.xhtml b/htdocs/imacat/me/diary/0174.html.en.xhtml new file mode 100644 index 0000000..984456f --- /dev/null +++ b/htdocs/imacat/me/diary/0174.html.en.xhtml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 174 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 174

    + +
    + +
    + +
    +
    5.18.’11. 11:51am.
    + +

    重順川菜

    + +

    上個禮拜吃峨嵋,吃五更腸旺和魚香肉絲,昨晚本來想吃螞蟻上樹和麻婆豆腐,峨嵋客滿,改吃斜對面的重順,比較峨嵋和重順和我做的魚香肉絲,和我最近做的宮保雞丁。 + +

    峨嵋的魚香肉絲,肉絲好少,炒得比較嫩,我炒得太老了。不過峨嵋勾芡沒有收乾,我試過幾次後,發現勾芡要收乾才好吃。重順的魚香肉絲肉比較多,但是油太多,吃完底層一層油。而且我做的魚香肉絲有用木耳,荸薺也切得比較大塊。

    + +

    重順的宮保雞丁好香,看起來也好好吃,一端上桌,色香味,我做的完全比不上。我嫌麻煩沒用糖色,改用多一兩匙砂糖代替,看來是錯的。用了糖色差好多。

    + +
    + +
    + +
    +
    5.4.’11. 10:15pm.
    + +

    「我們剛剛殺了人!」

    + +

    因為台灣好生活網摘的連結,我讀了「我們剛剛殺了人!」。

    + +

    其實賓拉登死後這幾天,網路上開始有不少同樣的反省。我也開始在反省:支持廢除死刑的我,為什麼同樣是殺人,同樣是人命死了,我卻沒有太大的感覺?殺人是不對的,每次看到死刑執行後,反廢死者歡樂慶祝時,我都覺得很噁心。那為什麼我看到美國舉國上下,為殺人而歡騰慶祝時,卻不覺得噁心?

    + +

    關魚的噗上,有人回應說,「這是一場戰爭」。這好像給了我啟示。

    + +

    所以是說,在戰爭面前,談論理性是沒有意義的,是嗎?所以即使歐巴馬宣佈我們剛剛殺了人,也不會覺得奇怪。因為如果不放棄「殺人是不對的」的理性思考的話,如何面對利比亞的民主內戰?如何支持利比亞人民,和屠殺人民的國家機器戰鬥?

    + +

    那麼,在戰爭中放棄理性這件事,是不是對的?有可能在戰爭中,保有「殺人是不對的」的理性嗎?

    + +
    + +
    + +
    +
    3.31.’11. 11:23pm.
    + +

    崖の上のポニョ 崖上的波妞—美麗的小美人魚故事

    + +
    +崖の上のポニョ 崖上的波妞
    +

    崖の上のポニョ 崖上的波妞

    +
    + +
      +
    • 片名: 崖の上のポニョ
    • +
    • 中譯片名:崖上的波妞
    • +
    • 發行年份: 2008
    • +
    • 製作公司:スタジオジブリ
    • +
    • 導演:宮崎駿
    • +
    + +

    崖上的波妞描寫小魚布倫希爾蒂趁魔法師爸爸藤本不注意時,跑到人類的岸上,被人類小孩宗介撿去,取名為波妞。宗介喜歡波妞,波妞也喜歡宗介。宗介家住在懸崖上,媽媽理沙在老人之家工作,爸爸耕一是船長,小學就在老人之家旁邊。藤本發現波妞不見後,發動大潮將波妞搶回海底的家。波妞想念宗介,想變成人類,竟然自己長出了手腳。藤本大驚,用魔法硬把波妞變回魚,用泡泡關起來。沒到波妞的妹妹們一起合力咬破泡泡,放出波妞,想離開的波妞衝破泡泡,海水灌進海底的家,把珍貴的生命之水沖進海中,得生命之水之助,波妞變成人形,急於上岸找宗介,引發颱風海嘯。從老人院趕回家的宗介和理沙發現變成人形的波妞,雖覺不可思議,也讓波妞住下。擔心老人院的理沙,開車下山,徹夜未歸。這時候波妞的媽媽海神曼瑪蓮也出現了,說服爸爸藤本,讓波妞失去魔力,變成人類。到天亮時宗介和波妞才發現,外面已變成一片水鄉澤國。靠著波妞的魔法,宗介和波妞用變大的玩具船去找理沙。藤本暫時將老人院的人們保護在海底泡泡中,等待宗介和波妞到來後,曼瑪蓮告知波妞將失去魔法變成人類,然後讓眾人回到地面上的世界。

    + +

    崖上的波妞像是日本版的小美人魚故事。因為捨棄電腦動畫,全部改用手工繪製之故,畫面雖然比較沒有那麼細膩,但非常豐富美麗。海洋裏的生物,定格來看,每一隻都有不同的表情,美不勝收。

    + +

    宗介的媽媽理沙超帥氣的,超喜歡!

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 172 | + 173 | + 174 | + 175 | + 176 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0174.html.zh-cn.html b/htdocs/imacat/me/diary/0174.html.zh-cn.html new file mode 120000 index 0000000..c2e27ca --- /dev/null +++ b/htdocs/imacat/me/diary/0174.html.zh-cn.html @@ -0,0 +1 @@ +0174.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0174.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0174.html.zh-cn.xhtml new file mode 100644 index 0000000..c0e1351 --- /dev/null +++ b/htdocs/imacat/me/diary/0174.html.zh-cn.xhtml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百七十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百七十四

    + +
    + +
    + +
    +
    5.18.’11. 11:51am.
    + +

    重顺川菜

    + +

    上个礼拜吃峨嵋,吃五更肠旺和鱼香肉丝,昨晚本来想吃蚂蚁上树和麻婆豆腐,峨嵋客满,改吃斜对面的重顺,比较峨嵋和重顺和我做的鱼香肉丝,和我最近做的宫保鸡丁。 + +

    峨嵋的鱼香肉丝,肉丝好少,炒得比较嫩,我炒得太老了。不过峨嵋勾芡没有收干,我试过几次后,发现勾芡要收干才好吃。重顺的鱼香肉丝肉比较多,但是油太多,吃完底层一层油。而且我做的鱼香肉丝有用木耳,荸荠也切得比较大块。

    + +

    重顺的宫保鸡丁好香,看起来也好好吃,一端上桌,色香味,我做的完全比不上。我嫌麻烦没用糖色,改用多一两匙砂糖代替,看来是错的。用了糖色差好多。

    + +
    + +
    + +
    +
    5.4.’11. 10:15pm.
    + +

    「我们刚刚杀了人!」

    + +

    因为台湾好生活网摘的连结,我读了「我们刚刚杀了人!」。

    + +

    其实宾拉登死后这几天,网路上开始有不少同样的反省。我也开始在反省:支持废除死刑的我,为什么同样是杀人,同样是人命死了,我却没有太大的感觉?杀人是不对的,每次看到死刑执行后,反废死者欢乐庆祝时,我都觉得很恶心。那为什么我看到美国举国上下,为杀人而欢腾庆祝时,却不觉得恶心?

    + +

    关鱼的噗上,有人回应说,「这是一场战争」。这好像给了我启示。

    + +

    所以是说,在战争面前,谈论理性是没有意义的,是吗?所以即使欧巴马宣布我们刚刚杀了人,也不会觉得奇怪。因为如果不放弃「杀人是不对的」的理性思考的话,如何面对利比亚的民主内战?如何支持利比亚人民,和屠杀人民的国家机器战斗?

    + +

    那么,在战争中放弃理性这件事,是不是对的?有可能在战争中,保有「杀人是不对的」的理性吗?

    + +
    + +
    + +
    +
    3.31.’11. 11:23pm.
    + +

    崖の上のポニョ 崖上的波妞—美丽的小美人鱼故事

    + +
    +崖の上のポニョ 崖上的波妞
    +

    崖の上のポニョ 崖上的波妞

    +
    + +
      +
    • 片名: 崖の上のポニョ
    • +
    • 中译片名:崖上的波妞
    • +
    • 发行年份: 2008
    • +
    • 制作公司:スタジオジブリ
    • +
    • 导演:宫崎骏
    • +
    + +

    崖上的波妞描写小鱼布伦希尔蒂趁魔法师爸爸藤本不注意时,跑到人类的岸上,被人类小孩宗介捡去,取名为波妞。宗介喜欢波妞,波妞也喜欢宗介。宗介家住在悬崖上,妈妈理沙在老人之家工作,爸爸耕一是船长,小学就在老人之家旁边。藤本发现波妞不见后,发动大潮将波妞抢回海底的家。波妞想念宗介,想变成人类,竟然自己长出了手脚。藤本大惊,用魔法硬把波妞变回鱼,用泡泡关起来。没到波妞的妹妹们一起合力咬破泡泡,放出波妞,想离开的波妞冲破泡泡,海水灌进海底的家,把珍贵的生命之水冲进海中,得生命之水之助,波妞变成人形,急於上岸找宗介,引发台风海啸。从老人院赶回家的宗介和理沙发现变成人形的波妞,虽觉不可思议,也让波妞住下。担心老人院的理沙,开车下山,彻夜未归。这时候波妞的妈妈海神曼玛莲也出现了,说服爸爸藤本,让波妞失去魔力,变成人类。到天亮时宗介和波妞才发现,外面已变成一片水乡泽国。靠著波妞的魔法,宗介和波妞用变大的玩具船去找理沙。藤本暂时将老人院的人们保护在海底泡泡中,等待宗介和波妞到来后,曼玛莲告知波妞将失去魔法变成人类,然后让众人回到地面上的世界。

    + +

    崖上的波妞像是日本版的小美人鱼故事。因为舍弃电脑动画,全部改用手工绘制之故,画面虽然比较没有那么细腻,但非常丰富美丽。海洋里的生物,定格来看,每一只都有不同的表情,美不胜收。

    + +

    宗介的妈妈理沙超帅气的,超喜欢!

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 172 | + 173 | + 174 | + 175 | + 176 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0174.html.zh-tw.html b/htdocs/imacat/me/diary/0174.html.zh-tw.html new file mode 120000 index 0000000..74c9164 --- /dev/null +++ b/htdocs/imacat/me/diary/0174.html.zh-tw.html @@ -0,0 +1 @@ +0174.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0174.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0174.html.zh-tw.xhtml new file mode 100644 index 0000000..711af0e --- /dev/null +++ b/htdocs/imacat/me/diary/0174.html.zh-tw.xhtml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百七十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百七十四

    + +
    + +
    + +
    +
    5.18.’11. 11:51am.
    + +

    重順川菜

    + +

    上個禮拜吃峨嵋,吃五更腸旺和魚香肉絲,昨晚本來想吃螞蟻上樹和麻婆豆腐,峨嵋客滿,改吃斜對面的重順,比較峨嵋和重順和我做的魚香肉絲,和我最近做的宮保雞丁。 + +

    峨嵋的魚香肉絲,肉絲好少,炒得比較嫩,我炒得太老了。不過峨嵋勾芡沒有收乾,我試過幾次後,發現勾芡要收乾才好吃。重順的魚香肉絲肉比較多,但是油太多,吃完底層一層油。而且我做的魚香肉絲有用木耳,荸薺也切得比較大塊。

    + +

    重順的宮保雞丁好香,看起來也好好吃,一端上桌,色香味,我做的完全比不上。我嫌麻煩沒用糖色,改用多一兩匙砂糖代替,看來是錯的。用了糖色差好多。

    + +
    + +
    + +
    +
    5.4.’11. 10:15pm.
    + +

    「我們剛剛殺了人!」

    + +

    因為台灣好生活網摘的連結,我讀了「我們剛剛殺了人!」。

    + +

    其實賓拉登死後這幾天,網路上開始有不少同樣的反省。我也開始在反省:支持廢除死刑的我,為什麼同樣是殺人,同樣是人命死了,我卻沒有太大的感覺?殺人是不對的,每次看到死刑執行後,反廢死者歡樂慶祝時,我都覺得很噁心。那為什麼我看到美國舉國上下,為殺人而歡騰慶祝時,卻不覺得噁心?

    + +

    關魚的噗上,有人回應說,「這是一場戰爭」。這好像給了我啟示。

    + +

    所以是說,在戰爭面前,談論理性是沒有意義的,是嗎?所以即使歐巴馬宣佈我們剛剛殺了人,也不會覺得奇怪。因為如果不放棄「殺人是不對的」的理性思考的話,如何面對利比亞的民主內戰?如何支持利比亞人民,和屠殺人民的國家機器戰鬥?

    + +

    那麼,在戰爭中放棄理性這件事,是不是對的?有可能在戰爭中,保有「殺人是不對的」的理性嗎?

    + +
    + +
    + +
    +
    3.31.’11. 11:23pm.
    + +

    崖の上のポニョ 崖上的波妞—美麗的小美人魚故事

    + +
    +崖の上のポニョ 崖上的波妞
    +

    崖の上のポニョ 崖上的波妞

    +
    + +
      +
    • 片名: 崖の上のポニョ
    • +
    • 中譯片名:崖上的波妞
    • +
    • 發行年份: 2008
    • +
    • 製作公司:スタジオジブリ
    • +
    • 導演:宮崎駿
    • +
    + +

    崖上的波妞描寫小魚布倫希爾蒂趁魔法師爸爸藤本不注意時,跑到人類的岸上,被人類小孩宗介撿去,取名為波妞。宗介喜歡波妞,波妞也喜歡宗介。宗介家住在懸崖上,媽媽理沙在老人之家工作,爸爸耕一是船長,小學就在老人之家旁邊。藤本發現波妞不見後,發動大潮將波妞搶回海底的家。波妞想念宗介,想變成人類,竟然自己長出了手腳。藤本大驚,用魔法硬把波妞變回魚,用泡泡關起來。沒到波妞的妹妹們一起合力咬破泡泡,放出波妞,想離開的波妞衝破泡泡,海水灌進海底的家,把珍貴的生命之水沖進海中,得生命之水之助,波妞變成人形,急於上岸找宗介,引發颱風海嘯。從老人院趕回家的宗介和理沙發現變成人形的波妞,雖覺不可思議,也讓波妞住下。擔心老人院的理沙,開車下山,徹夜未歸。這時候波妞的媽媽海神曼瑪蓮也出現了,說服爸爸藤本,讓波妞失去魔力,變成人類。到天亮時宗介和波妞才發現,外面已變成一片水鄉澤國。靠著波妞的魔法,宗介和波妞用變大的玩具船去找理沙。藤本暫時將老人院的人們保護在海底泡泡中,等待宗介和波妞到來後,曼瑪蓮告知波妞將失去魔法變成人類,然後讓眾人回到地面上的世界。

    + +

    崖上的波妞像是日本版的小美人魚故事。因為捨棄電腦動畫,全部改用手工繪製之故,畫面雖然比較沒有那麼細膩,但非常豐富美麗。海洋裏的生物,定格來看,每一隻都有不同的表情,美不勝收。

    + +

    宗介的媽媽理沙超帥氣的,超喜歡!

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 172 | + 173 | + 174 | + 175 | + 176 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0175.html.en.html b/htdocs/imacat/me/diary/0175.html.en.html new file mode 120000 index 0000000..c7aa821 --- /dev/null +++ b/htdocs/imacat/me/diary/0175.html.en.html @@ -0,0 +1 @@ +0175.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0175.html.en.xhtml b/htdocs/imacat/me/diary/0175.html.en.xhtml new file mode 100644 index 0000000..8ea3860 --- /dev/null +++ b/htdocs/imacat/me/diary/0175.html.en.xhtml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 175 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 175

    + +
    + +
    + +
    +
    5.27.’11. 10:12pm.
    + +

    脫下哥德蘿莉裝…

    + +

    脫下哥德蘿莉裝,結束我的哥德蘿莉週。

    + +

    從上禮拜六(5/21)在J-Live買了哥德蘿莉風洋裝,洗過之後,試著實踐下妻物語中深田恭子演的竜ヶ崎桃子所實踐的,蘿莉塔是一種堅持,一種生活態度。這個禮拜來,試著穿著顯眼的哥德蘿莉風洋裝,出門做每一件事,倒垃圾等等。其實也沒有倒垃圾啦,不過走路到附近的寶雅買生活用品倒是有。

    + +

    前天傍晚,穿著蘿莉裝,走路去附近的寶雅買條洗面乳,再從夜市尾走到夜市頭的五金行,買玻璃小缽。在夜市的衣服店看到不少好看的長洋裝,不過穿著蘿莉裝不方便試衣服,只好忍痛跳過。

    + +

    昨天下午,穿著蘿莉裝,去找設計師Apple染髮,染了紫紅雙色隱藏式挑染,搭上哥德蘿莉風洋裝,感覺超魔幻。傍晚染完去台北地下街,想去女僕喫茶,在夢幻餐車夢幻學園前,猶豫要去哪家時,看到餐車正好是御貓和觀月麻呂值班,超Lucky!就去了餐車。麻呂cos初音,好好看。御貓也還是好漂亮。御貓竟然還記得我耶,超開心!

    + +

    今天早上,因為公館修鞋的老伯只擺攤到中午,下大雨來不及出門,只好坐計程車趕去修小招的鞋,有點划不來。修鞋的錢350,好貴。修完鞋,離下午精粹上班還有時間,就去夢幻學園吃午飯。出捷運後走路走了好遠,還在台北火車站地下迷宮迷了路。迷路期間徹底貫徹蘿莉塔風格,無論走多久身姿都要非常優雅。學園這幾天正好是妹妹日,女僕都穿蘿莉裝,叫客人姊姊或哥哥。我穿哥德蘿莉進門,好像在跟女僕搶鏡頭一樣。不過花小花不在,真討厭。

    + +

    離開學園回去上班,回來的路上發現一家新開的執事喫茶店Chitty Mood少女心,有點想昏倒。執事女僕店越來越多了啊!下了班離回家還有點時間,猶豫著最後要去Chitty Mood見識一下,還是回去常去的Fatimaid。還沒去過Chitty Mood,可以當作約團的參考,而且穿著蘿莉裝,正適合當大小姐;不過好想去Fatimaid看吉他,而且我畢竟還是比較喜歡女生。想了一會,還是決定去Chitty Mood看看。不過Chitty Mood客滿,所以最後還是理所當然轉去Fatimaid了。這是我理想中最佳的結果,Chitty Mood客滿就沒辦法了,我心底其實還是比較想去Fatimaid。沒想到吉他主動跟我搭話,說很喜歡我這套蘿莉裝呢!還小聊了一下,超開心!

    + +

    沒有機會去Chitty Mood。從外觀看,Chitty Mood和Gloria執事喫茶比起來,Gloria比較維多利亞古典風,Chitty Mood比較夢幻二次元,很符合地下街女僕喫茶的風格。回來上網查,Chitty Mood和夢幻學園同一個集團,母店都是777咖啡美饌

    + +

    離開Fatimaid,回到家,脫下哥德蘿莉裝,結束我的哥德蘿莉狂熱週。穿了一個禮拜,也該洗了。日後還是會穿,不過可能不是很頻繁吧。畢竟穿脫都有點麻煩。可是穿著走動,堅持蘿莉塔style的感覺,還是超開心的。處女座果然對優雅沒有抵抗力啊!

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 173 | + 174 | + 175 | + 176 | + 177 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0175.html.zh-cn.html b/htdocs/imacat/me/diary/0175.html.zh-cn.html new file mode 120000 index 0000000..39f31d3 --- /dev/null +++ b/htdocs/imacat/me/diary/0175.html.zh-cn.html @@ -0,0 +1 @@ +0175.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0175.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0175.html.zh-cn.xhtml new file mode 100644 index 0000000..528c464 --- /dev/null +++ b/htdocs/imacat/me/diary/0175.html.zh-cn.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百七十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百七十五

    + +
    + +
    + +
    +
    5.27.’11. 10:12pm.
    + +

    脱下哥德萝莉装…

    + +

    脱下哥德萝莉装,结束我的哥德萝莉周。

    + +

    从上礼拜六(5/21)在J-Live买了哥德萝莉风洋装,洗过之后,试著实践下妻物语中深田恭子演的竜ヶ崎桃子所实践的,萝莉塔是一种坚持,一种生活态度。这个礼拜来,试著穿著显眼的哥德萝莉风洋装,出门做每一件事,倒垃圾等等。其实也没有倒垃圾啦,不过走路到附近的宝雅买生活用品倒是有。

    + +

    前天傍晚,穿著萝莉装,走路去附近的宝雅买条洗面乳,再从夜市尾走到夜市头的五金行,买玻璃小钵。在夜市的衣服店看到不少好看的长洋装,不过穿著萝莉装不方便试衣服,只好忍痛跳过。

    + +

    昨天下午,穿著萝莉装,去找设计师Apple染发,染了紫红双色隐藏式挑染,搭上哥德萝莉风洋装,感觉超魔幻。傍晚染完去台北地下街,想去女仆吃茶,在梦幻餐车梦幻学园前,犹豫要去哪家时,看到餐车正好是御猫和观月麻吕值班,超Lucky!就去了餐车。麻吕cos初音,好好看。御猫也还是好漂亮。御猫竟然还记得我耶,超开心!

    + +

    今天早上,因为公馆修鞋的老伯只摆摊到中午,下大雨来不及出门,只好坐计程车赶去修小招的鞋,有点划不来。修鞋的钱350,好贵。修完鞋,离下午精粹上班还有时间,就去梦幻学园吃午饭。出捷运后走路走了好远,还在台北火车站地下迷宫迷了路。迷路期间彻底贯彻萝莉塔风格,无论走多久身姿都要非常优雅。学园这几天正好是妹妹日,女仆都穿萝莉装,叫客人姊姊或哥哥。我穿哥德萝莉进门,好像在跟女仆抢镜头一样。不过花小花不在,真讨厌。

    + +

    离开学园回去上班,回来的路上发现一家新开的执事吃茶店Chitty Mood少女心,有点想昏倒。执事女仆店越来越多了啊!下了班离回家还有点时间,犹豫著最后要去Chitty Mood见识一下,还是回去常去的Fatimaid。还没去过Chitty Mood,可以当作约团的参考,而且穿著萝莉装,正适合当大小姐;不过好想去Fatimaid看吉他,而且我毕竟还是比较喜欢女生。想了一会,还是决定去Chitty Mood看看。不过Chitty Mood客满,所以最后还是理所当然转去Fatimaid了。这是我理想中最佳的结果,Chitty Mood客满就没办法了,我心底其实还是比较想去Fatimaid。没想到吉他主动跟我搭话,说很喜欢我这套萝莉装呢!还小聊了一下,超开心!

    + +

    没有机会去Chitty Mood。从外观看,Chitty Mood和Gloria执事吃茶比起来,Gloria比较维多利亚古典风,Chitty Mood比较梦幻二次元,很符合地下街女仆吃茶的风格。回来上网查,Chitty Mood和梦幻学园同一个集团,母店都是777咖啡美馔

    + +

    离开Fatimaid,回到家,脱下哥德萝莉装,结束我的哥德萝莉狂热周。穿了一个礼拜,也该洗了。日后还是会穿,不过可能不是很频繁吧。毕竟穿脱都有点麻烦。可是穿著走动,坚持萝莉塔style的感觉,还是超开心的。处女座果然对优雅没有抵抗力啊!

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 173 | + 174 | + 175 | + 176 | + 177 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0175.html.zh-tw.html b/htdocs/imacat/me/diary/0175.html.zh-tw.html new file mode 120000 index 0000000..23681cc --- /dev/null +++ b/htdocs/imacat/me/diary/0175.html.zh-tw.html @@ -0,0 +1 @@ +0175.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0175.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0175.html.zh-tw.xhtml new file mode 100644 index 0000000..c3b43fa --- /dev/null +++ b/htdocs/imacat/me/diary/0175.html.zh-tw.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百七十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百七十五

    + +
    + +
    + +
    +
    5.27.’11. 10:12pm.
    + +

    脫下哥德蘿莉裝…

    + +

    脫下哥德蘿莉裝,結束我的哥德蘿莉週。

    + +

    從上禮拜六(5/21)在J-Live買了哥德蘿莉風洋裝,洗過之後,試著實踐下妻物語中深田恭子演的竜ヶ崎桃子所實踐的,蘿莉塔是一種堅持,一種生活態度。這個禮拜來,試著穿著顯眼的哥德蘿莉風洋裝,出門做每一件事,倒垃圾等等。其實也沒有倒垃圾啦,不過走路到附近的寶雅買生活用品倒是有。

    + +

    前天傍晚,穿著蘿莉裝,走路去附近的寶雅買條洗面乳,再從夜市尾走到夜市頭的五金行,買玻璃小缽。在夜市的衣服店看到不少好看的長洋裝,不過穿著蘿莉裝不方便試衣服,只好忍痛跳過。

    + +

    昨天下午,穿著蘿莉裝,去找設計師Apple染髮,染了紫紅雙色隱藏式挑染,搭上哥德蘿莉風洋裝,感覺超魔幻。傍晚染完去台北地下街,想去女僕喫茶,在夢幻餐車夢幻學園前,猶豫要去哪家時,看到餐車正好是御貓和觀月麻呂值班,超Lucky!就去了餐車。麻呂cos初音,好好看。御貓也還是好漂亮。御貓竟然還記得我耶,超開心!

    + +

    今天早上,因為公館修鞋的老伯只擺攤到中午,下大雨來不及出門,只好坐計程車趕去修小招的鞋,有點划不來。修鞋的錢350,好貴。修完鞋,離下午精粹上班還有時間,就去夢幻學園吃午飯。出捷運後走路走了好遠,還在台北火車站地下迷宮迷了路。迷路期間徹底貫徹蘿莉塔風格,無論走多久身姿都要非常優雅。學園這幾天正好是妹妹日,女僕都穿蘿莉裝,叫客人姊姊或哥哥。我穿哥德蘿莉進門,好像在跟女僕搶鏡頭一樣。不過花小花不在,真討厭。

    + +

    離開學園回去上班,回來的路上發現一家新開的執事喫茶店Chitty Mood少女心,有點想昏倒。執事女僕店越來越多了啊!下了班離回家還有點時間,猶豫著最後要去Chitty Mood見識一下,還是回去常去的Fatimaid。還沒去過Chitty Mood,可以當作約團的參考,而且穿著蘿莉裝,正適合當大小姐;不過好想去Fatimaid看吉他,而且我畢竟還是比較喜歡女生。想了一會,還是決定去Chitty Mood看看。不過Chitty Mood客滿,所以最後還是理所當然轉去Fatimaid了。這是我理想中最佳的結果,Chitty Mood客滿就沒辦法了,我心底其實還是比較想去Fatimaid。沒想到吉他主動跟我搭話,說很喜歡我這套蘿莉裝呢!還小聊了一下,超開心!

    + +

    沒有機會去Chitty Mood。從外觀看,Chitty Mood和Gloria執事喫茶比起來,Gloria比較維多利亞古典風,Chitty Mood比較夢幻二次元,很符合地下街女僕喫茶的風格。回來上網查,Chitty Mood和夢幻學園同一個集團,母店都是777咖啡美饌

    + +

    離開Fatimaid,回到家,脫下哥德蘿莉裝,結束我的哥德蘿莉狂熱週。穿了一個禮拜,也該洗了。日後還是會穿,不過可能不是很頻繁吧。畢竟穿脫都有點麻煩。可是穿著走動,堅持蘿莉塔style的感覺,還是超開心的。處女座果然對優雅沒有抵抗力啊!

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 173 | + 174 | + 175 | + 176 | + 177 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0176.html.en.html b/htdocs/imacat/me/diary/0176.html.en.html new file mode 120000 index 0000000..d5e358c --- /dev/null +++ b/htdocs/imacat/me/diary/0176.html.en.html @@ -0,0 +1 @@ +0176.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0176.html.en.xhtml b/htdocs/imacat/me/diary/0176.html.en.xhtml new file mode 100644 index 0000000..f95cd23 --- /dev/null +++ b/htdocs/imacat/me/diary/0176.html.en.xhtml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 176 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 176

    + +
    + +
    + +
    +
    6.1.’11. 12:10pm.
    + +

    網站架設

    + +

    看到這一篇如果建築師必須如網頁設計師一般工作,有感。

    + +

    十幾年前.COM熱潮興起,我也是那時候開始看書、看文件學HTML、CSS等,做自己的網站。後來還靠這點能力,去做了一個MIS主管,後來做了網站開發工程師十年。

    + +

    這十年間變化很大,從早年書店裏滿架子簡簡單單學HTML的書,然後大家在瘋FrontPage、Dreamweaver,到後來Xoops、Drupal、WordPress等等現成的CMS。做網站簡單到,買一本書,下載個現成套件,翻翻點點,就可以做好一個網站。只要知道如何下載套件、翻翻點點做個網站,就可以出來開個人工作室,接案子做網站賺錢。

    + +

    也因為門檻這麼低,在JCase上的網站案子,價格壓到大概三千到五千左右。台北地下街的掛旗廣告,甚至有一個月五百的。之前急缺錢時,還上JCase註冊了付費帳號,付了三千六的年費,可是滿目都是三、五千的案子,一個價格像樣的案子也沒接到。

    + +

    一開始是一些學生做外快,學生學會一些網頁技術,就開始接案。反正學生吃穿都是家裏的,賺的是零用錢,也不會餓死。當年這些學生型的小型工作室,還常常上新聞。學生不會做業務賣東西,就只會壓價錢(行銷學上所謂價格策略),別人做七千我做六千五,別人做六千五我做五千。反正他們也不會餓死。逐漸地,學生不再是學生,可是行情被打爛了。現在,跟人家說做個網站要幾十萬,人家只會懷疑我詐欺。

    + +

    一個像樣的網站專案,有網站美工、程式設計,兩個人一個月薪水十萬。假設案子只做兩個月(請包括事前溝通規劃和結案測試的時間!),二十萬。公司有水電房租、專案經理和會計行政等固定成本,大概是人事成本的兩倍,四十萬。四十萬只是做一個普通的網站,這家公司營運打平的成本。

    + +

    我不知道這些收三千、五千的網站個人工作室,要怎麼活。假設個人工作室真的只有一個人,在家裏做,沒有固定成本,一個月三萬好了。那一個月要接六到十個網站,才能打平。兩個問題:

    + +
      +
    1. 到哪裏去接一個月六到十個網站?做網站哪裏有這麼大的市場?哪裏有這麼多案子可接?
    2. + +
    3. 假設真的接了六個網站好了,一個月二十二個工作天,六個客戶,每個案子只能做四天,超過就會賠錢。一個案子從需求規劃、美工設計製圖、程式撰寫,到完工測試,還有後續的收費,四天怎麼可能做得起來?
    4. +
    + +

    過低的價格,造成幾個結果。

    + +
      +
    1. 這些滿坑滿谷的個人網頁工作室,長期處於無法溫飽的狀態,餓不死,也活不下去。一個月只有一、兩個案子,月收入不一定有一萬,連房租都不夠付,卡債高築的,比比皆是。他們只會壓低價格搶案,到頭來還是苦了自己。這個月幫你做完案子,下個月可能付不出房租跑路了。
    2. + +
    3. 一個案子,含事前規劃和後續支援,只能分配到四個工作天,只能拿現有的CMS來修修改改,連圖片的版權都有問題。需要的功能,都上網抓現成的模組,他們不是真正的程式設計師,抓到的模組其實看不懂,出問題不會修,自己都吃不飽了,也沒有精力、成本幫你修。如果客戶要後續支援,他乾脆就跑路了比較快。
    4. +
    + +

    結果就是,接案的時候答應滿滿,個人工作室也不懂專案管理,什麼都跟你說可以說可以做;做完有問題,這裏要改那裏要修,接案方覺得客戶沒給多少錢還要求一堆,就開始吵架推拖,到後期就完全失蹤。不過沒關係,客戶會找到另一家五千塊錢的個人網頁工作室,再惡性循環一次。這是市場經濟,個人網頁工作室滿坑滿谷,滿街都找得到人兜售五千塊錢的網站。

    + +

    對像我這樣正規做網站的工程師而言,永遠都很難說服客戶,做一個網站要四、五十萬起跳,加一個功能要十萬、二十萬。我開這個價錢,因為我必須和你開會討論你的需求,必須去寫code,必須設計你的資料庫,還要做完整的內部測試、上線客戶端測試,和某個期間內的後續支援。可是客戶的MIS,永遠都會跳出一個親戚,五千塊錢就能幫他做一個網站。

    + +

    客戶可以去找那種五千塊錢一個網站的,沒有關係。我可以預知因為接案方賠錢,案子到後來會爛掉,不過我這時說的話,客戶也聽不進去。反正爛掉再換一家。台灣還缺五千塊錢的個人網頁工作室嗎?

    + +

    至於拿Xoops這種五千元技術,當核心研發技術的公司,我就完全無話可說了。(遠目)

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 174 | + 175 | + 176 | + 177 | + 178 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0176.html.zh-cn.html b/htdocs/imacat/me/diary/0176.html.zh-cn.html new file mode 120000 index 0000000..ef0b0a5 --- /dev/null +++ b/htdocs/imacat/me/diary/0176.html.zh-cn.html @@ -0,0 +1 @@ +0176.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0176.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0176.html.zh-cn.xhtml new file mode 100644 index 0000000..3373918 --- /dev/null +++ b/htdocs/imacat/me/diary/0176.html.zh-cn.xhtml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百七十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百七十六

    + +
    + +
    + +
    +
    6.1.’11. 12:10pm.
    + +

    网站架设

    + +

    看到这一篇如果建筑师必须如网页设计师一般工作,有感。

    + +

    十几年前.COM热潮兴起,我也是那时候开始看书、看文件学HTML、CSS等,做自己的网站。后来还靠这点能力,去做了一个MIS主管,后来做了网站开发工程师十年。

    + +

    这十年间变化很大,从早年书店里满架子简简单单学HTML的书,然后大家在疯FrontPage、Dreamweaver,到后来Xoops、Drupal、WordPress等等现成的CMS。做网站简单到,买一本书,下载个现成套件,翻翻点点,就可以做好一个网站。只要知道如何下载套件、翻翻点点做个网站,就可以出来开个人工作室,接案子做网站赚钱。

    + +

    也因为门槛这么低,在JCase上的网站案子,价格压到大概三千到五千左右。台北地下街的挂旗广告,甚至有一个月五百的。之前急缺钱时,还上JCase注册了付费帐号,付了三千六的年费,可是满目都是三、五千的案子,一个价格像样的案子也没接到。

    + +

    一开始是一些学生做外快,学生学会一些网页技术,就开始接案。反正学生吃穿都是家里的,赚的是零用钱,也不会饿死。当年这些学生型的小型工作室,还常常上新闻。学生不会做业务卖东西,就只会压价钱(行销学上所谓价格策略),别人做七千我做六千五,别人做六千五我做五千。反正他们也不会饿死。逐渐地,学生不再是学生,可是行情被打烂了。现在,跟人家说做个网站要几十万,人家只会怀疑我诈欺。

    + +

    一个像样的网站专案,有网站美工、程式设计,两个人一个月薪水十万。假设案子只做两个月(请包括事前沟通规划和结案测试的时间!),二十万。公司有水电房租、专案经理和会计行政等固定成本,大概是人事成本的两倍,四十万。四十万只是做一个普通的网站,这家公司营运打平的成本。

    + +

    我不知道这些收三千、五千的网站个人工作室,要怎么活。假设个人工作室真的只有一个人,在家里做,没有固定成本,一个月三万好了。那一个月要接六到十个网站,才能打平。两个问题:

    + +
      +
    1. 到哪里去接一个月六到十个网站?做网站哪里有这么大的市场?哪里有这么多案子可接?
    2. + +
    3. 假设真的接了六个网站好了,一个月二十二个工作天,六个客户,每个案子只能做四天,超过就会赔钱。一个案子从需求规划、美工设计制图、程式撰写,到完工测试,还有后续的收费,四天怎么可能做得起来?
    4. +
    + +

    过低的价格,造成几个结果。

    + +
      +
    1. 这些满坑满谷的个人网页工作室,长期处於无法温饱的状态,饿不死,也活不下去。一个月只有一、两个案子,月收入不一定有一万,连房租都不够付,卡债高筑的,比比皆是。他们只会压低价格抢案,到头来还是苦了自己。这个月帮你做完案子,下个月可能付不出房租跑路了。
    2. + +
    3. 一个案子,含事前规划和后续支援,只能分配到四个工作天,只能拿现有的CMS来修修改改,连图片的版权都有问题。需要的功能,都上网抓现成的模组,他们不是真正的程式设计师,抓到的模组其实看不懂,出问题不会修,自己都吃不饱了,也没有精力、成本帮你修。如果客户要后续支援,他干脆就跑路了比较快。
    4. +
    + +

    结果就是,接案的时候答应满满,个人工作室也不懂专案管理,什么都跟你说可以说可以做;做完有问题,这里要改那里要修,接案方觉得客户没给多少钱还要求一堆,就开始吵架推拖,到后期就完全失踪。不过没关系,客户会找到另一家五千块钱的个人网页工作室,再恶性循环一次。这是市场经济,个人网页工作室满坑满谷,满街都找得到人兜售五千块钱的网站。

    + +

    对像我这样正规做网站的工程师而言,永远都很难说服客户,做一个网站要四、五十万起跳,加一个功能要十万、二十万。我开这个价钱,因为我必须和你开会讨论你的需求,必须去写code,必须设计你的资料库,还要做完整的内部测试、上线客户端测试,和某个期间内的后续支援。可是客户的MIS,永远都会跳出一个亲戚,五千块钱就能帮他做一个网站。

    + +

    客户可以去找那种五千块钱一个网站的,没有关系。我可以预知因为接案方赔钱,案子到后来会烂掉,不过我这时说的话,客户也听不进去。反正烂掉再换一家。台湾还缺五千块钱的个人网页工作室吗?

    + +

    至於拿Xoops这种五千元技术,当核心研发技术的公司,我就完全无话可说了。(远目)

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 174 | + 175 | + 176 | + 177 | + 178 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0176.html.zh-tw.html b/htdocs/imacat/me/diary/0176.html.zh-tw.html new file mode 120000 index 0000000..9689442 --- /dev/null +++ b/htdocs/imacat/me/diary/0176.html.zh-tw.html @@ -0,0 +1 @@ +0176.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0176.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0176.html.zh-tw.xhtml new file mode 100644 index 0000000..dd157a0 --- /dev/null +++ b/htdocs/imacat/me/diary/0176.html.zh-tw.xhtml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百七十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百七十六

    + +
    + +
    + +
    +
    6.1.’11. 12:10pm.
    + +

    網站架設

    + +

    看到這一篇如果建築師必須如網頁設計師一般工作,有感。

    + +

    十幾年前.COM熱潮興起,我也是那時候開始看書、看文件學HTML、CSS等,做自己的網站。後來還靠這點能力,去做了一個MIS主管,後來做了網站開發工程師十年。

    + +

    這十年間變化很大,從早年書店裏滿架子簡簡單單學HTML的書,然後大家在瘋FrontPage、Dreamweaver,到後來Xoops、Drupal、WordPress等等現成的CMS。做網站簡單到,買一本書,下載個現成套件,翻翻點點,就可以做好一個網站。只要知道如何下載套件、翻翻點點做個網站,就可以出來開個人工作室,接案子做網站賺錢。

    + +

    也因為門檻這麼低,在JCase上的網站案子,價格壓到大概三千到五千左右。台北地下街的掛旗廣告,甚至有一個月五百的。之前急缺錢時,還上JCase註冊了付費帳號,付了三千六的年費,可是滿目都是三、五千的案子,一個價格像樣的案子也沒接到。

    + +

    一開始是一些學生做外快,學生學會一些網頁技術,就開始接案。反正學生吃穿都是家裏的,賺的是零用錢,也不會餓死。當年這些學生型的小型工作室,還常常上新聞。學生不會做業務賣東西,就只會壓價錢(行銷學上所謂價格策略),別人做七千我做六千五,別人做六千五我做五千。反正他們也不會餓死。逐漸地,學生不再是學生,可是行情被打爛了。現在,跟人家說做個網站要幾十萬,人家只會懷疑我詐欺。

    + +

    一個像樣的網站專案,有網站美工、程式設計,兩個人一個月薪水十萬。假設案子只做兩個月(請包括事前溝通規劃和結案測試的時間!),二十萬。公司有水電房租、專案經理和會計行政等固定成本,大概是人事成本的兩倍,四十萬。四十萬只是做一個普通的網站,這家公司營運打平的成本。

    + +

    我不知道這些收三千、五千的網站個人工作室,要怎麼活。假設個人工作室真的只有一個人,在家裏做,沒有固定成本,一個月三萬好了。那一個月要接六到十個網站,才能打平。兩個問題:

    + +
      +
    1. 到哪裏去接一個月六到十個網站?做網站哪裏有這麼大的市場?哪裏有這麼多案子可接?
    2. + +
    3. 假設真的接了六個網站好了,一個月二十二個工作天,六個客戶,每個案子只能做四天,超過就會賠錢。一個案子從需求規劃、美工設計製圖、程式撰寫,到完工測試,還有後續的收費,四天怎麼可能做得起來?
    4. +
    + +

    過低的價格,造成幾個結果。

    + +
      +
    1. 這些滿坑滿谷的個人網頁工作室,長期處於無法溫飽的狀態,餓不死,也活不下去。一個月只有一、兩個案子,月收入不一定有一萬,連房租都不夠付,卡債高築的,比比皆是。他們只會壓低價格搶案,到頭來還是苦了自己。這個月幫你做完案子,下個月可能付不出房租跑路了。
    2. + +
    3. 一個案子,含事前規劃和後續支援,只能分配到四個工作天,只能拿現有的CMS來修修改改,連圖片的版權都有問題。需要的功能,都上網抓現成的模組,他們不是真正的程式設計師,抓到的模組其實看不懂,出問題不會修,自己都吃不飽了,也沒有精力、成本幫你修。如果客戶要後續支援,他乾脆就跑路了比較快。
    4. +
    + +

    結果就是,接案的時候答應滿滿,個人工作室也不懂專案管理,什麼都跟你說可以說可以做;做完有問題,這裏要改那裏要修,接案方覺得客戶沒給多少錢還要求一堆,就開始吵架推拖,到後期就完全失蹤。不過沒關係,客戶會找到另一家五千塊錢的個人網頁工作室,再惡性循環一次。這是市場經濟,個人網頁工作室滿坑滿谷,滿街都找得到人兜售五千塊錢的網站。

    + +

    對像我這樣正規做網站的工程師而言,永遠都很難說服客戶,做一個網站要四、五十萬起跳,加一個功能要十萬、二十萬。我開這個價錢,因為我必須和你開會討論你的需求,必須去寫code,必須設計你的資料庫,還要做完整的內部測試、上線客戶端測試,和某個期間內的後續支援。可是客戶的MIS,永遠都會跳出一個親戚,五千塊錢就能幫他做一個網站。

    + +

    客戶可以去找那種五千塊錢一個網站的,沒有關係。我可以預知因為接案方賠錢,案子到後來會爛掉,不過我這時說的話,客戶也聽不進去。反正爛掉再換一家。台灣還缺五千塊錢的個人網頁工作室嗎?

    + +

    至於拿Xoops這種五千元技術,當核心研發技術的公司,我就完全無話可說了。(遠目)

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 174 | + 175 | + 176 | + 177 | + 178 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0177.html.en.html b/htdocs/imacat/me/diary/0177.html.en.html new file mode 120000 index 0000000..b8367f3 --- /dev/null +++ b/htdocs/imacat/me/diary/0177.html.en.html @@ -0,0 +1 @@ +0177.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0177.html.en.xhtml b/htdocs/imacat/me/diary/0177.html.en.xhtml new file mode 100644 index 0000000..78ebc54 --- /dev/null +++ b/htdocs/imacat/me/diary/0177.html.en.xhtml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 177 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 177

    + +
    + +
    + +
    +
    7.9.’11. 1:34am.
    + +

    台灣漫畫月刊讀後感

    + +
    +台灣漫畫月刊 +

    台灣漫畫月刊

    +
    + +

    這兩天的大事,大概就是楊蕙如出的台灣漫畫月刊創刊號終於發行了。全國各大書店、超商都有得買,漫畫出租店都有得租。我一向不是衝第一個的人,事實上還有點管線末端,直到噗浪上評論鋪天蓋地淹上來,楊蕙如都在PTT回應以後,到禮拜五打工出門,我才去找來看。本來這個封面和陣容,我應該不會去讀。但是這是朋友的朋友出的刊物,我還是去找來看了。

    + +

    在租書店漫畫雜誌架找了三、四遍才找到,差點還找漏了。第一個感想是:這麼這麼薄?薄到有點出乎意料,和旁邊的少快不成比例。雖然厚度不是重點就是了。

    + +

    網路上我看到最精彩的評論,就是自耕農草莓在噗浪上的評論,還有魔法設計師寫的傳說中的台灣漫畫月刊。面對眾多批評,楊蕙如後來在PTT上,也寫了[沒錯!]台灣漫畫月刊正式創刊了(請多指教)的回應文。回應的姿態很低,也坦白承認了很多缺失,所以我就不太苛求了。

    + +

    我只寫一些綜合自己讀後、外界評論、楊蕙如回應後的感想。上面刊載的七篇作品,分別是(依我主觀認知,約略主打程度與印象深淺順序):

    + + + +

    首先,全彩印刷真的只是純粹浪費錢、浪費漫畫家的人工而已。黑白印刷改成全彩,漫畫家很辛苦,印刷費用更會翻上三、五倍。我不知道把錢花在這個地方做什麼。大家會買海賊王黑執事的單行本,不是因為它全彩,是因為漫畫好看。我瞭解編輯部全彩印刷的用心,希望多衝幾本銷量。不過這是楊社長、藍主編抵押房子的錢和金主的錢,是很寶貴的現金,要花在刀口上,省下來去多燒幾期。燒在全彩印刷上沒有意義。沒有人會為了全彩印刷買漫畫。

    + +

    故事內容不清不楚

    + +

    至於漫畫好看嗎?說實話,只有血多的我是賣火材的小女孩這漾完成度比較高而已:在第一話,就有一個完整的劇情,並把角色的性格、背景等都交代清楚了。其他像少年殺無赦補教人生大宇宙戰爭年代誌皮諾丘之城等等,彷彿是頁數到了就下回分曉一樣,劇情走一半,不清不楚。這才是第一回,讀者忠誠度才剛開始培養,真的以為別人會看你的下一話嗎?為什麼別人要看你的下一話?

    + +

    楊蕙如說補教人生幾乎大家一開始都看不習慣…罵聲連連…看到第四五期開始就說…歐…不過滿好看的…看到六七八期就說…歐…真的很讚耶…。為什麼會認為一本新雜誌,一部新人作品,讀者有耐性等作者鋪八個月的梗?憑什麼大膽假設,台灣漫畫月刊第一期都不知道有沒有人買,一定可以撐到第八期?一開始看不習慣時,為什麼不聽從自己的直覺?

    + +

    皮諾丘之城是已畫了七年、出版六本的網路作品E-depth Angel E涯天使,原作完成度就很高。但是面對月刊連載頁數需求時,只能在不清不楚的地方下回分曉,慘不忍睹。而一本漫畫雜誌竟然不刊新刊,跑去刊登已出版的作品,誰要看?讀者網路上看下回就好,幹嘛去買?

    + +

    大宇宙戰爭年代誌像是台版的銀河英雄傳說。一開頭花了一整個跨頁說明人物設定。人物設定是漫畫家筆記本裏的東西,拜託請由劇情中帶出來,不要叫讀者去讀你的人物設定。

    + +

    畫面很髒

    + +

    畫功,就更不要提了。傷心農場網路星球東東鏘畫風比較乾淨。血多本來就不是乾淨的畫風。皮諾丘之城粉蠟筆著色不大乾淨,不過畫功很不錯。可是三部主打作少年殺無赦補教人生大宇宙戰爭年代誌,都是描照片的。描照片哪有畫功可言?描照片不需畫功,但畫面很髒,照片拍不出來的東西,有魄力的構圖,做不出來。這些缺點在三部主打作上展露無遺。

    + +

    我不知道是不是因為要擺脫日式漫畫風格,所以主打作全用描照片的。可是描照片不是畫漫畫,那根本不是用畫的。請走出台式風格,不要描照片。

    + +

    一篇粉蠟筆風,三篇描照片的主打作。我不知道這四篇,第二期以後,怎麼轉成黑白印刷。每期都全彩下去,我怕一千五百萬很快就燒光光。

    + +

    綜合感想

    + +

    一本漫畫雜誌,四篇主打作中,有三篇描照片,畫面很髒,沒有畫功,沒有精彩有魄力的構圖,第一回沒有清楚交代吸引人的劇情,前途堪慮。這三篇主打作,連東立漫畫新人獎的佳作都比不上。我建議編輯部研讀東立漫畫新人獎作品集的評審意見,雖不是絕對正確,還是有很多寶貴的前人經驗,可供編輯選稿參考。

    + +

    社方很用心不讓台灣漫畫月刊沾上政治色彩,用心應予肯定。但是還是破了功,玉山周報以一篇台灣漫畫月刊 打造本土文創平台,大力推崇台灣漫畫月刊

    + +

    楊蕙如不斷強調台灣需要本土漫畫。台灣的確需要本土漫畫,但是台灣不是沒有本土漫畫。東立多年來賠錢經營本土漫畫雜誌龍少年星少女,還砸大錢辦漫畫新人獎,培育出不少優秀漫畫家。台灣不是沒有本土漫畫。台灣需要本土漫畫,我也很樂於見到百花盛開,百家齊鳴。但是,少一本台灣漫畫月刊,本土漫畫不會消失。台灣需要本土漫畫這種國族主義為號召,龍少年創刊初期就做過了,失敗得很慘。那時候還只有一本龍少年。為什麼要重蹈覆輒?

    + +

    寫完後,又得知了一些事實。補充一句:真有心搞本土漫畫,請不要在雜誌最重要的籌備期,讓社務空轉,讓韋宗成這樣的核心大咖求去,只剩下這些不三不四的作品。不是抵押了房子燒了錢就叫有決心。把人整個燎下去才叫有決心。到底是不是真的有決心搞台灣漫畫?

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 175 | + 176 | + 177 | + 178 | + 179 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0177.html.zh-cn.html b/htdocs/imacat/me/diary/0177.html.zh-cn.html new file mode 120000 index 0000000..8a7562d --- /dev/null +++ b/htdocs/imacat/me/diary/0177.html.zh-cn.html @@ -0,0 +1 @@ +0177.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0177.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0177.html.zh-cn.xhtml new file mode 100644 index 0000000..bb9d84c --- /dev/null +++ b/htdocs/imacat/me/diary/0177.html.zh-cn.xhtml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百七十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百七十七

    + +
    + +
    + +
    +
    7.9.’11. 1:34am.
    + +

    台湾漫画月刊读后感

    + +
    +台湾漫画月刊 +

    台湾漫画月刊

    +
    + +

    这两天的大事,大概就是杨蕙如出的台湾漫画月刊创刊号终於发行了。全国各大书店、超商都有得买,漫画出租店都有得租。我一向不是冲第一个的人,事实上还有点管线末端,直到噗浪上评论铺天盖地淹上来,杨蕙如都在PTT回应以后,到礼拜五打工出门,我才去找来看。本来这个封面和阵容,我应该不会去读。但是这是朋友的朋友出的刊物,我还是去找来看了。

    + +

    在租书店漫画杂志架找了三、四遍才找到,差点还找漏了。第一个感想是:这么这么薄?薄到有点出乎意料,和旁边的少快不成比例。虽然厚度不是重点就是了。

    + +

    网路上我看到最精彩的评论,就是自耕农草莓在噗浪上的评论,还有魔法设计师写的传说中的台湾漫画月刊。面对众多批评,杨蕙如后来在PTT上,也写了[没错!]台湾漫画月刊正式创刊了(请多指教)的回应文。回应的姿态很低,也坦白承认了很多缺失,所以我就不太苛求了。

    + +

    我只写一些综合自己读后、外界评论、杨蕙如回应后的感想。上面刊载的七篇作品,分别是(依我主观认知,约略主打程度与印象深浅顺序):

    + + + +

    首先,全彩印刷真的只是纯粹浪费钱、浪费漫画家的人工而已。黑白印刷改成全彩,漫画家很辛苦,印刷费用更会翻上三、五倍。我不知道把钱花在这个地方做什么。大家会买海贼王黑执事的单行本,不是因为它全彩,是因为漫画好看。我了解编辑部全彩印刷的用心,希望多冲几本销量。不过这是杨社长、蓝主编抵押房子的钱和金主的钱,是很宝贵的现金,要花在刀口上,省下来去多烧几期。烧在全彩印刷上没有意义。没有人会为了全彩印刷买漫画。

    + +

    故事内容不清不楚

    + +

    至於漫画好看吗?说实话,只有血多的我是卖火材的小女孩这漾完成度比较高而已:在第一话,就有一个完整的剧情,并把角色的性格、背景等都交代清楚了。其他像少年杀无赦补教人生大宇宙战争年代志皮诺丘之城等等,彷佛是页数到了就下回分晓一样,剧情走一半,不清不楚。这才是第一回,读者忠诚度才刚开始培养,真的以为别人会看你的下一话吗?为什么别人要看你的下一话?

    + +

    杨蕙如说补教人生几乎大家一开始都看不习惯…骂声连连…看到第四五期开始就说…欧…不过满好看的…看到六七八期就说…欧…真的很赞耶…。为什么会认为一本新杂志,一部新人作品,读者有耐性等作者铺八个月的梗?凭什么大胆假设,台湾漫画月刊第一期都不知道有没有人买,一定可以撑到第八期?一开始看不习惯时,为什么不听从自己的直觉?

    + +

    皮诺丘之城是已画了七年、出版六本的网路作品E-depth Angel E涯天使,原作完成度就很高。但是面对月刊连载页数需求时,只能在不清不楚的地方下回分晓,惨不忍睹。而一本漫画杂志竟然不刊新刊,跑去刊登已出版的作品,谁要看?读者网路上看下回就好,干嘛去买?

    + +

    大宇宙战争年代志像是台版的银河英雄传说。一开头花了一整个跨页说明人物设定。人物设定是漫画家笔记本里的东西,拜托请由剧情中带出来,不要叫读者去读你的人物设定。

    + +

    画面很脏

    + +

    画功,就更不要提了。伤心农场网路星球东东锵画风比较干净。血多本来就不是干净的画风。皮诺丘之城粉蜡笔著色不大干净,不过画功很不错。可是三部主打作少年杀无赦补教人生大宇宙战争年代志,都是描照片的。描照片哪有画功可言?描照片不需画功,但画面很脏,照片拍不出来的东西,有魄力的构图,做不出来。这些缺点在三部主打作上展露无遗。

    + +

    我不知道是不是因为要摆脱日式漫画风格,所以主打作全用描照片的。可是描照片不是画漫画,那根本不是用画的。请走出台式风格,不要描照片。

    + +

    一篇粉蜡笔风,三篇描照片的主打作。我不知道这四篇,第二期以后,怎么转成黑白印刷。每期都全彩下去,我怕一千五百万很快就烧光光。

    + +

    综合感想

    + +

    一本漫画杂志,四篇主打作中,有三篇描照片,画面很脏,没有画功,没有精彩有魄力的构图,第一回没有清楚交代吸引人的剧情,前途堪虑。这三篇主打作,连东立漫画新人奖的佳作都比不上。我建议编辑部研读东立漫画新人奖作品集的评审意见,虽不是绝对正确,还是有很多宝贵的前人经验,可供编辑选稿参考。

    + +

    社方很用心不让台湾漫画月刊沾上政治色彩,用心应予肯定。但是还是破了功,玉山周报以一篇台湾漫画月刊 打造本土文创平台,大力推崇台湾漫画月刊

    + +

    杨蕙如不断强调台湾需要本土漫画。台湾的确需要本土漫画,但是台湾不是没有本土漫画。东立多年来赔钱经营本土漫画杂志龙少年星少女,还砸大钱办漫画新人奖,培育出不少优秀漫画家。台湾不是没有本土漫画。台湾需要本土漫画,我也很乐於见到百花盛开,百家齐鸣。但是,少一本台湾漫画月刊,本土漫画不会消失。台湾需要本土漫画这种国族主义为号召,龙少年创刊初期就做过了,失败得很惨。那时候还只有一本龙少年。为什么要重蹈覆辄?

    + +

    写完后,又得知了一些事实。补充一句:真有心搞本土漫画,请不要在杂志最重要的筹备期,让社务空转,让韦宗成这样的核心大咖求去,只剩下这些不三不四的作品。不是抵押了房子烧了钱就叫有决心。把人整个燎下去才叫有决心。到底是不是真的有决心搞台湾漫画?

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 175 | + 176 | + 177 | + 178 | + 179 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0177.html.zh-tw.html b/htdocs/imacat/me/diary/0177.html.zh-tw.html new file mode 120000 index 0000000..653571b --- /dev/null +++ b/htdocs/imacat/me/diary/0177.html.zh-tw.html @@ -0,0 +1 @@ +0177.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0177.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0177.html.zh-tw.xhtml new file mode 100644 index 0000000..4ecbe89 --- /dev/null +++ b/htdocs/imacat/me/diary/0177.html.zh-tw.xhtml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百七十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百七十七

    + +
    + +
    + +
    +
    7.9.’11. 1:34am.
    + +

    台灣漫畫月刊讀後感

    + +
    +台灣漫畫月刊 +

    台灣漫畫月刊

    +
    + +

    這兩天的大事,大概就是楊蕙如出的台灣漫畫月刊創刊號終於發行了。全國各大書店、超商都有得買,漫畫出租店都有得租。我一向不是衝第一個的人,事實上還有點管線末端,直到噗浪上評論鋪天蓋地淹上來,楊蕙如都在PTT回應以後,到禮拜五打工出門,我才去找來看。本來這個封面和陣容,我應該不會去讀。但是這是朋友的朋友出的刊物,我還是去找來看了。

    + +

    在租書店漫畫雜誌架找了三、四遍才找到,差點還找漏了。第一個感想是:這麼這麼薄?薄到有點出乎意料,和旁邊的少快不成比例。雖然厚度不是重點就是了。

    + +

    網路上我看到最精彩的評論,就是自耕農草莓在噗浪上的評論,還有魔法設計師寫的傳說中的台灣漫畫月刊。面對眾多批評,楊蕙如後來在PTT上,也寫了[沒錯!]台灣漫畫月刊正式創刊了(請多指教)的回應文。回應的姿態很低,也坦白承認了很多缺失,所以我就不太苛求了。

    + +

    我只寫一些綜合自己讀後、外界評論、楊蕙如回應後的感想。上面刊載的七篇作品,分別是(依我主觀認知,約略主打程度與印象深淺順序):

    + + + +

    首先,全彩印刷真的只是純粹浪費錢、浪費漫畫家的人工而已。黑白印刷改成全彩,漫畫家很辛苦,印刷費用更會翻上三、五倍。我不知道把錢花在這個地方做什麼。大家會買海賊王黑執事的單行本,不是因為它全彩,是因為漫畫好看。我瞭解編輯部全彩印刷的用心,希望多衝幾本銷量。不過這是楊社長、藍主編抵押房子的錢和金主的錢,是很寶貴的現金,要花在刀口上,省下來去多燒幾期。燒在全彩印刷上沒有意義。沒有人會為了全彩印刷買漫畫。

    + +

    故事內容不清不楚

    + +

    至於漫畫好看嗎?說實話,只有血多的我是賣火材的小女孩這漾完成度比較高而已:在第一話,就有一個完整的劇情,並把角色的性格、背景等都交代清楚了。其他像少年殺無赦補教人生大宇宙戰爭年代誌皮諾丘之城等等,彷彿是頁數到了就下回分曉一樣,劇情走一半,不清不楚。這才是第一回,讀者忠誠度才剛開始培養,真的以為別人會看你的下一話嗎?為什麼別人要看你的下一話?

    + +

    楊蕙如說補教人生幾乎大家一開始都看不習慣…罵聲連連…看到第四五期開始就說…歐…不過滿好看的…看到六七八期就說…歐…真的很讚耶…。為什麼會認為一本新雜誌,一部新人作品,讀者有耐性等作者鋪八個月的梗?憑什麼大膽假設,台灣漫畫月刊第一期都不知道有沒有人買,一定可以撐到第八期?一開始看不習慣時,為什麼不聽從自己的直覺?

    + +

    皮諾丘之城是已畫了七年、出版六本的網路作品E-depth Angel E涯天使,原作完成度就很高。但是面對月刊連載頁數需求時,只能在不清不楚的地方下回分曉,慘不忍睹。而一本漫畫雜誌竟然不刊新刊,跑去刊登已出版的作品,誰要看?讀者網路上看下回就好,幹嘛去買?

    + +

    大宇宙戰爭年代誌像是台版的銀河英雄傳說。一開頭花了一整個跨頁說明人物設定。人物設定是漫畫家筆記本裏的東西,拜託請由劇情中帶出來,不要叫讀者去讀你的人物設定。

    + +

    畫面很髒

    + +

    畫功,就更不要提了。傷心農場網路星球東東鏘畫風比較乾淨。血多本來就不是乾淨的畫風。皮諾丘之城粉蠟筆著色不大乾淨,不過畫功很不錯。可是三部主打作少年殺無赦補教人生大宇宙戰爭年代誌,都是描照片的。描照片哪有畫功可言?描照片不需畫功,但畫面很髒,照片拍不出來的東西,有魄力的構圖,做不出來。這些缺點在三部主打作上展露無遺。

    + +

    我不知道是不是因為要擺脫日式漫畫風格,所以主打作全用描照片的。可是描照片不是畫漫畫,那根本不是用畫的。請走出台式風格,不要描照片。

    + +

    一篇粉蠟筆風,三篇描照片的主打作。我不知道這四篇,第二期以後,怎麼轉成黑白印刷。每期都全彩下去,我怕一千五百萬很快就燒光光。

    + +

    綜合感想

    + +

    一本漫畫雜誌,四篇主打作中,有三篇描照片,畫面很髒,沒有畫功,沒有精彩有魄力的構圖,第一回沒有清楚交代吸引人的劇情,前途堪慮。這三篇主打作,連東立漫畫新人獎的佳作都比不上。我建議編輯部研讀東立漫畫新人獎作品集的評審意見,雖不是絕對正確,還是有很多寶貴的前人經驗,可供編輯選稿參考。

    + +

    社方很用心不讓台灣漫畫月刊沾上政治色彩,用心應予肯定。但是還是破了功,玉山周報以一篇台灣漫畫月刊 打造本土文創平台,大力推崇台灣漫畫月刊

    + +

    楊蕙如不斷強調台灣需要本土漫畫。台灣的確需要本土漫畫,但是台灣不是沒有本土漫畫。東立多年來賠錢經營本土漫畫雜誌龍少年星少女,還砸大錢辦漫畫新人獎,培育出不少優秀漫畫家。台灣不是沒有本土漫畫。台灣需要本土漫畫,我也很樂於見到百花盛開,百家齊鳴。但是,少一本台灣漫畫月刊,本土漫畫不會消失。台灣需要本土漫畫這種國族主義為號召,龍少年創刊初期就做過了,失敗得很慘。那時候還只有一本龍少年。為什麼要重蹈覆輒?

    + +

    寫完後,又得知了一些事實。補充一句:真有心搞本土漫畫,請不要在雜誌最重要的籌備期,讓社務空轉,讓韋宗成這樣的核心大咖求去,只剩下這些不三不四的作品。不是抵押了房子燒了錢就叫有決心。把人整個燎下去才叫有決心。到底是不是真的有決心搞台灣漫畫?

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 175 | + 176 | + 177 | + 178 | + 179 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0178.html.en.html b/htdocs/imacat/me/diary/0178.html.en.html new file mode 120000 index 0000000..7da8d10 --- /dev/null +++ b/htdocs/imacat/me/diary/0178.html.en.html @@ -0,0 +1 @@ +0178.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0178.html.en.xhtml b/htdocs/imacat/me/diary/0178.html.en.xhtml new file mode 100644 index 0000000..92161ed --- /dev/null +++ b/htdocs/imacat/me/diary/0178.html.en.xhtml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 178 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 178

    + +
    + +
    + +
    +
    7.9.’11. 4:49am.
    + +

    Apache與因緣

    + +

    其實,這一篇應該寫在前一篇台灣漫畫月刊讀後感前的,只是拖著忘了寫了。

    + +

    最近,我取得了新的Email信箱:imacat@apache.org。

    + +

    取得這個新的信箱,是因為我加入了Apache OpenOffice.org PMC (Project Management Committee) ,正式加入OpenOffice.org核心團隊,擁有Apache ID、投票權,和直接commit的權力。

    + +

    話說從頭。去年年中,在當時昇陽Sun的朋友力邀下,在COSCUP 2010發表了OpenOffice.org的UNO魔術—那些MS Office做不到的事演講,頗受好評。OSSACC的Eric和自由軟體鑄造場也很感興趣。年底在甲骨文Oracle(原昇陽Sun)、OSSACC與自由軟體鑄造場的促成下,我試圖重新恢復台灣本地OpenOffice.org社群的聚會活動。

    + +

    同一時間,國際OpenOffice.org社群因為對Oracle不滿出走,由FSF主導,向Google、Novell、Canonical、Red Hat等公司募款,9/28宣佈成立The Document Foundation,分枝出LibreOffice,和OpenOffice.org分庭抗禮。

    + +

    年底12/7的Gnome台灣聚會上,我意外在IRC搭上EducOOo/OOo4KidsEric Bachard,協助他們建立EducOO/OOo4Kids台灣站,也成為EducOOo國際團隊的一份子。今年年初,為考研究所,暫時閉關一陣子。三月底考完後,在shelandy的協助下,向OpenOffice.org L10N Project申請,4/1取得了OpenOffice.org Traditional Chinese Translation Lead。

    + +

    向OpenOffice.org L10N Project申請OpenOffice.org Traditional Chinese Translation Lead時,我答應他們,在4/26 OpenOffice.org 3.4 Freeze的期限內,將繁體中文的翻譯做好。我緊急求助台灣社群,在Mouette、Frank、Eric、凱如的努力下,在期限內,把原先剩下四千多字的翻譯,減少到剩下一兩百字。

    + +

    然而,就在台灣翻譯工作如火如荼進行中,4/15 Oracle竟突然宣布未來將把OpenOffice.org轉移給社群經營。因為之前OpenOffice.org的開發社群都轉去做LibreOffice了,和OpenOffice.org L10N Project申請交涉時,對方清一色Email都是@oracle.com,我根本看不到OpenOffice.org在Oracle外還有什麼社群。4/26 OpenOffice.org 3.4 Freeze後,本應釋出的OpenOffice.org 3.4,完全沒有動靜。我們都以為OpenOffice.org就這樣要消失了。

    + +

    過了一個半月,事情突然有了轉機。6/1傳出Oracle要將OpenOffice.org轉給Apache基金會經營。就在觀望時,6/3 EducOOo的Eric Bachard,提醒我把自己的名字填上Initial Committer。我不知道Initial Committer要做什麼,先填再說。直到6/23接到Rob Weir的信,才知道自己成為Apache OpenOffice.org管理團隊的原始成員了,可以申請Apache ID,擁有投票權,可以直接commit。

    + +

    事情的進展,有點出乎我意料。龐大的權力和責任,誠惶誠恐。以後,大概就沒有什麼藉口偷懶,可以說OpenOffice.org上游團隊不收patch了,因為我就是上游團隊成員了。

    + +

    不可思議的是,Apache ID,是我十幾年前一開始接觸自由軟體時的憧憬。沒想到會以這個方式實現。

    + +

    1999年加入精粹,開始學習使用自由軟體。精粹有很多O'Reilly的原文課本,都是專案的團隊作者群自己寫的經典教科書。Philip讓我隨便讀。我一開始讀的,就是Apache。讀完、使用、發現問題、回報bug。當時我看著那些回應我和我討論,Email信箱為@apache.org的Apache團隊成員,心裏不禁想著有為者亦若是。希望有一天,能夠成為國際性大型專案的核心成員。

    + +

    十二年後的今天,在因緣際會之下,我加入的Apache OpenOffice.org的核心管理團隊,擁有了@apache的Email信箱。沒想到當初的憧憬,會以這種方式實現。

    + +

    我發現,我很憧憬的某些人、事,多年以後,不知不覺間,我就會成為我憧憬的那個樣子。高中時參加夏令營,很憧憬一位台大雄友社的學姊,溫柔又有智慧;多年以後,猛然回頭,發現自己在一些朋友心目中,不知不覺成了溫柔又有智慧的大姊姊。這次也是。我很憧憬擁有@apache的Email信箱,作為國際自由軟體核心團隊的一員;多年以後,我竟然也擁有@apache的Email信箱,成為國際自由軟體核心團隊的一員。

    + +

    人生的因緣際遇,真是非常奇妙。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 176 | + 177 | + 178 | + 179 | + 180 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0178.html.zh-cn.html b/htdocs/imacat/me/diary/0178.html.zh-cn.html new file mode 120000 index 0000000..d390027 --- /dev/null +++ b/htdocs/imacat/me/diary/0178.html.zh-cn.html @@ -0,0 +1 @@ +0178.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0178.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0178.html.zh-cn.xhtml new file mode 100644 index 0000000..1252f03 --- /dev/null +++ b/htdocs/imacat/me/diary/0178.html.zh-cn.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百七十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百七十八

    + +
    + +
    + +
    +
    7.9.’11. 4:49am.
    + +

    Apache与因缘

    + +

    其实,这一篇应该写在前一篇台湾漫画月刊读后感前的,只是拖著忘了写了。

    + +

    最近,我取得了新的Email信箱:imacat@apache.org。

    + +

    取得这个新的信箱,是因为我加入了Apache OpenOffice.org PMC (Project Management Committee) ,正式加入OpenOffice.org核心团队,拥有Apache ID、投票权,和直接commit的权力。

    + +

    话说从头。去年年中,在当时升阳Sun的朋友力邀下,在COSCUP 2010发表了OpenOffice.org的UNO魔术—那些MS Office做不到的事演讲,颇受好评。OSSACC的Eric和自由软体铸造场也很感兴趣。年底在甲骨文Oracle(原升阳Sun)、OSSACC与自由软体铸造场的促成下,我试图重新恢复台湾本地OpenOffice.org社群的聚会活动。

    + +

    同一时间,国际OpenOffice.org社群因为对Oracle不满出走,由FSF主导,向Google、Novell、Canonical、Red Hat等公司募款,9/28宣布成立The Document Foundation,分枝出LibreOffice,和OpenOffice.org分庭抗礼。

    + +

    年底12/7的Gnome台湾聚会上,我意外在IRC搭上EducOOo/OOo4KidsEric Bachard,协助他们建立EducOO/OOo4Kids台湾站,也成为EducOOo国际团队的一份子。今年年初,为考研究所,暂时闭关一阵子。三月底考完后,在shelandy的协助下,向OpenOffice.org L10N Project申请,4/1取得了OpenOffice.org Traditional Chinese Translation Lead。

    + +

    向OpenOffice.org L10N Project申请OpenOffice.org Traditional Chinese Translation Lead时,我答应他们,在4/26 OpenOffice.org 3.4 Freeze的期限内,将繁体中文的翻译做好。我紧急求助台湾社群,在Mouette、Frank、Eric、凯如的努力下,在期限内,把原先剩下四千多字的翻译,减少到剩下一两百字。

    + +

    然而,就在台湾翻译工作如火如荼进行中,4/15 Oracle竟突然宣布未来将把OpenOffice.org转移给社群经营。因为之前OpenOffice.org的开发社群都转去做LibreOffice了,和OpenOffice.org L10N Project申请交涉时,对方清一色Email都是@oracle.com,我根本看不到OpenOffice.org在Oracle外还有什么社群。4/26 OpenOffice.org 3.4 Freeze后,本应释出的OpenOffice.org 3.4,完全没有动静。我们都以为OpenOffice.org就这样要消失了。

    + +

    过了一个半月,事情突然有了转机。6/1传出Oracle要将OpenOffice.org转给Apache基金会经营。就在观望时,6/3 EducOOo的Eric Bachard,提醒我把自己的名字填上Initial Committer。我不知道Initial Committer要做什么,先填再说。直到6/23接到Rob Weir的信,才知道自己成为Apache OpenOffice.org管理团队的原始成员了,可以申请Apache ID,拥有投票权,可以直接commit。

    + +

    事情的进展,有点出乎我意料。庞大的权力和责任,诚惶诚恐。以后,大概就没有什么藉口偷懒,可以说OpenOffice.org上游团队不收patch了,因为我就是上游团队成员了。

    + +

    不可思议的是,Apache ID,是我十几年前一开始接触自由软体时的憧憬。没想到会以这个方式实现。

    + +

    1999年加入精粹,开始学习使用自由软体。精粹有很多O'Reilly的原文课本,都是专案的团队作者群自己写的经典教科书。Philip让我随便读。我一开始读的,就是Apache。读完、使用、发现问题、回报bug。当时我看著那些回应我和我讨论,Email信箱为@apache.org的Apache团队成员,心里不禁想著有为者亦若是。希望有一天,能够成为国际性大型专案的核心成员。

    + +

    十二年后的今天,在因缘际会之下,我加入的Apache OpenOffice.org的核心管理团队,拥有了@apache的Email信箱。没想到当初的憧憬,会以这种方式实现。

    + +

    我发现,我很憧憬的某些人、事,多年以后,不知不觉间,我就会成为我憧憬的那个样子。高中时参加夏令营,很憧憬一位台大雄友社的学姊,温柔又有智慧;多年以后,猛然回头,发现自己在一些朋友心目中,不知不觉成了温柔又有智慧的大姊姊。这次也是。我很憧憬拥有@apache的Email信箱,作为国际自由软体核心团队的一员;多年以后,我竟然也拥有@apache的Email信箱,成为国际自由软体核心团队的一员。

    + +

    人生的因缘际遇,真是非常奇妙。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 176 | + 177 | + 178 | + 179 | + 180 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0178.html.zh-tw.html b/htdocs/imacat/me/diary/0178.html.zh-tw.html new file mode 120000 index 0000000..3051607 --- /dev/null +++ b/htdocs/imacat/me/diary/0178.html.zh-tw.html @@ -0,0 +1 @@ +0178.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0178.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0178.html.zh-tw.xhtml new file mode 100644 index 0000000..a528389 --- /dev/null +++ b/htdocs/imacat/me/diary/0178.html.zh-tw.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百七十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百七十八

    + +
    + +
    + +
    +
    7.9.’11. 4:49am.
    + +

    Apache與因緣

    + +

    其實,這一篇應該寫在前一篇台灣漫畫月刊讀後感前的,只是拖著忘了寫了。

    + +

    最近,我取得了新的Email信箱:imacat@apache.org。

    + +

    取得這個新的信箱,是因為我加入了Apache OpenOffice.org PMC (Project Management Committee) ,正式加入OpenOffice.org核心團隊,擁有Apache ID、投票權,和直接commit的權力。

    + +

    話說從頭。去年年中,在當時昇陽Sun的朋友力邀下,在COSCUP 2010發表了OpenOffice.org的UNO魔術—那些MS Office做不到的事演講,頗受好評。OSSACC的Eric和自由軟體鑄造場也很感興趣。年底在甲骨文Oracle(原昇陽Sun)、OSSACC與自由軟體鑄造場的促成下,我試圖重新恢復台灣本地OpenOffice.org社群的聚會活動。

    + +

    同一時間,國際OpenOffice.org社群因為對Oracle不滿出走,由FSF主導,向Google、Novell、Canonical、Red Hat等公司募款,9/28宣佈成立The Document Foundation,分枝出LibreOffice,和OpenOffice.org分庭抗禮。

    + +

    年底12/7的Gnome台灣聚會上,我意外在IRC搭上EducOOo/OOo4KidsEric Bachard,協助他們建立EducOO/OOo4Kids台灣站,也成為EducOOo國際團隊的一份子。今年年初,為考研究所,暫時閉關一陣子。三月底考完後,在shelandy的協助下,向OpenOffice.org L10N Project申請,4/1取得了OpenOffice.org Traditional Chinese Translation Lead。

    + +

    向OpenOffice.org L10N Project申請OpenOffice.org Traditional Chinese Translation Lead時,我答應他們,在4/26 OpenOffice.org 3.4 Freeze的期限內,將繁體中文的翻譯做好。我緊急求助台灣社群,在Mouette、Frank、Eric、凱如的努力下,在期限內,把原先剩下四千多字的翻譯,減少到剩下一兩百字。

    + +

    然而,就在台灣翻譯工作如火如荼進行中,4/15 Oracle竟突然宣布未來將把OpenOffice.org轉移給社群經營。因為之前OpenOffice.org的開發社群都轉去做LibreOffice了,和OpenOffice.org L10N Project申請交涉時,對方清一色Email都是@oracle.com,我根本看不到OpenOffice.org在Oracle外還有什麼社群。4/26 OpenOffice.org 3.4 Freeze後,本應釋出的OpenOffice.org 3.4,完全沒有動靜。我們都以為OpenOffice.org就這樣要消失了。

    + +

    過了一個半月,事情突然有了轉機。6/1傳出Oracle要將OpenOffice.org轉給Apache基金會經營。就在觀望時,6/3 EducOOo的Eric Bachard,提醒我把自己的名字填上Initial Committer。我不知道Initial Committer要做什麼,先填再說。直到6/23接到Rob Weir的信,才知道自己成為Apache OpenOffice.org管理團隊的原始成員了,可以申請Apache ID,擁有投票權,可以直接commit。

    + +

    事情的進展,有點出乎我意料。龐大的權力和責任,誠惶誠恐。以後,大概就沒有什麼藉口偷懶,可以說OpenOffice.org上游團隊不收patch了,因為我就是上游團隊成員了。

    + +

    不可思議的是,Apache ID,是我十幾年前一開始接觸自由軟體時的憧憬。沒想到會以這個方式實現。

    + +

    1999年加入精粹,開始學習使用自由軟體。精粹有很多O'Reilly的原文課本,都是專案的團隊作者群自己寫的經典教科書。Philip讓我隨便讀。我一開始讀的,就是Apache。讀完、使用、發現問題、回報bug。當時我看著那些回應我和我討論,Email信箱為@apache.org的Apache團隊成員,心裏不禁想著有為者亦若是。希望有一天,能夠成為國際性大型專案的核心成員。

    + +

    十二年後的今天,在因緣際會之下,我加入的Apache OpenOffice.org的核心管理團隊,擁有了@apache的Email信箱。沒想到當初的憧憬,會以這種方式實現。

    + +

    我發現,我很憧憬的某些人、事,多年以後,不知不覺間,我就會成為我憧憬的那個樣子。高中時參加夏令營,很憧憬一位台大雄友社的學姊,溫柔又有智慧;多年以後,猛然回頭,發現自己在一些朋友心目中,不知不覺成了溫柔又有智慧的大姊姊。這次也是。我很憧憬擁有@apache的Email信箱,作為國際自由軟體核心團隊的一員;多年以後,我竟然也擁有@apache的Email信箱,成為國際自由軟體核心團隊的一員。

    + +

    人生的因緣際遇,真是非常奇妙。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 176 | + 177 | + 178 | + 179 | + 180 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0179.html.en.html b/htdocs/imacat/me/diary/0179.html.en.html new file mode 120000 index 0000000..c34fa32 --- /dev/null +++ b/htdocs/imacat/me/diary/0179.html.en.html @@ -0,0 +1 @@ +0179.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0179.html.en.xhtml b/htdocs/imacat/me/diary/0179.html.en.xhtml new file mode 100644 index 0000000..65987e4 --- /dev/null +++ b/htdocs/imacat/me/diary/0179.html.en.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 179 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 179

    + +
    + +
    + +
    +
    1.14.’12. 2:31am.
    + +

    表態

    + +

    我會去投蔡英文。先前猶豫了很久,才下決定。有兩個正面和兩個負面的理由。

    + +

    第一個負面的理由是:蔡英文是女人,女性主義者挺女人。這不是正面的理由。女人不一定是好人,白冰冰就是很好的例子。不過,正因為有像白冰冰或辜寬敏那種女人不適合當總統混蛋,才更要力挺,做給那些人看。所以這是負面的理由。

    + +

    第二個負面的理由是:有必要讓政客瞭解到,他們當選一任,不代表一定可以當選第二任。阿扁做不好民進黨就要下台,天經地義。反過來也是這樣。更何況,從大埔農地、國光石化、都更法修正案種種看來,國民黨已經不只是做不好而已。蔡英文也要瞭解,她做不好,也會只有一任,有同樣的下場。

    + +

    正面的理由比較簡單:一、蔡英文是唯一支持同志伴侶權,並且有具體時程目標的候選人。雖然政見支票和執行是兩回事(馬英九633就是前例),不過政客都提出來了,如果沒有給予明確肯定挺同志,有票的話,那以後如何和政客談判?哪有籌碼?

    + +

    二、為了非核家園,一個安全乾淨的台灣。一旦核一、核二、核四發生災變,住在永和,我也是逃不掉的人。

    + +

    就這樣。立委我說過了,因為有邱毅,所以我會去投趙天麟。我不確定趙天麟是不是適合的人選,不過像毅中各表這種水準的傢伙,應該被淘汰。若不是邱毅,我會儘可能投兩黨外,其他適合人選。

    + +

    政黨票我一向是綠黨。綠黨不管在性別議題、同志議題、環境反核議題,即使還沒有進入立法院,都還是長期站在第一線。給不能說話的地球環境一票,是應該的。

    + +
    + +
    + +
    +
    7.11.’11. 11:28am.
    + +

    台灣漫畫月刊後續

    + +

    今天讀了[閒聊] 與台灣漫畫月刊社長面談記,嗯,果然,嗯啊。和我後來前側面瞭解、猜測的狀況所差無幾。相信我之術真是強大啊! (茶)

    + +

    之前多方瞭解了以後,想想覺得,好像不應該罵楊蕙如太多。實際執行的人是主編plamc藍弋丰,不是老闆。自己畫出並主推那種描照片的漫畫的也是藍弋丰。雖然老闆放著不管到這個地步也有錯,而且老闆本來就該概括承受就是了。

    + +

    再翻出之前找到的,Anjou寫的[閒聊] 一點點小八卦。留下來作為自己的剪報筆記。

    + +
    +5.大宇宙是成本最高的一篇 是一個很重要的指標
    + 台灣漫畫是否能發展出工業化 讓整個產業進入量產階段而不單單是單打獨鬥
    + 這部作品充滿了實驗風格 如果說SLOW有甚麼最值得尊敬的地方不是投資
    + 而是願意把錢投資在沒有人嘗試過的道路上 把錢燒在未知的技術與風格上 +
    + +

    所以描照片法,因為不需要長年累積的畫功支撐,不需要有畫功的成​名漫畫家來做,外行人就可以快速出稿,成為plamc藍弋丰主編​力推的工業化新技術嗎?

    + +

    覺得他腦袋裝的可能不是腦漿吧。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 177 | + 178 | + 179 | + 180 | + 181 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0179.html.zh-cn.html b/htdocs/imacat/me/diary/0179.html.zh-cn.html new file mode 120000 index 0000000..b0245d0 --- /dev/null +++ b/htdocs/imacat/me/diary/0179.html.zh-cn.html @@ -0,0 +1 @@ +0179.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0179.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0179.html.zh-cn.xhtml new file mode 100644 index 0000000..7fd6497 --- /dev/null +++ b/htdocs/imacat/me/diary/0179.html.zh-cn.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百七十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百七十九

    + +
    + +
    + +
    +
    1.14.’12. 2:31am.
    + +

    表态

    + +

    我会去投蔡英文。先前犹豫了很久,才下决定。有两个正面和两个负面的理由。

    + +

    第一个负面的理由是:蔡英文是女人,女性主义者挺女人。这不是正面的理由。女人不一定是好人,白冰冰就是很好的例子。不过,正因为有像白冰冰或辜宽敏那种女人不适合当总统混蛋,才更要力挺,做给那些人看。所以这是负面的理由。

    + +

    第二个负面的理由是:有必要让政客了解到,他们当选一任,不代表一定可以当选第二任。阿扁做不好民进党就要下台,天经地义。反过来也是这样。更何况,从大埔农地、国光石化、都更法修正案种种看来,国民党已经不只是做不好而已。蔡英文也要了解,她做不好,也会只有一任,有同样的下场。

    + +

    正面的理由比较简单:一、蔡英文是唯一支持同志伴侣权,并且有具体时程目标的候选人。虽然政见支票和执行是两回事(马英九633就是前例),不过政客都提出来了,如果没有给予明确肯定挺同志,有票的话,那以后如何和政客谈判?哪有筹码?

    + +

    二、为了非核家园,一个安全干净的台湾。一旦核一、核二、核四发生灾变,住在永和,我也是逃不掉的人。

    + +

    就这样。立委我说过了,因为有邱毅,所以我会去投赵天麟。我不确定赵天麟是不是适合的人选,不过像毅中各表这种水准的家伙,应该被淘汰。若不是邱毅,我会尽可能投两党外,其他适合人选。

    + +

    政党票我一向是绿党。绿党不管在性别议题、同志议题、环境反核议题,即使还没有进入立法院,都还是长期站在第一线。给不能说话的地球环境一票,是应该的。

    + +
    + +
    + +
    +
    7.11.’11. 11:28am.
    + +

    台湾漫画月刊后续

    + +

    今天读了[闲聊] 与台湾漫画月刊社长面谈记,嗯,果然,嗯啊。和我后来前侧面了解、猜测的状况所差无几。相信我之术真是强大啊! (茶)

    + +

    之前多方了解了以后,想想觉得,好像不应该骂杨蕙如太多。实际执行的人是主编plamc蓝弋丰,不是老板。自己画出并主推那种描照片的漫画的也是蓝弋丰。虽然老板放著不管到这个地步也有错,而且老板本来就该概括承受就是了。

    + +

    再翻出之前找到的,Anjou写的[闲聊] 一点点小八卦。留下来作为自己的剪报笔记。

    + +
    +5.大宇宙是成本最高的一篇 是一个很重要的指标
    + 台湾漫画是否能发展出工业化 让整个产业进入量产阶段而不单单是单打独斗
    + 这部作品充满了实验风格 如果说SLOW有甚么最值得尊敬的地方不是投资
    + 而是愿意把钱投资在没有人尝试过的道路上 把钱烧在未知的技术与风格上 +
    + +

    所以描照片法,因为不需要长年累积的画功支撑,不需要有画功的成​名漫画家来做,外行人就可以快速出稿,成为plamc蓝弋丰主编​力推的工业化新技术吗?

    + +

    觉得他脑袋装的可能不是脑浆吧。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 177 | + 178 | + 179 | + 180 | + 181 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0179.html.zh-tw.html b/htdocs/imacat/me/diary/0179.html.zh-tw.html new file mode 120000 index 0000000..60b3318 --- /dev/null +++ b/htdocs/imacat/me/diary/0179.html.zh-tw.html @@ -0,0 +1 @@ +0179.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0179.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0179.html.zh-tw.xhtml new file mode 100644 index 0000000..701c764 --- /dev/null +++ b/htdocs/imacat/me/diary/0179.html.zh-tw.xhtml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百七十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百七十九

    + +
    + +
    + +
    +
    1.14.’12. 2:31am.
    + +

    表態

    + +

    我會去投蔡英文。先前猶豫了很久,才下決定。有兩個正面和兩個負面的理由。

    + +

    第一個負面的理由是:蔡英文是女人,女性主義者挺女人。這不是正面的理由。女人不一定是好人,白冰冰就是很好的例子。不過,正因為有像白冰冰或辜寬敏那種女人不適合當總統混蛋,才更要力挺,做給那些人看。所以這是負面的理由。

    + +

    第二個負面的理由是:有必要讓政客瞭解到,他們當選一任,不代表一定可以當選第二任。阿扁做不好民進黨就要下台,天經地義。反過來也是這樣。更何況,從大埔農地、國光石化、都更法修正案種種看來,國民黨已經不只是做不好而已。蔡英文也要瞭解,她做不好,也會只有一任,有同樣的下場。

    + +

    正面的理由比較簡單:一、蔡英文是唯一支持同志伴侶權,並且有具體時程目標的候選人。雖然政見支票和執行是兩回事(馬英九633就是前例),不過政客都提出來了,如果沒有給予明確肯定挺同志,有票的話,那以後如何和政客談判?哪有籌碼?

    + +

    二、為了非核家園,一個安全乾淨的台灣。一旦核一、核二、核四發生災變,住在永和,我也是逃不掉的人。

    + +

    就這樣。立委我說過了,因為有邱毅,所以我會去投趙天麟。我不確定趙天麟是不是適合的人選,不過像毅中各表這種水準的傢伙,應該被淘汰。若不是邱毅,我會儘可能投兩黨外,其他適合人選。

    + +

    政黨票我一向是綠黨。綠黨不管在性別議題、同志議題、環境反核議題,即使還沒有進入立法院,都還是長期站在第一線。給不能說話的地球環境一票,是應該的。

    + +
    + +
    + +
    +
    7.11.’11. 11:28am.
    + +

    台灣漫畫月刊後續

    + +

    今天讀了[閒聊] 與台灣漫畫月刊社長面談記,嗯,果然,嗯啊。和我後來前側面瞭解、猜測的狀況所差無幾。相信我之術真是強大啊! (茶)

    + +

    之前多方瞭解了以後,想想覺得,好像不應該罵楊蕙如太多。實際執行的人是主編plamc藍弋丰,不是老闆。自己畫出並主推那種描照片的漫畫的也是藍弋丰。雖然老闆放著不管到這個地步也有錯,而且老闆本來就該概括承受就是了。

    + +

    再翻出之前找到的,Anjou寫的[閒聊] 一點點小八卦。留下來作為自己的剪報筆記。

    + +
    +5.大宇宙是成本最高的一篇 是一個很重要的指標
    + 台灣漫畫是否能發展出工業化 讓整個產業進入量產階段而不單單是單打獨鬥
    + 這部作品充滿了實驗風格 如果說SLOW有甚麼最值得尊敬的地方不是投資
    + 而是願意把錢投資在沒有人嘗試過的道路上 把錢燒在未知的技術與風格上 +
    + +

    所以描照片法,因為不需要長年累積的畫功支撐,不需要有畫功的成​名漫畫家來做,外行人就可以快速出稿,成為plamc藍弋丰主編​力推的工業化新技術嗎?

    + +

    覺得他腦袋裝的可能不是腦漿吧。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 177 | + 178 | + 179 | + 180 | + 181 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0180.html.en.html b/htdocs/imacat/me/diary/0180.html.en.html new file mode 120000 index 0000000..41b9c44 --- /dev/null +++ b/htdocs/imacat/me/diary/0180.html.en.html @@ -0,0 +1 @@ +0180.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0180.html.en.xhtml b/htdocs/imacat/me/diary/0180.html.en.xhtml new file mode 100644 index 0000000..7dbc191 --- /dev/null +++ b/htdocs/imacat/me/diary/0180.html.en.xhtml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 180 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 180

    + +
    + +
    + +
    +
    3.27.’12. 9:15pm.
    + +

    人生是一齣喜劇

    + +

    人生本來就是一齣喜劇。想起來的都是開心的笑,那也算沒有遺憾了。

    + +

    我一直覺得喜劇是一件非常深奧的事。我小時候對演戲也很有興趣,雖然後來沒有走上戲劇的路,但總以為我要是認真演,也可以演得很好。一直到離開台大後,有一陣子跟著一個文史工作室跑田野,工作室的另一個分身是野台劇團,我也在公演的劇目中軋一個小角色,飾演媒婆。排練的時候,我怎麼演都不行,連走路都走不好。經歷過挫折,我才體會了喜劇要演得好,是一件非常了不起的事。也讓我對幾位喜劇大師:卓別林、金凱瑞、周星馳等,懷抱著深深的景仰。

    + +

    我覺得喜劇是對理性的反諷,呈現出世界的理性外表下的深層矛盾。人世原本就是非理性、無常的,人試圖用理性去解釋,把世界框架起來。這也不是壞事,至少可以避免自己發瘋。但在表面的理性之下,非理性的矛盾還是依舊在那裏。能夠洞悉社會的深層矛盾,並將它用恢諧的方式呈現出來,必需要有獨到的社會洞察力,才做得到,才能產生出像卓別林的工業時代、金凱瑞的楚門的世界、周星馳的武狀元蘇乞兒一樣的經典作品。

    + +

    所以,我喜歡跟我奶奶講一些亂說話說笑,亂說一些表面文字正確,可是不知所云的無厘頭笑話。很多年以前,我曾經編過一個天上的黑雲來跟她打招呼的故事,或是當她的面,問她我阿嬤在家嗎,之類的。她剛開始會斥責我亂講,久了習慣了,會被我逗笑,後來甚至會順著我的話搭話,然後兩個人笑成一團。我也用這些笑話,來瞭解她的思考還清不清楚,分不分得出什麼是正確的話,什麼是不合理的胡說八道。我很訝異地發現,即使是今年初,她日常生活的記憶已經很困難了,我問她我阿嬤在家嗎,她還是會想想,回過頭去找:嗯,阿嬤是在家嗎?不知道耶。然後轉回頭來笑著看我,我們兩個笑成一團。她還是分得出我在跟她開玩笑,她的腦袋還是有部份是清楚的。

    + +

    記得最深的,是有一年,我妹妹回台灣,我們全家去城市光廊。當時我和我妹兩個人牽著她的手,一邊一個。我照樣跟她胡說八道亂說話,她也跟著亂搭話,邊說邊笑。我妹被我們感染,也跟著亂說一堆無厘頭的話,氣氛越來越嗨。走到一面牆,牆上有個小時鐘,我奶奶突然蹦出一句:你們知道嗎?那個時鐘的指針,是有人躲在裏面轉的!因為太大聲了,周圍的人都有聽到,很多人都轉過頭來看。她突然發現很丟臉,我們又笑成一團。我嚇了一跳。她竟然瞎掰出原創的梗了,知道什麼是真的,什麼是假的,還能夠從理性的虛實中,自己找出破綻來。

    + +

    昨晚深夜,打完幾通電話,寫幾封信,拜託朋友交待一些事後,繼續唸書時,不知不覺想起這些過去的事。不管是多年前她身體精神都良好的時候,還是今年過年回去,她已經有很嚴重記憶困難的時候,想起來的畫面,都是開心的笑臉,我不由得笑了。人生本來就是一齣喜劇。想起來的都是開心的笑,那也算沒有遺憾了。

    + +
    + +
    + +
    +
    2.24.’12. 12:07pm.
    + +

    Apache OpenOffice 3.4 新功能搶先看

    + +

    重要:這不是官方公告,也不是官方公告中譯。請參閱完整內容

    + +

    (其實是正好前兩天有iThome的專訪,所以整理了一下新功能。 ^^; )

    + +

    在眾人的努力之下, Apache OpenOffice 過幾個月即將釋出。這段期間 Apache OpenOffice Project Management Committee 不斷努力,將 GPL 的 OpenOffice.org 改寫為 Apache License 的 Apache OpenOffice 。這部份的工作已經完工,開發程式碼也已經上線。目前大家正在努力做 3.4 版釋出前的結案工作,務求在最短時間內,呈現一個全新又讓大家滿意的 Apache OpenOffice 3.4 。

    + +

    在正式釋出前,我們先來搶先看看, Apache OpenOffice 3.4 版有哪些新的改變。

    + +
      +
    1. OpenOffice.org 正式改名為 Apache OpenOffice : OpenOffice.org 去年四月由 Oracle 轉移給 Apache 軟體基金會管理, 3.4 版是由 Apache 軟體基金會管理下的第一個釋出版本。我們討論過後,決定去掉茸長的 .org ,以 Apache OpenOffice 新名釋出。改名也宣告一個新生命的開始。過去十年來, OpenOffice.org 受到許多人的支持,在商業辦公教育方面,擁有非常廣泛的應用。謝謝大家過去十年來對 OpenOffice.org 的支持,也希望大家支持新生的 Apache OpenOffice 。
    2. + +
    3. 中文翻譯更新:去年四月在中文團隊不眠不休的努力之下,翻整了 OpenOffice.org 的翻譯,除了補足四千多條未譯條目,更依一般辦公室軟體中文約定成俗用法、第一線推廣者的推廣經驗等,全面翻新舊有的翻譯。如今這些翻譯即將在 Apache OpenOffice 3.4 上釋出。在釋出前還會有最後的翻譯校正,也請大家一起來協助,讓 Apache OpenOffice 的中文更好。
    4. + +
    5. 中文字數修正:字數,是辦公室軟體的商業關鍵應用。翻譯、出版業的稿酬計算,甚至是學校學生作業等,均需依賴正確的字數計算。過往 OpenOffice.org 團隊因沒有亞洲語系的開發人力,字數問題長期無解。 Apache OpenOffice 在中文開發人力的加入後,已經修正了中文字數問題了。
    6. + +
    7. Data Pilot 資料助理改名 Pivot Table 樞鈕分析表:微軟 Excel 的樞鈕分析表,在 OpenOffice.org Calc 下叫做資料助理,讓很多第一線的推廣者、使用者深感困擾。這個問題在 3.4 版後已解決, OpenOffice.org Calc 的資料助理 Data Pilot 中英文,均改名為樞鈕分析表 Pivot Table 。
    8. + +
    9. 支援 SVG 向量圖檔:不管在 Writer 、 Calc 、 Impress 、 Draw ,讓你的專業美術版面設計,更能發揮得淋漓盡至。
    10. + +
    11. Impress 頁面配置簡化。
    12. + +
    13. 支援 ODF 1.2 版開放文件格式。
    14. + +
    15. Apache OpenOffice 的開放原始碼版權,由 GPL 變更為 Apache License :變更為 Apache License 意味著全面翻新的程式碼,及更多的自由,希望全新的程式碼和授權,能夠帶來更穩定的版本、更公開的參與、更廣泛的應用。
    16. + +
    17. (還有許多新的改變,等待你來發掘…)
    18. +
    + +

    3.4 版是 Apache 基金會接手維護後的第一個版本,也會是 Apache OpenOffice 3 系列版本的最終版。接下來我們將朝 Apache OpenOffice 4 版前進,會加入全新的使用介面設計,以提供給大家更好的使用介面和使用經驗。也請大家繼續支持 Apache OpenOffice !

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 178 | + 179 | + 180 | + 181 | + 182 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0180.html.zh-cn.html b/htdocs/imacat/me/diary/0180.html.zh-cn.html new file mode 120000 index 0000000..5fa0d1c --- /dev/null +++ b/htdocs/imacat/me/diary/0180.html.zh-cn.html @@ -0,0 +1 @@ +0180.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0180.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0180.html.zh-cn.xhtml new file mode 100644 index 0000000..90d4c05 --- /dev/null +++ b/htdocs/imacat/me/diary/0180.html.zh-cn.xhtml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百八十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百八十

    + +
    + +
    + +
    +
    3.27.’12. 9:15pm.
    + +

    人生是一出喜剧

    + +

    人生本来就是一出喜剧。想起来的都是开心的笑,那也算没有遗憾了。

    + +

    我一直觉得喜剧是一件非常深奥的事。我小时候对演戏也很有兴趣,虽然后来没有走上戏剧的路,但总以为我要是认真演,也可以演得很好。一直到离开台大后,有一阵子跟著一个文史工作室跑田野,工作室的另一个分身是野台剧团,我也在公演的剧目中轧一个小角色,饰演媒婆。排练的时候,我怎么演都不行,连走路都走不好。经历过挫折,我才体会了喜剧要演得好,是一件非常了不起的事。也让我对几位喜剧大师:卓别林、金凯瑞、周星驰等,怀抱著深深的景仰。

    + +

    我觉得喜剧是对理性的反讽,呈现出世界的理性外表下的深层矛盾。人世原本就是非理性、无常的,人试图用理性去解释,把世界框架起来。这也不是坏事,至少可以避免自己发疯。但在表面的理性之下,非理性的矛盾还是依旧在那里。能够洞悉社会的深层矛盾,并将它用恢谐的方式呈现出来,必需要有独到的社会洞察力,才做得到,才能产生出像卓别林的工业时代、金凯瑞的楚门的世界、周星驰的武状元苏乞儿一样的经典作品。

    + +

    所以,我喜欢跟我奶奶讲一些乱说话说笑,乱说一些表面文字正确,可是不知所云的无厘头笑话。很多年以前,我曾经编过一个天上的黑云来跟她打招呼的故事,或是当她的面,问她我阿嬷在家吗,之类的。她刚开始会斥责我乱讲,久了习惯了,会被我逗笑,后来甚至会顺著我的话搭话,然后两个人笑成一团。我也用这些笑话,来了解她的思考还清不清楚,分不分得出什么是正确的话,什么是不合理的胡说八道。我很讶异地发现,即使是今年初,她日常生活的记忆已经很困难了,我问她我阿嬷在家吗,她还是会想想,回过头去找:嗯,阿嬷是在家吗?不知道耶。然后转回头来笑著看我,我们两个笑成一团。她还是分得出我在跟她开玩笑,她的脑袋还是有部份是清楚的。

    + +

    记得最深的,是有一年,我妹妹回台湾,我们全家去城市光廊。当时我和我妹两个人牵著她的手,一边一个。我照样跟她胡说八道乱说话,她也跟著乱搭话,边说边笑。我妹被我们感染,也跟著乱说一堆无厘头的话,气氛越来越嗨。走到一面墙,墙上有个小时钟,我奶奶突然蹦出一句:你们知道吗?那个时钟的指针,是有人躲在里面转的!因为太大声了,周围的人都有听到,很多人都转过头来看。她突然发现很丢脸,我们又笑成一团。我吓了一跳。她竟然瞎掰出原创的梗了,知道什么是真的,什么是假的,还能够从理性的虚实中,自己找出破绽来。

    + +

    昨晚深夜,打完几通电话,写几封信,拜托朋友交待一些事后,继续念书时,不知不觉想起这些过去的事。不管是多年前她身体精神都良好的时候,还是今年过年回去,她已经有很严重记忆困难的时候,想起来的画面,都是开心的笑脸,我不由得笑了。人生本来就是一出喜剧。想起来的都是开心的笑,那也算没有遗憾了。

    + +
    + +
    + +
    +
    2.24.’12. 12:07pm.
    + +

    Apache OpenOffice 3.4 新功能抢先看

    + +

    重要:这不是官方公告,也不是官方公告中译。请参阅完整内容

    + +

    (其实是正好前两天有iThome的专访,所以整理了一下新功能。 ^^; )

    + +

    在众人的努力之下, Apache OpenOffice 过几个月即将释出。这段期间 Apache OpenOffice Project Management Committee 不断努力,将 GPL 的 OpenOffice.org 改写为 Apache License 的 Apache OpenOffice 。这部份的工作已经完工,开发程式码也已经上线。目前大家正在努力做 3.4 版释出前的结案工作,务求在最短时间内,呈现一个全新又让大家满意的 Apache OpenOffice 3.4 。

    + +

    在正式释出前,我们先来抢先看看, Apache OpenOffice 3.4 版有哪些新的改变。

    + +
      +
    1. OpenOffice.org 正式改名为 Apache OpenOffice : OpenOffice.org 去年四月由 Oracle 转移给 Apache 软体基金会管理, 3.4 版是由 Apache 软体基金会管理下的第一个释出版本。我们讨论过后,决定去掉茸长的 .org ,以 Apache OpenOffice 新名释出。改名也宣告一个新生命的开始。过去十年来, OpenOffice.org 受到许多人的支持,在商业办公教育方面,拥有非常广泛的应用。谢谢大家过去十年来对 OpenOffice.org 的支持,也希望大家支持新生的 Apache OpenOffice 。
    2. + +
    3. 中文翻译更新:去年四月在中文团队不眠不休的努力之下,翻整了 OpenOffice.org 的翻译,除了补足四千多条未译条目,更依一般办公室软体中文约定成俗用法、第一线推广者的推广经验等,全面翻新旧有的翻译。如今这些翻译即将在 Apache OpenOffice 3.4 上释出。在释出前还会有最后的翻译校正,也请大家一起来协助,让 Apache OpenOffice 的中文更好。
    4. + +
    5. 中文字数修正:字数,是办公室软体的商业关键应用。翻译、出版业的稿酬计算,甚至是学校学生作业等,均需依赖正确的字数计算。过往 OpenOffice.org 团队因没有亚洲语系的开发人力,字数问题长期无解。 Apache OpenOffice 在中文开发人力的加入后,已经修正了中文字数问题了。
    6. + +
    7. Data Pilot 资料助理改名 Pivot Table 枢钮分析表:微软 Excel 的枢钮分析表,在 OpenOffice.org Calc 下叫做资料助理,让很多第一线的推广者、使用者深感困扰。这个问题在 3.4 版后已解决, OpenOffice.org Calc 的资料助理 Data Pilot 中英文,均改名为枢钮分析表 Pivot Table 。
    8. + +
    9. 支援 SVG 向量图档:不管在 Writer 、 Calc 、 Impress 、 Draw ,让你的专业美术版面设计,更能发挥得淋漓尽至。
    10. + +
    11. Impress 页面配置简化。
    12. + +
    13. 支援 ODF 1.2 版开放文件格式。
    14. + +
    15. Apache OpenOffice 的开放原始码版权,由 GPL 变更为 Apache License :变更为 Apache License 意味著全面翻新的程式码,及更多的自由,希望全新的程式码和授权,能够带来更稳定的版本、更公开的参与、更广泛的应用。
    16. + +
    17. (还有许多新的改变,等待你来发掘…)
    18. +
    + +

    3.4 版是 Apache 基金会接手维护后的第一个版本,也会是 Apache OpenOffice 3 系列版本的最终版。接下来我们将朝 Apache OpenOffice 4 版前进,会加入全新的使用介面设计,以提供给大家更好的使用介面和使用经验。也请大家继续支持 Apache OpenOffice !

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 178 | + 179 | + 180 | + 181 | + 182 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0180.html.zh-tw.html b/htdocs/imacat/me/diary/0180.html.zh-tw.html new file mode 120000 index 0000000..1be2dac --- /dev/null +++ b/htdocs/imacat/me/diary/0180.html.zh-tw.html @@ -0,0 +1 @@ +0180.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0180.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0180.html.zh-tw.xhtml new file mode 100644 index 0000000..466c731 --- /dev/null +++ b/htdocs/imacat/me/diary/0180.html.zh-tw.xhtml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百八十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百八十

    + +
    + +
    + +
    +
    3.27.’12. 9:15pm.
    + +

    人生是一齣喜劇

    + +

    人生本來就是一齣喜劇。想起來的都是開心的笑,那也算沒有遺憾了。

    + +

    我一直覺得喜劇是一件非常深奧的事。我小時候對演戲也很有興趣,雖然後來沒有走上戲劇的路,但總以為我要是認真演,也可以演得很好。一直到離開台大後,有一陣子跟著一個文史工作室跑田野,工作室的另一個分身是野台劇團,我也在公演的劇目中軋一個小角色,飾演媒婆。排練的時候,我怎麼演都不行,連走路都走不好。經歷過挫折,我才體會了喜劇要演得好,是一件非常了不起的事。也讓我對幾位喜劇大師:卓別林、金凱瑞、周星馳等,懷抱著深深的景仰。

    + +

    我覺得喜劇是對理性的反諷,呈現出世界的理性外表下的深層矛盾。人世原本就是非理性、無常的,人試圖用理性去解釋,把世界框架起來。這也不是壞事,至少可以避免自己發瘋。但在表面的理性之下,非理性的矛盾還是依舊在那裏。能夠洞悉社會的深層矛盾,並將它用恢諧的方式呈現出來,必需要有獨到的社會洞察力,才做得到,才能產生出像卓別林的工業時代、金凱瑞的楚門的世界、周星馳的武狀元蘇乞兒一樣的經典作品。

    + +

    所以,我喜歡跟我奶奶講一些亂說話說笑,亂說一些表面文字正確,可是不知所云的無厘頭笑話。很多年以前,我曾經編過一個天上的黑雲來跟她打招呼的故事,或是當她的面,問她我阿嬤在家嗎,之類的。她剛開始會斥責我亂講,久了習慣了,會被我逗笑,後來甚至會順著我的話搭話,然後兩個人笑成一團。我也用這些笑話,來瞭解她的思考還清不清楚,分不分得出什麼是正確的話,什麼是不合理的胡說八道。我很訝異地發現,即使是今年初,她日常生活的記憶已經很困難了,我問她我阿嬤在家嗎,她還是會想想,回過頭去找:嗯,阿嬤是在家嗎?不知道耶。然後轉回頭來笑著看我,我們兩個笑成一團。她還是分得出我在跟她開玩笑,她的腦袋還是有部份是清楚的。

    + +

    記得最深的,是有一年,我妹妹回台灣,我們全家去城市光廊。當時我和我妹兩個人牽著她的手,一邊一個。我照樣跟她胡說八道亂說話,她也跟著亂搭話,邊說邊笑。我妹被我們感染,也跟著亂說一堆無厘頭的話,氣氛越來越嗨。走到一面牆,牆上有個小時鐘,我奶奶突然蹦出一句:你們知道嗎?那個時鐘的指針,是有人躲在裏面轉的!因為太大聲了,周圍的人都有聽到,很多人都轉過頭來看。她突然發現很丟臉,我們又笑成一團。我嚇了一跳。她竟然瞎掰出原創的梗了,知道什麼是真的,什麼是假的,還能夠從理性的虛實中,自己找出破綻來。

    + +

    昨晚深夜,打完幾通電話,寫幾封信,拜託朋友交待一些事後,繼續唸書時,不知不覺想起這些過去的事。不管是多年前她身體精神都良好的時候,還是今年過年回去,她已經有很嚴重記憶困難的時候,想起來的畫面,都是開心的笑臉,我不由得笑了。人生本來就是一齣喜劇。想起來的都是開心的笑,那也算沒有遺憾了。

    + +
    + +
    + +
    +
    2.24.’12. 12:07pm.
    + +

    Apache OpenOffice 3.4 新功能搶先看

    + +

    重要:這不是官方公告,也不是官方公告中譯。請參閱完整內容

    + +

    (其實是正好前兩天有iThome的專訪,所以整理了一下新功能。 ^^; )

    + +

    在眾人的努力之下, Apache OpenOffice 過幾個月即將釋出。這段期間 Apache OpenOffice Project Management Committee 不斷努力,將 GPL 的 OpenOffice.org 改寫為 Apache License 的 Apache OpenOffice 。這部份的工作已經完工,開發程式碼也已經上線。目前大家正在努力做 3.4 版釋出前的結案工作,務求在最短時間內,呈現一個全新又讓大家滿意的 Apache OpenOffice 3.4 。

    + +

    在正式釋出前,我們先來搶先看看, Apache OpenOffice 3.4 版有哪些新的改變。

    + +
      +
    1. OpenOffice.org 正式改名為 Apache OpenOffice : OpenOffice.org 去年四月由 Oracle 轉移給 Apache 軟體基金會管理, 3.4 版是由 Apache 軟體基金會管理下的第一個釋出版本。我們討論過後,決定去掉茸長的 .org ,以 Apache OpenOffice 新名釋出。改名也宣告一個新生命的開始。過去十年來, OpenOffice.org 受到許多人的支持,在商業辦公教育方面,擁有非常廣泛的應用。謝謝大家過去十年來對 OpenOffice.org 的支持,也希望大家支持新生的 Apache OpenOffice 。
    2. + +
    3. 中文翻譯更新:去年四月在中文團隊不眠不休的努力之下,翻整了 OpenOffice.org 的翻譯,除了補足四千多條未譯條目,更依一般辦公室軟體中文約定成俗用法、第一線推廣者的推廣經驗等,全面翻新舊有的翻譯。如今這些翻譯即將在 Apache OpenOffice 3.4 上釋出。在釋出前還會有最後的翻譯校正,也請大家一起來協助,讓 Apache OpenOffice 的中文更好。
    4. + +
    5. 中文字數修正:字數,是辦公室軟體的商業關鍵應用。翻譯、出版業的稿酬計算,甚至是學校學生作業等,均需依賴正確的字數計算。過往 OpenOffice.org 團隊因沒有亞洲語系的開發人力,字數問題長期無解。 Apache OpenOffice 在中文開發人力的加入後,已經修正了中文字數問題了。
    6. + +
    7. Data Pilot 資料助理改名 Pivot Table 樞鈕分析表:微軟 Excel 的樞鈕分析表,在 OpenOffice.org Calc 下叫做資料助理,讓很多第一線的推廣者、使用者深感困擾。這個問題在 3.4 版後已解決, OpenOffice.org Calc 的資料助理 Data Pilot 中英文,均改名為樞鈕分析表 Pivot Table 。
    8. + +
    9. 支援 SVG 向量圖檔:不管在 Writer 、 Calc 、 Impress 、 Draw ,讓你的專業美術版面設計,更能發揮得淋漓盡至。
    10. + +
    11. Impress 頁面配置簡化。
    12. + +
    13. 支援 ODF 1.2 版開放文件格式。
    14. + +
    15. Apache OpenOffice 的開放原始碼版權,由 GPL 變更為 Apache License :變更為 Apache License 意味著全面翻新的程式碼,及更多的自由,希望全新的程式碼和授權,能夠帶來更穩定的版本、更公開的參與、更廣泛的應用。
    16. + +
    17. (還有許多新的改變,等待你來發掘…)
    18. +
    + +

    3.4 版是 Apache 基金會接手維護後的第一個版本,也會是 Apache OpenOffice 3 系列版本的最終版。接下來我們將朝 Apache OpenOffice 4 版前進,會加入全新的使用介面設計,以提供給大家更好的使用介面和使用經驗。也請大家繼續支持 Apache OpenOffice !

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 178 | + 179 | + 180 | + 181 | + 182 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0181.html.en.html b/htdocs/imacat/me/diary/0181.html.en.html new file mode 120000 index 0000000..0d8abbc --- /dev/null +++ b/htdocs/imacat/me/diary/0181.html.en.html @@ -0,0 +1 @@ +0181.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0181.html.en.xhtml b/htdocs/imacat/me/diary/0181.html.en.xhtml new file mode 100644 index 0000000..8716542 --- /dev/null +++ b/htdocs/imacat/me/diary/0181.html.en.xhtml @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 181 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 181

    + +
    + +
    + +
    +
    12.8.’12. 10:32am.
    + +

    台灣的媒體環境

    + +

    覺得台灣新聞媒體環境,和美國越來越像。

    + +

    在美國,電視新聞媒體幾乎都是共和黨資本家所有物。經營電視新聞媒體需要大筆資金,非常依賴有錢人支持的共和黨。電視新聞媒體每天都在報導論七八糟麻蔽人心的新聞,等到選舉則砲口一致對準歐巴馬、民主黨,對準社會福利、健保政策、同志權益死命打,什麼謊話都說得出口,什麼假新聞都做得出來。美國的主要輿論,幾乎都控制在有錢的資本家手中。

    + +

    然而,即使電視新聞媒體口徑一致,沒日沒夜攻擊歐巴馬和民主黨,歐巴馬還是選贏了,不論總得票數,還是選舉人票數,都大贏共和黨。資本家控制的輿論,和民意完全背道而馳。

    + +

    台灣現在的電子媒體也幾乎完全為資本家所控制,可是媒體輿論也完全和民意背道而馳。

    + +

    在美國,除了少數像紐約時報外,只能寄望新興獨立媒體了。台灣的新興獨立媒體呢?

    + +
    + +
    + +
    +
    10.30.’12. 10:53pm.
    + +

    近況(二)

    + +

    下個禮拜, Apache 軟體基金會 (ASF) 的年會 ApacheCon Europe 2012 將在德國辛斯海姆的萊茵.內卡體育場舉行,一連四天 (11/5-8) 。

    + +

    我投稿的「 Mosaic Fun with OpenOffice Calc 」獲選,將在第二天的下午 4:10 ,發表演講。

    + +

    為此,我這個禮拜五會出發去德國,參加今年的 ApacheCon Europe 2012 。

    + +

    這趟旅行的目的,除了發表演講外,最重要的目的,是認識 OpenOffice 官方團隊中的其他夥伴,並討論 OpenOffice 的未來發展方向。

    + +

    此外,我也想試著重組已經停擺多年的 Apache Women ,試著把 Apache 軟體基金會的各國女生組織起來,鼓勵更多女生參與 Apache 軟體基金會的運作。

    + +

    台灣本地(及香港) OpenOffice 社群的朋友們,如果有什麼大方向上的想法或建議(不是 Bug 修正),歡迎提出來,我可以一併跟整個團隊討論。

    + +

    如果有女生想參與 Apache 軟體基金會的各項專案(包括 OpenOffice ),有什麼想法,也歡迎提出來。

    + +

    我想應該還會碰到 Apache 軟體基金會的很多人,包括 Apache HTTP server 的團隊、 Hadoop 的團隊等等。

    + +

    就這樣。有很多朋友已經知道了,不過我想還是再公開說明一次。謝謝大家的支持與參與。 ^_*'

    + +
    + +
    + +
    +
    10.30.’12. 10:36pm.
    + +

    近況

    + +

    兩個禮拜前 (10/18) , OpenOffice 終於由 Apache 育成專案下的子專案結業,昇格為 Apache 的普通專案了。

    + +

    OpenOffice 在育成期間,其實只有「準管理團隊 (Podling Project Management Committee, PPMC) 」,不是「管理團隊 (Project Management Committee, PMC) 」。我其實是「準管理團隊」成員,不是「管理團隊」成員。其實我也是約半年前,才弄懂這個區別。

    + +

    OpenOffice 結業,團隊也要重組,成立「管理團隊 PMC 」取代「準管理團隊 PPMC 」。在過程中,我很榮幸受提名,進入 26 人管理團隊中,正式成為 OpenOffice 管理團隊的成員。提名名次是第 7 名。

    + +

    提名過程中,我也提案應讓亞洲人和女性進入管理團隊, OpenOffice 才能顧及亞洲語言的問題,並鼓勵女性投入參與。新團隊中有一位台灣人(我),一位中國人,一位日本人。女性部份,因為我也想不到其他人選,目前只有我一位而已。

    + +

    我目前除了是 OpenOffice 官方管理團隊成員外,也是 OpenOffice 多國論壇的總站長, Wiki 站長。因接任這兩個站長之故,也加入 Apache Infrastructure 團隊,隸屬 Apache Infrastructure 團隊。

    + +

    就這樣。有些朋友已經知道了,不過我想還是說明清楚。過去自稱管理團隊成員,混淆之處,請各位朋友見諒。並請繼續支持 OpenOffice ,謝謝!

    + +
    + +
    + +
    +
    8.4.’12. 8:29am.
    + +

    換裝

    + +

    昨晚整理了一整夜最近新買衣服的自拍照片,以及買這些衣服的心情,直到清晨。晚上睡覺時,做了一個奇怪的夢。夢中,參加了妹妹的婚禮,又碰上學校的宿營。在半山坡上的營地中,我一路跌跌撞撞的,喜愛的衣物、鞋子,一路遺失在每個階梯口的垃圾堆積點。想起時回頭瘋狂去找,卻再也找不回來。

    + +

    隨著每一次的換裝,一部份的自己,再也找不回來。對失去的自我感到恐懼,卻也還是只能繼續向前走了。處女座的我,不安全感強烈,對於自己,總是希望能保留全部。即使是再也用不到的自我,我以往總覺得,也是我全部歷史的一部份,也讓我難以割捨。這樣的捨棄,沒有回頭路的捨棄,讓我感到恐懼。

    + +

    回頭反省,領悟到我在這幾件衣服中所追求的勇敢,想對自己的身體更有自信,其本質,就是要對抗我自己的不安全感與恐懼。

    + +
    + +
    + +
    +
    6.3.’12. 9:06am.
    + +

    遇到好賣家

    + +

    禮拜三深夜(其實是禮拜四凌晨)詢問、下單,還得到立即回覆。說是三天到貨,結果真的禮拜五就到貨了,趕上了禮拜六的OpenOffice 3.4 Release Party。Yahoo!奇摩拍賣還是有好賣家的嘛!

    + +

    不過還是要說一下:訂價設80元,運費1200元,怎麼說都不是誠實的行為。

    + +

    清理追蹤清單時,再仔細看看幾家不同賣家的關於我,開始有點心得挑賣家了。

    + +
      +
    1. 關於我不提供退換貨的就拒絕往來。這種賣家絕對惹不起。又不是沒有吃過虧,沒拿到東西誰知道有沒有問題?
    2. + +
    3. 看評價不是看評價數,而是看評價內容。很多買家怕被報復性負評,會邊給正評邊抱怨。
    4. + +
    5. 最重要的是看下單和給評的時間差,買家的義務只有付款,賣家最主要的服務就是送貨。送貨要兩個禮拜的,也別想它出問題三天幫你解決。
    6. + +
    7. 輕鬆付很重要,省一筆匯款手續費,買賣流程由Yahoo!奇摩拍賣站方控管,也比較不吃虧。
    8. +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 179 | + 180 | + 181 | + 182 | + 183 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0181.html.zh-cn.html b/htdocs/imacat/me/diary/0181.html.zh-cn.html new file mode 120000 index 0000000..b7f3a06 --- /dev/null +++ b/htdocs/imacat/me/diary/0181.html.zh-cn.html @@ -0,0 +1 @@ +0181.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0181.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0181.html.zh-cn.xhtml new file mode 100644 index 0000000..540f2d5 --- /dev/null +++ b/htdocs/imacat/me/diary/0181.html.zh-cn.xhtml @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百八十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百八十一

    + +
    + +
    + +
    +
    12.8.’12. 10:32am.
    + +

    台湾的媒体环境

    + +

    觉得台湾新闻媒体环境,和美国越来越像。

    + +

    在美国,电视新闻媒体几乎都是共和党资本家所有物。经营电视新闻媒体需要大笔资金,非常依赖有钱人支持的共和党。电视新闻媒体每天都在报导论七八糟麻蔽人心的新闻,等到选举则炮口一致对准欧巴马、民主党,对准社会福利、健保政策、同志权益死命打,什么谎话都说得出口,什么假新闻都做得出来。美国的主要舆论,几乎都控制在有钱的资本家手中。

    + +

    然而,即使电视新闻媒体口径一致,没日没夜攻击欧巴马和民主党,欧巴马还是选赢了,不论总得票数,还是选举人票数,都大赢共和党。资本家控制的舆论,和民意完全背道而驰。

    + +

    台湾现在的电子媒体也几乎完全为资本家所控制,可是媒体舆论也完全和民意背道而驰。

    + +

    在美国,除了少数像纽约时报外,只能寄望新兴独立媒体了。台湾的新兴独立媒体呢?

    + +
    + +
    + +
    +
    10.30.’12. 10:53pm.
    + +

    近况(二)

    + +

    下个礼拜, Apache 软体基金会 (ASF) 的年会 ApacheCon Europe 2012 将在德国辛斯海姆的莱茵.内卡体育场举行,一连四天 (11/5-8) 。

    + +

    我投稿的「 Mosaic Fun with OpenOffice Calc 」获选,将在第二天的下午 4:10 ,发表演讲。

    + +

    为此,我这个礼拜五会出发去德国,参加今年的 ApacheCon Europe 2012 。

    + +

    这趟旅行的目的,除了发表演讲外,最重要的目的,是认识 OpenOffice 官方团队中的其他伙伴,并讨论 OpenOffice 的未来发展方向。

    + +

    此外,我也想试著重组已经停摆多年的 Apache Women ,试著把 Apache 软体基金会的各国女生组织起来,鼓励更多女生参与 Apache 软体基金会的运作。

    + +

    台湾本地(及香港) OpenOffice 社群的朋友们,如果有什么大方向上的想法或建议(不是 Bug 修正),欢迎提出来,我可以一并跟整个团队讨论。

    + +

    如果有女生想参与 Apache 软体基金会的各项专案(包括 OpenOffice ),有什么想法,也欢迎提出来。

    + +

    我想应该还会碰到 Apache 软体基金会的很多人,包括 Apache HTTP server 的团队、 Hadoop 的团队等等。

    + +

    就这样。有很多朋友已经知道了,不过我想还是再公开说明一次。谢谢大家的支持与参与。 ^_*'

    + +
    + +
    + +
    +
    10.30.’12. 10:36pm.
    + +

    近况

    + +

    两个礼拜前 (10/18) , OpenOffice 终於由 Apache 育成专案下的子专案结业,升格为 Apache 的普通专案了。

    + +

    OpenOffice 在育成期间,其实只有「准管理团队 (Podling Project Management Committee, PPMC) 」,不是「管理团队 (Project Management Committee, PMC) 」。我其实是「准管理团队」成员,不是「管理团队」成员。其实我也是约半年前,才弄懂这个区别。

    + +

    OpenOffice 结业,团队也要重组,成立「管理团队 PMC 」取代「准管理团队 PPMC 」。在过程中,我很荣幸受提名,进入 26 人管理团队中,正式成为 OpenOffice 管理团队的成员。提名名次是第 7 名。

    + +

    提名过程中,我也提案应让亚洲人和女性进入管理团队, OpenOffice 才能顾及亚洲语言的问题,并鼓励女性投入参与。新团队中有一位台湾人(我),一位中国人,一位日本人。女性部份,因为我也想不到其他人选,目前只有我一位而已。

    + +

    我目前除了是 OpenOffice 官方管理团队成员外,也是 OpenOffice 多国论坛的总站长, Wiki 站长。因接任这两个站长之故,也加入 Apache Infrastructure 团队,隶属 Apache Infrastructure 团队。

    + +

    就这样。有些朋友已经知道了,不过我想还是说明清楚。过去自称管理团队成员,混淆之处,请各位朋友见谅。并请继续支持 OpenOffice ,谢谢!

    + +
    + +
    + +
    +
    8.4.’12. 8:29am.
    + +

    换装

    + +

    昨晚整理了一整夜最近新买衣服的自拍照片,以及买这些衣服的心情,直到清晨。晚上睡觉时,做了一个奇怪的梦。梦中,参加了妹妹的婚礼,又碰上学校的宿营。在半山坡上的营地中,我一路跌跌撞撞的,喜爱的衣物、鞋子,一路遗失在每个阶梯口的垃圾堆积点。想起时回头疯狂去找,却再也找不回来。

    + +

    随著每一次的换装,一部份的自己,再也找不回来。对失去的自我感到恐惧,却也还是只能继续向前走了。处女座的我,不安全感强烈,对於自己,总是希望能保留全部。即使是再也用不到的自我,我以往总觉得,也是我全部历史的一部份,也让我难以割舍。这样的舍弃,没有回头路的舍弃,让我感到恐惧。

    + +

    回头反省,领悟到我在这几件衣服中所追求的勇敢,想对自己的身体更有自信,其本质,就是要对抗我自己的不安全感与恐惧。

    + +
    + +
    + +
    +
    6.3.’12. 9:06am.
    + +

    遇到好卖家

    + +

    礼拜三深夜(其实是礼拜四凌晨)询问、下单,还得到立即回覆。说是三天到货,结果真的礼拜五就到货了,赶上了礼拜六的OpenOffice 3.4 Release Party。Yahoo!奇摩拍卖还是有好卖家的嘛!

    + +

    不过还是要说一下:订价设80元,运费1200元,怎么说都不是诚实的行为。

    + +

    清理追踪清单时,再仔细看看几家不同卖家的关於我,开始有点心得挑卖家了。

    + +
      +
    1. 关於我不提供退换货的就拒绝往来。这种卖家绝对惹不起。又不是没有吃过亏,没拿到东西谁知道有没有问题?
    2. + +
    3. 看评价不是看评价数,而是看评价内容。很多买家怕被报复性负评,会边给正评边抱怨。
    4. + +
    5. 最重要的是看下单和给评的时间差,买家的义务只有付款,卖家最主要的服务就是送货。送货要两个礼拜的,也别想它出问题三天帮你解决。
    6. + +
    7. 轻松付很重要,省一笔汇款手续费,买卖流程由Yahoo!奇摩拍卖站方控管,也比较不吃亏。
    8. +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 179 | + 180 | + 181 | + 182 | + 183 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0181.html.zh-tw.html b/htdocs/imacat/me/diary/0181.html.zh-tw.html new file mode 120000 index 0000000..e6a0992 --- /dev/null +++ b/htdocs/imacat/me/diary/0181.html.zh-tw.html @@ -0,0 +1 @@ +0181.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0181.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0181.html.zh-tw.xhtml new file mode 100644 index 0000000..764698e --- /dev/null +++ b/htdocs/imacat/me/diary/0181.html.zh-tw.xhtml @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百八十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百八十一

    + +
    + +
    + +
    +
    12.8.’12. 10:32am.
    + +

    台灣的媒體環境

    + +

    覺得台灣新聞媒體環境,和美國越來越像。

    + +

    在美國,電視新聞媒體幾乎都是共和黨資本家所有物。經營電視新聞媒體需要大筆資金,非常依賴有錢人支持的共和黨。電視新聞媒體每天都在報導論七八糟麻蔽人心的新聞,等到選舉則砲口一致對準歐巴馬、民主黨,對準社會福利、健保政策、同志權益死命打,什麼謊話都說得出口,什麼假新聞都做得出來。美國的主要輿論,幾乎都控制在有錢的資本家手中。

    + +

    然而,即使電視新聞媒體口徑一致,沒日沒夜攻擊歐巴馬和民主黨,歐巴馬還是選贏了,不論總得票數,還是選舉人票數,都大贏共和黨。資本家控制的輿論,和民意完全背道而馳。

    + +

    台灣現在的電子媒體也幾乎完全為資本家所控制,可是媒體輿論也完全和民意背道而馳。

    + +

    在美國,除了少數像紐約時報外,只能寄望新興獨立媒體了。台灣的新興獨立媒體呢?

    + +
    + +
    + +
    +
    10.30.’12. 10:53pm.
    + +

    近況(二)

    + +

    下個禮拜, Apache 軟體基金會 (ASF) 的年會 ApacheCon Europe 2012 將在德國辛斯海姆的萊茵.內卡體育場舉行,一連四天 (11/5-8) 。

    + +

    我投稿的「 Mosaic Fun with OpenOffice Calc 」獲選,將在第二天的下午 4:10 ,發表演講。

    + +

    為此,我這個禮拜五會出發去德國,參加今年的 ApacheCon Europe 2012 。

    + +

    這趟旅行的目的,除了發表演講外,最重要的目的,是認識 OpenOffice 官方團隊中的其他夥伴,並討論 OpenOffice 的未來發展方向。

    + +

    此外,我也想試著重組已經停擺多年的 Apache Women ,試著把 Apache 軟體基金會的各國女生組織起來,鼓勵更多女生參與 Apache 軟體基金會的運作。

    + +

    台灣本地(及香港) OpenOffice 社群的朋友們,如果有什麼大方向上的想法或建議(不是 Bug 修正),歡迎提出來,我可以一併跟整個團隊討論。

    + +

    如果有女生想參與 Apache 軟體基金會的各項專案(包括 OpenOffice ),有什麼想法,也歡迎提出來。

    + +

    我想應該還會碰到 Apache 軟體基金會的很多人,包括 Apache HTTP server 的團隊、 Hadoop 的團隊等等。

    + +

    就這樣。有很多朋友已經知道了,不過我想還是再公開說明一次。謝謝大家的支持與參與。 ^_*'

    + +
    + +
    + +
    +
    10.30.’12. 10:36pm.
    + +

    近況

    + +

    兩個禮拜前 (10/18) , OpenOffice 終於由 Apache 育成專案下的子專案結業,昇格為 Apache 的普通專案了。

    + +

    OpenOffice 在育成期間,其實只有「準管理團隊 (Podling Project Management Committee, PPMC) 」,不是「管理團隊 (Project Management Committee, PMC) 」。我其實是「準管理團隊」成員,不是「管理團隊」成員。其實我也是約半年前,才弄懂這個區別。

    + +

    OpenOffice 結業,團隊也要重組,成立「管理團隊 PMC 」取代「準管理團隊 PPMC 」。在過程中,我很榮幸受提名,進入 26 人管理團隊中,正式成為 OpenOffice 管理團隊的成員。提名名次是第 7 名。

    + +

    提名過程中,我也提案應讓亞洲人和女性進入管理團隊, OpenOffice 才能顧及亞洲語言的問題,並鼓勵女性投入參與。新團隊中有一位台灣人(我),一位中國人,一位日本人。女性部份,因為我也想不到其他人選,目前只有我一位而已。

    + +

    我目前除了是 OpenOffice 官方管理團隊成員外,也是 OpenOffice 多國論壇的總站長, Wiki 站長。因接任這兩個站長之故,也加入 Apache Infrastructure 團隊,隸屬 Apache Infrastructure 團隊。

    + +

    就這樣。有些朋友已經知道了,不過我想還是說明清楚。過去自稱管理團隊成員,混淆之處,請各位朋友見諒。並請繼續支持 OpenOffice ,謝謝!

    + +
    + +
    + +
    +
    8.4.’12. 8:29am.
    + +

    換裝

    + +

    昨晚整理了一整夜最近新買衣服的自拍照片,以及買這些衣服的心情,直到清晨。晚上睡覺時,做了一個奇怪的夢。夢中,參加了妹妹的婚禮,又碰上學校的宿營。在半山坡上的營地中,我一路跌跌撞撞的,喜愛的衣物、鞋子,一路遺失在每個階梯口的垃圾堆積點。想起時回頭瘋狂去找,卻再也找不回來。

    + +

    隨著每一次的換裝,一部份的自己,再也找不回來。對失去的自我感到恐懼,卻也還是只能繼續向前走了。處女座的我,不安全感強烈,對於自己,總是希望能保留全部。即使是再也用不到的自我,我以往總覺得,也是我全部歷史的一部份,也讓我難以割捨。這樣的捨棄,沒有回頭路的捨棄,讓我感到恐懼。

    + +

    回頭反省,領悟到我在這幾件衣服中所追求的勇敢,想對自己的身體更有自信,其本質,就是要對抗我自己的不安全感與恐懼。

    + +
    + +
    + +
    +
    6.3.’12. 9:06am.
    + +

    遇到好賣家

    + +

    禮拜三深夜(其實是禮拜四凌晨)詢問、下單,還得到立即回覆。說是三天到貨,結果真的禮拜五就到貨了,趕上了禮拜六的OpenOffice 3.4 Release Party。Yahoo!奇摩拍賣還是有好賣家的嘛!

    + +

    不過還是要說一下:訂價設80元,運費1200元,怎麼說都不是誠實的行為。

    + +

    清理追蹤清單時,再仔細看看幾家不同賣家的關於我,開始有點心得挑賣家了。

    + +
      +
    1. 關於我不提供退換貨的就拒絕往來。這種賣家絕對惹不起。又不是沒有吃過虧,沒拿到東西誰知道有沒有問題?
    2. + +
    3. 看評價不是看評價數,而是看評價內容。很多買家怕被報復性負評,會邊給正評邊抱怨。
    4. + +
    5. 最重要的是看下單和給評的時間差,買家的義務只有付款,賣家最主要的服務就是送貨。送貨要兩個禮拜的,也別想它出問題三天幫你解決。
    6. + +
    7. 輕鬆付很重要,省一筆匯款手續費,買賣流程由Yahoo!奇摩拍賣站方控管,也比較不吃虧。
    8. +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 179 | + 180 | + 181 | + 182 | + 183 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0182.html.en.html b/htdocs/imacat/me/diary/0182.html.en.html new file mode 120000 index 0000000..107f055 --- /dev/null +++ b/htdocs/imacat/me/diary/0182.html.en.html @@ -0,0 +1 @@ +0182.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0182.html.en.xhtml b/htdocs/imacat/me/diary/0182.html.en.xhtml new file mode 100644 index 0000000..b74d30d --- /dev/null +++ b/htdocs/imacat/me/diary/0182.html.en.xhtml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 182 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 182

    + +
    + +
    + +
    +
    4.5.’13. 4:13am.
    + +

    Temple Run 2 搭訕記

    + +

    禮拜三去南港,因著 Temple Run 2 ,被一個婆婆搭訕,也搭訕到一個蘿莉。

    + +

    故事一

    + +

    回程在板南線上,拿起手機來玩 Temple Run 2 。玩一玩突然感覺到後面的視線。記得是剛剛上車的國小女生,直接走到我後面,貼著我背後看。

    + +

    死掉的時候,我決定轉頭過去,問她要不要玩。她沒說話,臉上表情很高興。我就把手機拿給她。給小孩子開心一下也不錯。

    + +

    結果就這樣一路跑了四五站,跑得超順,我都看傻了。這可不是開心一下也不錯的等級了。這下子糟了,萬一害她沉迷錯過下車,就不好意思了。

    + +

    好不容易在轉車站前死掉了,一千多個金幣。我嚇到了(也算賺到了),問她:妳有玩過嗎?

    + +

    有玩過姊姊的。

    + +

    正好我們都要轉車,一路上隨便聊聊。原來只有小學五年級,玩過姊姊手機上的 Temple Run 2 ,很著迷。

    + +

    分開時跟她說,她快點長大,才能買自己的手機。

    + +

    故事二

    + +

    回程在南勢角線上,拿起手機來玩 Temple Run 2 。玩一玩旁邊婆婆突然跟我搭話:妳好厲害!妳怎麼玩的這麼厲害!

    + +

    我愣了一下,不知道該怎麼解釋我在玩什麼給婆婆聽,虛應一下,隨口問問:婆婆妳知道這是什麼嗎?

    + +

    知道啊,我也有玩,只是我都玩不好,沒有像妳那麼聰明。還是年輕人比較聰明!

    + +

    我心裏想:這和聰明應該沒有關係吧,應該是反應力或熟練的關係。沒啦,多玩幾次就熟了。

    + +

    哪有,我就是玩不好。說著,婆婆從包包拿出手機打開,然後開始玩 Temple Run 2 。我看著傻了。

    + +
    + +
    + +
    +
    3.12.’13. 2:48am.
    + +

    戀愛養成遊戲

    + +

    上次玩戀愛養成遊戲,已經是十年前的事了,玩的是買的補帖 DOS 遊戲大全集的。那時候就不大愛玩,對只是點點選項的冒險類遊戲沒什麼興趣。可是很多ACG梗,都是戀愛養成遊戲的梗,這兩年想找來玩,又因為都是 Windows 遊戲,我平常不在 Windows 上而卻步。去年想到可以用 Transformer 平板玩,可是看 Android 上戀愛遊戲還是空的。今年發現 Android 上的戀愛物語:湛藍的回憶,忍不住就下載來玩玩看。

    + +

    戀愛物語:湛藍的回憶和它的續作戀愛物語:我的機器女友戀愛物語3夢想之翼,日式風格,很意外地,都是台製遊戲。玩起來很不順手,才發現原來是 J2ME 的 Java 手機遊戲,用模擬器移殖上來 Android 的,操作方式則是模擬手機的數字鍵和方向鍵。

    + +

    戀愛物語:湛藍的回憶玩到最後女主角死了,玩完心裏動搖了一下,悶悶的心情不好。後來上網搜尋,發現竟然有好的結局攻略!把我心裏偷偷流的眼淚還給我!

    + +

    好吧,戀愛物語:湛藍的回憶的劇情真的很棒。另兩集續作就沒這麼好了。

    + +

    其實戀愛物語:湛藍的回憶與其說是遊戲,不如說是小說。好長的劇情,從頭到尾選項不到20個,幾乎是一路下一步到結束。其中一個選項,選錯了女主角星奈就死了。感覺有點莫名其妙,有沒有玩到好結局,有點碰運氣的意味。戀愛物語3夢想之翼甚至全部十幾個選項都要選對。感覺不像在感受故事,沒看攻略的話,感覺像強迫症一樣,玩個無數次猜選項來拼好結局。

    + +

    原來像這樣強迫症似地一直試結局,還有幾乎就是走劇情一樣沒什麼選項一直下一步,就是現在戀愛養成遊戲的樣子。嗯,對這種玩法,我還是不大有興趣。

    + +
    + +
    + +
    +
    1.30.’13. 0:26am.
    + +
    +拿到底座第一天1/24(五)晚上,睡前放rinse上,一轉頭就滑下去,邊角撞到地板,面板就壞了。Transformer有外圈鐵框保護,不小心邊角撞到地板,不嚴重的話不會有事。PadFone 2底座沒有外圈鐵框,撞會直接撞在觸控玻璃上。加上背後的插槽,背面不平整,很容易滑落。一開始拿去,華碩說太新了,面板維修費標準還沒出來。後來回報維修費5490元,太狠了。一般面板維修店家也只修普通液晶面板,不修觸控面板。只好認賠去買新的。 +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 180 | + 181 | + 182 | + 183 | + 184 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0182.html.zh-cn.html b/htdocs/imacat/me/diary/0182.html.zh-cn.html new file mode 120000 index 0000000..357422d --- /dev/null +++ b/htdocs/imacat/me/diary/0182.html.zh-cn.html @@ -0,0 +1 @@ +0182.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0182.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0182.html.zh-cn.xhtml new file mode 100644 index 0000000..1856481 --- /dev/null +++ b/htdocs/imacat/me/diary/0182.html.zh-cn.xhtml @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百八十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百八十二

    + +
    + +
    + +
    +
    4.5.’13. 4:13am.
    + +

    Temple Run 2 搭讪记

    + +

    礼拜三去南港,因著 Temple Run 2 ,被一个婆婆搭讪,也搭讪到一个萝莉。

    + +

    故事一

    + +

    回程在板南线上,拿起手机来玩 Temple Run 2 。玩一玩突然感觉到后面的视线。记得是刚刚上车的国小女生,直接走到我后面,贴著我背后看。

    + +

    死掉的时候,我决定转头过去,问她要不要玩。她没说话,脸上表情很高兴。我就把手机拿给她。给小孩子开心一下也不错。

    + +

    结果就这样一路跑了四五站,跑得超顺,我都看傻了。这可不是开心一下也不错的等级了。这下子糟了,万一害她沉迷错过下车,就不好意思了。

    + +

    好不容易在转车站前死掉了,一千多个金币。我吓到了(也算赚到了),问她:你有玩过吗?

    + +

    有玩过姊姊的。

    + +

    正好我们都要转车,一路上随便聊聊。原来只有小学五年级,玩过姊姊手机上的 Temple Run 2 ,很著迷。

    + +

    分开时跟她说,她快点长大,才能买自己的手机。

    + +

    故事二

    + +

    回程在南势角线上,拿起手机来玩 Temple Run 2 。玩一玩旁边婆婆突然跟我搭话:你好厉害!你怎么玩的这么厉害!

    + +

    我愣了一下,不知道该怎么解释我在玩什么给婆婆听,虚应一下,随口问问:婆婆你知道这是什么吗?

    + +

    知道啊,我也有玩,只是我都玩不好,没有像你那么聪明。还是年轻人比较聪明!

    + +

    我心里想:这和聪明应该没有关系吧,应该是反应力或熟练的关系。没啦,多玩几次就熟了。

    + +

    哪有,我就是玩不好。说著,婆婆从包包拿出手机打开,然后开始玩 Temple Run 2 。我看著傻了。

    + +
    + +
    + +
    +
    3.12.’13. 2:48am.
    + +

    恋爱养成游戏

    + +

    上次玩恋爱养成游戏,已经是十年前的事了,玩的是买的补帖 DOS 游戏大全集的。那时候就不大爱玩,对只是点点选项的冒险类游戏没什么兴趣。可是很多ACG梗,都是恋爱养成游戏的梗,这两年想找来玩,又因为都是 Windows 游戏,我平常不在 Windows 上而却步。去年想到可以用 Transformer 平板玩,可是看 Android 上恋爱游戏还是空的。今年发现 Android 上的恋爱物语:湛蓝的回忆,忍不住就下载来玩玩看。

    + +

    恋爱物语:湛蓝的回忆和它的续作恋爱物语:我的机器女友恋爱物语3梦想之翼,日式风格,很意外地,都是台制游戏。玩起来很不顺手,才发现原来是 J2ME 的 Java 手机游戏,用模拟器移殖上来 Android 的,操作方式则是模拟手机的数字键和方向键。

    + +

    恋爱物语:湛蓝的回忆玩到最后女主角死了,玩完心里动摇了一下,闷闷的心情不好。后来上网搜寻,发现竟然有好的结局攻略!把我心里偷偷流的眼泪还给我!

    + +

    好吧,恋爱物语:湛蓝的回忆的剧情真的很棒。另两集续作就没这么好了。

    + +

    其实恋爱物语:湛蓝的回忆与其说是游戏,不如说是小说。好长的剧情,从头到尾选项不到20个,几乎是一路下一步到结束。其中一个选项,选错了女主角星奈就死了。感觉有点莫名其妙,有没有玩到好结局,有点碰运气的意味。恋爱物语3梦想之翼甚至全部十几个选项都要选对。感觉不像在感受故事,没看攻略的话,感觉像强迫症一样,玩个无数次猜选项来拼好结局。

    + +

    原来像这样强迫症似地一直试结局,还有几乎就是走剧情一样没什么选项一直下一步,就是现在恋爱养成游戏的样子。嗯,对这种玩法,我还是不大有兴趣。

    + +
    + +
    + +
    +
    1.30.’13. 0:26am.
    + +
    +拿到底座第一天1/24(五)晚上,睡前放rinse上,一转头就滑下去,边角撞到地板,面板就坏了。Transformer有外圈铁框保护,不小心边角撞到地板,不严重的话不会有事。PadFone 2底座没有外圈铁框,撞会直接撞在触控玻璃上。加上背后的插槽,背面不平整,很容易滑落。一开始拿去,华硕说太新了,面板维修费标准还没出来。后来回报维修费5490元,太狠了。一般面板维修店家也只修普通液晶面板,不修触控面板。只好认赔去买新的。 +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 180 | + 181 | + 182 | + 183 | + 184 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0182.html.zh-tw.html b/htdocs/imacat/me/diary/0182.html.zh-tw.html new file mode 120000 index 0000000..58df078 --- /dev/null +++ b/htdocs/imacat/me/diary/0182.html.zh-tw.html @@ -0,0 +1 @@ +0182.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0182.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0182.html.zh-tw.xhtml new file mode 100644 index 0000000..2e35d98 --- /dev/null +++ b/htdocs/imacat/me/diary/0182.html.zh-tw.xhtml @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百八十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百八十二

    + +
    + +
    + +
    +
    4.5.’13. 4:13am.
    + +

    Temple Run 2 搭訕記

    + +

    禮拜三去南港,因著 Temple Run 2 ,被一個婆婆搭訕,也搭訕到一個蘿莉。

    + +

    故事一

    + +

    回程在板南線上,拿起手機來玩 Temple Run 2 。玩一玩突然感覺到後面的視線。記得是剛剛上車的國小女生,直接走到我後面,貼著我背後看。

    + +

    死掉的時候,我決定轉頭過去,問她要不要玩。她沒說話,臉上表情很高興。我就把手機拿給她。給小孩子開心一下也不錯。

    + +

    結果就這樣一路跑了四五站,跑得超順,我都看傻了。這可不是開心一下也不錯的等級了。這下子糟了,萬一害她沉迷錯過下車,就不好意思了。

    + +

    好不容易在轉車站前死掉了,一千多個金幣。我嚇到了(也算賺到了),問她:妳有玩過嗎?

    + +

    有玩過姊姊的。

    + +

    正好我們都要轉車,一路上隨便聊聊。原來只有小學五年級,玩過姊姊手機上的 Temple Run 2 ,很著迷。

    + +

    分開時跟她說,她快點長大,才能買自己的手機。

    + +

    故事二

    + +

    回程在南勢角線上,拿起手機來玩 Temple Run 2 。玩一玩旁邊婆婆突然跟我搭話:妳好厲害!妳怎麼玩的這麼厲害!

    + +

    我愣了一下,不知道該怎麼解釋我在玩什麼給婆婆聽,虛應一下,隨口問問:婆婆妳知道這是什麼嗎?

    + +

    知道啊,我也有玩,只是我都玩不好,沒有像妳那麼聰明。還是年輕人比較聰明!

    + +

    我心裏想:這和聰明應該沒有關係吧,應該是反應力或熟練的關係。沒啦,多玩幾次就熟了。

    + +

    哪有,我就是玩不好。說著,婆婆從包包拿出手機打開,然後開始玩 Temple Run 2 。我看著傻了。

    + +
    + +
    + +
    +
    3.12.’13. 2:48am.
    + +

    戀愛養成遊戲

    + +

    上次玩戀愛養成遊戲,已經是十年前的事了,玩的是買的補帖 DOS 遊戲大全集的。那時候就不大愛玩,對只是點點選項的冒險類遊戲沒什麼興趣。可是很多ACG梗,都是戀愛養成遊戲的梗,這兩年想找來玩,又因為都是 Windows 遊戲,我平常不在 Windows 上而卻步。去年想到可以用 Transformer 平板玩,可是看 Android 上戀愛遊戲還是空的。今年發現 Android 上的戀愛物語:湛藍的回憶,忍不住就下載來玩玩看。

    + +

    戀愛物語:湛藍的回憶和它的續作戀愛物語:我的機器女友戀愛物語3夢想之翼,日式風格,很意外地,都是台製遊戲。玩起來很不順手,才發現原來是 J2ME 的 Java 手機遊戲,用模擬器移殖上來 Android 的,操作方式則是模擬手機的數字鍵和方向鍵。

    + +

    戀愛物語:湛藍的回憶玩到最後女主角死了,玩完心裏動搖了一下,悶悶的心情不好。後來上網搜尋,發現竟然有好的結局攻略!把我心裏偷偷流的眼淚還給我!

    + +

    好吧,戀愛物語:湛藍的回憶的劇情真的很棒。另兩集續作就沒這麼好了。

    + +

    其實戀愛物語:湛藍的回憶與其說是遊戲,不如說是小說。好長的劇情,從頭到尾選項不到20個,幾乎是一路下一步到結束。其中一個選項,選錯了女主角星奈就死了。感覺有點莫名其妙,有沒有玩到好結局,有點碰運氣的意味。戀愛物語3夢想之翼甚至全部十幾個選項都要選對。感覺不像在感受故事,沒看攻略的話,感覺像強迫症一樣,玩個無數次猜選項來拼好結局。

    + +

    原來像這樣強迫症似地一直試結局,還有幾乎就是走劇情一樣沒什麼選項一直下一步,就是現在戀愛養成遊戲的樣子。嗯,對這種玩法,我還是不大有興趣。

    + +
    + +
    + +
    +
    1.30.’13. 0:26am.
    + +
    +拿到底座第一天1/24(五)晚上,睡前放rinse上,一轉頭就滑下去,邊角撞到地板,面板就壞了。Transformer有外圈鐵框保護,不小心邊角撞到地板,不嚴重的話不會有事。PadFone 2底座沒有外圈鐵框,撞會直接撞在觸控玻璃上。加上背後的插槽,背面不平整,很容易滑落。一開始拿去,華碩說太新了,面板維修費標準還沒出來。後來回報維修費5490元,太狠了。一般面板維修店家也只修普通液晶面板,不修觸控面板。只好認賠去買新的。 +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 180 | + 181 | + 182 | + 183 | + 184 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0183.html.en.html b/htdocs/imacat/me/diary/0183.html.en.html new file mode 120000 index 0000000..420053a --- /dev/null +++ b/htdocs/imacat/me/diary/0183.html.en.html @@ -0,0 +1 @@ +0183.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0183.html.en.xhtml b/htdocs/imacat/me/diary/0183.html.en.xhtml new file mode 100644 index 0000000..2798951 --- /dev/null +++ b/htdocs/imacat/me/diary/0183.html.en.xhtml @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 183 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 183

    + +
    + +
    + +
    +
    6.26.’13. 1:51pm.
    + +

    多餘的話

    + +

    總覺得自己在後巷講了多餘的話。算了。

    + +
    + +
    + +
    +
    6.26.’13. 1:48pm.
    + +

    日記的時間

    + +

    旅舍日記的時間好像怪怪的。算了口試完再修理好了。

    + +
    + +
    + +
    +
    6.26.’13. 1:46pm.
    + +

    日記

    + +

    重新用旅舍日記代替噗浪和部落格,宣洩自己想講的話。發現這樣也不錯,不是社群網路,不用在意別人有沒有回應。這是前 Web 2.0 時代的網路日記,單向的宣洩而已,感覺也沒什麼不好。

    + +

    而且日後還不用擔心被人家人肉搜索。嗯,好啦,是比較不用擔心。

    + +

    說起來為什麼非要用社群網路不可呢?

    + +
    + +
    + +
    +
    6.26.’13. 1:43pm.
    + +

    進度

    + +

    荒廢了四天,開始看老師改的東西。本來禮拜天就開始看了,禮拜一美文提醒了我研究方法老師改很多,心理壓力又來了,就又擱著。做好研究方法被完全打掉的最壞心理準備後,才回頭看。不敢仔細看,先快速翻過,再回頭細看,好像也沒有那麼糟。嗯啊。

    + +

    果然還是不行,我的心理強度還是不夠。平常只是個衝動的笨蛋而已。要保持平常心才寫得下去。平常心啊!

    + +

    好啦這四天我都在看漫畫。看完了 Sket Dance 學園救援團,看完了週刊少女野崎君。

    + +
    + +
    + +
    +
    6.26.’13. 1:35pm.
    + +

    關閉社交網路

    + +

    昨天在噗浪和臉書上宣佈閉關鎖帳號。鎖帳號具體來說,產生新一組的亂數密碼,新密碼另外存檔後,把密碼換成新密碼。這樣我就換了我不記得的密碼,每次要用同樣的亂數種子去產生,或是開檔去找,很麻煩。但是臨時要上噗浪臉書,也是可以。

    + +

    其實新密碼也可以不用另外存檔。就乾脆弄一組完全亂數密碼,換完就丟了。等閉關完,再從忘記密碼功能找回來。不過算了。

    + +

    開始有戒斷症狀,很多感想想噗。呃啊。習慣了社交網路的生活,總覺生活步調十分扭曲。

    + +

    不過每天都一直在回頭看臉書噗浪,看看有沒有什麼新鮮事。這已經很讓人分心很花時間了。看到有趣的事追下去,更分心更花時間。

    + +

    前兩天反省了噗浪和臉書的不同,反省了很多。大體上,臉書是真實人生的連結,噗浪不是。具體是怎麼樣,有空再來寫。也可以作為很有趣的研究題目。

    + +
    + +
    + +
    +
    6.16.’13. 1:24am.
    + +

    四十歲的尖尖的角角和火苗

    + +

    兩個禮拜前在某園一句「暫時關閉通知。抱歉。」,沒想到一發不可收拾。火延燒得這麼旺,甚至造成社團分裂,很多人出走。

    + +

    我只是不小心點了火而已,很多人一定不滿忍耐很久了。雖然事情發展非我本意,樂見後續發展。

    + +

    本來以為自己年歲漸長,越來越鄉愿沒用,火氣和棱角都被磨平了。沒想到都四十歲了,還能點起這麼大的火,看來我的角角還尖尖刺刺的,還能戰鬥。呵呵。 ^_*'

    + +
    + +
    + +
    +
    5.16.’13. 5:01pm.
    + +

    似是而非的國際觀

    + +

    打臉

    + +

    我很不能接受這篇文章胡說八道似是而非的論點。這些論點彰顯了作者的國際觀很有問題。

    + +

    問題一:不只菲律賓有美國海軍基地,台灣也有台灣關係法,兩邊都是美國盟邦。越戰美國犧牲四萬軍人後,美國對於用美國人人命幫別的國家主持正義,一直有所忌諱。現任總統歐巴馬主張軟性外交,美國盟邦敘利亞內戰兩年了都沒有出手。更何況菲律賓有錯在先,正義也不在菲律賓那邊。若真的發生小規模區域性衝突,只要不波及基地,美國怎麼會選邊站?

    + +

    補充一點:台灣是西太平洋島鏈的樞鈕,這是小學就教過的事。美國如果在區域衝突中幫菲律賓,中國正好有藉口出兵「協(ㄓㄢˋ)助(ㄌㄧㄥˇ)」台灣,突破西太平洋島鏈,美國整個西太平洋戰略佈局就大亂了。美國會為個菲律賓,自己砸自己的腳嗎?

    + +

    對國際情勢沒有全盤瞭解,單方面從有利菲律賓的角度來看,這樣也要鼓吹國際觀,未免可笑。

    + +

    問題二:台灣漁船沒有入侵菲律賓海域。作者對領海專屬經濟海域執法線海域這幾個詞一直搞不清楚。領海只有海岸外十二海哩,專屬經濟海域則是海岸外兩百海哩。台灣和菲律賓的領海都很小,重疊的是專屬經濟海域。台灣漁船是在重疊的專屬經濟海域上。作者最後用一個含糊不明的台灣漁船侵入菲律賓海域菲律賓海域是什麼東西?以為這樣含糊其詞就可以矇混過去,坳成是台灣人錯了嗎?

    + +

    問題三:菲律賓一直是一個人命不值錢的國家,可能沒有錯。不過菲律賓人命值不值錢,和台灣毫無關係。台灣人的人命值錢,菲律賓人命不值錢是他們的內政問題。逮補幫派份子的時候,去問他:喂!在你們幫派眼中人命值不值錢?這問題太荒謬了。

    + +

    問題四:全世界的漁民都會越界。前兩天台灣才兩艘漁船越界進入日本、越南專屬經濟海域,以前中國漁民天天越界,被台灣海巡整批遣返。台灣漁民可不可憐,也和被槍殺毫無關係。

    + +

    問題五:台灣人的確血汗剝削菲勞。和香港、新加坡比待遇有沒有比較好,我不知道。今天才看到內政部長說在台菲勞待遇比香港好,台灣佔菲律賓外匯多少比例。不過不管待遇如何,這都還不是經濟制裁(又一個含糊其詞),也和事件毫無關係。

    + +

    結語:國際情勢瞭解片面而錯誤的人,鼓吹國際觀,未面可笑。

    + +

    據自己有限的視界,抨擊別人的國際情勢看法就是沒有國際觀。我不清楚為什麼他的國際觀就是國際觀,別人的國際觀就是沒有國際觀。國際觀只是用來扣別人的大帽子嗎?

    + +

    感覺上他只是個人心態保守,然後拿國際觀的大帽子扣在採取行動、採取立場的人身上。心態保守無妨。可是採取行動、採取立場就是沒有國際觀,心態保守就是有國際觀?怎麼看都說不過去。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 181 | + 182 | + 183 | + 184 | + 185 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0183.html.zh-cn.html b/htdocs/imacat/me/diary/0183.html.zh-cn.html new file mode 120000 index 0000000..1c392e6 --- /dev/null +++ b/htdocs/imacat/me/diary/0183.html.zh-cn.html @@ -0,0 +1 @@ +0183.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0183.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0183.html.zh-cn.xhtml new file mode 100644 index 0000000..85482ca --- /dev/null +++ b/htdocs/imacat/me/diary/0183.html.zh-cn.xhtml @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百八十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百八十三

    + +
    + +
    + +
    +
    6.26.’13. 1:51pm.
    + +

    多余的话

    + +

    总觉得自己在后巷讲了多余的话。算了。

    + +
    + +
    + +
    +
    6.26.’13. 1:48pm.
    + +

    日记的时间

    + +

    旅舍日记的时间好像怪怪的。算了口试完再修理好了。

    + +
    + +
    + +
    +
    6.26.’13. 1:46pm.
    + +

    日记

    + +

    重新用旅舍日记代替噗浪和部落格,宣泄自己想讲的话。发现这样也不错,不是社群网路,不用在意别人有没有回应。这是前 Web 2.0 时代的网路日记,单向的宣泄而已,感觉也没什么不好。

    + +

    而且日后还不用担心被人家人肉搜索。嗯,好啦,是比较不用担心。

    + +

    说起来为什么非要用社群网路不可呢?

    + +
    + +
    + +
    +
    6.26.’13. 1:43pm.
    + +

    进度

    + +

    荒废了四天,开始看老师改的东西。本来礼拜天就开始看了,礼拜一美文提醒了我研究方法老师改很多,心理压力又来了,就又搁著。做好研究方法被完全打掉的最坏心理准备后,才回头看。不敢仔细看,先快速翻过,再回头细看,好像也没有那么糟。嗯啊。

    + +

    果然还是不行,我的心理强度还是不够。平常只是个冲动的笨蛋而已。要保持平常心才写得下去。平常心啊!

    + +

    好啦这四天我都在看漫画。看完了 Sket Dance 学园救援团,看完了周刊少女野崎君。

    + +
    + +
    + +
    +
    6.26.’13. 1:35pm.
    + +

    关闭社交网路

    + +

    昨天在噗浪和脸书上宣布闭关锁帐号。锁帐号具体来说,产生新一组的乱数密码,新密码另外存档后,把密码换成新密码。这样我就换了我不记得的密码,每次要用同样的乱数种子去产生,或是开档去找,很麻烦。但是临时要上噗浪脸书,也是可以。

    + +

    其实新密码也可以不用另外存档。就干脆弄一组完全乱数密码,换完就丢了。等闭关完,再从忘记密码功能找回来。不过算了。

    + +

    开始有戒断症状,很多感想想噗。呃啊。习惯了社交网路的生活,总觉生活步调十分扭曲。

    + +

    不过每天都一直在回头看脸书噗浪,看看有没有什么新鲜事。这已经很让人分心很花时间了。看到有趣的事追下去,更分心更花时间。

    + +

    前两天反省了噗浪和脸书的不同,反省了很多。大体上,脸书是真实人生的连结,噗浪不是。具体是怎么样,有空再来写。也可以作为很有趣的研究题目。

    + +
    + +
    + +
    +
    6.16.’13. 1:24am.
    + +

    四十岁的尖尖的角角和火苗

    + +

    两个礼拜前在某园一句「暂时关闭通知。抱歉。」,没想到一发不可收拾。火延烧得这么旺,甚至造成社团分裂,很多人出走。

    + +

    我只是不小心点了火而已,很多人一定不满忍耐很久了。虽然事情发展非我本意,乐见后续发展。

    + +

    本来以为自己年岁渐长,越来越乡愿没用,火气和棱角都被磨平了。没想到都四十岁了,还能点起这么大的火,看来我的角角还尖尖刺刺的,还能战斗。呵呵。 ^_*'

    + +
    + +
    + +
    +
    5.16.’13. 5:01pm.
    + +

    似是而非的国际观

    + +

    打脸

    + +

    我很不能接受这篇文章胡说八道似是而非的论点。这些论点彰显了作者的国际观很有问题。

    + +

    问题一:不只菲律宾有美国海军基地,台湾也有台湾关系法,两边都是美国盟邦。越战美国牺牲四万军人后,美国对於用美国人人命帮别的国家主持正义,一直有所忌讳。现任总统欧巴马主张软性外交,美国盟邦叙利亚内战两年了都没有出手。更何况菲律宾有错在先,正义也不在菲律宾那边。若真的发生小规模区域性冲突,只要不波及基地,美国怎么会选边站?

    + +

    补充一点:台湾是西太平洋岛链的枢钮,这是小学就教过的事。美国如果在区域冲突中帮菲律宾,中国正好有藉口出兵「协(ㄓㄢˋ)助(ㄌㄧㄥˇ)」台湾,突破西太平洋岛链,美国整个西太平洋战略布局就大乱了。美国会为个菲律宾,自己砸自己的脚吗?

    + +

    对国际情势没有全盘了解,单方面从有利菲律宾的角度来看,这样也要鼓吹国际观,未免可笑。

    + +

    问题二:台湾渔船没有入侵菲律宾海域。作者对领海专属经济海域执法线海域这几个词一直搞不清楚。领海只有海岸外十二海哩,专属经济海域则是海岸外两百海哩。台湾和菲律宾的领海都很小,重叠的是专属经济海域。台湾渔船是在重叠的专属经济海域上。作者最后用一个含糊不明的台湾渔船侵入菲律宾海域菲律宾海域是什么东西?以为这样含糊其词就可以蒙混过去,坳成是台湾人错了吗?

    + +

    问题三:菲律宾一直是一个人命不值钱的国家,可能没有错。不过菲律宾人命值不值钱,和台湾毫无关系。台湾人的人命值钱,菲律宾人命不值钱是他们的内政问题。逮补帮派份子的时候,去问他:喂!在你们帮派眼中人命值不值钱?这问题太荒谬了。

    + +

    问题四:全世界的渔民都会越界。前两天台湾才两艘渔船越界进入日本、越南专属经济海域,以前中国渔民天天越界,被台湾海巡整批遣返。台湾渔民可不可怜,也和被枪杀毫无关系。

    + +

    问题五:台湾人的确血汗剥削菲劳。和香港、新加坡比待遇有没有比较好,我不知道。今天才看到内政部长说在台菲劳待遇比香港好,台湾占菲律宾外汇多少比例。不过不管待遇如何,这都还不是经济制裁(又一个含糊其词),也和事件毫无关系。

    + +

    结语:国际情势了解片面而错误的人,鼓吹国际观,未面可笑。

    + +

    据自己有限的视界,抨击别人的国际情势看法就是没有国际观。我不清楚为什么他的国际观就是国际观,别人的国际观就是没有国际观。国际观只是用来扣别人的大帽子吗?

    + +

    感觉上他只是个人心态保守,然后拿国际观的大帽子扣在采取行动、采取立场的人身上。心态保守无妨。可是采取行动、采取立场就是没有国际观,心态保守就是有国际观?怎么看都说不过去。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 181 | + 182 | + 183 | + 184 | + 185 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0183.html.zh-tw.html b/htdocs/imacat/me/diary/0183.html.zh-tw.html new file mode 120000 index 0000000..f88b9ee --- /dev/null +++ b/htdocs/imacat/me/diary/0183.html.zh-tw.html @@ -0,0 +1 @@ +0183.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0183.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0183.html.zh-tw.xhtml new file mode 100644 index 0000000..99d9b42 --- /dev/null +++ b/htdocs/imacat/me/diary/0183.html.zh-tw.xhtml @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百八十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百八十三

    + +
    + +
    + +
    +
    6.26.’13. 1:51pm.
    + +

    多餘的話

    + +

    總覺得自己在後巷講了多餘的話。算了。

    + +
    + +
    + +
    +
    6.26.’13. 1:48pm.
    + +

    日記的時間

    + +

    旅舍日記的時間好像怪怪的。算了口試完再修理好了。

    + +
    + +
    + +
    +
    6.26.’13. 1:46pm.
    + +

    日記

    + +

    重新用旅舍日記代替噗浪和部落格,宣洩自己想講的話。發現這樣也不錯,不是社群網路,不用在意別人有沒有回應。這是前 Web 2.0 時代的網路日記,單向的宣洩而已,感覺也沒什麼不好。

    + +

    而且日後還不用擔心被人家人肉搜索。嗯,好啦,是比較不用擔心。

    + +

    說起來為什麼非要用社群網路不可呢?

    + +
    + +
    + +
    +
    6.26.’13. 1:43pm.
    + +

    進度

    + +

    荒廢了四天,開始看老師改的東西。本來禮拜天就開始看了,禮拜一美文提醒了我研究方法老師改很多,心理壓力又來了,就又擱著。做好研究方法被完全打掉的最壞心理準備後,才回頭看。不敢仔細看,先快速翻過,再回頭細看,好像也沒有那麼糟。嗯啊。

    + +

    果然還是不行,我的心理強度還是不夠。平常只是個衝動的笨蛋而已。要保持平常心才寫得下去。平常心啊!

    + +

    好啦這四天我都在看漫畫。看完了 Sket Dance 學園救援團,看完了週刊少女野崎君。

    + +
    + +
    + +
    +
    6.26.’13. 1:35pm.
    + +

    關閉社交網路

    + +

    昨天在噗浪和臉書上宣佈閉關鎖帳號。鎖帳號具體來說,產生新一組的亂數密碼,新密碼另外存檔後,把密碼換成新密碼。這樣我就換了我不記得的密碼,每次要用同樣的亂數種子去產生,或是開檔去找,很麻煩。但是臨時要上噗浪臉書,也是可以。

    + +

    其實新密碼也可以不用另外存檔。就乾脆弄一組完全亂數密碼,換完就丟了。等閉關完,再從忘記密碼功能找回來。不過算了。

    + +

    開始有戒斷症狀,很多感想想噗。呃啊。習慣了社交網路的生活,總覺生活步調十分扭曲。

    + +

    不過每天都一直在回頭看臉書噗浪,看看有沒有什麼新鮮事。這已經很讓人分心很花時間了。看到有趣的事追下去,更分心更花時間。

    + +

    前兩天反省了噗浪和臉書的不同,反省了很多。大體上,臉書是真實人生的連結,噗浪不是。具體是怎麼樣,有空再來寫。也可以作為很有趣的研究題目。

    + +
    + +
    + +
    +
    6.16.’13. 1:24am.
    + +

    四十歲的尖尖的角角和火苗

    + +

    兩個禮拜前在某園一句「暫時關閉通知。抱歉。」,沒想到一發不可收拾。火延燒得這麼旺,甚至造成社團分裂,很多人出走。

    + +

    我只是不小心點了火而已,很多人一定不滿忍耐很久了。雖然事情發展非我本意,樂見後續發展。

    + +

    本來以為自己年歲漸長,越來越鄉愿沒用,火氣和棱角都被磨平了。沒想到都四十歲了,還能點起這麼大的火,看來我的角角還尖尖刺刺的,還能戰鬥。呵呵。 ^_*'

    + +
    + +
    + +
    +
    5.16.’13. 5:01pm.
    + +

    似是而非的國際觀

    + +

    打臉

    + +

    我很不能接受這篇文章胡說八道似是而非的論點。這些論點彰顯了作者的國際觀很有問題。

    + +

    問題一:不只菲律賓有美國海軍基地,台灣也有台灣關係法,兩邊都是美國盟邦。越戰美國犧牲四萬軍人後,美國對於用美國人人命幫別的國家主持正義,一直有所忌諱。現任總統歐巴馬主張軟性外交,美國盟邦敘利亞內戰兩年了都沒有出手。更何況菲律賓有錯在先,正義也不在菲律賓那邊。若真的發生小規模區域性衝突,只要不波及基地,美國怎麼會選邊站?

    + +

    補充一點:台灣是西太平洋島鏈的樞鈕,這是小學就教過的事。美國如果在區域衝突中幫菲律賓,中國正好有藉口出兵「協(ㄓㄢˋ)助(ㄌㄧㄥˇ)」台灣,突破西太平洋島鏈,美國整個西太平洋戰略佈局就大亂了。美國會為個菲律賓,自己砸自己的腳嗎?

    + +

    對國際情勢沒有全盤瞭解,單方面從有利菲律賓的角度來看,這樣也要鼓吹國際觀,未免可笑。

    + +

    問題二:台灣漁船沒有入侵菲律賓海域。作者對領海專屬經濟海域執法線海域這幾個詞一直搞不清楚。領海只有海岸外十二海哩,專屬經濟海域則是海岸外兩百海哩。台灣和菲律賓的領海都很小,重疊的是專屬經濟海域。台灣漁船是在重疊的專屬經濟海域上。作者最後用一個含糊不明的台灣漁船侵入菲律賓海域菲律賓海域是什麼東西?以為這樣含糊其詞就可以矇混過去,坳成是台灣人錯了嗎?

    + +

    問題三:菲律賓一直是一個人命不值錢的國家,可能沒有錯。不過菲律賓人命值不值錢,和台灣毫無關係。台灣人的人命值錢,菲律賓人命不值錢是他們的內政問題。逮補幫派份子的時候,去問他:喂!在你們幫派眼中人命值不值錢?這問題太荒謬了。

    + +

    問題四:全世界的漁民都會越界。前兩天台灣才兩艘漁船越界進入日本、越南專屬經濟海域,以前中國漁民天天越界,被台灣海巡整批遣返。台灣漁民可不可憐,也和被槍殺毫無關係。

    + +

    問題五:台灣人的確血汗剝削菲勞。和香港、新加坡比待遇有沒有比較好,我不知道。今天才看到內政部長說在台菲勞待遇比香港好,台灣佔菲律賓外匯多少比例。不過不管待遇如何,這都還不是經濟制裁(又一個含糊其詞),也和事件毫無關係。

    + +

    結語:國際情勢瞭解片面而錯誤的人,鼓吹國際觀,未面可笑。

    + +

    據自己有限的視界,抨擊別人的國際情勢看法就是沒有國際觀。我不清楚為什麼他的國際觀就是國際觀,別人的國際觀就是沒有國際觀。國際觀只是用來扣別人的大帽子嗎?

    + +

    感覺上他只是個人心態保守,然後拿國際觀的大帽子扣在採取行動、採取立場的人身上。心態保守無妨。可是採取行動、採取立場就是沒有國際觀,心態保守就是有國際觀?怎麼看都說不過去。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 181 | + 182 | + 183 | + 184 | + 185 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0184.html.en.html b/htdocs/imacat/me/diary/0184.html.en.html new file mode 120000 index 0000000..6eb3154 --- /dev/null +++ b/htdocs/imacat/me/diary/0184.html.en.html @@ -0,0 +1 @@ +0184.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0184.html.en.xhtml b/htdocs/imacat/me/diary/0184.html.en.xhtml new file mode 100644 index 0000000..1850de7 --- /dev/null +++ b/htdocs/imacat/me/diary/0184.html.en.xhtml @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 184 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 184

    + +
    + +
    + +
    +
    6.28.’13. 3:00pm.
    + +

    學校的電腦蕾比

    + +

    學校實驗室的電腦,我取名叫蕾比 Levy 。蕾比是妖精尾巴公會中很會讀書的成員,取這個名字,希望能夠對學業有點幫助。

    + +

    蕾比上本來裝三個作業系統: Debian 、 Windows 7 、 EzGo ,硬碟不大。上個月把 Windows 7 換成 Windows 8 , 40GB 裝完 Windows 8 、 MS Office 2013 和 OpenOffice 後就滿了,只剩 1.7GB 。上個禮拜想開到 Windows 8 更新,進去後一直當。後來就算了。然後 EzGo 遠端從 Debian chroot 更新幾次後,也開不了機了。現在蕾比上只剩 Debian 可以開機。

    + +

    想想應該把 Windows 8 或 EzGo 兩個磁碟分割合併成一個,就有足夠的硬碟空間可以育了。可是實在不知道該捨棄 Windows 8 還是 EzGo 。 Windows 8 是學校配的正版,而且和新買的印表機列印時, Windows 8 比較沒問題; EzGo 是教育用自由軟體,也不想捨棄。當然更不可能捨棄日常用的 Debian 。

    + +

    而且最重要的是,就算可以捨棄,我也沒時間重灌。可是不重灌,印表機、 MS Office 等很多東西都不能用。煩哪。

    + +
    + +
    + +
    +
    6.28.’13. 2:30am.
    + +

    線上租漫畫

    + +

    公館的錦城漫畫出租店,什麼書都會進,所以可以找得到冷門的漫畫。可是老闆退書也退得很快,進書一個禮拜沒人看就退掉了,想看的漫畫都要搶租。

    + +

    好幾本百合漫,事後注意到,想回去找時,都被退書了。別家出租店,則根本沒有進書。百合和 BL 還是小眾,唉。

    + +

    晚上抱著一絲希望去仁愛路上的河馬租書店,果然還是沒有。不過看到柱子上寫線上預約租書,突然又冒出一線希望。連鎖漫畫出租店的話,只要全國有一本,應該就可以調得到。

    + +

    回來上網找,國內線上預約租書,好像只有花蝶online,柱子上應該是那家店之前是花蝶館時的宣傳。馬上申請會員,也有找到想看的百合漫。超開心!不過是因為不是實體會員嗎?沒有辦法預約。唉。還是實際去跑一趟花蝶館吧。

    + +
    + +
    + +
    +
    6.28.’13. 2:17am.
    + +

    執業魔女★Pico Pico

    + +

    想買好久的執業魔女★Pico Pico,在新瑞八德店看到兩本,一本是執業魔女★Pico Pico,一本是執業魔女★Pico Pico 1。搞不懂有什麼不同,店員說前面那本是短篇集,想想就買前面那本了。回來看看覺得還好,感覺上像是圖畫故事書,雖然我也喜歡畫得好的圖畫書,但沒有喜歡到想買下來的地步。等回家整理時看,發現其實書名是魔女手扎★Pico Pico。呃啊,買錯了。店員竟然也沒有發現書名不一樣。

    + +
    + +
    + +
    +
    6.28.’13. 2:13am.
    + +

    Temple Run: 勇敢傳說

    + +

    耶!終於拿到Temple Run: 勇敢傳說的神射手 100 個目標了!超難!

    + +

    之前偶然間發現安全高效率的減速法,可是那次在 98 個目標時飲恨。後來就一直很難接近那次的記錄。後來玩的過程中,雖然安全減速法越來越熟練,但是也覺得自己是不是熟悉慢速了,反而功力變差。這次一開始還覺得目標數:跑的距離比太低了,不抱希望,沒想到這樣熬著跑下去,竟然也跑到最後,跑了 44,832 公里,擊中 122 個目標,用掉 34 個復活翅膀,拿到 73,573 枚金幣,三千三百多萬分,乘倍後 50,696,772 分。嗯啊,看來果然還是運氣最重要。這次完全沒有碰到必死的連續陷阱。

    + +
    + +
    + +
    +
    6.27.’13. 11:32am.
    + +

    月刊少女野崎君

    + +

    其實我很不喜歡日本式的四格漫畫,就是看不習慣。不過月刊少女野崎君是少數的例外。

    + +

    為什麼台灣還沒有出版社進月刊少女野崎君啊啊啊啊啊啊啊!

    + +

    6/28: 發現竟然不小心寫成週刊少女野崎君,然後因為旅舍日記不是社群網路,所以沒有人發現跟我說。哈哈哈,尷尬。

    + +
    + +
    + +
    +
    6.27.’13. 2:37am.
    + +

    不大好改

    + +

    老師改回來的論文,有些雖然有道理,但是不大好改。煩。

    + +
    + +
    + +
    +
    6.26.’13. 2:33pm.
    + +

    + +

    寄了兩封信。一封是三個月前該寄的信,每次都忘了;一封是有點麻煩的事態變化。兩封信都很重要,不過都有點尷尬。嗯。

    + +
    + +
    + +
    +
    6.26.’13. 1:55pm.
    + +

    Sket Dance 學園救援團

    + +

    Sket Dance 學園救援團畫到後來就沒那麼好看了。我不喜歡把愛情元素拉進來,感覺很老套。姬子和 Bossun 之間還是早期那樣,沒有曖昧比較有趣。要談戀愛拜託也請跟學園救援團以外的角色談吧,像 Switch 那樣。

    + +

    我很不喜歡異性戀標準劇情範本:一男一女的主角,就一定要湊在一起。煩耶!

    + +

    還有拜託來個百合或 BL 吧!

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 182 | + 183 | + 184 | + 185 | + 186 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0184.html.zh-cn.html b/htdocs/imacat/me/diary/0184.html.zh-cn.html new file mode 120000 index 0000000..e73ad67 --- /dev/null +++ b/htdocs/imacat/me/diary/0184.html.zh-cn.html @@ -0,0 +1 @@ +0184.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0184.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0184.html.zh-cn.xhtml new file mode 100644 index 0000000..c88c696 --- /dev/null +++ b/htdocs/imacat/me/diary/0184.html.zh-cn.xhtml @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百八十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百八十四

    + +
    + +
    + +
    +
    6.28.’13. 3:00pm.
    + +

    学校的电脑蕾比

    + +

    学校实验室的电脑,我取名叫蕾比 Levy 。蕾比是妖精尾巴公会中很会读书的成员,取这个名字,希望能够对学业有点帮助。

    + +

    蕾比上本来装三个作业系统: Debian 、 Windows 7 、 EzGo ,硬碟不大。上个月把 Windows 7 换成 Windows 8 , 40GB 装完 Windows 8 、 MS Office 2013 和 OpenOffice 后就满了,只剩 1.7GB 。上个礼拜想开到 Windows 8 更新,进去后一直当。后来就算了。然后 EzGo 远端从 Debian chroot 更新几次后,也开不了机了。现在蕾比上只剩 Debian 可以开机。

    + +

    想想应该把 Windows 8 或 EzGo 两个磁碟分割合并成一个,就有足够的硬碟空间可以育了。可是实在不知道该舍弃 Windows 8 还是 EzGo 。 Windows 8 是学校配的正版,而且和新买的印表机列印时, Windows 8 比较没问题; EzGo 是教育用自由软体,也不想舍弃。当然更不可能舍弃日常用的 Debian 。

    + +

    而且最重要的是,就算可以舍弃,我也没时间重灌。可是不重灌,印表机、 MS Office 等很多东西都不能用。烦哪。

    + +
    + +
    + +
    +
    6.28.’13. 2:30am.
    + +

    线上租漫画

    + +

    公馆的锦城漫画出租店,什么书都会进,所以可以找得到冷门的漫画。可是老板退书也退得很快,进书一个礼拜没人看就退掉了,想看的漫画都要抢租。

    + +

    好几本百合漫,事后注意到,想回去找时,都被退书了。别家出租店,则根本没有进书。百合和 BL 还是小众,唉。

    + +

    晚上抱著一丝希望去仁爱路上的河马租书店,果然还是没有。不过看到柱子上写线上预约租书,突然又冒出一线希望。连锁漫画出租店的话,只要全国有一本,应该就可以调得到。

    + +

    回来上网找,国内线上预约租书,好像只有花蝶online,柱子上应该是那家店之前是花蝶馆时的宣传。马上申请会员,也有找到想看的百合漫。超开心!不过是因为不是实体会员吗?没有办法预约。唉。还是实际去跑一趟花蝶馆吧。

    + +
    + +
    + +
    +
    6.28.’13. 2:17am.
    + +

    执业魔女★Pico Pico

    + +

    想买好久的执业魔女★Pico Pico,在新瑞八德店看到两本,一本是执业魔女★Pico Pico,一本是执业魔女★Pico Pico 1。搞不懂有什么不同,店员说前面那本是短篇集,想想就买前面那本了。回来看看觉得还好,感觉上像是图画故事书,虽然我也喜欢画得好的图画书,但没有喜欢到想买下来的地步。等回家整理时看,发现其实书名是魔女手扎★Pico Pico。呃啊,买错了。店员竟然也没有发现书名不一样。

    + +
    + +
    + +
    +
    6.28.’13. 2:13am.
    + +

    Temple Run: 勇敢传说

    + +

    耶!终於拿到Temple Run: 勇敢传说的神射手 100 个目标了!超难!

    + +

    之前偶然间发现安全高效率的减速法,可是那次在 98 个目标时饮恨。后来就一直很难接近那次的记录。后来玩的过程中,虽然安全减速法越来越熟练,但是也觉得自己是不是熟悉慢速了,反而功力变差。这次一开始还觉得目标数:跑的距离比太低了,不抱希望,没想到这样熬著跑下去,竟然也跑到最后,跑了 44,832 公里,击中 122 个目标,用掉 34 个复活翅膀,拿到 73,573 枚金币,三千三百多万分,乘倍后 50,696,772 分。嗯啊,看来果然还是运气最重要。这次完全没有碰到必死的连续陷阱。

    + +
    + +
    + +
    +
    6.27.’13. 11:32am.
    + +

    月刊少女野崎君

    + +

    其实我很不喜欢日本式的四格漫画,就是看不习惯。不过月刊少女野崎君是少数的例外。

    + +

    为什么台湾还没有出版社进月刊少女野崎君啊啊啊啊啊啊啊!

    + +

    6/28: 发现竟然不小心写成周刊少女野崎君,然后因为旅舍日记不是社群网路,所以没有人发现跟我说。哈哈哈,尴尬。

    + +
    + +
    + +
    +
    6.27.’13. 2:37am.
    + +

    不大好改

    + +

    老师改回来的论文,有些虽然有道理,但是不大好改。烦。

    + +
    + +
    + +
    +
    6.26.’13. 2:33pm.
    + +

    + +

    寄了两封信。一封是三个月前该寄的信,每次都忘了;一封是有点麻烦的事态变化。两封信都很重要,不过都有点尴尬。嗯。

    + +
    + +
    + +
    +
    6.26.’13. 1:55pm.
    + +

    Sket Dance 学园救援团

    + +

    Sket Dance 学园救援团画到后来就没那么好看了。我不喜欢把爱情元素拉进来,感觉很老套。姬子和 Bossun 之间还是早期那样,没有暧昧比较有趣。要谈恋爱拜托也请跟学园救援团以外的角色谈吧,像 Switch 那样。

    + +

    我很不喜欢异性恋标准剧情范本:一男一女的主角,就一定要凑在一起。烦耶!

    + +

    还有拜托来个百合或 BL 吧!

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 182 | + 183 | + 184 | + 185 | + 186 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0184.html.zh-tw.html b/htdocs/imacat/me/diary/0184.html.zh-tw.html new file mode 120000 index 0000000..dc4a377 --- /dev/null +++ b/htdocs/imacat/me/diary/0184.html.zh-tw.html @@ -0,0 +1 @@ +0184.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0184.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0184.html.zh-tw.xhtml new file mode 100644 index 0000000..ea8dd59 --- /dev/null +++ b/htdocs/imacat/me/diary/0184.html.zh-tw.xhtml @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百八十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百八十四

    + +
    + +
    + +
    +
    6.28.’13. 3:00pm.
    + +

    學校的電腦蕾比

    + +

    學校實驗室的電腦,我取名叫蕾比 Levy 。蕾比是妖精尾巴公會中很會讀書的成員,取這個名字,希望能夠對學業有點幫助。

    + +

    蕾比上本來裝三個作業系統: Debian 、 Windows 7 、 EzGo ,硬碟不大。上個月把 Windows 7 換成 Windows 8 , 40GB 裝完 Windows 8 、 MS Office 2013 和 OpenOffice 後就滿了,只剩 1.7GB 。上個禮拜想開到 Windows 8 更新,進去後一直當。後來就算了。然後 EzGo 遠端從 Debian chroot 更新幾次後,也開不了機了。現在蕾比上只剩 Debian 可以開機。

    + +

    想想應該把 Windows 8 或 EzGo 兩個磁碟分割合併成一個,就有足夠的硬碟空間可以育了。可是實在不知道該捨棄 Windows 8 還是 EzGo 。 Windows 8 是學校配的正版,而且和新買的印表機列印時, Windows 8 比較沒問題; EzGo 是教育用自由軟體,也不想捨棄。當然更不可能捨棄日常用的 Debian 。

    + +

    而且最重要的是,就算可以捨棄,我也沒時間重灌。可是不重灌,印表機、 MS Office 等很多東西都不能用。煩哪。

    + +
    + +
    + +
    +
    6.28.’13. 2:30am.
    + +

    線上租漫畫

    + +

    公館的錦城漫畫出租店,什麼書都會進,所以可以找得到冷門的漫畫。可是老闆退書也退得很快,進書一個禮拜沒人看就退掉了,想看的漫畫都要搶租。

    + +

    好幾本百合漫,事後注意到,想回去找時,都被退書了。別家出租店,則根本沒有進書。百合和 BL 還是小眾,唉。

    + +

    晚上抱著一絲希望去仁愛路上的河馬租書店,果然還是沒有。不過看到柱子上寫線上預約租書,突然又冒出一線希望。連鎖漫畫出租店的話,只要全國有一本,應該就可以調得到。

    + +

    回來上網找,國內線上預約租書,好像只有花蝶online,柱子上應該是那家店之前是花蝶館時的宣傳。馬上申請會員,也有找到想看的百合漫。超開心!不過是因為不是實體會員嗎?沒有辦法預約。唉。還是實際去跑一趟花蝶館吧。

    + +
    + +
    + +
    +
    6.28.’13. 2:17am.
    + +

    執業魔女★Pico Pico

    + +

    想買好久的執業魔女★Pico Pico,在新瑞八德店看到兩本,一本是執業魔女★Pico Pico,一本是執業魔女★Pico Pico 1。搞不懂有什麼不同,店員說前面那本是短篇集,想想就買前面那本了。回來看看覺得還好,感覺上像是圖畫故事書,雖然我也喜歡畫得好的圖畫書,但沒有喜歡到想買下來的地步。等回家整理時看,發現其實書名是魔女手扎★Pico Pico。呃啊,買錯了。店員竟然也沒有發現書名不一樣。

    + +
    + +
    + +
    +
    6.28.’13. 2:13am.
    + +

    Temple Run: 勇敢傳說

    + +

    耶!終於拿到Temple Run: 勇敢傳說的神射手 100 個目標了!超難!

    + +

    之前偶然間發現安全高效率的減速法,可是那次在 98 個目標時飲恨。後來就一直很難接近那次的記錄。後來玩的過程中,雖然安全減速法越來越熟練,但是也覺得自己是不是熟悉慢速了,反而功力變差。這次一開始還覺得目標數:跑的距離比太低了,不抱希望,沒想到這樣熬著跑下去,竟然也跑到最後,跑了 44,832 公里,擊中 122 個目標,用掉 34 個復活翅膀,拿到 73,573 枚金幣,三千三百多萬分,乘倍後 50,696,772 分。嗯啊,看來果然還是運氣最重要。這次完全沒有碰到必死的連續陷阱。

    + +
    + +
    + +
    +
    6.27.’13. 11:32am.
    + +

    月刊少女野崎君

    + +

    其實我很不喜歡日本式的四格漫畫,就是看不習慣。不過月刊少女野崎君是少數的例外。

    + +

    為什麼台灣還沒有出版社進月刊少女野崎君啊啊啊啊啊啊啊!

    + +

    6/28: 發現竟然不小心寫成週刊少女野崎君,然後因為旅舍日記不是社群網路,所以沒有人發現跟我說。哈哈哈,尷尬。

    + +
    + +
    + +
    +
    6.27.’13. 2:37am.
    + +

    不大好改

    + +

    老師改回來的論文,有些雖然有道理,但是不大好改。煩。

    + +
    + +
    + +
    +
    6.26.’13. 2:33pm.
    + +

    + +

    寄了兩封信。一封是三個月前該寄的信,每次都忘了;一封是有點麻煩的事態變化。兩封信都很重要,不過都有點尷尬。嗯。

    + +
    + +
    + +
    +
    6.26.’13. 1:55pm.
    + +

    Sket Dance 學園救援團

    + +

    Sket Dance 學園救援團畫到後來就沒那麼好看了。我不喜歡把愛情元素拉進來,感覺很老套。姬子和 Bossun 之間還是早期那樣,沒有曖昧比較有趣。要談戀愛拜託也請跟學園救援團以外的角色談吧,像 Switch 那樣。

    + +

    我很不喜歡異性戀標準劇情範本:一男一女的主角,就一定要湊在一起。煩耶!

    + +

    還有拜託來個百合或 BL 吧!

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 182 | + 183 | + 184 | + 185 | + 186 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0185.html.en.html b/htdocs/imacat/me/diary/0185.html.en.html new file mode 120000 index 0000000..d5393e8 --- /dev/null +++ b/htdocs/imacat/me/diary/0185.html.en.html @@ -0,0 +1 @@ +0185.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0185.html.en.xhtml b/htdocs/imacat/me/diary/0185.html.en.xhtml new file mode 100644 index 0000000..010388a --- /dev/null +++ b/htdocs/imacat/me/diary/0185.html.en.xhtml @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 185 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 185

    + +
    + +
    + +
    +
    7.7.’13. 2:46pm.
    + +

    繞頸露背洋裝

    + +

    總覺得我對流行的感覺比別人慢一兩年。內搭褲流行隔年,我才開始喜歡上內搭褲;踩腳褲流行幾年以後,我才迷上踩腳褲; T 字涼鞋流行了兩年,我才開始瘋狂迷上 T 字涼鞋。

    + +

    繞頸露背洋裝也是。去年年底才開始覺得我應該能穿繞頸露背洋裝,夏天整個後背鏤空,不知道會有多清爽。那時候看到一件經典夢露繞頸綁繩背心洋裝,超想買。可是熬到今年夏天,前幾天南港高中講完課想買,就停產了。找遍了網路想找類似款,就是找不到,不是前胸太貼我沒辦法穿,就是後背不是露到我想要的腰,不然就不是短洋裝,或是太短太窄會曝光不好走,或是我已經有的平口款,或是太小我不能穿,或是材質沒有彈性我可能穿不下。連樂華夜市和師大夜市也走遍了,勉強找到幾件都不是很滿意。店員都說今年繞頸款式很少,看來我的流行感又晚別人好幾年了。

    + +

    最後只好買這件,後背有點露太低了,不過我剛好可以穿,而且很好看。不知道買回來後敢不敢穿,不過算了。

    + +

    賣家好神奇,我 10:56 結標, 10:39 就通知我貨寄出去了,才 45 分鐘就寄出去了。不會是假的吧?還是正好每週結算寄貨前夕呢?

    + +

    期待中!

    + +

    買到以後,就沒有那麼大想買露頸露背洋裝的心理壓力了。昨晚隨便逛逛樂華夜市,想找件式樣特別一點的露背、露肩洋裝,找到都太短了會走光。唉。結果到最後還是什麼都沒買。

    + +

    發現我真的肥了,好可怕。最近晚上寫不出來就一直吃點心,也沒有運動。要節食了。

    + +
    + +
    + +
    +
    7.7.’13. 2:27pm.
    + +

    Karel

    + +

    忘了 Karel 的 1991 年,是 DOS 的時代。原版的 Karel ,應該是 DOS 程式。

    + +

    這麼說來 Karel 機器人是怎麼在 DOS 上跑的呢?找了好一會,找到 DOS 版的 Karel ,不過有 Turbo Pascal 的界面,跑起來就是 ASCII 的文字圖。一直找不到 Richard E. Pattis 寫的 Karel 。感覺上 Richard E. Pattis 好像只有制定 Karel 語言標準,至於實作都是別人做的。反正程式也不難就是了。

    + +

    找到兩個版本的 DOS Karel : Timothy H. Totton 在 1990 年寫的 Turbo HAL使用說明), Linda Rising 寫的 Karel 2.0.2 。(女生耶!), Petr Laštovička 寫的捷克文 Karel 4.2Duane Buck 寫的 Karel 模擬器 ,則是 Karel the Robot 的書商 John Wiley & Sons, Inc. 提供下載, Windows 下的 Karel 模擬器,不過只能在舊版的 Windows 下執行。

    + +

    說起來, Logo 是更早期 UNIX 時代的產物。而且 Logo 須要有繪圖功能才能跑。不知道那個時候的 Logo ,是長什麼樣子的。可能要用磁帶機讀吧,所以更不可考了。

    + +
    + +
    + +
    +
    6.29.’13. 4:41am.
    + +

    白晝之雨

    + +

    白晝之雨是花蝶店員推薦的漫畫。好久沒有碰到這種可愛的店員了,霹靂啪啦自己推薦了一大堆漫畫停不下來,害我也很不好意思阻止她。她都那麼熱情,還幫我找到漫畫親吻戰神了,我還是硬著頭皮放了 300 元預付金,把白晝之雨帶回家看。日後她推薦的其它漫畫,還是要口試完才能看吧。嗯。不過總覺得有她的漫畫生活,會非常有趣。

    + +

    白晝之雨很奇怪,真的像她所說,是怪怪的漫畫。不難看,不過沒人推薦,我大概也不會去看。陰陰的,又很瑣碎,每個人都在瑣碎之中努力尋求生活的真實,而生活的真實,既不是 100 分的純粹,也不是 0 分的虛無,是在中間的分數之間不斷掙扎。森田的純粹,想當一個徹底邪惡的殺人魔,沒有勝利;安藤的純粹,想當一個徹底的純情者、徹底的處男、徹底的 M ,也沒有勝利;岡田的純粹,想過甜甜蜜蜜的人生,也沒有勝利。但他們也沒有完全失敗。就這樣。

    + +

    網路上對白晝之雨的評論,大多都是同情殺人魔森田,並且對森田的眼淚感到失望。我是不會這麼蠢啦。追求純粹的邪惡,也跟追求純粹的正義一樣,並沒有比較聰明。

    + +

    所以到最後,我還是不知道白晝之雨這個書名,是什麼意思。 + +

    + +
    + +
    +
    6.29.’13. 1:49am.
    + +

    面膜

    + +

    覺得市售的面膜,只是把浸滿精華液的不織布,蓋在臉上,讓臉上有泡在精華液中的效果而已。這麼說來,買化妝水精華液,每天晚上洗完澡後撲臉,效果也是一樣的,而且還比較省錢,比較環保,可以每天用,效果也比較好。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 183 | + 184 | + 185 | + 186 | + 187 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0185.html.zh-cn.html b/htdocs/imacat/me/diary/0185.html.zh-cn.html new file mode 120000 index 0000000..9a7b7f5 --- /dev/null +++ b/htdocs/imacat/me/diary/0185.html.zh-cn.html @@ -0,0 +1 @@ +0185.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0185.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0185.html.zh-cn.xhtml new file mode 100644 index 0000000..12a798e --- /dev/null +++ b/htdocs/imacat/me/diary/0185.html.zh-cn.xhtml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百八十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百八十五

    + +
    + +
    + +
    +
    7.7.’13. 2:46pm.
    + +

    绕颈露背洋装

    + +

    总觉得我对流行的感觉比别人慢一两年。内搭裤流行隔年,我才开始喜欢上内搭裤;踩脚裤流行几年以后,我才迷上踩脚裤; T 字凉鞋流行了两年,我才开始疯狂迷上 T 字凉鞋。

    + +

    绕颈露背洋装也是。去年年底才开始觉得我应该能穿绕颈露背洋装,夏天整个后背镂空,不知道会有多清爽。那时候看到一件经典梦露绕颈绑绳背心洋装,超想买。可是熬到今年夏天,前几天南港高中讲完课想买,就停产了。找遍了网路想找类似款,就是找不到,不是前胸太贴我没办法穿,就是后背不是露到我想要的腰,不然就不是短洋装,或是太短太窄会曝光不好走,或是我已经有的平口款,或是太小我不能穿,或是材质没有弹性我可能穿不下。连乐华夜市和师大夜市也走遍了,勉强找到几件都不是很满意。店员都说今年绕颈款式很少,看来我的流行感又晚别人好几年了。

    + +

    最后只好买这件,后背有点露太低了,不过我刚好可以穿,而且很好看。不知道买回来后敢不敢穿,不过算了。

    + +

    卖家好神奇,我 10:56 结标, 10:39 就通知我货寄出去了,才 45 分钟就寄出去了。不会是假的吧?还是正好每周结算寄货前夕呢?

    + +

    期待中!

    + +

    买到以后,就没有那么大想买露颈露背洋装的心理压力了。昨晚随便逛逛乐华夜市,想找件式样特别一点的露背、露肩洋装,找到都太短了会走光。唉。结果到最后还是什么都没买。

    + +

    发现我真的肥了,好可怕。最近晚上写不出来就一直吃点心,也没有运动。要节食了。

    + +
    + +
    + +
    +
    7.7.’13. 2:27pm.
    + +

    Karel

    + +

    忘了 Karel 的 1991 年,是 DOS 的时代。原版的 Karel ,应该是 DOS 程式。

    + +

    这么说来 Karel 机器人是怎么在 DOS 上跑的呢?找了好一会,找到 DOS 版的 Karel ,不过有 Turbo Pascal 的界面,跑起来就是 ASCII 的文字图。一直找不到 Richard E. Pattis 写的 Karel 。感觉上 Richard E. Pattis 好像只有制定 Karel 语言标准,至於实作都是别人做的。反正程式也不难就是了。

    + +

    找到两个版本的 DOS Karel : Timothy H. Totton 在 1990 年写的 Turbo HAL使用说明), Linda Rising 写的 Karel 2.0.2 。(女生耶!), Petr Laštovička 写的捷克文 Karel 4.2Duane Buck 写的 Karel 模拟器 ,则是 Karel the Robot 的书商 John Wiley & Sons, Inc. 提供下载, Windows 下的 Karel 模拟器,不过只能在旧版的 Windows 下执行。

    + +

    说起来, Logo 是更早期 UNIX 时代的产物。而且 Logo 须要有绘图功能才能跑。不知道那个时候的 Logo ,是长什么样子的。可能要用磁带机读吧,所以更不可考了。

    + +
    + +
    + +
    +
    6.29.’13. 4:41am.
    + +

    白昼之雨

    + +

    白昼之雨是花蝶店员推荐的漫画。好久没有碰到这种可爱的店员了,霹雳啪啦自己推荐了一大堆漫画停不下来,害我也很不好意思阻止她。她都那么热情,还帮我找到漫画亲吻战神了,我还是硬著头皮放了 300 元预付金,把白昼之雨带回家看。日后她推荐的其它漫画,还是要口试完才能看吧。嗯。不过总觉得有她的漫画生活,会非常有趣。

    + +

    白昼之雨很奇怪,真的像她所说,是怪怪的漫画。不难看,不过没人推荐,我大概也不会去看。阴阴的,又很琐碎,每个人都在琐碎之中努力寻求生活的真实,而生活的真实,既不是 100 分的纯粹,也不是 0 分的虚无,是在中间的分数之间不断挣扎。森田的纯粹,想当一个彻底邪恶的杀人魔,没有胜利;安藤的纯粹,想当一个彻底的纯情者、彻底的处男、彻底的 M ,也没有胜利;冈田的纯粹,想过甜甜蜜蜜的人生,也没有胜利。但他们也没有完全失败。就这样。

    + +

    网路上对白昼之雨的评论,大多都是同情杀人魔森田,并且对森田的眼泪感到失望。我是不会这么蠢啦。追求纯粹的邪恶,也跟追求纯粹的正义一样,并没有比较聪明。

    + +

    所以到最后,我还是不知道白昼之雨这个书名,是什么意思。 + +

    + +
    + +
    +
    6.29.’13. 1:49am.
    + +

    面膜

    + +

    觉得市售的面膜,只是把浸满精华液的不织布,盖在脸上,让脸上有泡在精华液中的效果而已。这么说来,买化妆水精华液,每天晚上洗完澡后扑脸,效果也是一样的,而且还比较省钱,比较环保,可以每天用,效果也比较好。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 183 | + 184 | + 185 | + 186 | + 187 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0185.html.zh-tw.html b/htdocs/imacat/me/diary/0185.html.zh-tw.html new file mode 120000 index 0000000..b1ee901 --- /dev/null +++ b/htdocs/imacat/me/diary/0185.html.zh-tw.html @@ -0,0 +1 @@ +0185.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0185.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0185.html.zh-tw.xhtml new file mode 100644 index 0000000..394c075 --- /dev/null +++ b/htdocs/imacat/me/diary/0185.html.zh-tw.xhtml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百八十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百八十五

    + +
    + +
    + +
    +
    7.7.’13. 2:46pm.
    + +

    繞頸露背洋裝

    + +

    總覺得我對流行的感覺比別人慢一兩年。內搭褲流行隔年,我才開始喜歡上內搭褲;踩腳褲流行幾年以後,我才迷上踩腳褲; T 字涼鞋流行了兩年,我才開始瘋狂迷上 T 字涼鞋。

    + +

    繞頸露背洋裝也是。去年年底才開始覺得我應該能穿繞頸露背洋裝,夏天整個後背鏤空,不知道會有多清爽。那時候看到一件經典夢露繞頸綁繩背心洋裝,超想買。可是熬到今年夏天,前幾天南港高中講完課想買,就停產了。找遍了網路想找類似款,就是找不到,不是前胸太貼我沒辦法穿,就是後背不是露到我想要的腰,不然就不是短洋裝,或是太短太窄會曝光不好走,或是我已經有的平口款,或是太小我不能穿,或是材質沒有彈性我可能穿不下。連樂華夜市和師大夜市也走遍了,勉強找到幾件都不是很滿意。店員都說今年繞頸款式很少,看來我的流行感又晚別人好幾年了。

    + +

    最後只好買這件,後背有點露太低了,不過我剛好可以穿,而且很好看。不知道買回來後敢不敢穿,不過算了。

    + +

    賣家好神奇,我 10:56 結標, 10:39 就通知我貨寄出去了,才 45 分鐘就寄出去了。不會是假的吧?還是正好每週結算寄貨前夕呢?

    + +

    期待中!

    + +

    買到以後,就沒有那麼大想買露頸露背洋裝的心理壓力了。昨晚隨便逛逛樂華夜市,想找件式樣特別一點的露背、露肩洋裝,找到都太短了會走光。唉。結果到最後還是什麼都沒買。

    + +

    發現我真的肥了,好可怕。最近晚上寫不出來就一直吃點心,也沒有運動。要節食了。

    + +
    + +
    + +
    +
    7.7.’13. 2:27pm.
    + +

    Karel

    + +

    忘了 Karel 的 1991 年,是 DOS 的時代。原版的 Karel ,應該是 DOS 程式。

    + +

    這麼說來 Karel 機器人是怎麼在 DOS 上跑的呢?找了好一會,找到 DOS 版的 Karel ,不過有 Turbo Pascal 的界面,跑起來就是 ASCII 的文字圖。一直找不到 Richard E. Pattis 寫的 Karel 。感覺上 Richard E. Pattis 好像只有制定 Karel 語言標準,至於實作都是別人做的。反正程式也不難就是了。

    + +

    找到兩個版本的 DOS Karel : Timothy H. Totton 在 1990 年寫的 Turbo HAL使用說明), Linda Rising 寫的 Karel 2.0.2 。(女生耶!), Petr Laštovička 寫的捷克文 Karel 4.2Duane Buck 寫的 Karel 模擬器 ,則是 Karel the Robot 的書商 John Wiley & Sons, Inc. 提供下載, Windows 下的 Karel 模擬器,不過只能在舊版的 Windows 下執行。

    + +

    說起來, Logo 是更早期 UNIX 時代的產物。而且 Logo 須要有繪圖功能才能跑。不知道那個時候的 Logo ,是長什麼樣子的。可能要用磁帶機讀吧,所以更不可考了。

    + +
    + +
    + +
    +
    6.29.’13. 4:41am.
    + +

    白晝之雨

    + +

    白晝之雨是花蝶店員推薦的漫畫。好久沒有碰到這種可愛的店員了,霹靂啪啦自己推薦了一大堆漫畫停不下來,害我也很不好意思阻止她。她都那麼熱情,還幫我找到漫畫親吻戰神了,我還是硬著頭皮放了 300 元預付金,把白晝之雨帶回家看。日後她推薦的其它漫畫,還是要口試完才能看吧。嗯。不過總覺得有她的漫畫生活,會非常有趣。

    + +

    白晝之雨很奇怪,真的像她所說,是怪怪的漫畫。不難看,不過沒人推薦,我大概也不會去看。陰陰的,又很瑣碎,每個人都在瑣碎之中努力尋求生活的真實,而生活的真實,既不是 100 分的純粹,也不是 0 分的虛無,是在中間的分數之間不斷掙扎。森田的純粹,想當一個徹底邪惡的殺人魔,沒有勝利;安藤的純粹,想當一個徹底的純情者、徹底的處男、徹底的 M ,也沒有勝利;岡田的純粹,想過甜甜蜜蜜的人生,也沒有勝利。但他們也沒有完全失敗。就這樣。

    + +

    網路上對白晝之雨的評論,大多都是同情殺人魔森田,並且對森田的眼淚感到失望。我是不會這麼蠢啦。追求純粹的邪惡,也跟追求純粹的正義一樣,並沒有比較聰明。

    + +

    所以到最後,我還是不知道白晝之雨這個書名,是什麼意思。 + +

    + +
    + +
    +
    6.29.’13. 1:49am.
    + +

    面膜

    + +

    覺得市售的面膜,只是把浸滿精華液的不織布,蓋在臉上,讓臉上有泡在精華液中的效果而已。這麼說來,買化妝水精華液,每天晚上洗完澡後撲臉,效果也是一樣的,而且還比較省錢,比較環保,可以每天用,效果也比較好。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 183 | + 184 | + 185 | + 186 | + 187 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0186.html.en.html b/htdocs/imacat/me/diary/0186.html.en.html new file mode 120000 index 0000000..41f8510 --- /dev/null +++ b/htdocs/imacat/me/diary/0186.html.en.html @@ -0,0 +1 @@ +0186.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0186.html.en.xhtml b/htdocs/imacat/me/diary/0186.html.en.xhtml new file mode 100644 index 0000000..bd4efdf --- /dev/null +++ b/htdocs/imacat/me/diary/0186.html.en.xhtml @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 186 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 186

    + +
    + +
    + +
    +
    7.10.’13. 3:37am.
    + +

    Karel the Robot

    + +

    網路上找了一晚,還用 Wine 裝了一大堆木馬,沒想到師大圖書館,就有這本「Karel the Robot: A Gentle Introduction to the Art of Programming」,還在總館館內,沒有被借走。馬上就去借來了。

    + +

    文獻探討一定要談 Karel ,要帶到 Greenfoot , Karel 的設計是很重要的關鍵。

    + +

    希望這是最後一本缺的文獻。寫不完了啊!(哀號)

    + +
    + +
    + +
    +
    7.10.’13. 3:34am.
    + +

    早期的 Logo

    + +

    早期的 Logo 是在 Mailframe 上執行的。當時是用一種叫作 teleprinter 的打字印表機,把 Logo 程式打進去,電腦會把 Logo 程式烏龜的軌跡圖,列印在紙上送出來。

    + +
    + +
    + +
    +
    7.10.’13. 0:52am.
    + +

    色狼事件後續

    + +

    其實,連我都沒有想到事情會有後續。現在真是超級生氣,不是對色狼生氣,是對自己生氣。

    + +
    色狼
    + +

    今天早上醒來,想想還是要去報案。中午去過一趟學校圖書館後,就回家裏附建的派出所報案。警察雖然熱心地給了我不少建議和協助,但最後還是沒有三聯單。我有時候對堆笑臉的人還是沒辦法。離開派出所後,越想越覺得被警察糊弄了。

    + +

    下午打工完,去公館錦城看漫畫。我因為習慣穿裙子,坐漫畫出租店沙發椅時,為免裙底走光,除了腿會夾緊外,會特別注意對面座的人,挑對面是空位或女生比較安心。晚上對面一個男生刻意移坐過來,坐過來後就低下身往我裙底看。

    + +

    我馬上就注意到他下流的眼神,瞪了他好一會,越看越眼熟,好像是昨晚的色狼。不過我平常不大會認人,又不大確定,瞪了一會,瞪到他換座位,想到要蒐證,就拿起手機拍他。拍了一張後,他就有警覺了。後來我想拍更多張,他一瞄到我拿手機,就開始拿書遮臉。

    + +

    就算不是他,也是長得很像他的人。不過從他的態度來看,我沒有記錯,就是他了。而且他還故意彎身看我裙底,兩個長得一模一樣的人都是色狼,見鬼了。

    + +

    想想,想試著錄音蒐證,就手機開錄音,然後往他走過去。他發現我走過去,馬上拿起手機假裝講電話,然後要逃走。我追上去問他,他當然現場否認,我只好讓他走掉了。

    + +

    事後回想,我應該直接報警,然後守在門口不讓他出去。昨晚跟他互瞪了好幾分鐘,明明記得他的長相,為什麼不相信自己的記憶?就算記錯了,他彎身看我裙底,我報警也不會報錯。

    + +

    我問店員,他是錦城常客。錦城全店都有監視攝影機,我記得他有去櫃台刷書,留有會員資料。這次我又有拍到清楚的照片,照片上有時間。只要把時間、監視攝影機畫面、出租店會員租書時間資料核對起來,一定可以抓到他。

    + +

    後來我拿照片,再去一次派出所,這次堅持要拿報案三聯單。警察說他們會先調監視器畫面,明天下午再請我正式報案,節省手續。這也不是不能接受就是了。

    + +

    昨晚我其實心情還很平靜,畢竟我有在管系統,扛三、四十公斤重的東西沒問題,對自己的力氣有自信,身高又比較高,並不怕他。可是今天再次碰到他,我竟然還是眼睜睜放他逃走,沒有報警抓他。身為一個女性主義者,竟然連著兩天兩次,讓猥褻現行犯從我手中溜走,真是沒用。對自己太生氣了!

    + +

    現在想想真的很可怕。他是錦城的常客?所以是守在我們家公寓門口等女生回家的隨機犯案,只是碰巧讓我在錦城遇到嗎?還是在錦城就注意到我,尾隨我而知道我家,針對我而來的?超恐怖!

    + +

    P.S.我平常嚴肅的時候,眼神煞氣很重。自拍的時候,都很困擾,表情都很僵。昨晚第一次感覺到眼神兇惡的好處。昨晚抓住他的時候,我還高他兩個階梯,那樣瞪著他,好像蛇盯著老鼠一樣。他一動也不敢動,大概以為我會當場殺了他吧。

    + +
    + +
    + +
    +
    7.9.’13. 3:22am.
    + +

    碰到色狼

    + +

    晚上回家,在樓下鐵門門口看到一個男人在講手機排徊,心裏開始警戒。二十幾歲左右,身高中等。長得有點像樓下最近搬來,門戶老是不關好的小鬼。拿鑰匙開門時,那個人裝做在請住戶開門,跟著我溜進鐵門內。關起門後我故意去旁邊開信箱,等他先上樓,我走後面。沒想到他不往前走還等我。我看了一眼,只好上樓。沒想到他突然一把摸下來。我馬上抓住他的手,惡狠狠地瞪他。

    + +

    雖然不害怕,但第一次碰到色狼,抓到現行犯的現場,也不知道接下來該怎麼辦。重複問了他兩三句:你要我報警嗎?想想也不知道接下來怎麼辦,就只好趕他走了。

    + +

    後來想想,應該報警,或直接抓去旁邊的派出所的。可是當時我雙肩各揹一個大袋子,沒把握能控制住他的行動,沒把握能全程把他押到警察局,用另一手拿起手機來報警,說不定會被他逃掉。回到家後反覆想,想到女生防身術的擒拿手,我抓住他左手,往左逆時針扭過去(右手的話往右順時針扭過去),把他的手反扭到背後,就能控制他的行動,扭送警察局,或是空出一隻手報警了。

    + +

    左想右想,應該不是樓下出入歲便的房客,應該是慣犯,在公寓門口等女生下班回家。沒有送去警察局,就會有下一個人受害。真是太失策了!

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 184 | + 185 | + 186 | + 187 | + 188 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0186.html.zh-cn.html b/htdocs/imacat/me/diary/0186.html.zh-cn.html new file mode 120000 index 0000000..065ce60 --- /dev/null +++ b/htdocs/imacat/me/diary/0186.html.zh-cn.html @@ -0,0 +1 @@ +0186.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0186.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0186.html.zh-cn.xhtml new file mode 100644 index 0000000..deeccc7 --- /dev/null +++ b/htdocs/imacat/me/diary/0186.html.zh-cn.xhtml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百八十六 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百八十六

    + +
    + +
    + +
    +
    7.10.’13. 3:37am.
    + +

    Karel the Robot

    + +

    网路上找了一晚,还用 Wine 装了一大堆木马,没想到师大图书馆,就有这本「Karel the Robot: A Gentle Introduction to the Art of Programming」,还在总馆馆内,没有被借走。马上就去借来了。

    + +

    文献探讨一定要谈 Karel ,要带到 Greenfoot , Karel 的设计是很重要的关键。

    + +

    希望这是最后一本缺的文献。写不完了啊!(哀号)

    + +
    + +
    + +
    +
    7.10.’13. 3:34am.
    + +

    早期的 Logo

    + +

    早期的 Logo 是在 Mailframe 上执行的。当时是用一种叫作 teleprinter 的打字印表机,把 Logo 程式打进去,电脑会把 Logo 程式乌龟的轨迹图,列印在纸上送出来。

    + +
    + +
    + +
    +
    7.10.’13. 0:52am.
    + +

    色狼事件后续

    + +

    其实,连我都没有想到事情会有后续。现在真是超级生气,不是对色狼生气,是对自己生气。

    + +
    色狼
    + +

    今天早上醒来,想想还是要去报案。中午去过一趟学校图书馆后,就回家里附建的派出所报案。警察虽然热心地给了我不少建议和协助,但最后还是没有三联单。我有时候对堆笑脸的人还是没办法。离开派出所后,越想越觉得被警察糊弄了。

    + +

    下午打工完,去公馆锦城看漫画。我因为习惯穿裙子,坐漫画出租店沙发椅时,为免裙底走光,除了腿会夹紧外,会特别注意对面座的人,挑对面是空位或女生比较安心。晚上对面一个男生刻意移坐过来,坐过来后就低下身往我裙底看。

    + +

    我马上就注意到他下流的眼神,瞪了他好一会,越看越眼熟,好像是昨晚的色狼。不过我平常不大会认人,又不大确定,瞪了一会,瞪到他换座位,想到要搜证,就拿起手机拍他。拍了一张后,他就有警觉了。后来我想拍更多张,他一瞄到我拿手机,就开始拿书遮脸。

    + +

    就算不是他,也是长得很像他的人。不过从他的态度来看,我没有记错,就是他了。而且他还故意弯身看我裙底,两个长得一模一样的人都是色狼,见鬼了。

    + +

    想想,想试著录音搜证,就手机开录音,然后往他走过去。他发现我走过去,马上拿起手机假装讲电话,然后要逃走。我追上去问他,他当然现场否认,我只好让他走掉了。

    + +

    事后回想,我应该直接报警,然后守在门口不让他出去。昨晚跟他互瞪了好几分钟,明明记得他的长相,为什么不相信自己的记忆?就算记错了,他弯身看我裙底,我报警也不会报错。

    + +

    我问店员,他是锦城常客。锦城全店都有监视摄影机,我记得他有去柜台刷书,留有会员资料。这次我又有拍到清楚的照片,照片上有时间。只要把时间、监视摄影机画面、出租店会员租书时间资料核对起来,一定可以抓到他。

    + +

    后来我拿照片,再去一次派出所,这次坚持要拿报案三联单。警察说他们会先调监视器画面,明天下午再请我正式报案,节省手续。这也不是不能接受就是了。

    + +

    昨晚我其实心情还很平静,毕竟我有在管系统,扛三、四十公斤重的东西没问题,对自己的力气有自信,身高又比较高,并不怕他。可是今天再次碰到他,我竟然还是眼睁睁放他逃走,没有报警抓他。身为一个女性主义者,竟然连著两天两次,让猥亵现行犯从我手中溜走,真是没用。对自己太生气了!

    + +

    现在想想真的很可怕。他是锦城的常客?所以是守在我们家公寓门口等女生回家的随机犯案,只是碰巧让我在锦城遇到吗?还是在锦城就注意到我,尾随我而知道我家,针对我而来的?超恐怖!

    + +

    P.S.我平常严肃的时候,眼神煞气很重。自拍的时候,都很困扰,表情都很僵。昨晚第一次感觉到眼神凶恶的好处。昨晚抓住他的时候,我还高他两个阶梯,那样瞪著他,好像蛇盯著老鼠一样。他一动也不敢动,大概以为我会当场杀了他吧。

    + +
    + +
    + +
    +
    7.9.’13. 3:22am.
    + +

    碰到色狼

    + +

    晚上回家,在楼下铁门门口看到一个男人在讲手机排徊,心里开始警戒。二十几岁左右,身高中等。长得有点像楼下最近搬来,门户老是不关好的小鬼。拿钥匙开门时,那个人装做在请住户开门,跟著我溜进铁门内。关起门后我故意去旁边开信箱,等他先上楼,我走后面。没想到他不往前走还等我。我看了一眼,只好上楼。没想到他突然一把摸下来。我马上抓住他的手,恶狠狠地瞪他。

    + +

    虽然不害怕,但第一次碰到色狼,抓到现行犯的现场,也不知道接下来该怎么办。重复问了他两三句:你要我报警吗?想想也不知道接下来怎么办,就只好赶他走了。

    + +

    后来想想,应该报警,或直接抓去旁边的派出所的。可是当时我双肩各背一个大袋子,没把握能控制住他的行动,没把握能全程把他押到警察局,用另一手拿起手机来报警,说不定会被他逃掉。回到家后反覆想,想到女生防身术的擒拿手,我抓住他左手,往左逆时针扭过去(右手的话往右顺时针扭过去),把他的手反扭到背后,就能控制他的行动,扭送警察局,或是空出一只手报警了。

    + +

    左想右想,应该不是楼下出入岁便的房客,应该是惯犯,在公寓门口等女生下班回家。没有送去警察局,就会有下一个人受害。真是太失策了!

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 184 | + 185 | + 186 | + 187 | + 188 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0186.html.zh-tw.html b/htdocs/imacat/me/diary/0186.html.zh-tw.html new file mode 120000 index 0000000..4e421d7 --- /dev/null +++ b/htdocs/imacat/me/diary/0186.html.zh-tw.html @@ -0,0 +1 @@ +0186.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0186.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0186.html.zh-tw.xhtml new file mode 100644 index 0000000..e21bdec --- /dev/null +++ b/htdocs/imacat/me/diary/0186.html.zh-tw.xhtml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百八十六 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百八十六

    + +
    + +
    + +
    +
    7.10.’13. 3:37am.
    + +

    Karel the Robot

    + +

    網路上找了一晚,還用 Wine 裝了一大堆木馬,沒想到師大圖書館,就有這本「Karel the Robot: A Gentle Introduction to the Art of Programming」,還在總館館內,沒有被借走。馬上就去借來了。

    + +

    文獻探討一定要談 Karel ,要帶到 Greenfoot , Karel 的設計是很重要的關鍵。

    + +

    希望這是最後一本缺的文獻。寫不完了啊!(哀號)

    + +
    + +
    + +
    +
    7.10.’13. 3:34am.
    + +

    早期的 Logo

    + +

    早期的 Logo 是在 Mailframe 上執行的。當時是用一種叫作 teleprinter 的打字印表機,把 Logo 程式打進去,電腦會把 Logo 程式烏龜的軌跡圖,列印在紙上送出來。

    + +
    + +
    + +
    +
    7.10.’13. 0:52am.
    + +

    色狼事件後續

    + +

    其實,連我都沒有想到事情會有後續。現在真是超級生氣,不是對色狼生氣,是對自己生氣。

    + +
    色狼
    + +

    今天早上醒來,想想還是要去報案。中午去過一趟學校圖書館後,就回家裏附建的派出所報案。警察雖然熱心地給了我不少建議和協助,但最後還是沒有三聯單。我有時候對堆笑臉的人還是沒辦法。離開派出所後,越想越覺得被警察糊弄了。

    + +

    下午打工完,去公館錦城看漫畫。我因為習慣穿裙子,坐漫畫出租店沙發椅時,為免裙底走光,除了腿會夾緊外,會特別注意對面座的人,挑對面是空位或女生比較安心。晚上對面一個男生刻意移坐過來,坐過來後就低下身往我裙底看。

    + +

    我馬上就注意到他下流的眼神,瞪了他好一會,越看越眼熟,好像是昨晚的色狼。不過我平常不大會認人,又不大確定,瞪了一會,瞪到他換座位,想到要蒐證,就拿起手機拍他。拍了一張後,他就有警覺了。後來我想拍更多張,他一瞄到我拿手機,就開始拿書遮臉。

    + +

    就算不是他,也是長得很像他的人。不過從他的態度來看,我沒有記錯,就是他了。而且他還故意彎身看我裙底,兩個長得一模一樣的人都是色狼,見鬼了。

    + +

    想想,想試著錄音蒐證,就手機開錄音,然後往他走過去。他發現我走過去,馬上拿起手機假裝講電話,然後要逃走。我追上去問他,他當然現場否認,我只好讓他走掉了。

    + +

    事後回想,我應該直接報警,然後守在門口不讓他出去。昨晚跟他互瞪了好幾分鐘,明明記得他的長相,為什麼不相信自己的記憶?就算記錯了,他彎身看我裙底,我報警也不會報錯。

    + +

    我問店員,他是錦城常客。錦城全店都有監視攝影機,我記得他有去櫃台刷書,留有會員資料。這次我又有拍到清楚的照片,照片上有時間。只要把時間、監視攝影機畫面、出租店會員租書時間資料核對起來,一定可以抓到他。

    + +

    後來我拿照片,再去一次派出所,這次堅持要拿報案三聯單。警察說他們會先調監視器畫面,明天下午再請我正式報案,節省手續。這也不是不能接受就是了。

    + +

    昨晚我其實心情還很平靜,畢竟我有在管系統,扛三、四十公斤重的東西沒問題,對自己的力氣有自信,身高又比較高,並不怕他。可是今天再次碰到他,我竟然還是眼睜睜放他逃走,沒有報警抓他。身為一個女性主義者,竟然連著兩天兩次,讓猥褻現行犯從我手中溜走,真是沒用。對自己太生氣了!

    + +

    現在想想真的很可怕。他是錦城的常客?所以是守在我們家公寓門口等女生回家的隨機犯案,只是碰巧讓我在錦城遇到嗎?還是在錦城就注意到我,尾隨我而知道我家,針對我而來的?超恐怖!

    + +

    P.S.我平常嚴肅的時候,眼神煞氣很重。自拍的時候,都很困擾,表情都很僵。昨晚第一次感覺到眼神兇惡的好處。昨晚抓住他的時候,我還高他兩個階梯,那樣瞪著他,好像蛇盯著老鼠一樣。他一動也不敢動,大概以為我會當場殺了他吧。

    + +
    + +
    + +
    +
    7.9.’13. 3:22am.
    + +

    碰到色狼

    + +

    晚上回家,在樓下鐵門門口看到一個男人在講手機排徊,心裏開始警戒。二十幾歲左右,身高中等。長得有點像樓下最近搬來,門戶老是不關好的小鬼。拿鑰匙開門時,那個人裝做在請住戶開門,跟著我溜進鐵門內。關起門後我故意去旁邊開信箱,等他先上樓,我走後面。沒想到他不往前走還等我。我看了一眼,只好上樓。沒想到他突然一把摸下來。我馬上抓住他的手,惡狠狠地瞪他。

    + +

    雖然不害怕,但第一次碰到色狼,抓到現行犯的現場,也不知道接下來該怎麼辦。重複問了他兩三句:你要我報警嗎?想想也不知道接下來怎麼辦,就只好趕他走了。

    + +

    後來想想,應該報警,或直接抓去旁邊的派出所的。可是當時我雙肩各揹一個大袋子,沒把握能控制住他的行動,沒把握能全程把他押到警察局,用另一手拿起手機來報警,說不定會被他逃掉。回到家後反覆想,想到女生防身術的擒拿手,我抓住他左手,往左逆時針扭過去(右手的話往右順時針扭過去),把他的手反扭到背後,就能控制他的行動,扭送警察局,或是空出一隻手報警了。

    + +

    左想右想,應該不是樓下出入歲便的房客,應該是慣犯,在公寓門口等女生下班回家。沒有送去警察局,就會有下一個人受害。真是太失策了!

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 184 | + 185 | + 186 | + 187 | + 188 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0187.html.en.html b/htdocs/imacat/me/diary/0187.html.en.html new file mode 120000 index 0000000..fac86d4 --- /dev/null +++ b/htdocs/imacat/me/diary/0187.html.en.html @@ -0,0 +1 @@ +0187.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0187.html.en.xhtml b/htdocs/imacat/me/diary/0187.html.en.xhtml new file mode 100644 index 0000000..c6efd72 --- /dev/null +++ b/htdocs/imacat/me/diary/0187.html.en.xhtml @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 187 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 187

    + +
    + +
    + +
    +
    7.15.’13. 11:15pm.
    + +

    討厭的論文

    + +

    多爭取到兩天,可以試著把論文初稿寫完。

    + +

    好討厭的論文監,真希望早點拚完,早點結束。

    + +
    + +
    + +
    +
    7.15.’13. 10:02am.
    + +

    終於

    + +

    終於趕完研究方法了。還剩下兩章:資料分析結果和討論。果然還是開天窗了。

    + +

    只好硬著頭皮去求老師,希望老師再等兩天了。最壞的狀況是拖到九月份畢業吧。

    + +

    好累。好想趕快脫離論文,回到沒有論文的世界。

    + +
    + +
    + +
    +
    7.13.’13. 3:53am.
    + +

    颱風天

    + +

    颱風天,風雨好大!

    + +
    + +
    + +
    +
    7.13.’13. 3:52am.
    + +

    文獻探討結束

    + +

    文獻探討終於結束了!呼。拖到早上四點。有點爛尾,不過算了。

    + +

    接下來怎麼辦啦?兩天能寫完結論嗎?(抱頭)

    + +
    + +
    + +
    +
    7.13.’13. 1:59am.
    + +

    結束文獻探討

    + +

    文獻探討的最後一部份,應該是寫 engaging 的判斷標準的,文獻有了,我卻寫不出來。超想昏倒啊!

    + +

    星期一要交初稿,怎麼看都不可能啊。怎麼辦?

    + +
    + +
    + +
    +
    7.13.’13. 1:58am.
    + +

    轉吧!企鵝罐

    + +

    轉吧!企鵝罐好像很好看。真的很有幾原邦彥的風格。口試完來看吧!

    + +

    話說少女革命我都還沒看完啊!

    + +
    + +
    + +
    +
    7.11.’13. 1:58pm.
    + +

    幾個大預言

    + +

    聽得很煩的幾個大預言。

    + +
      +
    • 中國的經濟,在十年內就會崩盤泡沫化。或是中國在五年內會崩潰分裂成地方割據勢力。
    • +
    • 受少子化的影響,現在的大學,五年內會有三分之一收起來。
    • +
    • 台灣的電力供應,在二十年內會不夠用。
    • +
    + +

    中國的經濟,在十年內就會崩盤泡沫化。這句話,第一次聽到,是九七的時候。到現在已經超過十年了,還是每個月都有專欄雜誌在寫,有專家在預言同一句話。大家都知道中國的經濟很扭曲,泡沫得很嚴重。不過這也是計劃經濟的特點:再怎麼扭曲泡沫,應該會崩盤的經濟,人為的管理黑手總是有辦法更加扭曲它,連崩盤的機制都扭曲掉了,讓它繼續泡沫上去。

    + +

    受少子化的影響,現在的大學,五年內會有三分之一收起來。這句話第一次聽到,也大約是十年前,教改開放大學的過一兩年的時候。現在已經五年過後五年再五年了,還是很多人掛在嘴邊。不過和中國的經濟一樣,人為管理的黑手,總是有辦法扭曲自然機制。就算再怎麼爛,全大學只有一百個學生,一個系全部只有個位數學生,教職員比學生多的大學,只要教育部不敢讓它倒,只要它們還有人脈關係,就是不會倒,每年還可以繼續拿好幾千萬的補助。

    + +

    一百個學生?你以為你是在辦大學,還是在辦偏鄉的義務教育?

    + +

    台灣的電力供應,在二十年內會不夠用。這句話是三、四十年前,我高中的時候,計劃興建核四時,所提出的主張。這和前兩者不同,就純然只是詐騙了。二十年後過去,第二個二十年也快過完了,台電還在講同樣一句預言。少子化人口成長減緩,產業外移,加上節能環保科技的進步,台灣的電力不但夠用,還綽綽有餘,核一核二核三關起來都沒問題。

    + +

    夠了!不要再把這些非常老舊的蠢預言拿來跟我說了啦!

    + +
    + +
    + +
    +
    7.11.’13. 11:38am.
    + +

    Alice

    + +

    忘了還有 Alice 還沒弄清楚。快昏頭了。還好馬上找到一篇 The Design of Alice 。只有 16 頁,希望一、兩個小時內可以看完。

    + +

    頭好昏。

    + +
    + +
    + +
    +
    7.11.’13. 11:37am.
    + +

    感冒

    + +

    昨晚電風扇沒開轉動,直直吹,感冒了。精神很不好。論文正在趕不及的時候,糟糕。

    + +

    整理了一下目前手上的文獻,讀過的有 70 篇,還沒讀的有 57 篇。總共 127 篇了。之前研究法老師說要畢業要讀一百篇左右。耶!這樣可以畢業了嗎?

    + +

    別傻了,不是總共 127 篇,是讀過的 70 篇。還差 30 篇。

    + +

    快昏頭了。

    + +
    + +
    + +
    +
    7.10.’13. 7:43pm.
    + +

    Scratch 2.0

    + +

    Scratch 2.0 完全瀏覽器上跑,真的是太讓我吃驚了! Google 把 AppInventor 捐給 MIT 後, Scratch 團隊看來從 AppInventor 學到很多東西。

    + +

    不過這樣,網路不穩或沒有網路的學校,怎麼辦?而且日後後要做像 S4A 一樣的分支版,就很難做出來了。

    + +
    + +
    + +
    +
    7.10.’13. 3:45am.
    + +

    程式碼內縮的重要

    + +

    Microworld 理論的時候,讀到:

    + +
    +
      +
    • Representations clarify the problem space for students, such as by organizing the problem and the search path.
    • +
    • A good representation reveals immediate implications.
    • +
    +
    + +

    想起上禮拜三天的 Greenfoot 經驗。發現初學者學程式設計時,程式碼內縮很重要。因為 C 系統的語言(包括 Java ),內不內縮不影響編譯,所以很多老師教學的時候,都不重視程式碼內縮。但是視覺結構會影響認知結構,程式碼內縮良好時,學生也很容易在腦中建立程式結構的心智模型。所以程式碼內縮,對初學者真的非常、非常重要。

    + +

    這麼說來,以內縮作為程式結構的 Python 和 Ruby ,的確很適合初學者,因為程式碼的視覺架構,直接對應到程式結構,學生很容易建立程式結構的心智模型,不會學了半天,還只能照抄老師指示的程式碼,不知道自己在寫什麼。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 185 | + 186 | + 187 | + 188 | + 189 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0187.html.zh-cn.html b/htdocs/imacat/me/diary/0187.html.zh-cn.html new file mode 120000 index 0000000..cce2d53 --- /dev/null +++ b/htdocs/imacat/me/diary/0187.html.zh-cn.html @@ -0,0 +1 @@ +0187.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0187.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0187.html.zh-cn.xhtml new file mode 100644 index 0000000..b97b4ab --- /dev/null +++ b/htdocs/imacat/me/diary/0187.html.zh-cn.xhtml @@ -0,0 +1,318 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百八十七 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百八十七

    + +
    + +
    + +
    +
    7.15.’13. 11:15pm.
    + +

    讨厌的论文

    + +

    多争取到两天,可以试著把论文初稿写完。

    + +

    好讨厌的论文监,真希望早点拚完,早点结束。

    + +
    + +
    + +
    +
    7.15.’13. 10:02am.
    + +

    终於

    + +

    终於赶完研究方法了。还剩下两章:资料分析结果和讨论。果然还是开天窗了。

    + +

    只好硬著头皮去求老师,希望老师再等两天了。最坏的状况是拖到九月份毕业吧。

    + +

    好累。好想赶快脱离论文,回到没有论文的世界。

    + +
    + +
    + +
    +
    7.13.’13. 3:53am.
    + +

    台风天

    + +

    台风天,风雨好大!

    + +
    + +
    + +
    +
    7.13.’13. 3:52am.
    + +

    文献探讨结束

    + +

    文献探讨终於结束了!呼。拖到早上四点。有点烂尾,不过算了。

    + +

    接下来怎么办啦?两天能写完结论吗?(抱头)

    + +
    + +
    + +
    +
    7.13.’13. 1:59am.
    + +

    结束文献探讨

    + +

    文献探讨的最后一部份,应该是写 engaging 的判断标准的,文献有了,我却写不出来。超想昏倒啊!

    + +

    星期一要交初稿,怎么看都不可能啊。怎么办?

    + +
    + +
    + +
    +
    7.13.’13. 1:58am.
    + +

    转吧!企鹅罐

    + +

    转吧!企鹅罐好像很好看。真的很有几原邦彦的风格。口试完来看吧!

    + +

    话说少女革命我都还没看完啊!

    + +
    + +
    + +
    +
    7.11.’13. 1:58pm.
    + +

    几个大预言

    + +

    听得很烦的几个大预言。

    + +
      +
    • 中国的经济,在十年内就会崩盘泡沫化。或是中国在五年内会崩溃分裂成地方割据势力。
    • +
    • 受少子化的影响,现在的大学,五年内会有三分之一收起来。
    • +
    • 台湾的电力供应,在二十年内会不够用。
    • +
    + +

    中国的经济,在十年内就会崩盘泡沫化。这句话,第一次听到,是九七的时候。到现在已经超过十年了,还是每个月都有专栏杂志在写,有专家在预言同一句话。大家都知道中国的经济很扭曲,泡沫得很严重。不过这也是计划经济的特点:再怎么扭曲泡沫,应该会崩盘的经济,人为的管理黑手总是有办法更加扭曲它,连崩盘的机制都扭曲掉了,让它继续泡沫上去。

    + +

    受少子化的影响,现在的大学,五年内会有三分之一收起来。这句话第一次听到,也大约是十年前,教改开放大学的过一两年的时候。现在已经五年过后五年再五年了,还是很多人挂在嘴边。不过和中国的经济一样,人为管理的黑手,总是有办法扭曲自然机制。就算再怎么烂,全大学只有一百个学生,一个系全部只有个位数学生,教职员比学生多的大学,只要教育部不敢让它倒,只要它们还有人脉关系,就是不会倒,每年还可以继续拿好几千万的补助。

    + +

    一百个学生?你以为你是在办大学,还是在办偏乡的义务教育?

    + +

    台湾的电力供应,在二十年内会不够用。这句话是三、四十年前,我高中的时候,计划兴建核四时,所提出的主张。这和前两者不同,就纯然只是诈骗了。二十年后过去,第二个二十年也快过完了,台电还在讲同样一句预言。少子化人口成长减缓,产业外移,加上节能环保科技的进步,台湾的电力不但够用,还绰绰有余,核一核二核三关起来都没问题。

    + +

    够了!不要再把这些非常老旧的蠢预言拿来跟我说了啦!

    + +
    + +
    + +
    +
    7.11.’13. 11:38am.
    + +

    Alice

    + +

    忘了还有 Alice 还没弄清楚。快昏头了。还好马上找到一篇 The Design of Alice 。只有 16 页,希望一、两个小时内可以看完。

    + +

    头好昏。

    + +
    + +
    + +
    +
    7.11.’13. 11:37am.
    + +

    感冒

    + +

    昨晚电风扇没开转动,直直吹,感冒了。精神很不好。论文正在赶不及的时候,糟糕。

    + +

    整理了一下目前手上的文献,读过的有 70 篇,还没读的有 57 篇。总共 127 篇了。之前研究法老师说要毕业要读一百篇左右。耶!这样可以毕业了吗?

    + +

    别傻了,不是总共 127 篇,是读过的 70 篇。还差 30 篇。

    + +

    快昏头了。

    + +
    + +
    + +
    +
    7.10.’13. 7:43pm.
    + +

    Scratch 2.0

    + +

    Scratch 2.0 完全浏览器上跑,真的是太让我吃惊了! Google 把 AppInventor 捐给 MIT 后, Scratch 团队看来从 AppInventor 学到很多东西。

    + +

    不过这样,网路不稳或没有网路的学校,怎么办?而且日后后要做像 S4A 一样的分支版,就很难做出来了。

    + +
    + +
    + +
    +
    7.10.’13. 3:45am.
    + +

    程式码内缩的重要

    + +

    Microworld 理论的时候,读到:

    + +
    +
      +
    • Representations clarify the problem space for students, such as by organizing the problem and the search path.
    • +
    • A good representation reveals immediate implications.
    • +
    +
    + +

    想起上礼拜三天的 Greenfoot 经验。发现初学者学程式设计时,程式码内缩很重要。因为 C 系统的语言(包括 Java ),内不内缩不影响编译,所以很多老师教学的时候,都不重视程式码内缩。但是视觉结构会影响认知结构,程式码内缩良好时,学生也很容易在脑中建立程式结构的心智模型。所以程式码内缩,对初学者真的非常、非常重要。

    + +

    这么说来,以内缩作为程式结构的 Python 和 Ruby ,的确很适合初学者,因为程式码的视觉架构,直接对应到程式结构,学生很容易建立程式结构的心智模型,不会学了半天,还只能照抄老师指示的程式码,不知道自己在写什么。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 185 | + 186 | + 187 | + 188 | + 189 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0187.html.zh-tw.html b/htdocs/imacat/me/diary/0187.html.zh-tw.html new file mode 120000 index 0000000..de4afd0 --- /dev/null +++ b/htdocs/imacat/me/diary/0187.html.zh-tw.html @@ -0,0 +1 @@ +0187.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0187.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0187.html.zh-tw.xhtml new file mode 100644 index 0000000..8bbf9a0 --- /dev/null +++ b/htdocs/imacat/me/diary/0187.html.zh-tw.xhtml @@ -0,0 +1,318 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百八十七 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百八十七

    + +
    + +
    + +
    +
    7.15.’13. 11:15pm.
    + +

    討厭的論文

    + +

    多爭取到兩天,可以試著把論文初稿寫完。

    + +

    好討厭的論文監,真希望早點拚完,早點結束。

    + +
    + +
    + +
    +
    7.15.’13. 10:02am.
    + +

    終於

    + +

    終於趕完研究方法了。還剩下兩章:資料分析結果和討論。果然還是開天窗了。

    + +

    只好硬著頭皮去求老師,希望老師再等兩天了。最壞的狀況是拖到九月份畢業吧。

    + +

    好累。好想趕快脫離論文,回到沒有論文的世界。

    + +
    + +
    + +
    +
    7.13.’13. 3:53am.
    + +

    颱風天

    + +

    颱風天,風雨好大!

    + +
    + +
    + +
    +
    7.13.’13. 3:52am.
    + +

    文獻探討結束

    + +

    文獻探討終於結束了!呼。拖到早上四點。有點爛尾,不過算了。

    + +

    接下來怎麼辦啦?兩天能寫完結論嗎?(抱頭)

    + +
    + +
    + +
    +
    7.13.’13. 1:59am.
    + +

    結束文獻探討

    + +

    文獻探討的最後一部份,應該是寫 engaging 的判斷標準的,文獻有了,我卻寫不出來。超想昏倒啊!

    + +

    星期一要交初稿,怎麼看都不可能啊。怎麼辦?

    + +
    + +
    + +
    +
    7.13.’13. 1:58am.
    + +

    轉吧!企鵝罐

    + +

    轉吧!企鵝罐好像很好看。真的很有幾原邦彥的風格。口試完來看吧!

    + +

    話說少女革命我都還沒看完啊!

    + +
    + +
    + +
    +
    7.11.’13. 1:58pm.
    + +

    幾個大預言

    + +

    聽得很煩的幾個大預言。

    + +
      +
    • 中國的經濟,在十年內就會崩盤泡沫化。或是中國在五年內會崩潰分裂成地方割據勢力。
    • +
    • 受少子化的影響,現在的大學,五年內會有三分之一收起來。
    • +
    • 台灣的電力供應,在二十年內會不夠用。
    • +
    + +

    中國的經濟,在十年內就會崩盤泡沫化。這句話,第一次聽到,是九七的時候。到現在已經超過十年了,還是每個月都有專欄雜誌在寫,有專家在預言同一句話。大家都知道中國的經濟很扭曲,泡沫得很嚴重。不過這也是計劃經濟的特點:再怎麼扭曲泡沫,應該會崩盤的經濟,人為的管理黑手總是有辦法更加扭曲它,連崩盤的機制都扭曲掉了,讓它繼續泡沫上去。

    + +

    受少子化的影響,現在的大學,五年內會有三分之一收起來。這句話第一次聽到,也大約是十年前,教改開放大學的過一兩年的時候。現在已經五年過後五年再五年了,還是很多人掛在嘴邊。不過和中國的經濟一樣,人為管理的黑手,總是有辦法扭曲自然機制。就算再怎麼爛,全大學只有一百個學生,一個系全部只有個位數學生,教職員比學生多的大學,只要教育部不敢讓它倒,只要它們還有人脈關係,就是不會倒,每年還可以繼續拿好幾千萬的補助。

    + +

    一百個學生?你以為你是在辦大學,還是在辦偏鄉的義務教育?

    + +

    台灣的電力供應,在二十年內會不夠用。這句話是三、四十年前,我高中的時候,計劃興建核四時,所提出的主張。這和前兩者不同,就純然只是詐騙了。二十年後過去,第二個二十年也快過完了,台電還在講同樣一句預言。少子化人口成長減緩,產業外移,加上節能環保科技的進步,台灣的電力不但夠用,還綽綽有餘,核一核二核三關起來都沒問題。

    + +

    夠了!不要再把這些非常老舊的蠢預言拿來跟我說了啦!

    + +
    + +
    + +
    +
    7.11.’13. 11:38am.
    + +

    Alice

    + +

    忘了還有 Alice 還沒弄清楚。快昏頭了。還好馬上找到一篇 The Design of Alice 。只有 16 頁,希望一、兩個小時內可以看完。

    + +

    頭好昏。

    + +
    + +
    + +
    +
    7.11.’13. 11:37am.
    + +

    感冒

    + +

    昨晚電風扇沒開轉動,直直吹,感冒了。精神很不好。論文正在趕不及的時候,糟糕。

    + +

    整理了一下目前手上的文獻,讀過的有 70 篇,還沒讀的有 57 篇。總共 127 篇了。之前研究法老師說要畢業要讀一百篇左右。耶!這樣可以畢業了嗎?

    + +

    別傻了,不是總共 127 篇,是讀過的 70 篇。還差 30 篇。

    + +

    快昏頭了。

    + +
    + +
    + +
    +
    7.10.’13. 7:43pm.
    + +

    Scratch 2.0

    + +

    Scratch 2.0 完全瀏覽器上跑,真的是太讓我吃驚了! Google 把 AppInventor 捐給 MIT 後, Scratch 團隊看來從 AppInventor 學到很多東西。

    + +

    不過這樣,網路不穩或沒有網路的學校,怎麼辦?而且日後後要做像 S4A 一樣的分支版,就很難做出來了。

    + +
    + +
    + +
    +
    7.10.’13. 3:45am.
    + +

    程式碼內縮的重要

    + +

    Microworld 理論的時候,讀到:

    + +
    +
      +
    • Representations clarify the problem space for students, such as by organizing the problem and the search path.
    • +
    • A good representation reveals immediate implications.
    • +
    +
    + +

    想起上禮拜三天的 Greenfoot 經驗。發現初學者學程式設計時,程式碼內縮很重要。因為 C 系統的語言(包括 Java ),內不內縮不影響編譯,所以很多老師教學的時候,都不重視程式碼內縮。但是視覺結構會影響認知結構,程式碼內縮良好時,學生也很容易在腦中建立程式結構的心智模型。所以程式碼內縮,對初學者真的非常、非常重要。

    + +

    這麼說來,以內縮作為程式結構的 Python 和 Ruby ,的確很適合初學者,因為程式碼的視覺架構,直接對應到程式結構,學生很容易建立程式結構的心智模型,不會學了半天,還只能照抄老師指示的程式碼,不知道自己在寫什麼。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 185 | + 186 | + 187 | + 188 | + 189 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0188.html.en.html b/htdocs/imacat/me/diary/0188.html.en.html new file mode 120000 index 0000000..fe27a76 --- /dev/null +++ b/htdocs/imacat/me/diary/0188.html.en.html @@ -0,0 +1 @@ +0188.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0188.html.en.xhtml b/htdocs/imacat/me/diary/0188.html.en.xhtml new file mode 100644 index 0000000..33cae56 --- /dev/null +++ b/htdocs/imacat/me/diary/0188.html.en.xhtml @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 188 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 188

    + +
    + +
    + +
    +
    10.10.’13. 9:29pm.
    + +

    Open Invention Network (OIN) 授權合約摘要筆記

    + +

    今天代表 WoFOSS 簽了 OIN 的專利授權合約。原文是商業專利權律師撰寫,非常難懂,摘要筆記之。可能有其他人會用到,因此分享在此。本文依 2013/9/6 版本的 OIN 授權合約。本文謹供參考,我不負任何責任,實際條款以原文合約為準。若商業公司要簽署 OIN 專利授權合約,請自行審閱原文合約,並與專利權律師依原文合約討論過,再行決定。

    + +
    1. 授權
    +
    +1.1 從今天起你被我們所有人在 Linux 上授權。
    +
    +1.2 (a) 你從今天起在 Linux 上授權我們所有人。
    +    (b) (i) 你保證你有權作以上授權。
    +        (ii) 你保證你目前沒有對我們成員提告。
    +    你和你的子公司在 Linux 不對其他成員提告,以換取你不被其他成員提告。
    +
    +1.3 你過往在 Linux 上被我們成員提告的訴訟一筆勾銷。
    +
    +1.4 你一筆勾銷過往在 Linux 上控告所有我們成員的訴訟。
    +
    +2. 授權異動、限制
    +
    +2.1 OIN 日後修訂會在 60 天前告知。
    +
    +2.2 限制授權:
    + (a) 限制授權日後一年內,只有可授權的部份有效,其他成員授權當日終止。
    + (b) 你 1.1 被授權範圍,限於你之前的產品。
    + (c) Linux 定義以限制授權日為準。
    + (d) 你 1.2 不授權給之後的新成員。
    + (e) 之後 OIN 的新授權,不授權給你。
    +
    +2.3 你無法繼續授權(如被購併)時:
    + (a) 你的 1.1 被授權結束。
    + (b) 之前你已 1.2 授權的,持續有效。
    + (c) 其他授權終止。
    +
    +3 授權終止
    +
    +3.1 授權自簽署後生效,終止於你和 OIN 專利最後結束日期。
    +
    +3.2 子公司脫離後, 1.1 被授權當日終止。母公司脫離後,母公司之前 1.2 已授權持續有效。
    +
    +3.3 若你或子公司,被其他成員或其母公司告,你可以暫停對他的 1.2 授權,直到他撤告。
    +
    +3.4 你一提告,對方不是被你 3.3 暫停授權的話,你的 1.1 被授權也會終止。
    +
    +3.5 終止暫停日前,合約義務仍有效。
    +
    +4. 通知
    +
    +本合約的通知需簽名,並通知下列地址:
    +
    +5. 雜項
    +
    +5.1 專利依合約授權,合約權利義務,非經對方同意,不可轉移。
    +
    +5.2 OIN 保證 1 有權授權。你只保證 1.2 有權授權。
    +
    +5.3 本合約不影響你和他人的授權。
    +
    +5.4 本合約希望不與 GPL 衝突,有衝突時以 GPL 解釋為準。
    +
    +5.5 所有成員都有權依本合約要求你。
    + +
    + +
    + +
    +
    7.19.’13. 4:54am.
    + +

    蟑螂

    + +

    一晚殺了三隻蟑螂。嗯啊。

    + +

    不知道為什麼家裏突然出現這麼多隻蟑螂。不過這三隻出現在家裏有一段時間了。一隻大的躲在浴室浴缸底下,兩隻一大一中躲在廚房。查了網路,大的好像是美洲蟑螂,中的以前沒見過這種,好像是澳洲蟑螂。

    + +

    本來以為蟑螂只能活七天,以為家裏有躲更多蟑螂。剛剛網路上查,蟑螂壽命有四、五十天。看來真的只有這三隻。

    + +

    之前忙唸書沒管,而且不解家裏沒下廚哪來蟑螂食物?晚上在廚房發現大的,轉頭拿殺蟲劑,一回頭又不見了。仔細一看,原來躲在棕刷上。對準一噴,沒想到一口氣掉下來兩隻。原來如此!因為刷炒鍋的棕刷上的殘油嗎?

    + +

    最後兩隻都落在水槽翻肚。這次不敢大意,不敢去動它們,怕一驚動又跑了,先放著。過了一會回來看,還再動,只好再噴。小力徐徐噴,不敢讓它因為噴氣力再翻回來。再過一會來看,真的不動了。拿衛生紙去撥也不會動,真的死透了,才來收拾。

    + +

    回房間不久,浴室那隻又跑出來。嚇死了。趕緊同樣方法對付,噴到翻肚後,就先擱著,過一會再來對著肚子徐徐噴。一下子就死了。

    + +

    等待的時候上網查,發現原來蟑螂的呼吸孔在肚子上,翻度時,對著肚子小力徐徐噴,讓它直接吸進殺蟲劑,就算沒有毒死,也被殺蟲劑堵塞呼吸恐窒息死。這樣一下子就死了。

    + +

    恐怖感還沒完全消失。希望就這三隻,沒了。大概是從樓下沿排水管爬上來的吧。唉。

    + +
    + +
    + +
    +
    7.18.’13. 6:34am.
    + +

    收工

    + +

    終於趕出來了。所以現在是…早上六點半嗎?

    + +
    + +
    + +
    +
    7.18.’13. 4:59am.
    + +

    終於

    + +

    終於,結論。

    + +

    拜託再給我一點點精神和腦力,讓我趕完吧!

    + +
    + +
    + +
    +
    7.15.’13. 11:43pm.
    + +

    公費留考與 TOEFL iBT

    + +

    公費留考的 TOEFL iBT 標準是 80 分以上,而我只唸三小時,考出來的成績是 96 分。 :p

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 186 | + 187 | + 188 | + 189 | + 190 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0188.html.zh-cn.html b/htdocs/imacat/me/diary/0188.html.zh-cn.html new file mode 120000 index 0000000..c7cdac8 --- /dev/null +++ b/htdocs/imacat/me/diary/0188.html.zh-cn.html @@ -0,0 +1 @@ +0188.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0188.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0188.html.zh-cn.xhtml new file mode 100644 index 0000000..1397629 --- /dev/null +++ b/htdocs/imacat/me/diary/0188.html.zh-cn.xhtml @@ -0,0 +1,276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百八十八 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百八十八

    + +
    + +
    + +
    +
    10.10.’13. 9:29pm.
    + +

    Open Invention Network (OIN) 授权合约摘要笔记

    + +

    今天代表 WoFOSS 签了 OIN 的专利授权合约。原文是商业专利权律师撰写,非常难懂,摘要笔记之。可能有其他人会用到,因此分享在此。本文依 2013/9/6 版本的 OIN 授权合约。本文谨供参考,我不负任何责任,实际条款以原文合约为准。若商业公司要签署 OIN 专利授权合约,请自行审阅原文合约,并与专利权律师依原文合约讨论过,再行决定。

    + +
    1. 授权
    +
    +1.1 从今天起你被我们所有人在 Linux 上授权。
    +
    +1.2 (a) 你从今天起在 Linux 上授权我们所有人。
    +    (b) (i) 你保证你有权作以上授权。
    +        (ii) 你保证你目前没有对我们成员提告。
    +    你和你的子公司在 Linux 不对其他成员提告,以换取你不被其他成员提告。
    +
    +1.3 你过往在 Linux 上被我们成员提告的诉讼一笔勾销。
    +
    +1.4 你一笔勾销过往在 Linux 上控告所有我们成员的诉讼。
    +
    +2. 授权异动、限制
    +
    +2.1 OIN 日后修订会在 60 天前告知。
    +
    +2.2 限制授权:
    + (a) 限制授权日后一年内,只有可授权的部份有效,其他成员授权当日终止。
    + (b) 你 1.1 被授权范围,限於你之前的产品。
    + (c) Linux 定义以限制授权日为准。
    + (d) 你 1.2 不授权给之后的新成员。
    + (e) 之后 OIN 的新授权,不授权给你。
    +
    +2.3 你无法继续授权(如被购并)时:
    + (a) 你的 1.1 被授权结束。
    + (b) 之前你已 1.2 授权的,持续有效。
    + (c) 其他授权终止。
    +
    +3 授权终止
    +
    +3.1 授权自签署后生效,终止於你和 OIN 专利最后结束日期。
    +
    +3.2 子公司脱离后, 1.1 被授权当日终止。母公司脱离后,母公司之前 1.2 已授权持续有效。
    +
    +3.3 若你或子公司,被其他成员或其母公司告,你可以暂停对他的 1.2 授权,直到他撤告。
    +
    +3.4 你一提告,对方不是被你 3.3 暂停授权的话,你的 1.1 被授权也会终止。
    +
    +3.5 终止暂停日前,合约义务仍有效。
    +
    +4. 通知
    +
    +本合约的通知需签名,并通知下列地址:
    +
    +5. 杂项
    +
    +5.1 专利依合约授权,合约权利义务,非经对方同意,不可转移。
    +
    +5.2 OIN 保证 1 有权授权。你只保证 1.2 有权授权。
    +
    +5.3 本合约不影响你和他人的授权。
    +
    +5.4 本合约希望不与 GPL 冲突,有冲突时以 GPL 解释为准。
    +
    +5.5 所有成员都有权依本合约要求你。
    + +
    + +
    + +
    +
    7.19.’13. 4:54am.
    + +

    蟑螂

    + +

    一晚杀了三只蟑螂。嗯啊。

    + +

    不知道为什么家里突然出现这么多只蟑螂。不过这三只出现在家里有一段时间了。一只大的躲在浴室浴缸底下,两只一大一中躲在厨房。查了网路,大的好像是美洲蟑螂,中的以前没见过这种,好像是澳洲蟑螂。

    + +

    本来以为蟑螂只能活七天,以为家里有躲更多蟑螂。刚刚网路上查,蟑螂寿命有四、五十天。看来真的只有这三只。

    + +

    之前忙念书没管,而且不解家里没下厨哪来蟑螂食物?晚上在厨房发现大的,转头拿杀虫剂,一回头又不见了。仔细一看,原来躲在棕刷上。对准一喷,没想到一口气掉下来两只。原来如此!因为刷炒锅的棕刷上的残油吗?

    + +

    最后两只都落在水槽翻肚。这次不敢大意,不敢去动它们,怕一惊动又跑了,先放著。过了一会回来看,还再动,只好再喷。小力徐徐喷,不敢让它因为喷气力再翻回来。再过一会来看,真的不动了。拿卫生纸去拨也不会动,真的死透了,才来收拾。

    + +

    回房间不久,浴室那只又跑出来。吓死了。赶紧同样方法对付,喷到翻肚后,就先搁著,过一会再来对著肚子徐徐喷。一下子就死了。

    + +

    等待的时候上网查,发现原来蟑螂的呼吸孔在肚子上,翻度时,对著肚子小力徐徐喷,让它直接吸进杀虫剂,就算没有毒死,也被杀虫剂堵塞呼吸恐窒息死。这样一下子就死了。

    + +

    恐怖感还没完全消失。希望就这三只,没了。大概是从楼下沿排水管爬上来的吧。唉。

    + +
    + +
    + +
    +
    7.18.’13. 6:34am.
    + +

    收工

    + +

    终於赶出来了。所以现在是…早上六点半吗?

    + +
    + +
    + +
    +
    7.18.’13. 4:59am.
    + +

    终於

    + +

    终於,结论。

    + +

    拜托再给我一点点精神和脑力,让我赶完吧!

    + +
    + +
    + +
    +
    7.15.’13. 11:43pm.
    + +

    公费留考与 TOEFL iBT

    + +

    公费留考的 TOEFL iBT 标准是 80 分以上,而我只念三小时,考出来的成绩是 96 分。 :p

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 186 | + 187 | + 188 | + 189 | + 190 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0188.html.zh-tw.html b/htdocs/imacat/me/diary/0188.html.zh-tw.html new file mode 120000 index 0000000..9910739 --- /dev/null +++ b/htdocs/imacat/me/diary/0188.html.zh-tw.html @@ -0,0 +1 @@ +0188.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0188.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0188.html.zh-tw.xhtml new file mode 100644 index 0000000..b7d3224 --- /dev/null +++ b/htdocs/imacat/me/diary/0188.html.zh-tw.xhtml @@ -0,0 +1,276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百八十八 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百八十八

    + +
    + +
    + +
    +
    10.10.’13. 9:29pm.
    + +

    Open Invention Network (OIN) 授權合約摘要筆記

    + +

    今天代表 WoFOSS 簽了 OIN 的專利授權合約。原文是商業專利權律師撰寫,非常難懂,摘要筆記之。可能有其他人會用到,因此分享在此。本文依 2013/9/6 版本的 OIN 授權合約。本文謹供參考,我不負任何責任,實際條款以原文合約為準。若商業公司要簽署 OIN 專利授權合約,請自行審閱原文合約,並與專利權律師依原文合約討論過,再行決定。

    + +
    1. 授權
    +
    +1.1 從今天起你被我們所有人在 Linux 上授權。
    +
    +1.2 (a) 你從今天起在 Linux 上授權我們所有人。
    +    (b) (i) 你保證你有權作以上授權。
    +        (ii) 你保證你目前沒有對我們成員提告。
    +    你和你的子公司在 Linux 不對其他成員提告,以換取你不被其他成員提告。
    +
    +1.3 你過往在 Linux 上被我們成員提告的訴訟一筆勾銷。
    +
    +1.4 你一筆勾銷過往在 Linux 上控告所有我們成員的訴訟。
    +
    +2. 授權異動、限制
    +
    +2.1 OIN 日後修訂會在 60 天前告知。
    +
    +2.2 限制授權:
    + (a) 限制授權日後一年內,只有可授權的部份有效,其他成員授權當日終止。
    + (b) 你 1.1 被授權範圍,限於你之前的產品。
    + (c) Linux 定義以限制授權日為準。
    + (d) 你 1.2 不授權給之後的新成員。
    + (e) 之後 OIN 的新授權,不授權給你。
    +
    +2.3 你無法繼續授權(如被購併)時:
    + (a) 你的 1.1 被授權結束。
    + (b) 之前你已 1.2 授權的,持續有效。
    + (c) 其他授權終止。
    +
    +3 授權終止
    +
    +3.1 授權自簽署後生效,終止於你和 OIN 專利最後結束日期。
    +
    +3.2 子公司脫離後, 1.1 被授權當日終止。母公司脫離後,母公司之前 1.2 已授權持續有效。
    +
    +3.3 若你或子公司,被其他成員或其母公司告,你可以暫停對他的 1.2 授權,直到他撤告。
    +
    +3.4 你一提告,對方不是被你 3.3 暫停授權的話,你的 1.1 被授權也會終止。
    +
    +3.5 終止暫停日前,合約義務仍有效。
    +
    +4. 通知
    +
    +本合約的通知需簽名,並通知下列地址:
    +
    +5. 雜項
    +
    +5.1 專利依合約授權,合約權利義務,非經對方同意,不可轉移。
    +
    +5.2 OIN 保證 1 有權授權。你只保證 1.2 有權授權。
    +
    +5.3 本合約不影響你和他人的授權。
    +
    +5.4 本合約希望不與 GPL 衝突,有衝突時以 GPL 解釋為準。
    +
    +5.5 所有成員都有權依本合約要求你。
    + +
    + +
    + +
    +
    7.19.’13. 4:54am.
    + +

    蟑螂

    + +

    一晚殺了三隻蟑螂。嗯啊。

    + +

    不知道為什麼家裏突然出現這麼多隻蟑螂。不過這三隻出現在家裏有一段時間了。一隻大的躲在浴室浴缸底下,兩隻一大一中躲在廚房。查了網路,大的好像是美洲蟑螂,中的以前沒見過這種,好像是澳洲蟑螂。

    + +

    本來以為蟑螂只能活七天,以為家裏有躲更多蟑螂。剛剛網路上查,蟑螂壽命有四、五十天。看來真的只有這三隻。

    + +

    之前忙唸書沒管,而且不解家裏沒下廚哪來蟑螂食物?晚上在廚房發現大的,轉頭拿殺蟲劑,一回頭又不見了。仔細一看,原來躲在棕刷上。對準一噴,沒想到一口氣掉下來兩隻。原來如此!因為刷炒鍋的棕刷上的殘油嗎?

    + +

    最後兩隻都落在水槽翻肚。這次不敢大意,不敢去動它們,怕一驚動又跑了,先放著。過了一會回來看,還再動,只好再噴。小力徐徐噴,不敢讓它因為噴氣力再翻回來。再過一會來看,真的不動了。拿衛生紙去撥也不會動,真的死透了,才來收拾。

    + +

    回房間不久,浴室那隻又跑出來。嚇死了。趕緊同樣方法對付,噴到翻肚後,就先擱著,過一會再來對著肚子徐徐噴。一下子就死了。

    + +

    等待的時候上網查,發現原來蟑螂的呼吸孔在肚子上,翻度時,對著肚子小力徐徐噴,讓它直接吸進殺蟲劑,就算沒有毒死,也被殺蟲劑堵塞呼吸恐窒息死。這樣一下子就死了。

    + +

    恐怖感還沒完全消失。希望就這三隻,沒了。大概是從樓下沿排水管爬上來的吧。唉。

    + +
    + +
    + +
    +
    7.18.’13. 6:34am.
    + +

    收工

    + +

    終於趕出來了。所以現在是…早上六點半嗎?

    + +
    + +
    + +
    +
    7.18.’13. 4:59am.
    + +

    終於

    + +

    終於,結論。

    + +

    拜託再給我一點點精神和腦力,讓我趕完吧!

    + +
    + +
    + +
    +
    7.15.’13. 11:43pm.
    + +

    公費留考與 TOEFL iBT

    + +

    公費留考的 TOEFL iBT 標準是 80 分以上,而我只唸三小時,考出來的成績是 96 分。 :p

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 186 | + 187 | + 188 | + 189 | + 190 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0189.html.en.html b/htdocs/imacat/me/diary/0189.html.en.html new file mode 120000 index 0000000..c9b7f8f --- /dev/null +++ b/htdocs/imacat/me/diary/0189.html.en.html @@ -0,0 +1 @@ +0189.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0189.html.en.xhtml b/htdocs/imacat/me/diary/0189.html.en.xhtml new file mode 100644 index 0000000..e0c7350 --- /dev/null +++ b/htdocs/imacat/me/diary/0189.html.en.xhtml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 189 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 189

    + +
    + +
    + +
    +
    11.25.’13. 2:13am.
    + +

    宗教博物館

    + +

    中午去中和磨菜刀,磨完去取刀的路上,經過 SOGO 旁的宗教博物館。宗教博物館就在家後面。家後面就有一座博物館,那麼多年了,總想應該去看看,可是也沒有很想去,像雞肋一樣。下午沒什麼約,正好可以去走走,去打鐵店拿回菜刀回來,就買了門票進去了。

    + +

    坐電梯上七樓博物館,慢慢走過長廊,正要開始看時,被導覽志工叫住,問要不要一起參加導覽。想想也好,就跟著走了。

    + +

    導覽志工帶著人群回一樓,說導覽全程大概一個半小時。我的媽呀!我只是隨便來逛逛而已,還有東西要買,回家還有家事。耐著性子聽了一會,志工就博物館的每個設計,開始講解設計背後的心靈智慧。我實在不愛聽這些人生智慧的空談,而且這些我上來的路上就已經注意到了。趁講解到熱烈的時候,偷偷溜了。

    + +

    志工導覽時,指著天花板橫樑上的萬千法門,同歸方寸問大家什麼是方寸。我沒多想就脫口而出,志工很高興地送了我獎品。其實答案很簡單,不大好意思拿什麼獎品。不過轉頭一看,是一張很可愛的書籤,就不要臉地收下來了。

    + +

    其實從小對宗教哲學,一直都很有興趣,高中反覆唸過蔡志忠的禪宗、老莊漫畫,空大時也用力唸過中國思想史。像這樣的問題,對我來說都很基本。所以實在不想耗在這樣的問題上,還是先溜了。

    + +

    我對宗教的興趣,比較傾向哲學、社會文化層面,而不是心靈、信仰層面。所以我很能欣賞、喜歡各種宗教間的異同,卻不會想要去追隨,也不會想要萬道歸一

    + +

    宗教博物館是個很奇怪的存在。哲學、文化可以並存,信仰卻是互斥的。會想把十個左右的世界主要宗教,一起擺在一個小空間中,努力解釋、尋求它們的共同之處,這件事本身就很矛盾。大概也只有某些佛教宗派,會這樣主張。事實上宗教博物館,是靈鷲山發起經營的。

    + +

    有一些收獲:在特展中,看了波斯拜火教,世界上第一個一神教。這是我第一次接觸到拜火教。也看了好幾個台灣比較少接觸到的宗教,像印度教、錫克教等。原來錫克教是在回教和印度教的夾縫中生出來的。原來阿南達、奎師那是印度教的,原來創價學會是日本神道教的。也第一次比較了猶太教和基督宗教的不同。

    + +

    在特展中,知道了原來靈鷲山以禪宗後繼者自居。難怪感覺很多地方很熟悉。

    + +

    另外,再每個宗教中,也介紹了現在在台灣的發展現況。這部份也是比較珍貴的資料。宗教常常和民族社會習習相關,部份宗教如基督宗教、佛教、回教可以跨越民族界線,但像神道教就很少在日本以外的地方生根,印度教和錫克教,也幾乎只有印度人信仰,在台灣,除了來台的外國人外,幾乎沒有宗教活動。

    + +

    也有不滿處。介紹台灣民間信仰時,眾神圖中,主神是玉皇大帝,沒有媽祖。台灣民間信仰最大的主神、香火最盛、轄區最廣的是天后媽祖,台灣最盛的其實是女神信仰。列舉男神,忽略媽祖的背後,其實有很嚴重的性別盲。

    + +

    就這樣。博物館小歸小,還是蠻有趣的。

    + +
    + +
    + +
    +
    11.25.’13. 1:16am.
    + +

    初音的聲線

    + +

    在漫畫出租店,聽著店家放的音樂,覺得很耳熟。想起是有名的 Vocaloid ,不過一時之間想不起名字。

    + +

    離開的時候,問店員:現在在放的是哪個誰的吧?店員看看歌單說:我也不知道,這首歌沒有寫名字。失望地走出去幾步,突然想起初音這個名字,興奮地回過頭去跟店員講。店員沒認出來,只能尷尬地陪笑。

    + +

    初音的聲線其實很好認:

    + +
      +
    1. 調音器調出來的聲音,假假的,很像 MIDI
    2. + +
    3. 絕對音準,絕對不會走音。因此也不會轉音、技巧音。
    4. + +
    5. 音量平穩,沒有起伏。
    6. +
    + +

    想起去年堂妹來台灣,帶她去月讀女僕咖啡,當時她也很興奮地跟我說,店裏正播放著初音的歌。那時候我也認不出來,只能尷尬地陪笑。現在立場完全反過來了。什麼時候開始,我認得出初音的聲線了呢?

    + +
    + +
    + +
    +
    11.14.’13. 4:00pm.
    + +

    網路書籤服務

    + +

    不知不覺間,把噗浪和臉書的分享,當成了簡單的 Web 剪貼簿,看到有趣的事務、有用的資源,就直接貼上來。等到注意到的時候,噗浪河道和臉書塗鴉牆,已經累積了大量的網路資源,找不回來,很苦惱。

    + +

    這一陣子比較空,開始想辦法把這些連結找回來。先找的是書籤服務,先試了有名的 Delicious ,結果奇慘,匯入超慢,也不支援中文匯入。後來找到 pinboard.in ,還有洛克鳥的推薦。冒險付了一次性註冊費後,發現真的很好用,介面簡單,速度快,中文匯入匯出也都沒問題。

    + +

    找到書籤服務後,接下來想辦法把臉書連結抓回來。試了臉書自己的下載備份功能,可是備份中沒有連結。再試過臉書 App Give Me My Data ,可以抓回連結,可是只能抓到公開連結,可是我塗鴉牆上大多都不是公開連結。找了很久,才找到 SocialSafe ,可以以自己的權限抓回所有檔案,抓回來的是 SQLite 資料庫,可以簡單讀回來。真是太好了!

    + +

    筆記一下,先用 SocialSafe 抓回完整塗鴉牆,再用 pinboard.in 匯入儲存。

    + +

    匯入後,再慢慢整理,發現很多很久以前看到的有趣東西。真好!

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 187 | + 188 | + 189 | + 190 | + 191 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0189.html.zh-cn.html b/htdocs/imacat/me/diary/0189.html.zh-cn.html new file mode 120000 index 0000000..34bb4d4 --- /dev/null +++ b/htdocs/imacat/me/diary/0189.html.zh-cn.html @@ -0,0 +1 @@ +0189.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0189.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0189.html.zh-cn.xhtml new file mode 100644 index 0000000..366d90e --- /dev/null +++ b/htdocs/imacat/me/diary/0189.html.zh-cn.xhtml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百八十九 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百八十九

    + +
    + +
    + +
    +
    11.25.’13. 2:13am.
    + +

    宗教博物馆

    + +

    中午去中和磨菜刀,磨完去取刀的路上,经过 SOGO 旁的宗教博物馆。宗教博物馆就在家后面。家后面就有一座博物馆,那么多年了,总想应该去看看,可是也没有很想去,像鸡肋一样。下午没什么约,正好可以去走走,去打铁店拿回菜刀回来,就买了门票进去了。

    + +

    坐电梯上七楼博物馆,慢慢走过长廊,正要开始看时,被导览志工叫住,问要不要一起参加导览。想想也好,就跟著走了。

    + +

    导览志工带著人群回一楼,说导览全程大概一个半小时。我的妈呀!我只是随便来逛逛而已,还有东西要买,回家还有家事。耐著性子听了一会,志工就博物馆的每个设计,开始讲解设计背后的心灵智慧。我实在不爱听这些人生智慧的空谈,而且这些我上来的路上就已经注意到了。趁讲解到热烈的时候,偷偷溜了。

    + +

    志工导览时,指著天花板横梁上的万千法门,同归方寸问大家什么是方寸。我没多想就脱口而出,志工很高兴地送了我奖品。其实答案很简单,不大好意思拿什么奖品。不过转头一看,是一张很可爱的书签,就不要脸地收下来了。

    + +

    其实从小对宗教哲学,一直都很有兴趣,高中反覆念过蔡志忠的禅宗、老庄漫画,空大时也用力念过中国思想史。像这样的问题,对我来说都很基本。所以实在不想耗在这样的问题上,还是先溜了。

    + +

    我对宗教的兴趣,比较倾向哲学、社会文化层面,而不是心灵、信仰层面。所以我很能欣赏、喜欢各种宗教间的异同,却不会想要去追随,也不会想要万道归一

    + +

    宗教博物馆是个很奇怪的存在。哲学、文化可以并存,信仰却是互斥的。会想把十个左右的世界主要宗教,一起摆在一个小空间中,努力解释、寻求它们的共同之处,这件事本身就很矛盾。大概也只有某些佛教宗派,会这样主张。事实上宗教博物馆,是灵鹫山发起经营的。

    + +

    有一些收获:在特展中,看了波斯拜火教,世界上第一个一神教。这是我第一次接触到拜火教。也看了好几个台湾比较少接触到的宗教,像印度教、锡克教等。原来锡克教是在回教和印度教的夹缝中生出来的。原来阿南达、奎师那是印度教的,原来创价学会是日本神道教的。也第一次比较了犹太教和基督宗教的不同。

    + +

    在特展中,知道了原来灵鹫山以禅宗后继者自居。难怪感觉很多地方很熟悉。

    + +

    另外,再每个宗教中,也介绍了现在在台湾的发展现况。这部份也是比较珍贵的资料。宗教常常和民族社会习习相关,部份宗教如基督宗教、佛教、回教可以跨越民族界线,但像神道教就很少在日本以外的地方生根,印度教和锡克教,也几乎只有印度人信仰,在台湾,除了来台的外国人外,几乎没有宗教活动。

    + +

    也有不满处。介绍台湾民间信仰时,众神图中,主神是玉皇大帝,没有妈祖。台湾民间信仰最大的主神、香火最盛、辖区最广的是天后妈祖,台湾最盛的其实是女神信仰。列举男神,忽略妈祖的背后,其实有很严重的性别盲。

    + +

    就这样。博物馆小归小,还是蛮有趣的。

    + +
    + +
    + +
    +
    11.25.’13. 1:16am.
    + +

    初音的声线

    + +

    在漫画出租店,听著店家放的音乐,觉得很耳熟。想起是有名的 Vocaloid ,不过一时之间想不起名字。

    + +

    离开的时候,问店员:现在在放的是哪个谁的吧?店员看看歌单说:我也不知道,这首歌没有写名字。失望地走出去几步,突然想起初音这个名字,兴奋地回过头去跟店员讲。店员没认出来,只能尴尬地陪笑。

    + +

    初音的声线其实很好认:

    + +
      +
    1. 调音器调出来的声音,假假的,很像 MIDI
    2. + +
    3. 绝对音准,绝对不会走音。因此也不会转音、技巧音。
    4. + +
    5. 音量平稳,没有起伏。
    6. +
    + +

    想起去年堂妹来台湾,带她去月读女仆咖啡,当时她也很兴奋地跟我说,店里正播放著初音的歌。那时候我也认不出来,只能尴尬地陪笑。现在立场完全反过来了。什么时候开始,我认得出初音的声线了呢?

    + +
    + +
    + +
    +
    11.14.’13. 4:00pm.
    + +

    网路书签服务

    + +

    不知不觉间,把噗浪和脸书的分享,当成了简单的 Web 剪贴簿,看到有趣的事务、有用的资源,就直接贴上来。等到注意到的时候,噗浪河道和脸书涂鸦墙,已经累积了大量的网路资源,找不回来,很苦恼。

    + +

    这一阵子比较空,开始想办法把这些连结找回来。先找的是书签服务,先试了有名的 Delicious ,结果奇惨,汇入超慢,也不支援中文汇入。后来找到 pinboard.in ,还有洛克鸟的推荐。冒险付了一次性注册费后,发现真的很好用,介面简单,速度快,中文汇入汇出也都没问题。

    + +

    找到书签服务后,接下来想办法把脸书连结抓回来。试了脸书自己的下载备份功能,可是备份中没有连结。再试过脸书 App Give Me My Data ,可以抓回连结,可是只能抓到公开连结,可是我涂鸦墙上大多都不是公开连结。找了很久,才找到 SocialSafe ,可以以自己的权限抓回所有档案,抓回来的是 SQLite 资料库,可以简单读回来。真是太好了!

    + +

    笔记一下,先用 SocialSafe 抓回完整涂鸦墙,再用 pinboard.in 汇入储存。

    + +

    汇入后,再慢慢整理,发现很多很久以前看到的有趣东西。真好!

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 187 | + 188 | + 189 | + 190 | + 191 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0189.html.zh-tw.html b/htdocs/imacat/me/diary/0189.html.zh-tw.html new file mode 120000 index 0000000..67be85b --- /dev/null +++ b/htdocs/imacat/me/diary/0189.html.zh-tw.html @@ -0,0 +1 @@ +0189.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0189.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0189.html.zh-tw.xhtml new file mode 100644 index 0000000..bd88dfc --- /dev/null +++ b/htdocs/imacat/me/diary/0189.html.zh-tw.xhtml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百八十九 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百八十九

    + +
    + +
    + +
    +
    11.25.’13. 2:13am.
    + +

    宗教博物館

    + +

    中午去中和磨菜刀,磨完去取刀的路上,經過 SOGO 旁的宗教博物館。宗教博物館就在家後面。家後面就有一座博物館,那麼多年了,總想應該去看看,可是也沒有很想去,像雞肋一樣。下午沒什麼約,正好可以去走走,去打鐵店拿回菜刀回來,就買了門票進去了。

    + +

    坐電梯上七樓博物館,慢慢走過長廊,正要開始看時,被導覽志工叫住,問要不要一起參加導覽。想想也好,就跟著走了。

    + +

    導覽志工帶著人群回一樓,說導覽全程大概一個半小時。我的媽呀!我只是隨便來逛逛而已,還有東西要買,回家還有家事。耐著性子聽了一會,志工就博物館的每個設計,開始講解設計背後的心靈智慧。我實在不愛聽這些人生智慧的空談,而且這些我上來的路上就已經注意到了。趁講解到熱烈的時候,偷偷溜了。

    + +

    志工導覽時,指著天花板橫樑上的萬千法門,同歸方寸問大家什麼是方寸。我沒多想就脫口而出,志工很高興地送了我獎品。其實答案很簡單,不大好意思拿什麼獎品。不過轉頭一看,是一張很可愛的書籤,就不要臉地收下來了。

    + +

    其實從小對宗教哲學,一直都很有興趣,高中反覆唸過蔡志忠的禪宗、老莊漫畫,空大時也用力唸過中國思想史。像這樣的問題,對我來說都很基本。所以實在不想耗在這樣的問題上,還是先溜了。

    + +

    我對宗教的興趣,比較傾向哲學、社會文化層面,而不是心靈、信仰層面。所以我很能欣賞、喜歡各種宗教間的異同,卻不會想要去追隨,也不會想要萬道歸一

    + +

    宗教博物館是個很奇怪的存在。哲學、文化可以並存,信仰卻是互斥的。會想把十個左右的世界主要宗教,一起擺在一個小空間中,努力解釋、尋求它們的共同之處,這件事本身就很矛盾。大概也只有某些佛教宗派,會這樣主張。事實上宗教博物館,是靈鷲山發起經營的。

    + +

    有一些收獲:在特展中,看了波斯拜火教,世界上第一個一神教。這是我第一次接觸到拜火教。也看了好幾個台灣比較少接觸到的宗教,像印度教、錫克教等。原來錫克教是在回教和印度教的夾縫中生出來的。原來阿南達、奎師那是印度教的,原來創價學會是日本神道教的。也第一次比較了猶太教和基督宗教的不同。

    + +

    在特展中,知道了原來靈鷲山以禪宗後繼者自居。難怪感覺很多地方很熟悉。

    + +

    另外,再每個宗教中,也介紹了現在在台灣的發展現況。這部份也是比較珍貴的資料。宗教常常和民族社會習習相關,部份宗教如基督宗教、佛教、回教可以跨越民族界線,但像神道教就很少在日本以外的地方生根,印度教和錫克教,也幾乎只有印度人信仰,在台灣,除了來台的外國人外,幾乎沒有宗教活動。

    + +

    也有不滿處。介紹台灣民間信仰時,眾神圖中,主神是玉皇大帝,沒有媽祖。台灣民間信仰最大的主神、香火最盛、轄區最廣的是天后媽祖,台灣最盛的其實是女神信仰。列舉男神,忽略媽祖的背後,其實有很嚴重的性別盲。

    + +

    就這樣。博物館小歸小,還是蠻有趣的。

    + +
    + +
    + +
    +
    11.25.’13. 1:16am.
    + +

    初音的聲線

    + +

    在漫畫出租店,聽著店家放的音樂,覺得很耳熟。想起是有名的 Vocaloid ,不過一時之間想不起名字。

    + +

    離開的時候,問店員:現在在放的是哪個誰的吧?店員看看歌單說:我也不知道,這首歌沒有寫名字。失望地走出去幾步,突然想起初音這個名字,興奮地回過頭去跟店員講。店員沒認出來,只能尷尬地陪笑。

    + +

    初音的聲線其實很好認:

    + +
      +
    1. 調音器調出來的聲音,假假的,很像 MIDI
    2. + +
    3. 絕對音準,絕對不會走音。因此也不會轉音、技巧音。
    4. + +
    5. 音量平穩,沒有起伏。
    6. +
    + +

    想起去年堂妹來台灣,帶她去月讀女僕咖啡,當時她也很興奮地跟我說,店裏正播放著初音的歌。那時候我也認不出來,只能尷尬地陪笑。現在立場完全反過來了。什麼時候開始,我認得出初音的聲線了呢?

    + +
    + +
    + +
    +
    11.14.’13. 4:00pm.
    + +

    網路書籤服務

    + +

    不知不覺間,把噗浪和臉書的分享,當成了簡單的 Web 剪貼簿,看到有趣的事務、有用的資源,就直接貼上來。等到注意到的時候,噗浪河道和臉書塗鴉牆,已經累積了大量的網路資源,找不回來,很苦惱。

    + +

    這一陣子比較空,開始想辦法把這些連結找回來。先找的是書籤服務,先試了有名的 Delicious ,結果奇慘,匯入超慢,也不支援中文匯入。後來找到 pinboard.in ,還有洛克鳥的推薦。冒險付了一次性註冊費後,發現真的很好用,介面簡單,速度快,中文匯入匯出也都沒問題。

    + +

    找到書籤服務後,接下來想辦法把臉書連結抓回來。試了臉書自己的下載備份功能,可是備份中沒有連結。再試過臉書 App Give Me My Data ,可以抓回連結,可是只能抓到公開連結,可是我塗鴉牆上大多都不是公開連結。找了很久,才找到 SocialSafe ,可以以自己的權限抓回所有檔案,抓回來的是 SQLite 資料庫,可以簡單讀回來。真是太好了!

    + +

    筆記一下,先用 SocialSafe 抓回完整塗鴉牆,再用 pinboard.in 匯入儲存。

    + +

    匯入後,再慢慢整理,發現很多很久以前看到的有趣東西。真好!

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 187 | + 188 | + 189 | + 190 | + 191 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0190.html.en.html b/htdocs/imacat/me/diary/0190.html.en.html new file mode 120000 index 0000000..eb3af95 --- /dev/null +++ b/htdocs/imacat/me/diary/0190.html.en.html @@ -0,0 +1 @@ +0190.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0190.html.en.xhtml b/htdocs/imacat/me/diary/0190.html.en.xhtml new file mode 100644 index 0000000..414dd30 --- /dev/null +++ b/htdocs/imacat/me/diary/0190.html.en.xhtml @@ -0,0 +1,241 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 190 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 190

    + +
    + +
    + +
    +
    12.14.’13. 1:41pm.
    + +

    Bard’s Tale

    + +

    差不多去年這個時候,買的 Bard’s Tale 。可是檔案太大,趁特價買下來後,就先刪了。這兩天清空手機舊 App 後,再挖出來玩了一下。

    + +

    嗯,還是不大好玩。

    + +
      +
    1. 不知道為什麼要用 3D 。其實根本無法調整到平行視角,只能由正上方俯視,看不到畫面細節,還常常因為可旋轉的方向,弄到方位錯亂。 2D 斜上 45 度地圖視角就好了啊,簡單好操作!
    2. + +
    3. 不知道為什麼要用模擬搖桿移動,難用得半死。為什麼不加上自動尋路系統呢?
    4. + +
    5. 對話語音、字幕太快。這是考我英聽還是英讀?不管是哪個都遠超過我的速度了!
    6. +
    + +

    不過全語音是很棒,對話也非常有趣。

    + +

    就這樣,一個不知道玩不玩得完的遊戲。玩得好累!

    + +
    + +
    + +
    +
    12.5.’13. 0:16am.
    + +

    多人家庭

    + +

    想再講清楚多人家庭。

    + +

    這是一個簡單又清楚的多人家庭例子。我不知道為什麼保守團體把多人家庭當成亂源。事實上,很多人應該都有經驗過,跟幾個單身的好友、姊妹們,約好老了沒伴的話,就一起住,就算不去養老院,也有個照應。這也是多人家庭。

    + +

    事實上,老人照養設施,也是多人家庭。許多沒有血緣的老人,就算戶籍不在一起,他們也實質地在一起生活,實質地組成家庭,直到終老。他們沒有跟原生家庭在一起生活,而是跟養老院的同伴、照護們一起生活,組成家庭。

    + +

    我們的社會,到處都是多人家庭。多人家庭,真的是那麼怪異、混亂的一件事嗎?

    + +
    + +
    + +
    + +
    +
    12.4.’13. 9:50pm.
    + +

    鱸魚

    + +
    +失敗的鱸魚 +
    + +

    想做豆瓣魚,依著食譜,到新生市場想買鯉魚。可是沒有鯉魚好買,問老闆有什麼可以替代,老闆推薦鱸魚。從來沒買過鱸魚這麼好的魚。捨不得買太貴,挑了兩隻最小的。每隻稱重超過一斤,正好食譜也寫要一斤四兩左右。

    + +

    算來兩隻將近兩百九,老闆算兩百伍給我。等老闆娘處理魚的時候,聽其他客人和老闆閒聊,才知道老闆家前晚女兒訂婚。算來將近八五折,算是賺到了。

    + +

    買回來做豆瓣魚,結果大失敗。鱸魚魚皮魚肉太軟,根本禁不起翻炸煮,而且一斤多果然太大了,炒鍋快放不下。我們家的家用廚具,能處理的魚的極限還是一斤。

    + +

    不過鱸魚的肉真肥美。隔天看閃光感冒,想想也沒辦法做豆瓣魚,就拿來煮湯了。

    + +
    + +
    + +
    + +
    +
    12.4.’13. 9:06pm.
    + +

    UL 性轉 3

    + +
    +UL 性轉 3 +
    + +

    第一次買同人誌,九號機UL 性轉 3

    + +

    最早是被九號機的噗迷上的,那時候第一次知道什麼是性轉,開始瘋狂尋找相關的性轉作品,甚至開始玩 Unlight

    + +

    前兩天看到九號機要出 UL 性轉 4 了,順著找到懶洋洋賣場,看到 UL 性轉 3 還有,趕快買下來!

    + +
    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 188 | + 189 | + 190 | + 191 | + 192 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0190.html.zh-cn.html b/htdocs/imacat/me/diary/0190.html.zh-cn.html new file mode 120000 index 0000000..c8d83a2 --- /dev/null +++ b/htdocs/imacat/me/diary/0190.html.zh-cn.html @@ -0,0 +1 @@ +0190.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0190.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0190.html.zh-cn.xhtml new file mode 100644 index 0000000..0267b0b --- /dev/null +++ b/htdocs/imacat/me/diary/0190.html.zh-cn.xhtml @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百九十 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百九十

    + +
    + +
    + +
    +
    12.14.’13. 1:41pm.
    + +

    Bard’s Tale

    + +

    差不多去年这个时候,买的 Bard’s Tale 。可是档案太大,趁特价买下来后,就先删了。这两天清空手机旧 App 后,再挖出来玩了一下。

    + +

    嗯,还是不大好玩。

    + +
      +
    1. 不知道为什么要用 3D 。其实根本无法调整到平行视角,只能由正上方俯视,看不到画面细节,还常常因为可旋转的方向,弄到方位错乱。 2D 斜上 45 度地图视角就好了啊,简单好操作!
    2. + +
    3. 不知道为什么要用模拟摇杆移动,难用得半死。为什么不加上自动寻路系统呢?
    4. + +
    5. 对话语音、字幕太快。这是考我英听还是英读?不管是哪个都远超过我的速度了!
    6. +
    + +

    不过全语音是很棒,对话也非常有趣。

    + +

    就这样,一个不知道玩不玩得完的游戏。玩得好累!

    + +
    + +
    + +
    +
    12.5.’13. 0:16am.
    + +

    多人家庭

    + +

    想再讲清楚多人家庭。

    + +

    这是一个简单又清楚的多人家庭例子。我不知道为什么保守团体把多人家庭当成乱源。事实上,很多人应该都有经验过,跟几个单身的好友、姊妹们,约好老了没伴的话,就一起住,就算不去养老院,也有个照应。这也是多人家庭。

    + +

    事实上,老人照养设施,也是多人家庭。许多没有血缘的老人,就算户籍不在一起,他们也实质地在一起生活,实质地组成家庭,直到终老。他们没有跟原生家庭在一起生活,而是跟养老院的同伴、照护们一起生活,组成家庭。

    + +

    我们的社会,到处都是多人家庭。多人家庭,真的是那么怪异、混乱的一件事吗?

    + +
    + +
    + +
    + +
    +
    12.4.’13. 9:50pm.
    + +

    鲈鱼

    + +
    +失败的鲈鱼 +
    + +

    想做豆瓣鱼,依著食谱,到新生市场想买鲤鱼。可是没有鲤鱼好买,问老板有什么可以替代,老板推荐鲈鱼。从来没买过鲈鱼这么好的鱼。舍不得买太贵,挑了两只最小的。每只称重超过一斤,正好食谱也写要一斤四两左右。

    + +

    算来两只将近两百九,老板算两百伍给我。等老板娘处理鱼的时候,听其他客人和老板闲聊,才知道老板家前晚女儿订婚。算来将近八五折,算是赚到了。

    + +

    买回来做豆瓣鱼,结果大失败。鲈鱼鱼皮鱼肉太软,根本禁不起翻炸煮,而且一斤多果然太大了,炒锅快放不下。我们家的家用厨具,能处理的鱼的极限还是一斤。

    + +

    不过鲈鱼的肉真肥美。隔天看闪光感冒,想想也没办法做豆瓣鱼,就拿来煮汤了。

    + +
    + +
    + +
    + +
    +
    12.4.’13. 9:06pm.
    + +

    UL 性转 3

    + +
    +UL 性转 3 +
    + +

    第一次买同人志,九号机UL 性转 3

    + +

    最早是被九号机的噗迷上的,那时候第一次知道什么是性转,开始疯狂寻找相关的性转作品,甚至开始玩 Unlight

    + +

    前两天看到九号机要出 UL 性转 4 了,顺著找到懒洋洋卖场,看到 UL 性转 3 还有,赶快买下来!

    + +
    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 188 | + 189 | + 190 | + 191 | + 192 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0190.html.zh-tw.html b/htdocs/imacat/me/diary/0190.html.zh-tw.html new file mode 120000 index 0000000..8cbb030 --- /dev/null +++ b/htdocs/imacat/me/diary/0190.html.zh-tw.html @@ -0,0 +1 @@ +0190.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0190.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0190.html.zh-tw.xhtml new file mode 100644 index 0000000..61c90b6 --- /dev/null +++ b/htdocs/imacat/me/diary/0190.html.zh-tw.xhtml @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百九十 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百九十

    + +
    + +
    + +
    +
    12.14.’13. 1:41pm.
    + +

    Bard’s Tale

    + +

    差不多去年這個時候,買的 Bard’s Tale 。可是檔案太大,趁特價買下來後,就先刪了。這兩天清空手機舊 App 後,再挖出來玩了一下。

    + +

    嗯,還是不大好玩。

    + +
      +
    1. 不知道為什麼要用 3D 。其實根本無法調整到平行視角,只能由正上方俯視,看不到畫面細節,還常常因為可旋轉的方向,弄到方位錯亂。 2D 斜上 45 度地圖視角就好了啊,簡單好操作!
    2. + +
    3. 不知道為什麼要用模擬搖桿移動,難用得半死。為什麼不加上自動尋路系統呢?
    4. + +
    5. 對話語音、字幕太快。這是考我英聽還是英讀?不管是哪個都遠超過我的速度了!
    6. +
    + +

    不過全語音是很棒,對話也非常有趣。

    + +

    就這樣,一個不知道玩不玩得完的遊戲。玩得好累!

    + +
    + +
    + +
    +
    12.5.’13. 0:16am.
    + +

    多人家庭

    + +

    想再講清楚多人家庭。

    + +

    這是一個簡單又清楚的多人家庭例子。我不知道為什麼保守團體把多人家庭當成亂源。事實上,很多人應該都有經驗過,跟幾個單身的好友、姊妹們,約好老了沒伴的話,就一起住,就算不去養老院,也有個照應。這也是多人家庭。

    + +

    事實上,老人照養設施,也是多人家庭。許多沒有血緣的老人,就算戶籍不在一起,他們也實質地在一起生活,實質地組成家庭,直到終老。他們沒有跟原生家庭在一起生活,而是跟養老院的同伴、照護們一起生活,組成家庭。

    + +

    我們的社會,到處都是多人家庭。多人家庭,真的是那麼怪異、混亂的一件事嗎?

    + +
    + +
    + +
    + +
    +
    12.4.’13. 9:50pm.
    + +

    鱸魚

    + +
    +失敗的鱸魚 +
    + +

    想做豆瓣魚,依著食譜,到新生市場想買鯉魚。可是沒有鯉魚好買,問老闆有什麼可以替代,老闆推薦鱸魚。從來沒買過鱸魚這麼好的魚。捨不得買太貴,挑了兩隻最小的。每隻稱重超過一斤,正好食譜也寫要一斤四兩左右。

    + +

    算來兩隻將近兩百九,老闆算兩百伍給我。等老闆娘處理魚的時候,聽其他客人和老闆閒聊,才知道老闆家前晚女兒訂婚。算來將近八五折,算是賺到了。

    + +

    買回來做豆瓣魚,結果大失敗。鱸魚魚皮魚肉太軟,根本禁不起翻炸煮,而且一斤多果然太大了,炒鍋快放不下。我們家的家用廚具,能處理的魚的極限還是一斤。

    + +

    不過鱸魚的肉真肥美。隔天看閃光感冒,想想也沒辦法做豆瓣魚,就拿來煮湯了。

    + +
    + +
    + +
    + +
    +
    12.4.’13. 9:06pm.
    + +

    UL 性轉 3

    + +
    +UL 性轉 3 +
    + +

    第一次買同人誌,九號機UL 性轉 3

    + +

    最早是被九號機的噗迷上的,那時候第一次知道什麼是性轉,開始瘋狂尋找相關的性轉作品,甚至開始玩 Unlight

    + +

    前兩天看到九號機要出 UL 性轉 4 了,順著找到懶洋洋賣場,看到 UL 性轉 3 還有,趕快買下來!

    + +
    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 188 | + 189 | + 190 | + 191 | + 192 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0191.html.en.html b/htdocs/imacat/me/diary/0191.html.en.html new file mode 120000 index 0000000..971f8ec --- /dev/null +++ b/htdocs/imacat/me/diary/0191.html.en.html @@ -0,0 +1 @@ +0191.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0191.html.en.xhtml b/htdocs/imacat/me/diary/0191.html.en.xhtml new file mode 100644 index 0000000..6d10853 --- /dev/null +++ b/htdocs/imacat/me/diary/0191.html.en.xhtml @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 191 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 191

    + +
    + +
    + +
    +
    12.27.’13. 10:55pm.
    + +

    瑪琪琳很難吃

    + +

    小時候,奶奶用瑪琪琳(人造植物奶油)代替奶油,抹吐司或烹調。奶奶說,瑪琪琳比較健康。奶油在常溫下不易化開,所以不好抹吐司,但是瑪琪淋常溫下軟軟的,就很好抹。雖然跟著奶奶吃瑪琪琳,但是心裏一直想著,想吃吃原味天然奶油。

    + +

    長大自己住以後,要做奶奶教的黃飯,會用到奶油。我開始買原味天然奶油。除了做黃飯外,最近早餐開始吃吐司,我也開始拿來抹吐司。不過奶油在常溫下不易化開,不好抹吐司,所以會先切小塊放麵包上,再去煎烤。

    + +

    前一陣子大統油品出問題,有一位高中理化老師在 PTT 寫了一篇Re: [問卦] 安全的食用油要在哪買?,讀了以後,瞭解動物油不好的原因,是在常溫下不容易化開,所以會堆積在心血管壁上。想想,還是乖乖回頭買瑪琪琳。

    + +

    可是吃慣了奶油,改回吃瑪琪琳,味道差好多。怎麼煎煮加熱都不香,食之無味。

    + +

    後來問淡江化學的吳嘉麗老師,吳嘉麗老師提醒血管內的溫度是體溫 37.5 度,不是常溫,就算是動物性油脂,在 37.5 度下也化開了。嗯啊,想想還真蠢。

    + +

    剛剛看維基百科,原來瑪琪琳製程容易產生大量反式脂肪。閃光也說,人造的加工過程,怎麼可能比天然的健康?

    + +

    想想,等這盒瑪琪琳吃完後,回頭買原味天然奶油好了。

    + +
    + +
    + +
    +
    12.21.’13. 0:50am.
    + +

    關於郭美江牧師的看法

    + +

    我看郭美江牧師的講道,不會覺得太可笑。這幾天,我反省了一下為什麼。

    + +

    我一直相信心理學上的比馬龍效應:當你相信一件事為真的時候,你的行為、舉動,都會不自覺傾向有助於該事情的方向,到最後,因為一切條件都預備好了,事情自然就會實現了。我以前仰慕的學姊的形象,多年以後恍然大悟,我自己在不知不覺中,成為了那個樣子。我希望自己能夠擁有的心境,多年以後,不知不覺間,已經擁有了。

    + +

    這是預言的自我實現性:預言有一股潛在的力量,會讓事情實現。這其實是心理作用,但力量很大。

    + +

    我覺得宗教的最大力量,就是提供心靈上的信心,促成比馬龍效應,讓個人達成個人希望的生命目標。這個效應的結果,大多數狀況都是好的。因此,我一直對宗教信仰,持審慎樂觀的態度,只要不對傷害現實生活,即使不合乎所謂的科學標準,也沒什麼不好。

    + +

    只是我對自己的力量有信心,目前不需要這樣的力量。

    + +

    所以,還好耶。郭美江牧師的講道、斬劍等等,其實就是儀式性的心理暗示。這種儀式性的心理暗示力量當然很強大,但是也不是很罕見的邪教作為。在佛教、天主教、基督教、台灣民間宗教的儀式、唸經唸法咒中,其實都很常見。覺得這些儀式很可笑的人,乩童、鯊魚劍、三太子,有比較好嗎?

    + +

    不過,雖然我覺得郭美江牧師的講道還好,可是內容中強烈的岐視和敵意,就無法視而不見了。

    + +
    + +
    + +
    +
    12.21.’13. 0:28am.
    + +

    統一教

    + +

    昨晚小花在分享時提到,以前統一教常常在台大門口拉人,我都不知道。

    + +

    仔細想想,其實是有,的確常常在校門口碰到統一教拉人。那為什麼我後來都沒有印象呢?

    + +

    是因為我在表面上的友善臉孔下,其實很冷漠嗎?

    + +
    + +
    + +
    +
    12.21.’13. 0:18am.
    + +

    青少年純潔運動協會

    + +

    原來青少年純潔運動協會,背後是統一教。我一直以為是基督教還是天主教,勵馨還是善牧的相關團體。

    + +

    青少年純潔運動協會,光看名字我就很討厭。我一直很討厭弱智化、無力化青少女/青少年的行動,好像小孩子都是白癡,什麼都不能給他們碰,然後到十八歲生日過後,他們就會一聲什麼都懂了。

    + +

    青少女/青少年在性成熟階段,本來就在摸索的年紀,就算什麼都不給他們看,他們還是會自己偷偷去看去碰去試。不看不聽不說,只是滿足大人自己的純潔想像而已,想說這樣青少女/青少年就會保持純潔,完全是大人一廂情願的癡心妄想。

    + +

    因為大人不看不聽不說,青少女/青少年對性的知識和想像,只能從地下管道取得,不正確不安全的性知識,反而陷青少女/青少年於懷孕、性病、暴力性行為的危險之中。

    + +

    這樣不看不聽不說長大的青少女/青少年,能夠有正確安全的性知識嗎?只會生產出下一代害怕性的大人而已。

    + +

    而這樣沒有安全性知識,只能自己偷偷探索的青少女/青少年,一但出事了,陷於危險的,往往是女生,而不是男生。

    + +
    + +
    + +
    +
    12.20.’13. 3:46pm.
    + +

    傳明酸、玻尿酸和保養品

    + +

    幾年前聽研究 STS 的閃光說,保養品貴的和便宜的,其實沒有什麼差別。

    + +

    這一陣子年紀大了,桌上瓶瓶罐罐多了。拿著標示的成份上網查,其實不外乎像傳明酸是衛生署唯一核可的美白成份,玻尿酸是保水分子等等。其實保養品原料也就這麼幾樣,濃度上限也有規定。那像 SKⅡ 什麼幾千塊的東西,和森田藥妝、開架保養品,真的沒有什麼差別。

    + +

    不知道專櫃在貴什麼。昨晚回去路上和 Sylvia 聊,大概是貴在專櫃服務的貴婦感吧。

    + +
    + +
    + +
    +
    12.20.’13. 3:29pm.
    + +

    動物油與植物油的謠言

    + +

    前一陣子看了這篇Re: [問卦] 安全的食用油要在哪買?,看完的心得:原來動物油不好的原因是這樣:動物油在常溫下會凝結成固態,所以會留在血管壁上,阻塞血管。

    + +

    上星期六女科技人學會聚餐,和淡江化學系吳嘉麗老師吃飯,問到她這個問題,她回答,人的體溫是 37.5 度,在這個溫度下,大多數的動物性脂肪都液化了,不會凝結在血管壁上。原來被騙了。

    + +

    只是動物性油脂是含有較多不飽合脂肪酸,容易生成膽固醇。不過膽固醇本來就是人體活動所必需,不是不好的東西。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 189 | + 190 | + 191 | + 192 | + 193 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0191.html.zh-cn.html b/htdocs/imacat/me/diary/0191.html.zh-cn.html new file mode 120000 index 0000000..93a9225 --- /dev/null +++ b/htdocs/imacat/me/diary/0191.html.zh-cn.html @@ -0,0 +1 @@ +0191.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0191.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0191.html.zh-cn.xhtml new file mode 100644 index 0000000..34cfdf0 --- /dev/null +++ b/htdocs/imacat/me/diary/0191.html.zh-cn.xhtml @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百九十一 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百九十一

    + +
    + +
    + +
    +
    12.27.’13. 10:55pm.
    + +

    玛琪琳很难吃

    + +

    小时候,奶奶用玛琪琳(人造植物奶油)代替奶油,抹吐司或烹调。奶奶说,玛琪琳比较健康。奶油在常温下不易化开,所以不好抹吐司,但是玛琪淋常温下软软的,就很好抹。虽然跟著奶奶吃玛琪琳,但是心里一直想著,想吃吃原味天然奶油。

    + +

    长大自己住以后,要做奶奶教的黄饭,会用到奶油。我开始买原味天然奶油。除了做黄饭外,最近早餐开始吃吐司,我也开始拿来抹吐司。不过奶油在常温下不易化开,不好抹吐司,所以会先切小块放面包上,再去煎烤。

    + +

    前一阵子大统油品出问题,有一位高中理化老师在 PTT 写了一篇Re: [问卦] 安全的食用油要在哪买?,读了以后,了解动物油不好的原因,是在常温下不容易化开,所以会堆积在心血管壁上。想想,还是乖乖回头买玛琪琳。

    + +

    可是吃惯了奶油,改回吃玛琪琳,味道差好多。怎么煎煮加热都不香,食之无味。

    + +

    后来问淡江化学的吴嘉丽老师,吴嘉丽老师提醒血管内的温度是体温 37.5 度,不是常温,就算是动物性油脂,在 37.5 度下也化开了。嗯啊,想想还真蠢。

    + +

    刚刚看维基百科,原来玛琪琳制程容易产生大量反式脂肪。闪光也说,人造的加工过程,怎么可能比天然的健康?

    + +

    想想,等这盒玛琪琳吃完后,回头买原味天然奶油好了。

    + +
    + +
    + +
    +
    12.21.’13. 0:50am.
    + +

    关於郭美江牧师的看法

    + +

    我看郭美江牧师的讲道,不会觉得太可笑。这几天,我反省了一下为什么。

    + +

    我一直相信心理学上的比马龙效应:当你相信一件事为真的时候,你的行为、举动,都会不自觉倾向有助於该事情的方向,到最后,因为一切条件都预备好了,事情自然就会实现了。我以前仰慕的学姊的形象,多年以后恍然大悟,我自己在不知不觉中,成为了那个样子。我希望自己能够拥有的心境,多年以后,不知不觉间,已经拥有了。

    + +

    这是预言的自我实现性:预言有一股潜在的力量,会让事情实现。这其实是心理作用,但力量很大。

    + +

    我觉得宗教的最大力量,就是提供心灵上的信心,促成比马龙效应,让个人达成个人希望的生命目标。这个效应的结果,大多数状况都是好的。因此,我一直对宗教信仰,持审慎乐观的态度,只要不对伤害现实生活,即使不合乎所谓的科学标准,也没什么不好。

    + +

    只是我对自己的力量有信心,目前不需要这样的力量。

    + +

    所以,还好耶。郭美江牧师的讲道、斩剑等等,其实就是仪式性的心理暗示。这种仪式性的心理暗示力量当然很强大,但是也不是很罕见的邪教作为。在佛教、天主教、基督教、台湾民间宗教的仪式、念经念法咒中,其实都很常见。觉得这些仪式很可笑的人,乩童、鲨鱼剑、三太子,有比较好吗?

    + +

    不过,虽然我觉得郭美江牧师的讲道还好,可是内容中强烈的岐视和敌意,就无法视而不见了。

    + +
    + +
    + +
    +
    12.21.’13. 0:28am.
    + +

    统一教

    + +

    昨晚小花在分享时提到,以前统一教常常在台大门口拉人,我都不知道。

    + +

    仔细想想,其实是有,的确常常在校门口碰到统一教拉人。那为什么我后来都没有印象呢?

    + +

    是因为我在表面上的友善脸孔下,其实很冷漠吗?

    + +
    + +
    + +
    +
    12.21.’13. 0:18am.
    + +

    青少年纯洁运动协会

    + +

    原来青少年纯洁运动协会,背后是统一教。我一直以为是基督教还是天主教,励馨还是善牧的相关团体。

    + +

    青少年纯洁运动协会,光看名字我就很讨厌。我一直很讨厌弱智化、无力化青少女/青少年的行动,好像小孩子都是白痴,什么都不能给他们碰,然后到十八岁生日过后,他们就会一声什么都懂了。

    + +

    青少女/青少年在性成熟阶段,本来就在摸索的年纪,就算什么都不给他们看,他们还是会自己偷偷去看去碰去试。不看不听不说,只是满足大人自己的纯洁想像而已,想说这样青少女/青少年就会保持纯洁,完全是大人一厢情愿的痴心妄想。

    + +

    因为大人不看不听不说,青少女/青少年对性的知识和想像,只能从地下管道取得,不正确不安全的性知识,反而陷青少女/青少年於怀孕、性病、暴力性行为的危险之中。

    + +

    这样不看不听不说长大的青少女/青少年,能够有正确安全的性知识吗?只会生产出下一代害怕性的大人而已。

    + +

    而这样没有安全性知识,只能自己偷偷探索的青少女/青少年,一但出事了,陷於危险的,往往是女生,而不是男生。

    + +
    + +
    + +
    +
    12.20.’13. 3:46pm.
    + +

    传明酸、玻尿酸和保养品

    + +

    几年前听研究 STS 的闪光说,保养品贵的和便宜的,其实没有什么差别。

    + +

    这一阵子年纪大了,桌上瓶瓶罐罐多了。拿著标示的成份上网查,其实不外乎像传明酸是卫生署唯一核可的美白成份,玻尿酸是保水分子等等。其实保养品原料也就这么几样,浓度上限也有规定。那像 SKⅡ 什么几千块的东西,和森田药妆、开架保养品,真的没有什么差别。

    + +

    不知道专柜在贵什么。昨晚回去路上和 Sylvia 聊,大概是贵在专柜服务的贵妇感吧。

    + +
    + +
    + +
    +
    12.20.’13. 3:29pm.
    + +

    动物油与植物油的谣言

    + +

    前一阵子看了这篇Re: [问卦] 安全的食用油要在哪买?,看完的心得:原来动物油不好的原因是这样:动物油在常温下会凝结成固态,所以会留在血管壁上,阻塞血管。

    + +

    上星期六女科技人学会聚餐,和淡江化学系吴嘉丽老师吃饭,问到她这个问题,她回答,人的体温是 37.5 度,在这个温度下,大多数的动物性脂肪都液化了,不会凝结在血管壁上。原来被骗了。

    + +

    只是动物性油脂是含有较多不饱合脂肪酸,容易生成胆固醇。不过胆固醇本来就是人体活动所必需,不是不好的东西。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 189 | + 190 | + 191 | + 192 | + 193 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0191.html.zh-tw.html b/htdocs/imacat/me/diary/0191.html.zh-tw.html new file mode 120000 index 0000000..28dc715 --- /dev/null +++ b/htdocs/imacat/me/diary/0191.html.zh-tw.html @@ -0,0 +1 @@ +0191.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0191.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0191.html.zh-tw.xhtml new file mode 100644 index 0000000..4be1a37 --- /dev/null +++ b/htdocs/imacat/me/diary/0191.html.zh-tw.xhtml @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百九十一 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百九十一

    + +
    + +
    + +
    +
    12.27.’13. 10:55pm.
    + +

    瑪琪琳很難吃

    + +

    小時候,奶奶用瑪琪琳(人造植物奶油)代替奶油,抹吐司或烹調。奶奶說,瑪琪琳比較健康。奶油在常溫下不易化開,所以不好抹吐司,但是瑪琪淋常溫下軟軟的,就很好抹。雖然跟著奶奶吃瑪琪琳,但是心裏一直想著,想吃吃原味天然奶油。

    + +

    長大自己住以後,要做奶奶教的黃飯,會用到奶油。我開始買原味天然奶油。除了做黃飯外,最近早餐開始吃吐司,我也開始拿來抹吐司。不過奶油在常溫下不易化開,不好抹吐司,所以會先切小塊放麵包上,再去煎烤。

    + +

    前一陣子大統油品出問題,有一位高中理化老師在 PTT 寫了一篇Re: [問卦] 安全的食用油要在哪買?,讀了以後,瞭解動物油不好的原因,是在常溫下不容易化開,所以會堆積在心血管壁上。想想,還是乖乖回頭買瑪琪琳。

    + +

    可是吃慣了奶油,改回吃瑪琪琳,味道差好多。怎麼煎煮加熱都不香,食之無味。

    + +

    後來問淡江化學的吳嘉麗老師,吳嘉麗老師提醒血管內的溫度是體溫 37.5 度,不是常溫,就算是動物性油脂,在 37.5 度下也化開了。嗯啊,想想還真蠢。

    + +

    剛剛看維基百科,原來瑪琪琳製程容易產生大量反式脂肪。閃光也說,人造的加工過程,怎麼可能比天然的健康?

    + +

    想想,等這盒瑪琪琳吃完後,回頭買原味天然奶油好了。

    + +
    + +
    + +
    +
    12.21.’13. 0:50am.
    + +

    關於郭美江牧師的看法

    + +

    我看郭美江牧師的講道,不會覺得太可笑。這幾天,我反省了一下為什麼。

    + +

    我一直相信心理學上的比馬龍效應:當你相信一件事為真的時候,你的行為、舉動,都會不自覺傾向有助於該事情的方向,到最後,因為一切條件都預備好了,事情自然就會實現了。我以前仰慕的學姊的形象,多年以後恍然大悟,我自己在不知不覺中,成為了那個樣子。我希望自己能夠擁有的心境,多年以後,不知不覺間,已經擁有了。

    + +

    這是預言的自我實現性:預言有一股潛在的力量,會讓事情實現。這其實是心理作用,但力量很大。

    + +

    我覺得宗教的最大力量,就是提供心靈上的信心,促成比馬龍效應,讓個人達成個人希望的生命目標。這個效應的結果,大多數狀況都是好的。因此,我一直對宗教信仰,持審慎樂觀的態度,只要不對傷害現實生活,即使不合乎所謂的科學標準,也沒什麼不好。

    + +

    只是我對自己的力量有信心,目前不需要這樣的力量。

    + +

    所以,還好耶。郭美江牧師的講道、斬劍等等,其實就是儀式性的心理暗示。這種儀式性的心理暗示力量當然很強大,但是也不是很罕見的邪教作為。在佛教、天主教、基督教、台灣民間宗教的儀式、唸經唸法咒中,其實都很常見。覺得這些儀式很可笑的人,乩童、鯊魚劍、三太子,有比較好嗎?

    + +

    不過,雖然我覺得郭美江牧師的講道還好,可是內容中強烈的岐視和敵意,就無法視而不見了。

    + +
    + +
    + +
    +
    12.21.’13. 0:28am.
    + +

    統一教

    + +

    昨晚小花在分享時提到,以前統一教常常在台大門口拉人,我都不知道。

    + +

    仔細想想,其實是有,的確常常在校門口碰到統一教拉人。那為什麼我後來都沒有印象呢?

    + +

    是因為我在表面上的友善臉孔下,其實很冷漠嗎?

    + +
    + +
    + +
    +
    12.21.’13. 0:18am.
    + +

    青少年純潔運動協會

    + +

    原來青少年純潔運動協會,背後是統一教。我一直以為是基督教還是天主教,勵馨還是善牧的相關團體。

    + +

    青少年純潔運動協會,光看名字我就很討厭。我一直很討厭弱智化、無力化青少女/青少年的行動,好像小孩子都是白癡,什麼都不能給他們碰,然後到十八歲生日過後,他們就會一聲什麼都懂了。

    + +

    青少女/青少年在性成熟階段,本來就在摸索的年紀,就算什麼都不給他們看,他們還是會自己偷偷去看去碰去試。不看不聽不說,只是滿足大人自己的純潔想像而已,想說這樣青少女/青少年就會保持純潔,完全是大人一廂情願的癡心妄想。

    + +

    因為大人不看不聽不說,青少女/青少年對性的知識和想像,只能從地下管道取得,不正確不安全的性知識,反而陷青少女/青少年於懷孕、性病、暴力性行為的危險之中。

    + +

    這樣不看不聽不說長大的青少女/青少年,能夠有正確安全的性知識嗎?只會生產出下一代害怕性的大人而已。

    + +

    而這樣沒有安全性知識,只能自己偷偷探索的青少女/青少年,一但出事了,陷於危險的,往往是女生,而不是男生。

    + +
    + +
    + +
    +
    12.20.’13. 3:46pm.
    + +

    傳明酸、玻尿酸和保養品

    + +

    幾年前聽研究 STS 的閃光說,保養品貴的和便宜的,其實沒有什麼差別。

    + +

    這一陣子年紀大了,桌上瓶瓶罐罐多了。拿著標示的成份上網查,其實不外乎像傳明酸是衛生署唯一核可的美白成份,玻尿酸是保水分子等等。其實保養品原料也就這麼幾樣,濃度上限也有規定。那像 SKⅡ 什麼幾千塊的東西,和森田藥妝、開架保養品,真的沒有什麼差別。

    + +

    不知道專櫃在貴什麼。昨晚回去路上和 Sylvia 聊,大概是貴在專櫃服務的貴婦感吧。

    + +
    + +
    + +
    +
    12.20.’13. 3:29pm.
    + +

    動物油與植物油的謠言

    + +

    前一陣子看了這篇Re: [問卦] 安全的食用油要在哪買?,看完的心得:原來動物油不好的原因是這樣:動物油在常溫下會凝結成固態,所以會留在血管壁上,阻塞血管。

    + +

    上星期六女科技人學會聚餐,和淡江化學系吳嘉麗老師吃飯,問到她這個問題,她回答,人的體溫是 37.5 度,在這個溫度下,大多數的動物性脂肪都液化了,不會凝結在血管壁上。原來被騙了。

    + +

    只是動物性油脂是含有較多不飽合脂肪酸,容易生成膽固醇。不過膽固醇本來就是人體活動所必需,不是不好的東西。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 189 | + 190 | + 191 | + 192 | + 193 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0192.html.en.html b/htdocs/imacat/me/diary/0192.html.en.html new file mode 120000 index 0000000..13c5737 --- /dev/null +++ b/htdocs/imacat/me/diary/0192.html.en.html @@ -0,0 +1 @@ +0192.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0192.html.en.xhtml b/htdocs/imacat/me/diary/0192.html.en.xhtml new file mode 100644 index 0000000..4b93ca3 --- /dev/null +++ b/htdocs/imacat/me/diary/0192.html.en.xhtml @@ -0,0 +1,241 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 192 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 192

    + +
    + +
    + +
    +
    1.2.’14. 2:10am.
    + +

    公民不服從跨年夜的市長候選人

    + +

    廢核行腳-公民不服從跨年夜的現場,來了兩黨加無黨,三位台北市長候選人:一開始就坐著的民進黨顧立雄,黑手那卡西的時候進來的無黨柯文哲,以及趁柯文哲進場騷動時,偷偷進來坐在旁邊的國民黨丁守中。

    + +

    三位台北市長候選人,不去最熱鬧的台北市政府跨年晚會,反而跑來只有一兩百人的公民不服從跨年夜。不過也是啦,台北市政府跨年晚會,除了台北市長外,別的政客也進不去。

    + +

    只是這些政客選前反核,等到選上了,又是另外一回事了。

    + +

    三個人中,只有丁守中有立委公職,之前投過票續建核四,現場大談他在德國綠黨的反核經驗,這樣也來反核,頗為不要臉。

    + +

    回來讀了新聞才知道,柯文哲在現場接受媒體採訪,從事後新聞看來他其實不反核,不反核也敢來,也很不要臉。

    + +
    + +
    + +
    +
    12.28.’13. 1:41am.
    + +

    范可欽與全人類的財產

    + +

    范可欽說霍夫曼至少收取一千萬元權利金,這不是商業化,什麼才是商業化?黃色小鴨屬於全人類財產,不屬於霍夫曼一個人!

    + +

    聽起來是很像自由軟體和開放著作權的理念啦,不過由范可欽的嘴吧說出來,就像是黃色小鴨是全人類的財產,全人類的財產就是我的財產。的感覺,超不要臉超噁爛的!

    + +
    + +
    + +
    +
    12.28.’13. 0:59am.
    + +

    自由市場與基進草根民主

    + +

    在古典經濟學理論中,每個人都追求自身的最佳利益,集合起來就會形成公眾的最佳利益,這就是自由市場。

    + +

    古典經濟學理論有很多漏洞。最近散步的時候想到,古典經濟學的前提是,每個人干涉市場的權力均等,互相制衡。然而資本是經濟權力的來源,資本主義追求擴大資本規模效益極大化。當市場上出現中大型資本,每個人干涉市場的權力均等的前提就消失了。到最後剩下少數大型資本壟斷市場,資本家的經濟權力大到可比政府干涉市場的黑手,可以制定沒有彈性的價格,不受市場左右。這和古典經濟學反對的干涉市場的政府黑手,有什麼差別?

    + +

    要維持自由市場,只能不斷打擊、防止大型資本的出現,維持市場由中小企業組成。這又違反資本主義追求的規模經濟效益極大化。

    + +

    這和政治民主的運作,有一些近似處。每個人的選票權力均等,是民主的基本原則。然而為了增加政治影響力,公民會結合成政治團體,來增加干涉政治的力量。到最後,政治被少數大型政黨把持。要實現基進草根民主,只能不斷對抗這些綁架民主的政黨。

    + +

    徹底的自由市場,和基進草根民主,是不是很像的東西呢?

    + +
    + +
    + +
    +
    12.28.’13. 0:21am.
    + +

    民意與代議民主政治

    + +

    即使主流民意再怎麼支持同性婚姻(TVBS中時中研院),政客們仍然選擇跟少數極端宗教團體站在一起(參加11/30遊行的縣市長們)。

    + +

    民主政治理論上,政治人物為了選票,會跟多數民意站在一起。但是實際運作時,政客、公共事務往往被少數既得利益團體綁架、把持。所以即使台灣人不想統一,國民黨還是捧著台灣去賣給中國;即使台灣人不想要核電,政客還是死也要蓋下去;即使台灣人多數支持同志婚姻,政客還是去給反同婚的遊行站台。

    + +

    所以公民投票是重要的事,跨越被綁架的代議民主,實現真正的公民民主政治。

    + +
    + +
    + +
    +
    12.27.’13. 11:45pm.
    + +

    捐款

    + +

    趕在年底前,捐款給維基百科Internet Archive 。從前兩年開始捐款給維基百科,今年加上 Internet Archive 。希望每年,都能多少捐一點,回饋給他們。

    + +
    + +
    + +
    +
    12.27.’13. 11:32pm.
    + +

    Internet Archive

    + +

    Internet Archive 現在捐款贊助,有四倍的祝福耶! ♥♥♥

    + +

    在匿名贊助者幫忙下,在 2014 年前,每個人每捐款贊助一塊錢,匿名贊助者會多捐三倍,總共四元。希望網路資訊不要隨時間流逝的人,快一起來贊助吧!

    + +

    今年整理舊連結,因為網路新聞連結大量失效,開始大量使用 Internet Archive 。除了蘋果、自由這兩家永不撤新聞的網站外,像聯合、中時、新頭殼的新聞,轉貼時,都會順手備份到 Internet Archive 。用這麼多,捐點錢贊助也是應該的。 ^_*'

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 190 | + 191 | + 192 | + 193 | + 194 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0192.html.zh-cn.html b/htdocs/imacat/me/diary/0192.html.zh-cn.html new file mode 120000 index 0000000..fe4c5fd --- /dev/null +++ b/htdocs/imacat/me/diary/0192.html.zh-cn.html @@ -0,0 +1 @@ +0192.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0192.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0192.html.zh-cn.xhtml new file mode 100644 index 0000000..0b21974 --- /dev/null +++ b/htdocs/imacat/me/diary/0192.html.zh-cn.xhtml @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百九十二 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百九十二

    + +
    + +
    + +
    +
    1.2.’14. 2:10am.
    + +

    公民不服从跨年夜的市长候选人

    + +

    废核行脚-公民不服从跨年夜的现场,来了两党加无党,三位台北市长候选人:一开始就坐著的民进党顾立雄,黑手那卡西的时候进来的无党柯文哲,以及趁柯文哲进场骚动时,偷偷进来坐在旁边的国民党丁守中。

    + +

    三位台北市长候选人,不去最热闹的台北市政府跨年晚会,反而跑来只有一两百人的公民不服从跨年夜。不过也是啦,台北市政府跨年晚会,除了台北市长外,别的政客也进不去。

    + +

    只是这些政客选前反核,等到选上了,又是另外一回事了。

    + +

    三个人中,只有丁守中有立委公职,之前投过票续建核四,现场大谈他在德国绿党的反核经验,这样也来反核,颇为不要脸。

    + +

    回来读了新闻才知道,柯文哲在现场接受媒体采访,从事后新闻看来他其实不反核,不反核也敢来,也很不要脸。

    + +
    + +
    + +
    +
    12.28.’13. 1:41am.
    + +

    范可钦与全人类的财产

    + +

    范可钦说霍夫曼至少收取一千万元权利金,这不是商业化,什么才是商业化?黄色小鸭属於全人类财产,不属於霍夫曼一个人!

    + +

    听起来是很像自由软体和开放著作权的理念啦,不过由范可钦的嘴吧说出来,就像是黄色小鸭是全人类的财产,全人类的财产就是我的财产。的感觉,超不要脸超恶烂的!

    + +
    + +
    + +
    +
    12.28.’13. 0:59am.
    + +

    自由市场与基进草根民主

    + +

    在古典经济学理论中,每个人都追求自身的最佳利益,集合起来就会形成公众的最佳利益,这就是自由市场。

    + +

    古典经济学理论有很多漏洞。最近散步的时候想到,古典经济学的前提是,每个人干涉市场的权力均等,互相制衡。然而资本是经济权力的来源,资本主义追求扩大资本规模效益极大化。当市场上出现中大型资本,每个人干涉市场的权力均等的前提就消失了。到最后剩下少数大型资本垄断市场,资本家的经济权力大到可比政府干涉市场的黑手,可以制定没有弹性的价格,不受市场左右。这和古典经济学反对的干涉市场的政府黑手,有什么差别?

    + +

    要维持自由市场,只能不断打击、防止大型资本的出现,维持市场由中小企业组成。这又违反资本主义追求的规模经济效益极大化。

    + +

    这和政治民主的运作,有一些近似处。每个人的选票权力均等,是民主的基本原则。然而为了增加政治影响力,公民会结合成政治团体,来增加干涉政治的力量。到最后,政治被少数大型政党把持。要实现基进草根民主,只能不断对抗这些绑架民主的政党。

    + +

    彻底的自由市场,和基进草根民主,是不是很像的东西呢?

    + +
    + +
    + +
    +
    12.28.’13. 0:21am.
    + +

    民意与代议民主政治

    + +

    即使主流民意再怎么支持同性婚姻(TVBS中时中研院),政客们仍然选择跟少数极端宗教团体站在一起(参加11/30游行的县市长们)。

    + +

    民主政治理论上,政治人物为了选票,会跟多数民意站在一起。但是实际运作时,政客、公共事务往往被少数既得利益团体绑架、把持。所以即使台湾人不想统一,国民党还是捧著台湾去卖给中国;即使台湾人不想要核电,政客还是死也要盖下去;即使台湾人多数支持同志婚姻,政客还是去给反同婚的游行站台。

    + +

    所以公民投票是重要的事,跨越被绑架的代议民主,实现真正的公民民主政治。

    + +
    + +
    + +
    +
    12.27.’13. 11:45pm.
    + +

    捐款

    + +

    赶在年底前,捐款给维基百科Internet Archive 。从前两年开始捐款给维基百科,今年加上 Internet Archive 。希望每年,都能多少捐一点,回馈给他们。

    + +
    + +
    + +
    +
    12.27.’13. 11:32pm.
    + +

    Internet Archive

    + +

    Internet Archive 现在捐款赞助,有四倍的祝福耶! ♥♥♥

    + +

    在匿名赞助者帮忙下,在 2014 年前,每个人每捐款赞助一块钱,匿名赞助者会多捐三倍,总共四元。希望网路资讯不要随时间流逝的人,快一起来赞助吧!

    + +

    今年整理旧连结,因为网路新闻连结大量失效,开始大量使用 Internet Archive 。除了苹果、自由这两家永不撤新闻的网站外,像联合、中时、新头壳的新闻,转贴时,都会顺手备份到 Internet Archive 。用这么多,捐点钱赞助也是应该的。 ^_*'

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 190 | + 191 | + 192 | + 193 | + 194 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0192.html.zh-tw.html b/htdocs/imacat/me/diary/0192.html.zh-tw.html new file mode 120000 index 0000000..12d6d76 --- /dev/null +++ b/htdocs/imacat/me/diary/0192.html.zh-tw.html @@ -0,0 +1 @@ +0192.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0192.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0192.html.zh-tw.xhtml new file mode 100644 index 0000000..1038b44 --- /dev/null +++ b/htdocs/imacat/me/diary/0192.html.zh-tw.xhtml @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百九十二 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百九十二

    + +
    + +
    + +
    +
    1.2.’14. 2:10am.
    + +

    公民不服從跨年夜的市長候選人

    + +

    廢核行腳-公民不服從跨年夜的現場,來了兩黨加無黨,三位台北市長候選人:一開始就坐著的民進黨顧立雄,黑手那卡西的時候進來的無黨柯文哲,以及趁柯文哲進場騷動時,偷偷進來坐在旁邊的國民黨丁守中。

    + +

    三位台北市長候選人,不去最熱鬧的台北市政府跨年晚會,反而跑來只有一兩百人的公民不服從跨年夜。不過也是啦,台北市政府跨年晚會,除了台北市長外,別的政客也進不去。

    + +

    只是這些政客選前反核,等到選上了,又是另外一回事了。

    + +

    三個人中,只有丁守中有立委公職,之前投過票續建核四,現場大談他在德國綠黨的反核經驗,這樣也來反核,頗為不要臉。

    + +

    回來讀了新聞才知道,柯文哲在現場接受媒體採訪,從事後新聞看來他其實不反核,不反核也敢來,也很不要臉。

    + +
    + +
    + +
    +
    12.28.’13. 1:41am.
    + +

    范可欽與全人類的財產

    + +

    范可欽說霍夫曼至少收取一千萬元權利金,這不是商業化,什麼才是商業化?黃色小鴨屬於全人類財產,不屬於霍夫曼一個人!

    + +

    聽起來是很像自由軟體和開放著作權的理念啦,不過由范可欽的嘴吧說出來,就像是黃色小鴨是全人類的財產,全人類的財產就是我的財產。的感覺,超不要臉超噁爛的!

    + +
    + +
    + +
    +
    12.28.’13. 0:59am.
    + +

    自由市場與基進草根民主

    + +

    在古典經濟學理論中,每個人都追求自身的最佳利益,集合起來就會形成公眾的最佳利益,這就是自由市場。

    + +

    古典經濟學理論有很多漏洞。最近散步的時候想到,古典經濟學的前提是,每個人干涉市場的權力均等,互相制衡。然而資本是經濟權力的來源,資本主義追求擴大資本規模效益極大化。當市場上出現中大型資本,每個人干涉市場的權力均等的前提就消失了。到最後剩下少數大型資本壟斷市場,資本家的經濟權力大到可比政府干涉市場的黑手,可以制定沒有彈性的價格,不受市場左右。這和古典經濟學反對的干涉市場的政府黑手,有什麼差別?

    + +

    要維持自由市場,只能不斷打擊、防止大型資本的出現,維持市場由中小企業組成。這又違反資本主義追求的規模經濟效益極大化。

    + +

    這和政治民主的運作,有一些近似處。每個人的選票權力均等,是民主的基本原則。然而為了增加政治影響力,公民會結合成政治團體,來增加干涉政治的力量。到最後,政治被少數大型政黨把持。要實現基進草根民主,只能不斷對抗這些綁架民主的政黨。

    + +

    徹底的自由市場,和基進草根民主,是不是很像的東西呢?

    + +
    + +
    + +
    +
    12.28.’13. 0:21am.
    + +

    民意與代議民主政治

    + +

    即使主流民意再怎麼支持同性婚姻(TVBS中時中研院),政客們仍然選擇跟少數極端宗教團體站在一起(參加11/30遊行的縣市長們)。

    + +

    民主政治理論上,政治人物為了選票,會跟多數民意站在一起。但是實際運作時,政客、公共事務往往被少數既得利益團體綁架、把持。所以即使台灣人不想統一,國民黨還是捧著台灣去賣給中國;即使台灣人不想要核電,政客還是死也要蓋下去;即使台灣人多數支持同志婚姻,政客還是去給反同婚的遊行站台。

    + +

    所以公民投票是重要的事,跨越被綁架的代議民主,實現真正的公民民主政治。

    + +
    + +
    + +
    +
    12.27.’13. 11:45pm.
    + +

    捐款

    + +

    趕在年底前,捐款給維基百科Internet Archive 。從前兩年開始捐款給維基百科,今年加上 Internet Archive 。希望每年,都能多少捐一點,回饋給他們。

    + +
    + +
    + +
    +
    12.27.’13. 11:32pm.
    + +

    Internet Archive

    + +

    Internet Archive 現在捐款贊助,有四倍的祝福耶! ♥♥♥

    + +

    在匿名贊助者幫忙下,在 2014 年前,每個人每捐款贊助一塊錢,匿名贊助者會多捐三倍,總共四元。希望網路資訊不要隨時間流逝的人,快一起來贊助吧!

    + +

    今年整理舊連結,因為網路新聞連結大量失效,開始大量使用 Internet Archive 。除了蘋果、自由這兩家永不撤新聞的網站外,像聯合、中時、新頭殼的新聞,轉貼時,都會順手備份到 Internet Archive 。用這麼多,捐點錢贊助也是應該的。 ^_*'

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 190 | + 191 | + 192 | + 193 | + 194 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0193.html.en.html b/htdocs/imacat/me/diary/0193.html.en.html new file mode 120000 index 0000000..f99a9ec --- /dev/null +++ b/htdocs/imacat/me/diary/0193.html.en.html @@ -0,0 +1 @@ +0193.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0193.html.en.xhtml b/htdocs/imacat/me/diary/0193.html.en.xhtml new file mode 100644 index 0000000..4753279 --- /dev/null +++ b/htdocs/imacat/me/diary/0193.html.en.xhtml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 193 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 193

    + +
    + +
    + +
    +
    4.10.’14. 11:36am.
    + +

    太陽花厭惡染黃—回應王顥中一文

    + +

    拜讀王顥中先生 2014/4/7 在苦勞網的苦勞評論「太陽花何懼抹黃?」及高旭寬先生在其後的評論。對於兩人的論點,難以苟同。

    + +

    中天政論節目「新聞龍捲風」的主持人戴立綱與來賓彭華幹,在 2014/4/4 節目中,針對太陽花學運的多張現場照片,以誇張下流不堪的語言及肢體動作,意淫照片中多位女性參與者。節目播出後引起軒然大波,當天網友號召 PTT 鄉民到 NCC 檢舉,導致 NCC 網站被檢舉擠爆,三立記者楊伊湄投書蘋果日報抗議,勵馨基金會、婦女新知基金會相繼發表聲明嚴正抗議,被侮蔑的照片當事人,其中一位關閉臉書,另外一位決定提告。新聞龍捲風製作單位第一時間在臉書上聲明是以「正面字眼稱讚該女」、「非關情色,更非物化」、「稱讚該女,應無不妥」,更威脅要對網友提告。

    + +

    王文提到:「…新聞操作,之所以能夠成為有效打壓學運的手段,其實是仰賴著公共空間排除『性』(包含性活動與性言說)的背景跟『社會共識』…社會文化將『性』看得非常負面。」「當勵馨等婦權團體出面嚴厲譴責中天名嘴時,我看到了『真兇痛批幫凶』這樣的荒謬場景。這些團體向來容不得性異議與各種邊緣偏差…台灣今天之所以會變成這樣一個動輒得咎的性恐慌社會,這些婦權團體絕對必須負起大半責任。」最後歸結「譴責電視台公然意淫女體,…但真正問題還是在於呈現方式,…將『意淫』直接等同於『歧視』,…只是再度把『性』的定義跟詮釋放手交由電視名嘴與既有的社會共識決定。…所有像是雞排妹這樣的主體,也將永遠只能被解釋成為父權結構下的被動受害者,而不是自主自信展現身體的異議不馴者。」高旭寬先生在下面的評論,更指出「因為女人的受害不是那兩個賤嘴小XX搞的,是整個社會要求女人得對自己的身體惜肉如金,不可以沾染情色,要不然就髒掉了,就不值得尊重了!」

    + +

    王文所言「…新聞操作,之所以能夠成為有效打壓學運的手段,其實是仰賴著公共空間排除『性』(包含性活動與性言說)的背景跟『社會共識』」,大體上正確。然而,這樣的論述中,省略掉一個重要的事實:中天新聞龍捲風的新聞操作,雖是以性和情慾為手段來打擊學運,但最終目的並不在性與情慾,而是對運動現場女性參與者的攻擊。性和情慾只是工具手段,不是問題的本身。無視於對女性的惡意,只是一昧把焦點放在性與情慾,是對事實的錯誤理解。純然以性與情慾來解讀事件,和新聞龍捲風節目製作單位所說的以「正面字眼稱讚該女」,有什麼不同?

    + +

    依王文的邏輯,「新聞龍捲風」之所以能攻擊女性,是因為社會對性和情慾的恐懼,只要去除社會對性和情慾的恐懼,就不會受傷了。然而,真的去除社會對性和情慾的恐懼,就不會有性侵、不會有性騷擾了嗎?所以性侵案該處罰的,是規訓身體意識的父母和學校,而不是攻擊的犯人嗎?

    + +

    高旭寬先生的回應,通篇充滿性器官、性行為的粗話,感覺更為粗鄙,更有男性氣概,更清楚展現了傳統沙文男性的社會形象。其背後的邏輯更粗糙、更直接,直接否認了「性攻擊」本身的因果關係,將受害的原因,直接導向女性的自我認知。所以女性被性騷擾、被性侵、被性攻擊,全部都是女人自己在社會規訓之下的被迫害妄想。直接否認掉加害的因果關係,出於一位性別工作者口中,讓人非常錯愕,憤怒與無法理解。

    + +

    這次的太陽花學運,和以往社、學運最大的不同之一,是現場我們看到很多的女性走出來,參與其中。不論是議場守夜、外圍防守、糾察、物資、醫療、法律、工程志工排班、攻佔行政院,及上台演說,都出現了大量的女性身影。大量女性參與者的投入,意謂著抗爭環境對女性越來越友善,女性的社會公民意識越來越清晰,自主性越來越強。反過來說,我們也可以期待大量女性參與者的投入,會帶動抗爭環境對女性更加友善。三立記者楊伊湄的投書,讓我訝異女性主義竟已深入這一代女性的靈魂之中,讓她們在第一時間就能勇敢跳出來反擊。然而,惡質的媒體,在抹黑運動的時候,仍然以最傳統的性來攻擊女參與者。而有著性別盲的傳統運動者同樣無法跳脫同樣的沙文邏輯,只看的到性攻擊裏的性,否認性攻擊的暴力本質,進而否認加害的因果關係,這是非常可悲的。 到頭來,媒體和傳統運動者,看待太陽花的女性運動者,眼中都只有性,別無其他。

    + +

    我們厭惡這種看不到女性被攻擊,只看得到女性的性的邏輯。太陽花不懼染黃,但是太陽花厭惡染黃!

    + +
    + +
    + +
    +
    1.7.’14. 11:34pm.
    + +

    幽麗塔

    + +

    乃木坂太郎幽麗塔好好看! FTM 跨性別、扮裝 CD 和不敢出櫃的男同志的懸疑推理故事。

    + +

    上網查過,原來幽麗塔是二手的改編故事。一開始的原作,是英國小說家 Alice Stuyvesant 在 1898 年寫的小說灰衣婦人 A Woman in Grey 。 1901 年日本小說家、翻譯家黑岩淚香將其翻譯、改寫為幽靈塔 ゆうれいとう Ghost Tower幽麗塔即改寫自黑岩淚香的幽靈塔。此外,江戶川亂步在 1937-1938 年,也改寫了黑岩淚香的幽靈塔。這麼多人改寫,感覺上,幽靈塔/幽麗塔的故事,是一個非常經典的推理小說的架構。

    + +

    幽麗塔不只故事結構,連人物名字,也取自黑岩淚香的幽靈塔幽麗塔中的反派檢查官丸部道九郎,正是黑岩淚香的幽靈塔主角的名字。

    + +

    不過長篇漫畫果然還是很吃力,連載到一半,前面的梗和人物關係,都忘得差不多了。後來上網從頭看,才想起丸部和山科是什麼樣的角色,劇情是如何演進到現在這樣的。原來山科是 Gay ,之前就鋪梗鋪了這麼久!港版已經出到第六集了,台版還在第四集,不知道是怎麼回事。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 191 | + 192 | + 193 | + 194 | + 195 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0193.html.zh-cn.html b/htdocs/imacat/me/diary/0193.html.zh-cn.html new file mode 120000 index 0000000..edea3a9 --- /dev/null +++ b/htdocs/imacat/me/diary/0193.html.zh-cn.html @@ -0,0 +1 @@ +0193.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0193.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0193.html.zh-cn.xhtml new file mode 100644 index 0000000..5e2918c --- /dev/null +++ b/htdocs/imacat/me/diary/0193.html.zh-cn.xhtml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百九十三 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百九十三

    + +
    + +
    + +
    +
    4.10.’14. 11:36am.
    + +

    太阳花厌恶染黄—回应王颢中一文

    + +

    拜读王颢中先生 2014/4/7 在苦劳网的苦劳评论「太阳花何惧抹黄?」及高旭宽先生在其后的评论。对於两人的论点,难以苟同。

    + +

    中天政论节目「新闻龙卷风」的主持人戴立纲与来宾彭华干,在 2014/4/4 节目中,针对太阳花学运的多张现场照片,以夸张下流不堪的语言及肢体动作,意淫照片中多位女性参与者。节目播出后引起轩然大波,当天网友号召 PTT 乡民到 NCC 检举,导致 NCC 网站被检举挤爆,三立记者杨伊湄投书苹果日报抗议,励馨基金会、妇女新知基金会相继发表声明严正抗议,被侮蔑的照片当事人,其中一位关闭脸书,另外一位决定提告。新闻龙卷风制作单位第一时间在脸书上声明是以「正面字眼称赞该女」、「非关情色,更非物化」、「称赞该女,应无不妥」,更威胁要对网友提告。

    + +

    王文提到:「…新闻操作,之所以能够成为有效打压学运的手段,其实是仰赖著公共空间排除『性』(包含性活动与性言说)的背景跟『社会共识』…社会文化将『性』看得非常负面。」「当励馨等妇权团体出面严厉谴责中天名嘴时,我看到了『真凶痛批帮凶』这样的荒谬场景。这些团体向来容不得性异议与各种边缘偏差…台湾今天之所以会变成这样一个动辄得咎的性恐慌社会,这些妇权团体绝对必须负起大半责任。」最后归结「谴责电视台公然意淫女体,…但真正问题还是在於呈现方式,…将『意淫』直接等同於『歧视』,…只是再度把『性』的定义跟诠释放手交由电视名嘴与既有的社会共识决定。…所有像是鸡排妹这样的主体,也将永远只能被解释成为父权结构下的被动受害者,而不是自主自信展现身体的异议不驯者。」高旭宽先生在下面的评论,更指出「因为女人的受害不是那两个贱嘴小XX搞的,是整个社会要求女人得对自己的身体惜肉如金,不可以沾染情色,要不然就脏掉了,就不值得尊重了!」

    + +

    王文所言「…新闻操作,之所以能够成为有效打压学运的手段,其实是仰赖著公共空间排除『性』(包含性活动与性言说)的背景跟『社会共识』」,大体上正确。然而,这样的论述中,省略掉一个重要的事实:中天新闻龙卷风的新闻操作,虽是以性和情欲为手段来打击学运,但最终目的并不在性与情欲,而是对运动现场女性参与者的攻击。性和情欲只是工具手段,不是问题的本身。无视於对女性的恶意,只是一昧把焦点放在性与情欲,是对事实的错误理解。纯然以性与情欲来解读事件,和新闻龙卷风节目制作单位所说的以「正面字眼称赞该女」,有什么不同?

    + +

    依王文的逻辑,「新闻龙卷风」之所以能攻击女性,是因为社会对性和情欲的恐惧,只要去除社会对性和情欲的恐惧,就不会受伤了。然而,真的去除社会对性和情欲的恐惧,就不会有性侵、不会有性骚扰了吗?所以性侵案该处罚的,是规训身体意识的父母和学校,而不是攻击的犯人吗?

    + +

    高旭宽先生的回应,通篇充满性器官、性行为的粗话,感觉更为粗鄙,更有男性气概,更清楚展现了传统沙文男性的社会形象。其背后的逻辑更粗糙、更直接,直接否认了「性攻击」本身的因果关系,将受害的原因,直接导向女性的自我认知。所以女性被性骚扰、被性侵、被性攻击,全部都是女人自己在社会规训之下的被迫害妄想。直接否认掉加害的因果关系,出於一位性别工作者口中,让人非常错愕,愤怒与无法理解。

    + +

    这次的太阳花学运,和以往社、学运最大的不同之一,是现场我们看到很多的女性走出来,参与其中。不论是议场守夜、外围防守、纠察、物资、医疗、法律、工程志工排班、攻占行政院,及上台演说,都出现了大量的女性身影。大量女性参与者的投入,意谓著抗争环境对女性越来越友善,女性的社会公民意识越来越清晰,自主性越来越强。反过来说,我们也可以期待大量女性参与者的投入,会带动抗争环境对女性更加友善。三立记者杨伊湄的投书,让我讶异女性主义竟已深入这一代女性的灵魂之中,让她们在第一时间就能勇敢跳出来反击。然而,恶质的媒体,在抹黑运动的时候,仍然以最传统的性来攻击女参与者。而有著性别盲的传统运动者同样无法跳脱同样的沙文逻辑,只看的到性攻击里的性,否认性攻击的暴力本质,进而否认加害的因果关系,这是非常可悲的。 到头来,媒体和传统运动者,看待太阳花的女性运动者,眼中都只有性,别无其他。

    + +

    我们厌恶这种看不到女性被攻击,只看得到女性的性的逻辑。太阳花不惧染黄,但是太阳花厌恶染黄!

    + +
    + +
    + +
    +
    1.7.’14. 11:34pm.
    + +

    幽丽塔

    + +

    乃木坂太郎幽丽塔好好看! FTM 跨性别、扮装 CD 和不敢出柜的男同志的悬疑推理故事。

    + +

    上网查过,原来幽丽塔是二手的改编故事。一开始的原作,是英国小说家 Alice Stuyvesant 在 1898 年写的小说灰衣妇人 A Woman in Grey 。 1901 年日本小说家、翻译家黑岩泪香将其翻译、改写为幽灵塔 ゆうれいとう Ghost Tower幽丽塔即改写自黑岩泪香的幽灵塔。此外,江户川乱步在 1937-1938 年,也改写了黑岩泪香的幽灵塔。这么多人改写,感觉上,幽灵塔/幽丽塔的故事,是一个非常经典的推理小说的架构。

    + +

    幽丽塔不只故事结构,连人物名字,也取自黑岩泪香的幽灵塔幽丽塔中的反派检查官丸部道九郎,正是黑岩泪香的幽灵塔主角的名字。

    + +

    不过长篇漫画果然还是很吃力,连载到一半,前面的梗和人物关系,都忘得差不多了。后来上网从头看,才想起丸部和山科是什么样的角色,剧情是如何演进到现在这样的。原来山科是 Gay ,之前就铺梗铺了这么久!港版已经出到第六集了,台版还在第四集,不知道是怎么回事。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 191 | + 192 | + 193 | + 194 | + 195 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0193.html.zh-tw.html b/htdocs/imacat/me/diary/0193.html.zh-tw.html new file mode 120000 index 0000000..520f336 --- /dev/null +++ b/htdocs/imacat/me/diary/0193.html.zh-tw.html @@ -0,0 +1 @@ +0193.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0193.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0193.html.zh-tw.xhtml new file mode 100644 index 0000000..cfb8a7f --- /dev/null +++ b/htdocs/imacat/me/diary/0193.html.zh-tw.xhtml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百九十三 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百九十三

    + +
    + +
    + +
    +
    4.10.’14. 11:36am.
    + +

    太陽花厭惡染黃—回應王顥中一文

    + +

    拜讀王顥中先生 2014/4/7 在苦勞網的苦勞評論「太陽花何懼抹黃?」及高旭寬先生在其後的評論。對於兩人的論點,難以苟同。

    + +

    中天政論節目「新聞龍捲風」的主持人戴立綱與來賓彭華幹,在 2014/4/4 節目中,針對太陽花學運的多張現場照片,以誇張下流不堪的語言及肢體動作,意淫照片中多位女性參與者。節目播出後引起軒然大波,當天網友號召 PTT 鄉民到 NCC 檢舉,導致 NCC 網站被檢舉擠爆,三立記者楊伊湄投書蘋果日報抗議,勵馨基金會、婦女新知基金會相繼發表聲明嚴正抗議,被侮蔑的照片當事人,其中一位關閉臉書,另外一位決定提告。新聞龍捲風製作單位第一時間在臉書上聲明是以「正面字眼稱讚該女」、「非關情色,更非物化」、「稱讚該女,應無不妥」,更威脅要對網友提告。

    + +

    王文提到:「…新聞操作,之所以能夠成為有效打壓學運的手段,其實是仰賴著公共空間排除『性』(包含性活動與性言說)的背景跟『社會共識』…社會文化將『性』看得非常負面。」「當勵馨等婦權團體出面嚴厲譴責中天名嘴時,我看到了『真兇痛批幫凶』這樣的荒謬場景。這些團體向來容不得性異議與各種邊緣偏差…台灣今天之所以會變成這樣一個動輒得咎的性恐慌社會,這些婦權團體絕對必須負起大半責任。」最後歸結「譴責電視台公然意淫女體,…但真正問題還是在於呈現方式,…將『意淫』直接等同於『歧視』,…只是再度把『性』的定義跟詮釋放手交由電視名嘴與既有的社會共識決定。…所有像是雞排妹這樣的主體,也將永遠只能被解釋成為父權結構下的被動受害者,而不是自主自信展現身體的異議不馴者。」高旭寬先生在下面的評論,更指出「因為女人的受害不是那兩個賤嘴小XX搞的,是整個社會要求女人得對自己的身體惜肉如金,不可以沾染情色,要不然就髒掉了,就不值得尊重了!」

    + +

    王文所言「…新聞操作,之所以能夠成為有效打壓學運的手段,其實是仰賴著公共空間排除『性』(包含性活動與性言說)的背景跟『社會共識』」,大體上正確。然而,這樣的論述中,省略掉一個重要的事實:中天新聞龍捲風的新聞操作,雖是以性和情慾為手段來打擊學運,但最終目的並不在性與情慾,而是對運動現場女性參與者的攻擊。性和情慾只是工具手段,不是問題的本身。無視於對女性的惡意,只是一昧把焦點放在性與情慾,是對事實的錯誤理解。純然以性與情慾來解讀事件,和新聞龍捲風節目製作單位所說的以「正面字眼稱讚該女」,有什麼不同?

    + +

    依王文的邏輯,「新聞龍捲風」之所以能攻擊女性,是因為社會對性和情慾的恐懼,只要去除社會對性和情慾的恐懼,就不會受傷了。然而,真的去除社會對性和情慾的恐懼,就不會有性侵、不會有性騷擾了嗎?所以性侵案該處罰的,是規訓身體意識的父母和學校,而不是攻擊的犯人嗎?

    + +

    高旭寬先生的回應,通篇充滿性器官、性行為的粗話,感覺更為粗鄙,更有男性氣概,更清楚展現了傳統沙文男性的社會形象。其背後的邏輯更粗糙、更直接,直接否認了「性攻擊」本身的因果關係,將受害的原因,直接導向女性的自我認知。所以女性被性騷擾、被性侵、被性攻擊,全部都是女人自己在社會規訓之下的被迫害妄想。直接否認掉加害的因果關係,出於一位性別工作者口中,讓人非常錯愕,憤怒與無法理解。

    + +

    這次的太陽花學運,和以往社、學運最大的不同之一,是現場我們看到很多的女性走出來,參與其中。不論是議場守夜、外圍防守、糾察、物資、醫療、法律、工程志工排班、攻佔行政院,及上台演說,都出現了大量的女性身影。大量女性參與者的投入,意謂著抗爭環境對女性越來越友善,女性的社會公民意識越來越清晰,自主性越來越強。反過來說,我們也可以期待大量女性參與者的投入,會帶動抗爭環境對女性更加友善。三立記者楊伊湄的投書,讓我訝異女性主義竟已深入這一代女性的靈魂之中,讓她們在第一時間就能勇敢跳出來反擊。然而,惡質的媒體,在抹黑運動的時候,仍然以最傳統的性來攻擊女參與者。而有著性別盲的傳統運動者同樣無法跳脫同樣的沙文邏輯,只看的到性攻擊裏的性,否認性攻擊的暴力本質,進而否認加害的因果關係,這是非常可悲的。 到頭來,媒體和傳統運動者,看待太陽花的女性運動者,眼中都只有性,別無其他。

    + +

    我們厭惡這種看不到女性被攻擊,只看得到女性的性的邏輯。太陽花不懼染黃,但是太陽花厭惡染黃!

    + +
    + +
    + +
    +
    1.7.’14. 11:34pm.
    + +

    幽麗塔

    + +

    乃木坂太郎幽麗塔好好看! FTM 跨性別、扮裝 CD 和不敢出櫃的男同志的懸疑推理故事。

    + +

    上網查過,原來幽麗塔是二手的改編故事。一開始的原作,是英國小說家 Alice Stuyvesant 在 1898 年寫的小說灰衣婦人 A Woman in Grey 。 1901 年日本小說家、翻譯家黑岩淚香將其翻譯、改寫為幽靈塔 ゆうれいとう Ghost Tower幽麗塔即改寫自黑岩淚香的幽靈塔。此外,江戶川亂步在 1937-1938 年,也改寫了黑岩淚香的幽靈塔。這麼多人改寫,感覺上,幽靈塔/幽麗塔的故事,是一個非常經典的推理小說的架構。

    + +

    幽麗塔不只故事結構,連人物名字,也取自黑岩淚香的幽靈塔幽麗塔中的反派檢查官丸部道九郎,正是黑岩淚香的幽靈塔主角的名字。

    + +

    不過長篇漫畫果然還是很吃力,連載到一半,前面的梗和人物關係,都忘得差不多了。後來上網從頭看,才想起丸部和山科是什麼樣的角色,劇情是如何演進到現在這樣的。原來山科是 Gay ,之前就鋪梗鋪了這麼久!港版已經出到第六集了,台版還在第四集,不知道是怎麼回事。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 191 | + 192 | + 193 | + 194 | + 195 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0194.html.en.html b/htdocs/imacat/me/diary/0194.html.en.html new file mode 120000 index 0000000..556ffd5 --- /dev/null +++ b/htdocs/imacat/me/diary/0194.html.en.html @@ -0,0 +1 @@ +0194.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0194.html.en.xhtml b/htdocs/imacat/me/diary/0194.html.en.xhtml new file mode 100644 index 0000000..6fe6b4c --- /dev/null +++ b/htdocs/imacat/me/diary/0194.html.en.xhtml @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 194 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 194

    + +
    + +
    + +
    +
    4.29.’14. 3:00am.
    + +

    關於勞權會八卦的一點碎碎念

    + +

    聽說勞權會從五一遊行的工作小組中被踢出去了。上網查新聞,查到兩篇:

    + +
      +
    1. 全國關廠工人連線:關於「建議勞權會退出五一平台」的備忘錄
    2. +
    3. 夏潮聯合會會長許育嘉:「反服貿,反自由貿易」?別再混淆不清
    4. +
    + +

    在第一篇備忘錄中,勞權會王娟萍提出,應該要將「反自由貿易協定」改為「反新自由主義經濟」。我原本一直看不懂把「反自由貿易協定」改為「反新自由主義經濟」是什麼意思。多謝夏潮的許育嘉,替王娟萍說明清楚後,我才豁然開朗。

    + +

    許育嘉提出要辨別「兩岸服貿協議」和「自由貿易協定」之間的共同性與差異性。在說明美國為首的新自由主義全球化問題後,許育嘉指出,兩岸服貿協議雖然是「自由貿易」,但卻與新自由主義全球化下的「自由貿易」有著完全不相同,甚至是對抗性的內涵。

    + +

    瞭解了許育嘉所提「美帝為首的新自由主義全球化下的自由貿易」和「非美帝、非新自由主義的自由貿易」的對抗性內涵後,勞權會的立場,便豁然開朗了。在勞權會和許育嘉的眼中,資本主義有兩種:

    + +
      +
    1. 美帝的資本主義自由貿易。
    2. +
    3. 非美帝的(中帝的)資本主義自由貿易。
    4. +
    + +

    在勞權會和許育嘉的眼中,工人應該對抗的是第一種美帝的資本主義,和第二種中帝的資本主義併肩站在一起。是的。「中帝」兩個字,是勞權會和許育嘉刻意忽略無視的。傳統左派理論,對於批判美帝有淵遠流長的理論歷史,六零年代中國的毛澤東主義,又是左派重要的理論之父。因此,在面對中帝資本主義時,傳統左派變得無能懦弱,選擇性的色盲。

    + +

    過去二十年來的中國「改革開放」,一直上演著十八世紀初英國資本主義同樣的悲劇:鄉村的村委和黨書紀把土地大量盜賣給大資本家,農民被大量掠奪土地和生產工具。鄉村的無產階級受金錢吸引,被迫進入都市求生,成為被生產工具控制、被剝削的勞工。同時中國利用著自己的資本優勢,透過孔子書院、電影戲劇合作投資等方式,將中國文化向全世界殖民,也壓榨著鄰近的國家。

    + +

    如果這不是資本主義,如果這不是帝國主義,那什麼是資本主義?什麼是帝國主義?

    + +

    這樣一種中國盲,曝露出勞權會為首的左派的最大問題:統大於左。工人的利益,碰到統獨,就軟掉了。在他們批判台灣社會的統獨大於工人利益的時候,他們也正是同樣的一群人。

    + +
    + +
    + +
    +
    4.16.’14. 11:10pm.
    + +

    1600

    + +
    +1600 +
    + +

    1600 - 這是我 4/10 深夜看到這個畫面時,心中想到的第一個詞。

    + +

    因為隔天一大早要去中研院 OSDC 佈置攤位,深夜繞去看大腸花後,不得不加快腳步回家。路經教育部,遠遠看到教育部庭院內待命的警察,或站或坐,或疲倦地靠在盾牌上小睡。他們都是一個一個有血有肉的人,可是在執政者眼中,他們只是 1600 ,一個比留守民眾還要多,以便執行強制驅離的數字。

    + +

    我不知道是幾點,但我知道這些警察會拖著疲憊的身驅強制驅離。我對他們無能為力。

    + +

    這是我對警察的態度。警察很辛苦,但我只會跟他們說辛苦了,不會跟他們說謝謝。說謝謝太虛偽了。警察只是執政者的工具和武器,我不會跟武器說謝謝,而無情的執政者也只把警察當成工具和武器,毫不憐憫體恤。

    + +
    + +
    + +
    +
    4.16.’14. 1:24am.
    + +

    一點自省

    + +

    覺得自己年紀越大,個性越衝了這樣。

    + +

    以前年紀小時,像極了處女座,做什麼事情都畏畏縮縮,怕被人家討厭閒話,怕違反規則,怕違背人情義理,怕破壞自己形象,東怕西怕,什麼都半弔子,沒有什麼太大的作為。

    + +

    年紀越大,好像就顧忌越來越少了。想想差不多了,目的手段都沒有問題,就衝了這樣。像極了上昇牡羊,瞻前不顧後,亂來一把的。

    + +
    + +
    + +
    +
    4.16.’14. 0:38am.
    + +

    一點對民進黨的感想

    + +

    很多媒體嘲笑,民進黨在這次的太陽花社運中被邊緣化,淪為顧門的。對這種講法,不是很同意。

    + +

    顧門是很辛苦的工作,辛苦危險的程度堪比八巷。如果八巷死守的朋友是勇士的話,那顧門的立委為什麼不是勇士?「民進黨淪為顧門的」這種說法,把八巷勇士置於何處?

    + +

    然而,對民進黨的批判,也不是憑空誣陷。蘇貞昌第三天(3/20)一出現,就開始談年底選舉,到底把運動現場當成什麼了?呂秀蓮4/12說社會運動不宜多蘇貞昌4/13說包圍警局模糊學運價值,都讓人覺得,這個黨已經沒救了。

    + +

    這些台灣的民主前輩們,忘了自己當年也是這樣義無反顧衝撞,才衝出台灣的民主之路來。現在反過來,責怪社會運動太多,責怪運動模糊價值。莫名其妙!

    + +

    民進黨不是完全沒救,還是有許多可戰之士,但是要依賴現在滿腦子算計守舊的美麗島天王,是不可能的。

    + +
    + +
    + +
    +
    4.16.’14. 0:38am.
    + +

    關於包圍中正一分局事件

    + +

    包圍中正一的事件是個試金石,測試太陽花退出立院後,公民意識的反抗火種,是不是還在人民的心中。事實證明,退出立院後,反抗的怒火沒有熄滅,反而更旺盛地燃燒起來,遍地開花。

    + +

    中計什麼的,我一點也不擔心。二十萬人挺方仰寧的粉絲頁,馬上被精明的鄉民拆穿,證明了台灣人不是吃素的。馬政府自以為聰明的計策,儘管放馬過來,台灣人不怕。

    + +

    這次運動虧欠蔡丁貴公投盟的,數都數不盡。沒有公投盟,就沒有今天的勝利。就算要揹再大的黑鍋,還是非挺不可。

    + +

    如果說有什麼值得反省的,那就是我年紀大了,這幾天工作太累,沒有力氣到現聲援,輸給優秀的學弟,非常慚愧。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 191 | + 192 | + 193 | + 194 | + 195 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0194.html.zh-cn.html b/htdocs/imacat/me/diary/0194.html.zh-cn.html new file mode 120000 index 0000000..8869bfc --- /dev/null +++ b/htdocs/imacat/me/diary/0194.html.zh-cn.html @@ -0,0 +1 @@ +0194.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0194.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0194.html.zh-cn.xhtml new file mode 100644 index 0000000..758f8ac --- /dev/null +++ b/htdocs/imacat/me/diary/0194.html.zh-cn.xhtml @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百九十四 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百九十四

    + +
    + +
    + +
    +
    4.29.’14. 3:00am.
    + +

    关於劳权会八卦的一点碎碎念

    + +

    听说劳权会从五一游行的工作小组中被踢出去了。上网查新闻,查到两篇:

    + +
      +
    1. 全国关厂工人连线:关於「建议劳权会退出五一平台」的备忘录
    2. +
    3. 夏潮联合会会长许育嘉:「反服贸,反自由贸易」?别再混淆不清
    4. +
    + +

    在第一篇备忘录中,劳权会王娟萍提出,应该要将「反自由贸易协定」改为「反新自由主义经济」。我原本一直看不懂把「反自由贸易协定」改为「反新自由主义经济」是什么意思。多谢夏潮的许育嘉,替王娟萍说明清楚后,我才豁然开朗。

    + +

    许育嘉提出要辨别「两岸服贸协议」和「自由贸易协定」之间的共同性与差异性。在说明美国为首的新自由主义全球化问题后,许育嘉指出,两岸服贸协议虽然是「自由贸易」,但却与新自由主义全球化下的「自由贸易」有著完全不相同,甚至是对抗性的内涵。

    + +

    了解了许育嘉所提「美帝为首的新自由主义全球化下的自由贸易」和「非美帝、非新自由主义的自由贸易」的对抗性内涵后,劳权会的立场,便豁然开朗了。在劳权会和许育嘉的眼中,资本主义有两种:

    + +
      +
    1. 美帝的资本主义自由贸易。
    2. +
    3. 非美帝的(中帝的)资本主义自由贸易。
    4. +
    + +

    在劳权会和许育嘉的眼中,工人应该对抗的是第一种美帝的资本主义,和第二种中帝的资本主义并肩站在一起。是的。「中帝」两个字,是劳权会和许育嘉刻意忽略无视的。传统左派理论,对於批判美帝有渊远流长的理论历史,六零年代中国的毛泽东主义,又是左派重要的理论之父。因此,在面对中帝资本主义时,传统左派变得无能懦弱,选择性的色盲。

    + +

    过去二十年来的中国「改革开放」,一直上演著十八世纪初英国资本主义同样的悲剧:乡村的村委和党书纪把土地大量盗卖给大资本家,农民被大量掠夺土地和生产工具。乡村的无产阶级受金钱吸引,被迫进入都市求生,成为被生产工具控制、被剥削的劳工。同时中国利用著自己的资本优势,透过孔子书院、电影戏剧合作投资等方式,将中国文化向全世界殖民,也压榨著邻近的国家。

    + +

    如果这不是资本主义,如果这不是帝国主义,那什么是资本主义?什么是帝国主义?

    + +

    这样一种中国盲,曝露出劳权会为首的左派的最大问题:统大於左。工人的利益,碰到统独,就软掉了。在他们批判台湾社会的统独大於工人利益的时候,他们也正是同样的一群人。

    + +
    + +
    + +
    +
    4.16.’14. 11:10pm.
    + +

    1600

    + +
    +1600 +
    + +

    1600 - 这是我 4/10 深夜看到这个画面时,心中想到的第一个词。

    + +

    因为隔天一大早要去中研院 OSDC 布置摊位,深夜绕去看大肠花后,不得不加快脚步回家。路经教育部,远远看到教育部庭院内待命的警察,或站或坐,或疲倦地靠在盾牌上小睡。他们都是一个一个有血有肉的人,可是在执政者眼中,他们只是 1600 ,一个比留守民众还要多,以便执行强制驱离的数字。

    + +

    我不知道是几点,但我知道这些警察会拖著疲惫的身驱强制驱离。我对他们无能为力。

    + +

    这是我对警察的态度。警察很辛苦,但我只会跟他们说辛苦了,不会跟他们说谢谢。说谢谢太虚伪了。警察只是执政者的工具和武器,我不会跟武器说谢谢,而无情的执政者也只把警察当成工具和武器,毫不怜悯体恤。

    + +
    + +
    + +
    +
    4.16.’14. 1:24am.
    + +

    一点自省

    + +

    觉得自己年纪越大,个性越冲了这样。

    + +

    以前年纪小时,像极了处女座,做什么事情都畏畏缩缩,怕被人家讨厌闲话,怕违反规则,怕违背人情义理,怕破坏自己形象,东怕西怕,什么都半吊子,没有什么太大的作为。

    + +

    年纪越大,好像就顾忌越来越少了。想想差不多了,目的手段都没有问题,就冲了这样。像极了上升牡羊,瞻前不顾后,乱来一把的。

    + +
    + +
    + +
    +
    4.16.’14. 0:38am.
    + +

    一点对民进党的感想

    + +

    很多媒体嘲笑,民进党在这次的太阳花社运中被边缘化,沦为顾门的。对这种讲法,不是很同意。

    + +

    顾门是很辛苦的工作,辛苦危险的程度堪比八巷。如果八巷死守的朋友是勇士的话,那顾门的立委为什么不是勇士?「民进党沦为顾门的」这种说法,把八巷勇士置於何处?

    + +

    然而,对民进党的批判,也不是凭空诬陷。苏贞昌第三天(3/20)一出现,就开始谈年底选举,到底把运动现场当成什么了?吕秀莲4/12说社会运动不宜多苏贞昌4/13说包围警局模糊学运价值,都让人觉得,这个党已经没救了。

    + +

    这些台湾的民主前辈们,忘了自己当年也是这样义无反顾冲撞,才冲出台湾的民主之路来。现在反过来,责怪社会运动太多,责怪运动模糊价值。莫名其妙!

    + +

    民进党不是完全没救,还是有许多可战之士,但是要依赖现在满脑子算计守旧的美丽岛天王,是不可能的。

    + +
    + +
    + +
    +
    4.16.’14. 0:38am.
    + +

    关於包围中正一分局事件

    + +

    包围中正一的事件是个试金石,测试太阳花退出立院后,公民意识的反抗火种,是不是还在人民的心中。事实证明,退出立院后,反抗的怒火没有熄灭,反而更旺盛地燃烧起来,遍地开花。

    + +

    中计什么的,我一点也不担心。二十万人挺方仰宁的粉丝页,马上被精明的乡民拆穿,证明了台湾人不是吃素的。马政府自以为聪明的计策,尽管放马过来,台湾人不怕。

    + +

    这次运动亏欠蔡丁贵公投盟的,数都数不尽。没有公投盟,就没有今天的胜利。就算要背再大的黑锅,还是非挺不可。

    + +

    如果说有什么值得反省的,那就是我年纪大了,这几天工作太累,没有力气到现声援,输给优秀的学弟,非常惭愧。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 191 | + 192 | + 193 | + 194 | + 195 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0194.html.zh-tw.html b/htdocs/imacat/me/diary/0194.html.zh-tw.html new file mode 120000 index 0000000..b76e2f0 --- /dev/null +++ b/htdocs/imacat/me/diary/0194.html.zh-tw.html @@ -0,0 +1 @@ +0194.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0194.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0194.html.zh-tw.xhtml new file mode 100644 index 0000000..2256ed0 --- /dev/null +++ b/htdocs/imacat/me/diary/0194.html.zh-tw.xhtml @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百九十四 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百九十四

    + +
    + +
    + +
    +
    4.29.’14. 3:00am.
    + +

    關於勞權會八卦的一點碎碎念

    + +

    聽說勞權會從五一遊行的工作小組中被踢出去了。上網查新聞,查到兩篇:

    + +
      +
    1. 全國關廠工人連線:關於「建議勞權會退出五一平台」的備忘錄
    2. +
    3. 夏潮聯合會會長許育嘉:「反服貿,反自由貿易」?別再混淆不清
    4. +
    + +

    在第一篇備忘錄中,勞權會王娟萍提出,應該要將「反自由貿易協定」改為「反新自由主義經濟」。我原本一直看不懂把「反自由貿易協定」改為「反新自由主義經濟」是什麼意思。多謝夏潮的許育嘉,替王娟萍說明清楚後,我才豁然開朗。

    + +

    許育嘉提出要辨別「兩岸服貿協議」和「自由貿易協定」之間的共同性與差異性。在說明美國為首的新自由主義全球化問題後,許育嘉指出,兩岸服貿協議雖然是「自由貿易」,但卻與新自由主義全球化下的「自由貿易」有著完全不相同,甚至是對抗性的內涵。

    + +

    瞭解了許育嘉所提「美帝為首的新自由主義全球化下的自由貿易」和「非美帝、非新自由主義的自由貿易」的對抗性內涵後,勞權會的立場,便豁然開朗了。在勞權會和許育嘉的眼中,資本主義有兩種:

    + +
      +
    1. 美帝的資本主義自由貿易。
    2. +
    3. 非美帝的(中帝的)資本主義自由貿易。
    4. +
    + +

    在勞權會和許育嘉的眼中,工人應該對抗的是第一種美帝的資本主義,和第二種中帝的資本主義併肩站在一起。是的。「中帝」兩個字,是勞權會和許育嘉刻意忽略無視的。傳統左派理論,對於批判美帝有淵遠流長的理論歷史,六零年代中國的毛澤東主義,又是左派重要的理論之父。因此,在面對中帝資本主義時,傳統左派變得無能懦弱,選擇性的色盲。

    + +

    過去二十年來的中國「改革開放」,一直上演著十八世紀初英國資本主義同樣的悲劇:鄉村的村委和黨書紀把土地大量盜賣給大資本家,農民被大量掠奪土地和生產工具。鄉村的無產階級受金錢吸引,被迫進入都市求生,成為被生產工具控制、被剝削的勞工。同時中國利用著自己的資本優勢,透過孔子書院、電影戲劇合作投資等方式,將中國文化向全世界殖民,也壓榨著鄰近的國家。

    + +

    如果這不是資本主義,如果這不是帝國主義,那什麼是資本主義?什麼是帝國主義?

    + +

    這樣一種中國盲,曝露出勞權會為首的左派的最大問題:統大於左。工人的利益,碰到統獨,就軟掉了。在他們批判台灣社會的統獨大於工人利益的時候,他們也正是同樣的一群人。

    + +
    + +
    + +
    +
    4.16.’14. 11:10pm.
    + +

    1600

    + +
    +1600 +
    + +

    1600 - 這是我 4/10 深夜看到這個畫面時,心中想到的第一個詞。

    + +

    因為隔天一大早要去中研院 OSDC 佈置攤位,深夜繞去看大腸花後,不得不加快腳步回家。路經教育部,遠遠看到教育部庭院內待命的警察,或站或坐,或疲倦地靠在盾牌上小睡。他們都是一個一個有血有肉的人,可是在執政者眼中,他們只是 1600 ,一個比留守民眾還要多,以便執行強制驅離的數字。

    + +

    我不知道是幾點,但我知道這些警察會拖著疲憊的身驅強制驅離。我對他們無能為力。

    + +

    這是我對警察的態度。警察很辛苦,但我只會跟他們說辛苦了,不會跟他們說謝謝。說謝謝太虛偽了。警察只是執政者的工具和武器,我不會跟武器說謝謝,而無情的執政者也只把警察當成工具和武器,毫不憐憫體恤。

    + +
    + +
    + +
    +
    4.16.’14. 1:24am.
    + +

    一點自省

    + +

    覺得自己年紀越大,個性越衝了這樣。

    + +

    以前年紀小時,像極了處女座,做什麼事情都畏畏縮縮,怕被人家討厭閒話,怕違反規則,怕違背人情義理,怕破壞自己形象,東怕西怕,什麼都半弔子,沒有什麼太大的作為。

    + +

    年紀越大,好像就顧忌越來越少了。想想差不多了,目的手段都沒有問題,就衝了這樣。像極了上昇牡羊,瞻前不顧後,亂來一把的。

    + +
    + +
    + +
    +
    4.16.’14. 0:38am.
    + +

    一點對民進黨的感想

    + +

    很多媒體嘲笑,民進黨在這次的太陽花社運中被邊緣化,淪為顧門的。對這種講法,不是很同意。

    + +

    顧門是很辛苦的工作,辛苦危險的程度堪比八巷。如果八巷死守的朋友是勇士的話,那顧門的立委為什麼不是勇士?「民進黨淪為顧門的」這種說法,把八巷勇士置於何處?

    + +

    然而,對民進黨的批判,也不是憑空誣陷。蘇貞昌第三天(3/20)一出現,就開始談年底選舉,到底把運動現場當成什麼了?呂秀蓮4/12說社會運動不宜多蘇貞昌4/13說包圍警局模糊學運價值,都讓人覺得,這個黨已經沒救了。

    + +

    這些台灣的民主前輩們,忘了自己當年也是這樣義無反顧衝撞,才衝出台灣的民主之路來。現在反過來,責怪社會運動太多,責怪運動模糊價值。莫名其妙!

    + +

    民進黨不是完全沒救,還是有許多可戰之士,但是要依賴現在滿腦子算計守舊的美麗島天王,是不可能的。

    + +
    + +
    + +
    +
    4.16.’14. 0:38am.
    + +

    關於包圍中正一分局事件

    + +

    包圍中正一的事件是個試金石,測試太陽花退出立院後,公民意識的反抗火種,是不是還在人民的心中。事實證明,退出立院後,反抗的怒火沒有熄滅,反而更旺盛地燃燒起來,遍地開花。

    + +

    中計什麼的,我一點也不擔心。二十萬人挺方仰寧的粉絲頁,馬上被精明的鄉民拆穿,證明了台灣人不是吃素的。馬政府自以為聰明的計策,儘管放馬過來,台灣人不怕。

    + +

    這次運動虧欠蔡丁貴公投盟的,數都數不盡。沒有公投盟,就沒有今天的勝利。就算要揹再大的黑鍋,還是非挺不可。

    + +

    如果說有什麼值得反省的,那就是我年紀大了,這幾天工作太累,沒有力氣到現聲援,輸給優秀的學弟,非常慚愧。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 191 | + 192 | + 193 | + 194 | + 195 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0195.html.en.html b/htdocs/imacat/me/diary/0195.html.en.html new file mode 120000 index 0000000..9eb863c --- /dev/null +++ b/htdocs/imacat/me/diary/0195.html.en.html @@ -0,0 +1 @@ +0195.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0195.html.en.xhtml b/htdocs/imacat/me/diary/0195.html.en.xhtml new file mode 100644 index 0000000..7bd0ecf --- /dev/null +++ b/htdocs/imacat/me/diary/0195.html.en.xhtml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary Volume 195 + + + + + + + +
    + +
    + + +

    Tavern Diary Volume 195

    + +
    + +
    + +
    +
    5.4.’14. 0:01am.
    + +

    我不支持抗稅

    + +

    說實話我完全不支持抗稅。

    + +

    任何反抗行動都必須以「會對對方造成困擾壓力」為前提。抗稅的前提是「政府沒有歲入會感到壓力」。問題是我們的執政者曾經為了財庫入不敷出感受過任何壓力嗎?沒有啊!政客根本不在乎財政收入不足,拼命花錢建設擴大內需,沒錢用借的發公債就好了。因為這是國庫,根本不是他們自己的錢。抗稅他們會在乎嗎?不會。大不了再發公債就有錢了。

    + +

    抗稅唯一會改變的,就是公債的數目,唯一會得到好處的,就是投資公債賺錢的投資客,以後我們要花更多錢付他們利息,並留下更多債給子孫而已。我不支持抗稅。

    + +
    + +
    + +
    +
    5.3.’14. 2:25am.
    + +

    關於運動,革命,和其他

    + +

    最近聽到幾個朋友,對運動感到很沮喪。他們對這個麻木不仁的政府徹底失望,無論怎麼大聲呼喊抗爭它都聽不到,只會拿警棍、法律對付人民,保護它自己耳根清靜。這些朋友對政府徹底失望,對運動感到灰心,覺得再怎麼抗爭,都會失敗,都沒有用,政府都不會理你。

    + +

    對此,我抱持不一樣的看法。引述林義雄先生4/30的「停止禁食聲明」(雖然我在之前就抱持著這樣的看法):

    + +
    +

    義雄對於當今的掌權者本無任何期待,因此不屑對他有任何請求。所以禁食的目的是在「懇請台灣人民以積極有力的方法」展現力量。

    +
    + +

    我對於政府,其實從來也沒有什麼期待。好吧多少有一點期待,希望能夠從體制內去聽到改變。但是只有一點點而已。執政掌權者,從來都是不可能會自己改變的。別天真了。革命和運動,真正應該期待的,不是政府,而是人民。只有人民擁有堅實而充沛的力量,只有一群無所畏懼、團結的人民挺身而出,堅不妥協,社會才會改變,執政者才可能被迫改變。

    + +

    因此,國民黨政府怎麼想,甚至未來的民進黨政府怎麼想,其實都不重要。重要的是,今天我們有五十萬人挺身而出。這個社會改變了,公民意識開始深植在人民的心中。人民看清執政者的暴力本質;人民開始拋棄冷漠,正面面對政治;人民願意挺身而出,犧牲個人時間精力,不畏國家暴力,捍衛民主。勇敢的人民力量,撼動了麻木不仁的政府,迫使政府在不甘不願下,停建三十年無法停建的核四,依法處理服貿。

    + +

    還有什麼,比這還更成功的呢?

    + +

    所以,朋友請不要灰心。妳看到政府奸險狡獪,麻木不仁。國家機器本來就是這樣,只是它終於露出真面目,讓妳看到了而已。和執政者的對抗,是一條沒有盡頭的路。只有強大團結的人民,才有可能對抗執政者。革命的對象從來都不是政府,而是人民。

    + +
    + +
    + +
    + +
    +
    + Index | + First | + Previous | + 191 | + 192 | + 193 | + 194 | + 195 | + Next | + Last +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0195.html.zh-cn.html b/htdocs/imacat/me/diary/0195.html.zh-cn.html new file mode 120000 index 0000000..ea511e4 --- /dev/null +++ b/htdocs/imacat/me/diary/0195.html.zh-cn.html @@ -0,0 +1 @@ +0195.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0195.html.zh-cn.xhtml b/htdocs/imacat/me/diary/0195.html.zh-cn.xhtml new file mode 100644 index 0000000..e3256f6 --- /dev/null +++ b/htdocs/imacat/me/diary/0195.html.zh-cn.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 卷一百九十五 + + + + + + + +
    + +
    + + +

    旅舍日记 卷一百九十五

    + +
    + +
    + +
    +
    5.4.’14. 0:01am.
    + +

    我不支持抗税

    + +

    说实话我完全不支持抗税。

    + +

    任何反抗行动都必须以「会对对方造成困扰压力」为前提。抗税的前提是「政府没有岁入会感到压力」。问题是我们的执政者曾经为了财库入不敷出感受过任何压力吗?没有啊!政客根本不在乎财政收入不足,拼命花钱建设扩大内需,没钱用借的发公债就好了。因为这是国库,根本不是他们自己的钱。抗税他们会在乎吗?不会。大不了再发公债就有钱了。

    + +

    抗税唯一会改变的,就是公债的数目,唯一会得到好处的,就是投资公债赚钱的投资客,以后我们要花更多钱付他们利息,并留下更多债给子孙而已。我不支持抗税。

    + +
    + +
    + +
    +
    5.3.’14. 2:25am.
    + +

    关於运动,革命,和其他

    + +

    最近听到几个朋友,对运动感到很沮丧。他们对这个麻木不仁的政府彻底失望,无论怎么大声呼喊抗争它都听不到,只会拿警棍、法律对付人民,保护它自己耳根清静。这些朋友对政府彻底失望,对运动感到灰心,觉得再怎么抗争,都会失败,都没有用,政府都不会理你。

    + +

    对此,我抱持不一样的看法。引述林义雄先生4/30的「停止禁食声明」(虽然我在之前就抱持著这样的看法):

    + +
    +

    义雄对於当今的掌权者本无任何期待,因此不屑对他有任何请求。所以禁食的目的是在「恳请台湾人民以积极有力的方法」展现力量。

    +
    + +

    我对於政府,其实从来也没有什么期待。好吧多少有一点期待,希望能够从体制内去听到改变。但是只有一点点而已。执政掌权者,从来都是不可能会自己改变的。别天真了。革命和运动,真正应该期待的,不是政府,而是人民。只有人民拥有坚实而充沛的力量,只有一群无所畏惧、团结的人民挺身而出,坚不妥协,社会才会改变,执政者才可能被迫改变。

    + +

    因此,国民党政府怎么想,甚至未来的民进党政府怎么想,其实都不重要。重要的是,今天我们有五十万人挺身而出。这个社会改变了,公民意识开始深植在人民的心中。人民看清执政者的暴力本质;人民开始抛弃冷漠,正面面对政治;人民愿意挺身而出,牺牲个人时间精力,不畏国家暴力,捍卫民主。勇敢的人民力量,撼动了麻木不仁的政府,迫使政府在不甘不愿下,停建三十年无法停建的核四,依法处理服贸。

    + +

    还有什么,比这还更成功的呢?

    + +

    所以,朋友请不要灰心。你看到政府奸险狡狯,麻木不仁。国家机器本来就是这样,只是它终於露出真面目,让你看到了而已。和执政者的对抗,是一条没有尽头的路。只有强大团结的人民,才有可能对抗执政者。革命的对象从来都不是政府,而是人民。

    + +
    + +
    + +
    + +
    +
    + 目录 | + 第一页 | + 前一页 | + 191 | + 192 | + 193 | + 194 | + 195 | + 下一页 | + 最末页 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/0195.html.zh-tw.html b/htdocs/imacat/me/diary/0195.html.zh-tw.html new file mode 120000 index 0000000..6995f4f --- /dev/null +++ b/htdocs/imacat/me/diary/0195.html.zh-tw.html @@ -0,0 +1 @@ +0195.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/0195.html.zh-tw.xhtml b/htdocs/imacat/me/diary/0195.html.zh-tw.xhtml new file mode 100644 index 0000000..afc19dc --- /dev/null +++ b/htdocs/imacat/me/diary/0195.html.zh-tw.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 卷一百九十五 + + + + + + + +
    + +
    + + +

    旅舍日記 卷一百九十五

    + +
    + +
    + +
    +
    5.4.’14. 0:01am.
    + +

    我不支持抗稅

    + +

    說實話我完全不支持抗稅。

    + +

    任何反抗行動都必須以「會對對方造成困擾壓力」為前提。抗稅的前提是「政府沒有歲入會感到壓力」。問題是我們的執政者曾經為了財庫入不敷出感受過任何壓力嗎?沒有啊!政客根本不在乎財政收入不足,拼命花錢建設擴大內需,沒錢用借的發公債就好了。因為這是國庫,根本不是他們自己的錢。抗稅他們會在乎嗎?不會。大不了再發公債就有錢了。

    + +

    抗稅唯一會改變的,就是公債的數目,唯一會得到好處的,就是投資公債賺錢的投資客,以後我們要花更多錢付他們利息,並留下更多債給子孫而已。我不支持抗稅。

    + +
    + +
    + +
    +
    5.3.’14. 2:25am.
    + +

    關於運動,革命,和其他

    + +

    最近聽到幾個朋友,對運動感到很沮喪。他們對這個麻木不仁的政府徹底失望,無論怎麼大聲呼喊抗爭它都聽不到,只會拿警棍、法律對付人民,保護它自己耳根清靜。這些朋友對政府徹底失望,對運動感到灰心,覺得再怎麼抗爭,都會失敗,都沒有用,政府都不會理你。

    + +

    對此,我抱持不一樣的看法。引述林義雄先生4/30的「停止禁食聲明」(雖然我在之前就抱持著這樣的看法):

    + +
    +

    義雄對於當今的掌權者本無任何期待,因此不屑對他有任何請求。所以禁食的目的是在「懇請台灣人民以積極有力的方法」展現力量。

    +
    + +

    我對於政府,其實從來也沒有什麼期待。好吧多少有一點期待,希望能夠從體制內去聽到改變。但是只有一點點而已。執政掌權者,從來都是不可能會自己改變的。別天真了。革命和運動,真正應該期待的,不是政府,而是人民。只有人民擁有堅實而充沛的力量,只有一群無所畏懼、團結的人民挺身而出,堅不妥協,社會才會改變,執政者才可能被迫改變。

    + +

    因此,國民黨政府怎麼想,甚至未來的民進黨政府怎麼想,其實都不重要。重要的是,今天我們有五十萬人挺身而出。這個社會改變了,公民意識開始深植在人民的心中。人民看清執政者的暴力本質;人民開始拋棄冷漠,正面面對政治;人民願意挺身而出,犧牲個人時間精力,不畏國家暴力,捍衛民主。勇敢的人民力量,撼動了麻木不仁的政府,迫使政府在不甘不願下,停建三十年無法停建的核四,依法處理服貿。

    + +

    還有什麼,比這還更成功的呢?

    + +

    所以,朋友請不要灰心。妳看到政府奸險狡獪,麻木不仁。國家機器本來就是這樣,只是它終於露出真面目,讓妳看到了而已。和執政者的對抗,是一條沒有盡頭的路。只有強大團結的人民,才有可能對抗執政者。革命的對象從來都不是政府,而是人民。

    + +
    + +
    + +
    + +
    +
    + 目錄 | + 第一頁 | + 前一頁 | + 191 | + 192 | + 193 | + 194 | + 195 | + 下一頁 | + 最末頁 +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/index.html.en.html b/htdocs/imacat/me/diary/index.html.en.html new file mode 120000 index 0000000..08fc4ee --- /dev/null +++ b/htdocs/imacat/me/diary/index.html.en.html @@ -0,0 +1 @@ +index.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/index.html.en.xhtml b/htdocs/imacat/me/diary/index.html.en.xhtml new file mode 100644 index 0000000..1c284f3 --- /dev/null +++ b/htdocs/imacat/me/diary/index.html.en.xhtml @@ -0,0 +1,711 @@ + + + + + + + + + + + + + + + + + + + + + + + + +Tavern Diary + + + + + + + +
    + +
    + + +

    Tavern Diary

    + + + +

    Index

    + +
      +
    1. Tavern Diary Volume 195

      +
      5.2.’14. - 5.3.’14.
    2. + +
    3. Tavern Diary Volume 194

      +
      4.15.’14. - 4.28.’14.
    4. + +
    5. Tavern Diary Volume 193

      +
      1.7.’14. - 4.10.’14.
    6. + +
    7. Tavern Diary Volume 192

      +
      12.27.’13. - 1.1.’14.
    8. + +
    9. Tavern Diary Volume 191

      +
      12.20.’13. - 12.27.’13.
    10. + +
    11. Tavern Diary Volume 190

      +
      12.4.’13. - 12.14.’13.
    12. + +
    13. Tavern Diary Volume 189

      +
      11.14.’13. - 11.24.’13.
    14. + +
    15. Tavern Diary Volume 188

      +
      7.15.’13. - 10.10.’13.
    16. + +
    17. Tavern Diary Volume 187

      +
      7.9.’13. - 7.15.’13.
    18. + +
    19. Tavern Diary Volume 186

      +
      7.8.’13. - 7.9.’13.
    20. + +
    21. Tavern Diary Volume 185

      +
      6.28.’13. - 7.7.’13.
    22. + +
    23. Tavern Diary Volume 184

      +
      6.26.’13. - 6.28.’13.
    24. + +
    25. Tavern Diary Volume 183

      +
      5.16.’13. - 6.26.’13.
    26. + +
    27. Tavern Diary Volume 182

      +
      1.29.’13. - 4.4.’13.
    28. + +
    29. Tavern Diary Volume 181

      +
      6.3.’12. - 12.8.’12.
    30. + +
    31. Tavern Diary Volume 180

      +
      2.24.’12. - 3.27.’12.
    32. + +
    33. Tavern Diary Volume 179

      +
      7.11.’11. - 1.13.’12.
    34. + +
    35. Tavern Diary Volume 178

      +
      7.8.’11. - 7.8.’11.
    36. + +
    37. Tavern Diary Volume 177

      +
      7.8.’11. - 7.8.’11.
    38. + +
    39. Tavern Diary Volume 176

      +
      6.1.’11. - 6.1.’11.
    40. + +
    41. Tavern Diary Volume 175

      +
      5.27.’11. - 5.27.’11.
    42. + +
    43. Tavern Diary Volume 174

      +
      3.31.’11. - 5.18.’11.
    44. + +
    45. Tavern Diary Volume 173

      +
      3.31.’11. - 3.31.’11.
    46. + +
    47. Tavern Diary Volume 172

      +
      3.29.’11. - 3.29.’11.
    48. + +
    49. Tavern Diary Volume 171

      +
      3.28.’11. - 3.28.’11.
    50. + +
    51. Tavern Diary Volume 170

      +
      3.28.’11. - 3.28.’11.
    52. + +
    53. Tavern Diary Volume 169

      +
      3.28.’11. - 3.28.’11.
    54. + +
    55. Tavern Diary Volume 168

      +
      3.25.’11. - 3.25.’11.
    56. + +
    57. Tavern Diary Volume 167

      +
      3.24.’11. - 3.24.’11.
    58. + +
    59. Tavern Diary Volume 166

      +
      3.24.’11. - 3.24.’11.
    60. + +
    61. Tavern Diary Volume 165

      +
      3.24.’11. - 3.24.’11.
    62. + +
    63. Tavern Diary Volume 164

      +
      1.6.’11. - 2.28.’11.
    64. + +
    65. Tavern Diary Volume 163

      +
      12.3.’10. - 12.3.’10.
    66. + +
    67. Tavern Diary Volume 162

      +
      10.26.’10. - 10.26.’10.
    68. + +
    69. Tavern Diary Volume 161

      +
      7.18.’10. - 7.18.’10.
    70. + +
    71. Tavern Diary Volume 160

      +
      3.4.’10. - 5.24.’10.
    72. + +
    73. Tavern Diary Volume 159

      +
      3.4.’10. - 3.4.’10.
    74. + +
    75. Tavern Diary Volume 158

      +
      2.18.’10. - 2.18.’10.
    76. + +
    77. Tavern Diary Volume 157

      +
      2.18.’10. - 2.18.’10.
    78. + +
    79. Tavern Diary Volume 156

      +
      2.3.’10. - 2.3.’10.
    80. + +
    81. Tavern Diary Volume 155

      +
      10.31.’09. - 1.5.’10.
    82. + +
    83. Tavern Diary Volume 154

      +
      10.18.’09. - 10.18.’09.
    84. + +
    85. Tavern Diary Volume 153

      +
      10.8.’09. - 10.8.’09.
    86. + +
    87. Tavern Diary Volume 152

      +
      2.28.’09. - 2.28.’09.
    88. + +
    89. Tavern Diary Volume 151

      +
      10.7.’08. - 10.7.’08.
    90. + +
    91. Tavern Diary Volume 150

      +
      10.7.’08. - 10.7.’08.
    92. + +
    93. Tavern Diary Volume 149

      +
      9.9.’08. - 9.9.’08.
    94. + +
    95. Tavern Diary Volume 148

      +
      7.24.’08. - 9.9.’08.
    96. + +
    97. Tavern Diary Volume 147

      +
      6.21.’08. - 6.21.’08.
    98. + +
    99. Tavern Diary Volume 146

      +
      4.8.’08. - 4.8.’08.
    100. + +
    101. Tavern Diary Volume 145

      +
      2.4.’08. - 2.4.’08.
    102. + +
    103. Tavern Diary Volume 144

      +
      1.31.’08. - 1.31.’08.
    104. + +
    105. Tavern Diary Volume 143

      +
      1.30.’08. - 1.30.’08.
    106. + +
    107. Tavern Diary Volume 142

      +
      1.30.’08. - 1.30.’08.
    108. + +
    109. Tavern Diary Volume 141

      +
      12.10.’07. - 12.10.’07.
    110. + +
    111. Tavern Diary Volume 140

      +
      11.25.’07. - 11.25.’07.
    112. + +
    113. Tavern Diary Volume 139

      +
      11.24.’07. - 11.24.’07.
    114. + +
    115. Tavern Diary Volume 138

      +
      10.21.’07. - 11.22.’07.
    116. + +
    117. Tavern Diary Volume 137

      +
      10.15.’07. - 10.21.’07.
    118. + +
    119. Tavern Diary Volume 136

      +
      10.10.’07. - 10.10.’07.
    120. + +
    121. Tavern Diary Volume 135

      +
      10.1.’07. - 10.3.’07.
    122. + +
    123. Tavern Diary Volume 134

      +
      9.27.’07. - 9.27.’07.
    124. + +
    125. Tavern Diary Volume 133

      +
      9.21.’07. - 9.21.’07.
    126. + +
    127. Tavern Diary Volume 132

      +
      9.20.’07. - 9.21.’07.
    128. + +
    129. Tavern Diary Volume 131

      +
      9.18.’07. - 9.20.’07.
    130. + +
    131. Tavern Diary Volume 130

      +
      9.18.’07. - 9.18.’07.
    132. + +
    133. Tavern Diary Volume 129

      +
      9.11.’07. - 9.11.’07.
    134. + +
    135. Tavern Diary Volume 128

      +
      9.11.’07. - 9.11.’07.
    136. + +
    137. Tavern Diary Volume 127

      +
      9.4.’07. - 9.7.’07.
    138. + +
    139. Tavern Diary Volume 126

      +
      8.28.’07. - 8.28.’07.
    140. + +
    141. Tavern Diary Volume 125

      +
      8.22.’07. - 8.22.’07.
    142. + +
    143. Tavern Diary Volume 124

      +
      8.16.’07. - 8.17.’07.
    144. + +
    145. Tavern Diary Volume 123

      +
      8.14.’07. - 8.14.’07.
    146. + +
    147. Tavern Diary Volume 122

      +
      8.13.’07. - 8.13.’07.
    148. + +
    149. Tavern Diary Volume 121

      +
      7.15.’07. - 8.3.’07.
    150. + +
    151. Tavern Diary Volume 120

      +
      6.22.’07. - 6.30.’07.
    152. + +
    153. Tavern Diary Volume 119

      +
      6.21.’07. - 6.21.’07.
    154. + +
    155. Tavern Diary Volume 118

      +
      6.20.’07. - 6.20.’07.
    156. + +
    157. Tavern Diary Volume 117

      +
      6.19.’07. - 6.19.’07.
    158. + +
    159. Tavern Diary Volume 116

      +
      6.18.’07. - 6.18.’07.
    160. + +
    161. Tavern Diary Volume 115

      +
      6.18.’07. - 6.18.’07.
    162. + +
    163. Tavern Diary Volume 114

      +
      6.11.’07. - 6.11.’07.
    164. + +
    165. Tavern Diary Volume 113

      +
      6.5.’07. - 6.5.’07.
    166. + +
    167. Tavern Diary Volume 112

      +
      4.1.’07. - 5.24.’07.
    168. + +
    169. Tavern Diary Volume 111

      +
      3.30.’07. - 3.30.’07.
    170. + +
    171. Tavern Diary Volume 110

      +
      2.10.’07. - 3.14.’07.
    172. + +
    173. Tavern Diary Volume 109

      +
      2.8.’07. - 2.8.’07.
    174. + +
    175. Tavern Diary Volume 108

      +
      2.8.’07. - 2.8.’07.
    176. + +
    177. Tavern Diary Volume 107

      +
      2.5.’07. - 2.5.’07.
    178. + +
    179. Tavern Diary Volume 106

      +
      2.3.’07. - 2.3.’07.
    180. + +
    181. Tavern Diary Volume 105

      +
      2.3.’07. - 2.3.’07.
    182. + +
    183. Tavern Diary Volume 104

      +
      2.3.’07. - 2.3.’07.
    184. + +
    185. Tavern Diary Volume 103

      +
      2.3.’07. - 2.3.’07.
    186. + +
    187. Tavern Diary Volume 102

      +
      1.14.’07. - 2.1.’07.
    188. + +
    189. Tavern Diary Volume 101

      +
      1.12.’07. - 1.14.’07.
    190. + +
    191. Tavern Diary Volume 100

      +
      1.7.’07. - 1.8.’07.
    192. + +
    193. Tavern Diary Volume 99

      +
      12.26.’06. - 12.26.’06.
    194. + +
    195. Tavern Diary Volume 98

      +
      12.25.’06. - 12.25.’06.
    196. + +
    197. Tavern Diary Volume 97

      +
      12.5.’06. - 12.9.’06.
    198. + +
    199. Tavern Diary Volume 96

      +
      12.5.’06. - 12.5.’06.
    200. + +
    201. Tavern Diary Volume 95

      +
      12.5.’06. - 12.5.’06.
    202. + +
    203. Tavern Diary Volume 94

      +
      11.17.’06. - 11.24.’06.
    204. + +
    205. Tavern Diary Volume 93

      +
      11.8.’06. - 11.13.’06.
    206. + +
    207. Tavern Diary Volume 92

      +
      11.6.’06. - 11.6.’06.
    208. + +
    209. Tavern Diary Volume 91

      +
      11.6.’06. - 11.6.’06.
    210. + +
    211. Tavern Diary Volume 90

      +
      11.3.’06. - 11.3.’06.
    212. + +
    213. Tavern Diary Volume 89

      +
      11.2.’06. - 11.2.’06.
    214. + +
    215. Tavern Diary Volume 88

      +
      11.2.’06. - 11.2.’06.
    216. + +
    217. Tavern Diary Volume 87

      +
      10.30.’06. - 10.30.’06.
    218. + +
    219. Tavern Diary Volume 86

      +
      10.12.’06. - 10.21.’06.
    220. + +
    221. Tavern Diary Volume 85

      +
      10.7.’06. - 10.12.’06.
    222. + +
    223. Tavern Diary Volume 84

      +
      10.7.’06. - 10.7.’06.
    224. + +
    225. Tavern Diary Volume 83

      +
      10.6.’06. - 10.6.’06.
    226. + +
    227. Tavern Diary Volume 82

      +
      10.3.’06. - 10.3.’06.
    228. + +
    229. Tavern Diary Volume 81

      +
      9.29.’06. - 10.1.’06.
    230. + +
    231. Tavern Diary Volume 80

      +
      9.25.’06. - 9.25.’06.
    232. + +
    233. Tavern Diary Volume 79

      +
      9.24.’06. - 9.24.’06.
    234. + +
    235. Tavern Diary Volume 78

      +
      9.22.’06. - 9.22.’06.
    236. + +
    237. Tavern Diary Volume 77

      +
      9.18.’06. - 9.18.’06.
    238. + +
    239. Tavern Diary Volume 76

      +
      9.17.’06. - 9.17.’06.
    240. + +
    241. Tavern Diary Volume 75

      +
      9.17.’06. - 9.17.’06.
    242. + +
    243. Tavern Diary Volume 74

      +
      9.17.’06. - 9.17.’06.
    244. + +
    245. Tavern Diary Volume 73

      +
      9.17.’06. - 9.17.’06.
    246. + +
    247. Tavern Diary Volume 72

      +
      9.16.’06. - 9.16.’06.
    248. + +
    249. Tavern Diary Volume 71

      +
      9.16.’06. - 9.16.’06.
    250. + +
    251. Tavern Diary Volume 70

      +
      9.15.’06. - 9.16.’06.
    252. + +
    253. Tavern Diary Volume 69

      +
      9.12.’06. - 9.12.’06.
    254. + +
    255. Tavern Diary Volume 68

      +
      8.27.’06. - 8.31.’06.
    256. + +
    257. Tavern Diary Volume 67

      +
      8.27.’06. - 8.27.’06.
    258. + +
    259. Tavern Diary Volume 66

      +
      8.27.’06. - 8.27.’06.
    260. + +
    261. Tavern Diary Volume 65

      +
      8.26.’06. - 8.27.’06.
    262. + +
    263. Tavern Diary Volume 64

      +
      8.26.’06. - 8.26.’06.
    264. + +
    265. Tavern Diary Volume 63

      +
      8.24.’06. - 8.25.’06.
    266. + +
    267. Tavern Diary Volume 62

      +
      8.24.’06. - 8.24.’06.
    268. + +
    269. Tavern Diary Volume 61

      +
      8.24.’06. - 8.24.’06.
    270. + +
    271. Tavern Diary Volume 60

      +
      8.23.’06. - 8.23.’06.
    272. + +
    273. Tavern Diary Volume 59

      +
      8.23.’06. - 8.23.’06.
    274. + +
    275. Tavern Diary Volume 58

      +
      8.22.’06. - 8.22.’06.
    276. + +
    277. Tavern Diary Volume 57

      +
      8.22.’06. - 8.22.’06.
    278. + +
    279. Tavern Diary Volume 56

      +
      8.22.’06. - 8.22.’06.
    280. + +
    281. Tavern Diary Volume 55

      +
      8.21.’06. - 8.21.’06.
    282. + +
    283. Tavern Diary Volume 54

      +
      8.20.’06. - 8.20.’06.
    284. + +
    285. Tavern Diary Volume 53

      +
      8.20.’06. - 8.20.’06.
    286. + +
    287. Tavern Diary Volume 52

      +
      8.19.’06. - 8.20.’06.
    288. + +
    289. Tavern Diary Volume 51

      +
      8.19.’06. - 8.19.’06.
    290. + +
    291. Tavern Diary Volume 50

      +
      8.18.’06. - 8.18.’06.
    292. + +
    293. Tavern Diary Volume 49

      +
      8.18.’06. - 8.18.’06.
    294. + +
    295. Tavern Diary Volume 48

      +
      8.18.’06. - 8.18.’06.
    296. + +
    297. Tavern Diary Volume 47

      +
      8.17.’06. - 8.18.’06.
    298. + +
    299. Tavern Diary Volume 46

      +
      8.17.’06. - 8.17.’06.
    300. + +
    301. Tavern Diary Volume 45

      +
      8.17.’06. - 8.17.’06.
    302. + +
    303. Tavern Diary Volume 44

      +
      8.13.’06. - 8.13.’06.
    304. + +
    305. Tavern Diary Volume 43

      +
      8.12.’06. - 8.12.’06.
    306. + +
    307. Tavern Diary Volume 42

      +
      8.12.’06. - 8.12.’06.
    308. + +
    309. Tavern Diary Volume 41

      +
      8.11.’06. - 8.11.’06.
    310. + +
    311. Tavern Diary Volume 40

      +
      8.11.’06. - 8.11.’06.
    312. + +
    313. Tavern Diary Volume 39

      +
      8.11.’06. - 8.11.’06.
    314. + +
    315. Tavern Diary Volume 38

      +
      8.10.’06. - 8.10.’06.
    316. + +
    317. Tavern Diary Volume 37

      +
      8.10.’06. - 8.10.’06.
    318. + +
    319. Tavern Diary Volume 36

      +
      8.10.’06. - 8.10.’06.
    320. + +
    321. Tavern Diary Volume 35

      +
      8.9.’06. - 8.9.’06.
    322. + +
    323. Tavern Diary Volume 34

      +
      8.8.’06. - 8.9.’06.
    324. + +
    325. Tavern Diary Volume 33

      +
      8.4.’06. - 8.4.’06.
    326. + +
    327. Tavern Diary Volume 32

      +
      8.2.’06. - 8.2.’06.
    328. + +
    329. Tavern Diary Volume 31

      +
      7.26.’06. - 8.2.’06.
    330. + +
    331. Tavern Diary Volume 30

      +
      7.23.’06. - 7.25.’06.
    332. + +
    333. Tavern Diary Volume 29

      +
      7.15.’06. - 7.23.’06.
    334. + +
    335. Tavern Diary Volume 28

      +
      7.4.’06. - 7.15.’06.
    336. + +
    337. Tavern Diary Volume 27

      +
      6.13.’06. - 6.30.’06.
    338. + +
    339. Tavern Diary Volume 26

      +
      6.4.’06. - 6.9.’06.
    340. + +
    341. Tavern Diary Volume 25

      +
      5.16.’06. - 6.4.’06.
    342. + +
    343. Tavern Diary Volume 24

      +
      4.25.’06. - 5.13.’06.
    344. + +
    345. Tavern Diary Volume 23

      +
      4.14.’06. - 4.23.’06.
    346. + +
    347. Tavern Diary Volume 22

      +
      4.1.’06. - 4.12.’06.
    348. + +
    349. Tavern Diary Volume 21

      +
      3.25.’06. - 3.25.’06.
    350. + +
    351. Tavern Diary Volume 20

      +
      2.11.’06. - 2.26.’06.
    352. + +
    353. Tavern Diary Volume 19

      +
      2.6.’06. - 2.6.’06.
    354. + +
    355. Tavern Diary Volume 18

      +
      1.29.’06. - 2.4.’06.
    356. + +
    357. Tavern Diary Volume 17

      +
      11.23.’05. - 1.26.’06.
    358. + +
    359. Tavern Diary Volume 16

      +
      10.18.’05. - 11.21.’05.
    360. + +
    361. Tavern Diary Volume 15

      +
      10.12.’05. - 10.12.’05.
    362. + +
    363. Tavern Diary Volume 14

      +
      10.10.’05. - 10.10.’05.
    364. + +
    365. Tavern Diary Volume 13

      +
      9.8.’05. - 9.30.’05.
    366. + +
    367. Tavern Diary Volume 12

      +
      8.28.’05. - 8.31.’05.
    368. + +
    369. Tavern Diary Volume 11

      +
      8.20.’05. - 8.27.’05.
    370. + +
    371. Tavern Diary Volume 10

      +
      6.28.’05. - 8.16.’05.
    372. + +
    373. Tavern Diary Volume 9

      +
      6.5.’05. - 6.9.’05.
    374. + +
    375. Tavern Diary Volume 8

      +
      5.27.’05. - 6.1.’05.
    376. + +
    377. Tavern Diary Volume 7

      +
      5.2.’05. - 5.27.’05.
    378. + +
    379. Tavern Diary Volume 6

      +
      3.3.’05. - 4.28.’05.
    380. + +
    381. Tavern Diary Volume 5

      +
      2.23.’05. - 2.23.’05.
    382. + +
    383. Tavern Diary Volume 4

      +
      8.25.’00. - 2.21.’05.
    384. + +
    385. Tavern Diary Volume 3

      +
      7.1.’00. - 8.20.’00.
    386. + +
    387. Tavern Diary Volume 2

      +
      10.11.’98. - 2.13.’00.
    388. + +
    389. Tavern Diary Volume 1

      +
      3.15.’98. - 4.22.’98.
    390. + +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/index.html.zh-cn.html b/htdocs/imacat/me/diary/index.html.zh-cn.html new file mode 120000 index 0000000..5ee9c39 --- /dev/null +++ b/htdocs/imacat/me/diary/index.html.zh-cn.html @@ -0,0 +1 @@ +index.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/index.html.zh-cn.xhtml b/htdocs/imacat/me/diary/index.html.zh-cn.xhtml new file mode 100644 index 0000000..2b46fbc --- /dev/null +++ b/htdocs/imacat/me/diary/index.html.zh-cn.xhtml @@ -0,0 +1,710 @@ + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日记 + + + + + + + +
    + +
    + + +

    旅舍日记

    + + + +

    目录

    + +
      +
    1. 旅舍日记 卷一百九十五

      +
      5.2.’14. - 5.3.’14.
    2. + +
    3. 旅舍日记 卷一百九十四

      +
      4.15.’14. - 4.28.’14.
    4. + +
    5. 旅舍日记 卷一百九十三

      +
      1.7.’14. - 4.10.’14.
    6. + +
    7. 旅舍日记 卷一百九十二

      +
      12.27.’13. - 1.1.’14.
    8. + +
    9. 旅舍日记 卷一百九十一

      +
      12.20.’13. - 12.27.’13.
    10. + +
    11. 旅舍日记 卷一百九十

      +
      12.4.’13. - 12.14.’13.
    12. + +
    13. 旅舍日记 卷一百八十九

      +
      11.14.’13. - 11.24.’13.
    14. + +
    15. 旅舍日记 卷一百八十八

      +
      7.15.’13. - 10.10.’13.
    16. + +
    17. 旅舍日记 卷一百八十七

      +
      7.9.’13. - 7.15.’13.
    18. + +
    19. 旅舍日记 卷一百八十六

      +
      7.8.’13. - 7.9.’13.
    20. + +
    21. 旅舍日记 卷一百八十五

      +
      6.28.’13. - 7.7.’13.
    22. + +
    23. 旅舍日记 卷一百八十四

      +
      6.26.’13. - 6.28.’13.
    24. + +
    25. 旅舍日记 卷一百八十三

      +
      5.16.’13. - 6.26.’13.
    26. + +
    27. 旅舍日记 卷一百八十二

      +
      1.29.’13. - 4.4.’13.
    28. + +
    29. 旅舍日记 卷一百八十一

      +
      6.3.’12. - 12.8.’12.
    30. + +
    31. 旅舍日记 卷一百八十

      +
      2.24.’12. - 3.27.’12.
    32. + +
    33. 旅舍日记 卷一百七十九

      +
      7.11.’11. - 1.13.’12.
    34. + +
    35. 旅舍日记 卷一百七十八

      +
      7.8.’11. - 7.8.’11.
    36. + +
    37. 旅舍日记 卷一百七十七

      +
      7.8.’11. - 7.8.’11.
    38. + +
    39. 旅舍日记 卷一百七十六

      +
      6.1.’11. - 6.1.’11.
    40. + +
    41. 旅舍日记 卷一百七十五

      +
      5.27.’11. - 5.27.’11.
    42. + +
    43. 旅舍日记 卷一百七十四

      +
      3.31.’11. - 5.18.’11.
    44. + +
    45. 旅舍日记 卷一百七十三

      +
      3.31.’11. - 3.31.’11.
    46. + +
    47. 旅舍日记 卷一百七十二

      +
      3.29.’11. - 3.29.’11.
    48. + +
    49. 旅舍日记 卷一百七十一

      +
      3.28.’11. - 3.28.’11.
    50. + +
    51. 旅舍日记 卷一百七十

      +
      3.28.’11. - 3.28.’11.
    52. + +
    53. 旅舍日记 卷一百六十九

      +
      3.28.’11. - 3.28.’11.
    54. + +
    55. 旅舍日记 卷一百六十八

      +
      3.25.’11. - 3.25.’11.
    56. + +
    57. 旅舍日记 卷一百六十七

      +
      3.24.’11. - 3.24.’11.
    58. + +
    59. 旅舍日记 卷一百六十六

      +
      3.24.’11. - 3.24.’11.
    60. + +
    61. 旅舍日记 卷一百六十五

      +
      3.24.’11. - 3.24.’11.
    62. + +
    63. 旅舍日记 卷一百六十四

      +
      1.6.’11. - 2.28.’11.
    64. + +
    65. 旅舍日记 卷一百六十三

      +
      12.3.’10. - 12.3.’10.
    66. + +
    67. 旅舍日记 卷一百六十二

      +
      10.26.’10. - 10.26.’10.
    68. + +
    69. 旅舍日记 卷一百六十一

      +
      7.18.’10. - 7.18.’10.
    70. + +
    71. 旅舍日记 卷一百六十

      +
      3.4.’10. - 5.24.’10.
    72. + +
    73. 旅舍日记 卷一百五十九

      +
      3.4.’10. - 3.4.’10.
    74. + +
    75. 旅舍日记 卷一百五十八

      +
      2.18.’10. - 2.18.’10.
    76. + +
    77. 旅舍日记 卷一百五十七

      +
      2.18.’10. - 2.18.’10.
    78. + +
    79. 旅舍日记 卷一百五十六

      +
      2.3.’10. - 2.3.’10.
    80. + +
    81. 旅舍日记 卷一百五十五

      +
      10.31.’09. - 1.5.’10.
    82. + +
    83. 旅舍日记 卷一百五十四

      +
      10.18.’09. - 10.18.’09.
    84. + +
    85. 旅舍日记 卷一百五十三

      +
      10.8.’09. - 10.8.’09.
    86. + +
    87. 旅舍日记 卷一百五十二

      +
      2.28.’09. - 2.28.’09.
    88. + +
    89. 旅舍日记 卷一百五十一

      +
      10.7.’08. - 10.7.’08.
    90. + +
    91. 旅舍日记 卷一百五十

      +
      10.7.’08. - 10.7.’08.
    92. + +
    93. 旅舍日记 卷一百四十九

      +
      9.9.’08. - 9.9.’08.
    94. + +
    95. 旅舍日记 卷一百四十八

      +
      7.24.’08. - 9.9.’08.
    96. + +
    97. 旅舍日记 卷一百四十七

      +
      6.21.’08. - 6.21.’08.
    98. + +
    99. 旅舍日记 卷一百四十六

      +
      4.8.’08. - 4.8.’08.
    100. + +
    101. 旅舍日记 卷一百四十五

      +
      2.4.’08. - 2.4.’08.
    102. + +
    103. 旅舍日记 卷一百四十四

      +
      1.31.’08. - 1.31.’08.
    104. + +
    105. 旅舍日记 卷一百四十三

      +
      1.30.’08. - 1.30.’08.
    106. + +
    107. 旅舍日记 卷一百四十二

      +
      1.30.’08. - 1.30.’08.
    108. + +
    109. 旅舍日记 卷一百四十一

      +
      12.10.’07. - 12.10.’07.
    110. + +
    111. 旅舍日记 卷一百四十

      +
      11.25.’07. - 11.25.’07.
    112. + +
    113. 旅舍日记 卷一百三十九

      +
      11.24.’07. - 11.24.’07.
    114. + +
    115. 旅舍日记 卷一百三十八

      +
      10.21.’07. - 11.22.’07.
    116. + +
    117. 旅舍日记 卷一百三十七

      +
      10.15.’07. - 10.21.’07.
    118. + +
    119. 旅舍日记 卷一百三十六

      +
      10.10.’07. - 10.10.’07.
    120. + +
    121. 旅舍日记 卷一百三十五

      +
      10.1.’07. - 10.3.’07.
    122. + +
    123. 旅舍日记 卷一百三十四

      +
      9.27.’07. - 9.27.’07.
    124. + +
    125. 旅舍日记 卷一百三十三

      +
      9.21.’07. - 9.21.’07.
    126. + +
    127. 旅舍日记 卷一百三十二

      +
      9.20.’07. - 9.21.’07.
    128. + +
    129. 旅舍日记 卷一百三十一

      +
      9.18.’07. - 9.20.’07.
    130. + +
    131. 旅舍日记 卷一百三十

      +
      9.18.’07. - 9.18.’07.
    132. + +
    133. 旅舍日记 卷一百二十九

      +
      9.11.’07. - 9.11.’07.
    134. + +
    135. 旅舍日记 卷一百二十八

      +
      9.11.’07. - 9.11.’07.
    136. + +
    137. 旅舍日记 卷一百二十七

      +
      9.4.’07. - 9.7.’07.
    138. + +
    139. 旅舍日记 卷一百二十六

      +
      8.28.’07. - 8.28.’07.
    140. + +
    141. 旅舍日记 卷一百二十五

      +
      8.22.’07. - 8.22.’07.
    142. + +
    143. 旅舍日记 卷一百二十四

      +
      8.16.’07. - 8.17.’07.
    144. + +
    145. 旅舍日记 卷一百二十三

      +
      8.14.’07. - 8.14.’07.
    146. + +
    147. 旅舍日记 卷一百二十二

      +
      8.13.’07. - 8.13.’07.
    148. + +
    149. 旅舍日记 卷一百二十一

      +
      7.15.’07. - 8.3.’07.
    150. + +
    151. 旅舍日记 卷一百二十

      +
      6.22.’07. - 6.30.’07.
    152. + +
    153. 旅舍日记 卷一百一十九

      +
      6.21.’07. - 6.21.’07.
    154. + +
    155. 旅舍日记 卷一百一十八

      +
      6.20.’07. - 6.20.’07.
    156. + +
    157. 旅舍日记 卷一百一十七

      +
      6.19.’07. - 6.19.’07.
    158. + +
    159. 旅舍日记 卷一百一十六

      +
      6.18.’07. - 6.18.’07.
    160. + +
    161. 旅舍日记 卷一百一十五

      +
      6.18.’07. - 6.18.’07.
    162. + +
    163. 旅舍日记 卷一百一十四

      +
      6.11.’07. - 6.11.’07.
    164. + +
    165. 旅舍日记 卷一百一十三

      +
      6.5.’07. - 6.5.’07.
    166. + +
    167. 旅舍日记 卷一百一十二

      +
      4.1.’07. - 5.24.’07.
    168. + +
    169. 旅舍日记 卷一百一十一

      +
      3.30.’07. - 3.30.’07.
    170. + +
    171. 旅舍日记 卷一百一十

      +
      2.10.’07. - 3.14.’07.
    172. + +
    173. 旅舍日记 卷一百零九

      +
      2.8.’07. - 2.8.’07.
    174. + +
    175. 旅舍日记 卷一百零八

      +
      2.8.’07. - 2.8.’07.
    176. + +
    177. 旅舍日记 卷一百零七

      +
      2.5.’07. - 2.5.’07.
    178. + +
    179. 旅舍日记 卷一百零六

      +
      2.3.’07. - 2.3.’07.
    180. + +
    181. 旅舍日记 卷一百零五

      +
      2.3.’07. - 2.3.’07.
    182. + +
    183. 旅舍日记 卷一百零四

      +
      2.3.’07. - 2.3.’07.
    184. + +
    185. 旅舍日记 卷一百零三

      +
      2.3.’07. - 2.3.’07.
    186. + +
    187. 旅舍日记 卷一百零二

      +
      1.14.’07. - 2.1.’07.
    188. + +
    189. 旅舍日记 卷一百零一

      +
      1.12.’07. - 1.14.’07.
    190. + +
    191. 旅舍日记 卷一百

      +
      1.7.’07. - 1.8.’07.
    192. + +
    193. 旅舍日记 卷九十九

      +
      12.26.’06. - 12.26.’06.
    194. + +
    195. 旅舍日记 卷九十八

      +
      12.25.’06. - 12.25.’06.
    196. + +
    197. 旅舍日记 卷九十七

      +
      12.5.’06. - 12.9.’06.
    198. + +
    199. 旅舍日记 卷九十六

      +
      12.5.’06. - 12.5.’06.
    200. + +
    201. 旅舍日记 卷九十五

      +
      12.5.’06. - 12.5.’06.
    202. + +
    203. 旅舍日记 卷九十四

      +
      11.17.’06. - 11.24.’06.
    204. + +
    205. 旅舍日记 卷九十三

      +
      11.8.’06. - 11.13.’06.
    206. + +
    207. 旅舍日记 卷九十二

      +
      11.6.’06. - 11.6.’06.
    208. + +
    209. 旅舍日记 卷九十一

      +
      11.6.’06. - 11.6.’06.
    210. + +
    211. 旅舍日记 卷九十

      +
      11.3.’06. - 11.3.’06.
    212. + +
    213. 旅舍日记 卷八十九

      +
      11.2.’06. - 11.2.’06.
    214. + +
    215. 旅舍日记 卷八十八

      +
      11.2.’06. - 11.2.’06.
    216. + +
    217. 旅舍日记 卷八十七

      +
      10.30.’06. - 10.30.’06.
    218. + +
    219. 旅舍日记 卷八十六

      +
      10.12.’06. - 10.21.’06.
    220. + +
    221. 旅舍日记 卷八十五

      +
      10.7.’06. - 10.12.’06.
    222. + +
    223. 旅舍日记 卷八十四

      +
      10.7.’06. - 10.7.’06.
    224. + +
    225. 旅舍日记 卷八十三

      +
      10.6.’06. - 10.6.’06.
    226. + +
    227. 旅舍日记 卷八十二

      +
      10.3.’06. - 10.3.’06.
    228. + +
    229. 旅舍日记 卷八十一

      +
      9.29.’06. - 10.1.’06.
    230. + +
    231. 旅舍日记 卷八十

      +
      9.25.’06. - 9.25.’06.
    232. + +
    233. 旅舍日记 卷七十九

      +
      9.24.’06. - 9.24.’06.
    234. + +
    235. 旅舍日记 卷七十八

      +
      9.22.’06. - 9.22.’06.
    236. + +
    237. 旅舍日记 卷七十七

      +
      9.18.’06. - 9.18.’06.
    238. + +
    239. 旅舍日记 卷七十六

      +
      9.17.’06. - 9.17.’06.
    240. + +
    241. 旅舍日记 卷七十五

      +
      9.17.’06. - 9.17.’06.
    242. + +
    243. 旅舍日记 卷七十四

      +
      9.17.’06. - 9.17.’06.
    244. + +
    245. 旅舍日记 卷七十三

      +
      9.17.’06. - 9.17.’06.
    246. + +
    247. 旅舍日记 卷七十二

      +
      9.16.’06. - 9.16.’06.
    248. + +
    249. 旅舍日记 卷七十一

      +
      9.16.’06. - 9.16.’06.
    250. + +
    251. 旅舍日记 卷七十

      +
      9.15.’06. - 9.16.’06.
    252. + +
    253. 旅舍日记 卷六十九

      +
      9.12.’06. - 9.12.’06.
    254. + +
    255. 旅舍日记 卷六十八

      +
      8.27.’06. - 8.31.’06.
    256. + +
    257. 旅舍日记 卷六十七

      +
      8.27.’06. - 8.27.’06.
    258. + +
    259. 旅舍日记 卷六十六

      +
      8.27.’06. - 8.27.’06.
    260. + +
    261. 旅舍日记 卷六十五

      +
      8.26.’06. - 8.27.’06.
    262. + +
    263. 旅舍日记 卷六十四

      +
      8.26.’06. - 8.26.’06.
    264. + +
    265. 旅舍日记 卷六十三

      +
      8.24.’06. - 8.25.’06.
    266. + +
    267. 旅舍日记 卷六十二

      +
      8.24.’06. - 8.24.’06.
    268. + +
    269. 旅舍日记 卷六十一

      +
      8.24.’06. - 8.24.’06.
    270. + +
    271. 旅舍日记 卷六十

      +
      8.23.’06. - 8.23.’06.
    272. + +
    273. 旅舍日记 卷五十九

      +
      8.23.’06. - 8.23.’06.
    274. + +
    275. 旅舍日记 卷五十八

      +
      8.22.’06. - 8.22.’06.
    276. + +
    277. 旅舍日记 卷五十七

      +
      8.22.’06. - 8.22.’06.
    278. + +
    279. 旅舍日记 卷五十六

      +
      8.22.’06. - 8.22.’06.
    280. + +
    281. 旅舍日记 卷五十五

      +
      8.21.’06. - 8.21.’06.
    282. + +
    283. 旅舍日记 卷五十四

      +
      8.20.’06. - 8.20.’06.
    284. + +
    285. 旅舍日记 卷五十三

      +
      8.20.’06. - 8.20.’06.
    286. + +
    287. 旅舍日记 卷五十二

      +
      8.19.’06. - 8.20.’06.
    288. + +
    289. 旅舍日记 卷五十一

      +
      8.19.’06. - 8.19.’06.
    290. + +
    291. 旅舍日记 卷五十

      +
      8.18.’06. - 8.18.’06.
    292. + +
    293. 旅舍日记 卷四十九

      +
      8.18.’06. - 8.18.’06.
    294. + +
    295. 旅舍日记 卷四十八

      +
      8.18.’06. - 8.18.’06.
    296. + +
    297. 旅舍日记 卷四十七

      +
      8.17.’06. - 8.18.’06.
    298. + +
    299. 旅舍日记 卷四十六

      +
      8.17.’06. - 8.17.’06.
    300. + +
    301. 旅舍日记 卷四十五

      +
      8.17.’06. - 8.17.’06.
    302. + +
    303. 旅舍日记 卷四十四

      +
      8.13.’06. - 8.13.’06.
    304. + +
    305. 旅舍日记 卷四十三

      +
      8.12.’06. - 8.12.’06.
    306. + +
    307. 旅舍日记 卷四十二

      +
      8.12.’06. - 8.12.’06.
    308. + +
    309. 旅舍日记 卷四十一

      +
      8.11.’06. - 8.11.’06.
    310. + +
    311. 旅舍日记 卷四十

      +
      8.11.’06. - 8.11.’06.
    312. + +
    313. 旅舍日记 卷三十九

      +
      8.11.’06. - 8.11.’06.
    314. + +
    315. 旅舍日记 卷三十八

      +
      8.10.’06. - 8.10.’06.
    316. + +
    317. 旅舍日记 卷三十七

      +
      8.10.’06. - 8.10.’06.
    318. + +
    319. 旅舍日记 卷三十六

      +
      8.10.’06. - 8.10.’06.
    320. + +
    321. 旅舍日记 卷三十五

      +
      8.9.’06. - 8.9.’06.
    322. + +
    323. 旅舍日记 卷三十四

      +
      8.8.’06. - 8.9.’06.
    324. + +
    325. 旅舍日记 卷三十三

      +
      8.4.’06. - 8.4.’06.
    326. + +
    327. 旅舍日记 卷三十二

      +
      8.2.’06. - 8.2.’06.
    328. + +
    329. 旅舍日记 卷三十一

      +
      7.26.’06. - 8.2.’06.
    330. + +
    331. 旅舍日记 卷三十

      +
      7.23.’06. - 7.25.’06.
    332. + +
    333. 旅舍日记 卷二十九

      +
      7.15.’06. - 7.23.’06.
    334. + +
    335. 旅舍日记 卷二十八

      +
      7.4.’06. - 7.15.’06.
    336. + +
    337. 旅舍日记 卷二十七

      +
      6.13.’06. - 6.30.’06.
    338. + +
    339. 旅舍日记 卷二十六

      +
      6.4.’06. - 6.9.’06.
    340. + +
    341. 旅舍日记 卷二十五

      +
      5.16.’06. - 6.4.’06.
    342. + +
    343. 旅舍日记 卷二十四

      +
      4.25.’06. - 5.13.’06.
    344. + +
    345. 旅舍日记 卷二十三

      +
      4.14.’06. - 4.23.’06.
    346. + +
    347. 旅舍日记 卷二十二

      +
      4.1.’06. - 4.12.’06.
    348. + +
    349. 旅舍日记 卷二十一

      +
      3.25.’06. - 3.25.’06.
    350. + +
    351. 旅舍日记 卷二十

      +
      2.11.’06. - 2.26.’06.
    352. + +
    353. 旅舍日记 卷十九

      +
      2.6.’06. - 2.6.’06.
    354. + +
    355. 旅舍日记 卷十八

      +
      1.29.’06. - 2.4.’06.
    356. + +
    357. 旅舍日记 卷十七

      +
      11.23.’05. - 1.26.’06.
    358. + +
    359. 旅舍日记 卷十六

      +
      10.18.’05. - 11.21.’05.
    360. + +
    361. 旅舍日记 卷十五

      +
      10.12.’05. - 10.12.’05.
    362. + +
    363. 旅舍日记 卷十四

      +
      10.10.’05. - 10.10.’05.
    364. + +
    365. 旅舍日记 卷十三

      +
      9.8.’05. - 9.30.’05.
    366. + +
    367. 旅舍日记 卷十二

      +
      8.28.’05. - 8.31.’05.
    368. + +
    369. 旅舍日记 卷十一

      +
      8.20.’05. - 8.27.’05.
    370. + +
    371. 旅舍日记 卷十

      +
      6.28.’05. - 8.16.’05.
    372. + +
    373. 旅舍日记 卷九

      +
      6.5.’05. - 6.9.’05.
    374. + +
    375. 旅舍日记 卷八

      +
      5.27.’05. - 6.1.’05.
    376. + +
    377. 旅舍日记 卷七

      +
      5.2.’05. - 5.27.’05.
    378. + +
    379. 旅舍日记 卷六

      +
      3.3.’05. - 4.28.’05.
    380. + +
    381. 旅舍日记 卷五

      +
      2.23.’05. - 2.23.’05.
    382. + +
    383. 旅舍日记 卷四

      +
      8.25.’00. - 2.21.’05.
    384. + +
    385. 旅舍日记 卷三

      +
      7.1.’00. - 8.20.’00.
    386. + +
    387. 旅舍日记 卷二

      +
      10.11.’98. - 2.13.’00.
    388. + +
    389. 旅舍日记 卷一

      +
      3.15.’98. - 4.22.’98.
    390. + +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/index.html.zh-tw.html b/htdocs/imacat/me/diary/index.html.zh-tw.html new file mode 120000 index 0000000..6c1b76e --- /dev/null +++ b/htdocs/imacat/me/diary/index.html.zh-tw.html @@ -0,0 +1 @@ +index.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/index.html.zh-tw.xhtml b/htdocs/imacat/me/diary/index.html.zh-tw.xhtml new file mode 100644 index 0000000..3f7c2ce --- /dev/null +++ b/htdocs/imacat/me/diary/index.html.zh-tw.xhtml @@ -0,0 +1,710 @@ + + + + + + + + + + + + + + + + + + + + + + + + +旅舍日記 + + + + + + + +
    + +
    + + +

    旅舍日記

    + + + +

    目錄

    + +
      +
    1. 旅舍日記 卷一百九十五

      +
      5.2.’14. - 5.3.’14.
    2. + +
    3. 旅舍日記 卷一百九十四

      +
      4.15.’14. - 4.28.’14.
    4. + +
    5. 旅舍日記 卷一百九十三

      +
      1.7.’14. - 4.10.’14.
    6. + +
    7. 旅舍日記 卷一百九十二

      +
      12.27.’13. - 1.1.’14.
    8. + +
    9. 旅舍日記 卷一百九十一

      +
      12.20.’13. - 12.27.’13.
    10. + +
    11. 旅舍日記 卷一百九十

      +
      12.4.’13. - 12.14.’13.
    12. + +
    13. 旅舍日記 卷一百八十九

      +
      11.14.’13. - 11.24.’13.
    14. + +
    15. 旅舍日記 卷一百八十八

      +
      7.15.’13. - 10.10.’13.
    16. + +
    17. 旅舍日記 卷一百八十七

      +
      7.9.’13. - 7.15.’13.
    18. + +
    19. 旅舍日記 卷一百八十六

      +
      7.8.’13. - 7.9.’13.
    20. + +
    21. 旅舍日記 卷一百八十五

      +
      6.28.’13. - 7.7.’13.
    22. + +
    23. 旅舍日記 卷一百八十四

      +
      6.26.’13. - 6.28.’13.
    24. + +
    25. 旅舍日記 卷一百八十三

      +
      5.16.’13. - 6.26.’13.
    26. + +
    27. 旅舍日記 卷一百八十二

      +
      1.29.’13. - 4.4.’13.
    28. + +
    29. 旅舍日記 卷一百八十一

      +
      6.3.’12. - 12.8.’12.
    30. + +
    31. 旅舍日記 卷一百八十

      +
      2.24.’12. - 3.27.’12.
    32. + +
    33. 旅舍日記 卷一百七十九

      +
      7.11.’11. - 1.13.’12.
    34. + +
    35. 旅舍日記 卷一百七十八

      +
      7.8.’11. - 7.8.’11.
    36. + +
    37. 旅舍日記 卷一百七十七

      +
      7.8.’11. - 7.8.’11.
    38. + +
    39. 旅舍日記 卷一百七十六

      +
      6.1.’11. - 6.1.’11.
    40. + +
    41. 旅舍日記 卷一百七十五

      +
      5.27.’11. - 5.27.’11.
    42. + +
    43. 旅舍日記 卷一百七十四

      +
      3.31.’11. - 5.18.’11.
    44. + +
    45. 旅舍日記 卷一百七十三

      +
      3.31.’11. - 3.31.’11.
    46. + +
    47. 旅舍日記 卷一百七十二

      +
      3.29.’11. - 3.29.’11.
    48. + +
    49. 旅舍日記 卷一百七十一

      +
      3.28.’11. - 3.28.’11.
    50. + +
    51. 旅舍日記 卷一百七十

      +
      3.28.’11. - 3.28.’11.
    52. + +
    53. 旅舍日記 卷一百六十九

      +
      3.28.’11. - 3.28.’11.
    54. + +
    55. 旅舍日記 卷一百六十八

      +
      3.25.’11. - 3.25.’11.
    56. + +
    57. 旅舍日記 卷一百六十七

      +
      3.24.’11. - 3.24.’11.
    58. + +
    59. 旅舍日記 卷一百六十六

      +
      3.24.’11. - 3.24.’11.
    60. + +
    61. 旅舍日記 卷一百六十五

      +
      3.24.’11. - 3.24.’11.
    62. + +
    63. 旅舍日記 卷一百六十四

      +
      1.6.’11. - 2.28.’11.
    64. + +
    65. 旅舍日記 卷一百六十三

      +
      12.3.’10. - 12.3.’10.
    66. + +
    67. 旅舍日記 卷一百六十二

      +
      10.26.’10. - 10.26.’10.
    68. + +
    69. 旅舍日記 卷一百六十一

      +
      7.18.’10. - 7.18.’10.
    70. + +
    71. 旅舍日記 卷一百六十

      +
      3.4.’10. - 5.24.’10.
    72. + +
    73. 旅舍日記 卷一百五十九

      +
      3.4.’10. - 3.4.’10.
    74. + +
    75. 旅舍日記 卷一百五十八

      +
      2.18.’10. - 2.18.’10.
    76. + +
    77. 旅舍日記 卷一百五十七

      +
      2.18.’10. - 2.18.’10.
    78. + +
    79. 旅舍日記 卷一百五十六

      +
      2.3.’10. - 2.3.’10.
    80. + +
    81. 旅舍日記 卷一百五十五

      +
      10.31.’09. - 1.5.’10.
    82. + +
    83. 旅舍日記 卷一百五十四

      +
      10.18.’09. - 10.18.’09.
    84. + +
    85. 旅舍日記 卷一百五十三

      +
      10.8.’09. - 10.8.’09.
    86. + +
    87. 旅舍日記 卷一百五十二

      +
      2.28.’09. - 2.28.’09.
    88. + +
    89. 旅舍日記 卷一百五十一

      +
      10.7.’08. - 10.7.’08.
    90. + +
    91. 旅舍日記 卷一百五十

      +
      10.7.’08. - 10.7.’08.
    92. + +
    93. 旅舍日記 卷一百四十九

      +
      9.9.’08. - 9.9.’08.
    94. + +
    95. 旅舍日記 卷一百四十八

      +
      7.24.’08. - 9.9.’08.
    96. + +
    97. 旅舍日記 卷一百四十七

      +
      6.21.’08. - 6.21.’08.
    98. + +
    99. 旅舍日記 卷一百四十六

      +
      4.8.’08. - 4.8.’08.
    100. + +
    101. 旅舍日記 卷一百四十五

      +
      2.4.’08. - 2.4.’08.
    102. + +
    103. 旅舍日記 卷一百四十四

      +
      1.31.’08. - 1.31.’08.
    104. + +
    105. 旅舍日記 卷一百四十三

      +
      1.30.’08. - 1.30.’08.
    106. + +
    107. 旅舍日記 卷一百四十二

      +
      1.30.’08. - 1.30.’08.
    108. + +
    109. 旅舍日記 卷一百四十一

      +
      12.10.’07. - 12.10.’07.
    110. + +
    111. 旅舍日記 卷一百四十

      +
      11.25.’07. - 11.25.’07.
    112. + +
    113. 旅舍日記 卷一百三十九

      +
      11.24.’07. - 11.24.’07.
    114. + +
    115. 旅舍日記 卷一百三十八

      +
      10.21.’07. - 11.22.’07.
    116. + +
    117. 旅舍日記 卷一百三十七

      +
      10.15.’07. - 10.21.’07.
    118. + +
    119. 旅舍日記 卷一百三十六

      +
      10.10.’07. - 10.10.’07.
    120. + +
    121. 旅舍日記 卷一百三十五

      +
      10.1.’07. - 10.3.’07.
    122. + +
    123. 旅舍日記 卷一百三十四

      +
      9.27.’07. - 9.27.’07.
    124. + +
    125. 旅舍日記 卷一百三十三

      +
      9.21.’07. - 9.21.’07.
    126. + +
    127. 旅舍日記 卷一百三十二

      +
      9.20.’07. - 9.21.’07.
    128. + +
    129. 旅舍日記 卷一百三十一

      +
      9.18.’07. - 9.20.’07.
    130. + +
    131. 旅舍日記 卷一百三十

      +
      9.18.’07. - 9.18.’07.
    132. + +
    133. 旅舍日記 卷一百二十九

      +
      9.11.’07. - 9.11.’07.
    134. + +
    135. 旅舍日記 卷一百二十八

      +
      9.11.’07. - 9.11.’07.
    136. + +
    137. 旅舍日記 卷一百二十七

      +
      9.4.’07. - 9.7.’07.
    138. + +
    139. 旅舍日記 卷一百二十六

      +
      8.28.’07. - 8.28.’07.
    140. + +
    141. 旅舍日記 卷一百二十五

      +
      8.22.’07. - 8.22.’07.
    142. + +
    143. 旅舍日記 卷一百二十四

      +
      8.16.’07. - 8.17.’07.
    144. + +
    145. 旅舍日記 卷一百二十三

      +
      8.14.’07. - 8.14.’07.
    146. + +
    147. 旅舍日記 卷一百二十二

      +
      8.13.’07. - 8.13.’07.
    148. + +
    149. 旅舍日記 卷一百二十一

      +
      7.15.’07. - 8.3.’07.
    150. + +
    151. 旅舍日記 卷一百二十

      +
      6.22.’07. - 6.30.’07.
    152. + +
    153. 旅舍日記 卷一百一十九

      +
      6.21.’07. - 6.21.’07.
    154. + +
    155. 旅舍日記 卷一百一十八

      +
      6.20.’07. - 6.20.’07.
    156. + +
    157. 旅舍日記 卷一百一十七

      +
      6.19.’07. - 6.19.’07.
    158. + +
    159. 旅舍日記 卷一百一十六

      +
      6.18.’07. - 6.18.’07.
    160. + +
    161. 旅舍日記 卷一百一十五

      +
      6.18.’07. - 6.18.’07.
    162. + +
    163. 旅舍日記 卷一百一十四

      +
      6.11.’07. - 6.11.’07.
    164. + +
    165. 旅舍日記 卷一百一十三

      +
      6.5.’07. - 6.5.’07.
    166. + +
    167. 旅舍日記 卷一百一十二

      +
      4.1.’07. - 5.24.’07.
    168. + +
    169. 旅舍日記 卷一百一十一

      +
      3.30.’07. - 3.30.’07.
    170. + +
    171. 旅舍日記 卷一百一十

      +
      2.10.’07. - 3.14.’07.
    172. + +
    173. 旅舍日記 卷一百零九

      +
      2.8.’07. - 2.8.’07.
    174. + +
    175. 旅舍日記 卷一百零八

      +
      2.8.’07. - 2.8.’07.
    176. + +
    177. 旅舍日記 卷一百零七

      +
      2.5.’07. - 2.5.’07.
    178. + +
    179. 旅舍日記 卷一百零六

      +
      2.3.’07. - 2.3.’07.
    180. + +
    181. 旅舍日記 卷一百零五

      +
      2.3.’07. - 2.3.’07.
    182. + +
    183. 旅舍日記 卷一百零四

      +
      2.3.’07. - 2.3.’07.
    184. + +
    185. 旅舍日記 卷一百零三

      +
      2.3.’07. - 2.3.’07.
    186. + +
    187. 旅舍日記 卷一百零二

      +
      1.14.’07. - 2.1.’07.
    188. + +
    189. 旅舍日記 卷一百零一

      +
      1.12.’07. - 1.14.’07.
    190. + +
    191. 旅舍日記 卷一百

      +
      1.7.’07. - 1.8.’07.
    192. + +
    193. 旅舍日記 卷九十九

      +
      12.26.’06. - 12.26.’06.
    194. + +
    195. 旅舍日記 卷九十八

      +
      12.25.’06. - 12.25.’06.
    196. + +
    197. 旅舍日記 卷九十七

      +
      12.5.’06. - 12.9.’06.
    198. + +
    199. 旅舍日記 卷九十六

      +
      12.5.’06. - 12.5.’06.
    200. + +
    201. 旅舍日記 卷九十五

      +
      12.5.’06. - 12.5.’06.
    202. + +
    203. 旅舍日記 卷九十四

      +
      11.17.’06. - 11.24.’06.
    204. + +
    205. 旅舍日記 卷九十三

      +
      11.8.’06. - 11.13.’06.
    206. + +
    207. 旅舍日記 卷九十二

      +
      11.6.’06. - 11.6.’06.
    208. + +
    209. 旅舍日記 卷九十一

      +
      11.6.’06. - 11.6.’06.
    210. + +
    211. 旅舍日記 卷九十

      +
      11.3.’06. - 11.3.’06.
    212. + +
    213. 旅舍日記 卷八十九

      +
      11.2.’06. - 11.2.’06.
    214. + +
    215. 旅舍日記 卷八十八

      +
      11.2.’06. - 11.2.’06.
    216. + +
    217. 旅舍日記 卷八十七

      +
      10.30.’06. - 10.30.’06.
    218. + +
    219. 旅舍日記 卷八十六

      +
      10.12.’06. - 10.21.’06.
    220. + +
    221. 旅舍日記 卷八十五

      +
      10.7.’06. - 10.12.’06.
    222. + +
    223. 旅舍日記 卷八十四

      +
      10.7.’06. - 10.7.’06.
    224. + +
    225. 旅舍日記 卷八十三

      +
      10.6.’06. - 10.6.’06.
    226. + +
    227. 旅舍日記 卷八十二

      +
      10.3.’06. - 10.3.’06.
    228. + +
    229. 旅舍日記 卷八十一

      +
      9.29.’06. - 10.1.’06.
    230. + +
    231. 旅舍日記 卷八十

      +
      9.25.’06. - 9.25.’06.
    232. + +
    233. 旅舍日記 卷七十九

      +
      9.24.’06. - 9.24.’06.
    234. + +
    235. 旅舍日記 卷七十八

      +
      9.22.’06. - 9.22.’06.
    236. + +
    237. 旅舍日記 卷七十七

      +
      9.18.’06. - 9.18.’06.
    238. + +
    239. 旅舍日記 卷七十六

      +
      9.17.’06. - 9.17.’06.
    240. + +
    241. 旅舍日記 卷七十五

      +
      9.17.’06. - 9.17.’06.
    242. + +
    243. 旅舍日記 卷七十四

      +
      9.17.’06. - 9.17.’06.
    244. + +
    245. 旅舍日記 卷七十三

      +
      9.17.’06. - 9.17.’06.
    246. + +
    247. 旅舍日記 卷七十二

      +
      9.16.’06. - 9.16.’06.
    248. + +
    249. 旅舍日記 卷七十一

      +
      9.16.’06. - 9.16.’06.
    250. + +
    251. 旅舍日記 卷七十

      +
      9.15.’06. - 9.16.’06.
    252. + +
    253. 旅舍日記 卷六十九

      +
      9.12.’06. - 9.12.’06.
    254. + +
    255. 旅舍日記 卷六十八

      +
      8.27.’06. - 8.31.’06.
    256. + +
    257. 旅舍日記 卷六十七

      +
      8.27.’06. - 8.27.’06.
    258. + +
    259. 旅舍日記 卷六十六

      +
      8.27.’06. - 8.27.’06.
    260. + +
    261. 旅舍日記 卷六十五

      +
      8.26.’06. - 8.27.’06.
    262. + +
    263. 旅舍日記 卷六十四

      +
      8.26.’06. - 8.26.’06.
    264. + +
    265. 旅舍日記 卷六十三

      +
      8.24.’06. - 8.25.’06.
    266. + +
    267. 旅舍日記 卷六十二

      +
      8.24.’06. - 8.24.’06.
    268. + +
    269. 旅舍日記 卷六十一

      +
      8.24.’06. - 8.24.’06.
    270. + +
    271. 旅舍日記 卷六十

      +
      8.23.’06. - 8.23.’06.
    272. + +
    273. 旅舍日記 卷五十九

      +
      8.23.’06. - 8.23.’06.
    274. + +
    275. 旅舍日記 卷五十八

      +
      8.22.’06. - 8.22.’06.
    276. + +
    277. 旅舍日記 卷五十七

      +
      8.22.’06. - 8.22.’06.
    278. + +
    279. 旅舍日記 卷五十六

      +
      8.22.’06. - 8.22.’06.
    280. + +
    281. 旅舍日記 卷五十五

      +
      8.21.’06. - 8.21.’06.
    282. + +
    283. 旅舍日記 卷五十四

      +
      8.20.’06. - 8.20.’06.
    284. + +
    285. 旅舍日記 卷五十三

      +
      8.20.’06. - 8.20.’06.
    286. + +
    287. 旅舍日記 卷五十二

      +
      8.19.’06. - 8.20.’06.
    288. + +
    289. 旅舍日記 卷五十一

      +
      8.19.’06. - 8.19.’06.
    290. + +
    291. 旅舍日記 卷五十

      +
      8.18.’06. - 8.18.’06.
    292. + +
    293. 旅舍日記 卷四十九

      +
      8.18.’06. - 8.18.’06.
    294. + +
    295. 旅舍日記 卷四十八

      +
      8.18.’06. - 8.18.’06.
    296. + +
    297. 旅舍日記 卷四十七

      +
      8.17.’06. - 8.18.’06.
    298. + +
    299. 旅舍日記 卷四十六

      +
      8.17.’06. - 8.17.’06.
    300. + +
    301. 旅舍日記 卷四十五

      +
      8.17.’06. - 8.17.’06.
    302. + +
    303. 旅舍日記 卷四十四

      +
      8.13.’06. - 8.13.’06.
    304. + +
    305. 旅舍日記 卷四十三

      +
      8.12.’06. - 8.12.’06.
    306. + +
    307. 旅舍日記 卷四十二

      +
      8.12.’06. - 8.12.’06.
    308. + +
    309. 旅舍日記 卷四十一

      +
      8.11.’06. - 8.11.’06.
    310. + +
    311. 旅舍日記 卷四十

      +
      8.11.’06. - 8.11.’06.
    312. + +
    313. 旅舍日記 卷三十九

      +
      8.11.’06. - 8.11.’06.
    314. + +
    315. 旅舍日記 卷三十八

      +
      8.10.’06. - 8.10.’06.
    316. + +
    317. 旅舍日記 卷三十七

      +
      8.10.’06. - 8.10.’06.
    318. + +
    319. 旅舍日記 卷三十六

      +
      8.10.’06. - 8.10.’06.
    320. + +
    321. 旅舍日記 卷三十五

      +
      8.9.’06. - 8.9.’06.
    322. + +
    323. 旅舍日記 卷三十四

      +
      8.8.’06. - 8.9.’06.
    324. + +
    325. 旅舍日記 卷三十三

      +
      8.4.’06. - 8.4.’06.
    326. + +
    327. 旅舍日記 卷三十二

      +
      8.2.’06. - 8.2.’06.
    328. + +
    329. 旅舍日記 卷三十一

      +
      7.26.’06. - 8.2.’06.
    330. + +
    331. 旅舍日記 卷三十

      +
      7.23.’06. - 7.25.’06.
    332. + +
    333. 旅舍日記 卷二十九

      +
      7.15.’06. - 7.23.’06.
    334. + +
    335. 旅舍日記 卷二十八

      +
      7.4.’06. - 7.15.’06.
    336. + +
    337. 旅舍日記 卷二十七

      +
      6.13.’06. - 6.30.’06.
    338. + +
    339. 旅舍日記 卷二十六

      +
      6.4.’06. - 6.9.’06.
    340. + +
    341. 旅舍日記 卷二十五

      +
      5.16.’06. - 6.4.’06.
    342. + +
    343. 旅舍日記 卷二十四

      +
      4.25.’06. - 5.13.’06.
    344. + +
    345. 旅舍日記 卷二十三

      +
      4.14.’06. - 4.23.’06.
    346. + +
    347. 旅舍日記 卷二十二

      +
      4.1.’06. - 4.12.’06.
    348. + +
    349. 旅舍日記 卷二十一

      +
      3.25.’06. - 3.25.’06.
    350. + +
    351. 旅舍日記 卷二十

      +
      2.11.’06. - 2.26.’06.
    352. + +
    353. 旅舍日記 卷十九

      +
      2.6.’06. - 2.6.’06.
    354. + +
    355. 旅舍日記 卷十八

      +
      1.29.’06. - 2.4.’06.
    356. + +
    357. 旅舍日記 卷十七

      +
      11.23.’05. - 1.26.’06.
    358. + +
    359. 旅舍日記 卷十六

      +
      10.18.’05. - 11.21.’05.
    360. + +
    361. 旅舍日記 卷十五

      +
      10.12.’05. - 10.12.’05.
    362. + +
    363. 旅舍日記 卷十四

      +
      10.10.’05. - 10.10.’05.
    364. + +
    365. 旅舍日記 卷十三

      +
      9.8.’05. - 9.30.’05.
    366. + +
    367. 旅舍日記 卷十二

      +
      8.28.’05. - 8.31.’05.
    368. + +
    369. 旅舍日記 卷十一

      +
      8.20.’05. - 8.27.’05.
    370. + +
    371. 旅舍日記 卷十

      +
      6.28.’05. - 8.16.’05.
    372. + +
    373. 旅舍日記 卷九

      +
      6.5.’05. - 6.9.’05.
    374. + +
    375. 旅舍日記 卷八

      +
      5.27.’05. - 6.1.’05.
    376. + +
    377. 旅舍日記 卷七

      +
      5.2.’05. - 5.27.’05.
    378. + +
    379. 旅舍日記 卷六

      +
      3.3.’05. - 4.28.’05.
    380. + +
    381. 旅舍日記 卷五

      +
      2.23.’05. - 2.23.’05.
    382. + +
    383. 旅舍日記 卷四

      +
      8.25.’00. - 2.21.’05.
    384. + +
    385. 旅舍日記 卷三

      +
      7.1.’00. - 8.20.’00.
    386. + +
    387. 旅舍日記 卷二

      +
      10.11.’98. - 2.13.’00.
    388. + +
    389. 旅舍日記 卷一

      +
      3.15.’98. - 4.22.’98.
    390. + +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/me/diary/latest.html.en.html b/htdocs/imacat/me/diary/latest.html.en.html new file mode 120000 index 0000000..d6f911c --- /dev/null +++ b/htdocs/imacat/me/diary/latest.html.en.html @@ -0,0 +1 @@ +latest.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/latest.html.en.xhtml b/htdocs/imacat/me/diary/latest.html.en.xhtml new file mode 120000 index 0000000..9eb863c --- /dev/null +++ b/htdocs/imacat/me/diary/latest.html.en.xhtml @@ -0,0 +1 @@ +0195.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/latest.html.zh-cn.html b/htdocs/imacat/me/diary/latest.html.zh-cn.html new file mode 120000 index 0000000..7be458a --- /dev/null +++ b/htdocs/imacat/me/diary/latest.html.zh-cn.html @@ -0,0 +1 @@ +latest.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/latest.html.zh-cn.xhtml b/htdocs/imacat/me/diary/latest.html.zh-cn.xhtml new file mode 120000 index 0000000..ea511e4 --- /dev/null +++ b/htdocs/imacat/me/diary/latest.html.zh-cn.xhtml @@ -0,0 +1 @@ +0195.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/latest.html.zh-tw.html b/htdocs/imacat/me/diary/latest.html.zh-tw.html new file mode 120000 index 0000000..f642bdf --- /dev/null +++ b/htdocs/imacat/me/diary/latest.html.zh-tw.html @@ -0,0 +1 @@ +latest.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/diary/latest.html.zh-tw.xhtml b/htdocs/imacat/me/diary/latest.html.zh-tw.xhtml new file mode 120000 index 0000000..6995f4f --- /dev/null +++ b/htdocs/imacat/me/diary/latest.html.zh-tw.xhtml @@ -0,0 +1 @@ +0195.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/index.html.en.html b/htdocs/imacat/me/index.html.en.html new file mode 120000 index 0000000..08fc4ee --- /dev/null +++ b/htdocs/imacat/me/index.html.en.html @@ -0,0 +1 @@ +index.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/index.html.en.xhtml b/htdocs/imacat/me/index.html.en.xhtml new file mode 100644 index 0000000..acdccce --- /dev/null +++ b/htdocs/imacat/me/index.html.en.xhtml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + +imacat’s Private Bed♥room + + + + + + + +
    + +
    + + +

    imacat’s Private Bed♥room

    + +
    My self-portrait
    + +

    Table of Contents

    + + + +
    + +
    + + + + diff --git a/htdocs/imacat/me/index.html.zh-cn.html b/htdocs/imacat/me/index.html.zh-cn.html new file mode 120000 index 0000000..5ee9c39 --- /dev/null +++ b/htdocs/imacat/me/index.html.zh-cn.html @@ -0,0 +1 @@ +index.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/index.html.zh-cn.xhtml b/htdocs/imacat/me/index.html.zh-cn.xhtml new file mode 100644 index 0000000..b45630b --- /dev/null +++ b/htdocs/imacat/me/index.html.zh-cn.xhtml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + +依玛猫的闺♥房 + + + + + + + +
    + +
    + + +

    依玛猫的闺♥房

    + +
    我的自画像
    + +

    目录

    + + + +
    + +
    + + + + diff --git a/htdocs/imacat/me/index.html.zh-tw.html b/htdocs/imacat/me/index.html.zh-tw.html new file mode 120000 index 0000000..6c1b76e --- /dev/null +++ b/htdocs/imacat/me/index.html.zh-tw.html @@ -0,0 +1 @@ +index.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/index.html.zh-tw.xhtml b/htdocs/imacat/me/index.html.zh-tw.xhtml new file mode 100644 index 0000000..a7866d7 --- /dev/null +++ b/htdocs/imacat/me/index.html.zh-tw.xhtml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + +依瑪貓的閨♥房 + + + + + + + +
    + +
    + + +

    依瑪貓的閨♥房

    + +
    我的自畫像
    + +

    目錄

    + + + +
    + +
    + + + + diff --git a/htdocs/imacat/me/pgpkey.asc b/htdocs/imacat/me/pgpkey.asc new file mode 100644 index 0000000..edd1cfe --- /dev/null +++ b/htdocs/imacat/me/pgpkey.asc @@ -0,0 +1,1188 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQGiBD0kfGQRBADaGggoSHTZ8P17j92IMMxWPpML0TdvbhzW5iFF7a5th0xCn9od +pHVwc2YxuEulwDz0LJUx2IwwbttftHcJafcH51vk57Qq2+hvNAE1o9a/MWReMIwv +KfBi3Q1bVxWIjVPDbHd+ZUbbo0pozbfrHEaRPQ0qR+/ZgK5+V6WJiLElrwCgsCQy +FGfo72h5p46w7MrW4qSmalkD/RMcVmPkszF5J0N9pWlgcJ/fTYlMKIit3V/W/fru +L4KkUT3d9CMcJSBZrcVlXlDbPeBF8L7vl46NImd4xfnRKLwOuAy67Tld6CbC+UWz +rv6472rGetTTaj7iBH5nR62BQUmaLK6W6Q8vFOrqIBqXEz5iJ+RLYpIxH5M8gOz5 +7b7GBACIZaPaMVzIbTqnysDCgKEQqOyFbpgcGfSH52xH3XXeNrJhuenJFvBbeV8J +RgmKSnn1ZixFHJ261uGu5kOA1CQemNrTgZRaeHDu6mdZALdbxpLXp9DeOC/oTUWa +1O2xmAWcZZo+63s0MciC9zDrRjlNuGcVOiHZZLh9P9vEfoJos7Q35qWK5aOr6Z2S +IChZYW5nIFNoaWgtQ2hpbmcpIDxpbWFjYXRAbWFpbC5pbWFjYXQuaWR2LnR3Pohj +BBMRAgAjAhsDBgsJCAcDAgQVAggDBBYCAwECHgECF4AFAkxr7fYCGQEACgkQi9gu +bzC5S1ycBwCgno7TSM8Wb5ZJS8iaj+Y5/hHI0mAAoKhR9AgA9eNEktTRU6YJFuwF +6LD5iQIcBBABAgAGBQJR/qRaAAoJENyrIvdSTgnnhWkQAKCfI1hsTnRoJ/HdSu8+ +uywFzVV4VgWMxkeGIaKyLYkwB4I1OgIRwLiFhZFfC1wtQI7Pd81uHKz5KefZKiwt +TRdFAF4JdkHy2c7StIXpl16ukH/BMwgwSRr/5GWGtTioCRFKhuoKDgFqa2jDlhgW +qHfb6HtvxwbOMztE3XGKeKSrpHjd7R/nUtPjGfcsFpmMUDwSkvFbDf7nKzqwNGIf +aYC1FMnhVQ98W4K1b5TtgvRwk8AxeyRBhg4xTVciqjEZB5sbrj3KzP21QvHfQZrN +LOHs8VtW2yeDeqBXIsnVmAwXTJfIy3nmv4YSHraBNyNdeNG0bHCGXJQ/m1keF1/Q +b+xys0YLRS/3GVMf4cXw+wuOhPRH94A5itMsH2VFLA+THbzskQqnvRzqHoQF41lQ +Dhc80IdsoMIF/HLSscGGqTMViKuip+VBKIG2uLtHqKKNgC0A3qRX3kvfQm9F2DKT +mcXxfLjal/UtgS7it5V5YWYuPGsd5DRm1UQm1zMRmW3BEmFVV08otZjT94pmT8zV +BOzUO2d2cm/M768U2g8dtsNQq5noF0DhUqU3FzQpPQuRwSx8BrcQbkDnoAw/+hIh +/PHJbL/IY/GA4AsDeoS7PNqDjbtwccuQjhYwtp9CfuWIAFn7H8Cnbg6cG28tWiq+ +HKI0CqfnFMOfpJeoqaxlm6nbiEYEEBECAAYFAkxs6xcACgkQvRNvgEopPL1irgCf +W3lNuneXqvOaWcdcab7bnBhn4MEAnjRA072Rhz8VJo8Izq4yfVGMGP8siEYEEBEC +AAYFAlDXx9wACgkQPeaoSmjQcuZloACePmzCGXZhWpKVfjPBCe8qX2B2rDkAnjpu +aQ1VyrQNoXN3YXoTn0ZSByE4iQEcBBABAgAGBQJQmiwYAAoJEO0JbZPu7UfaMTsI +AINIxPhVyBJ+u6hucMWjqU5GbrUzCFX4FUK+MrU7w63XfaMa7zphXfASwJFfNHvn +dC6a4dPmwO2gf6/oJQW5iasi8qqAoUsTvg1l/dAPySuK5zNraAViBe8mrvHYj7we +7jjqs5M8KSykT2YsXuLsRZ++OWG5bvdxA1kOwDzbUvDJFo37yF/xHmD3BARHeLEA +omTkaoypIDaaQZtYkdwFNsJP2660phKerhs20x94X5VPRYsCEBHisTVsayT9533O +AAj7/awRh1zeRWlrYKcbqPyKNf4y7Eg9cl1Ma4Y8RgwqZMCTvxvU2goRLIdH22XH +n9Xyv1Qs3/zk99MNnvs5hbGJASIEEwECAAwFAlCpb/8FgweGH4AACgkQTYzEcEfk +YQxWNwf+OT8pty5sKRb9+D/Gzez9KCdTBtbqKE296l8CG5P3wKKS6qeSSKeNwy4h +YvOk0jl/jmdebp6uTKWfrF+TMDjUX6+g2MdJMxux5WMkgslf4GY/i1FKDA3HIvfi +X4SnaRWB18fAlPnvUxT4yJx3K5JszQmjHLJBKoKGCTp3mFO8FCZlQE1vylBHSwbg +nzTPEMxdeZiN/RjLNAC0dGLVCnuEl+PllhzsiZLQNZku4F15BwF4neKmZuL/xGxP +o/q44DcFmGVHdzlavY3S32xzkUPrntJTFpv7vOHOvpgpnpWRigkE3X0FtXaQ/f+R +K2fVvRLTEl5hegLZSOglA20ja75S64kCHAQQAQgABgUCUC+5wQAKCRDCq/LOVNDw +SMAJD/4u+xZL0HRju2eunvUfPUD8+QCi4NYoatuFmK5iGhQ4zmPB8PmD84ocVmn5 +Xa3tkArUwXOVepambnPauqBCduRwpDwcKmhn8NlItk3cBvBdnjA2CGuv7ZaGUre4 +PvYDVYWywhR+/4gFJhNAQhplgmi9Ki1WPbabeVaWXNTMwdhwdiT7I0iWzKTgIP8H +YIvjJaH1WUz137Qgz4YVcl/tHlgthuZ7VUQctin0C6OVH1EkJ+eHM4awfhflrliF +tzJ3Jit4NO5EzoB0S6JhKSL9M/Jkdx+xUT/eSOpgKE2MlND6KOUaz2+tjyBvWFff +/lo1CLPjp1RounDjmYBwhZ255aAvwO0YrvT49lLjwQOw3Wt6PoM+QCCFBeZY4QlA ++8oMWrXIyUjbG7SLGKObT2GWYRIBMr5W+oCwn/bZes3F7diyQe13aYTsRekdodiR +jBKZUFt00ti0dC3LCubvRepD6y9cE9fGNZGU8LHulCCgEM5nFWWQ4iyQyrBk0/jB +qdVkFY/GUXbkjq8WFpc/floaoeEHi0iWk0128dum0ZC7AWlfTzmlqpcWqx5QhqN1 +GvCIFWtoO7/9Nl6VMkJxuCSss9SMoJs5UtvPBsvMRSWBU2ERHys7kZOObEVe3Cdi +IHVorWkPytlWYS4k/1t2Bzi2dfND6VL6Yy4Zi32nRGwdsvEDeYkCHAQQAQoABgUC +UJqmRwAKCRCa4pb9Aun2W+7kD/45p4GZmNtT86jVJ6oVzBDBedjnKdMgso7ob/Kv +vgjX/0mK16j65EyYJm0yoxLESCX4pwN5o5IXjWgfOUqd2aQM31vJO/W3A6NB4TXP +FjOZtC9f/T9Vs0j+h8p7Kuh1TkYrfaeiJHykE1lHuR8P+bP+8hwVcMfc++nRV5MW +DN8hPTEzE2azPciBdLBJ++LS6CHJ27YZje6Dvtr7KoxfCDnDnGnaf5SbxGkHM6Ug +lVm9dOfwvZ1iPEYcOm8kqoOvhR1AckaPToswC2f0qR92/cCc3W5iDMsFVc4BM1Y0 +ou7rjqIW4tQMNxQfqFAVJPTn3FXRl4/DBaSZwytjj30glajyla17HbKqDU9ubw2w +GRdoVWOvLKPVRcDS20Veh5mlM+ZQ+UY8nzKujrnsyeDeY/xnUI1UpXvyZcfRJQxX +emOxt60dzUARnG/eX3CFzEqnjZ5zLnzfesYXkIdN5ZSu0sYaT4uqyOYRCf/t89eC +P5hUOUUQC/sgt/d4IbbO5Ej9oc2gUpSgvF68OGkOXpN2pZ3HwrnOKJ+UjmhTN3+8 +nltbo/FU3mypqjAWs0tl2M9p+PO7QhKQYuC2unUKr+BUpaFC3r8ku4DHOyovir5y +6GW143L8aJIUUvOzJqCYGwye7M+3RT1q9OGCA3z0f79XMEOBgZN9K3+cBm/e0bIf +ZBAADYkCHAQTAQIABgUCUKJJKwAKCRBLHZ4IoJfJrtjbEACFW3rjg1jYd/sNf3Rt +HLfF34LZrzfTW4dIPtjMSvsaWWb627F2KyXwMzk/V07Mxy1xm6dzNkxJRrhRb4sC +yMJFzcJAp1TBWNcSnKLYi6v6BRMcPUWlKX/UkInb3YW2PjduAkmOcRSMM0x0cmwk +q2Fcz8TI5aD4hT2cTpVfwHuYvl7qaOOJadNdUQg0hSd5oe7Aj4wSCpEoSIm1jB2U +wU+4UTJUB0krfCwKwc63jCPzyAz1tq+zeyehhP2Xgz1Bw3eusj6hh4ClFdafixqo +ZgylkXbOGBR6u6wHYH2OPqJbZzR1rLj9rK2gaYh3DRiQxuHbJPzKSrJPjQ7Xj2LE +QTuZUc96xy+QIS/HVBtqQQamw6nSLxk0oRg40R+VZc3lIFD4WndjQLfmovz9z90u +5xGqRz17OXJ42jjuoY7+4bjVxQQ8ITonkl0mhrDQt7xKBzeSMeqxrnNT/bjpBW7r +kEIeU8qpdrAI6XhBwlNNCaI0O3zwR38H5gd//r5bNOLjmlcyuey83AHtw84MiSE/ +v6dQYiaoU3e0PxYGICl8bOGzLPanZnDvmsC9CEL58IXQfC5Mhe9NuLUIgUBM8Yql +rofxCNzYi9R3EPQgv7wzOmjTKX8O97ZQGmSguKVjRyHCbKmE4xZMn0Le8W3agxrN +3vcNbopEfoBaPufD7ckr3OpCtIkCIAQQAQoACgUCUKFFRAMFATwACgkQYtSPrRag +3gHq+w//STT+KhokRhSZmooAYgIq/yH8Ip71cc2JlP57fhVGgPufiQG6ShEuKV3B +gtgTNeVI6C9Mr4b0ccgM6E+QQS7LaL8wsc8EMF8NLNWOmB/GUXzhtwopa6lzrDaa +wB2U8MdYvrPcH4AWiux3CnD/Il3LBxJ4kNiag2Iy2NihH41jxVrzliKHY8nAbpaL ++/Tfxgempwr6dBLDnGLRaCw312mUjyaVw4l0UCSODwOxNz9WhANqq2q9FvISGV45 +FBO4rbvUVQ6FMKSp2zprcf7MNBFGQTSIp+wPCvSzYL6hKDwU08YOaQpHAj6VxlGl +Jn35P9bu+KzcTwy+9jgA4Apl85EePm53OgIY6mFyjsnROKKmC5pOM1XCd52MR2sH +GssoidYPN3r8OBvAsAi/TjfbPMOreqUmWZ+sBEiyi1SL8ms9TGdW9EDI+3C/yy+w +KtGZ+4MsuJs6ZJohV+IsgL2T+bqgIQQBVK/+mcs2K7hEa1wYRaXsqM6H/c8j6mSS +FZbSO74+Cxbf2S8KNjpzkpKdRzZ759DPccPuBBHHY0yEZsoyeKBYxsmCGNLbvd4y +T3pZ9Cj7kUDbjEAFfUmlC7sN0bzOM1r6iRYTxz/iLDV+yAHubPJ63jinNeAp+Nbl +izIGHfzADfuCYsEzaBD/4Ganja53mTmh72u56Zj8tm58eXuBGTWJAiIEEgEKAAwF +AlCaa88FgweGH4AACgkQcaRaPQ2NC5NFkA//UU3Ls67UdgqoDkQkjOl2GAcJZogZ +R/Gz79KUv/bVkNVh4g/mrMo3Xp97f4KuKd1TSra45ahljZdx1yp1JntpeOA8BWE0 +jJLPPDaOanF7248DREbu33meqNQNhzKGa3L7IxzV3XBCO+9vpafFsBhcldFrCXUe +QRwsfGj19vWF5LQG6d5IAhTEb1MedufRee/KNoS78hhKXa7MXKWgWS4HLxjk81R3 +BOPkyURzbHHk4wX0cfMexJnjx7RFw9ME7XSysZcO5iSsX5EVMAtA53pAgHwN9y9U +fvuxPjPod40O47xeQJlZpiXfyYOBLQlcD2TinUa/40NfDIMcz6+LCW2dum732p3V +Tti8cfE81D6E0t9bDDiVsL13n6NJjpy24iBZ34tOTzhxW/T8nbnfTvC7nSa0QEn0 +I+vBqwsu3sbHjw4Vqiru7kWsccxSW7kNmhZdPfxAXv3dPhWNhbjrHu+KlTGCo5z8 +th8RKbBt670KKuByCjOrClvTb5U+qOiZEkRbGSiDba2fZ+BgrMuHMQy6OrihP4x6 +qd0e5zHFtZMAycdr5TUh4+6+saDQJ55auuthGkA2OVGCSXBxa2TdsHPxsfisdFVP +RQotriWCERLZPBQI6cflB0ExwX6ouI44HCFKHM2KylBag+4pPPy4j9Zv07HCg/ok +l+ZO7S59EN35BxOIYAQTEQIAIAUCTGvtfwIbAwYLCQgHAwIEFQIIAwQWAgMBAh4B +AheAAAoJEIvYLm8wuUtc2ZYAnjicFOfcdKgDyYTo2AtogA0ifVo4AKCq81VQRjDZ +w4HuwIPuckxcjvfGJokCHAQQAQIABgUCUgEUuQAKCRDcqyL3Uk4J5wPDD/0XRugv +v6NDiWf5Dn7UPbd55y3TlvaytYx2Si+DXt/WtFuCod9zBq/l01I0SEKOXv9xa0pj +OY8a9/dalSh4s1rIw+4PcSHzzLzEH6HVK7r9HRSycXbGQ7AGzsU51YibAgQDnfPK +HRX5bi6oTZADLxzgvM/fAdlMC/9M4i3RMX700i502oAuBgzZLRyn4AXg2hBgnpvp +YXL12lgwflTOeJ2/49LUrG8xu8FGxwoUTB01LIhcgfA0X7Pt/oT9bQHIUXK5fd91 +J32U+EZsu1tLqZ50wWK/oAd7UoDjzKgOjmRDlWbItLKr8UXOzubiRE6EHN/InWM3 +48AZQHgvRJS5CDKsuGzJZhOWqG6Qpthy6k8EpVmDHcJnI9E0LJrVsaNedfaHReaX +EZGOiQQfzwa0SNGebq0HFKen7Vv27rlBmSjviyBhZ597nZwByd+XlKWV+yubDSnw +8br3901lEzPv5k7N6Imx4gIyY9Ke7ta9O+TXOqzjkSj/SyLUe6cLPbFtheDJluDJ +Vv34/3+DCfEQsj0am4S6YLIyZmdUBXQ/lOTVmlAvGb3aF8inB+w78eMpe0JINqXR +dFeXuKtloQBYjvy/rakGsQPcsGoJeAgACzPTrSizENQUhERh9Tx2SaY9++HSK9nr +rQTNJx87iHYMjyMMuPDtzz4A3V5vEiLpuSG70bQu5L6d55Gq6LKTIChpbWFjYXQp +IDxpbWFjYXRAbWFpbC5pbWFjYXQuaWR2LnR3PoheBBMRAgAeAhsDBgsJCAcDAgMV +AgMDFgIBAh4BAheABQJMa+3zAAoJEIvYLm8wuUtc8DMAn0U3jAcRPuIXxlbqgNdq +pJS9VuBEAKClDCRVEfEna+tS0zw42kEu0sLpvohhBBMRAgAhAhsDBgsJCAcDAgMV +AgMDFgIBAh4BAheABQJCiLw0AhkBAAoJEIvYLm8wuUtcyAYAoJePm0AXEvxgN6c/ +4KrbLVTBqtdtAKCjQ0xmsLfYpANmPFhgXtifNvlXUokCHAQQAQIABgUCUf+orAAK +CRDp7Eb1pUfzHp13D/477eozJFFAbgiOEHHAF/CMvDxTjmGhrS0HExQELtqpkOem +5GglqlrG3qT/vhPbmkSchiXCRldN4uI5i7ooxpJ33oBjLHXCRStuPNOzgsKW+hpF +HUTq//VxYkYEwho4qS56p1/5FIE4Kdpp0xUlzmFRMMeMXZ19aOKH8XwlqDM9rbwd +SU4ck6krKAqn1pEK4zDCGMX9U5N7e1/ylpaCQUn/OdVpkr8FCNhLosbiXfd5MhsT +q3bcKRERynmMG+MyFT1PkcRsL7r+snDi/PmvuFh8YWoCSvNBi7LG3rZaQcEvsQ40 +B10GjlXEt1HV9cI9FaAVThsMPIC7aPTNRvY2RUAnRSIwvqRqkZHZS8jRQ5TO9BAO +4l1kAf9N8h7EvhECAYzD83yTsh3v7FeYoPgnpH0TeksXfS0Z9vsgNVQ0TzT6T8sc +LOVilTvQVsafxEg66ET30tJgeouCjUBUwikqGggKwMJvrHw4UQ0r33Rm1u6IBvtE +NRUM7Cykj7v2A2G8kHS27Zud68SDOi8Zn6N9/k5IrMYg8+5mWGCNS5a8ngvAjoBo +dF9X8huVdWCxuls1aIoFoVd1FinbQaTE7eCb7OTBlTLxnrGqeFW75H8ON2mWv9hT +Sk9HKmQuXylNFkpFp4KN4Jgclfs3vMvolZC8cgZ7Xytqc0Q4wgFjtKKLRhcdBIhG +BBARAgAGBQJClB4nAAoJEKzGAWURwCOC7ygAoMGs9s+MlJfnW0NbBqnsX+ojbmaC +AKCvc5oJ0m7O6+g0s8bprBU8PiX/nIhGBBARAgAGBQJHIwWIAAoJEFlF7l2dc83X +FvMAn3mVp5pNHOmHy6C6EO5i+dkEhvDKAJ44nvUOQ9mtnqZft0QG/IqgCQm9HYhG +BBARAgAGBQJHK1PsAAoJECQf0g6hnJ32FoIAn2kkx7izNYGObbWUGOkR6eSCY/1n +AKCAp/rXrzk6eIz+qNQ4axAfZqLJQ4hGBBARAgAGBQJKv5e2AAoJEGDtvXwv0Jbt +GJUAn2dfutoQlMmJCDTtVnXV0qw8/XM6AJ9QxwSajJp9ZUnmohzSqd/HFKp13ohG +BBARAgAGBQJKv6AoAAoJEBzd5cdizPQ0Z70Anjp+Z076jm/V6FTacGEQI9qsyKla +AJ42kglFhiPsvdHCj2g+RsAAeNlLC4hGBBARAgAGBQJKwrn0AAoJENZOwK/Uzv03 +7tkAn1OT4SVa5hf43MRUw6OLsqZFpCNcAKC4dubjlPTkHV8WqWDAY3T9CDJlaIhG +BBARAgAGBQJKw0H1AAoJEKoM0e7Qi0f+eN4Anjyx8vn2m72WNeN/d1kObBBZnQFH +AJ9/3dxl6f8GCddYhfphKu5rhRmIyIhGBBARAgAGBQJKw40EAAoJEIcuj9XjeMMq +n4AAoJnlw5Ax39zsPM0nsw0dDRQSepHJAJ4kmJ/z0BhDm3w6lsFxfIlZn5EXZIhG +BBARAgAGBQJKxBqxAAoJEFhMgqH8ofFzOqQAnRrjt88GW7/cnSF6RwHbblvvYp44 +AJ9UPKFYd8Alp5T6cKQSlADmC7QWdIhGBBARAgAGBQJMbOmdAAoJEL0Tb4BKKTy9 +dsgAnRC+5x9nIbaSNuBTzdhpOQXxguJ6AJ9/L7DUsW6XDlVryiGzxyYAj/U24ohG +BBARAgAGBQJQnsj+AAoJEOYWZyllQio9QFoAnjfnvRIYNEPk4N1Oqeov/+0ndSCG +AJ4jgc3zkZvJAsC0iiLXXEvSe3TusohGBBARAgAGBQJQzOYrAAoJEJGTmI/nDSNX +6k0AoI+iMBpVh4pq3CX6SlZgFFPbPGfrAJ9IGDt+mdgYlMunWXC9i5S+INFNdohG +BBARAgAGBQJQ18fkAAoJED3mqEpo0HLmKZIAn1ijVede26o0Clm/OoeQOyXHDG7l +AJ9sIou7uZ5BP0YGEipC5y5WsS8mOIhGBBARAgAGBQJQ2wgJAAoJEP1viMYh0Kcb +HiUAnjCubcrn48xMJh9WB3x4Zpk9PkY7AKDIlgHUjLcxaofcyYzW7zPlWXO5dYhG +BBERAgAGBQJHFNk5AAoJEMzibBCD0VZGAWEAn0Lq9YwcVd1wqTWgOAmrTEAt2Z+u +AJ4zeQ2pIbsQSAbzlqffpH3wixpth4hGBBIRAgAGBQJCmMQWAAoJELSz3Tc8NQGg +dCYAoLa85znruykR4B+ZDVQnXAFhHyJLAKC6Q8zXubeDX/1vSrf3j8LJrRefHYhG +BBIRAgAGBQJHA/ueAAoJEIgIo2nUqPV5/DYAnjf9Obbte0rrxW6nfF7thrEreRM+ +AJ0X1e5egw8Klb0TRWRWEPmR99gW64icBBABAgAGBQJQ2wJsAAoJEDGmPZbsFAuB +I/0D/ipKKzr2D2Y3eI182YLhrJHPiGnDGREAwo7ue0qVBAs7PmiOS5ugiYP3F509 +DMvRkvoVWs9Oee2JZ4j3kG2XsXZwrmmRKpDMi3Onkx8DH2u34hJvW90+5bvCV0SH +2Du+j94+X5RDA8rDfPFSPd5AIWkczqfy6QOBB4mBg44DtP3ziQEcBBABAgAGBQJQ +miwYAAoJEO0JbZPu7Ufar9kH/RVqQG1Pxcgkqenpim7ypSw5q5ZLPLsVB+z0pBag +URX2xYectoTgFqihwmlMChGZXHqcoJ4n3k9XTr2QY/hd1Gwgf0CrxKw2WJQx6iRY +9ry3c3xUYG232wYYgdqJgRmCGLqN62P21DFcw8fqN78FAHpiVI/dYjJOJB+2SFzZ +unhC0tapcRxXYVMg4jUsOsOvekLaa0zdw/gMUn7gamTgeSdtRc3rCgAJOJ4e4qOT +yR//brnWl5zxH1jSpZDfKPp8B+pK4qS4wqcwc12tNAYur/lJf6+pA9x6Yy5DnEOi +LPADTtadVOB+wf9x24pKGGFb92cyYAWw0gPNXtRQLqmlP6yJARwEEAECAAYFAlCe +gu8ACgkQRxXcAmQovbqf6Qf/UwKpQ4dwuDSttFUsGyfGqhcGIsfnwn1DqfSd0X4I +hwosNifZ5NOnbDvjPXVHesb1N+9PqRvWCJc3zzOG5PYgMqU039GhvqCyaA67k2+W +Vt6H2XJT0RrfLGy3N/fVPQBGutgyTCBdvg9oNZp/0pwJyRyHERGih4EK8UPb4EXo +vslA9IS16oZ6+dciGYieTyyXnOhaoS740dEgSKPTltr+DhfQvkQWRsP+aJpI8ndF +gLBEdN3UI24XUquEWV/DhPNKtrtTSSoOLyh/AxmjrVYJTI8eYALcSZ28+LNBTpDF +dFPQBnAw5IPmo4mhu70dsaxhO1B1v3lRnSpMSjM0Wq48GokBIgQTAQIADAUCUJwf +8gWDB4YfgAAKCRBNjMRwR+RhDJJ0B/9Mm597HQLCG0GNpEKoNy3/aKRcIGnwSrwa +zunzPJJMkDZzOYp9+GWOr2VTdxWmmvLkYwFZVS+oaNyeAAMYm6a2oFq1PeuQJQhE +YR/0q95sTqgPQV1MP5TYmA+4ARDioD9YGs/0h0+pXRp8TnznJhjN50exwDOBherK +F5ZdsloXFeca8b7ma63gQdkeTSEnZvqy2FBPtOtkhl5boIt5JTlkJVGgK7nh62vg +/zu2VW7I78oy7jD7hw6ZJgKNarQbgljiqiauUYE0K/L+S9OhRywmRjXfgs3RkkzJ +clRYxgPxKAQPv4bjQpKHoduYO9kIieXiXFOgWlCgBIFuFu7KBH1niQIcBBABAgAG +BQJKw0IfAAoJECyPNQoVT0RXsHwP/AlrjN5rkNZvMYn/aPOqfsKhTpla9NSXy039 +WltS9UcFV3MfgykRbs3sBntFUggAjJG03kjyZfeGekCcc4QN0qiqOUFAUxehi4a6 +5+7ZJs8lpi3qwwNjzpN+lEq7FU/qvTwdsrhGpbHXBVkO0dwnDAgykK9y4NH2cswN +hVavPubGF1gGTOpE1/YbYGcYDS4P7xrWW+2YuYqVjpMaVW0i7u18JpSq9Efge94n +i9Pt3TpT2Xve2WCIXrQwJMyS58FYzjqubEzGPeTs+POscKecAB1M0pZxWsMWQAHw +UV7kIZqJFYjwyGfrFz0KIY92hmobHcoocLrKO4rgQzxlw1ewLpTnMqlqNMdKPcWI +5cVw0DO+zbtIZKWS+zLtNiyZC5NqHtdn6tsD85AHKen9jm40NLtGej1Dqz7yMvIy +iM7RSBIu/GaZ8vXc2s4KhSHdlPcumzL20vE93UtVLCA2gZXsGvMe5XLIEN/xKtqD +O0E0ie3L271z9NHZ2b7tzJlGjdfLbQE4WHFmebw6jHya1wqV99ru3FIy34kZ2oVa +wH4GvTnmhROjkvUFqVjmph2iKq0MZsthdlceYJs95aAcPuQ5S+S7RzZ8EmiNIuOA +j7VJkVh5Wq06zbWHIiC58Oy8nxxKV4hZ59c/r89G0ARx054Ef0ywSdOBQDoqBnTd +xv7wkn3yiQIcBBABAgAGBQJQmqk1AAoJEPtjPej1y65rxIkP/RoNxv8D0WGkCJaF +CokHKTXvuzeIX7lK6a17oIdRBTbkvYS+W6bZtHWMDK0xVQaM2KUN3XauYSeDxn/B +dFU/68RZdwz2W6ul9rWhKnCR2cfTgIIjz9trTQVtN+WFWWHHTiCcU04vEtagkgiS +vN3elvcLTZMtOlw+yfeVE8j4l7nAVYI95qrLBUikIS1+37t06JdihGIQK09KSQx1 +rZLOrEm4haPkS1ljvAB9/P4JP3Y1BfvvYaEokBcacubs4zDkA7uOGp+tntCf14CQ +HZ560tyTGfqHhWDjLBZOM8TxzrnZHLp7a49Jwuc7NndIV0i909/6FuamQV2h+HAo +Cp9tF9919xixTiMSeng3KbBIkqNnZhbGWyVvyzySCKVvLekE2E8wrgVufzT0bdZP +QkxlFRrOTKdracuQvOWpAdHf0yC+bCcQ65qObLrBgcDYXOD73n8QstKCJDWmYVgq +zM7mvptFPG9DqOuV5bSvzHNVSugMcrKuob6j7QY6hyv2iC1oD+3AF2w+ttT0QQxt +nXPI3xGg1Nn1a0pr1xg9JQl9d75ZetPbb70s1xXqj9byxjCXhQre+eudGNHBzxi8 +Pz3z9j6yP3PsdilouIIfh+RhEb/R4meXu/xnBmbHGpGSE7v5WHtCGgZnyfvXq7AT +vbv3KqSVa1H4DISSsLExHsHvt9ykiQIcBBABAgAGBQJQnPrEAAoJEDfnuKc+PLjJ +dw0QAIsniu71v6jpt9/MlaOJbDj57PN07dlcg4Z9GKvvMEZR2Al48L1gLIiryWPq +KXOkaoMmKp4vAZ7VyfMpiTSmBQECT9i97DME4PNK8RZ2JoA4zmefmqFtfJnCiqpe +RtKHI7ZZATkr/pUrLlOgbgtYkkwXJml8qUPVF9RnOSTjvbjSH1VIQf19PGJCNRSa +lGY7FGEiA28rRI6fHOP2d4lSKJh8sJWn/1h4O7dL4zHgUxH607SFvhgZHuHGssDy +xfkXSrgGHi4WwSLtmgIc5rthMPMkZ40cBUP1F2giroFRH+dzw8UDpNtqsnnQ0m0o +V8IzQ85nwu+8P9CeYA7KY1j3M43cWyvMQHNhXMZzIX4fy+trOHdBGCJMJ115RrSz +79bNVGVZ8RNXeoufPRuaKu/MXa80DU5iG15k28KQ7cPdpDGUoB6fu3fUFkRd/LBH +JGqV9vur7ZLZUeP6nKmcVdUd0NVqG/SXIrX4fU66g9udgtInHbO07vcl8pH1uXRo +E4qzL9u24+WUC7Siwhz+hWvRMYte6pIs6qGeOMGgzUs+2WNXHsYP2vnwCZgiJBs9 +w/P1acR57l/twz8SY6akS9LzSr6ILGKexCtI5QtE3RX0mLysB9AWF1K29QkYc18A +0bVyi/10/KukqmYThszwaH8DiH+SzDJblzucYHgdea87u12ziQIcBBABAgAGBQJQ +zOYZAAoJEExw8Ghv5Q8cx9gQAIVPHoAny8EcbfU/fJRI/VemQ+oBK7DDPTGinGpK +N0SrbOkXpMOLHHPscdW4XU+5dmXY62D3dp/ltZUICixfVFGg1YEArsKNQCD1TTyY +3HPuv0dER5IQ2ydivwMFwoC64dEnhctBlv6Hiaq2mtIZgbqPyc12VOT8tnQlsj8Q +PyNFqW4GTvQPRDPeLDxP8ewroOTFozIZKKIr5uGZUd4WqVWWyMVDXb//4zUQQZS0 +PiM4NGQo1rYk1iFGcteaOASeDA/aVDiA4RfxCF5W/mtid4LPMNtSWUJLTmxSCJOT +4dgxTe5EXqMGIleUc+9fV1au13icZxdk32LT/gaLAskQEnakPzzgG5KZukcmiCHR +kWpEcrd1dl9PQwzeRV4pguoE7zkVJp42oSf8BhlZ2tNAbyOJZuU2QEuFL7+XJA+0 +zlaoEN1rZ6AxBa6ULZ1Ih9LjZ8CTC1lLMwYF8Mm1/oFYx6UTl4qFlHnzPmFTui10 +xWlLQsCvdSDn6r3u4FbtdOC5AlfyGRxPoNT4yWXRUQerL9T/S8iWz/dKnPychKm/ +/hOlJuFElkSuMvT9y8zlhNivZyectpG000YZkpyCJF9vCjuv7B7oPDRm8NBxgeDE +boue9nGbokYKL4nylxwnbFRGJvAeAvAPkuU/vtO3o6UT/RjL9vbqyzu5j7Jh/cL2 +/7L4iQIcBBABAgAGBQJQzOa3AAoJECsRil+hXzC5IvAP/jKbD/+ije11hMwdsaw0 +iQsZXy/CQS2kBYyN9PeQ26BND3jfU97EfcYOgzvVcviWiClHQVvszTu+6vM1r+FM +CLGRU+oEb/P8zCvc2d/4pyS7xqIGzAzLvf1kd2o9SrC1+u7BSxYzY7fVw0Wdv9Mo +9bBkQjzGVG8XyWWVackcIHpSMkTsHCC+LXZDZ9TmjAHfYELsvhBICka66S6LVaaF +u4YyUdqOCL+7JeNoJnJGP+D5nyADXe1A9sno3dw2T/UUcwvivD3eIwUJzP7ZmKWG +Hkrvz/31AFQdVZEhfzbuRB5eY2CPizZ81/CMOsxBt6mRSyTR7/E2X2cDdh6Vi0ky +z/+2QZaW2Uc1M8RbqiVGJ/wZ36WzOZLMnEB3hEJP8mBYbXQPw+3WJ7muC83GJuoH +iW/zaL+ktsm5H+BLryxROWZ9TpsJqiMwrLy6AZXF5F8hjsythG3ULxQxaByr9b7t +Bz+Y4KNaxS7+9sf3N0D7GkMjBwv+Z9wd6P24qANAW7XIx2Mc9Inme905G4KeXoNQ +YWNVuO6t627mxXCYtUPDnWhVdpb8rvEkL8l/SuKw3hOcmOSQOVaD4fCLdPvcJVRp +NgpyBjsq5PbhfVWGAlz7yJ/z/JKUehuvT0ajRhlCr2GsABnzVNxYJB/HfFlfj5+Z +Szxtx8AHBXWqqVHXpq13F1pBiQIcBBABCAAGBQJQL7nBAAoJEMKr8s5U0PBIIggP +/iHa7EboGtJ11IJBDmtWfE1Y0L4L9oGMc9uu/AyXO/RY38BgwFnmeY3Op3DYunvj +hbvSGmGYINiBhfWCkhQGwUwhlODLj9MIPP93K4pudU+rABj3PRBi/csnpMP0t2xT +TQnzxtKLhv+o3fMTnyRBm5w56TkDRrSoXSiz3MUfB1RjbzowzJlbjXYb+EWQiJgR +/wcmPO+9ZNMnjkD3FIStgWAlnpPsABHfH9SWLierESxVUNyvq53A9auKlp6KPLmz +kckpXiLCWrv1J8qCOLuPTmVniiNtFLsdKLZUZe1927RCB8GEwCRlKFSm/7Wa2JpG +HJ/291r6BvqRcjuQpDXh51lKzsVVwWfRmYqtaNLb2uDbu4gU3U29I3k+8VXOcIkM +5FV9P2XGTcKgK5l4E4SJTmBTBysmaevflROpT7OWEL7QcplnoJRTgfcTqclRDUel +Pwoii2LUhrzUBKSftiDbMbQIff8rTuPCzgBLuoqdbRyM1zMcItWFXuh9dUWxBfR8 +h+5ccnSccm/3uNUfrXdOat2ckI7N4G70LDaBDRs8PSvj6vnvp2xGKbfcRkDF6CND +P4OXC9Fxwkll8pKLYEt7r8o6flUm84FKydWmiFvsmDWbgKGVpgYimo42OkdGVwAU +23BWWrZ0acCuDSKcluBwtPCDcun2JTS0i6lhiS794UCBiQIcBBABCgAGBQJQmqZH +AAoJEJrilv0C6fZbFKAQAKJ9MdDyuTgvw5/d1IOYKrnlgj85oVXMNtF8V9/zYKTb +UuoejgEG/YnJjeGjeAhNrJDtVjQyp1rpwJ3cAJj8v7+8broT3d+y9P1ojyBu9gY8 +sYX/EvSqF4BOH5fDdGio3RvAU1HUlfuWQA5aDxBK1E9CqMVQw5lYM2tWeFLYeh1C +NDIDw0xEihTWEi1RnAszG/8gPDP64d3we8i2V0YMoY0M+Qta5KPPgF2DeFsV8slA +joWCFgynAAZr1/ZQPSxElUHNENpPHOi6jyKFSRLxcm2e9an+/uSoWIzR5lQYknZv +hRMTQDugp4dEaqP7670WS9SSwiclUiBaMLJctO0t+7mfc38N4Tbn/9vmn/49q+o3 +cLh6A6Ixg0lGOgyR6jnqNwySYHbrQYeMLXTg1P4bNKvLd+CkbD4ILGT6nSEg1Urh +li2ag1MHlDJIUfacuZ/MwR0/P84J0eT0HNTJVy2QWLI6GW0xoQ469Od458beOQWk +5h3rUEaWj4TqtzTvRJtvdFHGKNXMnwhidHfc/y08WKlNxVkcQLYHS2pMHo5a8Bmn +2p0FtZ24kBXOhFKMnA9v0ZIRymq7kzLp3rzXZ5JfD+WjN24nafsEYSKkPosZWimF +XoeIPgLKYdtpCmSXRBJutiAcN6Ejr1JydET492lKIuNdo7xN/qCVpwfaeWPQ8l8Q +iQIcBBABCgAGBQJQnOoQAAoJEM/u8xZRtf3o+hYP/ijowpRw1Ojpv/KdkLNZ4Xhv +DYl5KvVl7Dm92lyH8mZADmu2LSwKrqfI/T2z4XxYn4L86OYiF0keWLa5j5Gxzz5r +zz0eH2q+Xbu9jGMoJkUhy3aJhiOYO+u/mFV84u136VSKBpVCN1C7WlMk+pRCo6sL +zgY+LDjjEe/xcNtJZcAgH3r/wPpP4+iNjSAMiTER0br9j/xqSC1HlI7495KDGBzR +4mTTuRxOC1Tf2ZH7AJE9foTN0kIa+4cKubfpuNbYVNcWot+6HPuqdl6tCHIJhJWl +uPBavu0BOqHGLajtoxgGDIpBOcwWIRd0j2BdatBGKheLEl60f8UgXzqvmV0BYiPv +vdW78/AAlkKTDTOiBjJ5C/T37mILHanP7x6LGw2iUp71faipgE0OD5F4bnSGcqKu +DVY57eYOLLRFsVYYHxGWdInk9nqfaMS4OmkpNmcN/d8/42/fojv5UKkduoweS6RX +5QsRUetb44Md8rjB4XB/vByMrbd7MgWDfEIXdJdAEeop3vgYM7U/xu6+olhNA3mA +RZxp8O6Pxw8GySOzMO4lcIjH7rnG3lVxr+GhL+mjCcA/NRLC0lod3bAwQt/sn88S +MOiqdG5nPUTB5BgMdVV007+pTweheEi0DT93EdxXuTWGx9NsxQHlfZ5EiwBjSbtg +7ceq0BpANUl5UIDg8ijuiQIcBBMBAgAGBQJQokktAAoJEEsdngigl8mukTsP/2r4 +IB9pnD4U7FCvcMfFOxqpSAbTFnqb3T/0oaMi55wkDJVQOcmr/2ITGAzBO1IGhuGO +3oR+XOwc9kBkm533diLyL2qmq0l3xHL8QZdxS8Np48IJO/TVfLpsqxMHppyFphXt +2hxtqrL1qok/P93BUU8sfx7z3Ao9cGyQCHLYlVHYKaBw4Zfi3k+7+hoKh4ZLaPdc +LOOfTLP5yFAElVRsGGOry72NnMoToy0gqcj46xsVwu1XFy+8pU7npb9zRbLP2v0w +ATIXFB0hxYzKSPXa+X1Tr8ROD7AdGO1K0XztnPmDk25DPXTJpinJrdTqlkEw1IlH +KNDxCOdoNYBmLuSemAGhqSlxWzmenQZQn8NT69bntAI9Jwrot2v8d8C40AqEhPxw +z1LHyr/VGth+gOcev3yucbFf1lsEJWuq7kmHjqR1HsuXS4rKYqlS2mBxC3DYMYEP +LCE+P/4GM+dySjtk+LFZorOgZhCJN9o2iRFwP95VIpPzX5XZ+tuF3pQe+xicFpoP +4/VMbPw9ExBVPOZd+kWYj8llbIOkgzmfMbJsX84PBfv5EVEzF/0t26CwzcrNXkhv +9luZZAbfz78VYONL3qIvv5kN5eWaNo/nYpd0H2ME6cbwNgBHLTrkfT0kHN5Mk63z +3A9YXj4uTBxuIMWYE5vmN22bOaI8EaPGS9YNjVH7iQIgBBABCgAKBQJQoUVGAwUB +PAAKCRBi1I+tFqDeAckiEACCe5CS0AD0fzL/jt2M0c7jkWnAHuo4gdR0LI6WK48G +kqdwQhh7307vagSB15gV51LRRtVtn+OfCKX2MDDvAynmm4R3hL7U8F3cGa2+eTOe +peox+HKARsEd2TvKRvevSLPoKfdf/svDdSrbt2wOC2afLlr2CyEdDNhXdNFPrV87 +zPlpIeEGDNZCQ+N0WV76JvrfEDyeRc9p+h5j2g4HR+d8EZgue6tWUwnglfyIpsty +6smDwDCfOxw+iQ+twOnkLyVgRWrWhd8BjVPrgEUvaljcxvU91LlNyrgkJbP1d7Jb +9QiN9cL7xpDBAxzO8T+zf7bfipKbm9UBInhCeWqrovkl0miQlVTAmXqSJkMLQOS0 +eYZWAEvIKu5KZcDkH8epqSdaXa7uJourKGRgybd8XcJsHLTpTc/N56zqdH0ilVv3 +t/RfOpgOftYOZb74Ww++n1iP53MurOa/ZkI344+EDVSXfx1MpzDHXc1Yp1puZSAm +dIw2zfQ4MSgHHZEZ9MiY4LWdMnRIC1Wvhsr/lAqsheIW8a3Q0RMF5RVp2ZMkEukq +L3O6YZ/oxGLjBwlihTQAgwLbbaz0qDLhLOhiwhxHJ7nfrOTLMVlsKsB1cvra9cjC +6QSnyJntKwe1aEtb37255Y5bS0MgkXdSa2I7TWNAY7EZSz998o9FgcyUg9k62dpf +L4kCIgQQAQIADAUCUKYdugWDB4YfgAAKCRDnwaAAIdH4Bs1SD/9qwtQ/pM8i21Gy +njJCoM0kN1f1oD616DK0ZQvNQr8L+dRlF/MpUUwMZzYca3h963HxxynB0c6agrd3 +hq5sxtbE7IaQ73IGweHRvoaAI44ivEnAeHF+zvV3OuAJU1UzEP8RJGXe94KyLxf7 +6Pa945QnyV5Y/AYMOP4IAQeMrj4CvIRJUMEHQISbYyssqZmDFlJ/hF1QtBcP2cQB +FMdYtn7KqbhgIsfr5q3bKNzaGiG+1r1uIuFp7ETtmjaO1r7ctvygqLHKNryS4S6e +PIe34L2YwsdtBDuKcSQ9FYkcfs3QWwPoSCMhszk7ePiJjnT58benOcuIkuVd/r4m +0nSa7LbQH+VdNK98OK3D7Y1qLXttUxKIKYkdgdQ+TBA42gSMX7V/pkhF72Ymelu8 +M7Q2BTJ3Fw9yKellch7liP/u2L5OSvRiAadoJbkawueKS7pnHBKWCetdP9sbso7U +dusv4mMUxkY2JRckesHCcI6qRuPBCaiy5o2KFOS0aAp27kqgw195HkoW/kakiBPn +PYwCA/fIgvDcFubrvP4tdEnIZQYjR6BkvH3tin9sX1hrZmfQz/7nkYfU0KNvT53q +A+UCtsIehXYdYgZxnvGjw4R+GTRw1KIDDjR1SkOS8myj62FMg9SdtiUSNLnxxtH7 +hP2XYBcg/tHStjgC1rwaY86QtzcR1okCIgQSAQoADAUCUJpr0AWDB4YfgAAKCRBx +pFo9DY0Lk5rnD/9pO0AcQhCylEl+vFmaKbt6ioDNm3zEEXp+crETAgFgpMJMbYhc +15iweatef/Nc/SUCcbcVd7NgJ6gajysLsTpnjGys1a0zOaLeerU6N2G+0T85piOK +0Phdu4KrC4wGb8VsHjdJYUuE/JKsIVAYbug6wCAABynxdYvKY2K7MfXP6chraxxH +jsZfdusMSfU55XJToL2yzKN1h4QScsrGZrsfGNqYn7MHbVARKducs5T7dHQGTC45 +c77YNg6pHpIBKuD7L4kdrxULuhc1V/ztqv92cgWh2xTwdp8G3XYxpdW/lnolfHdO +lqZ9kdXaP8wB6a+wonkevI9MV1y5/TImbenxsRR6kUQ7EcBxzyVGeuqtZlPqgdCv +eeXgyxiMQySucVIEpdNyPMwFghGu+qQHbN4oMz9vhRTSUPzerSRIo1C4aoFsDTRl +jtpd7iFJGd3LNA518iAxv5JhZT1w6ZLAJ0dXC/c/WgqBjS09YRNurgiHTDnZOIk4 +IFflMK8v40ZMvroS6WtAv60JCywYm0us+WYtZJqpC7jQAmqM/1Mez0+cJIykdWib +ef3UpvHqJUns+LYi7bcmeEiSj4UDD/WhBAquCGtpGJoKYs209MQwbfw1u+Qvtu4i +PLY4g0e3f2q2kW7GkNTzJ32ClSawJdNGOOZuwbQjEEnTRxWiK6uuJyP/J4heBBMR +AgAeBQJCiLwmAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEIvYLm8wuUtcmnYA +nRQCNXWcvgtk4CiTTBWqGWWZRjViAKCn/F6maM9R5RzuC1L5ER27f0AjbokCHAQQ +AQIABgUCUgEUuQAKCRDcqyL3Uk4J5yQoEACg+pT2dh8WzQG+FXVXOQndpImddsSG +7sHP84te8URVXUTRuiNxxCisx13ATZaIiZWOHfWDtE2hiaVekJdxUZw/qH9sfnvg +dM8h07SsCGeJp+y2SLuDaezr0xI2B24WvsyA4WKOEvfVLp1zahsLLkufYpyWQTTG +5vs3/hJdb42prKdSDr3zcS9kInlPD3fhoClsar/VcO+qAoSwxNJlcPeQF5kuPfKi +Dmll6sk+zr/jm7AbEfWvZTRX4jq0OZjo8OBVwfcZwVHa9KW+alswzGsDmvbzRllx +KJuR2CNus56aJ4p2lXhJBQ79zXwjTVP4BLPleJyP3lUkSDXSmplUBpajFm/aOCos +TZ1GLIGa9EzudW6rUnzMe7vR+c65puFyD6elulTZrmCM7J4AnJYA3xu2VfGRnLZI ++eDcfJ9En4X5UOxqjF0q5TCNSfg/hAAuIMRUzRwx8FqpJAruxKWEh13+nr5Hd+Rh +XmkwIijotocBQVi+8r7pxv12ok9Z+wxiCDO2F26o2NPWoUD0Pkdp/nVKrf5PlWDK +CedR/3W8P/ZVRXi6Ox7T/Uq7d4hG7UEinqBSEN2BRJYXhVplqWp43EFzRP7SogVX +PmB3Syomi8YTqQpIidi9hCQvWTegnSBI2TpRFUlUQCevrb7UoSRpdCgSiDu98eNz +Jo/4TwZN768XeLQp5L6d55Gq6LKTIChpbWFjYXQpIDxpbWFjYXQudHduQGdtYWls +LmNvbT6IYAQTEQIAIAIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheABQJMa+3fAAoJ +EIvYLm8wuUtckz8An15wBw95UP8FmzQ9tsNhNKjDZr6tAJ9S/RotkBP0e4CJscAO +nrctUaGIDohGBBARAgAGBQJMbOsXAAoJEL0Tb4BKKTy9sscAoJeEXI2fss1QzHXb +OGsEyqjH2d2sAJ9h+x5DGxvpiZaqAeDu8UUmZZJVY4hGBBARAgAGBQJQ18fkAAoJ +ED3mqEpo0HLmKmgAn0yiTDUzlemV/p/HDWKf/JVH4vV7AKCOxGbsPuCVQbHN/E7y +Z6DBUzk1EYkBHAQQAQIABgUCUJosGAAKCRDtCW2T7u1H2m13CADKXHfhLJq7s3El +xnmp+eUzTmntP7wEqgHQJKPMN+WgZ8hSDRN9+PNlZhh0V2wgeMyygn5cP+LjBYnm +6+zsh+n/hCN903u3DsL9n0OqcrxRcI0HvqkuDM/uNCfLwBPFgvZq10aIlUzYzUjU +8GKHWXGOihIDF59zhdICSqarVWVqtXIoH+ICktjeGoRCPlGRaSc74ceUJA2BKriB +A817k9xtr0bohv8DC7JTEWtdghp2lNAcgdXQwNPA2hPxwUAgcM3BsiowJCGiyDKq +lrCzTVR2JyTzH5ZZoAYNnQbvekttIadkJmnFSxZ1m6N9d4zRdL4zp10spDpqPtCf +vg8jbixHiQEiBBMBAgAMBQJQqW//BYMHhh+AAAoJEE2MxHBH5GEMP38IAKN07Zi3 +LyzvttFkOqFtAXmMQHSpt4OYaChrUpmwrKaLXaNRuph6AvJXZjPUOuFMegOD9PNi +1ExjrHoRVE2tWwagtGOU3iyNuc7DjOywuaG5nafVUBnkVjtwPapZE7unkEzfLEyD +ZXJzG3MhM6ihIfaKfV9fWVJhnq/YTDikUeIofmIQKtxsI1L4gKFK/HGxy/cuYSgd +92HDX8K0yP6clP+xSwk14H4F5Rs8FudAR3tt5uMR/dFW1fR0lStBxNpTVXxL7JTV +gMNdPmZlyqvjCoqP0oFtHhxjZskXFlLVa/r06MJXETQT/cEWNP8BxBmsDERF/TB4 +d2wdxyiEiMDQo/uJAhwEEAEIAAYFAlAvucEACgkQwqvyzlTQ8EhwpA/+OEnGiHKO +GLeitunf+sg9i9A9J+CYIZBm6UNqJTxZduWr5AY5oBL2l/yiwLYglJwnzEpZVeGS +VRWbVpZkavIj0JBxatncVHkq3msJuUursruVgVx99Fo4YwgPQEnb4XTHlftCSaiK +1t52BgLQTik8gD87S/jGn1F+wcOXWxF0Zbo/sgJVt0NjFFIg+1QApKYPDLrbUm+N +uIqGD9Il2/VaP6KKpcijSFw8/QN3yM9Cm810yxDo9f6DggACB01MmjaTgiFmr4nr +3ivwCyBYrfS6h/NLcjOrspbLMjHi/+k7Yodve4kvkk9uYwB1D0ug88GCuQGSQ9YK ++FPsmcgIge0e/HCoc1kJLIxiL00ab09+Bsrb6qvE/pH3eDdsZ/LMD3vsQVE8z5je +nOmpJyaXWD4VwaNxZupMynkEVO4wSvMCHcYOQrtSH8u4PeCzfE3XP+reRt0BGTyZ +DiDtDTiqyWueaEWqqUfZh92O9xuUxSIa0Cfzmghq7j2RTXz8reVUCxvLRK4mL8dS +SF+Ui/D7M/rDXLnm36LaBUj9Fno+PG70+1bQN85H6FcyKYgXB5rNOBgGDCOBnL33 +F02gmEZPiWgmNETQpRzIU8CEhtvrSb4H2HL0VgoAcY1L3dv4p9jUoWcDiLbOirkp ++bda/CWMR2Aacx0ozA8ezfyoQ5fQET1MXKOJAhwEEAEKAAYFAlCapkcACgkQmuKW +/QLp9ltS6Q//YYupqzfpeCXdJMyXn2oEIqnHO+ZRIxC3K8AO26VDXxXE7C4Dvplc ++CZvOBMDMcyCxrlE0n+OnJf1oSma5O5H9W6AzLi3kzlkCaYNDIXi8xzDcHOunQLe +RrM/NS682IGPsBrgEKbXtzlWMc4LeEMwe7AeGapVDNStVB76tAzzFnuJWJs+hgWj +4HflG8j9xipGXQI4FLh+VCDeDMbh1aDyjz8u8feADgOu4kmh3W+nejGT9d70OC4C +wsRPMSJEZ5XRyYfYB2LGrbsylY9vluR6yDgTNvL6EGYJfzg0i9j85zg5LO8v6dl3 +LlA94Ti+1pip+SQBsMXjEsN3wQMqgj4QWLJfhF877LZsjLklDQPX56i8yaVJEP6j +FxYK0h/KnXT4LxZdiXIYmBtIZZd8jvMLHc/wZV9dx4tTK3M95Khk1A4RB9DxsmKp +WKXIOekzU3NrGFF7WQCtkSyqGsX4OXuS2jBmFvFUX9N5kXlY8xnO+wNRZVRW303+ +UxKrJPEBFv0G71TdMWuStqw6CebkMVXdtGsHGveeGjPVQb/KxEwCrZI9j+W9L9Ew +LQx/aO+IL8ObpfxFMIHiP7aW1qowZue9C7r/0KNWeEaGGzMBWRCBXE7DQBfJgybr +GaPyW6WtreH2bRmLj53gb51qhqNfSMitE4yJjeAgjiy+W2wQjc6Z4C2JAhwEEAEK +AAYFAlCc6g4ACgkQz+7zFlG1/eiy4A/9H/RBpjtsUzV+hgfk+WfHdSFKEO/AEfXX +fd/QhKfUWBCpzc7k7vZ66+GnEOrwEtQCxfQPAtTmEqz2wzop12cbKIYut51Qs6FD +zVqtiSVVs2xE2vwyH5UupXgMT1/CJtG1nqc6AwEacv9nDNV5hFqtMxEL4JePrklo +mpiEkWu1v7bwxvelquVlcN0bd/8Q2RuyHT1YM7IRQM5N60euTd/iVBJqN30nofiU +0bduDXdjcRjTaJzYVWhpQbgvm3ytr4B0hOQ8kMgwjwlwD45RNvQJwadWyhV2qHTL +wub9vMZcK4fJ7MH6PzALun1ymy6/pNpVIWh3UbsMDjYcbbULEkRP8MsVgCyWlEUU +pD2kald3WwMiZIz6XOr0KXpf9d7mrL7VMpvWA+lMatvG82rYf1kc4CAAfJ9DaTS9 +LTR+cAsJWmAy5pLtddaX3nOLeyCSnl5xAZPQ6kQDemMMe4OGHUEaJFCoW3DY5WQN +tRGYHi9Ml2DcH9poHPXkJfSwTOJdiRJiQd5MB7VLc29ojbWL6ZVXEkvbA5UAN3Zu +xMpTNERxVf0UvcrXK4mzWEujHb6NqlfJN9BKUsg1iBrsnvd58nefBg4K5TMDS8yr +uhx193AJeGfYIdoEtbVnO/skvqKctxBsT47z6dlWmaaaYfQM1jiFYEMngkJj1MEz +TPPKN7xl3haJAhwEEwECAAYFAlCiSS4ACgkQSx2eCKCXya6aew//dWrG3KuojGSX +3gO2JLSEncPgVmgAQRmPEIT5bDXCsToDK6jj852l+yEWsLk17niHaZe29mYmzlMQ +IQQL3lhDXa1cfK+EzHVveru9A86lsw2RXEYmKvEnBQZMMnbDcu3eHl3ZYlMC5sQe +eSYI5E8fGXpw/0aQGLqWzsf7/aQQnYSNl+TLY09hHI11jOiulsrq8oOEg9zhtO+1 +VocWJt0o30Hn6ag5fxTFtfgot6S17EqN6pJEICT/aS1eDBxe7Rk4UtaDBPXmVPq4 +B0BFFID++kyOK0roFjITMrCiltSmoEg/LNoqj36nCq6Mq6nSSpuwtCxYpP0/gUnK +73J1Ja9thhVCfJX2ySwP782bzwaHNZ7UTFO8j1/jmG6hz7e4gCzKayXoVkVfrTM4 +mLVIOU+rAwykTEIslGWMYb5z2X0WjkY02swEcTgS/nDy6cPE3LxR/2MqElHj/2/V +sutyuCqaTwh0Bq6Bg6mn2mV33zT1mcJdJ1ZGEXXYOst+8RhYeLuFvUKoxgIfD+IA +1lQjdRJPyW9cF22hdrtvYP3vXgEAHKT/pEt5OWgT1YtJtentkK5BGyEgbsQtigjS +DYFolGaT2YLj/E2A5uUiNbndATy0+Pidh/YfpRjVLl9vxhDON9Ktk+9hAL9CEn+3 +8pdTCoGi1/KLFfwfINitBfJuOUwZg/eJAiAEEAEKAAoFAlChRUUDBQE8AAoJEGLU +j60WoN4BNNYP/1iM5sWv1Fs4l8tHEXKgVmukRPXu4QktMfLQxFP3PnqIxRZUq0XC +EuiNjgNXtjbG9Y/u+KLMj/RqUZxoDIQMB1WsE5tQnU3Z1Xz0rpuSfOchJq2pu9do +wTBX/7wDtpv3x2EETgJ3yhpZneIBF4P+9SPO9n20kQWBx/NYvHQmBNva4g5fwyuk +9DuB/RiKXQzpG6MfcIMcP1a6sWL0quEuFrSAm5vDFlzF4TRdwubR2m7p0MDXbRxy +WC1r+V5IEea31S4pzTH190ACvtIktsNlBXc3c0kEIjQDrqKwIRHPCKY4fTFcVHbr +e7bQEeq2Ah4QBd+iQhcI2Hh1C7l7nBC8EyGGGxstmU4abrpZAbiw7OOEuuJp5yhm +ctLlG0jxiDF3v9gZHh3vqfbcsdV7Ex9iAvxnazCrIjBYhSHnXIYQDuTnzo0fc4BU +DGZkNilb27FeyWDUb5IFSQFi6C++xYzpVl0Mw32AAESOFmUKDnb/OFM9fd4OGylB +hNbi95WhlholJDKlWrHo+8vK0rK/wSKqQ9GcjHdRTx2RDrRJ2RZS//Ru8lfTKsc8 +v2LabMQ4ei8Qmzfn6YnHmj5Ugrqch2o2452J07YQGd2jFWnomnKpgWs/IH7bWCRL +H4NH++jgFvKx6FeuSn2ScjFwhf0K9zypmIIzIcmcoOVkzV+zxvdcEerXiQIiBBIB +CgAMBQJQmmvQBYMHhh+AAAoJEHGkWj0NjQuTY24QAMZSmFMXwxTGl0CJi9YQQuW9 +2JZI/20mUTEEkRl9diTOlP+QbSK9YGt0xOrigygO74biwrUVivZ9m2+aQzLLQQXr +4k0eABJKBV5JdGJ9xExyceiqlDlYbqXuJvjp96T7TIX1LOxZE9OXEnUF4TjvxiMZ +V2QMCWcZbWJqc2K0OVCmGOMSTKxim3xkldAxU24a+Q2Lzu8lT9gcx7d7G6PyDL/K +PCKWelgqASonKqnrghdFiTrWO6ddMpPg7NpHbCsvXMD1ZTcv+el78To6mlug8Ui+ +K3bIDaCgmJkgzulnAYvuxvg1DZIUhMl3HOjruuo3Bx0xsYxo9ZfMRqpcIIAWA9IJ +1ppnAOO6PV0T1Oyy/1kmXt+/f5ZyjJi5i0CRilWahvAODegM29re4kz1wm4L9Z5C +GHNXfVIjSU+tlE74bHsNQJ7pzGJWiFoz1FScGr/SRN/IHuy8Tx+OEgxUzJhmysVh +pJxyjKhE0Y/8s+XHV77PfUvWkPgwCLedxUGuUemn9KAC3kStU6XSRTGkFRCgOk0d +NY5Iz/vyqBWYe9JDme4hhrl87FdzUq+AwsvuHus8mQyfcmH1WabyBK9vXKC+0XCe +DEnqevIhqL2+jIQH0lbx9RGgYj+OD6RGumCHuz9w8Ma8z1S+kCENkgt4Ft4XO301 +atiZnbVPY7RzrVrK0mJhiGAEExECACAFAkxr7R4CGwMGCwkIBwMCBBUCCAMEFgID +AQIeAQIXgAAKCRCL2C5vMLlLXCpdAJ9irfDJf5o9ZVcoMEIpLQD5t70mrwCggqee +QJ+wuZpJvvcleN3la0hQurWJAhwEEAECAAYFAlIBFLkACgkQ3Ksi91JOCedh/RAA +gpf1cKJqoV0CloEanGlUcERubokVJwnbEBm/AY2F3hD1+ClWp2h9xMPpnmj8AHLC +inWhtJgTD/DRkS98Wg3X5brjYQATjfdlxyCHG/DTTNbxJ0zMujrYVPrq2fCuhr/W +FvUJRP2/nV55bB0YJ+rgecwLQ59ADDrNAYfumk0XUZBoUUWnaREN8OMzko3MrkNZ +4js5iZHoVPL6ssl5nJ3OCZPeCWerRmiuH0Ir4dvEDYRVDSDinYOX3A82B5PrC3AK +fTBB00gtiILuuLCekVf3RWO31w7PJFg2kELITN7pT2ehpBxM/Nwh5YcpPj1akIE6 +5xLZZEUpwDIjZwUn6zVbDGDemfFVEoH6dLdB3ze4amWsBIReR74fh5yQIaaBqSRM +ruJyu56nnEmli6MdFFm73Ohk5ILmftfsNjCoXNzt1yriBx16Kb99fkNpP7QOX3hc +XfZFfI3n4WVHq+Kq9gmXh8kRsxUflbHajd/pcpQtxNI096tcwcvllst7CAXp5a7R +jtoW8pC5K5rcO8+8y/Ecb1IoPz7KTdPpJUK+4iWecK34EZsSPwJ2uHxuOmCfm0TX +27APMfIPRHiqtQTFVGA4vVyvZGEkwzJvgmUwOSM2g2UGpa36EAvzeXtDWposF+mQ +XMGrZwkNeOqZZeKImu5u+SLDKdqCNyIckA0w0jMQhAW0K+S+neeRquiykyAoaW1h +Y2F0KSA8aW1hY2F0QHByaXN0aW5lLmNvbS50dz6IXgQTEQIAHgUCQoi8lQIbAwYL +CQgHAwIDFQIDAxYCAQIeAQIXgAAKCRCL2C5vMLlLXC8FAKCXjf1kpiLdAJNa1idv +kYSwR1ah2QCggF9shdI3ER4/QBOLuYxdV7z8g0aIRgQQEQIABgUCQpQeKQAKCRCs +xgFlEcAjgtOsAJ4y2bA/kIbBgJfievOrJhWphe7SBACeLzH3Q406dYDcdpLHMdPx +ZGZ5TAiIRgQQEQIABgUCRyMFiAAKCRBZRe5dnXPN1w8SAJ9ltVg9ZP86j02rQp3H +JYdRdINY0QCeKvfEdzlhTAPVOK8/aLaDx0B36dWIRgQQEQIABgUCRytT7AAKCRAk +H9IOoZyd9iUMAJ4k0yVCiOlNmxvo074OR61taucB/QCfY4RpzqzrxxmZvDrEzxKs +dwOMwVaIRgQQEQIABgUCSr+XtgAKCRBg7b18L9CW7TirAKCmZyEodN/j5DgRpuP1 +iKaCVS0j0ACeJi9HARdqbnM/cDOVTxkl5T70zaeIRgQQEQIABgUCSsK59AAKCRDW +TsCv1M79N4T9AJ9p1/4Y0tv8J//9sk8okCBZ7xRIzgCfTJLYdgg120NFLomI/RpO +N9E404CIRgQQEQIABgUCSsNB9QAKCRCqDNHu0ItH/rDbAKCHOnF8HNbQOS7smtnC +GKSMvVdSbACeJ9gHvuOv20txOlv/8U6zfrpS6ZaIRgQQEQIABgUCSsONBAAKCRCH +Lo/V43jDKnOaAJsH+DOLTTioEIcvza2QpZEk0Gnn0wCfV3aQ04hd8zaRxXtHXZxe +U+GV8vOIRgQQEQIABgUCTGzpnQAKCRC9E2+ASik8vSZvAJ9VGJucD3yhVqzphf3M ++gGIPQxaZgCghUipxRlkbkEIZzYEjAnDbA+SeOmIRgQQEQIABgUCUJ7I/gAKCRDm +FmcpZUIqPV5SAJ0T9pCGhB72hhAH1ZPoBL4Y5NC/KACffQatZrPfM5mwSBWfBnl6 +X0yVLHKIRgQQEQIABgUCUMzmKwAKCRCRk5iP5w0jV4ZtAJ93v2Z3YOE3WxefFheY +8fN4mHrDdgCdFhDDH8XV9FaCTaIXsFecragCdiqIRgQQEQIABgUCUNfH5AAKCRA9 +5qhKaNBy5jcvAJ9ZQBHaDGkEg7sHdkRnYtS06YBJuQCfcpDCdnx2XwKRtU5rakgP +anmu+GeIRgQQEQIABgUCUNsICQAKCRD9b4jGIdCnG7ZGAJ0f48WCzBXe7PKOPQyW +vFr6/uJeZQCgzBtL/GWxy7cBE4fPXHkVT4dx+tiIRgQQEQgABgUCSxm/ywAKCRCK +kGd5GIAoPJYKAKCq4ZjArE9m68PfetvmPsnT6jerEACcDreP2EQEngtGHsoL0Taw +SDfU+xuIRgQREQIABgUCRxTZOQAKCRDM4mwQg9FWRlS8AJ0YIjv5NoboSMJbYeGl +4AoKaHKUlwCghZc2toARChWKsDjRThi8NNR+3zuIRgQSEQIABgUCQpjEFwAKCRC0 +s903PDUBoD7JAJ9KKJJxDokoc2WnY3wcPoUvWKqGiACgg8a5s9pch6LupiVOVxOm +m2THAh2IRgQSEQIABgUCRwP7ngAKCRCICKNp1Kj1eSPnAJ9tDbtnkQAC0pYXJWbw +akvh+OPjQQCeOpzfcYnMGPwrs+nermr5D97NMVyInAQQAQIABgUCUNsCbAAKCRAx +pj2W7BQLgfD1A/9Z98QTVamaQeLN4QNBMTMQeDxvKOYrvZLQnxmQBYNmJay1I8Jf +37V7/1M5Mw3RTsi35uKLA0/lb4Jv/97DdG/qjNk4l7iRPXPPX5ubSbrJOoAh2WNu +J2vHa5+bTPnbC0zzLuCC+rDAy1xqSU/p4FhUcvBrFplydyaWJSiX+42W8okBHAQQ +AQIABgUCUJosGAAKCRDtCW2T7u1H2rntB/0cDbQCckCf0zlkDCmeGCJDNunHAnOH +HnPy1//l3hBQPvWoGWOeTT4ZmufGEGvUkrvEOf6eM7x/cO0K5sHM1XyyPD2iyCEx +z5wkirI+6E9O4PpxTM1GDvztPvMAHZUG8zc6LZyF07yDMR/xALH3g60AuDxqGuBK +3A46yOj9XrARadQiryI/JCMUGMP2A9FqHoDj+ko9Vc0bFcLRcb2oy4DIqAyfU2io +nRHHlvBNaGrf1ZcIMJkceU2UfHjvRKnQDYlC7zgidARSPeJ74qLLh0gmf4TPEUby +m+RszA6RBarKQx25ZbVS/mNW1B05RcPnxFNZO67GdcK84dZg+VK/bUtdiQEcBBAB +AgAGBQJQnoLvAAoJEEcV3AJkKL26EjQIAKAx7BjrwGKgZFNuvKDz1zlMZIykXXeO +kaU2ISC3dG/KA5EgGF8gHlS4IMwEN47w47RmSMziR8Wv4MT7peYqUV2/3nFzccCk +3QRq4dTrB0fK3fvsk3LH24WkjRjfNHdwplikYaatyWOyOXkCR6Z19ydRDXipahBE +C/9iKeO4nSmIClZx36BvpF0kvtVxtDHo0mIinw68VmMQycDREs/Pv+PuIIE4J87m +6f7jRYKrY6uAImFW9aRy9I+yuu3Esoz6O4rYh9HURfWKLaRIBd6bSzkvz82NV7Yn +Cggy00c+eMLmyexE0rOxOJgmTULF1gLC842L6aWtwvt77ZZ3cvfO6QqJASIEEwEC +AAwFAlCcH/IFgweGH4AACgkQTYzEcEfkYQyIsAf/T7cse9x6VaBCpu/eDbKZmOVv +T3phHCrDzuFNTpr+4vsM8SCiJqCMHd954beAkt1OZ5/vCjDGsa6qKUbxUXFJdsZ0 +GRU4vnG9cvO7692Qony8VuvN3ju5D/KUkvzKoNBSrNXJuXwFaX8ND5lG/Zxw9nwm +04l44fz5sfRuShr38viY8snc/4JYoTHmpinJgYETY00ptt6flOPgQ9ZTPFXU4/Cr +BRbCnjcV5Dj6DPt7UhswqlxbMXl39poMZvXshpHTRqfao5qaRe5kS5MRWl0U02dF +SQqEzJpzbOVfzbFVb0j1wY8jVlPuEKqmxCFelNqbkYFaIdHoKK+uL6Z3pnPAhYkC +HAQQAQIABgUCSsNCHwAKCRAsjzUKFU9EV4dhD/9/8nfuVZHzuv4j87s1+hF5sRIB +rLWc0Dou00EfhOPAdoLUxRY64WNOWz0EzvIR9Oqmc9liW028NxOga5XiUsh05/ET +JAqAoJWGEYfFNJ6o3pyg/1EhYDdbAaN62cqGHbvn0LW1QeNFR23f+DsJ4te8Fmfi +ZAByJGH0hwnL12oxMAT8RXJYThv4pDOjb9+gaNzZ1SQfvSHHJC4uuJt46ti8Mn1Z +FnKr9467Ou2ydzN1IhLdsTTmHN5d+vs/SObpCcvGv7im3Uv1906YFPmzG8PZjMBC +GqzwJa7LW7E5tUbkXB7xeXpAwyrSxGvV+h9rEixupeKq6oplL6mJ4q6JVDXwRyW7 +oVstoTz8KTrZ6gKI5ocllO+TUXSAzs4bwT8wtP4jrOe+Bzsqwi5zxRI/CuKQToJ7 +eTbsged5XSgoXFJvqYdwK0n/nBZWkdzxbu/koRG5+WHlx4czdNJWp7ezoCVif65G +N19oHd7DLLJBfi07HSaCeco9YDD5yFe+3TNYNciF993izDdqcdlc/uZGCMowCCEH +3+sU9PDkevTaQBQruhqHw73aFofi58bE/ffBPKG+6cLWGpzfAh6P/kQO/7oQRXbi +pXUKYZhwvxuByxkSPLJ70T0XcfjyLai9CIBwyrd+PfdvZw2PseqwDtXKlLfJRd+3 +blQdjWBeyvMY2DbnEIkCHAQQAQIABgUCSu7tZAAKCRCvIoOqduKsexD2D/4pw6Cv +WhvilIBxOqTSzYIFe3724cRVD8v7lb0gZIP+qemZDF72DKLlPni5oQuciTqeLS8p +THgHHkOvUQV3I/uFX1Jydi40ZxtTRqE77kpqhFVOVBr+as8qf0wqA+Hvw3hTxHS/ +cH/XfWNXFwsbdf7hK9WmGkpMNkX4dNWKKgbQIdDhLSVZn12e72E1q9tVBJ+0i4U8 +7LkNOTYmTUEAoGcqvMFyeSsumTIF46Ug+XPOX9ug7cvcsnoreEUAC2cesMVzdVYu +3xzjg5QgqlY0UsziyM4Za/nztE/zKByvYI6CCeDIpkVKWGoc/nER2h68y3Yf5Ag/ +GxpVERdMXwWoGc2l+J1AIH+e6L8/AoDZwQzMO2iiviZ6KZ69/d7jFWb/Mky4jRVV +5a81HGaK5H3HJ2VhfQeEYWnqwZiT2Xz6etVJM8INW+yIjnMWorl9/C82wtBduAln +LLHSZklI3vd+/CLXpJfcYvdwxudhNcrWGWfEjd81Ojb1UvRYATTzodUJl2SHnU77 +E2UT7meuNESC/LEPfRstcgiv1mEqlKveLjYXqxLXGUOEogaizWjKjjgajCy0fmb5 +b8UbDstwznjcX5lNhkSde8w/FAXIpM/UbNRSiCs70FZDUuD91Xa4TGPQxMhEoK1v +UMMLUOtqSW6HGbxyOg9R5LV1i57xCfzo1MCa54kCHAQQAQIABgUCUJqpNgAKCRD7 +Yz3o9cuua3PcD/9Tm/ZI11lnYpEjFCaZi3Bc2hTgXj/Z0a8ImhGRAkYQC0a44+8z +0NfkA/05ds2j8fr9572oOM1ETmTIvOa/Ii7LtBstYeEjNSXZcTpobZJSRmPAqx0E +ogAw/2/hJdd1f7WdMuzTZPJ43lLgzqdzVlVtu6GkwL+q+SUC2P9QiIwc4Suwa4Eu +7zk8wWILqTCN+WV5GEKeCVn9yY2bNrSHqZD3bA/U6Q5QWEweLftsHwhS8GPBR+cW +nVYq2qXsEi167vW1JRWRtkmROoXEJZ3HQ2/ltjGkBEz4UBFA9lUO26m+nr+EIRaC +vtfyX6yRpxWsvd2phBpdy7T8+pQWq93sL3Sqw0XRbXqE/zIOjVQRNu9L/wPQSfnO +Np3aoi9TwKZ44amPO/MF1kDTG1cFxwkeOt0sOvI2Jp6lpxXL7P6EV72k/N5Wc5Fz +OOVKV28NRyBYQmwvQG8gfqH+1r1bjIp78Vhrdeh1KbCCWVu2EYsJPI9qDX3xL22k +CvPhF666Wampirf/umN+kYejaswkT4aPGJjhKKyBwBX34q7JuMfxUApkxp9sm+Jf +wOxHfLIWv1kepcSa7iORrkdyAOni3GWmPyXIYc2//NQiWU6il8M8IAUFxw8ffFJA +/2D2Wfv9J9PfHvT7Jz33owOoBPn4Og2oGrAKzYTh+e+5Ri4JsEPfftlVHIkCHAQQ +AQIABgUCUMzmGQAKCRBMcPBob+UPHPVEEADXxTzvk8cXmPwTUI1RJb0oU/c8SZgR +GGOSJRgT3KSWYNy2q/s0XQc2kNu8QRleIKBnEZxORFUmwz5vkAPoMut6ObIOhCsh +Mbh49oEy7OHF1T9WQE3o8o0+8xXouoz9dYEeEawgwjTyxQ96TzQocOse7Ll2LjmW +7Q/ZKRlc7G7jbTjn1ebvoGtdwjzzMEqkBlluA0i69TfJpwglrbTm9XEKKbR2yKor +8UFzWeEdOhrximp7h8Ei+/WZeg7DMp9pTk5BTWPmK6ZxKgVY4XnLXRd6s0fjMvHf +B+zzt16PWvD86P2U9Z0rEc9FtLnbLxTZr1XG2zTWuQjauJch86yZK9dfa3lciOvm +grK6+7eTuDGZTKf0lPTgVNWZVc77MMb4xvqqgYXX0ADQ+izCreRsHsv3tzvvIiw8 +6XkVnX3F1M+qM6HWZUZiYaYPGT6R5eXR7iG42g0vHH7uaAMbxklfLlVvZXEAh3TL +bG2JzI59MaL3RF6eCnITOEaq+h9qq3Cm0IHR64AuZcD0e75Jo3p3+8bYU99L2jXL +gVHWqqB++6vJX5LHS1Uf+hngP0y0sd9PcMogxua3KePgVeWW6/ARHgByrGDceydq +C9lx+3tWkKT+KxWQdSAoSBwfqImNMFuDdYClILowAEPzIONmQgM7eJcDrgnMEBFx +AMhAlQ3G2L8djYkCHAQQAQIABgUCUMzmtwAKCRArEYpfoV8wuZbJD/4l6D2DQv+A +PTJU3rMfIuqPwvSaunNkS3PNOjd2aPY77x8y/Pe5xf95cSpnxIz3pTx4QAu7Sf4w +iikZyqKKgXdmz88iGy/OALpbkGEjNQh4U5zmMAc0noUHhtJiLzjtSqjQGfSBpsOX +dvmxm077wIUFWom2xOp156r/aUlYs+YgYsDXLgqqqCu/JEgq/QZSdsB+zUxmRPLp +jJXyGzBBVufaQ1k4gO2X3LZIt3jlbLjudCUdm+4E1U1HcGdZCyrZqOuITz0QPjml +E9nscxMy0PhX6mU3FxvfvucmtwJQUICPu/fb/qf7aChbIYgmLUbFy4F4hGyH/fMY +yvfZGQAOYYwN9sXp18X6MR5je06bvA9TIHqB2dqNr9JfMnZJqlk4gWbPr3rdiiYC +6FwmsjMUg2Ob0O2KPlxeUYHZOhkuZYpzNCTIo3tJdATiS6/uOKO72MHx7gIsbUVA +gISnaxBoAy1H3R+9cfA+ugZJ/IR8m4NywFfSH6oeKy75qMiohxJJLe2X7ZgS/fvO +pA3ARcOka3YnuzIkyxwWPJA8e9x1AN2PuIL47JF7mW+WHsLzwD4CQeYfJpOnOV/d +gqzTXiXNhhO216tH8Rp3NX+vTe7ZGxOa8rKLpni/DP/GHQJo7HvXvbyjHQ9XGxpt +nwiwjKncTvCQZDAC30lzVVtV4iha3a9V74kCHAQQAQgABgUCSxnAEgAKCRB8Vqz+ +lHiX2ITzEACkyrjzbtqexfdGNXVeZgtP4QxMdmQER7E3lSh/B1WPeSqKr/Lmh9Fk +V9aIPhaeZi1FPM9nV+G35P/6RBy10jI72AejtDEto42BSM86NDuux/Ts95ngvSgC +j6G3kqM/6zJvVq1XizNWjjiUlWGVrw/PNubZcOCZ7mUvlOi5J9lUpCEWguyyEWZA +YfvX0QngsiXeYRwCfE2nf8Th2j6kbUG1VHT5V+brNCpEuw9hSwId3CXO8eJ6a4Sa +3tOXxzxLntfIv4CUUifNMlii+7d8c+BaEsvQeR5hybjrUqAZ+8ASXvY31kppEoNn +DGqFwGDbE0qkN82+zoT9PE3EB1v9WXbgrrTouxMCX+fuGmhlxuJ3Cu4S/Uf3DYr6 +N4eRp0SmNjF+nh+4/rCWJEt3x0tqsKDEhWr/CW2BCIbBOW11Xhr4v0Nhv2UoRX/C +r0ZwE7e/LSAK5yy23K+8QDvBZmxRcnF4pViSov4APPusSrFfs2Fi5Ti1vg7gclJl +mKl8HvyqjruAbf+eVag8+wIO7qnq/NwdUB0HDBd3v9Eb07ln1b8i2HVeIbLyM1Yl +4hPCiDx9BM24TEVAFLIdWug8PGkg51drqpJB5Y41CGPEPIP8ih+8bjsWxq8KuZJx +Hg26WFrYB53dBklXfskYvergnSmUWHZ2VJi/8JodTv2YhyMe505kcokCHAQQAQgA +BgUCUC+5wQAKCRDCq/LOVNDwSGxxD/9/goMWkUY+22Vr0lKfKbgm98KEJ6RANp4f +yRih+WesBGw2wyKvuDaz6GyFHvDxT4WsQPNQmu7bain4aIIqk2LjkxGbXi+Hq7iV +q/alNVrwA9TR+SBD3/6lExwQpNOZgwU7fCMaBo3WAhqx89ibNOanFMZ7wEZseRwJ +3iDUc7/9Wt/l1oaU4PUDsb5hbTYPjD1MObCAwdSZ2Q5kvtNywSceGIQ0mCVWCmQX +CciRhMK4WJZR8oopMiwRsrn01QqTzVg8qasyXerXs/bqGi5eC/Uo8Jz6+AZPOTOb +vZRdZNUVKWETNlZguf8wXv7vWnl5HPFnnHzDa0ynTZWPb3zdxllL+PDip5A6ptHd +ntNaNQ2e5zd1x7MJ/OVo36NhxImFjpVDFSvCZLeFaX3YwB7apwEBx5x9eq9wkYmG +OCs3uwoDIBzXTej8fxRDjIwO8CWZZjmHupZZyS8rZkdvnoG5dk883uN1EgeniekU +Ue6CA6VLj8BmQjfupZpCc/MstP3ygI7Gdi83wJXgqAlESqTv+hHeF55+3eK6pSVn +G9iQj+3+FGrp4myiwKscRjwCnW4jF10b1IfvtKxAD9HiaU7aB+LgRbp0QtiOhEue +TK5WI5Xac5GVKcnTLLCX1VZGR11J78K7/6XQt/ylzYzxvthTRhaiyfQdgGq5nTlp +j3rnpZwrIIkCHAQQAQoABgUCUJqmRwAKCRCa4pb9Aun2WyAhEAC7Y5Aa7ArpYxYE +N0HPKnTK78ZZIKT80MO3kdiHEfIzLW/xGCNa3L6oBp5UAj7Vv4gP4XeTWhO50/6C +UZnX67Gm7SEr8uWty6kquICTXq1oA9q9dGBKzx3ciEb40gRMU1y3Z8jAtd7KjxxL +eSKPqX9NV5S0bapxV3pqslAU+5ogim2kXYwM1IFqLJ+v765t6Ekp6kqMTMNCSmeQ +ZY7DNInqyLfUAMEBqbOJMZ9gzFHDCtPFS8uD6qj4CxwrrDzQcpmb+zvyDOoUZLnI +cJipJgJzWLydgUt+FfxZZ2Fp9w9dtSlY+ym8lmF0lnSOXNzpVKzJQldQetccmPPl +nzW3PD65LuVxBvK6gSxNh9K5qyAMEN0EqkEB9hQIhCUwcY+/aQ3f0aAvmWlEvSLN +sIDSiBdCt9o4wG0gv+HZYrWwMgk0NcZq1K5vIBTkiVXrBkZNTZRzKZSO6VAWYefw +UTMybJpDmi3dO3SUj6Fl8zjqPrCZl2/jqeLT2Yo4AUOdiBK+8yJT3c1CkDgtO/9q ++o27VcUzfBP4bWQXjN3ugmxS6oOf5g1kUXn3YUKLbJXW1id60YEG4LEJBDU8HSSW +Q9pc9TLPhJDCgTe4SBTXTkUiyn0NDFIw8kxho2RlIZbQLDV6WcpOt+4X/2ppYXTV +RKN5Fl01W/GHHlC1oCILtCCk3LKr7okCHAQQAQoABgUCUJzqDwAKCRDP7vMWUbX9 +6Mq8D/sE8GuVbiZId8u40Yaj0BmiQLl5Cw7CPTJ4OL0MawOm8jqN6VrT7qFc9Qim +GMTO2gV5hBGeP6X2BD+1HlTHyUKLd2UaV5d6k//HTIE4QjNYWwwc+CxtWtqQoNuv +VwG4gRlrFOzlN+j0C4FJdA3Z6xBzwooniVMOdfJ5YRsiDC4KUxhI6u9obaz910RM +Ejt6l0hMUYKyi1l1xd9NRq8y0ZJw4C/CC2VACHwGnoWhqL3Gg98CRdsXUNMIatuE +JsWZCDzRHjSt9B6I9ws5ey+8h0lsCGEI5qaLKpAFwLc0FR9kXCLRo1FklnGL7GAZ +Cs4E0yI1MCCgYcdIdQbHQuIjzzj2QgHCpyFDpPRv4cozyn9jgqJNoqobr4Q7meIk +REXPALzMgshubSCjbD5/lgxRjPxDyUhsbHGWNPB42hKSrdyunuLKCgqi22ROLFOH +ljP7SDH/+EuYbof2Z+Wm69pYV1qggMwpYcfzMY6ot4l21vDLS2SSCLDoJ6mCpT+o +ZYxhQzHFjGKbSH1n5iAlrXzP5J2yzTFiWEXKUpmzmTkq1qNf3mHgdJLQ7N3DFN0H +lNJxptMimYJV2J4rxaTkcyqC4L3F1HiB58Z5U1sHpVDYV9ehB8a8hub8ifAXjBHb +cMSAw5f5ot+b14eypgIf1P06yTC0Wtrw2nwsRj8A4LEij+YYaokCHAQTAQIABgUC +UKJJLAAKCRBLHZ4IoJfJriYsD/9UTCqGwgRvvS5KQcmNbZoEYdt/T4EgoYVn0EDt +Ww/mjZGXQKKsjp/oyKhsrNqT1Y6JWVDbYWjZs6u6+vy30yw9pIV6iLC6NvqT8PPc +UKTf7DBZ5zLLWfFWw2qORhpfcp7yx5dbnCHDwP4cRCVvZ0OFLxhD3I9cKg0pWfmM +3LU30j+kEYE2G6UcJDghPCLeWHSzrhy7UN8CMeE7dJtrkIqYP+zlz4uOqnYq5BO2 +pcZOea3GdzkulOZ/c37PTnay8CWuBYFUob+jY/Ee66lN8Gsm/dQDQditxajnUbOD +SQk1/SmfTjsrjjnZbLJNfdiIlnm0DDD/nQUsx0lUppHiZztdmCSg+ciaDROGQjMf +d2FMetgWo2eTSHMp4BT4kUQTvJKs2DxddfX4Yr6CoxYeoJDSJKAmD/8inc9AxGyL +d79RcxcBzwsetSFTA/zDm090UttpnqqybyCSbLi3Ly6oMrwomKW6J6XDQK7aqNiv +XrYik2BFXu3NcMZ/h+nJ2Q/nAwOLbtnOesCgde3yK7PTR8OlrVU22m0ladUuOjcV +D5Ri7OCP3gTPwOXmPzU3wmynOvW8FRiwDXl5aFZJ1NOowOQj+xK9i/jzWseaROR6 +ulq6zeyhTBv64ebShXvy9hgOZob9017YC7SbaTslnz1HFyqx8fJBgxJQrDObPs+3 +uu02d4kCIAQQAQoACgUCUKFFRQMFATwACgkQYtSPrRag3gG4jw/7BSbJYzVEO4fC +tONuRojK+MewRl4odvxJUaKa1CZq8sMG1qREKBO02I327KcoOa910MMNmlHcf8/H +ahTADmlckgZZjbEHb+NyMz8+lgmzeOhDLTASUkRvbde5L7SpMo15ck7rJvlAk+7P +6EX/xaE1gbLEbg93QYffhBNePmyqKxZTaxtmX8mE+sgLjVOvgONk55ydIIQE0sHI +CtNrRo4rjKXV21jx7aAKDePzntdP2uC3CJ+PKziZMTdg0YMvdvHpEEyuPV3lxNh6 +6aalJDzh1xwFDWO7Y7TQAfd4A9sv+4Ecekedldc3p9ZQ0f/YuBg0VwNZmdGWSa51 +osUeAeOXXWDXikz0sz+Gd1Rbym9t2fEkQtuvpbMn2FxZLVJ6qQlBUZmlonlqRDv1 +LDe27D2AzNSz8wtomLJ9knJtG/fCIUSqKGnDOP/XRgwcV7HMG997Ou6JY1RmhAZb +o0IImoOdI7Bvl0VFv0GDtPe9kb8Z3wY8OJ04b6XAo+cjColnAyTB1gUK7ZNBu+hm +G3MC8HFCpYBlhML8GD9gG3gjW0Ykj19go6aD/Bh7fiVsBIxN/XjW53m9kTz6bx4r +sx2UyG7evyz0ofZfznvbb7/6figWYHYkkB1KP0j0flUwHCasJbztb0dSbJtOktme +C4a7qqY1ym3IUXbt3qblw4QFnSkfUd6JAiIEEAECAAwFAlCmHbsFgweGH4AACgkQ +58GgACHR+AY69hAAl4g89jIo+1usmApz8uzaDqaAOL/1paa/hVQ0sTS4Q+AC0YFA +boQwPdYXoUb9H2hklk3vrqY4sQ7sfB/VpzDdsfGVOztJ5ifaDCB6Ss4uOtsZTwea +km1N4v2iYI0UpQeX9C4FAqvetRaSyxGQzB0bXYmhV/CilKWC7GZNQQywQDLtXTHj +MYfYFNqL2lvPcdA4PAcpEBNPxBoeaUh+U/TTV2oNCKKfvpPqKEgH7bK0f4MLkGjG +H5kn9e9QqwlySVESElaFa/2V/lFDilObWQChiTLQIv1AqchH0qPWy/tcHtHag0DS +AG2aQEHJxwZ4f5zFZfNgEYDmKO0ZM/DRt7JolrqSyrZytVATBa6I1UYPmDQzaCVW +l9Q0RFoIAAbn8sjnZpM7FLAzdiHqaGWORu3oIyses70iGQewnoo2nAuDDKxT1KDC +1bgC8gSntQDTQ4sZYINnAnFxPtmT4vNdISqW2NvLc1rzlacXE8uGX3s+2JEFxqco +BNhmBculbElPXZjR47//rYYLKrGrX+wRgLYtW73nbG9PNSHn/Fp7Is/l65pK5Ekk +PuRkbCJ0Gz39tVIk89ETC1f5ftxyPkCpCN/Ov33G3DtN/WwcmX43k87FgMRDm0te +RPauM1i3Xz5uPWvP9mw8+LfFzUw7bDyh/Kwc0yvIdoYIvwQcK907VE+2F+2JAiIE +EgEKAAwFAlCaa9AFgweGH4AACgkQcaRaPQ2NC5NdPA/9EY29Jw8JffE9zOdnfGyn +cocMObyuUqibRtD3yEO15Yf7HfQfHq5SdEqnOHvuBKeArnH72dpOLvKkQX7U0oYI ++uf/+tS5ezf/K5Q+xGL+2Tl7uNSVVYcIqTsWfooFlC8IANB51DsdZcgXEq5o8UAD +5VkJD1jCpNJUb36SL1/IqoHGSI5q8ag2ZCQIymLliZAid2v1WrCyTyo74LUT4tQJ +DlX81SGhDSc1Y3C6iFZ07K1/YcBY1ADKfVBrv9F8KKFCfeBF0PgP8lec0H+O7wrW +tWaJ9X1n789IPDhoXeAERBIID6dXQkuMFI9khTjYrSA6xN1EcG6+vNkYtIxd4kDw +EbJemx31uxuT2rNX/v6+ZmWfalZV0ranM2g3UKhvCudnuK0TgolwUmHGpSpDgl+9 +ZenaOH9TJlolWuAnrUcC5PFwpzjt84AHGZi+OEvRnmHj6665+VVWEy+uqGe2rJLu +RqW1ts8Pf/G42FKjZL8aOLwZjBx13y3El/2hcswQTpltzyF4iF5Q+FmQ8qr8A0cz +GiPuavB11N73RPfRalY1Ffzjqy26LyiUdAhm0twk1s+a20/ruMGg7kGlb6jUo545 +n5ZYuGZH2Id4nXMELThLd0NCUUIrPjtM4IWrq6UDZCLAVu9g3YFn/4RcLdHTySFF +D8SmpsqcP/Xrk7tloicJG5CIXgQTEQIAHgUCQpSccAIbAwYLCQgHAwIDFQIDAxYC +AQIeAQIXgAAKCRCL2C5vMLlLXHDrAJ43qri6z4LPijCs/3QZ2IB0VTYHrwCeKU/h +HmXFsJwx4VunPEit9WkPX6KJAhwEEAECAAYFAlIBFLkACgkQ3Ksi91JOCefpUg// +Rk2jM+l9+qmRLZjLhG9E1X+NpPMaXolRinPFXVtqG/lOhuPFzyjDyBUZIOFpMmv9 +qgzJSJ/AXco+JzXa+d7Fcy8jK3yOuxArr4AEijJX8EypblCAhJ/RnwUscg2yrir7 +P1aoya95KHb56WFbrrvAeDCfk8nTCezp919ZRKkEcEM5oXuYVovaMihZ/lpI+xc9 +VzwDmMvp9uMmwvvl/aGNXtnUMqZ7zQHXutSzYgPr9a/txc8EgsahHawHnxKKlE1B +uPLoTSZgHBUqBZBZ3qnQQRU8XtBiB3ML33N0bRg4iJaca67cv7ClKa5NcFnMF4sA +BKNQKn68Mu0J+wgndKhob979nlhjP3eIflDj6mBfapY71j47KKuK867S4Rzhk2lQ +wsPkqYwV6W47e0iOxddXr30oL7Wro2iRlVGz2YBWjkYLlJjqEgTUlv1KLvyGyg1f +/avOrUTCE4Cv+hRPmY9BthNcJRle1Fdni6r10et4aw4eH2w5zSaF8BEZec0EzO+k +JhGNq1yUfsAWz81Y5OjB0GtlVCFkgV9hvxvbNpCyBtrtPiqtXGZ0hfaTMlTK1Va8 +XqYU2yE2WGAPn9rK113sDQtRerDVQ+fX9AIveuj8pdukQXaUYeM9Okw/0Zu+b8Ev +mBj/0uJEPKK4sm3Qe5IbyZQ5jCGOCvYJrr8SS08tfg20JuS+neeRquiykyAoaW1h +Y2F0KSA8aW1hY2F0QGFwYWNoZS5vcmc+iGIEExECACIFAk4KGPYCGwMGCwkIBwMC +BhUIAgkKCwQWAgMBAh4BAheAAAoJEIvYLm8wuUtc4JoAnjPshTQ290t8M4HNFC9k +6Q6/l3waAKCGjuqn/j2v4kHAxD6jEhUk9KVvmIhGBBARAgAGBQJQ18fkAAoJED3m +qEpo0HLmcO0AniVFzUi1Y4f157QkNxL3l70JvjyvAJ9yI21lGudkhRsZeBi9P8BC +OJsBsYkBHAQQAQIABgUCUJosGAAKCRDtCW2T7u1H2oYqCAC9Z/9XNt5wAkqqHdJo +9NugC7BRWYxlvcU8DUJPyU1dizcwdI2ew1Svkway3DTZr0wdwqZEYJX7GfsdNLpH +aTpuWV9elWsNJc7/axCqotyU5xrH+EQ5FFE1EJJoybk7cxhlw9xfns49mlb4MmNN +tFuvA1i64VKLa/K8q+8Vxf1ZsbhS/1b8wbFma6W8T5jdEaExe76d1d0u0rKrUwfa +cfQrhoNftm8tCRHbLDYOFAcviiIFyhHD4ah/fp+JpScYwENvSG8Q4C6wpfGce0n+ +DnU7cIkAWFKP6WJfy7+h5tXGY2W7xHx5uMwpSRdf/5Cfp66Q4rfWLcy/AxQSzk+6 +uNiKiQEiBBMBAgAMBQJQqW//BYMHhh+AAAoJEE2MxHBH5GEMmpkIAJEk7mqZ9UF6 +kXyCtybo/DHl6IJA0+xIWFKHj2G7sY9C3YO9oSX9KorGf0SqcFIotMdJYAx/pcmC +vuvd4H86GVRQ5YkeJjwRANVwJlegbLHk/YW3SEgo0pfPrWoolAqW7ZWL3/eXYQAG +1Z8ZeLgAUZvQLLtgjhkVjuHP7c9v7KhX4OZABT7kvIOn0BdxES8OeLA9p8fUYQhg +/J7K2RbjbRgQSmC+t/XsRVA85+OFY84rGZ0DlgxwUfdzErmgPu/kjoc5GK9MHCJo +5dzaNljgbHCU4+1KolACGJ9DM1IagVXRY1DS074y0kiwiMxkhPnyvJNTAqNAvSyx +tX06jaqqCamJAhwEEAEIAAYFAlAvucEACgkQwqvyzlTQ8EhRBxAAhRRj5xkbFoaQ +H+pMxfSGO8WIPnJVEDNpa6qAC1eFi6cdEDk7y5NsVivEMbHRNR6icEMLZv0pXFQs +CQ3iz8UMYlEVbCNThxaP1ttmnW5vpxwZe5p/CmmX87UKp0IXDRgyc+56aGj7OWk1 +fit5VT8YxkDqiV00fTOUkC78NeMgxg/KBcc6jYU79Sv/tvDi4vmNhSU7CRYBlaqZ +noGgQ4mJ7113peFlqwbo6UpRnI6XxSPyj2iw7Ulaw6zx6168W3Oy1eS0ioJQHMb/ +Z5T2Ni/dZ+AsFrFSlMpRKir9o8Pm2XpguQysbvIx7mdOhwIaKd8vugu+csHJAzOr +CdLHnS46TmIMaPzFwON9h+4IgtoZaJLBsjUsapNmBqLqGc+WvT6CcrL2GoLlv8Er +ZFarxvhr9NeNp3TkVZHKCg/3Uav1GD7VCBvVIBKyWyNKoFEBi/C4eVC1so/qidgE +5npEtXSu9yCiFT5J81TKw5mkRffib/elxuIgTOJA2oVua6c4vKIML5Dp6/1g0mVn +V1RtiaX08wSHQ6CgUgCnxxX/ZbwX95wQiHlQ/XZreDp3Ygw55mcXz0PYlvpuFL7I +Nr1VkdYhYbDd4Peh3CFGz7mZENAnrCFGcRyEMgCvwbOHiLVamad1GI+7RiDYJnCP +MiPKxjBj9OE40cWiOEg224FgrEZRMtSJAhwEEAEKAAYFAlCc6gcACgkQz+7zFlG1 +/ejKghAAiy6+jr6dPSC2DVbDuMJNMpaQ81nM1cYGwC2xrNb/6NApioL+OsJTTbPm +vy9UQrrzpsGVEvla/wZT5OusqxpXOmzN3IvBG/TRULnXuaiX/i3Xq7coAGc6w8oV +0hxsXZ1Y22R7jy/eqqhGxkjpBwKlhKkGZg1ER1E/sqOeqO5TbtIP2gX+ULM5eVA3 +lnxpAXNzqDGAp64m/UTQEHECjqeL/GEtY6ronBeTD6CvL5YfH96y9gF2EB0Fxjdl +sNvGhq+G6mACTDWgmfUfascBIFhWli0NrD0SBwRE0Awm+XXQ0e1SOscdmqXPLltJ +FlJpjuQ85vY7ZQPu5azhcLY9l129JKJQzy+HtdR09HqdcYEiC9JTXtITmkCOXMJy +Saeg7HawN+gdQjObTHDTHZNmP6qyZPSmUdxT/wM9wbMSd/f1T9naula70bb3c2CE +RCieYUBbVdNAXLY14piMaOS42n341FLtLDwbHOvBm1pL8EXIJmDESaEy3ZeblKwK +ComzFKyFufeSeX5dQ2gQJT2yeY3Q3+6y8GeAn9syRq2KjLrfMTSs/TYMKu5+bj2y +x+tvTC0CFLpR9f0WeMARD7YWHZk6kIwYYsOhmrXw+gGbLzYrDFFHmCpWaqLN2RKW +6QbimmZkXPlL5+LMTgA4+z8hG6JT+6NjGHtLUSE5Xd+RboNhJoGJAhwEEwECAAYF +AlCiSTAACgkQSx2eCKCXya6oSg//a7Rqy7pSMJjAN2EZA8g9hXlTnfXgl+c/E6Za +Jfi4N0idm5DPuSjEBtzOJvzNqCUFrO2zl69Kk6ClX6pOI+7C90UR3ub3udBQ2Ig2 +JpVWI40n59naYCoTKmwzgqz+JGxMva3V1PTkDkDFHEuWJslxGrxnpPClW8XXu32B +db1Rn52WqFA9KD0Of0FeUcB/z6QkamAZoouezz8eaitvv3EoN7klXmaeP52xGg3+ +o7scZE78iDBVsc+cyypS+I318ZXf/2dvGmhVhciOKX6SIEFRYvcZ+XzwkirMnuRv +5rd993QfQ7W1KnTV8jCXbdsRFvXPqWsiGELBH1SGXX76922z0ltrwYCz0uvHjMdd +8OkTrIw247F28kqzeZjecOmcFN4MShJDIhvX59ffEL0LIYrarnr+ozzsT68vrNtZ +t4h8J/hz57M9wQt+F/GRN/enxrAipY+qIYTlpYtVz78OZQeWmpNrP6T9owBciSr+ +UwuxuOtZnRqTRjtZLAcZdfPjPM7XdVQhEMqrA5nzp+xZRsmSaCOfbozIke8d4su1 +eIZtoqoqntnzK4IWAEfJLyaWiSGa47476qQDjk6k3b4GJSrgMbwI3IAGO0phC1nL +nKAhCUx3fb3vDXYCFQLFEJM8J07R1X/StD0xjg/BbKmBB9G/NDfiKqaRFyBKCw8v +EIYVq8KJAiAEEAEKAAoFAlChRUcDBQE8AAoJEGLUj60WoN4Bn9IP/je6Elye+Q/F +gJefwQxul8AcxlKXU53EZUlx2xCh5JWuWTV5gZDqGHuLE6Kqd+SvefNi3R8FtxkN +puVjgWcjE9iN3iDFtr4UegQJ6VjH0jDOX7zvyNnwgLINoHcz/NlIeQqb7cdLa9G+ +jI2oKsrDo/dbWIs7JIIHZzpoprKSCFHsFdkU+D5a///uqDidlXMmcSTEFUMryMXW +AZ/AP2yUVWCgkjpt7aEGjnukx2YVi5rhWqc+lir+KreS2vHDyBsV6vlL2rG19g8K +4A7QN4yIF8uh4gyXP997TblHmDwsWR9ti9Hgew6WMhwAMrgcmz/QPfuYDZp3DckZ +Noryq32oKwetcoiz0yoQTvlWe+y/tk5FLgwqA8yNAYdI/1061SRbAylIcEcP5bcH +I1DbyTkWBOG/8SLPbDRoq+czfsiv1z44bMCg4b/u+mXZZ9b7C6WnB8nE30biqlhg +olQ0CmiTWlzUJWwNEeT1GoiiXOMTgdaEwIuF2pJaiQDZ35d/8/Ya9PLaFVrMQIAO +KS+lgJzb1SJsTgfJsL4NLzOamrcOP3iGqt3AzJtLCzYEggxfeSrjWv5W1tUgA6mc +zcg9Wi9xCwSQzuKkI3z8GiFnZ2HTW4gb2OCgbOYaPo16Run1XR4heZ5wEtblvg+J +S+yI3nlvCYB78WQF5W94vWjCHXGeL5LxiQIiBBIBCgAMBQJQmmvQBYMHhh+AAAoJ +EHGkWj0NjQuT3yAQAMNYIjHpRAzeNfsKAFrTUdtGYQcTBV9JMeaiA5MS5APVRyr9 +yvgV0mx88MqX70ym+/mNpS4rsXbzWO5yjWm3hVOKYRroNLU6vACjllEUJo4oqH+g +Uu1eD1n1uLmvI83rUZFni0KCFabJaIS7kna0QyH2HpusjBKDl3fa75gaP2NwrVQX +Af2J/REeRWdNEwHI3SGUglDQPmRH/G3oo5VYJwYcjjmqEetRUc+25XJXakMRvPhX +Kklc/HEpvR+6CR9FpdPYfQcSRSpmiwwUo1duXkt50bRtFZcIBxbU8q8eXPSyA6LE +wd79eS5bmKLtPEXHfLgxg0Ej5YmoqKOYR7suYmUIb3UZYVbAKf+7ncgkHHw+aNeu +SmWGR8X6TAGSevalqr86szU9ZShQbVSJN/8hufDphDym1rVynuAF4FYTxn6B3LsG +G9hVG3jCUFToLSHkCDJ5elLO5/xI5/xh1106l7ctcEqqTxTJa49pAZghnaCoZCt1 +vzbvbmluf34UjaNxdSenlwQ1Ahfi3ElDbinWESKix8DiUfhCHoBfVP/W+hNLCbYR +GA1BcCT6qEq+/gGgl2FWR+F52c/UWkGcQz2vbn2yie6Ya7XVULsuqwHmYvgru3dG +x5LP5SOvLC09fe/JniTkp+U/iuRAcgJPwpmdLTJgKbeLOdzPBELsHjUbZl1+iQIc +BBABAgAGBQJSARS5AAoJENyrIvdSTgnnkTIP/1LQRCLNvQDkmmFfluOrTfjbdHYa +DpYGMu8TM3ffif/JcOlIVnOect1bEhG/KdJqsYC6FiO9ox1UdUy0EHYlI76S5Alu +pT45XV6jQLF7DkdNIFjLNUtaoOgWMF6NgHc0Pa8mLVc9dGKhfQNTOb2AeSIR+Oz6 +dU+88ycRwgJ0W9BgDiBA8onJI+/eSwtu1PSAxUCMArzcufB1dvIM5w/RR9EL4zDz +A0GjZX3AzoJPPEQtFWAmJgcyJRJWC/sGNpEwgfLXRXXj5Z0SAXxNUd2+bXOOhOuq +P2QSQxD/8tH/Xbaig9CtZKYODi/Y7pwj8rxlT/CArRAiDne6CDtBPHhwklrzmTfc +nS1KAcZ46FYAEY05Taf9sVi7aC8ZqtSgd+osaOmdlTV2DH2toVoPlj8zlSJ+fKy2 +NcuILz2tIMk6kVeaimq8UYOh7JfUMxCICKlKb0+1S7BbEiRO89s/5UXBK4x3e5SS +5LbvS26edsPIO4RpL96pZyFQZgcjXVaP6z7zeiNnR+hs/EgegPoRnsazj6QQEOhF +Ukf0omMssX0Bom3tHVoUipb1Dws6pfkUSp/wgWT9QS5G6DPGDvs/cXrLK4MlGI4j +iaN3wk+yTQ7e/rFLI3DhaO5k1msyuWYqLfhtMCKuk+5RIw8eXxtUHUy4jp11ikXG +jNFe/VhIwvumhdxniQIcBBABCgAGBQJQnOoHAAoJEM/u8xZRtf3oyoIQAIsuvo6+ +nT0gtg1Ww7jCTTKWkPNZzNXGBsAtsazW/+jQKYqC/jrCU02z5r8vVEK686bBlRL5 +Wv8GU+TrrKsaVzpszdyLwRv00VC517mol/4t16u3KP////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +////////////////////////////////////tDFpbWFjYXQgKMKow4zCusK/wr/D +nykgPGltYWNhdEBtYWlsLmltYWNhdC5pZHYudHc+iIYEMBECAEYFAkKIxIQ/HQBu +YW1lL2NvbW1lbnQgaW4gQmlnNSBidXQgbm90IFVURi04LCB3aGljaCBpcyBpbnZh +bGlkIGluIEdudVBHAAoJEIvYLm8wuUtcokIAninHgy5hCqEoxfqSTDEc5GRZXsfu +AJ95muI9XQjx+eRj7F+3/cTXLmEwIohGBBARAgAGBQI9XMKDAAoJEBZ6N8vetRs3 +po0AoI7CX0Zww1agRt2ssm8xAQWX56ChAJ4kZCOJOxuG0OlVg4g34JW1d+Wt8IhG +BBIRAgAGBQI9xKKPAAoJEG/HQbrHj5AXmk4AoJZaqEy20gsreRQ05nti82++Oh+b +AKCgXlOmVmI3D99A11DJNbxj+gtKD4hGBBIRAgAGBQJCmMQXAAoJELSz3Tc8NQGg +oR0An0APjoG8uxOXhHCE9ZTfJHfhqyvmAJ9UX62A4FmLCmXs3q7UDVMOBFMF6YhG +BBMRAgAGBQI9OuYmAAoJEKzGAWURwCOCD40AoJ4D8mYfnAZoLq00No48GAPfXMLn +AJwLgVM3/AImeqTZ9FK3yeRnNKL614hhBBMRAgAhAh4BAheACAsJCAcECgMCBBUC +AwEDFgIBAhkBBQI9JHxqAAoJEIvYLm8wuUtcgggAn3rYFgdTmuLLovhohyE0R/N4 +5h2FAJ9mil3lo+Zwaqy3xxWg+ot5JCWtrokBIgQQAQIADAUCQnZ7qAUDABJ1AAAK +CRCXELibyletfMJwB/9HdbU9JxDZW2T22sYdbQ+tQBtxWT2s/tDswsHE5MHUUfBB +52CUko/gdMbpMGVcAcUY2beP5CFB7quUfwmkv4AwowhYA1vgoQ44mRNCYBEHJxc+ +H/wFGkS+NLXFwWin7N0MkQA9tU5s9hNMxUx9ybhhxQx2A8g7swe5QOd1lJ2Rd0C7 +NtG9AZeXKDRyi8/bM8CbKXQl25VAATK1rWWdxuVVwN5MBayYVNBXneiM1G7aFiT1 +KjR5ODHyErz6odrOUZ3zAww2rbChKkojvH3q5ndtB0bDivdr0q1W6R0eiWcKO6ax +0JvdncZnW67GdueqVquyX3BkGr391GTOQG8ays82iQEiBBABAgAMBQJCic4uBQMA +EnUAAAoJEJcQuJvKV618mB0H/09kd1ToVYTz0n+XnG4t+/BO4oqZsocARGL/e2sK +pyV60LMyeRLTUqK29UTR4jeXT+LyBSTKETdBDmzszY0pTUpHdH2RRLgi3+olBki+ +tZ0yNcWlU1AlBO9jOnMXvGFE/IJgTTdX5GTL9DzlxMrNb1qWsrrmynfjzXuGCGa+ +e6pOMgj9v2VduxAToBSA+dh7xAlE9MWxkv8AqP0HCl/pJMyTmeOLGigYQbXurwPB +0leklE3PmPZS3ZLojN4raRI/cqHVr4HvDCTtrruk8gVnB+BQ8hX2rmjLZWT+hIrD +THxTD8dCk8lsCoB9bs8Ph/WEfkGHKuUKk24DnJW8u0JgUXCJASIEEAECAAwFAkKc +6xMFAwASdQAACgkQlxC4m8pXrXzhWAf/QQJI3xuzfYGAeGmcrQS9RtD6vFVxdinc +j62zlWUyCVaD4HBeye41CW7EiCID9ev4Fnc1POAdnlRmHRuIo/v9Wvc+Ryof1jvW +GOD9U2/1fPFRcg7iFLKQB+t3woQuEUAHoeA/w0d8NyknS8f3VI4uRie8gleSCRAb +z1aYBjbJDStCJ0eID/bfauACExb4MKv+W3Pv/THjf9WMHD3NbPJG50aUbFf1TfN7 +x6xuFtnne8zqsvZg/8TIBaZ1Zo59XJqm5OtaAUD5W7btcTgJZCYJ5YfUEhir0Rab +k9jzTLqmEnUHjWyo4xg5uZslgOAF2Ba/qKwMp/oPqU/iCW2noHFRFokBIgQQAQIA +DAUCQrdVOgUDABJ1AAAKCRCXELibyletfNIqB/4pc8oZlBq26Ny3VQNonetIZCn+ +w6nlm2y5fCvJ2Oe5gjT8SrHJQ8DdFc7q8YwWMP5+L78YTaI+inClpM9n0IobkuXK +04LyuebYCY/m8tqb3xkd5tW0qIR0s0LyLTPvqXdaIiIM6sbekDFp17icrpuXkz74 +/d3CwhO4wHmkjyDtu2wonZqMxnyZr4Q7t1LcOu/EmnLkZOsyle0QTI67fxjrfwdz +vwHzrS6wzLPQUaEAwlK4x+riTcE8HPeWs+61PXQIhkORlXFCFOfhrI4R2qq49tXy +v1cWsooest1ux5VHzzUE93S3ZWi3hawpEsPyepOMvdpnkQwJ+pHblvoy/3WviQEi +BBABAgAMBQJC0RcQBQMAEnUAAAoJEJcQuJvKV618yhcH/RXZrE2HovfSnrBbI9Pm +UgOlo14Xy+fiJUGVZyMoUO2nznSTCR10+m3oSitqMGbKO9x0K3c+/wtkYVH3ZI24 +N649QttFw+pxSqVWtKC2qscmBA4j9yTq0N+LuQp6otnhIgU77G8cwbQS8jisNnz9 +VwZlwD58A7MecfCFVj9fHwrQmeIA9GgrvSF81RqSJMxQXT1N76nqJn+oHDAcAMgE +ctrf6NIcbresAr3z9bxGDRkIglVRv+xBNDRdS55yee3DMCKcXqveFS86HFFLov2R +K5Drcnf6kl1hhQlJz3rKlBw6b/E5k1UXfycyj2u+M7F/3b/vm6N5A5HEomMnDPWG +MvCJASIEEAECAAwFAkLRvOgFAwASdQAACgkQlxC4m8pXrXxykQgAjuYSeK7vSRpY +zJ7xfzhMmrgBHi5ULDG1jHH0+xxYVLoKBoSbaSjimII0zq9jhrSdbtiEwDxEz9ky +kdWykuif3e/sJ7/Zzx4fYu0kU73erWeLDCztuzzujKzhLFxI/+HGrhRNrhg9noL0 +n1zxWUi/aShZI5+uuy/fe5JMyC0P1AybRxiiPJQ1QxpEbwvMKvE97V4y0e5ZQ3bI +MQkuqG8cWmoDKD92D3fS2qziVKksaeG5MdvcJTAosU7UbJfy3uF89DR2dney1Oqe +vbTwmWa0VfDKxfk12Pfwib6PRfI1XLQDrPCJ4e+9cODx2Pgh2XT0HJV6TYZMhsHP +UiEspqzlCokBIgQQAQIADAUCQuzDQwUDABJ1AAAKCRCXELibyletfNebB/9Wfeio +CHtC9CQdEAXomt1+BYqX+7V/1QgfSWEwLNxMIFTAsBPt9jxzT8cAWkSY9sK/1KUr +v5n8e40YnE3JY/rz/KV7EXJyW7lzVvVDn0qE0zc6t2tqwsWbrAbi2m0E8fNRaN7T +M46ncyWHkoxTIY3be/tGQKMYpXcDuRccUhum1Lx6/JrLqApFpl0XRZ2KH/PNxaKy +VOWepmpCJfsdHZE86BHdVjKyZUqa2oHJy0+unXcMJFsx+UxyBg7GAhIlpr+KLjJl +qw+tyUd4Zj0VU/dYuAn3ip8OJTOFl3WNAyFoOnD6h0B5yAt7M3jbMb7emllL0b+m +kf8hyfDwiy6U78zPiQEiBBABAgAMBQJC7WmJBQMAEnUAAAoJEJcQuJvKV618kpUH +/Rpl8K9vRz6pystln1xN2ZX2n+MJIPVEOUW+EmwbpHzV+P88Pcq24zn5+2z2Sapc +HlB4IgYYPqBDp4gOapbzivy1b7KpBfIf3tCAtIrS8rplDDJ8vFPXzuAwXQBaBwre +gcIFPL1b6t39gpGwxJHpxcrYnuNYckJpygtTq7E5MaOqxr//L7i7zZ/I96K3FeM0 +IJ1vembe372bZae5NWefpZYT1OAE3slg6GanNHZ5nRJZtd1eMP16gnV2tkTQSO/z +ttIWyHRMmAOTXm1WL7LWQKcgW6Ys/FN3pKmQzdONOHJ2XR05KF9NR+HD+DgTLm/K +g5mH0fDI+MRIQ+WSs1JJWNe0M2ltYWNhdCAowqjDjMK6wr/Cv8OfL1BDSG9tZSkg +PGltYWNhdEBwY2hvbWUuY29tLnR3PoiGBDARAgBGBQJCiMSHPx0AbmFtZS9jb21t +ZW50IGluIEJpZzUgYnV0IG5vdCBVVEYtOCwgd2hpY2ggaXMgaW52YWxpZCBpbiBH +bnVQRwAKCRCL2C5vMLlLXEDfAJsGJyBw4yIGYWRDFb+gKQcOSoraHwCdGHEwAubk +Y3n8ilYI//UNC/uJpEOIRgQQEQIABgUCPVzCiAAKCRAWejfL3rUbN3OmAKC2g5w2 +XLGM+fYrtsNPAvK46AxsQACgpYheb7DecwOjmxUkcg3+9J9DdJqIRgQQEQIABgUC +QpQeKQAKCRCsxgFlEcAjgnERAKCjPR8qCNSu6EJxLn5KeAUM5gTRZACg8uN0/KRX +q3n4P87MgFVHZWFc0lKIRgQSEQIABgUCPcSikgAKCRBvx0G6x4+QF21ZAJ9vkBk8 +lQVcdSDXq0vShMCSNEC9cgCfaFWc2+6PtTrkfSo7mLAZi91+/taIRgQSEQIABgUC +QpjEFwAKCRC0s903PDUBoGimAJ9cl3OJMcJBkUe4FoI5y5TcMnvrCQCfYenKMTp5 +cRXK/bZl5Z1gGn/ZydCIYQQTEQIAIQUCPSSDFQIbAwgLCQgHBAoDAgQVAgMBAxYC +AQIeAQIXgAAKCRCL2C5vMLlLXP+dAJwPGhnQ1KRv93p2sPRrdmTfVmTOjgCgghKb +eKB5R41lEs6xRY/rSRfcoPOJASIEEAECAAwFAkJ2e6gFAwASdQAACgkQlxC4m8pX +rXwstQf/Xb0pRDSZXGYIR2k0y+oGHCbSCXDbkZb2Uj93+QHVNCgaFAS7+mj7sUJc +4Ai98hYoZApMpQkDSl93pfuq+2cA5ayLXcqqMo8nFtOXHzOif1tCHLn/QqnlBdb8 +BAZF04BCsfLjhXA4agyDlAb8bXKY0GnKH0KXIB2wdVQo/pRKWB+T5+B0oiz3v4Ft +HDRUits1M446eMWzbJcjEzJHn+k/f2ai/Z+gYwky35r/Zo98YJ/Cpt1u9nrqwCoH +9jmgGaHfZ4MlQAgLIvlUe7JojC7LXkQHWZ0HX9OawdN53LgnrkuGju58j+v9xgMO +C04ArgcyF9UxGMmV3Di+rWqp2YsSSokBIgQQAQIADAUCQonOLgUDABJ1AAAKCRCX +ELibyletfHG3CADHD8yLYQDbvTStIRrrgPdJ7ax4KC3FwzXAUEa9uAeBAcOqTHDN +WigzUexyN3ou+L7jahI1JZmMh21vWKp5MlXPzIxQqu2kHP6rtmLlXruFXSqiobZc +RTKU6Xz9o8qDY4YG45jD/HMT4dUKCyJTHi5WbGozyBVUBKXyxODXjG9PXQ7UN10i +vOp45ClXUyplIVdOiN6bxGkRqpEMDUYjXKJM54nKp52MfJLi+7opdASAhcGsOo6s +jBhL54Z9eFLxLnBqGHF1oLwXdl59q9sDYuYzPcpA8xAIag3OMXE5rOadXccxbydc +PSjVwMccoabpWQegKGgKsLgeRFPLbgupdCZZiQEiBBABAgAMBQJCnOsTBQMAEnUA +AAoJEJcQuJvKV618wncH/RtK8cotKanMOj/BYFvvsP3d6+asz81wBN3J1w983JDN +8L/Hvyx3EwD6cKWSj4aEjEcq3tQqpnyhVPMJY6LkwCXF4+lTE6XqzEtLqvddQlsy +3dcdVXUc9/nVTNCeXKZeGoEOu7Sjmw2IH5ceHL8EGbo/z/x6yFf1/ANvniKQ8yb1 +kwWeADJNTMPx+oWJ/EcxXRJZl8iBvq3vktZsoKFzQN090VhvVeUN7+BGVIr0Qcb6 +WVgMj9Ld20X89a7m4ovY6ngTLgXWFtFB4bG77MXCHHovMzXsrIhJrunR7Ohyp6XP +zi/kHKspfnOjBgPOGsz57mu9nytlTRZ2hXGSiLqGWmCJASIEEAECAAwFAkK3VToF +AwASdQAACgkQlxC4m8pXrXzFrAf+LClZ3pYPaYyJQFNiYxVEEi2yI/Acwmvk3Z0t +QPh9Kgtv0+vMwM/cdGanVRQBjcfIqxZw3XfCJp6NOuY7A4797Mbh5KbYvaa44953 +2zKD/2nze2OMohVba1qX8/z7Jav3t70YTaJMT2M0z3h8S9jT944ZsgD5mJumJUPm +22k0mH/06cSr3hSmjtk6WtccXBDHSep7ITVBLhrsC/95omWmjV4do2ODsrXOw7Rd +XJ47Oem9iPPXH6vBgcGpSpp9cuvj3aWbEiCD/+9fjq0bX0vYFbXdiiufqGcGTNUk +S1Yz1985reuYRMfmboVVy1qbmEsq8XdGSJF/vvFbMgPDS+Odb4kBIgQQAQIADAUC +QtEXEAUDABJ1AAAKCRCXELibyletfF1+B/4uMF+qwOYheuZBimlSM44k9UQVZ+ik +8FjaPcQxADxsYfWnQDFpdVM9V+9d2BlC4FPb44C1CCC38q3zfM/79snO7xkN2FfM +XIOrRlZxXGr2u9qB83sI0UijAJ2w/VMl7hdxK0+Xr0exNOv2Q1A1nSDirU138fPe +pkRirOxvIbSUfLjFsiMQqtWvlv7ZCzzv60zS4MN35XZODQ1vAbl1nkgt5mRhL686 +117O5G+H89MlrpW1Bp6xye5C+NPjRn76X0IPsM5DyDo0xN5hgPYy4PzUMeSnjrzD +glMryXUOGvFdiqySbDVqaxPUYc5vuwqIs4FaIseMXngr/dMYGU1qTNWPiQEiBBAB +AgAMBQJC0bzoBQMAEnUAAAoJEJcQuJvKV618rbEH/juEACvkrRiTRMS0KxI6fR+S +kd/qMAafS+ab0YzFWK2xnBUYZoaN10KJHFz1+bmxhi+bCZGJ2iTDtuDFziQ3QOZc +hZX4D97e3wdg/fVnEbk1TNCADiWTLsX67i/3vG94iGyc+DTRauLWZ+TQU/IRa5bx +Z7EM/vwDI5Iuex138QZBMpZl2GTLTA6Rp8BZC/8oJuT1BB9g5Vshf7JZkiczuVUM +N0kkoCYB9/r/j1+KnBUujIwb0nwVS0fEdUyFYKy4dVSyM7EG4Y62UZwfQleMjPjD ++qMjUCJ6UqNf5z/hOe5wkkqIyMPcjS/gmOAvLaEibCytn50tEWOTR6BVHT9Wr6CJ +ASIEEAECAAwFAkLsw0MFAwASdQAACgkQlxC4m8pXrXxZZwgAuNyppUi8VPZoXaJh +/kFxHP4BScZZXqaoA5BTBvnFM0JPImQGAUL9iObQIzm9StKtuiQ1Ci0pUSW7f4I8 +hS26uDwDj7tfA9PCOVhAD5IhZ7D86/xFa1I2P1NAtXWkAG5lN76IVeS62dh7gX2G +a2mKfm4TaD+MnyyjrKQ2IUAtQxXiCvjSD3HlUxC/QJDbUmUDHH24ddjlymrry5mp +rl4zxGL/KUN9hsvHLU9389z1tGtF6K8z2Z2/azmI+oxyZnrepVsExHNHRDik+JqP +oQEnHMx6+n/Mb1sIbTTUdxe2T3/271mZkI3mWTFN00nAG1ofs3lfWUlV48MqqjyB ++lT/2okBIgQQAQIADAUCQu1piQUDABJ1AAAKCRCXELibyletfNhFB/4yJS7UaJ/c +VZITKHqH5SK1zvYxdS7QqLo0c+CEvrXOIgWAUqw1tk/QX7xY1ujZESSh5iFMaQ/x +3bHDc0KP5Nh1U9WC/AW8xoP16qgbzaViXhcXwNg3ybuGnDDkPQUhRiZecFdeVnlO +ChJdg//AOOt6KzTWf7jyBtw9w3IIy7l88DX85UNidhUrMToB96ncaCPDZZpPj3AI +XNjxHPb8St6DDVydOA8BZroFnkahNvjGpkppxpECrSMtqSITd2rcQl/s20KiV5LZ +BYNiRV4pG44akXEYW+hyc/pAxrCNMHD79l2JnHMALsanU7XbQoUB89CncLPSEstB +eavQhHuQwURhtDdpbWFjYXQgKMKow4zCusK/wr/Dny9QcmlzdGluZSkgPGltYWNh +dEBwcmlzdGluZS5jb20udHc+iIYEMBECAEYFAkKIxIc/HQBuYW1lL2NvbW1lbnQg +aW4gQmlnNSBidXQgbm90IFVURi04LCB3aGljaCBpcyBpbnZhbGlkIGluIEdudVBH +AAoJEIvYLm8wuUtc9kUAnA8YU+6MTX8h8KX0FOlR1CKMJmpwAKCvR0nB000PgJxv +BB3wzdxMueAfeohGBBARAgAGBQI9XMKHAAoJEBZ6N8vetRs37qoAnigwMro1L3if +OoEtWwDpqPW2u+98AKCyLBFIx9ztDP4BfeWKOPplhCf0UohGBBARAgAGBQJClB4p +AAoJEKzGAWURwCOCcY4AniXUi+Xo/QB6+6/5mHLUTxUVSbxuAJsElha1UKF6+fkU +kZiaGXEIsm3lUohGBBIRAgAGBQI9xKKSAAoJEG/HQbrHj5AXhiAAoLa1RyBSzoh5 +J07aw4ZmgZrSL6g3AJ4x8tVw+HoacASbsdOCy+TUitXNcohGBBIRAgAGBQJCmMQX +AAoJELSz3Tc8NQGgDiYAn1JUlQeqPy9uSbbZdQkdGBd6GH7PAJ9bzkV6oRJgWLvB +bsLv1BfSduPd24hhBBMRAgAhBQI9JILrAhsDCAsJCAcECgMCBBUCAwEDFgIBAh4B +AheAAAoJEIvYLm8wuUtcpXMAoKnRFq6s2Ch3Lq/Cg3y7W9DOMuIHAJwMZnqSuBVt +58WpPtUt78vIJaTiBIkBIgQQAQIADAUCQnZ7qAUDABJ1AAAKCRCXELibyletfBVP +B/0WcahoT+UbwoW5fQysjbCIJeIbHg4R24ieKznlg/QWDSRoxmKES4FnQkIZDGCZ +4dCSa+5Cp21HqhiyosyJ9ragZPFYhRrqr+8UcBQIP0U/UyMkaUm4rj+cLzpGvWUu +xlfNlcJgfoV9BbDHgRlNu8kOu6v4nkh77mImLgQ68sk5eWGBh2BHLT29qjl1qFpd +hXiWpWZtG0taXmXy0NSowHX7Xc0PVn5zKbRNNsRc9AoM1G8XXTJQCbFhHLmYe1g4 +9CKRIj/QPanYke/P7QmSEamrwag4jqDrGfJ877j5MR2skl+EULKpyl0G+5mMJ+zc +UFyhsZENPJuMNMKUC/acVnXKiQEiBBABAgAMBQJCic4uBQMAEnUAAAoJEJcQuJvK +V61855sH/jlPomHMqAOeQKqiX7qZL9801ukp4RkoKzh1qk6LZKKyd/p0Lk9BH1zh +j3DFRyGbh+p2HoOThwS8Cs7h1h7NjxJVpbZc6TStyCmzxh/V0zeerKeiRKcAcRVn +AjTBNa/te58UGH+sC4hd6g39pyANpO3fa5xHMnriIQsIpLOQqjvQDV/JwDmXli8X +2rG7Xvb6oQiSnT27RXtV4oMzQKoRH+0HE6VlK8ojIDltFQCSuT05m3IoPc/+rs5T +WTvmQ54Pis+OahlXlAv5nADJ/xCuMrWIEIT370iAt9uBxPu/04t7wgC6mAEPMFOC +4W/Eo996FX8irk224sDbK+pSGPbi8qWJASIEEAECAAwFAkKc6xMFAwASdQAACgkQ +lxC4m8pXrXyCjQf/UdaW3CfBvOqBbuUZmmvsJ8k5cBRs4RdE5rFftq3FZc6vMyIA +Fx0yx19CyPzZqEwmnjstEPbWFQnvtvLzshEwQcZwiEM+UYKN+Zb4t/Moe4xHzaMB +lGW+U2X6sj0MorCFyYnKrgePf/Y7kIAmItgE5A+RQSOhT4MD2RdSCkB8krun24lT +XcQIAu8KfTUyx+lFWvBZwFdfu9YWClrQs2FLf9GQ3fy/9f3LZD0yoXaN3wPX+hyv +XNGHIw6SZX/7Prg96yw2srV/37lCUWu19pwwe/qUBDHJjKa7h++oK/i388+3AZqr +UY9p4g3e3e3p/2Rd89Xi3fXZCJYy/ZFUfKZrHYkBIgQQAQIADAUCQrdVOgUDABJ1 +AAAKCRCXELibyletfDIKCACYVATttqlQzIZZ4+eD5gJrqdXJKsVujILNyVc+0E0H +mziLpMqYcEU8JBl/utRF0cC6RYw9vGcvjovJ6UcXcRCwI1zUKfq+REVBixhZVBLO +5d4fJ810unGTWc2BHcoIJc097TGcuBg3Hp9NStbQSbQjfyTW70BFo/ox/PnSEIY3 +qr+iX9cP6pw+lfbuHs7lYatyDZ2dmbZRSeZ4W7fAe+3sRISlYzTiKdV9NObXN/RY +ah1wHjXgknHTAxCmDgRm/WOS8OSaQo+moTxaysmqO0yrburBGzFxMdtk2x/ZIOaV +Dq2ZDsurW5r/I2hoZlP/u2awO1mtVAqwNnXkW/gg5AAoiQEiBBABAgAMBQJC0RcQ +BQMAEnUAAAoJEJcQuJvKV618s7IH/2LyjqZQCne0QjI8EiSH1BLavFak2YrERePC +iziOlvLA8s3llIYjTjDaj68mQSpK5y0nIy60Ab0Qfc+PgQdq2DlOi7+dhR7ZyqQR +rj0IN4QakViFa5XnO0en0bemGK6SEBRSBdhbkCPiTLvD3VIGU9i59akeJl0taQXp +s5flenuOt6drBh40IsQsAfM0aaupNs3M3Rk82Bq81BeCrmQvRy9XNmO/K0rn+gq4 +cBiwc0X3S0kLtwTBP9SdgiC3ce0Vouohw7v2X0cZR4Pz3PrGPCP2QBoRpKbauTNv +0Sk1CVwgng42vyLLxK6/GF1fM43CmkgS/xFqT0qJINWqYIKazdaJASIEEAECAAwF +AkLRvOgFAwASdQAACgkQlxC4m8pXrXy5ogf9ECn+Aodl+4N/AYaVu0KrYEyeP0kF +1viMZ0cKiYkullnwxOmZn6zeAtF7XAr+Gh0/ZOJnjWqzxKHNEg+MtwdmVGer51fs +4ogVaDKKDI8qsS4eNPHms/DODuRP6PPvFaRSfiWPJ9Tn2fiomLdjN/F4AGHbDQ4h +Oaarwvvd4esQKzhSMnq/LpBfgpA5e9Zcc1wcNTYZnsj0cPnl5EK0b1mX/uASxtLu ++/CsYtx7hv7qqgwv/WlfwkbnJd59HzyEEz8Xaz90ejlYgr5wZtsehd0wyaC4t/rG +QS9UHoD/c0flIpAKuzBQZ2rDFfdXSHUMp/b+rQ/tWjh3wPOyY0bpJ1u814kBIgQQ +AQIADAUCQuzDQwUDABJ1AAAKCRCXELibyletfN4JCACYUZodRgeSe9vLaQg+CKFa +ylwNAhZEqT53wf6FJjgK/aV/8+94yJQ70fyvJUPa3dLdqCUbYcuEJno2+GAkaqv3 +7W9PNbDAYoaTD8Z+2EVqJZent4U69WIS9Ez70JG2WASN8UAY3W6W0rNdaQx0E8fi +sUG9D8X2NA5uUap+JwjgiStNvFOFeZk6/CQmbywPhtdngV7AGDGz+B74V3QgCICn +MyCjG9IRDJ7vZ5/iuRYhtXECyz3NYuFF5MvfUv3BDSuTwIavOAxMAl++r/+ry6IB +wKAuEZLzb6UhC0bODB2km2ZwcpNnLJVgPtu0nW7OmRWo0K6Vsp1+0vKg1/9to7TL +iQEiBBABAgAMBQJC7WmJBQMAEnUAAAoJEJcQuJvKV6187KwH/jQ7mRVyW+sR7nvH +mCMCSmNhZl3f6SWbk1jXC8B++iXmqizUH/qXypsdRR6TLOY1a3xtmstBZZknNX7D +1EdCFnXzMEwd3HN+GKbPZ8vhf54dBxUoI01DUuS3FWEpYIf7Q0o94c+Fj7vneAZN +H9MZPXfEH0PVNt4JOfOXBMT41jYZoTr51X1E6OyKIFydiCBucN+4LSshwcsr6DO2 +BskVBR1qYYFpl2vu/VLUq3CaM0v/GO0eu7MW89snyDKQEEuwHVdyyok26frnFIq2 +IShwaeJZiO4Oj36um+4jRfP/ZobkFgOkqK2t6ByaGoS85vmgovhDbqTr551YNwx6 +lxeBB02JASIEEAECAAwFAkR8nbcFAwASdQAACgkQlxC4m8pXrXyMwQf/QbsGc/nZ +y5efT2neNHMhoR6Gpw/mm6RUmyGiDsA/REO/+0iDO5ZwzvrXMHEybtlAcTKajPEi +1nfv4A6sNyuabRyaRErgn4A3WeoeYvZFdafNOmA7H9fSBxKhXE06H4uNgJixZzc/ +abbsxXQsxW4eMUh4H8buFIEukGPw77Lct9gtNiagaIHshPfeYDedbIuP/21fqffo +xeYXaghSg1BJ29frJSbajvapLf83hQfIBVDLjUa7TEbwPJN3+B9ETj2rORHrtAR2 +BlVNmDqYHOwFRksC0SgLyXjS6Xof8edrsiD31QVu+HVTUu5RuQ3/U0bQMn9NOzMC +XlLtiyze8XvfNYkBIgQQAQIADAUCRI5l1QUDABJ1AAAKCRCXELibyletfAU4B/47 +j8DiKioUFE+dY4mUePPWvX6F0amyASDxkLxivYPS8X0s8Fd+1w4/HTfY+uC4jV6f ++eZq5rQtqq1s7+ENxQ2NFxu4JyEwMNYBrFzw09F8DqDkjr7lW1guruPycvOCciwI +/JoorPzDqzUJk8Kss734SWNo32D2/ib09tVWy769vUNJ+hSrepzg5Ga3XCL5F82i +G96Ixd7WPm9heM7wSKIRvJ9NpktXLC59lMWgbQBi5OID/S+Gv6Nyo3EDb7dLmYBy +QvdnbAj55//BFocEqQxS12uF67diLUmj0r13YaTcVPcqeJInJdvJ+/IggLdPdSp4 +9T6iT6EZ8greEQMPPQgRiQEiBBABAgAMBQJEoDHNBQMAEnUAAAoJEJcQuJvKV618 +N1oIALlrN/SyV8mcNoDAz3ToMSA/mHZYK4ydWXEWARgUK3dzmcHTPAtxIzoeyCII +v+4nPTU4cq5XauNZfi4tX7TWWuWkJbQyIRGjp9cAxeTc7ec2dgv2AXMIAzJQY6Ov +IA1YEvDA/IF11n93iJy/4IAIU6sZl3JuOSMaGDky/tJOm72GLmSQlMslGXjiED9m +HEg94MwMek7GkbiZri+gsbmicKbD0magHHFma+18vZkpUWnzye8DlUekGqn3zYWD +dJgOrn2QybwnWlo+fYxCHsq7Pk/eMByuVvuUJiKSm8OWybM5BOQq1K+/uy4mlJle +jsBBtfrnw8fJENZD+wM0MWKKxP2JASIEEAECAAwFAkSxVgcFAwASdQAACgkQlxC4 +m8pXrXz8LQf7BhyAOcP9rEHek9MTf72xCHN2i9R9sMZF7nGGnHAFVF7nNI7Pgvte +mSeTF/42podvrAtBdLY72FGl4vi8q63eWZxba8xAb10toD1PGSUYQhZvHStEC/4x +aLtW0oOyH/SnT5Syc54rpJiGnNGWchTz0CY/U7F9gs/7AjKhDLPkNevSg+o7gh3m +Wuzc7Z2XJsKeLrH3sbDgaAQU+QZ8hq5+VPxm0PMBdGMIFUXhKAf6qVUzPjFnsuq4 +B0ndaXHxVaQEMbr2pa6LD2foYo6PRkAGKrN8PA5iPAbwoJHYw9wPVDKdT7D8+lLs +Vs+s1HjMiyQdhI/TGTAgV1dvcYPzB/0TDYkBIgQQAQIADAUCRMKCJQUDABJ1AAAK +CRCXELibyletfHCyB/9eU1+pYxORSaFdawd7o/Sh2Wx+fu5V61fdmJ+7ckX7hpO1 ++wHx70B11G3ncj46HmRGeq+p4dZqHDFO6Pc8YTCA/1+fAQyg2RH5pCrKlVJevjB4 +en8sA1umFlSNT3pbrl8DGD8K35dNBddgkGj4XmCTPdC5teXZ6dT+9TAhhGWrynPI +NUU/oD0LEaMmhN9VSha/PXQZ9pXGrVMr6og3bEpPB9IyQxIyF1jlhOQ8Z8BXIhE7 +YDf/XClatzreX8ISFFZ7NfWLZsU/UXnpckPY1ne0FAOx78qk7N29qLyVilq2BwDm +2kDuUA1J3EqDHXUJDYLMnjwVdnBoY0Q1OQrQI3h0iQEiBBABAgAMBQJE1FAWBQMA +EnUAAAoJEJcQuJvKV618FsMH/jMBWJE4p6kYvQ/wzMGMQfoKeMLZnabQoYJYykvb +OG6BIOybfnjplMU/fd7NImer+k6LC2tDPIGNk/w2ekK4iGiDM/EQWTtLs9E15aff +vN8ys5OUJmIm70GkanBQGQnG29hJ61hFPJKFri8hTZk+s7YymJ7YZi8FbjebAqR2 +DHthuS8x5vEn+uE8cbFkmb8CJFHKPeHoPXPAkhoHWQn0rII000jyyQUOG35ZLb4q +lU15iXrMfop1kzHNd+ZUZS65S6yip/zNcCbJjctZyBOWfcnlUJx8JWNjFigPfH29 +ecM5rsVBSQdYvuUERMrXXJRoNGTAgFGH4jfGy/9T4yRzA9qJASIEEAECAAwFAkTm +G/UFAwASdQAACgkQlxC4m8pXrXw/aQgArszCwYABgsqXnKmBrm9epad+GVogOlas +vFYbkLoLnQ0qUkAZr0/38p8FfeUxyEi8Ny61zoOfqKtonkynaBOTEmaKUN+MlrTo +5WCvSKYhyI9Pg4Kuo4+iCEkDAL3b4T8oH0A5ZFxx1LHQGfo6hr7NC+BmNe5CXSg3 +wKRAPH+aTus2X1sju5zgkILBLHFaj1ktLDULUSK3RInk2nPbG3jc/ZMzvhJCb06w +N6kkk/ls6glKMyjQWCRvzXBHLoZqh4klF3Kw8OaCg+3rm7PgRY8HypajV/5UKaz5 +IcSBwkJWZSLQ/uG1i3l1V8uQDtFdt6UXx4deQGXZtgKHNf0L9wh5xYkBIgQQAQIA +DAUCRPfryAUDABJ1AAAKCRCXELibyletfJI1CADGwdIHyPeiA9FkalSABBUS8Tq7 +3l8KfEtBmyYNoorBScJfy3mh9d/t0gXrdtwdhQN4LWuZgYMNMgFTprHp26vOJ0I+ +1ruAnehUO8rhog/wQXnOC+lFXp7UmOZtFdKEbY0ail/yKYZv/BtVDiboaK6if2Kt +W4UN6NQ2ZMvAUPgCV6jZ2weQFF9cfqg9snJrygqfL39htCxkOu+2maK23BzqJx3L +zrik7FuUFVedA4k3t7WQveyZNEbE2YPyehgk7RP/7HLVYdfjbfa4eLpLkHlRRS9c +mkfTFm3WsSBh+/J2mPBTR5GwBYWQgEWph8GCXsdTLZ+Nc13VHpPPIZCZt2d7iQEi +BBABAgAMBQJFCbNwBQMAEnUAAAoJEJcQuJvKV618UlIIALO9KkQejXgU7JnwKEVM +/NUEIXBrLMpKASoBug5vxiBgeFbRK5KHSwzJN1+CLSsmn/+LQjsWWMBU5resMJZi +ErfqyAxyrWEayQvmVJtgY+WCO2e9FrnByi4flnL0RYWh6hNr2g8Q7pc7uFSclznC +TAoYvqxxDZ8AnLje0fL7N0rLJ7aY0NxqZpUmymsBKyTcrUpMbNvl/swHMfWE/Nb2 +dYAFOOuBdBlUH9fM9iW2Ht/592881o7671cDXqCAC57wjDxckJheQdvRiP2rEV0I +wrD7SyUmPVvU8r/onTcFMd0G36+Nyx+9ANm7sGfCWgwD64UNbDATGsgM+Ts6fdS3 +5EeJASIEEAECAAwFAkUhtWMFAwASdQAACgkQlxC4m8pXrXzFGwgApA+A0VyxQRzv +9zmdVDygWPSrtzC0yuiWDeE3R4TbLZS2cGGEptS5Iz59mdU75SLcRsZgT2CZM3rL +VoDfbxPVOIFzcbKC/Cn0Vvj98VEUdvaFzwdO7yqKZ3PkIg2YVVKPUq5eNL+JlAt7 +grc8AvDhRUy0KvsB6m76o0HqLgz5KZSeoo3JZBTx5sfAQOyDdT0UwQO+FO1kzKGX +luFX1D3M4wynWQQ9rf4Xw0TpSayDqPuuNVNqHOmFbKJ4LRlTRrAcUg/ZuBda3z49 +YK+ZYzurNAH4SrO0MPq78MEryMj3dgreYRd4SZpo3A8BhXMKfAdb4J4dJblTq4FH +vCyOsZ6AnokBIgQQAQIADAUCRTRNTwUDABJ1AAAKCRCXELibyletfD2fB/46LA9p +jixaQ+Tq20qOkp7trAO0kEOcN5WPMx0l571IbYAOJbShHBtowhShhZyFuLNmhQi6 +xxH/YppB8rJrXfbcqh1g4ssk/RX/KvschoJ/ZWpCZX91lZ8YyRphhg++ejfWc8hg +/7A4OrqTuwwZL+30EMUthoHpal/HtnYAm0Ss3t7w+4uJ/BOh+O1HXE7Eoc0sj1Gb +TReUfkMCuz1jNsPij/HE0vcTo262QvhMxpYQG0hcJx6wIqoSStty2eugQWuVgkpm +MdFoqlkKogjSzvwZMKdx7leBDhiFcwp+eRGA6IzsUSpxuD65f025m+3ZmTLUk+uk +cmdJxpBJzmXkF7mPiQEiBBABAgAMBQJFV0PKBQMAEnUAAAoJEJcQuJvKV618zIUH +/0fH6LiDw6Q1DkYU4gwb8xgJjUVolr5CD0XgtccHqfV+v8TSuoxuoFnHPnF1bHHw +rF6NvjOVIdm7YciiUezyiGlKpR3P0slPKQGvNN/p6JoxSw390pvXiTg9/Oe6mE0e ++0jelwlGRnOk8LgV9XLNXonHOHFMmsVutPQeEMfMQlFRrB2yll8qk+G+8+yPb9qq +eWgp3FSdCepwXLe6MxpRyXlNCBiBtn8zBKceA2DMsnm4gWjL+yaoTYJYV55ihRCP +YDQEf2j5JshOWGZ0ugFVa/VN2a2geobo8vIU4WVzQIGDxPto9tfem4OPR+4cddlC +SbfP57uBlioHZkSMn1pg29aJASIEEAECAAwFAkV64foFAwASdQAACgkQlxC4m8pX +rXzB/QgAktaIrwsSVN3Ktp498i3fAGk7hPfPvJKsFPlgwT8Bxdl4/ifdmM0DzEt3 +vwzsL5LMyt17x1jcnNMn+e3wBQN56/r8zTd+gI4LB5jIfSF0yUCVtQA0a48qvrUm ++1Ci6TvQAEi4WmzxQHwYeIJyG4vQdNyEdCyeZtkRy/aP/quEsCkv1g+GUqTDdUBn +e2T2Bg6Wk3UsOAatE4AsHlgqoOAjp/rtpMXGio1EytAzrnMmAiGG2n7FjGfYu3E/ +9y28J6jeVeinsiGE4r7/Pliy2ZTXbdLhaG315f4TDAiqlUMZuzaH3mMx4Nd61kzi +mKyYRw5rcK/vRfZ66qthjufyp4zOxokBIgQQAQIADAUCRZ5BzAUDABJ1AAAKCRCX +ELibyletfFflB/4hmNjWiJ0+krdqEfCeG8ED2erc5NdDEwAXXlusP48GMXqhgD9t +73tohsa1CxlNXYN9kGVXU2kuxAPOzvv+0fdRTlGVhTHEy3f6QiuWFbp/Qs06r1jn +9xXvILnRNUdPJ8exfQJsdbr95LQQaDz1iVwHjAiVSvlEaAMnuI3GGIsh96YrWDTf +SdikzweeFWb9Vx+aePqZJSqg7os65jSI7PA1OjJf5PNXqpIEQUXhQNXJ6tnlKEIR +MPi5+wP44Nlnk8rDJsFCAQbCALrwkTOH1sgbAJhVP+JfQ97HZRT2d5FFKa/+BCRH +zeiNIHotlV3nFLHzocMz4KnBtc2DzwKS/f7ViQEiBBABAgAMBQJF5UCDBQMAEnUA +AAoJEJcQuJvKV618RQMIALClZ33dwTSuGMzsZD0g+6BQqDb41u0Wb0WL9H3ZQI6/ +NPh/q1H5FpvHLHs9ZVa12AUmG2Bdp5cpLgxhklq/QSqzErZ2iI6dZw4NdwK9E1Rv +HwURUjjwOnr2yHfxn/sRRDkTPsumfJNFOHmJgD+DFpiCuFqdRWUegbXKu+xsiHf+ +EKR53QR9mBEmDqYWDoXReJo+eV28d0Femycat8y2PI/VDMrqT9mnIRwPqW4VroIw +V66Ub/3agTtKVFpsog6i5/nX1Rf0tjTaCbuZm2hiL6jeXxkzIO/UbD3HyVgbI2N5 +bwWpKfCxg8TK/d9uLe/P66L5btZh7rjQJFKHRbGzJkC0N2ltYWNhdCAowqjDjMK6 +wr/Cv8OfL8K0wrzCqMK5KSA8aW1hY2F0QG1zMTAudXJsLmNvbS50dz6IhgQwEQIA +RgUCQojEhz8dAG5hbWUvY29tbWVudCBpbiBCaWc1IGJ1dCBub3QgVVRGLTgsIHdo +aWNoIGlzIGludmFsaWQgaW4gR251UEcACgkQi9gubzC5S1w+LgCgg76GKz6kx/GL +4I2MY6EJqKFFMSkAnRK6l3qf4JqDe71sSSbMWxzCRDeMiEYEEBECAAYFAj1cwogA +CgkQFno3y961GzdmxACfY/KtgTckvnHTlZl5oLp5EVB29o8AnjGrNEW7L939VP7h +wxpau4qV+X7YiEYEEBECAAYFAkKUHikACgkQrMYBZRHAI4IcLQCeIgidKAyQyyGh +tntLWFwH9/r7uxUAoMBksVOcapUXe4CeuOIAQU1j4AcjiEYEEhECAAYFAj3EopIA +CgkQb8dBusePkBcWzACgpg5/bpX4yIm8aum5QylE+ohdLAQAn16Scb+dDL3+oSlH +xG+z/qrywUcBiEYEEhECAAYFAkKYxBcACgkQtLPdNzw1AaAnOACbBU9bkNLme+9v +zL1V1sxq9J+OEM8An2hxktKEgBbFrWviarNQs0aikcUEiFwEExECABwFAj00KRgC +GwMECwcDAgMVAgMDFgIBAh4BAheAAAoJEIvYLm8wuUtc01oAniuTxHrNR0VN/AyH +EQ+ZUsOHW+g/AJ9pTaGaKxS0g/wp9d+bRZQRIThdvokBIgQQAQIADAUCQnZ7qAUD +ABJ1AAAKCRCXELibyletfFP/B/91IzeOizvAFmhXFTZMTgUiASWAjY2pAq98PJ68 +0GXnlHA3wcyeFTV4N5vRx8UEWMbMkEaXXLXMXOO05VHxuRRqPwAtZTU8h4d0RvrR +tY8N1wrASqDhfM2IL2K2e8rUoXShhjt6vmND9RlvMznFnbV2UCe2cB2xPdQpuVXK +rO5ivtr6Peg6u5lOSYBvAtio3/p2moUf4nLc2uZ2KaysnrPVW/vFxEIFb8zCi/66 +HTCgW+PQazSqFJxsjumrm2ABCUlslKT1Egd8sfTeHSsqKeHO/nXtGBDuJRgwdKa3 +e+2IAqsscEn2C6XiQL30O4lrC/q6R/LQlVLtz/EADDEi7D0EiQEiBBABAgAMBQJC +ic4uBQMAEnUAAAoJEJcQuJvKV618u/MH/RN2VFcamvsZ3v5dM6S4Fe137FsPkpsx +wmTRGb3tLfYcpu+g9Zaut73B0s13IX0GUyYwE4PuD3OWeg5adAquM5AwoTmdocax +/hXTf12wVCmdrOFjkBhbVSsRYV52rn2Xq075QNasTuGPG6oVDCKv98TfWl53EWdt +TQRYSQNF0mKy6YXVaE0E3Sah7AvRytBNgrTRuMELlaSXpNPqF/oNMv+V0pLhiR57 +ojTn28JsilHOCoXiU3EEOdb9HxOGwag5GxOy0Jgos7njz+vwCuE3GuXQJp3YB09X +xbIwGjfwY8KPreAoAcpwvnHjLQyvBfuUxvZkZj+F6xRRD/3QOIDfi1SJASIEEAEC +AAwFAkKc6xMFAwASdQAACgkQlxC4m8pXrXzwyAgAs3ouwO0Tj67XZAtFjYZANxW6 +13pC/K8PGtwndF0uvAThLQcKqfDy514mVNmdmC0GtnxdKWSbKDBBBbeZRF4sh/FO +gwV6U9lR3dIBHBqbMLHdcPHuldz5SxLrIIArvXBRJZ68Cw+6M/0cqFhnTYwxHR0D +y5DbP6QXezgf32A90iqAELW2F7bScTjgoEdpYVtf67HpK07jn3+S+w+NtgR7y/OL +qtJdZeoUPapUVf/2vyP/UVrZtW9kkihJUKb//YLefRNFwEAy4woCD88+FCS7CUDz +jtumoqd6gSeSpTmErXtG6zY4qIyIIzajLIIDno/73uKYN7SZqceOPWR4q223z4kB +IgQQAQIADAUCQrdVOwUDABJ1AAAKCRCXELibyletfLlyCAC5kE6d+RyaV4JnqCae +d4SUWH/Qbh3SE5/Uum6C2Rwt2l7zVsbYq4YsVVlequuWNh2leXKFpRqBhptuTW3x +qviclH3PnuJgRYyTD2z7QdV9c6r4RMQpQTYxN4OuK+kAQzYiIJC2A//pX4wVhLRv +dzJYgu+O5yQowMwHzUqMLpaoqLoDI8YByzUqT8npiigUDU7ZcK/23YBwmMzphaIS +ONXjcHOJIp/CquqHNqM6KtFH3RG/AdYsSJ+MVWfFYq2VRXPffXMqBfGAzfOaMJRD +XMJdXt6Jd2SKA5eNt6LLavUMBf4lluv471/63TNqGEm498pWn04DOVIvvus++c+x +iOzbiQEiBBABAgAMBQJC0RcQBQMAEnUAAAoJEJcQuJvKV618jYIH/2FyBAbPX2wL +3DA2SrgzhXZE69TVsvqCmtUgX53XBQutfu1662j5g5jUOHkjC7KdDilDG+pYHPXq +GIotg1XB/DRUXpPCu2gI3xzI9SmFQOdBOCz2oHn3M95tJQNqJ4DgfGvjRfEdc5mm +Jfox38JBBnI6wxY0KAZ0JaagwikPqCyXeBYO18f/2CvDmf3KPrxhnXAtrEC+FIHI +c9HYkpj3+EqR6pv7FDIkPuVyJNkr/Z+XXAJ/Lglnut2qxLM1ZbWtpWzcSKQdnZXd +xsX2AwxpOdb3KAzK3BWNGA9DIHtqcDoHvVQmQt616YroZZRdezNLscafFbtH0HKA +VN1eUlzbNbiJASIEEAECAAwFAkLRvOgFAwASdQAACgkQlxC4m8pXrXy4OggAi+Rd +uw5wm7laWO+Z+gmg0cf8d9k0KBd5b17ralkfJg0tAVngsD47L7wiBi+aSJJVOXjK +rrW2XU+9jriA5yKIFMNNZ7jdZdHzfrGhqlN4WZUi7cP1NqnymFPOuO8FIyQnXR3i +Clf8UTemxcwRwRnSf2Rw8fj+DpEITcEOAhXvciEaiUDCSrKBEXjOf4BehNp7jUIq +nblnWqk2Z4UGH10zd3hW073PrJeHq2vcSfJL50S9C4VJehhJ2Zay6mRhBIll391C +LeMkkDnVr4ovoq49/Y2moREPB7vdnhMdKlYIKVx1Khceackf7FzZ6xFLbbtu/chv +ShLrz7TVa9fg8HcXPokBIgQQAQIADAUCQuzDQwUDABJ1AAAKCRCXELibyletfAgB +CACULcR54cfmhWY/5JDvq/68WMGXnfV9ndcPj0cT8yQkg17dRsPuJFHFryX8d//p +WeonoZKJm1AI0z7gY1jtFqOMz6++vHpGxmGqInlPhJ1TSjaX6uzbPmnwq1/ffvnE +kq0roIofDbJrFdaUWG9luWkIMkSzyy814fo3j1GwA/zHxmNhjb40jCBz2FkguRud +Bzj9MyHuCh4Y4wCeWa5wm+DdFSVuliCpX8+cxlBG0UuoCNttsq1hqqJNvBKylkAa +4NqxgcJzjbLoflGbbLWQikmQKuXNtoGCvx2yOuUlgl351TNenMlwm1PxmEjNmHbx +lgPGh+Pn5rw8sv5h17+dLsHdiQEiBBABAgAMBQJC7WmJBQMAEnUAAAoJEJcQuJvK +V6185uQH+wVSxV3rgsir4KBYnY6wvXaeaRYZcNoGCdFqShjcmzC1ZvBzGFqFMom/ +JRYN80eNgDFoKFYvV1d9/fm6Y6dUnrPyS1sljDjlYbur1m3+4fK1e/OeMPxDUDiM +yFCBqGbzDOxN6rnYcCFQEigqGgSUX26tQJ3sUfD9HI2F12p0jU8TigP/MxkmIm0Y +sBr9d9q1M9WZ3RSB0UrynEocWekfULLCJVHa5q6gv9aJhOwmKGQCTjqhVGfQDblF +sOlM5EsQXzzSc6twhl7Aw8CieC1tFYhy6vRPrRiMTyrDuieFFYXix303D0aNjI+I +L/x2cIE8iB241pFllFbbnEjL8dgqRuK0KuS+neeRquiykyAoaW1hY2F0KSA8NjAw +MDgwMjBFQG50bnUuZWR1LnR3PohUBDARAgAUBQJPVIniDR0gV3JvbmcgRW1haWwA +CgkQi9gubzC5S1xU6ACgq+Nayp35D5ZbIn8XaP/7kvVrC+wAnRhj9wbdMge1/WXR +LGfggR2M0a1diGIEExECACIFAk55T1wCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4B +AheAAAoJEIvYLm8wuUtcOwoAnAn9N00R2qVJ+BiTw3C/nxJIRIDzAJ40GsjFAYiO +FAe1J7z/dej3jnVndokBHAQQAQIABgUCUJosGAAKCRDtCW2T7u1H2pIZCACTUhSw +PKBCSprX/ubIkS0yCXtp4PyTr9/c9e4+EbNG3tN3Mu0wJy0JTz4YmbBbU/Un/7k2 +1IkNW0CZ4FgbETPLNKRLrPlA5c0jApJUKtPwGfddPZ+pdEshjvvBzp2fpl4CVfYF +KP9DJHEe8RLre+gbIYnKcx+EjidgumKhow4oArO+3s6Gl/JUCawpUt31AuFYPKNU +15rtwU3zqIy3Radob2W+l07FSYx/q7RuvtJECyDuzUd1mAAyden/7PKPRHNKUA+u +KerQ2UojbwYHW4bV+Z/lpBPYobT5r2q2eieToFVqmgP2My8Aoy6u3jgXNFmSYihg +IIXjvW/LsoSNpQpeiQEiBBMBAgAMBQJQqW//BYMHhh+AAAoJEE2MxHBH5GEMID4H +/3ir4rlLUikeQSS43pYPrhJO7dw6UYKMir7x7z3M/aB1jQZGUwu7gRgw5Xg2Ha5z +LJ39sycVlyGibRVv56dkfLnavxcQWDdE4/VHNB9qK14mutRnfFWqt71ZaA8on8lg +QzhDtYtQqFRkUNOWyxV43mL74TtRKjVyjkPMo0mjf93srOL5fwPL8538LKHdYcap +FabdxC+GvnGoi1W7GSYBjQxTdFgContPtXbIpGuHHj1oyu/enpkXI1mFnyri9FRL +OyiwcyCEj/BxKBoIyBnLQbX9KdXGAu5tIZ6RibVVJuOl9VDmAwjMFnGAmtaySTc0 ++N1kYs+2mX+b257SQRF5JWyJAhwEEAEIAAYFAlAvucEACgkQwqvyzlTQ8EjXXg/9 +E/gSf881jBVK2OkhvWeRtboSEzz9LWgd1aIhAS35H7Z947TsoBRXwhmc8ocrtQsY +L4j1Na2wR9CpVn8OdfXZuFQpju7CTQnF+NA7n9O1r/J02wU2A1HCwC/Uf0Rc/r3B +tQ+6XfDkPQHbz7M1rohlCvR/RwK+2rbd6cvFn98nO+6ymu7/65Vyyw88OllnVxtg +yRp+rPoNmEjhQ94ERAVHPvxjg7HbBU+jr0MJj1BE1IXjv2ChmUDqdq7cOv9TjDZv +bmt9Jjcz1CE1Xi8SDKgo1M6wCF5IAATD5R38bon+yjNle7tC39W1Rz+W4r02TXo/ +g0HsSAyNgpw4FusccYJYfZq1xzaKcFGpjZcOF8iQpIyzkMWmN+wCoRiuiuWcbvaR +90DovsBLkAhz8vKY9n/bHnGgNDp5q7T2Iw6AEDbk4PbiBq/ZWvetgv5E9/7eyRYV +AKOhJIOyT42cc9oqyOs6+mYU/uOBDvoWUQyw5qFHOqcIgB+Jd7kULdHTrkc9bS0+ +DcKBk6jFsv3eNiz2zUvep+U3PXefgw6/vwrXsWU+OB1l2A8CsnGw65w84LvRpyAJ +0+X1J/ZZutkDYSixTiAfKaPJH2kkq88MXuMn++08pxxUQ1YKa/NYqY/cuy0/8HPN +wGckyzkdRlFlT63TrTr3z1I+zVYNtUUA2WbgkowxQ5GJAhwEEAEKAAYFAlCc6g4A +CgkQz+7zFlG1/ejyIA//W1DG3XxBLRdG4HP5KBSMSySWp8lz3zCYmNNgwrARowt+ +4XEHdwL31zHvoe+2AAFOIAjoO1XUQFLsCIu6aTyjcxnD9sJ54PxBffMvQjqhCf2e +r3pXeAg613wdr6gSxkewf3h8JD+3NkHNAGs/z2gr/FYZ+6+SZGR13SbJgGJmznAT +lgKc/YLqfEVV44X9Y0KXF3/V4h3ITGS6FULmGTNLzTEw5JWZWnT1BKhsB4SzzwRH +n0M9ZcuxvRj/39a0tGmz3B73iE+rUUrGWznbwUBno9A7XHV60UmuWPdSj0M1TAeA +vVZaBJhF9voKNe5ebaGOangc8WD3GvJvvcUc5s9uX9bOcr7Mz9iOB2iv8bvx/odR +ROh1FRY5pEBsQXwG7LsNiJg6zU6ccIt3QpzhsKxl+TxQhKl3RsJFbrZH+JRyedzt +evTcXKh9T2yV+pYQ5ch+Kv/U3edECOH/xuIKBXkhg/MngilSSKf+RAoS5j506IwW +4N0lWYJJYlch8wtsCpfp9q1DRRRaTadxj1axNBfWTLmSMS/J8523LfGiK1BWx0r7 +H6iYYpJsU2O2CVBf0sDva8e4JeWbGe84ytjYezbL6FwpJSTJVLgf+wrCCE89cRE8 +1hgrV3eDmBCEbO67uixczdQfkhOsxbgfLepCinlyElMI3mgonFlmq7ZfTC6bbiOJ +AiAEEAEKAAoFAlChRUcDBQE8AAoJEGLUj60WoN4BB14QALMTXhWIUPyq5/mRdiLa +KOYT3fxzaIPRFs0tDpArnPpKWkTk1Oxxtx++IiNDorbm+kSFRsCbA2MGtRBZXYTr +wqEJZlKgwlOiLng4BAjIMrX6TAH5VlO2sD71Lwir8+pyP/e0dgCbhCXIE1i9imLE +aVEsMZp997SBsgHJgeo+aocDAOEOYdlUX+WiW5xwSE9PpB5+/uYQzjxxIspxAOg4 +umeOjHNG4DcslJ0NMy+lUnoTs09LHaCzfxFj7L6+PZOFpfI3wIJosHIdYIUlxUiz +2Nm1J2a52DxHk0yg/WtGFLuSRPXRgl24lwqxwDQgo5Mw3kA49+LKw6l8xPFwadI+ +MJdVC04iLjrGomGurH2lBJm+HYefZo+NpQEdU8P5mDipXg1mWrVwNlGC77Lq6Jxb +2lpxRxxHoIz8YHWvQELDuSfyRGD+wAf8Mu1635wUtH0YGwyvbLnK3YW/Vese6Bbg +z1UqBlXb7BlNS57hcrp9Tk9syjxNL63lcHQGNCCx79ZYihXz4RyziJXatSHu24hz +8L3Iwh48fEakw9OPRC3uxaihP/N6o0FDyg3KRJU0LfWUTV55qtNEDAFRfzsS9WaO +Olhtr1yWUtf5vujbWQVOScRGycuGhJq8Rb1F0o6E51gsZ3r2wiVemkfmyMPLFoMv +b0rPRREFm3W+Xeagsfc+8dgriQIiBBIBCgAMBQJQmmvQBYMHhh+AAAoJEHGkWj0N +jQuTp5IP+QF1jkV0a4q1dyW9p5S/rTOUXXmVqGcObJbT/bk0/izIOwBpyMN0KkpL +kNv1UdCEvNlB+yIva7M5My4If7ofSyBGvFUqo0ZSeF4OUEjxvEToU06UyQBSb23z +Rzl1b6cxs9zMaNT3Q9Uvs0jz+fSmQ7whnjrVImgMOHr9G6MbdtP8zrkwC1zz/QYZ +zut2fjR0r6PcoUeWUbrRER9v2zkXQufd6oGQbsHAVvK6Le2JzamnaTqJqEZZtsvo +PrulKeLlkHARKotewi72COkkU0c8C6bF2wSHyT4q1TKAKEUV5v//YwF4kVCXZ2HB +Wy/FYwS77qTvPHbS9BxXnyxecZDjA5t8rgfYWREDLR7y/9cPoqhpIXYD56B0UPtR +fgVZguQk7nWzG5FKRsajahDvbcSnss03p7G8W8WV1UeB1GPD7DdQ5moxHKQEt2+f +btJQ4FYkXfEHdx5uydlfI5nf6Ej6ffibZ3ACU5JAQNT0mtEKzjZIem+txH/TNGmg +PhSVb931etG7H3Ue4Fylaiy4L/oVkGQ2Zz2vIwJnwJL9SjVr4uVoinMAP3a6GGLl +BxKytERtYugNsog0HCkFSKEvsOfUWqMMc0Ndn9TPVWrEYlHJKI7r8uckPhjuO5fv +j28FqlMu7FBbjR5viim5Cxtomj5TU6ugd79rlhBHjlgJtIk9RabKtDPmpYrlo6vp +nZIgKFlhbmcgU2hpaC1DaGluZykgPDYwMDA4MDI4RUBudG51LmVkdS50dz6IYgQT +EQIAIgUCT1SKPQIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQi9gubzC5 +S1wdXACeLQNiEBZiLARSVkpIH+Ty7kuaOhYAn1DOME94Iea60bgLWaMHm6bwRX0/ +iEYEEBECAAYFAlDXx+QACgkQPeaoSmjQcuYJMwCfYOqKVtO3e7cvF4JUhw6awlIa +F4AAn3hS9gPM6gr6ecrUwB+jJ73BI2WPiQIcBBMBAgAGBQJQokkxAAoJEEsdngig +l8munbEP/2urTfw4LE0IdXEXI4EIAdOZUFJ9/26mOQcv+Cih9NpIrLpl2zzGfScO +7hCWZGvQuY0C+jFaE1p+ziSkMy/dDHNEDaqi/auaxbz3xkKHxe/jgBZYh4ms55TW +oU5yGSbtiK/+WUZAPS+O+/OU4W3F7BcPMIjdvrKgVTSsZVA1Q+iGkoJpSCpjL/xG +R8Jp1R59uxN40+PXQKP+zraE3otTBtr1KvhEiCjupG7TnrerrHPqSXA7Qd2revUk +jJNV11LpinEv+atRMc+ZPeQ9dGGcVBXvNdry4LXHa++4xPC5YkOt6fzvgpCrIsIb +HDB0VyjvbJ7plQP5TtD4kQaAKgriaaYfuc50Ux1CIWhjSvAEq5pKJGBG62hbx+HH +/t065npzuhfAUX30ICH9qCbzO6YYJzlxYhEEnxSGAF+7n0Ek8S4RRpIyeCrKWUt1 +cRGwFIXj8BI2o6pFvCR/p0UNo3UVW17jv2smDfFE7aEAX88E9LQAr5oOvyvKueRA ++ywP+YOvvCwLrSipIQhM68u4LF83fKnLnPs8ANVtHnkcMbTP1HbHG1ZeiaLduDhj +q5CG1wDrvWdZpuvipfjg8UHRFBUcF+DXNS1FjgGrVxLr6NmGiEUEXUpyO2f6ZUH4 +K1tvndTjt0ac7GM7sbGvJEr7Nq9fqgp/R3dy8yrKQc1TtiGyCFG3iQIcBBABAgAG +BQJSARS5AAoJENyrIvdSTgnnR6QP/AwJVlzkMnAG7yHvO5RrD/q4TAqN6QM5/xyg +zZ4tUyMP0FkvwMe1bUJdzSJOCAXeCEpRqbmGtaW8tXgzdVk9DkyVhlj6SA2dw/Es +tT55AMuKPtpQtK9CSlVs1D0lgNU8e+Uc4CtepVT746wAz6qrPvdt9ASVeXnIwm3Y +L+ibQmCdpGeBC4utPqR8oD/0wFYEQLHjGMlQnwMdMd2C+QKZgEEAmRUBhBTZvDBF +X8NCD8bu9BGO8q6YexeKdc0Rikwsdc3t5s3XNRi/52hIYuAB1kkpg7uCMCAaZ02K +i+hcXodv879s8Hd9p2oOV3FwOF2SmhbRVr7UHvE1GLTW60lA2irpGczC8BZLsbMd +9g7SYYstB4haisVNQ7RRV95HCsCzqJO0awSLbEP2faEdmAB+AwZhylEH15sOf/bh +aaEzsWCXm+ehhXa9GNEATbA3e8n0xhiKho9vx+l8GqPZVsMGR24jrC4IA03QDA2/ +f/yyoSbC6hHBkImDL1k7/ESxAHYY46/u/tLqtpGfW4S0h1SHzZaNkA0yLMioROWZ +2QkGYt+Km3fAKEy04DFgUDbISTAk3DolRo07gHSVslXH7V/oJHxGRwbiGXYQ0e5v +S/MUYxaMRdAFUhe+qqWsoO12vYexiC/WGBLvCmo4gDlKxpT/E07iRlwJp6MBPqaI +pgJ673SVtCfkvp3nkarospMgKGltYWNhdCkgPGltYWNhdEBudG51LmVkdS50dz6I +YgQTEQIAIgUCVKpNawIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQi9gu +bzC5S1xIMgCghC6n+zQcRcFrFeKuCBir4uXecZ8AoKnME8Qa6vnUUpATaqmK9K3E +rA14tCjkvp3nkarospMgKGltYWNhdCkgPGltYWNhdEB3aWtpbWVkaWEudHc+iHgE +ExECADgWIQSBin4eTeP7OclnnAOL2C5vMLlLXAUCW1pv0gIbAwULCQgHAgYVCAkK +CwIEFgIDAQIeAQIXgAAKCRCL2C5vMLlLXBRwAJ0VOK7HTUV4rinfVzxG+zipOM/t +wgCfT8Hu5/7Nrw2zKJP/cxqyY2F3peO0KOS+neeRquiykyAoaW1hY2F0KSA8aW1h +Y2F0QHN0ZXBzLmNvbS50dz6IeAQTEQIAOBYhBIGKfh5N4/s5yWecA4vYLm8wuUtc +BQJbtsGVAhsDBQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEIvYLm8wuUtcp80A +nimnllD4oEKRPV7bUnvbo4qfjpJSAJ0QPDgMtoiHCeF4hJMaXaeIL3rZsrkEDQQ9 +JHzZEBAAowxPPj1TOZKGuav0eKopd8RrwFQ51P0FY85WyTAsCWg/KGcJIXFKwJ/r +4U381iQdz+16+E6oOzTIs/iwnkSKmfWx2M46uXdIa/VkLChZzHpCVDHeVICGE5sb +ECNS2gYDCRx/Jl/FnXNaeaI0RZm3i4gf204bvqsPm+epI/BOW4cZmbkqSd4BuG2/ +i7y/BZzPNhVseNVe2qhWFxs4Hj5S6y6xYSuuPLC4mZrkA7x1J9tq+wUt6z0mwIdR +hEaK5iE5PB44XiwGKW02sLt5CQXDW/DbqXlyu6VP90iVjWLg0ftI28dULipw2n6u +0DIGIxfLi4dDf0gcYyqDF++aMWYTlB7a89Vt055dp7NC59VaqltW9DgKnxkiTUMx +Z3HtqA67rwKtwKY3CQyuIYil31AQy0izi4fIu6MRznLtwHAfaqsB0Nej+kFl1XSU +spe3P6eaYzMs7on0X0KvPDWPo7AMz0Y/ex/XzYwR2+IzijTnaakH5TS7da0LKXb3 +FTV/PuIRUgH3P/yOwRyOU4VLWqcyLxBJuMlX1WVz3UdNfHwRfm+jqPktP0qnQ9Zr +Fk3VEOGv0hMvCeqj3Vw5CziYCTm3YiDG4OLPpUN3ByF944cUCYKwoGYEUKUf0vXP +vUYdshqBD49RyI0oy2nZstSt+iVefuCyWBYEyqIDu0eRGWY8FRMAAwUQAI/jMOnq +6mP7mfbsqq1ugXtx0r7cKNge0ebB/TA37ZLCo2UTdoxk/AsuGx1MK6kKJh3Zkxz8 +9jb84CXAjZbYbLOGhFioHCyiqfJwFbR7Abhsoo1NuEAtibJpFUm0oHym/Tjc4Xwh +t7cf52+8USfC918mFzmbPDOuIpkcHjGzXFztgDiMlX7iDrMvX2QOLzhp+g/I/pyA +hAcKH8EovcKeYOoQIM7hpP0eTZxgCDdRw9SpodU0/rTL6UzA4iXMcqncspH0OjfT +5gxj3cOoofhaPxsIoqllZA/V/x7CeykdNE5L5SYv3c0NBnTMe9kV4K8V0JHTyz7N +3ipiWJHPVObvgdrJyA9YYCpgorfE7a1rtmLPfr5evrTuKP+VMEInqvA0mAxzX/Hs +btsA+bNng6c5WibjO/kDKgfZfHFrPlLPiSSBVn9ygEySdlBuXpb5c7wft/YV0FyV +AikbhY3l3jJYmQ7kBxrtoIH9jK6Ff8rw7qbyBg6fDPoC3gevNdmoVtk5vTcKQTxP +KlCeXTtEJYfKDvX0BDkV8Wdizit03Sp0StpeietlX5vYQDyefp+w5J3k2SrbkEcz +zGZzXHq/5pm36cC0N0rA8ZW7JOpkThjZIJ733Y5DwtzhWqdUubWiCMmC7HfGmpI0 +OdV6QF8pkCKXIsJ90Uiep0lEDNQZg4Y96kuUiEYEGBECAAYFAj0kfNoACgkQi9gu +bzC5S1xOuACdELzJCBgMJVZ9siHwn48X2rXdQnIAn0yagIZfaIS0CfCamwcYeMfK +cQQV +=E/RG +-----END PGP PUBLIC KEY BLOCK----- diff --git a/htdocs/imacat/me/profile.html.en.html b/htdocs/imacat/me/profile.html.en.html new file mode 120000 index 0000000..d44feef --- /dev/null +++ b/htdocs/imacat/me/profile.html.en.html @@ -0,0 +1 @@ +profile.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/profile.html.en.xhtml b/htdocs/imacat/me/profile.html.en.xhtml new file mode 100644 index 0000000..97d4933 --- /dev/null +++ b/htdocs/imacat/me/profile.html.en.xhtml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + +imacat’s Personal Profile + + + + + + + +
    + +
    + + +

    imacat’s Personal Profile

    + +
    +imacat’s Private Bed♥room / imacat’s Personal Profile +
    + +

    You LIER! You have not even told your NAME!!!

    + +
      +
    • NAME: (Top Secret ^_*')
    • +
    • AGE: 29
    • +
    • BIRTHDAY: Thu, Sep. 13, 1973
    • +
    • ZODIAC: Virgo
    • +
    • BLOOD TYPE: B
    • +
    • PGP PUBLIC KEY:Click here
    • +
    + +
      +
    • HEIGHT: 167.5 cm
    • +
    • WEIGHT: 52 kg. Still dropping. I have to eat hard to keep it from dropping.
    • +
    • MAIN CHARACTERISTIC: A bundle of long, straight, soft hair swirling till my waist.
    • +
    • OTHER CHARACTERISTICS: Big eyes, dual eyelids and long eyelashes. I have a pair of beautiful eyes. Grecian nose.
    • +
    + +
      +
    • SCHOLARSHIP: Ungraduated from Math Department, National Taiwan University. (Quit at Jun,1995 as a sophomore. I stayed as a sophomore for 3 years.)
    • +
    • COLLEGE SOCIETY: NTU Continental Society
    • +
    • OCCUPATION: +
        +
      • Webmaster of Tavern IMACAT’s (1998/3~)
      • +
      • Editor and Webmaster of Woman’s Voice (WOV) Newsletter (1999/5~)
      • +
      • List Mamanger of Taiwan Linux Users’ Group (TLUG). (2001/8~)
      • +
      +
    • +
    • PART-TIME(:p) JOB: Web Application Developer. (2000/9~)
    • +
    • PAST EXPERIENCE: +
        +
      • Board Manager of Sex Board at NTU Palm BBS (1995/6~1995/7)
      • +
      • Volunteer for Taipei Association for The Promotion of Women’s Rights (1996/1~1996/6)
      • +
      • Secretary of NTU Continental Society (1996/1~1996/6)
      • +
      • Member of Dou-Nao-Re Troupe, Research Assistant of Tsai-Cha Culture Studio for the Project on History of Bai-Ho Town, Tainan County (1997/4~1997/8)
      • +
      • Volunteer for Taipei Alliance of Licensed Prostitutes and Solidary Front of Women Workers (1998/1~1998/8)
      • +
      • Volunteer for Taiwan New Telecommunications (TNT) (1998/4~1998/7)
      • +
      • Webmaster and Internet Contact Person of 98 Students’ Alliance Against High Tuition Policy (1998/6~1999/1)
      • +
      • Webmaster of Congress Legislative Yaun candidate Shu Zhu Fong’s website. (1998/10~1998/12)
      • +
      • Board Manager of Lesbian Board at NTU Palm BBS (1999/4~2000/6)
      • +
      • Column Writer of SCCID Newsletter (1999/7~2000/2)
      • +
      • Column Writer of HerCafé Woman’s Words (1999/10~)
      • +
      +
    • +
    + +
      +
    • FAVORITE STARS: Janet Jackson, Kelly Chen, A-baw, Kelly Huang, Chiaki
    • +
    • PROGRAMMING SPECIALTY: HTML/CSS, Perl, PHP, C
    • +
    + +
      +
    • ASTROLOGY CHART: +
      +9.3.1973 PM 6:30 at Taipei
      +121'30"E   25'03"N
      +Sun: Vir   Moo: Ari
      +Mer: Vir   Ven: Sco
      +Mar: Tau   Jup: Aqu
      +Sat: Can
      +Ura: Lib   Nep: Sag
      +Plu: Lib
      +Nor: Cap   Ris: Ari
      +Mid: Cap
      +
    • +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/me/profile.html.zh-cn.html b/htdocs/imacat/me/profile.html.zh-cn.html new file mode 120000 index 0000000..fc6a635 --- /dev/null +++ b/htdocs/imacat/me/profile.html.zh-cn.html @@ -0,0 +1 @@ +profile.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/profile.html.zh-cn.xhtml b/htdocs/imacat/me/profile.html.zh-cn.xhtml new file mode 100644 index 0000000..132a3ab --- /dev/null +++ b/htdocs/imacat/me/profile.html.zh-cn.xhtml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + +依玛猫的档案 + + + + + + + +
    + +
    + + +

    依玛猫的档案

    + +
    +依玛猫的闺♥房 / 依玛猫的个人资料 +
    + +

    骗人!你连名字都没有说!

    + +
      +
    • 姓名: (保密中)
    • +
    • 年龄: 29 岁
    • +
    • 出生年月日: 62 年 9 月 13 日
    • +
    • 星座: 处女座
    • +
    • 血型: B 型
    • +
    • PGP Public Key:按这边
    • +
    + +
      +
    • 身高: 167.5 公分
    • +
    • 体重: 52 公斤吧,下降中。要很用力吃才能维持。
    • +
    • 最大特徵: 长发及腰。很细很柔的直发喔!
    • +
    • 其他特徵: 大眼,双眼皮,长睫毛。眼睛很漂亮。高鼻。
    • +
    + +
      +
    • 学历: 台大数学系肄业( 84 年 6 月被 1/2 退学,二年级。我大二念了三年。)
    • +
    • 大学社团: 台大大陆社
    • +
    • 现职: +
        +
      • 旅舍依玛网站站长 (87.03~)
      • +
      • 《女声》电子报编辑兼网站站长 (88.05~)
      • +
      • 台湾 Linux 同好会通信群组管理员 (90.08~)
      • +
      +
    • +
    • 兼差( :p ): 网路应用工程师 (89.09~)
    • +
    • 经历: +
        +
      • 台大椰林风情 BBS 站性板板主 (84.06~84.07)
      • +
      • 台北市女性权益促进会义工 (84.06~84.07)
      • +
      • 台大大陆社干事 (85.01~85.06)
      • +
      • 斗闹热剧场团员、采茶文史工作室「台南县白河镇白河镇志计划」研究助理 (86.04~86.08)
      • +
      • 台北市公娼自救会、女工团结生产线义工 (87.01~87.08)
      • +
      • 宝岛新声广播电台 TNT 义工 (87.04~87.07)
      • +
      • 98 教春反高学费学生行动联盟网站站长兼网路联络人 (87.06~88.01)
      • +
      • 第三届立委选举候选人许主峰网站站长 (87.10~87.12)
      • +
      • 台大椰林风情 BBS 站拉子天堂板板主 (88.04~89.06)
      • +
      • 南方人文报专栏作家 (88.07~89.02)
      • +
      • HerCafé 女话专栏主笔 (88.10~91.05)
      • +
      +
    • +
    + +
      +
    • 喜欢的明星: 珍妮・杰克森、陈慧琳、曾宝仪(阿宝)、小娴(黄瑜娴)、藤本千秋
    • +
    • 程式专长: HTML/CSS, Perl, PHP, C
    • +
    + +
      +
    • 完整星座图: +
      +62 年 9 月 13 日 下午 6:30 台北
      +东经 121 度 30 分 北纬 25 度 03 分
      +太阳:处女 月亮:牡羊
      +水星:处女 金星:天蝎
      +火星:金牛 木星:水瓶
      +土星:巨蟹
      +天王:天秤 海王:射手
      +冥王:天秤
      +北方:摩羯 上升:牡羊
      +中间:摩羯
      +
    • +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/me/profile.html.zh-tw.html b/htdocs/imacat/me/profile.html.zh-tw.html new file mode 120000 index 0000000..7fa5913 --- /dev/null +++ b/htdocs/imacat/me/profile.html.zh-tw.html @@ -0,0 +1 @@ +profile.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/me/profile.html.zh-tw.xhtml b/htdocs/imacat/me/profile.html.zh-tw.xhtml new file mode 100644 index 0000000..a241430 --- /dev/null +++ b/htdocs/imacat/me/profile.html.zh-tw.xhtml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + +依瑪貓的檔案 + + + + + + + +
    + +
    + + +

    依瑪貓的檔案

    + +
    +依瑪貓的閨♥房 / 依瑪貓的個人資料 +
    + +

    騙人!妳連名字都沒有說!

    + +
      +
    • 姓名: (保密中)
    • +
    • 年齡: 29 歲
    • +
    • 出生年月日: 62 年 9 月 13 日
    • +
    • 星座: 處女座
    • +
    • 血型: B 型
    • +
    • PGP Public Key:按這邊
    • +
    + +
      +
    • 身高: 167.5 公分
    • +
    • 體重: 52 公斤吧,下降中。要很用力吃才能維持。
    • +
    • 最大特徵: 長髮及腰。很細很柔的直髮喔!
    • +
    • 其他特徵: 大眼,雙眼皮,長睫毛。眼睛很漂亮。高鼻。
    • +
    + +
      +
    • 學歷: 臺大數學系肄業( 84 年 6 月被 1/2 退學,二年級。我大二唸了三年。)
    • +
    • 大學社團: 臺大大陸社
    • +
    • 現職: +
        +
      • 旅舍依瑪網站站長 (87.03~)
      • +
      • 《女聲》電子報編輯兼網站站長 (88.05~)
      • +
      • 臺灣 Linux 同好會通信群組管理員 (90.08~)
      • +
      +
    • +
    • 兼差( :p ): 網路應用工程師 (89.09~)
    • +
    • 經歷: +
        +
      • 臺大椰林風情 BBS 站性板板主 (84.06~84.07)
      • +
      • 臺北市女性權益促進會義工 (84.06~84.07)
      • +
      • 臺大大陸社幹事 (85.01~85.06)
      • +
      • 鬥鬧熱劇場團員、採茶文史工作室「臺南縣白河鎮白河鎮誌計劃」研究助理 (86.04~86.08)
      • +
      • 臺北市公娼自救會、女工團結生產線義工 (87.01~87.08)
      • +
      • 寶島新聲廣播電臺 TNT 義工 (87.04~87.07)
      • +
      • 98 教春反高學費學生行動聯盟網站站長兼網路聯絡人 (87.06~88.01)
      • +
      • 第三屆立委選舉候選人許主峰網站站長 (87.10~87.12)
      • +
      • 臺大椰林風情 BBS 站拉子天堂板板主 (88.04~89.06)
      • +
      • 南方人文報專欄作家 (88.07~89.02)
      • +
      • HerCafé 女話專欄主筆 (88.10~91.05)
      • +
      +
    • +
    + +
      +
    • 喜歡的明星: 珍妮‧傑克森、陳慧琳、曾寶儀(阿寶)、小嫻(黃瑜嫻)、藤本千秋
    • +
    • 程式專長: HTML/CSS, Perl, PHP, C
    • +
    + +
      +
    • 完整星座圖: +
      +62 年 9 月 13 日 下午 6:30 臺北
      +東經 121 度 30 分 北緯 25 度 03 分
      +太陽:處女 月亮:牡羊
      +水星:處女 金星:天蠍
      +火星:金牛 木星:水瓶
      +土星:巨蟹
      +天王:天秤 海王:射手
      +冥王:天秤
      +北方:摩羯 上昇:牡羊
      +中間:摩羯
      +
    • +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/privacy.html.en.html b/htdocs/imacat/privacy.html.en.html new file mode 120000 index 0000000..4128cb5 --- /dev/null +++ b/htdocs/imacat/privacy.html.en.html @@ -0,0 +1 @@ +privacy.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/privacy.html.en.xhtml b/htdocs/imacat/privacy.html.en.xhtml new file mode 100644 index 0000000..cf2018c --- /dev/null +++ b/htdocs/imacat/privacy.html.en.xhtml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + +Privacy Policy of Tavern IMACAT’s + + + + + + + +
    + +
    + + +

    Privacy Policy of Tavern IMACAT’s

    + +

    Privacy Policy in Tavern IMACAT’s

    + +

    Tavern IMACAT’s supports internet privacy. I do not collect any personal infomation. The infomation you leave on Tavern IMACAT’s (if any) are not processed, collected, or redistributed by me. If you have any personal infomation that is distributed, violated, abused through Tavern IMACAT’s, please write to me.

    + + +

    Guestbook Privacy Policy in Tavern IMACAT’s

    + +

    All the guestbooks in the Tavern IMACAT’s (Travellers’ Guestbook, Soundless Backalley) are public web spaces. All infomation on them are public accessable. Tavern IMACAT’s does not collect any personal infomation on these guestbooks, but is also NOT responsible to any privacy issues regarding to infomations on the guestbooks. Please think twice before you leave any infomation on the guestbooks.

    + + +

    Cookie Policy in Tavern IMACAT’s

    + +

    Tavern IMACAT’s use cookies ONLY under the following circumstances:

    + +
      +
    1. Counter cookie, to avoid duplicated counter increasing.
    2. +
    + +

    All the cookies above are not physically saved onto your harddisk. They are constructed when the connection starts, and deleted automatic when the browser closes. Besides, Tavern does not use ANY cookie. Tavern does not use ANY cookie to trace, monitor, record users’ surfing habits, surfing records, surfing route and/or any of your personal infomation. All the cookies above are not necessary. You could safely turn off the cookies from your browser without any loses.

    + + +

    JavaScript Policy in Tavern IMACAT’s

    + +

    Tavern IMACAT’s use JavaScript ONLY under the following circumstances:

    + +
      +
    1. Pre-check the form inputs, in order to prevent transferring error data, to avoid wastes of internet bandwidth and to increase the surfing speed.
    2. +
    3. Ease your surfing in Tavern IMACAT’s.
    4. +
    5. Run the Hyper TextPlayground.
    6. +
    + +

    Otherwise, Tavern does not use any JavaScript. Tavern does not use any JavaScript to save, modify, return any of your personal infomation or contents on your harddisk. All the JavaScripts above are not necessary. You could safely turn off the JavaScript from your browser without any loses.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/privacy.html.zh-cn.html b/htdocs/imacat/privacy.html.zh-cn.html new file mode 120000 index 0000000..c4e13bf --- /dev/null +++ b/htdocs/imacat/privacy.html.zh-cn.html @@ -0,0 +1 @@ +privacy.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/privacy.html.zh-cn.xhtml b/htdocs/imacat/privacy.html.zh-cn.xhtml new file mode 100644 index 0000000..7326a55 --- /dev/null +++ b/htdocs/imacat/privacy.html.zh-cn.xhtml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + +旅舍依玛隐私权声明 + + + + + + + +
    + +
    + + +

    旅舍依玛隐私权声明

    + +

    旅舍依玛隐私权声明

    + +

    旅舍依玛支持网路隐私权,不搜集任何个人资料。你在旅舍留下的任何资料(如果有留的话)旅舍不会作任何处理、建档、散布。若你的个人资料经由旅舍依玛被散布、侵犯、使用,请来信告知。

    + + +

    旅舍依玛留言板隐私权声明

    + +

    旅舍依玛上的所有留言板(旅人留言簿、无声的后巷)属公共空间,留言板任何资料均为公众可阅读。旅舍依玛不搜集留言板上任何资料,但也不为留言板任何资料负任何责任。请自行斟酌你要留下的个人资料。

    + + +

    旅舍依玛 cookie 使用声明

    + +

    旅舍依玛只在下列情况下使用 cookies :

    + +
      +
    1. 访客计数器 cookie ,避免重复计数。
    2. +
    + +

    以上所列 cookies 皆不储存於你的硬碟中,於连线时建立,於浏览器关闭时自动清除。此外,旅舍不使用任何 cookies 。旅舍不使用任何 cookies 以追踪、监视、记录网友的上网习惯、上站记录、上站流程及你的个人资料。上述 cookies 均非必要,你可自由关闭浏览器的 cookies 功能,没有任何影响。

    + + +

    旅舍依玛 JavaScript 使用声明

    + +

    旅舍依玛只在下列情况下使用 JavaScript :

    + +
      +
    1. 预先检查表格错误,避免传送错误资料,浪费网路频宽并减缓浏览速度。
    2. +
    3. 方便浏览。
    4. +
    5. 执行超文字游乐场。
    6. +
    + +

    此外,旅舍不使用任何 JavaScript 。旅舍不使用 JavaScript 以储存、修改、回传你的个人资料或硬碟档案。上述 JavaScript 均非必要,你可自由关闭浏览器 JavaScript 功能,没有任何影响。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/privacy.html.zh-tw.html b/htdocs/imacat/privacy.html.zh-tw.html new file mode 120000 index 0000000..d1c3c99 --- /dev/null +++ b/htdocs/imacat/privacy.html.zh-tw.html @@ -0,0 +1 @@ +privacy.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/privacy.html.zh-tw.xhtml b/htdocs/imacat/privacy.html.zh-tw.xhtml new file mode 100644 index 0000000..8a34549 --- /dev/null +++ b/htdocs/imacat/privacy.html.zh-tw.xhtml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + +旅舍依瑪隱私權聲明 + + + + + + + +
    + +
    + + +

    旅舍依瑪隱私權聲明

    + +

    旅舍依瑪隱私權聲明

    + +

    旅舍依瑪支持網路隱私權,不搜集任何個人資料。妳在旅舍留下的任何資料(如果有留的話)旅舍不會作任何處理、建檔、散佈。若妳的個人資料經由旅舍依瑪被散佈、侵犯、使用,請來信告知。

    + + +

    旅舍依瑪留言板隱私權聲明

    + +

    旅舍依瑪上的所有留言板(旅人留言簿、無聲的後巷)屬公共空間,留言板任何資料均為公眾可閱讀。旅舍依瑪不搜集留言板上任何資料,但也不為留言板任何資料負任何責任。請自行斟酌妳要留下的個人資料。

    + + +

    旅舍依瑪 cookie 使用聲明

    + +

    旅舍依瑪只在下列情況下使用 cookies :

    + +
      +
    1. 訪客計數器 cookie ,避免重複計數。
    2. +
    + +

    以上所列 cookies 皆不儲存於妳的硬碟中,於連線時建立,於瀏覽器關閉時自動清除。此外,旅舍不使用任何 cookies 。旅舍不使用任何 cookies 以追蹤、監視、記錄網友的上網習慣、上站記錄、上站流程及妳的個人資料。上述 cookies 均非必要,妳可自由關閉瀏覽器的 cookies 功能,沒有任何影響。

    + + +

    旅舍依瑪 JavaScript 使用聲明

    + +

    旅舍依瑪只在下列情況下使用 JavaScript :

    + +
      +
    1. 預先檢查表格錯誤,避免傳送錯誤資料,浪費網路頻寬並減緩瀏覽速度。
    2. +
    3. 方便瀏覽。
    4. +
    5. 執行超文字遊樂場。
    6. +
    + +

    此外,旅舍不使用任何 JavaScript 。旅舍不使用 JavaScript 以儲存、修改、回傳妳的個人資料或硬碟檔案。上述 JavaScript 均非必要,妳可自由關閉瀏覽器 JavaScript 功能,沒有任何影響。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/robots.txt b/htdocs/imacat/robots.txt new file mode 100644 index 0000000..8137780 --- /dev/null +++ b/htdocs/imacat/robots.txt @@ -0,0 +1,11 @@ +User-agent: * +Crawl-delay: 1 +Disallow: /magicat/ +Disallow: /home/ +Disallow: /doc/ + +User-agent: chklinks +Disallow: + +User-agent: HTTrack +Disallow: / diff --git a/htdocs/imacat/scripts/accounting.js b/htdocs/imacat/scripts/accounting.js new file mode 100644 index 0000000..b8ee34c --- /dev/null +++ b/htdocs/imacat/scripts/accounting.js @@ -0,0 +1,198 @@ +/* Tavern IMACAT's + * accounting.js: The accounting-related JavaScript subroutines. + */ + +/* Copyright (c) 2007-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2007-09-26 + */ + +// setAutoSummary: Automatically supply a summary +function setAutoSummary(subj) { + var i, j, sum, dateText, today, subjText, subjCode, thisMonth; + // Get the name prefix of this selection + i = subj.name.indexOf("subj"); + // Obtain the summary column + sum = subj.form[subj.name.substr(0, i) + "summary"]; + // Get today's date + today = new Date; + dateText = trim(subj.form.date.value); + if (!isDate(dateText)) + return; + today.setFullYear(dateText.substr(0, 4)); + today.setMonth(dateText.substr(5, 2) - 1); + today.setDate(dateText.substr(8, 2)); + thisMonth = today.getMonth() + 1; + // Obtain the selected subject + // The value of the selection is S/N but not subject code, + // so we have to obtain the subject code from the option text + subjText = subj.options[subj.selectedIndex].text; + subjCode = parseInt(subjText.substr(0, subjText.indexOf(" "))); + switch (subjCode) { + // 62562 手機 0938-31-0688 + case 62562: + if (subj.name.substr(0, 4) == "debt") { + // Assume to be of the previous month + sum.value = "電話費" + ((thisMonth + 10) % 12 + 1) + "月"; + // 13 or later - assume to be of the previous month + //if (today.getDate() >= 13) { + // sum.value = "電話費" + ((thisMonth + 10) % 12 + 1) + "月"; + // Before 13 - assume to be of the previous-previous month + //} else { + // sum.value = "電話費" + ((thisMonth + 9) % 12 + 1) + "月"; + //} + } + break; + // 62561 共同生活基金 + case 62651: + sum.value = "共同生活基金" + thisMonth + "月"; + break; + // 21411 應付帳款—共同生活基金 + case 11411: + if (subj.name.substr(0, 4) == "debt") { + sum.value = "共同生活基金" + thisMonth + "月"; + } + break; + // 11411 應收帳款—精粹薪資 + case 11411: + if (subj.name.substr(0, 4) == "debt") { + sum.value = ((thisMonth + 10) % 12 + 1) + "月份薪水"; + } + break; + // 46111 勞務收入—精粹 + // 46112 勞務收入—晟鑫 + case 46111: + case 46112: + if (subj.name.substr(0, 4) == "crdt") { + sum.value = ((thisMonth + 10) % 12 + 1) + "月份薪水"; + } + break; + // 46114 勞務收入—師大 + // 46115 勞務收入—清大 + case 46114: + case 46115: + if (subj.name.substr(0, 4) == "crdt") { + sum.value = thisMonth + "月份薪水"; + } + break; + // 62621 全民健康保險 + case 62621: + if (subj.name.substr(0, 4) == "debt") { + // 15 or later - assume to be of previous month + if (today.getDate() >= 15) { + sum.value = "健保" + ((thisMonth + 10) % 12 + 1) + "月"; + // Before 15 - assume to be of previous-previous month + } else { + sum.value = "健保" + ((thisMonth + 9) % 12 + 1) + "月"; + } + } + break; + // 13141 國民年金 + case 13141: + sum.value = "國民年金" + thisMonth + "月"; + break; + // 21414 應付帳款—國民年金 + case 21414: + if (subj.name.substr(0, 4) == "crdt") { + sum.value = "國民年金" + thisMonth + "月"; + } else { + // 20 or later - assume to be of previous month + if (today.getDate() >= 15) { + sum.value = "國民年金" + ((thisMonth + 9) % 12 + 1) + "月"; + // Before 15 - assume to be of previous-previous month + } else { + sum.value = "國民年金" + ((thisMonth + 8) % 12 + 1) + "月"; + } + } + break; + } + return; +} + +// acctRepQueryDisableNoUseRanges: Disable range parameters that are not in use +function acctRepQueryDisableNoUseRanges() { + var i, form, curValue; + // Obtain our form + form = document.forms["acctrepquery"]; + if (form == undefined) + return; + // Find the current selection + for (i = 0; i < form.r.length; i++) { + if (form["r"][i].checked) { + curValue = form["r"][i].value; + break; + } + } + // Disable or enable the month selection + if (curValue == "m") + form["m"].disabled = false; + else + form["m"].disabled = true; + // Disable or enable the year selection + if (curValue == "y") + form["y"].disabled = false; + else + form["y"].disabled = true; + // Disable or enable the start and end date + if (curValue == "s") { + form["f"].disabled = false; + form["t"].disabled = false; + } else { + form["f"].disabled = true; + form["t"].disabled = true; + } + return; +} + +// calcTotal: Calculating the total +function calcTotal(amount) { + var i, j, side, sum, a, pos, isNumber; + a = "NT$ 3,433.00"; + side = amount.name.substr(0, 4); + for ( i = 0, sum = 0; + amount.form[side + i + "amount"] != undefined; + i++) { + a = amount.form[side + i + "amount"]; + // Trim the text + a.value = trim(a.value); + // Remove the dollar sign + if (a.value.substr(0, 3) == "NT$") + a.value = a.value.substr(3); + // Trim the text again, for possible spaces after the dollar sign + a.value = trim(a.value); + // Remove the decimal point + if (a.value.substr(a.value.length - 3) == ".00") + a.value = a.value.substr(0, a.value.length - 3); + // Remove the thousand seperators + while ((pos = a.value.indexOf(",")) != -1) { + a.value = a.value.substr(0, pos) + a.value.substr(pos + 1); + } + // Check if it is a number + for (j = 0, isNumber = true; j < a.value.length; j++) { + if (a.value.charCodeAt(j) < 48 || a.value.charCodeAt(j) > 57) { + isNumber = false; + break; + } + } + // Add the amount + if (isNumber) + sum = sum + a.value * 1; + } + a = amount.form[side + "total"]; + if (a != undefined) + a.value = sum; +} diff --git a/htdocs/imacat/scripts/common.js b/htdocs/imacat/scripts/common.js new file mode 100644 index 0000000..5da3298 --- /dev/null +++ b/htdocs/imacat/scripts/common.js @@ -0,0 +1,139 @@ +/* Tavern IMACAT's + * common.js: The common JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-06-24 + */ + +// _: Gettext +function _(msg) { + var i; + for (i = 0; i < lc_messages.length; i++) { + if (lc_messages[i][0] == msg) { + return lc_messages[i][1]; + } + } + return msg; +} +// The messages +lc_messages = []; + +// isEmail: Check if an email address is legal +function isEmail(a) { + var i, c, re; + if (typeof(RegExp) == "undefined") return true; + re = new RegExp("^[\\w\\-]+(\\.[\\w\\-]+)*\\@([\\w\\-]+\\.)+[\\w\\-]+$"); + if (typeof(a) != "string") return false; + a = a.toLowerCase(); + if (re.exec(a) == null) return false; + return true; +} + +// isDate: Check if a date is legal +function isDate(dateText) { + var i, year, month, day, maxDay; + if (dateText.length != 10) { + return false; + } + // Check each character + for (i = 0; i < dateText.length; i++) { + // The dash sign + if (i == 4 || i == 7) { + if (dateText.charAt(i) != "-") + return false; + // The digits + } else { + if (dateText.charCodeAt(i) < 48 || dateText.charCodeAt(i) > 57) + return false; + } + } + // Check if the date is valid + year = dateText.substr(0, 4) * 1; + month = dateText.substr(5, 2) * 1; + day = dateText.substr(8, 2) * 1; + // A reasonable month + if (month < 1 || month > 12) + return false; + // Find the maximum day in this month + switch (month) { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + maxDay = 31; + break; + case 4: + case 6: + case 9: + case 11: + maxDay = 30; + break; + case 2: + maxDay = 28; + if (year % 4 == 0) + maxDay = 29; + if (year % 100 == 0) + maxDay = 28; + if (year % 400 == 0) + maxDay = 29; + break; + } + // A reasonable day + if (day < 1 || day > maxDay) + return false; + return true; +} + +// trim: Trim the leading and tailing spaces +function trim(a) { + var pos, start, len, spaces; + start = 0; + len = a.length; + spaces = " \t\f\n\r"; + for (start = 0; start < a.length && spaces.indexOf(a.charAt(start)) >= 0; start++, len--); + for (pos = a.length - 1; pos >= 0 && spaces.indexOf(a.charAt(pos)) >= 0; pos--, len--); + return a.substr(start, len); +} +function trimText(a) { + var pos, start, len, spaces, newlines; + start = 0; + len = a.length; + spaces = " \t\f\n\r"; + newlines = "\n\r"; + for (start = 0; start < a.length && spaces.indexOf(a.charAt(start)) >= 0; start++, len--); + for ( ; start-1 >= 0 && newlines.indexOf(a.charAt(start-1)) < 0; start--, len++); + for (pos = a.length - 1; pos >= 0 && spaces.indexOf(a.charAt(pos)) >= 0; pos--, len--); + return a.substr(start, len); +} + +// replace: Replace one phace with another in a string +function replace(source, oldStr, newStr) { + var pos; + pos = 0; + while (true) { + pos = source.indexOf(oldStr, pos); + if (pos == -1) break; + source = source.substr(0, pos) + newStr + source.substr(pos + oldStr.length) + pos += newStr.length; + } + return source; +} diff --git a/htdocs/imacat/scripts/garbage.js b/htdocs/imacat/scripts/garbage.js new file mode 100644 index 0000000..d8fed9a --- /dev/null +++ b/htdocs/imacat/scripts/garbage.js @@ -0,0 +1,43 @@ +/* Tavern IMACAT's + * garbage.js: The Soundless Backalley related JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-06-24 + */ + +// isGuestbookOK: Check if the message is ready to be submitted +function isGuestbookOK(form) { + + // Regularize the fields + form.message.value = trimText(form.message.value); + + // Check the message + if (trim (form.message.value) == "" || form.message.value == _("Fill in your message here.")) { + alert(_("Please fill in your message.")); + form.message.focus(); + return false; + } + if (form.message.value.length > 10240) { + alert(_("Your message is too long. (Max. 10,240 letters)")); + form.message.focus(); + return false; + } + + return true; +} diff --git a/htdocs/imacat/scripts/guestbook.js b/htdocs/imacat/scripts/guestbook.js new file mode 100644 index 0000000..8f50e13 --- /dev/null +++ b/htdocs/imacat/scripts/guestbook.js @@ -0,0 +1,55 @@ +/* Tavern IMACAT's + * guestbook.js: The guestbook-related JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-06-24 + */ + +// isGuestbookOK: Check if the message is ready to be submitted +function isGuestbookOK(form) { + + // Regularize the fields + form.message.value = trimText(form.message.value); + form.name.value = trim(form.name.value); + form.identity.value = trim(form.identity.value); + form.location.value = trim(form.location.value); + form.email.value = trim(form.email.value); + form.url.value = trim(form.url.value); + + // Check the message + if (form.message.value == "" || form.message.value == _("Fill in your message here.")) { + alert(_("Please fill in your message.")); + form.message.focus(); + return false; + } + if (form.message.value.length > 10240) { + alert(_("Your message is too long. (Max. 10,240 letters)")); + form.message.focus(); + return false; + } + message = form.message.value.toLowerCase(); + if (message.indexOf(" + * First written: 2004-11-05 + */ diff --git a/htdocs/imacat/scripts/lang.zh-cn.js b/htdocs/imacat/scripts/lang.zh-cn.js new file mode 100644 index 0000000..6608c69 --- /dev/null +++ b/htdocs/imacat/scripts/lang.zh-cn.js @@ -0,0 +1,43 @@ +/* Tavern IMACAT's + * lang.zh-tw.js: The Chinese (Taiwan) localized messages. + */ + +/* Copyright (c) 2004-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2004-11-05 + */ + +// The messages +lc_messages = [ +["Fill in your message here.", "请填上你的留言。"], +["Please fill in your message.", "请填上你的留言。"], +["Your message is too long. (Max. 10,240 letters)", "你的留言太长了。(最长 10,240 个字)"], +["Your message contains HTML, which will be displayed \"AS IS\". If this is a commercial advertisement, it will be deleted right away and you are wasting your time. Do you still want to submit this message?", "你的留言内含 HTML , HTML 会以原代码秀出。一般商业广告留言随见随删,请勿浪费时间。你确定要留这则留言吗?"], +["Your message contains BBCode, which will be displayed \"AS IS\". If this is a commercial advertisement, it will be deleted right away and you are wasting your time. Do you still want to submit this message?", "你的留言内含 BBCode , BBCode 会以原代码秀出。一般商业广告留言随见随删,请勿浪费时间。你确定要留这则留言吗?"], + +["Fill in the description here.", "请填上简介。"], +["This description is too long. (Max. 256 letters)", "简介太长了。(最长 256 个字)"], +["Please fill in the site name.", "请填上站名。"], +["Please fill in the URL.", "请填上网址。"], +["Please fill in the description.", "请填上简介。"], + +["Please fill in your subscription e-mail.", "请填上收件用的 E-mail 信箱。"], +["This e-mail is malformed. Please fill in a valid one.", "E-mail 有误,请检查有没有拼错。"], +["Please fill in your password.", "请设置密码。"], +["Please confirm the password.", "请核对你设置的密码。"], +["The 2 passwords are different. Please fill in the password again.", "核对密码不符,请重新设置密码。"], +]; diff --git a/htdocs/imacat/scripts/lang.zh-tw.js b/htdocs/imacat/scripts/lang.zh-tw.js new file mode 100644 index 0000000..97de999 --- /dev/null +++ b/htdocs/imacat/scripts/lang.zh-tw.js @@ -0,0 +1,43 @@ +/* Tavern IMACAT's + * lang.zh-tw.js: The Chinese (Taiwan) localized messages. + */ + +/* Copyright (c) 2004-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2004-11-05 + */ + +// The messages +lc_messages = [ +["Fill in your message here.", "請填上妳的留言。"], +["Please fill in your message.", "請填上妳的留言。"], +["Your message is too long. (Max. 10,240 letters)", "妳的留言太長了。(最長 10,240 個字)"], +["Your message contains HTML, which will be displayed \"AS IS\". If this is a commercial advertisement, it will be deleted right away and you are wasting your time. Do you still want to submit this message?", "妳的留言內含 HTML , HTML 會以原始碼秀出。一般商業廣告留言隨見隨刪,請勿浪費時間。妳確定要留這則留言嗎?"], +["Your message contains BBCode, which will be displayed \"AS IS\". If this is a commercial advertisement, it will be deleted right away and you are wasting your time. Do you still want to submit this message?", "妳的留言內含 BBCode , BBCode 會以原始碼秀出。一般商業廣告留言隨見隨刪,請勿浪費時間。妳確定要留這則留言嗎?"], + +["Fill in the description here.", "請填上簡介。"], +["This description is too long. (Max. 256 letters)", "簡介太長了。(最長 256 個字)"], +["Please fill in the site name.", "請填上站名。"], +["Please fill in the URL.", "請填上網址。"], +["Please fill in the description.", "請填上簡介。"], + +["Please fill in your subscription e-mail.", "請填上收件用的 E-mail 信箱。"], +["This e-mail is malformed. Please fill in a valid one.", "E-mail 有誤,請檢查有沒有拼錯。"], +["Please fill in your password.", "請設定密碼。"], +["Please confirm the password.", "請核對你設定的密碼。"], +["The 2 passwords are different. Please fill in the password again.", "核對密碼不符,請重新設定密碼。"], +]; diff --git a/htdocs/imacat/scripts/links.js b/htdocs/imacat/scripts/links.js new file mode 100644 index 0000000..744aff9 --- /dev/null +++ b/htdocs/imacat/scripts/links.js @@ -0,0 +1,75 @@ +/* Tavern IMACAT's + * links.js: The related-link related JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-06-28 + */ + +// isRegisterOK: Check if the register form is ready to be submitted +function isRegisterOK(form) { + + // Regularize the fields + form.title.value = trim(form.title.value); + form.title_2ln.value = trim(form.title_2ln.value); + form.url.value = trim(form.url.value); + form.icon.value = trim(form.icon.value); + form.cat0.value = trim(form.cat0.value); + form.cat1.value = trim(form.cat1.value); + form.cat2.value = trim(form.cat2.value); + form.dsc.value = trimText(form.dsc.value); + form.email.value = trim(form.email.value); + form.addr.value = trim(form.addr.value); + form.tel.value = trim(form.tel.value); + form.fax.value = trim(form.fax.value); + + // Check the site name + if (form.title.value == "") { + alert(_("Please fill in the site name.")); + form.title.focus(); + return false; + } + + // Check the URL + if (form.url.value == "" || form.url.value == "http://") { + alert(_("Please fill in the URL.")); + form.url.focus(); + return false; + } + + // Check the description + if (form.dsc.value == "" || form.dsc.value == _("Fill in the description here.")) { + alert(_("Please fill in the description.")); + form.dsc.focus(); + return false; + } + if (form.dsc.value.length > 256) { + alert(_("This description is too long. (Max. 256 letters)")); + form.dsc.focus(); + return false; + } + + return true; +} + +// clearDscDefault: Clear the default value of the description +function clearDscDefault(dsc, deftext) { + if (dsc.value == deftext) { + dsc.value = ""; + } +} diff --git a/htdocs/imacat/scripts/openshow.js b/htdocs/imacat/scripts/openshow.js new file mode 100644 index 0000000..ee13d36 --- /dev/null +++ b/htdocs/imacat/scripts/openshow.js @@ -0,0 +1,188 @@ +/* Tavern IMACAT's + * openshow.js: The Opening Show JavaScript subroutines. + */ + +/* Copyright (c) 2004-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2004-11-05 + */ + +var wordsCount = 4; +var timeStep = 50; +var splitDegree = Math.PI * 2 / wordsCount; +var show01StartSize = 600; +var show01StartSizeStep = 20; +var show01SizeStepAccerator = 10; +var show02SizeStep = 4; +var show02FinalSize = 40; +var show03Size = 40; +var show03Radius = 160; +var show03DegreeStep = Math.PI / 24; +var show04Size = show03Size; +var show04Radius = show03Radius; +var show04StartDegreeStep = show03DegreeStep; +var show04DegreeStepAcceration = show04StartDegreeStep / 4; +var show05Size = show04Size; +var show05DegreeStep; +var show05Radius = show04Radius; +var show05RadiusStep = 4; +var show06Size = show02FinalSize; +var show07HueStep = 8; +var colors = new Array(); +var showWindow; + +function startShow() { + var bodyContent, pos; + bodyContent = document.all.tags("html")[0].innerHTML; + pos = bodyContent.lastIndexOf(" 0) setTimeout("show01(" + n + ", " + (size - sizeStep) + ", "+ (sizeStep + show01SizeStepAccerator) + ");", timeStep); + else if (n < wordsCount) setTimeout("show01(" + (n+1) + ", " + show01StartSize + ", "+ show01StartSizeStep + ");", timeStep); + else show02(4, true); +} +function show02(size, enlarge) { + var i, thisStyle; + if (size < 0) setTimeout("show03(0);", timeStep); + else if (size > show02FinalSize) setTimeout("show02(" + (size - show02SizeStep) + ", false);", timeStep * 4); + else if (enlarge) { + for (i = 1; i <= wordsCount; i++) { + thisStyle = document.all["word_" + i].style; + thisStyle.fontSize = size; + thisStyle.left = 170 + ((i-3) * 3 - 1) * size / 2; + thisStyle.top = (340 - size) / 2; + } + setTimeout("show02(" + (size + show02SizeStep) + ", true)", timeStep); + } else { + for (i = 1; i <= wordsCount; i++) { + thisStyle = document.all["word_" + i].style; + thisStyle.fontSize = size; + thisStyle.left = 170 + ((i-3) * 3 - 1) * size / 2; + thisStyle.top = (340 - size) / 2; + } + setTimeout("show02(" + (size - show02SizeStep) + ", false)", timeStep); + } +} +function show03(degree) { + var i, thisStyle, thisDegree, thisSize, thisSin, thisRadius; + thisSin = Math.sin(degree); + thisSize = parseInt(show03Size * thisSin); + if (thisSize < 0) thisSize *= -1; + thisRadius = show03Radius * thisSin; + for (i = 1; i <= wordsCount; i++) { + thisStyle = document.all["word_" + i].style; + thisDegree = degree + i * splitDegree; + thisStyle.top = parseInt(170 + thisRadius * Math.cos(thisDegree) - thisSize/2); + thisStyle.left = parseInt(170 - thisRadius * Math.sin(thisDegree) - thisSize/2); + thisStyle.fontSize = thisSize; + } + if (degree <= Math.PI * 2.5) setTimeout("show03(" + (degree + show03DegreeStep) + ");", timeStep); + else setTimeout("show04(" + (degree - Math.PI * 2 + show03DegreeStep) + "," + show04StartDegreeStep + ");", timeStep); +} +function show04(degree, degreeStep) { + var i; + for (i = 1; i <= wordsCount; i++) { + thisStyle = document.all["word_" + i].style; + thisDegree = degree + i * splitDegree; + thisStyle.top = parseInt(170 + show04Radius * Math.cos(thisDegree) - show04Size/2); + thisStyle.left = parseInt(170 - show04Radius * Math.sin(thisDegree) - show04Size/2); + } + if (degree <= Math.PI * 3) setTimeout("show04(" + (degree + degreeStep) + "," + (degreeStep + show04DegreeStepAcceration) + ");", timeStep); + else { + show05DegreeStep = degreeStep; + setTimeout("show05(" + (degree - Math.PI * 3 + degreeStep) + "," + show04Radius + ");", timeStep); + } +} +function show05(degree, radius) { + var i, thisSize; + thisSize = parseInt(show05Size * radius / show05Radius); + for (i = 1; i <= wordsCount; i++) { + thisStyle = document.all["word_" + i].style; + thisDegree = degree + i * splitDegree; + thisStyle.top = parseInt(170 + radius * Math.cos(thisDegree) - thisSize/2); + thisStyle.left = parseInt(170 - radius * Math.sin(thisDegree) - thisSize/2); + thisStyle.fontSize = thisSize; + } + if (radius >= show05RadiusStep) setTimeout("show05(" + (degree + show05DegreeStep) + "," + (radius - show05RadiusStep) + ");", timeStep); + else show06(1); +} +function show06(n) { + var thisStyle = document.all["word_" + n].style; + thisStyle.top = 170 - show06Size / 2; + thisStyle.left = 170 + ((n - 3) * 3 - 1) * show06Size / 2; + thisStyle.fontSize = show06Size; + if (n < wordsCount) setTimeout("show06(" + (n+1) + ");", timeStep * 4); + else { + setTimeout("document.all.press_to_close.style.visibility = \"visible\";", timeStep * 8); + setTimeout("show07(256/6);", timeStep); + } +} +function show07(hue) { + var red, green, blue; + if (hue < 256/6) { + red = 255; + green = parseInt(hue * 6); + blue = 0; + } else if (hue >= 256/6 && hue < 512/6) { + red = parseInt(255 - (hue - 256/6) * 6); + green = 255; + blue = 0; + } else if (hue >= 512/6 && hue < 768/6) { + red = 0; + green = 255; + blue = parseInt((hue - 512/6) * 6); + } else if (hue >= 768/6 && hue < 1024/6) { + red = 0; + green = parseInt(255 - (hue - 768/6) * 6); + blue = 255; + } else if (hue >= 1024/6 && hue < 1280/6) { + red = parseInt((hue - 1024/6) * 6); + green = 0; + blue = 255; + } else if (hue >= 1280/6) { + red = 255; + green = 0; + blue = parseInt(255 - (hue - 1280/6) * 6); + } + + for (i = 1; i <= wordsCount; i++) { + document.all["word_" + i].style.color = "#" + toHex(parseInt(red/16)) + toHex(red % 16) + toHex(parseInt(green/16)) + toHex(green % 16) + toHex(parseInt(blue/16)) + toHex(blue % 16); + } + hue += show07HueStep; + if (hue >= 256) hue -= 256; + setTimeout("show07(" + hue + ");", timeStep); +} +function toHex(digit) { + if (digit < 10) return digit; + return String.fromCharCode(55 + digit); +} +function showOpener() { + opener.document.all.tags("body")[0].style.visibility = "visible"; +} diff --git a/htdocs/imacat/scripts/playgrnd.js b/htdocs/imacat/scripts/playgrnd.js new file mode 100644 index 0000000..9b68a87 --- /dev/null +++ b/htdocs/imacat/scripts/playgrnd.js @@ -0,0 +1,182 @@ +/* Tavern IMACAT's + * playgrnd.js: The Hypetext Playground JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-07-02 + */ + +// Changes to a random font. +function setUpTitle() { + var i; + var cFonts = new Array("細明體", "新細明體", "標楷體", "華康儷粗黑", "華康少女文字W7"); + var eFonts = new Array("Times New Roman", "Arial", "Comic Sans MS"); + + if (navigator.appName == "Netscape") return; + for (i = 1; i <= 6; i++) { + document.all["titlec" + i].style.color = rndClr(); + document.all["titlec" + i].style.fontSize = rndTSize(); + document.all["titlec" + i].style.fontFamily = rndFont(cFonts); + } + for (i = 1; i <= 19; i++) { + document.all["titlee" + i].style.color = rndClr(); + document.all["titlee" + i].style.fontSize = rndTSize(); + document.all["titlee" + i].style.fontFamily = rndFont(eFonts); + } + return; +} + + +// Shows the result. +function gogogo(form) { + var html, len, text, paragraph, langPhases, fonts, phase, resultWin, i, j; + var cFonts = new Array(), eFonts = new Array(); + + if (navigator.appName == "Netscape" && parseInt(navigator.appVersion) < 5) return true; + for (i = 0, j = 0; i < form.cfonts.length; i++) { + if (form.cfonts[i].checked) { + cFonts[j] = form.cfonts[i].value; + j++; + } + } + for (i = 0, j = 0; i < form.efonts.length; i++) { + if (form.efonts[i].checked) { + eFonts[j] = form.efonts[i].value; + j++; + } + } + text = form.text.value; + text = replace(text, "\n", ""); + text = replace(text, "\r", ""); + html = ""; + html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; + html += "HyperText Playground 超文字遊樂場\n"; + html += "\n"; + html += "\n"; + html += "\n"; + while (text != "") { + html += "

    "; + len = rndPLen(); + paragraph = text.substr(0, len); + text = text.substr(len); + langPhases = sepLang(paragraph); + for (i = 0; i < langPhases.length; i++) { + if (langOf(langPhases[i]) == "ch") fonts = cFonts; + else fonts = eFonts; + while (langPhases[i] != "" ) { + len = rndLen(); + phase = langPhases[i].substr(0, len); + langPhases[i] = langPhases[i].substr(len); + html += "" + phase + ""; + } + } + html += "

    \n"; + html += "\n"; + } + html += "\n"; + html += ""; + resultWin = window.open("", "", "toolbar=no,location=no,menubar=no,status=yes,scrollbars=yes,resizable=yes,width=640,height=480"); + resultWin.document.write(html); + resultWin.document.close(); + return false; +} + +// Obtains a random paragraph length. +function rndPLen() { + return parseInt(Math.random() * 50) + 1; +} +// Obtains a random phrase length. +function rndLen() { + return parseInt(Math.random() * 5) + 1; +} +// Obtains a random font size. +function rndSize() { + return ((parseInt(Math.random() * 20) + 7) / 10) + "em"; +} +// Obtains a random font size for the title. +function rndTSize() { + return ((parseInt(Math.random() * 20) + 15) / 10) + "em"; +} +// Obtains a random font. +function rndFont(fonts) { + return fonts[parseInt(Math.random() * fonts.length)]; +} +// Obtains a random width. +function rndWidth() { + return (parseInt(Math.random() * 15) + 5) + "em"; +} +// Obtains a random color. +function rndClr() { + var hexNumber = "0123456789ABCDEF", result = "#"; + result += hexNumber.charAt(parseInt(Math.random() * 16)); + result += hexNumber.charAt(parseInt(Math.random() * 16)); + result += hexNumber.charAt(parseInt(Math.random() * 16)); + result += hexNumber.charAt(parseInt(Math.random() * 16)); + result += hexNumber.charAt(parseInt(Math.random() * 16)); + result += hexNumber.charAt(parseInt(Math.random() * 16)); + return result; +} + +// Split the text into pieces by language, Chinese or English. +function sepLang(a) { + var pos, phases = new Array(), count, lang; + for (count = 0, pos = 0; pos < a.length; count++) { + lang = langOf(a.charAt(pos)); + phases[count] = ""; + for (; pos < a.length && langOf(a.charAt(pos)) == lang; pos++) { + phases[count] += a.charAt(pos); + } + } + return phases; +} + +// Tells the language of a text piece. +function langOf(a) { + if (a.charCodeAt(0) > 256) return "ch"; + else return "en"; +} diff --git a/htdocs/imacat/scripts/subscribe.js b/htdocs/imacat/scripts/subscribe.js new file mode 100644 index 0000000..15ce9d6 --- /dev/null +++ b/htdocs/imacat/scripts/subscribe.js @@ -0,0 +1,90 @@ +/* Tavern IMACAT's + * subscribe.js: The mailing list subscription related JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-05-18 + */ + +/* isSubOK: is the subscription request OK? */ +function isSubOK(form) { + // Regularize the fields + form.email.value = trim(form.email.value); + if (form.email.value == "") { + alert(_("Please fill in your subscription e-mail.")); + form.email.focus(); + return false; + } + if (!isEmail(form.email.value)) { + alert(_("This e-mail is malformed. Please fill in a valid one.")); + form.email.focus(); + return false; + } + if (form.pw.value == "") { + alert(_("Please fill in your password.")); + form.pw.focus(); + return false; + } + if (form["pw-conf"].value == "") { + alert(_("Please confirm the password.")); + form["pw-conf"].focus(); + return false; + } + if (form.pw.value != form["pw-conf"].value) { + alert(_("The 2 passwords are different. Please fill in the password again.")); + form.pw.value = ""; + form["pw-conf"].value = ""; + form.pw.focus(); + return false; + } + return true; +} + +/* isInfoOK: is the information request OK? */ +function isInfoOK(form) { + // Regularize the fields + form.email.value = trim(form.email.value); + if (form.email.value == "") { + alert(_("Please fill in your subscription e-mail.")); + form.email.focus(); + return false; + } + if (!isEmail(form.email.value)) { + alert(_("This e-mail is malformed. Please fill in a valid one.")); + form.email.focus(); + return false; + } + return true; +} + +/* isOptionsOK: is the options request OK? */ +function isOptionsOK(form) { + // Regularize the fields + form.email.value = trim(form.email.value); + if (form.email.value == "") { + alert(_("Please fill in your subscription e-mail.")); + form.email.focus(); + return false; + } + if (!isEmail(form.email.value)) { + alert(_("This e-mail is malformed. Please fill in a valid one.")); + form.email.focus(); + return false; + } + return true; +} diff --git a/htdocs/imacat/scripts/writings-en.js b/htdocs/imacat/scripts/writings-en.js new file mode 100644 index 0000000..0b50ac0 --- /dev/null +++ b/htdocs/imacat/scripts/writings-en.js @@ -0,0 +1,33 @@ +/* Tavern IMACAT's + * writings-en.js: The English writings related JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-07-09 + */ + +// Go to a certain page +function goToEntry(file) { + var url, p; + url = window.location.href; + p = url.indexOf("/", 8); + p = url.indexOf("/", p + 1); + url = url.substr(0, p + 1) + file[file.selectedIndex].value; + window.location.href = url; + return; +} diff --git a/htdocs/imacat/scripts/writings-zh.js b/htdocs/imacat/scripts/writings-zh.js new file mode 100644 index 0000000..463a6d4 --- /dev/null +++ b/htdocs/imacat/scripts/writings-zh.js @@ -0,0 +1,33 @@ +/* Tavern IMACAT's + * writings-zh.js: The Chinese writings related JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-07-07 + */ + +// Go to a certain page +function goToEntry(file) { + var url, p; + url = window.location.href; + p = url.indexOf("/", 8); + p = url.indexOf("/", p + 1); + url = url.substr(0, p + 1) + file[file.selectedIndex].value; + window.location.href = url; + return; +} diff --git a/htdocs/imacat/search.ico b/htdocs/imacat/search.ico new file mode 100644 index 0000000..fdb6d70 Binary files /dev/null and b/htdocs/imacat/search.ico differ diff --git a/htdocs/imacat/stylesheets/analog.css b/htdocs/imacat/stylesheets/analog.css new file mode 100644 index 0000000..377bf87 --- /dev/null +++ b/htdocs/imacat/stylesheets/analog.css @@ -0,0 +1,30 @@ +/* Tavern IMACAT's + * analog.css: The style sheet for Analog analysis reports. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-11-11 + */ + +@import url("common.css"); +@import url("home.css"); + +p { + margin: 1em 0; + text-indent: 0; +} diff --git a/htdocs/imacat/stylesheets/common.css b/htdocs/imacat/stylesheets/common.css new file mode 100644 index 0000000..1b9e24c --- /dev/null +++ b/htdocs/imacat/stylesheets/common.css @@ -0,0 +1,1376 @@ +/* Tavern IMACAT's + * common.css: The common style sheet. + */ + +/* Copyright (c) 1999-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 1999-07-25 + */ + +/* General settings */ +body { + margin: 0; + padding: 0.5em 1em; +} +a { + text-decoration: none; +} +a:hover { + text-decoration: underline; +} +.noindent { + text-indent: 0; +} +p { + text-align: justify +} +hr { + clear: both; +} +form { + margin: 0; +} +.note { + font-size: 0.833em; + font-style: italic; +} +q:lang(zh-tw) { + quotes: "「" "」" "『" "』"; +} +q:lang(zh-cn) { + quotes: "※" "§" "&" "*"; +} +q:lang(en) { + quotes: "\201C" "\201D" "\2018" "\2019"; +} +q:lang(ja) { + quotes: "\300C" "\300D" "\300E" "\300F"; +} +cite:lang(zh-tw) { + quotes: "《" "》"; +} +cite:lang(zh-cn) { + quotes: "▲" "◎"; +} +cite:lang(en) { + quotes: "\00AB" "\00BB"; +} +cite.apa { + quotes: "" ""; +} +cite:before { + content: open-quote; +} +cite:after { + content: close-quote; +} +.intro { + margin: 1em 15%; +} +div.errmsg { + margin: 1em 0.5in; +} +/* The CAPTCHA */ +.trwebsite, .trlastname { + display: none; +} + +/* The title */ +.title { + margin: 2em 1em 1em 1em; +} +.title h2 { + background-color: transparent; + color: white; + font-size: 2.7em; + line-height: 0; + margin-top: 0.5em; +} +.title h1 { + background-color: transparent; + color: #FFFF80; + font-size: 5.4em; + line-height: 0.9em; + margin: -0.4em 0 0 0.7em; +} + +/* The navigation bar */ +.navibar, .pagebar, .langs { + text-align: center; + font-size: 0.833em; +} +.navibar .text { + width: 4em; +} +.nav hr { + margin: 0.1em 0; + padding: 0; + height: 0; +} +.navibar span em { + font-weight: normal; + font-style: italic; +} + +/* The footer */ +.footer { + clear: both; + font-size: 0.833em; + text-align: center; +} +.footer p { + margin: 0; + text-indent: 0; + text-align: center; +} +.footer div { + margin: 0.3em 0; +} +.footer img { + border-style: none; + height: 31px; + width: 88px; +} +.footer .modperl img { + height: 30px; + width: 110px; +} +.footer .linkcode { + border: thick ridge silver; + background-color: white; + color: black; + display: table; + font-size: 1em; + margin: 0 auto; + padding: 0.3em 1em; + text-align: left; + width: 10em; +} +.spamtrap { + display: none; +} + +/* The default list */ +.deflist { + margin: 1em 3em; +} +.deflist th { + white-space: nowrap; +} +.deflist th, .deflist td { + padding: 0.2em 0.5em; + vertical-align: top; +} +.deflist td a:link { + background-color: black; + color: yellow; +} +.deflist td a:visited { + background-color: black; + color: #C0C0FF; +} +.deflist td a:active { + background-color: black; + color: #E0E0C0; +} +.deflist td a:hover { + background-color: gray; + color: white; +} +.deflist thead { + background-color: silver; + color: black; +} +.deflist tbody th { + font-weight: normal; +} +.deflist .listno, .deflist .listdel { + text-align: center; +} +.deflist .listno { + text-align: center; +} +.deflist .oddrow { + background-color: white; + color: black; +} +.deflist .evenrow { + background-color: #C0C0FF; + color: black; +} +.deflist .amount { + text-align: right; +} +.deflist .amount .neg { + color: red; + background-color: transparent; +} +.deflist .crdtsubj { + text-indent: 2em; +} +.deflist .subjlv2 { + text-indent: 1em; +} +.deflist .subjlastlv { + text-indent: 2em; +} + +/* the default form */ +.defform { + margin: 0 10%; + width: 100%; +} +/* Refer to http://www.w3.org/Style/threepart-f.css */ +/* The child selectors are a hack to hide these rules from WinIE6 */ +.body>form.defform { + width: auto; +} +.defform table { + margin: 0 auto; + width: 100%; +} +.defform th, .defform td { + text-align: left; + vertical-align: top; +} +.defform .thfile { + width: 9em; +} +.defform .th { + width: 8.5em; +} +.defform .oldnew { + width: 3.5em; +} +.defform td .text, .defform td textarea { + width: 100%; +} +.defform td .prompt { + font-style: italic; + margin: 0; +} +.defform td ol, .defform td li ul { + margin: 0 0 0 2em; + padding: 0; +} +.defform td ul, .defform td li { + margin: 0; + padding: 0; +} +.defform td ul li { + list-style: none; +} +.defform td .oneline li { + display: block; + float: left; + margin-right: 0.5em; +} +.defform td h4, .defform td .picinfo, .defform td .piccap { + margin: 0; + padding: 0; +} +.defform .amount { + text-align: right; +} + +/* The main styles */ +body { + background: black url("../images/bg_cloth.gif"); + color: white; +} +a:link { + background-color: transparent; + color: #FFFF80; +} +a:visited { + background-color: transparent; + color: #C0C0FF; +} +a:active { + background-color: transparent; + color: #E0E0C0; +} +a:hover { + background-color: gray; + color: inherit; +} +.navibar span, .navibar label, .pagebar span, .langs span { + background-color: black; + color: inherit; +} + +/* The Tavern lobby */ +.home .titlearea { + height: 480px; +} +.home .logo { + position: absolute; + top: 1em; + right: 0.5in; + height: 480px; + width: 240px; +} +.home .logo img { + height: 480px; + width: 240px; +} +.home .titletext { + position: absolute; + top: 1em; + left: 0.5in; + height: 480px; +} +.home .title { + height: 320px; +} +.home .title0 { + padding: 40px 0; +} +.home .title p { + font-size: 1.728em; + margin: 0 0 1.5em 0; + font-style: normal; + text-indent: 0; +} +.home .titlenotes { + height: 160px; + font-style: italic; +} +.home .titlenotes .langs { + text-align: left; +} +.home .titlenotes p { + font-size: 1em; + margin: 0; + padding: 0; + text-align: left; + text-indent: 0; +} +.home .nav { + float: left; + padding: 0; + margin: 0 0 1em 0; + text-align: center; + width: 40%; +} +.home .nav .accessguide { + float: none; + text-align: left; + width: 100%; +} +.home .nav .nav1 { + display: table; + margin: 0 auto; + width: 12em; +} +.home .nav p { + text-indent: 0; +} +.home .nav ul { + margin: 0 0 1em 0; + padding: 0 0 0 2em; +} +.home .nav ul li { + text-align: left; + list-style: disc outside url("../images/button.png"); + margin: 0.5em 0 0.5em 0; + padding: 0; +} +.home .nav form .text { + width: 7em; +} +.home .bulletin { + background-color: white; + color: black; + border: thick ridge silver; + float: right; + margin: 0 0 1em 0; + width: 57%; +} +.home .bulletin .bulletin1 { + padding: 0.5em 1em; +} +.home .bulletin h2 { + text-align: center; + margin: 0; +} +.home .bulletin a { + background-color: transparent; + color: blue; + text-decoration: none; +} +.home .bulletin a:visited { + background-color: transparent; + color: navy; + text-decoration: none; +} +.home .bulletin a:hover { + background-color: yellow; + color: inherit; + text-decoration: underline; +} + +/* The Travellers' Guestbook */ +.guestbook .intro address { + font-style: italic; + text-align: right; +} +.guestbook .defform { + margin: 1em 15%; + width: 100%; +} +/* Refer to http://www.w3.org/Style/threepart-f.css */ +/* The child selectors are a hack to hide these rules from WinIE6 */ +.guestbook .body>form.defform { + width: auto; +} +.guestbook .defform p { + text-indent: 0; + margin: 0; +} +.guestbook .defform table { + margin: 0 auto; + width: 100%; +} +.guestbook .defform th { + text-align: left; + vertical-align: top; + width: 7.5em; +} +.guestbook .defform td { + vertical-align: top; +} +.guestbook .defform .text, .guestbook .defform textarea { + font-size: 1em; + width: 100%; +} +.guestbook .entries { + padding: 0 2em; +} +.guestbook .entry { + margin: 1em; +} +.guestbook .entry div { + margin: 1em 0; +} +.guestbook .entry address { + text-align: right; +} +.guestbook .entry address cite { + font-size: 1.44em; + font-style: normal; +} +.guestbook .entry address samp { + font-style: normal; + vertical-align: text-bottom; +} + +/* The Soundless Backalley */ +.garbage { + background: black url("../images/bg_bricks.gif"); + color: white; +} +.garbage a:hover { + background-color: gray; + color: inherit; +} +.garbage .navibar span, .garbage .navibar label, .garbage .pagebar span, .garbage .langs span { + background-color: black; + color: white; +} +.garbage .defform { + margin: 1em 15%; + width: 100%; +} +/* Refer to http://www.w3.org/Style/threepart-f.css */ +/* The child selectors are a hack to hide these rules from WinIE6 */ +.garbage .body>form.defform { + width: auto; +} +.garbage .defform div { + text-align: center; +} +.garbage .defform textarea { + width: 100%; +} +.garbage .entries { + padding: 0 2em; +} +.garbage .entry { + margin: 1em; +} +.garbage .entry div { + margin: 1em 0; +} +.garbage .entry address { + font-style: italic; + text-align: right; +} + +/* The related links */ +.links { + background: #FFD5FF url("../images/bg_pink_triangle.gif") fixed; + color: #400040; +} +.links a:link { + background-color: transparent; + color: #FF00FF; +} +.links a:visited { + background-color: transparent; + color: #C000C0; +} +.links a:active { + background-color: transparent; + color: #800080; +} +.links a:hover { + background-color: white; + color: inherit; +} +.links .navibar span, .links .navibar label, .links .pagebar span, .links .langs span { + background-color: #FFD5FF; + color: #400040; +} +.links .linkslist { + clear: both; + margin: 1em 0.5in; +} +.links .linkslist li { + margin: 1em 0; +} +.links .linkslist li img { + border: 0; + vertical-align: top; +} +.links .linkslist li cite { + font-size: 1.2em; + font-style: normal; +} + +/* The registration form */ +.links .regform { + margin: 1em 10%; + width: 100%; +} +/* Refer to http://www.w3.org/Style/threepart-f.css */ +/* The child selectors are a hack to hide these rules from WinIE6 */ +.links .body>form.regform { + width: auto; +} +.links .regform table { + margin: 0 auto; + width: 100%; +} +.links .regform th { + text-align: left; + vertical-align: top; + width: 8em; +} +.links .regform .text, .links .regform textarea { + width: 100%; +} + +/* My diary */ +.me { + background: white url("../images/bg_bedsheet.gif"); + color: #400020; +} +.me a:link { + background-color: transparent; + color: #FF0080; +} +.me a:visited { + background-color: transparent; + color: #C00060; +} +.me a:active { + background-color: transparent; + color: #800040; +} +.me a:hover { + background-color: #FFE000; + color: inherit; +} +.me h1 { + font-size: 2.7em; +} +.me em { + background-color: transparent; + color: #FF0080; + font-weight: bolder; + font-style: normal; +} +.me .navibar span, .me .navibar label, .me .pagebar span, .me .langs span { + background-color: white; + color: #400020; +} +.me .toc { + list-style: disc outside url("../images/button.png"); + margin: 1em 3em; + padding: 0 0 0 2em; +} +.me .toc li { + margin: 3em 0 0 0; + padding: 0; +} +.me .toc li h3 { + font-size: 1.44em; + margin: 0; +} +.me .portrait { + text-align: center; + float: right; + margin-right: 0.5in; +} +.me .portrait img { + border: thick ridge #FFB000; +} +.me dfn { + font-style: normal; + font-weight: bolder; +} +.me hr { + clear: none; +} +.me .entries { + padding: 0 2em; +} +.me .entry { + padding: 1em; + margin: 1em 0; + border-width: thin thick thick thin; + border-style: solid; + border-color: #400020; + background-color: white; + color: inherit; +} +.me .entry .freetext { + margin: 1em 0 0 0; +} +.me .entry blockquote { + border-width: thin thick thick thin; + border-style: solid; + border-color: #400020; + margin: 1em; + padding: 1em; +} +.me .entry .illus { + margin: 1em 3em; +} +.me .entry .illus img { + vertical-align: top; +} +.me .entry .illus p { + margin: 0; + font-style: italic; + text-indent: 0; +} +.me table caption { + font-size: 1.2em; +} +.me table th, .me table td { + padding: 0.2em 0.5em; +} +.me table th { + background-color: silver; + color: inherit; +} +.me table tbody th { + text-align: left; + white-space: nowrap; +} +.me table td { + background-color: #FFE0E0; + color: inherit; +} +@media screen, print { + .me .entries hr { + display: none; + } +} + +/* My Chinese writings */ +.literalzh { + background: white url("../images/bg_marble.gif") fixed; + color: black; +} +.literalzh a:link { + background-color: transparent; + color: blue; +} +.literalzh a:visited { + background-color: transparent; + color: gray; +} +.literalzh a:active { + background-color: transparent; + color: #80C080; +} +.literalzh a:hover { + background-color: white; + color: inherit; +} +.literalzh .navibar span, .literalzh .navibar label, .literalzh .pagebar span, .literalzh .langs span { + background-color: #E0E0E0; + color: black; +} +.literalzh p.langs { + margin: 0; + text-indent: 0; +} +.literalzh .toc { + float: left; + margin: 0 0 1em 0; + width: 49%; +} +.literalzh .toc h2 { + font-size: 1em; + margin: 0.5em 0 0 0; +} +.literalzh .toc p { + margin: 0; +} +.literalzh .intro { + float: right; + margin: 0 0 1em 0; + width: 49%; +} +.literalzh .intro p { + margin: 0 0 0.5em 0; +} +.literalzh h1 { + font-size: 1em; + font-style: italic; + font-weight: normal; +} +.literalzh .entries { + padding: 0 2em; +} +.literalzh .entry { + margin: 1em; +} +.literalzh .entry h2 { + margin: 0; +} +.literalzh .entry pre { + font-size: 1em; + margin: 0.5em 0; +} +.literalzh .entry p { + margin: 1em 0; +} + +/* My English writings */ +.literalen { + background: #EFE8CF url("../images/bg_linen.gif") fixed; + color: #302810; +} +.literalen a:link { + background-color: transparent; + color: #605020; +} +.literalen a:visited { + background-color: transparent; + color: #907830; +} +.literalen a:active { + background-color: transparent; + color: #C0A040; +} +.literalen a:hover, .literalen a:hover { + background-color: white; + color: inherit; +} +.literalen h1, .literalen h2, .literalen h3, .literalen h4, .literalen h5, .literalen h6 { + font-family: "Monotype Corsiva"; +} +.literalen .navibar span, .literalen .navibar label, .literalen .pagebar span, .literalen .langs span { + background-color: #EFE8CF; + color: #302810; +} +.literalen p.langs { + margin: 0; + text-indent: 0; +} +.literalen h1 { + text-align: center; +} +.literalen .body p { + margin: 0 0 0.5em 0; +} +.literalen .body .foreword { + font-style: italic; + margin: 1em 0.5in; + padding: 0.5em 2em; + border: thick double black; + background-color: #EFE8CF; + color: #302810; +} +.literalen .body .foreword h2 { + margin: 0 0 0.5em 0; +} + +/* The LesTalk mailing list */ +.les { + background: white url("../images/bg_coconut.png"); + color: #202000; +} +.les a:link { + background-color: transparent; + color: #A0A000; +} +.les a:visited { + background-color: transparent; + color: #404000; +} +.les a:active { + background-color: transparent; + color: #606000; +} +.les a:hover { + background-color: yellow; + color: inherit; +} +.les .navibar span, .les .navibar label, .les .pagebar span, .les .langs span { + background-color: #FFFFE0; + color: inherit; +} +.les .body { + margin: 1em 0.5in; +} +.les h1 { + margin-left: 2em; +} + +/* My technical notes */ +.tech { + background: #E0E0FF none; + color: #202000; +} +.tech a:link { + background-color: transparent; + color: blue; +} +.tech a:visited, .tech a:active { + background-color: transparent; + color: navy; +} +.tech a:hover { + background-color: yellow; + color: inherit; +} +.tech .navibar span, .tech .navibar label, .tech .pagebar span, .tech .langs span { + background-color: #F0F0FF; + color: inherit; +} +.tech .body { + margin: 1em 0.5in; +} +.tech h1 { + text-align: center; + clear: none; +} +.tech h2, .tech .body em { + text-transform: uppercase; +} +.tech .sep { + height: 0; + margin: 0; + visibility: hidden; + clear: both; +} +.tech abbr, .tech acronym { + font-size: 1em; +} +.tech .quickref { + background-color: white; + color: inherit; + border: thick double black; + padding: 1em; +} +.tech .helperslist li { + margin-bottom: 1em; +} +.tech .guiitem { + background-color: white; + color: inherit; + border: thin solid silver; + font-family: sans-serif; + line-height: 1.5em; + padding: 0.1em 0.5em; +} +.tech .guiitem kbd { + font-family: sans-serif; + text-decoration: underline; +} +.tech .illustration { + text-align: center; + margin: 0.5em; + line-height: 1.5em; +} + +/* The accounting */ +.acctrepquery p { + margin: 0; + padding: 0; + text-indent: 0; +} +.acctrepquery ul { + margin: 0; + padding: 0 0 0 0; +} +.acctrepquery ul li { + list-style: none; +} + +/* Miscellaneous pages */ +.misc .body { + background-color: white; + color: black; + margin: 1em 0.5in; + padding: 1em; + border: thick ridge silver; +} +.misc .body a:link { + background-color: transparent; + color: blue; +} +.misc .body a:visited, .misc .body a:active { + background-color: transparent; + color: navy; +} +.misc .body a:hover { + background-color: yellow; + color: inherit; +} +.misc h1 { + font-size: 2.4em; + text-align: center; +} + +/* The full text search */ +.searchresult em { + background-color: gray; + color: yellow; +} +.searchresult h3 { + margin: 0; +} +.searchresult li { + margin-bottom: 1em; +} + +/* Magicat */ +.magicat .savedform { + background-color: #C0C0FF; + color: black; + border: thick double white; + padding: 0.5em 1em; +} +.magicat .savedform span { + background-color: white; + color: inherit; +} + +/* The accessibility guides */ +.skiptobody { + position: absolute; + line-height: 0; + left: 0; + top: 0; + z-index: -9; + display: none; +} +.accessguide { + float: left; + font-size: 0.5em; + color: #FFFFFF; +} + +/* The preview mark */ +.previewmark { + position: fixed; + top: 1em; + left: 1em; + border: thick solid red; + color: red; + background-color: transparent; + margin: 0; + padding: 0.5em; +} +.previewmark h2 { + text-transform: uppercase; + text-align: center; + margin: 0; + padding: 0; +} +.previewmark p { + margin: 0; + padding: 0; + text-indent: 0; +} +.previewmark a, .previewmark a:visited, .previewmark a:hover { + color: red; + background-color: transparent; +} +@media print { + .previewmark { + display: none; + } +} + +/* The breadcrumb trail */ +.breadcrumb { + font-size: 1.44em; +} + +/* The split table of contents */ +.splittoc { + width: 90%; + margin: 1em 5%; +} +.tocl { + float: left; + width: 49%; +} +.tocl div { + float: right; +} +.tocl ul { + margin: 0; + padding: 0 0 0 3em; +} +.tocr { + float: right; + width: 49%; +} +.tocr div { + float: left; +} +.tocr ul { + margin: 0; + padding: 0 0 0 3em; +} +.splittoc ul li { + text-align: left; + list-style: disc outside url("../images/button.png"); + margin: 0.5em 0; + padding: 0; +} + +/* Not currently used */ +/* Women's sex */ +.sex { + background: black url("../images/bg_sex.jpg") fixed; + color: white; +} +.sex a:link { + background-color: transparent; + color: red; +} +.sex a:visited { + background-color: transparent; + color: #C00000; +} +.sex a:active { + background-color: transparent; + color: white; +} +.sex a:hover { + background-color: white; + color: inherit; +} +.sex .navibar span, .sex .navibar label, .sex .pagebar span, .sex .langs span { + background-color: #FFD060; + color: white; +} +.sex h1 { + text-align: center; +} +.sex .intro { + float: left; + width: 45%; +} +.sex .topics { + float: right; + width: 45%; +} +.sex .topics h2 { + text-align: center; +} + +/* The Hypertext Playground */ +.playgrnd { + background: white url("../images/bg_marble.gif") fixed; + color: black; +} +.playgrnd a:link { + background-color: transparent; + color: blue; +} +.playgrnd a:visited { + background-color: transparent; + color: gray; +} +.playgrnd a:active { + background-color: transparent; + color: #80C080; +} +.playgrnd a:hover { + background-color: white; + color: inherit; +} +.playgrnd .navibar span, .playgrnd .navibar label, .playgrnd .pagebar span, .playgrnd .langs span { + background-color: #E0E0E0; + color: black; +} +.playgrnd h1 { + background-color: transparent; + color: blue; + text-align: center; +} +.playgrnd .defform td { + vertical-align: top; +} +.playgrnd .defform textarea { + height: 30em; + margin: 1em 10%; + padding: 0; + width: 70%; +} +.playgrnd .result p { + border-color: black; + border-style: solid; + border-width: thin thick thick thin; + background-color: white; + color: black; + margin: 0.5em; + text-indent: 0; +} + +/* The Linux notes */ +.linux { + background: white url("../images/bg_linux.gif") scroll; +} +.linux .body { + margin: 1em 4em; + clear: both; +} +.linux li { + margin-top: 1em; +} +.linux h2 { + margin-top: 1em; +} +.linux blockquote { + margin: 0.5em; +} +.linux dl dt { + font-size: 1em; + font-family: serif; + font-weight: bolder; +} +.linux h1 { + font-size: 2.7em; + margin: 1em 1em 3em 1em; + text-align: center; +} + +/* The curriculum vitae */ +.cv { + background: #E0E0FF none; + color: black; +} +.cv a:link { + background-color: transparent; + color: blue; +} +.cv a:visited, .cv a:active { + background-color: transparent; + color: navy; +} +.cv a:hover { + background-color: yellow; + color: inherit; +} +.cv .navibar span, .cv .navibar label, .cv .pagebar span, .cv .langs span { + background-color: transparent; + color: inherit; +} +.cv .photo { + float: right; +} +.cv h2 { + background-color: white; + color: black; + font-weight: normal; + padding: 0.1em 1em; + border: 1px none; + width: auto; + font-size: 1.44em; + text-transform: uppercase; +} +.cv ul { + margin: 0; + padding: 0 0 0 3.44em; +} +.cv ul li { + margin: 0; + padding: 0; +} +.cv li p { + text-indent: 0; + margin: 0; +} +.cv dl { + margin-left: 1.44em; +} +.cv dt { + font-size: 1.2em; +} +.cv dd { + margin: 0.5em 0 1em 1.2em; + padding: 0; +} +.cv dd ul { + padding-left: 2em; +} +@media print { + .cv .nav, .cv hr, .cv .footer, .cv .accessguide { + display: none; + } + .cv { + background-color: white; + color: black; + } + .cv h2 { + background-color: #E0E0FF; + color: black; + border-color: black; + border-style: solid; + border-width: thin medium medium thin; + page-break-inside: avoid; + } + .cv a:link, .cv a:visited, .cv a:active, .cv a:hover { + background-color: transparent; + color: black; + text-decoration: none; + } + .cv .photo { + background-color: white; + border-color: black; + border-style: solid; + border-width: thin medium medium thin; + padding: 0.1em; + } + .cv abbr, .cv acronym { + border: none; + text-decoration: none; + } +} + +/* The Christmas card */ +.xmas2000 { + background-image: url("../images/bg_redbricks.gif"); + color: white; +} +.xmas2000 h1 { + display: none; +} +.xmas2000 a { + color: white; +} +.xmas2000 a:hover { + background-color: silver; + color: yellow; +} +.xmas2000 .dear { + font-size: 2.0736em; + margin: 0.5em; +} +.xmas2000 .greetings p { + font-size: 6em; + font-weight: bolder; + text-align: center; + text-indent: 0; +} +.xmas2000 .greetings p:lang(en) { + font-size: 4em; +} +.xmas2000 address { + font-size: 1.44em; + font-style: normal; + font-weight: bolder; + margin: 1em 0.5em; + text-align: right; +} +.xmas2000 cite { + font-size: 1.44em; + font-style: normal; +} + +/* The New Year card */ +.ny2001 { + background-image: url("../images/bg_newyear.gif"); + color: white; +} +.ny2001 h1 { + display: none; +} +.ny2001 a { + color: white; +} +.ny2001 a:hover { + background-color: silver; + color: yellow; +} +.ny2001 .dear { + font-size: 2.0736em; + margin: 0.5em; +} +.ny2001 .greetings p { + font-size: 6em; + font-weight: bolder; + text-align: center; + text-indent: 0; +} +.ny2001 .greetings p:lang(en) { + font-size: 4em; +} +.ny2001 address { + font-size: 1.44em; + font-style: normal; + font-weight: bolder; + margin: 1em 0.5em; + text-align: right; +} +.ny2001 cite { + font-size: 1.44em; + font-style: normal; +} + +/* The Plurk avatars */ +.plurkavatar, .plurkavatar img { + width: 195px; + height: 195px; +} +.plurkavatar { + float: left; + margin: 0.5em; + border: thick ridge black; +} diff --git a/htdocs/imacat/stylesheets/ctop.xsl b/htdocs/imacat/stylesheets/ctop.xsl new file mode 100644 index 0000000..853fe74 --- /dev/null +++ b/htdocs/imacat/stylesheets/ctop.xsl @@ -0,0 +1,1318 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + i + + + + + + + / + + + + + + + + + + + + + + + + + + + + + + + + e + + i + + + + + + + + + E + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (-1) + + + + + + + + + + + + + + + + + λ + + . + + + + + + + + + + + + + + + + + + + + +id + + + + +domain + + + + +codomain + + + + +image + + + + + + + + + + +{ + + + + +   if   + + + + + + + + + + + + + +/ + + + + + + + + + + + + + +! + + + + + + + + + / + + + + + + + + + + max + + + + + + + max + + + + + + + + + + + + + + + + + + + + + + + + + + + + ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + mod + + + + + + + + + + + ( + + + + + × + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + +gcd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + xor + + + + + + + +¬ + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + . + + + + + + + + + + +| + +| + + + + + + + + + +¯ + + + + + + arg + + + + + + + + + + + + + + + + lcm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + > + + + + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | + + + + + + + + + + + + + + + d + + + + + + + + + + + + + + + + d + + d + + + + d + d + + + + + + + + + + D + + +, + + + + + + + + + + + + + + + + + ++ + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + +div + + + + +grad + + + + +curl + + + + + +2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +| + +| + + + + + + + + + + × + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + limit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +e + + + + + + + + + + + + +log + + + +log + + + + + + + + + + + + + + + + + + , + + + + + + + + +σ + + + + + + +σ +( + +) + +2 + + + + + + +median + + + + + +mode + + + + + + + + + + + + + + + + + + + + +( + + + + + +) + + + + + + +( + + + +) + + + + + + + + + + + + + + + +det + + + + + + + + +| + + + +| + + + + + + + + + +T + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + +Z + + + + +R + + + + +Q + + + + +N + + + + +C + + + + +P + + + + + e + + + + + i + + + + + NaN + + + + + true + + + + + false + + + + + + + + + + + π + + + + + γ + + + + + + + + + + + + + + + ( + + + + + + + + + ) + + + + + + + + + ( + + + + + + + + ) + + + + + + + + + + + + | + + + + + + , + + + + + + + + + diff --git a/htdocs/imacat/stylesheets/lang.en.css b/htdocs/imacat/stylesheets/lang.en.css new file mode 100644 index 0000000..5382ece --- /dev/null +++ b/htdocs/imacat/stylesheets/lang.en.css @@ -0,0 +1,96 @@ +/* Tavern IMACAT's + * lang.en.css: The style sheet for English pages. + */ + +/* Copyright (c) 2001-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2001-11-04 + */ + +/* General settings */ +body { + font-family: Arial, sans-serif; +} +p { + text-indent: 0.5in; +} +h1, h2, h3, h4, h5, h6, caption, dt { + font-family: "Times New Roman", "Times.New.Roman", times, serif; + font-weight: bolder; +} +q { + quotes: '"' '"' "'" "'"; +} +cite { + quotes: "\00AB" "\00BB"; +} +ol { + margin: 0; + padding: 0 0 0 0.5in; +} +ol > li { + list-style: decimal; +} + +/* The title */ +.title h2 { + font-family: Arial, sans-serif; +} +.title h1 { + font-family: "Viner Hand ITC", "Viner.Hand.ITC", "Monotype Corsiva", "Monotype.Corsiva", cursive; +} +.title p { + font-family: "Monotype Corsiva", "Monotype.Corsiva", cursive; + font-weight: bolder; +} +.me h1, .me h2, .me h3, .me .breadcrumb { + font-family: "Comic Sans MS", "Comic.Sans.MS", fantasy; +} +.les h1, .les h2, .les h3, .les h4, .les h5, .les h6 { + font-family: "Comic Sans MS", "Comic.Sans.MS", fantasy; +} + +/* The breadcrumb trail */ +.links .breadcrumb { + font-family: "Times New Roman", "Times.New.Roman", times, serif; + font-weight: bolder; +} + +/* The Travellers' Book */ +.guestbook .entry address { + font-family: "Times New Roman", "Times.New.Roman", times, serif; +} +.guestbook .entry address cite { + font-family: "Viner Hand ITC", "Viner.Hand.ITC", "Monotype Corsiva", "Monotype.Corsiva", cursive; +} + +/* The Soundless Backalley */ +.garbage .entry address { + font-family: "Times New Roman", "Times.New.Roman", times, serif; +} + +/* The related links */ +.links .linkslist li cite { + font-family: "Times New Roman", "Times.New.Roman", times, serif; + font-weight: bolder; +} + +/* Not currently used */ +/* The curriculum vitae */ +.cv h1, .cv h2 { + font-family: Arial, sans-serif; +} diff --git a/htdocs/imacat/stylesheets/lang.zh-cn.css b/htdocs/imacat/stylesheets/lang.zh-cn.css new file mode 100644 index 0000000..392a756 --- /dev/null +++ b/htdocs/imacat/stylesheets/lang.zh-cn.css @@ -0,0 +1,145 @@ +/* Tavern IMACAT's + * lang.zh-cn.css: The style sheet for Chinese (China) pages. + */ + +/* Copyright (c) 2001-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2001-11-04 + */ + +/* General settings */ +p { + text-indent: 2em; +} +h1, h2, h3, h4, h5, h6, caption, dt { + font-family: "楷体_GB2312", KaiTi_GB2312, "KaiTi GB2312", kai, serif; + font-weight: normal; +} +q { + quotes: "“" "”" "‘" "’"; +} +cite { + quotes: "《" "》"; +} +ol { + margin: 0; + padding: 0 0 0 2em; +} +ol > li { + list-style: cjk-ideographic; +} +em { + font-weight: bolder; + font-style: normal; +} + +/* The contents in other languages */ +:lang(en) { + font-family: Arial, sans-serif; +} +h1:lang(en), h2:lang(en), h3:lang(en), h4:lang(en), h5:lang(en), h6:lang(en), caption:lang(en), dt:lang(en), h1 :lang(en), h2 :lang(en), h3 :lang(en), h4 :lang(en), h5 :lang(en), h6 :lang(en), caption :lang(en), dt :lang(en) { + font-family: "Times New Roman", "Times.New.Roman", times, serif; + font-weight: bolder; +} +samp:lang(en), pre:lang(en), code:lang(en), samp :lang(en), pre :lang(en), code :lang(en) { + font-family: monospace; +} +.me h1 :lang(zh-cn), .me h2 :lang(zh-cn), .me h3 :lang(zh-cn), .me h4 :lang(zh-cn), .me h5 :lang(zh-cn), .me h6 :lang(zh-cn), .me caption :lang(zh-cn), .me dt :lang(zh-cn) { + font-family: "楷体_GB2312", KaiTi_GB2312, "KaiTi GB2312", kai, fantasy; + font-weight: normal; +} + +/* The title */ +.title h2 { + font-family: "黑体", SimHei, sans-serif; +} +.title h1 { + font-family: "仿宋_GB2312", FangSong_GB2312, "FangSong GB2312", kai, cursive; +} +.title p { + font-family: "仿宋_GB2312", FangSong_GB2312, "FangSong GB2312", kai, cursive; +} +.me h1, .me h2, .me h3, .me .breadcrumb { + font-family: "楷体_GB2312", KaiTi_GB2312, "KaiTi GB2312", kai, fantasy; +} +.les h1, .les h2, .les h3, .les h4, .les h5, .les h6 { + font-family: "楷体_GB2312", KaiTi_GB2312, "KaiTi GB2312", kai, fantasy; +} + +/* The breadcrumb trail */ +.links .breadcrumb { + font-family: "楷体_GB2312", KaiTi_GB2312, "KaiTi GB2312", kai, serif; +} + +/* The Travellers' Guestbook */ +.guestbook .entry address { + font-family: "楷体_GB2312", KaiTi_GB2312, "KaiTi GB2312", kai, serif; +} +.guestbook .entry address cite { + font-family: "仿宋_GB2312", FangSong_GB2312, "FangSong GB2312", kai, cursive; + quotes: none; +} +.guestbook .entry address :lang(en) { + font-family: "Times New Roman", "Times.New.Roman", times, serif; +} + +/* The Soundless Backalley */ +.garbage .entry address:lang(en) { + font-family: "Times New Roman", "Times.New.Roman", times, serif; +} + +/* Keep travelling */ +.links .linkslist li cite { + font-family: "楷体_GB2312", KaiTi_GB2312, "KaiTi GB2312", kai, serif; + quotes: none; +} +.links .linkslist li cite :lang(en) { + font-family: "Times New Roman", "Times.New.Roman", times, serif; + font-weight: bolder; +} + +/* My Chinese writings */ +.literalzh .toc h2 { + font-family: "宋体", SimSun, serif; +} +.literalzh h1 { + font-family: "宋体", SimSun, serif; +} + +/* Not currently used */ +/* The Linux notes */ +.linux h1 { + font-family: "仿宋_GB2312", FangSong_GB2312, "FangSong GB2312", kai, cursive; +} +/* The curriculum vitae */ +.cv h1, .cv h2 { + font-family: "楷体_GB2312", KaiTi_GB2312, "KaiTi GB2312", kai, serif; +} +/* The Christmas card */ +.xmas2000 .body { + font-family: "黑体", SimHei, fantasy; +} +.xmas2000 .body :lang(en) { + font-family: "Comic Sans MS", "Comic.Sans.MS", fantasy; +} +/* The New Year card */ +.ny2001 .body { + font-family: "楷体_GB2312", KaiTi_GB2312, "KaiTi GB2312", kai, serif; +} +.ny2001 .body :lang(en) { + font-family: "Monotype Corsiva", "Monotype.Corsiva", cursive; +} diff --git a/htdocs/imacat/stylesheets/lang.zh-tw.css b/htdocs/imacat/stylesheets/lang.zh-tw.css new file mode 100644 index 0000000..67a2546 --- /dev/null +++ b/htdocs/imacat/stylesheets/lang.zh-tw.css @@ -0,0 +1,146 @@ +/* Tavern IMACAT's + * lang.zh-tw.css: The style sheet for Chinese (Taiwan) pages. + */ + +/* Copyright (c) 2001-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2001-11-04 + */ + +/* General settings */ +p { + text-indent: 2em; +} +h1, h2, h3, h4, h5, h6, caption, dt { + font-family: "標楷體", DFKai-SB, "DFKai SB", "AR PL UKai TW", kai, serif; + font-weight: normal; +} +q { + quotes: "「" "」" "『" "』"; +} +cite { + quotes: "《" "》"; +} +ol { + margin: 0; + padding: 0 0 0 2em; +} +ol > li { + list-style: cjk-ideographic; +} +em { + font-weight: bolder; + font-style: normal; +} + +/* The contents in other languages */ +:lang(en) { + font-family: Arial, sans-serif; +} +h1:lang(en), h2:lang(en), h3:lang(en), h4:lang(en), h5:lang(en), h6:lang(en), caption:lang(en), dt:lang(en), h1 :lang(en), h2 :lang(en), h3 :lang(en), h4 :lang(en), h5 :lang(en), h6 :lang(en), caption :lang(en), dt :lang(en) { + font-family: "Times New Roman", "Times.New.Roman", times, serif; + font-weight: bolder; +} +samp:lang(en), pre:lang(en), code:lang(en), samp :lang(en), pre :lang(en), code :lang(en) { + font-family: monospace; +} +.me h1 :lang(zh-tw), .me h2 :lang(zh-tw), .me h3 :lang(zh-tw), .me h4 :lang(zh-tw), .me h5 :lang(zh-tw), .me h6 :lang(zh-tw), .me caption :lang(zh-tw), .me dt :lang(zh-tw) { + font-family: "華康少女文字W5(P)", DFPGirlW5-B5, "DFPGirlW5 B5", "華康儷特圓(P)", DFPLiYuan-XB, "DFPLiYuan XB", "華康新特圓體(P)", DFPNYuanXBold-B5, "DFPNYuanXBold B5", fantasy; + font-weight: normal; +} + +/* The title */ +.title h2 { + font-family: "華康新儷粗黑", "DFLiHeiBold(P)", "華康儷粗黑(P)", DFPLiHei-BD, "DFPLiHei BD", "華康超黑體(P)", DFPHeiUBold-B5, "DFPHeiUBold B5", "文泉驛正黑", "WenQuanYi Zen Hei", sans-serif; +} +.title h1 { + font-family: "華康瘦金體(P)", DFPSoZing-B5, "DFPSoZing B5", "華康仿宋體W4(P)", DFPFangSongW4-B5, "DFPFangSongW4 B5", "標楷體", DFKai-SB, "DFKai SB", "AR PL UKai TW", kai, cursive; +} +.title p { + font-family: "華康行書體(P)", DFXingShu-B5, "DFXingShu B5", "標楷體", DFKai-SB, "DFKai SB", "AR PL UKai TW", kai, cursive; +} +.me h1, .me h2, .me h3, .me .breadcrumb { + font-family: "華康少女文字W5(P)", DFPGirlW5-B5, "DFPGirlW5 B5", "華康儷特圓(P)", DFPLiYuan-XB, "DFPLiYuan XB", "華康新特圓體(P)", DFPNYuanXBold-B5, "DFPNYuanXBold B5", fantasy; +} +.les h1, .les h2, .les h3, .les h4, .les h5, .les h6 { + font-family: "華康少女文字W5(P)", DFPGirlW5-B5, "DFPGirlW5 B5", "華康儷特圓(P)", DFPLiYuan-XB, "DFPLiYuan XB", "華康新特圓體(P)", DFPNYuanXBold-B5, "DFPNYuanXBold B5", fantasy; +} + +/* The breadcrumb trail */ +.links .breadcrumb { + font-family: "標楷體", DFKai-SB, "DFKai SB", "AR PL UKai TW", kai, serif; + font-weight: normal; +} + +/* The Travellers' Guestbook */ +.guestbook .entry address { + font-family: "標楷體", DFKai-SB, "DFKai SB", "AR PL UKai TW", kai, serif; +} +.guestbook .entry address cite { + font-family: "華康瘦金體(P)", DFPSoZing-B5, "DFPSoZing B5", "華康仿宋體W4(P)", DFPFangSongW4-B5, "DFPFangSongW4 B5", "標楷體", DFKai-SB, "DFKai SB", "AR PL UKai TW", kai, cursive; + quotes: none; +} +.guestbook .entry address :lang(en) { + font-family: "Times New Roman", "Times.New.Roman", times, serif; +} + +/* The Soundless Backalley */ +.garbage .entry address:lang(en) { + font-family: "Times New Roman", "Times.New.Roman", times, serif; +} + +/* The related links */ +.links .linkslist li cite { + font-family: "標楷體", DFKai-SB, "DFKai SB", "AR PL UKai TW", kai, serif; + quotes: none; +} +.links .linkslist li cite :lang(en) { + font-family: "Times New Roman", "Times.New.Roman", times, serif; + font-weight: bolder; +} + +/* My Chinese writings */ +.literalzh .toc h2 { + font-family: "新細明體", PMingLiu, serif; +} +.literalzh h1 { + font-family: "新細明體", PMingLiu, serif; +} + +/* Not currently used */ +/* The Linux notes */ +.linux h1 { + font-family: "華康瘦金體(P)", DFPSoZing-B5, "DFPSoZing B5", "華康仿宋體W4(P)", DFPFangSongW4-B5, "DFPFangSongW4 B5", "標楷體", DFKai-SB, "DFKai SB", "AR PL UKai TW", kai, cursive; +} +/* The curriculum vitae */ +.cv h1, .cv h2 { + font-family: "標楷體", DFKai-SB, "DFKai SB", "AR PL UKai TW", kai, serif; +} +/* The Christmas card */ +.xmas2000 .body { + font-family: "華康少女文字W5(P)", DFPGirlW5-B5, "DFPGirlW5 B5", "華康儷特圓(P)", DFPLiYuan-XB, "DFPLiYuan XB", "華康新特圓體(P)", DFPNYuanXBold-B5, "DFPNYuanXBold B5", fantasy; +} +.xmas2000 .body :lang(en) { + font-family: "Comic Sans MS", "Comic.Sans.MS", fantasy; +} +/* The New Year card */ +.ny2001 .body { + font-family: "華康隸書體W5(P)", DFLiShuW5-B5, "DFLiShuW5 B5", "標楷體", DFKai-SB, "DFKai SB", "AR PL UKai TW", kai, serif; +} +.ny2001 .body :lang(en) { + font-family: "Monotype Corsiva", "Monotype.Corsiva", cursive; +} diff --git a/htdocs/imacat/stylesheets/local.xsl b/htdocs/imacat/stylesheets/local.xsl new file mode 100644 index 0000000..83ab7e5 --- /dev/null +++ b/htdocs/imacat/stylesheets/local.xsl @@ -0,0 +1,203 @@ + + + + + + + + + + + / + + + + + + + + + + + + + + + + ( + + + + + ) + + + + + + + ÷ + + + + + + + + + + + + + + + + + + + + + + + + + ( + + + + + + + + + + + ) + + + + + + + + + ( + + + × + + + + + + + + ) + + + + + + + + + ( + + + × + + + + + + + + ) + + + + + + + + ( + + + + + + + + + + + + + + + + ) + + + + + + + + ( + + + + + + + + + + + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + += + + + + + diff --git a/htdocs/imacat/stylesheets/mathml.xsl b/htdocs/imacat/stylesheets/mathml.xsl new file mode 100644 index 0000000..6dc7c64 --- /dev/null +++ b/htdocs/imacat/stylesheets/mathml.xsl @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/htdocs/imacat/stylesheets/pmathml.xsl b/htdocs/imacat/stylesheets/pmathml.xsl new file mode 100644 index 0000000..97012f1 --- /dev/null +++ b/htdocs/imacat/stylesheets/pmathml.xsl @@ -0,0 +1,612 @@ + + + + + + + + + + '<!--' + + + + + + + + + + + + + + + + + + + + + + + + +in mpdialog mode, we just write out some JavaScript to display +dialog to the reader asking whether they want to install MathPlayer +Depending on the response we get, we then instantiate an XSL processor +and reprocess the doc, passing $secondpass according to the +reader response. + +Using d-o-e is fairly horrible, but this code is only for IE +anyway, and we need to force HTML semantics in this case. + + +var cookieName = "MathPlayerInstall="; +function MPInstall(){ + var showDialog=true; + var c = document.cookie; + var i = c.indexOf(cookieName); + if (i >= 0) { + if ( c.substr(i + cookieName.length, 1) >= 2) { showDialog=false; } + } + if (showDialog) { + MPDialog(); + c = document.cookie; + i = c.indexOf(cookieName); + } + if (i >= 0) return c.substr(i + cookieName.length, 1); + else return null; +} + +function MPDialog() { + var vArgs=""; + var sFeatures="dialogWidth:410px;dialogHeight:190px;help:off;status:no"; + var text = ""; + text += "javascript:document.write('" + text += '<script>' + text += 'function fnClose(v) { ' + text += 'var exp = new Date();' + text += 'var thirtyDays = exp.getTime() + (30 * 24 * 60 * 60 * 1000);' + text += 'exp.setTime(thirtyDays);' + text += 'var cookieProps = ";expires=" + exp.toGMTString();' + text += 'if (document.forms[0].dontask.checked) v+=2;' + text += 'document.cookie="' + cookieName + '"+v+cookieProps;' + text += 'window.close();' + text += '}' + text += '</' + 'script>' + text += '<head><title>Install MathPlayer?</title></head>' + text += '<body bgcolor="#D4D0C8"><form>' + text += '<table cellpadding=10 style="font-family:Arial;font-size:10pt" border=0 width=100%>' + text += '<tr><td align=left>This page requires Design Science\\\'s MathPlayer&trade;.<br>' + text += 'Do you want to download and install MathPlayer?</td></tr>'; + text += '<tr><td align=center><input type="checkbox" name="dontask">' + text += 'Don\\\'t ask me again</td></tr>' + text += '<tr><td align=center><input id=yes type="button" value=" Yes "' + text += ' onClick="fnClose(1)">&nbsp;&nbsp;&nbsp;' + text += '<input type="button" value=" No " onClick="fnClose(0)"></td></tr>' + text += '</table></form>'; + text += '</body>' + text += "')" + window.showModalDialog( text , vArgs, sFeatures ); +} + +function WaitDialog() { + var vArgs=""; + var sFeatures="dialogWidth:510px;dialogHeight:150px;help:off;status:no"; + var text = ""; + text += "javascript:document.write('" + text += '<script>' + text += 'window.onload=fnLoad;' + text += 'function fnLoad() {document.forms[0].yes.focus();}' + text += 'function fnClose(v) { ' + text += 'window.returnValue=v;' + text += 'window.close();' + text += '}' + text += '</' + 'script>' + text += '<head><title>Wait for Installation?</title></head>' + text += '<body bgcolor="#D4D0C8" onload="fnLoad()"><form><' + text += 'table cellpadding=10 style="font-family:Arial;font-size:10pt" border=0 width=100%>' + text += '<tr><td align=left>Click OK once MathPlayer is installed ' + text += 'to refresh the page.<br>' + text += 'Click Cancel to view the page immediately without MathPlayer.</td></tr>'; + text += '<tr><td align=center><input id=yes type="button" ' + text += 'value=" OK " onClick="fnClose(1)">&nbsp;&nbsp;&nbsp;' + text += '<input type="button" value="Cancel" onClick="fnClose(0)"></td></tr>' + text += '</table></form>'; + text += '</body>' + text += "')" + return window.showModalDialog( text , vArgs, sFeatures ); +} + +var result = MPInstall(); + +var action = "fallthrough"; +if (result == 1 || result == 3) { + window.open("http://www.dessci.com/webmath/mathplayer"); + var wait = WaitDialog(); + if ( wait == 1) { + action = "install"; + document.location.reload(); + + } +} +if (action == "fallthrough") { +var xsl = new ActiveXObject("Microsoft.FreeThreadedXMLDOM"); +xsl.async = false; +xsl.validateOnParse = false; +xsl.load("pmathmlcss.xsl"); +var xslTemplate = new ActiveXObject("MSXML2.XSLTemplate.3.0"); +xslTemplate.stylesheet=xsl.documentElement; +var xslProc = xslTemplate.createProcessor(); +xslProc.input = document.XMLDocument; + +xslProc.transform(); +var str = xslProc.output; + +var repl = "replace"; +if (window.navigator.appVersion.match(/Windows NT 5.1/)) { repl = ""; } +var newDoc = document.open("text/html", repl); +newDoc.write(str); +document.close(); +} + + +mathplayer-dl + +techexplorer-plugin + + + + + + + + techexplorer-plugin + + + + + mathplayer-dl + + + + + + + + + + + + +IE5 hacks +This code will be ignored by an XSLT engine as a top level +element in a foreign namespace. It will be executed by an IE5XSL +engine and insert <!-- into the output stream, ie the start of a +comment. This will comment out all the XSLT code which will be copied +to the output. A similar clause below will close this comment, it is +then followed by the IE5XSL templates to be executed. +This trick is due to Jonathan Marsh of Microsoft, and used in +the stylesheet for +the XPath 2 data model draft. + + +XSLT stylesheet +MSXSL script block + +The following script block implements an extension function that +tests whether a specified ActiveX component is known to the client. +This is used below to test for the existence of MathML rendering +components. + + function isinstalled(ax) + { + try { + var ActiveX = new ActiveXObject(ax); + return "true"; + } catch (e) { + return "false"; + } +} + + +The main bulk of this stylesheet is an identity transformation so... + + + + + + + + + +XHTML elements are copied sans prefix (XHTML is default namespace +here, so these elements will still be in XHTML namespace + + + + + + + +IE's treatment of XHTML as HTML needs a little help here... + + + + + + > + + + + + + + + + + +This just ensures the mathml prefix declaration isn't copied from +the source at this stage, so that the system will use the mml prefix +coming from this stylesheet + + + + + + + +We modify the head element to add code to specify a Microsoft +"Behaviour" if the behaviour component is known to the system. +Test for MathPlayer (Design Science) +Test for Techexplorer (IBM) +Test for Microsoft. In this case we just +output a small HTML file that executes a script that will re-process +the source docuument with a different stylesheet. Doing things this +way avoids the need to xsl:import the second stylesheet, which would +very much increase the processing overhead of running this +stylesheet. +Further tests (eg for netscape/mozilla) could +be added here if necessary + + + + + + + + + + namespace="mml" implementation="#mmlFactory" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Somewhat bizarrely in an otherwise namespace aware system, +Microsoft behaviours are defined to trigger off the +prefix not the Namespace. In the code above +we associated a MathML rendering behaviour (if one was found) with the +prefix mml: so here we ensure that this is the prefix +that actually gets used in the output. + + + + + + + +Copy semantics element through in IE (so mathplayer gets to see +mathplayer annotations, otherwise use first child or a presentation annotation. + + + + + + + + + + + + + + + + + + + + + + + + > + + + + + + + + + /> + + + + + + " + + + + + + " + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +IE5XSL stylesheet +In a rare fit of sympathy for users of +the-language-known-as-XSL-in-IE5 this file incorporates a +version of the above code designed to work in the Microsoft dialect. +This is needed otherwise users of a MathML rendering behaviour would +have to make a choice whether they wanted to use this stylesheet +(keeping their source documents conforming XHTML+MathML) or to use +the explicit Microsoft Object code, which is less portable, but would +work in at least IE5.5. + +This entire section of code, down to the end of the stylesheet is +contained within this ie5:if. Thus XSLT sees it as a top level element +from a foreign namespace and silently ignores it. IE5XSL sees it as +"if true" and so executes the code. + + +First close the comment started at the beginning. This ensures +that the bulk of the XSLT code, while being copied to the result tree +by the IE5XSL engine, will not be rendered in the browser. + +Lacking attribute value templates in +xsl:element, and the local-name() function, we resort to constructing +the start and end tags in strings in javascript, then using +no-entities attribute which is the IE5XSL equivalent of disable-output-encoding + + +'-->' + + + + + + function mpisinstalled() + { + try { + var ActiveX = new ActiveXObject("MathPlayer.Factory.1"); + return "true"; + } catch (e) { + return "false"; + } +} + + + + + + + + + + + + + + + + + + + + +'<mml:' + this.nodeName.substring(this.nodeName.indexOf(":")+1) + +' ' + this.nodeName="" + +'>' + +'</mml:' + this.nodeName.substring(this.nodeName.indexOf(":")+1) + '>' + + + + + + + +'<math>' + +'</math>' + + + + +'<mml:' + this.nodeName.substring(this.nodeName.indexOf(":")+1) + +' ' + this.nodeName="" + +'>' + +'</mml:' + this.nodeName.substring(this.nodeName.indexOf(":")+1) + '>' + + + + + + + + + + + namespace="mml" implementation="#mmlFactory" + + + + + + + + + + + + + + + + + diff --git a/htdocs/imacat/stylesheets/v403.css b/htdocs/imacat/stylesheets/v403.css new file mode 100644 index 0000000..63822a2 --- /dev/null +++ b/htdocs/imacat/stylesheets/v403.css @@ -0,0 +1,151 @@ +/* Tavern IMACAT's + * v403.css: The style sheet for the NOU computer network v403 class mailing list. + */ + +/* Copyright (c) 2004-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2004-04-27 + */ + +/* General settings */ +body { + background-color: #F0FFF0; + color: black; + margin: 0; + padding: 0; +} +.body { + padding: 1em; +} +.body1 { + margin: 0.5em 0.5in; +} +a:link { + background-color: transparent; + color: red; + text-decoration: none; +} +a:visited { + background-color: transparent; + color: maroon; + text-decoration: none; +} +a:active { + background-color: transparent; + color: #400000; + text-decoration: none; +} +a:hover { + background-color: #FFD700; + color: inherit; + text-decoration: underline; +} +h1, h2, h3, h4, h5, h6 { + font-family: "標楷體",cursive,serif; + font-weight: normal; +} +h1 { + text-align: center; +} +h2 { + background-color: #C0FFC0; + padding: 0.1em 1em; +} +p { + text-indent: 2em; +} +hr { + clear: both; +} +form { + margin: 0; +} +em { + font-style: normal; + font-weight: bolder; +} +q { + quotes: "「" "」" "『" "』"; +} + +/* navigation bar 瀏覽列 */ +.nav { + padding: 0.5em 0; + border-top: thin ridge silver; + border-bottom: thin ridge silver; + clear: both; +} + +/* Accessibility Guide 導盲磚 */ +.skiptobody { + position: absolute; + line-height: 0; + left: 0; + top: 0; + z-index: -9; +} +.accessguide { + float: left; + font-size: 0.5em; + color: #FFFFFF; +} + +/* 頁尾 */ +.footer { + padding: 0.5em 0; + text-align: center; + clear: both; +} +.footer p { + font-size: 0.833em; + margin: 0; + text-indent: 0; +} +.footer img { + border-style: none; +} + +/* 通訊選項 */ +#subscriber { + font-family: Arial, sans-serif; + text-align: center; + font-size: 1.44em; +} +#mlopts th { + background-color: white; + color: inherit; + font-weight: normal; + text-align: left; + vertical-align: middle; + padding: 0.5em 1em; +} +#mlopts td { + background-color: #FFE0E0; + color: inherit; + text-align: left; + vertical-align: middle; + white-space: nowrap; + padding: 0.5em 1em; +} +#mlopts th h3 { + margin: 0 0 0.5em 0; + padding: 0; +} +#mlopts th p { + margin: 0; + padding: 0; +} diff --git a/htdocs/imacat/tech/browlang.html.en.html b/htdocs/imacat/tech/browlang.html.en.html new file mode 120000 index 0000000..65febcd --- /dev/null +++ b/htdocs/imacat/tech/browlang.html.en.html @@ -0,0 +1 @@ +browlang.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/browlang.html.en.xhtml b/htdocs/imacat/tech/browlang.html.en.xhtml new file mode 100644 index 0000000..8743dac --- /dev/null +++ b/htdocs/imacat/tech/browlang.html.en.xhtml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + +How to Set Up Your Browsing Language? + + + + + + + +
    + +
    + + +

    How to Set Up Your Browsing Language?

    + +

    Table of Contents

    + +
      +
    1. Prefix
    2. +
    3. Firefox
    4. +
    5. Mozilla
    6. +
    7. Internet Explorer
    8. +
    9. Opera 6
    10. +
    + + +

    Prefix

    + +

    Currently 3 languages are supported by Tavern: Traditional Chinese, Simplified Chinese and English. It will choose appropriate language version according to your settings. If all these 3 languages are not in your system default, and if you don’t know how to set your preferred language, you’ll be asked to choose a language for every page you visited. Also, if the system default preferred language is not your preferred one, you’ll have to switch to your preferred language for every page.

    + +

    The detailed steps to set your preferred language are described below.

    + + +

    Mozilla

    + +

    From the top toolbar of Mozilla, select (E)ditPr(e)ferences, to pop up a Preferences window. Double-click the Browser from the Category on the left, will open a submenu. Click the Language option in that submenu. It will pop up an Add New Languages window. Add all the languages you like, such as Chinese (Taiwan) [zh-tw], Chinese (China) [zh-cn], English [en], Japanese [ja]. Remember to add the English, so that English is displayed when no appropriate language is available on some websites.

    + +

    Click(U)p or(D)own to adjust your preference order. When you surf the web, websites will check your preferred languages in order, and if one language is available, it will show that language.

    + +

    If you are using WINDOWS 2000/Me/XP, you can install the necessary fonts for the languages from the control panel. If you are not, you can start the Internet Explorer and go to Windows Update, to install the language supports you need. Mozilla will choose the appropriate fonts automatically.

    + + +

    Internet Explorer

    + +

    Start your Internet Explorer. From the Tools on the top toolbar, choose Internet Options.... In the popped-up Internet Options window, click the General at the top to move to the General page. Click the Languages... at the bottom. It will pop up a Language Preferences window. Click Add... to pop up an Add Language window. Choose the languages you can read from the Language: list, such as Chinese (Taiwan) [zh-tw], Chinese (China) [zh-cn], English [en], Japanese [ja], etc. Don’t forget to add the English [en] as a last fallback if all your preferred languages are not available on the website. Then click OK to add them.

    + +

    You could choose a language from the Language: list in the Language Preferences window, and click Move Up or Move Down to change its preference order. When you surf the web, the websites may check the preferred languages in order, and send the first available language version of the same content.

    + +

    If you are using WINDOWS 2000/Me/XP, you could install the necessary fonts for the languages from the Control Panel. If not, you could go to Windows Update, to install the specific language supports.

    + + +

    Opera 6

    + +

    Start your Opera. From the File on the top toolbar, choose Preferences.... In the popped-up window titled Preferences, choose the Languages at the left. In the Web pages at the right, click Add... to pop up an Accept Language window. Choose the language you can read from the list under Select Web language in language, such as Chinese (Taiwan) [zh-tw], Chinese (China) [zh-cn], English [en], Japanese [ja], etc., and click OK to add it. Don’t forget to add the English [en] as a last fallback if all your preferred languages are not available on the website.

    + +

    You could choose a language from the list under Preferred languages for Web pages in Web pages in the Preferences window, and click Move up or Move down to change its preference order. When you surf the web, the websites may check the preferred languages in order, and send the first available language version of the same content.

    + +

    If you are using WINDOWS 2000/Me/XP, you could install the necessary fonts for the languages from the Control Panel. If not, you could go to Windows Update, to install the specific language supports.

    + +
    by imacat, first written 2001-12-22, last updated 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/browlang.html.zh-cn.html b/htdocs/imacat/tech/browlang.html.zh-cn.html new file mode 120000 index 0000000..a594595 --- /dev/null +++ b/htdocs/imacat/tech/browlang.html.zh-cn.html @@ -0,0 +1 @@ +browlang.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/browlang.html.zh-cn.xhtml b/htdocs/imacat/tech/browlang.html.zh-cn.xhtml new file mode 100644 index 0000000..308b01e --- /dev/null +++ b/htdocs/imacat/tech/browlang.html.zh-cn.xhtml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + +如何设定上网的语言? + + + + + + + +
    + +
    + + +

    如何设定上网的语言?

    + +

    目录

    + +
      +
    1. 前言
    2. +
    3. Firefox
    4. +
    5. Mozilla
    6. +
    7. Internet Explorer 6
    8. +
    9. Internet Explorer 5
    10. +
    11. Opera 6
    12. +
    + + +

    前言

    + +

    旅舍目前支援下列三种语言:正体中文、简体中文、英文,并且会按照你设定的语言优先顺序,秀出适合的语言译本。若你浏览器预设的语言,不是你习惯的语言,那你连上每一页,都要切到自己习惯的语言,很不方便。

    + +

    以下,就是设定上网浏览时,语言优先顺序的方法。

    + + +

    Firefox

    + +

    启动 Firefox 后,由工具列上的 工具(T)选项(O)... 按下去,会打开一个 选项 的视窗。在左边的选择 一般 ,右边中间有一区 语言 ,点选右边的 语言(L)... 按钮,打开 内容语言与字元编码 的视窗。在中间 选择要加入的语言(S)... 的清单中,选出所有你会的语言,像 中文/台湾 [zh-tw]中文/中国大陆 [zh-cn]英文 [en]日文 [ja] 等等。记得一定要加上 英文 [en] ,这样网站内文没有你会的语言的时候,至少会显示英文。然后按 确定

    + +

    你可以在 依下面的顺序搜寻可用的语言 的清单上,选择一种语言,然后按右边的 上移(U)下移(D) ,调整语言的优先顺序。浏览时,网站可以按你的优先顺序一一检查,秀出最优先的语言翻译版。

    + +

    若你是在 WINDOWS 2000/Me/XP 上,你可以直接从系统安装各种语言的所需的字型。若不是,你可以打开 Internet Explorer ,连上 Windows Update ,安装所需的语言支援,如日文支援等。 Firefox 会自动选择适合该语言的字型。

    + + +

    Mozilla

    + +

    启动 Mozilla 后,由工具列上的 编辑(E)个人功能设定 按下去,会打开一个 功能设定 的视窗。在左边的 分类 中选择 网页浏览器 下的 语言设定 。如果 网页浏览器 左边的箭头朝右,看不到语言设定 ,在那个右箭头上按一下,就看得到了。按一下右边 网页所使用的语言 右下角的 新增... ,打开 新增语言 的视窗。在 语言: 的清单中,选出所有你会的语言,像 中文/台湾 [zh-tw]中文/中国大陆 [zh-cn]英文 [en]日文 [ja] 等等。记得一定要加上 英文 [en] ,这样网站内文没有你会的语言的时候,至少会显示英文。然后按 确定

    + +

    你可以在 网页所使用的语言 中,列在 偏好语言设定 下的清单上,选择一种语言,然后按右边的 上移(U)下移(D) ,调整语言的优先顺序。浏览时,网站可以按你的优先顺序一一检查,秀出最优先的语言翻译版。

    + +

    若你是在 WINDOWS 2000/Me/XP 上,你可以直接从系统安装各种语言的所需的字型。若不是,你可以打开 Internet Explorer ,连上 Windows Update ,安装所需的语言支援,如日文支援等。 Mozilla 会自动选择适合该语言的字型。

    + + +

    Internet Explorer 6

    + +

    启动 Internet Explorer 后,由工具列上的 工具(T)网际网路选项(O)... 按下去,会打开一个 网际网路选项 的视窗。按一下上方的 一般 ,翻到 一般 那一页。按一下下面的 语言(L)... ,打开 语言喜好设定 的视窗。按一下右边的 新增(A)... ,在打开的 新增语言 视窗, 语言(L): 下的清单中,选出所有你会的语言,像 中文 (台湾) [zh-tw]中文 (中国) [zh-cn]英文 [en]日文 [ja] 等等。记得一定要加上 英文 [en] ,这样网站内文没有你会的语言的时候,至少会显示英文。然后按 确定

    + +

    你可以在 语言喜好设定 的视窗中,列在 语言(L): 下的清单上,选择一种语言,然后按然后按右边的 上移(U)下移(D) ,调整语言的优先顺序。浏览时,网站可以按你的优先顺序一一检查,秀出最优先的语言翻译版。

    + +

    若你是在 WINDOWS 2000/Me/XP 上,你可以直接从系统安装各种语言的所需的字型。若不是,你可以打开 Internet Explorer ,连上 Windows Update ,安装所需的语言支援,如日文支援等。

    + + +

    Internet Explorer 5

    + +

    启动 Internet Explorer 后,由工具列上的 工具(T)Internet 选项(O)... 按下去,会打开一个 Internet 选项 的视窗。按一下上方的 一般 ,翻到 一般 那一页。按一下下面的 语言(L)... ,打开 语言设定 的视窗。按一下右边的 新增(A)... ,在打开的 新增语言 视窗, 语言(L): 下的清单中,选出所有你会的语言,像 中文 (台湾) [zh-tw]中文 (中国) [zh-cn]英文 [en]日文 [ja] 等等。记得一定要加上 英文 [en] ,这样网站内文没有你会的语言的时候,至少会显示英文。然后按 确定

    + +

    你可以在 语言设定 的视窗中,列在 语言(L): 下的清单上,选择一种语言,然后按然后按右边的 上移(U)下移(D) ,调整语言的优先顺序。浏览时,网站可以按你的优先顺序一一检查,秀出最优先的语言翻译版。

    + +

    若你是在 WINDOWS 2000/Me/XP 上,你可以直接从系统安装各种语言的所需的字型。若不是,你可以打开 Internet Explorer ,连上 Windows Update ,安装所需的语言支援,如日文支援等。

    + + +

    Opera 6

    + +

    启动 Opera 后,由工具列上的 档案(F)功能设定(R)... 按下去,会打开一个 功能设定 的视窗。在左边选择 语系 。在右边的 网页 中,按一下 新增(A)... ,打开 接受语系 的视窗。在 语系选择网页语系(S) 下的清单中,选出你会的语言,像 Chinese (Taiwan) [zh-tw]Chinese (China) [zh-cn]English [en]Japanese [ja] 等,然后按 确定 。记得一定要加上英文 [en] ,这样网站内文没有你会的语言的时候,至少会显示英文。

    + +

    你可以在 功能设定 视窗中,列在 网页 里的 选择检视网页要优先使用的语系(P) 下的清单上,选择一种语言,然后按然后按右边的 向上移(U)向下移(D) ,调整语言的优先顺序。浏览时,网站可以按你的优先顺序一一检查,秀出最优先的语言翻译版。

    + +

    若你是在 WINDOWS 2000/Me/XP 上,你可以直接从系统安装各种语言的所需的字型。若不是,你可以打开 Internet Explorer ,连上 Windows Update ,安装所需的语言支援,如日文支援等。

    + +
    依玛猫,初稿 2001-12-22 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/browlang.html.zh-tw.html b/htdocs/imacat/tech/browlang.html.zh-tw.html new file mode 120000 index 0000000..d94b446 --- /dev/null +++ b/htdocs/imacat/tech/browlang.html.zh-tw.html @@ -0,0 +1 @@ +browlang.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/browlang.html.zh-tw.xhtml b/htdocs/imacat/tech/browlang.html.zh-tw.xhtml new file mode 100644 index 0000000..bbc9600 --- /dev/null +++ b/htdocs/imacat/tech/browlang.html.zh-tw.xhtml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + +如何設定上網的語言? + + + + + + + +
    + +
    + + +

    如何設定上網的語言?

    + +

    目錄

    + +
      +
    1. 前言
    2. +
    3. Firefox
    4. +
    5. Mozilla
    6. +
    7. Internet Explorer 6
    8. +
    9. Internet Explorer 5
    10. +
    11. Opera 6
    12. +
    + + +

    前言

    + +

    旅舍目前支援下列三種語言:正體中文、簡體中文、英文,並且會按照妳設定的語言優先順序,秀出適合的語言譯本。若妳瀏覽器預設的語言,不是妳習慣的語言,那妳連上每一頁,都要切到自己習慣的語言,很不方便。

    + +

    以下,就是設定上網瀏覽時,語言優先順序的方法。

    + + +

    Firefox

    + +

    啟動 Firefox 後,由工具列上的 工具(T)選項(O)... 按下去,會打開一個 選項 的視窗。在左邊的選擇 一般 ,右邊中間有一區 語言 ,點選右邊的 語言(L)... 按鈕,打開 內容語言與字元編碼 的視窗。在中間 選擇要加入的語言(S)... 的清單中,選出所有妳會的語言,像 中文/台灣 [zh-tw]中文/中國大陸 [zh-cn]英文 [en]日文 [ja] 等等。記得一定要加上 英文 [en] ,這樣網站內文沒有妳會的語言的時候,至少會顯示英文。然後按 確定

    + +

    妳可以在 依下面的順序搜尋可用的語言 的清單上,選擇一種語言,然後按右邊的 上移(U)下移(D) ,調整語言的優先順序。瀏覽時,網站可以按妳的優先順序一一檢查,秀出最優先的語言翻譯版。

    + +

    若妳是在 WINDOWS 2000/Me/XP 上,妳可以直接從系統安裝各種語言的所需的字型。若不是,妳可以打開 Internet Explorer ,連上 Windows Update ,安裝所需的語言支援,如日文支援等。 Firefox 會自動選擇適合該語言的字型。

    + + +

    Mozilla

    + +

    啟動 Mozilla 後,由工具列上的 編輯(E)個人功能設定 按下去,會打開一個 功能設定 的視窗。在左邊的 分類 中選擇 網頁瀏覽器 下的 語言設定 。如果 網頁瀏覽器 左邊的箭頭朝右,看不到語言設定 ,在那個右箭頭上按一下,就看得到了。按一下右邊 網頁所使用的語言 右下角的 新增... ,打開 新增語言 的視窗。在 語言: 的清單中,選出所有妳會的語言,像 中文/台灣 [zh-tw]中文/中國大陸 [zh-cn]英文 [en]日文 [ja] 等等。記得一定要加上 英文 [en] ,這樣網站內文沒有妳會的語言的時候,至少會顯示英文。然後按 確定

    + +

    妳可以在 網頁所使用的語言 中,列在 偏好語言設定 下的清單上,選擇一種語言,然後按右邊的 上移(U)下移(D) ,調整語言的優先順序。瀏覽時,網站可以按妳的優先順序一一檢查,秀出最優先的語言翻譯版。

    + +

    若妳是在 WINDOWS 2000/Me/XP 上,妳可以直接從系統安裝各種語言的所需的字型。若不是,妳可以打開 Internet Explorer ,連上 Windows Update ,安裝所需的語言支援,如日文支援等。 Mozilla 會自動選擇適合該語言的字型。

    + + +

    Internet Explorer 6

    + +

    啟動 Internet Explorer 後,由工具列上的 工具(T)網際網路選項(O)... 按下去,會打開一個 網際網路選項 的視窗。按一下上方的 一般 ,翻到 一般 那一頁。按一下下面的 語言(L)... ,打開 語言喜好設定 的視窗。按一下右邊的 新增(A)... ,在打開的 新增語言 視窗, 語言(L): 下的清單中,選出所有妳會的語言,像 中文 (台灣) [zh-tw]中文 (中國) [zh-cn]英文 [en]日文 [ja] 等等。記得一定要加上 英文 [en] ,這樣網站內文沒有妳會的語言的時候,至少會顯示英文。然後按 確定

    + +

    妳可以在 語言喜好設定 的視窗中,列在 語言(L): 下的清單上,選擇一種語言,然後按然後按右邊的 上移(U)下移(D) ,調整語言的優先順序。瀏覽時,網站可以按妳的優先順序一一檢查,秀出最優先的語言翻譯版。

    + +

    若妳是在 WINDOWS 2000/Me/XP 上,妳可以直接從系統安裝各種語言的所需的字型。若不是,妳可以打開 Internet Explorer ,連上 Windows Update ,安裝所需的語言支援,如日文支援等。

    + + +

    Internet Explorer 5

    + +

    啟動 Internet Explorer 後,由工具列上的 工具(T)Internet 選項(O)... 按下去,會打開一個 Internet 選項 的視窗。按一下上方的 一般 ,翻到 一般 那一頁。按一下下面的 語言(L)... ,打開 語言設定 的視窗。按一下右邊的 新增(A)... ,在打開的 新增語言 視窗, 語言(L): 下的清單中,選出所有妳會的語言,像 中文 (台灣) [zh-tw]中文 (中國) [zh-cn]英文 [en]日文 [ja] 等等。記得一定要加上 英文 [en] ,這樣網站內文沒有妳會的語言的時候,至少會顯示英文。然後按 確定

    + +

    妳可以在 語言設定 的視窗中,列在 語言(L): 下的清單上,選擇一種語言,然後按然後按右邊的 上移(U)下移(D) ,調整語言的優先順序。瀏覽時,網站可以按妳的優先順序一一檢查,秀出最優先的語言翻譯版。

    + +

    若妳是在 WINDOWS 2000/Me/XP 上,妳可以直接從系統安裝各種語言的所需的字型。若不是,妳可以打開 Internet Explorer ,連上 Windows Update ,安裝所需的語言支援,如日文支援等。

    + + +

    Opera 6

    + +

    啟動 Opera 後,由工具列上的 檔案(F)功能設定(R)... 按下去,會打開一個 功能設定 的視窗。在左邊選擇 語系 。在右邊的 網頁 中,按一下 新增(A)... ,打開 接受語系 的視窗。在 語系選擇網頁語系(S) 下的清單中,選出妳會的語言,像 Chinese (Taiwan) [zh-tw]Chinese (China) [zh-cn]English [en]Japanese [ja] 等,然後按 確定 。記得一定要加上英文 [en] ,這樣網站內文沒有妳會的語言的時候,至少會顯示英文。

    + +

    妳可以在 功能設定 視窗中,列在 網頁 裏的 選擇檢視網頁要優先使用的語系(P) 下的清單上,選擇一種語言,然後按然後按右邊的 向上移(U)向下移(D) ,調整語言的優先順序。瀏覽時,網站可以按妳的優先順序一一檢查,秀出最優先的語言翻譯版。

    + +

    若妳是在 WINDOWS 2000/Me/XP 上,妳可以直接從系統安裝各種語言的所需的字型。若不是,妳可以打開 Internet Explorer ,連上 Windows Update ,安裝所需的語言支援,如日文支援等。

    + +
    依瑪貓,初稿 2001-12-22 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/buildooo.html.zh-cn.html b/htdocs/imacat/tech/buildooo.html.zh-cn.html new file mode 120000 index 0000000..08c81a9 --- /dev/null +++ b/htdocs/imacat/tech/buildooo.html.zh-cn.html @@ -0,0 +1 @@ +buildooo.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/buildooo.html.zh-cn.xhtml b/htdocs/imacat/tech/buildooo.html.zh-cn.xhtml new file mode 100644 index 0000000..629ebc9 --- /dev/null +++ b/htdocs/imacat/tech/buildooo.html.zh-cn.xhtml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + +如何由最新原始码编译 OpenOffice.org ? + + + + + + + +
    + +
    + + +

    如何由最新原始码编译 OpenOffice.org ?

    + +

    念书准备考试中,临时写一写,有空再补完说明。内容如果有误或不足,欢迎随时补充。

    + +

    版权所有 © 2011 依玛猫。本文采用创用 CC 姓名标示-相同方式分享 3.0 台湾授权条款授权。

    + +

    参考资料:Getting the source

    + +

    完整步骤

    + +
    # 下载
    +sudo apt-get install mercurial
    +mkdir /usr/local/src/openoffice.org
    +cd /usr/local/src/openoffice.org
    +wget -N http://hg.services.openoffice.org/bundle/DEV300.hg
    +hg init
    +hg unbundle DEV300.hg
    +hg pull http://hg.services.openoffice.org/DEV300
    +hg update
    +
    +# 下载外部辅助程式
    +mkdir -p external/unowinreg
    +cd external/unowinreg
    +wget -N http://tools.openoffice.org/unowinreg_prebuild/680/unowinreg.dll
    +cd ../..
    +
    +mkdir -p moz/download
    +cd moz/download
    +wget -N http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.11/source/seamonkey-2.0.11.source.tar.bz2
    +cd ../..
    +
    +# 编译
    +sudo apt-get install ant bison flex gcj gperf java-gcj-compat-dev \
    +  junit4 libarchive-zip-perl libcupsys2-dev libgnome-vfsmm-2.6-dev \
    +  libgstreamer-plugins-base0.10-dev libgtk2.0-dev libpam0g-dev \
    +  libxaw7-dev openjdk-6-jdk zip
    +./configure --with-lang=zh-TW
    +. ./bootstrap
    +cd instsetoo_native
    +../solenv/bin/build.pl --all -P2 -- -P2
    +cd ..
    +
    +# 安装
    +cd instsetoo_native/unxlngx6.pro/OpenOffice/deb/install/zh-TW/DEBS
    +sudo dpkg -i *.deb desktop-integration/*.deb
    +cd ../../../../../../..
    +cd instsetoo_native/unxlngx6.pro/OpenOffice_SDK/deb/install/en-US/DEBS
    +sudo dpkg -i *.deb
    +cd ../../../../../../..
    + +

    注意事项

    + +
      +
    1. 硬碟约需 15G( DEV300.hg 1G ,编译好约 11.4G ),在飞龙四核上编译约需一小时。
    2. + +
    3. hg 是 OpenOffice.org 用的版本管理系统 Mercurial 的程式。
    4. + +
    5. ./configure 不用设 --prefix ,设了也没用。安装目录写死固定在 /opt/openoffice.org3/opt/openoffice.org
    6. + +
    7. 不要用 make 。因为历史因素, OpenOffice.org 用 build.pl 编译。
    8. + +
    9. 编译好不用 make install.deb 安装档在 instsetoo_native/unxlngx6.pro/OpenOffice/deb/install/zh-TW/DEBS 下, SDKinstsetoo_native/unxlngx6.pro/OpenOffice_SDK/deb/install/en-US/DEBS 下。 unxlngx6.pro 是我的 x86_64 ,不同的 CPU/OS 会用不同字串。如果是 Fedora/openSUSE ,应该会换成 RPM ,待测。
    10. + +
    11. 编译出来的是最新原始码的不稳定开发版本,请勿在production环境中使用。
    12. + +
    13. Windows 的编译法待测。
    14. +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/buildooo.html.zh-tw.html b/htdocs/imacat/tech/buildooo.html.zh-tw.html new file mode 120000 index 0000000..c888e3c --- /dev/null +++ b/htdocs/imacat/tech/buildooo.html.zh-tw.html @@ -0,0 +1 @@ +buildooo.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/buildooo.html.zh-tw.xhtml b/htdocs/imacat/tech/buildooo.html.zh-tw.xhtml new file mode 100644 index 0000000..657f59e --- /dev/null +++ b/htdocs/imacat/tech/buildooo.html.zh-tw.xhtml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + +如何由最新原始碼編譯 OpenOffice.org ? + + + + + + + +
    + +
    + + +

    如何由最新原始碼編譯 OpenOffice.org ?

    + +

    唸書準備考試中,臨時寫一寫,有空再補完說明。內容如果有誤或不足,歡迎隨時補充。

    + +

    版權所有 © 2011 依瑪貓。本文採用創用 CC 姓名標示-相同方式分享 3.0 台灣授權條款授權。

    + +

    參考資料:Getting the source

    + +

    完整步驟

    + +
    # 下載
    +sudo apt-get install mercurial
    +mkdir /usr/local/src/openoffice.org
    +cd /usr/local/src/openoffice.org
    +wget -N http://hg.services.openoffice.org/bundle/DEV300.hg
    +hg init
    +hg unbundle DEV300.hg
    +hg pull http://hg.services.openoffice.org/DEV300
    +hg update
    +
    +# 下載外部輔助程式
    +mkdir -p external/unowinreg
    +cd external/unowinreg
    +wget -N http://tools.openoffice.org/unowinreg_prebuild/680/unowinreg.dll
    +cd ../..
    +
    +mkdir -p moz/download
    +cd moz/download
    +wget -N http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.11/source/seamonkey-2.0.11.source.tar.bz2
    +cd ../..
    +
    +# 編譯
    +sudo apt-get install ant bison flex gcj gperf java-gcj-compat-dev \
    +  junit4 libarchive-zip-perl libcupsys2-dev libgnome-vfsmm-2.6-dev \
    +  libgstreamer-plugins-base0.10-dev libgtk2.0-dev libpam0g-dev \
    +  libxaw7-dev openjdk-6-jdk zip
    +./configure --with-lang=zh-TW
    +. ./bootstrap
    +cd instsetoo_native
    +../solenv/bin/build.pl --all -P2 -- -P2
    +cd ..
    +
    +# 安裝
    +cd instsetoo_native/unxlngx6.pro/OpenOffice/deb/install/zh-TW/DEBS
    +sudo dpkg -i *.deb desktop-integration/*.deb
    +cd ../../../../../../..
    +cd instsetoo_native/unxlngx6.pro/OpenOffice_SDK/deb/install/en-US/DEBS
    +sudo dpkg -i *.deb
    +cd ../../../../../../..
    + +

    注意事項

    + +
      +
    1. 硬碟約需 15G( DEV300.hg 1G ,編譯好約 11.4G ),在飛龍四核上編譯約需一小時。
    2. + +
    3. hg 是 OpenOffice.org 用的版本管理系統 Mercurial 的程式。
    4. + +
    5. ./configure 不用設 --prefix ,設了也沒用。安裝目錄寫死固定在 /opt/openoffice.org3/opt/openoffice.org
    6. + +
    7. 不要用 make 。因為歷史因素, OpenOffice.org 用 build.pl 編譯。
    8. + +
    9. 編譯好不用 make install.deb 安裝檔在 instsetoo_native/unxlngx6.pro/OpenOffice/deb/install/zh-TW/DEBS 下, SDKinstsetoo_native/unxlngx6.pro/OpenOffice_SDK/deb/install/en-US/DEBS 下。 unxlngx6.pro 是我的 x86_64 ,不同的 CPU/OS 會用不同字串。如果是 Fedora/openSUSE ,應該會換成 RPM ,待測。
    10. + +
    11. 編譯出來的是最新原始碼的不穩定開發版本,請勿在production環境中使用。
    12. + +
    13. Windows 的編譯法待測。
    14. +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/cookies.html.en.html b/htdocs/imacat/tech/cookies.html.en.html new file mode 120000 index 0000000..ac967fb --- /dev/null +++ b/htdocs/imacat/tech/cookies.html.en.html @@ -0,0 +1 @@ +cookies.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/cookies.html.en.xhtml b/htdocs/imacat/tech/cookies.html.en.xhtml new file mode 100644 index 0000000..eb081bf --- /dev/null +++ b/htdocs/imacat/tech/cookies.html.en.xhtml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + +How to Set Up Cookies? + + + + + + + +
    + +
    + + +

    How to Set Up Cookies?

    + +

    Table of Contents

    + +
      +
    1. Prefix
    2. +
    3. Mozilla
    4. +
    5. Internet Explorer 6
    6. +
    7. Internet Explorer 5
    8. +
    9. Internet Explorer 4 or earlier
    10. +
    11. Netscape
    12. +
    13. Opera 6
    14. +
    + + +

    Prefix

    + +

    The web HTTP connection is itself unreliable. It disconnects as soon as it finished transferring a page. If you wish to read another page on the same website, it has to reconnect again. Because of that, it’s almost impossible for a website to know if some connections came from the same person or not. But, for the web membership systems like web mails, it has to know if you are the same one that logged in minutes ago, in order to open the right mailbox or provide other services correctly. In order to solve this, Netscape had invented a method called cookies. Cookies are some pieces of infomation that are saved on the users’ computers in order to retrieve later, so that the website can know that these connections came from the same person. However, cookies have still other applications. They can keep your real name, telephone number, address, credit card number, ID number and password when you bought something and submit them onto a website once, and allow the website to retrieve them freely afterwards. Another application is that, they can record each address you browsed on a website, like a secret monitor. Moreover, if an advertiser buys advertisements on all the major websites, they can analyse all the data they gathered from these major websites, and build a complete tracking record of everyone, including the exact time and address of all the places one has been. A monitor of everybody on the internet.

    + +

    Horrifying, eh?

    + +

    The problem of cookies is a dilemma: Without cookies, it’s almost impossible for the websites to recognize who you are, and thus employ the membership systems. On the other hand, with cookies, websites can monitor each of your movement, and record some private infomation without your notice.

    + +

    In order to solve this problem, the internet standard organization World Wide Web Consortium (W3C) had established the Platform for Privacy Preferences (P3P). According to P3P, websites have to state their cookie policy both in a clear document and in a format that’s known by the browsers. Users can set their cookie acceptance in advance. When browsing a website, browsers can compare the users’ settings with the websites’ statement, and decide if it shall accept the cookies or not. This sounds wonderful, but practically speaking it is nonsense. P3P itself is a lie. Websites can state anything they like, and save your real name, telephone number, address, credit card number, the time and address where you have been, in an encrypted format that browsers can never tell. Technology can not solve the problem of human dishonesty. It’s not surprising that P3P was established mainly by the major commercial websites and advertisers. It’s, after all, only a trick to cheat the users.

    + +

    In order to really solve the problem of cookies, you have to understand the working method of cookies: When a website sets a cookie, it can specify an expiration date. If a cookie is set without an expiration date, it is called session cookie, which is only valid in this session. It exists temporarily in the browser memory, and disappears whenever the browser exits. If, on the contrary, a cookie is set with an expiration date, it will stay on your computer until it expires. Note that, however, there’s no limit how websites can set the expiration date of its cookies. They can set the expiration date to 50 or 100 years, which means they nearly never expire. They could retrieve these cookies anytime in the future.

    + +

    Another way of categorizing cookies, is to seperate them into first party cookies and third party cookies: First party cookies are those sent from the website that you are browsing. Third party cookies are those sent from the websites of the files referred by the page you are browsing, mostly are advertisements.

    + +

    Technically speaking, only session cookies are necessary to set up membership systems. It only needs to remember who you are when your browser is working. It doesn’t have to record anything anymore when your browser closes. Also, you only need the cookie of the website whose membership system you are using. You don’t need the cookies of other websites. You should accept only the temporary cookies from the same website, and reject all the persistent cookies and third party cookies. Then, no matter what they record in their cookies, these infomation will disappear whenever the browser exists. They have no way at all to retrieve them in the future.

    + +

    Older browsers have only 3 options with cookies: Accept all, reject all, or ask you one by one. We cannot reject all the cookies, but we don’t want to accept all of them, too. However, it will become extremely annoying if the browser asks us one by one, since cookies are employed all over the internet now. Modern browsers have more options: You could turn off persistent cookies and third party cookies explicitly. However, because the venders of the major browsers are of the same interests of the major commercial websites and advertisers, the default settings of most of these browsers are always set to accept all the cookies. You have to turn them off manually by yourself.

    + + +

    Mozilla

    + +

    Start your Mozilla. From the Edit on the top toolbar, choose Preferences.... In the popped-up window titled Preferences, choose the Cookies below the Privacy & Security in the Category at the left. If you don’t see the Cookies and there’s a right arrow precede the Privacy & Security, click on the right arrow to display it. Choose the Enable cookies based on privacy levels in the Cookie Acceptance Policy at the right, and click the View Privacy Levels next to it. It will pop up a window titled Privacy Levels. Choose custom in Level of Privacy. In Cookie Acceptance Policy (a function of Level of Privacy), choose Session on all the options below the First Party Cookies, and choose Reject on all the options below the Third Party Cookies. Click OK. Also, check the Limit maximum lifetime of cookie to option and choose current session below. Click OK. That’s all.

    + + +

    Internet Explorer 6

    + +

    Start your Internet Explorer. From the Tools on the top toolbar, choose Internet Options.... In the popped-up Internet Options window, click the Privacy at the top to move to the Privacy page. Click the Advanced.. in the Settings. It will pop up an Advanced Privacy Settings window. In Cookies, check the Override automatic cookie handling option. Choose Block in First-party Cookies, and choose Block in Third-party Cookies. Then check the Always allow session cookies option. Click OK, OK. That’s all.

    + + +

    Internet Explorer 5

    + +

    Start your Internet Explorer. From the Tools on the top toolbar, choose Internet Options.... In the popped-up Internet Options window, click the Security at the top to move to the Security page. Click the Custom Level... at the bottom. It will pop up a Security Settings window. Scroll down in the Settings list to fine a category named Cookies. Choose Disable in Allow cookies that are stored on your computer, and choose Enable in Allow per-session cookies (not stored). Click OK, OK. That’s all.

    + + +

    Internet Explorer 4 and earlier

    + +

    Internet Explorer 4 and earlier versions can only set to accept all, reject all or ask you one by one. You cannot configure it delicately.

    + + +

    Netscape

    + +

    Netscape all versions can only set to accept all, reject all or ask you one by one. You cannot configure it delicately.

    + + +

    Opera 6

    + +

    Start your Opera. From the File on the top toolbar, choose Preferences.... In the popped-up window titled Preferences, choose the Privacy at the left. In the Cookies at the right, check the Enable cookies, choose the Automatically accept all cookies at the first option below, choose the Do not accept third party cookies at the second one, and check the Throw away new cookies on exit. Click OK. That’s all.

    + + +
    by imacat, first written 2002-01-13, last updated 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/cookies.html.zh-cn.html b/htdocs/imacat/tech/cookies.html.zh-cn.html new file mode 120000 index 0000000..6b34b20 --- /dev/null +++ b/htdocs/imacat/tech/cookies.html.zh-cn.html @@ -0,0 +1 @@ +cookies.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/cookies.html.zh-cn.xhtml b/htdocs/imacat/tech/cookies.html.zh-cn.xhtml new file mode 100644 index 0000000..c45c819 --- /dev/null +++ b/htdocs/imacat/tech/cookies.html.zh-cn.xhtml @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + +如何设定 Cookies ? + + + + + + + +
    + +
    + + +

    如何设定 Cookies ?

    + +

    目录

    + +
      +
    1. 前言
    2. +
    3. Mozilla
    4. +
    5. Internet Explorer 6
    6. +
    7. Internet Explorer 5
    8. +
    9. Internet Explorer 4 及更早的版本
    10. +
    11. Netscape
    12. +
    13. Opera 6
    14. +
    + + +

    前言

    + +

    Web 使用的 HTTP 通讯协定,是很不稳定的。只要网页读完,网站和读者两边就断线了,下次要连到别页,两边要再重新连线一次。所以,对网站来说,很难知道几次连上来的人,是不是同一个人。可是,像 Web 邮件等会员制的程式,一定要想办法确认连上来的人,和之前登入输入帐号密码的,是同一个人,才知道要打开谁的信箱。为此, Netscape 发明了 Cookies ,能够让网站在读者的电脑上存一些资料,可供随时参考,确认几次连上来的人是不是同一个人。不过, Cookies 也可以拿来做很多用途,例如把你上次连上来网路订购的时候,所填的姓名、电话、地址、身份证字号、信用卡号码、密码等等记下来,以便日后随时调阅。另一种常见的用法,是把你连上本站的每一页网址都记下来,随时调阅,像侧录监听一样。如果是广告商,在很多大型网站上刊登广告,就可以把各大网站侧录到的资料综合起来,做成全世界每个人每天上网的完整记录,详细记载每个人的上网时间,连到哪里,看了哪些东西等等,就像在你的网路线上装针孔一样。

    + +

    很可怕,对吧?

    + +

    Cookies 是个两难的问题:没有 Cookies ,网站分不清你是谁,就没办法做会员系统这类复杂的程式;有 Cookies ,网站可以监视你的一举一动,并偷偷录下你的各种资料。

    + +

    Cookies 的问题,全球资讯网联盟 W3C 定了一套叫 P3P 的标准,要求网站把自己的 Cookies 作法以白纸黑字写清楚,用 P3P 格式传给浏览器。读者可以设好自己的 Cookies 接收标准,让浏览器拿来和网站的作法比较,决定要不要收网站的 Cookies 。这个方法听起来不错,不过不要相信这个方法P3P 是骗人的,因为网站怎么作,都是它自己在说,事实上它在你的电脑存了什么东西,电话、地址、信用卡号码、看每一页的时间网址记录等等,它都可以编成乱码后再存,浏览器也分不出来。网站诚不诚实是人的问题,浏览器程式再怎么设计,也没有办法解决。 P3P 是几家大商业网站和广告商一起制定的,只是哄哄读者,让读者安心的技俩而已。

    + +

    要真正解决 Cookies 的问题,要深入了解 Cookies :网站在你电脑上设 Cookies 时,可以设定一个效期。要是没设效期,叫做暂时性的 Session Cookies ,浏览器只会暂时记著,不会存档,只要浏览器关掉,就会消失。否则,要是有设效期, Cookies 会一直存在电脑上,直到过了效期,才会删掉。不过,效期没有限制,网站可以设成五十年一百年,那几乎就不会过期,网站可以随时调阅。

    + +

    另外, Cookies 还分第一方和第三方的两种:第一方 Cookies 是指你要连上的网站自己发的 Cookies ,第三方是指你连上的网站,上面显示了其它网站上的图,这些其她网站发的 Cookies ,多半是广告商的 Cookies

    + +

    其实,会员系统只需要暂时性的 Cookies ,在浏览器开著的时候,记得你是谁就可以了,关掉浏览器后,就不用一直记著你的资料。而且,我们连上一个网站会员系统,只需要那个网站的 Cookies ,不需要别人的 Cookies 。我们可以不收长期的 Cookies ,也不收第三方的 Cookies ,只收原来网站暂时性的 Cookies 就好。这样,就算在你的 Cookies 里记下什么东西,只要关掉浏览器就没了,对方也无从调阅起。

    + +

    比较旧的浏览器,对 Cookies 只有三种选择:完全不用,完全接收,或是见一个问一个。我们既不可能完全不用,也不希望照单全收,如果见一个问一个,现在 Cookies 那么多,也会把自己烦死。新的浏览器,会有比较多的选择,可以关掉长期的 Cookies 和第三方的 Cookies ,不过,因为大多数的浏览器公司,和这些广告商及商业网站是利益共同体,所以大多数浏览器的预设,都会把 Cookies 完全打开,你要自己手动去关起来。

    + +

    以下,说明如何在自己的浏览器上设定 Cookies

    + + +

    Mozilla

    + +

    启动 Mozilla 后,由工具列上的 编辑(E)个人功能设定 按下去,会打开一个 功能设定 的视窗。在左边的 分类 中选择 个人及安全设定 下的 Cookies 。如果 个人及安全设定 左边的箭头朝右,看不到 Cookies ,在那个右箭头上按一下,就看得到了。在右边的 Cookies 接受原则 中,选择 使用自动根据个人隐私安全等级设定 cookies ,并按一下左边的 检视个人隐私安全等级(V) ,打开 个人隐私安全等级 的视窗。在 个人隐私安全等级 中选择 自订 ,并在下面的 Cookies 设定 中, First Party Cookies 下面全部选 SessionThird Party Cookies 下面全部选 拒绝 。然 确定确定 。这样就好了。

    + + +

    Internet Explorer 6

    + +

    启动 Internet Explorer 后,由工具列上的 工具(T)网际网路选项(O)... 按下去,会打开一个 网际网路选项 的视窗。按一下上方的 隐私权 ,翻到 隐私权 那一页,再按一下 设定值 区块下面的 进阶(V)... ,打开 进阶隐私设定 的视窗。在 Cookie 区块里, 覆写自动 Cookie 处理(O) 的选项上打勾,在 第一方 Cookies 下面选 封锁(B) ,在 第三方 Cookies 下面也选 封锁(B) ,然后在下面的 自动允许工作阶段 cookies(W) 上打勾。然后按 确定确定 。这样就好了。

    + + +

    Internet Explorer 5

    + +

    启动 Internet Explorer 后,由工具列上的 工具(T)Internet 选项(O)... 按下去,会打开一个 Internet 选项 的视窗。按一下上方的 安全性 ,翻到 安全性 那一页。按一下下面的 自订层级(C) ,开启 安全性设定 的视窗。在 设定(S): 中往下拉到 Cookies 的地方,在 允许每一阶段的 cookies (未储存) 的地方选 启动 ,在 允许除存在您电脑上的 cookies 的地方选 关闭 。然后按 确定确定 。这样就好了。

    + + +

    Internet Explorer 4 及更早的版本

    + +

    Internet Explorer 4 及更早的版本只能设成全部拒绝,全部接收,或见一个问一个,无法作细部设定。

    + + +

    Netscape

    + +

    Netscape 的所有版本只能设成全部拒绝,全部接收,或见一个问一个,无法作细部设定。

    + + +

    Opera 6

    + +

    启动 Opera 后,由工具列上的 档案(F)功能设定(R)... 按下去,会打开一个功能设定 的视窗。在左边选择 隐私 。在右边的 Cookies(K) 中,在 启动cookie(C) 上打勾,下面第一个选单选 自动接受所有cookie ,第二个选单选 不接受第三者的cookie ,再勾选下面的 离开时删除cookie(X) 。然后按 确定 。这样就好了。

    + + +
    依玛猫,初稿 2002-01-13 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/cookies.html.zh-tw.html b/htdocs/imacat/tech/cookies.html.zh-tw.html new file mode 120000 index 0000000..88b0bbe --- /dev/null +++ b/htdocs/imacat/tech/cookies.html.zh-tw.html @@ -0,0 +1 @@ +cookies.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/cookies.html.zh-tw.xhtml b/htdocs/imacat/tech/cookies.html.zh-tw.xhtml new file mode 100644 index 0000000..553feec --- /dev/null +++ b/htdocs/imacat/tech/cookies.html.zh-tw.xhtml @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + +如何設定 Cookies ? + + + + + + + +
    + +
    + + +

    如何設定 Cookies ?

    + +

    目錄

    + +
      +
    1. 前言
    2. +
    3. Mozilla
    4. +
    5. Internet Explorer 6
    6. +
    7. Internet Explorer 5
    8. +
    9. Internet Explorer 4 及更早的版本
    10. +
    11. Netscape
    12. +
    13. Opera 6
    14. +
    + + +

    前言

    + +

    Web 使用的 HTTP 通訊協定,是很不穩定的。只要網頁讀完,網站和讀者兩邊就斷線了,下次要連到別頁,兩邊要再重新連線一次。所以,對網站來說,很難知道幾次連上來的人,是不是同一個人。可是,像 Web 郵件等會員制的程式,一定要想辦法確認連上來的人,和之前登入輸入帳號密碼的,是同一個人,才知道要打開誰的信箱。為此, Netscape 發明了 Cookies ,能夠讓網站在讀者的電腦上存一些資料,可供隨時參考,確認幾次連上來的人是不是同一個人。不過, Cookies 也可以拿來做很多用途,例如把你上次連上來網路訂購的時候,所填的姓名、電話、地址、身份證字號、信用卡號碼、密碼等等記下來,以便日後隨時調閱。另一種常見的用法,是把你連上本站的每一頁網址都記下來,隨時調閱,像側錄監聽一樣。如果是廣告商,在很多大型網站上刊登廣告,就可以把各大網站側錄到的資料綜合起來,做成全世界每個人每天上網的完整記錄,詳細記載每個人的上網時間,連到哪裡,看了哪些東西等等,就像在你的網路線上裝針孔一樣。

    + +

    很可怕,對吧?

    + +

    Cookies 是個兩難的問題:沒有 Cookies ,網站分不清你是誰,就沒辦法做會員系統這類複雜的程式;有 Cookies ,網站可以監視你的一舉一動,並偷偷錄下你的各種資料。

    + +

    Cookies 的問題,全球資訊網聯盟 W3C 定了一套叫 P3P 的標準,要求網站把自己的 Cookies 作法以白紙黑字寫清楚,用 P3P 格式傳給瀏覽器。讀者可以設好自己的 Cookies 接收標準,讓瀏覽器拿來和網站的作法比較,決定要不要收網站的 Cookies 。這個方法聽起來不錯,不過不要相信這個方法P3P 是騙人的,因為網站怎麼作,都是它自己在說,事實上它在你的電腦存了什麼東西,電話、地址、信用卡號碼、看每一頁的時間網址記錄等等,它都可以編成亂碼後再存,瀏覽器也分不出來。網站誠不誠實是人的問題,瀏覽器程式再怎麼設計,也沒有辦法解決。 P3P 是幾家大商業網站和廣告商一起制定的,只是哄哄讀者,讓讀者安心的技倆而已。

    + +

    要真正解決 Cookies 的問題,要深入了解 Cookies :網站在你電腦上設 Cookies 時,可以設定一個效期。要是沒設效期,叫做暫時性的 Session Cookies ,瀏覽器只會暫時記著,不會存檔,只要瀏覽器關掉,就會消失。否則,要是有設效期, Cookies 會一直存在電腦上,直到過了效期,才會刪掉。不過,效期沒有限制,網站可以設成五十年一百年,那幾乎就不會過期,網站可以隨時調閱。

    + +

    另外, Cookies 還分第一方和第三方的兩種:第一方 Cookies 是指你要連上的網站自己發的 Cookies ,第三方是指你連上的網站,上面顯示了其它網站上的圖,這些其她網站發的 Cookies ,多半是廣告商的 Cookies

    + +

    其實,會員系統只需要暫時性的 Cookies ,在瀏覽器開著的時候,記得你是誰就可以了,關掉瀏覽器後,就不用一直記著你的資料。而且,我們連上一個網站會員系統,只需要那個網站的 Cookies ,不需要別人的 Cookies 。我們可以不收長期的 Cookies ,也不收第三方的 Cookies ,只收原來網站暫時性的 Cookies 就好。這樣,就算在你的 Cookies 裡記下什麼東西,只要關掉瀏覽器就沒了,對方也無從調閱起。

    + +

    比較舊的瀏覽器,對 Cookies 只有三種選擇:完全不用,完全接收,或是見一個問一個。我們既不可能完全不用,也不希望照單全收,如果見一個問一個,現在 Cookies 那麼多,也會把自己煩死。新的瀏覽器,會有比較多的選擇,可以關掉長期的 Cookies 和第三方的 Cookies ,不過,因為大多數的瀏覽器公司,和這些廣告商及商業網站是利益共同體,所以大多數瀏覽器的預設,都會把 Cookies 完全打開,你要自己手動去關起來。

    + +

    以下,說明如何在自己的瀏覽器上設定 Cookies

    + + +

    Mozilla

    + +

    啟動 Mozilla 後,由工具列上的 編輯(E)個人功能設定 按下去,會打開一個 功能設定 的視窗。在左邊的 分類 中選擇 個人及安全設定 下的 Cookies 。如果 個人及安全設定 左邊的箭頭朝右,看不到 Cookies ,在那個右箭頭上按一下,就看得到了。在右邊的 Cookies 接受原則 中,選擇 使用自動根據個人隱私安全等級設定 cookies ,並按一下左邊的 檢視個人隱私安全等級(V) ,打開 個人隱私安全等級 的視窗。在 個人隱私安全等級 中選擇 自訂 ,並在下面的 Cookies 設定 中, First Party Cookies 下面全部選 SessionThird Party Cookies 下面全部選 拒絕 。然 確定確定 。這樣就好了。

    + + +

    Internet Explorer 6

    + +

    啟動 Internet Explorer 後,由工具列上的 工具(T)網際網路選項(O)... 按下去,會打開一個 網際網路選項 的視窗。按一下上方的 隱私權 ,翻到 隱私權 那一頁,再按一下 設定值 區塊下面的 進階(V)... ,打開 進階隱私設定 的視窗。在 Cookie 區塊裡, 覆寫自動 Cookie 處理(O) 的選項上打勾,在 第一方 Cookies 下面選 封鎖(B) ,在 第三方 Cookies 下面也選 封鎖(B) ,然後在下面的 自動允許工作階段 cookies(W) 上打勾。然後按 確定確定 。這樣就好了。

    + + +

    Internet Explorer 5

    + +

    啟動 Internet Explorer 後,由工具列上的 工具(T)Internet 選項(O)... 按下去,會打開一個 Internet 選項 的視窗。按一下上方的 安全性 ,翻到 安全性 那一頁。按一下下面的 自訂層級(C) ,開啟 安全性設定 的視窗。在 設定(S): 中往下拉到 Cookies 的地方,在 允許每一階段的 cookies (未儲存) 的地方選 啟動 ,在 允許除存在您電腦上的 cookies 的地方選 關閉 。然後按 確定確定 。這樣就好了。

    + + +

    Internet Explorer 4 及更早的版本

    + +

    Internet Explorer 4 及更早的版本只能設成全部拒絕,全部接收,或見一個問一個,無法作細部設定。

    + + +

    Netscape

    + +

    Netscape 的所有版本只能設成全部拒絕,全部接收,或見一個問一個,無法作細部設定。

    + + +

    Opera 6

    + +

    啟動 Opera 後,由工具列上的 檔案(F)功能設定(R)... 按下去,會打開一個功能設定 的視窗。在左邊選擇 隱私 。在右邊的 Cookies(K) 中,在 啟動cookie(C) 上打勾,下面第一個選單選 自動接受所有cookie ,第二個選單選 不接受第三者的cookie ,再勾選下面的 離開時刪除cookie(X) 。然後按 確定 。這樣就好了。

    + + +
    依瑪貓,初稿 2002-01-13 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/debwine.html.zh-cn.html b/htdocs/imacat/tech/debwine.html.zh-cn.html new file mode 120000 index 0000000..1489fba --- /dev/null +++ b/htdocs/imacat/tech/debwine.html.zh-cn.html @@ -0,0 +1 @@ +debwine.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/debwine.html.zh-cn.xhtml b/htdocs/imacat/tech/debwine.html.zh-cn.xhtml new file mode 100644 index 0000000..0440346 --- /dev/null +++ b/htdocs/imacat/tech/debwine.html.zh-cn.xhtml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + +Debian 安装 wine 或 ttf-mscorefonts-installer 的问题(Ubuntu 同解) + + + + + + + +
    + +
    + + +

    Debian 安装 wine 或 ttf-mscorefonts-installer 的问题(Ubuntu 同解)

    + +

    在 Debian 下,安装 wine 或 ttf-mscorefonts-installer 的时候,若你在台湾,会碰到以下的错误:

    + +
    +root@rinse:~# apt-get install wine
    +…
    +正在设定 ttf-mscorefonts-installer (3.0) ...
    +
    +These fonts were provided by Microsoft "in the interest of cross-
    +platform compatibility".  This is no longer the case, but they are
    +still available from third parties.
    +
    +You are free to download these fonts and use them for your own use,
    +but you may not redistribute them in modified form, including changes
    +to the file name or packaging format.
    +
    +--2009-11-11 00:45:02--  http://downloads.sourceforge.net/corefonts/andale32.exe
    +正在查找主机 downloads.sourceforge.net... 216.34.181.59
    +正在连接 downloads.sourceforge.net|216.34.181.59|:80... 连上了。
    +已送出 HTTP 要求,正在等候回应... 302 Found
    +位置:http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/andale32.exe [跟随连结]
    +--2009-11-11 00:45:03--  http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/andale32.exe
    +正在查找主机 ncu.dl.sourceforge.net... 140.115.17.45
    +正在连接 ncu.dl.sourceforge.net|140.115.17.45|:80... 连上了。
    +已送出 HTTP 要求,正在等候回应... 200 OK
    +长度: 198384 (194K) [application/octet-stream]
    +Saving to: `./andale32.exe'
    +
    +100%[======================================>] 198,384     40.8K/s   in 4.7s
    +
    +2009-11-11 00:45:08 (40.8 KB/s) -- 已储存 ‘./andale32.exe’ [198384/198384])
    +
    +--2009-11-11 00:45:08--  http://downloads.sourceforge.net/corefonts/arialb32.exe
    +正在查找主机 downloads.sourceforge.net... 216.34.181.59
    +正在连接 downloads.sourceforge.net|216.34.181.59|:80... 连上了。
    +已送出 HTTP 要求,正在等候回应... 302 Found
    +位置:http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/arialb32.exe [跟随连结]
    +--2009-11-11 00:45:09--  http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/arialb32.exe
    +正在查找主机 ncu.dl.sourceforge.net... 140.115.17.45
    +正在连接 ncu.dl.sourceforge.net|140.115.17.45|:80... 连上了。
    +已送出 HTTP 要求,正在等候回应... 200 OK
    +长度: 168176 (164K) [application/octet-stream]
    +Saving to: `./arialb32.exe'
    +
    +100%[======================================>] 168,176     40.0K/s   in 4.1s
    +
    +2009-11-11 00:45:13 (40.0 KB/s) -- 已储存 ‘./arialb32.exe’ [168176/168176])
    +
    +--2009-11-11 00:45:13--  http://downloads.sourceforge.net/corefonts/arial32.exe
    +正在查找主机 downloads.sourceforge.net... 216.34.181.59
    +正在连接 downloads.sourceforge.net|216.34.181.59|:80... 连上了。
    +已送出 HTTP 要求,正在等候回应... 302 Found
    +位置:http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/arial32.exe [跟随连结]
    +--2009-11-11 00:45:14--  http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/arial32.exe
    +正在查找主机 ncu.dl.sourceforge.net... 140.115.17.45
    +正在连接 ncu.dl.sourceforge.net|140.115.17.45|:80... 失败:连线超过时间。
    +已放弃。
    +
    +--2009-11-11 00:45:19--  http://switch.dl.sourceforge.net/sourceforge/corefonts/arial32.exe
    +正在查找主机 switch.dl.sourceforge.net... 130.59.138.21, 2001:620:0:1b::21
    +正在连接 switch.dl.sourceforge.net|130.59.138.21|:80... 连上了。
    +已送出 HTTP 要求,正在等候回应... 302 Found
    +位置:http://downloads.sourceforge.net/sourceforge/corefonts/arial32.exe?download&failedmirror=switch.dl.sourceforge.net [跟随连结]
    +--2009-11-11 00:45:21--  http://downloads.sourceforge.net/sourceforge/corefonts/arial32.exe?download&failedmirror=switch.dl.sourceforge.net
    +正在查找主机 downloads.sourceforge.net... 216.34.181.59
    +正在连接 downloads.sourceforge.net|216.34.181.59|:80... 连上了。
    +已送出 HTTP 要求,正在等候回应... 302 Found
    +位置:http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/arial32.exe [跟随连结]
    +--2009-11-11 00:45:21--  http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/arial32.exe
    +正在查找主机 ncu.dl.sourceforge.net... 140.115.17.45
    +正在连接 ncu.dl.sourceforge.net|140.115.17.45|:80... 失败:连线超过时间。
    +已放弃。
    +…
    +
    + +

    从 ncu.dl.sourceforge.net 下载到第三个字型后就挂掉了,没办法继续下载后面的字型,安装会失败。从讯息中看起来,要下载字型的时候,透过 SourceForge.net 的镜像站切换伺服器,自动依使用者在台湾,转到中央大学的镜像站。而中央大学的镜像站又有防抓站,只要连续抓超过两个档案,就会丢掉封包,无法继续下载。所以当 ttf-mscorefonts-installer 要下载一连串的字型时,下载到第三个字型就会被挡住了。因为选取哪一个镜像站是 SourceForge.net 的镜像站切换伺服器决定的,也没办法去改掉。

    + +

    不过,倒有一个简单的 Hack 解法。

    + +

    因为下载用的程式还是 wget , wget 还是透过系统解析取得 ncu.dl.sourceforge.net 的 IP 去下载的。只要骗 wget 到另一个 IP 下载,就可以了。台湾有另外一个频宽更大的 SourceForge.net 镜像站在国网中心 nchc.dl.sourceforge.net ,只要能骗 wget 去国网中心下载即可。

    + +
    +root@rinse:~# host ncu.dl.sourceforge.net
    +ncu.dl.sourceforge.net has address 140.115.17.45
    +root@rinse:~# host nchc.dl.sourceforge.net
    +nchc.dl.sourceforge.net has address 211.79.60.17
    +nchc.dl.sourceforge.net has IPv6 address 2001:e10:ffff:1f02::17
    +root@rinse:~# echo "211.79.60.17 ncu.dl.sourceforge.net" >> /etc/hosts
    +root@rinse:~# apt-get install wine
    +
    + +

    其中 echo "211.79.60.17 ncu.dl.sourceforge.net" >> /etc/hosts 是把 ncu.dl.sourceforge.net 这个主机的 IP 写死在 211.79.60.17 。这不是正确的做法,只是一个简单的 Hack ,骗过 wget 而已。安装完毕后最好把那一行删掉,以免日后网域名称解析出问题。

    + +
    依玛猫,初稿 2009-11-11 ,上次更新日期 2009-11-11
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/debwine.html.zh-tw.html b/htdocs/imacat/tech/debwine.html.zh-tw.html new file mode 120000 index 0000000..5588045 --- /dev/null +++ b/htdocs/imacat/tech/debwine.html.zh-tw.html @@ -0,0 +1 @@ +debwine.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/debwine.html.zh-tw.xhtml b/htdocs/imacat/tech/debwine.html.zh-tw.xhtml new file mode 100644 index 0000000..cec65f0 --- /dev/null +++ b/htdocs/imacat/tech/debwine.html.zh-tw.xhtml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + +Debian 安裝 wine 或 ttf-mscorefonts-installer 的問題(Ubuntu 同解) + + + + + + + +
    + +
    + + +

    Debian 安裝 wine 或 ttf-mscorefonts-installer 的問題(Ubuntu 同解)

    + +

    在 Debian 下,安裝 wine 或 ttf-mscorefonts-installer 的時候,若你在台灣,會碰到以下的錯誤:

    + +
    +root@rinse:~# apt-get install wine
    +…
    +正在設定 ttf-mscorefonts-installer (3.0) ...
    +
    +These fonts were provided by Microsoft "in the interest of cross-
    +platform compatibility".  This is no longer the case, but they are
    +still available from third parties.
    +
    +You are free to download these fonts and use them for your own use,
    +but you may not redistribute them in modified form, including changes
    +to the file name or packaging format.
    +
    +--2009-11-11 00:45:02--  http://downloads.sourceforge.net/corefonts/andale32.exe
    +正在查找主機 downloads.sourceforge.net... 216.34.181.59
    +正在連接 downloads.sourceforge.net|216.34.181.59|:80... 連上了。
    +已送出 HTTP 要求,正在等候回應... 302 Found
    +位置:http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/andale32.exe [跟隨連結]
    +--2009-11-11 00:45:03--  http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/andale32.exe
    +正在查找主機 ncu.dl.sourceforge.net... 140.115.17.45
    +正在連接 ncu.dl.sourceforge.net|140.115.17.45|:80... 連上了。
    +已送出 HTTP 要求,正在等候回應... 200 OK
    +長度: 198384 (194K) [application/octet-stream]
    +Saving to: `./andale32.exe'
    +
    +100%[======================================>] 198,384     40.8K/s   in 4.7s
    +
    +2009-11-11 00:45:08 (40.8 KB/s) -- 已儲存 ‘./andale32.exe’ [198384/198384])
    +
    +--2009-11-11 00:45:08--  http://downloads.sourceforge.net/corefonts/arialb32.exe
    +正在查找主機 downloads.sourceforge.net... 216.34.181.59
    +正在連接 downloads.sourceforge.net|216.34.181.59|:80... 連上了。
    +已送出 HTTP 要求,正在等候回應... 302 Found
    +位置:http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/arialb32.exe [跟隨連結]
    +--2009-11-11 00:45:09--  http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/arialb32.exe
    +正在查找主機 ncu.dl.sourceforge.net... 140.115.17.45
    +正在連接 ncu.dl.sourceforge.net|140.115.17.45|:80... 連上了。
    +已送出 HTTP 要求,正在等候回應... 200 OK
    +長度: 168176 (164K) [application/octet-stream]
    +Saving to: `./arialb32.exe'
    +
    +100%[======================================>] 168,176     40.0K/s   in 4.1s
    +
    +2009-11-11 00:45:13 (40.0 KB/s) -- 已儲存 ‘./arialb32.exe’ [168176/168176])
    +
    +--2009-11-11 00:45:13--  http://downloads.sourceforge.net/corefonts/arial32.exe
    +正在查找主機 downloads.sourceforge.net... 216.34.181.59
    +正在連接 downloads.sourceforge.net|216.34.181.59|:80... 連上了。
    +已送出 HTTP 要求,正在等候回應... 302 Found
    +位置:http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/arial32.exe [跟隨連結]
    +--2009-11-11 00:45:14--  http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/arial32.exe
    +正在查找主機 ncu.dl.sourceforge.net... 140.115.17.45
    +正在連接 ncu.dl.sourceforge.net|140.115.17.45|:80... 失敗:連線超過時間。
    +已放棄。
    +
    +--2009-11-11 00:45:19--  http://switch.dl.sourceforge.net/sourceforge/corefonts/arial32.exe
    +正在查找主機 switch.dl.sourceforge.net... 130.59.138.21, 2001:620:0:1b::21
    +正在連接 switch.dl.sourceforge.net|130.59.138.21|:80... 連上了。
    +已送出 HTTP 要求,正在等候回應... 302 Found
    +位置:http://downloads.sourceforge.net/sourceforge/corefonts/arial32.exe?download&failedmirror=switch.dl.sourceforge.net [跟隨連結]
    +--2009-11-11 00:45:21--  http://downloads.sourceforge.net/sourceforge/corefonts/arial32.exe?download&failedmirror=switch.dl.sourceforge.net
    +正在查找主機 downloads.sourceforge.net... 216.34.181.59
    +正在連接 downloads.sourceforge.net|216.34.181.59|:80... 連上了。
    +已送出 HTTP 要求,正在等候回應... 302 Found
    +位置:http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/arial32.exe [跟隨連結]
    +--2009-11-11 00:45:21--  http://ncu.dl.sourceforge.net/project/corefonts/the%20fonts/final/arial32.exe
    +正在查找主機 ncu.dl.sourceforge.net... 140.115.17.45
    +正在連接 ncu.dl.sourceforge.net|140.115.17.45|:80... 失敗:連線超過時間。
    +已放棄。
    +…
    +
    + +

    從 ncu.dl.sourceforge.net 下載到第三個字型後就掛掉了,沒辦法繼續下載後面的字型,安裝會失敗。從訊息中看起來,要下載字型的時候,透過 SourceForge.net 的鏡像站切換伺服器,自動依使用者在台灣,轉到中央大學的鏡像站。而中央大學的鏡像站又有防抓站,只要連續抓超過兩個檔案,就會丟掉封包,無法繼續下載。所以當 ttf-mscorefonts-installer 要下載一連串的字型時,下載到第三個字型就會被擋住了。因為選取哪一個鏡像站是 SourceForge.net 的鏡像站切換伺服器決定的,也沒辦法去改掉。

    + +

    不過,倒有一個簡單的 Hack 解法。

    + +

    因為下載用的程式還是 wget , wget 還是透過系統解析取得 ncu.dl.sourceforge.net 的 IP 去下載的。只要騙 wget 到另一個 IP 下載,就可以了。台灣有另外一個頻寬更大的 SourceForge.net 鏡像站在國網中心 nchc.dl.sourceforge.net ,只要能騙 wget 去國網中心下載即可。

    + +
    +root@rinse:~# host ncu.dl.sourceforge.net
    +ncu.dl.sourceforge.net has address 140.115.17.45
    +root@rinse:~# host nchc.dl.sourceforge.net
    +nchc.dl.sourceforge.net has address 211.79.60.17
    +nchc.dl.sourceforge.net has IPv6 address 2001:e10:ffff:1f02::17
    +root@rinse:~# echo "211.79.60.17 ncu.dl.sourceforge.net" >> /etc/hosts
    +root@rinse:~# apt-get install wine
    +
    + +

    其中 echo "211.79.60.17 ncu.dl.sourceforge.net" >> /etc/hosts 是把 ncu.dl.sourceforge.net 這個主機的 IP 寫死在 211.79.60.17 。這不是正確的做法,只是一個簡單的 Hack ,騙過 wget 而已。安裝完畢後最好把那一行刪掉,以免日後網域名稱解析出問題。

    + +
    依瑪貓,初稿 2009-11-11 ,上次更新日期 2009-11-11
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/flashver.html.en.html b/htdocs/imacat/tech/flashver.html.en.html new file mode 120000 index 0000000..0a65ba9 --- /dev/null +++ b/htdocs/imacat/tech/flashver.html.en.html @@ -0,0 +1 @@ +flashver.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/flashver.html.en.xhtml b/htdocs/imacat/tech/flashver.html.en.xhtml new file mode 100644 index 0000000..aecdc14 --- /dev/null +++ b/htdocs/imacat/tech/flashver.html.en.xhtml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + +Flash Version Detection + + + + + + + +
    + +
    + + +

    Flash Version Detection

    + +

    This is my first flash. It’s very simple and small: Display your flash plugin version. I do this for myself. When installing a new OS, I need a small flash to test whether the flash plugin is installed correctly. It’d be better if it displays the flash plugin version. I tried to find one, but the only one I found on the Macromedia website is too large (66,468 bytes). Finally I decided to make one myself. It took me several days.

    + +

    This flash is 2,396 bytes. It is made with Macromedia Flash MX 2004 Trial. It can detect Flash version 3 and above.

    + +
    + + + You don’t have Flash player installed. + +
    + +

    Download the flash source.

    + +

    The above HTML was written according to the HTML 4.01/XHTML 1.1 specifications. Its content follows:

    + +
    +<div>
    +<object data="../images/flashver.swf" type="application/x-shockwave-flash"
    +    style="height: 60px; width: 360px;">
    +    <param name="movie" value="../images/flashver.swf" />
    +    You don&rsquo;t have Flash player installed.
    +</object>
    +</div>
    +
    + +
    by imacat, first written 2003-09-26, last updated 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/flashver.html.zh-cn.html b/htdocs/imacat/tech/flashver.html.zh-cn.html new file mode 120000 index 0000000..d9c1dfa --- /dev/null +++ b/htdocs/imacat/tech/flashver.html.zh-cn.html @@ -0,0 +1 @@ +flashver.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/flashver.html.zh-cn.xhtml b/htdocs/imacat/tech/flashver.html.zh-cn.xhtml new file mode 100644 index 0000000..40c3d0d --- /dev/null +++ b/htdocs/imacat/tech/flashver.html.zh-cn.xhtml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + +Flash 版本侦测 + + + + + + + +
    + +
    + + +

    Flash 版本侦测

    + +

    这是我的第一个 Flash ,很小很简单:秀出浏览器的 Flash 外挂程式版本。我做这个是我自己要用:装作业系统时,为测试 Flash 外挂程式,我需要一个小 Flash ,最好能顺便秀出 Flash 外挂程式的版本。我找了很久,只有在 Macromedia 网站上找到一个,可是很大 (66,468 bytes) 。最后我决定自己写,花了几天的时间摸索,才写出来。

    + +

    这个 Flash 大小 2,396 bytes ,以 Macromedia Flash MX 2004 试用版制作,可以侦测出 Flash 3 以上的版本。

    + +
    + + + You don’t have Flash player installed. + +
    + +

    下载 Flash 原始档

    + +

    以上 HTML ,依 HTML 4.01/XHTML 1.1 标准规定写作,内容如下:

    + +
    +<div>
    +<object data="../images/flashver.swf" type="application/x-shockwave-flash"
    +    style="height: 60px; width: 360px;">
    +    <param name="movie" value="../images/flashver.swf" />
    +    You don't have Flash player installed.
    +</object>
    +</div>
    +
    + +
    依玛猫,初稿 2003-09-26 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/flashver.html.zh-tw.html b/htdocs/imacat/tech/flashver.html.zh-tw.html new file mode 120000 index 0000000..8078131 --- /dev/null +++ b/htdocs/imacat/tech/flashver.html.zh-tw.html @@ -0,0 +1 @@ +flashver.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/flashver.html.zh-tw.xhtml b/htdocs/imacat/tech/flashver.html.zh-tw.xhtml new file mode 100644 index 0000000..442bf62 --- /dev/null +++ b/htdocs/imacat/tech/flashver.html.zh-tw.xhtml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + +Flash 版本偵測 + + + + + + + +
    + +
    + + +

    Flash 版本偵測

    + +

    這是我的第一個 Flash ,很小很簡單:秀出瀏覽器的 Flash 外掛程式版本。我做這個是我自己要用:裝作業系統時,為測試 Flash 外掛程式,我需要一個小 Flash ,最好能順便秀出 Flash 外掛程式的版本。我找了很久,只有在 Macromedia 網站上找到一個,可是很大 (66,468 bytes) 。最後我決定自己寫,花了幾天的時間摸索,才寫出來。

    + +

    這個 Flash 大小 2,396 bytes ,以 Macromedia Flash MX 2004 試用版製作,可以偵測出 Flash 3 以上的版本。

    + +
    + + + You don’t have Flash player installed. + +
    + +

    下載 Flash 原始檔

    + +

    以上 HTML ,依 HTML 4.01/XHTML 1.1 標準規定寫作,內容如下:

    + +
    +<div>
    +<object data="../images/flashver.swf" type="application/x-shockwave-flash"
    +    style="height: 60px; width: 360px;">
    +    <param name="movie" value="../images/flashver.swf" />
    +    You don't have Flash player installed.
    +</object>
    +</div>
    +
    + +
    依瑪貓,初稿 2003-09-26 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/forhire.html.zh-cn.html b/htdocs/imacat/tech/forhire.html.zh-cn.html new file mode 120000 index 0000000..b8de1a4 --- /dev/null +++ b/htdocs/imacat/tech/forhire.html.zh-cn.html @@ -0,0 +1 @@ +forhire.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/forhire.html.zh-cn.xhtml b/htdocs/imacat/tech/forhire.html.zh-cn.xhtml new file mode 100644 index 0000000..0189e85 --- /dev/null +++ b/htdocs/imacat/tech/forhire.html.zh-cn.xhtml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + +待聘 + + + + + + + +
    + +
    + + +

    待聘

    + +

    我在找额外的兼差中。如果你有需要兼职的高阶系统工程师,欢迎随时与我联络

    + + +

    资历

    + +
      +
    • Linux 系统正职三年 (2000~) ,私有网路三年 (1999~) 。
    • +
    • Windows NT/2000 系统正职一年,私有网路三年 (1999~) 。
    • +
    • 现任 TLUG (Taiwan Linux Users' Group) 台湾 Linux 使用者社群通讯管理员 (2000~) 。
    • +
    • 自有网站五年,独力撰写中小型网站超过十个。
    • +
    + + +

    专长

    + +
      +
    • 高阶 Linux 系统安全管理维护 (Sendmail, Samba, Apache, Perl, PHP, MySQL, AntiVirus, SSL, SSH, iptables) 。
    • +
    • 基本 Windows NT/2000 系统管理维护。
    • +
    • 网页撰写 (HTML) 、网站程式 Web Application (Perl, PHP) 、网站内文管理系统 (Content Management System) 。
    • +
    • 各项最新网路标准 (HTML, CSS, DOM, SMTP, HTTP…) 。
    • +
    + + +

    接案范围

    + +
      +
    • 公司、机关单位远端网管外包。
    • +
    • 电脑资讯策略顾问(采购、升级、新系统整合、成本评估、安全防护、防毒解毒、网站架设等等)。
    • +
    • 网站程式撰写外包。
    • +
    + + +

    优点

    + +
      +
    • 中小企业,机关单位无法负担专业网管薪资者,可透过远端网管外包,节省成本。
    • +
    • 现有网管工作量无法负荷,影响公司专案计划进度(如网站撰写)者,可透过网管外包,分散管理成本,让原有网管人员无后顾之忧,全力协助公司内部专案。
    • +
    • 高阶、专业有经验网管能力,较一般聘雇全职低薪的新手网管,能在更短的时间内,用更好的方式解决问题,减少时间、成本上的耗费。
    • +
    • 英文能力强,随时与最新技术、最新标准接轨,可减少公司网管人员学习新技术、新标准时,所需的学习时间成本。
    • +
    + +

    若有兴趣,欢迎随时来信洽询

    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/forhire.html.zh-tw.html b/htdocs/imacat/tech/forhire.html.zh-tw.html new file mode 120000 index 0000000..f61b2bd --- /dev/null +++ b/htdocs/imacat/tech/forhire.html.zh-tw.html @@ -0,0 +1 @@ +forhire.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/forhire.html.zh-tw.xhtml b/htdocs/imacat/tech/forhire.html.zh-tw.xhtml new file mode 100644 index 0000000..d5965a7 --- /dev/null +++ b/htdocs/imacat/tech/forhire.html.zh-tw.xhtml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + +待聘 + + + + + + + +
    + +
    + + +

    待聘

    + +

    我在找額外的兼差中。如果妳有需要兼職的高階系統工程師,歡迎隨時與我聯絡

    + + +

    資歷

    + +
      +
    • Linux 系統正職三年 (2000~) ,私有網路三年 (1999~) 。
    • +
    • Windows NT/2000 系統正職一年,私有網路三年 (1999~) 。
    • +
    • 現任 TLUG (Taiwan Linux Users' Group) 臺灣 Linux 使用者社群通訊管理員 (2000~) 。
    • +
    • 自有網站五年,獨力撰寫中小型網站超過十個。
    • +
    + + +

    專長

    + +
      +
    • 高階 Linux 系統安全管理維護 (Sendmail, Samba, Apache, Perl, PHP, MySQL, AntiVirus, SSL, SSH, iptables) 。
    • +
    • 基本 Windows NT/2000 系統管理維護。
    • +
    • 網頁撰寫 (HTML) 、網站程式 Web Application (Perl, PHP) 、網站內文管理系統 (Content Management System) 。
    • +
    • 各項最新網路標準 (HTML, CSS, DOM, SMTP, HTTP…) 。
    • +
    + + +

    接案範圍

    + +
      +
    • 公司、機關單位遠端網管外包。
    • +
    • 電腦資訊策略顧問(採購、昇級、新系統整合、成本評估、安全防護、防毒解毒、網站架設等等)。
    • +
    • 網站程式撰寫外包。
    • +
    + + +

    優點

    + +
      +
    • 中小企業,機關單位無法負擔專業網管薪資者,可透過遠端網管外包,節省成本。
    • +
    • 現有網管工作量無法負荷,影響公司專案計劃進度(如網站撰寫)者,可透過網管外包,分散管理成本,讓原有網管人員無後顧之憂,全力協助公司內部專案。
    • +
    • 高階、專業有經驗網管能力,較一般聘雇全職低薪的新手網管,能在更短的時間內,用更好的方式解決問題,減少時間、成本上的耗費。
    • +
    • 英文能力強,隨時與最新技術、最新標準接軌,可減少公司網管人員學習新技術、新標準時,所需的學習時間成本。
    • +
    + +

    若有興趣,歡迎隨時來信洽詢

    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/index.html.en.html b/htdocs/imacat/tech/index.html.en.html new file mode 120000 index 0000000..08fc4ee --- /dev/null +++ b/htdocs/imacat/tech/index.html.en.html @@ -0,0 +1 @@ +index.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/index.html.en.xhtml b/htdocs/imacat/tech/index.html.en.xhtml new file mode 100644 index 0000000..d07ed30 --- /dev/null +++ b/htdocs/imacat/tech/index.html.en.xhtml @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + +Tavern’s Computer Room + + + + + + + +
    + +
    + + +

    Tavern’s Computer Room

    + +

    In this section are my notes on the computer relative topics.

    + + + + + +

    My Member Pages

    + +

    Below is a list of my member pages on several services I applied. Various aspects of my newest infomation and activities are available there: ^_*’

    + + + + +

    My Projects

    + +

    These are some projects written by me. There must be someone out there who needs these functionalities, too. If one’s code is used by all who others need that functionality, we can save a lot of time not doing duplicated works. Then, we can used this saved time for more works that are not attended yet, which benefit every one of us. I think this is one of the essence of the term open source: sharing and accumulation.

    + +
      + +
    • +

      Calc Mosaic

      + +

      Calc Mosaic is a program to create mosaic art from images with OpenOffice Calc. This can be used to create cool stop-motion movies.

      +
    • + +
    • +

      Mobile Impress Presentation Controller

      + +

      Mobile Impress Presentation Controller is a mobile OpenOffice Impress presentation controller. It turns your smartphone into a presentation controller through TCP/IP networking. The documentation is still unavailable. Please subscribe for future updates.

      +
    • + +
    • +

      SNTP Client for Virtual PC

      + +

      SNTP Client for Virtual PC is an SNTP client daemon for machines without a sane system time. It was originally designed for my GNU/Linux server running on Connectix Virtual PC. It runs according to RFC 1769 SNTP, connecting the NTP server on UDP port 123.

      + +

      This is my first daemon, my first socket program and my first public-released C program. Any comment or suggestion is welcome. ^_*’

      +
    • + +
    • +

      Locale::Maketext::Gettext

      + +

      An effort to join the GNU gettext and Locale::Maketext localization frameworks. GNU gettext is excellent for its global design, its completeness and its simplicity, and is the de facto standard. But it’s weak in the plural issue. Locale::Maketext is excellent in its plural solution, but weak in all the other issues. Locale::Maketext::Gettext is a seamless solution to join both their advantages and get rid of both their problems. Now you can sit back and relax, embrace both their advantages without changing your way of working. ^_*’

      +
    • + +
    • +

      chklinks

      + +

      chklinks is a non-threaded Perl link checker. It helps finding broken links on your website.

      +
    • + +
    • +

      reslog

      + +

      reslog reverse-resolves IP in the Apache log files. These log files can then be analyzed by another program, like Analog. You can think of it as a replacement of Apache HostNameLookups directive, in the sense that it resolves the client IP altogether once a day.

      +
    • + +
    • +

      arclog

      + +

      arclog archives the log files monthly. It strips off previous months’ log records from the log file, and save them to compressed archive files named logfile.yyyymm. It then saves the hard disk space and prevents potential attacks on log files.

      + +

      Currently, arclog supports Apache access log, Syslog, NTP, Apache 1 SSL engine log and my own bracketed, modified ISO date/time log file formats, and gzip and bzip2 compression methods.

      +
    • + +
    • +

      flashver

      + +

      This is my first Flash. It displays your flash plug-in version.

      +
    • + +
    + + +

    HOWTO Tutorials

    + + + + +

    Server Infomations

    + + + + +

    Logo And Links

    + +

    Taver IMACAT’s server is powered by the following softwares:

    + +
    +Linux 2.4 | +Debian | +Apache | +mod_perl | +Comprehensive Perl Archive Network | +openssl | +mod_ssl | +Python | +Mailman | +Analog | +Pure-FTPd | +UltraEdit +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/index.html.zh-cn.html b/htdocs/imacat/tech/index.html.zh-cn.html new file mode 120000 index 0000000..5ee9c39 --- /dev/null +++ b/htdocs/imacat/tech/index.html.zh-cn.html @@ -0,0 +1 @@ +index.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/index.html.zh-cn.xhtml b/htdocs/imacat/tech/index.html.zh-cn.xhtml new file mode 100644 index 0000000..c328175 --- /dev/null +++ b/htdocs/imacat/tech/index.html.zh-cn.xhtml @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + +旅舍的电脑笔记 + + + + + + + +
    + +
    + + +

    旅舍的电脑笔记

    + +

    这个专区,是我在电脑相关领域的一些心得,和大家分享。

    + +

    待聘

    + +

    我在找额外的兼差中。若需要兼职的系统、开发工程师,欢迎随时与我联络

    + + + + +

    我的会员网页

    + +

    以下所列,是我在一些社群中的会员网页,这些网页里,也会有我最近的动态,欢迎参观。 ^_*’

    + + + + +

    我写的程式

    + +

    这是我写的一些程式。我想一定也有人需要这些程式。如果一个人写的程式,其她人有需要拿去用了,又合用的话,大家都可以省下很多的时间,不用重复做别人做过的事。省下来的时间,可以拿来做更多还没做好的事,再回过头来造福更多人。我想这就是 Open Source 的重要精神:分享和累积。

    + +
      + +
    • +

      Calc Mosaic

      + +

      Calc Mosaic 是在 OpenOffice Calc 上制作马赛克拼贴艺术的程式,可以用来制作定格动画。

      +
    • + +
    • +

      Mobile Impress Presentation Controller

      + +

      Mobile Impress Presentation ControllerOpenOffice Impress 的行动简报摇控器,透过 TCP/IP 网路,让你的行动电话变身为简报摇控器。说明文件还没有写好,请见谅。

      +
    • + +
    • +

      SNTP Client for Virtual PC

      + +

      SNTP Client for Virtual PCSNTP 客户端服务程式,专为时间不正常的系统设计,原先是我为了在 Connectix Virtual PC 上跑 GNU/Linux 系统而写。 vsntpRFC 1769 SNTP 标准,连线到 NTP 伺服器上的 UDP 埠 123 以校时。

      + +

      vsntp 是我写的第一个 daemon ,我写的第一个 socket 程式,也是我第一个公开发行的 C 程式。请多多指教~ ^_*’

      +
    • + +
    • +

      Locale::Maketext::Gettext

      + +

      这是 GNU gettextPerl Locale::Maketext 多语架构的整合方案。 GNU gettext 的多语化架构,无论是整体设计,完整性和易用性上,无人能出其右,也是目前通用的多语化标准。然而,它也有设计上的缺陷,例如单复数的处理。 Perl 的 Locale::Maketext 在单复数的处理设计上,独冠群伦,但在整体的设计上,则显得非常薄弱。 Locale::Maketext::Gettext 是两者的完美整合方案,合并了各自的优点,也同时摆脱了各自最大的缺陷。现在有了 Locale::Maketext::Gettext ,你可轻轻松松,拥抱两大多语架构的所有优点,再也不用烦恼这些问题罗! ^_*’

      +
    • + +
    • +

      chklinks

      + +

      chklinks 是单执行绪的 Perl 连结检查程式,用来检查网站上的超连结有没有疏漏。

      +
    • + +
    • +

      reslog

      + +

      reslog 是记录档的反查程式,用来反查 Apache 记录档里 IP 的主机名称。查过后,可以套用像 Analog 之类的记录档统计程式。你可以把它当做 Apache HostNameLookups 指令的替代品,每天一次反查当天所有的 IP

      +
    • + +
    • +

      arclog

      + +

      arclog 是记录档每月归档程式,将记录档中,前月的记录按月份压缩归档,以节省硬碟空间,并避免记录档被有心人士破坏。

      + +

      arclog 目前支援 ApacheSyslogNTPApache 1 SSL engine log 及我自己用的括弧 ISO 修正格式五种格式的记录档,与 gzipbzip2 两种压缩法。很多程式都可以用 Apache 相容记录档格式记录,如 CUPSProFTPDPure-FTPd…等, arclog 也可以归档这些 Apache 相容格式的记录档。

      +
    • + +
    • +

      flashver

      + +

      这是我写的第一个 Flash ,可以秀出浏览器的 Flash 外挂程式版本。

      +
    • + +
    + + +

    技术教学

    + + + + +

    伺服器相关资料

    + + + + +

    标志连结区

    + +

    旅舍依玛伺服器以下列程式建置:

    + +
    +Linux 2.4 | +Debian | +Apache | +mod_perl | +Comprehensive Perl Archive Network | +openssl | +mod_ssl | +Python | +Mailman | +Analog | +Pure-FTPd | +UltraEdit +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/index.html.zh-tw.html b/htdocs/imacat/tech/index.html.zh-tw.html new file mode 120000 index 0000000..6c1b76e --- /dev/null +++ b/htdocs/imacat/tech/index.html.zh-tw.html @@ -0,0 +1 @@ +index.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/index.html.zh-tw.xhtml b/htdocs/imacat/tech/index.html.zh-tw.xhtml new file mode 100644 index 0000000..1d27035 --- /dev/null +++ b/htdocs/imacat/tech/index.html.zh-tw.xhtml @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + +旅舍的電腦筆記 + + + + + + + +
    + +
    + + +

    旅舍的電腦筆記

    + +

    這個專區,是我在電腦相關領域的一些心得,和大家分享。

    + +

    待聘

    + +

    我在找額外的兼差中。若需要兼職的系統、開發工程師,歡迎隨時與我聯絡

    + + + + +

    我的會員網頁

    + +

    以下所列,是我在一些社群中的會員網頁,這些網頁裏,也會有我最近的動態,歡迎參觀。 ^_*’

    + + + + +

    我寫的程式

    + +

    這是我寫的一些程式。我想一定也有人需要這些程式。如果一個人寫的程式,其她人有需要拿去用了,又合用的話,大家都可以省下很多的時間,不用重複做別人做過的事。省下來的時間,可以拿來做更多還沒做好的事,再回過頭來造福更多人。我想這就是 Open Source 的重要精神:分享和累積。

    + +
      + +
    • +

      Calc Mosaic

      + +

      Calc Mosaic 是在 OpenOffice Calc 上製作馬賽克拼貼藝術的程式,可以用來製作定格動畫。

      +
    • + +
    • +

      Mobile Impress Presentation Controller

      + +

      Mobile Impress Presentation ControllerOpenOffice Impress 的行動簡報搖控器,透過 TCP/IP 網路,讓你的行動電話變身為簡報搖控器。說明文件還沒有寫好,請見諒。

      +
    • + +
    • +

      SNTP Client for Virtual PC

      + +

      SNTP Client for Virtual PCSNTP 客戶端服務程式,專為時間不正常的系統設計,原先是我為了在 Connectix Virtual PC 上跑 GNU/Linux 系統而寫。 vsntpRFC 1769 SNTP 標準,連線到 NTP 伺服器上的 UDP 埠 123 以校時。

      + +

      vsntp 是我寫的第一個 daemon ,我寫的第一個 socket 程式,也是我第一個公開發行的 C 程式。請多多指教~ ^_*’

      +
    • + +
    • +

      Locale::Maketext::Gettext

      + +

      這是 GNU gettextPerl Locale::Maketext 多語架構的整合方案。 GNU gettext 的多語化架構,無論是整體設計,完整性和易用性上,無人能出其右,也是目前通用的多語化標準。然而,它也有設計上的缺陷,例如單複數的處理。 Perl 的 Locale::Maketext 在單複數的處理設計上,獨冠群倫,但在整體的設計上,則顯得非常薄弱。 Locale::Maketext::Gettext 是兩者的完美整合方案,合併了各自的優點,也同時擺脫了各自最大的缺陷。現在有了 Locale::Maketext::Gettext ,妳可輕輕鬆鬆,擁抱兩大多語架構的所有優點,再也不用煩惱這些問題囉! ^_*’

      +
    • + +
    • +

      chklinks

      + +

      chklinks 是單執行緒的 Perl 連結檢查程式,用來檢查網站上的超連結有沒有疏漏。

      +
    • + +
    • +

      reslog

      + +

      reslog 是記錄檔的反查程式,用來反查 Apache 記錄檔裏 IP 的主機名稱。查過後,可以套用像 Analog 之類的記錄檔統計程式。妳可以把它當做 Apache HostNameLookups 指令的替代品,每天一次反查當天所有的 IP

      +
    • + +
    • +

      arclog

      + +

      arclog 是記錄檔每月歸檔程式,將記錄檔中,前月的記錄按月份壓縮歸檔,以節省硬碟空間,並避免記錄檔被有心人士破壞。

      + +

      arclog 目前支援 ApacheSyslogNTPApache 1 SSL engine log 及我自己用的括弧 ISO 修正格式五種格式的記錄檔,與 gzipbzip2 兩種壓縮法。很多程式都可以用 Apache 相容記錄檔格式記錄,如 CUPSProFTPDPure-FTPd…等, arclog 也可以歸檔這些 Apache 相容格式的記錄檔。

      +
    • + +
    • +

      flashver

      + +

      這是我寫的第一個 Flash ,可以秀出瀏覽器的 Flash 外掛程式版本。

      +
    • + +
    + + +

    技術教學

    + + + + +

    伺服器相關資料

    + + + + +

    標誌連結區

    + +

    旅舍依瑪伺服器以下列程式建置:

    + +
    +Linux 2.4 | +Debian | +Apache | +mod_perl | +Comprehensive Perl Archive Network | +openssl | +mod_ssl | +Python | +Mailman | +Analog | +Pure-FTPd | +UltraEdit +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/lnxbegin.html.en.html b/htdocs/imacat/tech/lnxbegin.html.en.html new file mode 120000 index 0000000..6c97954 --- /dev/null +++ b/htdocs/imacat/tech/lnxbegin.html.en.html @@ -0,0 +1 @@ +lnxbegin.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/lnxbegin.html.en.xhtml b/htdocs/imacat/tech/lnxbegin.html.en.xhtml new file mode 100644 index 0000000..0949a5b --- /dev/null +++ b/htdocs/imacat/tech/lnxbegin.html.en.xhtml @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + +How to Start Learning Linux As a Beginner? + + + + + + + +
    + +
    + + +

    How to Start Learning Linux As a Beginner?

    + +

    You can always try the following methods to find the answer:

    + +
      +
    1. You can go buy some books. O’Reilly has published many books for UNIX/Linux program packages. Most of them are written by the package authors themselves. They are classical learning materials. Many of these books have Chinese translations. You can go to O’relly Chinese website to look for them. They are available in many book stores, too. You can also go to the web bookstores, like Amazon, TenLong Computer Books, McGraw-Hill, silkbook.com, Book4u, books.com.twetc., to find the book for your needs.
    2. + +
    3. You can go to the libraries. Academic libraries have rich collections, like NTU Library, NTHU Library, NCTU Library, NCU Library, NSYSU Library, CCU Library, NCKU Library, NTUST Library, NTUT Library, FJU Library, CYCU Library, FCU Library, NOU Libraryetc.. You should make the best use of your contributed tuition. There’re still many public libraries, like NCL, NCL ICL, Academia Sinica Library Service, Taipei Public Library, National Taichung Library, Kaohsiung Municipal Libraryetc.. We pay tax to maintain these libraries. We should make best use of them, too.
    4. + +
    5. Many programs have built-in help messages. You can type program --help for these built-in helps.
    6. + +
    7. Most of the UNIX programs, commands, programming language functions and libraries have a single page online manual called manpage. They are often located at /usr/share/man, /usr/man or /usr/local/man. You can query them by typing man program. There are many websites offering web manpage querying services, like Tavern IMACAT’s, fifi.org, Ohio State University, Reino Linux, Linux.gr, Access Internet Communications, Penn State University, DCA-FEEC-Unicampetc..
    8. + +
    9. GNU programs have book-style info documents. Info documents have chapters, sections, links, references, indexes. They are far more structured and detailed than the single-page manpages. Info documents are often located at /usr/share/info, /usr/info or /usr/local/info. You can query them by typing info program.
    10. + +
    11. Many perl programs, libraries have built-in POD (Plain Old Documents) documents. POD is the standard document format of the perl programs. You can query them by typing perldoc file.
    12. + +
    13. Many programs have plain text or HTML documents included in their packages. You can download these packages, uncompress and untar them, and check the instruction in the README file.
    14. + +
    15. Traditionally UNIX has many documents located at /usr/share/doc, /usr/doc or /usr/html. You can check these places for your needed documents.
    16. + +
    17. Linux has a set of HOWTO learning materials. They are usually located at /usr/share/doc or /usr/doc. You can also go to The Linux Documentation Project website to download the newest version of these HOWTO documents.
    18. + +
    19. You can go to the official websites of the program itself. There are many documents and FAQs out there.
    20. + +
    21. You can search your answer on the search engines, like Google, OpenFind, Yam.com, Yahoo!, Lycos, Exciteetc..
    22. + +
    23. Many programs have their users’ mailing list. These mailing lists are built to offer a place for these users to discuss topics, ask and answer questions, offer suggestions and report bugs. Other people might have the same problem with you, too. They might have asked these questions, and these questions might have been answered before. You can check and search the archive of these mailing lists. If you cannot found your answer, you can join these mailing lists and ask for help there.
    24. +
    + +

    Be sure that you have searched all the existing documents, manuals, FAQs, mailing list archives, before you ask some questions to some real persons. It takes time to answer your questions. It’s not fair for the answerers if you are asking questions that are already documented elsewhere, or were answered over and over.

    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/lnxbegin.html.zh-cn.html b/htdocs/imacat/tech/lnxbegin.html.zh-cn.html new file mode 120000 index 0000000..720f6b8 --- /dev/null +++ b/htdocs/imacat/tech/lnxbegin.html.zh-cn.html @@ -0,0 +1 @@ +lnxbegin.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/lnxbegin.html.zh-cn.xhtml b/htdocs/imacat/tech/lnxbegin.html.zh-cn.xhtml new file mode 100644 index 0000000..7be59a5 --- /dev/null +++ b/htdocs/imacat/tech/lnxbegin.html.zh-cn.xhtml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + +新手如何入门学习 Linux ? + + + + + + + +
    + +
    + + +

    新手如何入门学习 Linux ?

    + +

    当你学习 Linux 碰到问题时,可以由以下方式找到答案:

    + +
      +
    1. 你可以去书店买书。 O'Reilly 出版社出了一系列 UNIX/Linux 程式的书,大都是程式原作者写的,是学习 UNIX/Linux 的经典教材。 O'Reilly 很多书都有中译本,译得都很不错,你可以上欧莱礼中文网站查,坊间书店也很容易找得到。此外,你还可以上 Amazon天珑书局麦格罗・希尔新丝路华文网博客来…等网路书店找书。
    2. + +
    3. 你可以上图书馆找书。很多学校图书馆藏书都很丰富,像台大图书馆清大图书馆交大图书馆中央图书馆中山图书馆中正图书馆成大图书馆台科大图书馆北科大图书馆辅大图书馆中原图书馆逢甲图书馆空大图书馆…等等。既然缴了很多学费,就要好好利用。还有很多公共图书馆,像国家图书馆国家图书馆附设资讯图书馆中研院图书馆台北市立图书馆国立台中图书馆高雄市立图书馆…等等图书馆,也是用我们缴的税金去办的,当然也要好好利用。
    4. + +
    5. 大多数的程式都会内建使用说明,你可以输入 程式名称 --help ,查阅这些内建的使用说明。
    6. + +
    7. UNIX 大多数的程式、指令、程式语言函式都有单页的 manpage 线上说明档,通常都存在 /usr/share/man/usr/man/usr/local/man 下,你可以用 man 程式名称 查阅。此外,有很多网站都有线上 manpage 查阅程式,如:旅舍依玛fifi.orgOhio State UniversityReino LinuxLinux.grAccess Internet CommunicationsPenn State UniversityDCA-FEEC-Unicamp …等等。
    8. + +
    9. GNU 的程式会附上另一种 info 说明档。这是一种分大小章节段落的线上说明书,远比单页的 manpage 还要详细完整。 info 说明书通常存在 /usr/share/info/usr/info/usr/local/info 下,你可以用 info 程式名称 查阅。
    10. + +
    11. 很多 Perl 程式、函式库都内建有 Perl 专属的 POD (Plain Old Document) 说明档,你可以用 perldoc 档案名称 查阅。
    12. + +
    13. 很多程式包装中都内含纯文字或 HTML 的完整说明文件,你可以下载解开了以后,看 README 档案里的说明。
    14. + +
    15. 传统的 UNIX 有不少说明文件会存在 /usr/share/doc/usr/doc/usr/html 中,可以在这里面找一找。
    16. + +
    17. Linux 有一种 HOWTO 如何…教学文件,通常存在 /usr/share/doc/usr/doc 下,也可以上 Linux 说明文件计划网站下载最新版的 HOWTO 文件。
    18. + +
    19. 上该程式官方网站上,会有很多说明文件和答客问 FAQ
    20. + +
    21. 上搜寻引擎寻找你要找的问题,如 GoogleOpenFind蕃薯藤Yahoo!LycosExcite …等。
    22. + +
    23. 很多程式都有爱用者通讯 Mailing List ,通常是供该程式使用者互相讨论、问答,并提出建议用的沟通管道。你想问的问题,别人往往也碰过,而且早就问过了。你可以翻阅、搜寻该 Mailing List 的旧信纪录,找找看有没有你想问的问题,别人回答过的。如果没有别人问过,你可以加入该程式的 Mailing List ,向其她使用者请教你的问题。
    24. +
    + +

    记住,请尽量先自己找过现有的说明文件、答客问、旧信归档后,都找不到答案后,再向别人提出问题。回答问题是需要心力的,如果没有先自己试著找答案,同样的问题一问再问,对回答的人也不公平。

    + + +
    依玛猫,初稿 2002-02-02 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/lnxbegin.html.zh-tw.html b/htdocs/imacat/tech/lnxbegin.html.zh-tw.html new file mode 120000 index 0000000..70b1e6b --- /dev/null +++ b/htdocs/imacat/tech/lnxbegin.html.zh-tw.html @@ -0,0 +1 @@ +lnxbegin.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/lnxbegin.html.zh-tw.xhtml b/htdocs/imacat/tech/lnxbegin.html.zh-tw.xhtml new file mode 100644 index 0000000..7701e97 --- /dev/null +++ b/htdocs/imacat/tech/lnxbegin.html.zh-tw.xhtml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + +新手如何入門學習 Linux ? + + + + + + + +
    + +
    + + +

    新手如何入門學習 Linux ?

    + +

    當妳學習 Linux 碰到問題時,可以由以下方式找到答案:

    + +
      +
    1. 妳可以去書店買書。 O'Reilly 出版社出了一系列 UNIX/Linux 程式的書,大都是程式原作者寫的,是學習 UNIX/Linux 的經典教材。 O'Reilly 很多書都有中譯本,譯得都很不錯,妳可以上歐萊禮中文網站查,坊間書店也很容易找得到。此外,妳還可以上 Amazon天瓏書局麥格羅‧希爾新絲路華文網博客來…等網路書店找書。
    2. + +
    3. 妳可以上圖書館找書。很多學校圖書館藏書都很豐富,像臺大圖書館清大圖書館交大圖書館中央圖書館中山圖書館中正圖書館成大圖書館臺科大圖書館北科大圖書館輔大圖書館中原圖書館逢甲圖書館空大圖書館…等等。既然繳了很多學費,就要好好利用。還有很多公共圖書館,像國家圖書館國家圖書館附設資訊圖書館中研院圖書館臺北市立圖書館國立臺中圖書館高雄市立圖書館…等等圖書館,也是用我們繳的稅金去辦的,當然也要好好利用。
    4. + +
    5. 大多數的程式都會內建使用說明,妳可以輸入 程式名稱 --help ,查閱這些內建的使用說明。
    6. + +
    7. UNIX 大多數的程式、指令、程式語言函式都有單頁的 manpage 線上說明檔,通常都存在 /usr/share/man/usr/man/usr/local/man 下,妳可以用 man 程式名稱 查閱。此外,有很多網站都有線上 manpage 查閱程式,如:旅舍依瑪fifi.orgOhio State UniversityReino LinuxLinux.grAccess Internet CommunicationsPenn State UniversityDCA-FEEC-Unicamp …等等。
    8. + +
    9. GNU 的程式會附上另一種 info 說明檔。這是一種分大小章節段落的線上說明書,遠比單頁的 manpage 還要詳細完整。 info 說明書通常存在 /usr/share/info/usr/info/usr/local/info 下,妳可以用 info 程式名稱 查閱。
    10. + +
    11. 很多 Perl 程式、函式庫都內建有 Perl 專屬的 POD (Plain Old Document) 說明檔,妳可以用 perldoc 檔案名稱 查閱。
    12. + +
    13. 很多程式包裝中都內含純文字或 HTML 的完整說明文件,妳可以下載解開了以後,看 README 檔案裡的說明。
    14. + +
    15. 傳統的 UNIX 有不少說明文件會存在 /usr/share/doc/usr/doc/usr/html 中,可以在這裏面找一找。
    16. + +
    17. Linux 有一種 HOWTO 如何…教學文件,通常存在 /usr/share/doc/usr/doc 下,也可以上 Linux 說明文件計劃網站下載最新版的 HOWTO 文件。
    18. + +
    19. 上該程式官方網站上,會有很多說明文件和答客問 FAQ
    20. + +
    21. 上搜尋引擎尋找妳要找的問題,如 GoogleOpenFind蕃薯藤Yahoo!LycosExcite …等。
    22. + +
    23. 很多程式都有愛用者通訊 Mailing List ,通常是供該程式使用者互相討論、問答,並提出建議用的溝通管道。妳想問的問題,別人往往也碰過,而且早就問過了。妳可以翻閱、搜尋該 Mailing List 的舊信紀錄,找找看有沒有妳想問的問題,別人回答過的。如果沒有別人問過,妳可以加入該程式的 Mailing List ,向其她使用者請教妳的問題。
    24. +
    + +

    記住,請儘量先自己找過現有的說明文件、答客問、舊信歸檔後,都找不到答案後,再向別人提出問題。回答問題是需要心力的,如果沒有先自己試著找答案,同樣的問題一問再問,對回答的人也不公平。

    + + +
    依瑪貓,初稿 2002-02-02 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/lnxprint.html.en.html b/htdocs/imacat/tech/lnxprint.html.en.html new file mode 120000 index 0000000..d3f3447 --- /dev/null +++ b/htdocs/imacat/tech/lnxprint.html.en.html @@ -0,0 +1 @@ +lnxprint.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/lnxprint.html.en.xhtml b/htdocs/imacat/tech/lnxprint.html.en.xhtml new file mode 100644 index 0000000..86bb0b1 --- /dev/null +++ b/htdocs/imacat/tech/lnxprint.html.en.xhtml @@ -0,0 +1,897 @@ + + + + + + + + + + + + + + + + + + + + + +How to Print Under Linux? + + + + + + + +
    + +
    + + +

    How to Print Under Linux?

    + +

    Table of Contents

    + + + + +

    Prefix

    + +

    This is a Printing-HOWTO written by me. It was originally a short note, to remind myself of the complicated configuration of printing. Then it became longer and longer, until it finally came to this Linux Printing HOWTO.

    + +

    This article introduces the samba - LPRng - ifhp filter - ghostscript uniprint driver printing model. If you are using other printing packages, the setting procedure may be different.

    + +

    I am the only author of this article. It was not authorized by, nor disscussed with any of these package authors. It is not an official documentation of any package. If you find any bias, error or deficiency, please mail to me. Thanks.

    + + +
    + +

    Quick Installation:

    + +

    If you share this printer only for your windows workstations, or if you are setting a print server for a windows-only network, that you does not really need linux printing, just follow these steps. If you are really setting a linux printing, wanting to print under linux, or if you want to know more about linux printing model, bypass these part.

    + +
      +
    1. +

      Connect Your Printer:

      + +

      Connect your printer to LPT1 and do the following test:

      + +
      +
      +% echo "Hello, world!" >> /dev/lp0
      +
      +
      + +

      Your printer should start working. Eject the paper and see if Hello, world! is properly printed. If it is, proceed to the next step. [1]

      +
    2. + + +
    3. +

      Configure LPRng:

      + +
        +
      1. Download the newest LPRng: http://www.lprng.com/.
      2. + +
      3. Uncompress, compile and install LPRng: + +
        +
        +% tar xzf LPRng-x.x.x.tgz
        +% cd LPRng-3.x.x
        +% ./configure --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man --disable-setuid
        +% make
        +% make test
        +% su
        +$ make install
        +
        +
        +
      4. + +
      5. Set your /etc/printcap as follows: + +
        +
        +# simpliest printcap file for samba client only
        +lp:
        +	:lp=/dev/lp0
        +	:sd=/var/spool/lpd/%P
        +
        +
        +
      6. + +
      7. Test: + +
        +
        +$ checkpc -f
        +$ echo "Hello, world!" | lpr
        +
        +
        + +Your printer should start working. Eject the paper and see if Hello, world! is properly print. If it is, go to next step. [24]
      8. + +
      +
    4. + + +
    5. +

      Configure samba:

      + +
        +
      1. Download and install samba from http://www.samba.org/samba/samba.html. This is out of the scope of this article. Please refer to the samba documentation.
      2. + +
      3. Configure the printer share: set the [printers] section in your /etc/smb.conf (or /usr/local/samba/lib/smb.conf) as follows: + +
        +
        +[printers]
        +	comment = Printers
        +	printable = yes
        +	browsable = no
        +	public = no
        +	valid users = @users
        +
        +	printing = lprng
        +	path = /var/spool/lpd/samba
        +	print command = /usr/bin/lpr -P%p -r %s
        +	lpq command = /usr/bin/lpq -P%p
        +	lprm command = /usr/bin/lprm -P%p %j
        +	lppause command = /usr/sbin/lpc hold %p %j
        +	lpresume command = /usr/sbin/lpc release %p %j
        +	queuepause command = /usr/sbin/lpc -P%p stop
        +	queueresume command = /usr/sbin/lpc -P%p start
        +
        +
        + +Remember to create the directory /var/spool/lpd/samba, with its owner as root and its permission as 1777.
      4. + +
      5. Test: check your smb.conf with testparm, + +
        +
        +$ /usr/local/samba/bin/testparm
        +
        +
        + +If everything is fine, restart your samba. Now you should go back to your windows workstation and reload your network neighborhood. Can you see the printer now? [26]
      6. + +
      +
    6. + +
    7. +

      Install the Remote Printer on Your Windows Workstation:

      + +

      Please refer the windows help and your printer manual for setting your remote printer on your windows workstation. Remember to print a test page to see if everything is OK. [27]

      +
    8. + +
    + +
    + + +

    The Concept of Linux Printing

    + +the linux printing concept + +

    The basic steps of linux printing are stated below:

    + +
      +
    1. Convert all types of target files into a unified PostScript printing format, using their specified xxx2ps PostScript converter according to their original file type.
    2. + +
    3. Send the PostScript output to Ghostscript, the PostScript printer emulator. Ghostscript then converts the received output to the low-level printer language according to the specified printer driver. The final output is then sent to the printer on printer port.
    4. +
    + + +

    The Printing Flow Sheet

    + +

    The dash lines are the path of the Windows/samba printing.

    + +the printing flow sheet + +
      +
    1. The target data is received by samba printer share. (You may pass this step.)
    2. + +
    3. The target data is print with lpr printing command by LPRng. The main configuration file is /etc/printcap.
    4. + +
    5. The target data is then sent to a print filter, such as ifhp. The print filter then call the file command to check the data format and process the data according the result format. The configuration file here is /etc/ifhp.conf.
    6. + +
    7. If the format is not raw data or plain text, the data is then converted to PostScript format using the proper PostScript converter according to its original data format.
    8. + +
    9. Convert the PostScript format data to low-level printer language using Ghostscript PostScript printer emulator (with uniprint), and sent to the printer on the printer port.
    10. +
    + + +

    Configuration Instruction

    + +

    We go bottom-up, step by step:

    + +
      +
    1. +

      Connect Your Printer:

      + +

      Connect your printer to LPT1 and do the following test:

      + +
      +
      +% echo "Hello, world!" >> /dev/lp0
      +
      +
      + +

      Your printer should start working. Eject the paper and see if Hello, world! is properly printed. If it is, proceed to the next step. [1]

      +
    2. + +
    3. +

      Configure Ghostscript, the PostScript Emulator (with uniprint):

      + +

      After you have properly connected your printer and been able to print simple English text directly, we want to print some PostScript documents. If you have a PostScript printer, (which, the, means that you are very rich, or your printer might be owned by the company or the school,) and you can print PostScript documents directly, you can bypass here and proceed to the next step.

      + +

      PostScript is the standard printing document format set up by Adobe, inc. at 1985. It is supported by most laser printers. But I guess yours is a cheap and poor inkjet or dot-matrix printer, so we move on.

      + +

      Ghostscript is a PostScript emulator. With software emulation, it turns a non-PostScript printer to a PostScript printer and print the PostScript format documents. By doing this way, our cheap and poor inkjet printer can then be treated as a deluxe PostScript laser printer. [3]

      + +

      Ghostscript translates PostScript language into all kinds of low-level printer language. The translated result is then sent to the printer. Ghostscripts needs to know all kinds of low-level printer languages, which are the so-called printer drivers. Ghostscript is released with a bunch of printer drivers. But if your printer driver is not inside, you could look for it in the LinuxPrinting printer database and see if someone had written a Ghostscript driver for your printer before. You can then download and ultilize it. You’ll have to recompile Ghostscript unless it is a uniprint driver.

      + +

      Uniprint (Unified Printer Drivers) is a Ghostscript printer driver specification that was originally designed for the Epson Stylus Color printers. It can be downloaded and used directly without recompiling Ghostscript itself. Uniprint drivers have an .upp file name suffix. [4]

      + + +
        +
      1. You’ll have to install zlib, libpng and jpeg first. They are out of the scope of this article. Please refer to their individual installation instruction.
      2. + +
      3. Download the newest Ghostscript: [5] + + + +You also need the Ghostscript fonts: http://www.cs.wisc.edu/~ghost/doc/AFPL/get700.htm.
      4. + +
      5. Uncompress, compile and install Ghostscript: + +
        +
        +% tar xzf gnu-gs-6.52.tar.gz or ghostscript-x.xx.tar.gz
        +% cd gsx.xx
        +% ln -s src/unix-gcc.mak Makefile
        +
        +
        + +Edit the Makefile and modify the installation prefix: + +
        +
        +prefix = /usr
        +
        +
        + +Run make now: + +
        +
        +% make
        +% make test
        +% su
        +$ make install
        +
        +
        + +Then, go to /usr/share/ghostscript/ and uncompress the Ghostscript fonts: + +
        +
        +$ cd /usr/share/ghostscript/
        +$ tar xzf ghostscript-fonts-std-x.x.tar.gz
        +$ tar xzf ghostscript-fonts-other-x.x.tar.gz
        +
        +
        +
      6. + +
      7. Configure your printer type and driver. Check the Ghostscript printer detail for your pinter model name or your uniprint driver name. If you do not find your printer there, you could try to search it in the LinuxPrinting printer database. You’ll need to recompile Ghostscript if your downloaded driver is not a uniprint driver. If it is, you just save it in /usr/share/usr/share/ghostscript/x.xx/, together with other .upp uniprint drivers. That’s all.
      8. + +
      9. Test: There’re some example PostScript files in /usr/share/ghostscript/x.xx/examples/. We will try to print them out. For a non-uniprint printer driver: + +
        +
        +$ cd /usr/share/ghostscript/x.xx/examples/
        +$ gs -sDEVICE=xxxxxxxx -sOutputFile=/dev/lp0 tiger.ps
        +
        +
        + +where xxxxxxxx is your printer model. For unprint, + +
        +
        +$ cd /usr/share/ghostscript/x.xx/examples/
        +$ gs @xxxxxxxx.upp -sOutputFile=/dev/lp0 tiger.ps
        +
        +
        + +where xxxxxxxx.upp is the file name of your uniprint driver. If Ghostscript could read your printer driver, it shall print a giant tiger now. [7] You could put this line as an alias in your ~/.bashrc: + +
        +
        +alias gs="gs -sDEVICE=xxxxxxxx -sOutputFile=/dev/lp0"
        +
        +
        +
      10. +
      +
    4. + + +
    5. +

      Configure All Kinds of xxx2ps PostScript Converters:

      + +

      Now you can print the PostScript documents. If you have a non-PostScript document, you can convert it into PostScript format and print it. There are plenty of PostScript converters for all the existing different file formats. Their installation procedures are rather simple, so I’ll omit them here. Some of the common PostScript converters are listed below:

      + + + +

      Don’t forget to test if you can print the converted PostScript results after you install these converters.

      + +
      +
      +$ echo "Hello, world" | a2ps -o - | gs -
      +$ html2ps < /usr/local/apache/htdocs/index.html | gs -
      +$ gs mypdf.pdf
      +$ giftopnm < mygif.gif | pnmtops | gs -
      +$ jpegtopnm < myjpeg.jpg | pnmtops | gs -
      +$ pngtopnm < mypng.png | pnmtops | gs -
      +$ bmptoppm < mybmp.bmp | pnmtops | gs -
      +$ tifftopnm < mytiff.tif | pnmtops | gs -
      +$ ...
      +
      +
      + +

      From this point on, you could print any file, as long as you can convert it into PostScript format with a proper PostScript converter. We can finally print files now.

      +
    6. + + +
    7. +

      Configure ifhp, the Print Filter:

      + +

      The ability to print files is not enough. For every file we print, we need a different converter. We convert this file here, and convert that file there, here and there, here and there… It’s so troublesome! We need an intelligent agent to automatically check the file type and call the necessary converter. This, is the so-called print filter. The basic of the print filter is very simple. You can try to write one, too, after reading the following illustrations.

      + +

      There are many existing filters. Some of the common ones are: lpdomatic (LPD-O-Matic) [12], tops, magicfilter [13], apsfilter [14] and rhs-printfilters [15]. ifhp is the print filter I’m using, and it is written by the LPRng team themselves, so I use it in the following illustration.

      + + +
        +
      1. Download the newest ifhp: http://www.lprng.com/.
      2. + +
      3. Uncompress, compile and install ifhp: + +
        +
        +% tar xzf ifhp-x.x.x.tgz
        +% cd ifhp-x.x.x
        +% ./configure --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man
        +% make
        +% make test
        +% su
        +$ make install
        +
        +
        + +
      4. + +
      5. Set your /etc/ifhp.conf as follows: + +
          +
        1. Set your printer’s section: Look for your printer’s section [ xxxxxxxx ] inside the /etc/ifhp.conf, where xxxxxxxx is your Ghostscript driver name. If you are using a downloaded driver, you might need to insert a new section by yourself. Take uniprint driver as an example: + +
          +
          +[ xxxxxxxx.upp ]
          +status
          +pjl@
          +pcl@
          +ps@
          +text
          +gs_converter=  \%s{gs_unidriver}
          +gs_device=xxxxxxxx.upp
          +
          +
          + +where xxxxxxxx.upp is the file name of your downloaded uniprint driver. By configuring this way, ifhp can locate your printer settings by the printer name.
        2. + +
        3. Set the file type maping: Insert the following file_output_match settings in the end of your printer section. If these settings already exist, you might have to overwrite them. + +
          +
          +file_output_match = [
          +	*postscript*		raw	\%s{gs_converter}
          +	*text*			text [16]
          +	*01-*			text
          +	*pcl*			filter	\%s{pcl_converter}
          +	*pjl*			filter	\%s{pjl_converter}
          +	*html*			filter	\%s{html_converter}
          +	*pdf*			raw	\%s{pdf_converter}
          +	*37)*			raw	\%s{pdf_converter}
          +	*jpeg*			filter	\%s{jpeg_converter}
          +	*gif*			filter	\%s{gif_converter}
          +	*png*			filter	\%s{png_converter}
          +	*pc_bitmap*		filter	\%s{bmp_converter}
          +	*tiff*			filter	\%s{tiff_converter}
          +	*gzip_compressed*	filter	\%s{gzip_decompress}
          +	*data*			raw
          +]
          +
          +
          + +where \%s{string} will be replace with the previous string= settings. When it comes to print, ifhp will call /usr/bin/file to check the file type. The returned result string will be compared with these patterns, and execute the command at the right side for the matching pattern at the left side. If there’s no more command at the right side for that matching left-side pattern, the data will be treated as the final converted result and sent to the printer directly. For example, + +
          +
          +% file myphoto.jpg
          +myphoto.jpg: JPEG image data, JFIF standard
          +
          +
          + +JPEG image data, JFIF standard matches *jpeg* (case insensitive), so ifhp will call jpeg_converter. You could design your own pattern according to the result string returned by the file command.
        4. + +
        5. Set the converts (xxx_conveter): Look for the line containing a2ps_converter=. Add the following lines below: + +
          +
          +html_converter= /usr/bin/html2ps 2>/dev/null
          +pdf_converter= \%s{gs_converter}
          +jpeg_converter= /usr/bin/jpegtopnm | /usr/bin/pnmtops -noturn[18]
          +gif_converter= /usr/bin/giftopnm | /usr/bin/pnmtops -noturn[19]
          +png_converter= /usr/bin/pngtopnm | /usr/bin/pnmtops -noturn
          +bmp_converter= /usr/bin/bmptoppm | /usr/bin/pnmtops -noturn
          +tiff_converter= /usr/bin/tifftopnm | /usr/bin/pnmtops -noturn
          +
          +
          + +ifhp will execute these commands with I/O pipping: send the source data to their stdin, and obtain their converted result from their stdout.
        6. +
        +
      6. + +
      7. Test: Try to print /tmp/myfile: + +
        +
        +$ /usr/libexec/filters/ifhp -Tdev=/dev/lp0,model=xxxxxxxx < /tmp/myfile
        +
        +
        + +If it is properly printed, your ifhp is ready. [20] We have come to an end at this point. Now we have an intelligent printing program that can print all kinds of files now. You can put the above line in your ~/.bashrc as an alias: + +
        +
        +alias ifhp="/usr/libexec/filters/ifhp -Tdev=/dev/lp0,model=xxxxxxxx"
        +
        +
        + +You can have yourself a cup of coffee and take a rest now. ^_*'
      8. +
      +
    8. + + +
    9. +

      Configure LPRng:

      + +

      We finally have ifhp, an intelligent print filter that can automatically assign the data conversion by file type, and send the finally output to the printer. With this ifhp we could print almost anything. Is that all?

      + +

      Not yet. What we need is far more complicated than a simple printing. We need a set of printer management: Queue the files in a line when several files are printed at the same time, put the important files first in the line, or stop printing when the paper is jamed. Besides, the permission of /dev/lp0 is 0660. It’s not a good idea to grant everyone the privilege to write to /dev/lp0 directly. [21]

      + +

      That’s why we need LPRng, the printer manager, to manage all the print jobs.

      + +
        +
      1. Download the newest LPRng: http://www.lprng.com/.
      2. + +
      3. Uncompress, compile and install LPRng: + +
        +
        +% tar xzf LPRng-x.x.x.tgz
        +% cd LPRng-x.x.x
        +% ./configure --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man --disable-setuid [22]
        +% make
        +% make test
        +% su
        +$ make install
        +
        +
        +
      4. + +
      5. Set your /etc/printcap: [23] If you use ifhp with Ghostscript uniprint driver, exactly the same as what I told you above, (well, nice girl. ^^;) set your /etc/printcap as follows: + +
        +
        +# printcap file for ifhp filter with Ghostprint uniprint driver
        +lp:
        +	:lp=/dev/lp0
        +	:sd=/var/spool/lpd/%P
        +	:ifhp=model=xxxxxxxx
        +	:filter=/usr/libexec/filters/ifhp
        +
        +
        + +%P will be replaced with the printer name, which is the lp: here on the first line. You could change it to a more meaningful name, like hpdj670c or so. The value of :sd= is the print queue directory. Be sure to create this directory if it does not exist. It should be owned by root with permission 1777, like the /tmp directory.
      6. + +
      7. Set your /etc/lpd.perm: /etc/lpd.perm is the configuration file of the printer privileges. lpd is running as root or daemon. We need first restrict the client domain or IP to avoid the security problem. Add the follow lines in the front of /etc/lpd.perm: + +
        +
        +# Reject outsiders by IP. The format is IP or IP/submask
        +REJECT SERVICE=X NOT REMOTEIP=127.0.0.1,192.168.0.0/255.255.0.0
        +# Reject outsiders by domain.
        +REJECT REMOTEHOST=X NOT REMOTEIP=localhost,*.your.domain
        +
        +
        + +If this printer is provided to a limited number of people, we can loosen the privilege to ease the management. Comment out the line ACCEPT SERVICE=C LPC=lpd,status,printcap, and replace with the following one: + +
        +
        +# Loosen the priviledge.  Let users pause/resume their print job.
        +#ACCEPT SERVICE=C LPC=lpd,status,printcap
        +ACCEPT SERVICE=C LPC=lpd,status,printcap,hold,release,stop,start REMOTEGROUP=users
        +
        +
        + +Also, you need to allow the administrator the priviledge to remove the broken print jobs. Locate the line ACCEPT SERVICE=M SERVER REMOTEUSER=root: + +
        +
        +# allow root on server to remove a job
        +ACCEPT SERVICE=M SERVER REMOTEUSER=root
        +ACCEPT SERVICE=M SERVER REMOTEGROUP=lp
        +
        +
        +
      8. + +
      9. Test: Check the settings in /etc/printcap first: + +
        +
        +$ checkpc -f
        +
        +
        + +checkpc -f will check the settings in /etc/printcap for problems, such as non-existing :sd= directory, and correct them at its best. Then, ask lpd to reread the /etc/printcap. + +
        +
        +$ lpc reread
        +
        +
        + +Now print the /tmp/myfile again: + +
        +
        +% lpr /tmp/myfile
        +
        +
        + +If it is properly printed, congratulations! Everything is ready now. ^_*' [24]
      10. +
      + +

      Refer to LPRng-HOWTO for more infomation on how to manage the print jobs with lpr, lprm, lpc, lpq… etc.

      +
    10. + + +
    11. +

      Configure samba: [25]

      + +

      You can bypass the following if you are not going to share this printer for your windows workstations.

      + +
        +
      1. Download and install samba: http://www.samba.org/samba/samba.html. (This is out of the scope of this article. Please refer to the samba documentations.)
      2. + +
      3. Set the printer shares: Set the [printers] section in your /etc/smb/conf (or /usr/local/samba/lib/smb.conf) as follows: + +
        +
        +[printers]
        +	comment = Printers
        +	printable = yes
        +	browsable = no
        +	public = no
        +	valid users = @users
        +
        +	printing = lprng
        +	path = /var/spool/lpd/samba
        +	print command = /usr/bin/lpr -P%p -r %s
        +	lpq command = /usr/bin/lpq -P%p
        +	lprm command = /usr/bin/lprm -P%p %j
        +	lppause command = /usr/sbin/lpc hold %p %j
        +	lpresume command = /usr/sbin/lpc release %p %j
        +	queuepause command = /usr/sbin/lpc -P%p stop
        +	queueresume command = /usr/sbin/lpc -P%p start
        +
        +
        + +Don’t forget to create the directory /var/spool/lpd/samba. It should be owned by root, with privilege 1777.
      4. + +
      5. Test: Test your smb.conf with testparm, + +
        +
        +% /usr/local/samba/bin/testparm
        +
        +
        + +If everything is fine, restart your samba. Now you should go back to your windows workstation and refresh your network neighborhood. Can you see this printer now? [26]
      6. +
      +
    12. + + +
    13. +

      Install the Remote Printer on Your Windows Workstation:

      + +

      Refer to the windows help and your printer’s installation guide. Don’t forget to print a test page and see if it works. [27]

      +
    14. + +
    + + +

    Annotations:

    + +
      +
    1. If you can’t even get the Hellp, world, check the following by order: +
        +
      • Is your printer broken? Is your power cord plugged in? Is your power switch on? Is your printer power light shining? Is your printer warning light flashing? Is your cartridge / toner run out? Is your paper run out? Is there a paper jam?
      • +
      • Is your printer on LPT1? Is the connector properly connected? Is there a bad connection? If your printer is on LPT2, use /dev/lp1 instead; if it is on LPT3, use /dev/lp2, and so on.
      • +
      • If you don’t be sure whether your printer printer is broken, connected it to a windows workstation and see if it works. If this still won’t help, contact the custom service line of your printer manufacturer.
      • +
      +(Back)
    2. + +
    3. As the time goes by, PostScript has become the standard printing document format for unix systems. So far, Adobe has established another standard called PDF (Portable Document Format). (Back)
    4. + + +
    5. It costs CPU, hard disk and memory to do software emulation. But modern CPU are faster than ever. Hard disk and memory prices are also very cheap now. Unless you are running a print server, or you are doing mass printing, you don’t really have to worry about this. If you ever need to do mass printing that might affect the system performance, you should afford a PostScript printer. :p (Back)
    6. + +
    7. Some of the Canon, HP and NEC printers and Sun raster file format use uniprint, too. Because uniprint is more flexable since it doesn’t need a recompilation of the Ghostscript itself, it has become the recommended driver format of the Ghostscript authors. (Back)
    8. + +
    9. Ghostscript was GNU before, that allows limited commercial use. After version 5.50, Ghostscript’s maintainance was transferred to artofcode LLC and Artifex Software Inc. They employ the Aladdin License that disallows the commercial use. This new version of Ghostscript is also called the Aladdin Ghostscript. Artofcode LLC and Artifex Software Inc have released version 6.52 as GNU recently. You can freely select which Ghostscript to use. New versions have less bugs, but we should support GNU packages. However, if you need to use it commercially, you can only select the GNU Ghostscript. For the same reason, most linux distributions, including Red Hat, only come with GNU Ghostscript. (Back)
    10. + +
    11. If you can find your Ghostscript driver at all, you might have to write one yourself, or you’ll have to give up now. :p Refer to the Ghostscript documentation for the Ghostscript driver specification. (Back)
    12. + +
    13. If it doesn’t, refer to the Ghostscript documentation. (Back)
    14. + +
    15. Most printers can print ASCII English text directly. The text does not need to convert to PostScript document with a2ps. However, if you need to use the Chinese fonts to print the Chinese text, or your printer cannot print the ASCII English text directly (which is mostly not possible ^^; ), you will need to convert the text into PostScript document with a2ps before printing. (Back)
    16. + +
    17. Besides, Ghostscript can read PDF directly. You could send PDF files to Ghostscript directly, just like the PostScript files. (Back)
    18. + +
    19. netpbm was formerly PBMPLUS. PBMPLUS was a set of graphic converters, which had stopped maintainance after Dec 10, 1991. At a later time a group of people put the PBMPLUS and several newly collected converters together and make the netpbm package. PBMPLUS and netpbm have established the PNM (Portable aNyMap) intermediate graphic format. People can convert all kinds of graphic files into PNM format, and then convert the PNM data into the target format. Thus, programmers only need to write 2n, instead of n2 converters. This greatly saves the programmers’ works. (Back)
    20. + +
    21. Alternatively, you can use all kinds of direct PostScript converters instead. For example, gif2ps in the libungif package, jpg2ps, imgtops2… etc. But I suggest you to use netpbm, for these converters have their individual problems. The size of a pixel is different for screens than for printers. If no proper adjustments were done, the output result may be too large or too small. gif2ps will adjust the image to the paper size, which may be very handy for large images, but is not a good workaround basically. jpeg2ps can configure the resolution, but it cannot read from /dev/stdin, hence cannot work with print filters. img2ps is merely a wrapper that wraps the jpeg image data with PostScript commands using the new jpeg support in PostScript version 2. It is not really a converter. The advantage of img2ps is that, it won’t uncompress jpeg image data, and thus is faster and the output result size is smaller. But the result resolution is not adjusted. You may get a very large print result at last. On the other hand, netpbm will adjust the resolution, which may be the best solution for now. (Back)
    22. + +
    23. lpdomatic (LPD-O-Matic) was designed to use with the old lpd. It is a widely-used print filter. It contains only a single perl script, thus is very small and simple. lpdomatic needs its own printer drivers. You can look for your driver and download it at the LinuxPrinting printer database. (Back)
    24. + +
    25. I did not find much about magicfilter. From the the infomation I found so far, it seems to be a print filter designed for Debian Linux. (Back)
    26. + +
    27. apsfilter is simple: you choose your printer from a list, and it will do the necessary changes to the configuration files. Many people like it, but not me. I don’t like automatic stuffs. It modifies /etc/printcap by itself; Its documentation is poor; you can only choose the drivers included with Ghostscript, while your downloaded drivers are not available. If you want to use apsfilter, you have to install LPRng first. It is very simple to install apsfilter: Unzip and untar your downloaded .tar.gz tarball into /usr/share/, then go into the apsfilter subdirectory and run ./SETUP. That’s all. (Back)
    28. + +
    29. rhs-printfilters is written by Red Hat Inc. to work with Red Hat Linux. It thus has many users, too. rhs-printfilters has only RPM installation. You have to configure it with printtool. Like the apsfilter, it will do the necessary changes to the configuration files for you. It runs only in X, choose printers from its internal printer list, and modified /etc/printcap by itself: So I hate it, too. :p If you want to use rhs-printfilters, you have to install LPRng first, then rhs-printfilters and printtool. Then, start your X and run printtool to choose your printer. (Back)
    30. + +
    31. Use the following line if you are using a2ps: +
      +
      +	*text*			filter	\%s{a2ps_converter}
      +
      +
      +(Back)
    32. + +
    33. If no matching was found, no printing will be done and ifhp will exit with an error code. (Back)
    34. + +
    35. Use the following line if you are using imgtops2: +
      +
      +jpeg_converter= /usr/bin/imgtops2
      +
      +
      +(Back)
    36. + +
    37. Use the following line if you are using gif2ps: +
      +
      +gif_converter= /usr/bin/gif2ps; exit 0
      +
      +
      +We need to exit 0 because gif2ps exits an error code even for non-critical warnings, which leads ifhp to believe that the conversion was failed and to stop printing. (Back)
    38. + +
    39. If not, debug with the following steps: Write a simple shell script /tmp/send: +
      +
      +#! /bin/sh
      +file=/tmp/myfile
      +ifhp=model=xxxxxxxx
      +cat /dev/null >/tmp/t
      +cat $file | /usr/libexec/filters/ifhp -Tdev=/tmp/t,trace,debug=2,${ifhp} 2> /tmp/trace
      +
      +
      +Run +
      +
      +$ sh -x /tmp/send
      +
      +
      +Review /tmp/trace and see what went wrong. You can enlarge the debug= value (for ex., debug=10) for more detailed debugging infomation. (Back)
    40. + +
    41. Why is printing so complicated? Because printer is a external device, which connects to the host machine with cords and connectors. In order to communicate and do jobs for the host machine, it has to do spooling. Spooling is means to line up in a queue. When jobs may not be run instantly for various reasons (for ex., speed difference, communication problem, disconnection, unstable connection or insufficient memory… etc.) they have to line up in a queue first to wait for their turns. When this happens, you need a queue manager to manage the queue, set its order, pause the queue, or even delete a job from the queue. Mail transference need spooling, too, because it sends messages across different hosts from distance. In fact, the communications between the components of your computer (CD-ROM, floppy, hard disk, memory… etc.) needs spooling, too. But you won’t feel them because they are silently dealed by the internal spooler system. (Back)
    42. + +
    43. Because we can’t grant everyone the privilege to write into /dev/lp0 directly, we need to grant a special privilege to the LPRng. One way is to make lpd setuid-root, but it is relatively dangerous. The other way is run lpd in daemon mode: Start lpd in daemon mode by root. It then turns its user into lp and waits for printing requests from lpr. If you are running lpd in this mode, be sure that the user lp has the privilege to write to /dev/lp0. (Back)
    44. + +
    45. If you are using automatic filters, like apsfilter or rhs-printfilters, you can bypass this part and set up your filter now. (Back)
    46. + +
    47. If not, try: +
      +
      +% lpq -L
      +
      +
      +to check the printer logs. If this still doesn’t help, refer to the LPRng HOWTO for more infomation. (Back)
    48. + +
    49. The printing data from the windows samba clients are already converted into low-level printer language by the windows printer drivers. There’s no necessity (and you shouldn’t) to convert this data again. You should configure the raw data to be sent to the printer on /dev/lp0 directly in your print filter configuration. If you are setting your printer for your windows clients only, you can bypass the print filter entirely and send the printing data directly to the printer. This is described in the front of this document. (Back)
    50. + +
    51. If you cannot see your printer from the network neighborhood, refer to the samba printing documentation. (Back)
    52. + +
    53. If it won’t work, check the printing logs by running lpq -L. (Back)
    54. +
    + + +

    References:

    + +

    Refer to the following addresses for more infomation:

    + + + + +
    by imacat, first written 2001-04-25, last updated 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/lnxprint.html.zh-cn.html b/htdocs/imacat/tech/lnxprint.html.zh-cn.html new file mode 120000 index 0000000..8a3c79d --- /dev/null +++ b/htdocs/imacat/tech/lnxprint.html.zh-cn.html @@ -0,0 +1 @@ +lnxprint.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/lnxprint.html.zh-cn.xhtml b/htdocs/imacat/tech/lnxprint.html.zh-cn.xhtml new file mode 100644 index 0000000..0f64716 --- /dev/null +++ b/htdocs/imacat/tech/lnxprint.html.zh-cn.xhtml @@ -0,0 +1,900 @@ + + + + + + + + + + + + + + + + + + + + + +如何在 Linux 下列印? + + + + + + + +
    + +
    + + +

    如何在 Linux 下列印?

    + +

    目录

    + + + + +

    前言

    + +

    这是我自己写的「如何列印」,原本只是一篇小笔记,因为设定印表机的过程很累很复杂,为了怕我自己日久生疏,而写给自己看的。后来越写越长,写成了完整的 Linux 列印设定教学。

    + +

    本文是采用 samba - LPRng - ifhp filter - ghostscript uniprint 驱动程式搭配的列印架构。如果你是用别的搭配方式,设定会有所不同。

    + +

    本文作者是我一个人,未曾受过各个列印程式作者的授权,也未曾和各个作者讨论,内文所述不能代表各列印程式的正式文件。本文或有疏失、遗漏、偏颇、错误之处,还请不吝告知,谢谢。

    + + +
    + +

    零、最最快速的安装说明:

    + +

    如果你只是要把印表机分享给 Windows 工作站用,或只是要设定一个 Windows 工作站用的 print server ,完全不要在 Linux 下印表,请依下列步骤。如果你真的是要「在 Linux 下设定印表机」,要在 Linux 下列印,或想更深入了解 Linux 下列印的架构,请跳过这一段。

    + +
      +
    1. +

      接好印表机:

      + +

      把印表机接到 LPT1 ,做下述测试:

      + +
      +
      +% echo "Hello, world!" >> /dev/lp0
      +
      +
      + +

      如果印表机有反应,把整张纸退出,看看「 Hello, world! 」有没有印出来。如果一切正常,继续下一步。[1]

      +
    2. + + +
    3. +

      安装设定 LPRng :

      + +
        +
      1. 下载最新版的 LPRng : +http://www.lprng.com/
      2. + +
      3. 解压缩、编译安装 LPRng : + +
        +
        +% tar xzf LPRng-x.x.x.tgz
        +% cd LPRng-3.x.x
        +% ./configure --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man --disable-setuid
        +% make
        +% make test
        +% su
        +$ make install
        +
        +
        +
      4. + +
      5. 设定 /etc/printcap 如下: + +
        +
        +# 最简化的 printcap 设定,只给 samba 客户端列印使用
        +lp:
        +	:lp=/dev/lp0
        +	:sd=/var/spool/lpd/%P
        +
        +
        +
      6. + +
      7. 测试: + +
        +
        +$ checkpc -f
        +$ echo "Hello, world!" | lpr
        +
        +
        + +这时印表机应该会有反应。把整张纸退出,看看「 Hello, world! 」有没有印出来。如果一切正常,继续下一步。[24]
      8. + +
      +
    4. + + +
    5. +

      安装设定 samba :

      + +
        +
      1. 下载、安装 samba : http://www.samba.org/samba/samba.html 。(这不在本文的范围内,请自行参考 samba 的安装设定说明。)
      2. + +
      3. 设定列印分享:在 /etc/smb.conf (或 /usr/local/samba/lib/smb.conf ), [printers] 节中设定如下: + +
        +
        +[printers]
        +	comment = Printers
        +	printable = yes
        +	browsable = no
        +	public = no
        +	valid users = @users
        +
        +	printing = lprng
        +	path = /var/spool/lpd/samba
        +	print command = /usr/bin/lpr -P%p -r %s
        +	lpq command = /usr/bin/lpq -P%p
        +	lprm command = /usr/bin/lprm -P%p %j
        +	lppause command = /usr/sbin/lpc hold %p %j
        +	lpresume command = /usr/sbin/lpc release %p %j
        +	queuepause command = /usr/sbin/lpc -P%p stop
        +	queueresume command = /usr/sbin/lpc -P%p start
        +
        +
        + +存档后,记得要开一个 /var/spool/lpd/samba 的目录,拥有者是 root ,权限是 1777 。
      4. + +
      5. 测试:用 testparm 检查 smb.conf , + +
        +
        +$ /usr/local/samba/bin/testparm
        +
        +
        + +如果没有问题,重开 samba ,回到 Windows 工作站,从网路上的芳邻中重新整理,看看能不能看得到这台印表机。[26]
      6. + +
      +
    6. + + +
    7. +

      安装设定 Windows 下的网路印表机:

      + +

      这部份请参考 Windows 的说明,和印表机说明书的安装设定说明。记得要印一张测试页,测试看看。[27]

      +
    8. + +
    + +
    + + +

    一、 Linux 列印基本概念

    + +Linux 列印基本概念 style="float: right;" /> + +

    Linux 列印的基本做法如下:

    + +
      +
    1. 依要列印的档案的类型,以各种不同的 xxx2ps PostScript 转换程式,统一转为列印专用的标准 PostScript 格式。
    2. + +
    3. 将转换后的 PostScript 格式资料传送给 PostScript 印表机模拟程式 Ghostscript 。 Ghostscript 配合印表机的驱动程式,将 PostScript 格式资料再转为低阶印表机指令,传送给印表机埠上的印表机。
    4. +
    + + +

    二、实际列印流程

    + +

    图中虚线为 Windows / samba 网路印表机列印资料传送流程。

    + +Linux 列印流程 + +
      +
    1. 由 samba 列印分享送出资料。(可省略。)
    2. + +
    3. 由 LPRng 列印程式( lpr )列印档案,主要设定档为 /etc/printcap 。
    4. + +
    5. 由 ifhp 或其她列印滤镜( filter )配合 file ,判断档案类型后分别处理,设定档为 /etc/ifhp.conf 。
    6. + +
    7. 若不是 raw 或纯文字等可以直接列印的档案格式,则由各种 PostScript 转换程式统一转为 PostScript 格式。
    8. + +
    9. 由 Ghostscript (with uniprint) PostScript 印表机模拟器处理 PostScript 格式的资料,转为低阶印表指令印出。
    10. +
    + + +

    三、设定指南

    + +

    我们从最下层往上设定起:

    + +
      +
    1. +

      接好印表机:

      + +

      把印表机接到 LPT1 ,做下述测试:

      + +
      +
      +% echo "Hello, world!" >> /dev/lp0
      +
      +
      + +

      如果印表机有反应,把整张纸退出,看看「 Hello, world! 」有没有印出来。如果一切正常,继续下一步。[1]

      +
    2. + +
    3. +

      安装 PostScript 印表机模拟器 Ghostscript (with uniprint) :

      + +

      印表机硬体通讯传输一切正常,可以直接列印英文后,接下来我们要让她列印 PostScript 文件。如果你的印表机本身就是 PostScript 印表机,(那你一定非常有钱,不然就是在公司或学校电算中心,)可以直接列印 PostScript ,可以跳过这一段。

      + +

      PostScript 是列印专用的文件格式,是 1985 年由 Adobe 制定的。[2] 大多数雷射印表机都可以直接列印 PostScript 文件。不过我想你和我的便宜喷墨(或点矩阵)印表机,应该都办不到,所以我们继续往下看。

      + +

      Ghostscript 是 PostScript 印表机模拟程式,透过软体模拟,可以让非 PostScript 印表机,也能印出 PostScript 文件。如此一来,就可以把我们的廉价印表机,当成贵贵的 PostScript 印表机来用了。[3]

      + +

      Ghostscript 的工作是转译印表指令,将 PostScript 指令,转译成各种印表机专用的低阶列印指令,送印表机执行。因此, Ghostscript 需要知道各种印表机的指令语言。这就是所谓的「驱动程式」。有的印表机 Ghostscript 有随附驱动程式,有的没有。没有随附驱动程式的时候,你可以上 LinuxPrinting 印表机资料库找,有没有别人写过你印表机的 Ghostscript 驱动程式,下载来用。除非是 uniprint 驱动程式,否则下载后,要再重新编译 Ghostscript 。

      + +

      uniprint (Unified Printer Drivers) 原先是设计给 Epson Stylus Color 系列的一种 Ghostscript 驱动程式规格,下载后可以直接存档使用,不用重新编译 Ghostscript 。 uniprint 驱动程式的附档名是 .upp 。[4]

      + + +
        +
      1. 安装 Ghostscript 前要先安装 zliblibpngjpeg 。这些不在本文范围内,请参考各自的安装说明。
      2. + +
      3. 下载最新版的 Ghostscript :[5] + + + +下载时,要连同 Ghostscript 字型一起下载安装: http://www.cs.wisc.edu/~ghost/doc/AFPL/get700.htm
      4. + +
      5. 解压缩、编译安装 Ghostscript : + +
        +
        +% tar xzf gnu-gs-6.52.tar.gz 或 ghostscript-x.xx.tar.gz
        +% cd gsx.xx
        +% ln -s src/unix-gcc.mak Makefile
        +
        +
        + +编辑 Makefile ,修改安装的位置: + +
        +
        +prefix = /usr
        +
        +
        + +接著安装: + +
        +
        +% make
        +% make test
        +% su
        +$ make install
        +
        +
        + +然后,到 /usr/share/ghostscript/ 下,解压缩 Ghostscript 字型: + +
        +
        +$ cd /usr/share/ghostscript/
        +$ tar xzf ghostscript-fonts-std-x.x.tar.gz
        +$ tar xzf ghostscript-fonts-other-x.x.tar.gz
        +
        +
        +
      6. + +
      7. 设定你的印表机型号和驱动程式。请查 Ghostscript 印表机说明,找到你印表机的代号,或是你印表机的 uniprint 驱动程式名称。如果没有,你可以上 LinuxPrinting 印表机资料库找别人写的驱动程式。[6] 下载驱动程式后,如果不是 uniprint ,你要重新编译 Ghostscript ;否则,只要存到 /usr/share/ghostscript/x.xx/ 下,和其她 .upp 驱动程式存在一起,就可以了。
      8. + +
      9. 测试: /usr/share/ghostscript/x.xx/examples/ 下有一些 PostScript 范例档,我们来印看看。如果你的印表机不是 uniprint 驱动程式, + +
        +
        +$ cd /usr/share/ghostscript/x.xx/examples/
        +$ gs -sDEVICE=xxxxxxxx -sOutputFile=/dev/lp0 tiger.ps
        +
        +
        + +xxxxxxxx 是你印表机的代号;如果是 uniprint , + +
        +
        +$ cd /usr/share/ghostscript/x.xx/examples/
        +$ gs @xxxxxxxx.upp -sOutputFile=/dev/lp0 tiger.ps
        +
        +
        + +xxxxxxxx.upp 是 uniprint 驱动程式档名。如果 Ghostscript 可以顺利读到驱动程式,就会印出一只大老虎了。[7] 你可以把这一行设定成 alias ,加在 ~/.bashrc 下: + +
        +
        +alias gs="gs -sDEVICE=xxxxxxxx -sOutputFile=/dev/lp0"
        +
        +
        + +
      10. +
      +
    4. + + +
    5. +

      安装各种 xxx2ps PostScript 转换程式:

      + +

      可以列印 PostScript 后,要印其她的档案,只要统一转为 PostScript ,就可以印了。 PostScript 的转换程式很多也很琐碎,安装设定都很简单,在这里就不详述了。以下列出几种常见的 xxx2ps PostScript 转换程式:

      + + + +

      安装完后,记得要测试转换后的 PostScript 档能不能印。

      + +
      +
      +$ echo "Hello, world" | a2ps -o - | gs -
      +$ html2ps < /usr/local/apache/htdocs/index.html | gs -
      +$ gs mypdf.pdf
      +$ giftopnm < mygif.gif | pnmtops | gs -
      +$ jpegtopnm < myjpeg.jpg | pnmtops | gs -
      +$ pngtopnm < mypng.png | pnmtops | gs -
      +$ bmptoppm < mybmp.bmp | pnmtops | gs -
      +$ tifftopnm < mytiff.tif | pnmtops | gs -
      +$ ...
      +
      +
      + +

      以后要列印,只要用 PostScript 转换程式转为 PostScript ,就一切 OK 罗。到此,我们已经可以「列印」了。不管要印什么,都通行无阻。

      +
    6. + + +
    7. +

      安装设定列印资料滤镜 ifhp filter :

      + +

      可以列印还不够。印不同的档案,要跑不同的转换程式,把档案格式转来转去。这样太麻烦了。我们需要一个智慧型程式,自动判断档案类型,呼叫要用的转换程式。这就是 filter 列印资料滤镜。 filter 的原理其实很简单,有兴趣的话,看完以下的说明,你也可以自己写一个试试看。

      + +

      现成的 filter 有很多,比较普遍的如 lpdomatic (LPD-O-Matic)[12]topsmagicfilter[13]apsfilter[14]rhs-printfilters[15] …等等。 ifhp 是 LPRng 同一个 team 写的 filter ,我自己用的是 ifhp ,所以以下以 ifhp 来说明:

      + +
        +
      1. 下载最新版的 ifhp : http://www.lprng.com/
      2. + +
      3. 解压缩、编译安装 ifhp : + +
        +
        +% tar xzf ifhp-x.x.x.tgz
        +% cd ifhp-x.x.x
        +% ./configure --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man
        +% make
        +% make test
        +% su
        +$ make install
        +
        +
        + +
      4. + +
      5. 设定 /etc/ifhp.conf 档: + +
          +
        1. 设定你的印表机那一节:打开 /etc/ifhp.conf 档,找找看有没有你的印表机那一节 [ xxxxxxxx ] , xxxxxxxx 是你的印表机的 Ghostscript 驱动程式名称。如果你是下载的驱动程式,那你要自己新增一节。以 uniprint 驱动程式为例: + +
          +
          +[ xxxxxxxx.upp ]
          +status
          +pjl@
          +pcl@
          +ps@
          +text
          +gs_converter=  \%s{gs_unidriver}
          +gs_device=xxxxxxxx.upp
          +
          +
          + +xxxxxxxx.upp 是你下载的 uniprint 驱动程式档名。这样 ifhp 才能从你指定的印表机代号,找到你的印表机该如何设定。
        2. + +
        3. 设定档案类型的对应表:在你印表机的那一节最后面,加上以下file_output_match 的设定(或盖掉原来的 file_output_match 设定): + +
          +
          +file_output_match = [
          +	*postscript*		raw	\%s{gs_converter}
          +	*text*			text [16]
          +	*01-*			text
          +	*pcl*			filter	\%s{pcl_converter}
          +	*pjl*			filter	\%s{pjl_converter}
          +	*html*			filter	\%s{html_converter}
          +	*pdf*			raw	\%s{pdf_converter}
          +	*37)*			raw	\%s{pdf_converter}
          +	*jpeg*			filter	\%s{jpeg_converter}
          +	*gif*			filter	\%s{gif_converter}
          +	*png*			filter	\%s{png_converter}
          +	*pc_bitmap*		filter	\%s{bmp_converter}
          +	*tiff*			filter	\%s{tiff_converter}
          +	*gzip_compressed*	filter	\%s{gzip_decompress}
          +	*data*			raw
          +]
          +
          +
          + +\%s{string} 会被代换为之前 string= 设定的字串。列印时, ifhp 会呼叫 /usr/bin/file 判断档案类型,从传回来的结果字串,和这些样式比对,如果符合,就执行后面设定的指令。[17] 如果后面没有指令了,就当成最终转换结果送出。例如: + +
          +
          +% file myphoto.jpg
          +myphoto.jpg: JPEG image data, JFIF standard
          +
          +
          + +"JPEG image data, JFIF standard" 符合 *jpeg* (不分大小写),於是就执行 jpeg_converter 。你可以依 file 执行传回的结果字串,设计新样式。
        4. + +
        5. 设定转换程式(各种 xxx_converter ):找到 a2ps_converter= 那一行,在下面加上这几行: + +
          +
          +html_converter= /usr/bin/html2ps 2>/dev/null
          +pdf_converter= \%s{gs_converter}
          +jpeg_converter= /usr/bin/jpegtopnm | /usr/bin/pnmtops -noturn[18]
          +gif_converter= /usr/bin/giftopnm | /usr/bin/pnmtops -noturn[19]
          +png_converter= /usr/bin/pngtopnm | /usr/bin/pnmtops -noturn
          +bmp_converter= /usr/bin/bmptoppm | /usr/bin/pnmtops -noturn
          +tiff_converter= /usr/bin/tifftopnm | /usr/bin/pnmtops -noturn
          +
          +
          + +执行时, ifhp 会用 pipe 输出入重导 (|) ,从标准输入 stdin 传入原始档案,而从标准输出 stdout 取得转换结果。
        6. +
        +
      6. + +
      7. 测试:列印 /tmp/myfile , + +
        +
        +$ /usr/libexec/filters/ifhp -Tdev=/dev/lp0,model=xxxxxxxx < /tmp/myfile
        +
        +
        + +如果印出来没问题, ifhp 就设定好了。[20] 到此,可以告一个段落,我们终於有了一个智慧型的列印程式,可以自动视情况列印各种档案了。你可以把上面那一行设定成 alias ,加在 ~/.bashrc 下: + +
        +
        +alias ifhp="/usr/libexec/filters/ifhp -Tdev=/dev/lp0,model=xxxxxxxx"
        +
        +
        + +然后喝杯咖啡,休息一下。 ^_*'
      8. +
      +
    8. + + +
    9. +

      安装设定 LPRng :

      + +

      我们终於有了一个智慧型列印资料滤镜 ifhp ,可以自动视情况分配档案格式的转换工作,再把最终结果送到印表机。只要用 ifhp ,要印什么都可以印了。总算结束了吧?

      + +

      还没有。列印工作远比想像中复杂。不只要能印,还要能「管理」:同时要印好几个档案的时候,你要让档案排队列印,或是把重要的档案抽出来先印,还要把送错了的档案取消掉,或是在卡纸的时候,暂停列印。更何况, /dev/lp0 的权限是 660 ,我们不可能让每个人都有权限,直接写到 /dev/lp0 去。[21]

      + +

      所以我们需要列印管理程式 LPRng ,管理所有的列印工作。

      + +
        +
      1. 下载最新版的 LPRng : http://www.lprng.com/
      2. + +
      3. 解压缩、编译安装 LPRng : + +
        +
        +% tar xzf LPRng-x.x.x.tgz
        +% cd LPRng-x.x.x
        +% ./configure --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man --disable-setuid[22]
        +% make
        +% make test
        +% su
        +$ make install
        +
        +
        +
      4. + +
      5. 设定 /etc/printcap 档:[23] 若是你乖乖照我说的,以 ifhp 配合 Ghostscript uniprint 的话,(你还真听话啊… ^^; ) /etc/printcap 设定如下: + +
        +
        +# 配合 ifhp filter 和 Ghostscript uniprint 驱动程式的 printcap
        +lp:
        +	:lp=/dev/lp0
        +	:sd=/var/spool/lpd/%P
        +	:ifhp=model=xxxxxxxx
        +	:filter=/usr/libexec/filters/ifhp
        +
        +
        + +%P 是指印表机的名称,也就是第一行设定的 lp: 。你可以把印表机名称改成你比较好记的名字,如 HPDJ670C 。 :sd= 设定的是列印伫列存放的目录,如果还没有建好这个目录,要记得去 mkdir 。拥有者是 root ,权限最好和 /tmp 一样是 1777 。
      6. + +
      7. 设定 /etc/lpd.perm 档: /etc/lpd.perm 设定的是列印管理的权限。我们首先要限制 IP 或 domain name ,避免系统安全漏洞。(别忘记 lpd 的权限是 root 或 daemon !)在最前面加上: + +
        +
        +# 限制可连线的 IP ,格式是 IP 或 IP/子网路遮罩
        +REJECT SERVICE=X NOT REMOTEIP=127.0.0.1,192.168.0.0/255.255.0.0
        +# 限制可连线的网域。
        +REJECT REMOTEHOST=X NOT REMOTEIP=localhost,*.your.domain
        +
        +
        + +如果使用者都是身边的熟人,把权限放松一点,给大家方便。把 "ACCEPT SERVICE=C LPC=lpd,status,printcap" 这一行去掉,改成: + +
        +
        +# 给大家方便,让大家自己暂停∕继续
        +#ACCEPT SERVICE=C LPC=lpd,status,printcap
        +ACCEPT SERVICE=C LPC=lpd,status,printcap,hold,release,stop,start REMOTEGROUP=users
        +
        +
        + +另外,要让管理者可以删掉印坏的文件。找到 "ACCEPT SERVICE=M SERVER REMOTEUSER=root" 那一行: + +
        +
        +# allow root on server to remove a job
        +ACCEPT SERVICE=M SERVER REMOTEUSER=root
        +ACCEPT SERVICE=M SERVER REMOTEGROUP=lp
        +
        +
        +
      8. + +
      9. 测试:先测试 /etc/printcap 的设定有没有问题: + +
        +
        +$ checkpc -f
        +
        +
        + +checkpc -f 会检查 printcap 的设定,如果有什么问题,例如 :sd= 的目录不存在,会试著自动修正。检查过没问题后,重读 /etc/printcap 档: + +
        +
        +$ lpc reread
        +
        +
        + +这时再列印看看 /tmp/myfile : + +
        +
        +% lpr /tmp/myfile
        +
        +
        + +如果没有问题,一切就大功告成罗! ^_*'[24]
      10. +
      + +

      关於如何利用 lpr 、 lprm 、 lpc 、 lpq …来管理列印工作,请参考 LPRng-HOWTO 的说明。

      + +
    10. + + +
    11. +

      安装设定 samba :[25]

      + +

      如果你没有要把这台印表机分享其她 Windows 工作站来用,可以不必看这一段。

      + +
        +
      1. 下载、安装 samba : http://www.samba.org/samba/samba.html 。(这不在本文的范围内,请自行参考 samba 的安装设定说明。)
      2. + +
      3. 设定列印分享:在 /etc/smb.conf (或 /usr/local/samba/lib/smb.conf ), [printers] 节中设定如下: + +
        +
        +[printers]
        +	comment = Printers
        +	printable = yes
        +	browsable = no
        +	public = no
        +	valid users = @users
        +
        +	printing = lprng
        +	path = /var/spool/lpd/samba
        +	print command = /usr/bin/lpr -P%p -r %s
        +	lpq command = /usr/bin/lpq -P%p
        +	lprm command = /usr/bin/lprm -P%p %j
        +	lppause command = /usr/sbin/lpc hold %p %j
        +	lpresume command = /usr/sbin/lpc release %p %j
        +	queuepause command = /usr/sbin/lpc -P%p stop
        +	queueresume command = /usr/sbin/lpc -P%p start
        +
        +
        + +存档后,记得要开一个 /var/spool/lpd/samba 的目录,拥有者是 root ,权限是 1777 。
      4. + +
      5. 测试:用 testparm 检查 smb.conf 设定有没有问题, + +
        +
        +% /usr/local/samba/bin/testparm
        +
        +
        + +如果没有问题,重开 samba ,回到 Windows 工作站,从网路上的芳邻中重新整理,看看能不能看得到这台印表机。[26]
      6. +
      +
    12. + + +
    13. +

      安装设定 Windows 下的网路印表机:

      + +

      这部份请参考 Windows 的说明,和印表机说明书的安装设定说明。记得要印一张测试页,测试看看。[27]

      +
    14. + +
    + + +

    四、注释

    + +
      +
    1. 如果连「 Hello, world 」都看不到,请依序检查下列事项: +
        +
      • 检查印表机没有坏掉,电源有没有接上,开关有没有打开,灯有没有亮,警告灯有没有在闪,墨水(或碳粉匣∕色带)是不是用完了,有没有放纸,有没有卡纸。
      • +
      • 检查印表机是不是接在 LPT1 ,排线有没有接好,有没有接触不良。如果印表机接在 LPT2 ,请改用 /dev/lp1 ,如果在 LPT3 ,请改用 /dev/lp2 ,以下类推。
      • +
      • 如果不知道印表机有没有坏,请重新接回 Windows 的电脑,试试看可不可以印。再不行,打电话给印表机厂商的客服专线。
      • +
      +(回正文)
    2. + +
    3. 随著时代的转变, PostScript 成了 Unix 下列印的标准文件格式。那个时代的电脑和印表机都很贵。后来 Adobe 又制定了 PDF (Portable Document Format) 可携式文件格式。 (回正文)
    4. + +
    5. 用软体模拟,会吃 CPU 、硬碟和记忆体。不过现在的 CPU 都跑得很快,硬碟超便宜,记忆体的价格也还可以,除非你要跑 print server ,或需要大量列印,否则影响不会很大。不过,如果你真的需要大量列印,大到会影响整体系统效能,说实话,我觉得你应该买得起 PostScript 印表机了。 :p (回正文)
    6. + +
    7. 少部份 Canon 、 HP 、 NEC 印表机和 Sun raster 档案也使用 uniprint 。因为 uniprint 下载后不需重新编译 Ghostscript ,弹性大,成为 Ghostscript 小组推广的新标准。 (回正文)
    8. + +
    9. Ghostscript 原本采用 GNU 公共版权,允许有限度商业使用;自 5.50 版以后,改由 artofcode LLC 和 Artifex Software Inc. 负责维护,采 Aladdin 公共版权,禁止商业使用,故又称 Aladdin Ghostscript 。最近 artofcode LLC 和 Artifex Software Inc. 又开放出 6.52 版的 Ghostscript 版权。你可以视需要决定要用哪个版本的 Ghostscript 。新版 bug 比较少,不过我们应该支持开放的版本。如果你要商业使用,只能用 GNU Ghostscript 。也因为这个理由, Red Hat 和许多 Linux 只能搭配发行 GNU Ghostscript 6.52 。 (回正文)
    10. + +
    11. 如果找不到 Ghostscript 的驱动程式,那你可能得要自己写,不然只好死心了。 :p Ghostscript 的驱动程式规格请看 Ghostscript 说明(回正文)
    12. + +
    13. 如果有问题,请参考 Ghostscript 说明(回正文)
    14. + +
    15. 一般情况下,印表机大多可以直接列印英文纯文字,不需要特别麻烦 a2ps 转为 PostScript 。不过如果你要印中文,要用到中文字型,或是印表机无法直接列印英文纯文字(这…不大可能吧? ^^;),就要先以 a2ps 转成 PostScript ,才能列印。 (回正文)
    16. + +
    17. 而且 Ghostscript 本身可直接读取 PDF , PDF 可以比照 PostScript 直接交给 Ghostscript 列印。 (回正文)
    18. + +
    19. netpbm 前身是 PBMPLUS ,是一组转换图档的小程式,已经於 1991 年 12 月 10 日停止维护。 后来的人把原先的 PBMPLUS ,加上零零散散搜集来,许多人新写的转换程式,整理成 netpbm 。 PBMPLUS 和 netpbm 制定了图档转换专用的 PNM ( Portable aNyMap )中介格式,先把图档统一转成 PNM ,再转成想要的格式,这样只要写 2n 个转换程式,不必写 n2 个,大大节省写程式的力气。 (回正文)
    20. + +
    21. 你也可以分别用各种直接转换 PostScript 的程式,如附在 libungif 中的 gif2ps 、 jpg2psimgtops2 …等等,不过她们转换后的图案大小都有点问题,目前我还是建议使用netpbm 。因为萤幕和印表机的解析度不同,如果不做好比例微调,印出来的大小会有问题。 gif2ps 转换时会把图案调整到和纸张一样大,原图太大的时候很方便,但不算是很好的作法。 jpeg2ps 可以设定解析度,可是无法从标准输入 /dev/stdin 读取图案,无法和 filter 列印资料滤镜搭配。 imgtops2 其实是包装程式 wrapper ,利用 PostScript 第二版新增的 jpeg 功能,将图案资讯直接加上 PostScript 指令后输出,不算转换程式,优点是速度快,得到的档案比较小,可是解析度有问题,印出来很大。比较起来, netpbm 会自动调整解析度,是目前比较好的选择。(回正文)
    22. + +
    23. lpdomatic (LPD-O-Matic) 是设计来和早期的 lpd 搭配用的,很多人使用,程式很小很简单,只有一个 perl script 。 lpdomatic 需要自己的印表机驱动程式,你可以到 LinuxPrinting 印表机资料库寻找下载。 (回正文)
    24. + +
    25. 关於 magicfilter 我找到的文件不多,就目前的资料看来,是专为 Debian Linux 设计的 filter 。 (回正文)
    26. + +
    27. 很多人都用 apsfilter ,可以从选单选印表机,自动改相关的设定档,设定简单;不过我不喜欢,因为太自动化了,会自己去乱改 /etc/printcap ,说明又不够清楚,而且只能选 Ghostscript 随附的驱动程式,无法新增自己下载的驱动程式。如果你用 apsfilter ,要先装 LPRng ,才能装 apsfilter 。安装 apsfilter 很简单,把下载的 .tar.gz 档解压缩在 /usr/share/ ,进去执行 ./SETUP 就可以了。 (回正文)
    28. + +
    29. rhs-printfilters 是 Red Hat 写的,搭配 Red Hat Linux 发行,因此使用者也很多。 rhs-printfilters 只有 RPM 版,要用 printtool 来设定。 printtool 像 apsfilter 一样,会自动帮你改相关的设定档,不过只能在 X-Window 下执行,只能从选单中选印表机,还会乱改 /etc/printcap ,太自动化了,我也敬而远之。 :p 如果你用 rhs-printfilter ,要先装 LPRng ,再装 rhs-printfilter ,最后装 printtool ,然后进入 X 下,执行 printtool 选印表机。(回正文)
    30. + +
    31. 如果你要用 a2ps ,请改用以下的设定: +
      +
      +	*text*			filter	\%s{a2ps_converter}
      +
      +
      +(回正文)
    32. + +
    33. 如果找不到符合的, ifhp 就不会印了,传回错误后结束。 (回正文)
    34. + +
    35. 如果你要用 imgtops2 ,请改用以下的设定: +
      +
      +jpeg_converter= /usr/bin/imgtops2
      +
      +
      +(回正文)
    36. + +
    37. 如果你要用 gif2ps ,请改用以下的设定: +
      +
      +gif_converter= /usr/bin/gif2ps; exit 0
      +
      +
      +exit 0 是因为 gif2ps 会把不严重的警告也以错误值传回, ifhp 会误判为转换失败,就不会印了。 (回正文)
    38. + +
    39. 如果没有印出来,依下述方式侦错:写一个简单 script /tmp/send : +
      +
      +#! /bin/sh
      +file=/tmp/myfile
      +ifhp=model=xxxxxxxx
      +cat /dev/null >/tmp/t
      +cat $file | /usr/libexec/filters/ifhp -Tdev=/tmp/t,trace,debug=2,${ifhp} 2> /tmp/trace
      +
      +
      +执行: +
      +
      +$ sh -x /tmp/send
      +
      +
      +仔细看看 /tmp/trace ,找到问题的原因。你可以把 debug= 的值设大一点(如 debug=10 ),以得到更详细的侦错资讯。 (回正文)
    40. + +
    41. 为什么列印会这么复杂?因为印表机是外部装置。既然不在机壳里面,要靠线路连接,那要和主电脑通讯、执行工作,就会有伫列 spooling 的问题。伫列是一种排队,在工作因为各种不同的原因(如执行速度太慢、通讯速度太慢、通讯中断或不稳、记忆体不足…等),无法全部送到对方去执行时,就要先排队,等排到的时候再送过去执行。这时候,就要能管理、设定先后次序、暂停、甚至删除排队中的工作。传送 E-mail 因为牵涉到不同的主机之间讯息相互传递,也是一个需要伫列 spooling 的系统。其实机壳里面的各个部份(光碟机、软碟机、硬碟机、记忆体…等)之间也会有伫列的问题,不过几乎都自动处理掉了,所以我们感觉不到。 (回正文)
    42. + +
    43. 因为我们不能让每个人都有权限写入 /dev/lp0 ,所以我们要给 LPRng 特殊权限。一个方法是把 lpd 设成 setuid root ,不过会有安全的顾虑。另一个方法是让 lpd 执行 daemon 模式,以 root 的权限启动,转为 daemon ,等待 lpr 呼叫,再来列印。 daemon 的帐号一定要有权限写入 /dev/lp0 。 (回正文)
    44. + +
    45. 如果你是用「自动化」的 filter (如 apsfilter 或 rhs-printfilters ),现在可以安装设定 filter 了,跳过以下的设定。 (回正文)
    46. + +
    47. 如果 lpr 印不出来,你可以执行: +
      +
      +% lpq -L
      +
      +
      +检查列印记录。若还是不行,请参考 LPRng HOWTO 的说明。 (回正文)
    48. + +
    49. 由 Windows samba 客户端传来的资料,事先经过 Windows 驱动程式转为低阶印表指令,不需(也不可)再做资料转换,在 filter 中需设定以 raw 直接传送至印表机 /dev/lp0 。若印表机只给 Windows 客户端列印,则可完全不设 filter ,直接由 LPRng 转送给印表机,设定方式如最前面 所述。 (回正文)
    50. + +
    51. 如果从网路上的芳邻看有问题,请参考 samba 列印说明(回正文)
    52. + +
    53. 如果印不出来,请检查 lpq -L 的列印记录。 (回正文)
    54. +
    + + +

    五、参考资料

    + +

    更进一步的资料请参考下列网址:

    + + + + +
    依玛猫,初稿 2001-04-25 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/lnxprint.html.zh-tw.html b/htdocs/imacat/tech/lnxprint.html.zh-tw.html new file mode 120000 index 0000000..0987246 --- /dev/null +++ b/htdocs/imacat/tech/lnxprint.html.zh-tw.html @@ -0,0 +1 @@ +lnxprint.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/lnxprint.html.zh-tw.xhtml b/htdocs/imacat/tech/lnxprint.html.zh-tw.xhtml new file mode 100644 index 0000000..19bbc5b --- /dev/null +++ b/htdocs/imacat/tech/lnxprint.html.zh-tw.xhtml @@ -0,0 +1,900 @@ + + + + + + + + + + + + + + + + + + + + + +如何在 Linux 下列印? + + + + + + + +
    + +
    + + +

    如何在 Linux 下列印?

    + +

    目錄

    + + + + +

    前言

    + +

    這是我自己寫的「如何列印」,原本只是一篇小筆記,因為設定印表機的過程很累很複雜,為了怕我自己日久生疏,而寫給自己看的。後來越寫越長,寫成了完整的 Linux 列印設定教學。

    + +

    本文是採用 samba - LPRng - ifhp filter - ghostscript uniprint 驅動程式搭配的列印架構。如果妳是用別的搭配方式,設定會有所不同。

    + +

    本文作者是我一個人,未曾受過各個列印程式作者的授權,也未曾和各個作者討論,內文所述不能代表各列印程式的正式文件。本文或有疏失、遺漏、偏頗、錯誤之處,還請不吝告知,謝謝。

    + + +
    + +

    零、最最快速的安裝說明:

    + +

    如果妳只是要把印表機分享給 Windows 工作站用,或只是要設定一個 Windows 工作站用的 print server ,完全不要在 Linux 下印表,請依下列步驟。如果妳真的是要「在 Linux 下設定印表機」,要在 Linux 下列印,或想更深入瞭解 Linux 下列印的架構,請跳過這一段。

    + +
      +
    1. +

      接好印表機:

      + +

      把印表機接到 LPT1 ,做下述測試:

      + +
      +
      +% echo "Hello, world!" >> /dev/lp0
      +
      +
      + +

      如果印表機有反應,把整張紙退出,看看「 Hello, world! 」有沒有印出來。如果一切正常,繼續下一步。[1]

      +
    2. + + +
    3. +

      安裝設定 LPRng :

      + +
        +
      1. 下載最新版的 LPRng : +http://www.lprng.com/
      2. + +
      3. 解壓縮、編譯安裝 LPRng : + +
        +
        +% tar xzf LPRng-x.x.x.tgz
        +% cd LPRng-3.x.x
        +% ./configure --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man --disable-setuid
        +% make
        +% make test
        +% su
        +$ make install
        +
        +
        +
      4. + +
      5. 設定 /etc/printcap 如下: + +
        +
        +# 最簡化的 printcap 設定,只給 samba 客戶端列印使用
        +lp:
        +	:lp=/dev/lp0
        +	:sd=/var/spool/lpd/%P
        +
        +
        +
      6. + +
      7. 測試: + +
        +
        +$ checkpc -f
        +$ echo "Hello, world!" | lpr
        +
        +
        + +這時印表機應該會有反應。把整張紙退出,看看「 Hello, world! 」有沒有印出來。如果一切正常,繼續下一步。[24]
      8. + +
      +
    4. + + +
    5. +

      安裝設定 samba :

      + +
        +
      1. 下載、安裝 samba : http://www.samba.org/samba/samba.html 。(這不在本文的範圍內,請自行參考 samba 的安裝設定說明。)
      2. + +
      3. 設定列印分享:在 /etc/smb.conf (或 /usr/local/samba/lib/smb.conf ), [printers] 節中設定如下: + +
        +
        +[printers]
        +	comment = Printers
        +	printable = yes
        +	browsable = no
        +	public = no
        +	valid users = @users
        +
        +	printing = lprng
        +	path = /var/spool/lpd/samba
        +	print command = /usr/bin/lpr -P%p -r %s
        +	lpq command = /usr/bin/lpq -P%p
        +	lprm command = /usr/bin/lprm -P%p %j
        +	lppause command = /usr/sbin/lpc hold %p %j
        +	lpresume command = /usr/sbin/lpc release %p %j
        +	queuepause command = /usr/sbin/lpc -P%p stop
        +	queueresume command = /usr/sbin/lpc -P%p start
        +
        +
        + +存檔後,記得要開一個 /var/spool/lpd/samba 的目錄,擁有者是 root ,權限是 1777 。
      4. + +
      5. 測試:用 testparm 檢查 smb.conf , + +
        +
        +$ /usr/local/samba/bin/testparm
        +
        +
        + +如果沒有問題,重開 samba ,回到 Windows 工作站,從網路上的芳鄰中重新整理,看看能不能看得到這臺印表機。[26]
      6. + +
      +
    6. + + +
    7. +

      安裝設定 Windows 下的網路印表機:

      + +

      這部份請參考 Windows 的說明,和印表機說明書的安裝設定說明。記得要印一張測試頁,測試看看。[27]

      +
    8. + +
    + +
    + + +

    一、 Linux 列印基本概念

    + +Linux 列印基本概念 style="float: right;" /> + +

    Linux 列印的基本做法如下:

    + +
      +
    1. 依要列印的檔案的類型,以各種不同的 xxx2ps PostScript 轉換程式,統一轉為列印專用的標準 PostScript 格式。
    2. + +
    3. 將轉換後的 PostScript 格式資料傳送給 PostScript 印表機模擬程式 Ghostscript 。 Ghostscript 配合印表機的驅動程式,將 PostScript 格式資料再轉為低階印表機指令,傳送給印表機埠上的印表機。
    4. +
    + + +

    二、實際列印流程

    + +

    圖中虛線為 Windows / samba 網路印表機列印資料傳送流程。

    + +Linux 列印流程 + +
      +
    1. 由 samba 列印分享送出資料。(可省略。)
    2. + +
    3. 由 LPRng 列印程式( lpr )列印檔案,主要設定檔為 /etc/printcap 。
    4. + +
    5. 由 ifhp 或其她列印濾鏡( filter )配合 file ,判斷檔案類型後分別處理,設定檔為 /etc/ifhp.conf 。
    6. + +
    7. 若不是 raw 或純文字等可以直接列印的檔案格式,則由各種 PostScript 轉換程式統一轉為 PostScript 格式。
    8. + +
    9. 由 Ghostscript (with uniprint) PostScript 印表機模擬器處理 PostScript 格式的資料,轉為低階印表指令印出。
    10. +
    + + +

    三、設定指南

    + +

    我們從最下層往上設定起:

    + +
      +
    1. +

      接好印表機:

      + +

      把印表機接到 LPT1 ,做下述測試:

      + +
      +
      +% echo "Hello, world!" >> /dev/lp0
      +
      +
      + +

      如果印表機有反應,把整張紙退出,看看「 Hello, world! 」有沒有印出來。如果一切正常,繼續下一步。[1]

      +
    2. + +
    3. +

      安裝 PostScript 印表機模擬器 Ghostscript (with uniprint) :

      + +

      印表機硬體通訊傳輸一切正常,可以直接列印英文後,接下來我們要讓她列印 PostScript 文件。如果妳的印表機本身就是 PostScript 印表機,(那妳一定非常有錢,不然就是在公司或學校電算中心,)可以直接列印 PostScript ,可以跳過這一段。

      + +

      PostScript 是列印專用的文件格式,是 1985 年由 Adobe 制定的。[2] 大多數雷射印表機都可以直接列印 PostScript 文件。不過我想妳和我的便宜噴墨(或點矩陣)印表機,應該都辦不到,所以我們繼續往下看。

      + +

      Ghostscript 是 PostScript 印表機模擬程式,透過軟體模擬,可以讓非 PostScript 印表機,也能印出 PostScript 文件。如此一來,就可以把我們的廉價印表機,當成貴貴的 PostScript 印表機來用了。[3]

      + +

      Ghostscript 的工作是轉譯印表指令,將 PostScript 指令,轉譯成各種印表機專用的低階列印指令,送印表機執行。因此, Ghostscript 需要知道各種印表機的指令語言。這就是所謂的「驅動程式」。有的印表機 Ghostscript 有隨附驅動程式,有的沒有。沒有隨附驅動程式的時候,妳可以上 LinuxPrinting 印表機資料庫找,有沒有別人寫過妳印表機的 Ghostscript 驅動程式,下載來用。除非是 uniprint 驅動程式,否則下載後,要再重新編譯 Ghostscript 。

      + +

      uniprint (Unified Printer Drivers) 原先是設計給 Epson Stylus Color 系列的一種 Ghostscript 驅動程式規格,下載後可以直接存檔使用,不用重新編譯 Ghostscript 。 uniprint 驅動程式的附檔名是 .upp 。[4]

      + + +
        +
      1. 安裝 Ghostscript 前要先安裝 zliblibpngjpeg 。這些不在本文範圍內,請參考各自的安裝說明。
      2. + +
      3. 下載最新版的 Ghostscript :[5] + + + +下載時,要連同 Ghostscript 字型一起下載安裝: http://www.cs.wisc.edu/~ghost/doc/AFPL/get700.htm
      4. + +
      5. 解壓縮、編譯安裝 Ghostscript : + +
        +
        +% tar xzf gnu-gs-6.52.tar.gz 或 ghostscript-x.xx.tar.gz
        +% cd gsx.xx
        +% ln -s src/unix-gcc.mak Makefile
        +
        +
        + +編輯 Makefile ,修改安裝的位置: + +
        +
        +prefix = /usr
        +
        +
        + +接著安裝: + +
        +
        +% make
        +% make test
        +% su
        +$ make install
        +
        +
        + +然後,到 /usr/share/ghostscript/ 下,解壓縮 Ghostscript 字型: + +
        +
        +$ cd /usr/share/ghostscript/
        +$ tar xzf ghostscript-fonts-std-x.x.tar.gz
        +$ tar xzf ghostscript-fonts-other-x.x.tar.gz
        +
        +
        +
      6. + +
      7. 設定妳的印表機型號和驅動程式。請查 Ghostscript 印表機說明,找到妳印表機的代號,或是妳印表機的 uniprint 驅動程式名稱。如果沒有,妳可以上 LinuxPrinting 印表機資料庫找別人寫的驅動程式。[6] 下載驅動程式後,如果不是 uniprint ,妳要重新編譯 Ghostscript ;否則,只要存到 /usr/share/ghostscript/x.xx/ 下,和其她 .upp 驅動程式存在一起,就可以了。
      8. + +
      9. 測試: /usr/share/ghostscript/x.xx/examples/ 下有一些 PostScript 範例檔,我們來印看看。如果妳的印表機不是 uniprint 驅動程式, + +
        +
        +$ cd /usr/share/ghostscript/x.xx/examples/
        +$ gs -sDEVICE=xxxxxxxx -sOutputFile=/dev/lp0 tiger.ps
        +
        +
        + +xxxxxxxx 是妳印表機的代號;如果是 uniprint , + +
        +
        +$ cd /usr/share/ghostscript/x.xx/examples/
        +$ gs @xxxxxxxx.upp -sOutputFile=/dev/lp0 tiger.ps
        +
        +
        + +xxxxxxxx.upp 是 uniprint 驅動程式檔名。如果 Ghostscript 可以順利讀到驅動程式,就會印出一隻大老虎了。[7] 妳可以把這一行設定成 alias ,加在 ~/.bashrc 下: + +
        +
        +alias gs="gs -sDEVICE=xxxxxxxx -sOutputFile=/dev/lp0"
        +
        +
        + +
      10. +
      +
    4. + + +
    5. +

      安裝各種 xxx2ps PostScript 轉換程式:

      + +

      可以列印 PostScript 後,要印其她的檔案,只要統一轉為 PostScript ,就可以印了。 PostScript 的轉換程式很多也很瑣碎,安裝設定都很簡單,在這裏就不詳述了。以下列出幾種常見的 xxx2ps PostScript 轉換程式:

      + + + +

      安裝完後,記得要測試轉換後的 PostScript 檔能不能印。

      + +
      +
      +$ echo "Hello, world" | a2ps -o - | gs -
      +$ html2ps < /usr/local/apache/htdocs/index.html | gs -
      +$ gs mypdf.pdf
      +$ giftopnm < mygif.gif | pnmtops | gs -
      +$ jpegtopnm < myjpeg.jpg | pnmtops | gs -
      +$ pngtopnm < mypng.png | pnmtops | gs -
      +$ bmptoppm < mybmp.bmp | pnmtops | gs -
      +$ tifftopnm < mytiff.tif | pnmtops | gs -
      +$ ...
      +
      +
      + +

      以後要列印,只要用 PostScript 轉換程式轉為 PostScript ,就一切 OK 囉。到此,我們已經可以「列印」了。不管要印什麼,都通行無阻。

      +
    6. + + +
    7. +

      安裝設定列印資料濾鏡 ifhp filter :

      + +

      可以列印還不夠。印不同的檔案,要跑不同的轉換程式,把檔案格式轉來轉去。這樣太麻煩了。我們需要一個智慧型程式,自動判斷檔案類型,呼叫要用的轉換程式。這就是 filter 列印資料濾鏡。 filter 的原理其實很簡單,有興趣的話,看完以下的說明,妳也可以自己寫一個試試看。

      + +

      現成的 filter 有很多,比較普遍的如 lpdomatic (LPD-O-Matic)[12]topsmagicfilter[13]apsfilter[14]rhs-printfilters[15] …等等。 ifhp 是 LPRng 同一個 team 寫的 filter ,我自己用的是 ifhp ,所以以下以 ifhp 來說明:

      + +
        +
      1. 下載最新版的 ifhp : http://www.lprng.com/
      2. + +
      3. 解壓縮、編譯安裝 ifhp : + +
        +
        +% tar xzf ifhp-x.x.x.tgz
        +% cd ifhp-x.x.x
        +% ./configure --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man
        +% make
        +% make test
        +% su
        +$ make install
        +
        +
        + +
      4. + +
      5. 設定 /etc/ifhp.conf 檔: + +
          +
        1. 設定妳的印表機那一節:打開 /etc/ifhp.conf 檔,找找看有沒有妳的印表機那一節 [ xxxxxxxx ] , xxxxxxxx 是妳的印表機的 Ghostscript 驅動程式名稱。如果妳是下載的驅動程式,那妳要自己新增一節。以 uniprint 驅動程式為例: + +
          +
          +[ xxxxxxxx.upp ]
          +status
          +pjl@
          +pcl@
          +ps@
          +text
          +gs_converter=  \%s{gs_unidriver}
          +gs_device=xxxxxxxx.upp
          +
          +
          + +xxxxxxxx.upp 是妳下載的 uniprint 驅動程式檔名。這樣 ifhp 才能從妳指定的印表機代號,找到妳的印表機該如何設定。
        2. + +
        3. 設定檔案類型的對應表:在妳印表機的那一節最後面,加上以下file_output_match 的設定(或蓋掉原來的 file_output_match 設定): + +
          +
          +file_output_match = [
          +	*postscript*		raw	\%s{gs_converter}
          +	*text*			text [16]
          +	*01-*			text
          +	*pcl*			filter	\%s{pcl_converter}
          +	*pjl*			filter	\%s{pjl_converter}
          +	*html*			filter	\%s{html_converter}
          +	*pdf*			raw	\%s{pdf_converter}
          +	*37)*			raw	\%s{pdf_converter}
          +	*jpeg*			filter	\%s{jpeg_converter}
          +	*gif*			filter	\%s{gif_converter}
          +	*png*			filter	\%s{png_converter}
          +	*pc_bitmap*		filter	\%s{bmp_converter}
          +	*tiff*			filter	\%s{tiff_converter}
          +	*gzip_compressed*	filter	\%s{gzip_decompress}
          +	*data*			raw
          +]
          +
          +
          + +\%s{string} 會被代換為之前 string= 設定的字串。列印時, ifhp 會呼叫 /usr/bin/file 判斷檔案類型,從傳回來的結果字串,和這些樣式比對,如果符合,就執行後面設定的指令。[17] 如果後面沒有指令了,就當成最終轉換結果送出。例如: + +
          +
          +% file myphoto.jpg
          +myphoto.jpg: JPEG image data, JFIF standard
          +
          +
          + +"JPEG image data, JFIF standard" 符合 *jpeg* (不分大小寫),於是就執行 jpeg_converter 。妳可以依 file 執行傳回的結果字串,設計新樣式。
        4. + +
        5. 設定轉換程式(各種 xxx_converter ):找到 a2ps_converter= 那一行,在下面加上這幾行: + +
          +
          +html_converter= /usr/bin/html2ps 2>/dev/null
          +pdf_converter= \%s{gs_converter}
          +jpeg_converter= /usr/bin/jpegtopnm | /usr/bin/pnmtops -noturn[18]
          +gif_converter= /usr/bin/giftopnm | /usr/bin/pnmtops -noturn[19]
          +png_converter= /usr/bin/pngtopnm | /usr/bin/pnmtops -noturn
          +bmp_converter= /usr/bin/bmptoppm | /usr/bin/pnmtops -noturn
          +tiff_converter= /usr/bin/tifftopnm | /usr/bin/pnmtops -noturn
          +
          +
          + +執行時, ifhp 會用 pipe 輸出入重導 (|) ,從標準輸入 stdin 傳入原始檔案,而從標準輸出 stdout 取得轉換結果。
        6. +
        +
      6. + +
      7. 測試:列印 /tmp/myfile , + +
        +
        +$ /usr/libexec/filters/ifhp -Tdev=/dev/lp0,model=xxxxxxxx < /tmp/myfile
        +
        +
        + +如果印出來沒問題, ifhp 就設定好了。[20] 到此,可以告一個段落,我們終於有了一個智慧型的列印程式,可以自動視情況列印各種檔案了。妳可以把上面那一行設定成 alias ,加在 ~/.bashrc 下: + +
        +
        +alias ifhp="/usr/libexec/filters/ifhp -Tdev=/dev/lp0,model=xxxxxxxx"
        +
        +
        + +然後喝杯咖啡,休息一下。 ^_*'
      8. +
      +
    8. + + +
    9. +

      安裝設定 LPRng :

      + +

      我們終於有了一個智慧型列印資料濾鏡 ifhp ,可以自動視情況分配檔案格式的轉換工作,再把最終結果送到印表機。只要用 ifhp ,要印什麼都可以印了。總算結束了吧?

      + +

      還沒有。列印工作遠比想像中複雜。不只要能印,還要能「管理」:同時要印好幾個檔案的時候,妳要讓檔案排隊列印,或是把重要的檔案抽出來先印,還要把送錯了的檔案取消掉,或是在卡紙的時候,暫停列印。更何況, /dev/lp0 的權限是 660 ,我們不可能讓每個人都有權限,直接寫到 /dev/lp0 去。[21]

      + +

      所以我們需要列印管理程式 LPRng ,管理所有的列印工作。

      + +
        +
      1. 下載最新版的 LPRng : http://www.lprng.com/
      2. + +
      3. 解壓縮、編譯安裝 LPRng : + +
        +
        +% tar xzf LPRng-x.x.x.tgz
        +% cd LPRng-x.x.x
        +% ./configure --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man --disable-setuid[22]
        +% make
        +% make test
        +% su
        +$ make install
        +
        +
        +
      4. + +
      5. 設定 /etc/printcap 檔:[23] 若是妳乖乖照我說的,以 ifhp 配合 Ghostscript uniprint 的話,(妳還真聽話啊… ^^; ) /etc/printcap 設定如下: + +
        +
        +# 配合 ifhp filter 和 Ghostscript uniprint 驅動程式的 printcap
        +lp:
        +	:lp=/dev/lp0
        +	:sd=/var/spool/lpd/%P
        +	:ifhp=model=xxxxxxxx
        +	:filter=/usr/libexec/filters/ifhp
        +
        +
        + +%P 是指印表機的名稱,也就是第一行設定的 lp: 。妳可以把印表機名稱改成妳比較好記的名字,如 HPDJ670C 。 :sd= 設定的是列印佇列存放的目錄,如果還沒有建好這個目錄,要記得去 mkdir 。擁有者是 root ,權限最好和 /tmp 一樣是 1777 。
      6. + +
      7. 設定 /etc/lpd.perm 檔: /etc/lpd.perm 設定的是列印管理的權限。我們首先要限制 IP 或 domain name ,避免系統安全漏洞。(別忘記 lpd 的權限是 root 或 daemon !)在最前面加上: + +
        +
        +# 限制可連線的 IP ,格式是 IP 或 IP/子網路遮罩
        +REJECT SERVICE=X NOT REMOTEIP=127.0.0.1,192.168.0.0/255.255.0.0
        +# 限制可連線的網域。
        +REJECT REMOTEHOST=X NOT REMOTEIP=localhost,*.your.domain
        +
        +
        + +如果使用者都是身邊的熟人,把權限放鬆一點,給大家方便。把 "ACCEPT SERVICE=C LPC=lpd,status,printcap" 這一行去掉,改成: + +
        +
        +# 給大家方便,讓大家自己暫停∕繼續
        +#ACCEPT SERVICE=C LPC=lpd,status,printcap
        +ACCEPT SERVICE=C LPC=lpd,status,printcap,hold,release,stop,start REMOTEGROUP=users
        +
        +
        + +另外,要讓管理者可以刪掉印壞的文件。找到 "ACCEPT SERVICE=M SERVER REMOTEUSER=root" 那一行: + +
        +
        +# allow root on server to remove a job
        +ACCEPT SERVICE=M SERVER REMOTEUSER=root
        +ACCEPT SERVICE=M SERVER REMOTEGROUP=lp
        +
        +
        +
      8. + +
      9. 測試:先測試 /etc/printcap 的設定有沒有問題: + +
        +
        +$ checkpc -f
        +
        +
        + +checkpc -f 會檢查 printcap 的設定,如果有什麼問題,例如 :sd= 的目錄不存在,會試著自動修正。檢查過沒問題後,重讀 /etc/printcap 檔: + +
        +
        +$ lpc reread
        +
        +
        + +這時再列印看看 /tmp/myfile : + +
        +
        +% lpr /tmp/myfile
        +
        +
        + +如果沒有問題,一切就大功告成囉! ^_*'[24]
      10. +
      + +

      關於如何利用 lpr 、 lprm 、 lpc 、 lpq …來管理列印工作,請參考 LPRng-HOWTO 的說明。

      + +
    10. + + +
    11. +

      安裝設定 samba :[25]

      + +

      如果妳沒有要把這臺印表機分享其她 Windows 工作站來用,可以不必看這一段。

      + +
        +
      1. 下載、安裝 samba : http://www.samba.org/samba/samba.html 。(這不在本文的範圍內,請自行參考 samba 的安裝設定說明。)
      2. + +
      3. 設定列印分享:在 /etc/smb.conf (或 /usr/local/samba/lib/smb.conf ), [printers] 節中設定如下: + +
        +
        +[printers]
        +	comment = Printers
        +	printable = yes
        +	browsable = no
        +	public = no
        +	valid users = @users
        +
        +	printing = lprng
        +	path = /var/spool/lpd/samba
        +	print command = /usr/bin/lpr -P%p -r %s
        +	lpq command = /usr/bin/lpq -P%p
        +	lprm command = /usr/bin/lprm -P%p %j
        +	lppause command = /usr/sbin/lpc hold %p %j
        +	lpresume command = /usr/sbin/lpc release %p %j
        +	queuepause command = /usr/sbin/lpc -P%p stop
        +	queueresume command = /usr/sbin/lpc -P%p start
        +
        +
        + +存檔後,記得要開一個 /var/spool/lpd/samba 的目錄,擁有者是 root ,權限是 1777 。
      4. + +
      5. 測試:用 testparm 檢查 smb.conf 設定有沒有問題, + +
        +
        +% /usr/local/samba/bin/testparm
        +
        +
        + +如果沒有問題,重開 samba ,回到 Windows 工作站,從網路上的芳鄰中重新整理,看看能不能看得到這臺印表機。[26]
      6. +
      +
    12. + + +
    13. +

      安裝設定 Windows 下的網路印表機:

      + +

      這部份請參考 Windows 的說明,和印表機說明書的安裝設定說明。記得要印一張測試頁,測試看看。[27]

      +
    14. + +
    + + +

    四、註釋

    + +
      +
    1. 如果連「 Hello, world 」都看不到,請依序檢查下列事項: +
        +
      • 檢查印表機沒有壞掉,電源有沒有接上,開關有沒有打開,燈有沒有亮,警告燈有沒有在閃,墨水(或碳粉匣∕色帶)是不是用完了,有沒有放紙,有沒有卡紙。
      • +
      • 檢查印表機是不是接在 LPT1 ,排線有沒有接好,有沒有接觸不良。如果印表機接在 LPT2 ,請改用 /dev/lp1 ,如果在 LPT3 ,請改用 /dev/lp2 ,以下類推。
      • +
      • 如果不知道印表機有沒有壞,請重新接回 Windows 的電腦,試試看可不可以印。再不行,打電話給印表機廠商的客服專線。
      • +
      +(回正文)
    2. + +
    3. 隨著時代的轉變, PostScript 成了 Unix 下列印的標準文件格式。那個時代的電腦和印表機都很貴。後來 Adobe 又制定了 PDF (Portable Document Format) 可攜式文件格式。 (回正文)
    4. + +
    5. 用軟體模擬,會吃 CPU 、硬碟和記憶體。不過現在的 CPU 都跑得很快,硬碟超便宜,記憶體的價格也還可以,除非妳要跑 print server ,或需要大量列印,否則影響不會很大。不過,如果妳真的需要大量列印,大到會影響整體系統效能,說實話,我覺得妳應該買得起 PostScript 印表機了。 :p (回正文)
    6. + +
    7. 少部份 Canon 、 HP 、 NEC 印表機和 Sun raster 檔案也使用 uniprint 。因為 uniprint 下載後不需重新編譯 Ghostscript ,彈性大,成為 Ghostscript 小組推廣的新標準。 (回正文)
    8. + +
    9. Ghostscript 原本採用 GNU 公共版權,允許有限度商業使用;自 5.50 版以後,改由 artofcode LLC 和 Artifex Software Inc. 負責維護,採 Aladdin 公共版權,禁止商業使用,故又稱 Aladdin Ghostscript 。最近 artofcode LLC 和 Artifex Software Inc. 又開放出 6.52 版的 Ghostscript 版權。妳可以視需要決定要用哪個版本的 Ghostscript 。新版 bug 比較少,不過我們應該支持開放的版本。如果妳要商業使用,只能用 GNU Ghostscript 。也因為這個理由, Red Hat 和許多 Linux 只能搭配發行 GNU Ghostscript 6.52 。 (回正文)
    10. + +
    11. 如果找不到 Ghostscript 的驅動程式,那妳可能得要自己寫,不然只好死心了。 :p Ghostscript 的驅動程式規格請看 Ghostscript 說明(回正文)
    12. + +
    13. 如果有問題,請參考 Ghostscript 說明(回正文)
    14. + +
    15. 一般情況下,印表機大多可以直接列印英文純文字,不需要特別麻煩 a2ps 轉為 PostScript 。不過如果妳要印中文,要用到中文字型,或是印表機無法直接列印英文純文字(這…不大可能吧? ^^;),就要先以 a2ps 轉成 PostScript ,才能列印。 (回正文)
    16. + +
    17. 而且 Ghostscript 本身可直接讀取 PDF , PDF 可以比照 PostScript 直接交給 Ghostscript 列印。 (回正文)
    18. + +
    19. netpbm 前身是 PBMPLUS ,是一組轉換圖檔的小程式,已經於 1991 年 12 月 10 日停止維護。 後來的人把原先的 PBMPLUS ,加上零零散散蒐集來,許多人新寫的轉換程式,整理成 netpbm 。 PBMPLUS 和 netpbm 制定了圖檔轉換專用的 PNM ( Portable aNyMap )中介格式,先把圖檔統一轉成 PNM ,再轉成想要的格式,這樣只要寫 2n 個轉換程式,不必寫 n2 個,大大節省寫程式的力氣。 (回正文)
    20. + +
    21. 妳也可以分別用各種直接轉換 PostScript 的程式,如附在 libungif 中的 gif2ps 、 jpg2psimgtops2 …等等,不過她們轉換後的圖案大小都有點問題,目前我還是建議使用netpbm 。因為螢幕和印表機的解析度不同,如果不做好比例微調,印出來的大小會有問題。 gif2ps 轉換時會把圖案調整到和紙張一樣大,原圖太大的時候很方便,但不算是很好的作法。 jpeg2ps 可以設定解析度,可是無法從標準輸入 /dev/stdin 讀取圖案,無法和 filter 列印資料濾鏡搭配。 imgtops2 其實是包裝程式 wrapper ,利用 PostScript 第二版新增的 jpeg 功能,將圖案資訊直接加上 PostScript 指令後輸出,不算轉換程式,優點是速度快,得到的檔案比較小,可是解析度有問題,印出來很大。比較起來, netpbm 會自動調整解析度,是目前比較好的選擇。(回正文)
    22. + +
    23. lpdomatic (LPD-O-Matic) 是設計來和早期的 lpd 搭配用的,很多人使用,程式很小很簡單,只有一個 perl script 。 lpdomatic 需要自己的印表機驅動程式,妳可以到 LinuxPrinting 印表機資料庫尋找下載。 (回正文)
    24. + +
    25. 關於 magicfilter 我找到的文件不多,就目前的資料看來,是專為 Debian Linux 設計的 filter 。 (回正文)
    26. + +
    27. 很多人都用 apsfilter ,可以從選單選印表機,自動改相關的設定檔,設定簡單;不過我不喜歡,因為太自動化了,會自己去亂改 /etc/printcap ,說明又不夠清楚,而且只能選 Ghostscript 隨附的驅動程式,無法新增自己下載的驅動程式。如果妳用 apsfilter ,要先裝 LPRng ,才能裝 apsfilter 。安裝 apsfilter 很簡單,把下載的 .tar.gz 檔解壓縮在 /usr/share/ ,進去執行 ./SETUP 就可以了。 (回正文)
    28. + +
    29. rhs-printfilters 是 Red Hat 寫的,搭配 Red Hat Linux 發行,因此使用者也很多。 rhs-printfilters 只有 RPM 版,要用 printtool 來設定。 printtool 像 apsfilter 一樣,會自動幫妳改相關的設定檔,不過只能在 X-Window 下執行,只能從選單中選印表機,還會亂改 /etc/printcap ,太自動化了,我也敬而遠之。 :p 如果妳用 rhs-printfilter ,要先裝 LPRng ,再裝 rhs-printfilter ,最後裝 printtool ,然後進入 X 下,執行 printtool 選印表機。(回正文)
    30. + +
    31. 如果妳要用 a2ps ,請改用以下的設定: +
      +
      +	*text*			filter	\%s{a2ps_converter}
      +
      +
      +(回正文)
    32. + +
    33. 如果找不到符合的, ifhp 就不會印了,傳回錯誤後結束。 (回正文)
    34. + +
    35. 如果妳要用 imgtops2 ,請改用以下的設定: +
      +
      +jpeg_converter= /usr/bin/imgtops2
      +
      +
      +(回正文)
    36. + +
    37. 如果妳要用 gif2ps ,請改用以下的設定: +
      +
      +gif_converter= /usr/bin/gif2ps; exit 0
      +
      +
      +exit 0 是因為 gif2ps 會把不嚴重的警告也以錯誤值傳回, ifhp 會誤判為轉換失敗,就不會印了。 (回正文)
    38. + +
    39. 如果沒有印出來,依下述方式偵錯:寫一個簡單 script /tmp/send : +
      +
      +#! /bin/sh
      +file=/tmp/myfile
      +ifhp=model=xxxxxxxx
      +cat /dev/null >/tmp/t
      +cat $file | /usr/libexec/filters/ifhp -Tdev=/tmp/t,trace,debug=2,${ifhp} 2> /tmp/trace
      +
      +
      +執行: +
      +
      +$ sh -x /tmp/send
      +
      +
      +仔細看看 /tmp/trace ,找到問題的原因。妳可以把 debug= 的值設大一點(如 debug=10 ),以得到更詳細的偵錯資訊。 (回正文)
    40. + +
    41. 為什麼列印會這麼複雜?因為印表機是外部裝置。既然不在機殼裏面,要靠線路連接,那要和主電腦通訊、執行工作,就會有佇列 spooling 的問題。佇列是一種排隊,在工作因為各種不同的原因(如執行速度太慢、通訊速度太慢、通訊中斷或不穩、記憶體不足…等),無法全部送到對方去執行時,就要先排隊,等排到的時候再送過去執行。這時候,就要能管理、設定先後次序、暫停、甚至刪除排隊中的工作。傳送 E-mail 因為牽涉到不同的主機之間訊息相互傳遞,也是一個需要佇列 spooling 的系統。其實機殼裏面的各個部份(光碟機、軟碟機、硬碟機、記憶體…等)之間也會有佇列的問題,不過幾乎都自動處理掉了,所以我們感覺不到。 (回正文)
    42. + +
    43. 因為我們不能讓每個人都有權限寫入 /dev/lp0 ,所以我們要給 LPRng 特殊權限。一個方法是把 lpd 設成 setuid root ,不過會有安全的顧慮。另一個方法是讓 lpd 執行 daemon 模式,以 root 的權限啟動,轉為 daemon ,等待 lpr 呼叫,再來列印。 daemon 的帳號一定要有權限寫入 /dev/lp0 。 (回正文)
    44. + +
    45. 如果妳是用「自動化」的 filter (如 apsfilter 或 rhs-printfilters ),現在可以安裝設定 filter 了,跳過以下的設定。 (回正文)
    46. + +
    47. 如果 lpr 印不出來,你可以執行: +
      +
      +% lpq -L
      +
      +
      +檢查列印記錄。若還是不行,請參考 LPRng HOWTO 的說明。 (回正文)
    48. + +
    49. 由 Windows samba 客戶端傳來的資料,事先經過 Windows 驅動程式轉為低階印表指令,不需(也不可)再做資料轉換,在 filter 中需設定以 raw 直接傳送至印表機 /dev/lp0 。若印表機只給 Windows 客戶端列印,則可完全不設 filter ,直接由 LPRng 轉送給印表機,設定方式如最前面 所述。 (回正文)
    50. + +
    51. 如果從網路上的芳鄰看有問題,請參考 samba 列印說明(回正文)
    52. + +
    53. 如果印不出來,請檢查 lpq -L 的列印記錄。 (回正文)
    54. +
    + + +

    五、參考資料

    + +

    更進一步的資料請參考下列網址:

    + + + + +
    依瑪貓,初稿 2001-04-25 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/plaineml.html.en.html b/htdocs/imacat/tech/plaineml.html.en.html new file mode 120000 index 0000000..57b2fa7 --- /dev/null +++ b/htdocs/imacat/tech/plaineml.html.en.html @@ -0,0 +1 @@ +plaineml.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/plaineml.html.en.xhtml b/htdocs/imacat/tech/plaineml.html.en.xhtml new file mode 100644 index 0000000..6e9c473 --- /dev/null +++ b/htdocs/imacat/tech/plaineml.html.en.xhtml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + +How to Set Up Plain Text E-mail? + + + + + + + +
    + +
    + + +

    How to Set Up Plain Text E-mail?

    + +

    Table of Contents

    + +
      +
    1. Prefix
    2. +
    3. Outlook Express 5/6
    4. +
    5. Outlook Express 4
    6. +
    7. Mozilla/Netscape 6
    8. +
    9. Netscape 4.5 and above
    10. +
    11. Netscape 4
    12. +
    13. Netscape 3 or earlier
    14. +
    15. Eudora
    16. +
    17. Becky!
    18. +
    + + +

    Prefix

    + +

    What is a plain text mail?

    + +

    If you were using e-mail programs like Outlook Express, Outlook, Netscape Mail or Eudora, you might not know what is a plain text mail.

    + +

    A plain text mail is the opposite of an HTML mail. When you write a new e-mail, you may change the font size or color, add an underscore, or center the whole sentence. When this mail is sent, many HTML tags are inserted into your content. It is then sent as an HTML mail. HTML is the internet standard document format. If the receiver’s e-mail program can read HTML mail, too, she/he can then read this mail, with your specified font size, color… etc.

    + +

    On the other hand, a plain text mail is the simplest form of mail. It has no formatting, no font size nor color. What you type is exactly what is sent through the internet. No additional formatting tags will be added. Thus, it can always be read no matter which e-mail program the receiver might have.

    + +

    Why should we use plain text mails?

    + +

    We use plain text mails for the following reasons:

    + +
      +
    1. Many common simple e-mail clients, like pine or elm under linux/UNIX, cannot read HTML mails. The HTML tags will come together with the content and the mail will become a clutter.
    2. + +
    3. It will have to strip the HTML tags first in order to do the full text search on a batch of mails. This will largely increase the programming difficulty, especially in mailing list archive searching.
    4. + +
    5. With a lot of HTML tags the e-mail’s size will be enlarged enormously. This will become serious burden for a slow dial-up reveiver or a ISDN fixed networking company. The bandwidth is wasted, and the time to check mail is slowed down a lot. For large-sized mailing lists, it will cause enormously burden to the global internet.
    6. +
    + +

    Safe delivering is far more important than formatting for a mail. We should try our best to deliver our infomation safely to our receiver’s hands, while minimizing the burden to the others. Please use plain text mails instead of HTML mails, to create a better e-mail communication environment together.

    + + +

    Outlook Express 5 and 6

    + +

    Start your Outlook Express. From the Tools on the top toolbar, choose Options.... In the popped-up Options window, click the Send at the top to move to the Send page. Choose Plain Text in the Mail Sending Format at the bottom. That’s all.

    + +

    You could click the Plain Text Settings beside it. It will pop up a Plain Text Settings window. Choose MIME in Message format, choose None at the Encode text using: options, and check the Allow 8-bit characters in headers. Click OK, OK.

    + + +

    Mozilla and Netscape 6

    + +

    Start your Mozilla Mail & Newsgroups or Netscape Mail & Newsgroups. From the Edit on the top toolbar, choose Mail & Newsgroups Account Settings.... In the popped-up window titled Mail & Newsgroups Account Settings, choose the account you are going to set up. Then check the Compose messages in HTML format at the lower-right. If you don’t see this option, just drag the lower-right edge of the window until you can see it. Then, click OK. That’s all.

    + + +

    Netscape 4.5 and above

    + +

    Start your Netscape Messenger. From the Edit on the top toolbar, choose Preferences.... In the popped-up window titled Preferences, choose the Formatting below the Mail & Newsgroups in the Category at the left. If you don’t see the Formatting and there’s a cross sign + precede the Mail & Newsgroups, click on the cross sign + to display it. Choose the Use the plain text editor to compose messages in the Message formatting at the right. Click OK. That’s all.

    + + +

    Netscape 4

    + +

    Start your Netscape Messenger Mailbox. From the Edit on the top toolbar, choose Preferences.... In the popped-up window titled Preferences, choose the Messages below the Mail & Groups in the Category at the left. If you don’t see the Messages and there’s a cross sign + precede the Mail & Groups, click on the cross sign + to display it. Uncheck the By default, send HTML messages in the Messages properties at the right. Click OK. That’s all.

    + + +

    Netscape 3 or earlier

    + +

    Netscape 3 or earlier does not send HTML mails by default.

    + + +

    Eudora

    + +

    Start your Eudora. From the Tools on the top toolbar, choose Options.... In the popped-up Options window, click the Styled Text on the Category at the left. Then, uncheck the Show formatting toolbar option. Also choose Send plain text only at the When sending mail with styled text (HTML): below. Click OK. That’s all.

    + + +

    Becky!

    + +

    Becky does not send HTML mails by default.

    + +
    by imacat, first written 2001-12-22, last updated 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/plaineml.html.zh-cn.html b/htdocs/imacat/tech/plaineml.html.zh-cn.html new file mode 120000 index 0000000..24f9718 --- /dev/null +++ b/htdocs/imacat/tech/plaineml.html.zh-cn.html @@ -0,0 +1 @@ +plaineml.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/plaineml.html.zh-cn.xhtml b/htdocs/imacat/tech/plaineml.html.zh-cn.xhtml new file mode 100644 index 0000000..bce0dd8 --- /dev/null +++ b/htdocs/imacat/tech/plaineml.html.zh-cn.xhtml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + +如何设定纯文字邮件? + + + + + + + +
    + +
    + + +

    如何设定纯文字邮件?

    + +

    目录

    + +
      +
    1. 前言
    2. +
    3. Outlook Express 5/6
    4. +
    5. Outlook Express 4
    6. +
    7. Internet Mail
    8. +
    9. Mozilla/Netscape 6
    10. +
    11. Netscape 4.5 以上
    12. +
    13. Netscape 4
    14. +
    15. Netscape 3 及更早的版本
    16. +
    17. Eudora
    18. +
    19. Becky!
    20. +
    + + +

    前言

    + +

    什么是纯文字邮件?

    + +

    如果你一开始学用 E-mail ,用的就是 Outlook Express 、 Outlook 、 Netscape Mail 、 Eudora 之类的 E-mail 程式,你可能不知道什么叫纯文字邮件

    + +

    纯文字邮件的相反是 HTML 邮件。你写 E-mail 的时候,可以把字体放大缩小、改变颜色、下面划线加重点、置中对齐…等等。这些信寄出去的时候,是插进很多 HTML 标签,用 HTML 格式寄出去的。因为 HTML 是标准的文件格式,所以只要对方的 E-mail 程式也能看 HTML 邮件,就能把你设定的字体大小、颜色等通通都秀出来。

    + +

    相反地,纯文字是最简单的 E-mail 型式。纯文字邮件没有格式,没有字体颜色可变,你打的内容会原原本本一字一字寄出去,没有什么格式设定,不过因为没有格式,不论对方的 E-mail 程式是什么,都可以读得出来。

    + +

    为什么要用纯文字邮件?

    + +

    因为以下几个理由:

    + +
      +
    1. 内文中夹杂了 HTML 标签时,很多简单常用的 E-mail 程式,像 Linux/UNIX 下常用的 pineelm 等等,就不能读信了,会变成乱码。
    2. + +
    3. 若想对一整批 E-mail 旧信做全文检索,写程式时要先去掉 HTML 标签,才能搜寻内文,通信群组 Mailing List 要做旧信全文检索,会变得很困难。
    4. + +
    5. 夹杂了一大堆 HTML 标签, E-mail 会变很大,对频宽不大的拨号网路收件人,或 ISDN 网路专线的公司伺服器而言,会造成很大的负荷,浪费频宽,让收信的人上网收信速度变得很慢。对大规模的通信群组 Mailing List 而言,无谓的大小会造成整体网路非常沉重的负荷。
    6. +
    + +

    E-mail 最重要的目的是传递讯息内容,格式是次要的。我们希望每封 E-mail 的讯息都能确实传递到收件人手中,同时尽量避免造成任何人的负担。请大家一起来使用纯文字邮件,拒用 HTML 邮件,以塑造更好的 E-mail 通信环境。

    + + +

    Outlook Express 5/6

    + +

    启动 Outlook Express 后,由工具列上的 工具(T)选项(O)... 按下去,会打开一个 选项 的视窗。按一下上方的 传送 ,翻到 传送 那一页。在下面的 邮件传送格式 ,选择 纯文字(P) 。这样就好了。

    + +

    你可以按一下旁边的 纯文字设定(E) ,会打开一个的 纯文字设定 的视窗。在 邮件格式 中,选择 MIME(M) ,下面的 文字编码方式(E) ,最后在 标题允许 8 位元的字元 的选项上打勾。然后按 确定确定

    + + +

    Outlook Express 4

    + +

    启动 Outlook Express 后,由工具列上的 工具(T)选项(O)... 按下去,会打开一个 选项 的视窗。按一下上方的 传送 ,翻到 传送 那一页。在下面的 邮件传送格式 ,选择 纯文字(P) 。这样就好了。

    + +

    你可以按一下旁边的 设定(E)... ,会打开一个的 纯文字设定 的视窗。在 邮件格式 中,选择 MIME(M) ,下面的 文字编码方式(E) ,最后在 表头允许 8 位元的字元 的选项上打勾。然后按 确定确定

    + + +

    Internet Mail

    + +

    启动 Internet Mail 后,由工具列上的 邮件(M)选项(O)... 按下去,会打开一个 选项 的视窗。按一下上方的 传送 ,翻到 传送 那一页。在下面的 邮件传送格式 ,选择 纯文字(P) 。这样就好了。

    + +

    你可以按一下旁边的 设定(E)... ,会打开一个的 纯文字设定 的视窗。在 邮件格式 中,选择 MIME(M) ,下面的 文字编码方式(E) ,最后在 表头允许 8 位元的字元 的选项上打勾。然后按 确定确定

    + + +

    Mozilla 与 Netscape 6

    + +

    启动 Mozilla 信件与 News 或 Netscape Mail & Newsgroups 后,由工具列上的 编辑(E)信件与 News 帐号设定(M)... 按下去,会打开一个 邮件与 News 帐号设定 的视窗。在左边选择你要设定的帐号,在视窗右边最下方 HTML 格式寄信 的选项上打勾。如果看不到 HTML 格式寄信 的选项,可以拉视窗的右下边缘,把视窗拉大,就看得到了。选项打勾后,按 确定 。这样就好了。

    + + +

    Netscape 4.5 以上

    + +

    启动 Netscape Messenger 后,由工具列上的 编辑(E)喜好设定(E)... 按下去,会打开一个 喜好设定 的视窗。在左边的 目录 中,选择邮件和新闻群组 下的 邮件格式 。如果邮件和新闻群组 的左边是加号 + ,看不到邮件格式 ,在加号 + 上按一下,就看得到了。然后在右边的 邮件邮件格式 里,选择 使用纯文字编辑器来编排邮件(T) 。然后按 确定 。这样就好了。

    + + +

    Netscape 4

    + +

    启动 Netscape Messenger Mailbox 后,由工具列上的 EditPreferences... 按下去,会打开一个 Preferences 的视窗。在左边的 Category 中,选择 Mail & Groups 下的 Messages 。如果 Mail & Groups 的左边是加号 + ,看不到 Messages ,在加号 + 上按一下,就看得到了。然后在右边的 Messages properties 里,选择 By default, send HTML messages 。然后按 OK 。这样就好了。

    + + +

    Netscape 3 及更早的版本

    + +

    Netscape 3 及更早的版本预设不使用 HTML 邮件。

    + + +

    Eudora

    + +

    启动 Eudora 后,由工具列上的 ToolsOptions... 按下去,会打开一个 Options 的视窗。在左边的 Category 中选择 Styled Text 。把视窗右边 Show formatting toolbar 的勾勾去掉,并在下面 When sending mail with styled text (HTML): 的地方选择 Send plain text only 。 然后按 OK 。这样就好了。

    + + +

    Becky!

    + +

    Becky! 预设不使用 HTML 邮件。

    + +
    依玛猫,初稿 2001-12-22 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/plaineml.html.zh-tw.html b/htdocs/imacat/tech/plaineml.html.zh-tw.html new file mode 120000 index 0000000..d02ae09 --- /dev/null +++ b/htdocs/imacat/tech/plaineml.html.zh-tw.html @@ -0,0 +1 @@ +plaineml.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/plaineml.html.zh-tw.xhtml b/htdocs/imacat/tech/plaineml.html.zh-tw.xhtml new file mode 100644 index 0000000..22aac2b --- /dev/null +++ b/htdocs/imacat/tech/plaineml.html.zh-tw.xhtml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + +如何設定純文字郵件? + + + + + + + +
    + +
    + + +

    如何設定純文字郵件?

    + +

    目錄

    + +
      +
    1. 前言
    2. +
    3. Outlook Express 5/6
    4. +
    5. Outlook Express 4
    6. +
    7. Internet Mail
    8. +
    9. Mozilla/Netscape 6
    10. +
    11. Netscape 4.5 以上
    12. +
    13. Netscape 4
    14. +
    15. Netscape 3 及更早的版本
    16. +
    17. Eudora
    18. +
    19. Becky!
    20. +
    + + +

    前言

    + +

    什麼是純文字郵件?

    + +

    如果妳一開始學用 E-mail ,用的就是 Outlook Express 、 Outlook 、 Netscape Mail 、 Eudora 之類的 E-mail 程式,妳可能不知道什麼叫純文字郵件

    + +

    純文字郵件的相反是 HTML 郵件。妳寫 E-mail 的時候,可以把字體放大縮小、改變顏色、下面劃線加重點、置中對齊…等等。這些信寄出去的時候,是插進很多 HTML 標籤,用 HTML 格式寄出去的。因為 HTML 是標準的文件格式,所以只要對方的 E-mail 程式也能看 HTML 郵件,就能把妳設定的字體大小、顏色等通通都秀出來。

    + +

    相反地,純文字是最簡單的 E-mail 型式。純文字郵件沒有格式,沒有字體顏色可變,妳打的內容會原原本本一字一字寄出去,沒有什麼格式設定,不過因為沒有格式,不論對方的 E-mail 程式是什麼,都可以讀得出來。

    + +

    為什麼要用純文字郵件?

    + +

    因為以下幾個理由:

    + +
      +
    1. 內文中夾雜了 HTML 標籤時,很多簡單常用的 E-mail 程式,像 Linux/UNIX 下常用的 pineelm 等等,就不能讀信了,會變成亂碼。
    2. + +
    3. 若想對一整批 E-mail 舊信做全文檢索,寫程式時要先去掉 HTML 標籤,才能搜尋內文,通信群組 Mailing List 要做舊信全文檢索,會變得很困難。
    4. + +
    5. 夾雜了一大堆 HTML 標籤, E-mail 會變很大,對頻寬不大的撥號網路收件人,或 ISDN 網路專線的公司伺服器而言,會造成很大的負荷,浪費頻寬,讓收信的人上網收信速度變得很慢。對大規模的通信群組 Mailing List 而言,無謂的大小會造成整體網路非常沉重的負荷。
    6. +
    + +

    E-mail 最重要的目的是傳遞訊息內容,格式是次要的。我們希望每封 E-mail 的訊息都能確實傳遞到收件人手中,同時儘量避免造成任何人的負擔。請大家一起來使用純文字郵件,拒用 HTML 郵件,以塑造更好的 E-mail 通信環境。

    + + +

    Outlook Express 5/6

    + +

    啟動 Outlook Express 後,由工具列上的 工具(T)選項(O)... 按下去,會打開一個 選項 的視窗。按一下上方的 傳送 ,翻到 傳送 那一頁。在下面的 郵件傳送格式 ,選擇 純文字(P) 。這樣就好了。

    + +

    妳可以按一下旁邊的 純文字設定(E) ,會打開一個的 純文字設定 的視窗。在 郵件格式 中,選擇 MIME(M) ,下面的 文字編碼方式(E) ,最後在 標題允許 8 位元的字元 的選項上打勾。然後按 確定確定

    + + +

    Outlook Express 4

    + +

    啟動 Outlook Express 後,由工具列上的 工具(T)選項(O)... 按下去,會打開一個 選項 的視窗。按一下上方的 傳送 ,翻到 傳送 那一頁。在下面的 郵件傳送格式 ,選擇 純文字(P) 。這樣就好了。

    + +

    妳可以按一下旁邊的 設定(E)... ,會打開一個的 純文字設定 的視窗。在 郵件格式 中,選擇 MIME(M) ,下面的 文字編碼方式(E) ,最後在 表頭允許 8 位元的字元 的選項上打勾。然後按 確定確定

    + + +

    Internet Mail

    + +

    啟動 Internet Mail 後,由工具列上的 郵件(M)選項(O)... 按下去,會打開一個 選項 的視窗。按一下上方的 傳送 ,翻到 傳送 那一頁。在下面的 郵件傳送格式 ,選擇 純文字(P) 。這樣就好了。

    + +

    妳可以按一下旁邊的 設定(E)... ,會打開一個的 純文字設定 的視窗。在 郵件格式 中,選擇 MIME(M) ,下面的 文字編碼方式(E) ,最後在 表頭允許 8 位元的字元 的選項上打勾。然後按 確定確定

    + + +

    Mozilla 與 Netscape 6

    + +

    啟動 Mozilla 信件與 News 或 Netscape Mail & Newsgroups 後,由工具列上的 編輯(E)信件與 News 帳號設定(M)... 按下去,會打開一個 郵件與 News 帳號設定 的視窗。在左邊選擇妳要設定的帳號,在視窗右邊最下方 HTML 格式寄信 的選項上打勾。如果看不到 HTML 格式寄信 的選項,可以拉視窗的右下邊緣,把視窗拉大,就看得到了。選項打勾後,按 確定 。這樣就好了。

    + + +

    Netscape 4.5 以上

    + +

    啟動 Netscape Messenger 後,由工具列上的 編輯(E)喜好設定(E)... 按下去,會打開一個 喜好設定 的視窗。在左邊的 目錄 中,選擇郵件和新聞群組 下的 郵件格式 。如果郵件和新聞群組 的左邊是加號 + ,看不到郵件格式 ,在加號 + 上按一下,就看得到了。然後在右邊的 郵件郵件格式 裏,選擇 使用純文字編輯器來編排郵件(T) 。然後按 確定 。這樣就好了。

    + + +

    Netscape 4

    + +

    啟動 Netscape Messenger Mailbox 後,由工具列上的 EditPreferences... 按下去,會打開一個 Preferences 的視窗。在左邊的 Category 中,選擇 Mail & Groups 下的 Messages 。如果 Mail & Groups 的左邊是加號 + ,看不到 Messages ,在加號 + 上按一下,就看得到了。然後在右邊的 Messages properties 裏,選擇 By default, send HTML messages 。然後按 OK 。這樣就好了。

    + + +

    Netscape 3 及更早的版本

    + +

    Netscape 3 及更早的版本預設不使用 HTML 郵件。

    + + +

    Eudora

    + +

    啟動 Eudora 後,由工具列上的 ToolsOptions... 按下去,會打開一個 Options 的視窗。在左邊的 Category 中選擇 Styled Text 。把視窗右邊 Show formatting toolbar 的勾勾去掉,並在下面 When sending mail with styled text (HTML): 的地方選擇 Send plain text only 。 然後按 OK 。這樣就好了。

    + + +

    Becky!

    + +

    Becky! 預設不使用 HTML 郵件。

    + +
    依瑪貓,初稿 2001-12-22 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/sslcerts.html.en.html b/htdocs/imacat/tech/sslcerts.html.en.html new file mode 120000 index 0000000..4006532 --- /dev/null +++ b/htdocs/imacat/tech/sslcerts.html.en.html @@ -0,0 +1 @@ +sslcerts.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/sslcerts.html.en.xhtml b/htdocs/imacat/tech/sslcerts.html.en.xhtml new file mode 100644 index 0000000..549e7e8 --- /dev/null +++ b/htdocs/imacat/tech/sslcerts.html.en.xhtml @@ -0,0 +1,1242 @@ + + + + + + + + + + + + + + + + + + + + + +How to Create the SSL X.509 Certificates? + + + + + + + +
    + +
    + + +

    How to Create the SSL X.509 Certificates?

    + +

    Table of Contents

    + +
      +
    1. Prefix
    2. +
    3. If You Are root +
        +
      1. Set up Your OpenSSL Environment
      2. +
      3. Create a Root CA +
          +
        1. Generate a Private Key (and a Public Key)
        2. +
        3. Fill in the Certificate Request
        4. +
        5. Issue the Certificate
        6. +
        +
      4. +
      5. Create a Server Certificate +
          +
        1. Generate a Private Key (and a Public Key)
        2. +
        3. Fill in the Certificate Request
        4. +
        5. Issue the Certificate
        6. +
        +
      6. +
      +
    4. +
    5. If You Are an Unprivileged User +
        +
      1. Set up Your OpenSSL Environment
      2. +
      3. Create a Root CA +
          +
        1. Generate a Private Key (and a Public Key)
        2. +
        3. Fill in the Certificate Request
        4. +
        5. Issue the Certificate
        6. +
        +
      4. +
      5. Create a Server Certificate +
          +
        1. Generate a Private Key (and a Public Key)
        2. +
        3. Fill in the Certificate Request
        4. +
        5. Issue the Certificate
        6. +
        +
      6. +
      +
    6. +
    7. Configure the Operating Systems +
        +
      1. Linux/*BSD/UNIX
      2. +
      3. MS-WINDOWS
      4. +
      +
    8. +
    9. Configure the Servers +
        +
      1. HTTP +
          +
        1. Apache
        2. +
        +
      2. +
      3. POP3 +
          +
        1. Qpopper
        2. +
        +
      4. +
      5. SMTP +
          +
        1. Sendmail
        2. +
        +
      6. +
      +
    10. +
    11. Configure the Browsers +
        +
      1. Mozilla/Netscape 6 or Newer
      2. +
      3. Internet Explorer
      4. +
      5. Opera
      6. +
      7. Lynx
      8. +
      +
    12. +
    13. Configure the E-mail Programs +
        +
      1. Mozilla/Netscape 6 or Newer
      2. +
      3. Netscape 4 or Earlier
      4. +
      5. Outlook Express 5.5/6
      6. +
      7. Outlook Express 4/5
      8. +
      9. Eudora 5.1 or Newer
      10. +
      11. Becky!
      12. +
      13. Opera Mail
      14. +
      +
    14. +
    15. Configure Programs That Do Not Support SSL/TLS +
        +
      1. Stunnel
      2. +
      +
    16. +
    17. Review and Discussion +
        +
      1. Introduction to SSL/X.509
      2. +
      3. Warning: Invalid Certificate
      4. +
      5. Wait! What Data?
      6. +
      7. So, I’m Safe Now (with SSL)?
      8. +
      9. What Is a Digital Signature?
      10. +
      11. What Is a Certificate?
      12. +
      13. What Is a CA?
      14. +
      15. What Is a Root CA?
      16. +
      17. How to Fill in the Certificate Request?
      18. +
      19. Review to the X.509 Certificate System
      20. +
      21. Alternative Methods to Create SSL/X.509 Certificates
      22. +
      +
    18. +
    19. Annotations
    20. +
    21. References
    22. +
    23. Notes
    24. +
    + + +

    Prefix

    + +

    Copyright © 2002-2006 imacat. All rights reserved. Please read the Copyright License first, if you want to forward or cite parts or all of this article.

    + +

    Our goal is: To create X.509 SSL certificates by our name, with OpenSSL and under Linux/*BSD/UNIX. We will create 2 certificates: First we will create a root CA, which is by our name (XXX Association, YYY Corporation) and issued by itself. Then we will create a certificate, which is by the server name (www.abccompany.com) and issued by our root CA created in the first step. To simplify this process, we will not be creating any intermediate CA, and will issue certificates with our root CA directly.

    + +

    This article merely tells you how to create SSL X.509 certificates. It does not cover the system security. It does not cover the encryption/decryption algorithms. It does not cover how to install OpenSSL as well. You are assumed to be understanding the basic concept of public key/private key cryptography, knowing what is the RSA/DSA algorithms. You are also assumed to have a properly-installed OpenSSL, that is configured according to FHS[1], as:

    + +
    +
    +./config --prefix=/usr --openssldir=/usr/share/ssl
    +
    +
    + +

    or use a RPM or DEB package.

    + +

    This article is a HOWTO. For this reason, the step-by-step tutorial instruction (how) are organized in the front. The explanation and discussion (what and why) are left behind. If you have difficulty understanding the tutorial instruction, or wish to learn more about SSL/X.509 first, you can go directly to the rear part. There is no necessity to read from the beginning.

    + +

    CAUTION: Your certificates created according to the instruction here will still produce a WARNING: Invalid Certificate. Refer to Introduction to SSL/X.509 and Warning: Invalid Certificate for more details.

    + +

    According to X.509, you can create certificates with either RSA or DSA key pairs. But only RSA key pairs are capable of exchanging keys when starting a new SSL connection with a SSL server. You can only use RSA key pairs as your server certificates. On the other hand, CAs do not have to exchange keys. They only issue other certificates. You can use either RSA or DSA key pair as your CAs. But, since some SSL programs do not support the DSA algorithm yet[2], we’ll still create RSA CAs here for the compatibility reason.

    + +

    You can create your root CA as an unprivileged user. There’s no need to be root to do this. But if your root CA will be used to issue certificates for your whole organization, you are strongly suggested to create it with the root privilege for security reasons. Again, you can also create your server certificate as an unprivileged user. There’s no need to be root to do this. But if your server certificate will be used by this server, you are strongly suggested to created it with the root privilege for security reasons.

    + + +

    If You Are root, and Are Creating a Root CA For Your Whole Organization

    + +

    Set up Your OpenSSL Environment

    + +

    If you install your OpenSSL with the instruction above:

    + +
    +
    +./config --prefix=/usr --openssldir=/usr/share/ssl
    +
    +
    + +

    or use Red Hat’s RPM package, your OpenSSL configuration will be located at /usr/share/ssl. If you use Mandrake’s RPM package, your OpenSSL configuration will be located at /usr/lib/ssl. Both of them violate FHS’ requirement. They are not convienent for backup, too. The OpenSSL configuration should be located at /etc/ssl. If you use Debian’s apt, your OpenSSL will be just there at /etc/ssl.

    + +
    +
    +# Set up the relevant directories
    +mkdir -p /etc/ssl
    +mkdir -p /etc/ssl/private
    +chmod og-rwx /etc/ssl/private
    +mkdir -p /etc/ssl/certs
    +mkdir -p /etc/ssl/crl
    +mkdir -p /etc/ssl/newcerts
    +
    +# Set up your OpenSSL configuration file[3]
    +mv /usr/share/ssl/openssl.cnf /etc/ssl
    +ln -s /etc/ssl/openssl.cnf /usr/share/ssl/openssl.cnf
    +
    +# Set up the location of your OpenSSL configuration file[4]
    +export OPENSSL_CONF="/etc/ssl/openssl.cnf"
    +
    +# Add the location of your OpenSSL configuration file to your .bashrc[5]
    +echo "# Location of the OpenSSL configuration file" >> ~/.bashrc
    +echo "export OPENSSL_CONF=\"/etc/ssl/openssl.cnf\"" >> ~/.bashrc
    +
    +# Create the random file[6]
    +openssl rand -out /etc/ssl/private/.rand 1024
    +chmod og-rwx /etc/ssl/private/.rand
    +
    +
    + +

    Now modify your /etc/ssl/openssl.cnf. Change the line

    + +
    +
    +dir		= ./demoCA		# Where everything is kept
    +
    +
    + +

    to

    + +
    +
    +dir		= /etc/ssl		# Where everything is kept
    +
    +
    + +

    Create the Root CA

    + +

    If you have created your root CA before, don’t do this step again. Otherwise, all your issued certificates will become invalid and you’ll have to sign them again. Unless your root CA itself expires, is lost, or its private key leaks out, you should never recreate your root CA for any reason.

    + +

    Assuming your root CA is called myrootca.

    + + +

    1. Generate a Private Key (and a Public Key)

    + +

    We will create a new private key here. The public key can be derived from its corresponding private key.

    + +

    Please set a proper password for the private key of your root CA.

    + +
    +
    +# Create an RSA[7] private key
    +openssl genrsa -aes256 -out /etc/ssl/private/myrootca.key 4096
    +chmod og-rwx /etc/ssl/private/myrootca.key
    +
    +
    + + +

    2. Fill in the Certificate Request

    + +

    A certificate request is a combination of your private key and your self-infomation in reality, in order for the CA to verify its correctness and sign on it later. For this reason, you will be asked several questions relevant to this key, including your country, city, organization, department, the certificate name, contact e-mail, and your applying valid period. Fill in them one by one. Refer to What Is a Certificate? for more details.

    + +

    If you want to use your root CA as the same server certificate for your server, fill in your server’s full qualified domain name (FQDN, i.e. www.abc.com) as the certificate’s common name here. Refer to Alternative Methods to Create SSL/X.509 Certificates for more details.

    + +

    If you don’t know how to fill in the certificate request, refer to How to Fill in the Certificate Request? for more details.

    + +
    +
    +# Fill in the certificate request
    +openssl req -new -key /etc/ssl/private/myrootca.key -out /tmp/myrootca.req
    +
    +
    + + +

    3. Issue the Certificate

    + +

    Root CA is the topmost CA. No further higher CA can issue a root CA. It has to be signed by itself. Refer to What is a Root CA? for more details.

    + +

    Root CA should never expire. Otherwise, all the certificates it had issued will need to be reissued, and all of the relevant SSL programs will need to be reconfigure. So we set its valid period to 7305 days (20 years). If we do not set the valid period, it will be set to its default as 30 days (1 month).

    + +

    The certificate request is not required after it is signed. We can safely delete it.

    + +
    +
    +# Sign its own certificate request
    +openssl x509 -req -days 7305 -sha512 \
    + -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
    + -signkey /etc/ssl/private/myrootca.key \
    + -in /tmp/myrootca.req -out /etc/ssl/certs/myrootca.crt
    +
    +# Delete the certificate request
    +rm -f /tmp/myrootca.req
    +
    +
    + +

    That’s all. The private key is /etc/ssl/private/myrootca.key, and the self-signed public key certificate is /etc/ssl/certs/myrootca.crt. myrootca.key is your private key. You should protect it carefully. It should be only readable by root, and its permission should be 0400. myrootca.crt is your public key certificate. You should spread it out and make it free for everyone. You should put it in your intranet or on your web site for everyone to download and install it freely by themselves.

    + + +

    Create a Server Certificate

    + +

    Assuming you are creating a server certificate for myhost.

    + + +

    1. Generate a Private Key (and a Public Key)

    + +

    We will create a new private key here. The public key can be derived from its corresponding private key.

    + +

    Please log into the host that you are creating a server certificate for.

    + +

    CAUTION: Do not set any password for the private key of your server certificate. Your SSL service will ask you for that password when it starts and reads its certificate private key. When your system boots and starts each server one by one, it will stop for the password from the keyboard for each SSL service that reads that private key. Now your server may be colocated at some IDC. You may leave the office during the weekend. You may not be able to attend to its keyboard at all times. You will not be happy to see if it cannot keep booting, waiting for a password from the keyboard, after a remote reboot or a crashed auto-reboot.

    + +
    +
    +# Create an RSA private key
    +openssl genrsa -out /etc/ssl/private/myhost.key 4096
    +chmod og-rwx /etc/ssl/private/myhost.key
    +
    +
    + + +

    2. Fill in the Certificate Request

    + +

    A certificate request is a combination of your private key and your self-infomation in reality, in order for the CA to verify its correctness and sign on it later. For this reason, you will be asked several questions relevant to this key, including your country, city, organization, department, the certificate name, contact e-mail, and your applying valid period. Fill in your server’s full qualified domain name (FQDN, i.e. www.abc.com) as the certificate’s common name here. Refer to What Is a Certificate? for more details.

    + +

    If you don’t know how to fill in the certificate request, refer to How to Fill in the Certificate Request? for more details.

    + +
    +
    +# Fill in the certificate request
    +openssl req -new -key /etc/ssl/private/myhost.key -out /tmp/myhost.req
    +
    +
    + + +

    3. Issue the Certificate with the Root CA[8]

    + +

    The valid period of the server certificate is not important at all. Just issue a new one when it is expired. SSL programs know only the root CAs but not the server certificates. A server certificate is valid as soon as it is issued by a valid root CA. You don’t have to reconfigure the SSL programs. But, to avoid the trouble to reissue certificates, we will set its valid period to 3650 days (about 10 years.)

    + +

    The certificate request is not required after it is signed. We can safely delete it.

    + +
    +
    +# Sign the certificate request
    +openssl x509 -req -days 3650 -sha512 \
    + -extfile /etc/ssl/openssl.cnf -extensions v3_req \
    + -CA /etc/ssl/certs/myrootca.crt -CAkey /etc/ssl/private/myrootca.key \
    + -CAserial /etc/ssl/myrootca.srl -CAcreateserial \
    + -in /tmp/myhost.req -out /etc/ssl/certs/myhost.crt
    +
    +# Delete the certificate request
    +rm -f /tmp/myhost.req
    +
    +
    + +

    That’s all.[9] The private key is /etc/ssl/private/myhost.key. You should protect it carefully. It should be only readable by root, and its permission should be 0400. The public key certificate is /etc/ssl/certs/myrootca.crt. You should spread it out and make it free for everyone. This private/public key pair can be used in HTTPS, POP3/TLS, SMTPS/TLS and other SSL services. They should not be moved to other places. You should not put your private key here and there to reduce security risks. You can set the location of the certificates to here in your service configuration files.

    + + +

    If You Are an Unprivileged User

    + +

    Set up Your OpenSSL Environment

    + +
    +
    +# Set up the relevant directories
    +mkdir -p ~/etc
    +mkdir -p ~/etc/ssl
    +mkdir -p ~/etc/ssl/private
    +chmod og-rwx ~/etc/ssl/private
    +mkdir -p ~/etc/ssl/certs
    +mkdir -p ~/etc/ssl/crl
    +mkdir -p ~/etc/ssl/newcerts
    +mkdir -p ~/tmp
    +
    +# Set up your OpenSSL configuration file[10]
    +cp /usr/share/ssl/openssl.cnf ~/etc/ssl
    +
    +# Set up the location of your OpenSSL configuration file[11]
    +export OPENSSL_CONF="$HOME/etc/ssl/openssl.cnf"
    +
    +# Add the location of your OpenSSL configuration file to your .bashrc[12]
    +echo "# Location of the OpenSSL configuration file" >> ~/.bashrc
    +echo "export OPENSSL_CONF=\"$HOME/etc/ssl/openssl.cnf\"" >> ~/.bashrc
    +
    +# Create the random file[13]
    +openssl rand -out ~/etc/ssl/private/.rand 1024
    +chmod og-rwx ~/etc/ssl/private/.rand
    +
    +
    + +

    Now modify your ~/etc/ssl/openssl.cnf. Change the line

    + +
    +
    +dir		= ./demoCA		# Where everything is kept
    +
    +
    + +

    to

    + +
    +
    +dir		= ~/etc/ssl		# Where everything is kept
    +
    +
    + + +

    Create a Root CA

    + +

    If you have created your root CA before, don’t do this step again. Otherwise, all your issued certificates will become invalid and you’ll have to sign them again. Unless your root CA itself expires, is lost, or its private key leaks out, you should never recreate your root CA for any reason.

    + +

    Assuming your root CA is called myrootca.

    + + +

    1. Generate a Private Key (and a Public Key)

    + +

    We will create a new private key here. The public key can be derived from its corresponding private key.

    + +

    Please set a proper password for the private key of your root CA.

    + +
    +
    +# Create an RSA[14] private key
    +openssl genrsa -aes256 -out ~/etc/ssl/private/myrootca.key 4096
    +chmod og-rwx ~/etc/ssl/private/myrootca.key
    +
    +
    + + +

    2. Fill in the Certificate Request

    + +

    A certificate request is a combination of your private key and your self-infomation in reality, in order for the CA to verify its correctness and sign on it later. For this reason, you will be asked several questions relevant to this key, including your country, city, organization, department, the certificate name, contact e-mail, and your applying valid period. Fill in them one by one. Refer to What Is a Certificate? for more details.

    + +

    If you want to use your root CA as the same server certificate for your server, fill in your server’s full qualified domain name (FQDN, i.e. www.abc.com) as the certificate’s common name here. Refer to Alternative Methods to Create SSL/X.509 Certificates for more details.

    + +

    If you don’t know how to fill in the certificate request, refer to How to Fill in the Certificate Request? for more details.

    + +
    +
    +# Fill in the certificate request
    +openssl req -new -key ~/etc/ssl/private/myrootca.key -out ~/tmp/myrootca.req
    +
    +
    + + +

    3. Issue the Certificate

    + +

    Root CA is the topmost CA. No further higher CA can issue a root CA. It has to be signed by itself. Refer to What is a Root CA? for more details.

    + +

    Root CA should never expire. Otherwise, all the certificates it had issued will need to be reissued, and all of the relevant SSL programs will need to be reconfigure. So we set its valid period to 7305 days (20 years). If we do not set the valid period, it will be set to its default as 30 days (1 month).

    + +

    The certificate request is not required after it is signed. We can safely delete it.

    + +
    +
    +# Sign its own certificate request
    +openssl x509 -req -days 7305 -sha512 \
    + -extfile ~/etc/ssl/openssl.cnf -extensions v3_ca \
    + -signkey ~/etc/ssl/private/myrootca.key \
    + -in ~/tmp/myrootca.req -out ~/etc/ssl/certs/myrootca.crt
    +
    +# Delete the certificate request
    +rm -f ~/tmp/myrootca.req
    +
    +
    + +

    That’s all. The private key is ~/etc/ssl/private/myrootca.key, and the self-signed public key certificate is ~/etc/ssl/certs/myrootca.crt. myrootca.key is your private key. You should protect it carefully. It should be only readable by yourself, and its permission should be 0400. myrootca.crt is your public key certificate. You should spread it out and make it free for everyone. You should put it on your web site for everyone to download and install it freely by themselves.

    + + +

    Create a Server Certificate

    + +

    Assuming you are creating a server certificate for +myhost.

    + + +

    1. Generate a Private Key (and a Public Key)

    + +

    We will create a new private key here. The public key can be derived from its corresponding private key.

    + +

    CAUTION: Do not set any password for the private key of your server certificate. Your SSL service will ask you for that password when it starts and reads its certificate private key. When your system boots and starts each server one by one, it will stop for the password from the keyboard for each SSL service that reads that private key. Now your server may be colocated at some IDC. You may leave the office during the weekend. You may not be able to attend to its keyboard at all times. You will not be happy to see if it cannot keep booting, waiting for a password from the keyboard, after a remote reboot or a crashed auto-reboot.

    + +
    +
    +# Create an RSA private key
    +openssl genrsa -out ~/etc/ssl/private/myhost.key 4096
    +chmod og-rwx ~/etc/ssl/private/myhost.key
    +
    +
    + + +

    2. Fill in the Certificate Request

    + +

    A certificate request is a combination of your private key and your self-infomation in reality, in order for the CA to verify its correctness and sign on it later. For this reason, you will be asked several questions relevant to this key, including your country, city, organization, department, the certificate name, contact e-mail, and your applying valid period. Fill in your server’s full qualified domain name (FQDN, i.e. www.abc.com) as the certificate’s common name here. Refer to What Is a Certificate? for more details.

    + +

    If you don’t know how to fill in the certificate request, refer to How to Fill in the Certificate Request? for more details.

    + +
    +
    +# Fill in the certificate request
    +openssl req -new -key ~/etc/ssl/private/myhost.key -out /tmp/myhost.req
    +
    +
    + + +

    3. Issue the Certificate with the Root CA[8][15]

    + +

    The valid period of the server certificate is not important at all. Just issue a new one when it is expired. SSL programs know only the root CAs but not the server certificates. A server certificate is valid as soon as it is issued by a valid root CA. You don’t have to reconfigure the SSL programs. But, to avoid the trouble to reissue certificates, we will set its valid period to 3650 days (about 10 years.)

    + +

    The certificate request is not required after it is signed. We can safely delete it.

    + +
    +
    +# Sign the certificate request
    +openssl x509 -req -days 3650 -sha512 \
    + -extfile ~/etc/ssl/openssl.cnf -extensions v3_req \
    + -CA ~/etc/ssl/certs/myrootca.crt -CAkey ~/etc/ssl/private/myrootca.key \
    + -CAserial ~/etc/ssl/myrootca.srl -CAcreateserial \
    + -in /tmp/myhost.req -out ~/etc/ssl/certs/myhost.crt
    +
    +# Delete the certificate request
    +rm -f /tmp/myhost.req
    +
    +
    + +

    That’s all.[16] The private key is ~/etc/ssl/private/myhost.key. You should protect it carefully. It should be only readable by root, and its permission should be 0400. The public key certificate is ~/etc/ssl/certs/myrootca.crt. You should spread it out and make it free for everyone. This private/public key pair can be used in HTTPS, POP3/TLS, SMTPS/TLS and other SSL services. They should not be moved to other places. You should not put your private key here and there to reduce security risks. You can set the location of the certificates to here in your service configuration files.

    + + +

    Configure the Operating Systems

    + +

    Many operating systems have a common system certificate database, to store all the recognized CAs and certificates in a central place. We can add our own root CA into this common certificate database, and then our root CA will be available to all the programs that ultilize this certificate database.

    + + +

    Linux/*BSD/UNIX

    + + +

    MS-WINDOWS

    + +

    MS-WINDOWS has a common system certificate database. Go to the [Control Panel]. There’s a [Internet Options] inside. Double click on it. A window titled [Internet Content] will pop up. Click on the [Content] tab at the top to move to the [Content] page. There’s a section titled [Certificates] in the middle, with a button [(C)ertificates...] inside. Click on that button. Another window titled [Certificates] will pop up. This is the place where MS-WINDOWS stores and manages its system certificate database.[20]

    + +

    To add our root CA in, copy our root CA myrootca.crt to our WINDOWS and double click on it. A window titled [Certificates] will pop up, displaying the content of our root CA. Click the [Install Certificate] button below. A [Certificate Manager Import Wizard] will pop up. Click the [Next] button step by step. That’s all.

    + +

    To the extend of my knowledge, the WINDOWS programs that will ultilize this common system certificate database include: Internet Exporer, Outlook Express, Outlook and Symantec pcAnywhere. As long as our root CA is there, it will be available to all these programs.

    + + +

    Configure the Servers

    + +

    There are 2 types of SSL connections: The first one is the traditional SSL, and the second is the newer TLS.

    + +

    For the traditional SSL, both sides enter SSL as soon as the client is connecting to the server. The whole connection is then encrypted. There’s a disadvantage for this: In order not to confuse the client program, we have to allocate another TCP port for our SSL connection, and configure the client program to connect to that SSL TCP port. HTTP and HTTPS is an example for this.

    + +

    For the newer TLS, the client sends a STARTTLS command to the server after it has connected to the server. If the server understands it, both sides will enter SSL and the encryption will begin. Otherwise, the client will continue the unencrypted connection as before. The benefit here is that: Users do not need to change the TCP port of the client programs. It can automatically enter SSL as possible or fall back to the unencrypted connection. The compatibility is a lot better. There is no need to allocate another TCP port. But it also has a disadvantage: The connection will always be valid with or without SSL. Even if the server’s certificate is invalid and SSL is unavailable, the connection can go on. Certificate verification becomes meaningless. We are only benefited from the connection encryption. The identity of the server will not be really verified.

    + +

    We will discuss each protocol in the following sections.

    + + +

    HTTP

    + +

    HTTP is the first SSL protocol. In fact, SSL was designed for HTTP by Netscape, in order to make secure transaction on the web. To run SSL, Netscape allocated a new TCP port 443 dedicated for SSL and named it as HTTPS. Since that, SSL on HTTP is doing the old SSL way. You have to use the HTTPS(443) port. No TLS negotiation is available.

    + + +

    Apache

    + +

    Apache can run HTTPS with either Apache-SSL or mod_ssl. Please refer to their individual manual.

    + +

    CAUTION: Apache can only have one certificate in its memory. Since the server name (site name) is recorded on the certificate, one Apache process can only run SSL with one site name. The result is that, one Apache process can only run one SSL site. If you want to run several SSL sites, you have to run many Apache processes, each on a different IP or a different TCP port.

    + +

    Taking mod_ssl as an example. Set up your httpd.conf as follows after you have successfully installed mod_ssl:

    + +
    +
    +…
    +## mod_ssl.c: mod_ssl configuration
    +<IfModule mod_ssl.c>
    +    Listen 443
    +    AddType application/x-x509-ca-cert .crt
    +    AddType application/x-pkcs7-crl    .crl
    +    SSLSessionCache dbm:/var/log/apache/ssl_scache
    +    SSLSessionCacheTimeout 300
    +    SSLPassPhraseDialog builtin
    +    SSLMutex file:/var/log/apache/ssl_mutex
    +    SSLRandomSeed startup builtin
    +    SSLRandomSeed connect builtin
    +    SSLLog /var/log/apache/ssl_engine_log
    +    SSLLogLevel info
    +    SSLCipherSuite ALL:!ADH:!EXP56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
    +    SSLCertificateFile /etc/ssl/certs/myhost.crt
    +    SSLCertificateKeyFile /etc/ssl/private/myhost.key
    +    <VirtualHost *:443>
    +        SSLEngine on
    +    </VirtualHost>
    +</IfModule>
    +…
    +
    +
    + +

    Then, check your httpd.conf:

    + +
    +
    +httpd -t
    +
    +
    + +

    If everything is OK, restart your httpd and you’ll have a SSL web site now.

    + + +

    POP3

    + +

    POP3 has both ways: The traditional SSL on a dedicated POP3(995) port, and the newer TLS with a STARTTLS extension on the same POP3(110) port.

    + +

    The STARTTLS command for POP3 is STLS.

    + + +

    Qpopper

    + +

    Refer to the Qpopper manual on how to compile and install the Qpopper.

    + +

    Qpopper is capable of both POP3(995) and POP3(110)/TLS. However, it can only run on one port with one SSL method. If you need both POP3(995) and POP3(110)/TLS, you have to run 2 seperated qpopper processes, each with a different configuration file.

    + +

    Set up your /etc/qpopper.conf as follows:

    + +
    +
    +# qpopper.conf: Configuration file for Qpopper POP3(110)/TLS
    +set clear-text-password         = always
    +set statistics                  = true
    +set tls-support                 = stls
    +set tls-private-key-file        = /etc/ssl/private/myhost.key
    +set tls-server-cert-file        = /etc/ssl/certs/myhost.crt
    +
    +
    + +

    Set up your /etc/qpopper-s.conf as follows:

    + +
    +
    +# qpopper-s.conf: Configuration file for Qpopper POP3S(995)
    +set clear-text-password         = tls
    +set statistics                  = true
    +set tls-support                 = alternate-port
    +set tls-private-key-file        = /etc/ssl/private/myhost.key
    +set tls-server-cert-file        = /etc/ssl/certs/myhost.crt
    +
    +
    + +

    Then, run these 2 commands with the root privilege:

    + +
    +
    +popper -f /etc/qpopper.conf
    +popper 995 -f /etc/qpopper-s.conf
    +
    +
    + +

    That’s all. Try:

    + +
    +
    +ps ax | grep popper
    +
    +
    + +

    You’ll see 2 popper processes running simultaneously, each with a different set of arguments. Try:

    + +
    +
    +netstat -ap | grep popper
    +
    +
    + +

    You’ll see 2 popper processes on POP3(110) and POP3(995), seperately.

    + + +

    SMTP

    + +

    SMTP has both ways, too: The old, traditional SMTPS(465) port dedicated for SSL, and the nowadays TLS over the same SMTP(25) port with a STARTTLS extension. TLS is strongly recommended here. It uses the same TCP port and thus has a better compatibility when sending and receiving mails. Use TLS as long as possible.[17]

    + +

    The STARTTLS command for SMTP is STARTTLS.

    + + +

    Sendmail

    + +

    Sendmail can compile in both SMTPS and TLS supports. But SMTPS support is not official for Sendmail yet, and is categorized as FFR (for future release) currently. You won’t find any infomation for SMTPS support in the whole Sendmail documentation. Only TLS support is documented at this time.

    + +

    When delivering mails, Sendmail will only try STARTTLS on the SMTP(25) port. If the other side does not understand TLS, it will continue to send mails unencrypted. No further SSL attempt will be made to the SMTPS(465) port of the other side.

    + +

    To reduce the delivery difficulties as much as possible, Sendmail won’t verify the certificate of the other side at all. Encryption is used as long as possible. After all, it is really meaningless to verify certificates in TLS.

    + +

    To enable Sendmail’s SSL support, add the follows to devtools/Site/site.config.m4 before you compile your Sendmail:

    + + +
    +
    +# STARTTLS - SSL/TLS support
    +APPENDDEF(`conf_sendmail_ENVDEF', `-DSTARTTLS')
    +APPENDDEF(`conf_sendmail_LIBS', `-lssl -lcrypto')
    +
    +# SMTP SSL - SMTPS support
    +APPENDDEF(`conf_sendmail_ENVDEF', `-D_FFR_SMTP_SSL')
    +
    +
    + +

    Compile and install Sendmail:

    + +
    +
    +# Compile Sendmail
    +./Build
    +
    +# Install Sendmail
    +make install
    +
    +
    + +

    Next we set up the Sendmail configuration file /etc/mail/sendmail.cf. If you build your Sendmail configuration file with m4, add the follows to your m4 file config.mc:

    + +
    +
    +dnl Sendmail SMTPS/STARTTLS SSL Support
    +define(`confCACERT_PATH', `/etc/ssl/certs')
    +define(`confCACERT', `/etc/ssl/certs/myrootca.crt')
    +define(`confSERVER_CERT', `/etc/ssl/certs/myhost.crt')
    +define(`confSERVER_KEY', `/etc/ssl/private/myhost.key')
    +define(`confCLIENT_CERT', `/etc/ssl/certs/myhost.crt')
    +define(`confCLIENT_KEY', `/etc/ssl/private/myhost.key')
    +DAEMON_OPTIONS(`Name=MTA')dnl
    +DAEMON_OPTIONS(`Port=465, Name=MTASSL, M=s')dnl
    +
    +
    + +

    Rebuild the configuration file:

    + +
    +
    +m4 m4/cf.m4 config.mc > config.cf
    +cp -f config.cf /etc/mail/sendmail.cf
    +
    +
    + +

    Now we restart the Sendmail. It will start to do SMTPS/TLS SSL. Try:

    + +
    +
    +netstat -ap | grep sendmail
    +
    +
    + +

    You’ll see a same sendmail process on both SMTP(25) and SMTPS(465)[18] TCP ports.

    + +

    But this is not the end of the story.

    + +

    Since version 8.12.1, Sendmail has seperated its server and its client, in order to improve its security. The Sendmail server needs to bind to the low port SMTP(25) that belows 1024, and to save mails into everyone’s mail boxes. It still requires the root priviledge to do so. But this can simply be archived by starting Sendmail server as root. The Sendmail client does not need the root priviledge. It only needs the priviledge to write into a dedicated mail spool. So, Sendmail has changed from setuid root to setgid smmsp[19]. When a Sendmail client needs to deliver mails, it connects to a SMTP server with to do so.

    + +

    The Sendmail server can read the certificate private key without any problem, as it has the root privilege. But the Sendmail client don’t. It cannot read our server private key now. What can we do?

    + +

    We don’t want our Sendmail to be setuid-root. We don’t want to permit others to read the private key of our server certificate, either. We have to create another certificate that is only readable by the smmsp group, dedicated for our Sendmail client only:

    + +
    +
    +# Set up the relevant directories
    +mkdir -p /etc/mail/private
    +chgrp smmsp /etc/mail/private
    +chmod o-rwx /etc/mail/private
    +mkdir -p /etc/mail/certs
    +
    +# Create an RSA private key
    +openssl genrsa -out /etc/mail/private/myhost-msp.key 4096
    +chgrp smmsp /etc/mail/private/myhost-msp.key
    +chmod o-rwx /etc/mail/private/myhost-msp.key
    +
    +# Fill in the certificate request
    +openssl req -new -key /etc/mail/private/myhost-msp.key \
    + -out /tmp/myhost-msp.req
    +
    +# Sign the certificate request
    +openssl x509 -req -days 3650 -sha512 \
    + -extfile /etc/ssl/openssl.cnf -extensions v3_req \
    + -CA /etc/ssl/certs/myrootca.crt -CAkey /etc/ssl/private/myrootca.key \
    + -CAserial /etc/ssl/myrootca.srl -CAcreateserial \
    + -in /tmp/myhost-msp.req -out /etc/mail/certs/myhost-msp.crt
    +
    +# Delete the certificate request
    +rm -f /tmp/myhost-msp.req
    +
    +
    + +

    Add the follows to your m4 file submic.mc:

    + +
    +
    +…
    +dnl Sendmail STARTTLS SSL/TLS support
    +define(`confCACERT_PATH', `/etc/ssl/certs')
    +define(`confCACERT', `/etc/ssl/certs/myrootca.crt')
    +define(`confCLIENT_CERT', `/etc/mail/certs/myhost-msp.crt')
    +define(`confCLIENT_KEY', `/etc/mail/private/myhost-msp.key')
    +define(`confDONT_BLAME_SENDMAIL', `GroupReadableKeyFile')
    +…
    +
    +
    + +

    Rebuild the configuration file:

    + +
    +
    +m4 m4/cf.m4 submit.mc > submit.cf
    +cp -f submit.cf /etc/mail/submit.cf
    +
    +
    + +

    That’s all. You don’t have to restart the Sendmail, as we are not configuring the Sendmail server here. ^_*' You can send a mail to yourself, and watch the maillog to see if SSL succeeds.

    + +
    +
    +…
    +Sep 14 04:19:24 rinse sendmail[12093]: STARTTLS=client, relay=localhost.localdom
    +ain., version=TLSv1/SSLv3, verify=OK, cipher=EDH-RSA-DES-CBC3-SHA, bits=168/168
    +…
    +
    +
    + + +

    Configure the Browser

    + +

    Mozilla/Netscape 6 or Newer

    + +

    Mozilla and Netscape 6 or newer has a common certificate database for its mail and browser programs. Starting from the tool bar, from [Edit], [Preferences...], a window titled [Preferences] will pop up. Expand the [Privacy & Security] menu in the left side, and click on the [Certificates]. The title in the right side will become [Certificates]. There’s a button [Manage Certificates...] in the middle. Click on it. Another window titled [Certificate Manager] will pop up. This is the place where Mozilla and Netscape manage their certificates.[21][22]

    + +

    To add our root CA in, put our root CA myrootca.crt onto a web server. Move to that address with Mozilla/Netscape browser. A window titled [Downloading Certificate] will pop up. Check all the 3 options: [Trust this CA to identify web sites], [Trust this CA to identify email users], [Trust this CA to identify email software developers]. Then click on [OK]. That’s all.

    + +

    If you are using Mozilla/Netscape under MS-WINDOWS, you can also add our root CA in by copying our root CA to the WINDOWS and typing the full path of our root CA in the Mozilla/Netscape address bar.

    + +

    The root CA imported into the Mozilla/Netscape browser will also be avaible to the Mozilla Mail and Netscape Mail & Newsgroups to verify the certificates.

    + + +

    Internet Explorer

    + +

    Internet Explorer ultilizes WINDOWS’s common system certificate database. Our root CA is available as long as it is imported into this certificate database. Refer to Configure MS-WINDOWS for more details.

    + + +

    Opera

    + +

    Until the time this article is written, Opera (6.05) does not support DSA algorithm. Only RSA algorithm is supported. You can only import RSA CAs, but not DSA CAs.

    + +

    Start your Opera. Starting from the tool bar, from [File], [Preferences...], a window titled [Preferences] will pop up. Click on the [Security] at the bottom of the left side menu. There will be a [Authorities...] button at the upper right. Click on the button. A window titled [Certificate Authorities] will pop up. Click on the [Import...] button at the upper right, find out our root CA and double click to import it. That’s all.

    + + +

    Lynx

    + +

    Until the time this article is written, Lynx (2.8.4) does not verify SSL certificates of the servers.

    + + +

    Configure the E-mail Programs

    + +

    Mozilla/Netscape 6 or Newer

    + +

    To receive mails using SSL, start your Mozilla/Netscape Mail & Newsgroups. Starting from the tool bar, from [Edit], [Mail & Newsgroups Account Settings...], a window titled [Mail & Newsgroups Account Settings] will pop up. Click the [Server Settings] below the account you want to configure in the left side menu. Fill your POP3 mail server’s full qualified domain name (FQDN) in the [Server Name:] at the right side of the window, and check the [Use secure connection (SSL)] below. Then click [OK]. That’s all.

    + +

    To send mails using SSL, start your Mozilla/Netscape Mail & Newsgroups. Starting from the tool bar, from [Edit], [Mail & Newsgroups Account Settings...], a window titled [Mail & Newsgroups Account Settings] will pop up. Click the [Outgoing Server (SMTP)] in the left side menu. The title of the right side will become [Outgoing Server (SMTP) Settings]. Fill your POP3 mail server’s full qualified domain name (FQDN) in the [Server Name:] at the right side of the window. There’s a [Use secure connection (SSL):] below. Choose [When available] there. Then click [OK]. That’s all.

    + +

    Mozilla/Netscape Mail & Newsgroups ultilizes the certificate database of Mozilla/Netscape 6. Our root CA is available as long as it is imported into this certificate database. Refer to Configure Mozilla/Netscape 6 or Newer for more details.

    + + +

    Netscape 4 or Earlier

    + +

    Netscape 4 or earlier does not support SSL.

    + + +

    Outlook Express 5.5/6

    + +

    To receive mails using SSL, start your Outlook Express. Starting from the tool bar, from [Tools], [Accounts...], a window titled [Internet Accounts] will pop up. Click on the account you want to configure at the left side, and click the [Properties] at the right side. A window titled [XXXXXX Properties] will pop up. Click on the [Servers] tab at the top to move to the [Servers] page. Fill your POP3 mail server’s full qualified domain name (FQDN) in the [Incoming mail (POP3):]. Now click the [Advanced] tab at the top to move to the [Advanced] page. Check the [This server requires a secure connection (SSL)] below the [Incoming mail - POP3:]. Then click [OK]. That’s all.

    + +

    To send mails using SSL, start your Outlook Express. Starting from the tool bar, from [Tools], [Accounts...], a window titled [Internet Accounts] will pop up. Click on the account you want to configure at the left side, and click the [Properties] at the right side. A window titled [XXXXXX Properties] will pop up. Click on the [Servers] tab at the top to move to the [Servers] page. Fill your SMTP mail server’s full qualified domain name (FQDN) in the [Outgoing mail (SMTP):]. Now click the [Advanced] tab at the top to move to the [Advanced] page. Check the [This server requires a secure connection (SSL)] below the [Outgoing mail - SMTP:], and change the port number in the [Outgoing mail - SMTP:] to 465. Then click [OK]. That’s all.

    + +

    Outlook Express ultilizes WINDOWS’s common system certificate database. Our root CA is available as long as it is imported into this certificate database. Refer to Configure MS-WINDOWS for more details.

    + + +

    Outlook Express 4/5

    + +

    To receive mails using SSL, start your Outlook Express. Starting from the tool bar, from [Tools], [Accounts...], a window titled [Internet Accounts] will pop up. Click on the account you want to configure at the left side, and click the [Properties] at the right side. A window titled [XXXXXX Properties] will pop up. Click on the [Servers] tab at the top to move to the [Servers] page. Fill your POP3 mail server’s full qualified domain name (FQDN) in the [Incoming mail (POP3):]. Now click the [Advanced] tab at the top to move to the [Advanced] page. Check the [This server requires a secure connection (SSL)] below the [Incoming mail - POP3:]. Then click [OK]. That’s all.

    + +

    To send mails using SSL, start your Outlook Express. Starting from the tool bar, from [Tools], [Accounts...], a window titled [Internet Accounts] will pop up. Click on the account you want to configure at the left side, and click the [Properties] at the right side. A window titled [XXXXXX Properties] will pop up. Click on the [Servers] tab at the top to move to the [Servers] page. Fill your SMTP mail server’s full qualified domain name (FQDN) in the [Outgoing mail (SMTP):]. Now click the [Advanced] tab at the top to move to the [Advanced] page. Check the [This server requires a secure connection (SSL)] below the [Outgoing mail - SMTP:], and change the port number in the [Outgoing mail - SMTP:] to 465. Then click [OK]. That’s all.

    + +

    Outlook Express 4/5 does not verify SSL certificates of the servers.

    + + +

    Eudora 5.1 or Newer

    + +

    Eudora has bad SSL design.

    + +

    There is a [Certificate Infomation Manager] in Eudora after Eudora 5.1, that can manage the Eudora certificate database. But there’s no way to go to this [Certificate Infomation Manager] directly[23]. You have to check your mails once with SSL first, then you can enter this [Certificate Infomation Manager][24].

    + +

    When receiving mails, Eudora tries STARTTLS to negotiate with the mail server first. If it succeeds, both sides will enter SSL and Eudora will start to receive mails. Otherwise, it will still start to receive mails without SSL encryption as usual. You don’t have to configure SSL specifically. But there’s a big problem in Eudora’s STARTTLS approach. If, after STARTTLS succeeds and both sides enter SSL, Eudora fails to verify the mail server’s certificate, it will stop receiving mails and close the connection immediately. It will not try to connect again without SSL, nor will it ask the user for the action to take. Only a small warning will be displayed at the bottom of Eudora in that case. If you add STARTTLS support to your mail server just now with a self-issued server certificate, your user’s previously-working Eudora will stop working without asking the user. Your innocent Eudora users may panic. That’s another big problem with Eudora’s SSL design. After all, it is really meaningless to verify certificates in TLS. Also, Eudora should ask the user, but not close the connection immediately, since the reason of certificate verification failure is merely that the issuer of the certificate is not recognized by Eudora, but not that there’s really any problem with the certificate itself.

    + +

    CAUTION: OpenSSL’s default certificate file format is PEM, so we were all working on PEM certificate files previously. But Eudora can only read DER certificate files. PEM files are merely Base64-encoded DER files, to be compatible with the traditional 7-bit networks, so that they can be put onto the web sites, sent with e-mails or embedded into text files. We can convert PEM files to DER files with OpenSSL:

    + +
    +
    +# Convert our root CA into DER files
    +openssl x509 -in myrootca.crt -outform der -out myrootca-der.crt
    +
    +
    + +

    To receive mails using SSL, start your Eudora. Starting from the tool bar, from [Tools], [Options...], a window titled [Options] will pop up. Click on [Checking Mail] from the [Category] left side menu. Fill your POP3 mail server’s full qualified domain name (FQDN) in the [Mail Server:] at the right side. Choose [If available, STARTTLS] in [Secure Sockets when Receiving:] at the lower right. Then click [OK]. That’s all.

    + +

    To send mails using SSL, start your Eudora. Starting from the tool bar, from [Tools], [Options...], a window titled [Options] will pop up. Click on [Sending Mail] from the [Category] left side menu. Fill your SMTP mail server’s full qualified domain name (FQDN) in the [Mail Server:] at the right side. Choose [If available, STARTTLS] in [Secure Sockets when Receiving:] at the lower right. Then click [OK]. That’s all.

    + +

    To add our CA in, you have to check your mails once first. There will be a error messages [SSL Negotiation Failed: Certificate Error: Cert Chain not trusted. ...] at the bottom of Eudora. Go to [Tools], [Options...], [Category], [Checking Mail], [Secure Sockets when Receiving:], as described above. Click on [Last SSL Info] below. A window titled [Eudora SSL Connection Infomation Manager] will pop up and display our certificate it just obtained from the server. Click on [Certificate Infomation Manager] at the bottom. Another window titled [Certificate Infomation Mangaer] will pop up. Now click on [Import Certificate] at the lower right, find out our root CA’s DER file myrootca-der.crt and double click to import it. That’s all.[25]

    + + +

    Becky!

    + +

    Tomohiro Norimatsu, the author of Becky!, had said that due to SSL patent issues, Becky! will not have SSL support.[26] But we can still use a SSL wrapper to enable Becky! to send and receive mails through SSL connections. Refer to Configure Programs That Do Not Support SSL/TLS for more details.

    + + +

    Opera Mail

    + +

    To receive mails using SSL, start your Opera. Starting from the tool bar, from [File], [Preferences...], a window titled [Preferences] will pop up. Click on [E-mail] from the [Category] left side menu. There will be a [Use Opera account] menu at the right side. Choose the account you want to configure, and click the [Properties...] beside. A window titled [E-mail account properties...] will pop up. Click on the [Servers] tab at the top to move to the [Servers] page. In the [Incoming] section, fill your POP3 mail server’s full qualified domain name (FQDN) in the [Server], and check the [TLS] beside the [Protocol] menu below. Then click [OK]. That’s all.

    + +

    To send mails using SSL, start your Opera. Starting from the tool bar, from [File], [Preferences...], a window titled [Preferences] will pop up. Click on [E-mail] from the [Category] left side menu. There will be a [Use Opera account] menu at the right side. Choose the account you want to configure, and click the [Properties...] beside. A window titled [E-mail account properties...] will pop up. Click on the [Servers] tab at the top to move to the [Servers] page. In the [Outgoing] section, fill your SMTP mail server’s full qualified domain name (FQDN) in the [Server], and check the [TLS] beside the [Protocol] menu below. Then click [OK]. That’s all.

    + +

    Opera Mail ultilizes the certificate database of Opera. Our root CA is available as long as it is imported into this certificate database. Refer to Configure Opera for more details.

    + + +

    Configure Programs That Do Not Support SSL/TLS

    + +

    Help! My program does not support SSL/TLS!

    + +

    It’s OK. We can use a SSL wrapper to build the SSL connection first, forward the commands from our program to the server through this SSL connection, and forward the response from the server through this SSL connection back to our program. By this way, we can enable our non-SSL programs to send and receive information through this SSL-encrypted connection. We’ll introduce an SSL wrapper below:

    + + +

    Stunnel

    + +

    You can downnload Stunnel from its web site at http://www.stunnel.org/. It’s a easy-to-use SSL wrapper that can be run under WINDOWS. To run Stunnel under WINDOWS, follow the simple instruction below:

    + +
      +
    • Download stunnel-x.xx.exe, libssl32.dll and libeay32.dll from the web site of Stunnel at http://www.stunnel.org/.
    • + +
    • Save your downloaded libssl32.dll and libeay32.dll into C:\WINDOWS\SYSTEM (for WINDOWS 98/ME) or C:\WINNT\SYSTEM32 (for WINDOWS NT/2000/XP).
    • + +
    • Create a new directory Stunnel under C:\Program Files, and save your downloaded stunnel-x.xx.exe here.
    • + +
    • Create a new file stunnel.conf under C:\Program Files\Stunnel, as the following example: + +
      +
      +client = yes
      +
      +[pop3s]
      +accept = localhost:50110
      +connect = my.mail.server:995
      +
      +[smtps]
      +accept = localhost:50025
      +connect = my.mail.server:465
      +
      +
      +
    • + +
    • Run the C:\Program Files\Stunnel\stunnel-x.xx.exe. It will shrink to a small icon to the right of the tool bar at the bottom of your desktop. If you go to [MS-DOS Mode] or [Command Prompt] now and type: + +
      +
      +netstat -an
      +
      +
      + +you’ll see something like this: + +
      +
      +TCP    127.0.0.1:50025        0.0.0.0:0              LISTENING
      +TCP    127.0.0.1:50110        0.0.0.0:0              LISTENING
      +
      +
      + +Double click on the small Stunnel icon at the right of the tool bar will display the logs of Stunnel.
    • + +
    • Start your program. Modify your settings: Change your SMTP from my.mail.server port 25 to localhost port 50025. Change your POP3 from my.mail.server port 110 to localhost port 50110.
    • + +
    • Check your mails.
    • + +
    + +

    That’s all. We have turn a non-SSL prorgam to send and receive data through SSL with Stunnel.

    + +

    This is only the basic of Stunnel. Stunnel itself is rather +powerful. It can forward all kinds of protocols: POP3, SMTP, IMAP, NNTP, LDAPetc.. It can even reversely forward SSL connection to non-SSL services, so that clients can use SSL even the server itself does not support SSL. Please download the source package of Stunnel and refer to its manual inside.

    + +

    But there’s a limitation to Stunnel: Stunnel does not support the TLS STARTTLS command. Stunnel works by building the SSL connection first and forward all the network traffic through that connection. It does not understand the specific protocol at all. Due to this limitation, it can only support the traditional full SSL.

    + + +

    Review and Discussion

    + +

    Introduction to SSL/X.509

    + +
    + The X.509 Hierarchical Structure
    + The X.509 Hierarchical Structure
    +
    + +

    SSL adopts the X.509 hierarchical certificate system.

    + +

    In X.509, every valid certificate has a signature. Every valid server certificate at the bottom level has a signature from its administrative CA. It means that this CA had verified that the infomation on this certificate is correct. Every intermediate CA has also a signature from its administrative root CA. It means that this root CA had authorized this CA to sign certificates. But root CAs have no administrative CAs anymore. No administrative CAs can sign root CAs. Root CAs have to sign themselves.

    + +

    SSL programs themselves recognize some reliable CAs in advance. When an SSL program encounters an SSL site, it may not recognize the received certificate from that site. But if it can recognize the signature on that certificate was signed by a recognized and truested CA, it can then know that this CA guaranteed that this certificate is OK.

    + +
    + When an SSL program meets a valid certificate
    + When an SSL program meets a valid certificate
    +
    + +

    But, on the contrary, if it cannot recognize the signature of that certificate, it cannot decide whether that certificate is OK or not. It will warn the user, then.

    + +
    + When an SSL program meets a suspicious certificate
    + When an SSL program meets a suspicious certificate
    +
    + + +

    Warning: Invalid Certificate

    + +

    At the beginning of this article we have discussed how to create our own root CA. Since this CA is made by ourself, the SSL program has no way to know it. Then, the signature on our certificate in the second step will not be recognized by the SSL program, either. Our SSL program will always issue a certificate invalidity warning.

    + +
    + When an SSL program meets our CA
    + When an SSL program meets our CA
    +
    + +

    If you want to eliminate this warning, you have to teach the SSL program to recognize our CA first. After that, the SSL program will be able to recognize the CA signature on our certificate. It will not issue certificate invalidity warnings any more.

    + +
    + Add our own CA in
    + Add our own CA in
    +
    + +

    Refer to discussions in Configure the Operating Systems, Configure the Browsers and Configure the E-mail Programs for how to do this.

    + +

    CAUTION: This practice requires you to manually add your CA into the SSL programs. For this reason, it is only practical for private servers, where you can add your CA into a limited number of SSL programs of nearby users, one by one. It is not possible if you are working on a public server. There is no way to add your CA into the SSL programs of numerous internet users around the world. This is due to the limitation of X.509. I can do nothing about it. If you do need SSL on your public server and care about this warning, please apply for a certificate from one of the major CAs. It costs about USD 1,000 per year.

    + + +

    Wait! What Data?

    + +

    Wait! In the last step of your illustration, it says OK. This is the data for you. But I haven’t fill in any data yet! How can it send my data by itself? What does it send? Will it automatically send my e-mail address, credit card number, my passwords to the server?

    + +

    It sends the server the symmetric key for the following encrypted connection.

    + +

    The asymmetric public/private key encryption is safe. You can release your public key to the world. Just keep your private key secretly. If someone wants to send you secret infomation and encrypts it with your public key, there’s no one in the world but who knows your private key (that is, you) can decrypt and see it. But it’s slow. On the contrary, the traditional symmetric encryption is fast. But both of you have to know the same key. It risks the danger that your key might be leaked out when you tell it to the other.

    + +

    SSL uses a two-step encryption: In the beginning it uses the asymmetric public/private key encryption to send the other end the symmetric key of the following actual communication. Then, it uses this symmetric key to communicate with each other. The actual encryption in use is symmetric encryption. This symmetric key is generated randomly and sent to the other end with the public/private key encryption. It changes upon each connection. Using this two-step theme, we can enjoy the fast encryption speed without worrying the disclosure of the encryption key.

    + + +

    So, SSL is safe now?

    + +

    Now that the SSL site’s certificate is valid, with a signature from a most trustworthy CA. Is it safe to send my credit card number now?

    + +

    No.

    + +

    Watch closely to the previous section on Introduction to SSL/X.509. In SSL/X.509, the signature of the CA merely assures that This public key really belongs to this very server of this very company. In other words, it only guarantees that Your credit card number will be handed to this very company. No other people can peek at your communication. But this does not imply that This company is honest. It will not abuse the received credit card number. It will not side record your credit card number. It will not request for additional payment. It will not sell your number to anyone. This also does not imply that This company takes great care on the server security. Nobody will be able to intrude this server and install a credit card number recorder stealthily.

    + +

    That’s right. SSL can only ensure that the received public key is not a fake. It cannot ensure that this company itself is honest. Even that this company is honest, it may still be the target of some bad intruder.

    + +

    OK, then, what should I do now? How can I send my infomation safely?

    + +

    You’re always careful when you deal with an unfamiliar store in the real world. It’s the same on the internet. You have to be careful making any transaction with any unfamiliar website, too. Think twice: Do I trust this company? Is this infomation important to me? For ex., for the guestbook messages, discussions, votes that are not so personal, you can send them freely. But for your real name, your cellular phone number, your home number, your credit card number, your e-mail address, etc., you should only give them to those that have your full trust.

    + + +

    What Is a Digital Signature?

    + +

    A digital signature is a piece of digest code, resulted from some source infomation and a private key. It is calculated with some digest hash algorithm (like SHA1). As long as the source infomation is changed, the resulted digest will be different, too. You can check the digest by a private key with its corresponding public key. Verifying the source infomation with the resulted digest by the corresponding public key, you can know that whether this source infomation is the same as the one signed by this private key, and whether this infomation was tempered by somebody.

    + +

    It’s much the same like making a big signature on the whole contract. People know your handwriting. They will know whenever someone writes over this contract.

    + +

    Since digital signatures can be used to check whether the source information is temptered or not, we can apply them to the certificates. The CA verifies if the owner infomation came with this public key is correct. If the infomation is correct, the certificate authority will use its private key to sign this applicant, as a certificate. Then, when someone receives this public key, she can verify its CA signature to know if its owner infomation is correct, if this key is owned by this company, and thus, if this server is indeed owned by this company.

    + + +

    What Is a Certificate?

    + +

    A certificate is a public key, attached with its owner’s infomation (company name, server name, personal real name, contact e-mail, postal address, etc) and digital signatures. There will be one or more digital signatures attached on the certificate, indicating that these signers have verified that the owner infomation of this certificate is correct.

    + +

    In X.509, each valid certificate has exactly one signature from a CA. It means that this CA has verified the owner infomation on this certificate is correct. When an SSL program sees an unknown certificate, as long as that certificate has a valid CA signature on it, the program can be sure that this CA has verified the owner infomation on this certificate is correct.

    + + +

    What Is a CA?

    + +

    CA is the abbreviation of Certificate Authority. CA is a part of the X.509 system. It is itself a certificate, too, attached with the owner infomation of this certificate authority. But its purpose is not to do encryption/decryption. Its purpose is to sign and issue certificates, in order to prove the owner infomation of that certificate is correct. Refer to the illustration in Introduction to SSL/X.509.

    + +

    Each valid CA has exactly one signature, too, from its governmental root CA. It means that this root CA has authorized this CA to issue certificates. When an SSL program sees an unknown certificate, whose signer CA is also unknwon, as long as that signer CA has a valid root CA signature on it, the program can be sure that this root CA has authorized this CA to issue certificates. The certificates issued by this CA will be valid, too.

    + + +

    What is a Root CA?

    + +

    Root CA is also a part of the X.509 system. It is itself a CA, too. Its difference from an ordinary CA is that, its purpose is not to issue certificates directly, but to authorize some intermediate CAs the priviledge to issue certificates. Refer to the illustration in Introduction to SSL/X.509.

    + +

    Since root CAs are highest, no more higher governmental CA can sign them. They can only have their own signatures. There is no another’s signature on a root CA, nobody to guarantee that a root CA is valid. There is no way to further verify a root CA. Thus, an SSL program must recognize some trustworthy root CAs in advance. It must know the public keys of these trustworthy root CAs.

    + +

    Since root CAs cannot be further verified, they have to be world-wide famous for its trustworthiness. If there’s an suspicious root CA sneaking into the SSL prorgam’s known root CA list, the security will be void whenever the program meets a certificate issued by that suspicious root CA. Thus, in X.509, an SSL program must take great care protecting its known root CA list. It should not let its user add new root CAs casually.

    + + +

    How to Fill in the Certificate Request?

    + +

    Consult the following example if you have no idea how to fill in the certificate request.

    + +
    +
    +You are about to be asked to enter information that will be incorporated
    +into your certificate request.
    +What you are about to enter is what is called a Distinguished Name or a DN.
    +There are quite a few fields but you can leave some blank
    +For some fields there will be a default value,
    +If you enter '.', the field will be left blank.
    +-----
    +Country Name (2 letter code) [AU]:TW
    +State or Province Name (full name) [Some-State]:Taiwan
    +Locality Name (eg, city) []:Taipei City
    +Organization Name (eg, company) [Internet Widgits Pty Ltd]:Tavern IMACAT's
    +Organizational Unit Name (eg, section) []:Owner
    +Common Name (eg, YOUR name) []:Tavern IMACAT's
    +Email Address []:imacat@mail.imacat.idv.tw
    +
    +Please enter the following 'extra' attributes
    +to be sent with your certificate request
    +A challenge password []:
    +An optional company name []:
    +
    +
    + +
      + +
    1. You have to fill everything in English (ASCII characters). Only ASCII English characters are allowed in X.509 certificates.
    2. + +
    3. Country Name is the two-letter upper-cased country code. The country code of Taiwan is TW. Refer to the ISO-3166 two-letter country code list if you are not in Taiwan.
    4. + +
    5. State Name is the full name of your country. You cannot fill in the country code above here. Fill in Taiwan here if you are in Taiwan.
    6. + +
    7. Locality Name is your place name. Fill in your city or your county here.
    8. + +
    9. Organization Name is the name of your organization. Fill in the name of your company name, your school or your institution here.
    10. + +
    11. Organizational Unit Name is the name of your department. Fill in the name of your department or your unit here.
    12. + +
    13. Organizational Unit Name is the name of this certificate. If this is a root CA, fill in the previous organization name here. You may append a RSA/4096 after the name to identify this CA in the future. If this is a server certificate, fill in the full qualified domain name of the server (www.abc.com) here. If this is an e-mail certificate, fill in your e-mail here.
    14. + +
    15. E-mail Address is the contact e-mail address of the applicant. Fill in your contact e-mail address here.
    16. + +
    17. A challenge password is the password for this certificate request. But we don’t need a password for the request. Leave it blank.
    18. + +
    19. An optional company name is name of the certificate application agent. Leave it blank, too.
    20. + +
    + + +

    Review to the X.509 Certificate System

    + +

    X.509 certificate system is a hierarchy. There are a few topmost trustworthy root CAs that are known in advance.

    + +

    (To be continued…)

    + + +
    by imacat, first written 2002-01-09, last updated 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/sslcerts.html.zh-cn.html b/htdocs/imacat/tech/sslcerts.html.zh-cn.html new file mode 120000 index 0000000..88353c5 --- /dev/null +++ b/htdocs/imacat/tech/sslcerts.html.zh-cn.html @@ -0,0 +1 @@ +sslcerts.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/sslcerts.html.zh-cn.xhtml b/htdocs/imacat/tech/sslcerts.html.zh-cn.xhtml new file mode 100644 index 0000000..3939948 --- /dev/null +++ b/htdocs/imacat/tech/sslcerts.html.zh-cn.xhtml @@ -0,0 +1,1581 @@ + + + + + + + + + + + + + + + + + + + + + +如何制作 SSL X.509 凭证? + + + + + + + +
    + +
    + + +

    如何制作 SSL X.509 凭证?

    + +

    目录

    + +
      +
    1. 前言
    2. +
    3. 若你是 root +
        +
      1. 设定 OpenSSL 的环境
      2. +
      3. 制作最高层认证中心 (Root CA) +
          +
        1. 制作 Public/Private Key
        2. +
        3. 填写凭证申请书
        4. +
        5. 签发凭证
        6. +
        +
      4. +
      5. 制作伺服器用的凭证 +
          +
        1. 制作 Public/Private Key
        2. +
        3. 填写凭证申请书
        4. +
        5. 签发凭证
        6. +
        +
      6. +
      +
    4. +
    5. 若你是一般使用者 +
        +
      1. 设定 OpenSSL 的环境
      2. +
      3. 制作最高层认证中心 (Root CA) +
          +
        1. 制作 Public/Private Key
        2. +
        3. 填写凭证申请书
        4. +
        5. 签发凭证
        6. +
        +
      4. +
      5. 制作伺服器用的凭证 +
          +
        1. 制作 Public/Private Key
        2. +
        3. 填写凭证申请书
        4. +
        5. 签发凭证
        6. +
        +
      6. +
      +
    6. +
    7. 设定作业系统 +
        +
      1. Linux/*BSD/UNIX
      2. +
      3. MS-WINDOWS
      4. +
      +
    8. +
    9. 设定伺服器 +
        +
      1. HTTP +
          +
        1. Apache
        2. +
        +
      2. +
      3. POP3 +
          +
        1. Qpopper
        2. +
        +
      4. +
      5. SMTP +
          +
        1. Sendmail
        2. +
        +
      6. +
      +
    10. +
    11. 设定浏览器 +
        +
      1. Mozilla 与 Netscape 6 以后的版本
      2. +
      3. Internet Explorer
      4. +
      5. Opera
      6. +
      7. Lynx
      8. +
      +
    12. +
    13. 设定电子邮件程式 +
        +
      1. Mozilla 与 Netscape 6 以后的版本
      2. +
      3. Netscape 4 及更早的版本
      4. +
      5. Outlook Express 6
      6. +
      7. Outlook Express 5.5
      8. +
      9. Outlook Express 4/5
      10. +
      11. Eudora 5.1 以后的版本
      12. +
      13. Becky!
      14. +
      15. Opera 邮件
      16. +
      +
    14. +
    15. 设定其她不支援 SSL/TLS 的程式 +
        +
      1. Stunnel
      2. +
      +
    16. +
    17. 观念讨论 +
        +
      1. SSL/X.509 简介
      2. +
      3. 凭证无效的警告
      4. +
      5. 资料?什么资料?
      6. +
      7. 所以 SSL 就安全了罗?
      8. +
      9. 什么是数位签名?
      10. +
      11. 什么是凭证?
      12. +
      13. 什么是认证中心?
      14. +
      15. 什么是最高层认证中心?
      16. +
      17. 如何填写凭证申请书
      18. +
      19. X.509 凭证制度的检讨
      20. +
      21. 其她 SSL/X.509 凭证的做法
      22. +
      +
    18. +
    19. 注释
    20. +
    21. 参考资料
    22. +
    23. 后记
    24. +
    + + +

    前言

    + +

    版权所有 © 2002-2006 依玛猫。依玛猫保有所有权利。如欲转载、引用本文,请先详阅旅舍依玛版权声明

    + +

    本文的目的为:在 Linux/*BSD/UNIX 下,用 OpenSSL ,以自己名字发行X.509 SSL 凭证 (Certificate) 。我们会制作两个凭证:第一步先做以自己为名 (XXX Association, YYY Corporation) ,自己签名背书的最高层认证中心 (Root CA) ,第二步再做以伺服器为名 (www.abccompany.com) ,用第一步做的最高层认证中心 (XXX Association, YYY Corporation) 签发的凭证 (Certificate) 。为简化起见,我们不做中间的认证中心,直接由最高层认证中心 (Root CA) ,来签发凭证。

    + +

    本文只讨论 SSL X.509 凭证做法,不讨论系统安全问题,不讨论加解密的演算法,也不讨论 OpenSSL 的如何安装。我假设你了解基本 Public Key/Private Key 不对称加解密的观念,知道什么是 RSA/DSA 演算法。我也假设你已经装好了 OpenSSL ,安装时使用下列符合FHS[1] 标准的设定:

    + +
    +
    +./config --prefix=/usr --openssldir=/usr/share/ssl
    +
    +
    + +

    或安装 RPM 或 apt 的 openssl 套件。

    + +

    本文是做法教学 (HOWTO) ,所以在编排上,把做法步骤 (how) 放在最前面,观念说明和讨论 (what and why) 等,都放在文末。若你看不懂做法,或想先学一些基本概念,请先往后翻阅,不需由前到后阅读。

    + +

    注意:依本文制作的凭证,还是会在浏览器等 SSL 程式上出现凭证无效的警告。详情请参考SSL/X.509 简介凭证无效的警告

    + +

    按 X.509 的规定,凭证可以用 RSA Key ,也可以用 DSA Key 。不过在 SSL 通讯中,伺服器的凭证因为要用来传 Key ,而只有 RSA 可以传 Key ,所以只能用 RSA 。至於认证中心,只是签名查核用,不用传 Key , DSARSA 都可以,但因为还有一些 SSL 程式不认得 DSA[2] ,为相容性起见,这里我们也做成 RSA

    + +

    要制作最高层认证中心,可以以一般使用者权限来做,不一定要是 root 。但如果做出来的最高层认证中心,是整个组织签发凭证要用的,建议以 root 的权限来做,比较安全。同理,制作凭证,也可以以一般使用者权限来做。但如果做出来的凭证,是这个伺服器要用的,为安全起见,建议以 root 的权限来做。

    + + +

    若你是 root ,要安装给整个组织来用:

    + +

    设定 OpenSSL 的环境

    + +

    若你是用上述方法安装:

    + +
    +
    +./config --prefix=/usr --openssldir=/usr/share/ssl
    +
    +
    + +

    或装 Red Hat 的 RPM , OpenSSL 的设定档目录会在 /usr/share/ssl 。若你是安装 Mandrake 的 RPM ,设定档目录会在 /usr/lib/ssl 。这两个位置都不符合 FHS 的要求,资料备份起来也不方便。设定档应该放在 /etc/ssl 下。若你是安装 Debian 的 apt ,设定档目录会在 /etc/ssl 下,不会有问题。

    + +
    +
    +# 设定相关的目录
    +mkdir -p /etc/ssl
    +mkdir -p /etc/ssl/private
    +chmod og-rwx /etc/ssl/private
    +mkdir -p /etc/ssl/certs
    +mkdir -p /etc/ssl/crl
    +mkdir -p /etc/ssl/newcerts
    +
    +# 设定 OpenSSL 设定档[3]
    +mv /usr/share/ssl/openssl.cnf /etc/ssl
    +ln -s /etc/ssl/openssl.cnf /usr/share/ssl/openssl.cnf
    +
    +# 设定 OpenSSL 设定档的位置[4]
    +export OPENSSL_CONF="/etc/ssl/openssl.cnf"
    +
    +# 把 OpenSSL 设定档的位置加进 .bashrc 中[5]
    +echo "# OpenSSL 设定档的位置" >> ~/.bashrc
    +echo "export OPENSSL_CONF=\"/etc/ssl/openssl.cnf\"" >> ~/.bashrc
    +
    +# 制作乱数档[6]
    +openssl rand -out /etc/ssl/private/.rand 1024
    +chmod og-rwx /etc/ssl/private/.rand
    +
    +
    + +

    然后修改 /etc/ssl/openssl.cnf ,把这一行

    +
    +
    +dir		= ./demoCA		# Where everything is kept
    +
    +
    +

    改成这样

    +
    +
    +dir		= /etc/ssl		# Where everything is kept
    +
    +
    + +

    制作最高层认证中心 (Root CA)

    + +

    若你之前做过最高层认证中心,不要重做,不然原来签发的凭证,都会失效,都要重签。除非最高层认证中心自己过期、档案遗失、 Private Key 外泄,否则绝对不要重做最高层认证中心。

    + +

    假设你要做的最高层认证中心叫做 myrootca

    + + +

    1. 制作 Private Key (及 Public Key )

    + +

    这里我们做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特别去做。

    + +

    请为最高层认证中心的 Private Key 设定一个适当的密码。

    + +
    +
    +# 制作 RSA[7] Private Key
    +openssl genrsa -aes256 -out /etc/ssl/private/myrootca.key.pem 4096
    +chmod og-rwx /etc/ssl/private/myrootca.key.pem
    +
    +
    + + +

    2. 填写凭证申请书

    + +

    凭证申请书,是把你的资料,和这个 Public Key 夹在一起,以便认证中心审核,签上签名用的。所以这个步骤,会问你这个 Key 的相关资料,包括国家、城市、单位名称、部门名称、凭证名称、联络人的信箱,以及申请的效期等等。请一一填写。详情请参考什么是凭证?

    + +

    若你要直接用最高层认证中心来直接当凭证用,凭证名称 (Common Name) 请用伺服器的全名 (www.abc.com) 。详情请参考其她 SSL/X.509 凭证的做法

    + +

    若不知如何填写,请参阅如何填写凭证申请书

    + +
    +
    +# 填写凭证申请书
    +openssl req -new -key /etc/ssl/private/myrootca.key.pem -out /tmp/myrootca.req.pem
    +
    +
    + + +

    3. 签发凭证

    + +

    最高层认证中心因为没有上级了,没有人能给它签名,只能自己给自己签名。详情请参考什么是最高层认证中心?

    + +

    最高层认证中心最好永远不要过期。要是过期重签,所有原来它签发的凭证也都要重签,所有 SSL 程式也都要重新设定。所以我们效期签7305 天( 20 年)。若不设效期的话,预设是 30 天(一个月)。

    + +

    签完凭证,凭证申请书就不用了,可以删掉。

    + +
    +
    +# 自己给自己签名
    +openssl x509 -req -days 7305 -sha512 \
    + -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
    + -signkey /etc/ssl/private/myrootca.key.pem \
    + -in /tmp/myrootca.req.pem -out /etc/ssl/certs/myrootca.crt.pem
    +
    +# 删除凭证申请书
    +rm -f /tmp/myrootca.req.pem
    +
    +# 建立 hash 索引
    +c_rehash /etc/ssl/certs
    +
    +
    + +

    这样就好了。 Private Key 在 +/etc/ssl/private/myrootca.key.pem ,自己签名的 Public Key 凭证在 /etc/ssl/certs/myrootca.crt.pemmyrootca.key.pem 是 Private Key ,要小心存好保护,只有 root 才能读,权限建议 0400 。 myrootca.crt.pem 是 Public Key 凭证,要尽量散出去,让大家用。最好放到内部网路上,或放到网站上,让大家自己下载,自己加进去。

    + + +

    制作伺服器用的凭证

    + +

    假设你要做 myhost 的凭证:

    + + +

    1. 制作 Private Key (及 Public Key )

    + +

    这里我们做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特别去做。

    + +

    请先登入到要用凭证的那台伺服器上。

    + +

    注意:伺服器的 Private Key 不要设密码,不然 SSL 伺服器程式启动的时候,一去读凭证和 Private Key ,就要问一次密码。每次重开机,依序启动每个伺服器程式的时候,一碰到要读 Private Key 的伺服器程式,都会停下来等键盘输入密码。要是放假没人,或伺服器放在 IDC 机房,从远端重开机或 Crash 后自行重开机,却当在那里等键盘敲密码,开不了机,那就不好玩了。

    + +
    +
    +# 制作 RSA Private Key
    +openssl genrsa -out /etc/ssl/private/myhost.key.pem 4096
    +chmod og-rwx /etc/ssl/private/myhost.key.pem
    +
    +
    + + +

    2. 填写凭证申请书

    + +

    凭证申请书,是把你的资料,和这个 Public Key 夹在一起,以便认证中心审核,签上签名用的。所以这个步骤,会问你这个 Key 的相关资料,包括国家、城市、单位名称、部门名称、凭证名称、联络人的信箱,以及申请的效期等等。这里凭证名称 (Common Name) 要用伺服器的全名 (www.abc.com) ,其她请一一填写。详情请参考什么是凭证?

    + +

    若不知如何填写,请参阅如何填写凭证申请书

    + +
    +
    +# 填写凭证申请书
    +openssl req -new -key /etc/ssl/private/myhost.key.pem -out /tmp/myhost.req.pem
    +
    +
    + + +

    3. 用最高层认证中心签发凭证[8]

    + +

    伺服器凭证的效期其实无所谓,过期重签一张就好了。 SSL 程式认的是认证中心,不是凭证,所以凭证签了就会生效,不用去设定 SSL 程式。不过为免重签的麻烦,我们效期还是签 3650 天(大约十年)。

    + +

    签完凭证,凭证申请书就不用了,可以删掉。

    + +
    +
    +# 签发凭证
    +openssl x509 -req -days 3650 -sha512 \
    + -extfile /etc/ssl/openssl.cnf -extensions v3_req \
    + -CA /etc/ssl/certs/myrootca.crt.pem -CAkey /etc/ssl/private/myrootca.key.pem \
    + -CAserial /etc/ssl/myrootca.srl -CAcreateserial \
    + -in /tmp/myhost.req.pem -out /etc/ssl/certs/myhost.crt.pem
    +
    +# 删除凭证申请书
    +rm -f /tmp/myhost.req.pem
    +
    +
    + +

    这样就好了。[9] Private Key 在 /etc/ssl/private/myhost.key.pem ,要小心存好保护,只有 root 才能读,建议权限为 0400 ; Public Key 凭证在 /etc/ssl/certs/myhost.crt.pem ,要尽量散出去,让大家用。这组 Public/Private Key 凭证可以做为 myhostSSL 凭证,用在 HTTPSPOP3/TLSSMTPS/TLS …等等各种 SSL 连线上。最好不要把档案搬到别的地方。你可以在设定档里,把凭证位置设定到这里。 PrivateKey 不要到处放,以免不小心忘记保护。

    + + +

    若你是一般使用者:

    + +

    设定 OpenSSL 的环境

    + +
    +
    +# 设定相关的目录
    +mkdir -p ~/etc
    +mkdir -p ~/etc/ssl
    +mkdir -p ~/etc/ssl/private
    +chmod og-rwx ~/etc/ssl/private
    +mkdir -p ~/etc/ssl/certs
    +mkdir -p ~/etc/ssl/crl
    +mkdir -p ~/etc/ssl/newcerts
    +mkdir -p ~/tmp
    +
    +# 设定 OpenSSL 设定档[10]
    +cp /usr/share/ssl/openssl.cnf ~/etc/ssl
    +
    +# 设定 OpenSSL 设定档的位置[11]
    +export OPENSSL_CONF="$HOME/etc/ssl/openssl.cnf"
    +
    +# 把 OpenSSL 设定档的位置加进 .bashrc 中[12]
    +echo "# OpenSSL 设定档的位置" >> ~/.bashrc
    +echo "export OPENSSL_CONF=\"$HOME/etc/ssl/openssl.cnf\"" >> ~/.bashrc
    +
    +# 制作乱数档[13]
    +openssl rand -out ~/etc/ssl/private/.rand 1024
    +chmod og-rwx ~/etc/ssl/private/.rand
    +
    +
    + +

    然后修改 ~/etc/ssl/openssl.cnf ,把这一行

    +
    +
    +dir		= ./demoCA		# Where everything is kept
    +
    +
    +

    改成这样

    +
    +
    +dir		= ~/etc/ssl		# Where everything is kept
    +
    +
    + + +

    制作最高层认证中心 (Root CA)

    + +

    若你之前做过最高层认证中心,不要重做,不然原来签发的凭证,都会失效,都要重签。除非最高层认证中心自己过期、档案遗失、 Private Key 外泄,否则绝对不要重做最高层认证中心。

    + +

    假设你要做的最高层认证中心叫做 myrootca

    + + +

    1. 制作 Private Key (及 Public Key )

    + +

    这里我们做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特别去做。

    + +

    请为最高层认证中心的 Private Key 设定一个适当的密码。

    + +
    +
    +# 制作 RSA[14] Private Key
    +openssl genrsa -aes256 -out ~/etc/ssl/private/myrootca.key.pem 4096
    +chmod og-rwx ~/etc/ssl/private/myrootca.key.pem
    +
    +
    + + +

    2. 填写凭证申请书

    + +

    凭证申请书,是把你的资料,和这个 Public Key 夹在一起,以便认证中心审核,签上签名用的。所以这个步骤,会问你这个 Key 的相关资料,包括国家、城市、单位名称、部门名称、凭证名称、联络人的信箱,以及申请的效期等等。请一一填写。详情请参考什么是凭证?

    + +

    若不知如何填写,请参阅如何填写凭证申请书

    + +

    若你要直接用最高层认证中心来直接当凭证用,凭证名称 (Common Name) 请用伺服器的全名 (www.abc.com) 。详情请参考其她 SSL/X.509 凭证的做法

    + +
    +
    +# 填写凭证申请书
    +openssl req -new -key ~/etc/ssl/private/myrootca.key.pem -out ~/tmp/myrootca.req.pem
    +
    +
    + + +

    3. 签发凭证

    + +

    最高层认证中心因为没有上级了,没有人能给它签名,只能自己给自己签名。详情请参考什么是最高层认证中心?

    + +

    最高层认证中心最好永远不要过期。要是过期重签,所有原来它签发的凭证也都要重签,所有 SSL 程式也都要重新设定。所以我们效期签 7305 天(大约 20年)。若不设效期的话,预设是 30 天(一个月)。

    + +

    签完凭证,凭证申请书就不用了,可以删掉。

    + +
    +
    +# 自己给自己签名
    +openssl x509 -req -days 7305 -sha512 \
    + -extfile ~/etc/ssl/openssl.cnf -extensions v3_ca \
    + -signkey ~/etc/ssl/private/myrootca.key.pem \
    + -in ~/tmp/myrootca.req.pem -out ~/etc/ssl/certs/myrootca.crt.pem
    +
    +# 删除凭证申请书
    +rm -f ~/tmp/myrootca.req.pem
    +
    +# 建立 hash 索引
    +c_rehash ~/etc/ssl/certs
    +
    +
    + +

    这样就好了。 Private Key 在 +~/etc/ssl/private/myrootca.key.pem ,自己签名的 Public Key 凭证在 ~/etc/ssl/certs/myrootca.crt.pemmyrootca.key.pem 是 Private Key ,要小心存好保护,只有自己才能读,权限建议 0400 。 myrootca.crt.pem 是 Public Key 凭证,要尽量散出去,让大家用。最好放到网站上,让大家自己下载,自己加进去。

    + + +

    制作伺服器用的凭证

    + +

    假设你要做 myhost 的凭证:

    + + +

    1. 制作 Private Key (及 Public Key )

    + +

    这里我们做一支新的 Private Key 。 Public Key 可由 Private Key 推得 +,所以不用特别去做。

    + +

    注意:伺服器的 Private Key 不要设密码,不然 SSL 伺服器程式启动的时候,一去读凭证和 Private Key ,就要问一次密码。每次重开机,依序启动每个伺服器程式的时候,一碰到要读 Private Key 的伺服器程式,都会停下来等键盘输入密码。要是放假没人,或伺服器放在 IDC 机房,从远端重开机或 Crash 后自行重开机,却当在那里等键盘敲密码,开不了机,那就不好玩了。

    + +
    +
    +# 制作 RSA Private Key
    +openssl genrsa -out ~/etc/ssl/private/myhost.key.pem 4096
    +chmod og-rwx ~/etc/ssl/private/myhost.key.pem
    +
    +
    + + +

    2. 填写凭证申请书

    + +

    凭证申请书,是把你的资料,和这个 Public Key 夹在一起,以便认证中心审核,签上签名用的。所以这个步骤,会问你这个 Key 的相关资料,包括国家、城市、单位名称、部门名称、凭证名称、联络人的信箱,以及申请的效期等等。这里凭证名称 (Common Name) 要用伺服器的全名 (www.abc.com) ,其她请一一填写。详情请参考什么是凭证?

    + +

    若不知如何填写,请参阅如何填写凭证申请书

    + +
    +
    +# 填写凭证申请书
    +openssl req -new -key ~/etc/ssl/private/myhost.key.pem -out /tmp/myhost.req.pem
    +
    +
    + + +

    3. 用最高层认证中心签发凭证[8][15]

    + +

    伺服器凭证的效期其实无所谓,过期重签一张就好了。 SSL 程式认的是认证中心,不是凭证,所以凭证签了就会生效,不用去设定 SSL 程式。不过为免重签的麻烦,我们效期还是签 3650 天(大约十年)。

    + +

    签完凭证,凭证申请书就不用了,可以删掉。

    + +
    +
    +# 签发凭证
    +openssl x509 -req -days 3650 -sha512 \
    + -extfile ~/etc/ssl/openssl.cnf -extensions v3_req \
    + -CA ~/etc/ssl/certs/myrootca.crt.pem -CAkey ~/etc/ssl/private/myrootca.key.pem \
    + -CAserial ~/etc/ssl/myrootca.srl -CAcreateserial \
    + -in /tmp/myhost.req.pem -out ~/etc/ssl/certs/myhost.crt.pem
    +
    +# 删除凭证申请书
    +rm -f /tmp/myhost.req.pem
    +
    +
    + +

    这样就好了。[16] Private Key 在 ~/etc/ssl/private/myhost.key.pem ,要小心存好保护,只有自己才能读,建议权限为 0400 ; Public Key 凭证在 ~/etc/ssl/certs/myhost.crt.pem ,要尽量散出去,让大家用。这组 Public/Private Key 凭证可以做为 myhostSSL 凭证,用在 HTTPSPOP3S/TLSSMTPS/TLS …等等各种 SSL 连线上。最好不要把档案搬到别的地方。你可以在设定档里,把凭证位置设定到这里。 PrivateKey 不要到处放,以免不小心忘记保护。

    + + +

    设定作业系统

    + +

    很多作业系统,都有系统公用的凭证库,把认得的凭证、认证中心放在一起。我们把我们自制的认证中心,加进系统公用的凭证库,使用这个凭证库的程式,就可以查得到了。

    + + +

    Linux/*BSD/UNIX

    + + +

    MS-WINDOWS

    + +

    MS-WINDOWS 设有共用的凭证库。从 [控制台] 进去,里面有 [网际网路选项] (或 [Internet 选项] )。在上面点两下,会打开一个[网际网路 内容] (或 [Internet 内容] )的视窗。在 [内容] 那一页里,中间有一区 [凭证] ,里面有一个 [凭证(C)...] 的按钮。按一下那个按钮,会打开一个视窗,标题是 [凭证] 。这里就是 MS-WINDOWS 管理凭证的地方。[20]

    + +

    要加进我们的最高层认证中心,将我们的最高层认证中心 myrootca.crt.pem 复制到 WINDOWS 上。点两下打开 myrootca.crt.pem ,会跳出一个 [凭证] 的视窗,里面会列出凭证的内容。按下面的 [安装凭证]按钮,会跑出一个 [凭证管理员汇入精灵] 。一直按 [下一步] ,就会加进去了。

    + +

    我所知道,会使用系统凭证库的 WINDOWS 程式,有 Internet Exporer 、 Outlook Express 、 Outlook 、 Symantec pcAnywhere 。只要把我们自制的认证中心加进来,这些程式都可以用得到。

    + + +

    设定伺服器

    + +

    常见的 SSL 通讯方式有两种:一种是传统的 SSL ,一种是新的 TLS

    + +

    传统的 SSL ,一连上伺服器,就进入 SSL ,全程加密。这样做有一个缺点:为了不让使用者程式混淆,要把SSL 开在另外一个 TCP 埠,还要设定使用者的程式,改连到 SSL 的那个 TCP 埠去。 HTTPHTTPS 的方式就是这样。

    + +

    新的 TLS ,则是在使用者程式连上伺服器后,下 STARTTLS 指令,如果伺服器有 SSL ,就会进入 SSL ,双方开始加密;如果伺服器没有 SSL ,看不懂 STARTTLS ,双方就按原来的方式继续连线。这样做的好处是,使用者程式不用改设连接埠,可以自行切入 SSL 或退回不加密连线,相容性高,也不用为了 SSL ,多开一个 TCP 埠。但 TLS 的缺点则是,就算凭证查核的结果有问题,不能做SSL ,还是可以退回原来的方式继续连线,那凭证查核的工作,有做等於没做。只有连线加密的的优点而已,无法查证伺服器的身份。

    + +

    以下依不同的通讯协定,分别讨论。

    + + +

    HTTP

    + +

    HTTP 是最早用 SSL 的通讯协定。 Netscape 当初是为了加密 HTTP ,做安全网路交易,才设计了 SSL ,开一个新的 TCP 埠 443 给它专用,取名为 HTTPS ,延用至今。因此, HTTPSSL 用的是传统的方式,没有 TLS ,要开 HTTPS(443) 。

    + + +

    Apache

    + +

    Apache 要做 HTTPS ,可以搭配 Apache-SSL ,或搭配 mod_ssl 。请参考各自的设定说明。

    + +

    注意:Apache 的记忆体中只能存一组凭证。而凭证上记有伺服器的全名,浏览器会用来核对网站站名,所以一个 Apache ,只能用一个 SSL 站名。也就是说,一个 Apache ,只能架一个 SSL 站。除非你跑很多份 Apache ,各自跑在不同的 IP 或不同的 TCP 埠上,才能在同一台伺服器上,跑好几个 SSL 站。

    + +

    以 mod_ssl 来说,安装好后, httpd.conf 设定举例如下:

    + +
    +
    +......
    +## mod_ssl.c: mod_ssl 基本设定
    +<IfModule mod_ssl.c>
    +    Listen 443
    +    AddType application/x-x509-ca-cert .crt
    +    AddType application/x-pkcs7-crl    .crl
    +    SSLSessionCache dbm:/var/log/apache/ssl_scache
    +    SSLSessionCacheTimeout 300
    +    SSLPassPhraseDialog builtin
    +    SSLMutex file:/var/log/apache/ssl_mutex
    +    SSLRandomSeed startup builtin
    +    SSLRandomSeed connect builtin
    +    SSLLog /var/log/apache/ssl_engine_log
    +    SSLLogLevel info
    +    SSLCipherSuite ALL:!ADH:!EXP56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
    +    SSLCertificateFile /etc/ssl/certs/myhost.crt.pem
    +    SSLCertificateKeyFile /etc/ssl/private/myhost.key.pem
    +    <VirtualHost *:443>
    +        SSLEngine on
    +    </VirtualHost>
    +</IfModule>
    +......
    +
    +
    + +

    设好后,检查看 httpd.conf 有没有设错:

    + +
    +
    +httpd -t
    +
    +
    + +

    要是没有问题,重开 httpdSSL 网站就开跑了。

    + + +

    POP3

    + +

    POP3 可以跑两种方式:传统用 POP3(995) 埠专跑 SSL ,或是用 TLS ,在原来的 POP3(110) 埠上,加上 STARTTLS 的功能。

    + +

    POP3 的 STARTTLS 指令是 STLS

    + + +

    Qpopper

    + +

    要安装 Qpopper ,请参考 Qpopper 的说明文件。

    + +

    Qpopper 可以做 POP3(995) ,也可以在 POP3(110) 上做 TLS 。然而,一个 Qpopper 只能开一个 TCP 埠,用一种方式跑。如果要同时做 POP3(995) 和 POP3(110)/TLS ,要跑两份 Qpopper,各自用不同的设定档。

    + +

    设定 /etc/qpopper.conf 如下:

    + +
    +
    +# qpopper.conf: Qpopper POP3(110)/TLS 的设定档
    +set clear-text-password         = always
    +set statistics                  = true
    +set tls-support                 = stls
    +set tls-private-key-file        = /etc/ssl/private/myhost.key.pem
    +set tls-server-cert-file        = /etc/ssl/certs/myhost.crt.pem
    +
    +
    + +

    设定 /etc/qpopper-s.conf 如下:

    + +
    +
    +# qpopper-s.conf: Qpopper POP3S(995) 的设定档
    +set clear-text-password         = tls
    +set statistics                  = true
    +set tls-support                 = alternate-port
    +set tls-private-key-file        = /etc/ssl/private/myhost.key.pem
    +set tls-server-cert-file        = /etc/ssl/certs/myhost.crt.pem
    +
    +
    + +

    然后用 root 的权限,分别执行:

    + +
    +
    +popper -f /etc/qpopper.conf
    +popper 995 -f /etc/qpopper-s.conf
    +
    +
    + +

    这样就可以了。查看:

    + +
    +
    +ps ax | grep popper
    +
    +
    + +

    你会看到有两个 popper ,用不同的参数在跑。查看:

    + +
    +
    +netstat -ap | grep popper
    +
    +
    + +

    你会看到两个 popper ,分别在 POP3(110) 和 POP3(995) 两个 TCP 埠上。

    + + +

    SMTP

    + +

    SMTP 也可以跑两种方式:旧式的做法,是另开一个 SMTPS(465) 埠,来专跑 SSL 。新的做法则用 TLS ,在原来的 SMTP(25) 埠上,加上 STARTTLS 的功能。 TLS 用同一个连接埠,相容性比较高,为邮件伺服器间收发信的相容性起见,请尽量采用 TLS[17]

    + +

    SMTP 的 STARTTLS 指令是 STARTTLS

    + + +

    Sendmail

    + +

    Sendmail 可以在编译时,加入 SMTPSTLS 的支援,不过 SMTPS 是属於 FFR (for future release) 尚未正式发表的功能,在所有 Sendmail 的说明文件中,都找不到 SMTPS 的说明,只有 TLS 的说明。

    + +

    Sendmail 送信时,只会在原来的 SMTP(25) 埠上,试 STARTTLS 指令。对方要是不支援 TLS 就算了,用原来不加密的方法寄信,不会去试对方的 SMTPS(465) 埠。

    + +

    为让邮件顺利流通,不要掉信, Sendmail 送信时,能加密就加密,不会查核对方的凭证。更何况,在 TLS 下查核凭证,也没什么意义。

    + +

    要设定 Sendmail 使用 SSL ,编译 Sendmail 时,要在 devtools/Site/site.config.m4 档,加入下列这几行:

    + +
    +
    +# STARTTLS - 加入 SSL/TLS 功能
    +APPENDDEF(`conf_sendmail_ENVDEF', `-DSTARTTLS')
    +APPENDDEF(`conf_sendmail_LIBS', `-lssl -lcrypto')
    +
    +# SMTP SSL - 加入 SMTPS 功能
    +APPENDDEF(`conf_sendmail_ENVDEF', `-D_FFR_SMTP_SSL')
    +
    +
    + +

    编译、安装:

    + +
    +
    +# 编译 Sendmail
    +./Build
    +
    +# 安装 Sendmail
    +make install
    +
    +
    + +

    接下来要设定 Sendmail 的设定档 /etc/mail/sendmail.cf 。如果你是用 m4 来做设定档,在 m4 档 config.mc 中加入下列几行:

    + +
    +
    +dnl Sendmail SMTPS/STARTTLS SSL 设定
    +define(`confCACERT_PATH', `/etc/ssl/certs')
    +define(`confCACERT', `/etc/ssl/certs/myrootca.crt.pem')
    +define(`confSERVER_CERT', `/etc/ssl/certs/myhost.crt.pem')
    +define(`confSERVER_KEY', `/etc/ssl/private/myhost.key.pem')
    +define(`confCLIENT_CERT', `/etc/ssl/certs/myhost.crt.pem')
    +define(`confCLIENT_KEY', `/etc/ssl/private/myhost.key.pem')
    +DAEMON_OPTIONS(`Name=MTA')dnl
    +DAEMON_OPTIONS(`Port=465, Name=MTASSL, M=s')dnl
    +
    +
    + +

    重做设定档:

    + +
    +
    +m4 m4/cf.m4 config.mc > config.cf
    +cp -f config.cf /etc/mail/sendmail.cf
    +
    +
    + +

    然后重开 Sendmail 。这样 Sendmail 就可以开始做 SMTPS/TLS SSL 了。查看:

    + +
    +
    +netstat -ap | grep sendmail
    +
    +
    + +

    你会看到同一个 sendmail ,跑在 SMTP(25) 和 SMTPS(465) 两个[18] TCP 埠上。

    + +

    不过设定还没结束。

    + +

    Sendmail 自 8.12.1 版以后,为加强安全性,将伺服器和使用者程式分开。伺服器程式因为要跑在低於 1024 的 SMTP(25) 埠,要有权限把信存进每个人的信箱,还是要以 root 的权限来执行。不过这只要以 root 来启动伺服器程式,就可以了。使用者程式则不需要 root 的权限,只要可以在专用的邮件伫列目录存档就够了。所以, Sendmail 不再 setuid root ,改成 setgid smmsp[19] 。使用者程式要发信的时候,再连到 SMTP 伺服器发信。

    + +

    Sendmail 伺服器程式因为有 root 的权限,要读 Private Key 不是问题。可是, Sendmail 使用者程式现在没有了 root 的权限,发信的时候,就读不到我们伺服器的 Private Key 了。怎么办?

    + +

    我们不要让 Sendmail setuid-root ,也不要开放伺服器 Private Key 的权限。我们可以另外做一组只有 smmsp 群组读得到的凭证,给 Sendmail 的使用者程式专用:

    + +
    +
    +# 设定目录
    +mkdir -p /etc/mail/private
    +chgrp smmsp /etc/mail/private
    +chmod o-rwx /etc/mail/private
    +mkdir -p /etc/mail/certs
    +
    +# 制作 RSA Private Key
    +openssl genrsa -out /etc/mail/private/myhost-msp.key.pem 4096
    +chgrp smmsp /etc/mail/private/myhost-msp.key.pem
    +chmod o-rwx /etc/mail/private/myhost-msp.key.pem
    +
    +# 填写凭证申请书
    +openssl req -new -key /etc/mail/private/myhost-msp.key.pem \
    + -out /tmp/myhost-msp.req.pem
    +
    +# 签发凭证
    +openssl x509 -req -days 3650 -sha512 \
    + -extfile /etc/ssl/openssl.cnf -extensions v3_req \
    + -CA /etc/ssl/certs/myrootca.crt.pem -CAkey /etc/ssl/private/myrootca.key.pem \
    + -CAserial /etc/ssl/myrootca.srl -CAcreateserial \
    + -in /tmp/myhost-msp.req.pem -out /etc/mail/certs/myhost-msp.crt.pem
    +
    +# 删除凭证申请书
    +rm -f /tmp/myhost-msp.req.pem
    +
    +
    + +

    然后设定 m4 档 submic.mc 如下:

    + +
    +
    +......
    +dnl Sendmail STARTTLS SSL/TLS support
    +define(`confCACERT_PATH', `/etc/ssl/certs')
    +define(`confCACERT', `/etc/ssl/certs/myrootca.crt.pem')
    +define(`confCLIENT_CERT', `/etc/mail/certs/myhost-msp.crt.pem')
    +define(`confCLIENT_KEY', `/etc/mail/private/myhost-msp.key.pem')
    +define(`confDONT_BLAME_SENDMAIL', `GroupReadableKeyFile')
    +......
    +
    +
    + +

    重做设定档:

    + +
    +
    +m4 m4/cf.m4 submit.mc > submit.cf
    +cp -f submit.cf /etc/mail/submit.cf
    +
    +
    + +

    这样就可以了。这不是设定 Sendmail 伺服器程式,不用重开 Sendmail 。 ^_*' 你可以寄一封信给自己,然后看看系统邮件记录 maillog ,有没有成功使用 SSL

    + +
    +
    +......
    +Sep 14 04:19:24 rinse sendmail[12093]: STARTTLS=client, relay=localhost.localdom
    +ain., version=TLSv1/SSLv3, verify=OK, cipher=EDH-RSA-DES-CBC3-SHA, bits=168/168
    +......
    +
    +
    + + +

    设定浏览器

    + +

    Mozilla 与 Netscape 6 以后的版本

    + +

    Mozilla 与 Netscape 6 以后的版本,有一个浏览器和邮件程式共用的凭证库。从工具列上的 [编辑(E)][个人功能设定(E)] 进去后,会跳出 [功能设定] 的视窗。展开视窗左边的 [个人及安全设定] ,点选里面的 [认证] ,右边的标题会切换成 [认证] ,中间会有一个 [管理认证...] 的按钮。按下按钮,会再跳出一个 [认证管理员] 的视窗。这里就是 Mozilla 与 Netscape 管理凭证的地方。[21][22]

    + +

    要加进我们的最高层认证中心,将我们的最高层认证中心 myrootca.crt.pem 放到网站上,用 Mozilla/Netscape 从 web 连到该网址后,会出现一个 [下载认证中] 的视窗。在 [信认此认证以识别网站][信认此认证以识别邮件用户][信认此认证以识别软体制造商] 三个选项上都打勾,然后按 [确定] ,就会加进去了。

    + +

    如果你用的是 MS-WINDOWS 下的 Mozilla/Netscape ,你也可以把最高层认证中心复制到 WINDOWS 上,网址列直接打上档案路径,也可以把它加进去。

    + +

    在 Mozilla/Netscape 浏览器加进来的认证中心,也会用在 Mozilla 信件或 Netscape Mail & Newsgroups 里,来查核凭证。

    + + +

    Internet Explorer

    + +

    Internet Explorer 使用 WINDOWS 系统的凭证库,你只要把认证中心加进系统的凭证库就可以了。详情请参考设定 MS-WINDOWS

    + + +

    Opera

    + +

    Opera 截至目前为止 (6.05) ,只支援 RSA ,不支援 DSA 。因此,只能汇入 RSA 认证中心,不能汇入 DSA 认证中心。

    + +

    打开 Opera ,从工具列上的 [档案(F)][功能设定(R)...] 进去后,会打开 [功能设定] 的视窗。在视窗左边的选单中,选最下面的 [安全性] 时,右上角会出现 [认证机构(A)...] 的按钮。按下按钮,会再打开 [认证机构] 的视窗。按一下右上角的 [汇入(I)...] 按钮,找到我们的最高层认证中心,在上面点两下,就会加进去了。

    + + +

    Lynx

    + +

    Lynx 截至目前为止 (2.8.4) ,不会检查伺服器的 SSL 凭证。

    + + +

    设定电子邮件程式

    + +

    Mozilla 与 Netscape 6 以后的版本

    + +

    要设定使用 SSL 收信,启动 Mozilla 信件与 News 或 Netscape Mail & Newsgroups 后,由工具列上的 [编辑(E)][信件与 News 帐号设定(M)...] 按下去,会打开一个 [信件与 News 帐号设定] 的视窗。在左边选择你要设定的帐号下的 [伺服器设定] 。视窗右边的 [伺服器名称:] 中,要填上 POP3 邮件伺服器的完整名称。在右下方 [伺服器设定] 里的 [使用 SSL 安全连线] 选项上打勾,然后按 [确定] 。这样就会用 SSL 收信了。

    + +

    要设定使用 SSL 寄信,启动 Mozilla 信件与 News 或 Netscape Mail & Newsgroups 后,由工具列上的 [编辑(E)][信件与 News 帐号设定(M)...] 按下去,会打开一个 [信件与 News 帐号设定] 的视窗。在左边选择 [SMTP 外寄邮件伺服器] ,右边标题会变成 [SMTP 外送邮件伺服器设定] 。视窗右边的 [伺服器名称:] 中,要填上 SMTP 邮件伺服器的完整名称。右边中间有一个 [使用 SSL 安全连线] ,选 [若可以时] 。然后按 [确定] 。这样就会用 SSL 寄信了。

    + +

    凭证查核的部份,Mozilla 信件与 News 或 Netscape Mail & Newsgroups 使用 Mozilla 或 Netscape 6 的凭证库,你只要把认证中心加进 Mozilla 或 Netscape 6 就可以了。详情请参考Mozilla 与 Netscape 6 的设定

    + + +

    Netscape 4 及更早的版本

    + +

    Netscape 4 及更早的版本不支援 SSL

    + + +

    Outlook Express 6

    + +

    要设定使用 SSL 收信,启动 Outlook Express 后,由工具列上的 [工具(T)][帐户(A)...] 按下去,会打开一个 [网际网路帐户] 的视窗。在视窗左边选择要设定的帐号,然后按下右边的 [内容(P)] 按钮,会打开另一个 [某某某 内容] 的视窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一页。在 [内送邮件 - POP3(I):] 中,要填上 POP3 邮件伺服器的完整名称。再按一下上方的[进阶] ,翻到 [进阶] 那一页。在 [内送邮件 - POP3(I):] 下面的 [这个伺服器需要安全连线 - SSL(C)] 的选项上打勾。然后按 [确定][关闭] 。这样就会用 SSL 收信了。

    + +

    要设定使用 SSL 寄信,启动 Outlook Express 后,由工具列上的 [工具(T)][帐户(A)...] 按下去,会打开一个 [网际网路帐户] 的视窗。在视窗左边选择要设定的帐号,然后按下右边的 [内容(P)] 按钮,会打开另一个 [某某某 内容] 的视窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一页。在 [外寄邮件 - SMTP(U):] 中,要填上 SMTP 邮件伺服器的完整名称。再按一下上方的[进阶] ,翻到 [进阶] 那一页。在 [外寄邮件 - SMTP(O):] 下面的 [这个伺服器需要安全连线 - SSL(Q)] 的选项上打勾,并把上面 [外寄邮件 - SMTP(O):] 的连接埠号码改为 465 。然后按 [确定][关闭] 。这样就会用 SSL 寄信了。

    + +

    凭证查核的部份, Outlook Express 6 使用 WINDOWS 系统的凭证库,你只要把认证中心加进系统的凭证库就可以了。详情请参考设定 MS-WINDOWS

    + + +

    Outlook Express 5.5

    + +

    要设定使用 SSL 收信,启动 Outlook Express 后,由工具列上的 [工具(T)][帐号(A)...] 按下去,会打开一个 [Internet 帐号] 的视窗。在视窗左边选择要设定的帐号,然后按下右边的 [内容(P)] 按钮,会打开另一个 [某某某 内容] 的视窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一页。在 [内送邮件 - POP3(I):] 中,要填上 POP3 邮件伺服器的完整名称。再按一下上方的[进阶] ,翻到 [进阶] 那一页。在 [内送邮件 - POP3(I):] 下面的 [这个伺服器需要安全连线 - SSL(C)] 的选项上打勾。然后按 [确定][关闭] 。这样就会用 SSL 收信了。

    + +

    要设定使用 SSL 寄信,启动 Outlook Express 后,由工具列上的 [工具(T)][帐号(A)...] 按下去,会打开一个 [Internet 帐号] 的视窗。在视窗左边选择要设定的帐号,然后按下右边的 [内容(P)] 按钮,会打开另一个 [某某某 内容] 的视窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一页。在 [外寄邮件 - SMTP(U):] 中,要填上 SMTP 邮件伺服器的完整名称。再按一下上方的[进阶] ,翻到 [进阶] 那一页。在 [外寄邮件 - SMTP(O):] 下面的 [这个伺服器需要安全连线 - SSL(Q)] 的选项上打勾,并把上面 [外寄邮件 - SMTP(O):] 的连接埠号码改为 465 。然后按 [确定][关闭] 。这样就会用 SSL 寄信了。

    + +

    凭证查核的部份, Outlook Express 5.5 使用 WINDOWS 系统的凭证库,你只要把认证中心加进系统的凭证库就可以了。详情请参考设定 MS-WINDOWS

    + + +

    Outlook Express 4 或 5

    + +

    要设定使用 SSL 收信,启动 Outlook Express 后,由工具列上的 [工具(T)][帐号(A)...] 按下去,会打开一个 [Internet 帐号] 的视窗。在视窗左边选择要设定的帐号,然后按下右边的 [内容(P)] 按钮,会打开另一个 [某某某 内容] 的视窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一页。在 [内送邮件 - POP3(I):] 中,要填上 POP3 邮件伺服器的完整名称。再按一下上方的[进阶] ,翻到 [进阶] 那一页。在 [内送邮件 - POP3(I):] 下面的 [这个伺服器需要安全连线 - SSL(C)] 的选项上打勾。然后按 [确定][结束] 。这样就会用 SSL 收信了。

    + +

    要设定使用 SSL 寄信,启动 Outlook Express 后,由工具列上的 [工具(T)][帐号(A)...] 按下去,会打开一个 [Internet 帐号] 的视窗。在视窗左边选择要设定的帐号,然后按下右边的 [内容(P)] 按钮,会打开另一个 [某某某 内容] 的视窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一页。在 [外寄邮件 - SMTP(U):] 中,要填上 SMTP 邮件伺服器的完整名称。再按一下上方的[进阶] ,翻到 [进阶] 那一页。在 [外寄邮件 - SMTP(O):] 下面的 [这个伺服器需要安全连线 - SSL(Q)] 的选项上打勾,并把上面 [外寄邮件 - SMTP(O):] 的连接埠号码改为 465 。然后按 [确定][关闭] 。这样就会用 SSL 寄信了。

    + +

    Outlook Express 4 与 5 不会检查伺服器的 SSL 凭证。

    + + +

    Eudora 5.1 以后的版本

    + +

    Eudora 的 SSL 设计不是很好。

    + +

    Eudora 5.1 以后有一个 [Certificate Infomation Manager] 凭证管理员,可以管理 Eudora 的凭证。可是很奇怪,没有办法直接进入 [Certificate Infomation Manager][23] ,要先用 SSL 收一次信,才能进入 [Certificate Infomation Manager][24]

    + +

    收信时, Eudora 会先用 STARTTLS 指令试探邮件伺服器。成功的话,双方就进入 SSL 加密连线,开始收信;否则,就继续用不加密的方式收信。不用特别设定 SSL 收信的方式。不过 Eudora 的 STARTTLS 做法很奇怪:如果 STARTTLS 成功,进入 SSL 以后, Eudora 却查核不到对方的凭证, Eudora 会立即停止收信,不会重做非 SSL 连线,不会询问使用者,只会在下面不明显的地方出现一个小小的警告。对使用自制的伺服器凭证,新加上 STARTTLS 功能的邮件伺服器来说,使用者的 Eudora 原本正常收的信,会不闻不问开始停止收信,给使用者带来很大的困扰。这是 Eudora 另一个不良的设计。在 TLS 下查核凭证,本来就没什么意义。而且凭证查核失败的原因,只是 Eudora 认不得核发单位,不是凭证真的有问题。Eudora 应该询问使用者,不应该直接停止收信。

    + +

    注意: OpenSSL 预设是做 PEM 格式的凭证,所以先前我们做的都是 PEM 格式的凭证。但 Eudora 只能汇入 DER 凭证格式。 PEM 只是把 DER 用 Base64 编码,以便和传统七位元的网路标准相容,放在网页上、用 E-mail 寄或贴在文字档中。我们可以用 OpenSSL 把 PEMDER

    + +
    +
    +# 将最高层认证中心转成 DER 档
    +openssl x509 -in myrootca.crt.pem -outform der -out myrootca.crt.der
    +
    +
    + +

    要设定使用 SSL 收信,启动 Eudora 后,由工具列上的 [Tools][Options...] 按下去,会打开一个 [Options] 的视窗。在左边的 [Category] 中选择 [Checking Mail] 。视窗右边的 [Mail Server:] 中,要填上 POP3 邮件伺服器的完整名称。右下方有一个 [Secure Sockets when Receiving:] 的选单,选 [If available, STARTTLS] 后,按 [OK] 。这样就会用 SSL 收信了。

    + +

    要设定使用 SSL 寄信,启动 Eudora 后,由工具列上的 [Tools][Options...] 按下去,会打开一个 [Options] 的视窗。在左边的 [Category] 中选择 [Sending Mail] 。视窗右边的 [Mail Server:] 中,要填上 SMTP 邮件伺服器的完整名称。右下方有一个 [Secure Sockets when Receiving:] 的选单,选 [If available, STARTTLS] 后,按 [OK] 。这样就会用 SSL 寄信了。

    + +

    要加入我们的认证中心,要先收一次信。视窗下面会显示 [SSL Negotiation Failed: Certificate Error: Cert Chain not trusted. ...] 的错误讯息。依前述方式回到 [Tools][Options...][Category][Checking Mail][Secure Sockets when Receiving:] 后,按一下 [Last SSL Info] ,以开启[Eudora SSL Connection Infomation Manager] 的视窗,显示刚刚收到的凭证内容。按一下下面的 [Certificate Infomation Manager] 按钮,会再跳出一个 [Certificate Infomation Manager] 的视窗。按一下右下角的 [Import Certificate] ,找到我们的最高层认证中心的 DERmyrootca.crt.der ,在上面点两下,就会加进去了。[25]

    + + +

    Becky!

    + +

    Becky! 的作者 Tomohiro Norimatsu 已经说过,因为 SSL 专利权的问题, Becky! 不会支援 SSL[26] 不过我们可以用SSL 包装程式,让 Becky! 透过 SSL 连线来收发信。详情请参考设定其她不支援 SSL/TLS 的程式

    + + +

    Opera 邮件

    + +

    要设定使用 SSL 收信,打开 Opera ,从工具列上的 [档案(F)][功能设定(R)...] 进去后,会打开 [功能设定] 的视窗。在视窗左边的选单中,选 [电子邮件] 时,右边会出现 [使用 Opera 的帐号(O)] 的选单。选择要设定的帐号,然后按旁边的 [更改(P)...] ,会跳出一个 [邮件帐号设定] 的视窗。在上面的 [伺服器] 上按一下,切换到 [伺服器] 那一页。在 [内收邮件] 里 , [主机位置(E)] 中,要填上 POP3 邮件伺服器的完整名称,然后在下面 [协定(R)] 旁边 [采用 TLS 安全性协定] 的地方打勾,按 [确定][确定] 。这样就会用 SSL 收信了。

    + +

    要设定使用 SSL 寄信,打开 Opera ,从工具列上的 [档案(F)][功能设定(R)...] 进去后,会打开 [功能设定] 的视窗。在视窗左边的选单中,选 [电子邮件] 时,右边会出现 [使用 Opera 的帐号(O)] 的选单。选择要设定的帐号,然后按旁边的 [更改(P)...] ,会跳出一个 [邮件帐号设定] 的视窗。在上面的 [伺服器] 上按一下,切换到 [伺服器] 那一页。在 [外寄邮件] 里 , [主机位置(V)] 中,要填上 SMTP 邮件伺服器的完整名称,然后在下面 [协定(C)] 旁边 [采用 TLS 安全性协定] 的地方打勾,按 [确定][确定] 。这样就会用 SSL 收信了。

    + +

    凭证查核的部份, Opera 邮件使用 Opera 的凭证库,你只要把认证中心加进 Opera 就可以了。详情请参考 Opera 的设定

    + + +

    设定其她不支援 SSL/TLS 的程式

    + +

    我的程式不支援 SSL/TLS ,怎么办?

    + +

    没有关系。我们可以用 SSL 包装程式,先和伺服器建立 SSL 连线,再将程式送的指令,透过这个 SSL 连线转送给伺服器,并将伺服器在 SSL 连线中的回应,转送回来。这样一来,即使程式本身不懂 SSL ,也可以透过这个 SSL 连线,来加密收送的资料。以下,我们介绍 SSL 包装程式。

    + + +

    Stunnel

    + +

    Stunnel 的网站在 http://www.stunnel.org/ ,可以从网站上下载。在 WINDOWS 下,是很简单好用的 SSL 包装程式。 WINDOWS 下的简易使用方式说明如下:

    + +
      +
    • 从网站 http://www.stunnel.org/ 上下载 stunnel-x.xx.exelibssl32.dlllibeay32.dll
    • + +
    • libssl32.dlllibeay32.dll 存到 C:\WINDOWS\SYSTEM (WINDOWS 98/ME) 或 C:\WINNT\SYSTEM32 (WINDOWS NT/2000/XP) 下。
    • + +
    • C:\Program Files 下新增一个 Stunnel 目录,把刚刚下载的 stunnel-x.xx.exe 存进这里。
    • + +
    • C:\Program Files\Stunnel 中新增一个档案 stunnel.conf ,内容举例如下: + +
      +
      +client = yes
      +
      +[pop3s]
      +accept = localhost:50110
      +connect = my.mail.server:995
      +
      +[smtps]
      +accept = localhost:50025
      +connect = my.mail.server:465
      +
      +
      +
    • + +
    • 启动 C:\Program Files\Stunnel\stunnel-x.xx.exe 。它会缩到桌面下方工具列的最右边,变成一个小图示。这时如果开启 [MS-DOS 模式][命令提示字元] ,打: + +
      +
      +netstat -an
      +
      +
      + +会看到类似: + +
      +
      +TCP    127.0.0.1:50025        0.0.0.0:0              LISTENING
      +TCP    127.0.0.1:50110        0.0.0.0:0              LISTENING
      +
      +
      + +的两行。点两下 Stunnel 在工具列右边的小图示,会显示 Stunnel 的使用记录。
    • + +
    • 启动程式,修改程式的设定,将原来 SMTP 连到 my.mail.server 连接埠 25 的地方,改连到 localhost 连接埠 50025 ;原来 POP3 连到 my.mail.server 连接埠 110 的地方,改连到 localhost 连接埠 50110 。
    • + +
    • 收、发信。
    • + +
    + +

    这样应该就可以了,原本不会 SSL 的程式,现在可以透过 Stunnel 使用 SSL 连线了。

    + +

    这只是 Stunnel 的基本功能。 Stunnel 还有很多强大的功能,不但可以转送 POP3SMTPIMAPNNTPLDAP … 等各种通讯协定,也可以将 SSL 连线,转送给不会 SSL 的伺服器程式。这样即使反过来,伺服器程式本身不会 SSL ,使用者也可以使用 SSL 加密连线。详细的做法,请下载 Stunnel 的原始程式码,参照内附的完整操作说明。

    + +

    不过 Stunnel 有一个很大的限制:因为 Stunnel 只负责先建立好 SSL 连线,并不了解通讯协定本身的指令语法,所以无法用 STARTTLS 指令建立 TLS 连线,只能用传统的方式,一开始就建立全程的 SSL 连线。

    + + +

    观念讨论

    + +

    SSL/X.509 简介

    + +
    + X.509 的金字塔制度
    + X.509 的金字塔制度
    +
    + +

    SSL 采用的是 X.509 ,由上而下金字塔式的凭证制度。

    + +

    在 X.509 中,每一个合格的凭证上,都会有一个签名。最下层的凭证上,会有一个认证中心 (CA) 的签名,表示这个认证中心 (CA) 检查过,确认所有者资料无误。中间的认证中心 (CA) 上,也会有管辖它的最高层认证中心 (Root CA) 的签名,表示最高层认证中心授权给它,可以签发别人的凭证。只有最高层认证中心上,因为它已经是最大,没有再上层可以给它签名了,所以只好自己签自己,凭证上的签名是自己签的。

    + +

    程式自己会认得几家可靠的认证中心 (CA) ,碰到 SSL 网站时,虽然不认得伺服器的凭证 (Certificate) ,但只要那个凭证上,有自己认得的认证中心 (CA) 签名保证过,那个凭证就没有问题。

    + +
    + 当程式碰到合格的 SSL 凭证
    + 当程式碰到合格的 SSL 凭证
    +
    + +

    但如果那个伺服器凭证上,没有自己认得的认证中心 (CA) 签名保证过,伺服器凭证就有可能有问题,会出现凭证无效的警告。

    + +
    + 当程式碰到有问题的 SSL 凭证
    + 当程式碰到有问题的 SSL 凭证
    +
    + + +

    凭证无效的警告

    + +

    本文第一步讨论的是如何自制最高层认证中心 (Root CA) 。因为这是我们自己的认证中心,程式不认得,所以第二步签发的凭证(Certificate) 上的签名,程式自然也不认得,一定会出现凭证无效的警告。

    + +
    + 当程式碰到我们自制的认证中心
    + 当程式碰到我们自制的认证中心
    +
    + +

    若不想看到这个警告,就要先让程式认得我们自己的认证中心 (CA) 。这时,第二步签发的凭证 (Certificate) ,程式认得上面认证中心 (CA) 的签名,就不会再出现凭证无效的警告。

    + +
    + 把我们自己的认证中心加上去
    + 把我们自己的认证中心加上去
    +
    + +

    详细做法,请参考设定作业系统设定浏览器设定电子邮件程式各节。

    + +

    注意:这个方法,因为要在程式上,手动加入自己的认证中心 (CA) ,所以只有自己内部用的网站,使用者和程式数目都有限,可以自己一个一个去设认证中心 (CA) 的情况下,方才可行。若要用在公开的网站上,因为上网者来自各个不同的地方,你也都不认识,没有办法在她们的电脑上,都加进自己的认证中心,就没有办法了。这一点受限於 X.509 的规定,爱莫能助。若真的很在意 SSL 凭证无效警告的问题,又需要在公开的网站使用 SSL ,请向各家签证公司申请,年费大概几万元台币。

    + + +

    资料?什么资料?

    + +

    等等,刚刚图中的最后一个步骤,『没问题,这是给你的资料』。使用者还没有填什么资料啊!程式怎么可以自己乱给对方资料呢?到底给了什么资料?程式会不会自己给对方 E-mail 、信用卡号码、身份证字号、密码?

    + +

    程式传给对方的,是接下来通信时,对称式加解密用的 Key 。

    + +

    Public/Private Key 的不对称加解密法 (Asymmetric Encryption) ,可以把 Public Key 告诉全世界, Private Key 自己秘密保管好,要传资料给你的话,只要用你的 Public Key 加密,全世界就只有你的 Private Key 才解得开。这种不对称加解密法虽然很安全,但是加解密的速度很慢。反过来说,传统的对称式加解密法 (Symmetric Encryption) ,虽然加解密速度快多了,但是双方都要握有同一个 Key ,把 Key 传给对方途中,会有被拦截监听的危险。

    + +

    SSL 采用两阶段式的作法:第一阶段,先用 Public/Private Key 不对称加解密法,传给对方接下来传真正资料时,对称式加解密法要用的 Key 。第二阶段,再用这个对称式加解密的 Key ,来传原本要传的资料。真正传资料时用的,其实是对称式加解密法。这个传资料用的对称 Key 是用乱数取的,再用 Public/Private Key 法传给对方,每一次连线时都不一样。用这种两阶段式的作法, Key 是用不对称加解密法传给对方的,不用担心中途被栏截,也能够享受合理的加解密速度。

    + + +

    所以 SSL 就安全了罗?

    + +

    所以,只要对方 SSL 网站的凭证合格,上面有可靠的认证中心 (CA) 签名,把我的信用卡资料传过去就安全罗?

    + +

    不对。

    + +

    仔细看看前段 SSL/X.509 简介,就会注意到, SSL/X.509 规定中,认证中心 (CA) 的签名所保证的,只有这个 Public Key 凭证的确是属於这家公司的这个伺服器而已。也就是说,它只保证你送的信用卡号码会确确实实交到这家公司的这个伺服器手中,不怕被任何人中途拦截监听。但这并不代表这家公司是优良企业,收到你的信用卡资料后,不会滥用,不会侧录下来,不会多刷两笔,不会转手把资料卖给别家公司,也不代表这家公司的伺服器安全防护做得很好,不会被人入侵,不会被人偷偷安装侧录上网资料的程式

    + +

    没错, SSL 只能保证收到的 Public Key 凭证不是伪造的,但不能保证这家公司本身没有问题。就算这家公司本身没有问题,也不能保证这家公司内部会不会成为别人入侵、窃取资料的目标。

    + +

    那怎么办?怎么样才能算安全?才能放心把资料传过去?

    + +

    就像在实体世界,跟不认识的商店买东西时,一定会保持戒心一样,在网路上和任何网站交易,也一定要保持戒心,除了要考虑你平常信不信任这个网站外,也要考虑你传过去的资料重不重要。举例来说,留言板、讨论区、网路投票等等,不是很私人的资料,可以放心传过去没问题;但如果是真实姓名、手机号码、家里电话、信用卡号码, E-mail 等等,就只能传给自己信任的网站了。

    + + +

    什么是数位签名?

    + +

    数位签名是用 Private Key ,针对某一段资料,用 Digest Hash 演算法(如 SHA512 )做出来的一段 Digest 摘要码。只要原来的资料有所不同,演算出来的 Digest 摘要码就会跟著变动。用 Private Key 做出来的 Digest 摘要码,可以用它的 Public Key 来检查。只要用它的 Public Key ,检查 Digest 摘要码和那一段资料符不符合,就可以知道资料有没有中途被窜改过,是不是这个 Private Key 当初签的那一段资料。

    + +

    这个性质很像合约中,在整份合约上大大签一个名一样,人家认得你签名的笔迹,日后只要合约有任何涂改,一认便知。所以我们把它叫做数位签名。

    + +

    因为数位签名可以用来检查资料有没有被窜改,所以我们把它用在凭证上,认证中心检查过 Public Key 的所有人,和 Key 上记载的所有人资料相符后,用认证中心自己的 Private Key ,在这些资料上面做个数位签名,表示证明。日后收到这个 Public Key 的人,只要检查上面认证中心的签名,就可以知道这个 Key ,和它上面所载的所有人资料相不相符,是不是真的是这家公司的 Key 。也就知道,连上的这个伺服器,是不是真的是这家公司的伺服器了。

    + + +

    什么是凭证?

    + +

    凭证的原文是 Certificate ,是附上所有人 (owner) 的资料(公司名称、伺服器名称、个人真实姓名、连络 E-mail 、通讯地址等资料),后面加上数位签名的 Public Key 。凭证上会附有几个数位签名,代表这些签名的人,确认过这个 Public Key 的所有人,和凭证上所载的资料相符,没有假造。

    + +

    在 X.509 中,最下层每一个合格的凭证 (Certificate) 上,会有一个认证中心 (CA) 的签名,表示这个认证中心 (CA) 检查过,确认凭证上的所有者资料无误。当程式碰到没见过的凭证时,只要检查凭证上认证中心 (CA) 的签名无误,即代表这个认证中心 (CA) 查核过这个凭证 (Certificate) ,凭证上的资料无误。

    + + +

    什么是认证中心?

    + +

    认证中心的原文是 CA ,是 Certificate Authority 的缩写,在微软正体中文 WINDOWS 上译成凭证授权凭证授权完全是逐字翻译,意思不通,不用。认证中心是 X.509 的一环。认证中心也是一种凭证,上面附有认证中心本身的资料,但不是用来加解密,而是用来签发凭证,证明凭证所有人和凭证上所载的资料无误。请参见SSL/X.509 简介的附图。

    + +

    每一个合格的认证中心 (CA) (微软正体中文 WINDOWS 上译成中继凭证授权,意思不通)上,会有一个管辖它的最高层认证中心 (Root CA) 的签名,表示最高层认证中心授权给它,可以签发别人的凭证。当程式碰到没见过的凭证,凭证上签名的认证中心 (CA) 也没见过时,只要检查认证中心上附的最高层认证中心 (Root CA) 的签名无误,即代表这个最高层认证中心 (Root CA) ,认为这个认证中心 (CA) 的凭证签发过程很仔细,检查资料很详实,所以授权给它,准许它可以签发凭证 (Certificate) 。所以这个认证中心 (CA) 签发的凭证 (Certificate) ,凭证上的资料也没有问题。

    + + +

    什么是最高层认证中心?

    + +

    最高层认证中心的原文是 Root CA ,在微软正体中文 WINDOWS 上译成根目录凭证授权根目录只是照 Root 这个字逐字翻译,意思不通,不用。最高层认证中心是 X.509 的一环。最高层认证中心也是认证中心 (CA) ,和一般认证中心的差别在於,它不会直接用来签发凭证,而是授权给一些中间的认证中心,让这些中间的认证中心来签发凭证。请参见SSL/X.509 简介的附图。

    + +

    最高层认证中心,因为已经是最大,没有再上层可以给它签名了,所以凭证上的是自己的签名,不是别人的签名。因为最高层认证中心没有再上面的签名了,没有人可以保证最高层认证中心本身有没有问题,没有办法再往上检查,所以程式只能事先就认得一些可靠的最高层认证中心,事先就知道一些可靠的最高层认证中心的 Public Key 。

    + +

    最高层认证中心只能由一些著名、可靠的公司来担任,因为没有办法再往上查验。如果程式被加进一些不可靠的最高层认证中心,接下来碰到它签下来的凭证,都会有问题,整个程式的安全都会被破坏。所以在 X.509 下, SSL 程式一定要好好保护最高层认证中心,一定要再三确认,不可以随便让人手动加进最高层认证中心。

    + + +

    如何填写凭证申请书

    + +

    如果你不知道该如何填写凭证申请书,请参考以下范例:

    + +
    +
    +You are about to be asked to enter information that will be incorporated
    +into your certificate request.
    +What you are about to enter is what is called a Distinguished Name or a DN.
    +There are quite a few fields but you can leave some blank
    +For some fields there will be a default value,
    +If you enter '.', the field will be left blank.
    +-----
    +Country Name (2 letter code) [AU]:TW
    +State or Province Name (full name) [Some-State]:Taiwan
    +Locality Name (eg, city) []:Taipei City
    +Organization Name (eg, company) [Internet Widgits Pty Ltd]:Tavern IMACAT's
    +Organizational Unit Name (eg, section) []:Owner
    +Common Name (eg, YOUR name) []:Tavern IMACAT's
    +Email Address []:imacat@mail.imacat.idv.tw
    +
    +Please enter the following 'extra' attributes
    +to be sent with your certificate request
    +A challenge password []:
    +An optional company name []:
    +
    +
    + +
      + +
    1. 所有资料都要填英文 (ASCII 字集) 。 X.509 凭证只接受英文 ASCII 字集的字。
    2. + +
    3. Country Name 一定要是大写的双字母国码,台湾是 TW ,台湾以外的地方,请参考 ISO-3166 的标准双字母国码。
    4. + +
    5. State Name 是国名或省名,不可以填国码。台湾填 Taiwan 即可。
    6. + +
    7. Locality Name 是地名,填所在地县市名即可。
    8. + +
    9. Organization Name 是组织单位名称,填公司行号,或学校局处的名称。
    10. + +
    11. Organizational Unit Name 是部门名称,填公司部门名称,或学校局处的单位名称。
    12. + +
    13. Common Name 是凭证的名称。若是最上层凭证机构,请填上前面填的组织单位名称,后面可以加上 RSA/4096 ,以便日后辨认凭证的性质。若是伺服器凭证,请填上伺服器的全名 (www.abc.com) 。若是 E-mail 凭证,请填上你的 E-mail
    14. + +
    15. E-mail Address 是申请单位的连络信箱,请填上你的联络用 E-mail
    16. + +
    17. A challenge password 是申请书的密码。不过申请书不用设密码,所以不填。
    18. + +
    19. An optional company name 是凭证代办公司的名称,也不用填。
    20. + +
    + + +

    X.509 凭证制度的检讨

    + +

    X.509 凭证制度,是靠事先认得一些可靠的最高层认证中心,再一层一层签发下来的金字塔型结构。这样的制度,很像信用卡制度或身份证制度:

    + +
    + X.509 制度
    + X.509 制度
    +
    + +
    + 信用卡制度
    + 信用卡制度
    +
    + +
    + 身份证制度
    + 身份证制度
    +
    + +

    这样的金字塔结构,有好有坏。

    + +

    好处在於,在无限宽广的网际网路上,我们根本不知道会碰到什么样的网站,所以根本也无从查认每一个收到的 Public Key 有没有问题,是不是真的是这家公司的网站,我是不是真的是跟这家公司打交道。在 X.509 下,只要我们预先认得几家可靠的最高层认证中心就好了。碰到不认识的 Public Key 时,只要一层一层往上追溯,如果最后追溯得到一个我们认得的可靠的最高层认证中心,那这个 Public Key 就没有问题了。这样的做法,简化了无限宽广的网际网路上,确认彼此身份的困难性。

    + +

    缺点则在於,因为 X.509 是金字塔结构,最高层认证中心 (Root CA) 手中握有整个网际网路信任关系的关键,权力太大了。庞大的权力,伴随著的是庞大的利益。曾经跟认证中心打过交道(如 VeriSign 、 HiTrust 网际威信、Taica 台湾网路认证等)的人都知道,申请签发 SSL 凭证非常贵,一年年费要好几万,普通人或中小企业,需要SSL 网站加密的时候,根本就负担不起。而因为金字塔顶层的最高层认证中心,是垄断事业,数目很少,不会有什么竞争,所以大型的最高层认证中心姿态都很高,年费一直降不下来。但若不靠这些最高层认证中心,自己来发证,程式没有内建我们自制的认证中心,连到 SSL 站上,一定会出现警告。小组织里内部自用的 SSL 伺服器还没有问题,我们可以自己加入自制的认证中心,但大型公开的伺服器(像公司网站)上,不可能要不认识的上网者信任我们的认证中心,把我们的认证中心加进去,这时候资料的安全,就会亮起红灯了。到头来,我们还是得回过头去,求这些大型的认证中心,乖乖缴一年好几万的年费。

    + +

    这真的没有办法吗?

    + +

    答案是否定的。即使是 X.509 的金字塔结构,至少就有两条路:第一条路是像信用卡制度一样。信用卡制度也是金字塔结构,顶层的信用卡集团也是垄断事业,数目很少,可是信用卡的年费只有几千块钱。有竞争就会降价,但没有竞争,并不代表价格一定降不下来。价格其实还是卡在认证中心如何定价,信用卡制度就是一例。第二是像身份证一样,由政府出面经营,以政府的信用担保、审核,把它变成免费的公用事业,让大家有钱没钱,都可以来用安全的网站交易。

    + +

    不过,仔细想想,我们是不是一定要用 X.509 这种金字塔制度,任这些顶层的认证中心宰割,予取予求呢?

    + +

    其实凭证有好几种。有一种叫做 PGP ,是采用信任网 (Web of Trust) 的模式,建立信任关系。 PGP 的信任网就像人际关系网一样:我认得你,你认得她,所以我只要请你来认她就好了。

    + +
    + PGP 的信任网
    + PGP 的信任网
    +
    + +

    在 PGP 信任网模式下,我们不需要一个最高层认证中心,给每个人核发凭证,才能取得 Public Key 的安全性。我们只要信任我们自己的 Public Key 凭证,用自己的凭证去签认识的 Public Key 的凭证,别人也用他们自己的凭证,去签他们认识的人的凭证,往外一层一层扩散出去,互相信任。碰到不认得的凭证时,只要能够从他凭证上的签名中,回溯到可信任的人的凭证身上,就可以了。其实事情本来就是这样。我们为什么要向别人缴一年好几万的年费,还要别人签名,才能信任自己的凭证呢?

    + +

    不过,不合理的是, SSL 规定,要用 X.509 。

    + + +

    其她 SSL/X.509 凭证的做法

    + +

    在本文中,我们做了两个凭证:一个是 Root CA 最上层认证中心,一个是用这个最高层认证中心签发的凭证。

    + +

    其实完整的话,应该要做三层(参考:SSL/X.509 简介中的附图):最高层认证中心 (Root CA) ,中间的认证中心 (CA) ,最后才签发下面的凭证。可是我不会做中间的认证中心, ^^; 完整的三层挺复杂的。而且,最高层认证中心 (Root CA) 只是不会用来直接签凭证,而不是不能用来直接签凭证,最高层认证中心(Root CA) 签的凭证,一样有效。更何况,我们通常都只有几台伺服器,只需要几个凭证就好,不需要授权好几个中间的认证中心,来让它们签凭证。所以我们就省略了中间的认证中心,直接用最高层认证中心 (Root CA) 来签发凭证 (Certificate) 。

    + +

    其实还有两个不那么麻烦的做法。 Apache mod_ssl 有随附一个印度蛇油公司 (Snake Oil) 的最高层认证中心 (Root CA) ,内有印度蛇油 (Snake Oil CA) 的 Private Key ,可以直接用印度蛇油认证中心 (Snake Oil CA) 的名义来签发凭证。只要在编译 Apache 时, make 以后打 make certificate ,就会自动用印度蛇油认证中心,签发 Apache 网站所需的伺服器凭证了。可是,基於安全上的理由,你只能够用这张签出来的网站凭证,绝对不可以把印度蛇油认证中心 (Snake Oil CA) ,加到程式认得的认证中心中。因为印度蛇油的 Private Key 是随著 Apache mod_ssl 公开散布的,任何人只要下载 Apache mod_ssl ,里面就会有印度蛇油的 Private Key ,就可以用印度蛇油的名义来签凭证,自称为某某公司。印度蛇油的可靠度是零,绝对不要加进程式中。(所以才叫做印度蛇油 Snake Oil ,骗人的。)

    + +

    另一个方法,是只做一个最高层认证中心 (Root CA) ,直接用这个最高层认证中心,来当伺服器的凭证。因为最高层认证中心 (Root CA) 本身,也是一个凭证,所以当然也可以用,一样有效。这时候,最高层认证中心的所有人名称,就要用伺服器的名称 (www.abc.com) ,而不是单位的名称 (ABC Corporation.) 。这个方法,适合只有一个伺服器,只需要一个凭证,而且不在乎凭证名称的人。用 Windows NT/2000 的 Certificate Server 凭证伺服器,可以做出这种凭证。但如果有好几台伺服器,每个凭证都要分别去加到每台电脑上,这个方法就不大方便了。

    + + +

    注释

    + +
      + +
    1. FHS 是指 Filesystem Hierarchy Standard 档案系统阶层标准,是一个 Unix 下,目录及档案存放位置的标准规定,以方便系统管理员管理,方便不同程式间互相搭配整合。目前大多数 Linux 版本(如 DebianRed HatMandrake 等)都已支援 FHS 。更进一步的资料请参考 FHS 的网站 http://www.pathname.com/fhs/(回正文)
    2. + +
    3. Opera 截至目前为止 (6.05) ,只支援 RSA ,不支援 DSA(回正文)
    4. + +
    5. 在 Mandrake 下装 RPM 时,请改用: +
      +
      +mv /usr/lib/ssl/openssl.cnf /etc/ssl
      +ln -s /etc/ssl/openssl.cnf /usr/lib/ssl/openssl.cnf
      +
      +
      +(回正文)
    6. + +
    7. 这是 bash 或 zsh 的指令。 csh 或 tcsh 下,请改用: +
      +
      +setenv OPENSSL_CONF "/etc/ssl/openssl.cnf"
      +
      +
      +(回正文)
    8. + +
    9. 这样以后登入的时候,都能够自动设定 OPENSSL_CONF 。这是用 bash 登入的情形,若用 csh 或 tcsh 登入,请改用: +
      +
      +echo "# OpenSSL 设定档的位置" >> ~/.cshrc
      +echo "setenv OPENSSL_CONF \"/etc/ssl/openssl.cnf\"" >> ~/.cshrc
      +
      +
      +若用 zsh 登入,请改用: +
      +
      +echo "# OpenSSL 设定档的位置" >> ~/.zshenv
      +echo "export OPENSSL_CONF=\"/etc/ssl/openssl.cnf\"" >> ~/.zshenv
      +
      +
      +(回正文)
    10. + +
    11. (感谢网中人 (netman) 提供)若你安装的是 Red Hat 的 openssl RPM ,在这里会出一点问题。 Red Hat 的 openssl 做 rand 指令,配合 -out 参数时,参数解析会出错,无法执行。目前我还没有看到网路上有人提过这件事。解决方法之一,是自己编译、安装 OpenSSL 。这其实很简单。在 Linux 上,步骤如下: +
      +
      +./config shared --prefix=/usr --openssldir=/usr/share/ssl
      +make
      +make install
      +
      +
      +在其她作业系统 (*BSD/UNIX) 上,步骤如下: +
      +
      +./config --prefix=/usr --openssldir=/usr/share/ssl
      +make
      +make install
      +
      +
      +如果不想自己编译、安装 OpenSSL ,另一个解决方法,由网中人提供,则是避开 -out 参数,改用输出重导向: +
      +
      +openssl rand 1024 > /etc/ssl/private/.rand
      +
      +
      +Mandrake 和 Debian 的 openssl 套件没有这个问题。 +(回正文)
    12. + +
    13. 若要做成 DSA Key,请改用: +
      +
      +# 制作 DSA 参数档
      +openssl dsaparam -out /tmp/dsaparam 4096
      +
      +# 制作 DSA Private Key
      +openssl gendsa -out /etc/ssl/private/myrootca.key.pem /tmp/dsaparam
      +chmod og-rwx /etc/ssl/private/myrootca.key.pem
      +
      +# 删除 DSA 参数档
      +rm -f /tmp/dsaparam
      +
      +
      +因为 DSA 取乱数参数要取很久,所以 OpenSSL 不直接做 DSA Key ,而把取出来的 DSA 参数存档,再用参数档来做 DSA Key ,做下一组 Key 时就可以用同一个参数档,以节省时间。不过这里我们只做一组 Key ,所以参数档用过就可以删了。 (回正文)
    14. + +
    15. 若你的最高层认证中心,放在另一台伺服器上,请将 /tmp/myhost.req.pem 复制到那台伺服器上的 /tmp/myhost.req.pem ,登入那台伺服器上,再继续进行。 (回正文:root/使用者)
    16. + +
    17. 如果你原来是在另一台伺服器做这组 Public/Private Key 的,把 /etc/ssl/certs/myhost.crt.pem 复制到原来的伺服器上的 /etc/ssl/certs/myhost.crt.pem ,就可以用了。记得要回到原来的伺服器上,把原来伺服器上的凭证申请书 /tmp/myhost.req.pem 也删掉。 +
      +
      +rm -f /tmp/myhost.req.pem
      +
      +
      +(回正文)
    18. + +
    19. 在 Mandrake 下装 RPM 时,请改用: +
      +
      +cp /usr/lib/ssl/openssl.cnf ~/etc/ssl
      +
      +
      +(回正文)
    20. + +
    21. 这是 bash 和 zsh 的指令。 csh 或 tcsh 下,请改用: +
      +
      +setenv OPENSSL_CONF "$HOME/etc/ssl/openssl.cnf"
      +
      +
      +(回正文)
    22. + +
    23. 这样以后登入的时候,都能够自动设定 OPENSSL_CONF 。这是用 bash 登入的情形,若用 csh 或 tcsh 登入,请改用: +
      +
      +echo "# OpenSSL 设定档的位置" >> ~/.cshrc
      +echo "setenv OPENSSL_CONF \"$HOME/etc/ssl/openssl.cnf\"" >> ~/.cshrc
      +
      +
      +若用 zsh 登入,请改用: +
      +
      +echo "# OpenSSL 设定档的位置" >> ~/.zshenv
      +echo "export OPENSSL_CONF=\"$HOME/etc/ssl/openssl.cnf\"" >> ~/.zshenv
      +
      +
      +(回正文)
    24. + +
    25. (感谢网中人 (netman) 提供)若你安装的是 Red Hat 的 openssl RPM ,在这里会出一点问题。 Red Hat 的 openssl 做rand 指令,配合 -out 参数时,参数解析会出错,无法执行。目前我还没有看到网路上有人提过这件事。解决方法之一,是自己编译、安装 OpenSSL 。这其实很简单。在 Linux 上,步骤如下: +
      +
      +./config shared --prefix=/usr --openssldir=/usr/share/ssl
      +make
      +make install
      +
      +
      +在其她作业系统 (*BSD/UNIX) 上,步骤如下: +
      +
      +./config --prefix=/usr --openssldir=/usr/share/ssl
      +make
      +make install
      +
      +
      +如果不想自己编译、安装 OpenSSL ,另一个解决方法,由网中人提供,则是避开 -out 参数,改用输出重导向: + +
      +
      +openssl rand 1024 > ~/etc/ssl/private/.rand
      +
      +
      +Mandrake 和 Debian 的 openssl 套件没有这个问题。 (回正文)
    26. + +
    27. 若要做成 DSA Key,请改用: +
      +
      +# 制作 DSA 参数档
      +openssl dsaparam -out ~/tmp/dsaparam 4096
      +
      +# 制作 DSA Private Key
      +openssl gendsa -out ~/etc/ssl/private/myrootca.key.pem ~/tmp/dsaparam
      +chmod og-rwx ~/etc/ssl/private/myrootca.key.pem
      +
      +# 删除 DSA 参数档
      +rm -f ~/tmp/dsaparam
      +
      +
      +因为 DSA 取乱数参数要取很久,所以 OpenSSL 不直接做 DSA Key ,而把取出来的 DSA 参数存档,再用参数档来做 DSA Key ,做下一组 Key 时就可以用同一个参数档,以节省时间。不过这里我们只做一组 Key ,所以参数档用过就可以删了。 (回正文)
    28. + +
    29. 若你的最高层认证中心,是由 root 管理,请接到 root 的第三步骤(回正文)
    30. + +
    31. 如果你原来是在另一台伺服器做这组 Public/Private Key 的,把 ~/etc/ssl/certs/myhost.crt.pem 复制到原来的伺服器上的 ~/etc/ssl/certs/myhost.crt.pem,就可以用了。记得要回到原来的伺服器上,把原来伺服器上的凭证申请书 /tmp/myhost.req.pem 也删掉。 +
      +
      +rm -f /tmp/myhost.req.pem
      +
      +
      +(回正文)
    32. + +
    33. 不过微软的 Outlook Express 很笨,不支援相容性高的TLS 新标准,只能跑旧式的 SMTPS 。若你要设定给 Outlook Express 用 SSL 寄信,就一定要在编译时加上 SMTPS 的支援。 (回正文)
    34. + +
    35. 其实你会看到三个连接埠: SMTP(25) 、SMTPS(465) 和 submission(587) 。 submission(587) 是给邮件程式寄信专用的,和 SMTP(25) 一样可以做 TLS 。 submission(587) 不需特别设定,为简化讨论起见,省略之。 (回正文)
    36. + +
    37. 若你在意系统安全,不想多开不必要的帐号的话,这里的 smmsp 可以改成 mail ,用 mail 帐号。我强烈建议这个做法。开太多不必要的帐号,增加不必要的系统权限,也是安全漏洞的来源之一。本来就没有什么程式在用 mail 帐号, mail 是闲置的系统帐号之一,不如好好利用这个现有的系统资源。更何况, Sendmail 建议的 smmsp 群组的 GID 25 ,和 Debian floppy 群组的 GID 冲突。这是系统安全的题外话,和 SSL 无关。 (回正文)
    38. + +
    39. 这里 MS-WINDOWS 把最高层认证中心 (Root CA) 译成根目录凭证授权,把认证中心 (CA) 译成凭证授权中继凭证授权,都是逐字翻译的结果,完全不知所云,翻译之大忌,戒之。 (回正文)
    40. + +
    41. 到 Mozilla 1.1 版为止, Mozilla 把凭证 (Certificate) 译成认证,把认证中心 (CA) 译成查证,也是有问题的译法,且不符目前的通译。我已跟 Mozilla 中文化的作者林弘德反映过这个问题,他承诺於 1.0.1 版后修正。 (回正文)
    42. + +
    43. 实际储存的地方,在 Mozilla 使用者设定档目录下的 cert7.db ,格式是 Berkeley DB 。 (回正文)
    44. + +
    45. 我还没找到直接开启 [Certificate Infomation Manager] 的方法。如果有人知道,烦请告诉我。 (回正文)
    46. + +
    47. 实际储存的地方,公用的认证中心在 Eudora 程式目录下的 rootcerts.p7b ,个人的认证中心在 Eudora 信箱目录下的 usercerts.p7b ,格式是标准凭证格式 DER 的 PKCS#7 档。 (回正文)
    48. + +
    49. 要先失败一次,才能去设定,其实挺蠢的。另一个比较不那么愚蠢的方法,就是直接去改 usercerts.p7busercerts.p7b 是标准凭证格式 PKCS#7 档,可以用 OpenSSL 处理: +
      +
      +# 备份原档案
      +mv usercerts.p7b usercerts-orig.p7b
      +
      +# 把 DER 的 PKCS#7 档,拆成一张一张的 PEM 凭证清单
      +openssl pkcs7 -print_certs -inform der \
      + -in usercerts-orig.p7b -out certslist.pem
      +
      +# 把我们的认证中心加进来
      +cat /etc/ssl/certs/myrootca.crt.pem >> certslist.pem
      +
      +# 将一张一张的 PEM 凭证清单,组合成 PEM 的 PKCS#7 档
      +openssl crl2pkcs7 -nocrl -certfile certslist.pem > usercerts.pem
      +
      +# 将 PEM 转为 DER
      +openssl pkcs7 -in usercerts.pem -outform der -out usercerts.p7b
      +
      +# 删掉多余的档案
      +rm -f certslist.pem usercerts.pem
      +
      +
      +这样就把我们的认证中心加进 usercerts.p7b 了。不要直接去改公用的认证中心 rootcerts.p7b ,这个档案留给 Eudora 自己去维护。 (回正文)
    50. + +
    51. 详情请参见这篇 Becky! 论坛上关於 SSL 的讨论(回正文)
    52. + +
    + + +

    参考资料

    + +
      +
    1. SSL: Netscape Security Documentation, Introduction to SSL, How SSL Works, SSL Protocol v3.0
    2. + +
    3. X.509: RFC 3280, RFC 2459 (旧版)
    4. + +
    5. OpenSSL: OpenSSL, openssl(1), x509(1), req(1), ca(1)
    6. + +
    7. PGP: GnuPG, PGPi, PGP, Introduction to Cryptography ( PDF 档, PGP 的原作者 Phil Zimmermann 作), Phil Zimmermann
    8. + +
    9. FHS
    10. + +
    11. TLS 1.0: RFC 2246
    12. + +
    13. Apache: http://www.apache.org/, Apache-SSL, mod_ssl
    14. + +
    15. Qpopper
    16. + +
    17. Sendmail
    18. + +
    19. Stunnel
    20. + +
    + + +

    后记

    + +
    2002-11-15
    + +

    小幅更新:

    + +
      +
    • 加上 Sendmail SMTPS(465) 功能的设定。这是 Sendmail 未公开的功能,之前在 Sendmail 文件中没有发现。我是在设定 Outlook Express 时,发现没办法按自己写的方式用 SSL 寄信,上 google 搜寻,才发现 Sendmail 的 SMTPS 支援的。不好意思,写出无法执行的东西,自己没有全部检查确认过,对大家非常抱歉。 ^^;
    • +
    • 加上 Stunnel SSL 包装程式。这是可以让 Becky! 等不支援 SSL 的程式,也能使用 SSL 连线的方法。
    • +
    • 加注不新增 smmsp 帐号的方法。
    • +
    • 几个之前编排文字时造成的小错误。
    • +
    + + +
    2002-09-15
    + +

    本文参考的资料有限。 SSL 和 X.509 我还没有完整看过。而目前网路上,即使是英文资料也很少。一开始,我只能从一堆零零散散的网路讨论,和 OpenSSL 的文件中,自己拼凑出 SSL 凭证的做法。因为网路上找不到比较完整的 SSL 凭证制作教学,所以我想把它写出来,开个先锋。我没有看完 SSL/X.509 ,只是尽量让我做出来的凭证,在我所知道的 SSL 程式上,都跑得动。做出来凭证不一定完全符合 SSL/X.509 ,也不一定在所有的SSL程式上都能用。

    + +

    然而,也不是每一个符合 SSL/X.509 的凭证,就能在所有的SSL 程式上用。不见得每个 SSL 程式都完整支援SSL/X.509 ,就像 Opera 目前还不支援 DSA 一样。

    + +

    本文第一版是 2002-01-09 ~ 2002-01-13 间所写。第一版写作的目的,是当时为了想自己做 Root CA (这样凭证看起来比较好看),想办法在网路上零碎的讨论中,拼凑出 Root CA 的做法。整个做法有点复杂,怕自己下次要发凭证时忘记,所以写下来,顺便写成 HOWTO 教学的形式,以把这个知识分享给大家。因为只是为了快点记下繁复的做法,写得很仓促,交代也不清不楚。

    + +

    这是第二版,是 2002-09-04 ~ 2002-09-15 间改写的,当初改写的目的,是这两三个月来,收到好几封信询问这篇文章,觉得自己这篇文章,交代得不清不楚,所以重新改写。因此原先改写的时候,著重在 WHAT 和 WHY 的说明,把 SSL/X.509 架构,交代得比较严谨,也把脑子里想的几张流程图,都给画出来。不过到后来, HOW 的部份,也大幅度地改写,重新编排流程,实验各种情况,更正几个错误,改善原来的设定,统整辞汇的翻译,加上流程的说明。原文 2,931 字,改写后 18,421 字, ^^; 改写的幅度很大。

    + +

    感谢 study-area网中人 (netman) 协助校正好几个错误、疏漏之处。

    + +

    希望改写后,能让这篇文章更好,更严谨,也更容易入手。

    + +
    依玛猫,初稿 2002-01-09 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/sslcerts.html.zh-tw.html b/htdocs/imacat/tech/sslcerts.html.zh-tw.html new file mode 120000 index 0000000..71aee8d --- /dev/null +++ b/htdocs/imacat/tech/sslcerts.html.zh-tw.html @@ -0,0 +1 @@ +sslcerts.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/sslcerts.html.zh-tw.xhtml b/htdocs/imacat/tech/sslcerts.html.zh-tw.xhtml new file mode 100644 index 0000000..1f425bf --- /dev/null +++ b/htdocs/imacat/tech/sslcerts.html.zh-tw.xhtml @@ -0,0 +1,1581 @@ + + + + + + + + + + + + + + + + + + + + + +如何製作 SSL X.509 憑證? + + + + + + + +
    + +
    + + +

    如何製作 SSL X.509 憑證?

    + +

    目錄

    + +
      +
    1. 前言
    2. +
    3. 若妳是 root +
        +
      1. 設定 OpenSSL 的環境
      2. +
      3. 製作最高層認證中心 (Root CA) +
          +
        1. 製作 Public/Private Key
        2. +
        3. 填寫憑證申請書
        4. +
        5. 簽發憑證
        6. +
        +
      4. +
      5. 製作伺服器用的憑證 +
          +
        1. 製作 Public/Private Key
        2. +
        3. 填寫憑證申請書
        4. +
        5. 簽發憑證
        6. +
        +
      6. +
      +
    4. +
    5. 若妳是一般使用者 +
        +
      1. 設定 OpenSSL 的環境
      2. +
      3. 製作最高層認證中心 (Root CA) +
          +
        1. 製作 Public/Private Key
        2. +
        3. 填寫憑證申請書
        4. +
        5. 簽發憑證
        6. +
        +
      4. +
      5. 製作伺服器用的憑證 +
          +
        1. 製作 Public/Private Key
        2. +
        3. 填寫憑證申請書
        4. +
        5. 簽發憑證
        6. +
        +
      6. +
      +
    6. +
    7. 設定作業系統 +
        +
      1. Linux/*BSD/UNIX
      2. +
      3. MS-WINDOWS
      4. +
      +
    8. +
    9. 設定伺服器 +
        +
      1. HTTP +
          +
        1. Apache
        2. +
        +
      2. +
      3. POP3 +
          +
        1. Qpopper
        2. +
        +
      4. +
      5. SMTP +
          +
        1. Sendmail
        2. +
        +
      6. +
      +
    10. +
    11. 設定瀏覽器 +
        +
      1. Mozilla 與 Netscape 6 以後的版本
      2. +
      3. Internet Explorer
      4. +
      5. Opera
      6. +
      7. Lynx
      8. +
      +
    12. +
    13. 設定電子郵件程式 +
        +
      1. Mozilla 與 Netscape 6 以後的版本
      2. +
      3. Netscape 4 及更早的版本
      4. +
      5. Outlook Express 6
      6. +
      7. Outlook Express 5.5
      8. +
      9. Outlook Express 4/5
      10. +
      11. Eudora 5.1 以後的版本
      12. +
      13. Becky!
      14. +
      15. Opera 郵件
      16. +
      +
    14. +
    15. 設定其她不支援 SSL/TLS 的程式 +
        +
      1. Stunnel
      2. +
      +
    16. +
    17. 觀念討論 +
        +
      1. SSL/X.509 簡介
      2. +
      3. 憑證無效的警告
      4. +
      5. 資料?什麼資料?
      6. +
      7. 所以 SSL 就安全了囉?
      8. +
      9. 什麼是數位簽名?
      10. +
      11. 什麼是憑證?
      12. +
      13. 什麼是認證中心?
      14. +
      15. 什麼是最高層認證中心?
      16. +
      17. 如何填寫憑證申請書
      18. +
      19. X.509 憑證制度的檢討
      20. +
      21. 其她 SSL/X.509 憑證的做法
      22. +
      +
    18. +
    19. 註釋
    20. +
    21. 參考資料
    22. +
    23. 後記
    24. +
    + + +

    前言

    + +

    版權所有 © 2002-2006 依瑪貓。依瑪貓保有所有權利。如欲轉載、引用本文,請先詳閱旅舍依瑪版權聲明

    + +

    本文的目的為:在 Linux/*BSD/UNIX 下,用 OpenSSL ,以自己名字發行X.509 SSL 憑證 (Certificate) 。我們會製作兩個憑證:第一步先做以自己為名 (XXX Association, YYY Corporation) ,自己簽名背書的最高層認證中心 (Root CA) ,第二步再做以伺服器為名 (www.abccompany.com) ,用第一步做的最高層認證中心 (XXX Association, YYY Corporation) 簽發的憑證 (Certificate) 。為簡化起見,我們不做中間的認證中心,直接由最高層認證中心 (Root CA) ,來簽發憑證。

    + +

    本文只討論 SSL X.509 憑證做法,不討論系統安全問題,不討論加解密的演算法,也不討論 OpenSSL 的如何安裝。我假設妳瞭解基本 Public Key/Private Key 不對稱加解密的觀念,知道什麼是 RSA/DSA 演算法。我也假設妳已經裝好了 OpenSSL ,安裝時使用下列符合FHS[1] 標準的設定:

    + +
    +
    +./config --prefix=/usr --openssldir=/usr/share/ssl
    +
    +
    + +

    或安裝 RPM 或 apt 的 openssl 套件。

    + +

    本文是做法教學 (HOWTO) ,所以在編排上,把做法步驟 (how) 放在最前面,觀念說明和討論 (what and why) 等,都放在文末。若妳看不懂做法,或想先學一些基本概念,請先往後翻閱,不需由前到後閱讀。

    + +

    注意:依本文製作的憑證,還是會在瀏覽器等 SSL 程式上出現憑證無效的警告。詳情請參考SSL/X.509 簡介憑證無效的警告

    + +

    按 X.509 的規定,憑證可以用 RSA Key ,也可以用 DSA Key 。不過在 SSL 通訊中,伺服器的憑證因為要用來傳 Key ,而只有 RSA 可以傳 Key ,所以只能用 RSA 。至於認證中心,只是簽名查核用,不用傳 Key , DSARSA 都可以,但因為還有一些 SSL 程式不認得 DSA[2] ,為相容性起見,這裏我們也做成 RSA

    + +

    要製作最高層認證中心,可以以一般使用者權限來做,不一定要是 root 。但如果做出來的最高層認證中心,是整個組織簽發憑證要用的,建議以 root 的權限來做,比較安全。同理,製作憑證,也可以以一般使用者權限來做。但如果做出來的憑證,是這個伺服器要用的,為安全起見,建議以 root 的權限來做。

    + + +

    若妳是 root ,要安裝給整個組織來用:

    + +

    設定 OpenSSL 的環境

    + +

    若妳是用上述方法安裝:

    + +
    +
    +./config --prefix=/usr --openssldir=/usr/share/ssl
    +
    +
    + +

    或裝 Red Hat 的 RPM , OpenSSL 的設定檔目錄會在 /usr/share/ssl 。若妳是安裝 Mandrake 的 RPM ,設定檔目錄會在 /usr/lib/ssl 。這兩個位置都不符合 FHS 的要求,資料備份起來也不方便。設定檔應該放在 /etc/ssl 下。若妳是安裝 Debian 的 apt ,設定檔目錄會在 /etc/ssl 下,不會有問題。

    + +
    +
    +# 設定相關的目錄
    +mkdir -p /etc/ssl
    +mkdir -p /etc/ssl/private
    +chmod og-rwx /etc/ssl/private
    +mkdir -p /etc/ssl/certs
    +mkdir -p /etc/ssl/crl
    +mkdir -p /etc/ssl/newcerts
    +
    +# 設定 OpenSSL 設定檔[3]
    +mv /usr/share/ssl/openssl.cnf /etc/ssl
    +ln -s /etc/ssl/openssl.cnf /usr/share/ssl/openssl.cnf
    +
    +# 設定 OpenSSL 設定檔的位置[4]
    +export OPENSSL_CONF="/etc/ssl/openssl.cnf"
    +
    +# 把 OpenSSL 設定檔的位置加進 .bashrc 中[5]
    +echo "# OpenSSL 設定檔的位置" >> ~/.bashrc
    +echo "export OPENSSL_CONF=\"/etc/ssl/openssl.cnf\"" >> ~/.bashrc
    +
    +# 製作亂數檔[6]
    +openssl rand -out /etc/ssl/private/.rand 1024
    +chmod og-rwx /etc/ssl/private/.rand
    +
    +
    + +

    然後修改 /etc/ssl/openssl.cnf ,把這一行

    +
    +
    +dir		= ./demoCA		# Where everything is kept
    +
    +
    +

    改成這樣

    +
    +
    +dir		= /etc/ssl		# Where everything is kept
    +
    +
    + +

    製作最高層認證中心 (Root CA)

    + +

    若妳之前做過最高層認證中心,不要重做,不然原來簽發的憑證,都會失效,都要重簽。除非最高層認證中心自己過期、檔案遺失、 Private Key 外洩,否則絕對不要重做最高層認證中心。

    + +

    假設妳要做的最高層認證中心叫做 myrootca

    + + +

    1. 製作 Private Key (及 Public Key )

    + +

    這裏我們做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特別去做。

    + +

    請為最高層認證中心的 Private Key 設定一個適當的密碼。

    + +
    +
    +# 製作 RSA[7] Private Key
    +openssl genrsa -aes256 -out /etc/ssl/private/myrootca.key.pem 4096
    +chmod og-rwx /etc/ssl/private/myrootca.key.pem
    +
    +
    + + +

    2. 填寫憑證申請書

    + +

    憑證申請書,是把妳的資料,和這個 Public Key 夾在一起,以便認證中心審核,簽上簽名用的。所以這個步驟,會問妳這個 Key 的相關資料,包括國家、城市、單位名稱、部門名稱、憑證名稱、聯絡人的信箱,以及申請的效期等等。請一一填寫。詳情請參考什麼是憑證?

    + +

    若妳要直接用最高層認證中心來直接當憑證用,憑證名稱 (Common Name) 請用伺服器的全名 (www.abc.com) 。詳情請參考其她 SSL/X.509 憑證的做法

    + +

    若不知如何填寫,請參閱如何填寫憑證申請書

    + +
    +
    +# 填寫憑證申請書
    +openssl req -new -key /etc/ssl/private/myrootca.key.pem -out /tmp/myrootca.req.pem
    +
    +
    + + +

    3. 簽發憑證

    + +

    最高層認證中心因為沒有上級了,沒有人能給它簽名,只能自己給自己簽名。詳情請參考什麼是最高層認證中心?

    + +

    最高層認證中心最好永遠不要過期。要是過期重簽,所有原來它簽發的憑證也都要重簽,所有 SSL 程式也都要重新設定。所以我們效期簽7305 天( 20 年)。若不設效期的話,預設是 30 天(一個月)。

    + +

    簽完憑證,憑證申請書就不用了,可以刪掉。

    + +
    +
    +# 自己給自己簽名
    +openssl x509 -req -days 7305 -sha512 \
    + -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
    + -signkey /etc/ssl/private/myrootca.key.pem \
    + -in /tmp/myrootca.req.pem -out /etc/ssl/certs/myrootca.crt.pem
    +
    +# 刪除憑證申請書
    +rm -f /tmp/myrootca.req.pem
    +
    +# 建立 hash 索引
    +c_rehash /etc/ssl/certs
    +
    +
    + +

    這樣就好了。 Private Key 在 +/etc/ssl/private/myrootca.key.pem ,自己簽名的 Public Key 憑證在 /etc/ssl/certs/myrootca.crt.pemmyrootca.key.pem 是 Private Key ,要小心存好保護,只有 root 才能讀,權限建議 0400 。 myrootca.crt.pem 是 Public Key 憑證,要儘量散出去,讓大家用。最好放到內部網路上,或放到網站上,讓大家自己下載,自己加進去。

    + + +

    製作伺服器用的憑證

    + +

    假設妳要做 myhost 的憑證:

    + + +

    1. 製作 Private Key (及 Public Key )

    + +

    這裏我們做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特別去做。

    + +

    請先登入到要用憑證的那臺伺服器上。

    + +

    注意:伺服器的 Private Key 不要設密碼,不然 SSL 伺服器程式啟動的時候,一去讀憑證和 Private Key ,就要問一次密碼。每次重開機,依序啟動每個伺服器程式的時候,一碰到要讀 Private Key 的伺服器程式,都會停下來等鍵盤輸入密碼。要是放假沒人,或伺服器放在 IDC 機房,從遠端重開機或 Crash 後自行重開機,卻當在那裏等鍵盤敲密碼,開不了機,那就不好玩了。

    + +
    +
    +# 製作 RSA Private Key
    +openssl genrsa -out /etc/ssl/private/myhost.key.pem 4096
    +chmod og-rwx /etc/ssl/private/myhost.key.pem
    +
    +
    + + +

    2. 填寫憑證申請書

    + +

    憑證申請書,是把妳的資料,和這個 Public Key 夾在一起,以便認證中心審核,簽上簽名用的。所以這個步驟,會問妳這個 Key 的相關資料,包括國家、城市、單位名稱、部門名稱、憑證名稱、聯絡人的信箱,以及申請的效期等等。這裏憑證名稱 (Common Name) 要用伺服器的全名 (www.abc.com) ,其她請一一填寫。詳情請參考什麼是憑證?

    + +

    若不知如何填寫,請參閱如何填寫憑證申請書

    + +
    +
    +# 填寫憑證申請書
    +openssl req -new -key /etc/ssl/private/myhost.key.pem -out /tmp/myhost.req.pem
    +
    +
    + + +

    3. 用最高層認證中心簽發憑證[8]

    + +

    伺服器憑證的效期其實無所謂,過期重簽一張就好了。 SSL 程式認的是認證中心,不是憑證,所以憑證簽了就會生效,不用去設定 SSL 程式。不過為免重簽的麻煩,我們效期還是簽 3650 天(大約十年)。

    + +

    簽完憑證,憑證申請書就不用了,可以刪掉。

    + +
    +
    +# 簽發憑證
    +openssl x509 -req -days 3650 -sha512 \
    + -extfile /etc/ssl/openssl.cnf -extensions v3_req \
    + -CA /etc/ssl/certs/myrootca.crt.pem -CAkey /etc/ssl/private/myrootca.key.pem \
    + -CAserial /etc/ssl/myrootca.srl -CAcreateserial \
    + -in /tmp/myhost.req.pem -out /etc/ssl/certs/myhost.crt.pem
    +
    +# 刪除憑證申請書
    +rm -f /tmp/myhost.req.pem
    +
    +
    + +

    這樣就好了。[9] Private Key 在 /etc/ssl/private/myhost.key.pem ,要小心存好保護,只有 root 才能讀,建議權限為 0400 ; Public Key 憑證在 /etc/ssl/certs/myhost.crt.pem ,要儘量散出去,讓大家用。這組 Public/Private Key 憑證可以做為 myhostSSL 憑證,用在 HTTPSPOP3/TLSSMTPS/TLS …等等各種 SSL 連線上。最好不要把檔案搬到別的地方。妳可以在設定檔裏,把憑證位置設定到這裏。 PrivateKey 不要到處放,以免不小心忘記保護。

    + + +

    若妳是一般使用者:

    + +

    設定 OpenSSL 的環境

    + +
    +
    +# 設定相關的目錄
    +mkdir -p ~/etc
    +mkdir -p ~/etc/ssl
    +mkdir -p ~/etc/ssl/private
    +chmod og-rwx ~/etc/ssl/private
    +mkdir -p ~/etc/ssl/certs
    +mkdir -p ~/etc/ssl/crl
    +mkdir -p ~/etc/ssl/newcerts
    +mkdir -p ~/tmp
    +
    +# 設定 OpenSSL 設定檔[10]
    +cp /usr/share/ssl/openssl.cnf ~/etc/ssl
    +
    +# 設定 OpenSSL 設定檔的位置[11]
    +export OPENSSL_CONF="$HOME/etc/ssl/openssl.cnf"
    +
    +# 把 OpenSSL 設定檔的位置加進 .bashrc 中[12]
    +echo "# OpenSSL 設定檔的位置" >> ~/.bashrc
    +echo "export OPENSSL_CONF=\"$HOME/etc/ssl/openssl.cnf\"" >> ~/.bashrc
    +
    +# 製作亂數檔[13]
    +openssl rand -out ~/etc/ssl/private/.rand 1024
    +chmod og-rwx ~/etc/ssl/private/.rand
    +
    +
    + +

    然後修改 ~/etc/ssl/openssl.cnf ,把這一行

    +
    +
    +dir		= ./demoCA		# Where everything is kept
    +
    +
    +

    改成這樣

    +
    +
    +dir		= ~/etc/ssl		# Where everything is kept
    +
    +
    + + +

    製作最高層認證中心 (Root CA)

    + +

    若妳之前做過最高層認證中心,不要重做,不然原來簽發的憑證,都會失效,都要重簽。除非最高層認證中心自己過期、檔案遺失、 Private Key 外洩,否則絕對不要重做最高層認證中心。

    + +

    假設妳要做的最高層認證中心叫做 myrootca

    + + +

    1. 製作 Private Key (及 Public Key )

    + +

    這裏我們做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特別去做。

    + +

    請為最高層認證中心的 Private Key 設定一個適當的密碼。

    + +
    +
    +# 製作 RSA[14] Private Key
    +openssl genrsa -aes256 -out ~/etc/ssl/private/myrootca.key.pem 4096
    +chmod og-rwx ~/etc/ssl/private/myrootca.key.pem
    +
    +
    + + +

    2. 填寫憑證申請書

    + +

    憑證申請書,是把妳的資料,和這個 Public Key 夾在一起,以便認證中心審核,簽上簽名用的。所以這個步驟,會問妳這個 Key 的相關資料,包括國家、城市、單位名稱、部門名稱、憑證名稱、聯絡人的信箱,以及申請的效期等等。請一一填寫。詳情請參考什麼是憑證?

    + +

    若不知如何填寫,請參閱如何填寫憑證申請書

    + +

    若妳要直接用最高層認證中心來直接當憑證用,憑證名稱 (Common Name) 請用伺服器的全名 (www.abc.com) 。詳情請參考其她 SSL/X.509 憑證的做法

    + +
    +
    +# 填寫憑證申請書
    +openssl req -new -key ~/etc/ssl/private/myrootca.key.pem -out ~/tmp/myrootca.req.pem
    +
    +
    + + +

    3. 簽發憑證

    + +

    最高層認證中心因為沒有上級了,沒有人能給它簽名,只能自己給自己簽名。詳情請參考什麼是最高層認證中心?

    + +

    最高層認證中心最好永遠不要過期。要是過期重簽,所有原來它簽發的憑證也都要重簽,所有 SSL 程式也都要重新設定。所以我們效期簽 7305 天(大約 20年)。若不設效期的話,預設是 30 天(一個月)。

    + +

    簽完憑證,憑證申請書就不用了,可以刪掉。

    + +
    +
    +# 自己給自己簽名
    +openssl x509 -req -days 7305 -sha512 \
    + -extfile ~/etc/ssl/openssl.cnf -extensions v3_ca \
    + -signkey ~/etc/ssl/private/myrootca.key.pem \
    + -in ~/tmp/myrootca.req.pem -out ~/etc/ssl/certs/myrootca.crt.pem
    +
    +# 刪除憑證申請書
    +rm -f ~/tmp/myrootca.req.pem
    +
    +# 建立 hash 索引
    +c_rehash ~/etc/ssl/certs
    +
    +
    + +

    這樣就好了。 Private Key 在 +~/etc/ssl/private/myrootca.key.pem ,自己簽名的 Public Key 憑證在 ~/etc/ssl/certs/myrootca.crt.pemmyrootca.key.pem 是 Private Key ,要小心存好保護,只有自己才能讀,權限建議 0400 。 myrootca.crt.pem 是 Public Key 憑證,要儘量散出去,讓大家用。最好放到網站上,讓大家自己下載,自己加進去。

    + + +

    製作伺服器用的憑證

    + +

    假設妳要做 myhost 的憑證:

    + + +

    1. 製作 Private Key (及 Public Key )

    + +

    這裏我們做一支新的 Private Key 。 Public Key 可由 Private Key 推得 +,所以不用特別去做。

    + +

    注意:伺服器的 Private Key 不要設密碼,不然 SSL 伺服器程式啟動的時候,一去讀憑證和 Private Key ,就要問一次密碼。每次重開機,依序啟動每個伺服器程式的時候,一碰到要讀 Private Key 的伺服器程式,都會停下來等鍵盤輸入密碼。要是放假沒人,或伺服器放在 IDC 機房,從遠端重開機或 Crash 後自行重開機,卻當在那裏等鍵盤敲密碼,開不了機,那就不好玩了。

    + +
    +
    +# 製作 RSA Private Key
    +openssl genrsa -out ~/etc/ssl/private/myhost.key.pem 4096
    +chmod og-rwx ~/etc/ssl/private/myhost.key.pem
    +
    +
    + + +

    2. 填寫憑證申請書

    + +

    憑證申請書,是把妳的資料,和這個 Public Key 夾在一起,以便認證中心審核,簽上簽名用的。所以這個步驟,會問妳這個 Key 的相關資料,包括國家、城市、單位名稱、部門名稱、憑證名稱、聯絡人的信箱,以及申請的效期等等。這裏憑證名稱 (Common Name) 要用伺服器的全名 (www.abc.com) ,其她請一一填寫。詳情請參考什麼是憑證?

    + +

    若不知如何填寫,請參閱如何填寫憑證申請書

    + +
    +
    +# 填寫憑證申請書
    +openssl req -new -key ~/etc/ssl/private/myhost.key.pem -out /tmp/myhost.req.pem
    +
    +
    + + +

    3. 用最高層認證中心簽發憑證[8][15]

    + +

    伺服器憑證的效期其實無所謂,過期重簽一張就好了。 SSL 程式認的是認證中心,不是憑證,所以憑證簽了就會生效,不用去設定 SSL 程式。不過為免重簽的麻煩,我們效期還是簽 3650 天(大約十年)。

    + +

    簽完憑證,憑證申請書就不用了,可以刪掉。

    + +
    +
    +# 簽發憑證
    +openssl x509 -req -days 3650 -sha512 \
    + -extfile ~/etc/ssl/openssl.cnf -extensions v3_req \
    + -CA ~/etc/ssl/certs/myrootca.crt.pem -CAkey ~/etc/ssl/private/myrootca.key.pem \
    + -CAserial ~/etc/ssl/myrootca.srl -CAcreateserial \
    + -in /tmp/myhost.req.pem -out ~/etc/ssl/certs/myhost.crt.pem
    +
    +# 刪除憑證申請書
    +rm -f /tmp/myhost.req.pem
    +
    +
    + +

    這樣就好了。[16] Private Key 在 ~/etc/ssl/private/myhost.key.pem ,要小心存好保護,只有自己才能讀,建議權限為 0400 ; Public Key 憑證在 ~/etc/ssl/certs/myhost.crt.pem ,要儘量散出去,讓大家用。這組 Public/Private Key 憑證可以做為 myhostSSL 憑證,用在 HTTPSPOP3S/TLSSMTPS/TLS …等等各種 SSL 連線上。最好不要把檔案搬到別的地方。妳可以在設定檔裏,把憑證位置設定到這裏。 PrivateKey 不要到處放,以免不小心忘記保護。

    + + +

    設定作業系統

    + +

    很多作業系統,都有系統公用的憑證庫,把認得的憑證、認證中心放在一起。我們把我們自製的認證中心,加進系統公用的憑證庫,使用這個憑證庫的程式,就可以查得到了。

    + + +

    Linux/*BSD/UNIX

    + + +

    MS-WINDOWS

    + +

    MS-WINDOWS 設有共用的憑證庫。從 [控制台] 進去,裏面有 [網際網路選項] (或 [Internet 選項] )。在上面點兩下,會打開一個[網際網路 內容] (或 [Internet 內容] )的視窗。在 [內容] 那一頁裏,中間有一區 [憑證] ,裏面有一個 [憑證(C)...] 的按鈕。按一下那個按鈕,會打開一個視窗,標題是 [憑證] 。這裏就是 MS-WINDOWS 管理憑證的地方。[20]

    + +

    要加進我們的最高層認證中心,將我們的最高層認證中心 myrootca.crt.pem 複製到 WINDOWS 上。點兩下打開 myrootca.crt.pem ,會跳出一個 [憑證] 的視窗,裏面會列出憑證的內容。按下面的 [安裝憑證]按鈕,會跑出一個 [憑證管理員匯入精靈] 。一直按 [下一步] ,就會加進去了。

    + +

    我所知道,會使用系統憑證庫的 WINDOWS 程式,有 Internet Exporer 、 Outlook Express 、 Outlook 、 Symantec pcAnywhere 。只要把我們自製的認證中心加進來,這些程式都可以用得到。

    + + +

    設定伺服器

    + +

    常見的 SSL 通訊方式有兩種:一種是傳統的 SSL ,一種是新的 TLS

    + +

    傳統的 SSL ,一連上伺服器,就進入 SSL ,全程加密。這樣做有一個缺點:為了不讓使用者程式混淆,要把SSL 開在另外一個 TCP 埠,還要設定使用者的程式,改連到 SSL 的那個 TCP 埠去。 HTTPHTTPS 的方式就是這樣。

    + +

    新的 TLS ,則是在使用者程式連上伺服器後,下 STARTTLS 指令,如果伺服器有 SSL ,就會進入 SSL ,雙方開始加密;如果伺服器沒有 SSL ,看不懂 STARTTLS ,雙方就按原來的方式繼續連線。這樣做的好處是,使用者程式不用改設連接埠,可以自行切入 SSL 或退回不加密連線,相容性高,也不用為了 SSL ,多開一個 TCP 埠。但 TLS 的缺點則是,就算憑證查核的結果有問題,不能做SSL ,還是可以退回原來的方式繼續連線,那憑證查核的工作,有做等於沒做。只有連線加密的的優點而已,無法查證伺服器的身份。

    + +

    以下依不同的通訊協定,分別討論。

    + + +

    HTTP

    + +

    HTTP 是最早用 SSL 的通訊協定。 Netscape 當初是為了加密 HTTP ,做安全網路交易,才設計了 SSL ,開一個新的 TCP 埠 443 給它專用,取名為 HTTPS ,延用至今。因此, HTTPSSL 用的是傳統的方式,沒有 TLS ,要開 HTTPS(443) 。

    + + +

    Apache

    + +

    Apache 要做 HTTPS ,可以搭配 Apache-SSL ,或搭配 mod_ssl 。請參考各自的設定說明。

    + +

    注意:Apache 的記憶體中只能存一組憑證。而憑證上記有伺服器的全名,瀏覽器會用來核對網站站名,所以一個 Apache ,只能用一個 SSL 站名。也就是說,一個 Apache ,只能架一個 SSL 站。除非妳跑很多份 Apache ,各自跑在不同的 IP 或不同的 TCP 埠上,才能在同一臺伺服器上,跑好幾個 SSL 站。

    + +

    以 mod_ssl 來說,安裝好後, httpd.conf 設定舉例如下:

    + +
    +
    +......
    +## mod_ssl.c: mod_ssl 基本設定
    +<IfModule mod_ssl.c>
    +    Listen 443
    +    AddType application/x-x509-ca-cert .crt
    +    AddType application/x-pkcs7-crl    .crl
    +    SSLSessionCache dbm:/var/log/apache/ssl_scache
    +    SSLSessionCacheTimeout 300
    +    SSLPassPhraseDialog builtin
    +    SSLMutex file:/var/log/apache/ssl_mutex
    +    SSLRandomSeed startup builtin
    +    SSLRandomSeed connect builtin
    +    SSLLog /var/log/apache/ssl_engine_log
    +    SSLLogLevel info
    +    SSLCipherSuite ALL:!ADH:!EXP56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
    +    SSLCertificateFile /etc/ssl/certs/myhost.crt.pem
    +    SSLCertificateKeyFile /etc/ssl/private/myhost.key.pem
    +    <VirtualHost *:443>
    +        SSLEngine on
    +    </VirtualHost>
    +</IfModule>
    +......
    +
    +
    + +

    設好後,檢查看 httpd.conf 有沒有設錯:

    + +
    +
    +httpd -t
    +
    +
    + +

    要是沒有問題,重開 httpdSSL 網站就開跑了。

    + + +

    POP3

    + +

    POP3 可以跑兩種方式:傳統用 POP3(995) 埠專跑 SSL ,或是用 TLS ,在原來的 POP3(110) 埠上,加上 STARTTLS 的功能。

    + +

    POP3 的 STARTTLS 指令是 STLS

    + + +

    Qpopper

    + +

    要安裝 Qpopper ,請參考 Qpopper 的說明文件。

    + +

    Qpopper 可以做 POP3(995) ,也可以在 POP3(110) 上做 TLS 。然而,一個 Qpopper 只能開一個 TCP 埠,用一種方式跑。如果要同時做 POP3(995) 和 POP3(110)/TLS ,要跑兩份 Qpopper,各自用不同的設定檔。

    + +

    設定 /etc/qpopper.conf 如下:

    + +
    +
    +# qpopper.conf: Qpopper POP3(110)/TLS 的設定檔
    +set clear-text-password         = always
    +set statistics                  = true
    +set tls-support                 = stls
    +set tls-private-key-file        = /etc/ssl/private/myhost.key.pem
    +set tls-server-cert-file        = /etc/ssl/certs/myhost.crt.pem
    +
    +
    + +

    設定 /etc/qpopper-s.conf 如下:

    + +
    +
    +# qpopper-s.conf: Qpopper POP3S(995) 的設定檔
    +set clear-text-password         = tls
    +set statistics                  = true
    +set tls-support                 = alternate-port
    +set tls-private-key-file        = /etc/ssl/private/myhost.key.pem
    +set tls-server-cert-file        = /etc/ssl/certs/myhost.crt.pem
    +
    +
    + +

    然後用 root 的權限,分別執行:

    + +
    +
    +popper -f /etc/qpopper.conf
    +popper 995 -f /etc/qpopper-s.conf
    +
    +
    + +

    這樣就可以了。查看:

    + +
    +
    +ps ax | grep popper
    +
    +
    + +

    妳會看到有兩個 popper ,用不同的參數在跑。查看:

    + +
    +
    +netstat -ap | grep popper
    +
    +
    + +

    妳會看到兩個 popper ,分別在 POP3(110) 和 POP3(995) 兩個 TCP 埠上。

    + + +

    SMTP

    + +

    SMTP 也可以跑兩種方式:舊式的做法,是另開一個 SMTPS(465) 埠,來專跑 SSL 。新的做法則用 TLS ,在原來的 SMTP(25) 埠上,加上 STARTTLS 的功能。 TLS 用同一個連接埠,相容性比較高,為郵件伺服器間收發信的相容性起見,請儘量採用 TLS[17]

    + +

    SMTP 的 STARTTLS 指令是 STARTTLS

    + + +

    Sendmail

    + +

    Sendmail 可以在編譯時,加入 SMTPSTLS 的支援,不過 SMTPS 是屬於 FFR (for future release) 尚未正式發表的功能,在所有 Sendmail 的說明文件中,都找不到 SMTPS 的說明,只有 TLS 的說明。

    + +

    Sendmail 送信時,只會在原來的 SMTP(25) 埠上,試 STARTTLS 指令。對方要是不支援 TLS 就算了,用原來不加密的方法寄信,不會去試對方的 SMTPS(465) 埠。

    + +

    為讓郵件順利流通,不要掉信, Sendmail 送信時,能加密就加密,不會查核對方的憑證。更何況,在 TLS 下查核憑證,也沒什麼意義。

    + +

    要設定 Sendmail 使用 SSL ,編譯 Sendmail 時,要在 devtools/Site/site.config.m4 檔,加入下列這幾行:

    + +
    +
    +# STARTTLS - 加入 SSL/TLS 功能
    +APPENDDEF(`conf_sendmail_ENVDEF', `-DSTARTTLS')
    +APPENDDEF(`conf_sendmail_LIBS', `-lssl -lcrypto')
    +
    +# SMTP SSL - 加入 SMTPS 功能
    +APPENDDEF(`conf_sendmail_ENVDEF', `-D_FFR_SMTP_SSL')
    +
    +
    + +

    編譯、安裝:

    + +
    +
    +# 編譯 Sendmail
    +./Build
    +
    +# 安裝 Sendmail
    +make install
    +
    +
    + +

    接下來要設定 Sendmail 的設定檔 /etc/mail/sendmail.cf 。如果妳是用 m4 來做設定檔,在 m4 檔 config.mc 中加入下列幾行:

    + +
    +
    +dnl Sendmail SMTPS/STARTTLS SSL 設定
    +define(`confCACERT_PATH', `/etc/ssl/certs')
    +define(`confCACERT', `/etc/ssl/certs/myrootca.crt.pem')
    +define(`confSERVER_CERT', `/etc/ssl/certs/myhost.crt.pem')
    +define(`confSERVER_KEY', `/etc/ssl/private/myhost.key.pem')
    +define(`confCLIENT_CERT', `/etc/ssl/certs/myhost.crt.pem')
    +define(`confCLIENT_KEY', `/etc/ssl/private/myhost.key.pem')
    +DAEMON_OPTIONS(`Name=MTA')dnl
    +DAEMON_OPTIONS(`Port=465, Name=MTASSL, M=s')dnl
    +
    +
    + +

    重做設定檔:

    + +
    +
    +m4 m4/cf.m4 config.mc > config.cf
    +cp -f config.cf /etc/mail/sendmail.cf
    +
    +
    + +

    然後重開 Sendmail 。這樣 Sendmail 就可以開始做 SMTPS/TLS SSL 了。查看:

    + +
    +
    +netstat -ap | grep sendmail
    +
    +
    + +

    妳會看到同一個 sendmail ,跑在 SMTP(25) 和 SMTPS(465) 兩個[18] TCP 埠上。

    + +

    不過設定還沒結束。

    + +

    Sendmail 自 8.12.1 版以後,為加強安全性,將伺服器和使用者程式分開。伺服器程式因為要跑在低於 1024 的 SMTP(25) 埠,要有權限把信存進每個人的信箱,還是要以 root 的權限來執行。不過這只要以 root 來啟動伺服器程式,就可以了。使用者程式則不需要 root 的權限,只要可以在專用的郵件佇列目錄存檔就夠了。所以, Sendmail 不再 setuid root ,改成 setgid smmsp[19] 。使用者程式要發信的時候,再連到 SMTP 伺服器發信。

    + +

    Sendmail 伺服器程式因為有 root 的權限,要讀 Private Key 不是問題。可是, Sendmail 使用者程式現在沒有了 root 的權限,發信的時候,就讀不到我們伺服器的 Private Key 了。怎麼辦?

    + +

    我們不要讓 Sendmail setuid-root ,也不要開放伺服器 Private Key 的權限。我們可以另外做一組只有 smmsp 群組讀得到的憑證,給 Sendmail 的使用者程式專用:

    + +
    +
    +# 設定目錄
    +mkdir -p /etc/mail/private
    +chgrp smmsp /etc/mail/private
    +chmod o-rwx /etc/mail/private
    +mkdir -p /etc/mail/certs
    +
    +# 製作 RSA Private Key
    +openssl genrsa -out /etc/mail/private/myhost-msp.key.pem 4096
    +chgrp smmsp /etc/mail/private/myhost-msp.key.pem
    +chmod o-rwx /etc/mail/private/myhost-msp.key.pem
    +
    +# 填寫憑證申請書
    +openssl req -new -key /etc/mail/private/myhost-msp.key.pem \
    + -out /tmp/myhost-msp.req.pem
    +
    +# 簽發憑證
    +openssl x509 -req -days 3650 -sha512 \
    + -extfile /etc/ssl/openssl.cnf -extensions v3_req \
    + -CA /etc/ssl/certs/myrootca.crt.pem -CAkey /etc/ssl/private/myrootca.key.pem \
    + -CAserial /etc/ssl/myrootca.srl -CAcreateserial \
    + -in /tmp/myhost-msp.req.pem -out /etc/mail/certs/myhost-msp.crt.pem
    +
    +# 刪除憑證申請書
    +rm -f /tmp/myhost-msp.req.pem
    +
    +
    + +

    然後設定 m4 檔 submic.mc 如下:

    + +
    +
    +......
    +dnl Sendmail STARTTLS SSL/TLS support
    +define(`confCACERT_PATH', `/etc/ssl/certs')
    +define(`confCACERT', `/etc/ssl/certs/myrootca.crt.pem')
    +define(`confCLIENT_CERT', `/etc/mail/certs/myhost-msp.crt.pem')
    +define(`confCLIENT_KEY', `/etc/mail/private/myhost-msp.key.pem')
    +define(`confDONT_BLAME_SENDMAIL', `GroupReadableKeyFile')
    +......
    +
    +
    + +

    重做設定檔:

    + +
    +
    +m4 m4/cf.m4 submit.mc > submit.cf
    +cp -f submit.cf /etc/mail/submit.cf
    +
    +
    + +

    這樣就可以了。這不是設定 Sendmail 伺服器程式,不用重開 Sendmail 。 ^_*' 妳可以寄一封信給自己,然後看看系統郵件記錄 maillog ,有沒有成功使用 SSL

    + +
    +
    +......
    +Sep 14 04:19:24 rinse sendmail[12093]: STARTTLS=client, relay=localhost.localdom
    +ain., version=TLSv1/SSLv3, verify=OK, cipher=EDH-RSA-DES-CBC3-SHA, bits=168/168
    +......
    +
    +
    + + +

    設定瀏覽器

    + +

    Mozilla 與 Netscape 6 以後的版本

    + +

    Mozilla 與 Netscape 6 以後的版本,有一個瀏覽器和郵件程式共用的憑證庫。從工具列上的 [編輯(E)][個人功能設定(E)] 進去後,會跳出 [功能設定] 的視窗。展開視窗左邊的 [個人及安全設定] ,點選裏面的 [認證] ,右邊的標題會切換成 [認證] ,中間會有一個 [管理認證...] 的按鈕。按下按鈕,會再跳出一個 [認證管理員] 的視窗。這裏就是 Mozilla 與 Netscape 管理憑證的地方。[21][22]

    + +

    要加進我們的最高層認證中心,將我們的最高層認證中心 myrootca.crt.pem 放到網站上,用 Mozilla/Netscape 從 web 連到該網址後,會出現一個 [下載認證中] 的視窗。在 [信認此認證以識別網站][信認此認證以識別郵件用戶][信認此認證以識別軟體製造商] 三個選項上都打勾,然後按 [確定] ,就會加進去了。

    + +

    如果妳用的是 MS-WINDOWS 下的 Mozilla/Netscape ,妳也可以把最高層認證中心複製到 WINDOWS 上,網址列直接打上檔案路徑,也可以把它加進去。

    + +

    在 Mozilla/Netscape 瀏覽器加進來的認證中心,也會用在 Mozilla 信件或 Netscape Mail & Newsgroups 裏,來查核憑證。

    + + +

    Internet Explorer

    + +

    Internet Explorer 使用 WINDOWS 系統的憑證庫,妳只要把認證中心加進系統的憑證庫就可以了。詳情請參考設定 MS-WINDOWS

    + + +

    Opera

    + +

    Opera 截至目前為止 (6.05) ,只支援 RSA ,不支援 DSA 。因此,只能匯入 RSA 認證中心,不能匯入 DSA 認證中心。

    + +

    打開 Opera ,從工具列上的 [檔案(F)][功能設定(R)...] 進去後,會打開 [功能設定] 的視窗。在視窗左邊的選單中,選最下面的 [安全性] 時,右上角會出現 [認證機構(A)...] 的按鈕。按下按鈕,會再打開 [認證機構] 的視窗。按一下右上角的 [匯入(I)...] 按鈕,找到我們的最高層認證中心,在上面點兩下,就會加進去了。

    + + +

    Lynx

    + +

    Lynx 截至目前為止 (2.8.4) ,不會檢查伺服器的 SSL 憑證。

    + + +

    設定電子郵件程式

    + +

    Mozilla 與 Netscape 6 以後的版本

    + +

    要設定使用 SSL 收信,啟動 Mozilla 信件與 News 或 Netscape Mail & Newsgroups 後,由工具列上的 [編輯(E)][信件與 News 帳號設定(M)...] 按下去,會打開一個 [信件與 News 帳號設定] 的視窗。在左邊選擇妳要設定的帳號下的 [伺服器設定] 。視窗右邊的 [伺服器名稱:] 中,要填上 POP3 郵件伺服器的完整名稱。在右下方 [伺服器設定] 裏的 [使用 SSL 安全連線] 選項上打勾,然後按 [確定] 。這樣就會用 SSL 收信了。

    + +

    要設定使用 SSL 寄信,啟動 Mozilla 信件與 News 或 Netscape Mail & Newsgroups 後,由工具列上的 [編輯(E)][信件與 News 帳號設定(M)...] 按下去,會打開一個 [信件與 News 帳號設定] 的視窗。在左邊選擇 [SMTP 外寄郵件伺服器] ,右邊標題會變成 [SMTP 外送郵件伺服器設定] 。視窗右邊的 [伺服器名稱:] 中,要填上 SMTP 郵件伺服器的完整名稱。右邊中間有一個 [使用 SSL 安全連線] ,選 [若可以時] 。然後按 [確定] 。這樣就會用 SSL 寄信了。

    + +

    憑證查核的部份,Mozilla 信件與 News 或 Netscape Mail & Newsgroups 使用 Mozilla 或 Netscape 6 的憑證庫,妳只要把認證中心加進 Mozilla 或 Netscape 6 就可以了。詳情請參考Mozilla 與 Netscape 6 的設定

    + + +

    Netscape 4 及更早的版本

    + +

    Netscape 4 及更早的版本不支援 SSL

    + + +

    Outlook Express 6

    + +

    要設定使用 SSL 收信,啟動 Outlook Express 後,由工具列上的 [工具(T)][帳戶(A)...] 按下去,會打開一個 [網際網路帳戶] 的視窗。在視窗左邊選擇要設定的帳號,然後按下右邊的 [內容(P)] 按鈕,會打開另一個 [某某某 內容] 的視窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一頁。在 [內送郵件 - POP3(I):] 中,要填上 POP3 郵件伺服器的完整名稱。再按一下上方的[進階] ,翻到 [進階] 那一頁。在 [內送郵件 - POP3(I):] 下面的 [這個伺服器需要安全連線 - SSL(C)] 的選項上打勾。然後按 [確定][關閉] 。這樣就會用 SSL 收信了。

    + +

    要設定使用 SSL 寄信,啟動 Outlook Express 後,由工具列上的 [工具(T)][帳戶(A)...] 按下去,會打開一個 [網際網路帳戶] 的視窗。在視窗左邊選擇要設定的帳號,然後按下右邊的 [內容(P)] 按鈕,會打開另一個 [某某某 內容] 的視窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一頁。在 [外寄郵件 - SMTP(U):] 中,要填上 SMTP 郵件伺服器的完整名稱。再按一下上方的[進階] ,翻到 [進階] 那一頁。在 [外寄郵件 - SMTP(O):] 下面的 [這個伺服器需要安全連線 - SSL(Q)] 的選項上打勾,並把上面 [外寄郵件 - SMTP(O):] 的連接埠號碼改為 465 。然後按 [確定][關閉] 。這樣就會用 SSL 寄信了。

    + +

    憑證查核的部份, Outlook Express 6 使用 WINDOWS 系統的憑證庫,妳只要把認證中心加進系統的憑證庫就可以了。詳情請參考設定 MS-WINDOWS

    + + +

    Outlook Express 5.5

    + +

    要設定使用 SSL 收信,啟動 Outlook Express 後,由工具列上的 [工具(T)][帳號(A)...] 按下去,會打開一個 [Internet 帳號] 的視窗。在視窗左邊選擇要設定的帳號,然後按下右邊的 [內容(P)] 按鈕,會打開另一個 [某某某 內容] 的視窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一頁。在 [內送郵件 - POP3(I):] 中,要填上 POP3 郵件伺服器的完整名稱。再按一下上方的[進階] ,翻到 [進階] 那一頁。在 [內送郵件 - POP3(I):] 下面的 [這個伺服器需要安全連線 - SSL(C)] 的選項上打勾。然後按 [確定][關閉] 。這樣就會用 SSL 收信了。

    + +

    要設定使用 SSL 寄信,啟動 Outlook Express 後,由工具列上的 [工具(T)][帳號(A)...] 按下去,會打開一個 [Internet 帳號] 的視窗。在視窗左邊選擇要設定的帳號,然後按下右邊的 [內容(P)] 按鈕,會打開另一個 [某某某 內容] 的視窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一頁。在 [外寄郵件 - SMTP(U):] 中,要填上 SMTP 郵件伺服器的完整名稱。再按一下上方的[進階] ,翻到 [進階] 那一頁。在 [外寄郵件 - SMTP(O):] 下面的 [這個伺服器需要安全連線 - SSL(Q)] 的選項上打勾,並把上面 [外寄郵件 - SMTP(O):] 的連接埠號碼改為 465 。然後按 [確定][關閉] 。這樣就會用 SSL 寄信了。

    + +

    憑證查核的部份, Outlook Express 5.5 使用 WINDOWS 系統的憑證庫,妳只要把認證中心加進系統的憑證庫就可以了。詳情請參考設定 MS-WINDOWS

    + + +

    Outlook Express 4 或 5

    + +

    要設定使用 SSL 收信,啟動 Outlook Express 後,由工具列上的 [工具(T)][帳號(A)...] 按下去,會打開一個 [Internet 帳號] 的視窗。在視窗左邊選擇要設定的帳號,然後按下右邊的 [內容(P)] 按鈕,會打開另一個 [某某某 內容] 的視窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一頁。在 [內送郵件 - POP3(I):] 中,要填上 POP3 郵件伺服器的完整名稱。再按一下上方的[進階] ,翻到 [進階] 那一頁。在 [內送郵件 - POP3(I):] 下面的 [這個伺服器需要安全連線 - SSL(C)] 的選項上打勾。然後按 [確定][結束] 。這樣就會用 SSL 收信了。

    + +

    要設定使用 SSL 寄信,啟動 Outlook Express 後,由工具列上的 [工具(T)][帳號(A)...] 按下去,會打開一個 [Internet 帳號] 的視窗。在視窗左邊選擇要設定的帳號,然後按下右邊的 [內容(P)] 按鈕,會打開另一個 [某某某 內容] 的視窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一頁。在 [外寄郵件 - SMTP(U):] 中,要填上 SMTP 郵件伺服器的完整名稱。再按一下上方的[進階] ,翻到 [進階] 那一頁。在 [外寄郵件 - SMTP(O):] 下面的 [這個伺服器需要安全連線 - SSL(Q)] 的選項上打勾,並把上面 [外寄郵件 - SMTP(O):] 的連接埠號碼改為 465 。然後按 [確定][關閉] 。這樣就會用 SSL 寄信了。

    + +

    Outlook Express 4 與 5 不會檢查伺服器的 SSL 憑證。

    + + +

    Eudora 5.1 以後的版本

    + +

    Eudora 的 SSL 設計不是很好。

    + +

    Eudora 5.1 以後有一個 [Certificate Infomation Manager] 憑證管理員,可以管理 Eudora 的憑證。可是很奇怪,沒有辦法直接進入 [Certificate Infomation Manager][23] ,要先用 SSL 收一次信,才能進入 [Certificate Infomation Manager][24]

    + +

    收信時, Eudora 會先用 STARTTLS 指令試探郵件伺服器。成功的話,雙方就進入 SSL 加密連線,開始收信;否則,就繼續用不加密的方式收信。不用特別設定 SSL 收信的方式。不過 Eudora 的 STARTTLS 做法很奇怪:如果 STARTTLS 成功,進入 SSL 以後, Eudora 卻查核不到對方的憑證, Eudora 會立即停止收信,不會重做非 SSL 連線,不會詢問使用者,只會在下面不明顯的地方出現一個小小的警告。對使用自製的伺服器憑證,新加上 STARTTLS 功能的郵件伺服器來說,使用者的 Eudora 原本正常收的信,會不聞不問開始停止收信,給使用者帶來很大的困擾。這是 Eudora 另一個不良的設計。在 TLS 下查核憑證,本來就沒什麼意義。而且憑證查核失敗的原因,只是 Eudora 認不得核發單位,不是憑證真的有問題。Eudora 應該詢問使用者,不應該直接停止收信。

    + +

    注意: OpenSSL 預設是做 PEM 格式的憑證,所以先前我們做的都是 PEM 格式的憑證。但 Eudora 只能匯入 DER 憑證格式。 PEM 只是把 DER 用 Base64 編碼,以便和傳統七位元的網路標準相容,放在網頁上、用 E-mail 寄或貼在文字檔中。我們可以用 OpenSSL 把 PEMDER

    + +
    +
    +# 將最高層認證中心轉成 DER 檔
    +openssl x509 -in myrootca.crt.pem -outform der -out myrootca.crt.der
    +
    +
    + +

    要設定使用 SSL 收信,啟動 Eudora 後,由工具列上的 [Tools][Options...] 按下去,會打開一個 [Options] 的視窗。在左邊的 [Category] 中選擇 [Checking Mail] 。視窗右邊的 [Mail Server:] 中,要填上 POP3 郵件伺服器的完整名稱。右下方有一個 [Secure Sockets when Receiving:] 的選單,選 [If available, STARTTLS] 後,按 [OK] 。這樣就會用 SSL 收信了。

    + +

    要設定使用 SSL 寄信,啟動 Eudora 後,由工具列上的 [Tools][Options...] 按下去,會打開一個 [Options] 的視窗。在左邊的 [Category] 中選擇 [Sending Mail] 。視窗右邊的 [Mail Server:] 中,要填上 SMTP 郵件伺服器的完整名稱。右下方有一個 [Secure Sockets when Receiving:] 的選單,選 [If available, STARTTLS] 後,按 [OK] 。這樣就會用 SSL 寄信了。

    + +

    要加入我們的認證中心,要先收一次信。視窗下面會顯示 [SSL Negotiation Failed: Certificate Error: Cert Chain not trusted. ...] 的錯誤訊息。依前述方式回到 [Tools][Options...][Category][Checking Mail][Secure Sockets when Receiving:] 後,按一下 [Last SSL Info] ,以開啟[Eudora SSL Connection Infomation Manager] 的視窗,顯示剛剛收到的憑證內容。按一下下面的 [Certificate Infomation Manager] 按鈕,會再跳出一個 [Certificate Infomation Manager] 的視窗。按一下右下角的 [Import Certificate] ,找到我們的最高層認證中心的 DERmyrootca.crt.der ,在上面點兩下,就會加進去了。[25]

    + + +

    Becky!

    + +

    Becky! 的作者 Tomohiro Norimatsu 已經說過,因為 SSL 專利權的問題, Becky! 不會支援 SSL[26] 不過我們可以用SSL 包裝程式,讓 Becky! 透過 SSL 連線來收發信。詳情請參考設定其她不支援 SSL/TLS 的程式

    + + +

    Opera 郵件

    + +

    要設定使用 SSL 收信,打開 Opera ,從工具列上的 [檔案(F)][功能設定(R)...] 進去後,會打開 [功能設定] 的視窗。在視窗左邊的選單中,選 [電子郵件] 時,右邊會出現 [使用 Opera 的帳號(O)] 的選單。選擇要設定的帳號,然後按旁邊的 [更改(P)...] ,會跳出一個 [郵件帳號設定] 的視窗。在上面的 [伺服器] 上按一下,切換到 [伺服器] 那一頁。在 [內收郵件] 裏 , [主機位置(E)] 中,要填上 POP3 郵件伺服器的完整名稱,然後在下面 [協定(R)] 旁邊 [採用 TLS 安全性協定] 的地方打勾,按 [確定][確定] 。這樣就會用 SSL 收信了。

    + +

    要設定使用 SSL 寄信,打開 Opera ,從工具列上的 [檔案(F)][功能設定(R)...] 進去後,會打開 [功能設定] 的視窗。在視窗左邊的選單中,選 [電子郵件] 時,右邊會出現 [使用 Opera 的帳號(O)] 的選單。選擇要設定的帳號,然後按旁邊的 [更改(P)...] ,會跳出一個 [郵件帳號設定] 的視窗。在上面的 [伺服器] 上按一下,切換到 [伺服器] 那一頁。在 [外寄郵件] 裏 , [主機位置(V)] 中,要填上 SMTP 郵件伺服器的完整名稱,然後在下面 [協定(C)] 旁邊 [採用 TLS 安全性協定] 的地方打勾,按 [確定][確定] 。這樣就會用 SSL 收信了。

    + +

    憑證查核的部份, Opera 郵件使用 Opera 的憑證庫,妳只要把認證中心加進 Opera 就可以了。詳情請參考 Opera 的設定

    + + +

    設定其她不支援 SSL/TLS 的程式

    + +

    我的程式不支援 SSL/TLS ,怎麼辦?

    + +

    沒有關係。我們可以用 SSL 包裝程式,先和伺服器建立 SSL 連線,再將程式送的指令,透過這個 SSL 連線轉送給伺服器,並將伺服器在 SSL 連線中的回應,轉送回來。這樣一來,即使程式本身不懂 SSL ,也可以透過這個 SSL 連線,來加密收送的資料。以下,我們介紹 SSL 包裝程式。

    + + +

    Stunnel

    + +

    Stunnel 的網站在 http://www.stunnel.org/ ,可以從網站上下載。在 WINDOWS 下,是很簡單好用的 SSL 包裝程式。 WINDOWS 下的簡易使用方式說明如下:

    + +
      +
    • 從網站 http://www.stunnel.org/ 上下載 stunnel-x.xx.exelibssl32.dlllibeay32.dll
    • + +
    • libssl32.dlllibeay32.dll 存到 C:\WINDOWS\SYSTEM (WINDOWS 98/ME) 或 C:\WINNT\SYSTEM32 (WINDOWS NT/2000/XP) 下。
    • + +
    • C:\Program Files 下新增一個 Stunnel 目錄,把剛剛下載的 stunnel-x.xx.exe 存進這裏。
    • + +
    • C:\Program Files\Stunnel 中新增一個檔案 stunnel.conf ,內容舉例如下: + +
      +
      +client = yes
      +
      +[pop3s]
      +accept = localhost:50110
      +connect = my.mail.server:995
      +
      +[smtps]
      +accept = localhost:50025
      +connect = my.mail.server:465
      +
      +
      +
    • + +
    • 啟動 C:\Program Files\Stunnel\stunnel-x.xx.exe 。它會縮到桌面下方工具列的最右邊,變成一個小圖示。這時如果開啟 [MS-DOS 模式][命令提示字元] ,打: + +
      +
      +netstat -an
      +
      +
      + +會看到類似: + +
      +
      +TCP    127.0.0.1:50025        0.0.0.0:0              LISTENING
      +TCP    127.0.0.1:50110        0.0.0.0:0              LISTENING
      +
      +
      + +的兩行。點兩下 Stunnel 在工具列右邊的小圖示,會顯示 Stunnel 的使用記錄。
    • + +
    • 啟動程式,修改程式的設定,將原來 SMTP 連到 my.mail.server 連接埠 25 的地方,改連到 localhost 連接埠 50025 ;原來 POP3 連到 my.mail.server 連接埠 110 的地方,改連到 localhost 連接埠 50110 。
    • + +
    • 收、發信。
    • + +
    + +

    這樣應該就可以了,原本不會 SSL 的程式,現在可以透過 Stunnel 使用 SSL 連線了。

    + +

    這只是 Stunnel 的基本功能。 Stunnel 還有很多強大的功能,不但可以轉送 POP3SMTPIMAPNNTPLDAP … 等各種通訊協定,也可以將 SSL 連線,轉送給不會 SSL 的伺服器程式。這樣即使反過來,伺服器程式本身不會 SSL ,使用者也可以使用 SSL 加密連線。詳細的做法,請下載 Stunnel 的原始程式碼,參照內附的完整操作說明。

    + +

    不過 Stunnel 有一個很大的限制:因為 Stunnel 只負責先建立好 SSL 連線,並不瞭解通訊協定本身的指令語法,所以無法用 STARTTLS 指令建立 TLS 連線,只能用傳統的方式,一開始就建立全程的 SSL 連線。

    + + +

    觀念討論

    + +

    SSL/X.509 簡介

    + +
    + X.509 的金字塔制度
    + X.509 的金字塔制度
    +
    + +

    SSL 採用的是 X.509 ,由上而下金字塔式的憑證制度。

    + +

    在 X.509 中,每一個合格的憑證上,都會有一個簽名。最下層的憑證上,會有一個認證中心 (CA) 的簽名,表示這個認證中心 (CA) 檢查過,確認所有者資料無誤。中間的認證中心 (CA) 上,也會有管轄它的最高層認證中心 (Root CA) 的簽名,表示最高層認證中心授權給它,可以簽發別人的憑證。只有最高層認證中心上,因為它已經是最大,沒有再上層可以給它簽名了,所以只好自己簽自己,憑證上的簽名是自己簽的。

    + +

    程式自己會認得幾家可靠的認證中心 (CA) ,碰到 SSL 網站時,雖然不認得伺服器的憑證 (Certificate) ,但只要那個憑證上,有自己認得的認證中心 (CA) 簽名保證過,那個憑證就沒有問題。

    + +
    + 當程式碰到合格的 SSL 憑證
    + 當程式碰到合格的 SSL 憑證
    +
    + +

    但如果那個伺服器憑證上,沒有自己認得的認證中心 (CA) 簽名保證過,伺服器憑證就有可能有問題,會出現憑證無效的警告。

    + +
    + 當程式碰到有問題的 SSL 憑證
    + 當程式碰到有問題的 SSL 憑證
    +
    + + +

    憑證無效的警告

    + +

    本文第一步討論的是如何自製最高層認證中心 (Root CA) 。因為這是我們自己的認證中心,程式不認得,所以第二步簽發的憑證(Certificate) 上的簽名,程式自然也不認得,一定會出現憑證無效的警告。

    + +
    + 當程式碰到我們自製的認證中心
    + 當程式碰到我們自製的認證中心
    +
    + +

    若不想看到這個警告,就要先讓程式認得我們自己的認證中心 (CA) 。這時,第二步簽發的憑證 (Certificate) ,程式認得上面認證中心 (CA) 的簽名,就不會再出現憑證無效的警告。

    + +
    + 把我們自己的認證中心加上去
    + 把我們自己的認證中心加上去
    +
    + +

    詳細做法,請參考設定作業系統設定瀏覽器設定電子郵件程式各節。

    + +

    注意:這個方法,因為要在程式上,手動加入自己的認證中心 (CA) ,所以只有自己內部用的網站,使用者和程式數目都有限,可以自己一個一個去設認證中心 (CA) 的情況下,方才可行。若要用在公開的網站上,因為上網者來自各個不同的地方,妳也都不認識,沒有辦法在她們的電腦上,都加進自己的認證中心,就沒有辦法了。這一點受限於 X.509 的規定,愛莫能助。若真的很在意 SSL 憑證無效警告的問題,又需要在公開的網站使用 SSL ,請向各家簽證公司申請,年費大概幾萬元臺幣。

    + + +

    資料?什麼資料?

    + +

    等等,剛剛圖中的最後一個步驟,『沒問題,這是給妳的資料』。使用者還沒有填什麼資料啊!程式怎麼可以自己亂給對方資料呢?到底給了什麼資料?程式會不會自己給對方 E-mail 、信用卡號碼、身份證字號、密碼?

    + +

    程式傳給對方的,是接下來通信時,對稱式加解密用的 Key 。

    + +

    Public/Private Key 的不對稱加解密法 (Asymmetric Encryption) ,可以把 Public Key 告訴全世界, Private Key 自己秘密保管好,要傳資料給妳的話,只要用妳的 Public Key 加密,全世界就只有妳的 Private Key 才解得開。這種不對稱加解密法雖然很安全,但是加解密的速度很慢。反過來說,傳統的對稱式加解密法 (Symmetric Encryption) ,雖然加解密速度快多了,但是雙方都要握有同一個 Key ,把 Key 傳給對方途中,會有被攔截監聽的危險。

    + +

    SSL 採用兩階段式的作法:第一階段,先用 Public/Private Key 不對稱加解密法,傳給對方接下來傳真正資料時,對稱式加解密法要用的 Key 。第二階段,再用這個對稱式加解密的 Key ,來傳原本要傳的資料。真正傳資料時用的,其實是對稱式加解密法。這個傳資料用的對稱 Key 是用亂數取的,再用 Public/Private Key 法傳給對方,每一次連線時都不一樣。用這種兩階段式的作法, Key 是用不對稱加解密法傳給對方的,不用擔心中途被欄截,也能夠享受合理的加解密速度。

    + + +

    所以 SSL 就安全了囉?

    + +

    所以,只要對方 SSL 網站的憑證合格,上面有可靠的認證中心 (CA) 簽名,把我的信用卡資料傳過去就安全囉?

    + +

    不對。

    + +

    仔細看看前段 SSL/X.509 簡介,就會注意到, SSL/X.509 規定中,認證中心 (CA) 的簽名所保證的,只有這個 Public Key 憑證的確是屬於這家公司的這個伺服器而已。也就是說,它只保證妳送的信用卡號碼會確確實實交到這家公司的這個伺服器手中,不怕被任何人中途攔截監聽。但這並不代表這家公司是優良企業,收到妳的信用卡資料後,不會濫用,不會側錄下來,不會多刷兩筆,不會轉手把資料賣給別家公司,也不代表這家公司的伺服器安全防護做得很好,不會被人入侵,不會被人偷偷安裝側錄上網資料的程式

    + +

    沒錯, SSL 只能保證收到的 Public Key 憑證不是偽造的,但不能保證這家公司本身沒有問題。就算這家公司本身沒有問題,也不能保證這家公司內部會不會成為別人入侵、竊取資料的目標。

    + +

    那怎麼辦?怎麼樣才能算安全?才能放心把資料傳過去?

    + +

    就像在實體世界,跟不認識的商店買東西時,一定會保持戒心一樣,在網路上和任何網站交易,也一定要保持戒心,除了要考慮妳平常信不信任這個網站外,也要考慮妳傳過去的資料重不重要。舉例來說,留言板、討論區、網路投票等等,不是很私人的資料,可以放心傳過去沒問題;但如果是真實姓名、手機號碼、家裏電話、信用卡號碼, E-mail 等等,就只能傳給自己信任的網站了。

    + + +

    什麼是數位簽名?

    + +

    數位簽名是用 Private Key ,針對某一段資料,用 Digest Hash 演算法(如 SHA512 )做出來的一段 Digest 摘要碼。只要原來的資料有所不同,演算出來的 Digest 摘要碼就會跟著變動。用 Private Key 做出來的 Digest 摘要碼,可以用它的 Public Key 來檢查。只要用它的 Public Key ,檢查 Digest 摘要碼和那一段資料符不符合,就可以知道資料有沒有中途被竄改過,是不是這個 Private Key 當初簽的那一段資料。

    + +

    這個性質很像合約中,在整份合約上大大簽一個名一樣,人家認得妳簽名的筆跡,日後只要合約有任何塗改,一認便知。所以我們把它叫做數位簽名。

    + +

    因為數位簽名可以用來檢查資料有沒有被竄改,所以我們把它用在憑證上,認證中心檢查過 Public Key 的所有人,和 Key 上記載的所有人資料相符後,用認證中心自己的 Private Key ,在這些資料上面做個數位簽名,表示證明。日後收到這個 Public Key 的人,只要檢查上面認證中心的簽名,就可以知道這個 Key ,和它上面所載的所有人資料相不相符,是不是真的是這家公司的 Key 。也就知道,連上的這個伺服器,是不是真的是這家公司的伺服器了。

    + + +

    什麼是憑證?

    + +

    憑證的原文是 Certificate ,是附上所有人 (owner) 的資料(公司名稱、伺服器名稱、個人真實姓名、連絡 E-mail 、通訊地址等資料),後面加上數位簽名的 Public Key 。憑證上會附有幾個數位簽名,代表這些簽名的人,確認過這個 Public Key 的所有人,和憑證上所載的資料相符,沒有假造。

    + +

    在 X.509 中,最下層每一個合格的憑證 (Certificate) 上,會有一個認證中心 (CA) 的簽名,表示這個認證中心 (CA) 檢查過,確認憑證上的所有者資料無誤。當程式碰到沒見過的憑證時,只要檢查憑證上認證中心 (CA) 的簽名無誤,即代表這個認證中心 (CA) 查核過這個憑證 (Certificate) ,憑證上的資料無誤。

    + + +

    什麼是認證中心?

    + +

    認證中心的原文是 CA ,是 Certificate Authority 的縮寫,在微軟正體中文 WINDOWS 上譯成憑證授權憑證授權完全是逐字翻譯,意思不通,不用。認證中心是 X.509 的一環。認證中心也是一種憑證,上面附有認證中心本身的資料,但不是用來加解密,而是用來簽發憑證,證明憑證所有人和憑證上所載的資料無誤。請參見SSL/X.509 簡介的附圖。

    + +

    每一個合格的認證中心 (CA) (微軟正體中文 WINDOWS 上譯成中繼憑證授權,意思不通)上,會有一個管轄它的最高層認證中心 (Root CA) 的簽名,表示最高層認證中心授權給它,可以簽發別人的憑證。當程式碰到沒見過的憑證,憑證上簽名的認證中心 (CA) 也沒見過時,只要檢查認證中心上附的最高層認證中心 (Root CA) 的簽名無誤,即代表這個最高層認證中心 (Root CA) ,認為這個認證中心 (CA) 的憑證簽發過程很仔細,檢查資料很詳實,所以授權給它,准許它可以簽發憑證 (Certificate) 。所以這個認證中心 (CA) 簽發的憑證 (Certificate) ,憑證上的資料也沒有問題。

    + + +

    什麼是最高層認證中心?

    + +

    最高層認證中心的原文是 Root CA ,在微軟正體中文 WINDOWS 上譯成根目錄憑證授權根目錄只是照 Root 這個字逐字翻譯,意思不通,不用。最高層認證中心是 X.509 的一環。最高層認證中心也是認證中心 (CA) ,和一般認證中心的差別在於,它不會直接用來簽發憑證,而是授權給一些中間的認證中心,讓這些中間的認證中心來簽發憑證。請參見SSL/X.509 簡介的附圖。

    + +

    最高層認證中心,因為已經是最大,沒有再上層可以給它簽名了,所以憑證上的是自己的簽名,不是別人的簽名。因為最高層認證中心沒有再上面的簽名了,沒有人可以保證最高層認證中心本身有沒有問題,沒有辦法再往上檢查,所以程式只能事先就認得一些可靠的最高層認證中心,事先就知道一些可靠的最高層認證中心的 Public Key 。

    + +

    最高層認證中心只能由一些著名、可靠的公司來擔任,因為沒有辦法再往上查驗。如果程式被加進一些不可靠的最高層認證中心,接下來碰到它簽下來的憑證,都會有問題,整個程式的安全都會被破壞。所以在 X.509 下, SSL 程式一定要好好保護最高層認證中心,一定要再三確認,不可以隨便讓人手動加進最高層認證中心。

    + + +

    如何填寫憑證申請書

    + +

    如果妳不知道該如何填寫憑證申請書,請參考以下範例:

    + +
    +
    +You are about to be asked to enter information that will be incorporated
    +into your certificate request.
    +What you are about to enter is what is called a Distinguished Name or a DN.
    +There are quite a few fields but you can leave some blank
    +For some fields there will be a default value,
    +If you enter '.', the field will be left blank.
    +-----
    +Country Name (2 letter code) [AU]:TW
    +State or Province Name (full name) [Some-State]:Taiwan
    +Locality Name (eg, city) []:Taipei City
    +Organization Name (eg, company) [Internet Widgits Pty Ltd]:Tavern IMACAT's
    +Organizational Unit Name (eg, section) []:Owner
    +Common Name (eg, YOUR name) []:Tavern IMACAT's
    +Email Address []:imacat@mail.imacat.idv.tw
    +
    +Please enter the following 'extra' attributes
    +to be sent with your certificate request
    +A challenge password []:
    +An optional company name []:
    +
    +
    + +
      + +
    1. 所有資料都要填英文 (ASCII 字集) 。 X.509 憑證只接受英文 ASCII 字集的字。
    2. + +
    3. Country Name 一定要是大寫的雙字母國碼,臺灣是 TW ,臺灣以外的地方,請參考 ISO-3166 的標準雙字母國碼。
    4. + +
    5. State Name 是國名或省名,不可以填國碼。臺灣填 Taiwan 即可。
    6. + +
    7. Locality Name 是地名,填所在地縣市名即可。
    8. + +
    9. Organization Name 是組織單位名稱,填公司行號,或學校局處的名稱。
    10. + +
    11. Organizational Unit Name 是部門名稱,填公司部門名稱,或學校局處的單位名稱。
    12. + +
    13. Common Name 是憑證的名稱。若是最上層憑證機構,請填上前面填的組織單位名稱,後面可以加上 RSA/4096 ,以便日後辨認憑證的性質。若是伺服器憑證,請填上伺服器的全名 (www.abc.com) 。若是 E-mail 憑證,請填上妳的 E-mail
    14. + +
    15. E-mail Address 是申請單位的連絡信箱,請填上妳的聯絡用 E-mail
    16. + +
    17. A challenge password 是申請書的密碼。不過申請書不用設密碼,所以不填。
    18. + +
    19. An optional company name 是憑證代辦公司的名稱,也不用填。
    20. + +
    + + +

    X.509 憑證制度的檢討

    + +

    X.509 憑證制度,是靠事先認得一些可靠的最高層認證中心,再一層一層簽發下來的金字塔型結構。這樣的制度,很像信用卡制度或身份證制度:

    + +
    + X.509 制度
    + X.509 制度
    +
    + +
    + 信用卡制度
    + 信用卡制度
    +
    + +
    + 身份證制度
    + 身份證制度
    +
    + +

    這樣的金字塔結構,有好有壞。

    + +

    好處在於,在無限寬廣的網際網路上,我們根本不知道會碰到什麼樣的網站,所以根本也無從查認每一個收到的 Public Key 有沒有問題,是不是真的是這家公司的網站,我是不是真的是跟這家公司打交道。在 X.509 下,只要我們預先認得幾家可靠的最高層認證中心就好了。碰到不認識的 Public Key 時,只要一層一層往上追溯,如果最後追溯得到一個我們認得的可靠的最高層認證中心,那這個 Public Key 就沒有問題了。這樣的做法,簡化了無限寬廣的網際網路上,確認彼此身份的困難性。

    + +

    缺點則在於,因為 X.509 是金字塔結構,最高層認證中心 (Root CA) 手中握有整個網際網路信任關係的關鍵,權力太大了。龐大的權力,伴隨著的是龐大的利益。曾經跟認證中心打過交道(如 VeriSign 、 HiTrust 網際威信、Taica 臺灣網路認證等)的人都知道,申請簽發 SSL 憑證非常貴,一年年費要好幾萬,普通人或中小企業,需要SSL 網站加密的時候,根本就負擔不起。而因為金字塔頂層的最高層認證中心,是壟斷事業,數目很少,不會有什麼競爭,所以大型的最高層認證中心姿態都很高,年費一直降不下來。但若不靠這些最高層認證中心,自己來發證,程式沒有內建我們自製的認證中心,連到 SSL 站上,一定會出現警告。小組織裏內部自用的 SSL 伺服器還沒有問題,我們可以自己加入自製的認證中心,但大型公開的伺服器(像公司網站)上,不可能要不認識的上網者信任我們的認證中心,把我們的認證中心加進去,這時候資料的安全,就會亮起紅燈了。到頭來,我們還是得回過頭去,求這些大型的認證中心,乖乖繳一年好幾萬的年費。

    + +

    這真的沒有辦法嗎?

    + +

    答案是否定的。即使是 X.509 的金字塔結構,至少就有兩條路:第一條路是像信用卡制度一樣。信用卡制度也是金字塔結構,頂層的信用卡集團也是壟斷事業,數目很少,可是信用卡的年費只有幾千塊錢。有競爭就會降價,但沒有競爭,並不代表價格一定降不下來。價格其實還是卡在認證中心如何定價,信用卡制度就是一例。第二是像身份證一樣,由政府出面經營,以政府的信用擔保、審核,把它變成免費的公用事業,讓大家有錢沒錢,都可以來用安全的網站交易。

    + +

    不過,仔細想想,我們是不是一定要用 X.509 這種金字塔制度,任這些頂層的認證中心宰割,予取予求呢?

    + +

    其實憑證有好幾種。有一種叫做 PGP ,是採用信任網 (Web of Trust) 的模式,建立信任關係。 PGP 的信任網就像人際關係網一樣:我認得妳,妳認得她,所以我只要請妳來認她就好了。

    + +
    + PGP 的信任網
    + PGP 的信任網
    +
    + +

    在 PGP 信任網模式下,我們不需要一個最高層認證中心,給每個人核發憑證,才能取得 Public Key 的安全性。我們只要信任我們自己的 Public Key 憑證,用自己的憑證去簽認識的 Public Key 的憑證,別人也用他們自己的憑證,去簽他們認識的人的憑證,往外一層一層擴散出去,互相信任。碰到不認得的憑證時,只要能夠從他憑證上的簽名中,回溯到可信任的人的憑證身上,就可以了。其實事情本來就是這樣。我們為什麼要向別人繳一年好幾萬的年費,還要別人簽名,才能信任自己的憑證呢?

    + +

    不過,不合理的是, SSL 規定,要用 X.509 。

    + + +

    其她 SSL/X.509 憑證的做法

    + +

    在本文中,我們做了兩個憑證:一個是 Root CA 最上層認證中心,一個是用這個最高層認證中心簽發的憑證。

    + +

    其實完整的話,應該要做三層(參考:SSL/X.509 簡介中的附圖):最高層認證中心 (Root CA) ,中間的認證中心 (CA) ,最後才簽發下面的憑證。可是我不會做中間的認證中心, ^^; 完整的三層挺複雜的。而且,最高層認證中心 (Root CA) 只是不會用來直接簽憑證,而不是不能用來直接簽憑證,最高層認證中心(Root CA) 簽的憑證,一樣有效。更何況,我們通常都只有幾台伺服器,只需要幾個憑證就好,不需要授權好幾個中間的認證中心,來讓它們簽憑證。所以我們就省略了中間的認證中心,直接用最高層認證中心 (Root CA) 來簽發憑證 (Certificate) 。

    + +

    其實還有兩個不那麼麻煩的做法。 Apache mod_ssl 有隨附一個印度蛇油公司 (Snake Oil) 的最高層認證中心 (Root CA) ,內有印度蛇油 (Snake Oil CA) 的 Private Key ,可以直接用印度蛇油認證中心 (Snake Oil CA) 的名義來簽發憑證。只要在編譯 Apache 時, make 以後打 make certificate ,就會自動用印度蛇油認證中心,簽發 Apache 網站所需的伺服器憑證了。可是,基於安全上的理由,妳只能夠用這張簽出來的網站憑證,絕對不可以把印度蛇油認證中心 (Snake Oil CA) ,加到程式認得的認證中心中。因為印度蛇油的 Private Key 是隨著 Apache mod_ssl 公開散佈的,任何人只要下載 Apache mod_ssl ,裏面就會有印度蛇油的 Private Key ,就可以用印度蛇油的名義來簽憑證,自稱為某某公司。印度蛇油的可靠度是零,絕對不要加進程式中。(所以才叫做印度蛇油 Snake Oil ,騙人的。)

    + +

    另一個方法,是只做一個最高層認證中心 (Root CA) ,直接用這個最高層認證中心,來當伺服器的憑證。因為最高層認證中心 (Root CA) 本身,也是一個憑證,所以當然也可以用,一樣有效。這時候,最高層認證中心的所有人名稱,就要用伺服器的名稱 (www.abc.com) ,而不是單位的名稱 (ABC Corporation.) 。這個方法,適合只有一個伺服器,只需要一個憑證,而且不在乎憑證名稱的人。用 Windows NT/2000 的 Certificate Server 憑證伺服器,可以做出這種憑證。但如果有好幾臺伺服器,每個憑證都要分別去加到每臺電腦上,這個方法就不大方便了。

    + + +

    註釋

    + +
      + +
    1. FHS 是指 Filesystem Hierarchy Standard 檔案系統階層標準,是一個 Unix 下,目錄及檔案存放位置的標準規定,以方便系統管理員管理,方便不同程式間互相搭配整合。目前大多數 Linux 版本(如 DebianRed HatMandrake 等)都已支援 FHS 。更進一步的資料請參考 FHS 的網站 http://www.pathname.com/fhs/(回正文)
    2. + +
    3. Opera 截至目前為止 (6.05) ,只支援 RSA ,不支援 DSA(回正文)
    4. + +
    5. 在 Mandrake 下裝 RPM 時,請改用: +
      +
      +mv /usr/lib/ssl/openssl.cnf /etc/ssl
      +ln -s /etc/ssl/openssl.cnf /usr/lib/ssl/openssl.cnf
      +
      +
      +(回正文)
    6. + +
    7. 這是 bash 或 zsh 的指令。 csh 或 tcsh 下,請改用: +
      +
      +setenv OPENSSL_CONF "/etc/ssl/openssl.cnf"
      +
      +
      +(回正文)
    8. + +
    9. 這樣以後登入的時候,都能夠自動設定 OPENSSL_CONF 。這是用 bash 登入的情形,若用 csh 或 tcsh 登入,請改用: +
      +
      +echo "# OpenSSL 設定檔的位置" >> ~/.cshrc
      +echo "setenv OPENSSL_CONF \"/etc/ssl/openssl.cnf\"" >> ~/.cshrc
      +
      +
      +若用 zsh 登入,請改用: +
      +
      +echo "# OpenSSL 設定檔的位置" >> ~/.zshenv
      +echo "export OPENSSL_CONF=\"/etc/ssl/openssl.cnf\"" >> ~/.zshenv
      +
      +
      +(回正文)
    10. + +
    11. (感謝網中人 (netman) 提供)若妳安裝的是 Red Hat 的 openssl RPM ,在這裏會出一點問題。 Red Hat 的 openssl 做 rand 指令,配合 -out 參數時,參數解析會出錯,無法執行。目前我還沒有看到網路上有人提過這件事。解決方法之一,是自己編譯、安裝 OpenSSL 。這其實很簡單。在 Linux 上,步驟如下: +
      +
      +./config shared --prefix=/usr --openssldir=/usr/share/ssl
      +make
      +make install
      +
      +
      +在其她作業系統 (*BSD/UNIX) 上,步驟如下: +
      +
      +./config --prefix=/usr --openssldir=/usr/share/ssl
      +make
      +make install
      +
      +
      +如果不想自己編譯、安裝 OpenSSL ,另一個解決方法,由網中人提供,則是避開 -out 參數,改用輸出重導向: +
      +
      +openssl rand 1024 > /etc/ssl/private/.rand
      +
      +
      +Mandrake 和 Debian 的 openssl 套件沒有這個問題。 +(回正文)
    12. + +
    13. 若要做成 DSA Key,請改用: +
      +
      +# 製作 DSA 參數檔
      +openssl dsaparam -out /tmp/dsaparam 4096
      +
      +# 製作 DSA Private Key
      +openssl gendsa -out /etc/ssl/private/myrootca.key.pem /tmp/dsaparam
      +chmod og-rwx /etc/ssl/private/myrootca.key.pem
      +
      +# 刪除 DSA 參數檔
      +rm -f /tmp/dsaparam
      +
      +
      +因為 DSA 取亂數參數要取很久,所以 OpenSSL 不直接做 DSA Key ,而把取出來的 DSA 參數存檔,再用參數檔來做 DSA Key ,做下一組 Key 時就可以用同一個參數檔,以節省時間。不過這裏我們只做一組 Key ,所以參數檔用過就可以刪了。 (回正文)
    14. + +
    15. 若妳的最高層認證中心,放在另一臺伺服器上,請將 /tmp/myhost.req.pem 複製到那臺伺服器上的 /tmp/myhost.req.pem ,登入那臺伺服器上,再繼續進行。 (回正文:root/使用者)
    16. + +
    17. 如果妳原來是在另一臺伺服器做這組 Public/Private Key 的,把 /etc/ssl/certs/myhost.crt.pem 複製到原來的伺服器上的 /etc/ssl/certs/myhost.crt.pem ,就可以用了。記得要回到原來的伺服器上,把原來伺服器上的憑證申請書 /tmp/myhost.req.pem 也刪掉。 +
      +
      +rm -f /tmp/myhost.req.pem
      +
      +
      +(回正文)
    18. + +
    19. 在 Mandrake 下裝 RPM 時,請改用: +
      +
      +cp /usr/lib/ssl/openssl.cnf ~/etc/ssl
      +
      +
      +(回正文)
    20. + +
    21. 這是 bash 和 zsh 的指令。 csh 或 tcsh 下,請改用: +
      +
      +setenv OPENSSL_CONF "$HOME/etc/ssl/openssl.cnf"
      +
      +
      +(回正文)
    22. + +
    23. 這樣以後登入的時候,都能夠自動設定 OPENSSL_CONF 。這是用 bash 登入的情形,若用 csh 或 tcsh 登入,請改用: +
      +
      +echo "# OpenSSL 設定檔的位置" >> ~/.cshrc
      +echo "setenv OPENSSL_CONF \"$HOME/etc/ssl/openssl.cnf\"" >> ~/.cshrc
      +
      +
      +若用 zsh 登入,請改用: +
      +
      +echo "# OpenSSL 設定檔的位置" >> ~/.zshenv
      +echo "export OPENSSL_CONF=\"$HOME/etc/ssl/openssl.cnf\"" >> ~/.zshenv
      +
      +
      +(回正文)
    24. + +
    25. (感謝網中人 (netman) 提供)若妳安裝的是 Red Hat 的 openssl RPM ,在這裏會出一點問題。 Red Hat 的 openssl 做rand 指令,配合 -out 參數時,參數解析會出錯,無法執行。目前我還沒有看到網路上有人提過這件事。解決方法之一,是自己編譯、安裝 OpenSSL 。這其實很簡單。在 Linux 上,步驟如下: +
      +
      +./config shared --prefix=/usr --openssldir=/usr/share/ssl
      +make
      +make install
      +
      +
      +在其她作業系統 (*BSD/UNIX) 上,步驟如下: +
      +
      +./config --prefix=/usr --openssldir=/usr/share/ssl
      +make
      +make install
      +
      +
      +如果不想自己編譯、安裝 OpenSSL ,另一個解決方法,由網中人提供,則是避開 -out 參數,改用輸出重導向: + +
      +
      +openssl rand 1024 > ~/etc/ssl/private/.rand
      +
      +
      +Mandrake 和 Debian 的 openssl 套件沒有這個問題。 (回正文)
    26. + +
    27. 若要做成 DSA Key,請改用: +
      +
      +# 製作 DSA 參數檔
      +openssl dsaparam -out ~/tmp/dsaparam 4096
      +
      +# 製作 DSA Private Key
      +openssl gendsa -out ~/etc/ssl/private/myrootca.key.pem ~/tmp/dsaparam
      +chmod og-rwx ~/etc/ssl/private/myrootca.key.pem
      +
      +# 刪除 DSA 參數檔
      +rm -f ~/tmp/dsaparam
      +
      +
      +因為 DSA 取亂數參數要取很久,所以 OpenSSL 不直接做 DSA Key ,而把取出來的 DSA 參數存檔,再用參數檔來做 DSA Key ,做下一組 Key 時就可以用同一個參數檔,以節省時間。不過這裏我們只做一組 Key ,所以參數檔用過就可以刪了。 (回正文)
    28. + +
    29. 若妳的最高層認證中心,是由 root 管理,請接到 root 的第三步驟(回正文)
    30. + +
    31. 如果妳原來是在另一臺伺服器做這組 Public/Private Key 的,把 ~/etc/ssl/certs/myhost.crt.pem 複製到原來的伺服器上的 ~/etc/ssl/certs/myhost.crt.pem,就可以用了。記得要回到原來的伺服器上,把原來伺服器上的憑證申請書 /tmp/myhost.req.pem 也刪掉。 +
      +
      +rm -f /tmp/myhost.req.pem
      +
      +
      +(回正文)
    32. + +
    33. 不過微軟的 Outlook Express 很笨,不支援相容性高的TLS 新標準,只能跑舊式的 SMTPS 。若妳要設定給 Outlook Express 用 SSL 寄信,就一定要在編譯時加上 SMTPS 的支援。 (回正文)
    34. + +
    35. 其實妳會看到三個連接埠: SMTP(25) 、SMTPS(465) 和 submission(587) 。 submission(587) 是給郵件程式寄信專用的,和 SMTP(25) 一樣可以做 TLS 。 submission(587) 不需特別設定,為簡化討論起見,省略之。 (回正文)
    36. + +
    37. 若妳在意系統安全,不想多開不必要的帳號的話,這裏的 smmsp 可以改成 mail ,用 mail 帳號。我強烈建議這個做法。開太多不必要的帳號,增加不必要的系統權限,也是安全漏洞的來源之一。本來就沒有什麼程式在用 mail 帳號, mail 是閒置的系統帳號之一,不如好好利用這個現有的系統資源。更何況, Sendmail 建議的 smmsp 群組的 GID 25 ,和 Debian floppy 群組的 GID 衝突。這是系統安全的題外話,和 SSL 無關。 (回正文)
    38. + +
    39. 這裏 MS-WINDOWS 把最高層認證中心 (Root CA) 譯成根目錄憑證授權,把認證中心 (CA) 譯成憑證授權中繼憑證授權,都是逐字翻譯的結果,完全不知所云,翻譯之大忌,戒之。 (回正文)
    40. + +
    41. 到 Mozilla 1.1 版為止, Mozilla 把憑證 (Certificate) 譯成認證,把認證中心 (CA) 譯成查證,也是有問題的譯法,且不符目前的通譯。我已跟 Mozilla 中文化的作者林弘德反映過這個問題,他承諾於 1.0.1 版後修正。 (回正文)
    42. + +
    43. 實際儲存的地方,在 Mozilla 使用者設定檔目錄下的 cert7.db ,格式是 Berkeley DB 。 (回正文)
    44. + +
    45. 我還沒找到直接開啟 [Certificate Infomation Manager] 的方法。如果有人知道,煩請告訴我。 (回正文)
    46. + +
    47. 實際儲存的地方,公用的認證中心在 Eudora 程式目錄下的 rootcerts.p7b ,個人的認證中心在 Eudora 信箱目錄下的 usercerts.p7b ,格式是標準憑證格式 DER 的 PKCS#7 檔。 (回正文)
    48. + +
    49. 要先失敗一次,才能去設定,其實挺蠢的。另一個比較不那麼愚蠢的方法,就是直接去改 usercerts.p7busercerts.p7b 是標準憑證格式 PKCS#7 檔,可以用 OpenSSL 處理: +
      +
      +# 備份原檔案
      +mv usercerts.p7b usercerts-orig.p7b
      +
      +# 把 DER 的 PKCS#7 檔,拆成一張一張的 PEM 憑證清單
      +openssl pkcs7 -print_certs -inform der \
      + -in usercerts-orig.p7b -out certslist.pem
      +
      +# 把我們的認證中心加進來
      +cat /etc/ssl/certs/myrootca.crt.pem >> certslist.pem
      +
      +# 將一張一張的 PEM 憑證清單,組合成 PEM 的 PKCS#7 檔
      +openssl crl2pkcs7 -nocrl -certfile certslist.pem > usercerts.pem
      +
      +# 將 PEM 轉為 DER
      +openssl pkcs7 -in usercerts.pem -outform der -out usercerts.p7b
      +
      +# 刪掉多餘的檔案
      +rm -f certslist.pem usercerts.pem
      +
      +
      +這樣就把我們的認證中心加進 usercerts.p7b 了。不要直接去改公用的認證中心 rootcerts.p7b ,這個檔案留給 Eudora 自己去維護。 (回正文)
    50. + +
    51. 詳情請參見這篇 Becky! 論壇上關於 SSL 的討論(回正文)
    52. + +
    + + +

    參考資料

    + +
      +
    1. SSL: Netscape Security Documentation, Introduction to SSL, How SSL Works, SSL Protocol v3.0
    2. + +
    3. X.509: RFC 3280, RFC 2459 (舊版)
    4. + +
    5. OpenSSL: OpenSSL, openssl(1), x509(1), req(1), ca(1)
    6. + +
    7. PGP: GnuPG, PGPi, PGP, Introduction to Cryptography ( PDF 檔, PGP 的原作者 Phil Zimmermann 作), Phil Zimmermann
    8. + +
    9. FHS
    10. + +
    11. TLS 1.0: RFC 2246
    12. + +
    13. Apache: http://www.apache.org/, Apache-SSL, mod_ssl
    14. + +
    15. Qpopper
    16. + +
    17. Sendmail
    18. + +
    19. Stunnel
    20. + +
    + + +

    後記

    + +
    2002-11-15
    + +

    小幅更新:

    + +
      +
    • 加上 Sendmail SMTPS(465) 功能的設定。這是 Sendmail 未公開的功能,之前在 Sendmail 文件中沒有發現。我是在設定 Outlook Express 時,發現沒辦法按自己寫的方式用 SSL 寄信,上 google 搜尋,才發現 Sendmail 的 SMTPS 支援的。不好意思,寫出無法執行的東西,自己沒有全部檢查確認過,對大家非常抱歉。 ^^;
    • +
    • 加上 Stunnel SSL 包裝程式。這是可以讓 Becky! 等不支援 SSL 的程式,也能使用 SSL 連線的方法。
    • +
    • 加註不新增 smmsp 帳號的方法。
    • +
    • 幾個之前編排文字時造成的小錯誤。
    • +
    + + +
    2002-09-15
    + +

    本文參考的資料有限。 SSL 和 X.509 我還沒有完整看過。而目前網路上,即使是英文資料也很少。一開始,我只能從一堆零零散散的網路討論,和 OpenSSL 的文件中,自己拼湊出 SSL 憑證的做法。因為網路上找不到比較完整的 SSL 憑證製作教學,所以我想把它寫出來,開個先鋒。我沒有看完 SSL/X.509 ,只是儘量讓我做出來的憑證,在我所知道的 SSL 程式上,都跑得動。做出來憑證不一定完全符合 SSL/X.509 ,也不一定在所有的SSL程式上都能用。

    + +

    然而,也不是每一個符合 SSL/X.509 的憑證,就能在所有的SSL 程式上用。不見得每個 SSL 程式都完整支援SSL/X.509 ,就像 Opera 目前還不支援 DSA 一樣。

    + +

    本文第一版是 2002-01-09 ~ 2002-01-13 間所寫。第一版寫作的目的,是當時為了想自己做 Root CA (這樣憑證看起來比較好看),想辦法在網路上零碎的討論中,拼湊出 Root CA 的做法。整個做法有點複雜,怕自己下次要發憑證時忘記,所以寫下來,順便寫成 HOWTO 教學的形式,以把這個知識分享給大家。因為只是為了快點記下繁複的做法,寫得很倉促,交代也不清不楚。

    + +

    這是第二版,是 2002-09-04 ~ 2002-09-15 間改寫的,當初改寫的目的,是這兩三個月來,收到好幾封信詢問這篇文章,覺得自己這篇文章,交代得不清不楚,所以重新改寫。因此原先改寫的時候,著重在 WHAT 和 WHY 的說明,把 SSL/X.509 架構,交代得比較嚴謹,也把腦子裏想的幾張流程圖,都給畫出來。不過到後來, HOW 的部份,也大幅度地改寫,重新編排流程,實驗各種情況,更正幾個錯誤,改善原來的設定,統整辭彙的翻譯,加上流程的說明。原文 2,931 字,改寫後 18,421 字, ^^; 改寫的幅度很大。

    + +

    感謝 study-area網中人 (netman) 協助校正好幾個錯誤、疏漏之處。

    + +

    希望改寫後,能讓這篇文章更好,更嚴謹,也更容易入手。

    + +
    依瑪貓,初稿 2002-01-09 ,上次更新日期 2006-04-06
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/untxtsvc.html.en.html b/htdocs/imacat/tech/untxtsvc.html.en.html new file mode 120000 index 0000000..7e273df --- /dev/null +++ b/htdocs/imacat/tech/untxtsvc.html.en.html @@ -0,0 +1 @@ +untxtsvc.html.en.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/untxtsvc.html.en.xhtml b/htdocs/imacat/tech/untxtsvc.html.en.xhtml new file mode 100644 index 0000000..dec6fc4 --- /dev/null +++ b/htdocs/imacat/tech/untxtsvc.html.en.xhtml @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + +How to Remove Microsoft Office’s Text Service? + + + + + + + +
    + +
    + + +

    How to Remove Microsoft Office’s Text Service?

    + +

    To prevent text service from running, follow these steps.

    + +
      +
    1. Uninstall Alternative User Input

      +

      To uninstall the alternative user input feature, set the installation state +to Not Available in Office XP Setup.

      +
        +
      1. Quit all Office programs.
      2. +
      3. Click Start, point to Settings, and then click +Control Panel.
      4. +
      5. In Control Panel, double-click Add/Remove Programs.
      6. +
      7. In the Currently installed programs list, click to select +Microsoft Office XP product. Click Change.
      8. +
      9. In the Maintenance Mode Options dialog box, select Add +or Remove Features, and then click Next. This displays the +Choose installation options for all Office applications and tools +dialog box.
      10. +
      11. Click the plus sign (+) next to Office Shared Features to +expand it.
      12. +
      13. Click the icon next to Alternative User Input, and then select +Not Available.
      14. +
      15. Click Update.
      16. +
      +
    2. + +
    3. Remove Alternative User Input Services from Text Services

      +
        +
      1. Click Start, point to Settings, and then click +Control Panel.
      2. +
      3. In the Control Panel, double-click Text Services.
      4. +
      5. Under Installed Services, select each input item that is +listed, and then click Remove to remove the item. All items must +be removed, one by one, except the following input service: +English (United States)- default Keyboard United States 101
      6. +
      +
    4. + +
    5. Run regsvr32 /U on the msimtf.dll and msctf.dll Files

      +
        +
      1. Click Start and then click Run.
      2. +
      3. In the Run dialog box, type the following command: +
        +regsvr32.exe /U msimtf.dll
        +
      4. +
      5. Click OK.
      6. +
      7. Repeat steps 1 through 3 for the msctf.dll file.
      8. +
      +
    6. +
    + +

    For additional information about how to remove ctfmon.exe, refer to the +article number below to view the article in the Microsoft Knowledge Base:

    +

    Q282599 OFFXP: What Is CTFMON and What Does It Do?

    + + +
    by imacat, first written 2003-06-20, last updated 2006-04-06
    +Source
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/untxtsvc.html.zh-cn.html b/htdocs/imacat/tech/untxtsvc.html.zh-cn.html new file mode 120000 index 0000000..60a656f --- /dev/null +++ b/htdocs/imacat/tech/untxtsvc.html.zh-cn.html @@ -0,0 +1 @@ +untxtsvc.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/untxtsvc.html.zh-cn.xhtml b/htdocs/imacat/tech/untxtsvc.html.zh-cn.xhtml new file mode 100644 index 0000000..6507bbe --- /dev/null +++ b/htdocs/imacat/tech/untxtsvc.html.zh-cn.xhtml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + +如何移除 Office 的文字服务? + + + + + + + +
    + +
    + + +

    如何移除 Office 的文字服务?

    + +

    要移除/关闭 Microsoft Office 中的文字服务,请按以下步骤:

    + +
      +
    1. 解除安装替代使用者输入

      +

      从系统中解除安装:

      +
        +
      1. 关闭所有 Office 程式。
      2. +
      3. 点选开始设定控制台
      4. +
      5. 在控制台里,按两下新增/移除程式
      6. +
      7. 在目前安装的程式中,选择 Microsoft Office XP 产品。点选变更
      8. +
      9. 在程式安装对话方块中,选择新增或移除功能,然后选下一步。这时会显示要安装的功能对话方块。
      10. +
      11. 按一下 Office 共用的功能旁边的加号。
      12. +
      13. 替代使用者输入的图示,选择无法使用
      14. +
      15. 更新
      16. +
      +
    2. + +
    3. 从文字服务里,移除使用者输入法:

      +
        +
      1. 点选开始设定控制台
      2. +
      3. 在控制台里,按两下文字服务
      4. +
      5. 在已安装服务清单中,除英语(美国)以外,一个个移除其余的输入法。
      6. +
      +
    4. + +
    5. 执行 regsvr32 /U 移除 msimtf.dll 和 msctf.dll 档案。

      +
        +
      1. 点选开始执行
      2. +
      3. 在执行对话方块,键入以下指令: +
        +regsvr32.exe /U msimtf.dll
        +
      4. +
      5. 确定
      6. +
      7. 对 msctf.dll 档案,重覆上述一到三步骤。
      8. +
      +
    6. +
    + +

    关闭文字服务后,就可以像以前一样,新增其他输入法了。想了解更多关於文字服务档 cftmon.exe 的资讯,请查阅以下说明:

    +

    Q282599 OFFXP: What Is CTFMON and What Does It Do?

    + + +
    正体中文编译:依玛猫,初稿 2003-06-20 ,上次更新日期 2006-04-06
    +原文出处
    + +
    + +
    + + + + diff --git a/htdocs/imacat/tech/untxtsvc.html.zh-tw.html b/htdocs/imacat/tech/untxtsvc.html.zh-tw.html new file mode 120000 index 0000000..a46fa0d --- /dev/null +++ b/htdocs/imacat/tech/untxtsvc.html.zh-tw.html @@ -0,0 +1 @@ +untxtsvc.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/tech/untxtsvc.html.zh-tw.xhtml b/htdocs/imacat/tech/untxtsvc.html.zh-tw.xhtml new file mode 100644 index 0000000..4d6b865 --- /dev/null +++ b/htdocs/imacat/tech/untxtsvc.html.zh-tw.xhtml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + +如何移除 Office 的文字服務? + + + + + + + +
    + +
    + + +

    如何移除 Office 的文字服務?

    + +

    要移除/關閉 Microsoft Office 中的文字服務,請按以下步驟:

    + +
      +
    1. 解除安裝替代使用者輸入

      +

      從系統中解除安裝:

      +
        +
      1. 關閉所有 Office 程式。
      2. +
      3. 點選開始設定控制台
      4. +
      5. 在控制台裡,按兩下新增/移除程式
      6. +
      7. 在目前安裝的程式中,選擇 Microsoft Office XP 產品。點選變更
      8. +
      9. 在程式安裝對話方塊中,選擇新增或移除功能,然後選下一步。這時會顯示要安裝的功能對話方塊。
      10. +
      11. 按一下 Office 共用的功能旁邊的加號。
      12. +
      13. 替代使用者輸入的圖示,選擇無法使用
      14. +
      15. 更新
      16. +
      +
    2. + +
    3. 從文字服務裡,移除使用者輸入法:

      +
        +
      1. 點選開始設定控制台
      2. +
      3. 在控制台裡,按兩下文字服務
      4. +
      5. 在已安裝服務清單中,除英語(美國)以外,一個個移除其餘的輸入法。
      6. +
      +
    4. + +
    5. 執行 regsvr32 /U 移除 msimtf.dll 和 msctf.dll 檔案。

      +
        +
      1. 點選開始執行
      2. +
      3. 在執行對話方塊,鍵入以下指令: +
        +regsvr32.exe /U msimtf.dll
        +
      4. +
      5. 確定
      6. +
      7. 對 msctf.dll 檔案,重覆上述一到三步驟。
      8. +
      +
    6. +
    + +

    關閉文字服務後,就可以像以前一樣,新增其他輸入法了。想了解更多關於文字服務檔 cftmon.exe 的資訊,請查閱以下說明:

    +

    Q282599 OFFXP: What Is CTFMON and What Does It Do?

    + + +
    正體中文編譯:依瑪貓,初稿 2003-06-20 ,上次更新日期 2006-04-06
    +原文出處
    + +
    + +
    + + + + diff --git a/htdocs/imacat/writings-en/19940512.html.html b/htdocs/imacat/writings-en/19940512.html.html new file mode 120000 index 0000000..7f48689 --- /dev/null +++ b/htdocs/imacat/writings-en/19940512.html.html @@ -0,0 +1 @@ +19940512.html.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-en/19940512.html.xhtml b/htdocs/imacat/writings-en/19940512.html.xhtml new file mode 100644 index 0000000..6b072e1 --- /dev/null +++ b/htdocs/imacat/writings-en/19940512.html.xhtml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + +The Drunk + + + + + + + +
    + +
    + + +

    The Drunk

    + +
    +

    Note.

    +

    I’m all exhauted now. This novelette has exhausted the last of my energy. I don’t know what to say here actually.

    +

    It’s my first attempt of the novelette. I don’t know how it works, but the story should be great, I think.

    +

    The idea is invoked from a criticism of F. M. Dostoevsky. As discussing about Crime and Punishment(1866), it says that the protagonist had killed himself to the eternal death before he killed that old woman. Well, That’s where the whole story is from, though I’ve not read Crime and Punishment yet.

    +

    It’s time to rest. I hope you’ll enjoy it.

    +
    + +

    Last Friday I went to the pub as usual. I was suffering from the lack of inspirations. I ordered a doubled whisky and sat at the bar.

    +

    So, are you drinking alone?

    +

    I turned around. There was a man standing there. He was of median age, some fat, in a smartly but wrinkled deep blue suit. Mostly speaking, he was clean. Obvious he was a little loaded, and he was accosting me. But I’m not interested in accosting with a man.

    +

    They said you’re a writer. I’ve got a story here. Are you interested?

    +

    I turned to the bartender. He tried hard not to notice my suspicion. I turned back to the man. He had already sat on the chair next to me without my permission.

    +

    What makes you think I’ll be interested?

    +

    You’ll certainly be. It’s the most interesting story you’ve ever heard before, and you’ll never know another one.

    +

    Oh yes? I was enraged by his insolent attitude. What makes you think I’ll need it?

    +

    You surely do. People always drink alone when they are in lack of inspirations.

    +

    I was surprised. This did interest me. I looked at him for a while.

    +

    What would it cost?

    +

    Nothing. I just have got a story and want someone to write it down.

    +

    I considered for a while. At least I had nothing to lose. Finally I accepted his suggestion.

    +

    So, what is your story?

    +

    So you finally accept my suggestion. He took a sip.

    +

    I was married with a beautiful young woman who had a beautiful black long hair. She was so attractive that no one would escape from her magical charm. Oh yes, she was beautiful. And she was tender, too. She was so tender that she could cure any hurt of a brave man. Her skin was softly white, so soft that you’ll never want to get off while you are in her arms. Her figure, her smile, that figure that would capture any dynamic young heart. Oh, that was her.

    +

    In fact, I was one of them who were charmed by her attraction. I fell in love when I first saw her. You can’t believe how I was struck by the figure of her standing behind the setting sun. She was just like an angel fallen from the heaven above. Yes, she was an angel for me. I believed it at the first sight I saw her.

    +

    How lucky I was! After a hard process of courting she finally nodded her lovely head. We finally got married. We’ve had a such good time. People envied us. Everyday I worked hard for us outside, thinking that she is waiting for me at home. When I got home in the evening, she stood there, at the front door, smiling at me. At the dinning table I’d tell her the whole story I’ve been all day long, and she’d be very concentrated to it. Then she would add another bowl for me, telling me the jokes she heard from the market at day. We talked and laughed, talked and laughed, talked and laughed, till we forgot the time and the thing that we were still dinning. We often had dinner from six to eleven, but we didn’t care.

    +

    But things changed. She did not stand at the front door anymore. She laughed to me fewer and fewer times. She was so attractive, you know. Although we’d married, there were people still courting her all the time. One day I found her dating with a young man on the street. I was so jealous! How could she do this to me? That evening the first thing I did when I got home was to question her. We argued and argued. I must have lost my mind then. Finally I grabbed a table knife and plugged it into her chest. She screamed. Her blood was bursting out from her heart. After several minutes, she died.

    +

    After a while of silence, I said:

    +

    So, is that all?

    +

    Yes, that’s all. I killed her.

    +

    When did it happen?

    +

    Not long ago. Just about last Thursday.

    +

    You are not a good lier, you know, I smiled. You have bad skills.

    +

    You know that?

    +

    Anyone who killed his wife with jealousy won’t have such a self-confident smile like you. Besides, it’s not as interesting as you have said…

    +

    That’s not true. I know a story about a friend that killed his wife with jealous that is more self-confident than me…

    +

    So, I cut him off, why not tell me the true story?

    +

    You do think I have another true story?

    +

    You might not, and I don’t care. I turned around. I would like to leave now.

    +

    Alright. I surrender. I just want to ensure that you’re truly a writer. I’ve won the game now. I’ll tell you the true story. He started.

    + +

    It was about forty years ago. I was a student, then, in a small senior high school in the country. She was my classmate, sitting just at the seat next to me. I was volatile then, with a lot of friends around. But she was always alone, and never played with us. She was quiet. She was inconspicuous, you know. She came from a rich family, and always looked well-cultivated. That’s okay. We were not as rich as she was. So we never cared to play with her. In fact we hated her.

    +

    One day I wanted to go home earlier. I surprisedly found that she went home in the same direction with me. I’ve never noticed her before, and this enkindled my curiosity. So I followed her home. (I’d got to follow her home, for she lived at the half way of mine.) She noticed me, too, and we began to talk. We talked and talked, about this and that. I found that she was not as solitary as I thought before. She just did not like nonsensical chatting. In fact, she was very tender. She was not pretty at all, but she was tender, and lovely. She was kind, very kind, that every time I told her a story about my friends, she would be very concentrated listening, and burst out a laughter when I told her a joke. We talked and talked, laughed and laughed, till we forgot we were on our way home. But finally we’ve reached her home, and we said goodbye to each other at her front door. We became friends.

    +

    From then on, we became friends, but not the kind of other friends that around me. In the day I still played around with my old mates and talked little with her, but on my way home often I rejected their invitations and walked home with her. Sometimes I even waited for her at her front door in the morning on our way to school. They said I were falling in love with her, and so they laughed at us. I did not care. I merely liked to talked with her. But words spread quickly, and soon her parents were informed. They disliked me, and sometimes drove me out for some ridiculous excuse. They endured me only for the reason of being polite. But we did not care, too. We were merely friends then, and there was really nothing between us.

    +

    Three years had passed, and we entered the same college. We became true lovers. We were free dating without her parents aside. But I was still volatile then, and so my life was divided into two different worlds: In one world there was she waiting, and in the other I was playing around with my other friends. I liked this division, and so did she. There were always friends of her murmuring around her that I did not deserve her, that I was a flirt and that she ought to find someone new. There were my friends, too, persuading me that she was not pretty at all, that she was too inconspicuous for me and that they would like to introduce someone new that is prettier and tenderer. But we cared them not. We liked the way we were. She knew me well, and she knew that finally I’d always return to her every time. I knew it, too. In the day I played around with my friends, boys and girls, and at night before the girls’ dorm was closed, I hurried there and asked someone to deliver a letter or some desert for me. Sometimes she would be standing by the window waiting for me, and wave her hands when she saw me. Then I’d wave mine, too, and wait there for her to come downstairs. Then we talked and laughed, talked and laughed, as usual. We both had a good time, then.

    +

    Another four years had passed, and we were both graduated from school. Though not spoken out, something we’d been worried for so long had coming near. Yes, we’d be married. But how should I tell her parents? You know, they liked me not at all. When I told them I would marry their daughter, you cannot imagine how frightened they were! They didn’t refuse me directly, out of politeness, but rather they persuaded her again and again. They even motivated her relatives to persuade her! They thought we (my family and I) were not as rich as them, and I did not deserve her at all! Of course they wouldn’t use the word deserve. Rather they said He’s not suitable for you. But she loved me. She loved me so much. Finally they gave up, and although they submitted us some difficult conditions, we were successfully married.

    +

    But I was enraged. They were too much, you know. We were not rich, though, but we were not the kind of scoundrel they thought! How could they speak of us in this way? At that night of my marriage I swore, oh yes I swore, that I’d never touch her, never, till they had admitted that I was the one for their daughter, the one who deserved that, and everything. Oh yes, I swore…

    +

    He paused, and took a sip. We came to a silence.

    +

    …You said… you swore that you would never touch her until they had admitted you? I asked him with disbelief. The whole stuff is ridiculous.

    +

    Yes, till they had admitted me. He continued. That’s the time when our marriage truly begins. I wanted them to admit my existence.

    +

    The next morning I canceled all the arrangements for our marriage, including our honeymoon tour. I told her our decision. She just sitting there, said nothing. I told her I was sorry for her. I was really sorry. I knew she would be sad, the whole stuff was unfair to her, but all I could say was I’m sorry. Things had to be going on this way.

    +

    That’s okay. I could understand. Just do as you wish. I’ll always be here with you. After several minutes of silence, she said. I lay down in her arms. Tears dropping from my cheeks.

    +

    Then I resigned from my current job, and took another job that was a lot harder but would have a far better future development. (In fact I started to learn about trading.) I worked hard in a factory in the day, after works I went for treats here and there, and at nights after I’ve been home I learned trading myself. It was a hard time then, but I was so determined that I could endure anything. And so was she.

    +

    But things did not change. They still chatting behind me. They said that I had treated their daughter badly. God knows why I was doing so! They said that I was self-abased in front of them, and that even so I should not treat her so badly. They even criticized my parents! They had never talked of these in front of me, but rather they chatted behind me. They thought I would never know, but I knew everything! I knew it from their eyes fallen on me, those eyes that were full of pride and contempt. They tried hard to pretend friendly, but it only made them dull.

    + +

    I could endure any kind of hard work, but I cannot stand for those insults. But I could do nothing! Nothing! Finally I started to beat her. At first I tried hard finding some excuse of her, questioned her, and then beat her, with some feeling of being sorry for her. Gradually I beat her more and more often, more and more severely, again and again. I found myself starting to hate her. I began to go home late, drinking a lot, getting on bed with barmaids and other women, and when I went home after the midnight I woke her up and beat her, again and again, till I was all drunk and had fallen into asleep.

    +

    But she was always sitting there quietly. Saying nothing, she born all my beating until I was tired. Then she sent me to sleep. While I was beating her her eyes were full of mercy. Oh yes, those mercy eyes. I hated them. I hated them while I was beating her. I asked her thousands of times in my mind: Why? Why should you endure this? Why don’t you find yourself some excuse? Come on! Say something! Say something and I’ll forgive you. But it was of no use. She was still sitting there, again and again, saying nothing, and bearing all my beating.

    +

    Gradually it became ambiguous. I could not tell if I loved her or hated her, or which was much more than the other. I just beat her, again and again, with some kind of emotion that I knew not. It’s just like a symbol, you know. She’s just like a symbol, a reminder that reminded me all the miserable fate I’d been. She just stood there, and it reminded me all those contemptuous eyes fallen on me. It reminded our miserable love and my shameful falling. I hated to see her, but I’d got to beat her. I drank, slept with different women, but before the dawn I would always return home, and beat her. You see, I needed to beat her.

    +

    But you think I’d forgotten the words I’d swore at the day we were married? You’re wrong. I still remembered that pledge. I’d never forgotten it. It was just like a holy milestone, with words carved on it saying that: When reaching here, all the misery ends. Yes, it would end then. I’d be having a high standing, and they’d be conceding my consequence. And at that moment I would end all the miseries.

    +

    The day came. After several years of hard working I had a big company and several factories of my own. I had my own industry now. All I’d got to do is to make it the biggest one in our profession. So I immediately constructed a detailed great plan and got it working. It worked. When I read from the magazine that our industry had successfully become the first one on the billboard list this month I know that the destined day had come. I cannot wait for the off time. I cannot wait any longer. I immediately grabbed my suit and left my office. On my way home I went to the shop and prepared everything.

    +

    When I opened the door she was washing the clothes. As I had expected, she was shocked, for my coming home earlier. In fact, I’d never come home before it is darkened. I watched her tenderly, softly and gently. We were standing there. Suddenly I found that she was wounded. She was wounded everywhere. Oh yes, I remembered, that was the wound I’d caused last night, and that was the day before yesterday, and that was the day… But it’s okay. It would be the last time I beat her. There would be no more. I immediately took the bandages and swathed her. I looked into her confused eyes. I kept watching her, staring at her, glancing at her, looking at her, up and down, here and there, and everywhere. Oh, she was so beautiful! If not for those bandages! But it did not matter. Oh, she was so beautiful! I immediately embraced her into my arms.

    +

    Then I picked up a dagger from inside my suit, and plugged it into her chest. Blood flowed from her chest to her clothes, her bandages, her underwear, and finally to everything. She was surprised, confusedly looking at me. Suddenly she knew everything. She smiled, and smiled, and died.

    +

    There was a long silence between us. Finally I cleared my throat.

    +

    …I… I can’t see, you know. Didn’t you have any children with her? Haven’t her parents complained about it to you?

    +

    We had two children, a boy and a girl…

    +

    …But… Wait! How could this be possible?… I mean, you have never touched her…

    +

    They are merely nursing.

    +

    … Do they know that?

    +

    No, they don’t know. I’ve never told them.

    +

    But what about the police? It’s a murder! Didn’t they take any actions?

    +

    Money is power. He smiled. You’ve got to remember.

    +

    Suddenly I understood everything.

    +

    Accident?

    +

    Yes, accident. He took another sip. No one knows what happened, except me and her.

    +

    …So, what happened to you after that?

    +

    Well, I am married again, and we have another two children now, he added, of our own.

    +

    My career is fair now. Everything goes so smoothly and so well. Do you want to know which one my industry is? It is…

    +

    He told me a name that has strictly frightened me. It is the famous chemical industry that we would see every several days in the newspaper. I think I should rather omit it here, for I don’t want to frighten you, too.

    +

    See, I’ve told you, I will frighten you. Just write it down and write it well, okay? My great writer. He turned and left. It’s my treat.

    +

    I meditated the whole stuff for a long while. Suddenly I recalled something.

    +

    Hay, man! Wait! I turned and called him. He was just at the door.

    +

    What? He smiled.

    +

    How dare you tell this story to a stranger? Aren’t you afraid that I will tell the police?

    +

    As you wish. Who will believe you? He smiled, Besides, I’ve killed myself since the day I killed her.

    +

    He is right. Nobody will believe such a ridiculous story. But I cared nothing about it. I was thinking of the last few words he spoke. I’ve killed myself since the day I killed her. Well, I’m still thinking about it now.

    + +
    + +
    +
    + Index | + First | + Previous | + 1 | + 2 | + Next | + Latest +
    + +
    + + + + diff --git a/htdocs/imacat/writings-en/19980201.html.html b/htdocs/imacat/writings-en/19980201.html.html new file mode 120000 index 0000000..a001404 --- /dev/null +++ b/htdocs/imacat/writings-en/19980201.html.html @@ -0,0 +1 @@ +19980201.html.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-en/19980201.html.xhtml b/htdocs/imacat/writings-en/19980201.html.xhtml new file mode 100644 index 0000000..3d94e5b --- /dev/null +++ b/htdocs/imacat/writings-en/19980201.html.xhtml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + +English Poetry + + + + + + + +
    + +
    + + +

    English Poetry

    + +
    2.1.’98
    +

    JUMP

    +
    +I wanna jump
    +I want reconstruction
    +Tear apart from deep within
    +And recompose into a new form of life
    +Yes, I want reconstruction of myself
    +Jumping across the deep gap and
    +    onto the edge of a new world
    +
    +That’s my desire
    +It torents my heart in this silent night
    +
    +Watching my windows
    +I keep watching through my windows sleeplessly
    +Imagining there’s a brand new world of dreams outside
    +Although I know there’s not
    +But it can’t calm me down
    +Can’t distinguish the fire of my desire
    +And can’t stop the pains of my heart
    +I keep looking out the windows
    +In the desire to jump
    +
    + +
    2.1.’98
    +

    THERE’S A FIRE

    +
    +There’s a fire
    +There’s a fire burning me
    +No way out
    +The night’s too deep
    +The street’s too quiet
    +And the people’re too sleeping
    +So I keep wondering
    +So I keep wondering my soul
    +Solely and awake
    +There’s a fire burning me
    +And I just can’t sleep
    +
    + +
    2.1.’98
    +

    WAKE UP

    +
    +Wake up!
    +Wake up!
    +Nobody here?
    +I woke up at the 2 A.M.
    +And found myself alone in the night
    +With the wind blowing the windows
    +And the dog barking in the air
    +Wake up!
    +Wake up!
    +I don’t want to be so sad and lonely
    +so please wake up
    +
    + +
    2.27.’98
    +

    WAKE UP IN THE FIRE

    +
    +I Wake up
    +and found myself in the burning fire
    +Everything’s burning
    +and I can’t stop laughing and laughing
    +and laughing and laughing and laughing...
    +Till it all burned down
    +
    + +
    + +
    +
    + Index | + First | + Previous | + 1 | + 2 | + Next | + Latest +
    + +
    + + + + diff --git a/htdocs/imacat/writings-en/index.html.html b/htdocs/imacat/writings-en/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/imacat/writings-en/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-en/index.html.xhtml b/htdocs/imacat/writings-en/index.html.xhtml new file mode 100644 index 0000000..0b704f1 --- /dev/null +++ b/htdocs/imacat/writings-en/index.html.xhtml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + +My English Writings + + + + + + + +
    + +
    + + +

    My English Writings

    + +

    1.31.’98. English Poetry

    + +

    Triple written at Kaohsiuoung this Chinese New Year. I got a pair of new pants and new shoes that night.

    + +

    5.11.’94. The Drunk

    + +

    This short novel was written long time ago in 1994 while I was still a college student. It was, actually, a homework of English class. I was crazy about writing then, and made 6 pieces of English writings instead of 3 of Teacher’s request. Thanks for Teacher’s understanding and helping me to finish it. It is not bad even from today’s point of view, so I put it here now.

    + +
    + + + + diff --git a/htdocs/imacat/writings-en/latest.html.html b/htdocs/imacat/writings-en/latest.html.html new file mode 120000 index 0000000..7a3ec04 --- /dev/null +++ b/htdocs/imacat/writings-en/latest.html.html @@ -0,0 +1 @@ +latest.html.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-en/latest.html.xhtml b/htdocs/imacat/writings-en/latest.html.xhtml new file mode 120000 index 0000000..a001404 --- /dev/null +++ b/htdocs/imacat/writings-en/latest.html.xhtml @@ -0,0 +1 @@ +19980201.html.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19970731.html.zh-cn.html b/htdocs/imacat/writings-zh/19970731.html.zh-cn.html new file mode 120000 index 0000000..f4265d4 --- /dev/null +++ b/htdocs/imacat/writings-zh/19970731.html.zh-cn.html @@ -0,0 +1 @@ +19970731.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19970731.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/19970731.html.zh-cn.xhtml new file mode 100644 index 0000000..48f7a5b --- /dev/null +++ b/htdocs/imacat/writings-zh/19970731.html.zh-cn.xhtml @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + +诗 7.30.’97. + + + + + + + +
    + +
    + + +

    7.30.’97.

    + +
    + +
    +

    (1)

    +
      思想汇聚成
    +  火焰烧尽一切烟蒂
    +  烫到了手
    +  赶紧甩开
    +  像垃圾一样抛弃
    +  像穿旧的拖鞋
    +  我是一双穿旧的旧拖鞋
    +
    +
    + +
    +

    (2)

    +
      习惯用写的
    +  因为可以多给自己一点
    +  空间保留储存
    +  在硬碟里
    +
    +
    + +
    +

    (3)

    +
      你要我什么时候走
    +  我就可以
    +  离开我说到做到这也就是我最大的
    +  痛苦
    +
    +
    + +
    +

    (4)

    +
      大鱼生小鱼了
    +  我们不能养乌龟了
    +
    +
    + +
    +

    (5)

    +
      开电风扇可以
    +        驱走热气
    +        驱走蚊子
    +        驱走灵魂
    +  剩下一个没有灵魂的
    +  空壳子我不想要它了
    +
    +
    + +
    +

    (5)

    +
      以为可以
    +  写诗的其实不行
    +  因为笔不好因为纸不好因为
    +  灵魂不好我
    +  想换一个新的灵魂不知
    +  要多少钱             便利超商的小姐告诉我:你的卡爆了
    +
    +
    + +
    +

    (6)

    +
      就是
    +  这样其实很想把这两页纸
    +  撕掉文字
    +  因为网路线路的缓慢速度而被切割在奇
    +  怪的地方思考
    +  也被切割在那里可是
    +  不能撕掉因为背面还有字
    +  其实这一切只是
    +  藉口因为背面的字还是
    +  我的
    +
    +7.31.’97. 12:27pm.
    +
    +
    + +
    +

    收音机

    +
      我是一台乱七ㄅ糟的
    +  收音机
    +  有
    +  杂讯
    +  很
    +  多
    +  所以
    +  快转另外一台吧
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 1 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19970731.html.zh-tw.html b/htdocs/imacat/writings-zh/19970731.html.zh-tw.html new file mode 120000 index 0000000..977e343 --- /dev/null +++ b/htdocs/imacat/writings-zh/19970731.html.zh-tw.html @@ -0,0 +1 @@ +19970731.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19970731.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/19970731.html.zh-tw.xhtml new file mode 100644 index 0000000..ea84a56 --- /dev/null +++ b/htdocs/imacat/writings-zh/19970731.html.zh-tw.xhtml @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + +詩 7.30.’97. + + + + + + + +
    + +
    + + +

    7.30.’97.

    + +
    + +
    +

    (1)

    +
      思想彙聚成
    +  火燄燒盡一切煙蒂
    +  燙到了手
    +  趕緊甩開
    +  像垃圾一樣拋棄
    +  像穿舊的拖鞋
    +  我是一雙穿舊的舊拖鞋
    +
    +
    + +
    +

    (2)

    +
      習慣用寫的
    +  因為可以多給自己一點
    +  空間保留儲存
    +  在硬碟裡
    +
    +
    + +
    +

    (3)

    +
      妳要我什麼時候走
    +  我就可以
    +  離開我說到做到這也就是我最大的
    +  痛苦
    +
    +
    + +
    +

    (4)

    +
      大魚生小魚了
    +  我們不能養烏龜了
    +
    +
    + +
    +

    (5)

    +
      開電風扇可以
    +        驅走熱氣
    +        驅走蚊子
    +        驅走靈魂
    +  剩下一個沒有靈魂的
    +  空殼子我不想要它了
    +
    +
    + +
    +

    (5)

    +
      以為可以
    +  寫詩的其實不行
    +  因為筆不好因為紙不好因為
    +  靈魂不好我
    +  想換一個新的靈魂不知
    +  要多少錢             便利超商的小姐告訴我:妳的卡爆了
    +
    +
    + +
    +

    (6)

    +
      就是
    +  這樣其實很想把這兩頁紙
    +  撕掉文字
    +  因為網路線路的緩慢速度而被切割在奇
    +  怪的地方思考
    +  也被切割在那裡可是
    +  不能撕掉因為背面還有字
    +  其實這一切只是
    +  藉口因為背面的字還是
    +  我的
    +
    +7.31.’97. 12:27pm.
    +
    +
    + +
    +

    收音機

    +
      我是一臺亂七ㄅ糟的
    +  收音機
    +  有
    +  雜訊
    +  很
    +  多
    +  所以
    +  快轉另外一台吧
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 1 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19970903.html.zh-cn.html b/htdocs/imacat/writings-zh/19970903.html.zh-cn.html new file mode 120000 index 0000000..89652ac --- /dev/null +++ b/htdocs/imacat/writings-zh/19970903.html.zh-cn.html @@ -0,0 +1 @@ +19970903.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19970903.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/19970903.html.zh-cn.xhtml new file mode 100644 index 0000000..624409a --- /dev/null +++ b/htdocs/imacat/writings-zh/19970903.html.zh-cn.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 9.2.’97. 分岔 + + + + + + + +
    + +
    + + +

    9.2.’97. 分岔

    + +
    + +
    +

    分岔(1)

    +
    长发 飘落在 死亡的界线
    +尾端的 分岔 分立 两边
    +打了个嗝 手里 剪刀 滑落
    +就
    +死了
    +
    +
    + +
    +

    分岔(2)

    +
    以为自己可以面对
    +死亡的其实不能手里握著剪刀时没想到我在
    +颤抖结果是打嗝帮我剪掉了
    +分岔
    +
    +
    + +
    +

    分岔(3)

    +
    分岔说为什么要剪掉
    +我我只是想长向不一样的方向自我
    +而已我说没有不一样的自我因为
    +你就是我於是我把不一样的自我
    +杀 死 了
    +
    +
    + +
    +

    分岔(4)

    +
    分岔继续生长我也
    +继续剪掉这是
    +一场永无休止的争战循环
    +我想结束却无法停止
    +打
    +嗝
    +
    +
    + +
    +

    分岔(5)

    +
    剪落的分岔 掉落 地平线的那一端
    +滑向 永恒 我开始 后悔 想把它捡回来
    +它告诉我 不可能 它遵从的是
    +地心引力 不是 我的命令
    +
    +Sep. 3. '97. 韩航飞机上
    +(时间不知道 那天我飞过了好几个时区 你问我的是汉城的时间还是莫斯科的时间)
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 1 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19970903.html.zh-tw.html b/htdocs/imacat/writings-zh/19970903.html.zh-tw.html new file mode 120000 index 0000000..c1c9c7c --- /dev/null +++ b/htdocs/imacat/writings-zh/19970903.html.zh-tw.html @@ -0,0 +1 @@ +19970903.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19970903.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/19970903.html.zh-tw.xhtml new file mode 100644 index 0000000..7c78af7 --- /dev/null +++ b/htdocs/imacat/writings-zh/19970903.html.zh-tw.xhtml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 9.2.’97. 分岔 + + + + + + + +
    + +
    + + +

    9.2.’97. 分岔

    + +
    + +
    +

    分岔(1)

    +
    長髮 飄落在 死亡的界線
    +尾端的 分岔 分立 兩邊
    +打了個嗝 手裡 剪刀 滑落
    +就
    +死了
    +
    +
    + +
    +

    分岔(2)

    +
    以為自己可以面對
    +死亡的其實不能手裡握著剪刀時沒想到我在
    +顫抖結果是打嗝幫我剪掉了
    +分岔
    +
    +
    + +
    +

    分岔(3)

    +
    分岔說為什麼要剪掉
    +我我只是想長向不一樣的方向自我
    +而已我說沒有不一樣的自我因為
    +妳就是我於是我把不一樣的自我
    +殺 死 了
    +
    +
    + +
    +

    分岔(4)

    +
    分岔繼續生長我也
    +繼續剪掉這是
    +一場永無休止的爭戰循環
    +我想結束卻無法停止
    +打
    +嗝
    +
    +
    + +
    +

    分岔(5)

    +
    剪落的分岔 掉落 地平線的那一端
    +滑向 永恆 我開始 後悔 想把它撿回來
    +它告訴我 不可能 它遵從的是
    +地心引力 不是 我的命令
    +
    +Sep. 3. '97. 韓航飛機上
    +(時間不知道 那天我飛過了好幾個時區 妳問我的是漢城的時間還是莫斯科的時間)
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 1 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19970916.html.zh-cn.html b/htdocs/imacat/writings-zh/19970916.html.zh-cn.html new file mode 120000 index 0000000..851e51e --- /dev/null +++ b/htdocs/imacat/writings-zh/19970916.html.zh-cn.html @@ -0,0 +1 @@ +19970916.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19970916.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/19970916.html.zh-cn.xhtml new file mode 100644 index 0000000..85f7b59 --- /dev/null +++ b/htdocs/imacat/writings-zh/19970916.html.zh-cn.xhtml @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 9.15.’97. + + + + + + + +
    + +
    + + +

    9.15.’97.

    + +
    + +
    +

    爆裂

    +
    雨滴 破裂成 千百万个 光点
    +降落在 飞行中的 高热的 钛合金的
    +尘埃上 爆裂 疯狂
    +射向在 四周的 木制家俱
    +
    +
    + +
    +

    金发

    +
    金发的 太阳 醒来
    +甩甩头 甩甩一头耀眼的金发
    +金发笑起来暖烘烘的
    +向日葵也跟著 笑得 暖烘烘的
    +
    +
    + +
    +

    塔台

    +
    没有音乐的塔台 传来 喷射引擎的声音
    +轰隆轰隆的 瞬间 所有人都安静了
    +所有人都禀息以待  突然
    +
    +起飞了
    +
    +
    + +
    +

    无感

    +
    我已失去了 分辨好坏的能力
    +任凭喷射引擎的声音 轰隆轰隆地
    +逐渐地远离 走向 死  亡
    +
    +
    + +
    +

    水泥的

    +
    在裂缝中 放上 一个时钟
    +酸雨打在 发条上 卡住了 时钟	不能动弹
    +於是 时间停止了 一切都 停止了
    +酸雨也 停止了 凝住 在空中
    +
    +
    + +
    +

    生日----赚钱金店

    +
    数著 三只用房地产广告纸折成的 千纸鹤
    +突然发现 第一只的头 折歪了
    +
    +
    + +
    +

    做爱

    +
    给你 我的身体 很容易
    +给你 我的心 好难
    +
    +
    + +
    +

    洪水

    +
    月亮 被我 淹没了
    +我太多了 月亮承载不住 也流 向 你
    +
    +
    + +
    +

    绊倒

    +
    鞋子 停留在 牛肉上
    +停留在 波斯地毯上
    +停留在 另一只鞋子上
    +停留在 第六根手指上
    +停留在 空中
    +停留在 我的头发上
    +绊倒了 侍者
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 1 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19970916.html.zh-tw.html b/htdocs/imacat/writings-zh/19970916.html.zh-tw.html new file mode 120000 index 0000000..4099ea9 --- /dev/null +++ b/htdocs/imacat/writings-zh/19970916.html.zh-tw.html @@ -0,0 +1 @@ +19970916.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19970916.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/19970916.html.zh-tw.xhtml new file mode 100644 index 0000000..e7b0b73 --- /dev/null +++ b/htdocs/imacat/writings-zh/19970916.html.zh-tw.xhtml @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 9.15.’97. + + + + + + + +
    + +
    + + +

    9.15.’97.

    + +
    + +
    +

    爆裂

    +
    雨滴 破裂成 千百萬個 光點
    +降落在 飛行中的 高熱的 鈦合金的
    +塵埃上 爆裂 瘋狂
    +射向在 四周的 木製傢俱
    +
    +
    + +
    +

    金髮

    +
    金髮的 太陽 醒來
    +甩甩頭 甩甩一頭耀眼的金髮
    +金髮笑起來暖烘烘的
    +向日葵也跟著 笑得 暖烘烘的
    +
    +
    + +
    +

    塔臺

    +
    沒有音樂的塔臺 傳來 噴射引擎的聲音
    +轟隆轟隆的 瞬間 所有人都安靜了
    +所有人都稟息以待  突然
    +
    +起飛了
    +
    +
    + +
    +

    無感

    +
    我已失去了 分辨好壞的能力
    +任憑噴射引擎的聲音 轟隆轟隆地
    +逐漸地遠離 走向 死  亡
    +
    +
    + +
    +

    水泥的

    +
    在裂縫中 放上 一個時鐘
    +酸雨打在 發條上 卡住了 時鐘	不能動彈
    +於是 時間停止了 一切都 停止了
    +酸雨也 停止了 凝住 在空中
    +
    +
    + +
    +

    生日----賺錢金店

    +
    數著 三隻用房地產廣告紙折成的 千紙鶴
    +突然發現 第一隻的頭 折歪了
    +
    +
    + +
    +

    做愛

    +
    給妳 我的身體 很容易
    +給妳 我的心 好難
    +
    +
    + +
    +

    洪水

    +
    月亮 被我 淹沒了
    +我太多了 月亮承載不住 也流 向 妳
    +
    +
    + +
    +

    絆倒

    +
    鞋子 停留在 牛肉上
    +停留在 波斯地毯上
    +停留在 另一隻鞋子上
    +停留在 第六根手指上
    +停留在 空中
    +停留在 我的頭髮上
    +絆倒了 侍者
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 1 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19980109.html.zh-cn.html b/htdocs/imacat/writings-zh/19980109.html.zh-cn.html new file mode 120000 index 0000000..7296dfa --- /dev/null +++ b/htdocs/imacat/writings-zh/19980109.html.zh-cn.html @@ -0,0 +1 @@ +19980109.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19980109.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/19980109.html.zh-cn.xhtml new file mode 100644 index 0000000..c421824 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980109.html.zh-cn.xhtml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 1.8.’98. 死亡昆虫 + + + + + + + +
    + +
    + + +

    1.8.’98. 死亡昆虫

    + +
    + +
    +

    死亡蝴蝶

    +
    美丽是我的天赋
    +死亡是我的宿命
    +每个人都在期待我的死亡
    +为了保存我的美丽
    +
    +
    + +
    +

    死亡蛾

    +
    啪的一声
    +掌心只剩下散落的金色鳞粉
    +我只有在死亡的一刻是最美的
    +余皆丑陋不堪
    +
    +
    + +
    +

    死亡蟑螂

    +
    即使我死了
    +你还是无法摆脱我的恶心
    +这是你的宿命
    +你只能接受
    +
    +
    + +
    +

    死亡蚊子

    +
    你早已成为我生命的一部份
    +不可分割
    +即使你杀死我
    +我流出来的血也是 你的
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 1 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19980109.html.zh-tw.html b/htdocs/imacat/writings-zh/19980109.html.zh-tw.html new file mode 120000 index 0000000..809bf9e --- /dev/null +++ b/htdocs/imacat/writings-zh/19980109.html.zh-tw.html @@ -0,0 +1 @@ +19980109.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19980109.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/19980109.html.zh-tw.xhtml new file mode 100644 index 0000000..b3412dc --- /dev/null +++ b/htdocs/imacat/writings-zh/19980109.html.zh-tw.xhtml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 1.8.’98. 死亡昆蟲 + + + + + + + +
    + +
    + + +

    1.8.’98. 死亡昆蟲

    + +
    + +
    +

    死亡蝴蝶

    +
    美麗是我的天賦
    +死亡是我的宿命
    +每個人都在期待我的死亡
    +為了保存我的美麗
    +
    +
    + +
    +

    死亡蛾

    +
    啪的一聲
    +掌心只剩下散落的金色鱗粉
    +我只有在死亡的一刻是最美的
    +餘皆醜陋不堪
    +
    +
    + +
    +

    死亡蟑螂

    +
    即使我死了
    +妳還是無法擺脫我的噁心
    +這是妳的宿命
    +妳只能接受
    +
    +
    + +
    +

    死亡蚊子

    +
    妳早已成為我生命的一部份
    +不可分割
    +即使妳殺死我
    +我流出來的血也是 妳的
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 1 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19980126.html.zh-cn.html b/htdocs/imacat/writings-zh/19980126.html.zh-cn.html new file mode 120000 index 0000000..c250140 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980126.html.zh-cn.html @@ -0,0 +1 @@ +19980126.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19980126.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/19980126.html.zh-cn.xhtml new file mode 100644 index 0000000..404598e --- /dev/null +++ b/htdocs/imacat/writings-zh/19980126.html.zh-cn.xhtml @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 1.25.’98. + + + + + + + +
    + +
    + + +

    1.25.’98.

    + +
    + +
    +

    飞行的莲蓬头

    +
    莲蓬头  在云里飞行
    +在这片土地上
    + 洒  水  洒  水  洒  水
    +  洒  水  洒  水  洒  水
    +  洒  水  洒  水  洒  水
    +   洒  水  洒  水  洒  水
    +莲蓬头的另一端 接著水管
    +水里的脏污 阻塞了飞行中的莲蓬头
    +逐渐 干 涸 水停了
    +土地也 逐渐 干. 涸..变成..沙......漠............
    +
    +
    + +
    +

    电视(有线电视)

    +
    日语和英语交杂的空间
    +我看著电视
    +电视 也看著我
    +
    +
    + +
    +

    飞航安全

    +
    是一张卡片
    +和呕吐袋放在一起
    +是空中小姐卖力的微笑演出
    +和一群看著报纸的群众
    +
    +
    + +
    +

    疯狂飞行

    +
    我想疯狂飞行
    +贴著大楼的玻璃帏幕
    +沿著永无止境的饭店长廊
    +穿梭在错综复杂的下水道
    +我想疯狂飞行
    +穿越云端
    +穿越我所有的恐惧
    +穿越你
    +我想疯狂飞行
    +正如我想疯狂坠落
    +享受最后的重力加速度
    +把无法跟上躯体速度的 沉重缓慢痛苦的灵魂 留在顶端
    +
    +
    + +
    +

    礼物

    +
    疲倦 侵蚀著我的灵魂
    +我想把我的灵魂送给你
    +捧在手心 才发现 太重了 连我自己都无法承受
    +
    +
    + +
    +

    礼物(2)

    +
    给你
    +给你
    +通通都给你
    +这么破烂的灵魂
    +我不要了
    +
    +
    + +
    +

    礼物(3)

    +
    我该给你什么样的 情人节礼物?
    +找不到我的灵魂里 好的部份 可以给你
    +
    +
    + +
    +

    自恋

    +
    看著 血液慢慢地从腕动脉 汨汨流出
    +手掌的颜色也 逐渐苍白
    +我太自恋了
    +无法不去迷恋这样 美丽的自己
    +
    +
    + +
    +

    黑咖啡

    +
    拒绝奶精 拒绝糖
    +我就是要这样 毫无杂质的 苦涩
    +
    +
    + +
    +

    黑蚯蚓

    +
    黑色的蚯蚓 从墨水笔的笔端 流泻出来
    +听说 把灵魂最黑暗丑陋的部份 排泄出来 就叫做 诗
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 8 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19980126.html.zh-tw.html b/htdocs/imacat/writings-zh/19980126.html.zh-tw.html new file mode 120000 index 0000000..560cd2e --- /dev/null +++ b/htdocs/imacat/writings-zh/19980126.html.zh-tw.html @@ -0,0 +1 @@ +19980126.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19980126.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/19980126.html.zh-tw.xhtml new file mode 100644 index 0000000..756c5cc --- /dev/null +++ b/htdocs/imacat/writings-zh/19980126.html.zh-tw.xhtml @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 1.25.’98. + + + + + + + +
    + +
    + + +

    1.25.’98.

    + +
    + +
    +

    飛行的蓮蓬頭

    +
    蓮蓬頭  在雲裡飛行
    +在這片土地上
    + 灑  水  灑  水  灑  水
    +  灑  水  灑  水  灑  水
    +  灑  水  灑  水  灑  水
    +   灑  水  灑  水  灑  水
    +蓮蓬頭的另一端 接著水管
    +水裡的髒污 阻塞了飛行中的蓮蓬頭
    +逐漸 乾 涸 水停了
    +土地也 逐漸 乾. 涸..變成..沙......漠............
    +
    +
    + +
    +

    電視(有線電視)

    +
    日語和英語交雜的空間
    +我看著電視
    +電視 也看著我
    +
    +
    + +
    +

    飛航安全

    +
    是一張卡片
    +和嘔吐袋放在一起
    +是空中小姐賣力的微笑演出
    +和一群看著報紙的群眾
    +
    +
    + +
    +

    瘋狂飛行

    +
    我想瘋狂飛行
    +貼著大樓的玻璃幃幕
    +沿著永無止境的飯店長廊
    +穿梭在錯綜複雜的下水道
    +我想瘋狂飛行
    +穿越雲端
    +穿越我所有的恐懼
    +穿越妳
    +我想瘋狂飛行
    +正如我想瘋狂墜落
    +享受最後的重力加速度
    +把無法跟上軀體速度的 沉重緩慢痛苦的靈魂 留在頂端
    +
    +
    + +
    +

    禮物

    +
    疲倦 侵蝕著我的靈魂
    +我想把我的靈魂送給妳
    +捧在手心 才發現 太重了 連我自己都無法承受
    +
    +
    + +
    +

    禮物(2)

    +
    給妳
    +給妳
    +通通都給妳
    +這麼破爛的靈魂
    +我不要了
    +
    +
    + +
    +

    禮物(3)

    +
    我該給妳什麼樣的 情人節禮物?
    +找不到我的靈魂裡 好的部份 可以給妳
    +
    +
    + +
    +

    自戀

    +
    看著 血液慢慢地從腕動脈 汨汨流出
    +手掌的顏色也 逐漸蒼白
    +我太自戀了
    +無法不去迷戀這樣 美麗的自己
    +
    +
    + +
    +

    黑咖啡

    +
    拒絕奶精 拒絕糖
    +我就是要這樣 毫無雜質的 苦澀
    +
    +
    + +
    +

    黑蚯蚓

    +
    黑色的蚯蚓 從墨水筆的筆端 流瀉出來
    +聽說 把靈魂最黑暗醜陋的部份 排洩出來 就叫做 詩
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 8 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19980206.html.zh-cn.html b/htdocs/imacat/writings-zh/19980206.html.zh-cn.html new file mode 120000 index 0000000..64b83d0 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980206.html.zh-cn.html @@ -0,0 +1 @@ +19980206.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19980206.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/19980206.html.zh-cn.xhtml new file mode 100644 index 0000000..5033d68 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980206.html.zh-cn.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 2.5.’98. + + + + + + + +
    + +
    + + +

    2.5.’98.

    + +
    + +
    +

    玻璃

    +
    像玻璃般透明
    +我小心翼翼地拿著 对你的感觉
    +危危颤颤 竖起所有神经末稍平衡著
    +深怕哪一只手指力量大一些 它就会破裂
    +
    +那就是我对你的感觉
    +我小心翼翼地把它放在玻璃瓶里
    +再包上一层又一层的报纸
    +却让我越来越看不清那是什么
    +直到有一天我再度打开
    +却发现它早已破裂
    +
    +
    + +
    +

    线

    +
    站在线的边缘 呼喊著
    +死命地拍打著线 换来的只是满手的玻璃碎片
    +曾经以为 你听得见我的呐喊
    +才知道 从线的那一边看来 我是无声的
    +曾经如此相信执著於这个梦想
    +如今梦想是否不会实现
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 3 | + 4 | + 5 | + 6 | + 7 | + 8 | + 9 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19980206.html.zh-tw.html b/htdocs/imacat/writings-zh/19980206.html.zh-tw.html new file mode 120000 index 0000000..161c2e4 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980206.html.zh-tw.html @@ -0,0 +1 @@ +19980206.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19980206.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/19980206.html.zh-tw.xhtml new file mode 100644 index 0000000..4da4e7b --- /dev/null +++ b/htdocs/imacat/writings-zh/19980206.html.zh-tw.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 2.5.’98. + + + + + + + +
    + +
    + + +

    2.5.’98.

    + +
    + +
    +

    玻璃

    +
    像玻璃般透明
    +我小心翼翼地拿著 對妳的感覺
    +危危顫顫 豎起所有神經末稍平衡著
    +深怕哪一隻手指力量大一些 它就會破裂
    +
    +那就是我對妳的感覺
    +我小心翼翼地把它放在玻璃瓶裡
    +再包上一層又一層的報紙
    +卻讓我越來越看不清那是什麼
    +直到有一天我再度打開
    +卻發現它早已破裂
    +
    +
    + +
    +

    +
    站在線的邊緣 呼喊著
    +死命地拍打著線 換來的只是滿手的玻璃碎片
    +曾經以為 妳聽得見我的吶喊
    +才知道 從線的那一邊看來 我是無聲的
    +曾經如此相信執著於這個夢想
    +如今夢想是否不會實現
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 3 | + 4 | + 5 | + 6 | + 7 | + 8 | + 9 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19980213.html.zh-cn.html b/htdocs/imacat/writings-zh/19980213.html.zh-cn.html new file mode 120000 index 0000000..c3edfff --- /dev/null +++ b/htdocs/imacat/writings-zh/19980213.html.zh-cn.html @@ -0,0 +1 @@ +19980213.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19980213.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/19980213.html.zh-cn.xhtml new file mode 100644 index 0000000..4f91d44 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980213.html.zh-cn.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 2.12.’98. + + + + + + + +
    + +
    + + +

    2.12.’98.

    + +
    + +
    +

    相纸

    +
    爱情 像照片一样 会褪色
    +於是我把爱情放在干燥密封玻璃瓶里
    +小心翼翼地包起来藏好
    +永远不去翻出来看
    +这样我对你的感觉就永远不会 褪色
    +
    +
    + +
    +

    杉树

    +
    杉树说
    +我爱你
    +我说
    +笨蛋
    +
    +
    + +
    +

    杉树.2

    +
    杉树说
    +我爱你
    +我说
    +笨蛋
    +杉树和榆树是不可能在一起的
    +
    +
    + +
    +

    鳄鱼

    +
    骄傲的鳄鱼呼噜呼噜地叫著
    +一口便把爱情给吞掉了
    +而她在笑
    +
    +
    + +
    +

    自私的鳄鱼

    +
    自私的鳄鱼低头思考著
    +怎么样才能让她对她印象更好
    +自私的鳄鱼低头思考著
    +怎么样才能把她留在她身边
    +於是她对她体贴备至
    +却因此失去了自我
    +
    +
    + +
    +

    鞋尖的线

    +
    疯狂的标语
    +掉落在第二条斑马线上
    +无限延伸
    +穿越了清醒的极限
    +与超级市场的小姐
    +交会
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 4 | + 5 | + 6 | + 7 | + 8 | + 9 | + 10 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19980213.html.zh-tw.html b/htdocs/imacat/writings-zh/19980213.html.zh-tw.html new file mode 120000 index 0000000..6018317 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980213.html.zh-tw.html @@ -0,0 +1 @@ +19980213.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19980213.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/19980213.html.zh-tw.xhtml new file mode 100644 index 0000000..6dab8a0 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980213.html.zh-tw.xhtml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 2.12.’98. + + + + + + + +
    + +
    + + +

    2.12.’98.

    + +
    + +
    +

    相紙

    +
    愛情 像照片一樣 會褪色
    +於是我把愛情放在乾燥密封玻璃瓶裡
    +小心翼翼地包起來藏好
    +永遠不去翻出來看
    +這樣我對妳的感覺就永遠不會 褪色
    +
    +
    + +
    +

    杉樹

    +
    杉樹說
    +我愛妳
    +我說
    +笨蛋
    +
    +
    + +
    +

    杉樹.2

    +
    杉樹說
    +我愛妳
    +我說
    +笨蛋
    +杉樹和榆樹是不可能在一起的
    +
    +
    + +
    +

    鱷魚

    +
    驕傲的鱷魚呼嚕呼嚕地叫著
    +一口便把愛情給吞掉了
    +而她在笑
    +
    +
    + +
    +

    自私的鱷魚

    +
    自私的鱷魚低頭思考著
    +怎麼樣才能讓她對她印象更好
    +自私的鱷魚低頭思考著
    +怎麼樣才能把她留在她身邊
    +於是她對她體貼備至
    +卻因此失去了自我
    +
    +
    + +
    +

    鞋尖的線

    +
    瘋狂的標語
    +掉落在第二條斑馬線上
    +無限延伸
    +穿越了清醒的極限
    +與超級市場的小姐
    +交會
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 4 | + 5 | + 6 | + 7 | + 8 | + 9 | + 10 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19980317.html.zh-cn.html b/htdocs/imacat/writings-zh/19980317.html.zh-cn.html new file mode 120000 index 0000000..020ec7c --- /dev/null +++ b/htdocs/imacat/writings-zh/19980317.html.zh-cn.html @@ -0,0 +1 @@ +19980317.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19980317.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/19980317.html.zh-cn.xhtml new file mode 100644 index 0000000..7ccd931 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980317.html.zh-cn.xhtml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 3.16.’98. 冰河 + + + + + + + +
    + +
    + + +

    3.16.’98. 冰河

    + +
    + +
    +

    冰河(0)

    +
    冰河
    +缓慢地流过
    +沉重而有力地带走
    +它所能带走的一切
    +并且在地面上留下深深的
    +刮痕
    +
    +跟你一样
    +
    +
    + +
    +

    冰河(1)

    +
    我和冰河一起飞翔在
    +没有空气的天空
    +於是
    +鸟儿躲避 死亡
    +而你说
    +那很好
    +
    +
    + +
    +

    冰河(3)

    +
    冰河无法接近人世间
    +所以我把你
    +杀了
    +再埋起来
    +於是你就不用再
    +嫉妒
    +
    +
    + +
    +

    冰河(4)

    +
    冰河被我和标题给 弄混乱了
    +搞不清我和你就竟是 什么
    +我说 没关系
    +因为在天空中究竟是 没有分别的。
    +
    +
    + +
    +

    冰河(5)

    +
    於是我和冰河之间有一条
    +沉重而无形的线
    +它被你沉重而缓慢地
    +刮走了
    +
    +
    + +
    +

    冰河(6)

    +
    冰河 恨我
    +而我
    +也恨她
    +
    +
    + +
    +

    冰河(7)

    +
    我是否能从此斩断
    +与冰河的连线
    +为就像风与诗一般
    +不再对话
    +什么我看到冰河就会
    +想起你
    +於是我看到国家地理杂志时
    +不再难过
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 5 | + 6 | + 7 | + 8 | + 9 | + 10 | + 11 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19980317.html.zh-tw.html b/htdocs/imacat/writings-zh/19980317.html.zh-tw.html new file mode 120000 index 0000000..d8a0dc6 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980317.html.zh-tw.html @@ -0,0 +1 @@ +19980317.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19980317.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/19980317.html.zh-tw.xhtml new file mode 100644 index 0000000..f148809 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980317.html.zh-tw.xhtml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 3.16.’98. 冰河 + + + + + + + +
    + +
    + + +

    3.16.’98. 冰河

    + +
    + +
    +

    冰河(0)

    +
    冰河
    +緩慢地流過
    +沉重而有力地帶走
    +它所能帶走的一切
    +並且在地面上留下深深的
    +刮痕
    +
    +跟妳一樣
    +
    +
    + +
    +

    冰河(1)

    +
    我和冰河一起飛翔在
    +沒有空氣的天空
    +於是
    +鳥兒躲避 死亡
    +而妳說
    +那很好
    +
    +
    + +
    +

    冰河(3)

    +
    冰河無法接近人世間
    +所以我把妳
    +殺了
    +再埋起來
    +於是妳就不用再
    +嫉妒
    +
    +
    + +
    +

    冰河(4)

    +
    冰河被我和標題給 弄混亂了
    +搞不清我和妳就竟是 什麼
    +我說 沒關係
    +因為在天空中究竟是 沒有分別的。
    +
    +
    + +
    +

    冰河(5)

    +
    於是我和冰河之間有一條
    +沉重而無形的線
    +它被妳沉重而緩慢地
    +刮走了
    +
    +
    + +
    +

    冰河(6)

    +
    冰河 恨我
    +而我
    +也恨她
    +
    +
    + +
    +

    冰河(7)

    +
    我是否能從此斬斷
    +與冰河的連線
    +為就像風與詩一般
    +不再對話
    +什麼我看到冰河就會
    +想起妳
    +於是我看到國家地理雜誌時
    +不再難過
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 5 | + 6 | + 7 | + 8 | + 9 | + 10 | + 11 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19980429.html.zh-cn.html b/htdocs/imacat/writings-zh/19980429.html.zh-cn.html new file mode 120000 index 0000000..f73c8d6 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980429.html.zh-cn.html @@ -0,0 +1 @@ +19980429.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19980429.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/19980429.html.zh-cn.xhtml new file mode 100644 index 0000000..9b96890 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980429.html.zh-cn.xhtml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 4.28.’98. + + + + + + + +
    + +
    + + +

    4.28.’98.

    + +
    + +
    +

    旅人之歌

    +
    旅人们在旅舍来来去去
    +心与心的距离曾是如此地靠近
    +又如此地遥远
    +
    +我们拥有的
    +是短暂交会的过去
    +我们面对的
    +是没有交集的未来
    +
    +
    + +
    +

    疯狂诗路

    +
    人们总以为诗人是伟大的
    +可我知道不是
    +至少我不是
    +
    +那只是某种虚掷的幻想
    +穿梭在不存在的时空中
    +燃烧的热情狂乱地毁灭了一切
    +末了只留下千篇一律的悔恨
    +和伤痕
    +
    +
    + +
    +

    伤痕

    +
    留下的伤痕
    +有三公分深
    +我试著用三公分长的舌头去舔
    +用力在伤痕里寻找 你美工刀的味道
    +
    +
    + +
    +

    绝望

    +
    哭到一半
    +想起晾在阳台的衣服还没收
    +
    +
    + +
    +

    狂歌

    +
    我想让声音流泻出来
    +流泻在你的谷底
    +倾听你身体内的声音
    +让声音成为我的感官
    +音波就是我的手
    +闭上双眼
    +就能感受你的存在
    +挤干自己身体的能量
    +化为振幅
    +轻轻掩住你的双眼
    +直到失去声音
    +再也不能渴望 和你交会
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 6 | + 7 | + 8 | + 9 | + 10 | + 11 | + 12 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19980429.html.zh-tw.html b/htdocs/imacat/writings-zh/19980429.html.zh-tw.html new file mode 120000 index 0000000..5e0f444 --- /dev/null +++ b/htdocs/imacat/writings-zh/19980429.html.zh-tw.html @@ -0,0 +1 @@ +19980429.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19980429.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/19980429.html.zh-tw.xhtml new file mode 100644 index 0000000..c432d8d --- /dev/null +++ b/htdocs/imacat/writings-zh/19980429.html.zh-tw.xhtml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 4.28.’98. + + + + + + + +
    + +
    + + +

    4.28.’98.

    + +
    + +
    +

    旅人之歌

    +
    旅人們在旅舍來來去去
    +心與心的距離曾是如此地靠近
    +又如此地遙遠
    +
    +我們擁有的
    +是短暫交會的過去
    +我們面對的
    +是沒有交集的未來
    +
    +
    + +
    +

    瘋狂詩路

    +
    人們總以為詩人是偉大的
    +可我知道不是
    +至少我不是
    +
    +那只是某種虛擲的幻想
    +穿梭在不存在的時空中
    +燃燒的熱情狂亂地毀滅了一切
    +末了只留下千篇一律的悔恨
    +和傷痕
    +
    +
    + +
    +

    傷痕

    +
    留下的傷痕
    +有三公分深
    +我試著用三公分長的舌頭去舔
    +用力在傷痕裡尋找 妳美工刀的味道
    +
    +
    + +
    +

    絕望

    +
    哭到一半
    +想起晾在陽臺的衣服還沒收
    +
    +
    + +
    +

    狂歌

    +
    我想讓聲音流瀉出來
    +流瀉在妳的谷底
    +傾聽妳身體內的聲音
    +讓聲音成為我的感官
    +音波就是我的手
    +閉上雙眼
    +就能感受妳的存在
    +擠乾自己身體的能量
    +化為振幅
    +輕輕掩住妳的雙眼
    +直到失去聲音
    +再也不能渴望 和妳交會
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 6 | + 7 | + 8 | + 9 | + 10 | + 11 | + 12 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19990820.html.zh-cn.html b/htdocs/imacat/writings-zh/19990820.html.zh-cn.html new file mode 120000 index 0000000..d5e960e --- /dev/null +++ b/htdocs/imacat/writings-zh/19990820.html.zh-cn.html @@ -0,0 +1 @@ +19990820.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19990820.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/19990820.html.zh-cn.xhtml new file mode 100644 index 0000000..d0e4505 --- /dev/null +++ b/htdocs/imacat/writings-zh/19990820.html.zh-cn.xhtml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 8.19.’99. irresistible + + + + + + + +
    + +
    + + +

    8.19.’99. irresistible

    + +
    + +
    +

    irresistible

    +
    irresistible
    +a.
    +不可抵抗的;不能压制的
    +
    +不可靠近的  一旦靠近  就会
    +崩解
    +
    +
    + +
    +

    illegal

    +
    illegal
    +a.
    +不合法的,非法的;违反规则的
    +
    +非法的  所以  不能存在
    +尽速消灭  以免为祸
    +
    +
    + +
    +

    无声的声音

    +
    我的声音,在雨中奔驰、呐喊、呼唤,却似没
    +有人听见一样,雨,仍然静静地下著。
    +
    +
    + +
    +

    残忍

    +
    莫名其妙
    +会为自己残忍
    +也对别人残忍
    +
    +把语言文字当作一把斧头
    +狠烈烈地劈在某个人的心中
    +看著她流血
    +也看著自己流血
    +
    +恶狠狠地舔著自己的血,笑著
    +咀嚼著伤口抹盐的痛觉
    +装作若无其事地走开
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 7 | + 8 | + 9 | + 10 | + 11 | + 12 | + 13 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/19990820.html.zh-tw.html b/htdocs/imacat/writings-zh/19990820.html.zh-tw.html new file mode 120000 index 0000000..7e5f2d2 --- /dev/null +++ b/htdocs/imacat/writings-zh/19990820.html.zh-tw.html @@ -0,0 +1 @@ +19990820.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/19990820.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/19990820.html.zh-tw.xhtml new file mode 100644 index 0000000..8a2d354 --- /dev/null +++ b/htdocs/imacat/writings-zh/19990820.html.zh-tw.xhtml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 8.19.’99. irresistible + + + + + + + +
    + +
    + + +

    8.19.’99. irresistible

    + +
    + +
    +

    irresistible

    +
    irresistible
    +a.
    +不可抵抗的;不能壓制的
    +
    +不可靠近的  一旦靠近  就會
    +崩解
    +
    +
    + +
    +

    illegal

    +
    illegal
    +a.
    +不合法的,非法的;違反規則的
    +
    +非法的  所以  不能存在
    +儘速消滅  以免為禍
    +
    +
    + +
    +

    無聲的聲音

    +
    我的聲音,在雨中奔馳、吶喊、呼喚,卻似沒
    +有人聽見一樣,雨,仍然靜靜地下著。
    +
    +
    + +
    +

    殘忍

    +
    莫名其妙
    +會為自己殘忍
    +也對別人殘忍
    +
    +把語言文字當作一把斧頭
    +狠烈烈地劈在某個人的心中
    +看著她流血
    +也看著自己流血
    +
    +惡狠狠地舔著自己的血,笑著
    +咀嚼著傷口抹鹽的痛覺
    +裝作若無其事地走開
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 7 | + 8 | + 9 | + 10 | + 11 | + 12 | + 13 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/20000816.html.zh-cn.html b/htdocs/imacat/writings-zh/20000816.html.zh-cn.html new file mode 120000 index 0000000..4f41deb --- /dev/null +++ b/htdocs/imacat/writings-zh/20000816.html.zh-cn.html @@ -0,0 +1 @@ +20000816.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/20000816.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/20000816.html.zh-cn.xhtml new file mode 100644 index 0000000..9b99d6d --- /dev/null +++ b/htdocs/imacat/writings-zh/20000816.html.zh-cn.xhtml @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 8.15.’00. 离职心情杂记 + + + + + + + +
    + +
    + + +

    8.15.’00. 离职心情杂记

    + +
    + +
    +

    (1)

    +
    很烦的时候
    +听著雨打在帘幕上的声音
    +好像一种折磨
    +心很想早点离开
    +可是不能
    +最后的两个小时
    +很难熬
    +
    +
    + +
    +

    (2)

    +
    喜欢下雨
    +因为下雨天只有我一个人
    +其实是没有原因的
    +只是因为那不是平常的天气
    +我喜欢不一样的天气
    +感觉很新鲜
    +让灵魂可以喘一口新鲜的空气
    +
    +
    + +
    +

    (3)

    +
    剩一个半小时
    +滴滴答答的雨像是为我倒数计时
    +雨声越来越小
    +心跳也越来越沉重
    +
    +
    + +
    +

    (4)

    +
    其实是想
    +我是想将所有事都做得很好的
    +不想让人家忌讳
    +不想让人家讨厌
    +不想让人家防著
    +可是.........
    +
    +我不行了
    +我还是要保护我自己
    +我已经没有力气再次受害了
    +好好把事情结束掉,干干净净,不带感情
    +不想多做,不想惹麻烦
    +就这样吧
    +
    +
    + +
    +

    (5)

    +
    就是这样
    +该是我的事,该不是我的事
    +还是只能清清楚楚,一干二净
    +以免责任不分,害了自己
    +
    +要收起柔软的心,铁下心来
    +嗯
    +
    +
    + +
    +

    (6)

    +
    深夜
    +一个人无法入眠
    +两个人也无法入眠
    +脑中反覆咀嚼著所受的伤
    +无法平静
    +无法找到一个适当的理由
    +可以说服自己
    +我赢了
    +我很快乐
    +
    +
    + +
    +

    (7)

    +
    希望下著雨
    +可是没有
    +一个人的时候
    +却无法快乐
    +不断告诉自己:我赢了
    +却快乐不起来
    +
    +
    + +
    +

    (8)

    +
    我是应该快乐的
    +因为我终於自由了
    +我是应该快乐的
    +因为我早日脱离了
    +我是应该快乐的
    +因为接下来就是我的假期
    +可是
    +我快乐不起来 快乐不起来 快乐不起来 快乐不起来 快乐不起来
    +快乐不起来 快乐不起来 快乐不起来 快乐不起来 快乐不起来
    +我不甘心
    +真的很不甘心
    +虽然是为了很无聊的小事在不甘心
    +可是我还是无法甘心
    +
    +
    + +
    +

    (9)

    +
    其实我不该不甘心的
    +其实我该 let go 的
    +放不放下手
    +一句话
    +去吧
    +多说无益
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 8 | + 9 | + 10 | + 11 | + 12 | + 13 | + 14 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/20000816.html.zh-tw.html b/htdocs/imacat/writings-zh/20000816.html.zh-tw.html new file mode 120000 index 0000000..94ae50d --- /dev/null +++ b/htdocs/imacat/writings-zh/20000816.html.zh-tw.html @@ -0,0 +1 @@ +20000816.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/20000816.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/20000816.html.zh-tw.xhtml new file mode 100644 index 0000000..02ab726 --- /dev/null +++ b/htdocs/imacat/writings-zh/20000816.html.zh-tw.xhtml @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 8.15.’00. 離職心情雜記 + + + + + + + +
    + +
    + + +

    8.15.’00. 離職心情雜記

    + +
    + +
    +

    (1)

    +
    很煩的時候
    +聽著雨打在簾幕上的聲音
    +好像一種折磨
    +心很想早點離開
    +可是不能
    +最後的兩個小時
    +很難熬
    +
    +
    + +
    +

    (2)

    +
    喜歡下雨
    +因為下雨天只有我一個人
    +其實是沒有原因的
    +只是因為那不是平常的天氣
    +我喜歡不一樣的天氣
    +感覺很新鮮
    +讓靈魂可以喘一口新鮮的空氣
    +
    +
    + +
    +

    (3)

    +
    剩一個半小時
    +滴滴答答的雨像是為我倒數計時
    +雨聲越來越小
    +心跳也越來越沉重
    +
    +
    + +
    +

    (4)

    +
    其實是想
    +我是想將所有事都做得很好的
    +不想讓人家忌諱
    +不想讓人家討厭
    +不想讓人家防著
    +可是.........
    +
    +我不行了
    +我還是要保護我自己
    +我已經沒有力氣再次受害了
    +好好把事情結束掉,乾乾淨淨,不帶感情
    +不想多做,不想惹麻煩
    +就這樣吧
    +
    +
    + +
    +

    (5)

    +
    就是這樣
    +該是我的事,該不是我的事
    +還是只能清清楚楚,一乾二淨
    +以免責任不分,害了自己
    +
    +要收起柔軟的心,鐵下心來
    +嗯
    +
    +
    + +
    +

    (6)

    +
    深夜
    +一個人無法入眠
    +兩個人也無法入眠
    +腦中反覆咀嚼著所受的傷
    +無法平靜
    +無法找到一個適當的理由
    +可以說服自己
    +我贏了
    +我很快樂
    +
    +
    + +
    +

    (7)

    +
    希望下著雨
    +可是沒有
    +一個人的時候
    +卻無法快樂
    +不斷告訴自己:我贏了
    +卻快樂不起來
    +
    +
    + +
    +

    (8)

    +
    我是應該快樂的
    +因為我終於自由了
    +我是應該快樂的
    +因為我早日脫離了
    +我是應該快樂的
    +因為接下來就是我的假期
    +可是
    +我快樂不起來 快樂不起來 快樂不起來 快樂不起來 快樂不起來
    +快樂不起來 快樂不起來 快樂不起來 快樂不起來 快樂不起來
    +我不甘心
    +真的很不甘心
    +雖然是為了很無聊的小事在不甘心
    +可是我還是無法甘心
    +
    +
    + +
    +

    (9)

    +
    其實我不該不甘心的
    +其實我該 let go 的
    +放不放下手
    +一句話
    +去吧
    +多說無益
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 8 | + 9 | + 10 | + 11 | + 12 | + 13 | + 14 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/20000826.html.zh-cn.html b/htdocs/imacat/writings-zh/20000826.html.zh-cn.html new file mode 120000 index 0000000..c0bbedf --- /dev/null +++ b/htdocs/imacat/writings-zh/20000826.html.zh-cn.html @@ -0,0 +1 @@ +20000826.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/20000826.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/20000826.html.zh-cn.xhtml new file mode 100644 index 0000000..6bad775 --- /dev/null +++ b/htdocs/imacat/writings-zh/20000826.html.zh-cn.xhtml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 8.25.’00. untie + + + + + + + +
    + +
    + + +

    8.25.’00. untie

    + +
    + +
    +

    (1)

    +
    无法想像的生活
    +到处充满著不可知的变数
    +很想想像一个无忧无虑、快乐的人
    +到底应该是什么样子
    +碰不到听不到在无法碰触的距离
    +以不到零点五公分的距离擦身而过
    +是我的生活
    +与你的生活
    +
    +
    + +
    +

    (2)

    +
    预期中
    +你应该是这个样子的
    +像我的世界里的某一个小点
    +在不经意的空间里扩散
    +无法掌握那样一个小点
    +就像我我无掌握自己一样
    +距离
    +很遥远
    +
    +
    + +
    +

    (3)

    +
    空气中
    +有股不存在的熟悉气息
    +搅动著某种
    +分子分母竞相扩张的无限赛跑
    +直到空气再也承受不住
    +而断裂
    +在距离胸前零点零零公厘的地方
    +用力割断
    +近距离撕毁的风压的拉力
    +让我窒息而死
    +
    +
    + +
    +

    (4)

    +
    忽然想要
    +流泻出很多很多的悲伤
    +那是我很久很久以前的悲伤
    +熟悉的气味却又非常遥远
    +我哭不出来
    +因为周围还很危险
    +那是我很久很久以前灵魂的警觉性
    +对危险环境天生的嗅觉
    +
    +
    + +
    +

    (5)

    +
    想让生活
    +扯裂
    +撕裂
    +可是已经太厚了
    +难以拉扯
    +距离有某种遥远的东西
    +在我身边拉扯
    +渐渐把我拖回
    +棺木里面的中间的核心
    +的地方
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 9 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/20000826.html.zh-tw.html b/htdocs/imacat/writings-zh/20000826.html.zh-tw.html new file mode 120000 index 0000000..061ef58 --- /dev/null +++ b/htdocs/imacat/writings-zh/20000826.html.zh-tw.html @@ -0,0 +1 @@ +20000826.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/20000826.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/20000826.html.zh-tw.xhtml new file mode 100644 index 0000000..58fb4a9 --- /dev/null +++ b/htdocs/imacat/writings-zh/20000826.html.zh-tw.xhtml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 8.25.’00. untie + + + + + + + +
    + +
    + + +

    8.25.’00. untie

    + +
    + +
    +

    (1)

    +
    無法想像的生活
    +到處充滿著不可知的變數
    +很想想像一個無憂無慮、快樂的人
    +到底應該是什麼樣子
    +碰不到聽不到在無法碰觸的距離
    +以不到零點五公分的距離擦身而過
    +是我的生活
    +與妳的生活
    +
    +
    + +
    +

    (2)

    +
    預期中
    +妳應該是這個樣子的
    +像我的世界裏的某一個小點
    +在不經意的空間裏擴散
    +無法掌握那樣一個小點
    +就像我我無掌握自己一樣
    +距離
    +很遙遠
    +
    +
    + +
    +

    (3)

    +
    空氣中
    +有股不存在的熟悉氣息
    +攪動著某種
    +分子分母競相擴張的無限賽跑
    +直到空氣再也承受不住
    +而斷裂
    +在距離胸前零點零零公釐的地方
    +用力割斷
    +近距離撕毀的風壓的拉力
    +讓我窒息而死
    +
    +
    + +
    +

    (4)

    +
    忽然想要
    +流瀉出很多很多的悲傷
    +那是我很久很久以前的悲傷
    +熟悉的氣味卻又非常遙遠
    +我哭不出來
    +因為周圍還很危險
    +那是我很久很久以前靈魂的警覺性
    +對危險環境天生的嗅覺
    +
    +
    + +
    +

    (5)

    +
    想讓生活
    +扯裂
    +撕裂
    +可是已經太厚了
    +難以拉扯
    +距離有某種遙遠的東西
    +在我身邊拉扯
    +漸漸把我拖回
    +棺木裏面的中間的核心
    +的地方
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 9 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/20001217.html.zh-cn.html b/htdocs/imacat/writings-zh/20001217.html.zh-cn.html new file mode 120000 index 0000000..d0ac65d --- /dev/null +++ b/htdocs/imacat/writings-zh/20001217.html.zh-cn.html @@ -0,0 +1 @@ +20001217.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/20001217.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/20001217.html.zh-cn.xhtml new file mode 100644 index 0000000..0677908 --- /dev/null +++ b/htdocs/imacat/writings-zh/20001217.html.zh-cn.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 12.16.’00. 换车 + + + + + + + +
    + +
    + + +

    12.16.’00. 换车

    + +
    + +
    +

    (1)

    +
    回去吧
    +像是在对自己呼喊著
    +从长久的梦中慢慢醒来
    +睁开眼是温暖的阳光
    +虽然还看不清楚
    +可是依悉已经看到眼前的路
    +
    +
    + +
    +

    (2)

    +
    从遥远中酥醒
    +有一点痛苦的是
    +自己的怯懦
    +我将这样怯懦地过了一生呢
    +还是不呢?
    +
    +
    + +
    +

    (3)

    +
    也许,从昏睡中清醒的是,
    +我有点摸索到了自己的路,
    +虽然模糊,
    +但也是个起点,一个端子,
    +可以走进未知的旅程。
    +
    +
    + +
    +

    (4)

    +
    那么,何时才能找到我的答案呢?
    +不知道。只是寻找。
    +但我已经无法抑制兴奋的悸动,
    +对终点景像的幻想,
    +已经盈满了我的脑,我的心。
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 16 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/20001217.html.zh-tw.html b/htdocs/imacat/writings-zh/20001217.html.zh-tw.html new file mode 120000 index 0000000..2f04b70 --- /dev/null +++ b/htdocs/imacat/writings-zh/20001217.html.zh-tw.html @@ -0,0 +1 @@ +20001217.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/20001217.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/20001217.html.zh-tw.xhtml new file mode 100644 index 0000000..28f1dc1 --- /dev/null +++ b/htdocs/imacat/writings-zh/20001217.html.zh-tw.xhtml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 12.16.’00. 換車 + + + + + + + +
    + +
    + + +

    12.16.’00. 換車

    + +
    + +
    +

    (1)

    +
    回去吧
    +像是在對自己呼喊著
    +從長久的夢中慢慢醒來
    +睜開眼是溫暖的陽光
    +雖然還看不清楚
    +可是依悉已經看到眼前的路
    +
    +
    + +
    +

    (2)

    +
    從遙遠中酥醒
    +有一點痛苦的是
    +自己的怯懦
    +我將這樣怯懦地過了一生呢
    +還是不呢?
    +
    +
    + +
    +

    (3)

    +
    也許,從昏睡中清醒的是,
    +我有點摸索到了自己的路,
    +雖然模糊,
    +但也是個起點,一個端子,
    +可以走進未知的旅程。
    +
    +
    + +
    +

    (4)

    +
    那麼,何時才能找到我的答案呢?
    +不知道。只是尋找。
    +但我已經無法抑制興奮的悸動,
    +對終點景像的幻想,
    +已經盈滿了我的腦,我的心。
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 16 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/20010224.html.zh-cn.html b/htdocs/imacat/writings-zh/20010224.html.zh-cn.html new file mode 120000 index 0000000..135b6c7 --- /dev/null +++ b/htdocs/imacat/writings-zh/20010224.html.zh-cn.html @@ -0,0 +1 @@ +20010224.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/20010224.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/20010224.html.zh-cn.xhtml new file mode 100644 index 0000000..b6a66bb --- /dev/null +++ b/htdocs/imacat/writings-zh/20010224.html.zh-cn.xhtml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 2.23.’01. 笨 + + + + + + + +
    + +
    + + +

    2.23.’01.

    + +
    + +
    +

    (1)

    +
    我是很笨的
    +很菜的
    +我知道
    +老是把事情搞砸
    +苍惶逃开
    +
    +
    + +
    +

    (2)

    +
    闭上眼睛,想的都是你
    +站在你身边,闻到的都是你的体味
    +我到底是怎么了
    +无法和你好好说话
    +无法正视你的眼神
    +一开口就开始结巴
    +你一来就不知道该说些什么
    +好想逃掉
    +转移话题吧
    +神啊
    +
    +
    + +
    +

    (3)

    +
    你一定觉得我很奇怪吧
    +那么拼命想约你出去
    +突然又对你那么冷漠
    +我没办法
    +我就是没办法
    +明知道这样会把气氛弄得更尴尬
    +可是就是没办法
    +
    +
    + +
    +

    (4)

    +
    我就是这么可笑
    +这么愚蠢
    +不要笑我
    +我已经被很多人笑过了
    +
    +
    + +
    +

    (5)

    +
    所以,如果你觉得我对你很冷漠
    +那就是我喜欢上你了
    +你就放心这样想吧
    +因为
    +愚蠢又乡愿的我
    +是不会对任何人冷漠的
    +除了喜欢的人
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 16 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/20010224.html.zh-tw.html b/htdocs/imacat/writings-zh/20010224.html.zh-tw.html new file mode 120000 index 0000000..2174edd --- /dev/null +++ b/htdocs/imacat/writings-zh/20010224.html.zh-tw.html @@ -0,0 +1 @@ +20010224.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/20010224.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/20010224.html.zh-tw.xhtml new file mode 100644 index 0000000..df3bfc4 --- /dev/null +++ b/htdocs/imacat/writings-zh/20010224.html.zh-tw.xhtml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 2.23.’01. 笨 + + + + + + + +
    + +
    + + +

    2.23.’01.

    + +
    + +
    +

    (1)

    +
    我是很笨的
    +很菜的
    +我知道
    +老是把事情搞砸
    +蒼惶逃開
    +
    +
    + +
    +

    (2)

    +
    閉上眼睛,想的都是妳
    +站在妳身邊,聞到的都是妳的體味
    +我到底是怎麼了
    +無法和妳好好說話
    +無法正視妳的眼神
    +一開口就開始結巴
    +妳一來就不知道該說些什麼
    +好想逃掉
    +轉移話題吧
    +神啊
    +
    +
    + +
    +

    (3)

    +
    妳一定覺得我很奇怪吧
    +那麼拼命想約妳出去
    +突然又對妳那麼冷漠
    +我沒辦法
    +我就是沒辦法
    +明知道這樣會把氣氛弄得更尷尬
    +可是就是沒辦法
    +
    +
    + +
    +

    (4)

    +
    我就是這麼可笑
    +這麼愚蠢
    +不要笑我
    +我已經被很多人笑過了
    +
    +
    + +
    +

    (5)

    +
    所以,如果妳覺得我對妳很冷漠
    +那就是我喜歡上妳了
    +妳就放心這樣想吧
    +因為
    +愚蠢又鄉愿的我
    +是不會對任何人冷漠的
    +除了喜歡的人
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 16 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/20130527.html.zh-cn.html b/htdocs/imacat/writings-zh/20130527.html.zh-cn.html new file mode 120000 index 0000000..dd8567e --- /dev/null +++ b/htdocs/imacat/writings-zh/20130527.html.zh-cn.html @@ -0,0 +1 @@ +20130527.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/20130527.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/20130527.html.zh-cn.xhtml new file mode 100644 index 0000000..27c3694 --- /dev/null +++ b/htdocs/imacat/writings-zh/20130527.html.zh-cn.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + +诗 5.26.’13. 散佚的爱与记忆 + + + + + + + +
    + +
    + + +

    5.26.’13. 散佚的爱与记忆

    + +
    + +
    +

    爱,只存在无意识之中。

    +
    曾经以为我不可能忘记你,
    +每天晚上梦里都是你,
    +走在路上眼神寻找的都是你的影子,
    +直到有一天,意识到自己每天都在想你,
    +然后我就开始忘记你了。
    +
    +
    + +
    +

    啊,原来是这样啊。

    +
    以为自己忘不了你,以为这份爱会埋在心里一辈子,
    +瞬间的幻灭后,
    +就突然间不爱你了。
    +埋藏多年的爱,抵不过一瞬间的幻灭。
    +
    +
    + +
    +

    不爱。

    +
    以为自己念旧固执,以为自己不会不爱,
    +原来不爱也是这么容易的事,
    +只是意识中一瞬间的事而已。
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 16 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/20130527.html.zh-tw.html b/htdocs/imacat/writings-zh/20130527.html.zh-tw.html new file mode 120000 index 0000000..d073e55 --- /dev/null +++ b/htdocs/imacat/writings-zh/20130527.html.zh-tw.html @@ -0,0 +1 @@ +20130527.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/20130527.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/20130527.html.zh-tw.xhtml new file mode 100644 index 0000000..9c26d9a --- /dev/null +++ b/htdocs/imacat/writings-zh/20130527.html.zh-tw.xhtml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + +詩 5.26.’13. 散佚的愛與記憶 + + + + + + + +
    + +
    + + +

    5.26.’13. 散佚的愛與記憶

    + +
    + +
    +

    愛,只存在無意識之中。

    +
    曾經以為我不可能忘記妳,
    +每天晚上夢裏都是妳,
    +走在路上眼神尋找的都是妳的影子,
    +直到有一天,意識到自己每天都在想妳,
    +然後我就開始忘記妳了。
    +
    +
    + +
    +

    啊,原來是這樣啊。

    +
    以為自己忘不了妳,以為這份愛會埋在心裏一輩子,
    +瞬間的幻滅後,
    +就突然間不愛妳了。
    +埋藏多年的愛,抵不過一瞬間的幻滅。
    +
    +
    + +
    +

    不愛。

    +
    以為自己念舊固執,以為自己不會不愛,
    +原來不愛也是這麼容易的事,
    +只是意識中一瞬間的事而已。
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 16 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/20160128.html.zh-cn.html b/htdocs/imacat/writings-zh/20160128.html.zh-cn.html new file mode 120000 index 0000000..73f7a3b --- /dev/null +++ b/htdocs/imacat/writings-zh/20160128.html.zh-cn.html @@ -0,0 +1 @@ +20160128.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/20160128.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/20160128.html.zh-cn.xhtml new file mode 100644 index 0000000..ef457fe --- /dev/null +++ b/htdocs/imacat/writings-zh/20160128.html.zh-cn.xhtml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + +诗 1.27.’16. 剥开 + + + + + + + +
    + +
    + + +

    1.27.’16. 剥开

    + +
    + +
    +

    剥开

    +
    华美的蛋壳被剥开
    +倾倒而出的只有混乱
    +下流卑鄙的欲望
    +不连贯的语言
    +不知道什么是什么
    +
    +混乱堵塞在胸口
    +无法言语
    +
    +有一点点高兴
    +因为还活著
    +
    +
    + +
    + +
    +
    + 目录 | + 第一篇 | + 前一篇 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 16 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/20160128.html.zh-tw.html b/htdocs/imacat/writings-zh/20160128.html.zh-tw.html new file mode 120000 index 0000000..03a3eab --- /dev/null +++ b/htdocs/imacat/writings-zh/20160128.html.zh-tw.html @@ -0,0 +1 @@ +20160128.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/20160128.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/20160128.html.zh-tw.xhtml new file mode 100644 index 0000000..7713a71 --- /dev/null +++ b/htdocs/imacat/writings-zh/20160128.html.zh-tw.xhtml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + +詩 1.27.’16. 剝開 + + + + + + + +
    + +
    + + +

    1.27.’16. 剝開

    + +
    + +
    +

    剝開

    +
    華美的蛋殼被剝開
    +傾倒而出的只有混亂
    +下流卑鄙的慾望
    +不連貫的語言
    +不知道什麼是什麼
    +
    +混亂堵塞在胸口
    +無法言語
    +
    +有一點點高興
    +因為還活著
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一篇 | + 前一篇 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 16 | + 下一篇 | + 最新篇 +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/index.html.zh-cn.html b/htdocs/imacat/writings-zh/index.html.zh-cn.html new file mode 120000 index 0000000..5ee9c39 --- /dev/null +++ b/htdocs/imacat/writings-zh/index.html.zh-cn.html @@ -0,0 +1 @@ +index.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/index.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/index.html.zh-cn.xhtml new file mode 100644 index 0000000..160a5be --- /dev/null +++ b/htdocs/imacat/writings-zh/index.html.zh-cn.xhtml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + +

    + +
    + +

    以下不按标题分类,而按日期分类。许多日期是后来推算的,有点疑问。

    + +

    1.27.’16. 剝開

    +

    剝開

    + + +

    5.26.’13. 散佚的愛與記憶

    +

    一點點記憶,一點點遺忘,一點點幻滅,一點點其他。

    + + +

    2.23.’01.

    +

    我是很笨的。

    + + +

    12.16.’00. 換車

    +

    換車。轉換跑道。進入另一個旅程。

    + + +

    8.25.’00. untie

    +

    難得換工作間的空檔時日,自言自語寫的胡說八道。很難形容自己在寫些什麼,跟生活有關,跟周遭的人有關,跟自己有關。

    + + +

    8.15.’00. 離職心情雜記

    +

    2000 年 8 月 15 日離開益華,在益華做滿一年整,離開時清清楚楚,光明磊落,卻被老闆當眾難堪。深夜,無法入眠。

    + + +

    8.19.’99. irresistible

    +

    irresistible 不可抵抗的;不能壓制的

    + + +

    4.28.’98.

    +

    最新的作品。

    + + +

    3.16.’98. 冰河

    +

    寫給某個不存在的女人。我恨她。

    + + +

    2.12.’98.

    +

    上臺北後,為了換電腦的事跑了好幾天光華商場,突然發現好幾天沒寫了。情人節前夕的一些實驗。其中有一篇實驗性很強。

    + + +

    2.5.’98.

    +

    這也是在高雄寫的。那晚和倫倫通電話,有感。另一首是給某個鴿子王。那晚在 Channel[V] 聽了很多遍敬原慎之的新歌「蒙太奇」,很喜歡日本流行樂歌詞的文字,寫出來就這樣了。文字有點商業化。

    + + +

    1.25.’98.

    +

    這是在高雄作的,因為蝦蝦的暴力威脅,所以只有貼在蝦蝦的東海大度山之戀 motss 板上,沒有貼到淡江蛋捲的 les 板。

    + + +

    1.8.’98. 死亡昆蟲

    +

    很多人喜歡這一系列,尤其是蚊子。以此系列紀念某人,這是在跟她的聊天中起的靈感。

    + + +

    9.15.’97.

    +

    一半是在高雄回臺北前在小港機場候機室無聊作的,另一半是上了臺北才作的。我生日剛過。

    + + +

    9.2.’97. 分岔

    +

    那時去莫斯科玩。這是在漢城飛莫斯科的韓航飛機上無聊坐的。那時候真的無聊到在飛機上剪分岔。

    + + +

    7.30.’97.

    +

    本來寫在大陸社留言本上的,覺得不錯,就抄到網路上。標題只有數字,而且編號還弄錯。不過弄錯的效果也不錯,就沒有改。發表在臺大椰林詩板。

    +
    + +
    + +

    终於把自己的中文诗,存进资料库了。

    + +

    中文诗,一直是整个旅舍依玛中,我最不愿意去面对的部份。里面有太多的不堪,夹杂纠结的感动、自负、自卑。我其实没有资格被叫做诗人。我从来也没有出过一本诗集,只是在最脆弱的时候,灵魂没有出口,只能靠写字来发泄、自我治疗;有时候觉得自己太久没写东西,舔称为诗人,於是就开始凭空瞎掰、乱写。这样乱七八糟的我,竟然也会被人称为网路诗人。每每在网路上看到人家给我这样的称号,就很汗颜、害怕。

    + +

    把自己的网站资料库化的过程中,不免又要碰及这一部份的自我。然而,奇怪地,这一次回头看,心情却出奇地平静。只觉得眼前是一堆平凡的文字而已,既不好,也不坏。说是诗有点过誉,不过所谓到处称诗人的名人,写的东西也不怎么样,所以称我这些文字为诗,也不至於过誉。

    + +

    为什么会这么平静呢?我也不清楚。

    + +

    从最后一篇到现在,事隔五年了。这五年来,我有什么成长? MonicaSelima ,两个完全自己写出来的庞大网站管理系统,五个自由软体专案。上网晃晃,偶尔会有人叫住我:鼎鼎大名的依玛猫,久仰久仰。我除了答:过誉过誉外,也不知道要答什么。我也不知道我到底做了什么大事,大名在哪里。 Selima 写了这么多年才稍微有个样子,想做的椰子拉子也没做出来,想加入的 TLDP 计划也无声无息, X.509 凭证教学英译了那么多年也译不出来,刊登要找兼差到现在也没有什么适合的,还到研考会的网站上去和人家吵架。用一事无成来形容,其实所去不远。

    + +

    回头看看五年前的自己,似乎可以好好看待那个不好也不坏的自己了。没有了纠结的感动、自负、自卑、羞愧的情感交杂。连感动也消失无踪了。反正就是这样。嗯。

    + +

    唔,好吧,说实话,其实是觉得还不错啦,呵呵。 ^_*'

    + +
    依玛猫 4.23.’06
    + +

    (你可以阅读之前的前言。)

    + +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/index.html.zh-tw.html b/htdocs/imacat/writings-zh/index.html.zh-tw.html new file mode 120000 index 0000000..6c1b76e --- /dev/null +++ b/htdocs/imacat/writings-zh/index.html.zh-tw.html @@ -0,0 +1 @@ +index.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/index.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/index.html.zh-tw.xhtml new file mode 100644 index 0000000..08bc943 --- /dev/null +++ b/htdocs/imacat/writings-zh/index.html.zh-tw.xhtml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + +

    + +
    + +

    以下不按標題分類,而按日期分類。許多日期是後來推算的,有點疑問。

    + +

    1.27.’16. 剝開

    +

    剝開

    + + +

    5.26.’13. 散佚的愛與記憶

    +

    一點點記憶,一點點遺忘,一點點幻滅,一點點其他。

    + + +

    2.23.’01.

    +

    我是很笨的。

    + + +

    12.16.’00. 換車

    +

    換車。轉換跑道。進入另一個旅程。

    + + +

    8.25.’00. untie

    +

    難得換工作間的空檔時日,自言自語寫的胡說八道。很難形容自己在寫些什麼,跟生活有關,跟周遭的人有關,跟自己有關。

    + + +

    8.15.’00. 離職心情雜記

    +

    2000 年 8 月 15 日離開益華,在益華做滿一年整,離開時清清楚楚,光明磊落,卻被老闆當眾難堪。深夜,無法入眠。

    + + +

    8.19.’99. irresistible

    +

    irresistible 不可抵抗的;不能壓制的

    + + +

    4.28.’98.

    +

    最新的作品。

    + + +

    3.16.’98. 冰河

    +

    寫給某個不存在的女人。我恨她。

    + + +

    2.12.’98.

    +

    上臺北後,為了換電腦的事跑了好幾天光華商場,突然發現好幾天沒寫了。情人節前夕的一些實驗。其中有一篇實驗性很強。

    + + +

    2.5.’98.

    +

    這也是在高雄寫的。那晚和倫倫通電話,有感。另一首是給某個鴿子王。那晚在 Channel[V] 聽了很多遍敬原慎之的新歌「蒙太奇」,很喜歡日本流行樂歌詞的文字,寫出來就這樣了。文字有點商業化。

    + + +

    1.25.’98.

    +

    這是在高雄作的,因為蝦蝦的暴力威脅,所以只有貼在蝦蝦的東海大度山之戀 motss 板上,沒有貼到淡江蛋捲的 les 板。

    + + +

    1.8.’98. 死亡昆蟲

    +

    很多人喜歡這一系列,尤其是蚊子。以此系列紀念某人,這是在跟她的聊天中起的靈感。

    + + +

    9.15.’97.

    +

    一半是在高雄回臺北前在小港機場候機室無聊作的,另一半是上了臺北才作的。我生日剛過。

    + + +

    9.2.’97. 分岔

    +

    那時去莫斯科玩。這是在漢城飛莫斯科的韓航飛機上無聊坐的。那時候真的無聊到在飛機上剪分岔。

    + + +

    7.30.’97.

    +

    本來寫在大陸社留言本上的,覺得不錯,就抄到網路上。標題只有數字,而且編號還弄錯。不過弄錯的效果也不錯,就沒有改。發表在臺大椰林詩板。

    +
    + +
    + +

    終於把自己的中文詩,存進資料庫了。

    + +

    中文詩,一直是整個旅舍依瑪中,我最不願意去面對的部份。裏面有太多的不堪,夾雜糾結的感動、自負、自卑。我其實沒有資格被叫做詩人。我從來也沒有出過一本詩集,只是在最脆弱的時候,靈魂沒有出口,只能靠寫字來發洩、自我治療;有時候覺得自己太久沒寫東西,舔稱為詩人,於是就開始憑空瞎掰、亂寫。這樣亂七八糟的我,竟然也會被人稱為網路詩人。每每在網路上看到人家給我這樣的稱號,就很汗顏、害怕。

    + +

    把自己的網站資料庫化的過程中,不免又要碰及這一部份的自我。然而,奇怪地,這一次回頭看,心情卻出奇地平靜。只覺得眼前是一堆平凡的文字而已,既不好,也不壞。說是詩有點過譽,不過所謂到處稱詩人的名人,寫的東西也不怎麼樣,所以稱我這些文字為詩,也不至於過譽。

    + +

    為什麼會這麼平靜呢?我也不清楚。

    + +

    從最後一篇到現在,事隔五年了。這五年來,我有什麼成長? MonicaSelima ,兩個完全自己寫出來的龐大網站管理系統,五個自由軟體專案。上網晃晃,偶爾會有人叫住我:鼎鼎大名的依瑪貓,久仰久仰。我除了答:過譽過譽外,也不知道要答什麼。我也不知道我到底做了什麼大事,大名在哪裏。 Selima 寫了這麼多年才稍微有個樣子,想做的椰子拉子也沒做出來,想加入的 TLDP 計劃也無聲無息, X.509 憑證教學英譯了那麼多年也譯不出來,刊登要找兼差到現在也沒有什麼適合的,還到研考會的網站上去和人家吵架。用一事無成來形容,其實所去不遠。

    + +

    回頭看看五年前的自己,似乎可以好好看待那個不好也不壞的自己了。沒有了糾結的感動、自負、自卑、羞愧的情感交雜。連感動也消失無蹤了。反正就是這樣。嗯。

    + +

    唔,好吧,說實話,其實是覺得還不錯啦,呵呵。 ^_*'

    + +
    依瑪貓 4.23.’06
    + +

    (妳可以閱讀之前的前言。)

    + +
    + +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/latest.html.zh-cn.html b/htdocs/imacat/writings-zh/latest.html.zh-cn.html new file mode 120000 index 0000000..7be458a --- /dev/null +++ b/htdocs/imacat/writings-zh/latest.html.zh-cn.html @@ -0,0 +1 @@ +latest.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/latest.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/latest.html.zh-cn.xhtml new file mode 120000 index 0000000..73f7a3b --- /dev/null +++ b/htdocs/imacat/writings-zh/latest.html.zh-cn.xhtml @@ -0,0 +1 @@ +20160128.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/latest.html.zh-tw.html b/htdocs/imacat/writings-zh/latest.html.zh-tw.html new file mode 120000 index 0000000..f642bdf --- /dev/null +++ b/htdocs/imacat/writings-zh/latest.html.zh-tw.html @@ -0,0 +1 @@ +latest.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/latest.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/latest.html.zh-tw.xhtml new file mode 120000 index 0000000..03a3eab --- /dev/null +++ b/htdocs/imacat/writings-zh/latest.html.zh-tw.xhtml @@ -0,0 +1 @@ +20160128.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/oldintro01.html.zh-cn.html b/htdocs/imacat/writings-zh/oldintro01.html.zh-cn.html new file mode 120000 index 0000000..6cfc9e4 --- /dev/null +++ b/htdocs/imacat/writings-zh/oldintro01.html.zh-cn.html @@ -0,0 +1 @@ +oldintro01.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/oldintro01.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/oldintro01.html.zh-cn.xhtml new file mode 100644 index 0000000..39db9d9 --- /dev/null +++ b/htdocs/imacat/writings-zh/oldintro01.html.zh-cn.xhtml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + +

    + +

    我的诗。

    + +

    终於有一个地方不用写英文翻译了。太好了~! ~~^_^~~

    + +

    ,其实是很丢脸的。在硬碟里保存最早的诗作是 8.23.’93 的作品,两首英文诗。那年我大二暑假,第一次办休学,没升上大三。那年暑假,丽香走了,我的初恋。好痛苦,几次想自杀,整个暑假都像游魂般濒临死亡,休学反而变成微不足道的小事。那两首是在精神崩溃边缘写的,英文 Windows 3.1 Write ,只有草草数行模糊狂乱的句子。

    + +

    ’94 年经历一段写作小说∕杂文的黄金期。那时和丽香分手半年了,每周固定去找吴英彰老师谘商(现在的台北市教育局长,那时是台大辅导中心主任),开始从失恋中走出来。我每周写信给丽香,回音都很令人沮丧。老师鼓励我多写,但信交给他,不要寄出去。当时看到台大文学奖海报,想起高中时对我的笔蛮自傲的,就试著写了两篇:失恋记事,交错式的杂感短篇小说;预谋狂想曲,联想式的杂文。那是我第一次尝试在文章中加入。现在看起来都太不成熟了。

    + +

    那以后的半年间,我突然开始疯了一样不停地写作,像是要把对丽香的热情全都挤出来。我不断地写给她的信,写小说,和给英文老师的作业。英文老师对我很好,学期作业只要三篇,她答应收我六篇。它们即使从现在的眼光来看都很棒。(其中最长最好的,我收在英文作品网页里。)从 ’94 年的三月到五月间,我总共写出了 17 篇中英文短小∕杂文∕剧本,最长的前后篇加起来有四万多字。

    + +

    此后认识了 oni ,和 oni 在一起,好一阵子没写出完整的东西,只有几段无题的破碎段落。

    + +

    真正开始写诗是从 ’’97 年的七月底。这时候已经和 oni 分手了近一年,开始和小紫在一起。 oni 说过我的文字有无法跳脱的模式,我却找不出来。那个暑假读了夏宇的诗集,在序中突然发现了新的文字使用方式—拼贴。我仍然看不懂夏宇文字里的颜色。不过无所谓。我有我可以拼贴的素材。我开始做一些尝试,直到现在。

    + +

    直到现在,我还是觉得自称写诗是一件很丢脸的事。诗人似乎是很高尚令人肃然起敬的,可是我其实没有那么好。常常我只是把很多灵魂的排泻物藉由文字来倾倒而已。我很讨厌诗写得很正气凛然、光明正大的人,尤其是写古诗的人。诗人该有她对生命和世界的敏感度的。

    + +

    我说太多了。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/oldintro01.html.zh-tw.html b/htdocs/imacat/writings-zh/oldintro01.html.zh-tw.html new file mode 120000 index 0000000..bbec8ae --- /dev/null +++ b/htdocs/imacat/writings-zh/oldintro01.html.zh-tw.html @@ -0,0 +1 @@ +oldintro01.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/oldintro01.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/oldintro01.html.zh-tw.xhtml new file mode 100644 index 0000000..d8edceb --- /dev/null +++ b/htdocs/imacat/writings-zh/oldintro01.html.zh-tw.xhtml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + +

    + +

    我的詩。

    + +

    終於有一個地方不用寫英文翻譯了。太好了~! ~~^_^~~

    + +

    ,其實是很丟臉的。在硬碟裡保存最早的詩作是 8.23.’93 的作品,兩首英文詩。那年我大二暑假,第一次辦休學,沒升上大三。那年暑假,麗香走了,我的初戀。好痛苦,幾次想自殺,整個暑假都像遊魂般瀕臨死亡,休學反而變成微不足道的小事。那兩首是在精神崩潰邊緣寫的,英文 Windows 3.1 Write ,只有草草數行模糊狂亂的句子。

    + +

    ’94 年經歷一段寫作小說∕雜文的黃金期。那時和麗香分手半年了,每週固定去找吳英彰老師諮商(現在的臺北市教育局長,那時是臺大輔導中心主任),開始從失戀中走出來。我每週寫信給麗香,回音都很令人沮喪。老師鼓勵我多寫,但信交給他,不要寄出去。當時看到臺大文學獎海報,想起高中時對我的筆蠻自傲的,就試著寫了兩篇:失戀記事,交錯式的雜感短篇小說;預謀狂想曲,聯想式的雜文。那是我第一次嚐試在文章中加入。現在看起來都太不成熟了。

    + +

    那以後的半年間,我突然開始瘋了一樣不停地寫作,像是要把對麗香的熱情全都擠出來。我不斷地寫給她的信,寫小說,和給英文老師的作業。英文老師對我很好,學期作業只要三篇,她答應收我六篇。它們即使從現在的眼光來看都很棒。(其中最長最好的,我收在英文作品網頁裡。)從 ’94 年的三月到五月間,我總共寫出了 17 篇中英文短小∕雜文∕劇本,最長的前後篇加起來有四萬多字。

    + +

    此後認識了 oni ,和 oni 在一起,好一陣子沒寫出完整的東西,只有幾段無題的破碎段落。

    + +

    真正開始寫詩是從 ’’97 年的七月底。這時候已經和 oni 分手了近一年,開始和小紫在一起。 oni 說過我的文字有無法跳脫的模式,我卻找不出來。那個暑假讀了夏宇的詩集,在序中突然發現了新的文字使用方式—拼貼。我仍然看不懂夏宇文字裡的顏色。不過無所謂。我有我可以拼貼的素材。我開始做一些嚐試,直到現在。

    + +

    直到現在,我還是覺得自稱寫詩是一件很丟臉的事。詩人似乎是很高尚令人肅然起敬的,可是我其實沒有那麼好。常常我只是把很多靈魂的排瀉物藉由文字來傾倒而已。我很討厭詩寫得很正氣凜然、光明正大的人,尤其是寫古詩的人。詩人該有她對生命和世界的敏感度的。

    + +

    我說太多了。

    + +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/oldintro02.html.zh-cn.html b/htdocs/imacat/writings-zh/oldintro02.html.zh-cn.html new file mode 120000 index 0000000..7ee989d --- /dev/null +++ b/htdocs/imacat/writings-zh/oldintro02.html.zh-cn.html @@ -0,0 +1 @@ +oldintro02.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/oldintro02.html.zh-cn.xhtml b/htdocs/imacat/writings-zh/oldintro02.html.zh-cn.xhtml new file mode 100644 index 0000000..54aa87a --- /dev/null +++ b/htdocs/imacat/writings-zh/oldintro02.html.zh-cn.xhtml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + +

    + +

    改版,把我的诗的前言也改掉好了。

    + +

    这么说来,这次的改版,真的很彻底。

    + +

    这样也好。这样才好。其实这里的东西,虽然有好几篇不错的,可是也有好几篇在现在看来,摆明了是无病呻吟嘛!

    + +

    其实本来就知道自己在无病呻吟,可是自己一直不承认而已。

    + +

    承认了以后,心底舒坦多了。其实诗和墙上的涂鸦差别不大的:不规则的文字,有片段,有抄袭模仿,有拼贴。不同人的涂鸦摆在一起,又形成了新的感受。诗也是,其实很难去强定诗是什么意义的,会随著时空,随著心情,随著不同人在看,而有所改变。

    + +

    从某个程度上来说,我说话时像诗一样:我永远也找不到一个洽当的形容词来形容我的意思。我害怕随著人类滥用而意义变质的文字,所以我想尽办法避开常用的词汇,寻找更能精确表达我意思的词汇。到最后我往往词穷,说出了一堆太过抽象没人听得懂的话。

    + +

    就像气质,我很怕去用这个词,因为每个人对气质的定义都不大一样。我不喜欢去谈气质这种含义不精确的词。

    + +

    我的困境,很像诗的困境:诗人对文字永远也不满意,永远在追求新的文字。因为害怕感觉会随著文字而定形,而僵化,无法真正贴近自己的感觉。这是个永无止境的矛盾,因为定形的文字永远会僵化,会转变,会死亡,而诗人的感情是活生生的,是跳动的,是文字永远也无法补捉的。

    + +

    那么,诗人其实最好的事,是闭嘴。

    + +

    可是,诗人不能闭嘴。因为诗人是自恋的,是敏感的,一个小小的波动,都会使得纤细的感情产生千万碎片。如果无法说出口,喧泄出来,那诗人就会被淹没在自己的情感中而窒息,而死亡。

    + +

    因此,你就看到了,这些又像呕吐物又像诗的腐烂文字。这是诗人的心血,也是粪土。

    + +

    (你可以阅读之前的前言。)

    + +
    + +
    + + + + diff --git a/htdocs/imacat/writings-zh/oldintro02.html.zh-tw.html b/htdocs/imacat/writings-zh/oldintro02.html.zh-tw.html new file mode 120000 index 0000000..f63a690 --- /dev/null +++ b/htdocs/imacat/writings-zh/oldintro02.html.zh-tw.html @@ -0,0 +1 @@ +oldintro02.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/imacat/writings-zh/oldintro02.html.zh-tw.xhtml b/htdocs/imacat/writings-zh/oldintro02.html.zh-tw.xhtml new file mode 100644 index 0000000..22693c8 --- /dev/null +++ b/htdocs/imacat/writings-zh/oldintro02.html.zh-tw.xhtml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + +

    + +

    改版,把我的詩的前言也改掉好了。

    + +

    這麼說來,這次的改版,真的很徹底。

    + +

    這樣也好。這樣才好。其實這裏的東西,雖然有好幾篇不錯的,可是也有好幾篇在現在看來,擺明了是無病呻吟嘛!

    + +

    其實本來就知道自己在無病呻吟,可是自己一直不承認而已。

    + +

    承認了以後,心底舒坦多了。其實詩和牆上的塗鴉差別不大的:不規則的文字,有片段,有抄襲模仿,有拼貼。不同人的塗鴉擺在一起,又形成了新的感受。詩也是,其實很難去強定詩是什麼意義的,會隨著時空,隨著心情,隨著不同人在看,而有所改變。

    + +

    從某個程度上來說,我說話時像詩一樣:我永遠也找不到一個洽當的形容詞來形容我的意思。我害怕隨著人類濫用而意義變質的文字,所以我想盡辦法避開常用的詞彙,尋找更能精確表達我意思的詞彙。到最後我往往詞窮,說出了一堆太過抽象沒人聽得懂的話。

    + +

    就像氣質,我很怕去用這個詞,因為每個人對氣質的定義都不大一樣。我不喜歡去談氣質這種含義不精確的詞。

    + +

    我的困境,很像詩的困境:詩人對文字永遠也不滿意,永遠在追求新的文字。因為害怕感覺會隨著文字而定形,而僵化,無法真正貼近自己的感覺。這是個永無止境的矛盾,因為定形的文字永遠會僵化,會轉變,會死亡,而詩人的感情是活生生的,是跳動的,是文字永遠也無法補捉的。

    + +

    那麼,詩人其實最好的事,是閉嘴。

    + +

    可是,詩人不能閉嘴。因為詩人是自戀的,是敏感的,一個小小的波動,都會使得纖細的感情產生千萬碎片。如果無法說出口,喧洩出來,那詩人就會被淹沒在自己的情感中而窒息,而死亡。

    + +

    因此,妳就看到了,這些又像嘔吐物又像詩的腐爛文字。這是詩人的心血,也是糞土。

    + +

    (妳可以閱讀之前的前言。)

    + +
    + +
    + + + + diff --git a/htdocs/index.html.en.html b/htdocs/index.html.en.html new file mode 120000 index 0000000..08fc4ee --- /dev/null +++ b/htdocs/index.html.en.html @@ -0,0 +1 @@ +index.html.en.xhtml \ No newline at end of file diff --git a/htdocs/index.html.en.xhtml b/htdocs/index.html.en.xhtml new file mode 100644 index 0000000..100d352 --- /dev/null +++ b/htdocs/index.html.en.xhtml @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + +Oops... you should upgrade your browser now. + + + + + + + + + +
    + + +

    Oops... you should upgrade your browser now.

    + +

    If you see this page, it either means that you link here by other URL, or that your browser can only employ HTTP 1.0 protocol. HTTP 1.0 is an extremely-old protocol that prevent you from seeing virtual websites nowadays. We suggest you upgrade your browser to the newest version. If you're not upgrading now, enter your target website by the following links.

    + + + +
    + + +
    +
    +Made with Cascading Style Sheets|Valid XHTML 1.1!|Valid CSS!|Level Triple-A conformance icon, W3C-WAI Web Content Accessibility Guidelines 1.0 +

    This page conforms with XHTML 1.1 / + CSS 2.1 / + WCAG 1.0 + Triple-A recommendations.

    +
    + +
    +

    Copyright © 2000-2005 imacat. All rights reserved.

    +
    + +
    + + + diff --git a/htdocs/index.html.html b/htdocs/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/index.html.xhtml b/htdocs/index.html.xhtml new file mode 120000 index 0000000..08fc4ee --- /dev/null +++ b/htdocs/index.html.xhtml @@ -0,0 +1 @@ +index.html.en.xhtml \ No newline at end of file diff --git a/htdocs/index.html.zh-cn.html b/htdocs/index.html.zh-cn.html new file mode 120000 index 0000000..5ee9c39 --- /dev/null +++ b/htdocs/index.html.zh-cn.html @@ -0,0 +1 @@ +index.html.zh-cn.xhtml \ No newline at end of file diff --git a/htdocs/index.html.zh-cn.xhtml b/htdocs/index.html.zh-cn.xhtml new file mode 100644 index 0000000..8f64c6d --- /dev/null +++ b/htdocs/index.html.zh-cn.xhtml @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + +喂,该升级浏览器啰~! + + + + + + + + + +
    + + +

    喂,该升级浏览器啰~!

    + +

    妳看到这一页时,如果妳不是用其它网址连上这个网站,就是妳的浏览器只能用 HTTP 1.0 通信协定。 HTTP 1.0 是很旧的通信协定,无法浏览新式的虚拟主机。我们建议妳升级新的浏览器。如果妳不打算升级,请由以下链接进入妳想进入的网站。

    + + + +
    + + +
    +
    +以 CSS 样式表制作|XHTML 1.1 正确!|CSS 正确!|W3C 无障碍网页规范 1.0 三 A 级标准标章 +

    本页符合 XHTML 1.1 / + CSS 2.1 / + 无障碍网页规范 1.0 三 A 级标准

    +
    + +
    +

    版权所有 © 2000-2018 依玛猫。依玛猫保有所有权利。

    +
    + +
    + + + diff --git a/htdocs/index.html.zh-tw.html b/htdocs/index.html.zh-tw.html new file mode 120000 index 0000000..6c1b76e --- /dev/null +++ b/htdocs/index.html.zh-tw.html @@ -0,0 +1 @@ +index.html.zh-tw.xhtml \ No newline at end of file diff --git a/htdocs/index.html.zh-tw.xhtml b/htdocs/index.html.zh-tw.xhtml new file mode 100644 index 0000000..0df00e7 --- /dev/null +++ b/htdocs/index.html.zh-tw.xhtml @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + +喂,該昇級瀏覽器囉~! + + + + + + + + + +
    + + +

    喂,該昇級瀏覽器囉~!

    + +

    妳看到這一頁時,如果妳不是用其它網址連上這個網站,就是妳的瀏覽器只能用 HTTP 1.0 通訊協定。 HTTP 1.0 是很舊的通訊協定,無法瀏覽新式的虛擬主機。我們建議妳昇級新的瀏覽器。如果妳不打算昇級,請由以下連結進入妳想進入的網站。

    + + + +
    + + +
    +
    +以 CSS 樣式表製作|XHTML 1.1 正確!|CSS 正確!|W3C 無障礙網頁規範 1.0 三 A 級標準標章 +

    本頁符合 XHTML 1.1 / + CSS 2.1 / + 無障礙網頁規範 1.0 三 A 級標準

    +
    + +
    +

    版權所有 © 2000-2018 依瑪貓。依瑪貓保有所有權利。

    +
    + +
    + + + diff --git a/htdocs/robots.txt b/htdocs/robots.txt new file mode 100644 index 0000000..f0405e6 --- /dev/null +++ b/htdocs/robots.txt @@ -0,0 +1,12 @@ +User-agent: * +Crawl-delay: 1 +Disallow: / + +User-agent: chklinks +Disallow: + +User-agent: events +Disallow: + +User-agent: HTTrack +Disallow: / diff --git a/htdocs/wov/cgi-bin/counter.cgi b/htdocs/wov/cgi-bin/counter.cgi new file mode 100755 index 0000000..295b436 --- /dev/null +++ b/htdocs/wov/cgi-bin/counter.cgi @@ -0,0 +1,219 @@ +#! /usr/bin/perl -w +# Woman's Voice +# counter.cgi: The visitor counter. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-07 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub dont_update(); +sub read_counter(); +sub update_counter(); +sub log_visitor($); +sub counter_cookie(); +sub html_image($); + +use Fcntl qw(:seek); +use Date::Format qw(time2str); +use GD; +use IO::NestedCapture qw(CAPTURE_STDOUT); +use Net::CIDR::Lite qw(); + +use constant DATA_FILE => $ENV{"DOCUMENT_ROOT"} . "/magicat/data/counter.dat"; +use constant LOG_FILE => "/var/log/apache2/wov/counter.log"; +use vars qw($OUR_NETWORKS @FGCOLOR @BGCOLOR $FONT); +# People in our networks will not be counted +$OUR_NETWORKS = Net::CIDR::Lite->new( + qw(127.0.0.1/8 10.0.0.0/8 211.20.30.96/29)); +@FGCOLOR = (0, 0, 0); # #000000 Black +@BGCOLOR = (255, 255, 255); # #FFFFFF White +$FONT = gdLargeFont; +use constant TRANSPARENT => 1; +use constant COOKIE_NAME => "counter"; +use constant COUNT_ARG => "countme"; +use constant IGNORE_ARG => "ignoreme"; +initenv( -allowed => [qw(GET HEAD)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0, + -multilang => 0); + +main; +exit 0; + +sub main() { + local ($_, %_); + + # If we should not update the counter + if (dont_update) { + # Check last-modified here + my (@tables, @files); + @tables = qw(); + @files = (DATA_FILE); + http_304 if not_modified @tables, @files; + html_image read_counter; + + # Update the counter + } else { + $_ = html_image update_counter; + # Log the visitor + log_visitor $_; + } + + # Set the counter cookie + $NEWCOOKIES{COOKIE_NAME()} = $_ if defined ($_ = counter_cookie); + + return; +} + +# dont_update: If we should not update the counter +sub dont_update() { + local ($_, %_); + # Find any reason that we should not update the counter + # If this visitor came from our own network + return 1 if $OUR_NETWORKS->find($ENV{"REMOTE_ADDR"}); + # If this visitor had been counted + return 1 if exists $COOKIES{COOKIE_NAME()}; + # If we are not told to count this visitor + return 1 if !defined $GET->param(COUNT_ARG); + # Well, update it + return 0; +} + +# read_counter: Read the counter +sub read_counter() { + return -s DATA_FILE? xfread DATA_FILE: 0; +} + +# update_counter: Update the counter +sub update_counter() { + local ($_, %_); + # File exists + if (-s DATA_FILE) { + my $FH; + open $FH, "+<", DATA_FILE or http_500 DATA_FILE . ": $!"; + flock $FH, LOCK_EX or http_500 DATA_FILE . ": $!"; + $_ = <$FH>; + $_++; + seek $FH, 0, SEEK_SET or http_500 DATA_FILE . ": $!"; + truncate $FH, 0 or http_500 DATA_FILE . ": $!"; + print $FH $_ or http_500 DATA_FILE . ": $!"; + flock $FH, LOCK_UN or http_500 DATA_FILE . ": $!"; + close $FH or http_500 DATA_FILE . ": $!"; + + # Not exists or zero sized -- create a new one + } else { + xfwrite DATA_FILE, ($_ = 1); + } + return $_; +} + +# log_visitor: Log the visitor +sub log_visitor($) { + local ($_, %_); + my ($host, $user, $date, $uri, $size, $referer, $ua, $langs, $FD); + $size = $_[0]; + + # Gather the infomation to log + $host = (defined remote_host)? remote_host: $ENV{"REMOTE_ADDR"}; + $user = (exists $ENV{"REMOTE_USER"} && $ENV{"REMOTE_USER"} ne "")? + $ENV{"REMOTE_USER"}: "-"; + $date = time2str("%d/%b/%Y:%T %z", time); + $uri = $REQUEST_URI; + $referer = (exists $ENV{"HTTP_REFERER"} && $ENV{"HTTP_REFERER"} ne "")? + $ENV{"HTTP_REFERER"}: "-"; + $ua = (exists $ENV{"HTTP_USER_AGENT"} && $ENV{"HTTP_USER_AGENT"} ne "")? + $ENV{"HTTP_USER_AGENT"}: "="; + $langs = (exists $ENV{"HTTP_ACCEPT_LANGUAGE"} && $ENV{"HTTP_ACCEPT_LANGUAGE"} ne "")? + $ENV{"HTTP_ACCEPT_LANGUAGE"}: "-"; + + # Compose the log record 組合紀錄行 + $_ = sprintf "%s - %s [%s] \"%s %s %s\" 200 %s \"%s\" \"%s\" \"%s\" %s %s\n", + $host, $user, $date, $ENV{"REQUEST_METHOD"}, $uri, + $ENV{"SERVER_PROTOCOL"}, $size, $referer, $ua, $langs, + $ENV{"REMOTE_ADDR"}, country_lookup($ENV{"REMOTE_ADDR"}); + + # Save the log record 儲存記錄 + xfappend LOG_FILE, $_; + + return; +} + +# counter_cookie: Set the counter cookie +sub counter_cookie() { + local ($_, %_); + # Leave our network alone + return if $OUR_NETWORKS->find($ENV{"REMOTE_ADDR"}); + # Already set + return if exists $COOKIES{COOKIE_NAME()}; + # Count me + return new CGI::Cookie( -name=>COOKIE_NAME, + -value=>"counted", + -path=>$REQUEST_PATH) + if defined $GET->param(COUNT_ARG); + # Ignore me + return new CGI::Cookie( -name=>COOKIE_NAME, + -value=>"ignored", + -path=>$REQUEST_PATH) + if defined $GET->param(IGNORE_ARG); + # Leave it alone + return; +} + +# html_image: Make the image from the counter value +sub html_image($) { + local $_; + my ($counter, $image, $width, $height, $fgcolor, $bgcolor); + $counter = $_[0]; + + # Group the counter with commas at thousand digits. + $counter = fmtno($counter); + + # Initialize the image object + # Get the width and height + $width = $FONT->width * (length $counter); + $height = $FONT->height; + # Create an image object + $image = GD::Image->new($width, $height); + # Create the forground/background color objects + $fgcolor = $image->colorAllocate(@FGCOLOR); + $bgcolor = $image->colorAllocate(@BGCOLOR); + + # Draw the image + # Set the transparent background + $image->transparent($bgcolor) if TRANSPARENT; + # Paint the background + $image->filledRectangle(0, 0, $width, $height, $bgcolor); + # Write the text + $image->string($FONT, 0, 0, $counter, $fgcolor); + + # Output + $CONTENT_TYPE = "image/png"; + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":raw"; + $_ = $image->png; + print $_; + + return length $_; +} diff --git a/htdocs/wov/cgi-bin/last_update.cgi b/htdocs/wov/cgi-bin/last_update.cgi new file mode 100755 index 0000000..83d3c2e --- /dev/null +++ b/htdocs/wov/cgi-bin/last_update.cgi @@ -0,0 +1,142 @@ +#! /usr/bin/perl -w +# Woman's Voice +# last_update.cgi: The last-update date of the whole web site. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-09 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub find_files_in(\@\@); +sub fmttime_local($); +sub html_image($); + +use File::Spec; +use GD; +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use vars qw(@DIREXCS %RDIREXCS @FGCOLOR @BGCOLOR $FONT); +# Directories to be excluded (no leading and trailing slashes) +@DIREXCS = qw(magicat); +@FGCOLOR = (0, 0, 0); # #000000 Black +@BGCOLOR = (255, 255, 255); # #FFFFFF White +$FONT = gdLargeFont; +use constant TRANSPARENT => 1; +initenv( -allowed => [qw(GET HEAD)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0, + -multilang => 0); +%RDIREXCS = map { File::Spec->catfile($DOC_ROOT, $_) => 1 } @DIREXCS; + +main; +exit 0; + +sub main() { + local ($_, %_); + my (@tables, @files); + + @tables = qw(); + @files = qw(); + @_ = ($DOC_ROOT); + find_files_in(@files, @_); + http_304 if not_modified @tables, @files; + + html_image($LAST_MODIFIED); + + return; +} + +# find_files_in: an easy file finder +sub find_files_in(\@\@) { + local ($_, %_); + my ($files, $dirs, @subdirs, $DH, $ent); + ($files, $dirs) = @_; + + # Bounce for nothing + return if scalar(@$dirs) == 0; + # Look in these directories + @subdirs = qw(); + foreach my $dir (@$dirs) { + $dir =~ s/\/$//; + opendir $DH, $dir or die "$dir: $!"; + while (defined($_ = readdir $DH)) { + next if /^\./; + # Using catfile() is better, but a lot slower + $ent = File::Spec->catfile($dir, $_); + #$ent = "$dir/$_"; + if (-f $ent) { + push @$files, $ent; + } elsif (-d $ent) { + push @subdirs, $ent + if !exists $RDIREXCS{$ent}; + } + } + closedir $DH or die "$dir: $!"; + } + # Look in the subdirectories + find_files_in @$files, @subdirs; + return; +} + +# fmttime_local: Format the time using my own format +sub fmttime_local($) { + @_ = localtime $_[0]; + return sprintf "%04d.%02d.%02d", $_[5]+1900, $_[4]+1, $_[3]; +} + +# html_image: Make the image from the last-update value +sub html_image($) { + local $_; + my ($last_update, $image, $width, $height, $fgcolor, $bgcolor); + $last_update = $_[0]; + + # Format the date to my preferred format + $last_update = fmttime_local($last_update); + + # Initialize the image object + # Get the width and height + $width = $FONT->width * (length $last_update); + $height = $FONT->height; + # Create an image object + $image = GD::Image->new($width, $height); + # Create the forground/background color objects + $fgcolor = $image->colorAllocate(@FGCOLOR); + $bgcolor = $image->colorAllocate(@BGCOLOR); + + # Draw the image + # Set the transparent background + $image->transparent($bgcolor) if TRANSPARENT; + # Paint the background + $image->filledRectangle(0, 0, $width, $height, $bgcolor); + # Write the text + $image->string($FONT, 0, 0, $last_update, $fgcolor); + + # Output + $CONTENT_TYPE = "image/png"; + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":raw"; + print $image->png; + + return; +} diff --git a/htdocs/wov/cgi-bin/mailto.cgi b/htdocs/wov/cgi-bin/mailto.cgi new file mode 100755 index 0000000..315f4fc --- /dev/null +++ b/htdocs/wov/cgi-bin/mailto.cgi @@ -0,0 +1,70 @@ +#! /usr/bin/perl -w +# Woman's Voice +# mailto.cgi: The e-mail hyperlink redirector. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-05-13 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_post(); + +use Fcntl qw(:seek); + +initenv(-allowed => [qw(POST)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 0); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $error; + + # Only POSTed forms are allowed + $error = check_post; + # If an error occurs + if (defined $error) { + http_400; + + # Else, save the data + } else { + http_303 "mailto:" . $POST->param("email"); + } + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::Checker::MailTo(curform); + $error = $checker->check(qw(email)); + return $error if defined $error; + # OK + return; +} diff --git a/htdocs/wov/cgi-bin/search.cgi b/htdocs/wov/cgi-bin/search.cgi new file mode 100755 index 0000000..37a8fc3 --- /dev/null +++ b/htdocs/wov/cgi-bin/search.cgi @@ -0,0 +1,56 @@ +#! /usr/bin/perl -w +# Woman's Voice +# search.cgi: The web site full-text search. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-28 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); + +use Fcntl qw(:seek); + +initenv(-allowed => [qw(GET HEAD)], + -session => 0, + -dbi_lock => {"nlarts" => LOCK_SH, + "newslets" => LOCK_SH, + "guestbook" => LOCK_SH, + "pages" => LOCK_SH, + "links" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("search, query, full text search")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $LIST; + # List handler handles its own error + $LIST = new Selima::wov::List::Search; + html_header $LIST->{"title"}, $LIST->{"etitle"}, $LIST->page_param; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/wov/copying.html.html b/htdocs/wov/copying.html.html new file mode 120000 index 0000000..3649ba5 --- /dev/null +++ b/htdocs/wov/copying.html.html @@ -0,0 +1 @@ +copying.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/copying.html.xhtml b/htdocs/wov/copying.html.xhtml new file mode 100644 index 0000000..234e1ee --- /dev/null +++ b/htdocs/wov/copying.html.xhtml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + +女聲著作權聲明 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲著作權聲明

    +

    Authority Announcement

    +
    + +
    +
    女聲著作權聲明
    + +
    +

    《女聲》電子報除網站留言板外,內文版權所有,歡迎轉載。唯請遵守以下事項:

    + +
      +
    1. 必須以下列格式,註明原作者及出處網址: +
      作者: [作者名] , [完整網址]
      +
    2. + +
    3. 請註明原作者及出處。
    4. + +
    5. 不得作任何更動、添增、刪改。
    6. + +
    7. 欲作商業或學術轉載(含論文發表、媒體報導、書刊出版)請事先取得我們同意。
    8. + +
    9. 《女聲》網站留言板所有留言著作權與《女聲》電子報無關,另以留言板著作權聲明為準。
    10. +
    +
    + +
    女聲留言板著作權聲明
    + +
    +

    《女聲》網站留言板所有留言版權屬各留言人所有,與《女聲》電子報無關。《女聲》著作權聲明不適用於留言板留言。欲轉載、引用任何留言板留言,請事先取得各留言人之同意。若留言人未留任何聯絡資料,一律禁止任何轉載、引用。

    +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/data/gender_law_idv.doc b/htdocs/wov/data/gender_law_idv.doc new file mode 100644 index 0000000..19b6880 Binary files /dev/null and b/htdocs/wov/data/gender_law_idv.doc differ diff --git a/htdocs/wov/data/gender_law_org.doc b/htdocs/wov/data/gender_law_org.doc new file mode 100644 index 0000000..3e56634 Binary files /dev/null and b/htdocs/wov/data/gender_law_org.doc differ diff --git a/htdocs/wov/data/wovs.zip b/htdocs/wov/data/wovs.zip new file mode 100644 index 0000000..44954a1 Binary files /dev/null and b/htdocs/wov/data/wovs.zip differ diff --git a/htdocs/wov/errors/301.html.html b/htdocs/wov/errors/301.html.html new file mode 120000 index 0000000..7d57edf --- /dev/null +++ b/htdocs/wov/errors/301.html.html @@ -0,0 +1 @@ +301.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/errors/301.html.xhtml b/htdocs/wov/errors/301.html.xhtml new file mode 100644 index 0000000..a9036df --- /dev/null +++ b/htdocs/wov/errors/301.html.xhtml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + +HTTP 301 網址已遷 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    HTTP 301 網址已遷

    +

    Moved Permanently

    +
    + +

    本頁已遷址,日後請更新妳的書籤或妳的最愛,並改往新址

    + +
    + +
    + + + + diff --git a/htdocs/wov/errors/303.html.html b/htdocs/wov/errors/303.html.html new file mode 120000 index 0000000..74b918a --- /dev/null +++ b/htdocs/wov/errors/303.html.html @@ -0,0 +1 @@ +303.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/errors/303.html.xhtml b/htdocs/wov/errors/303.html.xhtml new file mode 100644 index 0000000..291c391 --- /dev/null +++ b/htdocs/wov/errors/303.html.xhtml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + +HTTP 303 續往下址 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    HTTP 303 續往下址

    +

    See Other

    +
    + +

    請續往後續的網址

    + +
    + +
    + + + + diff --git a/htdocs/wov/errors/307.html.html b/htdocs/wov/errors/307.html.html new file mode 120000 index 0000000..5730eb3 --- /dev/null +++ b/htdocs/wov/errors/307.html.html @@ -0,0 +1 @@ +307.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/errors/307.html.xhtml b/htdocs/wov/errors/307.html.xhtml new file mode 100644 index 0000000..e0ff5ef --- /dev/null +++ b/htdocs/wov/errors/307.html.xhtml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + +HTTP 307 網址暫移 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    HTTP 307 網址暫移

    +

    Temporary Redirect

    +
    + +

    請參閱本頁目前的網址

    + +
    + +
    + + + + diff --git a/htdocs/wov/errors/400.html.html b/htdocs/wov/errors/400.html.html new file mode 120000 index 0000000..a1fe2e8 --- /dev/null +++ b/htdocs/wov/errors/400.html.html @@ -0,0 +1 @@ +400.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/errors/400.html.xhtml b/htdocs/wov/errors/400.html.xhtml new file mode 100644 index 0000000..bff1e75 --- /dev/null +++ b/htdocs/wov/errors/400.html.xhtml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + +HTTP 400 語法錯誤 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    HTTP 400 語法錯誤

    +

    Bad Request

    +
    + + + +

    很抱歉,妳的要求語法錯誤,網站看不懂妳的要求。這可能是瀏覽器的問題,或妳輸入的網址有筆誤。請更正妳的筆誤,或請回《女聲》電子報首頁重新瀏覽。

    + +

    若有任何問題,請來信告訴我們

    + +
    + +
    + + + + diff --git a/htdocs/wov/errors/401.html.html b/htdocs/wov/errors/401.html.html new file mode 120000 index 0000000..f605262 --- /dev/null +++ b/htdocs/wov/errors/401.html.html @@ -0,0 +1 @@ +401.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/errors/401.html.xhtml b/htdocs/wov/errors/401.html.xhtml new file mode 100644 index 0000000..a844b3b --- /dev/null +++ b/htdocs/wov/errors/401.html.xhtml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + +HTTP 401 非請莫入 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    HTTP 401 非請莫入

    +

    Unauthorized

    +
    + +

    很抱歉,本頁非請莫入,請回《女聲》電子報首頁重新瀏覽。

    + +

    若有任何問題,請來信告訴我們

    + +
    + +
    + + + + diff --git a/htdocs/wov/errors/403.html.html b/htdocs/wov/errors/403.html.html new file mode 120000 index 0000000..b668e83 --- /dev/null +++ b/htdocs/wov/errors/403.html.html @@ -0,0 +1 @@ +403.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/errors/403.html.xhtml b/htdocs/wov/errors/403.html.xhtml new file mode 100644 index 0000000..d3e1001 --- /dev/null +++ b/htdocs/wov/errors/403.html.xhtml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + +HTTP 403 禁止進入 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    HTTP 403 禁止進入

    +

    Forbidden

    +
    + + + +

    很抱歉,本頁禁止進入,請回《女聲》電子報首頁重新瀏覽。

    + +

    若有任何問題,請來信告訴我們

    + +
    + +
    + + + + diff --git a/htdocs/wov/errors/404.html.html b/htdocs/wov/errors/404.html.html new file mode 120000 index 0000000..4a7a8d7 --- /dev/null +++ b/htdocs/wov/errors/404.html.html @@ -0,0 +1 @@ +404.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/errors/404.html.xhtml b/htdocs/wov/errors/404.html.xhtml new file mode 100644 index 0000000..ab557aa --- /dev/null +++ b/htdocs/wov/errors/404.html.xhtml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + +HTTP 404 找不到網頁 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    HTTP 404 找不到網頁

    +

    Not Found

    +
    + +

    很抱歉,找不到妳想連的那一頁。請檢查妳的網址是否有誤。若妳是由其它地方連上這裡,請來信告訴我們

    + +

    妳可以回到《女聲》電子報首頁重新瀏覽。

    + +
    + +
    + + + + diff --git a/htdocs/wov/errors/405.html.html b/htdocs/wov/errors/405.html.html new file mode 120000 index 0000000..5a1bc52 --- /dev/null +++ b/htdocs/wov/errors/405.html.html @@ -0,0 +1 @@ +405.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/errors/405.html.xhtml b/htdocs/wov/errors/405.html.xhtml new file mode 100644 index 0000000..9a2f1aa --- /dev/null +++ b/htdocs/wov/errors/405.html.xhtml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + +HTTP 405 要求方式無效 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    HTTP 405 要求方式無效

    +

    Method Not Allowed

    +
    + +

    很抱歉,無法用這個方式連到此頁。請改用以下方式: $allowed 。

    + +

    若有任何問題,請來信告訴我們

    + +
    + +
    + + + + diff --git a/htdocs/wov/errors/410.html.html b/htdocs/wov/errors/410.html.html new file mode 120000 index 0000000..a9dad98 --- /dev/null +++ b/htdocs/wov/errors/410.html.html @@ -0,0 +1 @@ +410.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/errors/410.html.xhtml b/htdocs/wov/errors/410.html.xhtml new file mode 100644 index 0000000..80345aa --- /dev/null +++ b/htdocs/wov/errors/410.html.xhtml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + +HTTP 410 已刪 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    HTTP 410 已刪

    +

    Gone

    +
    + +

    本頁內容已刪,造成不便請見諒。

    + +

    妳可以回到《女聲》電子報首頁重新瀏覽。

    + +
    + +
    + + + + diff --git a/htdocs/wov/errors/500.html.html b/htdocs/wov/errors/500.html.html new file mode 120000 index 0000000..628a797 --- /dev/null +++ b/htdocs/wov/errors/500.html.html @@ -0,0 +1 @@ +500.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/errors/500.html.xhtml b/htdocs/wov/errors/500.html.xhtml new file mode 100644 index 0000000..4679e74 --- /dev/null +++ b/htdocs/wov/errors/500.html.xhtml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + +HTTP 500 網站執行錯誤 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    HTTP 500 網站執行錯誤

    +

    Internal Server Error

    +
    + + + +

    很抱歉,網站發生錯誤。這通常是 CGI 程式設計問題,請來信告訴我們

    + +

    妳可以回到《女聲》電子報首頁重新瀏覽。

    + +
    + +
    + + + + diff --git a/htdocs/wov/errors/503.html.html b/htdocs/wov/errors/503.html.html new file mode 120000 index 0000000..45a3b61 --- /dev/null +++ b/htdocs/wov/errors/503.html.html @@ -0,0 +1 @@ +503.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/errors/503.html.xhtml b/htdocs/wov/errors/503.html.xhtml new file mode 100644 index 0000000..071d195 --- /dev/null +++ b/htdocs/wov/errors/503.html.xhtml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + +HTTP 503 網站暫停服務 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    HTTP 503 網站暫停服務

    +

    Service Unavailable

    +
    + + + +

    很抱歉,網站暫時停止服務。我們正在更新網站,大約要花一個小時左右。請晚點再來,謝謝。

    + +
    + +
    + + + + diff --git a/htdocs/wov/favicon.ico b/htdocs/wov/favicon.ico new file mode 100644 index 0000000..a55b26c Binary files /dev/null and b/htdocs/wov/favicon.ico differ diff --git a/htdocs/wov/images/backgrnd.gif b/htdocs/wov/images/backgrnd.gif new file mode 100644 index 0000000..944d231 Binary files /dev/null and b/htdocs/wov/images/backgrnd.gif differ diff --git a/htdocs/wov/images/backgrnd.png b/htdocs/wov/images/backgrnd.png new file mode 100644 index 0000000..9811f70 Binary files /dev/null and b/htdocs/wov/images/backgrnd.png differ diff --git a/htdocs/wov/images/email.gif b/htdocs/wov/images/email.gif new file mode 100644 index 0000000..165ff04 Binary files /dev/null and b/htdocs/wov/images/email.gif differ diff --git a/htdocs/wov/images/email.png b/htdocs/wov/images/email.png new file mode 100644 index 0000000..965fdac Binary files /dev/null and b/htdocs/wov/images/email.png differ diff --git a/htdocs/wov/images/icon.gif b/htdocs/wov/images/icon.gif new file mode 100644 index 0000000..07ef56f Binary files /dev/null and b/htdocs/wov/images/icon.gif differ diff --git a/htdocs/wov/images/icon.png b/htdocs/wov/images/icon.png new file mode 100644 index 0000000..7654529 Binary files /dev/null and b/htdocs/wov/images/icon.png differ diff --git a/htdocs/wov/images/logo-half.gif b/htdocs/wov/images/logo-half.gif new file mode 100644 index 0000000..841fb3a Binary files /dev/null and b/htdocs/wov/images/logo-half.gif differ diff --git a/htdocs/wov/images/logo-half.png b/htdocs/wov/images/logo-half.png new file mode 100644 index 0000000..329e2ab Binary files /dev/null and b/htdocs/wov/images/logo-half.png differ diff --git a/htdocs/wov/images/logo.gif b/htdocs/wov/images/logo.gif new file mode 100644 index 0000000..75d9510 Binary files /dev/null and b/htdocs/wov/images/logo.gif differ diff --git a/htdocs/wov/images/logo.png b/htdocs/wov/images/logo.png new file mode 100644 index 0000000..8b8676c Binary files /dev/null and b/htdocs/wov/images/logo.png differ diff --git a/htdocs/wov/images/modperl.png b/htdocs/wov/images/modperl.png new file mode 100644 index 0000000..9c295b0 Binary files /dev/null and b/htdocs/wov/images/modperl.png differ diff --git a/htdocs/wov/index.html.html b/htdocs/wov/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/wov/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/index.html.xhtml b/htdocs/wov/index.html.xhtml new file mode 100644 index 0000000..bc0d209 --- /dev/null +++ b/htdocs/wov/index.html.xhtml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + +女聲 Woman’s Voice + + + + + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +Since 1999.05.02, last updated last update.
    +妳是第 訪客人數 個訪客 +
    + +
    +

    發聲就是政治,是權力,是對主體性的要求。

    + +

    女聲就是女人的聲音。聲音有的好聽,有的不好聽,有的悅耳,有的嘈雜。也許是學者、是政要、是學生、是女兒、是媽媽、是女同性戀、是雙性戀、是女工、是菲傭、是公娼、是私娼、是雛妓、是打工辣妹、是家庭主婦、是心理女性。可能都是,也可能都不是。這些都是女人,她們的聲音都同等重要,在差異中尋求最適合自己的生存策略。

    + +

    更重要的是,身為女人,是政治行動,不只是天生的命運。

    +
    + +
    + +
    +

    誰的言論、誰有自由?!

    + +

    西方18世紀哲學家伏爾泰有句名言:「雖然我不同意你的觀點,但我要以生命捍衛你說話的權利。」現今台灣主流社會顯然沒這種容納異己的雅量。他們容忍的界限大概就是,男人講話,女人閉嘴;大人有性,小孩沒性;男異性戀可以看裸女,男同性戀卻禁止看裸男。

    + + +
    +
    + + + + +
    + + + + diff --git a/htdocs/wov/links/culture.html.html b/htdocs/wov/links/culture.html.html new file mode 120000 index 0000000..cc1cf04 --- /dev/null +++ b/htdocs/wov/links/culture.html.html @@ -0,0 +1 @@ +culture.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/culture.html.xhtml b/htdocs/wov/links/culture.html.xhtml new file mode 100644 index 0000000..d761cf5 --- /dev/null +++ b/htdocs/wov/links/culture.html.xhtml @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + +女人文化界 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女人文化界

    +

    Cultural Women

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/feminist.html.html b/htdocs/wov/links/feminist.html.html new file mode 120000 index 0000000..065c953 --- /dev/null +++ b/htdocs/wov/links/feminist.html.html @@ -0,0 +1 @@ +feminist.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/feminist.html.xhtml b/htdocs/wov/links/feminist.html.xhtml new file mode 100644 index 0000000..b171247 --- /dev/null +++ b/htdocs/wov/links/feminist.html.xhtml @@ -0,0 +1,431 @@ + + + + + + + + + + + + + + + + + + +抗爭的女人 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    抗爭的女人

    +

    Struggling Women

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/general.html.html b/htdocs/wov/links/general.html.html new file mode 120000 index 0000000..2395a09 --- /dev/null +++ b/htdocs/wov/links/general.html.html @@ -0,0 +1 @@ +general.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/general.html.xhtml b/htdocs/wov/links/general.html.xhtml new file mode 100644 index 0000000..213655f --- /dev/null +++ b/htdocs/wov/links/general.html.xhtml @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + +多樣的女人 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    多樣的女人

    +

    Mass Women

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/history.html.html b/htdocs/wov/links/history.html.html new file mode 120000 index 0000000..b03305d --- /dev/null +++ b/htdocs/wov/links/history.html.html @@ -0,0 +1 @@ +history.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/history.html.xhtml b/htdocs/wov/links/history.html.xhtml new file mode 100644 index 0000000..0044350 --- /dev/null +++ b/htdocs/wov/links/history.html.xhtml @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + +回首的女人 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    回首的女人

    +

    Historical Women

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/index.html.html b/htdocs/wov/links/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/wov/links/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/index.html.xhtml b/htdocs/wov/links/index.html.xhtml new file mode 100644 index 0000000..8ab6807 --- /dev/null +++ b/htdocs/wov/links/index.html.xhtml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + +女網牽手 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女網牽手

    +

    Woman Interconnect

    +
    + +
    +

    女人牽手,總是多了一份親暱。

    + +

    幼稚園、小學時期,女人們牽手上廁所;中學時期,女人們牽手面對成長的 +喜怒哀樂;畢業後或念大學,或出社會,女人們牽手分享彼此的感情世界與就業 +環境……藉由牽手,女人的情感、資訊流轉,女人的生命由此連結。

    + +

    稍離現實的生活,女人進入虛擬網路的空間,藉由女網牽手,女人永不孤獨。

    +
    + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/intell.html.html b/htdocs/wov/links/intell.html.html new file mode 120000 index 0000000..ef2aa7c --- /dev/null +++ b/htdocs/wov/links/intell.html.html @@ -0,0 +1 @@ +intell.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/intell.html.xhtml b/htdocs/wov/links/intell.html.xhtml new file mode 100644 index 0000000..12257fa --- /dev/null +++ b/htdocs/wov/links/intell.html.xhtml @@ -0,0 +1,411 @@ + + + + + + + + + + + + + + + + + + +好學的女人 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    好學的女人

    +

    Studious Women

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/labor.html.html b/htdocs/wov/links/labor.html.html new file mode 120000 index 0000000..b7f26eb --- /dev/null +++ b/htdocs/wov/links/labor.html.html @@ -0,0 +1 @@ +labor.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/labor.html.xhtml b/htdocs/wov/links/labor.html.xhtml new file mode 100644 index 0000000..b4db63c --- /dev/null +++ b/htdocs/wov/links/labor.html.xhtml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + +勞動的女人 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    勞動的女人

    +

    Working Women

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/lesbian.html.html b/htdocs/wov/links/lesbian.html.html new file mode 120000 index 0000000..084d05c --- /dev/null +++ b/htdocs/wov/links/lesbian.html.html @@ -0,0 +1 @@ +lesbian.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/lesbian.html.xhtml b/htdocs/wov/links/lesbian.html.xhtml new file mode 100644 index 0000000..2fd972b --- /dev/null +++ b/htdocs/wov/links/lesbian.html.xhtml @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + +女人愛女人 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女人愛女人

    +

    Women Love Women

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/literate.html.html b/htdocs/wov/links/literate.html.html new file mode 120000 index 0000000..d66faa8 --- /dev/null +++ b/htdocs/wov/links/literate.html.html @@ -0,0 +1 @@ +literate.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/literate.html.xhtml b/htdocs/wov/links/literate.html.xhtml new file mode 100644 index 0000000..7e3c74b --- /dev/null +++ b/htdocs/wov/links/literate.html.xhtml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + +舞文弄墨的女人 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    舞文弄墨的女人

    +

    Literary Women

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/medicine.html.html b/htdocs/wov/links/medicine.html.html new file mode 120000 index 0000000..4734639 --- /dev/null +++ b/htdocs/wov/links/medicine.html.html @@ -0,0 +1 @@ +medicine.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/medicine.html.xhtml b/htdocs/wov/links/medicine.html.xhtml new file mode 100644 index 0000000..8d716cf --- /dev/null +++ b/htdocs/wov/links/medicine.html.xhtml @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + + + + +愛惜身體的女人 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    愛惜身體的女人

    +

    Healthy Women

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/orgs.html.html b/htdocs/wov/links/orgs.html.html new file mode 120000 index 0000000..52d1145 --- /dev/null +++ b/htdocs/wov/links/orgs.html.html @@ -0,0 +1 @@ +orgs.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/orgs.html.xhtml b/htdocs/wov/links/orgs.html.xhtml new file mode 100644 index 0000000..573d56d --- /dev/null +++ b/htdocs/wov/links/orgs.html.xhtml @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + +一大群女人 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    一大群女人

    +

    Organized Women

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/others.html.html b/htdocs/wov/links/others.html.html new file mode 120000 index 0000000..5332c46 --- /dev/null +++ b/htdocs/wov/links/others.html.html @@ -0,0 +1 @@ +others.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/others.html.xhtml b/htdocs/wov/links/others.html.xhtml new file mode 100644 index 0000000..682755e --- /dev/null +++ b/htdocs/wov/links/others.html.xhtml @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + +好人 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    好人

    +

    Others

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/queer.html.html b/htdocs/wov/links/queer.html.html new file mode 120000 index 0000000..49e8db4 --- /dev/null +++ b/htdocs/wov/links/queer.html.html @@ -0,0 +1 @@ +queer.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/queer.html.xhtml b/htdocs/wov/links/queer.html.xhtml new file mode 100644 index 0000000..13a7dec --- /dev/null +++ b/htdocs/wov/links/queer.html.xhtml @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + +搞怪的女人 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    搞怪的女人

    +

    Queer Women

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/science.html.html b/htdocs/wov/links/science.html.html new file mode 120000 index 0000000..9295458 --- /dev/null +++ b/htdocs/wov/links/science.html.html @@ -0,0 +1 @@ +science.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/science.html.xhtml b/htdocs/wov/links/science.html.xhtml new file mode 100644 index 0000000..0f7202c --- /dev/null +++ b/htdocs/wov/links/science.html.xhtml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + +女性與科技 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女性與科技

    +

    Scientific Women

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/links/sex.html.html b/htdocs/wov/links/sex.html.html new file mode 120000 index 0000000..505c2b0 --- /dev/null +++ b/htdocs/wov/links/sex.html.html @@ -0,0 +1 @@ +sex.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/links/sex.html.xhtml b/htdocs/wov/links/sex.html.xhtml new file mode 100644 index 0000000..859e5ac --- /dev/null +++ b/htdocs/wov/links/sex.html.xhtml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + +隨性的女人 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    隨性的女人

    +

    Sexual Women

    +
    + + + + + +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +
    + +
    + + + + diff --git a/htdocs/wov/magicat/archive/cgi-bin/guestbook.cgi b/htdocs/wov/magicat/archive/cgi-bin/guestbook.cgi new file mode 100755 index 0000000..906b63a --- /dev/null +++ b/htdocs/wov/magicat/archive/cgi-bin/guestbook.cgi @@ -0,0 +1,145 @@ +#! /usr/bin/perl -w +# Woman's Voice +# 1-guestbook.cgi: The guestbook. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-06 + +use 5.008; +use utf8; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub html_foreword(); + +initenv(-session => 0, + -this_table => "guestbook", + -dbi_lock => {"guestbook" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("your voice"), + "class" => "guestbook", + "javascripts" => [qw(/scripts/guestbook.js)]}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::wov::Processor::Guestbook::Public($POST); + $processor->process; + http_303 $REQUEST_FILE; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + # Old styled page number + http_301 $REQUEST_FILE if defined $GET->param("no"); + # List handler handles its own error + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::wov::Checker::Guestbook::Public(curform); + $error = $checker->check(qw(message name identity location + email url flood dup spam)); + return $error if defined $error; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM, $args); + $status = $_[0]; + $FORM = new Selima::wov::Form::Guestbook::Public($status); + $LIST = new Selima::wov::List::Guestbook::Public; + $args = $LIST->page_param; + html_header "妳的女聲", "Your Voice", $args; + html_foreword; + html_errmsg $status; + $FORM->html; + $LIST->html; + html_footer $args; + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# html_foreword: Print the HTML foreword +sub html_foreword() { + local ($_, %_); + print << "EOT"; +
    +

    發聲就是政治,是權力,是對主體性的要求。

    + +

    女聲就是女人的聲音。聲音有的好聽,有的不好聽,有的悅耳,有的嘈雜。 +也許\是學者、是政要、是學生、是女兒、是媽媽、是女同性戀、是雙性戀、是 +女工、是菲傭、是公娼、是私娼、是雛妓、是打工辣妹、是家庭主婦、是心理 +女性。可能都是,也可能都不是。這些都是女人,她們的聲音都同等重要,在 +差異中尋求最適合自己的生存策略。

    + +

    更重要的是,身為女人,是政治行動,不只是天生的命運。

    + +
    + +EOT + return; +} + +no utf8; diff --git a/htdocs/wov/magicat/archive/cgi-bin/subs_counter.cgi b/htdocs/wov/magicat/archive/cgi-bin/subs_counter.cgi new file mode 100755 index 0000000..50ffbf7 --- /dev/null +++ b/htdocs/wov/magicat/archive/cgi-bin/subs_counter.cgi @@ -0,0 +1,121 @@ +#! /usr/bin/perl -w +# Woman's Voice +# 1-subs_counter.cgi: The subscriber counter. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-05-17 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub get_counter(); +sub html_image($); + +use Fcntl qw(:flock :seek); +use GD; +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use constant DATA_FILE => "/var/lib/mailman/lists/wov/config.pck"; +use constant COUNTER_PROG => "/usr/libexec/total_members"; +use constant LISTNAME => "wov"; +use vars qw(@FGCOLOR @BGCOLOR $FONT); +@FGCOLOR = (0, 0, 0); # #000000 Black +@BGCOLOR = (255, 255, 255); # #FFFFFF White +$FONT = gdLargeFont; +use constant TRANSPARENT => 1; +initenv( -allowed => [qw(GET HEAD)], + -session => 0, + -dbi => DBI_NONE, + -lastmod => 1, + -lmfiles => [DATA_FILE], + -multilang => 0); + +use vars qw($COUNTER $MTIME); + +main; +exit 0; + +sub main() { + local ($_, %_); + + get_counter(); + html_image($COUNTER); + + return; +} + +# get_counter: Get the subscriber counter +sub get_counter() { + local ($_, %_); + my $OUT; + + # Obtain the mtime of the subscriber database file + $_ = (stat DATA_FILE)[9]; + # We should update the counter + if (!defined $MTIME || $MTIME != $_) { + # Update the timestamp + $MTIME = $_; + @_ = (COUNTER_PROG, LISTNAME); + open $OUT, "-|", @_ or http_500 COUNTER_PROG . ": $!"; + defined($COUNTER = <$OUT>) or http_500 COUNTER_PROG . ": $!"; + close $OUT or http_500 COUNTER_PROG . ": $!"; + chomp $COUNTER; + } + + return $COUNTER; +} + +# html_image: Make the image from the counter value +sub html_image($) { + local $_; + my ($counter, $image, $width, $height, $fgcolor, $bgcolor); + $counter = $_[0]; + + # Group the counter with commas at thousand digits. + $counter = fmtno($counter); + + # Initialize the image object + # Get the width and height + $width = $FONT->width * (length $counter); + $height = $FONT->height; + # Create an image object + $image = GD::Image->new($width, $height); + # Create the forground/background color objects + $fgcolor = $image->colorAllocate(@FGCOLOR); + $bgcolor = $image->colorAllocate(@BGCOLOR); + + # Draw the image + # Set the transparent background + $image->transparent($bgcolor) if TRANSPARENT; + # Paint the background + $image->filledRectangle(0, 0, $width, $height, $bgcolor); + # Write the text + $image->string($FONT, 0, 0, $counter, $fgcolor); + + # Output + $CONTENT_TYPE = "image/png"; + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":raw"; + print $image->png; + + return; +} diff --git a/htdocs/wov/magicat/archive/magicat/cgi-bin/acctrecs.cgi b/htdocs/wov/magicat/archive/magicat/cgi-bin/acctrecs.cgi new file mode 100755 index 0000000..002d537 --- /dev/null +++ b/htdocs/wov/magicat/archive/magicat/cgi-bin/acctrecs.cgi @@ -0,0 +1,242 @@ +#! /usr/bin/perl -w +# Woman's Voice +# acctrecs.cgi: The accounting record administration. + +# Copyright (c) 2007-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-24 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_seltrx($); +sub import_selsubj($); + +initenv(-restricted => 1, + -this_table => "acctrecs", + -dbi_lock => {"acctrecs" => LOCK_EX, + "accttrx" => LOCK_SH, + "acctsubj" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("accounting")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::AcctRec($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + # Only allowing to run on HTTPS + http_403 if !is_https; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Only allowing to run on HTTPS + http_403 if !is_https; + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::AcctRec(curform); + $checker->redir(qw(seltrx deltrx selsubj delsubj)); + $error = $checker->check(qw(trx type ord subj summary amount)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::AcctRec(curform); + $checker->redir(qw(del seltrx deltrx selsubj delsubj)); + $error = $checker->check(qw(trx type ord subj summary amount)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::AcctRec(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::AcctRec($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Accounting::Records; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the accounting record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This accounting record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $CURRENT{"type"} = $CURRENT{"credit"}? "credit": "debit"; + + # OK + return; +} + +# import_seltrx: Import the selected accounting transaction into the retrieved form +sub import_seltrx($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("trx", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "accttrx"; + return; +} + +# import_selsubj: Import the selected accounting subject into the retrieved form +sub import_selsubj($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("subj", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "acctsubj"; + return; +} diff --git a/htdocs/wov/magicat/archive/magicat/cgi-bin/acctreps.cgi b/htdocs/wov/magicat/archive/magicat/cgi-bin/acctreps.cgi new file mode 100755 index 0000000..3256e4c --- /dev/null +++ b/htdocs/wov/magicat/archive/magicat/cgi-bin/acctreps.cgi @@ -0,0 +1,107 @@ +#! /usr/bin/perl -w +# Woman's Voice +# acctreps.cgi: The accounting report viewer. + +# Copyright (c) 2007-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-24 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub html_page($); + +initenv(-restricted => 1, + -dbi_lock => {"acctsubj" => LOCK_SH, + "accttrx" => LOCK_SH, + "acctrecs" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("accounting"), + "javascripts" => [qw(/scripts/accounting.js)]}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $error; + # Only allowing requests with GET method + # Check it here, since we still want list preference handlers to work + http_405 qw(GET) if $ENV{"REQUEST_METHOD"} ne "GET"; + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + # Only allowing to run on HTTPS + http_403 if !is_https; + # List handler handles its own error + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $page_param); + $status = $_[0]; + # List the available items + $_ = list_type; + if ($_ eq "cashsum") { + $LIST = new Selima::List::Accounting::Reports::Cash::Summary; + } elsif ($_ eq "ldgr") { + $LIST = new Selima::List::Accounting::Reports::Ledger; + } elsif ($_ eq "ldgrsum") { + $LIST = new Selima::List::Accounting::Reports::Ledger::Summary; + } elsif ($_ eq "journal") { + $LIST = new Selima::List::Accounting::Reports::Journal; + } elsif ($_ eq "tb") { + $LIST = new Selima::List::Accounting::Reports::TriBlnc; + } elsif ($_ eq "incmstat") { + $LIST = new Selima::List::Accounting::Reports::IncmStat; + } elsif ($_ eq "blncshet") { + $LIST = new Selima::List::Accounting::Reports::BlncShet; + } elsif ($_ eq "search") { + $LIST = new Selima::List::Accounting::Reports::Search; + } else { + $LIST = new Selima::List::Accounting::Reports::Cash; + } + # Return the data as a CSV file + return $LIST->html if $LIST->{"iscsv"}; + # Ordinary list + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/wov/magicat/archive/magicat/cgi-bin/acctsubj.cgi b/htdocs/wov/magicat/archive/magicat/cgi-bin/acctsubj.cgi new file mode 100755 index 0000000..d5c9b9e --- /dev/null +++ b/htdocs/wov/magicat/archive/magicat/cgi-bin/acctsubj.cgi @@ -0,0 +1,292 @@ +#! /usr/bin/perl -w +# Woman's Voice +# acctsubj.cgi: The accounting subject administraion. + +# Copyright (c) 2007-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-24 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selparent($); + +initenv(-restricted => 1, + -this_table => "acctsubj", + -dbi_lock => {"acctsubj" => LOCK_EX, + "acctrecs" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("accounting")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::AcctSubj($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + # Only allowing to run on HTTPS + http_403 if !is_https; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new accounting subject from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + return {"msg"=>N_("This accounting subject has [numerate,_1,an accounting sub-subject,accounting sub-subjects]. It cannot be deleted. To delete the subject, [numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] must first be deleted."), + "margs"=>[$CURRENT{"ssubcount"}], + "isform"=>0} + if $CURRENT{"ssubcount"} > 0; + return {"msg"=>N_("This accounting subject has [numerate,_1,an accounting record,accounting records]. It cannot be deleted. To delete the subject, [numerate,_1,its accounting record,all of its accounting records] must first be deleted."), + "margs"=>[$CURRENT{"reccount"}], + "isform"=>0} + if $CURRENT{"reccount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Only allowing to run on HTTPS + http_403 if !is_https; + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Start from the default language + return {"msg"=>N_("Please add a new accounting subject from [_1]."), + "margs"=>["_DEFAULT_LANG"], + "isform"=>0} + if getlang ne $DEFAULT_LANG; + # Run the checker + $checker = new Selima::Checker::AcctSubj(curform); + $checker->redir(qw(selparent delparent)); + $error = $checker->check(qw(parent code title)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::AcctSubj(curform); + $checker->redir(qw(del zhsync selparent delparent)); + $error = $checker->check(qw(parent code title)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::AcctSubj(curform); + $checker->redir(qw(cancel)); + return {"msg"=>N_("This accounting subject has [numerate,_1,an accounting sub-subject,accounting sub-subjects]. It cannot be deleted. To delete the subject, [numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] must first be deleted."), + "margs"=>[$CURRENT{"ssubcount"}], + "isform"=>0} + if $CURRENT{"ssubcount"} > 0; + return {"msg"=>N_("This accounting subject has [numerate,_1,an accounting record,accounting records]. It cannot be deleted. To delete the subject, [numerate,_1,its accounting record,all of its accounting records] must first be deleted."), + "margs"=>[$CURRENT{"reccount"}], + "isform"=>0} + if $CURRENT{"reccount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::AcctSubj($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + if (list_type eq "lastlv") { + $LIST = new Selima::List::Accounting::Subjects::LastLv; + } else { + $LIST = new Selima::List::Accounting::Subjects; + } + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lang, $lndb, $lndbdef, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the accounting subject."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This accounting subject does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $lang = getlang; + $lndb = getlang LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + + # Obtain the belonging subjects list + @_ = qw(); + push @_, "sn AS sn"; + if (@ALL_LINGUAS > 1) { + $title = $lang eq $DEFAULT_LANG? "title_$lndb": + "COALESCE(title_$lndb, title_$lndbdef)"; + } else {; + $title = "title"; + } + push @_, $DBH->strcat("code", "' '", $title) . " AS title"; + $sql = "SELECT " . join(", ", @_) . " FROM acctsubj" + . " WHERE parent=$sn" + . " ORDER BY code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"ssubcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"ssubcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"ssub$_" . "sn"} = $$row{"sn"}; + $CURRENT{"ssub$_" . "title"} = $$row{"title"}; + } + + # Obtain the belonging records list + $sql = "SELECT sn FROM acctrecs" + . " WHERE subj=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"reccount"} = $sth->rows; + + # OK + return; +} + +# import_selparent: Import the selected parent into the retrieved form +sub import_selparent($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "acctsubj") { + $FORM->param("parent", $GET->param("selsn")); + $FORM->param("topmost", "false"); + } + return; +} diff --git a/htdocs/wov/magicat/archive/magicat/cgi-bin/accttrx.cgi b/htdocs/wov/magicat/archive/magicat/cgi-bin/accttrx.cgi new file mode 100755 index 0000000..47424e9 --- /dev/null +++ b/htdocs/wov/magicat/archive/magicat/cgi-bin/accttrx.cgi @@ -0,0 +1,278 @@ +#! /usr/bin/perl -w +# Woman's Voice +# accttrx.cgi: The accounting transaction administraion. + +# Copyright (c) 2007-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-24 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selsubj($); + +initenv(-restricted => 1, + -this_table => "accttrx", + -dbi_lock => {"accttrx" => LOCK_EX, + "acctrecs" => LOCK_EX, + "acctsubj" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("accounting"), + "javascripts" => [qw(/scripts/accounting.js)]}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::AcctTrx($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + # Only allowing to run on HTTPS + http_403 if !is_https; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Only allowing to run on HTTPS + http_403 if !is_https; + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::AcctTrx(curform); + $checker->redir(qw(cnvttrans selsubj)); + $error = $checker->check(qw(date ord note recs)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::AcctTrx(curform); + $checker->redir(qw(del cnvttrans selsubj)); + $error = $checker->check(qw(date ord note recs)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::AcctTrx(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::AcctTrx($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Accounting::Transacts; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the accounting transaction."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This accounting transaction does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging debit records list + $sql = "SELECT * FROM acctrecs" + . " WHERE trx=$sn" + . " AND NOT credit" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"debtcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"debtcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"debt$_" . "sn"} = $$row{"sn"}; + $CURRENT{"debt$_" . "ord"} = $$row{"ord"}; + $CURRENT{"debt$_" . "subj"} = $$row{"subj"}; + $CURRENT{"debt$_" . "summary"} = $$row{"summary"}; + $CURRENT{"debt$_" . "amount"} = $$row{"amount"}; + } + + # Obtain the belonging credit records list + $sql = "SELECT * FROM acctrecs" + . " WHERE trx=$sn" + . " AND credit" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"crdtcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"crdtcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"crdt$_" . "sn"} = $$row{"sn"}; + $CURRENT{"crdt$_" . "ord"} = $$row{"ord"}; + $CURRENT{"crdt$_" . "subj"} = $$row{"subj"}; + $CURRENT{"crdt$_" . "summary"} = $$row{"summary"}; + $CURRENT{"crdt$_" . "amount"} = $$row{"amount"}; + } + + # Determine the subform type + if ( $CURRENT{"debtcount"} == 1 + && acctsubj_code($CURRENT{"debt0subj"}) eq ACCTSUBJ_CASH + && !defined $CURRENT{"debt0summary"}) { + $CURRENT{"formsub"} = "income"; + } elsif ( $CURRENT{"crdtcount"} == 1 + && acctsubj_code($CURRENT{"crdt0subj"}) eq ACCTSUBJ_CASH + && !defined $CURRENT{"crdt0summary"}) { + $CURRENT{"formsub"} = "expense"; + } else { + $CURRENT{"formsub"} = "trans"; + } + + # OK + return; +} + +# import_selsubj: Import the selected subject into the retrieved form +sub import_selsubj($) { + my $FORM; + $FORM = $_[0]; + # Sanity checks + return $FORM + if !defined $GET->param("selsn") + || !check_sn_in ${$GET->param_fetch("selsn")}[0], "acctsubj" + || !defined $FORM->param("caller_index"); + $FORM->param($FORM->param("caller_index") . "subj", $GET->param("selsn")); + return $FORM; +} diff --git a/htdocs/wov/magicat/bin/r703alog b/htdocs/wov/magicat/bin/r703alog new file mode 100755 index 0000000..51dd57b --- /dev/null +++ b/htdocs/wov/magicat/bin/r703alog @@ -0,0 +1,343 @@ +#! /usr/bin/perl -w +# Filename: r703alog +# Description: Perl script to download r703a log files +# Author: imacat +# Date: 2000-12-21 +# Copyright: (c) 2000-2007 imacat + +use 5.006; +use strict; +use warnings; +use Compress::Zlib qw(gzopen); +use Fcntl qw(:flock :seek); +use File::Basename qw(basename); +use File::Temp qw(tempfile); +use Getopt::Long qw(GetOptions); +use IO::Handle qw(autoflush); +use IPC::Open3 qw(open3); +use Net::FTP qw(); +use Socket qw(); +# Prototype declaration +sub main(); +sub parse_args(); +sub is_member($@); +sub format_number($); +sub xfread($); + +use vars qw($THIS_FILE $VERSION $VERBOSE); +$THIS_FILE = basename($0); +$VERSION = "2.03"; +$VERBOSE = 1; + +use vars qw($R_HOST $R_ID $R_PASSWD $R_DIR $L_DIR $FILELIST %DNS @RESLOG @ARCLOG); +$R_HOST = "r703a.chem.nthu.edu.tw"; +$R_ID = "wov"; +$R_PASSWD = undef; +$R_DIR = "/srv/www/logs"; +$L_DIR = "/var/log/apache/wov/r703a"; +$FILELIST = "$L_DIR/filelist.txt"; +%DNS = qw(); +@RESLOG = qw(/usr/sbin/reslog.pl --stdout); +@ARCLOG = qw(/usr/sbin/arclog.pl --keep=all --override=append --sort - /var/log/apache/wov/r703a/access_log); + +use vars qw($VERMSG $SHORTHELP $HELPMSG); +$VERMSG = "$THIS_FILE v$VERSION by imacat "; +$SHORTHELP = "Try `$THIS_FILE --help' for more information."; +$HELPMSG = << "EOT"; +Usage: $THIS_FILE [options] +Download and archive the r703a apache access log files. + + -d,--debug Display debug messages. Multiple --debug to debug more. + -q,--quiet Disable debug messages. An opposite that cancels the + effect of --debug. + -h,--help Display this help. + -v,--version Display version number. + +EOT + +main; +exit 0; + +# main: Main program +sub main() { + local ($_, %_); + my ($FTP, @downloaded, @files, $t0, $t); + my ($WORKING, $FH); + my ($file, $gz, $bytes); + my ($fc_total, $fc_acc, $fc_new); + my ($rc_total, $rc_valid, $rc_file_total, $rc_file_valid); + my ($errline, @errmsgs); + + # Parse the arguments + parse_args; + + # No longer a working script + print "Mission completed long time ago. Program stopped to avoid further problems.\n"; + return; + + # Get the downloaded files list + print STDERR "Fetching the downloaded list... " if $VERBOSE >= 2; + @downloaded = xfread $FILELIST; + @downloaded = grep /\S/, @downloaded; + @downloaded = grep !/^#/, @downloaded; + chomp foreach @downloaded; + print STDERR "done\n" if $VERBOSE >= 2; + print STDERR "" . format_number(scalar @downloaded) . " downloaded files recorded in the downloaded list.\n" if $VERBOSE >= 1; + + # Get the files list + print STDERR "Connecting to $R_HOST... " if $VERBOSE >= 2; + $FTP = new Net::FTP($R_HOST) or die "$THIS_FILE: Failed FTP connection: $@"; + $FTP->login($R_ID, $R_PASSWD) or die "$THIS_FILE: Failed login: " . $FTP->code . " " . $FTP->message; + print STDERR "done\n" if $VERBOSE >= 2; + print STDERR "Fetching the files list... " if $VERBOSE >= 2; + $FTP->cwd($R_DIR) or die "$THIS_FILE: Failed cwd $R_DIR: " . $FTP->code . " " . $FTP->message; + (@files = $FTP->ls()) or die "$THIS_FILE: Failed ls: " . $FTP->code . " " . $FTP->message; + print STDERR "done\n" if $VERBOSE >= 2; + print STDERR "Filtering new access logs... " if $VERBOSE >= 2; + $fc_total = format_number(scalar @files); + @files = grep /^httpd-log\.[A-Z][a-z]{2}\d{4}\.gz$/, @files; + $fc_acc = format_number(scalar @files); + @files = grep !is_member($_, @downloaded), @files; + $fc_new = format_number(scalar @files); + print STDERR "done\n" if $VERBOSE >= 2; + print STDERR "$fc_new new files found in $fc_acc access logs in $fc_total files.\n" if $VERBOSE >= 1; + + if ($fc_new == 0) { + print STDERR "No new files found. Program exists\n" if $VERBOSE >= 1; + # Close the connection + print STDERR "Closing the FTP connection... " if $VERBOSE >= 2; + $FTP->quit or die "$THIS_FILE: ftp close: " . $FTP->code . " " . $FTP->message; + print STDERR "done\n" if $VERBOSE >= 2; + print STDERR "Done. " . format_number($fc_new) . " files processed, " . format_number(time - $^T) . " seconds elapsed\n" if $VERBOSE >= 1; + return; + } + + # Download the files + print STDERR "Now we will download the new files\n" if $VERBOSE >= 2; + $t0 = time; + foreach (@files) { + print STDERR "Downloading $_... " if $VERBOSE >= 1; + $t = time; + $FTP->get($_, "$L_DIR/$_") or die "$THIS_FILE: Failed get $L_DIR/$_: " . $FTP->code . " " . $FTP->message; + print STDERR "done, " . format_number(time - $t) . " seconds elapsed\n" if $VERBOSE >= 1; + } + print STDERR "Downloading finished, " . format_number(scalar @files) . " new files downloaded, " . format_number(time - $t0) . " seconds elapsed\n" if $VERBOSE >= 2; + + # Close the connection + print STDERR "Closing the FTP connection... " if $VERBOSE >= 2; + $FTP->quit or die "$THIS_FILE: ftp close: " . $FTP->code . " " . $FTP->message; + print STDERR "done\n" if $VERBOSE >= 2; + + # Create the temporary working file + print STDERR "Creating temporary working file... " if $VERBOSE >= 2; + ($WORKING = tempfile) or die "$THIS_FILE: $!"; + print STDERR "done\n" if $VERBOSE >= 2; + + # Copy the needed records into temporary working file + print STDERR "Now we will copy records to the temporary working file\n" if $VERBOSE >= 2; + ($rc_total, $rc_valid) = (0, 0); + foreach $file (@files) { + # Open the file + print STDERR "Opening $file... " if $VERBOSE >= 2; + $gz = gzopen("$L_DIR/$file", "rb") + or die "$THIS_FILE: $!"; + print STDERR "done\n" if $VERBOSE >= 2; + + # Copy to the temporary working file + print STDERR "Copying records... " if $VERBOSE >= 2; + ($rc_file_total, $rc_file_valid) = (0, 0); + while (($bytes = $gz->gzreadline($_)) != 0) { + die "$THIS_FILE: " . $gz->gzerror() if $bytes == -1; + $rc_file_total++; + next unless / \/(~|%7E)wov/; + print $WORKING $_; + $rc_file_valid++; + } + print STDERR "done\n" if $VERBOSE >= 2; + print "" . format_number($rc_file_valid) . " valid records copied in " . format_number($rc_file_total) . " found records.\n" if $VERBOSE >= 2; + $rc_total += $rc_file_total; + $rc_valid += $rc_file_valid; + + # Close the source file + print STDERR "Closing $file... " if $VERBOSE >= 2; + $gz->gzclose() && die "$THIS_FILE: " . $gz->gzerror(); + print STDERR "done\n" if $VERBOSE >= 2; + + # Deleting the source file + print STDERR "Deleting $file... " if $VERBOSE >= 2; + unlink "$L_DIR/$file" or die "$THIS_FILE: $L_DIR/$file: $!"; + print STDERR "done\n" if $VERBOSE >= 2; + } + print STDERR "Copying finished\n" if $VERBOSE >= 2; + print STDERR "Totally " . format_number($rc_valid) . " valid records copied in " . format_number($rc_total) . " found records.\n" if $VERBOSE >= 1; + + # Resolve the records + print STDERR "Now we will resolve the records\n" if $VERBOSE >= 1; + $t = time; + if ($VERBOSE >= 2) { + open3(\*DATA_W, \*DATA_R, \*DATA_E, @RESLOG, "--debug") + or die "$THIS_FILE: $!"; + } else { + open3(\*DATA_W, \*DATA_R, \*DATA_E, @RESLOG, "--quiet") + or die "$THIS_FILE: $!"; + } + + seek $WORKING, 0, SEEK_SET or die "$THIS_FILE: $!"; + print DATA_W $_ while defined($_ = <$WORKING>); + + close DATA_W or die "$THIS_FILE: $!"; + if ($VERBOSE >= 2) { + $errline = ""; + while (defined($_ = getc DATA_E)) { + print STDERR $_ if $VERBOSE >= 2; + $errline =~ s/^[^\n]*\n$//; + $errline .= $_; + if ($errline eq "Printing to STDOUT... ") { + seek $WORKING, 0, SEEK_SET + or die "$THIS_FILE: $!"; + truncate $WORKING, 0 or die "$THIS_FILE: $!"; + print $WORKING $_ while defined($_ = ); + } + } + } else { + seek $WORKING, 0, SEEK_SET or die "$THIS_FILE: $!"; + truncate $WORKING, 0 or die "$THIS_FILE: $!"; + print $WORKING $_ while defined($_ = ); + } + close DATA_E or die "$THIS_FILE: $!"; + close DATA_R or die "$THIS_FILE: $!"; + wait; + die "$THIS_FILE: Failed reslog.pl with error code $?" if $? != 0; + print STDERR "Resolving finished, " . format_number(time - $t) . " seconds elapsed\n" if $VERBOSE >= 1; + + # Archive the records + print STDERR "Now we will archive the records\n" if $VERBOSE >= 1; + $t = time; + if ($VERBOSE >= 2) { + open3(\*DATA_W, \*DATA_R, \*DATA_E, @ARCLOG) + or die "$THIS_FILE: $!"; + } else { + open3(\*DATA_W, \*DATA_R, \*DATA_E, @ARCLOG, "--quiet") + or die "$THIS_FILE: $!"; + } + + seek $WORKING, 0, SEEK_SET or die "$THIS_FILE: $!"; + print DATA_W $_ while defined($_ = <$WORKING>); + + close DATA_W or die "$THIS_FILE: $!"; + while (defined($_ = getc DATA_E)) { + print STDERR $_ if $VERBOSE >= 2; + } + close DATA_R or die "$THIS_FILE: $!"; + close DATA_E or die "$THIS_FILE: $!"; + wait; + die "$THIS_FILE: Failed arclog.pl with error code $?" if $? != 0; + print STDERR "Archiving finished, " . format_number(time - $t) . " seconds elapsed\n" if $VERBOSE >= 1; + + # Close the temporary working file + print STDERR "Closing temporary working file... " if $VERBOSE >= 2; + close $WORKING or die "$THIS_FILE: $!"; + print STDERR "done\n" if $VERBOSE >= 2; + + # Write the new files to the downloaded list + print STDERR "Updating the downloaded list... " if $VERBOSE >= 2; + open $FH, ">>$FILELIST" or die "$THIS_FILE: $FILELIST: $!"; + flock $FH, LOCK_EX or die "$THIS_FILE: $FILELIST: $!"; + print $FH join "", map "$_\n", @files; + flock $FH, LOCK_UN or die "$THIS_FILE: $FILELIST: $!"; + close $FH or die "$THIS_FILE: $FILELIST: $!"; + print STDERR "done\n" if $VERBOSE >= 2; + + print STDERR format_number(scalar @files) . " files processed\n" + if $VERBOSE > 0; + print STDERR "Done. " . (time - $^T) . " seconds elapsed.\n" + if $VERBOSE > 0; + return; +} + +# parse_args: Parse the arguments +sub parse_args() { + local ($_, %_); + + # Get the arguments + eval { + local $SIG{"__WARN__"} = sub { die $_[0]; }; + Getopt::Long::Configure(qw(no_auto_abbrev bundling)); + GetOptions( "debug|d+"=>\$VERBOSE, + "quiet|q"=>sub { $VERBOSE-- if $VERBOSE > 0; }, + "help|h"=>sub { print $HELPMSG; exit 0; }, + "version|v"=>sub { print "$VERMSG\n"; exit 0; }); + }; + die "$THIS_FILE: $@$SHORTHELP\n" if $@ ne ""; + + $| = 1 if $VERBOSE > 0; + + # Check the arguments + # We have no arguments + die "$THIS_FILE: Too many arguments: $ARGV[0]\n$SHORTHELP\n" + if @ARGV > 0; + + return; +} + +# is_member: If a variable is a member of an array +sub is_member($@) { + local ($_, %_); + my ($v, @a); + ($v, @a) = @_; + return 1 if grep ($_ eq $v, @a) > 0; + return 0; +} + +# format_number: Format the number every 3 digit +sub format_number($) { + local ($_, %_); + $_ = $_[0]; + # Group every 3 digit + $_ = $1 . "," . $2 . $3 while /^([^\.]*\d)(\d\d\d)(.*)$/; + return $_; +} + +# xfread: Read from a file +sub xfread($) { + local ($_, %_); + my ($FH, $file); + $file = $_[0]; + + # Return as lines + if (wantarray) { + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + @_ = <$FH>; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return @_; + + # A scalar file content + } else { + # Regular files + if (-f $file) { + my $size; + @_ = stat $file or die "$THIS_FILE: $file: $!"; + $size = $_[7]; + return "" if $size == 0; + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + read $FH, $_, $size or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return $_; + + # Special files + } else { + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + $_ = join "", <$FH>; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return $_; + } + } +} + +__END__ diff --git a/htdocs/wov/magicat/cgi-bin/actlog.cgi b/htdocs/wov/magicat/cgi-bin/actlog.cgi new file mode 100755 index 0000000..adb5285 --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/actlog.cgi @@ -0,0 +1,51 @@ +#! /usr/bin/perl -w +# Woman's Voice +# actlog.cgi: The activity log viewer. + +# Copyright (c) 2005-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-05-10 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); + +initenv(-restricted => 1, + -allowed => [qw(GET HEAD)], + -lastmod => 0, + -lmfiles => [$ACTLOG], + -page_param => {"keywords" => N_("activity, logs")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my $LIST; + # List handler handles its own error + $LIST = new Selima::List::ActLog; + html_header $LIST->{"title"}; + html_errmsg retrieve_status; + $LIST->html; + html_footer; + return; +} diff --git a/htdocs/wov/magicat/cgi-bin/groupmem.cgi b/htdocs/wov/magicat/cgi-bin/groupmem.cgi new file mode 100755 index 0000000..a3186f7 --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/groupmem.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# Woman's Voice +# groupmem.cgi: The group-to-group membership administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); +sub import_selmember($); + +initenv(-restricted => 1, + -this_table => "groupmem", + -dbi_lock => {"groupmem" => LOCK_EX, + "groups" => LOCK_SH, + "groups AS grpmembers" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("group membership")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::GroupMem($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(del selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::GroupMem(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::GroupMem($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::GroupMem; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the membership record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This membership record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} + +# import_selmember: Import the selected member into the retrieved form +sub import_selmember($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("member", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups AS grpmembers"; + return $FORM; +} diff --git a/htdocs/wov/magicat/cgi-bin/groups.cgi b/htdocs/wov/magicat/cgi-bin/groups.cgi new file mode 100755 index 0000000..e474eb6 --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/groups.cgi @@ -0,0 +1,357 @@ +#! /usr/bin/perl -w +# Woman's Voice +# groups.cgi: The account group administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selsubuser($); +sub import_selsubgroup($); +sub import_selsupgroup($); + +initenv(-restricted => 1, + -this_table => "groups", + -dbi_lock => {"groups" => LOCK_EX, + "usermem" => LOCK_EX, + "groupmem" => LOCK_EX, + "users" => LOCK_SH, + "users AS members" => LOCK_SH, + "groups AS members" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("groups")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Group($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my ($error, $FORM, $sn); + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth if !is_su && $sn == su_group_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error, $FORM, $sn); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(selsubuser selsubgroup selsupgroup)); + $error = $checker->check(qw(id dsc subuser subgroup supgroup)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(del selsubuser selsubgroup selsupgroup)); + $error = $checker->check(qw(id dsc subuser subgroup supgroup)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth if !is_su && $sn == su_group_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Group(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::Group($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Groups; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the group."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This group does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the user members list + $title = $DBH->strcat("users.id", "' ('", "users.name", "')'"); + $sql = "SELECT users.sn AS sn," + . " $title AS title" + . " FROM usermem" + . " INNER JOIN users ON usermem.member=users.sn" + . " WHERE usermem.grp=$sn" + . " ORDER BY users.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"subusercount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"subusercount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"subuser$_"} = 1; + $CURRENT{"subuser$_" . "sn"} = $$row{"sn"}; + $CURRENT{"subuser$_" . "title"} = $$row{"title"}; + } + + # Obtain the group members list + $sql = "SELECT groups.sn AS sn," + . " groups.dsc AS title FROM groupmem" + . " INNER JOIN groups ON groupmem.member=groups.sn" + . " WHERE groupmem.grp=$sn" + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"subgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"subgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"subgroup$_"} = 1; + $CURRENT{"subgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"subgroup$_" . "title"} = $$row{"title"}; + } + + # Obtain the belonging groups list + $sql = "SELECT groups.sn AS sn," + . " groups.dsc AS title FROM groupmem" + . " INNER JOIN groups ON groupmem.grp=groups.sn" + . " WHERE groupmem.member=$sn" + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"supgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"supgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"supgroup$_"} = 1; + $CURRENT{"supgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"supgroup$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} + +# import_selsubuser: Import the selected user into the retrieved form +sub import_selsubuser($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users AS members") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^subuser\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { userid $a cmp userid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^subuser\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^subuser\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("subuser$_" . "sn", $_[$_]); + $FORM->param("subuser$_", 1) if exists $_{$_[$_]}; + } + } + return; +} + +# import_selsubgroup: Import the selected user into the retrieved form +sub import_selsubgroup($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups AS members") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^subgroup\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { groupid $a cmp groupid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^subgroup\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^subgroup\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("subgroup$_" . "sn", $_[$_]); + $FORM->param("subgroup$_", 1) if exists $_{$_[$_]}; + } + } + return; +} + +# import_selsupgroup: Import the selected user into the retrieved form +sub import_selsupgroup($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + # Sanity checks + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups") { + # Get the current member list + %_ = map { $FORM->param($_) => 1 } grep /^supgroup\d+sn$/, $FORM->param; + $_{$GET->param("selsn")} = 1; + @_ = sort { groupid $a cmp groupid $b } keys %_; + # Get the checked member list + %_ = map { $FORM->param($_ . "sn") => 1 } + grep /^supgroup\d+$/ && defined $FORM->param($_ . "sn"), $FORM->param; + $_{$GET->param("selsn")} = 1; + # Remove the old values + $FORM->delete(grep /^supgroup\d+/, $FORM->param); + # Add the current values + for ($_ = 0; $_ < @_; $_++) { + $FORM->param("supgroup$_" . "sn", $_[$_]); + $FORM->param("supgroup$_", 1) if exists $_{$_[$_]}; + } + } + return; +} diff --git a/htdocs/wov/magicat/cgi-bin/guestbook.cgi b/htdocs/wov/magicat/cgi-bin/guestbook.cgi new file mode 100755 index 0000000..341a0b1 --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/guestbook.cgi @@ -0,0 +1,211 @@ +#! /usr/bin/perl -w +# Woman's Voice +# guestbook.cgi: The guestbook administration. + +# Copyright (c) 2003-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-05-11 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "guestbook", + -dbi_lock => {"guestbook" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("guestbook")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Guestbook($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::wov::Checker::Guestbook(curform); + $error = $checker->check(qw(name identity location + email url message)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::wov::Checker::Guestbook(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(name identity location + email url message)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::wov::Checker::Guestbook(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::wov::Form::Guestbook($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::wov::List::Guestbook; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the message."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This message does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/wov/magicat/cgi-bin/linkcat.cgi b/htdocs/wov/magicat/cgi-bin/linkcat.cgi new file mode 100755 index 0000000..4dfab5d --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/linkcat.cgi @@ -0,0 +1,297 @@ +#! /usr/bin/perl -w +# Woman's Voice +# linkcat.cgi: The related-link category administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +use 5.008; +use utf8; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selparent($); + +initenv(-restricted => 1, + -this_table => "linkcat", + -dbi_lock => {"linkcat" => LOCK_EX, + "links" => LOCK_SH, + "linkcatz" => LOCK_SH}, + -lastmod => 0, + -page_param => {"keywords" => N_("link categories")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::wov::Processor::LinkCat($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + return {"msg"=>N_("This category has [numerate,_1,a subcategory,subcategories]. It cannot be deleted. To delete the category, [numerate,_1,its subcategory,all of its subcategories] must first be deleted."), + "margs"=>[$CURRENT{"scatcount"}], + "isform"=>0} + if $CURRENT{"scatcount"} > 0; + return {"msg"=>N_("This category has [numerate,_1,a link,links]. It cannot be deleted. To delete the category, [numerate,_1,its link,all of its links] must first be deleted."), + "margs"=>[$CURRENT{"linkcount"}], + "isform"=>0} + if $CURRENT{"linkcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(selparent delparent)); + $error = $checker->check(qw(parent id ord title title_en kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(del selparent delparent)); + $error = $checker->check(qw(parent id ord title title_en kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCat(curform); + $checker->redir(qw(cancel)); + return {"msg"=>N_("This category has [numerate,_1,a subcategory,subcategories]. It cannot be deleted. To delete the category, [numerate,_1,its subcategory,all of its subcategories] must first be deleted."), + "margs"=>[$CURRENT{"scatcount"}], + "isform"=>0} + if $CURRENT{"scatcount"} > 0; + return {"msg"=>N_("This category has [numerate,_1,a link,links]. It cannot be deleted. To delete the category, [numerate,_1,its link,all of its links] must first be deleted."), + "margs"=>[$CURRENT{"linkcount"}], + "isform"=>0} + if $CURRENT{"linkcount"} > 0; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::wov::Form::LinkCat($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::LinkCat; + $LIST->{"title"} = "管理女網牽手分類" + unless $LIST->{"is_called_form"}; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lang, $lndb, $lndbdef, $langfile, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the category."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This category does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $lang = getlang; + $lndb = getlang LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + $langfile = getlang LN_FILENAME; + + # Obtain the belonging subcategories list + @_ = qw(); + push @_, "sn AS sn"; + if (@ALL_LINGUAS > 1) { + $title = $lang eq $DEFAULT_LANG? "title_$lndb": + "COALESCE(title_$lndb, title_$lndbdef)"; + push @_, "linkcat_fulltitle('$lang', parent, $title) AS title"; + } else { + push @_, "linkcat_fulltitle(parent, title) AS title"; + } + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS url"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_ischild($sn, sn)" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"scatcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"scatcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"scat$_" . "sn"} = $$row{"sn"}; + $CURRENT{"scat$_" . "title"} = $$row{"title"}; + $CURRENT{"scat$_" . "url"} = $$row{"url"}; + } + + # Obtain the belonging links list + @_ = qw(); + push @_, "links.sn AS sn"; + push @_, "links.title AS title"; + push @_, "url AS url"; + $sql = "SELECT " . join(", ", @_) . " FROM links" + . " INNER JOIN linkcatz ON linkcatz.link=links.sn" + . " WHERE linkcatz.cat=$sn" + . " ORDER BY title;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"linkcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"linkcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"link$_" . "sn"} = $$row{"sn"}; + $CURRENT{"link$_" . "title"} = $$row{"title"}; + $CURRENT{"link$_" . "url"} = $$row{"url"}; + } + + # OK + return; +} + +# import_selparent: Import the selected parent into the retrieved form +sub import_selparent($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "linkcat") { + $FORM->param("parent", $GET->param("selsn")); + $FORM->param("topmost", "false"); + } + return; +} + +no utf8; diff --git a/htdocs/wov/magicat/cgi-bin/linkcatz.cgi b/htdocs/wov/magicat/cgi-bin/linkcatz.cgi new file mode 100755 index 0000000..dfc71ea --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/linkcatz.cgi @@ -0,0 +1,241 @@ +#! /usr/bin/perl -w +# Woman's Voice +# linkcatz.cgi: The related-link category membership administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +use 5.008; +use utf8; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selcat($); +sub import_sellink($); + +initenv(-restricted => 1, + -this_table => "linkcatz", + -dbi_lock => {"linkcatz" => LOCK_EX, + "linkcat" => LOCK_SH, + "links" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("link categorization")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LinkCatz($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(selcat delcat sellink dellink)); + $error = $checker->check(qw(cat link)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(del selcat delcat sellink dellink)); + $error = $checker->check(qw(cat link)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::LinkCatz(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::LinkCatz($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::LinkCatz; + $LIST->{"title"} = "管理女網牽手分類表" + unless $LIST->{"is_called_form"}; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the categorization record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This categorization record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selcat: Import the selected category into the retrieved form +sub import_selcat($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("cat", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "linkcat"; + return; +} + +# import_sellink: Import the selected link into the retrieved form +sub import_sellink($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("link", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "links"; + return $FORM; +} + +no utf8; diff --git a/htdocs/wov/magicat/cgi-bin/links.cgi b/htdocs/wov/magicat/cgi-bin/links.cgi new file mode 100755 index 0000000..873d146 --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/links.cgi @@ -0,0 +1,245 @@ +#! /usr/bin/perl -w +# Woman's Voice +# links.cgi: The related-link administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +use 5.008; +use utf8; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "links", + -dbi_lock => {"links" => LOCK_EX, + "linkcatz" => LOCK_EX, + "linkcat" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("related links")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Link($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::Link(curform); + $error = $checker->check(qw(title title_2ln url icon + email addr tel fax dsc cats)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Link(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(title title_2ln url icon + email addr tel fax dsc cats)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::Link(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::Link($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Links; + $LIST->{"title"} = "管理女網牽手" + unless $LIST->{"is_called_form"}; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + my ($lang, $lndb, $lndbdef, $title); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the related link."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This related link does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + $lang = getlang; + $lndb = getlang LN_DATABASE; + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + + # Obtain the parent categories list + @_ = qw(); + push @_, "linkcat.sn AS sn"; + if (@ALL_LINGUAS > 1) { + $title = $lang eq $DEFAULT_LANG? "linkcat.title_$lndb": + "COALESCE(linkcat.title_$lndb, linkcat.title_$lndbdef)"; + push @_, "linkcat_fulltitle('$lang', linkcat.parent, $title) AS title"; + } else { + push @_, "linkcat_fulltitle(linkcat.parent, linkcat.title) AS title"; + } + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " INNER JOIN linkcatz ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.link=$sn" + . " ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord);\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"catcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"catcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"cat$_"} = $$row{"sn"}; + $CURRENT{"cat$_" . "title"} = $$row{"title"}; + } + + # OK + return; +} + +no utf8; diff --git a/htdocs/wov/magicat/cgi-bin/logout.cgi b/htdocs/wov/magicat/cgi-bin/logout.cgi new file mode 100755 index 0000000..800a48b --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/logout.cgi @@ -0,0 +1,158 @@ +#! /usr/bin/perl -w +# Woman's Voice +# logout.cgi: The log-out script. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub html_logoutform(); +sub html_relogin(); + +initenv(-dbi => DBI_NONE, + -lastmod => 1, + -page_param => {"keywords" => N_("log out")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::LogOut($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $status; + # There is a result to display + $status = retrieve_status; + # Successfully logged out + if ( defined $status + && exists $$status{"status"} + && $$status{"status"} eq "success") { + # Nothing to check + return; + } + # Check if this user has logged in + unauth unless defined get_login_sn; + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + # Check if this user has logged in + unauth unless defined get_login_sn; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my $status; + $status = $_[0]; + # Not logged out yet + if (defined get_login_sn) { + html_header __("Log Out"); + html_errmsg $status; + html_logoutform; + html_footer; + + # Logged out + } else { + html_header __("Log Out"); + html_errmsg $status; + html_relogin; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# html_logoutform: Display a form to log out +sub html_logoutform() { + local ($_, %_); + my ($msg, $submit); + $msg = h(__("Are you sure you want to log out?")); + $submit = h(__("Log out")); + print << "EOT"; +
    +
    +

    $msg

    + +
    +
    + +EOT + return; +} + +# html_relogin: Display links to log in again +sub html_relogin() { + local ($_, %_); + $_ = h(__("Log in again.")); + print << "EOT"; +

    $_

    + +EOT + return; +} diff --git a/htdocs/wov/magicat/cgi-bin/newslets.cgi b/htdocs/wov/magicat/cgi-bin/newslets.cgi new file mode 100755 index 0000000..389bcd5 --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/newslets.cgi @@ -0,0 +1,271 @@ +#! /usr/bin/perl -w +# Woman's Voice +# newslets.cgi: The newsletter administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-17 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +use Date::Parse qw(str2time); + +initenv(-restricted => 1, + -this_table => "newslets", + -dbi_lock => {"newslets" => LOCK_EX, + "nlarts" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("newsletters")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::wov::Processor::Newslet($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to preview a submitted item + } elsif ($_ eq "preview") { + my ($sql, $sth, $count, $row, @allno); + # Check at fetch_preview() + $error = fetch_preview; + return $error if defined $error; + $PREVIEW{"path"} = sprintf "/newsletters/wov%04d.html", $PREVIEW{"no"}; + $PREVIEW{"date"} = str2time $PREVIEW{"date"}; + $PREVIEW{"title"} = newslet_textno($PREVIEW{"no"}) . " " . $PREVIEW{"title"}; + + # Obtain all the pages + @_ = qw(); + push @_, "sn!=" . $PREVIEW{"sn"} if exists $PREVIEW{"sn"}; + push @_, "NOT hid"; + $sql = "SELECT no FROM newslets" + . " WHERE " . join(" AND ", @_) + . " ORDER BY no;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @allno = qw(); $i < $count; $i++) { + push @allno, ${$sth->fetch}[0]; + } + undef $sth; + # Insert this page + for ($_ = 0; $_ < @allno; $_++) { + last if $PREVIEW{"no"} < $allno[$_]; + } + @allno = ( + @allno[0..$_-1], + $PREVIEW{"no"}, + @allno[$_..$#allno]); + $PREVIEW{"allno"} = [@allno]; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::wov::Checker::Newslet(curform); + $error = $checker->check(qw(no date title cred_t cred_h kw arts)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::wov::Checker::Newslet(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(no date title cred_t cred_h kw arts)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::wov::Checker::Newslet(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + # A form to preview a submitted item + if (form_type eq "preview") { + html_preview; + + } else { + $FORM = new Selima::wov::Form::Newslet($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + } + + # List the available items + } else { + $LIST = new Selima::wov::List::Newslets; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the newsletter."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This newsletter does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the date + $CURRENT{"date"} = fmtdate $CURRENT{"date"}; + + # Obtain the articles list + $sql = "SELECT * FROM nlarts WHERE newslet=$sn ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"artcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"artcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"art$_"} = 1; + $CURRENT{"art$_" . "sn"} = $$row{"sn"}; + $CURRENT{"art$_" . "ord"} = $$row{"ord"}; + $CURRENT{"art$_" . "title"} = $$row{"title"}; + $CURRENT{"art$_" . "author"} = $$row{"author"}; + $CURRENT{"art$_" . "body_t"} = $$row{"body_t"}; + $CURRENT{"art$_" . "body_h"} = $$row{"body_h"}; + $CURRENT{"art$_" . "hid"} = $$row{"hid"}; + } + + # OK + return; +} diff --git a/htdocs/wov/magicat/cgi-bin/nlarts.cgi b/htdocs/wov/magicat/cgi-bin/nlarts.cgi new file mode 100755 index 0000000..d16a07c --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/nlarts.cgi @@ -0,0 +1,223 @@ +#! /usr/bin/perl -w +# Woman's Voice +# nlarts.cgi: The newsletter article administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-24 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selnewslet($); + +initenv(-restricted => 1, + -this_table => "nlarts", + -dbi_lock => {"nlarts" => LOCK_EX, + "newslets" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("newsletter articles")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::wov::Processor::NLArt($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::wov::Checker::NLArt(curform); + $checker->redir(qw(selnewslet delnewslet)); + $error = $checker->check(qw(newslet ord title author body_t body_h)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::wov::Checker::NLArt(curform); + $checker->redir(qw(del selnewslet delnewslet)); + $error = $checker->check(qw(newslet ord title author body_t body_h)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::wov::Checker::NLArt(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::wov::Form::NLArt($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::wov::List::NLArts; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the article."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This article does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selnewslet: Import the selected newsletter into the retrieved form +sub import_selnewslet($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("newslet", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "newslets"; + return; +} diff --git a/htdocs/wov/magicat/cgi-bin/pages.cgi b/htdocs/wov/magicat/cgi-bin/pages.cgi new file mode 100755 index 0000000..52c203c --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/pages.cgi @@ -0,0 +1,221 @@ +#! /usr/bin/perl -w +# Woman's Voice +# pages.cgi: The web page administration. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-03 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-restricted => 1, + -this_table => "pages", + -dbi_lock => {"pages" => LOCK_EX}, + -lastmod => 1, + -page_param => {"keywords" => N_("pages")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::wov::Processor::Page($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to preview a submitted item + } elsif ($_ eq "preview") { + # Check at fetch_preview() + $error = fetch_preview; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::Page(curform); + $error = $checker->check(qw(path ord title title_en body kw)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::Page(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(path ord title title_en body kw)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::Page(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + # A form to preview a submitted item + if (form_type eq "preview") { + html_preview; + + } else { + $FORM = new Selima::wov::Form::Page($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + } + + # List the available items + } else { + $LIST = new Selima::List::Pages; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the page."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This page does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} diff --git a/htdocs/wov/magicat/cgi-bin/rebuild.cgi b/htdocs/wov/magicat/cgi-bin/rebuild.cgi new file mode 100755 index 0000000..6f20fef --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/rebuild.cgi @@ -0,0 +1,105 @@ +#! /usr/bin/perl -w +# Woman's Voice +# rebuild.cgi: The web page rebuilder. + +# Copyright (c) 2006-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-04 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); + +initenv(-restricted => 1, + -lastmod => 1, + -page_param => {"keywords" => N_("rebuild pages")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::Rebuild($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + # Nothing to check here + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + # Run the checker + $checker = new Selima::Checker::Rebuild(curform); + $error = $checker->check(qw(type)); + return $error if defined $error; + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $FORM); + $status = $_[0]; + $FORM = new Selima::Form::Rebuild($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + return; +} diff --git a/htdocs/wov/magicat/cgi-bin/scptpriv.cgi b/htdocs/wov/magicat/cgi-bin/scptpriv.cgi new file mode 100755 index 0000000..bac90eb --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/scptpriv.cgi @@ -0,0 +1,223 @@ +#! /usr/bin/perl -w +# Woman's Voice +# scptpriv.cgi: The script privilege administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); + +initenv(-restricted => 1, + -this_table => "scptpriv", + -dbi_lock => {"scptpriv" => LOCK_EX, + "groups" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("script privilege")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::ScptPriv($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(selgrp delgrp)); + $error = $checker->check(qw(script grp)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(del selgrp delgrp)); + $error = $checker->check(qw(script grp)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::ScptPriv(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::ScptPriv($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::ScptPriv; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the script privilege record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This script privilege record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} diff --git a/htdocs/wov/magicat/cgi-bin/test.cgi b/htdocs/wov/magicat/cgi-bin/test.cgi new file mode 100755 index 0000000..0a1b044 --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/test.cgi @@ -0,0 +1,40 @@ +#! /usr/bin/perl -w +# Woman's Voice +# test.cgi: The test script. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +use 5.008; +use utf8; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $r = shift; +my $d = new Selima::Destroy; +# Prototype declaration +use Time::HiRes qw(); +initenv; +$CONTENT_TYPE = "text/plain"; + + +printf "[%s] Done. %0.10f seconds elapsed.\n", + fmttime, Time::HiRes::time-$T_START; +exit 0; +no utf8; diff --git a/htdocs/wov/magicat/cgi-bin/usermem.cgi b/htdocs/wov/magicat/cgi-bin/usermem.cgi new file mode 100755 index 0000000..4ce8771 --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/usermem.cgi @@ -0,0 +1,236 @@ +#! /usr/bin/perl -w +# Woman's Voice +# usermem.cgi: The user-to-group membership administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selgrp($); +sub import_selmember($); + +initenv(-restricted => 1, + -this_table => "usermem", + -dbi_lock => {"usermem" => LOCK_EX, + "groups" => LOCK_SH, + "users AS usrmembers" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("user membership")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::UserMem($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(del selgrp delgrp selmember delmember)); + $error = $checker->check(qw(grp member)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::UserMem(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::UserMem($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::UserMem; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the membership record."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This membership record does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selgrp: Import the selected group into the retrieved form +sub import_selgrp($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("grp", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "groups"; + return; +} + +# import_selmember: Import the selected user into the retrieved form +sub import_selmember($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + $FORM->param("member", $GET->param("selsn")) + if defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users AS usrmembers"; + return $FORM; +} diff --git a/htdocs/wov/magicat/cgi-bin/userpref.cgi b/htdocs/wov/magicat/cgi-bin/userpref.cgi new file mode 100755 index 0000000..69c3b40 --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/userpref.cgi @@ -0,0 +1,225 @@ +#! /usr/bin/perl -w +# Woman's Voice +# userpref.cgi: The user preference administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); +sub import_selusr($); + +initenv(-restricted => 1, + -this_table => "userpref", + -dbi_lock => {"userpref" => LOCK_EX, + "users" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("user preference")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::UserPref($POST); + $success = $processor->process; + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my $error; + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Nothing to check on a new form + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + } + # List handler handles its own error + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(selusr delusr)); + $error = $checker->check(qw(usr domain name value)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(del selusr delusr)); + $error = $checker->check(qw(usr domain name value)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::UserPref(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::UserPref($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::UserPref; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the user preference."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This user preference does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # OK + return; +} + +# import_selusr: Import the selected user into the retrieved form +sub import_selusr($) { + local ($_, %_); + my $FORM; + $FORM = $_[0]; + if ( defined $GET->param("selsn") + && check_sn_in ${$GET->param_fetch("selsn")}[0], "users") { + $FORM->param("usr", $GET->param("selsn")); + $FORM->param("everyone", "false"); + } + return; +} diff --git a/htdocs/wov/magicat/cgi-bin/users.cgi b/htdocs/wov/magicat/cgi-bin/users.cgi new file mode 100755 index 0000000..7a64a49 --- /dev/null +++ b/htdocs/wov/magicat/cgi-bin/users.cgi @@ -0,0 +1,273 @@ +#! /usr/bin/perl -w +# Woman's Voice +# users.cgi: The user account administration. + +# Copyright (c) 2004-2021 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +use 5.008; +use strict; +use warnings; +use lib $ENV{"DOCUMENT_ROOT"} . qw(/magicat/lib/perl5); +use Selima::wov; +local $SIG{"__DIE__"} = \&http_500; +my $d = new Selima::Destroy; +# Prototype declaration +sub main(); +sub check_get(); +sub check_post(); +sub html_page($); +sub fetch_curitem(); + +initenv(-this_table => "users", + -dbi_lock => {"users" => LOCK_EX, + "usermem" => LOCK_EX, + "userpref" => LOCK_EX, + "groupmem" => LOCK_SH, + "groups" => LOCK_SH}, + -lastmod => 1, + -page_param => {"keywords" => N_("users")}); + +main; +exit 0; + +sub main() { + local ($_, %_); + my ($error, $success, $processor); + + # If the request is a GET query + if ($ENV{"REQUEST_METHOD"} ne "POST") { + $error = check_get; + # If an error occurs + if (defined $error) { + html_page $error; + + # Display the page + } else { + html_page retrieve_status; + } + + # If a form was POSTed from the client + } else { + $error = check_post; + # If an error occurs + if (defined $error) { + # Password not saved + $POST->delete("passwd", "passwd2"); + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::User($POST); + $success = $processor->process; + # Password not saved + $POST->delete("passwd", "passwd2"); + success_redirect $success; + } + } + return; +} + +# check_get: Check the GET arguments +sub check_get() { + local ($_, %_); + my ($error, $FORM, $sn); + + # A form is requested + if (is_form) { + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Check the privilege to manage this table + unauth if !is_script_permitted; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted || $sn == get_login_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted; + unauth if !is_su && (is_su $sn || $sn == get_login_sn); + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + + # Not a valid form + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + + # List the available items + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + # List handler handles its own error + } + # OK + return; +} + +# check_post: Check the POSTed form +sub check_post() { + local ($_, %_); + my ($checker, $error, $FORM, $sn); + $_ = form_type; + # A form to create a new item + if ($_ eq "new") { + # Check the privilege to manage this table + unauth unless is_script_permitted; + # Run the checker + $checker = new Selima::Checker::User(curform); + $error = $checker->check(qw(id passwd name supgroup)); + return $error if defined $error; + + # A form to edit a current item + } elsif ($_ eq "cur") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted || $sn == get_login_sn; + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error; + # Run the checker + $checker = new Selima::Checker::User(curform); + $checker->redir(qw(del)); + $error = $checker->check(qw(id passwd name supgroup)); + return $error if defined $error; + + # A form to delete a current item + } elsif ($_ eq "del") { + # Check the privilege to manage this table + $FORM = curform; + $sn = defined $FORM->param("sn")? $FORM->param("sn"): -1; + unauth unless defined get_login_sn; + unauth unless is_script_permitted; + unauth if !is_su && (is_su $sn || $sn == get_login_sn); + # Check at fetch_curitem() + $error = fetch_curitem; + return $error if defined $error;; + # Run the checker + $checker = new Selima::Checker::User(curform); + $checker->redir(qw(cancel)); + + # Not a valid form + } else { + # Check the privilege to manage this table + unauth unless is_script_permitted; + return {"msg"=>N_("Incorrect form: [_1]."), + "margs"=>[$_], + "isform"=>0}; + } + # OK + return; +} + +# html_page: Display the page +sub html_page($) { + local ($_, %_); + my ($status, $LIST, $FORM); + $status = $_[0]; + # A form is requested + if (is_form $status) { + $FORM = new Selima::Form::User($status); + html_header $FORM->{"title"}; + html_errmsg $status; + $FORM->html; + html_footer; + + # List the available items + } else { + $LIST = new Selima::List::Users; + html_header $LIST->{"title"}, undef, $LIST->page_param; + html_errmsg $status; + $LIST->html; + html_footer; + } + return; +} + + +################################## +# Subroutines to manage the data # +################################## +# fetch_curitem: Fetch the current item +sub fetch_curitem() { + local ($_, %_); + my ($sn, $FORM, $sth, $sql, $row); + + # Return if fetched before + return if scalar(keys %CURRENT) > 0; + + # Obtain the current form + $FORM = curform; + # No item specified + return {"msg"=>N_("Please select the user."), + "isform"=>0} + if !defined $FORM->param("sn"); + $sn = $FORM->param("sn"); + + # Find the record + %CURRENT = fetchrec $sn, $THIS_TABLE; + # If this record exist + return {"msg"=>N_("This user does not exist anymore. Please select another one."), + "isform"=>0} + if scalar(keys %CURRENT) == 0; + + # Obtain the belonging groups list + $sql = "SELECT groups.sn AS sn," + . " groups.dsc AS title FROM usermem" + . " INNER JOIN groups ON usermem.grp=groups.sn" + . " WHERE usermem.member=$sn" + . " AND groups.id!=" . $DBH->quote(SU_GROUP) + . " AND groups.id!=" . $DBH->quote(ADMIN_GROUP) + . " AND groups.id!=" . $DBH->quote(ALLUSERS_GROUP) + . " ORDER BY groups.id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $CURRENT{"supgroupcount"} = $sth->rows; + for ($_ = 0; $_ < $CURRENT{"supgroupcount"}; $_++) { + $row = $sth->fetchrow_hashref; + $CURRENT{"supgroup$_"} = 1; + $CURRENT{"supgroup$_" . "sn"} = $$row{"sn"}; + $CURRENT{"supgroup$_" . "title"} = $$row{"title"}; + } + + # Get the admin flag + $CURRENT{"admin"} = is_admin($sn); + $CURRENT{"su"} = is_su($sn); + + # OK + return; +} diff --git a/htdocs/wov/magicat/data/counter.dat b/htdocs/wov/magicat/data/counter.dat new file mode 100644 index 0000000..880d265 --- /dev/null +++ b/htdocs/wov/magicat/data/counter.dat @@ -0,0 +1 @@ +167372 \ No newline at end of file diff --git a/htdocs/wov/magicat/data/editors_notes.txt b/htdocs/wov/magicat/data/editors_notes.txt new file mode 100644 index 0000000..82b6c61 --- /dev/null +++ b/htdocs/wov/magicat/data/editors_notes.txt @@ -0,0 +1,443 @@ +[Guestbook Entry&] +date=2000-06-15 20:00:39 +name=̺ +message= +wG +1. +2.d guestbook +3.q\{ +4.s@{ +5.Xȭpƾ counter +6.q\HƤΤWsܾ +7.HTTP 401 / HTTP 404 ~T +8.o{ +9.XȲέp{ +10.½V{ wovs.cgi +11.HTML 4.01/CSS1 ֳt˴s +12.kn CGI Ҳդ +13.˯ +14.ۧ@vn +15.p覡 +16.sO + +ݧG +1.V CGI Ҳդ +2.Ū̾\ŪsOΪ{ +3.kos links +3.o{_ +5.knd HTML +6.knؿɾz{ wovs.csv + +[Guestbook Entry&] +date=2000-06-15 23:06:05 +name=̺ +message= +u@iסG +1.V CGI ҲդƤw +2.knd HTML ƫOd +3.Ū̾\ŪsOε{Od +4.knp覡Od + +[Guestbook Entry&] +date=2000-06-16 09:09:33 +name=̺ +message= +u@G +1.Netscape +2.kos links +3.knؿ wovs.csv z{ +4.oǥ\˴ + +[Guestbook Entry&] +date=2000-06-16 17:32:22 +name=̺ +message= + +wu@ +1.oǥ\˴Pj +2.OpenFind jMn}~s +3.Netscape +4.q\ HTML + +u@ +1.kos +2.knؿ wovs.csv z{ +3.qHkn E-mail P}sT + +[Guestbook Entry&] +date=2000-06-16 20:02:40 +name=̺ +message= +kn´ + +http://www.wov.idv.tw/ kn + us /newsletters ql + x| /links ko + x + us /images ɥؿ + xu /stylesheets CSS ˦ؿ + xu /scripts Java O{ؿ + xu /cgi-bin CGI {ؿ + xu /data ɥؿ + xu /errors ~Tؿ + x| /icons ϥܥؿ + x + |w /magicat V + us /cgi-bin CGI {ؿ + xu /stylesheets CSS ˦ؿ + xu /scripts Java O{ؿ + xu /data ɥؿ + x| /contents qll + x + |w /r703a W3 sֶƯ + us /newsletters ql + x| /links ko + x + |s /images ɥؿ + u /stylesheets ˦ؿ + | /scripts Java O{ؿ + +[Guestbook Entry&] +date=2000-06-19 07:47:35 +name=̺ +message= +wu@ +1.kos + +u@ +1.koƺ@{ +2.knqlؿ@{ + +[Guestbook Entry&] +date=2000-06-20 00:43:00 +name=̺ +message= +wu@ +1.koƺ@{ + +u@ +1.knqlؿ@{ + +[Guestbook Entry&] +date=2000-06-22 13:49:11 +name=̺ +message= +wu@ +1.qlؿ@{ + +u@ +1.kot + +[Guestbook Entry&] +date=2000-06-27 23:27:43 +name=p +message= +ثeQ쪺IAڷQOΥDDκӤC + +1BXGԩԳA򳣽ͪC@ǤJAphercafeC + +2BkέӤHMݺGoӳOSkʷNѡAOOkʩΤk +HҬ[]AӤHβ´CoӪηNOnjaݬݡAkHOO +ʥFqOΧ޳NOA\hkHۦ[]C + +3BtSAҦpg... + +4BPӺCDnOkPӰաCLoӳ@ǪijCkPӬOOkHHpG +kPӪObPӪ{PAAnkPӺܡHΪ̳oӤ]is +OSϡCuSvNbPӡAӦbukvC + +5BT֥𶢫CO@Ǥkʥ𶢺C + +6BkCաAO]ڤ䦳@ǸưաILb@Ӥ麥ƪ@ +AzLM~AkH馨@ӹPkM~̪׭zAıo +oǺuoBuonAO帡BLlcաApGk[IbͳoةN +NAhnI + +7B^CڤQΰڬA]Lɰ...ıoλyӤ +nCثeQ쪺LNoˤlC + +LAC + + + + + + +[Guestbook Entry&] +date=2000-06-27 23:33:18 +name=p +message= +8B(к])kʥDq(Feminism or Feminist)AkBʺ + + + + + +[Guestbook Entry&] +date=2000-06-29 22:34:18 +name=̺ +message= +wu@: +1.kotΪB(p) +2.]wBsu@@ơA֨CnusvhlBJC + +anada [o~~ko{bΩO~~ ^_*' + +[Guestbook Entry&] +date=2000-08-31 22:44:21 +name=p +message= +bbswƷ|ij +2000/8/30 éMOw篫穱]AȺA׮tAA]hF^ + +wp}]30ӪC + +TwHhGҦ@ˡADHvAO򥻭hOueDȡv~ +CYbh~]Hް_ȯɡ]pGH^AhѨ̺NA +Pp۰Q׹FgBijC + +}]KOӷ~G]DACgwHA@ǸkʡBԤl͵άӷ~s +ihаOOdC + +[Guestbook Entry&] +date=2000-09-16 23:01:03 +name=̺ +message= +kn\ಾܷs Linux DC + +@@G 2000-09-16 +}G http://www.wov.idv.tw/ +DW١G rinse.wov.idv.tw +D}G 211.20.30.100 +@~tΡG Red Hat Linux 6.2 (Linux 2.2.16-3) + +[Guestbook Entry&] +date=2000-09-21 02:15:51 +name=̺ +message= +ݧu@G + +1.XȤR analog C +2.gkñ]w{ק虜C +3.gknؿƮwcC +4.root/imacat KXsC +5.Samba Domain Controller C + +[Guestbook Entry&] +date=2000-09-21 23:50:25 +name=̺ +message= +ɥRݧu@G +6.dOϥλC +7.OC +8.Mailing ListC + +[Guestbook Entry&] +date=2000-09-26 22:52:38 +name=̺ +message= +knĤQTXZ + +@@G 2000-09-26 +oZΡG +@HXG 1378 +@hHG 91 +@LĦa}BWLeq@oqG 78 +@]GhHOdq 13 +bbjc113@hotmail.com +itsshelly@hotmail.com +violalee@hotmail.com +yi_huans@hotmail.com +chunyean@jiannren.org.tw +d870050@ndmc1.ndmctsgh.edu.tw +e871146@student.stit.edu.tw +minerl@changhua.ncue.edu.tw +terencechenn@yammail.com.tw +tsut_1@yammail.com.tw +u8744108@mail.mis.cycu.edu.tw +u8608047@teddy.ttit.edu.tw +webmaster@ip-155-010.shu.edu.tw + +[Guestbook Entry&] +date=2000-09-27 00:02:01 +name=̺ +message= +wu@G +1.HTTP 403 ۭqT +2.kndϥλ +3.q\DUT + +ݧu@ +1.keywords +2.robots.txt + +[Guestbook Entry&] +date=2000-09-28 08:29:06 +name=̺ +message= +szݧu@G +1.XȤR analog C +2.gkñ]w{ק虜C +3.gknؿƮwcC +4.Samba Domain ControllerC +5.OC +6.Mailing ListC +7.KeywordsC +8.robots.txtC + +[Guestbook Entry&] +date=2000-09-28 11:32:58 +name=̺ +message= +wu@G +robots.txt + +[Guestbook Entry&] +date=2000-10-11 21:18:28 +name=̺ +message= +wu@G +1. Perl CGI Apache mod_perl C +2. HTTP header CGI.pm header BzC +3. time2str HTTP::Date IsC +4. Common.pm WC +5. $ID, $THIS_FILE, $THIS_URI ܼ + Perl Ҳէ script BzC +6. HTTP su Keep-Alive C +7. HTTP header Last-Update pC +8. HTML {ҵ{C + +ݧu@G +1.pƾPOǫhC +2.dLdɭp~ bug C +3. CSS {ҵ{C + +[Guestbook Entry&] +date=2000-10-12 00:09:12 +name=̺ +message= +wu@G +1.pƾPOǫhC +2.dLdɭp~ bug C + +[Guestbook Entry&] +date=2000-10-12 04:29:03 +name=̺ +message= +wu@G +1.db mod_perl Udd bug C + +ݧu@G +1. CSS {ҵ{C +2. keywords C + +[Guestbook Entry&] +date=2000-10-19 09:31:35 +name=̺ +message= +wu@G +1.H flock w}ɮסC +2.gknq\{P_y{C +3.}ɿ~ɦۦ沣 HTTP 500 ~TC +4.ϰ۰ʨ{ҡСЫݸɱjC + +[Guestbook Entry&] +date=2000-10-28 14:02:54 +name=̺ +message= +wu@G +1.[jɡBŪg HTTP 500 ~TC +2. HTTP 500 ~TH die AOd~OC +3.gXȭpƾPOy{Aɮwy橵C +4.gXȭpƾPOy{C +5.gXȭpƾ cookies {A֩һݸJҲաC +6.² GD ϫܵ{C +7.@~tΦ۰ʧPOC +8.g Win32 wިPO{AHAΩLDɱb޲zC +9.g Linux wިPO{AHtΨƧPOC + +[Guestbook Entry&] +date=2000-10-29 00:05:08 +name=̺ +message= +wu@G +1.keywords C (YEAH!!!!!!! *^_^*) +2.˯ JavaScript LoŵJC +3.Ȫ٤knۧ@vnsknWۧ@vnC + +[Guestbook Entry&] +date=2000-10-29 03:49:46 +name=̺ +message= +wu@G +1.gkoC + +[Guestbook Entry&] +date=2000-10-30 04:30:29 +name=̺ +message= +wu@ +1.ۭq~Tۧڿ~˴C +2.ۭq HTTP 500 ~ɡAH E-mail q޲z̡C +3.Bz If-Modified HTTP suA + Φۭq HTTP 304 Not Modified ^C +4.sW Last-Modified pзǡA + 쥻HeǡAHɮפǡA + HקKs֨áC +5.su覡Aۭq HTTP 405 Method Not Allowed C + +[Guestbook Entry&] +date=2000-11-06 00:25:32 +name=̺ +message= +wu@G +1. Win32 IIS CGI / Win32 IIS ISAPI / Apache CGI / + Apache mod_perl Apache::Registry / + Apache mod_perl Apache::PerlRun ۮeʡC +2.ɮŪgε|A + HoPAҤṲjۮeʡC +3.gϧε{]pƾB̪sBq\Hơ^ + y{AHM䥦{y{DҤ@PC +4.gq\{y{A + Bzq\nDAAP_̫sA + HTp̫sC + +[Guestbook Entry&] +date=2000-11-09 07:58:52 +name=̺ +message= +wu@G +1.קdƮwŪ覡AMƮwcA + Y[W "&" hXrAgĤ@dŪhX覡A + HקKdePƮwcVcA~Ū~C + +[Guestbook Entry&] +date=2001-04-27 16:59:37 +ip=211.20.30.99 +host=clio.wov.idv.tw +name=p +message= +ثeknݩ󤣩woZAҥHbSXZɭԡAӺ| +HdownUӪPıCMdǤ|TFFAH +activePıAṲ̄ʪҪŶesC + +ҥHAڷQXӪFiH@AڥOUӡCMoǷQkä +ݭnWIѦʡA򥻤WAOڦҧզAʤuC + +Ĥ@ӧıoiH@OukHn()vC( ֦sɡAڤwg +gĤTMF) oӴNOCgkʡBʧOsDCڤ]QCѪA +OڦۤvıoӥiAڭ̨SgOߺDAҥHi +ʹbC + +ĤGөOAOukH@vCNOʬݪάʧGiաC +]~vաAkn`@ǬʰTCڵyL[L +kʺAıosάO@ǬsǥDn٬OHʬD +AèS@ӾXʧGiCMbbs |SoجʧGiA@O +eAGO@ǸkʷNѪbbs F(MjkʥDqB +ak)AҥHıo@@ӤkʴCAڭ̥iHoǥ\C + +HeӷQTbdNnCoF@@_ӡAY +ObdA@jANIŻܥDFCҥHڬOɦVW +@ӪաCӥBڧƱkH@Nd@ˡAiHʥD +̦ۤvZnAAΰӷ~ڭ̤@ߧRC + diff --git a/htdocs/wov/magicat/include/footer.html b/htdocs/wov/magicat/include/footer.html new file mode 100644 index 0000000..dc7386e --- /dev/null +++ b/htdocs/wov/magicat/include/footer.html @@ -0,0 +1,41 @@ +
    + diff --git a/htdocs/wov/magicat/include/header.html b/htdocs/wov/magicat/include/header.html new file mode 100644 index 0000000..8100e0f --- /dev/null +++ b/htdocs/wov/magicat/include/header.html @@ -0,0 +1,14 @@ +
    + +
    diff --git a/htdocs/wov/magicat/index.html.html b/htdocs/wov/magicat/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/wov/magicat/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/magicat/index.html.xhtml b/htdocs/wov/magicat/index.html.xhtml new file mode 100644 index 0000000..068ff4a --- /dev/null +++ b/htdocs/wov/magicat/index.html.xhtml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + +梅姬,妳好 ^_*' + + + + + + + +
    + + +
    + +
    +女聲 LOGO +

    梅姬妳好 ^_*'

    +

    Hi, I’m Magicat

    +
    + +
    +目前訂戶 訂戶人數 人, +訪客 訪客人數 人 +
    + +
    +

    +妳好。我是女聲網站的管家—女巫梅姬。我很厲害,會做各式各樣的事喔。如果妳有需要,請儘管吩咐。 ^_*' +

    +
    + + +
    + + +
    + + + + diff --git a/htdocs/wov/magicat/lib/acctsubj.sql b/htdocs/wov/magicat/lib/acctsubj.sql new file mode 100644 index 0000000..b15aeb4 --- /dev/null +++ b/htdocs/wov/magicat/lib/acctsubj.sql @@ -0,0 +1,532 @@ +BEGIN TRANSACTION; +SET NAMES 'utf8'; +LOCK TABLE acctsubj IN ACCESS EXCLUSIVE MODE; +DELETE FROM acctsubj; +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (372638070, NULL, '1', '資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (779709797, NULL, '2', '負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (309096272, NULL, '3', '業主權益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (471592709, NULL, '4', '營業收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (923390793, NULL, '5', '營業成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (994752472, NULL, '6', '營業費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (962115884, NULL, '7', '營業外收入及費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (657609207, NULL, '8', '所得稅費用(或利益)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (487023601, NULL, '9', '非經常營業損益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (802972443, 372638070, '11', '流動資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (492735146, 372638070, '12', '流動資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (602662532, 372638070, '13', '基金及長期投資', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (601362886, 372638070, '14', '固定資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (463437233, 372638070, '15', '固定資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (813130827, 372638070, '16', '遞耗資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (888645287, 372638070, '17', '無形資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (314299094, 372638070, '18', '其他資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (613824503, 779709797, '21', '流動負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (125993341, 779709797, '22', '流動負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (434222646, 779709797, '23', '長期負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (741596219, 779709797, '28', '其他負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (714179679, 309096272, '31', '資本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (931945860, 309096272, '32', '資本公積', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (926682414, 309096272, '33', '保留盈餘(或累積虧損)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (676136047, 309096272, '34', '權益調整', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (793551134, 309096272, '35', '庫藏股', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (282449457, 309096272, '36', '少數股權', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (256854212, 471592709, '41', '銷貨收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (864303332, 471592709, '46', '勞務收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (685194984, 471592709, '47', '業務收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (585168046, 471592709, '48', '其他營業收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (776405888, 923390793, '51', '銷貨成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (484601714, 923390793, '56', '勞務成本製', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (656473437, 923390793, '57', '業務成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (526117422, 923390793, '58', '其他營業成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (847838836, 994752472, '61', '推銷費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (202779691, 994752472, '62', '管理及總務費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (390721534, 994752472, '63', '研究發展費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (613018617, 962115884, '71', '營業外收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (874636860, 962115884, '72', '營業外收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (933323474, 962115884, '73', '營業外收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (837668432, 962115884, '74', '營業外收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (658230315, 962115884, '75', '營業外費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (963623186, 962115884, '76', '營業外費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (726033439, 962115884, '77', '營業外費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (107974953, 962115884, '78', '營業外費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (531374062, 657609207, '81', '所得稅費用(或利益)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (441557451, 487023601, '91', '停業部門損益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (780750379, 487023601, '92', '非常損益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (576655458, 487023601, '93', '會計原則變動累積影響數', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (403027649, 487023601, '94', '少數股權淨利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (382831496, 802972443, '111', '現金及約當現金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (405656198, 802972443, '112', '短期投資', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (274218035, 802972443, '113', '應收票據', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (236197229, 802972443, '114', '應收帳款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (990834888, 802972443, '118', '其他應收款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (802773250, 492735146, '121', '存貨', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (466973933, 492735146, '122', '存貨', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (434050648, 492735146, '125', '預付費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (349755763, 492735146, '126', '預付款項', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (336471657, 492735146, '128', '其他流動資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (956889094, 492735146, '129', '其他流動資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (425778949, 602662532, '131', '基金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (640420175, 602662532, '132', '長期投資', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (410421689, 601362886, '141', '土地', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (503393820, 601362886, '142', '土地改良物', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (630438297, 601362886, '143', '房屋及建物', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (208976106, 601362886, '144', '機(器)具及設備', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (809268229, 601362886, '145', '機(器)具及設備', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (885610140, 601362886, '146', '機(器)具及設備', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (227011522, 463437233, '151', '租賃資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (733081973, 463437233, '152', '租賃權益改良', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (412438436, 463437233, '156', '未完工程及預付購置設備款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (373441509, 463437233, '158', '雜項固定資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (731330256, 813130827, '161', '遞耗資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (940611412, 888645287, '171', '商標權', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (138316570, 888645287, '172', '專利權', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (563900191, 888645287, '173', '特許權', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (423341137, 888645287, '174', '著作權', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (271146494, 888645287, '175', '電腦軟體', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (552238504, 888645287, '176', '商譽', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (207990296, 888645287, '177', '開辦費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (425720999, 888645287, '178', '其他無形資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (902673037, 314299094, '181', '遞延資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (966392319, 314299094, '182', '閒置資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (310547963, 314299094, '184', '長期應收票據及款項與催收帳款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (134097118, 314299094, '185', '出租資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (393449422, 314299094, '186', '存出保證金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (464092583, 314299094, '188', '雜項資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (526855977, 613824503, '211', '短期借款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (974972811, 613824503, '212', '應付短期票券', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (862092008, 613824503, '213', '應付票據', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (705668893, 613824503, '214', '應付帳款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (815852043, 613824503, '216', '應付所得稅', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (287571641, 613824503, '217', '應付費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (574165963, 613824503, '218', '其他應付款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (674331210, 613824503, '219', '其他應付款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (889654543, 125993341, '226', '預收款項', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (815683575, 125993341, '227', '一年或一營業週期內到期長期負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (149212812, 125993341, '228', '其他流動負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (124114781, 125993341, '229', '其他流動負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (636315607, 434222646, '231', '應付公司債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (663524372, 434222646, '232', '長期借款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (602970356, 434222646, '233', '長期應付票據及款項', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (319948252, 434222646, '234', '估計應付土地增值稅', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (489620321, 434222646, '235', '應計退休金負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (931718543, 434222646, '238', '其他長期負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (301894518, 741596219, '281', '遞延負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (753924220, 741596219, '286', '存入保證金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (492886608, 741596219, '288', '雜項負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (354712237, 714179679, '311', '資本(或股本)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (813886254, 931945860, '321', '股票溢價', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (369189273, 931945860, '323', '資產重估增值準備', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (708649341, 931945860, '324', '處分資產溢價公積', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (315953593, 931945860, '325', '合併公積', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (974832633, 931945860, '326', '受贈公積', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (981029756, 931945860, '328', '其他資本公積', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (782463283, 926682414, '331', '法定盈餘公積', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (511595327, 926682414, '332', '特別盈餘公積', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (266224620, 926682414, '335', '未分配盈餘(或累積虧損)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (306542380, 676136047, '341', '長期股權投資未實現跌價損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (385524103, 676136047, '342', '累積換算調整數', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (764640716, 676136047, '343', '未認列為退休金成本之淨損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (277312763, 793551134, '351', '庫藏股', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (172889653, 282449457, '361', '少數股權', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (960138746, 256854212, '411', '銷貨收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (989545725, 256854212, '417', '銷貨退回', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (745165875, 256854212, '419', '銷貨折讓', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (788006197, 864303332, '461', '勞務收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (636092325, 685194984, '471', '業務收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (560294799, 585168046, '488', '其他營業收入—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (868329781, 776405888, '511', '銷貨成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (715512696, 776405888, '512', '進貨', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (900537319, 776405888, '513', '進料', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (613686812, 776405888, '514', '直接人工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (241828224, 776405888, '515', '製造費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (181591613, 776405888, '516', '製造費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (304113670, 776405888, '517', '製造費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (302614029, 776405888, '518', '製造費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (181853880, 484601714, '561', '勞務成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (760077428, 656473437, '571', '業務成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (100599165, 526117422, '588', '其他營業成本—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (212916398, 847838836, '615', '推銷費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (193074244, 847838836, '616', '推銷費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (882721016, 847838836, '617', '推銷費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (514554832, 847838836, '618', '推銷費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (241184521, 202779691, '625', '管理及總務費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (776997540, 202779691, '626', '管理及總務費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (324522418, 202779691, '627', '管理及總務費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (543298708, 202779691, '628', '管理及總務費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (751717808, 390721534, '635', '研究發展費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (509842953, 390721534, '636', '研究發展費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (334520736, 390721534, '637', '研究發展費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (647304802, 390721534, '638', '研究發展費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (748583072, 613018617, '711', '利息收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (807935097, 613018617, '712', '投資收益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (256128674, 613018617, '713', '兌換利益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (902036208, 613018617, '714', '處分投資收益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (206038830, 613018617, '715', '處分資產溢價收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (699454747, 837668432, '748', '其他營業外收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (988959446, 658230315, '751', '利息費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (548598499, 658230315, '752', '投資損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (947980201, 658230315, '753', '兌換損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (286649244, 658230315, '754', '處分投資損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (537384847, 658230315, '755', '處分資產損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (928820789, 107974953, '788', '其他營業外費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (687819205, 531374062, '811', '所得稅費用(或利益)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (392121771, 441557451, '911', '停業部門損益—停業前營業損益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (816367329, 441557451, '912', '停業部門損益—處分損益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (749878410, 780750379, '921', '非常損益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (575458948, 576655458, '931', '會計原則變動累積影響數', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (867926470, 403027649, '941', '少數股權淨利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (709320418, 382831496, '1111', '庫存現金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (135867103, 382831496, '1112', '零用金/週轉金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (321673137, 382831496, '1113', '銀行存款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (914806389, 382831496, '1116', '在途現金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (408077817, 382831496, '1117', '約當現金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (269390224, 382831496, '1118', '其他現金及約當現金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (114003147, 405656198, '1121', '短期投資—股票', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (420496091, 405656198, '1122', '短期投資—短期票券', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (494011567, 405656198, '1123', '短期投資—政府債券', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (249856724, 405656198, '1124', '短期投資—受益憑證', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (216784076, 405656198, '1125', '短期投資—公司債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (816605640, 405656198, '1128', '短期投資—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (719765760, 405656198, '1129', '備抵短期投資跌價損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (530499921, 274218035, '1131', '應收票據', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (983472201, 274218035, '1132', '應收票據貼現', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (460805176, 274218035, '1137', '應收票據—關係人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (221108972, 274218035, '1138', '其他應收票據', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (190869303, 274218035, '1139', '備抵呆帳-應收票據', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (357244797, 236197229, '1141', '應收帳款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (138999680, 236197229, '1142', '應收分期帳款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (171512916, 236197229, '1147', '應收帳款—關係人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (742536124, 236197229, '1149', '備抵呆帳-應收帳款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (508867657, 990834888, '1181', '應收出售遠匯款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (616644337, 990834888, '1182', '應收遠匯款—外幣', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (302006318, 990834888, '1183', '買賣遠匯折價', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (903867355, 990834888, '1184', '應收收益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (854876598, 990834888, '1185', '應收退稅款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (641587374, 990834888, '1187', '其他應收款—關係人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (654713656, 990834888, '1188', '其他應收款—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (254902966, 990834888, '1189', '備抵呆帳—其他應收款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (517810159, 802773250, '1211', '商品存貨', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (856687013, 802773250, '1212', '寄銷商品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (349662815, 802773250, '1213', '在途商品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (949622536, 802773250, '1219', '備抵存貨跌價損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (269987198, 466973933, '1221', '製成品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (339342377, 466973933, '1222', '寄銷製成品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (795640862, 466973933, '1223', '副產品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (713275114, 466973933, '1224', '在製品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (237383628, 466973933, '1225', '委外加工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (968977504, 466973933, '1226', '原料', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (712112558, 466973933, '1227', '物料', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (944100101, 466973933, '1228', '在途原物料', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (407577736, 466973933, '1229', '備抵存貨跌價損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (880958169, 434050648, '1251', '預付薪資', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (490823964, 434050648, '1252', '預付租金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (917878000, 434050648, '1253', '預付保險費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (970366836, 434050648, '1254', '用品盤存', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (996500723, 434050648, '1255', '預付所得稅', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (473338112, 434050648, '1258', '其他預付費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (820572193, 349755763, '1261', '預付貨款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (739184995, 349755763, '1268', '其他預付款項', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (799510698, 336471657, '1281', '進項稅額', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (360348142, 336471657, '1282', '留抵稅額', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (108172724, 336471657, '1283', '暫付款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (331360768, 336471657, '1284', '代付款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (341189219, 336471657, '1285', '員工借支', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (576455206, 336471657, '1286', '存出保證金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (777109496, 336471657, '1287', '受限制存款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (683845821, 956889094, '1291', '遞延所得稅資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (296452414, 956889094, '1292', '遞延兌換損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (961765736, 956889094, '1293', '業主(股東)往來', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (775706481, 956889094, '1294', '同業往來', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (114433500, 956889094, '1298', '其他流動資產—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (329070757, 425778949, '1311', '償債基金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (141049975, 425778949, '1312', '改良及擴充基金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (263604680, 425778949, '1313', '意外損失準備基金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (205596434, 425778949, '1314', '退休基金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (477861646, 425778949, '1318', '其他基金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (269517922, 640420175, '1321', '長期股權投資', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (237455794, 640420175, '1322', '長期債券投資', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (645642557, 640420175, '1323', '長期不動產投資', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (988732317, 640420175, '1324', '人壽保險現金解約價值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (179029710, 640420175, '1328', '其他長期投資', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (557110012, 640420175, '1329', '備抵長期投資跌價損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (249470146, 410421689, '1411', '土地', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (247906429, 410421689, '1418', '土地—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (852596764, 503393820, '1421', '土地改良物', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (885681227, 503393820, '1428', '土地改良物—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (146158043, 503393820, '1429', '累積折舊—土地改良物', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (732874115, 630438297, '1431', '房屋及建物', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (961492609, 630438297, '1438', '房屋及建物—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (472025359, 630438297, '1439', '累積折舊—房屋及建物', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (443132757, 208976106, '1441', '機(器)具', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (878642052, 208976106, '1448', '機(器)具—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (176634779, 208976106, '1449', '累積折舊—機(器)具', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (167128653, 227011522, '1511', '租賃資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (894698061, 227011522, '1519', '累積折舊—租賃資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (848449822, 733081973, '1521', '租賃權益改良', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (752891550, 733081973, '1529', '累積折舊—租賃權益改良', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (852551772, 412438436, '1561', '未完工程', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (137095705, 412438436, '1562', '預付購置設備款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (917546730, 373441509, '1581', '雜項固定資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (615691173, 373441509, '1588', '雜項固定資產—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (334353583, 373441509, '1589', '累積折舊—雜項固定資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (631601277, 731330256, '1611', '天然資源', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (494736884, 731330256, '1618', '天然資源—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (708161453, 731330256, '1619', '累積折耗—天然資源', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (898829698, 940611412, '1711', '商標權', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (542872803, 138316570, '1721', '專利權', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (664609986, 563900191, '1731', '特許權', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (683710952, 423341137, '1741', '著作權', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (655011428, 271146494, '1751', '電腦軟體', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (491099730, 552238504, '1761', '商譽', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (780653448, 207990296, '1771', '開辦費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (623499301, 425720999, '1781', '遞延退休金成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (485309798, 425720999, '1782', '租賃權益改良', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (255497196, 425720999, '1788', '其他無形資產—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (949323475, 902673037, '1811', '債券發行成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (985965124, 902673037, '1812', '長期預付租金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (761148020, 902673037, '1813', '長期預付保險費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (783218271, 902673037, '1814', '遞延所得稅資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (542736097, 902673037, '1815', '預付退休金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (442130454, 902673037, '1818', '其他遞延資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (440158264, 966392319, '1821', '閒置資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (814490947, 310547963, '1841', '長期應收票據', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (464584131, 310547963, '1842', '長期應收帳款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (246737265, 310547963, '1843', '催收帳款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (269841085, 310547963, '1847', '長期應收票據及款項與催收帳款—關係人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (972215319, 310547963, '1848', '其他長期應收款項', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (273415222, 310547963, '1849', '備抵呆帳—長期應收票據及款項與催收帳款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (342664393, 134097118, '1851', '出租資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (967877399, 134097118, '1858', '出租資產—重估增值', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (465680425, 134097118, '1859', '累積折舊—出租資產', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (169304689, 393449422, '1861', '存出保證金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (691103727, 464092583, '1881', '受限制存款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (408984785, 464092583, '1888', '雜項資產—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (114592873, 526855977, '2111', '銀行透支', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (155572537, 526855977, '2112', '銀行借款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (679537588, 526855977, '2114', '短期借款—業主', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (113826174, 526855977, '2115', '短期借款—員工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (535176493, 526855977, '2117', '短期借款—關係人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (554436773, 526855977, '2118', '短期借款—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (845861820, 974972811, '2121', '應付商業本票', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (937575852, 974972811, '2122', '銀行承兌匯票', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (626442033, 974972811, '2128', '其他應付短期票券', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (343837879, 974972811, '2129', '應付短期票券折價', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (602560682, 862092008, '2131', '應付票據', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (188954343, 862092008, '2137', '應付票據—關係人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (716389216, 862092008, '2138', '其他應付票據', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (778146915, 705668893, '2141', '應付帳款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (277492307, 705668893, '2147', '應付帳款—關係人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (458551240, 815852043, '2161', '應付所得稅', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (247253522, 287571641, '2171', '應付薪工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (995680120, 287571641, '2172', '應付租金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (655731761, 287571641, '2173', '應付利息', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (795817638, 287571641, '2174', '應付營業稅', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (701122645, 287571641, '2175', '應付稅捐—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (415046011, 287571641, '2178', '其他應付費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (303499610, 574165963, '2181', '應付購入遠匯款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (784043626, 574165963, '2182', '應付遠匯款—外幣', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (855311038, 574165963, '2183', '買賣遠匯溢價', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (196069634, 574165963, '2184', '應付土地房屋款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (344246957, 574165963, '2185', '應付設備款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (522820430, 574165963, '2187', '其他應付款—關係人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (256595974, 674331210, '2191', '應付股利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (831657893, 674331210, '2192', '應付紅利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (397555135, 674331210, '2193', '應付董監事酬勞', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (727862503, 674331210, '2198', '其他應付款—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (968398485, 889654543, '2261', '預收貨款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (738337468, 889654543, '2262', '預收收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (563034212, 889654543, '2268', '其他預收款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (602636212, 815683575, '2271', '一年或一營業週期內到期公司債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (661663180, 815683575, '2272', '一年或一營業週期內到期長期借款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (395722825, 815683575, '2273', '一年或一營業週期內到期長期應付票據及款項', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (658576158, 815683575, '2277', '一年或一營業週期內到期長期應付票據及款項—關係人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (968075004, 815683575, '2278', '其他一年或一營業週期內到期長期負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (832790463, 149212812, '2281', '銷項稅額', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (520828967, 149212812, '2283', '暫收款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (900155521, 149212812, '2284', '代收款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (962885081, 149212812, '2285', '估計售後服務/保固負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (667554008, 124114781, '2291', '遞延所得稅負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (150466923, 124114781, '2292', '遞延兌換利益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (229204760, 124114781, '2293', '業主(股東)往來', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (743752020, 124114781, '2294', '同業往來', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (963358650, 124114781, '2298', '其他流動負債—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (994047310, 636315607, '2311', '應付公司債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (564067541, 636315607, '2319', '應付公司債溢(折)價', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (332401391, 663524372, '2321', '長期銀行借款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (241134962, 663524372, '2324', '長期借款—業主', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (536628622, 663524372, '2325', '長期借款—員工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (130108314, 663524372, '2327', '長期借款—關係人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (324261557, 663524372, '2328', '長期借款—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (448115003, 602970356, '2331', '長期應付票據', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (446205039, 602970356, '2332', '長期應付帳款', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (634999950, 602970356, '2333', '長期應付租賃負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (704803584, 602970356, '2337', '長期應付票據及款項—關係人', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (581989752, 602970356, '2338', '其他長期應付款項', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (324818500, 319948252, '2341', '估計應付土地增值稅', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (123105059, 489620321, '2351', '應計退休金負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (816932701, 931718543, '2388', '其他長期負債—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (371625981, 301894518, '2811', '遞延收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (446449324, 301894518, '2814', '遞延所得稅負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (507605492, 301894518, '2818', '其他遞延負債', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (402582161, 753924220, '2861', '存入保證金', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (278544397, 492886608, '2888', '雜項負債—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (828698884, 354712237, '3111', '普通股股本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (328325342, 354712237, '3112', '特別股股本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (459479972, 354712237, '3113', '預收股本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (243470269, 354712237, '3114', '待分配股票股利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (574499376, 354712237, '3115', '資本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (774555174, 813886254, '3211', '普通股股票溢價', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (429550621, 813886254, '3212', '特別股股票溢價', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (783013002, 369189273, '3231', '資產重估增值準備', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (505504878, 708649341, '3241', '處分資產溢價公積', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (198451128, 315953593, '3251', '合併公積', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (677269224, 974832633, '3261', '受贈公積', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (740275783, 981029756, '3281', '權益法長期股權投資資本公積', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (153032059, 981029756, '3282', '資本公積—庫藏股票交易', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (898896606, 782463283, '3311', '法定盈餘公積', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (847258147, 511595327, '3321', '意外損失準備', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (140115980, 511595327, '3322', '改良擴充準備', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (214588543, 511595327, '3323', '償債準備', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (296533405, 511595327, '3328', '其他特別盈餘公積', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (972322693, 266224620, '3351', '累積盈虧', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (782859992, 266224620, '3352', '前期損益調整', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (464874427, 266224620, '3353', '本期損益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (136762997, 306542380, '3411', '長期股權投資未實現跌價損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (361841681, 385524103, '3421', '累積換算調整數', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (800323292, 764640716, '3431', '未認列為退休金成本之淨損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (796953172, 277312763, '3511', '庫藏股', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (332969156, 172889653, '3611', '少數股權', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (650902163, 960138746, '4111', '銷貨收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (873610886, 960138746, '4112', '分期付款銷貨收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (480909546, 989545725, '4171', '銷貨退回', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (501414887, 745165875, '4191', '銷貨折讓', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (861798963, 788006197, '4611', '勞務收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (884801039, 636092325, '4711', '業務收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (859154718, 560294799, '4888', '其他營業收入—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (491926593, 868329781, '5111', '銷貨成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (689575672, 868329781, '5112', '分期付款銷貨成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (513484217, 715512696, '5121', '進貨', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (746574640, 715512696, '5122', '進貨費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (804616176, 715512696, '5123', '進貨退出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (704293010, 715512696, '5124', '進貨折讓', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (746290542, 900537319, '5131', '進料', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (993482623, 900537319, '5132', '進料費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (917839380, 900537319, '5133', '進料退出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (685864530, 900537319, '5134', '進料折讓', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (802855875, 613686812, '5141', '直接人工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (874928238, 241828224, '5151', '間接人工', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (571990586, 241828224, '5152', '租金支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (907852408, 241828224, '5153', '文具用品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (487824813, 241828224, '5154', '旅費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (142992418, 241828224, '5155', '運費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (438547603, 241828224, '5156', '郵電費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (338883877, 241828224, '5157', '修繕費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (405956607, 241828224, '5158', '包裝費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (472485669, 181591613, '5161', '水電瓦斯費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (205274197, 181591613, '5162', '保險費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (372710710, 181591613, '5163', '加工費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (759488099, 181591613, '5166', '稅捐', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (624747656, 181591613, '5168', '折舊', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (373245274, 181591613, '5169', '各項耗竭及攤提', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (857831389, 304113670, '5172', '伙食費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (224729498, 304113670, '5173', '職工福利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (380369895, 304113670, '5176', '訓練費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (756274240, 304113670, '5177', '間接材料', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (716532124, 302614029, '5188', '其他製造費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (152349985, 181853880, '5611', '勞務成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (757538860, 760077428, '5711', '業務成本', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (110601204, 100599165, '5888', '其他營業成本—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (501745153, 212916398, '6151', '薪資支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (484688983, 212916398, '6152', '租金支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (347797343, 212916398, '6153', '文具用品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (184863859, 212916398, '6154', '旅費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (982899606, 212916398, '6155', '運費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (548256289, 212916398, '6156', '郵電費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (201382357, 212916398, '6157', '修繕費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (945252074, 212916398, '6159', '廣告費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (912643138, 193074244, '6161', '水電瓦斯費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (482723373, 193074244, '6162', '保險費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (667516040, 193074244, '6164', '交際費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (696487087, 193074244, '6165', '捐贈', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (252695337, 193074244, '6166', '稅捐', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (464334795, 193074244, '6167', '呆帳損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (205262005, 193074244, '6168', '折舊', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (929323612, 193074244, '6169', '各項耗竭及攤提', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (615973093, 882721016, '6172', '伙食費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (584771226, 882721016, '6173', '職工福利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (193536017, 882721016, '6175', '佣金支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (893417802, 882721016, '6176', '訓練費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (764382524, 514554832, '6188', '其他推銷費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (851874623, 241184521, '6251', '薪資支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (176861982, 241184521, '6252', '租金支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (329717777, 241184521, '6253', '文具用品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (227243112, 241184521, '6254', '旅費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (489915115, 241184521, '6255', '運費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (930339612, 241184521, '6256', '郵電費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (928410985, 241184521, '6257', '修繕費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (128201317, 241184521, '6259', '廣告費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (570663854, 776997540, '6261', '水電瓦斯費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (433448958, 776997540, '6262', '保險費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (681610895, 776997540, '6264', '交際費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (521769517, 776997540, '6265', '捐贈', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (796674668, 776997540, '6266', '稅捐', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (829731934, 776997540, '6267', '呆帳損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (619404096, 776997540, '6268', '折舊', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (201420585, 776997540, '6269', '各項耗竭及攤提', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (761920757, 324522418, '6271', '外銷損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (666597144, 324522418, '6272', '伙食費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (893939737, 324522418, '6273', '職工福利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (695670103, 324522418, '6274', '研究發展費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (617144018, 324522418, '6275', '佣金支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (356589445, 324522418, '6276', '訓練費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (469570957, 324522418, '6278', '勞務費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (877041170, 543298708, '6288', '其他管理及總務費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (285629796, 751717808, '6351', '薪資支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (255109839, 751717808, '6352', '租金支出', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (293609536, 751717808, '6353', '文具用品', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (870547203, 751717808, '6354', '旅費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (885107086, 751717808, '6355', '運費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (987987224, 751717808, '6356', '郵電費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (438300022, 751717808, '6357', '修繕費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (926725156, 509842953, '6361', '水電瓦斯費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (371394354, 509842953, '6362', '保險費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (690276284, 509842953, '6364', '交際費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (991739983, 509842953, '6366', '稅捐', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (871746448, 509842953, '6368', '折舊', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (895377402, 509842953, '6369', '各項耗竭及攤提', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (691533190, 334520736, '6372', '伙食費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (425563486, 334520736, '6373', '職工福利', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (730229601, 334520736, '6376', '訓練費', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (755843878, 334520736, '6378', '其他研究發展費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (935512761, 748583072, '7111', '利息收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (117472286, 807935097, '7121', '權益法認列之投資收益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (740643479, 807935097, '7122', '股利收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (893347443, 807935097, '7123', '短期投資市價回升利益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (788210158, 256128674, '7131', '兌換利益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (164663168, 902036208, '7141', '處分投資收益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (318252073, 206038830, '7151', '處分資產溢價收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (444183965, 699454747, '7481', '捐贈收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (428472055, 699454747, '7482', '租金收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (592692377, 699454747, '7483', '佣金收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (525102294, 699454747, '7484', '出售下腳及廢料收入', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (806095768, 699454747, '7485', '存貨盤盈', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (742624311, 699454747, '7486', '存貨跌價回升利益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (666483691, 699454747, '7487', '壞帳轉回利益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (753349254, 699454747, '7488', '其他營業外收入—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (438653661, 988959446, '7511', '利息費用', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (647865532, 548598499, '7521', '權益法認列之投資損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (514482416, 548598499, '7523', '短期投資未實現跌價損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (929065316, 947980201, '7531', '兌換損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (869388482, 286649244, '7541', '處分投資損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (139281291, 537384847, '7551', '處分資產損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (222152959, 928820789, '7881', '停工損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (674468763, 928820789, '7882', '災害損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (922455040, 928820789, '7885', '存貨盤損', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (309527256, 928820789, '7886', '存貨跌價及呆滯損失', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (571194746, 928820789, '7888', '其他營業外費用—其他', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (792176665, 687819205, '8111', '所得稅費用(或利益)', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (958524871, 392121771, '9111', '停業部門損益—停業前營業損益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (997358780, 816367329, '9121', '停業部門損益—處分損益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (250404501, 749878410, '9211', '非常損益', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (334638274, 575458948, '9311', '會計原則變動累積影響數', now(), 923153018, now(), 923153018); +INSERT INTO acctsubj (sn, parent, code, title, created, createdby, updated, updatedby) VALUES (474145902, 867926470, '9411', '少數股權淨利', now(), 923153018, now(), 923153018); +COMMIT; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov.pm new file mode 100644 index 0000000..27d4667 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov.pm @@ -0,0 +1,70 @@ +# Woman's Voice +# wov.pm: Woman's Voice + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-06 + +package Selima::wov; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +@EXPORT = qw(); + +# Import our site-specific subroutines +use Selima::wov::Config; +push @EXPORT, @Selima::wov::Config::EXPORT; +use Selima::wov::DataVars qw(:all); +push @EXPORT, @Selima::wov::DataVars::EXPORT_OK; +use Selima::wov::HTML; +push @EXPORT, @Selima::wov::HTML::EXPORT; +use Selima::wov::Items; +push @EXPORT, @Selima::wov::Items::EXPORT; +use Selima::wov::Rebuild; +push @EXPORT, @Selima::wov::Rebuild::EXPORT; + +# Import our site-specific classess +use Selima::wov::Checker::Guestbook; +use Selima::wov::Checker::Guestbook::Public; +use Selima::wov::Checker::Newslet; +use Selima::wov::Checker::NLArt; +use Selima::wov::Form::Guestbook; +use Selima::wov::Form::Guestbook::Public; +use Selima::wov::Form::Page; +use Selima::wov::Form::LinkCat; +use Selima::wov::Form::Newslet; +use Selima::wov::Form::NLArt; +use Selima::wov::L10N; +use Selima::wov::List::Guestbook; +use Selima::wov::List::Guestbook::Public; +use Selima::wov::List::Newslets; +use Selima::wov::List::NLArts; +use Selima::wov::List::Search; +use Selima::wov::Processor::Guestbook::Public; +use Selima::wov::Processor::Page; +use Selima::wov::Processor::LinkCat; +use Selima::wov::Processor::Newslet; +use Selima::wov::Processor::NLArt; + +# Import our common modules +use Selima; +push @EXPORT, @Selima::EXPORT; + +@EXPORT_OK = @EXPORT; + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Checker/Guestbook.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Checker/Guestbook.pm new file mode 100644 index 0000000..067a1e9 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Checker/Guestbook.pm @@ -0,0 +1,27 @@ +# Woman's Voice +# Guestbook.pm: The administrative guestbook form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::wov::Checker::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker::Guestbook); + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Checker/Guestbook/Public.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Checker/Guestbook/Public.pm new file mode 100644 index 0000000..d285e9d --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Checker/Guestbook/Public.pm @@ -0,0 +1,60 @@ +# Woman's Voice +# Public.pm: The guestbook form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::wov::Checker::Guestbook::Public; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Selima::Checker::Guestbook::Public); + +use Selima::DataVars qw($DBH); +use Selima::HTTP; +use Selima::Logging; +use Selima::ShortCut; + +# _checkspam_local: Check the local content filter +sub _checkspam_local : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Block HiNet 61.224.20x till 2007-05-01, for 粉領上班族 + $self->_block_spam("_checkspam_local(): Suspicious spamming from 粉領上班族") + if time <= 1177948800 + && $ENV{"REMOTE_ADDR"} =~ /^61\.224\.20\d/; + # OK + return; +} + +# Old blocker +# 清濤命理網站 http://click.twmis.net/ +# $self->_block_spam("_checkspam_local(): Suspicious spamming from http://click.twmis.net/.") +# if $form->param("message") =~ /http:\/\/click\.twmis\.net/i +# || $form->param("url") =~ /http:\/\/click\.twmis\.net/i +# || $form->param("message") =~ /http:\/\/unn\.sexll\.com/i +# || $form->param("url") =~ /http:\/\/unn\.sexll\.com/i +# || $form->param("message") =~ /靈異節目(?:....)?老師/; +# Icegirl +# $self->_block_spam("_checkspam_local(): Suspicious spamming from Icegirl.") +# if $ENV{"REMOTE_ADDR"} eq "218.166.124.90" || $ENV{"REMOTE_ADDR"} eq "218.166.125.76"; + +no utf8; +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Checker/NLArt.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Checker/NLArt.pm new file mode 100644 index 0000000..ba4d12a --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Checker/NLArt.pm @@ -0,0 +1,139 @@ +# Woman's Voice +# NLArt.pm: The newsletter article form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-24 + +package Selima::wov::Checker::NLArt; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::CallForm; +use Selima::ChkFunc; +use Selima::ShortCut; + +use Selima::wov::DataVars qw(:forms); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "nlarts" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_author: Check the author +# Use the default author checker + +# _check_body_h: Check the HTML content body +sub _check_body_h : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("body_h"); + return $error if defined $error; + # Regularize it + $self->_trimtext("body_h"); + # Check if it is filled + $form->param("body_h", "") + if $form->param("body_h") eq __("Fill in the HTML content here."); + return {"msg"=>N_("Please fill in the HTML content.")} + if $form->param("body_h") eq ""; + # Check the length + return {"msg"=>N_("This HTML content is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"body_h"}]} + if length $form->param("body_h") > ${$self->{"maxlens"}}{"body_h"}; + # OK + return; +} + +# _check_body_t: Check the plain text content body +sub _check_body_t : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("body_t"); + return $error if defined $error; + # Regularize it + $self->_trimtext("body_t"); + # Check if it is filled + $form->param("body_t", "") + if $form->param("body_t") eq __("Fill in the plain text content here."); + return {"msg"=>N_("Please fill in the plain text content.")} + if $form->param("body_t") eq ""; + # Check the length + return {"msg"=>N_("This plain text content is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"body_t"}]} + if length $form->param("body_t") > ${$self->{"maxlens"}}{"body_t"}; + # OK + return; +} + +# _check_newslet: Check the newsletter +sub _check_newslet : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("newslet"); + return $error if defined $error; + # Regularize it + $self->_trim("newslet"); + # Check if it is filled + return {"msg"=>N_("Please select a newsletter.")} + if $form->param("newslet") eq ""; + # Check if the newsletter exists + return {"msg"=>N_("This newsletter does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("newslet")}[0], "newslets"; + # OK + return; +} + +# _check_title: Check the title +# Use the default title checker + +# _redir_selnewslet: Suspend and move to the newsletter selection form +sub _redir_selnewslet : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selnewslet"); + call_form FORM_NEWSLETS, undef, "import_selnewslet"; +} + +# _redir_delnewslet: Remove the newsletter +sub _redir_delnewslet : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("delnewslet"); + $self->{"form"}->delete("newslet"); + success_redirect undef; +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Checker/Newslet.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Checker/Newslet.pm new file mode 100644 index 0000000..4cd714b --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Checker/Newslet.pm @@ -0,0 +1,173 @@ +# Woman's Voice +# Newslet.pm: The newsletter form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-22 + +package Selima::wov::Checker::Newslet; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use CGI qw(); + +use Selima::ChkFunc; +use Selima::DataVars qw(:dataman); +use Selima::ShortCut; + +use Selima::wov::Items; + +use Selima::wov::Checker::NLArt; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "newslets" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_arts: Check the articles +sub _check_arts : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Remove the default content + foreach (grep /^art\d+body_t$/, $form->param) { + $form->param($_, "") + if $form->param($_) eq __("Fill in the plain text content here."); + } + foreach (grep /^art\d+body_h$/, $form->param) { + $form->param($_, "") + if $form->param($_) eq __("Fill in the HTML content here."); + } + # Loop each article + for ($_ = 0; !$self->_missing("art$_" . "title"); $_++) { + my ($subform, $checker, $error); + # Skip unselected ones + next if $self->_missing("art$_"); + # Regularize it + $self->_trim("art$_" . "title"); + $self->_trim("art$_" . "author"); + $self->_trimtext("art$_" . "body_t"); + $self->_trimtext("art$_" . "body_h"); + # Check with the subform checker + $subform = new CGI(""); + $subform->param("newslet", $self->{"sn"}) if $self->{"iscur"}; + $subform->param("title", $form->param("art$_" . "title")); + $subform->param("author", $form->param("art$_" . "author")); + $subform->param("body_t", $form->param("art$_" . "body_t")); + $subform->param("body_h", $form->param("art$_" . "body_h")); + $checker = new Selima::wov::Checker::NLArt($subform); + $error = $checker->check("title", "author", "body_t", "body_h"); + return $error if defined $error; + } + + return; +} + +# _check_no: Check the issue number +# Actually this is to set the issue number, but not to check it +sub _check_no : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Current form + if ($self->{"iscur"}) { + $self->{"form"}->param("no", $CURRENT{"no"}); + return; + } + # Create a new issue for this new newsletter + $self->{"form"}->param("no", new_nl_no); + return; +} + +# _check_date: Check the date +sub _check_date : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("date"); + return $error if defined $error; + # Regularize it + $self->_trim("date"); + # Check if it is filled + return {"msg"=>N_("Please fill in the date.")} + if $form->param("date") eq ""; + # Check the length + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + if length $form->param("date") != ${$self->{"maxlens"}}{"date"}; + # Check the date format + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + if length $form->param("date") !~ /^(\d{4})-(\d{2})-(\d{2})$/; + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + unless defined check_date($1, $2, $3); + # OK + return; +} + +# _check_cred_t: Check the plain text credits +sub _check_cred_t : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("cred_t"); + return $error if defined $error; + # Regularize it + $self->_trimtext("cred_t"); + # Check if it is filled + return {"msg"=>N_("Please fill in the plain text credits information.")} + if $form->param("cred_t") eq ""; + # Check the length + return {"msg"=>N_("This plain text credits information is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"cred_t"}]} + if length $form->param("cred_t") > ${$self->{"maxlens"}}{"cred_t"}; + # OK + return; +} + +# _check_cred_h: Check the HTML credits +sub _check_cred_h : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("cred_h"); + return $error if defined $error; + # Regularize it + $self->_trimtext("cred_h"); + # Check if it is filled + return {"msg"=>N_("Please fill in the HTML credits information.")} + if $form->param("cred_h") eq ""; + # Check the length + return {"msg"=>N_("This HTML credits information is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"cred_h"}]} + if length $form->param("cred_h") > ${$self->{"maxlens"}}{"cred_h"}; + # OK + return; +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Config.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Config.pm new file mode 100644 index 0000000..ff4e02f --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Config.pm @@ -0,0 +1,93 @@ +# Woman's Voice +# Config.pm: The web site configuration. + +# Copyright (c) 2003-2020 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-06 + +package Selima::wov::Config; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(siteconf page_replacements); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub siteconf(); +sub page_replacements(); +} + +# Get into the public variable space and initialize them +use lib $ENV{"DOCUMENT_ROOT"} . qw(/../../lib/perl5); +use Selima::CopyYear; +use Selima::DataVars qw(:all); +use Selima::ShortCut; + +use Selima::wov::DataVars qw(:all); + +# siteconf: Subroutine to initialize site configuration +sub siteconf() { + local ($_, %_); + + # The package name and the package title + $PACKAGE = "wov"; + $SITENAME_ABBR = "WOV"; + # The author and the copyright + $AUTHOR = "小招, 依瑪貓"; + $COPYRIGHT = "© 《女聲》電子報。《女聲》電子報保有所有權利。"; + # Document root, the library and the l10n directories + $DOC_ROOT = $ENV{"DOCUMENT_ROOT"}; + $SITE_LIBDIR = $DOC_ROOT . "/magicat/lib/perl5"; + $LOCALEDIR = $DOC_ROOT . "/magicat/locale"; + + # Tables to lock when rebuilding pages + @REBUILD_TABLES = qw(linkcat links linkcatz); + # The local rebuild type labels + %REBUILD_LABELS = ( + "newslets" => N_("Newsletter"), + ); + + # The languages + $DEFAULT_LANG = "zh-tw"; + @ALL_LINGUAS = qw(zh-tw); + + # The site data variables + $SCRIPTS{FORM_NEWSLETS()} = "/magicat/cgi-bin/newslets.cgi", + $SCRIPTS{FORM_NLARTS()} = "/magicat/cgi-bin/nlarts.cgi", + + return; +} + +# page_replacements: Dynamic page elements to be replaced, +# but not part of the content. Used by xfupdate_template(). +sub page_replacements() { + return { + "copyyear" => { + "pattern" => "1999(?:-\\d{4})?", + "content" => copyyear(1999), + }, + "generator" => { + "pattern" => "Selima \\d+\\.\\d+", + "content" => "Selima $Selima::VERSION", + }, + }; +} + +no utf8; +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/DataVars.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/DataVars.pm new file mode 100644 index 0000000..177a7e5 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/DataVars.pm @@ -0,0 +1,58 @@ +# Woman's Voice +# DataVars.pm: The site-wide constants and variables. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-25 + +package Selima::wov::DataVars; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT %EXPORT_TAGS @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +%EXPORT_TAGS = ( + forms => [qw(FORM_NEWSLETS FORM_NLARTS)], +); +@EXPORT_OK = qw(); +my %seen; +%seen = qw(); +foreach my $tag (keys %EXPORT_TAGS) { + push @EXPORT_OK, grep !$seen{$_}++, @{$EXPORT_TAGS{$tag}}; +} +$EXPORT_TAGS{"all"} = [@EXPORT_OK]; +# Prototype declaration +sub clear(); +} + +use Selima::DataVars qw(:forms); + +use constant FORM_NEWSLETS => 1001; +use constant FORM_NLARTS => 1002; + +# clear: Clear the data variables +sub clear() { + local ($_, %_); + + delete $SCRIPTS{FORM_NEWSLETS()}; + delete $SCRIPTS{FORM_NLARTS()}; + + return; +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/Guestbook.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/Guestbook.pm new file mode 100644 index 0000000..3075cda --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/Guestbook.pm @@ -0,0 +1,40 @@ +# Woman's Voice +# Guestbook.pm: The administrative guestbook form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::wov::Form::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form::Guestbook); + +use Selima::MarkAbbr; +use Selima::ShortCut; + +# _html_col_identity: The identity +sub _html_col_identity : method { + $_[0]->_html_coltmpl_text("identity", h_abbr(__("What kind of women you are?"))); +} + +# _html_col_url: The website URL +sub _html_col_url : method { + $_[0]->_html_coltmpl_url("url", h_abbr(__("Website URL.:"))); +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm new file mode 100644 index 0000000..bca41f2 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm @@ -0,0 +1,66 @@ +# Woman's Voice +# Public.pm: The guestbook form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::wov::Form::Guestbook::Public; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Selima::Form::Guestbook::Public); + +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"prefmsg"} = [] if !exists $$args{"prefmsg"}; + push @{$$args{"prefmsg"}}, __("General commercial advertisements, articles unrelated to gender/sex or articles involving personal attacks are not welcomed. They may be deleted without notice. HTML is not supported."); + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_identity: The identity +sub _html_col_identity : method { + $_[0]->_html_coltmpl_text("identity", h_abbr(__("What kind of women you are?")), + h_abbr("(女工、女學生、粉領上班族、公私娼酒吧舞女、打工辣妹……)")); +} + +# _html_col_message: The message +sub _html_col_message : method { + $_[0]->_html_coltmpl_textarea("message", h_abbr(__("Message:")), + h_abbr(__("Fill in your message here."))); +} + +# _html_col_url: The website URL +sub _html_col_url : method { + $_[0]->_html_coltmpl_url("url", h_abbr(__("Website URL.:"))); +} + +no utf8; +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/LinkCat.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/LinkCat.pm new file mode 100644 index 0000000..e1730b8 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/LinkCat.pm @@ -0,0 +1,58 @@ +# Woman's Voice +# LinkCat.pm: The related-link category form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-05 + +package Selima::wov::Form::LinkCat; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form::LinkCat); + +use Selima::FormFunc; +use Selima::HTTP; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(parent id ord title title_en kw hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn parent id ord title title_en kw hid + scats links + created createdby updated updatedby)]; + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/NLArt.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/NLArt.pm new file mode 100644 index 0000000..eb357f9 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/NLArt.pm @@ -0,0 +1,130 @@ +# Woman's Voice +# NLArt.pm: The newsletter article form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-24 + +package Selima::wov::Form::NLArt; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::ChkFunc; +use Selima::CommText; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; +use Selima::Unicode; + +use Selima::wov::Items; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "nlarts" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this article") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to write a new article."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current article."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a article."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(newslet ord title author body_t body_h hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn newslet ord title author body_t body_h hid + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Write a New Newsletter Article"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Newsletter Article"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Newsletter Article"); + } + } + $self = $class->SUPER::new($status, $args); + ${$self->{"maxlens"}}{"ord"} = 2; + return $self; +} + +# _html_col_body_t: The plain text body +sub _html_col_body_t : method { + $_[0]->_html_coltmpl_textarea("body_t", h_abbr(__("Content (text):")), + h(__("Fill in the plain text content here."))); +} + +# _html_col_body_h: The HTML body +sub _html_col_body_h : method { + $_[0]->_html_coltmpl_textarea("body_h", h_abbr(__("Content (HTML):")), + h(__("Fill in the HTML content here."))); +} + +# _html_col_hid: Hide? +sub _html_col_hid : method { + $_[0]->_html_coltmpl_bool("hid", h_abbr(__("Hide?")), + h_abbr(__("Hide this article")), h_abbr(__("Show this article")), + h_abbr(__("Hide this article currently."))); +} + +# _html_col_newslet: The newsletter +sub _html_col_newslet : method { + $_[0]->_html_coltmpl_call("newslet", h_abbr(__("Newsletter:")), \&newslet_title); +} + +# _html_col_ord: The order +sub _html_col_ord : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Set the default order to the half of the maximum + $form->param("ord", 99) + if $self->{"is_first_form"} && $self->{"type"} eq "new"; + $self->_html_coltmpl_text("ord", h_abbr(__("Order:")), undef, + ${$self->{"maxlens"}}{"ord"}); +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/Newslet.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/Newslet.pm new file mode 100644 index 0000000..90da1b8 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/Newslet.pm @@ -0,0 +1,408 @@ +# Woman's Voice +# Newslet.pm: The newsletter form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-17 + +package Selima::wov::Form::Newslet; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::A2HTML; +use Selima::ChkFunc; +use Selima::CommText; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +use Selima::wov::Items; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "newslets" + if !exists $$args{"table"}; + $$args{"deltext"} = __("Delete this newsletter") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = __("This table provides you a form to add a new newsletter."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = __("This table provides you a form to edit a current newsletter."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = __("This table provides you a form to delete a newsletter."); + } + } + $$args{"colspan"} = 3 + if !exists $$args{"colspan"}; + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(no date title cred_t cred_h kw arts hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn no date title cred_t cred_h kw arts hid + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = __("Add a New Newsletter"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = __("Edit a Current Newsletter"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = __("Delete a Newsletter"); + } + } + if (!exists $$args{"preview"}) { + $$args{"preview"} = 1; + } + if ($$args{"preview"} && !exists $$args{"prevmsg"}) { + $$args{"prevmsg"} = __("Preview this newsletter."); + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_arts: The articles +sub _html_col_arts : method { + local ($_, %_); + my ($self, $form, $current, $label, $orig, $new, $mark, $colspan, $cols, $rows); + my ($col, $val, $no, $rowspan, $rows_cur, $rows_new, $count_new); + my ($labeltitle, $labelauthor, $labelbody_t, $labelbody_h, $labelhid); + my ($marktitle, $markauthor, $markbody_t, $markbody_h, $markhid); + my ($hbody_tdef, $hbody_hdef, $texthid, $true, $false); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("arts"); + $colspan = $self->_colspan(-2); + $cols = h($self->{"defsize"}); + $rows = h(10); + $labeltitle = h_abbr(__("Title:")); + $labelauthor = h_abbr(__("Author:")); + $labelbody_t = h_abbr(__("Content (text):")); + $labelbody_h = h_abbr(__("Content (HTML):")); + $labelhid = h_abbr(__("Hide?")); + $hbody_tdef = h(__("Fill in the plain text content here.")); + $hbody_hdef = h(__("Fill in the HTML content here.")); + $texthid = h(__("Hide this article currently.")); + $marktitle = $self->_mark("arttitle"); + $markauthor = $self->_mark("artauthor"); + $markbody_t = $self->_mark("artbody_t"); + $markbody_h = $self->_mark("artbody_h"); + $markhid = $self->_mark("arthid"); + $true = h(__("Hide this article")); + $false = h(__("Show this article")); + + # A form to create a new item + if ($self->{"type"} eq "new") { + # Find the last filled article + for ($_ = 0; defined $form->param("art$_" . "title"); $_++) {} + for ($_--; $_ >= 0 + && $form->param("art$_" . "title") eq "" + && $form->param("art$_" . "author") eq "" + && $form->param("art$_" . "body_t") eq "" + && $form->param("art$_" . "body_h") eq ""; $_--) {} + $count_new = $_ + 1 + 3; + $rows_new = $count_new * 5; + $rows_new = $rows_new > 1? " rowspan=\"" . h($rows_new) . "\"": ""; + $label = h_abbr(__("[numerate,_1,Article]:", 0)); + print << "EOT"; + + +EOT + for ($_ = 0, @_ = qw(); $_ < $count_new; $_++) { + my ($coltitle, $colauthor, $colbody_t, $colbody_h, $colhid); + my ($valtitle, $valauthor, $valbody_t, $valbody_h, $valhid); + $col = "art$_"; + $val = $self->_val_check($col); + $valtitle = $self->_val_text($col . "title"); + $coltitle = h($col . "title"); + $valauthor = $self->_val_text($col . "author"); + $colauthor = h($col . "author"); + $valbody_t = $self->_val_textarea($col . "body_t", $hbody_tdef); + $colbody_t = h($col . "body_t"); + $valbody_h = $self->_val_textarea($col . "body_h", $hbody_hdef); + $colbody_h = h($col . "body_h"); + $valhid = $self->_val_check($col . "hid"); + $colhid = h($col . "hid"); + $col = h($col); + push @_, << "EOT"; + + + + + + + + + + + + + + + + + + + + +EOT + } + print join("\n\n", @_); + print << "EOT"; + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + # Find the last filled article + $rows_cur = $current->param("artcount") > 0? + $current->param("artcount") * 5: 1; + for ($_ = 0; defined $form->param("art$_" . "title"); $_++) {} + for ($_-- ; $_ >= 0 + && $form->param("art$_" . "title") eq "" + && $form->param("art$_" . "author") eq "" + && $form->param("art$_" . "body_t") eq "" + && $form->param("art$_" . "body_h") eq ""; $_--) {} + $count_new = $_ + 1 + 3; + $rows_new = $count_new * 5; + $rowspan = $rows_cur + $rows_new; + $rows_cur = $rows_cur > 1? " rowspan=\"" . h($rows_cur) . "\"": ""; + $rows_new = $rows_new > 1? " rowspan=\"" . h($rows_new) . "\"": ""; + $rowspan = $rowspan > 1? " rowspan=\"" . h($rowspan) . "\"": ""; + $label = h_abbr(__("[numerate,_1,Article]:", 0)); + $orig = h_abbr(__("Original:")); + $new = h_abbr(__("New:")); + print << "EOT"; + + + $orig +EOT + for ($_ = 0, @_ = qw(); $_ < $current->param("artcount"); $_++) { + my ($curtitle, $curauthor, $curbody_t, $curbody_h, $curhid); + $no = h($_ + 1); + $col = "art$_"; + $curtitle = h_abbr($current->param($col . "title")); + $curauthor = h_abbr($current->param($col . "author")); + $curbody_t = a2html($current->param($col . "body_t")); + $curbody_h = a2html($current->param($col . "body_h")); + $curhid = $self->{"cur"}->param($col . "hid")? $true: $false; + push @_, << "EOT"; + $no + $marktitle$labeltitle + $curtitle + + + $markauthor$labelauthor + $curauthor + + + $markbody_t$labelbody_t + $curbody_t + + + $markbody_h$labelbody_h + $curbody_h + + + $markhid$labelhid + $curhid +EOT + } + print @_ > 0? join("\n\n", @_): + " _colspan . ">" . h_abbr(t_none) . "\n"; + print << "EOT"; + + + +EOT + for ($_ = 0, @_ = qw(); $_ < $count_new; $_++) { + my ($coltitle, $colauthor, $colbody_t, $colbody_h, $colhid); + my ($valtitle, $valauthor, $valbody_t, $valbody_h, $valhid); + $col = "art$_"; + $val = $self->_val_check($col); + $valtitle = $self->_val_text($col . "title"); + $coltitle = h($col . "title"); + $valauthor = $self->_val_text($col . "author"); + $colauthor = h($col . "author"); + $valbody_t = $self->_val_textarea($col . "body_t", $hbody_tdef); + $colbody_t = h($col . "body_t"); + $valbody_h = $self->_val_textarea($col . "body_h", $hbody_hdef); + $colbody_h = h($col . "body_h"); + $valhid = $self->_val_check($col . "hid"); + $colhid = h($col . "hid"); + $col = h($col); + push @_, << "EOT"; + + + + + + + + + + + + + + + + + + + + +EOT + } + print join("\n\n", @_); + print << "EOT"; + +EOT + + # A form to delete a current item + } else { + # Find the last filled article + $rows_cur = $current->param("artcount") > 0? + $current->param("artcount") * 5: 1; + $rows_cur = $rows_cur > 1? " rowspan=\"" . h($rows_cur) . "\"": ""; + $label = h_abbr(__("[numerate,_1,Article]:", $current->param("artcount"))); + print << "EOT"; + + $mark$label +EOT + for ($_ = 0, @_ = qw(); $_ < $current->param("artcount"); $_++) { + my ($curtitle, $curauthor, $curbody_t, $curbody_h, $curhid); + $no = h($_ + 1); + $col = "art$_"; + $curtitle = h_abbr($current->param($col . "title")); + $curauthor = h_abbr($current->param($col . "author")); + $curbody_t = a2html($current->param($col . "body_t")); + $curbody_h = a2html($current->param($col . "body_h")); + $curhid = $self->{"cur"}->param($col . "hid")? $true: $false; + push @_, << "EOT"; + $no + $marktitle$labeltitle + $curtitle + + + $markauthor$labelauthor + $curauthor + + + $markbody_t$labelbody_t + $curbody_t + + + $markbody_h$labelbody_h + $curbody_h + + + $markhid$labelhid + $curhid +EOT + } + print @_ > 0? join("\n\n", @_): + " _colspan . ">" . h_abbr(t_none) . "\n"; + print << "EOT"; + +EOT + } + return; +} + +# _html_col_cred_t: The credits, in plain text +sub _html_col_cred_t : method { + $_[0]->_html_coltmpl_textarea("cred_t", h_abbr(__("Credits (text):")), + h(__("Fill in the credits in plain text here."))); +} + +# _html_col_cred_h: The credits, in HTML +sub _html_col_cred_h : method { + $_[0]->_html_coltmpl_textarea("cred_h", h_abbr(__("Credits (HTML):")), + h(__("Fill in the credits in HTML here."))); +} + +# _html_col_hid: Hide? +sub _html_col_hid : method { + $_[0]->_html_coltmpl_bool("hid", h_abbr(__("Hide?")), + h_abbr(__("Hide this newsletter")), h_abbr(__("Show this newsletter")), + h_abbr(__("Hide this newsletter currently."))); +} + +# _html_col_no: The issue number +sub _html_col_no : method { + local ($_, %_); + my ($self, $label, $cur, $mark, $colspan, $thclass, $thcolspan); + $self = $_[0]; + $label = h_abbr(__("Issue:")); + $mark = $self->_mark("no"); + $colspan = $self->_colspan; + + # A form to create a new item + if ($self->{"type"} eq "new") { + $cur = h_abbr(newslet_textno new_nl_no); + print << "EOT" + + $mark$label + $cur + +EOT + + # A current or delete form + } else { + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + $cur = h_abbr(newslet_textno scalar $self->{"cur"}->param("no")); + print << "EOT"; + + $mark$label + $cur + +EOT + } + return; +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/Page.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/Page.pm new file mode 100644 index 0000000..05eb0a9 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Form/Page.pm @@ -0,0 +1,57 @@ +# Woman's Voice +# Page.pm: The web page form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-05 + +package Selima::wov::Form::Page; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form::Page); + +use Selima::FormFunc; +use Selima::HTTP; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(path ord title title_en body kw html hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn path ord title title_en body kw html hid + created createdby updated updatedby)]; + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/HTML.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/HTML.pm new file mode 100644 index 0000000..0854b89 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/HTML.pm @@ -0,0 +1,1152 @@ +# Woman's Voice +# HTML.pm: The HTML web page parts. + +# Copyright (c) 2003-2020 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-06 + +package Selima::wov::HTML; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(html_header html_title html_message html_errmsg); +push @EXPORT, qw(html_nl_pagebar html_body html_newslet html_nl_index); +push @EXPORT, qw(html_body html_links html_links_index html_footer); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub html_header($;$$); +sub html_title($;$$); +sub html_message($); +sub html_errmsg($); +sub html_nav(;$); +sub html_login(;$); +sub html_nav_admin(;$); +sub html_nav_page(;$); +sub html_nl_pagebar($\@;$); +sub html_newslet($;$); +sub html_nl_index(\@;$); +sub html_body($;$); +sub html_links($;$); +sub html_links_index(\@;$); +sub html_links_register(;$); +sub html_footer(;$); +sub merged_tree($$;$); +} + +use Cwd qw(realpath); +use Encode qw(encode FB_HTMLCREF); +use File::Basename qw(basename dirname); +use File::Spec::Functions qw(); +use IO::NestedCapture qw(CAPTURE_STDOUT); +use URI::Escape qw(uri_escape); + +use Selima::A2HTML; +use Selima::AddGet; +use Selima::AltLang; +use Selima::DataVars qw(:author :env :input :list :lninfo :requri :siteconf); +use Selima::ErrMsg; +use Selima::Format; +use Selima::HTTPS; +use Selima::Links; +use Selima::LnInfo; +use Selima::LogIn; +use Selima::MarkAbbr; +use Selima::MungAddr; +use Selima::PageFunc; +use Selima::Preview; +use Selima::ScptPriv; +use Selima::ShortCut; +use Selima::Unicode; +use Selima::XFileIO; + +use vars qw(@ADMIN_SCRIPTS %HEADER %FOOTER); +@ADMIN_SCRIPTS = ( + { "title" => N_("Manage Content"), + "sub" => [ + { "title" => N_("Your Voice"), + "path" => "/magicat/cgi-bin/guestbook.cgi" }, + { "title" => N_("Pages"), + "path" => "/magicat/cgi-bin/pages.cgi" }, + { "title" => N_("Woman Interconnect"), + "path" => "/magicat/cgi-bin/links.cgi" }, + { "title" => N_("Woman Interconnect Categories"), + "path" => "/magicat/cgi-bin/linkcat.cgi" }, + { "title" => N_("Woman Interconnect Categorization"), + "path" => "/magicat/cgi-bin/linkcatz.cgi" }, + { "title" => N_("Newsletters"), + "path" => "/magicat/cgi-bin/newslets.cgi" }, + { "title" => N_("Newsletter Articles"), + "path" => "/magicat/cgi-bin/nlarts.cgi" }, + { "title" => N_("Newsletter Subscribers"), + "path" => "https://rinse.wov.idv.tw/mailman/admin/wov" }, + ], + }, + { "title" => N_("Manage Accounts"), + "sub" => [ + { "title" => N_("Users"), + "path" => "/magicat/cgi-bin/users.cgi" }, + { "title" => N_("Groups"), + "path" => "/magicat/cgi-bin/groups.cgi" }, + { "title" => N_("User Membership"), + "path" => "/magicat/cgi-bin/usermem.cgi" }, + { "title" => N_("Group Membership"), + "path" => "/magicat/cgi-bin/groupmem.cgi" }, + { "title" => N_("User Preferences"), + "path" => "/magicat/cgi-bin/userpref.cgi" }, + { "title" => N_("Script Privileges"), + "path" => "/magicat/cgi-bin/scptpriv.cgi" }, + ], + }, +# { "title" => N_("Manage Accounting"), +# "sub" => [ +# { "title" => N_("Reports"), +# "path" => "/magicat/cgi-bin/acctreps.cgi", +# "https" => 1 }, +# { "title" => N_("Transactions"), +# "path" => "/magicat/cgi-bin/accttrx.cgi", +# "https" => 1 }, +# { "title" => N_("Subjects"), +# "path" => "/magicat/cgi-bin/acctsubj.cgi", +# "https" => 1 }, +# { "title" => N_("Records"), +# "path" => "/magicat/cgi-bin/acctrecs.cgi", +# "https" => 1 }, +# ], +# }, + { "title" => N_("Miscellaneous"), + "sub" => [ + { "title" => N_("Accounting"), + "path" => "https://pythia.wov.idv.tw/accounting" }, + { "title" => N_("Activity Log"), + "path" => "/magicat/cgi-bin/actlog.cgi" }, + { "title" => N_("Rebuild Pages"), + "path" => "/magicat/cgi-bin/rebuild.cgi" }, + { "title" => N_("Analog"), + "path" => "/magicat/analog/" }, + { "title" => N_("Test Script"), + "path" => "/magicat/cgi-bin/test.cgi" }, + ], + }, +); + +# html_header: Display the page header +sub html_header($;$$) { + local ($_, %_); + my ($title, $title_en, $args, $guide); + my ($langname, $langfile); + my ($author, $copyright, $keywords, $copypage); + my ($stylesheets, $javascripts, $favicon, $class, $onload); + my ($titlelang, $skiptobody); + ($title, $title_en, $args) = @_; + # Obtain the page parameters + $args = page_param $args; + # Set the language + $langname = h(ln $$args{"lang"}, LN_NAME); + $langfile = ln($$args{"lang"}, LN_FILENAME); + # Misc + # The copyright message should be already HTML-escaped, + # for the copyright sign "©". + $author = exists $$args{"author"}? h($$args{"author"}): + defined $AUTHOR? h($AUTHOR): undef; + $copyright = exists $$args{"copyright"}? $$args{"copyright"}: + defined $COPYRIGHT? $COPYRIGHT: undef; + $keywords = exists $$args{"keywords"}? h($$args{"keywords"}): undef; + $copypage = exists $$args{"copypage"}? + h($$args{"copypage"}): h("/copying.html"); + # Style sheets + $stylesheets = []; + push @$stylesheets, "/stylesheets/common.css"; + push @$stylesheets, @{$$args{"stylesheets"}} + if exists $$args{"stylesheets"}; + # JavaScripts + $javascripts = []; + if (exists $$args{"javascripts"}) { + push @$javascripts, "/scripts/common.js"; + push @$javascripts, "/scripts/lang.$langfile.js"; + push @$javascripts, @{$$args{"javascripts"}}; + } + # Favorite icon + $favicon = exists $$args{"favicon"}? + h($$args{"favicon"}): h("/favicon.ico"); + # The class of body + $class = exists $$args{"class"}? + " class=\"" . h($$args{"class"}) . "\"": ""; + # The onload JavaScript event handler + $onload = exists $$args{"onload"}? + " onload=\"" . h($$args{"onload"}) . "\"": ""; + # The accessibility guide + $skiptobody = h(__("Skip to the page content area.")); + $guide = h(__("Page Content Area")); + + print << "EOT"; +" ?> + + + + + + +EOT + # Author, copyright and keywords + print "\n" + if defined $author; + print "\n" + if defined $copyright; + print "\n" + if defined $keywords; + print "\" />\n" + if $$args{"static"}; + # The home page + print "\n"; + # The copyright page + print "\n" + if defined $copypage; + # The author contact information + print "\n"; + # The search engine + print "\n"; + # Revelent pages + print "\n" + if exists $$args{"up"}; + print "\n" + if exists $$args{"first"}; + print "\n" + if exists $$args{"prev"}; + print "\n" + if exists $$args{"next"}; + print "\n" + if exists $$args{"last"}; + print "\n" + if exists $$args{"toc"}; + # Style sheets + print "\n" + foreach @$stylesheets; + # JavaScripts + print "\n" + foreach @$javascripts; + # Favorite Icon + print "\n"; + # The title + $titlelang = $$args{"title_lang"} eq $$args{"lang"}? "": + " xml:lang=\"" . h(ln $$args{"title_lang"}, LN_NAME) . "\""; + print "" . h($title) . "\n"; + print << "EOT"; + + + + + + +EOT + + # Show the navigation area + html_nav $args; + # Embrace the content + print << "EOT"; +
    + + +EOT + # Display the title + html_title $title, $title_en, $args unless $$args{"no_auto_title"}; + + return; +} + +# html_title: Print an HTML title +sub html_title($;$$) { + local ($_, %_); + my ($title, $title_en, $args, $h); + ($title, $title_en, $args) = @_; + + # There is an english title + if (defined $title_en) { + $h = << "EOT"; +
    +女聲 LOGO +

    %s

    +

    %s

    +
    + +EOT + printf $h, h_abbr($title), h_abbr($title_en); + + # Only Chinese title + } else { + $h = << "EOT"; +
    +女聲 LOGO +

    %s

    +
    +
    + +EOT + printf $h, h_abbr($title); + } + + return; +} + +# html_message: Print an HTML message +sub html_message($) { + local ($_, %_); + $_ = $_[0]; + return if !defined $_ || $_ eq ""; + $_ = h_abbr($_); + print << "EOT"; +

    $_

    + +EOT + return; +} + +# html_errmsg: Print an HTML error message, a wrapper to html_message() +sub html_errmsg($) { + local ($_, %_); + $_ = $_[0]; + return if !defined $_; + html_message(err2msg $_); + return; +} + +# html_nav: Print the HTML navigation bar +sub html_nav(;$) { + local ($_, %_); + my ($args, $lang, $guide, $FD, @sections); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + $lang = $$args{"lang"}; + # The accessibility guide + $guide = h(__("Navigation Links Area")); + + @sections = qw(); + # Print the primary navigation bar + $HEADER{"file"} = sprintf("%s/magicat/include/header.html", $DOC_ROOT) + if !exists $HEADER{"file"}; + undef $_; + if ( !exists $HEADER{"content"} + || !exists $HEADER{"date"} + || $HEADER{"date"} < ($_ = (stat $HEADER{"file"})[9])) { + $_ = (stat $HEADER{"file"})[9] if !defined $_; + $HEADER{"date"} = $_; + $HEADER{"content"} = hcref_decode ln($lang, LN_CHARSET), xfread $HEADER{"file"}; + } + push @sections, $HEADER{"content"}; + + # Print the section-specific navigation links + push @sections, $$args{"header_html_nav"} + if exists $$args{"header_html_nav"}; + + # Print the log-in information + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_login $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + push @sections, $_ if $_ ne ""; + + # Print the section-specific navigation bar + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + if ($$args{"admin"}) { + html_nav_admin $args; + } else { + html_nav_page $args; + } + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + push @sections, $_ if $_ ne ""; + + # Embrace the navigation links + print << "EOT"; + +
    + +EOT + + return; +} + +# html_login: Print the HTML log-in information +sub html_login(;$) { + local ($_, %_); + my ($args, $msg, $modify, $submit); + $args = $_[0]; + # Skip if not logged-in + return if !defined get_login_sn; + # Obtain the page parameters + $args = page_param $args; + # No log-in bar for static pages + return if $$args{"static"}; + + # The message + $modify = "/magicat/cgi-bin/users.cgi?form=cur&sn=" . get_login_sn; + $msg = sprintf __("Welcome, %s. (Modify)"), + h(get_login_name), h($modify); + $submit = h(__("Log out")); + + print << "EOT"; + +EOT + return; +} + +# html_nav_admin: Print the HTML administrative navigation bar +sub html_nav_admin(;$) { + local ($_, %_); + my ($args, $cgidir, $path, $title); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + + # Find the current CGI directory + $cgidir = "cgi-bin"; + $cgidir = $1 if $REQUEST_PATH =~ /\/(cgi-[a-z0-9]+)\/[a-z0-9]+\.cgi$/; + # Output them + foreach my $cat (@ADMIN_SCRIPTS) { + @_ = qw(); + foreach (@{$$cat{"sub"}}) { + next unless is_script_permitted $$_{"path"}; + ($path, $title) = ($$_{"path"}, $$_{"title"}); + # Fix the path to use the same cgi-* directory alias + $path =~ s/\/cgi-[a-z0-9]+\/([a-z0-9]+\.cgi)$/\/$cgidir\/$1/; + # Fix the path of the HTTPS scripts to use HTTPS + $path = "https://" . https_host . "/$PACKAGE$path" + if exists $$_{"https"} && $$_{"https"} && !is_https; + push @_, sprintf(" %s", + h($path), h_abbr(__($title))); + } + next if @_ == 0; + $title = $$cat{"title"}; + $_ = sprintf(__("%s:"), h_abbr(__($title))); + print "
    \n" + . $_ . "\n" . join(" |\n", @_) . "\n" + . "
    \n" + if @_ > 0; + } + return; +} + +# html_nav_page: Print the HTML page navigation bar +sub html_nav_page(;$) { + local ($_, %_); + my ($args, $tree); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + # Obtain the page tree + $tree = merged_tree $$args{"path"}, $$args{"lang"}, $$args{"preview"}; + # Bounce for nothing + return if !defined $tree + || !exists $$tree{"pages"} + || !defined $$tree{"pages"} + || @{$$tree{"pages"}} <= 1; + + # Output them + print << "EOT"; + + +EOT + return; +} + +# html_nl_pagebar: Print the HTML newsletter page navigation bar +sub html_nl_pagebar($\@;$) { + local ($_, %_); + my ($cur, $all, $args, $start, $end); + my ($url, $cell); + ($cur, $all, $args) = @_; + + # Fit in one page - paging is not needed + return unless @$all > 1; + + # Obtain page parameters + $args = page_param $args; + + # Fewer than 7 pages + if (@$all <= 7) { + $start = 0; + $end = $#$all; + # Near the beginning + } elsif ($cur < 4) { + $start = 0; + $end = 6; + # Near the end + } elsif ($cur > $#$all - 3) { + $start = $#$all - 6; + $end = $#$all; + # Normal, at the middle + } else { + $start = $cur - 3; + $end = $cur + 3; + } + + # Start output + print "
    \n"; + # The index + print " 目錄 |\n"; + # The first page + $cell = h("第一期"); + if ($cur != 0) { + $url = sprintf("wov%04d.html", $$all[0]); + $cell = "" . $cell . ""; + } + print " $cell |\n"; + # The previous page + $cell = h("前一期"); + if ($cur != 0) { + $url = sprintf("wov%04d.html", $$all[$cur - 1]); + $cell = "" . $cell . ""; + } + print " $cell |\n"; + + # Pages before + for ($_ = $start; $_ < $cur; $_++) { + $url = sprintf("wov%04d.html", $$all[$_]); + $cell = "" . h($$all[$_]) . ""; + print " $cell |\n"; + } + # Current page + $cell = h($$all[$cur]); + print " $cell |\n"; + # Pages after + for ($_ = $cur + 1; $_ <= $end; $_++) { + $url = sprintf("wov%04d.html", $$all[$_]); + $cell = "" . h($$all[$_]) . ""; + print " $cell |\n"; + } + + # The next page + $cell = h("下一期"); + if ($cur != $#$all) { + $url = sprintf("wov%04d.html", $$all[$cur + 1]); + $cell = "" . $cell . ""; + } + print " $cell |\n"; + # The last page + $cell = h("最新期"); + if ($cur != $#$all) { + $url = sprintf("wov%04d.html", $$all[$#$all]); + $cell = "" . $cell . ""; + } + print " $cell\n"; + print "
    "; + + return; +} + +# html_newslet: Print the HTML newsletter +sub html_newslet($;$) { + local ($_, %_); + my ($page, $args, @arts, $allarts); + ($page, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Obtain the articles + if (defined $$args{"preview"}) { + for ($_ = 0, my $o = 1, @arts = qw(); exists $$page{"art$_" . "title"}; $_++) { + push @arts, { + "ord" => $o++, + "title" => $$page{"art$_" . "title"}, + "author" => $$page{"art$_" . "author"}, + "body_h" => $$page{"art$_" . "body_h"}, + } if exists $$page{"art$_"} + && !(exists $$page{"art$_" . "hid"} + && $$page{"art$_" . "hid"}); + } + } else { + @arts = @{$$page{"arts"}}; + } + + # Output the credit information + my ($textno, $date, $creds); + $textno = h(($$page{"no"} == 1)? "創刊號": + sprintf("第%03d期", $$page{"no"})); + @_ = localtime $$page{"date"}; + $_[5] += 1900; + $_[4]++; + $date = sprintf "%d年%d月%d日", @_[5,4,3]; + $creds = $$page{"cred_h"}; + @_ = map sprintf("
  • %s/%s
  • \n", $$_{"ord"}, + h($$_{"title"}), h($$_{"author"})), @arts; + $allarts = "
      \n" . join("", @_) . "
    \n"; + print << "EOT"; +
    +《女聲》$textno $date 編輯:小招/依瑪貓
    +$creds +本期文章:
    +$allarts +
    + +
    + +EOT + + # Output the articles + @_ = map sprintf("
    \n" + . "

    %s

    \n" + . "
    %s
    \n\n" + . "%s\n" + . "
    \n\n", + $$_{"ord"}, h($$_{"title"}), h($$_{"author"}), $$_{"body_h"}), @arts; + print join "
    \n\n", @_; + return; +} + +# html_nl_index: Print the HTML newsletters index +sub html_nl_index(\@;$) { + local ($_, %_); + my ($newslets, $args, $newslet); + ($newslets, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Nothing to output + if (@$newslets == 0) { + print << "EOT"; +

    目前沒有已出刊的女聲可供閱讀。

    + +EOT + return; + } + + # Output the newsletter index */ + print << "EOT"; + + + + + + + + + + +EOT + foreach $newslet (@$newslets) { + my ($textno, $date, $title, $url, $arts); + $textno = h($$newslet{"no"} == 1? "創刊號": + sprintf "第%03d期", $$newslet{"no"}); + $date = h(myfmtdate $$newslet{"date"}); + $title = h($$newslet{"title"}); + $url = h(sprintf "wov%04d.html", $$newslet{"no"}); + @_ = map sprintf("
  • %s/%s
  • \n", + h($$_{"title"}), h($$_{"author"})), @{$$newslet{"arts"}}; + $arts = "
      \n" . join("", @_) . "
    \n"; + print << "EOT"; + + + + + + + + + + +EOT + } + print << "EOT"; +
    已出刊女聲目錄
    期數出刊日標題
    $textno
    $date

    $title

    $arts +
    + +EOT + + # Output the newsletter download link + my ($file, $basefile, $size); + $file = $DOC_ROOT . "/data/wovs.zip"; + if (-f $file) { + $basefile = h(basename($file)); + $size = h(fmtsize((stat $file)[7])); + print << "EOT"; +
    +
    下載所有過期女聲
    +

    $basefile, $size

    +
    + +EOT + } + + # Output the search function + print << "EOT"; +
    +
    +
    女聲全文檢索
    +
    + +

    妳可以在下方填上妳想搜尋的詞彙,然後按【搜尋】鈕,在女聲中尋找妳想要的資料。

    + + +
    +
    +
    + + +EOT + + return; +} + +# html_body: Print the HTML body +sub html_body($;$) { + local ($_, %_); + my ($page, $args); + ($page, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Output the picture + # To be done + + # Output the content + print "" . (!exists $$page{"html"} || !$$page{"html"}? + a2html($$page{"body"}): $$page{"body"}) . "\n\n"; + + return; +} + +# html_links: Print the HTML links list +sub html_links($;$) { + local ($_, %_); + my ($page, $args); + ($page, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Output the breadcrumb trai + @_ = qw(); + push @_, "" . h("女網牽手") . ""; + foreach my $parent (@{$$page{"parents"}}) { + push @_, "" + . h($$parent{"title"}) . ""; + } + push @_, h($$page{"title"}); + print "
    \n" + . join(" /\n", @_) . "\n
    \n\n"; + + # Output the subcategories + if (@{$$page{"scats"}} > 0) { + print << "EOT"; +
    +
    +
      +EOT + # Output the even half + for ($_ = 0; $_ < @{$$page{"scats"}}; $_ += 2) { + my ($cat, $title); + $cat = ${$$page{"scats"}}[$_]; + $title = h($$cat{"title"}); + $title .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
    • " + . "$title
    • \n"; + } + print << "EOT"; +
    +
    +EOT + if (@{$$page{"scats"}} > 1) { + print << "EOT"; +
    +
      +EOT + # Output the odd half + for ($_ = 1; $_ < @{$$page{"scats"}}; $_ += 2) { + my ($cat, $title); + $cat = ${$$page{"scats"}}[$_]; + $title = h($$cat{"title"}); + $title .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
    • " + . "$title
    • \n"; + } + print << "EOT"; +
    +
    +EOT + } + print << "EOT"; +
    + +EOT + } + + # Output the links + if (@{$$page{"links"}} > 0) { + my $emailalt; + $emailalt = h(__("E-mail")); + print "
      \n"; + foreach my $link (@{$$page{"links"}}) { + my ($url, $title, $ctitle, $dsc); + $url = h($$link{"url"}); + $title = h($$link{"title"}); + print "
    1. \n"; + print "
      \n
      \n" + if defined $$link{"email"}; + # Output the link icon + print "\"$title\"
      \n" + if defined $$link{"icon"}; + # Output the site title + $ctitle = is_usascii_printable($$link{"title"})? + "$title": $title; + if (defined $$link{"title_2ln"}) { + $_ = h($$link{"title_2ln"}); + $_ = "$_" + if is_usascii_printable($$link{"title_2ln"}); + $ctitle .= " $_"; + } + print "$ctitle
      \n"; + # Output the URL + print __("URL.:") . " $url
      \n"; + # Output other information + if (defined $$link{"email"}) { + print __("E-mail:") . " "; + print "\n"; + print "\n"; + print mung_email_span(h($$link{"email"})) . "
      \n"; + } + print __("Address:") . " " . h($$link{"addr"}) . "
      \n" + if defined $$link{"addr"}; + print __("Tel.:") . " " . h($$link{"tel"}) . "
      \n" + if defined $$link{"tel"}; + print __("Fax.:") . " " . h($$link{"fax"}) . "
      \n" + if defined $$link{"fax"}; + # Output the description + $dsc = $$link{"dsc"}; + print h($dsc) . "
      \n"; + print "
      \n
      \n" if defined $$link{"email"}; + print "
    2. \n\n"; + } + print "
    \n\n"; + } + + # Print the link registration form + html_links_register $args; + return; +} + +# html_links_index: Print the HTML link categories index +sub html_links_index(\@;$) { + local ($_, %_); + my ($cats, $args); + ($cats, $args) = @_; + + # Obtain page parameters + $args = page_param $args; + + # Display the foreword + print << "EOT"; +
    +

    女人牽手,總是多了一份親暱。

    + +

    幼稚園、小學時期,女人們牽手上廁所;中學時期,女人們牽手面對成長的 +喜怒哀樂;畢業後或念大學,或出社會,女人們牽手分享彼此的感情世界與就業 +環境……藉由牽手,女人的情感、資訊流轉,女人的生命由此連結。

    + +

    稍離現實的生活,女人進入虛擬網路的空間,藉由女網牽手,女人永不孤獨。

    +
    + +EOT + + # Bounce for nothing + if (@$cats == 0) { + print "

    " . h(__("The database is empty.")) . "

    \n\n"; + return; + } + + # Output the root categories + print << "EOT"; +
    +
    +
      +EOT + # Output the even half + for ($_ = 0; $_ < @$cats; $_ += 2) { + my ($cat, $title); + $cat = $$cats[$_]; + $title = h($$cat{"title"}); + $title .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
    • " + . "$title
    • \n"; + } + print << "EOT"; +
    +
    +EOT + if (@$cats > 1) { + print << "EOT"; +
    +
      +EOT + # Output the odd half + for ($_ = 1; $_ < @$cats; $_ += 2) { + my ($cat, $title); + $cat = $$cats[$_]; + $title = h($$cat{"title"}); + $title .= " (" + . h($$cat{"links"}) . ")" + if $$cat{"links"} > 0; + print "
    • " + . "$title
    • \n"; + } + print << "EOT"; +
    +
    +EOT + } + print << "EOT"; +
    + +EOT + # Print the link registration form + html_links_register $args; + return; +} + +# html_links_register: Print the HTML link registration form +sub html_links_register(;$) { + local ($_, %_); + my ($args, $subject); + $args = $_[0]; + # Obtain page parameters + $args = page_param $args; + + $subject = uri_escape(encode(ln($$args{"lang"}, LN_CHARSET), "[女聲回函] 網站登錄", FB_HTMLCREF)); + + print << "EOT"; +
    +

    女網牽手‧和妳牽手

    + +
    +

    女人上網,伴手相牽。我們希望和各種不同國女人發聲的網站,或為女人努力發聲的網站串連起來,匯集成女人自己的網路空間。若妳也願意和我們牽手,請填好下表寄出。我們將儘快查詢妳的網址是否正確,然後加入女網牽手中。

    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    + +
    +
    + +EOT + return; +} + +# html_footer: Print the HTML footer +sub html_footer(;$) { + local ($_, %_); + my ($args, $lang); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + $lang = $$args{"lang"}; + + # Embrace the content + print << "EOT"; +
    + +EOT + # Print the section-specific navigation bar + print "
    \n" . $$args{"footer_html_nav"} . "\n\n" + if exists $$args{"footer_html_nav"}; + + # Print the common footer + $FOOTER{"file"} = sprintf("%s/magicat/include/footer.html", $DOC_ROOT) + if !exists $FOOTER{"file"}; + undef $_; + if ( !exists $FOOTER{"content"} + || !exists $FOOTER{"date"} + || $FOOTER{"date"} < ($_ = (stat $FOOTER{"file"})[9])) { + $_ = (stat $FOOTER{"file"})[9] if !defined $_; + $FOOTER{"date"} = $_; + $FOOTER{"content"} = hcref_decode ln($lang, LN_CHARSET), xfread $FOOTER{"file"}; + } + $_ = $FOOTER{"content"}; + $FOOTER{"perl"} = {} if !exists $FOOTER{"perl"}; + if ($$args{"static"}) { + s/\n+\n+/\n\n/; + } elsif ($IS_MODPERL) { + if (!exists ${$FOOTER{"perl"}}{"modperl"}) { + ${$FOOTER{"perl"}}{"modperl"} = << "EOT"; +
    +%s +

    %s

    +
    +EOT + ${$FOOTER{"perl"}}{"modperl"} = sprintf(${$FOOTER{"perl"}}{"modperl"}, + h(__("mod_perl -- Speed, Power, Scalability")), + __("This script is written in Perl and optimized for mod_perl.")); + ${$FOOTER{"perl"}}{"modperl"} =~ s/()/$1 hreflang="en"$2/g + if $lang ne "en"; + } + s/\n/${$FOOTER{"perl"}}{"modperl"}/; + } else { + if (!exists ${$FOOTER{"perl"}}{"cgi"}) { + ${$FOOTER{"perl"}}{"cgi"} = << "EOT"; +
    +

    %s

    +
    +EOT + ${$FOOTER{"perl"}}{"cgi"} = sprintf(${$FOOTER{"perl"}}{"cgi"}, + __("This script is written in
    Perl.")); + ${$FOOTER{"perl"}}{"cgi"} =~ s/()/$1 hreflang="en"$2/g + if $lang ne "en"; + } + s/\n/${$FOOTER{"perl"}}{"cgi"}/; + } + print $_; + + # Show the HTML preview mark + html_preview_mark $args; + + print "\n\n\n"; + return; +} + +# merged_tree: Get the page tree in a directory +sub merged_tree($$;$) { + local ($_, %_); + my ($path, $lang, $preview); + ($path, $lang, $preview) = @_; + + # Return special areas + if ($path =~ /^\/links\//) { + return link_tree($path, $lang, $preview); + # Non-pages (scripts... etc) + } else { + return {}; + } +} + +no utf8; +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Items.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Items.pm new file mode 100644 index 0000000..c1ee57e --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Items.pm @@ -0,0 +1,130 @@ +# Woman's Voice +# Items.pm: The data record related subroutines. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-23 + +package Selima::wov::Items; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(new_nl_no newslet_textno newslet_title newslet_no); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub new_nl_no(); +sub newslet_textno($); +sub newslet_title($); +sub newslet_no($); +} + +use Encode qw(encode); + +use Selima::ChkFunc; +use Selima::CommText; +use Selima::DataVars qw(:db); + +# new_nl_no: Get the issue number for a new newsletter +sub new_nl_no() { + local ($_, %_); + my ($sql, $sth); + $sql = "SELECT no FROM newslets" + . " ORDER BY no DESC LIMIT 1;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return 1 if $sth->rows < 1; + return ${$sth->fetch}[0] + 1; +} + +# newslet_textno: Obtain the text representation of the issue number +sub newslet_textno($) { + local ($_, %_); + $_ = $_[0]; + # Invalid - returned "as is" + return $_ if !defined $_ || /\D/ || $_ < 0; + # First issue + return "創刊號" if $_ == 1; + return sprintf "第%03d期", $_; +} + +# newslet_title: Obtain a newsletter title +sub newslet_title($) { + local ($_, %_); + my ($sn, $sql, $sth); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + + # Check the serial number first + return t_na if !check_sn $sn; + + # Query + @_ = qw(); + $_ = "CASE no WHEN 1 THEN '創刊號' ELSE " + . $DBH->strcat("'第'", "lpad(cast(no AS text), 3, 0)", "'期'") . " END"; + push @_, encode("UTF-8", $_); + push @_, "' '"; + push @_, "title"; + push @_, "' '"; + push @_, "extract(year FROM date)"; + push @_, "'.'"; + push @_, "lpad(cast(extract(month FROM date) AS text), 2, 0)"; + push @_, "'.'"; + push @_, "lpad(cast(extract(day FROM date) AS text), 2, 0)"; + $_ = $DBH->strcat(@_) . " AS title"; + $sql = "SELECT $_ FROM newslets" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return t_na unless $sth->rows == 1; + + # Found + return ${$sth->fetch}[0]; +} + +# newslet_no: Obtain a newsletter number +sub newslet_no($) { + local ($_, %_); + my ($sn, $sql, $sth); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + + # Check the serial number first + return t_na if !check_sn $sn; + + # Query + $sql = "SELECT no FROM newslets" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return t_na unless $sth->rows == 1; + + # Found + return ${$sth->fetch}[0]; +} + +no utf8; +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/L10N.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/L10N.pm new file mode 100644 index 0000000..8f52600 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/L10N.pm @@ -0,0 +1,38 @@ +# Woman's Voice +# L10N.pm: The localization class. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-26 + +package Selima::wov::L10N; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +return 1; + +# The Chinese (Taiwan) localized messages. +package Selima::wov::L10N::zh_tw; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +sub numerate : method { $_[2] } + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/List/Guestbook.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/List/Guestbook.pm new file mode 100644 index 0000000..6e8f8f9 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/List/Guestbook.pm @@ -0,0 +1,47 @@ +# Woman's Voice +# Guestbook.pm: The administrative guestbook message list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::wov::List::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Guestbook); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "guestbook" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Message"): + __("Manage Your Voice"); + # Column labels + $self->col_labels( + "identity" => __("What kind of women you are?"), + ); + return $self; +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/List/Guestbook/Public.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/List/Guestbook/Public.pm new file mode 100644 index 0000000..7874493 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/List/Guestbook/Public.pm @@ -0,0 +1,36 @@ +# Woman's Voice +# Public.pm: The guestbook message list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::wov::List::Guestbook::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Guestbook::Public); + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + return $self; +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/List/NLArts.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/List/NLArts.pm new file mode 100644 index 0000000..7faacc5 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/List/NLArts.pm @@ -0,0 +1,99 @@ +# Woman's Voice +# NLArts.pm: The newsletter article list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-24 + +package Selima::wov::List::NLArts; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "nlarts" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Newsletter Article"): + __("Manage Newsletter Articles"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "-newslet,ord"; + # Columns that should display its brief instead + push @{$self->{"COLS_BRIEF"}}, qw(body_t body_h); + # Column labels + $self->col_labels( + "newslet" => __("Newsletter"), + "author" => __("Author"), + "body_t" => __("Content (text)"), + "body_h" => __("Content (HTML)"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Write a new article.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a article:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article].", $self->{"total"}); + # List result + } else { + return __("[*,_1,article].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/List/Newslets.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/List/Newslets.pm new file mode 100644 index 0000000..cc11d1d --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/List/Newslets.pm @@ -0,0 +1,98 @@ +# Woman's Voice +# Newslets.pm: The newsletter list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-17 + +package Selima::wov::List::Newslets; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "newslets" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + __("Select a Newsletter"): + __("Manage Newsletters"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "-no"; + # Columns that should display its brief instead + push @{$self->{"COLS_BRIEF"}}, qw(cred_t cred_h); + # Column labels + $self->col_labels( + "no" => __("Issue"), + "cred_t" => __("Credits (text)"), + "cred_h" => __("Credits (HTML)"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(__("Add a new newsletter.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search for a newsletter:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,newsletter].", $self->{"total"}); + # List result + } else { + return __("[*,_1,newsletter].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,newsletter], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,newsletter], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/List/Search.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/List/Search.pm new file mode 100644 index 0000000..0f9935b --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/List/Search.pm @@ -0,0 +1,194 @@ +# Woman's Voice +# Search.pm: The web site full-text search result list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-28 + +package Selima::wov::List::Search; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::Logging; +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The page title + if (!defined $self->{"query"}) { + $self->{"title"} = "女聲全文檢索"; + $self->{"etitle"} = "Website Search"; + } else { + $self->{"title"} = "全文檢索結果"; + $self->{"etitle"} = "Search Result"; + } + $self->{"view"} = "search_list"; + $self->{"COLS_NO_SEARCH"} = [qw(section path nlpath html piority)]; + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my $self; + $self = $_[0]; + # No search specified + if (!defined $self->{"query"}) { + $self->{"total"} = undef; + return $self->{"error"}; + } + # Check the query phrase + # Regularize it + $self->{"query"} =~ s/^\s*(.*?)\s*$/$1/; + # Check if it is filled + if ($self->{"query"} eq"") { + $self->{"total"} = undef; + $self->{"error"} = {"msg"=>N_("Please fill in your query.")}; + return $self->{"error"}; + } + # Run the parent method + $self->SUPER::fetch; + # Add an activity log record + actlog("Query with phrase \"" . $self->{"query"} . "\"."); + # Done + return $self->{"error"}; +} + +# sql_orderby: Get the SQL ORDER BY phase +# Always return nothing +sub sql_orderby : method { return ""; } + +# html_newlink: Display a link to add a new item +# Make it a null function +sub html_newlink : method {} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(__("Search in the website:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article].", $self->{"total"}); + # List result + } else { + return __("[*,_1,article].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return __("Your query found [*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return __("[*,_1,article], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +# html_list: List the items +sub html_list : method { + local ($_, %_); + my ($self); + $self = $_[0]; + # Do not show the list + return if !defined $self->{"total"}; + # No record to be listed + return if $self->{"total"} == 0; + + print << "EOT"; +
      +EOT + + # Print each record + foreach my $current (@{$self->{"current"}}) { + my ($url, $abstract); + $url = h($$current{"path"}); + $abstract = $self->query_abstract($current); + if ($$current{"section"} eq "newsletters") { + my ($title, $author, $newsletter, $nlurl); + $title = h($$current{"title"}); + $author = h($$current{"author"}); + $newsletter = h($$current{"newsletter"}); + $nlurl = h($$current{"nlpath"}); + + print << "EOT"; +
    1. $title $author

      +
      $newsletter
      +EOT + } elsif ($$current{"section"} eq "guestbook") { + my ($author, $date); + $author = defined $$current{"author"}? + " " . h($$current{"author"}) . "": ""; + $date = h($$current{"date"}); + + print << "EOT"; +
    2. $date 留言$author

      +
      妳的女聲
      +EOT + } elsif ($$current{"section"} eq "links") { + my $title; + $title = h($$current{"title"}); + + print << "EOT"; +
    3. $title

      +
      女網牽手
      +EOT + } elsif ($$current{"section"} eq "pages") { + my $title; + $title = h($$current{"title"}); + + print << "EOT"; +
    4. $title

      +EOT + } + print "\n

      $abstract

      \n" if defined $abstract; + print << "EOT"; +
    5. + +EOT + } + print << "EOT"; +
    + +EOT + return; +} + +no utf8; +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/Guestbook/Public.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/Guestbook/Public.pm new file mode 100644 index 0000000..7c9dca8 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/Guestbook/Public.pm @@ -0,0 +1,142 @@ +# Woman's Voice +# Public.pm: The guestbook data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-19 + +package Selima::wov::Processor::Guestbook::Public; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Selima::Processor::Guestbook); + +use Selima::Country; +use Selima::DataVars qw(:env :input :scptconf); +use Selima::Format; +use Selima::GeoIP; +use Selima::Guest; +use Selima::RemoHost; +use Selima::Unicode; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[0]->param("form", "new"); + $_[0]->param("confirm", 1); + $self = $class->SUPER::new(@_); + $self->{"notify"} = 1; + $self->{"debug"} = 1; + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my $self; + ($self, @_) = @_; + $self->SUPER::_save_cols(@_); + $self->{"cols"}->{"login"} = 723676436; + return; +} + +# _other_tasks: Perform tasks other than column updates +sub _other_tasks : method { + local ($_, %_); + my ($self, $form); + my ($mail, $body, $charset); + $self = $_[0]; + return unless $self->{"notify"}; + $form = $self->{"form"}; + + # Compose the mail body + $body = ""; + $body .= "若要編輯或刪除這則留言,請連上以下網址:\n"; + $body .= "http://" . $ENV{"SERVER_NAME"} . "/magicat/cgi-bin/guestbook.cgi" + . "?form=cur&sn=" . $self->{"sn"} . "\n\n"; + $body .= "日期: " . fmttime . "\n"; + @_ = qw(); + push @_, ctname_zhtw country_lookup; + push @_, remote_host if defined remote_host; + $body .= "來自: " . $ENV{"REMOTE_ADDR"} + . " (" . join(", ", @_) . ")\n"; + $body .= "簽名: " . $form->param("name") . "\n" + if $form->param("name") ne ""; + $body .= "物種: " . $form->param("identity") . "\n" + if $form->param("identity") ne ""; + $body .= "地點: " . $form->param("location") . "\n" + if $form->param("location") ne ""; + $body .= "信箱: " . $form->param("email") . "\n" + if $form->param("email") ne ""; + $body .= "網址: " . $form->param("url") . "\n" + if $form->param("url") ne "" && $form->param("url") ne "http://"; + $body .= "留言:\n\n" . $form->param("message") . "\n\n"; + $body .= "原始內容:\n" . $USER_INPUT{"POST_RAWDATA"} . "\n"; + + # Collecting Debugging infomation + if ($self->{"debug"}) { + $body .= "\n"; + $body .= "===== Start Debugging Infomation =====\n"; + if ($IS_MODPERL) { + $_ = $IS_MP2? Apache2::RequestUtil->request->as_string: + Apache->request->as_string; + s/^X-Selima-[^\n]+\n//mg; + s/^((?:[^\n]+\n)+).+?$/$1/s; + $body .= $_; + } else { + foreach (sort grep !/^HTTP_X_SELIMA_/, grep /^HTTP_/, keys %ENV) { + my $hname; + $hname = $_; + $hname =~ s/^HTTP_//; + $hname =~ s/_/-/g; + $hname =~ s/(\w)(\w+)/$1 . lc $2/ge; + $body .= "$hname: $ENV{$_}\n"; + } + } + $body .= "===== End Debugging Infomation =====\n"; + } + + # Set the best appropriate output character set + $charset = is_charset($body, "Big5")? "Big5": "UTF-8"; + + # Compose the mail + $mail = new Selima::Mail; + $mail->charset($charset); + $mail->from($THIS_FILE . "\@" . $ENV{"SERVER_NAME"}, "女聲留言本"); + $mail->to("editors\@mail.wov.idv.tw", "女聲編輯"); + $mail->subject("[女聲] 留言本留言通知 " . fmtdate); + $mail->body($body); + # Send it + $mail->send; + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my $self; + $self = $_[0]; + # A form to create a new item + return gactlog "Post a new message on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "."; +} + +no utf8; +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/LinkCat.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/LinkCat.pm new file mode 100644 index 0000000..36f444d --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/LinkCat.pm @@ -0,0 +1,70 @@ +# Woman's Voice +# LinkCat.pm: The related-link category data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-05 + +package Selima::wov::Processor::LinkCat; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor::LinkCat); + +use Selima::DataVars qw(:addcol); + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + if ($self->{"type"} ne "del") { + # Set the "topmost" parent + $form->delete("parent") if $form->param("topmost") eq "true"; + } + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("parent", $self->_form("parent")); + $self->{"cols"}->addstr("id", $self->_form("id")); + $self->{"cols"}->addnum("ord", $self->_form("ord")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("title_en", $self->_form("title_en")); + $self->{"cols"}->addstr("kw", $self->_form("kw")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("parent", $self->_form("parent"), scalar $cur->param("parent")); + $self->{"cols"}->addstr("id", $self->_form("id"), scalar $cur->param("id")); + $self->{"cols"}->addnum("ord", $self->_form("ord"), scalar $cur->param("ord")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("title_en", $self->_form("title_en"), scalar $cur->param("title_en")); + $self->{"cols"}->addstr("kw", $self->_form("kw"), scalar $cur->param("kw")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + } + return; +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/NLArt.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/NLArt.pm new file mode 100644 index 0000000..6d0f33a --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/NLArt.pm @@ -0,0 +1,151 @@ +# Woman's Voice +# NLArt.pm: The newsletter article processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-19 + +package Selima::wov::Processor::NLArt; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw(:addcol); +use Selima::Guest; +use Selima::ShortCut; + +use Selima::wov::Items; +use Selima::wov::Rebuild; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "nlarts" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("newslet", $self->_form("newslet")); + $self->{"cols"}->addnum("ord", $self->_form("ord")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("author", $self->_form("author")); + $self->{"cols"}->addstr("body_t", $self->_form("body_t")); + $self->{"cols"}->addstr("body_h", $self->_form("body_h")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("newslet", $self->_form("newslet"), scalar $cur->param("newslet")); + $self->{"cols"}->addnum("ord", $self->_form("ord"), scalar $cur->param("ord")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("author", $self->_form("author"), scalar $cur->param("author")); + $self->{"cols"}->addstr("body_t", $self->_form("body_t"), scalar $cur->param("body_t")); + $self->{"cols"}->addstr("body_h", $self->_form("body_h"), scalar $cur->param("body_h")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a newsletter article " . $form->param("title") + . " in newsletter No. " . newslet_no($form->param("newslet")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the newsletter article " . $form->param("title") + . " in newsletter No. " . newslet_no($form->param("newslet")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the newsletter article " . $cur->param("title") + . " in newsletter No. " . newslet_no($cur->param("newslet")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This article was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This article has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This article has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This article has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +# _rebuild_partial_pages: Rebuild a limited part of pages +sub _rebuild_partial_pages : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + + # Find the affected shown parts + %_ = qw(); + # A form to create a new item + if ($self->{"type"} eq "new") { + $_{$form->param("newslet")} = 1 unless defined $form->param("hid"); + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $_{$form->param("newslet")} = 1 unless defined $form->param("hid"); + $_{$cur->param("newslet")} = 1 unless $cur->param("hid"); + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $_{$cur->param("newslet")} = 1 unless $cur->param("hid"); + } + @_ = keys %_; + # Nothing to rebuild when no shown parts are seen + return if @_ == 0; + + # Rebuild the pages + rebuild_newslets @_; + return; +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/Newslet.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/Newslet.pm new file mode 100644 index 0000000..79d7492 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/Newslet.pm @@ -0,0 +1,263 @@ +# Woman's Voice +# Newslet.pm: The newsletter data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-19 + +package Selima::wov::Processor::Newslet; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw(:addcol :dataman); +use Selima::Guest; +use Selima::ShortCut; + +use Selima::wov::Rebuild; + +use Selima::wov::Processor::NLArt; +use Selima::Processor::Deletion; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "newslets" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur, $o); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("no", $self->_form("no")); + $self->{"cols"}->adddate("date", $self->_form("date")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("cred_t", $self->_form("cred_t")); + $self->{"cols"}->addstr("cred_h", $self->_form("cred_h")); + $self->{"cols"}->addstr("kw", $self->_form("kw")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + + # Find the changed items + for ($_ = 0, $o = 1; defined $form->param("art$_" . "title"); $_++) { + my ($subform, $cols); + # Not selected + next unless defined $form->param("art$_"); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("newslet", $self->{"sn"}); + $subform->param("ord", $o++); + $subform->param("title", $form->param("art$_" . "title")); + $subform->param("author", $form->param("art$_" . "author")); + $subform->param("body_t", $form->param("art$_" . "body_t")); + $subform->param("body_h", $form->param("art$_" . "body_h")); + $subform->param("hid", $form->param("art$_" . "hid")); + $cols = new Selima::wov::Processor::NLArt($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("no", $self->_form("no"), scalar $cur->param("no")); + $self->{"cols"}->adddate("date", $self->_form("date"), scalar $cur->param("date")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("cred_t", $self->_form("cred_t"), scalar $cur->param("cred_t")); + $self->{"cols"}->addstr("cred_h", $self->_form("cred_h"), scalar $cur->param("cred_h")); + $self->{"cols"}->addstr("kw", $self->_form("kw"), scalar $cur->param("kw")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + + # Find the changed items + @_ = qw(); + for ( $_ = 0, $o = 1; + $_ < $cur->param("artcount") + || defined $form->param("art$_" . "title"); + $_++) { + # Added items to the current + if ($_ >= $cur->param("artcount")) { + my ($subform, $cols); + # Not selected + next unless defined $form->param("art$_"); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("newslet", $self->{"sn"}); + $subform->param("ord", $o++); + $subform->param("title", $form->param("art$_" . "title")); + $subform->param("author", $form->param("art$_" . "author")); + $subform->param("body_t", $form->param("art$_" . "body_t")); + $subform->param("body_h", $form->param("art$_" . "body_h")); + $subform->param("hid", $form->param("art$_" . "hid")); + $cols = new Selima::wov::Processor::NLArt($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + + # Selected + } elsif (defined $form->param("art$_")) { + my ($subform, $cols, %CURRENT_SUP); + %CURRENT_SUP = %CURRENT; + %CURRENT = ( + "sn" => $cur->param("art$_" . "sn"), + "newslet" => $self->{"sn"}, + "ord" => $cur->param("art$_" . "ord"), + "title" => $cur->param("art$_" . "title"), + "author" => $cur->param("art$_" . "author"), + "body_t" => $cur->param("art$_" . "body_t"), + "body_h" => $cur->param("art$_" . "body_h"), + "hid" => $cur->param("art$_" . "hid"), + ); + $subform = new CGI(""); + $subform->param("form", "cur"); + $subform->param("sn", $cur->param("art$_" . "sn")); + $subform->param("newslet", $self->{"sn"}); + $subform->param("ord", $o++); + $subform->param("title", $form->param("art$_" . "title")); + $subform->param("author", $form->param("art$_" . "author")); + $subform->param("body_t", $form->param("art$_" . "body_t")); + $subform->param("body_h", $form->param("art$_" . "body_h")); + $subform->param("hid", $form->param("art$_" . "hid")); + $cols = new Selima::wov::Processor::NLArt($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + %CURRENT = %CURRENT_SUP; + + # Not selected + } else { + push @_, $cur->param("art$_" . "sn"); + } + } + if (@_ > 0) { + my $subform; + $_ = join " OR ", map "sn=$_", @_; + $subform = new CGI(""); + $subform->param("cond", $_); + # Delete first, to spare the order occupied + unshift @{$self->{"subs"}}, new Selima::Processor::Deletion($subform, "nlarts"); + } + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + # Find the changed items + $_ = new CGI(""); + $_->param("cond", "newslet=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($_, "nlarts"); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a newsletter No. " . $form->param("no") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the newsletter No. " . $form->param("no") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the newsletter No. " . $cur->param("no") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This newsletter was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This newsletter has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This newsletter has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This newsletter has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +# _rebuild_partial_pages: Rebuild a limited part of pages +sub _rebuild_partial_pages : method { + local ($_, %_); + my ($self, $form, $cur); + my $build_me_only; + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # Remove the unwanted pages + $self->_remove_curfile; + + # Check if there is any shown part affected + # A form to create a new item + if ($self->{"type"} eq "new") { + return if defined $form->param("hid"); + $build_me_only = 0; + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + return if $cur->param("hid") && defined $form->param("hid"); + $build_me_only = (!$cur->param("hid") && !defined $form->param("hid")); + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + return if $cur->param("hid"); + $build_me_only = 0; + } + + if ($build_me_only) { + rebuild_newslets $self->{"sn"}; + # Rebuild everything, since the page bar changed + } else { + rebuild_newslets; + } +} + +# _remove_curfile: Remove the unwanted page +sub _remove_curfile : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # Nothing to remove if there is no current page + return if $self->{"type"} eq "new" || $cur->param("hid"); + # A current page to be deleted or hidden + return grmoldpage sprintf "/newsletters/wov%04d.html", $cur->param("no") + if $self->{"type"} eq "del" || defined $form->param("hid"); + # A shown page update with a new page path to check with + # Page path is not updated + return; +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/Page.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/Page.pm new file mode 100644 index 0000000..4e4c4eb --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Processor/Page.pm @@ -0,0 +1,68 @@ +# Woman's Voice +# Page.pm: The web page form data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-05 + +package Selima::wov::Processor::Page; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor::Page); + +use Selima::DataVars qw(:addcol); + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("path", $self->_form("path")); + $self->{"cols"}->addnum("ord", $self->_form("ord")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("title_en", $self->_form("title_en")); + $self->{"cols"}->addstr("body", $self->_form("body")); + $self->{"cols"}->addstr("kw", $self->_form("kw")); + $self->{"cols"}->addbool("html", $self->_form("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("path", $self->_form("path"), scalar $cur->param("path")); + $self->{"cols"}->addnum("ord", $self->_form("ord"), scalar $cur->param("ord")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("title_en", $self->_form("title_en"), scalar $cur->param("title_en")); + $self->{"cols"}->addstr("body", $self->_form("body"), scalar $cur->param("body")); + $self->{"cols"}->addstr("kw", $self->_form("kw"), scalar $cur->param("kw")); + $self->{"cols"}->addbool("html", $self->_form("html"), scalar $cur->param("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + } + return; +} + +return 1; diff --git a/htdocs/wov/magicat/lib/perl5/Selima/wov/Rebuild.pm b/htdocs/wov/magicat/lib/perl5/Selima/wov/Rebuild.pm new file mode 100644 index 0000000..0e4edc6 --- /dev/null +++ b/htdocs/wov/magicat/lib/perl5/Selima/wov/Rebuild.pm @@ -0,0 +1,441 @@ +# Woman's Voice +# Rebuild.pm: The subroutines to rebuild the web pages. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-02 + +package Selima::wov::Rebuild; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(rebuild_all rebuild_pages rebuild_links rebuild_newslets compose_page); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub rebuild_all(); +sub rebuild_pages(;$); +sub rebuild_links(;$); +sub rebuild_newslets(@); +sub compose_page($;$); +} + +use Data::Dumper qw(); +use Fcntl qw(:flock); +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use Selima::DataVars qw($DBH :output :rebuild); +use Selima::GetLang; +use Selima::Guest; +use Selima::PageFunc; +use Selima::ShortCut; + +use Selima::wov::HTML; +use Selima::wov::Items; + +use vars qw($PKGL10N); + +# rebuild_all: Rebuild everything +sub rebuild_all() { + local ($_, %_); + # Lock the required tables + $DBH->lock(map { $_ => LOCK_SH } @REBUILD_TABLES); + # Rebuild the pages + rebuild_pages; + # Rebuild the links + rebuild_links; + # Rebuild the newsletters + rebuild_newslets; + # Rebuild the index + # To be done + #rebuild_index; + return; +} + +# rebuild_pages: Rebuild the pages +sub rebuild_pages(;$) { + local ($_, %_); + my ($sql, $sth, $count, $rebuild_everything); + my $lang; + $sql = $_[0]; + + $lang = getlang; + + # Rebuild everything + $rebuild_everything = !defined $sql; + if ($rebuild_everything) { + $sql = "SELECT * FROM pages" + . " WHERE NOT hid;\n"; + } + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + # Bounce if no pages to build on a partial rebuild + # This prevents needless sitemap rebuilding + return if !$rebuild_everything && $count == 0; + # Build each page + for (my $i = 0; $i < $count; $i++) { + my ($page, $html); + $page = $sth->fetchrow_hashref; + # Read the picture into the picture deposit + # To be done + + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + + # Output related pictures only when rebuilding everything + # To be done + } + + return; +} + +# rebuild_links: Rebuild the links +sub rebuild_links(;$) { + local ($_, %_); + my ($sql, $sth, $count, $FD, $rebuild_everything); + my ($lang, $args, $html); + $sql = $_[0]; + + $lang = getlang; + + # Rebuild everything + $rebuild_everything = !defined $sql; + if ($rebuild_everything) { + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_isshown(sn, hid, parent);\n"; + } + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0; $i < $count; $i++) { + my ($page, $sql1, $sth1, $count1, $row1); + $page = $sth->fetchrow_hashref; + + # Find the ancesters + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql1 = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE linkcat_ischild(sn, " . $$page{"sn"} . ")" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"parents"} = []; $i < $count1; $i++) { + push @{$$page{"parents"}}, $sth1->fetchrow_hashref; + } + + # Find the subcategories + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql1 = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE parent=" . $$page{"sn"} + . " AND linkcat_isshown(sn, hid, parent)" + . " ORDER BY ord;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"scats"} = []; $i < $count1; $i++) { + my ($sql2, $sth2, $row2); + $row1 = $sth1->fetchrow_hashref; + # Find the belonging links + $sql2 = "SELECT count(linkcatz.sn) AS count FROM linkcatz" + . " INNER JOIN links ON linkcatz.link=links.sn" + . " INNER JOIN linkcat ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.cat=" . $$row1{"sn"} + . " AND NOT links.hid;\n"; + $sth2 = $DBH->prepare($sql2); + $sth2->execute; + $row2 = $sth2->fetchrow_hashref; + $$row1{"links"} = $$row2{"count"}; + push @{$$page{"scats"}}, $row1; + } + + # Find the belonging links + @_ = map "links.$_", $DBH->cols("links"); + $sql1 = "SELECT " . join(", ", @_) . " FROM links" + . " INNER JOIN linkcatz ON linkcatz.link=links.sn" + . " WHERE linkcatz.cat=" . $$page{"sn"} + . " AND NOT links.hid;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"links"} = []; $i < $count1; $i++) { + push @{$$page{"links"}}, $sth1->fetchrow_hashref; + } + + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang + if defined $html; + } + + # Build the root index page + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE parent IS NULL" + . " AND linkcat_isshown(sn, hid, parent)" + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @_ = qw(); $_ < $count; $_++) { + my ($cat, $sql1, $sth1, $count1); + $cat = $sth->fetchrow_hashref; + + # Find the belonging links + $sql1 = "SELECT count(linkcatz.sn) AS count FROM linkcatz" + . " INNER JOIN links ON linkcatz.link=links.sn" + . " INNER JOIN linkcat ON linkcatz.cat=linkcat.sn" + . " WHERE linkcatz.cat=" . $$cat{"sn"} + . " AND NOT links.hid;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $$cat{"links"} = ${$sth1->fetch}[0]; + + push @_, $cat; + } + $ALT_PAGE_PARAM = { + "path" => "/links/", + "lang" => $lang, + "keywords" => __("related links"), + "class" => "links", + "javascripts" => [qw(/scripts/links.js)], + "static" => 1, + "all_linguas" => [$lang]}; + $args = page_param; + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header "女網牽手", "Woman Interconnect", $args; + html_links_index @_, $args; + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $html = join "", <$FD>; + undef $ALT_PAGE_PARAM; + goutpage $html, "/links/", $lang; + + return; +} + +# rebuild_newslets: Rebuild the newsletters +sub rebuild_newslets(@) { + local ($_, %_); + my (@newslets, $sql, $sth, $count, $FD, $rebuild_everything); + my ($lang, $args, $html, @allno); + @newslets = @_; + + $lang = getlang; + + # Obtain all the pages + { + my ($sql, $sth, $count); + $sql = "SELECT no FROM newslets" + . " WHERE NOT hid ORDER BY no;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @allno = qw(); $i < $count; $i++) { + push @allno, ${$sth->fetch}[0]; + } + undef $sth; + } + + # Rebuild everything + $rebuild_everything = (@newslets == 0); + if ($rebuild_everything) { + $sql = "SELECT * FROM newslets" + . " WHERE NOT hid ORDER BY no;\n"; + } else { + $_ = join " OR ", map "sn=$_", @newslets; + $_ = "($_)" if @newslets > 1; + $sql = "SELECT * FROM newslets" + . " WHERE $_" + . " AND NOT hid" + . " ORDER BY no;\n"; + } + + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0; $i < $count; $i++) { + my ($page, $sql1, $sth1, $count1, $row1, $title, $pagebar); + $page = $sth->fetchrow_hashref; + $$page{"path"} = sprintf "/newsletters/wov%04d.html", $$page{"no"}; + $title = newslet_textno($$page{"no"}) . " " . $$page{"title"}; + $$page{"allno"} = [@allno]; + + # Find the belonging articles + $sql1 = "SELECT * FROM nlarts" + . " WHERE newslet=" . $$page{"sn"} + . " AND NOT hid" + . " ORDER BY ord;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$page{"arts"} = []; $i < $count1; $i++) { + push @{$$page{"arts"}}, $sth1->fetchrow_hashref; + } + + $html = compose_page($page, $lang); + goutpage $html, $$page{"path"}, $lang; + } + + # Build the index page + $sql = "SELECT sn, no, date, title FROM newslets" + . " WHERE NOT hid ORDER BY no DESC;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @_ = qw(); $_ < $count; $_++) { + my ($newslet, $sql1, $sth1, $count1); + $newslet = $sth->fetchrow_hashref; + + # Find the belonging articles + $sql1 = "SELECT title, author FROM nlarts" + . " WHERE newslet=" . $$newslet{"sn"} + . " AND NOT hid" + . " ORDER BY ord;\n"; + $sth1 = $DBH->prepare($sql1); + $sth1->execute; + $count1 = $sth1->rows; + for (my $i = 0, $$newslet{"arts"} = []; $i < $count1; $i++) { + push @{$$newslet{"arts"}}, $sth1->fetchrow_hashref; + } + + push @_, $newslet; + } + $ALT_PAGE_PARAM = { + "path" => "/newsletters/", + "lang" => $lang, + "keywords" => "女聲電子報, 女性主義, 婦運, 性別, 小招, 依瑪貓", + "javascripts" => [qw(/scripts/search.js)], + "class" => "newsletters", + "static" => 1, + "all_linguas" => [$lang]}; + $args = page_param; + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header "女聲各期目錄", "Index of WOVs", $args; + html_nl_index @_, $args; + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $html = join "", <$FD>; + undef $ALT_PAGE_PARAM; + goutpage $html, "/newsletters/", $lang; + + return; +} + +# compose_page: Compose a page +sub compose_page($;$) { + local ($_, %_); + my ($page, $lang, $args, $title_en, $FD); + ($page, $lang) = @_; + $lang = getlang if !defined $lang; + + $ALT_PAGE_PARAM = { + "path" => $$page{"path"}, + "lang" => $lang, + "keywords" => $$page{"kw"}, + "static" => 1, + "all_linguas" => [$lang], + "no_auto_title" => exists $$page{"no_auto_title"} + && $$page{"no_auto_title"}}; + $$ALT_PAGE_PARAM{"preview"} = $page + if exists $$page{"preview"}; + if (exists $$page{"class"} && defined $$page{"class"} && $$page{"class"} ne "") { + $$ALT_PAGE_PARAM{"class"} = $$page{"class"}; + } elsif ($$page{"path"} =~ /^\/newsletters\//) { + $$ALT_PAGE_PARAM{"class"} = "newsletters"; + } elsif ($$page{"path"} =~ /^\/links\//) { + $$ALT_PAGE_PARAM{"class"} = "links"; + } + if ($$page{"path"} eq "/subscribe.html") { + $$ALT_PAGE_PARAM{"javascripts"} = ["/scripts/subscribe.js"]; + } + $args = page_param; + $title_en = exists $$page{"title_en"} && defined $$page{"title_en"}? + $$page{"title_en"}: undef; + + # Special rules for newsletters + if ($$page{"path"} =~ /^\/newsletters\/wov\d{4}\.html$/) { + $$args{"no_auto_title"} = 1; + + # The relative pages + $$args{"first"} = sprintf "/newsletters/wov%04d.html", ${$$page{"allno"}}[0]; + for ($_ = 0; $_ < @{$$page{"allno"}}; $_++) { + last if ${$$page{"allno"}}[$_] == $$page{"no"}; + } + $$args{"prev"} = sprintf "/newsletters/wov%04d.html", ${$$page{"allno"}}[$_ - 1] + if $_ > 0; + $$args{"next"} = sprintf "/newsletters/wov%04d.html", ${$$page{"allno"}}[$_ + 1] + if $_ < $#{$$page{"allno"}}; + $$args{"last"} = sprintf "/newsletters/wov%04d.html", ${$$page{"allno"}}[$#{$$page{"allno"}}]; + + # Obtain the page bar + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_nl_pagebar $_, @{$$page{"allno"}}, $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + if ($_ ne "") { + $$args{"header_html_nav"} = $_; + $$args{"footer_html_nav"} = $_; + } + } + + # Obtain the page + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + html_header $$page{"title"}, $title_en, $args; + if ($$page{"path"} =~ /^\/newsletters\/wov\d{4}\.html$/) { + html_title "女聲", "Woman’s Voice"; + html_newslet $page, $args; + } elsif ($$page{"path"} =~ /^\/links\/$/) { + #html_links_index $page, $args; + } elsif ($$page{"path"} =~ /^\/links\/.+$/) { + html_links $page, $args; + } else { + html_body $page, $args; + } + html_footer $args; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $_ = join "", <$FD>; + + undef $ALT_PAGE_PARAM; + return $_; +} + +no utf8; +return 1; diff --git a/htdocs/wov/magicat/lib/wov-semina.sql b/htdocs/wov/magicat/lib/wov-semina.sql new file mode 100644 index 0000000..4bcd9a6 --- /dev/null +++ b/htdocs/wov/magicat/lib/wov-semina.sql @@ -0,0 +1,1468 @@ +-- 檔案名稱: wov.sql +-- 程式說明: 女聲資料庫定義檔 +-- 程式作者: 依瑪貓 imacat +-- 初稿日期: 2004-10-16 +-- 版權字樣: 版權所有 (c) 2004-2014 依瑪貓 +-- Set PGCLIENTENCODING=utf8 before restoring it + +SET NAMES 'utf8'; + +START TRANSACTION; + + +-- +-- Table structure for table "mtime" +-- + +CREATE TABLE mtime ( + tabname varchar(16) NOT NULL PRIMARY KEY, + mtime timestamp NOT NULL DEFAULT now() +); +GRANT SELECT, INSERT, UPDATE, DELETE ON mtime TO nobody; + + +-- +-- Function definition for function "eschtml" +-- +-- integer eschtml(source text) +CREATE FUNCTION eschtml(source text) RETURNS text AS ' + DECLARE + result text; + BEGIN + result := source; + result := replace(result, ''&'', ''&''); + result := replace(result, ''<'', ''<''); + result := replace(result, ''>'', ''>''); + result := replace(result, ''"'', ''"''); + return result; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION eschtml(source text) TO nobody; + + +-- +-- Table structure for table "country" +-- + +CREATE TABLE country ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id char(2) NOT NULL UNIQUE CHECK (position(' ' in id) = 0), + name_en varchar(64) NOT NULL CHECK (name_en != ''), + name_zhtw varchar(32) CHECK (name_zhtw IS NULL OR name_zhtw != ''), + special boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL +); +GRANT SELECT, INSERT, UPDATE, DELETE ON country TO nobody; + + +-- +-- Table structure for table "users" +-- + +CREATE TABLE users ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(32) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + passwd char(32) NOT NULL, + name varchar(32) NOT NULL CHECK (name != ''), + disabled boolean NOT NULL DEFAULT FALSE, + deleted boolean NOT NULL DEFAULT FALSE, + lang varchar(5) CHECK (lang IS NULL OR lang != ''), + visits smallint NOT NULL DEFAULT 0 CHECK (visits >= 0), + visited timestamp, + ip inet, + host varchar(128), + ct char(2) REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON users TO nobody; + +CREATE VIEW users_list AS + SELECT + users.sn AS sn, + users.id AS id, + users.name AS name, + CASE WHEN users.disabled THEN '停用' + ELSE '' + END AS disabled, + CASE WHEN users.deleted THEN '已刪' + ELSE '' + END AS deleted, + CASE WHEN users.lang IS NULL THEN '(無)' + ELSE CASE users.lang + WHEN 'en' THEN '英文' + WHEN 'zh-tw' THEN '繁體中文' + WHEN 'zh-cn' THEN '簡體中文' + WHEN 'ja' THEN '日文' + WHEN 'de' THEN '德文' + WHEN 'es' THEN '西班牙文' + ELSE users.lang + END + END AS lang, + users.visits AS visits, + CASE WHEN users.visited IS NULL THEN '(無)' + ELSE to_char(users.visited, 'YYYY-MM-DD HH:MI:SS') + END AS visited, + CASE WHEN users.ip IS NULL THEN '(無)' + ELSE host(users.ip) + END AS ip, + CASE WHEN users.host IS NULL THEN '(無)' + ELSE users.host + END AS host, + CASE WHEN users.ct IS NULL THEN '(無)' + ELSE ct.name_zhtw + END AS ct, + to_char(users.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(users.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM users + LEFT JOIN country AS ct ON users.ct = ct.id + LEFT JOIN users AS createdby ON users.createdby = createdby.sn + LEFT JOIN users AS updatedby ON users.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON users_list TO nobody; + +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (923153018, 'imacat', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '依瑪貓', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (460376330, 'mandy', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '小招', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (723676436, 'guestbook', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '留言本', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); + +-- +-- Fixing the country table +-- + +ALTER TABLE country ADD FOREIGN KEY (createdby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +ALTER TABLE country ADD FOREIGN KEY (updatedby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +CREATE VIEW country_list AS + SELECT + country.sn AS sn, + country.id AS id, + COALESCE(country.name_zhtw, country.name_en) AS title, + CASE WHEN country.special THEN '特殊' + ELSE '' + END AS special, + to_char(country.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(country.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM country + LEFT JOIN users AS createdby ON country.createdby = createdby.sn + LEFT JOIN users AS updatedby ON country.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON country_list TO nobody; + + +-- +-- Table structure for table "groups" +-- + +CREATE TABLE groups ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(16) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + dsc varchar(64) NOT NULL CHECK (dsc != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groups TO nobody; + +CREATE VIEW groups_list AS + SELECT + groups.sn AS sn, + groups.id AS id, + groups.dsc AS dsc, + to_char(groups.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groups.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groups + LEFT JOIN users AS createdby ON groups.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groups.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON groups_list TO nobody; + +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (553229108, 'root', '總管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (802339805, 'guests', '暱名訪客', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (958210993, 'users', '已登入使用者', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (329685674, 'admin', '所有網站管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (157696540, 'acctman', '帳號管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (390105230, 'editor', '網站編輯', now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "usermem" +-- + +CREATE TABLE usermem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON usermem TO nobody; + +CREATE VIEW usermem_list AS + SELECT + usermem.sn AS sn, + groups.id || ' (' || groups.dsc || ')' AS grp, + members.id || ' (' || members.name || ')' AS member, + to_char(usermem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(usermem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM usermem + LEFT JOIN groups ON usermem.grp = groups.sn + LEFT JOIN users AS members ON usermem.member = members.sn + LEFT JOIN users AS createdby ON usermem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON usermem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON usermem_list TO nobody; + +-- INSERT INTO usermem (sn, grp, member, created, createdby, updated, updatedby) VALUES (593684712, 553229108, 923153018, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "groupmem" +-- + +CREATE TABLE groupmem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE CHECK (member != grp), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groupmem TO nobody; + +CREATE VIEW groupmem_list AS + SELECT + groupmem.sn AS sn, + groups.id || ' (' || groups.dsc || ')' AS grp, + members.id || ' (' || members.dsc || ')' AS member, + to_char(groupmem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groupmem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groupmem + LEFT JOIN groups ON groupmem.grp = groups.sn + LEFT JOIN groups AS members ON groupmem.member = members.sn + LEFT JOIN users AS createdby ON groupmem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groupmem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON groupmem_list TO nobody; + +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (569742102, 329685674, 157696540, now(), 923153018, now(), 923153018); +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (859385977, 329685674, 390105230, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "scptpriv" +-- + +CREATE TABLE scptpriv ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + script varchar(64) NOT NULL CHECK (script != ''), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (script, grp) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON scptpriv TO nobody; + +CREATE VIEW scptpriv_list AS + SELECT + scptpriv.sn AS sn, + scptpriv.script AS script, + groups.dsc AS grp, + to_char(scptpriv.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(scptpriv.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM scptpriv + LEFT JOIN groups ON scptpriv.grp = groups.sn + LEFT JOIN users AS createdby ON scptpriv.createdby = createdby.sn + LEFT JOIN users AS updatedby ON scptpriv.updatedby = updatedby.sn + ORDER BY script, grp; +GRANT SELECT ON scptpriv_list TO nobody; + + +-- +-- Table structure for table "userpref" +-- + +CREATE TABLE userpref ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + usr int REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + domain varchar(64) CHECK (domain IS NULL OR domain != ''), + name varchar(16) NOT NULL CHECK (name != ''), + value varchar(255) NOT NULL, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (usr, domain, name) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON userpref TO nobody; + +CREATE VIEW userpref_list AS + SELECT + userpref.sn AS sn, + CASE WHEN userpref.usr IS NOT NULL THEN users.name + ELSE '所有人' + END AS usr, + CASE WHEN userpref.domain IS NOT NULL THEN userpref.domain + ELSE '所有地方' + END AS domain, + userpref.name AS name, + userpref.value AS value, + to_char(userpref.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(userpref.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM userpref LEFT JOIN users ON userpref.usr = users.sn + LEFT JOIN users AS createdby ON userpref.createdby = createdby.sn + LEFT JOIN users AS updatedby ON userpref.updatedby = updatedby.sn + ORDER BY domain, usr, name; +GRANT SELECT ON userpref_list TO nobody; + + +-- +-- Function definitions for table "guestbook" +-- + +-- integer guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) +CREATE FUNCTION guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) RETURNS integer AS ' + DECLARE + row record; + len integer; + BEGIN + -- : 19, sn: 30 + 1, date: 54 + 1 + len := 105; + len := len + octet_length(host(ip)) + 22; + IF hostname IS NOT NULL THEN + len := len + octet_length(hostname) + 24; + END IF; + IF name IS NOT NULL THEN + len := len + octet_length(eschtml(name)) + 24; + END IF; + IF identity IS NOT NULL THEN + len := len + octet_length(eschtml(identity)) + 28; + END IF; + IF location IS NOT NULL THEN + len := len + octet_length(eschtml(location)) + 28; + END IF; + IF email IS NOT NULL THEN + len := len + octet_length(eschtml(email)) + 25; + END IF; + IF url IS NOT NULL THEN + len := len + octet_length(eschtml(url)) + 23; + END IF; + IF message IS NOT NULL THEN + len := len + octet_length(eschtml(message)) + 27; + END IF; + IF updated != date THEN + len := len + 58; + IF updatedby_arg = 923153018 THEN + len := len + 35; + ELSIF updatedby_arg = 460376330 THEN + len := len + 34; + ELSE + SELECT INTO row name FROM users WHERE sn=updatedby_arg; + len := len + octet_length(row.name) + 29; + END IF; + END IF; + RETURN len; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(date timestamp, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp, updatedby_arg integer) TO nobody; +-- integer guestbook_oldlen(sn_arg integer) +CREATE FUNCTION guestbook_oldlen(sn_arg integer) RETURNS integer AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM guestbook WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN guestbook_oldlen(row.created, row.ip, row.host, row.name, row.identity, row.location, row.email, row.url, row.message, row.updated, row.updatedby); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(sn_arg integer) TO nobody; + + +-- +-- Table structure for table "guestbook" +-- + +CREATE TABLE guestbook ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + name varchar(32) CHECK (name IS NULL OR name != ''), + identity varchar(64) CHECK (identity IS NULL OR identity != ''), + location varchar(64) CHECK (location IS NULL OR location != ''), + email varchar(64) CHECK (email IS NULL OR email != ''), + url varchar(128) CHECK (url IS NULL OR (url != '' AND url != 'http://')), + message text NOT NULL CHECK (message != ''), + hid boolean NOT NULL DEFAULT FALSE, + ip inet NOT NULL, + host varchar(255) CHECK (host IS NULL OR host != ''), + ct char(2) NOT NULL REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + pageno int NOT NULL, + oldpageno int, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON guestbook TO nobody; + +CREATE VIEW guestbook_list AS + SELECT + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS _viewurl, + guestbook.sn AS sn, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + COALESCE(guestbook.name, '(未設定)') AS name, + COALESCE(guestbook.identity, '(未設定)') AS identity, + COALESCE(guestbook.location, '(未設定)') AS location, + COALESCE(guestbook.email, '(未設定)') AS email, + COALESCE(guestbook.url, '(未設定)') AS url, + guestbook.message AS message, + CASE WHEN guestbook.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + host(guestbook.ip) AS ip, + COALESCE(guestbook.host, '(不可考)') AS host, + COALESCE(country.name_zhtw, country.name_en) AS ct, + guestbook.pageno AS pageno, + guestbook.oldpageno AS oldpageno, + to_char(guestbook.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(guestbook.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM guestbook + LEFT JOIN country ON guestbook.ct = country.id + LEFT JOIN users AS createdby ON guestbook.createdby = createdby.sn + LEFT JOIN users AS updatedby ON guestbook.updatedby = updatedby.sn + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_list TO nobody; + +CREATE VIEW guestbook_public AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + name AS name, + identity AS identity, + location AS location, + email AS email, + url AS url, + message AS message, + pageno AS pageno, + oldpageno AS oldpageno + FROM guestbook + WHERE NOT hid + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_public TO nobody; + + +-- +-- Table structure for table "pages" +-- + +CREATE TABLE pages ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + path varchar(64) NOT NULL UNIQUE CHECK (path != ''), + ord smallint NOT NULL DEFAULT 5000 CHECK (ord >= 0 AND ord < 10000), + title varchar(128) NOT NULL CHECK (title != ''), + title_en varchar(128) NOT NULL CHECK (title_en != ''), + body text NOT NULL CHECK (body != ''), + kw varchar(128) NOT NULL CHECK (kw != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pages TO nobody; + +CREATE VIEW pages_list AS + SELECT + pages.path AS _viewurl, + pages.sn AS sn, + pages.path AS path, + pages.ord AS ord, + pages.title AS title, + pages.title_en AS title_en, + pages.body AS body, + pages.kw AS kw, + CASE WHEN pages.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN pages.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(pages.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pages.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pages + LEFT JOIN users AS createdby ON pages.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pages.updatedby = updatedby.sn + ORDER BY path; +GRANT SELECT ON pages_list TO nobody; + + +-- +-- Function definitions for table "links" +-- + +-- boolean linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer); +CREATE FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) RETURNS boolean AS ' + BEGIN + IF parent_arg IS NULL THEN + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent IS NULL; + RETURN NOT FOUND; + ELSE + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent=parent_arg; + RETURN NOT FOUND; + END IF; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) TO nobody; + +-- numeric linkcat_fullord(parent_arg integer, ord_arg integer); +CREATE FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) RETURNS numeric AS ' + DECLARE + row record; + sn_loop integer; + ord_loop numeric; + BEGIN + sn_loop := parent_arg; + ord_loop := ord_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, ord FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN NULL; + END IF; + sn_loop := row.parent; + ord_loop := row.ord + ord_loop / 100; + END LOOP; + RETURN ord_loop; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) TO nobody; +-- numeric linkcat_fullord(sn_arg integer); +CREATE FUNCTION linkcat_fullord(sn_arg integer) RETURNS numeric AS ' + BEGIN + RETURN linkcat_fullord(sn_arg, 0); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(sn_arg integer) TO nobody; + +-- boolean linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + -- Check if we have childs + PERFORM links.sn FROM links + INNER JOIN linkcatz ON linkcatz.link=links.sn + WHERE NOT links.hid AND linkcatz.cat=sn_arg; + IF FOUND THEN + RETURN TRUE; + END IF; + -- Check if we have shown child categories + PERFORM sn FROM linkcat WHERE parent=sn_arg AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + RETURN TRUE; + END IF; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; +-- boolean linkcat_isshown(sn_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer) RETURNS boolean AS ' + DECLARE + row record; + BEGIN + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_isshown(sn_arg, row.hid, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer) TO nobody; +-- boolean linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + RETURN TRUE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; + +-- text linkcat_path(sn_arg integer, id_arg text, parent_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + path text; + BEGIN + PERFORM sn FROM linkcat + WHERE parent=sn_arg + AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + path := ''/'' || id_arg || ''/''; + ELSE + path := ''/'' || id_arg || ''.html''; + END IF; + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_loop; + path := ''/'' || row.id || path; + sn_loop := row.parent; + END LOOP; + RETURN path; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) TO nobody; +-- text linkcat_path(sn_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_path(sn_arg, row.id, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer) TO nobody; + +-- boolean linkcat_ischild(parent_arg integer, child_arg integer); +CREATE FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + sn_loop := child_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN FALSE; + END IF; + IF row.parent = parent_arg THEN + RETURN TRUE; + END IF; + sn_loop := row.parent; + END LOOP; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) TO nobody; + +-- text linkcat_fulltitle(sn_arg integer); +CREATE FUNCTION linkcat_fulltitle(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + title_full text; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + title_full := row.title; + WHILE row.parent IS NOT NULL LOOP + sn_loop := row.parent; + SELECT INTO row * FROM linkcat WHERE sn=sn_loop; + title_full := row.title || '' / '' || title_full; + END LOOP; + RETURN title_full; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(sn_arg integer) TO nobody; +-- text linkcat_fulltitle(parent_arg integer, title_arg text); +CREATE FUNCTION linkcat_fulltitle(parent_arg integer, title_arg text) RETURNS text AS ' + BEGIN + IF parent_arg IS NULL THEN + RETURN title_arg; + END IF; + RETURN linkcat_fulltitle(parent_arg) || '' / '' || title_arg; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(parent_arg integer, title_arg text) TO nobody; + + +-- +-- Table structure for table "linkcat" +-- + +CREATE TABLE linkcat ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + parent int REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE CHECK (parent IS NULL OR (parent != sn AND NOT linkcat_ischild(sn, parent))), + id varchar(8) NOT NULL CHECK (char_length(id) >= 2 AND linkcat_id_unique(id, sn, parent)), + ord smallint NOT NULL DEFAULT 50 CHECK (ord >= 0 AND ord < 100), + title varchar(128) NOT NULL CHECK (title != ''), + title_en varchar(128) CHECK (title_en IS NULL OR title_en != ''), + kw varchar(128) NOT NULL CHECK (kw != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcat TO nobody; + +CREATE VIEW linkcat_list AS + SELECT + '/links' || linkcat_path(linkcat.sn, linkcat.id, linkcat.parent) AS _viewurl, + linkcat.sn AS sn, + linkcat.id AS id, + linkcat.ord AS ord, + linkcat_fulltitle(linkcat.parent, linkcat.title) AS title, + linkcat.title_en AS title_en, + linkcat.kw AS kw, + CASE WHEN linkcat.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(linkcat.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcat.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcat + LEFT JOIN users AS createdby ON linkcat.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcat.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), id; +GRANT SELECT ON linkcat_list TO nobody; + + +-- +-- Table structure for table "links" +-- + +CREATE TABLE links ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + title varchar(96) NOT NULL CHECK (title != ''), + title_2ln varchar(96) CHECK (title_2ln IS NULL OR title_2ln != ''), + url varchar(128) NOT NULL UNIQUE CHECK (url != '' AND url != 'http://'), + email varchar(64) CHECK (email IS NULL OR email != ''), + icon varchar(128) CHECK (icon IS NULL OR (icon != '' AND icon != 'http://')), + addr varchar(128) CHECK (addr IS NULL OR addr != ''), + tel varchar(48) CHECK (tel IS NULL OR tel != ''), + fax varchar(32) CHECK (fax IS NULL OR fax != ''), + dsc varchar(256) NOT NULL CHECK (dsc != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON links TO nobody; + +CREATE VIEW links_list AS + SELECT + links.url AS _viewurl, + links.sn AS sn, + links.title AS title, + links.title_2ln AS title_2ln, + links.url AS url, + links.url AS _urlcheck, + links.icon AS _imgsrc, + links.email AS email, + links.addr AS addr, + links.tel AS tel, + links.fax AS fax, + links.dsc AS dsc, + CASE WHEN links.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(links.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(links.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM links + LEFT JOIN users AS createdby ON links.createdby = createdby.sn + LEFT JOIN users AS updatedby ON links.updatedby = updatedby.sn + ORDER BY links.title; +GRANT SELECT ON links_list TO nobody; + + +-- +-- Table structure for table "linkcatz" +-- + +CREATE TABLE linkcatz ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + cat int NOT NULL REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE, + link int NOT NULL REFERENCES links ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (cat, link) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcatz TO nobody; + +CREATE VIEW linkcatz_list AS + SELECT + linkcatz.sn AS sn, + linkcat_fulltitle(linkcat.parent, linkcat.title) AS cat, + links.title AS link, + to_char(linkcatz.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcatz.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcatz + LEFT JOIN linkcat ON linkcatz.cat = linkcat.sn + LEFT JOIN links ON linkcatz.link = links.sn + LEFT JOIN users AS createdby ON linkcatz.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcatz.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), linkcat.id, link; +GRANT SELECT ON linkcatz_list TO nobody; + + + +-- +-- Function definitions for table "newslets" +-- + +-- integer newslet_textno(no integer); +CREATE FUNCTION newslet_textno(no integer) RETURNS text AS ' + BEGIN + IF no = 1 THEN + RETURN ''創刊號''; + ELSE + RETURN ''第'' || lpad(cast(no AS text), 3, ''0'') || ''期''; + END IF; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION newslet_textno(no integer) TO nobody; + + +-- +-- Table structure for table "newslets" +-- + +CREATE TABLE newslets ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + no smallint NOT NULL UNIQUE CHECK (no > 0), + date date NOT NULL DEFAULT CURRENT_DATE, + title varchar(32) NOT NULL CHECK (title != ''), + cred_t text NOT NULL CHECK (cred_t != ''), + cred_h text NOT NULL CHECK (cred_h != ''), + kw varchar(64) NOT NULL CHECK (kw != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON newslets TO nobody; + +CREATE VIEW newslets_list AS + SELECT + '/newsletters/wov' || lpad(cast(newslets.no AS text), 4, '0') || '.html' + AS _viewurl, + newslets.sn AS sn, + CASE newslets.no WHEN 1 THEN '創刊號' + ELSE '第' || lpad(cast(newslets.no AS text), 3, '0') || '期' + END AS no, + to_char(newslets.date, 'YYYY-MM-DD') AS date, + newslets.title AS title, + newslets.cred_h AS cred_h, + newslets.cred_t AS cred_t, + newslets.kw AS kw, + CASE WHEN newslets.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(newslets.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(newslets.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM newslets + LEFT JOIN users AS createdby ON newslets.createdby = createdby.sn + LEFT JOIN users AS updatedby ON newslets.updatedby = updatedby.sn + ORDER BY newslets.no DESC; +GRANT SELECT ON newslets_list TO nobody; + + +-- +-- Table structure for table "nlarts" +-- + +CREATE TABLE nlarts ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + newslet int NOT NULL REFERENCES newslets ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + title varchar(32) NOT NULL CHECK (title != ''), + author varchar(16) NOT NULL CHECK (author != ''), + body_t text NOT NULL CHECK (body_t != ''), + body_h text NOT NULL CHECK (body_h != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (newslet, ord) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON nlarts TO nobody; + +CREATE VIEW nlarts_list AS + SELECT + '/newsletters/wov' || lpad(cast(newslets.no AS text), 4, '0') || '.html' + AS _viewurl, + nlarts.sn AS sn, + CASE newslets.no WHEN 1 THEN '創刊號' + ELSE '第' || lpad(cast(newslets.no AS text), 3, '0') || '期 ' + END || ' ' || to_char(newslets.date, 'YYYY.MM.DD') + AS newslet, + nlarts.ord AS ord, + nlarts.title AS title, + nlarts.author AS author, + nlarts.body_t AS body_t, + nlarts.body_h AS body_h, + CASE WHEN nlarts.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(nlarts.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(nlarts.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM nlarts + LEFT JOIN newslets ON nlarts.newslet = newslets.sn + LEFT JOIN users AS createdby ON nlarts.createdby = createdby.sn + LEFT JOIN users AS updatedby ON nlarts.updatedby = updatedby.sn + ORDER BY newslets.no DESC, nlarts.ord; +GRANT SELECT ON nlarts_list TO nobody; + + +-- +-- VIEW: Search +-- +CREATE VIEW search_list AS + (SELECT + 'pages' AS section, + pages.path AS path, + pages.title || ' ' || pages.title_en AS title, + null AS author, + to_char(pages.updated, 'YYYY-MM-DD') AS date, + null AS newsletter, + null AS nlpath, + pages.body AS body, + pages.kw AS kw, + pages.html AS html, + 1 AS piority + FROM pages + WHERE NOT pages.hid + AND pages.path NOT LIKE '/errors/%') + UNION + (SELECT + 'newsletters' AS section, + '/newsletters/wov' || lpad(cast(newslets.no AS text), 4, '0') + || '.html#art' || lpad(cast(nlarts.ord AS text), 2, '0') + AS path, + nlarts.title AS title, + nlarts.author AS author, + to_char(newslets.date, 'YYYY-MM-DD') AS date, + CASE newslets.no WHEN 1 THEN '創刊號' + ELSE '第' || lpad(cast(newslets.no AS text), 3, '0') || '期' + END || ' ' || newslets.title || ' ' || to_char(newslets.date, 'YYYY.MM.DD') + AS newsletter, + '/newsletters/wov' || lpad(cast(newslets.no AS text), 4, '0') + || '.html' AS nlpath, + nlarts.body_h AS body, + null AS kw, + TRUE AS html, + 0 AS piority + FROM nlarts + LEFT JOIN newslets ON nlarts.newslet = newslets.sn + WHERE NOT newslets.hid + AND NOT nlarts.hid) + UNION + (SELECT + 'links' AS section, + links.url AS path, + links.title AS title, + null AS author, + to_char(links.updated, 'YYYY-MM-DD') AS date, + null AS newsletter, + null AS nlpath, + links.dsc AS body, + CASE WHEN links.title_2ln IS NULL THEN '' ELSE links.title_2ln END + || ' +' || CASE WHEN links.url IS NULL THEN '' ELSE links.url END + || ' +' || CASE WHEN links.email IS NULL THEN '' ELSE links.email END + || ' +' || CASE WHEN links.addr IS NULL THEN '' ELSE links.addr END + || ' +' || CASE WHEN links.tel IS NULL THEN '' ELSE links.tel END + || ' +' || CASE WHEN links.fax IS NULL THEN '' ELSE links.fax END + AS kw, + FALSE AS html, + 1 AS piority + FROM links + WHERE NOT links.hid) + UNION + (SELECT + 'guestbook' AS section, + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS path, + null AS title, + guestbook.name AS author, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + null AS newsletter, + null AS nlpath, + guestbook.message AS body, + CASE WHEN guestbook.identity IS NULL THEN '' ELSE guestbook.identity END + || ' +' || CASE WHEN guestbook.location IS NULL THEN '' ELSE guestbook.location END + || ' +' || CASE WHEN guestbook.email IS NULL THEN '' ELSE guestbook.email END + || ' +' || CASE WHEN guestbook.url IS NULL THEN '' ELSE guestbook.url END + AS kw, + FALSE AS html, + 1 AS piority + FROM guestbook + WHERE NOT guestbook.hid) + ORDER BY piority, date DESC, title; +GRANT SELECT ON search_list TO nobody; + + +-- +-- Function definitions for table "accttrx" +-- + +-- boolean acctsubj_ischild(parent_arg integer, sn_arg integer, code_arg text); +CREATE FUNCTION acctsubj_ischild(parent_arg integer, sn_arg integer, code_arg text) RETURNS boolean AS ' + DECLARE + row record; + BEGIN + -- First level subjects have no parent + IF char_length(code_arg) = 1 THEN + IF parent_arg IS NULL THEN + RETURN TRUE; + ELSE + RETURN FALSE; + END IF; + END IF; + -- Second level subjects and below must have a parent + IF parent_arg IS NULL THEN + RETURN FALSE; + END IF; + -- A subject must not belong to itself + IF parent_arg IS NOT DISTINCT FROM sn_arg THEN + RETURN FALSE; + END IF; + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + SELECT INTO row code FROM public.acctsubj WHERE sn=parent_arg; + -- parent is guarenteed by FOREIGN KEY constraint, so we do not check it. + -- This helps when importing data from the dump files since we cannot help + -- the data order in the dump files. + IF NOT FOUND THEN + RETURN TRUE; + END IF; + -- The code of the parent must match the preceding part of our code + IF row.code = substring(code_arg FROM 1 FOR char_length(code_arg) - 1) THEN + RETURN TRUE; + END IF; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_ischild(parent_arg integer, sn_arg integer, code_arg text) TO nobody; + +-- text acctsubj_fulltitle(sn_arg integer); +CREATE FUNCTION acctsubj_fulltitle(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + title_full text; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM acctsubj WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + title_full := row.title; + WHILE row.parent IS NOT NULL LOOP + sn_loop := row.parent; + SELECT INTO row * FROM acctsubj WHERE sn=sn_loop; + title_full := row.title || '' / '' || title_full; + END LOOP; + RETURN title_full; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_fulltitle(sn_arg integer) TO nobody; +-- text acctsubj_fulltitle(parent_arg integer, title_arg text); +CREATE FUNCTION acctsubj_fulltitle(parent_arg integer, title_arg text) RETURNS text AS ' + BEGIN + IF parent_arg IS NULL THEN + RETURN title_arg; + END IF; + RETURN acctsubj_fulltitle(parent_arg) || '' / '' || title_arg; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_fulltitle(parent_arg integer, title_arg text) TO nobody; +-- text acctsubj_codetitle(sn_arg integer); +CREATE FUNCTION acctsubj_codetitle(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM acctsubj WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.code || '' '' || row.title; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_codetitle(sn_arg integer) TO nobody; + +-- timestamp acctsubj_recent(subj_arg integer); +CREATE FUNCTION acctsubj_recent(subj_arg integer) RETURNS timestamp AS ' + DECLARE + row record; + BEGIN + IF subj_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row updated FROM acctrecs WHERE subj=subj_arg + ORDER BY updated DESC LIMIT 1; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN row.updated; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_recent(subj_arg integer) TO nobody; + +-- boolean acctsubj_islastlv(sn_arg integer); +CREATE FUNCTION acctsubj_islastlv(sn_arg integer) RETURNS boolean AS ' + BEGIN + PERFORM sn FROM acctsubj WHERE parent=sn_arg LIMIT 1; + RETURN NOT FOUND; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsubj_islastlv(sn_arg integer) TO nobody; + +-- boolean accttrx_has_subj(sn_arg integer, code_arg text); +CREATE FUNCTION accttrx_has_subj(sn_arg integer, code_arg text) RETURNS boolean AS ' + BEGIN + PERFORM acctrecs.sn FROM acctrecs + LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn + WHERE acctrecs.trx=sn_arg + AND acctsubj.code LIKE code_arg || ''%'' + LIMIT 1; + RETURN FOUND; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION accttrx_has_subj(sn_arg integer, code_arg text) TO nobody; + +-- integer acctsum_debit(year_arg integer, month_arg integer, code_here text); +CREATE FUNCTION acctsum_debit(year_arg integer, month_arg integer, code_here text) RETURNS integer AS ' + DECLARE + row record; + BEGIN + SELECT INTO row sum(acctrecs.amount) AS sum + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + WHERE NOT acctrecs.credit + AND acctsubj.code LIKE code_here || ''%'' + AND extract(year FROM accttrx.date) = year_arg + AND extract(month FROM accttrx.date) = month_arg; + IF row.sum IS NULL THEN + RETURN 0; + END IF; + RETURN row.sum; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsum_debit(year_arg integer, month_arg integer, code_here text) TO nobody; +-- integer acctsum_credit(year_arg integer, month_arg integer, code_here text); +CREATE FUNCTION acctsum_credit(year_arg integer, month_arg integer, code_here text) RETURNS integer AS ' + DECLARE + row record; + BEGIN + SELECT INTO row sum(acctrecs.amount) AS sum + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + WHERE acctrecs.credit + AND acctsubj.code LIKE code_here || ''%'' + AND extract(year FROM accttrx.date) = year_arg + AND extract(month FROM accttrx.date) = month_arg; + IF row.sum IS NULL THEN + RETURN 0; + END IF; + RETURN row.sum; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsum_credit(year_arg integer, month_arg integer, code_here text) TO nobody; +-- integer acctsum_balance(year_arg integer, month_arg integer, code_here text); +CREATE FUNCTION acctsum_balance(year_arg integer, month_arg integer, code_here text) RETURNS integer AS ' + DECLARE + row record; + BEGIN + SELECT INTO row sum(CASE WHEN acctrecs.credit THEN -acctrecs.amount ELSE acctrecs.amount END) AS sum + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + WHERE acctsubj.code LIKE code_here || ''%'' + AND extract(year FROM accttrx.date) * 100 + extract(month FROM accttrx.date) <= year_arg * 100 + month_arg; + IF row.sum IS NULL THEN + RETURN 0; + END IF; + RETURN row.sum; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION acctsum_balance(year_arg integer, month_arg integer, code_here text) TO nobody; + + +-- +-- Table structure for table "acctsubj" +-- + +CREATE TABLE acctsubj ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + parent int REFERENCES acctsubj ON UPDATE CASCADE DEFERRABLE CHECK (acctsubj_ischild(parent, sn, code)), + code varchar(5) NOT NULL UNIQUE CHECK (code != ''), + title varchar(32) NOT NULL CHECK (title != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON acctsubj TO nobody; + +CREATE VIEW acctsubj_list AS + SELECT + acctsubj.sn AS sn, + acctsubj.code AS code, + acctsubj_fulltitle(acctsubj.parent, acctsubj.title) AS title, + to_char(acctsubj.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctsubj.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctsubj + LEFT JOIN users AS createdby ON acctsubj.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctsubj.updatedby = updatedby.sn + ORDER BY acctsubj.code; +GRANT SELECT ON acctsubj_list TO nobody; + +CREATE VIEW acctsubj_lastlv_list AS + SELECT + acctsubj.sn AS sn, + acctsubj.code AS code, + acctsubj_fulltitle(acctsubj.parent, acctsubj.title) AS title, + to_char(acctsubj.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctsubj.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctsubj + LEFT JOIN users AS createdby ON acctsubj.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctsubj.updatedby = updatedby.sn + WHERE acctsubj_islastlv(acctsubj.sn) + ORDER BY acctsubj.code; +GRANT SELECT ON acctsubj_lastlv_list TO nobody; + + +-- +-- Table structure for table "accttrx" +-- + +CREATE TABLE accttrx ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + date date NOT NULL DEFAULT CURRENT_DATE, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + note varchar(128) CHECK (note IS NULL OR note != ''), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON accttrx TO nobody; + +CREATE VIEW accttrx_list AS + SELECT + accttrx.sn AS sn, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS num, + accttrx.note AS note, + to_char(accttrx.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(accttrx.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM accttrx + LEFT JOIN users AS createdby ON accttrx.createdby = createdby.sn + LEFT JOIN users AS updatedby ON accttrx.updatedby = updatedby.sn + ORDER BY accttrx.date DESC, accttrx.ord DESC; +GRANT SELECT ON accttrx_list TO nobody; + + +-- +-- Table structure for table "acctrecs" +-- + +CREATE TABLE acctrecs ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + trx int NOT NULL REFERENCES accttrx ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + credit boolean NOT NULL, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + subj int NOT NULL REFERENCES acctsubj ON UPDATE CASCADE DEFERRABLE, + summary varchar(128) CHECK (summary IS NULL OR summary != ''), + amount int NOT NULL CHECK (amount > 0), + created timestamp NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (trx, credit, ord) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON acctrecs TO nobody; + +CREATE VIEW acctrecs_list AS + SELECT + acctrecs.sn AS sn, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS trx, + CASE WHEN credit THEN '貸' ELSE '借' END AS credit, + acctrecs.ord AS ord, + acctsubj.code || ' ' || acctsubj.title AS subj, + acctrecs.summary AS summary, + acctrecs.amount AS amount, + to_char(acctrecs.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(acctrecs.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + LEFT JOIN users AS createdby ON acctrecs.createdby = createdby.sn + LEFT JOIN users AS updatedby ON acctrecs.updatedby = updatedby.sn + ORDER BY accttrx.date DESC, accttrx.ord DESC, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrecs_list TO nobody; + + +-- +-- Accounting reports +-- +CREATE VIEW acctrep_cash_list AS + SELECT + TRUE AS _sel, + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + acctsubj.code AS _subj, + accttrx.date AS _date, + acctrecs.trx AS _trx, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + acctsubj.code || ' ' || acctsubj.title AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS income, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS expense, + 0 AS balance + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 1 ELSE 2 END, acctrecs.ord; +GRANT SELECT ON acctrep_cash_list TO nobody; + +CREATE VIEW acctrep_ledger_list AS + SELECT + TRUE AS _sel, + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + acctsubj.code AS _subj, + accttrx.date AS _date, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + acctsubj.code || ' ' || acctsubj.title AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS debit, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS credit, + 0 AS balance + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrep_ledger_list TO nobody; + +CREATE VIEW acctrep_search_list AS + SELECT + 'accttrx.cgi?form=cur&sn=' || accttrx.sn AS _selurl, + to_char(accttrx.date, 'YYYY-MM-DD') AS date, + to_char(accttrx.date, 'YYYYMMDD') || lpad(cast(accttrx.ord AS text), 2, '0') AS trxno, + acctsubj.code || ' ' || acctsubj.title AS subj, + acctrecs.summary AS summary, + CASE WHEN credit THEN 0 ELSE acctrecs.amount END AS debit, + CASE WHEN credit THEN acctrecs.amount ELSE 0 END AS credit, + accttrx.note AS note + FROM acctrecs + LEFT JOIN accttrx ON acctrecs.trx = accttrx.sn + LEFT JOIN acctsubj ON acctrecs.subj = acctsubj.sn + ORDER BY accttrx.date, accttrx.ord, CASE WHEN credit THEN 2 ELSE 1 END, acctrecs.ord; +GRANT SELECT ON acctrep_search_list TO nobody; + + +COMMIT; diff --git a/htdocs/wov/magicat/lib/wov.sql b/htdocs/wov/magicat/lib/wov.sql new file mode 100644 index 0000000..490e454 --- /dev/null +++ b/htdocs/wov/magicat/lib/wov.sql @@ -0,0 +1,1171 @@ +-- 檔案名稱: wov.sql +-- 程式說明: 女聲資料庫定義檔 +-- 程式作者: 依瑪貓 imacat +-- 初稿日期: 2004-10-16 +-- 版權字樣: 版權所有 (c) 2004-2020 依瑪貓 +-- Set PGCLIENTENCODING=utf8 before restoring it + +SET NAMES 'utf8'; + +START TRANSACTION; + + +-- +-- Table structure for table "mtime" +-- + +CREATE TABLE mtime ( + tabname varchar(32) NOT NULL PRIMARY KEY, + mtime timestamp with time zone NOT NULL DEFAULT now() +); +GRANT SELECT, INSERT, UPDATE, DELETE ON mtime TO nobody; + + +-- +-- Function definition for function "eschtml" +-- +-- integer eschtml(source text) +CREATE FUNCTION eschtml(source text) RETURNS text AS ' + DECLARE + result text; + BEGIN + result := source; + result := replace(result, ''&'', ''&''); + result := replace(result, ''<'', ''<''); + result := replace(result, ''>'', ''>''); + result := replace(result, ''"'', ''"''); + return result; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION eschtml(source text) TO nobody; + + +-- +-- Table structure for table "country" +-- + +CREATE TABLE country ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id char(2) NOT NULL UNIQUE CHECK (position(' ' in id) = 0), + name_en varchar(64) NOT NULL CHECK (name_en != ''), + name_zhtw varchar(32) CHECK (name_zhtw IS NULL OR name_zhtw != ''), + name_zhcn varchar(32) CHECK (name_zhcn IS NULL OR name_zhcn != ''), + special boolean NOT NULL DEFAULT FALSE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL +); +GRANT SELECT, INSERT, UPDATE, DELETE ON country TO nobody; + + +-- +-- Table structure for table "users" +-- + +CREATE TABLE users ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(32) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + passwd char(32) NOT NULL, + name varchar(32) NOT NULL CHECK (name != ''), + disabled boolean NOT NULL DEFAULT FALSE, + deleted boolean NOT NULL DEFAULT FALSE, + lang varchar(5) CHECK (lang IS NULL OR lang != ''), + visits smallint NOT NULL DEFAULT 0 CHECK (visits >= 0), + visited timestamp with time zone, + ip inet, + host varchar(128), + ct char(2) REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON users TO nobody; + +CREATE VIEW users_list AS + SELECT + users.sn AS sn, + users.id AS id, + users.name AS name, + CASE WHEN users.disabled THEN '停用' + ELSE '' + END AS disabled, + CASE WHEN users.deleted THEN '已刪' + ELSE '' + END AS deleted, + CASE WHEN users.lang IS NULL THEN '(無)' + ELSE CASE users.lang + WHEN 'en' THEN '英文' + WHEN 'zh-tw' THEN '繁體中文' + WHEN 'zh-cn' THEN '簡體中文' + WHEN 'ja' THEN '日文' + WHEN 'de' THEN '德文' + WHEN 'es' THEN '西班牙文' + ELSE users.lang + END + END AS lang, + users.visits AS visits, + CASE WHEN users.visited IS NULL THEN '(無)' + ELSE to_char(users.visited, 'YYYY-MM-DD HH:MI:SS') + END AS visited, + CASE WHEN users.ip IS NULL THEN '(無)' + ELSE host(users.ip) + END AS ip, + CASE WHEN users.host IS NULL THEN '(無)' + ELSE users.host + END AS host, + CASE WHEN users.ct IS NULL THEN '(無)' + ELSE ct.name_zhtw + END AS ct, + to_char(users.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(users.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM users + LEFT JOIN country AS ct ON users.ct = ct.id + LEFT JOIN users AS createdby ON users.createdby = createdby.sn + LEFT JOIN users AS updatedby ON users.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON users_list TO nobody; + +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (923153018, 'imacat', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '依瑪貓', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (460376330, 'mandy', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '小招', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); +-- INSERT INTO users (sn, id, passwd, name, disabled, deleted, lang, visits, visited, ip, host, created, createdby, updated, updatedby) VALUES (723676436, 'guestbook', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '留言本', FALSE, FALSE, NULL, 0, NULL, NULL, NULL, now(), 923153018, now(), 923153018); + +-- +-- Fixing the country table +-- + +ALTER TABLE country ADD FOREIGN KEY (createdby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +ALTER TABLE country ADD FOREIGN KEY (updatedby) REFERENCES users ON UPDATE CASCADE DEFERRABLE; +CREATE VIEW country_list AS + SELECT + country.sn AS sn, + country.id AS id, + COALESCE(country.name_zhtw, country.name_en) AS title, + CASE WHEN country.special THEN '特殊' + ELSE '' + END AS special, + to_char(country.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(country.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM country + LEFT JOIN users AS createdby ON country.createdby = createdby.sn + LEFT JOIN users AS updatedby ON country.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON country_list TO nobody; + + +-- +-- Table structure for table "groups" +-- + +CREATE TABLE groups ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + id varchar(16) NOT NULL UNIQUE CHECK (char_length(id) >= 3), + dsc varchar(64) NOT NULL CHECK (dsc != ''), + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groups TO nobody; + +CREATE VIEW groups_list AS + SELECT + groups.sn AS sn, + groups.id AS id, + groups.dsc AS dsc, + to_char(groups.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groups.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groups + LEFT JOIN users AS createdby ON groups.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groups.updatedby = updatedby.sn + ORDER BY id; +GRANT SELECT ON groups_list TO nobody; + +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (553229108, 'root', '總管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (802339805, 'guests', '暱名訪客', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (958210993, 'users', '已登入使用者', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (329685674, 'admin', '所有網站管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (157696540, 'acctman', '帳號管理員', now(), 923153018, now(), 923153018); +-- INSERT INTO groups (sn, id, dsc, created, createdby, updated, updatedby) VALUES (390105230, 'editor', '網站編輯', now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "usermem" +-- + +CREATE TABLE usermem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON usermem TO nobody; + +CREATE VIEW usermem_list AS + SELECT + usermem.sn AS sn, + groups.id || ' (' || groups.dsc || ')' AS grp, + members.id || ' (' || members.name || ')' AS member, + to_char(usermem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(usermem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM usermem + LEFT JOIN groups ON usermem.grp = groups.sn + LEFT JOIN users AS members ON usermem.member = members.sn + LEFT JOIN users AS createdby ON usermem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON usermem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON usermem_list TO nobody; + +-- INSERT INTO usermem (sn, grp, member, created, createdby, updated, updatedby) VALUES (593684712, 553229108, 923153018, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "groupmem" +-- + +CREATE TABLE groupmem ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + member int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE CHECK (member != grp), + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (grp, member) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON groupmem TO nobody; + +CREATE VIEW groupmem_list AS + SELECT + groupmem.sn AS sn, + groups.id || ' (' || groups.dsc || ')' AS grp, + members.id || ' (' || members.dsc || ')' AS member, + to_char(groupmem.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(groupmem.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM groupmem + LEFT JOIN groups ON groupmem.grp = groups.sn + LEFT JOIN groups AS members ON groupmem.member = members.sn + LEFT JOIN users AS createdby ON groupmem.createdby = createdby.sn + LEFT JOIN users AS updatedby ON groupmem.updatedby = updatedby.sn + ORDER BY grp, member; +GRANT SELECT ON groupmem_list TO nobody; + +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (569742102, 329685674, 157696540, now(), 923153018, now(), 923153018); +-- INSERT INTO groupmem (sn, grp, member, created, createdby, updated, updatedby) VALUES (859385977, 329685674, 390105230, now(), 923153018, now(), 923153018); + + +-- +-- Table structure for table "scptpriv" +-- + +CREATE TABLE scptpriv ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + script varchar(64) NOT NULL CHECK (script != ''), + grp int NOT NULL REFERENCES groups ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (script, grp) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON scptpriv TO nobody; + +CREATE VIEW scptpriv_list AS + SELECT + scptpriv.sn AS sn, + scptpriv.script AS script, + groups.dsc AS grp, + to_char(scptpriv.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(scptpriv.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM scptpriv + LEFT JOIN groups ON scptpriv.grp = groups.sn + LEFT JOIN users AS createdby ON scptpriv.createdby = createdby.sn + LEFT JOIN users AS updatedby ON scptpriv.updatedby = updatedby.sn + ORDER BY script, grp; +GRANT SELECT ON scptpriv_list TO nobody; + + +-- +-- Table structure for table "userpref" +-- + +CREATE TABLE userpref ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + usr int REFERENCES users ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + domain varchar(64) CHECK (domain IS NULL OR domain != ''), + name varchar(16) NOT NULL CHECK (name != ''), + value varchar(255) NOT NULL, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (usr, domain, name) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON userpref TO nobody; + +CREATE VIEW userpref_list AS + SELECT + userpref.sn AS sn, + CASE WHEN userpref.usr IS NOT NULL THEN users.name + ELSE '所有人' + END AS usr, + CASE WHEN userpref.domain IS NOT NULL THEN userpref.domain + ELSE '所有地方' + END AS domain, + userpref.name AS name, + userpref.value AS value, + to_char(userpref.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(userpref.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM userpref LEFT JOIN users ON userpref.usr = users.sn + LEFT JOIN users AS createdby ON userpref.createdby = createdby.sn + LEFT JOIN users AS updatedby ON userpref.updatedby = updatedby.sn + ORDER BY domain, usr, name; +GRANT SELECT ON userpref_list TO nobody; + + +-- +-- Function definitions for table "guestbook" +-- + +-- integer guestbook_oldlen(date timestamp with time zone, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp with time zone, updatedby_arg integer) +CREATE FUNCTION guestbook_oldlen(date timestamp with time zone, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp with time zone, updatedby_arg integer) RETURNS integer AS ' + DECLARE + row record; + len integer; + BEGIN + -- : 19, sn: 30 + 1, date: 54 + 1 + len := 105; + len := len + octet_length(host(ip)) + 22; + IF hostname IS NOT NULL THEN + len := len + octet_length(hostname) + 24; + END IF; + IF name IS NOT NULL THEN + len := len + octet_length(eschtml(name)) + 24; + END IF; + IF identity IS NOT NULL THEN + len := len + octet_length(eschtml(identity)) + 28; + END IF; + IF location IS NOT NULL THEN + len := len + octet_length(eschtml(location)) + 28; + END IF; + IF email IS NOT NULL THEN + len := len + octet_length(eschtml(email)) + 25; + END IF; + IF url IS NOT NULL THEN + len := len + octet_length(eschtml(url)) + 23; + END IF; + IF message IS NOT NULL THEN + len := len + octet_length(eschtml(message)) + 27; + END IF; + IF updated != date THEN + len := len + 58; + IF updatedby_arg = 923153018 THEN + len := len + 35; + ELSIF updatedby_arg = 460376330 THEN + len := len + 34; + ELSE + SELECT INTO row name FROM users WHERE sn=updatedby_arg; + len := len + octet_length(row.name) + 29; + END IF; + END IF; + RETURN len; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(date timestamp with time zone, ip inet, hostname text, name text, identity text, location text, email text, url text, message text, updated timestamp with time zone, updatedby_arg integer) TO nobody; +-- integer guestbook_oldlen(sn_arg integer) +CREATE FUNCTION guestbook_oldlen(sn_arg integer) RETURNS integer AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM guestbook WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN guestbook_oldlen(row.created, row.ip, row.host, row.name, row.identity, row.location, row.email, row.url, row.message, row.updated, row.updatedby); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION guestbook_oldlen(sn_arg integer) TO nobody; + + +-- +-- Table structure for table "guestbook" +-- + +CREATE TABLE guestbook ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + name varchar(32) CHECK (name IS NULL OR name != ''), + identity varchar(64) CHECK (identity IS NULL OR identity != ''), + location varchar(64) CHECK (location IS NULL OR location != ''), + email varchar(64) CHECK (email IS NULL OR email != ''), + url varchar(128) CHECK (url IS NULL OR (url != '' AND url != 'http://')), + message text NOT NULL CHECK (message != ''), + hid boolean NOT NULL DEFAULT FALSE, + ip inet NOT NULL, + host varchar(255) CHECK (host IS NULL OR host != ''), + ct char(2) NOT NULL REFERENCES country (id) ON UPDATE CASCADE DEFERRABLE, + pageno int NOT NULL, + oldpageno int, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON guestbook TO nobody; + +CREATE VIEW guestbook_list AS + SELECT + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS _viewurl, + guestbook.sn AS sn, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + COALESCE(guestbook.name, '(未設定)') AS name, + COALESCE(guestbook.identity, '(未設定)') AS identity, + COALESCE(guestbook.location, '(未設定)') AS location, + COALESCE(guestbook.email, '(未設定)') AS email, + COALESCE(guestbook.url, '(未設定)') AS url, + guestbook.message AS message, + CASE WHEN guestbook.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + host(guestbook.ip) AS ip, + COALESCE(guestbook.host, '(不可考)') AS host, + COALESCE(country.name_zhtw, country.name_en) AS ct, + guestbook.pageno AS pageno, + guestbook.oldpageno AS oldpageno, + to_char(guestbook.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(guestbook.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM guestbook + LEFT JOIN country ON guestbook.ct = country.id + LEFT JOIN users AS createdby ON guestbook.createdby = createdby.sn + LEFT JOIN users AS updatedby ON guestbook.updatedby = updatedby.sn + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_list TO nobody; + +CREATE VIEW guestbook_public AS + SELECT + sn AS sn, + extract(epoch FROM created) AS date, + name AS name, + identity AS identity, + location AS location, + email AS email, + url AS url, + message AS message, + pageno AS pageno, + oldpageno AS oldpageno + FROM guestbook + WHERE NOT hid + ORDER BY guestbook.created DESC; +GRANT SELECT ON guestbook_public TO nobody; + + +-- +-- Table structure for table "pages" +-- + +CREATE TABLE pages ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + path varchar(64) NOT NULL UNIQUE CHECK (path != ''), + ord smallint NOT NULL DEFAULT 5000 CHECK (ord >= 0 AND ord < 10000), + title varchar(128) NOT NULL CHECK (title != ''), + title_en varchar(128) NOT NULL CHECK (title_en != ''), + body text NOT NULL CHECK (body != ''), + kw varchar(128) NOT NULL CHECK (kw != ''), + html boolean NOT NULL DEFAULT FALSE, + hid boolean NOT NULL DEFAULT FALSE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON pages TO nobody; + +CREATE VIEW pages_list AS + SELECT + pages.path AS _viewurl, + pages.sn AS sn, + pages.path AS path, + pages.ord AS ord, + pages.title AS title, + pages.title_en AS title_en, + pages.body AS body, + pages.kw AS kw, + CASE WHEN pages.html THEN 'HTML' + ELSE '純文字' + END AS html, + CASE WHEN pages.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(pages.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(pages.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM pages + LEFT JOIN users AS createdby ON pages.createdby = createdby.sn + LEFT JOIN users AS updatedby ON pages.updatedby = updatedby.sn + ORDER BY path; +GRANT SELECT ON pages_list TO nobody; + + +-- +-- Function definitions for table "links" +-- + +-- boolean linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer); +CREATE FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) RETURNS boolean AS ' + BEGIN + IF parent_arg IS NULL THEN + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent IS NULL; + RETURN NOT FOUND; + ELSE + -- TODO: 2019/3/9 Removed schema "public"? Added or it will not work on restore. Not knowing why. + PERFORM * FROM public.linkcat + WHERE id=id_arg AND sn!=sn_arg AND parent=parent_arg; + RETURN NOT FOUND; + END IF; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_id_unique(id_arg text, sn_arg integer, parent_arg integer) TO nobody; + +-- numeric linkcat_fullord(parent_arg integer, ord_arg integer); +CREATE FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) RETURNS numeric AS ' + DECLARE + row record; + sn_loop integer; + ord_loop numeric; + BEGIN + sn_loop := parent_arg; + ord_loop := ord_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, ord FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN NULL; + END IF; + sn_loop := row.parent; + ord_loop := row.ord + ord_loop / 100; + END LOOP; + RETURN ord_loop; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(parent_arg integer, ord_arg integer) TO nobody; +-- numeric linkcat_fullord(sn_arg integer); +CREATE FUNCTION linkcat_fullord(sn_arg integer) RETURNS numeric AS ' + BEGIN + RETURN linkcat_fullord(sn_arg, 0); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fullord(sn_arg integer) TO nobody; + +-- boolean linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + -- Check if we have childs + PERFORM links.sn FROM links + INNER JOIN linkcatz ON linkcatz.link=links.sn + WHERE NOT links.hid AND linkcatz.cat=sn_arg; + IF FOUND THEN + RETURN TRUE; + END IF; + -- Check if we have shown child categories + PERFORM sn FROM linkcat WHERE parent=sn_arg AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + RETURN TRUE; + END IF; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; +-- boolean linkcat_isshown(sn_arg integer); +CREATE FUNCTION linkcat_isshown(sn_arg integer) RETURNS boolean AS ' + DECLARE + row record; + BEGIN + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_isshown(sn_arg, row.hid, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown(sn_arg integer) TO nobody; +-- boolean linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer); +CREATE FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + IF hid_arg THEN + RETURN FALSE; + END IF; + -- Check if we are hidden by our ancestors + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, hid FROM linkcat WHERE sn=sn_loop; + IF row.hid THEN + RETURN FALSE; + END IF; + sn_loop = row.parent; + END LOOP; + RETURN TRUE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_isshown_preview(sn_arg integer, hid_arg boolean, parent_arg integer) TO nobody; + +-- text linkcat_path(sn_arg integer, id_arg text, parent_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + path text; + BEGIN + PERFORM sn FROM linkcat + WHERE parent=sn_arg + AND linkcat_isshown(sn, hid, parent); + IF FOUND THEN + path := ''/'' || id_arg || ''/''; + ELSE + path := ''/'' || id_arg || ''.html''; + END IF; + sn_loop := parent_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_loop; + path := ''/'' || row.id || path; + sn_loop := row.parent; + END LOOP; + RETURN path; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer, id_arg text, parent_arg integer) TO nobody; +-- text linkcat_path(sn_arg integer); +CREATE FUNCTION linkcat_path(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row parent, id FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN linkcat_path(sn_arg, row.id, row.parent); + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_path(sn_arg integer) TO nobody; + +-- boolean linkcat_ischild(parent_arg integer, child_arg integer); +CREATE FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) RETURNS boolean AS ' + DECLARE + row record; + sn_loop integer; + BEGIN + sn_loop := child_arg; + WHILE sn_loop IS NOT NULL LOOP + SELECT INTO row parent FROM linkcat WHERE sn=sn_loop; + IF NOT FOUND THEN + RETURN FALSE; + END IF; + IF row.parent = parent_arg THEN + RETURN TRUE; + END IF; + sn_loop := row.parent; + END LOOP; + RETURN FALSE; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_ischild(parent_arg integer, child_arg integer) TO nobody; + +-- text linkcat_fulltitle(sn_arg integer); +CREATE FUNCTION linkcat_fulltitle(sn_arg integer) RETURNS text AS ' + DECLARE + row record; + sn_loop integer; + title_full text; + BEGIN + IF sn_arg IS NULL THEN + RETURN NULL; + END IF; + SELECT INTO row * FROM linkcat WHERE sn=sn_arg; + IF NOT FOUND THEN + RETURN NULL; + END IF; + title_full := row.title; + WHILE row.parent IS NOT NULL LOOP + sn_loop := row.parent; + SELECT INTO row * FROM linkcat WHERE sn=sn_loop; + title_full := row.title || '' / '' || title_full; + END LOOP; + RETURN title_full; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(sn_arg integer) TO nobody; +-- text linkcat_fulltitle(parent_arg integer, title_arg text); +CREATE FUNCTION linkcat_fulltitle(parent_arg integer, title_arg text) RETURNS text AS ' + BEGIN + IF parent_arg IS NULL THEN + RETURN title_arg; + END IF; + RETURN linkcat_fulltitle(parent_arg) || '' / '' || title_arg; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION linkcat_fulltitle(parent_arg integer, title_arg text) TO nobody; + + +-- +-- Table structure for table "linkcat" +-- + +CREATE TABLE linkcat ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + parent int REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE CHECK (parent IS NULL OR (parent != sn AND NOT linkcat_ischild(sn, parent))), + id varchar(8) NOT NULL CHECK (char_length(id) >= 2 AND linkcat_id_unique(id, sn, parent)), + ord smallint NOT NULL DEFAULT 50 CHECK (ord >= 0 AND ord < 100), + title varchar(128) NOT NULL CHECK (title != ''), + title_en varchar(128) CHECK (title_en IS NULL OR title_en != ''), + kw varchar(128) NOT NULL CHECK (kw != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcat TO nobody; + +CREATE VIEW linkcat_list AS + SELECT + '/links' || linkcat_path(linkcat.sn, linkcat.id, linkcat.parent) AS _viewurl, + linkcat.sn AS sn, + linkcat.id AS id, + linkcat.ord AS ord, + linkcat_fulltitle(linkcat.parent, linkcat.title) AS title, + linkcat.title_en AS title_en, + linkcat.kw AS kw, + CASE WHEN linkcat.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(linkcat.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcat.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcat + LEFT JOIN users AS createdby ON linkcat.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcat.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), id; +GRANT SELECT ON linkcat_list TO nobody; + + +-- +-- Table structure for table "links" +-- + +CREATE TABLE links ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + title varchar(96) NOT NULL CHECK (title != ''), + title_2ln varchar(96) CHECK (title_2ln IS NULL OR title_2ln != ''), + url varchar(128) NOT NULL UNIQUE CHECK (url != '' AND url != 'http://'), + email varchar(64) CHECK (email IS NULL OR email != ''), + icon varchar(128) CHECK (icon IS NULL OR (icon != '' AND icon != 'http://')), + addr varchar(128) CHECK (addr IS NULL OR addr != ''), + tel varchar(48) CHECK (tel IS NULL OR tel != ''), + fax varchar(32) CHECK (fax IS NULL OR fax != ''), + dsc varchar(256) NOT NULL CHECK (dsc != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON links TO nobody; + +CREATE VIEW links_list AS + SELECT + links.url AS _viewurl, + links.sn AS sn, + links.title AS title, + links.title_2ln AS title_2ln, + links.url AS url, + links.url AS _urlcheck, + links.icon AS _imgsrc, + links.email AS email, + links.addr AS addr, + links.tel AS tel, + links.fax AS fax, + links.dsc AS dsc, + CASE WHEN links.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(links.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(links.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM links + LEFT JOIN users AS createdby ON links.createdby = createdby.sn + LEFT JOIN users AS updatedby ON links.updatedby = updatedby.sn + ORDER BY links.title; +GRANT SELECT ON links_list TO nobody; + + +-- +-- Table structure for table "linkcatz" +-- + +CREATE TABLE linkcatz ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + cat int NOT NULL REFERENCES linkcat ON UPDATE CASCADE DEFERRABLE, + link int NOT NULL REFERENCES links ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (cat, link) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON linkcatz TO nobody; + +CREATE VIEW linkcatz_list AS + SELECT + linkcatz.sn AS sn, + linkcat_fulltitle(linkcat.parent, linkcat.title) AS cat, + links.title AS link, + to_char(linkcatz.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(linkcatz.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM linkcatz + LEFT JOIN linkcat ON linkcatz.cat = linkcat.sn + LEFT JOIN links ON linkcatz.link = links.sn + LEFT JOIN users AS createdby ON linkcatz.createdby = createdby.sn + LEFT JOIN users AS updatedby ON linkcatz.updatedby = updatedby.sn + ORDER BY linkcat_fullord(linkcat.parent, linkcat.ord), linkcat.id, link; +GRANT SELECT ON linkcatz_list TO nobody; + + + +-- +-- Function definitions for table "newslets" +-- + +-- integer newslet_textno(no integer); +CREATE FUNCTION newslet_textno(no integer) RETURNS text AS ' + BEGIN + IF no = 1 THEN + RETURN ''創刊號''; + ELSE + RETURN ''第'' || lpad(cast(no AS text), 3, ''0'') || ''期''; + END IF; + END +' LANGUAGE plpgsql; +GRANT EXECUTE ON FUNCTION newslet_textno(no integer) TO nobody; + + +-- +-- Table structure for table "newslets" +-- + +CREATE TABLE newslets ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + no smallint NOT NULL UNIQUE CHECK (no > 0), + date date NOT NULL DEFAULT CURRENT_DATE, + title varchar(32) NOT NULL CHECK (title != ''), + cred_t text NOT NULL CHECK (cred_t != ''), + cred_h text NOT NULL CHECK (cred_h != ''), + kw varchar(64) NOT NULL CHECK (kw != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); +GRANT SELECT, INSERT, UPDATE, DELETE ON newslets TO nobody; + +CREATE VIEW newslets_list AS + SELECT + '/newsletters/wov' || lpad(cast(newslets.no AS text), 4, '0') || '.html' + AS _viewurl, + newslets.sn AS sn, + CASE newslets.no WHEN 1 THEN '創刊號' + ELSE '第' || lpad(cast(newslets.no AS text), 3, '0') || '期' + END AS no, + to_char(newslets.date, 'YYYY-MM-DD') AS date, + newslets.title AS title, + newslets.cred_h AS cred_h, + newslets.cred_t AS cred_t, + newslets.kw AS kw, + CASE WHEN newslets.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(newslets.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(newslets.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM newslets + LEFT JOIN users AS createdby ON newslets.createdby = createdby.sn + LEFT JOIN users AS updatedby ON newslets.updatedby = updatedby.sn + ORDER BY newslets.no DESC; +GRANT SELECT ON newslets_list TO nobody; + + +-- +-- Table structure for table "nlarts" +-- + +CREATE TABLE nlarts ( + sn int NOT NULL PRIMARY KEY CHECK (sn >= 100000000 AND sn <= 999999999), + newslet int NOT NULL REFERENCES newslets ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + title varchar(32) NOT NULL CHECK (title != ''), + author varchar(16) NOT NULL CHECK (author != ''), + body_t text NOT NULL CHECK (body_t != ''), + body_h text NOT NULL CHECK (body_h != ''), + hid boolean NOT NULL DEFAULT FALSE, + created timestamp with time zone NOT NULL DEFAULT now(), + createdby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated timestamp with time zone NOT NULL DEFAULT now(), + updatedby int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (newslet, ord) +); +GRANT SELECT, INSERT, UPDATE, DELETE ON nlarts TO nobody; + +CREATE VIEW nlarts_list AS + SELECT + '/newsletters/wov' || lpad(cast(newslets.no AS text), 4, '0') || '.html' + AS _viewurl, + nlarts.sn AS sn, + CASE newslets.no WHEN 1 THEN '創刊號' + ELSE '第' || lpad(cast(newslets.no AS text), 3, '0') || '期 ' + END || ' ' || to_char(newslets.date, 'YYYY.MM.DD') + AS newslet, + nlarts.ord AS ord, + nlarts.title AS title, + nlarts.author AS author, + nlarts.body_t AS body_t, + nlarts.body_h AS body_h, + CASE WHEN nlarts.hid THEN '隱藏' + ELSE '秀出' + END AS hid, + to_char(nlarts.created, 'YYYY-MM-DD HH:MI:SS') AS created, + createdby.name AS createdby, + to_char(nlarts.updated, 'YYYY-MM-DD HH:MI:SS') AS updated, + updatedby.name AS updatedby + FROM nlarts + LEFT JOIN newslets ON nlarts.newslet = newslets.sn + LEFT JOIN users AS createdby ON nlarts.createdby = createdby.sn + LEFT JOIN users AS updatedby ON nlarts.updatedby = updatedby.sn + ORDER BY newslets.no DESC, nlarts.ord; +GRANT SELECT ON nlarts_list TO nobody; + + +-- +-- VIEW: Search +-- +CREATE VIEW search_list AS + (SELECT + 'pages' AS section, + pages.path AS path, + pages.title || ' ' || pages.title_en AS title, + null AS author, + to_char(pages.updated, 'YYYY-MM-DD') AS date, + null AS newsletter, + null AS nlpath, + pages.body AS body, + pages.kw AS kw, + pages.html AS html, + 1 AS piority + FROM pages + WHERE NOT pages.hid + AND pages.path NOT LIKE '/errors/%') + UNION + (SELECT + 'newsletters' AS section, + '/newsletters/wov' || lpad(cast(newslets.no AS text), 4, '0') + || '.html#art' || lpad(cast(nlarts.ord AS text), 2, '0') + AS path, + nlarts.title AS title, + nlarts.author AS author, + to_char(newslets.date, 'YYYY-MM-DD') AS date, + CASE newslets.no WHEN 1 THEN '創刊號' + ELSE '第' || lpad(cast(newslets.no AS text), 3, '0') || '期' + END || ' ' || newslets.title || ' ' || to_char(newslets.date, 'YYYY.MM.DD') + AS newsletter, + '/newsletters/wov' || lpad(cast(newslets.no AS text), 4, '0') + || '.html' AS nlpath, + nlarts.body_h AS body, + null AS kw, + TRUE AS html, + 0 AS piority + FROM nlarts + LEFT JOIN newslets ON nlarts.newslet = newslets.sn + WHERE NOT newslets.hid + AND NOT nlarts.hid) + UNION + (SELECT + 'links' AS section, + links.url AS path, + links.title AS title, + null AS author, + to_char(links.updated, 'YYYY-MM-DD') AS date, + null AS newsletter, + null AS nlpath, + links.dsc AS body, + CASE WHEN links.title_2ln IS NULL THEN '' ELSE links.title_2ln END + || ' +' || CASE WHEN links.url IS NULL THEN '' ELSE links.url END + || ' +' || CASE WHEN links.email IS NULL THEN '' ELSE links.email END + || ' +' || CASE WHEN links.addr IS NULL THEN '' ELSE links.addr END + || ' +' || CASE WHEN links.tel IS NULL THEN '' ELSE links.tel END + || ' +' || CASE WHEN links.fax IS NULL THEN '' ELSE links.fax END + AS kw, + FALSE AS html, + 1 AS piority + FROM links + WHERE NOT links.hid) + UNION + (SELECT + 'guestbook' AS section, + '/cgi-bin/guestbook.cgi?pageno=' || guestbook.pageno + || '#msg' || guestbook.sn + AS path, + null AS title, + guestbook.name AS author, + to_char(guestbook.created, 'YYYY-MM-DD') AS date, + null AS newsletter, + null AS nlpath, + guestbook.message AS body, + CASE WHEN guestbook.identity IS NULL THEN '' ELSE guestbook.identity END + || ' +' || CASE WHEN guestbook.location IS NULL THEN '' ELSE guestbook.location END + || ' +' || CASE WHEN guestbook.email IS NULL THEN '' ELSE guestbook.email END + || ' +' || CASE WHEN guestbook.url IS NULL THEN '' ELSE guestbook.url END + AS kw, + FALSE AS html, + 1 AS piority + FROM guestbook + WHERE NOT guestbook.hid) + ORDER BY piority, date DESC, title; +GRANT SELECT ON search_list TO nobody; + + +-- +-- Table structure for table "accounting_account" +-- + +CREATE TABLE accounting_account ( + id int NOT NULL PRIMARY KEY CHECK (id >= 100000000 AND id <= 999999999), + parent_id int REFERENCES accounting_account ON UPDATE CASCADE DEFERRABLE, + code varchar(5) NOT NULL UNIQUE CHECK (code != ''), + title varchar(32) NOT NULL CHECK (title != ''), + created_at timestamp with time zone NOT NULL DEFAULT now(), + created_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated_at timestamp with time zone NOT NULL DEFAULT now(), + updated_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); + + +-- +-- Table structure for table "accounting_account_l10n" +-- + +CREATE TABLE accounting_accountl10n ( + id int NOT NULL PRIMARY KEY CHECK (id >= 100000000 AND id <= 999999999), + master_id int REFERENCES accounting_account ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + language varchar(7) NOT NULL CHECK (language != ''), + name varchar(128) NOT NULL CHECK (name != ''), + value varchar(65535) NOT NULL CHECK (value != ''), + created_at timestamp with time zone NOT NULL DEFAULT now(), + created_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated_at timestamp with time zone NOT NULL DEFAULT now(), + updated_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + UNIQUE (master_id, name, language) +); + + +-- +-- Table structure for table "accounting_transaction" +-- + +CREATE TABLE accounting_transaction ( + id int NOT NULL PRIMARY KEY CHECK (id >= 100000000 AND id <= 999999999), + date date NOT NULL DEFAULT CURRENT_DATE, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + notes varchar(128) CHECK (notes IS NULL OR notes != ''), + created_at timestamp with time zone NOT NULL DEFAULT now(), + created_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated_at timestamp with time zone NOT NULL DEFAULT now(), + updated_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); + + +-- +-- Table structure for table "accounting_record" +-- + +CREATE TABLE accounting_record ( + id int NOT NULL PRIMARY KEY CHECK (id >= 100000000 AND id <= 999999999), + transaction_id int NOT NULL REFERENCES accounting_transaction ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE, + is_credit boolean NOT NULL, + ord smallint NOT NULL DEFAULT 1 CHECK (ord > 0 AND ord < 100), + account_id int NOT NULL REFERENCES accounting_account ON UPDATE CASCADE DEFERRABLE, + summary varchar(128) CHECK (summary IS NULL OR summary != ''), + amount numeric(18,2) NOT NULL CHECK (amount > 0), + created_at timestamp with time zone NOT NULL DEFAULT now(), + created_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE, + updated_at timestamp with time zone NOT NULL DEFAULT now(), + updated_by_id int NOT NULL REFERENCES users ON UPDATE CASCADE DEFERRABLE +); + +-- +-- Grant privileges +-- +GRANT ALL ON ALL TABLES IN SCHEMA public TO pythia; +-- You still need the connect privilege afterwards +-- GRANT CONNECT ON DATABASE wov TO pythia; + + +COMMIT; diff --git a/htdocs/wov/magicat/locale/zh_TW/LC_MESSAGES/wov.mo b/htdocs/wov/magicat/locale/zh_TW/LC_MESSAGES/wov.mo new file mode 100644 index 0000000..9af1b31 Binary files /dev/null and b/htdocs/wov/magicat/locale/zh_TW/LC_MESSAGES/wov.mo differ diff --git a/htdocs/wov/magicat/po/Makefile b/htdocs/wov/magicat/po/Makefile new file mode 100644 index 0000000..be23240 --- /dev/null +++ b/htdocs/wov/magicat/po/Makefile @@ -0,0 +1,44 @@ +# Possible make targets: +# all: Compile the PO files and copy the binary MO files +# into the appropriate directories +# xgettext: Obtain the newest PO template file $(PACKAGE).pot +# from the source programs +# msgmerge: Compare the template $(PACKAGE).pot and the existing +# PO files and get the newest POX files to work with. + + +PACKAGE = wov +ALLLINGUAS = zh_TW +PKGROOT = ../.. +PODIR = magicat/po +LOCALEDIR = $(PKGROOT)/magicat/locale +CATEGORY = LC_MESSAGES +PROGRAMS = cgi-bin/*.cgi magicat/cgi-bin/*.cgi magicat/lib/perl5/*/*.pm magicat/lib/perl5/*/*/*.pm magicat/lib/perl5/*/*/*/*.pm magicat/lib/perl5/*/*/*/*/*.pm + +all: + for ln in $(ALLLINGUAS); do \ + msgfmt $$ln.po -o $$ln.gmo; \ + test -d $(LOCALEDIR) || \ + (rm -rf $(LOCALEDIR) && \ + mkdir $(LOCALEDIR)); \ + test -d $(LOCALEDIR)/$$ln || \ + (rm -rf $(LOCALEDIR)/$$ln && \ + mkdir $(LOCALEDIR)/$$ln); \ + test -d $(LOCALEDIR)/$$ln/$(CATEGORY) || \ + (rm -rf $(LOCALEDIR)/$$ln/$(CATEGORY) && \ + mkdir $(LOCALEDIR)/$$ln/$(CATEGORY)); \ + rm -f $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + cp $$ln.gmo $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + done + +xgettext: + cd $(PKGROOT); \ + xgettext --keyword=__ --keyword=N_ -p $(PODIR)/ -o $(PACKAGE).pot \ + --language=c $(PROGRAMS); \ + cd $(PODIR); \ + for ln in $(ALLLINGUAS); do \ + msgmerge $$ln.po $(PACKAGE).pot > $$ln.pox; \ + done + +clean: + rm -f *.gmo diff --git a/htdocs/wov/magicat/po/wov.pot b/htdocs/wov/magicat/po/wov.pot new file mode 100644 index 0000000..2b0c414 --- /dev/null +++ b/htdocs/wov/magicat/po/wov.pot @@ -0,0 +1,833 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-03-24 07:11+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: cgi-bin/1-guestbook.cgi:41 +msgid "your voice" +msgstr "" + +#: cgi-bin/search.cgi:42 +msgid "search, query, full text search" +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:44 magicat/cgi-bin/acctreps.cgi:39 +#: magicat/cgi-bin/acctsubj.cgi:42 magicat/cgi-bin/accttrx.cgi:43 +msgid "accounting" +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:110 magicat/cgi-bin/acctrecs.cgi:157 +#: magicat/cgi-bin/acctsubj.cgi:120 magicat/cgi-bin/acctsubj.cgi:180 +#: magicat/cgi-bin/accttrx.cgi:110 magicat/cgi-bin/accttrx.cgi:157 +#: magicat/cgi-bin/groupmem.cgi:108 magicat/cgi-bin/groupmem.cgi:153 +#: magicat/cgi-bin/groups.cgi:116 magicat/cgi-bin/groups.cgi:165 +#: magicat/cgi-bin/guestbook.cgi:104 magicat/cgi-bin/guestbook.cgi:150 +#: magicat/cgi-bin/linkcat.cgi:116 magicat/cgi-bin/linkcat.cgi:169 +#: magicat/cgi-bin/linkcatz.cgi:109 magicat/cgi-bin/linkcatz.cgi:154 +#: magicat/cgi-bin/links.cgi:106 magicat/cgi-bin/links.cgi:152 +#: magicat/cgi-bin/newslets.cgi:140 magicat/cgi-bin/newslets.cgi:184 +#: magicat/cgi-bin/nlarts.cgi:106 magicat/cgi-bin/nlarts.cgi:151 +#: magicat/cgi-bin/pages.cgi:110 magicat/cgi-bin/pages.cgi:154 +#: magicat/cgi-bin/scptpriv.cgi:106 magicat/cgi-bin/scptpriv.cgi:151 +#: magicat/cgi-bin/usermem.cgi:108 magicat/cgi-bin/usermem.cgi:153 +#: magicat/cgi-bin/userpref.cgi:106 magicat/cgi-bin/userpref.cgi:151 +#: magicat/cgi-bin/users.cgi:125 magicat/cgi-bin/users.cgi:189 +msgid "Incorrect form: [_1]." +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:204 +msgid "Please select the accounting record." +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:212 +msgid "" +"This accounting record does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:93 magicat/cgi-bin/acctsubj.cgi:140 +msgid "Please add a new accounting subject from [_1]." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:109 magicat/cgi-bin/acctsubj.cgi:169 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the subject, " +"[numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] " +"must first be deleted." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:113 magicat/cgi-bin/acctsubj.cgi:173 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the subject, [numerate,_1,its " +"accounting record,all of its accounting records] must first be deleted." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:232 +msgid "Please select the accounting subject." +msgstr "" + +#: magicat/cgi-bin/acctsubj.cgi:240 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/accttrx.cgi:204 +msgid "Please select the accounting transaction." +msgstr "" + +#: magicat/cgi-bin/accttrx.cgi:212 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "" + +#: magicat/cgi-bin/actlog.cgi:36 +msgid "activity, logs" +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:44 +msgid "group membership" +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:200 magicat/cgi-bin/usermem.cgi:200 +msgid "Please select the membership record." +msgstr "" + +#: magicat/cgi-bin/groupmem.cgi:208 magicat/cgi-bin/usermem.cgi:208 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/groups.cgi:48 +msgid "groups" +msgstr "" + +#: magicat/cgi-bin/groups.cgi:212 +msgid "Please select the group." +msgstr "" + +#: magicat/cgi-bin/groups.cgi:220 +msgid "This group does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/guestbook.cgi:40 +msgid "guestbook" +msgstr "" + +#: magicat/cgi-bin/guestbook.cgi:197 +msgid "Please select the message." +msgstr "" + +#: magicat/cgi-bin/guestbook.cgi:205 +msgid "This message does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:44 +msgid "link categories" +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:105 magicat/cgi-bin/linkcat.cgi:158 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:109 magicat/cgi-bin/linkcat.cgi:162 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:219 +msgid "Please select the category." +msgstr "" + +#: magicat/cgi-bin/linkcat.cgi:227 +msgid "This category does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:45 +msgid "link categorization" +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:203 +msgid "Please select the categorization record." +msgstr "" + +#: magicat/cgi-bin/linkcatz.cgi:211 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "" + +#: magicat/cgi-bin/links.cgi:43 magicat/lib/perl5/Selima/wov/Rebuild.pm:226 +msgid "related links" +msgstr "" + +#: magicat/cgi-bin/links.cgi:202 +msgid "Please select the related link." +msgstr "" + +#: magicat/cgi-bin/links.cgi:210 +msgid "This related link does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/logout.cgi:39 +msgid "log out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:112 magicat/cgi-bin/logout.cgi:119 +msgid "Log Out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:135 +msgid "Are you sure you want to log out?" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:136 magicat/lib/perl5/Selima/wov/HTML.pm:433 +msgid "Log out" +msgstr "" + +#: magicat/cgi-bin/logout.cgi:152 +msgid "Log in again." +msgstr "" + +#: magicat/cgi-bin/newslets.cgi:43 +msgid "newsletters" +msgstr "" + +#: magicat/cgi-bin/newslets.cgi:237 +msgid "Please select the newsletter." +msgstr "" + +#: magicat/cgi-bin/newslets.cgi:245 +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:109 +msgid "This newsletter does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/nlarts.cgi:42 +msgid "newsletter articles" +msgstr "" + +#: magicat/cgi-bin/nlarts.cgi:198 +msgid "Please select the article." +msgstr "" + +#: magicat/cgi-bin/nlarts.cgi:206 +msgid "This article does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/pages.cgi:40 +msgid "pages" +msgstr "" + +#: magicat/cgi-bin/pages.cgi:207 +msgid "Please select the page." +msgstr "" + +#: magicat/cgi-bin/pages.cgi:215 +msgid "This page does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/rebuild.cgi:37 +msgid "rebuild pages" +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:42 +msgid "script privilege" +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:198 +msgid "Please select the script privilege record." +msgstr "" + +#: magicat/cgi-bin/scptpriv.cgi:206 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "" + +#: magicat/cgi-bin/usermem.cgi:44 +msgid "user membership" +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:42 +msgid "user preference" +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:198 +msgid "Please select the user preference." +msgstr "" + +#: magicat/cgi-bin/userpref.cgi:206 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "" + +#: magicat/cgi-bin/users.cgi:43 +msgid "users" +msgstr "" + +#: magicat/cgi-bin/users.cgi:236 +msgid "Please select the user." +msgstr "" + +#: magicat/cgi-bin/users.cgi:244 +msgid "This user does not exist anymore. Please select another one." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Config.pm:63 +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:46 +msgid "Newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:82 +msgid "Manage Content" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:84 +msgid "Your Voice" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:86 +msgid "Pages" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:88 +msgid "Woman Interconnect" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:90 +msgid "Woman Interconnect Categories" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:92 +msgid "Woman Interconnect Categorization" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:94 +msgid "Newsletters" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:96 +msgid "Newsletter Articles" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:98 +msgid "Newsletter Subscribers" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:102 +msgid "Manage Accounts" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:104 +msgid "Users" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:106 +msgid "Groups" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:108 +msgid "User Membership" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:110 +msgid "Group Membership" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:112 +msgid "User Preferences" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:114 +msgid "Script Privileges" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:134 +msgid "Miscellaneous" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:136 +msgid "Accounting" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:138 +msgid "Activity Log" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:140 +msgid "Rebuild Pages" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:142 +msgid "Analog" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:144 +msgid "Test Script" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:196 +msgid "Skip to the page content area." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:197 +msgid "Page Content Area" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:356 +msgid "Navigation Links Area" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:431 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:473 +#, c-format +msgid "%s:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:851 +msgid "E-mail" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:876 +msgid "URL.:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:879 +msgid "E-mail:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:885 +msgid "Address:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:887 +msgid "Tel.:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:889 +msgid "Fax.:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:930 +msgid "The database is empty." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:1107 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:1108 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:1121 +msgid "" +"This script is written in Perl." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:59 +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:60 +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:102 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:121 +msgid "Fill in the HTML content here." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:60 +msgid "Please fill in the HTML content." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:63 +msgid "This HTML content is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:83 +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:56 +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:96 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:120 +msgid "Fill in the plain text content here." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:84 +msgid "Please fill in the plain text content." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:87 +msgid "This plain text content is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:106 +msgid "Please select a newsletter." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:115 +msgid "Please fill in the date." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:118 +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:121 +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:123 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:141 +msgid "Please fill in the plain text credits information." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:144 +msgid "This plain text credits information is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:163 +msgid "Please fill in the HTML credits information." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:166 +msgid "This HTML credits information is too long. (Max. length [#,_1])" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook.pm:32 +#: magicat/lib/perl5/Selima/wov/List/Guestbook.pm:42 +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:50 +msgid "What kind of women you are?" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook.pm:37 +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:62 +msgid "Website URL.:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:51 +msgid "Delete this article" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:56 +msgid "This table provides you a form to write a new article." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:59 +msgid "This table provides you a form to edit a current article." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:62 +msgid "This table provides you a form to delete a article." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:79 +msgid "Write a New Newsletter Article" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:82 +msgid "Edit a Current Newsletter Article" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:85 +msgid "Delete a Newsletter Article" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:95 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:117 +msgid "Content (text):" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:101 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:118 +msgid "Content (HTML):" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:107 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:119 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:368 +msgid "Hide?" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:108 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:128 +msgid "Hide this article" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:108 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:129 +msgid "Show this article" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:109 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:122 +msgid "Hide this article currently." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:114 +msgid "Newsletter:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:126 +msgid "Order:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:51 +msgid "Delete this newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:56 +msgid "This table provides you a form to add a new newsletter." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:59 +msgid "This table provides you a form to edit a current newsletter." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:62 +msgid "This table provides you a form to delete a newsletter." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:81 +msgid "Add a New Newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:84 +msgid "Edit a Current Newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:87 +msgid "Delete a Newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:94 +msgid "Preview this newsletter." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:115 +msgid "Title:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:116 +msgid "Author:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:143 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:211 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:309 +msgid "[numerate,_1,Article]:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:212 +msgid "Original:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:213 +msgid "New:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:356 +msgid "Credits (text):" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:357 +msgid "Fill in the credits in plain text here." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:362 +msgid "Credits (HTML):" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:363 +msgid "Fill in the credits in HTML here." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:369 +msgid "Hide this newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:369 +msgid "Show this newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:370 +msgid "Hide this newsletter currently." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:378 +msgid "Issue:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Guestbook.pm:38 +msgid "Select a Message" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Guestbook.pm:39 +msgid "Manage Your Voice" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:38 +msgid "Select a Newsletter Article" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:39 +msgid "Manage Newsletter Articles" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:47 +msgid "Author" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:48 +msgid "Content (text)" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:49 +msgid "Content (HTML)" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:57 +msgid "Write a new article." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:63 +msgid "Search for a article:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:80 +#: magicat/lib/perl5/Selima/wov/List/Search.pm:105 +msgid "Your query found [*,_1,article]." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:83 +#: magicat/lib/perl5/Selima/wov/List/Search.pm:108 +msgid "[*,_1,article]." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:89 +#: magicat/lib/perl5/Selima/wov/List/Search.pm:114 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:93 +#: magicat/lib/perl5/Selima/wov/List/Search.pm:118 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:38 +msgid "Select a Newsletter" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:39 +msgid "Manage Newsletters" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:46 +msgid "Issue" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:47 +msgid "Credits (text)" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:48 +msgid "Credits (HTML)" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:56 +msgid "Add a new newsletter." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:62 +msgid "Search for a newsletter:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:79 +msgid "Your query found [*,_1,newsletter]." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:82 +msgid "[*,_1,newsletter]." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:88 +msgid "Your query found [*,_1,newsletter], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:92 +msgid "[*,_1,newsletter], listing [#,_2] to [#,_3]." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Search.pm:66 +msgid "Please fill in your query." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/List/Search.pm:88 +msgid "Search in the website:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Processor/NLArt.pm:105 +msgid "This article was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Processor/NLArt.pm:109 +msgid "This article has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Processor/NLArt.pm:113 +msgid "This article has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Processor/NLArt.pm:117 +msgid "This article has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Processor/Newslet.pm:197 +msgid "This newsletter was not modified." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Processor/Newslet.pm:201 +msgid "This newsletter has been successfully added." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Processor/Newslet.pm:205 +msgid "This newsletter has been successfully updated." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Processor/Newslet.pm:209 +msgid "This newsletter has been successfully deleted." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:43 +msgid "" +"General commercial advertisements, articles unrelated to gender/sex or " +"articles involving personal attacks are not welcomed. They may be deleted " +"without notice. HTML is not supported." +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:56 +msgid "Message:" +msgstr "" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:57 +msgid "Fill in your message here." +msgstr "" diff --git a/htdocs/wov/magicat/po/zh_TW.gmo b/htdocs/wov/magicat/po/zh_TW.gmo new file mode 100644 index 0000000..9af1b31 Binary files /dev/null and b/htdocs/wov/magicat/po/zh_TW.gmo differ diff --git a/htdocs/wov/magicat/po/zh_TW.po b/htdocs/wov/magicat/po/zh_TW.po new file mode 100644 index 0000000..b4769fe --- /dev/null +++ b/htdocs/wov/magicat/po/zh_TW.po @@ -0,0 +1,856 @@ +# Traditional Chinese PO file for the Woman's Voice +# Copyright (C) 2004-2018 imacat +# This file is distributed under the same license as the wov package. +# imacat , 2004-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: wov 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-03-24 07:11+0800\n" +"PO-Revision-Date: 2018-11-02 00:56+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: cgi-bin/1-guestbook.cgi:41 +msgid "your voice" +msgstr "妳的女聲" + +#: cgi-bin/search.cgi:42 +msgid "search, query, full text search" +msgstr "搜尋, 檢索, 全文檢索" + +#: magicat/cgi-bin/acctrecs.cgi:44 magicat/cgi-bin/acctreps.cgi:39 +#: magicat/cgi-bin/acctsubj.cgi:42 magicat/cgi-bin/accttrx.cgi:43 +msgid "accounting" +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:110 magicat/cgi-bin/acctrecs.cgi:157 +#: magicat/cgi-bin/acctsubj.cgi:120 magicat/cgi-bin/acctsubj.cgi:180 +#: magicat/cgi-bin/accttrx.cgi:110 magicat/cgi-bin/accttrx.cgi:157 +#: magicat/cgi-bin/groupmem.cgi:108 magicat/cgi-bin/groupmem.cgi:153 +#: magicat/cgi-bin/groups.cgi:116 magicat/cgi-bin/groups.cgi:165 +#: magicat/cgi-bin/guestbook.cgi:104 magicat/cgi-bin/guestbook.cgi:150 +#: magicat/cgi-bin/linkcat.cgi:116 magicat/cgi-bin/linkcat.cgi:169 +#: magicat/cgi-bin/linkcatz.cgi:109 magicat/cgi-bin/linkcatz.cgi:154 +#: magicat/cgi-bin/links.cgi:106 magicat/cgi-bin/links.cgi:152 +#: magicat/cgi-bin/newslets.cgi:140 magicat/cgi-bin/newslets.cgi:184 +#: magicat/cgi-bin/nlarts.cgi:106 magicat/cgi-bin/nlarts.cgi:151 +#: magicat/cgi-bin/pages.cgi:110 magicat/cgi-bin/pages.cgi:154 +#: magicat/cgi-bin/scptpriv.cgi:106 magicat/cgi-bin/scptpriv.cgi:151 +#: magicat/cgi-bin/usermem.cgi:108 magicat/cgi-bin/usermem.cgi:153 +#: magicat/cgi-bin/userpref.cgi:106 magicat/cgi-bin/userpref.cgi:151 +#: magicat/cgi-bin/users.cgi:125 magicat/cgi-bin/users.cgi:189 +msgid "Incorrect form: [_1]." +msgstr "查無此表格: [_1] 。" + +#: magicat/cgi-bin/acctrecs.cgi:204 +msgid "Please select the accounting record." +msgstr "請選擇會計分錄。" + +#: magicat/cgi-bin/acctrecs.cgi:212 +msgid "" +"This accounting record does not exist anymore. Please select another one." +msgstr "查無此會計分錄,請重新選擇。" + +#: magicat/cgi-bin/acctsubj.cgi:93 magicat/cgi-bin/acctsubj.cgi:140 +msgid "Please add a new accounting subject from [_1]." +msgstr "請由[_1]建新會計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:109 magicat/cgi-bin/acctsubj.cgi:169 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the subject, " +"[numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] " +"must first be deleted." +msgstr "" +"本會計科目下有子會計科目,不可直接刪除。要刪除本會計科目,請先刪除其下的子會" +"計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:113 magicat/cgi-bin/acctsubj.cgi:173 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the subject, [numerate,_1,its " +"accounting record,all of its accounting records] must first be deleted." +msgstr "" +"本會計科目下有會計分錄,不可直接刪除。要刪除本會計科目,請先刪除其下的會計分" +"錄。" + +#: magicat/cgi-bin/acctsubj.cgi:232 +msgid "Please select the accounting subject." +msgstr "請選擇會計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:240 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "查無此會計科目,請重新選擇。" + +#: magicat/cgi-bin/accttrx.cgi:204 +msgid "Please select the accounting transaction." +msgstr "請選擇會計傳票。" + +#: magicat/cgi-bin/accttrx.cgi:212 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "查無此會計傳票,請重新選擇。" + +#: magicat/cgi-bin/actlog.cgi:36 +msgid "activity, logs" +msgstr "活動, 記錄, 日誌" + +#: magicat/cgi-bin/groupmem.cgi:44 +msgid "group membership" +msgstr "群組成員" + +#: magicat/cgi-bin/groupmem.cgi:200 magicat/cgi-bin/usermem.cgi:200 +msgid "Please select the membership record." +msgstr "請選擇成員關係。" + +#: magicat/cgi-bin/groupmem.cgi:208 magicat/cgi-bin/usermem.cgi:208 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "查無此成員關係,請重新選擇。" + +#: magicat/cgi-bin/groups.cgi:48 +msgid "groups" +msgstr "群組" + +#: magicat/cgi-bin/groups.cgi:212 +msgid "Please select the group." +msgstr "請選擇群組。" + +#: magicat/cgi-bin/groups.cgi:220 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: magicat/cgi-bin/guestbook.cgi:40 +msgid "guestbook" +msgstr "留言本" + +#: magicat/cgi-bin/guestbook.cgi:197 +msgid "Please select the message." +msgstr "請選擇要設定的留言。" + +#: magicat/cgi-bin/guestbook.cgi:205 +msgid "This message does not exist anymore. Please select another one." +msgstr "查無該留言,請改選其她留言。" + +#: magicat/cgi-bin/linkcat.cgi:44 +msgid "link categories" +msgstr "相關連結分類" + +#: magicat/cgi-bin/linkcat.cgi:105 magicat/cgi-bin/linkcat.cgi:158 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: magicat/cgi-bin/linkcat.cgi:109 magicat/cgi-bin/linkcat.cgi:162 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: magicat/cgi-bin/linkcat.cgi:219 +msgid "Please select the category." +msgstr "請選擇分類。" + +#: magicat/cgi-bin/linkcat.cgi:227 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: magicat/cgi-bin/linkcatz.cgi:45 +msgid "link categorization" +msgstr "連結分類表" + +#: magicat/cgi-bin/linkcatz.cgi:203 +msgid "Please select the categorization record." +msgstr "請選擇分類資料。" + +#: magicat/cgi-bin/linkcatz.cgi:211 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "查無此分類資料,請重新選擇。" + +#: magicat/cgi-bin/links.cgi:43 magicat/lib/perl5/Selima/wov/Rebuild.pm:226 +msgid "related links" +msgstr "相關連結" + +#: magicat/cgi-bin/links.cgi:202 +msgid "Please select the related link." +msgstr "請選擇要設定的相關連結。" + +#: magicat/cgi-bin/links.cgi:210 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查無該相關連結,請改選其她相關連結。" + +#: magicat/cgi-bin/logout.cgi:39 +msgid "log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:112 magicat/cgi-bin/logout.cgi:119 +msgid "Log Out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:135 +msgid "Are you sure you want to log out?" +msgstr "妳確定要登出嗎?" + +#: magicat/cgi-bin/logout.cgi:136 magicat/lib/perl5/Selima/wov/HTML.pm:433 +msgid "Log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:152 +msgid "Log in again." +msgstr "重新登入。" + +#: magicat/cgi-bin/newslets.cgi:43 +msgid "newsletters" +msgstr "電子報" + +#: magicat/cgi-bin/newslets.cgi:237 +msgid "Please select the newsletter." +msgstr "請選擇電子報。" + +#: magicat/cgi-bin/newslets.cgi:245 +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:109 +msgid "This newsletter does not exist anymore. Please select another one." +msgstr "查無該電子報,請重新選擇。" + +#: magicat/cgi-bin/nlarts.cgi:42 +msgid "newsletter articles" +msgstr "電子報文章" + +#: magicat/cgi-bin/nlarts.cgi:198 +msgid "Please select the article." +msgstr "請選擇文章。" + +#: magicat/cgi-bin/nlarts.cgi:206 +msgid "This article does not exist anymore. Please select another one." +msgstr "查無該文,請改選其她文章。" + +#: magicat/cgi-bin/pages.cgi:40 +msgid "pages" +msgstr "網頁" + +#: magicat/cgi-bin/pages.cgi:207 +msgid "Please select the page." +msgstr "請選擇網頁。" + +#: magicat/cgi-bin/pages.cgi:215 +msgid "This page does not exist anymore. Please select another one." +msgstr "查無此頁,請改選其她網頁。" + +#: magicat/cgi-bin/rebuild.cgi:37 +msgid "rebuild pages" +msgstr "重製網頁" + +#: magicat/cgi-bin/scptpriv.cgi:42 +msgid "script privilege" +msgstr "程式權限" + +#: magicat/cgi-bin/scptpriv.cgi:198 +msgid "Please select the script privilege record." +msgstr "請選擇程式權限。" + +#: magicat/cgi-bin/scptpriv.cgi:206 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "查無該程式權限,請重新選擇。" + +#: magicat/cgi-bin/usermem.cgi:44 +msgid "user membership" +msgstr "使用者成員" + +#: magicat/cgi-bin/userpref.cgi:42 +msgid "user preference" +msgstr "使用者偏好" + +#: magicat/cgi-bin/userpref.cgi:198 +msgid "Please select the user preference." +msgstr "請選擇使用者偏好。" + +#: magicat/cgi-bin/userpref.cgi:206 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "查無該使用者偏好,請重新選擇。" + +#: magicat/cgi-bin/users.cgi:43 +msgid "users" +msgstr "帳號" + +#: magicat/cgi-bin/users.cgi:236 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: magicat/cgi-bin/users.cgi:244 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: magicat/lib/perl5/Selima/wov/Config.pm:63 +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:46 +msgid "Newsletter" +msgstr "電子報" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:82 +msgid "Manage Content" +msgstr "管理網站" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:84 +msgid "Your Voice" +msgstr "妳的女聲" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:86 +msgid "Pages" +msgstr "網頁" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:88 +msgid "Woman Interconnect" +msgstr "女網牽手" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:90 +msgid "Woman Interconnect Categories" +msgstr "女網牽手分類" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:92 +msgid "Woman Interconnect Categorization" +msgstr "女網牽手分類表" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:94 +msgid "Newsletters" +msgstr "電子報" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:96 +msgid "Newsletter Articles" +msgstr "電子報文章" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:98 +msgid "Newsletter Subscribers" +msgstr "電子報訂戶" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:102 +msgid "Manage Accounts" +msgstr "管理帳號" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:104 +msgid "Users" +msgstr "帳號" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:106 +msgid "Groups" +msgstr "群組" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:108 +msgid "User Membership" +msgstr "使用者成員表" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:110 +msgid "Group Membership" +msgstr "群組成員表" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:112 +msgid "User Preferences" +msgstr "使用者偏好" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:114 +msgid "Script Privileges" +msgstr "程式權限" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:134 +msgid "Miscellaneous" +msgstr "雜項" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:136 +msgid "Accounting" +msgstr "共用帳" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:138 +msgid "Activity Log" +msgstr "活動日誌" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:140 +msgid "Rebuild Pages" +msgstr "重製網頁" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:142 +msgid "Analog" +msgstr "訪客統計" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:144 +msgid "Test Script" +msgstr "測試程式" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:196 +msgid "Skip to the page content area." +msgstr "跳到網頁內文區。" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:197 +msgid "Page Content Area" +msgstr "網頁內文區" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:356 +msgid "Navigation Links Area" +msgstr "導覽連結區" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:431 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "%s,妳好!(修改資料)" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:473 +#, c-format +msgid "%s:" +msgstr "%s:" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:851 +msgid "E-mail" +msgstr "E-mail" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:876 +msgid "URL.:" +msgstr "網址:" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:879 +msgid "E-mail:" +msgstr "E-mail :" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:885 +msgid "Address:" +msgstr "地址:" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:887 +msgid "Tel.:" +msgstr "電話:" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:889 +msgid "Fax.:" +msgstr "傳真:" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:930 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:1107 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "mod_perl -- 速度,動力,無限可能" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:1108 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" +"本程式以 Perl 撰寫,專為 mod_perl 設計強化" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:1121 +msgid "" +"This script is written in Perl." +msgstr "" +"本程式以 Perl 撰寫" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:59 +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:60 +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:102 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:121 +msgid "Fill in the HTML content here." +msgstr "請填上 HTML 的內文。" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:60 +msgid "Please fill in the HTML content." +msgstr "請填上 HTML 的內文。" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:63 +msgid "This HTML content is too long. (Max. length [#,_1])" +msgstr "HTML 內文太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:83 +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:56 +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:96 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:120 +msgid "Fill in the plain text content here." +msgstr "請填上純文字的內文。" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:84 +msgid "Please fill in the plain text content." +msgstr "請填上純文字的內文。" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:87 +msgid "This plain text content is too long. (Max. length [#,_1])" +msgstr "純文字內文太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:106 +msgid "Please select a newsletter." +msgstr "請選擇電子報。" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:115 +msgid "Please fill in the date." +msgstr "請填上日期。" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:118 +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:121 +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:123 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期請以 YYYY-MM-DD 格式填寫。" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:141 +msgid "Please fill in the plain text credits information." +msgstr "請填上純文字發行欄。" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:144 +msgid "This plain text credits information is too long. (Max. length [#,_1])" +msgstr "純文字發行欄太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:163 +msgid "Please fill in the HTML credits information." +msgstr "請填上 HTML 發行欄。" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:166 +msgid "This HTML credits information is too long. (Max. length [#,_1])" +msgstr "HTML 發行欄太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook.pm:32 +#: magicat/lib/perl5/Selima/wov/List/Guestbook.pm:42 +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:50 +msgid "What kind of women you are?" +msgstr "妳是哪種女人?" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook.pm:37 +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:62 +msgid "Website URL.:" +msgstr "網站網址:" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:51 +msgid "Delete this article" +msgstr "刪掉這篇文章" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:56 +msgid "This table provides you a form to write a new article." +msgstr "本表提供寫新文章的表單。" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:59 +msgid "This table provides you a form to edit a current article." +msgstr "本表提供編輯文章的表單。" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:62 +msgid "This table provides you a form to delete a article." +msgstr "本表提供刪除文章的表單。" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:79 +msgid "Write a New Newsletter Article" +msgstr "寫新電子報文章" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:82 +msgid "Edit a Current Newsletter Article" +msgstr "編輯電子報文章" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:85 +msgid "Delete a Newsletter Article" +msgstr "刪除電子報文章" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:95 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:117 +msgid "Content (text):" +msgstr "內文(純文字):" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:101 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:118 +msgid "Content (HTML):" +msgstr "內文(HTML):" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:107 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:119 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:368 +msgid "Hide?" +msgstr "隱藏" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:108 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:128 +msgid "Hide this article" +msgstr "隱藏這篇電子報文章" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:108 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:129 +msgid "Show this article" +msgstr "秀出這篇電子報文章" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:109 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:122 +msgid "Hide this article currently." +msgstr "暫勿秀出這篇電子報文章。" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:114 +msgid "Newsletter:" +msgstr "電子報:" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:126 +msgid "Order:" +msgstr "次序:" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:51 +msgid "Delete this newsletter" +msgstr "刪掉這期電子報" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:56 +msgid "This table provides you a form to add a new newsletter." +msgstr "本表提供建新電子報的表單。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:59 +msgid "This table provides you a form to edit a current newsletter." +msgstr "本表提供編輯電子報的表單。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:62 +msgid "This table provides you a form to delete a newsletter." +msgstr "本表提供刪除電子報的表單。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:81 +msgid "Add a New Newsletter" +msgstr "建新電子報" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:84 +msgid "Edit a Current Newsletter" +msgstr "編輯電子報" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:87 +msgid "Delete a Newsletter" +msgstr "刪除電子報" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:94 +msgid "Preview this newsletter." +msgstr "預覽這期電子報。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:115 +msgid "Title:" +msgstr "標題:" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:116 +msgid "Author:" +msgstr "作者:" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:143 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:211 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:309 +msgid "[numerate,_1,Article]:" +msgstr "文章:" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:212 +msgid "Original:" +msgstr "原:" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:213 +msgid "New:" +msgstr "新:" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:356 +msgid "Credits (text):" +msgstr "發行欄(純文字):" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:357 +msgid "Fill in the credits in plain text here." +msgstr "請填上純文字的發行欄。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:362 +msgid "Credits (HTML):" +msgstr "發行欄(HTML):" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:363 +msgid "Fill in the credits in HTML here." +msgstr "請填上 HTML 的發行欄。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:369 +msgid "Hide this newsletter" +msgstr "隱藏這期電子報" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:369 +msgid "Show this newsletter" +msgstr "秀出這期電子報" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:370 +msgid "Hide this newsletter currently." +msgstr "暫勿秀出這期電子報。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:378 +msgid "Issue:" +msgstr "期數:" + +#: magicat/lib/perl5/Selima/wov/List/Guestbook.pm:38 +msgid "Select a Message" +msgstr "選擇留言" + +#: magicat/lib/perl5/Selima/wov/List/Guestbook.pm:39 +msgid "Manage Your Voice" +msgstr "管理妳的女聲" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:38 +msgid "Select a Newsletter Article" +msgstr "選擇電子報文章" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:39 +msgid "Manage Newsletter Articles" +msgstr "管理電子報文章" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:47 +msgid "Author" +msgstr "作者" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:48 +msgid "Content (text)" +msgstr "內文(純文字)" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:49 +msgid "Content (HTML)" +msgstr "內文(HTML)" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:57 +msgid "Write a new article." +msgstr "寫新文章。" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:63 +msgid "Search for a article:" +msgstr "搜尋文章:" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:80 +#: magicat/lib/perl5/Selima/wov/List/Search.pm:105 +msgid "Your query found [*,_1,article]." +msgstr "共 [#,_1] 篇相符的文章。" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:83 +#: magicat/lib/perl5/Selima/wov/List/Search.pm:108 +msgid "[*,_1,article]." +msgstr "共 [#,_1] 篇文章。" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:89 +#: magicat/lib/perl5/Selima/wov/List/Search.pm:114 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:93 +#: magicat/lib/perl5/Selima/wov/List/Search.pm:118 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:38 +msgid "Select a Newsletter" +msgstr "選擇電子報" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:39 +msgid "Manage Newsletters" +msgstr "管理電子報" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:46 +msgid "Issue" +msgstr "期數" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:47 +msgid "Credits (text)" +msgstr "發行欄(純文字)" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:48 +msgid "Credits (HTML)" +msgstr "發行欄(HTML)" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:56 +msgid "Add a new newsletter." +msgstr "建新電子報。" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:62 +msgid "Search for a newsletter:" +msgstr "搜尋電子報:" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:79 +msgid "Your query found [*,_1,newsletter]." +msgstr "共 [#,_1] 期相符的電子報。" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:82 +msgid "[*,_1,newsletter]." +msgstr "共 [#,_1] 期電子報。" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:88 +msgid "Your query found [*,_1,newsletter], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 期相符的電子報,列出第 [#,_2] 期到第 [#,_3] 期。" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:92 +msgid "[*,_1,newsletter], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 期電子報,列出第 [#,_2] 期到第 [#,_3] 期。" + +#: magicat/lib/perl5/Selima/wov/List/Search.pm:66 +msgid "Please fill in your query." +msgstr "請填上檢索的辭彙。" + +#: magicat/lib/perl5/Selima/wov/List/Search.pm:88 +msgid "Search in the website:" +msgstr "網站檢索:" + +#: magicat/lib/perl5/Selima/wov/Processor/NLArt.pm:105 +msgid "This article was not modified." +msgstr "文章未異動。" + +#: magicat/lib/perl5/Selima/wov/Processor/NLArt.pm:109 +msgid "This article has been successfully added." +msgstr "文章建好了。" + +#: magicat/lib/perl5/Selima/wov/Processor/NLArt.pm:113 +msgid "This article has been successfully updated." +msgstr "文章存好了。" + +#: magicat/lib/perl5/Selima/wov/Processor/NLArt.pm:117 +msgid "This article has been successfully deleted." +msgstr "文章刪掉了。" + +#: magicat/lib/perl5/Selima/wov/Processor/Newslet.pm:197 +msgid "This newsletter was not modified." +msgstr "電子報未異動。" + +#: magicat/lib/perl5/Selima/wov/Processor/Newslet.pm:201 +msgid "This newsletter has been successfully added." +msgstr "電子報建好了。" + +#: magicat/lib/perl5/Selima/wov/Processor/Newslet.pm:205 +msgid "This newsletter has been successfully updated." +msgstr "電子報存好了。" + +#: magicat/lib/perl5/Selima/wov/Processor/Newslet.pm:209 +msgid "This newsletter has been successfully deleted." +msgstr "電子報刪掉了。" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:43 +msgid "" +"General commercial advertisements, articles unrelated to gender/sex or " +"articles involving personal attacks are not welcomed. They may be deleted " +"without notice. HTML is not supported." +msgstr "" +"女聲留言本不歡迎一般商業廣告,與性別無關之言論,及無謂的攻擊性言論,請自重。" +"不支援 HTML 語法。" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:56 +msgid "Message:" +msgstr "留言:" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:57 +msgid "Fill in your message here." +msgstr "請填上妳的留言。" + +#~ msgid "Reports" +#~ msgstr "報表" + +#~ msgid "Transactions" +#~ msgstr "傳票" + +#~ msgid "Subjects" +#~ msgstr "科目" + +#~ msgid "Records" +#~ msgstr "分錄" diff --git a/htdocs/wov/magicat/po/zh_TW.pox b/htdocs/wov/magicat/po/zh_TW.pox new file mode 100644 index 0000000..bdb7de4 --- /dev/null +++ b/htdocs/wov/magicat/po/zh_TW.pox @@ -0,0 +1,857 @@ +# Traditional Chinese PO file for the Woman's Voice +# Copyright (C) 2004-2018 imacat +# This file is distributed under the same license as the wov package. +# imacat , 2004-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: wov 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-03-24 07:11+0800\n" +"PO-Revision-Date: 2018-11-02 00:56+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: cgi-bin/1-guestbook.cgi:41 +msgid "your voice" +msgstr "妳的女聲" + +#: cgi-bin/search.cgi:42 +msgid "search, query, full text search" +msgstr "搜尋, 檢索, 全文檢索" + +#: magicat/cgi-bin/acctrecs.cgi:44 magicat/cgi-bin/acctreps.cgi:39 +#: magicat/cgi-bin/acctsubj.cgi:42 magicat/cgi-bin/accttrx.cgi:43 +msgid "accounting" +msgstr "" + +#: magicat/cgi-bin/acctrecs.cgi:110 magicat/cgi-bin/acctrecs.cgi:157 +#: magicat/cgi-bin/acctsubj.cgi:120 magicat/cgi-bin/acctsubj.cgi:180 +#: magicat/cgi-bin/accttrx.cgi:110 magicat/cgi-bin/accttrx.cgi:157 +#: magicat/cgi-bin/groupmem.cgi:108 magicat/cgi-bin/groupmem.cgi:153 +#: magicat/cgi-bin/groups.cgi:116 magicat/cgi-bin/groups.cgi:165 +#: magicat/cgi-bin/guestbook.cgi:104 magicat/cgi-bin/guestbook.cgi:150 +#: magicat/cgi-bin/linkcat.cgi:116 magicat/cgi-bin/linkcat.cgi:169 +#: magicat/cgi-bin/linkcatz.cgi:109 magicat/cgi-bin/linkcatz.cgi:154 +#: magicat/cgi-bin/links.cgi:106 magicat/cgi-bin/links.cgi:152 +#: magicat/cgi-bin/newslets.cgi:140 magicat/cgi-bin/newslets.cgi:184 +#: magicat/cgi-bin/nlarts.cgi:106 magicat/cgi-bin/nlarts.cgi:151 +#: magicat/cgi-bin/pages.cgi:110 magicat/cgi-bin/pages.cgi:154 +#: magicat/cgi-bin/scptpriv.cgi:106 magicat/cgi-bin/scptpriv.cgi:151 +#: magicat/cgi-bin/usermem.cgi:108 magicat/cgi-bin/usermem.cgi:153 +#: magicat/cgi-bin/userpref.cgi:106 magicat/cgi-bin/userpref.cgi:151 +#: magicat/cgi-bin/users.cgi:125 magicat/cgi-bin/users.cgi:189 +msgid "Incorrect form: [_1]." +msgstr "查無此表格: [_1] 。" + +#: magicat/cgi-bin/acctrecs.cgi:204 +msgid "Please select the accounting record." +msgstr "請選擇會計分錄。" + +#: magicat/cgi-bin/acctrecs.cgi:212 +msgid "" +"This accounting record does not exist anymore. Please select another one." +msgstr "查無此會計分錄,請重新選擇。" + +#: magicat/cgi-bin/acctsubj.cgi:93 magicat/cgi-bin/acctsubj.cgi:140 +msgid "Please add a new accounting subject from [_1]." +msgstr "請由[_1]建新會計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:109 magicat/cgi-bin/acctsubj.cgi:169 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the subject, " +"[numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] " +"must first be deleted." +msgstr "" +"本會計科目下有子會計科目,不可直接刪除。要刪除本會計科目,請先刪除其下的子會" +"計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:113 magicat/cgi-bin/acctsubj.cgi:173 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the subject, [numerate,_1,its " +"accounting record,all of its accounting records] must first be deleted." +msgstr "" +"本會計科目下有會計分錄,不可直接刪除。要刪除本會計科目,請先刪除其下的會計分" +"錄。" + +#: magicat/cgi-bin/acctsubj.cgi:232 +msgid "Please select the accounting subject." +msgstr "請選擇會計科目。" + +#: magicat/cgi-bin/acctsubj.cgi:240 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "查無此會計科目,請重新選擇。" + +#: magicat/cgi-bin/accttrx.cgi:204 +msgid "Please select the accounting transaction." +msgstr "請選擇會計傳票。" + +#: magicat/cgi-bin/accttrx.cgi:212 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "查無此會計傳票,請重新選擇。" + +#: magicat/cgi-bin/actlog.cgi:36 +msgid "activity, logs" +msgstr "活動, 記錄, 日誌" + +#: magicat/cgi-bin/groupmem.cgi:44 +msgid "group membership" +msgstr "群組成員" + +#: magicat/cgi-bin/groupmem.cgi:200 magicat/cgi-bin/usermem.cgi:200 +msgid "Please select the membership record." +msgstr "請選擇成員關係。" + +#: magicat/cgi-bin/groupmem.cgi:208 magicat/cgi-bin/usermem.cgi:208 +msgid "" +"This membership record does not exist anymore. Please select another one." +msgstr "查無此成員關係,請重新選擇。" + +#: magicat/cgi-bin/groups.cgi:48 +msgid "groups" +msgstr "群組" + +#: magicat/cgi-bin/groups.cgi:212 +msgid "Please select the group." +msgstr "請選擇群組。" + +#: magicat/cgi-bin/groups.cgi:220 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: magicat/cgi-bin/guestbook.cgi:40 +msgid "guestbook" +msgstr "留言本" + +#: magicat/cgi-bin/guestbook.cgi:197 +msgid "Please select the message." +msgstr "請選擇要設定的留言。" + +#: magicat/cgi-bin/guestbook.cgi:205 +msgid "This message does not exist anymore. Please select another one." +msgstr "查無該留言,請改選其她留言。" + +#: magicat/cgi-bin/linkcat.cgi:44 +msgid "link categories" +msgstr "相關連結分類" + +#: magicat/cgi-bin/linkcat.cgi:105 magicat/cgi-bin/linkcat.cgi:158 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: magicat/cgi-bin/linkcat.cgi:109 magicat/cgi-bin/linkcat.cgi:162 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: magicat/cgi-bin/linkcat.cgi:219 +msgid "Please select the category." +msgstr "請選擇分類。" + +#: magicat/cgi-bin/linkcat.cgi:227 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: magicat/cgi-bin/linkcatz.cgi:45 +msgid "link categorization" +msgstr "連結分類表" + +#: magicat/cgi-bin/linkcatz.cgi:203 +msgid "Please select the categorization record." +msgstr "請選擇分類資料。" + +#: magicat/cgi-bin/linkcatz.cgi:211 +msgid "" +"This categorization record does not exist anymore. Please select another " +"one." +msgstr "查無此分類資料,請重新選擇。" + +#: magicat/cgi-bin/links.cgi:43 magicat/lib/perl5/Selima/wov/Rebuild.pm:226 +msgid "related links" +msgstr "相關連結" + +#: magicat/cgi-bin/links.cgi:202 +msgid "Please select the related link." +msgstr "請選擇要設定的相關連結。" + +#: magicat/cgi-bin/links.cgi:210 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查無該相關連結,請改選其她相關連結。" + +#: magicat/cgi-bin/logout.cgi:39 +msgid "log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:112 magicat/cgi-bin/logout.cgi:119 +msgid "Log Out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:135 +msgid "Are you sure you want to log out?" +msgstr "妳確定要登出嗎?" + +#: magicat/cgi-bin/logout.cgi:136 magicat/lib/perl5/Selima/wov/HTML.pm:433 +msgid "Log out" +msgstr "登出" + +#: magicat/cgi-bin/logout.cgi:152 +msgid "Log in again." +msgstr "重新登入。" + +#: magicat/cgi-bin/newslets.cgi:43 +msgid "newsletters" +msgstr "電子報" + +#: magicat/cgi-bin/newslets.cgi:237 +msgid "Please select the newsletter." +msgstr "請選擇電子報。" + +#: magicat/cgi-bin/newslets.cgi:245 +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:109 +msgid "This newsletter does not exist anymore. Please select another one." +msgstr "查無該電子報,請重新選擇。" + +#: magicat/cgi-bin/nlarts.cgi:42 +msgid "newsletter articles" +msgstr "電子報文章" + +#: magicat/cgi-bin/nlarts.cgi:198 +msgid "Please select the article." +msgstr "請選擇文章。" + +#: magicat/cgi-bin/nlarts.cgi:206 +msgid "This article does not exist anymore. Please select another one." +msgstr "查無該文,請改選其她文章。" + +#: magicat/cgi-bin/pages.cgi:40 +msgid "pages" +msgstr "網頁" + +#: magicat/cgi-bin/pages.cgi:207 +msgid "Please select the page." +msgstr "請選擇網頁。" + +#: magicat/cgi-bin/pages.cgi:215 +msgid "This page does not exist anymore. Please select another one." +msgstr "查無此頁,請改選其她網頁。" + +#: magicat/cgi-bin/rebuild.cgi:37 +msgid "rebuild pages" +msgstr "重製網頁" + +#: magicat/cgi-bin/scptpriv.cgi:42 +msgid "script privilege" +msgstr "程式權限" + +#: magicat/cgi-bin/scptpriv.cgi:198 +msgid "Please select the script privilege record." +msgstr "請選擇程式權限。" + +#: magicat/cgi-bin/scptpriv.cgi:206 +msgid "" +"This script privilege record does not exist anymore. Please select another " +"one." +msgstr "查無該程式權限,請重新選擇。" + +#: magicat/cgi-bin/usermem.cgi:44 +msgid "user membership" +msgstr "使用者成員" + +#: magicat/cgi-bin/userpref.cgi:42 +msgid "user preference" +msgstr "使用者偏好" + +#: magicat/cgi-bin/userpref.cgi:198 +msgid "Please select the user preference." +msgstr "請選擇使用者偏好。" + +#: magicat/cgi-bin/userpref.cgi:206 +msgid "" +"This user preference does not exist anymore. Please select another one." +msgstr "查無該使用者偏好,請重新選擇。" + +#: magicat/cgi-bin/users.cgi:43 +msgid "users" +msgstr "帳號" + +#: magicat/cgi-bin/users.cgi:236 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: magicat/cgi-bin/users.cgi:244 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: magicat/lib/perl5/Selima/wov/Config.pm:63 +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:46 +msgid "Newsletter" +msgstr "電子報" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:82 +msgid "Manage Content" +msgstr "管理網站" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:84 +msgid "Your Voice" +msgstr "妳的女聲" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:86 +msgid "Pages" +msgstr "網頁" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:88 +msgid "Woman Interconnect" +msgstr "女網牽手" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:90 +msgid "Woman Interconnect Categories" +msgstr "女網牽手分類" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:92 +msgid "Woman Interconnect Categorization" +msgstr "女網牽手分類表" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:94 +msgid "Newsletters" +msgstr "電子報" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:96 +msgid "Newsletter Articles" +msgstr "電子報文章" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:98 +msgid "Newsletter Subscribers" +msgstr "電子報訂戶" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:102 +msgid "Manage Accounts" +msgstr "管理帳號" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:104 +msgid "Users" +msgstr "帳號" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:106 +msgid "Groups" +msgstr "群組" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:108 +msgid "User Membership" +msgstr "使用者成員表" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:110 +msgid "Group Membership" +msgstr "群組成員表" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:112 +msgid "User Preferences" +msgstr "使用者偏好" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:114 +msgid "Script Privileges" +msgstr "程式權限" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:134 +msgid "Miscellaneous" +msgstr "雜項" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:136 +#, fuzzy +msgid "Accounting" +msgstr "管理會計" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:138 +msgid "Activity Log" +msgstr "活動日誌" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:140 +msgid "Rebuild Pages" +msgstr "重製網頁" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:142 +msgid "Analog" +msgstr "訪客統計" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:144 +msgid "Test Script" +msgstr "測試程式" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:196 +msgid "Skip to the page content area." +msgstr "跳到網頁內文區。" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:197 +msgid "Page Content Area" +msgstr "網頁內文區" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:356 +msgid "Navigation Links Area" +msgstr "導覽連結區" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:431 +#, c-format +msgid "Welcome, %s. (Modify)" +msgstr "%s,妳好!(修改資料)" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:473 +#, c-format +msgid "%s:" +msgstr "%s:" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:851 +msgid "E-mail" +msgstr "E-mail" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:876 +msgid "URL.:" +msgstr "網址:" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:879 +msgid "E-mail:" +msgstr "E-mail :" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:885 +msgid "Address:" +msgstr "地址:" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:887 +msgid "Tel.:" +msgstr "電話:" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:889 +msgid "Fax.:" +msgstr "傳真:" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:930 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:1107 +msgid "mod_perl -- Speed, Power, Scalability" +msgstr "mod_perl -- 速度,動力,無限可能" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:1108 +msgid "" +"This script is written in Perl and " +"optimized for mod_perl." +msgstr "" +"本程式以 Perl 撰寫,專為 mod_perl 設計強化" + +#: magicat/lib/perl5/Selima/wov/HTML.pm:1121 +msgid "" +"This script is written in Perl." +msgstr "" +"本程式以 Perl 撰寫" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:59 +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:60 +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:102 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:121 +msgid "Fill in the HTML content here." +msgstr "請填上 HTML 的內文。" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:60 +msgid "Please fill in the HTML content." +msgstr "請填上 HTML 的內文。" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:63 +msgid "This HTML content is too long. (Max. length [#,_1])" +msgstr "HTML 內文太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:83 +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:56 +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:96 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:120 +msgid "Fill in the plain text content here." +msgstr "請填上純文字的內文。" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:84 +msgid "Please fill in the plain text content." +msgstr "請填上純文字的內文。" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:87 +msgid "This plain text content is too long. (Max. length [#,_1])" +msgstr "純文字內文太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/wov/Checker/NLArt.pm:106 +msgid "Please select a newsletter." +msgstr "請選擇電子報。" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:115 +msgid "Please fill in the date." +msgstr "請填上日期。" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:118 +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:121 +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:123 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期請以 YYYY-MM-DD 格式填寫。" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:141 +msgid "Please fill in the plain text credits information." +msgstr "請填上純文字發行欄。" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:144 +msgid "This plain text credits information is too long. (Max. length [#,_1])" +msgstr "純文字發行欄太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:163 +msgid "Please fill in the HTML credits information." +msgstr "請填上 HTML 發行欄。" + +#: magicat/lib/perl5/Selima/wov/Checker/Newslet.pm:166 +msgid "This HTML credits information is too long. (Max. length [#,_1])" +msgstr "HTML 發行欄太長了。(最長 [#,_1] )" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook.pm:32 +#: magicat/lib/perl5/Selima/wov/List/Guestbook.pm:42 +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:50 +msgid "What kind of women you are?" +msgstr "妳是哪種女人?" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook.pm:37 +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:62 +msgid "Website URL.:" +msgstr "網站網址:" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:51 +msgid "Delete this article" +msgstr "刪掉這篇文章" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:56 +msgid "This table provides you a form to write a new article." +msgstr "本表提供寫新文章的表單。" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:59 +msgid "This table provides you a form to edit a current article." +msgstr "本表提供編輯文章的表單。" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:62 +msgid "This table provides you a form to delete a article." +msgstr "本表提供刪除文章的表單。" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:79 +msgid "Write a New Newsletter Article" +msgstr "寫新電子報文章" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:82 +msgid "Edit a Current Newsletter Article" +msgstr "編輯電子報文章" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:85 +msgid "Delete a Newsletter Article" +msgstr "刪除電子報文章" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:95 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:117 +msgid "Content (text):" +msgstr "內文(純文字):" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:101 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:118 +msgid "Content (HTML):" +msgstr "內文(HTML):" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:107 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:119 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:368 +msgid "Hide?" +msgstr "隱藏" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:108 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:128 +msgid "Hide this article" +msgstr "隱藏這篇電子報文章" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:108 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:129 +msgid "Show this article" +msgstr "秀出這篇電子報文章" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:109 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:122 +msgid "Hide this article currently." +msgstr "暫勿秀出這篇電子報文章。" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:114 +msgid "Newsletter:" +msgstr "電子報:" + +#: magicat/lib/perl5/Selima/wov/Form/NLArt.pm:126 +msgid "Order:" +msgstr "次序:" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:51 +msgid "Delete this newsletter" +msgstr "刪掉這期電子報" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:56 +msgid "This table provides you a form to add a new newsletter." +msgstr "本表提供建新電子報的表單。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:59 +msgid "This table provides you a form to edit a current newsletter." +msgstr "本表提供編輯電子報的表單。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:62 +msgid "This table provides you a form to delete a newsletter." +msgstr "本表提供刪除電子報的表單。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:81 +msgid "Add a New Newsletter" +msgstr "建新電子報" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:84 +msgid "Edit a Current Newsletter" +msgstr "編輯電子報" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:87 +msgid "Delete a Newsletter" +msgstr "刪除電子報" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:94 +msgid "Preview this newsletter." +msgstr "預覽這期電子報。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:115 +msgid "Title:" +msgstr "標題:" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:116 +msgid "Author:" +msgstr "作者:" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:143 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:211 +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:309 +msgid "[numerate,_1,Article]:" +msgstr "文章:" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:212 +msgid "Original:" +msgstr "原:" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:213 +msgid "New:" +msgstr "新:" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:356 +msgid "Credits (text):" +msgstr "發行欄(純文字):" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:357 +msgid "Fill in the credits in plain text here." +msgstr "請填上純文字的發行欄。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:362 +msgid "Credits (HTML):" +msgstr "發行欄(HTML):" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:363 +msgid "Fill in the credits in HTML here." +msgstr "請填上 HTML 的發行欄。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:369 +msgid "Hide this newsletter" +msgstr "隱藏這期電子報" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:369 +msgid "Show this newsletter" +msgstr "秀出這期電子報" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:370 +msgid "Hide this newsletter currently." +msgstr "暫勿秀出這期電子報。" + +#: magicat/lib/perl5/Selima/wov/Form/Newslet.pm:378 +msgid "Issue:" +msgstr "期數:" + +#: magicat/lib/perl5/Selima/wov/List/Guestbook.pm:38 +msgid "Select a Message" +msgstr "選擇留言" + +#: magicat/lib/perl5/Selima/wov/List/Guestbook.pm:39 +msgid "Manage Your Voice" +msgstr "管理妳的女聲" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:38 +msgid "Select a Newsletter Article" +msgstr "選擇電子報文章" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:39 +msgid "Manage Newsletter Articles" +msgstr "管理電子報文章" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:47 +msgid "Author" +msgstr "作者" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:48 +msgid "Content (text)" +msgstr "內文(純文字)" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:49 +msgid "Content (HTML)" +msgstr "內文(HTML)" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:57 +msgid "Write a new article." +msgstr "寫新文章。" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:63 +msgid "Search for a article:" +msgstr "搜尋文章:" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:80 +#: magicat/lib/perl5/Selima/wov/List/Search.pm:105 +msgid "Your query found [*,_1,article]." +msgstr "共 [#,_1] 篇相符的文章。" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:83 +#: magicat/lib/perl5/Selima/wov/List/Search.pm:108 +msgid "[*,_1,article]." +msgstr "共 [#,_1] 篇文章。" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:89 +#: magicat/lib/perl5/Selima/wov/List/Search.pm:114 +msgid "Your query found [*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇相符的文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/wov/List/NLArts.pm:93 +#: magicat/lib/perl5/Selima/wov/List/Search.pm:118 +msgid "[*,_1,article], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 篇文章,列出第 [#,_2] 篇到第 [#,_3] 篇。" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:38 +msgid "Select a Newsletter" +msgstr "選擇電子報" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:39 +msgid "Manage Newsletters" +msgstr "管理電子報" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:46 +msgid "Issue" +msgstr "期數" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:47 +msgid "Credits (text)" +msgstr "發行欄(純文字)" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:48 +msgid "Credits (HTML)" +msgstr "發行欄(HTML)" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:56 +msgid "Add a new newsletter." +msgstr "建新電子報。" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:62 +msgid "Search for a newsletter:" +msgstr "搜尋電子報:" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:79 +msgid "Your query found [*,_1,newsletter]." +msgstr "共 [#,_1] 期相符的電子報。" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:82 +msgid "[*,_1,newsletter]." +msgstr "共 [#,_1] 期電子報。" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:88 +msgid "Your query found [*,_1,newsletter], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 期相符的電子報,列出第 [#,_2] 期到第 [#,_3] 期。" + +#: magicat/lib/perl5/Selima/wov/List/Newslets.pm:92 +msgid "[*,_1,newsletter], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 期電子報,列出第 [#,_2] 期到第 [#,_3] 期。" + +#: magicat/lib/perl5/Selima/wov/List/Search.pm:66 +msgid "Please fill in your query." +msgstr "請填上檢索的辭彙。" + +#: magicat/lib/perl5/Selima/wov/List/Search.pm:88 +msgid "Search in the website:" +msgstr "網站檢索:" + +#: magicat/lib/perl5/Selima/wov/Processor/NLArt.pm:105 +msgid "This article was not modified." +msgstr "文章未異動。" + +#: magicat/lib/perl5/Selima/wov/Processor/NLArt.pm:109 +msgid "This article has been successfully added." +msgstr "文章建好了。" + +#: magicat/lib/perl5/Selima/wov/Processor/NLArt.pm:113 +msgid "This article has been successfully updated." +msgstr "文章存好了。" + +#: magicat/lib/perl5/Selima/wov/Processor/NLArt.pm:117 +msgid "This article has been successfully deleted." +msgstr "文章刪掉了。" + +#: magicat/lib/perl5/Selima/wov/Processor/Newslet.pm:197 +msgid "This newsletter was not modified." +msgstr "電子報未異動。" + +#: magicat/lib/perl5/Selima/wov/Processor/Newslet.pm:201 +msgid "This newsletter has been successfully added." +msgstr "電子報建好了。" + +#: magicat/lib/perl5/Selima/wov/Processor/Newslet.pm:205 +msgid "This newsletter has been successfully updated." +msgstr "電子報存好了。" + +#: magicat/lib/perl5/Selima/wov/Processor/Newslet.pm:209 +msgid "This newsletter has been successfully deleted." +msgstr "電子報刪掉了。" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:43 +msgid "" +"General commercial advertisements, articles unrelated to gender/sex or " +"articles involving personal attacks are not welcomed. They may be deleted " +"without notice. HTML is not supported." +msgstr "" +"女聲留言本不歡迎一般商業廣告,與性別無關之言論,及無謂的攻擊性言論,請自重。" +"不支援 HTML 語法。" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:56 +msgid "Message:" +msgstr "留言:" + +#: magicat/lib/perl5/Selima/wov/Form/Guestbook/Public.pm:57 +msgid "Fill in your message here." +msgstr "請填上妳的留言。" + +#~ msgid "Reports" +#~ msgstr "報表" + +#~ msgid "Transactions" +#~ msgstr "傳票" + +#~ msgid "Subjects" +#~ msgstr "科目" + +#~ msgid "Records" +#~ msgstr "分錄" diff --git a/htdocs/wov/newsletters/index.html.html b/htdocs/wov/newsletters/index.html.html new file mode 120000 index 0000000..258e986 --- /dev/null +++ b/htdocs/wov/newsletters/index.html.html @@ -0,0 +1 @@ +index.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/index.html.xhtml b/htdocs/wov/newsletters/index.html.xhtml new file mode 100644 index 0000000..aafc3d6 --- /dev/null +++ b/htdocs/wov/newsletters/index.html.xhtml @@ -0,0 +1,377 @@ + + + + + + + + + + + + + + + + + + + + + +女聲各期目錄 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲各期目錄

    +

    Index of WOVs

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    已出刊女聲目錄
    期數出刊日標題
    第015期
    1.15.’04.

    誰的言論、誰有自由?!

      +
    • 誰的言論、誰有自由?!/小招
    • +
    • 論人獸交,何罪之有?/依瑪貓
    • +
    • [婦運消息]聲援何春蕤出庭活動/編輯室代貼
    • +
    + +
    第014期
    2.4.’01.

    感動的背後

      +
    • 女性主義者快樂嗎?/小招
    • +
    • 感動的背後/依瑪貓
    • +
    + +
    第013期
    9.15.’00.

    離婚女人也有情慾自主權!!

      +
    • 離婚女人也有情慾自主權!!/小招
    • +
    • 習以為常的性別盲/依瑪貓
    • +
    • 〈讀者投書,來函照登〉/蘇岱崙
    • +
    + +
    第012期
    7.11.’00.

    再談女人的網路天空

      +
    • 編輯室手記/編輯室
    • +
    • 沈默的女人/小招
    • +
    • 再談女人的網路天空/依瑪貓
    • +
    + +
    第011期
    3.12.’00.

    「全民公敵」台灣版

      +
    • 女聲復刊通知/編輯室
    • +
    • 「全民公敵」台灣版/小招
    • +
    • 選舉,政治與價值觀的遊戲/依瑪貓
    • +
    + +
    第010期
    11.15.’99.

    媒體的男性凝視--從胖妹詐財案談起

      +
    • 性自主與婚姻的邊緣戰鬥--開拓網路情慾版圖/小招
    • +
    • 媒體的男性凝視--從胖妹詐財案談起/依瑪貓
    • +
    + +
    第009期
    10.25.’99.

    女性抽煙政治學

      +
    • 女性抽煙政治學/小招
    • +
    • 地震的權力遊戲/依瑪貓
    • +
    + +
    第008期
    9.25.’99.

    本期休刊

      +
    • 本期休刊/編輯室
    • +
    + +
    第007期
    9.15.’99.

    女性主義與男性

      +
    • 「必要之惡」誰之惡?/小招
    • +
    • 女性主義與男性/依瑪貓
    • +
    + +
    第006期
    8.30.’99.

    總統選舉,與我何干?

      +
    • 總統選舉,與我何干?/小招
    • +
    • 無處可逃的 Hello Kitty!/依瑪貓
    • +
    + +
    第005期
    8.12.’99.

    反身體歧視宣言

      +
    • 編按/編輯室
    • +
    • 反「胸部」歧視宣言/復活節島的居民
    • +
    • 輔大女研社現況與回顧/梁瓊丹‧張代親
    • +
    + +
    第004期
    7.31.’99.

    父兼母職?

      +
    • 編按/編輯室
    • +
    • 父兼母職?/DEMA
    • +
    • 訴諸男人的恐懼,也可以是一種策略/劉建忻
    • +
    • 「讓誰安心?」作者回應/小招
    • +
    + +
    第003期
    7.17.’99.

    網路上的婦運

      +
    • 讓誰安心?/小招
    • +
    • 網路上的婦運/依瑪貓
    • +
    • 《女聲》網頁/編輯室
    • +
    + +
    第002期
    6.29.’99.

    我們要跟政府算舊帳

      +
    • 編輯啟事/編輯室
    • +
    • 我們要跟政府算舊帳/小招
    • +
    • 美麗與自信--從「爆竹皇后」談起/依瑪貓
    • +
    • 女聲徵稿/編輯室
    • +
    + +
    創刊號
    6.5.’99.

    女性主義‧邊地發聲

      +
    • 三十歲,未婚女人的政治立場/小招
    • +
    • 女性主義邊地發聲/依瑪貓
    • +
    + +
    + +
    +
    下載所有過期女聲
    +

    wovs.zip, 74,671 位元組 (72.9 KB)

    +
    + +
    +
    +
    女聲全文檢索
    +
    + +

    妳可以在下方填上妳想搜尋的詞彙,然後按【搜尋】鈕,在女聲中尋找妳想要的資料。

    + + +
    +
    +
    + + +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0001.html.html b/htdocs/wov/newsletters/wov0001.html.html new file mode 120000 index 0000000..0a1dce4 --- /dev/null +++ b/htdocs/wov/newsletters/wov0001.html.html @@ -0,0 +1 @@ +wov0001.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0001.html.xhtml b/htdocs/wov/newsletters/wov0001.html.xhtml new file mode 100644 index 0000000..a4639f5 --- /dev/null +++ b/htdocs/wov/newsletters/wov0001.html.xhtml @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + +女性主義‧邊地發聲 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》創刊號 1999年6月6日 編輯:小招/依瑪貓
    +網址: http://www.south.nsysu.edu.tw/wov/
    +讀者意見或投稿請寄至:
    +依瑪貓 imacat@mail.eranet.net
    +小招 wandy@ms15.url.com.tw
    +本期文章:
    +
      +
    1. 三十歲,未婚女人的政治立場/小招
    2. +
    3. 女性主義邊地發聲/依瑪貓
    4. +
    + +
    + +
    + +
    +

    三十歲,未婚女人的政治立場

    +
    小招
    + +
    +

    我是一個 30 歲的未婚女人。

    + +

    不要小看所有 30 歲的未婚女人,她們必須面對在 30 歲後如潮湧來的種種社會壓力。

    + +

    這絕對沒有年齡歧視的意味。

    + +

    在父權社會中,只要是一個女人,打從她出生,所有社會對女人的壓迫都逐漸像千層派一樣,層層疊疊地堆上身來,只是裡頭的餡有粗有細,有濃有淡,有酸有苦的分別罷了。

    + +

    當然,會有所謂的天之嬌女(不論是自封的,或是他人想像建構來的),認為打小貼到身上來的幸福(壓迫)都是甜如蜜的。那很好,我們沒必要讓所有女人都認為自己患了受迫害妄想症,但我們也不希望所有女人都抱持著打是情、罵是愛幸福妄想症

    + +

    我只是想說,女人所受的壓迫是不分年齡階級的,當然,它會有差異。

    + +

    例如,當一位總統夫人獨自走在夜晚的窄巷裡,她所面對的心理恐懼,不會低於一位剛從工廠上完夜班的女工所承受的。她比這個女工佔優勢的是,她身邊總會有不少的隨身便衣警衛保護安全,但是,如果這位總統夫人落單了呢?這是所謂的護花使者論。我當然反對。叫大野狼去恐嚇小紅帽,小紅帽唯有委身獵人,才得安全。誰看不出來這是野狼與獵人狼狽為奸,引小紅帽入甕的詭計?

    + +

    真正的問題是,不管是總統夫人,還是人微言輕的女工,只要她是一個女人,她就沒有行動自由。

    + +

    似乎離題遠了。我要回頭來講三十歲未婚女人所面對的社會壓力、社會困境、經濟困境、情慾困境……,妳可以將 30 歲替換成各種年齡,所面對的壓力、困境加上種種的形容詞,讓我們招(召)換(喚)各種不同的女人聲音吧!

    + +

    因為我 30 歲,我的想像力也有限,因此就拿我自己當討論的個案吧!我說過了,我沒有年齡歧視的意思,也沒有矮化其她女人的意味,妳可能會在我身上看到其她女人的影子,我還是必須強調,如有雷同,純屬經驗

    + +

    一般人總認為 30 歲的女人好像很有錢,比如說大家可以看到坊間的暢銷書告訴女人如何在 30 歲前購屋,可是,縱使我在大學中工作,又兼一、兩個小教職,要買房子好像是天方夜譚。講難聽點,付完了房租、生活費,我連頭期款都拿不出來,就算頭期款只要 5 萬元,更何況是之後必須長期抗戰的貸款呢!想去申請便宜一點的房屋貸款,對不起,那是嘉惠合法夫妻的。三十而立,買房子行不通,我開始盤算我的財產繼承權。看看家人都已經幫我盤算好了。我的房子呢,是和我未來的配偶連再一起的。不管是爸爸媽媽、哥哥姊姊都問,男朋友家有沒有房子?沒有房子?!家人都勸我趁早分了吧!理由是不忍心看我得為房子打拼、吃苦,女兒栽培到這麼大,當然得找個有房子的好人家,別吃虧了。財產繼承權?簡單兩個字:放棄。連提都不用提。

    + +

    對女人而言, 30 歲,是一個老化的象徵,這不只是馬齒徒長的現象而已。妳想想,在大學校園中,如果大四等同沒人要的話,年屆 30 ,可就是超級沒人要了。不過,不嫁也沒什麼,我既不物化自己,也還養得活自己,人生不是七十才開始嗎?我還不到開始的時候呢。這可是一個民主自由的國家咧!不結婚犯法嗎?當然不。但結婚總是一個合法的制度,一個合法的制度,大家都進的去,妳如果不進去,那麼妳不是有寡人隱疾,就是沒人要。我自己不覺得什麼,家人可把它當莫大的恥辱。在這個社會中, 30 歲,未婚,早就是一項天大的污名,電視名嘴早已名之單身公害。父母甚至會用沒把妳教好,所以妳嫁不出去的道德觀譴責妳,也譴責她們自己。將婚姻視為享受人生的入口,人們開始把各種同情的眼光丟給妳,同情妳沒有合法的護花使者,同情你無法享受性的愉悅(所以背後稱妳為老處女),同情妳沒有養幾個小孩子來承歡膝下、享受天倫之樂,同情社會上又多了一個無人送終、孤獨無依的老女……,不管你願不願承受,這些自以為是的同情像是無厘頭電影中的蘋果派從四面八方炸過來。

    + +

    相愛的人一定要有婚姻制度來證明相愛的合法性,否則,就是不倫。好大的帽子呀!一個女人不結婚就等於放棄了相愛的權利。為什麼?很簡單,人家會告誡妳,不管對方年紀比妳大、比妳小,女人若不結婚,就別耽誤別人,人家可是要傳宗接代的。好啦,告訴妳對方也是不婚族,我倆只想同居,別人的眼光不止同情,還得加上憐憫了。沒結婚,就和人家住在一起,發生關係,這不注定虧大了? 30 歲的未婚女子若生了幾個孩子可成了重大的社會問題了。君不見代理孕母草案都有未婚歧視嗎?要求婚才夠格擔任代理孕母。所以不論一個未婚女子多會生孩子,生育能力就是會遭到否定,也難怪已婚不孕(兒子)者的壓力有多大了。

    + +

    一個 30 歲的單身女子,不論之前有多少情人, 30 歲,未婚就足以構成一個社會歧視的事實──妳沒有能力綁住一個男人。因此 30 歲未婚的女子事業有成與否並不重要,有不少朋友已經誓死無所不用其極地要把自己嫁出去。托人介紹,或在婚姻介紹所中投注大把的錢,希望可以找到一個比較不爛的男人來嫁,最起碼,不用再面對別人知道妳年齡時抱歉的眼神。運氣差一點的,可能遇到的婚姻騙子,成為報紙社會版上的一篇小故事,讓讀者引為茶餘飯後的閒聊話題,但這些好事的讀者們除了笑妳傻外,可從來不會認為他們可能是壓迫別人走入婚姻的共犯。嫁不出去成為生命中無法承受之輕,開始攬鏡自憐,想像出自己身上各種阻撓自己未婚的缺陷,答案也許是身材太胖、胸部不夠挺、臉蛋不好看、個性不夠溫柔……,不管是什麼答案,總之嫁不出去都要怪自己改造不夠婚姻轉化為未婚女子心頭自虐的枷鎖。

    + +

    不斷有人問:為什麼不結婚?我也常常反問對方:為什麼要結婚?結婚不過是一個約定俗成的習慣,一個傳承、確認子嗣的社會制度,從來就不是為了愛情而存在的,在台灣,成年情侶取得婚姻自主權是20世紀初的事。曾幾何時,婚姻成了雙方對感情負責任的作法。確認婚姻上的名分,並不保證會有一個幸福的婚姻生活,讓小孩有父親、母親,也不代表孩子就能快快樂樂的長成。

    + +

    我, 30 歲,不婚,沒有房子,和愛人住在一起與婚姻制度戰鬥。

    +
    +
    + +
    + +
    +

    女性主義邊地發聲

    +
    依瑪貓
    + +
    +

    26 歲了,我已經習慣用戰鬥來稱呼我自己的生活。

    + +

    五年來,早已經習慣了。生活,就是一場又一場的戰鬥。不管面對的是家人,還是情人、社團、網友、警察、同事。日子由一場一場的鬥爭堆砌起來。權力的遊戲既充斥在街頭,也充斥在生活的每一個角落。

    + +

    這樣的我,一旦停下腳步,就會變得很害怕。

    +
    + +
    +

    我很害怕,害怕寫不出東西。論述的書寫,似乎擺脫不了二元論的陷阱,必然要存在一個對抗的對象,主體才得以存在。我試著擺脫二元論,試著憑空書寫,卻發現失了焦,失了對象。然後就開始習慣性的長期頭痛,腦袋一片空白。

    + +

    我太 energetic(精力旺盛)了。在不知不覺中,逐漸變成《行動革命》中的葛蘿莉亞‧史坦能(我似乎老是會在不知不覺中變成自己崇拜的形象),永遠有用不完的精力,在任何事情上。不論在失意的朋友面前,在 BBS ,在椰林拉子板板面上,在女聲的先期製作過程,永遠都有用不完的熱情和精力,陪失戀網友聊天 +,和沙豬筆戰,思考如何塑造拉子板的方向和可以辦的活動,開拉子聊天室,學 Perl/CGI ,寫網頁,寫程式。

    + +

    史坦能在《行動革命》中說,精力旺盛,是自我空虛的象徵。不敢面對荒蕪的自我,不斷找事來填補自己的空乏。

    + +

    沒錯。好朋友在文學板辦創作比賽來邀稿,每個月總有一兩個看過我網頁的人,寫 E-Mail 問我什麼時候寫新的詩。我不敢寫。其實是寫不出來。一坐在螢幕面前面對自己,腦袋就一片空白。於是,頂多量產一些村上春樹調調的爛詩,更慘的時候連村上春樹都及不上,淪為流行歌的歌詞。

    + +

    我害怕,害怕寫不出女聲,害怕自己會被每天的戰鬥淹沒,害怕寫不出自己。

    +
    + +
    +

    這兩天,臺北市的小學生禁止戀愛了。

    + +

    一對小學六年級的情侶,因為在午休時間親嘴而引起軒然大波。社會各界交相指責連兒童也被污染了,校長對外澄清該女生還是完整的,超視新聞字幕就乾脆寫還好女生還是完璧

    + +

    看到這裏,腦子開始暈眩。似乎婦運這幾年的努力都是白做了。記得很早以前唸過 Andrew Rich 的一段話:我們的社會不給女人和小孩完整的人權,要求他們服從父親,卻寄望這種威權家庭能夠培育出有民主素養、獨立思考的公民!

    + +

    兒童,如同女人,面對的是龐大的家庭∕父權體制。一百年前父權社會說:女人不懂國家大事,不該有投票權;女人很純潔,需要保護以免受害。今天父權社會仍然說同樣的話,對象換了兒童:兒童什麼都不懂,不該有完整權利;兒童很純潔,需要保護以免受害。國小情侶中的女生,則處在性別、年齡雙重身份的交叉點。所以她是純潔再純潔的,受到污染是憾動天地的大事,就像世界末日一樣。

    + +

    我們不禁要問:這樣的思考,對小女孩公平嗎?

    + +

    我們承認、而且支持每個人對身體的自主權,絕對為任何對身體自主的侵害反抗到底。但這樣的身體自主權,有沒有包括兒童?當我們大聲要求我們情慾權的同時,卻看到許多媽媽跳出來要保護兒童免於色情,不讓兒童去接觸不正確的性知識──其實是非官方的性知識。性知識只有官方版的才正確。在這裏我們又看到了對身體自主權的剝奪與掌控──只不過這次是女人掌控女人,就像超視主播甜美但嚴厲的聲音一樣。

    + +

    那小女孩呢?處身性別與年齡的交叉點,承受著雙重的剝奪。沒有人會去追究小男孩到底有沒有完璧?校長不會檢查他是不是完整?但小女孩要接受保健室健康檢查,人們在電視畫面上一遍又一遍強調她貞操的重要性。她的身體自主權被支解了,支解她的是校方、警方、醫生、媒體和社會大眾,每個人都是共犯。

    + +

    兒童有沒有被污染不是重點。這甚至是笑話:即使大人不允許,大多數的小女生小男生早就開始探索自己的身體了。沒見識、大驚小怪、無知兼囉哩八唆的是大人。真正的重點是:大人為什麼這麼急著掌控小女孩與小男孩的身體?是不是害怕小女孩和小男孩太早熟悉自己的身體?害怕他們長大後有了身體自主權?

    +
    + +
    +

    26 歲了,終於出了第一期《女聲》。女聲的製作是一條永無止境的路。不止是目前寫作中的留言板程式而已,還想寫自動訂閱∕退訂處理程式,甚至讀者意見回函、網路投票程式(可以做網路民調)、線上投稿、交友留言板……可以做的有趣事太多了。甚至也許做得好,可以發展成組織,發揮更大的影響力……

    + +

    我不知道。我不知道我能做到什麼地步。也許我不是一個人,而是兩個人。也許不是我們兩個人,而是很多人。女運是一場無止境的奪權鬥爭。當媒體把陳文茜捧成女性主義者,大家也以為那樣就是女性主義者的時候,我就知道,我可以做的事還有很多。

    + +

    這一切,都是從《女聲》的發聲做為起點。

    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 1 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0002.html.html b/htdocs/wov/newsletters/wov0002.html.html new file mode 120000 index 0000000..c82f7ea --- /dev/null +++ b/htdocs/wov/newsletters/wov0002.html.html @@ -0,0 +1 @@ +wov0002.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0002.html.xhtml b/htdocs/wov/newsletters/wov0002.html.xhtml new file mode 100644 index 0000000..a448db8 --- /dev/null +++ b/htdocs/wov/newsletters/wov0002.html.xhtml @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + +我們要跟政府算舊帳 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第002期 1999年6月30日 編輯:小招/依瑪貓
    +網址: http://www.south.nsysu.edu.tw/wov/
    +讀者意見或投稿請寄至:
    +依瑪貓 imacat@mail.eranet.net
    +小招 wandy@ms15.url.com.tw
    +或 女聲專屬信箱 WomansVoice@dreamer.com.tw
    +本期文章:
    +
      +
    1. 編輯啟事/編輯室
    2. +
    3. 我們要跟政府算舊帳/小招
    4. +
    5. 美麗與自信--從「爆竹皇后」談起/依瑪貓
    6. +
    7. 女聲徵稿/編輯室
    8. +
    + +
    + +
    + +
    +

    編輯啟事

    +
    編輯室
    + +
    +
      +
    • 抱歉,因本刊編輯電腦重灌,所以出刊日期延誤,請讀者見諒。
    • +
    • 因應訂戶日漸增加,女聲要尋找專用發信軟體。必需能夠: +
        +
      1. 不受 ISP 限制;
      2. +
      3. 能用簡單方法(如CSV格式)讀取收信者清單。
      4. +
      +若妳知道符合上述條件,又不太貴的軟體,煩請推薦,謝謝。
    • +
    +
    +
    + +
    + +
    +

    我們要跟政府算舊帳

    +
    小招
    + +
    +

    這幾天,又發生了一件令全國震驚、恐懼的憾事,無須我多加說明,大家也知道我指的不是連戰在民調上超越陳水扁,或陳水扁、宋楚瑜皆有意拉攏政績不錯的陳唐山,或是彩虹頻道因播放強暴片遭到起訴一事……等,而是一位高中女生進入軍史館慘遭姦殺棄屍案。呼籲重視婦女安全的聲音再度高漲,婦女在即將舉行總統大選的前夕能獲得官方關注,真是頗為不易,似乎應該感到欣喜,但一想到必須用婦女層層疊疊的血屍堆積起來,除了選票,婦女的命是多麼的不值呢!

    + +

    破案之後,我們可以從各大報的民意論壇中管窺社會反應(畢竟投書民意論壇而能順利上報的仍是少數)。有人因此案發生在博愛特區感到不可思議,順勢推論日後進入總統府亦須戒慎思危,作好萬全的防備,以防不測;有人不斷感傷兇嫌、軍方傷了景美女中師生、社會大眾的心;有人談起士兵宛如軍中長官家僕;有人則痛斥軍方惡意阻隢辦案,蓄意破壞事發現場……等等。

    + +

    不論上述反應如何,卻在在證明臺灣婦女處在一個危險之島。對於幾年前的彭婉如案,相信大家都還記憶猶新,如今尚未破案;白曉燕案呢,聽說陳進興必須賠償天文數字的金額,法官面對人們的質疑時,亦不諱言象徵意義大於實質意義;至於那個五歲的小女孩是否獲得良善的照顧,我們則不得而知。政府的承諾永遠是在事後才提出。

    + +

    身為一個女人,彭婉如並非臺灣首件遭殺害棄屍的案件,現在我們也知道這並不是最後一件,報紙社會版中類似的慘案三五天就對女人發出這個世界多危險的警語。女人動輒得咎,衣服穿太少,會有人恐赫妳不怕被強暴呀!,衣服穿太多,怕被強暴啊?!。女人出門在外,人家會告訴妳:人少的地方不要去、太暗的地方不要去、人蛇雜處(人多的)的地方不要去、時間太晚不要去(所以用門禁把妳鎖起來)……。反正,只要是女人就要舉步維艱,再三思量,否則受到傷害只能算妳 +倒楣。當然現在譴責受害者的情況可能不如以往明顯,但是我們常常仍可以看到媒體拐彎抹角地指責被害者,例如預設受害者是用什麼樣的語言激怒加害者啦,以如何性感的服裝引發加害者的動機啦;明明是性侵害,卻要描寫成是當事人行為不檢;老師對學生的性侵犯,卻蓄意影射成是學生對老師的誘惑……。

    + +

    從事婦運多年,婦女安全議題算是老調重彈。我們總不斷的跟官方要求承諾,官方也習於和我們打高空。像這幾天案發後,報上又有讀者提出推動兩性平等教育的呼聲,但早在彭案後不久教育部就已經成立兩性平等教育委員會,但推行兩性平等教育成效如何?我們知道有許多老師在學校努力推動兩性教育,但畢竟是少數,進展有如牛步。軍方的問題早已層出不窮,但在尹清楓案沉寂多年的今日,軍史館在處理命案的手法上,完全沒有進步。政府似乎寧願將大把的鈔票送到科索伏,把握李總統認為的千載難逢機會,去營造一個人道主義國家的假象(誰知道他指的人道主義要怎麼寫,反正不會是為國內失業的勞工、醫療資源缺乏的原住民,或是殘障團體、單親貧窮家庭、為居住權抗爭的居民等弱勢團體),或是教育部在聲聲窮的藉口中,死命也要採取高學費政策的同時,大手筆的供出上佰億去追求卓越(誰知道他們想追求的卓越要怎麼寫?反正不會是針對付不出學費,可能喪失受教權的學生;或是付不出學費得從事特種行業,又得被警察追著跑學生們;也不是舉債完成學業,一畢業就得忙著還債的學生們)。

    + +

    人總是健忘的,但我發覺政府比人們還健忘。政府其實早已忘記彭婉如、白曉燕……無數的受害者,而會記得彭婉如、白曉燕名字的理由往往和一般人一樣,是因為她們特殊身分,而其他無數的受害者,早讓媒體的大量資訊淹沒掉了。我們不斷不斷地讓政府輕巧的閃過婦女議題,忘記,讓我們在無形中原諒了政府對婦女族群們的忽視;忘記,讓政府不斷的剝奪、削減婦女的福利與權益;忘記,讓我們一次又一次地投出選票支持執政者、政客們的霸權。

    + +

    那末,我們還要繼續淪為執政者們的幫兇嗎?我們心胸寬大,但我們決不容許政府賤踏婦女的基本生存權,今後,只要再發生任何危害婦女生存權的事故,我們必得勞勞記住,我們要跟政府算總賬。

    +
    +
    + +
    + +
    +

    美麗與自信--從「爆竹皇后」談起

    +
    依瑪貓
    + +
    +

    康奈兒是在美國小鎮長大的女孩,從小父母雙亡,跟表姊、表哥一起生活。她羨慕表姊當選爆竹皇后選美、帶領全鎮風光遊行,從小也立定志向要選美。她向表姊借她當年決賽穿的紅衣服,相信只要穿著那件紅衣服,就能像表姊一樣當選爆竹皇后。表姊卻推托不願借她。表哥因打架被關進精神病院,出院之後卻一直幫著康奈兒。康奈兒費盡心力參選,天卻不從人願。就當她心意灰冷之時,美麗的煙火讓她對人生又燃起希望。

    + +

    荷莉杭特和提姆羅賓斯主演的爆竹皇后,嚐試從另一角度,來詮釋美麗的標準。醜小鴨康奈兒努力想追求選美的后冠,雖然現實是殘酷的,但追求的過程本身就是一種成長:朝著目標前進,即使遙不可及,也不放棄;即使最終仍是失敗,但自我已在過程中變得更堅強。表面上的主題是選美比賽(外在的美麗標準),但背後真正的主題是內在自我變得更堅強。

    +
    + +
    +

    以上的話,妳相信嗎?

    + +

    直到前一刻我還相信;但我越寫越有菲夢絲廣告的感覺:美麗,讓我更有自信了。表面談外在美,但背後的主題是內在美,就像現今的塑身廣告邏輯:我們不是推銷美的標準,我們是在塑造自信。

    + +

    塑造內在美自信堅強,可以讓一切合理化。於是,美麗的標準變正當了,因為整個過程其實是追求自我的過程。若背後的主題是談內在美,那更背後的主題就是合理化以美麗的標準衡量女人,合理化女人追求美麗的標準的行為。反正其實是在追求自信嘛!

    + +

    這很精巧,不是嗎?比起以前簡單說美麗的女人更有自信,這次說的是美麗不重要,重要的是自信。像極了女性主義的話,不過自信要透過追求的過程來達成。這次不再是漂亮的最佳女主角,而是一大群外貌中上,打扮像洗澡洗到一半的女人,臉上寫滿透過努力得來的自信。我寧願一三五打工,二四六去媚登峰

    +
    + +
    +

    即使這樣,對女人有什麼好處。

    + +

    當然,美麗不能當飯吃,但不追求美麗省下來的錢,在離婚或失業時可以當飯吃。這是舊式談法。那自信呢?自信可以當飯吃啊!有自信人生可無往不利。沒錯,但,是哪一種自信?是對吃苦能力的自信嗎?

    + +

    我很能吃苦喔!看!連塑身的痛苦都熬過來了!

    + +

    自虐啊?為什麼要靠這樣培養自信?為什麼不一三五去打工,二四六喘口氣休息?資本主義下,女人賺錢是很辛苦的。如果一三五去打工,二四六去媚登峰,那還有什麼時間和閒錢享受自己的美麗與自信

    + +

    女人如果有閒錢,有閒時間,想讓自己更有自信,更充實,方法很多:可以發展興趣,可以寫作,可以學吉他,可以參與社區活動,可以開一家可愛的咖啡店,甚至,和朋友去唱唱歌,去酒吧喝喝酒。

    + +

    雖然以上對有夫有子,老公又收入不豐的大多數女人,已經夠奢侈了:白天上班,晚上做家事,哪裏還有什麼二四六去媚登峰

    +
    +
    + +
    + +
    +

    女聲徵稿

    +
    編輯室
    + +
    +

    我常在想:我們還可以怎麼做?

    + +

    這一陣子,我嚐試去實踐某些夢想:以社區的方式,來經營椰林拉子天堂板。碰巧南方專欄邀稿,我就試著把這一陣子所想寫出來。

    + +

    寫出來,才發現自己的不足。我嚐試談以認同為基礎的虛擬網路社區,但虛擬網路社區能做什麼?能開讀書會,出內部刊物,開板務會議……但如何化為行動?舉個例,人家社區做資源回收,我們可以嗎?(除非妳把螢幕上的資源回收筒算在內)

    + +

    我發覺我對社區理論所知太少。就算夠多,也不見得有用。這是全新的領域:虛擬網路社區,它結合基礎不是地域,而是認同

    + +

    認同社區。我不知道會變什麼樣子。

    + +

    《女聲》也是。若要更基進,必須擴大參與面。不能兩個人自己搞自己爽。如何發出各種女人的聲音?如何聽到更多女人的聲音?

    + +

    我們找朋友,問朋友要不要寫;找學妹,問學妹能不能寫。這些都是方式。這兩天收到某讀者來信,我們讀了相當感動。我想讀者中一定有更多的女性經驗,更多的女人看世界。若能夠把這些聲音都發出來,那該有多好?不一定生猛,也不一定婉約,不一定死硬,也不一定軟調。重要的是,我們想在這些之中找到力量,找到對性別的反省,找到女人的生命力。

    + +

    我們希望妳來稿。題材不限,但要以女人的位置看世界,譬如:工作、職場、家務分工、愛情關係、交通工具、國家政策、學校教材、電視媒體等等,或是我們沒想到的。儘可能以純文字(因為我們是純文字電子報),也勿包含特殊格式(譬如每行一定要幾個字等)。我們會視情況修改成刊登格式,或酌情退稿,但不會更動文稿內容。著作權仍然是妳的。

    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 1 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0003.html.html b/htdocs/wov/newsletters/wov0003.html.html new file mode 120000 index 0000000..3422dc5 --- /dev/null +++ b/htdocs/wov/newsletters/wov0003.html.html @@ -0,0 +1 @@ +wov0003.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0003.html.xhtml b/htdocs/wov/newsletters/wov0003.html.xhtml new file mode 100644 index 0000000..01e81a5 --- /dev/null +++ b/htdocs/wov/newsletters/wov0003.html.xhtml @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + +網路上的婦運 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第003期 1999年7月18日 編輯:小招/依瑪貓
    +網址: http://www.south.nsysu.edu.tw/wov/
    +讀者意見或投稿請寄至:
    +依瑪貓 imacat@mail.eranet.net
    +小招 wandy@ms15.url.com.tw
    +或 女聲專屬信箱 WomansVoice@dreamer.com.tw
    +本期文章:
    +
      +
    1. 讓誰安心?/小招
    2. +
    3. 網路上的婦運/依瑪貓
    4. +
    5. 《女聲》網頁/編輯室
    6. +
    + +
    + +
    + +
    +

    讓誰安心?

    +
    小招
    + +
    +

    最近大家可能常常在電視上,或是電影院的預告片時段看到內政部的宣導影片:一個女字邊衍生出每個人週遭可能出現的女性身分,像是字、字、字、字等,無非是提醒人們小心婦女人身安全,因為這些女人可能是每個家中的一分子,旁白配以男聲,以讓我們安心一詞作結。

    + +

    不知道看過這個廣告的人有何想法?我看到什麼?百分之百的父權心態。片中女人不斷以家庭中成員角色出現,女人的身份定位,只能套入家庭框架中說明,脫離家庭,女人無法單獨存在。旁白的男聲是所謂保護女性的父長式國家機器代言人,是家庭中的男性家長,是家庭中的男性兄長,影片中的女人不是無聲,就是一兩聲穿插其中的台詞,真正掌握完整影片解說權的,是在影片外觀看的男生(聲)們。

    + +

    不以直捷了當的方式宣告女人的基本人權不容侵犯,卻試圖以己所不欲,勿施於人的心態來激發男人的同理心。藉由同理心的道德說教來勸導男人們尊重彼此家中的婦女,以確保自己家中的婦女安全無虞,猶如確保自己財產所有權地讓自己安心,而不是讓女人安心。男人們以尊重彼此的保護權方式,來交換女人的人身安全。

    + +

    身為一個女人,在我的人身安全遭到威脅時,我無法顧及我的社會身份、家庭身份,危急中我所想到的是,我身為一個生命的基本尊嚴。一個以婦女人身安全為訴求的宣導短片,卻只是讓男人心安的手段,我不禁對政府的婦女人身安全政策感到不安。我彷彿已經預見,政府與男人們為求讓自己安心,以確保婦女人身安全的藉口,剝奪女人的行動權,如同實施青少年宵禁以確保青少年安全般,將女人 +一一鎖在的牢籠之中。

    + +

    而女人能說什麼呢?要求人身安全,卻可能失去自由?女人要求國家保障人身安全,是對生存權的基本要求,要的是從教育、法律、政府預算,或是硬體設施等的實質改善,不是政府機關強力播放一些傳統道德勸說的短片就能夠解決的。女人不是供人觀賞的寵物,也不是個人保有的財產,女人擁有自主的意識,安心與否,讓女人自己決定。政府的婦女政策,請從女人的角度出發,別再複製男性父權觀點。

    +
    +
    + +
    + +
    +

    網路上的婦運

    +
    依瑪貓
    + +
    +

    網路上的婦運,寫這種東西一定會被不屑到死。

    + +

    不可否認,網路具有很高的階級性。現在最便宜可上網的電腦一台也要兩萬多,經濟不到某種程度,仍然買不起。

    + +

    然而,電腦價格下滑是事實,電腦普及也是事實。在我買第一台電腦的十年前,一台特價也要五、六萬,和現在兩萬五一台、甚至免費電腦當道不可同日而語。 Windows 95 圖形界面的發展,使得用電腦變得容易很多,而一般公司因此跟著電腦化,也是另一個造成女人使用電腦普遍化的因素:即使大多數女人是文科∕商科畢業,也因為職場需要非用電腦不可。這些種種因素加起來,電腦已不再是幾年前的中產階級專利,而是一般中等收入個人的必需品。

    + +

    我們談網路婦運,必須以上述為基礎來談:網路仍然有階級性,只是因為普及化而日趨重要,就像當年的電視一樣。然而,這仍然不是窮人玩得起的遊戲。

    +
    + +
    +

    網路上的婦運,和現實社會中的婦運有什麼不一樣?

    + +

    不可否認,網路是一種媒體,承載訊息,將資訊由一處傳遞至另一處。和傳統媒體最大的不同是,資訊傳遞成本降低到幾乎大多數人都可以負擔。就像妳現在在看的這份《女聲》電子報,我們只有兩個窮女人,可是我們每期可以和近千人說話。也就是這個緣故,論述∕文本不再是單向性,由作者傳遞給讀者。在網路時代,每個讀者都有可能反過來當作者,取代作者的位置。五年前我開始接觸網路,去年新春買新 Windows 95 電腦後成立自己的網站,知道有電子報這樣東西,今年夏天發行了自己的電子報。這個過程雖不算容易,但也沒那麼難。

    + +

    看到了嗎?其實不難。

    + +

    在網路時代,取得發言權的途逕其實不難,媒體資源不再被文化霸權壟斷。女人要發言,要發聲,要談自己的處境,不再需要依賴男性媒體資本家∕男性編輯的同情。去年年中開始政府大量宣傳全民上網運動,加上 FrontPage 等像 Word 一樣簡單的網頁撰寫程式風行,一時間每個人都有了自己的網頁,每個人都成了某個小媒體的主人。雖然現在看來,其實是造成了成千上萬沒人看的網頁,但,這仍然顯示了網路最大的魅力和運動潛力所在:

    + +

    普遍的發言權力。

    +
    + +
    +

    正因為我們身處於一個意識型態統治的後資本主義社會,所以資訊的權力才會如此重要。我們每天每天,看一大堆男人寫的報紙、男人做的八點檔、男人演的政治秀、男人選的總統、男人做的廣告、男人製作的電影,而我們從中學到很多刻板印象,如:同性戀是可恥的、兒童被污染是可怕的、女人是哭哭啼啼的、青少女性行為是墮落的、婚外的女人是幸福感情殺手、特種行業的女人是好慕虛榮的、女人的外遇是不道德的、男人打女人是不得已的。試想想,若有一天,換我們自己來當媒體,來發聲呢?

    + +

    我不是說換女人來發聲,是換自己來發聲。這很重要。立法院一堆女委員、電視上的八點檔一堆都是女製作人製作的,我們從來也不能肯定地說:那些聲音代表了的聲音。

    + +

    我們要的,是真正我們的聲音。女記者說:公娼的問題,象徵社會道德的瓦解。這是我們公娼的聲音嗎?不是。主婦聯盟的媽媽說:公娼會對青少年帶來不良影響。這是我們公娼的聲音嗎?不是。女教授說:檳榔西施和 KTV 公主是污染青少年的色情打工場所。這是我們檳榔西施和 KTV 公主的聲音嗎?不是。

    + +

    如何發出我們的聲音?當然不是每個人都上網做個網頁就算了。當然,如果妳沒做過自己的網頁∕網站,妳可以試試看,會有很大的收獲。更重要的,是論述的生產,是掌握發言權力:透過不斷思考、寫作與傳達的過程,來對外發言、討論。這是網路最重要的地方:妳的聲音不再是沒有人聽,妳的意見不再是沒有人理會,不再只有某些少數人掌有發言權。

    +
    + +
    +

    權力,其實掌握在每個人手中。對運動者而言,在網路上做婦運,必須要體認到這個事實:我們不再處身於一個要和文化霸權作對抗,只掌握少數媒體資源的可憐階級。我們有那麼強大的發言權,我們也必須要把發言權下放給每個人,讓每個女人有平等的發言權,也能夠平等地發言。現在網頁熱已經過去了,媒體資本強勢介入網際網路的結果,重新壟斷了發言權。大家上網又變回單向的作者-讀者關係。但事情不應該是這樣。我們擁有的是一個每個人都可以發言的媒體。網路婦運工作者應該致力的,是讓每個女人都能夠發出自己的聲音,讓每個女人都能握有權力,而不是只當另一份報紙使用。

    + +

    這才是網路婦運最大的潛力。

    +
    +
    + +
    + +
    +

    《女聲》網頁

    +
    編輯室
    + +
    +

    《女聲》網站終於大致上完成了,大的問題都解決得差不多了。這使得我終於有心思好好寫這一期的文章。

    + +

    如果妳有上過幾次女聲網站,妳就會發現,最近這兩三個星期來網站幾乎天天更新。這三個星期來解決的主要問題有:《女聲》留言本 CGI 程式做出來了、訂閱方式改用 CGI 程式全自動處理;大部份的頁面都由 CGI 程式來產生,也因此可以解決各種瀏覽器( Netscape 、 IE4 、 IE5 )間頁面排版效果不同的問題,也都各自完成了 HTML 4.0/CSS1 的認證;在網上看各期《女聲》也改由 CGI 程式處理,並做出了女聲全文查詢系統。

    + +

    其中我最在意的是留言本,那是讓讀者發聲的最大關鍵。女聲是每個女人的聲音,因此必需要有方便的發聲管道。有人問我: E-Mail 也可以發聲, E-Mail 不行嗎?當然不行。寫信對大多數人來說,實在是太懶了。必需要有方便的發聲管道,降低發言的成本,這才是重點。

    + +

    謝謝老天,完成了。希望完成後的《女聲》網站,能夠帶給妳更新的感覺。

    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 1 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0004.html.html b/htdocs/wov/newsletters/wov0004.html.html new file mode 120000 index 0000000..0b8ffdc --- /dev/null +++ b/htdocs/wov/newsletters/wov0004.html.html @@ -0,0 +1 @@ +wov0004.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0004.html.xhtml b/htdocs/wov/newsletters/wov0004.html.xhtml new file mode 100644 index 0000000..8f07659 --- /dev/null +++ b/htdocs/wov/newsletters/wov0004.html.xhtml @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + +父兼母職? + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第004期 1999年8月1日 編輯:小招/依瑪貓
    +網址: http://www.south.nsysu.edu.tw/wov/
    +讀者意見或投稿請寄至:
    +依瑪貓 imacat@mail.eranet.net
    +小招 wandy@ms15.url.com.tw
    +或 女聲專屬信箱 WomansVoice@dreamer.com.tw
    +本期文章:
    +
      +
    1. 編按/編輯室
    2. +
    3. 父兼母職?/DEMA
    4. +
    5. 訴諸男人的恐懼,也可以是一種策略/劉建忻
    6. +
    7. 「讓誰安心?」作者回應/小招
    8. +
    + +
    + +
    + +
    +

    編按

    +
    編輯室
    + +
    +

    第三期女聲出刊後,我們非常高興讀者對我們的熱烈回應,希望大家在第四期女聲出刊後,也能提出更熱烈的討論。本期除了 DEMA 對父兼母職的探討外,並自本期起刊登讀者來函及作者回應,期待能藉此引發對女聲電子報的互動空間。但限於篇幅,讀者來函與作者回應只擇要一篇刊登。

    +
    +
    + +
    + +
    +

    父兼母職?

    +
    DEMA
    + +
    +

    外子的大哥與大嫂目前處於分居狀態,兩個姪女(名為小屏與小蘭)則留在大伯身邊。昨晚小蘭(目前才四歲)牽著我的手,說道:爸爸說,媽媽不在,爸爸也可以當媽媽。小蘭大概仍不理解父母親之間發生何事了,因此能坦然的表白這些話語。然而我心理想著,對於一位男人而言,要如何扮演女人的角色,何況又須具備媽媽的功能。

    + +

    每當小屏(目前才六歲)到家裡來,總是會訴說很久沒有與我談心事……,對小屏而言,聊天是我與她之間的互動,而且是只跟女生而已,在性別上小屏自己做了這樣的分類。當然也許將來大伯能重新與她建立這種關係;只是,談心事是種溫柔的感受,身為軍人的大伯似乎使小屏無法從中感覺到,因此,在無形之中,小屏將我的女性角色與溫柔對等起來了。

    + +

    當我們歌頌母親的特質時,總是以慈祥、溫暖懷抱及像月亮(陰性)等來比擬,媽媽的角色是以溫柔為取勝,假若按照這種邏輯推論,則以我大伯的性質,恐怕是難以做到爸爸也可以當媽媽的角色。因此,我好奇於一般男人在提出父兼母職的說辭時,到底他們對媽媽的角色認定是什麼?

    + +

    而當我們社會離婚率漸高而單親家庭比率也提高時,社會上又不斷訴求母親的溫柔性質時,對於未層嘗過母親溫柔的單親小孩,恐怕是一種傷害。我的目的並不是要否定母親不須扮演溫柔的角色;真正引起我的質疑的是,社會對於單親家庭的要求總是停留在父兼母職母兼父職,說穿了,其實是認為一個家庭一定要有一父一母,缺其一,就由另一個兼差另一個角色,果若如此,小孩從家庭中學習到的性別角色認定是與雙親家庭不同的。或許這是有助於單親家庭小孩打破父∕母(男∕女)的固定性別認同,然而真正另我擔心的是,父(母)對於他(她)所兼的母(父)職角色,到底是如何認定的?

    +
    +
    + +
    + +
    +

    訴諸男人的恐懼,也可以是一種策略

    +
    劉建忻
    + +
    +

    看完小招的這篇文章,試圖回憶上次在電影院看到的那個短片,沒錯,就是那樣,向男人做訴求的出發點,把女人描述成一個一個家庭中的角色,完全沒有人權至上的呼籲……,從婦運角度來看,小招的批判對它並不冤枉。

    + +

    不過,我也想在此提出另一種觀點。我主要想講的是,這段做的很差的廣告,並非一無用處;它的觀點或許男性中心,但未必比小招想看到的訴求角度更無效。它甚至也牽涉到如何定位訴求對象的問題,也就是說,本片的男性觀眾是性暴力的加害者還是事件旁觀者,仍有討論空間。

    + +

    不可否認地,男人和女人有著截然不同的生長經驗。男人的生命歷程中,沒有被內化在女人心中的行為準繩的灌輸,也沒有被強烈地關注過身體的形狀、月經的麻煩、被強暴的恐懼等。這些經驗,不管是被壓迫、麻煩、或恐懼,儘管都有一些類似的經驗可以幫助想像,儘管它們和男人的被壓迫、麻煩、或恐懼都可以訴諸同樣的原理,但那感覺就是不一樣。像性侵害這樣的事,男人因為受害的機率小,而且身體界線較女人寬鬆、沒有貞操觀、在兩性間的賺賠理論中所佔的位置不同,要去體會受害的痛苦,雖不至於不可能,但也一定會有極大的差距。

    + +

    當然這並不是說男人可以因此卸責,不用去瞭解女人的社會處境及心情。男人應該觀察身邊的女人,從她們的生活經驗看到她們面臨的問題,試圖理解體會,並思考如何建構一個兩性平等的社會。但這種理解仍然只是去塑造一種間接的經驗,離克服經驗差距所造成的體會不完全仍有一段距離。

    + +

    所以我們有兩種可能的方式,來提醒男人重視女人的問題:訴諸一種通用的理論告訴男人女人的人權和男人的一樣重要,或者找另一種連結把男人和那個問題連在一起。小招顯然認為應該是第一種,並批判第二種方式是不把女人放在主體地位的作法;我承認她說的確有道理,但並不認為第二種方式是絕對地不妥。我的想法是:如果我要男人放力氣和資源在防制性侵害事件的發生上,我不會放棄任何一種動員方式,包括讓男人產生女性親友被強暴的恐懼;只不過這種因恐懼所產生的驅動力,應該要被導向對保障人身安全環境的建構,而不是對女性的行為限制。而且,這種己所不欲勿施於人的訴求,也可能比直接講道理有效;就像人對於不要亂倒垃圾的自我約束,也可能是建立在對別人亂倒垃圾的厭惡感,而不是一個公民社會的道德規範上。

    + +

    這裡還應該處理的另一個問題是,這部和男人對話性侵害議題的宣導短片,究竟是把男人當成加害者還是旁觀者?小招的論述角度比較接近去認定男性觀眾是加害者,所以影片訴求看起來像是要求男人尊重彼此的財產權、不要侵犯其他男人的女人。不過,大多數男人不是性侵害的加害者(性騷擾我就不敢說了),公益宣導短片仍有向社會訴求的企圖,我想,如果把影片的企圖看做是激發觀眾對此一議題的重視,從而產生動員力量,是不是就有另一種解釋了?

    + +

    寫到這裡我想到了,前面提到的兩點—男人與女人間經驗的鴻溝、男人的尷尬角色(可以是伙伴,但更經常是加害者及壓迫者)—正是男人與婦運產生關連的最大困難。不過這是另一個問題了,而且好像還更大,恐怕我自己無法處理。

    + +

    不管怎樣,那段短片的確是拍的很爛,效果也有限。也許更積極的作法應該是告訴男人可以做些什麼,像是積極地加入社區夜巡隊伍,或是陪老婆一起學防身術。如果缺少了這些,結果可能就是男人看了短片之後回去叫老婆裙子不要穿得太短,那這份驅動力,就反會成為女人的另一層枷鎖。

    +
    +
    + +
    + +
    +

    「讓誰安心?」作者回應

    +
    小招
    + +
    +

    訴諸男人的恐懼,也可以是一種策略,這是一個挺有趣的標題。自古以來,恐懼便被模擬為一個有效的統治策略,但是否能達到成效不得而知。就像傳統的鬼故事背後總有一套獎善懲惡的意識型態,這個社會也沒因此撥亂反正,反倒是恐懼成了一種快感,貞子的怨念恐怖歸恐怖,不少人看了七夜怪談後,嚇得半夜不敢上廁所,但復活之路貞子謎咒上映時仍躍躍欲試。這樣,你還認為訴諸男人的恐懼,也可以是一種策略嗎?

    + +

    不論男人或女人,打出生起,或許會接觸到母親、祖母、姊妹、外婆、姑媽、阿姨這些親人,卻必須藉一支短短的社教短片來提醒自己,她們是女的?她們的人身安全堪憂?而不斷發生的血淋淋的事件卻無法警醒這些平常不關心身邊女性的人們?

    + +

    我同意傳媒一定有它的效力,錢都花下去了嘛!至於效果如何,是好是壞也無法驗證。我心疼的是,婦女每年能分到的預算就那麼一點點,還要浪費在這種影片……。

    + +

    長期以來,婦運界在看待性侵害事件中男性加害者的問題時,並不是以單純的性需求,而是以暴力作為思考的起點。與其去談如何引發男性對女性家人遭性侵害的恐懼,倒不如想想導致性侵害的源頭何在?

    + +

    傳統社會塑造女性柔弱可欺的形象,這樣思考不斷透過傳媒、語言、教育等途徑複製、深入人心。整個社會在建構男性暴力上不遺餘力,女人並不需要男性武力的保護,要求的是對整個男性暴力的省思。

    + +

    我仍堅持不能避談女人的主體性。如果人們不能接受台灣的將來由美國與中共決定,不能同意李登輝訴諸台灣人的恐懼,也可以是一種策略的話,那麼,訴諸男人的恐懼,就無法成為保障婦女人身安全的一種策略。

    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 1 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0005.html.html b/htdocs/wov/newsletters/wov0005.html.html new file mode 120000 index 0000000..4cdfc35 --- /dev/null +++ b/htdocs/wov/newsletters/wov0005.html.html @@ -0,0 +1 @@ +wov0005.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0005.html.xhtml b/htdocs/wov/newsletters/wov0005.html.xhtml new file mode 100644 index 0000000..4a2e917 --- /dev/null +++ b/htdocs/wov/newsletters/wov0005.html.xhtml @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + +反身體歧視宣言 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第005期 1999年8月13日 編輯:小招/依瑪貓
    +網址: http://www.south.nsysu.edu.tw/wov/
    +讀者意見或投稿請寄至:
    +依瑪貓 imacat@mail.eranet.net
    +小招 wandy@ms15.url.com.tw
    +或 女聲專屬信箱 WomansVoice@dreamer.com.tw
    +本期文章:
    +
      +
    1. 編按/編輯室
    2. +
    3. 反「胸部」歧視宣言/復活節島的居民
    4. +
    5. 輔大女研社現況與回顧/梁瓊丹‧張代親
    6. +
    + +
    + +
    + +
    +

    編按

    +
    編輯室
    + +
    +

    本期首篇文章轉載自女聲網頁的留言,另一篇則是轉載自《婦女與兩性研究通訊第51期》的輔大女研社現況與回顧

    + +

    在反胸部歧視宣言中,復活節島的居民一洩多年來的胸中積怨,從文本中,我們感受到女人要求尊重的力量!但是,女人何止只有胸部成為男性文化大作文章的材料呢?從頭髮的長短、臀部的大小、腋毛與腿毛的明顯與否,女人在他人品頭論足的過程中,不斷地被確認:是不是女人、像不像女人。例如:反串秀中不像女人的女人要成為女人,不是女人的女人要確立女人的真實性。其間評比的標準何在?很簡單,只要在外貌上能符合現實社會美女形象的人──就是女人!那麼,在現實生活中能有多少女人能達到所謂美女的標準呢?在這樣的父權社會凝視下,女人,該如何面對(欣賞)自己的身體?我們可以不甩男性價值的審美觀,反過來,我們更應該企圖顛覆現在標準化一元化規格化的審美標準。妳用什麼方式來對抗這個粗暴的審美標準呢?女聲電子報歡迎投稿,讓大家交流彼此抗暴心得,讓女人不再是默默承受社會歧視的受害者。

    +
    +
    + +
    + +
    +

    反「胸部」歧視宣言

    +
    復活節島的居民
    + +
    +

    這次回家,有一種很深的感慨,而這感慨要從我小時候到長大都一直蒙受的陰影說起。我是一個發育並不好的女孩子,已經二十歲的我,胸前仍無任何起伏。而這次媽媽帶我去買內衣,我竟然沒有一件可以穿的,原因是那裡的尺寸對我來說都太大了!老媽跟那攤位的老闆娘都滿頭疼的,想盡辦法要幫我找一件可以穿的內衣,沒想到在一番三挑四揀之後,她們終於決定幫我找一件內衣裡有很大塊胸墊的內衣,而我當時非常不想買,因為我買了也不會穿,可是看在老媽的愛女心切上,我還是不情願的買了!

    + +

    媽媽是好意,她不希望我出去被別人笑,但我卻以被笑習慣做為理由,想些推拖掉那些內衣。當我說自己已經被笑習慣的時候,那內心的無奈和酸楚是錐心的。我腦海中不停浮現出在我成長歷程中對我乳房何有任何嘲笑的人的嘴臉,笑我的人不知凡幾,從國中的同班男同學到高中的同班女同學,再來到大學的社團男同學,連我自己的男朋友也笑我!

    + +

    一個女人沒有乳房難道要被視為殘障嗎?別人身體的不如意可能已經對當事人產生一些陰影了,為什麼還要朝別人的傷口去一而再再而三的火上加油呢?真的搞不懂一些男人和女人,有乳房才能有愛情、才能有婚姻嗎?沒有乳房的女人難道在愛情和婚姻的道路上直接被判出局了嗎?

    + +

    乳房是造物者賜給女人哺育下一代的工具,它並不完全是用來求偶的,如果男人真喜歡大胸部的女人,為什麼不乾脆去買兩個籃球來抱;如果覺得有乳房才有美滿的性愛的話,那乾脆去路上抓隻母狗來解決就好了!

    + +

    我的憤怒是日積月累的,為什麼一堆人汲汲營營的忙著讓自己的外表更突出、更顯眼,而卻從沒想過要在思想上表現卓越與不凡?所謂胸大真的會無腦嗎?而有腦的女人一定胸小嗎?我想那不盡然吧!這些無聊的話是有心人故意物化女人的手段,女人的價值不是用胸大不大、或人長的美不美來評斷的,女人和所有的男人一樣,我們要的是──尊嚴。如果嘲笑一個女人的胸小,那我們是不是要反過頭來笑男人的陰莖短?這不是兩性互相尊重的方法。

    + +

    肯定人的方法有很多,外表只佔一小部分,更重要的是那個人是否有提升自己和別人層次的能力,我想這才是身為人的重要意義!

    + +

    如果說一個男人成天只知道看女人、為女人打分數的話,那他的操行成績就不及格了,像這種男人,說難聽一點,你們不是在審美,你們就像是在找另外一隻雌性動物交配罷了,像這樣的人,在我的心中,都被槍決掉了!

    + +

    女人要的不是色欲薰心的雙眼,我們要的只是肯定與尊重!

    +
    +
    + +
    + +
    +

    輔大女研社現況與回顧

    +
    梁瓊丹‧張代親
    + +
    轉載自婦女與兩性研究通訊第51期
    + +
    +

    ……要如何說呢?短短一學期的社團經驗,感覺蠻奇特的。原本只是很單純的想知道這個社團到底在幹嘛,想知道一群女人會產生出多大的力量及衝擊力,想知道如果我是這群人裡的一份子,我的人生將會有什麼改變……

    + +

    所以,我進了女研社。

    + +

    從最基本的讀書會到晚上瞞著家人偷偷跑到公娼館去加油助陣,對我來說,每次的衝擊都很大,尤其是讀書會,總覺得每次我的小腦袋都遍體鱗傷的回到家,哈!哈!哈!好像去打戰喔!*^_^* 可是,心情卻蠻舒服的,因為戰場都是我們的,想說什麼就說什麼,實在很爽。哈……哈!

    + +

    下來,我想講一下我對於女研社的看法。

    + +

    嗯!似乎女研社的社員通常都不多,我是認為說,一個社團的人不需要多,可是質要精(這是可以磨練出來的),然後一代接一代,各個據點都有個小尖兵,把一些理念傳播出去,也就好比是一棵大樹,樹愈長愈茂盛,底下的根也愈蔓延愈廣,這樣就會有希望了。只是社團不就是一群有某部分共同興趣的人集合起來的團體嗎?不同的社團提供不同的需求,所以我要問的是女研社提供了什麼,換句話說也就是她的訴求是什麼?

    + +

    而對於社團的走向,嗯!我認為,實務經驗與書本上的理論都需兼顧。

    + +

    至於在社團內情感的交流,嗯!我倒是覺得,這是女研社的一項優點,有一個專屬於女人的地方,想談什麼就談什麼,在外被壓抑變形的感受,在這可以還原到它最原始的面貌,讓人回歸成人。

    + +

    電影侏羅紀公園裡有一句話一直令我印象深刻:生命是會找尋出路的,女研社或許就是這條路,但也或許只是扇通往別處的門;我不知道,我還在摸索中。

    +
    + +
    +

    這是一個加入女研社一年多新生的感言,也大致說明了女研社的現況與活動方向。外界對於女研社有很多的好奇,而究竟女研社到底在做些什麼,我們也可約略從其中窺得一二。

    +
    + +
    +

    輔大女研社的成立

    + +

    輔大女研社,全名為女性研究社,民國八十年成立,原名我們之間—兩性問題研究社,由當時的台灣社會問題研究社和草原文學社中對於性別議題有濃厚興趣的成員推動而誕生。創社之初即以女性問題研究社為名,但校方認為女性本身沒有問題,要兩性相處時才會有問題,故要求要改名為兩性問題研究社。為了順利開創一個女性的空間,故先行與校方妥協,同意以這樣一個方式命名,但要求在社名之前加入我們之間,代表著成員間就如同好友般,可以共同分享喜怒哀樂,共同擔負了在 +一起的生活與命運。

    +
    + +
    +

    定位與走向

    + +

    自許為一個學術性與運動性兼具的社團,提供一個以女性為主的空間,以女人共同的經驗出發,希望能從個人的自覺經驗分享,達到自我肯定與認同女人及學習如何以性別的觀點看待這個男流的社會。各個學期的活動以讀書會,討論會,電影欣賞,大小型演講及成長團體的方式進行,作為經驗分享與相互學習的方式,從而激發出反抗的力量。

    + +

    例行活動討論的問題固然以女性,性∕別為主,如:性騷擾與性侵害,性與性工作,家庭,愛情,女人情慾,空間安全,媒體,參政,但亦積極注意其他社會問題。對於社團運動性的重視與強調是作為我們和其他女研社區隔的特色。大學生頂著高知識份子的頭銜發聲最能夠吸引社會大眾的注意,而女大學生兼具女人和學生的身份,故我們期許自己要能對婦運,學運多盡些心力,利用此身所具備的社會優勢和正當性挑戰社會加諸於女性的種種不合理要求及片面的價值觀。從讀書會到運動現場;從公娼抗爭到反高學費,到秋鬥,到反核,我們都希望能夠結合婦女團體與其他大學女研社的力量,關注女人的社會處境,爭取女性權益,以及共同聲援其他弱勢族群,包括公娼,原住民,同志與女工。

    + +

    女研社目前仍不招收男社員,雖在組織章程中未明文規定,但事實上社團的屬性是不適合男生參與的。因為某些例行活動,如成長團體,我們會討論一些屬於女人之間很私密的經驗,藉此來認識自己,與認識個別女人之間的差異,進而認同女人,凝聚力量。我們發現男社員的存在會使在活動進行中的女社員,較不敢主動發言,而且較有所顧忌。故為了讓個別的女人更有力量,進而重構自己的圖像,女研社還是暫不招收男生,但不否定有男人也可以成為女性主義主體的可能性。

    + +

    國父說主義是一種思想,一種信仰,一種力量。三民主義是這樣,女性主義對我們來說亦是如此。我們先去認識了解,以論述強化自身概念,進而信仰她,她遂成為支持我們走向前的力量,運動的動力也由此而來。

    +
    + +
    +

    參加女研社的動機

    + +

    大部份的社員都只是基於一個很單純的理由,來尋找志同道合的人做共同有興趣的事,是去尋找一種與自身生命經驗相契合的論式進而去反省生活,去挑戰一種大家認為是理所當然的價值觀,替自己找到另外一條前進的路。是找尋一個可以自由發聲的管道,讓常久以來被忽略的我們也有一個自己的舞台。偶然也有誤以為女研社為女同志社團的社員加入,但又如何呢?女研社的學生本就不該再持有與一般人相同的性別刻板印象,而女同志的加入更豐富了社團的文化。

    + +

    一群女生在一起可以做什麼事?我們要做什麼事?

    + +

    好女孩不做;女孩要作得好。註一我們不必要作別人眼中的女孩,當女孩又怎樣?我們並沒有因此過得更好?Y世代的新女生要有自己的主張,不必屈從於傳統藩籬,我們甚至要以作女孩為樂。女孩有過人的膽識挑戰一切不可能;女孩有獨特的見解與智識,知道如何展現自我。

    +
    + +
    +

    女研社中的姐妹情誼

    + +

    我們之間原是描寫兩名女子在戰後偶然相遇而結為好友的影片,她們彼此扶持,彼此分享喜悅,一起歡笑,一起悲傷。從片中我們看見女性情誼的展現以及身為女性如何去面對家庭,工作及自己情感的矛盾與衝突,以及至於最後女性選擇了彼此的聯結,擺脫困境及對抗種種不合理的現象,終於開拓她們自己的生存空間。這種屬於我們之間的情感與經驗應該是被熟悉的,故從創社的兩性研究社到今天的女研,社團中濃厚的姐妹情誼一直是我們所感到驕傲的。我們一起看到生命的侷限,一起釐清面對甚至對抗我們生命中所遇到的困難,處境與挫折,同時我們也了解這些經驗不只屬於我們幾個人而已,有更多的女性是與我們相同的,儘管時空不同,背景環境不同,只要是女人,都會有這樣相似的經驗與過程。

    + +

    初入這所人數眾多的大學,很容易感覺到人與人之間的陌生與疏離,人來人往的校園,大家互不相識。女研社的姐妹情誼就是一種歸屬感,幫助新生克服對新環境的不適應,對生命的疑慮,傾倒妳的心情殘渣,在這裡發洩,在這裡得到安慰。在冷漠的工業城,偌大的校園裡,就是有一個這樣讓人流戀的好地方。

    +
    + +
    +

    經營的瓶頸與困境

    + +

    資源的不足

    + +

    相較於其他背景雄厚的公立大學有相當多的軟硬體資源……輔大在這方面的支持就稍弱。許多公立大學都紛紛成立與婦女或是性別相關的研究室,除此之外她們還能聘請到眾多深具性別意識的老師作為女研社最為有力的支持。例如台大有婦女研究室,性別與空間研究室和女研社可以一起合作,故所收成效也能較大。而相對的私立大學的經費來源有限,這也成為學校拿來搪塞學生的藉口;而具有性別意識的老師也都蓼蓼可數,是否老師也該接受更進一步的性別教育才能正確的教育我們所有學子?

    + +

    人力不足的問題

    + +

    一般來說,相較於其他服務性社團,女研社的規模是小得多,而且有時甚至呈現出人力不足的情形。(少了佔二分之一比例的另一個性別的市場,這樣的情況會是必然?)。但人數的多寡和社團的活動力並非成正比或有直接的關連,求不求;在不在。如何維持一個人的熱情讓她持續地投入比起如何吸引到更多的人參加似乎重要得多。但究竟是女性主義者之名讓女學生望之卻步(被冠以負面的大女人主義)?抑或社團屬性不足以吸引女學生的參與;女研社未來的方向該如何掌控?這都是需要好好思索與討論的。

    + +

    在校內聯結其他異議性社團及幾位有性別意識的老師,一起為校內活動使力;在校外與其他女研社一起合作,以集體的力量(大專女生行動聯盟)發聲,辦活動(如講座,姐妹營,遊行),都是目前有效的解決方法。

    +
    + +
    +

    女學生的主體性在那裡?

    + +

    幾年前,台大女生看A片使得女研社聲名大噪,而女研社的女學生也被誤以為只重視情慾,只在乎性解放,或是只要性高潮,不要性騷擾。但近幾年來,女學運被評為漸走下坡,欲振乏力,只會跟著婦女團體的屁股後頭走,而缺乏自己的主體性。

    + +

    女學運的著力點在那裡?當然還是要從校園出發,從最切身的問題開始:宿舍門禁,校園安全,廁所,球場,這些打了許多年的老問題還是依然存在,或是說這些問題還有很大的發展空間,但我們還是可以從這裡開始,甚至去思考為什麼我們還在∕還得做這些事?

    + +

    輔大目前又開始針對宿舍管理制度進行抗爭,宿舍改革小組,女研社與其他異議性社團抗議男女宿舍的差別待遇,控制女人的行動自由,矛頭更要指向實權凌駕校長的三個教會,要求給予財務透明化並給予關於改革的具體回應。

    + +

    推動學校設置兩性平等教育委員會是我們近期的另外一個目標,盼由此組織的成立及後期的監督,兩性平等教育不再是個空泛的口號,我們不容許性別刻板印象在校園裡被進行複製,我們要求有足夠的女教授作為我們良好的典範,要求良好的教學品質,這樣,輔大也才能真正稱得上一所有競爭力的高等學府。

    +
    + +
    +

    女研社帶給我些什麼?—一個會思考的腦袋

    + +

    每學年的社團招生,我們可以發現對於女研社或是其他異議性社團有興趣的同學是有相當程度的重疊性。追求公平正義,關懷人群,學習另類思考的目的,吸引著有抱負的學生前來。同樣的,來到女研社的女孩學到了用性別的觀點看事物,並由小見大,從自身至整個大環境的關懷,我們都有屬於自己的訴求。例如在高學費政策下,我們討論女孩的受教權是如何成為第一被犧牲的考量;在繳不出學費的情況下,女學生會有什麼更悲慘的遭遇;一個女研社的學生為什麼要反核?破壞環境生態的核電廠一旦發生意外,居於弱勢地位沒錢沒勢的女性權益是如何被損害。女研社的學生就是這樣,試著用女人的觀點,性別的角度作思考一切問題。我們也許想得不多,想得也不夠清楚,但這都只是一個開始;至少我們開始了。

    +
    + +
    +

    女研社存在的必要性

    + +

    女人集結就是奪權的開始。女人常常不自覺的內化了男性價值觀;有時候女人甚至成為迫害女人的幫兇,那都是因為女人被迫處於無知的狀態,例如:女人總以為為了安全就得把自己關起來,忘記了該關的是那些壞男人。女研社提供了女人集結的場域,集結讓女人有力量找回自己本已喪失的權益。

    + +

    女人要發聲

    + +

    從三月學運(野百合學運)到現在,女學生還是在學運中被邊緣化,女人的聲音總是不被聆聽。現況下,我們要有自己的發聲權,我們要有自己的主張,分離主義似乎不可避免:女學運與學運必須分離,女研社的存在也就更有其必要性。

    +
    + +
    +

    檢討

    + +

    女學運十年,我們做了什麼?我們可以做些什麼?

    + +

    由於婦運界前輩及所有女研社學姐們的努力,女性的自覺意識逐漸被開展,使得女研社的成員組成有了明顯的改變。女研社的成員從開始以同志為主到現在以一般異性戀居多,甚至男學生的強烈入社意願,在在說明了社會的確在進步,讓我們對女學運的未來感到樂觀,但女研社的生存方針問題也隨之被考驗著。女大學生的運動對其他女人有示範和帶領風潮的作用,對父權社會可以是一大痛擊,女大學生的社會優勢不容被忽視,更須被善加利用。如何促使校園內更多女生自我意識的提升,進而一起行動與再改革,是需要大家一同努力與再思考的。

    +
    + +
    +

    註:

    + +
      +
    1. 女性影展片名之一。
    2. +
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 2 | + 3 | + 4 | + 5 | + 6 | + 7 | + 8 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0006.html.html b/htdocs/wov/newsletters/wov0006.html.html new file mode 120000 index 0000000..d8e1322 --- /dev/null +++ b/htdocs/wov/newsletters/wov0006.html.html @@ -0,0 +1 @@ +wov0006.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0006.html.xhtml b/htdocs/wov/newsletters/wov0006.html.xhtml new file mode 100644 index 0000000..a21e339 --- /dev/null +++ b/htdocs/wov/newsletters/wov0006.html.xhtml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + +總統選舉,與我何干? + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第006期 1999年8月31日 編輯:小招/依瑪貓
    +網址: http://www.south.nsysu.edu.tw/wov/
    +讀者意見或投稿請寄至:
    +依瑪貓 imacat@mail.eranet.net
    +小招 wandy@ms15.url.com.tw
    +或 女聲專屬信箱 WomansVoice@dreamer.com.tw
    +本期文章:
    +
      +
    1. 總統選舉,與我何干?/小招
    2. +
    3. 無處可逃的 Hello Kitty!/依瑪貓
    4. +
    + +
    + +
    + +
    +

    總統選舉,與我何干?

    +
    小招
    + +
    +

    總統大選已經成為媒體的流水帳了。每天翻開報紙,這些候選人的身邊大小事、八卦、小道消息,必定佔滿報紙的二、三版,大部份則是連頭版都不放過。總統候選人的政見大抵集中在整個國家定位上,一國兩制猶爭執不休。而總括這些候選人的意見,可以看出女人是無足輕重的,無殼蝸牛是無足輕重的,勞工被非法解雇是無足輕重的,豪水成災的災戶是無足輕重的,所有的弱勢都是無足輕重的,因為他們都只談大事、不管小事的。大事和小事標準區分何在?隨後選人高興。

    + +

    會的,我相信這些候選人在日後的選舉公報會列出一卡車的弱勢政見,不過,那必定是很久以後的事情了。可能是在選舉前夕,發表政見的時候了(至於當選後會不會實現呢?大家心知肚明)。

    + +

    沒有女總統候選人,這沒什麼令人驚訝的。會不會提名女性副總統候選人呢?新黨總統候選人說:女人太可愛了,所以不應該讓她們涉足政治領域。我驚訝的是,居然有候選人以這種方式來合理化對女性參政的歧視(雖然這種老套在 19 世紀末、 20 世紀初,拒絕婦女投票權時就已經有人用過),但我也好奇,他如何看待大選時女性所行使的投票權?

    + +

    我相信到了明年總統大選時,各黨派的候選人一定會拿到許多女性的選票(不然,他們靠什麼當選?)。然後,在某些女性主義者現身討論整個國家婦女政策的缺失時,也勢必會有人跳出來說,妳們女人是多麼的缺乏自覺,多麼不自強,多麼的不自立,多麼的不懂捍衛自身的權力云云。所以,女人的權益受到剝削,是自作自受,女人既不善用選票,也沒什麼好說的。

    + +

    可是,這些對女性的責備是合理的嗎?大家會說,女人不投票給女人,但是大部份的女人不是代夫出征,就是代父出征。當選的女性民意代表能掌握多大的職權呢?大部份侷限在象徵傳統社會中私領域的社會福利部門,卻又永遠缺乏完整的授權。此外,女人長期缺乏從政的資源,層層的結構性障礙阻絕了婦女參政之路。總統選舉的高門檻有多少人能通過呢?而這個社會又是如何看待從政的女性呢?同是民意代表出身的情侶,男性身為市長,卻能大剌剌的說,不希望自己的伴侶在外拋頭露面,我很懷疑他如何看待他轄區中的職業婦女?而女人真的不懂得善用自己的選票嗎?有人跟我說女人投票不是用腦,是看候選人的長相,如果是這樣的話,那叫偶像明星來選,勝選的機率不是更大?女人或許會因國族主義的因素,而投票給帶有性別歧視觀點的候選人,這不過是在一堆爛蘋果中挑一個比較不爛的罷了。

    + +

    在現今的環境下,女人仍然面對國族與性別的矛盾。不少女人不爽這些男人的訴求,但卻仍然要去投票,因為身旁的男人會不斷地提醒女人以國事為重,別放棄這神聖的一票。但我懷疑這神聖的一票能否改善婦女處境,就像我也懷疑不管台灣獨立、還是統一,是否真的能夠改善人民生活一樣。明年,我要去投票嗎?我忽然想起維吉尼亞‧吳爾夫說的女人無祖國,在父權社會的選舉機制中,女人投票,不過是為男性政客背書罷了。幾年前何春蕤提出女人投賭爛票。那麼,我多了一個選擇──拒絕投票。

    +
    +
    + +
    + +
    +

    無處可逃的 Hello Kitty!

    +
    依瑪貓
    + +
    +

    這一陣子,最轟動的新聞,除了蔡仁堅的誹聞案外,就是麥當勞的 Hello Kitty! 大轟動了。當然,我們已經排除了連宋扁許敖的排列組合遊戲。

    + +

    很多人很喜歡談這隻沒有嘴的貓,在沒有表情的無辜背後,隱藏著一個龐大的資本主義結構。這個龐大的資本主義結構,透過這隻沒有嘴的貓兒,掌控了每個人,每個人都被騙了,資本家賺得爽歪歪,之類的等等等等等。

    + +

    是這樣嗎?

    + +

    這種談法的背後,隱藏著一個命題,即是:在種種事件真相的背後,有一隻龐大的資本主義幕後黑手,在從事著陰險狡詐的陰謀。那麼,只要把這隻黑手揪出來,就可以解救世人免於 Hello Kitty! 的地獄。只要每個人都意識到 這隻黑手,就是一種反抗與革命的實踐。

    + +

    那麼,這隻黑手是誰?是誠泰銀行?還是麥當勞?是不是只要消滅誠泰銀行,消滅麥當勞,剪掉 Kitty Card ,丟掉新婚 Kitty! ,問題就會解決,人人都不再陷入 Hello Kitty! 陷阱了呢?

    + +

    別傻了。答案當然是否定的。

    +
    + +
    +

    沒錯,這隻沒有嘴、沒有表情的貓,象徵的是一個無憂無慮,空間感和歷史感通通都完全斷絕的世界。彷彿全世界的爭端、紛紛擾擾,都跟它無關。它就是靜靜地看著前方,超越一切時間空間。它不只處身在永恒的幸福之中,它本身就是幸福。

    + +

    這不只是麻醉,這是人們的世俗渴望。當這樣一隻永恒幸福的貓受到瘋狂愛戴時,其實背後所顯示的,是人們對生活環境、對身處的社會的不滿與無力感。當周遭的困境成為無法解決的社會現實的時候,能夠有所寄託的,只有一個能夠無限超脫的幸福象徵。這個幸福象徵是由麥當勞,由誠泰,還是由 7-11 所提供,並不重要。即使沒有 Hello Kitty! ,仍然會有人創造其它的偶像來代替。就像無尾熊。

    + +

    我也喜歡 Hello Kitty! ,我不想諱言這件事。我覺得排隊去買 Hello Kitty! 沒什麼可恥的。我喜歡 Hello Kitty! ,尤其是當我對工作上的現實很無力的時候。當面對著職場的現實,無法躲開的人事鬥爭和算計,我特別喜歡在每天深夜的時候,一個人躲在網路,想一些不著邊際的事。這是一種逃避,我不諱言。但逃避也是一種心理治療。需要被指責的不是我,是這個惡劣的世界。

    +
    + +
    +

    同樣地,問題根源不在誠泰或麥當勞,問題根源在於這個資本主義社會,將每個人都逼到某種無法躲開的絕境。我們處身在一個早熟的社會,當我們還沒有體認到自我的力量,就要被社會現實壓垮,就要依照社會現實規則玩遊戲。超高的學費,與強大的廣告宣傳,逼使(或引誘)大多數人從國中高中就要去打工補貼生活零用所需,從國中高中就開始面對社會現實──在青少年還沒培養出自己的力量感與社會意識之前。

    + +

    試想,一個從小在麥當勞打工到大賺學費的孩子,會認為到每小時 70 元的工資太低嗎?不會。當然不會。她們會告訴妳:這叫做社會現實。這個社會就是這樣。她們會感激妳為她們爭取勞基法最低薪資嗎?不會。她們會說:妳們太激烈了。

    + +

    我們失去反抗的力量,只能默默接受社會現實。所以我們要去尋找精神寄託。 Hello Kitty! 的背後,是社會的集體不滿,無力宣洩。那隻沒有嘴、沒有表情,永遠幸福無瑕的貓,是一種社會的集體治療。

    + +

    集體治療的背後,則是一個讓人無處可逃的資本主義社會。

    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 3 | + 4 | + 5 | + 6 | + 7 | + 8 | + 9 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0007.html.html b/htdocs/wov/newsletters/wov0007.html.html new file mode 120000 index 0000000..c8329c8 --- /dev/null +++ b/htdocs/wov/newsletters/wov0007.html.html @@ -0,0 +1 @@ +wov0007.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0007.html.xhtml b/htdocs/wov/newsletters/wov0007.html.xhtml new file mode 100644 index 0000000..fe26df0 --- /dev/null +++ b/htdocs/wov/newsletters/wov0007.html.xhtml @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + +女性主義與男性 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第007期 1999年9月16日 編輯:小招/依瑪貓
    +網址: http://www.south.nsysu.edu.tw/wov/
    +讀者意見或投稿請寄至:
    +依瑪貓 imacat@mail.eranet.net
    +小招 wandy@ms15.url.com.tw
    +或 女聲專屬信箱 WomansVoice@dreamer.com.tw
    +本期文章:
    +
      +
    1. 「必要之惡」誰之惡?/小招
    2. +
    3. 女性主義與男性/依瑪貓
    4. +
    + +
    + +
    + +
    +

    「必要之惡」誰之惡?

    +
    小招
    + +
    +

    這兩個星期,大家可能把目光都放在國代延任案上。延任案過了,除了蘇南成被轟下台外,沒有什麼改變。話都隨便延任國代講,必要之惡?!笑死人了。可怕的是,講久了,還真的有人信這一套。想想,還好當年想當皇帝的是袁世凱,賄選的是曹琨,要是換成今天這些延任國代,老百姓可能不是被賣而已,還得幫他們數鈔票吧。

    + +

    國大延任案一出,又該女人倒楣了。聯合報社論將憲法、民意比擬為遭強暴後淪落風塵的女人;蘇南成要下台,還自比楊貴妃訴說自己的委屈與可憐。莫名其妙!!女人權益遭到侵害時,也沒見這些人當一回事,出來提些建設性的觀點,怎麼不爽、委屈就硬捉女人出來跑龍套,羞辱女人以洩憤呢?還記得幾年前的司法改革嗎?沒錯!只要對修改結果不滿意,不管是媒體、政客、官僚、執政黨、在野黨,都可以將司法化身為皇后,加以輪暴。記得某個女性主義者曾寫著這是一個仇視女人的社會,它會自行衍生出各種壓迫女人的形式,初看這個言論似乎過激了些,然而,她確實揭露了父權暴力的本質。

    + +

    這幾天報紙的政治版很是熱鬧。不說惡名昭彰的國代延任案,看著李登輝、江澤民、柯林頓、陳水扁、宋楚瑜、連戰……等人的口水大戰,連蕭登標都能以受難者的身份出現在電視的訪談上,這麼明目張膽的通緝犯,大概也是台灣的特色之一了。就在口水亂噴之際,有個女人得了乳癌,在醫師丈夫罔顧醫療倫理的蓄意欺瞞延誤醫治下,已時日無多;有個女人死於同居人之手;還有個女人慘遭丈夫殺害,而除了女方家屬群情激憤外,沒看到哪份報紙違反媒體中立的立場,跳出來譴責這些沒天良的男性,但是前陣子駱立菖案發生時,大家倒是挺勤快得跳出來譴責駱明慧未能克盡母職,對駱明慧所遭受的婚姻暴力,大家可是裝成沒看到。此外,這些日子以來,已經有幾個無名(沒啥名氣)的女性死於非命,哪位總統候選人針對這些案子發表意見,也許他們和蔣仲苓有著同樣的想法──那個地方不死(女)人?

    + +

    大家還記得上期女聲總統選舉,與我何干!!中,在整個總統大選中,除了陳文茜、連方瑀等兩三個女人的聲音外(她們談的都不是女人的權益),女人幾乎是缺席的。有人提醒我,我話說得太快了,呂秀蓮有可能搭配陳水扁選副總統哪!那麼,身為女性,我應該以此為榮嗎?一半的女性人口,只出一個副總統的候選人,都還沒正式提出呢,也不知道是不是虛晃一招,加深女性選民的印象,民進黨內已經有人跳出來反彈了。反彈的理由是什麼?缺乏國際觀啦、拉不到客家票啦、黨內派系不滿啦……,總之,他們就是覺得呂秀蓮不夠力就對了。說實在的,衝著呂秀蓮,我倒是可能冒著讓陳水扁當總統的危險去投下神聖的一票,雖然我對屆時呂秀蓮所能掌控的權限多少仍感到不安。

    + +

    國大延任案好像已經平息下來了。不是要觀察嗎?李登輝出來為延任案消毒,延任國代則面無愧色地粉飾太平,硬要把黑的說成白的,不少人已經開始接受所謂必要之惡的說法了。不知道到了明年總統選舉時大家是不是還會記得這個體制之恥。可能不會。我並不認為人民是無知的,但是在政黨機器的強勢運作下,大家好像已經能夠接受了。就像我們也都知道這些國代說不支領任何費用,只是說說而已。反正他們可以把責任推給弱勢的助理啊。為了助理的薪水,所以他們還是會領錢,但他們一定會再三強調:是為了助理喔!!

    + +

    我們試著用心觀察這個父權的體制是否有適合女人生存的空間,但若是得出一個不好的結論,我們有什麼權力改變現況呢?遵循著現行體制的政治規則來玩,展現民意所趨嗎?報章媒體連罵了幾天,民意代表們甩都不甩,目前我們似乎只有一種選擇與答案──接受必要之惡,為了國家,人民應該以破壞民主的大局為重;因為不爽,女人應該以男人發洩情緒為重;為了國代的口袋,助理應該以老闆需求為重;為了整個強權的優質生活,弱勢應該以自我犧牲為重。不過女性面對的可不只是國大延任案,而是整個父權體制長期孳生的惡意,國代延任案衍生的語言暴力不過只是霰彈槍的一顆流彈而已。

    +
    +
    + +
    + +
    +

    女性主義與男性

    +
    依瑪貓
    + +
    +

    男人,該如何參與女性主義?

    + +

    六月份的臺灣,因為 Sandra Harding 的來訪,曾經引起一陣熱烈的討論:男性該如何參與女性主義?當月份的當代,更以專題的方式,大篇幅討論這個問題。

    + +

    從事後的紀錄中可以看出, Sandra Harding 對此抱相當肯定的態度。國內的女性主義者,雖然大體上仍支持男性參與女性主義的可能性,卻有相當程度的保留。

    + +

    對這個問題有興趣,是因為在這兩個月內,女聲網站上的留言簿前後有兩位男性引起熱烈的討論。這兩位男性面對女性主義,分別處於不同的位置。同時,我自己社團的暑期女性主義讀書小組,也因為有兩位學弟的參與,使讀書小組進行過程產生相當的質變,迫使我認真看待這個問題。

    + +

    那麼,男性該怎麼參與女性主義?

    +
    + +
    +

    當然,男性參與女性主義的可能性,基本上是毋庸置疑的。從婦運史上不少傑出男性的積極奔走,到現代臺灣社會中畢恆達等人的積極努力,都是正面的證明。從他們身上,我們清楚看到女性主義的基進立場是可以和性別處境分開的。

    + +

    然而,我們也在許多方面感到深深地受挫。讀書小組中,即使當事人不斷自我警惕,即使帶組員不斷提醒,仍然難以避免男性參與者佔據大多數的討論時間。我們常常收到訊息,以進步男性的姿態,建議我們該做什麼,不該做什麼,該把女聲電子報收起來,該恢復我溫柔婉約的個性等等。有些男性,即使知道他的問題,仍很難一時改正,難避免不自覺重蹈覆輒;有些男性,即使我連髒話都用上了,都感覺不到我們的憤怒。當然,也有男性小心翼翼想討女人開心,讓人哭笑不得。

    + +

    我不知道。就像我還在嚐試帶一個會有男性參與的女性主義讀書小組,但是還沒摸索到完美的方式。我努力尋找讓男性也能參與女性主義,卻不致讓女性受挫的方式,但仍然找不到。

    +
    + +
    +

    可是,至少有一些線索可尋。很多男性喜歡在女性主義團體中談自己的男性處境。這是很奈人尋味的。很多男性,都對解放自己的刻板性別角色,有很強烈的需求。這很好,可是仍有問題。問題在於:在女人面前談自己的男性處境,是否能積極改造男性處境?若只有消極的支持、傾聽的效果,那女性是不是又落入照顧者、支持者、傾聽者的角色?

    + +

    改造男人的性別角色,只能從男性自身做起。男性想解放自己的性別角色,積極面而言,應該從組織男性自覺團體開始,去改變其它人的性別觀念,而不是從講給女人聽開始。當然,我們仍常常會面臨資源不足的問題。並不是隨時有足夠有興趣的男性,可以組成男性自覺團體。

    +
    + +
    +

    若男性的興趣不在解放自己的性別處境,而是在參與女性主義運動呢?這不是不可能,但絕不是男人來告訴女人,女性主義運動應該怎麼做、怎麼走、怎麼調整腳步。很多男人一入門女性主義,就努力告訴女人,應該如何和男人對話,應該如何對男性友善,應該如何保持溫柔婉約的天性,應該如何爭取男性認同等等。這,反了吧?如果女性主義努力辛苦的成果,只是為了要跟男人對話,那幹嘛要叫女性主義

    + +

    女性主義從發展女性的力量開始,從培養女性的意識開始。妳可以鼓勵身邊的女性發聲,鼓勵她們自覺,鼓勵她們揮灑自己的力量。更進一步,可以協助女性爭取更友善的空間,更友善的環境,更平等的社會制度。這是實質的改造工程,也比文字的辯論有意義得多。

    +
    + +
    +

    然而,坦白說,若男性參與女性主義,只是為了訴說男性在女性主義中多麼被壓迫,多麼沒有空間,男性如何地背負生理的原罪,我想是免了。這不叫參與女性主義,這叫自我中心,這叫反挫。

    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 4 | + 5 | + 6 | + 7 | + 8 | + 9 | + 10 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0008.html.html b/htdocs/wov/newsletters/wov0008.html.html new file mode 120000 index 0000000..a754a08 --- /dev/null +++ b/htdocs/wov/newsletters/wov0008.html.html @@ -0,0 +1 @@ +wov0008.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0008.html.xhtml b/htdocs/wov/newsletters/wov0008.html.xhtml new file mode 100644 index 0000000..b185fd1 --- /dev/null +++ b/htdocs/wov/newsletters/wov0008.html.xhtml @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + +本期休刊 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第008期 1999年9月26日 編輯:小招/依瑪貓
    +網址: http://www.south.nsysu.edu.tw/wov/
    +讀者意見或投稿請寄至:
    +依瑪貓 imacat@mail.eranet.net
    +小招 wandy@ms15.url.com.tw
    +或 女聲專屬信箱 WomansVoice@dreamer.com.tw
    +本期文章:
    +
      +
    1. 本期休刊/編輯室
    2. +
    + +
    + +
    + +
    +

    本期休刊

    +
    編輯室
    + +
    +

    《女聲》電子報第八期為悼念臺灣 921 集集大地震所造成的慘重死傷,休刊一期,自第九期起復刊。《女聲》電子報謹對本次震災罹難者致上最沉痛的哀悼,並對所有在這幾天不眠不休投入救災工作的國內外民間與政府團體致上最崇高的敬意。若有任何救災團體需要人力、物力支援,歡迎不吝前往《女聲》網站留言板宣傳。

    +
    + +
    +

    截至目前為止,震災造成傷亡數字如下:

    + + + + + + + + + +
    死亡2060 人
    失蹤18 人
    受困171 人
    受傷8672 人
    + +

    根據目前我們側面得知的狀況,已有大量的救援物資進入災區,但受困於許多地區交通與通訊仍告中斷,物資難以適當分配,致使某些地區救援物資過多,而某些地區仍無任何救援物資進入。在此除呼籲大家繼續捐輸外,更希望救援物資能送到更深入更需要的地方。

    + +

    救災人力方面,初期救災志工已陸續投入災區中。但估計救災工作需持續到十月後,中後期志工人數目前仍嚴重不足,希望有心投入救災工作的朋友,能持續投入中後期救災工作。

    +
    + +
    +

    我們在此代為宣傳人本基金會民間重建團的徵召訊息。人本基金會號召民間重建團投入災後復建工作。目前仍有梯次如下:

    + + + + + + + + + + + + +
    梯次發出時間梯次日期
    9/29 中午9/30-10/2
    10/2 中午10/3-10/5
    10/5 中午10/6-10/8
    10/8 中午10/9-10/11
    + +

    義工條件如下:

    + +
      +
    1. 身體狀況佳:由於當地衛生狀況並不佳,因此易得腸胃炎、易嘔吐、易昏倒者,不宜參加。
    2. + +
    3. 心理狀況佳:當地實際工作非常可能會接觸到血、屍體、屍臭,而且會有心理壓力。並且有許多的處理事項。
    4. + +
    5. 一定要能夠待三天以上:工作才能持續,也才不會增加交通困擾。不接受現場臨時加入,無法組織。
    6. + +
    7. 不能洗澡:當地沒有水,不能洗澡。
    8. + +
    9. 未滿 18 歲者:一定要取得家長的同意。
    10. + +
    11. 願意接受當地的調配,配合進行各項工作。
    12. +
    + +

    符合以上條件者,請自行與人本基金會聯絡。北部請聯絡人本臺北總會: (02)2367-0151 、 (02)2364-2955 ,南部請聯絡高雄人本分會: (07)216-6510 ,或上人本網站查詢: http://hef.yam.org.tw/

    + +

    救援物資與捐款,請聯絡慈濟功德會救災中心: (038)26-6779 ,或捐給慈濟捐款帳戶: 0688779-1 請註明 921 震災捐款,或可到蕃薯藤網路信用卡捐款: http://sale.yam.com.tw/whipround/

    +
    + +
    +

    其它相關震災資訊:

    + + + + + + + + + + + +
    蕃薯藤傷亡名單查詢http://events.yam.com.tw/921/
    慈濟震災網頁http://www.tzuchi.org.tw/news/921report/firstnews.htm
    中時電子報http://www.chinatimes.com.tw/
    民視即時新聞http://www.ftv.com.tw/
    華視全球資訊網http://www.cts.com.tw/
    聯合新聞網http://udnnews.com/
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 5 | + 6 | + 7 | + 8 | + 9 | + 10 | + 11 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0009.html.html b/htdocs/wov/newsletters/wov0009.html.html new file mode 120000 index 0000000..40abfee --- /dev/null +++ b/htdocs/wov/newsletters/wov0009.html.html @@ -0,0 +1 @@ +wov0009.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0009.html.xhtml b/htdocs/wov/newsletters/wov0009.html.xhtml new file mode 100644 index 0000000..f040ff7 --- /dev/null +++ b/htdocs/wov/newsletters/wov0009.html.xhtml @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + +女性抽煙政治學 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第009期 1999年10月26日 編輯:小招/依瑪貓
    +網址: http://www.south.nsysu.edu.tw/wov/
    +讀者意見或投稿請寄至:
    +依瑪貓 imacat@mail.eranet.net
    +小招 wandy@ms15.url.com.tw
    +或 女聲專屬信箱 WomansVoice@dreamer.com.tw
    +本期文章:
    +
      +
    1. 女性抽煙政治學/小招
    2. +
    3. 地震的權力遊戲/依瑪貓
    4. +
    + +
    + +
    + +
    +

    女性抽煙政治學

    +
    小招
    + +
    +

    我喜歡抽煙,但很多人看到女人抽煙總是有一些奇怪的心態。

    + +

    有人看到女研社的社員抽煙,認為女研社的人抽煙只是一種對時尚的盲目追求;看到單身的女人抽煙,就認為這些女人在色誘異性;如果這個抽煙的女人已婚,那麼不管她是否懷著小孩,都能跟這些存在或不存在的小孩身心健康、養育良善與否扯在一起。

    + +

    有一天,我突然發覺男人不只管女人抽不抽煙,他們居然連女人抽煙姿勢是否合乎他們的標準都要加以指正,女人抽煙只能規規矩矩,直來直往,從嘴巴吸進去的,就不能從鼻孔呼出,因為不雅;即使從嘴巴將煙吐出,也不能因避免將煙吐到對方臉上而仰臉吐煙,因為會強化女性抽煙不正經的刻板印象???!!!

    + +

    女人抽煙不會只是盲從。抽煙不只是效仿男人的作為,不只是向男人示魅(媚)的手段,女人抽煙是向傳統父權規範的宣戰。女人抽煙之所以引起他人側目,是因為跨越性別刻板印象中的女性規範。傳統觀念中的好女人、賢妻良母、純情禁慾的女性都是不抽煙的,但是不管這些女人品行多麼高尚,一管短煙,就能將她的形象全面扭轉。

    + +

    誰能抽煙?,就是一種父權價值觀的展現, 520 酷煙胎死腹中,就是一個最好的例子。因為 520 酷煙設定的是青少年與女性消費群,所以引起禁煙人士的反彈,然而這些禁煙人士事實上也算是保守父權的代言人,如果 520 酷煙一開始的消費群定位是一般成年男性,或許不會引起這些禁煙團體如此大的反彈。

    + +

    沒錯,抽煙有害身體。但是身體是我的,要怎麼對待我的身體,由我自己決定,不是嗎?政府及某些高舉捍衛人民健康大旗的基金會,要求禁煙、戒酒,現在連既不噴二手煙,吃後也不會神智不清駕車肇事的檳榔都要被禁,就像傅科所說的,人民的身體逐步陷入國家監視與掌控之中。西方第二波婦運的著名標語個人即政治,爭取的不只是性自主權墮胎權而已,而是更進一步擺脫國家假科學權威之名對人民身體所進行的宰制。

    + +

    對許多女人而言,抽煙是一種自我解放的實踐。剛開始接觸女性主義論述時,女性主義者說的頭頭是道,自己卻常常陷入跟著書上說一套,實際上做的確是另一套的困境之中。我的重點並不在討論某些女性主義者所具有的偽善性格,我要說的是,女性主義者不是天生的,也同樣必須歷經從父權的包袱中掙脫而出的歷練。很多女性主義者要她的信徒別在意別人對自己身體的眼光,卻又一天到晚告訴這些女人男人用什麼眼光看妳的身體,試問女人要怎樣才能跳脫出男性凝視的包袱呢?想要追求身體解放的女人要怎麼跨越起步的性別柵欄?給女人一個自我解放及挑戰的起點吧。這些起點,可以是抽煙、喝酒、吃檳榔、不穿內衣,這不是向男人看齊,而是挑戰男人的特權。

    +
    +
    + +
    + +
    +

    地震的權力遊戲

    +
    依瑪貓
    + +
    +

    地震的傷口,在某些地方已經漸漸平復,而在某些地方,卻正一步一步蘊釀、擴大。

    + +

    臺灣是一個令我訝異的地方。

    + +

    這或許是我的偏見。我不是活在一個災難頻頻的地方,因此,我不習慣看到利用災難謀利的人。也許是因為我生活在臺北。若我生活在風災頻頻的花蓮,或處於戰爭中的巴基斯坦,也許我會習以為常。也許對生長在那兒的人們來說,人們藉此發國難財,政客藉此奪權,早已習以為常了。

    + +

    然而,我仍然無法習慣這些景像。我也不該去習慣這些景像。

    +
    + +
    +

    當地震後第二晚,在遠處目堵傾斜的臺北東興大樓時,心中的震憾是難以形容的。那時,我才真正感覺到我處在災區。路邊的二手家電行拿出六七臺電視供圍觀的路人看,我也湊過去,看到的景像和每年颱風過境時花東地區的畫面差不多。我感到羞愧。每年看著同樣的畫面,對著一堆死傷數字,我早已麻痺無感了,像早上邊吃早餐邊看報紙一樣。這時才發現,我是多麼中產,多麼優勢。

    + +

    我想想我能做什麼:我應該打個電話給朋友報平安,想辦法上網連絡處身災區的網友。這時候,電視閃過一個簡單的畫面,上面有幾行字:

    + +

    勁報和你一起共渡災難。即日起每訂閱一份勁報,我們將捐出……

    + +

    厭‧惡‧極‧了。這是記憶中第一個利用地震謀利的,周天瑞的勁報,就在地震隔天。誰不知道,報紙的收入來源不在報費,而在廣告費?廣告費則是靠派報量換來的。利用救災賣報紙,損失的是微不足道的報費,增加的是無價的派報量和廣告業務。

    + +

    這是第一個,但絕不會是最後一個。勁報不做,其它企業、團體、政客們也會馬上去做。接著幾天,各式各樣的形象廣告陸續登場。花大錢在黃金時段買廣告妳買一份我們捐出xx元,以義賣為名行銷。某些批判比較保留,打形象廣告是人之常情,要質疑的是花的廣告費比捐款還多。我的態度更嚴苛:有錢為什麼不乾脆捐出來?妳買一份我們捐出xx元,打著人道形象促銷,邊賑災邊賺得飽飽的,這是哪門子人之常情?

    + +

    後來,賑災行銷越來越普遍。從大企業到小路邊攤,臺灣人學得很快。頂好超市海報寫著災區來的蔬菜,買菜幫助災區農民重建家園,家裏附近的埔里檳榔攤寫著埔里來的檳榔,吃檳榔幫助埔里重建的招牌……

    + +

    昏倒。

    + +

    很明顯,這種賑災,針對的是我們這種同情心過剩的人。辛辛苦苦領薪水,一有災難,便義憤填膺地讓大企業削得飽飽的。

    + +

    這不是黑店,是什麼?緊急命令重罰烘抬物價的黑店,那這種黑店呢?

    +
    + +
    +

    網路上流傳,某大超市臺中賣場災後一個帳棚賣到 3000 元,被揭發出來後,幾天後就設了捐款帳號,又在賣場到處貼海報我們為平抑物價盡一份心力,轉瞬間,從黑店漂白成了白店,還是良心商家。礙於沒有下臺中實際看過該超市的 3000 元帳棚,無法指出是誰。

    + +

    是不是似曾相識呢?沒錯,我們的連戰副總統,開始幾天去災區時,災區民眾想陳情,都被隨扈粗暴地攔了下來;媒體報導出來後,沒幾天就安排演出一場連戰與災區村長老友會面落淚秀,黑的就漂成白的了。李登輝座機風壓壓死小女孩,李登輝還說她不該在旁邊旁觀。媒體報導後,李登輝竟說:媒體對政府報導太負面,到現在一句道歉都沒有,媒體也完全忘了這回事。黑的漂成了白的,那個小女孩,比兩千多人的統計數字更不如。

    + +

    慈濟在災區廣受肯定,民眾對民間團體比對政府有信心。李登輝一句話,媒體馬上為政府漂白,不到兩星期,政府的信心指數就拉上來了。又一個黑的漂成白的。

    +
    + +
    +

    地震很好用。全民同心,共渡難關;不共渡難關的都該死。地震成了另一種政治正確。某電子通訊流傳一篇名為愛國者遊戲的文章,反諷著某主播報新聞嘴角居然有微笑,這時候還只顧自己好看,真是可恥。於我心有戚戚焉。女聲也面臨了一樣的事件:這時候還在說這些有的沒有的,我詛咒妳們通通下地獄!

    + +

    是的,地震很好用。地震可以排除萬難,超越一切,最後滿足的,不是需要重建的災區,而是個人或明或暗的私慾。發電廠可以排除環保抗爭直接動工,即使新建的發電廠和災變毫無關係,也不可能在三天內蓋好舒解全臺供電。原住民可以立即遷村,不論該地地質、建築強度評估結果是否真的不堪居住。在災難的大旗下,什麼都該被排除,不論妳是環保,是原住民文化,是女人,是各式各樣人們的權益。

    +
    + +
    +

    地震過後,一場場私慾的角逐,正在臺灣各個角落漫沿著。

    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 6 | + 7 | + 8 | + 9 | + 10 | + 11 | + 12 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0010.html.html b/htdocs/wov/newsletters/wov0010.html.html new file mode 120000 index 0000000..5384c2a --- /dev/null +++ b/htdocs/wov/newsletters/wov0010.html.html @@ -0,0 +1 @@ +wov0010.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0010.html.xhtml b/htdocs/wov/newsletters/wov0010.html.xhtml new file mode 100644 index 0000000..b11f887 --- /dev/null +++ b/htdocs/wov/newsletters/wov0010.html.xhtml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + +媒體的男性凝視--從胖妹詐財案談起 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第010期 1999年11月16日 編輯:小招/依瑪貓
    +網址: http://www.south.nsysu.edu.tw/wov/
    +讀者意見或投稿請寄至:
    +依瑪貓 imacat@mail.eranet.net
    +小招 wandy@ms15.url.com.tw
    +或 女聲專屬信箱 WomansVoice@dreamer.com.tw
    +本期文章:
    +
      +
    1. 性自主與婚姻的邊緣戰鬥--開拓網路情慾版圖/小招
    2. +
    3. 媒體的男性凝視--從胖妹詐財案談起/依瑪貓
    4. +
    + +
    + +
    + +
    +

    性自主與婚姻的邊緣戰鬥--開拓網路情慾版圖

    +
    小招
    + +
    +

    網路一夜情、網路色情交易、網路愛情……,在網際網路日益普遍化的後現代,情慾生產工具改變,情慾生產方式亦隨之改變,透過科技的發展,人們之間的情慾互動不再侷限於具體的空間領域,這早就不是什麼新聞了。只是看到媒體總是以一副大驚小怪,聳人聽聞的姿態播報,真懷疑台灣的媒體記者們,是跟我們生活在同一個時代的人。

    + +

    也許是對匿名的不安,對科技的恐懼,跟不上社會變動,加上長期壓抑引發的恐懼感,仍堅持活在過去的媒體記者與衛道人士們試著將現實的道德規範套用在網路的虛擬空間。他們認為:網路色情有害青少年、兒童身心健康,應加以圍堵、防治,或是訴諸檢查制度;網路一夜情背負行為不檢、放蕩、性交易、性病等污名,是不安全的性;網路愛情是不安定的性,對未謀面的人產生愛情,是一種盲目的激情。其實,這些都是欲加之罪,何患無詞,簡單的說,沒有真實身份認證,缺乏婚姻 +承諾的愛情就是危害善良社會風俗

    + +

    由於目前國內女性教育程度已普遍提高,女學生畢業之初又多投入就業市場中,經濟獨立自主的未婚OL形象應運而生。然而就業市場中男女同工不同酬、男高於女的升遷機會、未婚條款……等性別歧視的勞動待遇,致使女性雖有經濟自主權,仍只能以合法的異性戀婚姻作為人生的主要生涯規畫。廿世紀初,女人獲得婚姻自主權後,手持著愛情神話的煙火尋找依託,在邁入廿一世紀之際,女人依然渴望愛情神話的引領,進入婚姻的枷鎖之中。愛不愛結不結婚因此巧妙地連結在一起。

    + +

    女人一出生,整個父權社會中持續加以最強的心靈制約,結婚幾乎成為女人的思維基礎。不論在現實社會中,亦或是虛擬的網路空間中,未來的戀愛對象不論是否已經出現,都深深地困擾的女性,從對方的身高、體重、星座、血型、彼此的年齡差距、收入、家庭都一一徵信,因為這可能是未來的結婚對象重要資訊。當然,我不否認男人也同樣受婚姻意識型態的制約,不過當女人準備以一生的幸福來談這場戀愛時,男人隨時打算以一時糊塗逢場作戲的藉口逃遁;或者大言不慚地宣稱因性而愛來合理化自己的片面貞操觀。

    + +

    是的,為了一生,女人在這些徵信資料中患得患失,為了愛夢一生、為了明天我要嫁給你啦,女人得準備一些籌碼,所以女人因愛而性與婚姻的關係也就不言可諭。女人真的爭取到性自主權了嗎?性,對女人來說,也不過在愛情婚姻夾縫中的苟延殘喘的附加物而已。至於在作愛的過程中,女人是否滿足,常常可能只是性伴侶的單方面認定。

    + +

    難道,在這樣的惡性循環的社會結構之中,女人的性自主權終究無法擺脫愛情與婚姻的聯手出擊?

    + +

    記得幾年前何春蕤的豪爽女人告訴女人如何爭取自己的性解放,讓自己豪爽(好爽),但不少女人在實踐的過程中卻得面對不少技術性的困難。例如性伴侶難尋的問題,畢竟電話交友可能太陌生,給對方電話又覺得不太安全,從中、小學同學錄中找,似乎又太明目張膽。這些技術性的困難,或許在開拓一個屬於自己的網路情慾版圖的過程中,迎刃而解;畢竟網路上縱流不息的對象與媒介不僅提供女人多元的情慾發展,網路虛擬空間的特性也可以讓女人暫時擺脫現實中步步驚魂的空間恐懼,最起碼,無須害怕針孔攝影機、徵信社,或者在進旅館的時候碰見熟人……。最重要的是,衛道人士所恐懼的網路匿名性,正是女人適時擺脫賺賠邏輯的好所在。

    +
    +
    + +
    + +
    +

    媒體的男性凝視--從胖妹詐財案談起

    +
    依瑪貓
    + +
    +

    10 月 26 日晚上,電視新聞以頭條、數分鐘的專題報導了一件詐財案:一個胖妹女高職生,在網路上散發模特兒的照片,謊報是自己的照片,以欺騙網友上勾,並以買電腦、旅遊為由,向被害人借取大筆金錢,借到了以後就消失無蹤。被害人數高達五人,都是受高等教育的學生。該胖妹目前就讀於某高職,平時成績優秀,發生這種事,師長都說難以置信,並懇求社會大眾能夠原諒她的一時糊塗,再給她一次機會。

    +
    + +
    +

    媒體用頭條、極長的秒數報導這則新聞。畫面上是瀏覽器上的一張張女模特兒照片,穿插被害人寫的情書,強調被害人感情如何被欺騙云云。結果出現一張臉部被馬賽克的胖妹照片,旁白則說,網路上談感情多麼容易被騙,跟現實有多大的落差等等。最後,還到新光三越廣場採訪所謂網路族(男)對網路愛情的看法。

    + +

    在整件新聞中,女人完全處在被凝視的位置。女人完全被對象化他者化了。

    + +

    在現實網路空間中,常常聽到很多女人抱怨,網友在名片檔寫得多帥,什麼保證妳滿意等等,結果一見面竟然是隻大恐龍,醜不拉磯,還洋洋得意。很多女人已經得到一個經驗,把自己寫得越帥,越不怎麼樣。

    + +

    結果,新聞卻片面變成男性代言人,以男性眼光看網路、看世界。不斷強調網友把自己寫得貌美如花,彷彿被欲求的對象只有女人。真正觀視的主體--男性被抽離開來了。沒有人去追究那幾個高等知識份子是不是恐龍,是不是帥哥,好不好看。鏡頭完全沒有照到那幾個男生。就連街頭網友訪問,也是清一色訪問男性的意見。

    + +

    鏡頭本身,就是徹頭徹尾男性本位的,代表男性的欲望,和男性的利益。不過諷刺的是,報導的記者,卻是個女記者。

    +
    + +
    +

    我曾經和網友討論過這件事。很多人覺得沒什麼。有個朋友說,基本上,會想用金錢援助,本身已經有把感情當交易的念頭了,自己想法已經不正當了,被騙了活該。有人覺得,這種錢用得心安理得,反正對方自己心態有問題。

    + +

    然而,沒有人去追究這些用錢養女人的男人心態。這正是一種感情交易:我對妳付出這麼多,妳也必需給我對等的期待(美貌)。所以才叫詐欺嘛!沒有交易何來的詐欺呢?高職女生並沒有脅迫男人簽下什麼假合同,但因為對方不符合自己的期待,所以交易就不公平了,就形成了詐欺。媒體只苛責女方沒有給付對等的酬勞,卻完全忽視男人心中交易的準繩。

    + +

    至於男人心中交易的那個準繩是什麼?就是女方的外貌。外貌美麗,交易就公平;否則就不公平,就是詐欺。所以醜女不該出現在網路上,因為會形成(對男人的)詐欺罪。高職女生詐欺在哪裏?在於她長得不好看,沒有提供一個公平的交易。男人的目光,主導了女人自我價值的判斷標準。

    +
    + +
    +

    關於此事件,可以討論的還有很多。南方的陳豐偉也討論過,傳統媒體對網路的污名化問題,以及肥胖歧視的問題。這裏對此不擬贅述。然而,我們在這個事件中,看到的是惡質的媒體,不加思索地順著八卦邏輯推演,只重視新聞性,完全複製了結構性的性別、階級權力關係。女記者比街頭被訪問到的那些男生還要激動、還要有正義感。(那些小男生遠比女記者溫和、寬容得多。)不禁讓人懷疑,媒體,到底有沒有性別呢?

    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 7 | + 8 | + 9 | + 10 | + 11 | + 12 | + 13 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0011.html.html b/htdocs/wov/newsletters/wov0011.html.html new file mode 120000 index 0000000..4752d4e --- /dev/null +++ b/htdocs/wov/newsletters/wov0011.html.html @@ -0,0 +1 @@ +wov0011.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0011.html.xhtml b/htdocs/wov/newsletters/wov0011.html.xhtml new file mode 100644 index 0000000..db13dcb --- /dev/null +++ b/htdocs/wov/newsletters/wov0011.html.xhtml @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + +「全民公敵」台灣版 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第011期 2000年3月13日 編輯:小招/依瑪貓
    +網址: http://wov.sts.com.tw/
    +讀者意見或投稿請寄至:
    +依瑪貓 imacat@mail.eranet.net
    +小招 wandy@ms15.url.com.tw
    +或 女聲專屬信箱 WomansVoice@dreamer.com.tw
    +本期文章:
    +
      +
    1. 女聲復刊通知/編輯室
    2. +
    3. 「全民公敵」台灣版/小招
    4. +
    5. 選舉,政治與價值觀的遊戲/依瑪貓
    6. +
    + +
    + +
    + +
    +

    女聲復刊通知

    +
    編輯室
    + +
    +

    經過三個多月的停擺,《女聲》終於復刊了。想起那段完全無法上自己網站的日子,每天懷著希望連線,再滿懷失望地斷線,剛開始完全不知道為什麼網站會一夕消失。雖然一再連絡南方,希望能解決《女聲》網站莫名其妙掛掉的情況,卻音訊杳然。這段期間《女聲》停止出刊,對此,《女聲》編輯群深感抱歉。目前《女聲》網站已由出問題的南方主機遷移至另一獨立的虛擬主機上,救回了所有的訂戶資料,並恢復了自動訂閱程式與留言板等所有程式的運作。

    + +

    同時,我們非常感謝 W3 新樂園在《女聲》落難時,伸出援手義助一個網路空間,作為《女聲》備站之用。

    + +
      +
    • 女聲新站網址: http://wov.sts.com.tw/
    • +
    • 女聲備站網址: http://r703a.chem.nthu.edu.tw/~wov/
    • +
    +
    + +
    +

    在這三個月間,發生了很多事。眾所囑目的千禧年過了,人類仍然沒有毀滅(當然啦,若為了資本家的商業效應而滅亡,人命也實在太不值了),平安邁向下一個世紀。世紀最大的鬧劇--跨世紀總統選舉也終於接近了尾聲。《女聲》訂戶也即將突破三千人次(這是很值得記念的,畢竟,在南方電子報大規模與大型網站合作前夕,訂戶也不過兩千多人。)

    + +

    這是一個嶄新的開始。我們很希望能夠做一個非常非常特別的專刊,但不知道我們寫出來的東西,是不是真的那麼特別。

    +
    +
    + +
    + +
    +

    「全民公敵」台灣版

    +
    小招
    + +
    +

    網路實在是一個粉便利的傳播空間及聯繫網絡,但同樣的,網路空間的耗時性也是不容小覷的。這麼說吧,我們把網路便利性上省下來的時間消耗在用網路的空間上,就像汽車縮短我們的空間距離,節省下來的時間則用來塞車。我們不斷地加強網路聯繫,藉此生產更多的知識時,我們並沒有同樣生產更多的閱讀時間,所以呢?網路的確是一個快速傳輸的過程,在傳輸的過程中,我們的時間也跟著消逝了。

    + +

    在一個速度發展的想像過程中,所謂的迅速是遙不可及的。為了享受工具的速度感,我們早就習慣等待。等待什麼呢?速度的速度。就像總統選舉,其實我們早就在期待它的重力加速度,我們在小學生式的謾罵、互揭瘡疤中,感受到醜陋的快感。大家在生活中的不滿,就藉由這些總統候選人小學生幫註 1.的叫陣宣洩而出。

    + +

    我們對安定、快樂的想像,就如同我們對速度的想像。選民不斷擴張解釋候選人的口中吐出的每一個字,只為了讓這些語言符合自己想像的標準。政黨的消毒有效嗎?沒有選民的暗中贊助,政黨根本沒有意義。或許是選民對權威的膜拜,或許是選民對政黨的忠誠不改,或許是選民的改革迷思,幻想換一個政黨,就會換來美麗新世界,甚至以幻想滿足對國家神話的想像。

    + +

    弔詭的是,去想像一個右派的政黨會產生一個左派的樂土?別傻了!連在網路上為自己命名的自由都沒有,最後能在網路生存的大概只有駭客級人物。右派政黨對駭客當然要趕盡殺絕,但這些駭客若是政黨人馬,當然另當別論,坐享榮華富貴囉。現在這類駭客電影演粉多了,大家自己可以找片子來看,如果都找不到,建議看看全民公敵

    + +

    我有個朋友叫思春(村),也有個朋友叫燕好(彥豪),還有朋友叫阿達跟遺精(宜菁)的,照政府管理網路的邏輯,政府是不是要強制她們改名,限制她們的命名權?然而,一個小小的網路 id 真能潛藏色情嗎?有多少的文學作品,三句不離字,五句不離字,想來一波解嚴後的禁書運動,或是再興場文字獄嗎?原來這就是執政黨的民主!

    + +

    但是,色情又怎樣呢?色情不等同性騷擾!色情最大的罪過可能只是暗藏顛覆婚姻體制的因子與動力。色情真的會對女性造成傷害嗎?不是所有女性都服膺在貞操的規訓中,被教養成對性深懷恐懼,生來對性冷感,只敢說不,不敢說要的菟絲花。

    + +

    誰害怕色情?人民真的害怕色情嗎?還是執政者藉此箝制言論,以順上意,合理化對人民的監控?抑或是執政者企圖以色情汙名為藉口,將對不記名選票的焦慮,轉化到同質性頗高的網路匿名群眾?

    + +

    不管試圖限制網路一夜情的發生,或是對富含情慾能量(官方或衛道主義者所謂的色情) id 的監控,網路族其實可以簡化的解讀,這是由於執政者對網路世界的無知,導致對虛擬與現實的認知錯亂,硬要將現實規範套在虛擬世界中的謬論。那麼,在網路空間與現實社會的拉鋸戰中,網路群眾們可以做什麼呢?難道是在一個右派的現實社會中,去想像一個左派的網路空間,並將網路的便利省下來的時間,耗在網路上集結--搞網路革命!?

    +
    + +
    +

    註:

    + +
      +
    1. 小學生幫是綜藝節目火焰大對抗中的一個短劇。
    2. +
    +
    +
    + +
    + +
    +

    選舉,政治與價值觀的遊戲

    +
    依瑪貓
    + +
    +

    我談遊戲,因為這的確不是一種理性的選擇。我鮮少碰到有人可以把政治當作理性的行為。這是包括我自己在內。

    + +

    我常常有機會和熟朋友討論總統選舉。我的朋友和家人之中有許多民進黨候選人的支持者。她們在某個程度上,都是潛在的臺獨、反國民黨支持者(所以才會選擇支持民進黨)。我們的討論範圍很廣泛,從全球經濟體系下的臺灣等第三世界國家的地位,加入 WTO 等國際組織對民生的影響,到國內主流氛圍下臺灣的前途,政治獻金法與從政者的階級利益,等等。

    + +

    然而,最後大家無話可說時,總是會說,換黨,政黨輪替,政治才會有希望。

    + +

    最近,已經較少看到民進黨的文宣中,寫出鋒利的政治批判,或是強調民進黨的能力。這兩年文宣的主調總是在圍繞在政黨輪替的觀念,仿似民進黨已經沒有什麼好的可以自豪了。這也難怪。政治獻金法,國大延任案,六、七輕的開發案,數不清的自肥案,以及派系連年的惡質內鬥,已經把人民對反對黨的信賴打落谷底。民進黨除了超人氣以外,還有什麼能力,可以自負呢?

    + +

    很碰巧,仿如國民黨氣數已盡似的,今年國民黨候選人特別差,幾乎可以篤定會政黨輪替。因此,我們可以很放心地把政黨輪替這個理由,排除在選舉觀察的因素之外。政黨輪替,已不足以構成我們支持反對黨的理由。

    + +

    那麼,剩下來,我實在想不出有什麼理由,可以支持貪污、腐化,並且充滿父權心態的各大政黨,以及其候選人。

    +
    + +
    +

    即使如此,大家還是會去投票,也不會改變自己的支持對象。

    + +

    這其中的心態,是值得玩味的。說穿了,我們都知道政治是骯髒的。然而,我們還是固執地守著某種政治忠誠。有些人從早期為了反對臺獨而反對民進黨,到現在因為民進黨太亂了而厭惡民進黨;有些人從早期為了臺灣民主而反對國民黨,到現在為了政黨輪替而反對國民黨。政治忠誠的理由,越來越單薄,越來越沒有說服力,也越來越脫離理性思考的範疇。

    + +

    人民對政治的態度中理性要素的缺乏,反映了公共領域論述中理性的缺乏。包括我們在內的知識精英們,每天每時,無時無刻,都在從各種政治立場,以各種獨特的政治語言,談論著政治,申述著自己的理性。有時是來自 call in 政治節目,有時是來自新聞,有時是來自電視廣告,有時則是來自朋友的閒談。不同立場,互相矛盾的理性各自表述陳列,明爭暗鬥,爭奪彼此的正當性。

    + +

    沒錯,如果不是希望搏取她人認同,那幹嘛要說?但當大家都希望自己能搶佔她人的認同的時候,最終的結果不外乎:彼此的力量同時被削弱。聽的人無法判斷哪一邊是正確的,最後只好守著自己不是很說得通的信念。人民的理性政治判斷,轉變成了被動的、非理性的政治忠誠。

    + +

    這樣的現象,尤其出現在許多簡單的是非被錯置的時候。總統的座機風壓壓死民眾,是民眾愛看熱鬧的錯;法官帶霹靂小組去抓對方陣營的人,是司法獨立,不容懷疑;阻礙全民健保推行的人,成了全民健保的推動者;打壓對弱勢族群的人,成了社會正義的代言人;對大資本家不斷靠攏的人,批評對手官商勾結、黑金不分。凡此種種各自表述的理性,透過一遍又一遍不斷地述說,像是催眠術一樣,企圖爭奪我們的認同。

    + +

    當論述場域充滿了這樣各自表述的理性以後,人們只好選擇沉默,選擇閉嘴,選擇秘密守著自己的小小信仰。

    +
    + +
    +

    那麼,如何讓公共事務回歸理性面?

    + +

    或許我們要做的,不是繼續熙熙嚷嚷,吵吵鬧鬧,用力討論何謂真正的理性真正的社會正義。而是重新去思考何謂公共事務,讓公共事務的落實到生活的基本層面。女性主義所談的個人即政治提供了一個最佳的典範。一瓶米酒多少錢?一包長壽煙多少錢?一斤蒜多少錢?這些都和我們切身相關,也都是公共事務。(很可惜,也都沒有一位候選人能夠向我們保證這些事。)女人在婚姻中的財產,有沒有保障?女人在職場的昇遷權,有沒有保障?社會是否有足夠的託育政策?是否願意提供足夠的避孕管道?低收入婦女如何養家、如何負擔子女學費?性工作從業者受到法律的保護嗎?公共領域是否塑造了一種支持的氛圍,支持我們去做這樣的思考,並加以行動實踐?

    + +

    這,才是公共事務的理性面,也是我們實踐的起點。

    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 8 | + 9 | + 10 | + 11 | + 12 | + 13 | + 14 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0012.html.html b/htdocs/wov/newsletters/wov0012.html.html new file mode 120000 index 0000000..f550d85 --- /dev/null +++ b/htdocs/wov/newsletters/wov0012.html.html @@ -0,0 +1 @@ +wov0012.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0012.html.xhtml b/htdocs/wov/newsletters/wov0012.html.xhtml new file mode 100644 index 0000000..efb2e3b --- /dev/null +++ b/htdocs/wov/newsletters/wov0012.html.xhtml @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + +再談女人的網路天空 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第012期 2000年7月12日 編輯:小招/依瑪貓
    +網址: http://www.wov.idv.tw/
    +讀者意見或投稿請寄至
    +女聲專屬信箱 editors@mail.wov.idv.tw
    +本期文章:
    +
      +
    1. 編輯室手記/編輯室
    2. +
    3. 沈默的女人/小招
    4. +
    5. 再談女人的網路天空/依瑪貓
    6. +
    + +
    + +
    + +
    +

    編輯室手記

    +
    編輯室
    + +
    +

    女聲電子報終於申請到自己的網域了。我們也因此更改了網址和聯絡信箱。女聲的新網址為 http://www.wov.idv.tw/ ,新聯絡信箱為 editors@mail.wov.idv.tw

    + +

    女聲這麼久才發刊,呵呵……(尷尬的笑),總之,請多多批評指教。

    +
    +
    + +
    + +
    +

    沈默的女人

    +
    小招
    + +
    +

    前陣子認識一位女性朋友,私底下侃侃而談。那天,四個人開了一個小會議,兩個鐘頭下來,這位朋友說不到十句話。我好奇之外,更試著鼓勵她說話,另一位嘴巴幾乎沒停過的男性友人幫她解釋:這種場合,她話原就不多。但真得是這樣嗎?

    + +

    女人打出世後,整個社會都教導、規訓她得安靜,整個社會都在監聽女人的音量、頻率,並進一步以此評斷女人。我曾經搭過載滿大學女生的校車,司機的收音機放得震天嘎響,女學生不甘示弱的放聲聊天。最後,司機將這群女學生訓斥一頓後,車內是安靜了些,司機的收音機卻音量不減,無視他本身才是嚴重噪音的來源。

    + +

    大學有個女同學,在課堂上總是熱烈發言,並積極在系務會議為系上學生爭取系主任的選舉權,這位女同學變成一個凶悍不講理的象徵,在求職過程中,師長對她的推薦評語是,她會跟老師吵架。

    + +

    然後,我想到有很多人也認為我很沈默。我知道我為什麼沈默。例如,在計程車上原來與司機先生愉快地聊著電影,司機先生卻話鋒一轉,儼然成為 call in 節目中情緒激昂的 call in 者,急切的想要確認我的國族認同是否符合他的要求,為了想顧及彼此間的和諧,我會沈默。因為不習慣在狹小的空間中與人爭辯,我會沉默。因為不想有所不測時,讓媒體繪聲繪影地影射,我是如何去激怒男性加害人的,我會沉默。我其實不喜歡沉默,但是妳不沉默,出了事,社會大眾不去譴責加害人,反而是回過頭來質疑受害人--女人,妳是如何以言語激怒對方的?彭婉如,不就是一個明顯的例子麼?

    + +

    更嚴重的事,女人,妳只要膽敢出來為自己說話,妳就是居心不良。因此,師大女學生強暴案、李璇案, Jo Jo 林案在事實尚未明瞭時,女當事人都已經被輿論轟得滿頭包。

    + +

    出外工作之後,也讓不少女人學得沈默之道,因為一個不小心,女人的發明權就可能在話語流轉中遭人遺忘。這樣的經驗,女人不會陌生,往往在提出好的建議或企畫後,同一個場合的男性再複述一次,這項建議的智慧財產權可能就在 repeat 的過程中,神不知鬼不覺地轉嫁給在場的男性。很奇怪的,在許多人的耳中,女人的聲音只有兩種頻率,一個是刺耳,一個是無聲。

    + +

    當我年紀日漸增長,我周遭多了許多有見地的女人,但是這些女人不管思路多麼清楚,說起話來多麼有條理,她們也都很意識到在開會過程中,她們只能發言,沒有。女人一旦奮發向上,想要求完整的發言權時,她得有與全世界為敵心理準備。

    + +

    就好像呂秀蓮,有人已經不耐煩言婦運必提呂秀蓮。呂秀蓮年紀是大了,人們對她的角色定位也多放在政治人物上。但是,我們能因此抹煞呂秀蓮對戰後婦運的貢獻麼?人們尊稱孫中山是中華民國的國父,有沒有因為中華民國已經將近一世紀,而試圖拿掉孫中山的開國光環呢?反觀呂秀蓮新女性主義的 1970 年代距今也還不到 30 年呢!

    + +

    也許有人看到這裡,開始要跟我討論孫中山跟呂秀蓮到底誰偉大,那沒有意義。我要談的不是誰偉大的問題,而是為什麼有些人的貢獻能不斷的受到反芻,而有些人卻像是揮之不去的陳腔濫調呢?其中不存在性別的問題嗎?

    + +

    因此,我們的確看到呂秀蓮對政治理想的堅持,始終如一,卻在她得以落實理想時,人們反喝斥她得閉嘴。陳水扁不斷地背棄對選民的承諾時,人們卻開始了造神運動。

    +
    +
    + +
    + +
    +

    再談女人的網路天空

    +
    依瑪貓
    + +
    +

    去年的這個時候,我曾在第三期《女聲》中寫過一篇網路上的婦運,以網路傳播成本低廉,父權資本難以壟斷的觀點出發,樂觀評估:網路可以創造更多女人的空間。今年四月,我在 HerCafe 《女話》網路女人的天空一文中,從大量的女性網站,來討論網路女性熱,及本身對女人的影響。

    + +

    然而這一年下來,女人的網路版圖,有了很大的改變。 HerCafe 和 iRose 的低迷,象徵了商業網站企圖介入女性網友的挫敗。即使我天天在旁邊催眠,但朋友寧願上 Kimo ,也記不得什麼是 HerCafe 或 iRose 。這當然部份受限於女性網站資源不足(例如:廣告宣傳不如企業主要的網站等等。)但更重要的是:單純訴諸女性,勉強去特殊化女性需求(如生理期 E-mail 提醒),並不是有效的。

    + +

    我們還很難去評估:為什麼 Kimo 不以女性網站為訴求,卻反而獲得女人青睞。也許是名字好聽可愛,也許是服務簡單好用。但不能因此斷定:女人的網路版圖,因商業女性網站的挫折,而跟著挫敗。

    +
    + +
    +

    有趣的是,我在另一個地方,看到了另一種女人的網路能量。我常常可以在 E-mail 中收到各式各樣稀奇古怪的東西:最常見的是美麗的泰國人妖照片,或是會讓她們自己感動的雋語集,或請大家一起追查沙石車肇事的兇手,或是新電腦病毒的謠言,或是心理小測驗,或是好玩的桌面小遊戲。這些東西像連鎖信一樣,在網路上繞了一圈又一圈,不知道始作甬者是誰,也不知道最後去向何方。有些甚至每隔一個月就會又收到一次,停也停不了。麻煩一點的,也許朋友是在學術網路或公司的寬頻中,所以寄來的檔案大到好幾 MB 也不自覺,我就會收信收得很辛苦。

    + +

    有趣的是,會做這種事的,大多都是女人,只有極少數的是男人轉寄過來的。

    + +

    這是另外一種形式的網路能量:不需要會寫網頁,不需要會寫留言板,甚至不需要會寫文章。只要會傳 E-mail ,會把朋友加進通訊錄。女人從另一個點上發展出自己的網路能量,並且學習得很快:如何轉寄檔案?如何轉寄別人的網頁?很多轉寄技巧,甚至是我這個網路工程師,都還不會的。

    +
    + +
    +

    女人,在網路上摸索了自己的路出來。這條路不是電腦專家教的,不是商業網站提供的。分析這些轉寄的內容,會發現許多有趣的東西。但重點是,藉由轉寄,女人溝通、分享彼此的社會正義認知(如:追查車禍肇事者)、價值觀認同(如:達賴喇嘛智慧語)、生活智慧(如:如何對付生氣、出國時要小心)、審美觀(如:美美的泰國人妖)、休閒觀(如: Kitty 占卜)等等。

    + +

    是不是女人的聰明,反而擺脫掉父權體制的糾纏(不論是父權電腦專家,還是父權資本家),走出了一條自己的路出來呢?

    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 9 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0013.html.html b/htdocs/wov/newsletters/wov0013.html.html new file mode 120000 index 0000000..05fd44a --- /dev/null +++ b/htdocs/wov/newsletters/wov0013.html.html @@ -0,0 +1 @@ +wov0013.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0013.html.xhtml b/htdocs/wov/newsletters/wov0013.html.xhtml new file mode 100644 index 0000000..da9f78a --- /dev/null +++ b/htdocs/wov/newsletters/wov0013.html.xhtml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + +離婚女人也有情慾自主權!! + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第013期 2000年9月16日 編輯:小招/依瑪貓
    +網址: http://www.wov.idv.tw/
    +讀者意見或投稿請寄至
    +女聲專屬信箱 editors@mail.wov.idv.tw
    +本期文章:
    +
      +
    1. 離婚女人也有情慾自主權!!/小招
    2. +
    3. 習以為常的性別盲/依瑪貓
    4. +
    5. 〈讀者投書,來函照登〉/蘇岱崙
    6. +
    + +
    + +
    + +
    +

    離婚女人也有情慾自主權!!

    +
    小招
    + +
    +

    前陣子逛了一個女性網站,其中設有一個女性解放論壇留言版。雖名為女性解放論壇,不知何故,其中卻充斥著保守的父權言論或一些與主題無干的留言。總之呢,其中一則留言吸引了我,倒不是內容多有見地,而是這則留言恰巧凸顯整個社會大眾對一個離婚女性的觀點。

    + +

    內容大抵是說,留言者的某同事,是個離婚又有小孩的女人,除了前夫常來騷擾外,又跟一個離婚的男人糾纏不清,而這個離婚的男人又跟前妻分得不清不楚。她並不認同這位朋友的作為,提出的問題是,質疑這位朋友為什麼自我作賤,而同樣身為空服員,也很害怕這位離婚的女同事會破壞她們的名譽。一位讀者回應,認為離婚的女人也有善待自己的權利,做為朋友應該尊重當事人的生活方式,而不是道德批判,卻因此引來眾人的圍剿。

    + +

    對於上述事件,我不想單純地評判誰是誰非。我想先從我們如何看待離婚女性的情慾談起。

    + +

    我沒結過婚,不太能瞭解一個人要決定離婚時的心理感受。我能夠確定的是,婚姻並不是一個能夠自由來去的狀態,尤其當婚姻不斷被合理化為人生的一個必經的過程時,社會輿論的壓力讓離婚者更難以平常心面對脫離婚姻的後果。我的離婚朋友們,便飽嚐自由戀愛的差別待遇。

    + +

    一個未婚者,不管她戀愛幾次,失戀幾次,乃至分手幾次,都有權要求幸福的祝福,走上婚姻舞台,這樣的祝福卻罕見加諸於離婚者的身上,尤其在交往期間。很多離了婚的單身女性卻好像作錯事的孩子一樣,彷彿每個人都有權力去干涉她、糾正她,盯著她的交友狀況,窺伺她的一舉一動、一言一行。不論是否談過戀愛,只要是沒離過婚的人都可視她為感情的無能者,否則怎會婚姻失敗?她的交友對象、狀況都得獲得每個人的認可,否則眾人便虎伺眈眈,抱著看肥皂劇的心態,滿心期待、預測著她將再度面臨感情受挫與不幸,重蹈覆轍。

    + +

    這些年來,一些婦運團體致力於修改民法親屬篇。為了修法,必須動之以情,才能影響輿論及民意代表,通常僅僅訴諸以理並不太能鞏固服袞袞諸公修法的意志。因此大部分凸顯出來的離婚個案,不是惡意遺棄、惡意脫產,就是暴力相向,以要求判決離婚者或爭取親子撫養權。基本上,我同意這樣的策略,而且這也的確達到某種成效。但是有意無意的,建構了一種離婚女性獨特的刻板印象--無助的、可憐的、受虐的、貧窮的、缺乏自信,含辛茹苦撫養子女的無慾女性。

    + +

    因為這些楚楚可憐的形象,沒有爭取到親子撫養權的女人,她得維持母親聖潔的光環供子女膜拜,爭取子女的尊重、懷念與諒解;爭取到親子撫養權的女人,得以小孩為重,節制個人慾望。一個離了婚的女人若是在眾人睽睽下把男人帶回家,她得面對周遭有聲、無聲的譴責;離了婚的男人帶女人回家,眾人會幫忙解圍,像是小孩需要媽媽,或是家中需要一個灑掃、洗衣、煮飯、顧家、課子的女人來合理化這個行為。女人,敢輕言離婚嗎?

    + +

    不可否認,有些女性是無法忍受家庭暴力而逃離婚姻,有些女性是惡意遺棄、惡意脫產下的犧牲者,但這並不代表所有婦女都是得告上法庭的離婚個案,有許多女性是雙方私下協商的兩願離婚。就好像有個朋友想離婚,找不到離婚的見證人,又不想被律師賺一筆時,在無計可施下,打電話向婦女團體求助,沒想到對方只想為她作心理諮商。

    + +

    這些女人脫離婚姻的牢籠後,如同自由的小鳥展翅高飛,隨心所欲。她很清楚自己在做什麼,也知道自己想做什麼,或是如何善待自己,所以才有勇氣離婚,畢竟整個社會對離婚的女人並不厚道,連帶地也歧視在單親家庭中成長的孩子。離婚的女人並沒有作錯事,不過是選擇了另一種生活方式,就如同當初選擇結婚一樣。

    + +

    如果我們能祝福結婚的人,為什麼不能祝福離婚者的生活方式,管她交幾個男朋友?重要的是,在離婚的好友找到情投意合的伴侶時,不要拿衛道的放大鏡去檢視、評論她的情慾生活,或是把對方視為破壞群體名譽的污泥,唯恐沾惹而避之不及,更不要只是想指導她能做什麼,或告誡她不能做什麼,在情慾的路上,我們並不比離婚者來得聰明。幸不幸福,如人飲水,冷暖自知,尊重離婚女性的情慾自主權,給予適當的協助(例如偶而幫她帶帶小孩,讓她有空去約個會、看看電影),這才是好朋友應該做的吧!

    +
    +
    + +
    + +
    +

    習以為常的性別盲

    +
    依瑪貓
    + +
    +

    我們常常會對很多明顯的性別問題,習以為常。

    + +

    譬如說,某位男藝人對女友隱瞞自己的婚姻狀況,我們會反過來為他辯護說:藝人在外發展不得已。我們不會同樣地把她的女友的處境當成不得已,反而會跟著閒言閒語:是啊,她的個性本來就有問題。又譬如說,女副總統為自己被架空而叫屈的時候,拼命抨擊女副總統為政治亂源,是新型態病毒,可是當其它同黨男同志高喊被男總統冷落時,卻開始低吟:嗯,的確,新政府有很多潛在危機。

    +
    + +
    +

    性別盲就是,看不見擺在眼前的性別問題,不論是用不同標準看待男∕女的道德標準,還是用不同標準看待男∕女的收入差距。把男∕女公平掛在嘴上,卻看不到赤裸裸的男∕女處境差距。

    + +

    性別盲的原因很多,其中一個原因是:習慣性地聽男人訴苦的結果。男人很辛苦的。我爸也很辛苦,每天為了養家在外面打拼,白天工作晚上應酬到凌晨三、四點,就為了我們這一群小鬼。每次他喝醉酒跟我們真情流露的時候,場面其實是很感人的。只是,那往往是清晨三、四點,我們睡到一半被挖起來聽他真情流露,隔天早上七點還要上學。不然就是,邊聽他真情流露邊聽媽媽被毆打的聲音,我們幾個小鬼害怕地躲在被窩裏裝睡。

    + +

    我花了很多年,才克服對男性處境的同情。最後我的結論是:同情又怎麼樣?很可憐又怎麼樣?無法掩飾男性佔有父權優勢的事實。我可以用很寬鬆的角度同情男人,但如果我這樣做,我要怎麼面對我周遭長期被壓迫的女人呢?

    +
    + +
    +

    同樣的道理。男人的確很辛苦,要養家,要多一點薪水。可是女人難道不辛苦嗎?女人難道不用養家嗎?不用付小孩的學費、飯錢嗎?女人不也需要多一點的薪水嗎?片面的思考,讓我們得到片面的結論,使我們看不到問題在哪裏。的確,養家很辛苦,錢不好賺,可是薪水水平不足,是整個社會薪資制度的問題,是勞工法規保護不夠完善的問題。然而,養家的辛苦,錢不好賺,是共同的問題,並不足以證明女人可以拿比較低的薪水。

    + +

    事情必需要像這樣攤開來看,兩邊比較。很多人喜歡說女聲偏激,說女性主義偏激,說支持女性主義是人云亦云,容易受人影響。我很好奇事情常常是反過來的:這麼多性別問題擺在眼前沒有解決,用眼睛就可以看得到,可是她們不願去看,不願去聽,寧可採取和社會大多數主流相同的看法。那麼,是誰盲目受影響呢?

    +
    +
    + +
    + +
    +

    〈讀者投書,來函照登〉

    +
    蘇岱崙
    + +
    +

    小招,依瑪貓你們好!

    + +

    閱讀了這期的女聲,心中有些小小感想,也願與大家分享。

    + +
      +
    1. +

      沈默的女人一文中,我與小招有類似經驗。在很多與男人相處的場合中,有時為了自己的安全,有時為避免許多麻煩,有時只是覺得不值得浪費自己的口沫與青春,選擇閉上嘴巴。但通常在這種場合裡,我更希望能把耳朵也閉上。

      + +

      多話其實是很多台灣男人的通病。他們在你面前分析股票投資,探討高科技產業未來的前景,發表各種自以為是的新聞、政治評論--我真的不知道這種傾向與習性是如何、何時被養成的。男性似乎被要求得博學多聞,但我想很多男性只是裝得博學多聞。記得曾身處在一群男性朋友居多的場合裡,見他們你一言我一語地交換著新知,每個人似乎想說服別人自己的消息來源是最新最正確的,不惜搬出認識某某人,某某人跟我很熟之類的。但在我眼裡看來只是愚蠢得可笑罷了。我真的不瞭解 +認識某某人也可以是一種值得炫耀的成就。

      + +

      我不是說女人之間的談話就高級許多。也許很多男性朋友覺得女人動不動就談八卦很沒水準。但我們也聊心事,談體己話,心靈無助時總是找得到人願意當你的情緒垃圾桶。我不是男人,我不知道是否男性朋友在心痛心碎時找得到同性朋友療傷。

      + +

      男人跟女人其實都有機會成為弱者。但親愛的男性朋友們似乎總是負擔太重,永遠都必須扮演強者,不論在異性或同性面前。我想,承認自己是弱者才是最真實的勇敢吧。比起佯裝的強者,不虛偽隱藏自己弱點的男性,更值得人信賴與相處。

      +
    2. + +
    3. +

      很抱歉,之前依瑪貓發表有關網路與女性的文章並無機會閱讀,以下純粹是對此期文章的感想。

      + +

      關於女性網站(如文中所提 HerCafe 、 iRose )表現不如預期,我想正如文中所提,是由許多因素交織而成,不能拿來做女性是網路低使用者的證據。

      + +

      走在台灣市區街頭,觀察一下各種零售通路,很多都是針對女性設計的。女性服飾店不說,康是美、屈臣氏等藥粧店,各種連鎖、個性咖啡店及茶店,消費族群似乎都以女性為主。這類商店越來越多,可見利潤相當不錯。幾年前的數據吧,不知道現在是否還如此,在台灣競爭激烈百家爭鳴的雜誌裡,發行量最高的雜誌竟是一本專門介紹女性化妝、服飾的美人誌。種種跡象都顯示女性蓬勃的購買消費力,從這個邏輯看來,抓出在街頭流動的女性共同消費慾望,作為規劃一個女性專門網站的基本理念,似乎也有蓬勃的前景。

      + +

      首先,我想一個性別區隔網站的規劃者必須要問的是,男性與女性使用網路的需求是否有差異?以我個人經驗,我使用網路最多的用途是 e-mail 及查資料,就這兩項需求而言,上不上女性專屬網站似乎沒有差別。其次,對喜愛使用線上對談功能的網友而言,上街購物、看雜誌和上網路功能是不同的,前者屬於單向消費、接收資訊,後者則提供互動機會。假設一位女性網友想在聊天室遇見異性,上一家設定為女性專門網站裡的聊天室遇見異性的機會大呢,還是去一家沒有性別區隔的熱門網站與異性聊天的機會大呢?最後,我會以為是因為線上購物的習慣在台灣尚不普及,正確來說,應該是在購物網站購買有品牌商品的習慣(有許多人寧願在留言版裡和陌生人交易電腦週邊產品,也不曾在網路上買一本書),這點應該是沒有性別差異的。

      + +

      不過關於依瑪貓引用女性轉寄郵件這個舉動,作為抗衡父權體制糾纏的例證,我倒有不同看法。

      + +

      依瑪貓提到她收到的轉寄郵件者大部分是女性,我的個人經驗卻不同。我收到的各式郵件轉寄者有男有女。況且,我想很多轉寄郵件是僅發生在男-男之間的(如色情圖片),這是身為女性的我們所體會不到的。

      + +

      再者,如果轉寄郵件者真如依瑪貓所說,大部分是女性所為,那麼我不但不會把它視作是行動力的象徵,反而有所擔憂--擔心女性朋友是否喪失了她們的判斷能力。許多轉寄郵件包藏了商業詭計(例如只要轉寄郵件給朋友就有免費手機,或一位瀕死的孩子就能因此獲得援助金等等);很多雋永小品及笑話也負載著似是而非的價值觀,尤其強化性別刻板印象的描述。再來接收轉寄郵件對大多數人其實是一種負擔,身為受害者之一,卻毫無過濾地把收到所有的轉寄郵件一股腦倒給通訊錄裡的朋友,加害於其他無辜的朋友。我曾發信給性喜轉寄大量郵件給我的朋友,拜託他們不要再轉寄無意義的郵件給我。一位女性朋友回應道,她其實也很厭煩接收這些轉寄郵件,收到我的抱怨也才驚覺, e-mail 的發明應是助人溝通,而不是增人負擔的。

      + +

      基於此,我希望聰明的女性朋友們,以後再收到轉寄郵件時,能夠留心過濾判斷,把有用的郵件轉寄給需要的人,其他的就丟到垃圾桶吧,別讓錯誤的訊息、龐大的郵件,害了你的朋友、爆了她 /他的信箱。

      +
    4. +
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 9 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0014.html.html b/htdocs/wov/newsletters/wov0014.html.html new file mode 120000 index 0000000..f59bfd2 --- /dev/null +++ b/htdocs/wov/newsletters/wov0014.html.html @@ -0,0 +1 @@ +wov0014.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0014.html.xhtml b/htdocs/wov/newsletters/wov0014.html.xhtml new file mode 100644 index 0000000..ce1eb45 --- /dev/null +++ b/htdocs/wov/newsletters/wov0014.html.xhtml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + +感動的背後 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第014期 2001年2月5日 編輯:小招/依瑪貓
    +網址: http://www.wov.idv.tw/
    +讀者意見或投稿請寄至
    +女聲專屬信箱 editors@mail.wov.idv.tw
    +本期文章:
    +
      +
    1. 女性主義者快樂嗎?/小招
    2. +
    3. 感動的背後/依瑪貓
    4. +
    + +
    + +
    + +
    +

    女性主義者快樂嗎?

    +
    小招
    + +
    +

    曾經有一位讀者阿澈來信詢問,內容只有短短三行:請問研究與實踐女權的各位,你們現在真的快樂嗎?P.S.絕非討打挑釁才寫這封信。這個缺乏上下文的提問顯然極為草率,雖然阿澈在信末聲明沒有挑釁意涵,但任誰看來這封來函都有那麼點挑釁意味,否則女性主義者快不快樂,又與他何干呢?

    +
    + +
    +

    女性主義者快樂嗎?

    + +

    當女性主義者挑戰一些長久以來為人忽視的性別歧視現象時,並沒有獲得社會大眾太多的鼓勵與迴響。相反地,有人從異性戀婚姻霸權來解讀婦女運動,認為是缺乏愛情滋潤、沒有男人緣,在婚姻市場中沒撈到好處的女人們,企圖挑撥兩性關係所發起的行動。而這樣的想法還可以標籤化一些勇於發言、爭取權力(利)的女人行為模式,進一步妖魔化企圖在各個領域與男人相抗衡的女人。

    + +

    在父權社會中,女人的理想,便是找一個好老公,成就一段幸福美滿的婚姻,當個男人背後的賢妻良母,這是每個女人從小就受到的社會制約。女人若表現得太過強勢,往往會傷及偉大丈夫的自尊,或嚇跑男人,而無法獲得幸福的婚姻。所以我們會看到,呂副總統的發言,只是稍稍讓那些男人感到刺耳,他們就會懷疑女副總統的單身生活是否不快樂?這些男性立委還會自作聰明地,自告奮勇地扮演起肥皂劇中的現代紅娘,想幫呂副總統介紹男友。一廂情願地以為,把強勢的女人跟任何一個男人送作堆,就能將她馴服於男人腳下,耳根便從此得享清靜。

    + +

    順著上述脈絡來推想,女性主義者不快樂的原因,是社會試圖將她們狹隘地定位在感情失敗者的位置。男人常常高估自己在女人心目中的地位,認定女性主義者是仇恨男人的女人,而這些女人為什麼仇恨男人呢?也許是吃過男人的虧,或上過男人的當,甚至是被男人拋棄了之類,才轉而投入婦女運動攻擊男人。既然是以仇恨為行動力的基礎,想必也快樂不到哪。

    +
    + +
    +

    然而,女性主義者真的不快樂?

    + +

    當然不是。其實,男人不必自抬身價,沒有男人,女人照樣可以過得很好,更何況異性戀也不過是一部份人的性偏好。因此,將女性主義者快樂與否,硬是要跟男人扯上關係,未免也太小覷女性主義者的理想。

    + +

    我必須承認,不論回顧或展望台灣婦女生活現狀,都讓人快樂不起來。比如,家庭暴力防治法已經實施一年多,我們依然從媒體看到又有哪個女人被配偶打得鼻青臉腫,甚至死亡。也有女性在取得保護令後,仍然難逃其配偶毒手。當我們看到公娼在兩年緩衝期滿後,只能化明為暗,性工作者仍然無法擺脫性污名,性工作權的相關立法依然無法登上國會殿堂。家務勞動仍然無酬,重擔照舊落在女性身上。托育照顧依然無解,得靠女人自我犧牲,為國家福利制度的欠缺解套。身為一個女性主義者,同樣會對暗夜來臨時的不友善環境中感到恐懼。

    + +

    跳脫對整個大環境的無力感,從個人實踐的層面來看,女性主義者活得快樂而自在。女性主義就是一種力量的來源,不甩父權意識型態那套老掉牙的道德觀。不婚生子是我的選擇,同居也是我的選擇,婚前性行為是我的自由,不刮腋毛、不穿胸罩,誰能干涉?我的身體,我決定,享有身體自主權,這就是女性主義者的快樂。

    +
    +
    + +
    + +
    +

    感動的背後

    +
    依瑪貓
    + +
    +

    我們很容易為了小事而感動,卻常常忘了感動的背後,是一樁樁不平等的累積。

    + +

    前一陣子,從朋友收到一封轉寄的信。這封心靈小品已經被到處轉寄很多年了,大意是:男主角以第一人稱述說,他被公司外派出國進修,想把妻子接去一起生活時,妻子突然提出離婚,結果兩個人分開了好幾年。男主角回國後,遍尋不著妻子,才知道兩人分開期間,妻子被人強暴,自覺無臉見丈夫,逐漸自閉,住進精神病院。最後男主角找到女主角,感動莫名地接納了她。

    +
    + +
    +

    很感動嗎?

    + +

    如果妳會感動的話,那這樣的感動,其實是很奇怪的。我有幾個朋友,曾經遭受過性暴力。她們之所以能夠從被強暴的痛苦經驗中走出來,大多是靠自己,或是靠身邊的好友陪她一起走過。沒有人是靠愛情關係中的男伴的接納,而走出來的。

    + +

    感動嗎?我不大感動。女人可以靠自己堅強的生命力走出被強暴的陰影,不需要男人把接納拿來施捨,才能過日子。女人自己可以活出自己的路,幹麻一副非要男人接納,否則活不下去的樣子呢?

    + +

    這樣的故事,非常違背現實。幾乎沒有人是靠著男伴的接納,而從被強暴的陰影中走出來的。為什麼?因為被強暴的痛苦,是來自於對人身安全和暴力的恐懼,和周圍的人接不接納,沒有直接關係。

    + +

    把女人被強暴的恐懼,和對不起丈夫的貞操觀連結在一起,不只是恢復到古早的貞節牌坊對女人的束縛,更否定了強暴過程中暴力的部份,對女人遭到的暴力視而不見。

    +
    + +
    +

    像這樣,我們常常感動,卻感動得失了理智。鐵達尼也很讓人感動:傑克的出現,解放了蘿絲,給蘿絲從沒有自由的黑暗牢籠中打開一扇窗口,射進了陽光。傑克雖然死了,但傑克的靈魂已經和自由的種子,一起永遠進駐蘿絲的心中。這是很感人的故事,但我們常常忘了問:為什麼女人從男人身上獲得自由?為什麼女人不能從別的女人身上獲得自由,或是自己給自己自由,自己解放自己呢?

    + +

    每個感動的背後,都有太多不平等的牢籠。太多的感動,讓我們對背後的問題視而不見,讓我們不知不覺認同了錯誤的價值觀。下次如果妳再看到類似的故事,兩性互相接納的完美大結局,不妨在感動之前,停下腳步想想:是不是非得要靠男人,女人才能得到故事的完美大結局呢?

    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 9 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/newsletters/wov0015.html.html b/htdocs/wov/newsletters/wov0015.html.html new file mode 120000 index 0000000..7f95681 --- /dev/null +++ b/htdocs/wov/newsletters/wov0015.html.html @@ -0,0 +1 @@ +wov0015.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/newsletters/wov0015.html.xhtml b/htdocs/wov/newsletters/wov0015.html.xhtml new file mode 100644 index 0000000..d2e191b --- /dev/null +++ b/htdocs/wov/newsletters/wov0015.html.xhtml @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + +誰的言論、誰有自由?! + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    女聲

    +

    Woman’s Voice

    +
    + +
    +《女聲》第015期 2004年1月16日 編輯:小招/依瑪貓
    +網址: http://www.wov.idv.tw/
    +讀者意見或投稿請寄至
    +女聲專屬信箱 editors@mail.wov.idv.tw
    +本期文章:
    +
      +
    1. 誰的言論、誰有自由?!/小招
    2. +
    3. 論人獸交,何罪之有?/依瑪貓
    4. +
    5. [婦運消息]聲援何春蕤出庭活動/編輯室代貼
    6. +
    + +
    + +
    + +
    +

    誰的言論、誰有自由?!

    +
    小招
    + +
    +

    五年級的朋友大概都跟我有同樣的經驗。念小學時,每天過得戰戰兢兢的,深怕自己沒有善盡保密防諜的義務,而害了國家或家人。然而,一個小學生能知道什麼國家機密呢?頂多知道自家成員姓名、地址、電話罷了,要小孩保密防諜,真可謂生命中不可承受之重。因為不知道什麼算是機密,所以只好把週遭的人都當成通匪的嫌疑人,凡事都來個一問三不知,小小的腦袋認為那是最好的保密之道,才能明哲保身。年紀稍長,知道憲法保障人民的言論自由,才發現自己從來不曾享有這種自由。自由,是當政者才有的權力。

    +
    + +
    +

    我在解嚴後上了大學,歌頌著解嚴後的言論自由,也跟人家喊學術自由。在客觀中立的學術光圈下,許多社會大眾還無法接受的議題,可以從各個角度探討,提出多元論述而不受限制。然而,誰能想到如此自由的論述領域,也埋著它的地雷,而何春蕤網站的人獸交連結踩到了這個地雷。然而該網站的連結真的會造成台灣孩童多大的傷害嗎?首先,那是掛在中央大學外文所上的國外網站,要看到該網站還得要有點英文程度。我記得有位學者曾反映台灣很多國中生連26個英文字母都記不住,要這些學生連上人獸交網站還真是天方夜譚呢。當學生要查字典七連八連才連得到的人獸交網站時,他直接打開電視就可以看到各種有線頻道,就可以輕易看到一大堆殺得亂七八糟的暴力電影,試問那一個頻道對青少年的影響比較大呢?答案很清楚啊。看看每天的報紙,出現青少年火拼、情殺與人獸交新聞的比例就知道了。其次,如果放兩個人獸交網站連結都引起如此軒然大波,那所有的搜尋網站大概都得關門了,因為那上面可不只兩個連結。還有,性/別研究室連基本的人類各種主流/非主流的性欲研究都禁止,那還有什麼研究是符合該研究室需求的?

    +
    + +
    +

    對何春蕤提出告訴的團體成員,人權大老許文彬說我們支持學術自由,但是一定要有限度。這個限度在哪呢?有人引用宗教支持者的說法,世間美好的事物那麼多,為何要去彰顯另類行為。照這麼說來,何春蕤的人獸交研究是因為不美好,所以才違反學術自由與言論自由的基本精神。然而,除了剽竊、抄襲等惡劣侵權的行為,學術研究本身哪有美不美的呢?學術研究既不是供人瞻仰的藝術品,也不是為他人歌功頌德、彰顯他者的工具。如要照美感主流的標準來看,舉凡陳舊陋俗、毒蛇猛獸、瘟疫死亡等研究都得收攤吧。因為不符合主流社會需求或美感價值,就判定非主流論述是有害的,而企圖剝奪其言論自由,這就是對學術自由的嚴重干預。

    +
    + +
    +

    西方18世紀哲學家伏爾泰有句名言:雖然我不同意你的觀點,但我要以生命捍衛你說話的權利。現今台灣主流社會顯然沒這種容納異己的雅量。他們容忍的界限大概就是,男人講話,女人閉嘴;大人有性,小孩沒性;男異性戀可以看裸女,男同性戀卻禁止看裸男。

    +
    +
    + +
    + +
    +

    論人獸交,何罪之有?

    +
    依瑪貓
    + +
    +

    九十二年四月九日,終止童妓協會、善牧基金會等婦女團體,聯合召開記者會,譴責中央大學何春蕤教授與性/別研究室的網站上,刊登人獸交的網站連結。六月二十三日,在立委曾蔡美佐陪同下,兒童少年保護委員會、勵馨基金會等團體,到台北地檢署申告。九月二十三日召開偵察庭,十二月五日起訴。今天九十三年一月十六日,將第一次開庭。

    +
    + +
    +

    事件的背後,糾結著複雜的因素。勵馨、善牧等團體,長期以來對性的保守立場,與何春蕤的性解放主張背道而馳,早已對其深懷敵意,欲除之而後快。在中產階級保守價值的保護傘下,何春蕤網站的人獸交連結,讓保守婦女團體找到引爆點,可以集結同情自己的保守勢力,除去這個心中刺、眼中釘。他們自然不會放過這個機會,集結同情自己的保守勢力,希望一舉擊潰對手。

    +
    + +
    +

    然而,撇開婦女團體與婦運團體的路線鬥爭不談。網站談到人獸交,到底犯了什麼錯?起訴書中指出,這些人獸交圖片,客觀上足以刺激性慾並引起一般人羞恥及厭惡感,侵害性道德的猥褻色情圖片。照這個理由,台灣網站上列的相關連結,凡是連結對方客觀上足以刺激性慾並引起一般人羞恥及厭惡感,侵害性道德的猥褻色情圖片。均屬違法。那何不取締 Yahoo! ?何不取締 Google ?是不是要學中國大陸一樣,對整個台灣的網路設限?

    +
    + +
    +

    中華民國憲法第十一條:人民有言論,講學,著作及出版之自由。除非依第二十三條:以上各條列舉之自由權利,除為防止妨礙他人自由,避免緊急危難,維持社會秩序,或增進公共利益所必要者外,不得以法律限制之。人獸交既不妨礙他人自由,也不造成緊急危難,勉強只能以維持社會秩序,增進公共利益加以限制。可是所謂張貼人獸交圖片也只是渲染出來的,這些圖片根本不是網站本身的出版品,只是網站參考資料上的出版品!出版品評議基金會執行長許文彬說:學術自由不應成為散播色情的無限上綱,但若根本沒有散播色情呢?

    +
    + +
    +

    反色情,反討論色情,更進一步反參考色情資料。真正在無限上綱的,其實就是反色情的論述。因為違反社會主流人士的價值,所以不能談,不能主張,不能參考。不能寫不能說不能聽,就是要淨化,完全消失在他們的眼前才算數。不然呢?因為網路沒有設限,孩子們會不小心進去,污染孩子的身心,加了警告標語也沒有用。他們把小孩子搬出來,小孩子是他們對付色情的武器。無辜的孩子變成大人打擊異己的武器。

    +
    + +
    +

    延伸下去,所有違反法律的議題,不合乎主流價值的議題,有害兒童身心健康、正確觀念的議題,都不應該談。我們不應該談優生保健法對墮胎限制的不合理性,不應該談援助交際的不合理性,不應該談著作權法的不合理性,不應該談死刑的不合理性,不應該談同性戀恐懼症的不合理性。像我們這些同性戀、動物戀、墮胎者、反廢死刑、支持性工作者,他們絕對會尊重我們的學術自由,不過只能關在房間裏談,不可以公開,不然會污染小孩子的身心健康絕對會尊重的學術自由與言論自由只限於房間裏。

    +
    + +
    +

    強迫少數弱勢者躲回到黑暗的櫃子,以留給主流支配者清淨的空間。這不是壓迫,是什麼?我們走了那麼多年,要得到的社會,真的是這個樣子的嗎?進步的多元民主社會,是這個樣子的嗎?

    +
    +
    + +
    + +
    +

    [婦運消息]聲援何春蕤出庭活動

    +
    編輯室代貼
    + + + +

    新聞稿 敬請發佈 歡迎採訪

    + +
    +
      +
    • 時間:2004年1月16日(五)上午10時30分
    • +
    • 地點:台北地方法院(台北市博愛路131號)
    • +
    + +

    中央英文系教授何春蕤從事性/別研究十餘年,持續開拓邊緣性議題,維護性少數人權。去年她的學術網路資料庫動物戀網頁超連結遭到在意識形態上與她纏鬥多年的宗教兒少團體檢舉,說是散播色情,妨害風化,要將她殺雞儆猴(告發人許文彬語)。目前何春蕤被提起公訴,將於2004年1月16日第一次出庭。各界人士,包含學界、社運界、各校學生均將參與性別人權協會發起的聲援何春蕤出庭活動。中央學生並在各大專院校之間發起聲援何老師就是保障自己!的串連行動,學生代表將於法院前演出不准看不准聽不准說行動劇

    +
    + +
    +

    在去年4月何春蕤被檢舉、6月何春蕤被告發的第一時間,已有性別學者謝臥龍、朱偉誠、張小虹、夏曉鵑等多人挺身而出以實際參與記者會方式聲援何春蕤,而過去一直保持沈默的女性主義學術團體—女學會,以及婦女團體—婦女新知基金會,亦於今(15日)首度打破沈默,發出聯合聲明公開支持何春蕤,並將於明(16日)派代表至法院前宣讀。

    +
    + +
    +

    由性別人權協會發起的聲援何春蕤—捍衛學術研究連署行動,已獲得國內外數千名學界、社會界人士之連署簽名,此份文件明日將由代表致交何春蕤本人,表達大家對她的支持之意。

    +
    + +

    活動流程:

    + +
      +
    1. 事件說明
    2. +
    3. 行動劇—不准看不准聽不准說
    4. +
    5. 交捍衛學術研究連署書給何春蕤
    6. +
    7. 各界支持發言: +
        +
      • 高師大性別教育研究所教授 謝臥龍
      • +
      • 中央大學英文系學生/酷兒社 林毓凱
      • +
      • 玄奘大學法律系學生/性別文化研究社 吳蕙如
      • +
      • 政大哲研所學生/工人民主協會/連結雜誌社 朱維立
      • +
      • 女性學學會代表
      • +
      • 其他現場代表
      • +
      +
    8. +
    + +
    +新聞連絡人:性別人權協會秘書長 王蘋
    +8251-0105, 0937-142425
    +
    +
    + +
    + +
    +
    + 目錄 | + 第一期 | + 前一期 | + 9 | + 10 | + 11 | + 12 | + 13 | + 14 | + 15 | + 下一期 | + 最新期 +
    + +
    + + + + diff --git a/htdocs/wov/robots.txt b/htdocs/wov/robots.txt new file mode 100644 index 0000000..f6f8dd7 --- /dev/null +++ b/htdocs/wov/robots.txt @@ -0,0 +1,9 @@ +User-agent: * +Crawl-delay: 1 +Disallow: /magicat/ + +User-agent: chklinks +Disallow: + +User-agent: HTTrack +Disallow: / diff --git a/htdocs/wov/scripts/accounting.js b/htdocs/wov/scripts/accounting.js new file mode 100644 index 0000000..5c09dc2 --- /dev/null +++ b/htdocs/wov/scripts/accounting.js @@ -0,0 +1,177 @@ +/* Woman's Voice + * accounting.js: The accounting-related JavaScript subroutines. + */ + +/* Copyright (c) 2007-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2007-09-26 + */ + +// setAutoSummary: Automatically supply a summary +function setAutoSummary(subj) { + var i, j, sum, dateText, today, subjText, subjCode, thisMonth; + // Get the name prefix of this selection + i = subj.name.indexOf("subj"); + // Obtain the summary column + sum = subj.form[subj.name.substr(0, i) + "summary"]; + // Get today's date + today = new Date; + dateText = trim(subj.form.date.value); + if (!isDate(dateText)) + return; + today.setFullYear(dateText.substr(0, 4)); + today.setMonth(dateText.substr(5, 2) - 1); + today.setDate(dateText.substr(8, 2)); + thisMonth = today.getMonth() + 1; + // Obtain the selected subject + // The value of the selection is S/N but not subject code, + // so we have to obtain the subject code from the option text + subjText = subj.options[subj.selectedIndex].text; + subjCode = parseInt(subjText.substr(0, subjText.indexOf(" "))); + switch (subjCode) { + // 74811 共同生活基金-燕秋 + case 74811: + sum.value = "燕秋" + thisMonth + "月"; + break; + // 74812 共同生活基金-士青 + case 74812: + sum.value = "士青" + thisMonth + "月"; + break; + // 6252 租金支出 + case 6252: + sum.value = "房租" + thisMonth + "月"; + break; + // 62562 市話 02-3233-7444 + case 62562: + // 2142 應付—電話費 + case 2142: + // 20 or later - assume to be of this month + if (today.getDate() >= 20) { + sum.value = "電話費" + thisMonth + "月"; + // Before 20 - assume to be of previous month + } else { + sum.value = "電話費" + ((thisMonth + 10) % 12 + 1) + "月"; + } + break; + // 62611 電費 + case 62611: + i = ((thisMonth + thisMonth % 2 + 8) % 12 + 1) + j = ((thisMonth + thisMonth % 2 + 9) % 12 + 1) + sum.value = "電費" + i + "–" + j + "月"; + break; + // 62612 水費 + case 62612: + i = ((thisMonth + thisMonth % 2 + 8) % 12 + 1) + j = ((thisMonth + thisMonth % 2 + 9) % 12 + 1) + sum.value = "水費" + i + "–" + j + "月"; + break; + // 62613 瓦斯費 + case 62613: + i = ((thisMonth + thisMonth % 2 + 8) % 12 + 1) + j = ((thisMonth + thisMonth % 2 + 9) % 12 + 1) + sum.value = "瓦斯費" + i + "–" + j + "月"; + break; + // 62614 公用電費 + case 62614: + i = ((thisMonth + thisMonth % 2 + 8) % 12 + 1) + j = ((thisMonth + thisMonth % 2 + 9) % 12 + 1) + sum.value = "公用電費" + i + "–" + j + "月"; + break; + // 62732 有線電視—新視波 + case 62732: + if (thisMonth == 12 || thisMonth == 1) + sum.value = "新視波1–6月" + else if (thisMonth == 6 || thisMonth == 7) + sum.value = "新視波7–12月" + break; + } + return; +} + +// acctRepQueryDisableNoUseRanges: Disable range parameters that are not in use +function acctRepQueryDisableNoUseRanges() { + var i, form, curValue; + // Obtain our form + form = document.forms["acctrepquery"]; + if (form == undefined) + return; + // Find the current selection + for (i = 0; i < form.r.length; i++) { + if (form["r"][i].checked) { + curValue = form["r"][i].value; + break; + } + } + // Disable or enable the month selection + if (curValue == "m") + form["m"].disabled = false; + else + form["m"].disabled = true; + // Disable or enable the year selection + if (curValue == "y") + form["y"].disabled = false; + else + form["y"].disabled = true; + // Disable or enable the start and end date + if (curValue == "s") { + form["f"].disabled = false; + form["t"].disabled = false; + } else { + form["f"].disabled = true; + form["t"].disabled = true; + } + return; +} + +// calcTotal: Calculating the total +function calcTotal(amount) { + var i, j, side, sum, a, pos, isNumber; + a = "NT$ 3,433.00"; + side = amount.name.substr(0, 4); + for ( i = 0, sum = 0; + amount.form[side + i + "amount"] != undefined; + i++) { + a = amount.form[side + i + "amount"]; + // Trim the text + a.value = trim(a.value); + // Remove the dollar sign + if (a.value.substr(0, 3) == "NT$") + a.value = a.value.substr(3); + // Trim the text again, for possible spaces after the dollar sign + a.value = trim(a.value); + // Remove the decimal point + if (a.value.substr(a.value.length - 3) == ".00") + a.value = a.value.substr(0, a.value.length - 3); + // Remove the thousand seperators + while ((pos = a.value.indexOf(",")) != -1) { + a.value = a.value.substr(0, pos) + a.value.substr(pos + 1); + } + // Check if it is a number + for (j = 0, isNumber = true; j < a.value.length; j++) { + if (a.value.charCodeAt(j) < 48 || a.value.charCodeAt(j) > 57) { + isNumber = false; + break; + } + } + // Add the amount + if (isNumber) + sum = sum + a.value * 1; + } + a = amount.form[side + "total"]; + if (a != undefined) + a.value = sum; +} diff --git a/htdocs/wov/scripts/common.js b/htdocs/wov/scripts/common.js new file mode 100644 index 0000000..f74477c --- /dev/null +++ b/htdocs/wov/scripts/common.js @@ -0,0 +1,139 @@ +/* Woman's Voice + * common.js: The common JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-05-17 + */ + +// _: Gettext +function _(msg) { + var i; + for (i = 0; i < lc_messages.length; i++) { + if (lc_messages[i][0] == msg) { + return lc_messages[i][1]; + } + } + return msg; +} +// The messages +lc_messages = []; + +// isEmail: Check if an email address is legal +function isEmail(a) { + var i, c, re; + if (typeof(RegExp) == "undefined") return true; + re = new RegExp("^[\\w\\-]+(\\.[\\w\\-]+)*\\@([\\w\\-]+\\.)+[\\w\\-]+$"); + if (typeof(a) != "string") return false; + a = a.toLowerCase(); + if (re.exec(a) == null) return false; + return true; +} + +// isDate: Check if a date is legal +function isDate(dateText) { + var i, year, month, day, maxDay; + if (dateText.length != 10) { + return false; + } + // Check each character + for (i = 0; i < dateText.length; i++) { + // The dash sign + if (i == 4 || i == 7) { + if (dateText.charAt(i) != "-") + return false; + // The digits + } else { + if (dateText.charCodeAt(i) < 48 || dateText.charCodeAt(i) > 57) + return false; + } + } + // Check if the date is valid + year = dateText.substr(0, 4) * 1; + month = dateText.substr(5, 2) * 1; + day = dateText.substr(8, 2) * 1; + // A reasonable month + if (month < 1 || month > 12) + return false; + // Find the maximum day in this month + switch (month) { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + maxDay = 31; + break; + case 4: + case 6: + case 9: + case 11: + maxDay = 30; + break; + case 2: + maxDay = 28; + if (year % 4 == 0) + maxDay = 29; + if (year % 100 == 0) + maxDay = 28; + if (year % 400 == 0) + maxDay = 29; + break; + } + // A reasonable day + if (day < 1 || day > maxDay) + return false; + return true; +} + +// trim: Trim the leading and tailing spaces +function trim(a) { + var pos, start, len, spaces; + start = 0; + len = a.length; + spaces = " \t\f\n\r"; + for (start = 0; start < a.length && spaces.indexOf(a.charAt(start)) >= 0; start++, len--); + for (pos = a.length - 1; pos >= 0 && spaces.indexOf(a.charAt(pos)) >= 0; pos--, len--); + return a.substr(start, len); +} +function trimText(a) { + var pos, start, len, spaces, newlines; + start = 0; + len = a.length; + spaces = " \t\f\n\r"; + newlines = "\n\r"; + for (start = 0; start < a.length && spaces.indexOf(a.charAt(start)) >= 0; start++, len--); + for ( ; start-1 >= 0 && newlines.indexOf(a.charAt(start-1)) < 0; start--, len++); + for (pos = a.length - 1; pos >= 0 && spaces.indexOf(a.charAt(pos)) >= 0; pos--, len--); + return a.substr(start, len); +} + +// Replace one phace with another in a string +function replace(source, oldStr, newStr) { + var pos; + pos = 0; + while (true) { + pos = source.indexOf(oldStr, pos); + if (pos == -1) break; + source = source.substr(0, pos) + newStr + source.substr(pos + oldStr.length) + pos += newStr.length; + } + return source; +} diff --git a/htdocs/wov/scripts/guestbook.js b/htdocs/wov/scripts/guestbook.js new file mode 100644 index 0000000..f814dea --- /dev/null +++ b/htdocs/wov/scripts/guestbook.js @@ -0,0 +1,55 @@ +/* Woman's Voice + * guestbook.js: The guestbook-related JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-06-07 + */ + +// isGuestbookOK: Check if the message is ready to be submitted +function isGuestbookOK(form) { + + // Regularize the fields + form.message.value = trimText(form.message.value); + form.name.value = trim(form.name.value); + form.identity.value = trim(form.identity.value); + form.location.value = trim(form.location.value); + form.email.value = trim(form.email.value); + form.url.value = trim(form.url.value); + + // Check the message + if (form.message.value == "" || form.message.value == _("Fill in your message here.")) { + alert(_("Please fill in your message.")); + form.message.focus(); + return false; + } + if (form.message.value.length > 10240) { + alert(_("Your message is too long. (Max. 10,240 letters)")); + form.message.focus(); + return false; + } + message = form.message.value.toLowerCase(); + if (message.indexOf(" + * First written: 2004-11-05 + */ + +// The messages +lc_messages = [ +["Fill in your message here.", "請填上妳的留言。"], +["Please fill in your message.", "請填上妳的留言。"], +["Your message is too long. (Max. 10,240 letters)", "妳的留言太長了。(最長 10,240 個字)"], +["Your message contains HTML, which will be displayed \"AS IS\". If this is a commercial advertisement, it will be deleted right away and you are wasting your time. Do you still want to submit this message?", "妳的留言內含 HTML , HTML 會以原始碼秀出。一般商業廣告留言隨見隨刪,請勿浪費時間。妳確定要留這則留言嗎?"], +["Your message contains BBCode, which will be displayed \"AS IS\". If this is a commercial advertisement, it will be deleted right away and you are wasting your time. Do you still want to submit this message?", "妳的留言內含 BBCode , BBCode 會以原始碼秀出。一般商業廣告留言隨見隨刪,請勿浪費時間。妳確定要留這則留言嗎?"], + +["Fill in the description here.", "請填上簡介。"], +["This description is too long. (Max. 256 letters)", "簡介太長了。(最長 256 個字)"], +["Please fill in the site name.", "請填上站名。"], +["Please fill in the URL.", "請填上網址。"], +["Please fill in the description.", "請填上簡介。"], + +["Please fill in your query.", "請填上檢索的辭彙。"], +]; diff --git a/htdocs/wov/scripts/links.js b/htdocs/wov/scripts/links.js new file mode 100644 index 0000000..97eeb49 --- /dev/null +++ b/htdocs/wov/scripts/links.js @@ -0,0 +1,75 @@ +/* Woman's Voice + * links.js: The related-link related JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-06-28 + */ + +// isRegisterOK: Check if the register form is ready to be submitted +function isRegisterOK(form) { + + // Regularize the fields + form.title.value = trim(form.title.value); + form.title_2ln.value = trim(form.title_2ln.value); + form.url.value = trim(form.url.value); + form.icon.value = trim(form.icon.value); + form.cat0.value = trim(form.cat0.value); + form.cat1.value = trim(form.cat1.value); + form.cat2.value = trim(form.cat2.value); + form.dsc.value = trimText(form.dsc.value); + form.email.value = trim(form.email.value); + form.addr.value = trim(form.addr.value); + form.tel.value = trim(form.tel.value); + form.fax.value = trim(form.fax.value); + + // Check the site name + if (form.title.value == "") { + alert(_("Please fill in the site name.")); + form.title.focus(); + return false; + } + + // Check the URL + if (form.url.value == "" || form.url.value == "http://") { + alert(_("Please fill in the URL.")); + form.url.focus(); + return false; + } + + // Check the description + if (form.dsc.value == "" || form.dsc.value == _("Fill in the description here.")) { + alert(_("Please fill in the description.")); + form.dsc.focus(); + return false; + } + if (form.dsc.value.length > 256) { + alert(_("This description is too long. (Max. 256 letters)")); + form.dsc.focus(); + return false; + } + + return true; +} + +// clearDscDefault: Clear the default value of the description +function clearDscDefault(dsc, deftext) { + if (dsc.value == deftext) { + dsc.value = ""; + } +} diff --git a/htdocs/wov/scripts/search.js b/htdocs/wov/scripts/search.js new file mode 100644 index 0000000..f0406de --- /dev/null +++ b/htdocs/wov/scripts/search.js @@ -0,0 +1,38 @@ +/* Woman's Voice + * search.js: The full text search related JavaScript subroutines. + */ + +/* Copyright (c) 2004-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2004-11-28 + */ + +// isSearchOK: Check if the query phrase is ready to be submitted +function isSearchOK(form) { + + // Regularize the fields + form.query.value = trim(form.query.value); + + // Check the query phrase + if (form.query.value == "") { + alert(_("Please fill in your query.")); + form.query.focus(); + return false; + } + + return true; +} diff --git a/htdocs/wov/scripts/subscribe.js b/htdocs/wov/scripts/subscribe.js new file mode 100644 index 0000000..b066b4c --- /dev/null +++ b/htdocs/wov/scripts/subscribe.js @@ -0,0 +1,73 @@ +/* Woman's Voice + * subscribe.js: The mailing list subscription related JavaScript subroutines. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-05-18 + */ + +/* isSubOK: is the subscription request OK? */ +function isSubOK(form) { + // Regularize the fields + form.email.value = trim(form.email.value); + if (form.email.value == "") { + alert("請填上收件用的 E-mail 信箱。"); + form.email.focus(); + return false; + } + if (!isEmail(form.email.value)) { + alert("E-mail 有誤,請檢查有沒有拼錯。"); + form.email.focus(); + return false; + } + if (form.pw.value == "") { + alert("請設定密碼。"); + form.pw.focus(); + return false; + } + if (form["pw-conf"].value == "") { + alert("請核對你設定的密碼。"); + form["pw-conf"].focus(); + return false; + } + if (form.pw.value != form["pw-conf"].value) { + alert("核對密碼不符,請重新設定密碼。"); + form.pw.value = ""; + form["pw-conf"].value = ""; + form.pw.focus(); + return false; + } + return true; +} + +/* isOptionsOK: is the options request OK? */ +function isOptionsOK(form) { + // Regularize the fields + form.email.value = trim(form.email.value); + if (form.email.value == "") { + alert("請填上妳的收件 E-mail 信箱。"); + form.email.focus(); + return false; + } + if (!isEmail(form.email.value)) { + alert("E-mail 有誤,請檢查有沒有拼錯。"); + form.email.focus(); + return false; + } + return true; +} diff --git a/htdocs/wov/stylesheets/analog.css b/htdocs/wov/stylesheets/analog.css new file mode 100644 index 0000000..2b37cfd --- /dev/null +++ b/htdocs/wov/stylesheets/analog.css @@ -0,0 +1,24 @@ +/* Woman's Voice + * analog.css: The style sheet for Analog analysis reports. + */ + +/* Copyright (c) 2000-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 2000-11-11 + */ + +@import url("common.css"); diff --git a/htdocs/wov/stylesheets/common.css b/htdocs/wov/stylesheets/common.css new file mode 100644 index 0000000..56a75cc --- /dev/null +++ b/htdocs/wov/stylesheets/common.css @@ -0,0 +1,636 @@ +/* Woman's Voice + * common.css: The common style sheet. + */ + +/* Copyright (c) 1999-2018 imacat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Author: imacat + * First written: 1999-05-24 + */ + +/* General settings */ +body { + background: #FFF8F8 url("../images/backgrnd") scroll; + color: black; + margin: 0; + padding: 0.5em 1em; +} +.body { + padding: 1em; +} +a:link { + background-color: transparent; + color: red; + text-decoration: none; +} +a:visited { + background-color: transparent; + color: maroon; + text-decoration: none; +} +a:active { + background-color: transparent; + color: #400000; + text-decoration: none; +} +a:hover { + background-color: #FFD700; + color: inherit; + text-decoration: underline; +} +h1, h2, h3, h4, h5, h6 { + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-weight: normal; +} +caption { + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-weight: normal; + font-size: 1.44em; +} +dl { + clear: both; + margin: 1em 0 1.5em 2em; +} +dl dt { + margin: 0 0 0.5em 0; + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.44em; +} +dl dd { + margin: 0.5em 0 0.5em 2em; +} +dl dl { + margin: 0; +} +dl dl dt { + margin: 0; + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.2em; +} +dl dl dd { + margin: 0; +} +p { + margin: 0.5em 0 0.5em 0; + text-indent: 0; +} +th { + vertical-align: top; +} +.en { + font-family: Arial, sans-serif; +} +.error { + background-color: transparent; + color: red; + font-weight: bold; + text-align: center; +} +address { + display: block; + font-size: 0.833em; + font-style: italic; + clear: both; +} +hr { + clear: both; +} +form { + margin: 0; +} +.note { + font-size: 0.833em; + font-style: italic; +} +em { + font-style: normal; + font-weight: bolder; +} +q { + quotes: "「" "」" "『" "』"; +} +div.errmsg { + margin: 1em 0.5in; +} +/* The CAPTCHA */ +.trwebsite, .trlastname { + display: none; +} + +/* The title */ +.title img { + float: left; + height: 150px; + width: 100px; +} +.title h1 { + font-family: "華康行書體(P)", DFPXingShu-B5, "DFPXingShu B5", "標楷體", DFKai-SB, "DFKai SB", kai, cursive; + font-size: 3.6em; + margin: 0 0 0 0; +} +.title h1.en { + font-family: "Monotype Corsiva", "Monotype.Corsiva", cursive; +} +.stitle img { + float: left; + height: 75px; + width: 50px; +} +.stitle h1 { + font-family: "華康行書體(P)", DFPXingShu-B5, "DFPXingShu B5", "標楷體", DFKai-SB, "DFKai SB", kai, cursive; + font-size: 3.6em; + margin: 0 0 0 0; +} +.intro { + clear: both; + margin: 1em 15%; +} +.intro p { + text-align: justify; + text-indent: 2em; + margin: 0.5em 0; +} + +/* The navigation bar */ +.navibar, .pagebar, .langs { + text-align: center; + font-size: 0.833em; +} +.navibar .text { + width: 4em; +} +.nav hr { + margin: 0.1em 0; + padding: 0; + height: 0; +} +.nav span { + background-color: #FFE4E1; + color: black; +} +.nav span a { + background-color: #FFE4E1; + color: red; +} + +/* The default list */ +.deflist { + margin: 1em 3em; +} +.deflist th { + white-space: nowrap; +} +.deflist th, .deflist td { + padding: 0.2em 0.5em; + vertical-align: top; +} +.deflist thead { + background-color: silver; + color: black; +} +.deflist tbody th { + font-weight: normal; +} +.deflist .listno, .deflist .listdel { + text-align: center; +} +.deflist .oddrow { + background-color: #FFE0E0; + color: black; +} +.deflist .evenrow { + background-color: #E0E0FF; + color: black; +} +.deflist .amount { + text-align: right; +} +.deflist .amount .neg { + color: red; + background-color: transparent; +} +.deflist .crdtsubj { + text-indent: 2em; +} +.deflist .subjlv2 { + text-indent: 1em; +} +.deflist .subjlastlv { + text-indent: 2em; +} + +/* The default form */ +.defform { + width: 100%; +} +.defform div { + margin: 0 4em; +} +.defform table { + margin: 0; + width: 100%; +} +.defform th, .defform td { + text-align: left; + vertical-align: top; +} +.defform .thfile { + width: 9em; +} +.defform .th { + width: 8.5em; +} +.defform .oldnew { + width: 3.5em; +} +.defform td .text, .defform td textarea { + width: 100%; +} +.defform td .prompt { + font-style: italic; + margin: 0; +} +.defform td ol, .defform td li ul { + margin: 0 0 0 2em; + padding: 0; +} +.defform td ul, .defform td li { + margin: 0; + padding: 0; +} +.defform td ul li { + list-style: none; +} +.defform td .oneline li { + display: block; + float: left; + margin-right: 0.5em; +} +.defform td h4, .defform td .picinfo, .defform td .piccap { + margin: 0; + padding: 0; +} +.defform .amount { + text-align: right; +} + +/* The newsletters */ +.newsletters .index { + margin: 1em 3em; +} +.newsletters .index th { + vertical-align: top; + text-align: left; +} +.newsletters .index h3 { + margin: 0; +} +.newsletters .index ul { + margin: 0; + padding: 0; +} +.newsletters .index ul li { + list-style: none; + margin: 0; + padding: 0; +} +.newsletters .credits { + background-color: white; + border: medium double black; + color: black; + margin: 1em 4em; + padding: 0.3em; + font-size: 0.833em; +} +.newsletters .credits ol { + margin: 0 0 0 2em; + padding: 0; +} +.newsletters .credits ol li { + margin: 0; + padding: 0; +} +.newsletters .article { + margin: 1em 4em 1em 4em; +} +.newsletters .article address { + font-family: "標楷體",cursive,serif; + font-size: 1.2em; + text-align: right; +} +.newsletters .article div { + margin: 1.5em 0 1.5em 0; +} +.newsletters .article h2 { + margin: 1em 0 0 2em; +} +.newsletters .article p { + text-indent: 2em; +} +.newsletters .article blockquote { + margin: 1.5em 3em; +} +.newsletters .article blockquote p.first:before { + content: "「"; +} +.newsletters .article blockquote p.last:after { + content: "」"; +} +.newsletters .article blockquote q { + quotes: "『" "』" "「" "」"; +} +.newsletters .article table th, .newsletters .article table td { + text-align: left; + vertical-align: top; + padding: 0.2em 0.5em; +} + +/* The guestbook */ +.guestbook .defform { + margin: 1em 3em; + padding: 0 10%; + width: 100%; +} +/* Refer to http://www.w3.org/Style/threepart-f.css */ +/* The child selectors are a hack to hide these rules from WinIE6 */ +.guestbook .body>form.defform { + width: auto; +} +.guestbook .defform p { + text-indent: 0; + margin: 0; +} +.guestbook .defform table { + margin: 0 auto; + width: 100%; +} +.guestbook .defform th { + text-align: left; + vertical-align: top; + width: 5.5em; +} +.guestbook .defform td { + vertical-align: top; +} +.guestbook .defform .text, .guestbook .defform textarea { + font-size: 1em; + width: 100%; +} +.guestbook .defform .prompt { + font-style: italic; + font-size: 0.833em; +} +.guestbook .entries { + margin: 0 2em; +} +.guestbook .entry { + margin: 1em 1em; +} +.guestbook .entry div { + margin: 1em 0; +} +.guestbook .entry address { + text-align: right; +} +.guestbook .entry address cite { + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.44em; + font-style: normal; +} +.guestbook .entry address :lang(en) { + font-family: "Times New Roman", "Times.New.Roman", times, serif; +} +.guestbook .entry address samp { + font-style: normal; + vertical-align: text-bottom; +} + +/* The breadcrumb trail */ +.breadcrumb { + clear: both; + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.44em; +} + +/* The related links */ +.links .linkslist { + clear: both; + margin: 0.5em 0.5in; +} +.links .linkslist li { + margin: 1em 0; +} +.links .linkslist li img { + vertical-align: top; + border: none; +} +.links .linkslist li cite { + font-family: "標楷體", DFKai-SB, "DFKai SB", kai, serif; + font-size: 1.2em; + font-style: normal; +} +.links .regform { + margin: 1em 10%; + width: 100%; +} +/* Refer to http://www.w3.org/Style/threepart-f.css */ +/* The child selectors are a hack to hide these rules from WinIE6 */ +.links .body>form.regform { + width: auto; +} +.links .regform table { + margin: 0; + width: 100%; +} +.links .regform th { + text-align: left; + vertical-align: top; + width: 8em; +} +.links .regform input.text, .links .regform textarea { + width: 100%; +} + +/* The full text search */ +.searchresult em { + background-color: #FFE0E0; + color: red; +} +.searchresult h3 { + margin: 0; +} +.searchresult li { + margin-bottom: 1em; +} + +/* The home page */ +.home .nav { + float: left; + padding: 0; + margin: 0 0 1em 0; + text-align: center; + width: 49%; +} +.home .nav .accessguide { + float: none; + text-align: left; + width: 100%; +} +.home .nav .nav1 { + display: table; + margin: 0 auto; + width: 10em; +} +.home .nav ul { + margin: 0; + padding: 0; +} +.home .nav ul li { + list-style-type: none; + background-color: #FFC0C0; + color: #000000; + margin: 0 0 0.8em 0; + padding: 0.3em 1em; + text-align: left; +} +.home .nav form .text { + width: 7em; +} +.home .bulletin { + border-width: thin thick thick thin; + border-style: solid; + background-color: white; + color: black; + float: right; + width: 50%; + margin: 0 0 1em 0; +} +.home .bulletin .bulletin1 { + padding: 1em; +} +.home .bulletin p { + text-indent: 2em; +} +.home .bulletin h2 { + text-align: center; +} + +/* The accessibility guides */ +.skiptobody { + position: absolute; + line-height: 0; + left: 0; + top: 0; + z-index: -9; +} +.accessguide { + float: left; + font-size: 0.5em; + color: #FFFFFF; +} + +/* The preview mark */ +.previewmark { + position: fixed; + top: 1em; + left: 1em; + border: thick solid red; + color: red; + background-color: transparent; + margin: 0; + padding: 0.5em; +} +.previewmark h2 { + text-transform: uppercase; + text-align: center; + margin: 0; + padding: 0; +} +.previewmark p { + margin: 0; + padding: 0; + text-indent: 0; +} +.previewmark a, .previewmark a:visited, .previewmark a:hover { + color: red; + background-color: transparent; +} + +/* The footer */ +.footer { + clear: both; + font-size: 0.833em; + text-align: center; +} +.footer p { + margin: 0; + text-indent: 0; +} +.footer img { + border-style: none; + height: 31px; + width: 88px; +} +.footer .modperl img { + height: 30px; + width: 110px; +} +.footer .linkcode { + border-width: thin thick thick thin; + border-style: solid; + background-color: white; + color: black; + display: table; + font-size: 1em; + margin: 0 auto; + padding: 0.5em; + text-align: left; + display: table; + width: 28em; +} + +/* The split table of contents */ +.splittoc { + width: 90%; + margin: 1em 5%; +} +.tocl { + float: left; + width: 45%; +} +.tocl ul { + float: right; + margin: 0; + padding: 0; +} +.tocr { + float: right; + width: 45%; +} +.tocr ul { + float: left; + margin: 0; + padding: 0; +} +.splittoc ul li { + background-color: #FFC0C0; + color: #000000; + list-style-type: none; + margin: 0.8em 0; + padding: 0.3em 1em; + text-align: left; + width: 11em; +} diff --git a/htdocs/wov/subscribe.html.html b/htdocs/wov/subscribe.html.html new file mode 120000 index 0000000..d27066a --- /dev/null +++ b/htdocs/wov/subscribe.html.html @@ -0,0 +1 @@ +subscribe.html.xhtml \ No newline at end of file diff --git a/htdocs/wov/subscribe.html.xhtml b/htdocs/wov/subscribe.html.xhtml new file mode 100644 index 0000000..9568ca0 --- /dev/null +++ b/htdocs/wov/subscribe.html.xhtml @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + +訂閱女聲 + + + + + + + +
    + +
    + + +
    +女聲 LOGO +

    訂閱女聲

    +

    Subscription

    +
    + +
    +
    訂閱《女聲》
    +
    +
    +

    請填上妳的 E-mail 收件信箱,並設定一個密碼,以供日後核對身份,更改設定。不要和提款卡、信用卡用同一個密碼,以免被欄截盜用。

    + +
    +
    + + + + +
    +
    +
    +
    + + +
    +
    訂戶設定
    +
    +
    +

    若妳是現有訂戶,要變更信箱、索取密碼、變更密碼、暫停收信、退訂……等等,請在下方填上妳的 E-mail 信箱:

    + +
    + +
    +
    +
    +
    + + +
    +
    《女聲》隱私權聲明
    +
    +

    《女聲》編輯室尊重網路隱私權與匿名權。妳在《女聲》電子報網站上填的 E-mail 信箱,除寄發《女聲》電子報外,不作任何用途。妳可以隨時訂閱∕退訂。退訂後,我們不會保留妳的訂閱資料。

    +
    +
    + +
    + +
    + + + + diff --git a/icons/icon_asp.png b/icons/icon_asp.png new file mode 100644 index 0000000..b88000b Binary files /dev/null and b/icons/icon_asp.png differ diff --git a/icons/icon_back.png b/icons/icon_back.png new file mode 100644 index 0000000..9e71068 Binary files /dev/null and b/icons/icon_back.png differ diff --git a/icons/icon_blank.png b/icons/icon_blank.png new file mode 100644 index 0000000..c8e718d Binary files /dev/null and b/icons/icon_blank.png differ diff --git a/icons/icon_bmp.png b/icons/icon_bmp.png new file mode 100644 index 0000000..a0e2783 Binary files /dev/null and b/icons/icon_bmp.png differ diff --git a/icons/icon_cab.png b/icons/icon_cab.png new file mode 100644 index 0000000..37395ae Binary files /dev/null and b/icons/icon_cab.png differ diff --git a/icons/icon_crt.png b/icons/icon_crt.png new file mode 100644 index 0000000..bff01e4 Binary files /dev/null and b/icons/icon_crt.png differ diff --git a/icons/icon_css.png b/icons/icon_css.png new file mode 100644 index 0000000..fe89c5c Binary files /dev/null and b/icons/icon_css.png differ diff --git a/icons/icon_csv.png b/icons/icon_csv.png new file mode 100644 index 0000000..97b6e11 Binary files /dev/null and b/icons/icon_csv.png differ diff --git a/icons/icon_dat.png b/icons/icon_dat.png new file mode 100644 index 0000000..230c2a1 Binary files /dev/null and b/icons/icon_dat.png differ diff --git a/icons/icon_desc.png b/icons/icon_desc.png new file mode 100644 index 0000000..e433dfb Binary files /dev/null and b/icons/icon_desc.png differ diff --git a/icons/icon_dir.png b/icons/icon_dir.png new file mode 100644 index 0000000..2639789 Binary files /dev/null and b/icons/icon_dir.png differ diff --git a/icons/icon_dll.png b/icons/icon_dll.png new file mode 100644 index 0000000..e63bb0b Binary files /dev/null and b/icons/icon_dll.png differ diff --git a/icons/icon_doc.png b/icons/icon_doc.png new file mode 100644 index 0000000..f8cc1f5 Binary files /dev/null and b/icons/icon_doc.png differ diff --git a/icons/icon_dot.png b/icons/icon_dot.png new file mode 100644 index 0000000..2a1a36a Binary files /dev/null and b/icons/icon_dot.png differ diff --git a/icons/icon_exe.png b/icons/icon_exe.png new file mode 100644 index 0000000..7fcd0c2 Binary files /dev/null and b/icons/icon_exe.png differ diff --git a/icons/icon_gif.png b/icons/icon_gif.png new file mode 100644 index 0000000..0d0370f Binary files /dev/null and b/icons/icon_gif.png differ diff --git a/icons/icon_hlp.png b/icons/icon_hlp.png new file mode 100644 index 0000000..abe2c0e Binary files /dev/null and b/icons/icon_hlp.png differ diff --git a/icons/icon_html.png b/icons/icon_html.png new file mode 100644 index 0000000..8f01d19 Binary files /dev/null and b/icons/icon_html.png differ diff --git a/icons/icon_ini.png b/icons/icon_ini.png new file mode 100644 index 0000000..ef69e34 Binary files /dev/null and b/icons/icon_ini.png differ diff --git a/icons/icon_jpeg.png b/icons/icon_jpeg.png new file mode 100644 index 0000000..b39a426 Binary files /dev/null and b/icons/icon_jpeg.png differ diff --git a/icons/icon_js.png b/icons/icon_js.png new file mode 100644 index 0000000..bdcf206 Binary files /dev/null and b/icons/icon_js.png differ diff --git a/icons/icon_mdb.png b/icons/icon_mdb.png new file mode 100644 index 0000000..3e5cf52 Binary files /dev/null and b/icons/icon_mdb.png differ diff --git a/icons/icon_misc.png b/icons/icon_misc.png new file mode 100644 index 0000000..cce2014 Binary files /dev/null and b/icons/icon_misc.png differ diff --git a/icons/icon_mp3.png b/icons/icon_mp3.png new file mode 100644 index 0000000..86ac7af Binary files /dev/null and b/icons/icon_mp3.png differ diff --git a/icons/icon_msi.png b/icons/icon_msi.png new file mode 100644 index 0000000..94813aa Binary files /dev/null and b/icons/icon_msi.png differ diff --git a/icons/icon_pdf.png b/icons/icon_pdf.png new file mode 100644 index 0000000..0da29c8 Binary files /dev/null and b/icons/icon_pdf.png differ diff --git a/icons/icon_perl.png b/icons/icon_perl.png new file mode 100644 index 0000000..67866ec Binary files /dev/null and b/icons/icon_perl.png differ diff --git a/icons/icon_png.png b/icons/icon_png.png new file mode 100644 index 0000000..856d4af Binary files /dev/null and b/icons/icon_png.png differ diff --git a/icons/icon_rar.png b/icons/icon_rar.png new file mode 100644 index 0000000..8cd0660 Binary files /dev/null and b/icons/icon_rar.png differ diff --git a/icons/icon_setup.png b/icons/icon_setup.png new file mode 100644 index 0000000..224e7a6 Binary files /dev/null and b/icons/icon_setup.png differ diff --git a/icons/icon_tiff.png b/icons/icon_tiff.png new file mode 100644 index 0000000..accfd6b Binary files /dev/null and b/icons/icon_tiff.png differ diff --git a/icons/icon_txt.png b/icons/icon_txt.png new file mode 100644 index 0000000..cb6bdbd Binary files /dev/null and b/icons/icon_txt.png differ diff --git a/icons/icon_zip.png b/icons/icon_zip.png new file mode 100644 index 0000000..8dcbaa6 Binary files /dev/null and b/icons/icon_zip.png differ diff --git a/lib/i686 b/lib/i686 new file mode 120000 index 0000000..fd32fa4 --- /dev/null +++ b/lib/i686 @@ -0,0 +1 @@ +i386 \ No newline at end of file diff --git a/lib/perl5/Selima.pm b/lib/perl5/Selima.pm new file mode 100644 index 0000000..e3eb9f1 --- /dev/null +++ b/lib/perl5/Selima.pm @@ -0,0 +1,171 @@ +# Selima Website Content Management System +# Selima.pm: Selima Website Content Management System + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-23 + +package Selima; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw($VERSION @EXPORT @EXPORT_OK); +$VERSION = "3.10"; +@EXPORT = qw(); + +# Import the subroutines +use Selima::A2HTML; +push @EXPORT, @Selima::A2HTML::EXPORT; +use Selima::AbsURI; +push @EXPORT, @Selima::AbsURI::EXPORT; +use Selima::Accounting; +push @EXPORT, @Selima::Accounting::EXPORT; +use Selima::AddGet; +push @EXPORT, @Selima::AddGet::EXPORT; +use Selima::AltLang; +push @EXPORT, @Selima::AltLang::EXPORT; +use Selima::Array; +push @EXPORT, @Selima::Array::EXPORT; +use Selima::Cache qw(); +push @EXPORT, @Selima::Cache::EXPORT; +use Selima::CallForm; +push @EXPORT, @Selima::CallForm::EXPORT; +use Selima::ChkFunc; +push @EXPORT, @Selima::ChkFunc::EXPORT; +use Selima::ChkPriv; +push @EXPORT, @Selima::ChkPriv::EXPORT; +use Selima::ChkWrite; +push @EXPORT, @Selima::ChkWrite::EXPORT; +use Selima::CommText; +push @EXPORT, @Selima::CommText::EXPORT; +use Selima::CopyYear; +push @EXPORT, @Selima::CopyYear::EXPORT; +use Selima::Country; +push @EXPORT, @Selima::Country::EXPORT; +use Selima::DataVars qw(:all); +push @EXPORT, @Selima::DataVars::EXPORT_OK; +use Selima::DBILogin; +push @EXPORT, @Selima::DBILogin::EXPORT; +use Selima::DecForm; +push @EXPORT, @Selima::DecForm::EXPORT; +use Selima::EchoForm; +push @EXPORT, @Selima::EchoForm::EXPORT; +use Selima::Encrypt; +push @EXPORT, @Selima::Encrypt::EXPORT; +use Selima::ErrMsg; +push @EXPORT, @Selima::ErrMsg::EXPORT; +use Selima::FetchRec; +push @EXPORT, @Selima::FetchRec::EXPORT; +use Selima::FormFunc; +push @EXPORT, @Selima::FormFunc::EXPORT; +use Selima::Format; +push @EXPORT, @Selima::Format::EXPORT; +use Selima::GeoIP; +push @EXPORT, @Selima::GeoIP::EXPORT; +use Selima::GetLang; +push @EXPORT, @Selima::GetLang::EXPORT; +use Selima::Guest; +push @EXPORT, @Selima::Guest::EXPORT; +use Selima::Guestbook; +push @EXPORT, @Selima::Guestbook::EXPORT; +use Selima::HTTP; +push @EXPORT, @Selima::HTTP::EXPORT; +use Selima::HTTPS; +push @EXPORT, @Selima::HTTPS::EXPORT; +use Selima::Init; +push @EXPORT, @Selima::Init::EXPORT; +use Selima::Links; +push @EXPORT, @Selima::Links::EXPORT; +use Selima::ListFunc; +push @EXPORT, @Selima::ListFunc::EXPORT; +use Selima::ListPref; +push @EXPORT, @Selima::ListPref::EXPORT; +use Selima::LnInfo; +push @EXPORT, @Selima::LnInfo::EXPORT; +use Selima::Logging; +push @EXPORT, @Selima::Logging::EXPORT; +use Selima::LogIn; +push @EXPORT, @Selima::LogIn::EXPORT; +use Selima::LogOut; +push @EXPORT, @Selima::LogOut::EXPORT; +use Selima::LastModf; +push @EXPORT, @Selima::LastModf::EXPORT; +use Selima::MarkAbbr; +push @EXPORT, @Selima::MarkAbbr::EXPORT; +use Selima::MkAllDir; +push @EXPORT, @Selima::MkAllDir::EXPORT; +use Selima::MungAddr; +push @EXPORT, @Selima::MungAddr::EXPORT; +use Selima::NewSN; +push @EXPORT, @Selima::NewSN::EXPORT; +use Selima::PageFunc; +push @EXPORT, @Selima::Page::EXPORT; +use Selima::Page2Rel; +push @EXPORT, @Selima::Page2Rel::EXPORT; +use Selima::Passwd; +push @EXPORT, @Selima::Passwd::EXPORT; +use Selima::Picture; +push @EXPORT, @Selima::Picture::EXPORT; +use Selima::Preview; +push @EXPORT, @Selima::Preview::EXPORT; +use Selima::Query; +push @EXPORT, @Selima::Query::EXPORT; +use Selima::RelURI; +push @EXPORT, @Selima::RelURI::EXPORT; +use Selima::RemoHost; +push @EXPORT, @Selima::RemoHost::EXPORT; +use Selima::ReqURI; +push @EXPORT, @Selima::ReqURI::EXPORT; +use Selima::ScptPriv; +push @EXPORT, @Selima::ScptPriv::EXPORT; +use Selima::SetL10N; +push @EXPORT, @Selima::SetL10N::EXPORT; +use Selima::Server; +push @EXPORT, @Selima::Server::EXPORT; +use Selima::ShortCut; +push @EXPORT, @Selima::ShortCut::EXPORT; +use Selima::Unauth; +push @EXPORT, @Selima::Unauth::EXPORT; +use Selima::Unicode; +push @EXPORT, @Selima::Unicode::EXPORT; +use Selima::UserName; +push @EXPORT, @Selima::UserName::EXPORT; +use Selima::UserPref; +push @EXPORT, @Selima::UserPref::EXPORT; +use Selima::XFileIO; +push @EXPORT, @Selima::XFileIO::EXPORT; + +# Pre-load :flock symbles +use Fcntl qw(:flock); +push @EXPORT, qw(LOCK_SH LOCK_EX LOCK_NB LOCK_UN); + +@EXPORT_OK = @EXPORT; + +# Load the classes +use Selima::AddCol; +use Selima::L10N; +use Selima::List; +use Selima::Checker; +use Selima::DBI; +use Selima::Destroy; +use Selima::Form; +use Selima::Mail; +use Selima::Page; +use Selima::Processor; +use Selima::Session; + +return 1; diff --git a/lib/perl5/Selima/A2HTML.pm b/lib/perl5/Selima/A2HTML.pm new file mode 100644 index 0000000..df565c7 --- /dev/null +++ b/lib/perl5/Selima/A2HTML.pm @@ -0,0 +1,101 @@ +# Selima Website Content Management System +# A2HTML.pm: The text to HTML converter. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-24 + +package Selima::A2HTML; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(a2html); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub a2html($); +} + +use Email::Find qw(); +use URI::Find qw(); + +use Selima::MarkAbbr; +use Selima::MungAddr; +use Selima::ShortCut; +use Selima::Unicode; + +use vars qw(%SUBST $TEXT $uri_finder $email_finder); +$uri_finder = new URI::Find( \&uri_subst ); +$email_finder = new Email::Find( \&email_subst ); + +# a2html: Convert a textarea input into HTML content +sub a2html($) { + local ($_, %_); + $TEXT = $_[0]; + + # Clear the registry + %SUBST = qw(); + # Strip the URLs + $uri_finder->find(\$TEXT); + # Strip the e-mails + $email_finder->find(\$TEXT); + # Escape the HTML characters and mark the abbreviation + $TEXT = h_abbr($TEXT); + # Return the substitutied URLs and e-mails as links + $TEXT =~ s/(\[subst:(\d{9})\])/exists $SUBST{$2}? $SUBST{$2}: $1;/ge; + # Normal text-to-HTML substitution + $TEXT =~ s/^ / /mg; + $TEXT =~ s/ /  /g; + $TEXT =~ s/\n/
    \n/g; + + return $TEXT; +} + +# uri_subst: Substitute an URL in the content +sub uri_subst { + local ($_, %_); + my ($uri, $uritext); + ($uri, $uritext) = @_; + do { + # Generate a random serial number + $_ = 100000000 + int rand 900000000; + } until $TEXT !~ /\[subst:$_\]/; + # Register this URI + $SUBST{$_} = "" + . mung_email_span(h($uritext)) . ""; + # Return the substitution + return "[subst:$_]"; +} + +# email_subst: Substitute an e-mail in the content +sub email_subst { + local ($_, %_); + my ($email, $emailtext); + ($email, $emailtext) = @_; + do { + # Generate a random serial number + $_ = 100000000 + int rand 900000000; + } until $TEXT !~ /\[subst:$_\]/; + # Register this URI + $SUBST{$_} = "format) . "\">" + . mung_email_span(h($emailtext)) . ""; + # Return the substitution + return "[subst:$_]"; +} + +return 1; diff --git a/lib/perl5/Selima/AbsURI.pm b/lib/perl5/Selima/AbsURI.pm new file mode 100644 index 0000000..7ca3ab1 --- /dev/null +++ b/lib/perl5/Selima/AbsURI.pm @@ -0,0 +1,57 @@ +# Selima Website Content Management System +# AbsURI.pm: The converter to turn all URIs to absolute URIs. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-26 + +package Selima::AbsURI; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(absuri); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub absuri($;$$); +} + +use URI qw(); + +use Selima::DataVars qw(:requri); + +# absuri: Convert and colonicalize to an absolute URI +sub absuri($;$$) { + local ($_, %_); + my ($uri, $base, $skip_fragment); + ($uri, $base, $skip_fragment) = @_; + + # Default base to $REQUEST_FULLURI + $base = defined $base? new URI($base): $REQUEST_FULLURI; + # Skip the fragment + return $uri if $skip_fragment && $uri =~ /^#/; + # Absolute path -- add the root difference + $uri = "$ROOT_DIFF$uri" if $uri =~ /^\//; + $uri = new URI($uri); + # Obtain the absolute URI + $uri = $uri->abs($base); + + return $uri->canonical; +} + +return 1; diff --git a/lib/perl5/Selima/Accounting.pm b/lib/perl5/Selima/Accounting.pm new file mode 100644 index 0000000..c3ad380 --- /dev/null +++ b/lib/perl5/Selima/Accounting.pm @@ -0,0 +1,294 @@ +# Selima Website Content Management System +# Accounting.pm: The accounting subroutines. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-20 + +package Selima::Accounting; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(acctsubj_title acctsubj_code acctsubj_sn); +push @EXPORT, qw(acctsubj_recent_options accttrx_id accttrxid_compose); +push @EXPORT, qw(accttrx_maxord); +push @EXPORT, qw(ACCTSUBJ_CASH ACCTSUBJ_INCOME_ACUM ACCTSUBJ_INCOME_CUR); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub acctsubj_title($); +sub acctsubj_code($); +sub acctsubj_sn($); +sub acctsubj_recent_options($); +sub accttrx_id($); +sub accttrxid_compose($$); +sub accttrx_maxord(;$$); +} + +use Selima::Cache qw(:account); +use Selima::ChkFunc; +use Selima::CommText; +use Selima::DataVars qw($DBH :l10n :lninfo); +use Selima::EchoForm; +use Selima::GetLang; +use Selima::LnInfo; + +# Certain subjects +use constant ACCTSUBJ_CASH => 1111; # 1111 庫存現金 +use constant ACCTSUBJ_INCOME_ACUM => 3351; # 3351 累積盈虧 +use constant ACCTSUBJ_INCOME_CUR => 3353; # 3353 本期損益 + +# acctsubj_title: Obtain an accounting subject title +sub acctsubj_title($) { + local ($_, %_); + my ($sn, $sql, $sth, $col); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + # Return the cache + return $Account_acctsubj_title{$sn} if exists $Account_acctsubj_title{$sn}; + + # Check the serial number first + return ($Account_acctsubj_title{$sn} = t_na) + if !check_sn $sn; + + # Query + # Unilingual + if (@ALL_LINGUAS == 1) { + $col = "acctsubj_codetitle($sn) AS title"; + # Multilingual + } else { + $_ = getlang; + $col = "acctsubj_codetitle('$_', $sn) AS title"; + } + $sql = "SELECT $col;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return ($Account_acctsubj_title{$sn} = t_na) + unless $sth->rows == 1; + + # Found + return ($Account_acctsubj_title{$sn} = ${$sth->fetch}[0]); +} + +# acctsubj_code: Obtain an accounting subject code +sub acctsubj_code($) { + local ($_, %_); + my ($sn, $sql, $sth, $col); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + # Return the cache + return $Account_acctsubj_code{$sn} if exists $Account_acctsubj_code{$sn}; + + # Check the serial number first + return ($Account_acctsubj_code{$sn} = t_na) + if !check_sn $sn; + + # Query + $sql = "SELECT code FROM acctsubj WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return ($Account_acctsubj_code{$sn} = t_na) + unless $sth->rows == 1; + + # Found + return ($Account_acctsubj_code{$sn} = ${$sth->fetch}[0]); +} + +# acctsubj_sn: Obtain an accounting subject S/N +sub acctsubj_sn($) { + local ($_, %_); + my ($code, $sql, $sth, $col); + $code = $_[0]; + # Bounce if there is any problem with $code + return t_notset if !defined $code; + # Return the cache + return $Account_acctsubj_sn{$code} if exists $Account_acctsubj_sn{$code}; + + # Query + $sql = "SELECT sn FROM acctsubj" + . " WHERE code=" . $DBH->quote($code) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return ($Account_acctsubj_sn{$code} = t_na) + unless $sth->rows == 1; + + # Found + return ($Account_acctsubj_sn{$code} = ${$sth->fetch}[0]); +} + +# acctsubj_recent_options: Obtain a recently-used accounting subject options list +sub acctsubj_recent_options($) { + local ($_, %_); + my ($value, $sql, $content); + my ($sth, $count, $row, @opts, $hascur, $optlist); + $value = $_[0]; + + # Obtain the recently-used options + # Unilingual + if (@ALL_LINGUAS == 1) { + $content = "acctsubj_codetitle(subj) AS content"; + # Multilingual + } else { + $_ = getlang; + $content = "acctsubj_codetitle('$_', subj) AS content"; + } + $sql = "SELECT subj AS value, $content FROM acctrecs" + . " GROUP BY subj" + . " ORDER BY acctsubj_recent(subj) DESC;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @opts = qw(), $hascur = 0; $i < $count; $i++) { + $row = $sth->fetchrow_hashref; + push @opts, { + "value" => $$row{"value"}, + "content" => $$row{"content"}, + }; + $hascur = 1 if defined $value && $$row{"value"} eq $value; + } + undef $sth; + + # Prepend the currently selected option if available + if (!$hascur && defined $value && check_sn $value) { + # Unilingual + if (@ALL_LINGUAS == 1) { + $content = "acctsubj_codetitle($value) AS content"; + # Multilingual + } else { + $_ = getlang; + $content = "acctsubj_codetitle('$_', $value) AS content"; + } + $sql = "SELECT $content;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + if ($sth->rows > 0) { + $row = $sth->fetchrow_hashref; + @opts = ({ + "value" => $value, + "content" => $$row{"content"}, + }, @opts); + } + undef $sth; + } + + # Obtain the HTML + $optlist = opt_list_array @opts; + + return preselect_options $optlist, $value; +} + +# accttrx_id: Obtain the accounting transaction ID. +sub accttrx_id($) { + local ($_, %_); + my ($sn, $sql, $sth, $col, $row); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + # Return the cache + return $Account_accttrx_id{$sn} if exists $Account_accttrx_id{$sn}; + + # Check the serial number first + return ($Account_accttrx_id{$sn} = t_na) + if !check_sn $sn; + + # Query + $sql = "SELECT date, ord FROM accttrx WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return ($Account_accttrx_id{$sn} = t_na) + unless $sth->rows == 1; + + # Found + $row = $sth->fetchrow_hashref; + return ($Account_accttrx_id{$sn} = accttrxid_compose $$row{"date"}, $$row{"ord"}); +} + +# accttrxid_compose: Compose the accounting transaction ID +sub accttrxid_compose($$) { + local ($_, %_); + my ($date, $ord); + ($date, $ord) = @_; + # In timestamp + if ($date =~ /^\d+$/) { + @_ = localtime $date; + $_[5] += 1900; + $_[4]++; + return sprintf "%04d%02d%02d%02d", @_[5,4,3], $ord; + } + # In ISO date YYYY-MM-DD format + return sprintf "%04d%02d%02d%02d", $1, $2, $3, $ord + if $date =~ /^(\d{4})-(\d{2})-(\d{2})$/; + # Invalid date + return undef; +} + +# accttrx_maxord: Obtain the default accounting transaction order +sub accttrx_maxord(;$$) { + local ($_, %_); + my ($date, $sn, $sql, $sth, $row); + ($date, $sn) = @_; + $date = time if !defined $date; + $sn = -1 if @_ < 2; + # In timestamp + if ($date =~ /^\d+$/) { + @_ = localtime $date; + $_[5] += 1900; + $_[4]++; + $date = sprintf "%04d-%02d-%02d", @_[5,4,3]; + # In ISO date YYYY-MM-DD format + } elsif ($date =~ /^(\d{4})-(\d{2})-(\d{2})$/) { + # Invalid date + } else { + return 99; + } + # Bounce if there is any problem with $sn + return 99 if !defined $sn; + # Return the cache + $Account_accttrx_id{$date} = {} if !exists $Account_accttrx_id{$date}; + return ${$Account_accttrx_id{$date}}{$sn} + if exists ${$Account_accttrx_id{$date}}{$sn}; + + # Check the serial number first + return (${$Account_accttrx_id{$date}}{$sn} = 99) + if $sn != -1 && !check_sn $sn; + + # Query + @_ = qw(); + push @_, "date=" . $DBH->quote($date); + push @_, "sn!=$sn" if $sn != -1; + $sql = "SELECT count(*) AS count FROM accttrx" + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + $row = $sth->fetchrow_hashref; + return (${$Account_accttrx_id{$date}}{$sn} = $$row{"count"} + 1); +} + +return 1; diff --git a/lib/perl5/Selima/AddCol.pm b/lib/perl5/Selima/AddCol.pm new file mode 100644 index 0000000..8c622e5 --- /dev/null +++ b/lib/perl5/Selima/AddCol.pm @@ -0,0 +1,872 @@ +# Selima Website Content Management System +# AddCol.pm: The data collector/handler for SQL/XML/CSV data output ("Model"). + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-26 + +package Selima::AddCol; +use 5.008; +use strict; +use warnings; + +use Date::Parse qw(str2time); +use Digest::MD5 qw(md5_hex); +use Encode qw(encode decode is_utf8 FB_CROAK); + +use Selima::Array; +use Selima::DataVars qw($DBH :addcol :input :lninfo); +use Selima::Format; +use Selima::GetLang; +use Selima::LogIn; +use Selima::Picture; +use Selima::ShortCut; + +use constant TYPE_NULL => 0; +use constant TYPE_NUM => 1; +use constant TYPE_STR => 2; +use constant TYPE_DATE => 3; +use constant TYPE_IPADDR => 4; +use constant TYPE_FILE => 5; +use constant TYPE_BOOL => 6; +use constant TYPE_EXPR => 7; + +# Prototype declaration +sub valout_sql($); +sub valout_xml($); +sub valout_csv($); + +# new: Initialize the columns deposit +sub new : method { + local ($_, %_); + my ($class, $table, $optype, $self); + ($class, $table, $optype) = @_; + $optype = ADDCOL_UPDATE if !defined $optype; + $self = bless {}, $class; + $self->{"cols"} = []; + $self->{"table"} = $table; + $self->{"optype"} = $optype; + if (defined $DBH) { + $self->{"allcols"} = [$DBH->cols($table)]; + $self->{"mlcols"} = [$DBH->cols_ml($table)]; + } else { + $self->{"allcols"} = []; + $self->{"mlcols"} = []; + } + return $self; +} + +# addstr: Add a modified string column to the columns deposit +# Input: $name: The column name. +# $val: The column value. +# $curval: The current value to be compared. +sub addstr : method { + local ($_, %_); + my ($self, $name, $val, $curval, $cur_exists, %col); + ($self, $name, $val, $curval) = @_; + $cur_exists = (scalar(@_) == 4); + $curval = decode("UTF-8", $curval, FB_CROAK) if !defined $DBH; + # Adjust the column name for multi-lingual columns + $name .= "_" . getlang LN_DATABASE + if in_array($name, @{$self->{"mlcols"}}); + + # The new column value + %col = qw(); + $col{"name"} = $name; + $col{"mod"} = 0; + # No value is supplied + if (!defined $val || $val eq "") { + $col{"type"} = TYPE_NULL; + $col{"value"} = undef; + # A valid value + } else { + $col{"type"} = TYPE_STR; + $col{"value"} = $val; + } + + # Check if we should set it + if ($self->{"optype"} == ADDCOL_INSERT) { + # Always set the value for INSERT + $col{"mod"} = 1; + + } else { + # A current value is supplied + if ($cur_exists) { + # This column had a value previously + if (defined $curval) { + # It has no value now. Remove it. + if ($col{"type"} == TYPE_NULL) { + $col{"mod"} = 1; + # A different new value. Modify it. + } elsif ($col{"value"} ne $curval) { + $col{"mod"} = 1; + } + # This column had no value previously + } else { + # But it has a value now. + if ($col{"type"} != TYPE_NULL) { + $col{"mod"} = 1; + } + } + # No current value to compare with. + } else { + # Set it anyway + $col{"mod"} = 1; + } + } + # Check if we should set it + # Add this column + push @{$self->{"cols"}}, {%col}; + return; +} + +# addstr_empty: Add a modified string column to the columns deposit, +# where empty string is allowed +# Input: $name: The column name. +# $val: The column value. +# $curval: The current value to be compared. +sub addstr_empty : method { + local ($_, %_); + my ($self, $name, $val, $curval, $cur_exists, %col); + ($self, $name, $val, $curval) = @_; + $cur_exists = (scalar(@_) == 4); + $curval = decode("UTF-8", $curval, FB_CROAK) if !defined $DBH; + # Adjust the column name for multi-lingual columns + $name .= "_" . getlang LN_DATABASE + if in_array($name, @{$self->{"mlcols"}}); + + # The new column value + %col = qw(); + $col{"name"} = $name; + $col{"mod"} = 0; + # No value is supplied + if (!defined $val) { + $col{"type"} = TYPE_NULL; + $col{"value"} = undef; + # A valid value + } else { + $col{"type"} = TYPE_STR; + $col{"value"} = $val; + } + + # Check if we should set it + if ($self->{"optype"} == ADDCOL_INSERT) { + # Always set the value for INSERT + $col{"mod"} = 1; + + } else { + # A current value is supplied + if ($cur_exists) { + # This column had a value previously + if (defined $curval) { + # It has no value now. Remove it. + if ($col{"type"} == TYPE_NULL) { + $col{"mod"} = 1; + # A different new value. Modify it. + } elsif ($col{"value"} ne $curval) { + $col{"mod"} = 1; + } + # This column had no value previously + } else { + # But it has a value now. + if ($col{"type"} != TYPE_NULL) { + $col{"mod"} = 1; + } + } + # No current value to compare with. + } else { + # Set it anyway + $col{"mod"} = 1; + } + } + # Check if we should set it + # Add this column + push @{$self->{"cols"}}, {%col}; + return; +} + +# addurl: Add a modified URL to the columns deposit, +# where "http://" also means empty +# Input: $name: The column name. +# $val: The column value. +# $curval: The current value to be compared. +sub addurl : method { + local ($_, %_); + my ($self, $name, $val, $curval, $cur_exists, %col); + ($self, $name, $val, $curval) = @_; + $cur_exists = (scalar(@_) == 4); + $curval = decode("UTF-8", $curval, FB_CROAK) if !defined $DBH; + # Adjust the column name for multi-lingual columns + $name .= "_" . getlang LN_DATABASE + if in_array($name, @{$self->{"mlcols"}}); + + # The new column value + %col = qw(); + $col{"name"} = $name; + $col{"mod"} = 0; + # No value is supplied + if (!defined $val || $val eq "" || $val eq "http://") { + $col{"type"} = TYPE_NULL; + $col{"value"} = undef; + # A valid value + } else { + $col{"type"} = TYPE_STR; + $col{"value"} = $val; + } + + # Check if we should set it + if ($self->{"optype"} == ADDCOL_INSERT) { + # Always set the value for INSERT + $col{"mod"} = 1; + + } else { + # A current value is supplied + if ($cur_exists) { + # This column had a value previously + if (defined $curval) { + # It has no value now. Remove it. + if ($col{"type"} == TYPE_NULL) { + $col{"mod"} = 1; + # A different new value. Modify it. + } elsif ($col{"value"} ne $curval) { + $col{"mod"} = 1; + } + # This column had no value previously + } else { + # But it has a value now. + if ($col{"type"} != TYPE_NULL) { + $col{"mod"} = 1; + } + } + # No current value to compare with. + } else { + # Set it anyway + $col{"mod"} = 1; + } + } + # Add this column + push @{$self->{"cols"}}, {%col}; + return; +} + +# addpass: Add a modified password to the columns deposit, +# where "" means "not changed". Passwords are never empty. +# Input: $name: The column name. +# $purge: If we should purge the password. +# $val: The column value. +# $curval: The current value to be compared. +sub addpass : method { + local ($_, %_); + my ($self, $name, $purge, $val, $curval, $cur_exists, %col); + ($self, $name, $purge, $val, $curval) = @_; + $cur_exists = (@_ == 5); + $curval = decode("UTF-8", $curval, FB_CROAK) if !defined $DBH; + # Adjust the column name for multi-lingual columns + $name .= "_" . getlang LN_DATABASE + if in_array($name, @{$self->{"mlcols"}}); + + # The new column value + %col = qw(); + $col{"name"} = $name; + $col{"mod"} = 0; + # Purge the password with a dummy one + if ($purge) { + $col{"type"} = TYPE_STR; + $col{"value"} = "x" x 32; + # No value is supplied + } elsif (!defined $val || $val eq "") { + $col{"type"} = TYPE_NULL; + $col{"value"} = undef; + # A valid value + } else { + $col{"type"} = TYPE_STR; + %_ = map { ${$_}{"name"} => $_ } @{$self->{"cols"}}; + $col{"value"} = md5_hex(${$_{"id"}}{"value"} . ":magicat:" . $val); + } + + # Check if we should set it + if ($self->{"optype"} == ADDCOL_INSERT) { + # Always set the value for INSERT + $col{"mod"} = 1; + + } else { + # A current value is supplied + if ($cur_exists) { + # A different new value. Modify it. + if ($col{"type"} != TYPE_NULL && $col{"value"} ne $curval) { + $col{"mod"} = 1; + } + # No current value to compare with. + } else { + # Set it anyway + $col{"mod"} = 1; + } + } + # Add this column + push @{$self->{"cols"}}, {%col}; + return; +} + +# addpic: Add a picture to the columns deposit +# Input: $name: The column name. +# $val: The column value. +# $curval: The current value to be compared. +sub addpic : method { + local ($_, %_); + my ($self, $name, $val, $curval, $cur_exists, %col, $PICS); + ($self, $name, $val, $curval) = @_; + $cur_exists = (scalar(@_) == 4); + $curval = decode("UTF-8", $curval, FB_CROAK) if !defined $DBH; + $PICS = pic_deposit; + # Set the 3rd argument as the current value + if ($cur_exists) { + # Get the picture content + $curval = ${$$PICS{$curval}}{"content"} + if defined $curval; + } + # Adjust the column name for multi-lingual columns + $name .= "_" . getlang LN_DATABASE + if in_array($name, @{$self->{"mlcols"}}); + + # The new column value + %col = qw(); + $col{"name"} = $name; + $col{"mod"} = 0; + # No value is supplied + if (!defined $val) { + $col{"type"} = TYPE_NULL; + $col{"value"} = undef; + # A valid value + } else { + $col{"type"} = TYPE_FILE; + $col{"value"} = ${$$PICS{$val}}{"content"} + } + + # Check if we should set it + if ($self->{"optype"} == ADDCOL_INSERT) { + # Always set the value for INSERT + $col{"mod"} = 1; + + } else { + # A current value is supplied + if ($cur_exists) { + # This column had a value previously + if (defined $curval) { + # It has no value now. Remove it. + if ($col{"type"} == TYPE_NULL) { + $col{"mod"} = 1; + # A different new value. Modify it. + } elsif ($col{"value"} ne $curval) { + $col{"mod"} = 1; + } + # This column had no value previously + } else { + # But it has a value now. + if ($col{"type"} != TYPE_NULL) { + $col{"mod"} = 1; + } + } + # No current value to compare with. + } else { + # Set it anyway + $col{"mod"} = 1; + } + } + # Add this column + push @{$self->{"cols"}}, {%col}; + return; +} + +# addnum: Add a modified numeric column to the columns deposit +# Input: $name: The column name. +# $val: The column value. +# $curval: The current value to be compared. +sub addnum : method { + local ($_, %_); + my ($self, $name, $val, $curval, $cur_exists, %col); + ($self, $name, $val, $curval) = @_; + $cur_exists = (scalar(@_) == 4); + $curval = decode("UTF-8", $curval, FB_CROAK) if !defined $DBH; + # Adjust the column name for multi-lingual columns + $name .= "_" . getlang LN_DATABASE + if in_array($name, @{$self->{"mlcols"}}); + + # The new column value + %col = qw(); + $col{"name"} = $name; + $col{"mod"} = 0; + # No value is supplied + if (!defined $val || $val eq "") { + $col{"type"} = TYPE_NULL; + $col{"value"} = undef; + # A valid value + } else { + $col{"type"} = TYPE_NUM; + $col{"value"} = $val; + } + + # Check if we should set it + if ($self->{"optype"} == ADDCOL_INSERT) { + # Always set the value for INSERT + $col{"mod"} = 1; + + } else { + # A current value is supplied + if ($cur_exists) { + # This column had a value previously + if (defined $curval) { + # It has no value now. Remove it. + if ($col{"type"} == TYPE_NULL) { + $col{"mod"} = 1; + # A different new value. Modify it. + } elsif ($col{"value"} != $curval) { + $col{"mod"} = 1; + } + # This column had no value previously + } else { + # But it has a value now. + if ($col{"type"} != TYPE_NULL) { + $col{"mod"} = 1; + } + } + # No current value to compare with. + } else { + # Set it anyway + $col{"mod"} = 1; + } + } + # Add this column + push @{$self->{"cols"}}, {%col}; + return; +} + +# adddate: Add a modified date column to the columns deposit +# Mostly the same as addstr(). Different when out. +# Input: $name: The column name. +# $val: The column value. +# $curval: The current value to be compared. +sub adddate : method { + local ($_, %_); + my ($self, $name, $val, $curval, $cur_exists, %col); + ($self, $name, $val, $curval) = @_; + $cur_exists = (scalar(@_) == 4); + $curval = decode("UTF-8", $curval, FB_CROAK) if !defined $DBH; + # Adjust the column name for multi-lingual columns + $name .= "_" . getlang LN_DATABASE + if in_array($name, @{$self->{"mlcols"}}); + + # The new column value + %col = qw(); + $col{"name"} = $name; + $col{"mod"} = 0; + # No value is supplied + if (!defined $val || $val eq "") { + $col{"type"} = TYPE_NULL; + $col{"value"} = undef; + # A valid value + } else { + $col{"type"} = TYPE_DATE; + $col{"value"} = $val; + } + + # Check if we should set it + if ($self->{"optype"} == ADDCOL_INSERT) { + # Always set the value for INSERT + $col{"mod"} = 1; + + } else { + # A current value is supplied + if ($cur_exists) { + # This column had a value previously + if (defined $curval) { + # It has no value now. Remove it. + if ($col{"type"} == TYPE_NULL) { + $col{"mod"} = 1; + # A different new value. Modify it. + } elsif (str2time($col{"value"}) != $curval) { + $col{"mod"} = 1; + } + # This column had no value previously + } else { + # But it has a value now. + if ($col{"type"} != TYPE_NULL) { + $col{"mod"} = 1; + } + } + # No current value to compare with. + } else { + # Set it anyway + $col{"mod"} = 1; + } + } + # Add this column + push @{$self->{"cols"}}, {%col}; + return; +} + +# addipaddr: Add a modified IP address column to the columns deposit +# Mostly the same as addstr(). Different when out. +# Input: $name: The column name. +# $val: The column value. +# $curval: The current value to be compared. +sub addipaddr : method { + local ($_, %_); + my ($self, $name, $val, $curval, $cur_exists, %col); + ($self, $name, $val, $curval) = @_; + $cur_exists = (scalar(@_) == 4); + $curval = decode("UTF-8", $curval, FB_CROAK) if !defined $DBH; + # Adjust the column name for multi-lingual columns + $name .= "_" . getlang LN_DATABASE + if in_array($name, @{$self->{"mlcols"}}); + + # The new column value + %col = qw(); + $col{"name"} = $name; + $col{"mod"} = 0; + # No value is supplied + if (!defined $val || $val eq "") { + $col{"type"} = TYPE_NULL; + $col{"value"} = undef; + # A valid value + } else { + $col{"type"} = TYPE_IPADDR; + $col{"value"} = $val; + } + + # Check if we should set it + if ($self->{"optype"} == ADDCOL_INSERT) { + # Always set the value for INSERT + $col{"mod"} = 1; + + } else { + # A current value is supplied + if ($cur_exists) { + # This column had a value previously + if (defined $curval) { + # It has no value now. Remove it. + if ($col{"type"} == TYPE_NULL) { + $col{"mod"} = 1; + # A different new value. Modify it. + } elsif ($col{"value"} ne $curval) { + $col{"mod"} = 1; + } + # This column had no value previously + } else { + # But it has a value now. + if ($col{"type"} != TYPE_NULL) { + $col{"mod"} = 1; + } + } + # No current value to compare with. + } else { + # Set it anyway + $col{"mod"} = 1; + } + } + # Add this column + push @{$self->{"cols"}}, {%col}; + return; +} + +# addbool: Add a modified boolean column to the columns deposit +# Input: $name: The column name. +# $val: The column value. +# $curval: The current value to be compared. +sub addbool : method { + local ($_, %_); + my ($self, $name, $val, $curval, $cur_exists, %col); + ($self, $name, $val, $curval) = @_; + $cur_exists = (scalar(@_) == 4); + $curval = decode("UTF-8", $curval, FB_CROAK) if !defined $DBH; + # Adjust the column name for multi-lingual columns + $name .= "_" . getlang LN_DATABASE + if in_array($name, @{$self->{"mlcols"}}); + + # The new column value + %col = qw(); + $col{"name"} = $name; + $col{"mod"} = 0; + # No value supplied means "false" + $col{"type"} = TYPE_BOOL; + $col{"value"} = defined $val && $val; + + # Check if we should set it + if ($self->{"optype"} == ADDCOL_INSERT) { + # Always set the value for INSERT + $col{"mod"} = 1; + + } else { + # A current value is supplied + if ($cur_exists) { + # This column is previously true + if ($curval) { + # New value is false. Disable it. + if (!$col{"value"}) { + $col{"mod"} = 1; + } + # The current value is false + } else { + # But it is true now. + if ($col{"value"}) { + $col{"mod"} = 1; + } + } + # No current value to compare with. + } else { + # Set it anyway + $col{"mod"} = 1; + } + } + # Add this column + push @{$self->{"cols"}}, {%col}; + return; +} + +# addexpr: Add a expression column value to the columns deposit +# Input: $name: The column name. +# $val: The column value. +sub addexpr : method { + local ($_, %_); + my ($self, $name, $val, %col); + ($self, $name, $val) = @_; + # Adjust the column name for multi-lingual columns + $name .= "_" . getlang LN_DATABASE + if in_array($name, @{$self->{"mlcols"}}); + + # The new column value + # Always set it, since it is not possible to compare the current value + %col = qw(); + $col{"name"} = $name; + $col{"mod"} = 1; + $col{"type"} = TYPE_EXPR; + $col{"value"} = $val; + # Add this column + push @{$self->{"cols"}}, {%col}; + return; +} + +# modified: Return if this record is modified +sub modified : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Find any column that is modified + foreach my $col (@{$self->{"cols"}}) { + return 1 if ${$col}{"mod"}; + } + return 0; +} + +# ret: Retrieve the columns deposit as an SQL statement +# Input: $timestamp: Whether we should record timestamps or not +# Log in forms should not update their timestamps. +# Output: An SQL statement in the corresponding query type. +sub ret : method { + local ($_, %_); + my ($self, $timestamp); + ($self, $timestamp) = @_; + $timestamp = 1 if !defined $timestamp; + # Set the login user + if ($timestamp) { + $self->{"login"} = get_login_sn + if !exists $self->{"login"}; + } + if ($self->{"optype"} == ADDCOL_INSERT) { + my (@names, @vals); + @names = qw(); + @vals = qw(); + foreach my $col (@{$self->{"cols"}}) { + # Skip columns that are not modified + next unless ${$col}{"mod"}; + push @names, $DBH->quote_identifier(${$col}{"name"}); + push @vals, valout_sql($col); + } + # Add the timestamp + if ($timestamp) { + if (in_array("created", @{$self->{"allcols"}})) { + push @names, $DBH->quote_identifier("created"); + push @vals, "now()"; + } + if (in_array("createdby", @{$self->{"allcols"}})) { + push @names, $DBH->quote_identifier("createdby"); + push @vals, $self->{"login"}; + } + if (in_array("updated", @{$self->{"allcols"}})) { + push @names, $DBH->quote_identifier("updated"); + push @vals, "now()"; + } + if (in_array("updatedby", @{$self->{"allcols"}})) { + push @names, $DBH->quote_identifier("updatedby"); + push @vals, $self->{"login"}; + } + } + # Decode from UTF-8, for easier post-processing + return decode("UTF-8", "(" . join(", ", @names) . ")" + . " VALUES (" . join(", ", @vals) . ")"); + + } else { + my @phrases; + @phrases = qw(); + foreach my $col (@{$self->{"cols"}}) { + # Skip columns that are not modified + next unless ${$col}{"mod"}; + push @phrases, $DBH->quote_identifier(${$col}{"name"}) . "=" + . valout_sql($col); + } + # Add the timestamp + if ($timestamp) { + if (in_array("updated", @{$self->{"allcols"}})) { + push @phrases, $DBH->quote_identifier("updated") . "=now()"; + } + if (in_array("updatedby", @{$self->{"allcols"}})) { + $_ = get_login_sn; + $_ = $POST->param("sn") if !defined $_; + push @phrases, $DBH->quote_identifier("updatedby") . "=$_"; + } + } + # Decode from UTF-8, for easier post-processing + return decode("UTF-8", "SET " . join(", ", @phrases)); + } +} + +# retxml: Retrieve the columns deposit as an XML record. +# Input: None. +# Output: An XML record. +sub retxml : method { + local ($_, %_); + my ($self, @vals, $user); + $self = $_[0]; + # XML has no engine. Output the whole record anyway, + # no matter updated or not. + @vals = map valout_xml($_), @{$self->{"cols"}}; + # Add the updated information + if ($self->{"optype"} == ADDCOL_UPDATE) { + $user = (exists $ENV{"REMOTE_USER"} && $ENV{"REMOTE_USER"} ne "")? + $ENV{"REMOTE_USER"}: "(" . $ENV{"REMOTE_ADDR"} . ")"; + push @vals, "" . h(fmttime) . "\n"; + push @vals, "" . h($user) . "\n"; + } + return encode("UTF-8", "\n" . join("", @vals) . "\n", FB_CROAK); +} + +# retcsv: Retrieve the columns deposit as a CSV row. +# Input: None. +# Output: A CSV row. +sub retcsv : method { + local ($_, %_); + my $self; + $self = $_[0]; + # CSV has no engine. Output the whole record anyway, + # no matter updated or not. + return join(",", map valout_csv($_), @{$self->{"cols"}}) . "\n"; +} + + +########################### +# Private subroutines, not to be called as methods +########################### +# valout_sql: Output a value in a proper SQL format. +sub valout_sql($) { + local ($_, %_); + my ($col, $val); + $col = $_[0]; + # Encode first. $DBH->quote() does encode() anyway + if (defined $$col{"value"}) { + $val = $$col{"value"}; + $val = encode("UTF-8", $val) if is_utf8($val); + } + return "NULL" + if $$col{"type"} == TYPE_NULL; + return $val + if $$col{"type"} == TYPE_NUM; + return $DBH->quote($val) + if $$col{"type"} == TYPE_STR; + return "'" . $val . "'" + if $$col{"type"} == TYPE_DATE; + return $DBH->quote_blob($val) + if $$col{"type"} == TYPE_FILE; + return "'" . $val . "'" + if $$col{"type"} == TYPE_IPADDR; + return $val? "TRUE": "FALSE" + if $$col{"type"} == TYPE_BOOL; + return $val + if $$col{"type"} == TYPE_EXPR; +} + +# valout_xml: Output a value in a proper XML format. +sub valout_xml($) { + local ($_, %_); + $_ = $_[0]; + return "" + if $$_{"type"} == TYPE_NULL; + return "" + . h($$_{"value"}) . "\n" + if $$_{"type"} == TYPE_NUM; + return "" + . h($$_{"value"}) . "\n" + if $$_{"type"} == TYPE_STR; + return "" + . h(fmttime $$_{"value"}) . "\n" + if $$_{"type"} == TYPE_DATE; + return "" + . h(fmttime $$_{"value"}) . "\n" + if $$_{"type"} == TYPE_FILE; + return "" + . h($$_{"value"}) . "\n" + if $$_{"type"} == TYPE_IPADDR; + return "" + . h($$_{"value"}? "TRUE": "FALSE") . "\n" + if $$_{"type"} == TYPE_BOOL; + # XML has no engine. The following is emulated. + if ($$_{"type"} == TYPE_EXPR) { + return "" + . h(fmttime) . "\n" + if lc $$_{"value"} eq "now" || lc $$_{"value"} eq "now()"; + } +} + +# valout_csv: Output a value in a proper CSV format. +sub valout_csv($) { + local ($_, %_); + $_ = $_[0]; + return "NULL" + if $$_{"type"} == TYPE_NULL; + return $$_{"value"} + if $$_{"type"} == TYPE_NUM; + if ($$_{"type"} == TYPE_STR) { + $_ = $$_{"value"}; + s/\\/\\\\/g; + s/"/\\"/g; + s/\n/\\n/g; + s/\r/\\r/g; + s/\t/\\t/g; + s/\0/\\0/g; + return "\"" . $_ . "\""; + } + return "\"" . $$_{"value"} . "\"" + if $$_{"type"} == TYPE_DATE; + return "\"" . $$_{"value"} . "\"" + if $$_{"type"} == TYPE_IPADDR; + return $$_{"value"}? "TRUE": "FALSE" + if $$_{"type"} == TYPE_BOOL; + # CSV has no engine. The following is emulated. + if ($$_{"type"} == TYPE_EXPR) { + return "\"" . fmttime() . "\"" + if $$_{"value"} =~ /^now(?:\(\))?$/i; + } +} + +return 1; diff --git a/lib/perl5/Selima/AddGet.pm b/lib/perl5/Selima/AddGet.pm new file mode 100644 index 0000000..93a1216 --- /dev/null +++ b/lib/perl5/Selima/AddGet.pm @@ -0,0 +1,101 @@ +# Selima Website Content Management System +# AddGet.pm: The subroutines to manipulate the arguments in an URL. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-30 + +package Selima::AddGet; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(DUP_OK DUP_NO add_get_arg rem_get_arg); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub add_get_arg($$$;$); +sub rem_get_arg($@); +} + +use URI::Escape qw(uri_escape); + +# Constant symbols +use constant DUP_OK => 1; +use constant DUP_NO => 0; + +# add_get_arg: Add a get argument to the end of an url +sub add_get_arg($$$;$) { + local ($_, %_); + my ($url, $name, $value, $if_dup, $script); + ($url, $name, $value, $if_dup) = @_; + $if_dup = DUP_NO if !defined $if_dup; + + # Escape the name and value first + $name = uri_escape($name); + $value = uri_escape($value); + + # No current arguments are appended yet + return "$url?$name=$value" if $url !~ /\?/; + + # It is OK to have duplicated same arguments + return "$url&$name=$value" if $if_dup == DUP_OK; + + # Have arguments already. We need to check if there is already + # a duplicated one and replace it if exists. + # Split the arguments + $url =~ /^(.*?)\?(.*)$/; + ($script, $_) = ($1, $2); + @_ = split /&/, $_; + # Remove the matched ones + @_ = grep !/^$name=/, @_; + # Add our argument + push @_, "$name=$value"; + return "$script?" . join("&", @_); +} + +# rem_get_arg: Remove a get argument from the end of an url +sub rem_get_arg($@) { + local ($_, %_); + my ($url, @names, $script, $name); + ($url, @names) = @_; + + # No current arguments are appended yet + return $url if $url !~ /\?/; + + # Escape the names + for ($_ = 0; $_ < @names; $_++) { + # Encode the name first + $names[$_] = uri_escape($names[$_]); + } + + # Have arguments already. We need to check if there is already + # a duplicated one and remove it if exists. + # Split the arguments + $url =~ /^(.*?)\?(.*)$/; + ($script, $_) = ($1, $2); + @_ = split /&/, $_; + # Check one by one + foreach $name (@names) { + @_ = grep !/^$name=/, @_; + } + # No arguments left + return $script if scalar(@_) == 0; + return "$script?" . join("&", @_); +} + +return 1; diff --git a/lib/perl5/Selima/AltLang.pm b/lib/perl5/Selima/AltLang.pm new file mode 100644 index 0000000..74702a7 --- /dev/null +++ b/lib/perl5/Selima/AltLang.pm @@ -0,0 +1,145 @@ +# Selima Website Content Management System +# AltLang.pm: The subroutines to obtain the URLs of the alternative language versions. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-03 + +package Selima::AltLang; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(altlang set_altlang_urls); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub altlang($$); +sub set_altlang_urls($); +} + +use Data::Dumper qw(); +use URI::Escape qw(uri_escape); + +use Selima::AddGet; +use Selima::DataVars qw(:input :lninfo :requri); +use Selima::EchoForm; +use Selima::LnInfo; +use Selima::Session; +use Selima::Unicode; + +use vars qw(%ALT_LANG %IS_SCRIPT); + +# altlang: Obtain the URL of an alternative language version +sub altlang($$) { + local ($_, %_); + my ($lang, $args); + ($lang, $args) = @_; + set_altlang_urls $args; + # Return it + return ${$$args{"altlang"}}{$lang}; +} + +# set_altlang_urls: Set the URLs of the language variants +sub set_altlang_urls($) { + local ($_, %_); + my ($args, $path, $langfile, %urls); + my ($args0, @argkeys0, $need_charset); + $args = $_[0]; + # Return if already obtained + return if exists $$args{"altlang"}; + + # Set the page path + $path = $$args{"path"}; + $path .= "index.html" if $path =~ /\/$/; + + # Set the URL parameter + if ($$args{"static"}) { + $langfile = ln $$args{"lang"}, LN_FILENAME; + $path =~ s/\.$langfile$//; + $path .= ".%s"; + + } else { + #$args0 = $USER_INPUT{"GET_UTF8"}; + eval Data::Dumper->Dump([$USER_INPUT{"GET_UTF8"}], [qw($args0)]); + @argkeys0 = @{$USER_INPUT{"GET_KEYS"}}; + %_ = map { $_ => 1 } @argkeys0; + # Whether we need to specify the character set + $need_charset = !is_usascii_printable($args0->Vars); + # Remove the session ID + if (exists $_{$Selima::Session::NAME}) { + $args0->delete($Selima::Session::NAME); + @argkeys0 = grep $_ ne $Selima::Session::NAME, @argkeys0; + } + # Non-ASCII -- specify the character set + if ($need_charset) { + if (!exists $_{"charset"}) { + $args0->param("charset", ""); + push @argkeys0, "charset"; + } + # US-ASCII -- we do not need to specify the character set + } else { + if (exists $_{"charset"}) { + $args0->delete("charset"); + @argkeys0 = grep $_ ne "charset", @argkeys0; + } + } + # Append the referer + if (auto_keep_referer) { + $args0->param("referer", $ENV{"HTTP_REFERER"}); + push @argkeys0, "referer"; + } + # Append the language + if (!exists $_{"lang"}) { + $args0->param("lang", ""); + push @argkeys0, "lang"; + } + } + + # Deal with each language + %urls = qw(); + foreach my $lang (@{$$args{"all_linguas"}}) { + if ($$args{"static"}) { + $urls{$lang} = sprintf $path, ln($lang, LN_FILENAME); + } else { + my ($args1, @argkeys1, $charset1); + # Make a copy of the variables + eval Data::Dumper->Dump([$args0], [qw($args1)]); + @argkeys1 = @argkeys0; + $charset1 = ln $lang, LN_CHARSET; + $args1->param("lang", $lang); + @_ = qw(); + # We need to specify the character set + $args1->param("charset", $charset1) + if $need_charset; + foreach (@argkeys1) { + foreach my $val ($args1->param($_)) { + push @_, uri_escape(h_encode($_, $charset1)) + . "=" . uri_escape(h_encode($val, $charset1)) + } + } + $urls{$lang} = $REQUEST_FILE . "?" . join "&", @_; + } + $urls{$lang} = $urls{$lang}; + } + + # Record it + $$args{"altlang"} = \%urls; + return; +} + +return 1; diff --git a/lib/perl5/Selima/Array.pm b/lib/perl5/Selima/Array.pm new file mode 100644 index 0000000..27e7568 --- /dev/null +++ b/lib/perl5/Selima/Array.pm @@ -0,0 +1,84 @@ +# Selima Website Content Management System +# Array.pm: The array-related subroutines. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-12 + +package Selima::Array; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(in_array keys_ml keys_nl); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub in_array($@); +sub keys_ml(\%); +sub keys_nl(\%); +} + +use Selima::DataVars qw(:lninfo); +use Selima::GetLang; + +# in_array: If something is in an array +sub in_array($@) { + local ($_, %_); + my ($item, @array); + ($item, @array) = @_; + %_ = map { $_ => 1 } @array; + return exists $_{$item}; +} + +# keys_ml: Return a list of multi-lingual keys in a hash +sub keys_ml(\%) { + local ($_, %_); + my ($hash, $lndb); + $hash = $_[0]; + $lndb = getlang LN_DATABASE; + @_ = qw(); + foreach (keys %$hash) { + # it has a language suffix + push @_, $_ if s/_$lndb$//; + } + return @_; +} + +# keys_nl: Return a list of keys without their multi-lingual in a hash +sub keys_nl(\%) { + local ($_, %_); + my ($hash, %mlkeys); + $hash = $_[0]; + %mlkeys = map { $_ => 1 } keys_ml %$hash; + %_ = qw(); + foreach (keys %$hash) { + # No suffix + if (!/^(.+)_[^_]+$/) { + $_{$_} = 1; + # The prefix is one of the language columns + } elsif (exists $mlkeys{$1}) { + $_{$1} = 1; + # An ordinary prefix + } else { + $_{$_} = 1; + } + } + return keys %_; +} + +return 1; diff --git a/lib/perl5/Selima/AuthDig.pm b/lib/perl5/Selima/AuthDig.pm new file mode 100644 index 0000000..f26aa48 --- /dev/null +++ b/lib/perl5/Selima/AuthDig.pm @@ -0,0 +1,152 @@ +# Selima Website Content Management System +# AuthDig.pm: The mod_perl HTTP digest authentication handler. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-12 + +package Selima::AuthDig; +use 5.008; +use strict; +use warnings; + +use Apache::AuthDigest::API qw(); +use CGI qw(); +use Fcntl qw(:flock); +use File::Spec::Functions qw(catfile); + +use Selima::Checker::LogIn; +use Selima::DataVars qw($AUTHINFO $IS_MP2 :db :input); +use Selima::DBI; +use Selima::HTTP; +use Selima::Init; +use Selima::LogIn; +use Selima::Session; + +BEGIN { +if ($IS_MP2) { + require Apache2::Const; + import Apache2::Const qw(OK AUTH_REQUIRED); +} else { + require Apache::Constants; + import Apache::Constants qw(OK AUTH_REQUIRED); +} +} + +# Full HTTP Digest Authentication is specified in RFC 2617 + +# handler: Handle the HTTP digest authentication +sub handler { + local ($_, %_); + my ($r, $rd, $d, $status, $response, $pkg); + my ($form, $checker); + $r = $_[0]; + $rd = Apache::AuthDigest::API->new($r); + $d = new Selima::AuthDig::Destroy($rd); + + # Retrieve the authentication information + ($status, $response) = $rd->get_digest_auth_response; + # No authentication information available + return $status unless $status == OK; + + # Initialize the environemnt + $pkg = $r->dir_config("PACKAGE"); + initvars($pkg); + + # Logged out + if ( defined($_ = $GET->param("logout")) + && -e ($_ = catfile($Selima::Session::DIR, "logout_$_"))) { + unlink $_; + $rd->note_digest_auth_failure; + return AUTH_REQUIRED; + } + + # Connect to the database + $DBH = Selima::DBI->new($DBI_TYPE); + %_ = ("users" => LOCK_EX, "groups" => LOCK_SH, "usermem" => LOCK_SH); + $DBH->lock(%_); + + # Check the password digest + $form = new CGI(""); + $form->param("id", $rd->user); + $checker = new Selima::Checker::LogIn($form); + $checker->{"rd"} = $rd; + $checker->{"response"} = $response; + $checker->{"login"} = 1; + $_ = $checker->check(qw(id authdig)); + + # Failed + if (defined $_) { + $rd->note_digest_auth_failure; + return AUTH_REQUIRED; + } + + # Let $d->DESTROY release the database lock + # We do not update user information here. Updating user information + # requires initiating the session and set the session cookie SID. + # But cookies cannot be set under HTTP 304 Not Modified. We are + # protecting the whole directory, where there are a lot of static + # contents, including the Magicat home index.html. HTTP 304 occurs + # all the time, from the beginning of Magicat home entrance. + # Failing to set session cookie SID causes new sessions be + # reinitialited for every request. The user visits accounting + # would become non-sense. That accounting is important! + # We update user information at the script executing phrase, where + # we have more control over the output, including the cookies + # and the HTTP 304 status. + $AUTHINFO = $checker->{"row"}; + return OK; +} + +# Selima::AuthDig::Destroy: Object to remove program data +package Selima::AuthDig::Destroy; + +use 5.008; +use strict; +use warnings; + +use Selima::DataVars qw($DBH); + +# new: Initialize the destroyer +sub new : method { + local ($_, %_); + my ($class, $rd, $self); + ($class, $rd) = @_; + $self = bless {}, $class; + $self->{"rd"} = $rd; + return $self; +} + +# DESTROY: Release the acquired locks +sub DESTROY : method { + local ($_, %_); + my ($self, $rd, $headers); + $self = $_[0]; + $rd = $self->{"rd"}; + + # Disconnect database handle + if (defined $DBH) { + $DBH->disconnect; + undef $DBH; + } + + # Destroy myself + $self->SUPER::DESTROY if $self->can("SUPER::DESTROY"); + # I cannot really undefine myself ($_[0]) after all + return; +} + +return 1; diff --git a/lib/perl5/Selima/Cache.pm b/lib/perl5/Selima/Cache.pm new file mode 100644 index 0000000..0e62046 --- /dev/null +++ b/lib/perl5/Selima/Cache.pm @@ -0,0 +1,168 @@ +# Selima Website Content Management System +# Cache.pm: The data cache. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-24 + +package Selima::Cache; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT %EXPORT_TAGS @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +%EXPORT_TAGS = ( + account => [qw(%Account_acctsubj_title %Account_acctsubj_code + %Account_acctsubj_sn %Account_accttrx_id %Account_accttrx_maxord)], + callform=> [qw($CallForm_form_this %Callform_retrieve_form)], + chkfunc => [qw(%ChkFunc_check_script %ChkFunc_is_url_reachable)], + chkpriv => [qw(%ChkPriv_is_admin %ChkPriv_is_su + %ChkPriv_user_parent_groups)], + copyyear=> [qw($CopyYear_copyyear)], + country => [qw(%Country_ctname)], + echoform=> [qw(%EchoForm_opt_list)], + formfunc=> [qw($FormFunc_get_or_post $FormFunc_curform $FormFunc_isform + $FormFunc_formtype)], + getlang => [qw($GetLang_lang $GetLang_charset @GetLang_all_charsets)], + guest => [qw(%Guest_is_guest)], + links => [qw(%Links_linkcat_title %Links_link_title %Links_link_url + %Links_link_tree %Links_link_tree_full)], + listfunc=> [qw($ListFunc_listtype)], + login => [qw($LogIn_use_users)], + https => [qw($HTTPS_https_process $HTTPS_fqdn)], + mail => [qw(%Mail_MSGIDS)], + picture => [qw(%Picture_pic_deposit)], + remohost=> [qw($RemoHost_remote)], + scptpriv=> [qw(%ScptPriv_is_script_permitted %ScptPriv_is_admin_script)], + setl10n => [qw(%SetL10N_checked)], + username=> [qw(%UserName_username %UserName_userid %UserName_groupid + %UserName_groupdsc %UserName_groupsn $UserName_su_group_sn)], + userpref=> [qw(%UserPref_userpref)], +); +@EXPORT_OK = qw(); +my %seen; +%seen = qw(); +foreach my $tag (keys %EXPORT_TAGS) { + push @EXPORT_OK, grep !$seen{$_}++, @{$EXPORT_TAGS{$tag}}; +} +# Prototype declaration +sub clear(); +} + +use vars qw(%Account_acctsubj_title %Account_acctsubj_code); +use vars qw(%Account_acctsubj_sn %Account_accttrx_id); +use vars qw(%Account_accttrx_maxord); +use vars qw($CallForm_form_this %Callform_retrieve_form); +use vars qw(%ChkFunc_check_script %ChkFunc_is_url_reachable); +use vars qw(%ChkPriv_is_admin %ChkPriv_is_su); +use vars qw(%ChkPriv_user_parent_groups); +use vars qw($CopyYear_copyyear); +use vars qw(%Country_ctname); +use vars qw(%EchoForm_opt_list); +use vars qw($FormFunc_get_or_post $FormFunc_curform $FormFunc_isform); +use vars qw($FormFunc_formtype); +use vars qw($GetLang_lang $GetLang_charset @GetLang_all_charsets); +use vars qw(%Guest_is_guest); +use vars qw(%Links_linkcat_title %Links_link_title %Links_link_url); +use vars qw(%Links_link_tree %Links_link_tree_full); +use vars qw($ListFunc_listtype); +use vars qw($LogIn_use_users); +use vars qw($HTTPS_https_process $HTTPS_fqdn); +use vars qw(%Mail_MSGIDS); +use vars qw(%Picture_pic_deposit); +use vars qw($RemoHost_remote); +use vars qw(%SetL10N_checked); +use vars qw(%ScptPriv_is_script_permitted %ScptPriv_is_admin_script); +use vars qw(%UserName_username %UserName_userid %UserName_groupid); +use vars qw(%UserName_groupdsc %UserName_groupsn $UserName_su_group_sn); +use vars qw(%UserPref_userpref); + +# clear: Clear the cache (for mod_perl) +sub clear() { + local ($_, %_); + + %Account_acctsubj_title = qw(); + %Account_acctsubj_code = qw(); + %Account_acctsubj_sn = qw(); + %Account_accttrx_id = qw(); + %Account_accttrx_maxord = qw(); + + undef $CallForm_form_this; + %Callform_retrieve_form = qw(); + + %ChkFunc_check_script = qw(); + %ChkFunc_is_url_reachable = qw(); + + %ChkPriv_is_admin = qw(); + %ChkPriv_is_su = qw(); + %ChkPriv_user_parent_groups = qw(); + + undef $CopyYear_copyyear; + + %Country_ctname = qw(); + + %EchoForm_opt_list = qw(); + + undef $FormFunc_get_or_post; + undef $FormFunc_curform; + undef $FormFunc_isform; + undef $FormFunc_formtype; + + undef $GetLang_lang; + undef $GetLang_charset; + @GetLang_all_charsets = qw(); + + %Guest_is_guest = qw(); + + %Links_linkcat_title = qw(); + %Links_link_title = qw(); + %Links_link_url = qw(); + %Links_link_tree = qw(); + %Links_link_tree_full = qw(); + + undef $ListFunc_listtype; + + undef $LogIn_use_users; + + $HTTPS_https_process = 0; + undef $HTTPS_fqdn; + + %Mail_MSGIDS = qw(); + + %Picture_pic_deposit = qw(); + + undef $RemoHost_remote; + + %ScptPriv_is_script_permitted = qw(); + %ScptPriv_is_admin_script = qw(); + + %SetL10N_checked = qw(); + + %UserName_username = qw(); + %UserName_userid = qw(); + %UserName_groupid = qw(); + %UserName_groupdsc = qw(); + %UserName_groupsn = qw(); + undef $UserName_su_group_sn; + + %UserPref_userpref = qw(); + + return; +} + +return 1; diff --git a/lib/perl5/Selima/CallForm.pm b/lib/perl5/Selima/CallForm.pm new file mode 100644 index 0000000..24d6dac --- /dev/null +++ b/lib/perl5/Selima/CallForm.pm @@ -0,0 +1,465 @@ +# Selima Website Content Management System +# CallForm.pm: The subroutines to transfer between a form and its subform. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-24 + +package Selima::CallForm; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(call_form error_redirect success_redirect); +push @EXPORT, qw(suspend_form retrieve_form suspend_status retrieve_status); +push @EXPORT, qw(is_called_form form_this); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub call_form($;$$); +sub proc_status_redirect($); +sub error_redirect($); +sub success_redirect($); +sub suspend_form(;$); +sub retrieve_form(;$); +sub suspend_status($); +sub retrieve_status(;$); +sub is_called_form(); +sub new_formid(); +sub new_statid(); +sub form_this(); +} + +use CGI qw(); +use Data::Dumper qw(); +use File::Spec::Functions qw(catfile); +use Fcntl qw(:flock); +use URI::Escape qw(uri_escape); + +use Selima::AddGet; +use Selima::Cache qw(:callform); +use Selima::DataVars qw($SESSION :env :forms :requri :scptconf); +use Selima::FormFunc; +use Selima::HTTP; +use Selima::Session; +use Selima::XFileIO; + +use vars qw(%SAVESTATS); + +# Settings +# The length of the ID +use constant ID_LEN => 9; + +# call_form: Suspend the current form and call another selection form +sub call_form($;$$) { + local ($_, %_); + my ($form, @args, $import_func, $FORM, $formid); + ($form, $_, $import_func) = @_; + @args = defined $_? @$_: qw(); + # Only work for defined forms + http_500 "Calling undefined form \"$form\".\n" + if !exists $SCRIPTS{$form}; + + # Record the selection import function + if (defined $import_func) { + # Obtain the form + $FORM = get_or_post; + $FORM->param("import_func", $import_func); + } + # Suspend the current form + $formid = suspend_form $FORM; + + # Add the caller + $_ = $REQUEST_PATH; + $_ =~ s/^$ROOT_DIFF//; + push @args, "caller=" . uri_escape($_); + # Add the caller form ID + push @args, "cformid=" . uri_escape($formid); + + # Redirect + http_303 $SCRIPTS{$form} . "?" . join("&", @args); + # No need to return + exit; +} + +# proc_status_redirect: Save the form status, suspend and redirect the form +sub proc_status_redirect($) { + local ($_, %_); + my ($status, $url, $FORM, $formid, $statid, $method); + $status = $_[0]; + + # Obtain the form + $FORM = get_or_post; + + # No more form + if ( defined $status + && exists $$status{"isform"} + && !$$status{"isform"}) { + # Find the referring script + # Specified + if (exists $$status{"nextstep"}) { + $url = $$status{"nextstep"}; + } elsif (defined $FORM->param("referer2")) { + $url = $FORM->param("referer2"); + # Back to the user home on the calling site + } elsif (defined $FORM->param("hostport")) { + # To be done + $url = $FORM->param("hostport") . "/magicat/"; + # Default to the current URL + } else { + $url = $REQUEST_FILE; + } + # Do not affect the previous form + delete $$status{"isform"}; + + # Default to this same script + } else { + $url = form_this; + # Suspend the current form + $formid = suspend_form $FORM; + $url = add_get_arg $url, "formid", $formid; + } + + # Add the status + if (defined $status) { + $statid = suspend_status $status; + $url = add_get_arg $url, "statid", $statid; + } + + # Redirect + $method = $IS_MODPERL? ($IS_MP2? + Apache2::RequestUtil->request->method: Apache->request->method): + $ENV{"REQUEST_METHOD"}; + if ($method eq "POST") { + http_303 $url; + } else { + http_307 $url; + } + # No need to return + exit; +} + +# error_redirect: Shortcut to redirect the error form +sub error_redirect($) { + local ($_, %_); + my $status; + $status = $_[0]; + + $$status{"status"} = "error" if defined $status; + proc_status_redirect $status; + # No need to return + exit; +} + +# success_redirect: Shortcut to redirect the success form +sub success_redirect($) { + local ($_, %_); + my $status; + $status = $_[0]; + + $$status{"status"} = "success" if defined $status; + proc_status_redirect $status; + # No need to return + exit; +} + +# suspend_form: Suspend the current form +sub suspend_form(;$) { + local ($_, %_); + my ($FORM, $formid, $dumper, $origumask); + $FORM = $_[0]; + + # Obtain the form + $FORM = get_or_post if !defined $FORM; + + # Using session is better + if (defined $SESSION) { + # Initialize the form deposit + $$SESSION{"saveforms"} = {} + if !exists $$SESSION{"saveforms"}; + # Do not use existing form ID + $formid = new_formid; + # Save the current form + ${$$SESSION{"saveforms"}}{$formid} = $FORM; + # Save the form ID + ${$$SESSION{"saveforms"}}{$formid}->param("formid", $formid); + ${$$SESSION{"saveforms"}}{$formid}->param("ownerscript", $REQUEST_PATH); + $SESSION->flush; + + # Not using session + } else { + # Do not use existing form ID + $formid = new_formid; + # Dump the form + $dumper = new Data::Dumper([$FORM], [qw($_)]); + $dumper->Indent(1); + $dumper->Sortkeys(1); + $_ = $dumper->Dump; + # Write to the file + $origumask = umask 0077; + xfwrite(catfile($Selima::Session::DIR, "saveform_$formid"), $_); + umask $origumask; + } + + return $formid; +} + +# retrieve_form: Retrieve a previously suspended form +# Return empty array instead of empty, to be merged directly +sub retrieve_form(;$) { + local ($_, %_); + my ($formid, $CUR_FORM, $file, $cache); + $formid = $_[0]; + $cache = \%Callform_retrieve_form; + + # Return the cache + if (!defined $formid) { + # $cache[0] is the default (previous form) + return $$cache{0} if exists $$cache{0}; + } else { + return $$cache{$formid} if exists $$cache{$formid}; + } + + # Using session is better + if (defined $SESSION) { + # Initialize the form deposit + if (!exists $$SESSION{"saveforms"}) { + $$SESSION{"saveforms"} = {}; + if (!defined $formid) { + return ($$cache{0} = new CGI("")); + } else { + return ($$cache{$formid} = new CGI("")); + } + } + + # Obtain the previous suspended form if form not specified + if (!defined $formid) { + # Obtain the form + $CUR_FORM = get_or_post; + # Return empty if not set + return ($$cache{0} = new CGI("")) + if !defined $CUR_FORM->param("formid"); + $formid = $CUR_FORM->param("formid"); + # There is no such previously suspended form + if (!exists ${$$SESSION{"saveforms"}}{$formid}) { + $$cache{$formid} = new CGI(""); + $$cache{0} = $$cache{$formid}; + return $$cache{0}; + } + $$cache{$formid} = ${$$SESSION{"saveforms"}}{$formid}; + $$cache{0} = $$cache{$formid}; + + } else { + # There is no such previously suspended form + return ($$cache{$formid} = new CGI("")) + if !exists ${$$SESSION{"saveforms"}}{$formid}; + $$cache{$formid} = ${$$SESSION{"saveforms"}}{$formid}; + } + + + # Not using session + } else { + # Obtain the previous suspended form if form not specified + if (!defined $formid) { + # Obtain the form + $CUR_FORM = get_or_post; + # Return empty if not set + return ($$cache{0} = new CGI("")) + if !defined $CUR_FORM->param("formid"); + $formid = $CUR_FORM->param("formid"); + # Compose the save form file name + $file = catfile($Selima::Session::DIR, "saveform_$formid"); + # There is no such previously suspended form + if (!-f $file || !-r $file || !-s $file) { + $$cache{$formid} = new CGI(""); + $$cache{0} = $$cache{$formid}; + return $$cache{0}; + } + $$cache{$formid} = eval xfread($file); + $$cache{0} = $$cache{$formid}; + + } else { + # Compose the save form file name + $file = catfile($Selima::Session::DIR, "saveform_$formid"); + # There is no such previously suspended form + return ($$cache{$formid} = new CGI("")) + if !-f $file || !-r $file || !-s $file; + $$cache{$formid} = eval xfread($file); + } + } + + # Import the selection if needed + &$_($$cache{$formid}) + if defined($_ = $$cache{$formid}->param("import_func")) + && defined($_ = $MAIN->can($_)); + + # Return the form + return $$cache{$formid}; +} + +# suspend_status: Suspend the current status +sub suspend_status($) { + local ($_, %_); + my ($status, $statid, $dumper, $origumask); + $status = $_[0]; + + # Using session is better + if (defined $SESSION) { + # Initialize the status deposit + $$SESSION{"savestats"} = {} + if !exists $$SESSION{"savestats"}; + # Do not use existing status ID + $statid = new_statid; + # Save the current status + ${$$SESSION{"savestats"}}{$statid} = $status; + # Save the status ID + ${${$$SESSION{"savestats"}}{$statid}}{"statid"} = $statid; + ${${$$SESSION{"savestats"}}{$statid}}{"ownerscript"} = $REQUEST_PATH; + $SESSION->flush; + + # Not using session + } else { + # Do not use existing status ID + $statid = new_statid; + # Dump the status + $dumper = new Data::Dumper([$status], [qw($_)]); + $dumper->Indent(1); + $dumper->Sortkeys(1); + $_ = $dumper->Dump; + # Write to the file + $origumask = umask 0077; + xfwrite(catfile($Selima::Session::DIR, "savestat_$statid"), $_); + umask $origumask; + } + + return $statid; +} + +# retrieve_status: Retrieve a previously suspended status +# Return empty array instead of empty, to be merged directly +sub retrieve_status(;$) { + local ($_, %_); + my ($statid, $CUR_FORM, $file); + $statid = $_[0]; + + if (!defined $statid) { + # Obtain the form + $CUR_FORM = get_or_post; + + # Return nothing if there is no status ID to retrieve + return if !defined $CUR_FORM->param("statid"); + $statid = $CUR_FORM->param("statid"); + } + + # Using session is better + if (defined $SESSION) { + return if !exists $$SESSION{"savestats"}; + return if !exists ${$$SESSION{"savestats"}}{$statid}; + return ${$$SESSION{"savestats"}}{$statid}; + + # Not using session + } else { + # Compose the save status file name + $file = catfile($Selima::Session::DIR, "savestat_$statid"); + # Check if this status is available + if (!-f $file || !-r $file || !-s $file) { + # Remove expired cache + delete $SAVESTATS{$file} if exists $SAVESTATS{$file}; + return; + } + + # Parse the status + $SAVESTATS{$statid} = eval xfread($file) + if !exists $SAVESTATS{$statid}; + # Return the status + return $SAVESTATS{$statid}; + } +} + +# is_called_form: If this is a called form +sub is_called_form() { + local ($_, %_); + $_ = curform; + return (defined $_->param("caller") && defined $_->param("cformid")); +} + +# new_formid: Generate a new random form ID number +sub new_formid() { + local ($_, %_); + my ($min, $max, $int, $formid); + + $min = 10 ** (ID_LEN - 1); # 100000000 + $max = (10 ** ID_LEN) - 1; # 999999999 + $int = $max - $min + 1; + + # Using session is better + if (defined $SESSION) { + do { + # Generate a random serial number + $formid = $min + int rand $int; + } until !exists ${$$SESSION{"saveforms"}}{$formid}; + + # Not using session + } else { + do { + # Generate a random serial number + $formid = $min + int rand $int; + } until !-e catfile($Selima::Session::DIR, "saveform_$formid"); + } + + return $formid; +} + +# new_statid: Generate a new random status ID number +sub new_statid() { + local ($_, %_); + my ($min, $max, $int, $statid); + + $min = 10 ** (ID_LEN - 1); # 100000000 + $max = (10 ** ID_LEN) - 1; # 999999999 + $int = $max - $min + 1; + + # Using session is better + if (defined $SESSION) { + do { + # Generate a random serial number + $statid = $min + int rand $int; + } until !exists ${$$SESSION{"savestats"}}{$statid}; + + # Not using session + } else { + do { + # Generate a random serial number + $statid = $min + int rand $int; + } until !-e catfile($Selima::Session::DIR, "savestat_$statid"); + } + + return $statid; +} + +# form_this: Find the processing script +sub form_this() { + local ($_, %_); + return $CallForm_form_this if defined $CallForm_form_this; + $_ = get_or_post; + return ($CallForm_form_this = $_) + if defined($_ = $_->param("referer")); + return ($CallForm_form_this = $REQUEST_FILE); +} + +return 1; diff --git a/lib/perl5/Selima/Checker.pm b/lib/perl5/Selima/Checker.pm new file mode 100644 index 0000000..8c91409 --- /dev/null +++ b/lib/perl5/Selima/Checker.pm @@ -0,0 +1,800 @@ +# Selima Website Content Management System +# Checker.pm: The base form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-25 + +package Selima::Checker; +use 5.008; +use strict; +use warnings; + +use Encode::HanConvert qw(trad_to_simp simp_to_trad); +use Regexp::Common::URI::RFC2396 qw(); +use URI::Escape qw(uri_escape); + +use Selima::AddGet; +use Selima::Array; +use Selima::CallForm; +use Selima::ChkFunc; +use Selima::ChkWrite; +use Selima::DataVars qw($DBH FORM_CAPTCHA :dataman :forms :l10n + :lninfo :requri); +use Selima::FormFunc; +use Selima::GetLang; +use Selima::HTTP; +use Selima::LnInfo; +use Selima::Logging; +use Selima::Picture; +use Selima::ShortCut; + +# Load these classes +use Selima::Checker::User; +use Selima::Checker::Group; +use Selima::Checker::UserMem; +use Selima::Checker::GroupMem; +use Selima::Checker::UserPref; +use Selima::Checker::ScptPriv; +use Selima::Checker::LogIn; +use Selima::Checker::ListPref; + +use Selima::Checker::Guestbook; +use Selima::Checker::Guestbook::Public; +use Selima::Checker::Page; +use Selima::Checker::LinkCat; +use Selima::Checker::Link; +use Selima::Checker::LinkCatz; + +use Selima::Checker::Rebuild; +use Selima::Checker::MailTo; + +use Selima::Checker::AcctSubj; +use Selima::Checker::AcctTrx; +use Selima::Checker::AcctRec; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $form, $table, $checker); + ($class, $form, $table) = @_; + $checker = bless {}, $class; + + $checker->{"form"} = $form; + if (defined $table) { + $checker->{"table"} = $table; + $checker->{"maxlens"} = { $DBH->col_lens($table) }; + } + $checker->{"minlens"} = {}; + ${$checker->{"minlens"}}{"id"} = 3; + $checker->{"iscur"} = (keys %CURRENT > 0)? 1: 0; + $checker->{"sn"} = $form->param("sn") + if $checker->{"iscur"} && defined $form->param("sn"); + return $checker; +} + +# check: Run a list of checks +sub check : method { + local ($_, %_); + my ($self, @cols, $error); + ($self, @cols) = @_; + + # Check the list itself first + @_ = qw(); + foreach my $col (@cols) { + http_500 "Called an undefined check \"$col\"" + if !defined($_ = $self->can("_check_$col")); + push @_, $_; + } + # Run each checker + foreach (@_) { + $error = &$_($self); + return $error if defined $error; + } + return; +} + +# redir: Redirect to another form +sub redir : method { + local ($_, %_); + my ($self, @cols); + ($self, @cols) = @_; + # Check the list itself first + @_ = qw(); + foreach my $col (@cols) { + http_500 "Called an undefined redirection \"$col\"" + if !defined($_ = $self->can("_redir_$col")); + push @_, $_; + } + # Check each redirection + &$_($self) foreach @_; + return; +} + +# +# Private column checkers. Do not call them directly. +# Add or override the column checkers when needed. +# Method names must be in the following format: +# sub _check_{column} : method { ... } +# Columns started with underlines are reserved for internal use, as usual. +# +# _check_usr: The default user checker +sub _check_usr : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("usr"); + return $error if defined $error; + # Regularize it + $self->_trim("usr"); + # Check if it is filled + return {"msg"=>N_("Please select a user.")} + if $form->param("usr") eq ""; + # Check if this user exists + return {"msg"=>N_("This user does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("usr")}[0], "users"; + # OK + return; +} + +# _check_grp: The default group checker +sub _check_grp : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("grp"); + return $error if defined $error; + # Regularize it + $self->_trim("grp"); + # Check if it is filled + return {"msg"=>N_("Please select a group.")} + if $form->param("grp") eq ""; + # Check if the group exists + return {"msg"=>N_("This group does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("grp")}[0], "groups"; + # OK + return; +} + +# _check_script: The default script checker +sub _check_script : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("script"); + return $error if defined $error; + # Regularize it + $self->_trim("script"); + # Check if it is filled + return {"msg"=>N_("Please fill in the script.")} + if $form->param("script") eq ""; + # Check the length + return {"msg"=>N_("This script is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"script"}]} + if length $form->param("script") > ${$self->{"maxlens"}}{"script"}; + # Check if this script exists + return {"msg"=>N_("This script is not a valid script. Please specify another one.")} + if !check_script($form->param("script")); + # OK + return; +} + +# _check_author: The default author checker +sub _check_author : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("author"); + return $error if defined $error; + # Regularize it + $self->_trim("author"); + # Check if it is filled + return {"msg"=>N_("Please fill in the author.")} + if $form->param("author") eq ""; + # Check the length + return {"msg"=>N_("This author is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"author"}]} + if length $form->param("author") > ${$self->{"maxlens"}}{"author"}; + # OK + return; +} + +# _check_body: The default content body checker +sub _check_body : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("body"); + return $error if defined $error; + # Regularize it + $self->_trimtext("body"); + # Check if it is filled + $form->param("body", "") + if $form->param("body") eq C_("Fill in the content here."); + return {"msg"=>N_("Please fill in the content.")} + if $form->param("body") eq ""; + # Check the length + return {"msg"=>N_("This content is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"body"}]} + if length $form->param("body") > ${$self->{"maxlens"}}{"body"}; + # OK + return; +} + +# _check_date: Check the date +sub _check_date : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("date"); + return $error if defined $error; + # Regularize it + $self->_trim("date"); + # Check if it is filled + return {"msg"=>N_("Please fill in a date.")} + if $form->param("date") eq ""; + # Check the length + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + if length $form->param("date") > ${$self->{"maxlens"}}{"date"}; + # Check the date format + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + if $form->param("date") !~ /^(\d{4})-(\d{2})-(\d{2})$/; + return {"msg"=>N_("Please fill in a valid date in YYYY-MM-DD format.")} + if !check_date $1, $2, $3; + # OK + return; +} + +# _check_dsc: The default description checker +sub _check_dsc : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("dsc"); + return $error if defined $error; + # Regularize it + $self->_trimtext("dsc"); + # Check if it is filled + $form->param("dsc", "") + if $form->param("dsc") eq C_("Fill in the description here."); + return {"msg"=>N_("Please fill in the description.")} + if $form->param("dsc") eq ""; + # Check the length + return {"msg"=>N_("This description is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"dsc"}]} + if length $form->param("dsc") > ${$self->{"maxlens"}}{"dsc"}; + # OK + return; +} + +# _check_id: The default ID. checker +sub _check_id : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("id"); + return $error if defined $error; + # Regularize it + $self->_trim("id"); + # Check if it is filled + return {"msg"=>N_("Please fill in the ID.")} + if $form->param("id") eq ""; + # Check the length + return {"msg"=>N_("This ID. is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"id"}]} + if length $form->param("id") > ${$self->{"maxlens"}}{"id"}; + return {"msg"=>N_("This ID. is too short. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"id"}]} + if length $form->param("id") < ${$self->{"minlens"}}{"id"}; + # Check if the characters used are valid + return {"msg"=>N_("Only lower-case English letters, numbers and underscores are allowed for the ID.")} + unless $form->param("id") =~ /^[a-z][a-z0-9_]*$/; + # OK + return; +} + +# _check_kw: The default keyword list checker +sub _check_kw : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("kw"); + return $error if defined $error; + # Regularize it + $self->_trim("kw"); + # Check if it is filled + return {"msg"=>N_("Please fill in the keywords.")} + if $form->param("kw") eq ""; + # Check the length + return {"msg"=>N_("This keyword list is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"kw"}]} + if length $form->param("kw") > ${$self->{"maxlens"}}{"kw"}; + # OK + return; +} + +# _check_message: The default message checker +sub _check_message : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("message"); + return $error if defined $error; + # Regularize it + $self->_trimtext("message"); + # Check if it is filled + $form->param("message", "") + if $form->param("message") eq C_("Fill in the message here."); + return {"msg"=>N_("Please fill in the message.")} + if $form->param("message") eq ""; + # Check the length + return {"msg"=>N_("This message is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"message"}]} + if length $form->param("message") > ${$self->{"maxlens"}}{"message"}; + # OK + return; +} + +# _check_ord: The default order checker +sub _check_ord : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("ord"); + return $error if defined $error; + # Regularize it + $self->_trim("ord"); + # Check if it is filled + return {"msg"=>N_("Please fill in the order.")} + if $form->param("ord") eq ""; + # Check the length + return {"msg"=>N_("This order is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"ord"}]} + if length $form->param("ord") > ${$self->{"maxlens"}}{"ord"}; + # Check if it is a valid positive integer + return {"msg"=>N_("Please fill in a positive integer order.")} + unless $form->param("ord") =~ /^\d+$/; + # Set to an integer + $_ = $form->param("ord"); + $_ += 0; + $form->param("ord", $_); + # OK + return; +} + +# _check_path: The default page path checker +sub _check_path : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("path"); + return $error if defined $error; + # Regularize it + $self->_trim("path"); + # Remove the trailing excess "index.html" + $_ = $form->param("path"); + s/\/index\.html?$/\//; + $form->param("path", $_); + # Check if it is filled + return {"msg"=>N_("Please fill in the page path.")} + if $form->param("path") eq ""; + # Check the length + return {"msg"=>N_("This page path is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"path"}]} + if length $form->param("path") > ${$self->{"maxlens"}}{"path"}; + # Check if this item is duplicated + @_ = qw(); + push @_, "path=" . $DBH->quote($form->param("path")); + push @_, "sn!=" . $self->{"sn"} if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This page already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + # Check if the path is absolute + return {"msg"=>N_("Please fill in an absolute page path.")} + if $form->param("path") !~ /^\//; + # Check if the path is legal + return {"msg"=>N_("Please fill in a valid page path.")} + if $form->param("path") !~ /^\/$Regexp::Common::URI::RFC2396::path_segments$/; + # Check if it is the cover home page + return {"msg"=>N_("You cannot overwrite the cover home page.")} + if $form->param("path") eq ""; + # Check if it is *.html + return {"msg"=>N_("You can only fill in an HTML page path (*.html).")} + if $form->param("path") !~ /(?:\/|\.html)$/; + # Check if we are permitted to write files there + if (@ALL_LINGUAS > 1) { + $_ = $DOC_ROOT . $form->param("path"); + $_ =~ s/\/$/\/index.html/; + $_ .= ".%s.xhtml"; + foreach my $ln (@ALL_LINGUAS) { + $error = check_writable sprintf $_, ln $ln, LN_FILENAME; + return $error if defined $error; + } + } else { + $error = check_writable $DOC_ROOT . $form->param("path") . ".xhtml"; + return $error if defined $error; + } + # OK + return; +} + +# _check_pic: The default picture checker +sub _check_pic : method { + local ($_, %_); + my ($self, $form, $error, $PICS); + $self = $_[0]; + $form = $self->{"form"}; + # Skip if there is no picture to check + return if $self->_missing("pic"); + # Check if this picture exists + return {"msg"=>N_("This picture does not exist anymore. Please upload another one.")} + if !pic_exists ${$form->param_fetch("pic")}[0]; + # Check the length + $PICS = pic_deposit; + return {"msg"=>N_("This picture is too large. Please upload another one. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"pic"}]} + if length ${$$PICS{$form->param("pic")}}{"content"} > ${$self->{"maxlens"}}{"pic"}; + # OK + return; +} + +# _check_piccap: default picture caption checker +sub _check_piccap : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Skip if there is no picture now + if ($self->_missing("pic")) { + $form->delete("piccap"); + return; + } + # Check if it exists + $error = $self->_missing("piccap"); + return $error if defined $error; + # Regularize it + $self->_trim("piccap"); + # Check if it is filled + return {"msg"=>N_("Please fill in the picture caption.")} + if $form->param("piccap") eq ""; + # Check the length + return {"msg"=>N_("This picture caption is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"piccap"}]} + if length $form->param("piccap") > ${$self->{"maxlens"}}{"piccap"}; + # OK + return; +} + +# _check_picpos: default picture position checker +sub _check_picpos : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Skip if there is no picture now + if ($self->_missing("pic")) { + $form->delete("picpos"); + return; + } + # Check if it exists + $error = $self->_missing("picpos"); + return $error if defined $error; + # Regularize it + $self->_trim("picpos"); + # Check if the picture position is legal + return {"msg"=>N_("This picture position is invalid. Please choose a proper picture position.")} + if !in_array($form->param("picpos"), @PIC_VALID_POS); + # OK + return; +} + +# _check_title: The default title checker +sub _check_title : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("title"); + return $error if defined $error; + # Regularize it + $self->_trim("title"); + # Check if it is filled + return {"msg"=>N_("Please fill in the title.")} + if $form->param("title") eq ""; + # Check the length + return {"msg"=>N_("This title is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"title"}]} + if length $form->param("title") > ${$self->{"maxlens"}}{"title"}; + # OK + return; +} + +# _check_title_en: The default English title checker +sub _check_title_en : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("title_en"); + return $error if defined $error; + # Regularize it + $self->_trim("title_en"); + # Check if it is filled + return {"msg"=>N_("Please fill in the English title.")} + if $form->param("title_en") eq ""; + # Check the length + return {"msg"=>N_("This English title is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"title_en"}]} + if length $form->param("title_en") > ${$self->{"maxlens"}}{"title_en"}; + # OK + return; +} + +# +# Spam Checkers: +# There are a series of checks for spam here. _check_spam() called each of them. +# Moved to Selima::Init. It starts at an early phrase before database initialization. +# +# _check_spam: Check the spam +sub _check_spam : method { + local ($_, %_); + # Check the CAPTCHA + $_[0]->_check_captcha; + # Check the local content filter + $_[0]->_checkspam_local if $_[0]->can("_checkspam_local"); + # OK + return; +} + +# _check_captcha: The default CAPTCHA checker +sub _check_captcha : method { + local ($_, %_); + my ($self, $form, $col, $error); + $self = $_[0]; + $form = $self->{"form"}; + $col = FORM_CAPTCHA; + # Check if it exists + $error = $self->_missing($col); + return $error if defined $error; + $self->_block_spam("_check_captcha: captcha column \"$col\" should be empty but got \"" + . $form->param($col) . "\".") + if $form->param($col) ne ""; + # OK + return; +} + +# _block_spam: Block the spam message +sub _block_spam : method { + local ($_, %_); + my ($self, $msg); + ($self, $msg) = @_; + spamlog $msg; + # Disconnect now. Leave resources for meaningful requests + $DBH->rollback; + $DBH->disconnect; + undef $DBH; + # Delay the spammer + sleep 300; + http_403(0); + # No return +} + +# +# Private form redirectors. Do not call them directly. +# Add redirector definitions here. +# Method names must be in the following format: +# sub _redir_{column} : method { ... } +# Columns started with underlines are reserved for internal use, as usual. +# +# _redir_del: Suspend and move to the deletion form +sub _redir_del : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("del"); + # Skip if S/N does not exist + return if $self->_missing("sn"); + @_ = qw(); + push @_, "form=del"; + push @_, "sn=" . uri_escape($self->{"form"}->param("sn")); + call_form FORM_THIS, [@_]; +} + +# _redir_zhsync: Synchronize Chinese columns +sub _redir_zhsync : method { + local ($_, %_); + my ($self, $form, $lndb); + $self = $_[0]; + $form = $self->{"form"}; + # Skip if not requested + return if $self->_missing("zhsync"); + %_ = map { $_ => 1 } @ALL_LINGUAS; + $_ = getlang; + # We are at a subordinary language + if ($_ ne $DEFAULT_LANG) { + # We are in Simplified Chinese and there is Traditional Chinese + if ($_ eq "zh-cn" && exists $_{"zh-tw"}) { + $lndb = ln "zh-tw", LN_DATABASE; + # Convert the form + $form->param($_, trad_to_simp($CURRENT{$_ . "_$lndb"})) + foreach grep s/_$lndb$//, keys %CURRENT; + + # We are in Traditional Chinese and there is Simplified Chinese + } elsif ($_ eq "zh-tw" && exists $_{"zh-cn"}) { + $lndb = ln "zh-cn", LN_DATABASE; + # Convert the form + $form->param($_, simp_to_trad($CURRENT{$_ . "_$lndb"})) + foreach grep s/_$lndb$//, keys %CURRENT; + } + } + # Show the form again + success_redirect undef; +} + +# _redir_cancel: Cancel the form and return to the originator +sub _redir_cancel : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("cancel"); + # A calling form -- return to the caller + if (!$self->_missing("caller", "cformid")) { + $_ = $self->{"form"}->param("caller"); + $_ = $self->{"form"}->param("hostport") . $_ + if !$self->_missing("hostport"); + $_ = add_get_arg($_, "formid", $self->{"form"}->param("cformid")); + if ($ENV{"REQUEST_METHOD"} eq "POST") { + http_303 $_; + } else { + http_307 $_; + } + } + # Referer2 specified -- return to referer2 + if (!$self->_missing("referer2")) { + $_ = $self->{"form"}->param("referer2"); + # Return to the hostport + } elsif (!$self->_missing("hostport")) { + $_ = $self->{"form"}->param("hostport") . "/magicat/"; + } else { + $_ = "/magicat/"; + } + if ($ENV{"REQUEST_METHOD"} eq "POST") { + http_303 $_; + } else { + http_307 $_; + } +} + +# _redir_selgrp: Suspend and move to the group selection form +sub _redir_selgrp : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if !defined $self->{"form"}->param("selgrp"); + call_form FORM_GROUPS, undef, "import_selgrp"; +} + +# _redir_delgrp: Remove the group +sub _redir_delgrp : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if !defined $self->{"form"}->param("delgrp"); + $self->{"form"}->delete("grp"); + success_redirect undef; +} + +# _redir_selparent: Suspend and move to the parent selection form +sub _redir_selparent : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selparent"); + call_form FORM_THIS, undef, "import_selparent"; +} + +# _redir_delparent: Remove the parent +sub _redir_delparent : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("delparent"); + $self->{"form"}->delete("parent"); + success_redirect undef; +} + +# +# Private utility methods. Do not override them. +# +# _missing: Check if certain columns are submitted +sub _missing : method { + local ($_, %_); + my ($self, @cols); + ($self, @cols) = @_; + %_ = map { $_ => 1 } $self->{"form"}->param; + foreach (@cols) { + return {"msg"=>N_("The following field was not received: \"[_1]\"."), + "margs"=>[$_], + "isform"=>0} + if !exists $_{$_}; + } + # OK + return; +} + +# _trim: Trim spaces from both sides of a field +sub _trim : method { + local ($_, %_); + my ($self, @cols); + ($self, @cols) = @_; + foreach my $col (@cols) { + s/^\s*(.*?)\s*$/$1/s foreach @{$self->{"form"}->param_fetch($col)} + } + return; +} + +# _trimtext: Trim spaces and blank lines from both sides of a text +sub _trimtext : method { + local ($_, %_); + my ($self, @cols); + ($self, @cols) = @_; + foreach my $col (@cols) { + foreach (@{$self->{"form"}->param_fetch($col)}) { + # Trim blank lines + s/^(?:\s*\n)?(.*?)\s*$/$1/s; + # Trim the trailing spaces of each line + s/[^\S\n]+\n/\n/g; + } + } + return; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/AcctRec.pm b/lib/perl5/Selima/Checker/AcctRec.pm new file mode 100644 index 0000000..b3a6d39 --- /dev/null +++ b/lib/perl5/Selima/Checker/AcctRec.pm @@ -0,0 +1,210 @@ +# Selima Website Content Management System +# AcctRec.pm: The accounting record form checker. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-22 + +package Selima::Checker::AcctRec; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::CallForm; +use Selima::ChkFunc; +use Selima::ShortCut; +use Selima::DataVars qw($DBH :forms); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "acctrecs" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + ${$self->{"maxlens"}}{"amount"} = 9; + return $self; +} + +# _check_trx: Check the transaction +sub _check_trx : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("trx"); + return $error if defined $error; + # Regularize it + $self->_trim("trx"); + # Check if it is filled + return {"msg"=>N_("Please select a accounting transaction.")} + if $form->param("trx") eq ""; + # Check if the transaction exists + return {"msg"=>N_("This accounting transaction does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("trx")}[0], "accttrx"; + # OK + return; +} + +# _check_type: Check the type +sub _check_type : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("type"); + return $error if defined $error; + # Regularize it + $self->_trim("type"); + # Check the option value + return {"msg"=>N_("This option is invalid. Please select a proper type.")} + unless $form->param("type") =~ /^(?:debit|credit)$/; + # OK + return; +} + +# _check_ord: Check the order +# Use the default order checker + +# _check_subj: Check the subject +sub _check_subj : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("subj"); + return $error if defined $error; + # Regularize it + $self->_trim("subj"); + # Check if it is filled + return {"msg"=>N_("Please select a accounting subject.")} + if $form->param("subj") eq ""; + # Check if the subject exists + return {"msg"=>N_("This accounting subject does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("subj")}[0], "acctsubj"; + # Check if this is the last level subject + $sql = "SELECT * FROM acctsubj" + . " WHERE parent=" . $form->param("subj") . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("Only a last-level accounting subject is allowed for an accounting subject.")} + if $sth->rows > 0; + # OK + return; +} + +# _check_summary: Check the summary +sub _check_summary : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("summary"); + return $error if defined $error; + # Regularize it + $self->_trim("summary"); + # Skip if it is not filled + return if $form->param("summary") eq ""; + # Check the length + return {"msg"=>N_("This summary is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"summary"}]} + if length $form->param("summary") > ${$self->{"maxlens"}}{"summary"}; + # OK + return; +} + +# _check_amount: Check the amount +sub _check_amount : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("amount"); + return $error if defined $error; + # Regularize it + $self->_trim("amount"); + $_ = $form->param("amount"); + s/NT\$ ?//; + s/,//g; + s/\.0+$//; + $form->param("amount", $_); + # Check if it is filled + return {"msg"=>N_("Please fill in the amount.")} + if $form->param("amount") eq ""; + # Check the length + return {"msg"=>N_("This amount is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"amount"}]} + if length $form->param("amount") > ${$self->{"maxlens"}}{"amount"}; + # Check if it is a valid positive integer + return {"msg"=>N_("Please fill in a positive integer amount.")} + unless $form->param("amount") =~ /^\d+$/ && $form->param("amount") > 0; + # Set to an integer + $_ = $form->param("amount"); + $_ += 0; + $form->param("amount", $_); + # OK + return; +} + +# _redir_seltrx: Suspend and move to the transaction selection form +sub _redir_seltrx : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if !defined $self->{"form"}->param("seltrx"); + call_form FORM_ACCTTRX, undef, "import_seltrx"; +} + +# _redir_deltrx: Remove the transaction +sub _redir_deltrx : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if !defined $self->{"form"}->param("deltrx"); + $self->{"form"}->delete("trx"); + success_redirect undef; +} + +# _redir_selsubj: Suspend and move to the accounting subject selection form +sub _redir_selsubj : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if !defined $self->{"form"}->param("selsubj"); + call_form FORM_ACCTSUBJ, ["list=lastlv"], "import_selsubj"; +} + +# _redir_delsubj: Remove the accounting subject +sub _redir_delsubj : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if !defined $self->{"form"}->param("delsubj"); + $self->{"form"}->delete("subj"); + success_redirect undef; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/AcctSubj.pm b/lib/perl5/Selima/Checker/AcctSubj.pm new file mode 100644 index 0000000..89f75ef --- /dev/null +++ b/lib/perl5/Selima/Checker/AcctSubj.pm @@ -0,0 +1,147 @@ +# Selima Website Content Management System +# AcctSubj.pm: The accounting subject form checker. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-08-23 + +package Selima::Checker::AcctSubj; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::CallForm; +use Selima::FetchRec; +use Selima::ShortCut; +use Selima::DataVars qw($DBH); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "acctsubj" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_code: Check the code +sub _check_code : method { + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("code"); + return $error if defined $error; + # Regularize it + $self->_trim("code"); + # Check if it is filled + return {"msg"=>N_("Please fill in the code.")} + if $form->param("code") eq ""; + # Check the length + return {"msg"=>N_("This code is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"code"}]} + if length $form->param("code") > ${$self->{"maxlens"}}{"code"}; + # Check if the characters used are valid + return {"msg"=>N_("Only numbers are allowed for the code.")} + unless $form->param("code") =~ /^\d+$/; + # Check if this item is duplicated + @_ = qw(); + push @_, "code=" . $DBH->quote($form->param("code")); + push @_, "sn!=" . $self->{"sn"} if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This accounting subject already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + # Check if its parent code exists + if (length $form->param("code") > 1) { + $_ = substr $form->param("code"), 0, -1; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE code=" . $DBH->quote($_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("Accounting subject [_1] does not exist. You cannot create a subject under that."), + "margs"=>[$_]} + if $sth->rows == 0; + } + # OK + return; +} + +# _check_parent: Check the parent subject +sub _check_parent : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql, %row); + $self = $_[0]; + $form = $self->{"form"}; + # "topmost not set" has a different form context + return {"msg"=>N_("Please select a parent accounting subject.")} + if $self->_missing("topmost"); + # Regularize it + $self->_trim("topmost"); + # Check the option value + return {"msg"=>N_("This option is invalid. Please select a proper parent accounting subject.")} + unless $form->param("topmost") =~ /^(?:true|false)$/; + # Check the parent subject if not a topmost subject + if ($form->param("topmost") eq "false") { + # Check if our code says we are topmost + if (!$self->_missing("code")) { + $self->_trim("code"); + return {"msg"=>N_("An accounting subject having its code with a single digit must not have a parent.")} + if length $form->param("code") < 2; + } + # Check if it exists + $error = $self->_missing("parent"); + return $error if defined $error; + # Regularize it + $self->_trim("parent"); + # Check if it is filled + return {"msg"=>N_("Please select a parent accounting subject.")} + if $form->param("parent") eq ""; + # Check if the parent subject is itself + return {"msg"=>N_("An accounting subject cannot belong to itself. Please select another one.")} + if $self->{"iscur"} && $form->param("parent") == $self->{"sn"}; + # Check if this subject exists + %row = fetchrec ${$form->param_fetch("parent")}[0], "acctsubj"; + return {"msg"=>N_("This parent accounting subject does not exist anymore. Please select another one.")} + if keys %row == 0; + # Check if the parent matches our code + if (!$self->_missing("code")) { + $_ = substr $form->param("code"), 0, -1; + return {"msg"=>N_("The parent accounting subject of accounting subject [_1] must be of code [_2], not [_3]."), + "margs"=>[$form->param("code"), $_, $row{"code"}]} + if $row{"code"} ne $_; + } + # Check the parent subject if a topmost subject + } else { + # Check if our code says we are not topmost + if (!$self->_missing("code")) { + $self->_trim("code"); + return {"msg"=>N_("An accounting subject having its code with more than one digit must have a parent.")} + if length $form->param("code") > 1; + } + } + # OK + return; +} + +# _check_title: Check the title +# Use the default title checker + +return 1; diff --git a/lib/perl5/Selima/Checker/AcctTrx.pm b/lib/perl5/Selima/Checker/AcctTrx.pm new file mode 100644 index 0000000..c287782 --- /dev/null +++ b/lib/perl5/Selima/Checker/AcctTrx.pm @@ -0,0 +1,268 @@ +# Selima Website Content Management System +# AcctTrx.pm: The accounting transaction form checker. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-22 + +package Selima::Checker::AcctTrx; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::Accounting; +use Selima::CallForm; +use Selima::ChkFunc; +use Selima::FetchRec; +use Selima::ShortCut; +use Selima::DataVars qw($DBH :forms); + +use Selima::Checker::AcctRec; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "accttrx" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + # Regularize the form subtype + $self->_trim("formsub") if !$self->_missing("formsub"); + # Record the form subtype + $self->{"subtype"} = $self->{"form"}->param("formsub"); + return $self; +} + +# _check_date: Check the date +# Use the default date checker + +# _check_ord: Check the order +# Use the default order checker + +# _check_recs: Check the records +sub _check_recs : method { + local ($_, %_); + my ($self, $form, $error, $debtcount, $crdtcount); + $self = $_[0]; + $form = $self->{"form"}; + # Check the subtype + # Check if it exists + $error = $self->_missing("formsub"); + return $error if defined $error; + # Check the option value + return {"msg"=>N_("This form suptype is invalid. Please specify a proper user.")} + unless $self->{"subtype"} =~ /^(?:expense|income|trans)$/; + # A form to fill in a cash expense transaction + if ($self->{"subtype"} eq "expense") { + $crdtcount = 0; + } else { + # Find the last-used credit record + for ( $_ = 0; + defined $form->param("crdt$_" . "subj") + && defined $form->param("crdt$_" . "summary") + && defined $form->param("crdt$_" . "amount"); $_++) {}; + if ($_ > 0) { + for ( $_--; + $_ >= 0 + && $form->param("crdt$_" . "subj") eq "" + && $form->param("crdt$_" . "summary") eq "" + && $form->param("crdt$_" . "amount") eq ""; $_--) {}; + } + $crdtcount = $_ + 1; + if ($crdtcount == 0) { + return {"msg"=>N_("Please fill in the credit side of the accounting transaction.")} + if $self->{"subtype"} eq "trans"; + return {"msg"=>N_("Please fill in the accounting transaction content.")}; + } + } + # A form to fill in a cash income transaction + if ($self->{"subtype"} eq "income") { + $debtcount = 0; + } else { + # Find the last-used debit record + for ( $_ = 0; + defined $form->param("debt$_" . "subj") + && defined $form->param("debt$_" . "summary") + && defined $form->param("debt$_" . "amount"); $_++) {}; + if ($_ > 0) { + for ( $_--; + $_ >= 0 + && $form->param("debt$_" . "subj") eq "" + && $form->param("debt$_" . "summary") eq "" + && $form->param("debt$_" . "amount") eq ""; $_--) {}; + } + $debtcount = $_ + 1; + if ($debtcount == 0) { + return {"msg"=>N_("Please fill in the debit side of the accounting transaction.")} + if $self->{"subtype"} eq "trans"; + return {"msg"=>N_("Please fill in the accounting transaction content.")}; + } + } + # Check the debit records + for ($_ = 0; $_ < $debtcount; $_++) { + my ($subform, $checker, $error); + # Regularize it + $self->_trim("debt$_" . "subj"); + $self->_trim("debt$_" . "summary"); + $self->_trim("debt$_" . "amount"); + # Skip if it is not filled + next if $form->param("debt$_" . "subj") eq "" + && $form->param("debt$_" . "summary") eq "" + && $form->param("debt$_" . "amount") eq ""; + # Check with the subform checker + $subform = new CGI(""); + $subform->param("trx", $self->{"sn"}) if $self->{"iscur"}; + $subform->param("subj", $form->param("debt$_" . "subj")); + $subform->param("summary", $form->param("debt$_" . "summary")); + $subform->param("amount", $form->param("debt$_" . "amount")); + $checker = new Selima::Checker::AcctRec($subform); + $error = $checker->check("subj", "summary", "amount"); + return $error if defined $error; + $form->param("debt$_" . "subj", $subform->param("subj")); + $form->param("debt$_" . "summary", $subform->param("summary")); + $form->param("debt$_" . "amount", $subform->param("amount")); + } + # Check the credit records + for ($_ = 0; $_ < $crdtcount; $_++) { + my ($subform, $checker, $error); + # Regularize it + $self->_trim("crdt$_" . "subj"); + $self->_trim("crdt$_" . "summary"); + $self->_trim("crdt$_" . "amount"); + # Skip if it is not filled + next if $form->param("crdt$_" . "subj") eq "" + && $form->param("crdt$_" . "summary") eq "" + && $form->param("crdt$_" . "amount") eq ""; + # Check with the subform checker + $subform = new CGI(""); + $subform->param("trx", $self->{"sn"}) if $self->{"iscur"}; + $subform->param("subj", $form->param("crdt$_" . "subj")); + $subform->param("summary", $form->param("crdt$_" . "summary")); + $subform->param("amount", $form->param("crdt$_" . "amount")); + $checker = new Selima::Checker::AcctRec($subform); + $error = $checker->check("subj", "summary", "amount"); + return $error if defined $error; + $form->param("crdt$_" . "subj", $subform->param("subj")); + $form->param("crdt$_" . "summary", $subform->param("summary")); + $form->param("crdt$_" . "amount", $subform->param("amount")); + } + # Check the balance + if ($self->{"subtype"} eq "trans") { + my ($sumdebit, $sumcredit); + for ($_ = 0, $sumdebit = 0; $_ < $debtcount; $_++) { + # Skip if it is not filled + next if $form->param("debt$_" . "amount") eq ""; + $sumdebit += $form->param("debt$_" . "amount"); + } + for ($_ = 0, $sumcredit = 0; $_ < $crdtcount; $_++) { + # Skip if it is not filled + next if $form->param("crdt$_" . "amount") eq ""; + $sumcredit += $form->param("crdt$_" . "amount"); + } + return {"msg"=>N_("The total amounts of the debit side and the credit side are not balanced (debit [_1], credit [_2]."), + "margs"=>[$sumdebit, $sumcredit]} + if $sumdebit != $sumcredit; + } + return; +} + +# _check_note: Check the note +sub _check_note : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("note"); + return $error if defined $error; + # Regularize it + $self->_trimtext("note"); + # Skip if it is not filled + $form->param("note", "") + if $form->param("note") eq C_("Fill in the note here."); + return if $form->param("note") eq ""; + # Check the length + return {"msg"=>N_("This note is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"note"}]} + if length $form->param("note") > ${$self->{"maxlens"}}{"note"}; + # OK + return; +} + +# _redir_cnvttrans: Convert to a transfer transaction +sub _redir_cnvttrans : method { + local ($_, %_); + my ($self, $form, $sum); + $self = $_[0]; + $form = $self->{"form"}; + # Skip if not requested + return if $self->_missing("cnvttrans"); + # Skip if the form subtype not supplied + return if !defined $self->{"subtype"}; + # Skip if it is not an cash expense/income transaction + return if $self->{"subtype"} !~ /^(?:expense|income)$/; + # Set to a transfer transaction + $form->param("formsub", "trans"); + # Set the other side + # A form to fill in a cash expense transaction + if ($self->{"subtype"} eq "expense") { + $form->param("crdt0subj", acctsubj_sn(ACCTSUBJ_CASH)); + $form->param("crdt0summary", undef); + $sum = 0; + foreach (grep /^debt\d+amount$/, $form->param) { + $self->_trim($_); + $_ = $form->param($_); + s/NT\$ ?//; + s/,//g; + s/\.0+$//; + $sum += $_ if /^\d+$/; + } + $form->param("crdt0amount", $sum); + # A form to fill in a cash income transaction + } elsif ($self->{"subtype"} eq "income") { + $form->param("debt0subj", acctsubj_sn(ACCTSUBJ_CASH)); + $form->param("debt0summary", undef); + $sum = 0; + foreach (grep /^crdt\d+amount$/, $form->param) { + $self->_trim($_); + $_ = $form->param($_); + s/NT\$ ?//; + s/,//g; + s/\.0+$//; + $sum += $_ if /^\d+$/; + } + $form->param("debt0amount", $sum); + } + # Show the form again + success_redirect undef; +} + +# _redir_selsubj: Suspend and move to the accounting subject selection form +sub _redir_selsubj : method { + local ($_, %_); + my $self; + $self = $_[0]; + @_ = sort grep /^sel(?:debt|crdt)\d+subj$/, $self->{"form"}->param; + # Skip if not requested + return if @_ == 0; + # Record the hit button + $_[0] =~ /^sel((?:debt|crdt)\d+)subj$/; + $self->{"form"}->param("caller_index", $1); + call_form FORM_ACCTSUBJ, ["list=lastlv"], "import_selsubj"; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/Group.pm b/lib/perl5/Selima/Checker/Group.pm new file mode 100644 index 0000000..1fe596a --- /dev/null +++ b/lib/perl5/Selima/Checker/Group.pm @@ -0,0 +1,218 @@ +# Selima Website Content Management System +# Group.pm: The account group form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-12 + +package Selima::Checker::Group; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::CallForm; +use Selima::ChkPriv; +use Selima::DataVars qw($DBH :forms); +use Selima::ShortCut; +use Selima::UserName; + +use Selima::Checker::UserMem; +use Selima::Checker::GroupMem; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my $class; + ($class, @_) = @_; + $_[1] = "groups" if scalar(@_) < 2 || !defined $_[1]; + return $class->SUPER::new(@_); +} + +# _check_id: Check the group ID. +sub _check_id : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # Skip for a non-super-user editing a super-user group + return if $self->{"iscur"} && !is_su && $self->{"sn"} == su_group_sn; + # Check if it exists + $error = $self->_missing("id"); + return $error if defined $error; + # Regularize it + $self->_trim("id"); + # Check if it is filled + return {"msg"=>N_("Please fill in the group ID.")} + if $form->param("id") eq ""; + # Check the length + return {"msg"=>N_("This group ID. is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"id"}]} + if length $form->param("id") > ${$self->{"maxlens"}}{"id"}; + return {"msg"=>N_("This group ID. is too short. (Min. length [#,_1])"), + "margs"=>[${$self->{"minlens"}}{"id"}]} + if length $form->param("id") < ${$self->{"minlens"}}{"id"}; + # Check if the characters used are valid + return {"msg"=>N_("Only lower-case English letters, numbers and underscores are allowed for the group ID.")} + unless $form->param("id") =~ /^[a-z][a-z0-9_]*$/; + # Check if this item is duplicated + @_ = qw(); + push @_, "id=" . $DBH->quote($form->param("id")); + push @_, "sn!=" . $self->{"sn"} if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This group already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + # OK + return; +} + +# _check_dsc: Check the group description +sub _check_dsc : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("id"); + return $error if defined $error; + # Regularize it + $self->_trim("dsc"); + # Check if it is filled + return {"msg"=>N_("Please fill in the privilege description.")} + if $form->param("dsc") eq ""; + # Check the length + return {"msg"=>N_("This privilege description is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"dsc"}]} + if length $form->param("dsc") > ${$self->{"maxlens"}}{"dsc"}; + # OK + return; +} + +# _check_subuser: Check the user members +sub _check_subuser : method { + local ($_, %_); + my ($self, $form, $error, $subform, $checker); + $self = $_[0]; + $form = $self->{"form"}; + # Skip for a non-super-user editing a super-user group + return if $self->{"iscur"} && !is_su && $self->{"sn"} == su_group_sn; + # Get the selected items + @_ = map $_ . "sn", + grep /^subuser\d+/ && defined $form->param($_ . "sn"), $form->param; + # Regularize them + $self->_trim(@_); + # Merge the duplicates + %_ = map { ($form->param($_))[0] => 1 } @_; + $subform = new CGI(""); + $subform->param("grp", $self->{"sn"}) if $self->{"iscur"}; + foreach (keys %_) { + $subform->param("member", $_); + $checker = new Selima::Checker::UserMem($subform); + $error = $checker->check("member"); + return $error if defined $error; + } + # OK + return; +} + +# _check_subgroup: Check the group members +sub _check_subgroup : method { + local ($_, %_); + my ($self, $form, $error, $subform, $checker); + $self = $_[0]; + $form = $self->{"form"}; + # Skip for a non-super-user editing a super-user group + return if $self->{"iscur"} && !is_su && $self->{"sn"} == su_group_sn; + # Get the selected items + @_ = map $_ . "sn", + grep /^subgroup\d+/ && defined $form->param($_ . "sn"), $form->param; + # Regularize them + $self->_trim(@_); + # Merge the duplicates + %_ = map { ($form->param($_))[0] => 1 } @_; + $subform = new CGI(""); + $subform->param("grp", $self->{"sn"}) if $self->{"iscur"}; + foreach (keys %_) { + $subform->param("member", $_); + $checker = new Selima::Checker::GroupMem($subform); + $error = $checker->check("member"); + return $error if defined $error; + } + # OK + return; +} + +# _check_supgroup: Check the belonging groups +sub _check_supgroup : method { + local ($_, %_); + my ($self, $form, $error, $subform, $checker); + $self = $_[0]; + $form = $self->{"form"}; + # Skip for a non-super-user editing a super-user group + return if $self->{"iscur"} && !is_su && $self->{"sn"} == su_group_sn; + # Get the selected items + @_ = map $_ . "sn", + grep /^supgroup\d+/ && defined $form->param($_ . "sn"), $form->param; + # Regularize them + $self->_trim(@_); + # Merge the duplicates + %_ = map { ($form->param($_))[0] => 1 } @_; + $subform = new CGI(""); + $subform->param("member", $self->{"sn"}) if $self->{"iscur"}; + foreach (keys %_) { + $subform->param("grp", $_); + $checker = new Selima::Checker::GroupMem($subform); + $error = $checker->check("grp"); + return $error if defined $error; + } + # OK + return; +} + +# _redir_selsubuser: Suspend and move to the subordinate user selection form +sub _redir_selsubuser : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selsubuser"); + call_form FORM_USERS, undef, "import_selsubuser"; +} + +# _redir_selsubgroup: Suspend and move to the subordinate group selection form +sub _redir_selsubgroup : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selsubgroup"); + call_form FORM_GROUPS, undef, "import_selsubgroup"; +} + +# _redir_selsupgroup: Suspend and move to the superordinate group selection form +sub _redir_selsupgroup : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selsupgroup"); + call_form FORM_GROUPS, undef, "import_selsupgroup"; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/GroupMem.pm b/lib/perl5/Selima/Checker/GroupMem.pm new file mode 100644 index 0000000..da70a83 --- /dev/null +++ b/lib/perl5/Selima/Checker/GroupMem.pm @@ -0,0 +1,143 @@ +# Selima Website Content Management System +# GroupMem.pm: The group-to-group membership form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-13 + +package Selima::Checker::GroupMem; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::ChkFunc; +use Selima::CallForm; +use Selima::DataVars qw($DBH :forms); +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my $class; + ($class, @_) = @_; + $_[1] = "groupmem" if scalar(@_) < 2 || !defined $_[1]; + return $class->SUPER::new(@_); +} + +# check: Run a list of checks +sub check : method { + local ($_, %_); + my ($self, $error, @cols); + ($self, @cols) = @_; + # Run the parent method first + $error = $self->SUPER::check(@cols); + return $error if defined $error; + # See if we need to check the duplicates. Check it in the end. + %_ = map { $_ => 1 } @cols; + if (exists $_{"grp"} && exists $_{"member"}) { + $error = $self->__check_dup(); + return $error if defined $error; + } + return; +} + +# _check_grp: Check the group +sub _check_grp : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Run the default group checker + $error = $self->SUPER::_check_grp; + return $error if defined $error; + # Check if the group and the member are different + return {"msg"=>N_("Please select a different belonging group.")} + if !$self->_missing("member") + && $form->param("member") ne "" + && $form->param("grp") == $form->param("member"); + # OK + return; +} + +# _check_member: Check the member +sub _check_member : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("member"); + return $error if defined $error; + # Regularize it + $self->_trim("member"); + # Check if it is filled + return {"msg"=>N_("Please select a member.")} + if $form->param("member") eq ""; + # Check if this group exists + return {"msg"=>N_("This member does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("member")}[0], "groups AS grpmembers"; + # Check if the group and the member are different + return {"msg"=>N_("Please select a different group member.")} + if !$self->_missing("grp") + && $form->param("grp") ne "" + && $form->param("grp") == $form->param("member"); + # OK + return; +} + +# __check_dup: Check if this item is duplicated +sub __check_dup : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + @_ = qw(); + push @_, "grp=" . $form->param("grp"); + push @_, "member=" . $form->param("member"); + push @_, "sn!=" . $self->{"sn"} + if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This membership record already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + return; +} + +# _redir_selmember: Suspend and move to the member selection form +sub _redir_selmember : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selmember"); + call_form FORM_GROUPS, undef, "import_selmember"; +} + +# _redir_delmember: Remove the member +sub _redir_delmember : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("delmember"); + $self->{"form"}->delete("member"); + success_redirect undef; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/Guestbook.pm b/lib/perl5/Selima/Checker/Guestbook.pm new file mode 100644 index 0000000..e43bb60 --- /dev/null +++ b/lib/perl5/Selima/Checker/Guestbook.pm @@ -0,0 +1,157 @@ +# Selima Website Content Management System +# Guestbook.pm: The base administrative guestbook form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +package Selima::Checker::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "guestbook" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + ${$self->{"maxlens"}}{"message"} = 10240; + return $self; +} + +# _check_name: Check the name +sub _check_name : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("name"); + return $error if defined $error; + # Regularize it + $self->_trim("name"); + # Check the length + return {"msg"=>N_("This signature is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"name"}]} + if length $form->param("name") > ${$self->{"maxlens"}}{"name"}; + # OK + return; +} + +# _check_name_req: Check the name (required) +sub _check_name_req : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("name"); + return $error if defined $error; + # Regularize it + $self->_trim("name"); + # Check if it is filled + return {"msg"=>N_("Please fill in the signature.")} + if $form->param("name") eq ""; + # Check the length + return {"msg"=>N_("This signature is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"name"}]} + if length $form->param("name") > ${$self->{"maxlens"}}{"name"}; + # OK + return; +} + +# _check_identity: Check the identity +sub _check_identity : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("identity"); + return $error if defined $error; + # Regularize it + $self->_trim("identity"); + # Check the length + return {"msg"=>N_("This identity is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"identity"}]} + if length $form->param("identity") > ${$self->{"maxlens"}}{"identity"}; + # OK + return; +} + +# _check_location: Check the location +sub _check_location : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("location"); + return $error if defined $error; + # Regularize it + $self->_trim("location"); + # Check the length + return {"msg"=>N_("This location is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"location"}]} + if length $form->param("location") > ${$self->{"maxlens"}}{"location"}; + # OK + return; +} + +# _check_email: Check the e-mail +sub _check_email : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("email"); + return $error if defined $error; + # Regularize it + $self->_trim("email"); + # Check the length + return {"msg"=>N_("This e-mail is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"email"}]} + if length $form->param("email") > ${$self->{"maxlens"}}{"email"}; + # OK + return; +} + +# _check_url: Check the URL +sub _check_url : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("url"); + return $error if defined $error; + # Regularize it + $self->_trim("url"); + # Check the length + return {"msg"=>N_("This website URL is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"url"}]} + if length $form->param("url") > ${$self->{"maxlens"}}{"url"}; + # OK + return; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/Guestbook/Public.pm b/lib/perl5/Selima/Checker/Guestbook/Public.pm new file mode 100644 index 0000000..422e9c3 --- /dev/null +++ b/lib/perl5/Selima/Checker/Guestbook/Public.pm @@ -0,0 +1,224 @@ +# Selima Website Content Management System +# Public.pm: The base guestbook form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-23 + +package Selima::Checker::Guestbook::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker::Guestbook); + +use URI::Find qw(); + +use Selima::DataVars qw($DBH :lninfo); +use Selima::GetLang; +use Selima::HTTP; +use Selima::ShortCut; + +use vars qw($uri_finder); + +# _check_name: Check the name +sub _check_name : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("name"); + return $error if defined $error; + # Regularize it + $self->_trim("name"); + # Skip if it is not filled + return if $form->param("name") eq ""; + # Check the length + return {"msg"=>N_("Your signature is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"name"}]} + if length $form->param("name") > ${$self->{"maxlens"}}{"name"}; + # OK + return; +} + +# _check_name_req: Check the name (required) +sub _check_name_req : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("name"); + return $error if defined $error; + # Regularize it + $self->_trim("name"); + # Check if it is filled + return {"msg"=>N_("Please fill in your signature.")} + if $form->param("name") eq ""; + # Check the length + return {"msg"=>N_("Your signature is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"name"}]} + if length $form->param("name") > ${$self->{"maxlens"}}{"name"}; + # OK + return; +} + +# _check_identity: Check the identity +sub _check_identity : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("identity"); + return $error if defined $error; + # Regularize it + $self->_trim("identity"); + # Skip if it is not filled + return if $form->param("identity") eq ""; + # Check the length + return {"msg"=>N_("Your identity is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"identity"}]} + if length $form->param("identity") > ${$self->{"maxlens"}}{"identity"}; + # OK + return; +} + +# _check_location: Check the location +sub _check_location : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("location"); + return $error if defined $error; + # Regularize it + $self->_trim("location"); + # Skip if it is not filled + return if $form->param("location") eq ""; + # Check the length + return {"msg"=>N_("Your location is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"location"}]} + if length $form->param("location") > ${$self->{"maxlens"}}{"location"}; + # OK + return; +} + +# _check_email: Check the e-mail +sub _check_email : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("email"); + return $error if defined $error; + # Regularize it + $self->_trim("email"); + # Skip if it is not filled + return if $form->param("email") eq ""; + # Check the length + return {"msg"=>N_("Your e-mail is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"email"}]} + if length $form->param("email") > ${$self->{"maxlens"}}{"email"}; + # OK + return; +} + +# _check_url: Check the URL +sub _check_url : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("url"); + return $error if defined $error; + # Regularize it + $self->_trim("url"); + # Skip if it is not filled + return if $form->param("url") eq ""; + # Check the length + return {"msg"=>N_("Your website URL is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"url"}]} + if length $form->param("url") > ${$self->{"maxlens"}}{"url"}; + # OK + return; +} + +# _check_message: The default message checker +sub _check_message : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("message"); + return $error if defined $error; + # Regularize it + $self->_trimtext("message"); + # Check if it is filled + $form->param("message", "") + if $form->param("message") eq C_("Fill in your message here."); + return {"msg"=>N_("Please fill in your message.")} + if $form->param("message") eq ""; + # Check the length + return {"msg"=>N_("Your message is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"message"}]} + if length $form->param("message") > ${$self->{"maxlens"}}{"message"}; + # OK + return; +} + +# _check_flood: Check the flooding attack +sub _check_flood : method { + local ($_, %_); + my ($self, $form, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # At most 5 posts/hours from a single IP + $sql = "SELECT count(*) AS count FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE created > now() - cast('1 hour' AS interval)" + . " AND ip='" . $ENV{"REMOTE_ADDR"} . "';\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("You can post at most 5 messages in 1 hour.")} + if ${$sth->fetch}[0] > 5; + # OK + return; +} + +# _check_dup: Check the duplicated message +sub _check_dup : method { + local ($_, %_); + my ($self, $form, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # No duplicated message in the recent 5 posts + $sql = "SELECT message FROM " . $DBH->quote_identifier($self->{"table"}) + . " ORDER BY created DESC LIMIT 5;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + for ($_ = 0; $_ < $sth->rows; $_++) { + return {"msg"=>N_("Your message is already posted.")} + if ${$sth->fetch}[0] eq $form->param("message"); + } + # OK + return; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/Link.pm b/lib/perl5/Selima/Checker/Link.pm new file mode 100644 index 0000000..3a0ae3a --- /dev/null +++ b/lib/perl5/Selima/Checker/Link.pm @@ -0,0 +1,252 @@ +# Selima Website Content Management System +# Link.pm: The related-link form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::Checker::Link; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Email::Valid; + +use Selima::ChkFunc; +use Selima::DataVars qw($DBH); +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "links" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + ${$self->{"minlens"}}{"email"} = 5; + return $self; +} + +# _check_addr: Check the address +sub _check_addr : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("addr"); + return $error if defined $error; + # Regularize it + $self->_trim("addr"); + # Skip if it is not filled + return if $form->param("addr") eq ""; + # Check the length + return {"msg"=>N_("This address is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"addr"}]} + if length $form->param("addr") > ${$self->{"maxlens"}}{"addr"}; + # OK + return; +} + +# _check_cats: Check the categories list +sub _check_cats : method { + local ($_, %_); + my ($self, $form, $error, $val); + $self = $_[0]; + $form = $self->{"form"}; + # Loop each category + for ($_ = 0, %_ = qw(); !$self->_missing("cat$_"); $_++) { + # Regularize it + $self->_trim("cat$_"); + # Skip if it is not filled + next if $form->param("cat$_") eq ""; + # Check if this selection is duplicated + return {"msg"=>N_("This category is duplicated. You cannot set duplicated ones.")} + if exists $_{$form->param("cat$_")}; + # Check if the category exists + return {"msg"=>N_("This category does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("cat$_")}[0], "linkcat"; + $_{$form->param("cat$_")} = 1; + } + # Check if there is any category selected + return {"msg"=>N_("Please select a category.")} + if scalar(keys %_) == 0; + # OK + return; +} + +# _check_email: Check the e-mail +sub _check_email : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("email"); + return $error if defined $error; + # Regularize it + $self->_trim("email"); + # Skip if it is not filled + return if $form->param("email") eq ""; + # Check the length + return {"msg"=>N_("This e-mail is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"email"}]} + if length $form->param("email") > ${$self->{"maxlens"}}{"email"}; + return {"msg"=>N_("This e-mail is too short. (Min. length [#,_1])"), + "margs"=>[${$self->{"minlens"}}{"email"}]} + if length $form->param("email") < ${$self->{"minlens"}}{"email"}; + # Check the e-mail validity + return {"msg"=>N_("Please fill in a valid e-mail address.")} + if !Email::Valid->rfc822($form->param("email")); + return {"msg"=>N_("The domain of this e-mail does not exists. Check if there is any typo in it.")} + if $self->_missing("hid") + && !Email::Valid->mx($form->param("email")); + # OK + return; +} + +# _check_fax: Check the facsimile number +sub _check_fax : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("fax"); + return $error if defined $error; + # Regularize it + $self->_trim("fax"); + # Skip if it is not filled + return if $form->param("fax") eq ""; + # Check the length + return {"msg"=>N_("This facsimile number is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"fax"}]} + if length $form->param("fax") > ${$self->{"maxlens"}}{"fax"}; + # OK + return; +} + +# _check_icon: Check the link icon +sub _check_icon : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("icon"); + return $error if defined $error; + # Regularize it + $self->_trim("icon"); + # Skip if it is not filled + return if $form->param("icon") eq "" || $form->param("icon") eq "http://"; + # Check the length + return {"msg"=>N_("This link icon URL is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"icon"}]} + if length $form->param("icon") > ${$self->{"maxlens"}}{"icon"}; + # Check its format + return {"msg"=>N_("Please fill in a valid link icon URL.")} + if !is_url_wellformed $form->param("icon"); + # Check if it is available + return {"msg"=>N_("This link icon URL is not reachable. Check if there is any typo in it.")} + if $self->_missing("hid") + && !is_url_reachable $form->param("icon"); + # OK + return; +} + +# _check_tel: Check the telephone number +sub _check_tel : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("tel"); + return $error if defined $error; + # Regularize it + $self->_trim("tel"); + # Skip if it is not filled + return if $form->param("tel") eq ""; + # Check the length + return {"msg"=>N_("This telephone number is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"tel"}]} + if length $form->param("tel") > ${$self->{"maxlens"}}{"tel"}; + # OK + return; +} + +# _check_title_2ln: The 2nd language title checker +sub _check_title_2ln : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("title_2ln"); + return $error if defined $error; + # Regularize it + $self->_trim("title_2ln"); + # Skip if it is not filled + return if $form->param("title_2ln") eq ""; + # Check the length + return {"msg"=>N_("This 2nd language title is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"title_2ln"}]} + if length $form->param("title_2ln") > ${$self->{"maxlens"}}{"title_2ln"}; + # OK + return; +} + +# _check_url: The URL checker +sub _check_url : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("url"); + return $error if defined $error; + # Regularize it + $self->_trim("url"); + # Check if it is filled + return {"msg"=>N_("Please fill in the URL.")} + if $form->param("url") eq "" || $form->param("url") eq "http://"; + # Check the length + return {"msg"=>N_("This URL is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"url"}]} + if length $form->param("url") > ${$self->{"maxlens"}}{"url"}; + # Check its format + return {"msg"=>N_("Please fill in a valid URL.")} + if !is_url_wellformed $form->param("url"); + # Check if this item is duplicated + @_ = qw(); + push @_, "url=" . $DBH->quote($form->param("url")); + push @_, "sn!=" . $self->{"sn"} if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This related link already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + # Check if it is available + return {"msg"=>N_("This URL is not reachable. Check if there is any typo in it.")} + if $self->_missing("hid") + && !is_url_reachable $form->param("url"); + # OK + return; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/LinkCat.pm b/lib/perl5/Selima/Checker/LinkCat.pm new file mode 100644 index 0000000..45442d6 --- /dev/null +++ b/lib/perl5/Selima/Checker/LinkCat.pm @@ -0,0 +1,121 @@ +# Selima Website Content Management System +# LinkCat.pm: The related-link category form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::Checker::LinkCat; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::CallForm; +use Selima::ChkFunc; +use Selima::DataVars qw($DBH :forms); +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "linkcat" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + ${$self->{"maxlens"}}{"ord"} = 2; + ${$self->{"minlens"}}{"id"} = 2; + return $self; +} + +# _check_id: Check the ID. +sub _check_id : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # Run the default ID. checker + $error = $self->SUPER::_check_id; + return $error if defined $error; + # ID. cannot be "index" to avoid overriding index.html + return {"msg"=>N_("\"index\" is dedicated to the index file index.html. You cannot set the ID. as \"index\".")} + if $form->param("id") eq "index"; + # Check if this item is duplicated + if (!$self->_missing("topmost", "parent")) { + @_ = qw(); + push @_, "id=" . $DBH->quote($form->param("id")); + push @_, "sn!=" . $self->{"sn"} if $self->{"iscur"}; + if ($form->param("topmost") eq "true") { + push @_, "parent IS NULL"; + } else { + push @_, "parent=" . $DBH->quote($form->param("parent")); + } + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This category already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + } + # OK + return; +} + +# _check_parent: Check the parent category +sub _check_parent : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # "topmost not set" has a different form context + return {"msg"=>N_("Please select a parent category.")} + if $self->_missing("topmost"); + # Regularize it + $self->_trim("topmost"); + # Check the option value + return {"msg"=>N_("This option is invalid. Please select a proper parent category.")} + unless $form->param("topmost") =~ /^(?:true|false)$/; + # Check the parent category if not a topmost category + if ($form->param("topmost") eq "false") { + # Check if it exists + $error = $self->_missing("parent"); + return $error if defined $error; + # Regularize it + $self->_trim("parent"); + # Check if it is filled + return {"msg"=>N_("Please select a parent category.")} + if $form->param("parent") eq ""; + # Check if this category exists + return {"msg"=>N_("This parent category does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("parent")}[0], "linkcat"; + if ($self->{"iscur"}) { + # Check if the parent category is itself + return {"msg"=>N_("A category cannot belong to itself. Please select another one.")} + if $form->param("parent") == $self->{"sn"}; + # Check if the parent directory is its descendant + $sql = "SELECT linkcat_ischild(" . $self->{"sn"} . ", " + . $form->param("parent") . ") AS is_child;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("A category cannot belong to its descendant. Please select another one.")} + if ${$sth->fetchrow_hashref}{"is_child"}; + } + } + # OK + return; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/LinkCatz.pm b/lib/perl5/Selima/Checker/LinkCatz.pm new file mode 100644 index 0000000..290bf47 --- /dev/null +++ b/lib/perl5/Selima/Checker/LinkCatz.pm @@ -0,0 +1,162 @@ +# Selima Website Content Management System +# LinkCatz.pm: The related-link category membership form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-03 + +package Selima::Checker::LinkCatz; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::ChkFunc; +use Selima::CallForm; +use Selima::DataVars qw($DBH :forms); +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my $class; + ($class, @_) = @_; + $_[1] = "linkcatz" if scalar(@_) < 2 || !defined $_[1]; + return $class->SUPER::new(@_); +} + +# check: Run a list of checks +sub check : method { + local ($_, %_); + my ($self, $error, @cols); + ($self, @cols) = @_; + # Run the parent method first + $error = $self->SUPER::check(@cols); + return $error if defined $error; + # See if we need to check the duplicates. Check it in the end. + %_ = map { $_ => 1 } @cols; + if (exists $_{"cat"} && exists $_{"link"}) { + $error = $self->__check_dup(); + return $error if defined $error; + } + return; +} + +# _check_cat: Check the category +sub _check_cat : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("cat"); + return $error if defined $error; + # Regularize it + $self->_trim("cat"); + # Check if it is filled + return {"msg"=>N_("Please select a category.")} + if $form->param("cat") eq ""; + # Check if the category exists + return {"msg"=>N_("This category does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("cat")}[0], "linkcat"; + # OK + return; +} + +# _check_link: Check the related link +sub _check_link : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("link"); + return $error if defined $error; + # Regularize it + $self->_trim("link"); + # Check if it is filled + return {"msg"=>N_("Please select a related link.")} + if $form->param("link") eq ""; + # Check if this link exists + return {"msg"=>N_("This related link does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("link")}[0], "links"; + # OK + return; +} + +# __check_dup: Check if this item is duplicated +sub __check_dup : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + @_ = qw(); + push @_, "cat=" . $form->param("cat"); + push @_, "link=" . $form->param("link"); + push @_, "sn!=" . $self->{"sn"} + if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This categorization record already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + return; +} + +# _redir_selcat: Suspend and move to the category selection form +sub _redir_selcat : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selcat"); + call_form FORM_LINKCAT, undef, "import_selcat"; +} + +# _redir_delcat: Remove the category +sub _redir_delcat : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("delcat"); + $self->{"form"}->delete("cat"); + success_redirect undef; +} + +# _redir_sellink: Suspend and move to the related link selection form +sub _redir_sellink : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("sellink"); + call_form FORM_LINKS, undef, "import_sellink"; +} + +# _redir_dellink: Remove the related link +sub _redir_dellink : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("dellink"); + $self->{"form"}->delete("link"); + success_redirect undef; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/ListPref.pm b/lib/perl5/Selima/Checker/ListPref.pm new file mode 100644 index 0000000..49463fe --- /dev/null +++ b/lib/perl5/Selima/Checker/ListPref.pm @@ -0,0 +1,132 @@ +# Selima Website Content Management System +# ListPref.pm: The list preference form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +package Selima::Checker::ListPref; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::CallForm; +use Selima::ChkFunc; +use Selima::DataVars qw($DBH :forms); +use Selima::HTTP; +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "userpref" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + ${$self->{"maxlens"}}{"listsize"} = 4; + return $self; +} + +# _check_domain: Check the preference domain +sub _check_domain : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("domain"); + return $error if defined $error; + # Regularize it + $self->_trim("domain"); + # Check if it is filled + return {"msg"=>N_("Please fill in the preference domain.")} + if $form->param("domain") eq ""; + # Check the length + return {"msg"=>N_("This preference domain is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"domain"}]} + if length $form->param("domain") > ${$self->{"maxlens"}}{"domain"}; + # OK + return; +} + +# _check_listcols: Check the list columns +sub _check_listcols : method { + local ($_, %_); + my ($self, $listcols, $errmsg); + $self = $_[0]; + # No need to check the validility. Invalids are simply ignored. + @_ = grep s/^listcols_//, $self->{"form"}->param; + # Obtain the preference value + $listcols = join " ", @_; + # Skip if it is not filled + return if $listcols eq ""; + # Check the length + if (length "listcols" > ${$self->{"maxlens"}}{"name"}) { + $errmsg = sprintf "Maximum preference name length too short (%d for \"%s\" %d)", + ${$self->{"maxlens"}}{"name"}, "listcols", length "listcols"; + http_500 $errmsg; + } + if (length $listcols > ${$self->{"maxlens"}}{"value"}) { + $errmsg = sprintf "Maximum preference value length too short (%d for \"%s\" %d)", + ${$self->{"maxlens"}}{"name"}, "listcols", length $listcols; + http_500 $errmsg; + } + # OK + return; +} + +# _check_listsize: Check the list size +sub _check_listsize : method { + local ($_, %_); + my ($self, $form, $error, $errmsg); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("listsize"); + return $error if defined $error; + # Regularize it + $self->_trim("listsize"); + # Check if it is filled + return {"msg"=>N_("Please fill in the number of rows per page.")} + if $form->param("listsize") eq ""; + # If there is any non-digit character + return {"msg"=>N_("Please fill in a positive integer number of rows per page.")} + unless $form->param("listsize") =~ /^[1-9][0-9]*$/; + # Set to an integer + $_ = $form->param("listsize"); + $_ += 0; + $form->param("listsize", $_); + # Check the length + return {"msg"=>N_("This number of rows per page is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"listsize"}]} + if length $form->param("listsize") > ${$self->{"maxlens"}}{"listsize"}; + # Check the length + if (length "listsize" > ${$self->{"maxlens"}}{"name"}) { + $errmsg = sprintf "Maximum preference name length too short (%d for \"%s\" %d)", + ${$self->{"maxlens"}}{"name"}, "listsize", length "listsize"; + http_500 $errmsg; + } + if (length $form->param("listsize") > ${$self->{"maxlens"}}{"value"}) { + $errmsg = sprintf "Maximum preference value length too short (%d for \"%s\" %d)", + ${$self->{"maxlens"}}{"name"}, "listsize", length $form->param("listsize"); + http_500 $errmsg; + } + # OK + return; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/LogIn.pm b/lib/perl5/Selima/Checker/LogIn.pm new file mode 100644 index 0000000..ed67d5b --- /dev/null +++ b/lib/perl5/Selima/Checker/LogIn.pm @@ -0,0 +1,238 @@ +# Selima Website Content Management System +# LogIn.pm: The log-in form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-26 + +package Selima::Checker::LogIn; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker::User); + +use Digest::MD5 qw(md5_hex); + +use Selima::Array; +use Selima::ChkPriv; +use Selima::DataVars qw($DBH :hostconf); +use Selima::Guest; +use Selima::HTTP; +use Selima::Logging; +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "users" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + $self->{"row"} = undef; + $self->{"allcols"} = [ $DBH->cols($self->{"table"}) ]; + return $self; +} + +# check: Run a list of checks +sub check : method { + local ($_, %_); + my ($self, $error, @cols); + ($self, @cols) = @_; + + # See if a log in is attemped. + %_ = map { $_ => 1 } @cols; + $self->{"login"} = exists $_{"id"} && exists $_{"passwd"} + if !exists $self->{"login"}; + # Run the parent method first + $error = $self->SUPER::check(@cols); + return $error if defined $error; + return; +} + +# _check_id: Check the user ID +sub _check_id : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("id"); + return $error if defined $error; + # Regularize it + $self->_trim("id"); + # Check if it is filled + return {"msg"=>N_("Please fill in your user ID.")} + if $form->param("id") eq ""; + # Check the length + if (length $form->param("id") > ${$self->{"maxlens"}}{"id"}) { + actlog("Log in failed for user " . $form->param("id") + . " because user ID is too long.") + if $self->{"login"}; + return {"msg"=>N_("Log in failed. Either your user ID or your password is incorrect.")}; + } + if (length $form->param("id") < ${$self->{"minlens"}}{"id"}) { + actlog("Log in failed for user " . $form->param("id") + . " because user ID is too short.") + if $self->{"login"}; + return {"msg"=>N_("Log in failed. Either your user ID or your password is incorrect.")}; + } + + # Check if this user exists + @_ = qw(); + push @_, "id=" . $DBH->quote($form->param("id")); + push @_, "NOT deleted" if in_array("deleted", @{$self->{"allcols"}}); + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + if ($sth->rows != 1) { + actlog("Log in failed for user " . $form->param("id") + . " because user ID does not exist.") + if $self->{"login"}; + return {"msg"=>N_("Log in failed. Either your user ID or your password is incorrect.")}; + } + # Save it for further reference + $self->{"row"} = $sth->fetchrow_hashref; + $self->{"sn"} = ${$self->{"row"}}{"sn"}; + # Check if log-in is closed + if ($NOLOGIN && !is_su $self->{"sn"}) { + actlog("Log in failed for user " . $form->param("id") + . " because website is temporarily closed.") + if $self->{"login"}; + # This message is duplicated + return {}; + } + # Check if this user is disabled + if (${$self->{"row"}}{"disabled"}) { + actlog("Log in failed for user " . $form->param("id") + . " because account is disabled.") + if $self->{"login"}; + return {"msg"=>N_("Your account is disabled. Contact our system administrator for assistence.")}; + } + # OK + return; +} + +# _check_passwd: Check the user password +sub _check_passwd : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Skip password checks for guests + return if exists $self->{"sn"} && is_guest $self->{"sn"}; + # Check if it exists + $error = $self->_missing("passwd"); + return $error if defined $error; + # Regularize it + $self->_trim("passwd"); + # Check if it is filled + return {"msg"=>N_("Please fill in your password.")} + if $form->param("passwd") eq ""; + # Check the length + if (length $form->param("passwd") > ${$self->{"maxlens"}}{"passwd"}) { + actlog("Log in failed for user " . $form->param("id") + . " because password is too long.") + if $self->{"login"}; + return {"msg"=>N_("Log in failed. Either your user ID or your password is incorrect.")}; + } + if (length $form->param("passwd") < ${$self->{"minlens"}}{"passwd"}) { + actlog("Log in failed for user " . $form->param("id") + . " because password is too short.") + if $self->{"login"}; + return {"msg"=>N_("Log in failed. Either your user ID or your password is incorrect.")}; + } + # Check if the password is correct + if ( defined $self->{"row"} + && md5_hex($form->param("id") . ":magicat:" + . $form->param("passwd")) eq ${$self->{"row"}}{"passwd"}) { + actlog("Log in failed for user " . $form->param("id") + . " because password is incorrect.") + if $self->{"login"}; + return {"msg"=>N_("Log in failed. Either your user ID or your password is incorrect.")}; + } + # OK + return; +} + +# _check_authdig: Check the user credential using HTTP Digest Authentication +sub _check_authdig : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Skip credential checks for guests + return if exists $self->{"sn"} && is_guest $self->{"sn"}; + # Check if it exists + http_500 "Apache::AuthDigest::API \"rd\" not supplied" + if !exists $self->{"rd"}; + http_500 "client response \"response\" not supplied" + if !exists $self->{"response"}; + http_500 "\"id\" did not checked before \"authdig\"" + if !defined $self->{"row"}; + # Check if the credential is correct + if ( !$self->{"rd"}->compare_digest_response($self->{"response"}, + ${$self->{"row"}}{"passwd"})) { + actlog("Log in failed for user " . $form->param("id") + . " because password is incorrect.") + if $self->{"login"}; + return {"msg"=>N_("Log in failed. Either your user ID or your password is incorrect.")}; + } + # OK + return; +} + +# _check_admin: Check if the user is an administrator +sub _check_admin : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Skip checking for guests + return if is_guest $self->{"sn"}; + # Skip checking for super users + return if is_su $self->{"sn"}; + # Check if this user is an administrator + if (!is_admin $self->{"sn"}) { + actlog("Log in failed for user " . $form->param("id") + . " because user is not an administrator.") + if $self->{"login"}; + return {"msg"=>N_("You are not an administrator and cannot log into here.")}; + } + # OK + return; +} + +# _check_nonadmin: Check if the user is not an administrator +sub _check_nonadmin : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Skip checking for guests + return if is_guest $self->{"sn"}; + # Check if this user is an administrator + if (is_admin $self->{"sn"}) { + actlog("Log in failed for user " . $form->param("id") + . " because user is an administrator.") + if $self->{"login"}; + return {"msg"=>N_("You are an administrator and cannot log into here.")}; + } + # OK + return; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/MailTo.pm b/lib/perl5/Selima/Checker/MailTo.pm new file mode 100644 index 0000000..2990ebf --- /dev/null +++ b/lib/perl5/Selima/Checker/MailTo.pm @@ -0,0 +1,58 @@ +# Selima Website Content Management System +# MailTo.pm: The e-mail hyperlink redirection form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-25 + +package Selima::Checker::MailTo; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Email::Valid qw(); + +use Selima::ShortCut; + +# _check_email: Check the submitted e-mail +sub _check_email : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("email"); + return $error if defined $error; + # Regularize it + $self->_trim("email"); + # Check if it is filled + return {"msg"=>N_("Please fill in the e-mail.")} + if $form->param("email") eq ""; + # Un-mung e-mail to its original format + $_ = $form->param("email"); + s/ at /\@/; + $form->param("email", $_); + # Check the e-mail validity + return {"msg"=>N_("Please fill in a valid e-mail address.")} + if !Email::Valid->rfc822($form->param("email")); + return {"msg"=>N_("The domain of this e-mail does not exists. Check if there is any typo in it.")} + if !Email::Valid->mx($form->param("email")); + # OK + return; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/Page.pm b/lib/perl5/Selima/Checker/Page.pm new file mode 100644 index 0000000..7d9bb35 --- /dev/null +++ b/lib/perl5/Selima/Checker/Page.pm @@ -0,0 +1,52 @@ +# Selima Website Content Management System +# Page.pm: The base web page form checker. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-28 + +package Selima::Checker::Page; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "pages" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + return $self; +} + +# _check_path: Check the page path +# Use the default page path checker + +# _check_ord: Check the order +# Use the default order checker + +# _check_title: Check the title +# Use the default title checker + +# _check_body: Check the content +# Use the default content checker + +# _check_kw: Check the keywords list +# Use the default keywords list checker + +return 1; diff --git a/lib/perl5/Selima/Checker/Rebuild.pm b/lib/perl5/Selima/Checker/Rebuild.pm new file mode 100644 index 0000000..9794539 --- /dev/null +++ b/lib/perl5/Selima/Checker/Rebuild.pm @@ -0,0 +1,51 @@ +# Selima Website Content Management System +# Rebuild.pm: The web page rebuild form checker. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-04 + +package Selima::Checker::Rebuild; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::DataVars qw(:scptconf); +use Selima::ShortCut; + +# _check_type: Check the page type +sub _check_type : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("type"); + return $error if defined $error; + # Regularize it + $self->_trim("addr"); + # Check if it is filled + return {"msg"=>N_("Please select the type.")} + if $form->param("type") eq ""; + # Check if this link exists + return {"msg"=>N_("This type does not exist anymore. Please select another one.")} + unless defined $MAIN->can("rebuild_" . $form->param("type")); + # OK + return; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/ScptPriv.pm b/lib/perl5/Selima/Checker/ScptPriv.pm new file mode 100644 index 0000000..200faec --- /dev/null +++ b/lib/perl5/Selima/Checker/ScptPriv.pm @@ -0,0 +1,82 @@ +# Selima Website Content Management System +# ScptPriv.pm: The script privilege form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +package Selima::Checker::ScptPriv; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::DataVars qw($DBH); +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my $class; + ($class, @_) = @_; + $_[1] = "scptpriv" if scalar(@_) < 2 || !defined $_[1]; + return $class->SUPER::new(@_); +} + +# check: Run a list of checks +sub check : method { + local ($_, %_); + my ($self, $error, @cols); + ($self, @cols) = @_; + # Run the parent method first + $error = $self->SUPER::check(@cols); + return $error if defined $error; + # See if we need to check the duplicates. Check it in the end. + %_ = map { $_ => 1 } @cols; + if (exists $_{"grp"} && exists $_{"member"}) { + $error = $self->__check_dup(); + return $error if defined $error; + } + return; +} + +# _check_script: Check the script +# Use the default script checker + +# _check_grp: Check the group +# Use the default group checker + +# __check_dup: Check if this item is duplicated +sub __check_dup : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + @_ = qw(); + push @_, "script=" . $form->param("script"); + push @_, "grp=" . $form->param("grp"); + push @_, "sn!=" . $self->{"sn"} + if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This script privilege record already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + return; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/User.pm b/lib/perl5/Selima/Checker/User.pm new file mode 100644 index 0000000..d39ed2c --- /dev/null +++ b/lib/perl5/Selima/Checker/User.pm @@ -0,0 +1,296 @@ +# Selima Website Content Management System +# User.pm: The user account form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-26 + +package Selima::Checker::User; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Crypt::Cracklib qw(fascist_check); +use Email::Valid qw(); +$Crypt::Cracklib::DICT = "/usr/share/dict/pw_dict"; + +use Selima::Array; +use Selima::ChkPriv; +use Selima::DataVars qw($DBH :groups); +use Selima::LogIn; +use Selima::UserName; +use Selima::Passwd; +use Selima::ShortCut; + +use Selima::Checker::UserMem; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my ($class, $self); + ($class, @_) = @_; + $_[1] = "users" if scalar(@_) < 2 || !defined $_[1]; + $self = $class->SUPER::new(@_); + ${$self->{"maxlens"}}{"passwd"} = 16; + ${$self->{"minlens"}}{"passwd"} = 6; + ${$self->{"minlens"}}{"email"} = 5; + return $self; +} + +# check: Run a list of checks +sub check : method { + local ($_, %_); + my ($self, @cols, $error); + ($self, @cols) = @_; + # Check the guest flag first + $self->_is_guest; + # Run the parent method + return $self->SUPER::check(@cols); +} + +# _is_guest: If the user being edited is a guest +sub _is_guest : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Checked before + return $form->param("_is_guest") if !$self->_missing("_is_guest"); + %_ = map { $_ => 1 } $form->param; + for ($_ = 0; exists $_{"supgroup$_" . "sn"}; $_++) { + # Skip unselected groups + next if !exists $_{"supgroup$_"}; + # Check if this is the guest group + return $form->param("_is_guest", 1) + if groupid($form->param("supgroup$_" . "sn")) eq GUEST_GROUP; + } + # No guest group was found + return $form->param("_is_guest", 0); +} + +# _check_id: Check the user ID. +sub _check_id : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + # Skip for a non-super-user editing a super-user + return if $self->{"iscur"} && !is_su && is_su $self->{"sn"}; + # Check if it exists + $error = $self->_missing("id"); + return $error if defined $error; + # Regularize it + $self->_trim("id"); + # Check if it is filled + return {"msg"=>N_("Please fill in the user ID.")} + if $form->param("id") eq ""; + # Check the length + return {"msg"=>N_("This user ID. is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"id"}]} + if length $form->param("id") > ${$self->{"maxlens"}}{"id"}; + return {"msg"=>N_("This user ID. is too short. (Min. length [#,_1])"), + "margs"=>[${$self->{"minlens"}}{"id"}]} + if length $form->param("id") < ${$self->{"minlens"}}{"id"}; + # Check if the characters used are valid + return {"msg"=>N_("Only English letters, numbers, at-signs, dots, dashes and underscores are allowed for the user ID.")} + unless $form->param("id") =~ /^[a-z][a-z0-9@\.\-_]*$/; + # Check if this item is duplicated + @_ = qw(); + push @_, "id=" . $DBH->quote($form->param("id")); + push @_, "sn!=" . $self->{"sn"} if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This user already has an account. You cannot create a duplicated one.")} + if $sth->rows > 0; + # OK + return; +} + +# _check_passwd: Check the user password +sub _check_passwd : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Skip for a non-super-user editing a super-user + return if $self->{"iscur"} && !is_su && is_su $self->{"sn"}; + # Set the passwords with the password registry + sync_saved_passwd($form, "*" x ${$self->{"maxlens"}}{"passwd"}); + # Skip password checking for guests + return if $self->_is_guest; + # Check if it exists + $error = $self->_missing("passwd", "passwd2"); + return $error if defined $error; + # Regularize it + $self->_trim("passwd", "passwd2"); + # Check if it is filled + return {"msg"=>N_("Please fill in the password.")} + if !$self->{"iscur"} && $form->param("passwd") eq ""; + return {"msg"=>N_("Please confirm the password.")} + if $form->param("passwd") ne "" && $form->param("passwd2") eq ""; + # Check the length + return {"msg"=>N_("This password is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"passwd"}]} + if length $form->param("passwd") > ${$self->{"maxlens"}}{"passwd"}; + return {"msg"=>N_("This password is too short. (Min. length [#,_1])"), + "margs"=>[${$self->{"minlens"}}{"passwd"}]} + if $form->param("passwd") ne "" + && length $form->param("passwd") < ${$self->{"minlens"}}{"passwd"}; + # Check if two passwords are consistent + return {"msg"=>N_("The 2 passwords are different. Please fill in the password again.")} + if $form->param("passwd") ne $form->param("passwd2"); + if ($form->param("passwd") ne "") { + # Check the password strength with cracklib + if (($_ = fascist_check($form->param("passwd"))) ne "ok") { + # See the message from cracklib/fscist.c + # FascistGecos() + #return {"msg"=>N_("You are not registered.")} + # if $_ eq "you are not registered in the password file"; + return {"msg"=>N_("This password is based on the user ID.")} + if $_ eq "it is based on your username"; + #return {"msg"=>N_("This password is based upon the personal information.")} + # if $_ eq "it is based upon your password entry"; + #return {"msg"=>N_("This password is derived from the personal information.")} + # if $_ eq "it is derived from your password entry" + # || $_ eq "it's derived from your password entry"; + #return {"msg"=>N_("This password is derivable from the personal information.")} + # if $_ eq "it is derivable from your password entry" + # || $_ eq "it's derivable from your password entry"; + # FascistLook() + #return {"msg"=>N_("This password is too short. (Min. length [#,_1])"), + # "margs"=>[${$self->{"minlens"}}{"passwd"}]} + # if $_ eq "it's WAY too short" + # || $_ eq "it is too short"; + return {"msg"=>N_("This password does not contain enough different characters.")} + if $_ eq "it does not contain enough DIFFERENT characters"; + #return {"msg"=>N_("This password is all whitespace.")} + # if $_ eq "it is all whitespace"; + return {"msg"=>N_("This password is too simplistic/systematic.")} + if $_ eq "it is too simplistic/systematic"; + #return {"msg"=>N_("This password looks like a National Insurance number.")} + # if $_ eq "it looks like a National Insurance number"; + return {"msg"=>N_("This password is based on a dictionary word.")} + if $_ eq "it is based on a dictionary word"; + return {"msg"=>N_("This password is based on a (reversed) dictionary word.")} + if $_ eq "it is based on a (reversed) dictionary word"; + return {"msg"=>N_("This password is too simple.")}; + } + return {"msg"=>$_} + if ($_ = fascist_check($form->param("passwd"))) ne "ok"; + # Check if the group and the member are different + return {"msg"=>N_("You cannot use a password that is based on your user ID.")} + if defined($_ = $form->param("id")) + && $form->param("passwd") =~ /$_/i; + } + # OK + return; +} + +# _check_name: Check the user name +sub _check_name : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("name"); + return $error if defined $error; + # Regularize it + $self->_trim("name"); + # Check if it is filled + return {"msg"=>N_("Please fill in the name.")} + if $form->param("name") eq ""; + # Check the length + return {"msg"=>N_("This name is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"name"}]} + if length $form->param("name") > ${$self->{"maxlens"}}{"name"}; + # OK + return; +} + +# _check_email: Check the user e-mail +sub _check_email : method { + local ($_, %_); + my ($self, $form, $error, $col); + ($self, $col) = @_; + $form = $self->{"form"}; + $col = "email" if !defined $col; + # Check if it exists + $error = $self->_missing($col); + return $error if defined $error; + # Regularize it + $self->_trim($col); + # Check if it is filled + return {"msg"=>N_("Please fill in the e-mail.")} + if $form->param($col) eq ""; + # Check the length + return {"msg"=>N_("This e-mail is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{$col}]} + if length $form->param($col) > ${$self->{"maxlens"}}{$col}; + return {"msg"=>N_("This e-mail is too short. (Min. length [#,_1])"), + "margs"=>[${$self->{"minlens"}}{$col}]} + if length $form->param($col) < ${$self->{"minlens"}}{$col}; + # Check the e-mail validity + return {"msg"=>N_("Please fill in a valid e-mail address.")} + if !Email::Valid->rfc822($form->param($col)); + return {"msg"=>N_("The domain of this e-mail does not exists. Check if there is any typo in it.")} + if !Email::Valid->mx($form->param($col)); + # OK + return; +} + +# _check_supgroup: Check the belonging groups +sub _check_supgroup : method { + local ($_, %_); + my ($self, $form, $error, %items); + $self = $_[0]; + $form = $self->{"form"}; + # Skip for a non-super-user editing herself + return if $self->{"iscur"} && !is_su && $self->{"sn"} == get_login_sn; + for (my $i = 0, %items = qw(); !$self->_missing("supgroup$i" . "sn"); $i++) { + my ($subform, $checker); + # Skip unselected ones + next if $self->_missing("supgroup$i"); + # Regularize it + $self->_trim("supgroup$i" . "sn"); + # Check if this selection is duplicated + return {"msg"=>N_("This belonging group is duplicated. You cannot set duplicated ones.")} + if exists $items{$form->param("supgroup$i" . "sn")}; + $items{$form->param("supgroup$i" . "sn")} = 1; + # Check with the subform checker + $subform = new CGI(""); + $subform->param("grp", $form->param("supgroup$i" . "sn")); + $subform->param("member", $self->{"sn"}) if $self->{"iscur"}; + $checker = new Selima::Checker::UserMem($subform); + $error = $checker->check("grp"); + return $error if defined $error; + # Check if a special group is submitted + $_ = groupid($form->param("supgroup$i" . "sn")); + return {"msg"=>N_("You cannot submit the super-user group along with other groups.")} + if $_ eq SU_GROUP; + return {"msg"=>N_("You cannot set the administrators group.")} + if $_ eq ADMIN_GROUP; + return {"msg"=>N_("You cannot set the all-users group.")} + if $_ eq ALLUSERS_GROUP; + } + # OK + return; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/UserMem.pm b/lib/perl5/Selima/Checker/UserMem.pm new file mode 100644 index 0000000..528f0f7 --- /dev/null +++ b/lib/perl5/Selima/Checker/UserMem.pm @@ -0,0 +1,123 @@ +# Selima Website Content Management System +# UserMem.pm: The user-to-group membership form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-10 + +package Selima::Checker::UserMem; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::ChkFunc; +use Selima::CallForm; +use Selima::DataVars qw($DBH :forms); +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my $class; + ($class, @_) = @_; + $_[1] = "usermem" if scalar(@_) < 2 || !defined $_[1]; + return $class->SUPER::new(@_); +} + +# check: Run a list of checks +sub check : method { + local ($_, %_); + my ($self, $error, @cols); + ($self, @cols) = @_; + # Run the parent method first + $error = $self->SUPER::check(@cols); + return $error if defined $error; + # See if we need to check the duplicates. Check it in the end. + %_ = map { $_ => 1 } @cols; + if (exists $_{"grp"} && exists $_{"member"}) { + $error = $self->__check_dup(); + return $error if defined $error; + } + return; +} + +# _check_grp: Check the group +# Use the default group checker + +# _check_member: Check the member +sub _check_member : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("member"); + return $error if defined $error; + # Regularize it + $self->_trim("member"); + # Check if it is filled + return {"msg"=>N_("Please select a member.")} + if $form->param("member") eq ""; + # Check if this user exists + return {"msg"=>N_("This member does not exist anymore. Please select another one.")} + if !check_sn_in ${$form->param_fetch("member")}[0], "users AS usrmembers"; + # OK + return; +} + +# __check_dup: Check if this item is duplicated +sub __check_dup : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + @_ = qw(); + push @_, "grp=" . $form->param("grp"); + push @_, "member=" . $form->param("member"); + push @_, "sn!=" . $self->{"sn"} + if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This membership record already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + return; +} + +# _redir_selmember: Suspend and move to the member selection form +sub _redir_selmember : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selmember"); + call_form FORM_USERS, undef, "import_selmember"; +} + +# _redir_delmember: Remove the member +sub _redir_delmember : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("delmember"); + $self->{"form"}->delete("member"); + success_redirect undef; +} + +return 1; diff --git a/lib/perl5/Selima/Checker/UserPref.pm b/lib/perl5/Selima/Checker/UserPref.pm new file mode 100644 index 0000000..e88eabd --- /dev/null +++ b/lib/perl5/Selima/Checker/UserPref.pm @@ -0,0 +1,207 @@ +# Selima Website Content Management System +# UserPref.pm: The user preference form checker. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +package Selima::Checker::UserPref; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Checker); + +use Selima::CallForm; +use Selima::DataVars qw($DBH :forms); +use Selima::ShortCut; + +# new: Initialize the checker +sub new : method { + local ($_, %_); + my $class; + ($class, @_) = @_; + $_[1] = "userpref" if scalar(@_) < 2 || !defined $_[1]; + return $class->SUPER::new(@_); +} + +# check: Run a list of checks +sub check : method { + local ($_, %_); + my ($self, $error, @cols); + ($self, @cols) = @_; + # Run the parent method first + $error = $self->SUPER::check(@cols); + return $error if defined $error; + # See if we need to check the duplicates. Check it in the end. + %_ = map { $_ => 1 } @cols; + if (exists $_{"usr"} && exists $_{"domain"} && exists $_{"name"}) { + $error = $self->__check_dup(); + return $error if defined $error; + } + return; +} + +# _check_usr: Check the user +sub _check_usr : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # "everyone not set" has a different form context + return {"msg"=>N_("Please select the user.")} + if $self->_missing("everyone"); + # Regularize it + $self->_trim("everyone"); + # Check the option value + return {"msg"=>N_("This option is invalid. Please select a proper user.")} + unless $form->param("everyone") =~ /^(?:true|false)$/; + # Check the user if not everyone + if ($form->param("everyone") eq "false") { + $error = $self->SUPER::_check_usr; + return $error if defined $error; + } + # OK + return; +} + +# _check_domain: Check the domain +sub _check_domain : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # "everywhere not set" has a different form context + return {"msg"=>N_("Please set the preference domain.")} + if $self->_missing("everywhere"); + # Regularize it + $self->_trim("everywhere"); + # Check the option value + return {"msg"=>N_("This option is invalid. Please set a proper preference domain.")} + unless $form->param("everywhere") =~ /^(?:true|false)$/; + # Check the domain if not everywhere + if ($form->param("everywhere") eq "false") { + # Check if it exists + $error = $self->_missing("domain"); + return $error if defined $error; + # Regularize it + $self->_trim("domain"); + # Check if it is filled + return {"msg"=>N_("Please fill in the preference domain.")} + if $form->param("domain") eq ""; + # Check the length + return {"msg"=>N_("This preference domain is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"domain"}]} + if length $form->param("domain") > ${$self->{"maxlens"}}{"domain"}; + } + # OK + return; +} + +# _check_name: Check the preference name +sub _check_name : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("name"); + return $error if defined $error; + # Regularize it + $self->_trim("name"); + # Check if it is filled + return {"msg"=>N_("Please fill in the preference name.")} + if $form->param("name") eq ""; + # Check the length + return {"msg"=>N_("This preference name is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"name"}]} + if length $form->param("name") > ${$self->{"maxlens"}}{"name"}; + # OK + return; +} + +# _check_value: Check the preference value +sub _check_value : method { + local ($_, %_); + my ($self, $form, $error); + $self = $_[0]; + $form = $self->{"form"}; + # Check if it exists + $error = $self->_missing("value"); + return $error if defined $error; + # Regularize it + $self->_trim("value"); + # Check if it is filled + return {"msg"=>N_("Please fill in the preference value.")} + if $form->param("value") eq ""; + # Check the length + return {"msg"=>N_("This preference value is too long. (Max. length [#,_1])"), + "margs"=>[${$self->{"maxlens"}}{"value"}]} + if length $form->param("value") > ${$self->{"maxlens"}}{"value"}; + # OK + return; +} + +# __check_dup: Check if this item is duplicated +sub __check_dup : method { + local ($_, %_); + my ($self, $form, $error, $sth, $sql); + $self = $_[0]; + $form = $self->{"form"}; + @_ = qw(); + if ($form->param("everyone") eq "true") { + push @_, "usr IS NULL"; + } else { + push @_, "usr=" . $form->param("usr"); + } + if ($form->param("everywhere") eq "true") { + push @_, "domain IS NULL"; + } else { + push @_, "domain=" . $DBH->quote($form->param("domain")); + } + push @_, "name=" . $DBH->quote($form->param("name")); + push @_, "sn!=" . $self->{"sn"} + if $self->{"iscur"}; + $sql = "SELECT * FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" AND ", @_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return {"msg"=>N_("This user preference already exists. You cannot create a duplicated one.")} + if $sth->rows > 0; + return; +} + +# _redir_selusr: Suspend and move to the user selection form +sub _redir_selusr : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("selusr"); + call_form FORM_USERS, undef, "import_selusr"; +} + +# _redir_delusr: Remove the user +sub _redir_delusr : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if not requested + return if $self->_missing("delusr"); + $self->{"form"}->delete("usr"); + success_redirect undef; +} + +return 1; diff --git a/lib/perl5/Selima/ChkFunc.pm b/lib/perl5/Selima/ChkFunc.pm new file mode 100644 index 0000000..e026f66 --- /dev/null +++ b/lib/perl5/Selima/ChkFunc.pm @@ -0,0 +1,141 @@ +# Selima Website Content Management System +# ChkFunc.pm: The data checkers. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-24 + +package Selima::ChkFunc; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(check_sn check_sn_in check_script check_date); +push @EXPORT, qw(is_url_wellformed is_url_reachable); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub check_sn(\$); +sub check_sn_in(\$$); +sub check_script($); +sub check_date($$$); +sub is_url_wellformed($); +sub is_url_reachable($); +} + +use LWP::UserAgent; +use Net::Telnet; +use Regexp::Common; +use Time::Local qw(timelocal); +use URI; + +use Selima::Cache qw(:chkfunc); +use Selima::DataVars qw($DBH :input :requri); +use Selima::ShortCut; + +use vars qw($URIRE); +$URIRE = "(?:" . $RE{"URI"} . "|" . $RE{"URI"}{"HTTP"}{-scheme=>"https"} . ")"; + +# check_sn: Check if a serial number is valid +# Rule for a serial number: +# An integer of 9 digits within 100000000 - 999999999 +sub check_sn(\$) { + local ($_, %_); + $_ = $_[0]; + return 0 unless defined $$_ && $$_ =~ /^[1-9][0-9]{8}$/; + $$_ += 0; + return 1; +} + +# check_sn_in: Check if a serial number exists in a table +sub check_sn_in(\$$) { + local ($_, %_); + my ($sn, $table, $sql, $sth); + ($sn, $table) = @_; + # Check the validity of the serial number first + return 0 if !check_sn $$sn; + if ($table =~ /^(.+) AS (.+)$/) { + $table = $DBH->quote_identifier($1) + . " AS " . $DBH->quote_identifier($2); + } else { + $table = $DBH->quote_identifier($table); + } + $sql = "SELECT * FROM $table WHERE sn=$$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return ($sth->rows == 1); +} + +# check_script: Check if a script exists +sub check_script($) { + local ($_, %_); + $_ = $_[0]; + # Return the cache + return $ChkFunc_check_script{$_} + if exists $ChkFunc_check_script{$_}; + # Not a CGI script + return ($ChkFunc_check_script{$_} = 0) + unless /\.(cgi|pl|plx)$/; + # Not exists + return ($ChkFunc_check_script{$_} = 0) + unless -x $DOC_ROOT . $_; + # OK + return ($ChkFunc_check_script{$_} = 1); +} + +# check_date: Check if a date is valid +sub check_date($$$) { + local ($_, %_); + my ($year, $month, $day); + ($year, $month, $day) = @_; + eval { $_ = timelocal(0, 0, 0, $day, $month-1, $year-1900); }; + return undef if $@ ne ""; + return $_; +} + +# is_url_wellformed: Check if an URL is well-formed +sub is_url_wellformed($) { $_[0] =~ /^$URIRE$/; } + +# is_url_reachable: Check if the target of an URL is reachable +sub is_url_reachable($) { + local ($_, %_); + my ($uri, $UA, $r); + $_ = $_[0]; + # Return the cache + return $ChkFunc_is_url_reachable{$_} + if exists $ChkFunc_is_url_reachable{$_}; + # Check if it is available + # LWP::UserAgent cannot handle telnet. We check it with Net::Telnet. + if (/^telnet:\/\//) { + $uri = new URI($_); + %_ = ( + Host => $uri->host, + Port => $uri->port, + ); + eval { new Net::Telnet(%_) }; + return ($ChkFunc_is_url_reachable{$_} = ($@ eq "")); + + # Use LWP::UserAgent + } else { + $UA = new LWP::UserAgent; + $r = $UA->get($_); + return ($ChkFunc_is_url_reachable{$_} = !$r->is_error); + } +} + +return 1; diff --git a/lib/perl5/Selima/ChkPriv.pm b/lib/perl5/Selima/ChkPriv.pm new file mode 100644 index 0000000..7043fe2 --- /dev/null +++ b/lib/perl5/Selima/ChkPriv.pm @@ -0,0 +1,133 @@ +# Selima Website Content Management System +# ChkPriv.pm: The privilege checkers. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-26 + +package Selima::ChkPriv; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(is_admin is_su user_parent_groups); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub is_admin(;$); +sub is_su(;$); +sub user_parent_groups($); +} + +use Selima::Array; +use Selima::Cache qw(:chkpriv); +use Selima::ChkFunc; +use Selima::DataVars qw($DBH :groups); +use Selima::LogIn; +use Selima::UserName; + +# is_admin: If the user is an administrator (by user sn) +sub is_admin(;$) { + local ($_, %_); + $_ = $_[0]; + # Default to the current logged-in user + return is_su || in_array(ADMIN_GROUP, get_login_groups) + if !defined $_ || (defined get_login_sn && $_ == get_login_sn); + # Return the cache + return $ChkPriv_is_admin{$_} if exists $ChkPriv_is_admin{$_}; + # Super user is always an administrator + return ($ChkPriv_is_admin{$_} = 1) if is_su($_); + # Check the groups + return ($ChkPriv_is_admin{$_} = + in_array(ADMIN_GROUP, user_parent_groups($_))); +} + +# is_su: If the user is a super user +sub is_su(;$) { + local ($_, %_); + $_ = $_[0]; + # Default to the current logged-in user + return in_array(SU_GROUP, get_login_groups) + if !defined $_ || (defined get_login_sn && $_ == get_login_sn); + # Return the cache + return $ChkPriv_is_su{$_} if exists $ChkPriv_is_su{$_}; + # Check the groups + return ($ChkPriv_is_admin{$_} = + in_array(SU_GROUP, user_parent_groups($_))); +} + +# user_parent_groups: Return the full list of groups a user belongs to +sub user_parent_groups($) { + local ($_, %_); + my ($sn, $sth, $sql, $count, %current, $group); + $sn = $_[0]; + # Bounce for null + return if !defined $sn; + # Return the cache + return @{$ChkPriv_user_parent_groups{$sn}} + if exists $ChkPriv_user_parent_groups{$sn}; + # Check the validity of the user first + if (defined get_login_sn && $sn != get_login_sn) { + if (!check_sn_in $sn, "users") { + $ChkPriv_user_parent_groups{$sn} = []; + return; + } + } + # Find the direct parent groups + $sql = "SELECT grp FROM usermem" + . " WHERE member=$sn" + . " ORDER BY grp;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + # Obtain the direct parent groups + for ($_ = 0, %current = qw(); $_ < $count; $_++) { + $current{${$sth->fetch}[0]} = 1; + } + # ALLUSERS_GROUP is automatically added to all the valid users + $current{groupsn(ALLUSERS_GROUP)} = 1; + # Trace all their ancester groups + while (1) { + $sql = "SELECT grp FROM groupmem" + . " WHERE " . join(" OR ", map "member=$_", keys %current) + . " GROUP BY grp ORDER BY grp;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @_ = qw(); $_ < $count; $_++) { + push @_, ${$sth->fetch}[0]; + } + @_ = grep !exists $current{$_}, @_; + last if scalar(@_) == 0; + $current{$_} = 1 foreach @_; + } + # Find their ID + $sql = "SELECT id FROM groups" + . " WHERE " . join(" OR ", map "sn=$_", keys %current) + . " ORDER BY id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @_ = qw(); $_ < $count; $_++) { + push @_, ${$sth->fetch}[0]; + } + # Cache it + $ChkPriv_user_parent_groups{$sn} = [@_]; + return @_; +} + +return 1; diff --git a/lib/perl5/Selima/ChkWrite.pm b/lib/perl5/Selima/ChkWrite.pm new file mode 100644 index 0000000..f23c5d6 --- /dev/null +++ b/lib/perl5/Selima/ChkWrite.pm @@ -0,0 +1,80 @@ +# Selima Website Content Management System +# ChkWrite.pm: The write-permission checker. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-28 + +package Selima::ChkWrite; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(check_writable); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub check_writable($); +} + +use File::Basename qw(dirname); + +use Selima::ShortCut; + +# check_writable: Check the permission to write to a file. +# Input: File full pathname $file. +# Output: true if success, false if failed. +sub check_writable($) { + local ($_, %_); + my ($file, $parent); + $file = $_[0]; + # Standardize it + # File exists. + if (-e $file) { + # If it is a file + return {"msg"=>N_("[_1]: It is not a file."), + "margs"=>[$file]} + if !-f $file; + # If it is writable + return {"msg"=>N_("[_1]: You have no permission to overwrite this file."), + "margs"=>[$file]} + if !-w $file; + + # Not an existing file. See if we can create it. + } else { + $parent = $file; + # Find the nearest existing parent + $parent = dirname($parent) + while $parent ne "" && !-e $parent; + # Creat files from root --- You are insane + return {"msg"=>N_("[_1]: You cannot create anything under the root directory."), + "margs"=>[$file]} + if $parent eq ""; + # This parent is not a directory + return {"msg"=>N_("[_1]: One of the parents of this file ([_2]) is not a directory. You cannot create any new file inside."), + "margs"=>[$file, $parent]} + if !-d $parent; + # If it is possible to create entries in this directory + return {"msg"=>N_("[_1]: You have no permission to create any file under [_2]."), + "margs"=>[$file, $parent]} + if !-w $parent; + } + # OK + return; +} + +return 1; diff --git a/lib/perl5/Selima/CommText.pm b/lib/perl5/Selima/CommText.pm new file mode 100644 index 0000000..4447cbb --- /dev/null +++ b/lib/perl5/Selima/CommText.pm @@ -0,0 +1,42 @@ +# Selima Website Content Management System +# CommText.pm: The core common text messages. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-03 + +package Selima::CommText; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(t_notset t_none t_na); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub t_notset(); +sub t_none(); +sub t_na(); +} + +use Selima::ShortCut; + +sub t_notset() { C_("(not set)"); } +sub t_none() { C_("(none)"); } +sub t_na() { C_("(N/A)"); } + +return 1; diff --git a/lib/perl5/Selima/CopyYear.pm b/lib/perl5/Selima/CopyYear.pm new file mode 100644 index 0000000..a251e68 --- /dev/null +++ b/lib/perl5/Selima/CopyYear.pm @@ -0,0 +1,51 @@ +# Selima Website Content Management System +# CopyYear.pm: The copyright year text generator. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-17 + +package Selima::CopyYear; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(copyyear); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub copyyear($); +} + +use Selima::Cache qw(:copyyear); +use Selima::DataVars qw(:proctime); + +# copyyear: Return the copyright year +sub copyyear($) { + local ($_, %_); + my ($startyear, $thisyear); + $startyear = $_[0]; + # Return the cache + return $CopyYear_copyyear if defined $CopyYear_copyyear; + $thisyear = (localtime $T_START)[5] + 1900; + $CopyYear_copyyear = $startyear; + $CopyYear_copyyear .= "-" . $thisyear + if $thisyear != $startyear; + return $CopyYear_copyyear; +} + +return 1; diff --git a/lib/perl5/Selima/Country.pm b/lib/perl5/Selima/Country.pm new file mode 100644 index 0000000..20d4205 --- /dev/null +++ b/lib/perl5/Selima/Country.pm @@ -0,0 +1,101 @@ +# Selima Website Content Management System +# Country.pm: The subroutines to query the country name from the database. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-17 + +package Selima::Country; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(ctname ctname_zhtw); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub ctname($); +sub ctname_zhtw($); +} + +use Selima::Cache qw(:country); +use Selima::CommText; +use Selima::DataVars qw($DBH :lninfo); +use Selima::GetLang; +use Selima::LnInfo; + +# The default language here is always English +use constant DEFAULT_LANG => "en"; +use constant TRAD_CHINESE => "zh-tw"; + +# ctname: Obtain a country name +sub ctname($) { + local ($_, %_); + my ($id, $name, $col, $defcol, $sql, $sth); + $id = $_[0]; + # Bounce if there is any problem with $id + return t_notset unless defined $id; + # Return the cache + return $Country_ctname{$id} if exists $Country_ctname{$id}; + + # Default language + if (getlang eq DEFAULT_LANG) { + $name = "name_" . getlang(LN_DATABASE) . " AS name"; + # Fall back to the default language + } else { + $col = "name_" . getlang LN_DATABASE; + $defcol = "name_" . ln DEFAULT_LANG, LN_DATABASE; + $name= "COALESCE($col, $defcol) AS name"; + } + # Query + $sql = "SELECT $name FROM country" + . " WHERE id=" . $DBH->quote($id) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Found + return ($Country_ctname{$id} = ${$sth->fetch}[0]) + if $sth->rows == 1; + # Not found + return ($Country_ctname{$id} = t_na); +} + +# ctname_zhtw: Obtain a country name in Traditional Chinese +sub ctname_zhtw($) { + local ($_, %_); + my ($id, $name, $col, $defcol, $sql, $sth); + $id = $_[0]; + # Bounce if there is any problem with $id + return t_notset unless defined $id; + + # Fall back to the default language + $col = "name_" . ln TRAD_CHINESE, LN_DATABASE; + $defcol = "name_" . ln DEFAULT_LANG, LN_DATABASE; + $name= "COALESCE($col, $defcol) AS name"; + # Query + $sql = "SELECT $name FROM country" + . " WHERE id=" . $DBH->quote($id) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Found + return ${$sth->fetch}[0] if $sth->rows == 1; + # Not found + return t_na; +} + +return 1; diff --git a/lib/perl5/Selima/DBD/Pg.pm b/lib/perl5/Selima/DBD/Pg.pm new file mode 100644 index 0000000..1a42740 --- /dev/null +++ b/lib/perl5/Selima/DBD/Pg.pm @@ -0,0 +1,454 @@ +# Selima Website Content Management System +# Pg.pm: The extended PostgreSQL database driver. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-08 + +package Selima::DBD::Pg; +use 5.008; +use strict; +use warnings; + +use MIME::Base64 qw(decode_base64); +use Term::ReadKey qw(ReadMode); + +use Selima::DataVars qw(:db :env :siteconf :scptconf); +use Selima::DBILogin; +use Selima::HTTP; + +#use vars qw($DBHC $PGDATABASE $PGHOST $PGPORT $PGUSER $PGPASSWORD); +use vars qw($DBHC); + +# new: Connect and establish a new PostgreSQL database source +sub new : method { + local ($_, %_); + my ($class, $dbiclass, $dbh); + $class = ref($_[0]) || $_[0]; + $dbiclass = (caller)[0]; + + # Login with from SQLLOGIN environment variable as a web application + if ($IS_CGI) { + my ($dsn, %r); + # Prepare the connection information + %r = get_dbi_login_info DBI_POSTGRESQL; + + # Return the available cached handle and clear the cache + if (defined $DBHC && $DBHC->{"Name"} eq $r{"PGDATABASE"} && $DBHC->ping) { + $dbh = $DBHC; + # Clear the cache to remove static reference to the database handle, + # to avoid leaving dead handles that owns table locks + undef $DBHC; + return $dbh; + } + # Clear the cache + undef $DBHC if defined $DBHC; + + # Compose the DSN + @_ = qw(); + push @_, "host=" . $r{"PGHOST"} . ";" if defined $r{"PGHOST"}; + push @_, "dbname=" . $r{"PGDATABASE"} . ";" if defined $r{"PGDATABASE"}; + $dsn = "dbi:Pg:" . join "", @_; + + # Try to log in, handling the failure later + %_ = ( "PrintError" => 0 ); + $dbh = $dbiclass->connect($dsn, $r{"PGUSER"}, $r{"PGPASSWORD"}, {%_}); + + # Login failed + http_500 $dbiclass->errstr if !defined $dbh; + + # Ask the password from the console + } else { + my ($dsn, $subseq, $user, $passwd); + $dsn = "dbi:Pg:dbname=$PACKAGE;"; + $subseq = 0; + # Try to log in + while (!defined($dbh = $dbiclass->connect($dsn, $user, $passwd, { PrintError => 0 }))) { + $_ = DBI->errstr; + if ($subseq) { + print STDERR $_; + sleep 5; + } + $subseq = 1; + # Obtain the current login user + $user = $1 if !defined $user && / failed for user "(.+?)"/; + # Disable console echo + ReadMode 2; + print STDERR defined $user? "PostgreSQL password for $user: ": + "PostgreSQL password: "; + $passwd = ; + print STDERR "\n"; + die "$THIS_FILE: Failed connecting to the PostgreSQL server\n" + if !defined $passwd; + chomp $passwd; + # Restore console echo status + ReadMode 0; + } + } + + # Bless the object, name it as the current class + $dbh = bless $dbh, $dbiclass . "::db"; + + # Set the client encoding to UTF-8 + $_ = "SET NAMES 'utf8';\n"; + $dbh->do($_); + + return $dbh; +} + +# park_handle: Suspend the database handle for further use (mod_perl) +sub park_handle : method { $DBHC = $_[1]; } + + +# Selima::DBD::Pg::db: The database-handler driver class +package Selima::DBD::Pg::db; + +use 5.008; +use strict; +use warnings; + +use Fcntl qw(:flock); + +use Selima::GetLang; +use Selima::HTTP; +use Selima::DataVars qw(:db :lninfo); + +# support: Return if a DBI feature is supported +sub support : method { + local ($_, %_); + my ($self, $feature); + ($self, $feature) = @_; + + # PostgreSQL has VIEWs. + return 1 if $feature eq DBI_FEATHER_VIEW; + + # Default to yes. We assume everyone is a good guy. + return 1; +} + +# lock: PostgreSQL table-locking handler +# PostgreSQL has no unlock +# Input: +# %locks: A hash table, where its keys are the tables to lock, +# and its values can be one of the following: +# LOCK_SH: Request a read lock +# LOCK_EX: Request a write lock +# LOCK_UN: No effect +# Return: None. Errors are directed to error handlers +sub lock : method { + local ($_, %_); + my ($self, %locks, @reads, @writes, $sth); + ($self, %locks) = @_; + + # Bounce for nothing + return if scalar(keys %locks) == 0; + + # Remove the table aliases -- compatibility with stupid MySQL + %_ = qw(); + foreach my $table (keys %locks) { + # Remove the table aliases + $_ = $table; + s/\s+AS\s+.+?$//i; + # No override previous write lock + next if exists $_{$_} && $_{$_} == LOCK_EX; + # Set the lock + $_{$_} = $locks{$table}; + } + %locks = %_; + + # Split into different lock modes + @reads = qw(); + @writes = qw(); + foreach (keys %locks) { + if ($locks{$_} == LOCK_SH) { + push @reads, $_; + } elsif ($locks{$_} == LOCK_EX) { + push @writes, $_; + } else { + http_500 "Bad SQL lock request: \"" . $locks{$_} . "\"" + . " on table \"$_\"."; + } + } + + # Start the transaction + $self->begin_work if $self->{"AutoCommit"}; + + # Request the locks + if (@reads > 0) { + $_ = "LOCK TABLE " . join(", ", @reads) + . " IN SHARE MODE;\n"; + $self->do($_); + } + if (@writes > 0) { + $_ = "LOCK TABLE " . join(", ", @writes) + . " IN ACCESS EXCLUSIVE MODE;\n"; + $self->do($_); + } + + return; +} + +# tables: Return the tables and views +sub tables : method { + local ($_, %_); + my ($self, $schema, $cache, $sth, @tables); + ($self, $schema) = @_; + + # Default schema + $schema = $self->current_schema if !defined $schema; + + # Initialize the cache + ${$self->{"private_selima"}}{"tables"} = {} + if !exists ${$self->{"private_selima"}}{"tables"}; + $cache = ${$self->{"private_selima"}}{"tables"}; + # Return the cache + return @{${$cache}{$schema}} if exists ${$cache}{$schema}; + + # Get the tables list + $sth = $self->table_info(undef, $schema, "%", "%") + or http_500 $self->errstr; + @tables = qw(); + push @tables, ${$_}{"TABLE_NAME"} + while defined($_ = $sth->fetchrow_hashref); + + # Cache it + ${$cache}{$schema} = [@tables]; + + return @tables; +} + +# cols: Return the columns of a table (or view) +sub cols : method { + local ($_, %_); + my ($self, $table, $schema, $cache, $sth, @cols); + ($self, $table, $schema) = @_; + + # Default schema + $schema = $self->current_schema if !defined $schema; + + # Initialize the cache + ${$self->{"private_selima"}}{"cols"} = {} + if !exists ${$self->{"private_selima"}}{"cols"}; + ${${$self->{"private_selima"}}{"cols"}}{$schema} = {} + if !exists ${${$self->{"private_selima"}}{"cols"}}{$schema}; + $cache = ${${$self->{"private_selima"}}{"cols"}}{$schema}; + # Return the cache + return @{${$cache}{$table}} if exists ${$cache}{$table}; + + # Get the columns list + $sth = $self->column_info(undef, $schema, $table, "%") + or http_500 $self->errstr; + @cols = qw(); + push @cols, ${$_}{"COLUMN_NAME"} + while defined($_ = $sth->fetchrow_hashref); + s/^"(.+)"/$1/ foreach @cols; + + # Cache it + ${$cache}{$table} = [@cols]; + + return @cols; +} + +# col_lens: Obtain the column lengths of a table +sub col_lens : method { + local ($_, %_); + my ($self, $table, $schema, $cache, $sth, $sql, $count, %lens, $lndb); + ($self, $table, $schema) = @_; + + # Default schema + $schema = $self->current_schema if !defined $schema; + + # Initialize the cache + ${$self->{"private_selima"}}{"col_lens"} = {} + if !exists ${$self->{"private_selima"}}{"col_lens"}; + ${${$self->{"private_selima"}}{"col_lens"}}{$schema} = {} + if !exists ${${$self->{"private_selima"}}{"col_lens"}}{$schema}; + $cache = ${${$self->{"private_selima"}}{"col_lens"}}{$schema}; + # Return the cache + return %{${$cache}{$table}} if exists ${$cache}{$table}; + + # Query + $sql = "SELECT pg_attribute.attname AS col," + . " pg_type.typname AS type," + . " pg_attribute.attlen AS len," + . " pg_attribute.atttypmod AS typmod" + . " FROM pg_attribute" + . " INNER JOIN pg_class ON pg_attribute.attrelid=pg_class.oid" + . " INNER JOIN pg_type ON pg_attribute.atttypid=pg_type.oid" + . " INNER JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid" + . " WHERE pg_namespace.nspname=" . $self->quote($schema) + . " AND pg_class.relname=" . $self->quote($table) + . " AND pg_class.relkind='r'" + . " AND pg_attribute.attnum>0" + . " ORDER BY pg_attribute.attnum;\n"; + $sth = $self->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, %lens = qw(); $i < $count; $i++) { + %_ = %{$sth->fetchrow_hashref}; + # Integer -- Digits of the largest number - 1 + if ($_{"type"} =~ /^int[248]$/) { + $lens{$_{"col"}} = int(log(256**$_{"len"})/log 10); + # Refer to typmod for char and varchar + } elsif ($_{"type"} =~ /^(?:var|bp)char$/) { + $lens{$_{"col"}} = $_{"typmod"} - 4; + # Set text and bytea to 4294967296 (2^32) (infinite actually) + } elsif ($_{"type"} =~ /^(?:text|bytea)$/) { + $lens{$_{"col"}} = 4294967296; + # Set timestamp to 19 + } elsif ($_{"type"} eq "timestamp" || $_{"type"} eq "timestamptz") { + $lens{$_{"col"}} = 19; + # Set date to 10 + } elsif ($_{"type"} eq "date") { + $lens{$_{"col"}} = 10; + # Set time to 8 + } elsif ($_{"type"} eq "time") { + $lens{$_{"col"}} = 8; + # Set numeric to precision + 1 decimal point + # Refer to http://archives.postgresql.org/pgsql-hackers/1999-01/msg00127.php + } elsif ($_{"type"} eq "numeric") { + my ($typmod, $scale, $precision); + $typmod = $_{"typmod"} - 4; + $scale = $typmod & 0xFFFF; + $precision = $typmod >> 16; + $lens{$_{"col"}} = $precision + 1; + # Set boolean to 1 + } elsif ($_{"type"} eq "bool") { + $lens{$_{"col"}} = 1; + # Set inet to 18 (nnn.nnn.nnn.nnn/nn) + } elsif ($_{"type"} eq "inet") { + $lens{$_{"col"}} = 18; + # Bounce for unknown columns + } else { + http_500 "Unknown column type " . $_{"type"} + . " for table $table.\n"; + } + } + + # Hash the multi-lingual columns + $lndb = getlang(LN_DATABASE); + $lens{$_} = $lens{$_ . "_$lndb"} foreach $self->cols_ml($table); + + # Cache it + ${$cache}{$table} = {%lens}; + + return %lens; +} + +# quote_blob: Quote a piece of BLOB octet +sub quote_blob : method { + local ($_, %_); + my ($self, $octet, $sth, $sql); + ($self, $octet) = @_; + $sql = "SELECT ?;\n"; + $sth = $self->prepare($sql); + $sth->bind_param(1, $octet, { pg_type => DBD::Pg::PG_BYTEA() }) + or http_500 $sql . $sth->errstr; + $sth->execute; + return "'" . ${$sth->fetch}[0] . "'"; +} + +# strcat: Concatenate strings +sub strcat : method { + local ($_, %_); + my ($self, @strings); + ($self, @strings) = @_; + return join " || ", @strings; +} + +# lastupd: Obtain the last updated time of a list of tables +sub lastupd : method { + local ($_, %_); + my ($self, @tables, $sql, $sth); + ($self, @tables) = @_; + # Bounce if no tables supplied + return if scalar(@tables) == 0; + # Remove table aliases + s/^(\S+) AS \S+$/$1/ foreach @tables; + # Remove duplicates + %_ = map { $_ => 1 } @tables; + @tables = keys %_; + # Query + $sql = "SELECT mtime FROM mtime" + . " WHERE " . join(" OR ", map "tabname=" . $self->quote($_), @tables) + . " ORDER BY mtime DESC LIMIT 1;\n"; + $sth = $self->prepare($sql); + $sth->execute; + # Bounce if no data found + return if $sth->rows != 1; + # Return the result + return ${$sth->fetchrow_hashref}{"mtime"}; +} + +# current_schema: Obtain the current schema +sub current_schema : method { + local ($_, %_); + my ($self, $sth, $sql); + $self = $_[0]; + + # Return the cache + return ${$self->{"private_selima"}}{"current_schema"} + if exists ${$self->{"private_selima"}}{"current_schema"}; + + $sql = "SELECT current_schema();\n"; + $sth = $self->prepare($sql); + $sth->execute; + $_ = ${$sth->fetch}[0]; + + # Cache it + ${$self->{"private_selima"}}{"current_schema"} = $_; + + return $_; +} + + +# Selima::DBD::Pg::st: The statement-handler driver class +package Selima::DBD::Pg::st; + +use 5.008; +use strict; +use warnings; + +# typecols: Return the list of columns in specific types +sub typecols : method { + local ($_, %_); + my ($self, $types, %cols); + $self = $_[0]; + $types = $self->{"pg_type"}; + %cols = ( + "date" => [], + "num" => [], + "bigint" => [], + "numeric" => [], + "text" => [], + ); + for ($_ = 0; $_ < @$types; $_++) { + if ($$types[$_] =~ /^(?:date|timestamp)$/) { + push @{$cols{"date"}}, $_; + } elsif ($$types[$_] =~ /^(?:int2|int4|float4|float8)$/) { + push @{$cols{"num"}}, $_; + } elsif ($$types[$_] eq "int8") { + push @{$cols{"bigint"}}, $_; + } elsif ($$types[$_] eq "numeric") { + push @{$cols{"numeric"}}, $_; + } elsif ($$types[$_] =~ /^(?:varchar|text)$/) { + push @{$cols{"text"}}, $_; + } + } + return \%cols; +} + +return 1; diff --git a/lib/perl5/Selima/DBD/mysql.pm b/lib/perl5/Selima/DBD/mysql.pm new file mode 100644 index 0000000..0de7e66 --- /dev/null +++ b/lib/perl5/Selima/DBD/mysql.pm @@ -0,0 +1,301 @@ +# Selima Website Content Management System +# mysql.pm: The extended MySQL database driver. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-23 + +package Selima::DBD::mysql; +use 5.008; +use strict; +use warnings; + +use MIME::Base64 qw(decode_base64); +use Term::ReadKey qw(ReadMode); + +use Selima::DataVars qw(:db :env :siteconf :scptconf); +use Selima::DBILogin; +use Selima::HTTP; + +#use vars qw(%DBH $MYSQL_HOST $MYSQL_TCP_PORT $MYSQL_UNIX_PORT $MYSQL_DB $MYSQL_USER $MYSQL_PWD); +use vars qw(%DBH); + +# new: Connect and establish a new MySQL database source +sub new : method { + local ($_, %_); + my ($class, $dbiclass, $dbh); + $class = ref($_[0]) || $_[0]; + + # Login with from SQLLOGIN environment variable as a web application + if ($IS_CGI) { + my ($dsn, %r); + # Prepare the connection information + %r = get_dbi_login_info DBI_MYSQL; + + # Compose the DSN + @_ = qw(); + push @_, "host=" . $r{"MYSQL_HOST"} . ";" if defined $r{"MYSQL_HOST"}; + $dsn = "dbi:mysql:" . join "", @_; + + # Return the available cached handle and clear the cache + if (exists $DBH{$dsn} && $DBH{$dsn}->ping) { + # Obtain the cached database handle + $dbh = $DBH{$dsn}; + # Clear the cache to remove static reference to the database handle, + # to avoid leaving dead handles that owns table locks + delete $DBH{$dsn}; + + # New connection + } else { + $dbiclass = (caller)[0]; + + # Try to log in, handling the failure later + %_ = ( "PrintError" => 0 ); + $dbh = $dbiclass->connect($dsn, $r{"MYSQL_USER"}, $r{"MYSQL_PWD"}, {%_}); + + # Login failed + http_500 $dbiclass->errstr if !defined $dbh; + + # Bless the object, name it as the current class + $dbh = bless $dbh, $dbiclass . "::db"; + + # Set the client encoding to UTF-8 + $_ = "SET NAMES 'utf8';\n"; + $dbh->do($_); + } + + # Set the database + $_ = "USE " . $r{"MYSQL_DB"} . ";\n"; + $dbh->do($_); + + # Ask the password from the console + } else { + my ($dsn, $subseq, $user, $passwd); + $dsn = "dbi:mysql:database=$PACKAGE;"; + $subseq = 0; + # Try to log in + while (!defined($dbh = DBI->connect($dsn, $user, $passwd, { PrintError => 0 }))) { + $_ = DBI->errstr; + if ($subseq) { + print STDERR "$_\n"; + sleep 5; + } + $subseq = 1; + # Obtain the current login user + $user = $1 if !defined $user && / denied for user: '(.+?)\@.+?'/; + # Disable console echo + ReadMode 2; + print STDERR defined $user? "MySQL password for $user: ": + "MySQL password: "; + $passwd = ; + print STDERR "\n"; + die "$THIS_FILE: Failed connecting to the MySQL server\n" + if !defined $passwd; + chomp $passwd; + # Restore console echo status + ReadMode 0; + } + } + + return $dbh; +} + +# park_handle: Suspend the database handle for further use (mod_perl) +sub park_handle : method { $DBH{"dbi:mysql:" . $_[1]->{"Name"}} = $_[1]; } + + +# Selima::DBD::mysql::db: The database-handler driver class +package Selima::DBD::mysql::db; + +use 5.008; +use strict; +use warnings; + +use Fcntl qw(:flock); + +use Selima::GetLang; +use Selima::HTTP; +use Selima::DataVars qw(:db :lninfo); + +# support: Return if a DBI feature is supported +sub support : method { + local ($_, %_); + my ($self, $feature); + ($self, $feature) = @_; + + # MySQL has VIEW since 5.0 + return 1 if $feature eq DBI_FEATHER_VIEW; + + # Default to yes. We assume everyone is a good guy. + return 1; +} + +# tables: Return the tables +sub tables : method { + local ($_, %_); + my ($self, $sth, $cache, @tables); + $self = $_[0]; + + # Initialize the cache + $cache = $self->{"private_selima"}; + # Return the cache + return @{${$cache}{"tables"}} if exists ${$cache}{"tables"}; + + # Get the tables list + $sth = $self->table_info(undef, undef, "%", undef) + or http_500 $self->errstr; + @tables = qw(); + push @tables, $$_{"TABLE_NAME"} + while defined($_ = $sth->fetchrow_hashref); + + # Cache it + ${$cache}{"tables"} = [@tables]; + + return @tables; +} + +# cols: Return the columns of a table +sub cols : method { + local ($_, %_); + my ($self, $table, $cache, $sth, @cols); + ($self, $table) = @_; + + # Initialize the cache + ${$self->{"private_selima"}}{"cols"} = {} + if !exists ${$self->{"private_selima"}}{"cols"}; + $cache = ${$self->{"private_selima"}}{"cols"}; + # Return the cache + return @{${$cache}{$table}} if exists ${$cache}{$table}; + + # Get the columns list + $sth = $self->column_info(undef, undef, $table, "%") + or http_500 $self->errstr; + @cols = qw(); + push @cols, $_ while defined($_ = $sth->fetchrow_hashref); + @cols = map $$_{"COLUMN_NAME"}, + sort { ${$a}{"ORDINAL_POSITION"} <=> ${$b}{"ORDINAL_POSITION"} } @cols; + + # Cache it + ${$cache}{$table} = [@cols]; + + return @cols; +} + +# col_lens: Obtain the column lengths of a table +sub col_lens : method { + local ($_, %_); + my ($self, $table, $cache, $sth, $sql, $count, %lens, $lndb); + ($self, $table) = @_; + + # Initialize the cache + ${$self->{"private_selima"}}{"col_lens"} = {} + if !exists ${$self->{"private_selima"}}{"col_lens"}; + $cache = ${$self->{"private_selima"}}{"col_lens"}; + # Return the cache + return %{${$cache}{$table}} if exists ${$cache}{$table}; + + # Use column_info here + $sth = $self->column_info(undef, undef, $table, "%") + or http_500 $self->errstr; + %_ = qw(); + $_{$$_{"COLUMN_NAME"}} = $$_{"COLUMN_SIZE"} + while defined($_ = $sth->fetchrow_hashref); + + # Hash the multi-lingual columns + $lndb = getlang(LN_DATABASE); + $lens{$_} = $lens{$_ . "_$lndb"} foreach $self->cols_ml($table); + + # Cache it + ${$cache}{"tables"} = {%_}; + + return %_; +} + +# quote_blob: Quote a piece of BLOB octet +sub quote_blob : method { + local ($_, %_); + my ($self, $octet); + ($self, $octet) = @_; + return $self->quote($octet); +} + +# strcat: Concatenate strings +sub strcat : method { + local ($_, %_); + my ($self, @strings); + ($self, @strings) = @_; + return "CONCAT(" . join(", ", @strings) . ")"; +} + +# lastupd: Obtain the last updated time of a list of tables +sub lastupd : method { + local ($_, %_); + my ($self, @tables, $sql, $sth); + ($self, @tables) = @_; + # Bounce if no tables supplied + return if scalar(@tables) == 0; + # Remove duplicates + %_ = map { $_ => 1 } @tables; + @tables = keys %_; + # Query + $sql = "SELECT mtime FROM mtime" + . " WHERE " . join(" OR ", map "tabname=" . $self->quote($_), @tables) + . " ORDER BY mtime DESC LIMIT 1;\n"; + $sth = $self->prepare($sql); + $sth->execute; + # Bounce if no data found + return if $sth->rows != 1; + # Return the result + return ${$sth->fetchrow_hashref}{"mtime"}; +} + +# Selima::DBD::mysql::st: The statement-handler driver class +package Selima::DBD::mysql::st; + +use 5.008; +use strict; +use warnings; + +# typecols: Return the list of columns in specific types +sub typecols : method { + local ($_, %_); + my ($self, $types, %cols); + $self = $_[0]; + $types = $self->{"mysql_type_name"}; + %cols = ( + "date" => [], + "num" => [], + "bigint" => [], + "numeric" => [], + "text" => [], + ); + for ($_ = 0; $_ < @$types; $_++) { + if ($$types[$_] =~ /^(?:date|datetime|timestamp)$/) { + push @{$cols{"date"}}, $_; + } elsif ($$types[$_] =~ /^(?:tinyint|smallint|middleint|integer|float|double)$/) { + push @{$cols{"num"}}, $_; + } elsif ($$types[$_] eq "bigint") { + push @{$cols{"bigint"}}, $_; + } elsif ($$types[$_] eq "decimal") { + push @{$cols{"numeric"}}, $_; + } elsif ($$types[$_] =~ /^(?:varchar|blob)$/) { + push @{$cols{"text"}}, $_; + } + } + return \%cols; +} + +return 1; diff --git a/lib/perl5/Selima/DBI.pm b/lib/perl5/Selima/DBI.pm new file mode 100644 index 0000000..73fe78f --- /dev/null +++ b/lib/perl5/Selima/DBI.pm @@ -0,0 +1,440 @@ +# Selima Website Content Management System +# DBI.pm: The extended DBI (database interface). + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-09 + +package Selima::DBI; +use 5.008; +use strict; +use warnings; +use base qw(DBI); + +use Selima::DataVars qw(:db); + +# new: Connect and establish a new database source +sub new : method { + local ($_, %_); + my ($type, $dbh, $class, $methods); + $type = $_[1]; + + # PostgreSQL + if ($type eq DBI_POSTGRESQL) { + require Selima::DBD::Pg; + $dbh = Selima::DBD::Pg->new; + # MySQL + } elsif ($type eq DBI_MYSQL) { + require Selima::DBD::mysql; + $dbh = Selima::DBD::mysql->new; + } + + # Keep the imported methods for cached DBH (mod_perl) + undef $methods; + $methods = ${$dbh->{"private_selima"}}{"methods"} + if exists $dbh->{"private_selima"} + && exists ${$dbh->{"private_selima"}}{"methods"}; + # Initialize the private attributes + $dbh->{"private_selima"} = {}; + # Import the methods + if (defined $methods) { + ${$dbh->{"private_selima"}}{"methods"} = $methods ; + } else { + $dbh->import_methods; + } + + return $dbh; +} + + +# Selima::DBI::db: The database-handler class +package Selima::DBI::db; + +use 5.008; +use strict; +use warnings; +use base qw(DBI::db); +use vars qw($METHODS_DEFINED @IMPORT_METHODS); +$METHODS_DEFINED = 0; +@IMPORT_METHODS = qw(support lock tables cols col_lens quote_blob + strcat lastupd current_schema); + +use Encode qw(encode); + +use Selima::DataVars qw(:env :lninfo); +use Selima::HTTP; +use Selima::GetLang; +use Selima::Guest; + +# import_methods: Import our own methods +sub import_methods : method { + local ($_, %_); + my ($self, $methods, $class, $driver); + $self = $_[0]; + + # Initialize the methods pool and the class and driver name + ${$self->{"private_selima"}}{"methods"} = {}; + $class = ref($self); + $driver = $class; + $driver =~ s/::DBI::db$//; + $driver .= "::DBD::" . $self->{"Driver"}->{"Name"} . "::db"; + + # Define the methods once + if (!$METHODS_DEFINED) { + # Short-cut to the methods pool + $methods = "\${\$_[0]->{\"private_selima\"}}{\"methods\"}"; + foreach (@IMPORT_METHODS) { + eval << "EOT"; +*$_ = sub { return \&{\${$methods}{"$_"}}(\@_); } +EOT + } + $METHODS_DEFINED = 1; + } + + # Short-cut to the methods pool + $methods = ${$self->{"private_selima"}}{"methods"}; + # Import each method + foreach my $func (@IMPORT_METHODS) { + if (defined($_ = $driver->can($func))) { + ${$methods}{$func} = $_; + } elsif (defined($_ = $class->can("SUPER::$func"))) { + ${$methods}{$func} = $_; + } else { + ${$methods}{$func} = sub {}; + } + } + return; +} + +# do: run SUPER::do() and handle errors +sub do : method { + local ($_, %_); + my ($self, $sql, $rv); + ($self, $sql, @_) = @_; + # $sql should always be a decoded text + $sql = encode("UTF-8", $sql); + # Run and handle errors + $rv = $self->SUPER::do($sql, @_) + or http_500 $sql . $self->errstr; + # Update the mtime + if ($sql =~ /^(?:INSERT\s+INTO|UPDATE|DELETE\s+FROM)\s+(\S+)/i) { + my ($table, $sql, $sth); + $table = $1; + $table =~ s/^"(.+?)"$/$1/; + $table = $self->quote($table); + $sql = "SELECT * FROM mtime WHERE tabname=$table;\n"; + $sth = $self->prepare($sql); + $sth->execute; + # Found + if ($sth->rows == 1) { + # Update the mtime + $sql = "UPDATE mtime SET mtime=now() WHERE tabname=$table;\n"; + $self->SUPER::do($sql); + # Not found + } else { + # Set the mtime + $sql = "INSERT INTO mtime (tabname, mtime) VALUES ($table, now());\n"; + $self->SUPER::do($sql); + } + } + return $rv; +} + +# gdo: only run do() when user is not a guest +sub gdo : method { + local ($_, %_); + my $self; + ($self, @_) = @_; + # Skip for guests + return 1 if is_guest; + return $self->do(@_); +} + +# prepare: run SUPER::prepare, handle errors and import our extension methods +sub prepare : method { + local ($_, %_); + my ($self, $sql, $sth); + ($self, $sql, @_) = @_; + # Run and handle errors + $sth = $self->SUPER::prepare($sql, @_) + or http_500 $sql . $self->errstr; + # Import our extension methods + $sth->{"private_selima"} = {}; + $sth->import_methods; + return $sth; +} + +# begin_work, commit, rollback do not need to handle their errors. +# errors can be silently ignored. See DBI(3) for more details. + +# +# Methods below are driver-indepedent. Override is not required. +# +# cols_ml: Return the multi-lingual columns list of a table (or view) +sub cols_ml : method { + local ($_, %_); + my ($self, $table, $sth, @cols, @cols_ml, $suf); + ($self, $table) = @_; + + $self->{"private_cols_ml"} = {} + if !exists $self->{"private_cols_ml"}; + # Return the cache + return @{${$self->{"private_cols_ml"}}{$table}} + if exists ${$self->{"private_cols_ml"}}{$table}; + + @cols = $self->cols($table); + @cols_ml = qw(); + $suf = "_" . getlang LN_DATABASE; + foreach (@cols) { + push @cols_ml, $_ if $_ =~ s/$suf$//; + } + + # Cache it + ${$self->{"private_cols_ml"}}{$table} = [@cols_ml]; + + return @cols_ml; +} + +# is_ml_table: Check if a table is multi-lingual +sub is_ml_table : method { + local ($_, %_); + my ($self, $table); + ($self, $table) = @_; + return scalar($self->cols_ml($table)) > 0; +} + +# esclike: Escape a phrase by the LIKE matching rule +# Double quote should never be used, according to +# the column name rules in the SQL standard. +sub esclike : method { + local ($_, %_); + my $self; + ($self, $_) = @_; + s/\\/\\\\\\\\/g; + s/%/\\\\%/g; + s/_/\\\\_/g; + # By the SQL standard + s/'/''/g; # ' gettext + # Non-standard, but this also works for most SQL DBMS + #s/'/\\\\\\'/g; + return $_; +} + +# disconnect: Disconnect from the database server +sub disconnect : method { + local ($_, %_); + my ($self, $class); + $self = $_[0]; + $class = ref($self); + $class =~ s/::DBI::db$//; + $class .= "::DBD::" . $self->{"Driver"}->{"Name"}; + + # Rollback the changes that are not committed and unlock the tables + $self->rollback if !$self->{"AutoCommit"}; + + # mod_perl: Suspend the database handle for further use, but not + # really disconnect it. + # Disabled. Save system from server load too high. + #if ($IS_MODPERL) { + # return $class->park_handle($self); + #} else { + $_ = $self->SUPER::disconnect or http_500 $self->errstr; + return $_; + #} +} + + +# Selima::DBI::st: The statement-handler class +package Selima::DBI::st; + +use 5.008; +use strict; +use warnings; +use base qw(DBI::st); +use vars qw($METHODS_DEFINED @IMPORT_METHODS); +$METHODS_DEFINED = 0; +@IMPORT_METHODS = qw(typecols); + +use DBI qw(:sql_types); +use Encode qw(decode_utf8 FB_CROAK is_utf8); +use Date::Parse qw(str2time); + +use Selima::HTTP; + +# import_methods: Import our own methods +sub import_methods : method { + local ($_, %_); + my ($self, $methods, $class, $driver); + $self = $_[0]; + + # Initialize the methods pool and the class and driver name + ${$self->{"private_selima"}}{"methods"} = {}; + $class = ref($self); + $driver = $class; + $driver =~ s/::DBI::st$//; + $driver .= "::DBD::" . $self->{"Database"}->{"Driver"}->{"Name"} . "::st"; + + # Define the methods once + if (!$METHODS_DEFINED) { + # Short-cut to the methods pool + $methods = "\${\$_[0]->{\"private_selima\"}}{\"methods\"}"; + foreach (@IMPORT_METHODS) { + eval << "EOT"; +*$_ = sub { return \&{\${$methods}{"$_"}}(\@_); } +EOT + } + $METHODS_DEFINED = 1; + } + + # Short-cut to the methods pool + $methods = ${$self->{"private_selima"}}{"methods"}; + # Import each method + foreach my $func (@IMPORT_METHODS) { + if (defined($_ = $driver->can($func))) { + ${$methods}{$func} = $_; + } elsif (defined($_ = $class->can("SUPER::$func"))) { + ${$methods}{$func} = $_; + } else { + ${$methods}{$func} = sub {}; + } + } + return; +} + +# execute: run SUPER::execute and handle errors +sub execute : method { + local ($_, %_); + my $self; + ($self, @_) = @_; + # Run and handle errors + $_ = $self->SUPER::execute(@_) + or http_500 $self->{"Statement"} . $self->errstr; + return $_; +} + +# fetch: fetch and decode from UTF-8 +# DBI::st returns a same array reference each time, with +# only the values changed. Then, after the first fetch, +# the values returned are all tagged as "wide characters" +# (decoded) and cannot be decode()ed again. To avoid this +# problem, we make a different copy of the returned values +# and decode that copy, instead of decoding those in the +# original array reference returned. +sub fetch : method { + local ($_, %_); + my ($self, @args, $row, $types); + ($self, @args) = @_; + # Fetch the row first + $row = $self->SUPER::fetch(@args); + # No record found or some error occurs + return undef if !defined $row; + + # Not called from within fetchrow_hashref() + if (exists $self->{"TYPE"}) { + # Make a copy of the record + $row = [@$row]; + # Obtain the type classes + ${$self->{"private_selima"}}{"types"} = $self->typecols + if !exists ${$self->{"private_selima"}}{"types"}; + $types = ${$self->{"private_selima"}}{"types"}; + # Convert the date/datetime columns + foreach (@{$$types{"date"}}) { + $$row[$_] = str2time $$row[$_] + if defined $$row[$_]; + } + # Convert the numeric columns + foreach (@{$$types{"num"}}) { + $$row[$_] = $$row[$_] + 0 + if defined $$row[$_]; + } + # Decode the text columns + foreach (@{$$types{"text"}}) { + $$row[$_] = decode_utf8($$row[$_], FB_CROAK) + if defined $$row[$_] && !is_utf8($$row[$_]); + } + } + return $row; +} + +# fetchrow_hashref: fetch and read some fields +sub fetchrow_hashref : method { + local ($_, %_); + my ($self, @args, $row, $types); + ($self, @args) = @_; + # Fetch the row first + $row = $self->SUPER::fetchrow_hashref(@args); + # No record found or some error occurs + return undef if !defined $row; + + # Make a copy of the record + $row = {%$row}; + # Obtain the type classes + ${$self->{"private_selima"}}{"types"} = $self->typecols + if !exists ${$self->{"private_selima"}}{"types"}; + $types = ${$self->{"private_selima"}}{"types"}; + # Convert the date/datetime columns + foreach (@{$$types{"date"}}) { + $$row{${$self->{"NAME"}}[$_]} = str2time $$row{${$self->{"NAME"}}[$_]} + if defined $$row{${$self->{"NAME"}}[$_]}; + } + # Convert the numeric columns + foreach (@{$$types{"num"}}) { + $$row{${$self->{"NAME"}}[$_]} = $$row{${$self->{"NAME"}}[$_]} + 0 + if defined $$row{${$self->{"NAME"}}[$_]}; + } + # Decode the text columns + foreach (@{$$types{"text"}}) { + $$row{${$self->{"NAME"}}[$_]} = decode_utf8($$row{${$self->{"NAME"}}[$_]}, FB_CROAK) + if defined $$row{${$self->{"NAME"}}[$_]} && !is_utf8($$row{${$self->{"NAME"}}[$_]}); + } + return $row; +} + +# fetchrow_arrayref: fetch and read some fields +sub fetchrow_arrayref : method { + local ($_, %_); + my ($self, @args, $row, $types); + ($self, @args) = @_; + # Fetch the row first + $row = $self->SUPER::fetchrow_arrayref(@args); + # No record found or some error occurs + return undef if !defined $row; + + # Make a copy of the record + $row = [@$row]; + # Obtain the type classes + ${$self->{"private_selima"}}{"types"} = $self->typecols + if !exists ${$self->{"private_selima"}}{"types"}; + $types = ${$self->{"private_selima"}}{"types"}; + # Convert the date/datetime columns + foreach (@{$$types{"date"}}) { + $$row[$_] = str2time $$row[$_] + if defined $$row[$_]; + } + # Convert the numeric columns + foreach (@{$$types{"num"}}) { + $$row[$_] = $$row[$_] + 0 + if defined $$row[$_]; + } + # Decode the text columns + foreach (@{$$types{"text"}}) { + $$row[$_] = decode_utf8($$row[$_], FB_CROAK) + if defined $$row[$_]; + } + return $row; +} + +return 1; diff --git a/lib/perl5/Selima/DBILogin.pm b/lib/perl5/Selima/DBILogin.pm new file mode 100644 index 0000000..a77dab4 --- /dev/null +++ b/lib/perl5/Selima/DBILogin.pm @@ -0,0 +1,93 @@ +# Selima Website Content Management System +# DBILogin.pm: The subroutine to extract the database log in information. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-02-02 + +package Selima::DBILogin; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(get_dbi_login_info); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub get_dbi_login_info($;$$); +} + +use MIME::Base64 qw(decode_base64); + +use Selima::DataVars qw(:db :siteconf); + +# get_dbi_login_info: Obtain the DBI log-in information +sub get_dbi_login_info($;$$) { + local ($_, %_); + my ($type, $host, $user, @names, %login); + ($type, $host, $user) = @_; + + # DBMS naming convensions + if ($type eq DBI_POSTGRESQL) { + @names = qw(PGHOST PGUSER PGPASSWORD PGDATABASE); + } elsif ($type eq DBI_MYSQL) { + @names = qw(MYSQL_HOST MYSQL_USER MYSQL_PW MYSQL_DB); + } + # Initialize the return values + %login = ( + $names[0] => undef, + $names[1] => undef, + $names[2] => undef, + $names[3] => "test", + ); + + # Obtain the DBI log-in information from the environment + if (exists $ENV{"SQLLOGIN"}) { + # Parse the DBI log-in information + # The first matched line is used, so put the default first + foreach my $line (split /\n/, decode_base64($ENV{"SQLLOGIN"})) { + @_ = split /\t/, $line; + # Skip malformed lines + next unless @_ == 4; + # Not this type + next if $_[0] ne $type; + # Not this host + next if defined $host && $_[1] ne $host; + # Not this user + next if defined $user && $_[2] ne $user; + # Found + # Deal with null values + foreach (@_) { + undef $_ if $_ eq "null"; + } + $login{$names[0]} = $_[1]; + $login{$names[1]} = $_[2]; + $login{$names[2]} = $_[3]; + $login{$names[3]} = $PACKAGE if defined $PACKAGE; + last; + } + } + + # Alternative information set in %DBILOGIN + foreach (keys %DBILOGIN) { + $login{$_} = $DBILOGIN{$_} if exists $login{$_}; + } + + return %login; +} + +return 1; diff --git a/lib/perl5/Selima/DataVars.pm b/lib/perl5/Selima/DataVars.pm new file mode 100644 index 0000000..55b7631 --- /dev/null +++ b/lib/perl5/Selima/DataVars.pm @@ -0,0 +1,243 @@ +# Selima Website Content Management System +# DataVars.pm: The core constants and variables. + +# Copyright (c) 2003-2020 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-24 + +package Selima::DataVars; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT %EXPORT_TAGS @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +%EXPORT_TAGS = ( + absuri => [qw(ABSURI_SKIP_FRAGMENT)], + addcol => [qw(ADDCOL_INSERT ADDCOL_UPDATE ADDCOL_NOTIMESTAMP)], + author => [qw($AUTHOR $COPYRIGHT)], + db => [qw($DBH $DBI_TYPE DBI_NONE DBI_POSTGRESQL DBI_MYSQL + DBI_FEATHER_VIEW %DBILOGIN)], + dataman => [qw($THIS_TABLE %CURRENT %REQUEST %PREVIEW)], + env => [qw($IS_CGI $IS_MODPERL $IS_MP2 $IS_PERLIS)], + forms => [qw(%SCRIPTS FORM_THIS FORM_USERS FORM_GROUPS FORM_USERMEM + FORM_GROUPMEM FORM_USERPREF FORM_SCPTPRIV FORM_PIC FORM_PAGES + FORM_NEWS FORM_LINKCAT FORM_LINKS FORM_ACCTSUBJ FORM_ACCTTRX + FORM_CAPTCHA)], + groups => [qw(SU_GROUP ADMIN_GROUP ALLUSERS_GROUP GUEST_GROUP)], + hostconf=> [qw($VIRTUAL_HOST $HTTPS_HOST $NOLOGIN)], + input => [qw(%USER_INPUT $POST $GET $UPLOAD %COOKIES $SESSION $AUTHINFO)], + l10n => [qw($DEFAULT_LANG @ALL_LINGUAS $LH $CLH $ALH + $LOCALEDIR COMMON_DOMAIN COMMON_LOCALEDIR)], + lastmod => [qw($LAST_MODIFIED)], + libdir => [qw($SITE_LIBDIR COMMON_LIBDIR)], + list => [qw($PAGEBAR_RANGE)], + lninfo => [qw(LN_NAME LN_CHARSET LN_FILENAME LN_LOCALE LN_DATABASE + LN_HTMLID LN_SPACE_BREAK LN_COUNTRY_FIRST + LN_DESC LN_DESC_CURLC LN_DESC_SELFLC LN_SWITCH_TITLE)], + mail => [qw(SMTP_HOST)], + output => [qw($CONTENT_TYPE $NO_AUTO_OUTPUT %NEWCOOKIES %HTTP_HEADERS + $PAGE_PARAM $ALT_PAGE_PARAM)], + proctime=> [qw($LOGTIME $T_START)], + rebuild => [qw(@REBUILD_TABLES %REBUILD_LABELS)], + requri => [qw($DOC_ROOT $ROOT_DIFF $REQUEST_PATH $REQUEST_FILE + $REQUEST_URI $REQUEST_FILEQS $REQUEST_SCHEME $REQUEST_HOST + $REQUEST_HOSTPORT $REQUEST_HOSTPATH $REQUEST_FULLURI)], + scptconf=> [qw($THIS_FILE $MAIN)], + siteconf=> [qw($PACKAGE $WEBMASTER $SITENAME_ABBR)], + user => [qw(%USERPREF)], +); +@EXPORT_OK = qw(); +my %seen; +%seen = qw(); +foreach my $tag (keys %EXPORT_TAGS) { + push @EXPORT_OK, grep !$seen{$_}++, @{$EXPORT_TAGS{$tag}}; +} +$EXPORT_TAGS{"all"} = [@EXPORT_OK]; +# Prototype declaration +sub clear(); +} + +use vars qw($AUTHOR $COPYRIGHT); +use vars qw($DBH $DBI_TYPE %DBILOGIN); +use vars qw($THIS_TABLE %CURRENT %REQUEST); +use vars qw($IS_CGI $IS_MODPERL $IS_MP2 $IS_PERLIS); +use vars qw(%SCRIPTS); +use vars qw($VIRTUAL_HOST $HTTPS_HOST $NOLOGIN); +use vars qw(%USER_INPUT $POST $GET $UPLOAD %COOKIES $SESSION $AUTHINFO); +use vars qw($DEFAULT_LANG @ALL_LINGUAS $LH $CLH $ALH); +use vars qw($LOCALEDIR); +use vars qw($LAST_MODIFIED); +use vars qw($SITE_LIBDIR); +use vars qw($PAGEBAR_RANGE); +use vars qw($CONTENT_TYPE $NO_AUTO_OUTPUT %NEWCOOKIES %HTTP_HEADERS); +use vars qw($PAGE_PARAM $ALT_PAGE_PARAM); +use vars qw($LOGTIME $T_START); +use vars qw(@REBUILD_TABLES %REBUILD_LABELS); +use vars qw($DOC_ROOT $ROOT_DIFF $REQUEST_PATH $REQUEST_FILE); +use vars qw($REQUEST_URI $REQUEST_FILEQS $REQUEST_SCHEME $REQUEST_HOST); +use vars qw($REQUEST_HOSTPORT $REQUEST_HOSTPATH $REQUEST_FULLURI); +use vars qw($THIS_FILE $MAIN); +use vars qw($PACKAGE $WEBMASTER $SITENAME_ABBR); +use vars qw(%USERPREF); +use constant ABSURI_SKIP_FRAGMENT => 1; + +use constant ADDCOL_INSERT => 0; +use constant ADDCOL_UPDATE => 1; +use constant ADDCOL_NOTIMESTAMP => 0; + +use constant DBI_NONE => ""; +use constant DBI_POSTGRESQL => "PostgreSQL"; +use constant DBI_MYSQL => "MySQL"; +use constant DBI_FEATHER_VIEW => "view"; + +use constant FORM_THIS => 0; +use constant FORM_USERS => 1; +use constant FORM_GROUPS => 2; +use constant FORM_USERPRIV => 3; +use constant FORM_USERMEM => 4; +use constant FORM_GROUPMEM => 5; +use constant FORM_USERPREF => 6; +use constant FORM_SCPTPRIV => 7; +use constant FORM_PIC => 8; +use constant FORM_PAGES => 9; +use constant FORM_NEWS => 10; +use constant FORM_LINKCAT => 11; +use constant FORM_LINKS => 12; +use constant FORM_ACCTSUBJ => 13; +use constant FORM_ACCTTRX => 14; +# The column name of the CAPTCHA +# This is used to deceive the spambots +use constant FORM_CAPTCHA => "lastname"; + +use constant SU_GROUP => "root"; +use constant ADMIN_GROUP => "admin"; +use constant ALLUSERS_GROUP => "users"; +use constant GUEST_GROUP => "guests"; + +use constant COMMON_DOMAIN => "selima"; +use constant COMMON_LOCALEDIR => $ENV{"DOCUMENT_ROOT"} . "/../../locale"; + +use constant COMMON_LIBDIR => $ENV{"DOCUMENT_ROOT"} . "/../../lib/perl5"; + +use constant LN_NAME => 0; +use constant LN_CHARSET => 1; +use constant LN_FILENAME => 2; +use constant LN_LOCALE => 3; +use constant LN_DATABASE => 4; +use constant LN_HTMLID => 5; +use constant LN_SPACE_BREAK => 6; +#use constant LN_IGNORE_CASE => 7; +use constant LN_COUNTRY_FIRST => 8; +use constant LN_DESC => 9; +use constant LN_DESC_CURLC => 10; +use constant LN_DESC_SELFLC => 11; +use constant LN_SWITCH_TITLE => 12; + +use constant SMTP_HOST => "localhost"; + +# Check the environment type in advance. These variables does not change +# at all even under mod_perl. +# GATEWAY_INTERFACE is not available yet when this script is loaded +$IS_CGI = exists $ENV{"GATEWAY_INTERFACE"} || exists $ENV{"MOD_PERL"}; +$IS_MODPERL = exists $ENV{"MOD_PERL"}; +$IS_MP2 = exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2; +$IS_PERLIS = exists $ENV{"PERLXS"} && $ENV{"PERLXS"} eq "PerlIS"; + +# clear: Clear the data variables +sub clear() { + local ($_, %_); + + # Reset all the data variables + undef $AUTHINFO; + + undef $AUTHOR; + undef $COPYRIGHT; + + undef $DBH; + undef $DBI_TYPE; + %DBILOGIN = qw(); + + undef $THIS_TABLE; + %CURRENT = qw(); + %REQUEST = qw(); + + %SCRIPTS = qw(); + + undef $VIRTUAL_HOST; + undef $HTTPS_HOST; + undef $NOLOGIN; + + %USER_INPUT = qw(); + undef $POST; + undef $GET; + undef $UPLOAD; + %COOKIES = qw(); + + undef $DEFAULT_LANG; + @ALL_LINGUAS = qw(); + undef $LH; + undef $CLH; + undef $ALH; + undef $LOCALEDIR; + + undef $LAST_MODIFIED; + + undef $SITE_LIBDIR; + + undef $PAGEBAR_RANGE; + + undef $CONTENT_TYPE; + undef $NO_AUTO_OUTPUT; + %NEWCOOKIES = qw(); + %HTTP_HEADERS = qw(); + undef $PAGE_PARAM; + undef $ALT_PAGE_PARAM; + + undef $LOGTIME; + undef $T_START; + + @REBUILD_TABLES = qw(); + %REBUILD_LABELS = qw(); + + undef $DOC_ROOT; + undef $ROOT_DIFF; + undef $REQUEST_PATH; + undef $REQUEST_FILE; + undef $REQUEST_URI; + undef $REQUEST_FILEQS; + undef $REQUEST_SCHEME; + undef $REQUEST_HOST; + undef $REQUEST_HOSTPORT; + undef $REQUEST_HOSTPATH; + undef $REQUEST_FULLURI; + + undef $SESSION; + + undef $THIS_FILE; + undef $MAIN; + + undef $PACKAGE; + undef $WEBMASTER; + undef $SITENAME_ABBR; + + %USERPREF = qw(); + + return; +} + +return 1; diff --git a/lib/perl5/Selima/DecForm.pm b/lib/perl5/Selima/DecForm.pm new file mode 100644 index 0000000..6e5e055 --- /dev/null +++ b/lib/perl5/Selima/DecForm.pm @@ -0,0 +1,443 @@ +# Selima Website Content Management System +# DecForm.pm: The subroutines to decode the the input form from various character sets. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-10 + +package Selima::DecForm; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(init_forms decode_forms decode_forms_delay); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub init_forms(); +sub decode_forms(); +sub decode_forms_delay(); +sub try_decode_form($$); +sub split_upload($); +} + +use Encode qw(decode FB_CROAK); +use URI::Escape qw(uri_escape); +use HTML::Entities qw(%entity2char); + +use Selima::DataVars qw(:env :input :l10n :lninfo); +use Selima::GetLang; +use Selima::HTTP; +use Selima::LnInfo; +use Selima::Unicode; + +use vars qw(@TRY); +@TRY = qw(US-ASCII Big5 GB2312 Shift-JIS UTF-8 ISO-8859-1 ISO-8859-15); + +# init_forms: Initialize the user-input form data +sub init_forms() { + local ($_, %_); + my ($r, $rawget, $rawpost, $postdelay); + + # Do not redo + return if scalar(keys %USER_INPUT) > 0; + + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + + # Scan the GET query + $rawget = $IS_MODPERL? (defined $r->args? $r->args: ""): + (exists $ENV{"QUERY_STRING"}? $ENV{"QUERY_STRING"}: ""); + $GET = new CGI($rawget); + + # Scan the POST form + $postdelay = 0; + if (($IS_MODPERL? $r->method: $ENV{"REQUEST_METHOD"}) eq "POST") { + if ($IS_MODPERL) { + # Ordinary POST form + if ( !defined($_ = $r->headers_in->get("Content-Type")) + || $_ eq "application/x-www-form-urlencoded") { + if ($IS_MP2) { + $r->read($rawpost, $r->headers_in->get("Content-Length")); + } else { + $rawpost = $r->content; + } + $POST = new CGI($rawpost); + $r->headers_in->set("X-Selima-POST", $rawpost); + # Others (file uploads, etc) and CGI environment is ready + # - parse with CGI.pm default parser + } elsif (exists $ENV{"SERVER_SOFTWARE"}) { + $POST = new CGI; + @_ = qw(); + foreach my $name ($POST->param) { + foreach my $val ($POST->param($name)) { + push @_, uri_escape($name) . "=" . uri_escape($val); + } + } + $rawpost = join "&", @_; + # Others (file uploads, etc) and CGI environment is not ready yet + # - delay the parsing + } else { + $rawpost = ""; + $POST = new CGI($rawpost); + $postdelay = 1; + } + } else { + # POST form was obtained by mod_perl handler before + if (exists $ENV{"HTTP_X_SELIMA_POST"}) { + $rawpost = $ENV{"HTTP_X_SELIMA_POST"}; + $POST = new CGI($rawpost); + # Ordinary POST form -- parse the STDIN + } elsif ( !exists $ENV{"HTTP_CONTENT_TYPE"} + || $ENV{"HTTP_CONTENT_TYPE"} eq "application/x-www-form-urlencoded") { + $rawpost = ; + $POST = new CGI($rawpost); + # Others (file uploads, etc) - parse with CGI.pm default parser + } else { + $POST = new CGI; + @_ = qw(); + foreach my $name ($POST->param) { + foreach my $val ($POST->param($name)) { + push @_, uri_escape($name) . "=" . uri_escape($val); + } + } + $rawpost = join "&", @_; + } + } + } else { + $rawpost = ""; + $POST = new CGI($rawpost); + } + + # Split the uploaded files + ($POST, $UPLOAD) = split_upload $POST; + + # Initialize the data deposit + %USER_INPUT = ( + "GET_RAW" => $GET, + "GET_UTF8" => $GET, + "GET_CHARSET" => undef, + "GET_CSERR" => 1, + "GET_RAWDATA" => $rawget, + "GET_KEYS" => [ $GET->param ], + "POST_RAW" => $POST, + "POST_UTF8" => $POST, + "POST_CHARSET" => undef, + "POST_CSERR" => 1, + "POST_RAWDATA" => $rawpost, + "POST_DELAY" => $postdelay, + "UPLOAD" => $UPLOAD, + ); + + return; +} + +# decode_forms: Decode user FORM input from some character set +sub decode_forms() { + local ($_, %_); + my (@charsets, @charsets_site); + + # The possible character sets of this website + @charsets_site = map ln($_, LN_CHARSET), @ALL_LINGUAS; + + # The GET arguments + # The character set candidates + @_ = qw(); + push @_, $GET->param("charset") if defined $GET->param("charset"); + push @_, getlang LN_CHARSET; + push @_, @charsets_site; + push @_, @TRY; + @charsets = qw(); + %_ = qw(); + foreach (@_) { + if (lc $_ eq "big5") { + if (!exists $_{"Big5-ETen"}) { + push @charsets, "Big5-ETen"; + $_{"Big5-ETen"} = 1; + } + if (!exists $_{"Big5"}) { + push @charsets, "Big5"; + $_{"Big5"} = 1; + } + if (!exists $_{"CP950"}) { + push @charsets, "CP950"; + $_{"CP950"} = 1; + } + if (!exists $_{"Big5-HKSCS"}) { + push @charsets, "Big5-HKSCS"; + $_{"Big5-HKSCS"} = 1; + } + } elsif (lc $_ eq "big5-hkscs") { + if (!exists $_{"Big5-HKSCS"}) { + push @charsets, "Big5-HKSCS"; + $_{"Big5-HKSCS"} = 1; + } + } elsif (lc $_ eq "gb2312" || lc $_ eq "gb18030") { + if (!exists $_{"GB2312"}) { + push @charsets, "GB2312"; + $_{"GB2312"} = 1; + } + if (!exists $_{"GB18030"}) { + push @charsets, "GB18030"; + $_{"GB18030"} = 1; + } + } else { + if (!exists $_{$_}) { + push @charsets, $_; + $_{$_} = 1; + } + } + } + # Check each character set + foreach my $charset (@charsets) { + $_ = $USER_INPUT{"GET_RAW"}; + # In this character set + if (defined($_ = try_decode_form $_, $charset)) { + $GET = $_; + $USER_INPUT{"GET_UTF8"} = $_; + $USER_INPUT{"GET_CHARSET"} = $charset; + $USER_INPUT{"GET_CSERR"} = 0; + $USER_INPUT{"GET_KEYS"} = [ $_->param ]; + last; + } + } + + # The POSTed form + # The character set candidates + @_ = qw(); + push @_, $POST->param("charset") if defined $POST->param("charset"); + push @_, getlang LN_CHARSET; + push @_, @charsets_site; + push @_, @TRY; + @charsets = qw(); + %_ = qw(); + foreach (@_) { + if (lc $_ eq "big5") { + if (!exists $_{"Big5-ETen"}) { + push @charsets, "Big5-ETen"; + $_{"Big5-ETen"} = 1; + } + if (!exists $_{"Big5"}) { + push @charsets, "Big5"; + $_{"Big5"} = 1; + } + if (!exists $_{"CP950"}) { + push @charsets, "CP950"; + $_{"CP950"} = 1; + } + if (!exists $_{"Big5-HKSCS"}) { + push @charsets, "Big5-HKSCS"; + $_{"Big5-HKSCS"} = 1; + } + } elsif (lc $_ eq "big5-hkscs") { + if (!exists $_{"Big5-HKSCS"}) { + push @charsets, "Big5-HKSCS"; + $_{"Big5-HKSCS"} = 1; + } + } elsif (lc $_ eq "gb2312" || lc $_ eq "gb18030") { + if (!exists $_{"GB2312"}) { + push @charsets, "GB2312"; + $_{"GB2312"} = 1; + } + if (!exists $_{"GB18030"}) { + push @charsets, "GB18030"; + $_{"GB18030"} = 1; + } + } else { + if (!exists $_{$_}) { + push @charsets, $_; + $_{$_} = 1; + } + } + } + # Check each character set + foreach my $charset (@charsets) { + $_ = $USER_INPUT{"POST_RAW"}; + # In this character set + if (defined($_ = try_decode_form $_, $charset)) { + $POST = $_; + $USER_INPUT{"POST_UTF8"} = $_; + $USER_INPUT{"POST_CHARSET"} = $charset; + $USER_INPUT{"POST_CSERR"} = 0; + last; + } + } + + # No valid character set was found + http_500 "Unable to detect the character set of your submitted information. Please specify the input character set with charset= parameter." + if $USER_INPUT{"GET_CSERR"} || $USER_INPUT{"POST_CSERR"}; + + return; +} + +# decode_forms_delay: Initialize and decode multipart/form-data (uploads) +# for mod_perl. We cannot obtain it before the CGI environment is ready. +sub decode_forms_delay() { + local ($_, %_); + my ($r, $rawpost, @charsets, @charsets_site); + # Parsing not delayed + return unless $USER_INPUT{"POST_DELAY"}; + + # Obtain the POST form + $POST = new CGI; + @_ = qw(); + foreach my $name ($POST->param) { + foreach my $val ($POST->param($name)) { + push @_, uri_escape($name) . "=" . uri_escape($val); + } + } + $rawpost = join "&", @_; + + # Split the uploaded files + ($POST, $UPLOAD) = split_upload $POST; + + # Record it + $USER_INPUT{"POST_RAW"} = $POST; + $USER_INPUT{"POST_UTF8"} = $POST; + $USER_INPUT{"POST_CHARSET"} = undef; + $USER_INPUT{"POST_CSERR"} = 1; + $USER_INPUT{"POST_RAWDATA"} = $rawpost; + $USER_INPUT{"UPLOAD"} = $UPLOAD; + + # The character set candidates + @_ = qw(); + push @_, $POST->param("charset") if defined $POST->param("charset"); + push @_, getlang LN_CHARSET; + push @_, map ln($_, LN_CHARSET), @ALL_LINGUAS; + push @_, @TRY; + @charsets = qw(); + %_ = qw(); + foreach (@_) { + if (lc $_ eq "big5") { + if (!exists $_{"Big5-ETen"}) { + push @charsets, "Big5-ETen"; + $_{"Big5-ETen"} = 1; + } + if (!exists $_{"Big5"}) { + push @charsets, "Big5"; + $_{"Big5"} = 1; + } + if (!exists $_{"CP950"}) { + push @charsets, "CP950"; + $_{"CP950"} = 1; + } + if (!exists $_{"Big5-HKSCS"}) { + push @charsets, "Big5-HKSCS"; + $_{"Big5-HKSCS"} = 1; + } + } elsif (lc $_ eq "big5-hkscs") { + if (!exists $_{"Big5-HKSCS"}) { + push @charsets, "Big5-HKSCS"; + $_{"Big5-HKSCS"} = 1; + } + } elsif (lc $_ eq "gb2312" || lc $_ eq "gb18030") { + if (!exists $_{"GB2312"}) { + push @charsets, "GB2312"; + $_{"GB2312"} = 1; + } + if (!exists $_{"GB18030"}) { + push @charsets, "GB18030"; + $_{"GB18030"} = 1; + } + } else { + if (!exists $_{$_}) { + push @charsets, $_; + $_{$_} = 1; + } + } + } + # Check each character set + foreach my $charset (@charsets) { + $_ = $USER_INPUT{"POST_RAW"}; + # In this character set + if (defined($_ = try_decode_form $_, $charset)) { + $POST = $_; + $USER_INPUT{"POST_UTF8"} = $_; + $USER_INPUT{"POST_CHARSET"} = $charset; + $USER_INPUT{"POST_CSERR"} = 0; + last; + } + } + + # No valid character set was found + http_500 "Unable to detect the character set of your submitted information. Please specify the input character set with charset= parameter." + if $USER_INPUT{"GET_CSERR"} || $USER_INPUT{"POST_CSERR"}; + + return; +} + +# try_decode_form: Try to decode a CGI form with a specific character set +sub try_decode_form($$) { + local ($_, %_); + my ($SOURCE, $charset, $RESULT, $name, $is_upload); + ($SOURCE, $charset) = @_; + + # Obtain a copy of the converted result + $RESULT = new CGI(""); + $is_upload = 0; + foreach $name ($SOURCE->param) { + @_ = $SOURCE->param($name); + return if !defined($name = hcref_decode($charset, $name)); + foreach (@_) { + s/\x00//g; + return if !defined($_ = hcref_decode($charset, $_)); + } + $RESULT->param($name, @_); + } + + return $RESULT; +} + +# split_upload: Split the uploaded files from the POST form +sub split_upload($) { + local ($_, %_); + my ($FORM, $UPLOAD, $name); + $FORM = $_[0]; + + $UPLOAD = $FORM; + $FORM = new CGI(""); + foreach $name ($UPLOAD->param) { + my (@valp, @valu); + @valp = qw(); + @valu = qw(); + foreach ($UPLOAD->param($name)) { + # A scalar value + if (ref $_ eq "") { + push @valp, $_; + # Others (file uploads Fh, etc.) + } else { + push @valu, $_; + } + } + # Some scalar found + if (@valp > 0) { + # Move to the POST form + $FORM->param($name, @valp); + # There are some uploaded files for this column + if (@valu > 0) { + $UPLOAD->param($name, @valu); + # No uploaded file for this column + } else { + $UPLOAD->delete($name); + } + } + } + + return ($FORM, $UPLOAD); +} + +return 1; diff --git a/lib/perl5/Selima/Destroy.pm b/lib/perl5/Selima/Destroy.pm new file mode 100644 index 0000000..fed1519 --- /dev/null +++ b/lib/perl5/Selima/Destroy.pm @@ -0,0 +1,226 @@ +# Selima Website Content Management System +# Destroy.pm: The script-environment cleaner. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-27 + +package Selima::Destroy; +use 5.008; +use strict; +use warnings; + +use CGI qw(header); +use HTTP::Date qw(time2str); +use IO::NestedCapture qw(CAPTURE_STDOUT); +use Time::HiRes qw(); + +BEGIN { +if (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + require Apache2::Response; +} +} + +use Selima::AltLang; +use Selima::Cache qw(); +use Selima::DataVars qw($DBH $SESSION :env :input :l10n :lastmod + :lninfo :output :proctime :requri :scptconf :siteconf); +use Selima::GetLang; +use Selima::HTTP; +use Selima::Logging; +use Selima::LogIn; +use Selima::Page2Rel; +use Selima::PageFunc; +use Selima::Unicode; +use Selima::XHTML; + +# new: Initialize the object +sub new : method { bless {}, $_[0]; } + +# DESTROY: Clean all the variables +sub DESTROY : method { + local ($_, %_); + my ($self, $html); + $self = $_[0]; + + # Disconnect the database handle + if (defined $DBH) { + $DBH->disconnect; + undef $DBH; + } + + # Flush, close and release the session and its lock + if (defined $SESSION) { + $SESSION->close; + undef $SESSION; + } + + # Output the content + if (!$NO_AUTO_OUTPUT) { + my ($type, $r, $charset, $is_html, $is_text); + + # Obtain the output + $html = ""; + while ( exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0) { + my $FD; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $html .= join "", <$FD>; + } + + # No content -- HTTP 204 + http_204 if $html eq ""; + + $type = defined $CONTENT_TYPE? $CONTENT_TYPE: xhtml_content_type; + $is_html = ($type =~ /^(?:text\/html|application\/xhtml\+xml)\b/)? 1: 0; + $is_text = ($type =~ /^(?:text\/plain|text\/csv)\b/)? 1: 0; + + # Do the run-time replacements + if ( ($is_text || $is_html) + && defined($_ = $MAIN->can("page_replacements"))) { + %_ = %{&$_}; + $html =~ s//${$_{$_}}{"content"}/g + foreach keys %_; + } + + # Fix the HTML output + if ($is_html) { + if ($type =~ /; charset=([^ ;]+)/) { + $charset = $1; + } else { + $charset = getlang(LN_CHARSET); + $type .= "; charset=$charset"; + } + # Convert the URLs to relative + $html = page2rel($html, $REQUEST_PATH); + # Encode the e-mail at-signs (@) + $html =~ s/@/@/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap@/spamtrap@/g; + # Convert to the desired character set + $html = page_encode($html, $charset); + + # Fix the plain text output + } elsif ($is_text) { + if ($type =~ /; charset=([^ ;]+)/) { + $charset = $1; + } else { + $charset = "UTF-8"; + $type .= "; charset=$charset"; + } + # Encode the e-mail at-signs (@) + $html =~ s/@/-at-/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap-at-/spamtrap@/g; + # Convert to the desired character set + $html = page_encode($html, $charset); + } + + # Only output headers to CGI + if ($IS_CGI) { + # The mod_perl way + if ($IS_MODPERL) { + $r = $IS_MP2? Apache2::RequestUtil->request: + Apache->request; + $r->content_type($type); + if ($IS_MP2) { + $r->set_content_length(length $html); + } else { + $r->headers_out->set("Content-Length"=>length $html); + } + $r->headers_out->set("Accept-Ranges"=>"none"); + $r->content_languages([getlang LN_NAME]) + if $type =~ /^text\// || $is_html; + # Client cache + if (defined $LAST_MODIFIED) { + if (defined get_login_sn) { + $r->headers_out->set("Cache-Control"=>"private"); + } else { + $r->headers_out->set("Cache-Control"=>"public"); + } + $r->headers_out->set("Last-Modified"=>time2str($LAST_MODIFIED)); + } else { + $r->headers_out->set("Cache-Control"=>"no-cache"); + } + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $r->method ne "POST" + && $r->method ne "PUT" + && !defined $GET->param("lang")) { + $r->headers_out->set("Content-Location"=>altlang(getlang, page_param)); + $r->headers_out->set("Vary"=>"accept-language,cookie"); + } + $r->headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + $r->headers_out->add($_=>$HTTP_HEADERS{$_}) + foreach keys %HTTP_HEADERS; + $r->send_http_header if !$IS_MP2; + + # Ordinary CGI + } else { + my %h; + %h = ( -type=>$type, + -Content_Length=>length $html, + -Accept_Ranges=>"none"); + $h{"-Content_Language"} = getlang LN_NAME + if $type =~ /^text\// || $is_html; + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $ENV{"REQUEST_METHOD"} ne "POST" + && $ENV{"REQUEST_METHOD"} ne "PUT" + && !defined $GET->param("lang")) { + $h{"-Content_Location"} = altlang getlang, page_param; + $h{"-Vary"} = "accept-language,cookie"; + } + # Client cache + if (defined $LAST_MODIFIED) { + if (defined get_login_sn) { + $h{"-Cache_Control"} = "private"; + } else { + $h{"-Cache_Control"} = "public"; + } + $h{"-Last_Modified"} = time2str($LAST_MODIFIED); + } else { + $h{"-Cache_Control"} = "no-cache"; + } + $h{"-cookie"} = [values %NEWCOOKIES]; + $h{$_} = $HTTP_HEADERS{$_} foreach keys %HTTP_HEADERS; + print header(%h); + } + } + # Print the page body + print $html if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Print the processing time for debugging purpose + log_warn "Process time: " . (Time::HiRes::time - $T_START) . " sec.\n" + if $LOGTIME; + + # Clear the data variables + $_ = "Selima::" . $PACKAGE . "::Config"; + &$_ if defined($_ = $_->can("clear")); + Selima::DataVars::clear; + # Clear the cache + Selima::Cache::clear; + + # Run the parent DESTROY method + $self->SUPER::DESTROY if $self->can("SUPER::DESTROY"); + # I cannot really undefine myself ($_[0]) after all + return; +} + +return 1; diff --git a/lib/perl5/Selima/EchoForm.pm b/lib/perl5/Selima/EchoForm.pm new file mode 100644 index 0000000..d6694c9 --- /dev/null +++ b/lib/perl5/Selima/EchoForm.pm @@ -0,0 +1,99 @@ +# Selima Website Content Management System +# EchoForm.pm: The subroutines to output various form elements. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-30 + +package Selima::EchoForm; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(auto_keep_referer); +push @EXPORT, qw(opt_list opt_list_array preselect_options); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub opt_list($$); +sub opt_list_array(\@); +sub preselect_options($$); +sub auto_keep_referer(); +} + +use Selima::Cache qw(:echoform); +use Selima::CommText; +use Selima::DataVars qw($DBH); +use Selima::ShortCut; +use Selima::Unicode; + +# opt_list: Return an options list +sub opt_list($$) { + local ($_, %_); + my ($sql, $curval, $sth, $count, $html); + ($sql, $curval) = @_; + # Not cached yet + if (!exists $EchoForm_opt_list{$sql}) { + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @_ = qw(); $_ < $count; $_++) { + push @_, $sth->fetchrow_hashref; + } + $EchoForm_opt_list{$sql} = opt_list_array @_; + } + return preselect_options($EchoForm_opt_list{$sql}, $curval); +} + +# opt_list_array: Return an options list from an array +sub opt_list_array(\@) { + local ($_, %_); + my ($opts, $html); + $opts = $_[0]; + # Obtain the HTML + $html = " \n"; + foreach (@$opts) { + $html .= " \n"; + } + return $html; +} + +# preselect_options: Presect an option in an option list +sub preselect_options($$) { + local ($_, %_); + my ($html, $value); + ($html, $value) = @_; + # Not selected if value not set + return $html if !defined $value; + $value = h_encode($value); + $html =~ s/<(option value="$value")>/<$1 selected="selected">/; + return $html; +} + +# auto_keep_referer: If we should keep the referer information +# To be done +sub auto_keep_referer() { + local ($_, %_); + # False for now; + return 0; +} + +return 1; diff --git a/lib/perl5/Selima/Encrypt.pm b/lib/perl5/Selima/Encrypt.pm new file mode 100644 index 0000000..ce92a58 --- /dev/null +++ b/lib/perl5/Selima/Encrypt.pm @@ -0,0 +1,62 @@ +# Selima Website Content Management System +# Encrypt.pm: The simple symmetric encrypter/decrypter. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-26 + +package Selima::Encrypt; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(encrypt decrypt); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub encrypt($); +sub decrypt($); +} + +use Crypt::Rijndael qw(); +use MIME::Base64 qw(encode_base64 decode_base64); + +use vars qw($cipher); +$cipher = new Crypt::Rijndael(decode_base64("MDkxcTc3dGNvMkRZTTYxM0dqRmZ2R2xvQmNLcUZkNVo=")); + +# This use symmetric encryption/decryption. It is not safe. +# Nothing is exported. Use it by the full package name. + +# encrypt: Encrypt +sub encrypt($) { + local ($_, %_); + $_ = $_[0]; + $_ = length($_) . " " . $_; + # Pad with US-ASCII printable characters + $_ .= chr(32 + int rand 95) while length($_) % 16 != 0; + return encode_base64($cipher->encrypt($_)); +} + +# decrypt: Decrypt +sub decrypt($) { + local ($_, %_); + $_ = $cipher->decrypt(decode_base64($_[0])); + s/^(\d+) //; + return substr $_, 0, $1; +} + +return 1; diff --git a/lib/perl5/Selima/ErrMsg.pm b/lib/perl5/Selima/ErrMsg.pm new file mode 100644 index 0000000..68617ae --- /dev/null +++ b/lib/perl5/Selima/ErrMsg.pm @@ -0,0 +1,57 @@ +# Selima Website Content Management System +# ErrMsg.pm: The Maketext error message composer. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-23 + +package Selima::ErrMsg; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(err2msg); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub err2msg($); +} + +use Selima::DataVars qw(:l10n :lninfo); +use Selima::LnInfo; +use Selima::ShortCut; + +# err2msg: Compose the error message from the $error hash reference +sub err2msg($) { + local (%_, $_); + my $status; + $status = $_[0]; + # Empty string + return "" if !exists $$status{"msg"}; + $_ = $$status{"msg"}; + @_ = qw(); + @_ = @{$$status{"margs"}} if exists $$status{"margs"}; + foreach (@_) { + if ($_ eq "_DEFAULT_LANG") { + $_ = h(ln $DEFAULT_LANG, LN_DESC_CURLC); + } + } + # Maketext + return F_($_, @_); +} + +return 1; diff --git a/lib/perl5/Selima/FetchRec.pm b/lib/perl5/Selima/FetchRec.pm new file mode 100644 index 0000000..db1752d --- /dev/null +++ b/lib/perl5/Selima/FetchRec.pm @@ -0,0 +1,56 @@ +# Selima Website Content Management System +# FetchRec.pm: The subroutine to fetch a record from a database table. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-28 + +package Selima::FetchRec; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(fetchrec); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub fetchrec(\$$); +} + +use Selima::ChkFunc; +use Selima::DataVars qw($DBH :lninfo); +use Selima::GetLang; + +# fetchrec: Try to fetch a record by its serial number +sub fetchrec(\$$) { + local ($_, %_); + my ($sn, $table, $sth, $sql, %row); + ($sn, $table) = @_; + return if !check_sn $$sn; + $sql = "SELECT * FROM " . $DBH->quote_identifier($table) + . " WHERE sn=$$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return if $sth->rows != 1; + %row = %{$sth->fetchrow_hashref}; + # Hash the multi-lingual columns + $row{$_} = $row{$_ . "_" . getlang LN_DATABASE} + foreach $DBH->cols_ml($table); + return %row; +} + +return 1; diff --git a/lib/perl5/Selima/Form.pm b/lib/perl5/Selima/Form.pm new file mode 100644 index 0000000..1611078 --- /dev/null +++ b/lib/perl5/Selima/Form.pm @@ -0,0 +1,2657 @@ +# Selima Website Content Management System +# Form.pm: The base form + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-28 + +package Selima::Form; +use 5.008; +use strict; +use warnings; + +use CGI qw(); +use Data::Dumper qw(); +use URI::Escape qw(uri_escape); + +use Selima::A2HTML; +use Selima::Array; +use Selima::CallForm; +use Selima::ChkFunc; +use Selima::CommText; +use Selima::Country; +use Selima::DataVars qw($DBH $SESSION FORM_CAPTCHA :dataman :hostconf :l10n + :lninfo :requri :scptconf :siteconf); +use Selima::FormFunc; +use Selima::Format; +use Selima::GetLang; +use Selima::Guest; +use Selima::HTTP; +use Selima::HTTPS; +use Selima::LnInfo; +use Selima::MarkAbbr; +use Selima::Picture; +use Selima::ShortCut; +use Selima::UserName; + +# Load these classes +use Selima::Form::User; +use Selima::Form::Group; +use Selima::Form::UserMem; +use Selima::Form::GroupMem; +use Selima::Form::UserPref; +use Selima::Form::ScptPriv; + +use Selima::Form::Guestbook; +use Selima::Form::Guestbook::Public; +use Selima::Form::Page; +use Selima::Form::LinkCat; +use Selima::Form::Link; +use Selima::Form::LinkCatz; + +use Selima::Form::Rebuild; + +use Selima::Form::AcctSubj; +use Selima::Form::AcctTrx; +use Selima::Form::AcctRec; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self, $CURFORM, $CALLINGFORM); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + $self = bless {}, $class; + $self->{"status"} = $status; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + # The form type + $self->{"type"} = exists $$args{"type"}? $$args{"type"}: form_type; + # The form type to pass to the handler + if (exists $$args{"type_to_pass"}) { + $self->{"type_to_pass"} = $$args{"type_to_pass"}; + } else { + $self->{"type_to_pass"} = $$args{"type"}; + } + # The allowed form types + $self->{"valid_types"} = exists $$args{"valid_types"}? + $$args{"valid_types"}: [qw(new cur del)]; + # Only new, cur or del is allowed for the form type + http_500 "invalid form type: " . $self->{"type"} + if !in_array($self->{"type"}, @{$self->{"valid_types"}}); + # The form step + $self->{"step"} = $$args{"step"} if exists $$args{"step"}; + # The request ID. + $self->{"req"} = $$args{"req"} if exists $$args{"req"}; + # The managing table + if (exists $$args{"table"}) { + $self->{"table"} = $$args{"table"}; + } elsif (defined $THIS_TABLE) { + $self->{"table"} = $THIS_TABLE; + } + # The current record + $self->{"cur"} = exists $$args{"current"}? $$args{"current"}: + new CGI({%CURRENT}); + $self->{"sn"} = $self->{"cur"}->param("sn") + if defined $self->{"cur"}->param("sn"); + # The submitted form + $self->{"form"} = exists $$args{"form"}? $$args{"form"}: + retrieve_form; + # If we should process with HTTPS/SSL + $self->{"https"} = 0 + if !defined($self->{"https"} = $self->https($args)); + # If the form contains file uploads (multipart/form-data) + $self->{"isupload"} = exists $$args{"isupload"} && $$args{"isupload"}; + # If this record can be deleted + $self->{"nodelete"} = exists $$args{"nodelete"} && $$args{"nodelete"}; + # The prefix message to display before the form + $self->{"prefmsg"} = []; + push @{$self->{"prefmsg"}}, @{$$args{"prefmsg"}} if exists $$args{"prefmsg"}; + # The deletion text + $self->{"deltext"} = exists $$args{"deltext"}? $$args{"deltext"}: + C_("Delete it."); + # The mark + $self->{"mark"} = exists $$args{"mark"}? $$args{"mark"}: + C_("*"); + # The columns to mark + $self->{"markcols"} = $$args{"markcols"} if exists $$args{"markcols"}; + # The prompt message for the marked columns + $self->{"markmsg"} = $$args{"markmsg"} if exists $$args{"markmsg"}; + # The hidden columns + $self->{"hidcols"} = $$args{"hidcols"} if exists $$args{"hidcols"}; + # The buttons to show before and after the form + $self->{"header_buttons"} = $$args{"header_buttons"} + if exists $$args{"header_buttons"}; + $self->{"footer_buttons"} = $$args{"footer_buttons"} + if exists $$args{"footer_buttons"}; + # If we should show the table + $self->{"show_table"} = exists $$args{"show_table"}? + $$args{"show_table"}: 1; + # The table summary + if (exists $$args{"summary"}) { + $self->{"summary"} = $$args{"summary"}; + } else { + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"summary"} = C_("This table provides you a form to add a new data record."); + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"summary"} = C_("This table provides you a form to update a current data record."); + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $self->{"summary"} = C_("This table provides you a form to delete a data record."); + } + } + # The form class + $self->{"class"} = exists $$args{"class"}? $$args{"class"}: "defform"; + # The onsubmit javascript form checker + $self->{"onsubmit"} = exists $$args{"onsubmit"}? + $$args{"onsubmit"}: undef; + # The colspan for each normal cell + $self->{"colspan"} = exists $$args{"colspan"}? $$args{"colspan"}: 1; + # The default input box size + $self->{"defsize"} = exists $$args{"defsize"}? $$args{"defsize"}: 40; + # The process URL + if (exists $$args{"procurl"}) { + $self->{"procurl"} = $$args{"procurl"}; + } elsif ($self->{"https"} && !is_guest) { + if ($VIRTUAL_HOST) { + $self->{"procurl"} = "https://" . https_host . $REQUEST_PATH; + } else { + $self->{"procurl"} = "https://" . https_host . "/" . $PACKAGE . $REQUEST_PATH; + } + } else { + $self->{"procurl"} = $REQUEST_FILE; + } + # The columns to display + if (exists $$args{"cols"}) { + $self->{"cols"} = $$args{"cols"}; + } elsif (exists $self->{"table"}) { + $self->{"cols"} = [$DBH->cols($self->{"table"})]; + } + # Should we automatically keep our HTTP_REFERER + $self->{"auto_referer2"} = exists $$args{"auto_referer2"}? + $$args{"auto_referer2"}: 1; + # The title + if (exists $$args{"title"}) { + $self->{"title"} = $$args{"title"}; + } else { + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"title"} = C_("Add a New Data Record"); + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"title"} = C_("Update a Current Data Record"); + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $self->{"title"} = C_("Delete a Data Record"); + } + } + # The caller form and form ID + $CURFORM = curform; + if ( exists $$args{"caller"} + && exists $$args{"cformid"}) { + $self->{"is_called_form"} = 1; + $self->{"caller"} = $$args{"caller"}; + $self->{"cformid"} = $$args{"cformid"}; + } elsif ( defined $CURFORM->param("caller") + && defined $CURFORM->param("cformid")) { + $self->{"is_called_form"} = 1; + $self->{"caller"} = $CURFORM->param("caller"); + $self->{"cformid"} = $CURFORM->param("cformid"); + } else { + $self->{"is_called_form"} = 0; + } + # The preview link + $self->{"preview"} = exists $$args{"preview"}? $$args{"preview"}: 0; + $self->{"prevmsg"} = exists $$args{"prevmsg"}? $$args{"prevmsg"}: + C_("Preview it.") + if $$args{"preview"}; + + # Initialize the first form + $self->{"is_first_form"} = 0; + if (scalar(@_ = $self->{"form"}->param) == 0) { + $self->{"is_first_form"} = 1; + # ...with the current item + eval Data::Dumper->Dump([$self->{"cur"}], [qw($self->{"form"})]) + if $self->{"type"} eq "cur"; + } + if (exists $self->{"table"}) { + $self->{"mlcols"} = [$DBH->cols_ml($self->{"table"})]; + $self->{"maxlens"} = {$DBH->col_lens($self->{"table"})}; + } + + # Check if each column is available + foreach (@{$self->{"cols"}}) { + http_500 "invalid table column \"$_\"" + if !$self->can("_html_col_$_"); + } + + # Set the referer2 (the place to return when finishing the form) + if ($self->{"is_called_form"}) { + # Referer specified + $CALLINGFORM = retrieve_form($self->{"cformid"}); + $self->{"referer2"} = $CALLINGFORM->param("referer2") + if defined $CALLINGFORM->param("referer2"); + # First form + } elsif ($self->{"is_first_form"}) { + # Referer specified + if (defined $CURFORM->param("referer")) { + $self->{"referer2"} = $CURFORM->param("referer"); + # Keep the source referer + } elsif ( $self->{"auto_referer2"} + && exists $ENV{"HTTP_REFERER"} + && substr($ENV{"HTTP_REFERER"}, 0, length($REQUEST_HOSTPORT)+1) eq $REQUEST_HOSTPORT . "/") { + $self->{"referer2"} = $ENV{"HTTP_REFERER"}; + } + # A subsequent form + } else { + # Maintain the previous referer2 + $self->{"referer2"} = $self->{"form"}->param("referer2") + if defined $self->{"form"}->param("referer2"); + } + + # The prefix of where to return after form is processed + # No need to have it if we have a proper referer2 to return to + $self->{"hostport"} = $REQUEST_HOSTPORT + if !exists $self->{"referer2"} && $self->{"https"}; + + # Check if Chinese synchronization is available + %_ = map { $_ => 1 } @ALL_LINGUAS; + $_ = getlang; + $self->{"zhsync"} = 0; + if ( exists $self->{"table"} + && $DBH->is_ml_table($self->{"table"}) + && $_ ne $DEFAULT_LANG) { + if ($_ eq "zh-tw" && exists $_{"zh-cn"}) { + $self->{"zhsync"} = h_abbr(C_("Convert from Simplified Chinese")); + } elsif ($_ eq "zh-cn" && exists $_{"zh-tw"}) { + $self->{"zhsync"} = h_abbr(C_("Convert from Traditional Chinese")); + } + } + + %_ = map { $_ => 1 } @ALL_LINGUAS; + $_ = getlang; + $self->{"zhsync"} = 0; + if ( exists $self->{"table"} + && $DBH->is_ml_table($self->{"table"}) + && $_ ne $DEFAULT_LANG) { + if ($_ eq "zh-tw" && exists $_{"zh-cn"}) { + $self->{"zhsync"} = h_abbr(C_("Convert from Simplified Chinese")); + } elsif ($_ eq "zh-cn" && exists $_{"zh-tw"}) { + $self->{"zhsync"} = h_abbr(C_("Convert from Traditional Chinese")); + } + } + + return $self; +} + +# html: Display the HTML form table +sub html : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Display the preview_link + $self->_html_preview_link; + # Display the form header + $self->_html_form_header; + + # Display the table + # Display the table header + $self->_html_table_header + if $self->{"show_table"}; + # Display each column + &{$self->can("_html_col_$_")}($self) foreach @{$self->{"cols"}}; + # Display the table footer + $self->_html_table_footer + if $self->{"show_table"}; + + # Display the form footer + $self->_html_form_footer; + return; +} + +# https: If we should process with HTTPS/SSL +sub https : method { + local ($_, %_); + my ($self, $args, $FORM); + ($self, $args) = @_; + # Checked before + return $self->{"https"} if exists $self->{"https"}; + # Already in HTTPS + return ($self->{"https"} = 0) if is_https; + # HTTPS specified + return $self->{"https"} = ($$args{"https"}? 1: 0) + if defined $args && exists $$args{"https"} && defined $$args{"https"}; + # Specified in the current form + $FORM = curform; + return ($self->{"https"} = 1) + if defined $FORM->param("https") && $FORM->param("https"); + # Specified in the GET or POST arguments + $FORM = get_or_post; + return ($self->{"https"} = 1) + if defined $FORM->param("https") && $FORM->param("https"); + # Unable to decide it + return undef; +} + + +################### +# Methods below are private. Do not call them directly. +################### +################### +# Basic form elements +################### +# _html_preview_link: Display the preview_link +sub _html_preview_link : method { + local ($_, %_); + my ($self, $form, $url, $msg); + $self = $_[0]; + $form = $self->{"form"}; + # Bounce when preview is not available for this form + return if !$self->{"preview"}; + # No preview on forms that cannot be previewed + if (defined $self->{"status"}) { + return unless exists ${$self->{"status"}}{"preview"} + && ${$self->{"status"}}{"preview"}; + } + + @_ = qw(); + push @_, "form=preview"; + # A form to create a new item + if ($self->{"type"} eq "new") { + # No preview for the first blank form + if ($self->{"is_first_form"}) { + return; + } else { + push @_, "sn=" . $form->param("formid"); + } + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + # Make a suspended form and get the form ID. + if ($self->{"is_first_form"}) { + push @_, "sn=" . $self->{"sn"}; + push @_, "source=db"; + } else { + push @_, "sn=" . $form->param("formid"); + } + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + # No preview for the deletion form + return; + } + $url = h($REQUEST_FILE . "?" . join "&", @_); + $msg = h_abbr($self->{"prevmsg"}); + print << "EOT"; +

    $msg

    + +EOT + return; +} + +# _html_form_header: Display the form header +sub _html_form_header : method { + local ($_, %_); + my ($self, $class, $url, $enctype, $onsubmit, $meta); + $self = $_[0]; + $class = defined $self->{"class"}? + " class=\"" . h($self->{"class"}) . "\"": ""; + $url = h($self->{"procurl"}); + $enctype = $self->{"isupload"}? " enctype=\"multipart/form-data\"": ""; + $onsubmit = defined $self->{"onsubmit"}? + " onsubmit=\"" . h($self->{"onsubmit"}) . "\"": ""; + + # The meta form information + $meta = Selima::Form::MetaCols->new; + $meta->add("hidden", "lang", getlang); + $meta->add("hidden", "charset", undef); + $meta->add("hidden", "form", $self->{"type_to_pass"}) + if defined $self->{"type_to_pass"}; + $meta->add("hidden", "step", $self->{"step"}) + if exists $self->{"step"}; + $meta->add("hidden", "sn", $self->{"sn"}) + if exists $self->{"sn"}; + $meta->add("hidden", "req", $self->{"req"}) + if exists $self->{"req"}; + if ($self->{"is_called_form"}) { + $meta->add("hidden", "caller", $self->{"caller"}); + $meta->add("hidden", "cformid", $self->{"cformid"}); + } + if ($self->{"https"}) { + $meta->add("hidden", "https", 1); + $meta->add("hidden", "referer", $REQUEST_HOSTPATH); + $meta->add("hidden", $$SESSION{".meta"}->{"name"}, + $$SESSION{".meta"}->{"id"}); + } + if (exists $self->{"referer2"}) { + $meta->add("hidden", "referer2", $self->{"referer2"}); + } elsif (exists $self->{"hostport"}) { + $meta->add("hidden", "hostport", $self->{"hostport"}); + } + if (exists $self->{"hidcols"}) { + $meta->add("hidden", $$_{"name"}, $$_{"value"}) + foreach @{$self->{"hidcols"}}; + } + + # The submit buttons + if (exists $self->{"header_buttons"}) { + $meta->add("submit", $$_{"name"}, $$_{"value"}) + foreach @{$self->{"header_buttons"}}; + } else { + # A form to create a new item + if ($self->{"type"} eq "new") { + $meta->add("submit", undef, C_("Submit")); + $meta->add("submit", "confirm", C_("Save")); + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $meta->add("submit", undef, C_("Submit")); + $meta->add("submit", "confirm", C_("Save")); + $meta->add("submit", "zhsync", $self->{"zhsync"}) + if $self->{"zhsync"}; + $meta->add("submit", "del", $self->{"deltext"}) + unless $self->{"nodelete"}; + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + } + } + + # Output the form header + print << "EOT"; + +EOT + # Display the prompt for the marked columns + $self->_html_mark_prompt; + # Display the prefix message + $self->_html_prefix_message; + print << "EOT"; +
    +EOT + # Output the meta form information + $meta->out; + return; +} + +# _html_mark_prompt: Display the prompt for the marked columns +sub _html_mark_prompt : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Bounce when there is no prompt message or no mark to use + return if !exists $self->{"markmsg"} || !defined $self->{"mark"}; + $_ = printf $self->{"markmsg"}, $self->{"mark"}; + print << "EOT"; +

    $_

    + +EOT + return; +} + +# _html_prefix_message: Display the prefix message +sub _html_prefix_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Bounce when there is no prefix message + foreach my $msg (@{$self->{"prefmsg"}}) { + $_ = h_abbr($msg); + print << "EOT"; +

    $_

    + +EOT + } + return; +} + +# _html_table_header: Display the table header +sub _html_table_header : method { + local ($_, %_); + my ($self, $cols, $summary); + $self = $_[0]; + # Output the table header + $cols = ""; + $cols .= "" if $self->{"type"} eq "cur"; + for ($_ = 0; $_ < $self->{"colspan"}; $_++) { + $cols .= ""; + } + $summary = h_abbr($self->{"summary"}); + print << "EOT"; + +$cols + +EOT + + return; +} + +# _html_table_footer: Display the table footer +sub _html_table_footer : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Output the table footer + print << "EOT"; + +
    +EOT + return; +} + +# _html_form_footer: Display the form footer +sub _html_form_footer : method { + local ($_, %_); + my ($self, $meta, $msg); + $self = $_[0]; + + # The meta form information + $meta = Selima::Form::MetaCols->new; + # The submit buttons + if (exists $self->{"footer_buttons"}) { + $meta->add("submit", $$_{"name"}, $$_{"value"}) + foreach @{$self->{"footer_buttons"}}; + } else { + # A form to create a new item + if ($self->{"type"} eq "new") { + $meta->add("submit", undef, C_("Submit")); + $meta->add("submit", "confirm", C_("Save")); + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $meta->add("submit", undef, C_("Submit")); + $meta->add("submit", "confirm", C_("Save")); + $meta->add("submit", "zhsync", $self->{"zhsync"}) + if $self->{"zhsync"}; + $meta->add("submit", "del", $self->{"deltext"}) + unless $self->{"nodelete"}; + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $meta->add("submit", "confirm", C_("Delete")); + $meta->add("submit", "cancel", C_("Cancel")); + } + } + + # Output the deletion warning + print "

    " . h_abbr(C_("Are you sure you want to delete this data? You cannot recover it if you do so.")) . "

    \n" + if $self->{"type"} eq "del"; + # Output the meta form information + $meta->out; + # Output the form footer + print << "EOT"; +
    + + +EOT + return; +} + + +################### +# Column templates +################### +# _html_coltmpl_ro: Display a read-only normal column +sub _html_coltmpl_ro : method { + local ($_, %_); + my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); + ($self, $col, $label, $prompt) = @_; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $cur = $self->_cval_text($col); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label + $cur$prompt + +EOT + return; +} + +# _html_coltmpl_ro_textarea: Display a read-only textarea column +sub _html_coltmpl_ro_textarea : method { + local ($_, %_); + my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); + ($self, $col, $label, $prompt) = @_; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $cur = $self->_cval_textarea($col); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label + $cur$prompt + +EOT + return; +} + +# _html_coltmpl_ro_bool: Display a read-only boolean column +sub _html_coltmpl_ro_bool : method { + local ($_, %_); + my ($self, $col, $label, $true, $false, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); + ($self, $col, $label, $true, $false, $prompt) = @_; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $cur = $self->{"cur"}->param($col)? $true: $false; + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label + $cur$prompt + +EOT + return; +} + +# _html_coltmpl_ro_user: Display a read-only user column +sub _html_coltmpl_ro_user : method { + local ($_, %_); + my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); + ($self, $col, $label, $prompt) = @_; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $cur = h_abbr(username scalar $self->{"cur"}->param($col)); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label + $cur$prompt + +EOT + return; +} + +# _html_coltmpl_ro_date: Display a read-only date column +sub _html_coltmpl_ro_date : method { + local ($_, %_); + my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); + ($self, $col, $label, $prompt) = @_; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $cur = defined $self->{"cur"}->param($col)? + h_abbr(fmtdate $self->{"cur"}->param($col)): h_abbr(t_none); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label + $cur$prompt + +EOT + return; +} + +# _html_coltmpl_ro_datetime: Display a read-only date-time column +sub _html_coltmpl_ro_datetime : method { + local ($_, %_); + my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); + ($self, $col, $label, $prompt) = @_; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $cur = defined $self->{"cur"}->param($col)? + h_abbr(fmttime $self->{"cur"}->param($col)): h_abbr(t_none); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label + $cur$prompt + +EOT + return; +} + +# _html_coltmpl_ro_lang: Display a read-only language column +sub _html_coltmpl_ro_lang : method { + local ($_, %_); + my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); + ($self, $col, $label, $prompt) = @_; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $cur = defined $self->{"cur"}->param($col)? + h_abbr(ln $self->{"cur"}->param($col), LN_DESC_CURLC): h_abbr(t_none); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label + $cur$prompt + +EOT + return; +} + +# _html_coltmpl_ro_ct: Display a read-only country column +sub _html_coltmpl_ro_ct : method { + local ($_, %_); + my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); + ($self, $col, $label, $prompt) = @_; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $cur = h_abbr(ctname $self->{"cur"}->param($col)); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label + $cur$prompt + +EOT + return; +} + +# _html_coltmpl_ro_title: Display a read-only column with a title function +sub _html_coltmpl_ro_title : method { + local ($_, %_); + my ($self, $col, $label, $titlefunc, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); + ($self, $col, $label, $titlefunc, $prompt) = @_; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $cur = h(&$titlefunc($self->{"cur"}->param($col))); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label + $cur$prompt + +EOT + return; +} + +# _html_coltmpl_ro_radio: Display a read-only column with a option list +sub _html_coltmpl_ro_radio : method { + local ($_, %_); + my ($self, $col, $label, $opts, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); + ($self, $col, $label, $opts, $prompt) = @_; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $cur = $$opts{grep $self->{"cur"}->param($col) eq $_, keys %$opts}; + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label + $cur$prompt + +EOT + return; +} + +# _html_coltmpl_text: Display a text column +sub _html_coltmpl_text : method { + local ($_, %_); + my ($self, $col, $label, $prompt, $size, $class, $mark, $colspan); + my ($cur, $val, $orig, $new); + ($self, $col, $label, $prompt, $size) = @_; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $class = defined $size? "": " class=\"text\""; + $size = h($self->{"defsize"}) if !defined $size; + + # A form to create a new item + if ($self->{"type"} eq "new") { + $val = $self->_val_text($col, $col); + $col = h($col); + print << "EOT"; + + + $prompt + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $cur = $self->_cval_text($col); + $val = $self->_val_text($col, $col); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + # A multi-lingual column, that is not in the default language + if (in_array($col, @{$self->{"mlcols"}}) && getlang ne $DEFAULT_LANG) { + my ($srclabel, $srccur); + $srclabel = h_abbr(C_("Source:")); + $_ = $col . "_" . ln($DEFAULT_LANG, LN_DATABASE); + $srccur = $self->_cval_text($_); + $col = h($col); + print << "EOT"; + + + $srclabel + $srccur + + + $orig + $cur + + + + $prompt + +EOT + + # A uni-lingual column + } else { + $col = h($col); + print << "EOT"; + + + $orig + $cur + + + + $prompt + +EOT + } + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $cur = $self->_cval_text($col); + print << "EOT"; + + $mark$label + $cur + +EOT + } + return; +} + +# _html_coltmpl_text_null: Display a nullable text column +sub _html_coltmpl_text_null : method { + local ($_, %_); + my ($self, $col, $label, $nullcol, $nulllabel, $prompt, $size, $class, $mark, $colspan); + my ($form, $cur, $val, $orig, $new, $valfalse, $valtrue); + ($self, $col, $label, $nullcol, $nulllabel, $prompt, $size) = @_; + $form = $self->{"form"}; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $class = defined $size? "": " class=\"textnull\""; + $size = h($self->{"defsize"}) if !defined $size; + + # A form to create a new item + if ($self->{"type"} eq "new") { + $valfalse = $self->_val_radio($nullcol, "false"); + $valtrue = $self->_val_radio($nullcol, "true"); + $val = $self->_val_text($col, $col); + $col = h($col); + $nullcol = h($nullcol); + print << "EOT"; + + + + $prompt
    + + + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $form->param($nullcol, !defined $form->param($col)? "true": "false") + if $self->{"is_first_form"}; + $valfalse = $self->_val_radio($nullcol, "false"); + $valtrue = $self->_val_radio($nullcol, "true"); + $val = $self->_val_text($col, $col); + $cur = defined $self->{"cur"}->param($col)? + h($self->{"cur"}->param($col)): $nulllabel; + $col = h($col); + $nullcol = h($nullcol); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + print << "EOT"; + + + $orig + $cur + + + + + $prompt
    + + + +EOT + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $cur = defined $self->{"cur"}->param($col)? + h($self->{"cur"}->param($col)): $nulllabel; + print << "EOT"; + + $mark$label + $cur + +EOT + } + return; +} + +# _html_coltmpl_textarea: Display a textarea column +sub _html_coltmpl_textarea : method { + local ($_, %_); + my ($self, $col, $label, $default, $prompt, $rows, $cols, $mark, $colspan, $hdef); + my ($cur, $val, $orig, $new); + ($self, $col, $label, $default, $prompt, $rows, $cols) = @_; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $cols = h($self->{"defsize"}) if !defined $cols; + $rows = h(10) if !defined $rows; + + # A form to create a new item + if ($self->{"type"} eq "new") { + $val = $self->_val_textarea($col, $default); + $hdef = h($default); + $col = h($col); + print << "EOT"; + + + $prompt + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $cur = $self->_cval_textarea($col); + $val = $self->_val_textarea($col, $default); + $hdef = h($default); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + # A multi-lingual column, that is not in the default language + if (in_array($col, @{$self->{"mlcols"}}) && getlang ne $DEFAULT_LANG) { + my ($srclabel, $srccur); + $srclabel = h_abbr(C_("Source:")); + $_ = $col . "_" . ln($DEFAULT_LANG, LN_DATABASE); + $srccur = $self->_cval_textarea($_); + $col = h($col); + print << "EOT"; + + + $srclabel + $srccur + + + $orig + $cur + + + + $prompt + +EOT + + # A uni-lingual column + } else { + $col = h($col); + print << "EOT"; + + + $orig + $cur + + + + $prompt + +EOT + } + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $cur = $self->_cval_textarea($col); + print << "EOT"; + + $mark$label + $cur + +EOT + } + return; +} + +# _html_coltmpl_bool: Display a boolean column +sub _html_coltmpl_bool : method { + local ($_, %_); + my ($self, $col, $label, $true, $false, $text, $prompt, $mark, $colspan); + my ($cur, $val, $orig, $new); + ($self, $col, $label, $true, $false, $text, $prompt) = @_; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + + # A form to create a new item + if ($self->{"type"} eq "new") { + $val = $self->_val_check($col); + $col = h($col); + print << "EOT"; + + + + $prompt + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $cur = $self->{"cur"}->param($col)? $true: $false; + $val = $self->_val_check($col); + $col = h($col); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + print << "EOT"; + + + $orig + $cur + + + + + $prompt + +EOT + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $cur = $self->{"cur"}->param($col)? $true: $false; + print << "EOT"; + + $mark$label + $cur + +EOT + } + return; +} + +# _html_coltmpl_call: The call selection column +sub _html_coltmpl_call : method { + local ($_, %_); + my ($self, $col, $label, $titlefunc, $prompt, $mark, $colspan); + my ($form, $cur, $val, $orig, $new); + my ($vallabel, $choose, $delete); + ($self, $col, $label, $titlefunc, $prompt) = @_; + $self = $_[0]; + $form = $self->{"form"}; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $choose = h_abbr(C_("Choose")); + $delete = h_abbr(C_("Delete")); + # "" means not selected yet + $form->delete($col) + if defined $form->param($col) && $form->param($col) eq ""; + + # A form to create a new item + if ($self->{"type"} eq "new") { + $val = $self->_val_text($col); + $vallabel = h(&$titlefunc($form->param($col))); + $col = h($col); + print << "EOT"; + + + +EOT + if (defined $form->param($col)) { + print << "EOT"; + +EOT + } else { + print << "EOT"; + +EOT + } + print << "EOT"; + $prompt + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $val = $self->_val_text($col); + $vallabel = h(&$titlefunc($form->param($col))); + $cur = h(&$titlefunc($self->{"cur"}->param($col))); + $col = h($col); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + print << "EOT"; + + + $orig + $cur + + + + +EOT + if (defined $form->param($col)) { + print << "EOT"; + +EOT + } else { + print << "EOT"; + +EOT + } + print << "EOT"; + $prompt + +EOT + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $cur = h(&$titlefunc($self->{"cur"}->param($col))); + print << "EOT"; + + $mark$label + $cur + +EOT + } + return; +} + +# _html_coltmpl_call_null: The nullable call selection column +sub _html_coltmpl_call_null : method { + local ($_, %_); + my ($self, $col, $label, $nullcol, $nulllabel, $titlefunc, $prompt, $mark, $colspan); + my ($form, $cur, $val, $orig, $new, $valfalse, $valtrue); + my ($vallabel, $choose, $delete); + ($self, $col, $label, $nullcol, $nulllabel, $titlefunc, $prompt) = @_; + $self = $_[0]; + $form = $self->{"form"}; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $choose = h_abbr(C_("Choose")); + $delete = h_abbr(C_("Delete")); + # "" means not selected yet + $form->delete($col) + if defined $form->param($col) && $form->param($col) eq ""; + + # A form to create a new item + if ($self->{"type"} eq "new") { + $valfalse = $self->_val_radio($nullcol, "false"); + $valtrue = $self->_val_radio($nullcol, "true"); + $val = $self->_val_text($col); + $vallabel = h(&$titlefunc($form->param($col))); + $col = h($col); + $nullcol = h($nullcol); + print << "EOT"; + + +
      +
    • + +EOT + if (defined $form->param($col)) { + print << "EOT"; + +EOT + } else { + print << "EOT"; + +EOT + } + print << "EOT"; + +
    • +
    • + +
    • +
    + $prompt + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $form->param($nullcol, !defined $form->param($col)? "true": "false") + if $self->{"is_first_form"}; + $valfalse = $self->_val_radio($nullcol, "false"); + $valtrue = $self->_val_radio($nullcol, "true"); + $val = $self->_val_text($col); + $vallabel = h(&$titlefunc($form->param($col))); + $cur = defined $self->{"cur"}->param($col)? + h(&$titlefunc($self->{"cur"}->param($col))): $nulllabel; + $col = h($col); + $nullcol = h($nullcol); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + print << "EOT"; + + + $orig + $cur + + + +
      +
    • + +EOT + if (defined $form->param($col)) { + print << "EOT"; + +EOT + } else { + print << "EOT"; + +EOT + } + print << "EOT"; + +
    • +
    • + +
    • +
    + $prompt + +EOT + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $cur = defined $self->{"cur"}->param($col)? + h(&$titlefunc($self->{"cur"}->param($col))): $nulllabel; + print << "EOT"; + + $mark$label + $cur + +EOT + } + return; +} + +# _html_coltmpl_select: The selection column +sub _html_coltmpl_select : method { + local ($_, %_); + my ($self, $form, $current, $col, $label, $optfunc, $titlefunc, $prompt, $mark, $colspan); + my ($cur, $orig, $new); + ($self, $col, $label, $optfunc, $titlefunc, $prompt) = @_; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + + # A form to create a new item + if ($self->{"type"} eq "new") { + $col = h($col); + print << "EOT"; + + + $prompt + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $cur = h(&$titlefunc($self->{"cur"}->param($col))); + $col = h($col); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + print << "EOT"; + + + $orig + $cur + + + + $prompt + +EOT + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $cur = h(&$titlefunc($self->{"cur"}->param($col))); + print << "EOT"; + + $mark$label + $cur + +EOT + } +} + +# _html_coltmpl_select_multi: The multiple selection column +sub _html_coltmpl_select_multi : method { + local ($_, %_); + my ($self, $form, $current, $col, $label, $optfunc, $prompt, $mark, $colspan); + my ($orig, $new, $count, $col0, $col_); + ($self, $col, $label, $optfunc, $prompt) = @_; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + + # Find the last used category index, and append 3 blank selections + for ($_ = 0; defined $form->param("$col$_"); $_++) { }; + for ($_--; $_ >= 0 && $form->param("$col$_") eq ""; $_--) { }; + $count = $_ + 3; + + # A form to create a new item + if ($self->{"type"} eq "new") { + $col0 = h($col . "0"); + print << "EOT"; + + +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ <= $count; $_++) { + $col_ = h($col . $_); + push @_, "
  • \n" + . "
  • \n"; + } + print "
      \n" . join("", @_) . "
    \n "; + print << "EOT"; +$prompt + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $col0 = h($col . "0"); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + print << "EOT"; + + + $orig +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("$col" . "count"); $_++) { + push @_, "
  • " . h($current->param("$col$_" . "title")) . "
  • \n"; + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + + + +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ <= $count; $_++) { + $col_ = h($col . $_); + push @_, "
  • \n" + . "
  • \n"; + } + print "
      \n" . join("", @_) . "
    \n "; + print << "EOT"; +$prompt + +EOT + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("$col" . "count"); $_++) { + push @_, "
  • " . h($current->param("$col$_" . "title")) . "
  • \n"; + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT + } +} + +# _html_coltmpl_radio: The radio column +sub _html_coltmpl_radio : method { + local ($_, %_); + my ($self, $form, $current, $col, $label, $opts, $prompt, $oneline, $mark, $colspan); + my ($orig, $new, $coldef, $found); + ($self, $col, $label, $opts, $prompt, $oneline) = @_; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $oneline = 0 if !defined $oneline; + $oneline = $oneline? " class=\"oneline\"": ""; + + # A form to create a new item + if ($self->{"type"} eq "new") { + $coldef = $col . (exists ${$$opts[0]}{"id"}? ${$$opts[0]}{"id"}: + ${$$opts[0]}{"val"}); + print << "EOT"; + + +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < @$opts; $_++) { + my $id; + $id = $col . (exists ${$$opts[$_]}{"id"}? ${$$opts[$_]}{"id"}: + ${$$opts[$_]}{"val"}); + push @_, sprintf("
  • \n" + . "
  • \n" + . "
  • \n" + . " \n" + . " %5\$s\n" + . "
  • \n", + h($col), h($_), $self->_val_text("$col$_" . "sn"), + $self->_val_check("$col$_"), + h_abbr(&$titlefunc($form->param("$col$_" . "sn")))); + } else { + push @_, sprintf( + "
  • \n" + . " \n" + . " %5\$s\n" + . "
  • \n", + h($col), h($_), $self->_val_text("$col$_" . "sn"), + $self->_val_check("$col$_"), h_abbr(t_na)); + } + } + print "\n" . join("", @_) . " \n" + . " $prompt"; + print << "EOT"; + + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $colfree = $col . "free"; + $valfree = $self->_val_text($colfree, $colfree); + $colfree = h($colfree); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + print << "EOT"; + + + $orig +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param($col . "count"); $_++) { + push @_, $self->_cval_text("$col$_" . "title"); + } + print @_ > 0? join(", ", @_): h_abbr(t_none); + print << "EOT"; + + + + +EOT + print " "; + for ($_ = 0, @_ = qw(); defined $form->param("$col$_" . "sn"); $_++) { + if (check_sn_in ${$form->param_fetch("$col$_" . "sn")}[0], $table) { + push @_, sprintf( + "
  • \n" + . " \n" + . " %5\$s\n" + . "
  • \n", + h($col), h($_), $self->_val_text("$col$_" . "sn"), + $self->_val_check("$col$_"), + h_abbr(&$titlefunc($form->param("$col$_" . "sn")))); + } else { + push @_, sprintf( + "
  • \n" + . " \n" + . " %5\$s\n" + . "
  • \n", + h($col), h($_), $self->_val_text("$col$_" . "sn"), + $self->_val_check("$col$_"), h_abbr(t_na)); + } + } + print "\n" . join("", @_) . " \n" + . " $prompt"; + print << "EOT"; + + +EOT + + # A form to delete a current item + } else { + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param($col . "count"); $_++) { + push @_, $self->_cval_text("$col$_" . "title"); + } + print @_ > 0? join(", ", @_): h_abbr(t_none); + print << "EOT"; + + +EOT + } + return; +} + +# _html_coltmpl_date: Display a date column +sub _html_coltmpl_date : method { + local ($_, %_); + my ($self, $form, $col, $label, $prompt, $size, $mark, $colspan); + my ($cur, $val, $orig, $new); + ($self, $col, $label, $prompt, $size) = @_; + $form = $self->{"form"}; + $mark = $self->_mark($col); + $colspan = $self->_colspan; + $prompt = !defined $prompt? "": + "\n

    " . h_abbr($prompt) . "

    \n "; + $size = h(10) if !defined $size; + + # A form to create a new item + if ($self->{"type"} eq "new") { + # Set the default date to today + $form->param($col, time) if $self->{"is_first_form"}; + $val = $self->_val_date($col, $col); + $col = h($col); + print << "EOT"; + + + $prompt + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $cur = defined $self->{"cur"}->param($col)? + h(fmtdate $self->{"cur"}->param($col)): h_abbr(t_none); + $val = $self->_val_date($col, $col); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + # A multi-lingual column, that is not in the default language + if (in_array($col, @{$self->{"mlcols"}}) && getlang ne $DEFAULT_LANG) { + my ($srclabel, $srccur); + $srclabel = h_abbr(C_("Source:")); + $_ = $col . "_" . ln($DEFAULT_LANG, LN_DATABASE); + $srccur = defined $self->{"cur"}->param($_)? + h($self->{"cur"}->param($_)): h_abbr(t_none); + $col = h($col); + print << "EOT"; + + + $srclabel + $srccur + + + $orig + $cur + + + + $prompt + +EOT + + # A uni-lingual column + } else { + $col = h($col); + print << "EOT"; + + + $orig + $cur + + + + $prompt + +EOT + } + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $cur = defined $self->{"cur"}->param($col)? + h(fmtdate $self->{"cur"}->param($col)): h_abbr(t_none); + print << "EOT"; + + $mark$label + $cur + +EOT + } + return; +} + +# _html_coltmpl_url: The URL column +sub _html_coltmpl_url : method { + $_[0]->{"form"}->param($_[1], "http://") + if $_[0]->{"is_first_form"} && !defined $_[0]->{"form"}->param($_[1]); + $_[0]->_html_coltmpl_text($_[1], $_[2], $_[3], $_[4]); +} + + +################### +# Columns, sorted alphabetically +################### +# _html_col_addr: The address +sub _html_col_addr : method { + $_[0]->_html_coltmpl_text("addr", h_abbr(C_("Address:"))); +} + +# _html_col_author: The author +sub _html_col_author : method { + $_[0]->_html_coltmpl_text("author", h_abbr(C_("Author:"))); +} + +# _html_col_body: The content body +sub _html_col_body : method { + $_[0]->_html_coltmpl_textarea("body", h_abbr(C_("Content:")), + h_abbr(C_("Fill in the content here."))); +} + +# _html_col_captcha: The CAPTCHA (human test) +# Add a field that is not displayed and should be empty to trap spam +# See: http://www.hockinson.com/programmer-web-designer-denver-co-usa.php?s=44 +sub _html_col_captcha : method { + local ($_, %_); + my ($self, $col, $label, $prompt, $size, $class, $mark, $colspan); + my ($thclass, $thcolspan); + $self = $_[0]; + $mark = $self->_mark("captcha"); + $col = FORM_CAPTCHA; + $label = h_abbr(C_("Current Website:")); + $size = h($self->{"defsize"}); + $class = " class=\"text\""; + $colspan = $self->_colspan; + $prompt = "\n

    " + . h_abbr(C_("Enter your website URL here.")) . "

    \n "; + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + + $prompt + +EOT + return; +} + +# _html_col_created: The creation time +sub _html_col_created : method { + $_[0]->_html_coltmpl_ro_datetime("created", h_abbr(C_("Created:"))); +} + +# _html_col_createdby: The creator +sub _html_col_createdby : method { + $_[0]->_html_coltmpl_ro_user("createdby", h_abbr(C_("Created by:"))); +} + +# _html_col_disabled: Disabled? +sub _html_col_disabled : method { + $_[0]->_html_coltmpl_bool("email", h_abbr(C_("Disabled?")), + h_abbr(C_("Disabled")), h_abbr(C_("Enabled")), h_abbr(C_("Disable it."))); +} + +# _html_col_date: The date +sub _html_col_date : method { + $_[0]->_html_coltmpl_date("date", C_("Date:")); +} + +# _html_col_dsc: The description +sub _html_col_dsc : method { + $_[0]->_html_coltmpl_textarea("dsc", h_abbr(C_("Description:")), + h_abbr(C_("Fill in the description here.")), undef, 4); +} + +# _html_col_email: The e-mail +sub _html_col_email : method { + $_[0]->_html_coltmpl_text("email", h_abbr(C_("E-mail:"))); +} + +# _html_col_fax: The facsimile number +sub _html_col_fax : method { + $_[0]->_html_coltmpl_text("fax", h_abbr(C_("Fax.:"))); +} + +# _html_col_grp: The group +sub _html_col_grp : method { + $_[0]->_html_coltmpl_call("grp", h_abbr(C_("Group:")), \&groupdsc); +} + +# _html_col_hid: Hide? +sub _html_col_hid : method { + $_[0]->_html_coltmpl_bool("hid", h_abbr(C_("Hide?")), + h_abbr(C_("Hide it")), h_abbr(C_("Show it")), h_abbr(C_("Hide it currently."))); +} + +# _html_col_html: HTML? +sub _html_col_html : method { + $_[0]->_html_coltmpl_bool("html", h_abbr(C_("HTML?")), + h_abbr(C_("HTML")), h_abbr(C_("Plain text")), h_abbr(C_("The submitted content is HTML."))); +} + +# _html_col_host: The hostname +sub _html_col_host : method { + $_[0]->_html_coltmpl_ro("host", h_abbr(C_("Host:"))); +} + +# _html_col_id: The ID. +sub _html_col_id : method { + $_[0]->_html_coltmpl_text("id", h_abbr(C_("ID.:"))); +} + +# _html_col_identity: The Identity +sub _html_col_identity : method { + $_[0]->_html_coltmpl_text("identity", h_abbr(C_("Identity:"))); +} + +# _html_col_intro: The introduction +sub _html_col_intro : method { + $_[0]->_html_coltmpl_textarea("intro", h_abbr(C_("Introduction:")), + h_abbr(C_("Fill in the introduction here.")), undef, 4); +} + +# _html_col_ip: The IP +sub _html_col_ip : method { + $_[0]->_html_coltmpl_ro("ip", h_abbr(C_("IP:"))); +} + +# _html_col_kw: The keywords list +sub _html_col_kw : method { + $_[0]->_html_coltmpl_text("kw", h_abbr(C_("Keywords:"))); +} + +# _html_col_lang: The language +sub _html_col_lang : method { + $_[0]->_html_coltmpl_ro_lang("lang", h_abbr(C_("Language:"))); +} + +# _html_col_location: The location +sub _html_col_location : method { + $_[0]->_html_coltmpl_text("location", h_abbr(C_("Location:"))); +} + +# _html_col_message: The message +sub _html_col_message : method { + $_[0]->_html_coltmpl_textarea("message", h_abbr(C_("Message:")), + h_abbr(C_("Fill in the message here."))); +} + +# _html_col_name: The name +sub _html_col_name : method { + $_[0]->_html_coltmpl_text("name", h_abbr(C_("Name:"))); +} + +# _html_col_ord: The order +sub _html_col_ord : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Set the default order to the half of the maximum + $form->param("ord", (10 ** ${$self->{"maxlens"}}{"ord"}) / 2) + if $self->{"is_first_form"} && $self->{"type"} eq "new"; + $self->_html_coltmpl_text("ord", h_abbr(C_("Order:")), undef, + ${$self->{"maxlens"}}{"ord"}); +} + +# _html_col_parent: The parent +sub _html_col_parent : method { + $_[0]->_html_coltmpl_call_null("parent", h_abbr(C_("Parent category:")), + "topmost", h_abbr(C_("At the very top")), $MAIN->can($_[0]->{"table"} . "_title")); +} + +# _html_col_passwd: The password +sub _html_col_passwd : method { + local ($_, %_); + my ($self, $label, $label2, $dummy, $val, $val_id, $passid, $mark, $colspan); + my ($orig, $new, $size); + $self = $_[0]; + $mark = $self->_mark("passwd"); + $colspan = $self->_colspan; + $size = h($self->{"defsize"}); + $label = h_abbr(C_("Password:")); + $label2 = h_abbr(C_("Confirm password:")); + $dummy = "*" x ${$self->{"maxlens"}}{"passwd"}; + + # A form to create a new item + if ($self->{"type"} eq "new") { + print << "EOT"; + + +EOT + # There is a previously-saved password + if (defined($passid = $self->{"form"}->param("passid"))) { + $passid = h($passid); + $val = $self->_val_scalar($dummy, "passwd"); + print << "EOT"; + +EOT + } else { + $val = $self->_val_scalar(undef, "passwd"); + print << "EOT"; + +EOT + } + print << "EOT"; + + + +EOT + # There is a previously-saved password + if (defined($passid = $self->{"form"}->param("passid2"))) { + $passid = h($passid); + $val = $self->_val_scalar($dummy, "passwd"); + print << "EOT"; + +EOT + } else { + $val = $self->_val_scalar(undef, "passwd"); + print << "EOT"; + +EOT + } + print << "EOT"; + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + print << "EOT"; + + +EOT + # There is a previous-saved password + if (defined($passid = $self->{"form"}->param("passid"))) { + $passid = h($passid); + $val = $self->_val_scalar($dummy, "passwd"); + print << "EOT"; + +EOT + } else { + $val = $self->_val_scalar(undef, "passwd"); + print << "EOT"; + +EOT + } + print << "EOT"; + + + +EOT + # There is a previous-saved password + if (defined($passid = $self->{"form"}->param("passid2"))) { + $passid = h($passid); + $val = $self->_val_scalar($dummy, "passwd"); + print << "EOT"; + +EOT + } else { + $val = $self->_val_scalar(undef, "passwd"); + print << "EOT"; + +EOT + } + print << "EOT"; + +EOT + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $dummy = h($dummy); + print << "EOT"; + + $mark$label + $dummy + +EOT + } + return; +} + +# _html_col_path: The page path +sub _html_col_path : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Set the default path to "/" + $form->param("path", "/") + if $self->{"is_first_form"} && $self->{"type"} eq "new"; + $self->_html_coltmpl_text("path", h_abbr(C_("Page path:"))); +} + +# _html_col_pic: The picture +sub _html_col_pic : method { + local ($_, %_); + my ($self, $form, $current, $label, $labelpos, $labelcap, $mark, $colspan); + my ($curpic, $curcap, $curpos, $val, $valpic, $valcap, $orig, $new); + my ($PICS, $pic, $setpic, $delpic, $picposid_default, $alt, $origalt); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("pic"); + $colspan = $self->_colspan; + $label = h_abbr(C_("Picture:")); + $labelcap = h_abbr(C_("Pic. caption:")); + $labelpos = h_abbr(C_("Pic. position:")); + # Obtain the picture deposit + $PICS = pic_deposit; + $setpic = h_abbr(C_("Set the picture")); + $delpic = h_abbr(C_("Delete this picture")); + $picposid_default = h("picpos" . lc PIC_POS_DEFAULT); + + # A form to create a new item + if ($self->{"type"} eq "new") { + $alt = h_abbr(C_("Picture preview")); + if (!defined $form->param("pic")) { + $_ = h_abbr(t_none); + print << "EOT"; + + + $_ + +EOT + } elsif (!pic_exists ${$form->param_fetch("pic")}[0]) { + $_ = h_abbr(t_na); + print << "EOT"; + + + $_ + +EOT + } else { + $val = $self->_val_text("pic"); + $pic = $$PICS{$form->param("pic")}; + $valpic = echopic $pic, $alt, $$pic{"ratio"}; + $valcap = $self->_val_text("piccap", "piccap"); + print << "EOT"; + + + $valpic
    + + + + + + + + +EOT + print " "; + @_ = map sprintf("%s", + h(lc $_), + $self->_val_radio("picpos", $_, ($_ eq PIC_POS_DEFAULT)), + h(lc $_), h_abbr(picpos_label $_)), @PIC_VALID_POS; + print join("\n ", @_); + print << "EOT"; + + +EOT + } + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + $origalt = h_abbr(C_("Original picture preview")); + $alt = h_abbr(C_("New picture preview")); + if (!defined $current->param("pic")) { + $curpic = h_abbr(t_none); + } elsif ($current->param("pic") == 0) { + $curpic = h_abbr(t_na); + } else { + $pic = $$PICS{$current->param("pic")}; + $curpic = echopic $pic, $origalt, $$pic{"ratio"}; + } + print << "EOT"; + + + $orig + $curpic + +EOT + if ( !pic_exists(${$current->param_fetch("pic")}[0]) + && getlang ne $DEFAULT_LANG) { + $_ = h_abbr(C_("Please upload a new picture from [_1].", + ln($DEFAULT_LANG, LN_DESC_CURLC))); + print << "EOT"; + + + $_ + +EOT + } elsif (!defined $form->param("pic")) { + $_ = h_abbr(t_none); + print << "EOT"; + + + $_ + +EOT + } elsif (!pic_exists ${$form->param_fetch("pic")}[0]) { + $_ = h_abbr(t_na); + print << "EOT"; + + + $_ + +EOT + } else { + $curcap = $self->_cval_text("piccap"); + $curpos = h_abbr(picpos_label $current->param("picpos")); + $val = $self->_val_text("pic"); + $pic = $$PICS{$form->param("pic")}; + $valpic = echopic $pic, $alt, $$pic{"ratio"}; + $valcap = $self->_val_text("piccap", "piccap"); + print << "EOT"; + + + $valpic
    + + +EOT + # A multi-lingual column, that is not in the default language + if (getlang ne $DEFAULT_LANG) { + my ($srclabel, $srccur); + $srclabel = h_abbr(C_("Source:")); + $_ = "piccap_" . ln($DEFAULT_LANG, LN_DATABASE); + $srccur = $self->_cval_text($_); + print << "EOT"; + + + $srclabel + $srccur + + + $orig + $curcap + + + + + +EOT + } else { + print << "EOT"; + + + $orig + $curcap + + + + + +EOT + } + print << "EOT"; + + + $orig + $curpos + + + +EOT + print " "; + @_ = map sprintf("%s", + h(lc $_), h($_), + $self->_val_radio("picpos", $_, ($_ eq PIC_POS_DEFAULT)), + h(lc $_), h_abbr(picpos_label $_)), @PIC_VALID_POS; + print join("\n ", @_); + print << "EOT"; + + +EOT + } + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $alt = h_abbr(C_("Picture preview")); + if (!defined $current->param("pic")) { + $curpic = h_abbr(t_none); + print << "EOT"; + + $mark$label + $curpic + +EOT + } elsif ($current->param("pic") == 0) { + $curpic = h_abbr(t_na); + print << "EOT"; + + $mark$label + $curpic + +EOT + } else { + $pic = $$PICS{$current->param("pic")}; + $curpic = echopic $pic, $origalt, $$pic{"ratio"}; + $curcap = $self->_cval_text("piccap"); + $curpos = h_abbr(picpos_label $current->param("picpos")); + print << "EOT"; + + $mark$label + $curpic + + + $mark$labelcap + $curcap + + + $mark$labelpos + $curpos + +EOT + } + } + return; +} + +# _html_col_scats: The subcategories +sub _html_col_scats : method { + local ($_, %_); + my ($self, $form, $current, $label, $url, $mark, $colspan, $thclass, $thcolspan); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("scats"); + $colspan = $self->_colspan; + $label = h_abbr(C_("[numerate,_1,Subcategory,Subcategories]:", $current->param("scatcount"))); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label +EOT + print " "; + @_ = qw(); + for ($_ = 0; $_ < $current->param("scatcount"); $_++) { + push @_, sprintf("
  • %2\$s\n" + . " (%3\$s)\n" + . "
  • \n", + h($REQUEST_FILE . "?form=cur&sn=" . $current->param("scat$_" . "sn")), + h($current->param("scat$_" . "title")), + h($current->param("scat$_" . "url"))); + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT +} + +# _html_col_script: The script +sub _html_col_script : method { + $_[0]->_html_coltmpl_text("script", h_abbr(C_("Script:"))); +} + +# _html_col_sn: The serial number +sub _html_col_sn : method { + $_[0]->_html_coltmpl_ro("sn", h_abbr(C_("S/N:"))); +} + +# _html_col_tel: The telephone number +sub _html_col_tel : method { + $_[0]->_html_coltmpl_text("tel", h_abbr(C_("Tel.:"))); +} + +# _html_col_title: The title +sub _html_col_title : method { + $_[0]->_html_coltmpl_text("title", h_abbr(C_("Title:"))); +} + +# _html_col_title_en: The English title +sub _html_col_title_en : method { + $_[0]->_html_coltmpl_text("title_en", h_abbr(C_("English title:"))); +} + +# _html_col_updated: The last-update time +sub _html_col_updated : method { + $_[0]->_html_coltmpl_ro_datetime("updated", h_abbr(C_("Updated:"))); +} + +# _html_col_updatedby: The last maintainer +sub _html_col_updatedby : method { + $_[0]->_html_coltmpl_ro_user("updatedby", h_abbr(C_("Updated by:"))); +} + +# _html_col_url: The URL +sub _html_col_url : method { + $_[0]->_html_coltmpl_url("url", h_abbr(C_("URL:"))); +} + +# _html_col_value: The preference value +sub _html_col_value : method { + $_[0]->_html_coltmpl_text("value", h_abbr(C_("Value:"))); +} + +# _html_col_visited: The last-visited time +sub _html_col_visited : method { + $_[0]->_html_coltmpl_ro_datetime("visited", h_abbr(C_("Visited:"))); +} + +# _html_col_visits: The visiting counter +sub _html_col_visits : method { + $_[0]->_html_coltmpl_ro("visits", h_abbr(C_("Visits:"))); +} + +##################### +# Private utility methods. Do not call them directly. +##################### +# _cval_text: Output a current text value +sub _cval_text : method { + local ($_, %_); + my ($self, $col); + ($self, $col) = @_; + return h($_) if defined($_ = $self->{"cur"}->param($col)); + return h_abbr(t_none); +} + +# _cval_textarea: Output a current textarea value +sub _cval_textarea : method { + local ($_, %_); + my ($self, $col); + ($self, $col) = @_; + return a2html($_) if defined($_ = $self->{"cur"}->param($col)); + return h_abbr(t_none); +} + +# _val_text: Output a value +sub _val_text : method { + local ($_, %_); + my ($self, $col, $maxcol, $html); + ($self, $col, $maxcol) = @_; + $html = ""; + $html .= " maxlength=\"" . h(${$self->{"maxlens"}}{$maxcol}) . "\"" + if defined $maxcol; + $html .= defined($_ = $self->{"form"}->param($col))? + " value=\"" . h($_) . "\"": " value=\"\""; + return $html; +} + +# _val_scalar: Output a scalar value +sub _val_scalar : method { + local ($_, %_); + my ($self, $val, $maxcol, $html); + ($self, $val, $maxcol) = @_; + $html = ""; + $html .= " maxlength=\"" . h(${$self->{"maxlens"}}{$maxcol}) . "\"" + if defined $maxcol; + $html .= defined $val? + " value=\"" . h($val) . "\"": " value=\"\""; + return $html; +} + +# _val_date: Output a date value +sub _val_date : method { + local ($_, %_); + my ($self, $col, $maxcol, $html, $val); + ($self, $col, $maxcol) = @_; + $html = ""; + $html .= " maxlength=\"" . h(${$self->{"maxlens"}}{$maxcol}) . "\"" + if defined $maxcol; + if (defined($val = $self->{"form"}->param($col))) { + $val = fmtdate $val if $val =~ /^\-?\d+(?:\.\d+)?$/; + } + $html .= defined $val? + " value=\"" . h($val) . "\"": " value=\"\""; + return $html; +} + +# _val_textarea: Output a value as a textarea content +sub _val_textarea : method { + local ($_, %_); + my ($self, $col, $default); + ($self, $col, $default) = @_; + return h($_) if defined($_ = $self->{"form"}->param($col)) && $_ ne ""; + return h($default); +} + +# _val_check: Output a value as a checkbox check value +sub _val_check : method { + local ($_, %_); + my ($self, $col); + ($self, $col) = @_; + return " checked=\"checked\"" + if defined($_ = $self->{"form"}->param($col)) && $_; + return ""; +} + +# _val_radio: Output a value as a radio check value +sub _val_radio : method { + local ($_, %_); + my ($self, $col, $valhere, $is_default); + ($self, $col, $valhere, $is_default) = @_; + $is_default = 0 if !defined $is_default; + + return " value=\"" . h($valhere) . "\"" + . (($_ eq $valhere)? " checked=\"checked\"": "") + if defined($_ = $self->{"form"}->param($col)); + return " value=\"" . h($valhere) . "\"" + . ($is_default? " checked=\"checked\"": ""); +} + +# _colspan: Output the colspan phrase +sub _colspan : method { + local ($_, %_); + my ($self, $addcols); + ($self, $addcols) = @_; + $addcols = 0 if !defined $addcols; + $_ = $self->{"colspan"} + $addcols; + # Only output for many columns + return $_ > 1? " colspan=\"" . h($_) . "\"": ""; +} + +# _colspan_full: Output the colspan phrase spanning the whole table +sub _colspan_full : method { + local ($_, %_); + my ($self, $addcols); + ($self, $addcols) = @_; + $addcols = 0 if !defined $addcols; + $_ = $self->{"colspan"} + $addcols; + $_ += ($self->{"type"} eq "cur")? 2: 1; + # Only output for many columns + return $_ > 1? " colspan=\"" . h($_) . "\"": ""; +} + +# _mark: Output the column mark +sub _mark : method { + local ($_, %_); + my ($self, $col); + ($self, $col) = @_; + # Bounce if no columns to check or no mark to use + return "" if !exists $self->{"markcols"} || !defined $self->{"mark"}; + %_ = map { $_ => 1 } @{$self->{"markcols"}}; + return exists $_{$col}? $self->{"mark"}: ""; +} + +# _delcolcount: Obtain the number of items of a column for the deletion form +sub _delcolcount : method { + local ($_, %_); + my ($self, $col); + ($self, $col) = @_; + # None-deletion form -- return 0 since the number of items is unknown + return 0 unless $self->{"type"} eq "del"; + # Deletion form -- return the number of items + return $self->{"cur"}->param($col . "count") +} + + +################### +# Echo the column values +################### + + +# Selima::Form::MetaCols: Manage and output the meta form information +package Selima::Form::MetaCols; +use 5.008; +use strict; +use warnings; + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($class, $self); + $class = $_[0]; + $self = bless {}, $class; + $self->{"cols"} = []; + return $self; +} + +# add: Add a column +sub add : method { + local ($_, %_); + my ($self, $type, $name, $value); + ($self, $type, $name, $value) = @_; + push @{$self->{"cols"}}, { + "type" => $type, + "name" => $name, + "value" => $value, + }; + return; +} + +# out: Output the columns +sub out : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Bounce for nothing + return if @{$self->{"cols"}} == 0; + # Output the first column + $_ = shift @{$self->{"cols"}}; + print "_out_attrs($_) . " />"; + # Output the rest columns + print "_out_attrs($_) . " />" + foreach @{$self->{"cols"}}; + # Output a new line + print "\n"; + return; +} + +# _out_attrs: Output the attributes +sub _out_attrs : method { + local ($_, %_); + my $self; + ($self, $_) = @_; + @_ = qw(); + push @_, "type=\"" . h($$_{"type"}) . "\""; + push @_, "name=\"" . h($$_{"name"}) . "\"" + if defined $$_{"name"}; + if (defined $$_{"name"} && $$_{"name"} eq "charset") { + push @_, "value=\"\""; + } else { + push @_, "value=\"" . h($$_{"value"}) . "\""; + } + return join " ", @_; +} + +return 1; diff --git a/lib/perl5/Selima/Form/AcctRec.pm b/lib/perl5/Selima/Form/AcctRec.pm new file mode 100644 index 0000000..560be9e --- /dev/null +++ b/lib/perl5/Selima/Form/AcctRec.pm @@ -0,0 +1,179 @@ +# Selima Website Content Management System +# AcctRec.pm: The accounting record form. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-23 + +package Selima::Form::AcctRec; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::Accounting; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "acctrecs" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this accounting record") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to add a new accounting record."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to edit a current accounting record."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete an accounting record."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(trx type ord subj summary amount)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn trx type ord subj summary amount + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Add a New Accounting Record"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Edit a Current Accounting Record"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete an Accounting Record"); + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_trx: The accounting transaction +sub _html_col_trx : method { + $_[0]->_html_coltmpl_call("trx", h_abbr(C_("Accounting transaction:")), \&accttrx_id); +} + +# _html_col_type: The type +sub _html_col_type : method { + local ($_, %_); + my ($self, @opts); + $self = $_[0]; + @opts = ( { "val" => "debit", + "title" => C_("Debit"), }, + { "val" => "credit", + "title" => C_("Credit"), }, ); + return $self->_html_coltmpl_radio("type", h_abbr(C_("Type:")), \@opts, undef, 1); +} + +# _html_col_subj: The accounting subject +sub _html_col_subj : method { + local ($_, %_); + my ($self, $form, $current, $label, $choose, $mark, $colspan); + my ($cur, $orig, $new); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $label = h_abbr(C_("Accounting subject:")); + $choose = h_abbr(C_("Choose")); + $mark = $self->_mark("subj"); + $colspan = $self->_colspan; + + # A form to create a new item + if ($self->{"type"} eq "new") { + print << "EOT"; + + + + + + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $cur = h(acctsubj_title $current->param("subj")); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + print << "EOT"; + + + $orig + $cur + + + + + + + +EOT + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $cur = h(acctsubj_title $current->param("subj")); + print << "EOT"; + + $mark$label + $cur + +EOT + } + return; +} + +# _html_col_summary: The summary +sub _html_col_summary : method { + $_[0]->_html_coltmpl_text("summary", h_abbr(C_("Summary:"))); +} + +# _html_col_amount: The amount +sub _html_col_amount : method { + $_[0]->_html_coltmpl_text("amount", h_abbr(C_("Amount:"))); +} + +return 1; diff --git a/lib/perl5/Selima/Form/AcctSubj.pm b/lib/perl5/Selima/Form/AcctSubj.pm new file mode 100644 index 0000000..761d958 --- /dev/null +++ b/lib/perl5/Selima/Form/AcctSubj.pm @@ -0,0 +1,143 @@ +# Selima Website Content Management System +# AcctSubj.pm: The accounting subject form. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-08-23 + +package Selima::Form::AcctSubj; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::CommText; +use Selima::DataVars qw(:requri :scptconf); +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "acctsubj" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this accounting subject") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to add a new accounting subject."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to edit a current accounting subject."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete an accounting subject."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(parent code title)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn parent code title ssubs + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Add a New Accounting Subject"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Edit a Current Accounting Subject"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete an Accounting Subject"); + } + } + $self = $class->SUPER::new($status, $args); + if ($self->{"type"} eq "cur") { + if (defined $self->{"cur"}->param("ssubcount") && $self->{"cur"}->param("ssubcount") > 0) { + $self->{"nodelete"} = 1; + push @{$self->{"prefmsg"}}, C_("This accounting subject has [numerate,_1,an accounting sub-subject,accounting sub-subjects]. It cannot be deleted. To delete the accounting subject, [numerate,_1,its accounting sub-subject,all of its accounting sub-subjects] must first be deleted.", $self->{"cur"}->param("ssubcount")); + } + if (defined $self->{"cur"}->param("reccount") && $self->{"cur"}->param("reccount") > 0) { + $self->{"nodelete"} = 1; + push @{$self->{"prefmsg"}}, C_("This accounting subject has [numerate,_1,an accounting record,accounting records]. It cannot be deleted. To delete the accounting subject, [numerate,_1,its accounting record,all of its accounting records] must first be deleted.", $self->{"cur"}->param("reccount")); + } + } + return $self; +} + +# _html_col_code: The code +sub _html_col_code : method { + $_[0]->_html_coltmpl_text("code", h_abbr(C_("Code:")), undef, + ${$_[0]->{"maxlens"}}{"code"}); +} + +# _html_col_parent: The parent +sub _html_col_parent : method { + $_[0]->_html_coltmpl_call_null("parent", h_abbr(C_("Parent subject:")), + "topmost", h_abbr(C_("At the very top")), $MAIN->can($_[0]->{"table"} . "_title")); +} + +# _html_col_ssubs: The sub-subjects +sub _html_col_ssubs : method { + local ($_, %_); + my ($self, $form, $current, $label, $url, $mark, $colspan, $thclass, $thcolspan); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("ssubs"); + $colspan = $self->_colspan; + $label = h_abbr(C_("[numerate,_1,Sub-subject,Sub-subjects]:", $current->param("ssubcount"))); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label +EOT + print " "; + @_ = qw(); + for ($_ = 0; $_ < $current->param("ssubcount"); $_++) { + push @_, sprintf("
  • %2\$s
  • \n", + h($REQUEST_FILE . "?form=cur&sn=" . $current->param("ssub$_" . "sn")), + h($current->param("ssub$_" . "title"))); + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT +} + +return 1; diff --git a/lib/perl5/Selima/Form/AcctTrx.pm b/lib/perl5/Selima/Form/AcctTrx.pm new file mode 100644 index 0000000..dbfb0b6 --- /dev/null +++ b/lib/perl5/Selima/Form/AcctTrx.pm @@ -0,0 +1,819 @@ +# Selima Website Content Management System +# AcctTrx.pm: The accounting transaction form. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-20 + +package Selima::Form::AcctTrx; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::Accounting; +use Selima::AddGet; +use Selima::CommText; +use Selima::DataVars qw($DBH :requri :scptconf); +use Selima::FormFunc; +use Selima::Format; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "accttrx" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this accounting transaction") + if !exists $$args{"deltext"}; + # The hidden columns + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to add a new accounting transaction."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to edit a current accounting transaction."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete an accounting transaction."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(date ord recs note)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn date ord recs note + created createdby updated updatedby)]; + } + } + $self = $class->SUPER::new($status, $args); + ${$self->{"maxlens"}}{"ord"} = 2; + # Set the subform type + if ($$args{"type"} eq "new") { + $_ = curform; + $self->{"subtype"} = $_->param("formsub"); + } elsif ($$args{"type"} eq "cur") { + $self->{"subtype"} = $self->{"form"}->param("formsub"); + } elsif ($$args{"type"} eq "del") { + $self->{"subtype"} = $self->{"cur"}->param("formsub"); + } + # Only expense, income or trans are allowed + http_500 "invalid form sub-type: " . $self->{"type"} + if $self->{"subtype"} !~ /^(?:expense|income|trans)$/; + if ($self->{"subtype"} eq "expense" || $self->{"subtype"} eq "income") { + $self->{"colspan"} = 3; + } else { + $self->{"colspan"} = 6; + } + $self->{"hidcols"} = [] if !exists $self->{"hidcols"}; + push @{$self->{"hidcols"}}, { + "name" => "formsub", + "value" => $self->{"subtype"}, + }; + if ($self->{"type"} eq "cur" && $self->{"subtype"} ne "trans") { + $self->{"header_buttons"} = [ + { "name" => undef, "value" => h(C_("Submit")) }, + { "name" => "confirm", "value" => h(C_("Save")) }, + { "name" => "del", "value" => h($self->{"deltext"}) }, + { "name" => "cnvttrans", "value" => h(C_("Convert to a transfer transaction")) }, ]; + $self->{"footer_buttons"} = [ + { "name" => undef, "value" => h(C_("Submit")) }, + { "name" => "confirm", "value" => h(C_("Save")) }, + { "name" => "del", "value" => h($self->{"deltext"}) }, + { "name" => "cnvttrans", "value" => h(C_("Convert to a transfer transaction")) }, ]; + } + # A form to create a new item + if ($self->{"type"} eq "new") { + if ($self->{"subtype"} eq "expense") { + $self->{"title"} = C_("Add a New Cache Expense Transaction"); + } elsif ($self->{"subtype"} eq "income") { + $self->{"title"} = C_("Add a New Cache Income Transaction"); + } elsif ($self->{"subtype"} eq "trans") { + $self->{"title"} = C_("Add a New Transfer Transaction"); + } + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + if ($self->{"subtype"} eq "expense") { + $self->{"title"} = C_("Edit a Current Cache Expense Transaction"); + } elsif ($self->{"subtype"} eq "income") { + $self->{"title"} = C_("Edit a Current Cache Income Transaction"); + } elsif ($self->{"subtype"} eq "trans") { + $self->{"title"} = C_("Edit a Current Transfer Transaction"); + } + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + if ($self->{"subtype"} eq "expense") { + $self->{"title"} = C_("Delete a Cache Expense Transaction"); + } elsif ($self->{"subtype"} eq "income") { + $self->{"title"} = C_("Delete a Cache Income Transaction"); + } elsif ($self->{"subtype"} eq "trans") { + $self->{"title"} = C_("Delete a Transfer Transaction"); + } + } + %_ = $DBH->col_lens("acctrec"); + ${$self->{"maxlens"}}{"recsubj"} = $_{"subj"}; + ${$self->{"maxlens"}}{"recsummary"} = $_{"summary"}; + ${$self->{"maxlens"}}{"recamount"} = $_{"amount"}; + return $self; +} + +# _html_coltmpl_ro_loop_rec: Display a read-only record row column +sub _html_coltmpl_ro_loop_rec : method { + local ($_, %_); + local ($_, %_); + my ($self, $i, $current, $rowhdrs); + my ($curlsubj, $curlsummary, $curlamount); + my ($curbsubj, $curbsummary, $curbamount); + ($self, $i) = @_; + $current = $self->{"cur"}; + $rowhdrs = "threcs"; + $rowhdrs .= " thold" if $self->{"type"} eq "cur"; + + # A form to fill in a cash expense transaction + if ($self->{"subtype"} eq "expense") { + $curlsubj = defined($_ = $current->param("debt$i" . "subj"))? + h_abbr(acctsubj_title $_): ""; + $curlsummary = defined($_ = $current->param("debt$i" . "summary"))? + h_abbr($_): ""; + $curlamount = defined($_ = $current->param("debt$i" . "amount"))? + h_abbr(fmtntamount $_): ""; + print << "EOT"; + + $curlsubj + $curlsummary + $curlamount + +EOT + + # A form to fill in a cash income transaction + } elsif ($self->{"subtype"} eq "income") { + $curbsubj = defined($_ = $current->param("crdt$i" . "subj"))? + h_abbr(acctsubj_title $_): ""; + $curbsummary = defined($_ = $current->param("crdt$i" . "summary"))? + h_abbr($_): ""; + $curbamount = defined($_ = $current->param("crdt$i" . "amount"))? + h_abbr(fmtntamount $_): ""; + print << "EOT"; + + $curbsubj + $curbsummary + $curbamount + +EOT + + # A form to fill in a transfer transaction + } elsif ($self->{"subtype"} eq "trans") { + $curlsubj = defined($_ = $current->param("debt$i" . "subj"))? + h_abbr(acctsubj_title $_): ""; + $curlsummary = defined($_ = $current->param("debt$i" . "summary"))? + h_abbr($_): ""; + $curlamount = defined($_ = $current->param("debt$i" . "amount"))? + h_abbr(fmtntamount $_): ""; + $curbsubj = defined($_ = $current->param("crdt$i" . "subj"))? + h_abbr(acctsubj_title $_): ""; + $curbsummary = defined($_ = $current->param("crdt$i" . "summary"))? + h_abbr($_): ""; + $curbamount = defined($_ = $current->param("crdt$i" . "amount"))? + h_abbr(fmtntamount $_): ""; + print << "EOT"; + + $curlsubj + $curlsummary + $curlamount + $curbsubj + $curbsummary + $curbamount + +EOT + } + return; +} + +# _html_coltmpl_loop_rec: Display a record row column +sub _html_coltmpl_loop_rec : method { + local ($_, %_); + my ($self, $i, $form, $choose, $rowhdrs); + my ($coldsubj, $coldsummary, $valdsummary, $coldamount, $valdamount); + my ($colcsubj, $colcsummary, $valcsummary, $colcamount, $valcamount); + ($self, $i) = @_; + $form = $self->{"form"}; + $choose = h_abbr(C_("Choose")); + $rowhdrs = "threcs"; + $rowhdrs .= " thnew" if $self->{"type"} eq "cur"; + + # A form to fill in a cash expense transaction + if ($self->{"subtype"} eq "expense") { + $coldsubj = "debt$i" . "subj"; + $coldsubj = h($coldsubj); + $coldsummary = "debt$i" . "summary"; + $valdsummary = $self->_val_text($coldsummary, "recsummary"); + $coldsummary = h($coldsummary); + $coldamount = "debt$i" . "amount"; + $valdamount = $self->_val_text($coldamount, "recamount"); + $coldamount = h($coldamount); + print << "EOT"; + + + + + + + +EOT + + # A form to fill in a cash income transaction + } elsif ($self->{"subtype"} eq "income") { + $colcsubj = "crdt$i" . "subj"; + $colcsubj = h($colcsubj); + $colcsummary = "crdt$i" . "summary"; + $valcsummary = $self->_val_text($colcsummary, "recsummary"); + $colcsummary = h($colcsummary); + $colcamount = "crdt$i" . "amount"; + $valcamount = $self->_val_text($colcamount, "recamount"); + $colcamount = h($colcamount); + print << "EOT"; + + + + + + + +EOT + + # A form to fill in a transfer transaction + } elsif ($self->{"subtype"} eq "trans") { + $coldsubj = "debt$i" . "subj"; + $coldsubj = h($coldsubj); + $coldsummary = "debt$i" . "summary"; + $valdsummary = $self->_val_text($coldsummary, "recsummary"); + $coldsummary = h($coldsummary); + $coldamount = "debt$i" . "amount"; + $valdamount = $self->_val_text($coldamount, "recamount"); + $coldamount = h($coldamount); + $colcsubj = "crdt$i" . "subj"; + $colcsubj = h($colcsubj); + $colcsummary = "crdt$i" . "summary"; + $valcsummary = $self->_val_text($colcsummary, "recsummary"); + $colcsummary = h($colcsummary); + $colcamount = "crdt$i" . "amount"; + $valcamount = $self->_val_text($colcamount, "recamount"); + $colcamount = h($colcamount); + print << "EOT"; + + + + + + + + + + + + +EOT + } + return; +} + +# _html_col_ord: The order +sub _html_col_ord : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Set the default order to maximum + $form->param("ord", 99) + if $self->{"is_first_form"} && $self->{"type"} eq "new"; + $self->_html_coltmpl_text("ord", h_abbr(C_("Order:")), undef, + ${$self->{"maxlens"}}{"ord"}); +} + +# _html_col_recs: The accounting records +sub _html_col_recs : method { + local ($_, %_); + my ($self, $form, $current, $label, $mark, $orig, $new); + my ($labeldebit, $labelcredit, $labelsubj, $labelsummary, $labelamount); + my ($labelsum, $sumdebit, $sumcredit); + my ($count_new, $rows_new, $count_cur, $rows_cur, $rowspan); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("recs"); + $labeldebit = h_abbr(C_("Debit")); + $labelcredit = h_abbr(C_("Credit")); + $labelsubj = h_abbr(C_("Accounting subject")); + $labelsummary = h_abbr(C_("Summary")); + $labelamount = h_abbr(C_("Amount")); + $labelsum = h_abbr(C_("Total")); + + # A form to create a new item + if ($self->{"type"} eq "new") { + # Find the total number of records + $count_new = 0; + # Find the last-used debit record + for ( $_ = 0; + defined $form->param("debt$_" . "subj") + || defined $form->param("debt$_" . "summary") + || defined $form->param("debt$_" . "amount"); $_++) {}; + if ($_ > 0) { + for ( $_--; + $_ >= 0 + && $form->param("debt$_" . "subj") eq "" + && $form->param("debt$_" . "summary") eq "" + && $form->param("debt$_" . "amount") eq ""; $_--) {}; + $_++; + } + $count_new = $_ if $count_new < $_; + # Find the last-used credit record + for ( $_ = 0; + defined $form->param("crdt$_" . "subj") + || defined $form->param("crdt$_" . "summary") + || defined $form->param("crdt$_" . "amount"); $_++) {}; + if ($_ > 0) { + for ( $_--; + $_ >= 0 + && $form->param("crdt$_" . "subj") eq "" + && $form->param("crdt$_" . "summary") eq "" + && $form->param("crdt$_" . "amount") eq ""; $_--) {}; + $_++; + } + $count_new = $_ if $count_new < $_; + # We need at least 5 blank records + $count_new += 5; + $_ = $count_new + 2; + $_++ if $self->{"subtype"} eq "trans"; + $rows_new = " rowspan=\"" . h($_) . "\""; + $rows_new = "" if $_ == 1; + $label = h_abbr(C_("[numerate,_1,Content]:", 0)); + # A form to fill in a cash expense transaction + if ($self->{"subtype"} eq "expense") { + print << "EOT"; + + + + + + +EOT + # A form to fill in a cash income transaction + } elsif ($self->{"subtype"} eq "income") { + print << "EOT"; + + + + + + +EOT + # A form to fill in a transfer transaction + } elsif ($self->{"subtype"} eq "trans") { + print << "EOT"; + + + + + + + + + + + + + +EOT + } + for ($_ = 0, @_ = qw(); $_ < $count_new; $_++) { + $self->_html_coltmpl_loop_rec($_); + } + # A form to fill in a cash expense transaction + if ($self->{"subtype"} eq "expense") { + for (my $i = 0, $sumdebit = 0; $i < $count_new; $i++) { + $sumdebit += $_ + if defined($_ = $form->param("debt$i" . "amount")) + && /^\d+$/; + } + print << "EOT"; + + + + +EOT + # A form to fill in a cash income transaction + } elsif ($self->{"subtype"} eq "income") { + for (my $i = 0, $sumcredit = 0; $i < $count_new; $i++) { + $sumcredit += $_ + if defined($_ = $current->param("crdt$i" . "amount")) + && /^\d+$/; + } + print << "EOT"; + + + + +EOT + # A form to fill in a transfer transaction + } elsif ($self->{"subtype"} eq "trans") { + for (my $i = 0, $sumdebit = 0, $sumcredit = 0; $i < $count_new; $i++) { + $sumdebit += $_ + if defined($_ = $current->param("debt$i" . "amount")) + && /^\d+$/; + $sumcredit += $_ + if defined($_ = $current->param("crdt$i" . "amount")) + && /^\d+$/; + } + print << "EOT"; + + + + + + +EOT + } + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $count_cur = 0; + $count_cur = $current->param("debtcount") + if $count_cur < $current->param("debtcount"); + $count_cur = $current->param("crdtcount") + if $count_cur < $current->param("crdtcount"); + $_ = $count_cur + 2; + $_++ if $self->{"subtype"} eq "trans"; + $rows_cur = " rowspan=\"" . h($_) . "\""; + $rows_cur = "" if $_ == 1; + # Find the total number of records + $count_new = 0; + # Find the last-used debit record + for ( $_ = 0; + defined $form->param("debt$_" . "subj") + || defined $form->param("debt$_" . "summary") + || defined $form->param("debt$_" . "amount"); $_++) {}; + if ($_ > 0) { + for ( $_--; + $_ > 0 + && $form->param("debt$_" . "subj") eq "" + && $form->param("debt$_" . "summary") eq "" + && $form->param("debt$_" . "amount") eq ""; $_--) {}; + } + $_++; + $count_new = $_ if $count_new < $_; + # Find the last-used credit record + for ( $_ = 0; + defined $form->param("crdt$_" . "subj") + || defined $form->param("crdt$_" . "summary") + || defined $form->param("crdt$_" . "amount"); $_++) {}; + if ($_ > 0) { + for ( $_--; + $_ > 0 + && $form->param("crdt$_" . "subj") eq "" + && $form->param("crdt$_" . "summary") eq "" + && $form->param("crdt$_" . "amount") eq ""; $_--) {}; + } + $_++; + $count_new = $_ if $count_new < $_; + # We need at least 5 blank records + $count_new += 5; + $_ = $count_new + 2; + $_++ if $self->{"subtype"} eq "trans"; + $rows_new = " rowspan=\"" . h($_) . "\""; + $rows_new = "" if $_ == 1; + $_ = $count_cur + $count_new + 4; + $_ += 2 if $self->{"subtype"} eq "trans"; + $rowspan = " rowspan=\"" . h($_) . "\""; + $rowspan = "" if $_ == 1; + $label = h_abbr(C_("[numerate,_1,Content]:", 0)); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + # A form to fill in a cash expense transaction + if ($self->{"subtype"} eq "expense") { + print << "EOT"; + + $mark$label + $orig + $labelsubj + $labelsummary + $labelamount + +EOT + # A form to fill in a cash income transaction + } elsif ($self->{"subtype"} eq "income") { + print << "EOT"; + + $mark$label + $orig + $labelsubj + $labelsummary + $labelamount + +EOT + # A form to fill in a transfer transaction + } elsif ($self->{"subtype"} eq "trans") { + print << "EOT"; + + $mark$label + $orig + $labeldebit + $labelcredit + + + $labelsubj + $labelsummary + $labelamount + $labelsubj + $labelsummary + $labelamount + +EOT + } + for ($_ = 0, @_ = qw(); $_ < $count_cur; $_++) { + $self->_html_coltmpl_ro_loop_rec($_); + } + # A form to fill in a cash expense transaction + if ($self->{"subtype"} eq "expense") { + for (my $i = 0, $sumdebit = 0; $i < $count_cur; $i++) { + $sumdebit += $_ + if defined($_ = $current->param("debt$i" . "amount")); + } + $sumdebit = h_abbr(fmtntamount $sumdebit); + print << "EOT"; + + $labelsum + $sumdebit + +EOT + # A form to fill in a cash income transaction + } elsif ($self->{"subtype"} eq "income") { + for (my $i = 0, $sumcredit = 0; $i < $count_cur; $i++) { + $sumcredit += $_ + if defined($_ = $current->param("crdt$i" . "amount")); + } + $sumcredit = h_abbr(fmtntamount $sumcredit); + print << "EOT"; + + $labelsum + $sumcredit + +EOT + # A form to fill in a transfer transaction + } elsif ($self->{"subtype"} eq "trans") { + for (my $i = 0, $sumdebit = 0, $sumcredit = 0; $i < $count_cur; $i++) { + $sumdebit += $_ + if defined($_ = $current->param("debt$i" . "amount")); + $sumcredit += $_ + if defined($_ = $current->param("crdt$i" . "amount")); + } + $sumdebit = h_abbr(fmtntamount $sumdebit); + $sumcredit = h_abbr(fmtntamount $sumcredit); + print << "EOT"; + + $labelsum + $sumdebit + $labelsum + $sumcredit + +EOT + } + # A form to fill in a cash expense transaction + if ($self->{"subtype"} eq "expense") { + print << "EOT"; + + $new + + + + +EOT + # A form to fill in a cash income transaction + } elsif ($self->{"subtype"} eq "income") { + print << "EOT"; + + $new + + + + +EOT + # A form to fill in a transfer transaction + } elsif ($self->{"subtype"} eq "trans") { + print << "EOT"; + + $new + + + + + + + + + + + +EOT + } + for ($_ = 0, @_ = qw(); $_ < $count_new; $_++) { + $self->_html_coltmpl_loop_rec($_); + } + # A form to fill in a cash expense transaction + if ($self->{"subtype"} eq "expense") { + for (my $i = 0, $sumdebit = 0; $i < $count_new; $i++) { + $sumdebit += $_ + if defined($_ = $form->param("debt$i" . "amount")) + && /^\d+$/; + } + print << "EOT"; + + + + +EOT + # A form to fill in a cash income transaction + } elsif ($self->{"subtype"} eq "income") { + for (my $i = 0, $sumcredit = 0; $i < $count_new; $i++) { + $sumcredit += $_ + if defined($_ = $current->param("crdt$i" . "amount")) + && /^\d+$/; + } + print << "EOT"; + + + + +EOT + # A form to fill in a transfer transaction + } elsif ($self->{"subtype"} eq "trans") { + for (my $i = 0, $sumdebit = 0, $sumcredit = 0; $i < $count_new; $i++) { + $sumdebit += $_ + if defined($_ = $current->param("debt$i" . "amount")) + && /^\d+$/; + $sumcredit += $_ + if defined($_ = $current->param("crdt$i" . "amount")) + && /^\d+$/; + } + print << "EOT"; + + + + + + +EOT + } + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $count_cur = 0; + $count_cur = $current->param("debtcount") + if $count_cur < $current->param("debtcount"); + $count_cur = $current->param("crdtcount") + if $count_cur < $current->param("crdtcount"); + $_ = $count_cur + 2; + $_++ if $self->{"subtype"} eq "trans"; + $rows_cur = " rowspan=\"" . h($_) . "\""; + $rows_cur = "" if $_ == 1; + $label = h_abbr(C_("[numerate,_1,Content]:", $count_cur)); + # A form to fill in a cash expense transaction + if ($self->{"subtype"} eq "expense") { + print << "EOT"; + + $mark$label + $labelsubj + $labelsummary + $labelamount + +EOT + # A form to fill in a cash income transaction + } elsif ($self->{"subtype"} eq "income") { + print << "EOT"; + + $mark$label + $labelsubj + $labelsummary + $labelamount + +EOT + # A form to fill in a transfer transaction + } elsif ($self->{"subtype"} eq "trans") { + print << "EOT"; + + $mark$label + $labeldebit + $labelcredit + + + $labelsubj + $labelsummary + $labelamount + $labelsubj + $labelsummary + $labelamount + +EOT + } + for ($_ = 0, @_ = qw(); $_ < $count_cur; $_++) { + $self->_html_coltmpl_ro_loop_rec($_); + } + # A form to fill in a cash expense transaction + if ($self->{"subtype"} eq "expense") { + for (my $i = 0, $sumdebit = 0; $i < $count_cur; $i++) { + $sumdebit += $_ + if defined($_ = $current->param("debt$i" . "amount")); + } + $sumdebit = h_abbr(fmtntamount $sumdebit); + print << "EOT"; + + $labelsum + $sumdebit + +EOT + # A form to fill in a cash income transaction + } elsif ($self->{"subtype"} eq "income") { + for (my $i = 0, $sumcredit = 0; $i < $count_cur; $i++) { + $sumcredit += $_ + if defined($_ = $current->param("crdt$i" . "amount")); + } + $sumcredit = h_abbr(fmtntamount $sumcredit); + print << "EOT"; + + $labelsum + $sumcredit + +EOT + # A form to fill in a transfer transaction + } elsif ($self->{"subtype"} eq "trans") { + for (my $i = 0, $sumdebit = 0, $sumcredit = 0; $i < $count_cur; $i++) { + $sumdebit += $_ + if defined($_ = $current->param("debt$i" . "amount")); + $sumcredit += $_ + if defined($_ = $current->param("crdt$i" . "amount")); + } + $sumdebit = h_abbr(fmtntamount $sumdebit); + $sumcredit = h_abbr(fmtntamount $sumcredit); + print << "EOT"; + + $labelsum + $sumdebit + $labelsum + $sumcredit + +EOT + } + } + return; +} + +# _html_col_note: The note +sub _html_col_note : method { + $_[0]->_html_coltmpl_textarea("note", h_abbr(C_("Note:")), + h_abbr(C_("Fill in the note here.")), undef, 2); +} + +return 1; diff --git a/lib/perl5/Selima/Form/Group.pm b/lib/perl5/Selima/Form/Group.pm new file mode 100644 index 0000000..862013b --- /dev/null +++ b/lib/perl5/Selima/Form/Group.pm @@ -0,0 +1,498 @@ +# Selima Website Content Management System +# Group.pm: The account group form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-12 + +package Selima::Form::Group; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::CommText; +use Selima::ChkPriv; +use Selima::ChkFunc; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; +use Selima::UserName; +use Selima::Unicode; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "groups" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this group") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to add a new group."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to update a current group."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete a group."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(id dsc subuser subgroup supgroup)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn id dsc subuser subgroup supgroup + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Add a New Group"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Update a Current Group"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete a Group"); + } + } + $self = $class->SUPER::new($status, $args); + if ($$args{"type"} eq "cur" && !is_su && $self->{"sn"} == su_group_sn) { + $self->{"nodelete"} = 1; + push @{$self->{"prefmsg"}}, C_("This is a super-user group. You can only change parts of its infomation."); + } + return $self; +} + +# _html_col_id: The group ID. +sub _html_col_id : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Read-only for a non-super-user editing a super-user + if ($self->{"type"} eq "cur" && !is_su && $self->{"sn"} == su_group_sn) { + $self->_html_coltmpl_ro("id", h_abbr(C_("Group ID.:"))); + } else { + $self->_html_coltmpl_text("id", h_abbr(C_("Group ID.:"))); + } +} + +# _html_col_dsc: The description +sub _html_col_dsc : method { + $_[0]->_html_coltmpl_text("dsc", h_abbr(C_("Description:"))); +} + +# _html_col_subuser: Its child users +sub _html_col_subuser : method { + local ($_, %_); + my ($self, $form, $current, $label, $orig, $new, $submit, $mark, $colspan, $title); + #my ($col, $val, $colsn, $valsn, $title); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("subuser"); + $colspan = $self->_colspan; + $submit = h_abbr(C_("Add a user")); + + # A form to create a new item + if ($self->{"type"} eq "new") { + $label = h_abbr(C_("[numerate,_1,User member]:", 0)); + print << "EOT"; + + +EOT + print " "; + for ($_ = 0, @_ = qw(); defined $form->param("subuser$_" . "sn"); $_++) { + if (defined($title = user_opt_label(scalar $form->param("subuser$_" . "sn"), "subuser$_"))) { + push @_, sprintf("
  • \n" + . " \n" + . " %4\$s\n" + . "
  • \n", + h($_), $self->_val_text("subuser$_" . "sn"), + $self->_val_check("subuser$_"), $title); + } else { + push @_, sprintf("
  • \n" + . " \n" + . " %4\$s\n" + . "
  • \n", + h($_), $self->_val_text("subuser$_" . "sn"), + $self->_val_check("subuser$_"), h_abbr(t_na)); + } + } + push @_, "
  • \n"; + print "
      \n" . join("", @_) . "
    \n "; + print << "EOT"; + + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + # Read-only for a non-super-user editing a super-user group + if (!is_su && $self->{"sn"} == su_group_sn) { + $label = h_abbr(C_("[numerate,_1,User member]:", $_[0]->_delcolcount("subuser"))); + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("subusercount"); $_++) { + push @_, "
  • " . $self->_cval_text("subuser$_" . "title") . "
  • \n"; + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT + + } else { + $label = h_abbr(C_("[numerate,_1,User member]:", 0)); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + print << "EOT"; + + + $orig +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("subusercount"); $_++) { + push @_, "
  • " . $self->_cval_text("subuser$_" . "title") . "
  • \n"; + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + + + +EOT + print " "; + for ($_ = 0, @_ = qw(); defined $form->param("subuser$_" . "sn"); $_++) { + if (defined($title = user_opt_label(scalar $form->param("subuser$_" . "sn"), "subuser$_"))) { + push @_, sprintf("
  • \n" + . " \n" + . " %4\$s\n" + . "
  • \n", + h($_), $self->_val_text("subuser$_" . "sn"), + $self->_val_check("subuser$_"), $title); + } else { + push @_, sprintf("
  • \n" + . " \n" + . " %4\$s\n" + . "
  • \n", + h($_), $self->_val_text("subuser$_" . "sn"), + $self->_val_check("subuser$_"), h_abbr(t_na)); + } + } + push @_, "
  • \n"; + print "
      \n" . join("", @_) . "
    \n "; + print << "EOT"; + + +EOT + } + + # A form to delete a current item + } else { + $label = h_abbr(C_("[numerate,_1,User member]:", $_[0]->_delcolcount("subuser"))); + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("subusercount"); $_++) { + push @_, "
  • " . $self->_cval_text("subuser$_" . "title") . "
  • \n"; + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT + } + return; +} + +# _html_col_subgroup: Its child groups +sub _html_col_subgroup : method { + local ($_, %_); + my ($self, $form, $current, $label, $orig, $new, $submit, $mark, $colspan, $title); + #my ($col, $val, $colsn, $valsn, $title); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("subgroup"); + $colspan = $self->_colspan; + $submit = h_abbr(C_("Add a group")); + + # A form to create a new item + if ($self->{"type"} eq "new") { + $label = h_abbr(C_("[numerate,_1,Group member]:", 0)); + print << "EOT"; + + +EOT + print " "; + for ($_ = 0, @_ = qw(); defined $form->param("subgroup$_" . "sn"); $_++) { + if (defined($title = group_opt_label(scalar $form->param("subgroup$_" . "sn"), "subgroup$_"))) { + push @_, sprintf("
  • \n" + . " \n" + . " %4\$s\n" + . "
  • \n", + h($_), $self->_val_text("subgroup$_" . "sn"), + $self->_val_check("subgroup$_"), $title); + } else { + push @_, sprintf("
  • \n" + . " \n" + . " %4\$s\n" + . "
  • \n", + h($_), $self->_val_text("subgroup$_" . "sn"), + $self->_val_check("subgroup$_"), h_abbr(t_na)); + } + } + push @_, "
  • \n"; + print "
      \n" . join("", @_) . "
    \n "; + print << "EOT"; + + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + # Read-only for a non-super-user editing a super-user group + if (!is_su && $self->{"sn"} == su_group_sn) { + $label = h_abbr(C_("[numerate,_1,Group member]:", $_[0]->_delcolcount("subgroup"))); + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("subgroupcount"); $_++) { + push @_, "
  • " . $self->_cval_text("subgroup$_" . "title") . "
  • \n"; + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT + + } else { + $label = h_abbr(C_("[numerate,_1,Group member]:", 0)); + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + print << "EOT"; + + + $orig +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("subgroupcount"); $_++) { + push @_, "
  • " . $self->_cval_text("subgroup$_" . "title") . "
  • \n"; + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + + + +EOT + print " "; + for ($_ = 0, @_ = qw(); defined $form->param("subgroup$_" . "sn"); $_++) { + if (defined($title = group_opt_label(scalar $form->param("subgroup$_" . "sn"), "subgroup$_"))) { + push @_, sprintf("
  • \n" + . " \n" + . " %4\$s\n" + . "
  • \n", + h($_), $self->_val_text("subgroup$_" . "sn"), + $self->_val_check("subgroup$_"), $title); + } else { + push @_, sprintf("
  • \n" + . " \n" + . " %4\$s\n" + . "
  • \n", + h($_), $self->_val_text("subgroup$_" . "sn"), + $self->_val_check("subgroup$_"), h_abbr(t_na)); + } + } + push @_, "
  • \n"; + print "
      \n" . join("", @_) . "
    \n "; + print << "EOT"; + + +EOT + } + + # A form to delete a current item + } else { + $label = h_abbr(C_("[numerate,_1,Group member]:", $_[0]->_delcolcount("subgroup"))); + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("subgroupcount"); $_++) { + push @_, "
  • " . $self->_cval_text("subgroup$_" . "title") . "
  • \n"; + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT + } + return; +} + +# _html_col_supgroup: Its belonging groups +sub _html_col_supgroup : method { + local ($_, %_); + my ($self, $form, $current, $label, $orig, $new, $submit, $mark, $colspan, $title); + #my ($col, $val, $colsn, $valsn, $title); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("supgroup"); + $colspan = $self->_colspan; + $label = h_abbr(C_("Belonging to:")); + $submit = h_abbr(C_("Add a group")); + + # A form to create a new item + if ($self->{"type"} eq "new") { + print << "EOT"; + + +EOT + print " "; + for ($_ = 0, @_ = qw(); defined $form->param("supgroup$_" . "sn"); $_++) { + if (defined($title = group_opt_label(scalar $form->param("supgroup$_" . "sn"), "supgroup$_"))) { + push @_, sprintf("
  • \n" + . " \n" + . " %4\$s\n" + . "
  • \n", + h($_), $self->_val_text("supgroup$_" . "sn"), + $self->_val_check("supgroup$_"), $title); + } else { + push @_, sprintf("
  • \n" + . " \n" + . " %4\$s\n" + . "
  • \n", + h($_), $self->_val_text("supgroup$_" . "sn"), + $self->_val_check("supgroup$_"), h_abbr(t_na)); + } + } + push @_, "
  • \n"; + print "
      \n" . join("", @_) . "
    \n "; + print << "EOT"; + + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + # Read-only for a non-super-user editing a super-user group + if (!is_su && $self->{"sn"} == su_group_sn) { + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("supgroupcount"); $_++) { + push @_, "
  • " . $self->_cval_text("supgroup$_" . "title") . "
  • \n"; + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT + + } else { + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + print << "EOT"; + + + $orig +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("supgroupcount"); $_++) { + push @_, "
  • " . $self->_cval_text("supgroup$_" . "title") . "
  • \n"; + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + + + +EOT + print " "; + for ($_ = 0, @_ = qw(); defined $form->param("supgroup$_" . "sn"); $_++) { + if (defined($title = group_opt_label(scalar $form->param("supgroup$_" . "sn"), "supgroup$_"))) { + push @_, sprintf("
  • \n" + . " \n" + . " %4\$s\n" + . "
  • \n", + h($_), $self->_val_text("supgroup$_" . "sn"), + $self->_val_check("supgroup$_"), $title); + } else { + push @_, sprintf("
  • \n" + . " \n" + . " %4\$s\n" + . "
  • \n", + h($_), $self->_val_text("supgroup$_" . "sn"), + $self->_val_check("supgroup$_"), h_abbr(t_na)); + } + } + push @_, "
  • \n"; + print "
      \n" . join("", @_) . "
    \n "; + print << "EOT"; + + +EOT + } + + # A form to delete a current item + } else { + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("supgroupcount"); $_++) { + push @_, "
  • " . $self->_cval_text("supgroup$_" . "title") . "
  • \n"; + } + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT + } + return; +} + +return 1; diff --git a/lib/perl5/Selima/Form/GroupMem.pm b/lib/perl5/Selima/Form/GroupMem.pm new file mode 100644 index 0000000..a96fceb --- /dev/null +++ b/lib/perl5/Selima/Form/GroupMem.pm @@ -0,0 +1,93 @@ +# Selima Website Content Management System +# GroupMem.pm: The group-to-group membership form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +package Selima::Form::GroupMem; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; +use Selima::UserName; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "groupmem" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this membership record") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to add a new membership record."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to change a current membership record."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete a membership record."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(grp member)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn grp member + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Add A New Group Membership Record"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Change a Current Group Membership Record"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete a Group Membership Record"); + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_member: The member +sub _html_col_member : method { + $_[0]->_html_coltmpl_call("member", h_abbr(C_("Member:")), \&groupdsc); +} + +return 1; diff --git a/lib/perl5/Selima/Form/Guestbook.pm b/lib/perl5/Selima/Form/Guestbook.pm new file mode 100644 index 0000000..83b7bfa --- /dev/null +++ b/lib/perl5/Selima/Form/Guestbook.pm @@ -0,0 +1,116 @@ +# Selima Website Content Management System +# Guestbook.pm: The base administrative guestbook form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +package Selima::Form::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "guestbook" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this message") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to add a new message."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to edit a current message."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete a message."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(name identity location email url message hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn name identity location email url message hid + ip host ct pageno oldpageno + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Write a New Message"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Edit a Current Message"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete a Message"); + } + } + $self = $class->SUPER::new($status, $args); + ${$self->{"maxlens"}}{"message"} = 10240; + return $self; +} + +# _html_col_ct: The country +sub _html_col_ct : method { + $_[0]->_html_coltmpl_ro_ct("ct", h_abbr(C_("Country:"))); +} + +# _html_col_hid: Hide? +sub _html_col_hid : method { + $_[0]->_html_coltmpl_bool("hid", h_abbr(C_("Hide?")), + h_abbr(C_("Hide this message")), h_abbr(C_("Show this message")), + h_abbr(C_("Hide this message currently."))); +} + +# _html_col_name: The name +sub _html_col_name : method { + $_[0]->_html_coltmpl_text("name", h_abbr(C_("Signature:"))); +} + +# _html_col_oldpageno: The old page number +sub _html_col_oldpageno : method { + $_[0]->_html_coltmpl_ro("oldpageno", h_abbr(C_("Old page no.:"))); +} + +# _html_col_pageno: The page number +sub _html_col_pageno : method { + $_[0]->_html_coltmpl_ro("pageno", h_abbr(C_("Page no.:"))); +} + +return 1; diff --git a/lib/perl5/Selima/Form/Guestbook/Public.pm b/lib/perl5/Selima/Form/Guestbook/Public.pm new file mode 100644 index 0000000..fbbb6c0 --- /dev/null +++ b/lib/perl5/Selima/Form/Guestbook/Public.pm @@ -0,0 +1,86 @@ +# Selima Website Content Management System +# Public.pm: The base guestbook form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +package Selima::Form::Guestbook::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form::Guestbook); + +use Selima::DataVars qw(:lninfo); +use Selima::GetLang; +use Selima::HTTP; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + # This should always be always a new form + $$args{"type"} = "new" + if !exists $$args{"type"}; + $$args{"type_to_pass"} = undef + if !exists $$args{"type_to_pass"}; + $$args{"valid_types"} = [qw(new)] + if !exists $$args{"valid_types"}; + $$args{"table"} = "guestbook" + if !exists $$args{"table"}; + $$args{"header_buttons"} = [] + if !exists $$args{"header_buttons"}; + $$args{"footer_buttons"} = [ + { "name" => "submit", "value" => h(C_("Leave a messsage")) } ] + if !exists $$args{"footer_buttons"}; + $$args{"summary"} = C_("This table provides you a form to leave a message.") + if !exists $$args{"summary"}; + $$args{"onsubmit"} = "return isGuestbookOK(this);" + if !exists $$args{"onsubmit"}; + $$args{"cols"} = [qw(message name identity location email captcha url)] + if !exists $$args{"cols"}; + $$args{"auto_referer2"} = 0 + if !exists $$args{"auto_referer2"}; + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_message: The message +sub _html_col_message : method { + local ($_, %_); + my ($self, $val, $label, $default, $colspan, $hdef); + $self = $_[0]; + $colspan = $self->_colspan_full; + $default = C_("Fill in your message here."); + $val = $self->_val_textarea("message", $default); + $hdef = h($default); + print << "EOT"; + + + +EOT + return; +} + +return 1; diff --git a/lib/perl5/Selima/Form/Link.pm b/lib/perl5/Selima/Form/Link.pm new file mode 100644 index 0000000..6b0db94 --- /dev/null +++ b/lib/perl5/Selima/Form/Link.pm @@ -0,0 +1,190 @@ +# Selima Website Content Management System +# Link.pm: The related-link form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::Form::Link; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::ChkFunc; +use Selima::CommText; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::Links; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "links" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this related link") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to add a new related link."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to edit a current related link."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete a related link."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(title title_2ln url icon email + addr tel fax dsc hid cats)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn title title_2ln url icon email + addr tel fax dsc hid cats + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Add a New Related Link"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Edit a Current Related Link"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete a Related Link"); + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_cats: The categories +sub _html_col_cats : method { + $_[0]->_html_coltmpl_select_multi("cat", + h_abbr(C_("[numerate,_1,Category,Categories]:", $_[0]->_delcolcount("cat"))), + \&linkcat_options); +} + +# _html_col_hid: Hide? +sub _html_col_hid : method { + $_[0]->_html_coltmpl_bool("hid", h_abbr(C_("Hide?")), + h_abbr(C_("Hide this related link")), h_abbr(C_("Show this related link")), + h_abbr(C_("Hide this related link currently."))); +} + +# _html_col_icon: The link icon +sub _html_col_icon : method { + local ($_, %_); + my ($self, $label, $alt, $size, $mark, $colspan); + my ($cur, $preview, $val, $orig, $new); + $self = $_[0]; + $mark = $self->_mark("icon"); + $colspan = $self->_colspan; + $label = h_abbr(C_("Link icon:")); + $alt = h(C_("Link icon unavailable")); + $size = h($self->{"defsize"}); + $self->{"form"}->param("icon", "http://") + if $self->{"is_first_form"} && !defined $self->{"form"}->param("icon"); + + # A form to create a new item + if ($self->{"type"} eq "new") { + $val = $self->_val_text("icon", "icon"); + if (is_url_wellformed $self->{"form"}->param("icon")) { + $preview = "{"form"}->param("icon")) + . "\" alt=\"$alt\" />
    \n"; + } else { + $preview = ""; + } + print << "EOT"; + + + $preview + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $cur = $self->{"cur"}->param("icon"); + if (defined $cur) { + $cur = "\"$alt\"
    \n" + . " " . h($cur); + } else { + $cur = h_abbr(t_none); + } + $val = $self->_val_text("icon", "icon"); + if (is_url_wellformed $self->{"form"}->param("icon")) { + $preview = "{"form"}->param("icon")) + . "\" alt=\"$alt\" />
    \n"; + } else { + $preview = ""; + } + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + print << "EOT"; + + + $orig + $cur + + + + $preview + +EOT + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $cur = $self->{"cur"}->param("icon"); + if (defined $cur) { + $cur = "\"$alt\"
    \n" + . " " . h($cur); + } else { + $cur = h_abbr(t_none); + } + print << "EOT"; + + $mark$label + $cur + +EOT + } + return; +} + +# _html_col_title_2ln: Title in the second language +sub _html_col_title_2ln : method { + $_[0]->_html_coltmpl_text("title_2ln", h_abbr(C_("2nd language title:"))); +} + +return 1; diff --git a/lib/perl5/Selima/Form/LinkCat.pm b/lib/perl5/Selima/Form/LinkCat.pm new file mode 100644 index 0000000..1f80893 --- /dev/null +++ b/lib/perl5/Selima/Form/LinkCat.pm @@ -0,0 +1,145 @@ +# Selima Website Content Management System +# LinkCat.pm: The related-link category form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::Form::LinkCat; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::CommText; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "linkcat" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this category") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to add a new category."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to edit a current category."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete a category."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(parent id ord title kw hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn parent id ord title kw hid + scats links + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Add a New Link Category"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Edit a Current Link Category"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete a Link Category"); + } + } + $self = $class->SUPER::new($status, $args); + ${$self->{"maxlens"}}{"ord"} = 2; + if ($self->{"type"} eq "cur") { + if (defined $self->{"cur"}->param("scatcount") && $self->{"cur"}->param("scatcount") > 0) { + $self->{"nodelete"} = 1; + push @{$self->{"prefmsg"}}, C_("This category has [numerate,_1,a subcategory,subcategories]. It cannot be deleted. To delete the category, [numerate,_1,its subcategory,all of its subcategories] must first be deleted.", $self->{"cur"}->param("scatcount")); + } + if (defined $self->{"cur"}->param("linkcount") && $self->{"cur"}->param("linkcount") > 0) { + $self->{"nodelete"} = 1; + push @{$self->{"prefmsg"}}, C_("This category has [numerate,_1,a link,links]. It cannot be deleted. To delete the category, [numerate,_1,its link,all of its links] must first be deleted.", $self->{"cur"}->param("linkcount")); + } + } + return $self; +} + +# _html_col_hid: Hide? +sub _html_col_hid : method { + $_[0]->_html_coltmpl_bool("hid", h_abbr(C_("Hide?")), + h_abbr(C_("Hide this category")), h_abbr(C_("Show this category")), + h_abbr(C_("Hide this category currently."))); +} + +# _html_col_id: The ID. +sub _html_col_id : method { + $_[0]->_html_coltmpl_text("id", h_abbr(C_("ID.:")), undef, 8); +} + +# _html_col_links: The links +sub _html_col_links : method { + my ($self, $form, $current, $label, $mark, $colspan, $thclass, $thcolspan); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("links"); + $colspan = $self->_colspan; + $label = h_abbr(C_("[numerate,_1,Link,Links]:", $current->param("linkcount"))); + # A current form span for 2 columns + $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; + $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; + + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("linkcount"); $_++) { + push @_, sprintf("
  • %2\$s\n" + . " (%3\$s)\n" + . "
  • \n", + h("links.cgi?form=cur&sn=" . $current->param("link$_" . "sn")), + h_abbr($current->param("link$_" . "title")), + h($current->param("link$_" . "url"))); + } + print @_ > 0? "
      \n" . join("", @_) ."
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT +} + +return 1; diff --git a/lib/perl5/Selima/Form/LinkCatz.pm b/lib/perl5/Selima/Form/LinkCatz.pm new file mode 100644 index 0000000..20b7ff9 --- /dev/null +++ b/lib/perl5/Selima/Form/LinkCatz.pm @@ -0,0 +1,98 @@ +# Selima Website Content Management System +# LinkCatz.pm: The related-link category membership form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-25 + +package Selima::Form::LinkCatz; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::Links; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "linkcatz" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this categorization record") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to add a new categorization record."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to change a current categorization record."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete a categorization record."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(cat link)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn cat link + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Add A New Link Categorization Record"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Change a Current Link Categorization Record"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete a Link Categorization Record"); + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_cat: The category +sub _html_col_cat : method { + $_[0]->_html_coltmpl_call("cat", h_abbr(C_("Category:")), \&linkcat_title); +} + +# _html_col_link: The link +sub _html_col_link : method { + $_[0]->_html_coltmpl_call("link", h_abbr(C_("Link:")), \&link_title); +} + +return 1; diff --git a/lib/perl5/Selima/Form/Page.pm b/lib/perl5/Selima/Form/Page.pm new file mode 100644 index 0000000..84efc71 --- /dev/null +++ b/lib/perl5/Selima/Form/Page.pm @@ -0,0 +1,100 @@ +# Selima Website Content Management System +# Page.pm: The base web page form. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-28 + +package Selima::Form::Page; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "pages" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this page") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to write a new page."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to edit a current page."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete a page."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(path ord title body kw html hid)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn path ord title body kw html hid + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Write a New Page"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Edit a Current Page"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete a Page"); + } + } + if (!exists $$args{"preview"}) { + $$args{"preview"} = 1; + } + if ($$args{"preview"} && !exists $$args{"prevmsg"}) { + $$args{"prevmsg"} = C_("Preview this page."); + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_hid: Hide? +sub _html_col_hid : method { + $_[0]->_html_coltmpl_bool("hid", h_abbr(C_("Hide?")), + h_abbr(C_("Hide this page")), h_abbr(C_("Show this page")), + h_abbr(C_("Hide this page currently."))); +} + +return 1; diff --git a/lib/perl5/Selima/Form/Rebuild.pm b/lib/perl5/Selima/Form/Rebuild.pm new file mode 100644 index 0000000..bfb178f --- /dev/null +++ b/lib/perl5/Selima/Form/Rebuild.pm @@ -0,0 +1,70 @@ +# Selima Website Content Management System +# Rebuild.pm: The web page rebuild form. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-04 + +package Selima::Form::Rebuild; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::PageFunc; +use Selima::ShortCut; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = "new" + if !exists $$args{"type"}; + $$args{"type_to_pass"} = undef + if !exists $$args{"type_to_pass"}; + $$args{"valid_types"} = [qw(new)] + if !exists $$args{"valid_types"}; + $$args{"cols"} = [qw(type)] + if !exists $$args{"cols"}; + $$args{"title"} = C_("Rebuild the Pages") + if !exists $$args{"title"}; + $$args{"header_buttons"} = [] + if !exists $$args{"header_buttons"}; + $$args{"footer_buttons"} = [ + { "name" => "confirm", "value" => h(C_("Confirm")) }, + { "name" => "cancel", "value" => h(C_("Cancel")) } ] + if !exists $$args{"footer_buttons"}; + $$args{"auto_referer2"} = 0 + if !exists $$args{"auto_referer2"}; + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_type: The page type +sub _html_col_type : method { + $_[0]->_html_coltmpl_select("type", h_abbr(C_("Type:")), + \&rebuildtype_options, undef); +} + +return 1; diff --git a/lib/perl5/Selima/Form/ScptPriv.pm b/lib/perl5/Selima/Form/ScptPriv.pm new file mode 100644 index 0000000..3c74deb --- /dev/null +++ b/lib/perl5/Selima/Form/ScptPriv.pm @@ -0,0 +1,93 @@ +# Selima Website Content Management System +# ScptPriv.pm: The script privilege form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +package Selima::Form::ScptPriv; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; +use Selima::UserName; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "scptpriv" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this script privilege record") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to add a new script privilege record."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to change a current script privilege record."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete a script privilege record."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(script grp)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn script grp + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Add A New Script Privilege Record"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Change a Current Script Privilege Record"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete a Script Privilege Record"); + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_grp: The privileged group +sub _html_col_grp : method { + $_[0]->_html_coltmpl_call("grp", h_abbr(C_("Privilege:")), \&groupdsc); +} + +return 1; diff --git a/lib/perl5/Selima/Form/User.pm b/lib/perl5/Selima/Form/User.pm new file mode 100644 index 0000000..a5ab3c5 --- /dev/null +++ b/lib/perl5/Selima/Form/User.pm @@ -0,0 +1,389 @@ +# Selima Website Content Management System +# User.pm: The user account form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-30 + +package Selima::Form::User; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::ChkPriv; +use Selima::CommText; +use Selima::DataVars qw($DBH :groups :l10n :lninfo); +use Selima::FormFunc; +use Selima::GetLang; +use Selima::HTTP; +use Selima::LnInfo; +use Selima::LogIn; +use Selima::MarkAbbr; +use Selima::ShortCut; +use Selima::UserName; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "users" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this user account") + if !exists $$args{"deltext"}; + $$args{"https"} = ($$args{"type"} ne "del") + if !exists $$args{"https"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to add a new user account."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to update a current user account."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete a user account."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(id passwd name disabled supgroup)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn id passwd name disabled supgroup + admin lang visits visited ip host ct + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Add a New User Account"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Update a Current User Account"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete a User Account"); + } + } + $self = $class->SUPER::new($status, $args); + ${$self->{"maxlens"}}{"passwd"} = 16; + if ( $$args{"type"} eq "cur" && !is_su + && ($self->{"cur"}->param("su") || $self->{"sn"} == get_login_sn)) { + $self->{"nodelete"} = 1; + push @{$self->{"prefmsg"}}, C_("This is a super-user. You can only change parts of her/his infomation.") + if $self->{"cur"}->param("su"); + } + # Set all the available belonging groups list + $self->_set_supgroup_list(); + return $self; +} + +# _set_supgroup_list: Set all the available belonging groups list +sub _set_supgroup_list : method { + local ($_, %_); + my ($self, $form, %checked, $sth, $sql, $count); + my ($lndb, $lndbdef, $title); + $self = $_[0]; + $form = $self->{"form"}; + # Get the list of checked groups + %checked = qw(); + for ($_ = 0; defined $form->param("supgroup$_" . "sn"); $_++) { + $checked{$form->param("supgroup$_" . "sn")} = 1 + if defined $form->param("supgroup$_"); + } + + # Remove the old groups list + foreach ($form->param) { + $form->delete($_) if /^supgroup/; + } + + # Get the list of all groups + if (@ALL_LINGUAS > 1) { + $lndb = getlang LN_DATABASE; + if (getlang eq $DEFAULT_LANG) { + $title = $DBH->strcat("id", "' ('", "dsc_$lndb", "')'"); + } else { + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + $title = $DBH->strcat("id", "' ('", + "COALESCE(dsc_$lndb, dsc_$lndbdef)", "')'"); + } + } else { + $title = $DBH->strcat("id", "' ('", "dsc", "')'"); + } + $sql = "SELECT sn AS sn, $title AS title FROM groups" + . " WHERE id!=" . $DBH->quote(SU_GROUP) + . " AND id!=" . $DBH->quote(ADMIN_GROUP) + . " AND id!=" . $DBH->quote(ALLUSERS_GROUP) + . " ORDER BY id;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0; $_ < $count; $_++) { + %_ = %{$sth->fetchrow_hashref}; + $form->param("supgroup$_" . "sn", $_{"sn"}); + $form->param("supgroup$_" . "title", $_{"title"}); + $form->param("supgroup$_", 1) if exists $checked{$_{"sn"}}; + } + return; +} + +# _html_col_admin: Is this user an administrator? +sub _html_col_admin : method { + $_[0]->_html_coltmpl_ro_bool("admin", h_abbr(C_("Administrator?")), + h_abbr(C_("Administrator")), h_abbr(C_("Non-administrator"))); +} + +# _html_col_ct: The country +sub _html_col_ct : method { + $_[0]->_html_coltmpl_ro_ct("ct", h_abbr(C_("Country:"))); +} + +# _html_col_disabled: Disabled? +sub _html_col_disabled : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Read-only for a non-super-user editing herself or a super-user + if ( $self->{"type"} eq "cur" && !is_su + && ($self->{"cur"}->param("su") || $self->{"sn"} == get_login_sn)) { + $self->_html_coltmpl_ro_bool("disabled", h_abbr(C_("Disabled?")), + h_abbr(C_("Disabled")), h_abbr(C_("Enabled"))); + } else { + $self->_html_coltmpl_bool("disabled", h_abbr(C_("Disabled?")), + h_abbr(C_("Disabled")), h_abbr(C_("Enabled")), + h_abbr(C_("Disable this user account."))); + } +} + +# _html_col_id: The user ID. +sub _html_col_id : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Read-only for a non-super-user editing a super-user + if ($self->{"type"} eq "cur" && !is_su && $self->{"cur"}->param("su")) { + $self->_html_coltmpl_ro("id", h_abbr(C_("User ID.:"))); + } else { + $self->_html_coltmpl_text("id", h_abbr(C_("User ID.:"))); + } +} + +# _html_col_lang: The preferred language +sub _html_col_lang : method { + $_[0]->_html_coltmpl_ro_lang("lang", h_abbr(C_("Pref. language:"))); +} + +# _html_col_name: The name +sub _html_col_name : method { + $_[0]->_html_coltmpl_text("name", h_abbr(C_("Full name:"))); +} + +# _html_col_passwd: The password +sub _html_col_passwd : method { + local ($_, %_); + my ($self, $label, $dummy, $mark, $colspan); + $self = $_[0]; + # Read-only for a non-super-user editing a super-user + if ($self->{"type"} eq "cur" && !is_su && $self->{"cur"}->param("su")) { + $mark = $self->_mark("passwd"); + $colspan = $self->_colspan; + $label = h_abbr(C_("Password:")); + $dummy = h("*" x ${$self->{"maxlens"}}{"passwd"}); + print << "EOT"; + + $mark$label + $dummy + +EOT + } else { + $self->SUPER::_html_col_passwd(); + } +} + +# _html_col_supgroup: Its belonging groups +sub _html_col_supgroup : method { + local ($_, %_); + my ($self, $form, $current, $label, $orig, $new, $mark, $colspan); + $self = $_[0]; + $form = $self->{"form"}; + $current = $self->{"cur"}; + $mark = $self->_mark("supgroup"); + $colspan = $self->_colspan; + $label = h_abbr(C_("Belonging to:")); + + # A form to create a new item + if ($self->{"type"} eq "new") { + print << "EOT"; + + +EOT + print " "; + for ($_ = 0, @_ = qw(); defined $form->param("supgroup$_" . "sn"); $_++) { + push @_, sprintf("
  • \n" + . " \n" + . " \n" + . "
  • \n", + h($_), $self->_val_text("supgroup$_" . "sn"), + $self->_val_check("supgroup$_"), + h_abbr($form->param("supgroup$_" . "title"))); + } + # Only super users can set the super-user group + if (su_group_sn != 0) { + if (is_su) { + push @_, sprintf("
  • \n" + . " %s\n" + . "
  • \n", + $self->_val_check("su"), + group_opt_label(su_group_sn, "su")); + } else { + push @_, sprintf("
  • \n" + . " %s\n" + . "
  • \n", + group_opt_label(su_group_sn)); + } + } + # Attach the all-users group in any case + push @_, sprintf("
  • \n" + . " %s\n" + . "
  • \n", + group_opt_label(groupsn(ALLUSERS_GROUP))) + if defined groupsn(ALLUSERS_GROUP); + print "
      \n" . join("", @_) . "
    \n "; + print << "EOT"; + + +EOT + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + # Read-only for a non-super-user editing herself or a super-user + if (!is_su && $self->{"sn"} == get_login_sn) { + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("supgroupcount"); $_++) { + push @_, "
  • " . h_abbr($current->param("supgroup$_" . "title")) . "
  • \n"; + } + push @_, "
  • " . group_opt_label(su_group_sn) . "
  • \n" + if $current->param("su"); + push @_, "
  • " . group_opt_label(groupsn(ALLUSERS_GROUP)) . "
  • \n" + if defined groupsn(ALLUSERS_GROUP); + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT + + } else { + $orig = h_abbr(C_("Original:")); + $new = h_abbr(C_("New:")); + print << "EOT"; + + + $orig +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("supgroupcount"); $_++) { + push @_, "
  • " . h_abbr($current->param("supgroup$_" . "title")) . "
  • \n"; + } + push @_, "
  • " . group_opt_label(su_group_sn) . "
  • \n" + if $current->param("su"); + push @_, "
  • " . group_opt_label(groupsn(ALLUSERS_GROUP)) . "
  • \n" + if defined groupsn(ALLUSERS_GROUP); + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + + + +EOT + print " "; + for ($_ = 0, @_ = qw(); defined $form->param("supgroup$_" . "sn"); $_++) { + push @_, sprintf("
  • \n" + . " \n" + . " \n" + . "
  • \n", + h($_), $self->_val_text("supgroup$_" . "sn"), + $self->_val_check("supgroup$_"), + h_abbr($form->param("supgroup$_" . "title"))); + } + # Only super users can set the super-user group + if (su_group_sn != 0) { + if (is_su) { + push @_, sprintf("
  • \n" + . " %s\n" + . "
  • \n", + $self->_val_check("su"), + group_opt_label(su_group_sn, "su")); + } else { + push @_, sprintf("
  • \n" + . " %s\n" + . "
  • \n", + $current->param("su")? " checked=\"checked\"": "", + group_opt_label(su_group_sn)); + } + } + # Attach the all-users group in any case + push @_, sprintf("
  • \n" + . " %s\n" + . "
  • \n", + group_opt_label(groupsn(ALLUSERS_GROUP))) + if defined groupsn(ALLUSERS_GROUP); + print "
      \n" . join("", @_) . "
    \n "; + print << "EOT"; + + +EOT + } + + # A form to delete a current item + } else { + print << "EOT"; + + $mark$label +EOT + print " "; + for ($_ = 0, @_ = qw(); $_ < $current->param("supgroupcount"); $_++) { + push @_, "
  • " . h_abbr($current->param("supgroup$_" . "title")) . "
  • \n"; + } + push @_, "
  • " . group_opt_label(su_group_sn) . "
  • \n" + if $current->param("su"); + push @_, "
  • " . group_opt_label(groupsn(ALLUSERS_GROUP)) . "
  • \n" + if defined groupsn(ALLUSERS_GROUP); + print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); + print << "EOT"; + + +EOT + } + return; +} + +return 1; diff --git a/lib/perl5/Selima/Form/UserMem.pm b/lib/perl5/Selima/Form/UserMem.pm new file mode 100644 index 0000000..c22a0b4 --- /dev/null +++ b/lib/perl5/Selima/Form/UserMem.pm @@ -0,0 +1,93 @@ +# Selima Website Content Management System +# UserMem.pm: The user-to-group membership form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +package Selima::Form::UserMem; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; +use Selima::UserName; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "usermem" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this membership record") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to add a new membership record."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to change a current membership record."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete a membership record."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(grp member)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn grp member + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Add A New User Membership Record"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Change a Current User Membership Record"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete a User Membership Record"); + } + } + $self = $class->SUPER::new($status, $args); + return $self; +} + +# _html_col_member: The member +sub _html_col_member : method { + $_[0]->_html_coltmpl_call("member", h_abbr(C_("Member:")), \&username); +} + +return 1; diff --git a/lib/perl5/Selima/Form/UserPref.pm b/lib/perl5/Selima/Form/UserPref.pm new file mode 100644 index 0000000..5927da6 --- /dev/null +++ b/lib/perl5/Selima/Form/UserPref.pm @@ -0,0 +1,111 @@ +# Selima Website Content Management System +# UserPref.pm: The user preference form. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +package Selima::Form::UserPref; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Form); + +use Selima::DataVars qw(:scptconf); +use Selima::FormFunc; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::ShortCut; +use Selima::Unicode; +use Selima::UserName; + +# new: Initialize the HTML form table displayer +sub new : method { + local ($_, %_); + my ($class, $status, $args, $self); + ($class, $status, $args) = @_; + $args = {} if !defined $args; + + # $args must be a hash reference + http_500 "type of argument 2 must be a hash reference" + if ref($args) ne "HASH"; + $$args{"type"} = form_type + if !exists $$args{"type"}; + $$args{"table"} = "usermem" + if !exists $$args{"table"}; + $$args{"deltext"} = C_("Delete this user preference") + if !exists $$args{"deltext"}; + if (!exists $$args{"summary"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"summary"} = C_("This table provides you a form to add a new user preference."); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"summary"} = C_("This table provides you a form to modify a current user preference."); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"summary"} = C_("This table provides you a form to delete a user preference."); + } + } + if (!exists $$args{"cols"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"cols"} = [qw(usr domain name value)]; + # A form to edit a current item + # A form to delete a current item + } elsif ($$args{"type"} eq "cur" || $$args{"type"} eq "del") { + $$args{"cols"} = [qw(sn usr domain name value + created createdby updated updatedby)]; + } + } + if (!exists $$args{"title"}) { + # A form to create a new item + if ($$args{"type"} eq "new") { + $$args{"title"} = C_("Add A New User Preference"); + # A form to edit a current item + } elsif ($$args{"type"} eq "cur") { + $$args{"title"} = C_("Modify a Current User Preference"); + # A form to delete a current item + } elsif ($$args{"type"} eq "del") { + $$args{"title"} = C_("Delete a User Preference"); + } + } + $self = $class->SUPER::new($status, $args); + $self->{"form"}->delete("usr") + if defined $self->{"form"}->param("usr") + && (!defined $self->{"form"}->param("usr") + || $self->{"form"}->param("usr") eq ""); + return $self; +} + +# _html_col_domain: The preference domain +sub _html_col_domain : method { + $_[0]->_html_coltmpl_text_null("domain", h_abbr(C_("Domain:")), + "everywhere", h_abbr(C_("Everywhere"))); +} + +# _html_col_usr: The user +sub _html_col_usr : method { + $_[0]->_html_coltmpl_call_null("usr", h_abbr(C_("User:")), + "everyone", h_abbr(C_("Everyone")), \&username); +} + +# _html_col_value: The preference value +sub _html_col_value : method { + $_[0]->_html_coltmpl_text("value", h_abbr(C_("Value:"))); +} + +return 1; diff --git a/lib/perl5/Selima/FormFunc.pm b/lib/perl5/Selima/FormFunc.pm new file mode 100644 index 0000000..b603749 --- /dev/null +++ b/lib/perl5/Selima/FormFunc.pm @@ -0,0 +1,115 @@ +# Selima Website Content Management System +# FormFunc.pm: The form-related functions. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-24 + +package Selima::FormFunc; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(get_or_post curform is_form form_type); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub get_or_post(); +sub curform(); +sub is_form(;$); +sub form_type(); +} + +use Selima::Cache qw(:formfunc); +use Selima::CallForm; +use Selima::DataVars qw(:env :input); + +# get_or_post: whether we should look for form data from $GET or $POST +sub get_or_post() { + local ($_, %_); + return $FormFunc_get_or_post if defined $FormFunc_get_or_post; + $_ = $IS_MODPERL? ($IS_MP2? + Apache2::RequestUtil->request->method: Apache->request->method): + $ENV{"REQUEST_METHOD"}; + return ($FormFunc_get_or_post = $_ eq "POST"? $POST: $GET); +} + +# curform: Obtain the current form, either from the sent form or +# from the suspended form +sub curform() { + local ($_, %_); + + return $FormFunc_curform if defined $FormFunc_curform; + + $FormFunc_curform = get_or_post; + $FormFunc_curform = retrieve_form + if defined $FormFunc_curform->param("formid"); + + return $FormFunc_curform; +} + +# is_form: whether this is a form +sub is_form(;$) { + local ($_, %_); + my ($isform, $FORM); + $isform = $_[0]; + + # Use "isform" to alter the cache + if (defined $isform) { + # A status is provided + if (ref $isform eq "HASH") { + $FormFunc_isform = $$isform{"isform"}? 1: 0 + if exists $$isform{"isform"}; + # A scalar value + } else { + $FormFunc_isform = $isform? 1: 0; + } + } + + # Return the cache + return $FormFunc_isform if defined $FormFunc_isform; + + # Obtain the current form + $FORM = curform; + # No valid form infomation + return ($FormFunc_isform = 0) if !defined $FORM->param("form"); + # "isform" was specified + if ( defined $FORM->param("status") + && exists ${$FORM->param("status")}{"isform"}) { + return ($FormFunc_isform = ${$FORM->param("status")}{"isform"}? 1: 0); + } + + return ($FormFunc_isform = 1); +} + +# form_type: Return the form name (new, cur, del, listpref... etc) +sub form_type() { + local ($_, %_); + + # Return the cache + return $FormFunc_formtype if defined $FormFunc_formtype; + + # Obtain the current form + $_ = curform; + # Form type specified in arguments + return ($FormFunc_formtype = $_->param("form")) + if defined $_->param("form"); + # No form source is found + return ($FormFunc_formtype = -1); +} + +return 1; diff --git a/lib/perl5/Selima/Format.pm b/lib/perl5/Selima/Format.pm new file mode 100644 index 0000000..ad22563 --- /dev/null +++ b/lib/perl5/Selima/Format.pm @@ -0,0 +1,197 @@ +# Selima Website Content Management System +# Format.pm: The data formatters. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-23 + +package Selima::Format; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(fmtno fmtsize fmtdate fmttime rdtime); +push @EXPORT, qw(myfmtdate myfmttime fmtntamount); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub fmtno($); +sub fmtsize($); +sub fmtdate(;$); +sub fmttime(;$); +sub rdtime($); +sub myfmtdate(;$); +sub myfmttime(;$); +sub fmtntamount($); +} + +use Time::Local qw(timelocal); + +use Selima::ShortCut; + +# fmtno: Format the number +sub fmtno($) { + local ($_, %_); + $_ = $_[0]; + 1 while s/^(\d+)(\d{3})/$1,$2/; + return $_; +} + +# fmtsize: Format the size +sub fmtsize($) { + local ($_, %_); + my ($report, $size, $kb, $mb, $gb, $tb, $digits, $rounded); + $size = $_[0]; + # Get the size + $report = C_("[#,_1] bytes", $size); + + # Try to use KB as the unit + $kb = $size / 1024; + # Bounce if there are fewer than 3 digits in the rounded result + return $report if sprintf("%0.0f", $kb * 100) < 100; + # Check the rounded result for each digit + for ($_ = 2; $_ >= 0; $_--) { + $digits = 10 ** $_; + $rounded = sprintf "%0.0f", $kb * $digits; + # There are 3 significient digits in the rounded result + return sprintf "%s (%." . $_ . "f KB)", $report, $rounded / $digits + if $rounded < 1000; + } + + # Try to use MB as the unit + $mb = $kb / 1024; + # Check each digit + for ($_ = 2; $_ >= 0; $_--) { + $digits = 10 ** $_; + $rounded = sprintf "%0.0f", $mb * $digits; + # There are 3 significient digits in the rounded result + return sprintf "%s (%." . $_ . "f MB)", $report, $rounded / $digits + if $rounded < 1000; + } + + # Try to use GB as the unit + $gb = $mb / 1024; + # Check each digit + for ($_ = 2; $_ >= 0; $_--) { + $digits = 10 ** $_; + $rounded = sprintf "%0.0f", $gb * $digits; + # There are 3 significient digits in the rounded result + return sprintf "%s (%." . $_ . "f GB)", $report, $rounded / $digits + if $rounded < 1000; + } + + # Try to use TB as the unit + $tb = $gb / 1024; + # Check each digit + for ($_ = 2; $_ >= 0; $_--) { + $digits = 10 ** $_; + $rounded = sprintf "%0.0f", $tb * $digits; + # There are 3 significient digits in the rounded result + return sprintf "%s (%." . $_ . "f TB)", $report, $rounded / $digits + if $rounded < 1000; + } + + # More than TB + return sprintf "%s (%0.0f TB)", $report, fmtno $tb; +} + +# fmtdate: Format the date with the standard ISO format YYYY-MM-DD +sub fmtdate(;$) { + @_ = defined $_[0]? localtime $_[0]: localtime; + return sprintf "%04d-%02d-%02d", + $_[5]+1900, $_[4]+1, $_[3]; +} + +# fmttime: Format the time with the standard ISO format YYYY-MM-DD HH:MM:SS +sub fmttime(;$) { + local ($_, %_); + if (defined $_[0]) { + $_ = $_[0]; + @_ = localtime $_; + $_ = $_ - int $_; + } else { + @_ = localtime; + $_ = 0; + } + $_[5] += 1900; + $_[4]++; + return sprintf "%04d-%02d-%02d %02d:%02d:%02d", @_[5,4,3,2,1,0] + if $_ == 0; + return sprintf "%04d-%02d-%02d %02d:%02d:%02d.%06d", + @_[5,4,3,2,1,0], $_ * 1000000; +} + +# rdtime: Read the time with the standard ISO format YYYY-MM-DD HH:MM:SS +sub rdtime($) { + # Not in a correct format + return 0 if $_[0] !~ /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/; + return timelocal($6, $5, $4, $3, $2-1, $1-1900); +} + +# myfmtdate: Format the date with my personal format +sub myfmtdate(;$) { + local ($_, %_); + if (defined $_[0]) { + # TODO: + # Actually the timestamp column should be changed to + # timestamp with time zone. But that requires a lot of + # changes, and I have no time for that now. + # imacat 2013-06-27 + #@_ = localtime $_[0]; + @_ = gmtime $_[0]; + } else { + @_ = localtime; + } + $_[5] = ($_[5]+1900) % 100; + $_[4]++; + return sprintf "%d.%d.’%02d.", $_[4], $_[3], $_[5]; +} + +# myfmttime: Format the time with my personal format +sub myfmttime(;$) { + local ($_, %_); + if (defined $_[0]) { + # TODO: + # Actually the timestamp column should be changed to + # timestamp with time zone. But that requires a lot of + # changes, and I have no time for that now. + # imacat 2013-06-27 + #@_ = localtime $_[0]; + @_ = gmtime $_[0]; + } else { + @_ = localtime; + } + $_[5] = ($_[5]+1900) % 100; + $_[4]++; + $_[0] = ($_[2] < 12)? "am": "pm"; + $_[2] = ($_[2] > 12)? $_[2]-12: $_[2]; + return sprintf "%d.%d.’%02d. %d:%02d%s.", + $_[4], $_[3], $_[5], $_[2], $_[1], $_[0]; +} + +# fmtntamount: Format an amount of money in NTD format +sub fmtntamount($) { + local ($_, %_); + $_ = $_[0]; + 1 while s/^(\d+)(\d{3})/$1,$2/; + return "NT\$ $_.00"; +} + +no utf8; +return 1; diff --git a/lib/perl5/Selima/GeoIP.pm b/lib/perl5/Selima/GeoIP.pm new file mode 100644 index 0000000..62c4c61 --- /dev/null +++ b/lib/perl5/Selima/GeoIP.pm @@ -0,0 +1,73 @@ +# Selima Website Content Management System +# GeoIP.pm: The GeoIP-related subroutines. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +package Selima::GeoIP; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(country_lookup); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub country_lookup(;$); +} + +use Geo::IP qw(GEOIP_MEMORY_CACHE); +use Net::CIDR::Lite qw(); + +BEGIN { +if (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + require Apache2::Connection; +} +} + +use Selima::DataVars qw(:env); + +use vars qw($PRIVATE_NETWORKS); +$PRIVATE_NETWORKS = Net::CIDR::Lite->new( + qw(10.0.0.0/8 172.16.0.0/12 192.168.0.0/16)); + +use constant CT_PRIVATE => "AA"; +use constant CT_UNKNOWN => "ZZ"; + +# country_lookup: Look-up country from IP +sub country_lookup(;$) { + local ($_, %_); + my ($GI, $ip, $ct); + $ip = $_[0]; + # Default to look up the client + $ip = $IS_MODPERL? ($IS_MP2? + Apache2::RequestUtil->request->connection->remote_ip: + Apache->request->connection->remote_ip): + $ENV{"REMOTE_ADDR"} + if !defined $ip; + # Start a new GeoIP handler. It rarely needs to be cached + $GI = Geo::IP->new(GEOIP_MEMORY_CACHE); + # Look up in the GeoIP database + return uc $_ if defined($_ = $GI->country_code_by_addr($ip)); + # Look up private IP + return CT_PRIVATE if $PRIVATE_NETWORKS->find($ip); + # Not known + return CT_UNKNOWN; +} + +return 1; diff --git a/lib/perl5/Selima/GetLang.pm b/lib/perl5/Selima/GetLang.pm new file mode 100644 index 0000000..508cd2c --- /dev/null +++ b/lib/perl5/Selima/GetLang.pm @@ -0,0 +1,303 @@ +# Selima Website Content Management System +# GetLang.pm: The subroutine to match the user preferred languages with our available languages. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-23 + +package Selima::GetLang; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(getlang getcharset); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub getlang(;$); +sub getcharset(); +sub getlang_real(); +sub getlang_filename(); +sub getlang_env(); +sub getlang_accept(); +sub getlang_setenv($); +sub getcharset_accept(); +sub all_charsets(); +} + +use CGI::Cookie qw(); + +use Selima::Cache qw(:getlang); +use Selima::DataVars qw(:input :l10n :lninfo :output :requri); +use Selima::LnInfo; + +# getlang: Get the appropriate language from the user-agent +sub getlang(;$) { + local ($_, %_); + $_ = $_[0]; + # Return the proper data type + return defined $_? ln(getlang_real, $_): getlang_real; +} + +# getcharset: Get the appropriate character set from the user-agent. +sub getcharset() { + local ($_, %_); + my $default; + # Obtained before + return $GetLang_charset if defined $GetLang_charset; + $default = getlang(LN_CHARSET); + + # We have no choice + return ($GetLang_charset = $default) if all_charsets < 2; + # Parse the character set by the Accept-Charset header + return $GetLang_charset if defined($GetLang_charset = getcharset_accept); + # Cannot parse -- return the default + return ($GetLang_charset = $default); +} + +# getlang_real: The real subroutine +sub getlang_real() { + local ($_, %_); + # Obtained before + return $GetLang_lang if defined $GetLang_lang; + + # Uni-lingual + return ($GetLang_lang = $DEFAULT_LANG) if @ALL_LINGUAS == 1; + # Check the file name for specified language + # No setting environment in this case + return $GetLang_lang if defined($GetLang_lang = getlang_filename); + # Methods below should set the language in the environment + # Check the environment for specified language + if (defined($GetLang_lang = getlang_env)) { + getlang_setenv $GetLang_lang; + return $GetLang_lang; + } + # Parse the language by the Accept-Language header + if (defined($GetLang_lang = getlang_accept)) { + getlang_setenv $GetLang_lang; + return $GetLang_lang; + } + # Cannot parse -- return the default + $GetLang_lang = $DEFAULT_LANG; + getlang_setenv $GetLang_lang; + return $GetLang_lang; +} + +# getlang_filename: Check the file name for specified language +sub getlang_filename() { + local ($_, %_); + my $langfile; + # Check the file name format + return undef unless defined $REQUEST_PATH && $REQUEST_PATH =~ /\.([^\.\/]+)\.[^\.\/]+$/; + $langfile = $1; + # Check each language for its file name format + @_ = grep $langfile = $_, map ln($_, LN_FILENAME), @ALL_LINGUAS; + return $_[0] if @_ > 0; + # Not found + return undef; +} + +# getlang_env: Check the environment for specified language +sub getlang_env() { + local ($_, %_); + %_ = map { $_ => 1 } @ALL_LINGUAS; + # Check the query string + return $_ if defined $GET + && defined($_ = $GET->param("lang")) && exists $_{$_}; + # Check the POSTed form + return $_ if defined $POST + && defined($_ = $POST->param("lang")) && exists $_{$_}; + # Check the cookies + return $_ if exists $COOKIES{"lang"} + && exists $_{$_ = $COOKIES{"lang"}->value}; + # Not set + return undef; +} + +# getlang_accept: Parse the language by the Accept-Language header +# Refer to HTTP/1.1 section 14.4 for this algorism +sub getlang_accept() { + local ($_, %_); + my (@rngs, %rngqf, $defqf, $ln, @attrs, %tagqf, $tag, $match); + # Accept-Language not set + return undef if !exists $ENV{"HTTP_ACCEPT_LANGUAGE"}; + + # Split into language ranges + $_ = $ENV{"HTTP_ACCEPT_LANGUAGE"}; + s/^\s*(.*?)\s*$/$1/; + @rngs = split /\s*,\s*/, $_; + %rngqf = qw(); + foreach my $range (@rngs) { + # Split into attributes + $range =~ s/^\s*(.*?)\s*$/$1/; + @attrs = split /\s*;\s*/, $range; + # First piece is the language range + $ln = shift @attrs; + # Lower-case it + $ln = lc $ln; + # Find the quality factor + foreach my $attr (@attrs) { + # A numeric quality factor found + $rngqf{$ln} = $1+0 if $attr =~ /^q=([01](?:\.\d{1,3})?)$/; + } + # Default quality factor to 1 + $rngqf{$ln} = 1 if !exists $rngqf{$ln}; + } + # The default quality factor + if (exists $rngqf{"*"}) { + $defqf = $rngqf{"*"}; + delete $rngqf{"*"}; + } else { + $defqf = 0; + } + + # Language tags (what we have) + %tagqf = qw(); # Calculated quality factor + foreach my $ln (@ALL_LINGUAS) { + # Language tag, as specified in ISO + $tag = ln $ln, LN_NAME; + # Matched range of the quality factor + undef $match if defined $match; + # Language ranges (what the user sent to match us) + foreach my $range (keys %rngqf) { + # Exactly match or match a prefix + if ($tag eq $range || $tag =~ /^\Q$range\E-/) { + # Not matched yet + if (!defined $match) { + $tagqf{$ln} = $rngqf{$range}; # Quality Factor + $match = $range; # Record the matched range + # A longer match range + } elsif (length $range > length $match) { + $tagqf{$ln} = $rngqf{$range}; # Quality Factor + $match = $range; # Record the matched range + } + } + } + # Not matched -- apply a default quality factor + $tagqf{$ln} = $defqf if !exists $tagqf{$ln}; + } + + # Drop unacceptable languages + foreach my $ln (keys %tagqf) { + delete $tagqf{$ln} unless $tagqf{$ln} > 0; + } + # Nothing acceptable + return undef if scalar(keys %tagqf) == 0; + + # Sort by the quality factor + @_ = sort { $tagqf{$b} <=> $tagqf{$a} + || ($a eq $DEFAULT_LANG? -1: 0) + || ($b eq $DEFAULT_LANG? 1: 0) } keys %tagqf; + # A preferred match + return $_[0]; +} + +# getlang_setenv: Check the environment for specified language +sub getlang_setenv($) { + local ($_, %_); + $_ = $_[0]; + # Set the cookie to keep the result + $NEWCOOKIES{"lang"} = new CGI::Cookie(-name=>"lang", -value=>$_) + if !exists $COOKIES{"lang"} || $COOKIES{"lang"}->value ne $_; + return; +} + +# getcharset_accept: Parse the character set by the Accept-Charset header +# Refer to HTTP/1.1 section 14.2 for this algorism +sub getcharset_accept() { + local ($_, %_); + my (@rngs, %rngqf, $defqf, $cs, @attrs, %tagqf, $tag, $default); + # Accept-Charset not set + return undef if !exists $ENV{"HTTP_ACCEPT_CHARSET"}; + $default = getlang(LN_CHARSET); + + # Split into character set ranges + $_ = $ENV{"HTTP_ACCEPT_CHARSET"}; + s/^\s*(.*?)\s*$/$1/; + @rngs = split /\s*,\s*/, $_; + %rngqf = qw(); + foreach my $range (@rngs) { + # Split into attributes + $range =~ s/^\s*(.*?)\s*$/$1/; + @attrs = split /\s*;\s*/, $range; + # First piece is the character set range + $cs = shift @attrs; + # Lower-case it + $cs = lc $cs; + # Find the quality factor + foreach my $attr (@attrs) { + # A numeric quality factor found + $rngqf{$cs} = $1+0 if $attr =~ /^q=([01](?:\.\d{1,3})?)$/; + } + # Default quality factor to 1 + $rngqf{$cs} = 1 if !exists $rngqf{$cs}; + } + # The default quality factor + if (exists $rngqf{"*"}) { + $defqf = $rngqf{"*"}; + delete $rngqf{"*"}; + } else { + # Default ISO-8859-1 to 1 + $rngqf{"iso-8859-1"} = 1 if !exists $rngqf{"iso-8859-1"}; + $defqf = 0; + } + + # Character set tags (what we have) + %tagqf = qw(); # Calculated quality factor + foreach my $cs (all_charsets) { + # Character set tag, as specified in ISO + $tag = lc $cs; + # Character set ranges (what the user sent to match us) + foreach my $range (keys %rngqf) { + # Matched + $tagqf{$cs} = $rngqf{$range} # Quality Factor + if $tag eq $range; + } + # Not matched -- apply a default quality factor + $tagqf{$cs} = $defqf if !exists $tagqf{$cs}; + } + + # Drop unacceptable character sets + foreach my $cs (keys %tagqf) { + delete $tagqf{$cs} unless $tagqf{$cs} > 0; + } + # Nothing acceptable + return undef if scalar(keys %tagqf) == 0; + + # Sort by the quality factor + @_ = sort { $tagqf{$b} <=> $tagqf{$a} + || ($a eq $default? -1: 0) + || ($b eq $default? 1: 0) } keys %tagqf; + # A preferred match + return $_[0]; +} + +# all_charsets: Obtain all the available character sets +# Available character sets are the default character set of this +# language, and UTF-8 +sub all_charsets() { + local ($_, %_); + return @GetLang_all_charsets if @GetLang_all_charsets > 0; + %_ = qw(); + $_ = getlang(LN_CHARSET); + $_{$_} = 1; + $_{"UTF-8"} = 1; + @GetLang_all_charsets = keys %_; + return @GetLang_all_charsets; +} + +return 1; diff --git a/lib/perl5/Selima/Guest.pm b/lib/perl5/Selima/Guest.pm new file mode 100644 index 0000000..2c57e9f --- /dev/null +++ b/lib/perl5/Selima/Guest.pm @@ -0,0 +1,83 @@ +# Selima Website Content Management System +# Guest.pm: The subroutines for anonymouse/guest operations. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-26 + +package Selima::Guest; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(is_guest gactlog goutpage grmoldpage grmoldfile); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub is_guest(;$); +sub gactlog($;$); +sub goutpage($$;$); +sub grmoldpage($;$); +sub grmoldfile($;$); +} + +use Selima::Array; +use Selima::Cache qw(:guest); +use Selima::ChkPriv; +use Selima::DataVars qw(:input :groups); +use Selima::Logging; +use Selima::LogIn; +use Selima::MkAllDir; +use Selima::PageFunc; +use Selima::UserName; +use Selima::XFileIO; + +# is_guest: If the user is a guest (by the user id) +sub is_guest(;$) { + local ($_, %_); + $_ = $_[0]; + # Default to the current logged-in user + return !is_su && in_array(GUEST_GROUP, get_login_groups) + if !defined $_ || (defined get_login_sn && $_ == get_login_sn); + # Super user is never a guest + return ($Guest_is_guest{$_} = 0) if is_su($_); + # Obtain the groups + return ($Guest_is_guest{$_} = in_array(GUEST_GROUP, + user_parent_groups($_))); +} + +# gactlog: Add an activity log record if the user is not a guest +sub gactlog($;$) { + actlog $_[0], $_[1] unless is_guest; +} + +# goutpage: outpage() if the user is not a guest +sub goutpage($$;$) { + outpage $_[0], $_[1], $_[2] unless is_guest; +} + +# grmoldpage: rmoldpage() if the user is not a guest +sub grmoldpage($;$) { + rmoldpage $_[0], $_[1] unless is_guest; +} + +# grmoldfile: rmoldfile() if the user is not a guest +sub grmoldfile($;$) { + rmoldfile $_[0], $_[1] unless is_guest; +} + +return 1; diff --git a/lib/perl5/Selima/Guestbook.pm b/lib/perl5/Selima/Guestbook.pm new file mode 100644 index 0000000..12e5432 --- /dev/null +++ b/lib/perl5/Selima/Guestbook.pm @@ -0,0 +1,206 @@ +# Selima Website Content Management System +# Guestbook.pm: The guestbook-related subroutines. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-23 + +package Selima::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(update_pageno); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub update_pageno($$$;$); +sub split_page(\@\%$;$); +sub update_old_gbpageno($$;$); +} + +use Selima::DataVars qw($DBH); +use Selima::Format; + +# update_pageno: Update the guestbook page number +sub update_pageno($$$;$) { + local ($_, %_); + my ($table, $page_size, $cols, $from, $sql, $sth, $count, $row, $len, $where); + my (@ents, %sizes, %orig, %pagenos, $startno, $startat, $commit); + ($table, $page_size, $cols, $from) = @_; + + # If we should begin and commit here + $commit = $DBH->{"AutoCommit"}; + $DBH->begin_work if $commit; + + # Update the current page number + # Check the page to start from + undef $startno; + undef $startat; + $from = fmttime $from if defined $from; + if (defined $from) { + $sql = "SELECT pageno FROM $table WHERE NOT hid AND created<'$from'" + . " ORDER BY created DESC LIMIT 1;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + undef $from if $sth->rows != 1; + } + if (defined $from) { + $startno = ${$sth->fetch}[0]; + undef $sth; + $sql = "SELECT created FROM $table WHERE NOT hid AND pageno=$startno" + . " ORDER BY created LIMIT 1;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $startat = ${$sth->fetch}[0]; + } + @_ = qw(); + push @_, "created>='" . fmttime($startat) . "'" if defined $startat; + $where = (@_ > 0)? " WHERE " . join(" AND ", @_): ""; + # Ge the size of everyhing + $len = join " + ", map "CASE WHEN $_ IS NULL THEN 0 ELSE char_length($_) END", @$cols; + $len = "CASE WHEN hid THEN 0 ELSE $len END AS len"; + $sql = "SELECT sn, $len, pageno FROM $table $where ORDER BY created;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @ents = qw(), %sizes = qw(), %orig = qw(); $_ < $count; $_++) { + $row = $sth->fetchrow_hashref; + push @ents, $$row{"sn"}; + $sizes{$$row{"sn"}} = $$row{"len"}; + $orig{$$row{"sn"}} = $$row{"pageno"}; + } + # Split page + %pagenos = split_page @ents, %sizes, $page_size, $startno; + # Update it + foreach (@ents) { + next if $orig{$_} == $pagenos{$_}; + $sql = "UPDATE $table SET pageno=$pagenos{$_} WHERE sn=$_;\n"; + $DBH->gdo($sql); + } + + # Update the old page number + # No need to update it anymore. Let it go. + $DBH->commit if $commit; + return; +} + +# split_page: Split page according to the entry sizes +sub split_page(\@\%$;$) { + local ($_, %_); + my ($ents, $sizes, $page_size, $startno, $cursize, %pagenos); + ($ents, $sizes, $page_size, $startno) = @_; + $startno = 1 if !defined $startno; + + # Bounce for nothing + return if scalar @$ents == 0; + + # Split pages + %pagenos = qw(); + $pagenos{$$ents[0]} = $startno; + $cursize = $$sizes{$$ents[0]}; + for ($_ = 1; $_ < scalar(@$ents); $_++) { + my ($hi_gap, $lo_gap); + # We need at least one record + if ($cursize == 0) { + $pagenos{$$ents[$_]} = $pagenos{$$ents[$_-1]}; + $cursize += $$sizes{$$ents[$_]}; + next; + # Not oversized yet + } elsif ($cursize + $$sizes{$$ents[$_]} < $page_size) { + $pagenos{$$ents[$_]} = $pagenos{$$ents[$_-1]}; + $cursize += $$sizes{$$ents[$_]}; + next; + } + $hi_gap = $cursize + $$sizes{$$ents[$_]} - $page_size; + $lo_gap = $page_size - $cursize; + # The upper boundary is closer, and the page is not too oversized + if ($hi_gap < $lo_gap && $hi_gap <= $page_size / 4) { + $pagenos{$$ents[$_]} = $pagenos{$$ents[$_-1]}; + $cursize += $$sizes{$$ents[$_]}; + # Or, we prefer the lower, since the page is not oversized + } else { + $pagenos{$$ents[$_]} = $pagenos{$$ents[$_-1]} + 1; + $cursize = $$sizes{$$ents[$_]}; + } + } + + return %pagenos; +} + +# update_old_gbpageno: Update the old guestbook page number +sub update_old_gbpageno($$;$) { + local ($_, %_); + my ($table, $page_size, $from, $sql, $sth, $count, $row, $len, $cond); + my (@ents, %sizes, %orig, %pagenos, $startno, $startat, $commit); + ($table, $page_size, $from) = @_; + + # If we should begin and commit here + $commit = $DBH->{"AutoCommit"}; + $DBH->begin_work if $commit; + + # Update the old page number + undef $startno; + undef $startat; + if (defined $from) { + $sql = "SELECT oldpageno FROM $table WHERE NOT hid AND created<'$from'" + . " ORDER BY created DESC LIMIT 1;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $startno = ${$sth->fetch}[0]; + undef $sth; + $sql = "SELECT created FROM $table WHERE NOT hid AND oldpageno=$startno" + . " ORDER BY created LIMIT 1;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $startat = ${$sth->fetch}[0]; + } + @_ = qw(); + push @_, "NOT hid"; + push @_, "created>='$startat'" if defined $startat; + $cond = join " AND ", @_; + # Ge the size of everyhing + $len = "${table}_oldlen(created, ip, host, name, identity, location, email, url, message, updated, updatedby) AS len"; + # Tavern Backalley has a special table structure + $len = "garbage_oldlen(created, ip, host, message, updated, updatedby) AS len" + if $table eq "garbage"; + $sql = "SELECT sn, $len, oldpageno FROM $table WHERE $cond ORDER BY created;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @ents = qw(), %sizes = qw(), %orig = qw(); $_ < $count; $_++) { + $row = $sth->fetchrow_hashref; + push @ents, $$row{"sn"}; + $sizes{$$row{"sn"}} = $$row{"len"}; + $orig{$$row{"sn"}} = $$row{"oldpageno"}; + } + # Split page + # Old page size is always 10240 + %pagenos = split_page @ents, %sizes, 10240, $startno; + # Update it + foreach (@ents) { + next if $orig{$_} == $pagenos{$_}; + $sql = "UPDATE $table SET oldpageno=$pagenos{$_} WHERE sn=$_;\n"; + $DBH->gdo($sql); + } + + $DBH->commit if $commit; + + return; +} + +return 1; diff --git a/lib/perl5/Selima/HTTP.pm b/lib/perl5/Selima/HTTP.pm new file mode 100644 index 0000000..bffc6fd --- /dev/null +++ b/lib/perl5/Selima/HTTP.pm @@ -0,0 +1,1627 @@ +# Selima Website Content Management System +# HTTP.pm: The various HTTP status processors. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-26 + +package Selima::HTTP; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(http_204 http_301 http_303 http_304 http_307); +push @EXPORT, qw(http_400 http_403 http_404 http_405 http_410 http_413 http_500 http_503); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub need_302(); +sub get_custom_status_message($); +sub shall_mail_error(); +sub http_204(); +sub http_301($); +sub http_303($); +sub http_304(); +sub http_307($); +sub http_400(;$); +sub http_403(;$); +sub http_404(); +sub http_405(@); +sub http_410(); +sub http_413(); +sub http_500($); +sub http_503(;$); +} + +use CGI qw(header); +use Encode qw(encode); +use HTTP::Date qw(time2str); +use IO::NestedCapture qw(CAPTURE_STDOUT); + +BEGIN { +if (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + require Apache2::Connection; + require Apache2::Response; +} +} + +use Selima::A2HTML; +use Selima::AbsURI; +use Selima::AltLang; +use Selima::DataVars qw(:env :input :l10n :lastmod :lninfo + :output :requri :siteconf); +use Selima::DecForm; +use Selima::Format; +use Selima::GeoIP; +use Selima::GetLang; +use Selima::Logging; +use Selima::LogIn; +use Selima::Page2Rel; +use Selima::PageFunc; +use Selima::ShortCut; +use Selima::Unicode; +use Selima::XFileIO; +use Selima::XHTML; + +use Selima::Mail; + +BEGIN { +# Only import this when mod_perl. +if ($IS_MODPERL) { + if ($IS_MP2) { + require Apache2::Const; + import Apache2::Const qw(:methods); + } else { + require Apache::Constants; + import Apache::Constants qw(:methods); + } +# Otherwise, set to dummy values to get around strict checking +} else { + require constant; + import constant M_OPTIONS => 0; + import constant M_GET => 0; + import constant M_HEAD => 0; + import constant M_POST => 0; + import constant M_PUT => 0; + import constant M_DELETE => 0; + import constant M_TRACE => 0; + import constant M_CONNECT => 0; +} +} + +# need_302: Is this browser capable of HTTP 303 and HTTP 307? +# Currently only older Netscape without Gecko (version <= 4.xx) +# is known of this problem. +# Return: +# false: Standard behavior to send HTTP 303 or 307. +# true: Browser lacks the capability of redirecting +# HTTP 303 and 307. Send HTTP 302 instead. +sub need_302() { + local ($_, %_); + # User-Agent not sent, default to the standard behavior. + return 0 unless exists $ENV{"HTTP_USER_AGENT"}; + + $_ = $ENV{"HTTP_USER_AGENT"}; + # Not Mozilla/Netscape series + return 0 unless /^Mozilla\//; + # Mozilla/Netscape compatible + return 0 if /\bcompatible\b/; + # Mozilla/Netscape with Gecko (version > 4) + return 0 if /\bGecko\b/; + # Mozilla/Netscape without Gecko (version <= 4) + return 1; +} + +# get_custom_status_message: Obtain the custom status message +sub get_custom_status_message($) { + local ($_, %_); + my ($html, $status, $langfile, $charset); + $status = $_[0]; + + $langfile = getlang(LN_FILENAME); + + # Find language specific error message first + if (-e ($_ = "$DOC_ROOT/errors/$status.html.$langfile.xhtml")) { + $html = xfread $_; + } elsif (-e ($_ = "$DOC_ROOT/errors/$status.html.$langfile")) { + $html = xfread $_; + } elsif (-e ($_ = "$DOC_ROOT/$langfile/errors/$status.html.xhtml")) { + $html = xfread $_; + } elsif (-e ($_ = "$DOC_ROOT/$langfile/errors/$status.html")) { + $html = xfread $_; + } elsif (-e ($_ = "$DOC_ROOT/errors/$status.html.xhtml")) { + $html = xfread $_; + } elsif (-e ($_ = "$DOC_ROOT/errors/$status.html")) { + $html = xfread $_; + } + # Not found + return if !defined $html; + + # Reserve the character set + $charset = getlang(LN_CHARSET); + $html = hcref_decode($charset, $html); + + $charset = h($charset); + $html =~ s/(?<=\bencoding=")$charset(?=")//; + $html =~ s/(?<=\bcontent="text\/html; charset=)$charset(?=")//; + $html =~ s/(?<=\bcontent="application\/xhtml\+xml; charset=)$charset(?=")//; + $html =~ s/(?<=\btype="hidden" name="charset" value=")$charset(?=" \/>)//g; + $html =~ s/(?<=\baccept-charset=")$charset(?=")//g; + return $html; +} + +# shall_mail_error: Should we mail the error to the webmaster +sub shall_mail_error() { + local ($_, %_); + # Return "no" if not CGI + return 0 if !$IS_CGI; + # Return "no" if inside our intranet + $_ = $IS_MODPERL? ($IS_MP2? + Apache2::RequestUtil->request->connection->remote_ip: + Apache->request->connection->remote_ip): + $ENV{"REMOTE_ADDR"}; + return 0 if /^10\.0\.0\./ || $_ eq "127.0.0.1"; + # Default to yes + return 1; +} + +# http_204: HTTP/1.1 204 No Content +sub http_204() { + local ($_, %_); + my ($html, $r, $type, %h); + + # Obtain the Apache mod_perl request + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + # Clear the STDOUT buffer + IO::NestedCapture->stop(CAPTURE_STDOUT) + while exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0; + # Skip content auto-output + $NO_AUTO_OUTPUT = 1; + + # Only output headers to the CGI interface + if ($IS_CGI) { + $type = defined $CONTENT_TYPE? $CONTENT_TYPE: xhtml_content_type; + # The mod_perl way + if ($IS_MODPERL) { + $r->status(204); + $r->headers_out->set("Content-Length"=>0); + $r->content_languages([getlang LN_NAME]) + if $type =~ /^text\//; + # Client cache + if (defined $LAST_MODIFIED) { + if (defined get_login_sn) { + $r->headers_out->set("Cache-Control"=>"private"); + } else { + $r->headers_out->set("Cache-Control"=>"public"); + } + $r->headers_out->set("Last-Modified"=>time2str($LAST_MODIFIED)); + } else { + $r->headers_out->set("Cache-Control"=>"no-cache"); + } + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $r->method ne "POST" + && $r->method ne "PUT" + && !defined $GET->param("lang")) { + $r->headers_out->set("Content-Location"=>altlang(getlang, page_param)); + $r->headers_out->set("Vary"=>"accept-language,cookie"); + } + $r->headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + + # Ordinary CGI + } else { + # Output the status message + %h = ( -status=>"204 No Content", + -Content_Length=>0); + $h{"-Content_Language"} = getlang LN_NAME + if $type =~ /^text\//; + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $ENV{"REQUEST_METHOD"} ne "POST" + && $ENV{"REQUEST_METHOD"} ne "PUT" + && !defined $GET->param("lang")) { + $h{"-Content_Location"} = altlang getlang, page_param; + $h{"-Vary"} = "accept-language,cookie"; + } + # Client cache + if (defined $LAST_MODIFIED) { + if (defined get_login_sn) { + $h{"-Cache_Control"} = "private"; + } else { + $h{"-Cache_Control"} = "public"; + } + $h{"-Last_Modified"} = time2str($LAST_MODIFIED); + } else { + $h{"-Cache_Control"} = "no-cache"; + } + $h{"-cookie"} = [values %NEWCOOKIES]; + print header(%h); + } + } + + # No need to return + exit; +} + +# http_301: HTTP/1.1 301 Moved Permanently +sub http_301($) { + local ($_, %_); + my ($html, $r, $type, %h, $url); + $url = $_[0]; + + # Obtain the Apache mod_perl request + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + # Clear the STDOUT buffer + IO::NestedCapture->stop(CAPTURE_STDOUT) + while exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0; + # Skip content auto-output + $NO_AUTO_OUTPUT = 1; + # Make URL absolute + $url = absuri $url; + + # Obtain the status message + $html = get_custom_status_message(301); + # Fall back to a simplest default + if (!defined $html) { + $html = << "EOT"; + + + + +301 Moved Permanently + + +

    301 Moved Permanently

    +

    You should refer to the new location.

    + + +EOT + } + # Replace the page content + $html =~ s/\$url/h($url)/ge; + # Convert the URLs to relative + $html = page2rel $html, $REQUEST_PATH; + # Encode the e-mail at-signs (@) + $html =~ s/@/@/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap@/spamtrap@/g; + + # Only output headers to the CGI interface + if ($IS_CGI) { + # The mod_perl way + if ($IS_MODPERL) { + # Error documents can only be output as ISO-8859-1 under mod_perl. + # It is hardcoded into Apache http_protocol.c ap_send_error_response(). + # See http://www.geocrawler.com/mail/msg.php3?msg_id=6288656 + $html = page_encode($html, "ISO-8859-1"); + $r->custom_response(301, $html); + $r->status(301); + $r->err_headers_out->set("Location"=>$url); + $r->err_headers_out->set("Content-Language"=>getlang LN_NAME); + $r->err_headers_out->set("Content-Length"=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $r->method ne "POST" + && $r->method ne "PUT" + && !defined $GET->param("lang")) { + $r->err_headers_out->set("Content-Location"=>altlang(getlang, page_param)); + $r->err_headers_out->set("Vary"=>"accept-language,cookie"); + } + $r->err_headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + + # Ordinary CGI + } else { + $html = page_encode($html, getlang(LN_CHARSET)); + $type = xhtml_content_type . "; charset=" . getlang(LN_CHARSET); + %h = ( -status=>"301 Moved Permanently", + -type=>$type, + -Location=>$url, + -Content_Language=>getlang(LN_NAME), + -Content_Length=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $ENV{"REQUEST_METHOD"} ne "POST" + && $ENV{"REQUEST_METHOD"} ne "PUT" + && !defined $GET->param("lang")) { + $h{"-Content_Location"} = altlang getlang, page_param; + $h{"-Vary"} = "accept-language,cookie"; + } + $h{"-cookie"} = [values %NEWCOOKIES]; + print header(%h); + print $html if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Output the content directly as a console application + } else { + print page_encode($html, getlang(LN_CHARSET)) + if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # No need to return + exit; +} + +# http_303: HTTP/1.1 303 See Others +sub http_303($) { + local ($_, %_); + my ($html, $r, $type, %h, $url); + $url = $_[0]; + + # Obtain the Apache mod_perl request + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + # Clear the STDOUT buffer + IO::NestedCapture->stop(CAPTURE_STDOUT) + while exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0; + # Skip content auto-output + $NO_AUTO_OUTPUT = 1; + # Make URL absolute + $url = absuri $url; + + # Obtain the status message + $html = get_custom_status_message(303); + # Fall back to a simplest default + if (!defined $html) { + $html = << "EOT"; + + + + +303 See Others + + +

    303 See Others

    +

    Please follow this location.

    + + +EOT + } + # Replace the page content + $html =~ s/\$url/h($url)/ge; + # Convert the URLs to relative + $html = page2rel $html, $REQUEST_PATH; + # Encode the e-mail at-signs (@) + $html =~ s/@/@/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap@/spamtrap@/g; + + # Only output headers to the CGI interface + if ($IS_CGI) { + # The mod_perl way + if ($IS_MODPERL) { + # Error documents can only be output as ISO-8859-1 under mod_perl. + # It is hardcoded into Apache http_protocol.c ap_send_error_response(). + # See http://www.geocrawler.com/mail/msg.php3?msg_id=6288656 + $html = page_encode($html, "ISO-8859-1"); + if (need_302) { + $r->custom_response(302, $html); + $r->status(302); + } else { + $r->custom_response(303, $html); + $r->status(303); + } + $r->err_headers_out->set("Location"=>$url); + $r->err_headers_out->set("Content-Language"=>getlang LN_NAME); + $r->err_headers_out->set("Content-Length"=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $r->method ne "POST" + && $r->method ne "PUT" + && !defined $GET->param("lang")) { + $r->err_headers_out->set("Content-Location"=>altlang(getlang, page_param)); + $r->err_headers_out->set("Vary"=>"accept-language,cookie"); + } + $r->err_headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + + # Ordinary CGI + } else { + $html = page_encode($html, getlang(LN_CHARSET)); + $type = xhtml_content_type . "; charset=" . getlang(LN_CHARSET); + %h = ( -status=>"303 See Others", + -type=>$type, + -Location=>$url, + -Content_Language=>getlang(LN_NAME), + -Content_Length=>length $html); + $h{"-status"} = "302 Found" if need_302; + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $ENV{"REQUEST_METHOD"} ne "POST" + && $ENV{"REQUEST_METHOD"} ne "PUT" + && !defined $GET->param("lang")) { + $h{"-Content_Location"} = altlang getlang, page_param; + $h{"-Vary"} = "accept-language,cookie"; + } + $h{"-cookie"} = [values %NEWCOOKIES]; + print header(%h); + print $html if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Output the content directly as a console application + } else { + print page_encode($html, getlang(LN_CHARSET)) + if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # No need to return + exit; +} + +# http_304: HTTP/1.1 304 Not Modified +sub http_304() { + local ($_, %_); + my ($html, $r, $type, %h); + + # Obtain the Apache mod_perl request + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + # Clear the STDOUT buffer + IO::NestedCapture->stop(CAPTURE_STDOUT) + while exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0; + # Skip content auto-output + $NO_AUTO_OUTPUT = 1; + + # Only output headers to the CGI interface + # See HTTP/1.1 sec 10.3.5 for appropriate headers to send + if ($IS_CGI) { + # The mod_perl way + # We must do it in the mod_perl way, since the CGI.pm sends an + # excess line break under mod_perl, which breaks the HTTP/304 + # response for the browser. + if ($IS_MODPERL) { + $r->status(304); + $r->err_headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + # We must send them + $r->err_headers_out->set("Content-Location"=>altlang(getlang, page_param)) + if @ALL_LINGUAS > 1; + + # Ordinary CGI + } else { + $type = (defined $CONTENT_TYPE? $CONTENT_TYPE: xhtml_content_type) + . "; charset=" . getlang(LN_CHARSET); + # Output the status message + %h = ( -status=>"304 Not Modified"); + $h{"-Content_Location"} = altlang getlang, page_param + if @ALL_LINGUAS > 1; + # Avoid the bug of Apache/CGI that always send the content type + # even with HTTP/304 + $h{"-type"} = $type; + $h{"-cookie"} = [values %NEWCOOKIES]; + print header(%h); + } + + # Output the content directly as a console application + } else { + print page_encode($html, getlang(LN_CHARSET)) + if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # No need to return + exit; +} + +# http_307: HTTP/1.1 307 Temporary Redirect +sub http_307($) { + local ($_, %_); + my ($html, $r, $type, %h, $url); + $url = $_[0]; + + # Obtain the Apache mod_perl request + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + # Clear the STDOUT buffer + IO::NestedCapture->stop(CAPTURE_STDOUT) + while exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0; + # Skip content auto-output + $NO_AUTO_OUTPUT = 1; + # Make URL absolute + $url = absuri $url; + + # Obtain the status message + $html = get_custom_status_message(307); + # Fall back to a simplest default + if (!defined $html) { + $html = << "EOT"; + + + + +307 Temporary Redirect + + +

    307 Temporary Redirect

    +

    Please refer to the following location.

    + + +EOT + } + # Replace the page content + $html =~ s/\$url/h($url)/ge; + # Convert the URLs to relative + $html = page2rel $html, $REQUEST_PATH; + # Encode the e-mail at-signs (@) + $html =~ s/@/@/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap@/spamtrap@/g; + + # Only output headers to the CGI interface + if ($IS_CGI) { + # The mod_perl way + if ($IS_MODPERL) { + # Error documents can only be output as ISO-8859-1 under mod_perl. + # It is hardcoded into Apache http_protocol.c ap_send_error_response(). + # See http://www.geocrawler.com/mail/msg.php3?msg_id=6288656 + $html = page_encode($html, "ISO-8859-1"); + if (need_302) { + $r->custom_response(302, $html); + $r->status(302); + } else { + $r->custom_response(307, $html); + $r->status(307); + } + $r->err_headers_out->set("Location"=>$url); + $r->err_headers_out->set("Content-Language"=>getlang LN_NAME); + $r->err_headers_out->set("Content-Length"=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $r->method ne "POST" + && $r->method ne "PUT" + && !defined $GET->param("lang")) { + $r->err_headers_out->set("Content-Location"=>altlang(getlang, page_param)); + $r->err_headers_out->set("Vary"=>"accept-language,cookie"); + } + $r->err_headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + + # Ordinary CGI + } else { + $html = page_encode($html, getlang(LN_CHARSET)); + $type = xhtml_content_type . "; charset=" . getlang(LN_CHARSET); + %h = ( -status=>"307 Temporary Redirect", + -type=>$type, + -Location=>$url, + -Content_Language=>getlang(LN_NAME), + -Content_Length=>length $html); + $h{"-status"} = "302 Found" if need_302; + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $ENV{"REQUEST_METHOD"} ne "POST" + && $ENV{"REQUEST_METHOD"} ne "PUT" + && !defined $GET->param("lang")) { + $h{"-Content_Location"} = altlang getlang, page_param; + $h{"-Vary"} = "accept-language,cookie"; + } + $h{"-cookie"} = [values %NEWCOOKIES]; + print header(%h); + print $html if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Output the content directly as a console application + } else { + print page_encode($html, getlang(LN_CHARSET)) + if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # No need to return + exit; +} + +# http_400: HTTP/1.1 400 Bad Request +# 0 to disable error page output +sub http_400(;$) { + local ($_, %_); + my ($html, $r, $type, %h); + my $errmsg; + $errmsg = $_[0]; + + # Obtain the Apache mod_perl request + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + # Clear the STDOUT buffer + IO::NestedCapture->stop(CAPTURE_STDOUT) + while exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0; + # Skip content auto-output + $NO_AUTO_OUTPUT = 1; + + # Obtain the status message + $html = get_custom_status_message(400) + unless defined $errmsg && $errmsg eq "0"; + # Fall back to a simplest default + if (!defined $html) { + $html = << "EOT"; + + + + +400 Bad Request + + +

    400 Bad Request

    + +

    Sorry, the server cannot understand what you are asking for.

    + + +EOT + } + # Replace the page content + $html =~ s//defined $errmsg && $errmsg ne "0"? + "

    " . h(F_($errmsg)) . "<\/p>": ""/ge; + # Convert the URLs to relative + $html = page2rel $html, $REQUEST_PATH; + # Encode the e-mail at-signs (@) + $html =~ s/@/@/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap@/spamtrap@/g; + + # Only output headers to the CGI interface + if ($IS_CGI) { + # The mod_perl way + if ($IS_MODPERL) { + # Error documents can only be output as ISO-8859-1 under mod_perl. + # It is hardcoded into Apache http_protocol.c ap_send_error_response(). + # See http://www.geocrawler.com/mail/msg.php3?msg_id=6288656 + $html = page_encode($html, "ISO-8859-1"); + $r->custom_response(400, $html); + $r->status(400); + $r->err_headers_out->set("Content-Language"=>getlang LN_NAME); + $r->err_headers_out->set("Content-Length"=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $r->method ne "POST" + && $r->method ne "PUT" + && !defined $GET->param("lang")) { + $r->err_headers_out->set("Content-Location"=>altlang(getlang, page_param)); + $r->err_headers_out->set("Vary"=>"accept-language,cookie"); + } + $r->err_headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + + # Ordinary CGI + } else { + $html = page_encode($html, getlang(LN_CHARSET)); + $type = xhtml_content_type . "; charset=" . getlang(LN_CHARSET); + %h = ( -status=>"400 Bad Request", + -type=>$type, + -Content_Language=>getlang(LN_NAME), + -Content_Length=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $ENV{"REQUEST_METHOD"} ne "POST" + && $ENV{"REQUEST_METHOD"} ne "PUT" + && !defined $GET->param("lang")) { + $h{"-Content_Location"} = altlang getlang, page_param; + $h{"-Vary"} = "accept-language,cookie"; + } + $h{"-cookie"} = [values %NEWCOOKIES]; + print header(%h); + print $html if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Output the content directly as a console application + } else { + print page_encode($html, getlang(LN_CHARSET)) + if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Log the error message to the server error log + if (!defined $errmsg) { + log_error "Bad Request: $REQUEST_URI"; + } elsif ($errmsg eq "0") { + if ($IS_MODPERL) { + $_ = $r->the_request; + } else { + $_ = $ENV{"REQUEST_METHOD"} . " " + . $ENV{"REQUEST_URI"} . " " . $ENV{"SERVER_PROTOCOL"}; + } + log_error "Invalid URI in request $_"; + } else { + log_error "Bad Request: $REQUEST_URI: $errmsg"; + } + + # No need to return + exit 400 if !$IS_CGI; + exit; +} + +# http_403: HTTP/1.1 403 Forbidden +sub http_403(;$) { + local ($_, %_); + my ($html, $r, $type, %h); + my $errmsg; + $errmsg = $_[0]; + + # Obtain the Apache mod_perl request + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + # Clear the STDOUT buffer + IO::NestedCapture->stop(CAPTURE_STDOUT) + while exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0; + # Skip content auto-output + $NO_AUTO_OUTPUT = 1; + + # Obtain the status message + $html = get_custom_status_message(403) + unless defined $errmsg && $errmsg eq "0"; + # Fall back to a simplest default + if (!defined $html) { + $html = << "EOT"; + + + + +403 Forbidden + + +

    403 Forbidden

    + +

    You are not allowed to enter here.

    + + +EOT + } + # Replace the page content + $html =~ s//defined $errmsg && $errmsg ne "0"? + "

    " . h(F_($errmsg)) . "<\/p>": ""/ge; + # Convert the URLs to relative + $html = page2rel $html, $REQUEST_PATH; + # Encode the e-mail at-signs (@) + $html =~ s/@/@/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap@/spamtrap@/g; + + # Only output headers to the CGI interface + if ($IS_CGI) { + # The mod_perl way + if ($IS_MODPERL) { + # Error documents can only be output as ISO-8859-1 under mod_perl. + # It is hardcoded into Apache http_protocol.c ap_send_error_response(). + # See http://www.geocrawler.com/mail/msg.php3?msg_id=6288656 + $html = page_encode($html, "ISO-8859-1"); + $r->custom_response(403, $html); + $r->status(403); + $r->err_headers_out->set("Content-Language"=>getlang LN_NAME); + $r->err_headers_out->set("Content-Length"=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $r->method ne "POST" + && $r->method ne "PUT" + && !defined $GET->param("lang")) { + $r->err_headers_out->set("Content-Location"=>altlang(getlang, page_param)); + $r->err_headers_out->set("Vary"=>"accept-language,cookie"); + } + $r->err_headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + + # Ordinary CGI + } else { + $html = page_encode($html, getlang(LN_CHARSET)); + $type = xhtml_content_type . "; charset=" . getlang(LN_CHARSET); + %h = ( -status=>"403 Forbidden", + -type=>$type, + -Content_Language=>getlang(LN_NAME), + -Content_Length=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $ENV{"REQUEST_METHOD"} ne "POST" + && $ENV{"REQUEST_METHOD"} ne "PUT" + && !defined $GET->param("lang")) { + $h{"-Content_Location"} = altlang getlang, page_param; + $h{"-Vary"} = "accept-language,cookie"; + } + $h{"-cookie"} = [values %NEWCOOKIES]; + print header(%h); + print $html if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Output the content directly as a console application + } else { + print page_encode($html, getlang(LN_CHARSET)) + if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Log the error message to the server error log + if (!defined $errmsg) { + log_error "Forbidden: $REQUEST_URI"; + } elsif ($errmsg eq "0") { + if ($IS_MODPERL) { + $_ = $r->the_request; + } else { + $_ = $ENV{"REQUEST_METHOD"} . " " + . $ENV{"REQUEST_URI"} . " " . $ENV{"SERVER_PROTOCOL"}; + } + log_error "Suspicious bad robot: $_"; + } else { + log_error "Forbidden: $REQUEST_URI: $errmsg"; + } + + # No need to return + exit 403 if !$IS_CGI; + exit; +} + +# http_404: HTTP/1.1 404 Not Found +sub http_404() { + local ($_, %_); + my ($html, $r, $type, %h); + + # Obtain the Apache mod_perl request + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + # Clear the STDOUT buffer + IO::NestedCapture->stop(CAPTURE_STDOUT) + while exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0; + # Skip content auto-output + $NO_AUTO_OUTPUT = 1; + + # Obtain the status message + $html = get_custom_status_message(404); + # Fall back to a simplest default + if (!defined $html) { + $html = << "EOT"; + + + + +404 Not Found + + +

    404 Not Found

    +

    The document you requested was not found.

    + + +EOT + } + # Convert the URLs to relative + $html = page2rel $html, $REQUEST_PATH; + # Encode the e-mail at-signs (@) + $html =~ s/@/@/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap@/spamtrap@/g; + + # Only output headers to the CGI interface + if ($IS_CGI) { + # The mod_perl way + if ($IS_MODPERL) { + # Error documents can only be output as ISO-8859-1 under mod_perl. + # It is hardcoded into Apache http_protocol.c ap_send_error_response(). + # See http://www.geocrawler.com/mail/msg.php3?msg_id=6288656 + $html = page_encode($html, "ISO-8859-1"); + $r->custom_response(404, $html); + $r->status(404); + $r->err_headers_out->set("Content-Language"=>getlang LN_NAME); + $r->err_headers_out->set("Content-Length"=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $r->method ne "POST" + && $r->method ne "PUT" + && !defined $GET->param("lang")) { + $r->err_headers_out->set("Content-Location"=>altlang(getlang, page_param)); + $r->err_headers_out->set("Vary"=>"accept-language,cookie"); + } + $r->err_headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + + # Ordinary CGI + } else { + $html = page_encode($html, getlang(LN_CHARSET)); + $type = xhtml_content_type . "; charset=" . getlang(LN_CHARSET); + %h = ( -status=>"404 Not Found", + -type=>$type, + -Content_Language=>getlang(LN_NAME), + -Content_Length=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $ENV{"REQUEST_METHOD"} ne "POST" + && $ENV{"REQUEST_METHOD"} ne "PUT" + && !defined $GET->param("lang")) { + $h{"-Content_Location"} = altlang getlang, page_param; + $h{"-Vary"} = "accept-language,cookie"; + } + $h{"-cookie"} = [values %NEWCOOKIES]; + print header(%h); + print $html if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Output the content directly as a console application + } else { + print page_encode($html, getlang(LN_CHARSET)) + if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Log the error message to the server error log + log_error "Not Found: $REQUEST_URI"; + + # No need to return + exit 404 if !$IS_CGI; + exit; +} + +# http_405: HTTP/1.1 405 Method Not Allowed +sub http_405(@) { + local ($_, %_); + my ($html, $r, $type, %h, @allowed); + @allowed = @_; + + # Obtain the Apache mod_perl request + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + # Clear the STDOUT buffer + IO::NestedCapture->stop(CAPTURE_STDOUT) + while exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0; + # Skip content auto-output + $NO_AUTO_OUTPUT = 1; + + # Obtain the status message + $html = get_custom_status_message(405); + # Fall back to a simplest default + if (!defined $html) { + $html = << "EOT"; + + + + +405 Method Not Allowed + + +

    405 Method Not Allowed

    +

    You should use the following methods: \$allowed.

    + + +EOT + } + # Replace the page content + $html =~ s/\$allowed/join(", ", map "" . h($_) . "<\/samp>", @allowed)/ge; + # Convert the URLs to relative + $html = page2rel $html, $REQUEST_PATH; + # Encode the e-mail at-signs (@) + $html =~ s/@/@/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap@/spamtrap@/g; + + # Only output headers to the CGI interface + if ($IS_CGI) { + # The mod_perl way + if ($IS_MODPERL) { + my $allowed_b; + $allowed_b = 0; + foreach (@allowed) { + if ($_ eq "OPTIONS") { + $allowed_b |= (1 << M_OPTIONS); + } elsif ($_ eq "GET") { + $allowed_b |= (1 << M_GET); + # M_HEAD is not defined in Apache. It is implied by M_GET. + #} elsif ($_ eq "HEAD") { + # $allowed_b |= (1 << M_HEAD); + } elsif ($_ eq "POST") { + $allowed_b |= (1 << M_POST); + } elsif ($_ eq "PUT") { + $allowed_b |= (1 << M_PUT); + } elsif ($_ eq "DELETE") { + $allowed_b |= (1 << M_DELETE); + } elsif ($_ eq "TRACE") { + $allowed_b |= (1 << M_TRACE); + } elsif ($_ eq "CONNECT") { + $allowed_b |= (1 << M_CONNECT); + } + } + # Error documents can only be output as ISO-8859-1 under mod_perl. + # It is hardcoded into Apache http_protocol.c ap_send_error_response(). + # See http://www.geocrawler.com/mail/msg.php3?msg_id=6288656 + $html = page_encode($html, "ISO-8859-1"); + $r->custom_response(405, $html); + $r->status(405); + $r->allowed($allowed_b); + $r->err_headers_out->set("Content-Language"=>getlang LN_NAME); + $r->err_headers_out->set("Content-Length"=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $r->method ne "POST" + && $r->method ne "PUT" + && !defined $GET->param("lang")) { + $r->err_headers_out->set("Content-Location"=>altlang(getlang, page_param)); + $r->err_headers_out->set("Vary"=>"accept-language,cookie"); + } + $r->err_headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + + # Ordinary CGI + } else { + $html = page_encode($html, getlang(LN_CHARSET)); + $type = xhtml_content_type . "; charset=" . getlang(LN_CHARSET); + %h = ( -status=>"405 Method Not Allowed", + -type=>$type, + -Allow=>join(", ", @allowed), + -Content_Language=>getlang(LN_NAME), + -Content_Length=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $ENV{"REQUEST_METHOD"} ne "POST" + && $ENV{"REQUEST_METHOD"} ne "PUT" + && !defined $GET->param("lang")) { + $h{"-Content_Location"} = altlang getlang, page_param; + $h{"-Vary"} = "accept-language,cookie"; + } + $h{"-cookie"} = [values %NEWCOOKIES]; + print header(%h); + print $html if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Output the content directly as a console application + } else { + print page_encode($html, getlang(LN_CHARSET)) + if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Log the error message to the server error log + $_ = $IS_MODPERL? $r->method: $ENV{"REQUEST_METHOD"}; + log_error "$_: Method Not Allowed (" . join(", ", @allowed) . "): $REQUEST_URI\n"; + + # No need to return + exit 405 if !$IS_CGI; + exit; +} + +# http_410: HTTP 410 Gone +sub http_410() { + local ($_, %_); + my ($html, $r, $type, %h); + + # Obtain the Apache mod_perl request + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + # Clear the STDOUT buffer + IO::NestedCapture->stop(CAPTURE_STDOUT) + while exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0; + # Skip content auto-output + $NO_AUTO_OUTPUT = 1; + + # Obtain the status message + $html = get_custom_status_message(410); + # Fall back to a simplest default + if (!defined $html) { + $html = << "EOT"; + + + + +410 Gone + + +

    410 Gone

    +

    Sorry, this page is removed permanently, and there is no forwarding address available. Please remove your bookmarks, and stop referring to this page any more. Thanks.

    + + +EOT + } + # Convert the URLs to relative + $html = page2rel $html, $REQUEST_PATH; + # Encode the e-mail at-signs (@) + $html =~ s/@/@/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap@/spamtrap@/g; + + # Only output headers to the CGI interface + if ($IS_CGI) { + # The mod_perl way + if ($IS_MODPERL) { + # Error documents can only be output as ISO-8859-1 under mod_perl. + # It is hardcoded into Apache http_protocol.c ap_send_error_response(). + # See http://www.geocrawler.com/mail/msg.php3?msg_id=6288656 + $html = page_encode($html, "ISO-8859-1"); + $r->custom_response(410, $html); + $r->status(410); + $r->err_headers_out->set("Content-Language"=>getlang LN_NAME); + $r->err_headers_out->set("Content-Length"=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $r->method ne "POST" + && $r->method ne "PUT" + && !defined $GET->param("lang")) { + $r->err_headers_out->set("Content-Location"=>altlang(getlang, page_param)); + $r->err_headers_out->set("Vary"=>"accept-language,cookie"); + } + $r->err_headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + + # Ordinary CGI + } else { + $html = page_encode($html, getlang(LN_CHARSET)); + $type = xhtml_content_type . "; charset=" . getlang(LN_CHARSET); + %h = ( -status=>"410 Gone", + -type=>$type, + -Content_Language=>getlang(LN_NAME), + -Content_Length=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $ENV{"REQUEST_METHOD"} ne "POST" + && $ENV{"REQUEST_METHOD"} ne "PUT" + && !defined $GET->param("lang")) { + $h{"-Content_Location"} = altlang getlang, page_param; + $h{"-Vary"} = "accept-language,cookie"; + } + $h{"-cookie"} = [values %NEWCOOKIES]; + print header(%h); + print $html if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Output the content directly as a console application + } else { + print page_encode($html, getlang(LN_CHARSET)) + if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Log the error message to the server error log + log_error "Gone: $REQUEST_URI"; + + # No need to return + exit 410 if !$IS_CGI; + exit; +} + +# http_413: HTTP/1.1 413 Request Entity Too Large +sub http_413() { + local ($_, %_); + my ($html, $r, $type, %h); + + # Obtain the Apache mod_perl request + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + # Clear the STDOUT buffer + IO::NestedCapture->stop(CAPTURE_STDOUT) + while exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0; + # Skip content auto-output + $NO_AUTO_OUTPUT = 1; + + # Obtain the status message + $html = get_custom_status_message(413); + # Fall back to a simplest default + if (!defined $html) { + $html = << "EOT"; + + + + +413 Request Entity Too Large + + +

    413 Request Entity Too Large

    +

    The server refuses to process your large submitted data.

    + + +EOT + } + # Convert the URLs to relative + $html = page2rel $html, $REQUEST_PATH; + # Encode the e-mail at-signs (@) + $html =~ s/@/@/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap@/spamtrap@/g; + + # Only output headers to the CGI interface + if ($IS_CGI) { + # The mod_perl way + if ($IS_MODPERL) { + # Error documents can only be output as ISO-8859-1 under mod_perl. + # It is hardcoded into Apache http_protocol.c ap_send_error_response(). + # See http://www.geocrawler.com/mail/msg.php3?msg_id=6288656 + $html = page_encode($html, "ISO-8859-1"); + $r->custom_response(413, $html); + $r->status(413); + $r->err_headers_out->set("Content-Language"=>getlang LN_NAME); + $r->err_headers_out->set("Content-Length"=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $r->method ne "POST" + && $r->method ne "PUT" + && !defined $GET->param("lang")) { + $r->err_headers_out->set("Content-Location"=>altlang(getlang, page_param)); + $r->err_headers_out->set("Vary"=>"accept-language,cookie"); + } + $r->err_headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + + # Ordinary CGI + } else { + $html = page_encode($html, getlang(LN_CHARSET)); + $type = xhtml_content_type . "; charset=" . getlang(LN_CHARSET); + %h = ( -status=>"413 Request Entity Too Large", + -type=>$type, + -Content_Language=>getlang(LN_NAME), + -Content_Length=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $ENV{"REQUEST_METHOD"} ne "POST" + && $ENV{"REQUEST_METHOD"} ne "PUT" + && !defined $GET->param("lang")) { + $h{"-Content_Location"} = altlang getlang, page_param; + $h{"-Vary"} = "accept-language,cookie"; + } + $h{"-cookie"} = [values %NEWCOOKIES]; + print header(%h); + print $html if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Output the content directly as a console application + } else { + print page_encode($html, getlang(LN_CHARSET)) + if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Log the error message to the server error log + log_error "Request Entity Too Large: $REQUEST_URI"; + + # No need to return + exit 413 if !$IS_CGI; + exit; +} + +# http_500: HTTP/1.1 500 Internet Server Error +sub http_500($) { + local ($_, %_); + my ($html, $r, $type, %h); + my ($errmsg, @callers, $remote); + $errmsg = $_[0]; + + # Find out our context + for (my $i = 0, @callers = qw(); (@_ = caller $i) > 0; $i++) { + # Avoid recursive calls + # Not possible. $SIG{"__DIE__"} is disabled during itself. + # Context after Apache::Registry is not meaningful + last if $_[1] =~ /\/Apache\/Registry\.pm$/; + # Skip if in eval(). + # Apache handler() eval() is not trapped for it is at Apache::Registry + # and is skipped by the above rule. + return if $_[3] eq "(eval)"; + push @callers, [@_]; + } + + # Obtain the Apache mod_perl request + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + # Clear the STDOUT buffer + IO::NestedCapture->stop(CAPTURE_STDOUT) + while exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0; + # Skip content auto-output + $NO_AUTO_OUTPUT = 1; + $remote = $IS_MODPERL? $r->connection->remote_ip: + $ENV{"REMOTE_ADDR"}; + + # Variables in the status message + $errmsg =~ s/ at \S+ line \d+\.\n//; + # Obtain the status message + $html = get_custom_status_message(500); + # Fall back to a simplest default + if (!defined $html) { + $html = << "EOT"; + + + + +500 Internel Server Error + + +

    500 Internel Server Error

    + + + + + +EOT + } + # Replace the page content + $html =~ s// + "
    \n" . a2html($errmsg) . "<\/samp>
    \n" + . join("
    \n", map "at " . h($$_[1]) . "<\/samp> line " . h($$_[2]), @callers) + . ".\n<\/div>"/ge; + # Convert the URLs to relative + $html = page2rel $html, $REQUEST_PATH; + # Encode the e-mail at-signs (@) + $html =~ s/@/@/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap@/spamtrap@/g; + + # Only output headers to the CGI interface + if ($IS_CGI) { + # The mod_perl way + if ($IS_MODPERL) { + # Error documents can only be output as ISO-8859-1 under mod_perl. + # It is hardcoded into Apache http_protocol.c ap_send_error_response(). + # See http://www.geocrawler.com/mail/msg.php3?msg_id=6288656 + $html = page_encode($html, "ISO-8859-1"); + $r->custom_response(500, $html); + $r->status(500); + $r->err_headers_out->set("Content-Language"=>getlang LN_NAME); + $r->err_headers_out->set("Content-Length"=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $r->method ne "POST" + && $r->method ne "PUT" + && !defined $GET->param("lang")) { + $r->err_headers_out->set("Content-Location"=>altlang(getlang, page_param)); + $r->err_headers_out->set("Vary"=>"accept-language,cookie"); + } + $r->err_headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + + # Ordinary CGI + } else { + $html = page_encode($html, getlang(LN_CHARSET)); + $type = xhtml_content_type . "; charset=" . getlang(LN_CHARSET); + %h = ( -status=>"500 Internel Server Error", + -type=>$type, + -Content_Language=>getlang(LN_NAME), + -Content_Length=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $ENV{"REQUEST_METHOD"} ne "POST" + && $ENV{"REQUEST_METHOD"} ne "PUT" + && !defined $GET->param("lang")) { + $h{"-Content_Location"} = altlang getlang, page_param; + $h{"-Vary"} = "accept-language,cookie"; + } + $h{"-cookie"} = [values %NEWCOOKIES]; + print header(%h); + print $html if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Output the content directly as a console application + } else { + print page_encode($html, getlang(LN_CHARSET)) + if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Mail the webmaster on this error + if (shall_mail_error) { + my ($mail, $webmaster, $site, $body, $reqline, $reqhdrs, $form); + # Get the webmaster address to notify to + if (defined $WEBMASTER) { + $webmaster = $WEBMASTER; + } elsif (exists $ENV{"SERVER_ADMIN"}) { + $webmaster = $ENV{"SERVER_ADMIN"}; + } else { + $webmaster = "webmaster\@" . $ENV{"SERVER_NAME"}; + } + # Get the site name + $site = defined $SITENAME_ABBR? $SITENAME_ABBR: + defined $PACKAGE? $PACKAGE: $REQUEST_HOST; + # The request string + if ($IS_MODPERL) { + $r->as_string =~ /^([^\n]+)\n((?:[^\n]+\n)*).+?$/s; + ($reqline, $reqhdrs) = ($1, $2); + $reqhdrs =~ s/^(.+)$/* $1/gm; + } else { + $reqline = sprintf "%s %s%s %s", + $ENV{"REQUEST_METHOD"}, $ROOT_DIFF, $REQUEST_URI, + $ENV{"SERVER_PROTOCOL"}; + %_ = qw(); + foreach my $key (grep /^HTTP_/, keys %ENV) { + $_ = $key; + s/^HTTP_//; + s/_/-/g; + s/(\w)(\w+)/$1 . lc $2/ge; + $_{$_} = $ENV{$key}; + } + $reqhdrs = join "", map "* $_: $_{$_}\n", sort keys %_; + } + + $body = ""; + # Basic information + $_ = << "EOT"; +[%s] HTTP 500 Server Error Report %s +============================== +* Time: %s +* URI: %s +* Request: %s +* Error Message: + +%s +%s. + +EOT + $body = sprintf $_, $site, fmtdate, + fmttime, $REQUEST_FULLURI, $reqline, + $errmsg, join("\n", map " at $$_[1] line $$_[2]", @callers); + + # Client headers + $body .= "Client Headers:\n$reqhdrs\n"; + + # POSTed form + if (($IS_MODPERL? $r->method: $ENV{"REQUEST_METHOD"}) eq "POST") { + $body .= "POST form:\n"; + if (exists $USER_INPUT{"POST_RAW"}) { + $form = $USER_INPUT{"POST_RAW"}; + } else { + $form = new CGI; + } + $body .= join "", map "* $_: " . $form->param($_) . "\n", + sort $form->param; + $body .= "\n"; + } + + # CGI metavariables - refer to CGI 1.1 + @_ = qw(AUTH_TYPE CONTENT_LENGTH CONTENT_TYPE GATEWAY_INTERFACE + PATH_INFO PATH_TRANSLATED QUERY_STRING REMOTE_ADDR REMOTE_HOST + REMOTE_IDENT REMOTE_USER REQUEST_METHOD SCRIPT_NAME SERVER_PORT + SERVER_PROTOCOL SERVER_SOFTWARE); + $body .= "CGI Metavariables:\n"; + $body .= join "", map "* $_: $ENV{$_}\n", grep exists $ENV{$_}, @_; + $body .= "\n"; + + # Other information + $body .= "Other information:\n"; + if (defined get_login_sn) { + $_ = ""; + $_ .= "* User ID.: " . get_login_id . "\n"; + $_ .= "* User name: " . get_login_name . "\n"; + $_ .= "* User S/N: " . get_login_sn . "\n"; + $_ .= "* User groups: " . join(" ", get_login_groups) . "\n"; + $body .= encode("UTF-8", $_); + } else { + $body .= "* User ID.: (not logged in)\n"; + } + $body .= "* Client country: " . country_lookup . "\n"; + $body .= "\n"; + + # Compose and send the mail + $mail = new Selima::Mail; + $mail->from("HTTP.pm\@" . $ENV{"SERVER_NAME"}, "$site Website"); + $mail->to($webmaster, "$site Webmaster"); + $mail->subject(sprintf("[%s] HTTP 500 Server Error Report %s", $site, fmtdate)); + $mail->body($body); + $mail->send; + } + + # Log the error message to the server error log + log_error("$errmsg " . join(" ", map "at $$_[1] line $$_[2]", @callers) . "."); + + # No need to return + exit 500 if !$IS_CGI; + exit; +} + +# http_503: HTTP/1.1 503 Service Unavailable +sub http_503(;$) { + local ($_, %_); + my ($html, $r, $type, %h); + my $errmsg; + $errmsg = $_[0]; + + # Obtain the Apache mod_perl request + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + # Clear the STDOUT buffer + IO::NestedCapture->stop(CAPTURE_STDOUT) + while exists IO::NestedCapture->instance->{"STDOUT_current"} + && @{IO::NestedCapture->instance->{"STDOUT_current"}} > 0; + # Skip content auto-output + $NO_AUTO_OUTPUT = 1; + + # Obtain the status message + $html = get_custom_status_message(503); + # Fall back to a simplest default + if (!defined $html) { + $html = << "EOT"; + + + + +503 Service Unavailable + + +

    503 Service Unavailable

    + +

    Sorry, our service is currently not available. Please come back later.

    + + +EOT + } + # Replace the page content + $html =~ s//defined $errmsg? "

    " . h($errmsg) . "<\/p>": ""/ge; + # Convert the URLs to relative + $html = page2rel $html, $REQUEST_PATH; + # Encode the e-mail at-signs (@) + $html =~ s/@/@/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap@/spamtrap@/g; + + # Only output headers to the CGI interface + if ($IS_CGI) { + # The mod_perl way + if ($IS_MODPERL) { + # Error documents can only be output as ISO-8859-1 under mod_perl. + # It is hardcoded into Apache http_protocol.c ap_send_error_response(). + # See http://www.geocrawler.com/mail/msg.php3?msg_id=6288656 + $html = page_encode($html, "ISO-8859-1"); + $r->custom_response(503, $html); + $r->status(503); + $r->err_headers_out->set("Content-Language"=>getlang LN_NAME); + $r->err_headers_out->set("Content-Length"=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $r->method ne "POST" + && $r->method ne "PUT" + && !defined $GET->param("lang")) { + $r->err_headers_out->set("Content-Location"=>altlang(getlang, page_param)); + $r->err_headers_out->set("Vary"=>"accept-language,cookie"); + } + $r->err_headers_out->add("Set-Cookie"=>$_) + foreach values %NEWCOOKIES; + + # Ordinary CGI + } else { + $html = page_encode($html, getlang(LN_CHARSET)); + $type = xhtml_content_type . "; charset=" . getlang(LN_CHARSET); + %h = ( -status=>"503 Service Unavailable", + -type=>$type, + -Content_Language=>getlang(LN_NAME), + -Content_Length=>length $html); + # Content negotiation, see HTTP/1.1 section 13.6 + if ( @ALL_LINGUAS > 1 + && $ENV{"REQUEST_METHOD"} ne "POST" + && $ENV{"REQUEST_METHOD"} ne "PUT" + && !defined $GET->param("lang")) { + $h{"-Content_Location"} = altlang getlang, page_param; + $h{"-Vary"} = "accept-language,cookie"; + } + $h{"-cookie"} = [values %NEWCOOKIES]; + print header(%h); + print $html if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Output the content directly as a console application + } else { + print page_encode($html, getlang(LN_CHARSET)) + if $ENV{"REQUEST_METHOD"} ne "HEAD"; + } + + # Log the error message to the server error log + # No logging due to maintainance + # No need to return + exit 503 if !$IS_CGI; + exit; +} + +return 1; diff --git a/lib/perl5/Selima/HTTPS.pm b/lib/perl5/Selima/HTTPS.pm new file mode 100644 index 0000000..36970d0 --- /dev/null +++ b/lib/perl5/Selima/HTTPS.pm @@ -0,0 +1,94 @@ +# Selima Website Content Management System +# HTTPS.pm: The HTTPS SSL subroutines. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-12 + +package Selima::HTTPS; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(https_process https_host fqdn is_https); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub https_process(;$); +sub https_host(); +sub fqdn(); +sub is_https(); +} + +use Socket qw(inet_aton inet_ntoa AF_INET); + +use Selima::Cache qw(:https); +use Selima::DataVars qw(:hostconf); +use Selima::Server; + +# https_process: Use HTTPs to process the request +sub https_process(;$) { + local ($_, %_); + my $https; + $https = $_[0]; + # Set the answer + $HTTPS_https_process = 1 if defined $https; + # Return the answer + return $HTTPS_https_process; +} + +# https_host: The default HTTPs host name +sub https_host() { + local ($_, %_); + # Respect the pre-defined setting + return $HTTPS_HOST if defined $HTTPS_HOST; + # Use the fully-qualified domain name (FQDN) + return ($HTTPS_HOST = fqdn); +} + +# fqdn: The fully qualified domain name +sub fqdn() { + local ($_, %_); + # Return the cache + return $HTTPS_fqdn if defined $HTTPS_fqdn; + + # Use DNS look-up for the current host name + # Apache implementation + $_ = is_apache? $ENV{"SERVER_ADDR"}: + # Microsoft IIS implementation + is_iis? $ENV{"LOCAL_ADDR"}: + # Else, do DNS query + inet_ntoa(scalar gethostbyname $ENV{"SERVER_NAME"}); + # Reverse-DNS query for a fully-qualified domain name (FQDN) + $HTTPS_fqdn = gethostbyaddr inet_aton($_), AF_INET; + + return $HTTPS_fqdn; +} + +# is_https: Check if current scheme is HTTPS +sub is_https() { + local ($_, %_); + # Apache implementation + return exists $ENV{"HTTPS"} if is_apache; + # Microsoft IIS implementation + return exists $ENV{"SERVER_PORT_SECURE"} if is_iis; + # Well, set port 443 to https and others to http. + # This is a bad approach. Avoid it whenever possible. + return ($ENV{"SERVER_PORT"} == 443); +} + +return 1; diff --git a/lib/perl5/Selima/Init.pm b/lib/perl5/Selima/Init.pm new file mode 100644 index 0000000..54b12f0 --- /dev/null +++ b/lib/perl5/Selima/Init.pm @@ -0,0 +1,351 @@ +# Selima Website Content Management System +# Init.pm: The script initializer. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-23 + +package Selima::Init; +use 5.008; +use utf8; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(initvars initenv); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub initvars($); +sub initenv(%); +sub check_spambots(); +sub block_spam($); +} + +use Fcntl qw(:flock); +use File::Basename qw(basename); +use File::Spec::Functions qw(splitpath splitdir catpath catdir catfile); +use IO::NestedCapture qw(CAPTURE_STDOUT); +use POSIX qw(setlocale LC_ALL); +use Sys::Hostname qw(hostname); +use Time::HiRes qw(); +use URI qw(); +use URI::Escape qw(uri_unescape); + +BEGIN { +if (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + require Apache2::RequestRec; +} +} + +use Selima::Cache qw(); +use Selima::CallForm; +use Selima::DataVars qw(:all); +use Selima::DBI; +use Selima::DecForm; +use Selima::FormFunc; +use Selima::HTTP; +use Selima::LastModf; +use Selima::ListPref; +use Selima::LogIn; +use Selima::Logging; +use Selima::ReqURI; +use Selima::ScptPriv; +use Selima::SetL10N; +use Selima::ShortCut; +use Selima::Session; +use Selima::Unauth; + +# initvars: Initialize the data variables +sub initvars($) { + local ($_, %_); + my ($pkg, $r); + $pkg = $_[0]; + + # Only run once for mod_perl + if ($IS_MODPERL) { + $r = $IS_MP2? Apache2::RequestUtil->request: + Apache->request; + # Bounce if already initialized under mod_perl + return if defined $r->headers_in->get("X-Selima-Initialized"); + $r->headers_in->set("X-Selima-Initialized", "yes"); + # Clean-up before initialization, only for mod_perl + Selima::DataVars::clear; + Selima::Cache::clear; + # Cear the site data variables + if (defined $pkg) { + $_ = "Selima::" . $pkg . "::DataVars"; + &$_ if defined($_ = $_->can("clear")); + } + } + + # Set the default values of some variables + # By default we use PostgreSQL, unless changed by site configuration + $DBI_TYPE = DBI_POSTGRESQL; + + # The script path + %SCRIPTS = ( + FORM_USERS() => "/magicat/cgi-bin/users.cgi", + FORM_GROUPS() => "/magicat/cgi-bin/groups.cgi", + FORM_USERMEM() => "/magicat/cgi-bin/usermem.cgi", + FORM_GROUPMEM() => "/magicat/cgi-bin/groupmem.cgi", + FORM_USERPREF() => "/magicat/cgi-bin/userpref.cgi", + FORM_SCPTPRIV() => "/magicat/cgi-bin/scpptpriv.cgi", + FORM_PIC() => "/magicat/cgi-bin/pic.cgi", + FORM_PAGES() => "/magicat/cgi-bin/pages.cgi", + FORM_NEWS() => "/magicat/cgi-bin/news.cgi", + FORM_LINKCAT() => "/magicat/cgi-bin/linkcat.cgi", + FORM_LINKS() => "/magicat/cgi-bin/links.cgi", + FORM_ACCTSUBJ() => "/magicat/cgi-bin/acctsubj.cgi", + FORM_ACCTTRX() => "/magicat/cgi-bin/accttrx.cgi", + ); + + $NOLOGIN = 0; + + $DEFAULT_LANG = "zh-tw"; + + $PAGEBAR_RANGE = 2; + + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + $NO_AUTO_OUTPUT = 0; + + $LOGTIME = 0; + $T_START = Time::HiRes::time; + + # Load the site and host configuration + if (defined $pkg) { + # Load the site configuration + $_ = "Selima::" . $pkg . "::Config"; + &$_ if defined($_ = $_->can("siteconf")); + # Load the host-specific configuration + $_ = "Selima::" . $pkg . "::HostConf"; + &$_ if defined($_ = $_->can("hostconf")); + # Look for siteconf() and hostconf() imported to the caller + } else { + (caller 1)[0]->siteconf if (caller 1)[0]->can("siteconf"); + (caller 1)[0]->hostconf if (caller 1)[0]->can("hostconf"); + } + + # Set $0 of the non-CGI scripts + if (!$IS_CGI) { + # Deal with the relative path + require FindBin; + if ($FindBin::Script ne "-" && $FindBin::Script ne "-e") { + @_ = splitpath($FindBin::Bin); + $_[1] = catdir(splitdir($_[1])); + $_ = catpath(@_); + $0 = catfile($_, $FindBin::Script); + } + } + + # Emulate the CGI environment, if not + if (!$IS_CGI) { + $ENV{"GATEWAY_INTERFACE"} = ""; + $ENV{"QUERY_STRING"} = "" if !exists $ENV{"QUERY_STRING"}; + $ENV{"REMOTE_ADDR"} = "127.0.0.1" if !exists $ENV{"REMOTE_ADDR"}; + $ENV{"REMOTE_HOST"} = "localhost" if !exists $ENV{"REMOTE_HOST"}; + $ENV{"REQUEST_METHOD"} = "GET" if !exists $ENV{"REQUEST_METHOD"}; + $ENV{"SCRIPT_NAME"} = $0 if !exists $ENV{"SCRIPT_NAME"}; + $ENV{"SERVER_NAME"} = hostname if !exists $ENV{"SERVER_NAME"}; + $ENV{"SERVER_PORT"} = 80 if !exists $ENV{"SERVER_PORT"}; + $ENV{"SERVER_SOFTWARE"} = $^O if !exists $ENV{"SERVER_SOFTWARE"}; + } + + # Try to obtain the request information + init_request_uri; + # Scan the parameters + %COOKIES = fetch CGI::Cookie; + init_forms; + # Initialize the localization framework (gettext/Maketext) + # This runs gettext implicitly + set_l10n; + decode_forms; + # Set the path of the this processing form + $SCRIPTS{FORM_THIS()} = form_this; + + return; +} + +# initenv: Initialize the script environment +sub initenv(%) { + local ($_, %_); + my (%param); + my ($dbi, $session, $restricted, $lastmod); + %param = @_; + + # Initialize the data variables and cache + $MAIN = (caller)[0]; + &$_ if defined($_ = $MAIN->can("siteconf")); + initvars $PACKAGE; + decode_forms_delay; + # Load the script configuration + $THIS_FILE = basename($0); + # $MAIN was cleaned-up in initvars(), so we need to obtain it again + $MAIN = (caller)[0]; + &$_ if defined($_ = $MAIN->can("scptconf")); + + # Parse the arguments + $dbi = exists $param{"-dbi"}? $param{"-dbi"}: + defined $DBI_TYPE? $DBI_TYPE: DBI_NONE; + $session = exists $param{"-session"}? $param{"-session"}: 1; + $restricted = exists $param{"-restricted"}? $param{"-restricted"}: 0; + $lastmod = exists $param{"-lastmod"}? $param{"-lastmod"}: 0; + # Tag if we should log the processing time + $LOGTIME = $param{"-logtime"} if exists $param{"-logtime"}; + if (exists $param{"-page_param"}) { + $PAGE_PARAM = $param{"-page_param"}; + # Maketext now, since we have already set_l10n() in initvars() + $$PAGE_PARAM{"keywords"} = __($$PAGE_PARAM{"keywords"}) + if exists $$PAGE_PARAM{"keywords"}; + } + + # Block FunWebProduct + # See http://www.networkworld.com/newsletters/web/2003/1208web2.html + http_403(N_("Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) are are not welcome. It duplicates your request and produces high load and even crashes to our server. Please remove it first before you visit us.")) + if exists $ENV{"HTTP_USER_AGENT"} + && $ENV{"HTTP_USER_AGENT"} =~ /FunWebProduct/; + # Block bad-behaved e-mail crawlers + # Some bad-behaved e-mail crawlers cannot deal with the parent + # directory "/.." and ampersands, and attach them to the URI infinitely + http_400(0) if $REQUEST_PATH =~ /\/\.\./ || $REQUEST_URI =~ /&/; + # Check the request method + $_ = exists $param{"-allowed"}? $param{"-allowed"}: [qw(GET HEAD POST)]; + if (defined $_) { + %_ = map { $_ => 1 } @$_; + http_405 @$_ if !exists $_{$ENV{"REQUEST_METHOD"}}; + } + # Check and block the spambots + check_spambots; + + # Start the session + $SESSION = Selima::Session->init if $session; + + # If client has not logged in on restricted area, we can + # bypass SQL connection to save our work + if ($IS_CGI && $restricted) { + if (exists $INC{"Apache/AuthDigest/API.pm"}) { + unauth if !defined $AUTHINFO; + } else { + unauth if !exists $ENV{"REMOTE_USER"}; + } + } + + # Initialize the database connection + if ($dbi) { + $DBH = Selima::DBI->new($dbi) ; + # Set the current table + $THIS_TABLE = $param{"-this_table"} if exists $param{"-this_table"}; + } + + # Prepare the SQL tables to lock + if ($dbi && exists $param{"-dbi_lock"}) { + # Read-only on non-POSTed forms + if ($ENV{"REQUEST_METHOD"} ne "POST") { + ${$param{"-dbi_lock"}}{$_} = LOCK_SH + foreach keys %{$param{"-dbi_lock"}}; + } + # Supply the default locks + if (use_users) { + ${$param{"-dbi_lock"}}{$_} = LOCK_SH + foreach grep !exists ${$param{"-dbi_lock"}}{$_}, + (qw(users groups scptpriv userpref), + "users AS createdby", "users AS updatedby"); + } + } + + # Check the last modified + if ($lastmod) { + my (@tables, @files); + # Set the database tables to check + @tables = qw(); + push @tables, @{$param{"-lmtables"}} if exists $param{"-lmtables"}; + # Add the locked tables automatically + push @tables, keys %{$param{"-dbi_lock"}} if exists $param{"-dbi_lock"}; + # Set the files to check + @files = qw(); + push @files, @{$param{"-lmfiles"}} if exists $param{"-lmfiles"}; + http_304 if not_modified @tables, @files; + } + + # Lock the SQL tables + $DBH->lock(%{$param{"-dbi_lock"}}) + if $dbi && exists $param{"-dbi_lock"}; + + # Only available on systems with membership turned on + if ($dbi && use_users && $session) { + # Update the log-in information + if (exists $INC{"Apache/AuthDigest/API.pm"}) { + upd_login_info if defined $AUTHINFO; + } else { + upd_login_info if exists $ENV{"REMOTE_USER"}; + upd_login_info if !$IS_CGI; + } + # Check the client permission + unauth if $restricted && !is_script_permitted; + } + + # Process the list preference form + if (form_type eq "listpref") { + my $domain; + if ( defined($domain = $POST->param("domain")) + && $domain->can("new")) { + $_ = $domain->new; + $_->set_listpref; + } else { + $_ = new Selima::ListPref($POST); + $_->main; + } + } + + return; +} + +# check_spambots: Check and block spam bots +# This starts at an earlier phrase before the database initialization, +# to decrease the server load. +sub check_spambots() { + local ($_, %_); + my ($r, $method, $col); + if ($IS_MODPERL) { + $r = $IS_MP2? Apache2::RequestUtil->request: + Apache->request; + $method = $r->method; + } else { + $method = $ENV{"REQUEST_METHOD"}; + } + $col = FORM_CAPTCHA; + # Block the spam for POST forms + if ($method eq "POST" && defined $POST->param($col)) { + block_spam "check_spambots: captcha column \"$col\" should be empty but got \"" + . $POST->param($col) . "\"." + if $POST->param($col) ne ""; + } +} + +# block_spam: Block the spam message +sub block_spam($) { + local ($_, %_); + $_ = $_[0]; + spamlog $_; + # Delay the spammer + sleep 300; + http_403(0); + # No return +} + +no utf8; +return 1; diff --git a/lib/perl5/Selima/L10N.pm b/lib/perl5/Selima/L10N.pm new file mode 100644 index 0000000..3b94c31 --- /dev/null +++ b/lib/perl5/Selima/L10N.pm @@ -0,0 +1,106 @@ +# Selima Website Content Management System +# L10N.pm: The core localization class. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-21 + +package Selima::L10N; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +return 1; + +# The core Chinese (Taiwan) localized messages. +package Selima::L10N::zh_tw; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +sub numerate : method { $_[2] } + +return 1; + +# The core Chinese (China) localized messages. +package Selima::L10N::zh_cn; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +sub numerate : method { $_[2] } + +return 1; + +# The core Chinese localized messages. +package Selima::L10N::zh; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +sub numerate : method { $_[2] } + +return 1; + +# The core English localized messages. +package Selima::L10N::en; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +return 1; + +# The core English (United States) localized messages. +package Selima::L10N::en_us; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +return 1; + +# The core default-language localized messages. +package Selima::L10N::i_default; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +return 1; + + +# The core automatic localized messages. +package Selima::_AUTO::L10N; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +return 1; + +# The core automatic default-language localized messages. +package Selima::_AUTO::L10N::i_default; +use 5.008; +use strict; +use warnings; +use base qw(Locale::Maketext::Gettext); + +return 1; diff --git a/lib/perl5/Selima/LastModf.pm b/lib/perl5/Selima/LastModf.pm new file mode 100644 index 0000000..b1049d9 --- /dev/null +++ b/lib/perl5/Selima/LastModf.pm @@ -0,0 +1,173 @@ +# Selima Website Content Management System +# LastModf.pm: The web site last-modified time calculator. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-23 + +package Selima::LastModf; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(not_modified); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub not_modified(\@\@); +sub find_last_modified(\@\@); +sub check_inc(); +sub updmtime_tables(\@); +sub updmtime_file($); +} + +use File::Spec::Functions qw(catfile); +use HTTP::Date qw(str2time); + +use Selima::CallForm; +use Selima::DataVars qw($DBH :input :l10n :lninfo :lastmod :libdir :requri :siteconf); +use Selima::GetLang; +use Selima::HTTP; +use Selima::Session; + +# not_modified: Check if we should send "HTTP/1.1 304 Not Modified" +sub not_modified(\@\@) { + local ($_, %_); + my ($tables, $files); + ($tables, $files) = @_; + # HTTP/1.1 304 only works for GET or HEAD + return 0 unless $ENV{"REQUEST_METHOD"} eq "GET" + || $ENV{"REQUEST_METHOD"} eq "HEAD"; + # Find the last-modified time + find_last_modified @$tables, @$files; + # If-Modified-Since not supplied. The client had not cached yet. + return 0 if !exists $ENV{"HTTP_IF_MODIFIED_SINCE"}; + # Malformed If-Modified-Since value + return 0 if !defined($_ = str2time($ENV{"HTTP_IF_MODIFIED_SINCE"})); + # We are newer than the cache + return 0 if $LAST_MODIFIED > $_; + # Yes, use the cache + return 1; +} + +# find_last_modified: Find the last-modified time +sub find_last_modified(\@\@) { + local ($_, %_); + my ($tables, $files); + ($tables, $files) = @_; + + # Checked before + return if defined $LAST_MODIFIED; + + # Remove duplicates + %_ = map { $_ => 1 } @$tables; + @$tables = keys %_; + %_ = map { $_ => 1 } @$files; + @$files = keys %_; + + # Start with EPOCH 1970-01-01 00:00:00 + $LAST_MODIFIED = 0; + + # Check myself + updmtime_file $0; + # Check mtime from the included modules and gettext MO files + check_inc; + # Check the supplied data files + updmtime_file $_ foreach grep -f $_, @$files; + # Check the supplied data tables + updmtime_tables @$tables; + # Check the saved form and status + if (defined $GET->param("formid")) { + $_ = catfile($Selima::Session::DIR, "saveform_" . $GET->param("formid")); + updmtime_file $_ if -f $_; + } + if (defined $GET->param("statid")) { + $_ = catfile($Selima::Session::DIR, "savestat_" . $GET->param("statid")); + updmtime_file $_ if -f $_; + } + + return; +} + +# check_inc: Check mtime from the included modules and gettext MO files +sub check_inc() { + local ($_, %_); + my ($t, $DH); + + # Check the included modules + updmtime_file $_ foreach grep /^\Q$SITE_LIBDIR\E\b/, values %INC; + $t = COMMON_LIBDIR; + updmtime_file $_ foreach grep /^$t\b/, values %INC; + + # Check the header and footer + $_ = $DOC_ROOT . "/magicat/include"; + @_ = qw(); + if (@ALL_LINGUAS > 1) { + push @_, $_ . "/header." . getlang(LN_FILENAME) . ".html"; + push @_, $_ . "/footer." . getlang(LN_FILENAME) . ".html"; + } else { + push @_, $_ . "/header.html"; + push @_, $_ . "/footer.html"; + } + foreach (@_) { + updmtime_file $_ if -e $_; + } + + # Check the gettext mo files + if (-d $LOCALEDIR) { + opendir $DH, $LOCALEDIR or http_500 "$LOCALEDIR: $!"; + @_ = readdir $DH or http_500 "$LOCALEDIR: $!"; + closedir $DH or http_500 "$LOCALEDIR: $!"; + foreach (@_) { + $_ = "$LOCALEDIR/$_/LC_MESSAGES/$PACKAGE.mo"; + updmtime_file $_ if -f $_; + } + } + opendir $DH, COMMON_LOCALEDIR or http_500 COMMON_LOCALEDIR . ": $!"; + @_ = readdir $DH or http_500 COMMON_LOCALEDIR . ": $!"; + closedir $DH or http_500 COMMON_LOCALEDIR . ": $!"; + foreach (@_) { + $_ = COMMON_LOCALEDIR . "/$_/LC_MESSAGES/" . COMMON_DOMAIN . ".mo"; + updmtime_file $_ if -f $_; + } + + return; +} + +# updmtime_tables: Update the $LAST_MODIFIED with the mtime of tables +sub updmtime_tables(\@) { + local ($_, %_); + my ($tables, $sql, $sth); + $tables = $_[0]; + # Only work when using database + return if !defined $DBH; + + return unless defined($_ = $DBH->lastupd(@$tables)); + $_ = int $_; + $LAST_MODIFIED = $_ if defined $_ && $LAST_MODIFIED < $_; + return; +} + +# updmtime_file: Update the $LAST_MODIFIED with the mtime of a file +sub updmtime_file($) { + local ($_, %_); + $_ = (stat $_[0])[9]; + $LAST_MODIFIED = $_ if $LAST_MODIFIED < $_; + return; +} + +return 1; diff --git a/lib/perl5/Selima/Links.pm b/lib/perl5/Selima/Links.pm new file mode 100644 index 0000000..02b8327 --- /dev/null +++ b/lib/perl5/Selima/Links.pm @@ -0,0 +1,364 @@ +# Selima Website Content Management System +# Links.pm: The related-link related subroutines. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::Links; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(linkcat_title linkcat_options link_title); +push @EXPORT, qw(links_shown_parts link_tree link_tree_full); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub linkcat_title($); +sub linkcat_options($); +sub link_title($); +sub links_shown_parts(); +sub link_tree($$;$); +sub link_tree_full($;$); +sub link_subtree($$$;$); +} + +use Encode qw(decode); + +use Selima::Cache qw(:links); +use Selima::ChkFunc; +use Selima::CommText; +use Selima::DataVars qw($DBH :l10n :lninfo); +use Selima::EchoForm; +use Selima::GetLang; +use Selima::LnInfo; +use Selima::PageFunc; +use Selima::ShortCut; + +# linkcat_title: Obtain a link category title +sub linkcat_title($) { + local ($_, %_); + my ($sn, $sql, $sth, $col, $thiscol, $lang, $defcol); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + # Return the cache + return $Links_linkcat_title{$sn} if exists $Links_linkcat_title{$sn}; + + # Check the serial number first + return ($Links_linkcat_title{$sn} = t_na) + if !check_sn $sn; + + # Query + # Unilingual + if (@ALL_LINGUAS == 1) { + $col = "linkcat_fulltitle(parent, title) AS title"; + # Multilingual + } else { + $thiscol = "title_" . getlang LN_DATABASE; + $lang = getlang; + # Default language + if ($lang eq $DEFAULT_LANG) { + $col = "linkcat_fulltitle('$lang', parent, $thiscol) AS title"; + # Fall back to the default language + } else { + $defcol = "title_" . ln($DEFAULT_LANG, LN_DATABASE); + $col = "linkcat_fulltitle('$lang', parent, COALESCE($thiscol, $defcol)) AS title"; + } + } + $sql = "SELECT $col FROM linkcat WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return ($Links_linkcat_title{$sn} = t_na) + unless $sth->rows == 1; + + # Found + return ($Links_linkcat_title{$sn} = ${$sth->fetch}[0]); +} + +# linkcat_options: Obtain a link category options list +sub linkcat_options($) { + local ($_, %_); + my ($value, $sql, $thiscol, $defcol, $lang, $content); + $value = $_[0]; + + # Unilingual + if (@ALL_LINGUAS == 1) { + $content = "linkcat_fulltitle(parent, title) AS content"; + # Multilingual + } else { + $thiscol = "title_" . getlang(LN_DATABASE); + $lang = getlang; + # Default language + if ($lang eq $DEFAULT_LANG) { + $content = "linkcat_fulltitle('$lang', parent, $thiscol) AS content"; + # Fall back to the default language + } else { + $defcol = "title_" . ln($DEFAULT_LANG, LN_DATABASE); + $content = "linkcat_fulltitle('$lang', parent, COALESCE($thiscol, $defcol)) AS content"; + } + } + $sql = "SELECT sn AS value, $content FROM linkcat" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + return opt_list $sql, $value; +} + +# link_title: Obtain a link title +sub link_title($) { + local ($_, %_); + my ($sn, $sql, $sth, $thiscol, $defcol); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + # Return the cache + return $Links_link_title{$sn} if exists $Links_link_title{$sn}; + + # Check the serial number first + return ($Links_link_title{$sn} = t_na) + if !check_sn $sn; + + # Query + $sql = "SELECT title FROM links WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return ($Links_link_title{$sn} = t_na) + unless $sth->rows == 1; + + # Found + return ($Links_link_title{$sn} = ${$sth->fetch}[0]); +} + +# link_url: Obtain a link URL +sub link_url($) { + local ($_, %_); + my ($sn, $sql, $sth, $thiscol, $defcol); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + # Return the cache + return $Links_link_title{$sn} if exists $Links_link_title{$sn}; + + # Check the serial number first + return ($Links_link_title{$sn} = t_na) + if !check_sn $sn; + + # Query + $sql = "SELECT url FROM links WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return ($Links_link_title{$sn} = t_na) + unless $sth->rows == 1; + + # Found + return ($Links_link_title{$sn} = ${$sth->fetch}[0]); +} + +# links_shown_parts: Obtain the shown links parts +sub links_shown_parts() { + local ($_, %_); + my ($sql, $sth, $count, $row, $path); + + %_ = ( + "cats" => [], + "catspath" => [], + ); + + # Obtain the shown categories + $path = $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT sn, $path FROM linkcat" + . " WHERE linkcat_isshown(sn, hid, parent)" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0; $_ < $count; $_++) { + $row = $sth->fetchrow_hashref; + push @{$_{"cats"}}, $$row{"sn"}; + push @{$_{"catspath"}}, $$row{"path"}; + } + @{$_{"cats"}} = sort @{$_{"cats"}}; + @{$_{"catspath"}} = sort @{$_{"catspath"}}; + + return \%_; +} + + +#################### +# Subroutines about link categories +#################### +# link_tree: Get the page tree of the links +sub link_tree($$;$) { + local ($_, %_); + my ($path, $lang, $preview, $dir, $tree); + ($path, $lang, $preview) = @_; + # Obtain the directory + $dir = $path; + $dir =~ s/[^\/]+\/?$//; + + # Initialize the directory array + $Links_link_tree{$lang} = {} + if !exists $Links_link_tree{$lang}; + # Return the cache + return ${$Links_link_tree{$lang}}{$dir} + if exists ${$Links_link_tree{$lang}}{$dir}; + + # Get the full page tree of the links + $tree = link_tree_full $lang, $preview; + # Make a hash of the page tree + $Links_link_tree{$lang} = {hash_tree $tree}; + + # Not found + return undef if !exists ${$Links_link_tree{$lang}}{$dir}; + return ${$Links_link_tree{$lang}}{$dir}; +} + +# link_tree_full: Get the page tree of the links +sub link_tree_full($;$) { + local ($_, %_); + my ($lang, $preview, $charset, $tree, $pages); + ($lang, $preview) = @_; + # Return the cache + return $Links_link_tree_full{$lang} + if exists $Links_link_tree_full{$lang}; + + # Set the language + $charset = ln($lang, LN_CHARSET); + + # Initialize the result + $tree = qw(); + + # Set the index page + $$tree{"index"} = { + "path" => "/links/", + "title" => C_("Related Links"), + }; + + # Get the link categories + $pages = link_subtree "/links", undef, $lang, $preview; + $$tree{"pages"} = $pages if defined $pages; + + return $tree; +} + +# link_subtree: Get the page subtree of the links +sub link_subtree($$$;$) { + local ($_, %_); + my ($path, $parent, $lang, $preview); + my ($lndb, $lndbdef, $has_links, $pages); + my ($sql, $sth, $count, @cols, @conds); + ($path, $parent, $lang, $preview) = @_; + + # Check if there is any link below this category + $has_links = 0; + if (defined $parent) { + $sql = "SELECT links.sn FROM links" + . " INNER JOIN linkcatz ON linkcatz.link=links.sn" + . " WHERE linkcatz.cat=" . $parent + . " AND NOT links.hid;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $has_links = ($sth->rows > 0); + # Check the preview + $has_links = in_array($parent, @{$$preview{"cats"}}) + if !$has_links && defined $preview; + } + + # Obtain the subcategories + @cols = qw(); + push @cols, "sn AS sn"; + push @cols, "id AS id"; + # Unilingual + if (@ALL_LINGUAS == 1) { + push @cols, "title AS title"; + # Multilingual + } else { + # Set the language + $lndb = ln $lang, LN_DATABASE; + if ($lang eq $DEFAULT_LANG) { + push @cols, "title_$lndb AS title"; + } else { + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + push @cols, "COALESCE(title_$lndb, title_$lndbdef)" + . " AS title"; + } + } + push @cols, "ord AS ord"; + @conds = qw(); + if (!defined $parent) { + push @conds, "parent IS NULL"; + } else { + push @conds, "parent=$parent"; + } + push @conds, "NOT hid"; + push @conds, "sn!=" . $$preview{"sn"} + if defined $preview && exists $$preview{"sn"}; + $sql = "SELECT " . join(", ", @cols) . " FROM linkcat" + . " WHERE " . join(" AND ", @conds) + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, $pages = []; $_ < $count; $_++) { + my ($row, $subpages, $subpath); + $row = $sth->fetchrow_hashref; + $subpages = link_subtree($path . "/" . $$row{"id"}, + $$row{"sn"}, $lang, $preview); + # Only create subtree that has some content + if (defined $subpages) { + # No subcategories -- create it as a ".html" page + if (@$subpages == 0) { + $subpath = $path . "/" . $$row{"id"} . ".html"; + push @$pages, { + "path" => $subpath, + "title" => $$row{"title"}, + "ord" => $$row{"ord"}, + }; + # There are subcatgories -- create it as a directory + } else { + $subpath = $path . "/" . $$row{"id"} . "/"; + push @$pages, { + "path" => $subpath, + "title" => $$row{"title"}, + "ord" => $$row{"ord"}, + "sub" => { + "index" => { + "path" => $subpath, + "title" => $$row{"title"}, + }, + "pages" => $subpages, + }, + }; + } + } + } + + # No content below + return undef if !$has_links && @$pages == 0; + + return $pages; +} + +return 1; diff --git a/lib/perl5/Selima/List.pm b/lib/perl5/Selima/List.pm new file mode 100644 index 0000000..ef98865 --- /dev/null +++ b/lib/perl5/Selima/List.pm @@ -0,0 +1,1619 @@ +# Selima Website Content Management System +# List.pm: The base list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-09 + +package Selima::List; +use 5.008; +use utf8; +use strict; +use warnings; +BEGIN { +# Prototype declaration +sub urlcheck(\@); +} + +use CGI qw(); +use Encode qw(encode decode FB_CROAK); +use HTML::Strip qw(); +use IPC::Open3 qw(open3); +use POSIX qw(floor); + +use Selima::AddGet; +use Selima::Array; +use Selima::CommText; +use Selima::ChkFunc; +use Selima::DataVars qw($SESSION :db :env :l10n :libdir :lninfo :requri); +use Selima::DBI; +use Selima::ErrMsg; +use Selima::FormFunc; +use Selima::GetLang; +use Selima::ListPref; +use Selima::LogIn; +use Selima::HTTP; +use Selima::MarkAbbr; +use Selima::Query; +use Selima::ShortCut; +use Selima::Unicode; +use Selima::UserPref; + +# Load these classes +use Selima::List::Users; +use Selima::List::Groups; +use Selima::List::UserMem; +use Selima::List::GroupMem; +use Selima::List::UserPref; +use Selima::List::ScptPriv; + +use Selima::List::Guestbook; +use Selima::List::Guestbook::Public; +use Selima::List::Pages; +use Selima::List::LinkCat; +use Selima::List::Links; +use Selima::List::LinkCatz; + +use Selima::List::Category; +use Selima::List::Categorz; +use Selima::List::ActLog; + +use Selima::List::Accounting::Subjects; +use Selima::List::Accounting::Subjects::LastLv; +use Selima::List::Accounting::Transacts; +use Selima::List::Accounting::Records; +use Selima::List::Accounting::Reports; +use Selima::List::Accounting::Reports::Cash::Summary; +use Selima::List::Accounting::Reports::Cash; +use Selima::List::Accounting::Reports::Ledger; +use Selima::List::Accounting::Reports::Ledger::Summary; +use Selima::List::Accounting::Reports::Journal; +use Selima::List::Accounting::Reports::TriBlnc; +use Selima::List::Accounting::Reports::IncmStat; +use Selima::List::Accounting::Reports::BlncShet; +use Selima::List::Accounting::Reports::Search; + +use vars qw(@URLCHECK); +@URLCHECK = (COMMON_LIBDIR . "/Selima/urlcheck"); + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class, $FORM, $table); + ($class, $FORM, $table) = @_; + $class = ref $class if ref $class ne ""; + $self = bless {}, $class; + + $FORM = curform if !defined $FORM; + $self->{"FORM"} = $FORM; + $self->{"table"} = $table; + + $self->{"pageno"} = $FORM->param("pageno"); + $self->{"sortby"} = $FORM->param("sortby"); + $self->{"query"} = $FORM->param("query"); + $self->{"useview"} = $DBH->support(DBI_FEATHER_VIEW) + if defined $DBH; + $self->{"reverse"} = 0; + $self->{"static"} = 0; + $self->{"static_filepat"} = "%04d.html"; + $self->{"static_lastfile"} = "last.html"; + $self->{"limit"} = undef; + + # The default column labels + + # Parameters for the called forms + $self->{"caller"} = $FORM->param("caller"); + $self->{"cformid"} = $FORM->param("cformid"); + $self->{"is_called_form"} = defined $self->{"caller"} + && defined $self->{"cformid"}; + if ($self->{"is_called_form"}) { + $self->{"seltext"} = C_("Select"); + $self->{"selurl_tmpl"} = $self->{"caller"} + . "?formid=" . $self->{"cformid"} . "&selsn=%d"; + $self->{"title"} = C_("Select A Data Record"); + } else { + $self->{"seltext"} = C_("Edit"); + $self->{"selurl_tmpl"} = $REQUEST_FILE . "?form=cur&sn=%d"; + $self->{"title"} = C_("Manage Data"); + } + + $self->{"fetched"} = 0; + $self->{"error"} = {}; + # The default number of rows per page -- when user preference system is not available + $self->{"DEFAULT_LIST_SIZE"} = 10; + $self->{"DEFAULT_LIST_COLS"} = [qw(sn)]; + # The default sort order -- for non-VIEW lists only + $self->{"DEFAULT_SORTBY"} = undef; + # The list brief size + $self->{"DEFAULT_BRIEF_LEN"} = 30; + # The query abstract span from the found phrase + $self->{"QABS_SPAN"} = 30; + # The maximum query abstract length + $self->{"QABS_MAXLEN"} = 200; + + $self->{"total"} = undef; + $self->{"lastpage"} = undef; + $self->{"massdel"} = 0; + $self->{"noselect"} = 0; + $self->{"col_labels"} = {}; + + # Default settings + # Known columns that should not be displayed (has a special purpose) + $self->{"COLS_NO_DISPLAY"} = [qw(_viewurl _sel _selurl _statord)]; + # Known columns that should never be searched against + $self->{"COLS_NO_SEARCH"} = [qw(pic _urlcheck _viewurl _sel _selurl _statord)]; + # Known columns that should not be sorted with + $self->{"COLS_NO_SORT_BY"} = [qw(_urlcheck _viewurl _sel _selurl _statord)]; + # Columns that should display its brief instead + $self->{"COLS_BRIEF"} = []; + + # Intermediate parsing results when fetching a list + $self->{"coldefs"} = []; + $self->{"sortkeys"} = []; + $self->{"query_phrases"} = []; + $self->{"listcols"} = []; + + # The default column labels + $self->col_labels( + # Common labels shared by all list handlers + "sn" => C_("S/N"), + "created" => C_("Created"), + "createdby" => C_("Created by"), + "updated" => C_("Updated"), + "updatedby" => C_("Updated by"), + # Other commonly-seen column labels + "body" => C_("Content"), + "cat" => C_("Category"), + "date" => C_("Date"), + "disabled" => C_("Disabled?"), + "dsc" => C_("Description"), + "email" => C_("E-mail"), + "hid" => C_("Hidden?"), + "html" => C_("HTML?"), + "id" => C_("ID."), + "kw" => C_("Keywords"), + "name" => C_("Name"), + "ord" => C_("Order"), + "path" => C_("Page path"), + "pic" => C_("Picture"), + "picratio" => C_("Pic. ratio"), + "piccap" => C_("Pic. caption"), + "picpos" => C_("Pic. position"), + "title" => C_("Title"), + "title_en" => C_("English title"), + "url" => C_("URL."), + "_urlcheck" => C_("Status (slow)"), + ); + + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, $cols, $table, $where, $orderby, $limit, $sth, $sql, $error); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + $self->{"total"} = undef; + + # See if we need to use views or not. + # Views make things much faster and easier, but some DBMS has no views. + # *MySQL has no views* + if ($self->{"useview"}) { + ($cols, $table, $where, $orderby, $limit) = $self->select_with_view; + } else { + ($cols, $table, $where, $orderby, $limit) = $self->select_without_view; + } + + # The number of rows per page + $_ = userpref("listsize", ref $self); + $self->{"pagesize"} = defined $_? $_: $self->{"DEFAULT_LIST_SIZE"}; + # Paging not in use + if (!defined $self->{"pagesize"}) { + $self->{"select"} = sprintf "SELECT %s FROM %s%s%s%s;\n", + $cols, $table, $where, $orderby, $limit; + $sql = $self->{"select"}; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Fetch everything + $self->{"current"} = []; + push @{$self->{"current"}}, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + + $self->{"total"} = scalar(@{$self->{"current"}}); + $self->{"lastpage"} = 1; + $self->{"startno"} = 0; + $self->{"endno"} = $self->{"total"} - 1; + # If endno is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Done + return $self->{"error"}; + } + + # Obtain the total number + $self->{"select_total"} = sprintf "SELECT count(*) FROM %s%s%s;\n", $table, $where, $limit; + $sql = $self->{"select_total"}; + $sth = $DBH->prepare($sql); + $sth->execute; + $self->{"total"} = ($sth->fetchrow_array)[0]; + undef $sth; + $self->{"lastpage"} = floor(($self->{"total"} - 1) / $self->{"pagesize"}) + 1; + # If last page is 0 (when total is 0), set to page 1 + $self->{"lastpage"} = 1 if $self->{"lastpage"} < 1; + + # Check the page number + $error = $self->check_pageno; + $self->{"error"} = $error if defined $error && !defined $self->{"error"}; + + # Calculate the start and end record number + $self->{"startno"} = ($self->{"pageno"} - 1) * $self->{"pagesize"}; + $self->{"endno"} = $self->{"pageno"} * $self->{"pagesize"} - 1; + # If there is not enough remaining records, set to the last one + $self->{"endno"} = $self->{"total"} - 1 + if $self->{"endno"} > $self->{"total"} - 1; + # If the last record is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Obtain everything in this page + $self->{"current"} = []; + if (!$self->{"reverse"}) { + $self->{"select"} = sprintf "SELECT %s FROM %s%s%s LIMIT %d OFFSET %d;\n", + $cols, $table, $where, $orderby, + $self->{"endno"} - $self->{"startno"} + 1, + $self->{"startno"}; + } else { + $self->{"select"} = sprintf "SELECT %s FROM %s%s%s LIMIT %d OFFSET %d;\n", + $cols, $table, $where, $orderby, + $self->{"endno"} - $self->{"startno"} + 1, + $self->{"total"} - $self->{"endno"} - 1; + } + # If not empty + if ($self->{"total"} > 0) { + $sql = $self->{"select"}; + $sth = $DBH->prepare($sql); + $sth->execute; + push @{$self->{"current"}}, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + } + + # Set the columns to be displayed + $self->check_listcols; + # Done + return $self->{"error"}; +} + +# page_param: Obtain page parameters +sub page_param : method { + local ($_, %_); + my ($self, $baseurl); + $self = $_[0]; + # Fetch the current list if not fetched yet + $self->fetch if !$self->{"fetched"}; + $_ = {}; + # The onload event handler + $$_{"onload"} = $self->{"onload"} if exists $self->{"onload"}; + # No paging + return if !defined $self->{"DEFAULT_LIST_SIZE"}; + # Do not show the list + return if !defined $self->{"total"}; + # No record to be listed + return if $self->{"total"} == 0; + # Our base URL + $baseurl = rem_get_arg $REQUEST_FILEQS, "pageno"; + # The first page -- only meaningful when there is more than one page + if ($self->{"lastpage"} > 1) { + if ($self->{"static"}) { + $$_{"first"} = sprintf $self->{"static_filepat"}, 1; + } elsif ($self->{"reverse"}) { + $$_{"first"} = add_get_arg $baseurl, "pageno", 1, DUP_OK; + } else { + $$_{"first"} = $baseurl; + } + } + # The previous page + if ($self->{"pageno"} > 1) { + if ($self->{"static"}) { + $$_{"prev"} = sprintf $self->{"static_filepat"}, + $self->{"pageno"} - 1; + } elsif ($self->{"reverse"} || $self->{"pageno"} -1 != 1) { + $$_{"prev"} = add_get_arg $baseurl, "pageno", $self->{"pageno"} - 1, DUP_OK; + } else { + $$_{"prev"} = $baseurl; + } + } + # The next page + if ($self->{"pageno"} < $self->{"lastpage"}) { + if ($self->{"static"}) { + if ( defined $self->{"static_lastfile"} + && $self->{"pageno"} + 1 == $self->{"lastpage"}) { + $$_{"next"} = $self->{"static_lastfile"}; + } else { + $$_{"next"} = sprintf $self->{"static_filepat"}, + $self->{"pageno"} + 1; + } + } elsif (!$self->{"reverse"} || $self->{"pageno"} + 1 != $self->{"lastpage"}) { + $$_{"next"} = add_get_arg $baseurl, "pageno", $self->{"pageno"} + 1, DUP_OK; + } else { + $$_{"next"} = $baseurl; + } + } + # The last page -- only meaningful when there is more than one page + if ($self->{"lastpage"} > 1) { + if ($self->{"static"}) { + if (defined $self->{"static_lastfile"}) { + $$_{"last"} = $self->{"static_lastfile"}; + } else { + $$_{"last"} = sprintf $self->{"static_filepat"}, $self->{"lastpage"}; + } + } elsif (!$self->{"reverse"}) { + $$_{"last"} = add_get_arg $baseurl, "pageno", $self->{"lastpage"}, DUP_OK; + } else { + $$_{"last"} = $baseurl; + } + } + return $_; +} + +# html: Output the list +sub html : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Fetch the current list if not fetched yet + $self->fetch if !$self->{"fetched"}; + + # Display the title + $self->html_title; + # Display the error message + $self->html_errmsg; + # Display a link to add a new item + $self->html_newlink; + # Display the switch for different lists + $self->html_lists_switch; + # Display the search box + $self->html_search; + # Display the data download link + $self->html_data_download; + # Display the list status message + $self->html_liststat; + # Display the page bar at the beginning + $self->html_pagebar; + # List the items + $self->html_list; + # Display the page bar at the END + $self->html_pagebar; + # Display a form to change the list preference + $self->html_listprefform; + + return; +} + +# set_listpref: Set the list preference +sub set_listpref : method { + local ($_, %_); + my $self; + $self = $_[0]; + $_ = new Selima::ListPref($self->{"FORM"}); + $_->main; +} + +# +# Methods belows are private. Do not call them directly. +# Override them when needed. +# +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Empty comes from a query + if (defined $self->{"query"}) { + return C_("Nothing found. Please try another query."); + # Empty database + } else { + return C_("The database is empty."); + } + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,record].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,record].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +# pagebar_tags: The tags for the page bar +# No arrows anymore. No more ASCII-art, as per WCAG 1.0 checkpoint 1.1 +sub pagebar_tags : method { + local ($_, %_); + return ( + first => h_abbr(C_("First")), + prev => h_abbr(C_("Previous")), + next => h_abbr(C_("Next")), + last => h_abbr(C_("Last")), + ); +} + +# colval: Output a list column value +sub colval : method { + local ($_, %_); + my ($self, $col, %row, $brflen, $alt); + ($self, $col, %row) = @_; + + # Null/no value + return h(t_notset()) if !defined $row{$col}; + + # A brief should be displayed instead + $brflen = $self->{"DEFAULT_BRIEF_LEN"}; + if (in_array($col, @{$self->{"COLS_BRIEF"}}) && length $row{$col} > $brflen) { + # Strip the HTML tags + $_ = $row{$col}; + if (exists $row{"html"} && $row{"html"}) { + # HTML::Strip does not work with decode()d UTF-8 text + $_ = encode("UTF-8", $_); + $_ = (new HTML::Strip)->parse($_); + $_ = decode("UTF-8", $_); + } + return h(substr $_, 0, $brflen) . "…"; + } + + # Always display "pic" column as a picture + # To be done + if ($col eq "pic") { + #$alt = C_("Picture preview"); + #$picid = readpic($row{$col}, + # array("max" => $self->{"PIC_THUMBNAIL_SIZE"}), + # $row["sn"], $self->{"table"}); + #$PICS =& pic_deposit; + #$pic = $PICS[$picid]; + #return echopic_thumbnail($pic, $alt); + return ""; + } + + # Always display "_imgsrc" column as image reference + if ($col eq "_imgsrc") { + return "\"""; + } + + # Always display "_urlcheck" unencoded, since it is a result text + return h($row{$col}) if $col eq "_urlcheck"; + + # Ordinary columns + return h($row{$col}); +} + +# check_pageno: Check the page number +sub check_pageno : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # Save it elsewhere and replace with default value temporarily + $_ = $self->{"pageno"}; + $self->{"pageno"} = !$self->{"reverse"}? 1: $self->{"lastpage"}; + # Page number not specified + return if !defined $_; + + # It is too long, or contains any non-digit character + return {"msg"=>N_("Page number ([_1]) invalid. Please specify a valid page number."), + "margs"=>[$_]} + if length $_ > 9 || /\D/ || /^0+$/; + $_ += 0; + + # Out of range + return {"msg"=>N_("Page number ([#,_1]) out of range. Please specify between 1 and [#,_2]."), + "margs"=>[$_, $self->{"lastpage"}]} + if defined $self->{"lastpage"} && $_ > $self->{"lastpage"}; + # Redirect to the page without page number, if it can be omitted + if ($self->{"pageno"} == $_) { + my ($method, $url); + $method = $IS_MODPERL? ($IS_MP2? + Apache2::RequestUtil->request->method: Apache->request->method): + $ENV{"REQUEST_METHOD"}; + $url = rem_get_arg $REQUEST_FILEQS, "pageno"; + if ($method eq "POST") { + http_303 $url; + } else { + http_307 $url; + } + } + # OK + $self->{"pageno"} = $_; + return; +} + +# +# Methods belows are private. Do not call them directly. +# Do not override them, either. +# + +# select_with_view: Obtain the SQL statement with views +# This makes life easier *^_^* +sub select_with_view : method { + local ($_, %_); + my ($self, $cols, $table, $where, $orderby, $limit); + $self = $_[0]; + + # Obtain the view name + if (!exists $self->{"view"}) { + $self->{"view"} = $self->{"table"} . "_list"; + $self->{"view"} .= "_" . getlang LN_DATABASE if @ALL_LINGUAS > 1; + } + # Obtain the available columns + $self->{"cols"} = [$DBH->cols($self->{"view"})]; + + $cols = "*"; + $table = $DBH->quote_identifier($self->{"view"}); + # Obtain the SQL WHERE phase + $where = $self->sql_filter(); + # Obtain the SQL ORDER BY phase + $orderby = $self->sql_orderby(); + # Obtain the LIMIT phase + $limit = defined $self->{"limit"}? " LIMIT " . $self->{"limit"}: ""; + + return ($cols, $table, $where, $orderby, $limit); +} + +# select_without_view: Obtain the SQL statement manually without views +# *BAD BAD BAD~~ Stupid MySQL* Keep it here for compatibility +# Should be remove as long as MySQL is vanished +sub select_without_view : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # To be done + return $self->select_with_view; +} + +# sql_filter: Get the SQL WHERE phase +sub sql_filter : method { + local ($_, %_); + my ($self, @cols, @conds); + $self = $_[0]; + + # No query, return empty string + if (!defined $self->{"query"}) { + return " WHERE " . $_ + if $self->can("pre_filter") && defined($_ = $self->pre_filter()); + return ""; + } + + # Regularize it + $self->{"query"} =~ s/^\s*(.*?)\s*$/$1/; + # Check if it is filled + if ($self->{"query"} eq "") { + $self->{"error"} = {"msg"=>N_("Please fill in your query.")}; + return " WHERE " . $_ + if $self->can("pre_filter") && defined($_ = $self->pre_filter()); + return ""; + } + + $self->{"query_phrases"} = [parse_query $self->{"query"}]; + # Bounce if nothing to query + if (@{$self->{"query_phrases"}} == 0) { + return " WHERE " . $_ + if $self->can("pre_filter") && defined($_ = $self->pre_filter()); + return ""; + } + + # Obtain the columns to query + if ($self->{"useview"}) { + %_ = map { $_ => 1 } @{$self->{"COLS_NO_SEARCH"}}; + @cols = grep !exists $_{$_}, @{$self->{"cols"}}; + # Use the column definition kept so far + } else { + @cols = map ${$_}{"def"}, + grep !in_array(${$_}{"alias"}, @{$self->{"COLS_NO_SEARCH"}}), + @{$self->{"coldefs"}} + } + + # Compose the query condition + @conds = qw(); + # Obtain each phase + foreach my $phrase (@{$self->{"query_phrases"}}) { + my (@subconds, $lphrase); + $lphrase = "'%" . $DBH->esclike($phrase) . "%'"; + @subconds = qw(); + foreach my $col (@cols) { + push @subconds, "cast($col AS text) ILIKE $lphrase"; + } + push @conds, join " OR ", @subconds; + } + # Append the the pre-defined filter + push @conds, $_ + if $self->can("pre_filter") && defined($_ = $self->pre_filter()); + # Compose the WHERE statement + return " WHERE " . (@conds == 1? $conds[0]: join " AND ", map "($_)", @conds); +} + +# sql_orderby: Get the SQL ORDER BY phase +sub sql_orderby : method { + local ($_, %_); + my ($self, @phrases, $error); + $self = $_[0]; + + # Parse the "sortby" argument + $self->parse_sortby($self->{"sortby"}); + # Check the sort keys, and empty them if invalid + $error = $self->check_sortkeys; + if (defined $error) { + $self->{"error"} = $error if !defined $self->{"error"}; + $self->{"sortkeys"} = []; + } + # Apply DEFAULT_SORTBY if not in a view + if ( @{$self->{"sortkeys"}} == 0 + && !$self->{"useview"} + && defined $self->{"DEFAULT_SORTBY"}) { + # Parse the DEFAULT_SORTBY argument + $self->parse_sortby($self->{"DEFAULT_SORTBY"}); + # Check the sort keys, and empty them if invalid + $error = $self->check_sortkeys; + if (defined $error) { + $self->{"error"} = $error if !defined $self->{"error"}; + $self->{"sortkeys"} = []; + } + } + # Set the "sortby" attribute + $self->compose_sortby; + + # Bounce if there is no sorting key + return "" if @{$self->{"sortkeys"}} == 0; + + # Obtain the corresponding SQL phrase + @_ = qw(); + @_ = map ${$_}{"sql"}, @{$self->{"sortkeys"}}; + $_ = " ORDER BY " . join ", ", @_; + + return $_; +} + +# parse_sortby: Parse the "sortby" argument +# $sortby argument should be specified as "key1,-key2,...", +# where initial minus (-) before the key means decreasing. +sub parse_sortby : method { + local ($_, %_); + my ($self, $sortby); + ($self, $sortby) = @_; + + $self->{"sortkeys"} = []; + # Bounce for nothing + return if !defined $sortby; + $sortby =~ s/^\s*(.*?)\s*$/$1/; + # Bounce if $sortby is empty + return if $sortby eq ""; + + # Split by comma + foreach my $phrase (split /,/, $sortby) { + # Compose the sort key + $_{"key"} = $phrase; + $_{"key"} =~ s/^\s*(.*?)\s*$/$1/; + $_{"desc"} = 0; + $_ = $_{"key"}; + $_{"sql"} = $DBH->quote_identifier(encode("UTF-8", $_, FB_CROAK)); + # Check the decreasing flag with the initial "-" sign + if ($_{"key"} =~ s/^-//) { + $_{"desc"} = 1; + $_ = $_{"key"}; + $_{"sql"} = $DBH->quote_identifier(encode("UTF-8", $_, FB_CROAK)) + . " DESC"; + } + # Add this sort key + push @{$self->{"sortkeys"}}, {%_}; + } + + return; +} + +# check_sortkeys: Check if the sorting keys are valid +sub check_sortkeys : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Skip if nothing to check + return if @{$self->{"sortkeys"}} == 0;; + + # Obtain the valid sorting keys + if ($self->{"useview"}) { + %_ = map { $_ => 1 } @{$self->{"COLS_NO_SORT_BY"}}; + %_ = map { $_ => 1 } grep !exists $_{$_}, @{$self->{"cols"}}; + # Check each candidate + foreach (@{$self->{"sortkeys"}}) { + return {"msg"=>N_("You cannot sort by \"[_1]\"."), + "margs"=>[${$_}{"key"}]} + if !exists $_{${$_}{"key"}}; + } + # Use the column definition kept so far + } else { + # Turn the column definition into an associative array + %_ = map { ${$_}{"alias"} => ${$_}{"def"} } @{$self->{"coldefs"}}; + # Check each candidate + foreach (@{$self->{"sortkeys"}}) { + return {"msg"=>N_("You cannot sort by \"[_1]\"."), + "margs"=>[${$_}{"key"}]} + if !exists $_{${$_}{"key"}}; + # Reset the SQL according to the column definition + ${$_}{"sql"} = $_{${$_}{"key"}}; + ${$_}{"sql"} .= " DESC" if ${$_}{"desc"}; + } + } + + # OK + return; +} + +# compose_sortby: Compose the "sortby" argument from sorting keys +sub compose_sortby : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # Bounce if there is no sorting keys + if (@{$self->{"sortkeys"}} == 0) { + $self->{"sortby"} = ""; + return; + } + @_ = qw(); + foreach (@{$self->{"sortkeys"}}) { + if (${$_}{"desc"}) { + push @_, "-" . ${$_}{"key"}; + } else { + push @_, ${$_}{"key"}; + } + } + $self->{"sortby"} = join ",", @_; + return; +} + +# col_labels: Set the column labels +sub col_labels : method { + local ($_, %_); + my ($self, %labels); + ($self, %labels) = @_; + %{$self->{"col_labels"}} = (%{$self->{"col_labels"}}, %labels); + return; +} + +# check_listcols: Set the columns to be displayed +sub check_listcols : method { + local ($_, %_); + my ($self, @listcols, @validcols); + $self = $_[0]; + + # The columns to be displayed + $_ = userpref("listcols", ref($self)); + if (defined $_) { + @listcols = split / /, encode("US-ASCII", $_, FB_CROAK); + } else { + @listcols = @{$self->{"DEFAULT_LIST_COLS"}}; + } + # Obtain the columns to list + # Remove columns not to be displayed + %_ = map { $_ => 1 } @{$self->{"COLS_NO_DISPLAY"}}; + @_ = grep !exists $_{$_}, @{$self->{"cols"}}; + # Only take valid columns in the preferenced columns + %_ = map { $_ => 1 } @_; + $self->{"listcols"} = [grep exists $_{$_}, @listcols]; + return; +} + +# query_abstract: Get the abstract regarding to the query phrase +# It always work with the "body" column +sub query_abstract : method { + local ($_, %_); + my ($self, $current, $body, @queries, $query, $start, $end, @union); + my ($len_andsoon, $len, $reached_maximum, $union, $needlen); + ($self, $current) = @_; + # The column + $body = $$current{"body"}; + # Strip the HTML tags + if (exists $$current{"html"} && $$current{"html"}) { + # HTML::Strip does not work with decode()d UTF-8 text + $body = encode("UTF-8", $body); + $body = (new HTML::Strip)->parse($body); + $body = decode("UTF-8", $body); + $body = dh($body); + } + # Trim excess spaces + $body =~ s/\s+/ /g; + # Sort the query phrases by their lengths + if (exists $self->{"query_zh_phrases"}) { + @queries = sort { length $b <=> length $a } @{$self->{"query_zh_phrases"}}; + } else { + @queries = sort { length $b <=> length $a } @{$self->{"query_phrases"}}; + } + # Gather the abstract of each query phrase + @_ = qw(); + foreach my $query (@queries) { + my $base; + $base = 0; + # Gather each match + while (substr($body, $base) =~ /^(.*?)\Q$query\E/i) { + $_ = $base + length $1; + $start = $_ - $self->{"QABS_SPAN"}; + $start = 0 if $start < 0; + $end = $_ + length($query) + $self->{"QABS_SPAN"}; + $end = length $body if $end > length $body; + push @_, { + "start" => $start, + "end" => $end, + }; + $base = $_ + length $query; + } + } + # Sanity check + return undef if @_ == 0; + # Sort the ranges + @_ = sort { $$a{"start"}<=>$$b{"start"} || $$a{"end"}<=>$$b{"end"} } @_; + + # Get the union of the ranges + @union = qw(); + $_ = 0; + $start = ${$_[0]}{"start"}; + $end = ${$_[0]}{"end"}; + while (1) { + # Find the next segment that exceeds the current segment + for ( ; $_ < @_ && ${$_[$_]}{"end"} <= $end; $_++) {}; + # Meet the last entry + if ($_ == @_) { + # Save the last segment + push @union, { + "start" => $start, + "end" => $end, + "len" => $end - $start, + "text" => substr($body, $start, $end - $start), + }; + last; + } + # A new segment seperated from the current segment + if (${$_[$_]}{"start"} > $end) { + # Save the last segment + push @union, { + "start" => $start, + "end" => $end, + "len" => $end - $start, + "text" => substr($body, $start, $end - $start), + }; + # Start a new segment + $start = ${$_[$_]}{"start"}; + $end = ${$_[$_]}{"end"}; + next; + } + # Expend the current segment + $end = ${$_[$_]}{"end"}; + next; + } + + # Trim the union + $len_andsoon = 1; + $len = 0; + $len += $len_andsoon if ${$union[0]}{"start"} != 0; + $reached_maximum = 0; + for ($_ = 0; $_ < @union; $_++) { + $union = $union[$_]; + $needlen = $$union{"len"} + $len_andsoon; + # Not even enough for an abstract section + if ($len + $len_andsoon > $self->{"QABS_MAXLEN"}) { + $reached_maximum = 1; + # Discard the rest sections + pop @union while @union > $_; + last; + + # Reached the maximum + } elsif ($len + $needlen > $self->{"QABS_MAXLEN"}) { + $reached_maximum = 1; + $$union{"len"} = $self->{"QABS_MAXLEN"} - $len - $len_andsoon; + $$union{"end"} = $$union{"start"} + $$union{"len"}; + $$union{"text"} = substr $body, $$union{"start"}, $$union{"len"}; + # Discard the rest sections + pop @union while @union > $_ + 1; + last; + } + # Not reached the maximum yet + $len += $$union{"len"} + $len_andsoon; + } + # Not reached the maximum yet - check the last section + if (!$reached_maximum) { + $union = $union[$#union]; + $needlen = $$union{"len"}; + $needlen += $len_andsoon if $$union{"end"} != length $body; + # Not even enough for an abstract section + if ($len + $len_andsoon > $self->{"QABS_MAXLEN"}) { + # Forget it. We can do nothing now. + pop @union; + + # Reached the maximum + } elsif ($len + $needlen > $self->{"QABS_MAXLEN"}) { + $$union{"len"} = $self->{"QABS_MAXLEN"} - $len - $len_andsoon; + $$union{"end"} = $$union{"start"} + $$union{"len"}; + $$union{"text"} = substr $body, $$union{"start"}, $$union{"len"}; + } + # Not reached the maximum yet + } + + # Mark the query phrases + foreach $union (@union) { + my @pieces; + @pieces = ( + { "text" => $$union{"text"}, + "is_match" => 0, + } + ); + # Mark each query phrase + foreach my $query (@queries) { + for ($_ = 0; $_ < @pieces; $_++) { + my ($pos, $piece); + $piece = $pieces[$_]; + # Skip matches of other query phrases + next if $$piece{"is_match"}; + # Skip if not matched + next unless $$piece{"text"} =~ /^(.*?)(\Q$query\E)(.*)$/i; + @pieces = ( + @pieces[0 ... $_ - 1], + { "text" => $1, + "is_match" => 0, + }, + { "text" => $2, + "is_match" => 1, + }, + { "text" => $3, + "is_match" => 0, + }, + @pieces[$_ + 1 ... $#pieces], + ); + $_++; + } + } + $$union{"marked"} = join "", map(($$_{"is_match"}? + "" . h($$_{"text"}) . "": h($$_{"text"})), @pieces); + } + + # Join these segments + $_ = join "…", map $$_{"marked"}, @union; + $_ = "…" . $_ if ${$union[0]}{"start"} != 0; + $_ .= "…" if ${$union[$#union]}{"end"} != length $body; + + return $_; +} + +# html_title: Display the title +# Make it a null function +sub html_title : method {} + +# html_errmsg: Display the error message +sub html_errmsg : method { + local ($_, %_); + my ($self, $message); + $self = $_[0]; + + return if !defined $self->{"error"}; + $message = h(err2msg $self->{"error"}); + + print << "EOT"; +

    $message

    + +EOT + return; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + local ($_, %_); + my ($self, $prompt, $url); + ($self, $prompt) = @_; + + # No new item creation if it is a called form + return if $self->{"is_called_form"}; + return if !defined $prompt; + # Start from the default language + return if $DBH->is_ml_table($self->{"table"}) + && getlang ne $DEFAULT_LANG; + $url = $REQUEST_FILEQS; + # Remove list parameters + $url = rem_get_arg $url, "query", "sortby", "pageno", "form", "formid", "statid"; + $url = add_get_arg $url, "form", "new", DUP_OK; + $url = h($url); + $prompt = h($prompt); + + print << "EOT"; +

    $prompt

    + +EOT + return; +} + +# html_lists_switch: Display the switch for different lists +sub html_lists_switch : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Bounce for nothing + return unless exists $self->{"lists_switch"} + && @{$self->{"lists_switch"}} > 0; + print "
    \n"; + print join " |\n", + map " " . h($$_{"title"}) . "", + @{$self->{"lists_switch"}}; + print "
    \n\n"; + return; +} + +# html_search: Display the search box +sub html_search : method { + local ($_, %_); + my ($self, $prompt, $label, $query, $request_file); + ($self, $prompt) = @_; + # No search box is displayed if no records yet + if ( $self->{"fetched"} + && defined $self->{"total"} && $self->{"total"} == 0 + && !defined $self->{"query"}) { + return; + } + + $request_file = h($REQUEST_FILE); + $query = defined $self->{"query"}? h($self->{"query"}): ""; + $label = h(C_("Search")); + + print << "EOT"; +
    + +
    + +EOT + return; +} + +# html_data_download: Display the data download link +sub html_data_download : method { + local ($_, %_); + # Normally empty + return; +} + +# html_liststat: Display the list statistics +sub html_liststat : method { + local ($_, %_); + my ($self, $message); + $self = $_[0]; + # Do not show the list + return if !defined $self->{"total"}; + return if !defined($message = $self->liststat_message()); + $message = h($message); + + print << "EOT"; +

    $message

    + +EOT + return; +} + +# html_pagebar: Display a page navigation bar +# We display a page bar for scrolling between previous and next 2 pages +sub html_pagebar : method { + local ($_, %_); + my ($self, $html, $startpage, $endpage, $baseurl, $url, $cell, %tags); + $self = $_[0]; + + # Do not show the list + return if !defined $self->{"total"}; + # Fit in one page - paging is not needed + return if $self->{"lastpage"} <= 1; + # Cached before + if (exists $self->{"html_pagebar"}) { + print $self->{"html_pagebar"}; + return; + } + + # Fewer than 5 pages + if ($self->{"lastpage"} <= 5) { + $startpage = 1; + $endpage = $self->{"lastpage"}; + # Near the beginning + } elsif ($self->{"pageno"} < 3) { + $startpage = 1; + $endpage = 5; + # Near the end + } elsif ($self->{"pageno"} > $self->{"lastpage"} - 2) { + $startpage = $self->{"lastpage"} - 4; + $endpage = $self->{"lastpage"}; + # Normal, at the middle + } else { + $startpage = $self->{"pageno"} - 2; + $endpage = $self->{"pageno"} + 2; + } + + + # Start output + $html = ""; + %tags = $self->pagebar_tags; + # Static page -- Display the index + if ($self->{"static"}) { + $html .= "
    \n" + . " " . h(C_("Index")) . " |\n"; + # Dynamic page -- Display a paging form + } else { + # Base url without the "pageno" argument + $baseurl = rem_get_arg $REQUEST_FILEQS, "pageno", "statid"; + $_ = h($REQUEST_FILE); + $html .= << "EOT"; +
    +
    +EOT + if ($self->{"is_called_form"}) { + my ($caller, $cformid); + $caller = h($self->{"caller"}); + $cformid = h($self->{"cformid"}); + print << "EOT"; + + +EOT + } + if (defined $self->{"query"}) { + $_ = h($self->{"query"}); + print << "EOT"; + +EOT + } + if (defined $self->{"sortby"} && $self->{"sortby"} ne "") { + $_ = h($self->{"sortby"}); + print << "EOT"; + +EOT + } + } + # The first page + $cell = $tags{"first"}; + if ($self->{"pageno"} != 1) { + if ($self->{"static"}) { + $url = sprintf $self->{"static_filepat"}, 1; + } elsif ($self->{"reverse"}) { + $url = add_get_arg $baseurl, "pageno", 1, DUP_OK; + } else { + $url = $baseurl; + } + $cell = "" . $cell . ""; + } + $html .= " $cell |\n"; + # The previous page + $cell = $tags{"prev"}; + if ($self->{"pageno"} != 1) { + if ($self->{"static"}) { + $url = sprintf $self->{"static_filepat"}, $self->{"pageno"} - 1; + } elsif ($self->{"reverse"} || $self->{"pageno"} - 1 != 1) { + $url = add_get_arg $baseurl, "pageno", $self->{"pageno"} - 1, DUP_OK; + } else { + $url = $baseurl; + } + $cell = "" . $cell . ""; + } + $html .= " $cell |\n"; + + # Pages before + for ($_ = $startpage; $_ < $self->{"pageno"}; $_++) { + $cell = h($_); + if ($self->{"static"}) { + $url = sprintf $self->{"static_filepat"}, $_; + } elsif ($self->{"reverse"} || $_ != 1) { + $url = add_get_arg $baseurl, "pageno", $_, DUP_OK; + } else { + $url = $baseurl; + } + $cell = "" . $cell . ""; + $html .= " $cell |\n"; + } + # Current page + $cell = h($self->{"pageno"}); + $html .= " $cell |\n"; + # Pages after + for ($_ = $self->{"pageno"} + 1; $_ <= $endpage; $_++) { + $cell = h($_); + if ($self->{"static"}) { + if ( defined $self->{"static_lastfile"} + && $_ == $self->{"lastpage"}) { + $url = $self->{"static_lastfile"}; + } else { + $url = sprintf $self->{"static_filepat"}, $_; + } + } elsif (!$self->{"reverse"} || $_ != $self->{"lastpage"}) { + $url = add_get_arg $baseurl, "pageno", $_, DUP_OK; + } else { + $url = $baseurl; + } + $cell = "" . $cell . ""; + $html .= " $cell |\n"; + } + + # The next page + $cell = $tags{"next"}; + if ($self->{"pageno"} != $self->{"lastpage"}) { + if ($self->{"static"}) { + if ( defined $self->{"static_lastfile"} + && $self->{"pageno"} + 1 == $self->{"lastpage"}) { + $url = $self->{"static_lastfile"}; + } else { + $url = sprintf $self->{"static_filepat"}, + $self->{"pageno"} + 1; + } + } elsif (!$self->{"reverse"} || $self->{"pageno"} + 1 != $self->{"lastpage"}) { + $url = add_get_arg $baseurl, "pageno", $self->{"pageno"} + 1, DUP_OK; + } else { + $url = $baseurl; + } + $cell = "" . $cell . ""; + } + $html .= " $cell |\n"; + # The last page + $cell = $tags{"last"}; + if ($self->{"pageno"} != $self->{"lastpage"}) { + if ($self->{"static"}) { + if (defined $self->{"static_lastfile"}) { + $url = $self->{"static_lastfile"}; + } else { + $url = sprintf $self->{"static_filepat"}, $self->{"lastpage"}; + } + } elsif (!$self->{"reverse"}) { + $url = add_get_arg $baseurl, "pageno", $self->{"lastpage"}, DUP_OK; + } else { + $url = $baseurl; + } + $cell = "" . $cell . ""; + } + $html .= " $cell"; + if ($self->{"static"}) { + $html .= << "EOT"; + +
    + +EOT + } else { + my ($label, $input, $pageno); + $label = h(C_("Page:")); + $input = h(C_("View")); + $pageno = h($self->{"pageno"}); + $html .= << "EOT"; + | + +
    + + +EOT + } + print $html; + # Cache it + $self->{"html_pagebar"} = $html; + + return; +} + +# html_list: List the items +sub html_list : method { + local ($_, %_); + my ($self, $baseurl, $url, $need_view); + $self = $_[0]; + # Do not show the list + return if !defined $self->{"total"}; + # No record to be listed + return if $self->{"total"} == 0; + + # Remove "sortby" from the URL first + $baseurl = $REQUEST_FILEQS; + $baseurl = rem_get_arg $baseurl, "formid", "statid", "sortby", "pageno"; + + # Do we need a view link? + $need_view = in_array("_viewurl", @{$self->{"cols"}}) + && !$self->{"is_called_form"}; + # Check the URL first + urlcheck @{$self->{"current"}} + if in_array("_urlcheck", @{$self->{"listcols"}}); + + # Mass deletion -- surround it with a form + if ($self->{"massdel"} && !$self->{"is_called_form"}) { + my $label; + $label = h(C_("Delete the selected items.")); + $url = h($REQUEST_FILE); + print << "EOT"; +
    +
    +EOT + } + + print << "EOT"; + +EOT + print ""; + print "" if $self->{"massdel"} && !$self->{"is_called_form"}; + print "" if $need_view; + print "" if !$self->{"noselect"}; + for ($_ = 0; $_ < @{$self->{"listcols"}}; $_++) { + print ""; + } + print "\n"; + print << "EOT"; + + +EOT + print " \n"; + print " \n" + if $self->{"massdel"} && !$self->{"is_called_form"}; + print " \n" if $need_view; + print " \n" if !$self->{"noselect"}; + foreach my $col (@{$self->{"listcols"}}) { + my ($label, $key); + $label = h_abbr(exists ${$self->{"col_labels"}}{$col}? ${$self->{"col_labels"}}{$col}: $col); + if (in_array($col, @{$self->{"COLS_NO_SORT_BY"}})) { + print << "EOT"; + +EOT + } else { + $key = $col; + $key = "-$key" if defined $self->{"sortby"} && $self->{"sortby"} eq $key; + $url = h(add_get_arg($baseurl, "sortby", $key, DUP_OK)); + print << "EOT"; + +EOT + } + } + print << "EOT"; + + + +EOT + + # Print each record + my ($no, $inc, $rowclass); + if (!$self->{"reverse"}) { + $no = $self->{"startno"} + 1; + $inc = 1; + } else { + $no = $self->{"endno"} + 1; + $inc = -1; + } + $rowclass = ""; + foreach my $current (@{$self->{"current"}}) { + my ($issel, $selurl); + $rowclass = h(($rowclass eq "oddrow")? "evenrow": "oddrow"); + # The URL. to handle the selection + $issel = ((!in_array("_sel", @{$self->{"cols"}}) || $$current{"_sel"}) + && !$self->{"noselect"}); + if ($issel) { + $selurl = exists $$current{"_selurl"}? $$current{"_selurl"}: + sprintf $self->{"selurl_tmpl"}, h($$current{"sn"}); + } + + print << "EOT"; + + +EOT + print " \n" + if $self->{"massdel"} && !$self->{"is_called_form"}; + if ($need_view) { + if (!defined $$current{"_viewurl"}) { + print " \n" + } else { + print " \n"; + } + } + if (!$self->{"noselect"}) { + print " \n"; + } + foreach my $col (@{$self->{"listcols"}}) { + print " \n"; + } + print << "EOT"; + +EOT + $no += $inc; + } + print << "EOT"; + +
    " . h_abbr(C_("No.")) . "" . h_abbr(C_("Delete")) . "" . h_abbr(C_("View")) . "" . h_abbr($self->{"seltext"}) . "$label$label
    $no" + . h(C_("View")) . ""; + print "" + . h($self->{"seltext"}) . "" + if $issel; + print "" . $self->colval($col, %$current) . "
    + +EOT + + # Mass deletion -- surround it with a form + if ($self->{"massdel"} && !$self->{"is_called_form"}) { + my $label; + $label = h(C_("Delete the selected items.")); + print << "EOT"; +
    +
    + +EOT + } + + return; +} + +# html_listprefform: Display a form to change the list preference +sub html_listprefform : method { + local ($_, %_); + my ($self, $submit, $referer, @validcols, $request_file_h, $domain); + my ($label, $pagesize); + $self = $_[0]; + + # Do not show the list + return if !defined $self->{"total"}; + # No record to be listed + return if $self->{"total"} == 0; + # Return if users preferences are not available + return if !use_users || !defined $SESSION; + $submit = C_("Set"); + # The referer + $referer = h(rem_get_arg $REQUEST_FULLURI, "statid"); + + # Obtain the columns to list + %_ = map { $_ => 1 } @{$self->{"COLS_NO_DISPLAY"}}; + @validcols = grep !exists $_{$_}, @{$self->{"cols"}}; + + $request_file_h = h($REQUEST_FILE); + # The domain -- my class name + $domain = h(ref($self)); + + print << "EOT"; +
    +
    +EOT + + # The number of rows per page + $label = h_abbr(C_("Rows per page:")); + $pagesize = h($self->{"pagesize"}); + print << "EOT"; + +EOT + + # The display columns + print h_abbr(C_("Display columns:")) . "\n"; + %_ = map { $_ => 1 } @{$self->{"listcols"}}; + foreach my $col (@validcols) { + my ($name, $label, $check); + $label = h_abbr(exists ${$self->{"col_labels"}}{$col}? ${$self->{"col_labels"}}{$col}: $col); + $name = h("listcols_" . $col); + $check = exists $_{$col}? " checked=\"checked\"": ""; + print << "EOT"; + +EOT + } + + print << "EOT"; +
    +
    + +EOT + + return; +} + + +####################### +# Below are functions +####################### +# urlcheck: Proform URL checks +sub urlcheck(\@) { + local ($_, %_); + my ($current, @tocheck); + my ($pid, $out, $err, $exitno, $CHILD_IN, $CHILD_OUT, $CHILD_ERR); + $current = $_[0]; + + @tocheck = qw(); + foreach (@$current) { + if (!is_url_wellformed $$_{"_urlcheck"}) { + $$_{"_urlcheck"} = C_("Malformed"); + } else { + push @tocheck, $_; + } + } + + # Nothing to check further + return if @tocheck == 0; + + # Duplicate the file handles and fork + $pid = open3($CHILD_IN, $CHILD_OUT, $CHILD_ERR, @URLCHECK); + # Get the result of the child + if (defined $CHILD_IN) { + print $CHILD_IN join("", map $$_{"_urlcheck"} . "\n", @tocheck) + or http_500 join(" ", @URLCHECK) . ": $!"; + close $CHILD_IN or http_500 join(" ", @URLCHECK) . ": $!"; + } + if (defined $CHILD_OUT) { + $out = join "", <$CHILD_OUT>; + close $CHILD_OUT or http_500 join(" ", @URLCHECK) . ": $!"; + } + if (defined $CHILD_ERR) { + $err = join "", <$CHILD_ERR>; + close $CHILD_ERR or http_500 join(" ", @URLCHECK) . ": $!"; + } + + waitpid $pid, 0; + $exitno = $? >> 8; + #$coredump = $? & 128; + http_500 join(" ", @URLCHECK) . ": $exitno $err" if $exitno != 0; + + # Save the result + @_ = split /\n/, $out; + for ($_ = 0; $_ < @tocheck; $_++) { + ${$tocheck[$_]}{"_urlcheck"} = $_[$_]? C_("OK"): C_("Unreachable"); + } + + return; +} + +no utf8; +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Records.pm b/lib/perl5/Selima/List/Accounting/Records.pm new file mode 100644 index 0000000..5d19118 --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Records.pm @@ -0,0 +1,121 @@ +# Selima Website Content Management System +# Records.pm: The accounting record list. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-23 + +package Selima::List::Accounting::Records; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::CommText; +use Selima::Format; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "acctrecs" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + C_("Select an Accounting Record"): + C_("Manage Accounting Records"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "trx"; + # Column labels + $self->col_labels( + "trx" => C_("Accounting transaction"), + "credit" => C_("Debit/credit"), + "subj" => C_("Accounting subject"), + "summary" => C_("Summary"), + "amount" => C_("Amount"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + local ($_, %_); + # Run the parent method + return $_[0]->SUPER::html_newlink(C_("Add a new accounting record.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for an accounting record:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,accounting record].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,accounting record].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,accounting record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,accounting record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +# colval: Output a list column value +sub colval : method { + local ($_, %_); + my ($self, $col, %row); + ($self, $col, %row) = @_; + + # Null/no value + return h(t_notset()) if !defined $row{$col}; + + # The balance + if ($col eq "amount") { + return "
    " + . h_abbr(fmtntamount $row{$col}) . "
    "; + } + + # Run the parent method + return $self->SUPER::colval($col, %row); +} + +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Reports.pm b/lib/perl5/Selima/List/Accounting/Reports.pm new file mode 100644 index 0000000..38006d2 --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Reports.pm @@ -0,0 +1,667 @@ +# Selima Website Content Management System +# Reports.pm: The base accounting report. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-24 + +package Selima::List::Accounting::Reports; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Time::Local qw(timelocal); + +use Selima::AddGet; +use Selima::CommText; +use Selima::ChkFunc; +use Selima::DataVars qw($DBH :input :requri); +use Selima::Format; +use Selima::LogIn; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class, $sql, $sth); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = C_("View the Accounting Reports"); + # Known columns that should not be displayed (has a special purpose) + push @{$self->{"COLS_NO_DISPLAY"}}, qw(_subj _date _trx); + # Known columns that should not be sorted with + # List sorting is disabled here at all + push @{$self->{"COLS_NO_SORT_BY"}}, qw(date month trxno subj summary + income expense debit credit balance note); + # The list type + $self->{"type"} = $self->{"FORM"}->param("list"); + # The date range + $self->{"range"} = $self->{"FORM"}->param("r"); + # The onload event handler + $self->{"onload"} = "acctRepQueryDisableNoUseRanges();"; + # Should we return the data as CSV + $self->{"iscsv"} = 0; + $self->{"iscsv"} = 1 + if defined($_ = $self->{"FORM"}->param("format")) && $_ eq "csv"; + # If the database is empty + $sql = "SELECT sn FROM accttrx LIMIT 1;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $self->{"nodata"} = ($sth->rows == 0); + # The full period - used in all reports + if (!$self->{"nodata"}) { + # The earliest start date + $sql = "SELECT date FROM accttrx ORDER BY date LIMIT 1;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + @_ = localtime ${$sth->fetchrow_hashref}{"date"}; + $self->{"startdate"} = sprintf "%04d-%02d-%02d", + $_[5] + 1900, $_[4] + 1, $_[3]; + # The latest end date + $sql = "SELECT date FROM accttrx ORDER BY date DESC LIMIT 1;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + @_ = localtime ${$sth->fetchrow_hashref}{"date"}; + $self->{"enddate"} = sprintf "%04d-%02d-%02d", + $_[5] + 1900, $_[4] + 1, $_[3]; + } + # Column labels + $self->col_labels( + "month" => C_("Month"), + "subj" => C_("Accounting subject"), + "summary" => C_("Summary"), + "debit" => C_("Debit"), + "credit" => C_("Credit"), + "income" => C_("Income"), + "expense" => C_("Expense"), + "balance" => C_("Balance"), + ); + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + return if !defined $_[0]->{"type"}; + # Run the parent method + return $_[0]->SUPER::fetch; +} + +# colval: Output a list column value +sub colval : method { + local ($_, %_); + my ($self, $col, %row); + ($self, $col, %row) = @_; + + # Null/no value + return h(t_notset()) if !defined $row{$col}; + + # The debit and the credit + if ( $col eq "debit" || $col eq "credit" + || $col eq "income" || $col eq "expense") { + return "" if $row{$col} == 0; + return "
    " + . h_abbr(fmtntamount $row{$col}) . "
    "; + } + + # Run the parent method + return $self->SUPER::colval($col, %row); +} + +# pre_filter: Set the pre-defined filter +sub pre_filter : method { + local ($_, %_); + my ($self, $form, @conds, $year, $month, $day, $from, $to); + my ($sql, $sth, $startdate); + $self = $_[0]; + $form = $self->{"FORM"}; + + # No need to run if there is no data at all + return undef if $self->{"nodata"}; + + @conds = qw(); + # The active range that is affecting this list + $self->{"actrange"} = undef; + # Range specified + if (defined $self->{"range"}) { + # By month + if ($self->{"range"} eq "m") { + # Trim the value + if (defined($_ = $form->param("m"))) { + s/^\s+//; + s/\s+$//; + $form->param("m", $_); + } + if (!defined $form->param("m") || $form->param("m") eq "") { + $self->{"error"} = {"msg"=>N_("Please specify a month.")} + if !defined $self->{"error"}; + } elsif ( $form->param("m") !~ /^(\d{4})-(\d{2})$/ + || !check_date($year = $1, $month = $2, 1)) { + $self->{"error"} = {"msg"=>N_("Please specify a valid month in YYYY-MM format.")} + if !defined $self->{"error"}; + } else { + $from = sprintf "%04d-%02d-%02d", $year, $month, 1; + $self->{"startdate"} = $from + if ($self->{"startdate"} cmp $from) < 0; + # The next month + $month++; + if ($month > 12) { + $year++; + $month = 1; + } + # The previous day before the first day of next month + # - The last day of this month + $_ = timelocal(0, 0, 0, 1, $month - 1, $year - 1900); + $_ -= 86400; + @_ = localtime $_; + $to = sprintf "%04d-%02d-%02d", + $_[5] + 1900, $_[4] + 1, $_[3]; + $self->{"enddate"} = $to + if ($self->{"enddate"} cmp $to) > 0; + push @conds, "date>=" . $DBH->quote($self->{"startdate"}); + push @conds, "date<=" . $DBH->quote($self->{"enddate"}); + $self->{"actrange"} = "r=m&m=" . $form->param("m"); + } + + # By year + } elsif ($self->{"range"} eq "y") { + # Trim the value + if (defined($_ = $form->param("y"))) { + s/^\s+//; + s/\s+$//; + $form->param("y", $_); + } + if (!defined $form->param("y") || $form->param("y") eq "") { + $self->{"error"} = {"msg"=>N_("Please specify a year.")} + if !defined $self->{"error"}; + } elsif ( ($_ = $form->param("y")) !~ /^\d{4}$/ + || !check_date($_, 1, 1)) { + $self->{"error"} = {"msg"=>N_("Please specify a valid year in YYYY format.")} + if !defined $self->{"error"}; + } else { + $from = sprintf "%04d-%02d-%02d", $_, 1, 1; + $self->{"startdate"} = $from + if ($self->{"startdate"} cmp $from) < 0; + $to = sprintf "%04d-%02d-%02d", $_, 12, 31; + $self->{"enddate"} = $to + if ($self->{"enddate"} cmp $to) > 0; + push @conds, "date>=" . $DBH->quote($self->{"startdate"}); + push @conds, "date<=" . $DBH->quote($self->{"enddate"}); + $self->{"actrange"} = "r=y&y=" . $form->param("y"); + } + + # Specified reange + } elsif ($self->{"range"} eq "s") { + my @actrange; + @actrange = qw(); + # Trim the value + if (defined($_ = $form->param("f"))) { + s/^\s+//; + s/\s+$//; + $form->param("f", $_); + } + if (defined($_ = $form->param("t"))) { + s/^\s+//; + s/\s+$//; + $form->param("t", $_); + } + # The start day + if (!defined $form->param("f") || $form->param("f") eq "") { + $self->{"error"} = {"msg"=>N_("Please specify the start date.")} + if !defined $self->{"error"}; + } elsif ( $form->param("f") !~ /^(\d{4})-(\d{2})-(\d{2})$/ + || !check_date($year = $1, $month = $2, $day =$3)) { + $self->{"error"} = {"msg"=>N_("Please specify a valid start date in YYYY-MM-DD format.")} + if !defined $self->{"error"}; + } else { + $from = sprintf "%04d-%02d-%02d", $year, $month, $day; + $self->{"startdate"} = $from + if ($self->{"startdate"} cmp $from) < 0; + push @conds, "date>=" . $DBH->quote($self->{"startdate"}); + push @actrange, "f=" . $form->param("f"); + } + # The end day + if (!defined $form->param("t") || $form->param("t") eq "") { + $self->{"error"} = {"msg"=>N_("Please specify the end date.")}; + } elsif ( $form->param("t") !~ /^(\d{4})-(\d{2})-(\d{2})$/ + || !check_date($year = $1, $month = $2, $day =$3)) { + $self->{"error"} = {"msg"=>N_("Please specify a valid end date in YYYY-MM-DD format.")} + if !defined $self->{"error"}; + } else { + $to = sprintf "%04d-%02d-%02d", $year, $month, $day; + $self->{"enddate"} = $to + if ($self->{"enddate"} cmp $to) > 0; + push @conds, "date<=" . $DBH->quote($self->{"enddate"}); + push @actrange, "t=" . $form->param("t"); + } + if (@actrange > 0) { + unshift @actrange, "r=s"; + $self->{"actrange"} = join "&", @actrange; + } + + # All + } elsif ($self->{"range"} eq "a") { + # No condition is applied here + $self->{"actrange"} = "r=a"; + + # Else + } else { + $self->{"error"} = {"msg"=>N_("This option is invalid. Please select a proper date range.")} + if !defined $self->{"error"}; + } + } + # Range not set - default to the current month + if (!defined $self->{"actrange"}) { + ($year, $month) = (localtime)[5,4]; + $year += 1900; + $month++; + $from = sprintf "%04d-%02d-%02d", $year, $month, 1; + $self->{"startdate"} = $from + if ($self->{"startdate"} cmp $from) < 0; + $self->{"actrange"} = "r=m&m=" . sprintf("%04d-%02d", $year, $month); + $month++; + if ($month > 12) { + $year++; + $month = 1; + } + # The previous day before the first day of next month + # - The last day of this month + $_ = timelocal(0, 0, 0, 1, $month - 1, $year - 1900); + $_ -= 86400; + @_ = localtime $_; + $to = sprintf "%04d-%02d-%02d", + $_[5] + 1900, $_[4] + 1, $_[3]; + $self->{"enddate"} = $to + if ($self->{"enddate"} cmp $to) > 0; + push @conds, "date>=" . $DBH->quote($self->{"startdate"}); + push @conds, "date<=" . $DBH->quote($self->{"enddate"}); + } + # Th end date should not be before the first date + $self->{"enddate"} = $self->{"startdate"} + if exists $self->{"startdate"} && exists $self->{"enddate"} + && ($self->{"startdate"} cmp $self->{"enddate"}) > 0; + return undef if @conds == 0; + return join " AND ", @conds; +} + +# html: Output the list +sub html : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Fetch the current list if not fetched yet + $self->fetch if !$self->{"fetched"}; + # Download the CSV + return $self->html_csv if $self->{"iscsv"} && $self->can("html_csv"); + # Run the parent method + return $self->SUPER::html; +} + +# set_listpref: Set the list preference +sub set_listpref : method { + local ($_, %_); + my $self; + $self = $_[0]; + $_ = new Selima::ListPref::AcctReps($self->{"FORM"}); + $_->main; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + local ($_, %_); + my ($self, $urle, $urli, $urlt, $prompt); + $self = $_[0]; + + $urle = "accttrx.cgi?form=new&formsub=expense"; + $urli = "accttrx.cgi?form=new&formsub=income"; + $urlt = "accttrx.cgi?form=new&formsub=trans"; + $prompt = C_("Add a new cash expense transaction, add a new cash income transaction or add a new transfer transaction.", + h($urle), h($urli), h($urlt)); + + print << "EOT"; +

    $prompt

    + +EOT + return; +} + +# html_lists_switch: Display the switch for different lists +sub html_lists_switch : method { + local ($_, %_); + my ($self, $labellist, @lists); + $self = $_[0]; + + # No need to run if there is no data at all + return if $self->{"nodata"}; + + # Switch for different lists + $labellist = h_abbr(C_("Report type:")); + @lists = qw(); + push @lists, { + "type" => "cash", + "title" => C_("Cash book"), + }; + push @lists, { + "type" => "cashsum", + "title" => C_("Cash book summary"), + }; + push @lists, { + "type" => "ldgr", + "title" => C_("Ledger"), + }; + push @lists, { + "type" => "ldgrsum", + "title" => C_("Ledger summary"), + }; + push @lists, { + "type" => "journal", + "title" => C_("Journal"), + }; + push @lists, { + "type" => "tb", + "title" => C_("Trial balance"), + }; + push @lists, { + "type" => "incmstat", + "title" => C_("Income statement"), + }; + push @lists, { + "type" => "blncshet", + "title" => C_("Balance sheet"), + }; + + # Display the form + print << "EOT"; +

    $labellist +EOT + @_ = qw(); + foreach (@lists) { + if (defined $self->{"type"} && $self->{"type"} eq $$_{"type"}) { + push @_, h($$_{"title"}); + } else { + push @_, sprintf("%s", + h($REQUEST_FILE . "?list=" . $$_{"type"}), + h($$_{"title"})); + } + } + print join(" |\n", @_) . "\n"; + print << "EOT"; +

    + +EOT + return; +} + +# html_search: Display the search box +sub html_search : method { + local ($_, %_); + my ($self, $prompt, $label, $query, $request_file); + ($self, $prompt) = @_; + + # No need to run if there is no data at all + return if $self->{"nodata"}; + + # Display the report query box + $self->html_report_query; + + $prompt = C_("Search the accounting records:") if !defined $prompt; + $prompt = h($prompt); + $request_file = h($REQUEST_FILE); + $query = defined $self->{"query"}? h($self->{"query"}): ""; + $label = h(C_("Search")); + + print << "EOT"; +
    + +
    + +EOT + return; +} + +# html_report_query: Display the report query box +sub html_report_query : method { + local ($_, %_); + my ($self, $form, $request_file, $label, $curlist); + my ($labelmonth, $labelyear, $labelspecified, $labelall); + my ($labelfrom, $labelto, $labelrange); + my ($valrm, $valry, $valrs, $valra); + my ($valm, $valy, $valf, $valt); + my ($sql, $sth, $count, $row); + $self = $_[0]; + $form = $self->{"FORM"}; + + $request_file = h($REQUEST_FILE); + $label = h_abbr(C_("Query")); + $labelrange = h_abbr(C_("Date range:")); + $labelmonth = h_abbr(C_("By month:")); + $labelyear = h_abbr(C_("By year:")); + $labelspecified = h_abbr(C_("Specified date range:")); + $labelall = h_abbr(C_("All")); + $labelfrom = h_abbr(C_("From")); + $labelto = h_abbr(C_("to")); + + # Whether each radio button is checked + ($valrm, $valry, $valrs, $valra) = ("", "", "", ""); + if (defined $self->{"range"}) { + $valrm = " checked=\"checked\"" + if $self->{"range"} eq "m"; + $valry = " checked=\"checked\"" + if $self->{"range"} eq "y"; + $valrs = " checked=\"checked\"" + if $self->{"range"} eq "s"; + $valra = " checked=\"checked\"" + if $self->{"range"} eq "a"; + # Default to this month + } else { + $valrm = " checked=\"checked\""; + } + # The value of each range + @_ = localtime; + $_[5] += 1900; + $_[4]++; + $valm = defined $form->param("m")? h($form->param("m")): + sprintf("%04d-%02d", @_[5,4]); + $valy = defined $form->param("y")? h($form->param("y")): $_[5]; + $valf = defined $form->param("f")? h($form->param("f")): + sprintf("%04d-%02d-%02d", @_[5,4,3]); + $valt = defined $form->param("t")? h($form->param("t")): + sprintf("%04d-%02d-%02d", @_[5,4,3]); + + $curlist = h($self->{"type"}); + print << "EOT"; +
    +
    +
    + +EOT + # Display the subject selection if available + $self->html_select_subject if $self->can("html_select_subject"); + + print << "EOT"; +

    $labelrange + + + + +

    + +

    +

    +
    +
    + +EOT + return; +} + +# html_liststat: Display the list statistics +sub html_liststat : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Print the current time period + if (!$self->{"nodata"}) { + my ($message, $from, $to); + ($from, $to) = ($self->{"startdate"}, $self->{"enddate"}); + $message = h(C_("From [_1] to [_2].", $from, $to)); + + print << "EOT"; +

    $message

    + +EOT + } + # Run the parent method + return $self->SUPER::html_liststat; +} + +# html_listprefform: Display a form to change the list preference +sub html_listprefform : method { + local ($_, %_); + my ($self, $submit, $referer, $request_file_h, $domain); + my ($label, $pagesize); + $self = $_[0]; + + # Do not show the list + return if !defined $self->{"total"}; + # No record to be listed + return if $self->{"total"} == 0; + # Return if users preferences are not available + return if !use_users || !defined $SESSION; + $submit = C_("Set"); + # The referer + $referer = h(rem_get_arg $REQUEST_FULLURI, "statid"); + + $request_file_h = h($REQUEST_FILE); + # The domain -- my class name + $domain = h(ref($self)); + + print << "EOT"; +
    +
    +EOT + + # The number of rows per page + $label = h_abbr(C_("Rows per page:")); + $pagesize = h($self->{"pagesize"}); + print << "EOT"; + +EOT + + print << "EOT"; +
    +
    + +EOT + + return; +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,accounting record].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,accounting record].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,accounting record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,accounting record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm b/lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm new file mode 100644 index 0000000..88393a6 --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm @@ -0,0 +1,372 @@ +# Selima Website Content Management System +# BlncShet.pm: The balance sheet accounting report. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-10-03 + +package Selima::List::Accounting::Reports::BlncShet; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Accounting::Reports); + +use Selima::Accounting; +use Selima::CommText; +use Selima::DataVars qw($DBH :l10n :lninfo :output :requri); +use Selima::Format; +use Selima::GetLang; +use Selima::LnInfo; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = C_("Balance Sheet"); + # The list type + $self->{"type"} = "blncshet"; + # The default number of rows per page + $self->{"DEFAULT_LIST_SIZE"} = undef; + # Known columns that should not be sorted with + # List sorting is disabled here at all + push @{$self->{"COLS_NO_SORT_BY"}}, qw(subjd amountd subjc amountc); + $self->{"noselect"} = 1; + # Column labels + $self->col_labels( + "subjd" => C_("Assets accounting subject"), + "amountd" => C_("Assets amount"), + "subjc" => C_("Liabilities accounting subject"), + "amountc" => C_("Liabilities amount"), + ); + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, @cols, $title, $sth, $sql, $error); + my (@subjs, %recs, @debits, @credits, $sumdebit, $sumcredit); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + $self->{"total"} = undef; + + # No need to run if there is no data at all + if (exists $self->{"nodata"} && $self->{"nodata"}) { + $self->{"total"} = 0; + return; + } + + # Construct the SQL query statement + # Obtain the period once + $self->sql_filter; + @cols = qw(); + if (@ALL_LINGUAS == 1) { + $title = "acctsubj.title"; + } else { + my ($lndb, $lndbdef); + $lndb = getlang LN_DATABASE; + if (getlang eq $DEFAULT_LANG) { + $title = "acctsubj.title_$lndb"; + } else { + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + $title = "COALESCE(acctsubj.title_$lndb, acctsubj.title_$lndbdef)"; + } + } + push @cols, $DBH->strcat("acctsubj.code", "' '", $title) . " AS subj"; + push @cols, "sum(CASE WHEN acctrecs.credit THEN acctrecs.amount ELSE -acctrecs.amount END)" + . " AS balance"; + $sql = "SELECT " . join(", ", @cols) + . " FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " LEFT JOIN accttrx ON acctrecs.trx=accttrx.sn" + . " WHERE date<=" . $DBH->quote($self->{"enddate"}) + . " AND (acctsubj.code LIKE '1%'" + . " OR acctsubj.code LIKE '2%'" + . " OR acctsubj.code LIKE '3%')" + . " GROUP BY acctsubj.code, $title" + . " ORDER BY acctsubj.code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + @subjs = qw(); + push @subjs, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + @subjs = grep $$_{"balance"} != 0, @subjs; + + # Obtain the carry-over record of assets/liabilities + $_ = "sum(CASE WHEN acctrecs.credit THEN -acctrecs.amount ELSE acctrecs.amount END)" + . " AS balance"; + $sql = "SELECT $_ FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " LEFT JOIN accttrx ON acctrecs.trx=accttrx.sn" + . " WHERE (acctsubj.code LIKE '1%'" + . " OR acctsubj.code LIKE '2%'" + . " OR acctsubj.code LIKE '3%')" + . " AND accttrx.date<" . $DBH->quote($self->{"startdate"}) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $_ = $sth->fetchrow_hashref; + undef $sth; + push @subjs, { + "subj" => acctsubj_title(acctsubj_sn(ACCTSUBJ_INCOME_ACUM)), + "balance" => $$_{"balance"}, + } if defined $$_{"balance"}; + + # Obtain the net income or loss for current period + $self->sql_filter; + $_ = "sum(CASE WHEN acctrecs.credit THEN acctrecs.amount ELSE -acctrecs.amount END)" + . " AS balance"; + $sql = "SELECT $_ FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " LEFT JOIN accttrx ON acctrecs.trx=accttrx.sn" + . " WHERE date>=" . $DBH->quote($self->{"startdate"}) + . " AND date<=" . $DBH->quote($self->{"enddate"}) + . " AND NOT (acctsubj.code LIKE '1%'" + . " OR acctsubj.code LIKE '2%'" + . " OR acctsubj.code LIKE '3%');\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $_ = $sth->fetchrow_hashref; + undef $sth; + push @subjs, { + "subj" => acctsubj_title(acctsubj_sn(ACCTSUBJ_INCOME_CUR)), + "balance" => $$_{"balance"}, + } if defined $$_{"balance"}; + + # Add each major category + %recs = qw(); + ($sumdebit, $sumcredit) = (0, 0); + foreach my $majsubj ((1, 2, 3)) { + my $sum; + $recs{$majsubj} = []; + push @{$recs{$majsubj}}, { + "subj" => acctsubj_title(acctsubj_sn($majsubj)), + "amount" => "", + }; + $sum = 0; + %_ = map { substr($$_{"subj"}, 0, 2) => 1 } + grep $$_{"subj"} =~ /^$majsubj/, @subjs; + foreach my $minsubj (sort keys %_) { + push @{$recs{$majsubj}}, { + "subj" => acctsubj_title(acctsubj_sn($minsubj)), + "amount" => "", + } if $minsubj !~ /^(?:12|15|22)$/; + foreach (sort { $$a{"subj"} cmp $$b{"subj"} } grep $$_{"subj"} =~ /^$minsubj/, @subjs) { + push @{$recs{$majsubj}}, { + "subj" => $$_{"subj"}, + "amount" => $$_{"balance"}, + }; + $sum += $$_{"balance"}; + } + } + push @{$recs{$majsubj}}, { + "subj" => C_("Total"), + "amount" => $sum, + }; + if ($majsubj == 1) { + $sumdebit += $sum; + } else { + $sumcredit += $sum; + } + } + @debits = @{$recs{1}}; + @credits = (@{$recs{2}}, { "subj" => "", "amount" => "" }, @{$recs{3}}); + + # Supply blank records + while (@debits != @credits) { + if (@debits < @credits) { + push @debits, { "subj" => "", "amount" => "" }; + } else { + push @credits, { "subj" => "", "amount" => "" }; + } + } + + # Supply the total record + push @debits, { + "subj" => C_("Total"), + "amount" => $sumdebit, + }; + push @credits, { + "subj" => C_("Total"), + "amount" => $sumcredit, + }; + + # Invert the amount of the debit records + foreach (@debits) { + $$_{"amount"} *= -1 if $$_{"amount"} ne ""; + } + + # Join the debit and credit records into the balance sheet + $self->{"current"} = []; + for ($_ = 0; $_ < @debits; $_++) { + push @{$self->{"current"}}, { + "subjd" => ${$debits[$_]}{"subj"}, + "amountd" => ${$debits[$_]}{"amount"}, + "subjc" => ${$credits[$_]}{"subj"}, + "amountc" => ${$credits[$_]}{"amount"}, + }; + } + + # The number of rows per page + $self->{"pagesize"} = $self->{"DEFAULT_LIST_SIZE"}; + # Paging not in use + $self->{"total"} = scalar(@{$self->{"current"}}); + $self->{"lastpage"} = 1; + $self->{"startno"} = 0; + $self->{"endno"} = $self->{"total"} - 1; + # If endno is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Set the columns to be displayed + $self->{"cols"} = [qw(subjd amountd subjc amountc)]; + $self->{"listcols"} = [qw(subjd amountd subjc amountc)]; + + # Done + return $self->{"error"}; +} + +# colval: Output a list column value +sub colval : method { + local ($_, %_); + my ($self, $col, %row); + ($self, $col, %row) = @_; + + # Null/no value + return h(t_notset()) if !defined $row{$col}; + + # The debit and the credit + if ($col eq "subjd" || $col eq "subjc") { + if ($row{$col} =~ /^\d\d /) { + return "
    " + . h_abbr($row{$col}) . "
    "; + } elsif ($row{$col} =~ /^\d\d\d/) { + return "
    " + . h_abbr($row{$col}) . "
    "; + } else { + return h_abbr($row{$col}); + } + } + + # The amount + if ($col eq "amountd" || $col eq "amountc") { + return "" if $row{$col} eq ""; + if ($row{$col} < 0) { + return "
    (" + . h_abbr(fmtntamount -$row{$col}) . ")
    "; + } else { + return "
    " + . h_abbr(fmtntamount $row{$col}) . "
    "; + } + } + + # Run the parent method + return $self->SUPER::colval($col, %row); +} + +# html_data_download: Display the data download link +sub html_data_download : method { + local ($_, %_); + my ($self, $url, $title); + $self = $_[0]; + # No data + return if $self->{"total"} == 0; + # Construct the URL + @_ = qw(); + push @_, "list=blncshet"; + push @_, $self->{"actrange"}; + push @_, "format=csv"; + $url = $REQUEST_FILE . "?" . join "&", @_; + $title = h_abbr(C_("Download the data as a CSV file.")); + print << "EOT"; +

    $title

    + +EOT + return; +} + +# html_csv: Return the data as CSV +sub html_csv : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Output a header to suggest for download instead of display + $HTTP_HEADERS{"Content-Disposition"} = + "attachment; filename=balance_sheet.csv"; + $CONTENT_TYPE = "text/csv; charset=" . getlang LN_CHARSET; + # The header column + @_ = map((exists ${$self->{"col_labels"}}{$_}? ${$self->{"col_labels"}}{$_}: $_), + @{$self->{"listcols"}}); + s/"/""/g foreach @_; # " + print join(",", map "\"$_\"", @_) . "\n"; + # The data + foreach my $current (@{$self->{"current"}}) { + @_ = map $$current{$_}, @{$self->{"listcols"}}; + foreach (@_) { + $_ = "" if !defined $_; + s/"/""/g; # " + } + print join(",", map "\"$_\"", @_) . "\n"; + } + return; +} + +# html_liststat: Display the list statistics +sub html_liststat : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Print the current time period + if (!$self->{"nodata"}) { + my ($message, $from, $to); + ($from, $to) = ($self->{"startdate"}, $self->{"enddate"}); + $message = h(C_("From [_1] to [_2].", $from, $to)); + + print << "EOT"; +

    $message

    + +EOT + } + return; +} + +# html_listprefform: Display a form to change the list preference +# Make it a null function +sub html_listprefform : method {} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my ($self, $total); + $self = $_[0]; + + $total = $self->{"total"}; + # Inherit the empty list statistics message + return $self->SUPER::liststat_message if $self->{"total"} == 0; + return C_("[*,_1,accounting subject].", $self->{"total"} - 1); +} + +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Reports/Cash.pm b/lib/perl5/Selima/List/Accounting/Reports/Cash.pm new file mode 100644 index 0000000..2b30170 --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Reports/Cash.pm @@ -0,0 +1,440 @@ +# Selima Website Content Management System +# Cash.pm: The cash accounting report. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-24 + +package Selima::List::Accounting::Reports::Cash; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Accounting::Reports); + +use POSIX qw(floor); +use Text::Capitalize qw(capitalize_title); +use URI::Escape qw(uri_escape); + +use Selima::Accounting; +use Selima::CommText; +use Selima::DataVars qw($DBH :l10n :lninfo :output :requri); +use Selima::Format; +use Selima::GetLang; +use Selima::LnInfo; +use Selima::MarkAbbr; +use Selima::ShortCut; +use Selima::UserPref; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The list type + $self->{"type"} = "cash"; + if (@ALL_LINGUAS == 1) { + $self->{"view"} = "acctrep_cash_list"; + } else { + $self->{"view"} = "acctrep_cash_list_" . getlang(LN_DATABASE); + } + # The subject + $self->{"subj"} = $self->{"FORM"}->param("subj"); + $self->{"subj"} = "" if !defined $self->{"subj"}; + # The page title + $_ = $self->{"subj"} eq ""? + C_("current assets and liabilities"): + acctsubj_title(acctsubj_sn($self->{"subj"})); + s/^\d+ //; + $self->{"title"} = capitalize_title(C_("Cash book - [_1]", $_)); + $self->{"title"} =~ s/ - /\x{2014}/; + # Column labels + $self->col_labels( + ); + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, $cols, $table, $where, $orderby, $limit, $sth, $sql, $error); + my ($balance, $brought, $sumincome, $sumexpense); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + $self->{"total"} = undef; + + # No need to run if there is no data at all + if ($self->{"nodata"}) { + $self->{"total"} = 0; + return $self->{"error"}; + } + + # See if we need to use views or not. + # Views make things much faster and easier, but some DBMS has no views. + # *MySQL has no views* + if ($self->{"useview"}) { + ($cols, $table, $where, $orderby, $limit) = $self->select_with_view; + } else { + ($cols, $table, $where, $orderby, $limit) = $self->select_without_view; + } + + # Find the balance before our date range + $_ = "sum(CASE WHEN acctrecs.credit THEN -amount ELSE amount END) AS sum"; + if ($self->{"subj"} eq "") { + $sql = "SELECT $_ FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " LEFT JOIN accttrx ON acctrecs.trx=accttrx.sn" + . " WHERE (acctsubj.code LIKE '11%'" + . " OR acctsubj.code LIKE '12%'" + . " OR acctsubj.code LIKE '21%'" + . " OR acctsubj.code LIKE '22%')" + . " AND accttrx.date<" . $DBH->quote($self->{"startdate"}) . ";\n"; + } else { + $sql = "SELECT $_ FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " LEFT JOIN accttrx ON acctrecs.trx=accttrx.sn" + . " WHERE acctsubj.code LIKE '" . $self->{"subj"} . "%'" + . " AND accttrx.date<" . $DBH->quote($self->{"startdate"}) . ";\n"; + } + $sth = $DBH->prepare($sql); + $sth->execute; + $balance = ${$sth->fetch}[0]; + + # Fetch everything + $self->{"select"} = sprintf "SELECT %s FROM %s%s%s%s;\n", + $cols, $table, $where, $orderby, $limit; + $sql = $self->{"select"}; + $sth = $DBH->prepare($sql); + $sth->execute; + + $self->{"current"} = []; + push @{$self->{"current"}}, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + + # Brought-forward record + undef $brought; + $brought = { + "_sel" => 0, + "_selurl" => undef, + "date" => $self->{"startdate"}, + "subj" => acctsubj_title(acctsubj_sn(ACCTSUBJ_INCOME_ACUM)), + "summary" => undef, + "income" => $balance > 0? $balance: 0, + "expense" => $balance < 0? -$balance: 0, + "balance" => $balance, + } if defined $balance; + # Do calculation on each record + $balance = 0 if !defined $balance; + ($sumincome, $sumexpense) = (0, 0); + for (my $i = 0; $i < @{$self->{"current"}}; $i++) { + $_ = ${$self->{"current"}}[$i]; + $balance = $balance + $$_{"income"} - $$_{"expense"}; + $sumincome += $$_{"income"}; + $sumexpense += $$_{"expense"}; + $$_{"balance"} = $balance; + } + # Prepend the brought-forward record + unshift @{$self->{"current"}}, $brought if defined $brought; + # Append the total record + push @{$self->{"current"}}, { + "_sel" => 0, + "_selurl" => undef, + "date" => $self->{"enddate"}, + "subj" => $self->{"subj"} eq ""? + C_("current assets and liabilities"): + acctsubj_title(acctsubj_sn($self->{"subj"})), + "summary" => C_("Total"), + "income" => $sumincome, + "expense" => $sumexpense, + "balance" => $balance, + }; + + # The number of rows per page + $_ = userpref("listsize", ref $self); + $self->{"pagesize"} = defined $_? $_: $self->{"DEFAULT_LIST_SIZE"}; + # Paging not in use + if (!defined $self->{"pagesize"}) { + $self->{"total"} = scalar(@{$self->{"current"}}); + $self->{"lastpage"} = 1; + $self->{"startno"} = 0; + $self->{"endno"} = $self->{"total"} - 1; + # If endno is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Done + return $self->{"error"}; + } + + # Obtain the total number + $self->{"total"} = scalar @{$self->{"current"}}; + $self->{"lastpage"} = floor(($self->{"total"} - 1) / $self->{"pagesize"}) + 1; + # If last page is 0 (when total is 0), set to page 1 + $self->{"lastpage"} = 1 if $self->{"lastpage"} < 1; + + # Check the page number + # Show the last page by default, but not reverse the number colume + $_ = $self->{"reverse"}; + $self->{"reverse"} = 1; + $error = $self->check_pageno; + $self->{"reverse"} = $_; + $self->{"error"} = $error if defined $error && !defined $self->{"error"}; + + # Calculate the start and end record number + $self->{"startno"} = ($self->{"pageno"} - 1) * $self->{"pagesize"}; + $self->{"endno"} = $self->{"pageno"} * $self->{"pagesize"} - 1; + # If there is not enough remaining records, set to the last one + $self->{"endno"} = $self->{"total"} - 1 + if $self->{"endno"} > $self->{"total"} - 1; + # If the last record is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Obtain everything in this page + $self->{"current"} = [ @{$self->{"current"}}[$self->{"startno"}...$self->{"endno"}] ] + if !$self->{"iscsv"}; + + # Set the columns to be displayed + $self->{"listcols"} = [qw(date subj summary income expense balance)]; + # Done + return $self->{"error"}; +} + +# page_param: Obtain page parameters +sub page_param : method { + local ($_, %_); + my ($self, $rev, $r); + $self = $_[0]; + $rev = $self->{"reverse"}; + $self->{"reverse"} = 1; + # Run the parent method + $r = $self->SUPER::page_param; + $self->{"reverse"} = $rev; + return $r; +} + +# colval: Output a list column value +sub colval : method { + local ($_, %_); + my ($self, $col, %row); + ($self, $col, %row) = @_; + + # Display nothing instead of "not set" for empty summaries + return "" if $col =~ /^(?:date|summary)$/ && !defined $row{$col}; + + # Null/no value + return h(t_notset()) if !defined $row{$col}; + + # The balance + if ($col eq "balance") { + return "" if $row{$col} eq ""; + if ($row{$col} > 0) { + return "
    " + . h_abbr(fmtntamount $row{$col}) . "
    "; + } elsif ($row{$col} < 0) { + return "
    -" + . h_abbr(fmtntamount -$row{$col}) . "
    "; + } else { + return "
    -
    "; + } + } + + # Run the parent method + return $self->SUPER::colval($col, %row); +} + +# pre_filter: Set the pre-defined filter +sub pre_filter : method { + local ($_, %_); + my ($self, @conds); + $self = $_[0]; + @conds = qw(); + if ($self->{"subj"} eq "") { + push @conds, "_subj NOT LIKE '11%'"; + push @conds, "_subj NOT LIKE '12%'"; + push @conds, "_subj NOT LIKE '21%'"; + push @conds, "_subj NOT LIKE '22%'"; + @_ = qw(); + push @_, "accttrx_has_subj(_trx, '11')"; + push @_, "accttrx_has_subj(_trx, '12')"; + push @_, "accttrx_has_subj(_trx, '21')"; + push @_, "accttrx_has_subj(_trx, '22')"; + push @conds, "(" . join(" OR ", @_) . ")"; + } else { + push @conds, "_subj NOT LIKE '" . $self->{"subj"} . "%'"; + push @conds, "accttrx_has_subj(_trx, '" . $self->{"subj"} . "')"; + } + push @conds, $_ if defined($_ = $self->SUPER::pre_filter); + return undef if @conds == 0; + return join " AND ", @conds; +} + +# html_select_subject: Display the subject search box +sub html_select_subject : method { + local ($_, %_); + my ($self, $label, @subjs); + my ($sql, $sth, $count, $row, $thiscol, $defcol); + $self = $_[0]; + + # The subject + $label = h_abbr(C_("Accounting subject:")); + # Obtain all the cash subjects + $sql = "SELECT acctsubj.code FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " WHERE acctsubj.code LIKE '11%'" + . " OR acctsubj.code LIKE '12%'" + . " OR acctsubj.code LIKE '21%'" + . " OR acctsubj.code LIKE '22%'" + . " GROUP BY acctsubj.code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @_ = qw(); $i < $count; $i++) { + $row = $sth->fetchrow_hashref; + push @_, $$row{"code"}; + } + undef $sth; + %_ = map { $_ => 1 } @_; + # Add all of their parents + foreach (keys %_) { + $_{$_} = 1 while s/.$//; + } + delete $_{""}; + delete $_{"1"}; + delete $_{"11"}; + delete $_{"12"}; + delete $_{"2"}; + delete $_{"21"}; + delete $_{"22"}; + @_ = qw(); + push @_, "code AS value"; + if (@ALL_LINGUAS == 1) { + push @_, $DBH->strcat("code", "' '", "title") + . " AS content"; + } else { + $thiscol = "title_" . getlang LN_DATABASE; + if (getlang eq $DEFAULT_LANG) { + push @_, $DBH->strcat("code", "' '", $thiscol) + . " AS content"; + } else { + $defcol = "title_" . ln($DEFAULT_LANG, LN_DATABASE); + push @_, $DBH->strcat("code", "' '", "COALESCE($thiscol, $defcol)") + . " AS content"; + } + } + $sql = "SELECT " . join(", ", @_) . " FROM acctsubj" + . " WHERE " . join(" OR ", map "code=" . $DBH->quote($_), sort keys %_) + . " ORDER BY code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @subjs = qw(); $i < $count; $i++) { + push @subjs, {%{$sth->fetchrow_hashref}}; + } + undef $sth; + unshift @subjs, { "value" => "", "content" => C_("current assets and liabilities"), }; + + # Display the form + print << "EOT"; +

    $label + +

    + +EOT + return; +} + +# html_data_download: Display the data download link +sub html_data_download : method { + local ($_, %_); + my ($self, $form, $url, $title); + $self = $_[0]; + $form = $self->{"FORM"}; + # No data + return if $self->{"total"} == 0; + # Construct the URL + @_ = qw(); + push @_, "list=cash"; + push @_, "subj=" . uri_escape($self->{"subj"}); + push @_, $self->{"actrange"}; + push @_, "format=csv"; + $url = $REQUEST_FILE . "?" . join "&", @_; + $title = h_abbr(C_("Download the data as a CSV file.")); + print << "EOT"; +

    $title

    + +EOT + return; +} + +# html_csv: Return the data as CSV +sub html_csv : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Output a header to suggest for download instead of display + $HTTP_HEADERS{"Content-Disposition"} = + "attachment; filename=cash_details.csv"; + $CONTENT_TYPE = "text/csv; charset=" . getlang LN_CHARSET; + # The header column + @_ = map((exists ${$self->{"col_labels"}}{$_}? ${$self->{"col_labels"}}{$_}: $_), + @{$self->{"listcols"}}); + s/"/""/g foreach @_; # " + print join(",", map "\"$_\"", @_) . "\n"; + # The data + foreach my $current (@{$self->{"current"}}) { + @_ = map $$current{$_}, @{$self->{"listcols"}}; + foreach (@_) { + $_ = "" if !defined $_; + s/"/""/g; # " + } + print join(",", map "\"$_\"", @_) . "\n"; + } + return; +} + +# html_pagebar: Display a page navigation bar +sub html_pagebar : method { + local ($_, %_); + my ($self, $rev, $r); + $self = $_[0]; + $rev = $self->{"reverse"}; + $self->{"reverse"} = 1; + # Run the parent method + $r = $self->SUPER::html_pagebar; + $self->{"reverse"} = $rev; + return $r; +} + +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm b/lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm new file mode 100644 index 0000000..d0bf217 --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm @@ -0,0 +1,477 @@ +# Selima Website Content Management System +# Summary.pm: The cash summary accounting report. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-27 + +package Selima::List::Accounting::Reports::Cash::Summary; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Accounting::Reports); + +use POSIX qw(floor); +use Text::Capitalize qw(capitalize_title); +use URI::Escape qw(uri_escape); + +use Selima::Accounting; +use Selima::CommText; +use Selima::DataVars qw($DBH :env :l10n :lninfo :output :requri); +use Selima::Format; +use Selima::GetLang; +use Selima::LnInfo; +use Selima::MarkAbbr; +use Selima::ShortCut; +use Selima::UserPref; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class, @cols, $sql); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The list type + $self->{"type"} = "cashsum"; + # The subject + $self->{"subj"} = $self->{"FORM"}->param("subj"); + $self->{"subj"} = "" if !defined $self->{"subj"}; + # The page title + $_ = $self->{"subj"} eq ""? + C_("current assets and liabilities"): + acctsubj_title(acctsubj_sn($self->{"subj"})); + s/^\d+ //; + $self->{"title"} = capitalize_title(C_("Cash Book Summary - [_1]", $_)); + $self->{"title"} =~ s/ - /\x{2014}/; + + # Construct the view + $self->{"view"} = "acctrep_cash_summary_list"; + $self->{"noselect"} = 1; + @_ = qw(); + push @_, "list=cash"; + push @_, "subj=" . uri_escape($self->{"subj"}); + push @_, "r=m"; + push @_, "m="; + $_ = $REQUEST_FILE . "?" . join "&", @_; + + if ($self->{"subj"} eq "") { + @cols = qw(); + push @cols, $DBH->strcat($DBH->quote($_), + "lpad(cast(extract(year FROM date) AS text), 4, '0')", + "'-'", "lpad(cast(extract(month FROM date) AS text), 2, '0')") . " AS _viewurl"; + push @cols, $DBH->strcat("lpad(cast(extract(year FROM date) AS text), 4, '0')", + "'-'", "lpad(cast(extract(month FROM date) AS text), 2, '0')") . " AS month"; + @_ = qw(); + push @_, "acctsum_debit(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), '11')"; + push @_, "acctsum_debit(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), '12')"; + push @_, "acctsum_debit(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), '21')"; + push @_, "acctsum_debit(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), '22')"; + push @cols, join(" + ", @_) . " AS income"; + @_ = qw(); + push @_, "acctsum_credit(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), '11')"; + push @_, "acctsum_credit(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), '12')"; + push @_, "acctsum_credit(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), '21')"; + push @_, "acctsum_credit(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), '22')"; + push @cols, join(" + ", @_) . " AS expense"; + @_ = qw(); + push @_, "acctsum_balance(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), '11')"; + push @_, "acctsum_balance(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), '12')"; + push @_, "acctsum_balance(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), '21')"; + push @_, "acctsum_balance(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), '22')"; + push @cols, join(" + ", @_) . " AS balance"; + $sql = "CREATE TEMPORARY VIEW " . $self->{"view"} . " AS" + . " SELECT " . join(", ", @cols) + . " FROM accttrx" + . " GROUP BY extract(year FROM date), extract(month FROM date)" + . " ORDER BY extract(year FROM date), extract(month FROM date);\n"; + } else { + @cols = qw(); + push @cols, $DBH->strcat($DBH->quote($_), + "lpad(cast(extract(year FROM date) AS text), 4, '0')", + "'-'", "lpad(extract(cast(month FROM date) AS text), 2, '0')") . " AS _viewurl"; + push @cols, $DBH->strcat("lpad(cast(extract(year FROM date) AS text), 4, '0')", + "'-'", "lpad(cast(extract(month FROM date) AS text), 2, '0')") . " AS month"; + push @cols, "acctsum_debit(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), " + . " " . $DBH->quote($self->{"subj"}) . ") AS income"; + push @cols, "acctsum_credit(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer)," + . " " . $DBH->quote($self->{"subj"}) . ") AS expense"; + push @cols, "acctsum_balance(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), " + . " " . $DBH->quote($self->{"subj"}) . ") AS balance"; + $sql = "CREATE TEMPORARY VIEW " . $self->{"view"} . " AS" + . " SELECT " . join(", ", @cols) + . " FROM accttrx" + . " GROUP BY extract(year FROM date), extract(month FROM date)" + . " ORDER BY extract(year FROM date), extract(month FROM date);\n"; + } + $DBH->do($sql); + + # Column labels + $self->col_labels( + ); + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, $cols, $table, $where, $orderby, $limit, $sth, $sql, $error); + my ($sumincome, $sumexpense); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + $self->{"total"} = undef; + + # No need to run if there is no data at all + if (exists $self->{"nodata"} && $self->{"nodata"}) { + $self->{"total"} = 0; + return; + } + + # See if we need to use views or not. + # Views make things much faster and easier, but some DBMS has no views. + # *MySQL has no views* + if ($self->{"useview"}) { + ($cols, $table, $where, $orderby, $limit) = $self->select_with_view; + } else { + ($cols, $table, $where, $orderby, $limit) = $self->select_without_view; + } + + # Fetch everything + $self->{"select"} = sprintf "SELECT %s FROM %s%s%s%s;\n", + $cols, $table, $where, $orderby, $limit; + $sql = $self->{"select"}; + $sth = $DBH->prepare($sql); + $sth->execute; + + $self->{"current"} = []; + push @{$self->{"current"}}, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + + # Do calculation on each record + ($sumincome, $sumexpense) = (0, 0); + foreach (@{$self->{"current"}}) { + $sumincome += $$_{"income"}; + $sumexpense += $$_{"expense"}; + } + # Remove the starting and ending empty records + @_ = @{$self->{"current"}}; + shift @_ while @_ > 0 && ${$_[0]}{"income"} == 0 && ${$_[0]}{"expense"} == 0; + pop @_ while @_ > 0 && ${$_[$#_]}{"income"} == 0 && ${$_[$#_]}{"expense"} == 0; + $self->{"current"} = [@_]; + # Append the total record + if (@{$self->{"current"}} > 0) { + @_ = qw(); + push @_, "list=cash"; + push @_, "subj=" . uri_escape($self->{"subj"}); + push @_, "r=a"; + push @{$self->{"current"}}, { + "_viewurl" => $REQUEST_FILE . "?" . join("&", @_), + "month" => C_("Total"), + "income" => $sumincome, + "expense" => $sumexpense, + "balance" => ${(reverse @{$self->{"current"}})[0]}{"balance"}, + }; + } + + # The number of rows per page + $_ = userpref("listsize", ref $self); + $self->{"pagesize"} = defined $_? $_: $self->{"DEFAULT_LIST_SIZE"}; + # Paging not in use + if (!defined $self->{"pagesize"}) { + $self->{"total"} = scalar(@{$self->{"current"}}); + $self->{"lastpage"} = 1; + $self->{"startno"} = 0; + $self->{"endno"} = $self->{"total"} - 1; + # If endno is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Done + return $self->{"error"}; + } + + # Obtain the total number + $self->{"total"} = scalar @{$self->{"current"}}; + $self->{"lastpage"} = floor(($self->{"total"} - 1) / $self->{"pagesize"}) + 1; + # If last page is 0 (when total is 0), set to page 1 + $self->{"lastpage"} = 1 if $self->{"lastpage"} < 1; + + # Check the page number + # Show the last page by default, but not reverse the number colume + $_ = $self->{"reverse"}; + $self->{"reverse"} = 1; + $error = $self->check_pageno; + $self->{"reverse"} = $_; + $self->{"error"} = $error if defined $error && !defined $self->{"error"}; + + # Calculate the start and end record number + $self->{"startno"} = ($self->{"pageno"} - 1) * $self->{"pagesize"}; + $self->{"endno"} = $self->{"pageno"} * $self->{"pagesize"} - 1; + # If there is not enough remaining records, set to the last one + $self->{"endno"} = $self->{"total"} - 1 + if $self->{"endno"} > $self->{"total"} - 1; + # If the last record is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Obtain everything in this page + $self->{"current"} = [ @{$self->{"current"}}[$self->{"startno"}...$self->{"endno"}] ] + if !$self->{"iscsv"}; + + # Set the columns to be displayed + $self->{"cols"} = [qw(_viewurl month income expense balance)]; + $self->{"listcols"} = [qw(month income expense balance)]; + # Done + return $self->{"error"}; +} + +# page_param: Obtain page parameters +sub page_param : method { + local ($_, %_); + my ($self, $rev, $r); + $self = $_[0]; + $rev = $self->{"reverse"}; + $self->{"reverse"} = 1; + # Run the parent method + $r = $self->SUPER::page_param; + $self->{"reverse"} = $rev; + return $r; +} + +# colval: Output a list column value +sub colval : method { + local ($_, %_); + my ($self, $col, %row); + ($self, $col, %row) = @_; + + # Null/no value + return h(t_notset()) if !defined $row{$col}; + + # The balance + if ($col eq "balance") { + if ($row{$col} > 0) { + return "
    " + . h_abbr(fmtntamount $row{$col}) . "
    "; + } elsif ($row{$col} < 0) { + return "
    -" + . h_abbr(fmtntamount -$row{$col}) . "
    "; + } else { + return "
    -
    "; + } + } + + # Run the parent method + return $self->SUPER::colval($col, %row); +} + +# pre_filter: Set the pre-defined filter +# Make it a null function +sub pre_filter : method { } + +# html_report_query: Display the report query box +sub html_report_query : method { + local ($_, %_); + my ($self, $form, $request_file, $label, $curlist); + $self = $_[0]; + $form = $self->{"FORM"}; + + $request_file = h($REQUEST_FILE); + $label = h_abbr(C_("Query")); + + $curlist = h($self->{"type"}); + print << "EOT"; +
    +
    +
    + +EOT + # Display the subject selection if available + $self->html_select_subject if $self->can("html_select_subject"); + + print << "EOT"; +

    +

    +
    +
    + +EOT + return; +} + +# html_select_subject: Display the subject search box +sub html_select_subject : method { + local ($_, %_); + my ($self, $label, @subjs); + my ($sql, $sth, $count, $row, $thiscol, $defcol); + $self = $_[0]; + + # The subject + $label = h_abbr(C_("Accounting subject:")); + # Obtain all the cash subjects + $sql = "SELECT acctsubj.code FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " WHERE acctsubj.code LIKE '11%'" + . " OR acctsubj.code LIKE '12%'" + . " OR acctsubj.code LIKE '21%'" + . " OR acctsubj.code LIKE '22%'" + . " GROUP BY acctsubj.code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @_ = qw(); $i < $count; $i++) { + $row = $sth->fetchrow_hashref; + push @_, $$row{"code"}; + } + undef $sth; + %_ = map { $_ => 1 } @_; + # Add all of their parents + foreach (keys %_) { + $_{$_} = 1 while s/.$//; + } + delete $_{""}; + delete $_{"1"}; + delete $_{"11"}; + delete $_{"12"}; + delete $_{"2"}; + delete $_{"21"}; + delete $_{"22"}; + @_ = qw(); + push @_, "code AS value"; + if (@ALL_LINGUAS == 1) { + push @_, $DBH->strcat("code", "' '", "title") + . " AS content"; + } else { + $thiscol = "title_" . getlang LN_DATABASE; + if (getlang eq $DEFAULT_LANG) { + push @_, $DBH->strcat("code", "' '", $thiscol) + . " AS content"; + } else { + $defcol = "title_" . ln($DEFAULT_LANG, LN_DATABASE); + push @_, $DBH->strcat("code", "' '", "COALESCE($thiscol, $defcol)") + . " AS content"; + } + } + $sql = "SELECT " . join(", ", @_) . " FROM acctsubj" + . " WHERE " . join(" OR ", map "code=" . $DBH->quote($_), sort keys %_) + . " ORDER BY code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @subjs = qw(); $i < $count; $i++) { + push @subjs, {%{$sth->fetchrow_hashref}}; + } + undef $sth; + unshift @subjs, { "value" => "", "content" => C_("current assets and liabilities"), }; + + # Display the form + print << "EOT"; +

    $label + +

    + +EOT + return; +} + +# html_data_download: Display the data download link +sub html_data_download : method { + local ($_, %_); + my ($self, $url, $title); + $self = $_[0]; + # No data + return if $self->{"total"} == 0; + # Construct the URL + @_ = qw(); + push @_, "list=cashsum"; + push @_, "subj=" . uri_escape($self->{"subj"}); + push @_, "format=csv"; + $url = $REQUEST_FILE . "?" . join "&", @_; + $title = h_abbr(C_("Download the data as a CSV file.")); + print << "EOT"; +

    $title

    + +EOT + return; +} + +# html_csv: Return the data as CSV +sub html_csv : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Output a header to suggest for download instead of display + $HTTP_HEADERS{"Content-Disposition"} = + "attachment; filename=cash_summary.csv"; + $CONTENT_TYPE = "text/csv; charset=" . getlang LN_CHARSET; + # The header column + @_ = map((exists ${$self->{"col_labels"}}{$_}? ${$self->{"col_labels"}}{$_}: $_), + @{$self->{"listcols"}}); + s/"/""/g foreach @_; # " + print join(",", map "\"$_\"", @_) . "\n"; + # The data + foreach my $current (@{$self->{"current"}}) { + print join(",", map $$current{$_}, @{$self->{"listcols"}}) . "\n"; + } + return; +} + +# html_pagebar: Display a page navigation bar +sub html_pagebar : method { + local ($_, %_); + my ($self, $rev, $r); + $self = $_[0]; + $rev = $self->{"reverse"}; + $self->{"reverse"} = 1; + # Run the parent method + $r = $self->SUPER::html_pagebar; + $self->{"reverse"} = $rev; + return $r; +} + +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm b/lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm new file mode 100644 index 0000000..42f752f --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm @@ -0,0 +1,366 @@ +# Selima Website Content Management System +# IncmStat.pm: The income statement accounting report. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-10-03 + +package Selima::List::Accounting::Reports::IncmStat; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Accounting::Reports); + +use Selima::Accounting; +use Selima::CommText; +use Selima::DataVars qw($DBH :l10n :lninfo :output :requri); +use Selima::Format; +use Selima::GetLang; +use Selima::LnInfo; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = C_("Income Statement"); + # The list type + $self->{"type"} = "incmstat"; + # The default number of rows per page + $self->{"DEFAULT_LIST_SIZE"} = undef; + # Known columns that should not be sorted with + # List sorting is disabled here at all + push @{$self->{"COLS_NO_SORT_BY"}}, qw(amount1 amount2); + $self->{"noselect"} = 1; + # Column labels + $self->col_labels( + "amount1" => C_("Amount"), + "amount2" => C_("Amount"), + ); + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, @cols, $title, $sth, $sql, $error); + my (@subjs, $sum, $balance); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + $self->{"total"} = undef; + + # No need to run if there is no data at all + if (exists $self->{"nodata"} && $self->{"nodata"}) { + $self->{"total"} = 0; + return; + } + + # Construct the SQL query statement + # Obtain the period once + $self->sql_filter; + @cols = qw(); + if (@ALL_LINGUAS == 1) { + $title = "acctsubj.title"; + } else { + my ($lndb, $lndbdef); + $lndb = getlang LN_DATABASE; + if (getlang eq $DEFAULT_LANG) { + $title = "acctsubj.title_$lndb"; + } else { + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + $title = "COALESCE(acctsubj.title_$lndb, acctsubj.title_$lndbdef)"; + } + } + push @cols, $DBH->strcat("acctsubj.code", "' '", $title) . " AS subj"; + push @cols, "sum(CASE WHEN acctrecs.credit THEN acctrecs.amount ELSE -acctrecs.amount END)" + . " AS balance"; + $sql = "SELECT " . join(", ", @cols) + . " FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " LEFT JOIN accttrx ON acctrecs.trx=accttrx.sn" + . " WHERE date>=" . $DBH->quote($self->{"startdate"}) + . " AND date<=" . $DBH->quote($self->{"enddate"}) + . " AND NOT (acctsubj.code LIKE '1%'" + . " OR acctsubj.code LIKE '2%'" + . " OR acctsubj.code LIKE '3%')" + . " GROUP BY acctsubj.code, $title" + . " ORDER BY acctsubj.code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + @subjs = qw(); + push @subjs, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + + $self->{"current"} = []; + $balance = 0; + foreach my $majsubj ((4, 5, 6, 7, 8, 9)) { + push @{$self->{"current"}}, { + "subj" => acctsubj_title(acctsubj_sn($majsubj)), + "amount1" => "", + "amount2" => "", + }; + # non-operating revenue and expenses, other income (expense) + if ($majsubj == 7) { + # non-operating revenue + $sum = 0; + push @{$self->{"current"}}, { + "subj" => acctsubj_title(acctsubj_sn(71)), + "amount1" => "", + "amount2" => "", + }; + foreach (grep $$_{"subj"} =~ /^7[1234]/, @subjs) { + push @{$self->{"current"}}, { + "subj" => $$_{"subj"}, + "amount1" => $$_{"balance"}, + "amount2" => "", + }; + $sum += $$_{"balance"}; + } + push @{$self->{"current"}}, { + "subj" => C_("Total"), + "amount1" => "", + "amount2" => $sum, + }; + $balance += $sum; + # non-operating expenses + $sum = 0; + push @{$self->{"current"}}, { + "subj" => acctsubj_title(acctsubj_sn(75)), + "amount1" => "", + "amount2" => "", + }; + foreach (grep $$_{"subj"} =~ /^7[5678]/, @subjs) { + push @{$self->{"current"}}, { + "subj" => $$_{"subj"}, + "amount1" => $$_{"balance"}, + "amount2" => "", + }; + $sum += $$_{"balance"}; + } + push @{$self->{"current"}}, { + "subj" => C_("Total"), + "amount1" => "", + "amount2" => $sum, + }; + $balance += $sum; + # Other categories + } else { + $sum = 0; + %_ = map { substr($$_{"subj"}, 0, 2) => 1 } + grep $$_{"subj"} =~ /^$majsubj/, @subjs; + foreach my $minsubj (sort keys %_) { + push @{$self->{"current"}}, { + "subj" => acctsubj_title(acctsubj_sn($minsubj)), + "amount1" => "", + "amount2" => "", + }; + foreach (grep $$_{"subj"} =~ /^$minsubj/, @subjs) { + push @{$self->{"current"}}, { + "subj" => $$_{"subj"}, + "amount1" => $$_{"balance"}, + "amount2" => "", + }; + $sum += $$_{"balance"}; + } + } + push @{$self->{"current"}}, { + "subj" => C_("Total"), + "amount1" => "", + "amount2" => $sum, + }; + $balance += $sum; + } + # 4 operating revenue + # No balance after operating revenue + if ($majsubj != 4) { + # 5 operating costs + $_ = C_("Gross income") if $majsubj == 5; + # 6 operating expenses + $_ = C_("Operating income") if $majsubj == 6; + # 7 non-operating revenue and expenses, other income (expense) + $_ = C_("Before tax income") if $majsubj == 7; + # 8 income tax expense (or benefit) + $_ = C_("After tax income") if $majsubj == 8; + # 9 nonrecurring gain or loss + $_ = acctsubj_title(acctsubj_sn(ACCTSUBJ_INCOME_CUR)) + if $majsubj == 9; + push @{$self->{"current"}}, { + "subj" => $_, + "amount1" => "", + "amount2" => $balance, + }; + } + # Put a blank separator record + if ($majsubj != 9) { + push @{$self->{"current"}}, { + "subj" => "", + "amount1" => "", + "amount2" => "", + }; + } + } + + # The number of rows per page + $self->{"pagesize"} = $self->{"DEFAULT_LIST_SIZE"}; + # Paging not in use + $self->{"total"} = scalar(@{$self->{"current"}}); + $self->{"lastpage"} = 1; + $self->{"startno"} = 0; + $self->{"endno"} = $self->{"total"} - 1; + # If endno is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Set the columns to be displayed + $self->{"cols"} = [qw(subj amount1 amount2)]; + $self->{"listcols"} = [qw(subj amount1 amount2)]; + + # Done + return $self->{"error"}; +} + +# colval: Output a list column value +sub colval : method { + local ($_, %_); + my ($self, $col, %row); + ($self, $col, %row) = @_; + + # Null/no value + return h(t_notset()) if !defined $row{$col}; + + # The debit and the credit + if ($col eq "subj") { + if ($row{$col} =~ /^\d\d /) { + return "
    " + . h_abbr($row{$col}) . "
    "; + } elsif ( $row{$col} =~ /^\d\d\d/ + && substr($row{$col}, 0, 4) ne ACCTSUBJ_INCOME_CUR) { + return "
    " + . h_abbr($row{$col}) . "
    "; + } else { + return h_abbr($row{$col}); + } + } + + # The amount + if ($col eq "amount1" || $col eq "amount2") { + return "" if $row{$col} eq ""; + if ($row{$col} < 0) { + return "
    (" + . h_abbr(fmtntamount -$row{$col}) . ")
    "; + } else { + return "
    " + . h_abbr(fmtntamount $row{$col}) . "
    "; + } + } + + # Run the parent method + return $self->SUPER::colval($col, %row); +} + +# html_data_download: Display the data download link +sub html_data_download : method { + local ($_, %_); + my ($self, $url, $title); + $self = $_[0]; + # No data + return if $self->{"total"} == 0; + # Construct the URL + @_ = qw(); + push @_, "list=incmstat"; + push @_, $self->{"actrange"}; + push @_, "format=csv"; + $url = $REQUEST_FILE . "?" . join "&", @_; + $title = h_abbr(C_("Download the data as a CSV file.")); + print << "EOT"; +

    $title

    + +EOT + return; +} + +# html_csv: Return the data as CSV +sub html_csv : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Output a header to suggest for download instead of display + $HTTP_HEADERS{"Content-Disposition"} = + "attachment; filename=income_statement.csv"; + $CONTENT_TYPE = "text/csv; charset=" . getlang LN_CHARSET; + # The header column + @_ = map((exists ${$self->{"col_labels"}}{$_}? ${$self->{"col_labels"}}{$_}: $_), + @{$self->{"listcols"}}); + s/"/""/g foreach @_; # " + print join(",", map "\"$_\"", @_) . "\n"; + # The data + foreach my $current (@{$self->{"current"}}) { + @_ = map $$current{$_}, @{$self->{"listcols"}}; + foreach (@_) { + $_ = "" if !defined $_; + s/"/""/g; # " + } + print join(",", map "\"$_\"", @_) . "\n"; + } + return; +} + +# html_liststat: Display the list statistics +sub html_liststat : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Print the current time period + if (!$self->{"nodata"}) { + my ($message, $from, $to); + ($from, $to) = ($self->{"startdate"}, $self->{"enddate"}); + $message = h(C_("From [_1] to [_2].", $from, $to)); + + print << "EOT"; +

    $message

    + +EOT + } + return; +} + +# html_listprefform: Display a form to change the list preference +# Make it a null function +sub html_listprefform : method {} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my ($self, $total); + $self = $_[0]; + + $total = $self->{"total"}; + # Inherit the empty list statistics message + return $self->SUPER::liststat_message if $self->{"total"} == 0; + return C_("[*,_1,accounting subject].", $self->{"total"} - 1); +} + +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Reports/Journal.pm b/lib/perl5/Selima/List/Accounting/Reports/Journal.pm new file mode 100644 index 0000000..f57d185 --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Reports/Journal.pm @@ -0,0 +1,322 @@ +# Selima Website Content Management System +# Journal.pm: The journal accounting report. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-29 + +package Selima::List::Accounting::Reports::Journal; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Accounting::Reports); + +use POSIX qw(floor); +use URI::Escape qw(uri_escape); + +use Selima::Accounting; +use Selima::CommText; +use Selima::DataVars qw($DBH :l10n :lninfo :output :requri); +use Selima::GetLang; +use Selima::MarkAbbr; +use Selima::ShortCut; +use Selima::UserPref; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = C_("Journal"); + # The list type + $self->{"type"} = "journal"; + if (@ALL_LINGUAS == 1) { + $self->{"view"} = "acctrep_search_list"; + } else { + $self->{"view"} = "acctrep_search_list_" . getlang(LN_DATABASE); + } + # Columns should be displayed in a reversed order + $self->{"reverse"} = 1; + # Column labels + $self->col_labels( + "trxno" => C_("Transaction Number"), + "note" => C_("Note"), + ); + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, $cols, $table, $where, $orderby, $limit, $sth, $sql, $error); + my (@debits, @credits); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + $self->{"total"} = undef; + + # No need to run if there is no data at all + if (exists $self->{"nodata"} && $self->{"nodata"}) { + $self->{"total"} = 0; + return; + } + + # See if we need to use views or not. + # Views make things much faster and easier, but some DBMS has no views. + # *MySQL has no views* + if ($self->{"useview"}) { + ($cols, $table, $where, $orderby, $limit) = $self->select_with_view; + } else { + ($cols, $table, $where, $orderby, $limit) = $self->select_without_view; + } + + # Fetch everything + $self->{"select"} = sprintf "SELECT %s FROM %s%s%s%s;\n", + $cols, $table, $where, $orderby, $limit; + $sql = $self->{"select"}; + $sth = $DBH->prepare($sql); + $sth->execute; + + $self->{"current"} = []; + push @{$self->{"current"}}, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + # Set the selection column + unshift @{$self->{"cols"}}, "_sel"; + $$_{"_sel"} = 1 foreach @{$self->{"current"}}; + + # Find the carry-over balance + @_ = qw(); + push @_, "acctsubj.code AS code"; + push @_, "sum(CASE WHEN acctrecs.credit THEN -amount ELSE amount END) AS sum"; + $sql = "SELECT " . join(", ", @_) . " FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " LEFT JOIN accttrx ON acctrecs.trx=accttrx.sn" + . " WHERE (acctsubj.code LIKE '1%'" + . " OR acctsubj.code LIKE '2%'" + . " OR acctsubj.code LIKE '3%')" + . " AND acctsubj.code != " . $DBH->quote(ACCTSUBJ_INCOME_ACUM) + . " AND accttrx.date<" . $DBH->quote($self->{"startdate"}) + . " GROUP BY acctsubj.code" + . " ORDER BY acctsubj.code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + for ($_ = 0, @_ = qw(); $_ < $sth->rows; $_++) { + push @_, {%{$sth->fetchrow_hashref}}; + } + undef $sth; + # Create the carry-over transaction + @debits = qw(); + @credits = qw(); + foreach (@_) { + # Positive balance - from carry-over to account + if ($$_{"sum"} > 0) { + push @debits, { + "_sel" => 0, + "_selurl" => undef, + "date" => $self->{"startdate"}, + "trxno" => "", + "subj" => acctsubj_title(acctsubj_sn($$_{"code"})), + "summary" => "", + "debit" => $$_{"sum"}, + "credit" => 0, + "note" => C_("Brought forward"), + }; + push @credits, { + "_sel" => 0, + "_selurl" => undef, + "date" => $self->{"startdate"}, + "trxno" => "", + "subj" => acctsubj_title(acctsubj_sn(ACCTSUBJ_INCOME_ACUM)), + "summary" => acctsubj_title(acctsubj_sn($$_{"code"})), + "debit" => 0, + "credit" => $$_{"sum"}, + "note" => C_("Brought forward"), + }; + # Negative balance - from account to carry-over + } elsif ($$_{"sum"} < 0) { + push @debits, { + "_sel" => 0, + "_selurl" => undef, + "date" => $self->{"startdate"}, + "trxno" => "", + "subj" => acctsubj_title(acctsubj_sn(ACCTSUBJ_INCOME_ACUM)), + "summary" => acctsubj_title(acctsubj_sn($$_{"code"})), + "debit" => -$$_{"sum"}, + "credit" => 0, + "note" => C_("Brought forward"), + }; + push @credits, { + "_sel" => 0, + "_selurl" => undef, + "date" => $self->{"startdate"}, + "trxno" => "", + "subj" => acctsubj_title(acctsubj_sn($$_{"code"})), + "summary" => "", + "debit" => 0, + "credit" => -$$_{"sum"}, + "note" => C_("Brought forward"), + }; + } + # Skip subjects with zero balances + } + $self->{"current"} = [@debits, @credits, @{$self->{"current"}}]; + + # The number of rows per page + $_ = userpref("listsize", ref $self); + $self->{"pagesize"} = defined $_? $_: $self->{"DEFAULT_LIST_SIZE"}; + # Paging not in use + if (!defined $self->{"pagesize"}) { + $self->{"total"} = scalar(@{$self->{"current"}}); + $self->{"lastpage"} = 1; + $self->{"startno"} = 0; + $self->{"endno"} = $self->{"total"} - 1; + # If endno is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Done + return $self->{"error"}; + } + + # Obtain the total number + $self->{"total"} = scalar @{$self->{"current"}}; + $self->{"lastpage"} = floor(($self->{"total"} - 1) / $self->{"pagesize"}) + 1; + # If last page is 0 (when total is 0), set to page 1 + $self->{"lastpage"} = 1 if $self->{"lastpage"} < 1; + + # Check the page number + # Show the last page by default, but not reverse the number colume + $_ = $self->{"reverse"}; + $self->{"reverse"} = 1; + $error = $self->check_pageno; + $self->{"reverse"} = $_; + $self->{"error"} = $error if defined $error && !defined $self->{"error"}; + + # Calculate the start and end record number + $self->{"startno"} = ($self->{"pageno"} - 1) * $self->{"pagesize"}; + $self->{"endno"} = $self->{"pageno"} * $self->{"pagesize"} - 1; + # If there is not enough remaining records, set to the last one + $self->{"endno"} = $self->{"total"} - 1 + if $self->{"endno"} > $self->{"total"} - 1; + # If the last record is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Obtain everything in this page + $self->{"current"} = [ @{$self->{"current"}}[$self->{"startno"}...$self->{"endno"}] ] + if !$self->{"iscsv"}; + + # Set the columns to be displayed + $self->{"listcols"} = [qw(date trxno subj summary debit credit note)]; + # Done + return $self->{"error"}; +} + +# colval: Output a list column value +sub colval : method { + local ($_, %_); + my ($self, $col, %row); + ($self, $col, %row) = @_; + + # The subject + if ($col eq "subj") { + if ($row{"credit"} > 0) { + return "
    " + . h_abbr($row{$col}) . "
    "; + } else { + return h_abbr($row{$col}); + } + } + + # The summary + if ($col eq "summary") { + return "" if !defined $row{$col}; + return h_abbr($row{$col}); + } + + # Null/no value + return h(t_notset()) if !defined $row{$col}; + + # Run the parent method + return $self->SUPER::colval($col, %row); +} + +# html_data_download: Display the data download link +sub html_data_download : method { + local ($_, %_); + my ($self, $url, $title); + $self = $_[0]; + # No data + return if $self->{"total"} == 0; + # Construct the URL + @_ = qw(); + push @_, "list=journal"; + push @_, $self->{"actrange"}; + push @_, "format=csv"; + $url = $REQUEST_FILE . "?" . join "&", @_; + $title = h_abbr(C_("Download the data as a CSV file.")); + print << "EOT"; +

    $title

    + +EOT + return; +} + +# html_csv: Return the data as CSV +sub html_csv : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Output a header to suggest for download instead of display + $HTTP_HEADERS{"Content-Disposition"} = + "attachment; filename=journal.csv"; + $CONTENT_TYPE = "text/csv; charset=" . getlang LN_CHARSET; + # The header column + @_ = map((exists ${$self->{"col_labels"}}{$_}? ${$self->{"col_labels"}}{$_}: $_), + @{$self->{"listcols"}}); + s/"/""/g foreach @_; # " + print join(",", map "\"$_\"", @_) . "\n"; + # The data + foreach my $current (@{$self->{"current"}}) { + @_ = map $$current{$_}, @{$self->{"listcols"}}; + foreach (@_) { + $_ = "" if !defined $_; + s/"/""/g; # " + } + print join(",", map "\"$_\"", @_) . "\n"; + } + return; +} + +# html_list: List the items +sub html_list : method { + local ($_, %_); + my $self; + $self = $_[0]; + $self->{"reverse"} = 0; + # Run the parent method + $self->SUPER::html_list; + $self->{"reverse"} = 1; + return; +} + +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Reports/Ledger.pm b/lib/perl5/Selima/List/Accounting/Reports/Ledger.pm new file mode 100644 index 0000000..27613cd --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Reports/Ledger.pm @@ -0,0 +1,412 @@ +# Selima Website Content Management System +# Ledger.pm: The ledger accounting report. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-24 + +package Selima::List::Accounting::Reports::Ledger; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Accounting::Reports); + +use POSIX qw(floor); +use Text::Capitalize qw(capitalize_title); +use URI::Escape qw(uri_escape); + +use Selima::Accounting; +use Selima::CommText; +use Selima::DataVars qw($DBH :l10n :lninfo :output :requri); +use Selima::Format; +use Selima::GetLang; +use Selima::LnInfo; +use Selima::MarkAbbr; +use Selima::ShortCut; +use Selima::UserPref; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The list type + $self->{"type"} = "ldgr"; + if (@ALL_LINGUAS == 1) { + $self->{"view"} = "acctrep_ledger_list"; + } else { + $self->{"view"} = "acctrep_ledger_list_" . getlang(LN_DATABASE); + } + # The subject + $self->{"subj"} = $self->{"FORM"}->param("subj"); + $self->{"subj"} = ACCTSUBJ_CASH if !defined $self->{"subj"}; + # The page title + $_ = acctsubj_title(acctsubj_sn($self->{"subj"})); + s/^\d+ //; + $self->{"title"} = capitalize_title(C_("Ledger - [_1]", $_)); + $self->{"title"} =~ s/ - /\x{2014}/; + # Column labels + $self->col_labels( + ); + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, $cols, $table, $where, $orderby, $limit, $sth, $sql, $error); + my ($balance, @carryover); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + $self->{"total"} = undef; + + # No need to run if there is no data at all + if (exists $self->{"nodata"} && $self->{"nodata"}) { + $self->{"total"} = 0; + return; + } + + # See if we need to use views or not. + # Views make things much faster and easier, but some DBMS has no views. + # *MySQL has no views* + if ($self->{"useview"}) { + ($cols, $table, $where, $orderby, $limit) = $self->select_with_view; + } else { + ($cols, $table, $where, $orderby, $limit) = $self->select_without_view; + } + + # Fetch everything + $self->{"select"} = sprintf "SELECT %s FROM %s%s%s%s;\n", + $cols, $table, $where, $orderby, $limit; + $sql = $self->{"select"}; + $sth = $DBH->prepare($sql); + $sth->execute; + + $self->{"current"} = []; + push @{$self->{"current"}}, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + + # Find the carry-over records + if ($self->{"subj"} =~ /^[123]/) { + @_ = qw(); + push @_, "acctsubj.code AS code"; + push @_, "sum(CASE WHEN acctrecs.credit THEN -amount ELSE amount END) AS sum"; + $sql = "SELECT " . join(", ", @_) . " FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " LEFT JOIN accttrx ON acctrecs.trx=accttrx.sn" + . " WHERE acctsubj.code LIKE " . $DBH->strcat($DBH->quote($self->{"subj"}), "'%'") + . " AND accttrx.date<" . $DBH->quote($self->{"startdate"}) + . " GROUP BY acctsubj.code" + . " ORDER BY acctsubj.code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + for ($_ = 0, @_ = qw(); $_ < $sth->rows; $_++) { + push @_, {%{$sth->fetchrow_hashref}}; + } + undef $sth; + # Create the carry over transaction + @carryover = qw(); + foreach (@_) { + # Positive balance - from carry-over to account + if ($$_{"sum"} > 0) { + push @carryover, { + "_sel" => 0, + "_selurl" => undef, + "_subj" => $self->{"subj"}, + "_date" => $self->{"startdate"}, + "date" => $self->{"startdate"}, + "subj" => acctsubj_title(acctsubj_sn($$_{"code"})), + "summary" => C_("Brought forward"), + "debit" => $$_{"sum"}, + "credit" => 0, + "balance" => 0, + }; + # Negative balance - from account to carry-over + } elsif ($$_{"sum"} < 0) { + push @carryover, { + "_sel" => 0, + "_selurl" => undef, + "_subj" => $self->{"subj"}, + "_date" => $self->{"startdate"}, + "date" => $self->{"startdate"}, + "subj" => acctsubj_title(acctsubj_sn($$_{"code"})), + "summary" => C_("Brought forward"), + "debit" => 0, + "credit" => -$$_{"sum"}, + "balance" => 0, + }; + } + # Skip subjects with zero balances + } + $self->{"current"} = [@carryover, @{$self->{"current"}}]; + } + + # Calculate the balance + $balance = 0; + foreach (@{$self->{"current"}}) { + $balance = $balance + $$_{"debit"} - $$_{"credit"}; + $$_{"balance"} = $balance; + } + + # The number of rows per page + $_ = userpref("listsize", ref $self); + $self->{"pagesize"} = defined $_? $_: $self->{"DEFAULT_LIST_SIZE"}; + # Paging not in use + if (!defined $self->{"pagesize"}) { + $self->{"total"} = scalar(@{$self->{"current"}}); + $self->{"lastpage"} = 1; + $self->{"startno"} = 0; + $self->{"endno"} = $self->{"total"} - 1; + # If endno is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Done + return $self->{"error"}; + } + + # Obtain the total number + $self->{"total"} = scalar @{$self->{"current"}}; + $self->{"lastpage"} = floor(($self->{"total"} - 1) / $self->{"pagesize"}) + 1; + # If last page is 0 (when total is 0), set to page 1 + $self->{"lastpage"} = 1 if $self->{"lastpage"} < 1; + + # Check the page number + # Show the last page by default, but not reverse the number colume + $_ = $self->{"reverse"}; + $self->{"reverse"} = 1; + $error = $self->check_pageno; + $self->{"reverse"} = $_; + $self->{"error"} = $error if defined $error && !defined $self->{"error"}; + + # Calculate the start and end record number + $self->{"startno"} = ($self->{"pageno"} - 1) * $self->{"pagesize"}; + $self->{"endno"} = $self->{"pageno"} * $self->{"pagesize"} - 1; + # If there is not enough remaining records, set to the last one + $self->{"endno"} = $self->{"total"} - 1 + if $self->{"endno"} > $self->{"total"} - 1; + # If the last record is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Obtain everything in this page + $self->{"current"} = [ @{$self->{"current"}}[$self->{"startno"}...$self->{"endno"}] ] + if !$self->{"iscsv"}; + + # Set the columns to be displayed + $self->{"listcols"} = [qw(date subj summary debit credit balance)]; + # Done + return $self->{"error"}; +} + +# page_param: Obtain page parameters +sub page_param : method { + local ($_, %_); + my ($self, $rev, $r); + $self = $_[0]; + $rev = $self->{"reverse"}; + $self->{"reverse"} = 1; + # Run the parent method + $r = $self->SUPER::page_param; + $self->{"reverse"} = $rev; + return $r; +} + +# colval: Output a list column value +sub colval : method { + local ($_, %_); + my ($self, $col, %row); + ($self, $col, %row) = @_; + + # Null/no value + return h(t_notset()) if !defined $row{$col}; + + # The balance + if ($col eq "balance") { + return "" if $row{$col} eq ""; + if ($row{$col} > 0) { + return "
    " . h_abbr(C_("Debit")) . " " + . h_abbr(fmtntamount $row{$col}) . "
    "; + } elsif ($row{$col} < 0) { + return "
    " + . h_abbr(C_("Credit")) . " " + . h_abbr(fmtntamount -$row{$col}) . "
    "; + } else { + return "
    -
    "; + } + } + + # Run the parent method + return $self->SUPER::colval($col, %row); +} + +# pre_filter: Set the pre-defined filter +sub pre_filter : method { + local ($_, %_); + my $self; + $self = $_[0]; + @_ = qw(); + push @_, "_subj LIKE '" . $self->{"subj"} . "%'"; + push @_, $_ if defined($_ = $self->SUPER::pre_filter); + return undef if @_ == 0; + return join " AND ", @_; +} + +# html_select_subject: Display the subject search box +sub html_select_subject : method { + local ($_, %_); + my ($self, $label, @subjs); + my ($sql, $sth, $count, $row, $thiscol, $defcol); + $self = $_[0]; + + # The subject + $label = h_abbr(C_("Accounting subject:")); + # Obtain all the using subjects + $sql = "SELECT acctsubj.code FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " GROUP BY acctsubj.code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @_ = qw(); $i < $count; $i++) { + $row = $sth->fetchrow_hashref; + push @_, $$row{"code"}; + } + undef $sth; + %_ = map { $_ => 1 } @_; + # Add all of their parents + foreach (keys %_) { + $_{$_} = 1 while s/.$//; + } + delete $_{""}; + @_ = qw(); + push @_, "code AS value"; + if (@ALL_LINGUAS == 1) { + push @_, $DBH->strcat("code", "' '", "title") + . " AS content"; + } else { + $thiscol = "title_" . getlang LN_DATABASE; + if (getlang eq $DEFAULT_LANG) { + push @_, $DBH->strcat("code", "' '", $thiscol) + . " AS content"; + } else { + $defcol = "title_" . ln($DEFAULT_LANG, LN_DATABASE); + push @_, $DBH->strcat("code", "' '", "COALESCE($thiscol, $defcol)") + . " AS content"; + } + } + $sql = "SELECT " . join(", ", @_) . " FROM acctsubj" + . " WHERE " . join(" OR ", map "code=" . $DBH->quote($_), sort keys %_) + . " ORDER BY code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @subjs = qw(); $i < $count; $i++) { + push @subjs, {%{$sth->fetchrow_hashref}}; + } + undef $sth; + + # Display the form + print << "EOT"; +

    $label + +

    + +EOT + return; +} + +# html_data_download: Display the data download link +sub html_data_download : method { + local ($_, %_); + my ($self, $url, $title); + $self = $_[0]; + # No data + return if $self->{"total"} == 0; + # Construct the URL + @_ = qw(); + push @_, "list=ldgr"; + push @_, "subj=" . uri_escape($self->{"subj"}); + push @_, $self->{"actrange"}; + push @_, "format=csv"; + $url = $REQUEST_FILE . "?" . join "&", @_; + $title = h_abbr(C_("Download the data as a CSV file.")); + print << "EOT"; +

    $title

    + +EOT + return; +} + +# html_csv: Return the data as CSV +sub html_csv : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Output a header to suggest for download instead of display + $HTTP_HEADERS{"Content-Disposition"} = + "attachment; filename=ledger.csv"; + $CONTENT_TYPE = "text/csv; charset=" . getlang LN_CHARSET; + # The header column + @_ = map((exists ${$self->{"col_labels"}}{$_}? ${$self->{"col_labels"}}{$_}: $_), + @{$self->{"listcols"}}); + s/"/""/g foreach @_; # " + print join(",", map "\"$_\"", @_) . "\n"; + # The data + foreach my $current (@{$self->{"current"}}) { + @_ = map $$current{$_}, @{$self->{"listcols"}}; + foreach (@_) { + $_ = "" if !defined $_; + s/"/""/g; # " + } + print join(",", map "\"$_\"", @_) . "\n"; + } + return; +} + +# html_pagebar: Display a page navigation bar +sub html_pagebar : method { + local ($_, %_); + my ($self, $rev, $r); + $self = $_[0]; + $rev = $self->{"reverse"}; + $self->{"reverse"} = 1; + # Run the parent method + $r = $self->SUPER::html_pagebar; + $self->{"reverse"} = $rev; + return $r; +} + +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm b/lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm new file mode 100644 index 0000000..e77b00f --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm @@ -0,0 +1,422 @@ +# Selima Website Content Management System +# Summary.pm: The summary ledger accounting report. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-30 + +package Selima::List::Accounting::Reports::Ledger::Summary; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Accounting::Reports); + +use POSIX qw(floor); +use Text::Capitalize qw(capitalize_title); +use URI::Escape qw(uri_escape); + +use Selima::Accounting; +use Selima::CommText; +use Selima::DataVars qw($DBH :env :l10n :lninfo :output :requri); +use Selima::Format; +use Selima::GetLang; +use Selima::LnInfo; +use Selima::MarkAbbr; +use Selima::ShortCut; +use Selima::UserPref; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class, @cols, $sql); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The list type + $self->{"type"} = "ldgrsum"; + # The subject + $self->{"subj"} = $self->{"FORM"}->param("subj"); + $self->{"subj"} = ACCTSUBJ_CASH if !defined $self->{"subj"}; + # The page title + $_ = acctsubj_title(acctsubj_sn($self->{"subj"})); + s/^\d+ //; + $self->{"title"} = capitalize_title(C_("Ledger Summary - [_1]", $_)); + $self->{"title"} =~ s/ - /\x{2014}/; + + # Construct the view + $self->{"view"} = "acctrep_ledger_summary_list"; + $self->{"noselect"} = 1; + @_ = qw(); + push @_, "list=ldgr"; + push @_, "subj=" . uri_escape($self->{"subj"}); + push @_, "r=m"; + push @_, "m="; + $_ = $REQUEST_FILE . "?" . join "&", @_; + + @cols = qw(); + push @cols, $DBH->strcat($DBH->quote($_), + "lpad(cast(extract(year FROM date) AS text), 4, '0')", + "'-'", "lpad(cast(extract(month FROM date) AS text), 2, '0')") . " AS _viewurl"; + push @cols, $DBH->strcat("lpad(cast(extract(year FROM date) AS text), 4, '0')", + "'-'", "lpad(cast(extract(month FROM date) AS text), 2, '0')") . " AS month"; + push @cols, "acctsum_debit(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer)," + . " " . $DBH->quote($self->{"subj"}) . ") AS debit"; + push @cols, "acctsum_credit(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), " + . " " . $DBH->quote($self->{"subj"}) . ") AS credit"; + push @cols, "acctsum_balance(cast(extract(year FROM date) AS integer)," + . " cast(extract(month FROM date) AS integer), " + . " " . $DBH->quote($self->{"subj"}) . ") AS balance"; + $sql = "CREATE TEMPORARY VIEW " . $self->{"view"} . " AS" + . " SELECT " . join(", ", @cols) + . " FROM accttrx" + . " GROUP BY extract(year FROM date), extract(month FROM date)" + . " ORDER BY extract(year FROM date), extract(month FROM date);\n"; + $DBH->do($sql); + + # Column labels + $self->col_labels( + ); + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, $cols, $table, $where, $orderby, $limit, $sth, $sql, $error); + my ($sumdebit, $sumcredit); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + $self->{"total"} = undef; + + # No need to run if there is no data at all + if (exists $self->{"nodata"} && $self->{"nodata"}) { + $self->{"total"} = 0; + return; + } + + # See if we need to use views or not. + # Views make things much faster and easier, but some DBMS has no views. + # *MySQL has no views* + if ($self->{"useview"}) { + ($cols, $table, $where, $orderby, $limit) = $self->select_with_view; + } else { + ($cols, $table, $where, $orderby, $limit) = $self->select_without_view; + } + + # Fetch everything + $self->{"select"} = sprintf "SELECT %s FROM %s%s%s%s;\n", + $cols, $table, $where, $orderby, $limit; + $sql = $self->{"select"}; + $sth = $DBH->prepare($sql); + $sth->execute; + + $self->{"current"} = []; + push @{$self->{"current"}}, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + + # Do calculation on each record + ($sumdebit, $sumcredit) = (0, 0); + foreach (@{$self->{"current"}}) { + $$_{"balance"} = 0 if !defined $$_{"balance"}; + $sumdebit += $$_{"debit"}; + $sumcredit += $$_{"credit"}; + } + # Remove the starting and ending empty records + @_ = @{$self->{"current"}}; + shift @_ while @_ > 0 && ${$_[0]}{"credit"} == 0 && ${$_[0]}{"debit"} == 0; + pop @_ while @_ > 0 && ${$_[$#_]}{"credit"} == 0 && ${$_[$#_]}{"debit"} == 0; + $self->{"current"} = [@_]; + # Append the total record + if (@{$self->{"current"}} > 0) { + @_ = qw(); + push @_, "list=ldgr"; + push @_, "subj=" . uri_escape($self->{"subj"}); + push @_, "r=a"; + push @{$self->{"current"}}, { + "_viewurl" => $REQUEST_FILE . "?" . join("&", @_), + "month" => C_("Total"), + "debit" => $sumdebit, + "credit" => $sumcredit, + "balance" => ${(reverse @{$self->{"current"}})[0]}{"balance"}, + }; + } + + # The number of rows per page + $_ = userpref("listsize", ref $self); + $self->{"pagesize"} = defined $_? $_: $self->{"DEFAULT_LIST_SIZE"}; + # Paging not in use + if (!defined $self->{"pagesize"}) { + $self->{"total"} = scalar(@{$self->{"current"}}); + $self->{"lastpage"} = 1; + $self->{"startno"} = 0; + $self->{"endno"} = $self->{"total"} - 1; + # If endno is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Done + return $self->{"error"}; + } + + # Obtain the total number + $self->{"total"} = scalar @{$self->{"current"}}; + $self->{"lastpage"} = floor(($self->{"total"} - 1) / $self->{"pagesize"}) + 1; + # If last page is 0 (when total is 0), set to page 1 + $self->{"lastpage"} = 1 if $self->{"lastpage"} < 1; + + # Check the page number + # Show the last page by default, but not reverse the number colume + $_ = $self->{"reverse"}; + $self->{"reverse"} = 1; + $error = $self->check_pageno; + $self->{"reverse"} = $_; + $self->{"error"} = $error if defined $error && !defined $self->{"error"}; + + # Calculate the start and end record number + $self->{"startno"} = ($self->{"pageno"} - 1) * $self->{"pagesize"}; + $self->{"endno"} = $self->{"pageno"} * $self->{"pagesize"} - 1; + # If there is not enough remaining records, set to the last one + $self->{"endno"} = $self->{"total"} - 1 + if $self->{"endno"} > $self->{"total"} - 1; + # If the last record is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Obtain everything in this page + $self->{"current"} = [ @{$self->{"current"}}[$self->{"startno"}...$self->{"endno"}] ] + if !$self->{"iscsv"}; + + # Set the columns to be displayed + $self->{"cols"} = [qw(_viewurl month debit credit balance)]; + $self->{"listcols"} = [qw(month debit credit balance)]; + # Done + return $self->{"error"}; +} + +# page_param: Obtain page parameters +sub page_param : method { + local ($_, %_); + my ($self, $rev, $r); + $self = $_[0]; + $rev = $self->{"reverse"}; + $self->{"reverse"} = 1; + # Run the parent method + $r = $self->SUPER::page_param; + $self->{"reverse"} = $rev; + return $r; +} + +# colval: Output a list column value +sub colval : method { + local ($_, %_); + my ($self, $col, %row); + ($self, $col, %row) = @_; + + # Null/no value + return h(t_notset()) if !defined $row{$col}; + + # The balance + if ($col eq "balance") { + if ($row{$col} > 0) { + return "
    " . h_abbr(C_("Debit")) . " " + . h_abbr(fmtntamount $row{$col}) . "
    "; + } elsif ($row{$col} < 0) { + return "
    " + . h_abbr(C_("Credit")) . " " + . h_abbr(fmtntamount -$row{$col}) . "
    "; + } else { + return "
    -
    "; + } + } + + # Run the parent method + return $self->SUPER::colval($col, %row); +} + +# pre_filter: Set the pre-defined filter +# Make it a null function +sub pre_filter : method { } + +# html_report_query: Display the report query box +sub html_report_query : method { + local ($_, %_); + my ($self, $form, $request_file, $label, $curlist); + $self = $_[0]; + $form = $self->{"FORM"}; + + $request_file = h($REQUEST_FILE); + $label = h_abbr(C_("Query")); + + $curlist = h($self->{"type"}); + print << "EOT"; +
    +
    +
    + +EOT + # Display the subject selection if available + $self->html_select_subject if $self->can("html_select_subject"); + + print << "EOT"; +

    +

    +
    +
    + +EOT + return; +} + +# html_select_subject: Display the subject search box +sub html_select_subject : method { + local ($_, %_); + my ($self, $label, @subjs); + my ($sql, $sth, $count, $row, $thiscol, $defcol); + $self = $_[0]; + + # The subject + $label = h_abbr(C_("Accounting subject:")); + # Obtain all the using subjects + $sql = "SELECT acctsubj.code FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " GROUP BY acctsubj.code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @_ = qw(); $i < $count; $i++) { + $row = $sth->fetchrow_hashref; + push @_, $$row{"code"}; + } + undef $sth; + %_ = map { $_ => 1 } @_; + # Add all of their parents + foreach (keys %_) { + $_{$_} = 1 while s/.$//; + } + delete $_{""}; + @_ = qw(); + push @_, "code AS value"; + if (@ALL_LINGUAS == 1) { + push @_, $DBH->strcat("code", "' '", "title") + . " AS content"; + } else { + $thiscol = "title_" . getlang LN_DATABASE; + if (getlang eq $DEFAULT_LANG) { + push @_, $DBH->strcat("code", "' '", $thiscol) + . " AS content"; + } else { + $defcol = "title_" . ln($DEFAULT_LANG, LN_DATABASE); + push @_, $DBH->strcat("code", "' '", "COALESCE($thiscol, $defcol)") + . " AS content"; + } + } + $sql = "SELECT " . join(", ", @_) . " FROM acctsubj" + . " WHERE " . join(" OR ", map "code=" . $DBH->quote($_), sort keys %_) + . " ORDER BY code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for (my $i = 0, @subjs = qw(); $i < $count; $i++) { + push @subjs, {%{$sth->fetchrow_hashref}}; + } + undef $sth; + + # Display the form + print << "EOT"; +

    $label + +

    + +EOT + return; +} + +# html_data_download: Display the data download link +sub html_data_download : method { + local ($_, %_); + my ($self, $url, $title); + $self = $_[0]; + # No data + return if $self->{"total"} == 0; + # Construct the URL + @_ = qw(); + push @_, "list=ldgrsum"; + push @_, "subj=" . uri_escape($self->{"subj"}); + push @_, "format=csv"; + $url = $REQUEST_FILE . "?" . join "&", @_; + $title = h_abbr(C_("Download the data as a CSV file.")); + print << "EOT"; +

    $title

    + +EOT + return; +} + +# html_csv: Return the data as CSV +sub html_csv : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Output a header to suggest for download instead of display + $HTTP_HEADERS{"Content-Disposition"} = + "attachment; filename=ledger_summary.csv"; + $CONTENT_TYPE = "text/csv; charset=" . getlang LN_CHARSET; + # The header column + @_ = map((exists ${$self->{"col_labels"}}{$_}? ${$self->{"col_labels"}}{$_}: $_), + @{$self->{"listcols"}}); + s/"/""/g foreach @_; # " + print join(",", map "\"$_\"", @_) . "\n"; + # The data + foreach my $current (@{$self->{"current"}}) { + print join(",", map $$current{$_}, @{$self->{"listcols"}}) . "\n"; + } + return; +} + +# html_pagebar: Display a page navigation bar +sub html_pagebar : method { + local ($_, %_); + my ($self, $rev, $r); + $self = $_[0]; + $rev = $self->{"reverse"}; + $self->{"reverse"} = 1; + # Run the parent method + $r = $self->SUPER::html_pagebar; + $self->{"reverse"} = $rev; + return $r; +} + +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Reports/Search.pm b/lib/perl5/Selima/List/Accounting/Reports/Search.pm new file mode 100644 index 0000000..033bbdf --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Reports/Search.pm @@ -0,0 +1,120 @@ +# Selima Website Content Management System +# Search.pm: The accounting data search result list. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-29 + +package Selima::List::Accounting::Reports::Search; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Accounting::Reports); + +use Selima::DataVars qw(:l10n :lninfo); +use Selima::GetLang; +use Selima::Logging; +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The page title + if (!defined $self->{"query"}) { + $self->{"title"} = C_("Search the Accounting Records"); + } else { + $self->{"title"} = C_("Search Result"); + } + if (@ALL_LINGUAS == 1) { + $self->{"view"} = "acctrep_search_list"; + } else { + $self->{"view"} = "acctrep_search_list_" . getlang(LN_DATABASE); + } + # Column labels + $self->col_labels( + "trxno" => C_("Transaction Number"), + "note" => C_("Note"), + ); + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my $self; + $self = $_[0]; + # No search specified + if (!defined $self->{"query"}) { + $self->{"total"} = undef; + return $self->{"error"}; + } + # Check the query phrase + # Regularize it + $self->{"query"} =~ s/^\s*(.*?)\s*$/$1/; + # Check if it is filled + if ($self->{"query"} eq"") { + $self->{"total"} = undef; + $self->{"error"} = {"msg"=>N_("Please fill in your query.")}; + return $self->{"error"}; + } + # Run the parent method + $self->SUPER::fetch; + # Set the columns to be displayed + $self->{"listcols"} = [qw(date trxno subj summary debit credit note)]; + # Done + return $self->{"error"}; +} + +# check_pageno: Check the page number +# Default to the last page +sub check_pageno : method { + local ($_, %_); + my ($self, $rev); + $self = $_[0]; + $rev = $self->{"reverse"}; + $self->{"reverse"} = 1; + # Run the parent method + $self->SUPER::check_pageno; + $self->{"reverse"} = $rev; + return; +} + +# pre_filter: Set the pre-defined filter +# Make it a null function +sub pre_filter : method { } + +# html_report_query: Display the report query box +# Make it a null function +sub html_report_query : method { } + +# html_pagebar: Display a page navigation bar +# The first page needs a page number, because default to the last page +sub html_pagebar : method { + local ($_, %_); + my ($self, $rev, $r); + $self = $_[0]; + $rev = $self->{"reverse"}; + $self->{"reverse"} = 1; + # Run the parent method + $r = $self->SUPER::html_pagebar; + $self->{"reverse"} = $rev; + return $r; +} + +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm b/lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm new file mode 100644 index 0000000..4782c18 --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm @@ -0,0 +1,268 @@ +# Selima Website Content Management System +# TriBlnc.pm: The trial balance accounting report. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-29 + +package Selima::List::Accounting::Reports::TriBlnc; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Accounting::Reports); + +use Selima::Accounting; +use Selima::CommText; +use Selima::DataVars qw($DBH :l10n :lninfo :output :requri); +use Selima::GetLang; +use Selima::LnInfo; +use Selima::MarkAbbr; +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = C_("Trial Balance"); + # The list type + $self->{"type"} = "tb"; + # The default number of rows per page + $self->{"DEFAULT_LIST_SIZE"} = undef; + $self->{"noselect"} = 1; + + # Column labels + $self->col_labels( + ); + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, @cols, $title, $sth, $sql, $error); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + $self->{"total"} = undef; + + # Construct the SQL query statement + # Obtain the period once + $self->sql_filter; + @cols = qw(); + if (@ALL_LINGUAS == 1) { + $title = "acctsubj.title"; + } else { + my ($lndb, $lndbdef); + $lndb = getlang LN_DATABASE; + if (getlang eq $DEFAULT_LANG) { + $title = "acctsubj.title_$lndb"; + } else { + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + $title = "COALESCE(acctsubj.title_$lndb, acctsubj.title_$lndbdef)"; + } + } + push @cols, "acctsubj.code AS code"; + push @cols, $DBH->strcat("acctsubj.code", "' '", $title) . " AS subj"; + push @cols, "sum(CASE WHEN acctrecs.credit THEN -acctrecs.amount ELSE acctrecs.amount END)" + . " AS balance"; + $self->{"current"} = []; + + # The real accounts + $sql = "SELECT " . join(", ", @cols) + . " FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " LEFT JOIN accttrx ON acctrecs.trx=accttrx.sn" + . " WHERE date<=" . $DBH->quote($self->{"enddate"}) + . " AND (acctsubj.code LIKE '1%'" + . " OR acctsubj.code LIKE '2%'" + . " OR acctsubj.code LIKE '3%')" + . " GROUP BY acctsubj.code, $title" + . " ORDER BY acctsubj.code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + push @{$self->{"current"}}, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + + # The nominal accounts + $sql = "SELECT " . join(", ", @cols) + . " FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " LEFT JOIN accttrx ON acctrecs.trx=accttrx.sn" + . " WHERE date>=" . $DBH->quote($self->{"startdate"}) + . " AND date<=" . $DBH->quote($self->{"enddate"}) + . " AND NOT (acctsubj.code LIKE '1%'" + . " OR acctsubj.code LIKE '2%'" + . " OR acctsubj.code LIKE '3%')" + . " GROUP BY acctsubj.code, $title" + . " ORDER BY acctsubj.code;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + push @{$self->{"current"}}, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + + # Obtain the carry-over record of assets/liabilities + $_ = "sum(CASE WHEN acctrecs.credit THEN -acctrecs.amount ELSE acctrecs.amount END)" + . " AS balance"; + $sql = "SELECT $_ FROM acctrecs" + . " LEFT JOIN acctsubj ON acctrecs.subj=acctsubj.sn" + . " LEFT JOIN accttrx ON acctrecs.trx=accttrx.sn" + . " WHERE (acctsubj.code LIKE '1%'" + . " OR acctsubj.code LIKE '2%'" + . " OR acctsubj.code LIKE '3%')" + . " AND accttrx.date<" . $DBH->quote($self->{"startdate"}) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $_ = $sth->fetchrow_hashref; + undef $sth; + if (defined $$_{"balance"}) { + push @{$self->{"current"}}, { + "subj" => acctsubj_title(acctsubj_sn(ACCTSUBJ_INCOME_ACUM)), + "balance" => -$$_{"balance"}, + }; + } + + # Sort by the subject + $self->{"current"} = [ sort { $$a{"subj"} cmp $$b{"subj"} } @{$self->{"current"}} ]; + + # Set the debit and credit amount + if (@{$self->{"current"}} > 0) { + my ($sumdebit, $sumcredit, $viewurl); + ($sumdebit, $sumcredit) = (0, 0); + @_ = qw(); + push @_, "list=ldgr"; + push @_, "subj=%s"; + push @_, $self->{"actrange"}; + $viewurl = $REQUEST_FILE . "?" . join "&", @_; + foreach (@{$self->{"current"}}) { + $$_{"_viewurl"} = sprintf $viewurl, $$_{"code"}; + delete $$_{"code"}; + if ($$_{"balance"} > 0) { + $$_{"debit"} = $$_{"balance"}; + $$_{"credit"} = 0; + $sumdebit += $$_{"debit"}; + } elsif ($$_{"balance"} < 0) { + $$_{"debit"} = 0; + $$_{"credit"} = -$$_{"balance"}; + $sumcredit += $$_{"credit"}; + } else { + $$_{"debit"} = 0; + $$_{"credit"} = 0; + } + delete $_{"balance"}; + } + # Append the total record + if (@{$self->{"current"}} > 0) { + push @{$self->{"current"}}, { + "_viewurl" => undef, + "subj" => C_("Total"), + "debit" => $sumdebit, + "credit" => $sumcredit, + }; + } + } + + # The number of rows per page + $self->{"pagesize"} = $self->{"DEFAULT_LIST_SIZE"}; + # Paging not in use + $self->{"total"} = scalar(@{$self->{"current"}}); + $self->{"lastpage"} = 1; + $self->{"startno"} = 0; + $self->{"endno"} = $self->{"total"} - 1; + # If endno is -1 (when total is 0), set to 0 + $self->{"endno"} = 0 if $self->{"endno"} < 0; + + # Set the columns to be displayed + $self->{"cols"} = [qw(_viewurl subj debit credit)]; + $self->{"listcols"} = [qw(subj debit credit)]; + + # Done + return $self->{"error"}; +} + +# html_data_download: Display the data download link +sub html_data_download : method { + local ($_, %_); + my ($self, $url, $title); + $self = $_[0]; + # No data + return if $self->{"total"} == 0; + # Construct the URL + @_ = qw(); + push @_, "list=tb"; + push @_, $self->{"actrange"}; + push @_, "format=csv"; + $url = $REQUEST_FILE . "?" . join "&", @_; + $title = h_abbr(C_("Download the data as a CSV file.")); + print << "EOT"; +

    $title

    + +EOT + return; +} + +# html_csv: Return the data as CSV +sub html_csv : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Output a header to suggest for download instead of display + $HTTP_HEADERS{"Content-Disposition"} = + "attachment; filename=trial_balance.csv"; + $CONTENT_TYPE = "text/csv; charset=" . getlang LN_CHARSET; + # The header column + @_ = map((exists ${$self->{"col_labels"}}{$_}? ${$self->{"col_labels"}}{$_}: $_), + @{$self->{"listcols"}}); + s/"/""/g foreach @_; # " + print join(",", map "\"$_\"", @_) . "\n"; + # The data + foreach my $current (@{$self->{"current"}}) { + @_ = map $$current{$_}, @{$self->{"listcols"}}; + foreach (@_) { + $_ = "" if !defined $_; + s/"/""/g; # " + } + print join(",", map "\"$_\"", @_) . "\n"; + } + return; +} + +# html_listprefform: Display a form to change the list preference +# Make it a null function +sub html_listprefform : method {} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my ($self, $total); + $self = $_[0]; + + $total = $self->{"total"}; + # Inherit the empty list statistics message + return $self->SUPER::liststat_message if $self->{"total"} == 0; + return C_("[*,_1,accounting subject].", $self->{"total"} - 1); +} + +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Subjects.pm b/lib/perl5/Selima/List/Accounting/Subjects.pm new file mode 100644 index 0000000..d7a39af --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Subjects.pm @@ -0,0 +1,95 @@ +# Selima Website Content Management System +# Subjects.pm: The accounting subject list. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-08-23 + +package Selima::List::Accounting::Subjects; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "acctsubj" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + C_("Select an Accounting Subject"): + C_("Manage Accounting Subjects"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "code"; + # Column labels + $self->col_labels( + "parent" => C_("Parent subject"), + "code" => C_("Code"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(C_("Add a new accounting subject.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for an accounting subject:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,accounting subject].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,accounting subject].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,accounting subject], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,accounting subject], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Subjects/LastLv.pm b/lib/perl5/Selima/List/Accounting/Subjects/LastLv.pm new file mode 100644 index 0000000..03fb9ad --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Subjects/LastLv.pm @@ -0,0 +1,45 @@ +# Selima Website Content Management System +# LastLv.pm: The last-level accounting subject list. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-22 + +package Selima::List::Accounting::Subjects::LastLv; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Accounting::Subjects); + +use Selima::DataVars qw(:l10n :lninfo); +use Selima::GetLang; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "acctsubj" if !defined $_[1]; + $self = $class->SUPER::new(@_); + if (@ALL_LINGUAS == 1) { + $self->{"view"} = "acctsubj_lastlv_list"; + } else { + $self->{"view"} = "acctsubj_lastlv_list_" . getlang LN_DATABASE; + } + return $self; +} + +return 1; diff --git a/lib/perl5/Selima/List/Accounting/Transacts.pm b/lib/perl5/Selima/List/Accounting/Transacts.pm new file mode 100644 index 0000000..5945f5e --- /dev/null +++ b/lib/perl5/Selima/List/Accounting/Transacts.pm @@ -0,0 +1,116 @@ +# Selima Website Content Management System +# Transacts.pm: The accounting transaction list. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-08-23 + +package Selima::List::Accounting::Transacts; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::AddGet; +use Selima::DataVars qw(:requri); +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "accttrx" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + C_("Select an Accounting Transaction"): + C_("Manage Accounting Transactions"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "-date,-ord"; + # Column labels + $self->col_labels( + "num" => C_("Number"), + "note" => C_("Note"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + local ($_, %_); + my ($self, $urle, $urli, $urlt, $prompt); + $self = $_[0]; + + # No new item creation if it is a called form + return if $self->{"is_called_form"}; + $_ = $REQUEST_FILEQS; + # Remove list parameters + $_ = rem_get_arg $_, "query", "sortby", "pageno", "form", "formcat", "formid", "statid"; + $_ = add_get_arg $_, "form", "new", DUP_OK; + $urle = add_get_arg $_, "formsub", "expense", DUP_OK; + $urli = add_get_arg $_, "formsub", "income", DUP_OK; + $urlt = add_get_arg $_, "formsub", "trans", DUP_OK; + $prompt = C_("Add a new cash expense transaction, add a new cash income transaction or add a new transfer transaction.", + h($urle), h($urli), h($urlt)); + + print << "EOT"; +

    $prompt

    + +EOT + return; +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for an accounting transaction:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,accounting transaction].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,accounting transaction].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,accounting transaction], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,accounting transaction], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/List/ActLog.pm b/lib/perl5/Selima/List/ActLog.pm new file mode 100644 index 0000000..bbe0742 --- /dev/null +++ b/lib/perl5/Selima/List/ActLog.pm @@ -0,0 +1,256 @@ +# Selima Website Content Management System +# ActLog.pm: The activity log record list. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-05-10 + +package Selima::List::ActLog; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Encode qw(decode); +use Fcntl qw(:flock); + +use Selima::A2HTML; +use Selima::DataVars qw(:lninfo :requri); +use Selima::GetLang; +use Selima::Logging; +use Selima::HTTP; +use Selima::Query; +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = C_("Browse the Activity Log"); + $self->{"rows"} = defined $self->{"FORM"}->param("rows")? + $self->{"FORM"}->param("rows"): undef; + $self->{"rdgt"} = 4; + $self->{"reverse"} = 1; + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, $error, $FH); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + $self->{"total"} = undef; + + # Check the query phrases + $self->check_query; + # Check the number of rows to display + $error = $self->check_pagesize; + if (defined $error) { + $self->{"error"} = $error if !defined $self->{"error"}; + $self->{"pagesize"} = $self->{"DEFAULT_LIST_SIZE"}; + } elsif (!defined $self->{"rows"}) { + $self->{"pagesize"} = $self->{"DEFAULT_LIST_SIZE"}; + } else { + $self->{"pagesize"} = $self->{"rows"}; + } + + check_actlog_file; + open $FH, $ACTLOG or http_500 "$ACTLOG: $!"; + flock $FH, LOCK_SH or http_500 "$ACTLOG: $!"; + # Obtain all the log entries + if (@{$self->{"query_phrases"}} == 0) { + $self->{"current"} = [map decode("UTF-8", $_), <$FH>]; + # Obtain all the matched log entries + } else { + $self->{"current"} = []; + while (defined($_ = <$FH>)) { + my $matched; + $_ = decode("UTF-8", $_); + $matched = 1; + foreach my $phrase (@{$self->{"query_phrases"}}) { + next if /\Q$phrase\E/i; + $matched = 0; + last; + } + push @{$self->{"current"}}, $_ if $matched; + } + } + flock $FH, LOCK_UN or http_500 "$ACTLOG: $!"; + close $FH or http_500 "$ACTLOG: $!"; + $self->{"total"} = scalar @{$self->{"current"}}; + + $self->{"endno"} = $self->{"total"} - 1; + $self->{"startno"} = 1; + if ($self->{"total"} > $self->{"pagesize"}) { + $self->{"startno"} = $self->{"endno"} - $self->{"pagesize"} + 1; + $self->{"current"} = [@{$self->{"current"}}[$self->{"startno"}...$self->{"endno"}]]; + } + + $self->{"current"} = [reverse @{$self->{"current"}}]; + + # Done + return $self->{"error"}; +} + +# check_query: Check the query phrases +sub check_query : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No query, return + return if !defined $self->{"query"}; + + # Regularize it + $self->{"query"} =~ s/^\s*(.*?)\s*$/$1/; + # Check if it is filled + return if $self->{"query"} eq ""; + + $self->{"query_phrases"} = [parse_query $self->{"query"}]; + return; +} + +# check_pagesize: Check the number of rows to display +sub check_pagesize : method { + local ($_, %_); + my ($self, $error, $errmsg); + $self = $_[0]; + # No rows, return + return if !defined $self->{"rows"}; + # Regularize it + $self->{"rows"} =~ s/^\s*(.*?)\s*$/$1/; + # Check if it is filled + return {"msg"=>N_("Please fill in the number of rows to display.")} + if $self->{"rows"} eq ""; + # If there is any non-digit character + return {"msg"=>N_("Please fill in a positive integer number of rows to display.")} + unless $self->{"rows"} =~ /^[1-9][0-9]*$/; + # Set to an integer + $self->{"rows"} += 0; + # Check the length + return {"msg"=>N_("This number of rows to display is too long. (Max. length [#,_1])"), + "margs"=>[$self->{"rdgt"}]} + if length $self->{"rows"} > $self->{"rdgt"}; + # OK + return; +} + +# html_newlink: Display a link to add a new item +# Make it a null function +sub html_newlink : method {} + +# html_search: Display the search box +sub html_search : method { + local ($_, %_); + my ($self, $prompt, $label, $query, $request_file); + my ($prompt2, $rows, $size); + ($self, $prompt) = @_; + $prompt = C_("Search for log entries:") if !defined $prompt; + $prompt = h($prompt); + + $request_file = h($REQUEST_FILE); + $query = defined $self->{"query"}? h($self->{"query"}): ""; + $label = h(C_("Display")); + $prompt2 = h(C_("Display rows:")); + $rows = defined $self->{"rows"}? h($self->{"rows"}): + h($self->{"DEFAULT_LIST_SIZE"}); + $size = h($self->{"rdgt"}); + + print << "EOT"; +
    + +
    + +EOT + return; +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,log entry,log entries].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,log entry,log entries].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,log entry,log entries], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +# html_pagebar: Display a page navigation bar +# Make it a null function +sub html_pagebar : method {} + +# html_list: List the items +sub html_list : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Do not show the list + return if !defined $self->{"total"}; + # No record to be listed + return if $self->{"total"} == 0; + + $_ = a2html(join "", @{$self->{"current"}}); + s/([\x00-\x08\x0B\x0C\x0E-\x1F])/sprintf("\\x%02x", ord($1));/ge; + print << "EOT"; +
    +$_ +
    + +EOT + return; +} + +return 1; diff --git a/lib/perl5/Selima/List/Category.pm b/lib/perl5/Selima/List/Category.pm new file mode 100644 index 0000000..d475bbb --- /dev/null +++ b/lib/perl5/Selima/List/Category.pm @@ -0,0 +1,74 @@ +# Selima Website Content Management System +# Category.pm: The base category list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-21 + +package Selima::List::Category; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(C_("Add a new category.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for a category:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,category,categories].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,category,categories].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,category,categories], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,category,categories], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/List/Categorz.pm b/lib/perl5/Selima/List/Categorz.pm new file mode 100644 index 0000000..3f14986 --- /dev/null +++ b/lib/perl5/Selima/List/Categorz.pm @@ -0,0 +1,74 @@ +# Selima Website Content Management System +# Categorz.pm: The base category membership list. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-21 + +package Selima::List::Categorz; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(C_("Add a new categorization record.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for a categorization record:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,categorization record].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,categorization record].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,categorization record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,categorization record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/List/GroupMem.pm b/lib/perl5/Selima/List/GroupMem.pm new file mode 100644 index 0000000..574d3ff --- /dev/null +++ b/lib/perl5/Selima/List/GroupMem.pm @@ -0,0 +1,95 @@ +# Selima Website Content Management System +# GroupMem.pm: The group-to-group membership list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +package Selima::List::GroupMem; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "groupmem" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + C_("Select a Group Membership Record"): + C_("Manage Group Membership"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "grp,member"; + # Column labels + $self->col_labels( + "grp" => C_("Group"), + "member" => C_("Member"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(C_("Add a new membership record.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for a membership record:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,membership record].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,membership record].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,membership record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,membership record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/List/Groups.pm b/lib/perl5/Selima/List/Groups.pm new file mode 100644 index 0000000..96d5f6a --- /dev/null +++ b/lib/perl5/Selima/List/Groups.pm @@ -0,0 +1,94 @@ +# Selima Website Content Management System +# Groups.pm: The account group list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-12 + +package Selima::List::Groups; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "groups" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? C_("Select a Group"): + C_("Manage Groups"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "id"; + # Column labels + $self->col_labels( + "id" => C_("Group ID."), + "dsc" => C_("Description"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(C_("Add a new group.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for a group:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,group].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,group].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,group], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,group], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/List/Guestbook.pm b/lib/perl5/Selima/List/Guestbook.pm new file mode 100644 index 0000000..8145193 --- /dev/null +++ b/lib/perl5/Selima/List/Guestbook.pm @@ -0,0 +1,110 @@ +# Selima Website Content Management System +# Guestbook.pm: The base administrative guestbook message list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +package Selima::List::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::AddGet; +use Selima::DataVars qw(:requri); +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "guestbook" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + C_("Select a Message"): + C_("Manage Guestbook"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "created"; + # Columns that should display its brief instead + push @{$self->{"COLS_BRIEF"}}, qw(message); + # Columns should be displayed in a reversed order + $self->{"reverse"} = 1; + # The list brief size + $self->{"DEFAULT_BRIEF_LEN"} = 20; + # Column labels + $self->col_labels( + "name" => C_("Signature"), + "identity" => C_("Identity"), + "location" => C_("Location"), + "message" => C_("Message"), + "ip" => C_("IP"), + "host" => C_("Host"), + "ct" => C_("Country"), + "pageno" => C_("Page No."), + "oldpageno" => C_("Old page No."), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(C_("Write a new message.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for a message:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,message].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,message].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,message], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,message], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/List/Guestbook/Public.pm b/lib/perl5/Selima/List/Guestbook/Public.pm new file mode 100644 index 0000000..0f2cfc3 --- /dev/null +++ b/lib/perl5/Selima/List/Guestbook/Public.pm @@ -0,0 +1,226 @@ +# Selima Website Content Management System +# Public.pm: The base guestbook message list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-23 + +package Selima::List::Guestbook::Public; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use IO::NestedCapture qw(CAPTURE_STDOUT); + +use Selima::A2HTML; +use Selima::DataVars qw($DBH :requri); +use Selima::Format; +use Selima::GetLang; +use Selima::MungAddr; +use Selima::ShortCut; +use Selima::Unicode; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "guestbook" if !defined $_[1]; + $self = $class->SUPER::new(@_); + $self->{"view"} = "guestbook_public"; + # Entries should be displayed in a reversed order + $self->{"reverse"} = 1; + # Magical Traditional/Simplified Chinese conversion + $self->{"magic_zhconv"} = 0; + return $self; +} + +# fetch: Fetch the current list +sub fetch : method { + local ($_, %_); + my ($self, $table, $sth, $sql, $error); + $self = $_[0]; + + # Fetched before + return $self->{"error"} if $self->{"fetched"}; + $self->{"fetched"} = 1; + + # Initialize the error status + $self->{"error"} = undef; + + # The view name + $table = $DBH->quote_identifier($self->{"view"}); + + # Find the last page number + $sql = "SELECT pageno FROM $table ORDER BY pageno DESC LIMIT 1;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + # No records yet + if ($sth->rows != 1) { + $self->{"lastpage"} = 1; + } else { + $self->{"lastpage"} = ${$sth->fetch}[0]; + } + # Check the page number + $error = $self->check_pageno; + $self->{"error"} = $error if defined $error && !defined $self->{"error"}; + + # Obtain the total number + $self->{"select_total"} = sprintf "SELECT count(*) FROM $table;\n"; + $sql = $self->{"select_total"}; + $sth = $DBH->prepare($sql); + $sth->execute; + $self->{"total"} = ($sth->fetchrow_array)[0]; + + # Obtain everything in this page + $self->{"current"} = []; + # Always reverse + $self->{"select"} = "SELECT * FROM $table" + . " WHERE pageno=" . $self->{"pageno"} . ";\n"; + $sql = $self->{"select"}; + $sth = $DBH->prepare($sql); + $sth->execute; + push @{$self->{"current"}}, $_ + while defined($_ = $sth->fetchrow_hashref); + undef $sth; + + # Done + return $self->{"error"}; +} + +# page_param: Obtain page parameters +sub page_param : method { + local ($_, %_); + my ($self, $args); + $self = $_[0]; + # Run the parent method + $args = $self->SUPER::page_param; + # Add the page bar to the page parameters + if (defined $args && $self->{"lastpage"} > 1) { + my $FD; + # Obtain the page bar + IO::NestedCapture->start(CAPTURE_STDOUT); + binmode IO::NestedCapture->instance->{"STDOUT_current"}[-1], ":utf8"; + $self->html_pagebar; + IO::NestedCapture->stop(CAPTURE_STDOUT); + $FD = IO::NestedCapture->get_last_out; + $$args{"header_html_nav"} = join "", <$FD>; + $$args{"header_html_nav"} =~ s/\s+$//; + $$args{"footer_html_nav"} = $$args{"header_html_nav"}; + } + return $args; +} + +# html: Output the list +sub html : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Fetch the current list if not fetched yet + $self->fetch if !$self->{"fetched"}; + + # Display the error message + $self->html_errmsg; + # List the items + $self->html_list; + + return; +} + +# html_list: List the items +sub html_list : method { + local ($_, %_); + my ($self, @htmls, $emailalt); + $self = $_[0]; + # No record to be listed + return if $self->{"total"} == 0; + + $emailalt = h(C_("E-mail")); + foreach my $current (@{$self->{"current"}}) { + my $h; + # Magical Traditional/Simplified Chinese conversion + if ($self->{"magic_zhconv"}) { + $_ = getlang; + if ( $_ eq "zh-tw" && + !(defined $$current{"lang"} + && $$current{"lang"} eq "zh-tw")) { + foreach my $col (qw(name identity location email url message)) { + $$current{$col} = all_to_trad($$current{$col}) + if defined $$current{$col}; + } + } elsif ( $_ eq "zh-cn" && + !(defined $$current{"lang"} + && $$current{"lang"} eq "zh-cn")) { + foreach my $col (qw(name identity location email url message)) { + $$current{$col} = all_to_simp($$current{$col}) + if defined $$current{$col}; + } + } + } + $h = ""; + $h .= "
    \n"; + $h .= "
    \n" . a2html($$current{"message"}) . "\n
    \n\n"; + #
    ...
    cannot live inside of
    ...
    + $h .= "
    \n" + if defined $$current{"email"} && $$current{"email"} =~ /\@/; + $h .= "
    \n"; + $h .= "" . h($$current{"name"}) . "
    \n" + if defined $$current{"name"}; + if (getlang eq "en") { + $h .= myfmttime($$current{"date"}) . "
    \n"; + } else { + $h .= "" . myfmttime($$current{"date"}) . "
    \n"; + } + $h .= h($$current{"identity"}) . "
    \n" + if defined $$current{"identity"}; + $h .= h($$current{"location"}) . "
    \n" + if defined $$current{"location"}; + if (defined $$current{"email"}) { + if ($$current{"email"} =~ /\@/) { + $h .= "" . mung_email_span(h($$current{"email"})) . "" + . "" + . "
    \n"; + } else { + $h .= "" . mung_email_span(h($$current{"email"})) . "
    \n"; + } + } + if (defined $$current{"url"}) { + if ($$current{"url"} =~ /^(?:http|https|ftp|gopher|telnet):\/\//) { + $h .= "" + . h($$current{"url"}) . "
    \n"; + } else { + $h .= h($$current{"url"}) . "
    \n"; + } + } + $h .= C_("~[Edit~]", + h("/magicat/cgi-bin/guestbook.cgi?form=cur&sn=" . $$current{"sn"})) . "\n" + if $ENV{"REMOTE_ADDR"} =~ /^10\./; + $h .= "
    \n"; + $h .= "
    \n" if defined $$current{"email"} && $$current{"email"} =~ /\@/; + $h .= "
    \n\n"; + push @htmls, $h; + } + + $_ = h(C_("The message entry seperator")); + print "
    \n\n
    \n\n" + . join("
    \n\n", @htmls) . "
    \n\n"; + + return; +} + +return 1; diff --git a/lib/perl5/Selima/List/LinkCat.pm b/lib/perl5/Selima/List/LinkCat.pm new file mode 100644 index 0000000..5999dd6 --- /dev/null +++ b/lib/perl5/Selima/List/LinkCat.pm @@ -0,0 +1,48 @@ +# Selima Website Content Management System +# LinkCat.pm: The related-link category list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::List::LinkCat; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Category); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "linkcat" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + C_("Select a Link Category"): + C_("Manage Link Categories"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "ord,id"; + # Column labels + $self->col_labels( + ); + return $self; +} + +return 1; diff --git a/lib/perl5/Selima/List/LinkCatz.pm b/lib/perl5/Selima/List/LinkCatz.pm new file mode 100644 index 0000000..0a94f56 --- /dev/null +++ b/lib/perl5/Selima/List/LinkCatz.pm @@ -0,0 +1,49 @@ +# Selima Website Content Management System +# LinkCatz.pm: The related-link category membership list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-25 + +package Selima::List::LinkCatz; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List::Categorz); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "linkcatz" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + C_("Select a Link Categorization Record"): + C_("Manage Link Categorization"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "cat,link"; + # Column labels + $self->col_labels( + "link" => C_("Link"), + ); + return $self; +} + +return 1; diff --git a/lib/perl5/Selima/List/Links.pm b/lib/perl5/Selima/List/Links.pm new file mode 100644 index 0000000..fa45dd0 --- /dev/null +++ b/lib/perl5/Selima/List/Links.pm @@ -0,0 +1,100 @@ +# Selima Website Content Management System +# Links.pm: The related-link list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::List::Links; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "links" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + C_("Select a Related Link"): + C_("Manage Related Links"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "title"; + # Columns that should display its brief instead + push @{$self->{"COLS_BRIEF"}}, qw(dsc); + # Column labels + $self->col_labels( + "title_2ln" => C_("2nd language title"), + "_imgsrc" => C_("Link icon"), + "addr" => C_("Address"), + "tel" => C_("Tel."), + "fax" => C_("Fax."), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(C_("Add a new related link.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for a related link:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,related link].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,related link].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,related link], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,related link], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/List/Pages.pm b/lib/perl5/Selima/List/Pages.pm new file mode 100644 index 0000000..aef36a8 --- /dev/null +++ b/lib/perl5/Selima/List/Pages.pm @@ -0,0 +1,96 @@ +# Selima Website Content Management System +# Pages.pm: The base web page list. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-28 + +package Selima::List::Pages; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "pages" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + C_("Select a Page"): + C_("Manage Pages"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "title"; + # Columns that should display its brief instead + push @{$self->{"COLS_BRIEF"}}, qw(body); + # Column labels + $self->col_labels( + "path" => C_("Page path"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(C_("Write a new page.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for a page:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,page].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,page].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,page], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,page], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/List/ScptPriv.pm b/lib/perl5/Selima/List/ScptPriv.pm new file mode 100644 index 0000000..768c8f8 --- /dev/null +++ b/lib/perl5/Selima/List/ScptPriv.pm @@ -0,0 +1,95 @@ +# Selima Website Content Management System +# ScptPriv.pm: The script privilege list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +package Selima::List::ScptPriv; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "scptpriv" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + C_("Select a Script Privilege Record"): + C_("Manage Script Privileges"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "script,grp"; + # Column labels + $self->col_labels( + "script" => C_("Script"), + "grp" => C_("Privilege"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(C_("Add a new script privilege record.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for a script privilege record:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,script privilege record].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,script privilege record].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,script privilege record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,script privilege record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/List/UserMem.pm b/lib/perl5/Selima/List/UserMem.pm new file mode 100644 index 0000000..cd1d40c --- /dev/null +++ b/lib/perl5/Selima/List/UserMem.pm @@ -0,0 +1,95 @@ +# Selima Website Content Management System +# UserMem.pm: The user-to-group membership list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-13 + +package Selima::List::UserMem; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "usermem" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + C_("Select a User Membership Record"): + C_("Manage User Membership"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "grp,member"; + # Column labels + $self->col_labels( + "grp" => C_("Group"), + "member" => C_("Member"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(C_("Add a new membership record.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for a membership record:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,membership record].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,membership record].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,membership record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,membership record], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/List/UserPref.pm b/lib/perl5/Selima/List/UserPref.pm new file mode 100644 index 0000000..01d7840 --- /dev/null +++ b/lib/perl5/Selima/List/UserPref.pm @@ -0,0 +1,96 @@ +# Selima Website Content Management System +# UserPref.pm: The user preference list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +package Selima::List::UserPref; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "userpref" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? + C_("Select a User Preference"): + C_("Manage User Preferences"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "domain,usr,name"; + # Column labels + $self->col_labels( + "usr" => C_("User"), + "domain" => C_("Domain"), + "value" => C_("Value"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(C_("Add a new user preference.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for a user preference:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,user preference].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,user preference].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,user preference], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,user preference], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/List/Users.pm b/lib/perl5/Selima/List/Users.pm new file mode 100644 index 0000000..6ae9c62 --- /dev/null +++ b/lib/perl5/Selima/List/Users.pm @@ -0,0 +1,101 @@ +# Selima Website Content Management System +# Users.pm: The user account list. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-28 + +package Selima::List::Users; +use 5.008; +use strict; +use warnings; +use base qw(Selima::List); + +use Selima::ShortCut; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "users" if !defined $_[1]; + $self = $class->SUPER::new(@_); + # The page title + $self->{"title"} = $self->{"is_called_form"}? C_("Select a User"): + C_("Manage Users"); + # The default sort order + $self->{"DEFAULT_SORTBY"} = "id"; + # Column labels + $self->col_labels( + "id" => C_("User ID."), + "name" => C_("Full name"), + "deleted" => C_("Deleted?"), + "lang" => C_("Pref. language"), + "visits" => C_("Visits"), + "visited" => C_("Visited"), + "ip" => C_("IP"), + "host" => C_("Host"), + "ct" => C_("Country"), + ); + return $self; +} + +# html_newlink: Display a link to add a new item +sub html_newlink : method { + # Run the parent method + return $_[0]->SUPER::html_newlink(C_("Add a new user account.")); +} + +# html_search: Display the search box +sub html_search : method { + # Run the parent method + return $_[0]->SUPER::html_search(C_("Search for a user:")); +} + +# liststat_message: Return the current list statistics message +sub liststat_message : method { + local ($_, %_); + my $self; + $self = $_[0]; + + # No record to list + if ($self->{"total"} == 0) { + # Inherit the empty list statistics message + return $self->SUPER::liststat_message; + # Fit in one page + } elsif ($self->{"total"} <= $self->{"pagesize"}) { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,user].", $self->{"total"}); + # List result + } else { + return C_("[*,_1,user].", $self->{"total"}); + } + # More than one page + } else { + # Result comes from a query + if (defined $self->{"query"}) { + return C_("Your query found [*,_1,user], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + # List result + } else { + return C_("[*,_1,user], listing [#,_2] to [#,_3].", + $self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1); + } + } +} + +return 1; diff --git a/lib/perl5/Selima/ListFunc.pm b/lib/perl5/Selima/ListFunc.pm new file mode 100644 index 0000000..855a478 --- /dev/null +++ b/lib/perl5/Selima/ListFunc.pm @@ -0,0 +1,58 @@ +# Selima Website Content Management System +# ListFunc.pm: The subroutines for the lists. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-11-17 + +package Selima::ListFunc; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(list_type); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub list_type(;$); +} + +use Selima::Cache qw(:listfunc); +use Selima::FormFunc; + +# list_type: Return the list name +sub list_type(;$) { + local ($_, %_); + my $type; + $type = $_[0]; + + # Set the form type + return ($ListFunc_listtype = $type) if defined $type; + + # Return the cache + return $ListFunc_listtype if defined $ListFunc_listtype; + + # Obtain the current form + $_ = curform; + # Form type specified in arguments + return ($ListFunc_listtype = $_->param("list")) + if defined $_->param("list"); + # No form source is found + return ($ListFunc_listtype = -1); +} + +return 1; diff --git a/lib/perl5/Selima/ListPref.pm b/lib/perl5/Selima/ListPref.pm new file mode 100644 index 0000000..bcd839d --- /dev/null +++ b/lib/perl5/Selima/ListPref.pm @@ -0,0 +1,147 @@ +# Selima Website Content Management System +# ListPref.pm: The list preference administration. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-14 + +package Selima::ListPref; +use 5.008; +use strict; +use warnings; + +use Fcntl qw(:flock); +use URI qw(); + +use Selima::AddGet; +use Selima::CallForm; +use Selima::DataVars qw($DBH :env :requri); +use Selima::HTTP; + +use Selima::Checker::ListPref; +use Selima::Processor::ListPref; + +# Load these classes +use Selima::ListPref::AcctReps; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($class, $form, $self); + ($class, $form) = @_; + $self = bless {}, $class; + $self->{"form"} = $form; + $self->_set_referer; + $self->_set_domain; + return $self; +} + +# main: Change the list preference +sub main : method { + local ($_, %_); + my ($self, $error, $processor); + $self = $_[0]; + # Lock the necessary tables + $DBH->lock("userpref" => LOCK_EX); + + $error = $self->_check_post(); + # If an error occurs + if (defined $error) { + $$error{"isform"} = 0; + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::ListPref($self->{"form"}); + $processor->process; + http_303 $self->{"referer"}; + } +} + +# _check_post: Check the list preference form +sub _check_post : method { + local ($_, %_); + my ($self, $checker, $error); + $self = $_[0]; + # Run the checker + $checker = new Selima::Checker::ListPref($self->{"form"}); + $error = $checker->check(qw(domain listcols listsize)); + return $error if defined $error; + # OK + return; +} + +# _set_referer: Obtain the referer to return to +sub _set_referer : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Obtained before + return $self->{"referer"} if exists $self->{"referer"}; + # Remove the status from the source referer + return ($self->{"referer"} = rem_get_arg $self->_source_referer, "statid"); +} + +# _source_referer: Obtain the source referer +sub _source_referer : method { + local ($_, %_); + my ($self, $r); + $self = $_[0]; + # Use the POSTed referer + return $_ if defined($_ = $self->{"form"}->param("referer")); + # Use the referer from the request + if ($IS_MODPERL) { + $r = $IS_MP2? Apache2::RequestUtil->request: + Apache->request; + return $_ if defined($_ = $r->headers_in->get("Referer")); + } else { + return $ENV{"HTTP_REFERER"} if exists $ENV{"HTTP_REFERER"}; + } + # Fall back to myself + return $REQUEST_FULLURI; +} + +# _set_domain: Obtain the domain this preference belongs to +sub _set_domain : method { + local ($_, %_); + my ($self, $form, $uri); + $self = $_[0]; + $form = $self->{"form"}; + # Obtained before + return $self->{"domain"} if exists $self->{"domain"}; + # Return the supplied domain + return ($self->{"domain"} = $_) + if defined($_ = $form->param("domain")); + # Obtain the referer first + $self->_set_referer; + # Return the current script path for the most cases + if ($self->{"referer"} eq $REQUEST_FULLURI) { + $self->{"domain"} = $REQUEST_PATH; + $form->param("domain", $self->{"domain"}); + return $self->{"domain"}; + } + + # Parse the referer to get the script path + $uri = new URI($self->{"referer"}); + # Fall back to the root directory if there is no script part + $self->{"domain"} = (($_ = $uri->path) ne "")? $_: "/"; + # Strip the leading root difference + $self->{"domain"} =~ s/^$ROOT_DIFF//; + $form->param("domain", $self->{"domain"}); + return $self->{"domain"}; +} + +return 1; diff --git a/lib/perl5/Selima/ListPref/AcctReps.pm b/lib/perl5/Selima/ListPref/AcctReps.pm new file mode 100644 index 0000000..942c12f --- /dev/null +++ b/lib/perl5/Selima/ListPref/AcctReps.pm @@ -0,0 +1,71 @@ +# Selima Website Content Management System +# AcctReps.pm: The accounting report list preference administration. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-10-01 + +package Selima::ListPref::AcctReps; +use 5.008; +use strict; +use warnings; +use base qw(Selima::ListPref); + +use Fcntl qw(:flock); + +use Selima::CallForm; +use Selima::DataVars qw($DBH); +use Selima::HTTP; + +use Selima::Checker::ListPref; +use Selima::Processor::ListPref::AcctReps; + +# main: Change the list preference +sub main : method { + local ($_, %_); + my ($self, $error, $processor); + $self = $_[0]; + # Lock the necessary tables + $DBH->lock("userpref" => LOCK_EX); + + $error = $self->_check_post(); + # If an error occurs + if (defined $error) { + $$error{"isform"} = 0; + error_redirect $error; + + # Else, save the data + } else { + $processor = new Selima::Processor::ListPref::AcctReps($self->{"form"}); + $processor->process; + http_303 $self->{"referer"}; + } +} + +# _check_post: Check the list preference form +sub _check_post : method { + local ($_, %_); + my ($self, $checker, $error); + $self = $_[0]; + # Run the checker + $checker = new Selima::Checker::ListPref($self->{"form"}); + $error = $checker->check(qw(domain listsize)); + return $error if defined $error; + # OK + return; +} + +return 1; diff --git a/lib/perl5/Selima/LnInfo.pm b/lib/perl5/Selima/LnInfo.pm new file mode 100644 index 0000000..2fa6b63 --- /dev/null +++ b/lib/perl5/Selima/LnInfo.pm @@ -0,0 +1,268 @@ +# Selima Website Content Management System +# LnInfo.pm: The language information. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-23 + +package Selima::LnInfo; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(ln); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub init_lninfo(); +sub ln($$); +sub name($); +sub charset($); +sub filename($); +sub locale($); +sub db($); +sub htmlid($); +sub space_break($); +sub country_first($); +sub desc($); +sub desc_curlc($); +sub desc_selflc($); +sub switch_title($); +} + +use Selima::DataVars qw(:l10n :lninfo); +use Selima::GetLang; +use Selima::SetL10N; +use Selima::ShortCut; + +use vars qw(%LANGS %DESC_SELFLC %SWITCH_TITLE); +%LANGS = ( + "zh-tw" => { + "name" => "zh-tw", + "filename" => "zh-tw", + "charset" => "UTF-8", + "db" => "zhtw", + "htmlid" => "zhtw", + "locale" => "zh_TW", + "sp_break" => 0, + "ctfirst" => 1, + "longdesc" => N_("Traditional Chinese")}, + "zh-cn" => { + "name" => "zh-cn", + "filename" => "zh-cn", + "charset" => "UTF-8", + "db" => "zhcn", + "htmlid" => "zhcn", + "locale" => "zh_CN", + "sp_break" => 0, + "ctfirst" => 1, + "longdesc" => N_("Simplified Chinese")}, + "en" => { + "name" => "en-us", + "filename" => "en", + "charset" => "UTF-8", + "db" => "en", + "htmlid" => "en", + "locale" => "en_US", + "sp_break" => 1, + "ctfirst" => 0, + "longdesc" => N_("English")}, + "ja" => { + "name" => "ja", + "filename" => "ja", + "charset" => "UTF-8", + "db" => "ja", + "htmlid" => "ja", + "locale" => "ja_JP", + "sp_break" => 0, + "ctfirst" => 1, + "longdesc" => N_("Japanese")}, + "de" => { + "name" => "de", + "filename" => "de", + "charset" => "UTF-8", + "db" => "de", + "htmlid" => "de", + "locale" => "de_DE", + "sp_break" => 0, + "ctfirst" => 1, + "longdesc" => N_("German")}); + +# Subroutines +# ln: Uniformed wrapper for everything +sub ln($$) { + local ($_, %_); + my ($lang, $type); + ($lang, $type) = @_; + + if ($type == LN_NAME) { + return name($lang); + } elsif ($type == LN_CHARSET) { + return charset($lang); + } elsif ($type == LN_FILENAME) { + return filename($lang); + } elsif ($type == LN_LOCALE) { + return locale($lang); + } elsif ($type == LN_DATABASE) { + return db($lang); + } elsif ($type == LN_HTMLID) { + return htmlid($lang); + } elsif ($type == LN_SPACE_BREAK) { + return space_break($lang); + } elsif ($type == LN_COUNTRY_FIRST) { + return country_first($lang); + } elsif ($type == LN_DESC) { + return desc($lang); + } elsif ($type == LN_DESC_CURLC) { + return desc_curlc($lang); + } elsif ($type == LN_DESC_SELFLC) { + return desc_selflc($lang); + } elsif ($type == LN_SWITCH_TITLE) { + return switch_title($lang); + } else { + return $lang; + } +} + +# name: Language complete name +# Return en-us for en, to be more specified +sub name($) { + return exists $LANGS{$_[0]} && ${$LANGS{$_[0]}}{"name"}? + ${$LANGS{$_[0]}}{"name"}: $_[0]; +} + +# charset: File system name +sub charset($) { + return exists $LANGS{$_[0]} && ${$LANGS{$_[0]}}{"charset"}? + ${$LANGS{$_[0]}}{"charset"}: $_[0]; +} + +# filename: Most common charset that is used with the specified language +sub filename($) { + return exists $LANGS{$_[0]} && ${$LANGS{$_[0]}}{"filename"}? + ${$LANGS{$_[0]}}{"filename"}: $_[0]; +} + +# locale: Locale used by GNU glibc and gettext +# Replace hyphens with underscores, and upper-case the district divisions, +# as used in GNU glibc +sub locale($) { + local ($_, %_); + return ${$LANGS{$_[0]}}{"locale"} + if exists $LANGS{$_[0]} && ${$LANGS{$_[0]}}{"locale"}; + $_ = $_[0]; + s/-/_/; + s/_([a-z]+)/"_" . uc $1/e; + return $_; +} + +# db: Database column name +# Hyphens are not allowed, to avoid confusion +# with the substraction operator "-" +sub db($) { + local ($_, %_); + return ${$LANGS{$_[0]}}{"db"} + if exists $LANGS{$_[0]} && ${$LANGS{$_[0]}}{"db"}; + $_ = $_[0]; + s/-//g; + return $_; +} + +# htmlid: HTML id value +# Hyphens are not allowed, as specified in HTML 4.01 specification +sub htmlid($) { + local ($_, %_); + return ${$LANGS{$_[0]}}{"htmlid"} + if exists $LANGS{$_[0]} && ${$LANGS{$_[0]}}{"htmlid"}; + $_ = $_[0]; + s/-//g; + return $_; +} + +# space_break: Whether words are seperated at spaces +sub space_break($) { + # Default to true, for alphabetic languages + return exists $LANGS{$_[0]} && ${$LANGS{$_[0]}}{"sp_break"}? + ${$LANGS{$_[0]}}{"sp_break"}: 1; +} + +# country_first: Whether country should be listed first in a mail address +sub country_first($) { + # Default to false, for European languages + return exists $LANGS{$_[0]} && ${$LANGS{$_[0]}}{"ctfirst"}? + ${$LANGS{$_[0]}}{"ctfirst"}: 0; +} + +# desc: Long description +sub desc($) { + return exists $LANGS{$_[0]} && ${$LANGS{$_[0]}}{"longdesc"}? + ${$LANGS{$_[0]}}{"longdesc"}: $_[0]; +} + +# desc_curlc: Long description in the current locale +sub desc_curlc($) { + return C_(desc($_[0])); +} + +# desc_selflc: Long description in its own locale +sub desc_selflc($) { + local ($_, %_); + my ($lang, $lh); + $lang = $_[0]; + + # Obtain the description list + if (scalar(keys %DESC_SELFLC) == 0) { + foreach my $ln (keys %LANGS) { + # Switch the locale + set_l10n $ln; + # Obtain the long description + $DESC_SELFLC{$ln} = C_(desc $ln); + } + # Switch back the locale + set_l10n; + } + + # Return the proper description + return exists $DESC_SELFLC{$lang}? $DESC_SELFLC{$lang}: $lang; +} + +# switch_title: Title of the language switch +sub switch_title($) { + my ($lang, $lh); + $lang = $_[0]; + + # Obtain the description list + if (scalar(keys %SWITCH_TITLE) == 0) { + # Find the descriptions in their own locale first + # Obtain the description list + foreach my $ln (keys %LANGS) { + # Switch the locale + set_l10n $ln; + # Obtain the long description + $SWITCH_TITLE{$ln} = C_("Switch to the %s version of this page."); + } + # Switch back the locale + set_l10n; + } + + # Not found -- use description in its own locale instead + return desc_selflc($lang) if !exists $SWITCH_TITLE{$lang}; + # Return the proper description + return sprintf $SWITCH_TITLE{$lang}, desc_selflc($lang); +} + +return 1; diff --git a/lib/perl5/Selima/LogIn.pm b/lib/perl5/Selima/LogIn.pm new file mode 100644 index 0000000..8ea4cd8 --- /dev/null +++ b/lib/perl5/Selima/LogIn.pm @@ -0,0 +1,247 @@ +# Selima Website Content Management System +# LogIn.pm: The log-in subroutines. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-12 + +package Selima::LogIn; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(use_users); +push @EXPORT, qw(get_login_sn get_login_id get_login_name get_login_groups); +push @EXPORT, qw(upd_login_info); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub use_users(); +sub get_login_sn(); +sub get_login_id(); +sub get_login_name(); +sub get_login_groups(); +sub upd_login_info(); +} + +use Fcntl qw(:flock); + +BEGIN { +if (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + require Apache2::Connection; +} +} + +use Selima::Array; +use Selima::AddCol; +use Selima::Cache qw(:login); +use Selima::ChkPriv; +use Selima::DataVars qw($DBH $SESSION :addcol :env :input :lninfo :output); +use Selima::Encrypt; +use Selima::GeoIP; +use Selima::HTTP; +use Selima::GetLang; +use Selima::Init; +use Selima::RemoHost; + +use vars qw($REMEMBER); +$REMEMBER = "Wwo80oTBNnMuw0rx"; + +# use_users: Use user/membership system +sub use_users() { + local ($_, %_); + # Return the cache + return $LogIn_use_users if defined $LogIn_use_users; + # Find in the available tables + return ($LogIn_use_users = defined $DBH && in_array("users", $DBH->tables)); +} + +# get_login_sn: Obtain the user serial number of the current logged-in user +sub get_login_sn() { + return $$SESSION{"usersn"} + if defined $SESSION && exists $$SESSION{"usersn"}; + return undef; +} + +# get_login_id: Obtain the user ID. of the current logged-in user +sub get_login_id() { + return $$SESSION{"userid"} + if defined $SESSION && exists $$SESSION{"userid"}; + return undef; +} + +# get_login_name: Obtain the full name of the current logged-in user +sub get_login_name() { + return $$SESSION{"username"} + if defined $SESSION && exists $$SESSION{"username"}; + return undef; +} + +# get_login_groups: Obtain the groups of the current logged-in user +sub get_login_groups() { + return @{$$SESSION{"groups"}} + if defined $SESSION && exists $$SESSION{"groups"}; + return; +} + +# upd_login_info: Update the logged-in infomation +sub upd_login_info() { + local ($_, %_); + my ($row, $sth, $sql, $cols, @updcols); + + # Lock the necessary tables and begin transaction + %_ = ( "users" => LOCK_EX, + "groups" => LOCK_SH, + "usermem" => LOCK_SH, + "groupmem" => LOCK_SH); + $DBH->lock(%_); + + $cols = new Selima::AddCol("users", ADDCOL_UPDATE); + @updcols = qw(); + # Run on the console + if (!$IS_CGI) { + # To be done: this is not working on MSWin32 + $_ = getpwuid $>; + # Password entry is gone for this user + if (!defined $_) { + if ($ENV{"REQUEST_METHOD"} eq "POST") { + http_303 "/" . getlang(LN_FILENAME) . "/misc/loginchanged.html"; + } else { + http_307 "/" . getlang(LN_FILENAME) . "/misc/loginchanged.html"; + } + # No need to return + exit; + } + # Fetch the user infomation + $sql = "SELECT * FROM users" + . " WHERE id=" . $DBH->quote($_) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + # This user is not in the list of the users for the current package + http_403 if $sth->rows == 0; + $row = $sth->fetchrow_hashref; + + # Logged-in from Apache::AuthDigest Digest Authentication + } elsif (defined $AUTHINFO) { + $row = $AUTHINFO; + if ( !exists $$SESSION{"usersn"} + || $$SESSION{"usersn"} != $$row{"sn"}) { + $$SESSION{"usersn"} = $$row{"sn"}; + $cols->addexpr("visits", "visits+1"); + $cols->addstr("host", remote_host); + $cols->addstr("ct", country_lookup); + $cols->addexpr("visited", "now()"); + } + + # Log-in from Apache mod_auth_digest Digest Authentication + } elsif (exists $ENV{"REMOTE_USER"}) { + # Fetch the user infomation + $sql = "SELECT * FROM users" + . " WHERE id=" . $DBH->quote($ENV{"REMOTE_USER"}) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + # User does not exist anymore + if ($sth->rows == 0) { + logout(); + if ($ENV{"REQUEST_METHOD"} eq "POST") { + http_303 "/" . getlang(LN_FILENAME) . "/misc/loginchanged.html"; + } else { + http_307 "/" . getlang(LN_FILENAME) . "/misc/loginchanged.html"; + } + # No need to return + exit; + } + $row = $sth->fetchrow_hashref; + $$SESSION{"usersn"} = $$row{"sn"}; + + # Log-in information not supplied by either one + } else { + # Return if not logged-in yet + return if !defined get_login_sn; + + # Fetch the user infomation + $sql = "SELECT * FROM users" + . " WHERE sn=" . $DBH->quote(get_login_sn) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + # User does not exist anymore + if ($sth->rows == 0) { + logout(); + if ($ENV{"REQUEST_METHOD"} eq "POST") { + http_303 "/" . getlang(LN_FILENAME) . "/misc/loginchanged.html"; + } else { + http_307 "/" . getlang(LN_FILENAME) . "/misc/loginchanged.html"; + } + # No need to return + exit; + } + $row = $sth->fetchrow_hashref; + } + + # Remember the user + if (exists $$SESSION{"remember"}) { + # Remember me + if ($$SESSION{"remember"}) { + $NEWCOOKIES{$REMEMBER} = new CGI::Cookie(-name=>$REMEMBER, + -value=>encrypt $$row{"id"}, -expires=>"+1y"); + # Forget me + } else { + $NEWCOOKIES{$REMEMBER} = new CGI::Cookie(-name=>$REMEMBER, + -value=>"", -expires=>"-1s"); + } + delete $$SESSION{"remember"}; + # Update the remembered user ID + } elsif ( exists $COOKIES{$REMEMBER} + && decrypt($COOKIES{$REMEMBER}->value) ne $$row{"id"}) { + $NEWCOOKIES{$REMEMBER} = new CGI::Cookie(-name=>$REMEMBER, + -value=>encrypt $$row{"id"}, -expires=>"+1y"); + } + + # Update the user ID and full name + $$SESSION{"usersn"} = $$row{"sn"}; + $$SESSION{"userid"} = $$row{"id"}; + $$SESSION{"username"} = $$row{"name"}; + + # Update the IP and the preferred language + $_ = $IS_MODPERL? ($IS_MP2? + Apache2::RequestUtil->request->connection->remote_ip: + Apache->request->connection->remote_ip): + $ENV{"REMOTE_ADDR"}; + $cols->addipaddr("ip", $_, $$row{"ip"}); + $cols->addstr("lang", getlang, $$row{"lang"}); + + if ($cols->modified) { + $sql = "UPDATE users " . $cols->ret(ADDCOL_NOTIMESTAMP) + . " WHERE sn=" . $$row{"sn"} . ";\n"; + $DBH->do($sql); + } + + # Update the groups + @_ = user_parent_groups get_login_sn; + $$SESSION{"groups"} = [@_]; + %_ = map { $_ => 1 } @_; + $$SESSION{"guest"} = exists $_{GUEST_GROUP}; + $$SESSION{"admin"} = exists $_{ADMIN_GROUP}; + $SESSION->flush; + + # Commit the SQL transaction + $DBH->commit; + return; +} + +return 1; diff --git a/lib/perl5/Selima/LogOut.pm b/lib/perl5/Selima/LogOut.pm new file mode 100644 index 0000000..1bc63e6 --- /dev/null +++ b/lib/perl5/Selima/LogOut.pm @@ -0,0 +1,90 @@ +# Selima Website Content Management System +# LogOut.pm: The log-out subroutines. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-16 + +package Selima::LogOut; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(logout); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub logout(); +sub new_logoutid(); +} + +use File::Spec::Functions qw(catfile); + +use Selima::AddGet; +use Selima::DataVars qw($SESSION $AUTHINFO :env); +use Selima::HTTP; +use Selima::Session; +use Selima::XFileIO; + +# logout: Log out +sub logout() { + local ($_, %_); + delete $$SESSION{"usersn"}; + delete $$SESSION{"userid"}; + delete $$SESSION{"username"}; + delete $$SESSION{"userpref"}; + delete $$SESSION{"groups"}; + delete $$SESSION{"admin"}; + delete $$SESSION{"guest"}; + # Logged-in from Apache/mod_perl HTTP Authentication + if (defined $AUTHINFO) { + my ($id, $file, $r, $uri, $method); + ($id, $file) = new_logoutid; + # Tag the log out file + xfwrite($file, ""); + + # Get back to the referer + $r = $IS_MP2? Apache2::RequestUtil->request: + Apache->request; + $uri = $r->headers_in->get("Referer"); + # Default to the home if referer is not available + $uri = "/magicat/" if !defined $uri; + # Append the logout ID. + $uri = add_get_arg $uri, "logout", $id; + + # Back to the referer + if ($r->method eq "POST") { + http_303 $uri; + } else { + http_307 $uri; + } + } + return; +} + +# new_logoutid: Generate a new random logout ID number +sub new_logoutid() { + local ($_, %_); + my ($id, $file); + do { + $id = 100000000 + int rand 900000000; + $file = catfile($Selima::Session::DIR, "logout_$id"); + } until !-e $file; + return ($id, $file); +} + +return 1; diff --git a/lib/perl5/Selima/Logging.pm b/lib/perl5/Selima/Logging.pm new file mode 100644 index 0000000..41e8460 --- /dev/null +++ b/lib/perl5/Selima/Logging.pm @@ -0,0 +1,207 @@ +# Selima Website Content Management System +# Logging.pm: The loggers. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-26 + +package Selima::Logging; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(log_error log_warn actlog sub check_actlog_file); +push @EXPORT, qw(spamlog check_spamlog_file $ACTLOG $SPAMLOG); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub log_error($); +sub log_warn($); +sub actlog($;$); +sub check_actlog_file(); +sub spamlog($); +sub check_spamlog_file(); +} + +use Date::Format qw(time2str); +use Encode qw(encode is_utf8 FB_CROAK); +use File::Spec::Functions qw(catfile); + +BEGIN { +if (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + require Apache2::Connection; +} +} + +use Selima::DataVars qw(:env :siteconf :requri); +use Selima::HTTP; +use Selima::LogIn; +use Selima::RemoHost; +use Selima::XFileIO; + +use vars qw($ACTLOG $SPAMLOG); + +# log_error: Log to Apache error_log as error +sub log_error($) { + local ($_, %_); + my $remote; + $_ = $_[0]; + chomp; + + # mod_perl: use Apache->request->log_error + if ($IS_MODPERL) { + my $r; + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request; + $remote = defined remote_host? remote_host: + $r->connection->remote_ip; + $_ = sprintf "[client %s] %s", $remote, $_; + $r->log_error($_); + + # Non-mod_perl: print to STDERR + } else { + $remote = defined remote_host? remote_host: + $ENV{"REMOTE_ADDR"}; + $_ = sprintf "[client %s] %s", $remote, $_; + printf STDERR "[%s] [error] %s\n", + time2str("%a %b %e %T %Y", time), $_; + } + return; +} + +# log_error: Log to Apache error_log as warning +sub log_warn($) { + local ($_, %_); + my $remote; + $_ = $_[0]; + chomp; + + # mod_perl: use Apache->request->log_error + if ($IS_MODPERL) { + my $r; + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request; + remote_host; + $remote = defined remote_host? remote_host: + $r->connection->remote_ip; + $_ = sprintf "[client %s] %s", $remote, $_; + $r->warn($_); + + # Non-mod_perl: print to STDERR + } else { + $remote = defined remote_host? remote_host: + $ENV{"REMOTE_ADDR"}; + $_ = sprintf "[client %s] %s", $remote, $_; + printf STDERR "[%s] [warn] %s\n", + time2str("%a %b %e %T %Y", time), $_; + } + return; +} + +# actlog: Log an activity +sub actlog($;$) { + local ($_, %_); + my ($msg, $user, $remote); + ($msg, $user) = @_; + + # Set the file location of the activity log file + check_actlog_file; + # No valid activity log file is found + http_500 "Activity log actlog.txt not found" + if !defined $ACTLOG; + + # Escape control characters for safety + $msg =~ s/\t/\\t/g; + $msg =~ s/\r/\\r/g; + $msg =~ s/\n/\\n/g; + $msg =~ s/([\x00-\x08\x0B\x0C\x0E-\x1F])/sprintf("\\x%02x", ord($1));/ge; + $msg = encode("UTF-8", $msg, FB_CROAK) if is_utf8($msg); + + if (!defined $user) { + $user = defined get_login_id? get_login_id: "anonymous"; + } + $remote = $IS_MODPERL? ($IS_MP2? + Apache2::RequestUtil->request->connection->remote_ip: + Apache->request->connection->remote_ip): + $ENV{"REMOTE_ADDR"}; + $msg = sprintf "[%s] %s: (%s from %s) %s\n", + time2str("%Y-%m-%d %X %z", time), $REQUEST_PATH, $user, $remote, $msg; + xfappend($ACTLOG, $msg); + return; +} + +# check_actlog_file: Check the activity log file +sub check_actlog_file() { + local ($_, %_); + # Gather the candidates + @_ = qw(); + push @_, catfile("/var/log/apache2", $PACKAGE, "actlog.txt"); + push @_, catfile("/var/log/apache2", "actlog.txt"); + # Found + foreach (@_) { + return ($ACTLOG = $_) if -e $_ && -f $_ && -w $_; + } + # Not found + undef $ACTLOG; + return undef; +} + +# spamlog: Log a suspicious spammer +sub spamlog($) { + local ($_, %_); + my ($msg, $remote); + $msg = $_[0]; + + # Set the file location of the activity log file + check_spamlog_file; + # No valid activity log file is found + http_500 "Spam log spamlog.txt not found" + if !defined $SPAMLOG; + + # Escape control characters for safety + $msg =~ s/\t/\\t/g; + $msg =~ s/\r/\\r/g; + $msg =~ s/\n/\\n/g; + $msg =~ s/([\x00-\x08\x0B\x0C\x0E-\x1F])/sprintf("\\x%02x", ord($1));/ge; + $msg = encode("UTF-8", $msg, FB_CROAK) if is_utf8($msg); + + $remote = $IS_MODPERL? ($IS_MP2? + Apache2::RequestUtil->request->connection->remote_ip: + Apache->request->connection->remote_ip): + $ENV{"REMOTE_ADDR"}; + $msg = sprintf "[%s] %s: %s: (from %s) %s\n", + time2str("%Y-%m-%d %X %z", time), $PACKAGE, $REQUEST_PATH, $remote, $msg; + xfappend($SPAMLOG, $msg); + return; +} + +# check_spamlog_file: Check the spammer log file +sub check_spamlog_file() { + local ($_, %_); + # Gather the candidates + @_ = qw(); + push @_, catfile("/var/log/apache2", $PACKAGE, "spamlog.txt"); + push @_, catfile("/var/log/apache2", "spamlog.txt"); + # Found + foreach (@_) { + return ($SPAMLOG = $_) if -e $_ && -f $_ && -w $_; + } + # Not found + undef $SPAMLOG; + return undef; +} + +return 1; diff --git a/lib/perl5/Selima/Mail.pm b/lib/perl5/Selima/Mail.pm new file mode 100644 index 0000000..0582d0d --- /dev/null +++ b/lib/perl5/Selima/Mail.pm @@ -0,0 +1,1417 @@ +# Selima Website Content Management System +# Mail.pm: The mail composer and sender. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-18 + +package Selima::Mail; +use 5.008; +use strict; +use warnings; +BEGIN { +# Prototype declaration +sub quote($); +sub rfc822_phrase_need_quoting($); +sub rfc1521_value_need_quoting($); +sub b64hdr_encode($$); +sub rfc822_time(;$); +} + +use Digest::MD5 qw(md5_base64); +use Date::Format qw(time2str); +use Encode qw(encode is_utf8 FB_CROAK); +use File::Basename qw(basename); +use File::MMagic qw(); +use MIME::Base64 qw(encode_base64); +use MIME::QuotedPrint qw(encode_qp); +use Net::SMTP; +use Time::HiRes qw(); +use Socket qw(inet_aton inet_ntoa AF_INET); + +BEGIN { +if (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + require Apache2::Connection; +} +} + +use Selima::Cache qw(:mail); +use Selima::DataVars qw(:env :lninfo :mail); +use Selima::GeoIP; +use Selima::HTTP; +use Selima::HTTPS; +use Selima::LnInfo; +use Selima::LogIn; +use Selima::Server; +use Selima::Unicode; +use Selima::XFileIO; + +use vars qw($MM); +$MM = new File::MMagic; + +# new: Initialize the e-mail message +sub new : method { + local ($_, %_); + my ($class, $self); + $class = $_[0]; + $self = bless {}, $class; + + $self->{"body"} = undef; + $self->{"parts"} = []; + $self->{"charset"} = undef; + $self->{"modified"} = 0; + $self->{"output"} = undef; + $self->{"attaches"} = []; + if (-x "/usr/sbin/sendmail") { + $self->{"send_with"} = "sendmail"; + } else { + $self->{"send_with"} = "smtp"; + } + + # RFC 821 headers/properties + $self->{"mail_from"} = undef; + $self->{"rcpt_to"} = undef; + # RFC 822 headers/properties + $self->{"from"} = undef; + $self->{"subject"} = undef; + $self->{"sender"} = undef; + $self->{"to"} = undef; + $self->{"cc"} = undef; + $self->{"bcc"} = undef; + $self->{"reply_to"} = undef; + # RFC 1521 MIME headers/properties + $self->{"type"} = "text/plain"; + $self->{"id"} = undef; + # RFC 1766 Content-Language + $self->{"lang"} = undef; + # RFC 1806/2183 Content-Disposition + $self->{"disposition"} = undef; + $self->{"filename"} = undef; + $self->{"filemtime"} = undef; + $self->{"filesize"} = undef; + # RFC 1864 Content-MD5 + $self->{"md5"} = 0; + # RFC 2387 MIME multipart/related headers/properties + $self->{"related_type"} = undef; + $self->{"related_start"} = undef; + # RFC 2369/2919 Mailing Lists headers/properties + $self->{"list_id"} = undef; + $self->{"list_help"} = undef; + $self->{"list_subscribe"} = undef; + $self->{"list_unsubscribe"} = undef; + $self->{"list_post"} = undef; + $self->{"list_owner"} = undef; + $self->{"list_archive"} = undef; + # Non-standard headers + $self->{"errors_to"} = undef; + $self->{"precedence"} = undef; + $self->{"mailer"} = "$class http://www.imacat.idv.tw/"; + $self->{"any_header"} = []; + + $self->{"boundary_len"} = 32; + + return $self; +} + +# RFC 821 headers/properties +# mail_from: Set/retrieve the MAIL FROM: sender +sub mail_from : method { + local ($_, %_); + my ($self, $email); + ($self, $email) = @_; + if (@_ > 1) { + $self->{"mail_from"} = $email; + $self->{"modified"} = 1; + } + return $self->{"mail_from"}; +} +# rcpt_to: Set/retrieve the real recipients (to be used in send()) +sub rcpt_to : method { + local ($_, %_); + my ($self, $email); + ($self, $email) = @_; + # Reset it + if (!defined $email) { + undef $self->{"rcpt_to"}; + # Add it + } else { + $self->{"rcpt_to"} = [] + if !defined $self->{"rcpt_to"} || ref $self->{"rcpt_to"} ne "ARRAY"; + %_ = map { $_ => 1 } @{$self->{"rcpt_to"}}; + push @{$self->{"rcpt_to"}}, $email + if !exists $_{$email}; + } + return undef if !defined $self->{"rcpt_to"}; + return join ",", @{$self->{"rcpt_to"}}; +} + +# RFC 822 headers/properties +# from: Set/retrieve the From: header +sub from : method { + local ($_, %_); + my ($self, $email, $name); + ($self, $email, $name) = @_; + $self->_add_addr(\$self->{"from"}, $email, $name) + if @_ > 1; + return $self->_ret_addrs($self->{"from"}); +} +# subject: Set/retrieve the subject +sub subject : method { + local ($_, %_); + my ($self, $subject); + ($self, $subject) = @_; + if (@_ > 1) { + $self->{"subject"} = $subject; + $self->{"modified"} = 1; + } + return $self->{"subject"}; +} +# sender: Set/retrieve the Sender: header +sub sender : method { + local ($_, %_); + my ($self, $email, $name); + ($self, $email, $name) = @_; + $self->_set_addr(\$self->{"sender"}, $email, $name) + if @_ > 1; + return $self->_ret_addr($self->{"sender"}); +} +# to: Set/retrieve the To: header +sub to : method { + local ($_, %_); + my ($self, $email, $name); + ($self, $email, $name) = @_; + $self->_add_addr(\$self->{"to"}, $email, $name) + if @_ > 1; + return $self->_ret_addrs($self->{"to"}); +} +# cc: Set/retrieve the Cc: header +sub cc : method { + local ($_, %_); + my ($self, $email, $name); + ($self, $email, $name) = @_; + $self->_add_addr(\$self->{"cc"}, $email, $name) + if @_ > 1; + return $self->_ret_addrs($self->{"cc"}); +} +# bcc: Set/retrieve the Bcc: header +sub bcc : method { + local ($_, %_); + my ($self, $email, $name); + ($self, $email, $name) = @_; + $self->_add_addr(\$self->{"bcc"}, $email, $name) + if @_ > 1; + return $self->_ret_addrs($self->{"bcc"}); +} +# reply_to: Set/retrieve the Reply-To: header +sub reply_to : method { + local ($_, %_); + my ($self, $email, $name); + ($self, $email, $name) = @_; + $self->_add_addr(\$self->{"reply_to"}, $email, $name) + if @_ > 1; + return $self->_ret_addrs($self->{"reply_to"}); +} + +# RFC 1521 MIME headers/properties +# charset: Set/retrieve the desired character set +# Note that this is the desired character set. The input information +# should still in UTF-8 +sub charset : method { + local ($_, %_); + my ($self, $charset); + ($self, $charset) = @_; + if (@_ > 1) { + $self->{"charset"} = $charset; + $self->{"modified"} = 1; + } + return $self->{"charset"}; +} +# type: Set/retrieve the MIME content type +sub type : method { + local ($_, %_); + my ($self, $type); + ($self, $type) = @_; + if (@_ > 1) { + $self->{"type"} = $type; + $self->{"modified"} = 1; + } + return $self->{"type"}; +} +# id: Set/retrieve the content ID. +sub id : method { + local ($_, %_); + my ($self, $id); + ($self, $id) = @_; + if (@_ > 1) { + # Set a content ID. + if ($id) { + if (!defined $self->{"id"}) { + $self->{"id"} = $self->_new_msgid; + $self->{"modified"} = 1; + } + # Unset the content ID. + } else { + if (defined $self->{"id"}) { + undef $self->{"id"}; + $self->{"modified"} = 1; + } + } + } + return $self->{"id"}; +} + +# RFC 1766 Content-Language +# lang: Set/retrieve the language +sub lang : method { + local ($_, %_); + my ($self, $lang); + ($self, $lang) = @_; + if (@_ > 1) { + # Reset it + if (!defined $lang) { + undef $self->{"lang"}; + # Add it + } else { + http_500 "bad language $lang" + unless is_usascii_printable $lang; + $lang = encode("US-ASCII", $lang) if is_utf8($lang); + $self->{"lang"} = [] + if !defined $self->{"lang"} || ref $self->{"lang"} ne "ARRAY"; + push @{$self->{"lang"}}, $lang; + } + $self->{"modified"} = 1; + } + return undef if !defined $self->{"lang"}; + return join ", ", map ln($_, LN_NAME), @{$self->{"lang"}}; +} + +# RFC 1806/2183 Content-Disposition +# disposition: Set/retrieve the MIME content disposition +# "inline" or "attachment" +sub disposition : method { + local ($_, %_); + my ($self, $disposition); + ($self, $disposition) = @_; + if (@_ > 1) { + if (!defined $disposition) { + undef $self->{"disposition"}; + } elsif ($disposition =~ /^(?:inline|attachment)$/) { + $disposition = encode("US-ASCII", $disposition) + if is_utf8($disposition); + $self->{"disposition"} = $disposition; + } else { + http_500 "bad content disposition $disposition"; + } + $self->{"modified"} = 1; + } + return $self->{"disposition"}; +} +# filename: Set/retrieve the MIME content disposition filename +sub filename : method { + local ($_, %_); + my ($self, $filename); + ($self, $filename) = @_; + if (@_ > 1) { + $self->{"filename"} = filename + $self->{"modified"} = 1; + } + return $self->{"filename"}; +} +# filemtime: Set/retrieve the MIME content disposition modification time +sub filemtime : method { + local ($_, %_); + my ($self, $filemtime); + ($self, $filemtime) = @_; + if (@_ > 1) { + http_500 "bad mtime $filemtime" + unless $filemtime =~ /^\d+$/; + $filemtime = encode("US-ASCII", $filemtime) if is_utf8($filemtime); + $self->{"filemtime"} = $filemtime; + $self->{"modified"} = 1; + } + return $self->{"filemtime"}; +} +# filesize: Set/retrieve the MIME content disposition size +sub filesize : method { + local ($_, %_); + my ($self, $filesize); + ($self, $filesize) = @_; + if (@_ > 1) { + http_500 "bad size $filesize" + unless $filesize =~ /^\d+$/; + $filesize = encode("US-ASCII", $filesize) if is_utf8($filesize); + $self->{"filesize"} = $filesize; + $self->{"modified"} = 1; + } + return $self->{"filesize"}; +} + +# RFC 1864 Content-MD5 +# md5: Set/retrieve the MD5 digest enable/disable flag +sub md5 : method { + local ($_, %_); + my ($self, $md5); + ($self, $md5) = @_; + if (@_ > 1) { + $self->{"md5"} = $md5? 1: 0; + $self->{"modified"} = 1; + } + return $self->{"md5"}; +} + +# RFC 2387 MIME multipart/related headers/properties +# related_type: Set/retrieve the multipart/related type +sub related_type : method { + local ($_, %_); + my ($self, $reltype); + ($self, $reltype) = @_; + if (@_ > 1) { + $self->{"related_type"} = $reltype; + $self->{"modified"} = 1; + } + return $self->{"related_type"}; +} +# related_start: Set/retrieve the multipart/related start +sub related_start : method { + local ($_, %_); + my ($self, $relstart); + ($self, $relstart) = @_; + if (@_ > 1) { + $self->{"related_start"} = $relstart; + $self->{"modified"} = 1; + } + return $self->{"related_start"}; +} + +# RFC 2369/2919 Mailing Lists headers/properties +# list_id: Set/retrieve the list ID. +sub list_id : method { + local ($_, %_); + my ($self, $id, $phrase); + ($self, $id, $phrase) = @_; + if (@_ > 1) { + # Reset it + if (!defined $id) { + undef $self->{"list_id"}; + # Set it + } else { + $self->{"list_id"} = { + "id" => $id, + "phrase" => $phrase, + }; + } + $self->{"modified"} = 1; + } + return undef if !defined $self->{"list_id"}; + $_ = "<" . ${$self->{"list_id"}}{"id"} . ">"; + if (defined ${$self->{"list_id"}}{"phrase"}) { + $phrase = ${$self->{"list_id"}}{"phrase"}; + $phrase = quote $phrase if rfc822_phrase_need_quoting $phrase; + $_ = "$phrase $_"; + } + return $_; +} +# list_help: Set/retrieve the list help address +sub list_help : method { + local ($_, %_); + my ($self, $url); + ($self, $url) = @_; + $self->_add_list_url(\$self->{"list_help"}, $url) + if @_ > 1; + return $self->_ret_list_urls($self->{"list_help"}); +} +# list_subscribe: Set/retrieve the list subscribe address +sub list_subscribe : method { + local ($_, %_); + my ($self, $url); + ($self, $url) = @_; + $self->_add_list_url(\$self->{"list_subscribe"}, $url) + if @_ > 1; + return $self->_ret_list_urls($self->{"list_subscribe"}); +} +# list_unsubscribe: Set/retrieve the list unsubscribe address +sub list_unsubscribe : method { + local ($_, %_); + my ($self, $url); + ($self, $url) = @_; + $self->_add_list_url(\$self->{"list_unsubscribe"}, $url) + if @_ > 1; + return $self->_ret_list_urls($self->{"list_unsubscribe"}); +} +# list_post: Set/retrieve the list post address +# "" means "List-Post: NO" +sub list_post : method { + local ($_, %_); + my ($self, $url); + ($self, $url) = @_; + if (@_ > 1) { + if ($url eq "") { + $self->{"list_post"} = ""; + } else { + $self->_add_list_url(\$self->{"list_post"}, $url); + } + } + return undef if !defined $self->{"list_post"}; + return "NO" if ref $self->{"list_post"} ne "ARRAY"; + return $self->_ret_list_urls($self->{"list_post"}); +} +# list_owner: Set/retrieve the list owner address +sub list_owner : method { + local ($_, %_); + my ($self, $url); + ($self, $url) = @_; + $self->_add_list_url(\$self->{"list_owner"}, $url) + if @_ > 1; + return $self->_ret_list_urls($self->{"list_owner"}); +} +# list_archive: Set/retrieve the list archive address +sub list_archive : method { + local ($_, %_); + my ($self, $url); + ($self, $url) = @_; + $self->_add_list_url(\$self->{"list_archive"}, $url) + if @_ > 1; + return $self->_ret_list_urls($self->{"list_archive"}); +} + +# Non-standard headers +# errors_to: Set/retrieve the Errors-To: header +sub errors_to : method { + local ($_, %_); + my ($self, $email); + ($self, $email) = @_; + if (@_ > 1) { + if (!defined $email) { + undef $self->{"errors_to"}; + } else { + $self->{"errors_to"} = []; + push @{$self->{"errors_to"}}, $email; + } + $self->{"modified"} = 1; + } + return $self->{"errors_to"}; +} + +# precedence: Set/retrieve the precedence, mentioned in RFC 2076 +# "bulk" or "first-class" +sub precedence : method { + local ($_, %_); + my ($self, $precedence); + ($self, $precedence) = @_; + if (@_ > 1) { + if (!defined $precedence) { + undef $self->{"precedence"}; + } elsif ($precedence =~ /^(?:bulk|first-class)$/) { + $precedence = encode("US-ASCII", $precedence) + if is_utf8($precedence); + $self->{"precedence"} = $precedence; + } else { + http_500 "bad precedence $precedence"; + } + $self->{"modified"} = 1; + } + return $self->{"precedence"}; +} + +# mailer: Set/retrieve the mailer +sub mailer : method { + local ($_, %_); + my ($self, $mailer); + ($self, $mailer) = @_; + if (@_ > 1) { + $self->{"mailer"} = $mailer; + $self->{"modified"} = 1; + } + return $self->{"mailer"}; +} + +# any_header: Set/retrieve any header +sub any_header : method { + local ($_, %_); + my ($self, $name, $value, $ndx); + ($self, $name, $value) = @_; + # Find the index of that header + undef $ndx; + for ($_ = 0; $_ < @{$self->{"any_header"}}; $_++) { + next if ${${$self->{"any_header"}}[$_]}{"name"} ne $name; + $ndx = $_; + last; + } + # Set the value + if (@_ > 1) { + if (defined $ndx) { + ${${$self->{"any_header"}}[$ndx]}{"value"} = $value; + } else { + # Only add a defined value + if (defined $value) { + push @{$self->{"any_header"}}, { + "name" => $name, + "value" => $value, + } + } + } + $self->{"modified"} = 1; + return $value; + # Retrieve the value + } else { + return ${${$self->{"any_header"}}[$ndx]}{"value"} + if defined $ndx; + return undef; + } +} + +# body: Set/retrieve the body +sub body : method { + local ($_, %_); + my ($self, $body); + ($self, $body) = @_; + if (@_ > 1) { + $self->{"body"} = $body; + $self->{"modified"} = 1; + } + return $self->{"body"}; +} + +# addpart: Add an MIME part +# $mail is a Selima::Mail object +sub addpart : method { + local ($_, %_); + my ($self, $mail); + ($self, $mail) = @_; + if (!defined $mail) { + $self->{"parts"} = []; + } else { + push @{$self->{"parts"}}, $mail; + } + $self->{"modified"} = 1; + return $mail; +} + +# from_file: Set the mail from a file +sub from_file : method { + local ($_, %_); + my ($self, $file); + ($self, $file) = @_; + $self->{"type"} = $MM->checktype_filename($file); + $self->{"body"} = xfread($file); + $self->{"modified"} = 1; + return; +} + +# as_attach: Set the mail as an attachment +sub as_attach : method { + local ($_, %_); + my ($self, $file, $filename); + ($self, $file, $filename) = @_; + $self->{"type"} = $MM->checktype_filename($file); + $self->{"disposition"} = "attachment"; + $self->{"filename"} = defined $filename? $filename: basename($file); + ($self->{"filemtime"}, $self->{"filesize"}) = (stat $file)[9,7]; + $self->{"body"} = xfread($file); + $self->{"modified"} = 1; + return $self->{"body"}; +} + +# as_attach_upload: Set the an attachment from $SESSION +# To be done +sub as_attach_upload : method { + local ($_, %_); + my ($self, $sn); + ($self, $sn) = @_; +} + +# add_attach: Add an attachment +sub add_attach : method { + local ($_, %_); + my ($self, $file, $filename, $attach); + ($self, $file, $filename) = @_; + if (!defined $file) { + $self->{"attaches"} = []; + } else { + # Create the attachment + $attach = new Selima::Mail; + $attach->as_attach($file, $filename); + push @{$self->{"attaches"}}, $attach; + } + $self->{"modified"} = 1; + return; +} + +# add_attach_upload: Add an attachment from $SESSION +# To be done +sub add_attach_upload : method { + local ($_, %_); + my ($self, $sn); + ($self, $sn) = @_; +} + +# send_with: Set the mail sending method +sub send_with : method { + local ($_, %_); + my ($self, $send_with); + ($self, $send_with) = @_; + # Set the value + if (@_ > 1) { + http_500 "you must specify a sending method" + if !defined $send_with; + if ($send_with eq "sendmail") { + # Check if sendmail exists + http_500 "/usr/sbin/sendmail missing" + if !-e "/usr/sbin/sendmail"; + $self->{"send_with"} = $send_with; + } elsif ($send_with eq "smtp") { + # SMTP is always possible + $self->{"send_with"} = $send_with; + } else { + http_500 "unknown sending method: $send_with"; + } + } + return $self->{"send_with"}; +} + +# output: Output the mail message +sub output : method { + local ($_, %_); + my ($self, $is_full_msg, $mail, $body, @headers); + my ($content_transfer_encoding, $boundary, $md5); + ($self, $is_full_msg) = @_; + $is_full_msg = 1 if !defined $is_full_msg; + # Output before + return $self->{"output"} + if defined $self->{"output"} && !$self->{"modified"}; + + # Set the attachment + $mail = $self->_get_attached_mail; + + # Check the message + $self->_check if $is_full_msg; + + # Set the mail body + # Set the body first, since we need to know Content-Transfer-Encoding + # and MIME multipart boundary first + $body = ""; + undef $content_transfer_encoding; + # A single content + if ( !defined $mail->{"type"} + || $mail->{"type"} !~ /^multipart\//) { + if (defined $mail->{"body"}) { + $body = $mail->{"body"}; + # A text message + if ($mail->{"type"} =~ /^text\//) { + # Encode it + # This piece of code shall be refined + $body = encode($mail->{"charset"}, $body) + if $mail->{"type"} eq "text/plain" + && !is_usascii_printable $body + && defined $mail->{"charset"}; + $body =~ s/\r\n/\n/g; + # Not in US-ASCII, containing long lines, or MD5 is in use + # encode_qp() only work with Unix "\n" text + if ( !is_usascii_printable_text $body + || $body =~ /[^\r\n]{76}/ + || $mail->{"md5"}) { + $body = encode_qp($body); + $content_transfer_encoding = "quoted-printable"; + } + $body =~ s/\n/\r\n/g; + $md5 = md5_base64($body) if $mail->{"md5"}; + + # A piece of RFC-822 e-mail message + } elsif ($mail->{"type"} =~ /^message\//) { + # Do nothing + + # A piece of binary data + } else { + $md5 = md5_base64($body) if $mail->{"md5"}; + $body = encode_base64($body, "\r\n"); + $content_transfer_encoding = "base64"; + } + } + + # A multipart MIME content + } else { + my (@parts, $everything); + @parts = map $_->output(0), @{$mail->{"parts"}}; + $everything = join "\r\n", @parts; + # Create a boundary + do { + $boundary = "=_"; + while (length $boundary < $mail->{"boundary_len"}) { + $_ = int rand 3; + if ($_ == 0) { + $boundary .= chr(ord "0" + int rand 10); + } elsif ($_ == 1) { + $boundary .= chr(ord "A" + int rand 26); + } else { + $boundary .= chr(ord "a" + int rand 26); + } + } + } until $everything !~ /$boundary/; + # Add the boundary and compose the body + $body = join "", map "--$boundary\r\n$_\r\n", @parts; + } + # Ensure a CRLF is in the end + $body =~ s/(\r\n)?$/\r\n/; + + @headers = qw(); + + # RFC 822 headers + # RFC-822 suggests the header order as: + # "Return-Path", "Received", "Date", "From", "Subject", "Sender", + # "To", "cc", etc. + # We do not set the Received: header. It is added before mail is sent. + # Set the Date: header + push @headers, "Date: " . rfc822_time . "\r\n" + if $is_full_msg; + # Set the From: header + if (defined $mail->{"from"}) { + push @headers, "From: " . $mail->_out_addrs($mail->{"from"}) . "\r\n"; + } elsif ($is_full_msg) { + @_ = getpwuid $>; + $_ = { + "name" => $_[6], + "email" => $_[0] . "@" . fqdn, + }; + push @headers, "From: " . $mail->_out_addr($_) . "\r\n"; + } + # Set the Subject: header + if (defined $mail->{"subject"}) { + $_ = $mail->{"subject"}; + $_ = b64hdr_encode $_, $mail->{"charset"}; + push @headers, "Subject: $_\r\n"; + } + # Set the Sender: header + if (defined $mail->{"sender"}) { + my $need; + $need = 0; + # Multiple From: + if (@{$mail->{"from"}} > 1) { + $need = 1; + # Different than the only From: + } else { + my ($from, $sender); + $from = ${$mail->{"from"}}[0]; + $sender = ${$mail->{"sender"}}; + if ($$from{"email"} ne $$sender{"email"}) { + $need = 1; + } elsif (!defined $$from{"name"} && defined $$sender{"name"}) { + $need = 1; + } elsif (defined $$from{"name"}) { + if (!defined $$sender{"name"}) { + $need = 1; + } elsif ($$from{"name"} ne $$sender{"name"}) { + $need = 1; + } + } + } + push @headers, "Sender: " . $mail->_out_addr($mail->{"sender"}) . "\r\n" + if $need; + } + # Set the To: header + push @headers, "To: " . $mail->_out_addrs($mail->{"to"}) . "\r\n" + if defined $mail->{"to"}; + # Set the Cc: header + push @headers, "Cc: " . $mail->_out_addrs($mail->{"cc"}) . "\r\n" + if defined $mail->{"cc"}; + # Set the Bcc: header + push @headers, "Bcc: " . $mail->_out_addrs($mail->{"bcc"}) . "\r\n" + if defined $mail->{"bcc"}; + # Destination must exist (by RFC 822 4.1) + #push @headers, "Bcc: \r\n" + # if $is_full_msg + # && !defined $mail->{"to"} + # && !defined $mail->{"cc"} + # && !defined $mail->{"bcc"}; + # Set the Reply-To: header + push @headers, "Reply-To: " . $mail->_out_addrs($mail->{"reply_to"}) . "\r\n" + if defined $mail->{"reply_to"}; + # Set the Message-ID: header + if ($is_full_msg) { + $_ = defined $mail->{"id"}? $mail->{"id"}: $mail->_new_msgid; + push @headers, "Message-ID: <$_>\r\n"; + } + + # RFC 1521 MIME headers + # Set the MIME-Version: header + push @headers, "MIME-Version: 1.0\r\n" + if $is_full_msg && defined $mail->{"type"}; + # Set the Content-Type: header + if (defined $mail->{"type"}) { + my $type; + $type = $mail->{"type"}; + $type = encode($mail->{"charset"}, $type) + if is_utf8($type) && defined $mail->{"charset"}; + $type .= "; charset=" . $mail->{"charset"} + if $type =~ /^text\// && defined $mail->{"charset"}; + # Attachment filename -- deprecated + #if (defined $mail->{"filename"}) { + # $_ = $mail->{"filename"}; + # $_ = b64hdr_encode $_, $mail->{"charset"}; + # $_ = quote $_ if rfc1521_value_need_quoting $_; + # $type .= ";\r\n name=$_"; + #} + if ($type =~ /^multipart\//) { + # Add type and start parameter to multipart/related + if ($type eq "multipart/related") { + $_ = ${$mail->{"parts"}}[0]->type + if !defined($_ = $mail->{"related_type"}); + $_ = encode($mail->{"charset"}, $_) + if is_utf8($_) && defined $mail->{"charset"}; + $type .= ";\r\n type=\"$_\""; + # "start" parameter is broken in most e-mail client (??? why?) + #$_ = ${$mail->{"parts"}}[0]->id(1) + # if !defined($_ = $mail->{"related_start"}); + #$_ = encode($mail->{"charset"}, $_) + # if is_utf8($_) && defined $mail->{"charset"}; + #$type .= ";\r\n start=\"$_\""; + + } + $type .= ";\r\n boundary=\"$boundary\""; + } + push @headers, "Content-Type: $type\r\n"; + } + # Set the Content-ID: header + # Do not generate Content-ID for complete messages. Complete + # messages has Message-ID instead. + push @headers, "Content-ID: <" . $mail->{"id"} . ">\r\n" + if !$is_full_msg && defined $mail->{"id"}; + # Set the Content-Transfer-Encoding: header + push @headers, "Content-Transfer-Encoding: $content_transfer_encoding\r\n" + if defined $content_transfer_encoding; + + # RFC 1766 Content-Language + push @headers, join ", ", map ln($_, LN_NAME), @{$mail->{"lang"}} + if defined $mail->{"lang"}; + + # RFC 1806/2183 Content-Disposition + if (defined $mail->{"disposition"}) { + my $disposition; + $disposition = $mail->{"disposition"}; + if (defined $mail->{"filename"}) { + # Note: Eudora cannot handle encoded MIME parameter values + $_ = $mail->{"filename"}; + $_ = b64hdr_encode $_, $mail->{"charset"}; + $_ = quote $_ if rfc1521_value_need_quoting $_; + $disposition .= ";\r\n filename=$_"; + } + $disposition .= ";\r\n modification-date=\"" + . rfc822_time($mail->{"filemtime"}) . "\"" + if defined $mail->{"filemtime"}; + $disposition .= ";\r\n size=" . $mail->{"filesize"} + if defined $mail->{"filesize"}; + push @headers, "Content-Disposition: $disposition\r\n"; + } + # RFC 1864 Content-MD5 + push @headers, "Content-MD5: $md5\r\n" if $mail->{"md5"}; + + # RFC 2369/2919 Mailing Lists headers + # Set the List-ID: header + if (defined $mail->{"list_id"}) { + $_ = ${$mail->{"list_id"}}{"id"}; + $_ = encode($mail->{"charset"}, $_) + if is_utf8($_) && defined $mail->{"charset"}; + $_ = "<$_>"; + if (defined ${$mail->{"list_id"}}{"phrase"}) { + my $phrase; + $phrase = ${$mail->{"list_id"}}{"phrase"}; + $phrase = quote $phrase if rfc822_phrase_need_quoting $phrase; + $phrase = b64hdr_encode $phrase, $mail->{"charset"}; + $_ = "$phrase $_"; + } + push @headers, "List-ID: $_\r\n"; + } + # Set the List-Help: header + push @headers, "List-Help: " + . $mail->_out_list_urls($mail->{"list_help"}) . "\r\n" + if defined $mail->{"list_help"}; + # Set the List-Subscribe: header + push @headers, "List-Subscribe: " + . $mail->_out_list_urls($mail->{"list_subscribe"}) . "\r\n" + if defined $mail->{"list_subscribe"}; + # Set the List-Unsubscribe: header + push @headers, "List-Unsubscribe: " + . $mail->_out_list_urls($mail->{"list_unsubscribe"}) . "\r\n" + if defined $mail->{"list_unsubscribe"}; + # Set the List-Post: header + if (defined $mail->{"list_post"}) { + $_ = ref $mail->{"list_post"} eq "ARRAY"? + $mail->_out_list_urls($mail->{"list_post"}): "NO"; + push @headers, "List-Post: $_\r\n"; + } + # Set the List-Owner: header + push @headers, "List-Owner: " + . $mail->_out_list_urls($mail->{"list_owner"}) . "\r\n" + if defined $mail->{"list_owner"}; + # Set the List-Archive: header + push @headers, "List-Archive: " + . $mail->_out_list_urls($mail->{"list_archive"}) . "\r\n" + if defined $mail->{"list_archive"}; + + # Set the Errors-To: header + push @headers, "Errors-To: " . join(", ", $mail->{"errors_to"}) . "\r\n" + if $is_full_msg && defined $mail->{"errors_to"}; + + # Set the Precedence: header + push @headers, "Precedence: " . $mail->{"precedence"} . "\r\n" + if $is_full_msg && defined $mail->{"precedence"}; + + # Set the X-Mailer: header + if ($is_full_msg && defined $mail->{"mailer"}) { + $_ = $mail->{"mailer"}; + $_ = encode($mail->{"charset"}, $_) + if is_utf8($_) && defined $mail->{"charset"}; + push @headers, "X-Mailer: " . $mail->{"mailer"} . "\r\n"; + } + + # Compose it + $self->{"output"} = join("", @headers) . "\r\n" . $body; + $self->{"modified"} = 0; + return $self->{"output"}; +} + +# send: Send the mail message +sub send : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Send the mail with Sendmail + if ($self->{"send_with"} eq "sendmail") { + return $self->_send_with_sendmail; + # Send the mail with SMTP + } elsif ($self->{"send_with"} eq "smtp") { + return $self->_send_with_smtp; + } +} + + +# _new_msgid: Obtain a new message ID. +sub _new_msgid : method { + local ($_, %_); + my ($sec, $msec, $sn, $fqdn); + # Epoch time and minisecond + $sec = int($_ = Time::HiRes::time); + $msec = int(($_ - $sec) * 1000000); + # A random serial number + do { + $sn = int rand 10000; + } until !exists $Mail_MSGIDS{$sn}; + $Mail_MSGIDS{$sn} = 1; + # Compose it + return sprintf "%10d.%06d.%05d.%04d.selima@%s", + $sec, $msec, $$, $sn, fqdn; +} + +# _get_attached_mail: Get the mail with its attachment +# Actually, this will convert the mail to multipart/mixed +# and add the attachments +sub _get_attached_mail : method { + local ($_, %_); + my ($self, $mail); + $self = $_[0]; + # Make a copy of myself + $mail = $self; + + # Return myself if there is no attachment + return $mail if @{$mail->{"attaches"}} == 0; + + # Not multipart/mixed -- convert to multipart/mixed + unless (defined $mail->{"type"} && $mail->{"type"} eq "multipart/mixed") { + # Pass the content to the body part + my $body; + $body = new Selima::Mail; + $body->{"charset"} = $mail->{"charset"}; + $body->{"type"} = $mail->{"type"}; + $body->{"id"} = $mail->{"id"}; + $body->{"lang"} = $mail->{"lang"}; + $body->{"md5"} = $mail->{"md5"}; + # Set the body + # The origin is multipart/xxx + if ( defined $mail->{"type"} + && $mail->{"type"} =~ /^multipart\//) { + $body->{"parts"} = $mail->{"parts"}; + } else { + $body->{"body"} = $mail->{"body"}; + } + # Reset these values + $mail->{"parts"} = []; + undef $mail->{"body"}; + $mail->{"type"} = "multipart/mixed"; + undef $mail->{"id"}; + undef $mail->{"lang"}; + $mail->{"md5"} = 0; + $mail->addpart($body); + } + + # Add each attachment + $mail->addpart($_) foreach @{$mail->{"attaches"}}; + + return $mail; +} + +# _set_addr: Set an address +sub _set_addr : method { + local ($_, %_); + my ($self, $addr, $email, $name); + ($self, $addr, $email, $name) = @_; + # Reset it + if (!defined $email) { + undef $$addr; + # Set it + } else { + $$addr = { + "name" => $name, + "email" => $email, + }; + } + $self->{"modified"} = 1; +} +# _add_addr: Add an address to an address list +sub _add_addr : method { + local ($_, %_); + my ($self, $list, $email, $name); + ($self, $list, $email, $name) = @_; + # Reset it + if (!defined $email) { + undef $$list; + # Add it + } else { + $$list = [] if !defined $$list || ref $$list ne "ARRAY"; + push @$$list, { + "name" => $name, + "email" => $email, + }; + } + $self->{"modified"} = 1; +} + +# _ret_addr: Return an address +sub _ret_addr : method { + local ($_, %_); + my ($self, $addr, $name); + ($self, $addr) = @_; + return undef if !defined $addr; + return $$addr{"email"} if !defined $$addr{"name"}; + $name = $$addr{"name"}; + $name = quote $name if rfc822_phrase_need_quoting $name; + return sprintf "%s <%s>", $name, $$addr{"email"}; +} +# _ret_addrs: Return a list of addresses +sub _ret_addrs : method { + local ($_, %_); + my ($self, $list); + ($self, $list) = @_; + return undef if !defined $list; + return join ", ", map $self->_ret_addr($_), @$list; +} + +# _out_addr: Output an address +sub _out_addr : method { + local ($_, %_); + my ($self, $addr, $name, $email); + ($self, $addr) = @_; + $email = $$addr{"email"}; + $email = encode($self->{"charset"}, $email) + if is_utf8($email) && defined $self->{"charset"}; + return $email if !defined $$addr{"name"}; + $name = $$addr{"name"}; + $name = quote $name if rfc822_phrase_need_quoting $name; + $name = b64hdr_encode $name, $self->{"charset"}; + return sprintf "%s <%s>", $name, $email; +} +# _out_addrs: Output a list of addresses +sub _out_addrs : method { + local ($_, %_); + my ($self, $list); + ($self, $list) = @_; + return join ",\r\n ", map $self->_out_addr($_), @$list; +} + +# _add_list_url:Add a list URL to a list URL list +sub _add_list_url : method { + local ($_, %_); + my ($self, $list, $url); + ($self, $list, $url) = @_; + # Reset it + if (!defined $url) { + undef $$list; + # Add it + } else { + $$list = [] if !defined $$list || ref $$list ne "ARRAY"; + push @$$list, $url; + } + $self->{"modified"} = 1; +} +# _ret_list_urls: Return a list of list URLs +sub _ret_list_urls : method { + local ($_, %_); + my ($self, $list); + ($self, $list) = @_; + return join ", ", map "<$_>", @$list; +} +# _out_list_urls: Output a list of list URLs +sub _out_list_urls : method { + local ($_, %_); + my ($self, $list); + ($self, $list) = @_; + @_ = @$list; + if (defined $self->{"charset"}) { + foreach (@_) { + $_ = encode($self->{"charset"}, $_) if is_utf8($_); + } + } + return join ",\r\n ", map "<$_>", @_; +} +# _out_trace: Output the trace information (the Received: header) +# See RFC 2821 4.4 Trace Information +sub _out_trace : method { + local ($_, %_); + my ($self, @trace_info); + my ($from_address_literal, $from_tcpinfo_domain, $from_tcp_info); + my ($by_address_literal, $by_domain, $by_tcpinfo_domain, $by_tcp_info); + $self = $_[0]; + # The trace information + @trace_info = qw(); + + # From-domain + # mod_perl: use Apache->request->connection->remote_ip + $from_address_literal = $IS_MODPERL? ($IS_MP2? + Apache2::RequestUtil->request->connection->remote_ip: + Apache->request->connection->remote_ip): + $ENV{"REMOTE_ADDR"}; + $from_tcpinfo_domain = gethostbyaddr inet_aton($from_address_literal), AF_INET; + if (!defined $from_tcpinfo_domain) { + $from_tcp_info = sprintf "[%s]", $from_address_literal; + } else { + $from_tcp_info = sprintf "%s [%s]", + $from_tcpinfo_domain, $from_address_literal; + } + push @trace_info, "from webclient ($from_tcp_info)"; + + # The invoking user, as a from comment + if (!defined get_login_sn) { + $_ = "invoked by anonymous web user" + . " country " . country_lookup; + } else { + $_ = "invoked by web user " . get_login_id + . " S/N " . get_login_sn + . " country " . country_lookup; + } + push @trace_info, "($_)"; + + # By-domain + # Apache implementation + $by_address_literal = is_apache? $ENV{"SERVER_ADDR"}: + # Microsoft IIS implementation + is_iis? $ENV{"LOCAL_ADDR"}: + # Else, do DNS query + inet_ntoa(scalar gethostbyname $ENV{"SERVER_NAME"}); + if (exists $ENV{"HTTP_HOST"}) { + $by_domain = $ENV{"HTTP_HOST"}; + $by_domain =~ s/:\d+$//; + } else { + $by_domain = $by_address_literal; + } + $by_tcpinfo_domain = gethostbyaddr inet_aton($by_address_literal), AF_INET; + if (!defined $by_tcpinfo_domain) { + $by_tcp_info = sprintf "[%s]", $by_address_literal; + } else { + $by_tcp_info = sprintf "%s [%s]", + $by_tcpinfo_domain, $by_address_literal; + } + push @trace_info, sprintf("by %s (%s)", $by_domain, $by_tcp_info); + + # VIA Link and WITH Protocol + push @trace_info, "via TCP with HTTP"; + + # For recipients + push @trace_info, "for " . join(" ", map "<$_>", @_) + if (@_ = $self->_get_rcpts) > 0; + + return sprintf("Received: %s ;\r\n\t%s\r\n", + join("\r\n\t", @trace_info), rfc822_time); +} + +# _check: Check if it is ready to be output +# Refer to RFC 822 +sub _check : method { + local ($_, %_); + my $self; + $self = $_[0]; + # When no valid From: exists, default to the current user of the running process + # Check if a valid Sender: exists with multiple From: + http_500 "Multiple From: without a valid Sender: (RFC-822)" + if defined $self->{"from"} + && @{$self->{"from"}} > 1 + && !defined $self->{"sender"}; + # Check if valid contents exist + http_500 "MIME Multipart without any valid part" + if defined $self->{"type"} + && $self->{"type"} =~ /^multipart\// + && $self->{"parts"} == 0; +} + +# _get_sender: Collect the sender +sub _get_sender : method { + local ($_, %_); + my ($self, $fallback); + ($self, $fallback) = @_; + $fallback = 0 if !defined $fallback; + # MAIL FROM: specified + return $self->{"mail_from"} + if defined $self->{"mail_from"}; + # Sender specified + return ${$self->{"sender"}}{"email"} + if defined $self->{"sender"}; + # Obtain the sender from From: + return ${${$self->{"from"}}[0]}{"email"} + if defined $self->{"from"}; + # Nothing left + return undef if !$fallback; + # Use the current user + return (getpwuid $>)[0] . "@" . fqdn; +} + +# _get_rcpts: Collect the recipients list +sub _get_rcpts : method { + local ($_, %_); + my ($self, @rcpts); + $self = $_[0]; + # Recipients specified + return @{$self->{"rcpt_to"}} + if defined $self->{"rcpt_to"}; + + # Obtain the recipients from To:, Cc: and Bcc: + @rcpts = qw(); + %_ = qw(); + @_ = qw(); + push @_, @{$self->{"to"}} if defined $self->{"to"}; + push @_, @{$self->{"cc"}} if defined $self->{"cc"}; + push @_, @{$self->{"bcc"}} if defined $self->{"bcc"}; + foreach (@_) { + next if exists $_{$$_{"email"}}; + push @rcpts, $$_{"email"}; + $_{$$_{"email"}} = 1; + } + return @rcpts; +} + +# _send_with_sendmail: Send the mail with Sendmail +sub _send_with_sendmail : method { + local ($_, %_); + my ($self, $sender, @rcpts, $SENDMAIL); + $self = $_[0]; + # Get the sender + $sender = $self->_get_sender; + # Collect the Recipients list + @rcpts = $self->_get_rcpts; + # No recipients found + http_500 "No recipients found\n" + if @rcpts == 0; + + # Obtain the mail content + $_ = $self->_out_trace . $self->output; + # Sendmail must escape "."s on a line. See RFC 821 SMTP 4.5.2 + s/^(\.+\r)/.$1/gm; + + # Send with Sendmail + @_ = qw(/usr/sbin/sendmail -odb); + push @_, ("-f", $sender) if defined $sender; + push @_, @rcpts; + open $SENDMAIL, "|-", @_ or http_500 $_[0] . ": $!"; + print $SENDMAIL $_ or http_500 $_[0] . ": $!"; + close $SENDMAIL or http_500 $_[0] . ": $!"; + return; +} + +# _send_with_smtp: Send the mail with SMTP +sub _send_with_smtp : method { + local ($_, %_); + my ($self, $sender, @rcpts, $SMTP); + $self = $_[0]; + # Get the sender + $sender = $self->_get_sender(1); + # Collect the Recipients list + @rcpts = $self->_get_rcpts; + # No recipients found + http_500 "No recipients found\n" + if @rcpts == 0; + + # Obtain the mail content + $_ = $self->_out_trace . $self->output; + # SMTP must escape lines with leading "."s. See RFC 821 SMTP 4.5.2 + # Net::SMTP does this for me. + + # Send with SMTP + $SMTP = new Net::SMTP(SMTP_HOST) or http_500 "$!"; + $SMTP->mail($sender, Size=>length $_) or http_500 "MAIL FROM:<$sender>: " . $SMTP->code . " " . $SMTP->message; + foreach (@rcpts) { + $SMTP->to($_) or http_500 "RCPT TO:<$_>:: " . $SMTP->code . " " . $SMTP->message; + } + $SMTP->data or http_500 "DATA: " . $SMTP->code . " " . $SMTP->message; + $SMTP->datasend($_) or http_500 "DATA: " . $SMTP->code . " " . $SMTP->message; + $SMTP->dataend($_) or http_500 "DATA: " . $SMTP->code . " " . $SMTP->message; + $SMTP->quit or http_500 "QUIT: " . $SMTP->code . " " . $SMTP->message; + return; +} + +####################### +# Below are Functions # +####################### +# quote: Quote a text string +# Quoting is REQUIRED for CR and \ and ", by RFC 822 3.4.1 # " gettext +sub quote($) { + local ($_, %_); + $_ = $_[0]; + s/\\/\\\\/g; + s/"/\\"/g; + s/\r/\\\r/g; + return "\"$_\""; +} +# rfc822_phrase_need_quoting: Whether a phrase need to be quoted by RFC-822 +sub rfc822_phrase_need_quoting($) { + return $_[0] =~ /[()<>@,;:\\"\.\[\]\x01-\x1F\x7F]/; # " gettext +} +# rfc1521_value_need_quoting: Whether a value need to be quoted by RFC-1521 +sub rfc1521_value_need_quoting($) { + return $_[0] =~ /[()<>@,;:\\"\/\[\]\?= \x01-\x1F\x7F]/; # " gettext +} +# b64hdr_encode: Encode a piece of header text with Base-64 +# Refer to RFC-1522 4.1 +sub b64hdr_encode($$) { + local ($_, %_); + my ($text, $charset); + ($text, $charset) = @_; + # US-ASCII printable -- no need to encode it + return $text if is_usascii_printable $text; + # No desired character set available + return $text if !defined $charset; + # Successfully encoded + return "=?$charset?B?" . encode_base64($_, "") . "?=" + if eval { $_ = encode($charset, $text, FB_CROAK); 1; }; + # Else -- send in UTF-8 + $_ = encode("UTF-8", $text, FB_CROAK); + return "=?UTF-8?B?" . encode_base64($_, "") . "?="; +} +# rfc822_time: Output the time as RFC-822 +# Day should be displayed as one digit, without the padding space. +sub rfc822_time(;$) { + local ($_, %_); + $_ = $_[0]; + $_ = time if !defined $_; + return sprintf time2str("%a, %%d %b %Y %X %z", $_), (localtime $_)[3]; +} + +return 1; diff --git a/lib/perl5/Selima/MarkAbbr.pm b/lib/perl5/Selima/MarkAbbr.pm new file mode 100644 index 0000000..49e9895 --- /dev/null +++ b/lib/perl5/Selima/MarkAbbr.pm @@ -0,0 +1,92 @@ +# Selima Website Content Management System +# MarkAbbr.pm: The subroutine to mark the abbreviations. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-24 + +package Selima::MarkAbbr; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(h_abbr markabbr); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub h_abbr($); +sub markabbr($); +} + +use Selima::DataVars qw($MAIN); +use Selima::ShortCut; + +# h_abbr: Shortcut to markabbr(h()) +sub h_abbr($) { return markabbr(h($_[0])); } + +# markabbr: Mark the abbreviation +sub markabbr($) { + local ($_, %_); + $_ = $_[0]; + my $localext; + + # FAQ + s/\b(FAQ)\b(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/g; + # HTTP + s/\b(HTTP)\b(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/g; + # HTML + s/\b(HTML)\b(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/g; + # CGI + s/\b(CGI)\b(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/g; + # SSL + s/\b(SSL)\b(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/g; + # PDF + s/\b(PDF)\b(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/g; + # CSV + s/\b(CSV)\b(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/g; + # IP + s/\b(IP)\b(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/g; + # S/N + s/\b(S\/N)\b(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/g; + # No. + s/\b(No\.|Num\.)(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/g; + # ID. + s/\bID\.(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/g; + # Pic. + s/\bPic\.(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/g; + # URL. + s/\b(URL\b\.?)(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/g; + # E-mail + s/\b(E-mail)\b(?!<\/abbr>|<\/acronym>)/$1<\/acronym>/gi; + # MIME + s/\b(MIME\b\.?)(?!<\/abbr>|<\/acronym>)/$1<\/acronym>/g; + # Perl/PHP/GNU + s/\b(Perl)\b(?!<\/abbr>|<\/acronym>)/$1<\/acronym>/gi; + s/\b(PHP)\b(?!<\/abbr>|<\/acronym>)/$1<\/abbr>/gi; + s/\b(GNU)\b(?!<\/abbr>|<\/acronym>)/$1<\/acronym>/gi; + # KB/MB/GB/TB from report_size() + s/(\d+) KB\)/$1 KB<\/abbr>/g; + s/(\d+) KB\)/$1 MB<\/abbr>/g; + s/(\d+) KB\)/$1 GB<\/abbr>/g; + s/(\d+) KB\)/$1 TB<\/abbr>/g; + # Load the local extension + # Load it at last to prevent mark-up recursion + $_ = &$localext($_) if defined($localext = $MAIN->can("markabbr_site")); + return $_; +} + +return 1; diff --git a/lib/perl5/Selima/MkAllDir.pm b/lib/perl5/Selima/MkAllDir.pm new file mode 100644 index 0000000..cf19615 --- /dev/null +++ b/lib/perl5/Selima/MkAllDir.pm @@ -0,0 +1,169 @@ +# Selima Website Content Management System +# MkAllDir.pm: The subroutines to create/remove directories and subdirectories at once. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-25 + +package Selima::MkAllDir; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(mkalldir rmoldpage rmoldfile); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub mkalldir($); +sub rmoldpage($;$); +sub rmoldfile($;$); +sub dir_not_empty($); +} + +use File::Spec; +use File::Basename qw(dirname); + +use Selima::DataVars qw(:l10n :lninfo :requri); +use Selima::HTTP; +use Selima::LnInfo; +use Selima::XFileIO; + +# mkalldir: Create all the components of a directory +# Input: Directory name $dir. It does not check at all. +sub mkalldir($) { + local ($_, %_); + $_ = $_[0]; + # Standardize it + $_ = File::Spec->canonpath($_); + @_ = File::Spec->splitdir($_); + $_ = File::Spec->catdir(shift @_); + while (@_ > 0) { + $_ = File::Spec->catdir($_, shift @_); + next if -e $_; + mkdir $_ or http_500 "$_: $!"; + } + return; +} + +# rmoldpage: Remove the old page before creating a new one +# Input: The old page path $oldpage to be removed, and an optional new page +# path $newpage to be compared with. It does not check at all. +# Path is without $DOC_ROOT +sub rmoldpage($;$) { + local ($_, %_); + my ($oldpage, $newpage, $oldfile, $newfile); + ($oldpage, $newpage) = @_; + + $oldpage =~ s/\/$/\/index.html/; + # The new file is supplied to be compared with + if (defined $newpage) { + $newpage =~ s/\/$/\/index.html/; + # Return if unchanged + return if $oldpage eq $newpage; + } + + $oldfile = $DOC_ROOT . $oldpage; + if (defined $newpage) { + $newfile = $DOC_ROOT . $newpage; + rmoldfile($oldfile, $newfile); + } else { + rmoldfile($oldfile); + } + return; +} + +# rmoldfile: Remove the old file before creating a new one +# Input: The old file $oldfile to be removed, and an optional new file +# $newfile to be compared with. It does not check at all +sub rmoldfile($;$) { + local ($_, %_); + my ($oldfile, $newfile, $parent, @dirs); + ($oldfile, $newfile) = @_; + + # The new file is unchanged + return if defined $newfile && $oldfile eq $newfile; + + # Obtain the parent directory + $parent = dirname($oldfile); + # Return if its parent is not a directory + return unless -d $parent; + # Remove the file + @_ = qw(); + push @_, ($oldfile, "$oldfile.html", "$oldfile.xhtml"); + foreach my $lnfile (map ln($_, LN_FILENAME), @ALL_LINGUAS) { + push @_, ("$oldfile.$lnfile", "$oldfile.$lnfile.html", "$oldfile.$lnfile.xhtml"); + } + foreach (@_) { + next unless -f $_ || -l $_; + # We can delete this file + if (-w $parent) { + unlink $_; + # We cannot delete the file -- Empty it if possible + } else { + xfwrite $_, "" if -f $_ && -w $_; + } + } + + # Get all sections of the new file + if (defined $newfile) { + @_ = File::Spec->splitdir(dirname($newfile)); + for ($_ = 1, @dirs = (File::Spec->catdir($_[0])); $_ < @_; $_++) { + unshift @dirs, File::Spec->catdir($dirs[0], $_[$_]); + } + %_ = map { $_ => 1 } @dirs; + } else { + %_ = qw(); + } + # Get all sections of the old file + @_ = File::Spec->splitdir($oldfile); + for ($_ = 1, @dirs = (File::Spec->catdir($_[0])); $_ < @_; $_++) { + unshift @dirs, File::Spec->catdir($dirs[0], $_[$_]); + } + + # Remove the parents as much as possible and necessary + for ($_ = 0; $_ < @dirs - 1; $_++) { + # Coincident with the new path ends + return if exists $_{$dirs[$_]}; + # Skip to the next parent if directory not exists + next if !-e $dirs[$_]; + # We cannot remove, or the directory is not empty + return if !-w $dirs[$_+1] || !-d $dirs[$_] || dir_not_empty $dirs[$_]; + # Remove this directory + rmdir $dirs[$_]; + } +} + +# dir_not_empty: Check if a directory is empty +sub dir_not_empty($) { + local ($_, %_); + my ($dir, $DH); + $dir = $_[0]; + + opendir $DH, $dir or http_500 "$dir: $!"; + while (defined($_ = readdir $DH)) { + # A real entry is found + if ($_ ne "." && $_ ne "..") { + closedir $DH or http_500 "$dir: $!"; + return 1; + } + } + # No real entry was found + closedir $DH or http_500 "$dir: $!"; + return 0; +} + +return 1; diff --git a/lib/perl5/Selima/MungAddr.pm b/lib/perl5/Selima/MungAddr.pm new file mode 100644 index 0000000..3a21048 --- /dev/null +++ b/lib/perl5/Selima/MungAddr.pm @@ -0,0 +1,60 @@ +# Selima Website Content Management System +# MungAddr.pm: The subroutines to hide e-mail addresses from spammers' e-mail collectors. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-31 + +package Selima::MungAddr; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(mung_address_at unmung_address_at mung_email_span); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub mung_address_at($); +sub unmung_address_at($); +sub mung_email_span($); +} + +# mung_address_at: Mung mail addresses with " at " +sub mung_address_at($) { + local ($_, %_); + $_ = $_[0]; + s/@/ at /g; + return $_; +} + +# unmung_address_at: Un-mung mail addresses with " at " +sub unmung_address_at($) { + local ($_, %_); + $_ = $_[0]; + s/ at /@/g; + return $_; +} + +# mung_email_span: Mung mail addresses with @ +sub mung_email_span($) { + local ($_, %_); + $_ = $_[0]; + s/@/@<\/span>/g; + return $_; +} + +return 1; diff --git a/lib/perl5/Selima/NewSN.pm b/lib/perl5/Selima/NewSN.pm new file mode 100644 index 0000000..109862a --- /dev/null +++ b/lib/perl5/Selima/NewSN.pm @@ -0,0 +1,92 @@ +# Selima Website Content Management System +# NewSN.pm: The new S/N generator. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-03 + +package Selima::NewSN; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(newsn newsn_hash newsn_xmltab); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub newsn($); +sub newsn_hash(%); +sub newsn_xmltab($); +} + +use Selima::DataVars qw($DBH); + +use constant SN_LEN => 9; + +# The relevent variables +use vars qw($MIN $MAX $INT); +$MIN = 10 ** (SN_LEN - 1); # 100000000 +$MAX = (10 ** SN_LEN) - 1; # 999999999 +$INT = $MAX - $MIN + 1; + +# newsn: Generate a new random serial number for a database table +sub newsn($) { + local ($_, %_); + my ($table, $sth, $sql); + $table = $_[0]; + + do { + # Generate a random serial number + $_ = $MIN + int rand $INT; + # Check if this serial number exists + $sql = "SELECT sn FROM $table WHERE sn=$_;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + } until $sth->rows == 0; + + return $_; +} + +# newsn_hash: Generate a new random serial number +sub newsn_hash(%) { + local ($_, %_); + my %SN = @_; + + do { + # Generate a random serial number + $_ = $MIN + int rand $INT; + } until !exists $SN{$_}; + + return $_; +} + +# newsn_xmltab: Generate a new random serial number +sub newsn_xmltab($) { + local ($_, %_); + my $SN = $_[0]; + + do { + # Generate a random serial number + $_ = $MIN + int rand $INT; + } until !exists ${$SN}{$_}; + + ${$SN}{$_} = (keys %{$SN}); + + return $_; +} + +return 1; diff --git a/lib/perl5/Selima/Page.pm b/lib/perl5/Selima/Page.pm new file mode 100644 index 0000000..aa4e905 --- /dev/null +++ b/lib/perl5/Selima/Page.pm @@ -0,0 +1,187 @@ +# Selima Website Content Management System +# Page.pm: A web page. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-02-26 + +package Selima::Page; +use 5.008; +use strict; +use warnings; + +use Selima::HTTP; + +#use Selima::PageList; + +# new: Initialize the web page +sub new : method { + local ($_, %_); + my ($class, %args, $self); + ($class, %args) = @_; + $self = bless {}, $class; + # Set the title + http_500 "Please specify the page title." + if !exists $args{"title"}; + $self->{"title"} = $args{"title"}; + # Set the page path + http_500 "Please specify the page path." + if !exists $args{"path"}; + $self->{"path"} = $args{"path"}; + # Set the order + $self->{"ord"} = exists $args{"ord"}? $args{"ord"}: 5000; + return $self; +} + +# title: Set/return the page title +sub title : method { + local ($_, %_); + my ($self, $title); + ($self, $title) = @_; + if (@_ > 1) { + http_500 "Please specify the page title." + unless defined $title; + $self->{"title"} = $title; + } + return $self->{"title"}; +} + +# path: Set/return the page path +sub path : method { + local ($_, %_); + my ($self, $path); + ($self, $path) = @_; + if (@_ > 1) { + http_500 "Please specify the page path." + unless defined $path; + $self->{"path"} = $path; + } + return $self->{"path"}; +} + +# ord: Set/return the page order +sub ord : method { + local ($_, %_); + my ($self, $ord); + ($self, $ord) = @_; + if (@_ > 1) { + http_500 "Please specify the page order." + unless defined $ord; + $self->{"ord"} = $ord; + } + return $self->{"ord"}; +} + +# addsub: Add the page under this page +sub addsub : method { + local ($_, %_); + my ($self, @pages); + ($self, @pages) = @_; + http_500 "Cannot add sub pages under pages that are not directory indices." + unless $self->{"path"} =~ /\/$/; + if (!exists $self->{"sub"}) { + $self->{"sub"} = new Selima::PageList(); + $self->{"sub"}->index($self); + } + $self->{"sub"}->add($_) foreach @pages; + return; +} + +# compare_to: Compare the order with another page +sub compare_to : method { + local ($_, %_); + my ($self, $another); + ($self, $another) = @_; + # We only compare to another Selima::Page object + http_500 "The compare_to() method of a Selima::Page object only accepts another Selima::Page object." + if ref $another ne "Selima::Page"; + # Check the page order + return ($self->ord < $another->ord? -1: 1) + if $self->ord != $another->ord; + # Check the page path + return $self->path cmp $another->path + if $self->path ne $another->path; + # Check the page title (should not) + return $self->title cmp $another->title + if $self->title ne $another->title; + return 0; +} + + +# Selima::PageList: A list of pages +package Selima::PageList; +use 5.008; +use strict; +use warnings; + +use Selima::HTTP; + +# new: Initialize the handler +sub new : method { + local ($_, %_); + my ($class, @pages, $self); + ($class, @pages) = @_; + $self = bless {}, $class; + $self->{"pages"} = []; + $self->add(@pages); + return $self; +} + +# add: Add web pages to the page list +sub add : method { + local ($_, %_); + my ($self, @pages); + ($self, @pages) = @_; + # Add all the pages + foreach my $page (@pages) { + # We only accept Selima::Page objects + http_500 "The add() method of a Selima::PageList object only accepts Selima::Page objects." + if ref $page ne "Selima::Page"; + # Find the page after the added page + for ($_ = 0; $_ < @{$self->{"pages"}}; $_++) { + last if $page->compare_to(${$self->{"pages"}}[$_]) < 0; + } + # Insert the page + $self->{"pages"} = [ + @{$self->{"pages"}}[0..$_-1], + $page, + @{$self->{"pages"}}[$_..$#{$self->{"pages"}}] + ]; + } + return; +} + +# index: Set/return the index page +sub index : method { + local ($_, %_); + my ($self, $page); + ($self, $page) = @_; + # We only accept a Selima::Page object + if (@_ > 1) { + # Delete it + if (!defined $page) { + delete $self->{"index"}; + # Set it + } else { + http_500 "The index() method of a Selima::PageList object only accepts a Selima::Page object." + if ref $page ne "Selima::Page"; + $self->{"index"} = $page; + } + } + return exists $self->{"index"}? $self->{"index"}: undef; +} + +return 1; diff --git a/lib/perl5/Selima/Page2Rel.pm b/lib/perl5/Selima/Page2Rel.pm new file mode 100644 index 0000000..76c9233 --- /dev/null +++ b/lib/perl5/Selima/Page2Rel.pm @@ -0,0 +1,137 @@ +# Selima Website Content Management System +# Page2Rel.pm: The converter to turn absolute URLs in HTML to relative URLs. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-24 + +package Selima::Page2Rel; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(page2rel page2abs); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub page2rel($$); +sub page2abs($$); +} + +use Encode qw(is_utf8); + +use Selima::Unicode; + +# page2rel: Convert URLs in a page to relative +sub page2rel($$) { + local ($_, %_); + my ($page, $base); + ($page, $base) = @_; + $_ = new Selima::Page2Rel::Converter($base, 1); + return $_->convert($page); +} + +# page2abs: Convert URLs in a page to absolute +sub page2abs($$) { + local ($_, %_); + my ($page, $base); + ($page, $base) = @_; + $_ = new Selima::Page2Rel::Converter($base, 0); + return $_->convert($page); +} + + +# Selima::Page2Rel::Converter: convert URLs in a page to relative +package Selima::Page2Rel::Converter; +use 5.008; +use strict; +use warnings; + +use HTML::Tagset qw(); +# HTML::Tagset does not export anything +use vars qw(%LINKELE); +$LINKELE{$_} = { map { $_ => 1 } @{$HTML::Tagset::linkElements{$_}} } + foreach keys %HTML::Tagset::linkElements; + +use Selima::AbsURI; +use Selima::DataVars qw(:absuri); +use Selima::RelURI; +use Selima::ShortCut; + +# new: Initialize the converter +sub new : method { + local ($_, %_); + my ($class, $base, $is_rel, $self); + ($class, $base, $is_rel) = @_; + $self = bless {}, $class; + $self->{"base"} = $base; + $self->{"is_rel"} = $is_rel; + return $self; +} + +# convert: Convert URLs in a page to relative/absolute +sub convert : method { + local ($_, %_); + my $self; + ($self, $_) = @_; + s/(|<[a-z]+\d?(?:\s+[a-z\-]+(?:=(?:"[^"]*"|'[^']*'|[^"'\s<>]+))?)*(?:\s+\/|\s*)?>)/$self->cnvtele($1);/gesi; # ' gettext + return $_; +} + +# cnvtele: Convert URLs in an element to relative/absolute +sub cnvtele : method { + local ($_, %_); + my $self; + ($self, $_) = @_; + # Skip the comments + return $_ unless /^<([a-z]+\d?)/; + # A link element + if (exists $LINKELE{$1}) { + $self->{"attrs"} = $LINKELE{$1}; + s/(?<=\s)([a-z\-]+(?:=(?:"[^"]*"|'[^']*'|[^"'\s<>]+))?)/$self->cnvtattr($1);/gei; # ' gettext + } + # External language handlers + # To be done + return $_; +} + +# cnvtattr: Convert URLs in an attribute to relative/absolute +sub cnvtattr : method { + local ($_, %_); + my ($self, $name, $quote); + ($self, $_) = @_; + # Skip attributes without a value + return $_ unless /^([a-z\-]+)=("[^"]*"|'[^']*'|[^"'\s<>]+)$/; # ' gettext + ($name, $_) = ($1, $2); + # Skip non-link attributes + return "$name=$_" unless exists ${$self->{"attrs"}}{$name}; + + # Strip the quotation + s/^(["']?)(.+)\1/$quote = $1; $2;/e; # " gettext + # Decode the HTML characters + $_ = dh($_); + # Convert it + $_ = $self->{"is_rel"}? reluri($_, $self->{"base"}): + absuri($_, $self->{"base"}, ABSURI_SKIP_FRAGMENT); + # Encode the HTML characters + $_ = h($_); + # Add the quotation + $_ = "$quote$_$quote" if $quote ne ""; + return "$name=$_"; +} + +return 1; diff --git a/lib/perl5/Selima/PageFunc.pm b/lib/perl5/Selima/PageFunc.pm new file mode 100644 index 0000000..023b53a --- /dev/null +++ b/lib/perl5/Selima/PageFunc.pm @@ -0,0 +1,255 @@ +# Selima Website Content Management System +# PageFunc.pm: The web page related subroutines. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-15 + +package Selima::PageFunc; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(page_param page_all_linguas hash_tree outpage rebuildtype_options); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub page_param(;$); +sub page_all_linguas($); +sub hash_tree($); +sub outpage($$;$); +sub rebuildtype_options($); +} + +use Config qw(%Config); +use Devel::Symdump; +use File::Basename qw(basename dirname); + +use Selima::AbsURI; +use Selima::DataVars qw($DBH :dataman :l10n :lninfo :output :rebuild :requri :scptconf); +use Selima::EchoForm; +use Selima::GetLang; +use Selima::Guest; +use Selima::LnInfo; +use Selima::MkAllDir; +use Selima::Page2Rel; +use Selima::ScptPriv; +use Selima::ShortCut; +use Selima::Unicode; +use Selima::XFileIO; + +# page_param: Gather page parameters +sub page_param(;$) { + local ($_, %_); + my $args; + $args = $_[0]; + # Default to an empty array + $args = {} if !defined $args; + return $args if exists $$args{".fixed"}; + + # Obtain page parameters + $args = {%$ALT_PAGE_PARAM, %$args} if defined $ALT_PAGE_PARAM; + $args = {%$PAGE_PARAM, %$args} if defined $PAGE_PARAM; + + # Set the path + $$args{"path"} = $REQUEST_PATH + if !exists $$args{"path"}; + # Set the language + $$args{"lang"} = getlang + if !exists $$args{"lang"}; + # Set if static or not + $$args{"static"} = 0 + if !exists $$args{"static"}; + # Set if show a pretty result or not + $$args{"clean"} = 0 + if !exists $$args{"clean"}; + # Set if this page is administrative + $$args{"admin"} = is_admin_script $$args{"path"} + if !exists $$args{"admin"}; + # Set if this is a preview page or not + $$args{"preview"} = undef + if !exists $$args{"preview"}; + # Set if we shoud show the tite in html_header() or not + $$args{"no_auto_title"} = 0 + if !exists $$args{"no_auto_title"}; + # Set all the available languages + $$args{"all_linguas"} = [@ALL_LINGUAS] + if !exists $$args{"all_linguas"}; + # Set the language of the title + $$args{"title_lang"} = $$args{"lang"} + if !exists $$args{"title_lang"}; + # The upper level index page + if (!exists $$args{"up"}) { + if ($$args{"path"} !~ /\/(?:errors|picdesc)\//) { + $$args{"up"} = $$args{"path"}; + $$args{"up"} =~ s/[^\/]+\/?$//; + # Remove the /cgi-bin/ directory + $$args{"up"} =~ s/\/cgi-(?:bin|perl|raw)\/$/\//; + } + } + + # Load the local extension when available + $args = &$_($args) if defined $MAIN + && defined $MAIN->can("page_param_site"); + $args = &$_($args) if defined $MAIN + && defined $MAIN->can("page_param_script"); + + # Tag that we have fixed it + $$args{".fixed"} = 1; + return $args; +} + +# page_all_linguas: Get the available languages for this page +sub page_all_linguas($) { + local ($_, %_); + my ($page, $lndb); + $page = $_[0]; + + # It is specified + return @{$$page{"all_linguas"}} + if exists $$page{"all_linguas"}; + + # Preview + if (exists $$page{"preview"} && $$page{"preview"}) { + my ($sql, $sth, $count, $row); + # Uni-lingual + return (getlang) unless $DBH->is_ml_table($THIS_TABLE); + # Find the page + return (getlang) unless exists $$page{"sn"}; + $sql = "SELECT * FROM $THIS_TABLE" + . " WHERE sn=" . $$page{"sn"} . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + # If this record exist + return (getlang) if $sth->rows == 0; + $row = $sth->fetchrow_hashref; + # Check each language + @_ = qw(); + foreach my $lang (@ALL_LINGUAS) { + $lndb = ln $lang, LN_DATABASE; + # Add it if the page for this language exists + push @_, $lang if defined $$row{"title_$lndb"} + || $lang eq getlang; + } + return @_; + } + + # $page is uni-lingual + return (getlang) if exists $$page{"title"}; + + # $page is multi-lingual + # Check each language + @_ = qw(); + foreach my $lang (@ALL_LINGUAS) { + $lndb = ln $lang, LN_DATABASE; + # Skip if the page for this language does not exist + push @_, $lang if defined $$page{"title_$lndb"}; + } + return @_; +} + +# hash_tree: Make a hash of the page tree +sub hash_tree($) { + local ($_, %_); + my ($tree, %hash); + $tree = $_[0]; + # The index page + $hash{${$$tree{"index"}}{"path"}} = $tree + if exists $$tree{"index"}; + # Track the subdirectories + if (exists $$tree{"pages"}) { + for ($_ = 0; $_ < @{$$tree{"pages"}}; $_++) { + # A subdirectory exists + if (exists ${${$$tree{"pages"}}[$_]}{"sub"}) { + %hash = (%hash, + hash_tree ${${$$tree{"pages"}}[$_]}{"sub"}); + } + } + } + return %hash; +} + +# outpage: Output a page +sub outpage($$;$) { + local ($_, %_); + my ($html, $path, $lang, $file); + ($html, $path, $lang) = @_; + $lang = getlang if !defined $lang; + + # Convert the URLs to relative + if ($path =~ /^\/errors\//) { + $html = page2abs $html, $path; + $html =~ s/href="\/errors\/(\$url)"/href="$1"/g; + $html =~ s/href="$path(#.+?)"/href="$1"/g; + } else { + $html = page2rel $html, $path; + } + # Encode the e-mail at-signs (@) + $html =~ s/@/@/g; + # Decode the e-mail at-signs (@) of spamtrap + $html =~ s/spamtrap@/spamtrap@/g; + # Encode the page to the target character set + $html = page_encode($html, ln($lang, LN_CHARSET)); + # Obtain the real file name + $file = $DOC_ROOT . $path; + $file .= "index.html" if $file =~ /\/$/; + $file .= "." . ln($lang, LN_FILENAME) if @ALL_LINGUAS > 1; + # Create the necessary directories + mkalldir dirname($file); + # Write the file + xfupdate_template "$file.xhtml", $html; + # Make the symbolic link for the text/html + if (defined $Config{"d_symlink"}) { + my ($targfile, $linkfile); + ($targfile, $linkfile) = (basename("$file.xhtml"), "$file.html"); + unless (-l $linkfile && readlink $linkfile eq $targfile) { + unlink $linkfile if -l $linkfile; + symlink $targfile, $linkfile; + } + } + + return; +} + +# rebuildtype_options: Obtain a rebuild type options list +sub rebuildtype_options($) { + local ($_, %_); + my $value; + $value = $_[0]; + # The type labels + %_ = ( + "pages" => C_("Web pages"), + "news" => C_("News"), + "links" => C_("Related links"), + "home" => C_("Home page"), + "all" => C_("Whole web site"), + map { $_ => __($REBUILD_LABELS{$_}) } keys %REBUILD_LABELS, + ); + + # Get the available rebuild types + @_ = map { + "value" => $_, + "content" => (exists $_{$_}? $_{$_}: $_), + }, sort grep s/^.+::rebuild_([^:]+)$/$1/, + Devel::Symdump->new($MAIN)->functions; + # Obtain the HTML + $_ = opt_list_array @_; + + return preselect_options($_, $value); +} + +return 1; diff --git a/lib/perl5/Selima/Passwd.pm b/lib/perl5/Selima/Passwd.pm new file mode 100644 index 0000000..0ada6a4 --- /dev/null +++ b/lib/perl5/Selima/Passwd.pm @@ -0,0 +1,129 @@ +# Selima Website Content Management System +# Passwd.pm: The subroutines to manipulate passwords that are temporarily stored between password forms. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-26 + +package Selima::Passwd; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(sync_saved_passwd); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub sync_saved_passwd($$); +sub suspend($); +sub ret($); +sub prev_valid($$); +} + +use Selima::DataVars qw($SESSION); +use Selima::Encrypt; +use Selima::NewSN; + +# This use symmetric encryption/decryption. It is not safe. +# Nothing is exported. Use it by the full package name + +# sync_saved_passwd: Set the passwords with the password registry +sub sync_saved_passwd($$) { + local ($_, %_); + my ($FORM, $dummy); + ($FORM, $dummy) = @_; + + # Do not process again + return if defined $FORM->param("_sync_saved_passwd"); + # The passwd field + if (defined $FORM->param("passwd")) { + # Empty password is provided. Restore to the old password. + if ($FORM->param("passwd") eq "") { + $FORM->delete("passid"); + # A new password is provided + } elsif ($FORM->param("passwd") ne $dummy) { + $FORM->param("passid", suspend $FORM->param("passwd")); + # A previous valid password exists + } elsif (prev_valid "passid", $FORM) { + $FORM->param("passwd", ret $FORM->param("passid")); + # Invalid previous password. Restore to the old password. + } else { + $FORM->delete("passid"); + $FORM->param("passwd", ""); + } + } + # The passwd2 field + if (defined $FORM->param("passwd2")) { + # Empty password is provided. Restore to the old password. + if ($FORM->param("passwd2") eq "") { + $FORM->delete("passid2"); + # A new password is provided + } elsif ($FORM->param("passwd2") ne $dummy) { + $FORM->param("passid2", suspend $FORM->param("passwd2")); + # A previous valid password exists + } elsif (prev_valid "passid2", $FORM) { + $FORM->param("passwd2", ret $FORM->param("passid2")); + # Invalid previous password. Restore to the old password. + } else { + $FORM->delete("passid2"); + $FORM->param("passwd2", ""); + } + } + $FORM->param("_sync_saved_passwd", 1); + return; +} + +# suspend: Suspend a password +sub suspend($) { + local ($_, %_); + my ($password, $passid); + $password = $_[0]; + + # Initialize the password registry + $$SESSION{"savepass"} = {} + if !defined $$SESSION{"savepass"}; + + # Generate a new random password ID + $passid = newsn_hash %{$$SESSION{"savepass"}}; + ${$$SESSION{"savepass"}}{$passid} = encrypt $password; + $SESSION->flush; + return $passid; +} + +# ret: Retrieve a password +sub ret($) { + local ($_, %_); + my $passid; + $passid = $_[0]; + return decrypt ${$$SESSION{"savepass"}}{$passid}; +} + +# prev_valid: If there is a previously-saved password +sub prev_valid($$) { + my ($col, $FORM); + ($col, $FORM) = @_; + + # Password ID does not exist + return 0 if !defined $FORM->param($col); + # Password registry not initialized yet + return 0 if !defined $$SESSION{"savepass"}; + # Password does not exists in the registry + return 0 if !exists ${$$SESSION{"savepass"}}{$FORM->param($col)}; + return 1; +} + +return 1; diff --git a/lib/perl5/Selima/Picture.pm b/lib/perl5/Selima/Picture.pm new file mode 100644 index 0000000..2af5a58 --- /dev/null +++ b/lib/perl5/Selima/Picture.pm @@ -0,0 +1,257 @@ +# Selima Website Content Management System +# Picture.pm: The subroutines to manipulate the pictures. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-27 + +package Selima::Picture; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(@PIC_VALID_POS PIC_POS_DEFAULT); +push @EXPORT, qw(pic_exists echopic picpos_label pic_deposit); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub picurl($;$); +sub picinfo($;$); +sub picstyle($;$); +sub check_pic_ratio($\$); +sub best_pic_ratio($); +sub newpicx($;$); +sub newpicy($;$); +sub pic_exists(\$); +sub echopic(\$$;$); +sub picpos_label($); +sub pic_deposit(); +} + +use GD; +use Math::Round qw(round); +use POSIX qw(floor); +use Regexp::Common; +use URI::Escape qw(uri_escape); + +use Selima::Cache qw(:picture); +use Selima::ChkFunc; +use Selima::DataVars qw($SESSION); +use Selima::ShortCut; + +use constant PIC_MAX_WIDTH => 800; +use constant PIC_MAX_HEIGHT => 1024; +use constant PIC_MAX_RATIO => 9.99; +use vars qw(@PIC_VALID_POS %PIC_POS_LABEL); +@PIC_VALID_POS = qw(L R); +%PIC_POS_LABEL = ( + "L" => N_("Left-aligned"), + "R" => N_("Right-aligned")); +use constant PIC_POS_DEFAULT => "L"; +use constant SHOWPIC_SCRIPT => "/magicat/cgi-bin/showpic.cgi"; + +# picurl: Get the picture display URL +sub picurl($;$) { + local ($_, %_); + my ($pic, $ratio); + ($pic, $ratio) = @_; + # Default ratio to the picture ratio + if (!defined $ratio) { + # Set the default picture ratio to 1 + $$pic{"ratio"} = 1 if !exists $$pic{"ratio"}; + $ratio = $$pic{"ratio"}; + } + # Compose the fields list + @_ = qw(); + # Add the columns + push @_, "sn=" . uri_escape($$pic{"sn"}); + push @_, "ratio=" . uri_escape($ratio); + return SHOWPIC_SCRIPT . "?" . join("&", @_); +} + +# picinfo: Return the picture infomation +sub picinfo($;$) { + local ($_, %_); + my ($pic, $ratio, $x, $y); + ($pic, $ratio) = @_; + $ratio = 1 if !defined $ratio; + # Original size not recorded yet + if (!exists $$pic{"width"} || !exists $$pic{"height"}) { + $_ = GD::Image->new($$pic{"content"}); + $$pic{"width"} = $_->width; + $$pic{"height"} = $_->height; + } + $x = newpicx $pic, $ratio; + $y = newpicy $pic, $ratio; + return sprintf C_("Width: [#,_1], height: [#,_2], ratio: [sprintf,%0.2f,_3]", $x, $y, $ratio); +} + +# picstyle: Return the picture style +sub picstyle($;$) { + local ($_, %_); + my ($pic, $ratio, $x, $y); + ($pic, $ratio) = @_; + $ratio = 1 if !defined $ratio; + # Original size not recorded yet + if (!exists $$pic{"width"} || !exists $$pic{"height"}) { + $_ = GD::Image->new($$pic{"content"}); + $$pic{"width"} = $_->width; + $$pic{"height"} = $_->height; + } + $x = newpicx $pic, $ratio; + $y = newpicy $pic, $ratio; + return sprintf "height: %dpx; width: %dpx;", $y, $x; +} + +# check_pic_ratio: Check the sanity of the picture ratio +sub check_pic_ratio($\$) { + local ($_, %_); + my ($pic, $ratio); + ($pic, $ratio) = @_; + # Check if the resize ratio is valid + return {"msg"=>N_("Please specify a numeric ratio.")} + unless $$ratio =~ /^$RE{"num"}{"real"}$/; + $$ratio += 0; + return {"msg"=>N_("Please specify a positive ratio.")} + if $$ratio <= 0; + return {"msg"=>N_("Please specify a ratio less than or equal to [sprintf,%0.2f,_1]."), + "margs"=>[PIC_MAX_RATIO]} + if $$ratio > PIC_MAX_RATIO; + # The resulted picture is over the limit + return {"msg"=>N_("This image is too large to display.")} + if newpicx $pic, $ratio > PIC_MAX_WIDTH + || newpicy $pic, $ratio > PIC_MAX_HEIGHT; + # OK + return; +} + +# best_pic_ratio: Get the best ratio of a picture +sub best_pic_ratio($) { + local ($_, %_); + my ($pic, $rx, $ry); + $pic = $_[0]; + # Return the cache + return $$pic{"best_ratio"} if !exists $$pic{"best_ratio"}; + + # Original size not recorded yet + if (!exists $$pic{"width"} || !exists $$pic{"height"}) { + $_ = GD::Image->new($$pic{"content"}); + $$pic{"width"} = $_->width; + $$pic{"height"} = $_->height; + } + # Good + return ($$pic{"best_ratio"} = 1) + if PIC_MAX_RATIO >= 1 + && $$pic{"width"} <= PIC_MAX_WIDTH + && $$pic{"height"} <= PIC_MAX_HEIGHT; + # Too large + # Find the largest proper ratio + $rx = floor(PIC_MAX_WIDTH*100 / $$pic{"width"})/100; + $ry = floor(PIC_MAX_HEIGHT*100 / $$pic{"height"})/100; + # Use the smallest among them + return ($$pic{"best_ratio"} = (sort $rx, $ry, PIC_MAX_RATIO)[0]); +} + +# newpicx: Calculate the new picture x +sub newpicx($;$) { + local ($_, %_); + my ($pic, $ratio); + ($pic, $ratio) = @_; + # Original size not recorded yet + $$pic{"width"} = GD::Image->new($$pic{"content"})->width + if !exists $$pic{"width"}; + # No calculation needed + return $$pic{"width"} if $ratio == 1; + $_ = round($$pic{"width"} * $ratio); + # Smallest 1 + $_ = 1 if $_ == 0; + return $_; +} + +# newpicy: Calculate the new picture y +sub newpicy($;$) { + local ($_, %_); + my ($pic, $ratio); + ($pic, $ratio) = @_; + # Original size not recorded yet + $$pic{"height"} = GD::Image->new($$pic{"content"})->height + if !exists $$pic{"height"}; + # No calculation needed + return $$pic{"height"} if $ratio == 1; + $_ = round($$pic{"height"} * $ratio); + # Smallest 1 + $_ = 1 if $_ == 0; + return $_; +} + +# pic_exists: Check if a picture exists +sub pic_exists(\$) { + local ($_, %_); + my ($sn, $PICS); + $sn = $_[0]; + # Check the validity of the serial number first + return 0 if !check_sn $$sn; + $PICS = pic_deposit; + return 0 if !exists $$PICS{$$sn}; + return 1; +} + +# echopic: Output a picture +sub echopic(\$$;$) { + local ($_, %_); + my ($pic, $alt, $ratio, $error, $url, $style, $picinfo, $html); + ($pic, $alt, $ratio) = @_; + if (!defined $ratio) { + $ratio = best_pic_ratio $pic; + } else { + $error = check_pic_ratio $pic, $ratio; + $ratio = best_pic_ratio $pic if defined $error; + } + $style = h(picstyle $pic, $ratio); + $picinfo = h(picinfo $pic, $ratio); + $url = h(picurl $pic, $ratio); + $alt = h($alt); + $html = << "EOT"; +$alt
    + $picinfo +EOT + chomp $html; + return $html; +} + +# picpos_label: Output the label of a picture position +sub picpos_label($) { return $PIC_POS_LABEL{$_[0]}; } + +# pic_deposit: Return a picture deposit +sub pic_deposit() { + local ($_, %_); + # Session in use + if (defined $SESSION) { + $$SESSION{"savepics"} = {} + if !defined $$SESSION{"savepics"}; + return $$SESSION{"savepics"}; + + # Session not in use + } else { + return \%Picture_pic_deposit; + } +} + +return 1; diff --git a/lib/perl5/Selima/Preview.pm b/lib/perl5/Selima/Preview.pm new file mode 100644 index 0000000..cbf567b --- /dev/null +++ b/lib/perl5/Selima/Preview.pm @@ -0,0 +1,154 @@ +# Selima Website Content Management System +# Preview.pm: The subroutines to handle the HTML output of the page preview. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-07 + +package Selima::Preview; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(fetch_preview html_preview html_preview_mark); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub fetch_preview(); +sub html_preview(); +sub html_preview_mark(;$); +} + +use Fcntl qw(:flock); + +use Selima::DataVars qw($DBH :dataman :input :rebuild :requri :scptconf); +use Selima::CallForm; +use Selima::HTTP; +use Selima::Page2Rel; +use Selima::PageFunc; +use Selima::ReqURI; +use Selima::ShortCut; + +# fetch_preview: Retrieve a previously suspended preview from, +# from $SESSION or database +sub fetch_preview() { + local ($_, %_); + my $source; + # S/N not specified + return {"msg"=>N_("The following field was not received: \"[_1]\"."), + "margs"=>["sn"], + "isform"=>0} + if !defined $GET->param("sn"); + # Check the source to retrieve the preview form + $source = "session"; + if (defined $GET->param("source")) { + # Retrieve from the database + if ($GET->param("source") eq "db") { + $source = "db"; + # Retrieve from the $SESSION saveform + } elsif ($GET->param("source") eq "session") { + $source = "session"; + # Other preview sources + } else { + return {"msg"=>N_("Unknown preview source: \"[_1]\"."), + "margs"=>[$GET->param("source")], + "isform"=>0} + } + } + + # Retrieve the preview form + # Retrieve from the database + if ($source eq "db") { + # Fetch with fetch_curitem() + $_ = $MAIN->can("fetch_curitem"); + &$_(); + %PREVIEW = %CURRENT; + # Retrieve from the $SESSION saveform + } elsif ($source eq "session") { + %PREVIEW = retrieve_form($GET->param("sn"))->Vars; + return {"msg"=>N_("Unknown preview form: \"[_1]\"."), + "margs"=>[$GET->param("sn")], + "isform"=>0} + if keys %PREVIEW == 0 + } + # Tag that this is a preview content + $PREVIEW{"preview"} = 1; + # OK + return; +} + +# html_preview: Display the preview +sub html_preview() { + local ($_, %_); + my ($lang, $html); + $lang = exists $PREVIEW{"lang"}? $PREVIEW{"lang"}: undef; + # Lock the required tables + $DBH->lock(map { $_ => LOCK_SH } @REBUILD_TABLES); + $_ = $MAIN->can("compose_page"); + $html = &$_({%PREVIEW}, $lang); + $html = page2rel(page2abs($html, $PREVIEW{"path"}), $REQUEST_PATH); + print $html; + return; +} + +# html_preview_mark: Print the HTML preview mark +sub html_preview_mark(;$) { + local ($_, %_); + my ($args, $source, $uri, $title, $ret); + $args = $_[0]; + # Obtain the page parameters + $args = page_param $args; + # This is only for the preview + return unless defined $$args{"preview"}; + + # Decide the data source + $source = "session"; + if (defined $GET->param("source")) { + # Retrieve from the database + if ($GET->param("source") eq "db") { + $source = "db"; + # Retrieve from the $SESSION saveform + } elsif ($GET->param("source") eq "session") { + $source = "session"; + # Other preview sources + } else { + http_500 C_("Unknown preview source: \"[_1]\".", $GET->param("source")); + } + } + + # Retrieve from the database + if ($source eq "db") { + $uri = h($REQUEST_PATH . "?form=cur&sn=" . $GET->param("sn")); + # Retrieve from the $SESSION saveform + } elsif ($source eq "session") { + $uri = h($REQUEST_PATH . "?formid=" . $GET->param("sn")); + } + $title = h(C_("Preview")); + $ret = h(C_("Finish preview and return.")); + + print << "EOT"; +
    +

    $title

    +

    $ret

    +
    + +EOT + + return; +} + +return 1; diff --git a/lib/perl5/Selima/Processor.pm b/lib/perl5/Selima/Processor.pm new file mode 100644 index 0000000..467aa42 --- /dev/null +++ b/lib/perl5/Selima/Processor.pm @@ -0,0 +1,316 @@ +# Selima Website Content Management System +# Processor.pm: The base data processor. + +# Copyright (c) 2005-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2005-06-30 + +package Selima::Processor; +use 5.008; +use strict; +use warnings; + +use Selima::AddCol; +use Selima::DataVars qw($DBH :addcol :dataman :l10n); +use Selima::GetLang; +use Selima::Guest; +use Selima::HTTP; +use Selima::ShortCut; +use Selima::Unicode; + +# Load these classes +use Selima::Processor::User; +use Selima::Processor::Group; +use Selima::Processor::UserMem; +use Selima::Processor::GroupMem; +use Selima::Processor::UserPref; +use Selima::Processor::ScptPriv; +use Selima::Processor::ListPref; + +use Selima::Processor::Guestbook; +use Selima::Processor::Page; +use Selima::Processor::LinkCat; +use Selima::Processor::Link; +use Selima::Processor::LinkCatz; + +use Selima::Processor::Rebuild; +use Selima::Processor::Deletion; +use Selima::Processor::LogOut; +use Selima::Processor::Category; +use Selima::Processor::Categorz; + +use Selima::Processor::AcctSubj; +use Selima::Processor::AcctTrx; +use Selima::Processor::AcctRec; +use Selima::Processor::ListPref::AcctReps; + +# The relevent variables +use constant NEWSN_LEN => 9; +use vars qw($NEWSN_MIN $NEWSN_MAX $NEWSN_INT); +$NEWSN_MIN = 10 ** (NEWSN_LEN - 1); # 100000000 +$NEWSN_MAX = (10 ** NEWSN_LEN) - 1; # 999999999 +$NEWSN_INT = $NEWSN_MAX - $NEWSN_MIN + 1; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($class, $form, $table, $self); + ($class, $form, $table) = @_; + $self = bless {}, $class; + $self->{"form"} = $form; + $self->{"table"} = $table; + $self->{"pres"} = []; + $self->{"subs"} = []; + $self->{"type"} = $self->{"form"}->param("form") + if defined $self->{"form"}->param("form"); + $self->{"step"} = $self->{"form"}->param("step") + if defined $self->{"form"}->param("step"); + $self->{"sn"} = $self->{"form"}->param("sn") + if defined $self->{"form"}->param("sn"); + # The current item + $self->{"cur"} = new CGI({%CURRENT}); + # The user request + $self->{"req"} = new CGI({%REQUEST}); + $self->{"is_sql"} = 1; + $self->{"update_timestamp"} = 1; + return $self; +} + +# process: Process the form, fully +sub process : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Submitted but not confirmed yet + return {"preview"=>1} if !defined $self->{"form"}->param("confirm"); + + # Save the column deposit + $self->_save_cols; + # Not modified + return $self->_ret_status unless $self->_modified; + + # Begin the SQL transaction + $DBH->begin_work if $self->{"is_sql"}; + # Update the columns + $self->_update_cols; + # Rebuild a limited part of pages + $self->_rebuild_partial_pages; + # Perform tasks other than column updates + $self->_other_tasks; + # Commit the SQL transaction + $DBH->commit if $self->{"is_sql"}; + + # Log and return the process status + $self->_actlog; + return $self->_ret_status; +} + +################### +# Methods belows are to be called by other processors. Do not call them directly. +# Override them when needed. +################### +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my $self; + $self = $_[0]; + return unless exists $self->{"type"}; + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + } + return; +} + +################### +# Methods belows are private. Do not call them directly. +# Override them when needed. +################### +# _update_cols: Update the columns +sub _update_cols : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Run the pre-processing sub-processors + foreach (@{$self->{"pres"}}) { + $_->_update_cols if $_->_modified; + } + + # Process the update + if ($self->{"is_sql"} && exists $self->{"type"}) { + # A form to create a new item + if ($self->{"type"} eq "new" && exists $self->{"cols"}) { + $_ = "INSERT INTO " . $self->{"table"} + . " " . $self->{"cols"}->ret($self->{"update_timestamp"}) . ";\n"; + $DBH->gdo($_); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur" && exists $self->{"cols"} && exists $self->{"sn"}) { + $_ = "UPDATE " . $self->{"table"} + . " " . $self->{"cols"}->ret($self->{"update_timestamp"}) + . " WHERE sn=" . $self->{"sn"} . ";\n"; + $DBH->gdo($_); + + # A form to delete a current item + } elsif ($self->{"type"} eq "del" && exists $self->{"sn"}) { + $_ = "DELETE FROM " . $self->{"table"} + . " WHERE sn=" . $self->{"sn"} . ";\n"; + $DBH->gdo($_); + } + } + + # Run the sub-processors + foreach (@{$self->{"subs"}}) { + $_->_update_cols if $_->_modified; + } + return; +} + +# _rebuild_partial_pages: Rebuild a limited part of pages +# Empty by default. Put page building code here. +sub _rebuild_partial_pages : method {} + +# _other_tasks: Perform tasks other than column updates +# Empty by default. +sub _other_tasks : method {} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my $self; + $self = $_[0]; + # A form to create a new item + return gactlog "Create a record with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the record with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the record with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This record was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This record has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This record has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This record has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +# _form: Return a specific form value +# Return undef if that column is empty +sub _form : method { + local ($_, %_); + my ($self, $name); + ($self, $name) = @_; + return scalar $self->{"form"}->param($name); +} + +################### +# Methods belows are private. Do not call them directly. +# Do not override them, either. +################### +# _modified: If the item is modified +sub _modified : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Modification status checked before + return $self->{"modified"} if exists $self->{"modified"}; + # Return true for addition and deletion processors + return ($self->{"modified"} = 1) + if exists $self->{"type"} && $self->{"type"} ne "cur"; + # Return true if the columns are modified + return ($self->{"modified"} = 1) + if exists $self->{"cols"} && $self->{"cols"}->modified; + # Return true if any of the subprocessors is modified + foreach (@{$self->{"pres"}}) { + return ($self->{"modified"} = 1) if $_->_modified; + } + foreach (@{$self->{"subs"}}) { + return ($self->{"modified"} = 1) if $_->_modified; + } + # Not modified + return ($self->{"modified"} = 0); +} + +# _zhsync: Automatic Traditional Chinese to Simplified Chinese conversion +sub _zhsync : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # Skip unless multilingual + return unless @ALL_LINGUAS > 1; + # Skip unless we are in Traditional Chinese, and there is Simplified Chinese + %_ = map { $_ => 1 } @ALL_LINGUAS; + return unless getlang eq "zh-tw" && exists $_{"zh-cn"}; + # A form to create a new item + if ($self->{"type"} eq "new") { + foreach my $col ($DBH->cols_ml($self->{"table"})) { + $self->{"cols"}->addstr($col . "_zhcn", all_to_simp($_)) + if defined($_ = $form->param($col)); + } + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + foreach my $col ($DBH->cols_ml($self->{"table"})) { + $self->{"cols"}->addstr($col . "_zhcn", all_to_simp($_), $cur->param($col . "_zhcn")) + if defined($_ = $form->param($col)); + } + } +} + +# _new_sn: Generate a new random serial number for an SQL table +sub _new_sn : method { + local ($_, %_); + my ($self, $sql, $sth); + $self = $_[0]; + + do { + # Generate a random serial number + $_ = $NEWSN_MIN + int rand $NEWSN_INT; + # Check if this serial number exists + $sql = "SELECT sn FROM " . $self->{"table"} + . " WHERE sn=$_;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + } until $sth->rows == 0; + + return $_; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/AcctRec.pm b/lib/perl5/Selima/Processor/AcctRec.pm new file mode 100644 index 0000000..2cbda9d --- /dev/null +++ b/lib/perl5/Selima/Processor/AcctRec.pm @@ -0,0 +1,134 @@ +# Selima Website Content Management System +# AcctRec.pm: The accounting record data processor. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-23 + +package Selima::Processor::AcctRec; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::Accounting; +use Selima::DataVars qw(:addcol); +use Selima::Guest; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "acctrecs" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + if ($self->{"type"} ne "del") { + # Set the debit/credit status + if (defined $form->param("type")) { + if ($form->param("type") eq "credit") { + $form->param("credit", 1); + } elsif ($form->param("type") eq "debit") { + $form->delete("credit"); + } + } + } + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("trx", $self->_form("trx")); + $self->{"cols"}->addbool("credit", $self->_form("credit")); + $self->{"cols"}->addnum("ord", $self->_form("ord")); + $self->{"cols"}->addnum("subj", $self->_form("subj")); + $self->{"cols"}->addstr("summary", $self->_form("summary")); + $self->{"cols"}->addnum("amount", $self->_form("amount")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("trx", $self->_form("trx"), scalar $cur->param("trx")); + $self->{"cols"}->addbool("credit", $self->_form("credit"), scalar $cur->param("credit")); + $self->{"cols"}->addnum("ord", $self->_form("ord"), scalar $cur->param("ord")); + $self->{"cols"}->addnum("subj", $self->_form("subj"), scalar $cur->param("subj")); + $self->{"cols"}->addstr("summary", $self->_form("summary"), scalar $cur->param("summary")); + $self->{"cols"}->addnum("amount", $self->_form("amount"), scalar $cur->param("amount")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create an accounting record " + . (defined $form->param("credit")? "credit": "debit") + . " number " . $form->param("ord") + . " of transaction " . accttrx_id($form->param("trx")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the accounting record " + . (defined $form->param("credit")? "credit": "debit") + . " number " . $form->param("ord") + . " of transaction " . accttrx_id($form->param("trx")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the accounting record " + . ($cur->param("credit")? "credit": "debit") + . " number " . $cur->param("ord") + . " of transaction " . accttrx_id($cur->param("trx")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This accounting record was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This accounting record has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This accounting record has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This accounting record has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/AcctSubj.pm b/lib/perl5/Selima/Processor/AcctSubj.pm new file mode 100644 index 0000000..e0a3454 --- /dev/null +++ b/lib/perl5/Selima/Processor/AcctSubj.pm @@ -0,0 +1,117 @@ +# Selima Website Content Management System +# AcctSubj.pm: The accounting subject data processor. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-08-23 + +package Selima::Processor::AcctSubj; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw(:addcol); +use Selima::Guest; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "acctsubj" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + if ($self->{"type"} ne "del") { + # Set the "topmost" parent + $form->delete("parent") if defined $form->param("topmost") + && $form->param("topmost") eq "true"; + } + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("parent", $self->_form("parent")); + $self->{"cols"}->addstr("code", $self->_form("code")); + $self->{"cols"}->addstr("title", $self->_form("title")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("parent", $self->_form("parent"), scalar $cur->param("parent")); + $self->{"cols"}->addstr("code", $self->_form("code"), scalar $cur->param("code")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create an accounting subject of code " . $form->param("code") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the accounting subject of code " . $form->param("code") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the accounting subject of code " . $cur->param("code") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This accounting subject was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This accounting subject has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This accounting subject has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This accounting subject has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/AcctTrx.pm b/lib/perl5/Selima/Processor/AcctTrx.pm new file mode 100644 index 0000000..9623413 --- /dev/null +++ b/lib/perl5/Selima/Processor/AcctTrx.pm @@ -0,0 +1,449 @@ +# Selima Website Content Management System +# AcctTrx.pm: The accounting transaction data processor. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-09-23 + +package Selima::Processor::AcctTrx; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::Accounting; +use Selima::DataVars qw($DBH :addcol :dataman); +use Selima::Format; +use Selima::Guest; +use Selima::ShortCut; + +use Selima::Processor::AcctRec; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "accttrx" if @_ < 2; + $self = $class->SUPER::new(@_); + $self->{"fix_ord"} = 1; + $self->{"subtype"} = $self->{"form"}->param("formsub"); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur, $o, $sum, $myord); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + + if ($self->{"type"} ne "del") { + # Supply the omitting debit/credit record + # A form to fill in a cash expense transaction + if ($self->{"subtype"} eq "expense") { + $sum = 0; + foreach (grep /^debt\d+amount$/, $form->param) { + $sum += $form->param($_) if $form->param($_) =~ /^\d+$/ + } + $form->delete($_) + foreach grep /^crdt\d+/, $form->param; + $form->param("crdt0subj", acctsubj_sn(ACCTSUBJ_CASH)); + $form->param("crdt0summary", undef); + $form->param("crdt0amount", $sum); + if ( $self->{"type"} eq "cur" + && $cur->param("crdtcount") == 1 + && $cur->param("crdt0subj") == acctsubj_sn(ACCTSUBJ_CASH)) { + $form->param("crdt0summary", $cur->param("crdt0summary")); + } + # A form to fill in a cash income transaction + } elsif ($self->{"subtype"} eq "income") { + $sum = 0; + foreach (grep /^crdt\d+amount$/, $form->param) { + $sum += $form->param($_) if $form->param($_) =~ /^\d+$/ + } + $form->delete($_) + foreach grep /^debt\d+/, $form->param; + $form->param("debt0subj", acctsubj_sn(ACCTSUBJ_CASH)); + $form->param("debt0summary", undef); + $form->param("debt0amount", $sum); + if ( $self->{"type"} eq "cur" + && $cur->param("debtcount") == 1 + && $cur->param("debt0subj") == acctsubj_sn(ACCTSUBJ_CASH)) { + $form->param("debt0summary", $cur->param("debt0summary")); + } + } + } + + # A form to create a new item + if ($self->{"type"} eq "new") { + # Shrink to the maximum order + $myord = $form->param("ord"); + $myord = accttrx_maxord $form->param("date") + if $self->{"fix_ord"} && $myord > accttrx_maxord $form->param("date"); + $self->{"myord"} = $myord; + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->adddate("date", $self->_form("date")); + $self->{"cols"}->addnum("ord", $myord); + $self->{"cols"}->addstr("note", $self->_form("note")); + + # Fix the order of other records + if ($self->{"fix_ord"}) { + my ($sql, $sth, $count, $row); + $sql = "SELECT * FROM " . $self->{"table"} + . " WHERE date=" . $DBH->quote($form->param("date")) + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, $o = 1; $_ < $count; $_++, $o++) { + my ($subform, $cols, %CURRENT_SUP); + $row = $sth->fetchrow_hashref; + $o++ if $o == $myord; + next if $$row{"ord"} == $o; + %CURRENT_SUP = %CURRENT; + %CURRENT = (%$row); + $subform = new CGI({%CURRENT}); + $subform->param("form", "cur"); + $subform->param("formsub", "trans"); + $subform->param("ord", $o); + $subform->param("date", fmtdate($CURRENT{"date"})); + $cols = new Selima::Processor::AcctTrx($subform); + $cols->{"fix_ord"} = 0; + $cols->_save_cols; + unshift @{$self->{"pres"}}, $cols; + %CURRENT = %CURRENT_SUP; + } + } + + # Find the changed items + if ($self->{"fix_ord"}) { + for ($_ = 0, $o = 1; defined $form->param("debt$_" . "subj"); $_++) { + my ($subform, $cols); + # Not selected + next unless $form->param("debt$_" . "subj") ne ""; + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("trx", $self->{"sn"}); + $subform->delete("credit"); + $subform->param("ord", $o++); + $subform->param("subj", $form->param("debt$_" . "subj")); + $subform->param("summary", $form->param("debt$_" . "summary")); + $subform->param("amount", $form->param("debt$_" . "amount")); + $cols = new Selima::Processor::AcctRec($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + + for ($_ = 0, $o = 1; defined $form->param("crdt$_" . "subj"); $_++) { + my ($subform, $cols); + # Not selected + next unless $form->param("crdt$_" . "subj") ne ""; + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("trx", $self->{"sn"}); + $subform->param("credit", 1); + $subform->param("ord", $o++); + $subform->param("subj", $form->param("crdt$_" . "subj")); + $subform->param("summary", $form->param("crdt$_" . "summary")); + $subform->param("amount", $form->param("crdt$_" . "amount")); + $cols = new Selima::Processor::AcctRec($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + } + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + # Shrink to the maximum order + $myord = $form->param("ord"); + $myord = accttrx_maxord $form->param("date") + if $self->{"fix_ord"} && $myord > accttrx_maxord $form->param("date"), $self->{"sn"}; + $self->{"myord"} = $myord; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->adddate("date", $self->_form("date"), scalar $cur->param("date")); + $self->{"cols"}->addnum("ord", $myord, scalar $cur->param("ord")); + $self->{"cols"}->addstr("note", $self->_form("note"), scalar $cur->param("note")); + + # Fix the order of other records + if ($self->{"fix_ord"}) { + my ($sql, $sth, $count, $row); + # Date changed + if (fmtdate($cur->param("date")) ne $form->param("date")) { + $sql = "SELECT * FROM " . $self->{"table"} + . " WHERE date=" . $DBH->quote(fmtdate $cur->param("date")) + . " AND sn!=" . $self->{"sn"} + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, $o = 1; $_ < $count; $_++, $o++) { + my ($subform, $cols, %CURRENT_SUP); + $row = $sth->fetchrow_hashref; + next if $$row{"ord"} == $o; + %CURRENT_SUP = %CURRENT; + %CURRENT = (%$row); + $subform = new CGI({%CURRENT}); + $subform->param("form", "cur"); + $subform->param("formsub", "trans"); + $subform->param("ord", $o); + $subform->param("date", fmtdate($CURRENT{"date"})); + $cols = new Selima::Processor::AcctTrx($subform); + $cols->{"fix_ord"} = 0; + $cols->_save_cols; + unshift @{$self->{"pres"}}, $cols; + %CURRENT = %CURRENT_SUP; + } + } + $sql = "SELECT * FROM " . $self->{"table"} + . " WHERE date=" . $DBH->quote($form->param("date")) + . " AND sn!=" . $self->{"sn"} + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, $o = 1; $_ < $count; $_++, $o++) { + my ($subform, $cols, %CURRENT_SUP); + $row = $sth->fetchrow_hashref; + $o++ if $o == $myord; + next if $$row{"ord"} == $o; + %CURRENT_SUP = %CURRENT; + %CURRENT = (%$row); + $subform = new CGI({%CURRENT}); + $subform->param("form", "cur"); + $subform->param("formsub", "trans"); + $subform->param("ord", $o); + $subform->param("date", fmtdate($CURRENT{"date"})); + $cols = new Selima::Processor::AcctTrx($subform); + $cols->{"fix_ord"} = 0; + $cols->_save_cols; + unshift @{$self->{"pres"}}, $cols; + %CURRENT = %CURRENT_SUP; + } + } + + # Find the changed items + if ($self->{"fix_ord"}) { + @_ = qw(); + # The debit records + for ( $_ = 0, $o = 1; + $_ < $cur->param("debtcount") + || defined $form->param("debt$_" . "subj"); + $_++) { + # Added items to the current + if ($_ >= $cur->param("debtcount")) { + my ($subform, $cols); + # Not selected + next unless $form->param("debt$_" . "subj") ne ""; + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("trx", $self->{"sn"}); + $subform->delete("credit"); + $subform->param("ord", $o++); + $subform->param("subj", $form->param("debt$_" . "subj")); + $subform->param("summary", $form->param("debt$_" . "summary")); + $subform->param("amount", $form->param("debt$_" . "amount")); + $cols = new Selima::Processor::AcctRec($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + + # Selected + } elsif ($form->param("debt$_" . "subj") ne "") { + my ($subform, $cols, %CURRENT_SUP); + %CURRENT_SUP = %CURRENT; + %CURRENT = ( + "sn" => $cur->param("debt$_" . "sn"), + "trx" => $self->{"sn"}, + "credit" => undef, + "ord" => $cur->param("debt$_" . "ord"), + "subj" => $cur->param("debt$_" . "subj"), + "summary" => scalar $cur->param("debt$_" . "summary"), + "amount" => $cur->param("debt$_" . "amount"), + ); + $subform = new CGI(""); + $subform->param("form", "cur"); + $subform->param("sn", $cur->param("debt$_" . "sn")); + $subform->param("trx", $self->{"sn"}); + $subform->delete("credit"); + $subform->param("ord", $o++); + $subform->param("subj", $form->param("debt$_" . "subj")); + $subform->param("summary", $form->param("debt$_" . "summary")); + $subform->param("amount", $form->param("debt$_" . "amount")); + $cols = new Selima::Processor::AcctRec($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + %CURRENT = %CURRENT_SUP; + + # Not selected + } else { + push @_, $cur->param("debt$_" . "sn"); + } + } + # The credit records + for ( $_ = 0, $o = 1; + $_ < $cur->param("crdtcount") + || defined $form->param("crdt$_" . "subj"); + $_++) { + # Added items to the current + if ($_ >= $cur->param("crdtcount")) { + my ($subform, $cols); + # Not selected + next unless $form->param("crdt$_" . "subj") ne ""; + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("trx", $self->{"sn"}); + $subform->param("credit", 1); + $subform->param("ord", $o++); + $subform->param("subj", $form->param("crdt$_" . "subj")); + $subform->param("summary", $form->param("crdt$_" . "summary")); + $subform->param("amount", $form->param("crdt$_" . "amount")); + $cols = new Selima::Processor::AcctRec($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + + # Selected + } elsif ($form->param("crdt$_" . "subj") ne "") { + my ($subform, $cols, %CURRENT_SUP); + %CURRENT_SUP = %CURRENT; + %CURRENT = ( + "sn" => $cur->param("crdt$_" . "sn"), + "trx" => $self->{"sn"}, + "credit" => 1, + "ord" => $cur->param("crdt$_" . "ord"), + "subj" => $cur->param("crdt$_" . "subj"), + "summary" => scalar $cur->param("crdt$_" . "summary"), + "amount" => $cur->param("crdt$_" . "amount"), + ); + $subform = new CGI(""); + $subform->param("form", "cur"); + $subform->param("sn", $cur->param("crdt$_" . "sn")); + $subform->param("trx", $self->{"sn"}); + $subform->param("credit", 1); + $subform->param("ord", $o++); + $subform->param("subj", $form->param("crdt$_" . "subj")); + $subform->param("summary", $form->param("crdt$_" . "summary")); + $subform->param("amount", $form->param("crdt$_" . "amount")); + $cols = new Selima::Processor::AcctRec($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + %CURRENT = %CURRENT_SUP; + + # Not selected + } else { + push @_, $cur->param("crdt$_" . "sn"); + } + } + + # Debit and credit records are in a same table + if (@_ > 0) { + my $subform; + $_ = join " OR ", map "sn=$_", @_; + $subform = new CGI(""); + $subform->param("cond", $_); + # Delete first, to spare the order occupied + unshift @{$self->{"pres"}}, new Selima::Processor::Deletion($subform, "acctrecs"); + } + } + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + # Fix the order of other records + if ($self->{"fix_ord"}) { + my ($sql, $sth, $count, $row); + $sql = "SELECT * FROM " . $self->{"table"} + . " WHERE date=" . $DBH->quote(fmtdate $cur->param("date")) + . " AND sn!=" . $self->{"sn"} + . " ORDER BY ord;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, $o = 1; $_ < $count; $_++, $o++) { + my ($subform, $cols, %CURRENT_SUP); + $row = $sth->fetchrow_hashref; + next if $$row{"ord"} == $o; + %CURRENT_SUP = %CURRENT; + %CURRENT = (%$row); + $subform = new CGI({%CURRENT}); + $subform->param("form", "cur"); + $subform->param("formsub", "trans"); + $subform->param("ord", $o); + $subform->param("date", fmtdate($CURRENT{"date"})); + $cols = new Selima::Processor::AcctTrx($subform); + $cols->{"fix_ord"} = 0; + $cols->_save_cols; + unshift @{$self->{"pres"}}, $cols; + %CURRENT = %CURRENT_SUP; + } + } + + # Find the changed items + if ($self->{"fix_ord"}) { + $_ = new CGI(""); + $_->param("cond", "trx=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($_, "acctrecs"); + } + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create an accounting transaction " + . accttrxid_compose($form->param("date"), $self->{"myord"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the accounting transaction " + . accttrxid_compose($form->param("date"), $self->{"myord"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the accounting transaction " + . accttrxid_compose($cur->param("date"), $cur->param("ord")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This accounting transaction was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This accounting transaction has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This accounting transaction has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This accounting transaction has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/Category.pm b/lib/perl5/Selima/Processor/Category.pm new file mode 100644 index 0000000..2c23d75 --- /dev/null +++ b/lib/perl5/Selima/Processor/Category.pm @@ -0,0 +1,51 @@ +# Selima Website Content Management System +# Category.pm: The base category data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-18 + +package Selima::Processor::Category; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::ShortCut; + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This category was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This category has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This category has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This category has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/Categorz.pm b/lib/perl5/Selima/Processor/Categorz.pm new file mode 100644 index 0000000..3250aa2 --- /dev/null +++ b/lib/perl5/Selima/Processor/Categorz.pm @@ -0,0 +1,51 @@ +# Selima Website Content Management System +# Categorz.pm: The base category membership data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-17 + +package Selima::Processor::Categorz; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::ShortCut; + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This categorization record was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This categorization record has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This categorization record has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This categorization record has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/Deletion.pm b/lib/perl5/Selima/Processor/Deletion.pm new file mode 100644 index 0000000..d1dd3a1 --- /dev/null +++ b/lib/perl5/Selima/Processor/Deletion.pm @@ -0,0 +1,52 @@ +# Selima Website Content Management System +# Deletion.pm: The data deletion processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-17 + +package Selima::Processor::Deletion; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw($DBH); + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[0]->param("form", "del"); + $self = $class->SUPER::new(@_); + $self->{"cond"} = $self->{"form"}->param("cond"); + return $self; +} + +# _update_cols: Update the columns +sub _update_cols : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Process the update + $_ = "DELETE FROM " . $self->{"table"} + . " WHERE " . $self->{"cond"} . ";\n"; + $DBH->gdo($_); + return; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/Group.pm b/lib/perl5/Selima/Processor/Group.pm new file mode 100644 index 0000000..63affd1 --- /dev/null +++ b/lib/perl5/Selima/Processor/Group.pm @@ -0,0 +1,284 @@ +# Selima Website Content Management System +# Group.pm: The account group data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-17 + +package Selima::Processor::Group; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use CGI; + +use Selima::ChkPriv; +use Selima::DataVars qw(:addcol); +use Selima::Guest; +use Selima::LogIn; +use Selima::ShortCut; +use Selima::UserName; + +use Selima::Processor::UserMem; +use Selima::Processor::GroupMem; +use Selima::Processor::Deletion; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "groups" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur, @olditems, @newitems, @additems, @delitems); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("id", $self->_form("id")); + $self->{"cols"}->addstr("dsc", $self->_form("dsc")); + + # Find the changed items + @additems = qw(); + for ($_ = 0; defined $form->param("subuser$_" . "sn"); $_++) { + push @additems, $form->param("subuser$_" . "sn") + if defined $form->param("subuser$_"); + } + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("grp", $self->{"sn"}); + $subform->param("member", $item); + $cols = new Selima::Processor::UserMem($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + + @additems = qw(); + for ($_ = 0; defined $form->param("subgroup$_" . "sn"); $_++) { + push @additems, $form->param("subgroup$_" . "sn") + if defined $form->param("subgroup$_"); + } + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("grp", $self->{"sn"}); + $subform->param("member", $item); + $cols = new Selima::Processor::GroupMem($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + + @additems = qw(); + for ($_ = 0; defined $form->param("supgroup$_" . "sn"); $_++) { + push @additems, $form->param("supgroup$_" . "sn") + if defined $form->param("supgroup$_"); + } + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("grp", $item); + $subform->param("member", $self->{"sn"}); + $cols = new Selima::Processor::GroupMem($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + # Skip for non-super-user editing a super-user-group + unless (!is_su && $self->{"sn"} == su_group_sn) { + $self->{"cols"}->addstr("id", $self->_form("id"), scalar $cur->param("id")); + } + $self->{"cols"}->addstr("dsc", $self->_form("dsc"), scalar $cur->param("dsc")); + + # Find the changed items + @olditems = qw(); + @newitems = qw(); + # Skip for a non-super-user editing a super-user group + unless (!is_su && $self->{"sn"} == get_login_sn) { + for ($_ = 0; $_ < $cur->param("subusercount"); $_++) { + push @olditems, $cur->param("subuser$_" . "sn"); + } + for ($_ = 0; defined $form->param("subuser$_" . "sn"); $_++) { + push @newitems, $form->param("subuser$_" . "sn") + if defined $form->param("subuser$_"); + } + } + %_ = map { $_ => 1 } @newitems; + @delitems = grep !exists $_{$_}, @olditems; + %_ = map { $_ => 1 } @olditems; + @additems = grep !exists $_{$_}, @newitems; + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("grp", $self->{"sn"}); + $subform->param("member", $item); + $cols = new Selima::Processor::UserMem($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + if (@delitems > 0) { + my $subform; + @_ = map "member=$_", @delitems; + $_ = (scalar(@_) == 1)? $_[0]: "(" . join(" OR ", @_) . ")"; + $subform = new CGI(""); + $subform->param("cond", "$_ AND grp=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($subform, "usermem"); + } + + @olditems = qw(); + @newitems = qw(); + # Skip for a non-super-user editing a super-user group + unless (!is_su && $self->{"sn"} == get_login_sn) { + for ($_ = 0; $_ < $cur->param("subgroupcount"); $_++) { + push @olditems, $cur->param("subgroup$_" . "sn"); + } + for ($_ = 0; defined $form->param("subgroup$_" . "sn"); $_++) { + push @newitems, $form->param("subgroup$_" . "sn") + if defined $form->param("subgroup$_"); + } + } + %_ = map { $_ => 1 } @newitems; + @delitems = grep !exists $_{$_}, @olditems; + %_ = map { $_ => 1 } @olditems; + @additems = grep !exists $_{$_}, @newitems; + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("grp", $self->{"sn"}); + $subform->param("member", $item); + $cols = new Selima::Processor::GroupMem($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + if (@delitems > 0) { + my $subform; + @_ = map "member=$_", @delitems; + $_ = (scalar(@_) == 1)? $_[0]: "(" . join(" OR ", @_) . ")"; + $subform = new CGI(""); + $subform->param("cond", "$_ AND grp=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($subform, "groupmem"); + } + + @olditems = qw(); + @newitems = qw(); + # Skip for a non-super-user editing a super-user group + unless (!is_su && $self->{"sn"} == get_login_sn) { + for ($_ = 0; $_ < $cur->param("supgroupcount"); $_++) { + push @olditems, $cur->param("supgroup$_" . "sn"); + } + for ($_ = 0; defined $form->param("supgroup$_" . "sn"); $_++) { + push @newitems, $form->param("supgroup$_" . "sn") + if defined $form->param("supgroup$_"); + } + } + %_ = map { $_ => 1 } @newitems; + @delitems = grep !exists $_{$_}, @olditems; + %_ = map { $_ => 1 } @olditems; + @additems = grep !exists $_{$_}, @newitems; + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("grp", $item); + $subform->param("member", $self->{"sn"}); + $cols = new Selima::Processor::GroupMem($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + if (@delitems > 0) { + my $subform; + @_ = map "grp=$_", @delitems; + $_ = (scalar(@_) == 1)? $_[0]: "(" . join(" OR ", @_) . ")"; + $subform = new CGI(""); + $subform->param("cond", "$_ AND member=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($subform, "groupmem"); + } + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + # Find the changed items + $_ = new CGI(""); + $_->param("cond", "grp=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($_, "usermem"); + + $_ = new CGI(""); + $_->param("cond", "grp=" . $self->{"sn"} . " OR member=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($_, "groupmem"); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a group " . $form->param("id") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the group " . $form->param("id") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the group " . $cur->param("id") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This group was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This group has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This group has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This group has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/GroupMem.pm b/lib/perl5/Selima/Processor/GroupMem.pm new file mode 100644 index 0000000..d724d1e --- /dev/null +++ b/lib/perl5/Selima/Processor/GroupMem.pm @@ -0,0 +1,110 @@ +# Selima Website Content Management System +# GroupMem.pm: The group-to-group membership data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-17 + +package Selima::Processor::GroupMem; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw(:addcol); +use Selima::Guest; +use Selima::ShortCut; +use Selima::UserName; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "groupmem" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("grp", $self->_form("grp")); + $self->{"cols"}->addnum("member", $self->_form("member")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("grp", $self->_form("grp"), scalar $cur->param("grp")); + $self->{"cols"}->addnum("member", $self->_form("member"), scalar $cur->param("member")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a group membership " . groupid($form->param("member")) + . " in group " . groupid($form->param("grp")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the group membership " . groupid($form->param("member")) + . " in group " . groupid($form->param("grp")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the group membership " . groupid($cur->param("member")) + . " in group " . groupid($cur->param("grp")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This group membership record was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This group membership record has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This group membership record has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This group membership record has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/Guestbook.pm b/lib/perl5/Selima/Processor/Guestbook.pm new file mode 100644 index 0000000..d094824 --- /dev/null +++ b/lib/perl5/Selima/Processor/Guestbook.pm @@ -0,0 +1,148 @@ +# Selima Website Content Management System +# Guestbook.pm: The base guestbook data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-19 + +package Selima::Processor::Guestbook; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw($DBH :addcol); +use Selima::Format; +use Selima::Guest; +use Selima::GeoIP; +use Selima::Guestbook; +use Selima::RemoHost; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "guestbook" if @_ < 2; + $self = $class->SUPER::new(@_); + $self->{"page_size"} = 2560; + $self->{"form_cols"} = [qw(name identity location email url message)]; + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("name", $self->_form("name")); + $self->{"cols"}->addstr("identity", $self->_form("identity")); + $self->{"cols"}->addstr("location", $self->_form("location")); + $self->{"cols"}->addstr("email", $self->_form("email")); + $self->{"cols"}->addurl("url", $self->_form("url")); + $self->{"cols"}->addstr("message", $self->_form("message")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + $self->{"cols"}->addipaddr("ip", $ENV{"REMOTE_ADDR"}); + $self->{"cols"}->addstr("host", remote_host); + $self->{"cols"}->addstr("ct", country_lookup); + $self->{"cols"}->addnum("pageno", 1); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("name", $self->_form("name"), scalar $cur->param("name")); + $self->{"cols"}->addstr("identity", $self->_form("identity"), scalar $cur->param("identity")); + $self->{"cols"}->addstr("location", $self->_form("location"), scalar $cur->param("title_2ln")); + $self->{"cols"}->addstr("email", $self->_form("email"), scalar $cur->param("email")); + $self->{"cols"}->addurl("url", $self->_form("url"), scalar $cur->param("url")); + $self->{"cols"}->addstr("message", $self->_form("message"), scalar $cur->param("message")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + } + return; +} + +# _update_cols: Update the columns +sub _update_cols : method { + local ($_, %_); + my $self; + ($self, @_) = @_; + $self->SUPER::_update_cols(@_); + # Update the page number + if ($self->{"type"} eq "new") { + my ($sql, $sth, $row); + $sql = "SELECT created FROM " . $self->{"table"} + . " WHERE sn=" . $self->{"sn"} . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $row = $sth->fetchrow_hashref; + $self->{"date"} = $$row{"created"}; + } else { + $self->{"date"} = $self->{"cur"}->param("created"); + } + update_pageno $self->{"table"}, $self->{"page_size"}, + $self->{"form_cols"}, $self->{"date"}; + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my $self; + $self = $_[0]; + # A form to create a new item + return gactlog "Create a message on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the message on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the message on " . fmtdate($self->{"date"}) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This message was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This message has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This message has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This message has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/Link.pm b/lib/perl5/Selima/Processor/Link.pm new file mode 100644 index 0000000..c0926e4 --- /dev/null +++ b/lib/perl5/Selima/Processor/Link.pm @@ -0,0 +1,337 @@ +# Selima Website Content Management System +# Link.pm: The related-link data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-18 + +package Selima::Processor::Link; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use CGI; + +use Selima::DataVars qw($DBH :addcol :scptconf); +use Selima::Guest; +use Selima::Links; +use Selima::ShortCut; + +use Selima::Processor::LinkCatz; +use Selima::Processor::Deletion; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "links" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur, @olditems, @newitems, @additems, @delitems); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("title_2ln", $self->_form("title_2ln")); + $self->{"cols"}->addurl("url", $self->_form("url")); + $self->{"cols"}->addstr("email", $self->_form("email")); + $self->{"cols"}->addurl("icon", $self->_form("icon")); + $self->{"cols"}->addstr("addr", $self->_form("addr")); + $self->{"cols"}->addstr("tel", $self->_form("tel")); + $self->{"cols"}->addstr("fax", $self->_form("fax")); + $self->{"cols"}->addstr("dsc", $self->_form("dsc")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + + # Find the changed items + @additems = qw(); + for ($_ = 0; defined $form->param("cat$_"); $_++) { + push @additems, $form->param("cat$_") + if $form->param("cat$_") ne ""; + } + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("cat", $item); + $subform->param("link", $self->{"sn"}); + $cols = new Selima::Processor::LinkCatz($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("title_2ln", $self->_form("title_2ln"), scalar $cur->param("title_2ln")); + $self->{"cols"}->addurl("url", $self->_form("url"), scalar $cur->param("url")); + $self->{"cols"}->addstr("email", $self->_form("email"), scalar $cur->param("email")); + $self->{"cols"}->addurl("icon", $self->_form("icon"), scalar $cur->param("icon")); + $self->{"cols"}->addstr("addr", $self->_form("addr"), scalar $cur->param("addr")); + $self->{"cols"}->addstr("tel", $self->_form("tel"), scalar $cur->param("tel")); + $self->{"cols"}->addstr("fax", $self->_form("fax"), scalar $cur->param("fax")); + $self->{"cols"}->addstr("dsc", $self->_form("dsc"), scalar $cur->param("dsc")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + + # Find the changed items + @olditems = qw(); + @newitems = qw(); + for ($_ = 0; $_ < $cur->param("catcount"); $_++) { + push @olditems, $cur->param("cat$_"); + } + for ($_ = 0; defined $form->param("cat$_"); $_++) { + push @newitems, $form->param("cat$_") + if $form->param("cat$_") ne ""; + } + %_ = map { $_ => 1 } @newitems; + @delitems = grep !exists $_{$_}, @olditems; + %_ = map { $_ => 1 } @olditems; + @additems = grep !exists $_{$_}, @newitems; + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("cat", $item); + $subform->param("link", $self->{"sn"}); + $cols = new Selima::Processor::LinkCatz($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + if (@delitems > 0) { + my $subform; + @_ = map "cat=$_", @delitems; + $_ = (scalar(@_) == 1)? $_[0]: "(" . join(" OR ", @_) . ")"; + $subform = new CGI(""); + $subform->param("cond", "$_ AND link=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($subform, "linkcatz"); + } + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + # Find the changed items + $_ = new CGI(""); + $_->param("cond", "link=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($_, "linkcatz"); + } + return; +} + +# _update_cols: Update the columns +sub _update_cols : method { + local ($_, %_); + my $self; + ($self, @_) = @_; + $self->{"curshown"} = $self->_shown_parts; + $self->SUPER::_update_cols(@_); + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a related link " . $form->param("url") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the related link " . $form->param("url") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the related link " . $cur->param("url") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This related link was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This related link has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This related link has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This related link has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +# _rebuild_partial_pages: Rebuild a limited part of pages +sub _rebuild_partial_pages : method { + local ($_, %_); + my ($self, $form, $cur); + my ($sql, @parents, @cats, @oldcats, @newcats, $cond); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + $self->{"newshown"} = $self->_shown_parts; + # Remove the unwanted pages + $self->_remove_curfile; + + # Find the affected parents + @parents = qw(); + @_ = qw(); + %_ = map { $_ => 1 } @{${$self->{"curshown"}}{"cats"}}; + push @_, grep !exists $_{$_}, @{${$self->{"newshown"}}{"cats"}}; + %_ = map { $_ => 1 } @{${$self->{"newshown"}}{"cats"}}; + push @_, grep !exists $_{$_}, @{${$self->{"curshown"}}{"cats"}}; + if (@_ > 0) { + my ($sql, $sth, $count, $row); + $sql = "SELECT parent FROM linkcat" + . " WHERE " . join(" OR ", map "sn=$_", @_) + . " GROUP BY parent;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0; $_ < $count; $_++) { + push @parents, ${$sth->fetch}[0]; + } + } + + # Add myself and my parents + @oldcats = qw(); + @newcats = qw(); + # A form to create a new item + if ($self->{"type"} eq "new") { + if (!defined $form->param("hid")) { + for ($_ = 0; defined $form->param("cat$_"); $_++) { + push @newcats, $form->param("cat$_") + if $form->param("cat$_") ne ""; + } + } + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + if (!$cur->param("hid")) { + for ($_ = 0; $_ < $cur->param("catcount"); $_++) { + push @oldcats, $cur->param("cat$_"); + } + } + if (!defined $form->param("hid")) { + for ($_ = 0; defined $form->param("cat$_"); $_++) { + push @newcats, $form->param("cat$_") + if $form->param("cat$_") ne ""; + } + } + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + if (!$cur->param("hid")) { + for ($_ = 0; $_ < $cur->param("catcount"); $_++) { + push @oldcats, $cur->param("cat$_"); + } + } + } + @cats = qw(); + %_ = map { $_ => 1 } (@oldcats, @newcats); + push @cats, keys %_; + # The statistics pages on their parents are affected + @_ = qw(); + %_ = map { $_ => 1 } @oldcats; + push @_, grep !exists $_{$_}, @newcats; + %_ = map { $_ => 1 } @newcats; + push @_, grep !exists $_{$_}, @oldcats; + if (@_ > 0) { + my ($sql, $sth, $count); + $_ = join(" OR ", map "sn=$_", @_); + $_ = "($_)" if @_ > 1; + $sql = "SELECT parent FROM linkcat" + . " WHERE $_" + . " AND parent IS NOT NULL" + . " AND linkcat_isshown(sn, hid, parent)" + . " GROUP BY parent;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0; $_ < $count; $_++) { + push @cats, ${$sth->fetch}[0]; + } + } + %_ = map { $_ => 1 } @cats; + @cats = keys %_; + + # Nothing to rebuild + return if @cats == 0 && @parents == 0; + + # Compose the SQL statement + @_ = qw(); + push @_, "sn=" . $_ foreach @cats; + foreach (@parents) { + # The parent page and those share the same parent + if (defined $_) { + push @_, "sn=" . $_; + push @_, "parent=" . $_; + # The topmost pages + } else { + push @_, "parent IS NULL"; + } + } + $cond = join " OR ", @_; + $cond = "($cond)" if @_ > 1; + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE $cond" + . " AND linkcat_isshown(sn, hid, parent);\n"; + # Rebuild the pages + $_ = $MAIN->can("rebuild_links"); + &$_($sql); + return; +} + +# _remove_curfile: Remove the unwanted page +sub _remove_curfile : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Remove the unwanted category files + %_ = map { $_ => 1 } @{${$self->{"newshown"}}{"catspath"}}; + grmoldpage $_ + foreach grep !exists $_{$_}, @{${$self->{"curshown"}}{"catspath"}}; + return; +} + +# _shown_parts: Obtain the shown parts +sub _shown_parts : method { + return links_shown_parts; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/LinkCat.pm b/lib/perl5/Selima/Processor/LinkCat.pm new file mode 100644 index 0000000..f97522d --- /dev/null +++ b/lib/perl5/Selima/Processor/LinkCat.pm @@ -0,0 +1,219 @@ +# Selima Website Content Management System +# LinkCat.pm: The related-link category data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-17 + +package Selima::Processor::LinkCat; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor::Category); + +use Selima::DataVars qw($DBH :addcol :scptconf); +use Selima::Guest; +use Selima::Links; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "linkcat" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + if ($self->{"type"} ne "del") { + # Set the "topmost" parent + $form->delete("parent") if defined $form->param("topmost") + && $form->param("topmost") eq "true"; + } + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("parent", $self->_form("parent")); + $self->{"cols"}->addstr("id", $self->_form("id")); + $self->{"cols"}->addnum("ord", $self->_form("ord")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("kw", $self->_form("kw")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("parent", $self->_form("parent"), scalar $cur->param("parent")); + $self->{"cols"}->addstr("id", $self->_form("id"), scalar $cur->param("id")); + $self->{"cols"}->addnum("ord", $self->_form("ord"), scalar $cur->param("ord")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("kw", $self->_form("kw"), scalar $cur->param("kw")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + } + return; +} + +# _update_cols: Update the columns +sub _update_cols : method { + local ($_, %_); + my $self; + ($self, @_) = @_; + $self->{"curshown"} = $self->_shown_parts; + $self->SUPER::_update_cols(@_); + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a link category " . $form->param("id") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the link category " . $form->param("id") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the link category " . $cur->param("id") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _rebuild_partial_pages: Rebuild a limited part of pages +sub _rebuild_partial_pages : method { + local ($_, %_); + my ($self, $form, $cur); + my ($sql, @parents, $build_myself, $cond); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + $self->{"newshown"} = $self->_shown_parts; + # Remove the unwanted pages + $self->_remove_curfile; + # Page was not shown, and is still not shown now + return unless ${$self->{"curshown"}}{"self"} + || ${$self->{"newshown"}}{"self"}; + + # Find the affected parents + @parents = qw(); + @_ = qw(); + %_ = map { $_ => 1 } @{${$self->{"curshown"}}{"cats"}}; + push @_, grep !exists $_{$_}, @{${$self->{"newshown"}}{"cats"}}; + %_ = map { $_ => 1 } @{${$self->{"newshown"}}{"cats"}}; + push @_, grep !exists $_{$_}, @{${$self->{"curshown"}}{"cats"}}; + if (@_ > 0) { + my ($sql, $sth, $count, $row); + $sql = "SELECT parent FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE " . join(" OR ", map "sn=$_", @_) + . " GROUP BY parent;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0; $_ < $count; $_++) { + push @parents, ${$sth->fetch}[0]; + } + } + + # Add myself and my parents + $build_myself = 0; + # A form to edit a current item + if ($self->{"type"} eq "cur") { + push @parents, $cur->param("parent") + if !$cur->param("hid"); + if (!defined $form->param("hid")) { + push @parents, $form->param("parent"); + $build_myself = 1; + } + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + push @parents, $cur->param("parent") + if !$cur->param("hid"); + } + + # Nothing to rebuild + return if @parents == 0 && !$build_myself; + + # Compose the SQL statement + @_ = qw(); + push @_, "sn=" . $self->{"sn"} if $build_myself; + foreach (@parents) { + # The parent page and those share the same parent + if (defined $_) { + push @_, "sn=" . $_; + push @_, "parent=" . $_; + # The topmost pages + } else { + push @_, "parent IS NULL"; + } + } + $cond = join " OR ", @_; + $cond = "($cond)" if @_ > 1; + @_ = $DBH->cols($self->{"table"}); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT " . join(", ", @_) . " FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE $cond" + . " AND linkcat_isshown(sn, hid, parent);\n"; + # Rebuild the pages + $_ = $MAIN->can("rebuild_links"); + &$_($sql); + return; +} + +# _remove_curfile: Remove the unwanted page +sub _remove_curfile : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Remove the unwanted category files + %_ = map { $_ => 1 } @{${$self->{"newshown"}}{"catspath"}}; + grmoldpage $_ + foreach grep !exists $_{$_}, @{${$self->{"curshown"}}{"catspath"}}; + return; +} + +# _shown_parts: Obtain the shown parts +sub _shown_parts : method { + local ($_, %_); + my ($self, $shown, $sql, $sth); + $self = $_[0]; + $shown = links_shown_parts; + # Check if myself is shown + $sql = "SELECT sn FROM " . $DBH->quote_identifier($self->{"table"}) + . " WHERE sn=" . $self->{"sn"} + . " AND linkcat_isshown(sn, hid, parent);\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $$shown{"self"} = ($sth->rows > 0); + return $shown; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/LinkCatz.pm b/lib/perl5/Selima/Processor/LinkCatz.pm new file mode 100644 index 0000000..a821ef9 --- /dev/null +++ b/lib/perl5/Selima/Processor/LinkCatz.pm @@ -0,0 +1,198 @@ +# Selima Website Content Management System +# LinkCatz.pm: The related-link category membership data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-17 + +package Selima::Processor::LinkCatz; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor::Categorz); + +use Selima::DataVars qw($DBH :addcol :scptconf); +use Selima::Guest; +use Selima::Links; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "linkcatz" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("cat", $self->_form("cat")); + $self->{"cols"}->addnum("link", $self->_form("link")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("cat", $self->_form("cat"), scalar $cur->param("cat")); + $self->{"cols"}->addnum("link", $self->_form("link"), scalar $cur->param("link")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a link categorization record " . link_url($form->param("link")) + . " in category " . linkcat_title($form->param("cat")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the link categorization record " . link_url($form->param("link")) + . " in category " . linkcat_title($form->param("cat")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the link categorization record " . link_url($cur->param("link")) + . " in category " . linkcat_title($cur->param("cat")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _rebuild_partial_pages: Rebuild a limited part of pages +sub _rebuild_partial_pages : method { + local ($_, %_); + my ($self, $form, $cur); + my ($sql, @parents, @cats, $cond); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + $self->{"newshown"} = $self->_shown_parts; + # Remove the unwanted pages + $self->_remove_curfile; + + # Find the affected parents + @parents = qw(); + @_ = qw(); + %_ = map { $_ => 1 } @{${$self->{"curshown"}}{"cats"}}; + push @_, grep !exists $_{$_}, @{${$self->{"newshown"}}{"cats"}}; + %_ = map { $_ => 1 } @{${$self->{"newshown"}}{"cats"}}; + push @_, grep !exists $_{$_}, @{${$self->{"curshown"}}{"cats"}}; + if (@_ > 0) { + my ($sql, $sth, $count, $row); + $sql = "SELECT parent FROM linkcat" + . " WHERE " . join(" OR ", map "sn=$_", @_) + . " GROUP BY parent;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0; $_ < $count; $_++) { + push @parents, ${$sth->fetch}[0]; + } + } + + # Find the affected parts + # Only the shown parts are added + %_ = qw(); + # A form to create a new item + if ($self->{"type"} eq "new") { + $_{$form->param("cat")} = 1; + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $_{$form->param("cat")} = 1; + $_{$cur->param("cat")} = 1; + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $_{$cur->param("cat")} = 1; + } + @cats = keys %_; + # The statistics pages on their parents are affected + unless ($self->{"type"} eq "cur" + && $form->param("cat") == $cur->param("cat")) { + my ($sql, $sth, $count); + $_ = join(" OR ", map "sn=$_", @cats); + $_ = "($_)" if @_ > 1; + $sql = "SELECT parent FROM linkcat" + . " WHERE $_" + . " AND parent IS NOT NULL" + . " AND linkcat_isshown(sn, hid, parent)" + . " GROUP BY parent;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0; $_ < $count; $_++) { + push @cats, ${$sth->fetch}[0]; + } + } + %_ = map { $_ => 1 } @cats; + @cats = keys %_; + + # Compose the SQL statement + @_ = qw(); + push @_, "sn=" . $_ foreach @cats; + foreach (@parents) { + # The parent page and those share the same parent + if (defined $_) { + push @_, "sn=" . $_; + push @_, "parent=" . $_; + # The topmost pages + } else { + push @_, "parent IS NULL"; + } + } + $cond = join " OR ", @_; + $cond = "($cond)" if @_ > 1; + @_ = $DBH->cols("linkcat"); + push @_, $DBH->strcat("'/links'", "linkcat_path(sn, id, parent)") + . " AS path"; + $sql = "SELECT " . join(", ", @_) . " FROM linkcat" + . " WHERE $cond" + . " AND linkcat_isshown(sn, hid, parent);\n"; + # Rebuild the pages + $_ = $MAIN->can("rebuild_links"); + &$_($sql); + return; +} + +# _remove_curfile: Remove the unwanted page +sub _remove_curfile : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Remove the unwanted category files + %_ = map { $_ => 1 } @{${$self->{"newshown"}}{"catspath"}}; + grmoldpage $_ + foreach grep !exists $_{$_}, @{${$self->{"curshown"}}{"catspath"}}; + return; +} + +# _shown_parts: Obtain the shown parts +sub _shown_parts : method { + return links_shown_parts; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/ListPref.pm b/lib/perl5/Selima/Processor/ListPref.pm new file mode 100644 index 0000000..185a681 --- /dev/null +++ b/lib/perl5/Selima/Processor/ListPref.pm @@ -0,0 +1,157 @@ +# Selima Website Content Management System +# ListPref.pm: The list preference data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-22 + +package Selima::Processor::ListPref; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use CGI; + +use Selima::DataVars qw($DBH :dataman :input); +use Selima::Guest; +use Selima::LogIn; +use Selima::UserPref; + +# Load these classes +use Selima::Processor::UserPref; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + $self->{"is_sql"} = 0 if is_guest; + $self->{"names"} = [qw(listsize listcols)]; + return $self; +} + +# process: Process the form, fully +sub process : method { + local ($_, %_); + my ($self, $form); + ($self, @_) = @_; + # Use the parent processor for ordinary users + return $self->SUPER::process(@_) unless is_guest; + + # Guest preferences are saved in $SESSION + $form = $self->{"form"}; + $$SESSION{"userpref"} = {} + if !exists $$SESSION{"userpref"}; + ${$$SESSION{"userpref"}}{$form->param("domain")} = {} + if !exists ${$$SESSION{"userpref"}}{$form->param("domain")}; + $_ = ${$$SESSION{"userpref"}}{$form->param("domain")}; + + foreach my $name (@{$self->{"names"}}) { + $$_{$name} = $form->param($name); + } + return; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + + foreach my $name (@{$self->{"names"}}) { + my ($val, $sql, $sth, $row, $sn, $cols, $subform); + # Obtain the preference value + $val = $self->_prefval($name); + # Only update if value is different + $_ = userpref $name, $form->param("domain"); + next if defined $_ && $_ eq $val; + + # Check if there is already an existing user preference + $sql = "SELECT * FROM userpref" + . " WHERE usr=" . get_login_sn + . " AND domain=" . $DBH->quote($form->param("domain")) + . " AND name=" . $DBH->quote($name) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + # There is an existing user preference + if ($sth->rows == 1) { + my ($subform, $cols, %CURRENT_SUP); + $row = $sth->fetchrow_hashref; + %CURRENT_SUP = %CURRENT; + %CURRENT = ( + "sn" => $$row{"sn"}, + "usr" => $$row{"usr"}, + "domain" => $$row{"domain"}, + "name" => $$row{"name"}, + "value" => $$row{"value"}, + ); + $subform = new CGI(""); + $subform->param("form", "cur"); + $subform->param("sn", $$row{"sn"}); + $subform->param("usr", get_login_sn); + $subform->param("domain", $form->param("domain")); + $subform->param("name", $name); + $subform->param("value", $val); + $cols = new Selima::Processor::UserPref($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + %CURRENT = %CURRENT_SUP; + + # There is no existing user preference + } else { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("usr", get_login_sn); + $subform->param("domain", $form->param("domain")); + $subform->param("name", $name); + $subform->param("value", $val); + $cols = new Selima::Processor::UserPref($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Run the sub-processors + foreach (@{$self->{"subs"}}) { + $_->_actlog if $_->_modified; + } +} + +# _prefval: Obtain the preference value +sub _prefval : method { + local ($_, %_); + my ($self, $name); + ($self, $name) = @_; + # Specified + return $_ if defined($_ = $self->{"form"}->param($name)); + # No need to check the validility. Invalids are simply ignored. + @_ = grep s/^${name}_//, $self->{"form"}->param; + # Compose the preference value + return join " ", @_; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/ListPref/AcctReps.pm b/lib/perl5/Selima/Processor/ListPref/AcctReps.pm new file mode 100644 index 0000000..9f762ac --- /dev/null +++ b/lib/perl5/Selima/Processor/ListPref/AcctReps.pm @@ -0,0 +1,37 @@ +# Selima Website Content Management System +# AcctReps.pm: The accounting report list preference data processor. + +# Copyright (c) 2007-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2007-10-01 + +package Selima::Processor::ListPref::AcctReps; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor::ListPref); + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + $self->{"names"} = [qw(listsize)]; + return $self; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/LogOut.pm b/lib/perl5/Selima/Processor/LogOut.pm new file mode 100644 index 0000000..868e214 --- /dev/null +++ b/lib/perl5/Selima/Processor/LogOut.pm @@ -0,0 +1,71 @@ +# Selima Website Content Management System +# LogOut.pm: The log-out processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-19 + +package Selima::Processor::LogOut; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::ChkPriv; +use Selima::Guest; +use Selima::LogIn; +use Selima::LogOut; +use Selima::Logging; +use Selima::ScptPriv; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + $self->{"sn"} = get_login_sn; + $self->{"is_sql"} = 0; + $self->{"modified"} = 1; + $self->{"is_admin"} = is_guest()? is_admin_script: is_admin; + return $self; +} + +# _save_cols: Save the column deposit +# Make it a null function +sub _save_cols : method {} + +# _other_tasks: Perform tasks other than column updates +sub _other_tasks : method { + $_[0]->{"userid"} = get_login_id; + logout; +} + +# _actlog: Log the activity +sub _actlog : method { + # Log the guest log out, too + return actlog "Log out with s/n " . $_[0]->{"sn"} . ".", $_[0]->{"userid"}; +} + +# _ret_status: Return the process status +sub _ret_status : method { + return {"msg"=>N_("You have successfully logged out."), + "isform"=>0, + "is_admin"=>$_[0]->{"is_admin"}}; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/Page.pm b/lib/perl5/Selima/Processor/Page.pm new file mode 100644 index 0000000..2780c73 --- /dev/null +++ b/lib/perl5/Selima/Processor/Page.pm @@ -0,0 +1,157 @@ +# Selima Website Content Management System +# Page.pm: The base web page form data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-02 + +package Selima::Processor::Page; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw(:addcol :scptconf); +use Selima::Guest; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "pages" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("path", $self->_form("path")); + $self->{"cols"}->addnum("ord", $self->_form("ord")); + $self->{"cols"}->addstr("title", $self->_form("title")); + $self->{"cols"}->addstr("body", $self->_form("body")); + $self->{"cols"}->addstr("kw", $self->_form("kw")); + $self->{"cols"}->addbool("html", $self->_form("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("path", $self->_form("path"), scalar $cur->param("path")); + $self->{"cols"}->addnum("ord", $self->_form("ord"), scalar $cur->param("ord")); + $self->{"cols"}->addstr("title", $self->_form("title"), scalar $cur->param("title")); + $self->{"cols"}->addstr("body", $self->_form("body"), scalar $cur->param("body")); + $self->{"cols"}->addstr("kw", $self->_form("kw"), scalar $cur->param("kw")); + $self->{"cols"}->addbool("html", $self->_form("html"), scalar $cur->param("html")); + $self->{"cols"}->addbool("hid", $self->_form("hid"), scalar $cur->param("hid")); + # Automatic Traditional Chinese to Simplified Chinese conversion + $self->_zhsync; + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a page " . $form->param("path") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the page " . $form->param("path") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the page " . $cur->param("path") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This page was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This page has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This page has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This page has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +# _rebuild_partial_pages: Rebuild a limited part of pages +sub _rebuild_partial_pages : method { + local ($_, %_); + my ($self, $form, $cur); + my $sql; + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # Remove the unwanted pages + $self->_remove_curfile; + # Nothing to rebuild when no shown parts are seen + return if $self->{"type"} eq "del" || defined $form->param("hid"); + + # Compose the SQL statement + $sql = "SELECT * FROM pages" + . " WHERE sn=" . $self->{"sn"} . ";\n"; + # Rebuild the pages + $_ = $MAIN->can("rebuild_pages"); + &$_($sql); + return; +} + +# _remove_curfile: Remove the unwanted pages +sub _remove_curfile : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # Nothing to remove if there is no current page + return if $self->{"type"} eq "new" || $cur->param("hid"); + # A current page to be deleted or hidden + return grmoldpage $cur->param("path") + if $self->{"type"} eq "del" || defined $form->param("hid"); + # A shown page update with a new page path to check with + return grmoldpage $cur->param("path"), $form->param("path"); + return; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/Rebuild.pm b/lib/perl5/Selima/Processor/Rebuild.pm new file mode 100644 index 0000000..3f5fa34 --- /dev/null +++ b/lib/perl5/Selima/Processor/Rebuild.pm @@ -0,0 +1,66 @@ +# Selima Website Content Management System +# Rebuild.pm: The web page rebuild processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-04-04 + +package Selima::Processor::Rebuild; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Time::HiRes qw(); + +use Selima::DataVars qw(:scptconf); +use Selima::Guest; +use Selima::ShortCut; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $self = $class->SUPER::new(@_); + $self->{"modified"} = 1; + return $self; +} + +# _other_tasks: Perform tasks other than column updates +sub _other_tasks : method { + local ($_, %_); + my $self; + $self = $_[0]; + # Rebuild the pages + $self->{"t_start"} = Time::HiRes::time; + $_ = $MAIN->can("rebuild_" . $self->{"form"}->param("type")); + &$_(); + $self->{"t_end"} = Time::HiRes::time; +} + +# _actlog: Log the activity +sub _actlog : method { + return gactlog "Rebuild pages of type \"" . $_[0]->{"form"}->param("type") . "\"."; +} + +# _ret_status: Return the process status +sub _ret_status : method { + return {"msg"=>N_("The specified web pages have been successfully rebuilt. ([sprintf,%0.3f,_1] seconds)"), + "margs"=>[$_[0]->{"t_end"}-$_[0]->{"t_start"}]}; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/ScptPriv.pm b/lib/perl5/Selima/Processor/ScptPriv.pm new file mode 100644 index 0000000..0c10799 --- /dev/null +++ b/lib/perl5/Selima/Processor/ScptPriv.pm @@ -0,0 +1,110 @@ +# Selima Website Content Management System +# ScptPriv.pm: The script privilege data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-17 + +package Selima::Processor::ScptPriv; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw(:addcol); +use Selima::Guest; +use Selima::ShortCut; +use Selima::UserName; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "scptpriv" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("script", $self->_form("script")); + $self->{"cols"}->addnum("grp", $self->_form("grp")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addstr("script", $self->_form("script"), scalar $cur->param("script")); + $self->{"cols"}->addnum("grp", $self->_form("grp"), scalar $cur->param("grp")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a script privilege record " . $form->param("script") + . " for group " . groupid($form->param("grp")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the script privilege record " . $form->param("script") + . " for group " . groupid($form->param("grp")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the script privilege record " . $cur->param("script") + . " for group " . groupid($cur->param("grp")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This script privilege record was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This script privilege record has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This script privilege record has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This script privilege record has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/User.pm b/lib/perl5/Selima/Processor/User.pm new file mode 100644 index 0000000..31baaa2 --- /dev/null +++ b/lib/perl5/Selima/Processor/User.pm @@ -0,0 +1,238 @@ +# Selima Website Content Management System +# User.pm: The user account data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-17 + +package Selima::Processor::User; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use CGI; + +use Selima::ChkPriv; +use Selima::DataVars qw(:addcol :groups); +use Selima::Guest; +use Selima::LogIn; +use Selima::ShortCut; +use Selima::UserName; + +use Selima::Processor::UserMem; +use Selima::Processor::Deletion; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "users" if @_ < 2; + $self = $class->SUPER::new(@_); + $self->{"is_self"} = 0; + $self->{"no_set_groups"} = 0; + # Non-super-users editing herself are not allowed to update the groups + $self->{"no_set_groups"} = 1 + if exists $self->{"sn"} && !is_su && $self->{"sn"} == get_login_sn; + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur, @olditems, @newitems, @additems, @delitems, $passwd); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + # Set a dummy password for guests + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->{"login"} = $self->{"sn"} + if $self->{"is_self"} && !defined get_login_sn; + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addstr("id", $self->_form("id")); + $self->{"cols"}->addpass("passwd", $self->_purge_passwd, $self->_form("passwd")); + $self->{"cols"}->addstr("name", $self->_form("name")); + $self->{"cols"}->addbool("disabled", $self->_form("disabled")); + + # Find the changed items + unless ($self->{"no_set_groups"}) { + @additems = qw(); + for ($_ = 0; defined $form->param("supgroup$_" . "sn"); $_++) { + push @additems, $form->param("supgroup$_" . "sn") + if defined $form->param("supgroup$_"); + } + # Super users can set the super-user privilege + if (is_su) { + # Super user privilege is added + push @additems, su_group_sn + if defined $form->param("su"); + } + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("grp", $item); + $subform->param("member", $self->{"sn"}); + $cols = new Selima::Processor::UserMem($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + } + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->{"login"} = $self->{"sn"} + if $self->{"is_self"} && !defined get_login_sn; + # Skip for non-super-user editing a super-user + unless (!is_su && $cur->param("su")) { + $self->{"cols"}->addstr("id", $self->_form("id"), scalar $cur->param("id")); + $self->{"cols"}->addpass("passwd", $self->_purge_passwd, $self->_form("passwd"), scalar $cur->param("passwd")); + } + $self->{"cols"}->addstr("name", $self->_form("name"), scalar $cur->param("name")); + # Skip for non-super-user editing herself or a super-user + unless (!is_su && ($cur->param("su") || $self->{"sn"} == get_login_sn)) { + $self->{"cols"}->addbool("disabled", $self->_form("disabled"), scalar $cur->param("disabled")); + } + + # Find the changed items + unless ($self->{"no_set_groups"}) { + @olditems = qw(); + @newitems = qw(); + for ($_ = 0; $_ < $cur->param("supgroupcount"); $_++) { + push @olditems, $cur->param("supgroup$_" . "sn"); + } + for ($_ = 0; defined $form->param("supgroup$_" . "sn"); $_++) { + push @newitems, $form->param("supgroup$_" . "sn") + if defined $form->param("supgroup$_"); + } + %_ = map { $_ => 1 } @newitems; + @delitems = grep !exists $_{$_}, @olditems; + %_ = map { $_ => 1 } @olditems; + @additems = grep !exists $_{$_}, @newitems; + # Super users can set the super-user privilege + if (is_su) { + # Super user privilege is added + if (!$cur->param("su") && defined $form->param("su")) { + push @additems, su_group_sn; + # Super user privilege is removed + } elsif ($cur->param("su") && !defined $form->param("su")) { + push @delitems, su_group_sn; + } + } + foreach my $item (@additems) { + my ($subform, $cols); + $subform = new CGI(""); + $subform->param("form", "new"); + $subform->param("grp", $item); + $subform->param("member", $self->{"sn"}); + $cols = new Selima::Processor::UserMem($subform); + $cols->_save_cols; + push @{$self->{"subs"}}, $cols; + } + if (@delitems > 0) { + my $subform; + @_ = map "grp=$_", @delitems; + $_ = (scalar(@_) == 1)? $_[0]: "(" . join(" OR ", @_) . ")"; + $subform = new CGI(""); + $subform->param("cond", "$_ AND member=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($subform, "usermem"); + } + } + + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + # Find the changed items + $_ = new CGI(""); + $_->param("cond", "member=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($_, "usermem"); + + $_ = new CGI(""); + $_->param("cond", "usr=" . $self->{"sn"}); + push @{$self->{"subs"}}, new Selima::Processor::Deletion($_, "userpref"); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a user account " . $form->param("id") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the user account " + . (defined $form->param("id")? $form->param("id"): $cur->param("id")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the user account " . $cur->param("id") + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This user account was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This user account has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This user account has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This user account has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +# _purge_passwd: If we need to purge the password of the user +sub _purge_passwd : method { + local ($_, %_); + my ($self, $form); + $self = $_[0]; + $form = $self->{"form"}; + # Checked before + return $self->{"purge_passwd"} if exists $self->{"purge_passwd"}; + # Purge password for guests + unless ($self->{"no_set_groups"}) { + for ($_ = 0; defined $form->param("supgroup$_" . "sn"); $_++) { + # Skip unselected groups + next unless defined $form->param("supgroup$_"); + # Check if this is the guest group + return ($self->{"purge_passwd"} = 1) + if groupid($form->param("supgroup$_" . "sn")) eq GUEST_GROUP; + } + } + # No guest group was found + return ($self->{"purge_passwd"} = 0); +} + +return 1; diff --git a/lib/perl5/Selima/Processor/UserMem.pm b/lib/perl5/Selima/Processor/UserMem.pm new file mode 100644 index 0000000..3dd705d --- /dev/null +++ b/lib/perl5/Selima/Processor/UserMem.pm @@ -0,0 +1,110 @@ +# Selima Website Content Management System +# UserMem.pm: The user-to-group membership data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-17 + +package Selima::Processor::UserMem; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw(:addcol); +use Selima::Guest; +use Selima::ShortCut; +use Selima::UserName; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "usermem" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("grp", $self->_form("grp")); + $self->{"cols"}->addnum("member", $self->_form("member")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("grp", $self->_form("grp"), scalar $cur->param("grp")); + $self->{"cols"}->addnum("member", $self->_form("member"), scalar $cur->param("member")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + return gactlog "Create a user membership " . userid($form->param("member")) + . " in group " . groupid($form->param("grp")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "new"; + # A form to edit a current item + return gactlog "Update the user membership " . userid($form->param("member")) + . " in group " . groupid($form->param("grp")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "cur"; + # A form to delete a current item + return gactlog "Delete the user membership " . userid($cur->param("member")) + . " in group " . groupid($cur->param("grp")) + . " with s/n " . $self->{"sn"} . "." + if $self->{"type"} eq "del"; +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This user membership record was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This user membership record has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This user membership record has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This user membership record has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/lib/perl5/Selima/Processor/UserPref.pm b/lib/perl5/Selima/Processor/UserPref.pm new file mode 100644 index 0000000..9856dcd --- /dev/null +++ b/lib/perl5/Selima/Processor/UserPref.pm @@ -0,0 +1,159 @@ +# Selima Website Content Management System +# UserPref.pm: The user preference data processor. + +# Copyright (c) 2006-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2006-03-17 + +package Selima::Processor::UserPref; +use 5.008; +use strict; +use warnings; +use base qw(Selima::Processor); + +use Selima::DataVars qw(:addcol); +use Selima::Guest; +use Selima::ShortCut; +use Selima::UserName; + +# new: Initialize the processor +sub new : method { + local ($_, %_); + my ($self, $class); + ($class, @_) = @_; + $_[1] = "userpref" if @_ < 2; + $self = $class->SUPER::new(@_); + return $self; +} + +# _save_cols: Save the column deposit +sub _save_cols : method { + local ($_, %_); + my ($self, $form, $cur); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + if ($self->{"type"} ne "del") { + # Set the "everyone" user + $form->delete("usr") if defined $form->param("everyone") + && $form->param("everyone") eq "true"; + # Set the "everywhere" domain + $form->delete("domain") if defined $form->param("everywhere") + && $form->param("everywhere") eq "true"; + } + # A form to create a new item + if ($self->{"type"} eq "new") { + $self->{"sn"} = $self->_new_sn; + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_INSERT); + $self->{"cols"}->addnum("sn", $self->{"sn"}); + $self->{"cols"}->addnum("usr", $self->_form("usr")); + $self->{"cols"}->addstr("domain", $self->_form("domain")); + $self->{"cols"}->addstr("name", $self->_form("name")); + $self->{"cols"}->addstr_empty("value", $self->_form("value")); + + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + $self->{"cols"} = new Selima::AddCol($self->{"table"}, ADDCOL_UPDATE); + $self->{"cols"}->addnum("usr", $self->_form("usr"), scalar $cur->param("usr")); + $self->{"cols"}->addstr("domain", $self->_form("domain"), scalar $cur->param("domain")); + $self->{"cols"}->addstr("name", $self->_form("name"), scalar $cur->param("name")); + $self->{"cols"}->addstr_empty("value", $self->_form("value"), scalar $cur->param("value")); + } + return; +} + +# _actlog: Log the activity +sub _actlog : method { + local ($_, %_); + my ($self, $form, $cur, $user, $domain); + $self = $_[0]; + ($form, $cur) = ($self->{"form"}, $self->{"cur"}); + # A form to create a new item + if ($self->{"type"} eq "new") { + if ( defined $form->param("everyone") + && $form->param("everyone") eq "true") { + $user = "everyone"; + } elsif (!defined $form->param("usr")) { + $user = "everyone"; + } else { + $user = userid $form->param("usr"); + } + if ( defined $form->param("everywhere") + && $form->param("everywhere") eq "true") { + $domain = "everywhere"; + } elsif (!defined $form->param("domain")) { + $domain = "everywhere"; + } else { + $domain = $form->param("domain"); + } + return gactlog "Create a user preference \"" . $form->param("name") . "\"" + . " of $user for $domain" + . " with s/n " . $self->{"sn"} . "."; + # A form to edit a current item + } elsif ($self->{"type"} eq "cur") { + if ( defined $form->param("everyone") + && $form->param("everyone") eq "true") { + $user = "everyone"; + } elsif (!defined $form->param("usr")) { + $user = "everyone"; + } else { + $user = userid $form->param("usr"); + } + if ( defined $form->param("everywhere") + && $form->param("everywhere") eq "true") { + $domain = "everywhere"; + } elsif (!defined $form->param("domain")) { + $domain = "everywhere"; + } else { + $domain = $form->param("domain"); + } + return gactlog "Update the user preference \"" . $form->param("name") . "\"" + . " of $user for $domain" + . " with s/n " . $self->{"sn"} . "."; + # A form to delete a current item + } elsif ($self->{"type"} eq "del") { + $user = defined $cur->param("usr")? + userid $cur->param("usr"): "everyone"; + $domain = defined $cur->param("domain")? + $cur->param("domain"): "everywhere"; + return gactlog "Delete the user preference \"" . $cur->param("name") . "\"" + . " of $user for $domain" + . " with s/n " . $self->{"sn"} . "."; + } +} + +# _ret_status: Return the process status +sub _ret_status : method { + local ($_, %_); + my $self; + $self = $_[0]; + return {"msg"=>N_("This user preference was not modified."), + "isform"=>0} + if !$self->_modified; + # A form to create a new item + return {"msg"=>N_("This user preference has been successfully added."), + "isform"=>0} + if $self->{"type"} eq "new"; + # A form to edit a current item + return {"msg"=>N_("This user preference has been successfully updated."), + "isform"=>0} + if $self->{"type"} eq "cur"; + # A form to delete a current item + return {"msg"=>N_("This user preference has been successfully deleted."), + "isform"=>0} + if $self->{"type"} eq "del"; +} + +return 1; diff --git a/lib/perl5/Selima/Query.pm b/lib/perl5/Selima/Query.pm new file mode 100644 index 0000000..11dd60b --- /dev/null +++ b/lib/perl5/Selima/Query.pm @@ -0,0 +1,58 @@ +# Selima Website Content Management System +# Query.pm: The search string parser. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-12 + +package Selima::Query; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(parse_query); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub parse_query($); +} + +# parse_query: Parse the query string into multiple search phrases +sub parse_query($) { + local ($_, %_); + $_ = $_[0]; + + s/^\s*(.*?)\s*$/$1/; + @_ = qw(); + while ($_ ne "") { + # Non-quoted word + if (s/^([^\s"']+)\s*//) { # " gettext + push @_, $1; + # Double-quoted string + } elsif (s/^"((?:[^\\"]|\\.)+)"?\s*//) { # " gettext + eval "push \@_, \"$1\";\n"; + # Single-quoted string + } elsif (s/^'((?:[^\\']|\\.)+)'?\s*//) { # ' gettext + eval "push \@_, '$1';\n"; + # Discard empty quoted strings + } elsif (s/^(?:""?|''?)\s*//) { + } + } + return @_; +} + +return 1; diff --git a/lib/perl5/Selima/RelURI.pm b/lib/perl5/Selima/RelURI.pm new file mode 100644 index 0000000..8e71ef1 --- /dev/null +++ b/lib/perl5/Selima/RelURI.pm @@ -0,0 +1,75 @@ +# Selima Website Content Management System +# RelURI.pm: The converter to turn all URIs to relative URIs. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-04-03 + +package Selima::RelURI; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(reluri); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub reluri($;$); +} + +use Encode qw(encode decode is_utf8); +use URI qw(); + +use Selima::DataVars qw(:requri); + +# reluri: Turn an absolute URI to a relative URI +sub reluri($;$) { + local ($_, %_); + my ($uri, $base, $encoded); + ($uri, $base) = @_; + + # URI has bug with encode(). We get around it here. + $encoded = 0; + if (is_utf8($uri)) { + $uri = encode("UTF-8", $uri); + $encoded = 1; + } + # Default base to $REQUEST_FULLURI + $base = defined $base? + ($base =~ /^\//? new URI($REQUEST_HOSTPORT . $base): + new URI($base)): + new URI($REQUEST_FULLURI); + # Absolute path -- add the root difference and absolute it + if ($uri =~ /^\//) { + $uri = "$ROOT_DIFF$uri" ; + $uri = new URI($uri); + $uri = $uri->abs($REQUEST_FULLURI); + } else { + $uri = new URI($uri); + } + # Obtain the relative URI + $uri = $uri->rel($base); + + $uri = $uri->canonical->as_string; + # Fix it for my own style + $uri =~ s/\/$// if $uri =~ /(? +# First written: 2003-04-07 + +package Selima::RemoHost; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(remote_host); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub remote_host(); +} + +use Socket qw(inet_aton AF_INET); + +use Selima::DataVars qw(:env); + +BEGIN { +if (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + require Apache2::Connection; +} +} + +use Selima::Cache qw(:remohost); +use Selima::DataVars qw(:env); + +# remote_host: Look up the remote host domain name +sub remote_host() { + local ($_, %_); + my ($r, $addr); + + # Looked-up before + if (defined $RemoHost_remote) { + return $RemoHost_remote ne "-"? $RemoHost_remote: undef; + } + + if ($IS_MODPERL) { + $r = $IS_MP2? Apache2::RequestUtil->request: + Apache->request; + $addr = $r->connection->remote_ip; + $_ = $IS_MP2? $r->connection->get_remote_host: + $r->get_remote_host; + return ($RemoHost_remote = $_) + if defined $_ && $_ ne $addr; + } else { + $addr = $ENV{"REMOTE_ADDR"}; + # The server had done the job + return ($RemoHost_remote = $ENV{"REMOTE_HOST"}) + if exists $ENV{"REMOTE_HOST"} + && $ENV{"REMOTE_HOST"} ne $addr; + } + + # Look up now + $_ = gethostbyaddr inet_aton($addr), AF_INET; + return ($RemoHost_remote = $_) if defined $_; + + # Return not found + $RemoHost_remote = "-"; + return undef; +} + +return 1; diff --git a/lib/perl5/Selima/ReqURI.pm b/lib/perl5/Selima/ReqURI.pm new file mode 100644 index 0000000..abe4c20 --- /dev/null +++ b/lib/perl5/Selima/ReqURI.pm @@ -0,0 +1,196 @@ +# Selima Website Content Management System +# ReqURI.pm: The request URI finder. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-23 + +package Selima::ReqURI; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(init_request_uri); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub init_request_uri(); +sub path_info_is_broken(); +} + +use CGI qw(); +use File::Spec::Functions qw(catdir splitdir); +use URI::Escape qw(uri_escape); + +use Selima::DataVars qw($SESSION :env :requri :siteconf); +use Selima::HTTPS; +use Selima::Server; +use Selima::Session; + +# init_request_uri: Obtain the REQUEST_URI +sub init_request_uri() { + local ($_, %_); + my ($r, $file, $script, $script_name, $query, $port); + + # Calculated before + return if defined $REQUEST_URI; + + # mod_perl has no CGI environment variables when run at PerlInitHandler + $r = $IS_MP2? Apache2::RequestUtil->request: Apache->request + if $IS_MODPERL; + + # Build the document root + # Selima/.pm should always be put at /magicat/lib/perl5/Selima/.pm + $DOC_ROOT = join "/", splitdir $INC{"Selima/$PACKAGE.pm"}; + $DOC_ROOT =~ s/\/(?:magicat|admin)\/lib\/perl5\/Selima\/$PACKAGE.pm$//; + $DOC_ROOT = catdir splitdir $DOC_ROOT; + # Find the root difference + # Apache stores the file name in SCRIPT_FILENAME + undef $file; + if (!$IS_CGI) { + $file = $0; + } elsif ($IS_MODPERL) { + $file = $r->filename; + } elsif (is_apache()) { + $file = $ENV{"SCRIPT_FILENAME"}; + # Microsoft-IIS stores the file name in PATH_TRANSLATED + } elsif (is_iis()) { + $file = $ENV{"PATH_TRANSLATED"}; + # I have not seen any other implementation yet. + } + undef $script; + if (defined $file) { + $file = join "/", splitdir $file; + $_ = join "/", splitdir $DOC_ROOT; + $script = $1 if $file =~ /^$_(\/.+)$/; + } + undef $ROOT_DIFF; + if (defined $script) { + if ($IS_MODPERL) { + $script_name = $r->uri; + $_ = $r->path_info; + $script_name =~ s/$_$//; + } else { + $script_name = $ENV{"SCRIPT_NAME"}; + } + $script_name =~ s/\/cgi-(perl|raw)\//\/cgi-bin\//; + $ROOT_DIFF = $1 if $script_name =~ /^(.+)$script$/; + } + # Assume no root difference if that is not available + $ROOT_DIFF = "" if !defined $ROOT_DIFF; + + # Build the REQUEST_PATH first + if ($IS_MODPERL) { + $REQUEST_URI = $r->the_request; + $_ = $r->protocol; + $REQUEST_URI =~ s/\s+$_//; + $_ = $r->method; + $REQUEST_URI =~ s/^$_\s+//; + # Remove the schema and host part with absoluteURI + $REQUEST_URI =~ s/^[^:\/ ]+:\/\/[^\/ ]+//; + $REQUEST_PATH = $REQUEST_URI; + $REQUEST_PATH =~ s/\?.*$//; + + # Apache REQUEST_URI exists. Use it for simplicity and accuracy. + } elsif (exists $ENV{"REQUEST_URI"}) { + $REQUEST_URI = $ENV{"REQUEST_URI"}; + # Remove the schema and host part with absoluteURI + $REQUEST_URI =~ s/^[^:\/ ]+:\/\/[^\/ ]+//; + $REQUEST_PATH = $REQUEST_URI; + $REQUEST_PATH =~ s/\?.*$//; + + # Construct the REQUEST_PATH from scratches + # Avoid it whenever possible, since its result is not always right, + # especially for directory indices, like index.php. + } else { + $REQUEST_PATH = $ENV{"SCRIPT_NAME"}; + $REQUEST_PATH .= $ENV{"PATH_INFO"} + if exists $ENV{"PATH_INFO"} && !path_info_is_broken; + } + $REQUEST_PATH =~ s/^$ROOT_DIFF//; + + # Set the REQUEST_FILE from REQUEST_PATH + $REQUEST_FILE = $REQUEST_PATH; + $REQUEST_FILE =~ s/^.*\///; + # Set to "." for directories, since we do not know what + # exact file name it should be + $REQUEST_FILE = "." if $REQUEST_FILE eq ""; + + # Strip the unwanted arguments from the query string + $query = ""; + if ($IS_MODPERL) { + $query = $r->args if defined $r->args; + } else { + $query = $ENV{"QUERY_STRING"} + if exists $ENV{"QUERY_STRING"} && $ENV{"QUERY_STRING"} ne ""; + } + # Construct the REQUEST_URI + # REQUEST_URI is raw. All arguments are kept. + $REQUEST_URI = $REQUEST_PATH . ($query ne ""? "?$query": "") + if !defined $REQUEST_URI; + if ($query ne "") { + ($_, $query) = (new CGI($query), ""); + # Remove the unwanted arguments + # *NOTE*: session may not be started yet + $_->delete("lang", $Selima::Session::NAME, "charset"); + if (defined $_->param) { + @_ = qw(); + foreach my $name ($_->param) { + foreach my $val ($_->param($name)) { + push @_, uri_escape($name) . "=" . uri_escape($val) + } + } + $query = "?" . join "&", @_; + } + } + # Construct the REQUEST_FILEQS + $REQUEST_FILEQS = $REQUEST_FILE . $query; + + # Construct the REQUEST_FULLURI, with the scheme and the host name + $REQUEST_SCHEME = !$IS_CGI? "file": is_https()? "https": "http"; + if (!$IS_CGI) { + $REQUEST_HOST = "localhost"; + } elsif ($IS_MODPERL) { + $REQUEST_HOST = defined $r->hostname? $r->hostname: + $r->server->server_hostname; + } else { + if (exists $ENV{"HTTP_HOST"}) { + $REQUEST_HOST = $ENV{"HTTP_HOST"}; + $REQUEST_HOST =~ s/:\d+$//; + } else { + $REQUEST_HOST = $ENV{"SERVER_NAME"}; + } + } + # Deal with the URI bug that remembers the port when calculating authority + $_ = $IS_MODPERL? $r->get_server_port: $ENV{"SERVER_PORT"}; + $port = ($_ == (is_https()? 443: 80)? "": ":$_"); + $REQUEST_HOSTPORT = $REQUEST_SCHEME . "://" . $REQUEST_HOST . $port . $ROOT_DIFF; + $REQUEST_HOSTPATH = new URI($REQUEST_HOSTPORT . $REQUEST_PATH); + $REQUEST_FULLURI = new URI($REQUEST_SCHEME . "://" . $REQUEST_HOST . $port . $REQUEST_URI); + + return; +} + +# path_info_is_broken: If the server has a broken PATH_INFO +sub path_info_is_broken() { + local ($_, %_); + # Microsoft-IIS is broken + return 1 if is_iis(); + return 0; +} + +return 1; diff --git a/lib/perl5/Selima/ScptPriv.pm b/lib/perl5/Selima/ScptPriv.pm new file mode 100644 index 0000000..c240b3f --- /dev/null +++ b/lib/perl5/Selima/ScptPriv.pm @@ -0,0 +1,99 @@ +# Selima Website Content Management System +# ScptPriv.pm: The script privilege checkers. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-28 + +package Selima::ScptPriv; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(is_script_permitted is_admin_script); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub is_script_permitted(;$); +sub is_admin_script(;$); +} + +use Selima::Cache qw(:scptpriv); +use Selima::ChkPriv; +use Selima::DataVars qw($DBH :requri); +use Selima::Guest; +use Selima::LogIn; + +# is_script_permitted: Check the script privilege +sub is_script_permitted(;$) { + local ($_, %_); + my ($script, $sth, $sql, $count); + $script = $_[0]; + # Default to the current script + $script = $REQUEST_PATH if !defined $script; + + # Return the cache + return $ScptPriv_is_script_permitted{$script} + if exists $ScptPriv_is_script_permitted{$script}; + + # Always true for super users + return ($ScptPriv_is_script_permitted{$script} = 1) if is_su(); + + # Obtain the permitted groups + $sql = "SELECT groups.id AS grp FROM scptpriv" + . " INNER JOIN groups ON scptpriv.grp=groups.sn" + . " WHERE scptpriv.script=" . $DBH->quote($script) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + $count = $sth->rows; + for ($_ = 0, @_ = qw(); $_ < $count; $_++) { + push @_, ${$sth->fetch}[0]; + } + + # Only true for guests to act like ordinary administrators + return ($ScptPriv_is_script_permitted{$script} = 1) + if is_guest && scalar(@_) > 0; + + # Obtain the belonged groups + %_ = map { $_ => 1 } @_; + @_ = get_login_groups; + # If there is any intersection + foreach (@_) { + return ($ScptPriv_is_script_permitted{$script} = 1) + if exists $_{$_}; + } + + # Default to false + return ($ScptPriv_is_script_permitted{$script} = 0); +} + +# is_admin_script: If this is an administrative script +sub is_admin_script(;$) { + local ($_, %_); + my $script; + $script = $_[0]; + # Default to the current script + $script = $REQUEST_PATH if !defined $script; + # Return the cache + return $ScptPriv_is_admin_script{$script} + if exists $ScptPriv_is_admin_script{$script}; + # Check the "/magicat/" or "/admin/" prefix + return ($ScptPriv_is_admin_script{$script} = + $script =~ /^\/(?:magicat|admin)\//); +} + +return 1; diff --git a/lib/perl5/Selima/Server.pm b/lib/perl5/Selima/Server.pm new file mode 100644 index 0000000..500e9a9 --- /dev/null +++ b/lib/perl5/Selima/Server.pm @@ -0,0 +1,62 @@ +# Selima Website Content Management System +# Server.pm: The server software identifiers. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-12 + +package Selima::Server; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(is_apache is_iis); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub is_apache(); +sub is_iis(); +} + +use Selima::DataVars qw(:env); + +# The result never changes in any circumstances +use vars qw($IS_APACHE $IS_IIS); +undef $IS_APACHE; +undef $IS_IIS; + +# is_apache: If this server is Apache +sub is_apache() { + # Checked before + return $IS_APACHE if defined $IS_APACHE; + # mod_perl always run on Apache + return ($IS_APACHE = 1) if $IS_MODPERL; + # Check from SERVER_SOFTWARE + return ($IS_APACHE = ($ENV{"SERVER_SOFTWARE"} =~ /^Apache\b/? 1: 0)); +} + +# is_iis: If this server is Microsoft-IIS +sub is_iis() { + # Checked before + return $IS_IIS if defined $IS_IIS; + # mod_perl never run on Microsoft-IIS + return ($IS_IIS = 0) if $IS_MODPERL; + # Check from SERVER_SOFTWARE + return ($IS_IIS = ($ENV{"SERVER_SOFTWARE"} =~ /^Microsoft-(?:IIS|PWS)\b/? 1: 0)); +} + +return 1; diff --git a/lib/perl5/Selima/Session.pm b/lib/perl5/Selima/Session.pm new file mode 100644 index 0000000..d3bb231 --- /dev/null +++ b/lib/perl5/Selima/Session.pm @@ -0,0 +1,259 @@ +# Selima Website Content Management System +# Session.pm: The custom session handler. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-03 + +package Selima::Session; +use 5.008; +use strict; +use warnings; +BEGIN { +sub sorter($); +} + +use CGI::Cookie qw(); +use Data::Dumper qw(); +use Digest::MD5 qw(md5_hex); +use Fcntl qw(:flock :seek); +use File::Spec::Functions qw(catfile tmpdir); +use IO::File; # To use IO::Handle->flush + +BEGIN { +if (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + require Apache2::Connection; +} +} + +use Selima::DataVars qw(:env :input :output :proctime); +use Selima::FormFunc; +use Selima::HTTP; +use Selima::Logging; + +use vars qw($DIR $NAME $META_SESSION); +use constant DEFAULT_DIR => "/dev/shm/cgi"; +$DIR = DEFAULT_DIR; +if (!-e $DIR) { + mkdir $DIR or http_500 "$DIR: $!"; + chmod 0700, $DIR or http_500 "$DIR: $!"; +} elsif (!(-d $DIR && -w $DIR)) { + $DIR = $ENV{"HOME"} . "/tmp"; + $DIR = tmpdir if !(-d $DIR && -w $DIR); +} +$NAME = "SID"; + +# This is much simpler than CGI::Session and Apache::Session +# And the most important, it is working, but they are not. :p +# CGI::Session use several storage engines. Session data +# are not locked throughout the session, but only on +# initialization, flush and close, in order to meet different +# capability on different storage engine. +# Apache::Session creates a seperate session lock file in order +# to meet different capability of different storage engine. +# This is doomed to fail. :p +# I'm not using different storage engine. That's not useful to +# me at all. Besides, using Data::Dumper make things very +# easy, easier than working around the problems of them. +# It is easier to work on myself. +# I am not using Apache mod_perl memory to store the session data +# anymore. Using share memory file system /dev/shm to store +# the session data if needed, to get rid of disk I/O overhead. +# Having multiple copies of session data in memory, in Apache +# and /dev/shm, is non-sense. It is a nightmare to decide the +# one to use and synchronize the other, too. + +# import: Set the session directory +sub import : method { $DIR = $_[1] if defined $_[1]; }; + +# init: Initialize the session +sub init : method { + local ($_, %_); + my ($class, $DH, $id, $is_old, $file, $remote); + my ($newcookie, $origumask, $FH, $meta); + $class = $_[0]; + + # Do not initialize twice + return $$META_SESSION{"data"} if defined $META_SESSION; + + # Expire old sessions from disk + if ($DIR eq DEFAULT_DIR) { + opendir $DH, $DIR or http_500 "$DIR: $!"; + while (defined($_ = readdir $DH)) { + next if /^\./; + $file = catfile($DIR, $_); + next unless -f $file; + next if $T_START - (stat $file)[8] < 9000; + unlink $file; + } + closedir $DH or http_500 "$DIR: $!"; + } + + # Get the remote IP + $remote = $IS_MODPERL? ($IS_MP2? + Apache2::RequestUtil->request->connection->remote_ip: + Apache->request->connection->remote_ip): + $ENV{"REMOTE_ADDR"}; + + # Obtain the session ID + $is_old = 0; + $_ = get_or_post; + $id = defined $_->param($NAME)? $_->param($NAME): + exists $COOKIES{$NAME}? $COOKIES{$NAME}->value: undef; + if (defined $id) { + $file = catfile($DIR, "sess_" . $id); + # Get the session from the disk file, mod_perl or not. + # Store on share memory file system /dev/shm to get rid + # of disk I/O instead. + if (-e $file) { + open $FH, "+<$file" or http_500 "$file: $!"; + flock $FH, LOCK_EX or http_500 "$file: $!"; + read $FH, $_, (stat $file)[7] or http_500 "$file: $!"; + $META_SESSION = eval $_; + # Not from the same host -- reject it + if ($$META_SESSION{"remote"} ne $remote) { + flock $FH, LOCK_UN or http_500 "$file: $!"; + $FH->close or http_500 "$file: $!"; + undef $FH; + undef $META_SESSION; + undef $id; + } else { + $$META_SESSION{"mtime"} = (stat $file)[9]; + $$META_SESSION{"atime"} = time; + $$META_SESSION{"fh"} = $FH; + ${$$META_SESSION{"data"}}{".meta"} = $META_SESSION; + $$META_SESSION{"dump"} = $$META_SESSION{"data"}->dump; + $is_old = 1; + } + } + } + + # Create a new session + if (!$is_old) { + # Generate a new session ID + if (!defined $id) { + do { + $_ = ""; + $_ .= chr int rand 256 while length $_ < 32; + $id = md5_hex($_); + $file = catfile($DIR, "sess_" . $id); + } until !-e $file; + } + $META_SESSION = { + "mtime" => time, + "atime" => time, + "id" => $id, + "name" => $NAME, + "remote" => $remote, + "data" => bless({}, $class), + "file" => $file, + }; + # Self-referring, so that we can find ourself later. + ${$$META_SESSION{"data"}}{".meta"} = $META_SESSION; + # Create the session file + $origumask = umask 0077; + open $FH, "+>$file" or http_500 "$file: $!"; + flock $FH, LOCK_EX or http_500 "$file: $!"; + umask $origumask; + $$META_SESSION{"fh"} = $FH; + # Dump the session + $_ = $$META_SESSION{"data"}->dump; + $$META_SESSION{"dump"} = $_; + print $FH $_ or http_500 "$file: $!"; + $FH->flush or http_500 "$file: $!"; + } + + # Set the cookie + if (!exists $COOKIES{$NAME} || $COOKIES{$NAME}->value ne $id) { + $newcookie = new CGI::Cookie(-name=>$NAME, -value=>$id); + $COOKIES{$NAME} = $newcookie; + $NEWCOOKIES{$NAME} = $newcookie; + } + + return $$META_SESSION{"data"}; +} + +# sorter: Dump the session +sub sorter($) { + local ($_, %_); + %_ = map { $_ => 1 } keys %{$_[0]}; + delete $_{"mtime"}; + delete $_{"atime"}; + delete $_{"fh"}; + delete $_{"dump"}; + return [sort keys %_]; +} + +# dump: Dump the session +sub dump : method { + local ($_, %_); + my ($self, $meta, $dumper); + $self = $_[0]; + $meta = $$self{".meta"}; + # Clone the meta-session + $dumper = new Data::Dumper([$meta], [qw($_)]); + $dumper->Indent(1); + $dumper->Sortkeys(\&sorter); + return $dumper->Dump; +} + +# flush: Flush the session data to the hard disk +sub flush : method { + local ($_, %_); + my ($self, $meta, $FH); + $self = $_[0]; + $meta = $$self{".meta"}; + # Return if session content not updated + return if ($_ = $self->dump) eq $$meta{"dump"}; + $$meta{"dump"} = $_; + # Update the mtime + $$meta{"mtime"} = time; + # Output and flush the data + $FH = $$meta{"fh"}; + seek $FH, 0, SEEK_SET or http_500 $$meta{"file"} . ": $!"; + truncate $FH, 0 or http_500 $$meta{"file"} . ": $!"; + print $FH $$meta{"dump"} or http_500 $$meta{"file"} . ": $!"; + $FH->flush or http_500 $$meta{"file"} . ": $!"; + return; +} + +# close: Close the session +sub close : method { + local ($_, %_); + my ($self, $meta, $FH); + # Only close for once + return unless defined $META_SESSION; + $self = $_[0]; + $meta = $$self{".meta"}; + # Flush the session data + $self->flush; + # Close the data file + $FH = $$meta{"fh"}; + flock $FH, LOCK_UN or http_500 $$meta{"file"} . ": $!"; + $FH->close or http_500 $$meta{"file"} . ": $!"; + # Undefine the session variables + # This is not DESTROY. $META_SESSION will not be cleaned automatically. + undef $META_SESSION; + return; +} + +# DESTROY: Flush and close the session before everything ends +sub DESTROY : method { + $_[0]->close; + $_[0]->SUPER::DESTROY if $_[0]->can("SUPER::DESTROY"); +} + +return 1; diff --git a/lib/perl5/Selima/SetL10N.pm b/lib/perl5/Selima/SetL10N.pm new file mode 100644 index 0000000..db6a524 --- /dev/null +++ b/lib/perl5/Selima/SetL10N.pm @@ -0,0 +1,123 @@ +# Selima Website Content Management System +# SetL10N.pm: The subroutine to set the localization handler. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-10-26 + +package Selima::SetL10N; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(set_l10n); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub set_l10n(;$); +} + +# Ensure that these modules are installed +use Encode::Big5Common qw(); +use Encode::HanExtra qw(); # For GB18030, real encoding used in GB2312 forms +use Encode::Alias qw(define_alias); +# Set Big5 to Big5-Common +define_alias("Big5", "Big5-Common"); + +use Selima::Cache qw(:setl10n); +use Selima::DataVars qw(:l10n :lninfo :siteconf); +use Selima::GetLang; +use Selima::HTTP; +use Selima::LnInfo; + +use Selima::L10N; + +use vars qw(%LH %CLH); + +# set_l10n: Set the current language handler +sub set_l10n(;$) { + local ($_, %_); + my $lang; + $lang = $_[0]; + $lang = getlang if !defined $lang; + + # Set the package language handler + # Cached -- use the cache + if (exists $LH{$PACKAGE} && exists ${$LH{$PACKAGE}}{$lang}) { + $LH = ${$LH{$PACKAGE}}{$lang}; + # Automatic reload text whenever it is updated + if (-e $LH->{"MOFILE"}) { + $SetL10N_checked{$PACKAGE} = {} + if !exists $SetL10N_checked{$PACKAGE}; + if (!exists ${$SetL10N_checked{$PACKAGE}}{$lang}) { + $_ = (stat $LH->{"MOFILE"})[9]; + if ($LH->{"MOFILE_MTIME"} < $_) { + $LH->{"MOFILE_MTIME"} = $_; + $LH->reload_text; + } + ${$SetL10N_checked{$PACKAGE}}{$lang} = 1; + } + } + # Not cached yet + } else { + $_ = "Selima::" . $PACKAGE . "::L10N"; + $LH = $_->get_handle($lang) + or http_500 "Failed creating language handle from $_ for $lang"; + $LH->encoding(undef); + $LH->bindtextdomain($PACKAGE, $LOCALEDIR); + $LH->textdomain($PACKAGE); + # Cache it + $LH{$PACKAGE} = {} if !exists $LH{$PACKAGE}; + ${$LH{$PACKAGE}}{$lang} = $LH; + $LH->{"MOFILE_MTIME"} = (stat $LH->{"MOFILE"})[9] + if -e $LH->{"MOFILE"}; + } + + # Set the common language handler + # Cached -- use the cache + if (exists $CLH{$lang}) { + $CLH = $CLH{$lang}; + # Automatic reload text whenever it is updated + if (-e $CLH->{"MOFILE"}) { + $SetL10N_checked{COMMON_DOMAIN()} = {} + if !exists $SetL10N_checked{COMMON_DOMAIN()}; + if (!exists ${$SetL10N_checked{COMMON_DOMAIN()}}{$lang}) { + $_ = (stat $CLH->{"MOFILE"})[9]; + if ($CLH->{"MOFILE_MTIME"} < $_) { + $CLH->{"MOFILE_MTIME"} = $_; + $CLH->reload_text; + } + ${$SetL10N_checked{COMMON_DOMAIN()}}{$lang} = 1; + } + } + # Not cached yet + } else { + $CLH = Selima::L10N->get_handle($lang) + or http_500 "Failed creating language handle from Selima::L10N for $lang"; + $CLH->encoding(undef); + $CLH->bindtextdomain(COMMON_DOMAIN, COMMON_LOCALEDIR); + # Cache it + $CLH->textdomain(COMMON_DOMAIN); + $CLH{$lang} = $CLH; + $CLH->{"MOFILE_MTIME"} = (stat $CLH->{"MOFILE"})[9] + if -e $CLH->{"MOFILE"}; + } + + return; +} + +return 1; diff --git a/lib/perl5/Selima/ShortCut.pm b/lib/perl5/Selima/ShortCut.pm new file mode 100644 index 0000000..9228ca9 --- /dev/null +++ b/lib/perl5/Selima/ShortCut.pm @@ -0,0 +1,108 @@ +# Selima Website Content Management System +# ShortCut.pm: The shortcut subroutines. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-23 + +package Selima::ShortCut; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(h dh __ C_ F_ N_); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub h($); +sub dh($); +sub __($@); +sub C_($@); +sub F_($@); +sub N_($@); +} + +use Selima::DataVars qw(:l10n); + +# Define them first +# h: Escape the HTML characters +sub h($) { + local ($_, %_); + $_ = $_[0]; + return "" if !defined $_; + s/&/&/g; + s//>/g; + s/"/"/g; # (xgettext) " + return $_; +} + +# dh: De-escape the HTML characters +sub dh($) { + local ($_, %_); + $_ = $_[0]; + return "" if !defined $_; + s/"/"/g; # (xgettext) " + s/>/>/g; + s/</maketext($key, @params); +} +# C_: Maketext in the common domain +sub C_($@) { + local ($_, %_); + my ($key, @params); + ($key, @params) = @_; + # Initialize the localization framework + set_l10n if !defined $CLH; + return $CLH->maketext($key, @params); +} +# F_: Maketext, fallback from the current domain to the common domain +sub F_($@) { + local ($_, %_); + my ($key, @params, $pkg); + ($key, @params) = @_; + # Initialize the localization framework + Selima::SetL10N::set_l10n if !defined $LH || !defined $CLH; + # Try the local text + return $LH->maketext($key, @params) + if exists ${$LH->{"Lexicon"}}{$key}; + # Try the common text + return $CLH->maketext($key, @params); +} + +return 1; diff --git a/lib/perl5/Selima/Unauth.pm b/lib/perl5/Selima/Unauth.pm new file mode 100644 index 0000000..9aa1965 --- /dev/null +++ b/lib/perl5/Selima/Unauth.pm @@ -0,0 +1,60 @@ +# Selima Website Content Management System +# Unauth.pm: The unauthorized access processor. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-28 + +package Selima::Unauth; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(unauth); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub unauth(); +} + +use URI::Escape qw(uri_escape); + +use Selima::DataVars qw(:requri); +use Selima::LogIn; +use Selima::HTTP; + +# unauth: User is not authorized +sub unauth() { + local ($_, %_); + + # Logged in but privilege not enough + http_403 if defined get_login_sn; + + # Not logged in yet - log in + @_ = qw(); + push @_, "referer=" . uri_escape($REQUEST_FULLURI); + # To be done + #$script = userhome(); + $_ = "login.cgi?" . join "&", @_; + if ($ENV{"REQUEST_METHOD"} eq "POST") { + http_303 $_; + } else { + http_307 $_; + } +} + +return 1; diff --git a/lib/perl5/Selima/Unicode.pm b/lib/perl5/Selima/Unicode.pm new file mode 100644 index 0000000..58ec864 --- /dev/null +++ b/lib/perl5/Selima/Unicode.pm @@ -0,0 +1,244 @@ +# Selima Website Content Management System +# Unicode.pm: The subroutines to deal with character set encodings. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-23 + +package Selima::Unicode; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(h_encode a_encode); +push @EXPORT, qw(is_charset is_usascii_printable is_usascii_printable_text); +push @EXPORT, qw(all_to_trad all_to_simp); +push @EXPORT, qw(hcref_encode hcref_decode page_encode); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub h_encode($;$); +sub a_encode($;$); +sub is_charset($$); +sub is_usascii_printable($); +sub is_usascii_printable_text($); +sub all_to_trad($); +sub all_to_simp($); +sub hcref_encode($$); +sub hcref_decode($$); +sub page_encode($$); +sub hcref2char($); +sub hcref2char_keep($); +} + +use Config qw(%Config); +use Encode qw(encode decode from_to FB_CROAK FB_HTMLCREF); +use File::Basename qw(dirname); +use File::Spec::Functions qw(splitdir catdir); +use GDBM_File qw(GDBM_READER); +use HTML::Entities qw(%entity2char %char2entity); + +use Selima::A2HTML; +use Selima::HTTP; +use Selima::DataVars qw(:lninfo); +use Selima::GetLang; +use Selima::ShortCut; + +use vars qw(%BIG5_RANGES $ETEN_EXT); +%BIG5_RANGES = ( + "常用字" => [ 0xA440, 0xC67E ], # 5401 + "次常用字" => [ 0xC940, 0xF9D5 ], # 7652 + "常用符號" => [ 0xA140, 0xA3BF ], # 408 +# "控制碼" => [ 0xA3C0, 0xA3E0 ], # 33 +# "罕用符號" => [ 0xC6A1, 0xC8FE ], +); + +# Big5 is indeed Big5-ETen, which has ETen extension character that covers +# Japanese, where ETen extension is not covered by Microsoft CP950. +# Using Big5 (Big5-ETen) will preserve Japanese characters that cannot +# be displayed under Microsoft Internet Explorer. +# CP950 converts European characters into US-ASCII. European characters +# will not be output correctly. + +use vars qw($ALL2TRAD %ALL2TRAD $ALL2SIMP %ALL2SIMP); +BEGIN { +my (@dirs, $arch); +@dirs = splitdir(dirname((caller 1)[1])); +$arch = $Config{"myarchname"}; +$arch =~ s/-[^\-]+$//; +$ALL2TRAD = catdir(@dirs[0..$#dirs-2], $arch, "all2trad.db"); +$ALL2SIMP = catdir(@dirs[0..$#dirs-2], $arch, "all2simp.db"); +} + +# h_encode: Encode and escape HTML special characters +sub h_encode($;$) { + local ($_, %_); + my ($source, $encoding); + ($source, $encoding) = @_; + $encoding = getlang LN_CHARSET if !defined $encoding; + return hcref_encode($encoding, h($source)); +} + +# a_encode: Encode and convert from plain text to HTML +sub a_encode($;$) { + local ($_, %_); + my ($source, $encoding); + ($source, $encoding) = @_; + $encoding = getlang LN_CHARSET if !defined $encoding; + return hcref_encode($encoding, a2html($source)); +} + +# is_charset: If a piece of text is in a certain character set +sub is_charset($$) { + local ($_, %_); + my ($text, $charset); + ($text, $charset) = @_; + eval { encode($charset, $text, FB_CROAK); }; + return $@ eq ""; +} + +# is_usascii_printable: If a piece of text is US-ASCII printable +# Positive range. Decoded unicode text may have a HEX value larger than \xFF. +sub is_usascii_printable($) { + local ($_, %_); + $_ = $_[0]; + # Scalar + return /^[\x20-\x7E]+$/ if ref $_ eq ""; + # Array + if (ref $_ eq "ARRAY") { + @_ = @$_; + foreach (@_) { + return 0 if !is_usascii_printable $_; + } + return 1; + } + # Hash + if (ref $_ eq "HASH") { + %_ = %$_; + foreach (keys %_) { + return 0 if !is_usascii_printable $_ + || !is_usascii_printable $_{$_}; + } + return 1; + } + # False for others. We have no idea about other types of data. + return 0; +} + +# is_usascii_printable_text: If a piece of multi-line text is US-ASCII printable +# Positive range. Decoded unicode text may have a HEX value larger than \xFF. +sub is_usascii_printable_text($) { $_[0] =~ /^[\x20-\x7E\s]+$/; } + +# all_to_trad: Convert all Simplified characters in text to Traditional Chinese +sub all_to_trad($) { + local ($_, %_); + my $text; + $text = $_[0]; + if (!tied %ALL2TRAD) { + tie %ALL2TRAD, "GDBM_File", $ALL2TRAD, &GDBM_READER, 0644 + or http_500 "$ALL2TRAD: $!"; + } + @_ = split //, $text; + foreach my $c (@_) { + $_ = ord $c; + $c = chr $ALL2TRAD{$_} if exists $ALL2TRAD{$_}; + } + return join "", @_; +} + +# all_to_simp: Convert all Simplified characters in text to Traditional Chinese +sub all_to_simp($) { + local ($_, %_); + my $text; + $text = $_[0]; + if (!tied %ALL2SIMP) { + tie %ALL2SIMP, "GDBM_File", $ALL2SIMP, &GDBM_READER, 0644 + or http_500 "$ALL2SIMP: $!"; + } + @_ = split //, $text; + foreach my $c (@_) { + $_ = ord $c; + $c = chr $ALL2SIMP{$_} if exists $ALL2SIMP{$_}; + } + return join "", @_; +} + +# hcref_encode: Encode text with HTML character entity references +sub hcref_encode($$) { + local ($_, %_); + my $charset; + ($charset, $_) = @_; + $_ = encode($charset, $_, FB_HTMLCREF); + s/&#(\d{1,10});/exists $char2entity{chr $1}? $char2entity{chr $1}: "&#$1;";/ge; + return $_; +} + +# hcref_decode: Decode octets and HTML character references +sub hcref_decode($$) { + local ($_, %_); + my $charset; + ($charset, $_) = @_; + eval { $_ = decode($charset, $_, FB_CROAK); 1; }; + return undef if $@ ne ""; + return hcref2char($_); +} + +# page_encode: encode() an HTML page +sub page_encode($$) { + local ($_, %_); + my $charset; + ($_, $charset) = @_; + $_ = hcref_encode($charset, $_); + return if !defined $_; + $charset = h($charset); + s//$charset/g; + return $_; +} + +# hcref2char: Decode HTML character entity references +# The input and output should have already been decoded +# It preserves encoded US-ASCII characters. US-ASCII characters do +# not need to be encoded. There must be some reason to encode them. +# (like @/@, </<, >/>, etc.) +sub hcref2char($) { + local ($_, %_); + $_ = $_[0]; + + # Numeric character references (decimal) + s/&#(\d{1,10});/my $c = decode("UTF-32LE", pack("V", $1), FB_CROAK); + !hcref2char_keep($c)? $c: "&#$1;";/ge; + # Numeric character references (hexadecimal) + s/&#x([0-9a-f]{1,8});/my $c = decode("UTF-32LE", pack("V", hex $1), FB_CROAK); + !hcref2char_keep($c)? $c: "&#x$1;";/gei; + # Character entity references + s/&([a-z]{2,8}\d{0,2};)/ + if ( !exists $entity2char{$1} + || hcref2char_keep($entity2char{$1})) { + "&$1"; + } else { + $entity2char{$1}; + } /gei; + + return $_; +} + +# hcref2char_keep: If this character should not be decoded +# HTML characters are not decoded (<, >, ", &) " gettext +sub hcref2char_keep($) { $_[0] =~ /^[<>s"&]$/; } # " gettext + +return 1; diff --git a/lib/perl5/Selima/UserName.pm b/lib/perl5/Selima/UserName.pm new file mode 100644 index 0000000..2750bda --- /dev/null +++ b/lib/perl5/Selima/UserName.pm @@ -0,0 +1,273 @@ +# Selima Website Content Management System +# UserName.pm: The user information subroutines. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-26 + +package Selima::UserName; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(); +push @EXPORT, qw(username userid groupid groupdsc groupsn); +push @EXPORT, qw(user_opt_label group_opt_label su_group_sn); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub username($); +sub userid($); +sub groupid($); +sub groupdsc($); +sub groupsn($); +sub user_opt_label($;$); +sub group_opt_label($;$); +sub su_group_sn(); +} + +use Selima::Cache qw(:username); +use Selima::ChkFunc; +use Selima::CommText; +use Selima::DataVars qw($DBH :groups :l10n :lninfo); +use Selima::GetLang; +use Selima::LnInfo; +use Selima::ShortCut; + +# username: Obtain a user name +sub username($) { + local ($_, %_); + my ($sn, $sql, $sth); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + # Return the cache + return $UserName_username{$sn} if exists $UserName_username{$sn}; + + # Check the serial number first + return ($UserName_username{$sn} = t_na) + if !check_sn $sn; + + # Query + $sql = "SELECT name FROM users WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return ($UserName_username{$sn} = t_na) + unless $sth->rows == 1; + + # Found + return ($UserName_username{$sn} = ${$sth->fetch}[0]); +} + +# userid: Obtain a user ID. +sub userid($) { + local ($_, %_); + my ($sn, $sql, $sth); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + # Return the cache + return $UserName_userid{$sn} if exists $UserName_userid{$sn}; + + # Check the serial number first + return ($UserName_userid{$sn} = t_na) + if !check_sn $sn; + + # Query + $sql = "SELECT id FROM users WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return ($UserName_userid{$sn} = t_na) + unless $sth->rows == 1; + + # Found + return ($UserName_userid{$sn} = ${$sth->fetch}[0]); +} + +# groupid: Obtain a group ID. +sub groupid($) { + local ($_, %_); + my ($sn, $sql, $sth); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + # Return the cache + return $UserName_groupid{$sn} if exists $UserName_groupid{$sn}; + + # Check the serial number first + return ($UserName_groupid{$sn} = t_na) + if !check_sn $sn; + + # Query + $sql = "SELECT id FROM groups WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return ($UserName_groupid{$sn} = t_na) + unless $sth->rows == 1; + + # Found + return ($UserName_groupid{$sn} = ${$sth->fetch}[0]); +} + +# groupdsc: Obtain a group description +sub groupdsc($) { + local ($_, %_); + my ($sn, $sql, $sth, $col, $thiscol, $defcol); + $sn = $_[0]; + # Bounce if there is any problem with $sn + return t_notset if !defined $sn; + # Return the cache + return $UserName_groupdsc{$sn} if exists $UserName_groupdsc{$sn}; + + # Check the serial number first + return ($UserName_groupdsc{$sn} = t_na) + if !check_sn $sn; + + # Query + # Unilingual + if (@ALL_LINGUAS == 1) { + $col = "dsc AS dsc"; + # Multilingual + } else { + $thiscol = "dsc_" . getlang(LN_DATABASE); + # Default language + if (getlang eq $DEFAULT_LANG) { + $col = "$thiscol AS dsc"; + # Fall back to the default language + } else { + $defcol = "title_" . ln($DEFAULT_LANG, LN_DATABASE); + $col = "COALESCE($thiscol, $defcol) AS dsc"; + } + } + $sql = "SELECT $col FROM groups WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return ($UserName_groupdsc{$sn} = t_na) + unless $sth->rows == 1; + + # Found + return ($UserName_groupdsc{$sn} = ${$sth->fetch}[0]); +} + +# groupsn: Obtain a group S/N +sub groupsn($) { + local ($_, %_); + my ($id, $sql, $sth); + $id = $_[0]; + # Bounce if there is any problem with $id + return if !defined $id; + # Return the cache + return $UserName_groupsn{$id} if exists $UserName_groupsn{$id}; + + # Query + $sql = "SELECT sn FROM groups" + . " WHERE id=" . $DBH->quote($id) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return ($UserName_groupsn{$id} = undef) unless $sth->rows == 1; + + # Found + return ($UserName_groupsn{$id} = ${$sth->fetch}[0]); +} + +# user_opt_label: Obtain a user option label +sub user_opt_label($;$) { + local ($_, %_); + my ($sn, $for, $sql, $sth); + ($sn, $for) = @_; + # Check the validity of the serial number first + return if !check_sn $sn; + $sql = "SELECT id, name FROM users" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return if $sth->rows != 1; + $_ = $sth->fetchrow_hashref; + if (defined $for) { + return sprintf("", + h($for), h($$_{"id"}), h($$_{"name"})); + } else { + return sprintf("%s (%s)", + h($$_{"id"}), h($$_{"name"})); + } +} + +# group_opt_label: Obtain a group option label +sub group_opt_label($;$) { + local ($_, %_); + my ($sn, $for, $sql, $sth, $lndb, $lndbdef, $dsc); + ($sn, $for) = @_; + # Check the validity of the serial number first + return t_na if !check_sn $sn; + if (@ALL_LINGUAS > 1) { + $lndb = getlang LN_DATABASE; + if (getlang eq $DEFAULT_LANG) { + $dsc = "dsc_$lndb AS dsc"; + } else { + $lndbdef = ln $DEFAULT_LANG, LN_DATABASE; + $dsc = "COALESCE(dsc_$lndb, dsc_$lndbdef) AS dsc"; + } + } else { + $dsc = "dsc AS dsc"; + } + $sql = "SELECT id, $dsc FROM groups" + . " WHERE sn=$sn;\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return t_na if $sth->rows != 1; + $_ = $sth->fetchrow_hashref; + if (defined $for) { + return sprintf("", + h($for), h($$_{"id"}), h($$_{"dsc"})); + } else { + return sprintf("%s (%s)", + h($$_{"id"}), h($$_{"dsc"})); + } +} + +# su_group_sn: Return the S/N of the super user group +# Return 0 on "no super user group" +sub su_group_sn() { + local ($_, %_); + my ($sth, $sql); + # Return the cache + return $UserName_su_group_sn if defined $UserName_su_group_sn; + + # Query + $sql = "SELECT sn FROM groups" + . " WHERE id=" . $DBH->quote(SU_GROUP) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + + # Not found + return ($UserName_su_group_sn = 0) if $sth->rows != 1; + + # Found + return ($UserName_su_group_sn = ${$sth->fetchrow_hashref}{"sn"}); +} + +return 1; diff --git a/lib/perl5/Selima/UserPref.pm b/lib/perl5/Selima/UserPref.pm new file mode 100644 index 0000000..fd4369b --- /dev/null +++ b/lib/perl5/Selima/UserPref.pm @@ -0,0 +1,121 @@ +# Selima Website Content Management System +# UserPref.pm: The user preference subroutine. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-12 + +package Selima::UserPref; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(userpref); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub userpref($;$); +} + +use Selima::Cache qw(:userpref); +use Selima::DataVars qw($DBH $SESSION :requri :user); +use Selima::Guest; +use Selima::LogIn; + +# userpref: Obtain the specified user preference +sub userpref($;$) { + local ($_, %_); + my ($name, $domain, $cache, $sql, $sth, $row); + ($name, $domain) = @_; + # Set the default domain + $domain = $REQUEST_PATH if !defined $domain; + # Initialize the cache + $UserPref_userpref{$domain} = {} if !exists $UserPref_userpref{$domain}; + $cache = $UserPref_userpref{$domain}; + # Return the cache + return $$cache{$name} if exists $$cache{$name}; + + # User system not available + if (!use_users || !defined $SESSION) { + return ($$cache{$name} = ${$USERPREF{$domain}}{$name}) + if exists $USERPREF{$domain} + && exists ${$USERPREF{$domain}}{$name}; + return ($$cache{$name} = undef); + } + + # User system is in use + # Check guest preferences in $SESSION + if (is_guest) { + # Check the preference on this domain + return ($$cache{$name} = ${${$$SESSION{"userpref"}}{$domain}}{$name}) + if exists $$SESSION{"userpref"} + && exists ${$$SESSION{"userpref"}}{$domain} + && exists ${${$$SESSION{"userpref"}}{$domain}}{$name}; + # Check the default preference + return ($$cache{$name} = ${${$$SESSION{"userpref"}}{"*"}}{$name}) + if exists $$SESSION{"userpref"} + && exists ${$$SESSION{"userpref"}}{"*"} + && exists ${${$$SESSION{"userpref"}}{"*"}}{$name}; + } + + # Already logged in -- check the user preference + if (defined get_login_sn) { + # Check the user preference on this domain + $sql = "SELECT value FROM userpref" + . " WHERE usr=" . get_login_sn + . " AND domain=" . $DBH->quote($domain) + . " AND name=" . $DBH->quote($name) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return ($$cache{$name} = ${$sth->fetch}[0]) + if $sth->rows == 1; + + # Check the default preference of this user + $sql = "SELECT value FROM userpref" + . " WHERE usr=" . get_login_sn + . " AND domain IS NULL" + . " AND name=" . $DBH->quote($name) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return ($$cache{$name} = ${$sth->fetch}[0]) + if $sth->rows == 1; + } + + # Check the default preference on this domain + $sql = "SELECT value FROM userpref" + . " WHERE usr IS NULL" + . " AND domain=" . $DBH->quote($domain) + . " AND name=" . $DBH->quote($name) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return ($$cache{$name} = ${$sth->fetch}[0]) + if $sth->rows == 1; + + # Check the default preference for everything + $sql = "SELECT value FROM userpref" + . " WHERE usr IS NULL" + . " AND domain IS NULL" + . " AND name=" . $DBH->quote($name) . ";\n"; + $sth = $DBH->prepare($sql); + $sth->execute; + return ($$cache{$name} = ${$sth->fetch}[0]) + if $sth->rows == 1; + + return ($$cache{$name} = undef); +} + +return 1; diff --git a/lib/perl5/Selima/XFileIO.pm b/lib/perl5/Selima/XFileIO.pm new file mode 100644 index 0000000..44bdec7 --- /dev/null +++ b/lib/perl5/Selima/XFileIO.pm @@ -0,0 +1,232 @@ +# Selima Website Content Management System +# XFileIO.pm: The extended file input/output subroutines. + +# Copyright (c) 2003-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2003-03-24 + +package Selima::XFileIO; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(xfread xfwrite xfappend xfupdate xfupdate_template); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub xfread($); +sub xfwrite($$); +sub xfappend($$); +sub xfupdate($$); +sub xfupdate_template($$;$); +sub template_updated($$$); +} + +use Fcntl qw(:flock :seek); + +use Selima::DataVars qw(:scptconf); +use Selima::HTTP; + +# xfread: Read from a file +# Input: file path $file +# Output: file content +sub xfread($) { + local ($_, %_); + my ($FH, $file, $size); + $file = $_[0]; + + # Return as lines + if (wantarray) { + open $FH, $file or http_500 "$file: $!"; + flock $FH, LOCK_SH or http_500 "$file: $!"; + @_ = <$FH>; + flock $FH, LOCK_UN or http_500 "$file: $!"; + close $FH or http_500 "$file: $!"; + return @_; + + # A scalar file content + } else { + # Regular files + if (-f $file) { + @_ = stat $file or http_500 "$file: $!"; + $size = $_[7]; + return "" if $size == 0; + open $FH, $file or http_500 "$file: $!"; + flock $FH, LOCK_SH or http_500 "$file: $!"; + read $FH, $_, $size or http_500 "$file: $!"; + flock $FH, LOCK_UN or http_500 "$file: $!"; + close $FH or http_500 "$file: $!"; + return $_; + + # Special files + } else { + open $FH, $file or http_500 "$file: $!"; + flock $FH, LOCK_SH or http_500 "$file: $!"; + $_ = join "", <$FH>; + flock $FH, LOCK_UN or http_500 "$file: $!"; + close $FH or http_500 "$file: $!"; + return $_; + } + } +} + +# xfwrite: Write to a file +# Input: file path $file and file content $conten +# Output: none +sub xfwrite($$) { + local ($_, %_); + my ($FH, $file, $content); + ($file, $content) = @_; + + open $FH, ">$file" or http_500 "$file: $!"; + flock $FH, LOCK_EX or http_500 "$file: $!"; + print $FH $content or http_500 "$file: $!"; + flock $FH, LOCK_UN or http_500 "$file: $!"; + close $FH or http_500 "$file: $!"; + + return; +} + +# xfappend: Append to a file +# Input: file path $file and file content $conten +# Output: none +sub xfappend($$) { + local ($_, %_); + my ($FH, $file, $content); + ($file, $content) = @_; + + open $FH, ">>$file" or http_500 "$file: $!"; + flock $FH, LOCK_EX or http_500 "$file: $!"; + print $FH $content or http_500 "$file: $!"; + flock $FH, LOCK_UN or http_500 "$file: $!"; + close $FH or http_500 "$file: $!"; + + return; +} + +# xfupdate: Update a file +# Input: file path $file and file content $conten +# Output: none +sub xfupdate($$) { + local ($_, %_); + my ($FH, $file, $content, $size); + ($file, $content) = @_; + + # Write as a new file if the old file does not exist + if (!-e $file) { + open $FH, ">$file" or http_500 "$file: $!"; + flock $FH, LOCK_EX or http_500 "$file: $!"; + print $FH $content or http_500 "$file: $!"; + flock $FH, LOCK_UN or http_500 "$file: $!"; + close $FH or http_500 "$file: $!"; + + # Old file exists -- compare the content and update only if necessary + } else { + @_ = stat $file or http_500 "$file: $!"; + $size = $_[7]; + open $FH, "+<$file" or http_500 "$file: $!"; + flock $FH, LOCK_SH or http_500 "$file: $!"; + if ($size == 0) { + $_ = ""; + } else { + read $FH, $_, $size or http_500 "$file: $!"; + } + if ($_ ne $content) { + seek $FH, 0, SEEK_SET or http_500 "$file: $!"; + truncate $FH, 0 or http_500 "$file: $!"; + print $FH $content or http_500 "$file: $!"; + } + flock $FH, LOCK_UN or http_500 "$file: $!"; + close $FH or http_500 "$file: $!"; + } + return; +} + +# xfupdate_template: Update a file comparing with a template +# Input: the file path $file, the new content template $tmpl +# and its replacements $rep +# Output: none +sub xfupdate_template($$;$) { + local ($_, %_); + my ($FH, $file, $tmpl, $rep, $old, $new, $size); + ($file, $tmpl, $rep) = @_; + # Obtain the replacements + $rep = defined($_ = $MAIN->can("page_replacements"))? &$_: {} + if !defined $rep; + + # Write as a new file if the old file does not exist + if (!-e $file) { + $new = $tmpl; + $new =~ s//${$$rep{$_}}{"content"}/g + foreach keys %$rep; + xfwrite($file, $new); + + # Old file exists -- compare the content and update only if necessary + } else { + @_ = stat $file or http_500 "$file: $!"; + $size = $_[7]; + open $FH, "+<$file" or http_500 "$file: $!"; + flock $FH, LOCK_EX or http_500 "$file: $!"; + if ($size == 0) { + $old = ""; + } else { + read $FH, $old, $size or http_500 "$file: $!"; + } + # Not matched + if (template_updated $old, $tmpl, $rep) { + $new = $tmpl; + $new =~ s//${$$rep{$_}}{"content"}/g + foreach keys %$rep; + seek $FH, 0, SEEK_SET or http_500 "$file: $!"; + truncate $FH, 0 or http_500 "$file: $!"; + print $FH $new or http_500 "$file: $!"; + } + flock $FH, LOCK_UN or http_500 "$file: $!"; + close $FH or http_500 "$file: $!"; + } + +} + +# template_updated: If a page is updated comparing to the template +sub template_updated($$$) { + local ($_, %_); + my ($old, $tmpl, $rep); + ($old, $tmpl, $rep) = @_; + + # Process piece by piece + while ($tmpl =~ s/^(.*?)()(.*)$/$4/s) { + my ($plain, $repsec, $key); + ($plain, $repsec, $key) = ($1, $2, $3); + + # Try to match the plain text part + return 1 if $old !~ s/^\Q$plain\E//; + + # A valid replacement is found -- try to match the pattern + if (exists $$rep{$key}) { + return 1 if $old !~ s/^${$$rep{$key}}{"pattern"}//; + + # Not a valid replacement -- treat it as a plain text part + } else { + return 1 if $old !~ s/^\Q$repsec\E//; + } + } + # Check the remains as a plain text part + return 1 if $old ne $tmpl; + return 0; +} + +return 1; diff --git a/lib/perl5/Selima/XHTML.pm b/lib/perl5/Selima/XHTML.pm new file mode 100644 index 0000000..bba54e9 --- /dev/null +++ b/lib/perl5/Selima/XHTML.pm @@ -0,0 +1,63 @@ +# Selima Website Content Management System +# XHTML.pm: The subroutine to return application/xhtml+xml on supported browsers and text/html othersise. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-12-26 + +package Selima::XHTML; +use 5.008; +use strict; +use warnings; +use base qw(Exporter); +use vars qw(@EXPORT @EXPORT_OK); +BEGIN { +@EXPORT = qw(xhtml_content_type); +@EXPORT_OK = @EXPORT; +# Prototype declaration +sub xhtml_content_type(); +} + +use Selima::DataVars qw($IS_MODPERL :env); + +# xhtml_content_type: Check whether application/xhtml+xml or text/html +# should be sent to the client +sub xhtml_content_type() { + local ($_, %_); + my ($r, $acpt, $ua); + + # Obtain the required parameters + if ($IS_MODPERL) { + $r = $IS_MP2? Apache2::RequestUtil->request: + Apache->request; + $acpt = $r->headers_in->get("Accept"); + $ua = $r->headers_in->get("User-Agent"); + } else { + $acpt = exists $ENV{"HTTP_ACCEPT"}? $ENV{"HTTP_ACCEPT"}: undef; + $ua = exists $ENV{"HTTP_USER_AGENT"}? $ENV{"HTTP_USER_AGENT"}: undef; + } + + # Browsers that claim to support application/xhtml+xml explicitly + return "application/xhtml+xml" + if defined $acpt && $acpt =~ /\bapplication\/xhtml\+xml\b/; + # Browsers that are known to support application/xhtml+xml + return "application/xhtml+xml" + if defined $ua && $ua =~ /^W3C_Validator\//; + # Else, we assume that application/xhtml+xml is not supported + return "text/html"; +} + +return 1; diff --git a/lib/perl5/Selima/startup.pl b/lib/perl5/Selima/startup.pl new file mode 100644 index 0000000..615d5ee --- /dev/null +++ b/lib/perl5/Selima/startup.pl @@ -0,0 +1,55 @@ +#! /usr/bin/perl -w +# Selima Website Content Management System +# startup.pl: The mod_perl environment initializer. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-09-20 + +use 5.005; +use strict; +use warnings; + +# Add the library directory to @INC +# FindBin cannot be used here, for $0 is /dev/null. +use lib qw(/srv/www/lib/perl5); +use lib qw(/srv/www/htdocs/imacat/magicat/lib/perl5); +use lib qw(/srv/www/htdocs/wov/magicat/lib/perl5); +use lib qw(/srv/www/htdocs/emily/magicat/lib/perl5); +use lib qw(/srv/www/htdocs/htc/magicat/lib/perl5); +use lib qw(/srv/www/htdocs/emandy/magicat/lib/perl5); +# Pre-load perl modules +use Selima qw(); +use Selima::imacat qw(); +use Selima::wov qw(); +use Selima::emily qw(); +use Selima::htc qw(); +use Selima::emandy qw(); +use Selima::Init qw(); +BEGIN { +unless (exists $ENV{"MOD_PERL_API_VERSION"} && $ENV{"MOD_PERL_API_VERSION"} >= 2) { + require Selima::AuthDig; +} +} +use Selima::XHTML qw(); +# Make the session directory +if (!-e $Selima::Session::DIR) { + mkdir $Selima::Session::DIR; + chown(@_ = (getpwnam "nobody")[2,3], $Selima::Session::DIR); + chmod 0700, $Selima::Session::DIR; +} + +return 1 diff --git a/lib/perl5/Selima/urlcheck b/lib/perl5/Selima/urlcheck new file mode 100755 index 0000000..b77cc24 --- /dev/null +++ b/lib/perl5/Selima/urlcheck @@ -0,0 +1,114 @@ +#! /usr/bin/perl -w +# Selima Website Content Management System +# urlcheck: The URL validator. + +# Copyright (c) 2004-2018 imacat. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Author: imacat +# First written: 2004-11-06 + +use 5.008; +use strict; +use warnings; +use threads; +use threads::shared; +# Prototype declaration +sub main(); +sub check_urls(); +sub check_urls_nonthread(); +sub check_urls_in_a_thread(); +sub is_reachable($); + +use Config qw(%Config); +use LWP::UserAgent; +use Net::Telnet; +use URI; + +our ($CURINDEX, @URLS) : shared; +$CURINDEX = 0; +@URLS = qw(); + + +main; +exit 0; + +sub main() { + local ($_, %_); + + @URLS = ; + chomp foreach @URLS; + check_urls; + print join "", map "$_\n", @URLS; + + return; +} + +# check_urls: Proform URL checks (with threading) +sub check_urls() { + local ($_, %_); + # Run check_urls_nonthread() if ithread is not available + return check_urls_nonthread + if !defined $Config{"useithreads"}; + # Start the thread workers + for ($_ = 0, @_ = qw(); $_ < 10; $_++) { + push @_, threads->new(\&check_urls_in_a_thread) + } + # Wait for everyone to end + $_->join foreach @_; + # Return the result + return; +} + +# check_urls_nonthread: Proform URL checks without threading +sub check_urls_nonthread() { + local ($_, %_); + @URLS = map is_reachable($_), @URLS; + return; +} + +# check_urls_in_a_thread: Proform URL checks in a thread +sub check_urls_in_a_thread() { + local ($_, %_); + # Check until the end + while (($_ = $CURINDEX++) < @URLS) { + $URLS[$_] = is_reachable($URLS[$_]); + } + return; +} + +# is_reachable: Check if the target of an URL is reachable +sub is_reachable($) { + local ($_, %_); + my ($uri, $UA, $r); + $_ = $_[0]; + # Check if it is available + # LWP::UserAgent cannot handle telnet. We check it with Net::Telnet. + if (/^telnet:\/\//) { + $uri = new URI($_); + %_ = ( + Host => $uri->host, + Port => $uri->port, + ); + eval { new Net::Telnet(%_) }; + return ($@ eq ""? 1: 0); + + # Use LWP::UserAgent + } else { + $UA = new LWP::UserAgent; + $UA->timeout(20); + $r = $UA->get($_); + return (!$r->is_error? 1: 0); + } +} diff --git a/lib/php/GeoIP/geoip.inc b/lib/php/GeoIP/geoip.inc new file mode 100644 index 0000000..a095469 --- /dev/null +++ b/lib/php/GeoIP/geoip.inc @@ -0,0 +1,498 @@ + 0, "AP" => 1, "EU" => 2, "AD" => 3, "AE" => 4, "AF" => 5, +"AG" => 6, "AI" => 7, "AL" => 8, "AM" => 9, "AN" => 10, "AO" => 11, +"AQ" => 12, "AR" => 13, "AS" => 14, "AT" => 15, "AU" => 16, "AW" => 17, +"AZ" => 18, "BA" => 19, "BB" => 20, "BD" => 21, "BE" => 22, "BF" => 23, +"BG" => 24, "BH" => 25, "BI" => 26, "BJ" => 27, "BM" => 28, "BN" => 29, +"BO" => 30, "BR" => 31, "BS" => 32, "BT" => 33, "BV" => 34, "BW" => 35, +"BY" => 36, "BZ" => 37, "CA" => 38, "CC" => 39, "CD" => 40, "CF" => 41, +"CG" => 42, "CH" => 43, "CI" => 44, "CK" => 45, "CL" => 46, "CM" => 47, +"CN" => 48, "CO" => 49, "CR" => 50, "CU" => 51, "CV" => 52, "CX" => 53, +"CY" => 54, "CZ" => 55, "DE" => 56, "DJ" => 57, "DK" => 58, "DM" => 59, +"DO" => 60, "DZ" => 61, "EC" => 62, "EE" => 63, "EG" => 64, "EH" => 65, +"ER" => 66, "ES" => 67, "ET" => 68, "FI" => 69, "FJ" => 70, "FK" => 71, +"FM" => 72, "FO" => 73, "FR" => 74, "FX" => 75, "GA" => 76, "GB" => 77, +"GD" => 78, "GE" => 79, "GF" => 80, "GH" => 81, "GI" => 82, "GL" => 83, +"GM" => 84, "GN" => 85, "GP" => 86, "GQ" => 87, "GR" => 88, "GS" => 89, +"GT" => 90, "GU" => 91, "GW" => 92, "GY" => 93, "HK" => 94, "HM" => 95, +"HN" => 96, "HR" => 97, "HT" => 98, "HU" => 99, "ID" => 100, "IE" => 101, +"IL" => 102, "IN" => 103, "IO" => 104, "IQ" => 105, "IR" => 106, "IS" => 107, +"IT" => 108, "JM" => 109, "JO" => 110, "JP" => 111, "KE" => 112, "KG" => 113, +"KH" => 114, "KI" => 115, "KM" => 116, "KN" => 117, "KP" => 118, "KR" => 119, +"KW" => 120, "KY" => 121, "KZ" => 122, "LA" => 123, "LB" => 124, "LC" => 125, +"LI" => 126, "LK" => 127, "LR" => 128, "LS" => 129, "LT" => 130, "LU" => 131, +"LV" => 132, "LY" => 133, "MA" => 134, "MC" => 135, "MD" => 136, "MG" => 137, +"MH" => 138, "MK" => 139, "ML" => 140, "MM" => 141, "MN" => 142, "MO" => 143, +"MP" => 144, "MQ" => 145, "MR" => 146, "MS" => 147, "MT" => 148, "MU" => 149, +"MV" => 150, "MW" => 151, "MX" => 152, "MY" => 153, "MZ" => 154, "NA" => 155, +"NC" => 156, "NE" => 157, "NF" => 158, "NG" => 159, "NI" => 160, "NL" => 161, +"NO" => 162, "NP" => 163, "NR" => 164, "NU" => 165, "NZ" => 166, "OM" => 167, +"PA" => 168, "PE" => 169, "PF" => 170, "PG" => 171, "PH" => 172, "PK" => 173, +"PL" => 174, "PM" => 175, "PN" => 176, "PR" => 177, "PS" => 178, "PT" => 179, +"PW" => 180, "PY" => 181, "QA" => 182, "RE" => 183, "RO" => 184, "RU" => 185, +"RW" => 186, "SA" => 187, "SB" => 188, "SC" => 189, "SD" => 190, "SE" => 191, +"SG" => 192, "SH" => 193, "SI" => 194, "SJ" => 195, "SK" => 196, "SL" => 197, +"SM" => 198, "SN" => 199, "SO" => 200, "SR" => 201, "ST" => 202, "SV" => 203, +"SY" => 204, "SZ" => 205, "TC" => 206, "TD" => 207, "TF" => 208, "TG" => 209, +"TH" => 210, "TJ" => 211, "TK" => 212, "TM" => 213, "TN" => 214, "TO" => 215, +"TL" => 216, "TR" => 217, "TT" => 218, "TV" => 219, "TW" => 220, "TZ" => 221, +"UA" => 222, "UG" => 223, "UM" => 224, "US" => 225, "UY" => 226, "UZ" => 227, +"VA" => 228, "VC" => 229, "VE" => 230, "VG" => 231, "VI" => 232, "VN" => 233, +"VU" => 234, "WF" => 235, "WS" => 236, "YE" => 237, "YT" => 238, "RS" => 239, +"ZA" => 240, "ZM" => 241, "ME" => 242, "ZW" => 243, "A1" => 244, "A2" => 245, +"O1" => 246, "AX" => 247, "GG" => 248, "IM" => 249, "JE" => 250 +); + var $GEOIP_COUNTRY_CODES = array( +"", "AP", "EU", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", +"AR", "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", +"BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", +"CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", +"CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", +"EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "FX", "GA", "GB", +"GD", "GE", "GF", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", +"GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN", +"IO", "IQ", "IR", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", +"KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", +"LT", "LU", "LV", "LY", "MA", "MC", "MD", "MG", "MH", "MK", "ML", "MM", "MN", +"MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", +"NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", +"PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", +"QA", "RE", "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", +"SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TC", "TD", +"TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TL", "TR", "TT", "TV", "TW", +"TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", +"VU", "WF", "WS", "YE", "YT", "RS", "ZA", "ZM", "ME", "ZW", "A1", "A2", "O1", +"AX", "GG", "IM", "JE" +); + var $GEOIP_COUNTRY_CODES3 = array( +"","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","ANT","AGO","AQ","ARG", +"ASM","AUT","AUS","ABW","AZE","BIH","BRB","BGD","BEL","BFA","BGR","BHR","BDI", +"BEN","BMU","BRN","BOL","BRA","BHS","BTN","BV","BWA","BLR","BLZ","CAN","CC", +"COD","CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI","CUB","CPV", +"CX","CYP","CZE","DEU","DJI","DNK","DMA","DOM","DZA","ECU","EST","EGY","ESH", +"ERI","ESP","ETH","FIN","FJI","FLK","FSM","FRO","FRA","FX","GAB","GBR","GRD", +"GEO","GUF","GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","GS","GTM","GUM", +"GNB","GUY","HKG","HM","HND","HRV","HTI","HUN","IDN","IRL","ISR","IND","IO", +"IRQ","IRN","ISL","ITA","JAM","JOR","JPN","KEN","KGZ","KHM","KIR","COM","KNA", +"PRK","KOR","KWT","CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU", +"LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI","MMR","MNG","MAC", +"MNP","MTQ","MRT","MSR","MLT","MUS","MDV","MWI","MEX","MYS","MOZ","NAM","NCL", +"NER","NFK","NGA","NIC","NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER", +"PYF","PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW","PRY","QAT", +"REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN","SWE","SGP","SHN","SVN","SJM", +"SVK","SLE","SMR","SEN","SOM","SUR","STP","SLV","SYR","SWZ","TCA","TCD","TF", +"TGO","THA","TJK","TKL","TLS","TKM","TUN","TON","TUR","TTO","TUV","TWN","TZA", +"UKR","UGA","UM","USA","URY","UZB","VAT","VCT","VEN","VGB","VIR","VNM","VUT", +"WLF","WSM","YEM","YT","SRB","ZAF","ZMB","MNE","ZWE","A1","A2","O1", +"ALA","GGY","IMN","JEY" + ); + var $GEOIP_COUNTRY_NAMES = array( +"", "Asia/Pacific Region", "Europe", "Andorra", "United Arab Emirates", +"Afghanistan", "Antigua and Barbuda", "Anguilla", "Albania", "Armenia", +"Netherlands Antilles", "Angola", "Antarctica", "Argentina", "American Samoa", +"Austria", "Australia", "Aruba", "Azerbaijan", "Bosnia and Herzegovina", +"Barbados", "Bangladesh", "Belgium", "Burkina Faso", "Bulgaria", "Bahrain", +"Burundi", "Benin", "Bermuda", "Brunei Darussalam", "Bolivia", "Brazil", +"Bahamas", "Bhutan", "Bouvet Island", "Botswana", "Belarus", "Belize", +"Canada", "Cocos (Keeling) Islands", "Congo, The Democratic Republic of the", +"Central African Republic", "Congo", "Switzerland", "Cote D'Ivoire", "Cook +Islands", "Chile", "Cameroon", "China", "Colombia", "Costa Rica", "Cuba", "Cape +Verde", "Christmas Island", "Cyprus", "Czech Republic", "Germany", "Djibouti", +"Denmark", "Dominica", "Dominican Republic", "Algeria", "Ecuador", "Estonia", +"Egypt", "Western Sahara", "Eritrea", "Spain", "Ethiopia", "Finland", "Fiji", +"Falkland Islands (Malvinas)", "Micronesia, Federated States of", "Faroe +Islands", "France", "France, Metropolitan", "Gabon", "United Kingdom", +"Grenada", "Georgia", "French Guiana", "Ghana", "Gibraltar", "Greenland", +"Gambia", "Guinea", "Guadeloupe", "Equatorial Guinea", "Greece", "South Georgia +and the South Sandwich Islands", "Guatemala", "Guam", "Guinea-Bissau", +"Guyana", "Hong Kong", "Heard Island and McDonald Islands", "Honduras", +"Croatia", "Haiti", "Hungary", "Indonesia", "Ireland", "Israel", "India", +"British Indian Ocean Territory", "Iraq", "Iran, Islamic Republic of", +"Iceland", "Italy", "Jamaica", "Jordan", "Japan", "Kenya", "Kyrgyzstan", +"Cambodia", "Kiribati", "Comoros", "Saint Kitts and Nevis", "Korea, Democratic +People's Republic of", "Korea, Republic of", "Kuwait", "Cayman Islands", +"Kazakstan", "Lao People's Democratic Republic", "Lebanon", "Saint Lucia", +"Liechtenstein", "Sri Lanka", "Liberia", "Lesotho", "Lithuania", "Luxembourg", +"Latvia", "Libyan Arab Jamahiriya", "Morocco", "Monaco", "Moldova, Republic +of", "Madagascar", "Marshall Islands", "Macedonia", +"Mali", "Myanmar", "Mongolia", "Macau", "Northern Mariana Islands", +"Martinique", "Mauritania", "Montserrat", "Malta", "Mauritius", "Maldives", +"Malawi", "Mexico", "Malaysia", "Mozambique", "Namibia", "New Caledonia", +"Niger", "Norfolk Island", "Nigeria", "Nicaragua", "Netherlands", "Norway", +"Nepal", "Nauru", "Niue", "New Zealand", "Oman", "Panama", "Peru", "French +Polynesia", "Papua New Guinea", "Philippines", "Pakistan", "Poland", "Saint +Pierre and Miquelon", "Pitcairn Islands", "Puerto Rico", "Palestinian Territory", +"Portugal", "Palau", "Paraguay", "Qatar", "Reunion", "Romania", +"Russian Federation", "Rwanda", "Saudi Arabia", "Solomon Islands", +"Seychelles", "Sudan", "Sweden", "Singapore", "Saint Helena", "Slovenia", +"Svalbard and Jan Mayen", "Slovakia", "Sierra Leone", "San Marino", "Senegal", +"Somalia", "Suriname", "Sao Tome and Principe", "El Salvador", "Syrian Arab +Republic", "Swaziland", "Turks and Caicos Islands", "Chad", "French Southern +Territories", "Togo", "Thailand", "Tajikistan", "Tokelau", "Turkmenistan", +"Tunisia", "Tonga", "Timor-Leste", "Turkey", "Trinidad and Tobago", "Tuvalu", +"Taiwan", "Tanzania, United Republic of", "Ukraine", +"Uganda", "United States Minor Outlying Islands", "United States", "Uruguay", +"Uzbekistan", "Holy See (Vatican City State)", "Saint Vincent and the +Grenadines", "Venezuela", "Virgin Islands, British", "Virgin Islands, U.S.", +"Vietnam", "Vanuatu", "Wallis and Futuna", "Samoa", "Yemen", "Mayotte", +"Serbia", "South Africa", "Zambia", "Montenegro", "Zimbabwe", +"Anonymous Proxy","Satellite Provider","Other", +"Aland Islands","Guernsey","Isle of Man","Jersey" +); +} +function geoip_load_shared_mem ($file) { + + $fp = fopen($file, "rb"); + if (!$fp) { + print "error opening $file: $php_errormsg\n"; + exit; + } + $s_array = fstat($fp); + $size = $s_array['size']; + if ($shmid = @shmop_open (GEOIP_SHM_KEY, "w", 0, 0)) { + shmop_delete ($shmid); + shmop_close ($shmid); + } + $shmid = shmop_open (GEOIP_SHM_KEY, "c", 0644, $size); + shmop_write ($shmid, fread($fp, $size), 0); + shmop_close ($shmid); +} + +function _setup_segments($gi){ + $gi->databaseType = GEOIP_COUNTRY_EDITION; + $gi->record_length = STANDARD_RECORD_LENGTH; + if ($gi->flags & GEOIP_SHARED_MEMORY) { + $offset = @shmop_size ($gi->shmid) - 3; + for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) { + $delim = @shmop_read ($gi->shmid, $offset, 3); + $offset += 3; + if ($delim == (chr(255).chr(255).chr(255))) { + $gi->databaseType = ord(@shmop_read ($gi->shmid, $offset, 1)); + $offset++; + + if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){ + $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0; + } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){ + $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1; + } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0)|| + ($gi->databaseType == GEOIP_CITY_EDITION_REV1) + || ($gi->databaseType == GEOIP_ORG_EDITION) + || ($gi->databaseType == GEOIP_ISP_EDITION) + || ($gi->databaseType == GEOIP_ASNUM_EDITION)){ + $gi->databaseSegments = 0; + $buf = @shmop_read ($gi->shmid, $offset, SEGMENT_RECORD_LENGTH); + for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){ + $gi->databaseSegments += (ord($buf[$j]) << ($j * 8)); + } + if (($gi->databaseType == GEOIP_ORG_EDITION)|| + ($gi->databaseType == GEOIP_ISP_EDITION)) { + $gi->record_length = ORG_RECORD_LENGTH; + } + } + break; + } else { + $offset -= 4; + } + } + if (($gi->databaseType == GEOIP_COUNTRY_EDITION)|| + ($gi->databaseType == GEOIP_PROXY_EDITION)|| + ($gi->databaseType == GEOIP_NETSPEED_EDITION)){ + $gi->databaseSegments = GEOIP_COUNTRY_BEGIN; + } + } else { + $filepos = ftell($gi->filehandle); + fseek($gi->filehandle, -3, SEEK_END); + for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) { + $delim = fread($gi->filehandle,3); + if ($delim == (chr(255).chr(255).chr(255))){ + $gi->databaseType = ord(fread($gi->filehandle,1)); + if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){ + $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0; + } + else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){ + $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1; + } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0) || + ($gi->databaseType == GEOIP_CITY_EDITION_REV1) || + ($gi->databaseType == GEOIP_ORG_EDITION) || + ($gi->databaseType == GEOIP_ISP_EDITION) || + ($gi->databaseType == GEOIP_ASNUM_EDITION)){ + $gi->databaseSegments = 0; + $buf = fread($gi->filehandle,SEGMENT_RECORD_LENGTH); + for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){ + $gi->databaseSegments += (ord($buf[$j]) << ($j * 8)); + } + if ($gi->databaseType == GEOIP_ORG_EDITION || + $gi->databaseType == GEOIP_ISP_EDITION) { + $gi->record_length = ORG_RECORD_LENGTH; + } + } + break; + } else { + fseek($gi->filehandle, -4, SEEK_CUR); + } + } + if (($gi->databaseType == GEOIP_COUNTRY_EDITION)|| + ($gi->databaseType == GEOIP_PROXY_EDITION)|| + ($gi->databaseType == GEOIP_NETSPEED_EDITION)){ + $gi->databaseSegments = GEOIP_COUNTRY_BEGIN; + } + fseek($gi->filehandle,$filepos,SEEK_SET); + } + return $gi; +} + +function geoip_open($filename, $flags) { + $gi = new GeoIP; + $gi->flags = $flags; + if ($gi->flags & GEOIP_SHARED_MEMORY) { + $gi->shmid = @shmop_open (GEOIP_SHM_KEY, "a", 0, 0); + } else { + $gi->filehandle = fopen($filename,"rb"); + if ($gi->flags & GEOIP_MEMORY_CACHE) { + $s_array = fstat($gi->filehandle); + $gi->memory_buffer = fread($gi->filehandle, $s_array['size']); + } + } + + $gi = _setup_segments($gi); + return $gi; +} + +function geoip_close($gi) { + if ($gi->flags & GEOIP_SHARED_MEMORY) { + return true; + } + + return fclose($gi->filehandle); +} + +function geoip_country_id_by_name($gi, $name) { + $addr = gethostbyname($name); + if (!$addr || $addr == $name) { + return false; + } + return geoip_country_id_by_addr($gi, $addr); +} + +function geoip_country_code_by_name($gi, $name) { + $country_id = geoip_country_id_by_name($gi,$name); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_CODES[$country_id]; + } + return false; +} + +function geoip_country_name_by_name($gi, $name) { + $country_id = geoip_country_id_by_name($gi,$name); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_NAMES[$country_id]; + } + return false; +} + +function geoip_country_id_by_addr($gi, $addr) { + $ipnum = ip2long($addr); + return _geoip_seek_country($gi, $ipnum) - GEOIP_COUNTRY_BEGIN; +} + +function geoip_country_code_by_addr($gi, $addr) { + if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) { + $record = geoip_record_by_addr($gi,$addr); + return $record->country_code; + } else { + $country_id = geoip_country_id_by_addr($gi,$addr); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_CODES[$country_id]; + } + } + return false; +} + +function geoip_country_name_by_addr($gi, $addr) { + if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) { + $record = geoip_record_by_addr($gi,$addr); + return $record->country_name; + } else { + $country_id = geoip_country_id_by_addr($gi,$addr); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_NAMES[$country_id]; + } + } + return false; +} + +function _geoip_seek_country($gi, $ipnum) { + $offset = 0; + for ($depth = 31; $depth >= 0; --$depth) { + if ($gi->flags & GEOIP_MEMORY_CACHE) { + $buf = substr($gi->memory_buffer, + 2 * $gi->record_length * $offset, + 2 * $gi->record_length); + } elseif ($gi->flags & GEOIP_SHARED_MEMORY) { + $buf = @shmop_read ($gi->shmid, + 2 * $gi->record_length * $offset, + 2 * $gi->record_length ); + } else { + fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0 + or die("fseek failed"); + $buf = fread($gi->filehandle, 2 * $gi->record_length); + } + $x = array(0,0); + for ($i = 0; $i < 2; ++$i) { + for ($j = 0; $j < $gi->record_length; ++$j) { + $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8); + } + } + if ($ipnum & (1 << $depth)) { + if ($x[1] >= $gi->databaseSegments) { + return $x[1]; + } + $offset = $x[1]; + } else { + if ($x[0] >= $gi->databaseSegments) { + return $x[0]; + } + $offset = $x[0]; + } + } + trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR); + return false; +} + +function _get_org($gi,$ipnum){ + $seek_org = _geoip_seek_country($gi,$ipnum); + if ($seek_org == $gi->databaseSegments) { + return NULL; + } + $record_pointer = $seek_org + (2 * $gi->record_length - 1) * $gi->databaseSegments; + if ($gi->flags & GEOIP_SHARED_MEMORY) { + $org_buf = @shmop_read ($gi->shmid, $record_pointer, MAX_ORG_RECORD_LENGTH); + } else { + fseek($gi->filehandle, $record_pointer, SEEK_SET); + $org_buf = fread($gi->filehandle,MAX_ORG_RECORD_LENGTH); + } + $org_buf = substr($org_buf, 0, strpos($org_buf, 0)); + return $org_buf; +} + +function geoip_org_by_addr ($gi,$addr) { + if ($addr == NULL) { + return 0; + } + $ipnum = ip2long($addr); + return _get_org($gi, $ipnum); +} + +function _get_region($gi,$ipnum){ + if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){ + $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV0; + if ($seek_region >= 1000){ + $country_code = "US"; + $region = chr(($seek_region - 1000)/26 + 65) . chr(($seek_region - 1000)%26 + 65); + } else { + $country_code = $gi->GEOIP_COUNTRY_CODES[$seek_region]; + $region = ""; + } + return array ($country_code,$region); + } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1) { + $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV1; + //print $seek_region; + if ($seek_region < US_OFFSET){ + $country_code = ""; + $region = ""; + } else if ($seek_region < CANADA_OFFSET) { + $country_code = "US"; + $region = chr(($seek_region - US_OFFSET)/26 + 65) . chr(($seek_region - US_OFFSET)%26 + 65); + } else if ($seek_region < WORLD_OFFSET) { + $country_code = "CA"; + $region = chr(($seek_region - CANADA_OFFSET)/26 + 65) . chr(($seek_region - CANADA_OFFSET)%26 + 65); + } else { + $country_code = $gi->GEOIP_COUNTRY_CODES[($seek_region - WORLD_OFFSET) / FIPS_RANGE]; + $region = ""; + } + return array ($country_code,$region); + } +} + +function geoip_region_by_addr ($gi,$addr) { + if ($addr == NULL) { + return 0; + } + $ipnum = ip2long($addr); + return _get_region($gi, $ipnum); +} + +function getdnsattributes ($l,$ip){ + $r = new Net_DNS_Resolver(); + $r->nameservers = array("ws1.maxmind.com"); + $p = $r->search($l."." . $ip .".s.maxmind.com","TXT","IN"); + $str = is_object($p->answer[0])?$p->answer[0]->string():''; + ereg("\"(.*)\"",$str,$regs); + $str = $regs[1]; + return $str; +} + +?> diff --git a/lib/php/monica/a2html.inc.php b/lib/php/monica/a2html.inc.php new file mode 100644 index 0000000..a94cb88 --- /dev/null +++ b/lib/php/monica/a2html.inc.php @@ -0,0 +1,142 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// This file is in UTF-8 萬國碼 + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/htmlchar.inc.php"; +require_once "monica/markabbr.inc.php"; +require_once "monica/urlregex.inc.php"; + +// The URL regular-expression pattern +define("_A2HTML_URLREGEX_COMBINED", "(?:" . URLREGEX_EMAIL . "|" . URLREGEX_FTP + . "|" . URLREGEX_FILE . "|" . URLREGEX_HTTP . "|" . URLREGEX_HTTPS + . "|" . URLREGEX_GOPHER . "|" . URLREGEX_MAILTO . "|" . URLREGEX_NEWS + . "|" . URLREGEX_NNTP . "|" . URLREGEX_TELNET . "|" . URLREGEX_WAIS + . "|" . URLREGEX_PROSPERO . ")"); + +// The substitution ID configuration +define("_A2HTML_SUBST_ID_LEN", 5); +define("_A2HTML_SUBST_ID_MIN", pow(10, _A2HTML_SUBST_ID_LEN - 1)); +define("_A2HTML_SUBST_ID_MAX", pow(10, _A2HTML_SUBST_ID_LEN) - 1); + +// The punctuation information +$_A2HTML_QUOTES = array( + "\"" => "\"", + "'" => "'", + "`" => "'", + "(" => ")", + "[" => "]", + "{" => "}", + "<" => ">", + "「" => "」", + "『" => "』", + "〈" => "〉", + "《" => "》", + "【" => "】", + "〔" => "〕", + "”" => "”", + "“" => "”", + "‘" => "’", + "‵" => "′", +); +$_A2HTML_DOTS = array( + "...", ".", ",", ":", ";", "!", "?", + "。", ",", ":", ";", "、", "…", "!", "?", +); + +// a2html: Convert a textarea input into HTML content +function a2html($source) +{ + // The punctuation information + global $_A2HTML_QUOTES, $_A2HTML_DOTS; + + $result = $source; + + // Find and record all the URL's + // Process line by line. PHP PCRE has serial bugs that crashes + // randomly when matching RFC-822 e-mails. The reason is not clear. + // We try to avoid it by reducing the text piece size as possible + // while keeping the integrity of the text. This is not a solution, + // though. + $lines = explode("\n", $result); + for ($i = 0; $i < count($lines); $i++) { + $temp = $lines[$i]; + $lines[$i] = ""; + if (substr($temp, 0, 1) == " ") { + $lines[$i] .= " "; + $temp = substr($temp, 1); + } + $substs = array(); + while ( preg_match("/^(.*?)(" . _A2HTML_URLREGEX_COMBINED . ")(.*)$/s", + $temp, $m)) { + // De-quote + foreach (array_keys($_A2HTML_QUOTES) as $start) { + $end = $_A2HTML_QUOTES[$start]; + // In a quotation + if ( substr($m[1], -strlen($start)) == $start + && substr($m[2], -strlen($end)) == $end) { + $m[2] = substr($m[2], 0, -strlen($end)); + $m[3] = $end . $m[3]; + break; + } + } + // Remove trailing dots + foreach ($_A2HTML_DOTS as $dot) { + // End in this dot + if (substr($m[2], -strlen($dot)) == $dot) { + $m[2] = substr($m[2], 0, -strlen($dot)); + $m[3] = $dot . $m[3]; + break; + } + } + // Still matched after the above removal + if (preg_match("/^" . _A2HTML_URLREGEX_COMBINED . "$/", $m[2])) { + $lines[$i] .= _a2html_plain_line($m[1]) . _a2html_url2link($m[2]); + } else { + $lines[$i] .= _a2html_plain_line($m[1] . $m[2]); + } + $temp = $m[3]; + } + // Add the remains + $lines[$i] .= _a2html_plain_line($temp); + } + + $result = implode("\n", $lines); + // Add line breaks + $result = preg_replace("/(\r?\n)/", "
    \\1", $result); + + return $result; +} + +// _a2html_plain_line: Convert plain line content to HTML +function _a2html_plain_line($line) +{ + // Escape the HTML characters and mark the abbreviation + $line = h_abbr($line); + // Tag non-breaking spaces + $line = str_replace(" ", "  ", $line); + return $line; +} + +// _a2html_url2link: Convert an URL to a link +function _a2html_url2link($url) +{ + // There is a scheme + if (preg_match("/^" . URLREGEX_SCHEME . ":/", $url)) { + return "" . h($url) . ""; + // Schemeless - assumed to be an e-mail address + } else { + return "" . h($url) . ""; + } +} + +?> diff --git a/lib/php/monica/actlog.inc.php b/lib/php/monica/actlog.inc.php new file mode 100644 index 0000000..cb81fb9 --- /dev/null +++ b/lib/php/monica/actlog.inc.php @@ -0,0 +1,87 @@ + +// Copyright: Copyright (C) 2002-2013 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/cgiemu.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/requri.inc.php"; + +// Settings +if (!defined("_ACTLOG_DONE_FINDING")) { + _actlog_find_actlog_txt(); + define("_ACTLOG_DONE_FINDING", true); +} + +// actlog: Log an activity +function actlog($message, $user = null) +{ + // ACTLOG must be defined first + if (!defined("ACTLOG")) { + trigger_error("Activity log actlog.txt not found", E_USER_ERROR); + } + $date = date("Y-m-d H:i:s O"); + $script = REQUEST_PATH; + $remote = $_SERVER["REMOTE_ADDR"]; + if (is_null($user)) { + $user = get_login_id(); + if (is_null($user)) { + $user = "anonymous"; + } + } + + // Escape control characters for safety + $message = str_replace("\t", "\\t", $message); + $message = str_replace("\r", "\\r", $message); + $message = str_replace("\n", "\\n", $message); + $message = preg_replace_callback("/([\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F])/", + function ($matches) { + return sprintf("\\x%02x", ord($matches[1])); + }, $message); + + $fp = fopen(ACTLOG, "a"); + flock($fp, LOCK_EX); + fwrite($fp, "[$date] $script: ($user from $remote) $message\n"); + flock($fp, LOCK_UN); + fclose($fp); + return; +} + +// _actlog_find_actlog_txt: Find the activity log file +function _actlog_find_actlog_txt() +{ + // It is set + if (defined("ACTLOG")) { + return; + } + + // The file location candidates + $cands = array(); + if (defined("PACKAGE")) { + $cands[] = "/var/log/apache2/" . PACKAGE . "/actlog.txt"; + } + $cands[] = "/var/log/apache2/actlog.txt"; + + // Find the first available one + $actlog = null; + foreach ($cands as $file) { + if (file_exists($file) && is_file($file) && is_writable($file)) { + $actlog = $file; + break; + } + } + + if (!is_null($actlog)) { + define("ACTLOG", $actlog); + } + return; +} + +?> diff --git a/lib/php/monica/addcol.inc.php b/lib/php/monica/addcol.inc.php new file mode 100644 index 0000000..36e8bb8 --- /dev/null +++ b/lib/php/monica/addcol.inc.php @@ -0,0 +1,1018 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/getlang.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/pic.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/sqlconst.inc.php"; +require_once "monica/upload.inc.php"; + +// Settings +define("ADDCOL_INSERT", 1); +define("ADDCOL_UPDATE", 2); +define("_ADDCOL_TYPE_NULL", "_ADDCOL_TYPE_NULL"); +define("_ADDCOL_TYPE_NUM", "_ADDCOL_TYPE_NUM"); +define("_ADDCOL_TYPE_STR", "_ADDCOL_TYPE_STR"); +define("_ADDCOL_TYPE_DATE", "_ADDCOL_TYPE_DATE"); +define("_ADDCOL_TYPE_IPADDR", "_ADDCOL_TYPE_IPADDR"); +define("_ADDCOL_TYPE_FILE", "_ADDCOL_TYPE_FILE"); +define("_ADDCOL_TYPE_BOOL", "_ADDCOL_TYPE_BOOL"); +define("_ADDCOL_TYPE_EXPR", "_ADDCOL_TYPE_EXPR"); +define("ADDCOL_NOTIMESTAMP", false); + +// AddCol: Prepare columns for SQL updates +class AddCol +{ + // Run as this user + public $login = null; + + private $_cols; + private $_table; + private $_optype; + private $_allcols; + private $_mlcols; + + // __construct: Initialize the columns deposit + function __construct($table, $optype = ADDCOL_UPDATE) + { + $this->_cols = array(); + $this->_table = $table; + $this->_optype = $optype; + if ($GLOBALS["SQL_DBTYPE"] != SQL_NONE) { + $this->_allcols = sql_cols($table); + $this->_mlcols = sql_cols_ml($table); + } else { + $this->_allcols = array(); + $this->_mlcols = array(); + } + } + + // addstr: Add a modified string column to the columns deposit + // Input: $name: The column name. + // $val: The column value. + // $curval: The current value to be compared. + // Output: None. + function addstr($name, $val) + { + // Set the 3rd argument as the current value + $cur_exists = false; + if (func_num_args() == 3) { + $cur_exists = true; + $curval = func_get_arg(2); + } + // Adjust the column name for multi-lingual columns + if (in_array($name, $this->_mlcols)) { + $name .= "_" . getlang(LN_DATABASE); + } + + // The new column value + $col = array(); + $col["name"] = $name; + $col["mod"] = false; + // No value is supplied + if (is_null($val) || $val === "") { + $col["type"] = _ADDCOL_TYPE_NULL; + $col["value"] = null; + // A valid value + } else { + $col["type"] = _ADDCOL_TYPE_STR; + $col["value"] = $val; + } + + // Check if we should set it + switch ($this->_optype) { + case ADDCOL_INSERT: + // Always set the value for INSERT + $col["mod"] = true; + break; + + case ADDCOL_UPDATE: + default: + // A current value is supplied + if ($cur_exists) { + // This column had a value previously + if (!is_null($curval)) { + // It has no value now. Remove it. + if ($col["type"] == _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + // A different new value. Modify it. + } elseif ($col["value"] !== $curval) { + $col["mod"] = true; + } + // This column had no value previously + } else { + // But it has a value now. + if ($col["type"] != _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + } + } + // No current value to compare with. + } else { + // Set it anyway + $col["mod"] = true; + } + break; + } + // Add this column + $this->_cols[] = $col; + return; + } + + // addstr_empty: Add a modified string column to the columns deposit, + // where empty string is allowed + // Input: $name: The column name. + // $val: The column value. + // $curval: The current value to be compared. + // Output: None. + function addstr_empty($name, $val) + { + // Set the 3rd argument as the current value + $cur_exists = false; + if (func_num_args() == 3) { + $cur_exists = true; + $curval = func_get_arg(2); + } + // Adjust the column name for multi-lingual columns + if (in_array($name, $this->_mlcols)) { + $name .= "_" . getlang(LN_DATABASE); + } + + // The new column value + $col = array(); + $col["name"] = $name; + $col["mod"] = false; + // No value is supplied + if (is_null($val)) { + $col["type"] = _ADDCOL_TYPE_NULL; + $col["value"] = null; + // A valid value + } else { + $col["type"] = _ADDCOL_TYPE_STR; + $col["value"] = $val; + } + + // Check if we should set it + switch ($this->_optype) { + case ADDCOL_INSERT: + // Always set the value for INSERT + $col["mod"] = true; + break; + + case ADDCOL_UPDATE: + default: + // A current value is supplied + if ($cur_exists) { + // This column had a value previously + if (!is_null($curval)) { + // It has no value now. Remove it. + if ($col["type"] == _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + // A different new value. Modify it. + } elseif ($col["value"] !== $curval) { + $col["mod"] = true; + } + // This column had no value previously + } else { + // But it has a value now. + if ($col["type"] != _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + } + } + // No current value to compare with. + } else { + // Set it anyway + $col["mod"] = true; + } + break; + } + // Add this column + $this->_cols[] = $col; + return; + } + + // addurl: Add a modified URL to the columns deposit, + // where "http://" also means empty + // Input: $name: The column name. + // $val: The column value. + // $curval: The current value to be compared. + // Output: None. + function addurl($name, $val) + { + // Set the 3rd argument as the current value + $cur_exists = false; + if (func_num_args() == 3) { + $cur_exists = true; + $curval = func_get_arg(2); + } + // Adjust the column name for multi-lingual columns + if (in_array($name, $this->_mlcols)) { + $name .= "_" . getlang(LN_DATABASE); + } + + // The new column value + $col = array(); + $col["name"] = $name; + $col["mod"] = false; + // No value is supplied + if (is_null($val) || $val === "" || $val == "http://") { + $col["type"] = _ADDCOL_TYPE_NULL; + $col["value"] = null; + // A valid value + } else { + $col["type"] = _ADDCOL_TYPE_STR; + $col["value"] = $val; + } + + // Check if we should set it + switch ($this->_optype) { + case ADDCOL_INSERT: + // Always set the value for INSERT + $col["mod"] = true; + break; + + case ADDCOL_UPDATE: + default: + // A current value is supplied + if ($cur_exists) { + // This column had a value previously + if (!is_null($curval)) { + // It has no value now. Remove it. + if ($col["type"] == _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + // A different new value. Modify it. + } elseif ($col["value"] !== $curval) { + $col["mod"] = true; + } + // This column had no value previously + } else { + // But it has a value now. + if ($col["type"] != _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + } + } + // No current value to compare with. Modify it anyway + } else { + // Set it anyway + $col["mod"] = true; + } + break; + } + // Add this column + $this->_cols[] = $col; + return; + } + + // addpass: Add a modified password to the columns deposit, + // where "" means "not changed". Passwords are never empty. + // Input: $name: The column name. + // $purge: If we should purge the password. + // $val: The column value. + // $curval: The current value to be compared. + // Output: None. + function addpass($name, $purge, $val) + { + // Set the 4nd argument as the current value + $cur_exists = false; + if (func_num_args() == 4) { + $cur_exists = true; + $curval = func_get_arg(3); + } + // Adjust the column name for multi-lingual columns + if (in_array($name, $this->_mlcols)) { + $name .= "_" . getlang(LN_DATABASE); + } + + // The new column value + $col = array(); + $col["name"] = $name; + $col["mod"] = false; + // Purge the password with a dummy one + if ($purge) { + $col["type"] = _ADDCOL_TYPE_STR; + $col["value"] = str_repeat("x", 32); + // No value is supplied + } elseif (is_null($val) || $val === "") { + // There is always a value. This means no change + $col["type"] = _ADDCOL_TYPE_NULL; + $col["value"] = null; + // A valid value + } else { + $col["type"] = _ADDCOL_TYPE_STR; + $col["value"] = md5($val); + } + + // Check if we should set it + switch ($this->_optype) { + case ADDCOL_INSERT: + // Always set the value for INSERT + $col["mod"] = true; + break; + + case ADDCOL_UPDATE: + default: + // A current value is supplied + if ($cur_exists) { + // A different new value. Modify it. + if ($col["type"] != _ADDCOL_TYPE_NULL && $col["value"] != $curval) { + $col["mod"] = true; + } + // No current value to compare with. Modify it anyway + } else { + // Set it anyway + $col["mod"] = true; + } + break; + } + // Add this column + $this->_cols[] = $col; + return; + } + + // addpic: Add a picture to the columns deposit + // Input: $name: The column name. + // $val: The column value. + // $curval: The current value to be compared. + // Output: None. + function addpic($name, $val) + { + $PICS =& pic_deposit(); + // Set the 3rd argument as the current value + $cur_exists = false; + if (func_num_args() == 3) { + $cur_exists = true; + $curval = func_get_arg(2); + // Get the picture content + if (!is_null($curval)) { + $curval = $PICS[$curval]["content"]; + } + } + // Adjust the column name for multi-lingual columns + if (in_array($name, $this->_mlcols)) { + $name .= "_" . getlang(LN_DATABASE); + } + + // The new column value + $col = array(); + $col["name"] = $name; + $col["mod"] = false; + // No value is supplied + if (is_null($val)) { + $col["type"] = _ADDCOL_TYPE_NULL; + $col["value"] = null; + // A valid value + } else { + $col["type"] = _ADDCOL_TYPE_FILE; + $col["value"] = $PICS[$val]["content"]; + } + + // Check if we should set it + switch ($this->_optype) { + case ADDCOL_INSERT: + // Always set the value for INSERT + $col["mod"] = true; + break; + + case ADDCOL_UPDATE: + default: + // A current value is supplied + if ($cur_exists) { + // This column had a value previously + if (!is_null($curval)) { + // It has no value now. Remove it. + if ($col["type"] == _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + // A different new value. Modify it. + } elseif ($col["value"] !== $curval) { + $col["mod"] = true; + } + // This column had no value previously + } else { + // But it has a value now. + if ($col["type"] != _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + } + } + // No current value to compare with. Modify it anyway + } else { + // Set it anyway + $col["mod"] = true; + } + break; + } + // Add this column + $this->_cols[] = $col; + return; + } + + // addfile: Add a file to the columns deposit + // Input: $name: The column name. + // $val: The column value. + // $curval: The current value to be compared. + // Output: None. + function addfile($name, $val) + { + $FILES =& file_deposit(); + // Set the 3rd argument as the current value + $cur_exists = false; + if (func_num_args() == 3) { + $cur_exists = true; + $curval = func_get_arg(2); + // Get the picture content + if (!is_null($curval)) { + $curval = $FILES[$curval]["content"]; + } + } + // Adjust the column name for multi-lingual columns + if (in_array($name, $this->_mlcols)) { + $name .= "_" . getlang(LN_DATABASE); + } + + // The new column value + $col = array(); + $col["name"] = $name; + $col["mod"] = false; + // No value is supplied + if (is_null($val)) { + $col["type"] = _ADDCOL_TYPE_NULL; + $col["value"] = null; + // A valid value + } else { + $col["type"] = _ADDCOL_TYPE_FILE; + $col["value"] = $FILES[$val]["content"]; + } + + // Check if we should set it + switch ($this->_optype) { + case ADDCOL_INSERT: + // Always set the value for INSERT + $col["mod"] = true; + break; + + case ADDCOL_UPDATE: + default: + // A current value is supplied + if ($cur_exists) { + // This column had a value previously + if (!is_null($curval)) { + // It has no value now. Remove it. + if ($col["type"] == _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + // A different new value. Modify it. + } elseif ($col["value"] !== $curval) { + $col["mod"] = true; + } + // This column had no value previously + } else { + // But it has a value now. + if ($col["type"] != _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + } + } + // No current value to compare with. Modify it anyway + } else { + // Set it anyway + $col["mod"] = true; + } + break; + } + // Add this column + $this->_cols[] = $col; + return; + } + + // addnum: Add a modified numeric column to the columns deposit + // Input: $name: The column name. + // $val: The column value. + // $curval: The current value to be compared. + function addnum($name, $val) + { + // Set the 3rd argument as the current value + $cur_exists = false; + if (func_num_args() == 3) { + $cur_exists = true; + $curval = func_get_arg(2); + } + // Adjust the column name for multi-lingual columns + if (in_array($name, $this->_mlcols)) { + $name .= "_" . getlang(LN_DATABASE); + } + + // The new column value + $col = array(); + $col["name"] = $name; + $col["mod"] = false; + // No value is supplied + if (is_null($val) || $val === "") { + $col["type"] = _ADDCOL_TYPE_NULL; + $col["value"] = null; + // A valid value + } else { + $col["type"] = _ADDCOL_TYPE_NUM; + $col["value"] = $val; + } + + // Check if we should set it + switch ($this->_optype) { + case ADDCOL_INSERT: + // Always set the value for INSERT + $col["mod"] = true; + break; + + case ADDCOL_UPDATE: + default: + // A current value is supplied + if ($cur_exists) { + // This column had a value previously + if (!is_null($curval)) { + // It has no value now. Remove it. + if ($col["type"] == _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + // A different new value. Modify it. + } elseif ($col["value"] != $curval) { + $col["mod"] = true; + } + // This column had no value previously + } else { + // But it has a value now. + if ($col["type"] != _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + } + } + // No current value to compare with. + } else { + // Set it anyway + $col["mod"] = true; + } + break; + } + // Add this column + $this->_cols[] = $col; + return; + } + + // adddate: Add a modified date column to the columns deposit + // Mostly the same as addstr(). Different when out. + // Input: $name: The column name. + // $val: The column value. + // $curval: The current value to be compared. + // Output: None. + function adddate($name, $val) + { + // Set the 3rd argument as the current value + $cur_exists = false; + if (func_num_args() == 3) { + $cur_exists = true; + $curval = func_get_arg(2); + } + // Adjust the column name for multi-lingual columns + if (in_array($name, $this->_mlcols)) { + $name .= "_" . getlang(LN_DATABASE); + } + + // The new column value + $col = array(); + $col["name"] = $name; + $col["mod"] = false; + // No value is supplied + if (is_null($val) || $val === "") { + $col["type"] = _ADDCOL_TYPE_NULL; + $col["value"] = null; + // A valid value + } else { + $col["type"] = _ADDCOL_TYPE_DATE; + $col["value"] = $val; + } + + // Check if we should set it + switch ($this->_optype) { + case ADDCOL_INSERT: + // Always set the value for INSERT + $col["mod"] = true; + break; + + case ADDCOL_UPDATE: + default: + // A current value is supplied + if ($cur_exists) { + // This column had a value previously + if (!is_null($curval)) { + // It has no value now. Remove it. + if ($col["type"] == _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + // A different new value. Modify it. + } elseif ($col["value"] !== $curval) { + $col["mod"] = true; + } + // This column had no value previously + } else { + // But it has a value now. + if ($col["type"] != _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + } + } + // No current value to compare with. + } else { + // Set it anyway + $col["mod"] = true; + } + break; + } + // Add this column + $this->_cols[] = $col; + return; + } + + // addipaddr: Add a modified IP address column to the columns deposit + // Mostly the same as addstr(). Different when out. + // Input: $name: The column name. + // $val: The column value. + // $curval: The current value to be compared. + // Output: None. + function addipaddr($name, $val) + { + // Set the 3rd argument as the current value + $cur_exists = false; + if (func_num_args() == 3) { + $cur_exists = true; + $curval = func_get_arg(2); + } + // Adjust the column name for multi-lingual columns + if (in_array($name, $this->_mlcols)) { + $name .= "_" . getlang(LN_DATABASE); + } + + // The new column value + $col = array(); + $col["name"] = $name; + $col["mod"] = false; + // No value is supplied + if (is_null($val) || $val === "") { + $col["type"] = _ADDCOL_TYPE_NULL; + $col["value"] = null; + // A valid value + } else { + $col["type"] = _ADDCOL_TYPE_IPADDR; + $col["value"] = $val; + } + + // Check if we should set it + switch ($this->_optype) { + case ADDCOL_INSERT: + // Always set the value for INSERT + $col["mod"] = true; + break; + + case ADDCOL_UPDATE: + default: + // A current value is supplied + if ($cur_exists) { + // This column had a value previously + if (!is_null($curval)) { + // It has no value now. Remove it. + if ($col["type"] == _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + // A different new value. Modify it. + } elseif ($col["value"] !== $curval) { + $col["mod"] = true; + } + // This column had no value previously + } else { + // But it has a value now. + if ($col["type"] != _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + } + } + // No current value to compare with. + } else { + // Set it anyway + $col["mod"] = true; + } + break; + } + // Add this column + $this->_cols[] = $col; + return; + } + + // addbool: Add a modified boolean column to the columns deposit + // Input: $name: The column name. + // $val: The column value. + // $curval: The current value to be compared. + function addbool($name, $val) + { + // Set the 3rd argument as the current value + $cur_exists = false; + if (func_num_args() == 3) { + $cur_exists = true; + $curval = func_get_arg(2); + } + // Adjust the column name for multi-lingual columns + if (in_array($name, $this->_mlcols)) { + $name .= "_" . getlang(LN_DATABASE); + } + + // The new column value + $col = array(); + $col["name"] = $name; + $col["mod"] = false; + // No value supplied means "false" + $col["type"] = _ADDCOL_TYPE_BOOL; + $col["value"] = !is_null($val) && $val; + + // Check if we should set it + switch ($this->_optype) { + case ADDCOL_INSERT: + // Always set the value for INSERT + $col["mod"] = true; + break; + + case ADDCOL_UPDATE: + default: + // A current value is supplied + if ($cur_exists) { + // This column is previously true + if ($curval) { + // New value is false. Disable it. + if (!$col["value"]) { + $col["mod"] = true; + } + // The current value is false + } else { + // But it is true now. + if ($col["value"]) { + $col["mod"] = true; + } + } + // No current value to compare with. + } else { + // set it anyway + $col["mod"] = true; + } + break; + } + // Add this column + $this->_cols[] = $col; + return; + } + + // addboolnull: Add a modified boolean column to the columns deposit + // Input: $name: The column name. + // $val: The column value. + // $curval: The current value to be compared. + function addboolnull($name, $val) + { + // Set the 3rd argument as the current value + $cur_exists = false; + if (func_num_args() == 3) { + $cur_exists = true; + $curval = func_get_arg(2); + } + // Adjust the column name for multi-lingual columns + if (in_array($name, $this->_mlcols)) { + $name .= "_" . getlang(LN_DATABASE); + } + + // The new column value + $col = array(); + $col["name"] = $name; + $col["mod"] = false; + // No value is supplied + if (is_null($val) || $val === "") { + $col["type"] = _ADDCOL_TYPE_NULL; + $col["value"] = null; + // A valid value + } else { + $col["type"] = _ADDCOL_TYPE_BOOL; + switch ($val) { + case "yes": + case "true": + $col["value"] = true; + break; + case "no": + case "false": + $col["value"] = false; + break; + } + } + + // Check if we should set it + switch ($this->_optype) { + case ADDCOL_INSERT: + // Always set the value for INSERT + $col["mod"] = true; + break; + + case ADDCOL_UPDATE: + default: + // A current value is supplied + if ($cur_exists) { + // This column had a value previously + if (!is_null($curval)) { + // It has no value now. Remove it. + if ($col["type"] == _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + // A different new value. Modify it. + } elseif ($col["value"] !== $curval) { + $col["mod"] = true; + } + // This column had no value previously + } else { + // But it has a value now. + if ($col["type"] != _ADDCOL_TYPE_NULL) { + $col["mod"] = true; + } + } + // No current value to compare with. + } else { + // Set it anyway + $col["mod"] = true; + } + break; + } + // Add this column + $this->_cols[] = $col; + return; + } + + // addexpr: Add a expression column value to the columns deposit + // Input: $name: The column name. + // $val: The column value. + function addexpr($name, $expr) + { + // Adjust the column name for multi-lingual columns + if (in_array($name, $this->_mlcols)) { + $name .= "_" . getlang(LN_DATABASE); + } + // The new column value + // Always set it, since it is not possible to compare the current value + $col = array(); + $col["name"] = $name; + $col["mod"] = true; + $col["type"] = _ADDCOL_TYPE_EXPR; + $col["value"] = $expr; + // Add this column + $this->_cols[] = $col; + return; + } + + // modified: Return if this record is modified + function modified() + { + // Find any column that is modified + foreach ($this->_cols as $col) { + if ($col["mod"]) { + return true; + } + } + return false; + } + + // ret: Retrieve the columns deposit in an SQL statement + // Input: $timestamp: Whether we should record timestamps or not + // Log in forms should not update their timestamps. + // Output: An SQL statement in the corresponding query type. + function ret($timestamp = true) + { + // Set the login user + if ($timestamp) { + if (is_null($this->login)) { + $this->login = get_login_sn(); + } + } + switch ($this->_optype) { + case ADDCOL_INSERT: + $names = array(); + $vals = array(); + for ($i = 0; $i < count($this->_cols); $i++) { + // Skip columns that are not modified + if (!$this->_cols[$i]["mod"]) { + continue; + } + $names[] = $this->_cols[$i]["name"]; + $vals[] = $this->_valout_sql($this->_cols[$i]); + } + // Add the timestamp + if ($timestamp) { + if (in_array("created", $this->_allcols)) { + $names[] = "created"; + $vals[] = "now()"; + } + if (in_array("createdby", $this->_allcols)) { + $names[] = "createdby"; + $vals[] = $this->login; + } + if (in_array("updated", $this->_allcols)) { + $names[] = "updated"; + $vals[] = "now()"; + } + if (in_array("updatedby", $this->_allcols)) { + $names[] = "updatedby"; + $vals[] = $this->login; + } + } + return "(" . implode(", ", $names) .")" + . " VALUES (" . implode(", ", $vals) . ")"; + + case ADDCOL_UPDATE: + default: + $phrases = array(); + for ($i = 0; $i < count($this->_cols); $i++) { + // Skip columns that are not modified + if (!$this->_cols[$i]["mod"]) { + continue; + } + $phrases[] = $this->_cols[$i]["name"] . "=" + . $this->_valout_sql($this->_cols[$i]); + } + // Add the timestamp + if ($timestamp) { + if (in_array("updated", $this->_allcols)) { + $phrases[] = "updated=now()"; + } + if (in_array("updatedby", $this->_allcols)) { + $phrases[] = "updatedby=" . $this->login; + } + } + return "SET " . implode(", ", $phrases); + } + } + + // _valout_sql: Output a value in a proper SQL format. + function _valout_sql($col) + { + switch ($col["type"]) { + case _ADDCOL_TYPE_NULL: + return "NULL"; + case _ADDCOL_TYPE_NUM: + return $col["value"]; + case _ADDCOL_TYPE_STR: + return "'" . sql_esctext($col["value"]) . "'"; + case _ADDCOL_TYPE_DATE: + return "'" . $col["value"] . "'"; + case _ADDCOL_TYPE_FILE: + return "'" . sql_escblob($col["value"]) . "'"; + case _ADDCOL_TYPE_IPADDR: + return "'" . $col["value"] . "'"; + case _ADDCOL_TYPE_BOOL: + return $col["value"]? sql_true(): sql_false(); + case _ADDCOL_TYPE_EXPR: + return $col["value"]; + } + } + + // retcsv: Retrieve the columns deposit in a CSV row. + // Input: None. + // Output: The CSV row + function retcsv() + { + // CSV has no engine. Output the whole record anyway, + // no matter updated or not. + $vals = array(); + for ($i = 0; $i < count($this->_cols); $i++) { + $vals[] = $this->_valout_csv($this->_cols[$i]); + } + return implode(",", $vals) . "\n"; + } + + // _valout_csv: Output a value in a proper CSV format. + function _valout_csv($col) + { + switch ($col["type"]) { + case _ADDCOL_TYPE_NULL: + return "NULL"; + case _ADDCOL_TYPE_NUM: + return $col["value"]; + case _ADDCOL_TYPE_STR: + $val = addslashes($col["value"]); + $val = str_replace("\n", "\\n", $val); + $val = str_replace("\r", "\\r", $val); + $val = str_replace("\0", "\\0", $val); + return "\"" . $val . "\""; + case _ADDCOL_TYPE_DATE: + return "\"" . $col["value"] . "\""; + case _ADDCOL_TYPE_BOOL: + return $col["value"]? "TRUE": "FALSE"; + case _ADDCOL_TYPE_IPADDR: + return "\"" . $col["value"] . "\""; + // CSV has no engine. The following is emulated. + case _ADDCOL_TYPE_EXPR: + switch ($col["value"]) { + case "now()": + return "\"" . date("Y-m-d H:i:s") . "\""; + } + } + } +} + +?> diff --git a/lib/php/monica/addget.inc.php b/lib/php/monica/addget.inc.php new file mode 100644 index 0000000..083ef3f --- /dev/null +++ b/lib/php/monica/addget.inc.php @@ -0,0 +1,105 @@ + +// Copyright: Copyright (C) 2001-2007 Pristine Communications + +// Constant symbols +if (!defined("DUP_OK")) { + define("DUP_OK", true); + define("DUP_NO", false); +} + +// add_get_arg: Add a get argument to the end of an url +function add_get_arg($cururl, $name, $value, $dup_ok = DUP_NO) +{ + // Encode the name and value first + $name = urlencode($name); + $value = urlencode($value); + + $pos = strpos($cururl, "?"); + // No current arguments were appended yet + if ($pos === false) { + return "$cururl?$name=$value"; + } + + // It's OK to have duplicated same arguments + if ($dup_ok) { + return "$cururl&$name=$value"; + } + + // Have arguments already. We need to check if there is already + // a duplicated one and replace it if exists. + // Split the arguments + $script = substr($cururl, 0, $pos); + $argslist = substr($cururl, $pos+1); + $oldargs = explode("&", $argslist); + $newargs = array(); + $l = strlen("$name="); + $found = false; + foreach ($oldargs as $arg) { + // Replace existing arguments + if (substr($arg, 0, $l) == "$name=") { + // Replace the first one and discard the rest + if (!$found) { + $newargs[] = "$name=$value"; + $found = true; + } + continue; + } + $newargs[] = $arg; + } + // Add it if not found at last + if (!$found) { + $newargs[] = "$name=$value"; + } + return "$script?" . implode("&", $newargs); +} + +// rem_get_arg: Remove a get argument from the end of an url +function rem_get_arg($cururl, $names) +{ + // If $names is not an array, set to an one-element array + if (!is_array($names)) { + $names = array($names); + } + // Parse the names + $lens = array(); + for ($i = 0; $i < count($names); $i++) { + // Encode the name first + $names[$i] = urlencode($names[$i]); + // Save its length + $lens[$names[$i]] = strlen($names[$i] . "="); + } + + $pos = strpos($cururl, "?"); + // No current arguments are appended yet + if ($pos === false) { + return $cururl; + } + + // Have arguments already. We need to check if there is already + // a duplicated one and remove it if exists. + // Split the arguments + $script = substr($cururl, 0, $pos); + $argslist = substr($cururl, $pos+1); + $oldargs = explode("&", $argslist); + $newargs = array(); + foreach ($oldargs as $arg) { + // Skip found arguments + foreach ($names as $name) { + if (substr($arg, 0, $lens[$name]) == "$name=") { + continue 2; + } + } + $newargs[] = $arg; + } + // No arguments left + if (count($newargs) == 0) { + return $script; + } + return "$script?" . implode("&", $newargs); +} + +?> diff --git a/lib/php/monica/addslash.inc.php b/lib/php/monica/addslash.inc.php new file mode 100644 index 0000000..0cd80a5 --- /dev/null +++ b/lib/php/monica/addslash.inc.php @@ -0,0 +1,60 @@ + +// Copyright: Copyright (C) 2003-2007 Pristine Communications + +// addslashes_like: addslashes() in like version +// Removed. Replaced with sql_esclike() + +// addslashes_re: addslashes() in regular expression version +function addslashes_re($s) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($s, $cache)) { + return $cache[$s]; + } + $r = $s; + $r = preg_replace("/\\\\/", "\\\\\\\\", $r); + $r = preg_replace("/(\W)/", "\\\\$1", $r); + if (preg_match("/^\w/", $s)) { + $r = "[[:<:]]" . $r; + } + if (preg_match("/\w$/", $s)) { + $r = $r . "[[:>:]]"; + } + $cache[$s] = $r; + return $r; +} + +// addslashes_re_php: addslashes() in PHP preg_* version +function addslashes_re_php($s) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($s, $cache)) { + return $cache[$s]; + } + $r = $s; + // ASCII punctuations area + $r = preg_replace("/([\\x21-\\x2F\\x3A-\\x40\\x5B-\\x60\\x7B-\\x7E])/", "\\\\$1", $r); + $r = str_replace("\n", "\\n", $r); + $r = str_replace("\r", "\\r", $r); + $r = str_replace("\t", "\\t", $r); + // Disabled. It may not always be a word piece. + // To be designed a better handling method on this issue. + //if (preg_match("/^\w/", $s)) { + // $r = "\\b" . $r; + //} + //if (preg_match("/\w$/", $s)) { + // $r = $r . "\\b"; + //} + $cache[$s] = $r; + return $r; +} + +?> diff --git a/lib/php/monica/altlang.inc.php b/lib/php/monica/altlang.inc.php new file mode 100644 index 0000000..ee8bec7 --- /dev/null +++ b/lib/php/monica/altlang.inc.php @@ -0,0 +1,205 @@ + +// Copyright: Copyright (C) 2004-2008 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/cgiemu.inc.php"; +require_once "monica/decform.inc.php"; +require_once "monica/echoform.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/unicode.inc.php"; + +// altlang: Obtain the URL of an alternative language version +function altlang($lang, $args) +{ + // Obtain the URLs + set_altlang_urls($args); + // Return it + return $args["altlang"][$lang]; +} + +// set_altlang_urls: Set the URLs of the language variants +function set_altlang_urls(&$args) +{ + // Return if already obtained + if (array_key_exists("altlang", $args)) { + return; + } + + // Set the path + $path = $args["path"]; + if (substr($path, -11) == "/index.html") { + $path = substr($path, 0, -10); + } + + // Set the URL parameter + if ($args["static"]) { + $len = strlen(ln($args["lang"], LN_FILENAME)) + 2; + $path = "/%s/" . substr($path, $len); + } else { + // GET arguments not converted to UTF-8 yet + if (!array_key_exists("USER_INPUT", $GLOBALS)) { + decode_forms(); + } + global $USER_INPUT; + // Whether we need to specify the character set + $need_charset = !$USER_INPUT["GET_CSERR"] + && !is_usascii_printable($USER_INPUT["GET_UTF8"]); + $args0 = array(); + if ( array_key_exists("QUERY_STRING", $_SERVER) + && $_SERVER["QUERY_STRING"] != "") { + $args0 = _altlang_parse_qs($_SERVER["QUERY_STRING"], $USER_INPUT["GET_CHARSET"]); + } + // Remove the session ID. + $args0 = _altlang_qsargs_rem_arg($args0, session_name()); + // US-ASCII -- we don't need to specify the character set + if (!$need_charset) { + $args0 = _altlang_qsargs_rem_arg($args0, "charset"); + } + // Append the referer + if (auto_keep_referer()) { + $args0 = _altlang_qsargs_set_arg($args0, "referer", $_SERVER["HTTP_REFERER"]); + } + } + + // Deal with each language + $urls = array(); + foreach ($args["all_linguas"] as $lang) { + if ($args["static"]) { + $urls[$lang] = sprintf($path, ln($lang, LN_FILENAME)); + } else { + // Make a copy of the variables + $args1 = $args0; + // Set the language + $args1 = _altlang_qsargs_set_arg($args1, "lang", $lang); + // We need to specify the character set + if ($need_charset) { + $charset1 = ln($lang, LN_CHARSET); + $args1 = _altlang_qsargs_set_arg($args1, "charset", $charset1); + for ($i = 0; $i < count($args1); $i++) { + if (is_null($args1[$i]["name"])) { + $args1[$i] = rawurlencode(h_encode($args1[$i]["val"], $charset1)); + } else { + $args1[$i] = rawurlencode(h_encode($args1[$i]["name"], $charset1)) + . "=" . rawurlencode(h_encode($args1[$i]["val"], $charset1)); + } + } + } else { + for ($i = 0; $i < count($args1); $i++) { + if (is_null($args1[$i]["name"])) { + $args1[$i] = rawurlencode($args1[$i]["val"]); + } else { + $args1[$i] = rawurlencode($args1[$i]["name"]) + . "=" . rawurlencode($args1[$i]["val"]); + } + } + } + $urls[$lang] = REQUEST_FILE . "?" . implode("&", $args1); + } + $urls[$lang] = $urls[$lang]; + } + + // Record it + $args["altlang"] = $urls; + return; +} + +// _altlang_parse_qs: Parse the query string +function _altlang_parse_qs($qs, $charset) +{ + $args = explode("&", $qs); + for ($i = 0; $i < count($args); $i++) { + if (preg_match("/^([^=]*)=(.*)$/", $args[$i], $m)) { + $name = h_decode(urldecode($m[1]), $charset); + if (is_null($name)) { + $name = ""; + } + // PHP treats [] as array indices but not part of the names + $phpname = preg_replace("/^([^\[]*)\[.*$/", "$1", $name); + $val = h_decode(urldecode($m[2]), $charset); + if (is_null($val)) { + $val = ""; + } + } else { + $name = null; + $phpname = null; + $val = h_decode(urldecode($args[$i]), $charset); + if (is_null($val)) { + $val = ""; + } + } + $args[$i] = array( + "name" => $name, + "phpname" => $phpname, + "val" => $val, + ); + } + return $args; +} + +// _altlang_qsargs_set_arg: Set a query argument +function _altlang_qsargs_set_arg($args, $name, $val) +{ + $found = false; + for ($i = 0; $i < count($args); $i++) { + // Not this argument + if ( is_null($args[$i]["phpname"]) + || $args[$i]["phpname"] != $name) { + continue; + } + // The first occurrence + if (!$found) { + $args[$i] = array( + "name" => $name, + "phpname" => $name, + "val" => $val, + ); + $found = true; + // Drop the rest of the occurrences + } else { + $args = array_merge( + array_slice($args, 0, $i), + array_slice($args, $i + 1) + ); + $i--; + } + } + // Add it if not found + if (!$found) { + $args[] = array( + "name" => $name, + "phpname" => $name, + "val" => $val, + ); + } + return $args; +} + +// _altlang_qsargs_rem_arg: Remove a query argument +function _altlang_qsargs_rem_arg($args, $name) +{ + for ($i = 0; $i < count($args); $i++) { + // Not this argument + if ( is_null($args[$i]["phpname"]) + || $args[$i]["phpname"] != $name) { + continue; + } + // Remove this argument + $args = array_merge( + array_slice($args, 0, $i), + array_slice($args, $i + 1) + ); + $i--; + } + return $args; +} + +?> diff --git a/lib/php/monica/big5.inc.php b/lib/php/monica/big5.inc.php new file mode 100644 index 0000000..12d87ac --- /dev/null +++ b/lib/php/monica/big5.inc.php @@ -0,0 +1,99 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// 編碼規則: +// 高位元組: A1-FE, 8E-A0, 81-8D +// 低位元組: 40-7E, A1-FE +// 常用字: A440-C67E +// 次常用字: C940-F9D5 +// 常用符號: A140-A3BF +// 罕用符號: C6A1-C8FE +// 控制碼: A3C0-A3E0 + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/xfileio.inc.php"; + +// Settings +define("_BIG5_VAR", "/tmp/big5.var"); +$_BIG5 = null; + +// init_big5: Initialize the Big5 characters array +function init_big5() +{ + global $_BIG5; + // Already initialized + if (!is_null($_BIG5)) { + return; + } + // Initialize from the existing table + if (file_exists(_BIG5_VAR)) { + eval(xfread(_BIG5_VAR)); + return; + } + // Initialize the characters + $_BIG5 = array( + "常用字" => _big5_gen_chars(0xA440, 0xC67E), + "次常用字" => _big5_gen_chars(0xC940, 0xF9D5), + "常用符號" => _big5_gen_chars(0xA140, 0xA3BF), + //"罕用符號" => _big5_gen_chars(0xC6A1, 0xC8FE), + //"控制碼" => _big5_gen_chars(0xA3C0, 0xA3E0), + ); + + // Save the result + $string = "\$_BIG5 = " . var_export($_BIG5, true) . ";\n"; + xfupdate(_BIG5_VAR, $string); + return; +} + +// _big5_gen_chars: Generate a range of Big5 characters +function _big5_gen_chars($start, $end) +{ + $chars = array(); + for ($code = $start; $code <= $end; ) { + $chars[] = pack("n", $code); + # Next character + $hi = $code & 0xFF00; + $lo = $code & 0x00FF; + if ($lo == 0xFE) { + $lo = 0x40; + $hi += 0x0100; + } elseif ($lo == 0x7E) { + $lo = 0xA1; + } else { + $lo++; + } + $code = $hi | $lo; + } + return $chars; +} + +// big5_feq_chars: Return the Big5 frequently-used characters +function &big5_feq_chars() +{ + init_big5(); + return $GLOBALS["_BIG5"]["常用字"]; +} + +// big5_nonfeq_chars: Return the Big5 non-frequently-used characters +function &big5_nonfeq_chars() +{ + init_big5(); + return $GLOBALS["_BIG5"]["次常用字"]; +} + +// big5_punc_chars: Return the Big5 punctuation characters +function &big5_punc_chars() +{ + init_big5(); + return $GLOBALS["_BIG5"]["常用符號"]; +} + +?> diff --git a/lib/php/monica/callform.inc.php b/lib/php/monica/callform.inc.php new file mode 100644 index 0000000..82be80d --- /dev/null +++ b/lib/php/monica/callform.inc.php @@ -0,0 +1,431 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/addget.inc.php"; +require_once "monica/cgiemu.inc.php"; +require_once "monica/formfunc.inc.php"; +require_once "monica/formreg.inc.php"; +require_once "monica/http.inc.php"; +require_once "monica/newsn.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/userhome.inc.php"; + +// Settings +define("FORMID_LEN", 9); +register_form("FORM_THIS", _callform_form_this()); +register_form("FORM_USERS", "/admin/users.php"); +register_form("FORM_GROUPS", "/admin/groups.php"); +register_form("FORM_USERMEM", "/admin/usermem.php"); +register_form("FORM_GROUPMEM", "/admin/groupmem.php"); +register_form("FORM_USERPREF", "/admin/userpref.php"); +register_form("FORM_SCPTPRIV", "/admin/scpptpriv.php"); +register_form("FORM_PIC", "/admin/pic.php"); +register_form("FORM_PAGES", "/admin/pages.php"); +register_form("FORM_NEWS", "/admin/news.php"); +register_form("FORM_LINKCAT", "/admin/linkcat.php"); +register_form("FORM_LINKS", "/admin/links.php"); +if (!defined("USE_SUSPEND_FORM")) { + define("USE_SUSPEND_FORM", true); +} + +// call_form: Suspend the current form and call another selection form +function call_form($form, $args, $import_func) +{ + // Only work for defined forms + if (is_null(get_registered_form($form))) { + trigger_error("Calling undefined form \"$form\".\n", E_USER_ERROR); + } + + // Record the selection import function + if (!is_null($import_func)) { + // Obtain the form + $FORM =& get_or_post(); + $FORM["import_func"] = $import_func; + } + // Suspend the current form + $formid = suspend_form(); + + // Base URL + $url = get_registered_form($form); + // Initialize as an empty array + if (is_null($args)) { + $args = array(); + } + // Add the caller + $args[] = "caller=" . urlencode(REQUEST_PATH); + // Add the caller form ID + $args[] = "cformid=" . urlencode($formid); + + // Redirect + http_303($url . "?" . implode("&", $args)); + // No need to return + exit; +} + +// proc_status_redirect: Save the form status, suspend and redirect +// the form +function proc_status_redirect(&$status) +{ + // Obtain the form + $FORM =& get_or_post(); + // Set the status + if (!is_null($status)) { + $FORM["status"] = $status; + } + + // No more form + if ( is_array($status) + && array_key_exists("isform", $status) + && !$status["isform"]) { + // Find the referring script + // Back to the page that refer to this form + if (array_key_exists("referer2", $FORM)) { + $url = $FORM["referer2"]; + // Back to the user's home on the calling site + } elseif (array_key_exists("hostport", $FORM)) { + $url = $FORM["hostport"] . userhome(); + // Default to the current URL + } else { + $url = REQUEST_FILE; + } + // Do not affect the previous form + unset($status["isform"]); + // Do not suspend the form in this case + + // Default to this same script + } else { + $url = _callform_form_this(); + // Suspend the current form + $formid = suspend_form(); + $url = add_get_arg($url, "formid", $formid); + } + if (!is_null($status)) { + $statid = suspend_status($status); + $url = add_get_arg($url, "statid", $statid); + } + + // Redirect + if ($_SERVER["REQUEST_METHOD"] == "POST") { + http_303($url); + } else { + http_307($url); + } + // No need to return + exit; +} + +// error_redirect: Shortcut to redirect the error form +function error_redirect(&$status) +{ + if (!is_null($status)) { + $status["status"] = "error"; + } + proc_status_redirect($status); + // No need to return + exit; +} + +// success_redirect: Shortcut to redirect the success form +function success_redirect(&$status) +{ + if (!is_null($status)) { + $status["status"] = "success"; + } + proc_status_redirect($status); + // No need to return + exit; +} + +// goto_form: Goto a specific form +function goto_form(&$FORM, $url = null) +{ + // Add the caller infomation + if (is_called_form()) { + // Obtain the current form + $CURFORM =& curform(); + // Add the caller infomation + $FORM["caller"] = $CURFORM["caller"]; + $FORM["cformid"] = $CURFORM["cformid"]; + } + // Suspend the supplied form + $formid = suspend_form($FORM); + + // Base URL + // Default to this same script + if (is_null($url)) { + $url = REQUEST_FILE; + } + // Add the form ID + $url = add_get_arg($url, "formid", $formid); + + // Redirect + if ($_SERVER["REQUEST_METHOD"] == "POST") { + http_303($url); + } else { + http_307($url); + } + // No need to return + exit; +} + +// suspend_form: Suspend the current form to $_SESSION +function suspend_form($FORM = null) +{ + // Obtain the form + if (is_null($FORM)) { + $FORM =& get_or_post(); + } + + // Initialize the form deposit + if (!array_key_exists("saveforms", $_SESSION)) { + $_SESSION["saveforms"] = array(); + } + + // Generate a new random form ID + $formid = new_sn_assoc($_SESSION["saveforms"]); + + // Save the current form + $_SESSION["saveforms"][$formid] = $FORM; + // Save the form ID + $_SESSION["saveforms"][$formid]["formid"] = $formid; + $_SESSION["saveforms"][$formid]["ownerscript"] = REQUEST_PATH; + + // Return the form ID + return $formid; +} + +// retrieve_form: Retrieve a previously suspended form from $_SESSION +// Return empty array instead of empty, to be merged directly +function &retrieve_form($formid = null) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (is_null($formid)) { + // $cache[0] is the default (previous form) + if (array_key_exists(0, $cache)) { + return $cache[0]; + } + } else { + if (array_key_exists($formid, $cache)) { + return $cache[$formid]; + } + } + + // Session not in use, return null in all cases + if (!isset($_SESSION)) { + if (is_null($formid)) { + $cache[0] = array(); + return $cache[0]; + } else { + $cache[$formid] = array(); + return $cache[$formid]; + } + } + // Initialize the form deposit + if (!array_key_exists("saveforms", $_SESSION)) { + $_SESSION["saveforms"] = array(); + if (is_null($formid)) { + $cache[0] = array(); + return $cache[0]; + } else { + $cache[$formid] = array(); + return $cache[$formid]; + } + } + + // Obtain the previous suspended form if form not specified + if (is_null($formid)) { + // Obtain the form + $FORM =& get_or_post(); + // Return empty if not set + if (!array_key_exists("formid", $FORM)) { + $cache[0] = array(); + return $cache[0]; + } + $formid = $FORM["formid"]; + // There is no such previously suspended form + if (!array_key_exists($formid, $_SESSION["saveforms"])) { + $cache[$formid] = array(); + $cache[0] = array(); + return $cache[0]; + } + $cache[$formid] = $_SESSION["saveforms"][$formid]; + $cache[0] =& $cache[$formid]; + + } else { + // There is no such previously suspended form + if (!array_key_exists($formid, $_SESSION["saveforms"])) { + $cache[$formid] = array(); + return $cache[$formid]; + } + $cache[$formid] = $_SESSION["saveforms"][$formid]; + } + + // Import the selection if needed + if ( array_key_exists("import_func", $cache[$formid]) + && function_exists($cache[$formid]["import_func"])) { + $cache[$formid] = call_user_func($cache[$formid]["import_func"], + $cache[$formid]); + } + + // Return the form + return $cache[$formid]; +} + +// is_first_form: If it is a first form +function is_first_form() +{ + // Obtain the form + $FORM =& get_or_post(); + // Return empty if not set + return !array_key_exists("formid", $FORM); +} + +// is_called_form: If this is a called form +function is_called_form($FORM = null) +{ + if (!USE_SUSPEND_FORM) { + return false; + } + // Obtain the current form + if (is_null($FORM)) { + $FORM =& curform(); + } + // Full caller infomation provided + return array_key_exists("caller", $FORM) + && array_key_exists("cformid", $FORM); +} + +// args_addcaller: Add the caller infomation to the GET argument list +function args_addcaller(&$args) +{ + if (is_called_form()) { + // Obtain the current form + $FORM =& curform(); + // Add the caller infomation + $args[] = "caller=" . urlencode($FORM["caller"]); + $args[] = "cformid=" . urlencode($FORM["cformid"]); + } + return; +} + +// suspend_status: Suspend the current status to $_SESSION +function suspend_status($status) +{ + // Bounce + if (is_null($status)) { + return null; + } + + // Initialize the status deposit + if (!array_key_exists("savestats", $_SESSION)) { + $_SESSION["savestats"] = array(); + } + + // Generate a new random status ID + $id = new_sn_assoc($_SESSION["savestats"]); + + // Save the current status + $_SESSION["savestats"][$id] = $status; + // Save the status ID + $_SESSION["savestats"][$id]["id"] = $id; + + // Return the status ID + return $id; +} + +// retrieve_status: Retrieve a previously suspended status from $_SESSION +function &retrieve_status($statid = null) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (is_null($statid)) { + // $cache[0] is the default (previous form) + if (array_key_exists(0, $cache)) { + return $cache[0]; + } + } else { + if (array_key_exists($statid, $cache)) { + return $cache[$statid]; + } + } + + // Session not in use, return null in all cases + if (!isset($_SESSION)) { + if (is_null($statid)) { + $cache[0] = null; + return $cache[0]; + } else { + $cache[$statid] = null; + return $cache[$statid]; + } + } + // Initialize the status deposit + if (!array_key_exists("savestats", $_SESSION)) { + $_SESSION["savestats"] = array(); + if (is_null($statid)) { + $cache[0] = null; + return $cache[0]; + } else { + $cache[$statid] = null; + return $cache[$statid]; + } + } + + // Obtain the previous suspended status if status not specified + if (is_null($statid)) { + // Obtain the form + $FORM =& get_or_post(); + // Return empty if not set + if (!array_key_exists("statid", $FORM)) { + $cache[0] = null; + return $cache[0]; + } + $statid = $FORM["statid"]; + // There is no such previously suspended status + if (!array_key_exists($statid, $_SESSION["savestats"])) { + $cache[$statid] = null; + $cache[0] = null; + return $cache[0]; + } + $cache[$statid] = $_SESSION["savestats"][$statid]; + $cache[0] =& $cache[$statid]; + + } else { + // There is no such previously suspended status + if (!array_key_exists($statid, $_SESSION["savestats"])) { + $cache[$statid] = null; + return $cache[$statid]; + } + $cache[$statid] = $_SESSION["savestats"][$statid]; + } + + // Return the status + return $cache[$statid]; +} + +// _callform_form_this: Find the processing script +function _callform_form_this() +{ + static $cache; + if (isset($cache)) { + return $cache; + } + $FORM =& get_or_post(); + $cache = (array_key_exists("referer", $FORM)? $FORM["referer"]: + REQUEST_FILE); + return $cache; +} + +?> diff --git a/lib/php/monica/captitle.inc.php b/lib/php/monica/captitle.inc.php new file mode 100644 index 0000000..cee0e64 --- /dev/null +++ b/lib/php/monica/captitle.inc.php @@ -0,0 +1,35 @@ + +// Copyright: Copyright (C) 2006-2007 Pristine Communications + +// capitalize_title: Capitalize a title +function capitalize_title($title) +{ + $title = preg_replace("/\\b(\\w+)\\b/ie", "_captitle_capitalize_word(\"\\1\");", strtolower($title)); + $title = preg_replace("/(: +)(\\w+)\\b/ie", "\"\\1\" . ucfirst(\"\\2\");", $title); + $title = preg_replace("/'S /", "'s ", $title); + return ucfirst($title); +} + +// _captitle_capitalize_word: Capitalize a word +function _captitle_capitalize_word($word) +{ + // Words that should not be capitalized + if (preg_match("/^(a|about|across|after|against|along|among|an|and|around|at|before|below|beneath|beside|besides|between|beyond|but|but|by|concerning|despite|down|during|except|excepting|for|for|from|in|into|like|near|nor|of|off|on|or|past|regarding|since|so|the|through|throughout|thus|till|to|toward|under|underneath|up|upon|with|within|without|yet)$/i", $word)) { + return strtolower($word); + } + // Words without any vowel that look like an abbreviation + if (!preg_match("/[aeiou]/i", $word)) { + return strtoupper($word); + } + // Words that look like a roman number + if (preg_match("/^(?:i|ii|iii|iv|v|vi|vii|viii|ix|x|xi|xii|xiii)$/i", $word)) { + return strtoupper($word); + } + return ucfirst($word); +} + +?> diff --git a/lib/php/monica/cgiemu.inc.php b/lib/php/monica/cgiemu.inc.php new file mode 100644 index 0000000..a86f72e --- /dev/null +++ b/lib/php/monica/cgiemu.inc.php @@ -0,0 +1,78 @@ + +// Copyright: Copyright (C) 2007 Pristine Communications + +// Constant symbols +if (!defined("_CGIEMU_SET")) { + _set_cgi_emu(); + define("_CGIEMU_SET", true); +} + +// add_get_arg: Add a get argument to the end of an url +function _set_cgi_emu() +{ + // php-cgi can work on both web and console, + // but only CLI has STDIN and STDERR + define("IS_CGI", getenv("GATEWAY_INTERFACE") !== false); + // Only work if we are not under CGI environment + if (IS_CGI) { + return; + } + // GATEWAY_INTERFACE + if (!array_key_exists("GATEWAY_INTERFACE", $_SERVER)) { + $_SERVER["GATEWAY_INTERFACE"] = ""; + putenv("GATEWAY_INTERFACE=" . $_SERVER["GATEWAY_INTERFACE"]); + } + // QUERY_STRING + if (!array_key_exists("QUERY_STRING", $_SERVER)) { + $_SERVER["QUERY_STRING"] = ""; + putenv("QUERY_STRING=" . $_SERVER["QUERY_STRING"]); + } + // REMOTE_ADDR + if (!array_key_exists("REMOTE_ADDR", $_SERVER)) { + $_SERVER["REMOTE_ADDR"] = "127.0.0.1"; + putenv("REMOTE_ADDR=" . $_SERVER["REMOTE_ADDR"]); + } + // REMOTE_HOST + if (!array_key_exists("REMOTE_HOST", $_SERVER)) { + $_SERVER["REMOTE_HOST"] = "localhost"; + putenv("REMOTE_HOST=" . $_SERVER["REMOTE_HOST"]); + } + // REQUEST_METHOD + if (!array_key_exists("REQUEST_METHOD", $_SERVER)) { + $_SERVER["REQUEST_METHOD"] = "GET"; + putenv("REQUEST_METHOD=" . $_SERVER["REQUEST_METHOD"]); + } + // SERVER_NAME + if (!array_key_exists("SERVER_NAME", $_SERVER)) { + $_SERVER["SERVER_NAME"] = php_uname("n"); + putenv("SERVER_NAME=" . $_SERVER["SERVER_NAME"]); + } + // SERVER_PORT + if (!array_key_exists("SERVER_PORT", $_SERVER)) { + $_SERVER["SERVER_PORT"] = 80; + putenv("SERVER_PORT=" . $_SERVER["SERVER_PORT"]); + } + // SERVER_SOFTWARE + if (!array_key_exists("SERVER_SOFTWARE", $_SERVER)) { + $_SERVER["SERVER_SOFTWARE"] = PHP_OS; + putenv("SERVER_SOFTWARE=" . $_SERVER["SERVER_SOFTWARE"]); + } + // session.save_path + $sessdir = ini_get("session.save_path"); + if ($sessdir != "" && !is_writable($sessdir)) { + // Use the temporarily working directory in user's home first + $sessdir = getenv("HOME") . "/tmp"; + if (!is_writable($sessdir)) { + // Use system temporarily working directory + $sessdir = sys_get_temp_dir(); + } + ini_set("session.save_path", $sessdir); + } + return; +} + +?> diff --git a/lib/php/monica/checker.inc.php b/lib/php/monica/checker.inc.php new file mode 100644 index 0000000..862903d --- /dev/null +++ b/lib/php/monica/checker.inc.php @@ -0,0 +1,3347 @@ + +// Copyright: Copyright (C) 2004-2013 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/actlog.inc.php"; +require_once "monica/addget.inc.php"; +require_once "monica/callform.inc.php"; +require_once "monica/cgiemu.inc.php"; +require_once "monica/chkfunc.inc.php"; +require_once "monica/chkpriv.inc.php"; +require_once "monica/chkwrite.inc.php"; +require_once "monica/cracklib.inc.php"; +require_once "monica/echoform.inc.php"; +require_once "monica/email.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/guest.inc.php"; +require_once "monica/http.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/mimetype.inc.php"; +require_once "monica/passwd.inc.php"; +require_once "monica/pic.inc.php"; +require_once "monica/request.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/rfc2396.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/trimtext.inc.php"; +require_once "monica/upload.inc.php"; +require_once "monica/userhome.inc.php"; +require_once "monica/username.inc.php"; +require_once "monica/usrconst.inc.php"; +require_once "monica/xfileio.inc.php"; +require_once "monica/zh2py.inc.php"; + +// BaseChecker: Base form checker class +class BaseChecker +{ + protected $_form; + protected $_iscur = null; + protected $_isreq = null; + protected $_sn = null; + protected $_table; + public $maxlens; + public $minlens; + + // __construct: Initialize the checker + function __construct(&$form, $table) + { + $this->_form =& $form; + $this->_table = $table; + if (!is_null($table)) { + $this->maxlens = sql_col_lens($table); + } + $this->minlens = array(); + $this->minlens["id"] = 3; + $this->_iscur = array_key_exists("CURRENT", $GLOBALS); + if ($this->_iscur && array_key_exists("sn", $form)) { + $this->_sn = $form["sn"]; + } + $this->_isreq = is_userreq(); + } + + // check: Run a list of checks + function check($cols) + { + // Check the list itself first + foreach ($cols as $col) { + if (!method_exists($this, "_check_$col")) { + trigger_error("Called an undefined check \"$col\"", E_USER_ERROR); + } + } + // Run each checker + foreach ($cols as $col) { + $error = call_user_func(array(&$this, "_check_$col")); + if (!is_null($error)) { + return $error; + } + } + return null; + } + + // redir: Check and redirect to another form + function redir($cols) + { + // Check the list itself first + foreach ($cols as $col) { + if (!method_exists($this, "_redir_$col")) { + trigger_error("Called an undefined redirection \"$col\"", E_USER_ERROR); + } + } + // Check each redirection + foreach ($cols as $col) { + call_user_func(array(&$this, "_redir_$col")); + } + return; + } + + // save_uploaded: Check and save the uploaded file + function save_uploaded($cols) + { + // Check the list itself first + foreach ($cols as $col) { + if (!method_exists($this, "_save_uploaded_$col")) { + trigger_error("Called an undefined uploaded file handler \"$col\"", E_USER_ERROR); + } + } + // Check each uploaded file + $errors = array(); + foreach ($cols as $col) { + $error = call_user_func(array(&$this, "_save_uploaded_$col")); + if (!is_null($error)) { + // A list of errors + if (array_key_exists(0, $error)) { + $errors = array_merge($errors, $error); + } else { + $errors[] = $error; + } + } + } + switch (count($errors)) { + // OK + case 0: + return null; + case 1: + return $errors[0]; + default: + return array("errors"=>$errors); + } + } + + ///////////////////////// + // Private column checkers. Do not call them directly. + // Add or override the column checkers when needed. + // Method names must be in the following format: + // function _check_{column}() { ... } + // Columns started with underlines are reserved for internal use, as usual. + ///////////////////////// + // _check_usr: The default user checker + function _check_usr() + { + // Check if it exists + $error = $this->_missing("usr"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["usr"] = trim($this->_form["usr"]); + // Check if it is filled + if ($this->_form["usr"] == "") { + return array("msg"=>NC_("Please select a user.")); + } + // Check if this user exists + if (!check_sn_in($this->_form["usr"], "users")) { + return array("msg"=>NC_("This user does not exist anymore. Please select another one.")); + } + // OK + return null; + } + + // _check_grp: The default group checker + function _check_grp() + { + // Check if it exists + $error = $this->_missing("grp"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["grp"] = trim($this->_form["grp"]); + // Check if it is filled + if ($this->_form["grp"] == "") { + return array("msg"=>NC_("Please select a group.")); + } + // Check if the group exists + if (!check_sn_in($this->_form["grp"], "groups")) { + return array("msg"=>NC_("This group does not exist anymore. Please select another one.")); + } + // OK + return null; + } + + // _check_script: The default script checker + function _check_script() + { + // Check if it exists + $error = $this->_missing("script"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["script"] = trim($this->_form["script"]); + // Check if it is filled + if ($this->_form["script"] == "") { + return array("msg"=>NC_("Please fill in the script.")); + } + // Check the length + if (sql_strlen($this->_form["script"]) > $this->maxlens["script"]) { + return array("msg"=>NC_("This script is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["script"])); + } + // Check if this script exists + if (!check_script($this->_form["script"])) { + return array("msg"=>NC_("This script is not a valid script. Please specify another one.")); + } + // OK + return null; + } + + // _check_date: The default date checker + function _check_date() + { + // Check if it exists + $error = $this->_missing("date"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["date"] = trim($this->_form["date"]); + // Check if it is filled + if ($this->_form["date"] == "") { + return array("msg"=>NC_("Please fill in the date.")); + } + // Check the length + if (sql_strlen($this->_form["date"]) != $this->maxlens["date"]) { + return array("msg"=>NC_("Please fill in a valid date in YYYY-MM-DD format.")); + } + // Check the date format + if (!preg_match("/^(\d{4})-(\d{2})-(\d{2})$/", $this->_form["date"], $m)) { + return array("msg"=>NC_("Please fill in a valid date in YYYY-MM-DD format.")); + } + if (!checkdate($m[2], $m[3], $m[1])) { + return array("msg"=>NC_("Please fill in a valid date in YYYY-MM-DD format.")); + } + // OK + return null; + } + + // _check_id: The default ID. checker + function _check_id() + { + // Check if it exists + $error = $this->_missing("id"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["id"] = trim($this->_form["id"]); + // Check if it is filled + if ($this->_form["id"] == "") { + return array("msg"=>NC_("Please fill in the ID.")); + } + // Check the length + if (sql_strlen($this->_form["id"]) > $this->maxlens["id"]) { + return array("msg"=>NC_("This ID. is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["id"])); + } + if (sql_strlen($this->_form["id"]) < $this->minlens["id"]) { + return array("msg"=>NC_("This ID. is too short. (Min. length %d)"), + "margs"=>array($this->minlens["id"])); + } + // Check if the characters used are valid + if (!preg_match("/^[a-z][a-z0-9_]*$/", $this->_form["id"])) { + return array("msg"=>NC_("Only lower-case English letters, numbers and underscores are allowed for the ID.")); + } + // OK + return null; + } + + // _check_ord: The default order checker + function _check_ord() + { + // Check if it exists + $error = $this->_missing("ord"); + if (!is_null($error)) { + return $error; + } + $min = 0; + $max = pow(10, $this->maxlens["ord"]) - 1; + // Text string + if (is_string($this->_form["ord"])) { + // Regularize it + $this->_form["ord"] = trim($this->_form["ord"]); + // Check if it is filled + if ($this->_form["ord"] == "") { + return array("msg"=>NC_("Please fill in the order.")); + } + // Check the length + if (sql_strlen($this->_form["ord"]) > $this->maxlens["ord"]) { + return array("msg"=>NC_("This order is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["ord"])); + } + // If there is any non-digit character + if (preg_match("/\D/", $this->_form["ord"])) { + return array("msg"=>NC_("Please fill in a positive integer order.")); + } + // Check if it is in the valid range + if ($this->_form["ord"] < $min) { + return array("msg"=>NC_("The order is too small. Please fill in a larger order between %d and %d."), + "margs"=>array($min, $max)); + } + // It is not possible to be too large now. + // Convert its type to integer + settype($this->_form["ord"], "integer"); + // Integer + } elseif (is_int($this->_form["ord"])) { + // Check if it is in the valid range + if ($this->_form["ord"] < $min) { + return array("msg"=>NC_("The order is too small. Please fill in a larger order between %d and %d."), + "margs"=>array($min, $max)); + } + if ($this->_form["ord"] > $max) { + return array("msg"=>NC_("The order is too large. Please fill in a smaller order between %d and %d."), + "margs"=>array($min, $max)); + } + // Other types are non-sense + } else { + trigger_error("Unknown type for column \"ord\"", E_USER_ERROR); + } + // OK + return null; + } + + // _check_path: The default page order checker + function _check_path() + { + // Get the available languages list + global $ALL_LINGUAS; + // Check if it exists + $error = $this->_missing("path"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["path"] = trim($this->_form["path"]); + // Remove the trailing excess "index.html" + $this->_form["path"] = preg_replace("/\/index\.html?$/i", "/", $this->_form["path"]); + // Check if it is filled + if ($this->_form["path"] == "") { + return array("msg"=>NC_("Please fill in the page path.")); + } + // Check the length + if (sql_strlen($this->_form["path"]) > $this->maxlens["path"]) { + return array("msg"=>NC_("This page path is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["path"])); + } + // Check if this item is duplicated + $conds = array(); + $conds[] = "path='" . sql_esctext($this->_form["path"]) . "'"; + if ($this->_iscur) { + $conds[] = "sn!=" . $this->_sn; + } + $select = "SELECT * FROM " . $this->_table + . " WHERE " . implode(" AND ", $conds) . ";\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 0) { + return array("msg"=>NC_("This page already exists. You cannot create a duplicated one.")); + } + // Check if the path is absolute + if (substr($this->_form["path"], 0, 1) != "/") { + return array("msg"=>NC_("Please fill in an absolute page path.")); + } + // Check if the path is legal + if (!preg_match("/^\\/" . RFC2396_PATH_SEGMENTS . "$/", $this->_form["path"])) { + return array("msg"=>NC_("Please fill in a valid page path.")); + } + // Check if it is the cover home page + if ($this->_form["path"] == "/") { + return array("msg"=>NC_("You cannot overwrite the cover home page.")); + } + // Check if it is *.html + if (!preg_match("/(?:\/|\.html)$/", $this->_form["path"])) { + return array("msg"=>NC_("You can only fill in an HTML page path (*.html).")); + } + // Check if we are permitted to write files there + if (count($ALL_LINGUAS) > 1) { + $pathpat = DOC_ROOT . "/%s" . $this->_form["path"]; + if (substr($pathpat, -1, 1) == "/") { + $pathpat .= "index.html"; + } + for ($l = 0; $l < count($ALL_LINGUAS); $l++) { + $langfile = ln($ALL_LINGUAS[$l], LN_FILENAME); + $error = check_writable(sprintf($pathpat, $langfile)); + if (!is_null($error)) { + return $error; + } + } + } else { + $path = DOC_ROOT . $this->_form["path"]; + if (substr($path, -1, 1) == "/") { + $path .= "index.html"; + } + $error = check_writable(DOC_ROOT . $path); + if (!is_null($error)) { + return $error; + } + } + // OK + return null; + } + + // _check_attdsc: The default attachment description checker + function _check_attdsc() + { + // Skip if there is no file to check + $error = $this->_missing("att"); + if (!is_null($error)) { + return null; + } + // Check if it exists + $error = $this->_missing("attdsc"); + if (!is_null($error)) { + // No attdsc will be sent when uploading an attachment from nothing + return array("msg"=>NC_("Please fill in the attachment description.")); + } + // Regularize it + $this->_form["attdsc"] = trim($this->_form["attdsc"]); + // Check if it is filled + if ($this->_form["attdsc"] == "") { + return array("msg"=>NC_("Please fill in the attachment description.")); + } + // Check the length + if (sql_strlen($this->_form["attdsc"]) > $this->maxlens["attdsc"]) { + return array("msg"=>NC_("This attachment description is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["attdsc"])); + } + // OK + return null; + } + + // _check_pdf: The default PDF. file checker + function _check_pdf() + { + // Skip if there is no file to check + $error = $this->_missing("pdf"); + if (!is_null($error)) { + return null; + } + // Check if this file exists + if (!savefile_exists($this->_form["pdf"])) { + return array("msg"=>NC_("This PDF. file does not exist anymore. Please upload another one.")); + } + // Obtain the file deposit + $FILES =& file_deposit(); + $file =& $FILES[$this->_form["pdf"]]; + // Check if this size is too large + if ($file["size"] > $this->maxlens["pdf"]) { + return array("msg"=>NC_("This PDF. file is too large. (Max. size %s)"), + "margs"=>array(report_size($this->maxlens["pdf"]))); + } + // Check if the file type is valid + if ($file["type"] != "application/pdf") { + return array("msg"=>NC_("Please upload only PDF. file.")); + } + // OK + return null; + } + + // _check_title: The default title checker + function _check_title() + { + // Check if it exists + $error = $this->_missing("title"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["title"] = trim($this->_form["title"]); + // Check if it is filled + if ($this->_form["title"] == "") { + return array("msg"=>NC_("Please fill in the title.")); + } + // Check the length + if (sql_strlen($this->_form["title"]) > $this->maxlens["title"]) { + return array("msg"=>NC_("This title is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["title"])); + } + // OK + return null; + } + + // _check_subject: Check the subject + function _check_subject() + { + // Check if it exists + $error = $this->_missing("subject"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["subject"] = trim($this->_form["subject"]); + // Check if it is filled + if ($this->_form["subject"] == "") { + return array("msg"=>NC_("Please fill in the subject.")); + } + // Check the length + if (sql_strlen($this->_form["subject"]) > $this->maxlens["subject"]) { + return array("msg"=>NC_("This subject is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["subject"])); + } + // OK + return null; + } + + // _check_body: The default content body checker + function _check_body() + { + // Check if it exists + $error = $this->_missing("body"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["body"] = trimtext($this->_form["body"]); + // Check if it is filled + if ($this->_form["body"] == C_("Fill in the content here.")) { + $this->_form["body"] = ""; + } + if ($this->_form["body"] == "") { + return array("msg"=>NC_("Please fill in the content.")); + } + // Check the length + if (sql_strlen($this->_form["body"]) > $this->maxlens["body"]) { + return array("msg"=>NC_("This content is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["body"])); + } + // OK + return null; + } + + // _check_kw: The default keyword list checker + function _check_kw() + { + // Check if it exists + $error = $this->_missing("kw"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["kw"] = trim($this->_form["kw"]); + // Check if it is filled + if ($this->_form["kw"] == "") { + return array("msg"=>NC_("Please fill in the keywords.")); + } + // Check the length + if (sql_strlen($this->_form["kw"]) > $this->maxlens["kw"]) { + return array("msg"=>NC_("This keyword list is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["kw"])); + } + // OK + return null; + } + + // _check_pinyin: The default pinyin checker + function _check_pinyin() + { + // Skip if there is no Chinese + if ($this->_missing("chinese")) { + return null; + } + // Check if it exists + $error = $this->_missing("pinyin"); + if (!is_null($error)) { + return array("msg"=>NC_("Please select a proper pinyin.")); + } + // Regularize it + $this->_form["pinyin"] = trim($this->_form["pinyin"]); + // Check the length + if (sql_strlen($this->_form["pinyin"]) > $this->maxlens["pinyin"]) { + return array("msg"=>NC_("This pinyin is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["pinyin"])); + } + // Check if the pinyin is in our safe list + if (!in_array($this->_form["pinyin"], zh2pys($this->_form["chinese"]))) { + return array("msg"=>NC_("This pinyin does not match the Chinese. Please select a proper pinyin from the list.")); + } + // OK + return null; + } + + // _check_pic: The default picture checker + function _check_pic() + { + // Check if it exists + $error = $this->_missing("pic"); + if (!is_null($error)) { + // Check against the default language + // Only check if multilingual, not in the default language and column is multilingual + if ( ($this->_iscur || $this->_isreq) + && count($GLOBALS["ALL_LINGUAS"]) > 1 + && getlang() != DEFAULT_LANG + && in_array("pic", sql_cols_ml($this->_table))) { + $lndbdef = ln(DEFAULT_LANG, LN_DATABASE); + if ($this->_isreq) { + $defpic = $GLOBALS["REQUEST"]["args"]["pic_$lndbdef"]; + } else { + $defpic = $GLOBALS["CURRENT"]["pic_$lndbdef"]; + } + // Check if there is a matching column to the default language + if (!is_null($defpic)) { + return array("msg"=>N_("Please upload the picture.")); + } + } + return null; + } + // Check if this picture exists + if (!pic_exists($this->_form["pic"])) { + return array("msg"=>NC_("This picture does not exist anymore. Please upload another one.")); + } + // Obtain the picture deposit + $PICS =& pic_deposit(); + // Check the length + if (strlen($PICS[$this->_form["pic"]]["content"]) > $this->maxlens["pic"]) { + return array("msg"=>NC_("This picture is too large. Please upload another one. (Max. size %d)"), + "margs"=>array($this->maxlens["pic"])); + } + // Check against the default language + // Only check if multilingual, not in the default language and column is multilingual + if ( ($this->_iscur || $this->_isreq) + && count($GLOBALS["ALL_LINGUAS"]) > 1 + && getlang() != DEFAULT_LANG + && in_array("pic", sql_cols_ml($this->_table))) { + $lndbdef = ln(DEFAULT_LANG, LN_DATABASE); + if ($this->_isreq) { + $defpic = $GLOBALS["REQUEST"]["args"]["pic_$lndbdef"]; + } else { + $defpic = $GLOBALS["CURRENT"]["pic_$lndbdef"]; + } + // Check if we start from the default language + if (!pic_exists($defpic)) { + return array("msg"=>NC_("Please upload a new picture from %s."), + "margs"=>array("_DEFAULT_LANG")); + } + } + // OK + return null; + } + + // _check_piccap: The default picture caption checker + function _check_piccap() + { + // Skip if there is no picture now + if ($this->_missing("pic")) { + unset($this->_form["piccap"]); + return null; + } + // Check if it exists + $error = $this->_missing("piccap"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["piccap"] = trim($this->_form["piccap"]); + // Check if it is filled + if ($this->_form["piccap"] == "") { + return array("msg"=>NC_("Please fill in the picture caption.")); + } + // Check the length + if (sql_strlen($this->_form["piccap"]) > $this->maxlens["piccap"]) { + return array("msg"=>NC_("This picture caption is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["piccap"])); + } + // OK + return null; + } + + // _check_picpos: The default picture position checker + function _check_picpos() + { + // Skip if there is no picture now + if ($this->_missing("pic")) { + unset($this->_form["picpos"]); + return null; + } + // Check if it exists + $error = $this->_missing("picpos"); + if (!is_null($error)) { + return array("msg"=>NC_("Please select the picture position.")); + } + // Regularize it + $this->_form["picpos"] = trim($this->_form["picpos"]); + // Check if the picture position is legal + if (!in_array($this->_form["picpos"], $GLOBALS["PIC_VALID_POS"])) { + return array("msg"=>NC_("This picture position is invalid. Please choose a proper picture position.")); + } + // OK + return null; + } + + // _check_called_form: Check if this form is a called form + function _check_called_form() + { + // Check if it exists + $error = $this->_missing("caller", "cformid"); + if (!is_null($error)) { + return $error; + } + // OK + return null; + } + + // _check_cap: The default picture caption checker + function _check_cap() + { + // Skip if there is no picture now + if ($this->_missing("pic")) { + unset($this->_form["cap"]); + return null; + } + // Check if it exists + $error = $this->_missing("cap"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["cap"] = trim($this->_form["cap"]); + // Check if it is filled + if ($this->_form["cap"] == "") { + return array("msg"=>NC_("Please fill in the picture caption.")); + } + // Check the length + if (sql_strlen($this->_form["cap"]) > $this->maxlens["cap"]) { + return array("msg"=>NC_("This picture caption is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["cap"])); + } + // OK + return null; + } + + // _check_pos: The default picture position checker + function _check_pos() + { + // Skip if there is no picture now + if ($this->_missing("pic")) { + unset($this->_form["pos"]); + return null; + } + // Check if it exists + $error = $this->_missing("pos"); + if (!is_null($error)) { + return array("msg"=>NC_("Please select the picture position.")); + } + // Regularize it + $this->_form["pos"] = trim($this->_form["pos"]); + // Check if the picture position is legal + if (!in_array($this->_form["pos"], $GLOBALS["PIC_VALID_POS"])) { + return array("msg"=>NC_("This picture position is invalid. Please choose a proper picture position.")); + } + // OK + return null; + } + + // __check_upload: The default file checker + function __check_upload($col) + { + // Skip if multi-lingual and not in the default language + if ( ($this->_iscur || $this->_isreq) + && count($GLOBALS["ALL_LINGUAS"]) > 1 + && getlang() != DEFAULT_LANG + && in_array($col, sql_cols_ml($this->_table))) { + $defcol = $col . "_" . ln(DEFAULT_LANG, LN_DATABASE); + $deffile = $this->_isreq? $GLOBALS["REQUEST"]["args"][$defcol]: + $GLOBALS["CURRENT"][$defcol]; + if (!savefile_exists($deffile)) { + return null; + } + } + // Check if it exists + $error = file_has("up$col"); + if (!is_null($error)) { + return $error; + } + // Check the file upload status + switch ($_FILES["up$col"]["error"]) { + // Success + case UPLOAD_ERR_OK: + return null; + // Nothing uploaded + case UPLOAD_ERR_NO_FILE: + return null; + // Below are errors + case UPLOAD_ERR_INI_SIZE: + return array("msg"=>NC_("Your uploaded file is too large (Max %s)."), + "margs"=>array(get_cfg_var("upload_max_filesize"))); + case UPLOAD_ERR_FORM_SIZE: + return array("msg"=>NC_("Your uploaded file is too large (Max %s)."), + "margs"=>array(UPLOAD_ERR_FORM_SIZE)); + case UPLOAD_ERR_PARTIAL: + return array("msg"=>NC_("Upload not completed. Disk may be full or connection may be closed in the half. You may try to upload again, or contact the system administrator for this problem.")); + default: + return array("msg"=>NC_("Upload failed with an unknown error (%d)."), + "margs"=>array($_FILES["up$col"]["error"])); + } + } + + ///////////////////////// + // Private form redirectors. Do not call them directly. + // Add redirector definitions here. + // Method names must be in the following format: + // function _redir_{column}() { ... } + // Columns started with underlines are reserved for internal use, as usual. + ///////////////////////// + // _redir_del: Suspend and move to the deletion form + function _redir_del() + { + // Skip if not requested + if ($this->_missing("del")) { + return; + } + $args = array(); + $args[] = "form=del"; + if (!$this->_missing("sn")) { + $args[] = "sn=" . $this->_form["sn"]; + } elseif (!$this->_missing("req")) { + $args[] = "req=" . $this->_form["req"]; + } + call_form(FORM_THIS, $args, null); + } + + // _redir_cancel: Cancel the form and return to the originator + function _redir_cancel() + { + // Skip if not requested + if ($this->_missing("cancel")) { + return; + } + // A calling form -- return to the caller + if (!$this->_missing("caller", "cformid")) { + $url = $this->_form["caller"]; + if (!$this->_missing("hostport")) { + $url = $this->_form["hostport"] . $url; + } + $url = add_get_arg($url, "formid", $this->_form["cformid"]); + if ($_SERVER["REQUEST_METHOD"] == "POST") { + http_303($url); + } else { + http_307($url); + } + } + // Referer2 specified -- return to referer2 + if (!$this->_missing("referer2")) { + $url = $this->_form["referer2"]; + // Return to the hostport + } elseif (!$this->_missing("hostport")) { + $url = $this->_form["hostport"] . userhome(); + } else { + $url = userhome(); + } + if ($_SERVER["REQUEST_METHOD"] == "POST") { + http_303($url); + } else { + http_307($url); + } + } + + // _redir_selgrp: Suspend and move to the group selection form + function _redir_selgrp() + { + // Skip if not requested + if ($this->_missing("selgrp")) { + return; + } + call_form(FORM_GROUPS, null, "import_selgrp"); + } + + // _redir_delgrp: Remove the group + function _redir_delgrp() + { + // Skip if not requested + if ($this->_missing("delgrp")) { + return; + } + // Remove the item + unset($this->_form["grp"]); + $status = null; + success_redirect($status); + } + + // _redir_setpic: Suspend and move to the picture manager + function _redir_setpic() + { + // Skip if not requested + if ($this->_missing("setpic")) { + return; + } + // There is a current picture + if (!$this->_missing("pic")) { + $args = array(); + $args[] = "form=cur"; + $args[] = "sn=" . urlencode($this->_form["pic"]); + call_form(FORM_PIC, $args, "import_setpic"); + // There is no current picture + } else { + $args = array(); + $args[] = "form=new"; + call_form(FORM_PIC, $args, "import_setpic"); + } + } + + // _redir_delpic: Remove the picture + function _redir_delpic() + { + // Skip if not requested + if ($this->_missing("delpic")) { + return; + } + // Remove the item + unset($this->_form["pic"]); + unset($this->_form["piccap"]); + unset($this->_form["picpos"]); + $status = null; + success_redirect($status); + } + + // _redir_delfile: Remove the file + function _redir_delfile() + { + // Skip if not requested + if ($this->_missing("delfile")) { + return; + } + // Remove the file + unset($this->_form["file"]); + $status = null; + success_redirect($status); + } + + // _redir_delatt: Remove the attachment file + function _redir_delatt() + { + // Skip if not requested + if ($this->_missing("delatt")) { + return; + } + // Remove the file + unset($this->_form["att"]); + $status = null; + success_redirect($status); + } + + // _redir_delpdf: Remove the PDF. file + function _redir_delpdf() + { + // Skip if not requested + if ($this->_missing("delpdf")) { + return; + } + // Remove the file + unset($this->_form["pdf"]); + $status = null; + success_redirect($status); + } + + // _redir_selpage: Suspend and move to the page selection form + function _redir_selpage() + { + // Skip if not requested + if ($this->_missing("selpage")) { + return; + } + call_form(FORM_PAGES, null, "import_selpage"); + } + + // _redir_selnews: Suspend and move to the news article selection form + function _redir_selnews() + { + // Skip if not requested + if ($this->_missing("selnews")) { + return; + } + call_form(FORM_NEWS, null, "import_selnews"); + } + + // _redir_delnews: Remove the news article + function _redir_delnews() + { + // Skip if not requested + if ($this->_missing("delnews")) { + return; + } + // Remove the item + unset($this->_form["news"]); + $status = null; + success_redirect($status); + } + + // _redir_sellink: Suspend and move to the related link selection form + function _redir_sellink() + { + // Skip if not requested + if ($this->_missing("sellink")) { + return; + } + call_form(FORM_LINKS, null, "import_sellink"); + } + + // _redir_dellink: Remove the link + function _redir_dellink() + { + // Skip if not requested + if ($this->_missing("dellink")) { + return; + } + // Remove the item + unset($this->_form["link"]); + $status = null; + success_redirect($status); + } + + // _redir_selparent: Suspend and move to the parent selection form + function _redir_selparent() + { + // Skip if not requested + if ($this->_missing("selparent")) { + return; + } + call_form(FORM_THIS, null, "import_selparent"); + } + + // _redir_delparent: Remove the parent + function _redir_delparent() + { + // Skip if not requested + if ($this->_missing("delparent")) { + return; + } + // Remove the item + unset($this->_form["parent"]); + $status = null; + success_redirect($status); + } + + ///////////////////////// + // Private uploaded file handlers. Do not call them directly. + // Add uploaded file handlers definitions here. + // Method names must be in the following format: + // function _save_uploaded_{column}() { ... } + // Columns started with underlines are reserved for internal use, as usual. + ///////////////////////// + // _save_uploaded_pdf: Check and save the uploaded PDF. file + function _save_uploaded_pdf() + { + // Skip if multi-lingual and not in the default language + if ( ($this->_iscur || $this->_isreq) + && count($GLOBALS["ALL_LINGUAS"]) > 1 + && getlang() != DEFAULT_LANG + && in_array("pdf", sql_cols_ml($this->_table))) { + $defcol = "pdf_" . ln(DEFAULT_LANG, LN_DATABASE); + $deffile = $this->_isreq? $GLOBALS["REQUEST"]["args"][$defcol]: + $GLOBALS["CURRENT"][$defcol]; + if (!savefile_exists($deffile)) { + return null; + } + } + // Check with the basic upload checker + $error = $this->__check_upload("pdf"); + if (!is_null($error)) { + return $error; + } + // Skip if no new file was submitted + if ($_FILES["uppdf"]["error"] == UPLOAD_ERR_NO_FILE) { + return null; + } + $type = check_mime_type($_FILES["uppdf"]["tmp_name"], + $_FILES["uppdf"]["name"], $_FILES["uppdf"]["type"]); + // Save the file + $file = array(); + $file["content"] = xfread($_FILES["uppdf"]["tmp_name"]); + $file["name"] = $_FILES["uppdf"]["name"]; + $file["type"] = $type; + $file["size"] = strlen($file["content"]); + $fileid = suspend_file($file); + $this->_form["pdf"] = $fileid; + // Do not confirm now + if (!$this->_missing("confirm")) { + unset($this->_form["confirm"]); + } + // OK + return null; + } + + // _save_uploaded_att: Check and save the uploaded attachment file + function _save_uploaded_att() + { + // Skip if multi-lingual and not in the default language + if ( ($this->_iscur || $this->_isreq) + && count($GLOBALS["ALL_LINGUAS"]) > 1 + && getlang() != DEFAULT_LANG + && in_array("att", sql_cols_ml($this->_table))) { + $defcol = "att_" . ln(DEFAULT_LANG, LN_DATABASE); + $deffile = $this->_isreq? $GLOBALS["REQUEST"]["args"][$defcol]: + $GLOBALS["CURRENT"][$defcol]; + if (!savefile_exists($deffile)) { + return null; + } + } + // Check with the basic upload checker + $error = $this->__check_upload("att"); + if (!is_null($error)) { + return $error; + } + // Skip if no new file was submitted + if ($_FILES["upatt"]["error"] == UPLOAD_ERR_NO_FILE) { + return null; + } + $type = check_mime_type($_FILES["upatt"]["tmp_name"], + $_FILES["upatt"]["name"], $_FILES["upatt"]["type"]); + // Save the file + $file = array(); + $file["content"] = xfread($_FILES["upatt"]["tmp_name"]); + $file["name"] = $_FILES["upatt"]["name"]; + $file["type"] = $type; + $file["size"] = strlen($file["content"]); + $fileid = suspend_file($file); + $this->_form["att"] = $fileid; + // Do not confirm now + if (!$this->_missing("confirm")) { + unset($this->_form["confirm"]); + } + // OK + return null; + } + + // _save_uploaded_file: Check and save the uploaded file + function _save_uploaded_file() + { + // Skip if multi-lingual and not in the default language + if ( ($this->_iscur || $this->_isreq) + && count($GLOBALS["ALL_LINGUAS"]) > 1 + && getlang() != DEFAULT_LANG + && in_array("file", sql_cols_ml($this->_table))) { + $defcol = "file_" . ln(DEFAULT_LANG, LN_DATABASE); + $deffile = $this->_isreq? $GLOBALS["REQUEST"]["args"][$defcol]: + $GLOBALS["CURRENT"][$defcol]; + if (!savefile_exists($deffile)) { + return null; + } + } + // Check with the basic upload checker + $error = $this->__check_upload("file"); + if (!is_null($error)) { + return $error; + } + // Skip if no new file was submitted + if ($_FILES["upfile"]["error"] == UPLOAD_ERR_NO_FILE) { + return null; + } + $type = check_mime_type($_FILES["upfile"]["tmp_name"], + $_FILES["upfile"]["name"], $_FILES["upfile"]["type"]); + // Save the file + $file = array(); + $file["content"] = xfread($_FILES["upfile"]["tmp_name"]); + $file["name"] = $_FILES["upfile"]["name"]; + $file["type"] = $type; + $file["size"] = strlen($file["content"]); + $fileid = suspend_file($file); + $this->_form["file"] = $fileid; + // Do not confirm now + if (!$this->_missing("confirm")) { + unset($this->_form["confirm"]); + } + // OK + return null; + } + + ///////////////////////// + // Private utility methods. Do not override them. + ///////////////////////// + // _missing: Check if a column is submitted + function _missing() + { + $cols = func_get_args(); + foreach ($cols as $col) { + if (!array_key_exists($col, $this->_form)) { + return array("msg"=>NC_("The following field was not received: \"%s\"."), + "margs"=>array($col), + "isform"=>false); + } + } + // OK + return null; + } +} + + +///////////////////////// +// Account Checkers: Checkers for the account management system +///////////////////////// +// UserChecker: User form checker class +class UserChecker extends BaseChecker +{ + protected $_is_guest = null; + + // __construct: Initialize the checker + function __construct(&$form, $table = "users") + { + parent::__construct($form, $table); + $this->maxlens["passwd"] = 100; + $this->minlens["passwd"] = 6; + } + + // check: Run a list of checks + function check($cols) + { + // Check the guest flag first + $this->_is_guest(); + // Run the parent method + $error = parent::check($cols); + if (!is_null($error)) { + return $error; + } + return null; + } + + // _is_guest: If the user being edited is a guest + function _is_guest() + { + // Checked before + if (!is_null($this->_is_guest)) { + return $this->_is_guest; + } + for ($i = 0; !$this->_missing("supgroup$i" . "sn"); $i++) { + // Skip unselected groups + if ($this->_missing("supgroup$i")) { + continue; + } + // Check if this is the guest group + if (groupid($this->_form["supgroup$i" . "sn"]) == GUEST_GROUP) { + $this->_is_guest = true; + return true; + } + } + // No guest group was found + $this->_is_guest = false; + return false; + } + + // _check_id: Check the user ID. + function _check_id() + { + // Skip for a non-super-user editing a super-user + if ($this->_iscur && !is_su() && is_su($this->_sn)) { + return null; + } + // Check if it exists + $error = $this->_missing("id"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["id"] = trim($this->_form["id"]); + // Check if it is filled + if ($this->_form["id"] == "") { + return array("msg"=>NC_("Please fill in the user ID.")); + } + // Check the length + if (sql_strlen($this->_form["id"]) > $this->maxlens["id"]) { + return array("msg"=>NC_("This user ID. is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["id"])); + } + if (sql_strlen($this->_form["id"]) < $this->minlens["id"]) { + return array("msg"=>NC_("This user ID. is too short. (Min. length %d)"), + "margs"=>array($this->minlens["id"])); + } + // Check if the characters used are valid + if (!preg_match("/^[a-z][a-z0-9@.\-_]*$/", $this->_form["id"])) { + return array("msg"=>NC_("Only lower-case English letters, numbers, at-signs, dots, dashes and underscores are allowed for the user ID.")); + } + // Check if this item is duplicated + $conds = array(); + $conds[] = "id='" . sql_esctext($this->_form["id"]) . "'"; + if ($this->_iscur) { + $conds[] = "sn!=" . $this->_sn; + } + $select = "SELECT * FROM " . $this->_table + . " WHERE " . implode(" AND ", $conds) . ";\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 0) { + return array("msg"=>NC_("This user already has an account. You cannot create a duplicated one.")); + } + // OK + return null; + } + + // _check_passwd: Check the user password + function _check_passwd() + { + // Skip for a non-super-user editing a super-user + if ($this->_iscur && !is_su() && is_su($this->_sn)) { + return null; + } + // Set the passwords with the password registry + $dummy = str_repeat("*", 16); + sync_saved_passwd($this->_form, $dummy); + // Skip password checking for guests + if ($this->_is_guest()) { + return null; + } + // Check if it exists + $error = $this->_missing("passwd", "passwd2"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["passwd"] = trim($this->_form["passwd"]); + $this->_form["passwd2"] = trim($this->_form["passwd2"]); + // Check if it is filled + if (!$this->_iscur && $this->_form["passwd"] == "") { + return array("msg"=>NC_("Please fill in the password.")); + } + if ($this->_form["passwd"] != "" && $this->_form["passwd2"] == "") { + return array("msg"=>NC_("Please confirm the password.")); + } + // Check the length + if (sql_strlen($this->_form["passwd"]) > $this->maxlens["passwd"]) { + return array("msg"=>NC_("This password is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["passwd"])); + } + if ( $this->_form["passwd"] != "" + && sql_strlen($this->_form["passwd"]) < $this->minlens["passwd"]) { + return array("msg"=>NC_("This password is too short. (Min. length %d)"), + "margs"=>array($this->minlens["passwd"])); + } + // Check if two passwords are consistent + if ($this->_form["passwd"] != $this->_form["passwd2"]) { + return array("msg"=>NC_("The 2 passwords are different. Please fill in the password again.")); + } + if ($this->_form["passwd"] != "") { + // Check the password strength with cracklib + if (!crack_check($this->_form["passwd"])) { + // See the message from cracklib/fscist.c + switch (crack_getlastmessage()) { + // FascistGecos() + /* case "you are not registered in the password file": + return array("msg"=>NC_("You are not registered.")); */ + case "it is based on your username": + return array("msg"=>NC_("This password is based on the user ID.")); + /* case "it is based upon your password entry": + return array("msg"=>NC_("This password is based upon the personal information.")); + case "it is derived from your password entry": + case "it's derived from your password entry": + return array("msg"=>NC_("This password is derived from the personal information.")); + case "it is derivable from your password entry": + case "it's derivable from your password entry": + return array("msg"=>NC_("This password is derivable from the personal information.")); */ + // FascistLook() + /* case "it's WAY too short": + case "it is too short": + return array("msg"=>NC_("This password is too short. (Min. length %d)"), + "margs"=>array($this->minlens["passwd"])); */ + case "it does not contain enough DIFFERENT characters": + return array("msg"=>NC_("This password does not contain enough different characters.")); + /* case "it is all whitespace": + return array("msg"=>NC_("This password is all whitespace.")); */ + case "it is too simplistic/systematic": + return array("msg"=>NC_("This password is too simplistic/systematic.")); + /* case "it looks like a National Insurance number": + return array("msg"=>NC_("This password looks like a National Insurance number.")); */ + case "it is based on a dictionary word": + return array("msg"=>NC_("This password is based on a dictionary word.")); + case "it is based on a (reversed) dictionary word": + return array("msg"=>NC_("This password is based on a (reversed) dictionary word.")); + default: + return array("msg"=>NC_("This password is too simple.")); + } + } + // Check if the password is based on the user ID. + if ( !$this->_missing("id") + && strpos(strtolower($this->_form["passwd"]), strtolower($this->_form["id"])) !== false) { + return array("msg"=>NC_("You cannot use a password that is based on the user ID.")); + } + } + // OK + return null; + } + + // _check_name: Check the user name + function _check_name() + { + // Check if it exists + $error = $this->_missing("name"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["name"] = trim($this->_form["name"]); + // Check if it is filled + if ($this->_form["name"] == "") { + return array("msg"=>NC_("Please fill in the name.")); + } + // Check the length + if (sql_strlen($this->_form["name"]) > $this->maxlens["name"]) { + return array("msg"=>NC_("This name is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["name"])); + } + // OK + return null; + } + + // _check_email: Check the user e-mail + function _check_email($col = "email") + { + // Check if it exists + $error = $this->_missing($col); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form[$col] = trim($this->_form[$col]); + // Check if it is filled + if ($this->_form[$col] == "") { + return array("msg"=>NC_("Please fill in the e-mail.")); + } + // Check the length + if (sql_strlen($this->_form[$col]) > $this->maxlens[$col]) { + return array("msg"=>NC_("This e-mail is too long. (Max. length %d)"), + "margs"=>array($this->maxlens[$col])); + } + if (sql_strlen($this->_form[$col]) < $this->minlens[$col]) { + return array("msg"=>NC_("This e-mail is too short. (Min. length %d)"), + "margs"=>array($this->minlens[$col])); + } + // Check the e-mail validity + switch (is_email($this->_form[$col])) { + case ISEMAIL_OK: + break; + case ISEMAIL_MALFORMED: + default: + return array("msg"=>NC_("Please fill in a valid e-mail address.")); + case ISEMAIL_DOMAIN_NOT_FOUND: + return array("msg"=>NC_("The domain of this e-mail does not exists. Check if there is any typo in it.")); + } + // OK + return null; + } + + // _check_supgroup: Check the belonging groups + function _check_supgroup() + { + // Skip for a non-super-user editing herself + if ($this->_iscur && !is_su() && $this->_sn == get_login_sn()) { + return null; + } + for ($i = 0, $items = array(); !$this->_missing("supgroup$i" . "sn"); $i++) { + // Skip unselected ones + if ($this->_missing("supgroup$i")) { + continue; + } + // Regularize it + $this->_form["supgroup$i" . "sn"] = trim($this->_form["supgroup$i" . "sn"]); + // Check if this selection is duplicated + if (in_array($this->_form["supgroup$i" . "sn"], $items)) { + return array("msg"=>NC_("This belonging group is duplicated. You cannot set duplicated ones.")); + } + $items[] = $this->_form["supgroup$i" . "sn"]; + // Check with the subform checker + $form = array(); + $form["grp"] =& $this->_form["supgroup$i" . "sn"]; + if ($this->_iscur) { + $form["member"] =& $this->_sn; + } + $checker = new UserMembershipChecker($form); + $error = $checker->check(array("grp")); + if (!is_null($error)) { + return $error; + } + // Check if a special group is submitted + switch (groupid($this->_form["supgroup$i" . "sn"])) { + case SU_GROUP: + return array("msg"=>NC_("You cannot submit the super-user group along with other groups.")); + case ADMIN_GROUP: + return array("msg"=>NC_("You cannot set the administrators group.")); + case ALLUSERS_GROUP: + return array("msg"=>NC_("You cannot set the all-users group.")); + } + } + // OK + return null; + } +} + +// GroupChecker: Group form checker class +class GroupChecker extends BaseChecker +{ + // __construct: Initialize the checker + function __construct(&$form, $table = "groups") + { + parent::__construct($form, $table); + } + + // _check_id: Check the group ID. + function _check_id() + { + // Skip for a non-super-user editing a super-user group + if ($this->_iscur && !is_su() && $this->_sn == su_group_sn()) { + return null; + } + // Check if it exists + $error = $this->_missing("id"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["id"] = trim($this->_form["id"]); + // Check if it is filled + if ($this->_form["id"] == "") { + return array("msg"=>NC_("Please fill in the group ID.")); + } + // Check the length + if (sql_strlen($this->_form["id"]) > $this->maxlens["id"]) { + return array("msg"=>NC_("This group ID. is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["id"])); + } + if (sql_strlen($this->_form["id"]) < $this->minlens["id"]) { + return array("msg"=>NC_("This group ID. is too short. (Min. length %d)"), + "margs"=>array($this->minlens["id"])); + } + // Check if the characters used are valid + if (!preg_match("/^[a-z][a-z0-9_]*$/", $this->_form["id"])) { + return array("msg"=>NC_("Only lower-case English letters, numbers and underscores are allowed for the group ID.")); + } + // Check if this item is duplicated + $conds = array(); + $conds[] = "id='" . sql_esctext($this->_form["id"]) . "'"; + if ($this->_iscur) { + $conds[] = "sn!=" . $this->_sn; + } + $select = "SELECT * FROM " . $this->_table + . " WHERE " . implode(" AND ", $conds) . ";\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 0) { + return array("msg"=>NC_("This group already exists. You cannot create a duplicated one.")); + } + // OK + return null; + } + + // _check_dsc: Check the group description + function _check_dsc() + { + // Check if it exists + $error = $this->_missing("dsc"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["dsc"] = trim($this->_form["dsc"]); + // Check if it is filled + if ($this->_form["dsc"] == "") { + return array("msg"=>NC_("Please fill in the privilege description.")); + } + // Check the length + if (sql_strlen($this->_form["dsc"]) > $this->maxlens["dsc"]) { + return array("msg"=>NC_("This privilege description is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["dsc"])); + } + // OK + return null; + } + + // _check_subuser: Check the user members + function _check_subuser() + { + // Skip for a non-super-user editing a super-user group + if ($this->_iscur && !is_su() && $this->_sn == su_group_sn()) { + return null; + } + for ($i = 0, $items = array(); !$this->_missing("subuser$i" . "sn"); $i++) { + // Skip unselected ones + if ($this->_missing("subuser$i")) { + continue; + } + // Regularize it + $this->_form["subuser$i" . "sn"] = trim($this->_form["subuser$i" . "sn"]); + // Check if this selection is duplicated + if (in_array($this->_form["subuser$i" . "sn"], $items)) { + return array("msg"=>NC_("This user member is duplicated. You cannot set duplicated ones.")); + } + $items[] = $this->_form["subuser$i" . "sn"]; + // Check with the subform checker + $form = array(); + $form["member"] =& $this->_form["subuser$i" . "sn"]; + if ($this->_iscur) { + $form["grp"] =& $this->_sn; + } + $checker = new UserMembershipChecker($form); + $error = $checker->check(array("member")); + if (!is_null($error)) { + return $error; + } + } + // OK + return null; + } + + // _check_subgroup: Check the group members + function _check_subgroup() + { + // Skip for a non-super-user editing a super-user group + if ($this->_iscur && !is_su() && $this->_sn == su_group_sn()) { + return null; + } + for ($i = 0, $items = array(); !$this->_missing("subgroup$i" . "sn"); $i++) { + // Skip unselected ones + if ($this->_missing("subgroup$i")) { + continue; + } + // Regularize it + $this->_form["subgroup$i" . "sn"] = trim($this->_form["subgroup$i" . "sn"]); + // Check if this selection is duplicated + if (in_array($this->_form["subgroup$i" . "sn"], $items)) { + return array("msg"=>NC_("This group member is duplicated. You cannot set duplicated ones.")); + } + $items[] = $this->_form["subgroup$i" . "sn"]; + // Check with the subform checker + $form = array(); + $form["member"] =& $this->_form["subgroup$i" . "sn"]; + if ($this->_iscur) { + $form["grp"] =& $this->_sn; + } + $checker = new GroupMembershipChecker($form); + $error = $checker->check(array("member")); + if (!is_null($error)) { + return $error; + } + } + // OK + return null; + } + + // _check_supgroup: Check the belonging groups + function _check_supgroup() + { + // Skip for a non-super-user editing a super-user group + if ($this->_iscur && !is_su() && $this->_sn == su_group_sn()) { + return null; + } + for ($i = 0, $items = array(); !$this->_missing("supgroup$i" . "sn"); $i++) { + // Skip unselected ones + if ($this->_missing("supgroup$i")) { + continue; + } + // Regularize it + $this->_form["supgroup$i" . "sn"] = trim($this->_form["supgroup$i" . "sn"]); + // Check if this selection is duplicated + if (in_array($this->_form["supgroup$i" . "sn"], $items)) { + return array("msg"=>NC_("This belonging group is duplicated. You cannot set duplicated ones.")); + } + $items[] = $this->_form["supgroup$i" . "sn"]; + // Check with the subform checker + $form = array(); + $form["grp"] =& $this->_form["supgroup$i" . "sn"]; + if ($this->_iscur) { + $form["member"] =& $this->_sn; + } + $checker = new GroupMembershipChecker($form); + $error = $checker->check(array("grp")); + if (!is_null($error)) { + return $error; + } + } + // OK + return null; + } + + // _redir_selsubuser: Suspend and move to the subordinate user selection form + function _redir_selsubuser() + { + // Skip if not requested + if ($this->_missing("selsubuser")) { + return; + } + call_form(FORM_USERS, null, "import_selsubuser"); + } + + // _redir_selsubgroup: Suspend and move to the subordinate group selection form + function _redir_selsubgroup() + { + // Skip if not requested + if ($this->_missing("selsubgroup")) { + return; + } + call_form(FORM_GROUPS, null, "import_selsubgroup"); + } + + // _redir_selsupgroup: Suspend and move to the superordinate group selection form + function _redir_selsupgroup() + { + // Skip if not requested + if ($this->_missing("selsupgroup")) { + return; + } + call_form(FORM_GROUPS, null, "import_selsupgroup"); + } +} + +// UserMembershipChecker: User membership form checker class +class UserMembershipChecker extends BaseChecker +{ + // __construct: Initialize the checker + function __construct(&$form, $table = "usermem") + { + parent::__construct($form, $table); + } + + // check: Run a list of checks + function check($cols) + { + // Run the parent method + $error = parent::check($cols); + if (!is_null($error)) { + return $error; + } + // See if we need to check the duplicates. Check it in the end. + if (in_array("grp", $cols) && in_array("member", $cols)) { + $error = $this->__check_dup(); + if (!is_null($error)) { + return $error; + } + } + return null; + } + + // _check_grp: Check the group + // Use the default group checker + + // _check_member: Check the member + function _check_member() + { + // Check if it exists + $error = $this->_missing("member"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["member"] = trim($this->_form["member"]); + // Check if it is filled + if ($this->_form["member"] == "") { + return array("msg"=>NC_("Please select a member.")); + } + // Check if this member exists + if (!check_sn_in($this->_form["member"], "users AS usrmembers")) { + return array("msg"=>NC_("This member does not exist anymore. Please select another one.")); + } + // OK + return null; + } + + // __check_dup: Check if this item is duplicated + function __check_dup() + { + $conds = array(); + $conds[] = "grp=" . $this->_form["grp"]; + $conds[] = "member=" . $this->_form["member"]; + if ($this->_iscur) { + $conds[] = "sn!=" . $this->_sn; + } + $select = "SELECT * FROM " . $this->_table + . " WHERE " . implode(" AND ", $conds) . ";\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 0) { + return array("msg"=>NC_("This membership record already exists. You cannot create a duplicated one.")); + } + return null; + } + + // _redir_selmember: Suspend and move to the member selection form + function _redir_selmember() + { + // Skip if not requested + if ($this->_missing("selmember")) { + return; + } + call_form(FORM_USERS, null, "import_selmember"); + } + + // _redir_delmember: Remove the member + function _redir_delmember() + { + // Skip if not requested + if ($this->_missing("delmember")) { + return; + } + // Remove the item + unset($this->_form["member"]); + $status = null; + success_redirect($status); + } +} + +// GroupMembershipChecker: Group membership form checker class +class GroupMembershipChecker extends BaseChecker +{ + // __construct: Initialize the checker + function __construct(&$form, $table = "groupmem") + { + parent::__construct($form, $table); + } + + // check: Run a list of checks + function check($cols) + { + // Run the parent method + $error = parent::check($cols); + if (!is_null($error)) { + return $error; + } + // See if we need to check the duplicates. Check it in the end. + if (in_array("grp", $cols) && in_array("member", $cols)) { + $error = $this->__check_dup(); + if (!is_null($error)) { + return $error; + } + } + return null; + } + + // _check_grp: Check the group + function _check_grp() + { + // Run the default group checker + $error = parent::_check_grp(); + if (!is_null($error)) { + return $error; + } + // Check if the group and the member are different + if ( !$this->_missing("member") + && $this->_form["grp"] == $this->_form["member"]) { + return array("msg"=>NC_("Please select a different belonging group.")); + } + // OK + return null; + } + + // _check_member: Check the member + function _check_member() + { + // Check if it exists + $error = $this->_missing("member"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["member"] = trim($this->_form["member"]); + // Check if it is filled + if ($this->_form["member"] == "") { + return array("msg"=>NC_("Please select a member.")); + } + // Check if this member exists + if (!check_sn_in($this->_form["member"], "groups AS grpmembers")) { + return array("msg"=>NC_("This member does not exist anymore. Please select another one.")); + } + // Check if the group and the member are different + if ( !$this->_missing("grp") + && $this->_form["grp"] == $this->_form["member"]) { + return array("msg"=>NC_("Please select a different group member.")); + } + // OK + return null; + } + + // __check_dup: Check if this item is duplicated + function __check_dup() + { + $conds = array(); + $conds[] = "grp=" . $this->_form["grp"]; + $conds[] = "member=" . $this->_form["member"]; + if ($this->_iscur) { + $conds[] = "sn!=" . $this->_sn; + } + $select = "SELECT * FROM " . $this->_table + . " WHERE " . implode(" AND ", $conds) . ";\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 0) { + return array("msg"=>NC_("This membership record already exists. You cannot create a duplicated one.")); + } + return null; + } + + // _redir_selmember: Suspend and move to the member selection form + function _redir_selmember() + { + // Skip if not requested + if ($this->_missing("selmember")) { + return; + } + call_form(FORM_GROUPS, null, "import_selmember"); + } + + // _redir_delmember: Remove the member + function _redir_delmember() + { + // Skip if not requested + if ($this->_missing("delmember")) { + return; + } + // Remove the item + unset($this->_form["member"]); + $status = null; + success_redirect($status); + } +} + +// ScriptPrivilegeChecker: Script privilege form checker class +class ScriptPrivilegeChecker extends BaseChecker +{ + // __construct: Initialize the checker + function __construct(&$form, $table = "scptpriv") + { + parent::__construct($form, $table); + } + + // check: Run a list of checks + function check($cols) + { + // Run the parent method + $error = parent::check($cols); + if (!is_null($error)) { + return $error; + } + // See if we need to check the duplicates. Check it in the end. + if (in_array("script", $cols) && in_array("grp", $cols)) { + $error = $this->__check_dup(); + if (!is_null($error)) { + return $error; + } + } + return null; + } + + // _check_script: Check the script + // Use the default script checker + + // _check_grp: Check the group + // Use the default group checker + + // __check_dup: Check if this item is duplicated + function __check_dup() + { + $conds = array(); + $conds[] = "script='" . sql_esctext($this->_form["script"]) . "'"; + $conds[] = "grp=" . $this->_form["grp"]; + if ($this->_iscur) { + $conds[] = "sn!=" . $this->_sn; + } + $select = "SELECT * FROM " . $this->_table + . " WHERE " . implode(" AND ", $conds) . ";\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 0) { + return array("msg"=>NC_("This script privilege already exists. You cannot create a duplicated one.")); + } + return null; + } +} + +// UserPreferenceChecker: User preference form checker class +class UserPreferenceChecker extends BaseChecker +{ + // __construct: Initialize the checker + function __construct(&$form, $table = "userpref") + { + parent::__construct($form, $table); + } + + // check: Run a list of checks + function check($cols) + { + // Run the parent method + $error = parent::check($cols); + if (!is_null($error)) { + return $error; + } + // See if we need to check the duplicates. Check it in the end. + if (in_array("usr", $cols) && in_array("domain", $cols) && in_array("name", $cols)) { + $error = $this->__check_dup(); + if (!is_null($error)) { + return $error; + } + } + return null; + } + + // _check_usr: Check the user + function _check_usr() + { + // "everyone not set" has a different form context + if ($this->_missing("everyone")) { + return array("msg"=>NC_("Please select the user.")); + } + // Regularize it + $this->_form["everyone"] = trim($this->_form["everyone"]); + // Check the option value + if (!in_array($this->_form["everyone"], array("true", "false"))) { + return array("msg"=>NC_("This option is invalid. Please select a proper user.")); + } + // Run the default user checker if not everyone + if ($this->_form["everyone"] == "false") { + $error = parent::_check_usr(); + if (!is_null($error)) { + return $error; + } + } + // OK + return null; + } + + // _check_domain: Check the preference domain + function _check_domain() + { + // "everywhere not set" has a different form context + if ($this->_missing("everywhere")) { + return array("msg"=>NC_("Please set the preference domain.")); + } + // Regularize it + $this->_form["everywhere"] = trim($this->_form["everywhere"]); + // Check the option value + if (!in_array($this->_form["everywhere"], array("true", "false"))) { + return array("msg"=>NC_("This option is invalid. Please set a proper preference domain.")); + } + // Check the domain if not everywhere + if ($this->_form["everywhere"] == "false") { + // Check if it exists + $error = $this->_missing("domain"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["domain"] = trim($this->_form["domain"]); + // Check if it is filled + if ($this->_form["domain"] == "") { + return array("msg"=>NC_("Please fill in the preference domain.")); + } + // Check the length + if (sql_strlen($this->_form["domain"]) > $this->maxlens["domain"]) { + return array("msg"=>NC_("This preference domain is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["domain"])); + } + } + // OK + return null; + } + + // _check_name: Check the preference name + function _check_name() + { + // Check if it exists + $error = $this->_missing("name"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["name"] = trim($this->_form["name"]); + // Check if it is filled + if ($this->_form["name"] == "") { + return array("msg"=>NC_("Please fill in the preference name.")); + } + // Check the length + if (sql_strlen($this->_form["name"]) > $this->maxlens["name"]) { + return array("msg"=>NC_("This preference name is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["name"])); + } + // OK + return null; + } + + // _check_value: Check the preference value + function _check_value() + { + // Check if it exists + $error = $this->_missing("value"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["value"] = trim($this->_form["value"]); + // Check if it is filled + if ($this->_form["value"] == "") { + return array("msg"=>NC_("Please fill in the preference value.")); + } + // Check the length + if (sql_strlen($this->_form["value"]) > $this->maxlens["value"]) { + return array("msg"=>NC_("This preference value is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["value"])); + } + // OK + return null; + } + + // __check_dup: Check if this item is duplicated + function __check_dup() + { + $conds = array(); + if ($this->_form["everyone"] == "true") { + $conds[] = "usr IS NULL"; + } else { + $conds[] = "usr=" . $this->_form["usr"]; + } + if ($this->_form["everywhere"] == "true") { + $conds[] = "domain IS NULL"; + } else { + $conds[] = "domain='" . sql_esctext($this->_form["domain"]) . "'"; + } + $conds[] = "name='" . sql_esctext($this->_form["name"]) . "'"; + if ($this->_iscur) { + $conds[] = "sn!=" . $this->_sn; + } + $select = "SELECT * FROM " . $this->_table + . " WHERE " . implode(" AND ", $conds) . ";\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 0) { + return array("msg"=>NC_("This user preference already exists. You cannot create a duplicated one.")); + } + return null; + } + + // _redir_selusr: Suspend and move to the user selection form + function _redir_selusr() + { + // Skip if not requested + if ($this->_missing("selusr")) { + return; + } + call_form(FORM_USERS, null, "import_selusr"); + } + + // _redir_delusr: Remove the user + function _redir_delusr() + { + // Skip if not requested + if ($this->_missing("delusr")) { + return; + } + // Remove the item + unset($this->_form["usr"]); + $status = null; + success_redirect($status); + } +} + +// UserRequestChecker: user requests form checker class +class UserRequestChecker extends UserChecker +{ + protected $_types = array(); + + // __construct: Initialize the checker + function __construct(&$form, $table = "userreq") + { + parent::__construct($form, $table); + $this->minlens["email"] = 5; + $this->_types = array("join", "chgeml", "rstpwd"); + } + + // _check_type: Check the request type + function _check_type() + { + // "type not set" has a different form context + $error = $this->_missing("type"); + if (!is_null($error)) { + return array("msg"=>NC_("Please select the request type.")); + } + // Regularize it + $this->_form["type"] = trim($this->_form["type"]); + // Check the option value + if (!in_array($this->_form["type"], $this->_types)) { + return array("msg"=>NC_("This option is invalid. Please select a proper request type.")); + } + // OK + return null; + } + + // _check_usr: Check the user + function _check_usr() + { + // "anonymous not set" has a different form context + if ($this->_missing("anonymous")) { + return array("msg"=>NC_("Please select the user.")); + } + // Regularize it + $this->_form["anonymous"] = trim($this->_form["anonymous"]); + // Check the option value + if (!in_array($this->_form["anonymous"], array("true", "false"))) { + return array("msg"=>NC_("This option is invalid. Please select a proper user.")); + } + // Anonymous option depends on the request type + if ($this->_form["type"] == "join" && $this->_form["anonymous"] == "false") { + return array("msg"=>NC_("You must choose anonymous for join requests.")); + } + if ($this->_form["type"] != "join" && $this->_form["anonymous"] == "true") { + return array("msg"=>NC_("You cannot choose anonymous for non-join requests.")); + } + // Run the default user checker if not anonymous + if ($this->_form["anonymous"] == "false") { + $error = parent::_check_usr(); + if (!is_null($error)) { + return $error; + } + } + // OK + return null; + } + + // _check_args: Check the arguments + function _check_args() + { + // Check if it exists + $error = $this->_missing("args"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["args"] = trimtext($this->_form["args"]); + // Skip if it is not filled + if ($this->_form["args"] == C_("Please fill in the request arguments list here.")) { + $this->_form["args"] = ""; + } + if ($this->_form["args"] == "") { + return null; + } + // Check the length + if (sql_strlen($this->_form["args"]) > $this->maxlens["args"]) { + return array("msg"=>NC_("This request arguments list is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["args"])); + } + // OK + return null; + } + + // _redir_selusr: Suspend and move to the user selection form + function _redir_selusr() + { + // Skip if not requested + if ($this->_missing("selusr")) { + return; + } + call_form(FORM_USERS, null, "import_selusr"); + } + + // _redir_delusr: Remove the user + function _redir_delusr() + { + // Skip if not requested + if ($this->_missing("delusr")) { + return; + } + // Remove the item + unset($this->_form["usr"]); + $status = null; + success_redirect($status); + } +} + +// ListPreferenceChecker: List preference form checker class +class ListPreferenceChecker extends BaseChecker +{ + // Maximum list size is 1000, to prevent processing timeout. + const MAX_LISTSIZE = 1000; + + // __construct: Initialize the checker + function __construct(&$form, $table = "userpref") + { + if (func_num_args() < 2) { + if (!is_guest()) { + $table = "userpref"; + } else { + $table = null; + } + } + parent::__construct($form, $table); + if (is_null($table)) { + $this->maxlens = array(); + $this->maxlens["domain"] = 64; + $this->maxlens["name"] = 16; + $this->maxlens["value"] = 65536; + } + $this->maxlens["listsize"] = 4; + } + + // _check_domain: Check the preference domain + function _check_domain() + { + // Check if it exists + $error = $this->_missing("domain"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["domain"] = trim($this->_form["domain"]); + // Check if it is filled + if ($this->_form["domain"] == "") { + return array("msg"=>NC_("Please fill in the preference domain.")); + } + // Check the length + if (sql_strlen($this->_form["domain"]) > $this->maxlens["domain"]) { + return array("msg"=>NC_("This preference domain is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["domain"])); + } + // OK + return null; + } + + // _check_listcols: Check the list columns + function _check_listcols() + { + // No need to check the validility. Invalids are simply ignored. + $cols = array(); + foreach (array_keys($this->_form) as $key) { + if (preg_match("/^listcols_(.+)$/", $key, $m)) { + $cols[] = $m[1]; + } + } + // Obtain the preference value + $listcols = implode(" ", $cols); + // Check the length + if (sql_strlen("listcols") > $this->maxlens["name"]) { + $errmsg = sprintf("Maximum preference name length too short (%d for \"%s\" %d)", + $this->maxlens["name"], "listcols", sql_strlen("listcols")); + trigger_error($errmsg, E_USER_ERROR); + } + if (sql_strlen($listcols) > $this->maxlens["value"]) { + $errmsg = sprintf("Maximum preference value length too short (%d for \"%s\" %d)", + $this->maxlens["value"], $listcols, sql_strlen($listcols)); + trigger_error($errmsg, E_USER_ERROR); + } + // OK + return null; + } + + // _check_listsize: Check the list size + function _check_listsize() + { + // Check if it exists + $error = $this->_missing("listsize"); + if (!is_null($error)) { + return $error; + } + $min = 0; + //$max = pow(10, $this->maxlens["listsize"]) - 1; + // Text string + if (is_string($this->_form["listsize"])) { + // Regularize it + $this->_form["listsize"] = trim($this->_form["listsize"]); + // Check if it is filled + if ($this->_form["listsize"] == "") { + return array("msg"=>NC_("Please fill in the number of rows per page.")); + } + // Check the length + if (sql_strlen($this->_form["listsize"]) > $this->maxlens["listsize"]) { + return array("msg"=>NC_("This number of rows per page is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["listsize"])); + } + // If there is any non-digit character + if (preg_match("/\D/", $this->_form["listsize"])) { + return array("msg"=>NC_("Please fill in a positive integer number of rows per page.")); + } + // Check if it is in the valid range + if ($this->_form["listsize"] < $min) { + return array("msg"=>NC_("The number of rows per page is too small. Please fill in a larger number of rows per page between %d and %d."), + "margs"=>array($min, self::MAX_LISTSIZE)); + } + if ($this->_form["listsize"] > self::MAX_LISTSIZE) { + return array("msg"=>NC_("The number of rows per page is too large. Please fill in a smaller number of rows per page between %d and %d."), + "margs"=>array($min, self::MAX_LISTSIZE)); + } + // Convert its type to integer + settype($this->_form["listsize"], "integer"); + // Integer + } elseif (is_int($this->_form["listsize"])) { + // Check if it is in the valid range + if ($this->_form["listsize"] < $min) { + return array("msg"=>NC_("The number of rows per page is too small. Please fill in a larger number of rows per page between %d and %d."), + "margs"=>array($min, self::MAX_LISTSIZE)); + } + if ($this->_form["listsize"] > self::MAX_LISTSIZE) { + return array("msg"=>NC_("The number of rows per page is too large. Please fill in a smaller number of rows per page between %d and %d."), + "margs"=>array($min, self::MAX_LISTSIZE)); + } + // Other types are non-sense + } else { + trigger_error("Unknown type for column \"listsize\"", E_USER_ERROR); + } + // Check the length + if (sql_strlen("listsize") > $this->maxlens["name"]) { + $errmsg = sprintf("Maximum preference name length too short (%d for \"%s\" %d)", + $this->maxlens["name"], "listsize", sql_strlen("listsize")); + trigger_error($errmsg, E_USER_ERROR); + } + if (sql_strlen($this->_form["listsize"]) > $this->maxlens["value"]) { + $errmsg = sprintf("Maximum preference value length too short (%d for \"%s\" %d)", + $this->maxlens["value"], $this->_form["listsize"], sql_strlen($this->_form["listsize"])); + trigger_error($errmsg, E_USER_ERROR); + } + // OK + return null; + } +} + +// LogInChecker: Log in form checker class +class LogInChecker extends UserChecker +{ + public $row = null; + protected $_allcols; + protected $_login = null; + + // __construct: Initialize the checker + function __construct(&$form, $table = "users") + { + parent::__construct($form, $table); + $this->row = null; + $this->_allcols = sql_cols($table); + // Always confirmed + $this->_form["confirm"] = true; + } + + // check: Run a list of checks + function check($cols) + { + // See if a log in is attemped. + if (is_null($this->_login)) { + $this->_login = (in_array("id", $cols) && in_array("passwd", $cols)); + } + // Run the parent method + $error = parent::check($cols); + if (!is_null($error)) { + return $error; + } + return null; + } + + // _check_id: Check the user ID. + function _check_id() + { + // Check if it exists + $error = $this->_missing("id"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["id"] = trim($this->_form["id"]); + // Check if it is filled + if ($this->_form["id"] == "") { + return array("msg"=>NC_("Please fill in your user ID.")); + } + // Check the length + if (sql_strlen($this->_form["id"]) > $this->maxlens["id"]) { + if ($this->_login) { + actlog("Log in failed for user " . $this->_form["id"] + . " because user ID is too long."); + } + return array("msg"=>NC_("Log in failed. Either your user ID or your password is incorrect.")); + } + if (sql_strlen($this->_form["id"]) < $this->minlens["id"]) { + if ($this->_login) { + actlog("Log in failed for user " . $this->_form["id"] + . " because user ID is too short."); + } + return array("msg"=>NC_("Log in failed. Either your user ID or your password is incorrect.")); + } + + // Check if this user exists + $conds = array(); + $conds[] = "id='" . sql_esctext($this->_form["id"]) . "'"; + if (in_array("deleted", $this->_allcols)) { + $conds[] = sql_is_false("deleted"); + } + $select = "SELECT * FROM " . $this->_table + . " WHERE " . implode(" AND ", $conds) . ";\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 1) { + if ($this->_login) { + actlog("Log in failed for user " . $this->_form["id"] + . " because user ID does not exist."); + } + return array("msg"=>NC_("Log in failed. Either your user ID or your password is incorrect.")); + } + // Save it for further reference + $this->row = sql_fetch_assoc($result); + $this->_sn = $this->row["sn"]; + // Check if log-in is closed + if (defined("NOLOGIN") && NOLOGIN && !is_su($this->_sn)) { + if ($this->_login) { + actlog("Log in failed for user " . $this->_form["id"] + . " website is temporarily closed."); + } + // This message is duplicated + return array(); + } + // Check if this user is disabled + if ($this->row["disabled"]) { + if ($this->_login) { + actlog("Log in failed for user " . $this->_form["id"] + . " because account is disabled."); + } + return array("msg"=>NC_("Your account is disabled. Contact our system administrator for assistence.")); + } + // Check if we have exceed the maximum number of fail logins + // Skip super users - super users are invincible + if ( defined("MAX_FAIL_LOGINS") + && MAX_FAIL_LOGINS !== false + && !is_su($this->_sn) + && $this->row["fails"] >= MAX_FAIL_LOGINS) { + if ($this->_login) { + actlog("Log in failed for user " . $this->_form["id"] + . " because too many bad logins (" . $this->row["fails"] . ")."); + } + $this->_update_fails(); + return array("msg"=>NC_("Log in failed. Either your user ID or your password is incorrect.")); + } + // OK + return null; + } + + // _check_passwd: Check the user password + function _check_passwd() + { + // Skip password checks for guests + if ( !is_null($this->_sn) + && is_guest($this->_sn)) { + return null; + } + // Check if it exists + $error = $this->_missing("passwd"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["passwd"] = trim($this->_form["passwd"]); + // Check if it is filled + if ($this->_form["passwd"] == "") { + return array("msg"=>NC_("Please fill in your password.")); + } + // Check the length + if (sql_strlen($this->_form["passwd"]) > $this->maxlens["passwd"]) { + if ($this->_login) { + actlog("Log in failed for user " . $this->_form["id"] + . " because password is too long."); + } + $this->_update_fails(); + return array("msg"=>NC_("Log in failed. Either your user ID or your password is incorrect.")); + } + if (sql_strlen($this->_form["passwd"]) < $this->minlens["passwd"]) { + if ($this->_login) { + actlog("Log in failed for user " . $this->_form["id"] + . " because password is too short."); + } + $this->_update_fails(); + return array("msg"=>NC_("Log in failed. Either your user ID or your password is incorrect.")); + } + // Check if the password is correct + if ( !is_null($this->row) + && md5($this->_form["passwd"]) != $this->row["passwd"]) { + if ($this->_login) { + actlog("Log in failed for user " . $this->_form["id"] + . " because password is incorrect."); + } + $this->_update_fails(); + return array("msg"=>NC_("Log in failed. Either your user ID or your password is incorrect.")); + } + // OK + return null; + } + + // _check_admin: Check if the user is an administrator + function _check_admin() + { + // Skip checking for guests + if (is_guest($this->_sn)) { + return null; + } + // Skip checking for super users + if (is_su($this->_sn)) { + return null; + } + // Check if this user is an administrator + if (!is_admin($this->_sn)) { + if ($this->_login) { + actlog("Log in failed for user " . $this->_form["id"] + . " because user is not an administrator."); + } + return array("msg"=>NC_("You are not an administrator so may not log in here.")); + } + // OK + return null; + } + + // _check_nonadmin: Check if the user is not an administrator + function _check_nonadmin() + { + // Skip checking for guests + if (is_guest($this->_sn)) { + return null; + } + // Check if this user is an administrator + if (is_admin($this->_sn)) { + if ($this->_login) { + actlog("Log in failed for user " . $this->_form["id"] + . " because user is an administrator."); + } + return array("msg"=>NC_("You are an administrator so may not log in here.")); + } + // OK + return null; + } + + // _update_fails: Add one to the number of failed logins + function _update_fails() + { + // We need the user information + if (is_null($this->_sn)) { + return; + } + sql_begin(); + $update = "UPDATE users SET fails=fails+1," + . " updated=now()" + . " WHERE sn=" . $this->_sn . ";\n"; + sql_query($update); + sql_commit(); + $this->row["fails"]++; + return; + } +} + +///////////////////////// +// Content Checkers: Checkers for the content management system +///////////////////////// +// PageChecker: Page form checker class +class PageChecker extends BaseChecker +{ + // __construct: Initialize the checker + function __construct(&$form, $table = "pages") + { + parent::__construct($form, $table); + } + + // _check_path: Check the page path + // Use the default page path checker + + // _check_ord: Check the order + // Use the default order checker + + // _check_title: Check the title + // Use the default title checker + + // _check_body: Check the content body + // Use the default content body checker + + // _check_kw: Check the keyword list + // Use the default keyword list checker + + // _check_pic: Check the picture + // Use the default picture checker + + // _check_piccap: Check the picture caption + // Use the default picture captio checker + + // _check_picpos: Check the picture position + // Use the default picture position checker +} + +// NewsChecker: News form checker class +class NewsChecker extends BaseChecker +{ + // __construct: Initialize the checker + function __construct(&$form, $table = "news") + { + parent::__construct($form, $table); + } + + // _check_date: Check the date + // Use the default date checker + + // _check_ord: Check the order + // Actually this is to set the order, but not to check the order + function _check_ord() + { + // Current form + if ($this->_iscur) { + global $CURRENT; + // Same day -- inherit the same order + if ($this->_form["date"] == $CURRENT["date"]) { + $this->_form["ord"] = $CURRENT["ord"]; + return; + } + } + // Create a new order for this new day + $this->_form["ord"] = $this->_new_ord(); + return; + } + + // _check_title: Check the title + // Use the default title checker + + // _check_body: Check the content body + // Use the default content body checker + + // _check_kw: Check the keyword list + // Use the default keyword list checker + + // _check_pic: Check the picture + // Use the default picture checker + + // _new_ord: Create a new news order + function _new_ord() + { + // Cache the result + static $cache; + // Return the cache + if (isset($cache)) { + return $cache; + } + // Get the largest or der + $select = "SELECT ord FROM " . $this->_table + . " WHERE date='" . $this->_form["date"] . "'" + . " ORDER BY ord DESC LIMIT 1;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + // No record yet + if ($count == 0) { + $cache = 1; + // Largest plus 1 + } else { + $row = sql_fetch_assoc($result); + $cache = $row["ord"] + 1; + } + return $cache; + } +} + +// CountryChecker: Country form checker class +class CountryChecker extends BaseChecker +{ + // __construct: Initialize the checker + function __construct(&$form, $table = "country") + { + parent::__construct($form, $table); + $this->minlens["id"] = 2; + } + + // _check_id: Check the country code + function _check_id() + { + // Check if it exists + $error = $this->_missing("id"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["id"] = trim($this->_form["id"]); + // Check if it is filled + if ($this->_form["id"] == "") { + return array("msg"=>NC_("Please fill in the code.")); + } + // Check the length + if (sql_strlen($this->_form["id"]) != $this->maxlens["id"]) { + return array("msg"=>NC_("You must fill in a %d-letters code."), + "margs"=>array($this->maxlens["id"])); + } + // Check if the characters used are valid + if (!preg_match("/^(?:[A-Z][A-Z0-9]|==)$/", $this->_form["id"])) { + return array("msg"=>NC_("You can only use upper letters and for the code.")); + } + // Check if this item is duplicated + $conds = array(); + $conds[] = "id='" . sql_esctext($this->_form["id"]) . "'"; + if ($this->_iscur) { + $conds[] = "sn!=" . $this->_sn; + } + $select = "SELECT * FROM " . $this->_table + . " WHERE " . implode(" AND ", $conds) . ";\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 0) { + return array("msg"=>NC_("This code is duplicated. You cannot create a duplicated one.")); + } + // OK + return null; + } + + // _check_name: Check the country name + function _check_name() + { + // Check if it exists + $error = $this->_missing("name"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["name"] = trim($this->_form["name"]); + // Check if it is filled + if ($this->_form["name"] == "") { + return array("msg"=>NC_("Please fill in the country name.")); + } + // Check the length + if (sql_strlen($this->_form["name"]) > $this->maxlens["name"]) { + return array("msg"=>NC_("This country name is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["name"])); + } + // OK + return null; + } +} + +///////////////////////// +// Link Checkers: Checkers for the related links +///////////////////////// +// LinkCategoryChecker: Link category form checker class +class LinkCategoryChecker extends BaseChecker +{ + // __construct: Initialize the checker + function __construct(&$form, $table = "linkcat") + { + parent::__construct($form, $table); + $this->maxlens["ord"] = 2; + $this->minlens["id"] = 2; + } + + // _check_parent: Check the parent category + function _check_parent() + { + // "topmost not set" has a different form context + $error = $this->_missing("topmost"); + if (!is_null($error)) { + return array("msg"=>NC_("Please select a parent category.")); + } + // Regularize it + $this->_form["topmost"] = trim($this->_form["topmost"]); + // Check the option value + if (!in_array($this->_form["topmost"], array("true", "false"))) { + return array("msg"=>NC_("This option is invalid. Please select a proper parent category.")); + } + // Check the parent category if not a topmost category + if ($this->_form["topmost"] == "false") { + // Check if it exists + $error = $this->_missing("parent"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["parent"] = trim($this->_form["parent"]); + // Check if it is filled + if ($this->_form["parent"] == "") { + return array("msg"=>NC_("Please select a parent category.")); + } + // Check if this category exists + if (!check_sn_in($this->_form["parent"], "linkcat")) { + return array("msg"=>NC_("This parent category does not exist anymore. Please select another one.")); + } + if ($this->_iscur) { + // Check if the parent category is itself + if ($this->_form["parent"] == $this->_sn) { + return array("msg"=>NC_("A category cannot belong to itself. Please select another one.")); + } + // Check if the parent directory is its descendant + $select = "SELECT linkcat_ischild(" . $this->_sn . ", " + . $this->_form["parent"] . ") AS is_child;\n"; + $result = sql_query($select); + $row = sql_fetch_assoc($result); + if ($row["is_child"]) { + return array("msg"=>NC_("A category cannot belong to its descendant. Please select another one.")); + } + } + } + // OK + return null; + } + + // _check_id: Check the ID. + function _check_id() + { + // Run the default ID. checker + $error = parent::_check_id(); + if (!is_null($error)) { + return $error; + } + // ID. cannot be "index" to avoid overriding index.html + if ($this->_form["id"] == "index") { + return array("msg"=>NC_("\"index\" is dedicated to the index file index.html. You cannot set the ID. as \"index\".")); + } + // Check if this item is duplicated + if (!$this->_missing("topmost", "parent")) { + $conds = array(); + $conds[] = "id='" . sql_esctext($this->_form["id"]) . "'"; + if ($this->_iscur) { + $conds[] = "sn!=" . $this->_sn; + } + if ($this->_form["topmost"] == "true") { + $conds[] = "parent IS NULL"; + } else { + $conds[] = "parent=" . $this->_form["parent"]; + } + $select = "SELECT * FROM " . $this->_table + . " WHERE " . implode(" AND ", $conds) . ";\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 0) { + return array("msg"=>NC_("This category already exists. You cannot create a duplicated one.")); + } + } + // OK + return null; + } + + // _check_ord: Check the order + // Use the default order checker + + // _check_title: Check the title + // Use the default title checker + + // _check_kw: Check the keyword list + // Use the default keyword list checker + + // _redir_selparent: Suspend and move to the parent selection form + // Use the default parent redirector + + // _redir_delparent: Remove the parent + // Use the default parent remover +} + +// LinkChecker: Link form checker class +class LinkChecker extends BaseChecker +{ + // __construct: Initialize the checker + function __construct(&$form, $table = "links") + { + parent::__construct($form, $table); + } + + // _check_title: Check the title + // Use the default title checker + + // _check_url: Check the URL. + function _check_url() + { + // Check if it exists + $error = $this->_missing("url"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["url"] = trim($this->_form["url"]); + // Check if it is filled + if ($this->_form["url"] == "" || $this->_form["url"] == "http://") { + return array("msg"=>NC_("Please fill in the URL..")); + } + // Check the length + if (sql_strlen($this->_form["url"]) > $this->maxlens["url"]) { + return array("msg"=>NC_("This URL. is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["url"])); + } + // Check its format + if (!is_url_wellformed($this->_form["url"])) { + return array("msg"=>NC_("Please fill in a valid URL..")); + } + // Check if this item is duplicated + $conds = array(); + $conds[] = "url='" . sql_esctext($this->_form["url"]) . "'"; + if ($this->_iscur) { + $conds[] = "sn!=" . $this->_sn; + } + $select = "SELECT * FROM " . $this->_table + . " WHERE " . implode(" AND ", $conds) . ";\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 0) { + return array("msg"=>NC_("This related link already exists. You cannot create a duplicated one.")); + } + // Check if it is available + if ( $this->_missing("hid") + && !is_url_reachable($this->_form["url"])) { + return array("msg"=>NC_("This URL. is not reachable. Check if there is any typo in it.")); + } + // OK + return null; + } + + // _check_dsc: Check the description + function _check_dsc() + { + // Check if it exists + $error = $this->_missing("dsc"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["dsc"] = trimtext($this->_form["dsc"]); + // Check if it is filled + if ($this->_form["dsc"] == C_("Fill in the description here.")) { + $this->_form["dsc"] = ""; + } + if ($this->_form["dsc"] == "") { + return array("msg"=>NC_("Please fill in the description.")); + } + // Check the length + if (sql_strlen($this->_form["dsc"]) > $this->maxlens["dsc"]) { + return array("msg"=>NC_("This description is too long. (Max. length %d)"), + "margs"=>array($this->maxlens["dsc"])); + } + // OK + return null; + } + + // _check_cats: Check the categories list + function _check_cats() + { + // Loop each category + for ($i = 0, $items = array(); !$this->_missing("cat$i"); $i++) { + // Regularize it + $this->_form["cat$i"] = trim($this->_form["cat$i"]); + // Skip if it is not filled + if ($this->_form["cat$i"] == "") { + continue; + } + // Check if this selection is duplicated + if (in_array($this->_form["cat$i"], $items)) { + return array("msg"=>NC_("This category is duplicated. You cannot set duplicated ones.")); + } + // Check if the category exists + if (!check_sn_in($this->_form["cat$i"], "linkcat")) { + return array("msg"=>NC_("This category does not exist anymore. Please select another one.")); + } + $items[] = $this->_form["cat$i"]; + } + // Check if there is any category selected + if (count($items) == 0) { + return array("msg"=>NC_("Please select a category.")); + } + // OK + return null; + } +} + +// LinkCategorizationChecker: Link categorization form checker class +class LinkCategorizationChecker extends BaseChecker +{ + // __construct: Initialize the checker + function __construct(&$form, $table = "linkcatz") + { + parent::__construct($form, $table); + } + + // check: Run a list of checks + function check($cols) + { + // Run the parent method + $error = parent::check($cols); + if (!is_null($error)) { + return $error; + } + // See if we need to check the duplicates. Check it in the end. + if (in_array("cat", $cols) && in_array("link", $cols)) { + $error = $this->__check_dup(); + if (!is_null($error)) { + return $error; + } + } + return null; + } + + // _check_cat: Check the category + function _check_cat() + { + // Check if it exists + $error = $this->_missing("cat"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["cat"] = trim($this->_form["cat"]); + // Check if it is filled + if ($this->_form["cat"] == "") { + return array("msg"=>NC_("Please select a category.")); + } + // Check if this category exists + if (!check_sn_in($this->_form["cat"], "linkcat")) { + return array("msg"=>NC_("This category does not exist anymore. Please select another one.")); + } + // OK + return null; + } + + // _check_link: Check the link + function _check_link() + { + // Check if it exists + $error = $this->_missing("link"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["link"] = trim($this->_form["link"]); + // Check if it is filled + if ($this->_form["link"] == "") { + return array("msg"=>NC_("Please select a related link.")); + } + // Check if this link exists + if (!check_sn_in($this->_form["link"], "links")) { + return array("msg"=>NC_("This link does not exist anymore. Please select another one.")); + } + // OK + return null; + } + + // __check_dup: Check if this item is duplicated + function __check_dup() + { + $conds = array(); + $conds[] = "cat=" . $this->_form["cat"]; + $conds[] = "link=" . $this->_form["link"]; + if ($this->_iscur) { + $conds[] = "sn!=" . $this->_sn; + } + $select = "SELECT * FROM " . $this->_table + . " WHERE " . implode(" AND ", $conds) . ";\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 0) { + return array("msg"=>NC_("This link categorization already exists. You cannot create a duplicated one.")); + } + return null; + } + + // _redir_sellink: Suspend and move to the link selection form + function _redir_sellink() + { + // Skip if not requested + if ($this->_missing("sellink")) { + return; + } + call_form(FORM_LINKS, null, "import_sellink"); + } +} + + +///////////////////////// +// Miscellaneous Checkers: Checkers for various data +///////////////////////// +// RebuildChecker: Rebuild form checker class +class RebuildChecker extends BaseChecker +{ + // __construct: Initialize the checker + function __construct(&$form, $table = null) + { + parent::__construct($form, $table); + } + + // _check_type: Check the page type + function _check_type() + { + // Check if it exists + $error = $this->_missing("type"); + if (!is_null($error)) { + return $error; + } + // Regularize it + $this->_form["type"] = trim($this->_form["type"]); + // Check if it is filled + if ($this->_form["type"] == "") { + return array("msg"=>NC_("Please select the type.")); + } + // Check if this link exists + if (!function_exists("rebuild_" . $this->_form["type"])) { + return array("msg"=>NC_("This type does not exist anymore. Please select another one.")); + } + // OK + return null; + } +} + +// QueryChecker: Query form checker class +class QueryChecker extends BaseChecker +{ + // __construct: Initialize the checker + function __construct(&$form, $table = null) + { + parent::__construct($form, $table); + } + + // _check_query: Check the query phrase + function _check_query() + { + // Skip if there is no query phrase + if ($this->_missing("query")) { + return null; + } + // Regularize it + $this->_form["query"] = trim($this->_form["query"]); + // Check if it is filled + if ($this->_form["query"] == "") { + return array("msg"=>NC_("Please fill in your query.")); + } + // OK + return null; + } +} + +// PictureChecker: Picture form checker class +// This is specially for the pic.php picture handler +class PictureChecker extends BaseChecker +{ + protected $_newpic = null; + + // __construct: Initialize the checker + function __construct(&$form, $table = null) + { + parent::__construct($form, $table); + } + + // _check_pic: Check the picture + function _check_pic() + { + // Check if it exists + $error = $this->_missing("pic"); + if (!is_null($error)) { + return array("msg"=>NC_("Please submit the picture.")); + } + // Check if this picture exists + if (!pic_exists($this->_form["pic"])) { + return array("msg"=>NC_("This picture does not exist anymore. Please upload another one.")); + } + // Obtain the picture + $PICS =& pic_deposit(); + $this->_newpic =& $PICS[$this->_form["pic"]]; + // OK + return null; + } + + // _check_ratio: Check the picture ratio + function _check_ratio() + { + // Check if it exists + $error = $this->_missing("ratio"); + if (!is_null($error)) { + return $error; + } + // Regularize it + if (is_string($this->_form["ratio"])) { + $this->_form["ratio"] = trim($this->_form["ratio"]); + } + // Check if it is filled + if ($this->_form["ratio"] == "") { + return array("msg"=>NC_("Please fill in the resize ratio.")); + } + // Check if the resize ratio is valid + if (!is_null($this->_newpic)) { + $error = check_pic_ratio($this->_newpic, $this->_form["ratio"]); + if (!is_null($error)) { + return $error; + } + } + } + + // _save_uploaded_pic: Check and save the uploaded picture + function _save_uploaded_pic() + { + // Check if it exists + $error = file_has("uppic"); + if (!is_null($error)) { + return $error; + } + // Skip if no new file was submitted + if ($_FILES["uppic"]["error"] == UPLOAD_ERR_NO_FILE) { + return null; + } + // Check the upload error + $error = check_picfile("uppic"); + if (!is_null($error)) { + return $error; + } + // Save the picture + $pic = array(); + $pic["content"] = xfread($_FILES["uppic"]["tmp_name"]); + $pic["type"] = $_FILES["uppic"]["type"]; + $img = imagecreatefromstring($pic["content"]); + $pic["width"] = imagesx($img); + $pic["height"] = imagesy($img); + $picid = suspend_pic($pic); + $this->_form["pic"] = $picid; + $this->_form["ratio"] = best_pic_ratio($pic); + // Do not confirm now + if (!$this->_missing("confirm")) { + unset($this->_form["confirm"]); + } + // OK + return null; + } +} + +// ShowPictureChecker: Show picture form checker class +class ShowPictureChecker extends BaseChecker +{ + protected $_pic = null; + + // __construct: Initialize the checker + function __construct(&$form, $table = null) + { + parent::__construct($form, $table); + } + + // _check_sn: Check the picture S/N + function _check_sn() + { + // Check if it exists + $error = $this->_missing("sn"); + if (!is_null($error)) { + return $error; + } + // Check if the picture is valid + if (!pic_exists($this->_form["sn"])) { + return array("msg"=>NC_("Please specify a valid picture.")); + } + // Obtain the picture + $PICS =& pic_deposit(); + $this->_pic =& $PICS[$this->_form["sn"]]; + // OK + return null; + } + + // _check_ratio: Check the picture ratio + function _check_ratio() + { + // Check if it exists + $error = $this->_missing("ratio"); + if (!is_null($error)) { + return $error; + } + // Regularize it + if (is_string($this->_form["ratio"])) { + $this->_form["ratio"] = trim($this->_form["ratio"]); + } + // Check if it is filled + if ($this->_form["ratio"] == "") { + return array("msg"=>NC_("Please fill in the resize ratio.")); + } + // Check if the resize ratio is valid + if (!is_null($this->_pic)) { + $error = check_pic_ratio($this->_pic, $this->_form["ratio"]); + if (!is_null($error)) { + return $error; + } + } + } +} + +?> diff --git a/lib/php/monica/chkfunc.inc.php b/lib/php/monica/chkfunc.inc.php new file mode 100644 index 0000000..d85d695 --- /dev/null +++ b/lib/php/monica/chkfunc.inc.php @@ -0,0 +1,284 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/errhndl.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/urlregex.inc.php"; + +// get_has: Check if certain GET fields are submitted +function get_has() +{ + // field names are read from the arguments + $fields = func_get_args(); + return _form_has($_GET, $fields); +} + +// post_has: Check if certain POST fields are submitted +function post_has() +{ + // field names are read from the arguments + $fields = func_get_args(); + return _form_has($_POST, $fields); +} + +// file_has: Check if certain files are submitted +function file_has() +{ + // Field names are read from the arguments + $fields = func_get_args(); + foreach ($fields as $field) { + // Field recognized as a file field, regardless of whether + // a file uploaded or not + if (array_key_exists($field, $_FILES)) { + continue; + } + // Field presented as an empty POST field when no + // file was submitted + if (array_key_exists($field, $_POST) && $_POST[$field] == "") { + // Present it as the above format + unset($_POST[$field]); + $_FILES[$field] = array("name" => "", + "type" => "application/octet-stream", + "tmp_name" => "", + "error" => 4, + "size" => 0); + continue; + } + // The field was not submitted at all + return array("msg"=>NC_("The following field was not received: \"%s\"."), + "margs"=>array($field), + "init"=>true); + } + // OK + return null; +} + +// _form_has: Check if certain form fields are submitted +function _form_has(&$FORM, $fields) +{ + foreach ($fields as $field) { + if (!array_key_exists($field, $FORM)) { + return array("msg"=>NC_("The following field was not received: \"%s\"."), + "margs"=>array($field), + "init"=>true); + } + } + // OK + return null; +} + +// check_sn: Check if a serial number is valid +// Rule for a serial number: +// An integer of 9 digits within 100000000 - 999999999 +function check_sn(&$sn) +{ + // Text string + if (is_string($sn)) { + // If it is too long or too short + if (strlen($sn) != 9) { + return false; + } + // If there is any non-digit character + if (preg_match("/\D/", $sn)) { + return false; + } + // Check if it is in the valid range. It is not possible to be + // larger than 999999999 now, due to the previous length check. + if ($sn < 100000000) { + return false; + } + // Convert its type to integer + settype($sn, "integer"); + return true; + } + + // Integer + if (is_int($sn)) { + // Check if it is in the valid range + return ($sn >= 100000000 && $sn <= 999999999); + } + + // Bounce other types + return false; +} + +// check_ord: Check if an order is valid +// Rule for an order: +// An integer within 0 - 9999 +function check_ord(&$ord) +{ + // Text string + if (is_string($ord)) { + // If it is too long or too short + if (strlen($ord) > 4) { + return false; + } + // If there is any non-digit character + if (preg_match("/\D/", $ord)) { + return false; + } + // Check if it is in the valid range. It is not possible to be + // less than 0 now, due to the previous non-digit character check. + if ($ord < 9999) { + return false; + } + // Convert its type to integer + settype($ord, "integer"); + return true; + } + + // Integer + if (is_int($ord)) { + // Check if it is in the valid range + return ($ord >= 0 && $ord <= 9999); + } + + // Bounce other types + return false; +} + +// check_date: Check if a submitted date set is valid +function check_date($year, $month, $day) +{ + // Check if the year is legal + if (!is_numeric($year)) { + return array("msg"=>NC_("Please select a legal year.")); + } + $year += 0; + if (!is_int($year)) { + return array("msg"=>NC_("Please select a legal year.")); + } + if (defined("YEAR_START") && $year < YEAR_START) { + return array("msg"=>NC_("Please select a legal year.")); + } + if (defined("YEAR_END") && $year > YEAR_END) { + return array("msg"=>NC_("Please select a legal year.")); + } + + // Check if the month is legal + if (!is_numeric($month)) { + return array("msg"=>NC_("Please select a legal month.")); + } + $month += 0; + if (!is_int($month)) { + return array("msg"=>NC_("Please select a legal month.")); + } + if ($month < 1 || $month > 12) { + return array("msg"=>NC_("Please select a legal month.")); + } + + // Check if the day is legal + if (!is_numeric($day)) { + return array("msg"=>NC_("Please select a legal day.")); + } + $day += 0; + if (!is_int($day)) { + return array("msg"=>NC_("Please select a legal day.")); + } + // Count the last day number of that specified month + $first_day_of_next_month = mktime(0, 0, 0, $month+1, 1, $year); + $last_day_of_this_month = $first_day_of_next_month - 86400; + if ($day < 1 || $day > date("j", $last_day_of_this_month)) { + return array("msg"=>NC_("Please select a legal day.")); + } + // OK + return null; +} + +// check_sn_in: Check if a serial number exists in a table +function check_sn_in(&$sn, $table) +{ + // Check the validity of the serial number first + if (!check_sn($sn)) { + return false; + } + $select = "SELECT * FROM $table WHERE sn=$sn;\n"; + $result = sql_query($select); + return (sql_num_rows($result) == 1); +} + +// check_script: Check if a script exists +function check_script($path) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($path, $cache)) { + return $cache[$path]; + } + + // Add index.php to directories + if (substr($path, -1) == "/") { + $path .= "index.php"; + } + + // Not a PHP script + if (substr($path, -4) != ".php") { + $cache[$path] = false; + // Not exists + } elseif (!file_exists(DOC_ROOT . $path)) { + $cache[$path] = false; + // OK + } else { + $cache[$path] = true; + } + return $cache[$path]; +} + +// check_country: Check if a country exists +function check_country($ct) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($ct, $cache)) { + return $cache[$ct]; + } + + $select = "SELECT id FROM country WHERE id='" . sql_esctext($ct) . "';\n"; + $result = sql_query($select); + $cache[$ct] = (sql_num_rows($result) == 1); + return $cache[$ct]; +} + +// is_url_wellformed: Check if the target of an URL is wellformed +function is_url_wellformed($url) +{ + return preg_match("/^" . URLREGEX_URL . "$/", $url)? true: false; +} + +// is_url_reachable: Check if the target of an URL is reachable +function is_url_reachable($url) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($url, $cache)) { + return $cache[$url]; + } + // Check if it is available + set_error_handler("null_error_handler"); + $fp = fopen($url, "r"); + restore_error_handler(); + if ($fp === false) { + $cache[$url] = false; + return false; + } + fclose($fp); + // OK + $cache[$url] = true; + return true; +} + +?> diff --git a/lib/php/monica/chkpriv.inc.php b/lib/php/monica/chkpriv.inc.php new file mode 100644 index 0000000..0d178ea --- /dev/null +++ b/lib/php/monica/chkpriv.inc.php @@ -0,0 +1,335 @@ + +// Copyright: Copyright (C) 2001-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/chkfunc.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/username.inc.php"; +require_once "monica/usrconst.inc.php"; + +// Constant symbols + +// is_admin: If the user is an administrator (by user sn) +function is_admin($user = null) +{ + // Cache the result + static $cache = array(); + // Default to the current logged-in user + if (is_null($user) || $user == get_login_sn()) { + return is_su() || in_array(ADMIN_GROUP, get_login_groups()); + } + // Return the cache + if (array_key_exists($user, $cache)) { + return $cache[$user]; + } + // Super user is always an administrator + if (is_su($user)) { + $cache[$user] = true; + return true; + } + // Obtain the groups + $groups = user_parent_groups($user); + $cache[$user] = in_array(ADMIN_GROUP, $groups); + return $cache[$user]; +} + +// is_group: If the user belongs to a group +function is_group($group) +{ + return in_array($group, get_login_groups()); +} + +// is_su: If the user is a super user +function is_su($user = null) +{ + // Cache the result + static $cache = array(); + // Default to check the current user + if (is_null($user)) { + return in_array(SU_GROUP, get_login_groups()); + } + // Return the cache + if (array_key_exists($user, $cache)) { + return $cache[$user]; + } + // Obtain the groups + $groups = user_parent_groups($user); + $cache[$user] = in_array(SU_GROUP, $groups); + return $cache[$user]; +} + +// user_parent_groups: Return the full list of groups a user belongs to +function user_parent_groups($sn) +{ + // Cache the result + static $cache = array(); + // Bounce for null + if (is_null($sn)) { + return array(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + // Check the validity of the user first + if ($sn != get_login_sn()) { + if (!check_sn_in($sn, "users")) { + $cache[$sn] = array(); + return $cache[$sn]; + } + } + // Find the direct parent groups + $select = "SELECT grp FROM usermem" + . " WHERE member=$sn" + . " ORDER BY grp;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + // Obtain the direct parent groups + for ($i = 0, $current = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $current[] = $row["grp"]; + } + // ALLUSERS_GROUP is automatically added to all logged-in users + $allusers = groupsn(ALLUSERS_GROUP); + if (!is_null($allusers) && !in_array($allusers, $current)) { + $current[] = $allusers; + sort($current); + } + // Trace all their ancester groups + while (true) { + $conds = array(); + for ($i = 0; $i < count($current); $i++) { + $conds[] = "member=" . $current[$i]; + } + $select = "SELECT grp FROM groupmem" + . " WHERE " . implode(" OR ", $conds) + . " GROUP BY grp ORDER BY grp;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0, $newfound = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $newfound[] = $row["grp"]; + } + $newfound = array_diff($newfound, $current); + if (count($newfound) == 0) { + break; + } + $current = array_merge($current, $newfound); + } + // Find their ID + $conds = array(); + for ($i = 0; $i < count($current); $i++) { + $conds[] = "sn=" . $current[$i]; + } + $select = "SELECT id FROM groups" + . " WHERE " . implode(" OR ", $conds) + . " ORDER BY id;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0, $items = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $items[] = $row["id"]; + } + // Cache it + $cache[$sn] = $items; + return $items; +} + +// group_parent_groups: Return the full list of groups a group belongs to +function group_parent_groups($sn) +{ + // Cache the result + static $cache = array(); + // Bounce for null + if (is_null($sn)) { + return array(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + // Check the validity of the group first + if (!check_sn_in($sn, "groups")) { + $cache[$sn] = array(); + return $cache[$sn]; + } + $current = array($sn); + // Trace all their ancester groups + while (true) { + $conds = array(); + for ($i = 0; $i < count($current); $i++) { + $conds[] = "member=" . $current[$i]; + } + $select = "SELECT grp FROM groupmem" + . " WHERE " . implode(" OR ", $conds) + . " GROUP BY grp ORDER BY grp;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0, $newfound = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $newfound[] = $row["grp"]; + } + $newfound = array_values(array_unique(array_merge($current, $newfound))); + sort($newfound); + if ($newfound == $current) { + break; + } + $current = $newfound; + } + // Remove myself + $current = array_values(array_diff($current, array($sn))); + // Find their ID + $conds = array(); + for ($i = 0; $i < count($current); $i++) { + $conds[] = "sn=" . $current[$i]; + } + $select = "SELECT id FROM groups" + . " WHERE " . implode(" OR ", $conds) + . " ORDER BY id;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0, $items = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $items[] = $row["id"]; + } + // Cache it + $cache[$sn] = $items; + return $items; +} + +// group_child_users: Return the full list of users in a group +function group_child_users($sn) +{ + // Cache the result + static $cache = array(); + // Bounce for null + if (is_null($sn)) { + return array(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + $current = array($sn); + // Collect all their lower child groups + while (true) { + $conds = array(); + for ($i = 0; $i < count($current); $i++) { + $conds[] = "grp=" . $current[$i]; + } + $select = "SELECT member FROM groupmem" + . " WHERE " . implode(" OR ", $conds) + . " GROUP BY member ORDER BY member;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0, $newfound = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $newfound[] = $row["member"]; + } + $newfound = array_values(array_unique(array_merge($current, $newfound))); + sort($newfound); + if ($newfound == $current) { + break; + } + $current = $newfound; + } + // Find their member users + $conds = array(); + for ($i = 0; $i < count($current); $i++) { + $conds[] = "grp=" . $current[$i]; + } + $select = "SELECT member FROM usermem" + . " WHERE " . implode(" OR ", $conds) + . " GROUP BY member ORDER BY member;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0, $current = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $current[] = $row["member"]; + } + // Find their ID + $conds = array(); + for ($i = 0; $i < count($current); $i++) { + $conds[] = "sn=" . $current[$i]; + } + $select = "SELECT id FROM users" + . " WHERE " . implode(" OR ", $conds) + . " ORDER BY id;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0, $items = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $items[] = $row["id"]; + } + // Cache it + $cache[$sn] = $items; + return $items; +} + +// group_child_groups: Return the full list of groups in a group +function group_child_groups($sn) +{ + // Cache the result + static $cache = array(); + // Bounce for null + if (is_null($sn)) { + return array(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + $current = array($sn); + // Collect all their lower child groups + while (true) { + $conds = array(); + for ($i = 0; $i < count($current); $i++) { + $conds[] = "grp=" . $current[$i]; + } + $select = "SELECT member FROM groupmem" + . " WHERE " . implode(" OR ", $conds) + . " GROUP BY member ORDER BY member;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0, $newfound = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $newfound[] = $row["member"]; + } + $newfound = array_values(array_unique(array_merge($current, $newfound))); + sort($newfound); + if ($newfound == $current) { + break; + } + $current = $newfound; + } + // Remove myself + $current = array_values(array_diff($current, array($sn))); + // Find their ID + $conds = array(); + for ($i = 0; $i < count($current); $i++) { + $conds[] = "sn=" . $current[$i]; + } + $select = "SELECT id FROM groups" + . " WHERE " . implode(" OR ", $conds) + . " ORDER BY id;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0, $items = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $items[] = $row["id"]; + } + // Cache it + $cache[$sn] = $items; + return $items; +} + +?> diff --git a/lib/php/monica/chkwrite.inc.php b/lib/php/monica/chkwrite.inc.php new file mode 100644 index 0000000..567ed47 --- /dev/null +++ b/lib/php/monica/chkwrite.inc.php @@ -0,0 +1,63 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/gettext.inc.php"; +require_once "monica/rel2abs.inc.php"; + +// check_writable: Check the permission to write to a file. +// Input: File full pathname $file. +// Output: true if success, false if failed. +function check_writable($file) +{ + // Standardize it + $file = stdpath($file); + // File exists. + if (file_exists($file)) { + // If it is a file + if (!is_file($file)) { + return array("msg"=>NC_("%s: It is not a file."), + "margs"=>array($file)); + } + // If it is writable + if (!is_writable($file)) { + return array("msg"=>NC_("%s: You have no permission to overwrite this file."), + "margs"=>array($file)); + } + + // Not an existing file. See if we can create it. + } else { + $parent = $file; + // Find the nearest existing parent + while ($parent != "" && !file_exists($parent)) { + $parent = dirname($parent); + } + // Creat files from root --- You are insane + if ($parent == "") { + return array("msg"=>NC_("%s: You cannot create anything under the root directory."), + "margs"=>array($file)); + } + // This parent is not a directory + if (!is_dir($parent)) { + return array("msg"=>NC_("%s: One of the parents of this file (%s) is not a directory. You cannot create any new file inside."), + "margs"=>array($file, $parent)); + } + // If it is possible to create entries in this directory + if (!is_writable($parent)) { + return array("msg"=>NC_("%s: You have no permission to create any file under %s."), + "margs"=>array($file, $parent)); + } + } + // OK + return null; +} + +?> diff --git a/lib/php/monica/cnvtmap/Big5.inc.php b/lib/php/monica/cnvtmap/Big5.inc.php new file mode 100644 index 0000000..788ee94 --- /dev/null +++ b/lib/php/monica/cnvtmap/Big5.inc.php @@ -0,0 +1,3817 @@ + +// Copyright: Copyright (C) 2005-2007 Pristine Communications + +// Big5 +$CNVTMAP["Big5"] = array( + 0x000081, 0x0000A6, 0x000000, 0xFFFFFF, + 0x0000A8, 0x0000AE, 0x000000, 0xFFFFFF, + 0x0000B2, 0x0000B6, 0x000000, 0xFFFFFF, + 0x0000B8, 0x0000D6, 0x000000, 0xFFFFFF, + 0x0000D8, 0x0000F6, 0x000000, 0xFFFFFF, + 0x0000F8, 0x0002C6, 0x000000, 0xFFFFFF, + 0x0002C8, 0x0002C8, 0x000000, 0xFFFFFF, + 0x0002CC, 0x0002CC, 0x000000, 0xFFFFFF, + 0x0002CE, 0x0002D8, 0x000000, 0xFFFFFF, + 0x0002DA, 0x000390, 0x000000, 0xFFFFFF, + 0x0003A2, 0x0003A2, 0x000000, 0xFFFFFF, + 0x0003AA, 0x0003B0, 0x000000, 0xFFFFFF, + 0x0003C2, 0x0003C2, 0x000000, 0xFFFFFF, + 0x0003CA, 0x002012, 0x000000, 0xFFFFFF, + 0x002015, 0x002017, 0x000000, 0xFFFFFF, + 0x00201A, 0x00201B, 0x000000, 0xFFFFFF, + 0x00201E, 0x002024, 0x000000, 0xFFFFFF, + 0x002028, 0x002031, 0x000000, 0xFFFFFF, + 0x002033, 0x002034, 0x000000, 0xFFFFFF, + 0x002036, 0x00203A, 0x000000, 0xFFFFFF, + 0x00203C, 0x0020AB, 0x000000, 0xFFFFFF, + 0x0020AD, 0x002102, 0x000000, 0xFFFFFF, + 0x002104, 0x002104, 0x000000, 0xFFFFFF, + 0x002106, 0x002108, 0x000000, 0xFFFFFF, + 0x00210A, 0x00215F, 0x000000, 0xFFFFFF, + 0x00216A, 0x00218F, 0x000000, 0xFFFFFF, + 0x002194, 0x002195, 0x000000, 0xFFFFFF, + 0x00219A, 0x002214, 0x000000, 0xFFFFFF, + 0x002216, 0x002219, 0x000000, 0xFFFFFF, + 0x00221B, 0x00221D, 0x000000, 0xFFFFFF, + 0x002221, 0x002222, 0x000000, 0xFFFFFF, + 0x002224, 0x002224, 0x000000, 0xFFFFFF, + 0x002226, 0x002228, 0x000000, 0xFFFFFF, + 0x00222C, 0x00222D, 0x000000, 0xFFFFFF, + 0x00222F, 0x002233, 0x000000, 0xFFFFFF, + 0x002236, 0x002251, 0x000000, 0xFFFFFF, + 0x002253, 0x00225F, 0x000000, 0xFFFFFF, + 0x002262, 0x002265, 0x000000, 0xFFFFFF, + 0x002268, 0x002294, 0x000000, 0xFFFFFF, + 0x002296, 0x002298, 0x000000, 0xFFFFFF, + 0x00229A, 0x0022A4, 0x000000, 0xFFFFFF, + 0x0022A6, 0x0022BE, 0x000000, 0xFFFFFF, + 0x0022C0, 0x0024FF, 0x000000, 0xFFFFFF, + 0x002501, 0x002501, 0x000000, 0xFFFFFF, + 0x002503, 0x00250B, 0x000000, 0xFFFFFF, + 0x00250D, 0x00250F, 0x000000, 0xFFFFFF, + 0x002511, 0x002513, 0x000000, 0xFFFFFF, + 0x002515, 0x002517, 0x000000, 0xFFFFFF, + 0x002519, 0x00251B, 0x000000, 0xFFFFFF, + 0x00251D, 0x002523, 0x000000, 0xFFFFFF, + 0x002525, 0x00252B, 0x000000, 0xFFFFFF, + 0x00252D, 0x002533, 0x000000, 0xFFFFFF, + 0x002535, 0x00253B, 0x000000, 0xFFFFFF, + 0x00253D, 0x00254F, 0x000000, 0xFFFFFF, + 0x002575, 0x002580, 0x000000, 0xFFFFFF, + 0x002590, 0x002592, 0x000000, 0xFFFFFF, + 0x002596, 0x00259F, 0x000000, 0xFFFFFF, + 0x0025A2, 0x0025B1, 0x000000, 0xFFFFFF, + 0x0025B4, 0x0025BB, 0x000000, 0xFFFFFF, + 0x0025BE, 0x0025C5, 0x000000, 0xFFFFFF, + 0x0025C8, 0x0025CA, 0x000000, 0xFFFFFF, + 0x0025CC, 0x0025CD, 0x000000, 0xFFFFFF, + 0x0025D0, 0x0025E1, 0x000000, 0xFFFFFF, + 0x0025E6, 0x002604, 0x000000, 0xFFFFFF, + 0x002607, 0x00263F, 0x000000, 0xFFFFFF, + 0x002641, 0x002641, 0x000000, 0xFFFFFF, + 0x002643, 0x002FFF, 0x000000, 0xFFFFFF, + 0x003004, 0x003007, 0x000000, 0xFFFFFF, + 0x003013, 0x003013, 0x000000, 0xFFFFFF, + 0x003016, 0x00301C, 0x000000, 0xFFFFFF, + 0x00301F, 0x003020, 0x000000, 0xFFFFFF, + 0x00302A, 0x003104, 0x000000, 0xFFFFFF, + 0x00312A, 0x0032A2, 0x000000, 0xFFFFFF, + 0x0032A4, 0x00338D, 0x000000, 0xFFFFFF, + 0x003390, 0x00339B, 0x000000, 0xFFFFFF, + 0x00339F, 0x0033A0, 0x000000, 0xFFFFFF, + 0x0033A2, 0x0033C3, 0x000000, 0xFFFFFF, + 0x0033C5, 0x0033CD, 0x000000, 0xFFFFFF, + 0x0033CF, 0x0033D0, 0x000000, 0xFFFFFF, + 0x0033D3, 0x0033D4, 0x000000, 0xFFFFFF, + 0x0033D6, 0x004DFF, 0x000000, 0xFFFFFF, + 0x004E02, 0x004E02, 0x000000, 0xFFFFFF, + 0x004E04, 0x004E06, 0x000000, 0xFFFFFF, + 0x004E12, 0x004E13, 0x000000, 0xFFFFFF, + 0x004E17, 0x004E17, 0x000000, 0xFFFFFF, + 0x004E1A, 0x004E1D, 0x000000, 0xFFFFFF, + 0x004E20, 0x004E25, 0x000000, 0xFFFFFF, + 0x004E27, 0x004E2A, 0x000000, 0xFFFFFF, + 0x004E2C, 0x004E2C, 0x000000, 0xFFFFFF, + 0x004E2F, 0x004E2F, 0x000000, 0xFFFFFF, + 0x004E34, 0x004E37, 0x000000, 0xFFFFFF, + 0x004E3A, 0x004E3A, 0x000000, 0xFFFFFF, + 0x004E3D, 0x004E41, 0x000000, 0xFFFFFF, + 0x004E44, 0x004E44, 0x000000, 0xFFFFFF, + 0x004E46, 0x004E46, 0x000000, 0xFFFFFF, + 0x004E49, 0x004E4A, 0x000000, 0xFFFFFF, + 0x004E4C, 0x004E4C, 0x000000, 0xFFFFFF, + 0x004E50, 0x004E51, 0x000000, 0xFFFFFF, + 0x004E54, 0x004E55, 0x000000, 0xFFFFFF, + 0x004E57, 0x004E57, 0x000000, 0xFFFFFF, + 0x004E5A, 0x004E5B, 0x000000, 0xFFFFFF, + 0x004E60, 0x004E68, 0x000000, 0xFFFFFF, + 0x004E6A, 0x004E72, 0x000000, 0xFFFFFF, + 0x004E74, 0x004E7D, 0x000000, 0xFFFFFF, + 0x004E80, 0x004E81, 0x000000, 0xFFFFFF, + 0x004E85, 0x004E85, 0x000000, 0xFFFFFF, + 0x004E87, 0x004E87, 0x000000, 0xFFFFFF, + 0x004E89, 0x004E8A, 0x000000, 0xFFFFFF, + 0x004E8F, 0x004E90, 0x000000, 0xFFFFFF, + 0x004E96, 0x004E98, 0x000000, 0xFFFFFF, + 0x004E9A, 0x004E9A, 0x000000, 0xFFFFFF, + 0x004E9C, 0x004E9D, 0x000000, 0xFFFFFF, + 0x004EA0, 0x004EA0, 0x000000, 0xFFFFFF, + 0x004EA3, 0x004EA3, 0x000000, 0xFFFFFF, + 0x004EA7, 0x004EA7, 0x000000, 0xFFFFFF, + 0x004EA9, 0x004EAA, 0x000000, 0xFFFFFF, + 0x004EAF, 0x004EB2, 0x000000, 0xFFFFFF, + 0x004EB4, 0x004EB5, 0x000000, 0xFFFFFF, + 0x004EB7, 0x004EB8, 0x000000, 0xFFFFFF, + 0x004EBB, 0x004EBF, 0x000000, 0xFFFFFF, + 0x004EC5, 0x004EC5, 0x000000, 0xFFFFFF, + 0x004ECC, 0x004ECC, 0x000000, 0xFFFFFF, + 0x004ECE, 0x004ED3, 0x000000, 0xFFFFFF, + 0x004EDB, 0x004EDB, 0x000000, 0xFFFFFF, + 0x004EE0, 0x004EE0, 0x000000, 0xFFFFFF, + 0x004EE2, 0x004EE2, 0x000000, 0xFFFFFF, + 0x004EE6, 0x004EE7, 0x000000, 0xFFFFFF, + 0x004EEA, 0x004EEF, 0x000000, 0xFFFFFF, + 0x004EF8, 0x004EFA, 0x000000, 0xFFFFFF, + 0x004EFC, 0x004EFC, 0x000000, 0xFFFFFF, + 0x004EFE, 0x004EFE, 0x000000, 0xFFFFFF, + 0x004F03, 0x004F03, 0x000000, 0xFFFFFF, + 0x004F06, 0x004F07, 0x000000, 0xFFFFFF, + 0x004F0C, 0x004F0C, 0x000000, 0xFFFFFF, + 0x004F16, 0x004F17, 0x000000, 0xFFFFFF, + 0x004F1A, 0x004F1C, 0x000000, 0xFFFFFF, + 0x004F1E, 0x004F21, 0x000000, 0xFFFFFF, + 0x004F23, 0x004F2B, 0x000000, 0xFFFFFF, + 0x004F2E, 0x004F2E, 0x000000, 0xFFFFFF, + 0x004F31, 0x004F32, 0x000000, 0xFFFFFF, + 0x004F35, 0x004F35, 0x000000, 0xFFFFFF, + 0x004F37, 0x004F37, 0x000000, 0xFFFFFF, + 0x004F39, 0x004F39, 0x000000, 0xFFFFFF, + 0x004F40, 0x004F40, 0x000000, 0xFFFFFF, + 0x004F42, 0x004F42, 0x000000, 0xFFFFFF, + 0x004F44, 0x004F45, 0x000000, 0xFFFFFF, + 0x004F4A, 0x004F4B, 0x000000, 0xFFFFFF, + 0x004F65, 0x004F66, 0x000000, 0xFFFFFF, + 0x004F68, 0x004F68, 0x000000, 0xFFFFFF, + 0x004F6D, 0x004F6D, 0x000000, 0xFFFFFF, + 0x004F71, 0x004F72, 0x000000, 0xFFFFFF, + 0x004F8A, 0x004F8A, 0x000000, 0xFFFFFF, + 0x004F8C, 0x004F8C, 0x000000, 0xFFFFFF, + 0x004F8E, 0x004F8E, 0x000000, 0xFFFFFF, + 0x004F93, 0x004F93, 0x000000, 0xFFFFFF, + 0x004F99, 0x004F99, 0x000000, 0xFFFFFF, + 0x004F9F, 0x004FAD, 0x000000, 0xFFFFFF, + 0x004FB0, 0x004FB1, 0x000000, 0xFFFFFF, + 0x004FB4, 0x004FB4, 0x000000, 0xFFFFFF, + 0x004FB8, 0x004FB8, 0x000000, 0xFFFFFF, + 0x004FBC, 0x004FBE, 0x000000, 0xFFFFFF, + 0x004FC6, 0x004FC6, 0x000000, 0xFFFFFF, + 0x004FC8, 0x004FC8, 0x000000, 0xFFFFFF, + 0x004FCC, 0x004FCC, 0x000000, 0xFFFFFF, + 0x004FD2, 0x004FD2, 0x000000, 0xFFFFFF, + 0x004FD5, 0x004FD5, 0x000000, 0xFFFFFF, + 0x004FE2, 0x004FEB, 0x000000, 0xFFFFFF, + 0x004FED, 0x004FED, 0x000000, 0xFFFFFF, + 0x004FF0, 0x004FF0, 0x000000, 0xFFFFFF, + 0x004FF2, 0x004FF2, 0x000000, 0xFFFFFF, + 0x004FF9, 0x004FF9, 0x000000, 0xFFFFFF, + 0x004FFB, 0x004FFD, 0x000000, 0xFFFFFF, + 0x004FFF, 0x004FFF, 0x000000, 0xFFFFFF, + 0x005001, 0x005004, 0x000000, 0xFFFFFF, + 0x005008, 0x005008, 0x000000, 0xFFFFFF, + 0x00500A, 0x00500A, 0x000000, 0xFFFFFF, + 0x005010, 0x005010, 0x000000, 0xFFFFFF, + 0x00501D, 0x00501D, 0x000000, 0xFFFFFF, + 0x005024, 0x005024, 0x000000, 0xFFFFFF, + 0x00502E, 0x00502E, 0x000000, 0xFFFFFF, + 0x005032, 0x005032, 0x000000, 0xFFFFFF, + 0x005034, 0x005034, 0x000000, 0xFFFFFF, + 0x005036, 0x005036, 0x000000, 0xFFFFFF, + 0x005038, 0x00503B, 0x000000, 0xFFFFFF, + 0x00503D, 0x00503F, 0x000000, 0xFFFFFF, + 0x005042, 0x005042, 0x000000, 0xFFFFFF, + 0x005044, 0x005044, 0x000000, 0xFFFFFF, + 0x005050, 0x005050, 0x000000, 0xFFFFFF, + 0x005052, 0x005052, 0x000000, 0xFFFFFF, + 0x005054, 0x005054, 0x000000, 0xFFFFFF, + 0x005056, 0x005056, 0x000000, 0xFFFFFF, + 0x005058, 0x005059, 0x000000, 0xFFFFFF, + 0x005066, 0x005067, 0x000000, 0xFFFFFF, + 0x00506C, 0x00506C, 0x000000, 0xFFFFFF, + 0x005071, 0x005071, 0x000000, 0xFFFFFF, + 0x005078, 0x005079, 0x000000, 0xFFFFFF, + 0x00507B, 0x00507C, 0x000000, 0xFFFFFF, + 0x00507E, 0x00507F, 0x000000, 0xFFFFFF, + 0x005081, 0x005081, 0x000000, 0xFFFFFF, + 0x005084, 0x005084, 0x000000, 0xFFFFFF, + 0x005086, 0x005086, 0x000000, 0xFFFFFF, + 0x005088, 0x00508A, 0x000000, 0xFFFFFF, + 0x00508F, 0x005090, 0x000000, 0xFFFFFF, + 0x005093, 0x005093, 0x000000, 0xFFFFFF, + 0x005097, 0x005097, 0x000000, 0xFFFFFF, + 0x00509F, 0x0050A1, 0x000000, 0xFFFFFF, + 0x0050A4, 0x0050AB, 0x000000, 0xFFFFFF, + 0x0050B9, 0x0050B9, 0x000000, 0xFFFFFF, + 0x0050BC, 0x0050BC, 0x000000, 0xFFFFFF, + 0x0050C0, 0x0050C0, 0x000000, 0xFFFFFF, + 0x0050C3, 0x0050C3, 0x000000, 0xFFFFFF, + 0x0050CC, 0x0050CD, 0x000000, 0xFFFFFF, + 0x0050D0, 0x0050D0, 0x000000, 0xFFFFFF, + 0x0050D2, 0x0050D2, 0x000000, 0xFFFFFF, + 0x0050D8, 0x0050D9, 0x000000, 0xFFFFFF, + 0x0050DC, 0x0050DC, 0x000000, 0xFFFFFF, + 0x0050DE, 0x0050DF, 0x000000, 0xFFFFFF, + 0x0050E1, 0x0050E2, 0x000000, 0xFFFFFF, + 0x0050EB, 0x0050EB, 0x000000, 0xFFFFFF, + 0x0050F2, 0x0050F2, 0x000000, 0xFFFFFF, + 0x0050F4, 0x0050F4, 0x000000, 0xFFFFFF, + 0x0050F7, 0x0050F7, 0x000000, 0xFFFFFF, + 0x0050FA, 0x0050FA, 0x000000, 0xFFFFFF, + 0x0050FC, 0x0050FC, 0x000000, 0xFFFFFF, + 0x005101, 0x005101, 0x000000, 0xFFFFFF, + 0x00510D, 0x00510F, 0x000000, 0xFFFFFF, + 0x005116, 0x005116, 0x000000, 0xFFFFFF, + 0x005119, 0x005119, 0x000000, 0xFFFFFF, + 0x00511B, 0x00511B, 0x000000, 0xFFFFFF, + 0x00511D, 0x00511E, 0x000000, 0xFFFFFF, + 0x005123, 0x005123, 0x000000, 0xFFFFFF, + 0x005127, 0x005128, 0x000000, 0xFFFFFF, + 0x00512B, 0x00512C, 0x000000, 0xFFFFFF, + 0x00512F, 0x00512F, 0x000000, 0xFFFFFF, + 0x005136, 0x005136, 0x000000, 0xFFFFFF, + 0x00513E, 0x00513E, 0x000000, 0xFFFFFF, + 0x005142, 0x005142, 0x000000, 0xFFFFFF, + 0x00514A, 0x00514A, 0x000000, 0xFFFFFF, + 0x00514E, 0x005151, 0x000000, 0xFFFFFF, + 0x005153, 0x005153, 0x000000, 0xFFFFFF, + 0x005156, 0x005156, 0x000000, 0xFFFFFF, + 0x005158, 0x005158, 0x000000, 0xFFFFFF, + 0x005160, 0x005160, 0x000000, 0xFFFFFF, + 0x005164, 0x005164, 0x000000, 0xFFFFFF, + 0x005166, 0x005166, 0x000000, 0xFFFFFF, + 0x00516A, 0x00516A, 0x000000, 0xFFFFFF, + 0x00516F, 0x005170, 0x000000, 0xFFFFFF, + 0x005172, 0x005174, 0x000000, 0xFFFFFF, + 0x005179, 0x00517B, 0x000000, 0xFFFFFF, + 0x00517D, 0x00517F, 0x000000, 0xFFFFFF, + 0x005181, 0x005186, 0x000000, 0xFFFFFF, + 0x005188, 0x005188, 0x000000, 0xFFFFFF, + 0x00518B, 0x00518C, 0x000000, 0xFFFFFF, + 0x00518E, 0x00518E, 0x000000, 0xFFFFFF, + 0x005190, 0x005190, 0x000000, 0xFFFFFF, + 0x005196, 0x005196, 0x000000, 0xFFFFFF, + 0x005199, 0x00519D, 0x000000, 0xFFFFFF, + 0x00519F, 0x00519F, 0x000000, 0xFFFFFF, + 0x0051A1, 0x0051A1, 0x000000, 0xFFFFFF, + 0x0051A3, 0x0051A3, 0x000000, 0xFFFFFF, + 0x0051A6, 0x0051A9, 0x000000, 0xFFFFFF, + 0x0051AB, 0x0051AB, 0x000000, 0xFFFFFF, + 0x0051AD, 0x0051AF, 0x000000, 0xFFFFFF, + 0x0051B2, 0x0051B5, 0x000000, 0xFFFFFF, + 0x0051B8, 0x0051B8, 0x000000, 0xFFFFFF, + 0x0051BA, 0x0051BB, 0x000000, 0xFFFFFF, + 0x0051BF, 0x0051C3, 0x000000, 0xFFFFFF, + 0x0051C7, 0x0051C7, 0x000000, 0xFFFFFF, + 0x0051C9, 0x0051C9, 0x000000, 0xFFFFFF, + 0x0051CF, 0x0051CF, 0x000000, 0xFFFFFF, + 0x0051D1, 0x0051D3, 0x000000, 0xFFFFFF, + 0x0051D5, 0x0051D6, 0x000000, 0xFFFFFF, + 0x0051D9, 0x0051DB, 0x000000, 0xFFFFFF, + 0x0051DF, 0x0051DF, 0x000000, 0xFFFFFF, + 0x0051E2, 0x0051EF, 0x000000, 0xFFFFFF, + 0x0051F2, 0x0051F2, 0x000000, 0xFFFFFF, + 0x0051F4, 0x0051F4, 0x000000, 0xFFFFFF, + 0x0051F7, 0x0051F7, 0x000000, 0xFFFFFF, + 0x0051FB, 0x0051FC, 0x000000, 0xFFFFFF, + 0x0051FE, 0x0051FF, 0x000000, 0xFFFFFF, + 0x005202, 0x005202, 0x000000, 0xFFFFFF, + 0x005204, 0x005205, 0x000000, 0xFFFFFF, + 0x00520B, 0x00520B, 0x000000, 0xFFFFFF, + 0x00520D, 0x00520D, 0x000000, 0xFFFFFF, + 0x00520F, 0x00520F, 0x000000, 0xFFFFFF, + 0x005214, 0x005215, 0x000000, 0xFFFFFF, + 0x005218, 0x00521B, 0x000000, 0xFFFFFF, + 0x00521F, 0x005220, 0x000000, 0xFFFFFF, + 0x005222, 0x005223, 0x000000, 0xFFFFFF, + 0x005226, 0x005227, 0x000000, 0xFFFFFF, + 0x00522B, 0x00522D, 0x000000, 0xFFFFFF, + 0x00522F, 0x00522F, 0x000000, 0xFFFFFF, + 0x005234, 0x005234, 0x000000, 0xFFFFFF, + 0x005239, 0x005239, 0x000000, 0xFFFFFF, + 0x00523C, 0x005240, 0x000000, 0xFFFFFF, + 0x005242, 0x005242, 0x000000, 0xFFFFFF, + 0x005245, 0x005245, 0x000000, 0xFFFFFF, + 0x005248, 0x005248, 0x000000, 0xFFFFFF, + 0x00524F, 0x005251, 0x000000, 0xFFFFFF, + 0x005253, 0x005253, 0x000000, 0xFFFFFF, + 0x005257, 0x005259, 0x000000, 0xFFFFFF, + 0x005260, 0x005260, 0x000000, 0xFFFFFF, + 0x005263, 0x005268, 0x000000, 0xFFFFFF, + 0x005270, 0x005271, 0x000000, 0xFFFFFF, + 0x005273, 0x005273, 0x000000, 0xFFFFFF, + 0x005276, 0x005276, 0x000000, 0xFFFFFF, + 0x005279, 0x005279, 0x000000, 0xFFFFFF, + 0x00527E, 0x00527E, 0x000000, 0xFFFFFF, + 0x005285, 0x005286, 0x000000, 0xFFFFFF, + 0x00528E, 0x005290, 0x000000, 0xFFFFFF, + 0x005292, 0x005292, 0x000000, 0xFFFFFF, + 0x005294, 0x005295, 0x000000, 0xFFFFFF, + 0x00529A, 0x00529A, 0x000000, 0xFFFFFF, + 0x00529C, 0x00529E, 0x000000, 0xFFFFFF, + 0x0052A1, 0x0052A2, 0x000000, 0xFFFFFF, + 0x0052A4, 0x0052A5, 0x000000, 0xFFFFFF, + 0x0052A7, 0x0052A8, 0x000000, 0xFFFFFF, + 0x0052AF, 0x0052BA, 0x000000, 0xFFFFFF, + 0x0052BD, 0x0052BD, 0x000000, 0xFFFFFF, + 0x0052BF, 0x0052BF, 0x000000, 0xFFFFFF, + 0x0052C4, 0x0052C6, 0x000000, 0xFFFFFF, + 0x0052C8, 0x0052C8, 0x000000, 0xFFFFFF, + 0x0052CA, 0x0052CC, 0x000000, 0xFFFFFF, + 0x0052CE, 0x0052D1, 0x000000, 0xFFFFFF, + 0x0052D4, 0x0052D4, 0x000000, 0xFFFFFF, + 0x0052DA, 0x0052DA, 0x000000, 0xFFFFFF, + 0x0052DC, 0x0052DC, 0x000000, 0xFFFFFF, + 0x0052E0, 0x0052E1, 0x000000, 0xFFFFFF, + 0x0052E5, 0x0052E5, 0x000000, 0xFFFFFF, + 0x0052E7, 0x0052E8, 0x000000, 0xFFFFFF, + 0x0052EA, 0x0052EA, 0x000000, 0xFFFFFF, + 0x0052EC, 0x0052EE, 0x000000, 0xFFFFFF, + 0x0052F2, 0x0052F2, 0x000000, 0xFFFFFF, + 0x0052F6, 0x0052F6, 0x000000, 0xFFFFFF, + 0x0052F9, 0x0052F9, 0x000000, 0xFFFFFF, + 0x0052FD, 0x0052FD, 0x000000, 0xFFFFFF, + 0x005300, 0x005304, 0x000000, 0xFFFFFF, + 0x005307, 0x005307, 0x000000, 0xFFFFFF, + 0x00530C, 0x00530C, 0x000000, 0xFFFFFF, + 0x005313, 0x005314, 0x000000, 0xFFFFFF, + 0x005318, 0x005318, 0x000000, 0xFFFFFF, + 0x00531B, 0x00531B, 0x000000, 0xFFFFFF, + 0x00531E, 0x00531E, 0x000000, 0xFFFFFF, + 0x005324, 0x005329, 0x000000, 0xFFFFFF, + 0x00532B, 0x00532C, 0x000000, 0xFFFFFF, + 0x00532E, 0x00532E, 0x000000, 0xFFFFFF, + 0x005332, 0x005333, 0x000000, 0xFFFFFF, + 0x005335, 0x005336, 0x000000, 0xFFFFFF, + 0x005338, 0x005338, 0x000000, 0xFFFFFF, + 0x00533A, 0x00533B, 0x000000, 0xFFFFFF, + 0x005342, 0x005342, 0x000000, 0xFFFFFF, + 0x005346, 0x005346, 0x000000, 0xFFFFFF, + 0x00534B, 0x00534B, 0x000000, 0xFFFFFF, + 0x00534E, 0x005350, 0x000000, 0xFFFFFF, + 0x005355, 0x005356, 0x000000, 0xFFFFFF, + 0x005358, 0x005359, 0x000000, 0xFFFFFF, + 0x00535B, 0x00535B, 0x000000, 0xFFFFFF, + 0x00535D, 0x00535D, 0x000000, 0xFFFFFF, + 0x00535F, 0x00535F, 0x000000, 0xFFFFFF, + 0x005362, 0x005362, 0x000000, 0xFFFFFF, + 0x005364, 0x005365, 0x000000, 0xFFFFFF, + 0x005367, 0x00536B, 0x000000, 0xFFFFFF, + 0x00536D, 0x00536D, 0x000000, 0xFFFFFF, + 0x005374, 0x005374, 0x000000, 0xFFFFFF, + 0x005376, 0x005376, 0x000000, 0xFFFFFF, + 0x00537A, 0x00537A, 0x000000, 0xFFFFFF, + 0x00537D, 0x00537E, 0x000000, 0xFFFFFF, + 0x005380, 0x005381, 0x000000, 0xFFFFFF, + 0x005383, 0x005383, 0x000000, 0xFFFFFF, + 0x005385, 0x005389, 0x000000, 0xFFFFFF, + 0x00538B, 0x00538D, 0x000000, 0xFFFFFF, + 0x005390, 0x005391, 0x000000, 0xFFFFFF, + 0x005393, 0x005393, 0x000000, 0xFFFFFF, + 0x005395, 0x005395, 0x000000, 0xFFFFFF, + 0x00539B, 0x00539B, 0x000000, 0xFFFFFF, + 0x0053A0, 0x0053A3, 0x000000, 0xFFFFFF, + 0x0053A6, 0x0053A6, 0x000000, 0xFFFFFF, + 0x0053A8, 0x0053AB, 0x000000, 0xFFFFFF, + 0x0053AE, 0x0053B1, 0x000000, 0xFFFFFF, + 0x0053B3, 0x0053B3, 0x000000, 0xFFFFFF, + 0x0053B5, 0x0053B8, 0x000000, 0xFFFFFF, + 0x0053BA, 0x0053BA, 0x000000, 0xFFFFFF, + 0x0053BC, 0x0053C2, 0x000000, 0xFFFFFF, + 0x0053C4, 0x0053C7, 0x000000, 0xFFFFFF, + 0x0053CC, 0x0053CC, 0x000000, 0xFFFFFF, + 0x0053CE, 0x0053D3, 0x000000, 0xFFFFFF, + 0x0053D5, 0x0053D5, 0x000000, 0xFFFFFF, + 0x0053D8, 0x0053DA, 0x000000, 0xFFFFFF, + 0x0053DC, 0x0053DE, 0x000000, 0xFFFFFF, + 0x0053E0, 0x0053E0, 0x000000, 0xFFFFFF, + 0x0053E7, 0x0053E7, 0x000000, 0xFFFFFF, + 0x0053F4, 0x0053F4, 0x000000, 0xFFFFFF, + 0x0053F6, 0x0053F7, 0x000000, 0xFFFFFF, + 0x0053F9, 0x0053FA, 0x000000, 0xFFFFFF, + 0x0053FD, 0x005400, 0x000000, 0xFFFFFF, + 0x005402, 0x005402, 0x000000, 0xFFFFFF, + 0x005405, 0x005405, 0x000000, 0xFFFFFF, + 0x005413, 0x005417, 0x000000, 0xFFFFFF, + 0x00541A, 0x00541A, 0x000000, 0xFFFFFF, + 0x005421, 0x005423, 0x000000, 0xFFFFFF, + 0x00542F, 0x00542F, 0x000000, 0xFFFFFF, + 0x005432, 0x005432, 0x000000, 0xFFFFFF, + 0x005434, 0x005434, 0x000000, 0xFFFFFF, + 0x00543A, 0x00543A, 0x000000, 0xFFFFFF, + 0x00543F, 0x00543F, 0x000000, 0xFFFFFF, + 0x005444, 0x005444, 0x000000, 0xFFFFFF, + 0x005449, 0x005449, 0x000000, 0xFFFFFF, + 0x00544B, 0x00544D, 0x000000, 0xFFFFFF, + 0x005450, 0x005453, 0x000000, 0xFFFFFF, + 0x005455, 0x00545F, 0x000000, 0xFFFFFF, + 0x005469, 0x00546A, 0x000000, 0xFFFFFF, + 0x00546D, 0x00546E, 0x000000, 0xFFFFFF, + 0x005479, 0x005479, 0x000000, 0xFFFFFF, + 0x005483, 0x005483, 0x000000, 0xFFFFFF, + 0x005485, 0x005485, 0x000000, 0xFFFFFF, + 0x005489, 0x00548A, 0x000000, 0xFFFFFF, + 0x00548F, 0x00548F, 0x000000, 0xFFFFFF, + 0x005493, 0x005494, 0x000000, 0xFFFFFF, + 0x005497, 0x005497, 0x000000, 0xFFFFFF, + 0x005499, 0x005499, 0x000000, 0xFFFFFF, + 0x00549B, 0x00549F, 0x000000, 0xFFFFFF, + 0x0054A3, 0x0054A4, 0x000000, 0xFFFFFF, + 0x0054B2, 0x0054B2, 0x000000, 0xFFFFFF, + 0x0054B4, 0x0054B5, 0x000000, 0xFFFFFF, + 0x0054B9, 0x0054B9, 0x000000, 0xFFFFFF, + 0x0054CA, 0x0054CD, 0x000000, 0xFFFFFF, + 0x0054D0, 0x0054D5, 0x000000, 0xFFFFFF, + 0x0054D7, 0x0054DD, 0x000000, 0xFFFFFF, + 0x0054DF, 0x0054DF, 0x000000, 0xFFFFFF, + 0x0054E3, 0x0054E3, 0x000000, 0xFFFFFF, + 0x0054EC, 0x0054EC, 0x000000, 0xFFFFFF, + 0x0054EF, 0x0054F0, 0x000000, 0xFFFFFF, + 0x0054F4, 0x0054F6, 0x000000, 0xFFFFFF, + 0x0054F9, 0x0054F9, 0x000000, 0xFFFFFF, + 0x0054FE, 0x0054FE, 0x000000, 0xFFFFFF, + 0x005500, 0x005500, 0x000000, 0xFFFFFF, + 0x005502, 0x005502, 0x000000, 0xFFFFFF, + 0x00550D, 0x00550D, 0x000000, 0xFFFFFF, + 0x005513, 0x005513, 0x000000, 0xFFFFFF, + 0x005515, 0x005516, 0x000000, 0xFFFFFF, + 0x005518, 0x005519, 0x000000, 0xFFFFFF, + 0x00551B, 0x005525, 0x000000, 0xFFFFFF, + 0x005528, 0x005529, 0x000000, 0xFFFFFF, + 0x00552B, 0x00552B, 0x000000, 0xFFFFFF, + 0x00553A, 0x00553A, 0x000000, 0xFFFFFF, + 0x00553D, 0x00553D, 0x000000, 0xFFFFFF, + 0x00553F, 0x00553F, 0x000000, 0xFFFFFF, + 0x005542, 0x005542, 0x000000, 0xFFFFFF, + 0x005547, 0x005547, 0x000000, 0xFFFFFF, + 0x005549, 0x005549, 0x000000, 0xFFFFFF, + 0x00554C, 0x00554C, 0x000000, 0xFFFFFF, + 0x005553, 0x005554, 0x000000, 0xFFFFFF, + 0x005558, 0x00555B, 0x000000, 0xFFFFFF, + 0x00555D, 0x00555D, 0x000000, 0xFFFFFF, + 0x005560, 0x005560, 0x000000, 0xFFFFFF, + 0x005567, 0x005569, 0x000000, 0xFFFFFF, + 0x00556B, 0x005574, 0x000000, 0xFFFFFF, + 0x005578, 0x00557A, 0x000000, 0xFFFFFF, + 0x005585, 0x005586, 0x000000, 0xFFFFFF, + 0x005590, 0x005590, 0x000000, 0xFFFFFF, + 0x005596, 0x005597, 0x000000, 0xFFFFFF, + 0x00559B, 0x00559B, 0x000000, 0xFFFFFF, + 0x00559E, 0x00559E, 0x000000, 0xFFFFFF, + 0x0055A0, 0x0055A0, 0x000000, 0xFFFFFF, + 0x0055A9, 0x0055A9, 0x000000, 0xFFFFFF, + 0x0055AF, 0x0055B0, 0x000000, 0xFFFFFF, + 0x0055B4, 0x0055B4, 0x000000, 0xFFFFFF, + 0x0055B6, 0x0055BA, 0x000000, 0xFFFFFF, + 0x0055BC, 0x0055BE, 0x000000, 0xFFFFFF, + 0x0055C1, 0x0055C1, 0x000000, 0xFFFFFF, + 0x0055D7, 0x0055D8, 0x000000, 0xFFFFFF, + 0x0055DE, 0x0055DE, 0x000000, 0xFFFFFF, + 0x0055E0, 0x0055E0, 0x000000, 0xFFFFFF, + 0x0055EA, 0x0055EE, 0x000000, 0xFFFFFF, + 0x0055F0, 0x0055F1, 0x000000, 0xFFFFFF, + 0x0055F3, 0x0055F5, 0x000000, 0xFFFFFF, + 0x0055F8, 0x0055F8, 0x000000, 0xFFFFFF, + 0x0055FB, 0x0055FB, 0x000000, 0xFFFFFF, + 0x005603, 0x005603, 0x000000, 0xFFFFFF, + 0x005605, 0x005605, 0x000000, 0xFFFFFF, + 0x005607, 0x005607, 0x000000, 0xFFFFFF, + 0x00560A, 0x00560B, 0x000000, 0xFFFFFF, + 0x005611, 0x005611, 0x000000, 0xFFFFFF, + 0x005618, 0x00561A, 0x000000, 0xFFFFFF, + 0x00561E, 0x00561E, 0x000000, 0xFFFFFF, + 0x005620, 0x005626, 0x000000, 0xFFFFFF, + 0x005628, 0x005628, 0x000000, 0xFFFFFF, + 0x00562B, 0x00562B, 0x000000, 0xFFFFFF, + 0x00562D, 0x00562D, 0x000000, 0xFFFFFF, + 0x005631, 0x005631, 0x000000, 0xFFFFFF, + 0x005637, 0x005637, 0x000000, 0xFFFFFF, + 0x00563C, 0x00563C, 0x000000, 0xFFFFFF, + 0x005643, 0x005644, 0x000000, 0xFFFFFF, + 0x005647, 0x005647, 0x000000, 0xFFFFFF, + 0x00564B, 0x00564B, 0x000000, 0xFFFFFF, + 0x00564D, 0x00564D, 0x000000, 0xFFFFFF, + 0x00564F, 0x005652, 0x000000, 0xFFFFFF, + 0x005654, 0x005656, 0x000000, 0xFFFFFF, + 0x00565B, 0x00565D, 0x000000, 0xFFFFFF, + 0x00565F, 0x00565F, 0x000000, 0xFFFFFF, + 0x005661, 0x005661, 0x000000, 0xFFFFFF, + 0x005667, 0x005667, 0x000000, 0xFFFFFF, + 0x005675, 0x005675, 0x000000, 0xFFFFFF, + 0x00567A, 0x00567D, 0x000000, 0xFFFFFF, + 0x005688, 0x00568B, 0x000000, 0xFFFFFF, + 0x005691, 0x005692, 0x000000, 0xFFFFFF, + 0x005694, 0x005694, 0x000000, 0xFFFFFF, + 0x005696, 0x005696, 0x000000, 0xFFFFFF, + 0x00569B, 0x00569B, 0x000000, 0xFFFFFF, + 0x00569E, 0x0056A4, 0x000000, 0xFFFFFF, + 0x0056A9, 0x0056A9, 0x000000, 0xFFFFFF, + 0x0056AF, 0x0056B1, 0x000000, 0xFFFFFF, + 0x0056B8, 0x0056BB, 0x000000, 0xFFFFFF, + 0x0056BF, 0x0056BF, 0x000000, 0xFFFFFF, + 0x0056C4, 0x0056C4, 0x000000, 0xFFFFFF, + 0x0056C7, 0x0056C7, 0x000000, 0xFFFFFF, + 0x0056CE, 0x0056D0, 0x000000, 0xFFFFFF, + 0x0056D2, 0x0056D2, 0x000000, 0xFFFFFF, + 0x0056D5, 0x0056D6, 0x000000, 0xFFFFFF, + 0x0056D8, 0x0056D9, 0x000000, 0xFFFFFF, + 0x0056DC, 0x0056DC, 0x000000, 0xFFFFFF, + 0x0056E2, 0x0056E3, 0x000000, 0xFFFFFF, + 0x0056E6, 0x0056E6, 0x000000, 0xFFFFFF, + 0x0056E8, 0x0056E9, 0x000000, 0xFFFFFF, + 0x0056EC, 0x0056ED, 0x000000, 0xFFFFFF, + 0x0056EF, 0x0056EF, 0x000000, 0xFFFFFF, + 0x0056F1, 0x0056F6, 0x000000, 0xFFFFFF, + 0x0056F8, 0x0056F8, 0x000000, 0xFFFFFF, + 0x0056FB, 0x0056FE, 0x000000, 0xFFFFFF, + 0x005700, 0x005700, 0x000000, 0xFFFFFF, + 0x005705, 0x005706, 0x000000, 0xFFFFFF, + 0x00570E, 0x005711, 0x000000, 0xFFFFFF, + 0x005715, 0x005715, 0x000000, 0xFFFFFF, + 0x005717, 0x005717, 0x000000, 0xFFFFFF, + 0x005719, 0x005719, 0x000000, 0xFFFFFF, + 0x00571D, 0x00571D, 0x000000, 0xFFFFFF, + 0x005721, 0x005721, 0x000000, 0xFFFFFF, + 0x005724, 0x005727, 0x000000, 0xFFFFFF, + 0x00572B, 0x00572B, 0x000000, 0xFFFFFF, + 0x005731, 0x005732, 0x000000, 0xFFFFFF, + 0x005735, 0x00573A, 0x000000, 0xFFFFFF, + 0x00573C, 0x00573D, 0x000000, 0xFFFFFF, + 0x00573F, 0x00573F, 0x000000, 0xFFFFFF, + 0x005742, 0x005744, 0x000000, 0xFFFFFF, + 0x005746, 0x005746, 0x000000, 0xFFFFFF, + 0x005748, 0x005748, 0x000000, 0xFFFFFF, + 0x005753, 0x005760, 0x000000, 0xFFFFFF, + 0x005763, 0x005763, 0x000000, 0xFFFFFF, + 0x005765, 0x005765, 0x000000, 0xFFFFFF, + 0x005767, 0x005767, 0x000000, 0xFFFFFF, + 0x00576C, 0x00576C, 0x000000, 0xFFFFFF, + 0x00576E, 0x00576E, 0x000000, 0xFFFFFF, + 0x005778, 0x00577A, 0x000000, 0xFFFFFF, + 0x00577E, 0x00577F, 0x000000, 0xFFFFFF, + 0x005781, 0x005781, 0x000000, 0xFFFFFF, + 0x005784, 0x00578A, 0x000000, 0xFFFFFF, + 0x00578D, 0x00578E, 0x000000, 0xFFFFFF, + 0x005790, 0x005792, 0x000000, 0xFFFFFF, + 0x005796, 0x005796, 0x000000, 0xFFFFFF, + 0x00579C, 0x00579C, 0x000000, 0xFFFFFF, + 0x0057A1, 0x0057A1, 0x000000, 0xFFFFFF, + 0x0057A6, 0x0057AD, 0x000000, 0xFFFFFF, + 0x0057AF, 0x0057B4, 0x000000, 0xFFFFFF, + 0x0057B7, 0x0057B7, 0x000000, 0xFFFFFF, + 0x0057BB, 0x0057BB, 0x000000, 0xFFFFFF, + 0x0057BE, 0x0057BE, 0x000000, 0xFFFFFF, + 0x0057C0, 0x0057C0, 0x000000, 0xFFFFFF, + 0x0057C4, 0x0057C5, 0x000000, 0xFFFFFF, + 0x0057C8, 0x0057CA, 0x000000, 0xFFFFFF, + 0x0057CD, 0x0057CD, 0x000000, 0xFFFFFF, + 0x0057D1, 0x0057D1, 0x000000, 0xFFFFFF, + 0x0057D3, 0x0057D3, 0x000000, 0xFFFFFF, + 0x0057D6, 0x0057DB, 0x000000, 0xFFFFFF, + 0x0057DD, 0x0057DE, 0x000000, 0xFFFFFF, + 0x0057E6, 0x0057E6, 0x000000, 0xFFFFFF, + 0x0057E8, 0x0057E8, 0x000000, 0xFFFFFF, + 0x0057EA, 0x0057EB, 0x000000, 0xFFFFFF, + 0x0057EF, 0x0057EF, 0x000000, 0xFFFFFF, + 0x0057FE, 0x0057FF, 0x000000, 0xFFFFFF, + 0x005803, 0x005803, 0x000000, 0xFFFFFF, + 0x00580F, 0x00580F, 0x000000, 0xFFFFFF, + 0x005811, 0x005813, 0x000000, 0xFFFFFF, + 0x005815, 0x005818, 0x000000, 0xFFFFFF, + 0x00581A, 0x00581A, 0x000000, 0xFFFFFF, + 0x00581F, 0x00581F, 0x000000, 0xFFFFFF, + 0x005822, 0x005822, 0x000000, 0xFFFFFF, + 0x005826, 0x005826, 0x000000, 0xFFFFFF, + 0x00582B, 0x00582B, 0x000000, 0xFFFFFF, + 0x00583A, 0x00583A, 0x000000, 0xFFFFFF, + 0x00583C, 0x00583C, 0x000000, 0xFFFFFF, + 0x00583E, 0x00583E, 0x000000, 0xFFFFFF, + 0x005840, 0x005847, 0x000000, 0xFFFFFF, + 0x005850, 0x005850, 0x000000, 0xFFFFFF, + 0x005856, 0x005856, 0x000000, 0xFFFFFF, + 0x00585C, 0x00585C, 0x000000, 0xFFFFFF, + 0x00585F, 0x005861, 0x000000, 0xFFFFFF, + 0x005866, 0x005867, 0x000000, 0xFFFFFF, + 0x005869, 0x00586A, 0x000000, 0xFFFFFF, + 0x00586C, 0x00586C, 0x000000, 0xFFFFFF, + 0x00586E, 0x00586E, 0x000000, 0xFFFFFF, + 0x005870, 0x005870, 0x000000, 0xFFFFFF, + 0x005872, 0x005873, 0x000000, 0xFFFFFF, + 0x005877, 0x005878, 0x000000, 0xFFFFFF, + 0x005884, 0x005884, 0x000000, 0xFFFFFF, + 0x00588C, 0x00588D, 0x000000, 0xFFFFFF, + 0x005892, 0x005892, 0x000000, 0xFFFFFF, + 0x005895, 0x005897, 0x000000, 0xFFFFFF, + 0x005899, 0x00589B, 0x000000, 0xFFFFFF, + 0x0058A2, 0x0058A2, 0x000000, 0xFFFFFF, + 0x0058A4, 0x0058A4, 0x000000, 0xFFFFFF, + 0x0058A7, 0x0058A7, 0x000000, 0xFFFFFF, + 0x0058AA, 0x0058AA, 0x000000, 0xFFFFFF, + 0x0058AD, 0x0058AD, 0x000000, 0xFFFFFF, + 0x0058B0, 0x0058B0, 0x000000, 0xFFFFFF, + 0x0058B2, 0x0058B2, 0x000000, 0xFFFFFF, + 0x0058B4, 0x0058B9, 0x000000, 0xFFFFFF, + 0x0058C0, 0x0058C0, 0x000000, 0xFFFFFF, + 0x0058C3, 0x0058C4, 0x000000, 0xFFFFFF, + 0x0058CA, 0x0058CD, 0x000000, 0xFFFFFF, + 0x0058D0, 0x0058D0, 0x000000, 0xFFFFFF, + 0x0058D7, 0x0058D7, 0x000000, 0xFFFFFF, + 0x0058DC, 0x0058DC, 0x000000, 0xFFFFFF, + 0x0058E0, 0x0058E1, 0x000000, 0xFFFFFF, + 0x0058E5, 0x0058E6, 0x000000, 0xFFFFFF, + 0x0058EA, 0x0058EA, 0x000000, 0xFFFFFF, + 0x0058ED, 0x0058EE, 0x000000, 0xFFFFFF, + 0x0058F0, 0x0058F3, 0x000000, 0xFFFFFF, + 0x0058F5, 0x0058F8, 0x000000, 0xFFFFFF, + 0x0058FB, 0x0058FB, 0x000000, 0xFFFFFF, + 0x005900, 0x005902, 0x000000, 0xFFFFFF, + 0x005904, 0x005905, 0x000000, 0xFFFFFF, + 0x005907, 0x00590B, 0x000000, 0xFFFFFF, + 0x005910, 0x005911, 0x000000, 0xFFFFFF, + 0x005913, 0x005913, 0x000000, 0xFFFFFF, + 0x005918, 0x005918, 0x000000, 0xFFFFFF, + 0x00591B, 0x00591B, 0x000000, 0xFFFFFF, + 0x00591D, 0x00591F, 0x000000, 0xFFFFFF, + 0x005921, 0x005921, 0x000000, 0xFFFFFF, + 0x005923, 0x005923, 0x000000, 0xFFFFFF, + 0x005926, 0x005926, 0x000000, 0xFFFFFF, + 0x005928, 0x005928, 0x000000, 0xFFFFFF, + 0x005930, 0x005930, 0x000000, 0xFFFFFF, + 0x005932, 0x005936, 0x000000, 0xFFFFFF, + 0x005939, 0x00593B, 0x000000, 0xFFFFFF, + 0x00593D, 0x00593D, 0x000000, 0xFFFFFF, + 0x00593F, 0x00593F, 0x000000, 0xFFFFFF, + 0x005941, 0x005943, 0x000000, 0xFFFFFF, + 0x005946, 0x005946, 0x000000, 0xFFFFFF, + 0x00594B, 0x00594D, 0x000000, 0xFFFFFF, + 0x005952, 0x005952, 0x000000, 0xFFFFFF, + 0x005956, 0x005956, 0x000000, 0xFFFFFF, + 0x005959, 0x005959, 0x000000, 0xFFFFFF, + 0x00595B, 0x00595B, 0x000000, 0xFFFFFF, + 0x00595D, 0x00595F, 0x000000, 0xFFFFFF, + 0x005963, 0x005966, 0x000000, 0xFFFFFF, + 0x005968, 0x005968, 0x000000, 0xFFFFFF, + 0x00596C, 0x00596C, 0x000000, 0xFFFFFF, + 0x00596F, 0x00596F, 0x000000, 0xFFFFFF, + 0x005975, 0x005975, 0x000000, 0xFFFFFF, + 0x00597A, 0x00597A, 0x000000, 0xFFFFFF, + 0x005986, 0x005989, 0x000000, 0xFFFFFF, + 0x00598B, 0x00598C, 0x000000, 0xFFFFFF, + 0x005991, 0x005991, 0x000000, 0xFFFFFF, + 0x005994, 0x005995, 0x000000, 0xFFFFFF, + 0x00599A, 0x00599C, 0x000000, 0xFFFFFF, + 0x00599F, 0x00599F, 0x000000, 0xFFFFFF, + 0x0059A9, 0x0059AD, 0x000000, 0xFFFFFF, + 0x0059B0, 0x0059B0, 0x000000, 0xFFFFFF, + 0x0059B7, 0x0059B8, 0x000000, 0xFFFFFF, + 0x0059BF, 0x0059BF, 0x000000, 0xFFFFFF, + 0x0059C2, 0x0059C2, 0x000000, 0xFFFFFF, + 0x0059C4, 0x0059C4, 0x000000, 0xFFFFFF, + 0x0059C9, 0x0059C9, 0x000000, 0xFFFFFF, + 0x0059D5, 0x0059D5, 0x000000, 0xFFFFFF, + 0x0059D7, 0x0059D7, 0x000000, 0xFFFFFF, + 0x0059D9, 0x0059D9, 0x000000, 0xFFFFFF, + 0x0059DF, 0x0059DF, 0x000000, 0xFFFFFF, + 0x0059E2, 0x0059E2, 0x000000, 0xFFFFFF, + 0x0059E7, 0x0059E7, 0x000000, 0xFFFFFF, + 0x0059EB, 0x0059EB, 0x000000, 0xFFFFFF, + 0x0059EF, 0x0059F0, 0x000000, 0xFFFFFF, + 0x0059F8, 0x0059F9, 0x000000, 0xFFFFFF, + 0x005A02, 0x005A02, 0x000000, 0xFFFFFF, + 0x005A04, 0x005A08, 0x000000, 0xFFFFFF, + 0x005A0B, 0x005A0B, 0x000000, 0xFFFFFF, + 0x005A0D, 0x005A0E, 0x000000, 0xFFFFFF, + 0x005A10, 0x005A10, 0x000000, 0xFFFFFF, + 0x005A12, 0x005A12, 0x000000, 0xFFFFFF, + 0x005A14, 0x005A14, 0x000000, 0xFFFFFF, + 0x005A1A, 0x005A1A, 0x000000, 0xFFFFFF, + 0x005A1D, 0x005A1D, 0x000000, 0xFFFFFF, + 0x005A21, 0x005A22, 0x000000, 0xFFFFFF, + 0x005A24, 0x005A24, 0x000000, 0xFFFFFF, + 0x005A26, 0x005A28, 0x000000, 0xFFFFFF, + 0x005A2A, 0x005A2C, 0x000000, 0xFFFFFF, + 0x005A2F, 0x005A32, 0x000000, 0xFFFFFF, + 0x005A34, 0x005A34, 0x000000, 0xFFFFFF, + 0x005A3A, 0x005A3B, 0x000000, 0xFFFFFF, + 0x005A3D, 0x005A3D, 0x000000, 0xFFFFFF, + 0x005A3F, 0x005A3F, 0x000000, 0xFFFFFF, + 0x005A45, 0x005A45, 0x000000, 0xFFFFFF, + 0x005A4B, 0x005A4B, 0x000000, 0xFFFFFF, + 0x005A4E, 0x005A4F, 0x000000, 0xFFFFFF, + 0x005A54, 0x005A54, 0x000000, 0xFFFFFF, + 0x005A59, 0x005A59, 0x000000, 0xFFFFFF, + 0x005A61, 0x005A61, 0x000000, 0xFFFFFF, + 0x005A63, 0x005A63, 0x000000, 0xFFFFFF, + 0x005A68, 0x005A68, 0x000000, 0xFFFFFF, + 0x005A6B, 0x005A6B, 0x000000, 0xFFFFFF, + 0x005A6E, 0x005A6F, 0x000000, 0xFFFFFF, + 0x005A71, 0x005A76, 0x000000, 0xFFFFFF, + 0x005A79, 0x005A79, 0x000000, 0xFFFFFF, + 0x005A7E, 0x005A7E, 0x000000, 0xFFFFFF, + 0x005A80, 0x005A82, 0x000000, 0xFFFFFF, + 0x005A85, 0x005A89, 0x000000, 0xFFFFFF, + 0x005A8D, 0x005A8D, 0x000000, 0xFFFFFF, + 0x005A91, 0x005A91, 0x000000, 0xFFFFFF, + 0x005A96, 0x005A96, 0x000000, 0xFFFFFF, + 0x005A98, 0x005A99, 0x000000, 0xFFFFFF, + 0x005AA0, 0x005AA1, 0x000000, 0xFFFFFF, + 0x005AA3, 0x005AA4, 0x000000, 0xFFFFFF, + 0x005AA8, 0x005AA8, 0x000000, 0xFFFFFF, + 0x005AAA, 0x005AAB, 0x000000, 0xFFFFFF, + 0x005AAD, 0x005AAD, 0x000000, 0xFFFFFF, + 0x005AC3, 0x005AC3, 0x000000, 0xFFFFFF, + 0x005AC5, 0x005AC5, 0x000000, 0xFFFFFF, + 0x005ACE, 0x005AD4, 0x000000, 0xFFFFFF, + 0x005AE4, 0x005AE4, 0x000000, 0xFFFFFF, + 0x005AE7, 0x005AE7, 0x000000, 0xFFFFFF, + 0x005AEF, 0x005AF2, 0x000000, 0xFFFFFF, + 0x005AFC, 0x005AFC, 0x000000, 0xFFFFFF, + 0x005AFE, 0x005AFE, 0x000000, 0xFFFFFF, + 0x005B00, 0x005B00, 0x000000, 0xFFFFFF, + 0x005B04, 0x005B04, 0x000000, 0xFFFFFF, + 0x005B06, 0x005B06, 0x000000, 0xFFFFFF, + 0x005B0A, 0x005B0A, 0x000000, 0xFFFFFF, + 0x005B0D, 0x005B0E, 0x000000, 0xFFFFFF, + 0x005B11, 0x005B12, 0x000000, 0xFFFFFF, + 0x005B15, 0x005B15, 0x000000, 0xFFFFFF, + 0x005B18, 0x005B18, 0x000000, 0xFFFFFF, + 0x005B1C, 0x005B1C, 0x000000, 0xFFFFFF, + 0x005B1F, 0x005B1F, 0x000000, 0xFFFFFF, + 0x005B22, 0x005B22, 0x000000, 0xFFFFFF, + 0x005B29, 0x005B29, 0x000000, 0xFFFFFF, + 0x005B2B, 0x005B2B, 0x000000, 0xFFFFFF, + 0x005B31, 0x005B31, 0x000000, 0xFFFFFF, + 0x005B33, 0x005B33, 0x000000, 0xFFFFFF, + 0x005B35, 0x005B37, 0x000000, 0xFFFFFF, + 0x005B39, 0x005B3B, 0x000000, 0xFFFFFF, + 0x005B41, 0x005B42, 0x000000, 0xFFFFFF, + 0x005B44, 0x005B44, 0x000000, 0xFFFFFF, + 0x005B46, 0x005B46, 0x000000, 0xFFFFFF, + 0x005B49, 0x005B4A, 0x000000, 0xFFFFFF, + 0x005B4F, 0x005B4F, 0x000000, 0xFFFFFF, + 0x005B52, 0x005B52, 0x000000, 0xFFFFFF, + 0x005B59, 0x005B59, 0x000000, 0xFFFFFF, + 0x005B5E, 0x005B5E, 0x000000, 0xFFFFFF, + 0x005B60, 0x005B61, 0x000000, 0xFFFFFF, + 0x005B66, 0x005B68, 0x000000, 0xFFFFFF, + 0x005B6A, 0x005B6A, 0x000000, 0xFFFFFF, + 0x005B6D, 0x005B6D, 0x000000, 0xFFFFFF, + 0x005B6F, 0x005B6F, 0x000000, 0xFFFFFF, + 0x005B74, 0x005B74, 0x000000, 0xFFFFFF, + 0x005B76, 0x005B76, 0x000000, 0xFFFFFF, + 0x005B79, 0x005B79, 0x000000, 0xFFFFFF, + 0x005B7C, 0x005B7C, 0x000000, 0xFFFFFF, + 0x005B7E, 0x005B7E, 0x000000, 0xFFFFFF, + 0x005B80, 0x005B80, 0x000000, 0xFFFFFF, + 0x005B82, 0x005B82, 0x000000, 0xFFFFFF, + 0x005B86, 0x005B86, 0x000000, 0xFFFFFF, + 0x005B8A, 0x005B8A, 0x000000, 0xFFFFFF, + 0x005B8D, 0x005B8D, 0x000000, 0xFFFFFF, + 0x005B90, 0x005B91, 0x000000, 0xFFFFFF, + 0x005B94, 0x005B94, 0x000000, 0xFFFFFF, + 0x005B96, 0x005B96, 0x000000, 0xFFFFFF, + 0x005B9D, 0x005BA1, 0x000000, 0xFFFFFF, + 0x005BA9, 0x005BAB, 0x000000, 0xFFFFFF, + 0x005BAF, 0x005BAF, 0x000000, 0xFFFFFF, + 0x005BB1, 0x005BB2, 0x000000, 0xFFFFFF, + 0x005BB7, 0x005BB7, 0x000000, 0xFFFFFF, + 0x005BBA, 0x005BBE, 0x000000, 0xFFFFFF, + 0x005BC3, 0x005BC3, 0x000000, 0xFFFFFF, + 0x005BC8, 0x005BC9, 0x000000, 0xFFFFFF, + 0x005BCF, 0x005BCF, 0x000000, 0xFFFFFF, + 0x005BD5, 0x005BD5, 0x000000, 0xFFFFFF, + 0x005BD7, 0x005BD7, 0x000000, 0xFFFFFF, + 0x005BDA, 0x005BDD, 0x000000, 0xFFFFFF, + 0x005BED, 0x005BED, 0x000000, 0xFFFFFF, + 0x005BF3, 0x005BF4, 0x000000, 0xFFFFFF, + 0x005BF7, 0x005BF7, 0x000000, 0xFFFFFF, + 0x005BF9, 0x005BF9, 0x000000, 0xFFFFFF, + 0x005BFB, 0x005C00, 0x000000, 0xFFFFFF, + 0x005C02, 0x005C02, 0x000000, 0xFFFFFF, + 0x005C05, 0x005C06, 0x000000, 0xFFFFFF, + 0x005C13, 0x005C14, 0x000000, 0xFFFFFF, + 0x005C17, 0x005C19, 0x000000, 0xFFFFFF, + 0x005C1B, 0x005C1E, 0x000000, 0xFFFFFF, + 0x005C20, 0x005C21, 0x000000, 0xFFFFFF, + 0x005C23, 0x005C23, 0x000000, 0xFFFFFF, + 0x005C26, 0x005C27, 0x000000, 0xFFFFFF, + 0x005C29, 0x005C29, 0x000000, 0xFFFFFF, + 0x005C2B, 0x005C2B, 0x000000, 0xFFFFFF, + 0x005C2D, 0x005C2F, 0x000000, 0xFFFFFF, + 0x005C32, 0x005C32, 0x000000, 0xFFFFFF, + 0x005C34, 0x005C36, 0x000000, 0xFFFFFF, + 0x005C3D, 0x005C3D, 0x000000, 0xFFFFFF, + 0x005C42, 0x005C43, 0x000000, 0xFFFFFF, + 0x005C49, 0x005C4A, 0x000000, 0xFFFFFF, + 0x005C52, 0x005C53, 0x000000, 0xFFFFFF, + 0x005C57, 0x005C57, 0x000000, 0xFFFFFF, + 0x005C5A, 0x005C5B, 0x000000, 0xFFFFFF, + 0x005C5E, 0x005C5F, 0x000000, 0xFFFFFF, + 0x005C61, 0x005C61, 0x000000, 0xFFFFFF, + 0x005C66, 0x005C66, 0x000000, 0xFFFFFF, + 0x005C6B, 0x005C6B, 0x000000, 0xFFFFFF, + 0x005C70, 0x005C70, 0x000000, 0xFFFFFF, + 0x005C72, 0x005C72, 0x000000, 0xFFFFFF, + 0x005C75, 0x005C78, 0x000000, 0xFFFFFF, + 0x005C7D, 0x005C7D, 0x000000, 0xFFFFFF, + 0x005C7F, 0x005C85, 0x000000, 0xFFFFFF, + 0x005C87, 0x005C87, 0x000000, 0xFFFFFF, + 0x005C8E, 0x005C8E, 0x000000, 0xFFFFFF, + 0x005C96, 0x005C9C, 0x000000, 0xFFFFFF, + 0x005C9E, 0x005C9E, 0x000000, 0xFFFFFF, + 0x005CB2, 0x005CB2, 0x000000, 0xFFFFFF, + 0x005CB4, 0x005CB4, 0x000000, 0xFFFFFF, + 0x005CB9, 0x005CC5, 0x000000, 0xFFFFFF, + 0x005CCD, 0x005CCD, 0x000000, 0xFFFFFF, + 0x005CD1, 0x005CD1, 0x000000, 0xFFFFFF, + 0x005CD5, 0x005CD5, 0x000000, 0xFFFFFF, + 0x005CDC, 0x005CDD, 0x000000, 0xFFFFFF, + 0x005CE0, 0x005CE7, 0x000000, 0xFFFFFF, + 0x005CE9, 0x005CE9, 0x000000, 0xFFFFFF, + 0x005CEB, 0x005CEB, 0x000000, 0xFFFFFF, + 0x005CEF, 0x005CEF, 0x000000, 0xFFFFFF, + 0x005CF2, 0x005CF3, 0x000000, 0xFFFFFF, + 0x005CF5, 0x005CF5, 0x000000, 0xFFFFFF, + 0x005CFA, 0x005CFA, 0x000000, 0xFFFFFF, + 0x005CFC, 0x005CFC, 0x000000, 0xFFFFFF, + 0x005CFE, 0x005CFE, 0x000000, 0xFFFFFF, + 0x005D02, 0x005D05, 0x000000, 0xFFFFFF, + 0x005D08, 0x005D0A, 0x000000, 0xFFFFFF, + 0x005D10, 0x005D10, 0x000000, 0xFFFFFF, + 0x005D13, 0x005D13, 0x000000, 0xFFFFFF, + 0x005D15, 0x005D15, 0x000000, 0xFFFFFF, + 0x005D18, 0x005D18, 0x000000, 0xFFFFFF, + 0x005D1C, 0x005D1C, 0x000000, 0xFFFFFF, + 0x005D21, 0x005D21, 0x000000, 0xFFFFFF, + 0x005D2A, 0x005D2D, 0x000000, 0xFFFFFF, + 0x005D2F, 0x005D2F, 0x000000, 0xFFFFFF, + 0x005D3B, 0x005D3B, 0x000000, 0xFFFFFF, + 0x005D3E, 0x005D3E, 0x000000, 0xFFFFFF, + 0x005D44, 0x005D44, 0x000000, 0xFFFFFF, + 0x005D46, 0x005D46, 0x000000, 0xFFFFFF, + 0x005D48, 0x005D48, 0x000000, 0xFFFFFF, + 0x005D4D, 0x005D4D, 0x000000, 0xFFFFFF, + 0x005D4F, 0x005D4F, 0x000000, 0xFFFFFF, + 0x005D53, 0x005D54, 0x000000, 0xFFFFFF, + 0x005D56, 0x005D58, 0x000000, 0xFFFFFF, + 0x005D5A, 0x005D5D, 0x000000, 0xFFFFFF, + 0x005D5F, 0x005D61, 0x000000, 0xFFFFFF, + 0x005D64, 0x005D64, 0x000000, 0xFFFFFF, + 0x005D66, 0x005D66, 0x000000, 0xFFFFFF, + 0x005D6A, 0x005D6A, 0x000000, 0xFFFFFF, + 0x005D6D, 0x005D6E, 0x000000, 0xFFFFFF, + 0x005D70, 0x005D70, 0x000000, 0xFFFFFF, + 0x005D73, 0x005D76, 0x000000, 0xFFFFFF, + 0x005D78, 0x005D78, 0x000000, 0xFFFFFF, + 0x005D7B, 0x005D7B, 0x000000, 0xFFFFFF, + 0x005D83, 0x005D83, 0x000000, 0xFFFFFF, + 0x005D85, 0x005D85, 0x000000, 0xFFFFFF, + 0x005D8B, 0x005D8C, 0x000000, 0xFFFFFF, + 0x005D8E, 0x005D91, 0x000000, 0xFFFFFF, + 0x005D96, 0x005D96, 0x000000, 0xFFFFFF, + 0x005D98, 0x005D98, 0x000000, 0xFFFFFF, + 0x005D9B, 0x005D9B, 0x000000, 0xFFFFFF, + 0x005DA3, 0x005DA6, 0x000000, 0xFFFFFF, + 0x005DAB, 0x005DAB, 0x000000, 0xFFFFFF, + 0x005DB3, 0x005DB3, 0x000000, 0xFFFFFF, + 0x005DB6, 0x005DB6, 0x000000, 0xFFFFFF, + 0x005DB9, 0x005DB9, 0x000000, 0xFFFFFF, + 0x005DBB, 0x005DBB, 0x000000, 0xFFFFFF, + 0x005DBE, 0x005DBF, 0x000000, 0xFFFFFF, + 0x005DC1, 0x005DC1, 0x000000, 0xFFFFFF, + 0x005DC4, 0x005DC5, 0x000000, 0xFFFFFF, + 0x005DC8, 0x005DC8, 0x000000, 0xFFFFFF, + 0x005DCA, 0x005DCA, 0x000000, 0xFFFFFF, + 0x005DCC, 0x005DCC, 0x000000, 0xFFFFFF, + 0x005DCE, 0x005DCE, 0x000000, 0xFFFFFF, + 0x005DD0, 0x005DD0, 0x000000, 0xFFFFFF, + 0x005DD3, 0x005DD3, 0x000000, 0xFFFFFF, + 0x005DD7, 0x005DD7, 0x000000, 0xFFFFFF, + 0x005DD9, 0x005DDC, 0x000000, 0xFFFFFF, + 0x005DE3, 0x005DE4, 0x000000, 0xFFFFFF, + 0x005DE9, 0x005DEA, 0x000000, 0xFFFFFF, + 0x005DEC, 0x005DED, 0x000000, 0xFFFFFF, + 0x005DEF, 0x005DEF, 0x000000, 0xFFFFFF, + 0x005DF5, 0x005DF6, 0x000000, 0xFFFFFF, + 0x005DF8, 0x005DF8, 0x000000, 0xFFFFFF, + 0x005DFA, 0x005DFC, 0x000000, 0xFFFFFF, + 0x005E00, 0x005E01, 0x000000, 0xFFFFFF, + 0x005E05, 0x005E05, 0x000000, 0xFFFFFF, + 0x005E07, 0x005E09, 0x000000, 0xFFFFFF, + 0x005E0B, 0x005E0B, 0x000000, 0xFFFFFF, + 0x005E0D, 0x005E0D, 0x000000, 0xFFFFFF, + 0x005E0F, 0x005E10, 0x000000, 0xFFFFFF, + 0x005E12, 0x005E13, 0x000000, 0xFFFFFF, + 0x005E1C, 0x005E1C, 0x000000, 0xFFFFFF, + 0x005E1E, 0x005E1E, 0x000000, 0xFFFFFF, + 0x005E26, 0x005E27, 0x000000, 0xFFFFFF, + 0x005E2A, 0x005E2A, 0x000000, 0xFFFFFF, + 0x005E2C, 0x005E2C, 0x000000, 0xFFFFFF, + 0x005E2E, 0x005E32, 0x000000, 0xFFFFFF, + 0x005E35, 0x005E35, 0x000000, 0xFFFFFF, + 0x005E39, 0x005E3C, 0x000000, 0xFFFFFF, + 0x005E3F, 0x005E3F, 0x000000, 0xFFFFFF, + 0x005E42, 0x005E42, 0x000000, 0xFFFFFF, + 0x005E46, 0x005E49, 0x000000, 0xFFFFFF, + 0x005E50, 0x005E52, 0x000000, 0xFFFFFF, + 0x005E56, 0x005E56, 0x000000, 0xFFFFFF, + 0x005E5A, 0x005E5A, 0x000000, 0xFFFFFF, + 0x005E5E, 0x005E5E, 0x000000, 0xFFFFFF, + 0x005E64, 0x005E65, 0x000000, 0xFFFFFF, + 0x005E71, 0x005E71, 0x000000, 0xFFFFFF, + 0x005E77, 0x005E77, 0x000000, 0xFFFFFF, + 0x005E7A, 0x005E7A, 0x000000, 0xFFFFFF, + 0x005E7F, 0x005E7F, 0x000000, 0xFFFFFF, + 0x005E81, 0x005E81, 0x000000, 0xFFFFFF, + 0x005E83, 0x005E83, 0x000000, 0xFFFFFF, + 0x005E85, 0x005E86, 0x000000, 0xFFFFFF, + 0x005E8E, 0x005E8E, 0x000000, 0xFFFFFF, + 0x005E90, 0x005E94, 0x000000, 0xFFFFFF, + 0x005E98, 0x005E99, 0x000000, 0xFFFFFF, + 0x005E9D, 0x005E9F, 0x000000, 0xFFFFFF, + 0x005EA1, 0x005EA1, 0x000000, 0xFFFFFF, + 0x005EA9, 0x005EA9, 0x000000, 0xFFFFFF, + 0x005EAF, 0x005EAF, 0x000000, 0xFFFFFF, + 0x005EBA, 0x005EBD, 0x000000, 0xFFFFFF, + 0x005EBF, 0x005EC0, 0x000000, 0xFFFFFF, + 0x005EC3, 0x005EC3, 0x000000, 0xFFFFFF, + 0x005ECD, 0x005ECD, 0x000000, 0xFFFFFF, + 0x005ECF, 0x005ED0, 0x000000, 0xFFFFFF, + 0x005EE4, 0x005EE4, 0x000000, 0xFFFFFF, + 0x005EEA, 0x005EEB, 0x000000, 0xFFFFFF, + 0x005EED, 0x005EED, 0x000000, 0xFFFFFF, + 0x005EF0, 0x005EF0, 0x000000, 0xFFFFFF, + 0x005EF4, 0x005EF5, 0x000000, 0xFFFFFF, + 0x005EF8, 0x005EF9, 0x000000, 0xFFFFFF, + 0x005EFB, 0x005EFD, 0x000000, 0xFFFFFF, + 0x005F00, 0x005F00, 0x000000, 0xFFFFFF, + 0x005F03, 0x005F03, 0x000000, 0xFFFFFF, + 0x005F06, 0x005F06, 0x000000, 0xFFFFFF, + 0x005F09, 0x005F09, 0x000000, 0xFFFFFF, + 0x005F0C, 0x005F0E, 0x000000, 0xFFFFFF, + 0x005F10, 0x005F11, 0x000000, 0xFFFFFF, + 0x005F16, 0x005F16, 0x000000, 0xFFFFFF, + 0x005F19, 0x005F19, 0x000000, 0xFFFFFF, + 0x005F1C, 0x005F1C, 0x000000, 0xFFFFFF, + 0x005F1E, 0x005F1E, 0x000000, 0xFFFFFF, + 0x005F20, 0x005F21, 0x000000, 0xFFFFFF, + 0x005F25, 0x005F25, 0x000000, 0xFFFFFF, + 0x005F2A, 0x005F2C, 0x000000, 0xFFFFFF, + 0x005F2F, 0x005F2F, 0x000000, 0xFFFFFF, + 0x005F32, 0x005F32, 0x000000, 0xFFFFFF, + 0x005F34, 0x005F34, 0x000000, 0xFFFFFF, + 0x005F39, 0x005F3B, 0x000000, 0xFFFFFF, + 0x005F3D, 0x005F3F, 0x000000, 0xFFFFFF, + 0x005F41, 0x005F42, 0x000000, 0xFFFFFF, + 0x005F45, 0x005F45, 0x000000, 0xFFFFFF, + 0x005F47, 0x005F47, 0x000000, 0xFFFFFF, + 0x005F4D, 0x005F4D, 0x000000, 0xFFFFFF, + 0x005F50, 0x005F53, 0x000000, 0xFFFFFF, + 0x005F55, 0x005F55, 0x000000, 0xFFFFFF, + 0x005F5A, 0x005F5C, 0x000000, 0xFFFFFF, + 0x005F5E, 0x005F61, 0x000000, 0xFFFFFF, + 0x005F63, 0x005F63, 0x000000, 0xFFFFFF, + 0x005F66, 0x005F66, 0x000000, 0xFFFFFF, + 0x005F68, 0x005F68, 0x000000, 0xFFFFFF, + 0x005F6E, 0x005F6E, 0x000000, 0xFFFFFF, + 0x005F72, 0x005F72, 0x000000, 0xFFFFFF, + 0x005F75, 0x005F75, 0x000000, 0xFFFFFF, + 0x005F7A, 0x005F7B, 0x000000, 0xFFFFFF, + 0x005F83, 0x005F84, 0x000000, 0xFFFFFF, + 0x005F8D, 0x005F8F, 0x000000, 0xFFFFFF, + 0x005F93, 0x005F95, 0x000000, 0xFFFFFF, + 0x005F9A, 0x005F9A, 0x000000, 0xFFFFFF, + 0x005F9D, 0x005F9D, 0x000000, 0xFFFFFF, + 0x005FA2, 0x005FA4, 0x000000, 0xFFFFFF, + 0x005FA7, 0x005FA7, 0x000000, 0xFFFFFF, + 0x005FB0, 0x005FB1, 0x000000, 0xFFFFFF, + 0x005FB3, 0x005FB4, 0x000000, 0xFFFFFF, + 0x005FB8, 0x005FB8, 0x000000, 0xFFFFFF, + 0x005FBA, 0x005FBA, 0x000000, 0xFFFFFF, + 0x005FC2, 0x005FC2, 0x000000, 0xFFFFFF, + 0x005FC4, 0x005FC4, 0x000000, 0xFFFFFF, + 0x005FC6, 0x005FC8, 0x000000, 0xFFFFFF, + 0x005FCA, 0x005FCB, 0x000000, 0xFFFFFF, + 0x005FCE, 0x005FCE, 0x000000, 0xFFFFFF, + 0x005FD3, 0x005FD3, 0x000000, 0xFFFFFF, + 0x005FDA, 0x005FDC, 0x000000, 0xFFFFFF, + 0x005FDF, 0x005FDF, 0x000000, 0xFFFFFF, + 0x005FE2, 0x005FE2, 0x000000, 0xFFFFFF, + 0x005FE6, 0x005FE7, 0x000000, 0xFFFFFF, + 0x005FE9, 0x005FE9, 0x000000, 0xFFFFFF, + 0x005FEC, 0x005FEC, 0x000000, 0xFFFFFF, + 0x005FF0, 0x005FF0, 0x000000, 0xFFFFFF, + 0x005FF2, 0x005FF2, 0x000000, 0xFFFFFF, + 0x005FF6, 0x005FF6, 0x000000, 0xFFFFFF, + 0x005FF9, 0x005FF9, 0x000000, 0xFFFFFF, + 0x005FFC, 0x005FFC, 0x000000, 0xFFFFFF, + 0x005FFE, 0x005FFE, 0x000000, 0xFFFFFF, + 0x006001, 0x006008, 0x000000, 0xFFFFFF, + 0x006018, 0x006018, 0x000000, 0xFFFFFF, + 0x00601F, 0x00601F, 0x000000, 0xFFFFFF, + 0x006023, 0x006023, 0x000000, 0xFFFFFF, + 0x006030, 0x006031, 0x000000, 0xFFFFFF, + 0x006036, 0x006036, 0x000000, 0xFFFFFF, + 0x006038, 0x006038, 0x000000, 0xFFFFFF, + 0x00603A, 0x00603F, 0x000000, 0xFFFFFF, + 0x006048, 0x006048, 0x000000, 0xFFFFFF, + 0x00604A, 0x00604B, 0x000000, 0xFFFFFF, + 0x00604E, 0x00604F, 0x000000, 0xFFFFFF, + 0x006051, 0x006051, 0x000000, 0xFFFFFF, + 0x006056, 0x006057, 0x000000, 0xFFFFFF, + 0x00605C, 0x00605C, 0x000000, 0xFFFFFF, + 0x006060, 0x006061, 0x000000, 0xFFFFFF, + 0x006071, 0x006071, 0x000000, 0xFFFFFF, + 0x006073, 0x00607E, 0x000000, 0xFFFFFF, + 0x006082, 0x006082, 0x000000, 0xFFFFFF, + 0x00608B, 0x00608B, 0x000000, 0xFFFFFF, + 0x00608F, 0x00608F, 0x000000, 0xFFFFFF, + 0x006091, 0x006091, 0x000000, 0xFFFFFF, + 0x006093, 0x006093, 0x000000, 0xFFFFFF, + 0x006098, 0x006099, 0x000000, 0xFFFFFF, + 0x00609E, 0x00609E, 0x000000, 0xFFFFFF, + 0x0060A1, 0x0060A1, 0x000000, 0xFFFFFF, + 0x0060A4, 0x0060A7, 0x000000, 0xFFFFFF, + 0x0060A9, 0x0060AF, 0x000000, 0xFFFFFF, + 0x0060B3, 0x0060B3, 0x000000, 0xFFFFFF, + 0x0060C2, 0x0060C2, 0x000000, 0xFFFFFF, + 0x0060D0, 0x0060D0, 0x000000, 0xFFFFFF, + 0x0060D2, 0x0060D2, 0x000000, 0xFFFFFF, + 0x0060D6, 0x0060D7, 0x000000, 0xFFFFFF, + 0x0060DE, 0x0060DE, 0x000000, 0xFFFFFF, + 0x0060E3, 0x0060E3, 0x000000, 0xFFFFFF, + 0x0060E5, 0x0060E5, 0x000000, 0xFFFFFF, + 0x0060E7, 0x0060EF, 0x000000, 0xFFFFFF, + 0x0060FD, 0x0060FD, 0x000000, 0xFFFFFF, + 0x006102, 0x006102, 0x000000, 0xFFFFFF, + 0x006107, 0x006107, 0x000000, 0xFFFFFF, + 0x00610C, 0x00610C, 0x000000, 0xFFFFFF, + 0x006111, 0x006111, 0x000000, 0xFFFFFF, + 0x006117, 0x006117, 0x000000, 0xFFFFFF, + 0x006119, 0x006119, 0x000000, 0xFFFFFF, + 0x00611E, 0x00611E, 0x000000, 0xFFFFFF, + 0x006120, 0x006122, 0x000000, 0xFFFFFF, + 0x006124, 0x006126, 0x000000, 0xFFFFFF, + 0x00612A, 0x00612A, 0x000000, 0xFFFFFF, + 0x00612D, 0x00612D, 0x000000, 0xFFFFFF, + 0x006130, 0x006131, 0x000000, 0xFFFFFF, + 0x006133, 0x006133, 0x000000, 0xFFFFFF, + 0x006135, 0x006135, 0x000000, 0xFFFFFF, + 0x006138, 0x00613A, 0x000000, 0xFFFFFF, + 0x00613C, 0x00613D, 0x000000, 0xFFFFFF, + 0x006142, 0x006143, 0x000000, 0xFFFFFF, + 0x006150, 0x006151, 0x000000, 0xFFFFFF, + 0x006157, 0x006157, 0x000000, 0xFFFFFF, + 0x006159, 0x006159, 0x000000, 0xFFFFFF, + 0x00615C, 0x00615C, 0x000000, 0xFFFFFF, + 0x006160, 0x006160, 0x000000, 0xFFFFFF, + 0x006164, 0x006164, 0x000000, 0xFFFFFF, + 0x006169, 0x006169, 0x000000, 0xFFFFFF, + 0x00616D, 0x00616D, 0x000000, 0xFFFFFF, + 0x00616F, 0x00616F, 0x000000, 0xFFFFFF, + 0x006178, 0x006178, 0x000000, 0xFFFFFF, + 0x00617B, 0x00617B, 0x000000, 0xFFFFFF, + 0x00617D, 0x00617D, 0x000000, 0xFFFFFF, + 0x00617F, 0x00617F, 0x000000, 0xFFFFFF, + 0x006181, 0x006181, 0x000000, 0xFFFFFF, + 0x006184, 0x006188, 0x000000, 0xFFFFFF, + 0x00618F, 0x00618F, 0x000000, 0xFFFFFF, + 0x006195, 0x006195, 0x000000, 0xFFFFFF, + 0x006197, 0x006199, 0x000000, 0xFFFFFF, + 0x00619C, 0x00619C, 0x000000, 0xFFFFFF, + 0x00619E, 0x00619E, 0x000000, 0xFFFFFF, + 0x0061A0, 0x0061A0, 0x000000, 0xFFFFFF, + 0x0061A3, 0x0061A3, 0x000000, 0xFFFFFF, + 0x0061A5, 0x0061A6, 0x000000, 0xFFFFFF, + 0x0061B7, 0x0061B7, 0x000000, 0xFFFFFF, + 0x0061B9, 0x0061B9, 0x000000, 0xFFFFFF, + 0x0061BB, 0x0061BB, 0x000000, 0xFFFFFF, + 0x0061BD, 0x0061BD, 0x000000, 0xFFFFFF, + 0x0061C0, 0x0061C0, 0x000000, 0xFFFFFF, + 0x0061C4, 0x0061C4, 0x000000, 0xFFFFFF, + 0x0061CE, 0x0061D5, 0x000000, 0xFFFFFF, + 0x0061D7, 0x0061D7, 0x000000, 0xFFFFFF, + 0x0061D9, 0x0061DD, 0x000000, 0xFFFFFF, + 0x0061E1, 0x0061E2, 0x000000, 0xFFFFFF, + 0x0061EC, 0x0061EC, 0x000000, 0xFFFFFF, + 0x0061EF, 0x0061EF, 0x000000, 0xFFFFFF, + 0x0061F3, 0x0061F4, 0x000000, 0xFFFFFF, + 0x006202, 0x006202, 0x000000, 0xFFFFFF, + 0x006205, 0x006206, 0x000000, 0xFFFFFF, + 0x00620B, 0x00620B, 0x000000, 0xFFFFFF, + 0x00620F, 0x00620F, 0x000000, 0xFFFFFF, + 0x006213, 0x006213, 0x000000, 0xFFFFFF, + 0x006217, 0x006218, 0x000000, 0xFFFFFF, + 0x00621C, 0x00621E, 0x000000, 0xFFFFFF, + 0x006226, 0x006226, 0x000000, 0xFFFFFF, + 0x006228, 0x006228, 0x000000, 0xFFFFFF, + 0x00622C, 0x00622C, 0x000000, 0xFFFFFF, + 0x00622F, 0x00622F, 0x000000, 0xFFFFFF, + 0x006231, 0x006231, 0x000000, 0xFFFFFF, + 0x006235, 0x006235, 0x000000, 0xFFFFFF, + 0x006237, 0x006239, 0x000000, 0xFFFFFF, + 0x00623B, 0x00623C, 0x000000, 0xFFFFFF, + 0x006244, 0x006245, 0x000000, 0xFFFFFF, + 0x00624C, 0x00624C, 0x000000, 0xFFFFFF, + 0x00624F, 0x00624F, 0x000000, 0xFFFFFF, + 0x006255, 0x006257, 0x000000, 0xFFFFFF, + 0x00625D, 0x00625D, 0x000000, 0xFFFFFF, + 0x00625F, 0x00625F, 0x000000, 0xFFFFFF, + 0x006267, 0x00626C, 0x000000, 0xFFFFFF, + 0x006275, 0x006275, 0x000000, 0xFFFFFF, + 0x006278, 0x006278, 0x000000, 0xFFFFFF, + 0x006282, 0x006282, 0x000000, 0xFFFFFF, + 0x006285, 0x006285, 0x000000, 0xFFFFFF, + 0x00628B, 0x00628B, 0x000000, 0xFFFFFF, + 0x00628D, 0x00628D, 0x000000, 0xFFFFFF, + 0x006290, 0x006290, 0x000000, 0xFFFFFF, + 0x006299, 0x0062A7, 0x000000, 0xFFFFFF, + 0x0062B2, 0x0062B2, 0x000000, 0xFFFFFF, + 0x0062B7, 0x0062B7, 0x000000, 0xFFFFFF, + 0x0062BA, 0x0062BA, 0x000000, 0xFFFFFF, + 0x0062C0, 0x0062C1, 0x000000, 0xFFFFFF, + 0x0062C3, 0x0062C3, 0x000000, 0xFFFFFF, + 0x0062C5, 0x0062C5, 0x000000, 0xFFFFFF, + 0x0062D5, 0x0062D5, 0x000000, 0xFFFFFF, + 0x0062DD, 0x0062EA, 0x000000, 0xFFFFFF, + 0x006304, 0x006306, 0x000000, 0xFFFFFF, + 0x00630A, 0x00630A, 0x000000, 0xFFFFFF, + 0x006312, 0x006312, 0x000000, 0xFFFFFF, + 0x006317, 0x006327, 0x000000, 0xFFFFFF, + 0x00632E, 0x00632E, 0x000000, 0xFFFFFF, + 0x006330, 0x006331, 0x000000, 0xFFFFFF, + 0x006335, 0x006335, 0x000000, 0xFFFFFF, + 0x006337, 0x006337, 0x000000, 0xFFFFFF, + 0x00633F, 0x00633F, 0x000000, 0xFFFFFF, + 0x006352, 0x006353, 0x000000, 0xFFFFFF, + 0x00635B, 0x006364, 0x000000, 0xFFFFFF, + 0x006366, 0x006366, 0x000000, 0xFFFFFF, + 0x00636A, 0x00636A, 0x000000, 0xFFFFFF, + 0x00636C, 0x00636C, 0x000000, 0xFFFFFF, + 0x006373, 0x006374, 0x000000, 0xFFFFFF, + 0x006379, 0x006379, 0x000000, 0xFFFFFF, + 0x00637E, 0x00637F, 0x000000, 0xFFFFFF, + 0x006386, 0x006386, 0x000000, 0xFFFFFF, + 0x00638B, 0x00638B, 0x000000, 0xFFFFFF, + 0x006393, 0x006393, 0x000000, 0xFFFFFF, + 0x006395, 0x006395, 0x000000, 0xFFFFFF, + 0x00639A, 0x00639A, 0x000000, 0xFFFFFF, + 0x0063A6, 0x0063A6, 0x000000, 0xFFFFFF, + 0x0063B2, 0x0063BC, 0x000000, 0xFFFFFF, + 0x0063BF, 0x0063BF, 0x000000, 0xFFFFFF, + 0x0063C1, 0x0063C1, 0x000000, 0xFFFFFF, + 0x0063D1, 0x0063D1, 0x000000, 0xFFFFFF, + 0x0063D4, 0x0063D4, 0x000000, 0xFFFFFF, + 0x0063DE, 0x0063DE, 0x000000, 0xFFFFFF, + 0x0063E2, 0x0063E2, 0x000000, 0xFFFFFF, + 0x0063E6, 0x0063E6, 0x000000, 0xFFFFFF, + 0x0063EC, 0x0063EC, 0x000000, 0xFFFFFF, + 0x0063F7, 0x0063F8, 0x000000, 0xFFFFFF, + 0x0063FA, 0x006405, 0x000000, 0xFFFFFF, + 0x006407, 0x006408, 0x000000, 0xFFFFFF, + 0x006411, 0x006411, 0x000000, 0xFFFFFF, + 0x006419, 0x006419, 0x000000, 0xFFFFFF, + 0x00641D, 0x00641D, 0x000000, 0xFFFFFF, + 0x006429, 0x006429, 0x000000, 0xFFFFFF, + 0x006431, 0x006432, 0x000000, 0xFFFFFF, + 0x006438, 0x006438, 0x000000, 0xFFFFFF, + 0x00643A, 0x00643C, 0x000000, 0xFFFFFF, + 0x006442, 0x006442, 0x000000, 0xFFFFFF, + 0x006444, 0x00644A, 0x000000, 0xFFFFFF, + 0x00644C, 0x00644C, 0x000000, 0xFFFFFF, + 0x00644F, 0x00644F, 0x000000, 0xFFFFFF, + 0x006455, 0x006457, 0x000000, 0xFFFFFF, + 0x00645A, 0x00645A, 0x000000, 0xFFFFFF, + 0x006462, 0x006464, 0x000000, 0xFFFFFF, + 0x00646A, 0x00646A, 0x000000, 0xFFFFFF, + 0x006471, 0x006471, 0x000000, 0xFFFFFF, + 0x00647C, 0x00647C, 0x000000, 0xFFFFFF, + 0x00647E, 0x00647E, 0x000000, 0xFFFFFF, + 0x006480, 0x006481, 0x000000, 0xFFFFFF, + 0x006483, 0x006484, 0x000000, 0xFFFFFF, + 0x006486, 0x006486, 0x000000, 0xFFFFFF, + 0x00648D, 0x00648E, 0x000000, 0xFFFFFF, + 0x006491, 0x006491, 0x000000, 0xFFFFFF, + 0x006494, 0x006494, 0x000000, 0xFFFFFF, + 0x00649B, 0x00649B, 0x000000, 0xFFFFFF, + 0x0064A1, 0x0064A1, 0x000000, 0xFFFFFF, + 0x0064A7, 0x0064A8, 0x000000, 0xFFFFFF, + 0x0064AA, 0x0064AA, 0x000000, 0xFFFFFF, + 0x0064AF, 0x0064AF, 0x000000, 0xFFFFFF, + 0x0064B4, 0x0064BA, 0x000000, 0xFFFFFF, + 0x0064C0, 0x0064C0, 0x000000, 0xFFFFFF, + 0x0064C6, 0x0064C6, 0x000000, 0xFFFFFF, + 0x0064C8, 0x0064C8, 0x000000, 0xFFFFFF, + 0x0064CC, 0x0064CC, 0x000000, 0xFFFFFF, + 0x0064D1, 0x0064D1, 0x000000, 0xFFFFFF, + 0x0064D3, 0x0064D3, 0x000000, 0xFFFFFF, + 0x0064D5, 0x0064D5, 0x000000, 0xFFFFFF, + 0x0064DC, 0x0064DF, 0x000000, 0xFFFFFF, + 0x0064E1, 0x0064E1, 0x000000, 0xFFFFFF, + 0x0064E5, 0x0064E5, 0x000000, 0xFFFFFF, + 0x0064E7, 0x0064E7, 0x000000, 0xFFFFFF, + 0x0064EA, 0x0064EA, 0x000000, 0xFFFFFF, + 0x0064EE, 0x0064EE, 0x000000, 0xFFFFFF, + 0x0064F5, 0x0064F6, 0x000000, 0xFFFFFF, + 0x0064F9, 0x0064F9, 0x000000, 0xFFFFFF, + 0x006502, 0x006502, 0x000000, 0xFFFFFF, + 0x006505, 0x006505, 0x000000, 0xFFFFFF, + 0x006508, 0x006508, 0x000000, 0xFFFFFF, + 0x00650A, 0x00650B, 0x000000, 0xFFFFFF, + 0x006511, 0x006512, 0x000000, 0xFFFFFF, + 0x00651A, 0x00651A, 0x000000, 0xFFFFFF, + 0x00651E, 0x00651F, 0x000000, 0xFFFFFF, + 0x006527, 0x006528, 0x000000, 0xFFFFFF, + 0x006530, 0x006531, 0x000000, 0xFFFFFF, + 0x006534, 0x006535, 0x000000, 0xFFFFFF, + 0x00653A, 0x00653A, 0x000000, 0xFFFFFF, + 0x00653C, 0x00653C, 0x000000, 0xFFFFFF, + 0x006540, 0x006540, 0x000000, 0xFFFFFF, + 0x006542, 0x006542, 0x000000, 0xFFFFFF, + 0x006544, 0x006544, 0x000000, 0xFFFFFF, + 0x006547, 0x006547, 0x000000, 0xFFFFFF, + 0x00654B, 0x00654E, 0x000000, 0xFFFFFF, + 0x006550, 0x006550, 0x000000, 0xFFFFFF, + 0x006552, 0x006552, 0x000000, 0xFFFFFF, + 0x00655A, 0x00655B, 0x000000, 0xFFFFFF, + 0x00655F, 0x006561, 0x000000, 0xFFFFFF, + 0x006569, 0x006569, 0x000000, 0xFFFFFF, + 0x00656B, 0x00656B, 0x000000, 0xFFFFFF, + 0x00656D, 0x00656E, 0x000000, 0xFFFFFF, + 0x006570, 0x006571, 0x000000, 0xFFFFFF, + 0x00657D, 0x00657E, 0x000000, 0xFFFFFF, + 0x006585, 0x006586, 0x000000, 0xFFFFFF, + 0x006588, 0x00658B, 0x000000, 0xFFFFFF, + 0x00658D, 0x00658F, 0x000000, 0xFFFFFF, + 0x006593, 0x006593, 0x000000, 0xFFFFFF, + 0x006598, 0x006598, 0x000000, 0xFFFFFF, + 0x00659A, 0x00659A, 0x000000, 0xFFFFFF, + 0x0065A3, 0x0065A3, 0x000000, 0xFFFFFF, + 0x0065A6, 0x0065A6, 0x000000, 0xFFFFFF, + 0x0065A9, 0x0065A9, 0x000000, 0xFFFFFF, + 0x0065AD, 0x0065AD, 0x000000, 0xFFFFFF, + 0x0065B1, 0x0065B1, 0x000000, 0xFFFFFF, + 0x0065B4, 0x0065B5, 0x000000, 0xFFFFFF, + 0x0065BA, 0x0065BA, 0x000000, 0xFFFFFF, + 0x0065BE, 0x0065BE, 0x000000, 0xFFFFFF, + 0x0065C0, 0x0065C0, 0x000000, 0xFFFFFF, + 0x0065C7, 0x0065CA, 0x000000, 0xFFFFFF, + 0x0065D1, 0x0065D1, 0x000000, 0xFFFFFF, + 0x0065D4, 0x0065D5, 0x000000, 0xFFFFFF, + 0x0065D8, 0x0065D9, 0x000000, 0xFFFFFF, + 0x0065DC, 0x0065DC, 0x000000, 0xFFFFFF, + 0x0065E0, 0x0065E0, 0x000000, 0xFFFFFF, + 0x0065E3, 0x0065E4, 0x000000, 0xFFFFFF, + 0x0065E7, 0x0065E7, 0x000000, 0xFFFFFF, + 0x0065EA, 0x0065EB, 0x000000, 0xFFFFFF, + 0x0065F6, 0x0065F9, 0x000000, 0xFFFFFF, + 0x0065FE, 0x0065FF, 0x000000, 0xFFFFFF, + 0x006601, 0x006601, 0x000000, 0xFFFFFF, + 0x006616, 0x00661B, 0x000000, 0xFFFFFF, + 0x00661E, 0x00661E, 0x000000, 0xFFFFFF, + 0x006623, 0x006623, 0x000000, 0xFFFFFF, + 0x006629, 0x00662A, 0x000000, 0xFFFFFF, + 0x00662C, 0x00662C, 0x000000, 0xFFFFFF, + 0x006630, 0x006630, 0x000000, 0xFFFFFF, + 0x006637, 0x006638, 0x000000, 0xFFFFFF, + 0x00663B, 0x006640, 0x000000, 0xFFFFFF, + 0x006644, 0x006644, 0x000000, 0xFFFFFF, + 0x006646, 0x006646, 0x000000, 0xFFFFFF, + 0x006648, 0x006648, 0x000000, 0xFFFFFF, + 0x00664B, 0x00664B, 0x000000, 0xFFFFFF, + 0x00664D, 0x00664E, 0x000000, 0xFFFFFF, + 0x006650, 0x006650, 0x000000, 0xFFFFFF, + 0x006653, 0x006658, 0x000000, 0xFFFFFF, + 0x006660, 0x006660, 0x000000, 0xFFFFFF, + 0x006663, 0x006663, 0x000000, 0xFFFFFF, + 0x006667, 0x006667, 0x000000, 0xFFFFFF, + 0x006669, 0x006669, 0x000000, 0xFFFFFF, + 0x00666B, 0x00666B, 0x000000, 0xFFFFFF, + 0x00666D, 0x00666D, 0x000000, 0xFFFFFF, + 0x006673, 0x006673, 0x000000, 0xFFFFFF, + 0x006675, 0x006675, 0x000000, 0xFFFFFF, + 0x00667D, 0x00667D, 0x000000, 0xFFFFFF, + 0x00667F, 0x00667F, 0x000000, 0xFFFFFF, + 0x006681, 0x006683, 0x000000, 0xFFFFFF, + 0x006685, 0x006685, 0x000000, 0xFFFFFF, + 0x00668E, 0x00668F, 0x000000, 0xFFFFFF, + 0x006692, 0x006693, 0x000000, 0xFFFFFF, + 0x00669A, 0x00669C, 0x000000, 0xFFFFFF, + 0x00669E, 0x00669E, 0x000000, 0xFFFFFF, + 0x0066A3, 0x0066A7, 0x000000, 0xFFFFFF, + 0x0066AC, 0x0066AD, 0x000000, 0xFFFFFF, + 0x0066B3, 0x0066B3, 0x000000, 0xFFFFFF, + 0x0066B6, 0x0066B6, 0x000000, 0xFFFFFF, + 0x0066BC, 0x0066BC, 0x000000, 0xFFFFFF, + 0x0066BF, 0x0066BF, 0x000000, 0xFFFFFF, + 0x0066C1, 0x0066C3, 0x000000, 0xFFFFFF, + 0x0066C5, 0x0066C5, 0x000000, 0xFFFFFF, + 0x0066CD, 0x0066CE, 0x000000, 0xFFFFFF, + 0x0066D0, 0x0066D1, 0x000000, 0xFFFFFF, + 0x0066D3, 0x0066D5, 0x000000, 0xFFFFFF, + 0x0066D7, 0x0066D7, 0x000000, 0xFFFFFF, + 0x0066DF, 0x0066DF, 0x000000, 0xFFFFFF, + 0x0066E1, 0x0066E2, 0x000000, 0xFFFFFF, + 0x0066E5, 0x0066E5, 0x000000, 0xFFFFFF, + 0x0066E7, 0x0066E7, 0x000000, 0xFFFFFF, + 0x0066EA, 0x0066EA, 0x000000, 0xFFFFFF, + 0x0066EF, 0x0066EF, 0x000000, 0xFFFFFF, + 0x0066F1, 0x0066F1, 0x000000, 0xFFFFFF, + 0x0066F5, 0x0066F5, 0x000000, 0xFFFFFF, + 0x0066FA, 0x0066FB, 0x000000, 0xFFFFFF, + 0x0066FD, 0x0066FD, 0x000000, 0xFFFFFF, + 0x006702, 0x006702, 0x000000, 0xFFFFFF, + 0x006706, 0x006707, 0x000000, 0xFFFFFF, + 0x00670C, 0x00670C, 0x000000, 0xFFFFFF, + 0x00670E, 0x00670E, 0x000000, 0xFFFFFF, + 0x006711, 0x006711, 0x000000, 0xFFFFFF, + 0x006716, 0x006716, 0x000000, 0xFFFFFF, + 0x006719, 0x00671A, 0x000000, 0xFFFFFF, + 0x00671C, 0x00671C, 0x000000, 0xFFFFFF, + 0x00671E, 0x00671E, 0x000000, 0xFFFFFF, + 0x006724, 0x006725, 0x000000, 0xFFFFFF, + 0x006729, 0x006729, 0x000000, 0xFFFFFF, + 0x00672F, 0x006730, 0x000000, 0xFFFFFF, + 0x006732, 0x006732, 0x000000, 0xFFFFFF, + 0x006736, 0x006737, 0x000000, 0xFFFFFF, + 0x006740, 0x006744, 0x000000, 0xFFFFFF, + 0x00674A, 0x00674A, 0x000000, 0xFFFFFF, + 0x006752, 0x006752, 0x000000, 0xFFFFFF, + 0x006754, 0x006754, 0x000000, 0xFFFFFF, + 0x006758, 0x006758, 0x000000, 0xFFFFFF, + 0x00675B, 0x00675B, 0x000000, 0xFFFFFF, + 0x006761, 0x006769, 0x000000, 0xFFFFFF, + 0x00676B, 0x00676B, 0x000000, 0xFFFFFF, + 0x00676E, 0x00676E, 0x000000, 0xFFFFFF, + 0x006780, 0x006780, 0x000000, 0xFFFFFF, + 0x006782, 0x006782, 0x000000, 0xFFFFFF, + 0x006788, 0x006788, 0x000000, 0xFFFFFF, + 0x00678A, 0x00678A, 0x000000, 0xFFFFFF, + 0x00678F, 0x00678F, 0x000000, 0xFFFFFF, + 0x006796, 0x006796, 0x000000, 0xFFFFFF, + 0x00679B, 0x00679B, 0x000000, 0xFFFFFF, + 0x00679E, 0x00679E, 0x000000, 0xFFFFFF, + 0x0067A0, 0x0067AD, 0x000000, 0xFFFFFF, + 0x0067B1, 0x0067B1, 0x000000, 0xFFFFFF, + 0x0067BC, 0x0067BF, 0x000000, 0xFFFFFF, + 0x0067C7, 0x0067C7, 0x000000, 0xFFFFFF, + 0x0067D5, 0x0067D7, 0x000000, 0xFFFFFF, + 0x0067E0, 0x0067E1, 0x000000, 0xFFFFFF, + 0x0067E8, 0x0067E8, 0x000000, 0xFFFFFF, + 0x0067F9, 0x0067F9, 0x000000, 0xFFFFFF, + 0x0067FB, 0x0067FB, 0x000000, 0xFFFFFF, + 0x0067FD, 0x0067FE, 0x000000, 0xFFFFFF, + 0x006800, 0x006811, 0x000000, 0xFFFFFF, + 0x006815, 0x006815, 0x000000, 0xFFFFFF, + 0x006819, 0x006819, 0x000000, 0xFFFFFF, + 0x00681B, 0x00681B, 0x000000, 0xFFFFFF, + 0x00681E, 0x00681E, 0x000000, 0xFFFFFF, + 0x006822, 0x006824, 0x000000, 0xFFFFFF, + 0x006827, 0x006827, 0x000000, 0xFFFFFF, + 0x00682C, 0x00682C, 0x000000, 0xFFFFFF, + 0x006830, 0x006830, 0x000000, 0xFFFFFF, + 0x006836, 0x006837, 0x000000, 0xFFFFFF, + 0x00683E, 0x00683F, 0x000000, 0xFFFFFF, + 0x006847, 0x006847, 0x000000, 0xFFFFFF, + 0x00684A, 0x00684A, 0x000000, 0xFFFFFF, + 0x006852, 0x006852, 0x000000, 0xFFFFFF, + 0x006855, 0x00686A, 0x000000, 0xFFFFFF, + 0x00686C, 0x00686C, 0x000000, 0xFFFFFF, + 0x006870, 0x006870, 0x000000, 0xFFFFFF, + 0x006873, 0x006873, 0x000000, 0xFFFFFF, + 0x00687A, 0x00687A, 0x000000, 0xFFFFFF, + 0x006884, 0x006884, 0x000000, 0xFFFFFF, + 0x006888, 0x006888, 0x000000, 0xFFFFFF, + 0x00688D, 0x00688E, 0x000000, 0xFFFFFF, + 0x006895, 0x006895, 0x000000, 0xFFFFFF, + 0x006898, 0x00689A, 0x000000, 0xFFFFFF, + 0x00689E, 0x00689E, 0x000000, 0xFFFFFF, + 0x0068A5, 0x0068A6, 0x000000, 0xFFFFFF, + 0x0068B6, 0x0068C3, 0x000000, 0xFFFFFF, + 0x0068C5, 0x0068C5, 0x000000, 0xFFFFFF, + 0x0068CA, 0x0068CA, 0x000000, 0xFFFFFF, + 0x0068CF, 0x0068CF, 0x000000, 0xFFFFFF, + 0x0068D9, 0x0068D9, 0x000000, 0xFFFFFF, + 0x0068DB, 0x0068DB, 0x000000, 0xFFFFFF, + 0x0068E2, 0x0068E2, 0x000000, 0xFFFFFF, + 0x0068E5, 0x0068E5, 0x000000, 0xFFFFFF, + 0x0068ED, 0x0068ED, 0x000000, 0xFFFFFF, + 0x0068FE, 0x006903, 0x000000, 0xFFFFFF, + 0x006909, 0x006909, 0x000000, 0xFFFFFF, + 0x006916, 0x006916, 0x000000, 0xFFFFFF, + 0x006918, 0x006924, 0x000000, 0xFFFFFF, + 0x006926, 0x006929, 0x000000, 0xFFFFFF, + 0x00692B, 0x00692E, 0x000000, 0xFFFFFF, + 0x006931, 0x006931, 0x000000, 0xFFFFFF, + 0x006936, 0x006936, 0x000000, 0xFFFFFF, + 0x00693A, 0x00693A, 0x000000, 0xFFFFFF, + 0x00693E, 0x00693E, 0x000000, 0xFFFFFF, + 0x006943, 0x006943, 0x000000, 0xFFFFFF, + 0x006946, 0x006947, 0x000000, 0xFFFFFF, + 0x00694D, 0x00694D, 0x000000, 0xFFFFFF, + 0x006950, 0x006950, 0x000000, 0xFFFFFF, + 0x006955, 0x006955, 0x000000, 0xFFFFFF, + 0x006961, 0x006961, 0x000000, 0xFFFFFF, + 0x006964, 0x006964, 0x000000, 0xFFFFFF, + 0x006967, 0x006967, 0x000000, 0xFFFFFF, + 0x006972, 0x006973, 0x000000, 0xFFFFFF, + 0x00697C, 0x006981, 0x000000, 0xFFFFFF, + 0x006984, 0x006985, 0x000000, 0xFFFFFF, + 0x006987, 0x00698C, 0x000000, 0xFFFFFF, + 0x00698F, 0x00698F, 0x000000, 0xFFFFFF, + 0x006992, 0x006992, 0x000000, 0xFFFFFF, + 0x006998, 0x006998, 0x000000, 0xFFFFFF, + 0x00699D, 0x00699D, 0x000000, 0xFFFFFF, + 0x00699F, 0x00699F, 0x000000, 0xFFFFFF, + 0x0069A2, 0x0069A2, 0x000000, 0xFFFFFF, + 0x0069B2, 0x0069B2, 0x000000, 0xFFFFFF, + 0x0069B8, 0x0069B8, 0x000000, 0xFFFFFF, + 0x0069BA, 0x0069BA, 0x000000, 0xFFFFFF, + 0x0069C0, 0x0069C0, 0x000000, 0xFFFFFF, + 0x0069C5, 0x0069C5, 0x000000, 0xFFFFFF, + 0x0069C7, 0x0069C8, 0x000000, 0xFFFFFF, + 0x0069D1, 0x0069D2, 0x000000, 0xFFFFFF, + 0x0069D5, 0x0069D8, 0x000000, 0xFFFFFF, + 0x0069DA, 0x0069E1, 0x000000, 0xFFFFFF, + 0x0069E3, 0x0069E3, 0x000000, 0xFFFFFF, + 0x0069E9, 0x0069EA, 0x000000, 0xFFFFFF, + 0x0069EF, 0x0069F0, 0x000000, 0xFFFFFF, + 0x0069F5, 0x0069F5, 0x000000, 0xFFFFFF, + 0x0069F9, 0x0069FA, 0x000000, 0xFFFFFF, + 0x006A03, 0x006A03, 0x000000, 0xFFFFFF, + 0x006A0B, 0x006A0C, 0x000000, 0xFFFFFF, + 0x006A0E, 0x006A0E, 0x000000, 0xFFFFFF, + 0x006A10, 0x006A10, 0x000000, 0xFFFFFF, + 0x006A12, 0x006A12, 0x000000, 0xFFFFFF, + 0x006A1A, 0x006A1A, 0x000000, 0xFFFFFF, + 0x006A1C, 0x006A1C, 0x000000, 0xFFFFFF, + 0x006A22, 0x006A22, 0x000000, 0xFFFFFF, + 0x006A24, 0x006A24, 0x000000, 0xFFFFFF, + 0x006A29, 0x006A31, 0x000000, 0xFFFFFF, + 0x006A33, 0x006A33, 0x000000, 0xFFFFFF, + 0x006A36, 0x006A37, 0x000000, 0xFFFFFF, + 0x006A42, 0x006A43, 0x000000, 0xFFFFFF, + 0x006A45, 0x006A45, 0x000000, 0xFFFFFF, + 0x006A4A, 0x006A4A, 0x000000, 0xFFFFFF, + 0x006A4C, 0x006A4C, 0x000000, 0xFFFFFF, + 0x006A52, 0x006A53, 0x000000, 0xFFFFFF, + 0x006A57, 0x006A57, 0x000000, 0xFFFFFF, + 0x006A5C, 0x006A5C, 0x000000, 0xFFFFFF, + 0x006A63, 0x006A63, 0x000000, 0xFFFFFF, + 0x006A65, 0x006A65, 0x000000, 0xFFFFFF, + 0x006A6C, 0x006A6C, 0x000000, 0xFFFFFF, + 0x006A6E, 0x006A6E, 0x000000, 0xFFFFFF, + 0x006A70, 0x006A75, 0x000000, 0xFFFFFF, + 0x006A77, 0x006A7D, 0x000000, 0xFFFFFF, + 0x006A82, 0x006A82, 0x000000, 0xFFFFFF, + 0x006A86, 0x006A86, 0x000000, 0xFFFFFF, + 0x006A88, 0x006A88, 0x000000, 0xFFFFFF, + 0x006A8A, 0x006A8B, 0x000000, 0xFFFFFF, + 0x006A8F, 0x006A8F, 0x000000, 0xFFFFFF, + 0x006A98, 0x006A99, 0x000000, 0xFFFFFF, + 0x006A9D, 0x006A9D, 0x000000, 0xFFFFFF, + 0x006AA7, 0x006AA7, 0x000000, 0xFFFFFF, + 0x006AA9, 0x006AAB, 0x000000, 0xFFFFFF, + 0x006AB0, 0x006AB2, 0x000000, 0xFFFFFF, + 0x006AB5, 0x006AB5, 0x000000, 0xFFFFFF, + 0x006ABC, 0x006ABC, 0x000000, 0xFFFFFF, + 0x006ABE, 0x006AC1, 0x000000, 0xFFFFFF, + 0x006AC4, 0x006AC4, 0x000000, 0xFFFFFF, + 0x006AC8, 0x006ACA, 0x000000, 0xFFFFFF, + 0x006ACE, 0x006ACE, 0x000000, 0xFFFFFF, + 0x006AD2, 0x006AD2, 0x000000, 0xFFFFFF, + 0x006AD4, 0x006AD8, 0x000000, 0xFFFFFF, + 0x006AE2, 0x006AE4, 0x000000, 0xFFFFFF, + 0x006AE6, 0x006AE6, 0x000000, 0xFFFFFF, + 0x006AE9, 0x006AE9, 0x000000, 0xFFFFFF, + 0x006AED, 0x006AED, 0x000000, 0xFFFFFF, + 0x006AF2, 0x006AF2, 0x000000, 0xFFFFFF, + 0x006AF4, 0x006AF7, 0x000000, 0xFFFFFF, + 0x006AFD, 0x006AFF, 0x000000, 0xFFFFFF, + 0x006B01, 0x006B01, 0x000000, 0xFFFFFF, + 0x006B05, 0x006B07, 0x000000, 0xFFFFFF, + 0x006B0C, 0x006B0E, 0x000000, 0xFFFFFF, + 0x006B14, 0x006B15, 0x000000, 0xFFFFFF, + 0x006B1B, 0x006B1D, 0x000000, 0xFFFFFF, + 0x006B1F, 0x006B1F, 0x000000, 0xFFFFFF, + 0x006B22, 0x006B22, 0x000000, 0xFFFFFF, + 0x006B24, 0x006B24, 0x000000, 0xFFFFFF, + 0x006B26, 0x006B27, 0x000000, 0xFFFFFF, + 0x006B29, 0x006B2B, 0x000000, 0xFFFFFF, + 0x006B2E, 0x006B2E, 0x000000, 0xFFFFFF, + 0x006B30, 0x006B30, 0x000000, 0xFFFFFF, + 0x006B35, 0x006B35, 0x000000, 0xFFFFFF, + 0x006B40, 0x006B40, 0x000000, 0xFFFFFF, + 0x006B44, 0x006B44, 0x000000, 0xFFFFFF, + 0x006B4F, 0x006B4F, 0x000000, 0xFFFFFF, + 0x006B52, 0x006B53, 0x000000, 0xFFFFFF, + 0x006B57, 0x006B58, 0x000000, 0xFFFFFF, + 0x006B5A, 0x006B5A, 0x000000, 0xFFFFFF, + 0x006B5D, 0x006B5D, 0x000000, 0xFFFFFF, + 0x006B68, 0x006B69, 0x000000, 0xFFFFFF, + 0x006B6B, 0x006B6C, 0x000000, 0xFFFFFF, + 0x006B6E, 0x006B71, 0x000000, 0xFFFFFF, + 0x006B73, 0x006B75, 0x000000, 0xFFFFFF, + 0x006B7A, 0x006B7A, 0x000000, 0xFFFFFF, + 0x006B7C, 0x006B7D, 0x000000, 0xFFFFFF, + 0x006B81, 0x006B81, 0x000000, 0xFFFFFF, + 0x006B85, 0x006B85, 0x000000, 0xFFFFFF, + 0x006B87, 0x006B87, 0x000000, 0xFFFFFF, + 0x006B8B, 0x006B8B, 0x000000, 0xFFFFFF, + 0x006B90, 0x006B90, 0x000000, 0xFFFFFF, + 0x006B92, 0x006B93, 0x000000, 0xFFFFFF, + 0x006B9A, 0x006B9A, 0x000000, 0xFFFFFF, + 0x006B9C, 0x006B9D, 0x000000, 0xFFFFFF, + 0x006BA1, 0x006BA1, 0x000000, 0xFFFFFF, + 0x006BA8, 0x006BA9, 0x000000, 0xFFFFFF, + 0x006BAC, 0x006BAC, 0x000000, 0xFFFFFF, + 0x006BB1, 0x006BB1, 0x000000, 0xFFFFFF, + 0x006BB4, 0x006BB4, 0x000000, 0xFFFFFF, + 0x006BB8, 0x006BB9, 0x000000, 0xFFFFFF, + 0x006BBB, 0x006BBB, 0x000000, 0xFFFFFF, + 0x006BBE, 0x006BBE, 0x000000, 0xFFFFFF, + 0x006BC1, 0x006BC2, 0x000000, 0xFFFFFF, + 0x006BCE, 0x006BCE, 0x000000, 0xFFFFFF, + 0x006BD1, 0x006BD1, 0x000000, 0xFFFFFF, + 0x006BD5, 0x006BD5, 0x000000, 0xFFFFFF, + 0x006BD9, 0x006BD9, 0x000000, 0xFFFFFF, + 0x006BDC, 0x006BDD, 0x000000, 0xFFFFFF, + 0x006BDF, 0x006BDF, 0x000000, 0xFFFFFF, + 0x006BE1, 0x006BE1, 0x000000, 0xFFFFFF, + 0x006BE5, 0x006BE5, 0x000000, 0xFFFFFF, + 0x006BE9, 0x006BEA, 0x000000, 0xFFFFFF, + 0x006BED, 0x006BEE, 0x000000, 0xFFFFFF, + 0x006BF1, 0x006BF1, 0x000000, 0xFFFFFF, + 0x006BF4, 0x006BF6, 0x000000, 0xFFFFFF, + 0x006BFA, 0x006BFA, 0x000000, 0xFFFFFF, + 0x006C07, 0x006C07, 0x000000, 0xFFFFFF, + 0x006C0A, 0x006C0A, 0x000000, 0xFFFFFF, + 0x006C0E, 0x006C0E, 0x000000, 0xFFFFFF, + 0x006C12, 0x006C12, 0x000000, 0xFFFFFF, + 0x006C17, 0x006C17, 0x000000, 0xFFFFFF, + 0x006C1C, 0x006C1C, 0x000000, 0xFFFFFF, + 0x006C1E, 0x006C1E, 0x000000, 0xFFFFFF, + 0x006C22, 0x006C22, 0x000000, 0xFFFFFF, + 0x006C29, 0x006C29, 0x000000, 0xFFFFFF, + 0x006C2D, 0x006C2D, 0x000000, 0xFFFFFF, + 0x006C31, 0x006C32, 0x000000, 0xFFFFFF, + 0x006C35, 0x006C35, 0x000000, 0xFFFFFF, + 0x006C37, 0x006C37, 0x000000, 0xFFFFFF, + 0x006C39, 0x006C3A, 0x000000, 0xFFFFFF, + 0x006C3C, 0x006C3D, 0x000000, 0xFFFFFF, + 0x006C44, 0x006C45, 0x000000, 0xFFFFFF, + 0x006C47, 0x006C49, 0x000000, 0xFFFFFF, + 0x006C51, 0x006C51, 0x000000, 0xFFFFFF, + 0x006C53, 0x006C53, 0x000000, 0xFFFFFF, + 0x006C56, 0x006C56, 0x000000, 0xFFFFFF, + 0x006C58, 0x006C58, 0x000000, 0xFFFFFF, + 0x006C5A, 0x006C5A, 0x000000, 0xFFFFFF, + 0x006C62, 0x006C64, 0x000000, 0xFFFFFF, + 0x006C6C, 0x006C6C, 0x000000, 0xFFFFFF, + 0x006C6E, 0x006C6E, 0x000000, 0xFFFFFF, + 0x006C75, 0x006C75, 0x000000, 0xFFFFFF, + 0x006C77, 0x006C77, 0x000000, 0xFFFFFF, + 0x006C79, 0x006C79, 0x000000, 0xFFFFFF, + 0x006C7C, 0x006C7C, 0x000000, 0xFFFFFF, + 0x006C7F, 0x006C7F, 0x000000, 0xFFFFFF, + 0x006C91, 0x006C91, 0x000000, 0xFFFFFF, + 0x006C97, 0x006C97, 0x000000, 0xFFFFFF, + 0x006C9E, 0x006CAA, 0x000000, 0xFFFFFF, + 0x006CAF, 0x006CAF, 0x000000, 0xFFFFFF, + 0x006CB2, 0x006CB2, 0x000000, 0xFFFFFF, + 0x006CB5, 0x006CB5, 0x000000, 0xFFFFFF, + 0x006CC8, 0x006CC8, 0x000000, 0xFFFFFF, + 0x006CCB, 0x006CCB, 0x000000, 0xFFFFFF, + 0x006CCE, 0x006CCE, 0x000000, 0xFFFFFF, + 0x006CD8, 0x006CD8, 0x000000, 0xFFFFFF, + 0x006CDF, 0x006CDF, 0x000000, 0xFFFFFF, + 0x006CE4, 0x006CE4, 0x000000, 0xFFFFFF, + 0x006CE6, 0x006CE6, 0x000000, 0xFFFFFF, + 0x006CEA, 0x006CEA, 0x000000, 0xFFFFFF, + 0x006CF4, 0x006CF4, 0x000000, 0xFFFFFF, + 0x006CF6, 0x006CF8, 0x000000, 0xFFFFFF, + 0x006CFA, 0x006CFF, 0x000000, 0xFFFFFF, + 0x006D02, 0x006D02, 0x000000, 0xFFFFFF, + 0x006D05, 0x006D06, 0x000000, 0xFFFFFF, + 0x006D13, 0x006D15, 0x000000, 0xFFFFFF, + 0x006D1C, 0x006D1C, 0x000000, 0xFFFFFF, + 0x006D21, 0x006D21, 0x000000, 0xFFFFFF, + 0x006D23, 0x006D24, 0x000000, 0xFFFFFF, + 0x006D26, 0x006D26, 0x000000, 0xFFFFFF, + 0x006D43, 0x006D57, 0x000000, 0xFFFFFF, + 0x006D5B, 0x006D5D, 0x000000, 0xFFFFFF, + 0x006D6B, 0x006D6B, 0x000000, 0xFFFFFF, + 0x006D71, 0x006D73, 0x000000, 0xFFFFFF, + 0x006D81, 0x006D81, 0x000000, 0xFFFFFF, + 0x006D8F, 0x006D8F, 0x000000, 0xFFFFFF, + 0x006D96, 0x006D96, 0x000000, 0xFFFFFF, + 0x006D99, 0x006DA9, 0x000000, 0xFFFFFF, + 0x006DAD, 0x006DAD, 0x000000, 0xFFFFFF, + 0x006DB0, 0x006DB1, 0x000000, 0xFFFFFF, + 0x006DB6, 0x006DB6, 0x000000, 0xFFFFFF, + 0x006DB9, 0x006DB9, 0x000000, 0xFFFFFF, + 0x006DC1, 0x006DC1, 0x000000, 0xFFFFFF, + 0x006DC3, 0x006DC3, 0x000000, 0xFFFFFF, + 0x006DCE, 0x006DCE, 0x000000, 0xFFFFFF, + 0x006DE7, 0x006DE7, 0x000000, 0xFFFFFF, + 0x006DF8, 0x006DF8, 0x000000, 0xFFFFFF, + 0x006DFE, 0x006DFF, 0x000000, 0xFFFFFF, + 0x006E01, 0x006E02, 0x000000, 0xFFFFFF, + 0x006E04, 0x006E04, 0x000000, 0xFFFFFF, + 0x006E06, 0x006E18, 0x000000, 0xFFFFFF, + 0x006E1E, 0x006E1E, 0x000000, 0xFFFFFF, + 0x006E29, 0x006E2A, 0x000000, 0xFFFFFF, + 0x006E37, 0x006E37, 0x000000, 0xFFFFFF, + 0x006E42, 0x006E42, 0x000000, 0xFFFFFF, + 0x006E48, 0x006E48, 0x000000, 0xFFFFFF, + 0x006E4C, 0x006E4C, 0x000000, 0xFFFFFF, + 0x006E4F, 0x006E50, 0x000000, 0xFFFFFF, + 0x006E57, 0x006E57, 0x000000, 0xFFFFFF, + 0x006E59, 0x006E59, 0x000000, 0xFFFFFF, + 0x006E6A, 0x006E6A, 0x000000, 0xFFFFFF, + 0x006E6C, 0x006E6D, 0x000000, 0xFFFFFF, + 0x006E70, 0x006E70, 0x000000, 0xFFFFFF, + 0x006E75, 0x006E76, 0x000000, 0xFFFFFF, + 0x006E7A, 0x006E87, 0x000000, 0xFFFFFF, + 0x006E8A, 0x006E8C, 0x000000, 0xFFFFFF, + 0x006E91, 0x006E91, 0x000000, 0xFFFFFF, + 0x006E95, 0x006E95, 0x000000, 0xFFFFFF, + 0x006E9A, 0x006E9A, 0x000000, 0xFFFFFF, + 0x006EA8, 0x006EA9, 0x000000, 0xFFFFFF, + 0x006EAC, 0x006EAD, 0x000000, 0xFFFFFF, + 0x006EB5, 0x006EB5, 0x000000, 0xFFFFFF, + 0x006EB8, 0x006EB8, 0x000000, 0xFFFFFF, + 0x006EBB, 0x006EBB, 0x000000, 0xFFFFFF, + 0x006ED7, 0x006ED7, 0x000000, 0xFFFFFF, + 0x006ED9, 0x006EDB, 0x000000, 0xFFFFFF, + 0x006EDD, 0x006EEA, 0x000000, 0xFFFFFF, + 0x006EF0, 0x006EF0, 0x000000, 0xFFFFFF, + 0x006EF3, 0x006EF3, 0x000000, 0xFFFFFF, + 0x006EFA, 0x006EFA, 0x000000, 0xFFFFFF, + 0x006F04, 0x006F04, 0x000000, 0xFFFFFF, + 0x006F0B, 0x006F0C, 0x000000, 0xFFFFFF, + 0x006F10, 0x006F11, 0x000000, 0xFFFFFF, + 0x006F16, 0x006F17, 0x000000, 0xFFFFFF, + 0x006F1B, 0x006F1B, 0x000000, 0xFFFFFF, + 0x006F1D, 0x006F1D, 0x000000, 0xFFFFFF, + 0x006F24, 0x006F24, 0x000000, 0xFFFFFF, + 0x006F28, 0x006F28, 0x000000, 0xFFFFFF, + 0x006F34, 0x006F34, 0x000000, 0xFFFFFF, + 0x006F3D, 0x006F3D, 0x000000, 0xFFFFFF, + 0x006F42, 0x006F42, 0x000000, 0xFFFFFF, + 0x006F44, 0x006F4D, 0x000000, 0xFFFFFF, + 0x006F56, 0x006F56, 0x000000, 0xFFFFFF, + 0x006F59, 0x006F59, 0x000000, 0xFFFFFF, + 0x006F5C, 0x006F5C, 0x000000, 0xFFFFFF, + 0x006F65, 0x006F65, 0x000000, 0xFFFFFF, + 0x006F68, 0x006F68, 0x000000, 0xFFFFFF, + 0x006F71, 0x006F71, 0x000000, 0xFFFFFF, + 0x006F74, 0x006F75, 0x000000, 0xFFFFFF, + 0x006F79, 0x006F79, 0x000000, 0xFFFFFF, + 0x006F81, 0x006F81, 0x000000, 0xFFFFFF, + 0x006F83, 0x006F83, 0x000000, 0xFFFFFF, + 0x006F8A, 0x006F8A, 0x000000, 0xFFFFFF, + 0x006F8F, 0x006F8F, 0x000000, 0xFFFFFF, + 0x006F91, 0x006F91, 0x000000, 0xFFFFFF, + 0x006F98, 0x006F9D, 0x000000, 0xFFFFFF, + 0x006F9F, 0x006F9F, 0x000000, 0xFFFFFF, + 0x006FB5, 0x006FB5, 0x000000, 0xFFFFFF, + 0x006FB7, 0x006FB7, 0x000000, 0xFFFFFF, + 0x006FBB, 0x006FBB, 0x000000, 0xFFFFFF, + 0x006FBE, 0x006FBE, 0x000000, 0xFFFFFF, + 0x006FC5, 0x006FC5, 0x000000, 0xFFFFFF, + 0x006FD0, 0x006FD3, 0x000000, 0xFFFFFF, + 0x006FD6, 0x006FD7, 0x000000, 0xFFFFFF, + 0x006FD9, 0x006FDA, 0x000000, 0xFFFFFF, + 0x006FE5, 0x006FE5, 0x000000, 0xFFFFFF, + 0x006FEA, 0x006FEA, 0x000000, 0xFFFFFF, + 0x006FF3, 0x006FF3, 0x000000, 0xFFFFFF, + 0x006FF5, 0x006FF6, 0x000000, 0xFFFFFF, + 0x006FF8, 0x006FF9, 0x000000, 0xFFFFFF, + 0x006FFD, 0x006FFD, 0x000000, 0xFFFFFF, + 0x007002, 0x007003, 0x000000, 0xFFFFFF, + 0x007008, 0x007008, 0x000000, 0xFFFFFF, + 0x007010, 0x007010, 0x000000, 0xFFFFFF, + 0x007012, 0x007013, 0x000000, 0xFFFFFF, + 0x00701E, 0x00701E, 0x000000, 0xFFFFFF, + 0x007025, 0x007025, 0x000000, 0xFFFFFF, + 0x00702C, 0x00702E, 0x000000, 0xFFFFFF, + 0x007036, 0x007036, 0x000000, 0xFFFFFF, + 0x00703D, 0x00703D, 0x000000, 0xFFFFFF, + 0x007047, 0x007047, 0x000000, 0xFFFFFF, + 0x00704B, 0x00704B, 0x000000, 0xFFFFFF, + 0x00704D, 0x007050, 0x000000, 0xFFFFFF, + 0x007053, 0x007054, 0x000000, 0xFFFFFF, + 0x007059, 0x007059, 0x000000, 0xFFFFFF, + 0x00705C, 0x00705C, 0x000000, 0xFFFFFF, + 0x007067, 0x007067, 0x000000, 0xFFFFFF, + 0x00706C, 0x00706F, 0x000000, 0xFFFFFF, + 0x007072, 0x007073, 0x000000, 0xFFFFFF, + 0x007075, 0x007075, 0x000000, 0xFFFFFF, + 0x007077, 0x007077, 0x000000, 0xFFFFFF, + 0x007079, 0x007079, 0x000000, 0xFFFFFF, + 0x00707B, 0x00707B, 0x000000, 0xFFFFFF, + 0x00707E, 0x007081, 0x000000, 0xFFFFFF, + 0x007087, 0x007089, 0x000000, 0xFFFFFF, + 0x00708B, 0x00708D, 0x000000, 0xFFFFFF, + 0x00708F, 0x007090, 0x000000, 0xFFFFFF, + 0x007097, 0x007097, 0x000000, 0xFFFFFF, + 0x00709B, 0x00709E, 0x000000, 0xFFFFFF, + 0x0070A0, 0x0070A0, 0x000000, 0xFFFFFF, + 0x0070A2, 0x0070A3, 0x000000, 0xFFFFFF, + 0x0070A5, 0x0070A8, 0x000000, 0xFFFFFF, + 0x0070AA, 0x0070AA, 0x000000, 0xFFFFFF, + 0x0070B2, 0x0070B2, 0x000000, 0xFFFFFF, + 0x0070B6, 0x0070B6, 0x000000, 0xFFFFFF, + 0x0070B9, 0x0070B9, 0x000000, 0xFFFFFF, + 0x0070BB, 0x0070BD, 0x000000, 0xFFFFFF, + 0x0070BF, 0x0070C4, 0x000000, 0xFFFFFF, + 0x0070C9, 0x0070C9, 0x000000, 0xFFFFFF, + 0x0070CC, 0x0070CC, 0x000000, 0xFFFFFF, + 0x0070D0, 0x0070D0, 0x000000, 0xFFFFFF, + 0x0070D5, 0x0070D6, 0x000000, 0xFFFFFF, + 0x0070DB, 0x0070DB, 0x000000, 0xFFFFFF, + 0x0070DF, 0x0070DF, 0x000000, 0xFFFFFF, + 0x0070E3, 0x0070E3, 0x000000, 0xFFFFFF, + 0x0070E5, 0x0070EE, 0x000000, 0xFFFFFF, + 0x0070F1, 0x0070F2, 0x000000, 0xFFFFFF, + 0x0070F5, 0x0070F5, 0x000000, 0xFFFFFF, + 0x0070FE, 0x0070FE, 0x000000, 0xFFFFFF, + 0x007101, 0x007101, 0x000000, 0xFFFFFF, + 0x007103, 0x007103, 0x000000, 0xFFFFFF, + 0x007105, 0x007105, 0x000000, 0xFFFFFF, + 0x007107, 0x007108, 0x000000, 0xFFFFFF, + 0x00710F, 0x00710F, 0x000000, 0xFFFFFF, + 0x007111, 0x007112, 0x000000, 0xFFFFFF, + 0x007114, 0x007116, 0x000000, 0xFFFFFF, + 0x007118, 0x007118, 0x000000, 0xFFFFFF, + 0x00711D, 0x00711D, 0x000000, 0xFFFFFF, + 0x007124, 0x007124, 0x000000, 0xFFFFFF, + 0x007127, 0x007127, 0x000000, 0xFFFFFF, + 0x007129, 0x00712D, 0x000000, 0xFFFFFF, + 0x007133, 0x007135, 0x000000, 0xFFFFFF, + 0x007137, 0x007139, 0x000000, 0xFFFFFF, + 0x00713B, 0x007140, 0x000000, 0xFFFFFF, + 0x007145, 0x007145, 0x000000, 0xFFFFFF, + 0x007148, 0x007148, 0x000000, 0xFFFFFF, + 0x00714A, 0x00714A, 0x000000, 0xFFFFFF, + 0x00714F, 0x00714F, 0x000000, 0xFFFFFF, + 0x007151, 0x007151, 0x000000, 0xFFFFFF, + 0x007155, 0x007155, 0x000000, 0xFFFFFF, + 0x007157, 0x007157, 0x000000, 0xFFFFFF, + 0x00715B, 0x00715B, 0x000000, 0xFFFFFF, + 0x00716B, 0x00716B, 0x000000, 0xFFFFFF, + 0x00716D, 0x00716D, 0x000000, 0xFFFFFF, + 0x00716F, 0x00716F, 0x000000, 0xFFFFFF, + 0x007171, 0x007171, 0x000000, 0xFFFFFF, + 0x007173, 0x007177, 0x000000, 0xFFFFFF, + 0x007179, 0x00717A, 0x000000, 0xFFFFFF, + 0x00717C, 0x00717C, 0x000000, 0xFFFFFF, + 0x00717E, 0x00717F, 0x000000, 0xFFFFFF, + 0x007183, 0x007183, 0x000000, 0xFFFFFF, + 0x007188, 0x007188, 0x000000, 0xFFFFFF, + 0x00718B, 0x00718E, 0x000000, 0xFFFFFF, + 0x007191, 0x007191, 0x000000, 0xFFFFFF, + 0x007193, 0x007193, 0x000000, 0xFFFFFF, + 0x007195, 0x007196, 0x000000, 0xFFFFFF, + 0x007198, 0x007198, 0x000000, 0xFFFFFF, + 0x0071A2, 0x0071A3, 0x000000, 0xFFFFFF, + 0x0071A6, 0x0071A6, 0x000000, 0xFFFFFF, + 0x0071AB, 0x0071AB, 0x000000, 0xFFFFFF, + 0x0071AD, 0x0071AE, 0x000000, 0xFFFFFF, + 0x0071B4, 0x0071B4, 0x000000, 0xFFFFFF, + 0x0071B6, 0x0071B7, 0x000000, 0xFFFFFF, + 0x0071BA, 0x0071BB, 0x000000, 0xFFFFFF, + 0x0071CC, 0x0071CD, 0x000000, 0xFFFFFF, + 0x0071D1, 0x0071D1, 0x000000, 0xFFFFFF, + 0x0071D3, 0x0071D3, 0x000000, 0xFFFFFF, + 0x0071D7, 0x0071D7, 0x000000, 0xFFFFFF, + 0x0071DD, 0x0071DE, 0x000000, 0xFFFFFF, + 0x0071E3, 0x0071E3, 0x000000, 0xFFFFFF, + 0x0071E9, 0x0071EB, 0x000000, 0xFFFFFF, + 0x0071EF, 0x0071EF, 0x000000, 0xFFFFFF, + 0x0071F3, 0x0071F3, 0x000000, 0xFFFFFF, + 0x0071F5, 0x0071F7, 0x000000, 0xFFFFFF, + 0x0071FA, 0x0071FA, 0x000000, 0xFFFFFF, + 0x007200, 0x007200, 0x000000, 0xFFFFFF, + 0x007204, 0x007204, 0x000000, 0xFFFFFF, + 0x007208, 0x007209, 0x000000, 0xFFFFFF, + 0x00720B, 0x00720B, 0x000000, 0xFFFFFF, + 0x00720E, 0x00720F, 0x000000, 0xFFFFFF, + 0x007211, 0x007212, 0x000000, 0xFFFFFF, + 0x007215, 0x007218, 0x000000, 0xFFFFFF, + 0x00721C, 0x00721C, 0x000000, 0xFFFFFF, + 0x007220, 0x007221, 0x000000, 0xFFFFFF, + 0x007224, 0x007225, 0x000000, 0xFFFFFF, + 0x00722B, 0x00722B, 0x000000, 0xFFFFFF, + 0x00722E, 0x00722F, 0x000000, 0xFFFFFF, + 0x007231, 0x007234, 0x000000, 0xFFFFFF, + 0x007237, 0x007237, 0x000000, 0xFFFFFF, + 0x00723C, 0x00723C, 0x000000, 0xFFFFFF, + 0x007240, 0x007240, 0x000000, 0xFFFFFF, + 0x007243, 0x007243, 0x000000, 0xFFFFFF, + 0x007245, 0x007245, 0x000000, 0xFFFFFF, + 0x00724D, 0x00724E, 0x000000, 0xFFFFFF, + 0x007250, 0x007251, 0x000000, 0xFFFFFF, + 0x007254, 0x007255, 0x000000, 0xFFFFFF, + 0x007257, 0x007257, 0x000000, 0xFFFFFF, + 0x00725C, 0x00725C, 0x000000, 0xFFFFFF, + 0x007264, 0x007266, 0x000000, 0xFFFFFF, + 0x007268, 0x007268, 0x000000, 0xFFFFFF, + 0x00726B, 0x00726B, 0x000000, 0xFFFFFF, + 0x00726D, 0x00726D, 0x000000, 0xFFFFFF, + 0x007271, 0x007271, 0x000000, 0xFFFFFF, + 0x007275, 0x007275, 0x000000, 0xFFFFFF, + 0x00727A, 0x00727A, 0x000000, 0xFFFFFF, + 0x007282, 0x007283, 0x000000, 0xFFFFFF, + 0x007287, 0x007287, 0x000000, 0xFFFFFF, + 0x00728A, 0x00728A, 0x000000, 0xFFFFFF, + 0x00728F, 0x00728F, 0x000000, 0xFFFFFF, + 0x007294, 0x007294, 0x000000, 0xFFFFFF, + 0x007299, 0x007299, 0x000000, 0xFFFFFF, + 0x00729C, 0x00729C, 0x000000, 0xFFFFFF, + 0x00729F, 0x0072A0, 0x000000, 0xFFFFFF, + 0x0072AB, 0x0072AB, 0x000000, 0xFFFFFF, + 0x0072AD, 0x0072AD, 0x000000, 0xFFFFFF, + 0x0072B1, 0x0072B3, 0x000000, 0xFFFFFF, + 0x0072B6, 0x0072B9, 0x000000, 0xFFFFFF, + 0x0072BB, 0x0072BC, 0x000000, 0xFFFFFF, + 0x0072BE, 0x0072BE, 0x000000, 0xFFFFFF, + 0x0072C7, 0x0072C8, 0x000000, 0xFFFFFF, + 0x0072CD, 0x0072CD, 0x000000, 0xFFFFFF, + 0x0072CF, 0x0072CF, 0x000000, 0xFFFFFF, + 0x0072D3, 0x0072D3, 0x000000, 0xFFFFFF, + 0x0072D5, 0x0072D5, 0x000000, 0xFFFFFF, + 0x0072DB, 0x0072DB, 0x000000, 0xFFFFFF, + 0x0072DD, 0x0072DE, 0x000000, 0xFFFFFF, + 0x0072E2, 0x0072E2, 0x000000, 0xFFFFFF, + 0x0072E5, 0x0072E5, 0x000000, 0xFFFFFF, + 0x0072E7, 0x0072E7, 0x000000, 0xFFFFFF, + 0x0072EC, 0x0072F2, 0x000000, 0xFFFFFF, + 0x0072F5, 0x0072F5, 0x000000, 0xFFFFFF, + 0x007302, 0x007306, 0x000000, 0xFFFFFF, + 0x007309, 0x007309, 0x000000, 0xFFFFFF, + 0x00730D, 0x00730E, 0x000000, 0xFFFFFF, + 0x007310, 0x007310, 0x000000, 0xFFFFFF, + 0x007314, 0x007315, 0x000000, 0xFFFFFF, + 0x00731A, 0x00731A, 0x000000, 0xFFFFFF, + 0x00731F, 0x007321, 0x000000, 0xFFFFFF, + 0x007324, 0x007324, 0x000000, 0xFFFFFF, + 0x007328, 0x007328, 0x000000, 0xFFFFFF, + 0x00732A, 0x00732C, 0x000000, 0xFFFFFF, + 0x00732E, 0x00732F, 0x000000, 0xFFFFFF, + 0x007338, 0x007339, 0x000000, 0xFFFFFF, + 0x00733D, 0x00733D, 0x000000, 0xFFFFFF, + 0x007341, 0x007341, 0x000000, 0xFFFFFF, + 0x007346, 0x007348, 0x000000, 0xFFFFFF, + 0x00734B, 0x00734B, 0x000000, 0xFFFFFF, + 0x00734F, 0x00734F, 0x000000, 0xFFFFFF, + 0x007353, 0x007356, 0x000000, 0xFFFFFF, + 0x00735C, 0x00735C, 0x000000, 0xFFFFFF, + 0x007363, 0x007364, 0x000000, 0xFFFFFF, + 0x00736D, 0x00736D, 0x000000, 0xFFFFFF, + 0x007371, 0x007371, 0x000000, 0xFFFFFF, + 0x007374, 0x007374, 0x000000, 0xFFFFFF, + 0x007379, 0x007379, 0x000000, 0xFFFFFF, + 0x00738C, 0x00738D, 0x000000, 0xFFFFFF, + 0x00738F, 0x007391, 0x000000, 0xFFFFFF, + 0x007398, 0x00739C, 0x000000, 0xFFFFFF, + 0x00739E, 0x00739E, 0x000000, 0xFFFFFF, + 0x0073A3, 0x0073A3, 0x000000, 0xFFFFFF, + 0x0073A7, 0x0073A7, 0x000000, 0xFFFFFF, + 0x0073AA, 0x0073AA, 0x000000, 0xFFFFFF, + 0x0073AE, 0x0073B1, 0x000000, 0xFFFFFF, + 0x0073BA, 0x0073BA, 0x000000, 0xFFFFFF, + 0x0073BD, 0x0073BD, 0x000000, 0xFFFFFF, + 0x0073C1, 0x0073C1, 0x000000, 0xFFFFFF, + 0x0073C4, 0x0073C4, 0x000000, 0xFFFFFF, + 0x0073C9, 0x0073C9, 0x000000, 0xFFFFFF, + 0x0073CE, 0x0073D1, 0x000000, 0xFFFFFF, + 0x0073D5, 0x0073D5, 0x000000, 0xFFFFFF, + 0x0073DF, 0x0073DF, 0x000000, 0xFFFFFF, + 0x0073E1, 0x0073E2, 0x000000, 0xFFFFFF, + 0x0073E4, 0x0073E4, 0x000000, 0xFFFFFF, + 0x0073E6, 0x0073E6, 0x000000, 0xFFFFFF, + 0x0073EC, 0x0073EC, 0x000000, 0xFFFFFF, + 0x0073EF, 0x0073F3, 0x000000, 0xFFFFFF, + 0x0073F7, 0x0073F7, 0x000000, 0xFFFFFF, + 0x0073F9, 0x0073F9, 0x000000, 0xFFFFFF, + 0x0073FB, 0x0073FB, 0x000000, 0xFFFFFF, + 0x007402, 0x007402, 0x000000, 0xFFFFFF, + 0x00740E, 0x007415, 0x000000, 0xFFFFFF, + 0x007417, 0x007419, 0x000000, 0xFFFFFF, + 0x00741C, 0x00741C, 0x000000, 0xFFFFFF, + 0x00741E, 0x00741F, 0x000000, 0xFFFFFF, + 0x007427, 0x007427, 0x000000, 0xFFFFFF, + 0x007437, 0x007439, 0x000000, 0xFFFFFF, + 0x00743B, 0x00743E, 0x000000, 0xFFFFFF, + 0x007443, 0x007443, 0x000000, 0xFFFFFF, + 0x007445, 0x007445, 0x000000, 0xFFFFFF, + 0x007447, 0x007449, 0x000000, 0xFFFFFF, + 0x00744C, 0x00744C, 0x000000, 0xFFFFFF, + 0x007453, 0x007453, 0x000000, 0xFFFFFF, + 0x007456, 0x007456, 0x000000, 0xFFFFFF, + 0x007458, 0x007458, 0x000000, 0xFFFFFF, + 0x00745D, 0x00745D, 0x000000, 0xFFFFFF, + 0x007460, 0x007461, 0x000000, 0xFFFFFF, + 0x007465, 0x007466, 0x000000, 0xFFFFFF, + 0x007468, 0x007468, 0x000000, 0xFFFFFF, + 0x00746B, 0x00746C, 0x000000, 0xFFFFFF, + 0x007474, 0x007474, 0x000000, 0xFFFFFF, + 0x007476, 0x007478, 0x000000, 0xFFFFFF, + 0x00747A, 0x00747B, 0x000000, 0xFFFFFF, + 0x007482, 0x007482, 0x000000, 0xFFFFFF, + 0x007484, 0x007484, 0x000000, 0xFFFFFF, + 0x00748C, 0x00748F, 0x000000, 0xFFFFFF, + 0x007491, 0x007491, 0x000000, 0xFFFFFF, + 0x007493, 0x007493, 0x000000, 0xFFFFFF, + 0x007496, 0x007496, 0x000000, 0xFFFFFF, + 0x007499, 0x007499, 0x000000, 0xFFFFFF, + 0x00749B, 0x00749B, 0x000000, 0xFFFFFF, + 0x00749D, 0x00749D, 0x000000, 0xFFFFFF, + 0x0074A2, 0x0074A2, 0x000000, 0xFFFFFF, + 0x0074A4, 0x0074A4, 0x000000, 0xFFFFFF, + 0x0074AC, 0x0074AC, 0x000000, 0xFFFFFF, + 0x0074AE, 0x0074AE, 0x000000, 0xFFFFFF, + 0x0074B3, 0x0074B4, 0x000000, 0xFFFFFF, + 0x0074B9, 0x0074B9, 0x000000, 0xFFFFFF, + 0x0074BC, 0x0074BC, 0x000000, 0xFFFFFF, + 0x0074C4, 0x0074C4, 0x000000, 0xFFFFFF, + 0x0074C6, 0x0074C9, 0x000000, 0xFFFFFF, + 0x0074CC, 0x0074CE, 0x000000, 0xFFFFFF, + 0x0074D0, 0x0074D3, 0x000000, 0xFFFFFF, + 0x0074E7, 0x0074E7, 0x000000, 0xFFFFFF, + 0x0074EA, 0x0074EB, 0x000000, 0xFFFFFF, + 0x0074ED, 0x0074ED, 0x000000, 0xFFFFFF, + 0x0074EF, 0x0074F3, 0x000000, 0xFFFFFF, + 0x0074F8, 0x0074FA, 0x000000, 0xFFFFFF, + 0x0074FC, 0x0074FC, 0x000000, 0xFFFFFF, + 0x007501, 0x007501, 0x000000, 0xFFFFFF, + 0x007505, 0x007506, 0x000000, 0xFFFFFF, + 0x007509, 0x00750A, 0x000000, 0xFFFFFF, + 0x00750E, 0x00750E, 0x000000, 0xFFFFFF, + 0x007519, 0x007519, 0x000000, 0xFFFFFF, + 0x00751B, 0x00751B, 0x000000, 0xFFFFFF, + 0x00751E, 0x00751E, 0x000000, 0xFFFFFF, + 0x007520, 0x007520, 0x000000, 0xFFFFFF, + 0x007523, 0x007524, 0x000000, 0xFFFFFF, + 0x007527, 0x007527, 0x000000, 0xFFFFFF, + 0x007534, 0x007536, 0x000000, 0xFFFFFF, + 0x00753B, 0x00753C, 0x000000, 0xFFFFFF, + 0x007541, 0x007546, 0x000000, 0xFFFFFF, + 0x007549, 0x00754A, 0x000000, 0xFFFFFF, + 0x00754D, 0x00754D, 0x000000, 0xFFFFFF, + 0x007550, 0x007553, 0x000000, 0xFFFFFF, + 0x007555, 0x007558, 0x000000, 0xFFFFFF, + 0x00755E, 0x00755E, 0x000000, 0xFFFFFF, + 0x007560, 0x007561, 0x000000, 0xFFFFFF, + 0x007567, 0x007569, 0x000000, 0xFFFFFF, + 0x00756D, 0x00756E, 0x000000, 0xFFFFFF, + 0x007571, 0x007575, 0x000000, 0xFFFFFF, + 0x00757A, 0x00757C, 0x000000, 0xFFFFFF, + 0x007581, 0x007583, 0x000000, 0xFFFFFF, + 0x007585, 0x007585, 0x000000, 0xFFFFFF, + 0x007588, 0x007589, 0x000000, 0xFFFFFF, + 0x00758D, 0x00758E, 0x000000, 0xFFFFFF, + 0x007592, 0x007593, 0x000000, 0xFFFFFF, + 0x007596, 0x007597, 0x000000, 0xFFFFFF, + 0x00759B, 0x00759C, 0x000000, 0xFFFFFF, + 0x00759E, 0x0075A1, 0x000000, 0xFFFFFF, + 0x0075A6, 0x0075A6, 0x000000, 0xFFFFFF, + 0x0075A8, 0x0075A9, 0x000000, 0xFFFFFF, + 0x0075AC, 0x0075AF, 0x000000, 0xFFFFFF, + 0x0075B1, 0x0075B1, 0x000000, 0xFFFFFF, + 0x0075B4, 0x0075B4, 0x000000, 0xFFFFFF, + 0x0075B7, 0x0075B7, 0x000000, 0xFFFFFF, + 0x0075C3, 0x0075C3, 0x000000, 0xFFFFFF, + 0x0075C6, 0x0075C6, 0x000000, 0xFFFFFF, + 0x0075C8, 0x0075C9, 0x000000, 0xFFFFFF, + 0x0075D3, 0x0075D3, 0x000000, 0xFFFFFF, + 0x0075D6, 0x0075D6, 0x000000, 0xFFFFFF, + 0x0075DC, 0x0075DC, 0x000000, 0xFFFFFF, + 0x0075E5, 0x0075E5, 0x000000, 0xFFFFFF, + 0x0075E8, 0x0075EC, 0x000000, 0xFFFFFF, + 0x0075EE, 0x0075EE, 0x000000, 0xFFFFFF, + 0x007602, 0x007602, 0x000000, 0xFFFFFF, + 0x007604, 0x007607, 0x000000, 0xFFFFFF, + 0x00760E, 0x00760E, 0x000000, 0xFFFFFF, + 0x007612, 0x007612, 0x000000, 0xFFFFFF, + 0x007617, 0x007618, 0x000000, 0xFFFFFF, + 0x00762A, 0x00762C, 0x000000, 0xFFFFFF, + 0x00762E, 0x00762E, 0x000000, 0xFFFFFF, + 0x007636, 0x007637, 0x000000, 0xFFFFFF, + 0x007639, 0x007639, 0x000000, 0xFFFFFF, + 0x00763B, 0x00763B, 0x000000, 0xFFFFFF, + 0x00763E, 0x007641, 0x000000, 0xFFFFFF, + 0x007644, 0x007645, 0x000000, 0xFFFFFF, + 0x00764A, 0x00764B, 0x000000, 0xFFFFFF, + 0x00764D, 0x00764F, 0x000000, 0xFFFFFF, + 0x007651, 0x007651, 0x000000, 0xFFFFFF, + 0x007654, 0x007655, 0x000000, 0xFFFFFF, + 0x00765B, 0x00765B, 0x000000, 0xFFFFFF, + 0x00765D, 0x00765E, 0x000000, 0xFFFFFF, + 0x007663, 0x007663, 0x000000, 0xFFFFFF, + 0x007666, 0x007668, 0x000000, 0xFFFFFF, + 0x00766B, 0x00766B, 0x000000, 0xFFFFFF, + 0x00766F, 0x00766F, 0x000000, 0xFFFFFF, + 0x007673, 0x007674, 0x000000, 0xFFFFFF, + 0x007676, 0x007677, 0x000000, 0xFFFFFF, + 0x00767A, 0x00767A, 0x000000, 0xFFFFFF, + 0x007680, 0x007680, 0x000000, 0xFFFFFF, + 0x007683, 0x007683, 0x000000, 0xFFFFFF, + 0x007685, 0x007685, 0x000000, 0xFFFFFF, + 0x00768C, 0x00768D, 0x000000, 0xFFFFFF, + 0x007690, 0x007691, 0x000000, 0xFFFFFF, + 0x007694, 0x007694, 0x000000, 0xFFFFFF, + 0x007697, 0x007698, 0x000000, 0xFFFFFF, + 0x00769F, 0x0076A3, 0x000000, 0xFFFFFF, + 0x0076A5, 0x0076A5, 0x000000, 0xFFFFFF, + 0x0076A7, 0x0076A9, 0x000000, 0xFFFFFF, + 0x0076AC, 0x0076AC, 0x000000, 0xFFFFFF, + 0x0076B1, 0x0076B3, 0x000000, 0xFFFFFF, + 0x0076B6, 0x0076B7, 0x000000, 0xFFFFFF, + 0x0076B9, 0x0076B9, 0x000000, 0xFFFFFF, + 0x0076BC, 0x0076BC, 0x000000, 0xFFFFFF, + 0x0076C0, 0x0076C1, 0x000000, 0xFFFFFF, + 0x0076C7, 0x0076C7, 0x000000, 0xFFFFFF, + 0x0076CB, 0x0076CC, 0x000000, 0xFFFFFF, + 0x0076CF, 0x0076D1, 0x000000, 0xFFFFFF, + 0x0076D5, 0x0076D9, 0x000000, 0xFFFFFF, + 0x0076E0, 0x0076E0, 0x000000, 0xFFFFFF, + 0x0076E2, 0x0076E2, 0x000000, 0xFFFFFF, + 0x0076E8, 0x0076E8, 0x000000, 0xFFFFFF, + 0x0076EB, 0x0076EB, 0x000000, 0xFFFFFF, + 0x0076F6, 0x0076F6, 0x000000, 0xFFFFFF, + 0x0076FD, 0x0076FD, 0x000000, 0xFFFFFF, + 0x0076FF, 0x007700, 0x000000, 0xFFFFFF, + 0x007702, 0x007702, 0x000000, 0xFFFFFF, + 0x007706, 0x007706, 0x000000, 0xFFFFFF, + 0x00770C, 0x00770F, 0x000000, 0xFFFFFF, + 0x007714, 0x007714, 0x000000, 0xFFFFFF, + 0x007716, 0x007718, 0x000000, 0xFFFFFF, + 0x00771C, 0x00771C, 0x000000, 0xFFFFFF, + 0x00771E, 0x00771E, 0x000000, 0xFFFFFF, + 0x007721, 0x007721, 0x000000, 0xFFFFFF, + 0x007724, 0x007724, 0x000000, 0xFFFFFF, + 0x007726, 0x007726, 0x000000, 0xFFFFFF, + 0x00772A, 0x00772C, 0x000000, 0xFFFFFF, + 0x00772E, 0x00772E, 0x000000, 0xFFFFFF, + 0x007730, 0x007730, 0x000000, 0xFFFFFF, + 0x00773F, 0x007743, 0x000000, 0xFFFFFF, + 0x007748, 0x007749, 0x000000, 0xFFFFFF, + 0x007750, 0x007751, 0x000000, 0xFFFFFF, + 0x007753, 0x007753, 0x000000, 0xFFFFFF, + 0x007757, 0x007758, 0x000000, 0xFFFFFF, + 0x00775D, 0x00775D, 0x000000, 0xFFFFFF, + 0x007764, 0x007764, 0x000000, 0xFFFFFF, + 0x007770, 0x007778, 0x000000, 0xFFFFFF, + 0x00777A, 0x00777B, 0x000000, 0xFFFFFF, + 0x007786, 0x007786, 0x000000, 0xFFFFFF, + 0x00778A, 0x00778A, 0x000000, 0xFFFFFF, + 0x007790, 0x007790, 0x000000, 0xFFFFFF, + 0x007792, 0x007794, 0x000000, 0xFFFFFF, + 0x007796, 0x007796, 0x000000, 0xFFFFFF, + 0x007798, 0x007798, 0x000000, 0xFFFFFF, + 0x0077A4, 0x0077A4, 0x000000, 0xFFFFFF, + 0x0077A6, 0x0077A6, 0x000000, 0xFFFFFF, + 0x0077A9, 0x0077A9, 0x000000, 0xFFFFFF, + 0x0077AE, 0x0077AF, 0x000000, 0xFFFFFF, + 0x0077B8, 0x0077B9, 0x000000, 0xFFFFFF, + 0x0077BE, 0x0077BE, 0x000000, 0xFFFFFF, + 0x0077C0, 0x0077C1, 0x000000, 0xFFFFFF, + 0x0077C3, 0x0077C3, 0x000000, 0xFFFFFF, + 0x0077C5, 0x0077C6, 0x000000, 0xFFFFFF, + 0x0077C8, 0x0077C8, 0x000000, 0xFFFFFF, + 0x0077CB, 0x0077CB, 0x000000, 0xFFFFFF, + 0x0077D1, 0x0077D2, 0x000000, 0xFFFFFF, + 0x0077D6, 0x0077D6, 0x000000, 0xFFFFFF, + 0x0077DD, 0x0077DD, 0x000000, 0xFFFFFF, + 0x0077DF, 0x0077DF, 0x000000, 0xFFFFFF, + 0x0077E1, 0x0077E1, 0x000000, 0xFFFFFF, + 0x0077E4, 0x0077E4, 0x000000, 0xFFFFFF, + 0x0077E6, 0x0077E6, 0x000000, 0xFFFFFF, + 0x0077EA, 0x0077EB, 0x000000, 0xFFFFFF, + 0x0077F4, 0x0077F6, 0x000000, 0xFFFFFF, + 0x0077FE, 0x007801, 0x000000, 0xFFFFFF, + 0x007804, 0x007804, 0x000000, 0xFFFFFF, + 0x007807, 0x007808, 0x000000, 0xFFFFFF, + 0x00780A, 0x00780B, 0x000000, 0xFFFFFF, + 0x007815, 0x00781C, 0x000000, 0xFFFFFF, + 0x00781E, 0x00781E, 0x000000, 0xFFFFFF, + 0x007824, 0x007824, 0x000000, 0xFFFFFF, + 0x007836, 0x007836, 0x000000, 0xFFFFFF, + 0x007839, 0x007842, 0x000000, 0xFFFFFF, + 0x007844, 0x007844, 0x000000, 0xFFFFFF, + 0x007846, 0x007847, 0x000000, 0xFFFFFF, + 0x00784B, 0x00784B, 0x000000, 0xFFFFFF, + 0x00784F, 0x00784F, 0x000000, 0xFFFFFF, + 0x007851, 0x007851, 0x000000, 0xFFFFFF, + 0x007853, 0x00785B, 0x000000, 0xFFFFFF, + 0x00785F, 0x00785F, 0x000000, 0xFFFFFF, + 0x007861, 0x007861, 0x000000, 0xFFFFFF, + 0x007863, 0x007863, 0x000000, 0xFFFFFF, + 0x007866, 0x007867, 0x000000, 0xFFFFFF, + 0x007872, 0x007878, 0x000000, 0xFFFFFF, + 0x00787A, 0x00787A, 0x000000, 0xFFFFFF, + 0x00787D, 0x00787D, 0x000000, 0xFFFFFF, + 0x007882, 0x007882, 0x000000, 0xFFFFFF, + 0x007888, 0x007888, 0x000000, 0xFFFFFF, + 0x00788A, 0x00788B, 0x000000, 0xFFFFFF, + 0x00788D, 0x00788D, 0x000000, 0xFFFFFF, + 0x007890, 0x007890, 0x000000, 0xFFFFFF, + 0x007892, 0x007892, 0x000000, 0xFFFFFF, + 0x00789B, 0x00789D, 0x000000, 0xFFFFFF, + 0x0078A6, 0x0078A6, 0x000000, 0xFFFFFF, + 0x0078AE, 0x0078AF, 0x000000, 0xFFFFFF, + 0x0078B1, 0x0078B1, 0x000000, 0xFFFFFF, + 0x0078B5, 0x0078B9, 0x000000, 0xFFFFFF, + 0x0078BD, 0x0078BD, 0x000000, 0xFFFFFF, + 0x0078BF, 0x0078C0, 0x000000, 0xFFFFFF, + 0x0078C2, 0x0078C2, 0x000000, 0xFFFFFF, + 0x0078C6, 0x0078C7, 0x000000, 0xFFFFFF, + 0x0078D2, 0x0078D3, 0x000000, 0xFFFFFF, + 0x0078D6, 0x0078D9, 0x000000, 0xFFFFFF, + 0x0078DC, 0x0078DC, 0x000000, 0xFFFFFF, + 0x0078E4, 0x0078E4, 0x000000, 0xFFFFFF, + 0x0078E6, 0x0078E6, 0x000000, 0xFFFFFF, + 0x0078EB, 0x0078EB, 0x000000, 0xFFFFFF, + 0x0078EE, 0x0078EE, 0x000000, 0xFFFFFF, + 0x0078F0, 0x0078F1, 0x000000, 0xFFFFFF, + 0x0078F5, 0x0078F6, 0x000000, 0xFFFFFF, + 0x0078F8, 0x0078F8, 0x000000, 0xFFFFFF, + 0x007900, 0x007900, 0x000000, 0xFFFFFF, + 0x007903, 0x007903, 0x000000, 0xFFFFFF, + 0x007906, 0x007908, 0x000000, 0xFFFFFF, + 0x00790A, 0x00790B, 0x000000, 0xFFFFFF, + 0x00790D, 0x00790D, 0x000000, 0xFFFFFF, + 0x00790F, 0x00790F, 0x000000, 0xFFFFFF, + 0x007915, 0x007916, 0x000000, 0xFFFFFF, + 0x007918, 0x007918, 0x000000, 0xFFFFFF, + 0x00791A, 0x00791A, 0x000000, 0xFFFFFF, + 0x00791F, 0x007920, 0x000000, 0xFFFFFF, + 0x007922, 0x007922, 0x000000, 0xFFFFFF, + 0x00792E, 0x00792E, 0x000000, 0xFFFFFF, + 0x007930, 0x007930, 0x000000, 0xFFFFFF, + 0x007932, 0x007934, 0x000000, 0xFFFFFF, + 0x007936, 0x007937, 0x000000, 0xFFFFFF, + 0x00793B, 0x00793C, 0x000000, 0xFFFFFF, + 0x007943, 0x007943, 0x000000, 0xFFFFFF, + 0x00794D, 0x00794E, 0x000000, 0xFFFFFF, + 0x007958, 0x007959, 0x000000, 0xFFFFFF, + 0x007962, 0x007962, 0x000000, 0xFFFFFF, + 0x007966, 0x007966, 0x000000, 0xFFFFFF, + 0x00796C, 0x00796C, 0x000000, 0xFFFFFF, + 0x00796E, 0x00796F, 0x000000, 0xFFFFFF, + 0x007971, 0x007971, 0x000000, 0xFFFFFF, + 0x007975, 0x007978, 0x000000, 0xFFFFFF, + 0x00797B, 0x00797B, 0x000000, 0xFFFFFF, + 0x00797E, 0x00797E, 0x000000, 0xFFFFFF, + 0x007980, 0x007980, 0x000000, 0xFFFFFF, + 0x007983, 0x007987, 0x000000, 0xFFFFFF, + 0x007989, 0x007989, 0x000000, 0xFFFFFF, + 0x00798C, 0x00798C, 0x000000, 0xFFFFFF, + 0x007991, 0x007991, 0x000000, 0xFFFFFF, + 0x007999, 0x007999, 0x000000, 0xFFFFFF, + 0x00799D, 0x00799F, 0x000000, 0xFFFFFF, + 0x0079A3, 0x0079A3, 0x000000, 0xFFFFFF, + 0x0079A5, 0x0079A5, 0x000000, 0xFFFFFF, + 0x0079A9, 0x0079A9, 0x000000, 0xFFFFFF, + 0x0079AF, 0x0079AF, 0x000000, 0xFFFFFF, + 0x0079B5, 0x0079B5, 0x000000, 0xFFFFFF, + 0x0079BC, 0x0079BC, 0x000000, 0xFFFFFF, + 0x0079C2, 0x0079C4, 0x000000, 0xFFFFFF, + 0x0079C6, 0x0079C7, 0x000000, 0xFFFFFF, + 0x0079CA, 0x0079CA, 0x000000, 0xFFFFFF, + 0x0079CC, 0x0079CC, 0x000000, 0xFFFFFF, + 0x0079D0, 0x0079D0, 0x000000, 0xFFFFFF, + 0x0079D3, 0x0079D4, 0x000000, 0xFFFFFF, + 0x0079D7, 0x0079D7, 0x000000, 0xFFFFFF, + 0x0079D9, 0x0079DB, 0x000000, 0xFFFFFF, + 0x0079E1, 0x0079E2, 0x000000, 0xFFFFFF, + 0x0079E5, 0x0079E5, 0x000000, 0xFFFFFF, + 0x0079E8, 0x0079E8, 0x000000, 0xFFFFFF, + 0x0079EF, 0x0079F5, 0x000000, 0xFFFFFF, + 0x0079F9, 0x0079F9, 0x000000, 0xFFFFFF, + 0x0079FC, 0x0079FF, 0x000000, 0xFFFFFF, + 0x007A01, 0x007A01, 0x000000, 0xFFFFFF, + 0x007A06, 0x007A07, 0x000000, 0xFFFFFF, + 0x007A09, 0x007A09, 0x000000, 0xFFFFFF, + 0x007A0E, 0x007A0F, 0x000000, 0xFFFFFF, + 0x007A16, 0x007A16, 0x000000, 0xFFFFFF, + 0x007A1D, 0x007A1D, 0x000000, 0xFFFFFF, + 0x007A21, 0x007A21, 0x000000, 0xFFFFFF, + 0x007A23, 0x007A25, 0x000000, 0xFFFFFF, + 0x007A27, 0x007A27, 0x000000, 0xFFFFFF, + 0x007A29, 0x007A2A, 0x000000, 0xFFFFFF, + 0x007A2C, 0x007A2D, 0x000000, 0xFFFFFF, + 0x007A32, 0x007A36, 0x000000, 0xFFFFFF, + 0x007A38, 0x007A38, 0x000000, 0xFFFFFF, + 0x007A3A, 0x007A3A, 0x000000, 0xFFFFFF, + 0x007A3E, 0x007A3E, 0x000000, 0xFFFFFF, + 0x007A41, 0x007A43, 0x000000, 0xFFFFFF, + 0x007A45, 0x007A45, 0x000000, 0xFFFFFF, + 0x007A49, 0x007A49, 0x000000, 0xFFFFFF, + 0x007A4F, 0x007A53, 0x000000, 0xFFFFFF, + 0x007A55, 0x007A55, 0x000000, 0xFFFFFF, + 0x007A59, 0x007A59, 0x000000, 0xFFFFFF, + 0x007A5D, 0x007A5E, 0x000000, 0xFFFFFF, + 0x007A63, 0x007A66, 0x000000, 0xFFFFFF, + 0x007A6A, 0x007A6A, 0x000000, 0xFFFFFF, + 0x007A6F, 0x007A6F, 0x000000, 0xFFFFFF, + 0x007A72, 0x007A73, 0x000000, 0xFFFFFF, + 0x007A77, 0x007A77, 0x000000, 0xFFFFFF, + 0x007A7C, 0x007A7D, 0x000000, 0xFFFFFF, + 0x007A82, 0x007A83, 0x000000, 0xFFFFFF, + 0x007A8D, 0x007A8E, 0x000000, 0xFFFFFF, + 0x007A91, 0x007A91, 0x000000, 0xFFFFFF, + 0x007A93, 0x007A93, 0x000000, 0xFFFFFF, + 0x007A9A, 0x007A9D, 0x000000, 0xFFFFFF, + 0x007AA1, 0x007AA1, 0x000000, 0xFFFFFF, + 0x007AA4, 0x007AA7, 0x000000, 0xFFFFFF, + 0x007AAD, 0x007AAD, 0x000000, 0xFFFFFF, + 0x007AB0, 0x007AB0, 0x000000, 0xFFFFFF, + 0x007AB9, 0x007AB9, 0x000000, 0xFFFFFF, + 0x007ABB, 0x007ABD, 0x000000, 0xFFFFFF, + 0x007AC2, 0x007AC3, 0x000000, 0xFFFFFF, + 0x007AC6, 0x007AC6, 0x000000, 0xFFFFFF, + 0x007AC8, 0x007AC9, 0x000000, 0xFFFFFF, + 0x007ACC, 0x007AD0, 0x000000, 0xFFFFFF, + 0x007AD2, 0x007AD7, 0x000000, 0xFFFFFF, + 0x007ADA, 0x007ADE, 0x000000, 0xFFFFFF, + 0x007AE1, 0x007AE2, 0x000000, 0xFFFFFF, + 0x007AE7, 0x007AEA, 0x000000, 0xFFFFFF, + 0x007AEC, 0x007AEC, 0x000000, 0xFFFFFF, + 0x007AF0, 0x007AF5, 0x000000, 0xFFFFFF, + 0x007AF8, 0x007AF8, 0x000000, 0xFFFFFF, + 0x007AFC, 0x007AFC, 0x000000, 0xFFFFFF, + 0x007AFE, 0x007AFE, 0x000000, 0xFFFFFF, + 0x007B02, 0x007B03, 0x000000, 0xFFFFFF, + 0x007B07, 0x007B07, 0x000000, 0xFFFFFF, + 0x007B0B, 0x007B0D, 0x000000, 0xFFFFFF, + 0x007B14, 0x007B17, 0x000000, 0xFFFFFF, + 0x007B1C, 0x007B1C, 0x000000, 0xFFFFFF, + 0x007B1F, 0x007B1F, 0x000000, 0xFFFFFF, + 0x007B21, 0x007B21, 0x000000, 0xFFFFFF, + 0x007B27, 0x007B27, 0x000000, 0xFFFFFF, + 0x007B29, 0x007B29, 0x000000, 0xFFFFFF, + 0x007B36, 0x007B37, 0x000000, 0xFFFFFF, + 0x007B39, 0x007B3A, 0x000000, 0xFFFFFF, + 0x007B3C, 0x007B3F, 0x000000, 0xFFFFFF, + 0x007B41, 0x007B43, 0x000000, 0xFFFFFF, + 0x007B53, 0x007B53, 0x000000, 0xFFFFFF, + 0x007B55, 0x007B55, 0x000000, 0xFFFFFF, + 0x007B57, 0x007B57, 0x000000, 0xFFFFFF, + 0x007B59, 0x007B5F, 0x000000, 0xFFFFFF, + 0x007B62, 0x007B62, 0x000000, 0xFFFFFF, + 0x007B68, 0x007B68, 0x000000, 0xFFFFFF, + 0x007B6A, 0x007B6C, 0x000000, 0xFFFFFF, + 0x007B6F, 0x007B6F, 0x000000, 0xFFFFFF, + 0x007B79, 0x007B81, 0x000000, 0xFFFFFF, + 0x007B83, 0x007B83, 0x000000, 0xFFFFFF, + 0x007B86, 0x007B86, 0x000000, 0xFFFFFF, + 0x007B89, 0x007B89, 0x000000, 0xFFFFFF, + 0x007B92, 0x007B93, 0x000000, 0xFFFFFF, + 0x007B9A, 0x007B9A, 0x000000, 0xFFFFFF, + 0x007B9E, 0x007B9F, 0x000000, 0xFFFFFF, + 0x007BA2, 0x007BA3, 0x000000, 0xFFFFFF, + 0x007BA5, 0x007BAB, 0x000000, 0xFFFFFF, + 0x007BAE, 0x007BAE, 0x000000, 0xFFFFFF, + 0x007BB0, 0x007BB0, 0x000000, 0xFFFFFF, + 0x007BB2, 0x007BB3, 0x000000, 0xFFFFFF, + 0x007BB6, 0x007BB6, 0x000000, 0xFFFFFF, + 0x007BBA, 0x007BBD, 0x000000, 0xFFFFFF, + 0x007BBF, 0x007BBF, 0x000000, 0xFFFFFF, + 0x007BC2, 0x007BC3, 0x000000, 0xFFFFFF, + 0x007BC5, 0x007BC5, 0x000000, 0xFFFFFF, + 0x007BC8, 0x007BC8, 0x000000, 0xFFFFFF, + 0x007BCD, 0x007BCD, 0x000000, 0xFFFFFF, + 0x007BCF, 0x007BD3, 0x000000, 0xFFFFFF, + 0x007BD6, 0x007BD7, 0x000000, 0xFFFFFF, + 0x007BEC, 0x007BEF, 0x000000, 0xFFFFFF, + 0x007BF5, 0x007BF6, 0x000000, 0xFFFFFF, + 0x007BFA, 0x007BFA, 0x000000, 0xFFFFFF, + 0x007BFC, 0x007BFC, 0x000000, 0xFFFFFF, + 0x007C04, 0x007C04, 0x000000, 0xFFFFFF, + 0x007C08, 0x007C08, 0x000000, 0xFFFFFF, + 0x007C12, 0x007C18, 0x000000, 0xFFFFFF, + 0x007C1A, 0x007C1B, 0x000000, 0xFFFFFF, + 0x007C24, 0x007C24, 0x000000, 0xFFFFFF, + 0x007C2E, 0x007C2F, 0x000000, 0xFFFFFF, + 0x007C31, 0x007C32, 0x000000, 0xFFFFFF, + 0x007C34, 0x007C36, 0x000000, 0xFFFFFF, + 0x007C3A, 0x007C3A, 0x000000, 0xFFFFFF, + 0x007C41, 0x007C42, 0x000000, 0xFFFFFF, + 0x007C44, 0x007C44, 0x000000, 0xFFFFFF, + 0x007C46, 0x007C46, 0x000000, 0xFFFFFF, + 0x007C4B, 0x007C4B, 0x000000, 0xFFFFFF, + 0x007C4E, 0x007C4F, 0x000000, 0xFFFFFF, + 0x007C51, 0x007C52, 0x000000, 0xFFFFFF, + 0x007C55, 0x007C56, 0x000000, 0xFFFFFF, + 0x007C58, 0x007C58, 0x000000, 0xFFFFFF, + 0x007C5D, 0x007C5E, 0x000000, 0xFFFFFF, + 0x007C61, 0x007C62, 0x000000, 0xFFFFFF, + 0x007C68, 0x007C68, 0x000000, 0xFFFFFF, + 0x007C6D, 0x007C6D, 0x000000, 0xFFFFFF, + 0x007C70, 0x007C71, 0x000000, 0xFFFFFF, + 0x007C74, 0x007C74, 0x000000, 0xFFFFFF, + 0x007C76, 0x007C77, 0x000000, 0xFFFFFF, + 0x007C7B, 0x007C7C, 0x000000, 0xFFFFFF, + 0x007C7E, 0x007C7E, 0x000000, 0xFFFFFF, + 0x007C82, 0x007C83, 0x000000, 0xFFFFFF, + 0x007C86, 0x007C87, 0x000000, 0xFFFFFF, + 0x007C8B, 0x007C8B, 0x000000, 0xFFFFFF, + 0x007C8E, 0x007C90, 0x000000, 0xFFFFFF, + 0x007C93, 0x007C93, 0x000000, 0xFFFFFF, + 0x007C99, 0x007C9D, 0x000000, 0xFFFFFF, + 0x007CA0, 0x007CA0, 0x000000, 0xFFFFFF, + 0x007CA4, 0x007CA4, 0x000000, 0xFFFFFF, + 0x007CA6, 0x007CA6, 0x000000, 0xFFFFFF, + 0x007CA9, 0x007CAE, 0x000000, 0xFFFFFF, + 0x007CB0, 0x007CB0, 0x000000, 0xFFFFFF, + 0x007CB6, 0x007CB8, 0x000000, 0xFFFFFF, + 0x007CC0, 0x007CC4, 0x000000, 0xFFFFFF, + 0x007CC6, 0x007CC7, 0x000000, 0xFFFFFF, + 0x007CC9, 0x007CC9, 0x000000, 0xFFFFFF, + 0x007CCD, 0x007CCD, 0x000000, 0xFFFFFF, + 0x007CCF, 0x007CCF, 0x000000, 0xFFFFFF, + 0x007CD3, 0x007CD3, 0x000000, 0xFFFFFF, + 0x007CD8, 0x007CD8, 0x000000, 0xFFFFFF, + 0x007CDA, 0x007CDB, 0x000000, 0xFFFFFF, + 0x007CE1, 0x007CE1, 0x000000, 0xFFFFFF, + 0x007CE3, 0x007CE6, 0x000000, 0xFFFFFF, + 0x007CE9, 0x007CE9, 0x000000, 0xFFFFFF, + 0x007CEB, 0x007CEB, 0x000000, 0xFFFFFF, + 0x007CED, 0x007CED, 0x000000, 0xFFFFFF, + 0x007CF3, 0x007CF3, 0x000000, 0xFFFFFF, + 0x007CF5, 0x007CF5, 0x000000, 0xFFFFFF, + 0x007CF9, 0x007CFA, 0x000000, 0xFFFFFF, + 0x007CFC, 0x007CFC, 0x000000, 0xFFFFFF, + 0x007CFF, 0x007CFF, 0x000000, 0xFFFFFF, + 0x007D23, 0x007D27, 0x000000, 0xFFFFFF, + 0x007D2A, 0x007D2A, 0x000000, 0xFFFFFF, + 0x007D2D, 0x007D2D, 0x000000, 0xFFFFFF, + 0x007D34, 0x007D34, 0x000000, 0xFFFFFF, + 0x007D37, 0x007D37, 0x000000, 0xFFFFFF, + 0x007D48, 0x007D49, 0x000000, 0xFFFFFF, + 0x007D4B, 0x007D4D, 0x000000, 0xFFFFFF, + 0x007D57, 0x007D57, 0x000000, 0xFFFFFF, + 0x007D59, 0x007D5A, 0x000000, 0xFFFFFF, + 0x007D5D, 0x007D5D, 0x000000, 0xFFFFFF, + 0x007D60, 0x007D60, 0x000000, 0xFFFFFF, + 0x007D64, 0x007D65, 0x000000, 0xFFFFFF, + 0x007D6C, 0x007D6C, 0x000000, 0xFFFFFF, + 0x007D74, 0x007D78, 0x000000, 0xFFFFFF, + 0x007D7E, 0x007D7E, 0x000000, 0xFFFFFF, + 0x007D82, 0x007D82, 0x000000, 0xFFFFFF, + 0x007D87, 0x007D87, 0x000000, 0xFFFFFF, + 0x007D89, 0x007D8B, 0x000000, 0xFFFFFF, + 0x007D90, 0x007D90, 0x000000, 0xFFFFFF, + 0x007D95, 0x007D95, 0x000000, 0xFFFFFF, + 0x007D97, 0x007D9B, 0x000000, 0xFFFFFF, + 0x007DA4, 0x007DA5, 0x000000, 0xFFFFFF, + 0x007DA8, 0x007DA8, 0x000000, 0xFFFFFF, + 0x007DAB, 0x007DAB, 0x000000, 0xFFFFFF, + 0x007DB3, 0x007DB3, 0x000000, 0xFFFFFF, + 0x007DB6, 0x007DB6, 0x000000, 0xFFFFFF, + 0x007DC3, 0x007DC3, 0x000000, 0xFFFFFF, + 0x007DC8, 0x007DC8, 0x000000, 0xFFFFFF, + 0x007DCD, 0x007DCD, 0x000000, 0xFFFFFF, + 0x007DCF, 0x007DD1, 0x000000, 0xFFFFFF, + 0x007DD3, 0x007DD6, 0x000000, 0xFFFFFF, + 0x007DDC, 0x007DDC, 0x000000, 0xFFFFFF, + 0x007DE2, 0x007DE2, 0x000000, 0xFFFFFF, + 0x007DE4, 0x007DE5, 0x000000, 0xFFFFFF, + 0x007DEB, 0x007DEB, 0x000000, 0xFFFFFF, + 0x007DED, 0x007DED, 0x000000, 0xFFFFFF, + 0x007DF5, 0x007DF5, 0x000000, 0xFFFFFF, + 0x007DF8, 0x007DF8, 0x000000, 0xFFFFFF, + 0x007DFC, 0x007E02, 0x000000, 0xFFFFFF, + 0x007E04, 0x007E07, 0x000000, 0xFFFFFF, + 0x007E18, 0x007E19, 0x000000, 0xFFFFFF, + 0x007E26, 0x007E28, 0x000000, 0xFFFFFF, + 0x007E2C, 0x007E2C, 0x000000, 0xFFFFFF, + 0x007E4A, 0x007E4B, 0x000000, 0xFFFFFF, + 0x007E4D, 0x007E4F, 0x000000, 0xFFFFFF, + 0x007E5B, 0x007E5B, 0x000000, 0xFFFFFF, + 0x007E5D, 0x007E5D, 0x000000, 0xFFFFFF, + 0x007E64, 0x007E67, 0x000000, 0xFFFFFF, + 0x007E6C, 0x007E6C, 0x000000, 0xFFFFFF, + 0x007E6E, 0x007E6E, 0x000000, 0xFFFFFF, + 0x007E71, 0x007E71, 0x000000, 0xFFFFFF, + 0x007E7F, 0x007E7F, 0x000000, 0xFFFFFF, + 0x007E83, 0x007E85, 0x000000, 0xFFFFFF, + 0x007E89, 0x007E89, 0x000000, 0xFFFFFF, + 0x007E8E, 0x007E8E, 0x000000, 0xFFFFFF, + 0x007E90, 0x007E90, 0x000000, 0xFFFFFF, + 0x007E92, 0x007E92, 0x000000, 0xFFFFFF, + 0x007E9D, 0x007F35, 0x000000, 0xFFFFFF, + 0x007F37, 0x007F37, 0x000000, 0xFFFFFF, + 0x007F3B, 0x007F3C, 0x000000, 0xFFFFFF, + 0x007F40, 0x007F42, 0x000000, 0xFFFFFF, + 0x007F46, 0x007F47, 0x000000, 0xFFFFFF, + 0x007F49, 0x007F49, 0x000000, 0xFFFFFF, + 0x007F4E, 0x007F4E, 0x000000, 0xFFFFFF, + 0x007F52, 0x007F53, 0x000000, 0xFFFFFF, + 0x007F56, 0x007F57, 0x000000, 0xFFFFFF, + 0x007F59, 0x007F5A, 0x000000, 0xFFFFFF, + 0x007F62, 0x007F62, 0x000000, 0xFFFFFF, + 0x007F64, 0x007F64, 0x000000, 0xFFFFFF, + 0x007F6F, 0x007F6F, 0x000000, 0xFFFFFF, + 0x007F71, 0x007F71, 0x000000, 0xFFFFFF, + 0x007F74, 0x007F74, 0x000000, 0xFFFFFF, + 0x007F78, 0x007F78, 0x000000, 0xFFFFFF, + 0x007F80, 0x007F82, 0x000000, 0xFFFFFF, + 0x007F84, 0x007F84, 0x000000, 0xFFFFFF, + 0x007F8F, 0x007F90, 0x000000, 0xFFFFFF, + 0x007F93, 0x007F93, 0x000000, 0xFFFFFF, + 0x007F97, 0x007F99, 0x000000, 0xFFFFFF, + 0x007F9F, 0x007F9F, 0x000000, 0xFFFFFF, + 0x007FA3, 0x007FA3, 0x000000, 0xFFFFFF, + 0x007FAA, 0x007FAB, 0x000000, 0xFFFFFF, + 0x007FAE, 0x007FAE, 0x000000, 0xFFFFFF, + 0x007FB4, 0x007FB4, 0x000000, 0xFFFFFF, + 0x007FC4, 0x007FC4, 0x000000, 0xFFFFFF, + 0x007FC6, 0x007FC6, 0x000000, 0xFFFFFF, + 0x007FC8, 0x007FC8, 0x000000, 0xFFFFFF, + 0x007FD3, 0x007FD3, 0x000000, 0xFFFFFF, + 0x007FD6, 0x007FD6, 0x000000, 0xFFFFFF, + 0x007FD8, 0x007FDA, 0x000000, 0xFFFFFF, + 0x007FDD, 0x007FDD, 0x000000, 0xFFFFFF, + 0x007FE4, 0x007FE4, 0x000000, 0xFFFFFF, + 0x007FE7, 0x007FE7, 0x000000, 0xFFFFFF, + 0x007FF6, 0x007FF6, 0x000000, 0xFFFFFF, + 0x007FFA, 0x007FFA, 0x000000, 0xFFFFFF, + 0x008002, 0x008002, 0x000000, 0xFFFFFF, + 0x008008, 0x00800A, 0x000000, 0xFFFFFF, + 0x008013, 0x008013, 0x000000, 0xFFFFFF, + 0x00801A, 0x00801A, 0x000000, 0xFFFFFF, + 0x00801D, 0x00801D, 0x000000, 0xFFFFFF, + 0x008020, 0x008020, 0x000000, 0xFFFFFF, + 0x008022, 0x008023, 0x000000, 0xFFFFFF, + 0x008025, 0x008025, 0x000000, 0xFFFFFF, + 0x008027, 0x008027, 0x000000, 0xFFFFFF, + 0x00802B, 0x00802B, 0x000000, 0xFFFFFF, + 0x00802D, 0x00802F, 0x000000, 0xFFFFFF, + 0x008031, 0x008032, 0x000000, 0xFFFFFF, + 0x008038, 0x008038, 0x000000, 0xFFFFFF, + 0x00803A, 0x00803C, 0x000000, 0xFFFFFF, + 0x008040, 0x008042, 0x000000, 0xFFFFFF, + 0x008044, 0x008045, 0x000000, 0xFFFFFF, + 0x008049, 0x008049, 0x000000, 0xFFFFFF, + 0x00804B, 0x00804E, 0x000000, 0xFFFFFF, + 0x008053, 0x008055, 0x000000, 0xFFFFFF, + 0x008057, 0x008057, 0x000000, 0xFFFFFF, + 0x008059, 0x008059, 0x000000, 0xFFFFFF, + 0x00805B, 0x00805B, 0x000000, 0xFFFFFF, + 0x00805F, 0x008063, 0x000000, 0xFFFFFF, + 0x008065, 0x008066, 0x000000, 0xFFFFFF, + 0x008068, 0x00806B, 0x000000, 0xFFFFFF, + 0x00806D, 0x00806E, 0x000000, 0xFFFFFF, + 0x008074, 0x008074, 0x000000, 0xFFFFFF, + 0x00807A, 0x00807C, 0x000000, 0xFFFFFF, + 0x008080, 0x008081, 0x000000, 0xFFFFFF, + 0x008083, 0x008083, 0x000000, 0xFFFFFF, + 0x008088, 0x008088, 0x000000, 0xFFFFFF, + 0x00808D, 0x00808E, 0x000000, 0xFFFFFF, + 0x008091, 0x008091, 0x000000, 0xFFFFFF, + 0x008094, 0x008094, 0x000000, 0xFFFFFF, + 0x008097, 0x008097, 0x000000, 0xFFFFFF, + 0x00809E, 0x0080A0, 0x000000, 0xFFFFFF, + 0x0080A4, 0x0080A4, 0x000000, 0xFFFFFF, + 0x0080A6, 0x0080A8, 0x000000, 0xFFFFFF, + 0x0080AC, 0x0080AC, 0x000000, 0xFFFFFF, + 0x0080B0, 0x0080B0, 0x000000, 0xFFFFFF, + 0x0080B3, 0x0080B3, 0x000000, 0xFFFFFF, + 0x0080B6, 0x0080B7, 0x000000, 0xFFFFFF, + 0x0080B9, 0x0080B9, 0x000000, 0xFFFFFF, + 0x0080BB, 0x0080C1, 0x000000, 0xFFFFFF, + 0x0080C6, 0x0080C6, 0x000000, 0xFFFFFF, + 0x0080CB, 0x0080CB, 0x000000, 0xFFFFFF, + 0x0080D2, 0x0080D3, 0x000000, 0xFFFFFF, + 0x0080DF, 0x0080DF, 0x000000, 0xFFFFFF, + 0x0080E2, 0x0080E2, 0x000000, 0xFFFFFF, + 0x0080E7, 0x0080EC, 0x000000, 0xFFFFFF, + 0x0080EE, 0x0080EE, 0x000000, 0xFFFFFF, + 0x0080F6, 0x0080F7, 0x000000, 0xFFFFFF, + 0x0080FF, 0x0080FF, 0x000000, 0xFFFFFF, + 0x008103, 0x008104, 0x000000, 0xFFFFFF, + 0x008107, 0x008107, 0x000000, 0xFFFFFF, + 0x008109, 0x008109, 0x000000, 0xFFFFFF, + 0x00810B, 0x008114, 0x000000, 0xFFFFFF, + 0x008117, 0x008117, 0x000000, 0xFFFFFF, + 0x00811A, 0x00811A, 0x000000, 0xFFFFFF, + 0x00811C, 0x00811C, 0x000000, 0xFFFFFF, + 0x008120, 0x008120, 0x000000, 0xFFFFFF, + 0x008126, 0x008126, 0x000000, 0xFFFFFF, + 0x008128, 0x008128, 0x000000, 0xFFFFFF, + 0x00812A, 0x00812A, 0x000000, 0xFFFFFF, + 0x00812E, 0x00812E, 0x000000, 0xFFFFFF, + 0x008131, 0x008138, 0x000000, 0xFFFFFF, + 0x00813B, 0x00813C, 0x000000, 0xFFFFFF, + 0x00813F, 0x008142, 0x000000, 0xFFFFFF, + 0x008145, 0x008145, 0x000000, 0xFFFFFF, + 0x008148, 0x008149, 0x000000, 0xFFFFFF, + 0x008156, 0x00815A, 0x000000, 0xFFFFFF, + 0x00815D, 0x00815D, 0x000000, 0xFFFFFF, + 0x00815F, 0x00815F, 0x000000, 0xFFFFFF, + 0x008163, 0x008163, 0x000000, 0xFFFFFF, + 0x008168, 0x008168, 0x000000, 0xFFFFFF, + 0x00816A, 0x00816A, 0x000000, 0xFFFFFF, + 0x00816C, 0x00816D, 0x000000, 0xFFFFFF, + 0x008175, 0x008175, 0x000000, 0xFFFFFF, + 0x00817B, 0x00817E, 0x000000, 0xFFFFFF, + 0x008181, 0x008181, 0x000000, 0xFFFFFF, + 0x008184, 0x008185, 0x000000, 0xFFFFFF, + 0x00818E, 0x00818E, 0x000000, 0xFFFFFF, + 0x008190, 0x008194, 0x000000, 0xFFFFFF, + 0x008196, 0x008196, 0x000000, 0xFFFFFF, + 0x0081A1, 0x0081A1, 0x000000, 0xFFFFFF, + 0x0081A4, 0x0081A5, 0x000000, 0xFFFFFF, + 0x0081AA, 0x0081AA, 0x000000, 0xFFFFFF, + 0x0081AD, 0x0081AD, 0x000000, 0xFFFFFF, + 0x0081AF, 0x0081AF, 0x000000, 0xFFFFFF, + 0x0081B6, 0x0081B6, 0x000000, 0xFFFFFF, + 0x0081B8, 0x0081B8, 0x000000, 0xFFFFFF, + 0x0081C1, 0x0081C1, 0x000000, 0xFFFFFF, + 0x0081C8, 0x0081C8, 0x000000, 0xFFFFFF, + 0x0081CB, 0x0081CB, 0x000000, 0xFFFFFF, + 0x0081CE, 0x0081CE, 0x000000, 0xFFFFFF, + 0x0081D3, 0x0081D4, 0x000000, 0xFFFFFF, + 0x0081D6, 0x0081D6, 0x000000, 0xFFFFFF, + 0x0081DC, 0x0081DC, 0x000000, 0xFFFFFF, + 0x0081E4, 0x0081E4, 0x000000, 0xFFFFFF, + 0x0081EB, 0x0081EB, 0x000000, 0xFFFFFF, + 0x0081EF, 0x0081F1, 0x000000, 0xFFFFFF, + 0x0081F5, 0x0081F6, 0x000000, 0xFFFFFF, + 0x0081FD, 0x0081FD, 0x000000, 0xFFFFFF, + 0x008203, 0x008203, 0x000000, 0xFFFFFF, + 0x008206, 0x008206, 0x000000, 0xFFFFFF, + 0x00820E, 0x00820F, 0x000000, 0xFFFFFF, + 0x008213, 0x008213, 0x000000, 0xFFFFFF, + 0x008217, 0x00821A, 0x000000, 0xFFFFFF, + 0x008223, 0x008224, 0x000000, 0xFFFFFF, + 0x008226, 0x008227, 0x000000, 0xFFFFFF, + 0x008229, 0x008229, 0x000000, 0xFFFFFF, + 0x00822D, 0x00822E, 0x000000, 0xFFFFFF, + 0x008230, 0x008231, 0x000000, 0xFFFFFF, + 0x00823B, 0x00823B, 0x000000, 0xFFFFFF, + 0x00823E, 0x00823E, 0x000000, 0xFFFFFF, + 0x008241, 0x008241, 0x000000, 0xFFFFFF, + 0x008243, 0x008243, 0x000000, 0xFFFFFF, + 0x008246, 0x008246, 0x000000, 0xFFFFFF, + 0x008248, 0x008248, 0x000000, 0xFFFFFF, + 0x00824A, 0x00824A, 0x000000, 0xFFFFFF, + 0x00824C, 0x00824D, 0x000000, 0xFFFFFF, + 0x008254, 0x008254, 0x000000, 0xFFFFFF, + 0x00825D, 0x00825D, 0x000000, 0xFFFFFF, + 0x008260, 0x008260, 0x000000, 0xFFFFFF, + 0x008262, 0x008262, 0x000000, 0xFFFFFF, + 0x008265, 0x008265, 0x000000, 0xFFFFFF, + 0x008267, 0x008267, 0x000000, 0xFFFFFF, + 0x00826A, 0x00826A, 0x000000, 0xFFFFFF, + 0x008270, 0x008270, 0x000000, 0xFFFFFF, + 0x008273, 0x008273, 0x000000, 0xFFFFFF, + 0x008276, 0x008276, 0x000000, 0xFFFFFF, + 0x008279, 0x00827B, 0x000000, 0xFFFFFF, + 0x008281, 0x008282, 0x000000, 0xFFFFFF, + 0x008286, 0x008289, 0x000000, 0xFFFFFF, + 0x00828C, 0x00828C, 0x000000, 0xFFFFFF, + 0x008295, 0x008297, 0x000000, 0xFFFFFF, + 0x00829C, 0x00829C, 0x000000, 0xFFFFFF, + 0x0082A6, 0x0082A6, 0x000000, 0xFFFFFF, + 0x0082AA, 0x0082AA, 0x000000, 0xFFFFFF, + 0x0082B2, 0x0082B2, 0x000000, 0xFFFFFF, + 0x0082BF, 0x0082BF, 0x000000, 0xFFFFFF, + 0x0082C1, 0x0082C1, 0x000000, 0xFFFFFF, + 0x0082C4, 0x0082D0, 0x000000, 0xFFFFFF, + 0x0082D8, 0x0082D8, 0x000000, 0xFFFFFF, + 0x0082DA, 0x0082DA, 0x000000, 0xFFFFFF, + 0x0082DD, 0x0082DD, 0x000000, 0xFFFFFF, + 0x0082E2, 0x0082E2, 0x000000, 0xFFFFFF, + 0x0082E9, 0x0082E9, 0x000000, 0xFFFFFF, + 0x0082EE, 0x0082EE, 0x000000, 0xFFFFFF, + 0x0082F7, 0x0082F8, 0x000000, 0xFFFFFF, + 0x0082FC, 0x0082FD, 0x000000, 0xFFFFFF, + 0x0082FF, 0x0082FF, 0x000000, 0xFFFFFF, + 0x00830A, 0x00830B, 0x000000, 0xFFFFFF, + 0x00830E, 0x008315, 0x000000, 0xFFFFFF, + 0x008318, 0x008318, 0x000000, 0xFFFFFF, + 0x00831A, 0x00831A, 0x000000, 0xFFFFFF, + 0x00831D, 0x00831D, 0x000000, 0xFFFFFF, + 0x00831F, 0x00831F, 0x000000, 0xFFFFFF, + 0x008321, 0x008321, 0x000000, 0xFFFFFF, + 0x008323, 0x008323, 0x000000, 0xFFFFFF, + 0x00832E, 0x00832E, 0x000000, 0xFFFFFF, + 0x008330, 0x008330, 0x000000, 0xFFFFFF, + 0x00833D, 0x00833E, 0x000000, 0xFFFFFF, + 0x008346, 0x008346, 0x000000, 0xFFFFFF, + 0x008355, 0x008355, 0x000000, 0xFFFFFF, + 0x008357, 0x008372, 0x000000, 0xFFFFFF, + 0x008379, 0x008379, 0x000000, 0xFFFFFF, + 0x008380, 0x008380, 0x000000, 0xFFFFFF, + 0x008382, 0x008382, 0x000000, 0xFFFFFF, + 0x008384, 0x008385, 0x000000, 0xFFFFFF, + 0x008391, 0x008391, 0x000000, 0xFFFFFF, + 0x00839C, 0x00839C, 0x000000, 0xFFFFFF, + 0x00839F, 0x00839F, 0x000000, 0xFFFFFF, + 0x0083A1, 0x0083A1, 0x000000, 0xFFFFFF, + 0x0083AC, 0x0083AD, 0x000000, 0xFFFFFF, + 0x0083B1, 0x0083BC, 0x000000, 0xFFFFFF, + 0x0083BE, 0x0083BE, 0x000000, 0xFFFFFF, + 0x0083CD, 0x0083CD, 0x000000, 0xFFFFFF, + 0x0083D0, 0x0083D0, 0x000000, 0xFFFFFF, + 0x0083D2, 0x0083D3, 0x000000, 0xFFFFFF, + 0x0083DA, 0x0083DA, 0x000000, 0xFFFFFF, + 0x0083E6, 0x0083E6, 0x000000, 0xFFFFFF, + 0x0083ED, 0x0083ED, 0x000000, 0xFFFFFF, + 0x0083F7, 0x0083F7, 0x000000, 0xFFFFFF, + 0x008400, 0x008400, 0x000000, 0xFFFFFF, + 0x008402, 0x008402, 0x000000, 0xFFFFFF, + 0x008405, 0x008405, 0x000000, 0xFFFFFF, + 0x008408, 0x008408, 0x000000, 0xFFFFFF, + 0x008414, 0x00841A, 0x000000, 0xFFFFFF, + 0x00841C, 0x008422, 0x000000, 0xFFFFFF, + 0x008424, 0x008428, 0x000000, 0xFFFFFF, + 0x00842A, 0x00842A, 0x000000, 0xFFFFFF, + 0x00842E, 0x00842E, 0x000000, 0xFFFFFF, + 0x00843E, 0x00843E, 0x000000, 0xFFFFFF, + 0x008441, 0x008441, 0x000000, 0xFFFFFF, + 0x008448, 0x008448, 0x000000, 0xFFFFFF, + 0x00844A, 0x00844A, 0x000000, 0xFFFFFF, + 0x00844F, 0x00844F, 0x000000, 0xFFFFFF, + 0x008453, 0x008453, 0x000000, 0xFFFFFF, + 0x008455, 0x008455, 0x000000, 0xFFFFFF, + 0x008458, 0x008458, 0x000000, 0xFFFFFF, + 0x00845C, 0x00845C, 0x000000, 0xFFFFFF, + 0x008462, 0x008462, 0x000000, 0xFFFFFF, + 0x008464, 0x008464, 0x000000, 0xFFFFFF, + 0x00846A, 0x00846A, 0x000000, 0xFFFFFF, + 0x008471, 0x008472, 0x000000, 0xFFFFFF, + 0x00847B, 0x00847C, 0x000000, 0xFFFFFF, + 0x00847F, 0x008481, 0x000000, 0xFFFFFF, + 0x008483, 0x008485, 0x000000, 0xFFFFFF, + 0x008487, 0x00848C, 0x000000, 0xFFFFFF, + 0x008492, 0x008493, 0x000000, 0xFFFFFF, + 0x008495, 0x008496, 0x000000, 0xFFFFFF, + 0x0084A3, 0x0084A3, 0x000000, 0xFFFFFF, + 0x0084A5, 0x0084A6, 0x000000, 0xFFFFFF, + 0x0084AD, 0x0084AD, 0x000000, 0xFFFFFF, + 0x0084B3, 0x0084B3, 0x000000, 0xFFFFFF, + 0x0084B5, 0x0084B5, 0x000000, 0xFFFFFF, + 0x0084B7, 0x0084B7, 0x000000, 0xFFFFFF, + 0x0084BD, 0x0084BE, 0x000000, 0xFFFFFF, + 0x0084C3, 0x0084C3, 0x000000, 0xFFFFFF, + 0x0084C8, 0x0084C8, 0x000000, 0xFFFFFF, + 0x0084D5, 0x0084D5, 0x000000, 0xFFFFFF, + 0x0084D8, 0x0084DA, 0x000000, 0xFFFFFF, + 0x0084DC, 0x0084E6, 0x000000, 0xFFFFFF, + 0x0084ED, 0x0084ED, 0x000000, 0xFFFFFF, + 0x0084F5, 0x0084F5, 0x000000, 0xFFFFFF, + 0x0084F8, 0x0084F8, 0x000000, 0xFFFFFF, + 0x008501, 0x008501, 0x000000, 0xFFFFFF, + 0x008503, 0x008505, 0x000000, 0xFFFFFF, + 0x008510, 0x008510, 0x000000, 0xFFFFFF, + 0x00851B, 0x00851B, 0x000000, 0xFFFFFF, + 0x008522, 0x008522, 0x000000, 0xFFFFFF, + 0x008532, 0x00853A, 0x000000, 0xFFFFFF, + 0x00853C, 0x00853C, 0x000000, 0xFFFFFF, + 0x00853F, 0x00853F, 0x000000, 0xFFFFFF, + 0x008542, 0x008542, 0x000000, 0xFFFFFF, + 0x00854B, 0x00854C, 0x000000, 0xFFFFFF, + 0x00854F, 0x008550, 0x000000, 0xFFFFFF, + 0x008552, 0x008552, 0x000000, 0xFFFFFF, + 0x00855A, 0x00855A, 0x000000, 0xFFFFFF, + 0x00855C, 0x00855C, 0x000000, 0xFFFFFF, + 0x00855F, 0x00855F, 0x000000, 0xFFFFFF, + 0x00856F, 0x008570, 0x000000, 0xFFFFFF, + 0x008572, 0x008574, 0x000000, 0xFFFFFF, + 0x00857D, 0x00857D, 0x000000, 0xFFFFFF, + 0x00857F, 0x00857F, 0x000000, 0xFFFFFF, + 0x008592, 0x008593, 0x000000, 0xFFFFFF, + 0x008597, 0x008597, 0x000000, 0xFFFFFF, + 0x0085A5, 0x0085A5, 0x000000, 0xFFFFFF, + 0x0085AB, 0x0085AE, 0x000000, 0xFFFFFF, + 0x0085B2, 0x0085B2, 0x000000, 0xFFFFFF, + 0x0085BB, 0x0085BC, 0x000000, 0xFFFFFF, + 0x0085C1, 0x0085C1, 0x000000, 0xFFFFFF, + 0x0085CA, 0x0085CA, 0x000000, 0xFFFFFF, + 0x0085CC, 0x0085CC, 0x000000, 0xFFFFFF, + 0x0085D3, 0x0085D4, 0x000000, 0xFFFFFF, + 0x0085D6, 0x0085D6, 0x000000, 0xFFFFFF, + 0x0085DB, 0x0085DB, 0x000000, 0xFFFFFF, + 0x0085E0, 0x0085E0, 0x000000, 0xFFFFFF, + 0x0085E7, 0x0085E7, 0x000000, 0xFFFFFF, + 0x0085EE, 0x0085EE, 0x000000, 0xFFFFFF, + 0x0085F3, 0x0085F5, 0x000000, 0xFFFFFF, + 0x0085FC, 0x0085FC, 0x000000, 0xFFFFFF, + 0x008602, 0x008603, 0x000000, 0xFFFFFF, + 0x008608, 0x008608, 0x000000, 0xFFFFFF, + 0x00860D, 0x008610, 0x000000, 0xFFFFFF, + 0x008612, 0x008616, 0x000000, 0xFFFFFF, + 0x00861D, 0x00861D, 0x000000, 0xFFFFFF, + 0x008628, 0x008628, 0x000000, 0xFFFFFF, + 0x00862B, 0x00862B, 0x000000, 0xFFFFFF, + 0x00862F, 0x008630, 0x000000, 0xFFFFFF, + 0x008637, 0x008637, 0x000000, 0xFFFFFF, + 0x00863D, 0x00863D, 0x000000, 0xFFFFFF, + 0x008641, 0x008642, 0x000000, 0xFFFFFF, + 0x008644, 0x008645, 0x000000, 0xFFFFFF, + 0x008649, 0x00864A, 0x000000, 0xFFFFFF, + 0x00864F, 0x00864F, 0x000000, 0xFFFFFF, + 0x008651, 0x008651, 0x000000, 0xFFFFFF, + 0x008657, 0x008658, 0x000000, 0xFFFFFF, + 0x00865A, 0x00865A, 0x000000, 0xFFFFFF, + 0x00865D, 0x00865D, 0x000000, 0xFFFFFF, + 0x008660, 0x008660, 0x000000, 0xFFFFFF, + 0x008666, 0x008666, 0x000000, 0xFFFFFF, + 0x00866C, 0x00866C, 0x000000, 0xFFFFFF, + 0x008672, 0x008672, 0x000000, 0xFFFFFF, + 0x008675, 0x008676, 0x000000, 0xFFFFFF, + 0x008678, 0x008678, 0x000000, 0xFFFFFF, + 0x00867D, 0x008684, 0x000000, 0xFFFFFF, + 0x008688, 0x008689, 0x000000, 0xFFFFFF, + 0x00868F, 0x00868F, 0x000000, 0xFFFFFF, + 0x008692, 0x008692, 0x000000, 0xFFFFFF, + 0x00869B, 0x00869B, 0x000000, 0xFFFFFF, + 0x00869F, 0x0086A0, 0x000000, 0xFFFFFF, + 0x0086A6, 0x0086A6, 0x000000, 0xFFFFFF, + 0x0086AB, 0x0086AE, 0x000000, 0xFFFFFF, + 0x0086B2, 0x0086B2, 0x000000, 0xFFFFFF, + 0x0086CA, 0x0086CA, 0x000000, 0xFFFFFF, + 0x0086CD, 0x0086CF, 0x000000, 0xFFFFFF, + 0x0086D2, 0x0086D2, 0x000000, 0xFFFFFF, + 0x0086D5, 0x0086D5, 0x000000, 0xFFFFFF, + 0x0086E0, 0x0086E1, 0x000000, 0xFFFFFF, + 0x0086E5, 0x0086E5, 0x000000, 0xFFFFFF, + 0x0086E7, 0x0086E7, 0x000000, 0xFFFFFF, + 0x0086EE, 0x0086F4, 0x000000, 0xFFFFFF, + 0x0086FC, 0x0086FD, 0x000000, 0xFFFFFF, + 0x0086FF, 0x0086FF, 0x000000, 0xFFFFFF, + 0x00870F, 0x008710, 0x000000, 0xFFFFFF, + 0x008714, 0x008717, 0x000000, 0xFFFFFF, + 0x00871D, 0x00871D, 0x000000, 0xFFFFFF, + 0x00871F, 0x00871F, 0x000000, 0xFFFFFF, + 0x00872B, 0x00872B, 0x000000, 0xFFFFFF, + 0x00872F, 0x00872F, 0x000000, 0xFFFFFF, + 0x008736, 0x008736, 0x000000, 0xFFFFFF, + 0x008739, 0x008739, 0x000000, 0xFFFFFF, + 0x00873D, 0x00873D, 0x000000, 0xFFFFFF, + 0x008744, 0x008745, 0x000000, 0xFFFFFF, + 0x008747, 0x00874B, 0x000000, 0xFFFFFF, + 0x008770, 0x008772, 0x000000, 0xFFFFFF, + 0x00877C, 0x008780, 0x000000, 0xFFFFFF, + 0x008786, 0x008786, 0x000000, 0xFFFFFF, + 0x00878A, 0x00878C, 0x000000, 0xFFFFFF, + 0x00878E, 0x00878E, 0x000000, 0xFFFFFF, + 0x008795, 0x008795, 0x000000, 0xFFFFFF, + 0x008799, 0x008799, 0x000000, 0xFFFFFF, + 0x0087A0, 0x0087A1, 0x000000, 0xFFFFFF, + 0x0087A5, 0x0087A9, 0x000000, 0xFFFFFF, + 0x0087B1, 0x0087B1, 0x000000, 0xFFFFFF, + 0x0087C1, 0x0087C1, 0x000000, 0xFFFFFF, + 0x0087C7, 0x0087C7, 0x000000, 0xFFFFFF, + 0x0087CD, 0x0087D0, 0x000000, 0xFFFFFF, + 0x0087D5, 0x0087D6, 0x000000, 0xFFFFFF, + 0x0087DA, 0x0087DA, 0x000000, 0xFFFFFF, + 0x0087E9, 0x0087E9, 0x000000, 0xFFFFFF, + 0x0087EE, 0x0087EE, 0x000000, 0xFFFFFF, + 0x0087F0, 0x0087F1, 0x000000, 0xFFFFFF, + 0x0087F5, 0x0087F5, 0x000000, 0xFFFFFF, + 0x0087F8, 0x0087F8, 0x000000, 0xFFFFFF, + 0x0087FD, 0x0087FD, 0x000000, 0xFFFFFF, + 0x008804, 0x008804, 0x000000, 0xFFFFFF, + 0x008807, 0x008807, 0x000000, 0xFFFFFF, + 0x00880E, 0x00880F, 0x000000, 0xFFFFFF, + 0x008812, 0x008812, 0x000000, 0xFFFFFF, + 0x008818, 0x008818, 0x000000, 0xFFFFFF, + 0x00881A, 0x00881A, 0x000000, 0xFFFFFF, + 0x00881E, 0x00881E, 0x000000, 0xFFFFFF, + 0x008827, 0x008827, 0x000000, 0xFFFFFF, + 0x00882D, 0x00882D, 0x000000, 0xFFFFFF, + 0x008834, 0x008834, 0x000000, 0xFFFFFF, + 0x00883A, 0x00883A, 0x000000, 0xFFFFFF, + 0x008842, 0x008842, 0x000000, 0xFFFFFF, + 0x008845, 0x008847, 0x000000, 0xFFFFFF, + 0x008849, 0x008849, 0x000000, 0xFFFFFF, + 0x00884F, 0x008851, 0x000000, 0xFFFFFF, + 0x008854, 0x008854, 0x000000, 0xFFFFFF, + 0x008858, 0x008858, 0x000000, 0xFFFFFF, + 0x00885C, 0x00885C, 0x000000, 0xFFFFFF, + 0x00885E, 0x008860, 0x000000, 0xFFFFFF, + 0x008864, 0x008866, 0x000000, 0xFFFFFF, + 0x00886C, 0x00886C, 0x000000, 0xFFFFFF, + 0x00886E, 0x00886E, 0x000000, 0xFFFFFF, + 0x008873, 0x008873, 0x000000, 0xFFFFFF, + 0x008878, 0x008878, 0x000000, 0xFFFFFF, + 0x00887A, 0x00887B, 0x000000, 0xFFFFFF, + 0x008884, 0x008887, 0x000000, 0xFFFFFF, + 0x00888A, 0x00888A, 0x000000, 0xFFFFFF, + 0x00888F, 0x008890, 0x000000, 0xFFFFFF, + 0x008894, 0x008894, 0x000000, 0xFFFFFF, + 0x00889C, 0x00889D, 0x000000, 0xFFFFFF, + 0x0088A0, 0x0088A0, 0x000000, 0xFFFFFF, + 0x0088A3, 0x0088A3, 0x000000, 0xFFFFFF, + 0x0088A5, 0x0088A6, 0x000000, 0xFFFFFF, + 0x0088A9, 0x0088A9, 0x000000, 0xFFFFFF, + 0x0088AD, 0x0088B0, 0x000000, 0xFFFFFF, + 0x0088B3, 0x0088B5, 0x000000, 0xFFFFFF, + 0x0088BB, 0x0088BB, 0x000000, 0xFFFFFF, + 0x0088BF, 0x0088BF, 0x000000, 0xFFFFFF, + 0x0088C3, 0x0088C8, 0x000000, 0xFFFFFF, + 0x0088D1, 0x0088D1, 0x000000, 0xFFFFFF, + 0x0088D3, 0x0088D3, 0x000000, 0xFFFFFF, + 0x0088E0, 0x0088E0, 0x000000, 0xFFFFFF, + 0x0088E2, 0x0088E6, 0x000000, 0xFFFFFF, + 0x0088E9, 0x0088EA, 0x000000, 0xFFFFFF, + 0x0088ED, 0x0088ED, 0x000000, 0xFFFFFF, + 0x0088F5, 0x0088F5, 0x000000, 0xFFFFFF, + 0x0088FF, 0x008900, 0x000000, 0xFFFFFF, + 0x008903, 0x008904, 0x000000, 0xFFFFFF, + 0x008908, 0x008908, 0x000000, 0xFFFFFF, + 0x00890D, 0x00890D, 0x000000, 0xFFFFFF, + 0x00890F, 0x00890F, 0x000000, 0xFFFFFF, + 0x00891B, 0x00891D, 0x000000, 0xFFFFFF, + 0x008920, 0x008920, 0x000000, 0xFFFFFF, + 0x008924, 0x008924, 0x000000, 0xFFFFFF, + 0x008928, 0x008928, 0x000000, 0xFFFFFF, + 0x008934, 0x008934, 0x000000, 0xFFFFFF, + 0x008939, 0x00893A, 0x000000, 0xFFFFFF, + 0x00893F, 0x008940, 0x000000, 0xFFFFFF, + 0x008943, 0x008943, 0x000000, 0xFFFFFF, + 0x008945, 0x008945, 0x000000, 0xFFFFFF, + 0x008947, 0x008948, 0x000000, 0xFFFFFF, + 0x00894A, 0x00894A, 0x000000, 0xFFFFFF, + 0x00894D, 0x00894E, 0x000000, 0xFFFFFF, + 0x008954, 0x008955, 0x000000, 0xFFFFFF, + 0x008965, 0x008965, 0x000000, 0xFFFFFF, + 0x008967, 0x008968, 0x000000, 0xFFFFFF, + 0x008970, 0x008970, 0x000000, 0xFFFFFF, + 0x008975, 0x008975, 0x000000, 0xFFFFFF, + 0x008977, 0x008978, 0x000000, 0xFFFFFF, + 0x00897D, 0x00897D, 0x000000, 0xFFFFFF, + 0x008980, 0x008980, 0x000000, 0xFFFFFF, + 0x008984, 0x008984, 0x000000, 0xFFFFFF, + 0x008987, 0x008987, 0x000000, 0xFFFFFF, + 0x008989, 0x00898A, 0x000000, 0xFFFFFF, + 0x00898C, 0x00898E, 0x000000, 0xFFFFFF, + 0x008990, 0x008992, 0x000000, 0xFFFFFF, + 0x008994, 0x008994, 0x000000, 0xFFFFFF, + 0x008999, 0x00899A, 0x000000, 0xFFFFFF, + 0x0089A0, 0x0089A0, 0x000000, 0xFFFFFF, + 0x0089A5, 0x0089A5, 0x000000, 0xFFFFFF, + 0x0089A7, 0x0089A9, 0x000000, 0xFFFFFF, + 0x0089AB, 0x0089AB, 0x000000, 0xFFFFFF, + 0x0089B0, 0x0089B1, 0x000000, 0xFFFFFF, + 0x0089B3, 0x0089B5, 0x000000, 0xFFFFFF, + 0x0089B8, 0x0089B8, 0x000000, 0xFFFFFF, + 0x0089BB, 0x0089BC, 0x000000, 0xFFFFFF, + 0x0089C1, 0x0089D1, 0x000000, 0xFFFFFF, + 0x0089D7, 0x0089D8, 0x000000, 0xFFFFFF, + 0x0089DE, 0x0089DE, 0x000000, 0xFFFFFF, + 0x0089E7, 0x0089E7, 0x000000, 0xFFFFFF, + 0x0089EA, 0x0089EA, 0x000000, 0xFFFFFF, + 0x0089EE, 0x0089EF, 0x000000, 0xFFFFFF, + 0x0089F5, 0x0089F5, 0x000000, 0xFFFFFF, + 0x0089F9, 0x0089F9, 0x000000, 0xFFFFFF, + 0x0089FD, 0x0089FD, 0x000000, 0xFFFFFF, + 0x008A01, 0x008A01, 0x000000, 0xFFFFFF, + 0x008A05, 0x008A06, 0x000000, 0xFFFFFF, + 0x008A09, 0x008A09, 0x000000, 0xFFFFFF, + 0x008A0B, 0x008A0B, 0x000000, 0xFFFFFF, + 0x008A0D, 0x008A0D, 0x000000, 0xFFFFFF, + 0x008A14, 0x008A14, 0x000000, 0xFFFFFF, + 0x008A19, 0x008A1A, 0x000000, 0xFFFFFF, + 0x008A1C, 0x008A1C, 0x000000, 0xFFFFFF, + 0x008A20, 0x008A21, 0x000000, 0xFFFFFF, + 0x008A24, 0x008A24, 0x000000, 0xFFFFFF, + 0x008A26, 0x008A26, 0x000000, 0xFFFFFF, + 0x008A28, 0x008A29, 0x000000, 0xFFFFFF, + 0x008A2B, 0x008A2B, 0x000000, 0xFFFFFF, + 0x008A2E, 0x008A2F, 0x000000, 0xFFFFFF, + 0x008A32, 0x008A33, 0x000000, 0xFFFFFF, + 0x008A35, 0x008A35, 0x000000, 0xFFFFFF, + 0x008A37, 0x008A38, 0x000000, 0xFFFFFF, + 0x008A3D, 0x008A3D, 0x000000, 0xFFFFFF, + 0x008A42, 0x008A43, 0x000000, 0xFFFFFF, + 0x008A47, 0x008A47, 0x000000, 0xFFFFFF, + 0x008A49, 0x008A49, 0x000000, 0xFFFFFF, + 0x008A4B, 0x008A4B, 0x000000, 0xFFFFFF, + 0x008A53, 0x008A53, 0x000000, 0xFFFFFF, + 0x008A5A, 0x008A5A, 0x000000, 0xFFFFFF, + 0x008A5C, 0x008A5D, 0x000000, 0xFFFFFF, + 0x008A5F, 0x008A5F, 0x000000, 0xFFFFFF, + 0x008A64, 0x008A65, 0x000000, 0xFFFFFF, + 0x008A67, 0x008A67, 0x000000, 0xFFFFFF, + 0x008A6A, 0x008A6A, 0x000000, 0xFFFFFF, + 0x008A6F, 0x008A6F, 0x000000, 0xFFFFFF, + 0x008A78, 0x008A78, 0x000000, 0xFFFFFF, + 0x008A7D, 0x008A7E, 0x000000, 0xFFFFFF, + 0x008A80, 0x008A80, 0x000000, 0xFFFFFF, + 0x008A88, 0x008A8A, 0x000000, 0xFFFFFF, + 0x008A8E, 0x008A8E, 0x000000, 0xFFFFFF, + 0x008A90, 0x008A90, 0x000000, 0xFFFFFF, + 0x008A94, 0x008A94, 0x000000, 0xFFFFFF, + 0x008A97, 0x008A97, 0x000000, 0xFFFFFF, + 0x008A9B, 0x008A9D, 0x000000, 0xFFFFFF, + 0x008A9F, 0x008A9F, 0x000000, 0xFFFFFF, + 0x008AA2, 0x008AA2, 0x000000, 0xFFFFFF, + 0x008AA9, 0x008AA9, 0x000000, 0xFFFFFF, + 0x008AAC, 0x008AAF, 0x000000, 0xFFFFFF, + 0x008AB1, 0x008AB1, 0x000000, 0xFFFFFF, + 0x008AB3, 0x008AB5, 0x000000, 0xFFFFFF, + 0x008AB7, 0x008AB7, 0x000000, 0xFFFFFF, + 0x008AC1, 0x008AC1, 0x000000, 0xFFFFFF, + 0x008ACA, 0x008ACA, 0x000000, 0xFFFFFF, + 0x008ACC, 0x008ACC, 0x000000, 0xFFFFFF, + 0x008ACE, 0x008ACE, 0x000000, 0xFFFFFF, + 0x008AD0, 0x008AD0, 0x000000, 0xFFFFFF, + 0x008ADA, 0x008ADA, 0x000000, 0xFFFFFF, + 0x008AE3, 0x008AE3, 0x000000, 0xFFFFFF, + 0x008AE5, 0x008AE5, 0x000000, 0xFFFFFF, + 0x008AE9, 0x008AEA, 0x000000, 0xFFFFFF, + 0x008AEC, 0x008AEC, 0x000000, 0xFFFFFF, + 0x008AF9, 0x008AF9, 0x000000, 0xFFFFFF, + 0x008AFD, 0x008AFD, 0x000000, 0xFFFFFF, + 0x008B03, 0x008B03, 0x000000, 0xFFFFFF, + 0x008B09, 0x008B09, 0x000000, 0xFFFFFF, + 0x008B0C, 0x008B0C, 0x000000, 0xFFFFFF, + 0x008B1F, 0x008B1F, 0x000000, 0xFFFFFF, + 0x008B21, 0x008B21, 0x000000, 0xFFFFFF, + 0x008B29, 0x008B29, 0x000000, 0xFFFFFF, + 0x008B2D, 0x008B2D, 0x000000, 0xFFFFFF, + 0x008B32, 0x008B32, 0x000000, 0xFFFFFF, + 0x008B34, 0x008B34, 0x000000, 0xFFFFFF, + 0x008B38, 0x008B38, 0x000000, 0xFFFFFF, + 0x008B3F, 0x008B3F, 0x000000, 0xFFFFFF, + 0x008B43, 0x008B44, 0x000000, 0xFFFFFF, + 0x008B4C, 0x008B4D, 0x000000, 0xFFFFFF, + 0x008B5B, 0x008B5B, 0x000000, 0xFFFFFF, + 0x008B5E, 0x008B5E, 0x000000, 0xFFFFFF, + 0x008B61, 0x008B62, 0x000000, 0xFFFFFF, + 0x008B64, 0x008B64, 0x000000, 0xFFFFFF, + 0x008B69, 0x008B69, 0x000000, 0xFFFFFF, + 0x008B6E, 0x008B6E, 0x000000, 0xFFFFFF, + 0x008B71, 0x008B73, 0x000000, 0xFFFFFF, + 0x008B75, 0x008B76, 0x000000, 0xFFFFFF, + 0x008B7C, 0x008B7C, 0x000000, 0xFFFFFF, + 0x008B81, 0x008B81, 0x000000, 0xFFFFFF, + 0x008B83, 0x008B83, 0x000000, 0xFFFFFF, + 0x008B87, 0x008B87, 0x000000, 0xFFFFFF, + 0x008B89, 0x008B89, 0x000000, 0xFFFFFF, + 0x008B8D, 0x008B8D, 0x000000, 0xFFFFFF, + 0x008B8F, 0x008B91, 0x000000, 0xFFFFFF, + 0x008B97, 0x008B97, 0x000000, 0xFFFFFF, + 0x008B9B, 0x008B9B, 0x000000, 0xFFFFFF, + 0x008B9D, 0x008B9D, 0x000000, 0xFFFFFF, + 0x008BA0, 0x008C36, 0x000000, 0xFFFFFF, + 0x008C38, 0x008C38, 0x000000, 0xFFFFFF, + 0x008C3A, 0x008C3A, 0x000000, 0xFFFFFF, + 0x008C40, 0x008C40, 0x000000, 0xFFFFFF, + 0x008C44, 0x008C44, 0x000000, 0xFFFFFF, + 0x008C51, 0x008C53, 0x000000, 0xFFFFFF, + 0x008C58, 0x008C59, 0x000000, 0xFFFFFF, + 0x008C5B, 0x008C5B, 0x000000, 0xFFFFFF, + 0x008C5E, 0x008C5E, 0x000000, 0xFFFFFF, + 0x008C60, 0x008C60, 0x000000, 0xFFFFFF, + 0x008C63, 0x008C63, 0x000000, 0xFFFFFF, + 0x008C67, 0x008C67, 0x000000, 0xFFFFFF, + 0x008C6E, 0x008C6E, 0x000000, 0xFFFFFF, + 0x008C74, 0x008C74, 0x000000, 0xFFFFFF, + 0x008C7C, 0x008C7C, 0x000000, 0xFFFFFF, + 0x008C7E, 0x008C7F, 0x000000, 0xFFFFFF, + 0x008C83, 0x008C83, 0x000000, 0xFFFFFF, + 0x008C87, 0x008C88, 0x000000, 0xFFFFFF, + 0x008C8B, 0x008C8B, 0x000000, 0xFFFFFF, + 0x008C8E, 0x008C8E, 0x000000, 0xFFFFFF, + 0x008C96, 0x008C96, 0x000000, 0xFFFFFF, + 0x008C9B, 0x008C9B, 0x000000, 0xFFFFFF, + 0x008C9F, 0x008C9F, 0x000000, 0xFFFFFF, + 0x008CA6, 0x008CA6, 0x000000, 0xFFFFFF, + 0x008CAD, 0x008CAE, 0x000000, 0xFFFFFF, + 0x008CB1, 0x008CB1, 0x000000, 0xFFFFFF, + 0x008CC6, 0x008CC6, 0x000000, 0xFFFFFF, + 0x008CC9, 0x008CC9, 0x000000, 0xFFFFFF, + 0x008CCB, 0x008CCB, 0x000000, 0xFFFFFF, + 0x008CCD, 0x008CCE, 0x000000, 0xFFFFFF, + 0x008CD0, 0x008CD0, 0x000000, 0xFFFFFF, + 0x008CD4, 0x008CD4, 0x000000, 0xFFFFFF, + 0x008CD6, 0x008CD6, 0x000000, 0xFFFFFF, + 0x008CD8, 0x008CD8, 0x000000, 0xFFFFFF, + 0x008CDB, 0x008CDB, 0x000000, 0xFFFFFF, + 0x008CE9, 0x008CE9, 0x000000, 0xFFFFFF, + 0x008CEB, 0x008CEB, 0x000000, 0xFFFFFF, + 0x008CEF, 0x008CEF, 0x000000, 0xFFFFFF, + 0x008CF2, 0x008CF2, 0x000000, 0xFFFFFF, + 0x008CF6, 0x008CF7, 0x000000, 0xFFFFFF, + 0x008CFF, 0x008CFF, 0x000000, 0xFFFFFF, + 0x008D01, 0x008D01, 0x000000, 0xFFFFFF, + 0x008D03, 0x008D03, 0x000000, 0xFFFFFF, + 0x008D0B, 0x008D0C, 0x000000, 0xFFFFFF, + 0x008D0E, 0x008D0E, 0x000000, 0xFFFFFF, + 0x008D11, 0x008D12, 0x000000, 0xFFFFFF, + 0x008D18, 0x008D18, 0x000000, 0xFFFFFF, + 0x008D1A, 0x008D1A, 0x000000, 0xFFFFFF, + 0x008D1C, 0x008D63, 0x000000, 0xFFFFFF, + 0x008D65, 0x008D65, 0x000000, 0xFFFFFF, + 0x008D6A, 0x008D6A, 0x000000, 0xFFFFFF, + 0x008D71, 0x008D71, 0x000000, 0xFFFFFF, + 0x008D75, 0x008D75, 0x000000, 0xFFFFFF, + 0x008D7A, 0x008D7A, 0x000000, 0xFFFFFF, + 0x008D7C, 0x008D7C, 0x000000, 0xFFFFFF, + 0x008D7E, 0x008D7F, 0x000000, 0xFFFFFF, + 0x008D82, 0x008D83, 0x000000, 0xFFFFFF, + 0x008D86, 0x008D88, 0x000000, 0xFFFFFF, + 0x008D8B, 0x008D8B, 0x000000, 0xFFFFFF, + 0x008D97, 0x008D98, 0x000000, 0xFFFFFF, + 0x008D9A, 0x008D9A, 0x000000, 0xFFFFFF, + 0x008D9D, 0x008D9E, 0x000000, 0xFFFFFF, + 0x008DA2, 0x008DA2, 0x000000, 0xFFFFFF, + 0x008DA4, 0x008DA4, 0x000000, 0xFFFFFF, + 0x008DA6, 0x008DA6, 0x000000, 0xFFFFFF, + 0x008DA9, 0x008DA9, 0x000000, 0xFFFFFF, + 0x008DB0, 0x008DB1, 0x000000, 0xFFFFFF, + 0x008DB8, 0x008DB8, 0x000000, 0xFFFFFF, + 0x008DBB, 0x008DBB, 0x000000, 0xFFFFFF, + 0x008DBD, 0x008DBD, 0x000000, 0xFFFFFF, + 0x008DC0, 0x008DC0, 0x000000, 0xFFFFFF, + 0x008DC3, 0x008DC4, 0x000000, 0xFFFFFF, + 0x008DC9, 0x008DCA, 0x000000, 0xFFFFFF, + 0x008DD2, 0x008DD2, 0x000000, 0xFFFFFF, + 0x008DD4, 0x008DD4, 0x000000, 0xFFFFFF, + 0x008DDE, 0x008DDE, 0x000000, 0xFFFFFF, + 0x008DE5, 0x008DE5, 0x000000, 0xFFFFFF, + 0x008DED, 0x008DED, 0x000000, 0xFFFFFF, + 0x008DF5, 0x008DF9, 0x000000, 0xFFFFFF, + 0x008DFB, 0x008DFB, 0x000000, 0xFFFFFF, + 0x008E01, 0x008E01, 0x000000, 0xFFFFFF, + 0x008E08, 0x008E08, 0x000000, 0xFFFFFF, + 0x008E0B, 0x008E0C, 0x000000, 0xFFFFFF, + 0x008E0E, 0x008E0E, 0x000000, 0xFFFFFF, + 0x008E28, 0x008E28, 0x000000, 0xFFFFFF, + 0x008E2A, 0x008E2A, 0x000000, 0xFFFFFF, + 0x008E2C, 0x008E2D, 0x000000, 0xFFFFFF, + 0x008E2F, 0x008E2F, 0x000000, 0xFFFFFF, + 0x008E32, 0x008E32, 0x000000, 0xFFFFFF, + 0x008E37, 0x008E37, 0x000000, 0xFFFFFF, + 0x008E3A, 0x008E3B, 0x000000, 0xFFFFFF, + 0x008E43, 0x008E43, 0x000000, 0xFFFFFF, + 0x008E46, 0x008E46, 0x000000, 0xFFFFFF, + 0x008E4F, 0x008E4F, 0x000000, 0xFFFFFF, + 0x008E51, 0x008E52, 0x000000, 0xFFFFFF, + 0x008E58, 0x008E58, 0x000000, 0xFFFFFF, + 0x008E68, 0x008E68, 0x000000, 0xFFFFFF, + 0x008E6B, 0x008E6B, 0x000000, 0xFFFFFF, + 0x008E6E, 0x008E6E, 0x000000, 0xFFFFFF, + 0x008E70, 0x008E71, 0x000000, 0xFFFFFF, + 0x008E75, 0x008E75, 0x000000, 0xFFFFFF, + 0x008E77, 0x008E77, 0x000000, 0xFFFFFF, + 0x008E79, 0x008E79, 0x000000, 0xFFFFFF, + 0x008E7D, 0x008E80, 0x000000, 0xFFFFFF, + 0x008E83, 0x008E83, 0x000000, 0xFFFFFF, + 0x008E8F, 0x008E8F, 0x000000, 0xFFFFFF, + 0x008E99, 0x008E99, 0x000000, 0xFFFFFF, + 0x008E9B, 0x008E9C, 0x000000, 0xFFFFFF, + 0x008EA2, 0x008EA2, 0x000000, 0xFFFFFF, + 0x008EA7, 0x008EA7, 0x000000, 0xFFFFFF, + 0x008EAD, 0x008EB1, 0x000000, 0xFFFFFF, + 0x008EB3, 0x008EB9, 0x000000, 0xFFFFFF, + 0x008EBB, 0x008EBC, 0x000000, 0xFFFFFF, + 0x008EBE, 0x008EBF, 0x000000, 0xFFFFFF, + 0x008EC1, 0x008EC1, 0x000000, 0xFFFFFF, + 0x008EC3, 0x008EC8, 0x000000, 0xFFFFFF, + 0x008ECE, 0x008ECE, 0x000000, 0xFFFFFF, + 0x008ED0, 0x008ED0, 0x000000, 0xFFFFFF, + 0x008ED5, 0x008ED6, 0x000000, 0xFFFFFF, + 0x008ED9, 0x008EDA, 0x000000, 0xFFFFFF, + 0x008EE2, 0x008EE4, 0x000000, 0xFFFFFF, + 0x008EEA, 0x008EEA, 0x000000, 0xFFFFFF, + 0x008EED, 0x008EED, 0x000000, 0xFFFFFF, + 0x008EF0, 0x008EF0, 0x000000, 0xFFFFFF, + 0x008EF2, 0x008EF3, 0x000000, 0xFFFFFF, + 0x008EFD, 0x008EFD, 0x000000, 0xFFFFFF, + 0x008F04, 0x008F04, 0x000000, 0xFFFFFF, + 0x008F0C, 0x008F0C, 0x000000, 0xFFFFFF, + 0x008F0F, 0x008F0F, 0x000000, 0xFFFFFF, + 0x008F19, 0x008F19, 0x000000, 0xFFFFFF, + 0x008F21, 0x008F22, 0x000000, 0xFFFFFF, + 0x008F27, 0x008F28, 0x000000, 0xFFFFFF, + 0x008F2B, 0x008F2B, 0x000000, 0xFFFFFF, + 0x008F2D, 0x008F2D, 0x000000, 0xFFFFFF, + 0x008F30, 0x008F31, 0x000000, 0xFFFFFF, + 0x008F3A, 0x008F3A, 0x000000, 0xFFFFFF, + 0x008F3C, 0x008F3D, 0x000000, 0xFFFFFF, + 0x008F41, 0x008F41, 0x000000, 0xFFFFFF, + 0x008F4A, 0x008F4A, 0x000000, 0xFFFFFF, + 0x008F4C, 0x008F4C, 0x000000, 0xFFFFFF, + 0x008F5C, 0x008F5C, 0x000000, 0xFFFFFF, + 0x008F65, 0x008F9A, 0x000000, 0xFFFFFF, + 0x008F9D, 0x008F9E, 0x000000, 0xFFFFFF, + 0x008FA0, 0x008FA2, 0x000000, 0xFFFFFF, + 0x008FA4, 0x008FA5, 0x000000, 0xFFFFFF, + 0x008FA7, 0x008FA7, 0x000000, 0xFFFFFF, + 0x008FA9, 0x008FAC, 0x000000, 0xFFFFFF, + 0x008FB3, 0x008FB3, 0x000000, 0xFFFFFF, + 0x008FB5, 0x008FBE, 0x000000, 0xFFFFFF, + 0x008FC0, 0x008FC1, 0x000000, 0xFFFFFF, + 0x008FC3, 0x008FC3, 0x000000, 0xFFFFFF, + 0x008FC7, 0x008FC8, 0x000000, 0xFFFFFF, + 0x008FCA, 0x008FCA, 0x000000, 0xFFFFFF, + 0x008FCC, 0x008FCC, 0x000000, 0xFFFFFF, + 0x008FCF, 0x008FD0, 0x000000, 0xFFFFFF, + 0x008FD8, 0x008FDF, 0x000000, 0xFFFFFF, + 0x008FE7, 0x008FE7, 0x000000, 0xFFFFFF, + 0x008FE9, 0x008FE9, 0x000000, 0xFFFFFF, + 0x008FEC, 0x008FEC, 0x000000, 0xFFFFFF, + 0x008FEF, 0x008FEF, 0x000000, 0xFFFFFF, + 0x008FF1, 0x008FF3, 0x000000, 0xFFFFFF, + 0x008FF9, 0x008FF9, 0x000000, 0xFFFFFF, + 0x009007, 0x00900A, 0x000000, 0xFFFFFF, + 0x00900E, 0x00900E, 0x000000, 0xFFFFFF, + 0x009012, 0x009013, 0x000000, 0xFFFFFF, + 0x009018, 0x009018, 0x000000, 0xFFFFFF, + 0x009025, 0x00902C, 0x000000, 0xFFFFFF, + 0x009030, 0x009030, 0x000000, 0xFFFFFF, + 0x009033, 0x009033, 0x000000, 0xFFFFFF, + 0x009037, 0x009037, 0x000000, 0xFFFFFF, + 0x009039, 0x00903B, 0x000000, 0xFFFFFF, + 0x009040, 0x009040, 0x000000, 0xFFFFFF, + 0x009043, 0x009043, 0x000000, 0xFFFFFF, + 0x009045, 0x009046, 0x000000, 0xFFFFFF, + 0x009048, 0x009048, 0x000000, 0xFFFFFF, + 0x00904C, 0x00904C, 0x000000, 0xFFFFFF, + 0x009056, 0x009057, 0x000000, 0xFFFFFF, + 0x00905A, 0x00905A, 0x000000, 0xFFFFFF, + 0x00905F, 0x00905F, 0x000000, 0xFFFFFF, + 0x009061, 0x009061, 0x000000, 0xFFFFFF, + 0x009064, 0x009066, 0x000000, 0xFFFFFF, + 0x00906A, 0x00906A, 0x000000, 0xFFFFFF, + 0x00906C, 0x00906C, 0x000000, 0xFFFFFF, + 0x009071, 0x009071, 0x000000, 0xFFFFFF, + 0x009089, 0x009089, 0x000000, 0xFFFFFF, + 0x00908C, 0x00908C, 0x000000, 0xFFFFFF, + 0x00908E, 0x00908E, 0x000000, 0xFFFFFF, + 0x009092, 0x009093, 0x000000, 0xFFFFFF, + 0x009096, 0x009096, 0x000000, 0xFFFFFF, + 0x00909A, 0x00909A, 0x000000, 0xFFFFFF, + 0x00909C, 0x00909D, 0x000000, 0xFFFFFF, + 0x0090A4, 0x0090A4, 0x000000, 0xFFFFFF, + 0x0090A8, 0x0090A9, 0x000000, 0xFFFFFF, + 0x0090AB, 0x0090AE, 0x000000, 0xFFFFFF, + 0x0090B7, 0x0090B7, 0x000000, 0xFFFFFF, + 0x0090B9, 0x0090BC, 0x000000, 0xFFFFFF, + 0x0090C0, 0x0090C0, 0x000000, 0xFFFFFF, + 0x0090C2, 0x0090C2, 0x000000, 0xFFFFFF, + 0x0090C4, 0x0090C4, 0x000000, 0xFFFFFF, + 0x0090C6, 0x0090C6, 0x000000, 0xFFFFFF, + 0x0090C9, 0x0090C9, 0x000000, 0xFFFFFF, + 0x0090CC, 0x0090CD, 0x000000, 0xFFFFFF, + 0x0090CF, 0x0090D3, 0x000000, 0xFFFFFF, + 0x0090DE, 0x0090DE, 0x000000, 0xFFFFFF, + 0x0090E6, 0x0090E7, 0x000000, 0xFFFFFF, + 0x0090EE, 0x0090EE, 0x000000, 0xFFFFFF, + 0x0090F6, 0x0090F8, 0x000000, 0xFFFFFF, + 0x00910A, 0x00910A, 0x000000, 0xFFFFFF, + 0x00910C, 0x00910C, 0x000000, 0xFFFFFF, + 0x009113, 0x009113, 0x000000, 0xFFFFFF, + 0x009115, 0x009115, 0x000000, 0xFFFFFF, + 0x009125, 0x009125, 0x000000, 0xFFFFFF, + 0x009137, 0x009137, 0x000000, 0xFFFFFF, + 0x00913C, 0x00913D, 0x000000, 0xFFFFFF, + 0x009142, 0x009142, 0x000000, 0xFFFFFF, + 0x009151, 0x009151, 0x000000, 0xFFFFFF, + 0x009154, 0x009154, 0x000000, 0xFFFFFF, + 0x009159, 0x009159, 0x000000, 0xFFFFFF, + 0x00915B, 0x00915E, 0x000000, 0xFFFFFF, + 0x009166, 0x009167, 0x000000, 0xFFFFFF, + 0x00916B, 0x00916B, 0x000000, 0xFFFFFF, + 0x00916D, 0x00916D, 0x000000, 0xFFFFFF, + 0x009170, 0x009171, 0x000000, 0xFFFFFF, + 0x009176, 0x009176, 0x000000, 0xFFFFFF, + 0x00917B, 0x00917F, 0x000000, 0xFFFFFF, + 0x009188, 0x009188, 0x000000, 0xFFFFFF, + 0x00918C, 0x00918C, 0x000000, 0xFFFFFF, + 0x00918E, 0x00918E, 0x000000, 0xFFFFFF, + 0x009194, 0x009198, 0x000000, 0xFFFFFF, + 0x0091A4, 0x0091A4, 0x000000, 0xFFFFFF, + 0x0091A6, 0x0091A6, 0x000000, 0xFFFFFF, + 0x0091A9, 0x0091A9, 0x000000, 0xFFFFFF, + 0x0091B6, 0x0091B6, 0x000000, 0xFFFFFF, + 0x0091B8, 0x0091B8, 0x000000, 0xFFFFFF, + 0x0091BB, 0x0091BB, 0x000000, 0xFFFFFF, + 0x0091BF, 0x0091BF, 0x000000, 0xFFFFFF, + 0x0091C4, 0x0091C4, 0x000000, 0xFFFFFF, + 0x0091C8, 0x0091C8, 0x000000, 0xFFFFFF, + 0x0091CA, 0x0091CA, 0x000000, 0xFFFFFF, + 0x0091D2, 0x0091D2, 0x000000, 0xFFFFFF, + 0x0091D6, 0x0091D6, 0x000000, 0xFFFFFF, + 0x0091DB, 0x0091DB, 0x000000, 0xFFFFFF, + 0x0091DE, 0x0091E1, 0x000000, 0xFFFFFF, + 0x0091E5, 0x0091E5, 0x000000, 0xFFFFFF, + 0x0091EF, 0x0091F0, 0x000000, 0xFFFFFF, + 0x0091F2, 0x0091F2, 0x000000, 0xFFFFFF, + 0x0091F6, 0x0091F6, 0x000000, 0xFFFFFF, + 0x0091FA, 0x0091FC, 0x000000, 0xFFFFFF, + 0x0091FE, 0x0091FE, 0x000000, 0xFFFFFF, + 0x009208, 0x009208, 0x000000, 0xFFFFFF, + 0x00920B, 0x00920B, 0x000000, 0xFFFFFF, + 0x00920E, 0x00920E, 0x000000, 0xFFFFFF, + 0x009213, 0x009213, 0x000000, 0xFFFFFF, + 0x009218, 0x009218, 0x000000, 0xFFFFFF, + 0x00921B, 0x00921B, 0x000000, 0xFFFFFF, + 0x00921D, 0x00921D, 0x000000, 0xFFFFFF, + 0x00921F, 0x009222, 0x000000, 0xFFFFFF, + 0x009228, 0x00922C, 0x000000, 0xFFFFFF, + 0x00922F, 0x00922F, 0x000000, 0xFFFFFF, + 0x009235, 0x009235, 0x000000, 0xFFFFFF, + 0x00923B, 0x00923C, 0x000000, 0xFFFFFF, + 0x009241, 0x009244, 0x000000, 0xFFFFFF, + 0x009247, 0x009247, 0x000000, 0xFFFFFF, + 0x009255, 0x009255, 0x000000, 0xFFFFFF, + 0x009258, 0x009259, 0x000000, 0xFFFFFF, + 0x00925C, 0x00925D, 0x000000, 0xFFFFFF, + 0x00925F, 0x00925F, 0x000000, 0xFFFFFF, + 0x009262, 0x009262, 0x000000, 0xFFFFFF, + 0x009268, 0x00926B, 0x000000, 0xFFFFFF, + 0x00926E, 0x00926E, 0x000000, 0xFFFFFF, + 0x009271, 0x009271, 0x000000, 0xFFFFFF, + 0x009273, 0x009275, 0x000000, 0xFFFFFF, + 0x009277, 0x009277, 0x000000, 0xFFFFFF, + 0x009281, 0x009281, 0x000000, 0xFFFFFF, + 0x009284, 0x009284, 0x000000, 0xFFFFFF, + 0x009289, 0x009289, 0x000000, 0xFFFFFF, + 0x00928F, 0x009290, 0x000000, 0xFFFFFF, + 0x009292, 0x009292, 0x000000, 0xFFFFFF, + 0x00929E, 0x00929F, 0x000000, 0xFFFFFF, + 0x0092AD, 0x0092B1, 0x000000, 0xFFFFFF, + 0x0092B8, 0x0092B8, 0x000000, 0xFFFFFF, + 0x0092BA, 0x0092BA, 0x000000, 0xFFFFFF, + 0x0092BD, 0x0092BF, 0x000000, 0xFFFFFF, + 0x0092D4, 0x0092D4, 0x000000, 0xFFFFFF, + 0x0092D6, 0x0092D6, 0x000000, 0xFFFFFF, + 0x0092DA, 0x0092DC, 0x000000, 0xFFFFFF, + 0x0092E2, 0x0092E3, 0x000000, 0xFFFFFF, + 0x0092E5, 0x0092E5, 0x000000, 0xFFFFFF, + 0x0092EB, 0x0092ED, 0x000000, 0xFFFFFF, + 0x0092F2, 0x0092F6, 0x000000, 0xFFFFFF, + 0x0092FD, 0x0092FD, 0x000000, 0xFFFFFF, + 0x009303, 0x009303, 0x000000, 0xFFFFFF, + 0x009305, 0x009305, 0x000000, 0xFFFFFF, + 0x009307, 0x009307, 0x000000, 0xFFFFFF, + 0x00930A, 0x00930A, 0x000000, 0xFFFFFF, + 0x009311, 0x009311, 0x000000, 0xFFFFFF, + 0x009317, 0x009317, 0x000000, 0xFFFFFF, + 0x00931C, 0x00931C, 0x000000, 0xFFFFFF, + 0x00932C, 0x00932C, 0x000000, 0xFFFFFF, + 0x009330, 0x009332, 0x000000, 0xFFFFFF, + 0x009337, 0x009337, 0x000000, 0xFFFFFF, + 0x00933A, 0x00933B, 0x000000, 0xFFFFFF, + 0x00933D, 0x009345, 0x000000, 0xFFFFFF, + 0x009348, 0x009348, 0x000000, 0xFFFFFF, + 0x009353, 0x009353, 0x000000, 0xFFFFFF, + 0x00935D, 0x00935D, 0x000000, 0xFFFFFF, + 0x00935F, 0x00935F, 0x000000, 0xFFFFFF, + 0x009362, 0x009362, 0x000000, 0xFFFFFF, + 0x009366, 0x009366, 0x000000, 0xFFFFFF, + 0x009368, 0x009369, 0x000000, 0xFFFFFF, + 0x00936B, 0x00936B, 0x000000, 0xFFFFFF, + 0x00936E, 0x00936F, 0x000000, 0xFFFFFF, + 0x009372, 0x009374, 0x000000, 0xFFFFFF, + 0x009378, 0x009378, 0x000000, 0xFFFFFF, + 0x00937D, 0x00937D, 0x000000, 0xFFFFFF, + 0x00937F, 0x00937F, 0x000000, 0xFFFFFF, + 0x009381, 0x009381, 0x000000, 0xFFFFFF, + 0x009384, 0x009387, 0x000000, 0xFFFFFF, + 0x00938B, 0x00938B, 0x000000, 0xFFFFFF, + 0x009390, 0x009390, 0x000000, 0xFFFFFF, + 0x009393, 0x009393, 0x000000, 0xFFFFFF, + 0x00939C, 0x00939C, 0x000000, 0xFFFFFF, + 0x0093A0, 0x0093A0, 0x000000, 0xFFFFFF, + 0x0093AB, 0x0093AB, 0x000000, 0xFFFFFF, + 0x0093AD, 0x0093AD, 0x000000, 0xFFFFFF, + 0x0093B6, 0x0093B6, 0x000000, 0xFFFFFF, + 0x0093B8, 0x0093BF, 0x000000, 0xFFFFFF, + 0x0093C1, 0x0093C1, 0x000000, 0xFFFFFF, + 0x0093C5, 0x0093C6, 0x000000, 0xFFFFFF, + 0x0093C9, 0x0093C9, 0x000000, 0xFFFFFF, + 0x0093CB, 0x0093CB, 0x000000, 0xFFFFFF, + 0x0093D3, 0x0093D3, 0x000000, 0xFFFFFF, + 0x0093DB, 0x0093DB, 0x000000, 0xFFFFFF, + 0x0093E0, 0x0093E0, 0x000000, 0xFFFFFF, + 0x0093E5, 0x0093E5, 0x000000, 0xFFFFFF, + 0x0093E9, 0x0093EB, 0x000000, 0xFFFFFF, + 0x0093ED, 0x0093ED, 0x000000, 0xFFFFFF, + 0x0093EF, 0x0093F4, 0x000000, 0xFFFFFF, + 0x009401, 0x009402, 0x000000, 0xFFFFFF, + 0x009404, 0x009405, 0x000000, 0xFFFFFF, + 0x009408, 0x009408, 0x000000, 0xFFFFFF, + 0x009417, 0x009417, 0x000000, 0xFFFFFF, + 0x00941A, 0x00941F, 0x000000, 0xFFFFFF, + 0x009421, 0x009427, 0x000000, 0xFFFFFF, + 0x00942D, 0x00942D, 0x000000, 0xFFFFFF, + 0x00942F, 0x00942F, 0x000000, 0xFFFFFF, + 0x009434, 0x009434, 0x000000, 0xFFFFFF, + 0x00943E, 0x00943E, 0x000000, 0xFFFFFF, + 0x009441, 0x009443, 0x000000, 0xFFFFFF, + 0x00944D, 0x00944E, 0x000000, 0xFFFFFF, + 0x009453, 0x009454, 0x000000, 0xFFFFFF, + 0x009456, 0x009456, 0x000000, 0xFFFFFF, + 0x009458, 0x00945C, 0x000000, 0xFFFFFF, + 0x00945F, 0x00945F, 0x000000, 0xFFFFFF, + 0x009461, 0x009461, 0x000000, 0xFFFFFF, + 0x009465, 0x009467, 0x000000, 0xFFFFFF, + 0x00946C, 0x00946C, 0x000000, 0xFFFFFF, + 0x009479, 0x00947B, 0x000000, 0xFFFFFF, + 0x009484, 0x009576, 0x000000, 0xFFFFFF, + 0x009578, 0x009579, 0x000000, 0xFFFFFF, + 0x00957E, 0x00957F, 0x000000, 0xFFFFFF, + 0x009581, 0x009581, 0x000000, 0xFFFFFF, + 0x009584, 0x009585, 0x000000, 0xFFFFFF, + 0x009587, 0x009587, 0x000000, 0xFFFFFF, + 0x00958A, 0x00958A, 0x000000, 0xFFFFFF, + 0x009595, 0x009597, 0x000000, 0xFFFFFF, + 0x009599, 0x00959A, 0x000000, 0xFFFFFF, + 0x00959D, 0x00959D, 0x000000, 0xFFFFFF, + 0x0095A0, 0x0095A0, 0x000000, 0xFFFFFF, + 0x0095A2, 0x0095A2, 0x000000, 0xFFFFFF, + 0x0095A6, 0x0095A7, 0x000000, 0xFFFFFF, + 0x0095AA, 0x0095AA, 0x000000, 0xFFFFFF, + 0x0095AF, 0x0095AF, 0x000000, 0xFFFFFF, + 0x0095B2, 0x0095B4, 0x000000, 0xFFFFFF, + 0x0095B8, 0x0095B8, 0x000000, 0xFFFFFF, + 0x0095C1, 0x0095C2, 0x000000, 0xFFFFFF, + 0x0095C4, 0x0095C4, 0x000000, 0xFFFFFF, + 0x0095CE, 0x0095CF, 0x000000, 0xFFFFFF, + 0x0095D7, 0x0095D9, 0x000000, 0xFFFFFF, + 0x0095DD, 0x0095DD, 0x000000, 0xFFFFFF, + 0x0095E6, 0x00961B, 0x000000, 0xFFFFFF, + 0x00961D, 0x00961D, 0x000000, 0xFFFFFF, + 0x00961F, 0x00961F, 0x000000, 0xFFFFFF, + 0x009625, 0x009627, 0x000000, 0xFFFFFF, + 0x009629, 0x009629, 0x000000, 0xFFFFFF, + 0x00962B, 0x00962B, 0x000000, 0xFFFFFF, + 0x009633, 0x009638, 0x000000, 0xFFFFFF, + 0x00963E, 0x00963E, 0x000000, 0xFFFFFF, + 0x009641, 0x009641, 0x000000, 0xFFFFFF, + 0x009645, 0x009649, 0x000000, 0xFFFFFF, + 0x009652, 0x009652, 0x000000, 0xFFFFFF, + 0x009655, 0x009657, 0x000000, 0xFFFFFF, + 0x009659, 0x00965A, 0x000000, 0xFFFFFF, + 0x009660, 0x009660, 0x000000, 0xFFFFFF, + 0x009665, 0x009669, 0x000000, 0xFFFFFF, + 0x00966E, 0x00966E, 0x000000, 0xFFFFFF, + 0x009679, 0x00967B, 0x000000, 0xFFFFFF, + 0x00967F, 0x00967F, 0x000000, 0xFFFFFF, + 0x009681, 0x009682, 0x000000, 0xFFFFFF, + 0x00968C, 0x00968C, 0x000000, 0xFFFFFF, + 0x00968F, 0x009690, 0x000000, 0xFFFFFF, + 0x009696, 0x009696, 0x000000, 0xFFFFFF, + 0x00969A, 0x00969A, 0x000000, 0xFFFFFF, + 0x00969D, 0x00969D, 0x000000, 0xFFFFFF, + 0x00969F, 0x0096A0, 0x000000, 0xFFFFFF, + 0x0096A3, 0x0096A3, 0x000000, 0xFFFFFF, + 0x0096A5, 0x0096A6, 0x000000, 0xFFFFFF, + 0x0096AB, 0x0096AB, 0x000000, 0xFFFFFF, + 0x0096AD, 0x0096AD, 0x000000, 0xFFFFFF, + 0x0096AF, 0x0096AF, 0x000000, 0xFFFFFF, + 0x0096B2, 0x0096B2, 0x000000, 0xFFFFFF, + 0x0096B5, 0x0096B7, 0x000000, 0xFFFFFF, + 0x0096BA, 0x0096BA, 0x000000, 0xFFFFFF, + 0x0096BD, 0x0096BE, 0x000000, 0xFFFFFF, + 0x0096CF, 0x0096D1, 0x000000, 0xFFFFFF, + 0x0096E0, 0x0096E0, 0x000000, 0xFFFFFF, + 0x0096E4, 0x0096E4, 0x000000, 0xFFFFFF, + 0x0096E6, 0x0096E7, 0x000000, 0xFFFFFF, + 0x0096EB, 0x0096EE, 0x000000, 0xFFFFFF, + 0x0096F3, 0x0096F4, 0x000000, 0xFFFFFF, + 0x0096FC, 0x0096FC, 0x000000, 0xFFFFFF, + 0x0096FE, 0x0096FE, 0x000000, 0xFFFFFF, + 0x009701, 0x009701, 0x000000, 0xFFFFFF, + 0x009703, 0x009703, 0x000000, 0xFFFFFF, + 0x00970A, 0x00970A, 0x000000, 0xFFFFFF, + 0x00970C, 0x00970C, 0x000000, 0xFFFFFF, + 0x009714, 0x009715, 0x000000, 0xFFFFFF, + 0x009717, 0x009717, 0x000000, 0xFFFFFF, + 0x00971A, 0x00971B, 0x000000, 0xFFFFFF, + 0x009721, 0x009721, 0x000000, 0xFFFFFF, + 0x00972D, 0x00972D, 0x000000, 0xFFFFFF, + 0x009731, 0x009731, 0x000000, 0xFFFFFF, + 0x009733, 0x009734, 0x000000, 0xFFFFFF, + 0x009736, 0x009737, 0x000000, 0xFFFFFF, + 0x00973B, 0x00973C, 0x000000, 0xFFFFFF, + 0x009740, 0x009741, 0x000000, 0xFFFFFF, + 0x009745, 0x009745, 0x000000, 0xFFFFFF, + 0x00974A, 0x00974A, 0x000000, 0xFFFFFF, + 0x00974C, 0x009751, 0x000000, 0xFFFFFF, + 0x009753, 0x009755, 0x000000, 0xFFFFFF, + 0x009757, 0x009757, 0x000000, 0xFFFFFF, + 0x009759, 0x009759, 0x000000, 0xFFFFFF, + 0x00975D, 0x00975D, 0x000000, 0xFFFFFF, + 0x00975F, 0x00975F, 0x000000, 0xFFFFFF, + 0x009763, 0x009765, 0x000000, 0xFFFFFF, + 0x009767, 0x009767, 0x000000, 0xFFFFFF, + 0x00976B, 0x00976B, 0x000000, 0xFFFFFF, + 0x00976D, 0x00976D, 0x000000, 0xFFFFFF, + 0x00976F, 0x00976F, 0x000000, 0xFFFFFF, + 0x009771, 0x009771, 0x000000, 0xFFFFFF, + 0x009775, 0x009775, 0x000000, 0xFFFFFF, + 0x009779, 0x009779, 0x000000, 0xFFFFFF, + 0x009786, 0x009787, 0x000000, 0xFFFFFF, + 0x009789, 0x009789, 0x000000, 0xFFFFFF, + 0x00978C, 0x00978C, 0x000000, 0xFFFFFF, + 0x009790, 0x009793, 0x000000, 0xFFFFFF, + 0x009795, 0x009796, 0x000000, 0xFFFFFF, + 0x00979B, 0x00979B, 0x000000, 0xFFFFFF, + 0x00979F, 0x00979F, 0x000000, 0xFFFFFF, + 0x0097A7, 0x0097A7, 0x000000, 0xFFFFFF, + 0x0097A9, 0x0097A9, 0x000000, 0xFFFFFF, + 0x0097AF, 0x0097B2, 0x000000, 0xFFFFFF, + 0x0097B4, 0x0097B5, 0x000000, 0xFFFFFF, + 0x0097B8, 0x0097B8, 0x000000, 0xFFFFFF, + 0x0097BA, 0x0097BA, 0x000000, 0xFFFFFF, + 0x0097BC, 0x0097BE, 0x000000, 0xFFFFFF, + 0x0097C0, 0x0097C0, 0x000000, 0xFFFFFF, + 0x0097C2, 0x0097C2, 0x000000, 0xFFFFFF, + 0x0097C8, 0x0097C8, 0x000000, 0xFFFFFF, + 0x0097CA, 0x0097CA, 0x000000, 0xFFFFFF, + 0x0097D1, 0x0097D2, 0x000000, 0xFFFFFF, + 0x0097DA, 0x0097DB, 0x000000, 0xFFFFFF, + 0x0097E0, 0x0097E0, 0x000000, 0xFFFFFF, + 0x0097E2, 0x0097E2, 0x000000, 0xFFFFFF, + 0x0097E4, 0x0097E4, 0x000000, 0xFFFFFF, + 0x0097E6, 0x0097EC, 0x000000, 0xFFFFFF, + 0x0097EE, 0x0097EF, 0x000000, 0xFFFFFF, + 0x0097F2, 0x0097F2, 0x000000, 0xFFFFFF, + 0x0097F4, 0x0097F5, 0x000000, 0xFFFFFF, + 0x0097F7, 0x0097F7, 0x000000, 0xFFFFFF, + 0x0097FC, 0x0097FC, 0x000000, 0xFFFFFF, + 0x009809, 0x009809, 0x000000, 0xFFFFFF, + 0x00980B, 0x00980B, 0x000000, 0xFFFFFF, + 0x009814, 0x009815, 0x000000, 0xFFFFFF, + 0x009819, 0x00981A, 0x000000, 0xFFFFFF, + 0x00981F, 0x00981F, 0x000000, 0xFFFFFF, + 0x009822, 0x009823, 0x000000, 0xFFFFFF, + 0x009825, 0x009825, 0x000000, 0xFFFFFF, + 0x00982A, 0x00982A, 0x000000, 0xFFFFFF, + 0x00982C, 0x00982C, 0x000000, 0xFFFFFF, + 0x00982E, 0x00982E, 0x000000, 0xFFFFFF, + 0x009831, 0x009831, 0x000000, 0xFFFFFF, + 0x009833, 0x009834, 0x000000, 0xFFFFFF, + 0x009836, 0x009836, 0x000000, 0xFFFFFF, + 0x00983A, 0x00983A, 0x000000, 0xFFFFFF, + 0x00983C, 0x009840, 0x000000, 0xFFFFFF, + 0x009842, 0x009842, 0x000000, 0xFFFFFF, + 0x009847, 0x009847, 0x000000, 0xFFFFFF, + 0x00984B, 0x00984B, 0x000000, 0xFFFFFF, + 0x009854, 0x009856, 0x000000, 0xFFFFFF, + 0x00985A, 0x00985A, 0x000000, 0xFFFFFF, + 0x009861, 0x009861, 0x000000, 0xFFFFFF, + 0x009866, 0x009866, 0x000000, 0xFFFFFF, + 0x009868, 0x009868, 0x000000, 0xFFFFFF, + 0x00986C, 0x00986E, 0x000000, 0xFFFFFF, + 0x009875, 0x0098A7, 0x000000, 0xFFFFFF, + 0x0098AA, 0x0098AB, 0x000000, 0xFFFFFF, + 0x0098B0, 0x0098B0, 0x000000, 0xFFFFFF, + 0x0098B4, 0x0098B5, 0x000000, 0xFFFFFF, + 0x0098B7, 0x0098B7, 0x000000, 0xFFFFFF, + 0x0098B9, 0x0098B9, 0x000000, 0xFFFFFF, + 0x0098C3, 0x0098C3, 0x000000, 0xFFFFFF, + 0x0098C5, 0x0098C5, 0x000000, 0xFFFFFF, + 0x0098C7, 0x0098C8, 0x000000, 0xFFFFFF, + 0x0098CA, 0x0098CA, 0x000000, 0xFFFFFF, + 0x0098CD, 0x0098DA, 0x000000, 0xFFFFFF, + 0x0098DC, 0x0098DE, 0x000000, 0xFFFFFF, + 0x0098E0, 0x0098E1, 0x000000, 0xFFFFFF, + 0x0098E4, 0x0098E4, 0x000000, 0xFFFFFF, + 0x0098E6, 0x0098E6, 0x000000, 0xFFFFFF, + 0x0098E8, 0x0098E8, 0x000000, 0xFFFFFF, + 0x0098EC, 0x0098EC, 0x000000, 0xFFFFFF, + 0x0098EE, 0x0098EE, 0x000000, 0xFFFFFF, + 0x0098F0, 0x0098F1, 0x000000, 0xFFFFFF, + 0x0098F3, 0x0098F3, 0x000000, 0xFFFFFF, + 0x0098F5, 0x0098F5, 0x000000, 0xFFFFFF, + 0x0098F7, 0x0098F8, 0x000000, 0xFFFFFF, + 0x0098FB, 0x0098FB, 0x000000, 0xFFFFFF, + 0x0098FF, 0x0098FF, 0x000000, 0xFFFFFF, + 0x009901, 0x009901, 0x000000, 0xFFFFFF, + 0x009904, 0x009904, 0x000000, 0xFFFFFF, + 0x009906, 0x009906, 0x000000, 0xFFFFFF, + 0x00990B, 0x00990B, 0x000000, 0xFFFFFF, + 0x00990D, 0x00990F, 0x000000, 0xFFFFFF, + 0x009919, 0x009919, 0x000000, 0xFFFFFF, + 0x00991C, 0x00991D, 0x000000, 0xFFFFFF, + 0x009920, 0x009920, 0x000000, 0xFFFFFF, + 0x009922, 0x009923, 0x000000, 0xFFFFFF, + 0x009926, 0x009926, 0x000000, 0xFFFFFF, + 0x009934, 0x009934, 0x000000, 0xFFFFFF, + 0x009936, 0x009939, 0x000000, 0xFFFFFF, + 0x00993B, 0x00993B, 0x000000, 0xFFFFFF, + 0x009940, 0x009940, 0x000000, 0xFFFFFF, + 0x009942, 0x009942, 0x000000, 0xFFFFFF, + 0x009944, 0x009944, 0x000000, 0xFFFFFF, + 0x009946, 0x009946, 0x000000, 0xFFFFFF, + 0x00994A, 0x00994A, 0x000000, 0xFFFFFF, + 0x00994D, 0x00994D, 0x000000, 0xFFFFFF, + 0x00994F, 0x00994F, 0x000000, 0xFFFFFF, + 0x00995A, 0x00995A, 0x000000, 0xFFFFFF, + 0x00995D, 0x00995D, 0x000000, 0xFFFFFF, + 0x009960, 0x009960, 0x000000, 0xFFFFFF, + 0x009962, 0x009995, 0x000000, 0xFFFFFF, + 0x00999A, 0x00999B, 0x000000, 0xFFFFFF, + 0x00999F, 0x0099A0, 0x000000, 0xFFFFFF, + 0x0099A2, 0x0099A2, 0x000000, 0xFFFFFF, + 0x0099A4, 0x0099A4, 0x000000, 0xFFFFFF, + 0x0099A9, 0x0099AA, 0x000000, 0xFFFFFF, + 0x0099B6, 0x0099B8, 0x000000, 0xFFFFFF, + 0x0099BC, 0x0099BC, 0x000000, 0xFFFFFF, + 0x0099BE, 0x0099C0, 0x000000, 0xFFFFFF, + 0x0099C4, 0x0099C6, 0x000000, 0xFFFFFF, + 0x0099C8, 0x0099C8, 0x000000, 0xFFFFFF, + 0x0099CA, 0x0099CA, 0x000000, 0xFFFFFF, + 0x0099DA, 0x0099DA, 0x000000, 0xFFFFFF, + 0x0099DE, 0x0099DE, 0x000000, 0xFFFFFF, + 0x0099E0, 0x0099E1, 0x000000, 0xFFFFFF, + 0x0099E6, 0x0099E6, 0x000000, 0xFFFFFF, + 0x0099E8, 0x0099E8, 0x000000, 0xFFFFFF, + 0x0099EB, 0x0099EB, 0x000000, 0xFFFFFF, + 0x0099EF, 0x0099EF, 0x000000, 0xFFFFFF, + 0x0099F2, 0x0099F3, 0x000000, 0xFFFFFF, + 0x0099F5, 0x0099F5, 0x000000, 0xFFFFFF, + 0x009A00, 0x009A00, 0x000000, 0xFFFFFF, + 0x009A08, 0x009A08, 0x000000, 0xFFFFFF, + 0x009A0C, 0x009A0C, 0x000000, 0xFFFFFF, + 0x009A10, 0x009A10, 0x000000, 0xFFFFFF, + 0x009A12, 0x009A13, 0x000000, 0xFFFFFF, + 0x009A17, 0x009A18, 0x000000, 0xFFFFFF, + 0x009A1F, 0x009A1F, 0x000000, 0xFFFFFF, + 0x009A21, 0x009A21, 0x000000, 0xFFFFFF, + 0x009A26, 0x009A26, 0x000000, 0xFFFFFF, + 0x009A28, 0x009A28, 0x000000, 0xFFFFFF, + 0x009A2F, 0x009A2F, 0x000000, 0xFFFFFF, + 0x009A33, 0x009A33, 0x000000, 0xFFFFFF, + 0x009A3B, 0x009A3C, 0x000000, 0xFFFFFF, + 0x009A47, 0x009A47, 0x000000, 0xFFFFFF, + 0x009A4B, 0x009A4B, 0x000000, 0xFFFFFF, + 0x009A51, 0x009A51, 0x000000, 0xFFFFFF, + 0x009A58, 0x009A58, 0x000000, 0xFFFFFF, + 0x009A5C, 0x009A5D, 0x000000, 0xFFFFFF, + 0x009A61, 0x009A61, 0x000000, 0xFFFFFF, + 0x009A63, 0x009A63, 0x000000, 0xFFFFFF, + 0x009A6C, 0x009AA7, 0x000000, 0xFFFFFF, + 0x009AA9, 0x009AAA, 0x000000, 0xFFFFFF, + 0x009AAC, 0x009AAC, 0x000000, 0xFFFFFF, + 0x009AAE, 0x009AAE, 0x000000, 0xFFFFFF, + 0x009AB2, 0x009AB2, 0x000000, 0xFFFFFF, + 0x009AB5, 0x009AB6, 0x000000, 0xFFFFFF, + 0x009ABA, 0x009ABA, 0x000000, 0xFFFFFF, + 0x009ABD, 0x009ABD, 0x000000, 0xFFFFFF, + 0x009AC3, 0x009AC5, 0x000000, 0xFFFFFF, + 0x009AC8, 0x009AC9, 0x000000, 0xFFFFFF, + 0x009ACB, 0x009ACC, 0x000000, 0xFFFFFF, + 0x009ACE, 0x009ACE, 0x000000, 0xFFFFFF, + 0x009AD7, 0x009AD7, 0x000000, 0xFFFFFF, + 0x009AD9, 0x009ADB, 0x000000, 0xFFFFFF, + 0x009ADD, 0x009ADE, 0x000000, 0xFFFFFF, + 0x009AE0, 0x009AE0, 0x000000, 0xFFFFFF, + 0x009AE2, 0x009AE2, 0x000000, 0xFFFFFF, + 0x009AE4, 0x009AE5, 0x000000, 0xFFFFFF, + 0x009AE8, 0x009AEA, 0x000000, 0xFFFFFF, + 0x009AF0, 0x009AF0, 0x000000, 0xFFFFFF, + 0x009AF4, 0x009AF5, 0x000000, 0xFFFFFF, + 0x009AF8, 0x009AF8, 0x000000, 0xFFFFFF, + 0x009AFF, 0x009B00, 0x000000, 0xFFFFFF, + 0x009B02, 0x009B02, 0x000000, 0xFFFFFF, + 0x009B07, 0x009B07, 0x000000, 0xFFFFFF, + 0x009B09, 0x009B09, 0x000000, 0xFFFFFF, + 0x009B0F, 0x009B0F, 0x000000, 0xFFFFFF, + 0x009B13, 0x009B14, 0x000000, 0xFFFFFF, + 0x009B1B, 0x009B1D, 0x000000, 0xFFFFFF, + 0x009B21, 0x009B21, 0x000000, 0xFFFFFF, + 0x009B26, 0x009B26, 0x000000, 0xFFFFFF, + 0x009B2A, 0x009B2A, 0x000000, 0xFFFFFF, + 0x009B2C, 0x009B2D, 0x000000, 0xFFFFFF, + 0x009B30, 0x009B30, 0x000000, 0xFFFFFF, + 0x009B34, 0x009B34, 0x000000, 0xFFFFFF, + 0x009B36, 0x009B36, 0x000000, 0xFFFFFF, + 0x009B38, 0x009B39, 0x000000, 0xFFFFFF, + 0x009B3D, 0x009B3D, 0x000000, 0xFFFFFF, + 0x009B40, 0x009B40, 0x000000, 0xFFFFFF, + 0x009B47, 0x009B47, 0x000000, 0xFFFFFF, + 0x009B49, 0x009B49, 0x000000, 0xFFFFFF, + 0x009B50, 0x009B50, 0x000000, 0xFFFFFF, + 0x009B53, 0x009B53, 0x000000, 0xFFFFFF, + 0x009B57, 0x009B57, 0x000000, 0xFFFFFF, + 0x009B5C, 0x009B5E, 0x000000, 0xFFFFFF, + 0x009B62, 0x009B63, 0x000000, 0xFFFFFF, + 0x009B65, 0x009B65, 0x000000, 0xFFFFFF, + 0x009B69, 0x009B6B, 0x000000, 0xFFFFFF, + 0x009B6D, 0x009B6E, 0x000000, 0xFFFFFF, + 0x009B72, 0x009B73, 0x000000, 0xFFFFFF, + 0x009B78, 0x009B79, 0x000000, 0xFFFFFF, + 0x009B7F, 0x009B7F, 0x000000, 0xFFFFFF, + 0x009B81, 0x009B81, 0x000000, 0xFFFFFF, + 0x009B83, 0x009B84, 0x000000, 0xFFFFFF, + 0x009B89, 0x009B8F, 0x000000, 0xFFFFFF, + 0x009B94, 0x009B94, 0x000000, 0xFFFFFF, + 0x009B96, 0x009B99, 0x000000, 0xFFFFFF, + 0x009B9C, 0x009B9D, 0x000000, 0xFFFFFF, + 0x009B9F, 0x009B9F, 0x000000, 0xFFFFFF, + 0x009BA3, 0x009BA3, 0x000000, 0xFFFFFF, + 0x009BA7, 0x009BA7, 0x000000, 0xFFFFFF, + 0x009BA9, 0x009BA9, 0x000000, 0xFFFFFF, + 0x009BAC, 0x009BAC, 0x000000, 0xFFFFFF, + 0x009BB0, 0x009BB4, 0x000000, 0xFFFFFF, + 0x009BB7, 0x009BB7, 0x000000, 0xFFFFFF, + 0x009BBA, 0x009BBC, 0x000000, 0xFFFFFF, + 0x009BBE, 0x009BBE, 0x000000, 0xFFFFFF, + 0x009BC2, 0x009BC2, 0x000000, 0xFFFFFF, + 0x009BC5, 0x009BC5, 0x000000, 0xFFFFFF, + 0x009BCB, 0x009BD2, 0x000000, 0xFFFFFF, + 0x009BD8, 0x009BD8, 0x000000, 0xFFFFFF, + 0x009BDD, 0x009BDD, 0x000000, 0xFFFFFF, + 0x009BDF, 0x009BDF, 0x000000, 0xFFFFFF, + 0x009BE3, 0x009BE3, 0x000000, 0xFFFFFF, + 0x009BE9, 0x009BE9, 0x000000, 0xFFFFFF, + 0x009BED, 0x009BEF, 0x000000, 0xFFFFFF, + 0x009BF1, 0x009BF6, 0x000000, 0xFFFFFF, + 0x009BF9, 0x009BFC, 0x000000, 0xFFFFFF, + 0x009BFE, 0x009C04, 0x000000, 0xFFFFFF, + 0x009C0A, 0x009C0A, 0x000000, 0xFFFFFF, + 0x009C0C, 0x009C0C, 0x000000, 0xFFFFFF, + 0x009C0F, 0x009C11, 0x000000, 0xFFFFFF, + 0x009C15, 0x009C16, 0x000000, 0xFFFFFF, + 0x009C18, 0x009C1B, 0x000000, 0xFFFFFF, + 0x009C1E, 0x009C20, 0x000000, 0xFFFFFF, + 0x009C22, 0x009C22, 0x000000, 0xFFFFFF, + 0x009C26, 0x009C27, 0x000000, 0xFFFFFF, + 0x009C2A, 0x009C2A, 0x000000, 0xFFFFFF, + 0x009C2E, 0x009C30, 0x000000, 0xFFFFFF, + 0x009C35, 0x009C35, 0x000000, 0xFFFFFF, + 0x009C38, 0x009C38, 0x000000, 0xFFFFFF, + 0x009C3A, 0x009C3A, 0x000000, 0xFFFFFF, + 0x009C42, 0x009C43, 0x000000, 0xFFFFFF, + 0x009C45, 0x009C45, 0x000000, 0xFFFFFF, + 0x009C47, 0x009C47, 0x000000, 0xFFFFFF, + 0x009C4F, 0x009C4F, 0x000000, 0xFFFFFF, + 0x009C51, 0x009C51, 0x000000, 0xFFFFFF, + 0x009C53, 0x009C53, 0x000000, 0xFFFFFF, + 0x009C5A, 0x009C5D, 0x000000, 0xFFFFFF, + 0x009C61, 0x009C61, 0x000000, 0xFFFFFF, + 0x009C64, 0x009C65, 0x000000, 0xFFFFFF, + 0x009C69, 0x009C6C, 0x000000, 0xFFFFFF, + 0x009C6F, 0x009C70, 0x000000, 0xFFFFFF, + 0x009C72, 0x009C72, 0x000000, 0xFFFFFF, + 0x009C76, 0x009C76, 0x000000, 0xFFFFFF, + 0x009C7B, 0x009CE4, 0x000000, 0xFFFFFF, + 0x009CE8, 0x009CE8, 0x000000, 0xFFFFFF, + 0x009CEB, 0x009CEC, 0x000000, 0xFFFFFF, + 0x009CEE, 0x009CF0, 0x000000, 0xFFFFFF, + 0x009CF8, 0x009CF8, 0x000000, 0xFFFFFF, + 0x009CFE, 0x009CFE, 0x000000, 0xFFFFFF, + 0x009D01, 0x009D02, 0x000000, 0xFFFFFF, + 0x009D0A, 0x009D0F, 0x000000, 0xFFFFFF, + 0x009D11, 0x009D11, 0x000000, 0xFFFFFF, + 0x009D13, 0x009D13, 0x000000, 0xFFFFFF, + 0x009D16, 0x009D16, 0x000000, 0xFFFFFF, + 0x009D1A, 0x009D1A, 0x000000, 0xFFFFFF, + 0x009D1C, 0x009D1C, 0x000000, 0xFFFFFF, + 0x009D21, 0x009D21, 0x000000, 0xFFFFFF, + 0x009D24, 0x009D24, 0x000000, 0xFFFFFF, + 0x009D27, 0x009D27, 0x000000, 0xFFFFFF, + 0x009D2A, 0x009D2C, 0x000000, 0xFFFFFF, + 0x009D32, 0x009D32, 0x000000, 0xFFFFFF, + 0x009D34, 0x009D35, 0x000000, 0xFFFFFF, + 0x009D39, 0x009D3A, 0x000000, 0xFFFFFF, + 0x009D3C, 0x009D3C, 0x000000, 0xFFFFFF, + 0x009D44, 0x009D44, 0x000000, 0xFFFFFF, + 0x009D46, 0x009D49, 0x000000, 0xFFFFFF, + 0x009D4D, 0x009D4E, 0x000000, 0xFFFFFF, + 0x009D50, 0x009D50, 0x000000, 0xFFFFFF, + 0x009D55, 0x009D55, 0x000000, 0xFFFFFF, + 0x009D5E, 0x009D5E, 0x000000, 0xFFFFFF, + 0x009D62, 0x009D66, 0x000000, 0xFFFFFF, + 0x009D6D, 0x009D6E, 0x000000, 0xFFFFFF, + 0x009D76, 0x009D76, 0x000000, 0xFFFFFF, + 0x009D7A, 0x009D7A, 0x000000, 0xFFFFFF, + 0x009D7C, 0x009D7C, 0x000000, 0xFFFFFF, + 0x009D7E, 0x009D7E, 0x000000, 0xFFFFFF, + 0x009D83, 0x009D83, 0x000000, 0xFFFFFF, + 0x009D8D, 0x009D8F, 0x000000, 0xFFFFFF, + 0x009D91, 0x009D91, 0x000000, 0xFFFFFF, + 0x009D93, 0x009D93, 0x000000, 0xFFFFFF, + 0x009D95, 0x009D95, 0x000000, 0xFFFFFF, + 0x009DA5, 0x009DA5, 0x000000, 0xFFFFFF, + 0x009DAB, 0x009DAB, 0x000000, 0xFFFFFF, + 0x009DAE, 0x009DAE, 0x000000, 0xFFFFFF, + 0x009DB0, 0x009DB0, 0x000000, 0xFFFFFF, + 0x009DBD, 0x009DBD, 0x000000, 0xFFFFFF, + 0x009DC0, 0x009DC0, 0x000000, 0xFFFFFF, + 0x009DC4, 0x009DC4, 0x000000, 0xFFFFFF, + 0x009DC6, 0x009DC6, 0x000000, 0xFFFFFF, + 0x009DC9, 0x009DC9, 0x000000, 0xFFFFFF, + 0x009DD4, 0x009DD4, 0x000000, 0xFFFFFF, + 0x009DE0, 0x009DE0, 0x000000, 0xFFFFFF, + 0x009DE7, 0x009DE7, 0x000000, 0xFFFFFF, + 0x009DEA, 0x009DEA, 0x000000, 0xFFFFFF, + 0x009DF1, 0x009DF1, 0x000000, 0xFFFFFF, + 0x009DFC, 0x009DFC, 0x000000, 0xFFFFFF, + 0x009E08, 0x009E08, 0x000000, 0xFFFFFF, + 0x009E0A, 0x009E0A, 0x000000, 0xFFFFFF, + 0x009E0C, 0x009E0C, 0x000000, 0xFFFFFF, + 0x009E0E, 0x009E0E, 0x000000, 0xFFFFFF, + 0x009E16, 0x009E16, 0x000000, 0xFFFFFF, + 0x009E18, 0x009E18, 0x000000, 0xFFFFFF, + 0x009E1C, 0x009E1C, 0x000000, 0xFFFFFF, + 0x009E1F, 0x009E74, 0x000000, 0xFFFFFF, + 0x009E76, 0x009E78, 0x000000, 0xFFFFFF, + 0x009E7B, 0x009E7B, 0x000000, 0xFFFFFF, + 0x009E7E, 0x009E7E, 0x000000, 0xFFFFFF, + 0x009E81, 0x009E81, 0x000000, 0xFFFFFF, + 0x009E84, 0x009E85, 0x000000, 0xFFFFFF, + 0x009E8F, 0x009E90, 0x000000, 0xFFFFFF, + 0x009E95, 0x009E96, 0x000000, 0xFFFFFF, + 0x009E98, 0x009E98, 0x000000, 0xFFFFFF, + 0x009E9E, 0x009E9E, 0x000000, 0xFFFFFF, + 0x009EA2, 0x009EA3, 0x000000, 0xFFFFFF, + 0x009EA6, 0x009EA6, 0x000000, 0xFFFFFF, + 0x009EA8, 0x009EA8, 0x000000, 0xFFFFFF, + 0x009EAA, 0x009EAC, 0x000000, 0xFFFFFF, + 0x009EAF, 0x009EAF, 0x000000, 0xFFFFFF, + 0x009EB1, 0x009EB3, 0x000000, 0xFFFFFF, + 0x009EB8, 0x009EBA, 0x000000, 0xFFFFFF, + 0x009EBD, 0x009EBD, 0x000000, 0xFFFFFF, + 0x009EBF, 0x009EBF, 0x000000, 0xFFFFFF, + 0x009EC1, 0x009EC1, 0x000000, 0xFFFFFF, + 0x009EC4, 0x009EC7, 0x000000, 0xFFFFFF, + 0x009EC9, 0x009ECB, 0x000000, 0xFFFFFF, + 0x009ED2, 0x009ED2, 0x000000, 0xFFFFFF, + 0x009ED7, 0x009ED7, 0x000000, 0xFFFFFF, + 0x009ED9, 0x009ED9, 0x000000, 0xFFFFFF, + 0x009EE1, 0x009EE3, 0x000000, 0xFFFFFF, + 0x009EE9, 0x009EEA, 0x000000, 0xFFFFFF, + 0x009EEC, 0x009EEC, 0x000000, 0xFFFFFF, + 0x009EF1, 0x009EF1, 0x000000, 0xFFFFFF, + 0x009EF8, 0x009EF8, 0x000000, 0xFFFFFF, + 0x009EFE, 0x009EFE, 0x000000, 0xFFFFFF, + 0x009F02, 0x009F05, 0x000000, 0xFFFFFF, + 0x009F08, 0x009F08, 0x000000, 0xFFFFFF, + 0x009F0B, 0x009F0D, 0x000000, 0xFFFFFF, + 0x009F11, 0x009F11, 0x000000, 0xFFFFFF, + 0x009F14, 0x009F14, 0x000000, 0xFFFFFF, + 0x009F17, 0x009F17, 0x000000, 0xFFFFFF, + 0x009F1D, 0x009F1D, 0x000000, 0xFFFFFF, + 0x009F1F, 0x009F1F, 0x000000, 0xFFFFFF, + 0x009F21, 0x009F21, 0x000000, 0xFFFFFF, + 0x009F26, 0x009F27, 0x000000, 0xFFFFFF, + 0x009F39, 0x009F3A, 0x000000, 0xFFFFFF, + 0x009F3C, 0x009F3C, 0x000000, 0xFFFFFF, + 0x009F3F, 0x009F3F, 0x000000, 0xFFFFFF, + 0x009F44, 0x009F45, 0x000000, 0xFFFFFF, + 0x009F50, 0x009F51, 0x000000, 0xFFFFFF, + 0x009F53, 0x009F53, 0x000000, 0xFFFFFF, + 0x009F5A, 0x009F5A, 0x000000, 0xFFFFFF, + 0x009F62, 0x009F62, 0x000000, 0xFFFFFF, + 0x009F68, 0x009F69, 0x000000, 0xFFFFFF, + 0x009F6D, 0x009F6D, 0x000000, 0xFFFFFF, + 0x009F73, 0x009F73, 0x000000, 0xFFFFFF, + 0x009F7C, 0x009F7D, 0x000000, 0xFFFFFF, + 0x009F7F, 0x009F8C, 0x000000, 0xFFFFFF, + 0x009F8E, 0x009F8F, 0x000000, 0xFFFFFF, + 0x009F93, 0x009F93, 0x000000, 0xFFFFFF, + 0x009F96, 0x009F97, 0x000000, 0xFFFFFF, + 0x009F99, 0x009F9B, 0x000000, 0xFFFFFF, + 0x009F9D, 0x009F9F, 0x000000, 0xFFFFFF, + 0x009FA1, 0x009FA1, 0x000000, 0xFFFFFF, + 0x009FA3, 0x009FA3, 0x000000, 0xFFFFFF, + 0x009FA5, 0x00F6B0, 0x000000, 0xFFFFFF, + 0x00F849, 0x00FA0B, 0x000000, 0xFFFFFF, + 0x00FA0E, 0x00FE2F, 0x000000, 0xFFFFFF, + 0x00FE32, 0x00FE32, 0x000000, 0xFFFFFF, + 0x00FE45, 0x00FE48, 0x000000, 0xFFFFFF, + 0x00FE53, 0x00FE53, 0x000000, 0xFFFFFF, + 0x00FE58, 0x00FE58, 0x000000, 0xFFFFFF, + 0x00FE67, 0x00FE67, 0x000000, 0xFFFFFF, + 0x00FE6C, 0x00FF00, 0x000000, 0xFFFFFF, + 0x00FF02, 0x00FF02, 0x000000, 0xFFFFFF, + 0x00FF07, 0x00FF07, 0x000000, 0xFFFFFF, + 0x00FF3B, 0x00FF3B, 0x000000, 0xFFFFFF, + 0x00FF3D, 0x00FF3E, 0x000000, 0xFFFFFF, + 0x00FF40, 0x00FF40, 0x000000, 0xFFFFFF, + 0x00FF5F, 0x00FFDF, 0x000000, 0xFFFFFF, + 0x00FFE2, 0x00FFE2, 0x000000, 0xFFFFFF, + 0x00FFE4, 0x00FFE4, 0x000000, 0xFFFFFF, + 0x00FFE6, 0x1FFFFF, 0x000000, 0xFFFFFF, +); + +?> diff --git a/lib/php/monica/cnvtmap/EUC-KR.inc.php b/lib/php/monica/cnvtmap/EUC-KR.inc.php new file mode 100644 index 0000000..82c9aa3 --- /dev/null +++ b/lib/php/monica/cnvtmap/EUC-KR.inc.php @@ -0,0 +1,5013 @@ + +// Copyright: Copyright (C) 2007 Pristine Communications + +// EUC-KR +$CNVTMAP["EUC-KR"] = array( + 0x0000A0, 0x0000A0, 0x000000, 0xFFFFFF, + 0x0000A2, 0x0000A3, 0x000000, 0xFFFFFF, + 0x0000A5, 0x0000A6, 0x000000, 0xFFFFFF, + 0x0000A9, 0x0000A9, 0x000000, 0xFFFFFF, + 0x0000AB, 0x0000AC, 0x000000, 0xFFFFFF, + 0x0000AF, 0x0000AF, 0x000000, 0xFFFFFF, + 0x0000B5, 0x0000B5, 0x000000, 0xFFFFFF, + 0x0000BB, 0x0000BB, 0x000000, 0xFFFFFF, + 0x0000C0, 0x0000C5, 0x000000, 0xFFFFFF, + 0x0000C7, 0x0000CF, 0x000000, 0xFFFFFF, + 0x0000D1, 0x0000D6, 0x000000, 0xFFFFFF, + 0x0000D9, 0x0000DD, 0x000000, 0xFFFFFF, + 0x0000E0, 0x0000E5, 0x000000, 0xFFFFFF, + 0x0000E7, 0x0000EF, 0x000000, 0xFFFFFF, + 0x0000F1, 0x0000F6, 0x000000, 0xFFFFFF, + 0x0000F9, 0x0000FD, 0x000000, 0xFFFFFF, + 0x0000FF, 0x000110, 0x000000, 0xFFFFFF, + 0x000112, 0x000125, 0x000000, 0xFFFFFF, + 0x000128, 0x000130, 0x000000, 0xFFFFFF, + 0x000134, 0x000137, 0x000000, 0xFFFFFF, + 0x000139, 0x00013E, 0x000000, 0xFFFFFF, + 0x000143, 0x000148, 0x000000, 0xFFFFFF, + 0x00014C, 0x000151, 0x000000, 0xFFFFFF, + 0x000154, 0x000165, 0x000000, 0xFFFFFF, + 0x000168, 0x0002C6, 0x000000, 0xFFFFFF, + 0x0002C8, 0x0002CF, 0x000000, 0xFFFFFF, + 0x0002D1, 0x0002D7, 0x000000, 0xFFFFFF, + 0x0002DC, 0x0002DC, 0x000000, 0xFFFFFF, + 0x0002DE, 0x000390, 0x000000, 0xFFFFFF, + 0x0003A2, 0x0003A2, 0x000000, 0xFFFFFF, + 0x0003AA, 0x0003B0, 0x000000, 0xFFFFFF, + 0x0003C2, 0x0003C2, 0x000000, 0xFFFFFF, + 0x0003CA, 0x000400, 0x000000, 0xFFFFFF, + 0x000402, 0x00040F, 0x000000, 0xFFFFFF, + 0x000450, 0x000450, 0x000000, 0xFFFFFF, + 0x000452, 0x002014, 0x000000, 0xFFFFFF, + 0x002016, 0x002017, 0x000000, 0xFFFFFF, + 0x00201A, 0x00201B, 0x000000, 0xFFFFFF, + 0x00201E, 0x00201F, 0x000000, 0xFFFFFF, + 0x002022, 0x002024, 0x000000, 0xFFFFFF, + 0x002027, 0x00202F, 0x000000, 0xFFFFFF, + 0x002031, 0x002031, 0x000000, 0xFFFFFF, + 0x002034, 0x00203A, 0x000000, 0xFFFFFF, + 0x00203C, 0x002073, 0x000000, 0xFFFFFF, + 0x002075, 0x00207E, 0x000000, 0xFFFFFF, + 0x002080, 0x002080, 0x000000, 0xFFFFFF, + 0x002085, 0x0020A8, 0x000000, 0xFFFFFF, + 0x0020AA, 0x0020AB, 0x000000, 0xFFFFFF, + 0x0020AD, 0x002102, 0x000000, 0xFFFFFF, + 0x002104, 0x002108, 0x000000, 0xFFFFFF, + 0x00210A, 0x002112, 0x000000, 0xFFFFFF, + 0x002114, 0x002115, 0x000000, 0xFFFFFF, + 0x002117, 0x002120, 0x000000, 0xFFFFFF, + 0x002123, 0x002125, 0x000000, 0xFFFFFF, + 0x002127, 0x00212A, 0x000000, 0xFFFFFF, + 0x00212C, 0x002152, 0x000000, 0xFFFFFF, + 0x002155, 0x00215A, 0x000000, 0xFFFFFF, + 0x00215F, 0x00215F, 0x000000, 0xFFFFFF, + 0x00216A, 0x00216F, 0x000000, 0xFFFFFF, + 0x00217A, 0x00218F, 0x000000, 0xFFFFFF, + 0x00219A, 0x0021D1, 0x000000, 0xFFFFFF, + 0x0021D3, 0x0021D3, 0x000000, 0xFFFFFF, + 0x0021D5, 0x0021FF, 0x000000, 0xFFFFFF, + 0x002201, 0x002201, 0x000000, 0xFFFFFF, + 0x002204, 0x002206, 0x000000, 0xFFFFFF, + 0x002209, 0x00220A, 0x000000, 0xFFFFFF, + 0x00220C, 0x00220E, 0x000000, 0xFFFFFF, + 0x002210, 0x002210, 0x000000, 0xFFFFFF, + 0x002212, 0x002219, 0x000000, 0xFFFFFF, + 0x00221B, 0x00221C, 0x000000, 0xFFFFFF, + 0x00221F, 0x00221F, 0x000000, 0xFFFFFF, + 0x002221, 0x002224, 0x000000, 0xFFFFFF, + 0x002226, 0x002226, 0x000000, 0xFFFFFF, + 0x00222D, 0x00222D, 0x000000, 0xFFFFFF, + 0x00222F, 0x002233, 0x000000, 0xFFFFFF, + 0x002236, 0x00223B, 0x000000, 0xFFFFFF, + 0x00223E, 0x002251, 0x000000, 0xFFFFFF, + 0x002253, 0x00225F, 0x000000, 0xFFFFFF, + 0x002262, 0x002263, 0x000000, 0xFFFFFF, + 0x002266, 0x002269, 0x000000, 0xFFFFFF, + 0x00226C, 0x002281, 0x000000, 0xFFFFFF, + 0x002284, 0x002285, 0x000000, 0xFFFFFF, + 0x002288, 0x002298, 0x000000, 0xFFFFFF, + 0x00229A, 0x0022A4, 0x000000, 0xFFFFFF, + 0x0022A6, 0x002311, 0x000000, 0xFFFFFF, + 0x002313, 0x00245F, 0x000000, 0xFFFFFF, + 0x00246F, 0x002473, 0x000000, 0xFFFFFF, + 0x002483, 0x00249B, 0x000000, 0xFFFFFF, + 0x0024B6, 0x0024CF, 0x000000, 0xFFFFFF, + 0x0024EA, 0x0024FF, 0x000000, 0xFFFFFF, + 0x002504, 0x00250B, 0x000000, 0xFFFFFF, + 0x00254C, 0x002591, 0x000000, 0xFFFFFF, + 0x002593, 0x00259F, 0x000000, 0xFFFFFF, + 0x0025A2, 0x0025A2, 0x000000, 0xFFFFFF, + 0x0025AA, 0x0025B1, 0x000000, 0xFFFFFF, + 0x0025B4, 0x0025B5, 0x000000, 0xFFFFFF, + 0x0025B8, 0x0025BB, 0x000000, 0xFFFFFF, + 0x0025BE, 0x0025BF, 0x000000, 0xFFFFFF, + 0x0025C2, 0x0025C5, 0x000000, 0xFFFFFF, + 0x0025C9, 0x0025CA, 0x000000, 0xFFFFFF, + 0x0025CC, 0x0025CD, 0x000000, 0xFFFFFF, + 0x0025D2, 0x002604, 0x000000, 0xFFFFFF, + 0x002607, 0x00260D, 0x000000, 0xFFFFFF, + 0x002610, 0x00261B, 0x000000, 0xFFFFFF, + 0x00261D, 0x00261D, 0x000000, 0xFFFFFF, + 0x00261F, 0x00263F, 0x000000, 0xFFFFFF, + 0x002641, 0x002641, 0x000000, 0xFFFFFF, + 0x002643, 0x00265F, 0x000000, 0xFFFFFF, + 0x002662, 0x002662, 0x000000, 0xFFFFFF, + 0x002666, 0x002666, 0x000000, 0xFFFFFF, + 0x00266B, 0x00266B, 0x000000, 0xFFFFFF, + 0x00266E, 0x002FFF, 0x000000, 0xFFFFFF, + 0x003004, 0x003007, 0x000000, 0xFFFFFF, + 0x003012, 0x003012, 0x000000, 0xFFFFFF, + 0x003016, 0x003040, 0x000000, 0xFFFFFF, + 0x003094, 0x0030A0, 0x000000, 0xFFFFFF, + 0x0030F7, 0x003130, 0x000000, 0xFFFFFF, + 0x00318F, 0x0031FF, 0x000000, 0xFFFFFF, + 0x00321D, 0x00325F, 0x000000, 0xFFFFFF, + 0x00327C, 0x00327E, 0x000000, 0xFFFFFF, + 0x003280, 0x00337F, 0x000000, 0xFFFFFF, + 0x003385, 0x003387, 0x000000, 0xFFFFFF, + 0x0033CB, 0x0033CE, 0x000000, 0xFFFFFF, + 0x0033D1, 0x0033D2, 0x000000, 0xFFFFFF, + 0x0033D4, 0x0033D5, 0x000000, 0xFFFFFF, + 0x0033D7, 0x0033D7, 0x000000, 0xFFFFFF, + 0x0033D9, 0x0033DA, 0x000000, 0xFFFFFF, + 0x0033DE, 0x004DFF, 0x000000, 0xFFFFFF, + 0x004E02, 0x004E02, 0x000000, 0xFFFFFF, + 0x004E04, 0x004E06, 0x000000, 0xFFFFFF, + 0x004E0C, 0x004E0C, 0x000000, 0xFFFFFF, + 0x004E0E, 0x004E10, 0x000000, 0xFFFFFF, + 0x004E12, 0x004E13, 0x000000, 0xFFFFFF, + 0x004E17, 0x004E17, 0x000000, 0xFFFFFF, + 0x004E1A, 0x004E1D, 0x000000, 0xFFFFFF, + 0x004E1F, 0x004E2C, 0x000000, 0xFFFFFF, + 0x004E2E, 0x004E31, 0x000000, 0xFFFFFF, + 0x004E33, 0x004E37, 0x000000, 0xFFFFFF, + 0x004E3A, 0x004E3A, 0x000000, 0xFFFFFF, + 0x004E3C, 0x004E41, 0x000000, 0xFFFFFF, + 0x004E44, 0x004E44, 0x000000, 0xFFFFFF, + 0x004E46, 0x004E4A, 0x000000, 0xFFFFFF, + 0x004E4C, 0x004E4C, 0x000000, 0xFFFFFF, + 0x004E50, 0x004E55, 0x000000, 0xFFFFFF, + 0x004E57, 0x004E57, 0x000000, 0xFFFFFF, + 0x004E5A, 0x004E5C, 0x000000, 0xFFFFFF, + 0x004E60, 0x004E6A, 0x000000, 0xFFFFFF, + 0x004E6C, 0x004E6C, 0x000000, 0xFFFFFF, + 0x004E6E, 0x004E72, 0x000000, 0xFFFFFF, + 0x004E74, 0x004E75, 0x000000, 0xFFFFFF, + 0x004E78, 0x004E7D, 0x000000, 0xFFFFFF, + 0x004E7F, 0x004E81, 0x000000, 0xFFFFFF, + 0x004E83, 0x004E85, 0x000000, 0xFFFFFF, + 0x004E87, 0x004E87, 0x000000, 0xFFFFFF, + 0x004E89, 0x004E8A, 0x000000, 0xFFFFFF, + 0x004E8D, 0x004E8D, 0x000000, 0xFFFFFF, + 0x004E8F, 0x004E8F, 0x000000, 0xFFFFFF, + 0x004E93, 0x004E93, 0x000000, 0xFFFFFF, + 0x004E96, 0x004E97, 0x000000, 0xFFFFFF, + 0x004E99, 0x004E9A, 0x000000, 0xFFFFFF, + 0x004E9C, 0x004E9D, 0x000000, 0xFFFFFF, + 0x004E9F, 0x004EA0, 0x000000, 0xFFFFFF, + 0x004EA3, 0x004EA3, 0x000000, 0xFFFFFF, + 0x004EA7, 0x004EA7, 0x000000, 0xFFFFFF, + 0x004EA9, 0x004EAA, 0x000000, 0xFFFFFF, + 0x004EAF, 0x004EB5, 0x000000, 0xFFFFFF, + 0x004EB7, 0x004EB9, 0x000000, 0xFFFFFF, + 0x004EBB, 0x004EBF, 0x000000, 0xFFFFFF, + 0x004EC2, 0x004EC3, 0x000000, 0xFFFFFF, + 0x004EC5, 0x004EC6, 0x000000, 0xFFFFFF, + 0x004EC8, 0x004EC9, 0x000000, 0xFFFFFF, + 0x004ECC, 0x004ECC, 0x000000, 0xFFFFFF, + 0x004ECE, 0x004ED3, 0x000000, 0xFFFFFF, + 0x004EDA, 0x004EDC, 0x000000, 0xFFFFFF, + 0x004EDE, 0x004EDE, 0x000000, 0xFFFFFF, + 0x004EE0, 0x004EE2, 0x000000, 0xFFFFFF, + 0x004EE6, 0x004EEF, 0x000000, 0xFFFFFF, + 0x004EF1, 0x004EF1, 0x000000, 0xFFFFFF, + 0x004EF3, 0x004EF5, 0x000000, 0xFFFFFF, + 0x004EF8, 0x004EFA, 0x000000, 0xFFFFFF, + 0x004EFC, 0x004F00, 0x000000, 0xFFFFFF, + 0x004F02, 0x004F08, 0x000000, 0xFFFFFF, + 0x004F0C, 0x004F0C, 0x000000, 0xFFFFFF, + 0x004F12, 0x004F2E, 0x000000, 0xFFFFFF, + 0x004F30, 0x004F33, 0x000000, 0xFFFFFF, + 0x004F35, 0x004F35, 0x000000, 0xFFFFFF, + 0x004F37, 0x004F37, 0x000000, 0xFFFFFF, + 0x004F39, 0x004F39, 0x000000, 0xFFFFFF, + 0x004F3B, 0x004F3B, 0x000000, 0xFFFFFF, + 0x004F3E, 0x004F42, 0x000000, 0xFFFFFF, + 0x004F44, 0x004F45, 0x000000, 0xFFFFFF, + 0x004F49, 0x004F4C, 0x000000, 0xFFFFFF, + 0x004F52, 0x004F54, 0x000000, 0xFFFFFF, + 0x004F56, 0x004F58, 0x000000, 0xFFFFFF, + 0x004F5D, 0x004F68, 0x000000, 0xFFFFFF, + 0x004F6A, 0x004F6E, 0x000000, 0xFFFFFF, + 0x004F71, 0x004F72, 0x000000, 0xFFFFFF, + 0x004F74, 0x004F75, 0x000000, 0xFFFFFF, + 0x004F77, 0x004F79, 0x000000, 0xFFFFFF, + 0x004F7B, 0x004F7D, 0x000000, 0xFFFFFF, + 0x004F80, 0x004F80, 0x000000, 0xFFFFFF, + 0x004F82, 0x004F82, 0x000000, 0xFFFFFF, + 0x004F85, 0x004F85, 0x000000, 0xFFFFFF, + 0x004F87, 0x004F87, 0x000000, 0xFFFFFF, + 0x004F89, 0x004F89, 0x000000, 0xFFFFFF, + 0x004F8C, 0x004F8C, 0x000000, 0xFFFFFF, + 0x004F8E, 0x004F8E, 0x000000, 0xFFFFFF, + 0x004F90, 0x004F90, 0x000000, 0xFFFFFF, + 0x004F92, 0x004F95, 0x000000, 0xFFFFFF, + 0x004F97, 0x004F97, 0x000000, 0xFFFFFF, + 0x004F99, 0x004F9A, 0x000000, 0xFFFFFF, + 0x004F9C, 0x004F9C, 0x000000, 0xFFFFFF, + 0x004F9E, 0x004FAD, 0x000000, 0xFFFFFF, + 0x004FB0, 0x004FB4, 0x000000, 0xFFFFFF, + 0x004FB7, 0x004FBE, 0x000000, 0xFFFFFF, + 0x004FC0, 0x004FC1, 0x000000, 0xFFFFFF, + 0x004FC5, 0x004FC8, 0x000000, 0xFFFFFF, + 0x004FCB, 0x004FCD, 0x000000, 0xFFFFFF, + 0x004FCF, 0x004FD0, 0x000000, 0xFFFFFF, + 0x004FD2, 0x004FD2, 0x000000, 0xFFFFFF, + 0x004FD5, 0x004FD6, 0x000000, 0xFFFFFF, + 0x004FD8, 0x004FD9, 0x000000, 0xFFFFFF, + 0x004FDB, 0x004FDC, 0x000000, 0xFFFFFF, + 0x004FDE, 0x004FDE, 0x000000, 0xFFFFFF, + 0x004FE2, 0x004FED, 0x000000, 0xFFFFFF, + 0x004FF0, 0x004FF0, 0x000000, 0xFFFFFF, + 0x004FF2, 0x004FF2, 0x000000, 0xFFFFFF, + 0x004FF4, 0x004FF4, 0x000000, 0xFFFFFF, + 0x004FF6, 0x004FF7, 0x000000, 0xFFFFFF, + 0x004FF9, 0x004FF9, 0x000000, 0xFFFFFF, + 0x004FFB, 0x005001, 0x000000, 0xFFFFFF, + 0x005003, 0x005005, 0x000000, 0xFFFFFF, + 0x005007, 0x005008, 0x000000, 0xFFFFFF, + 0x00500A, 0x00500A, 0x000000, 0xFFFFFF, + 0x00500C, 0x00500C, 0x000000, 0xFFFFFF, + 0x00500E, 0x005010, 0x000000, 0xFFFFFF, + 0x005013, 0x005015, 0x000000, 0xFFFFFF, + 0x005017, 0x005018, 0x000000, 0xFFFFFF, + 0x00501B, 0x00501B, 0x000000, 0xFFFFFF, + 0x00501D, 0x00501D, 0x000000, 0xFFFFFF, + 0x005020, 0x005020, 0x000000, 0xFFFFFF, + 0x005022, 0x005022, 0x000000, 0xFFFFFF, + 0x005025, 0x005025, 0x000000, 0xFFFFFF, + 0x005029, 0x005029, 0x000000, 0xFFFFFF, + 0x00502E, 0x00503A, 0x000000, 0xFFFFFF, + 0x00503C, 0x005042, 0x000000, 0xFFFFFF, + 0x005044, 0x005046, 0x000000, 0xFFFFFF, + 0x00504A, 0x00504E, 0x000000, 0xFFFFFF, + 0x005050, 0x005054, 0x000000, 0xFFFFFF, + 0x005056, 0x005059, 0x000000, 0xFFFFFF, + 0x00505B, 0x00505B, 0x000000, 0xFFFFFF, + 0x00505D, 0x005064, 0x000000, 0xFFFFFF, + 0x005066, 0x005073, 0x000000, 0xFFFFFF, + 0x005077, 0x005077, 0x000000, 0xFFFFFF, + 0x005079, 0x00507F, 0x000000, 0xFFFFFF, + 0x005081, 0x005084, 0x000000, 0xFFFFFF, + 0x005086, 0x00508C, 0x000000, 0xFFFFFF, + 0x00508E, 0x005090, 0x000000, 0xFFFFFF, + 0x005092, 0x005097, 0x000000, 0xFFFFFF, + 0x00509A, 0x0050AB, 0x000000, 0xFFFFFF, + 0x0050AE, 0x0050B1, 0x000000, 0xFFFFFF, + 0x0050B4, 0x0050B4, 0x000000, 0xFFFFFF, + 0x0050B6, 0x0050B6, 0x000000, 0xFFFFFF, + 0x0050B8, 0x0050BD, 0x000000, 0xFFFFFF, + 0x0050BF, 0x0050C4, 0x000000, 0xFFFFFF, + 0x0050C6, 0x0050C8, 0x000000, 0xFFFFFF, + 0x0050CB, 0x0050CE, 0x000000, 0xFFFFFF, + 0x0050D0, 0x0050D0, 0x000000, 0xFFFFFF, + 0x0050D2, 0x0050D4, 0x000000, 0xFFFFFF, + 0x0050D7, 0x0050D9, 0x000000, 0xFFFFFF, + 0x0050DB, 0x0050DD, 0x000000, 0xFFFFFF, + 0x0050DF, 0x0050E4, 0x000000, 0xFFFFFF, + 0x0050E6, 0x0050E6, 0x000000, 0xFFFFFF, + 0x0050E8, 0x0050EC, 0x000000, 0xFFFFFF, + 0x0050EE, 0x0050F8, 0x000000, 0xFFFFFF, + 0x0050FA, 0x0050FA, 0x000000, 0xFFFFFF, + 0x0050FC, 0x0050FE, 0x000000, 0xFFFFFF, + 0x005102, 0x005103, 0x000000, 0xFFFFFF, + 0x005105, 0x005105, 0x000000, 0xFFFFFF, + 0x005107, 0x005108, 0x000000, 0xFFFFFF, + 0x00510A, 0x005111, 0x000000, 0xFFFFFF, + 0x005113, 0x00511E, 0x000000, 0xFFFFFF, + 0x005120, 0x005120, 0x000000, 0xFFFFFF, + 0x005122, 0x005129, 0x000000, 0xFFFFFF, + 0x00512B, 0x005131, 0x000000, 0xFFFFFF, + 0x005133, 0x005136, 0x000000, 0xFFFFFF, + 0x005138, 0x005139, 0x000000, 0xFFFFFF, + 0x00513B, 0x00513B, 0x000000, 0xFFFFFF, + 0x00513D, 0x00513F, 0x000000, 0xFFFFFF, + 0x005142, 0x005142, 0x000000, 0xFFFFFF, + 0x00514A, 0x00514A, 0x000000, 0xFFFFFF, + 0x00514F, 0x005151, 0x000000, 0xFFFFFF, + 0x005153, 0x00515B, 0x000000, 0xFFFFFF, + 0x00515D, 0x005161, 0x000000, 0xFFFFFF, + 0x005163, 0x005164, 0x000000, 0xFFFFFF, + 0x005166, 0x005166, 0x000000, 0xFFFFFF, + 0x00516F, 0x005170, 0x000000, 0xFFFFFF, + 0x005172, 0x005174, 0x000000, 0xFFFFFF, + 0x005179, 0x00517B, 0x000000, 0xFFFFFF, + 0x00517D, 0x00517F, 0x000000, 0xFFFFFF, + 0x005181, 0x005185, 0x000000, 0xFFFFFF, + 0x005187, 0x005189, 0x000000, 0xFFFFFF, + 0x00518B, 0x00518C, 0x000000, 0xFFFFFF, + 0x00518E, 0x005191, 0x000000, 0xFFFFFF, + 0x005193, 0x005194, 0x000000, 0xFFFFFF, + 0x005196, 0x005196, 0x000000, 0xFFFFFF, + 0x005198, 0x00519F, 0x000000, 0xFFFFFF, + 0x0051A1, 0x0051A4, 0x000000, 0xFFFFFF, + 0x0051A6, 0x0051A9, 0x000000, 0xFFFFFF, + 0x0051AB, 0x0051AB, 0x000000, 0xFFFFFF, + 0x0051AD, 0x0051B5, 0x000000, 0xFFFFFF, + 0x0051B8, 0x0051BC, 0x000000, 0xFFFFFF, + 0x0051BE, 0x0051C3, 0x000000, 0xFFFFFF, + 0x0051C5, 0x0051C5, 0x000000, 0xFFFFFF, + 0x0051C7, 0x0051C8, 0x000000, 0xFFFFFF, + 0x0051CA, 0x0051CA, 0x000000, 0xFFFFFF, + 0x0051CE, 0x0051DB, 0x000000, 0xFFFFFF, + 0x0051DF, 0x0051E0, 0x000000, 0xFFFFFF, + 0x0051E2, 0x0051EF, 0x000000, 0xFFFFFF, + 0x0051F2, 0x0051F5, 0x000000, 0xFFFFFF, + 0x0051F7, 0x0051F7, 0x000000, 0xFFFFFF, + 0x0051FB, 0x0051FC, 0x000000, 0xFFFFFF, + 0x0051FE, 0x0051FF, 0x000000, 0xFFFFFF, + 0x005201, 0x005202, 0x000000, 0xFFFFFF, + 0x005204, 0x005205, 0x000000, 0xFFFFFF, + 0x005209, 0x005209, 0x000000, 0xFFFFFF, + 0x00520B, 0x00520D, 0x000000, 0xFFFFFF, + 0x00520F, 0x005210, 0x000000, 0xFFFFFF, + 0x005212, 0x005216, 0x000000, 0xFFFFFF, + 0x005218, 0x00521C, 0x000000, 0xFFFFFF, + 0x00521E, 0x005223, 0x000000, 0xFFFFFF, + 0x005226, 0x005228, 0x000000, 0xFFFFFF, + 0x00522B, 0x00522D, 0x000000, 0xFFFFFF, + 0x00522F, 0x00522F, 0x000000, 0xFFFFFF, + 0x005231, 0x005235, 0x000000, 0xFFFFFF, + 0x00523C, 0x005242, 0x000000, 0xFFFFFF, + 0x005244, 0x005246, 0x000000, 0xFFFFFF, + 0x005248, 0x005249, 0x000000, 0xFFFFFF, + 0x00524E, 0x005253, 0x000000, 0xFFFFFF, + 0x005255, 0x005255, 0x000000, 0xFFFFFF, + 0x005257, 0x00525A, 0x000000, 0xFFFFFF, + 0x00525C, 0x00525C, 0x000000, 0xFFFFFF, + 0x00525E, 0x005260, 0x000000, 0xFFFFFF, + 0x005262, 0x005268, 0x000000, 0xFFFFFF, + 0x00526B, 0x00526E, 0x000000, 0xFFFFFF, + 0x005270, 0x005271, 0x000000, 0xFFFFFF, + 0x005273, 0x005274, 0x000000, 0xFFFFFF, + 0x005276, 0x00527C, 0x000000, 0xFFFFFF, + 0x00527E, 0x00527E, 0x000000, 0xFFFFFF, + 0x005280, 0x005282, 0x000000, 0xFFFFFF, + 0x005284, 0x005286, 0x000000, 0xFFFFFF, + 0x00528A, 0x00528C, 0x000000, 0xFFFFFF, + 0x00528E, 0x005290, 0x000000, 0xFFFFFF, + 0x005293, 0x00529A, 0x000000, 0xFFFFFF, + 0x00529C, 0x00529E, 0x000000, 0xFFFFFF, + 0x0052A1, 0x0052A2, 0x000000, 0xFFFFFF, + 0x0052A5, 0x0052A8, 0x000000, 0xFFFFFF, + 0x0052AC, 0x0052BD, 0x000000, 0xFFFFFF, + 0x0052BF, 0x0052C0, 0x000000, 0xFFFFFF, + 0x0052C2, 0x0052C2, 0x000000, 0xFFFFFF, + 0x0052C4, 0x0052C4, 0x000000, 0xFFFFFF, + 0x0052C6, 0x0052C6, 0x000000, 0xFFFFFF, + 0x0052C8, 0x0052C8, 0x000000, 0xFFFFFF, + 0x0052CA, 0x0052CC, 0x000000, 0xFFFFFF, + 0x0052CE, 0x0052D1, 0x000000, 0xFFFFFF, + 0x0052D3, 0x0052D4, 0x000000, 0xFFFFFF, + 0x0052D7, 0x0052D7, 0x000000, 0xFFFFFF, + 0x0052DA, 0x0052DA, 0x000000, 0xFFFFFF, + 0x0052DC, 0x0052DC, 0x000000, 0xFFFFFF, + 0x0052E0, 0x0052E1, 0x000000, 0xFFFFFF, + 0x0052E5, 0x0052F2, 0x000000, 0xFFFFFF, + 0x0052F4, 0x0052F4, 0x000000, 0xFFFFFF, + 0x0052F6, 0x0052F7, 0x000000, 0xFFFFFF, + 0x0052F9, 0x0052F9, 0x000000, 0xFFFFFF, + 0x0052FC, 0x0052FD, 0x000000, 0xFFFFFF, + 0x005300, 0x005304, 0x000000, 0xFFFFFF, + 0x005306, 0x005307, 0x000000, 0xFFFFFF, + 0x005309, 0x00530C, 0x000000, 0xFFFFFF, + 0x00530E, 0x00530E, 0x000000, 0xFFFFFF, + 0x005311, 0x005314, 0x000000, 0xFFFFFF, + 0x005318, 0x005318, 0x000000, 0xFFFFFF, + 0x00531A, 0x00531F, 0x000000, 0xFFFFFF, + 0x005322, 0x005322, 0x000000, 0xFFFFFF, + 0x005324, 0x005329, 0x000000, 0xFFFFFF, + 0x00532B, 0x00532E, 0x000000, 0xFFFFFF, + 0x005330, 0x005338, 0x000000, 0xFFFFFF, + 0x00533A, 0x00533E, 0x000000, 0xFFFFFF, + 0x005342, 0x005342, 0x000000, 0xFFFFFF, + 0x005345, 0x005346, 0x000000, 0xFFFFFF, + 0x00534B, 0x00534C, 0x000000, 0xFFFFFF, + 0x00534E, 0x005350, 0x000000, 0xFFFFFF, + 0x005355, 0x005356, 0x000000, 0xFFFFFF, + 0x005358, 0x005359, 0x000000, 0xFFFFFF, + 0x00535B, 0x00535B, 0x000000, 0xFFFFFF, + 0x00535D, 0x00535D, 0x000000, 0xFFFFFF, + 0x00535F, 0x00535F, 0x000000, 0xFFFFFF, + 0x005361, 0x005365, 0x000000, 0xFFFFFF, + 0x005367, 0x005367, 0x000000, 0xFFFFFF, + 0x005369, 0x00536E, 0x000000, 0xFFFFFF, + 0x005372, 0x005373, 0x000000, 0xFFFFFF, + 0x005376, 0x005376, 0x000000, 0xFFFFFF, + 0x005378, 0x00537C, 0x000000, 0xFFFFFF, + 0x00537E, 0x00537E, 0x000000, 0xFFFFFF, + 0x005380, 0x005383, 0x000000, 0xFFFFFF, + 0x005385, 0x005392, 0x000000, 0xFFFFFF, + 0x005394, 0x005397, 0x000000, 0xFFFFFF, + 0x005399, 0x005399, 0x000000, 0xFFFFFF, + 0x00539B, 0x00539E, 0x000000, 0xFFFFFF, + 0x0053A1, 0x0053A4, 0x000000, 0xFFFFFF, + 0x0053A7, 0x0053AC, 0x000000, 0xFFFFFF, + 0x0053AE, 0x0053BA, 0x000000, 0xFFFFFF, + 0x0053BC, 0x0053C2, 0x000000, 0xFFFFFF, + 0x0053C4, 0x0053C7, 0x000000, 0xFFFFFF, + 0x0053CC, 0x0053CC, 0x000000, 0xFFFFFF, + 0x0053CE, 0x0053D3, 0x000000, 0xFFFFFF, + 0x0053D5, 0x0053D5, 0x000000, 0xFFFFFF, + 0x0053D8, 0x0053DA, 0x000000, 0xFFFFFF, + 0x0053DC, 0x0053E0, 0x000000, 0xFFFFFF, + 0x0053E6, 0x0053E8, 0x000000, 0xFFFFFF, + 0x0053EE, 0x0053EE, 0x000000, 0xFFFFFF, + 0x0053F4, 0x0053F7, 0x000000, 0xFFFFFF, + 0x0053F9, 0x005402, 0x000000, 0xFFFFFF, + 0x005405, 0x005407, 0x000000, 0xFFFFFF, + 0x00540B, 0x00540B, 0x000000, 0xFFFFFF, + 0x005412, 0x00541A, 0x000000, 0xFFFFFF, + 0x00541C, 0x00541C, 0x000000, 0xFFFFFF, + 0x00541E, 0x00541E, 0x000000, 0xFFFFFF, + 0x005421, 0x005425, 0x000000, 0xFFFFFF, + 0x005427, 0x005428, 0x000000, 0xFFFFFF, + 0x00542A, 0x00542A, 0x000000, 0xFFFFFF, + 0x00542C, 0x005432, 0x000000, 0xFFFFFF, + 0x005434, 0x005437, 0x000000, 0xFFFFFF, + 0x00543A, 0x00543A, 0x000000, 0xFFFFFF, + 0x00543D, 0x00543D, 0x000000, 0xFFFFFF, + 0x00543F, 0x005441, 0x000000, 0xFFFFFF, + 0x005443, 0x005447, 0x000000, 0xFFFFFF, + 0x005449, 0x005449, 0x000000, 0xFFFFFF, + 0x00544B, 0x005450, 0x000000, 0xFFFFFF, + 0x005452, 0x005467, 0x000000, 0xFFFFFF, + 0x005469, 0x005469, 0x000000, 0xFFFFFF, + 0x00546B, 0x005470, 0x000000, 0xFFFFFF, + 0x005472, 0x005472, 0x000000, 0xFFFFFF, + 0x005474, 0x005474, 0x000000, 0xFFFFFF, + 0x005476, 0x00547A, 0x000000, 0xFFFFFF, + 0x00547E, 0x00547F, 0x000000, 0xFFFFFF, + 0x005481, 0x005485, 0x000000, 0xFFFFFF, + 0x005487, 0x00548B, 0x000000, 0xFFFFFF, + 0x00548D, 0x00548D, 0x000000, 0xFFFFFF, + 0x00548F, 0x00548F, 0x000000, 0xFFFFFF, + 0x005491, 0x0054A3, 0x000000, 0xFFFFFF, + 0x0054A5, 0x0054A7, 0x000000, 0xFFFFFF, + 0x0054A9, 0x0054AA, 0x000000, 0xFFFFFF, + 0x0054AD, 0x0054B2, 0x000000, 0xFFFFFF, + 0x0054B4, 0x0054B7, 0x000000, 0xFFFFFF, + 0x0054B9, 0x0054BC, 0x000000, 0xFFFFFF, + 0x0054BE, 0x0054BF, 0x000000, 0xFFFFFF, + 0x0054C2, 0x0054C3, 0x000000, 0xFFFFFF, + 0x0054C5, 0x0054C7, 0x000000, 0xFFFFFF, + 0x0054CA, 0x0054E0, 0x000000, 0xFFFFFF, + 0x0054E2, 0x0054E4, 0x000000, 0xFFFFFF, + 0x0054E6, 0x0054E7, 0x000000, 0xFFFFFF, + 0x0054E9, 0x0054EC, 0x000000, 0xFFFFFF, + 0x0054EF, 0x0054F1, 0x000000, 0xFFFFFF, + 0x0054F3, 0x0054F9, 0x000000, 0xFFFFFF, + 0x0054FB, 0x005503, 0x000000, 0xFFFFFF, + 0x005505, 0x005505, 0x000000, 0xFFFFFF, + 0x005508, 0x00550D, 0x000000, 0xFFFFFF, + 0x00550F, 0x00550F, 0x000000, 0xFFFFFF, + 0x005511, 0x00551B, 0x000000, 0xFFFFFF, + 0x00551D, 0x00552E, 0x000000, 0xFFFFFF, + 0x005530, 0x005530, 0x000000, 0xFFFFFF, + 0x005532, 0x005534, 0x000000, 0xFFFFFF, + 0x005536, 0x00553D, 0x000000, 0xFFFFFF, + 0x00553F, 0x005543, 0x000000, 0xFFFFFF, + 0x005545, 0x005545, 0x000000, 0xFFFFFF, + 0x005547, 0x00554E, 0x000000, 0xFFFFFF, + 0x005550, 0x005552, 0x000000, 0xFFFFFF, + 0x005554, 0x005555, 0x000000, 0xFFFFFF, + 0x005557, 0x00555D, 0x000000, 0xFFFFFF, + 0x00555F, 0x005562, 0x000000, 0xFFFFFF, + 0x005564, 0x00557B, 0x000000, 0xFFFFFF, + 0x00557D, 0x00557F, 0x000000, 0xFFFFFF, + 0x005581, 0x005583, 0x000000, 0xFFFFFF, + 0x005585, 0x005585, 0x000000, 0xFFFFFF, + 0x005588, 0x005588, 0x000000, 0xFFFFFF, + 0x00558B, 0x005597, 0x000000, 0xFFFFFF, + 0x00559B, 0x00559B, 0x000000, 0xFFFFFF, + 0x00559E, 0x0055A6, 0x000000, 0xFFFFFF, + 0x0055A8, 0x0055A8, 0x000000, 0xFFFFFF, + 0x0055AD, 0x0055AD, 0x000000, 0xFFFFFF, + 0x0055AF, 0x0055C4, 0x000000, 0xFFFFFF, + 0x0055C6, 0x0055C6, 0x000000, 0xFFFFFF, + 0x0055C8, 0x0055D3, 0x000000, 0xFFFFFF, + 0x0055D5, 0x0055D9, 0x000000, 0xFFFFFF, + 0x0055DB, 0x0055DB, 0x000000, 0xFFFFFF, + 0x0055DD, 0x0055DE, 0x000000, 0xFFFFFF, + 0x0055E0, 0x0055E2, 0x000000, 0xFFFFFF, + 0x0055E5, 0x0055FC, 0x000000, 0xFFFFFF, + 0x0055FF, 0x005605, 0x000000, 0xFFFFFF, + 0x005607, 0x005608, 0x000000, 0xFFFFFF, + 0x00560A, 0x005613, 0x000000, 0xFFFFFF, + 0x005615, 0x005616, 0x000000, 0xFFFFFF, + 0x005618, 0x00562E, 0x000000, 0xFFFFFF, + 0x005630, 0x005631, 0x000000, 0xFFFFFF, + 0x005633, 0x005633, 0x000000, 0xFFFFFF, + 0x005635, 0x005635, 0x000000, 0xFFFFFF, + 0x005637, 0x005652, 0x000000, 0xFFFFFF, + 0x005654, 0x005667, 0x000000, 0xFFFFFF, + 0x005669, 0x00566A, 0x000000, 0xFFFFFF, + 0x00566C, 0x005673, 0x000000, 0xFFFFFF, + 0x005675, 0x005685, 0x000000, 0xFFFFFF, + 0x005687, 0x0056A4, 0x000000, 0xFFFFFF, + 0x0056A6, 0x0056AB, 0x000000, 0xFFFFFF, + 0x0056AD, 0x0056AD, 0x000000, 0xFFFFFF, + 0x0056AF, 0x0056B3, 0x000000, 0xFFFFFF, + 0x0056B5, 0x0056BB, 0x000000, 0xFFFFFF, + 0x0056BD, 0x0056C9, 0x000000, 0xFFFFFF, + 0x0056CB, 0x0056CC, 0x000000, 0xFFFFFF, + 0x0056CE, 0x0056D0, 0x000000, 0xFFFFFF, + 0x0056D2, 0x0056D9, 0x000000, 0xFFFFFF, + 0x0056DC, 0x0056DD, 0x000000, 0xFFFFFF, + 0x0056DF, 0x0056DF, 0x000000, 0xFFFFFF, + 0x0056E1, 0x0056EF, 0x000000, 0xFFFFFF, + 0x0056F1, 0x0056F8, 0x000000, 0xFFFFFF, + 0x0056FB, 0x005702, 0x000000, 0xFFFFFF, + 0x005705, 0x005707, 0x000000, 0xFFFFFF, + 0x005709, 0x00570A, 0x000000, 0xFFFFFF, + 0x00570C, 0x00570C, 0x000000, 0xFFFFFF, + 0x00570E, 0x005711, 0x000000, 0xFFFFFF, + 0x005714, 0x005715, 0x000000, 0xFFFFFF, + 0x005717, 0x005717, 0x000000, 0xFFFFFF, + 0x005719, 0x00571E, 0x000000, 0xFFFFFF, + 0x005720, 0x005727, 0x000000, 0xFFFFFF, + 0x005729, 0x00572C, 0x000000, 0xFFFFFF, + 0x00572E, 0x00572F, 0x000000, 0xFFFFFF, + 0x005731, 0x00573A, 0x000000, 0xFFFFFF, + 0x00573C, 0x00573F, 0x000000, 0xFFFFFF, + 0x005741, 0x005741, 0x000000, 0xFFFFFF, + 0x005743, 0x005746, 0x000000, 0xFFFFFF, + 0x005748, 0x005749, 0x000000, 0xFFFFFF, + 0x00574B, 0x00574C, 0x000000, 0xFFFFFF, + 0x00574F, 0x00574F, 0x000000, 0xFFFFFF, + 0x005752, 0x005760, 0x000000, 0xFFFFFF, + 0x005762, 0x005763, 0x000000, 0xFFFFFF, + 0x005765, 0x005765, 0x000000, 0xFFFFFF, + 0x005767, 0x005769, 0x000000, 0xFFFFFF, + 0x00576B, 0x00576D, 0x000000, 0xFFFFFF, + 0x00576F, 0x00576F, 0x000000, 0xFFFFFF, + 0x005771, 0x005774, 0x000000, 0xFFFFFF, + 0x005776, 0x00577B, 0x000000, 0xFFFFFF, + 0x00577D, 0x005781, 0x000000, 0xFFFFFF, + 0x005783, 0x005787, 0x000000, 0xFFFFFF, + 0x005789, 0x00578A, 0x000000, 0xFFFFFF, + 0x00578C, 0x005792, 0x000000, 0xFFFFFF, + 0x005794, 0x00579F, 0x000000, 0xFFFFFF, + 0x0057A1, 0x0057A1, 0x000000, 0xFFFFFF, + 0x0057A4, 0x0057C2, 0x000000, 0xFFFFFF, + 0x0057C4, 0x0057C6, 0x000000, 0xFFFFFF, + 0x0057C9, 0x0057CA, 0x000000, 0xFFFFFF, + 0x0057CC, 0x0057CD, 0x000000, 0xFFFFFF, + 0x0057CF, 0x0057DE, 0x000000, 0xFFFFFF, + 0x0057E1, 0x0057EF, 0x000000, 0xFFFFFF, + 0x0057F1, 0x0057F3, 0x000000, 0xFFFFFF, + 0x0057F5, 0x0057F6, 0x000000, 0xFFFFFF, + 0x0057F8, 0x0057F8, 0x000000, 0xFFFFFF, + 0x0057FB, 0x0057FB, 0x000000, 0xFFFFFF, + 0x0057FD, 0x0057FF, 0x000000, 0xFFFFFF, + 0x005801, 0x005801, 0x000000, 0xFFFFFF, + 0x005803, 0x005804, 0x000000, 0xFFFFFF, + 0x005807, 0x005807, 0x000000, 0xFFFFFF, + 0x00580B, 0x00581D, 0x000000, 0xFFFFFF, + 0x00581F, 0x005820, 0x000000, 0xFFFFFF, + 0x005822, 0x005823, 0x000000, 0xFFFFFF, + 0x005825, 0x005826, 0x000000, 0xFFFFFF, + 0x005828, 0x005829, 0x000000, 0xFFFFFF, + 0x00582B, 0x00582E, 0x000000, 0xFFFFFF, + 0x005832, 0x005833, 0x000000, 0xFFFFFF, + 0x005836, 0x005839, 0x000000, 0xFFFFFF, + 0x00583B, 0x005849, 0x000000, 0xFFFFFF, + 0x00584C, 0x00584E, 0x000000, 0xFFFFFF, + 0x005850, 0x005850, 0x000000, 0xFFFFFF, + 0x005852, 0x005853, 0x000000, 0xFFFFFF, + 0x005855, 0x005856, 0x000000, 0xFFFFFF, + 0x005859, 0x005859, 0x000000, 0xFFFFFF, + 0x00585B, 0x00585D, 0x000000, 0xFFFFFF, + 0x00585F, 0x005860, 0x000000, 0xFFFFFF, + 0x005863, 0x005863, 0x000000, 0xFFFFFF, + 0x005865, 0x005874, 0x000000, 0xFFFFFF, + 0x005876, 0x005878, 0x000000, 0xFFFFFF, + 0x00587A, 0x00587B, 0x000000, 0xFFFFFF, + 0x00587D, 0x00587D, 0x000000, 0xFFFFFF, + 0x00587F, 0x005882, 0x000000, 0xFFFFFF, + 0x005884, 0x005884, 0x000000, 0xFFFFFF, + 0x005886, 0x005888, 0x000000, 0xFFFFFF, + 0x00588A, 0x005892, 0x000000, 0xFFFFFF, + 0x005894, 0x00589B, 0x000000, 0xFFFFFF, + 0x00589D, 0x00589D, 0x000000, 0xFFFFFF, + 0x0058A0, 0x0058A7, 0x000000, 0xFFFFFF, + 0x0058AA, 0x0058AD, 0x000000, 0xFFFFFF, + 0x0058AF, 0x0058B2, 0x000000, 0xFFFFFF, + 0x0058B4, 0x0058B9, 0x000000, 0xFFFFFF, + 0x0058BC, 0x0058BD, 0x000000, 0xFFFFFF, + 0x0058BF, 0x0058C0, 0x000000, 0xFFFFFF, + 0x0058C2, 0x0058C4, 0x000000, 0xFFFFFF, + 0x0058C6, 0x0058C6, 0x000000, 0xFFFFFF, + 0x0058C8, 0x0058CD, 0x000000, 0xFFFFFF, + 0x0058CF, 0x0058D0, 0x000000, 0xFFFFFF, + 0x0058D2, 0x0058D2, 0x000000, 0xFFFFFF, + 0x0058D4, 0x0058D4, 0x000000, 0xFFFFFF, + 0x0058D6, 0x0058D7, 0x000000, 0xFFFFFF, + 0x0058DA, 0x0058DD, 0x000000, 0xFFFFFF, + 0x0058E0, 0x0058E3, 0x000000, 0xFFFFFF, + 0x0058E5, 0x0058EA, 0x000000, 0xFFFFFF, + 0x0058ED, 0x0058EE, 0x000000, 0xFFFFFF, + 0x0058F0, 0x0058F8, 0x000000, 0xFFFFFF, + 0x0058FC, 0x0058FC, 0x000000, 0xFFFFFF, + 0x0058FE, 0x00590E, 0x000000, 0xFFFFFF, + 0x005910, 0x005913, 0x000000, 0xFFFFFF, + 0x005917, 0x005918, 0x000000, 0xFFFFFF, + 0x00591B, 0x00591B, 0x000000, 0xFFFFFF, + 0x00591D, 0x005921, 0x000000, 0xFFFFFF, + 0x005923, 0x005926, 0x000000, 0xFFFFFF, + 0x005928, 0x005928, 0x000000, 0xFFFFFF, + 0x00592C, 0x00592C, 0x000000, 0xFFFFFF, + 0x00592F, 0x005930, 0x000000, 0xFFFFFF, + 0x005932, 0x005936, 0x000000, 0xFFFFFF, + 0x005938, 0x00593D, 0x000000, 0xFFFFFF, + 0x00593F, 0x005943, 0x000000, 0xFFFFFF, + 0x005945, 0x005946, 0x000000, 0xFFFFFF, + 0x00594A, 0x00594D, 0x000000, 0xFFFFFF, + 0x005952, 0x005953, 0x000000, 0xFFFFFF, + 0x005956, 0x005956, 0x000000, 0xFFFFFF, + 0x005958, 0x005959, 0x000000, 0xFFFFFF, + 0x00595B, 0x00595F, 0x000000, 0xFFFFFF, + 0x005961, 0x005961, 0x000000, 0xFFFFFF, + 0x005963, 0x005966, 0x000000, 0xFFFFFF, + 0x005968, 0x005969, 0x000000, 0xFFFFFF, + 0x00596F, 0x005972, 0x000000, 0xFFFFFF, + 0x005975, 0x005977, 0x000000, 0xFFFFFF, + 0x005979, 0x00597C, 0x000000, 0xFFFFFF, + 0x00597E, 0x005981, 0x000000, 0xFFFFFF, + 0x005985, 0x005989, 0x000000, 0xFFFFFF, + 0x00598B, 0x005992, 0x000000, 0xFFFFFF, + 0x005994, 0x005995, 0x000000, 0xFFFFFF, + 0x005998, 0x005998, 0x000000, 0xFFFFFF, + 0x00599A, 0x0059A4, 0x000000, 0xFFFFFF, + 0x0059A6, 0x0059A7, 0x000000, 0xFFFFFF, + 0x0059A9, 0x0059AB, 0x000000, 0xFFFFFF, + 0x0059AD, 0x0059B8, 0x000000, 0xFFFFFF, + 0x0059BA, 0x0059BA, 0x000000, 0xFFFFFF, + 0x0059BC, 0x0059BD, 0x000000, 0xFFFFFF, + 0x0059BF, 0x0059C2, 0x000000, 0xFFFFFF, + 0x0059C4, 0x0059C5, 0x000000, 0xFFFFFF, + 0x0059C7, 0x0059C8, 0x000000, 0xFFFFFF, + 0x0059CA, 0x0059CA, 0x000000, 0xFFFFFF, + 0x0059CC, 0x0059CF, 0x000000, 0xFFFFFF, + 0x0059D2, 0x0059D2, 0x000000, 0xFFFFFF, + 0x0059D5, 0x0059D8, 0x000000, 0xFFFFFF, + 0x0059DB, 0x0059DB, 0x000000, 0xFFFFFF, + 0x0059DE, 0x0059E5, 0x000000, 0xFFFFFF, + 0x0059E7, 0x0059E7, 0x000000, 0xFFFFFF, + 0x0059E9, 0x0059E9, 0x000000, 0xFFFFFF, + 0x0059EB, 0x0059EB, 0x000000, 0xFFFFFF, + 0x0059ED, 0x0059ED, 0x000000, 0xFFFFFF, + 0x0059EF, 0x0059F7, 0x000000, 0xFFFFFF, + 0x0059F9, 0x0059FA, 0x000000, 0xFFFFFF, + 0x0059FC, 0x0059FE, 0x000000, 0xFFFFFF, + 0x005A00, 0x005A00, 0x000000, 0xFFFFFF, + 0x005A02, 0x005A02, 0x000000, 0xFFFFFF, + 0x005A04, 0x005A10, 0x000000, 0xFFFFFF, + 0x005A12, 0x005A17, 0x000000, 0xFFFFFF, + 0x005A19, 0x005A1A, 0x000000, 0xFFFFFF, + 0x005A1D, 0x005A1E, 0x000000, 0xFFFFFF, + 0x005A21, 0x005A24, 0x000000, 0xFFFFFF, + 0x005A26, 0x005A28, 0x000000, 0xFFFFFF, + 0x005A2A, 0x005A35, 0x000000, 0xFFFFFF, + 0x005A37, 0x005A3B, 0x000000, 0xFFFFFF, + 0x005A3D, 0x005A40, 0x000000, 0xFFFFFF, + 0x005A42, 0x005A45, 0x000000, 0xFFFFFF, + 0x005A47, 0x005A48, 0x000000, 0xFFFFFF, + 0x005A4A, 0x005A59, 0x000000, 0xFFFFFF, + 0x005A5B, 0x005A61, 0x000000, 0xFFFFFF, + 0x005A63, 0x005A65, 0x000000, 0xFFFFFF, + 0x005A67, 0x005A91, 0x000000, 0xFFFFFF, + 0x005A93, 0x005A99, 0x000000, 0xFFFFFF, + 0x005A9C, 0x005AA3, 0x000000, 0xFFFFFF, + 0x005AA5, 0x005AC0, 0x000000, 0xFFFFFF, + 0x005AC3, 0x005AC3, 0x000000, 0xFFFFFF, + 0x005AC5, 0x005AC8, 0x000000, 0xFFFFFF, + 0x005ACA, 0x005ACB, 0x000000, 0xFFFFFF, + 0x005ACD, 0x005AE0, 0x000000, 0xFFFFFF, + 0x005AE2, 0x005AE5, 0x000000, 0xFFFFFF, + 0x005AE7, 0x005AE8, 0x000000, 0xFFFFFF, + 0x005AEA, 0x005B04, 0x000000, 0xFFFFFF, + 0x005B06, 0x005B08, 0x000000, 0xFFFFFF, + 0x005B0A, 0x005B0A, 0x000000, 0xFFFFFF, + 0x005B0D, 0x005B15, 0x000000, 0xFFFFFF, + 0x005B17, 0x005B29, 0x000000, 0xFFFFFF, + 0x005B2B, 0x005B3F, 0x000000, 0xFFFFFF, + 0x005B41, 0x005B42, 0x000000, 0xFFFFFF, + 0x005B44, 0x005B4F, 0x000000, 0xFFFFFF, + 0x005B52, 0x005B53, 0x000000, 0xFFFFFF, + 0x005B56, 0x005B56, 0x000000, 0xFFFFFF, + 0x005B59, 0x005B59, 0x000000, 0xFFFFFF, + 0x005B5B, 0x005B5B, 0x000000, 0xFFFFFF, + 0x005B5E, 0x005B5E, 0x000000, 0xFFFFFF, + 0x005B60, 0x005B62, 0x000000, 0xFFFFFF, + 0x005B65, 0x005B68, 0x000000, 0xFFFFFF, + 0x005B6A, 0x005B6A, 0x000000, 0xFFFFFF, + 0x005B6C, 0x005B6F, 0x000000, 0xFFFFFF, + 0x005B72, 0x005B74, 0x000000, 0xFFFFFF, + 0x005B76, 0x005B77, 0x000000, 0xFFFFFF, + 0x005B79, 0x005B79, 0x000000, 0xFFFFFF, + 0x005B7B, 0x005B7B, 0x000000, 0xFFFFFF, + 0x005B7D, 0x005B84, 0x000000, 0xFFFFFF, + 0x005B86, 0x005B86, 0x000000, 0xFFFFFF, + 0x005B8A, 0x005B8A, 0x000000, 0xFFFFFF, + 0x005B8D, 0x005B8E, 0x000000, 0xFFFFFF, + 0x005B90, 0x005B92, 0x000000, 0xFFFFFF, + 0x005B94, 0x005B94, 0x000000, 0xFFFFFF, + 0x005B9D, 0x005BA1, 0x000000, 0xFFFFFF, + 0x005BA7, 0x005BAB, 0x000000, 0xFFFFFF, + 0x005BAD, 0x005BAD, 0x000000, 0xFFFFFF, + 0x005BAF, 0x005BAF, 0x000000, 0xFFFFFF, + 0x005BB1, 0x005BB2, 0x000000, 0xFFFFFF, + 0x005BB7, 0x005BB7, 0x000000, 0xFFFFFF, + 0x005BBA, 0x005BBE, 0x000000, 0xFFFFFF, + 0x005BC1, 0x005BC1, 0x000000, 0xFFFFFF, + 0x005BC8, 0x005BCB, 0x000000, 0xFFFFFF, + 0x005BCD, 0x005BCF, 0x000000, 0xFFFFFF, + 0x005BD1, 0x005BD1, 0x000000, 0xFFFFFF, + 0x005BD5, 0x005BD6, 0x000000, 0xFFFFFF, + 0x005BD8, 0x005BDD, 0x000000, 0xFFFFFF, + 0x005BE0, 0x005BE0, 0x000000, 0xFFFFFF, + 0x005BE3, 0x005BE3, 0x000000, 0xFFFFFF, + 0x005BEA, 0x005BEA, 0x000000, 0xFFFFFF, + 0x005BED, 0x005BED, 0x000000, 0xFFFFFF, + 0x005BF0, 0x005BF4, 0x000000, 0xFFFFFF, + 0x005BF7, 0x005BF7, 0x000000, 0xFFFFFF, + 0x005BF9, 0x005BF9, 0x000000, 0xFFFFFF, + 0x005BFB, 0x005C00, 0x000000, 0xFFFFFF, + 0x005C02, 0x005C03, 0x000000, 0xFFFFFF, + 0x005C05, 0x005C06, 0x000000, 0xFFFFFF, + 0x005C0C, 0x005C0C, 0x000000, 0xFFFFFF, + 0x005C10, 0x005C10, 0x000000, 0xFFFFFF, + 0x005C12, 0x005C15, 0x000000, 0xFFFFFF, + 0x005C17, 0x005C18, 0x000000, 0xFFFFFF, + 0x005C1A, 0x005C23, 0x000000, 0xFFFFFF, + 0x005C25, 0x005C27, 0x000000, 0xFFFFFF, + 0x005C29, 0x005C30, 0x000000, 0xFFFFFF, + 0x005C32, 0x005C37, 0x000000, 0xFFFFFF, + 0x005C3D, 0x005C3D, 0x000000, 0xFFFFFF, + 0x005C41, 0x005C44, 0x000000, 0xFFFFFF, + 0x005C47, 0x005C47, 0x000000, 0xFFFFFF, + 0x005C49, 0x005C4A, 0x000000, 0xFFFFFF, + 0x005C4C, 0x005C4C, 0x000000, 0xFFFFFF, + 0x005C4F, 0x005C50, 0x000000, 0xFFFFFF, + 0x005C52, 0x005C54, 0x000000, 0xFFFFFF, + 0x005C56, 0x005C5A, 0x000000, 0xFFFFFF, + 0x005C5C, 0x005C5F, 0x000000, 0xFFFFFF, + 0x005C61, 0x005C61, 0x000000, 0xFFFFFF, + 0x005C63, 0x005C63, 0x000000, 0xFFFFFF, + 0x005C66, 0x005C6B, 0x000000, 0xFFFFFF, + 0x005C6D, 0x005C6E, 0x000000, 0xFFFFFF, + 0x005C70, 0x005C70, 0x000000, 0xFFFFFF, + 0x005C72, 0x005C78, 0x000000, 0xFFFFFF, + 0x005C7A, 0x005C8F, 0x000000, 0xFFFFFF, + 0x005C92, 0x005CA0, 0x000000, 0xFFFFFF, + 0x005CA2, 0x005CA8, 0x000000, 0xFFFFFF, + 0x005CAA, 0x005CAA, 0x000000, 0xFFFFFF, + 0x005CAD, 0x005CB0, 0x000000, 0xFFFFFF, + 0x005CB2, 0x005CB2, 0x000000, 0xFFFFFF, + 0x005CB4, 0x005CB4, 0x000000, 0xFFFFFF, + 0x005CB6, 0x005CB6, 0x000000, 0xFFFFFF, + 0x005CB9, 0x005CB9, 0x000000, 0xFFFFFF, + 0x005CBB, 0x005CBD, 0x000000, 0xFFFFFF, + 0x005CBF, 0x005CBF, 0x000000, 0xFFFFFF, + 0x005CC1, 0x005CD8, 0x000000, 0xFFFFFF, + 0x005CDA, 0x005CDF, 0x000000, 0xFFFFFF, + 0x005CE1, 0x005CE7, 0x000000, 0xFFFFFF, + 0x005CE9, 0x005CEE, 0x000000, 0xFFFFFF, + 0x005CF1, 0x005CF3, 0x000000, 0xFFFFFF, + 0x005CF5, 0x005CF5, 0x000000, 0xFFFFFF, + 0x005CF7, 0x005CFA, 0x000000, 0xFFFFFF, + 0x005CFC, 0x005CFC, 0x000000, 0xFFFFFF, + 0x005CFE, 0x005D06, 0x000000, 0xFFFFFF, + 0x005D08, 0x005D0C, 0x000000, 0xFFFFFF, + 0x005D0F, 0x005D10, 0x000000, 0xFFFFFF, + 0x005D12, 0x005D13, 0x000000, 0xFFFFFF, + 0x005D15, 0x005D15, 0x000000, 0xFFFFFF, + 0x005D18, 0x005D18, 0x000000, 0xFFFFFF, + 0x005D1A, 0x005D26, 0x000000, 0xFFFFFF, + 0x005D28, 0x005D28, 0x000000, 0xFFFFFF, + 0x005D2A, 0x005D4A, 0x000000, 0xFFFFFF, + 0x005D4D, 0x005D4F, 0x000000, 0xFFFFFF, + 0x005D51, 0x005D68, 0x000000, 0xFFFFFF, + 0x005D6A, 0x005D6B, 0x000000, 0xFFFFFF, + 0x005D6D, 0x005D6E, 0x000000, 0xFFFFFF, + 0x005D70, 0x005D86, 0x000000, 0xFFFFFF, + 0x005D88, 0x005D8A, 0x000000, 0xFFFFFF, + 0x005D8C, 0x005D9C, 0x000000, 0xFFFFFF, + 0x005D9E, 0x005D9F, 0x000000, 0xFFFFFF, + 0x005DA1, 0x005DA1, 0x000000, 0xFFFFFF, + 0x005DA3, 0x005DA9, 0x000000, 0xFFFFFF, + 0x005DAB, 0x005DB7, 0x000000, 0xFFFFFF, + 0x005DB9, 0x005DB9, 0x000000, 0xFFFFFF, + 0x005DBB, 0x005DBB, 0x000000, 0xFFFFFF, + 0x005DBE, 0x005DCC, 0x000000, 0xFFFFFF, + 0x005DCE, 0x005DD1, 0x000000, 0xFFFFFF, + 0x005DD3, 0x005DD5, 0x000000, 0xFFFFFF, + 0x005DD7, 0x005DDC, 0x000000, 0xFFFFFF, + 0x005DDF, 0x005DE0, 0x000000, 0xFFFFFF, + 0x005DE3, 0x005DE4, 0x000000, 0xFFFFFF, + 0x005DE9, 0x005DEA, 0x000000, 0xFFFFFF, + 0x005DEC, 0x005DED, 0x000000, 0xFFFFFF, + 0x005DEF, 0x005DF0, 0x000000, 0xFFFFFF, + 0x005DF5, 0x005DF6, 0x000000, 0xFFFFFF, + 0x005DF8, 0x005DFC, 0x000000, 0xFFFFFF, + 0x005DFF, 0x005E01, 0x000000, 0xFFFFFF, + 0x005E04, 0x005E05, 0x000000, 0xFFFFFF, + 0x005E07, 0x005E0B, 0x000000, 0xFFFFFF, + 0x005E0D, 0x005E10, 0x000000, 0xFFFFFF, + 0x005E12, 0x005E15, 0x000000, 0xFFFFFF, + 0x005E17, 0x005E18, 0x000000, 0xFFFFFF, + 0x005E1A, 0x005E1A, 0x000000, 0xFFFFFF, + 0x005E1C, 0x005E1C, 0x000000, 0xFFFFFF, + 0x005E1E, 0x005E24, 0x000000, 0xFFFFFF, + 0x005E26, 0x005E2A, 0x000000, 0xFFFFFF, + 0x005E2C, 0x005E2C, 0x000000, 0xFFFFFF, + 0x005E2E, 0x005E32, 0x000000, 0xFFFFFF, + 0x005E34, 0x005E35, 0x000000, 0xFFFFFF, + 0x005E37, 0x005E37, 0x000000, 0xFFFFFF, + 0x005E39, 0x005E3C, 0x000000, 0xFFFFFF, + 0x005E3E, 0x005E3E, 0x000000, 0xFFFFFF, + 0x005E41, 0x005E43, 0x000000, 0xFFFFFF, + 0x005E46, 0x005E46, 0x000000, 0xFFFFFF, + 0x005E48, 0x005E4B, 0x000000, 0xFFFFFF, + 0x005E4D, 0x005E54, 0x000000, 0xFFFFFF, + 0x005E56, 0x005E5E, 0x000000, 0xFFFFFF, + 0x005E60, 0x005E60, 0x000000, 0xFFFFFF, + 0x005E64, 0x005E71, 0x000000, 0xFFFFFF, + 0x005E75, 0x005E76, 0x000000, 0xFFFFFF, + 0x005E7A, 0x005E7A, 0x000000, 0xFFFFFF, + 0x005E7F, 0x005E83, 0x000000, 0xFFFFFF, + 0x005E85, 0x005E86, 0x000000, 0xFFFFFF, + 0x005E88, 0x005E89, 0x000000, 0xFFFFFF, + 0x005E8B, 0x005E8E, 0x000000, 0xFFFFFF, + 0x005E90, 0x005E94, 0x000000, 0xFFFFFF, + 0x005E96, 0x005E96, 0x000000, 0xFFFFFF, + 0x005E98, 0x005E99, 0x000000, 0xFFFFFF, + 0x005E9B, 0x005E9B, 0x000000, 0xFFFFFF, + 0x005E9D, 0x005E9F, 0x000000, 0xFFFFFF, + 0x005EA1, 0x005EA5, 0x000000, 0xFFFFFF, + 0x005EA8, 0x005EAA, 0x000000, 0xFFFFFF, + 0x005EAC, 0x005EAC, 0x000000, 0xFFFFFF, + 0x005EAE, 0x005EB4, 0x000000, 0xFFFFFF, + 0x005EB9, 0x005EBD, 0x000000, 0xFFFFFF, + 0x005EBF, 0x005EC1, 0x000000, 0xFFFFFF, + 0x005EC3, 0x005EC7, 0x000000, 0xFFFFFF, + 0x005ECB, 0x005ECF, 0x000000, 0xFFFFFF, + 0x005ED1, 0x005ED2, 0x000000, 0xFFFFFF, + 0x005ED4, 0x005ED5, 0x000000, 0xFFFFFF, + 0x005ED7, 0x005ED9, 0x000000, 0xFFFFFF, + 0x005EDC, 0x005EDE, 0x000000, 0xFFFFFF, + 0x005EE1, 0x005EE1, 0x000000, 0xFFFFFF, + 0x005EE4, 0x005EEB, 0x000000, 0xFFFFFF, + 0x005EED, 0x005EF2, 0x000000, 0xFFFFFF, + 0x005EF4, 0x005EF5, 0x000000, 0xFFFFFF, + 0x005EF8, 0x005EF9, 0x000000, 0xFFFFFF, + 0x005EFC, 0x005F00, 0x000000, 0xFFFFFF, + 0x005F02, 0x005F03, 0x000000, 0xFFFFFF, + 0x005F05, 0x005F09, 0x000000, 0xFFFFFF, + 0x005F0B, 0x005F0E, 0x000000, 0xFFFFFF, + 0x005F10, 0x005F10, 0x000000, 0xFFFFFF, + 0x005F12, 0x005F12, 0x000000, 0xFFFFFF, + 0x005F16, 0x005F16, 0x000000, 0xFFFFFF, + 0x005F19, 0x005F1A, 0x000000, 0xFFFFFF, + 0x005F1C, 0x005F1E, 0x000000, 0xFFFFFF, + 0x005F20, 0x005F25, 0x000000, 0xFFFFFF, + 0x005F28, 0x005F28, 0x000000, 0xFFFFFF, + 0x005F2A, 0x005F30, 0x000000, 0xFFFFFF, + 0x005F32, 0x005F34, 0x000000, 0xFFFFFF, + 0x005F36, 0x005F39, 0x000000, 0xFFFFFF, + 0x005F3B, 0x005F3B, 0x000000, 0xFFFFFF, + 0x005F3D, 0x005F47, 0x000000, 0xFFFFFF, + 0x005F49, 0x005F49, 0x000000, 0xFFFFFF, + 0x005F4B, 0x005F4B, 0x000000, 0xFFFFFF, + 0x005F4D, 0x005F4D, 0x000000, 0xFFFFFF, + 0x005F4F, 0x005F55, 0x000000, 0xFFFFFF, + 0x005F58, 0x005F58, 0x000000, 0xFFFFFF, + 0x005F5A, 0x005F5A, 0x000000, 0xFFFFFF, + 0x005F5C, 0x005F61, 0x000000, 0xFFFFFF, + 0x005F63, 0x005F65, 0x000000, 0xFFFFFF, + 0x005F68, 0x005F68, 0x000000, 0xFFFFFF, + 0x005F6E, 0x005F6F, 0x000000, 0xFFFFFF, + 0x005F72, 0x005F76, 0x000000, 0xFFFFFF, + 0x005F78, 0x005F78, 0x000000, 0xFFFFFF, + 0x005F7A, 0x005F7B, 0x000000, 0xFFFFFF, + 0x005F7D, 0x005F7E, 0x000000, 0xFFFFFF, + 0x005F82, 0x005F84, 0x000000, 0xFFFFFF, + 0x005F86, 0x005F86, 0x000000, 0xFFFFFF, + 0x005F88, 0x005F89, 0x000000, 0xFFFFFF, + 0x005F8D, 0x005F8F, 0x000000, 0xFFFFFF, + 0x005F93, 0x005F96, 0x000000, 0xFFFFFF, + 0x005F9A, 0x005F9D, 0x000000, 0xFFFFFF, + 0x005F9F, 0x005F9F, 0x000000, 0xFFFFFF, + 0x005FA2, 0x005FA7, 0x000000, 0xFFFFFF, + 0x005FAB, 0x005FAD, 0x000000, 0xFFFFFF, + 0x005FAF, 0x005FB4, 0x000000, 0xFFFFFF, + 0x005FB6, 0x005FB6, 0x000000, 0xFFFFFF, + 0x005FB8, 0x005FB8, 0x000000, 0xFFFFFF, + 0x005FBA, 0x005FBC, 0x000000, 0xFFFFFF, + 0x005FBE, 0x005FC2, 0x000000, 0xFFFFFF, + 0x005FC4, 0x005FC4, 0x000000, 0xFFFFFF, + 0x005FC6, 0x005FCB, 0x000000, 0xFFFFFF, + 0x005FCE, 0x005FD5, 0x000000, 0xFFFFFF, + 0x005FDA, 0x005FDF, 0x000000, 0xFFFFFF, + 0x005FE1, 0x005FEA, 0x000000, 0xFFFFFF, + 0x005FEC, 0x005FF4, 0x000000, 0xFFFFFF, + 0x005FF6, 0x005FFC, 0x000000, 0xFFFFFF, + 0x005FFE, 0x005FFE, 0x000000, 0xFFFFFF, + 0x006000, 0x00600E, 0x000000, 0xFFFFFF, + 0x006010, 0x006011, 0x000000, 0xFFFFFF, + 0x006013, 0x006015, 0x000000, 0xFFFFFF, + 0x006017, 0x00601B, 0x000000, 0xFFFFFF, + 0x00601E, 0x00601F, 0x000000, 0xFFFFFF, + 0x006022, 0x006024, 0x000000, 0xFFFFFF, + 0x006026, 0x006026, 0x000000, 0xFFFFFF, + 0x006029, 0x006029, 0x000000, 0xFFFFFF, + 0x00602B, 0x00602E, 0x000000, 0xFFFFFF, + 0x006030, 0x006040, 0x000000, 0xFFFFFF, + 0x006044, 0x00604C, 0x000000, 0xFFFFFF, + 0x00604E, 0x00604F, 0x000000, 0xFFFFFF, + 0x006051, 0x006051, 0x000000, 0xFFFFFF, + 0x006053, 0x006054, 0x000000, 0xFFFFFF, + 0x006056, 0x006058, 0x000000, 0xFFFFFF, + 0x00605A, 0x00605C, 0x000000, 0xFFFFFF, + 0x00605E, 0x006061, 0x000000, 0xFFFFFF, + 0x006066, 0x006067, 0x000000, 0xFFFFFF, + 0x00606B, 0x00606B, 0x000000, 0xFFFFFF, + 0x00606E, 0x00606E, 0x000000, 0xFFFFFF, + 0x006071, 0x006084, 0x000000, 0xFFFFFF, + 0x006086, 0x006088, 0x000000, 0xFFFFFF, + 0x00608A, 0x00608B, 0x000000, 0xFFFFFF, + 0x00608E, 0x006093, 0x000000, 0xFFFFFF, + 0x006095, 0x006095, 0x000000, 0xFFFFFF, + 0x006097, 0x006099, 0x000000, 0xFFFFFF, + 0x00609C, 0x00609E, 0x000000, 0xFFFFFF, + 0x0060A1, 0x0060A2, 0x000000, 0xFFFFFF, + 0x0060A5, 0x0060A6, 0x000000, 0xFFFFFF, + 0x0060A8, 0x0060AF, 0x000000, 0xFFFFFF, + 0x0060B1, 0x0060B1, 0x000000, 0xFFFFFF, + 0x0060B5, 0x0060B5, 0x000000, 0xFFFFFF, + 0x0060B7, 0x0060B7, 0x000000, 0xFFFFFF, + 0x0060B9, 0x0060BB, 0x000000, 0xFFFFFF, + 0x0060BE, 0x0060C4, 0x000000, 0xFFFFFF, + 0x0060C6, 0x0060C6, 0x000000, 0xFFFFFF, + 0x0060C8, 0x0060D0, 0x000000, 0xFFFFFF, + 0x0060D2, 0x0060D9, 0x000000, 0xFFFFFF, + 0x0060DB, 0x0060DB, 0x000000, 0xFFFFFF, + 0x0060DD, 0x0060DE, 0x000000, 0xFFFFFF, + 0x0060E2, 0x0060EF, 0x000000, 0xFFFFFF, + 0x0060F2, 0x0060F2, 0x000000, 0xFFFFFF, + 0x0060F4, 0x0060F5, 0x000000, 0xFFFFFF, + 0x0060F7, 0x0060F8, 0x000000, 0xFFFFFF, + 0x0060FC, 0x006100, 0x000000, 0xFFFFFF, + 0x006102, 0x006105, 0x000000, 0xFFFFFF, + 0x006107, 0x006107, 0x000000, 0xFFFFFF, + 0x00610A, 0x00610C, 0x000000, 0xFFFFFF, + 0x006110, 0x006114, 0x000000, 0xFFFFFF, + 0x006116, 0x006119, 0x000000, 0xFFFFFF, + 0x00611C, 0x00611E, 0x000000, 0xFFFFFF, + 0x006120, 0x006126, 0x000000, 0xFFFFFF, + 0x006128, 0x00612F, 0x000000, 0xFFFFFF, + 0x006131, 0x006133, 0x000000, 0xFFFFFF, + 0x006135, 0x006136, 0x000000, 0xFFFFFF, + 0x006138, 0x00613B, 0x000000, 0xFFFFFF, + 0x00613D, 0x00613D, 0x000000, 0xFFFFFF, + 0x006140, 0x006141, 0x000000, 0xFFFFFF, + 0x006143, 0x006143, 0x000000, 0xFFFFFF, + 0x006145, 0x006146, 0x000000, 0xFFFFFF, + 0x006149, 0x006149, 0x000000, 0xFFFFFF, + 0x00614D, 0x006152, 0x000000, 0xFFFFFF, + 0x006154, 0x006154, 0x000000, 0xFFFFFF, + 0x006156, 0x006157, 0x000000, 0xFFFFFF, + 0x00615A, 0x00615C, 0x000000, 0xFFFFFF, + 0x00615E, 0x00615E, 0x000000, 0xFFFFFF, + 0x006160, 0x006161, 0x000000, 0xFFFFFF, + 0x006165, 0x006166, 0x000000, 0xFFFFFF, + 0x006169, 0x00616A, 0x000000, 0xFFFFFF, + 0x00616C, 0x00616D, 0x000000, 0xFFFFFF, + 0x00616F, 0x00616F, 0x000000, 0xFFFFFF, + 0x006171, 0x006175, 0x000000, 0xFFFFFF, + 0x006178, 0x00617C, 0x000000, 0xFFFFFF, + 0x00617F, 0x006180, 0x000000, 0xFFFFFF, + 0x006183, 0x006189, 0x000000, 0xFFFFFF, + 0x00618B, 0x00618D, 0x000000, 0xFFFFFF, + 0x00618F, 0x00618F, 0x000000, 0xFFFFFF, + 0x006192, 0x006193, 0x000000, 0xFFFFFF, + 0x006195, 0x006197, 0x000000, 0xFFFFFF, + 0x00619B, 0x0061A3, 0x000000, 0xFFFFFF, + 0x0061A5, 0x0061A6, 0x000000, 0xFFFFFF, + 0x0061A8, 0x0061A8, 0x000000, 0xFFFFFF, + 0x0061AA, 0x0061AA, 0x000000, 0xFFFFFF, + 0x0061AD, 0x0061AD, 0x000000, 0xFFFFFF, + 0x0061AF, 0x0061B1, 0x000000, 0xFFFFFF, + 0x0061B3, 0x0061B5, 0x000000, 0xFFFFFF, + 0x0061B7, 0x0061B9, 0x000000, 0xFFFFFF, + 0x0061BB, 0x0061BD, 0x000000, 0xFFFFFF, + 0x0061BF, 0x0061C2, 0x000000, 0xFFFFFF, + 0x0061C4, 0x0061C6, 0x000000, 0xFFFFFF, + 0x0061CC, 0x0061E5, 0x000000, 0xFFFFFF, + 0x0061E7, 0x0061F1, 0x000000, 0xFFFFFF, + 0x0061F3, 0x0061F5, 0x000000, 0xFFFFFF, + 0x0061F9, 0x0061F9, 0x000000, 0xFFFFFF, + 0x0061FB, 0x0061FB, 0x000000, 0xFFFFFF, + 0x0061FD, 0x0061FE, 0x000000, 0xFFFFFF, + 0x006201, 0x006206, 0x000000, 0xFFFFFF, + 0x006209, 0x006209, 0x000000, 0xFFFFFF, + 0x00620B, 0x00620B, 0x000000, 0xFFFFFF, + 0x00620F, 0x00620F, 0x000000, 0xFFFFFF, + 0x006213, 0x006215, 0x000000, 0xFFFFFF, + 0x006217, 0x006219, 0x000000, 0xFFFFFF, + 0x00621B, 0x00621E, 0x000000, 0xFFFFFF, + 0x006220, 0x006220, 0x000000, 0xFFFFFF, + 0x006222, 0x006229, 0x000000, 0xFFFFFF, + 0x00622B, 0x00622D, 0x000000, 0xFFFFFF, + 0x00622F, 0x00622F, 0x000000, 0xFFFFFF, + 0x006232, 0x006233, 0x000000, 0xFFFFFF, + 0x006235, 0x006235, 0x000000, 0xFFFFFF, + 0x006237, 0x00623D, 0x000000, 0xFFFFFF, + 0x006242, 0x006246, 0x000000, 0xFFFFFF, + 0x00624A, 0x00624A, 0x000000, 0xFFFFFF, + 0x00624C, 0x00624C, 0x000000, 0xFFFFFF, + 0x00624E, 0x006252, 0x000000, 0xFFFFFF, + 0x006254, 0x006257, 0x000000, 0xFFFFFF, + 0x006259, 0x00626D, 0x000000, 0xFFFFFF, + 0x00626F, 0x006270, 0x000000, 0xFFFFFF, + 0x006272, 0x006275, 0x000000, 0xFFFFFF, + 0x006277, 0x006278, 0x000000, 0xFFFFFF, + 0x00627A, 0x00627B, 0x000000, 0xFFFFFF, + 0x00627D, 0x00627E, 0x000000, 0xFFFFFF, + 0x006281, 0x006283, 0x000000, 0xFFFFFF, + 0x006285, 0x006288, 0x000000, 0xFFFFFF, + 0x00628B, 0x006290, 0x000000, 0xFFFFFF, + 0x006293, 0x006294, 0x000000, 0xFFFFFF, + 0x006296, 0x006296, 0x000000, 0xFFFFFF, + 0x006299, 0x00629A, 0x000000, 0xFFFFFF, + 0x00629C, 0x0062AA, 0x000000, 0xFFFFFF, + 0x0062AC, 0x0062B0, 0x000000, 0xFFFFFF, + 0x0062B2, 0x0062B4, 0x000000, 0xFFFFFF, + 0x0062B6, 0x0062B8, 0x000000, 0xFFFFFF, + 0x0062BA, 0x0062BB, 0x000000, 0xFFFFFF, + 0x0062BE, 0x0062C1, 0x000000, 0xFFFFFF, + 0x0062C3, 0x0062C6, 0x000000, 0xFFFFFF, + 0x0062CA, 0x0062CB, 0x000000, 0xFFFFFF, + 0x0062CE, 0x0062CE, 0x000000, 0xFFFFFF, + 0x0062D1, 0x0062D1, 0x000000, 0xFFFFFF, + 0x0062D5, 0x0062D5, 0x000000, 0xFFFFFF, + 0x0062DA, 0x0062DA, 0x000000, 0xFFFFFF, + 0x0062DD, 0x0062EB, 0x000000, 0xFFFFFF, + 0x0062F0, 0x0062F0, 0x000000, 0xFFFFFF, + 0x0062F2, 0x0062F2, 0x000000, 0xFFFFFF, + 0x0062F4, 0x0062F6, 0x000000, 0xFFFFFF, + 0x0062F8, 0x0062FD, 0x000000, 0xFFFFFF, + 0x006300, 0x006300, 0x000000, 0xFFFFFF, + 0x006302, 0x006306, 0x000000, 0xFFFFFF, + 0x006308, 0x006308, 0x000000, 0xFFFFFF, + 0x00630A, 0x006310, 0x000000, 0xFFFFFF, + 0x006312, 0x00632A, 0x000000, 0xFFFFFF, + 0x00632C, 0x00632E, 0x000000, 0xFFFFFF, + 0x006330, 0x006339, 0x000000, 0xFFFFFF, + 0x00633C, 0x00633C, 0x000000, 0xFFFFFF, + 0x00633F, 0x006348, 0x000000, 0xFFFFFF, + 0x00634A, 0x00634B, 0x000000, 0xFFFFFF, + 0x00634D, 0x00634E, 0x000000, 0xFFFFFF, + 0x006351, 0x006354, 0x000000, 0xFFFFFF, + 0x006356, 0x006366, 0x000000, 0xFFFFFF, + 0x006369, 0x00636D, 0x000000, 0xFFFFFF, + 0x00636F, 0x006371, 0x000000, 0xFFFFFF, + 0x006373, 0x006376, 0x000000, 0xFFFFFF, + 0x006378, 0x006379, 0x000000, 0xFFFFFF, + 0x00637C, 0x00637E, 0x000000, 0xFFFFFF, + 0x006380, 0x006382, 0x000000, 0xFFFFFF, + 0x006384, 0x006387, 0x000000, 0xFFFFFF, + 0x00638A, 0x00638B, 0x000000, 0xFFFFFF, + 0x00638D, 0x006391, 0x000000, 0xFFFFFF, + 0x006393, 0x006395, 0x000000, 0xFFFFFF, + 0x006397, 0x006397, 0x000000, 0xFFFFFF, + 0x006399, 0x00639A, 0x000000, 0xFFFFFF, + 0x00639C, 0x00639F, 0x000000, 0xFFFFFF, + 0x0063A3, 0x0063A4, 0x000000, 0xFFFFFF, + 0x0063A6, 0x0063A6, 0x000000, 0xFFFFFF, + 0x0063AB, 0x0063BF, 0x000000, 0xFFFFFF, + 0x0063C1, 0x0063C3, 0x000000, 0xFFFFFF, + 0x0063C5, 0x0063C5, 0x000000, 0xFFFFFF, + 0x0063C7, 0x0063CE, 0x000000, 0xFFFFFF, + 0x0063D1, 0x0063D5, 0x000000, 0xFFFFFF, + 0x0063D7, 0x0063D9, 0x000000, 0xFFFFFF, + 0x0063DC, 0x0063E0, 0x000000, 0xFFFFFF, + 0x0063E2, 0x0063EC, 0x000000, 0xFFFFFF, + 0x0063EF, 0x0063F3, 0x000000, 0xFFFFFF, + 0x0063F5, 0x0063F5, 0x000000, 0xFFFFFF, + 0x0063F8, 0x00640C, 0x000000, 0xFFFFFF, + 0x00640E, 0x00640E, 0x000000, 0xFFFFFF, + 0x006410, 0x006413, 0x000000, 0xFFFFFF, + 0x006415, 0x006415, 0x000000, 0xFFFFFF, + 0x006418, 0x00641B, 0x000000, 0xFFFFFF, + 0x00641D, 0x006421, 0x000000, 0xFFFFFF, + 0x006423, 0x00642B, 0x000000, 0xFFFFFF, + 0x00642E, 0x006439, 0x000000, 0xFFFFFF, + 0x00643B, 0x00643D, 0x000000, 0xFFFFFF, + 0x00643F, 0x006457, 0x000000, 0xFFFFFF, + 0x006459, 0x00645F, 0x000000, 0xFFFFFF, + 0x006461, 0x006468, 0x000000, 0xFFFFFF, + 0x00646A, 0x00646E, 0x000000, 0xFFFFFF, + 0x006470, 0x006477, 0x000000, 0xFFFFFF, + 0x00647B, 0x006487, 0x000000, 0xFFFFFF, + 0x006489, 0x006490, 0x000000, 0xFFFFFF, + 0x006494, 0x006499, 0x000000, 0xFFFFFF, + 0x00649B, 0x00649D, 0x000000, 0xFFFFFF, + 0x00649F, 0x0064A3, 0x000000, 0xFFFFFF, + 0x0064A6, 0x0064AA, 0x000000, 0xFFFFFF, + 0x0064AC, 0x0064AC, 0x000000, 0xFFFFFF, + 0x0064AF, 0x0064AF, 0x000000, 0xFFFFFF, + 0x0064B1, 0x0064B1, 0x000000, 0xFFFFFF, + 0x0064B3, 0x0064BA, 0x000000, 0xFFFFFF, + 0x0064BC, 0x0064C0, 0x000000, 0xFFFFFF, + 0x0064C2, 0x0064C3, 0x000000, 0xFFFFFF, + 0x0064C6, 0x0064C6, 0x000000, 0xFFFFFF, + 0x0064C8, 0x0064C9, 0x000000, 0xFFFFFF, + 0x0064CB, 0x0064CC, 0x000000, 0xFFFFFF, + 0x0064CF, 0x0064D1, 0x000000, 0xFFFFFF, + 0x0064D3, 0x0064D3, 0x000000, 0xFFFFFF, + 0x0064D5, 0x0064D7, 0x000000, 0xFFFFFF, + 0x0064D9, 0x0064D9, 0x000000, 0xFFFFFF, + 0x0064DB, 0x0064E0, 0x000000, 0xFFFFFF, + 0x0064E3, 0x0064E4, 0x000000, 0xFFFFFF, + 0x0064E8, 0x0064EB, 0x000000, 0xFFFFFF, + 0x0064ED, 0x0064F1, 0x000000, 0xFFFFFF, + 0x0064F3, 0x0064F3, 0x000000, 0xFFFFFF, + 0x0064F5, 0x0064F9, 0x000000, 0xFFFFFF, + 0x0064FB, 0x0064FD, 0x000000, 0xFFFFFF, + 0x0064FF, 0x0064FF, 0x000000, 0xFFFFFF, + 0x006501, 0x006503, 0x000000, 0xFFFFFF, + 0x006505, 0x006517, 0x000000, 0xFFFFFF, + 0x006519, 0x00651C, 0x000000, 0xFFFFFF, + 0x00651E, 0x006522, 0x000000, 0xFFFFFF, + 0x006524, 0x006529, 0x000000, 0xFFFFFF, + 0x00652D, 0x00652E, 0x000000, 0xFFFFFF, + 0x006530, 0x006535, 0x000000, 0xFFFFFF, + 0x00653A, 0x00653A, 0x000000, 0xFFFFFF, + 0x00653C, 0x00653D, 0x000000, 0xFFFFFF, + 0x006540, 0x006544, 0x000000, 0xFFFFFF, + 0x006546, 0x006547, 0x000000, 0xFFFFFF, + 0x006549, 0x00654C, 0x000000, 0xFFFFFF, + 0x006550, 0x006550, 0x000000, 0xFFFFFF, + 0x006552, 0x006555, 0x000000, 0xFFFFFF, + 0x006558, 0x00655D, 0x000000, 0xFFFFFF, + 0x00655F, 0x006561, 0x000000, 0xFFFFFF, + 0x006564, 0x006565, 0x000000, 0xFFFFFF, + 0x006567, 0x00656B, 0x000000, 0xFFFFFF, + 0x00656E, 0x006571, 0x000000, 0xFFFFFF, + 0x006573, 0x006573, 0x000000, 0xFFFFFF, + 0x006576, 0x006576, 0x000000, 0xFFFFFF, + 0x006579, 0x00657D, 0x000000, 0xFFFFFF, + 0x00657F, 0x006581, 0x000000, 0xFFFFFF, + 0x006584, 0x006584, 0x000000, 0xFFFFFF, + 0x006586, 0x006586, 0x000000, 0xFFFFFF, + 0x006588, 0x00658B, 0x000000, 0xFFFFFF, + 0x00658D, 0x00658F, 0x000000, 0xFFFFFF, + 0x006592, 0x006596, 0x000000, 0xFFFFFF, + 0x006598, 0x006598, 0x000000, 0xFFFFFF, + 0x00659A, 0x00659A, 0x000000, 0xFFFFFF, + 0x00659D, 0x00659E, 0x000000, 0xFFFFFF, + 0x0065A0, 0x0065A0, 0x000000, 0xFFFFFF, + 0x0065A2, 0x0065A3, 0x000000, 0xFFFFFF, + 0x0065A6, 0x0065A6, 0x000000, 0xFFFFFF, + 0x0065A8, 0x0065AA, 0x000000, 0xFFFFFF, + 0x0065AD, 0x0065AE, 0x000000, 0xFFFFFF, + 0x0065B1, 0x0065B6, 0x000000, 0xFFFFFF, + 0x0065B8, 0x0065B8, 0x000000, 0xFFFFFF, + 0x0065BA, 0x0065BB, 0x000000, 0xFFFFFF, + 0x0065BE, 0x0065C0, 0x000000, 0xFFFFFF, + 0x0065C2, 0x0065C4, 0x000000, 0xFFFFFF, + 0x0065C6, 0x0065CA, 0x000000, 0xFFFFFF, + 0x0065CD, 0x0065CE, 0x000000, 0xFFFFFF, + 0x0065D0, 0x0065D1, 0x000000, 0xFFFFFF, + 0x0065D3, 0x0065D6, 0x000000, 0xFFFFFF, + 0x0065D8, 0x0065DF, 0x000000, 0xFFFFFF, + 0x0065E1, 0x0065E2, 0x000000, 0xFFFFFF, + 0x0065E4, 0x0065E4, 0x000000, 0xFFFFFF, + 0x0065E7, 0x0065E7, 0x000000, 0xFFFFFF, + 0x0065EA, 0x0065EB, 0x000000, 0xFFFFFF, + 0x0065EE, 0x0065F0, 0x000000, 0xFFFFFF, + 0x0065F2, 0x0065F3, 0x000000, 0xFFFFFF, + 0x0065F5, 0x0065F9, 0x000000, 0xFFFFFF, + 0x0065FE, 0x0065FE, 0x000000, 0xFFFFFF, + 0x006600, 0x006605, 0x000000, 0xFFFFFF, + 0x006608, 0x006608, 0x000000, 0xFFFFFF, + 0x00660B, 0x00660B, 0x000000, 0xFFFFFF, + 0x00660D, 0x00660D, 0x000000, 0xFFFFFF, + 0x006612, 0x006612, 0x000000, 0xFFFFFF, + 0x006616, 0x00661D, 0x000000, 0xFFFFFF, + 0x006621, 0x006624, 0x000000, 0xFFFFFF, + 0x006626, 0x006626, 0x000000, 0xFFFFFF, + 0x006629, 0x00662C, 0x000000, 0xFFFFFF, + 0x00662E, 0x00662E, 0x000000, 0xFFFFFF, + 0x006632, 0x006633, 0x000000, 0xFFFFFF, + 0x006635, 0x006635, 0x000000, 0xFFFFFF, + 0x006637, 0x006639, 0x000000, 0xFFFFFF, + 0x00663C, 0x006640, 0x000000, 0xFFFFFF, + 0x006645, 0x006648, 0x000000, 0xFFFFFF, + 0x00664A, 0x00664A, 0x000000, 0xFFFFFF, + 0x00664C, 0x00664E, 0x000000, 0xFFFFFF, + 0x006650, 0x006658, 0x000000, 0xFFFFFF, + 0x00665A, 0x00665A, 0x000000, 0xFFFFFF, + 0x00665C, 0x00665C, 0x000000, 0xFFFFFF, + 0x006660, 0x006663, 0x000000, 0xFFFFFF, + 0x00666A, 0x00666A, 0x000000, 0xFFFFFF, + 0x00666C, 0x00666D, 0x000000, 0xFFFFFF, + 0x006670, 0x006672, 0x000000, 0xFFFFFF, + 0x006675, 0x006675, 0x000000, 0xFFFFFF, + 0x006679, 0x006679, 0x000000, 0xFFFFFF, + 0x00667B, 0x006683, 0x000000, 0xFFFFFF, + 0x006685, 0x006686, 0x000000, 0xFFFFFF, + 0x00668A, 0x00668D, 0x000000, 0xFFFFFF, + 0x00668F, 0x00668F, 0x000000, 0xFFFFFF, + 0x006692, 0x006695, 0x000000, 0xFFFFFF, + 0x006699, 0x00669C, 0x000000, 0xFFFFFF, + 0x00669E, 0x00669F, 0x000000, 0xFFFFFF, + 0x0066A1, 0x0066A1, 0x000000, 0xFFFFFF, + 0x0066A3, 0x0066AA, 0x000000, 0xFFFFFF, + 0x0066AC, 0x0066AD, 0x000000, 0xFFFFFF, + 0x0066AF, 0x0066B1, 0x000000, 0xFFFFFF, + 0x0066B5, 0x0066B8, 0x000000, 0xFFFFFF, + 0x0066BA, 0x0066BA, 0x000000, 0xFFFFFF, + 0x0066BC, 0x0066BD, 0x000000, 0xFFFFFF, + 0x0066BF, 0x0066C3, 0x000000, 0xFFFFFF, + 0x0066C5, 0x0066C5, 0x000000, 0xFFFFFF, + 0x0066C8, 0x0066C8, 0x000000, 0xFFFFFF, + 0x0066CA, 0x0066D5, 0x000000, 0xFFFFFF, + 0x0066D7, 0x0066D8, 0x000000, 0xFFFFFF, + 0x0066DA, 0x0066DB, 0x000000, 0xFFFFFF, + 0x0066DE, 0x0066DF, 0x000000, 0xFFFFFF, + 0x0066E1, 0x0066E5, 0x000000, 0xFFFFFF, + 0x0066E7, 0x0066EF, 0x000000, 0xFFFFFF, + 0x0066F1, 0x0066F1, 0x000000, 0xFFFFFF, + 0x0066F5, 0x0066F6, 0x000000, 0xFFFFFF, + 0x0066FB, 0x0066FB, 0x000000, 0xFFFFFF, + 0x0066FD, 0x0066FD, 0x000000, 0xFFFFFF, + 0x006701, 0x006702, 0x000000, 0xFFFFFF, + 0x006704, 0x006707, 0x000000, 0xFFFFFF, + 0x00670A, 0x00670A, 0x000000, 0xFFFFFF, + 0x00670C, 0x00670C, 0x000000, 0xFFFFFF, + 0x00670E, 0x006713, 0x000000, 0xFFFFFF, + 0x006716, 0x006716, 0x000000, 0xFFFFFF, + 0x006718, 0x00671A, 0x000000, 0xFFFFFF, + 0x00671C, 0x00671C, 0x000000, 0xFFFFFF, + 0x006720, 0x006725, 0x000000, 0xFFFFFF, + 0x006729, 0x006729, 0x000000, 0xFFFFFF, + 0x00672F, 0x006730, 0x000000, 0xFFFFFF, + 0x006732, 0x006733, 0x000000, 0xFFFFFF, + 0x006735, 0x006735, 0x000000, 0xFFFFFF, + 0x006737, 0x006739, 0x000000, 0xFFFFFF, + 0x00673B, 0x00673C, 0x000000, 0xFFFFFF, + 0x00673E, 0x006745, 0x000000, 0xFFFFFF, + 0x006747, 0x006748, 0x000000, 0xFFFFFF, + 0x00674A, 0x00674D, 0x000000, 0xFFFFFF, + 0x006752, 0x006752, 0x000000, 0xFFFFFF, + 0x006754, 0x006755, 0x000000, 0xFFFFFF, + 0x006757, 0x00675B, 0x000000, 0xFFFFFF, + 0x00675D, 0x00675D, 0x000000, 0xFFFFFF, + 0x006760, 0x00676C, 0x000000, 0xFFFFFF, + 0x00676E, 0x00676E, 0x000000, 0xFFFFFF, + 0x006772, 0x006772, 0x000000, 0xFFFFFF, + 0x006774, 0x006774, 0x000000, 0xFFFFFF, + 0x006776, 0x006776, 0x000000, 0xFFFFFF, + 0x006778, 0x00677A, 0x000000, 0xFFFFFF, + 0x00677C, 0x00677D, 0x000000, 0xFFFFFF, + 0x006780, 0x006786, 0x000000, 0xFFFFFF, + 0x006788, 0x006788, 0x000000, 0xFFFFFF, + 0x00678A, 0x00678A, 0x000000, 0xFFFFFF, + 0x00678C, 0x00678E, 0x000000, 0xFFFFFF, + 0x006791, 0x006792, 0x000000, 0xFFFFFF, + 0x006794, 0x006794, 0x000000, 0xFFFFFF, + 0x006796, 0x006796, 0x000000, 0xFFFFFF, + 0x006798, 0x006799, 0x000000, 0xFFFFFF, + 0x00679B, 0x00679B, 0x000000, 0xFFFFFF, + 0x00679E, 0x0067AE, 0x000000, 0xFFFFFF, + 0x0067B1, 0x0067B2, 0x000000, 0xFFFFFF, + 0x0067B4, 0x0067B5, 0x000000, 0xFFFFFF, + 0x0067B9, 0x0067BD, 0x000000, 0xFFFFFF, + 0x0067BF, 0x0067C3, 0x000000, 0xFFFFFF, + 0x0067C5, 0x0067CE, 0x000000, 0xFFFFFF, + 0x0067D5, 0x0067D9, 0x000000, 0xFFFFFF, + 0x0067DB, 0x0067DC, 0x000000, 0xFFFFFF, + 0x0067DE, 0x0067E8, 0x000000, 0xFFFFFF, + 0x0067EA, 0x0067EB, 0x000000, 0xFFFFFF, + 0x0067ED, 0x0067EE, 0x000000, 0xFFFFFF, + 0x0067F2, 0x0067F2, 0x000000, 0xFFFFFF, + 0x0067F7, 0x0067FA, 0x000000, 0xFFFFFF, + 0x0067FC, 0x0067FD, 0x000000, 0xFFFFFF, + 0x0067FF, 0x006811, 0x000000, 0xFFFFFF, + 0x006814, 0x006815, 0x000000, 0xFFFFFF, + 0x006818, 0x006820, 0x000000, 0xFFFFFF, + 0x006823, 0x006829, 0x000000, 0xFFFFFF, + 0x00682B, 0x00682E, 0x000000, 0xFFFFFF, + 0x006830, 0x006837, 0x000000, 0xFFFFFF, + 0x00683A, 0x00683B, 0x000000, 0xFFFFFF, + 0x00683E, 0x00683F, 0x000000, 0xFFFFFF, + 0x006844, 0x006847, 0x000000, 0xFFFFFF, + 0x006849, 0x00684D, 0x000000, 0xFFFFFF, + 0x00684F, 0x00684F, 0x000000, 0xFFFFFF, + 0x006852, 0x006852, 0x000000, 0xFFFFFF, + 0x006855, 0x00686C, 0x000000, 0xFFFFFF, + 0x00686E, 0x006875, 0x000000, 0xFFFFFF, + 0x006877, 0x00687E, 0x000000, 0xFFFFFF, + 0x006880, 0x006880, 0x000000, 0xFFFFFF, + 0x006882, 0x006884, 0x000000, 0xFFFFFF, + 0x006886, 0x00688E, 0x000000, 0xFFFFFF, + 0x006890, 0x006892, 0x000000, 0xFFFFFF, + 0x006895, 0x006896, 0x000000, 0xFFFFFF, + 0x006898, 0x00689C, 0x000000, 0xFFFFFF, + 0x00689E, 0x00689E, 0x000000, 0xFFFFFF, + 0x0068A0, 0x0068A0, 0x000000, 0xFFFFFF, + 0x0068A3, 0x0068A6, 0x000000, 0xFFFFFF, + 0x0068A9, 0x0068AC, 0x000000, 0xFFFFFF, + 0x0068AE, 0x0068AE, 0x000000, 0xFFFFFF, + 0x0068B2, 0x0068B2, 0x000000, 0xFFFFFF, + 0x0068B4, 0x0068B4, 0x000000, 0xFFFFFF, + 0x0068B7, 0x0068C3, 0x000000, 0xFFFFFF, + 0x0068C6, 0x0068C8, 0x000000, 0xFFFFFF, + 0x0068CA, 0x0068CA, 0x000000, 0xFFFFFF, + 0x0068CC, 0x0068CC, 0x000000, 0xFFFFFF, + 0x0068CE, 0x0068D1, 0x000000, 0xFFFFFF, + 0x0068D3, 0x0068D4, 0x000000, 0xFFFFFF, + 0x0068D6, 0x0068D6, 0x000000, 0xFFFFFF, + 0x0068D9, 0x0068D9, 0x000000, 0xFFFFFF, + 0x0068DB, 0x0068DE, 0x000000, 0xFFFFFF, + 0x0068E1, 0x0068E6, 0x000000, 0xFFFFFF, + 0x0068E9, 0x0068ED, 0x000000, 0xFFFFFF, + 0x0068EF, 0x0068F1, 0x000000, 0xFFFFFF, + 0x0068F3, 0x0068F8, 0x000000, 0xFFFFFF, + 0x0068FB, 0x0068FF, 0x000000, 0xFFFFFF, + 0x006901, 0x006904, 0x000000, 0xFFFFFF, + 0x006906, 0x00690C, 0x000000, 0xFFFFFF, + 0x00690F, 0x006911, 0x000000, 0xFFFFFF, + 0x006913, 0x006926, 0x000000, 0xFFFFFF, + 0x006928, 0x00692F, 0x000000, 0xFFFFFF, + 0x006931, 0x00693C, 0x000000, 0xFFFFFF, + 0x00693E, 0x00693E, 0x000000, 0xFFFFFF, + 0x006940, 0x006949, 0x000000, 0xFFFFFF, + 0x00694B, 0x006952, 0x000000, 0xFFFFFF, + 0x006956, 0x006956, 0x000000, 0xFFFFFF, + 0x006958, 0x006958, 0x000000, 0xFFFFFF, + 0x00695B, 0x00695D, 0x000000, 0xFFFFFF, + 0x00695F, 0x00695F, 0x000000, 0xFFFFFF, + 0x006964, 0x006967, 0x000000, 0xFFFFFF, + 0x006969, 0x00696A, 0x000000, 0xFFFFFF, + 0x00696C, 0x00696C, 0x000000, 0xFFFFFF, + 0x006970, 0x006974, 0x000000, 0xFFFFFF, + 0x006976, 0x006976, 0x000000, 0xFFFFFF, + 0x00697A, 0x006994, 0x000000, 0xFFFFFF, + 0x006996, 0x00699A, 0x000000, 0xFFFFFF, + 0x00699D, 0x0069A4, 0x000000, 0xFFFFFF, + 0x0069A6, 0x0069A6, 0x000000, 0xFFFFFF, + 0x0069A8, 0x0069AD, 0x000000, 0xFFFFFF, + 0x0069AF, 0x0069B3, 0x000000, 0xFFFFFF, + 0x0069B5, 0x0069BA, 0x000000, 0xFFFFFF, + 0x0069BC, 0x0069C0, 0x000000, 0xFFFFFF, + 0x0069C2, 0x0069C2, 0x000000, 0xFFFFFF, + 0x0069C4, 0x0069CA, 0x000000, 0xFFFFFF, + 0x0069CE, 0x0069CF, 0x000000, 0xFFFFFF, + 0x0069D1, 0x0069E7, 0x000000, 0xFFFFFF, + 0x0069E9, 0x0069E9, 0x000000, 0xFFFFFF, + 0x0069EB, 0x0069FA, 0x000000, 0xFFFFFF, + 0x0069FC, 0x0069FC, 0x000000, 0xFFFFFF, + 0x0069FE, 0x0069FE, 0x000000, 0xFFFFFF, + 0x006A00, 0x006A01, 0x000000, 0xFFFFFF, + 0x006A03, 0x006A09, 0x000000, 0xFFFFFF, + 0x006A0B, 0x006A10, 0x000000, 0xFFFFFF, + 0x006A12, 0x006A12, 0x000000, 0xFFFFFF, + 0x006A14, 0x006A16, 0x000000, 0xFFFFFF, + 0x006A18, 0x006A18, 0x000000, 0xFFFFFF, + 0x006A1A, 0x006A1D, 0x000000, 0xFFFFFF, + 0x006A20, 0x006A20, 0x000000, 0xFFFFFF, + 0x006A22, 0x006A22, 0x000000, 0xFFFFFF, + 0x006A24, 0x006A34, 0x000000, 0xFFFFFF, + 0x006A36, 0x006A37, 0x000000, 0xFFFFFF, + 0x006A3B, 0x006A3C, 0x000000, 0xFFFFFF, + 0x006A3E, 0x006A43, 0x000000, 0xFFFFFF, + 0x006A45, 0x006A47, 0x000000, 0xFFFFFF, + 0x006A49, 0x006A4A, 0x000000, 0xFFFFFF, + 0x006A4C, 0x006A51, 0x000000, 0xFFFFFF, + 0x006A54, 0x006A57, 0x000000, 0xFFFFFF, + 0x006A5A, 0x006A5E, 0x000000, 0xFFFFFF, + 0x006A60, 0x006A60, 0x000000, 0xFFFFFF, + 0x006A62, 0x006A6A, 0x000000, 0xFFFFFF, + 0x006A6C, 0x006A7F, 0x000000, 0xFFFFFF, + 0x006A81, 0x006A83, 0x000000, 0xFFFFFF, + 0x006A85, 0x006A88, 0x000000, 0xFFFFFF, + 0x006A8A, 0x006A8C, 0x000000, 0xFFFFFF, + 0x006A8F, 0x006A96, 0x000000, 0xFFFFFF, + 0x006A98, 0x006A9B, 0x000000, 0xFFFFFF, + 0x006A9D, 0x006AA1, 0x000000, 0xFFFFFF, + 0x006AA4, 0x006AB2, 0x000000, 0xFFFFFF, + 0x006AB4, 0x006ABA, 0x000000, 0xFFFFFF, + 0x006ABC, 0x006AC1, 0x000000, 0xFFFFFF, + 0x006AC4, 0x006AD2, 0x000000, 0xFFFFFF, + 0x006AD4, 0x006AD9, 0x000000, 0xFFFFFF, + 0x006ADC, 0x006AF5, 0x000000, 0xFFFFFF, + 0x006AF7, 0x006AFA, 0x000000, 0xFFFFFF, + 0x006AFC, 0x006B03, 0x000000, 0xFFFFFF, + 0x006B05, 0x006B09, 0x000000, 0xFFFFFF, + 0x006B0B, 0x006B0B, 0x000000, 0xFFFFFF, + 0x006B0D, 0x006B11, 0x000000, 0xFFFFFF, + 0x006B13, 0x006B15, 0x000000, 0xFFFFFF, + 0x006B17, 0x006B1F, 0x000000, 0xFFFFFF, + 0x006B22, 0x006B22, 0x000000, 0xFFFFFF, + 0x006B24, 0x006B31, 0x000000, 0xFFFFFF, + 0x006B33, 0x006B39, 0x000000, 0xFFFFFF, + 0x006B3B, 0x006B3C, 0x000000, 0xFFFFFF, + 0x006B3F, 0x006B45, 0x000000, 0xFFFFFF, + 0x006B48, 0x006B4B, 0x000000, 0xFFFFFF, + 0x006B4D, 0x006B4D, 0x000000, 0xFFFFFF, + 0x006B4F, 0x006B4F, 0x000000, 0xFFFFFF, + 0x006B51, 0x006B5E, 0x000000, 0xFFFFFF, + 0x006B60, 0x006B60, 0x000000, 0xFFFFFF, + 0x006B67, 0x006B69, 0x000000, 0xFFFFFF, + 0x006B6B, 0x006B71, 0x000000, 0xFFFFFF, + 0x006B73, 0x006B76, 0x000000, 0xFFFFFF, + 0x006B79, 0x006B7A, 0x000000, 0xFFFFFF, + 0x006B7C, 0x006B7E, 0x000000, 0xFFFFFF, + 0x006B80, 0x006B82, 0x000000, 0xFFFFFF, + 0x006B85, 0x006B85, 0x000000, 0xFFFFFF, + 0x006B87, 0x006B88, 0x000000, 0xFFFFFF, + 0x006B8B, 0x006B95, 0x000000, 0xFFFFFF, + 0x006B97, 0x006B97, 0x000000, 0xFFFFFF, + 0x006B99, 0x006B9D, 0x000000, 0xFFFFFF, + 0x006B9F, 0x006BAD, 0x000000, 0xFFFFFF, + 0x006BB0, 0x006BB1, 0x000000, 0xFFFFFF, + 0x006BB3, 0x006BB4, 0x000000, 0xFFFFFF, + 0x006BB6, 0x006BB6, 0x000000, 0xFFFFFF, + 0x006BB8, 0x006BB9, 0x000000, 0xFFFFFF, + 0x006BBB, 0x006BBB, 0x000000, 0xFFFFFF, + 0x006BBD, 0x006BBE, 0x000000, 0xFFFFFF, + 0x006BC0, 0x006BC0, 0x000000, 0xFFFFFF, + 0x006BC2, 0x006BC4, 0x000000, 0xFFFFFF, + 0x006BC7, 0x006BCA, 0x000000, 0xFFFFFF, + 0x006BCC, 0x006BCC, 0x000000, 0xFFFFFF, + 0x006BCE, 0x006BCE, 0x000000, 0xFFFFFF, + 0x006BD0, 0x006BD1, 0x000000, 0xFFFFFF, + 0x006BD5, 0x006BD5, 0x000000, 0xFFFFFF, + 0x006BD9, 0x006BDA, 0x000000, 0xFFFFFF, + 0x006BDC, 0x006BEA, 0x000000, 0xFFFFFF, + 0x006BED, 0x006C07, 0x000000, 0xFFFFFF, + 0x006C09, 0x006C0E, 0x000000, 0xFFFFFF, + 0x006C10, 0x006C10, 0x000000, 0xFFFFFF, + 0x006C12, 0x006C12, 0x000000, 0xFFFFFF, + 0x006C14, 0x006C22, 0x000000, 0xFFFFFF, + 0x006C24, 0x006C33, 0x000000, 0xFFFFFF, + 0x006C35, 0x006C36, 0x000000, 0xFFFFFF, + 0x006C39, 0x006C3D, 0x000000, 0xFFFFFF, + 0x006C3F, 0x006C3F, 0x000000, 0xFFFFFF, + 0x006C43, 0x006C4D, 0x000000, 0xFFFFFF, + 0x006C4F, 0x006C4F, 0x000000, 0xFFFFFF, + 0x006C51, 0x006C54, 0x000000, 0xFFFFFF, + 0x006C56, 0x006C56, 0x000000, 0xFFFFFF, + 0x006C58, 0x006C59, 0x000000, 0xFFFFFF, + 0x006C5B, 0x006C5C, 0x000000, 0xFFFFFF, + 0x006C61, 0x006C67, 0x000000, 0xFFFFFF, + 0x006C69, 0x006C69, 0x000000, 0xFFFFFF, + 0x006C6B, 0x006C6C, 0x000000, 0xFFFFFF, + 0x006C6E, 0x006C6F, 0x000000, 0xFFFFFF, + 0x006C71, 0x006C71, 0x000000, 0xFFFFFF, + 0x006C73, 0x006C75, 0x000000, 0xFFFFFF, + 0x006C77, 0x006C79, 0x000000, 0xFFFFFF, + 0x006C7B, 0x006C7C, 0x000000, 0xFFFFFF, + 0x006C7F, 0x006C80, 0x000000, 0xFFFFFF, + 0x006C84, 0x006C84, 0x000000, 0xFFFFFF, + 0x006C89, 0x006C8B, 0x000000, 0xFFFFFF, + 0x006C8D, 0x006C8F, 0x000000, 0xFFFFFF, + 0x006C91, 0x006C91, 0x000000, 0xFFFFFF, + 0x006C97, 0x006C98, 0x000000, 0xFFFFFF, + 0x006C9C, 0x006CAA, 0x000000, 0xFFFFFF, + 0x006CAC, 0x006CAD, 0x000000, 0xFFFFFF, + 0x006CAF, 0x006CB2, 0x000000, 0xFFFFFF, + 0x006CB4, 0x006CB7, 0x000000, 0xFFFFFF, + 0x006CBA, 0x006CBA, 0x000000, 0xFFFFFF, + 0x006CC0, 0x006CC0, 0x000000, 0xFFFFFF, + 0x006CC3, 0x006CC3, 0x000000, 0xFFFFFF, + 0x006CC5, 0x006CC8, 0x000000, 0xFFFFFF, + 0x006CCB, 0x006CCB, 0x000000, 0xFFFFFF, + 0x006CCD, 0x006CD2, 0x000000, 0xFFFFFF, + 0x006CD4, 0x006CD4, 0x000000, 0xFFFFFF, + 0x006CD6, 0x006CD6, 0x000000, 0xFFFFFF, + 0x006CD8, 0x006CDA, 0x000000, 0xFFFFFF, + 0x006CDC, 0x006CE0, 0x000000, 0xFFFFFF, + 0x006CE4, 0x006CE4, 0x000000, 0xFFFFFF, + 0x006CE6, 0x006CE7, 0x000000, 0xFFFFFF, + 0x006CE9, 0x006CEA, 0x000000, 0xFFFFFF, + 0x006CEC, 0x006CED, 0x000000, 0xFFFFFF, + 0x006CF1, 0x006CF2, 0x000000, 0xFFFFFF, + 0x006CF4, 0x006D0A, 0x000000, 0xFFFFFF, + 0x006D0D, 0x006D10, 0x000000, 0xFFFFFF, + 0x006D12, 0x006D16, 0x000000, 0xFFFFFF, + 0x006D18, 0x006D18, 0x000000, 0xFFFFFF, + 0x006D1A, 0x006D1A, 0x000000, 0xFFFFFF, + 0x006D1C, 0x006D1D, 0x000000, 0xFFFFFF, + 0x006D1F, 0x006D24, 0x000000, 0xFFFFFF, + 0x006D26, 0x006D26, 0x000000, 0xFFFFFF, + 0x006D28, 0x006D28, 0x000000, 0xFFFFFF, + 0x006D2B, 0x006D31, 0x000000, 0xFFFFFF, + 0x006D33, 0x006D34, 0x000000, 0xFFFFFF, + 0x006D37, 0x006D37, 0x000000, 0xFFFFFF, + 0x006D3A, 0x006D3A, 0x000000, 0xFFFFFF, + 0x006D3C, 0x006D3C, 0x000000, 0xFFFFFF, + 0x006D3F, 0x006D40, 0x000000, 0xFFFFFF, + 0x006D42, 0x006D58, 0x000000, 0xFFFFFF, + 0x006D5B, 0x006D5B, 0x000000, 0xFFFFFF, + 0x006D5D, 0x006D62, 0x000000, 0xFFFFFF, + 0x006D64, 0x006D65, 0x000000, 0xFFFFFF, + 0x006D67, 0x006D68, 0x000000, 0xFFFFFF, + 0x006D6B, 0x006D6B, 0x000000, 0xFFFFFF, + 0x006D6D, 0x006D6D, 0x000000, 0xFFFFFF, + 0x006D6F, 0x006D73, 0x000000, 0xFFFFFF, + 0x006D75, 0x006D76, 0x000000, 0xFFFFFF, + 0x006D7A, 0x006D7E, 0x000000, 0xFFFFFF, + 0x006D80, 0x006D84, 0x000000, 0xFFFFFF, + 0x006D86, 0x006D86, 0x000000, 0xFFFFFF, + 0x006D8A, 0x006D8B, 0x000000, 0xFFFFFF, + 0x006D8F, 0x006D90, 0x000000, 0xFFFFFF, + 0x006D92, 0x006D92, 0x000000, 0xFFFFFF, + 0x006D94, 0x006D94, 0x000000, 0xFFFFFF, + 0x006D96, 0x006DAE, 0x000000, 0xFFFFFF, + 0x006DB0, 0x006DB1, 0x000000, 0xFFFFFF, + 0x006DB3, 0x006DB4, 0x000000, 0xFFFFFF, + 0x006DB6, 0x006DBF, 0x000000, 0xFFFFFF, + 0x006DC1, 0x006DC2, 0x000000, 0xFFFFFF, + 0x006DC8, 0x006DCA, 0x000000, 0xFFFFFF, + 0x006DCC, 0x006DCE, 0x000000, 0xFFFFFF, + 0x006DD0, 0x006DD0, 0x000000, 0xFFFFFF, + 0x006DD2, 0x006DD7, 0x000000, 0xFFFFFF, + 0x006DDB, 0x006DDD, 0x000000, 0xFFFFFF, + 0x006DDF, 0x006DE0, 0x000000, 0xFFFFFF, + 0x006DE2, 0x006DE7, 0x000000, 0xFFFFFF, + 0x006DE9, 0x006DE9, 0x000000, 0xFFFFFF, + 0x006DEC, 0x006DED, 0x000000, 0xFFFFFF, + 0x006DEF, 0x006DF0, 0x000000, 0xFFFFFF, + 0x006DF2, 0x006DF2, 0x000000, 0xFFFFFF, + 0x006DF4, 0x006DF4, 0x000000, 0xFFFFFF, + 0x006DF6, 0x006DF6, 0x000000, 0xFFFFFF, + 0x006DFC, 0x006E16, 0x000000, 0xFFFFFF, + 0x006E18, 0x006E18, 0x000000, 0xFFFFFF, + 0x006E1C, 0x006E1E, 0x000000, 0xFFFFFF, + 0x006E22, 0x006E22, 0x000000, 0xFFFFFF, + 0x006E27, 0x006E2A, 0x000000, 0xFFFFFF, + 0x006E2E, 0x006E2E, 0x000000, 0xFFFFFF, + 0x006E30, 0x006E31, 0x000000, 0xFFFFFF, + 0x006E33, 0x006E33, 0x000000, 0xFFFFFF, + 0x006E35, 0x006E35, 0x000000, 0xFFFFFF, + 0x006E37, 0x006E37, 0x000000, 0xFFFFFF, + 0x006E39, 0x006E39, 0x000000, 0xFFFFFF, + 0x006E3B, 0x006E3B, 0x000000, 0xFFFFFF, + 0x006E3F, 0x006E42, 0x000000, 0xFFFFFF, + 0x006E45, 0x006E49, 0x000000, 0xFFFFFF, + 0x006E4B, 0x006E4C, 0x000000, 0xFFFFFF, + 0x006E4E, 0x006E55, 0x000000, 0xFFFFFF, + 0x006E57, 0x006E57, 0x000000, 0xFFFFFF, + 0x006E59, 0x006E5A, 0x000000, 0xFFFFFF, + 0x006E5D, 0x006E5D, 0x000000, 0xFFFFFF, + 0x006E60, 0x006E66, 0x000000, 0xFFFFFF, + 0x006E68, 0x006E6A, 0x000000, 0xFFFFFF, + 0x006E6C, 0x006E6D, 0x000000, 0xFFFFFF, + 0x006E70, 0x006E71, 0x000000, 0xFFFFFF, + 0x006E74, 0x006E79, 0x000000, 0xFFFFFF, + 0x006E7B, 0x006E8F, 0x000000, 0xFFFFFF, + 0x006E91, 0x006E95, 0x000000, 0xFFFFFF, + 0x006E97, 0x006E9B, 0x000000, 0xFFFFFF, + 0x006E9E, 0x006E9E, 0x000000, 0xFFFFFF, + 0x006EA0, 0x006EA1, 0x000000, 0xFFFFFF, + 0x006EA3, 0x006EA4, 0x000000, 0xFFFFFF, + 0x006EA6, 0x006EA9, 0x000000, 0xFFFFFF, + 0x006EAC, 0x006EAE, 0x000000, 0xFFFFFF, + 0x006EB0, 0x006EB0, 0x000000, 0xFFFFFF, + 0x006EB2, 0x006EB5, 0x000000, 0xFFFFFF, + 0x006EB7, 0x006EB9, 0x000000, 0xFFFFFF, + 0x006EBB, 0x006EC1, 0x000000, 0xFFFFFF, + 0x006EC3, 0x006EC3, 0x000000, 0xFFFFFF, + 0x006EC6, 0x006EC8, 0x000000, 0xFFFFFF, + 0x006ECA, 0x006ECA, 0x000000, 0xFFFFFF, + 0x006ECD, 0x006ECD, 0x000000, 0xFFFFFF, + 0x006ECF, 0x006ED0, 0x000000, 0xFFFFFF, + 0x006ED2, 0x006ED2, 0x000000, 0xFFFFFF, + 0x006ED5, 0x006EEE, 0x000000, 0xFFFFFF, + 0x006EF0, 0x006EF3, 0x000000, 0xFFFFFF, + 0x006EF5, 0x006EF7, 0x000000, 0xFFFFFF, + 0x006EF9, 0x006EFD, 0x000000, 0xFFFFFF, + 0x006F00, 0x006F00, 0x000000, 0xFFFFFF, + 0x006F03, 0x006F05, 0x000000, 0xFFFFFF, + 0x006F07, 0x006F0E, 0x000000, 0xFFFFFF, + 0x006F10, 0x006F10, 0x000000, 0xFFFFFF, + 0x006F12, 0x006F13, 0x000000, 0xFFFFFF, + 0x006F16, 0x006F1F, 0x000000, 0xFFFFFF, + 0x006F21, 0x006F21, 0x000000, 0xFFFFFF, + 0x006F24, 0x006F2A, 0x000000, 0xFFFFFF, + 0x006F2D, 0x006F30, 0x000000, 0xFFFFFF, + 0x006F33, 0x006F37, 0x000000, 0xFFFFFF, + 0x006F39, 0x006F3E, 0x000000, 0xFFFFFF, + 0x006F40, 0x006F40, 0x000000, 0xFFFFFF, + 0x006F42, 0x006F50, 0x000000, 0xFFFFFF, + 0x006F52, 0x006F53, 0x000000, 0xFFFFFF, + 0x006F55, 0x006F56, 0x000000, 0xFFFFFF, + 0x006F59, 0x006F59, 0x000000, 0xFFFFFF, + 0x006F5C, 0x006F5D, 0x000000, 0xFFFFFF, + 0x006F60, 0x006F61, 0x000000, 0xFFFFFF, + 0x006F63, 0x006F63, 0x000000, 0xFFFFFF, + 0x006F65, 0x006F6C, 0x000000, 0xFFFFFF, + 0x006F6F, 0x006F6F, 0x000000, 0xFFFFFF, + 0x006F71, 0x006F79, 0x000000, 0xFFFFFF, + 0x006F7B, 0x006F7B, 0x000000, 0xFFFFFF, + 0x006F7F, 0x006F80, 0x000000, 0xFFFFFF, + 0x006F82, 0x006F83, 0x000000, 0xFFFFFF, + 0x006F85, 0x006F87, 0x000000, 0xFFFFFF, + 0x006F89, 0x006F8C, 0x000000, 0xFFFFFF, + 0x006F8F, 0x006F8F, 0x000000, 0xFFFFFF, + 0x006F91, 0x006F93, 0x000000, 0xFFFFFF, + 0x006F95, 0x006F96, 0x000000, 0xFFFFFF, + 0x006F98, 0x006FA2, 0x000000, 0xFFFFFF, + 0x006FA5, 0x006FA6, 0x000000, 0xFFFFFF, + 0x006FA8, 0x006FAD, 0x000000, 0xFFFFFF, + 0x006FB0, 0x006FB0, 0x000000, 0xFFFFFF, + 0x006FB2, 0x006FB2, 0x000000, 0xFFFFFF, + 0x006FB4, 0x006FB8, 0x000000, 0xFFFFFF, + 0x006FBA, 0x006FBD, 0x000000, 0xFFFFFF, + 0x006FBF, 0x006FBF, 0x000000, 0xFFFFFF, + 0x006FC4, 0x006FC9, 0x000000, 0xFFFFFF, + 0x006FCB, 0x006FD4, 0x000000, 0xFFFFFF, + 0x006FD6, 0x006FD9, 0x000000, 0xFFFFFF, + 0x006FDB, 0x006FDE, 0x000000, 0xFFFFFF, + 0x006FE2, 0x006FE3, 0x000000, 0xFFFFFF, + 0x006FE5, 0x006FE8, 0x000000, 0xFFFFFF, + 0x006FEA, 0x006FEA, 0x000000, 0xFFFFFF, + 0x006FED, 0x006FEE, 0x000000, 0xFFFFFF, + 0x006FF0, 0x006FF0, 0x000000, 0xFFFFFF, + 0x006FF2, 0x006FFD, 0x000000, 0xFFFFFF, + 0x006FFF, 0x007000, 0x000000, 0xFFFFFF, + 0x007002, 0x007004, 0x000000, 0xFFFFFF, + 0x007007, 0x007008, 0x000000, 0xFFFFFF, + 0x00700A, 0x00700A, 0x000000, 0xFFFFFF, + 0x00700C, 0x00700E, 0x000000, 0xFFFFFF, + 0x007010, 0x007010, 0x000000, 0xFFFFFF, + 0x007012, 0x007014, 0x000000, 0xFFFFFF, + 0x007016, 0x007017, 0x000000, 0xFFFFFF, + 0x007019, 0x007019, 0x000000, 0xFFFFFF, + 0x007020, 0x007022, 0x000000, 0xFFFFFF, + 0x007024, 0x007026, 0x000000, 0xFFFFFF, + 0x007029, 0x00702E, 0x000000, 0xFFFFFF, + 0x007030, 0x007036, 0x000000, 0xFFFFFF, + 0x007038, 0x00703D, 0x000000, 0xFFFFFF, + 0x00703F, 0x00704B, 0x000000, 0xFFFFFF, + 0x00704D, 0x00704F, 0x000000, 0xFFFFFF, + 0x007052, 0x007057, 0x000000, 0xFFFFFF, + 0x007059, 0x00705C, 0x000000, 0xFFFFFF, + 0x00705E, 0x007062, 0x000000, 0xFFFFFF, + 0x007064, 0x00706A, 0x000000, 0xFFFFFF, + 0x00706C, 0x00706F, 0x000000, 0xFFFFFF, + 0x007071, 0x007077, 0x000000, 0xFFFFFF, + 0x007079, 0x00707B, 0x000000, 0xFFFFFF, + 0x00707E, 0x007084, 0x000000, 0xFFFFFF, + 0x007086, 0x007089, 0x000000, 0xFFFFFF, + 0x00708B, 0x00708D, 0x000000, 0xFFFFFF, + 0x00708F, 0x007091, 0x000000, 0xFFFFFF, + 0x007093, 0x007097, 0x000000, 0xFFFFFF, + 0x00709B, 0x0070A0, 0x000000, 0xFFFFFF, + 0x0070A2, 0x0070A3, 0x000000, 0xFFFFFF, + 0x0070A5, 0x0070AA, 0x000000, 0xFFFFFF, + 0x0070AE, 0x0070AE, 0x000000, 0xFFFFFF, + 0x0070B0, 0x0070B2, 0x000000, 0xFFFFFF, + 0x0070B4, 0x0070B6, 0x000000, 0xFFFFFF, + 0x0070BA, 0x0070C7, 0x000000, 0xFFFFFF, + 0x0070C9, 0x0070CA, 0x000000, 0xFFFFFF, + 0x0070CC, 0x0070CE, 0x000000, 0xFFFFFF, + 0x0070D0, 0x0070D7, 0x000000, 0xFFFFFF, + 0x0070DA, 0x0070DC, 0x000000, 0xFFFFFF, + 0x0070DE, 0x0070DE, 0x000000, 0xFFFFFF, + 0x0070E0, 0x0070F0, 0x000000, 0xFFFFFF, + 0x0070F2, 0x0070F8, 0x000000, 0xFFFFFF, + 0x0070FA, 0x0070FC, 0x000000, 0xFFFFFF, + 0x0070FE, 0x007103, 0x000000, 0xFFFFFF, + 0x007105, 0x007108, 0x000000, 0xFFFFFF, + 0x00710A, 0x00710B, 0x000000, 0xFFFFFF, + 0x00710D, 0x007118, 0x000000, 0xFFFFFF, + 0x00711B, 0x00711D, 0x000000, 0xFFFFFF, + 0x00711F, 0x007120, 0x000000, 0xFFFFFF, + 0x007122, 0x007125, 0x000000, 0xFFFFFF, + 0x007127, 0x00712F, 0x000000, 0xFFFFFF, + 0x007131, 0x007135, 0x000000, 0xFFFFFF, + 0x007137, 0x007146, 0x000000, 0xFFFFFF, + 0x007148, 0x007148, 0x000000, 0xFFFFFF, + 0x00714B, 0x00714B, 0x000000, 0xFFFFFF, + 0x00714D, 0x00714D, 0x000000, 0xFFFFFF, + 0x00714F, 0x00714F, 0x000000, 0xFFFFFF, + 0x007151, 0x007155, 0x000000, 0xFFFFFF, + 0x007157, 0x007158, 0x000000, 0xFFFFFF, + 0x00715A, 0x00715B, 0x000000, 0xFFFFFF, + 0x00715D, 0x00715D, 0x000000, 0xFFFFFF, + 0x00715F, 0x007163, 0x000000, 0xFFFFFF, + 0x007168, 0x007168, 0x000000, 0xFFFFFF, + 0x00716A, 0x00716B, 0x000000, 0xFFFFFF, + 0x00716D, 0x00716D, 0x000000, 0xFFFFFF, + 0x00716F, 0x00717C, 0x000000, 0xFFFFFF, + 0x00717E, 0x007183, 0x000000, 0xFFFFFF, + 0x007185, 0x007188, 0x000000, 0xFFFFFF, + 0x00718B, 0x00718E, 0x000000, 0xFFFFFF, + 0x007190, 0x007191, 0x000000, 0xFFFFFF, + 0x007193, 0x007193, 0x000000, 0xFFFFFF, + 0x007195, 0x007198, 0x000000, 0xFFFFFF, + 0x00719A, 0x00719E, 0x000000, 0xFFFFFF, + 0x0071A0, 0x0071A1, 0x000000, 0xFFFFFF, + 0x0071A3, 0x0071AB, 0x000000, 0xFFFFFF, + 0x0071AD, 0x0071B0, 0x000000, 0xFFFFFF, + 0x0071B2, 0x0071B8, 0x000000, 0xFFFFFF, + 0x0071BB, 0x0071BD, 0x000000, 0xFFFFFF, + 0x0071BF, 0x0071C0, 0x000000, 0xFFFFFF, + 0x0071C2, 0x0071C2, 0x000000, 0xFFFFFF, + 0x0071C4, 0x0071C7, 0x000000, 0xFFFFFF, + 0x0071CA, 0x0071CD, 0x000000, 0xFFFFFF, + 0x0071CF, 0x0071CF, 0x000000, 0xFFFFFF, + 0x0071D1, 0x0071D1, 0x000000, 0xFFFFFF, + 0x0071D3, 0x0071D3, 0x000000, 0xFFFFFF, + 0x0071D6, 0x0071DE, 0x000000, 0xFFFFFF, + 0x0071E0, 0x0071E4, 0x000000, 0xFFFFFF, + 0x0071E8, 0x0071EC, 0x000000, 0xFFFFFF, + 0x0071EF, 0x0071FA, 0x000000, 0xFFFFFF, + 0x0071FD, 0x0071FD, 0x000000, 0xFFFFFF, + 0x007201, 0x007205, 0x000000, 0xFFFFFF, + 0x007207, 0x00720F, 0x000000, 0xFFFFFF, + 0x007211, 0x00721A, 0x000000, 0xFFFFFF, + 0x00721C, 0x007229, 0x000000, 0xFFFFFF, + 0x00722B, 0x00722B, 0x000000, 0xFFFFFF, + 0x00722E, 0x00722F, 0x000000, 0xFFFFFF, + 0x007231, 0x007231, 0x000000, 0xFFFFFF, + 0x007233, 0x007234, 0x000000, 0xFFFFFF, + 0x007237, 0x007239, 0x000000, 0xFFFFFF, + 0x00723C, 0x00723C, 0x000000, 0xFFFFFF, + 0x00723F, 0x00723F, 0x000000, 0xFFFFFF, + 0x007241, 0x007245, 0x000000, 0xFFFFFF, + 0x007249, 0x00724B, 0x000000, 0xFFFFFF, + 0x00724D, 0x007251, 0x000000, 0xFFFFFF, + 0x007253, 0x007257, 0x000000, 0xFFFFFF, + 0x00725A, 0x00725A, 0x000000, 0xFFFFFF, + 0x00725C, 0x00725C, 0x000000, 0xFFFFFF, + 0x00725E, 0x00725E, 0x000000, 0xFFFFFF, + 0x007260, 0x007260, 0x000000, 0xFFFFFF, + 0x007263, 0x007266, 0x000000, 0xFFFFFF, + 0x007268, 0x007268, 0x000000, 0xFFFFFF, + 0x00726A, 0x007271, 0x000000, 0xFFFFFF, + 0x007273, 0x007278, 0x000000, 0xFFFFFF, + 0x00727A, 0x00727C, 0x000000, 0xFFFFFF, + 0x00727E, 0x00727F, 0x000000, 0xFFFFFF, + 0x007282, 0x0072A1, 0x000000, 0xFFFFFF, + 0x0072A3, 0x0072A6, 0x000000, 0xFFFFFF, + 0x0072A8, 0x0072AB, 0x000000, 0xFFFFFF, + 0x0072AD, 0x0072AE, 0x000000, 0xFFFFFF, + 0x0072B0, 0x0072BF, 0x000000, 0xFFFFFF, + 0x0072C1, 0x0072C1, 0x000000, 0xFFFFFF, + 0x0072C3, 0x0072C3, 0x000000, 0xFFFFFF, + 0x0072C5, 0x0072CD, 0x000000, 0xFFFFFF, + 0x0072CF, 0x0072CF, 0x000000, 0xFFFFFF, + 0x0072D1, 0x0072D6, 0x000000, 0xFFFFFF, + 0x0072D8, 0x0072D8, 0x000000, 0xFFFFFF, + 0x0072DA, 0x0072E0, 0x000000, 0xFFFFFF, + 0x0072E2, 0x0072E8, 0x000000, 0xFFFFFF, + 0x0072EA, 0x0072F7, 0x000000, 0xFFFFFF, + 0x0072FA, 0x0072FB, 0x000000, 0xFFFFFF, + 0x0072FE, 0x007309, 0x000000, 0xFFFFFF, + 0x00730B, 0x007315, 0x000000, 0xFFFFFF, + 0x007317, 0x00731A, 0x000000, 0xFFFFFF, + 0x00731E, 0x007324, 0x000000, 0xFFFFFF, + 0x007326, 0x007328, 0x000000, 0xFFFFFF, + 0x00732C, 0x007335, 0x000000, 0xFFFFFF, + 0x007338, 0x00733D, 0x000000, 0xFFFFFF, + 0x007340, 0x007343, 0x000000, 0xFFFFFF, + 0x007346, 0x00734F, 0x000000, 0xFFFFFF, + 0x007351, 0x007351, 0x000000, 0xFFFFFF, + 0x007353, 0x007356, 0x000000, 0xFFFFFF, + 0x007358, 0x007367, 0x000000, 0xFFFFFF, + 0x007369, 0x007369, 0x000000, 0xFFFFFF, + 0x00736B, 0x00736F, 0x000000, 0xFFFFFF, + 0x007371, 0x007371, 0x000000, 0xFFFFFF, + 0x007373, 0x007374, 0x000000, 0xFFFFFF, + 0x007376, 0x007377, 0x000000, 0xFFFFFF, + 0x007379, 0x007379, 0x000000, 0xFFFFFF, + 0x00737C, 0x007383, 0x000000, 0xFFFFFF, + 0x007385, 0x007385, 0x000000, 0xFFFFFF, + 0x007388, 0x007388, 0x000000, 0xFFFFFF, + 0x00738A, 0x00738A, 0x000000, 0xFFFFFF, + 0x00738C, 0x00738D, 0x000000, 0xFFFFFF, + 0x00738F, 0x007393, 0x000000, 0xFFFFFF, + 0x007395, 0x007395, 0x000000, 0xFFFFFF, + 0x007399, 0x00739E, 0x000000, 0xFFFFFF, + 0x0073A0, 0x0073A6, 0x000000, 0xFFFFFF, + 0x0073A8, 0x0073A8, 0x000000, 0xFFFFFF, + 0x0073AA, 0x0073AC, 0x000000, 0xFFFFFF, + 0x0073AE, 0x0073B1, 0x000000, 0xFFFFFF, + 0x0073B4, 0x0073B8, 0x000000, 0xFFFFFF, + 0x0073BA, 0x0073BF, 0x000000, 0xFFFFFF, + 0x0073C1, 0x0073C1, 0x000000, 0xFFFFFF, + 0x0073C3, 0x0073C8, 0x000000, 0xFFFFFF, + 0x0073CB, 0x0073CB, 0x000000, 0xFFFFFF, + 0x0073CE, 0x0073CE, 0x000000, 0xFFFFFF, + 0x0073D0, 0x0073D5, 0x000000, 0xFFFFFF, + 0x0073D7, 0x0073D8, 0x000000, 0xFFFFFF, + 0x0073DA, 0x0073DC, 0x000000, 0xFFFFFF, + 0x0073DF, 0x0073DF, 0x000000, 0xFFFFFF, + 0x0073E1, 0x0073E2, 0x000000, 0xFFFFFF, + 0x0073E7, 0x0073E8, 0x000000, 0xFFFFFF, + 0x0073EB, 0x0073EC, 0x000000, 0xFFFFFF, + 0x0073EE, 0x0073F6, 0x000000, 0xFFFFFF, + 0x0073F8, 0x0073F8, 0x000000, 0xFFFFFF, + 0x0073FA, 0x0073FC, 0x000000, 0xFFFFFF, + 0x0073FF, 0x007400, 0x000000, 0xFFFFFF, + 0x007402, 0x007402, 0x000000, 0xFFFFFF, + 0x007404, 0x007404, 0x000000, 0xFFFFFF, + 0x007408, 0x007408, 0x000000, 0xFFFFFF, + 0x00740A, 0x007412, 0x000000, 0xFFFFFF, + 0x007414, 0x00741A, 0x000000, 0xFFFFFF, + 0x00741C, 0x00741F, 0x000000, 0xFFFFFF, + 0x007423, 0x007424, 0x000000, 0xFFFFFF, + 0x007427, 0x007427, 0x000000, 0xFFFFFF, + 0x007429, 0x007429, 0x000000, 0xFFFFFF, + 0x00742D, 0x00742D, 0x000000, 0xFFFFFF, + 0x007431, 0x007432, 0x000000, 0xFFFFFF, + 0x007437, 0x007437, 0x000000, 0xFFFFFF, + 0x007439, 0x007439, 0x000000, 0xFFFFFF, + 0x00743B, 0x00743E, 0x000000, 0xFFFFFF, + 0x007442, 0x007442, 0x000000, 0xFFFFFF, + 0x007445, 0x00744A, 0x000000, 0xFFFFFF, + 0x00744C, 0x007454, 0x000000, 0xFFFFFF, + 0x007456, 0x007456, 0x000000, 0xFFFFFF, + 0x007458, 0x007458, 0x000000, 0xFFFFFF, + 0x00745D, 0x00745D, 0x000000, 0xFFFFFF, + 0x007461, 0x007461, 0x000000, 0xFFFFFF, + 0x007463, 0x007463, 0x000000, 0xFFFFFF, + 0x007466, 0x007467, 0x000000, 0xFFFFFF, + 0x00746B, 0x00746E, 0x000000, 0xFFFFFF, + 0x007470, 0x00747D, 0x000000, 0xFFFFFF, + 0x00747F, 0x007481, 0x000000, 0xFFFFFF, + 0x007484, 0x007486, 0x000000, 0xFFFFFF, + 0x007488, 0x007488, 0x000000, 0xFFFFFF, + 0x00748A, 0x00748A, 0x000000, 0xFFFFFF, + 0x00748C, 0x007497, 0x000000, 0xFFFFFF, + 0x007499, 0x00749B, 0x000000, 0xFFFFFF, + 0x00749D, 0x00749D, 0x000000, 0xFFFFFF, + 0x0074A0, 0x0074A0, 0x000000, 0xFFFFFF, + 0x0074A2, 0x0074A2, 0x000000, 0xFFFFFF, + 0x0074A4, 0x0074A4, 0x000000, 0xFFFFFF, + 0x0074A6, 0x0074A6, 0x000000, 0xFFFFFF, + 0x0074A9, 0x0074A9, 0x000000, 0xFFFFFF, + 0x0074AB, 0x0074AF, 0x000000, 0xFFFFFF, + 0x0074B1, 0x0074B1, 0x000000, 0xFFFFFF, + 0x0074B3, 0x0074B4, 0x000000, 0xFFFFFF, + 0x0074B6, 0x0074B8, 0x000000, 0xFFFFFF, + 0x0074BA, 0x0074BC, 0x000000, 0xFFFFFF, + 0x0074BE, 0x0074BE, 0x000000, 0xFFFFFF, + 0x0074C0, 0x0074C5, 0x000000, 0xFFFFFF, + 0x0074C7, 0x0074C9, 0x000000, 0xFFFFFF, + 0x0074CB, 0x0074CE, 0x000000, 0xFFFFFF, + 0x0074D0, 0x0074D3, 0x000000, 0xFFFFFF, + 0x0074D5, 0x0074D7, 0x000000, 0xFFFFFF, + 0x0074D9, 0x0074D9, 0x000000, 0xFFFFFF, + 0x0074DB, 0x0074DB, 0x000000, 0xFFFFFF, + 0x0074DD, 0x0074DF, 0x000000, 0xFFFFFF, + 0x0074E1, 0x0074E1, 0x000000, 0xFFFFFF, + 0x0074E4, 0x0074E5, 0x000000, 0xFFFFFF, + 0x0074E7, 0x0074ED, 0x000000, 0xFFFFFF, + 0x0074EF, 0x0074F6, 0x000000, 0xFFFFFF, + 0x0074F8, 0x007500, 0x000000, 0xFFFFFF, + 0x007502, 0x007503, 0x000000, 0xFFFFFF, + 0x007505, 0x007510, 0x000000, 0xFFFFFF, + 0x007512, 0x007514, 0x000000, 0xFFFFFF, + 0x007516, 0x007517, 0x000000, 0xFFFFFF, + 0x007519, 0x007519, 0x000000, 0xFFFFFF, + 0x00751C, 0x00751E, 0x000000, 0xFFFFFF, + 0x007520, 0x007522, 0x000000, 0xFFFFFF, + 0x007524, 0x007524, 0x000000, 0xFFFFFF, + 0x007527, 0x007527, 0x000000, 0xFFFFFF, + 0x007529, 0x00752A, 0x000000, 0xFFFFFF, + 0x00752D, 0x00752F, 0x000000, 0xFFFFFF, + 0x007534, 0x007536, 0x000000, 0xFFFFFF, + 0x007539, 0x007539, 0x000000, 0xFFFFFF, + 0x00753B, 0x007546, 0x000000, 0xFFFFFF, + 0x007548, 0x00754B, 0x000000, 0xFFFFFF, + 0x00754D, 0x00754E, 0x000000, 0xFFFFFF, + 0x007550, 0x007550, 0x000000, 0xFFFFFF, + 0x007552, 0x007552, 0x000000, 0xFFFFFF, + 0x007555, 0x007558, 0x000000, 0xFFFFFF, + 0x00755A, 0x00755A, 0x000000, 0xFFFFFF, + 0x00755E, 0x007561, 0x000000, 0xFFFFFF, + 0x007563, 0x007564, 0x000000, 0xFFFFFF, + 0x007567, 0x007569, 0x000000, 0xFFFFFF, + 0x00756B, 0x00756E, 0x000000, 0xFFFFFF, + 0x007571, 0x007574, 0x000000, 0xFFFFFF, + 0x007577, 0x007577, 0x000000, 0xFFFFFF, + 0x007579, 0x007579, 0x000000, 0xFFFFFF, + 0x00757B, 0x00757E, 0x000000, 0xFFFFFF, + 0x007580, 0x007585, 0x000000, 0xFFFFFF, + 0x007588, 0x007589, 0x000000, 0xFFFFFF, + 0x00758C, 0x00758D, 0x000000, 0xFFFFFF, + 0x007590, 0x007590, 0x000000, 0xFFFFFF, + 0x007592, 0x00759C, 0x000000, 0xFFFFFF, + 0x00759E, 0x0075A4, 0x000000, 0xFFFFFF, + 0x0075A6, 0x0075AA, 0x000000, 0xFFFFFF, + 0x0075AC, 0x0075B0, 0x000000, 0xFFFFFF, + 0x0075B4, 0x0075B4, 0x000000, 0xFFFFFF, + 0x0075B6, 0x0075B7, 0x000000, 0xFFFFFF, + 0x0075BA, 0x0075BB, 0x000000, 0xFFFFFF, + 0x0075BF, 0x0075C1, 0x000000, 0xFFFFFF, + 0x0075C3, 0x0075C4, 0x000000, 0xFFFFFF, + 0x0075C6, 0x0075C6, 0x000000, 0xFFFFFF, + 0x0075C8, 0x0075CC, 0x000000, 0xFFFFFF, + 0x0075CE, 0x0075D1, 0x000000, 0xFFFFFF, + 0x0075D3, 0x0075D3, 0x000000, 0xFFFFFF, + 0x0075D6, 0x0075D7, 0x000000, 0xFFFFFF, + 0x0075DA, 0x0075DA, 0x000000, 0xFFFFFF, + 0x0075DC, 0x0075E1, 0x000000, 0xFFFFFF, + 0x0075E3, 0x0075EF, 0x000000, 0xFFFFFF, + 0x0075F1, 0x0075F1, 0x000000, 0xFFFFFF, + 0x0075F3, 0x0075F3, 0x000000, 0xFFFFFF, + 0x0075F5, 0x0075F9, 0x000000, 0xFFFFFF, + 0x0075FB, 0x0075FB, 0x000000, 0xFFFFFF, + 0x0075FD, 0x0075FF, 0x000000, 0xFFFFFF, + 0x007601, 0x00760C, 0x000000, 0xFFFFFF, + 0x00760E, 0x007618, 0x000000, 0xFFFFFF, + 0x00761A, 0x00761E, 0x000000, 0xFFFFFF, + 0x007623, 0x007623, 0x000000, 0xFFFFFF, + 0x007625, 0x007625, 0x000000, 0xFFFFFF, + 0x007627, 0x00763A, 0x000000, 0xFFFFFF, + 0x00763C, 0x007641, 0x000000, 0xFFFFFF, + 0x007643, 0x00764B, 0x000000, 0xFFFFFF, + 0x00764D, 0x00764D, 0x000000, 0xFFFFFF, + 0x00764F, 0x007651, 0x000000, 0xFFFFFF, + 0x007653, 0x007655, 0x000000, 0xFFFFFF, + 0x007657, 0x007660, 0x000000, 0xFFFFFF, + 0x007662, 0x007663, 0x000000, 0xFFFFFF, + 0x007665, 0x007668, 0x000000, 0xFFFFFF, + 0x00766A, 0x00766B, 0x000000, 0xFFFFFF, + 0x00766D, 0x00766F, 0x000000, 0xFFFFFF, + 0x007671, 0x007671, 0x000000, 0xFFFFFF, + 0x007673, 0x007677, 0x000000, 0xFFFFFF, + 0x007679, 0x00767A, 0x000000, 0xFFFFFF, + 0x00767F, 0x007683, 0x000000, 0xFFFFFF, + 0x007685, 0x007685, 0x000000, 0xFFFFFF, + 0x007688, 0x00768D, 0x000000, 0xFFFFFF, + 0x00768F, 0x00768F, 0x000000, 0xFFFFFF, + 0x007691, 0x007692, 0x000000, 0xFFFFFF, + 0x007694, 0x0076AD, 0x000000, 0xFFFFFF, + 0x0076AF, 0x0076B9, 0x000000, 0xFFFFFF, + 0x0076BB, 0x0076BE, 0x000000, 0xFFFFFF, + 0x0076C0, 0x0076C1, 0x000000, 0xFFFFFF, + 0x0076C4, 0x0076C5, 0x000000, 0xFFFFFF, + 0x0076C7, 0x0076C7, 0x000000, 0xFFFFFF, + 0x0076C9, 0x0076C9, 0x000000, 0xFFFFFF, + 0x0076CB, 0x0076D1, 0x000000, 0xFFFFFF, + 0x0076D3, 0x0076D5, 0x000000, 0xFFFFFF, + 0x0076D7, 0x0076DA, 0x000000, 0xFFFFFF, + 0x0076DD, 0x0076DD, 0x000000, 0xFFFFFF, + 0x0076E0, 0x0076E0, 0x000000, 0xFFFFFF, + 0x0076E2, 0x0076E2, 0x000000, 0xFFFFFF, + 0x0076E5, 0x0076E6, 0x000000, 0xFFFFFF, + 0x0076E8, 0x0076ED, 0x000000, 0xFFFFFF, + 0x0076EF, 0x0076F1, 0x000000, 0xFFFFFF, + 0x0076F3, 0x0076F3, 0x000000, 0xFFFFFF, + 0x0076F5, 0x0076F7, 0x000000, 0xFFFFFF, + 0x0076F9, 0x0076FB, 0x000000, 0xFFFFFF, + 0x0076FD, 0x0076FD, 0x000000, 0xFFFFFF, + 0x0076FF, 0x007700, 0x000000, 0xFFFFFF, + 0x007702, 0x007703, 0x000000, 0xFFFFFF, + 0x007705, 0x007707, 0x000000, 0xFFFFFF, + 0x00770A, 0x00770A, 0x000000, 0xFFFFFF, + 0x00770C, 0x00771D, 0x000000, 0xFFFFFF, + 0x00771F, 0x00771F, 0x000000, 0xFFFFFF, + 0x007721, 0x007728, 0x000000, 0xFFFFFF, + 0x00772A, 0x007736, 0x000000, 0xFFFFFF, + 0x007739, 0x007739, 0x000000, 0xFFFFFF, + 0x00773B, 0x00773B, 0x000000, 0xFFFFFF, + 0x00773D, 0x00773F, 0x000000, 0xFFFFFF, + 0x007741, 0x00774C, 0x000000, 0xFFFFFF, + 0x00774E, 0x00775A, 0x000000, 0xFFFFFF, + 0x00775C, 0x007760, 0x000000, 0xFFFFFF, + 0x007762, 0x007762, 0x000000, 0xFFFFFF, + 0x007764, 0x007765, 0x000000, 0xFFFFFF, + 0x007767, 0x00776A, 0x000000, 0xFFFFFF, + 0x00776C, 0x007778, 0x000000, 0xFFFFFF, + 0x00777A, 0x00777D, 0x000000, 0xFFFFFF, + 0x007780, 0x00778A, 0x000000, 0xFFFFFF, + 0x00778C, 0x007790, 0x000000, 0xFFFFFF, + 0x007792, 0x00779D, 0x000000, 0xFFFFFF, + 0x00779F, 0x0077A4, 0x000000, 0xFFFFFF, + 0x0077A6, 0x0077AB, 0x000000, 0xFFFFFF, + 0x0077AE, 0x0077AF, 0x000000, 0xFFFFFF, + 0x0077B1, 0x0077B2, 0x000000, 0xFFFFFF, + 0x0077B4, 0x0077BA, 0x000000, 0xFFFFFF, + 0x0077BD, 0x0077BE, 0x000000, 0xFFFFFF, + 0x0077C0, 0x0077D6, 0x000000, 0xFFFFFF, + 0x0077D8, 0x0077DA, 0x000000, 0xFFFFFF, + 0x0077DD, 0x0077E1, 0x000000, 0xFFFFFF, + 0x0077E4, 0x0077E4, 0x000000, 0xFFFFFF, + 0x0077E6, 0x0077E8, 0x000000, 0xFFFFFF, + 0x0077EA, 0x0077EC, 0x000000, 0xFFFFFF, + 0x0077F0, 0x0077F2, 0x000000, 0xFFFFFF, + 0x0077F4, 0x007801, 0x000000, 0xFFFFFF, + 0x007803, 0x007811, 0x000000, 0xFFFFFF, + 0x007813, 0x007824, 0x000000, 0xFFFFFF, + 0x007828, 0x00782B, 0x000000, 0xFFFFFF, + 0x00782D, 0x007831, 0x000000, 0xFFFFFF, + 0x007833, 0x007833, 0x000000, 0xFFFFFF, + 0x007835, 0x007844, 0x000000, 0xFFFFFF, + 0x007846, 0x00784E, 0x000000, 0xFFFFFF, + 0x007850, 0x00785C, 0x000000, 0xFFFFFF, + 0x00785E, 0x00786A, 0x000000, 0xFFFFFF, + 0x00786D, 0x00786E, 0x000000, 0xFFFFFF, + 0x007870, 0x00787B, 0x000000, 0xFFFFFF, + 0x00787D, 0x007880, 0x000000, 0xFFFFFF, + 0x007882, 0x007886, 0x000000, 0xFFFFFF, + 0x007888, 0x00788B, 0x000000, 0xFFFFFF, + 0x00788F, 0x007890, 0x000000, 0xFFFFFF, + 0x007892, 0x007896, 0x000000, 0xFFFFFF, + 0x007898, 0x0078A2, 0x000000, 0xFFFFFF, + 0x0078A4, 0x0078A6, 0x000000, 0xFFFFFF, + 0x0078A8, 0x0078A8, 0x000000, 0xFFFFFF, + 0x0078AA, 0x0078B9, 0x000000, 0xFFFFFF, + 0x0078BD, 0x0078C0, 0x000000, 0xFFFFFF, + 0x0078C2, 0x0078C4, 0x000000, 0xFFFFFF, + 0x0078C6, 0x0078C9, 0x000000, 0xFFFFFF, + 0x0078CC, 0x0078CD, 0x000000, 0xFFFFFF, + 0x0078CF, 0x0078CF, 0x000000, 0xFFFFFF, + 0x0078D1, 0x0078E7, 0x000000, 0xFFFFFF, + 0x0078E9, 0x0078EB, 0x000000, 0xFFFFFF, + 0x0078ED, 0x0078EE, 0x000000, 0xFFFFFF, + 0x0078F0, 0x0078F4, 0x000000, 0xFFFFFF, + 0x0078F6, 0x0078FA, 0x000000, 0xFFFFFF, + 0x0078FC, 0x007900, 0x000000, 0xFFFFFF, + 0x007902, 0x00790D, 0x000000, 0xFFFFFF, + 0x00790F, 0x007915, 0x000000, 0xFFFFFF, + 0x007917, 0x007929, 0x000000, 0xFFFFFF, + 0x00792D, 0x007939, 0x000000, 0xFFFFFF, + 0x00793B, 0x00793D, 0x000000, 0xFFFFFF, + 0x00793F, 0x00793F, 0x000000, 0xFFFFFF, + 0x007942, 0x007946, 0x000000, 0xFFFFFF, + 0x00794A, 0x00794F, 0x000000, 0xFFFFFF, + 0x007951, 0x007955, 0x000000, 0xFFFFFF, + 0x007958, 0x007959, 0x000000, 0xFFFFFF, + 0x00795F, 0x00795F, 0x000000, 0xFFFFFF, + 0x007961, 0x007964, 0x000000, 0xFFFFFF, + 0x007966, 0x007967, 0x000000, 0xFFFFFF, + 0x007969, 0x00796C, 0x000000, 0xFFFFFF, + 0x00796E, 0x007979, 0x000000, 0xFFFFFF, + 0x00797B, 0x00797E, 0x000000, 0xFFFFFF, + 0x007980, 0x007980, 0x000000, 0xFFFFFF, + 0x007982, 0x00798C, 0x000000, 0xFFFFFF, + 0x007990, 0x007990, 0x000000, 0xFFFFFF, + 0x007992, 0x0079A5, 0x000000, 0xFFFFFF, + 0x0079A8, 0x0079A9, 0x000000, 0xFFFFFF, + 0x0079AB, 0x0079AD, 0x000000, 0xFFFFFF, + 0x0079AF, 0x0079B0, 0x000000, 0xFFFFFF, + 0x0079B2, 0x0079B2, 0x000000, 0xFFFFFF, + 0x0079B4, 0x0079B8, 0x000000, 0xFFFFFF, + 0x0079BA, 0x0079BC, 0x000000, 0xFFFFFF, + 0x0079C2, 0x0079C8, 0x000000, 0xFFFFFF, + 0x0079CC, 0x0079D0, 0x000000, 0xFFFFFF, + 0x0079D3, 0x0079D4, 0x000000, 0xFFFFFF, + 0x0079D6, 0x0079D7, 0x000000, 0xFFFFFF, + 0x0079D9, 0x0079DE, 0x000000, 0xFFFFFF, + 0x0079E0, 0x0079E3, 0x000000, 0xFFFFFF, + 0x0079E5, 0x0079E5, 0x000000, 0xFFFFFF, + 0x0079E8, 0x0079E8, 0x000000, 0xFFFFFF, + 0x0079EA, 0x0079FA, 0x000000, 0xFFFFFF, + 0x0079FC, 0x0079FF, 0x000000, 0xFFFFFF, + 0x007A01, 0x007A04, 0x000000, 0xFFFFFF, + 0x007A06, 0x007A07, 0x000000, 0xFFFFFF, + 0x007A09, 0x007A0A, 0x000000, 0xFFFFFF, + 0x007A0C, 0x007A0C, 0x000000, 0xFFFFFF, + 0x007A0E, 0x007A13, 0x000000, 0xFFFFFF, + 0x007A15, 0x007A16, 0x000000, 0xFFFFFF, + 0x007A18, 0x007A18, 0x000000, 0xFFFFFF, + 0x007A1B, 0x007A1B, 0x000000, 0xFFFFFF, + 0x007A1D, 0x007A1E, 0x000000, 0xFFFFFF, + 0x007A21, 0x007A2D, 0x000000, 0xFFFFFF, + 0x007A2F, 0x007A30, 0x000000, 0xFFFFFF, + 0x007A32, 0x007A35, 0x000000, 0xFFFFFF, + 0x007A38, 0x007A3A, 0x000000, 0xFFFFFF, + 0x007A3E, 0x007A3E, 0x000000, 0xFFFFFF, + 0x007A41, 0x007A45, 0x000000, 0xFFFFFF, + 0x007A47, 0x007A48, 0x000000, 0xFFFFFF, + 0x007A4A, 0x007A4C, 0x000000, 0xFFFFFF, + 0x007A4F, 0x007A56, 0x000000, 0xFFFFFF, + 0x007A58, 0x007A60, 0x000000, 0xFFFFFF, + 0x007A63, 0x007A68, 0x000000, 0xFFFFFF, + 0x007A6A, 0x007A6A, 0x000000, 0xFFFFFF, + 0x007A6C, 0x007A6F, 0x000000, 0xFFFFFF, + 0x007A71, 0x007A73, 0x000000, 0xFFFFFF, + 0x007A75, 0x007A75, 0x000000, 0xFFFFFF, + 0x007A77, 0x007A78, 0x000000, 0xFFFFFF, + 0x007A7B, 0x007A7C, 0x000000, 0xFFFFFF, + 0x007A7E, 0x007A7E, 0x000000, 0xFFFFFF, + 0x007A80, 0x007A80, 0x000000, 0xFFFFFF, + 0x007A82, 0x007A83, 0x000000, 0xFFFFFF, + 0x007A85, 0x007A87, 0x000000, 0xFFFFFF, + 0x007A89, 0x007A91, 0x000000, 0xFFFFFF, + 0x007A94, 0x007A94, 0x000000, 0xFFFFFF, + 0x007A96, 0x007A97, 0x000000, 0xFFFFFF, + 0x007A99, 0x007A9E, 0x000000, 0xFFFFFF, + 0x007AA0, 0x007AA8, 0x000000, 0xFFFFFF, + 0x007AAB, 0x007AAD, 0x000000, 0xFFFFFF, + 0x007AB0, 0x007AB9, 0x000000, 0xFFFFFF, + 0x007ABB, 0x007AC3, 0x000000, 0xFFFFFF, + 0x007AC6, 0x007AC6, 0x000000, 0xFFFFFF, + 0x007AC8, 0x007AC9, 0x000000, 0xFFFFFF, + 0x007ACC, 0x007AD6, 0x000000, 0xFFFFFF, + 0x007AD8, 0x007AD8, 0x000000, 0xFFFFFF, + 0x007ADA, 0x007ADC, 0x000000, 0xFFFFFF, + 0x007ADE, 0x007ADE, 0x000000, 0xFFFFFF, + 0x007AE1, 0x007AE2, 0x000000, 0xFFFFFF, + 0x007AE4, 0x007AE4, 0x000000, 0xFFFFFF, + 0x007AE6, 0x007AE9, 0x000000, 0xFFFFFF, + 0x007AEB, 0x007AEC, 0x000000, 0xFFFFFF, + 0x007AEE, 0x007AEE, 0x000000, 0xFFFFFF, + 0x007AF0, 0x007AF5, 0x000000, 0xFFFFFF, + 0x007AF7, 0x007AF8, 0x000000, 0xFFFFFF, + 0x007AFB, 0x007AFE, 0x000000, 0xFFFFFF, + 0x007B00, 0x007B0E, 0x000000, 0xFFFFFF, + 0x007B10, 0x007B10, 0x000000, 0xFFFFFF, + 0x007B12, 0x007B18, 0x000000, 0xFFFFFF, + 0x007B1A, 0x007B1A, 0x000000, 0xFFFFFF, + 0x007B1C, 0x007B1D, 0x000000, 0xFFFFFF, + 0x007B1F, 0x007B1F, 0x000000, 0xFFFFFF, + 0x007B21, 0x007B25, 0x000000, 0xFFFFFF, + 0x007B27, 0x007B2B, 0x000000, 0xFFFFFF, + 0x007B2E, 0x007B38, 0x000000, 0xFFFFFF, + 0x007B3A, 0x007B45, 0x000000, 0xFFFFFF, + 0x007B47, 0x007B48, 0x000000, 0xFFFFFF, + 0x007B4A, 0x007B4A, 0x000000, 0xFFFFFF, + 0x007B4E, 0x007B4E, 0x000000, 0xFFFFFF, + 0x007B53, 0x007B53, 0x000000, 0xFFFFFF, + 0x007B55, 0x007B55, 0x000000, 0xFFFFFF, + 0x007B57, 0x007B5F, 0x000000, 0xFFFFFF, + 0x007B61, 0x007B6B, 0x000000, 0xFFFFFF, + 0x007B6D, 0x007B6D, 0x000000, 0xFFFFFF, + 0x007B6F, 0x007B74, 0x000000, 0xFFFFFF, + 0x007B76, 0x007B7C, 0x000000, 0xFFFFFF, + 0x007B7E, 0x007B86, 0x000000, 0xFFFFFF, + 0x007B88, 0x007B8A, 0x000000, 0xFFFFFF, + 0x007B8C, 0x007B8E, 0x000000, 0xFFFFFF, + 0x007B90, 0x007B93, 0x000000, 0xFFFFFF, + 0x007B96, 0x007B96, 0x000000, 0xFFFFFF, + 0x007B98, 0x007B99, 0x000000, 0xFFFFFF, + 0x007B9B, 0x007B9C, 0x000000, 0xFFFFFF, + 0x007B9E, 0x007BA0, 0x000000, 0xFFFFFF, + 0x007BA2, 0x007BAC, 0x000000, 0xFFFFFF, + 0x007BAE, 0x007BB0, 0x000000, 0xFFFFFF, + 0x007BB2, 0x007BB3, 0x000000, 0xFFFFFF, + 0x007BB5, 0x007BB7, 0x000000, 0xFFFFFF, + 0x007BB9, 0x007BBF, 0x000000, 0xFFFFFF, + 0x007BC2, 0x007BC3, 0x000000, 0xFFFFFF, + 0x007BC5, 0x007BC5, 0x000000, 0xFFFFFF, + 0x007BC8, 0x007BC8, 0x000000, 0xFFFFFF, + 0x007BCA, 0x007BD1, 0x000000, 0xFFFFFF, + 0x007BD3, 0x007BDF, 0x000000, 0xFFFFFF, + 0x007BE1, 0x007BE3, 0x000000, 0xFFFFFF, + 0x007BE5, 0x007BE8, 0x000000, 0xFFFFFF, + 0x007BEA, 0x007C06, 0x000000, 0xFFFFFF, + 0x007C08, 0x007C11, 0x000000, 0xFFFFFF, + 0x007C13, 0x007C1D, 0x000000, 0xFFFFFF, + 0x007C1F, 0x007C20, 0x000000, 0xFFFFFF, + 0x007C22, 0x007C26, 0x000000, 0xFFFFFF, + 0x007C28, 0x007C29, 0x000000, 0xFFFFFF, + 0x007C2C, 0x007C3C, 0x000000, 0xFFFFFF, + 0x007C40, 0x007C42, 0x000000, 0xFFFFFF, + 0x007C44, 0x007C4B, 0x000000, 0xFFFFFF, + 0x007C4E, 0x007C5F, 0x000000, 0xFFFFFF, + 0x007C61, 0x007C63, 0x000000, 0xFFFFFF, + 0x007C65, 0x007C6B, 0x000000, 0xFFFFFF, + 0x007C6D, 0x007C72, 0x000000, 0xFFFFFF, + 0x007C74, 0x007C82, 0x000000, 0xFFFFFF, + 0x007C84, 0x007C88, 0x000000, 0xFFFFFF, + 0x007C8A, 0x007C91, 0x000000, 0xFFFFFF, + 0x007C93, 0x007C94, 0x000000, 0xFFFFFF, + 0x007C96, 0x007C96, 0x000000, 0xFFFFFF, + 0x007C99, 0x007C9E, 0x000000, 0xFFFFFF, + 0x007CA0, 0x007CA4, 0x000000, 0xFFFFFF, + 0x007CA6, 0x007CA6, 0x000000, 0xFFFFFF, + 0x007CA8, 0x007CAD, 0x000000, 0xFFFFFF, + 0x007CAF, 0x007CB0, 0x000000, 0xFFFFFF, + 0x007CB4, 0x007CB8, 0x000000, 0xFFFFFF, + 0x007CBA, 0x007CBD, 0x000000, 0xFFFFFF, + 0x007CBF, 0x007CC9, 0x000000, 0xFFFFFF, + 0x007CCB, 0x007CD5, 0x000000, 0xFFFFFF, + 0x007CD7, 0x007CDD, 0x000000, 0xFFFFFF, + 0x007CE1, 0x007CE6, 0x000000, 0xFFFFFF, + 0x007CE8, 0x007CFA, 0x000000, 0xFFFFFF, + 0x007CFC, 0x007CFD, 0x000000, 0xFFFFFF, + 0x007CFF, 0x007CFF, 0x000000, 0xFFFFFF, + 0x007D01, 0x007D01, 0x000000, 0xFFFFFF, + 0x007D03, 0x007D03, 0x000000, 0xFFFFFF, + 0x007D09, 0x007D09, 0x000000, 0xFFFFFF, + 0x007D0C, 0x007D0C, 0x000000, 0xFFFFFF, + 0x007D0E, 0x007D0F, 0x000000, 0xFFFFFF, + 0x007D11, 0x007D13, 0x000000, 0xFFFFFF, + 0x007D15, 0x007D16, 0x000000, 0xFFFFFF, + 0x007D1C, 0x007D1F, 0x000000, 0xFFFFFF, + 0x007D23, 0x007D2A, 0x000000, 0xFFFFFF, + 0x007D2D, 0x007D2D, 0x000000, 0xFFFFFF, + 0x007D31, 0x007D32, 0x000000, 0xFFFFFF, + 0x007D34, 0x007D34, 0x000000, 0xFFFFFF, + 0x007D36, 0x007D38, 0x000000, 0xFFFFFF, + 0x007D3B, 0x007D41, 0x000000, 0xFFFFFF, + 0x007D47, 0x007D4F, 0x000000, 0xFFFFFF, + 0x007D51, 0x007D5D, 0x000000, 0xFFFFFF, + 0x007D5F, 0x007D60, 0x000000, 0xFFFFFF, + 0x007D63, 0x007D65, 0x000000, 0xFFFFFF, + 0x007D67, 0x007D67, 0x000000, 0xFFFFFF, + 0x007D69, 0x007D69, 0x000000, 0xFFFFFF, + 0x007D6B, 0x007D6D, 0x000000, 0xFFFFFF, + 0x007D6F, 0x007D70, 0x000000, 0xFFFFFF, + 0x007D74, 0x007D75, 0x000000, 0xFFFFFF, + 0x007D77, 0x007D78, 0x000000, 0xFFFFFF, + 0x007D7A, 0x007D7E, 0x000000, 0xFFFFFF, + 0x007D80, 0x007D8D, 0x000000, 0xFFFFFF, + 0x007D90, 0x007D92, 0x000000, 0xFFFFFF, + 0x007D94, 0x007D9B, 0x000000, 0xFFFFFF, + 0x007D9D, 0x007D9F, 0x000000, 0xFFFFFF, + 0x007DA1, 0x007DA1, 0x000000, 0xFFFFFF, + 0x007DA3, 0x007DAB, 0x000000, 0xFFFFFF, + 0x007DAE, 0x007DB0, 0x000000, 0xFFFFFF, + 0x007DB3, 0x007DB3, 0x000000, 0xFFFFFF, + 0x007DB6, 0x007DB7, 0x000000, 0xFFFFFF, + 0x007DB9, 0x007DB9, 0x000000, 0xFFFFFF, + 0x007DBC, 0x007DBC, 0x000000, 0xFFFFFF, + 0x007DC0, 0x007DC6, 0x000000, 0xFFFFFF, + 0x007DC8, 0x007DC9, 0x000000, 0xFFFFFF, + 0x007DCC, 0x007DD5, 0x000000, 0xFFFFFF, + 0x007DD7, 0x007DD7, 0x000000, 0xFFFFFF, + 0x007DD9, 0x007DD9, 0x000000, 0xFFFFFF, + 0x007DDB, 0x007DDC, 0x000000, 0xFFFFFF, + 0x007DDF, 0x007DDF, 0x000000, 0xFFFFFF, + 0x007DE2, 0x007DE2, 0x000000, 0xFFFFFF, + 0x007DE4, 0x007DE7, 0x000000, 0xFFFFFF, + 0x007DEA, 0x007DEB, 0x000000, 0xFFFFFF, + 0x007DED, 0x007DEE, 0x000000, 0xFFFFFF, + 0x007DF0, 0x007DF3, 0x000000, 0xFFFFFF, + 0x007DF5, 0x007DFA, 0x000000, 0xFFFFFF, + 0x007DFC, 0x007E08, 0x000000, 0xFFFFFF, + 0x007E0B, 0x007E14, 0x000000, 0xFFFFFF, + 0x007E16, 0x007E1A, 0x000000, 0xFFFFFF, + 0x007E1C, 0x007E1C, 0x000000, 0xFFFFFF, + 0x007E20, 0x007E20, 0x000000, 0xFFFFFF, + 0x007E22, 0x007E22, 0x000000, 0xFFFFFF, + 0x007E24, 0x007E2A, 0x000000, 0xFFFFFF, + 0x007E2C, 0x007E2D, 0x000000, 0xFFFFFF, + 0x007E30, 0x007E30, 0x000000, 0xFFFFFF, + 0x007E32, 0x007E36, 0x000000, 0xFFFFFF, + 0x007E38, 0x007E3C, 0x000000, 0xFFFFFF, + 0x007E3F, 0x007E40, 0x000000, 0xFFFFFF, + 0x007E42, 0x007E42, 0x000000, 0xFFFFFF, + 0x007E44, 0x007E45, 0x000000, 0xFFFFFF, + 0x007E48, 0x007E51, 0x000000, 0xFFFFFF, + 0x007E53, 0x007E53, 0x000000, 0xFFFFFF, + 0x007E56, 0x007E5D, 0x000000, 0xFFFFFF, + 0x007E5F, 0x007E60, 0x000000, 0xFFFFFF, + 0x007E62, 0x007E68, 0x000000, 0xFFFFFF, + 0x007E6C, 0x007E6C, 0x000000, 0xFFFFFF, + 0x007E6E, 0x007E6F, 0x000000, 0xFFFFFF, + 0x007E71, 0x007E78, 0x000000, 0xFFFFFF, + 0x007E7A, 0x007E7B, 0x000000, 0xFFFFFF, + 0x007E7D, 0x007E81, 0x000000, 0xFFFFFF, + 0x007E83, 0x007E8B, 0x000000, 0xFFFFFF, + 0x007E8D, 0x007E8E, 0x000000, 0xFFFFFF, + 0x007E90, 0x007E92, 0x000000, 0xFFFFFF, + 0x007E94, 0x007E95, 0x000000, 0xFFFFFF, + 0x007E97, 0x007E97, 0x000000, 0xFFFFFF, + 0x007E99, 0x007E9A, 0x000000, 0xFFFFFF, + 0x007E9D, 0x007F35, 0x000000, 0xFFFFFF, + 0x007F37, 0x007F37, 0x000000, 0xFFFFFF, + 0x007F39, 0x007F39, 0x000000, 0xFFFFFF, + 0x007F3B, 0x007F4B, 0x000000, 0xFFFFFF, + 0x007F4D, 0x007F4F, 0x000000, 0xFFFFFF, + 0x007F51, 0x007F53, 0x000000, 0xFFFFFF, + 0x007F56, 0x007F69, 0x000000, 0xFFFFFF, + 0x007F6C, 0x007F6D, 0x000000, 0xFFFFFF, + 0x007F6F, 0x007F6F, 0x000000, 0xFFFFFF, + 0x007F71, 0x007F71, 0x000000, 0xFFFFFF, + 0x007F73, 0x007F74, 0x000000, 0xFFFFFF, + 0x007F76, 0x007F76, 0x000000, 0xFFFFFF, + 0x007F78, 0x007F78, 0x000000, 0xFFFFFF, + 0x007F7A, 0x007F84, 0x000000, 0xFFFFFF, + 0x007F86, 0x007F87, 0x000000, 0xFFFFFF, + 0x007F89, 0x007F89, 0x000000, 0xFFFFFF, + 0x007F8B, 0x007F8B, 0x000000, 0xFFFFFF, + 0x007F8D, 0x007F8D, 0x000000, 0xFFFFFF, + 0x007F8F, 0x007F93, 0x000000, 0xFFFFFF, + 0x007F95, 0x007F99, 0x000000, 0xFFFFFF, + 0x007F9B, 0x007F9D, 0x000000, 0xFFFFFF, + 0x007F9F, 0x007FA3, 0x000000, 0xFFFFFF, + 0x007FA5, 0x007FA7, 0x000000, 0xFFFFFF, + 0x007FAA, 0x007FB1, 0x000000, 0xFFFFFF, + 0x007FB3, 0x007FB7, 0x000000, 0xFFFFFF, + 0x007FBA, 0x007FBC, 0x000000, 0xFFFFFF, + 0x007FBE, 0x007FC0, 0x000000, 0xFFFFFF, + 0x007FC2, 0x007FC4, 0x000000, 0xFFFFFF, + 0x007FC6, 0x007FC9, 0x000000, 0xFFFFFF, + 0x007FCB, 0x007FCB, 0x000000, 0xFFFFFF, + 0x007FCD, 0x007FCD, 0x000000, 0xFFFFFF, + 0x007FCF, 0x007FD1, 0x000000, 0xFFFFFF, + 0x007FD3, 0x007FD3, 0x000000, 0xFFFFFF, + 0x007FD6, 0x007FDE, 0x000000, 0xFFFFFF, + 0x007FE2, 0x007FE8, 0x000000, 0xFFFFFF, + 0x007FEA, 0x007FEA, 0x000000, 0xFFFFFF, + 0x007FEC, 0x007FEF, 0x000000, 0xFFFFFF, + 0x007FF1, 0x007FF8, 0x000000, 0xFFFFFF, + 0x007FFA, 0x007FFB, 0x000000, 0xFFFFFF, + 0x007FFD, 0x007FFF, 0x000000, 0xFFFFFF, + 0x008002, 0x008002, 0x000000, 0xFFFFFF, + 0x008004, 0x008004, 0x000000, 0xFFFFFF, + 0x008007, 0x008008, 0x000000, 0xFFFFFF, + 0x00800A, 0x00800B, 0x000000, 0xFFFFFF, + 0x00800D, 0x00800F, 0x000000, 0xFFFFFF, + 0x008011, 0x008014, 0x000000, 0xFFFFFF, + 0x008016, 0x008016, 0x000000, 0xFFFFFF, + 0x008019, 0x00802C, 0x000000, 0xFFFFFF, + 0x00802E, 0x008032, 0x000000, 0xFFFFFF, + 0x008034, 0x008035, 0x000000, 0xFFFFFF, + 0x008037, 0x00803C, 0x000000, 0xFFFFFF, + 0x00803E, 0x00803E, 0x000000, 0xFFFFFF, + 0x008040, 0x008042, 0x000000, 0xFFFFFF, + 0x008044, 0x008045, 0x000000, 0xFFFFFF, + 0x008047, 0x008049, 0x000000, 0xFFFFFF, + 0x00804B, 0x008055, 0x000000, 0xFFFFFF, + 0x008057, 0x008057, 0x000000, 0xFFFFFF, + 0x008059, 0x008059, 0x000000, 0xFFFFFF, + 0x00805B, 0x00805D, 0x000000, 0xFFFFFF, + 0x00805F, 0x00806E, 0x000000, 0xFFFFFF, + 0x008071, 0x008071, 0x000000, 0xFFFFFF, + 0x008074, 0x008076, 0x000000, 0xFFFFFF, + 0x008078, 0x00807C, 0x000000, 0xFFFFFF, + 0x008080, 0x008083, 0x000000, 0xFFFFFF, + 0x008088, 0x008088, 0x000000, 0xFFFFFF, + 0x00808A, 0x00808A, 0x000000, 0xFFFFFF, + 0x00808D, 0x008095, 0x000000, 0xFFFFFF, + 0x008097, 0x00809A, 0x000000, 0xFFFFFF, + 0x00809C, 0x00809C, 0x000000, 0xFFFFFF, + 0x00809E, 0x0080A0, 0x000000, 0xFFFFFF, + 0x0080A3, 0x0080A4, 0x000000, 0xFFFFFF, + 0x0080A6, 0x0080A8, 0x000000, 0xFFFFFF, + 0x0080AB, 0x0080AE, 0x000000, 0xFFFFFF, + 0x0080B0, 0x0080B0, 0x000000, 0xFFFFFF, + 0x0080B3, 0x0080B3, 0x000000, 0xFFFFFF, + 0x0080B5, 0x0080B9, 0x000000, 0xFFFFFF, + 0x0080BB, 0x0080C2, 0x000000, 0xFFFFFF, + 0x0080C5, 0x0080CB, 0x000000, 0xFFFFFF, + 0x0080CD, 0x0080CD, 0x000000, 0xFFFFFF, + 0x0080CF, 0x0080D9, 0x000000, 0xFFFFFF, + 0x0080DC, 0x0080DD, 0x000000, 0xFFFFFF, + 0x0080DF, 0x0080E0, 0x000000, 0xFFFFFF, + 0x0080E2, 0x0080E3, 0x000000, 0xFFFFFF, + 0x0080E6, 0x0080F0, 0x000000, 0xFFFFFF, + 0x0080F2, 0x0080F3, 0x000000, 0xFFFFFF, + 0x0080F5, 0x0080F7, 0x000000, 0xFFFFFF, + 0x0080F9, 0x0080FC, 0x000000, 0xFFFFFF, + 0x0080FE, 0x008101, 0x000000, 0xFFFFFF, + 0x008103, 0x008104, 0x000000, 0xFFFFFF, + 0x008109, 0x008109, 0x000000, 0xFFFFFF, + 0x00810B, 0x008117, 0x000000, 0xFFFFFF, + 0x008119, 0x008119, 0x000000, 0xFFFFFF, + 0x00811C, 0x008122, 0x000000, 0xFFFFFF, + 0x008124, 0x008128, 0x000000, 0xFFFFFF, + 0x00812A, 0x00812A, 0x000000, 0xFFFFFF, + 0x00812C, 0x00812E, 0x000000, 0xFFFFFF, + 0x008130, 0x008138, 0x000000, 0xFFFFFF, + 0x00813A, 0x00813D, 0x000000, 0xFFFFFF, + 0x00813F, 0x00814A, 0x000000, 0xFFFFFF, + 0x00814C, 0x00814D, 0x000000, 0xFFFFFF, + 0x00814F, 0x00814F, 0x000000, 0xFFFFFF, + 0x008152, 0x008153, 0x000000, 0xFFFFFF, + 0x008156, 0x008164, 0x000000, 0xFFFFFF, + 0x008167, 0x00816A, 0x000000, 0xFFFFFF, + 0x00816C, 0x00816F, 0x000000, 0xFFFFFF, + 0x008172, 0x008177, 0x000000, 0xFFFFFF, + 0x00817B, 0x00817E, 0x000000, 0xFFFFFF, + 0x008181, 0x008187, 0x000000, 0xFFFFFF, + 0x008189, 0x008189, 0x000000, 0xFFFFFF, + 0x00818B, 0x00818E, 0x000000, 0xFFFFFF, + 0x008190, 0x008199, 0x000000, 0xFFFFFF, + 0x00819B, 0x00819B, 0x000000, 0xFFFFFF, + 0x00819E, 0x00819F, 0x000000, 0xFFFFFF, + 0x0081A1, 0x0081A2, 0x000000, 0xFFFFFF, + 0x0081A4, 0x0081A7, 0x000000, 0xFFFFFF, + 0x0081A9, 0x0081B2, 0x000000, 0xFFFFFF, + 0x0081B4, 0x0081B4, 0x000000, 0xFFFFFF, + 0x0081B6, 0x0081B9, 0x000000, 0xFFFFFF, + 0x0081BB, 0x0081BC, 0x000000, 0xFFFFFF, + 0x0081C1, 0x0081C1, 0x000000, 0xFFFFFF, + 0x0081C3, 0x0081C5, 0x000000, 0xFFFFFF, + 0x0081C7, 0x0081CC, 0x000000, 0xFFFFFF, + 0x0081CE, 0x0081D7, 0x000000, 0xFFFFFF, + 0x0081D9, 0x0081DE, 0x000000, 0xFFFFFF, + 0x0081E0, 0x0081E2, 0x000000, 0xFFFFFF, + 0x0081E4, 0x0081E4, 0x000000, 0xFFFFFF, + 0x0081E6, 0x0081E6, 0x000000, 0xFFFFFF, + 0x0081E9, 0x0081E9, 0x000000, 0xFFFFFF, + 0x0081EB, 0x0081EC, 0x000000, 0xFFFFFF, + 0x0081EE, 0x0081F2, 0x000000, 0xFFFFFF, + 0x0081F5, 0x0081F9, 0x000000, 0xFFFFFF, + 0x0081FD, 0x0081FD, 0x000000, 0xFFFFFF, + 0x0081FF, 0x008204, 0x000000, 0xFFFFFF, + 0x008206, 0x008206, 0x000000, 0xFFFFFF, + 0x008209, 0x008209, 0x000000, 0xFFFFFF, + 0x00820B, 0x00820B, 0x000000, 0xFFFFFF, + 0x00820E, 0x008211, 0x000000, 0xFFFFFF, + 0x008213, 0x00821A, 0x000000, 0xFFFFFF, + 0x00821D, 0x00821D, 0x000000, 0xFFFFFF, + 0x008220, 0x008220, 0x000000, 0xFFFFFF, + 0x008222, 0x008229, 0x000000, 0xFFFFFF, + 0x00822D, 0x008234, 0x000000, 0xFFFFFF, + 0x008238, 0x008238, 0x000000, 0xFFFFFF, + 0x00823A, 0x00823F, 0x000000, 0xFFFFFF, + 0x008241, 0x008244, 0x000000, 0xFFFFFF, + 0x008246, 0x008246, 0x000000, 0xFFFFFF, + 0x008248, 0x008258, 0x000000, 0xFFFFFF, + 0x00825A, 0x008263, 0x000000, 0xFFFFFF, + 0x008265, 0x008265, 0x000000, 0xFFFFFF, + 0x008267, 0x00826D, 0x000000, 0xFFFFFF, + 0x008270, 0x008270, 0x000000, 0xFFFFFF, + 0x008273, 0x008275, 0x000000, 0xFFFFFF, + 0x008277, 0x008277, 0x000000, 0xFFFFFF, + 0x008279, 0x00827D, 0x000000, 0xFFFFFF, + 0x00827F, 0x00828A, 0x000000, 0xFFFFFF, + 0x00828C, 0x00828C, 0x000000, 0xFFFFFF, + 0x00828F, 0x008291, 0x000000, 0xFFFFFF, + 0x008293, 0x008298, 0x000000, 0xFFFFFF, + 0x00829B, 0x00829C, 0x000000, 0xFFFFFF, + 0x00829E, 0x00829E, 0x000000, 0xFFFFFF, + 0x0082A0, 0x0082A4, 0x000000, 0xFFFFFF, + 0x0082A7, 0x0082A8, 0x000000, 0xFFFFFF, + 0x0082AA, 0x0082AB, 0x000000, 0xFFFFFF, + 0x0082B0, 0x0082B0, 0x000000, 0xFFFFFF, + 0x0082B2, 0x0082B2, 0x000000, 0xFFFFFF, + 0x0082B4, 0x0082B6, 0x000000, 0xFFFFFF, + 0x0082BA, 0x0082BA, 0x000000, 0xFFFFFF, + 0x0082BE, 0x0082BE, 0x000000, 0xFFFFFF, + 0x0082C0, 0x0082D0, 0x000000, 0xFFFFFF, + 0x0082D3, 0x0082D3, 0x000000, 0xFFFFFF, + 0x0082D6, 0x0082D6, 0x000000, 0xFFFFFF, + 0x0082D8, 0x0082DA, 0x000000, 0xFFFFFF, + 0x0082DC, 0x0082DD, 0x000000, 0xFFFFFF, + 0x0082E0, 0x0082E0, 0x000000, 0xFFFFFF, + 0x0082E2, 0x0082E4, 0x000000, 0xFFFFFF, + 0x0082E8, 0x0082F0, 0x000000, 0xFFFFFF, + 0x0082F2, 0x0082FC, 0x000000, 0xFFFFFF, + 0x0082FF, 0x008300, 0x000000, 0xFFFFFF, + 0x008306, 0x008308, 0x000000, 0xFFFFFF, + 0x00830A, 0x008316, 0x000000, 0xFFFFFF, + 0x008318, 0x008327, 0x000000, 0xFFFFFF, + 0x008329, 0x00832A, 0x000000, 0xFFFFFF, + 0x00832C, 0x00832E, 0x000000, 0xFFFFFF, + 0x008330, 0x008330, 0x000000, 0xFFFFFF, + 0x008332, 0x008333, 0x000000, 0xFFFFFF, + 0x008337, 0x008337, 0x000000, 0xFFFFFF, + 0x00833A, 0x00833F, 0x000000, 0xFFFFFF, + 0x008341, 0x008346, 0x000000, 0xFFFFFF, + 0x008348, 0x008348, 0x000000, 0xFFFFFF, + 0x00834B, 0x00834E, 0x000000, 0xFFFFFF, + 0x008350, 0x008350, 0x000000, 0xFFFFFF, + 0x008353, 0x008372, 0x000000, 0xFFFFFF, + 0x008374, 0x008376, 0x000000, 0xFFFFFF, + 0x008378, 0x00837A, 0x000000, 0xFFFFFF, + 0x00837C, 0x008388, 0x000000, 0xFFFFFF, + 0x00838B, 0x00838D, 0x000000, 0xFFFFFF, + 0x00838F, 0x008395, 0x000000, 0xFFFFFF, + 0x008397, 0x008397, 0x000000, 0xFFFFFF, + 0x008399, 0x00839D, 0x000000, 0xFFFFFF, + 0x00839F, 0x0083A1, 0x000000, 0xFFFFFF, + 0x0083A3, 0x0083A8, 0x000000, 0xFFFFFF, + 0x0083AC, 0x0083BC, 0x000000, 0xFFFFFF, + 0x0083BE, 0x0083C0, 0x000000, 0xFFFFFF, + 0x0083C2, 0x0083C4, 0x000000, 0xFFFFFF, + 0x0083C6, 0x0083C8, 0x000000, 0xFFFFFF, + 0x0083CB, 0x0083CB, 0x000000, 0xFFFFFF, + 0x0083CD, 0x0083D2, 0x000000, 0xFFFFFF, + 0x0083D4, 0x0083D5, 0x000000, 0xFFFFFF, + 0x0083D7, 0x0083DB, 0x000000, 0xFFFFFF, + 0x0083DD, 0x0083E8, 0x000000, 0xFFFFFF, + 0x0083EA, 0x0083EA, 0x000000, 0xFFFFFF, + 0x0083EC, 0x0083EE, 0x000000, 0xFFFFFF, + 0x0083F3, 0x0083F3, 0x000000, 0xFFFFFF, + 0x0083F5, 0x0083F8, 0x000000, 0xFFFFFF, + 0x0083FA, 0x0083FC, 0x000000, 0xFFFFFF, + 0x0083FE, 0x008402, 0x000000, 0xFFFFFF, + 0x008405, 0x008409, 0x000000, 0xFFFFFF, + 0x00840B, 0x00840B, 0x000000, 0xFFFFFF, + 0x00840F, 0x008428, 0x000000, 0xFFFFFF, + 0x00842A, 0x00842B, 0x000000, 0xFFFFFF, + 0x00842D, 0x008430, 0x000000, 0xFFFFFF, + 0x008432, 0x008437, 0x000000, 0xFFFFFF, + 0x008439, 0x00843C, 0x000000, 0xFFFFFF, + 0x00843E, 0x008448, 0x000000, 0xFFFFFF, + 0x00844A, 0x008456, 0x000000, 0xFFFFFF, + 0x008458, 0x00845A, 0x000000, 0xFFFFFF, + 0x00845C, 0x008460, 0x000000, 0xFFFFFF, + 0x008462, 0x008462, 0x000000, 0xFFFFFF, + 0x008464, 0x008465, 0x000000, 0xFFFFFF, + 0x008467, 0x00846A, 0x000000, 0xFFFFFF, + 0x00846D, 0x00846E, 0x000000, 0xFFFFFF, + 0x008470, 0x008474, 0x000000, 0xFFFFFF, + 0x008476, 0x008479, 0x000000, 0xFFFFFF, + 0x00847B, 0x00848F, 0x000000, 0xFFFFFF, + 0x008491, 0x008493, 0x000000, 0xFFFFFF, + 0x008495, 0x008498, 0x000000, 0xFFFFFF, + 0x00849A, 0x00849B, 0x000000, 0xFFFFFF, + 0x00849D, 0x0084A0, 0x000000, 0xFFFFFF, + 0x0084A2, 0x0084B1, 0x000000, 0xFFFFFF, + 0x0084B3, 0x0084B7, 0x000000, 0xFFFFFF, + 0x0084B9, 0x0084BA, 0x000000, 0xFFFFFF, + 0x0084BD, 0x0084BE, 0x000000, 0xFFFFFF, + 0x0084C1, 0x0084C1, 0x000000, 0xFFFFFF, + 0x0084C3, 0x0084C3, 0x000000, 0xFFFFFF, + 0x0084C5, 0x0084C5, 0x000000, 0xFFFFFF, + 0x0084C7, 0x0084C8, 0x000000, 0xFFFFFF, + 0x0084CA, 0x0084CA, 0x000000, 0xFFFFFF, + 0x0084CC, 0x0084CC, 0x000000, 0xFFFFFF, + 0x0084CE, 0x0084D0, 0x000000, 0xFFFFFF, + 0x0084D2, 0x0084D9, 0x000000, 0xFFFFFF, + 0x0084DB, 0x0084EB, 0x000000, 0xFFFFFF, + 0x0084ED, 0x0084ED, 0x000000, 0xFFFFFF, + 0x0084EF, 0x0084F3, 0x000000, 0xFFFFFF, + 0x0084F5, 0x0084FB, 0x000000, 0xFFFFFF, + 0x0084FD, 0x008510, 0x000000, 0xFFFFFF, + 0x008512, 0x008512, 0x000000, 0xFFFFFF, + 0x008515, 0x008516, 0x000000, 0xFFFFFF, + 0x008519, 0x008519, 0x000000, 0xFFFFFF, + 0x00851B, 0x00851D, 0x000000, 0xFFFFFF, + 0x00851F, 0x008520, 0x000000, 0xFFFFFF, + 0x008522, 0x008522, 0x000000, 0xFFFFFF, + 0x008524, 0x008524, 0x000000, 0xFFFFFF, + 0x008526, 0x00852B, 0x000000, 0xFFFFFF, + 0x00852E, 0x00852E, 0x000000, 0xFFFFFF, + 0x008530, 0x00853C, 0x000000, 0xFFFFFF, + 0x00853E, 0x00853E, 0x000000, 0xFFFFFF, + 0x008540, 0x008540, 0x000000, 0xFFFFFF, + 0x008542, 0x008542, 0x000000, 0xFFFFFF, + 0x008544, 0x008548, 0x000000, 0xFFFFFF, + 0x00854A, 0x00854D, 0x000000, 0xFFFFFF, + 0x00854F, 0x008552, 0x000000, 0xFFFFFF, + 0x008554, 0x008558, 0x000000, 0xFFFFFF, + 0x00855A, 0x008562, 0x000000, 0xFFFFFF, + 0x008564, 0x008567, 0x000000, 0xFFFFFF, + 0x00856B, 0x00856C, 0x000000, 0xFFFFFF, + 0x00856E, 0x008583, 0x000000, 0xFFFFFF, + 0x008585, 0x008586, 0x000000, 0xFFFFFF, + 0x008588, 0x00858E, 0x000000, 0xFFFFFF, + 0x008590, 0x008590, 0x000000, 0xFFFFFF, + 0x008592, 0x008593, 0x000000, 0xFFFFFF, + 0x008595, 0x00859A, 0x000000, 0xFFFFFF, + 0x00859C, 0x0085A5, 0x000000, 0xFFFFFF, + 0x0085A7, 0x0085A7, 0x000000, 0xFFFFFF, + 0x0085AB, 0x0085AE, 0x000000, 0xFFFFFF, + 0x0085B1, 0x0085B9, 0x000000, 0xFFFFFF, + 0x0085BB, 0x0085C0, 0x000000, 0xFFFFFF, + 0x0085C2, 0x0085C8, 0x000000, 0xFFFFFF, + 0x0085CA, 0x0085CC, 0x000000, 0xFFFFFF, + 0x0085D0, 0x0085D4, 0x000000, 0xFFFFFF, + 0x0085D6, 0x0085DB, 0x000000, 0xFFFFFF, + 0x0085DE, 0x0085E3, 0x000000, 0xFFFFFF, + 0x0085E6, 0x0085E8, 0x000000, 0xFFFFFF, + 0x0085EB, 0x0085F6, 0x000000, 0xFFFFFF, + 0x0085F8, 0x0085F9, 0x000000, 0xFFFFFF, + 0x0085FC, 0x0085FE, 0x000000, 0xFFFFFF, + 0x008600, 0x008601, 0x000000, 0xFFFFFF, + 0x008603, 0x008605, 0x000000, 0xFFFFFF, + 0x008608, 0x008609, 0x000000, 0xFFFFFF, + 0x00860B, 0x008615, 0x000000, 0xFFFFFF, + 0x008618, 0x008619, 0x000000, 0xFFFFFF, + 0x00861B, 0x00862C, 0x000000, 0xFFFFFF, + 0x00862E, 0x00863E, 0x000000, 0xFFFFFF, + 0x008640, 0x00864D, 0x000000, 0xFFFFFF, + 0x00864F, 0x00864F, 0x000000, 0xFFFFFF, + 0x008651, 0x008653, 0x000000, 0xFFFFFF, + 0x008656, 0x00865A, 0x000000, 0xFFFFFF, + 0x00865D, 0x00865D, 0x000000, 0xFFFFFF, + 0x008660, 0x008666, 0x000000, 0xFFFFFF, + 0x008668, 0x008678, 0x000000, 0xFFFFFF, + 0x00867A, 0x008689, 0x000000, 0xFFFFFF, + 0x00868B, 0x00868B, 0x000000, 0xFFFFFF, + 0x00868D, 0x008692, 0x000000, 0xFFFFFF, + 0x008694, 0x0086A2, 0x000000, 0xFFFFFF, + 0x0086A5, 0x0086A8, 0x000000, 0xFFFFFF, + 0x0086AA, 0x0086C6, 0x000000, 0xFFFFFF, + 0x0086C8, 0x0086CA, 0x000000, 0xFFFFFF, + 0x0086CC, 0x0086D3, 0x000000, 0xFFFFFF, + 0x0086D5, 0x0086D8, 0x000000, 0xFFFFFF, + 0x0086DA, 0x0086DA, 0x000000, 0xFFFFFF, + 0x0086DC, 0x0086DE, 0x000000, 0xFFFFFF, + 0x0086E0, 0x0086E3, 0x000000, 0xFFFFFF, + 0x0086E5, 0x0086EC, 0x000000, 0xFFFFFF, + 0x0086EE, 0x0086FD, 0x000000, 0xFFFFFF, + 0x0086FF, 0x0086FF, 0x000000, 0xFFFFFF, + 0x008701, 0x008701, 0x000000, 0xFFFFFF, + 0x008704, 0x008707, 0x000000, 0xFFFFFF, + 0x008709, 0x008717, 0x000000, 0xFFFFFF, + 0x008719, 0x008719, 0x000000, 0xFFFFFF, + 0x00871B, 0x00871B, 0x000000, 0xFFFFFF, + 0x00871D, 0x00874D, 0x000000, 0xFFFFFF, + 0x00874F, 0x008754, 0x000000, 0xFFFFFF, + 0x008756, 0x008756, 0x000000, 0xFFFFFF, + 0x008758, 0x00875E, 0x000000, 0xFFFFFF, + 0x008760, 0x008765, 0x000000, 0xFFFFFF, + 0x008767, 0x008767, 0x000000, 0xFFFFFF, + 0x008769, 0x008773, 0x000000, 0xFFFFFF, + 0x008775, 0x008775, 0x000000, 0xFFFFFF, + 0x008777, 0x008777, 0x000000, 0xFFFFFF, + 0x008779, 0x008781, 0x000000, 0xFFFFFF, + 0x008783, 0x00878C, 0x000000, 0xFFFFFF, + 0x00878E, 0x00879E, 0x000000, 0xFFFFFF, + 0x0087A0, 0x0087A1, 0x000000, 0xFFFFFF, + 0x0087A3, 0x0087B2, 0x000000, 0xFFFFFF, + 0x0087B4, 0x0087B9, 0x000000, 0xFFFFFF, + 0x0087BB, 0x0087C3, 0x000000, 0xFFFFFF, + 0x0087C5, 0x0087DF, 0x000000, 0xFFFFFF, + 0x0087E1, 0x0087EB, 0x000000, 0xFFFFFF, + 0x0087ED, 0x0087EE, 0x000000, 0xFFFFFF, + 0x0087F0, 0x0087F1, 0x000000, 0xFFFFFF, + 0x0087F3, 0x0087F8, 0x000000, 0xFFFFFF, + 0x0087FA, 0x0087FA, 0x000000, 0xFFFFFF, + 0x0087FC, 0x0087FD, 0x000000, 0xFFFFFF, + 0x0087FF, 0x008804, 0x000000, 0xFFFFFF, + 0x008806, 0x00881E, 0x000000, 0xFFFFFF, + 0x008820, 0x008821, 0x000000, 0xFFFFFF, + 0x008824, 0x008830, 0x000000, 0xFFFFFF, + 0x008832, 0x008835, 0x000000, 0xFFFFFF, + 0x008837, 0x00883A, 0x000000, 0xFFFFFF, + 0x00883C, 0x00883F, 0x000000, 0xFFFFFF, + 0x008841, 0x008845, 0x000000, 0xFFFFFF, + 0x008847, 0x00884B, 0x000000, 0xFFFFFF, + 0x00884E, 0x008851, 0x000000, 0xFFFFFF, + 0x008854, 0x008856, 0x000000, 0xFFFFFF, + 0x008858, 0x008858, 0x000000, 0xFFFFFF, + 0x00885A, 0x00885A, 0x000000, 0xFFFFFF, + 0x00885C, 0x00885C, 0x000000, 0xFFFFFF, + 0x00885E, 0x008860, 0x000000, 0xFFFFFF, + 0x008864, 0x008867, 0x000000, 0xFFFFFF, + 0x008869, 0x00886A, 0x000000, 0xFFFFFF, + 0x00886C, 0x00886F, 0x000000, 0xFFFFFF, + 0x008871, 0x008871, 0x000000, 0xFFFFFF, + 0x008873, 0x008876, 0x000000, 0xFFFFFF, + 0x008878, 0x00887D, 0x000000, 0xFFFFFF, + 0x008880, 0x008880, 0x000000, 0xFFFFFF, + 0x008883, 0x008887, 0x000000, 0xFFFFFF, + 0x008889, 0x00888A, 0x000000, 0xFFFFFF, + 0x00888C, 0x00888C, 0x000000, 0xFFFFFF, + 0x00888E, 0x008891, 0x000000, 0xFFFFFF, + 0x008893, 0x008895, 0x000000, 0xFFFFFF, + 0x008898, 0x00889D, 0x000000, 0xFFFFFF, + 0x00889F, 0x0088AA, 0x000000, 0xFFFFFF, + 0x0088AC, 0x0088B3, 0x000000, 0xFFFFFF, + 0x0088B5, 0x0088C0, 0x000000, 0xFFFFFF, + 0x0088C3, 0x0088CE, 0x000000, 0xFFFFFF, + 0x0088D0, 0x0088D3, 0x000000, 0xFFFFFF, + 0x0088D6, 0x0088D8, 0x000000, 0xFFFFFF, + 0x0088DA, 0x0088DB, 0x000000, 0xFFFFFF, + 0x0088DE, 0x0088DE, 0x000000, 0xFFFFFF, + 0x0088E0, 0x0088E0, 0x000000, 0xFFFFFF, + 0x0088E2, 0x0088E7, 0x000000, 0xFFFFFF, + 0x0088E9, 0x0088F2, 0x000000, 0xFFFFFF, + 0x0088F6, 0x0088F7, 0x000000, 0xFFFFFF, + 0x0088F9, 0x0088FC, 0x000000, 0xFFFFFF, + 0x0088FE, 0x008906, 0x000000, 0xFFFFFF, + 0x008908, 0x00890F, 0x000000, 0xFFFFFF, + 0x008911, 0x008911, 0x000000, 0xFFFFFF, + 0x008914, 0x008917, 0x000000, 0xFFFFFF, + 0x00891A, 0x008924, 0x000000, 0xFFFFFF, + 0x008926, 0x008929, 0x000000, 0xFFFFFF, + 0x00892B, 0x008935, 0x000000, 0xFFFFFF, + 0x008937, 0x008937, 0x000000, 0xFFFFFF, + 0x008939, 0x00893A, 0x000000, 0xFFFFFF, + 0x00893C, 0x008940, 0x000000, 0xFFFFFF, + 0x008942, 0x008943, 0x000000, 0xFFFFFF, + 0x008945, 0x00895E, 0x000000, 0xFFFFFF, + 0x008960, 0x008963, 0x000000, 0xFFFFFF, + 0x008965, 0x008969, 0x000000, 0xFFFFFF, + 0x00896B, 0x008971, 0x000000, 0xFFFFFF, + 0x008973, 0x00897E, 0x000000, 0xFFFFFF, + 0x008980, 0x008980, 0x000000, 0xFFFFFF, + 0x008982, 0x008982, 0x000000, 0xFFFFFF, + 0x008984, 0x008985, 0x000000, 0xFFFFFF, + 0x008988, 0x00898A, 0x000000, 0xFFFFFF, + 0x00898C, 0x00898E, 0x000000, 0xFFFFFF, + 0x008990, 0x008992, 0x000000, 0xFFFFFF, + 0x008994, 0x008995, 0x000000, 0xFFFFFF, + 0x008997, 0x0089A0, 0x000000, 0xFFFFFF, + 0x0089A2, 0x0089A8, 0x000000, 0xFFFFFF, + 0x0089AB, 0x0089B1, 0x000000, 0xFFFFFF, + 0x0089B3, 0x0089B9, 0x000000, 0xFFFFFF, + 0x0089BB, 0x0089BC, 0x000000, 0xFFFFFF, + 0x0089BE, 0x0089BF, 0x000000, 0xFFFFFF, + 0x0089C1, 0x0089D1, 0x000000, 0xFFFFFF, + 0x0089D3, 0x0089E2, 0x000000, 0xFFFFFF, + 0x0089E4, 0x0089F3, 0x000000, 0xFFFFFF, + 0x0089F5, 0x0089F7, 0x000000, 0xFFFFFF, + 0x0089F9, 0x0089FF, 0x000000, 0xFFFFFF, + 0x008A01, 0x008A01, 0x000000, 0xFFFFFF, + 0x008A04, 0x008A07, 0x000000, 0xFFFFFF, + 0x008A09, 0x008A09, 0x000000, 0xFFFFFF, + 0x008A0B, 0x008A0B, 0x000000, 0xFFFFFF, + 0x008A0D, 0x008A0D, 0x000000, 0xFFFFFF, + 0x008A0F, 0x008A12, 0x000000, 0xFFFFFF, + 0x008A14, 0x008A15, 0x000000, 0xFFFFFF, + 0x008A19, 0x008A1A, 0x000000, 0xFFFFFF, + 0x008A1C, 0x008A1C, 0x000000, 0xFFFFFF, + 0x008A1E, 0x008A1E, 0x000000, 0xFFFFFF, + 0x008A20, 0x008A22, 0x000000, 0xFFFFFF, + 0x008A24, 0x008A24, 0x000000, 0xFFFFFF, + 0x008A26, 0x008A29, 0x000000, 0xFFFFFF, + 0x008A2B, 0x008A2C, 0x000000, 0xFFFFFF, + 0x008A2E, 0x008A30, 0x000000, 0xFFFFFF, + 0x008A32, 0x008A33, 0x000000, 0xFFFFFF, + 0x008A35, 0x008A35, 0x000000, 0xFFFFFF, + 0x008A37, 0x008A39, 0x000000, 0xFFFFFF, + 0x008A3C, 0x008A4F, 0x000000, 0xFFFFFF, + 0x008A51, 0x008A53, 0x000000, 0xFFFFFF, + 0x008A56, 0x008A5A, 0x000000, 0xFFFFFF, + 0x008A5C, 0x008A5D, 0x000000, 0xFFFFFF, + 0x008A5F, 0x008A5F, 0x000000, 0xFFFFFF, + 0x008A61, 0x008A61, 0x000000, 0xFFFFFF, + 0x008A64, 0x008A65, 0x000000, 0xFFFFFF, + 0x008A67, 0x008A68, 0x000000, 0xFFFFFF, + 0x008A6A, 0x008A6C, 0x000000, 0xFFFFFF, + 0x008A6F, 0x008A6F, 0x000000, 0xFFFFFF, + 0x008A74, 0x008A74, 0x000000, 0xFFFFFF, + 0x008A76, 0x008A78, 0x000000, 0xFFFFFF, + 0x008A7A, 0x008A84, 0x000000, 0xFFFFFF, + 0x008A86, 0x008A86, 0x000000, 0xFFFFFF, + 0x008A88, 0x008A8B, 0x000000, 0xFFFFFF, + 0x008A8E, 0x008A92, 0x000000, 0xFFFFFF, + 0x008A94, 0x008A94, 0x000000, 0xFFFFFF, + 0x008A96, 0x008A97, 0x000000, 0xFFFFFF, + 0x008A99, 0x008A9D, 0x000000, 0xFFFFFF, + 0x008A9F, 0x008A9F, 0x000000, 0xFFFFFF, + 0x008AA2, 0x008AA2, 0x000000, 0xFFFFFF, + 0x008AA7, 0x008AA7, 0x000000, 0xFFFFFF, + 0x008AA9, 0x008AA9, 0x000000, 0xFFFFFF, + 0x008AAB, 0x008AAF, 0x000000, 0xFFFFFF, + 0x008AB1, 0x008AB1, 0x000000, 0xFFFFFF, + 0x008AB3, 0x008AB8, 0x000000, 0xFFFFFF, + 0x008ABA, 0x008ABB, 0x000000, 0xFFFFFF, + 0x008ABD, 0x008ABD, 0x000000, 0xFFFFFF, + 0x008AC0, 0x008AC1, 0x000000, 0xFFFFFF, + 0x008AC3, 0x008AC3, 0x000000, 0xFFFFFF, + 0x008AC5, 0x008AC6, 0x000000, 0xFFFFFF, + 0x008AC8, 0x008ACA, 0x000000, 0xFFFFFF, + 0x008ACC, 0x008ACC, 0x000000, 0xFFFFFF, + 0x008ACE, 0x008ACE, 0x000000, 0xFFFFFF, + 0x008AD0, 0x008AD1, 0x000000, 0xFFFFFF, + 0x008AD3, 0x008AD5, 0x000000, 0xFFFFFF, + 0x008AD7, 0x008ADA, 0x000000, 0xFFFFFF, + 0x008ADD, 0x008AE0, 0x000000, 0xFFFFFF, + 0x008AE2, 0x008AE5, 0x000000, 0xFFFFFF, + 0x008AE8, 0x008AE9, 0x000000, 0xFFFFFF, + 0x008AEC, 0x008AEC, 0x000000, 0xFFFFFF, + 0x008AEF, 0x008AF0, 0x000000, 0xFFFFFF, + 0x008AF2, 0x008AF5, 0x000000, 0xFFFFFF, + 0x008AF9, 0x008AF9, 0x000000, 0xFFFFFF, + 0x008AFB, 0x008AFD, 0x000000, 0xFFFFFF, + 0x008AFF, 0x008AFF, 0x000000, 0xFFFFFF, + 0x008B03, 0x008B03, 0x000000, 0xFFFFFF, + 0x008B05, 0x008B0D, 0x000000, 0xFFFFFF, + 0x008B0F, 0x008B0F, 0x000000, 0xFFFFFF, + 0x008B11, 0x008B13, 0x000000, 0xFFFFFF, + 0x008B15, 0x008B15, 0x000000, 0xFFFFFF, + 0x008B18, 0x008B18, 0x000000, 0xFFFFFF, + 0x008B1C, 0x008B1C, 0x000000, 0xFFFFFF, + 0x008B1E, 0x008B1F, 0x000000, 0xFFFFFF, + 0x008B21, 0x008B27, 0x000000, 0xFFFFFF, + 0x008B29, 0x008B2A, 0x000000, 0xFFFFFF, + 0x008B2D, 0x008B32, 0x000000, 0xFFFFFF, + 0x008B34, 0x008B38, 0x000000, 0xFFFFFF, + 0x008B3A, 0x008B40, 0x000000, 0xFFFFFF, + 0x008B42, 0x008B48, 0x000000, 0xFFFFFF, + 0x008B4A, 0x008B4D, 0x000000, 0xFFFFFF, + 0x008B50, 0x008B57, 0x000000, 0xFFFFFF, + 0x008B59, 0x008B59, 0x000000, 0xFFFFFF, + 0x008B5B, 0x008B5B, 0x000000, 0xFFFFFF, + 0x008B5D, 0x008B65, 0x000000, 0xFFFFFF, + 0x008B67, 0x008B6B, 0x000000, 0xFFFFFF, + 0x008B6D, 0x008B6E, 0x000000, 0xFFFFFF, + 0x008B71, 0x008B73, 0x000000, 0xFFFFFF, + 0x008B75, 0x008B76, 0x000000, 0xFFFFFF, + 0x008B78, 0x008B7C, 0x000000, 0xFFFFFF, + 0x008B7E, 0x008B7F, 0x000000, 0xFFFFFF, + 0x008B81, 0x008B89, 0x000000, 0xFFFFFF, + 0x008B8B, 0x008B8F, 0x000000, 0xFFFFFF, + 0x008B91, 0x008B91, 0x000000, 0xFFFFFF, + 0x008B94, 0x008B95, 0x000000, 0xFFFFFF, + 0x008B97, 0x008B99, 0x000000, 0xFFFFFF, + 0x008B9B, 0x008C36, 0x000000, 0xFFFFFF, + 0x008C38, 0x008C3E, 0x000000, 0xFFFFFF, + 0x008C40, 0x008C40, 0x000000, 0xFFFFFF, + 0x008C42, 0x008C45, 0x000000, 0xFFFFFF, + 0x008C47, 0x008C47, 0x000000, 0xFFFFFF, + 0x008C49, 0x008C49, 0x000000, 0xFFFFFF, + 0x008C4B, 0x008C4B, 0x000000, 0xFFFFFF, + 0x008C4D, 0x008C54, 0x000000, 0xFFFFFF, + 0x008C56, 0x008C59, 0x000000, 0xFFFFFF, + 0x008C5B, 0x008C60, 0x000000, 0xFFFFFF, + 0x008C62, 0x008C69, 0x000000, 0xFFFFFF, + 0x008C6C, 0x008C78, 0x000000, 0xFFFFFF, + 0x008C7B, 0x008C81, 0x000000, 0xFFFFFF, + 0x008C83, 0x008C89, 0x000000, 0xFFFFFF, + 0x008C8B, 0x008C8B, 0x000000, 0xFFFFFF, + 0x008C8D, 0x008C9C, 0x000000, 0xFFFFFF, + 0x008C9F, 0x008C9F, 0x000000, 0xFFFFFF, + 0x008CA3, 0x008CA6, 0x000000, 0xFFFFFF, + 0x008CAD, 0x008CAE, 0x000000, 0xFFFFFF, + 0x008CB1, 0x008CB2, 0x000000, 0xFFFFFF, + 0x008CB5, 0x008CB5, 0x000000, 0xFFFFFF, + 0x008CB9, 0x008CBA, 0x000000, 0xFFFFFF, + 0x008CBE, 0x008CBE, 0x000000, 0xFFFFFF, + 0x008CC5, 0x008CC6, 0x000000, 0xFFFFFF, + 0x008CC9, 0x008CC9, 0x000000, 0xFFFFFF, + 0x008CCB, 0x008CD0, 0x000000, 0xFFFFFF, + 0x008CD2, 0x008CD2, 0x000000, 0xFFFFFF, + 0x008CD4, 0x008CD9, 0x000000, 0xFFFFFF, + 0x008CDB, 0x008CDB, 0x000000, 0xFFFFFF, + 0x008CDD, 0x008CDD, 0x000000, 0xFFFFFF, + 0x008CDF, 0x008CDF, 0x000000, 0xFFFFFF, + 0x008CE1, 0x008CE1, 0x000000, 0xFFFFFF, + 0x008CE5, 0x008CE5, 0x000000, 0xFFFFFF, + 0x008CE7, 0x008CE9, 0x000000, 0xFFFFFF, + 0x008CEB, 0x008CEC, 0x000000, 0xFFFFFF, + 0x008CEE, 0x008CF3, 0x000000, 0xFFFFFF, + 0x008CF5, 0x008CFA, 0x000000, 0xFFFFFF, + 0x008CFE, 0x008D03, 0x000000, 0xFFFFFF, + 0x008D06, 0x008D06, 0x000000, 0xFFFFFF, + 0x008D09, 0x008D09, 0x000000, 0xFFFFFF, + 0x008D0B, 0x008D0C, 0x000000, 0xFFFFFF, + 0x008D0E, 0x008D12, 0x000000, 0xFFFFFF, + 0x008D14, 0x008D15, 0x000000, 0xFFFFFF, + 0x008D17, 0x008D63, 0x000000, 0xFFFFFF, + 0x008D65, 0x008D65, 0x000000, 0xFFFFFF, + 0x008D67, 0x008D6A, 0x000000, 0xFFFFFF, + 0x008D6C, 0x008D6F, 0x000000, 0xFFFFFF, + 0x008D71, 0x008D72, 0x000000, 0xFFFFFF, + 0x008D75, 0x008D76, 0x000000, 0xFFFFFF, + 0x008D78, 0x008D84, 0x000000, 0xFFFFFF, + 0x008D86, 0x008D89, 0x000000, 0xFFFFFF, + 0x008D8B, 0x008D98, 0x000000, 0xFFFFFF, + 0x008D9A, 0x008DA2, 0x000000, 0xFFFFFF, + 0x008DA4, 0x008DA7, 0x000000, 0xFFFFFF, + 0x008DA9, 0x008DB2, 0x000000, 0xFFFFFF, + 0x008DB4, 0x008DB9, 0x000000, 0xFFFFFF, + 0x008DBB, 0x008DBD, 0x000000, 0xFFFFFF, + 0x008DBF, 0x008DC5, 0x000000, 0xFFFFFF, + 0x008DC7, 0x008DCA, 0x000000, 0xFFFFFF, + 0x008DCD, 0x008DCE, 0x000000, 0xFFFFFF, + 0x008DD0, 0x008DDA, 0x000000, 0xFFFFFF, + 0x008DDC, 0x008DDC, 0x000000, 0xFFFFFF, + 0x008DDE, 0x008DE0, 0x000000, 0xFFFFFF, + 0x008DE2, 0x008DE2, 0x000000, 0xFFFFFF, + 0x008DE4, 0x008DE7, 0x000000, 0xFFFFFF, + 0x008DE9, 0x008DEE, 0x000000, 0xFFFFFF, + 0x008DF0, 0x008DF2, 0x000000, 0xFFFFFF, + 0x008DF4, 0x008E09, 0x000000, 0xFFFFFF, + 0x008E0B, 0x008E0E, 0x000000, 0xFFFFFF, + 0x008E11, 0x008E1D, 0x000000, 0xFFFFFF, + 0x008E1F, 0x008E29, 0x000000, 0xFFFFFF, + 0x008E2B, 0x008E2F, 0x000000, 0xFFFFFF, + 0x008E31, 0x008E34, 0x000000, 0xFFFFFF, + 0x008E36, 0x008E41, 0x000000, 0xFFFFFF, + 0x008E43, 0x008E43, 0x000000, 0xFFFFFF, + 0x008E45, 0x008E46, 0x000000, 0xFFFFFF, + 0x008E4B, 0x008E58, 0x000000, 0xFFFFFF, + 0x008E5A, 0x008E5E, 0x000000, 0xFFFFFF, + 0x008E61, 0x008E73, 0x000000, 0xFFFFFF, + 0x008E75, 0x008E75, 0x000000, 0xFFFFFF, + 0x008E77, 0x008E80, 0x000000, 0xFFFFFF, + 0x008E82, 0x008E86, 0x000000, 0xFFFFFF, + 0x008E88, 0x008E89, 0x000000, 0xFFFFFF, + 0x008E8B, 0x008E8C, 0x000000, 0xFFFFFF, + 0x008E8E, 0x008EA9, 0x000000, 0xFFFFFF, + 0x008EAD, 0x008EBF, 0x000000, 0xFFFFFF, + 0x008EC1, 0x008EC9, 0x000000, 0xFFFFFF, + 0x008ECE, 0x008ED1, 0x000000, 0xFFFFFF, + 0x008ED3, 0x008EDE, 0x000000, 0xFFFFFF, + 0x008EE0, 0x008EEA, 0x000000, 0xFFFFFF, + 0x008EEC, 0x008EF7, 0x000000, 0xFFFFFF, + 0x008EF9, 0x008EFA, 0x000000, 0xFFFFFF, + 0x008EFC, 0x008EFD, 0x000000, 0xFFFFFF, + 0x008EFF, 0x008F02, 0x000000, 0xFFFFFF, + 0x008F04, 0x008F04, 0x000000, 0xFFFFFF, + 0x008F06, 0x008F08, 0x000000, 0xFFFFFF, + 0x008F0A, 0x008F11, 0x000000, 0xFFFFFF, + 0x008F16, 0x008F1A, 0x000000, 0xFFFFFF, + 0x008F20, 0x008F25, 0x000000, 0xFFFFFF, + 0x008F28, 0x008F28, 0x000000, 0xFFFFFF, + 0x008F2B, 0x008F2E, 0x000000, 0xFFFFFF, + 0x008F30, 0x008F32, 0x000000, 0xFFFFFF, + 0x008F34, 0x008F37, 0x000000, 0xFFFFFF, + 0x008F3A, 0x008F3A, 0x000000, 0xFFFFFF, + 0x008F3C, 0x008F3D, 0x000000, 0xFFFFFF, + 0x008F40, 0x008F43, 0x000000, 0xFFFFFF, + 0x008F46, 0x008F48, 0x000000, 0xFFFFFF, + 0x008F4A, 0x008F4C, 0x000000, 0xFFFFFF, + 0x008F4F, 0x008F5C, 0x000000, 0xFFFFFF, + 0x008F5E, 0x008F5E, 0x000000, 0xFFFFFF, + 0x008F60, 0x008F61, 0x000000, 0xFFFFFF, + 0x008F63, 0x008F9A, 0x000000, 0xFFFFFF, + 0x008F9D, 0x008FA2, 0x000000, 0xFFFFFF, + 0x008FA4, 0x008FA5, 0x000000, 0xFFFFFF, + 0x008FA7, 0x008FA7, 0x000000, 0xFFFFFF, + 0x008FA9, 0x008FAC, 0x000000, 0xFFFFFF, + 0x008FAE, 0x008FAE, 0x000000, 0xFFFFFF, + 0x008FB3, 0x008FC1, 0x000000, 0xFFFFFF, + 0x008FC3, 0x008FC4, 0x000000, 0xFFFFFF, + 0x008FC6, 0x008FCD, 0x000000, 0xFFFFFF, + 0x008FCF, 0x008FD0, 0x000000, 0xFFFFFF, + 0x008FD2, 0x008FD3, 0x000000, 0xFFFFFF, + 0x008FD5, 0x008FE5, 0x000000, 0xFFFFFF, + 0x008FE7, 0x008FE9, 0x000000, 0xFFFFFF, + 0x008FEC, 0x008FEC, 0x000000, 0xFFFFFF, + 0x008FEE, 0x008FEF, 0x000000, 0xFFFFFF, + 0x008FF1, 0x008FF1, 0x000000, 0xFFFFFF, + 0x008FF3, 0x008FF6, 0x000000, 0xFFFFFF, + 0x008FF8, 0x008FF8, 0x000000, 0xFFFFFF, + 0x008FFA, 0x008FFC, 0x000000, 0xFFFFFF, + 0x008FFE, 0x008FFF, 0x000000, 0xFFFFFF, + 0x009004, 0x009004, 0x000000, 0xFFFFFF, + 0x009007, 0x009007, 0x000000, 0xFFFFFF, + 0x009009, 0x00900A, 0x000000, 0xFFFFFF, + 0x00900C, 0x00900C, 0x000000, 0xFFFFFF, + 0x00900E, 0x00900E, 0x000000, 0xFFFFFF, + 0x009012, 0x009013, 0x000000, 0xFFFFFF, + 0x009016, 0x009016, 0x000000, 0xFFFFFF, + 0x009018, 0x009018, 0x000000, 0xFFFFFF, + 0x00901B, 0x00901C, 0x000000, 0xFFFFFF, + 0x009024, 0x00902D, 0x000000, 0xFFFFFF, + 0x00902F, 0x009030, 0x000000, 0xFFFFFF, + 0x009033, 0x009034, 0x000000, 0xFFFFFF, + 0x009036, 0x009037, 0x000000, 0xFFFFFF, + 0x009039, 0x00903B, 0x000000, 0xFFFFFF, + 0x00903D, 0x00903D, 0x000000, 0xFFFFFF, + 0x00903F, 0x009040, 0x000000, 0xFFFFFF, + 0x009043, 0x009046, 0x000000, 0xFFFFFF, + 0x009048, 0x009049, 0x000000, 0xFFFFFF, + 0x00904C, 0x00904C, 0x000000, 0xFFFFFF, + 0x00904F, 0x00904F, 0x000000, 0xFFFFFF, + 0x009052, 0x009052, 0x000000, 0xFFFFFF, + 0x009056, 0x009058, 0x000000, 0xFFFFFF, + 0x00905A, 0x00905B, 0x000000, 0xFFFFFF, + 0x00905F, 0x00905F, 0x000000, 0xFFFFFF, + 0x009062, 0x009062, 0x000000, 0xFFFFFF, + 0x009064, 0x009068, 0x000000, 0xFFFFFF, + 0x00906A, 0x00906C, 0x000000, 0xFFFFFF, + 0x009070, 0x009071, 0x000000, 0xFFFFFF, + 0x009073, 0x009074, 0x000000, 0xFFFFFF, + 0x009076, 0x009076, 0x000000, 0xFFFFFF, + 0x009079, 0x009079, 0x000000, 0xFFFFFF, + 0x00907B, 0x00907B, 0x000000, 0xFFFFFF, + 0x00907E, 0x00907E, 0x000000, 0xFFFFFF, + 0x009085, 0x009086, 0x000000, 0xFFFFFF, + 0x009089, 0x009089, 0x000000, 0xFFFFFF, + 0x00908B, 0x00908E, 0x000000, 0xFFFFFF, + 0x009090, 0x009090, 0x000000, 0xFFFFFF, + 0x009092, 0x009094, 0x000000, 0xFFFFFF, + 0x009096, 0x009098, 0x000000, 0xFFFFFF, + 0x00909A, 0x0090A1, 0x000000, 0xFFFFFF, + 0x0090A4, 0x0090A5, 0x000000, 0xFFFFFF, + 0x0090A7, 0x0090A7, 0x000000, 0xFFFFFF, + 0x0090A9, 0x0090A9, 0x000000, 0xFFFFFF, + 0x0090AB, 0x0090AE, 0x000000, 0xFFFFFF, + 0x0090B2, 0x0090B4, 0x000000, 0xFFFFFF, + 0x0090B6, 0x0090B7, 0x000000, 0xFFFFFF, + 0x0090B9, 0x0090C0, 0x000000, 0xFFFFFF, + 0x0090C2, 0x0090C9, 0x000000, 0xFFFFFF, + 0x0090CB, 0x0090DD, 0x000000, 0xFFFFFF, + 0x0090DF, 0x0090E0, 0x000000, 0xFFFFFF, + 0x0090E2, 0x0090E7, 0x000000, 0xFFFFFF, + 0x0090E9, 0x0090EC, 0x000000, 0xFFFFFF, + 0x0090EE, 0x0090F4, 0x000000, 0xFFFFFF, + 0x0090F6, 0x0090FC, 0x000000, 0xFFFFFF, + 0x0090FE, 0x009101, 0x000000, 0xFFFFFF, + 0x009103, 0x009111, 0x000000, 0xFFFFFF, + 0x009113, 0x009114, 0x000000, 0xFFFFFF, + 0x009116, 0x009118, 0x000000, 0xFFFFFF, + 0x00911A, 0x009126, 0x000000, 0xFFFFFF, + 0x009128, 0x00912C, 0x000000, 0xFFFFFF, + 0x00912E, 0x009131, 0x000000, 0xFFFFFF, + 0x009133, 0x009148, 0x000000, 0xFFFFFF, + 0x00914F, 0x009151, 0x000000, 0xFFFFFF, + 0x009153, 0x009161, 0x000000, 0xFFFFFF, + 0x009163, 0x009168, 0x000000, 0xFFFFFF, + 0x00916B, 0x00916B, 0x000000, 0xFFFFFF, + 0x00916D, 0x009174, 0x000000, 0xFFFFFF, + 0x009176, 0x009176, 0x000000, 0xFFFFFF, + 0x009179, 0x009186, 0x000000, 0xFFFFFF, + 0x009188, 0x009188, 0x000000, 0xFFFFFF, + 0x00918A, 0x00918A, 0x000000, 0xFFFFFF, + 0x00918C, 0x00918C, 0x000000, 0xFFFFFF, + 0x00918E, 0x009191, 0x000000, 0xFFFFFF, + 0x009193, 0x00919B, 0x000000, 0xFFFFFF, + 0x00919D, 0x0091AA, 0x000000, 0xFFFFFF, + 0x0091AD, 0x0091AD, 0x000000, 0xFFFFFF, + 0x0091B0, 0x0091B0, 0x000000, 0xFFFFFF, + 0x0091B2, 0x0091B3, 0x000000, 0xFFFFFF, + 0x0091B6, 0x0091BF, 0x000000, 0xFFFFFF, + 0x0091C1, 0x0091C6, 0x000000, 0xFFFFFF, + 0x0091C8, 0x0091C8, 0x000000, 0xFFFFFF, + 0x0091CA, 0x0091CA, 0x000000, 0xFFFFFF, + 0x0091D2, 0x0091D6, 0x000000, 0xFFFFFF, + 0x0091D9, 0x0091DB, 0x000000, 0xFFFFFF, + 0x0091DE, 0x0091E2, 0x000000, 0xFFFFFF, + 0x0091E4, 0x0091E6, 0x000000, 0xFFFFFF, + 0x0091E8, 0x0091E9, 0x000000, 0xFFFFFF, + 0x0091EB, 0x0091F4, 0x000000, 0xFFFFFF, + 0x0091F6, 0x00920C, 0x000000, 0xFFFFFF, + 0x00920E, 0x00920F, 0x000000, 0xFFFFFF, + 0x009213, 0x009216, 0x000000, 0xFFFFFF, + 0x009218, 0x00921D, 0x000000, 0xFFFFFF, + 0x00921F, 0x009233, 0x000000, 0xFFFFFF, + 0x009235, 0x009239, 0x000000, 0xFFFFFF, + 0x00923B, 0x00923E, 0x000000, 0xFFFFFF, + 0x009241, 0x009244, 0x000000, 0xFFFFFF, + 0x009246, 0x009248, 0x000000, 0xFFFFFF, + 0x00924A, 0x009256, 0x000000, 0xFFFFFF, + 0x009258, 0x00925A, 0x000000, 0xFFFFFF, + 0x00925C, 0x00925D, 0x000000, 0xFFFFFF, + 0x00925F, 0x009261, 0x000000, 0xFFFFFF, + 0x009263, 0x009263, 0x000000, 0xFFFFFF, + 0x009267, 0x00927F, 0x000000, 0xFFFFFF, + 0x009281, 0x009282, 0x000000, 0xFFFFFF, + 0x009284, 0x009284, 0x000000, 0xFFFFFF, + 0x009286, 0x009290, 0x000000, 0xFFFFFF, + 0x009292, 0x009292, 0x000000, 0xFFFFFF, + 0x009294, 0x009295, 0x000000, 0xFFFFFF, + 0x009297, 0x009297, 0x000000, 0xFFFFFF, + 0x009299, 0x00929B, 0x000000, 0xFFFFFF, + 0x00929D, 0x0092B2, 0x000000, 0xFFFFFF, + 0x0092B4, 0x0092B5, 0x000000, 0xFFFFFF, + 0x0092B8, 0x0092B8, 0x000000, 0xFFFFFF, + 0x0092BA, 0x0092CB, 0x000000, 0xFFFFFF, + 0x0092CD, 0x0092CE, 0x000000, 0xFFFFFF, + 0x0092D0, 0x0092D1, 0x000000, 0xFFFFFF, + 0x0092D3, 0x0092E3, 0x000000, 0xFFFFFF, + 0x0092E5, 0x0092E9, 0x000000, 0xFFFFFF, + 0x0092EB, 0x0092F7, 0x000000, 0xFFFFFF, + 0x0092F9, 0x0092FB, 0x000000, 0xFFFFFF, + 0x0092FD, 0x009303, 0x000000, 0xFFFFFF, + 0x009305, 0x00930F, 0x000000, 0xFFFFFF, + 0x009311, 0x009317, 0x000000, 0xFFFFFF, + 0x009319, 0x009319, 0x000000, 0xFFFFFF, + 0x00931B, 0x00931D, 0x000000, 0xFFFFFF, + 0x009323, 0x009323, 0x000000, 0xFFFFFF, + 0x009325, 0x009325, 0x000000, 0xFFFFFF, + 0x009327, 0x009327, 0x000000, 0xFFFFFF, + 0x009329, 0x00932A, 0x000000, 0xFFFFFF, + 0x00932C, 0x00932D, 0x000000, 0xFFFFFF, + 0x009330, 0x009347, 0x000000, 0xFFFFFF, + 0x009349, 0x009349, 0x000000, 0xFFFFFF, + 0x00934C, 0x00934C, 0x000000, 0xFFFFFF, + 0x00934E, 0x009353, 0x000000, 0xFFFFFF, + 0x009355, 0x00935A, 0x000000, 0xFFFFFF, + 0x00935C, 0x00936D, 0x000000, 0xFFFFFF, + 0x00936F, 0x009374, 0x000000, 0xFFFFFF, + 0x009376, 0x00937B, 0x000000, 0xFFFFFF, + 0x00937D, 0x00937D, 0x000000, 0xFFFFFF, + 0x00937F, 0x00938B, 0x000000, 0xFFFFFF, + 0x00938D, 0x009393, 0x000000, 0xFFFFFF, + 0x009395, 0x009395, 0x000000, 0xFFFFFF, + 0x009397, 0x009399, 0x000000, 0xFFFFFF, + 0x00939B, 0x0093A2, 0x000000, 0xFFFFFF, + 0x0093A4, 0x0093A6, 0x000000, 0xFFFFFF, + 0x0093A8, 0x0093AB, 0x000000, 0xFFFFFF, + 0x0093AE, 0x0093AF, 0x000000, 0xFFFFFF, + 0x0093B1, 0x0093C2, 0x000000, 0xFFFFFF, + 0x0093C4, 0x0093D0, 0x000000, 0xFFFFFF, + 0x0093D2, 0x0093DD, 0x000000, 0xFFFFFF, + 0x0093DF, 0x0093E0, 0x000000, 0xFFFFFF, + 0x0093E2, 0x0093E3, 0x000000, 0xFFFFFF, + 0x0093E5, 0x0093F5, 0x000000, 0xFFFFFF, + 0x0093F7, 0x009403, 0x000000, 0xFFFFFF, + 0x009405, 0x009417, 0x000000, 0xFFFFFF, + 0x009419, 0x009424, 0x000000, 0xFFFFFF, + 0x009426, 0x00942A, 0x000000, 0xFFFFFF, + 0x00942C, 0x009434, 0x000000, 0xFFFFFF, + 0x009436, 0x009437, 0x000000, 0xFFFFFF, + 0x009439, 0x009443, 0x000000, 0xFFFFFF, + 0x009445, 0x009450, 0x000000, 0xFFFFFF, + 0x009453, 0x00945A, 0x000000, 0xFFFFFF, + 0x00945C, 0x00947C, 0x000000, 0xFFFFFF, + 0x00947E, 0x00947E, 0x000000, 0xFFFFFF, + 0x009480, 0x009576, 0x000000, 0xFFFFFF, + 0x009578, 0x00957F, 0x000000, 0xFFFFFF, + 0x009581, 0x009582, 0x000000, 0xFFFFFF, + 0x009584, 0x009588, 0x000000, 0xFFFFFF, + 0x00958A, 0x00958A, 0x000000, 0xFFFFFF, + 0x00958C, 0x00958E, 0x000000, 0xFFFFFF, + 0x009590, 0x009590, 0x000000, 0xFFFFFF, + 0x009595, 0x009597, 0x000000, 0xFFFFFF, + 0x009599, 0x0095A2, 0x000000, 0xFFFFFF, + 0x0095A6, 0x0095A7, 0x000000, 0xFFFFFF, + 0x0095A9, 0x0095AC, 0x000000, 0xFFFFFF, + 0x0095AE, 0x0095B0, 0x000000, 0xFFFFFF, + 0x0095B2, 0x0095BA, 0x000000, 0xFFFFFF, + 0x0095BD, 0x0095C6, 0x000000, 0xFFFFFF, + 0x0095C8, 0x0095C9, 0x000000, 0xFFFFFF, + 0x0095CB, 0x0095D3, 0x000000, 0xFFFFFF, + 0x0095D7, 0x0095DB, 0x000000, 0xFFFFFF, + 0x0095DD, 0x0095E0, 0x000000, 0xFFFFFF, + 0x0095E3, 0x00961B, 0x000000, 0xFFFFFF, + 0x00961D, 0x009620, 0x000000, 0xFFFFFF, + 0x009622, 0x009629, 0x000000, 0xFFFFFF, + 0x00962B, 0x00962D, 0x000000, 0xFFFFFF, + 0x00962F, 0x009631, 0x000000, 0xFFFFFF, + 0x009633, 0x00963A, 0x000000, 0xFFFFFF, + 0x00963C, 0x00963E, 0x000000, 0xFFFFFF, + 0x009641, 0x009641, 0x000000, 0xFFFFFF, + 0x009643, 0x009643, 0x000000, 0xFFFFFF, + 0x009645, 0x00964A, 0x000000, 0xFFFFFF, + 0x00964E, 0x00964F, 0x000000, 0xFFFFFF, + 0x009651, 0x00965A, 0x000000, 0xFFFFFF, + 0x009660, 0x009661, 0x000000, 0xFFFFFF, + 0x009665, 0x009669, 0x000000, 0xFFFFFF, + 0x00966B, 0x00966F, 0x000000, 0xFFFFFF, + 0x009671, 0x009672, 0x000000, 0xFFFFFF, + 0x009674, 0x009674, 0x000000, 0xFFFFFF, + 0x009679, 0x00967C, 0x000000, 0xFFFFFF, + 0x00967E, 0x009684, 0x000000, 0xFFFFFF, + 0x009687, 0x009689, 0x000000, 0xFFFFFF, + 0x00968C, 0x00968C, 0x000000, 0xFFFFFF, + 0x00968F, 0x009693, 0x000000, 0xFFFFFF, + 0x009696, 0x009697, 0x000000, 0xFFFFFF, + 0x00969A, 0x00969A, 0x000000, 0xFFFFFF, + 0x00969D, 0x0096A2, 0x000000, 0xFFFFFF, + 0x0096A4, 0x0096A6, 0x000000, 0xFFFFFF, + 0x0096A9, 0x0096A9, 0x000000, 0xFFFFFF, + 0x0096AB, 0x0096B0, 0x000000, 0xFFFFFF, + 0x0096B2, 0x0096B6, 0x000000, 0xFFFFFF, + 0x0096B8, 0x0096BA, 0x000000, 0xFFFFFF, + 0x0096BC, 0x0096BF, 0x000000, 0xFFFFFF, + 0x0096C2, 0x0096C3, 0x000000, 0xFFFFFF, + 0x0096C8, 0x0096C8, 0x000000, 0xFFFFFF, + 0x0096CA, 0x0096CA, 0x000000, 0xFFFFFF, + 0x0096CF, 0x0096D4, 0x000000, 0xFFFFFF, + 0x0096D7, 0x0096D8, 0x000000, 0xFFFFFF, + 0x0096DA, 0x0096DA, 0x000000, 0xFFFFFF, + 0x0096DD, 0x0096E1, 0x000000, 0xFFFFFF, + 0x0096E4, 0x0096E7, 0x000000, 0xFFFFFF, + 0x0096EB, 0x0096EE, 0x000000, 0xFFFFFF, + 0x0096F1, 0x0096F1, 0x000000, 0xFFFFFF, + 0x0096F3, 0x0096F5, 0x000000, 0xFFFFFF, + 0x0096F8, 0x0096F8, 0x000000, 0xFFFFFF, + 0x0096FA, 0x0096FA, 0x000000, 0xFFFFFF, + 0x0096FC, 0x0096FF, 0x000000, 0xFFFFFF, + 0x009701, 0x009705, 0x000000, 0xFFFFFF, + 0x009708, 0x009710, 0x000000, 0xFFFFFF, + 0x009712, 0x009712, 0x000000, 0xFFFFFF, + 0x009714, 0x009715, 0x000000, 0xFFFFFF, + 0x009717, 0x009718, 0x000000, 0xFFFFFF, + 0x00971A, 0x00971B, 0x000000, 0xFFFFFF, + 0x00971D, 0x00971D, 0x000000, 0xFFFFFF, + 0x00971F, 0x009726, 0x000000, 0xFFFFFF, + 0x009728, 0x00972F, 0x000000, 0xFFFFFF, + 0x009731, 0x009731, 0x000000, 0xFFFFFF, + 0x009733, 0x009738, 0x000000, 0xFFFFFF, + 0x00973A, 0x00973C, 0x000000, 0xFFFFFF, + 0x00973E, 0x009741, 0x000000, 0xFFFFFF, + 0x009743, 0x009743, 0x000000, 0xFFFFFF, + 0x009745, 0x009747, 0x000000, 0xFFFFFF, + 0x009749, 0x009750, 0x000000, 0xFFFFFF, + 0x009752, 0x009755, 0x000000, 0xFFFFFF, + 0x009757, 0x00975B, 0x000000, 0xFFFFFF, + 0x00975D, 0x00975D, 0x000000, 0xFFFFFF, + 0x00975F, 0x009760, 0x000000, 0xFFFFFF, + 0x009763, 0x009768, 0x000000, 0xFFFFFF, + 0x00976A, 0x00976C, 0x000000, 0xFFFFFF, + 0x00976E, 0x009773, 0x000000, 0xFFFFFF, + 0x009775, 0x009776, 0x000000, 0xFFFFFF, + 0x009778, 0x009779, 0x000000, 0xFFFFFF, + 0x00977B, 0x00978A, 0x000000, 0xFFFFFF, + 0x00978C, 0x00978C, 0x000000, 0xFFFFFF, + 0x00978E, 0x00978E, 0x000000, 0xFFFFFF, + 0x009790, 0x00979F, 0x000000, 0xFFFFFF, + 0x0097A1, 0x0097A7, 0x000000, 0xFFFFFF, + 0x0097A9, 0x0097AA, 0x000000, 0xFFFFFF, + 0x0097AC, 0x0097AC, 0x000000, 0xFFFFFF, + 0x0097AE, 0x0097C5, 0x000000, 0xFFFFFF, + 0x0097C7, 0x0097CA, 0x000000, 0xFFFFFF, + 0x0097CC, 0x0097D2, 0x000000, 0xFFFFFF, + 0x0097D4, 0x0097DB, 0x000000, 0xFFFFFF, + 0x0097DD, 0x0097F2, 0x000000, 0xFFFFFF, + 0x0097F4, 0x0097F5, 0x000000, 0xFFFFFF, + 0x0097F7, 0x0097FA, 0x000000, 0xFFFFFF, + 0x0097FC, 0x0097FE, 0x000000, 0xFFFFFF, + 0x009804, 0x009804, 0x000000, 0xFFFFFF, + 0x009807, 0x009807, 0x000000, 0xFFFFFF, + 0x009809, 0x009809, 0x000000, 0xFFFFFF, + 0x00980B, 0x00980B, 0x000000, 0xFFFFFF, + 0x00980D, 0x00980F, 0x000000, 0xFFFFFF, + 0x009814, 0x009816, 0x000000, 0xFFFFFF, + 0x009819, 0x00982C, 0x000000, 0xFFFFFF, + 0x00982E, 0x00982F, 0x000000, 0xFFFFFF, + 0x009831, 0x009837, 0x000000, 0xFFFFFF, + 0x00983A, 0x00983A, 0x000000, 0xFFFFFF, + 0x00983C, 0x009845, 0x000000, 0xFFFFFF, + 0x009847, 0x00984B, 0x000000, 0xFFFFFF, + 0x00984F, 0x009853, 0x000000, 0xFFFFFF, + 0x009855, 0x009857, 0x000000, 0xFFFFFF, + 0x009859, 0x009859, 0x000000, 0xFFFFFF, + 0x00985B, 0x00985D, 0x000000, 0xFFFFFF, + 0x00985F, 0x009864, 0x000000, 0xFFFFFF, + 0x009866, 0x009866, 0x000000, 0xFFFFFF, + 0x009868, 0x00986A, 0x000000, 0xFFFFFF, + 0x00986C, 0x00986E, 0x000000, 0xFFFFFF, + 0x009870, 0x0098A7, 0x000000, 0xFFFFFF, + 0x0098A9, 0x0098AE, 0x000000, 0xFFFFFF, + 0x0098B0, 0x0098B0, 0x000000, 0xFFFFFF, + 0x0098B2, 0x0098C3, 0x000000, 0xFFFFFF, + 0x0098C5, 0x0098C6, 0x000000, 0xFFFFFF, + 0x0098C8, 0x0098DA, 0x000000, 0xFFFFFF, + 0x0098DD, 0x0098DE, 0x000000, 0xFFFFFF, + 0x0098E0, 0x0098E0, 0x000000, 0xFFFFFF, + 0x0098E3, 0x0098EC, 0x000000, 0xFFFFFF, + 0x0098F0, 0x0098F3, 0x000000, 0xFFFFFF, + 0x0098F5, 0x0098FB, 0x000000, 0xFFFFFF, + 0x0098FF, 0x009902, 0x000000, 0xFFFFFF, + 0x009904, 0x009908, 0x000000, 0xFFFFFF, + 0x00990B, 0x00990B, 0x000000, 0xFFFFFF, + 0x00990D, 0x00990F, 0x000000, 0xFFFFFF, + 0x009911, 0x009912, 0x000000, 0xFFFFFF, + 0x009914, 0x009917, 0x000000, 0xFFFFFF, + 0x009919, 0x00991D, 0x000000, 0xFFFFFF, + 0x00991F, 0x00991F, 0x000000, 0xFFFFFF, + 0x009921, 0x009927, 0x000000, 0xFFFFFF, + 0x009929, 0x009944, 0x000000, 0xFFFFFF, + 0x009946, 0x009948, 0x000000, 0xFFFFFF, + 0x00994A, 0x00994A, 0x000000, 0xFFFFFF, + 0x00994E, 0x009950, 0x000000, 0xFFFFFF, + 0x009953, 0x009953, 0x000000, 0xFFFFFF, + 0x009955, 0x009956, 0x000000, 0xFFFFFF, + 0x009958, 0x009995, 0x000000, 0xFFFFFF, + 0x009997, 0x009998, 0x000000, 0xFFFFFF, + 0x00999A, 0x00999C, 0x000000, 0xFFFFFF, + 0x00999E, 0x0099A4, 0x000000, 0xFFFFFF, + 0x0099A6, 0x0099A7, 0x000000, 0xFFFFFF, + 0x0099A9, 0x0099AB, 0x000000, 0xFFFFFF, + 0x0099AF, 0x0099B0, 0x000000, 0xFFFFFF, + 0x0099B2, 0x0099B2, 0x000000, 0xFFFFFF, + 0x0099B5, 0x0099B8, 0x000000, 0xFFFFFF, + 0x0099BA, 0x0099C0, 0x000000, 0xFFFFFF, + 0x0099C2, 0x0099CF, 0x000000, 0xFFFFFF, + 0x0099D3, 0x0099D4, 0x000000, 0xFFFFFF, + 0x0099D6, 0x0099D8, 0x000000, 0xFFFFFF, + 0x0099DA, 0x0099DC, 0x000000, 0xFFFFFF, + 0x0099DE, 0x0099DE, 0x000000, 0xFFFFFF, + 0x0099E0, 0x0099EC, 0x000000, 0xFFFFFF, + 0x0099EE, 0x0099F0, 0x000000, 0xFFFFFF, + 0x0099F2, 0x0099FE, 0x000000, 0xFFFFFF, + 0x009A00, 0x009A00, 0x000000, 0xFFFFFF, + 0x009A02, 0x009A07, 0x000000, 0xFFFFFF, + 0x009A09, 0x009A0D, 0x000000, 0xFFFFFF, + 0x009A10, 0x009A18, 0x000000, 0xFFFFFF, + 0x009A1A, 0x009A2A, 0x000000, 0xFFFFFF, + 0x009A2C, 0x009A2F, 0x000000, 0xFFFFFF, + 0x009A31, 0x009A35, 0x000000, 0xFFFFFF, + 0x009A38, 0x009A3F, 0x000000, 0xFFFFFF, + 0x009A41, 0x009A42, 0x000000, 0xFFFFFF, + 0x009A44, 0x009A44, 0x000000, 0xFFFFFF, + 0x009A46, 0x009A4C, 0x000000, 0xFFFFFF, + 0x009A4E, 0x009A54, 0x000000, 0xFFFFFF, + 0x009A56, 0x009A56, 0x000000, 0xFFFFFF, + 0x009A58, 0x009A59, 0x000000, 0xFFFFFF, + 0x009A5C, 0x009A5E, 0x000000, 0xFFFFFF, + 0x009A60, 0x009A61, 0x000000, 0xFFFFFF, + 0x009A63, 0x009A64, 0x000000, 0xFFFFFF, + 0x009A66, 0x009A68, 0x000000, 0xFFFFFF, + 0x009A6B, 0x009AA7, 0x000000, 0xFFFFFF, + 0x009AA9, 0x009AB7, 0x000000, 0xFFFFFF, + 0x009AB9, 0x009AD2, 0x000000, 0xFFFFFF, + 0x009AD5, 0x009AD7, 0x000000, 0xFFFFFF, + 0x009AD9, 0x009AE4, 0x000000, 0xFFFFFF, + 0x009AE6, 0x009AED, 0x000000, 0xFFFFFF, + 0x009AEF, 0x009B19, 0x000000, 0xFFFFFF, + 0x009B1B, 0x009B26, 0x000000, 0xFFFFFF, + 0x009B28, 0x009B29, 0x000000, 0xFFFFFF, + 0x009B2B, 0x009B30, 0x000000, 0xFFFFFF, + 0x009B32, 0x009B3B, 0x000000, 0xFFFFFF, + 0x009B3D, 0x009B40, 0x000000, 0xFFFFFF, + 0x009B46, 0x009B4E, 0x000000, 0xFFFFFF, + 0x009B50, 0x009B53, 0x000000, 0xFFFFFF, + 0x009B55, 0x009B59, 0x000000, 0xFFFFFF, + 0x009B5B, 0x009B6E, 0x000000, 0xFFFFFF, + 0x009B70, 0x009B8D, 0x000000, 0xFFFFFF, + 0x009B8F, 0x009B90, 0x000000, 0xFFFFFF, + 0x009B92, 0x009B9E, 0x000000, 0xFFFFFF, + 0x009BA0, 0x009BAA, 0x000000, 0xFFFFFF, + 0x009BAC, 0x009BAD, 0x000000, 0xFFFFFF, + 0x009BAF, 0x009BC8, 0x000000, 0xFFFFFF, + 0x009BCA, 0x009BD5, 0x000000, 0xFFFFFF, + 0x009BD7, 0x009BE3, 0x000000, 0xFFFFFF, + 0x009BE5, 0x009BE7, 0x000000, 0xFFFFFF, + 0x009BE9, 0x009C0C, 0x000000, 0xFFFFFF, + 0x009C0E, 0x009C0F, 0x000000, 0xFFFFFF, + 0x009C11, 0x009C11, 0x000000, 0xFFFFFF, + 0x009C13, 0x009C14, 0x000000, 0xFFFFFF, + 0x009C16, 0x009C24, 0x000000, 0xFFFFFF, + 0x009C26, 0x009C31, 0x000000, 0xFFFFFF, + 0x009C33, 0x009C3A, 0x000000, 0xFFFFFF, + 0x009C3C, 0x009C46, 0x000000, 0xFFFFFF, + 0x009C48, 0x009C48, 0x000000, 0xFFFFFF, + 0x009C4A, 0x009C56, 0x000000, 0xFFFFFF, + 0x009C58, 0x009CE4, 0x000000, 0xFFFFFF, + 0x009CE6, 0x009CE6, 0x000000, 0xFFFFFF, + 0x009CE8, 0x009CE8, 0x000000, 0xFFFFFF, + 0x009CEA, 0x009CF2, 0x000000, 0xFFFFFF, + 0x009CF5, 0x009CF5, 0x000000, 0xFFFFFF, + 0x009CF7, 0x009D08, 0x000000, 0xFFFFFF, + 0x009D0A, 0x009D1A, 0x000000, 0xFFFFFF, + 0x009D1C, 0x009D25, 0x000000, 0xFFFFFF, + 0x009D27, 0x009D27, 0x000000, 0xFFFFFF, + 0x009D29, 0x009D3A, 0x000000, 0xFFFFFF, + 0x009D3C, 0x009D50, 0x000000, 0xFFFFFF, + 0x009D52, 0x009D5C, 0x000000, 0xFFFFFF, + 0x009D5E, 0x009D5F, 0x000000, 0xFFFFFF, + 0x009D62, 0x009D6B, 0x000000, 0xFFFFFF, + 0x009D6D, 0x009D71, 0x000000, 0xFFFFFF, + 0x009D73, 0x009DA8, 0x000000, 0xFFFFFF, + 0x009DAA, 0x009DAE, 0x000000, 0xFFFFFF, + 0x009DB0, 0x009DB3, 0x000000, 0xFFFFFF, + 0x009DB5, 0x009DC3, 0x000000, 0xFFFFFF, + 0x009DC5, 0x009DD6, 0x000000, 0xFFFFFF, + 0x009DD8, 0x009DF1, 0x000000, 0xFFFFFF, + 0x009DF3, 0x009DF7, 0x000000, 0xFFFFFF, + 0x009DFB, 0x009E19, 0x000000, 0xFFFFFF, + 0x009E1B, 0x009E1D, 0x000000, 0xFFFFFF, + 0x009E1F, 0x009E74, 0x000000, 0xFFFFFF, + 0x009E76, 0x009E78, 0x000000, 0xFFFFFF, + 0x009E7A, 0x009E7C, 0x000000, 0xFFFFFF, + 0x009E7E, 0x009E7E, 0x000000, 0xFFFFFF, + 0x009E80, 0x009E91, 0x000000, 0xFFFFFF, + 0x009E94, 0x009E96, 0x000000, 0xFFFFFF, + 0x009E98, 0x009E9C, 0x000000, 0xFFFFFF, + 0x009E9E, 0x009E9E, 0x000000, 0xFFFFFF, + 0x009EA0, 0x009EA4, 0x000000, 0xFFFFFF, + 0x009EA6, 0x009EB3, 0x000000, 0xFFFFFF, + 0x009EB6, 0x009EBA, 0x000000, 0xFFFFFF, + 0x009EBC, 0x009EBD, 0x000000, 0xFFFFFF, + 0x009EBF, 0x009EC2, 0x000000, 0xFFFFFF, + 0x009EC4, 0x009ECC, 0x000000, 0xFFFFFF, + 0x009ECF, 0x009ED0, 0x000000, 0xFFFFFF, + 0x009ED2, 0x009ED3, 0x000000, 0xFFFFFF, + 0x009ED5, 0x009ED7, 0x000000, 0xFFFFFF, + 0x009ED9, 0x009EDA, 0x000000, 0xFFFFFF, + 0x009EDD, 0x009EDD, 0x000000, 0xFFFFFF, + 0x009EDF, 0x009EE7, 0x000000, 0xFFFFFF, + 0x009EE9, 0x009EF3, 0x000000, 0xFFFFFF, + 0x009EF5, 0x009F06, 0x000000, 0xFFFFFF, + 0x009F09, 0x009F0D, 0x000000, 0xFFFFFF, + 0x009F0F, 0x009F12, 0x000000, 0xFFFFFF, + 0x009F14, 0x009F1F, 0x000000, 0xFFFFFF, + 0x009F21, 0x009F3A, 0x000000, 0xFFFFFF, + 0x009F3C, 0x009F49, 0x000000, 0xFFFFFF, + 0x009F4C, 0x009F4D, 0x000000, 0xFFFFFF, + 0x009F4F, 0x009F51, 0x000000, 0xFFFFFF, + 0x009F53, 0x009F5E, 0x000000, 0xFFFFFF, + 0x009F60, 0x009F60, 0x000000, 0xFFFFFF, + 0x009F62, 0x009F66, 0x000000, 0xFFFFFF, + 0x009F68, 0x009F69, 0x000000, 0xFFFFFF, + 0x009F6B, 0x009F6B, 0x000000, 0xFFFFFF, + 0x009F6D, 0x009F76, 0x000000, 0xFFFFFF, + 0x009F78, 0x009F8C, 0x000000, 0xFFFFFF, + 0x009F8E, 0x009F8F, 0x000000, 0xFFFFFF, + 0x009F91, 0x009F94, 0x000000, 0xFFFFFF, + 0x009F96, 0x009F9B, 0x000000, 0xFFFFFF, + 0x009F9D, 0x00ABFF, 0x000000, 0xFFFFFF, + 0x00AC02, 0x00AC03, 0x000000, 0xFFFFFF, + 0x00AC05, 0x00AC06, 0x000000, 0xFFFFFF, + 0x00AC0B, 0x00AC0F, 0x000000, 0xFFFFFF, + 0x00AC18, 0x00AC18, 0x000000, 0xFFFFFF, + 0x00AC1E, 0x00AC1F, 0x000000, 0xFFFFFF, + 0x00AC21, 0x00AC23, 0x000000, 0xFFFFFF, + 0x00AC25, 0x00AC2B, 0x000000, 0xFFFFFF, + 0x00AC2E, 0x00AC2E, 0x000000, 0xFFFFFF, + 0x00AC32, 0x00AC37, 0x000000, 0xFFFFFF, + 0x00AC3A, 0x00AC3B, 0x000000, 0xFFFFFF, + 0x00AC3D, 0x00AC3F, 0x000000, 0xFFFFFF, + 0x00AC41, 0x00AC4A, 0x000000, 0xFFFFFF, + 0x00AC4C, 0x00AC4C, 0x000000, 0xFFFFFF, + 0x00AC4E, 0x00AC53, 0x000000, 0xFFFFFF, + 0x00AC55, 0x00AC57, 0x000000, 0xFFFFFF, + 0x00AC59, 0x00AC5B, 0x000000, 0xFFFFFF, + 0x00AC5D, 0x00AC6F, 0x000000, 0xFFFFFF, + 0x00AC72, 0x00AC73, 0x000000, 0xFFFFFF, + 0x00AC75, 0x00AC76, 0x000000, 0xFFFFFF, + 0x00AC79, 0x00AC79, 0x000000, 0xFFFFFF, + 0x00AC7B, 0x00AC7F, 0x000000, 0xFFFFFF, + 0x00AC82, 0x00AC82, 0x000000, 0xFFFFFF, + 0x00AC87, 0x00AC88, 0x000000, 0xFFFFFF, + 0x00AC8D, 0x00AC8F, 0x000000, 0xFFFFFF, + 0x00AC91, 0x00AC93, 0x000000, 0xFFFFFF, + 0x00AC95, 0x00AC9B, 0x000000, 0xFFFFFF, + 0x00AC9E, 0x00AC9E, 0x000000, 0xFFFFFF, + 0x00ACA2, 0x00ACA7, 0x000000, 0xFFFFFF, + 0x00ACAB, 0x00ACAB, 0x000000, 0xFFFFFF, + 0x00ACAD, 0x00ACAE, 0x000000, 0xFFFFFF, + 0x00ACB1, 0x00ACB7, 0x000000, 0xFFFFFF, + 0x00ACBA, 0x00ACBA, 0x000000, 0xFFFFFF, + 0x00ACBE, 0x00ACC0, 0x000000, 0xFFFFFF, + 0x00ACC2, 0x00ACC3, 0x000000, 0xFFFFFF, + 0x00ACC5, 0x00ACC7, 0x000000, 0xFFFFFF, + 0x00ACC9, 0x00ACCB, 0x000000, 0xFFFFFF, + 0x00ACCD, 0x00ACD4, 0x000000, 0xFFFFFF, + 0x00ACD6, 0x00ACD6, 0x000000, 0xFFFFFF, + 0x00ACD8, 0x00ACDF, 0x000000, 0xFFFFFF, + 0x00ACE2, 0x00ACE3, 0x000000, 0xFFFFFF, + 0x00ACE5, 0x00ACE6, 0x000000, 0xFFFFFF, + 0x00ACE9, 0x00ACE9, 0x000000, 0xFFFFFF, + 0x00ACEB, 0x00ACEB, 0x000000, 0xFFFFFF, + 0x00ACED, 0x00ACEE, 0x000000, 0xFFFFFF, + 0x00ACF2, 0x00ACF2, 0x000000, 0xFFFFFF, + 0x00ACF4, 0x00ACF4, 0x000000, 0xFFFFFF, + 0x00ACF7, 0x00ACFB, 0x000000, 0xFFFFFF, + 0x00ACFE, 0x00ACFF, 0x000000, 0xFFFFFF, + 0x00AD01, 0x00AD03, 0x000000, 0xFFFFFF, + 0x00AD05, 0x00AD05, 0x000000, 0xFFFFFF, + 0x00AD07, 0x00AD0B, 0x000000, 0xFFFFFF, + 0x00AD0E, 0x00AD0E, 0x000000, 0xFFFFFF, + 0x00AD10, 0x00AD10, 0x000000, 0xFFFFFF, + 0x00AD12, 0x00AD17, 0x000000, 0xFFFFFF, + 0x00AD19, 0x00AD1B, 0x000000, 0xFFFFFF, + 0x00AD1D, 0x00AD1F, 0x000000, 0xFFFFFF, + 0x00AD21, 0x00AD28, 0x000000, 0xFFFFFF, + 0x00AD2A, 0x00AD2B, 0x000000, 0xFFFFFF, + 0x00AD2E, 0x00AD33, 0x000000, 0xFFFFFF, + 0x00AD36, 0x00AD37, 0x000000, 0xFFFFFF, + 0x00AD39, 0x00AD3B, 0x000000, 0xFFFFFF, + 0x00AD3D, 0x00AD43, 0x000000, 0xFFFFFF, + 0x00AD46, 0x00AD46, 0x000000, 0xFFFFFF, + 0x00AD48, 0x00AD48, 0x000000, 0xFFFFFF, + 0x00AD4A, 0x00AD4F, 0x000000, 0xFFFFFF, + 0x00AD51, 0x00AD53, 0x000000, 0xFFFFFF, + 0x00AD55, 0x00AD57, 0x000000, 0xFFFFFF, + 0x00AD59, 0x00AD60, 0x000000, 0xFFFFFF, + 0x00AD62, 0x00AD62, 0x000000, 0xFFFFFF, + 0x00AD64, 0x00AD6B, 0x000000, 0xFFFFFF, + 0x00AD6E, 0x00AD6F, 0x000000, 0xFFFFFF, + 0x00AD71, 0x00AD72, 0x000000, 0xFFFFFF, + 0x00AD77, 0x00AD7A, 0x000000, 0xFFFFFF, + 0x00AD7E, 0x00AD7E, 0x000000, 0xFFFFFF, + 0x00AD80, 0x00AD80, 0x000000, 0xFFFFFF, + 0x00AD83, 0x00AD87, 0x000000, 0xFFFFFF, + 0x00AD8A, 0x00AD8B, 0x000000, 0xFFFFFF, + 0x00AD8D, 0x00AD8F, 0x000000, 0xFFFFFF, + 0x00AD91, 0x00AD9B, 0x000000, 0xFFFFFF, + 0x00AD9E, 0x00ADA3, 0x000000, 0xFFFFFF, + 0x00ADA5, 0x00ADB6, 0x000000, 0xFFFFFF, + 0x00ADB8, 0x00ADBF, 0x000000, 0xFFFFFF, + 0x00ADC2, 0x00ADC3, 0x000000, 0xFFFFFF, + 0x00ADC5, 0x00ADC7, 0x000000, 0xFFFFFF, + 0x00ADC9, 0x00ADCF, 0x000000, 0xFFFFFF, + 0x00ADD2, 0x00ADD2, 0x000000, 0xFFFFFF, + 0x00ADD4, 0x00ADDB, 0x000000, 0xFFFFFF, + 0x00ADDD, 0x00ADDF, 0x000000, 0xFFFFFF, + 0x00ADE1, 0x00ADE3, 0x000000, 0xFFFFFF, + 0x00ADE5, 0x00ADF7, 0x000000, 0xFFFFFF, + 0x00ADFA, 0x00ADFB, 0x000000, 0xFFFFFF, + 0x00ADFD, 0x00ADFE, 0x000000, 0xFFFFFF, + 0x00AE02, 0x00AE07, 0x000000, 0xFFFFFF, + 0x00AE0A, 0x00AE0A, 0x000000, 0xFFFFFF, + 0x00AE0C, 0x00AE0C, 0x000000, 0xFFFFFF, + 0x00AE0E, 0x00AE13, 0x000000, 0xFFFFFF, + 0x00AE15, 0x00AE2F, 0x000000, 0xFFFFFF, + 0x00AE32, 0x00AE33, 0x000000, 0xFFFFFF, + 0x00AE35, 0x00AE36, 0x000000, 0xFFFFFF, + 0x00AE39, 0x00AE39, 0x000000, 0xFFFFFF, + 0x00AE3B, 0x00AE3F, 0x000000, 0xFFFFFF, + 0x00AE42, 0x00AE42, 0x000000, 0xFFFFFF, + 0x00AE44, 0x00AE44, 0x000000, 0xFFFFFF, + 0x00AE47, 0x00AE49, 0x000000, 0xFFFFFF, + 0x00AE4B, 0x00AE4B, 0x000000, 0xFFFFFF, + 0x00AE4F, 0x00AE4F, 0x000000, 0xFFFFFF, + 0x00AE51, 0x00AE53, 0x000000, 0xFFFFFF, + 0x00AE55, 0x00AE55, 0x000000, 0xFFFFFF, + 0x00AE57, 0x00AE5B, 0x000000, 0xFFFFFF, + 0x00AE5E, 0x00AE5E, 0x000000, 0xFFFFFF, + 0x00AE62, 0x00AE64, 0x000000, 0xFFFFFF, + 0x00AE66, 0x00AE67, 0x000000, 0xFFFFFF, + 0x00AE6A, 0x00AE6B, 0x000000, 0xFFFFFF, + 0x00AE6D, 0x00AE6F, 0x000000, 0xFFFFFF, + 0x00AE71, 0x00AE77, 0x000000, 0xFFFFFF, + 0x00AE7A, 0x00AE7A, 0x000000, 0xFFFFFF, + 0x00AE7E, 0x00AE83, 0x000000, 0xFFFFFF, + 0x00AE86, 0x00AE8B, 0x000000, 0xFFFFFF, + 0x00AE8D, 0x00AEBB, 0x000000, 0xFFFFFF, + 0x00AEBF, 0x00AEBF, 0x000000, 0xFFFFFF, + 0x00AEC1, 0x00AEC3, 0x000000, 0xFFFFFF, + 0x00AEC5, 0x00AECB, 0x000000, 0xFFFFFF, + 0x00AECE, 0x00AECE, 0x000000, 0xFFFFFF, + 0x00AED2, 0x00AED7, 0x000000, 0xFFFFFF, + 0x00AEDA, 0x00AEDB, 0x000000, 0xFFFFFF, + 0x00AEDD, 0x00AEE7, 0x000000, 0xFFFFFF, + 0x00AEE9, 0x00AEEA, 0x000000, 0xFFFFFF, + 0x00AEEC, 0x00AEEC, 0x000000, 0xFFFFFF, + 0x00AEEE, 0x00AEF3, 0x000000, 0xFFFFFF, + 0x00AEF5, 0x00AEF7, 0x000000, 0xFFFFFF, + 0x00AEF9, 0x00AEFB, 0x000000, 0xFFFFFF, + 0x00AEFD, 0x00AF06, 0x000000, 0xFFFFFF, + 0x00AF09, 0x00AF0C, 0x000000, 0xFFFFFF, + 0x00AF0E, 0x00AF0F, 0x000000, 0xFFFFFF, + 0x00AF11, 0x00AF2B, 0x000000, 0xFFFFFF, + 0x00AF2E, 0x00AF2F, 0x000000, 0xFFFFFF, + 0x00AF31, 0x00AF31, 0x000000, 0xFFFFFF, + 0x00AF33, 0x00AF33, 0x000000, 0xFFFFFF, + 0x00AF35, 0x00AF3B, 0x000000, 0xFFFFFF, + 0x00AF3E, 0x00AF3E, 0x000000, 0xFFFFFF, + 0x00AF40, 0x00AF40, 0x000000, 0xFFFFFF, + 0x00AF44, 0x00AF47, 0x000000, 0xFFFFFF, + 0x00AF4A, 0x00AF4F, 0x000000, 0xFFFFFF, + 0x00AF51, 0x00AF5B, 0x000000, 0xFFFFFF, + 0x00AF5E, 0x00AF63, 0x000000, 0xFFFFFF, + 0x00AF66, 0x00AF78, 0x000000, 0xFFFFFF, + 0x00AF7A, 0x00AF7F, 0x000000, 0xFFFFFF, + 0x00AF81, 0x00AF83, 0x000000, 0xFFFFFF, + 0x00AF85, 0x00AF87, 0x000000, 0xFFFFFF, + 0x00AF89, 0x00AF8F, 0x000000, 0xFFFFFF, + 0x00AF92, 0x00AF94, 0x000000, 0xFFFFFF, + 0x00AF96, 0x00AF9B, 0x000000, 0xFFFFFF, + 0x00AF9D, 0x00AFB7, 0x000000, 0xFFFFFF, + 0x00AFBA, 0x00AFBB, 0x000000, 0xFFFFFF, + 0x00AFBD, 0x00AFBF, 0x000000, 0xFFFFFF, + 0x00AFC1, 0x00AFC6, 0x000000, 0xFFFFFF, + 0x00AFCA, 0x00AFCA, 0x000000, 0xFFFFFF, + 0x00AFCC, 0x00AFCC, 0x000000, 0xFFFFFF, + 0x00AFCF, 0x00AFD3, 0x000000, 0xFFFFFF, + 0x00AFD5, 0x00AFDB, 0x000000, 0xFFFFFF, + 0x00AFDD, 0x00AFE7, 0x000000, 0xFFFFFF, + 0x00AFEA, 0x00AFEF, 0x000000, 0xFFFFFF, + 0x00AFF2, 0x00AFF3, 0x000000, 0xFFFFFF, + 0x00AFF5, 0x00AFF7, 0x000000, 0xFFFFFF, + 0x00AFF9, 0x00AFFF, 0x000000, 0xFFFFFF, + 0x00B002, 0x00B003, 0x000000, 0xFFFFFF, + 0x00B005, 0x00B00B, 0x000000, 0xFFFFFF, + 0x00B00D, 0x00B00F, 0x000000, 0xFFFFFF, + 0x00B011, 0x00B013, 0x000000, 0xFFFFFF, + 0x00B015, 0x00B01B, 0x000000, 0xFFFFFF, + 0x00B01E, 0x00B027, 0x000000, 0xFFFFFF, + 0x00B029, 0x00B043, 0x000000, 0xFFFFFF, + 0x00B046, 0x00B047, 0x000000, 0xFFFFFF, + 0x00B049, 0x00B049, 0x000000, 0xFFFFFF, + 0x00B04B, 0x00B04B, 0x000000, 0xFFFFFF, + 0x00B04D, 0x00B04D, 0x000000, 0xFFFFFF, + 0x00B04F, 0x00B052, 0x000000, 0xFFFFFF, + 0x00B056, 0x00B056, 0x000000, 0xFFFFFF, + 0x00B058, 0x00B058, 0x000000, 0xFFFFFF, + 0x00B05A, 0x00B05C, 0x000000, 0xFFFFFF, + 0x00B05E, 0x00B07B, 0x000000, 0xFFFFFF, + 0x00B07E, 0x00B07F, 0x000000, 0xFFFFFF, + 0x00B081, 0x00B083, 0x000000, 0xFFFFFF, + 0x00B085, 0x00B08B, 0x000000, 0xFFFFFF, + 0x00B08E, 0x00B08E, 0x000000, 0xFFFFFF, + 0x00B090, 0x00B090, 0x000000, 0xFFFFFF, + 0x00B092, 0x00B097, 0x000000, 0xFFFFFF, + 0x00B09B, 0x00B09B, 0x000000, 0xFFFFFF, + 0x00B09D, 0x00B09E, 0x000000, 0xFFFFFF, + 0x00B0A3, 0x00B0A7, 0x000000, 0xFFFFFF, + 0x00B0AA, 0x00B0AA, 0x000000, 0xFFFFFF, + 0x00B0B0, 0x00B0B0, 0x000000, 0xFFFFFF, + 0x00B0B2, 0x00B0B2, 0x000000, 0xFFFFFF, + 0x00B0B6, 0x00B0B7, 0x000000, 0xFFFFFF, + 0x00B0B9, 0x00B0BB, 0x000000, 0xFFFFFF, + 0x00B0BD, 0x00B0C3, 0x000000, 0xFFFFFF, + 0x00B0C6, 0x00B0C6, 0x000000, 0xFFFFFF, + 0x00B0CA, 0x00B0CF, 0x000000, 0xFFFFFF, + 0x00B0D2, 0x00B0D3, 0x000000, 0xFFFFFF, + 0x00B0D5, 0x00B0D7, 0x000000, 0xFFFFFF, + 0x00B0D9, 0x00B0DF, 0x000000, 0xFFFFFF, + 0x00B0E1, 0x00B0E4, 0x000000, 0xFFFFFF, + 0x00B0E6, 0x00B107, 0x000000, 0xFFFFFF, + 0x00B10A, 0x00B10A, 0x000000, 0xFFFFFF, + 0x00B10D, 0x00B10F, 0x000000, 0xFFFFFF, + 0x00B111, 0x00B111, 0x000000, 0xFFFFFF, + 0x00B114, 0x00B117, 0x000000, 0xFFFFFF, + 0x00B11A, 0x00B11A, 0x000000, 0xFFFFFF, + 0x00B11E, 0x00B122, 0x000000, 0xFFFFFF, + 0x00B126, 0x00B127, 0x000000, 0xFFFFFF, + 0x00B129, 0x00B12B, 0x000000, 0xFFFFFF, + 0x00B12D, 0x00B133, 0x000000, 0xFFFFFF, + 0x00B136, 0x00B136, 0x000000, 0xFFFFFF, + 0x00B13A, 0x00B13F, 0x000000, 0xFFFFFF, + 0x00B142, 0x00B143, 0x000000, 0xFFFFFF, + 0x00B145, 0x00B147, 0x000000, 0xFFFFFF, + 0x00B149, 0x00B14F, 0x000000, 0xFFFFFF, + 0x00B152, 0x00B153, 0x000000, 0xFFFFFF, + 0x00B156, 0x00B157, 0x000000, 0xFFFFFF, + 0x00B159, 0x00B15B, 0x000000, 0xFFFFFF, + 0x00B15D, 0x00B15F, 0x000000, 0xFFFFFF, + 0x00B161, 0x00B177, 0x000000, 0xFFFFFF, + 0x00B17A, 0x00B17B, 0x000000, 0xFFFFFF, + 0x00B17D, 0x00B17F, 0x000000, 0xFFFFFF, + 0x00B181, 0x00B181, 0x000000, 0xFFFFFF, + 0x00B183, 0x00B187, 0x000000, 0xFFFFFF, + 0x00B18A, 0x00B18A, 0x000000, 0xFFFFFF, + 0x00B18C, 0x00B18C, 0x000000, 0xFFFFFF, + 0x00B18E, 0x00B191, 0x000000, 0xFFFFFF, + 0x00B195, 0x00B197, 0x000000, 0xFFFFFF, + 0x00B199, 0x00B19B, 0x000000, 0xFFFFFF, + 0x00B19D, 0x00B1A7, 0x000000, 0xFFFFFF, + 0x00B1A9, 0x00B1CB, 0x000000, 0xFFFFFF, + 0x00B1CD, 0x00B1CF, 0x000000, 0xFFFFFF, + 0x00B1D1, 0x00B1D3, 0x000000, 0xFFFFFF, + 0x00B1D5, 0x00B1DB, 0x000000, 0xFFFFFF, + 0x00B1DE, 0x00B1DE, 0x000000, 0xFFFFFF, + 0x00B1E0, 0x00B1E7, 0x000000, 0xFFFFFF, + 0x00B1EA, 0x00B1EB, 0x000000, 0xFFFFFF, + 0x00B1ED, 0x00B1EF, 0x000000, 0xFFFFFF, + 0x00B1F1, 0x00B1F8, 0x000000, 0xFFFFFF, + 0x00B1FA, 0x00B1FA, 0x000000, 0xFFFFFF, + 0x00B1FC, 0x00B1FC, 0x000000, 0xFFFFFF, + 0x00B1FE, 0x00B203, 0x000000, 0xFFFFFF, + 0x00B206, 0x00B207, 0x000000, 0xFFFFFF, + 0x00B209, 0x00B20A, 0x000000, 0xFFFFFF, + 0x00B20D, 0x00B213, 0x000000, 0xFFFFFF, + 0x00B216, 0x00B216, 0x000000, 0xFFFFFF, + 0x00B218, 0x00B218, 0x000000, 0xFFFFFF, + 0x00B21A, 0x00B21F, 0x000000, 0xFFFFFF, + 0x00B221, 0x00B233, 0x000000, 0xFFFFFF, + 0x00B235, 0x00B23B, 0x000000, 0xFFFFFF, + 0x00B23D, 0x00B257, 0x000000, 0xFFFFFF, + 0x00B259, 0x00B25B, 0x000000, 0xFFFFFF, + 0x00B25D, 0x00B25F, 0x000000, 0xFFFFFF, + 0x00B261, 0x00B267, 0x000000, 0xFFFFFF, + 0x00B26A, 0x00B273, 0x000000, 0xFFFFFF, + 0x00B276, 0x00B27B, 0x000000, 0xFFFFFF, + 0x00B27D, 0x00B283, 0x000000, 0xFFFFFF, + 0x00B286, 0x00B288, 0x000000, 0xFFFFFF, + 0x00B28A, 0x00B28F, 0x000000, 0xFFFFFF, + 0x00B292, 0x00B293, 0x000000, 0xFFFFFF, + 0x00B295, 0x00B297, 0x000000, 0xFFFFFF, + 0x00B29B, 0x00B29F, 0x000000, 0xFFFFFF, + 0x00B2A2, 0x00B2A2, 0x000000, 0xFFFFFF, + 0x00B2A4, 0x00B2A4, 0x000000, 0xFFFFFF, + 0x00B2A7, 0x00B2A9, 0x000000, 0xFFFFFF, + 0x00B2AB, 0x00B2AB, 0x000000, 0xFFFFFF, + 0x00B2AD, 0x00B2AF, 0x000000, 0xFFFFFF, + 0x00B2B1, 0x00B2B3, 0x000000, 0xFFFFFF, + 0x00B2B5, 0x00B2C7, 0x000000, 0xFFFFFF, + 0x00B2CA, 0x00B2CB, 0x000000, 0xFFFFFF, + 0x00B2CD, 0x00B2CF, 0x000000, 0xFFFFFF, + 0x00B2D1, 0x00B2D1, 0x000000, 0xFFFFFF, + 0x00B2D3, 0x00B2D7, 0x000000, 0xFFFFFF, + 0x00B2DA, 0x00B2DA, 0x000000, 0xFFFFFF, + 0x00B2DC, 0x00B2DC, 0x000000, 0xFFFFFF, + 0x00B2DE, 0x00B2E1, 0x000000, 0xFFFFFF, + 0x00B2E3, 0x00B2E3, 0x000000, 0xFFFFFF, + 0x00B2E7, 0x00B2E7, 0x000000, 0xFFFFFF, + 0x00B2E9, 0x00B2EA, 0x000000, 0xFFFFFF, + 0x00B2F0, 0x00B2F2, 0x000000, 0xFFFFFF, + 0x00B2F6, 0x00B2F6, 0x000000, 0xFFFFFF, + 0x00B2FC, 0x00B2FE, 0x000000, 0xFFFFFF, + 0x00B302, 0x00B303, 0x000000, 0xFFFFFF, + 0x00B305, 0x00B307, 0x000000, 0xFFFFFF, + 0x00B309, 0x00B30F, 0x000000, 0xFFFFFF, + 0x00B312, 0x00B312, 0x000000, 0xFFFFFF, + 0x00B316, 0x00B31B, 0x000000, 0xFFFFFF, + 0x00B31D, 0x00B353, 0x000000, 0xFFFFFF, + 0x00B357, 0x00B357, 0x000000, 0xFFFFFF, + 0x00B359, 0x00B35A, 0x000000, 0xFFFFFF, + 0x00B35D, 0x00B35D, 0x000000, 0xFFFFFF, + 0x00B360, 0x00B363, 0x000000, 0xFFFFFF, + 0x00B366, 0x00B366, 0x000000, 0xFFFFFF, + 0x00B368, 0x00B368, 0x000000, 0xFFFFFF, + 0x00B36A, 0x00B36A, 0x000000, 0xFFFFFF, + 0x00B36C, 0x00B36D, 0x000000, 0xFFFFFF, + 0x00B36F, 0x00B36F, 0x000000, 0xFFFFFF, + 0x00B372, 0x00B373, 0x000000, 0xFFFFFF, + 0x00B375, 0x00B377, 0x000000, 0xFFFFFF, + 0x00B379, 0x00B37F, 0x000000, 0xFFFFFF, + 0x00B382, 0x00B382, 0x000000, 0xFFFFFF, + 0x00B386, 0x00B38B, 0x000000, 0xFFFFFF, + 0x00B38D, 0x00B38F, 0x000000, 0xFFFFFF, + 0x00B391, 0x00B393, 0x000000, 0xFFFFFF, + 0x00B395, 0x00B39F, 0x000000, 0xFFFFFF, + 0x00B3A2, 0x00B3A7, 0x000000, 0xFFFFFF, + 0x00B3A9, 0x00B3AB, 0x000000, 0xFFFFFF, + 0x00B3AD, 0x00B3C3, 0x000000, 0xFFFFFF, + 0x00B3C6, 0x00B3C7, 0x000000, 0xFFFFFF, + 0x00B3C9, 0x00B3CA, 0x000000, 0xFFFFFF, + 0x00B3CD, 0x00B3CD, 0x000000, 0xFFFFFF, + 0x00B3CF, 0x00B3CF, 0x000000, 0xFFFFFF, + 0x00B3D1, 0x00B3D3, 0x000000, 0xFFFFFF, + 0x00B3D6, 0x00B3D6, 0x000000, 0xFFFFFF, + 0x00B3D8, 0x00B3D8, 0x000000, 0xFFFFFF, + 0x00B3DA, 0x00B3DA, 0x000000, 0xFFFFFF, + 0x00B3DC, 0x00B3DC, 0x000000, 0xFFFFFF, + 0x00B3DE, 0x00B3DF, 0x000000, 0xFFFFFF, + 0x00B3E1, 0x00B3E3, 0x000000, 0xFFFFFF, + 0x00B3E5, 0x00B3E7, 0x000000, 0xFFFFFF, + 0x00B3E9, 0x00B3FB, 0x000000, 0xFFFFFF, + 0x00B3FD, 0x00B40F, 0x000000, 0xFFFFFF, + 0x00B411, 0x00B417, 0x000000, 0xFFFFFF, + 0x00B419, 0x00B41B, 0x000000, 0xFFFFFF, + 0x00B41D, 0x00B41F, 0x000000, 0xFFFFFF, + 0x00B421, 0x00B427, 0x000000, 0xFFFFFF, + 0x00B42A, 0x00B42A, 0x000000, 0xFFFFFF, + 0x00B42C, 0x00B433, 0x000000, 0xFFFFFF, + 0x00B435, 0x00B44F, 0x000000, 0xFFFFFF, + 0x00B452, 0x00B453, 0x000000, 0xFFFFFF, + 0x00B455, 0x00B457, 0x000000, 0xFFFFFF, + 0x00B459, 0x00B45F, 0x000000, 0xFFFFFF, + 0x00B462, 0x00B462, 0x000000, 0xFFFFFF, + 0x00B464, 0x00B464, 0x000000, 0xFFFFFF, + 0x00B466, 0x00B46B, 0x000000, 0xFFFFFF, + 0x00B46D, 0x00B47F, 0x000000, 0xFFFFFF, + 0x00B481, 0x00B487, 0x000000, 0xFFFFFF, + 0x00B489, 0x00B49C, 0x000000, 0xFFFFFF, + 0x00B49E, 0x00B4A3, 0x000000, 0xFFFFFF, + 0x00B4A5, 0x00B4A7, 0x000000, 0xFFFFFF, + 0x00B4A9, 0x00B4AB, 0x000000, 0xFFFFFF, + 0x00B4AD, 0x00B4B4, 0x000000, 0xFFFFFF, + 0x00B4B6, 0x00B4B6, 0x000000, 0xFFFFFF, + 0x00B4B8, 0x00B4B8, 0x000000, 0xFFFFFF, + 0x00B4BA, 0x00B4BF, 0x000000, 0xFFFFFF, + 0x00B4C1, 0x00B4C3, 0x000000, 0xFFFFFF, + 0x00B4C5, 0x00B4C7, 0x000000, 0xFFFFFF, + 0x00B4C9, 0x00B4CF, 0x000000, 0xFFFFFF, + 0x00B4D1, 0x00B4D4, 0x000000, 0xFFFFFF, + 0x00B4D6, 0x00B4DB, 0x000000, 0xFFFFFF, + 0x00B4DE, 0x00B4DF, 0x000000, 0xFFFFFF, + 0x00B4E1, 0x00B4E2, 0x000000, 0xFFFFFF, + 0x00B4E5, 0x00B4E5, 0x000000, 0xFFFFFF, + 0x00B4E7, 0x00B4EB, 0x000000, 0xFFFFFF, + 0x00B4EE, 0x00B4EE, 0x000000, 0xFFFFFF, + 0x00B4F0, 0x00B4F0, 0x000000, 0xFFFFFF, + 0x00B4F2, 0x00B4F7, 0x000000, 0xFFFFFF, + 0x00B4F9, 0x00B513, 0x000000, 0xFFFFFF, + 0x00B516, 0x00B517, 0x000000, 0xFFFFFF, + 0x00B519, 0x00B51A, 0x000000, 0xFFFFFF, + 0x00B51D, 0x00B523, 0x000000, 0xFFFFFF, + 0x00B526, 0x00B526, 0x000000, 0xFFFFFF, + 0x00B52B, 0x00B52F, 0x000000, 0xFFFFFF, + 0x00B532, 0x00B533, 0x000000, 0xFFFFFF, + 0x00B535, 0x00B537, 0x000000, 0xFFFFFF, + 0x00B539, 0x00B53F, 0x000000, 0xFFFFFF, + 0x00B542, 0x00B542, 0x000000, 0xFFFFFF, + 0x00B546, 0x00B54A, 0x000000, 0xFFFFFF, + 0x00B54E, 0x00B54F, 0x000000, 0xFFFFFF, + 0x00B551, 0x00B553, 0x000000, 0xFFFFFF, + 0x00B555, 0x00B55B, 0x000000, 0xFFFFFF, + 0x00B55E, 0x00B55E, 0x000000, 0xFFFFFF, + 0x00B562, 0x00B59F, 0x000000, 0xFFFFFF, + 0x00B5A2, 0x00B5A3, 0x000000, 0xFFFFFF, + 0x00B5A5, 0x00B5A7, 0x000000, 0xFFFFFF, + 0x00B5A9, 0x00B5A9, 0x000000, 0xFFFFFF, + 0x00B5AC, 0x00B5AF, 0x000000, 0xFFFFFF, + 0x00B5B2, 0x00B5B2, 0x000000, 0xFFFFFF, + 0x00B5B6, 0x00B5BA, 0x000000, 0xFFFFFF, + 0x00B5BE, 0x00B5BF, 0x000000, 0xFFFFFF, + 0x00B5C1, 0x00B5C3, 0x000000, 0xFFFFFF, + 0x00B5C5, 0x00B5CB, 0x000000, 0xFFFFFF, + 0x00B5CE, 0x00B5CE, 0x000000, 0xFFFFFF, + 0x00B5D2, 0x00B5D7, 0x000000, 0xFFFFFF, + 0x00B5D9, 0x00B5EB, 0x000000, 0xFFFFFF, + 0x00B5ED, 0x00B60F, 0x000000, 0xFFFFFF, + 0x00B612, 0x00B613, 0x000000, 0xFFFFFF, + 0x00B615, 0x00B617, 0x000000, 0xFFFFFF, + 0x00B619, 0x00B624, 0x000000, 0xFFFFFF, + 0x00B626, 0x00B62B, 0x000000, 0xFFFFFF, + 0x00B62D, 0x00B633, 0x000000, 0xFFFFFF, + 0x00B635, 0x00B647, 0x000000, 0xFFFFFF, + 0x00B649, 0x00B663, 0x000000, 0xFFFFFF, + 0x00B665, 0x00B667, 0x000000, 0xFFFFFF, + 0x00B669, 0x00B69B, 0x000000, 0xFFFFFF, + 0x00B69E, 0x00B69F, 0x000000, 0xFFFFFF, + 0x00B6A1, 0x00B6A3, 0x000000, 0xFFFFFF, + 0x00B6A5, 0x00B6AA, 0x000000, 0xFFFFFF, + 0x00B6AD, 0x00B6B0, 0x000000, 0xFFFFFF, + 0x00B6B2, 0x00B6D3, 0x000000, 0xFFFFFF, + 0x00B6D5, 0x00B6EF, 0x000000, 0xFFFFFF, + 0x00B6F1, 0x00B6F3, 0x000000, 0xFFFFFF, + 0x00B6F5, 0x00B6F7, 0x000000, 0xFFFFFF, + 0x00B6F9, 0x00B6FF, 0x000000, 0xFFFFFF, + 0x00B702, 0x00B704, 0x000000, 0xFFFFFF, + 0x00B706, 0x00B727, 0x000000, 0xFFFFFF, + 0x00B72A, 0x00B72B, 0x000000, 0xFFFFFF, + 0x00B72D, 0x00B72E, 0x000000, 0xFFFFFF, + 0x00B731, 0x00B737, 0x000000, 0xFFFFFF, + 0x00B73A, 0x00B73A, 0x000000, 0xFFFFFF, + 0x00B73C, 0x00B743, 0x000000, 0xFFFFFF, + 0x00B745, 0x00B747, 0x000000, 0xFFFFFF, + 0x00B749, 0x00B74B, 0x000000, 0xFFFFFF, + 0x00B74D, 0x00B753, 0x000000, 0xFFFFFF, + 0x00B756, 0x00B75F, 0x000000, 0xFFFFFF, + 0x00B761, 0x00B763, 0x000000, 0xFFFFFF, + 0x00B765, 0x00B767, 0x000000, 0xFFFFFF, + 0x00B769, 0x00B76F, 0x000000, 0xFFFFFF, + 0x00B772, 0x00B772, 0x000000, 0xFFFFFF, + 0x00B774, 0x00B774, 0x000000, 0xFFFFFF, + 0x00B776, 0x00B77B, 0x000000, 0xFFFFFF, + 0x00B77E, 0x00B77F, 0x000000, 0xFFFFFF, + 0x00B781, 0x00B783, 0x000000, 0xFFFFFF, + 0x00B785, 0x00B78B, 0x000000, 0xFFFFFF, + 0x00B78E, 0x00B78E, 0x000000, 0xFFFFFF, + 0x00B793, 0x00B795, 0x000000, 0xFFFFFF, + 0x00B79A, 0x00B79B, 0x000000, 0xFFFFFF, + 0x00B79D, 0x00B79F, 0x000000, 0xFFFFFF, + 0x00B7A1, 0x00B7A7, 0x000000, 0xFFFFFF, + 0x00B7AA, 0x00B7AA, 0x000000, 0xFFFFFF, + 0x00B7AE, 0x00B7B3, 0x000000, 0xFFFFFF, + 0x00B7B6, 0x00B7B7, 0x000000, 0xFFFFFF, + 0x00B7B9, 0x00B7C6, 0x000000, 0xFFFFFF, + 0x00B7C8, 0x00B7C8, 0x000000, 0xFFFFFF, + 0x00B7CA, 0x00B7EB, 0x000000, 0xFFFFFF, + 0x00B7EE, 0x00B7EF, 0x000000, 0xFFFFFF, + 0x00B7F1, 0x00B7F3, 0x000000, 0xFFFFFF, + 0x00B7F5, 0x00B7FB, 0x000000, 0xFFFFFF, + 0x00B7FE, 0x00B7FE, 0x000000, 0xFFFFFF, + 0x00B802, 0x00B806, 0x000000, 0xFFFFFF, + 0x00B80A, 0x00B80B, 0x000000, 0xFFFFFF, + 0x00B80D, 0x00B80F, 0x000000, 0xFFFFFF, + 0x00B811, 0x00B817, 0x000000, 0xFFFFFF, + 0x00B81A, 0x00B81A, 0x000000, 0xFFFFFF, + 0x00B81C, 0x00B81C, 0x000000, 0xFFFFFF, + 0x00B81E, 0x00B823, 0x000000, 0xFFFFFF, + 0x00B826, 0x00B827, 0x000000, 0xFFFFFF, + 0x00B829, 0x00B82B, 0x000000, 0xFFFFFF, + 0x00B82D, 0x00B833, 0x000000, 0xFFFFFF, + 0x00B836, 0x00B836, 0x000000, 0xFFFFFF, + 0x00B83A, 0x00B83F, 0x000000, 0xFFFFFF, + 0x00B841, 0x00B843, 0x000000, 0xFFFFFF, + 0x00B845, 0x00B850, 0x000000, 0xFFFFFF, + 0x00B852, 0x00B852, 0x000000, 0xFFFFFF, + 0x00B854, 0x00B85B, 0x000000, 0xFFFFFF, + 0x00B85E, 0x00B85F, 0x000000, 0xFFFFFF, + 0x00B861, 0x00B863, 0x000000, 0xFFFFFF, + 0x00B865, 0x00B86B, 0x000000, 0xFFFFFF, + 0x00B86E, 0x00B86E, 0x000000, 0xFFFFFF, + 0x00B870, 0x00B870, 0x000000, 0xFFFFFF, + 0x00B872, 0x00B877, 0x000000, 0xFFFFFF, + 0x00B879, 0x00B87B, 0x000000, 0xFFFFFF, + 0x00B87D, 0x00B88C, 0x000000, 0xFFFFFF, + 0x00B88E, 0x00B8A7, 0x000000, 0xFFFFFF, + 0x00B8A9, 0x00B8AF, 0x000000, 0xFFFFFF, + 0x00B8B1, 0x00B8B3, 0x000000, 0xFFFFFF, + 0x00B8B5, 0x00B8B7, 0x000000, 0xFFFFFF, + 0x00B8B9, 0x00B8BF, 0x000000, 0xFFFFFF, + 0x00B8C2, 0x00B8C2, 0x000000, 0xFFFFFF, + 0x00B8C4, 0x00B8C4, 0x000000, 0xFFFFFF, + 0x00B8C6, 0x00B8CB, 0x000000, 0xFFFFFF, + 0x00B8CD, 0x00B8CF, 0x000000, 0xFFFFFF, + 0x00B8D1, 0x00B8D3, 0x000000, 0xFFFFFF, + 0x00B8D5, 0x00B8DC, 0x000000, 0xFFFFFF, + 0x00B8DE, 0x00B8DE, 0x000000, 0xFFFFFF, + 0x00B8E0, 0x00B8E0, 0x000000, 0xFFFFFF, + 0x00B8E2, 0x00B8E7, 0x000000, 0xFFFFFF, + 0x00B8EA, 0x00B8EB, 0x000000, 0xFFFFFF, + 0x00B8ED, 0x00B8EF, 0x000000, 0xFFFFFF, + 0x00B8F1, 0x00B8F7, 0x000000, 0xFFFFFF, + 0x00B8FA, 0x00B8FA, 0x000000, 0xFFFFFF, + 0x00B8FC, 0x00B8FC, 0x000000, 0xFFFFFF, + 0x00B8FE, 0x00B903, 0x000000, 0xFFFFFF, + 0x00B905, 0x00B917, 0x000000, 0xFFFFFF, + 0x00B919, 0x00B91F, 0x000000, 0xFFFFFF, + 0x00B921, 0x00B93B, 0x000000, 0xFFFFFF, + 0x00B93E, 0x00B93F, 0x000000, 0xFFFFFF, + 0x00B941, 0x00B943, 0x000000, 0xFFFFFF, + 0x00B945, 0x00B94B, 0x000000, 0xFFFFFF, + 0x00B94D, 0x00B94E, 0x000000, 0xFFFFFF, + 0x00B950, 0x00B950, 0x000000, 0xFFFFFF, + 0x00B952, 0x00B957, 0x000000, 0xFFFFFF, + 0x00B95A, 0x00B95B, 0x000000, 0xFFFFFF, + 0x00B95D, 0x00B95F, 0x000000, 0xFFFFFF, + 0x00B961, 0x00B967, 0x000000, 0xFFFFFF, + 0x00B96A, 0x00B96A, 0x000000, 0xFFFFFF, + 0x00B96C, 0x00B96C, 0x000000, 0xFFFFFF, + 0x00B96E, 0x00B973, 0x000000, 0xFFFFFF, + 0x00B976, 0x00B977, 0x000000, 0xFFFFFF, + 0x00B979, 0x00B97B, 0x000000, 0xFFFFFF, + 0x00B97D, 0x00B983, 0x000000, 0xFFFFFF, + 0x00B986, 0x00B986, 0x000000, 0xFFFFFF, + 0x00B988, 0x00B988, 0x000000, 0xFFFFFF, + 0x00B98B, 0x00B98C, 0x000000, 0xFFFFFF, + 0x00B98F, 0x00B9AB, 0x000000, 0xFFFFFF, + 0x00B9AE, 0x00B9AF, 0x000000, 0xFFFFFF, + 0x00B9B1, 0x00B9B3, 0x000000, 0xFFFFFF, + 0x00B9B5, 0x00B9BB, 0x000000, 0xFFFFFF, + 0x00B9BE, 0x00B9BE, 0x000000, 0xFFFFFF, + 0x00B9C0, 0x00B9C0, 0x000000, 0xFFFFFF, + 0x00B9C2, 0x00B9C7, 0x000000, 0xFFFFFF, + 0x00B9CA, 0x00B9CB, 0x000000, 0xFFFFFF, + 0x00B9CD, 0x00B9CD, 0x000000, 0xFFFFFF, + 0x00B9D3, 0x00B9D7, 0x000000, 0xFFFFFF, + 0x00B9DA, 0x00B9DA, 0x000000, 0xFFFFFF, + 0x00B9DC, 0x00B9DC, 0x000000, 0xFFFFFF, + 0x00B9DF, 0x00B9E0, 0x000000, 0xFFFFFF, + 0x00B9E2, 0x00B9E2, 0x000000, 0xFFFFFF, + 0x00B9E6, 0x00B9E7, 0x000000, 0xFFFFFF, + 0x00B9E9, 0x00B9EB, 0x000000, 0xFFFFFF, + 0x00B9ED, 0x00B9F3, 0x000000, 0xFFFFFF, + 0x00B9F6, 0x00B9F6, 0x000000, 0xFFFFFF, + 0x00B9FB, 0x00B9FF, 0x000000, 0xFFFFFF, + 0x00BA02, 0x00BA07, 0x000000, 0xFFFFFF, + 0x00BA09, 0x00BA14, 0x000000, 0xFFFFFF, + 0x00BA16, 0x00BA37, 0x000000, 0xFFFFFF, + 0x00BA3A, 0x00BA3B, 0x000000, 0xFFFFFF, + 0x00BA3D, 0x00BA3F, 0x000000, 0xFFFFFF, + 0x00BA41, 0x00BA41, 0x000000, 0xFFFFFF, + 0x00BA43, 0x00BA47, 0x000000, 0xFFFFFF, + 0x00BA4A, 0x00BA4A, 0x000000, 0xFFFFFF, + 0x00BA4C, 0x00BA4C, 0x000000, 0xFFFFFF, + 0x00BA4F, 0x00BA52, 0x000000, 0xFFFFFF, + 0x00BA56, 0x00BA57, 0x000000, 0xFFFFFF, + 0x00BA59, 0x00BA5B, 0x000000, 0xFFFFFF, + 0x00BA5D, 0x00BA63, 0x000000, 0xFFFFFF, + 0x00BA66, 0x00BA66, 0x000000, 0xFFFFFF, + 0x00BA6A, 0x00BA6F, 0x000000, 0xFFFFFF, + 0x00BA72, 0x00BA73, 0x000000, 0xFFFFFF, + 0x00BA75, 0x00BA77, 0x000000, 0xFFFFFF, + 0x00BA79, 0x00BA82, 0x000000, 0xFFFFFF, + 0x00BA86, 0x00BA86, 0x000000, 0xFFFFFF, + 0x00BA88, 0x00BA8B, 0x000000, 0xFFFFFF, + 0x00BA8D, 0x00BAA7, 0x000000, 0xFFFFFF, + 0x00BAAA, 0x00BAAA, 0x000000, 0xFFFFFF, + 0x00BAAD, 0x00BAAF, 0x000000, 0xFFFFFF, + 0x00BAB1, 0x00BAB1, 0x000000, 0xFFFFFF, + 0x00BAB3, 0x00BAB7, 0x000000, 0xFFFFFF, + 0x00BABA, 0x00BABA, 0x000000, 0xFFFFFF, + 0x00BABC, 0x00BABC, 0x000000, 0xFFFFFF, + 0x00BABE, 0x00BAC3, 0x000000, 0xFFFFFF, + 0x00BAC5, 0x00BAC7, 0x000000, 0xFFFFFF, + 0x00BAC9, 0x00BAD7, 0x000000, 0xFFFFFF, + 0x00BADA, 0x00BAFB, 0x000000, 0xFFFFFF, + 0x00BAFD, 0x00BAFF, 0x000000, 0xFFFFFF, + 0x00BB01, 0x00BB03, 0x000000, 0xFFFFFF, + 0x00BB05, 0x00BB0C, 0x000000, 0xFFFFFF, + 0x00BB0E, 0x00BB0E, 0x000000, 0xFFFFFF, + 0x00BB10, 0x00BB10, 0x000000, 0xFFFFFF, + 0x00BB12, 0x00BB17, 0x000000, 0xFFFFFF, + 0x00BB19, 0x00BB1B, 0x000000, 0xFFFFFF, + 0x00BB1D, 0x00BB1F, 0x000000, 0xFFFFFF, + 0x00BB21, 0x00BB28, 0x000000, 0xFFFFFF, + 0x00BB2A, 0x00BB2A, 0x000000, 0xFFFFFF, + 0x00BB2C, 0x00BB33, 0x000000, 0xFFFFFF, + 0x00BB37, 0x00BB37, 0x000000, 0xFFFFFF, + 0x00BB39, 0x00BB3A, 0x000000, 0xFFFFFF, + 0x00BB3F, 0x00BB43, 0x000000, 0xFFFFFF, + 0x00BB46, 0x00BB46, 0x000000, 0xFFFFFF, + 0x00BB48, 0x00BB48, 0x000000, 0xFFFFFF, + 0x00BB4A, 0x00BB4C, 0x000000, 0xFFFFFF, + 0x00BB4E, 0x00BB4E, 0x000000, 0xFFFFFF, + 0x00BB51, 0x00BB53, 0x000000, 0xFFFFFF, + 0x00BB55, 0x00BB57, 0x000000, 0xFFFFFF, + 0x00BB59, 0x00BB60, 0x000000, 0xFFFFFF, + 0x00BB62, 0x00BB62, 0x000000, 0xFFFFFF, + 0x00BB64, 0x00BB6B, 0x000000, 0xFFFFFF, + 0x00BB6D, 0x00BB87, 0x000000, 0xFFFFFF, + 0x00BB89, 0x00BB8B, 0x000000, 0xFFFFFF, + 0x00BB8D, 0x00BB8F, 0x000000, 0xFFFFFF, + 0x00BB91, 0x00BBA3, 0x000000, 0xFFFFFF, + 0x00BBA5, 0x00BBA7, 0x000000, 0xFFFFFF, + 0x00BBA9, 0x00BBAB, 0x000000, 0xFFFFFF, + 0x00BBAD, 0x00BBB3, 0x000000, 0xFFFFFF, + 0x00BBB5, 0x00BBB6, 0x000000, 0xFFFFFF, + 0x00BBB8, 0x00BBBF, 0x000000, 0xFFFFFF, + 0x00BBC1, 0x00BBC3, 0x000000, 0xFFFFFF, + 0x00BBC5, 0x00BBC7, 0x000000, 0xFFFFFF, + 0x00BBC9, 0x00BBCF, 0x000000, 0xFFFFFF, + 0x00BBD1, 0x00BBD2, 0x000000, 0xFFFFFF, + 0x00BBD4, 0x00BBF7, 0x000000, 0xFFFFFF, + 0x00BBFA, 0x00BBFB, 0x000000, 0xFFFFFF, + 0x00BBFD, 0x00BBFE, 0x000000, 0xFFFFFF, + 0x00BC01, 0x00BC01, 0x000000, 0xFFFFFF, + 0x00BC03, 0x00BC07, 0x000000, 0xFFFFFF, + 0x00BC0A, 0x00BC0A, 0x000000, 0xFFFFFF, + 0x00BC0E, 0x00BC0E, 0x000000, 0xFFFFFF, + 0x00BC10, 0x00BC10, 0x000000, 0xFFFFFF, + 0x00BC12, 0x00BC13, 0x000000, 0xFFFFFF, + 0x00BC19, 0x00BC1A, 0x000000, 0xFFFFFF, + 0x00BC20, 0x00BC23, 0x000000, 0xFFFFFF, + 0x00BC26, 0x00BC26, 0x000000, 0xFFFFFF, + 0x00BC28, 0x00BC28, 0x000000, 0xFFFFFF, + 0x00BC2A, 0x00BC2C, 0x000000, 0xFFFFFF, + 0x00BC2E, 0x00BC2F, 0x000000, 0xFFFFFF, + 0x00BC32, 0x00BC33, 0x000000, 0xFFFFFF, + 0x00BC35, 0x00BC37, 0x000000, 0xFFFFFF, + 0x00BC39, 0x00BC3F, 0x000000, 0xFFFFFF, + 0x00BC42, 0x00BC42, 0x000000, 0xFFFFFF, + 0x00BC46, 0x00BC48, 0x000000, 0xFFFFFF, + 0x00BC4A, 0x00BC4B, 0x000000, 0xFFFFFF, + 0x00BC4E, 0x00BC4F, 0x000000, 0xFFFFFF, + 0x00BC51, 0x00BC5C, 0x000000, 0xFFFFFF, + 0x00BC5E, 0x00BC83, 0x000000, 0xFFFFFF, + 0x00BC86, 0x00BC87, 0x000000, 0xFFFFFF, + 0x00BC89, 0x00BC8A, 0x000000, 0xFFFFFF, + 0x00BC8D, 0x00BC8D, 0x000000, 0xFFFFFF, + 0x00BC8F, 0x00BC93, 0x000000, 0xFFFFFF, + 0x00BC96, 0x00BC96, 0x000000, 0xFFFFFF, + 0x00BC98, 0x00BC98, 0x000000, 0xFFFFFF, + 0x00BC9B, 0x00BC9F, 0x000000, 0xFFFFFF, + 0x00BCA2, 0x00BCA3, 0x000000, 0xFFFFFF, + 0x00BCA5, 0x00BCA6, 0x000000, 0xFFFFFF, + 0x00BCA9, 0x00BCAF, 0x000000, 0xFFFFFF, + 0x00BCB2, 0x00BCB2, 0x000000, 0xFFFFFF, + 0x00BCB6, 0x00BCBB, 0x000000, 0xFFFFFF, + 0x00BCBE, 0x00BCBF, 0x000000, 0xFFFFFF, + 0x00BCC1, 0x00BCC3, 0x000000, 0xFFFFFF, + 0x00BCC5, 0x00BCCC, 0x000000, 0xFFFFFF, + 0x00BCCE, 0x00BCCE, 0x000000, 0xFFFFFF, + 0x00BCD2, 0x00BCD4, 0x000000, 0xFFFFFF, + 0x00BCD6, 0x00BCD7, 0x000000, 0xFFFFFF, + 0x00BCD9, 0x00BCDB, 0x000000, 0xFFFFFF, + 0x00BCDD, 0x00BCF3, 0x000000, 0xFFFFFF, + 0x00BCF7, 0x00BCF7, 0x000000, 0xFFFFFF, + 0x00BCF9, 0x00BCFB, 0x000000, 0xFFFFFF, + 0x00BCFD, 0x00BD03, 0x000000, 0xFFFFFF, + 0x00BD06, 0x00BD06, 0x000000, 0xFFFFFF, + 0x00BD08, 0x00BD08, 0x000000, 0xFFFFFF, + 0x00BD0A, 0x00BD0F, 0x000000, 0xFFFFFF, + 0x00BD11, 0x00BD13, 0x000000, 0xFFFFFF, + 0x00BD15, 0x00BD23, 0x000000, 0xFFFFFF, + 0x00BD25, 0x00BD2B, 0x000000, 0xFFFFFF, + 0x00BD2D, 0x00BD3F, 0x000000, 0xFFFFFF, + 0x00BD41, 0x00BD47, 0x000000, 0xFFFFFF, + 0x00BD4A, 0x00BD4B, 0x000000, 0xFFFFFF, + 0x00BD4D, 0x00BD4F, 0x000000, 0xFFFFFF, + 0x00BD51, 0x00BD57, 0x000000, 0xFFFFFF, + 0x00BD5A, 0x00BD63, 0x000000, 0xFFFFFF, + 0x00BD65, 0x00BD67, 0x000000, 0xFFFFFF, + 0x00BD69, 0x00BD7F, 0x000000, 0xFFFFFF, + 0x00BD82, 0x00BD83, 0x000000, 0xFFFFFF, + 0x00BD85, 0x00BD86, 0x000000, 0xFFFFFF, + 0x00BD8B, 0x00BD8F, 0x000000, 0xFFFFFF, + 0x00BD92, 0x00BD92, 0x000000, 0xFFFFFF, + 0x00BD94, 0x00BD94, 0x000000, 0xFFFFFF, + 0x00BD96, 0x00BD98, 0x000000, 0xFFFFFF, + 0x00BD9B, 0x00BD9B, 0x000000, 0xFFFFFF, + 0x00BD9D, 0x00BDA3, 0x000000, 0xFFFFFF, + 0x00BDA5, 0x00BDAF, 0x000000, 0xFFFFFF, + 0x00BDB1, 0x00BDB7, 0x000000, 0xFFFFFF, + 0x00BDB9, 0x00BDD3, 0x000000, 0xFFFFFF, + 0x00BDD6, 0x00BDD7, 0x000000, 0xFFFFFF, + 0x00BDD9, 0x00BDDB, 0x000000, 0xFFFFFF, + 0x00BDDD, 0x00BDE8, 0x000000, 0xFFFFFF, + 0x00BDEA, 0x00BDEF, 0x000000, 0xFFFFFF, + 0x00BDF1, 0x00BDF3, 0x000000, 0xFFFFFF, + 0x00BDF5, 0x00BDF7, 0x000000, 0xFFFFFF, + 0x00BDF9, 0x00BDFF, 0x000000, 0xFFFFFF, + 0x00BE01, 0x00BE02, 0x000000, 0xFFFFFF, + 0x00BE04, 0x00BE04, 0x000000, 0xFFFFFF, + 0x00BE06, 0x00BE0B, 0x000000, 0xFFFFFF, + 0x00BE0E, 0x00BE0F, 0x000000, 0xFFFFFF, + 0x00BE11, 0x00BE13, 0x000000, 0xFFFFFF, + 0x00BE15, 0x00BE1B, 0x000000, 0xFFFFFF, + 0x00BE1E, 0x00BE1E, 0x000000, 0xFFFFFF, + 0x00BE20, 0x00BE43, 0x000000, 0xFFFFFF, + 0x00BE46, 0x00BE47, 0x000000, 0xFFFFFF, + 0x00BE49, 0x00BE4B, 0x000000, 0xFFFFFF, + 0x00BE4D, 0x00BE4D, 0x000000, 0xFFFFFF, + 0x00BE4F, 0x00BE53, 0x000000, 0xFFFFFF, + 0x00BE56, 0x00BE56, 0x000000, 0xFFFFFF, + 0x00BE58, 0x00BE58, 0x000000, 0xFFFFFF, + 0x00BE5C, 0x00BE5F, 0x000000, 0xFFFFFF, + 0x00BE62, 0x00BE63, 0x000000, 0xFFFFFF, + 0x00BE65, 0x00BE67, 0x000000, 0xFFFFFF, + 0x00BE69, 0x00BE69, 0x000000, 0xFFFFFF, + 0x00BE6B, 0x00BE6F, 0x000000, 0xFFFFFF, + 0x00BE72, 0x00BE72, 0x000000, 0xFFFFFF, + 0x00BE76, 0x00BE7A, 0x000000, 0xFFFFFF, + 0x00BE7E, 0x00BE7F, 0x000000, 0xFFFFFF, + 0x00BE81, 0x00BE83, 0x000000, 0xFFFFFF, + 0x00BE85, 0x00BE8B, 0x000000, 0xFFFFFF, + 0x00BE8E, 0x00BE8E, 0x000000, 0xFFFFFF, + 0x00BE92, 0x00BE97, 0x000000, 0xFFFFFF, + 0x00BE9A, 0x00BEA7, 0x000000, 0xFFFFFF, + 0x00BEA9, 0x00BECF, 0x000000, 0xFFFFFF, + 0x00BED2, 0x00BED3, 0x000000, 0xFFFFFF, + 0x00BED5, 0x00BED6, 0x000000, 0xFFFFFF, + 0x00BED9, 0x00BEDF, 0x000000, 0xFFFFFF, + 0x00BEE1, 0x00BEE2, 0x000000, 0xFFFFFF, + 0x00BEE6, 0x00BEEB, 0x000000, 0xFFFFFF, + 0x00BEED, 0x00BF00, 0x000000, 0xFFFFFF, + 0x00BF02, 0x00BF07, 0x000000, 0xFFFFFF, + 0x00BF0A, 0x00BF17, 0x000000, 0xFFFFFF, + 0x00BF1A, 0x00BF1A, 0x000000, 0xFFFFFF, + 0x00BF1E, 0x00BF3F, 0x000000, 0xFFFFFF, + 0x00BF42, 0x00BF43, 0x000000, 0xFFFFFF, + 0x00BF45, 0x00BF47, 0x000000, 0xFFFFFF, + 0x00BF49, 0x00BF4F, 0x000000, 0xFFFFFF, + 0x00BF52, 0x00BF54, 0x000000, 0xFFFFFF, + 0x00BF56, 0x00BF93, 0x000000, 0xFFFFFF, + 0x00BF95, 0x00BFAF, 0x000000, 0xFFFFFF, + 0x00BFB1, 0x00BFC4, 0x000000, 0xFFFFFF, + 0x00BFC6, 0x00BFCB, 0x000000, 0xFFFFFF, + 0x00BFCE, 0x00BFCF, 0x000000, 0xFFFFFF, + 0x00BFD1, 0x00BFD3, 0x000000, 0xFFFFFF, + 0x00BFD5, 0x00BFDB, 0x000000, 0xFFFFFF, + 0x00BFDD, 0x00BFDE, 0x000000, 0xFFFFFF, + 0x00BFE0, 0x00BFE0, 0x000000, 0xFFFFFF, + 0x00BFE2, 0x00C03B, 0x000000, 0xFFFFFF, + 0x00C03D, 0x00C050, 0x000000, 0xFFFFFF, + 0x00C052, 0x00C057, 0x000000, 0xFFFFFF, + 0x00C059, 0x00C05B, 0x000000, 0xFFFFFF, + 0x00C05D, 0x00C05F, 0x000000, 0xFFFFFF, + 0x00C061, 0x00C067, 0x000000, 0xFFFFFF, + 0x00C06A, 0x00C08F, 0x000000, 0xFFFFFF, + 0x00C092, 0x00C093, 0x000000, 0xFFFFFF, + 0x00C095, 0x00C097, 0x000000, 0xFFFFFF, + 0x00C099, 0x00C09F, 0x000000, 0xFFFFFF, + 0x00C0A2, 0x00C0A2, 0x000000, 0xFFFFFF, + 0x00C0A4, 0x00C0A4, 0x000000, 0xFFFFFF, + 0x00C0A6, 0x00C0AB, 0x000000, 0xFFFFFF, + 0x00C0AE, 0x00C0AE, 0x000000, 0xFFFFFF, + 0x00C0B1, 0x00C0B2, 0x000000, 0xFFFFFF, + 0x00C0B7, 0x00C0BB, 0x000000, 0xFFFFFF, + 0x00C0BE, 0x00C0BE, 0x000000, 0xFFFFFF, + 0x00C0C2, 0x00C0C4, 0x000000, 0xFFFFFF, + 0x00C0C6, 0x00C0C7, 0x000000, 0xFFFFFF, + 0x00C0CA, 0x00C0CB, 0x000000, 0xFFFFFF, + 0x00C0CD, 0x00C0CF, 0x000000, 0xFFFFFF, + 0x00C0D1, 0x00C0D7, 0x000000, 0xFFFFFF, + 0x00C0DA, 0x00C0DA, 0x000000, 0xFFFFFF, + 0x00C0DE, 0x00C0E3, 0x000000, 0xFFFFFF, + 0x00C0E6, 0x00C0E7, 0x000000, 0xFFFFFF, + 0x00C0E9, 0x00C0EB, 0x000000, 0xFFFFFF, + 0x00C0ED, 0x00C0F3, 0x000000, 0xFFFFFF, + 0x00C0F6, 0x00C0F6, 0x000000, 0xFFFFFF, + 0x00C0F8, 0x00C0F8, 0x000000, 0xFFFFFF, + 0x00C0FA, 0x00C0FF, 0x000000, 0xFFFFFF, + 0x00C101, 0x00C103, 0x000000, 0xFFFFFF, + 0x00C105, 0x00C107, 0x000000, 0xFFFFFF, + 0x00C109, 0x00C10F, 0x000000, 0xFFFFFF, + 0x00C111, 0x00C114, 0x000000, 0xFFFFFF, + 0x00C116, 0x00C11B, 0x000000, 0xFFFFFF, + 0x00C121, 0x00C122, 0x000000, 0xFFFFFF, + 0x00C125, 0x00C125, 0x000000, 0xFFFFFF, + 0x00C128, 0x00C12B, 0x000000, 0xFFFFFF, + 0x00C12E, 0x00C12E, 0x000000, 0xFFFFFF, + 0x00C132, 0x00C135, 0x000000, 0xFFFFFF, + 0x00C137, 0x00C137, 0x000000, 0xFFFFFF, + 0x00C13A, 0x00C13B, 0x000000, 0xFFFFFF, + 0x00C13D, 0x00C13F, 0x000000, 0xFFFFFF, + 0x00C141, 0x00C147, 0x000000, 0xFFFFFF, + 0x00C14A, 0x00C14A, 0x000000, 0xFFFFFF, + 0x00C14E, 0x00C153, 0x000000, 0xFFFFFF, + 0x00C156, 0x00C157, 0x000000, 0xFFFFFF, + 0x00C159, 0x00C15B, 0x000000, 0xFFFFFF, + 0x00C15D, 0x00C163, 0x000000, 0xFFFFFF, + 0x00C166, 0x00C166, 0x000000, 0xFFFFFF, + 0x00C16A, 0x00C16F, 0x000000, 0xFFFFFF, + 0x00C171, 0x00C173, 0x000000, 0xFFFFFF, + 0x00C175, 0x00C177, 0x000000, 0xFFFFFF, + 0x00C179, 0x00C184, 0x000000, 0xFFFFFF, + 0x00C186, 0x00C18B, 0x000000, 0xFFFFFF, + 0x00C18F, 0x00C18F, 0x000000, 0xFFFFFF, + 0x00C191, 0x00C193, 0x000000, 0xFFFFFF, + 0x00C195, 0x00C195, 0x000000, 0xFFFFFF, + 0x00C197, 0x00C19B, 0x000000, 0xFFFFFF, + 0x00C19E, 0x00C19E, 0x000000, 0xFFFFFF, + 0x00C1A0, 0x00C1A0, 0x000000, 0xFFFFFF, + 0x00C1A2, 0x00C1A4, 0x000000, 0xFFFFFF, + 0x00C1A6, 0x00C1A7, 0x000000, 0xFFFFFF, + 0x00C1AA, 0x00C1AB, 0x000000, 0xFFFFFF, + 0x00C1AD, 0x00C1AF, 0x000000, 0xFFFFFF, + 0x00C1B1, 0x00C1BC, 0x000000, 0xFFFFFF, + 0x00C1BE, 0x00C1C3, 0x000000, 0xFFFFFF, + 0x00C1C5, 0x00C1C7, 0x000000, 0xFFFFFF, + 0x00C1C9, 0x00C1CB, 0x000000, 0xFFFFFF, + 0x00C1CD, 0x00C1D3, 0x000000, 0xFFFFFF, + 0x00C1D5, 0x00C1D6, 0x000000, 0xFFFFFF, + 0x00C1D9, 0x00C1DF, 0x000000, 0xFFFFFF, + 0x00C1E1, 0x00C1E3, 0x000000, 0xFFFFFF, + 0x00C1E5, 0x00C1E7, 0x000000, 0xFFFFFF, + 0x00C1E9, 0x00C1EF, 0x000000, 0xFFFFFF, + 0x00C1F2, 0x00C1F2, 0x000000, 0xFFFFFF, + 0x00C1F4, 0x00C1FB, 0x000000, 0xFFFFFF, + 0x00C1FE, 0x00C1FF, 0x000000, 0xFFFFFF, + 0x00C201, 0x00C203, 0x000000, 0xFFFFFF, + 0x00C205, 0x00C20B, 0x000000, 0xFFFFFF, + 0x00C20E, 0x00C20E, 0x000000, 0xFFFFFF, + 0x00C210, 0x00C210, 0x000000, 0xFFFFFF, + 0x00C212, 0x00C217, 0x000000, 0xFFFFFF, + 0x00C21A, 0x00C21B, 0x000000, 0xFFFFFF, + 0x00C21D, 0x00C21E, 0x000000, 0xFFFFFF, + 0x00C221, 0x00C227, 0x000000, 0xFFFFFF, + 0x00C22A, 0x00C22A, 0x000000, 0xFFFFFF, + 0x00C22C, 0x00C22C, 0x000000, 0xFFFFFF, + 0x00C22E, 0x00C22E, 0x000000, 0xFFFFFF, + 0x00C230, 0x00C230, 0x000000, 0xFFFFFF, + 0x00C233, 0x00C233, 0x000000, 0xFFFFFF, + 0x00C235, 0x00C247, 0x000000, 0xFFFFFF, + 0x00C249, 0x00C24F, 0x000000, 0xFFFFFF, + 0x00C252, 0x00C253, 0x000000, 0xFFFFFF, + 0x00C255, 0x00C257, 0x000000, 0xFFFFFF, + 0x00C259, 0x00C25F, 0x000000, 0xFFFFFF, + 0x00C261, 0x00C264, 0x000000, 0xFFFFFF, + 0x00C266, 0x00C26B, 0x000000, 0xFFFFFF, + 0x00C26E, 0x00C26F, 0x000000, 0xFFFFFF, + 0x00C271, 0x00C273, 0x000000, 0xFFFFFF, + 0x00C275, 0x00C27B, 0x000000, 0xFFFFFF, + 0x00C27E, 0x00C27E, 0x000000, 0xFFFFFF, + 0x00C280, 0x00C280, 0x000000, 0xFFFFFF, + 0x00C282, 0x00C287, 0x000000, 0xFFFFFF, + 0x00C28A, 0x00C28F, 0x000000, 0xFFFFFF, + 0x00C291, 0x00C297, 0x000000, 0xFFFFFF, + 0x00C299, 0x00C29A, 0x000000, 0xFFFFFF, + 0x00C29C, 0x00C29C, 0x000000, 0xFFFFFF, + 0x00C29E, 0x00C2A3, 0x000000, 0xFFFFFF, + 0x00C2A6, 0x00C2A7, 0x000000, 0xFFFFFF, + 0x00C2A9, 0x00C2AB, 0x000000, 0xFFFFFF, + 0x00C2AE, 0x00C2B3, 0x000000, 0xFFFFFF, + 0x00C2B6, 0x00C2B6, 0x000000, 0xFFFFFF, + 0x00C2B8, 0x00C2B8, 0x000000, 0xFFFFFF, + 0x00C2BA, 0x00C2DB, 0x000000, 0xFFFFFF, + 0x00C2DE, 0x00C2DF, 0x000000, 0xFFFFFF, + 0x00C2E1, 0x00C2E2, 0x000000, 0xFFFFFF, + 0x00C2E5, 0x00C2EA, 0x000000, 0xFFFFFF, + 0x00C2EE, 0x00C2EE, 0x000000, 0xFFFFFF, + 0x00C2F0, 0x00C2F0, 0x000000, 0xFFFFFF, + 0x00C2F2, 0x00C2F5, 0x000000, 0xFFFFFF, + 0x00C2F7, 0x00C2F7, 0x000000, 0xFFFFFF, + 0x00C2FA, 0x00C2FA, 0x000000, 0xFFFFFF, + 0x00C2FD, 0x00C2FF, 0x000000, 0xFFFFFF, + 0x00C301, 0x00C307, 0x000000, 0xFFFFFF, + 0x00C30A, 0x00C30B, 0x000000, 0xFFFFFF, + 0x00C30E, 0x00C312, 0x000000, 0xFFFFFF, + 0x00C316, 0x00C317, 0x000000, 0xFFFFFF, + 0x00C319, 0x00C31B, 0x000000, 0xFFFFFF, + 0x00C31D, 0x00C323, 0x000000, 0xFFFFFF, + 0x00C326, 0x00C327, 0x000000, 0xFFFFFF, + 0x00C32A, 0x00C344, 0x000000, 0xFFFFFF, + 0x00C346, 0x00C367, 0x000000, 0xFFFFFF, + 0x00C36A, 0x00C36B, 0x000000, 0xFFFFFF, + 0x00C36D, 0x00C36F, 0x000000, 0xFFFFFF, + 0x00C371, 0x00C371, 0x000000, 0xFFFFFF, + 0x00C373, 0x00C377, 0x000000, 0xFFFFFF, + 0x00C37A, 0x00C37B, 0x000000, 0xFFFFFF, + 0x00C37E, 0x00C383, 0x000000, 0xFFFFFF, + 0x00C385, 0x00C387, 0x000000, 0xFFFFFF, + 0x00C389, 0x00C38B, 0x000000, 0xFFFFFF, + 0x00C38D, 0x00C3BF, 0x000000, 0xFFFFFF, + 0x00C3C1, 0x00C3D7, 0x000000, 0xFFFFFF, + 0x00C3DA, 0x00C3DB, 0x000000, 0xFFFFFF, + 0x00C3DD, 0x00C3DE, 0x000000, 0xFFFFFF, + 0x00C3E1, 0x00C3E1, 0x000000, 0xFFFFFF, + 0x00C3E3, 0x00C3E7, 0x000000, 0xFFFFFF, + 0x00C3EA, 0x00C3EC, 0x000000, 0xFFFFFF, + 0x00C3EE, 0x00C3F3, 0x000000, 0xFFFFFF, + 0x00C3F6, 0x00C3F7, 0x000000, 0xFFFFFF, + 0x00C3F9, 0x00C407, 0x000000, 0xFFFFFF, + 0x00C409, 0x00C40F, 0x000000, 0xFFFFFF, + 0x00C411, 0x00C423, 0x000000, 0xFFFFFF, + 0x00C425, 0x00C42B, 0x000000, 0xFFFFFF, + 0x00C42D, 0x00C42F, 0x000000, 0xFFFFFF, + 0x00C431, 0x00C433, 0x000000, 0xFFFFFF, + 0x00C435, 0x00C43B, 0x000000, 0xFFFFFF, + 0x00C43E, 0x00C447, 0x000000, 0xFFFFFF, + 0x00C449, 0x00C463, 0x000000, 0xFFFFFF, + 0x00C466, 0x00C467, 0x000000, 0xFFFFFF, + 0x00C469, 0x00C46B, 0x000000, 0xFFFFFF, + 0x00C46D, 0x00C473, 0x000000, 0xFFFFFF, + 0x00C476, 0x00C478, 0x000000, 0xFFFFFF, + 0x00C47A, 0x00C47F, 0x000000, 0xFFFFFF, + 0x00C481, 0x00C493, 0x000000, 0xFFFFFF, + 0x00C495, 0x00C49B, 0x000000, 0xFFFFFF, + 0x00C49D, 0x00C4B7, 0x000000, 0xFFFFFF, + 0x00C4B9, 0x00C4BB, 0x000000, 0xFFFFFF, + 0x00C4BD, 0x00C4E8, 0x000000, 0xFFFFFF, + 0x00C4EA, 0x00C4EF, 0x000000, 0xFFFFFF, + 0x00C4F2, 0x00C4F3, 0x000000, 0xFFFFFF, + 0x00C4F5, 0x00C4F7, 0x000000, 0xFFFFFF, + 0x00C4F9, 0x00C4F9, 0x000000, 0xFFFFFF, + 0x00C4FB, 0x00C4FE, 0x000000, 0xFFFFFF, + 0x00C502, 0x00C50B, 0x000000, 0xFFFFFF, + 0x00C50D, 0x00C50F, 0x000000, 0xFFFFFF, + 0x00C511, 0x00C513, 0x000000, 0xFFFFFF, + 0x00C515, 0x00C51B, 0x000000, 0xFFFFFF, + 0x00C51D, 0x00C527, 0x000000, 0xFFFFFF, + 0x00C52A, 0x00C52B, 0x000000, 0xFFFFFF, + 0x00C52D, 0x00C52F, 0x000000, 0xFFFFFF, + 0x00C531, 0x00C537, 0x000000, 0xFFFFFF, + 0x00C53A, 0x00C53A, 0x000000, 0xFFFFFF, + 0x00C53C, 0x00C53C, 0x000000, 0xFFFFFF, + 0x00C53E, 0x00C543, 0x000000, 0xFFFFFF, + 0x00C546, 0x00C547, 0x000000, 0xFFFFFF, + 0x00C54B, 0x00C54B, 0x000000, 0xFFFFFF, + 0x00C54F, 0x00C552, 0x000000, 0xFFFFFF, + 0x00C556, 0x00C556, 0x000000, 0xFFFFFF, + 0x00C55A, 0x00C55C, 0x000000, 0xFFFFFF, + 0x00C55F, 0x00C55F, 0x000000, 0xFFFFFF, + 0x00C562, 0x00C563, 0x000000, 0xFFFFFF, + 0x00C565, 0x00C567, 0x000000, 0xFFFFFF, + 0x00C569, 0x00C56F, 0x000000, 0xFFFFFF, + 0x00C572, 0x00C572, 0x000000, 0xFFFFFF, + 0x00C576, 0x00C57B, 0x000000, 0xFFFFFF, + 0x00C57E, 0x00C57F, 0x000000, 0xFFFFFF, + 0x00C581, 0x00C583, 0x000000, 0xFFFFFF, + 0x00C585, 0x00C586, 0x000000, 0xFFFFFF, + 0x00C588, 0x00C58B, 0x000000, 0xFFFFFF, + 0x00C58E, 0x00C58E, 0x000000, 0xFFFFFF, + 0x00C590, 0x00C590, 0x000000, 0xFFFFFF, + 0x00C592, 0x00C594, 0x000000, 0xFFFFFF, + 0x00C596, 0x00C596, 0x000000, 0xFFFFFF, + 0x00C599, 0x00C59B, 0x000000, 0xFFFFFF, + 0x00C59D, 0x00C59F, 0x000000, 0xFFFFFF, + 0x00C5A1, 0x00C5A8, 0x000000, 0xFFFFFF, + 0x00C5AA, 0x00C5B3, 0x000000, 0xFFFFFF, + 0x00C5B6, 0x00C5B7, 0x000000, 0xFFFFFF, + 0x00C5BA, 0x00C5BA, 0x000000, 0xFFFFFF, + 0x00C5BF, 0x00C5C3, 0x000000, 0xFFFFFF, + 0x00C5CB, 0x00C5CB, 0x000000, 0xFFFFFF, + 0x00C5CD, 0x00C5CD, 0x000000, 0xFFFFFF, + 0x00C5CF, 0x00C5CF, 0x000000, 0xFFFFFF, + 0x00C5D2, 0x00C5D3, 0x000000, 0xFFFFFF, + 0x00C5D5, 0x00C5D7, 0x000000, 0xFFFFFF, + 0x00C5D9, 0x00C5DF, 0x000000, 0xFFFFFF, + 0x00C5E2, 0x00C5E2, 0x000000, 0xFFFFFF, + 0x00C5E4, 0x00C5E4, 0x000000, 0xFFFFFF, + 0x00C5E6, 0x00C5EB, 0x000000, 0xFFFFFF, + 0x00C5EF, 0x00C5EF, 0x000000, 0xFFFFFF, + 0x00C5F1, 0x00C5F3, 0x000000, 0xFFFFFF, + 0x00C5F5, 0x00C5F5, 0x000000, 0xFFFFFF, + 0x00C5F8, 0x00C5FB, 0x000000, 0xFFFFFF, + 0x00C602, 0x00C604, 0x000000, 0xFFFFFF, + 0x00C609, 0x00C60B, 0x000000, 0xFFFFFF, + 0x00C60D, 0x00C60F, 0x000000, 0xFFFFFF, + 0x00C611, 0x00C617, 0x000000, 0xFFFFFF, + 0x00C61A, 0x00C61A, 0x000000, 0xFFFFFF, + 0x00C61D, 0x00C623, 0x000000, 0xFFFFFF, + 0x00C626, 0x00C627, 0x000000, 0xFFFFFF, + 0x00C629, 0x00C62B, 0x000000, 0xFFFFFF, + 0x00C62F, 0x00C62F, 0x000000, 0xFFFFFF, + 0x00C631, 0x00C632, 0x000000, 0xFFFFFF, + 0x00C636, 0x00C636, 0x000000, 0xFFFFFF, + 0x00C638, 0x00C638, 0x000000, 0xFFFFFF, + 0x00C63A, 0x00C63A, 0x000000, 0xFFFFFF, + 0x00C63C, 0x00C63F, 0x000000, 0xFFFFFF, + 0x00C642, 0x00C643, 0x000000, 0xFFFFFF, + 0x00C645, 0x00C647, 0x000000, 0xFFFFFF, + 0x00C649, 0x00C64F, 0x000000, 0xFFFFFF, + 0x00C652, 0x00C652, 0x000000, 0xFFFFFF, + 0x00C656, 0x00C65B, 0x000000, 0xFFFFFF, + 0x00C65E, 0x00C65F, 0x000000, 0xFFFFFF, + 0x00C661, 0x00C66B, 0x000000, 0xFFFFFF, + 0x00C66D, 0x00C66E, 0x000000, 0xFFFFFF, + 0x00C670, 0x00C670, 0x000000, 0xFFFFFF, + 0x00C672, 0x00C677, 0x000000, 0xFFFFFF, + 0x00C67A, 0x00C67B, 0x000000, 0xFFFFFF, + 0x00C67D, 0x00C67F, 0x000000, 0xFFFFFF, + 0x00C681, 0x00C687, 0x000000, 0xFFFFFF, + 0x00C68A, 0x00C68A, 0x000000, 0xFFFFFF, + 0x00C68C, 0x00C68C, 0x000000, 0xFFFFFF, + 0x00C68E, 0x00C693, 0x000000, 0xFFFFFF, + 0x00C696, 0x00C697, 0x000000, 0xFFFFFF, + 0x00C699, 0x00C69B, 0x000000, 0xFFFFFF, + 0x00C69D, 0x00C6A3, 0x000000, 0xFFFFFF, + 0x00C6A6, 0x00C6A6, 0x000000, 0xFFFFFF, + 0x00C6A8, 0x00C6A8, 0x000000, 0xFFFFFF, + 0x00C6AA, 0x00C6AF, 0x000000, 0xFFFFFF, + 0x00C6B2, 0x00C6B3, 0x000000, 0xFFFFFF, + 0x00C6B5, 0x00C6B7, 0x000000, 0xFFFFFF, + 0x00C6BB, 0x00C6BF, 0x000000, 0xFFFFFF, + 0x00C6C2, 0x00C6C2, 0x000000, 0xFFFFFF, + 0x00C6C4, 0x00C6C4, 0x000000, 0xFFFFFF, + 0x00C6C6, 0x00C6CB, 0x000000, 0xFFFFFF, + 0x00C6CE, 0x00C6CF, 0x000000, 0xFFFFFF, + 0x00C6D1, 0x00C6D3, 0x000000, 0xFFFFFF, + 0x00C6D5, 0x00C6DB, 0x000000, 0xFFFFFF, + 0x00C6DE, 0x00C6DF, 0x000000, 0xFFFFFF, + 0x00C6E2, 0x00C6E7, 0x000000, 0xFFFFFF, + 0x00C6EA, 0x00C6EB, 0x000000, 0xFFFFFF, + 0x00C6ED, 0x00C6EF, 0x000000, 0xFFFFFF, + 0x00C6F1, 0x00C6F7, 0x000000, 0xFFFFFF, + 0x00C6FA, 0x00C6FC, 0x000000, 0xFFFFFF, + 0x00C6FE, 0x00C703, 0x000000, 0xFFFFFF, + 0x00C706, 0x00C707, 0x000000, 0xFFFFFF, + 0x00C709, 0x00C70B, 0x000000, 0xFFFFFF, + 0x00C70D, 0x00C713, 0x000000, 0xFFFFFF, + 0x00C716, 0x00C716, 0x000000, 0xFFFFFF, + 0x00C718, 0x00C718, 0x000000, 0xFFFFFF, + 0x00C71A, 0x00C71F, 0x000000, 0xFFFFFF, + 0x00C722, 0x00C723, 0x000000, 0xFFFFFF, + 0x00C725, 0x00C727, 0x000000, 0xFFFFFF, + 0x00C729, 0x00C72F, 0x000000, 0xFFFFFF, + 0x00C732, 0x00C732, 0x000000, 0xFFFFFF, + 0x00C734, 0x00C734, 0x000000, 0xFFFFFF, + 0x00C736, 0x00C736, 0x000000, 0xFFFFFF, + 0x00C738, 0x00C73B, 0x000000, 0xFFFFFF, + 0x00C73E, 0x00C73F, 0x000000, 0xFFFFFF, + 0x00C741, 0x00C743, 0x000000, 0xFFFFFF, + 0x00C745, 0x00C749, 0x000000, 0xFFFFFF, + 0x00C74B, 0x00C74B, 0x000000, 0xFFFFFF, + 0x00C74E, 0x00C74E, 0x000000, 0xFFFFFF, + 0x00C750, 0x00C750, 0x000000, 0xFFFFFF, + 0x00C759, 0x00C75B, 0x000000, 0xFFFFFF, + 0x00C75D, 0x00C75F, 0x000000, 0xFFFFFF, + 0x00C761, 0x00C767, 0x000000, 0xFFFFFF, + 0x00C769, 0x00C76A, 0x000000, 0xFFFFFF, + 0x00C76C, 0x00C773, 0x000000, 0xFFFFFF, + 0x00C776, 0x00C777, 0x000000, 0xFFFFFF, + 0x00C779, 0x00C77B, 0x000000, 0xFFFFFF, + 0x00C77F, 0x00C782, 0x000000, 0xFFFFFF, + 0x00C786, 0x00C786, 0x000000, 0xFFFFFF, + 0x00C78B, 0x00C78D, 0x000000, 0xFFFFFF, + 0x00C78F, 0x00C78F, 0x000000, 0xFFFFFF, + 0x00C792, 0x00C793, 0x000000, 0xFFFFFF, + 0x00C795, 0x00C795, 0x000000, 0xFFFFFF, + 0x00C799, 0x00C799, 0x000000, 0xFFFFFF, + 0x00C79B, 0x00C79F, 0x000000, 0xFFFFFF, + 0x00C7A2, 0x00C7A2, 0x000000, 0xFFFFFF, + 0x00C7A7, 0x00C7AB, 0x000000, 0xFFFFFF, + 0x00C7AE, 0x00C7AF, 0x000000, 0xFFFFFF, + 0x00C7B1, 0x00C7B3, 0x000000, 0xFFFFFF, + 0x00C7B5, 0x00C7BB, 0x000000, 0xFFFFFF, + 0x00C7BE, 0x00C7BE, 0x000000, 0xFFFFFF, + 0x00C7C2, 0x00C7C7, 0x000000, 0xFFFFFF, + 0x00C7CA, 0x00C7CB, 0x000000, 0xFFFFFF, + 0x00C7CD, 0x00C7CD, 0x000000, 0xFFFFFF, + 0x00C7CF, 0x00C7CF, 0x000000, 0xFFFFFF, + 0x00C7D1, 0x00C7D7, 0x000000, 0xFFFFFF, + 0x00C7D9, 0x00C7DC, 0x000000, 0xFFFFFF, + 0x00C7DE, 0x00C7E3, 0x000000, 0xFFFFFF, + 0x00C7E5, 0x00C7E7, 0x000000, 0xFFFFFF, + 0x00C7E9, 0x00C7EB, 0x000000, 0xFFFFFF, + 0x00C7ED, 0x00C7FF, 0x000000, 0xFFFFFF, + 0x00C802, 0x00C803, 0x000000, 0xFFFFFF, + 0x00C805, 0x00C807, 0x000000, 0xFFFFFF, + 0x00C809, 0x00C809, 0x000000, 0xFFFFFF, + 0x00C80B, 0x00C80F, 0x000000, 0xFFFFFF, + 0x00C812, 0x00C812, 0x000000, 0xFFFFFF, + 0x00C814, 0x00C814, 0x000000, 0xFFFFFF, + 0x00C817, 0x00C81B, 0x000000, 0xFFFFFF, + 0x00C81E, 0x00C81F, 0x000000, 0xFFFFFF, + 0x00C821, 0x00C823, 0x000000, 0xFFFFFF, + 0x00C825, 0x00C82B, 0x000000, 0xFFFFFF, + 0x00C82E, 0x00C82E, 0x000000, 0xFFFFFF, + 0x00C830, 0x00C830, 0x000000, 0xFFFFFF, + 0x00C832, 0x00C837, 0x000000, 0xFFFFFF, + 0x00C839, 0x00C83B, 0x000000, 0xFFFFFF, + 0x00C83D, 0x00C83F, 0x000000, 0xFFFFFF, + 0x00C841, 0x00C847, 0x000000, 0xFFFFFF, + 0x00C84A, 0x00C84B, 0x000000, 0xFFFFFF, + 0x00C84E, 0x00C853, 0x000000, 0xFFFFFF, + 0x00C855, 0x00C86F, 0x000000, 0xFFFFFF, + 0x00C872, 0x00C873, 0x000000, 0xFFFFFF, + 0x00C875, 0x00C877, 0x000000, 0xFFFFFF, + 0x00C879, 0x00C879, 0x000000, 0xFFFFFF, + 0x00C87B, 0x00C87F, 0x000000, 0xFFFFFF, + 0x00C882, 0x00C882, 0x000000, 0xFFFFFF, + 0x00C884, 0x00C884, 0x000000, 0xFFFFFF, + 0x00C888, 0x00C88A, 0x000000, 0xFFFFFF, + 0x00C88E, 0x00C893, 0x000000, 0xFFFFFF, + 0x00C895, 0x00C89C, 0x000000, 0xFFFFFF, + 0x00C89E, 0x00C89E, 0x000000, 0xFFFFFF, + 0x00C8A0, 0x00C8A0, 0x000000, 0xFFFFFF, + 0x00C8A2, 0x00C8A7, 0x000000, 0xFFFFFF, + 0x00C8A9, 0x00C8BB, 0x000000, 0xFFFFFF, + 0x00C8BE, 0x00C8C3, 0x000000, 0xFFFFFF, + 0x00C8C5, 0x00C8C7, 0x000000, 0xFFFFFF, + 0x00C8C9, 0x00C8CB, 0x000000, 0xFFFFFF, + 0x00C8CD, 0x00C8D3, 0x000000, 0xFFFFFF, + 0x00C8D6, 0x00C8D6, 0x000000, 0xFFFFFF, + 0x00C8D8, 0x00C8D8, 0x000000, 0xFFFFFF, + 0x00C8DA, 0x00C8DF, 0x000000, 0xFFFFFF, + 0x00C8E2, 0x00C8E3, 0x000000, 0xFFFFFF, + 0x00C8E5, 0x00C8F4, 0x000000, 0xFFFFFF, + 0x00C8F6, 0x00C8FB, 0x000000, 0xFFFFFF, + 0x00C8FE, 0x00C8FF, 0x000000, 0xFFFFFF, + 0x00C901, 0x00C903, 0x000000, 0xFFFFFF, + 0x00C907, 0x00C90B, 0x000000, 0xFFFFFF, + 0x00C90E, 0x00C90E, 0x000000, 0xFFFFFF, + 0x00C910, 0x00C910, 0x000000, 0xFFFFFF, + 0x00C912, 0x00C917, 0x000000, 0xFFFFFF, + 0x00C919, 0x00C92B, 0x000000, 0xFFFFFF, + 0x00C92D, 0x00C933, 0x000000, 0xFFFFFF, + 0x00C935, 0x00C94F, 0x000000, 0xFFFFFF, + 0x00C952, 0x00C953, 0x000000, 0xFFFFFF, + 0x00C955, 0x00C957, 0x000000, 0xFFFFFF, + 0x00C959, 0x00C95F, 0x000000, 0xFFFFFF, + 0x00C962, 0x00C962, 0x000000, 0xFFFFFF, + 0x00C964, 0x00C96B, 0x000000, 0xFFFFFF, + 0x00C96D, 0x00C96F, 0x000000, 0xFFFFFF, + 0x00C971, 0x00C973, 0x000000, 0xFFFFFF, + 0x00C975, 0x00C97B, 0x000000, 0xFFFFFF, + 0x00C97D, 0x00C987, 0x000000, 0xFFFFFF, + 0x00C98A, 0x00C98B, 0x000000, 0xFFFFFF, + 0x00C98D, 0x00C98F, 0x000000, 0xFFFFFF, + 0x00C991, 0x00C997, 0x000000, 0xFFFFFF, + 0x00C99A, 0x00C99A, 0x000000, 0xFFFFFF, + 0x00C99C, 0x00C99C, 0x000000, 0xFFFFFF, + 0x00C99E, 0x00C9BF, 0x000000, 0xFFFFFF, + 0x00C9C2, 0x00C9C3, 0x000000, 0xFFFFFF, + 0x00C9C5, 0x00C9C6, 0x000000, 0xFFFFFF, + 0x00C9C9, 0x00C9C9, 0x000000, 0xFFFFFF, + 0x00C9CB, 0x00C9CF, 0x000000, 0xFFFFFF, + 0x00C9D2, 0x00C9D2, 0x000000, 0xFFFFFF, + 0x00C9D4, 0x00C9D4, 0x000000, 0xFFFFFF, + 0x00C9D7, 0x00C9D8, 0x000000, 0xFFFFFF, + 0x00C9DB, 0x00C9DB, 0x000000, 0xFFFFFF, + 0x00C9DE, 0x00C9DF, 0x000000, 0xFFFFFF, + 0x00C9E1, 0x00C9E1, 0x000000, 0xFFFFFF, + 0x00C9E3, 0x00C9E3, 0x000000, 0xFFFFFF, + 0x00C9E5, 0x00C9E6, 0x000000, 0xFFFFFF, + 0x00C9E8, 0x00C9EB, 0x000000, 0xFFFFFF, + 0x00C9EE, 0x00C9EE, 0x000000, 0xFFFFFF, + 0x00C9F2, 0x00C9F7, 0x000000, 0xFFFFFF, + 0x00C9FA, 0x00C9FB, 0x000000, 0xFFFFFF, + 0x00C9FD, 0x00C9FF, 0x000000, 0xFFFFFF, + 0x00CA01, 0x00CA07, 0x000000, 0xFFFFFF, + 0x00CA0A, 0x00CA0A, 0x000000, 0xFFFFFF, + 0x00CA0E, 0x00CA13, 0x000000, 0xFFFFFF, + 0x00CA15, 0x00CA17, 0x000000, 0xFFFFFF, + 0x00CA19, 0x00CA28, 0x000000, 0xFFFFFF, + 0x00CA2A, 0x00CA4B, 0x000000, 0xFFFFFF, + 0x00CA4E, 0x00CA4F, 0x000000, 0xFFFFFF, + 0x00CA51, 0x00CA53, 0x000000, 0xFFFFFF, + 0x00CA55, 0x00CA5B, 0x000000, 0xFFFFFF, + 0x00CA5E, 0x00CA5E, 0x000000, 0xFFFFFF, + 0x00CA62, 0x00CA67, 0x000000, 0xFFFFFF, + 0x00CA69, 0x00CA7C, 0x000000, 0xFFFFFF, + 0x00CA7E, 0x00CA83, 0x000000, 0xFFFFFF, + 0x00CA85, 0x00CA97, 0x000000, 0xFFFFFF, + 0x00CA99, 0x00CABB, 0x000000, 0xFFFFFF, + 0x00CABE, 0x00CABF, 0x000000, 0xFFFFFF, + 0x00CAC1, 0x00CAC3, 0x000000, 0xFFFFFF, + 0x00CAC5, 0x00CACB, 0x000000, 0xFFFFFF, + 0x00CACE, 0x00CACE, 0x000000, 0xFFFFFF, + 0x00CAD0, 0x00CAD0, 0x000000, 0xFFFFFF, + 0x00CAD2, 0x00CAD2, 0x000000, 0xFFFFFF, + 0x00CAD4, 0x00CAD7, 0x000000, 0xFFFFFF, + 0x00CADA, 0x00CADF, 0x000000, 0xFFFFFF, + 0x00CAE1, 0x00CAEB, 0x000000, 0xFFFFFF, + 0x00CAED, 0x00CAF3, 0x000000, 0xFFFFFF, + 0x00CAF5, 0x00CB07, 0x000000, 0xFFFFFF, + 0x00CB09, 0x00CB0F, 0x000000, 0xFFFFFF, + 0x00CB11, 0x00CB13, 0x000000, 0xFFFFFF, + 0x00CB15, 0x00CB17, 0x000000, 0xFFFFFF, + 0x00CB19, 0x00CB1F, 0x000000, 0xFFFFFF, + 0x00CB22, 0x00CB40, 0x000000, 0xFFFFFF, + 0x00CB42, 0x00CB47, 0x000000, 0xFFFFFF, + 0x00CB4A, 0x00CB4B, 0x000000, 0xFFFFFF, + 0x00CB4D, 0x00CB4F, 0x000000, 0xFFFFFF, + 0x00CB51, 0x00CB57, 0x000000, 0xFFFFFF, + 0x00CB5A, 0x00CB5C, 0x000000, 0xFFFFFF, + 0x00CB5E, 0x00CB63, 0x000000, 0xFFFFFF, + 0x00CB65, 0x00CB77, 0x000000, 0xFFFFFF, + 0x00CB7A, 0x00CB9B, 0x000000, 0xFFFFFF, + 0x00CB9D, 0x00CBB7, 0x000000, 0xFFFFFF, + 0x00CBB9, 0x00CBD3, 0x000000, 0xFFFFFF, + 0x00CBD5, 0x00CBE3, 0x000000, 0xFFFFFF, + 0x00CBE5, 0x00CBE6, 0x000000, 0xFFFFFF, + 0x00CBE8, 0x00CBE8, 0x000000, 0xFFFFFF, + 0x00CBEA, 0x00CC0B, 0x000000, 0xFFFFFF, + 0x00CC0E, 0x00CC0F, 0x000000, 0xFFFFFF, + 0x00CC11, 0x00CC13, 0x000000, 0xFFFFFF, + 0x00CC15, 0x00CC1B, 0x000000, 0xFFFFFF, + 0x00CC1E, 0x00CC20, 0x000000, 0xFFFFFF, + 0x00CC23, 0x00CC26, 0x000000, 0xFFFFFF, + 0x00CC2A, 0x00CC2B, 0x000000, 0xFFFFFF, + 0x00CC2D, 0x00CC2D, 0x000000, 0xFFFFFF, + 0x00CC2F, 0x00CC2F, 0x000000, 0xFFFFFF, + 0x00CC31, 0x00CC37, 0x000000, 0xFFFFFF, + 0x00CC3A, 0x00CC3A, 0x000000, 0xFFFFFF, + 0x00CC3F, 0x00CC43, 0x000000, 0xFFFFFF, + 0x00CC46, 0x00CC47, 0x000000, 0xFFFFFF, + 0x00CC49, 0x00CC4B, 0x000000, 0xFFFFFF, + 0x00CC4D, 0x00CC53, 0x000000, 0xFFFFFF, + 0x00CC56, 0x00CC56, 0x000000, 0xFFFFFF, + 0x00CC5A, 0x00CC5F, 0x000000, 0xFFFFFF, + 0x00CC61, 0x00CC63, 0x000000, 0xFFFFFF, + 0x00CC65, 0x00CC65, 0x000000, 0xFFFFFF, + 0x00CC67, 0x00CC67, 0x000000, 0xFFFFFF, + 0x00CC69, 0x00CC6F, 0x000000, 0xFFFFFF, + 0x00CC71, 0x00CC74, 0x000000, 0xFFFFFF, + 0x00CC76, 0x00CC97, 0x000000, 0xFFFFFF, + 0x00CC9A, 0x00CC9B, 0x000000, 0xFFFFFF, + 0x00CC9D, 0x00CC9F, 0x000000, 0xFFFFFF, + 0x00CCA1, 0x00CCA7, 0x000000, 0xFFFFFF, + 0x00CCAA, 0x00CCAA, 0x000000, 0xFFFFFF, + 0x00CCAE, 0x00CCB3, 0x000000, 0xFFFFFF, + 0x00CCB6, 0x00CCB7, 0x000000, 0xFFFFFF, + 0x00CCB9, 0x00CCBB, 0x000000, 0xFFFFFF, + 0x00CCBD, 0x00CCC3, 0x000000, 0xFFFFFF, + 0x00CCC6, 0x00CCC6, 0x000000, 0xFFFFFF, + 0x00CCC8, 0x00CCC8, 0x000000, 0xFFFFFF, + 0x00CCCA, 0x00CCCF, 0x000000, 0xFFFFFF, + 0x00CCD1, 0x00CCD3, 0x000000, 0xFFFFFF, + 0x00CCD5, 0x00CCE3, 0x000000, 0xFFFFFF, + 0x00CCE5, 0x00CCEB, 0x000000, 0xFFFFFF, + 0x00CCED, 0x00CCEF, 0x000000, 0xFFFFFF, + 0x00CCF1, 0x00CD00, 0x000000, 0xFFFFFF, + 0x00CD02, 0x00CD07, 0x000000, 0xFFFFFF, + 0x00CD0A, 0x00CD0B, 0x000000, 0xFFFFFF, + 0x00CD0D, 0x00CD0F, 0x000000, 0xFFFFFF, + 0x00CD11, 0x00CD17, 0x000000, 0xFFFFFF, + 0x00CD1A, 0x00CD1A, 0x000000, 0xFFFFFF, + 0x00CD1C, 0x00CD1C, 0x000000, 0xFFFFFF, + 0x00CD1E, 0x00CD23, 0x000000, 0xFFFFFF, + 0x00CD25, 0x00CD27, 0x000000, 0xFFFFFF, + 0x00CD29, 0x00CD2B, 0x000000, 0xFFFFFF, + 0x00CD2D, 0x00CD38, 0x000000, 0xFFFFFF, + 0x00CD3A, 0x00CD5B, 0x000000, 0xFFFFFF, + 0x00CD5D, 0x00CD5F, 0x000000, 0xFFFFFF, + 0x00CD61, 0x00CD63, 0x000000, 0xFFFFFF, + 0x00CD65, 0x00CD6B, 0x000000, 0xFFFFFF, + 0x00CD6E, 0x00CD6E, 0x000000, 0xFFFFFF, + 0x00CD70, 0x00CD70, 0x000000, 0xFFFFFF, + 0x00CD72, 0x00CD77, 0x000000, 0xFFFFFF, + 0x00CD79, 0x00CD87, 0x000000, 0xFFFFFF, + 0x00CD89, 0x00CD93, 0x000000, 0xFFFFFF, + 0x00CD96, 0x00CD97, 0x000000, 0xFFFFFF, + 0x00CD99, 0x00CD9B, 0x000000, 0xFFFFFF, + 0x00CD9D, 0x00CDA3, 0x000000, 0xFFFFFF, + 0x00CDA6, 0x00CDA6, 0x000000, 0xFFFFFF, + 0x00CDA8, 0x00CDA8, 0x000000, 0xFFFFFF, + 0x00CDAA, 0x00CDAF, 0x000000, 0xFFFFFF, + 0x00CDB1, 0x00CDC3, 0x000000, 0xFFFFFF, + 0x00CDC5, 0x00CDCB, 0x000000, 0xFFFFFF, + 0x00CDCD, 0x00CDCF, 0x000000, 0xFFFFFF, + 0x00CDD1, 0x00CDE7, 0x000000, 0xFFFFFF, + 0x00CDE9, 0x00CDEB, 0x000000, 0xFFFFFF, + 0x00CDED, 0x00CDEF, 0x000000, 0xFFFFFF, + 0x00CDF1, 0x00CDF7, 0x000000, 0xFFFFFF, + 0x00CDFA, 0x00CDFA, 0x000000, 0xFFFFFF, + 0x00CDFC, 0x00CDFC, 0x000000, 0xFFFFFF, + 0x00CDFE, 0x00CE03, 0x000000, 0xFFFFFF, + 0x00CE05, 0x00CE07, 0x000000, 0xFFFFFF, + 0x00CE09, 0x00CE0B, 0x000000, 0xFFFFFF, + 0x00CE0D, 0x00CE13, 0x000000, 0xFFFFFF, + 0x00CE15, 0x00CE18, 0x000000, 0xFFFFFF, + 0x00CE1A, 0x00CE1F, 0x000000, 0xFFFFFF, + 0x00CE22, 0x00CE23, 0x000000, 0xFFFFFF, + 0x00CE25, 0x00CE27, 0x000000, 0xFFFFFF, + 0x00CE29, 0x00CE2F, 0x000000, 0xFFFFFF, + 0x00CE32, 0x00CE32, 0x000000, 0xFFFFFF, + 0x00CE34, 0x00CE34, 0x000000, 0xFFFFFF, + 0x00CE36, 0x00CE57, 0x000000, 0xFFFFFF, + 0x00CE5A, 0x00CE5B, 0x000000, 0xFFFFFF, + 0x00CE5D, 0x00CE5E, 0x000000, 0xFFFFFF, + 0x00CE62, 0x00CE67, 0x000000, 0xFFFFFF, + 0x00CE6A, 0x00CE6A, 0x000000, 0xFFFFFF, + 0x00CE6C, 0x00CE6C, 0x000000, 0xFFFFFF, + 0x00CE6E, 0x00CE73, 0x000000, 0xFFFFFF, + 0x00CE76, 0x00CE77, 0x000000, 0xFFFFFF, + 0x00CE79, 0x00CE7B, 0x000000, 0xFFFFFF, + 0x00CE7D, 0x00CE83, 0x000000, 0xFFFFFF, + 0x00CE86, 0x00CE86, 0x000000, 0xFFFFFF, + 0x00CE88, 0x00CE88, 0x000000, 0xFFFFFF, + 0x00CE8A, 0x00CE8F, 0x000000, 0xFFFFFF, + 0x00CE92, 0x00CE93, 0x000000, 0xFFFFFF, + 0x00CE95, 0x00CE97, 0x000000, 0xFFFFFF, + 0x00CE99, 0x00CE9F, 0x000000, 0xFFFFFF, + 0x00CEA2, 0x00CEA2, 0x000000, 0xFFFFFF, + 0x00CEA6, 0x00CEAB, 0x000000, 0xFFFFFF, + 0x00CEAE, 0x00CEC0, 0x000000, 0xFFFFFF, + 0x00CEC2, 0x00CEE3, 0x000000, 0xFFFFFF, + 0x00CEE6, 0x00CEE7, 0x000000, 0xFFFFFF, + 0x00CEE9, 0x00CEEA, 0x000000, 0xFFFFFF, + 0x00CEED, 0x00CEF3, 0x000000, 0xFFFFFF, + 0x00CEF6, 0x00CEF6, 0x000000, 0xFFFFFF, + 0x00CEFA, 0x00CEFF, 0x000000, 0xFFFFFF, + 0x00CF02, 0x00CF03, 0x000000, 0xFFFFFF, + 0x00CF05, 0x00CF07, 0x000000, 0xFFFFFF, + 0x00CF09, 0x00CF0F, 0x000000, 0xFFFFFF, + 0x00CF12, 0x00CF12, 0x000000, 0xFFFFFF, + 0x00CF14, 0x00CF14, 0x000000, 0xFFFFFF, + 0x00CF16, 0x00CF1B, 0x000000, 0xFFFFFF, + 0x00CF1D, 0x00CF1F, 0x000000, 0xFFFFFF, + 0x00CF21, 0x00CF23, 0x000000, 0xFFFFFF, + 0x00CF25, 0x00CF2B, 0x000000, 0xFFFFFF, + 0x00CF2E, 0x00CF2E, 0x000000, 0xFFFFFF, + 0x00CF32, 0x00CF37, 0x000000, 0xFFFFFF, + 0x00CF39, 0x00CF53, 0x000000, 0xFFFFFF, + 0x00CF56, 0x00CF57, 0x000000, 0xFFFFFF, + 0x00CF59, 0x00CF5B, 0x000000, 0xFFFFFF, + 0x00CF5D, 0x00CF63, 0x000000, 0xFFFFFF, + 0x00CF66, 0x00CF66, 0x000000, 0xFFFFFF, + 0x00CF68, 0x00CF68, 0x000000, 0xFFFFFF, + 0x00CF6A, 0x00CF6F, 0x000000, 0xFFFFFF, + 0x00CF72, 0x00CF73, 0x000000, 0xFFFFFF, + 0x00CF75, 0x00CF77, 0x000000, 0xFFFFFF, + 0x00CF79, 0x00CF7F, 0x000000, 0xFFFFFF, + 0x00CF81, 0x00CF84, 0x000000, 0xFFFFFF, + 0x00CF86, 0x00CF8B, 0x000000, 0xFFFFFF, + 0x00CF8D, 0x00CFA0, 0x000000, 0xFFFFFF, + 0x00CFA2, 0x00CFA7, 0x000000, 0xFFFFFF, + 0x00CFA9, 0x00CFAF, 0x000000, 0xFFFFFF, + 0x00CFB1, 0x00CFC3, 0x000000, 0xFFFFFF, + 0x00CFC5, 0x00CFDF, 0x000000, 0xFFFFFF, + 0x00CFE2, 0x00CFE3, 0x000000, 0xFFFFFF, + 0x00CFE5, 0x00CFE7, 0x000000, 0xFFFFFF, + 0x00CFE9, 0x00CFEF, 0x000000, 0xFFFFFF, + 0x00CFF2, 0x00CFF2, 0x000000, 0xFFFFFF, + 0x00CFF4, 0x00CFF4, 0x000000, 0xFFFFFF, + 0x00CFF6, 0x00CFFB, 0x000000, 0xFFFFFF, + 0x00CFFD, 0x00CFFF, 0x000000, 0xFFFFFF, + 0x00D001, 0x00D003, 0x000000, 0xFFFFFF, + 0x00D005, 0x00D010, 0x000000, 0xFFFFFF, + 0x00D012, 0x00D017, 0x000000, 0xFFFFFF, + 0x00D019, 0x00D02C, 0x000000, 0xFFFFFF, + 0x00D02E, 0x00D033, 0x000000, 0xFFFFFF, + 0x00D036, 0x00D037, 0x000000, 0xFFFFFF, + 0x00D039, 0x00D03B, 0x000000, 0xFFFFFF, + 0x00D03D, 0x00D043, 0x000000, 0xFFFFFF, + 0x00D046, 0x00D046, 0x000000, 0xFFFFFF, + 0x00D048, 0x00D048, 0x000000, 0xFFFFFF, + 0x00D04A, 0x00D04F, 0x000000, 0xFFFFFF, + 0x00D051, 0x00D053, 0x000000, 0xFFFFFF, + 0x00D055, 0x00D057, 0x000000, 0xFFFFFF, + 0x00D059, 0x00D05F, 0x000000, 0xFFFFFF, + 0x00D061, 0x00D06B, 0x000000, 0xFFFFFF, + 0x00D06E, 0x00D06F, 0x000000, 0xFFFFFF, + 0x00D071, 0x00D073, 0x000000, 0xFFFFFF, + 0x00D075, 0x00D07B, 0x000000, 0xFFFFFF, + 0x00D07E, 0x00D080, 0x000000, 0xFFFFFF, + 0x00D082, 0x00D0A3, 0x000000, 0xFFFFFF, + 0x00D0A6, 0x00D0A7, 0x000000, 0xFFFFFF, + 0x00D0A9, 0x00D0AB, 0x000000, 0xFFFFFF, + 0x00D0AD, 0x00D0B3, 0x000000, 0xFFFFFF, + 0x00D0B6, 0x00D0B6, 0x000000, 0xFFFFFF, + 0x00D0B8, 0x00D0B8, 0x000000, 0xFFFFFF, + 0x00D0BA, 0x00D0BF, 0x000000, 0xFFFFFF, + 0x00D0C2, 0x00D0C3, 0x000000, 0xFFFFFF, + 0x00D0C5, 0x00D0C7, 0x000000, 0xFFFFFF, + 0x00D0CA, 0x00D0CF, 0x000000, 0xFFFFFF, + 0x00D0D2, 0x00D0D2, 0x000000, 0xFFFFFF, + 0x00D0D6, 0x00D0DB, 0x000000, 0xFFFFFF, + 0x00D0DE, 0x00D0DF, 0x000000, 0xFFFFFF, + 0x00D0E1, 0x00D0E3, 0x000000, 0xFFFFFF, + 0x00D0E5, 0x00D0EB, 0x000000, 0xFFFFFF, + 0x00D0EE, 0x00D0EE, 0x000000, 0xFFFFFF, + 0x00D0F2, 0x00D0F7, 0x000000, 0xFFFFFF, + 0x00D0F9, 0x00D10C, 0x000000, 0xFFFFFF, + 0x00D10E, 0x00D12F, 0x000000, 0xFFFFFF, + 0x00D132, 0x00D133, 0x000000, 0xFFFFFF, + 0x00D135, 0x00D137, 0x000000, 0xFFFFFF, + 0x00D139, 0x00D139, 0x000000, 0xFFFFFF, + 0x00D13B, 0x00D13F, 0x000000, 0xFFFFFF, + 0x00D142, 0x00D142, 0x000000, 0xFFFFFF, + 0x00D146, 0x00D14B, 0x000000, 0xFFFFFF, + 0x00D14E, 0x00D14F, 0x000000, 0xFFFFFF, + 0x00D151, 0x00D153, 0x000000, 0xFFFFFF, + 0x00D155, 0x00D15B, 0x000000, 0xFFFFFF, + 0x00D15E, 0x00D15E, 0x000000, 0xFFFFFF, + 0x00D160, 0x00D160, 0x000000, 0xFFFFFF, + 0x00D162, 0x00D167, 0x000000, 0xFFFFFF, + 0x00D169, 0x00D16B, 0x000000, 0xFFFFFF, + 0x00D16D, 0x00D17B, 0x000000, 0xFFFFFF, + 0x00D17D, 0x00D183, 0x000000, 0xFFFFFF, + 0x00D185, 0x00D187, 0x000000, 0xFFFFFF, + 0x00D189, 0x00D19F, 0x000000, 0xFFFFFF, + 0x00D1A2, 0x00D1A3, 0x000000, 0xFFFFFF, + 0x00D1A5, 0x00D1A7, 0x000000, 0xFFFFFF, + 0x00D1A9, 0x00D1AF, 0x000000, 0xFFFFFF, + 0x00D1B2, 0x00D1B2, 0x000000, 0xFFFFFF, + 0x00D1B4, 0x00D1B4, 0x000000, 0xFFFFFF, + 0x00D1B6, 0x00D1B9, 0x000000, 0xFFFFFF, + 0x00D1BB, 0x00D1BB, 0x000000, 0xFFFFFF, + 0x00D1BD, 0x00D1BF, 0x000000, 0xFFFFFF, + 0x00D1C1, 0x00D1D7, 0x000000, 0xFFFFFF, + 0x00D1D9, 0x00D1F3, 0x000000, 0xFFFFFF, + 0x00D1F5, 0x00D1F7, 0x000000, 0xFFFFFF, + 0x00D1F9, 0x00D206, 0x000000, 0xFFFFFF, + 0x00D208, 0x00D208, 0x000000, 0xFFFFFF, + 0x00D20A, 0x00D20F, 0x000000, 0xFFFFFF, + 0x00D211, 0x00D22B, 0x000000, 0xFFFFFF, + 0x00D22E, 0x00D22F, 0x000000, 0xFFFFFF, + 0x00D231, 0x00D233, 0x000000, 0xFFFFFF, + 0x00D235, 0x00D23B, 0x000000, 0xFFFFFF, + 0x00D23E, 0x00D23E, 0x000000, 0xFFFFFF, + 0x00D240, 0x00D240, 0x000000, 0xFFFFFF, + 0x00D242, 0x00D247, 0x000000, 0xFFFFFF, + 0x00D249, 0x00D25B, 0x000000, 0xFFFFFF, + 0x00D25D, 0x00D263, 0x000000, 0xFFFFFF, + 0x00D265, 0x00D27F, 0x000000, 0xFFFFFF, + 0x00D282, 0x00D283, 0x000000, 0xFFFFFF, + 0x00D285, 0x00D287, 0x000000, 0xFFFFFF, + 0x00D289, 0x00D28F, 0x000000, 0xFFFFFF, + 0x00D292, 0x00D294, 0x000000, 0xFFFFFF, + 0x00D296, 0x00D29B, 0x000000, 0xFFFFFF, + 0x00D29D, 0x00D29F, 0x000000, 0xFFFFFF, + 0x00D2A1, 0x00D2A3, 0x000000, 0xFFFFFF, + 0x00D2A5, 0x00D2AB, 0x000000, 0xFFFFFF, + 0x00D2AD, 0x00D2B0, 0x000000, 0xFFFFFF, + 0x00D2B2, 0x00D2B7, 0x000000, 0xFFFFFF, + 0x00D2BA, 0x00D2BB, 0x000000, 0xFFFFFF, + 0x00D2BD, 0x00D2BE, 0x000000, 0xFFFFFF, + 0x00D2C1, 0x00D2C1, 0x000000, 0xFFFFFF, + 0x00D2C3, 0x00D2C7, 0x000000, 0xFFFFFF, + 0x00D2CA, 0x00D2CA, 0x000000, 0xFFFFFF, + 0x00D2CC, 0x00D2D3, 0x000000, 0xFFFFFF, + 0x00D2D5, 0x00D2D7, 0x000000, 0xFFFFFF, + 0x00D2D9, 0x00D2DB, 0x000000, 0xFFFFFF, + 0x00D2DD, 0x00D2E3, 0x000000, 0xFFFFFF, + 0x00D2E6, 0x00D2EF, 0x000000, 0xFFFFFF, + 0x00D2F2, 0x00D2F3, 0x000000, 0xFFFFFF, + 0x00D2F5, 0x00D2F7, 0x000000, 0xFFFFFF, + 0x00D2F9, 0x00D2FF, 0x000000, 0xFFFFFF, + 0x00D302, 0x00D302, 0x000000, 0xFFFFFF, + 0x00D304, 0x00D304, 0x000000, 0xFFFFFF, + 0x00D306, 0x00D30B, 0x000000, 0xFFFFFF, + 0x00D30F, 0x00D30F, 0x000000, 0xFFFFFF, + 0x00D311, 0x00D313, 0x000000, 0xFFFFFF, + 0x00D315, 0x00D315, 0x000000, 0xFFFFFF, + 0x00D317, 0x00D31B, 0x000000, 0xFFFFFF, + 0x00D31E, 0x00D31E, 0x000000, 0xFFFFFF, + 0x00D322, 0x00D324, 0x000000, 0xFFFFFF, + 0x00D326, 0x00D327, 0x000000, 0xFFFFFF, + 0x00D32A, 0x00D32B, 0x000000, 0xFFFFFF, + 0x00D32D, 0x00D32F, 0x000000, 0xFFFFFF, + 0x00D331, 0x00D337, 0x000000, 0xFFFFFF, + 0x00D33A, 0x00D33A, 0x000000, 0xFFFFFF, + 0x00D33E, 0x00D343, 0x000000, 0xFFFFFF, + 0x00D346, 0x00D37B, 0x000000, 0xFFFFFF, + 0x00D37E, 0x00D37F, 0x000000, 0xFFFFFF, + 0x00D381, 0x00D383, 0x000000, 0xFFFFFF, + 0x00D385, 0x00D38B, 0x000000, 0xFFFFFF, + 0x00D38E, 0x00D38E, 0x000000, 0xFFFFFF, + 0x00D392, 0x00D397, 0x000000, 0xFFFFFF, + 0x00D39A, 0x00D39B, 0x000000, 0xFFFFFF, + 0x00D39D, 0x00D39F, 0x000000, 0xFFFFFF, + 0x00D3A1, 0x00D3A7, 0x000000, 0xFFFFFF, + 0x00D3AA, 0x00D3AA, 0x000000, 0xFFFFFF, + 0x00D3AC, 0x00D3AC, 0x000000, 0xFFFFFF, + 0x00D3AE, 0x00D3B3, 0x000000, 0xFFFFFF, + 0x00D3B5, 0x00D3B7, 0x000000, 0xFFFFFF, + 0x00D3B9, 0x00D3BB, 0x000000, 0xFFFFFF, + 0x00D3BD, 0x00D3C3, 0x000000, 0xFFFFFF, + 0x00D3C6, 0x00D3C7, 0x000000, 0xFFFFFF, + 0x00D3CA, 0x00D3CF, 0x000000, 0xFFFFFF, + 0x00D3D1, 0x00D3D7, 0x000000, 0xFFFFFF, + 0x00D3D9, 0x00D3E0, 0x000000, 0xFFFFFF, + 0x00D3E2, 0x00D3E2, 0x000000, 0xFFFFFF, + 0x00D3E4, 0x00D3EB, 0x000000, 0xFFFFFF, + 0x00D3EE, 0x00D3EF, 0x000000, 0xFFFFFF, + 0x00D3F1, 0x00D3F3, 0x000000, 0xFFFFFF, + 0x00D3F5, 0x00D3FB, 0x000000, 0xFFFFFF, + 0x00D3FE, 0x00D3FE, 0x000000, 0xFFFFFF, + 0x00D400, 0x00D400, 0x000000, 0xFFFFFF, + 0x00D402, 0x00D407, 0x000000, 0xFFFFFF, + 0x00D409, 0x00D41C, 0x000000, 0xFFFFFF, + 0x00D41E, 0x00D43F, 0x000000, 0xFFFFFF, + 0x00D441, 0x00D443, 0x000000, 0xFFFFFF, + 0x00D445, 0x00D45B, 0x000000, 0xFFFFFF, + 0x00D45D, 0x00D45F, 0x000000, 0xFFFFFF, + 0x00D461, 0x00D463, 0x000000, 0xFFFFFF, + 0x00D465, 0x00D46C, 0x000000, 0xFFFFFF, + 0x00D46E, 0x00D46E, 0x000000, 0xFFFFFF, + 0x00D470, 0x00D477, 0x000000, 0xFFFFFF, + 0x00D47A, 0x00D47B, 0x000000, 0xFFFFFF, + 0x00D47D, 0x00D47E, 0x000000, 0xFFFFFF, + 0x00D481, 0x00D481, 0x000000, 0xFFFFFF, + 0x00D483, 0x00D487, 0x000000, 0xFFFFFF, + 0x00D48A, 0x00D48A, 0x000000, 0xFFFFFF, + 0x00D48C, 0x00D48C, 0x000000, 0xFFFFFF, + 0x00D48E, 0x00D493, 0x000000, 0xFFFFFF, + 0x00D495, 0x00D4A8, 0x000000, 0xFFFFFF, + 0x00D4AA, 0x00D4CB, 0x000000, 0xFFFFFF, + 0x00D4CD, 0x00D4CF, 0x000000, 0xFFFFFF, + 0x00D4D1, 0x00D4D3, 0x000000, 0xFFFFFF, + 0x00D4D5, 0x00D4DB, 0x000000, 0xFFFFFF, + 0x00D4DD, 0x00D4DE, 0x000000, 0xFFFFFF, + 0x00D4E0, 0x00D4E7, 0x000000, 0xFFFFFF, + 0x00D4E9, 0x00D4EB, 0x000000, 0xFFFFFF, + 0x00D4ED, 0x00D4EF, 0x000000, 0xFFFFFF, + 0x00D4F1, 0x00D4F7, 0x000000, 0xFFFFFF, + 0x00D4F9, 0x00D4FA, 0x000000, 0xFFFFFF, + 0x00D4FC, 0x00D4FC, 0x000000, 0xFFFFFF, + 0x00D4FE, 0x00D503, 0x000000, 0xFFFFFF, + 0x00D505, 0x00D507, 0x000000, 0xFFFFFF, + 0x00D509, 0x00D50B, 0x000000, 0xFFFFFF, + 0x00D50D, 0x00D513, 0x000000, 0xFFFFFF, + 0x00D516, 0x00D516, 0x000000, 0xFFFFFF, + 0x00D518, 0x00D53B, 0x000000, 0xFFFFFF, + 0x00D53E, 0x00D53F, 0x000000, 0xFFFFFF, + 0x00D541, 0x00D543, 0x000000, 0xFFFFFF, + 0x00D545, 0x00D54B, 0x000000, 0xFFFFFF, + 0x00D54E, 0x00D54E, 0x000000, 0xFFFFFF, + 0x00D550, 0x00D550, 0x000000, 0xFFFFFF, + 0x00D552, 0x00D557, 0x000000, 0xFFFFFF, + 0x00D55A, 0x00D55B, 0x000000, 0xFFFFFF, + 0x00D55D, 0x00D55F, 0x000000, 0xFFFFFF, + 0x00D561, 0x00D564, 0x000000, 0xFFFFFF, + 0x00D566, 0x00D567, 0x000000, 0xFFFFFF, + 0x00D56A, 0x00D56A, 0x000000, 0xFFFFFF, + 0x00D56C, 0x00D56C, 0x000000, 0xFFFFFF, + 0x00D56E, 0x00D573, 0x000000, 0xFFFFFF, + 0x00D576, 0x00D577, 0x000000, 0xFFFFFF, + 0x00D579, 0x00D57B, 0x000000, 0xFFFFFF, + 0x00D57D, 0x00D583, 0x000000, 0xFFFFFF, + 0x00D586, 0x00D586, 0x000000, 0xFFFFFF, + 0x00D58A, 0x00D58F, 0x000000, 0xFFFFFF, + 0x00D591, 0x00D5A4, 0x000000, 0xFFFFFF, + 0x00D5A6, 0x00D5C7, 0x000000, 0xFFFFFF, + 0x00D5CA, 0x00D5CB, 0x000000, 0xFFFFFF, + 0x00D5CD, 0x00D5CF, 0x000000, 0xFFFFFF, + 0x00D5D1, 0x00D5D1, 0x000000, 0xFFFFFF, + 0x00D5D3, 0x00D5D7, 0x000000, 0xFFFFFF, + 0x00D5DA, 0x00D5DA, 0x000000, 0xFFFFFF, + 0x00D5DC, 0x00D5DC, 0x000000, 0xFFFFFF, + 0x00D5DE, 0x00D5E3, 0x000000, 0xFFFFFF, + 0x00D5E6, 0x00D5E7, 0x000000, 0xFFFFFF, + 0x00D5E9, 0x00D5EB, 0x000000, 0xFFFFFF, + 0x00D5ED, 0x00D5F3, 0x000000, 0xFFFFFF, + 0x00D5F6, 0x00D5F6, 0x000000, 0xFFFFFF, + 0x00D5F8, 0x00D5F8, 0x000000, 0xFFFFFF, + 0x00D5FA, 0x00D5FF, 0x000000, 0xFFFFFF, + 0x00D602, 0x00D603, 0x000000, 0xFFFFFF, + 0x00D605, 0x00D607, 0x000000, 0xFFFFFF, + 0x00D609, 0x00D60F, 0x000000, 0xFFFFFF, + 0x00D612, 0x00D612, 0x000000, 0xFFFFFF, + 0x00D616, 0x00D61B, 0x000000, 0xFFFFFF, + 0x00D61D, 0x00D61F, 0x000000, 0xFFFFFF, + 0x00D621, 0x00D623, 0x000000, 0xFFFFFF, + 0x00D625, 0x00D62C, 0x000000, 0xFFFFFF, + 0x00D62E, 0x00D637, 0x000000, 0xFFFFFF, + 0x00D63A, 0x00D63B, 0x000000, 0xFFFFFF, + 0x00D63D, 0x00D63F, 0x000000, 0xFFFFFF, + 0x00D641, 0x00D644, 0x000000, 0xFFFFFF, + 0x00D646, 0x00D647, 0x000000, 0xFFFFFF, + 0x00D64A, 0x00D64A, 0x000000, 0xFFFFFF, + 0x00D64C, 0x00D64C, 0x000000, 0xFFFFFF, + 0x00D64E, 0x00D650, 0x000000, 0xFFFFFF, + 0x00D652, 0x00D653, 0x000000, 0xFFFFFF, + 0x00D656, 0x00D657, 0x000000, 0xFFFFFF, + 0x00D659, 0x00D65B, 0x000000, 0xFFFFFF, + 0x00D65D, 0x00D666, 0x000000, 0xFFFFFF, + 0x00D668, 0x00D668, 0x000000, 0xFFFFFF, + 0x00D66A, 0x00D66F, 0x000000, 0xFFFFFF, + 0x00D672, 0x00D673, 0x000000, 0xFFFFFF, + 0x00D675, 0x00D682, 0x000000, 0xFFFFFF, + 0x00D684, 0x00D684, 0x000000, 0xFFFFFF, + 0x00D686, 0x00D68B, 0x000000, 0xFFFFFF, + 0x00D68E, 0x00D68F, 0x000000, 0xFFFFFF, + 0x00D691, 0x00D693, 0x000000, 0xFFFFFF, + 0x00D695, 0x00D69C, 0x000000, 0xFFFFFF, + 0x00D69E, 0x00D69E, 0x000000, 0xFFFFFF, + 0x00D6A0, 0x00D6A0, 0x000000, 0xFFFFFF, + 0x00D6A2, 0x00D6A7, 0x000000, 0xFFFFFF, + 0x00D6A9, 0x00D6AB, 0x000000, 0xFFFFFF, + 0x00D6AD, 0x00D6AF, 0x000000, 0xFFFFFF, + 0x00D6B1, 0x00D6B8, 0x000000, 0xFFFFFF, + 0x00D6BA, 0x00D6BA, 0x000000, 0xFFFFFF, + 0x00D6BC, 0x00D6C3, 0x000000, 0xFFFFFF, + 0x00D6C6, 0x00D6C7, 0x000000, 0xFFFFFF, + 0x00D6C9, 0x00D6CB, 0x000000, 0xFFFFFF, + 0x00D6CD, 0x00D6D0, 0x000000, 0xFFFFFF, + 0x00D6D2, 0x00D6D3, 0x000000, 0xFFFFFF, + 0x00D6D5, 0x00D6D6, 0x000000, 0xFFFFFF, + 0x00D6D8, 0x00D6D8, 0x000000, 0xFFFFFF, + 0x00D6DA, 0x00D6DF, 0x000000, 0xFFFFFF, + 0x00D6E1, 0x00D6E3, 0x000000, 0xFFFFFF, + 0x00D6E5, 0x00D6E7, 0x000000, 0xFFFFFF, + 0x00D6E9, 0x00D6EF, 0x000000, 0xFFFFFF, + 0x00D6F1, 0x00D6F4, 0x000000, 0xFFFFFF, + 0x00D6F6, 0x00D6FB, 0x000000, 0xFFFFFF, + 0x00D6FE, 0x00D6FF, 0x000000, 0xFFFFFF, + 0x00D701, 0x00D703, 0x000000, 0xFFFFFF, + 0x00D705, 0x00D710, 0x000000, 0xFFFFFF, + 0x00D712, 0x00D717, 0x000000, 0xFFFFFF, + 0x00D71A, 0x00D71B, 0x000000, 0xFFFFFF, + 0x00D71D, 0x00D71F, 0x000000, 0xFFFFFF, + 0x00D721, 0x00D727, 0x000000, 0xFFFFFF, + 0x00D72A, 0x00D72A, 0x000000, 0xFFFFFF, + 0x00D72C, 0x00D72C, 0x000000, 0xFFFFFF, + 0x00D72E, 0x00D733, 0x000000, 0xFFFFFF, + 0x00D736, 0x00D737, 0x000000, 0xFFFFFF, + 0x00D739, 0x00D73B, 0x000000, 0xFFFFFF, + 0x00D73D, 0x00D743, 0x000000, 0xFFFFFF, + 0x00D745, 0x00D746, 0x000000, 0xFFFFFF, + 0x00D748, 0x00D748, 0x000000, 0xFFFFFF, + 0x00D74A, 0x00D74F, 0x000000, 0xFFFFFF, + 0x00D752, 0x00D753, 0x000000, 0xFFFFFF, + 0x00D755, 0x00D755, 0x000000, 0xFFFFFF, + 0x00D75A, 0x00D75F, 0x000000, 0xFFFFFF, + 0x00D762, 0x00D762, 0x000000, 0xFFFFFF, + 0x00D764, 0x00D764, 0x000000, 0xFFFFFF, + 0x00D766, 0x00D768, 0x000000, 0xFFFFFF, + 0x00D76A, 0x00D76B, 0x000000, 0xFFFFFF, + 0x00D76D, 0x00D76F, 0x000000, 0xFFFFFF, + 0x00D771, 0x00D773, 0x000000, 0xFFFFFF, + 0x00D775, 0x00D77B, 0x000000, 0xFFFFFF, + 0x00D77E, 0x00D780, 0x000000, 0xFFFFFF, + 0x00D782, 0x00D787, 0x000000, 0xFFFFFF, + 0x00D78A, 0x00D78B, 0x000000, 0xFFFFFF, + 0x00D78D, 0x00D78F, 0x000000, 0xFFFFFF, + 0x00D791, 0x00D797, 0x000000, 0xFFFFFF, + 0x00D79A, 0x00D79A, 0x000000, 0xFFFFFF, + 0x00D79C, 0x00D79C, 0x000000, 0xFFFFFF, + 0x00D79E, 0x00F8FF, 0x000000, 0xFFFFFF, + 0x00FA0C, 0x00FF00, 0x000000, 0xFFFFFF, + 0x00FF5F, 0x00FFDF, 0x000000, 0xFFFFFF, + 0x00FFE4, 0x00FFE4, 0x000000, 0xFFFFFF, + 0x00FFE7, 0x1FFFFF, 0x000000, 0xFFFFFF, +); + +?> diff --git a/lib/php/monica/cnvtmap/GB2312.inc.php b/lib/php/monica/cnvtmap/GB2312.inc.php new file mode 100644 index 0000000..5aa120a --- /dev/null +++ b/lib/php/monica/cnvtmap/GB2312.inc.php @@ -0,0 +1,3643 @@ + +// Copyright: Copyright (C) 2005-2007 Pristine Communications + +// GB2312 +$CNVTMAP["GB2312"] = array( + 0x000080, 0x0000A3, 0x000000, 0xFFFFFF, + 0x0000A5, 0x0000A6, 0x000000, 0xFFFFFF, + 0x0000A9, 0x0000AF, 0x000000, 0xFFFFFF, + 0x0000B2, 0x0000D6, 0x000000, 0xFFFFFF, + 0x0000D8, 0x0000DF, 0x000000, 0xFFFFFF, + 0x0000E2, 0x0000E7, 0x000000, 0xFFFFFF, + 0x0000EB, 0x0000EB, 0x000000, 0xFFFFFF, + 0x0000EE, 0x0000F1, 0x000000, 0xFFFFFF, + 0x0000F4, 0x0000F6, 0x000000, 0xFFFFFF, + 0x0000F8, 0x0000F8, 0x000000, 0xFFFFFF, + 0x0000FB, 0x0000FB, 0x000000, 0xFFFFFF, + 0x0000FD, 0x000100, 0x000000, 0xFFFFFF, + 0x000102, 0x000112, 0x000000, 0xFFFFFF, + 0x000114, 0x00011A, 0x000000, 0xFFFFFF, + 0x00011C, 0x00012A, 0x000000, 0xFFFFFF, + 0x00012C, 0x00014C, 0x000000, 0xFFFFFF, + 0x00014E, 0x00016A, 0x000000, 0xFFFFFF, + 0x00016C, 0x0001CD, 0x000000, 0xFFFFFF, + 0x0001CF, 0x0001CF, 0x000000, 0xFFFFFF, + 0x0001D1, 0x0001D1, 0x000000, 0xFFFFFF, + 0x0001D3, 0x0001D3, 0x000000, 0xFFFFFF, + 0x0001D5, 0x0001D5, 0x000000, 0xFFFFFF, + 0x0001D7, 0x0001D7, 0x000000, 0xFFFFFF, + 0x0001D9, 0x0001D9, 0x000000, 0xFFFFFF, + 0x0001DB, 0x0001DB, 0x000000, 0xFFFFFF, + 0x0001DD, 0x0002C6, 0x000000, 0xFFFFFF, + 0x0002C8, 0x0002C8, 0x000000, 0xFFFFFF, + 0x0002CA, 0x000390, 0x000000, 0xFFFFFF, + 0x0003A2, 0x0003A2, 0x000000, 0xFFFFFF, + 0x0003AA, 0x0003B0, 0x000000, 0xFFFFFF, + 0x0003C2, 0x0003C2, 0x000000, 0xFFFFFF, + 0x0003CA, 0x000400, 0x000000, 0xFFFFFF, + 0x000402, 0x00040F, 0x000000, 0xFFFFFF, + 0x000450, 0x000450, 0x000000, 0xFFFFFF, + 0x000452, 0x002014, 0x000000, 0xFFFFFF, + 0x002017, 0x002017, 0x000000, 0xFFFFFF, + 0x00201A, 0x00201B, 0x000000, 0xFFFFFF, + 0x00201E, 0x002025, 0x000000, 0xFFFFFF, + 0x002027, 0x00202F, 0x000000, 0xFFFFFF, + 0x002031, 0x002031, 0x000000, 0xFFFFFF, + 0x002034, 0x00203A, 0x000000, 0xFFFFFF, + 0x00203C, 0x002102, 0x000000, 0xFFFFFF, + 0x002104, 0x002115, 0x000000, 0xFFFFFF, + 0x002117, 0x00215F, 0x000000, 0xFFFFFF, + 0x00216C, 0x00218F, 0x000000, 0xFFFFFF, + 0x002194, 0x002207, 0x000000, 0xFFFFFF, + 0x002209, 0x00220E, 0x000000, 0xFFFFFF, + 0x002210, 0x002210, 0x000000, 0xFFFFFF, + 0x002212, 0x002219, 0x000000, 0xFFFFFF, + 0x00221B, 0x00221C, 0x000000, 0xFFFFFF, + 0x00221F, 0x00221F, 0x000000, 0xFFFFFF, + 0x002221, 0x002224, 0x000000, 0xFFFFFF, + 0x002226, 0x002226, 0x000000, 0xFFFFFF, + 0x00222C, 0x00222D, 0x000000, 0xFFFFFF, + 0x00222F, 0x002233, 0x000000, 0xFFFFFF, + 0x002238, 0x00223C, 0x000000, 0xFFFFFF, + 0x00223E, 0x002247, 0x000000, 0xFFFFFF, + 0x002249, 0x00224B, 0x000000, 0xFFFFFF, + 0x00224D, 0x00225F, 0x000000, 0xFFFFFF, + 0x002262, 0x002263, 0x000000, 0xFFFFFF, + 0x002266, 0x00226D, 0x000000, 0xFFFFFF, + 0x002270, 0x002298, 0x000000, 0xFFFFFF, + 0x00229A, 0x0022A4, 0x000000, 0xFFFFFF, + 0x0022A6, 0x002311, 0x000000, 0xFFFFFF, + 0x002313, 0x00245F, 0x000000, 0xFFFFFF, + 0x00246A, 0x002473, 0x000000, 0xFFFFFF, + 0x00249C, 0x0024FF, 0x000000, 0xFFFFFF, + 0x00254C, 0x00259F, 0x000000, 0xFFFFFF, + 0x0025A2, 0x0025B1, 0x000000, 0xFFFFFF, + 0x0025B4, 0x0025C5, 0x000000, 0xFFFFFF, + 0x0025C8, 0x0025CA, 0x000000, 0xFFFFFF, + 0x0025CC, 0x0025CD, 0x000000, 0xFFFFFF, + 0x0025D0, 0x002604, 0x000000, 0xFFFFFF, + 0x002607, 0x00263F, 0x000000, 0xFFFFFF, + 0x002641, 0x002641, 0x000000, 0xFFFFFF, + 0x002643, 0x002FFF, 0x000000, 0xFFFFFF, + 0x003004, 0x003004, 0x000000, 0xFFFFFF, + 0x003006, 0x003007, 0x000000, 0xFFFFFF, + 0x003012, 0x003012, 0x000000, 0xFFFFFF, + 0x003018, 0x003040, 0x000000, 0xFFFFFF, + 0x003094, 0x0030A0, 0x000000, 0xFFFFFF, + 0x0030F7, 0x0030FA, 0x000000, 0xFFFFFF, + 0x0030FC, 0x003104, 0x000000, 0xFFFFFF, + 0x00312A, 0x00321F, 0x000000, 0xFFFFFF, + 0x00322A, 0x004DFF, 0x000000, 0xFFFFFF, + 0x004E02, 0x004E02, 0x000000, 0xFFFFFF, + 0x004E04, 0x004E06, 0x000000, 0xFFFFFF, + 0x004E0F, 0x004E0F, 0x000000, 0xFFFFFF, + 0x004E12, 0x004E12, 0x000000, 0xFFFFFF, + 0x004E17, 0x004E17, 0x000000, 0xFFFFFF, + 0x004E1F, 0x004E21, 0x000000, 0xFFFFFF, + 0x004E23, 0x004E23, 0x000000, 0xFFFFFF, + 0x004E26, 0x004E26, 0x000000, 0xFFFFFF, + 0x004E29, 0x004E29, 0x000000, 0xFFFFFF, + 0x004E2E, 0x004E2F, 0x000000, 0xFFFFFF, + 0x004E31, 0x004E31, 0x000000, 0xFFFFFF, + 0x004E33, 0x004E33, 0x000000, 0xFFFFFF, + 0x004E35, 0x004E35, 0x000000, 0xFFFFFF, + 0x004E37, 0x004E37, 0x000000, 0xFFFFFF, + 0x004E3C, 0x004E3C, 0x000000, 0xFFFFFF, + 0x004E40, 0x004E42, 0x000000, 0xFFFFFF, + 0x004E44, 0x004E44, 0x000000, 0xFFFFFF, + 0x004E46, 0x004E46, 0x000000, 0xFFFFFF, + 0x004E4A, 0x004E4A, 0x000000, 0xFFFFFF, + 0x004E51, 0x004E51, 0x000000, 0xFFFFFF, + 0x004E55, 0x004E55, 0x000000, 0xFFFFFF, + 0x004E57, 0x004E57, 0x000000, 0xFFFFFF, + 0x004E5A, 0x004E5B, 0x000000, 0xFFFFFF, + 0x004E62, 0x004E65, 0x000000, 0xFFFFFF, + 0x004E67, 0x004E68, 0x000000, 0xFFFFFF, + 0x004E6A, 0x004E6F, 0x000000, 0xFFFFFF, + 0x004E72, 0x004E72, 0x000000, 0xFFFFFF, + 0x004E74, 0x004E7D, 0x000000, 0xFFFFFF, + 0x004E7F, 0x004E85, 0x000000, 0xFFFFFF, + 0x004E87, 0x004E87, 0x000000, 0xFFFFFF, + 0x004E8A, 0x004E8A, 0x000000, 0xFFFFFF, + 0x004E90, 0x004E90, 0x000000, 0xFFFFFF, + 0x004E96, 0x004E97, 0x000000, 0xFFFFFF, + 0x004E99, 0x004E99, 0x000000, 0xFFFFFF, + 0x004E9C, 0x004E9E, 0x000000, 0xFFFFFF, + 0x004EA3, 0x004EA3, 0x000000, 0xFFFFFF, + 0x004EAA, 0x004EAA, 0x000000, 0xFFFFFF, + 0x004EAF, 0x004EB1, 0x000000, 0xFFFFFF, + 0x004EB4, 0x004EB4, 0x000000, 0xFFFFFF, + 0x004EB6, 0x004EB9, 0x000000, 0xFFFFFF, + 0x004EBC, 0x004EBE, 0x000000, 0xFFFFFF, + 0x004EC8, 0x004EC8, 0x000000, 0xFFFFFF, + 0x004ECC, 0x004ECC, 0x000000, 0xFFFFFF, + 0x004ECF, 0x004ED0, 0x000000, 0xFFFFFF, + 0x004ED2, 0x004ED2, 0x000000, 0xFFFFFF, + 0x004EDA, 0x004EDC, 0x000000, 0xFFFFFF, + 0x004EE0, 0x004EE0, 0x000000, 0xFFFFFF, + 0x004EE2, 0x004EE2, 0x000000, 0xFFFFFF, + 0x004EE6, 0x004EE7, 0x000000, 0xFFFFFF, + 0x004EE9, 0x004EE9, 0x000000, 0xFFFFFF, + 0x004EED, 0x004EEF, 0x000000, 0xFFFFFF, + 0x004EF1, 0x004EF1, 0x000000, 0xFFFFFF, + 0x004EF4, 0x004EF4, 0x000000, 0xFFFFFF, + 0x004EF8, 0x004EFA, 0x000000, 0xFFFFFF, + 0x004EFC, 0x004EFC, 0x000000, 0xFFFFFF, + 0x004EFE, 0x004EFE, 0x000000, 0xFFFFFF, + 0x004F00, 0x004F00, 0x000000, 0xFFFFFF, + 0x004F02, 0x004F08, 0x000000, 0xFFFFFF, + 0x004F0B, 0x004F0C, 0x000000, 0xFFFFFF, + 0x004F12, 0x004F16, 0x000000, 0xFFFFFF, + 0x004F1C, 0x004F1D, 0x000000, 0xFFFFFF, + 0x004F21, 0x004F21, 0x000000, 0xFFFFFF, + 0x004F23, 0x004F23, 0x000000, 0xFFFFFF, + 0x004F28, 0x004F29, 0x000000, 0xFFFFFF, + 0x004F2C, 0x004F2E, 0x000000, 0xFFFFFF, + 0x004F31, 0x004F31, 0x000000, 0xFFFFFF, + 0x004F33, 0x004F33, 0x000000, 0xFFFFFF, + 0x004F35, 0x004F35, 0x000000, 0xFFFFFF, + 0x004F37, 0x004F37, 0x000000, 0xFFFFFF, + 0x004F39, 0x004F39, 0x000000, 0xFFFFFF, + 0x004F3B, 0x004F3B, 0x000000, 0xFFFFFF, + 0x004F3E, 0x004F42, 0x000000, 0xFFFFFF, + 0x004F44, 0x004F45, 0x000000, 0xFFFFFF, + 0x004F47, 0x004F4C, 0x000000, 0xFFFFFF, + 0x004F52, 0x004F52, 0x000000, 0xFFFFFF, + 0x004F54, 0x004F54, 0x000000, 0xFFFFFF, + 0x004F56, 0x004F56, 0x000000, 0xFFFFFF, + 0x004F61, 0x004F62, 0x000000, 0xFFFFFF, + 0x004F66, 0x004F66, 0x000000, 0xFFFFFF, + 0x004F68, 0x004F68, 0x000000, 0xFFFFFF, + 0x004F6A, 0x004F6B, 0x000000, 0xFFFFFF, + 0x004F6D, 0x004F6E, 0x000000, 0xFFFFFF, + 0x004F71, 0x004F72, 0x000000, 0xFFFFFF, + 0x004F75, 0x004F75, 0x000000, 0xFFFFFF, + 0x004F77, 0x004F7A, 0x000000, 0xFFFFFF, + 0x004F7D, 0x004F7D, 0x000000, 0xFFFFFF, + 0x004F80, 0x004F82, 0x000000, 0xFFFFFF, + 0x004F85, 0x004F87, 0x000000, 0xFFFFFF, + 0x004F8A, 0x004F8A, 0x000000, 0xFFFFFF, + 0x004F8C, 0x004F8C, 0x000000, 0xFFFFFF, + 0x004F8E, 0x004F8E, 0x000000, 0xFFFFFF, + 0x004F90, 0x004F90, 0x000000, 0xFFFFFF, + 0x004F92, 0x004F93, 0x000000, 0xFFFFFF, + 0x004F95, 0x004F96, 0x000000, 0xFFFFFF, + 0x004F98, 0x004F9A, 0x000000, 0xFFFFFF, + 0x004F9C, 0x004F9C, 0x000000, 0xFFFFFF, + 0x004F9E, 0x004F9F, 0x000000, 0xFFFFFF, + 0x004FA1, 0x004FA2, 0x000000, 0xFFFFFF, + 0x004FA4, 0x004FA4, 0x000000, 0xFFFFFF, + 0x004FAB, 0x004FAB, 0x000000, 0xFFFFFF, + 0x004FAD, 0x004FAD, 0x000000, 0xFFFFFF, + 0x004FB0, 0x004FB4, 0x000000, 0xFFFFFF, + 0x004FB6, 0x004FBE, 0x000000, 0xFFFFFF, + 0x004FC0, 0x004FC2, 0x000000, 0xFFFFFF, + 0x004FC6, 0x004FC9, 0x000000, 0xFFFFFF, + 0x004FCB, 0x004FCD, 0x000000, 0xFFFFFF, + 0x004FD2, 0x004FD6, 0x000000, 0xFFFFFF, + 0x004FD9, 0x004FD9, 0x000000, 0xFFFFFF, + 0x004FDB, 0x004FDB, 0x000000, 0xFFFFFF, + 0x004FE0, 0x004FE0, 0x000000, 0xFFFFFF, + 0x004FE2, 0x004FE2, 0x000000, 0xFFFFFF, + 0x004FE4, 0x004FE5, 0x000000, 0xFFFFFF, + 0x004FE7, 0x004FE7, 0x000000, 0xFFFFFF, + 0x004FEB, 0x004FEC, 0x000000, 0xFFFFFF, + 0x004FF0, 0x004FF0, 0x000000, 0xFFFFFF, + 0x004FF2, 0x004FF2, 0x000000, 0xFFFFFF, + 0x004FF4, 0x004FF7, 0x000000, 0xFFFFFF, + 0x004FF9, 0x004FF9, 0x000000, 0xFFFFFF, + 0x004FFB, 0x004FFD, 0x000000, 0xFFFFFF, + 0x004FFF, 0x00500B, 0x000000, 0xFFFFFF, + 0x00500E, 0x00500E, 0x000000, 0xFFFFFF, + 0x005010, 0x005011, 0x000000, 0xFFFFFF, + 0x005013, 0x005013, 0x000000, 0xFFFFFF, + 0x005015, 0x005017, 0x000000, 0xFFFFFF, + 0x00501B, 0x00501B, 0x000000, 0xFFFFFF, + 0x00501D, 0x00501E, 0x000000, 0xFFFFFF, + 0x005020, 0x005020, 0x000000, 0xFFFFFF, + 0x005022, 0x005024, 0x000000, 0xFFFFFF, + 0x005027, 0x005027, 0x000000, 0xFFFFFF, + 0x00502B, 0x00502B, 0x000000, 0xFFFFFF, + 0x00502F, 0x005039, 0x000000, 0xFFFFFF, + 0x00503B, 0x00503B, 0x000000, 0xFFFFFF, + 0x00503D, 0x00503D, 0x000000, 0xFFFFFF, + 0x00503F, 0x005042, 0x000000, 0xFFFFFF, + 0x005044, 0x005046, 0x000000, 0xFFFFFF, + 0x005049, 0x00504B, 0x000000, 0xFFFFFF, + 0x00504D, 0x00504D, 0x000000, 0xFFFFFF, + 0x005050, 0x005054, 0x000000, 0xFFFFFF, + 0x005056, 0x005059, 0x000000, 0xFFFFFF, + 0x00505B, 0x00505B, 0x000000, 0xFFFFFF, + 0x00505D, 0x005064, 0x000000, 0xFFFFFF, + 0x005066, 0x00506B, 0x000000, 0xFFFFFF, + 0x00506D, 0x005075, 0x000000, 0xFFFFFF, + 0x005078, 0x00507A, 0x000000, 0xFFFFFF, + 0x00507C, 0x00507D, 0x000000, 0xFFFFFF, + 0x005081, 0x005084, 0x000000, 0xFFFFFF, + 0x005086, 0x005087, 0x000000, 0xFFFFFF, + 0x005089, 0x00508C, 0x000000, 0xFFFFFF, + 0x00508E, 0x0050A2, 0x000000, 0xFFFFFF, + 0x0050A4, 0x0050A4, 0x000000, 0xFFFFFF, + 0x0050A6, 0x0050A6, 0x000000, 0xFFFFFF, + 0x0050AA, 0x0050AB, 0x000000, 0xFFFFFF, + 0x0050AD, 0x0050B1, 0x000000, 0xFFFFFF, + 0x0050B3, 0x0050B9, 0x000000, 0xFFFFFF, + 0x0050BC, 0x0050CE, 0x000000, 0xFFFFFF, + 0x0050D0, 0x0050D5, 0x000000, 0xFFFFFF, + 0x0050D7, 0x0050D9, 0x000000, 0xFFFFFF, + 0x0050DB, 0x0050E5, 0x000000, 0xFFFFFF, + 0x0050E8, 0x0050EB, 0x000000, 0xFFFFFF, + 0x0050EF, 0x0050F2, 0x000000, 0xFFFFFF, + 0x0050F4, 0x0050F4, 0x000000, 0xFFFFFF, + 0x0050F6, 0x0050FA, 0x000000, 0xFFFFFF, + 0x0050FC, 0x005105, 0x000000, 0xFFFFFF, + 0x005108, 0x00510A, 0x000000, 0xFFFFFF, + 0x00510C, 0x005111, 0x000000, 0xFFFFFF, + 0x005113, 0x005120, 0x000000, 0xFFFFFF, + 0x005122, 0x00513E, 0x000000, 0xFFFFFF, + 0x005142, 0x005142, 0x000000, 0xFFFFFF, + 0x005147, 0x005147, 0x000000, 0xFFFFFF, + 0x00514A, 0x00514A, 0x000000, 0xFFFFFF, + 0x00514C, 0x00514C, 0x000000, 0xFFFFFF, + 0x00514E, 0x005150, 0x000000, 0xFFFFFF, + 0x005152, 0x005153, 0x000000, 0xFFFFFF, + 0x005157, 0x005159, 0x000000, 0xFFFFFF, + 0x00515B, 0x00515B, 0x000000, 0xFFFFFF, + 0x00515D, 0x005161, 0x000000, 0xFFFFFF, + 0x005163, 0x005164, 0x000000, 0xFFFFFF, + 0x005166, 0x005167, 0x000000, 0xFFFFFF, + 0x005169, 0x00516A, 0x000000, 0xFFFFFF, + 0x00516F, 0x00516F, 0x000000, 0xFFFFFF, + 0x005172, 0x005172, 0x000000, 0xFFFFFF, + 0x00517A, 0x00517A, 0x000000, 0xFFFFFF, + 0x00517E, 0x00517F, 0x000000, 0xFFFFFF, + 0x005183, 0x005184, 0x000000, 0xFFFFFF, + 0x005186, 0x005187, 0x000000, 0xFFFFFF, + 0x00518A, 0x00518B, 0x000000, 0xFFFFFF, + 0x00518E, 0x005191, 0x000000, 0xFFFFFF, + 0x005193, 0x005194, 0x000000, 0xFFFFFF, + 0x005198, 0x005198, 0x000000, 0xFFFFFF, + 0x00519A, 0x00519A, 0x000000, 0xFFFFFF, + 0x00519D, 0x00519F, 0x000000, 0xFFFFFF, + 0x0051A1, 0x0051A1, 0x000000, 0xFFFFFF, + 0x0051A3, 0x0051A3, 0x000000, 0xFFFFFF, + 0x0051A6, 0x0051AA, 0x000000, 0xFFFFFF, + 0x0051AD, 0x0051AE, 0x000000, 0xFFFFFF, + 0x0051B4, 0x0051B4, 0x000000, 0xFFFFFF, + 0x0051B8, 0x0051BA, 0x000000, 0xFFFFFF, + 0x0051BE, 0x0051BF, 0x000000, 0xFFFFFF, + 0x0051C1, 0x0051C3, 0x000000, 0xFFFFFF, + 0x0051C5, 0x0051C5, 0x000000, 0xFFFFFF, + 0x0051C8, 0x0051C8, 0x000000, 0xFFFFFF, + 0x0051CA, 0x0051CA, 0x000000, 0xFFFFFF, + 0x0051CD, 0x0051CE, 0x000000, 0xFFFFFF, + 0x0051D0, 0x0051D0, 0x000000, 0xFFFFFF, + 0x0051D2, 0x0051DA, 0x000000, 0xFFFFFF, + 0x0051DC, 0x0051DC, 0x000000, 0xFFFFFF, + 0x0051DE, 0x0051DF, 0x000000, 0xFFFFFF, + 0x0051E2, 0x0051E3, 0x000000, 0xFFFFFF, + 0x0051E5, 0x0051EA, 0x000000, 0xFFFFFF, + 0x0051EC, 0x0051EC, 0x000000, 0xFFFFFF, + 0x0051EE, 0x0051EE, 0x000000, 0xFFFFFF, + 0x0051F1, 0x0051F2, 0x000000, 0xFFFFFF, + 0x0051F4, 0x0051F4, 0x000000, 0xFFFFFF, + 0x0051F7, 0x0051F7, 0x000000, 0xFFFFFF, + 0x0051FE, 0x0051FE, 0x000000, 0xFFFFFF, + 0x005204, 0x005205, 0x000000, 0xFFFFFF, + 0x005209, 0x005209, 0x000000, 0xFFFFFF, + 0x00520B, 0x00520C, 0x000000, 0xFFFFFF, + 0x00520F, 0x005210, 0x000000, 0xFFFFFF, + 0x005213, 0x005215, 0x000000, 0xFFFFFF, + 0x00521C, 0x00521C, 0x000000, 0xFFFFFF, + 0x00521E, 0x00521F, 0x000000, 0xFFFFFF, + 0x005221, 0x005223, 0x000000, 0xFFFFFF, + 0x005225, 0x005227, 0x000000, 0xFFFFFF, + 0x00522A, 0x00522A, 0x000000, 0xFFFFFF, + 0x00522C, 0x00522C, 0x000000, 0xFFFFFF, + 0x00522F, 0x00522F, 0x000000, 0xFFFFFF, + 0x005231, 0x005232, 0x000000, 0xFFFFFF, + 0x005234, 0x005235, 0x000000, 0xFFFFFF, + 0x00523C, 0x00523C, 0x000000, 0xFFFFFF, + 0x00523E, 0x00523E, 0x000000, 0xFFFFFF, + 0x005244, 0x005249, 0x000000, 0xFFFFFF, + 0x00524B, 0x00524B, 0x000000, 0xFFFFFF, + 0x00524E, 0x00524F, 0x000000, 0xFFFFFF, + 0x005252, 0x005253, 0x000000, 0xFFFFFF, + 0x005255, 0x005255, 0x000000, 0xFFFFFF, + 0x005257, 0x00525B, 0x000000, 0xFFFFFF, + 0x00525D, 0x00525D, 0x000000, 0xFFFFFF, + 0x00525F, 0x005260, 0x000000, 0xFFFFFF, + 0x005262, 0x005264, 0x000000, 0xFFFFFF, + 0x005266, 0x005266, 0x000000, 0xFFFFFF, + 0x005268, 0x005268, 0x000000, 0xFFFFFF, + 0x00526B, 0x00526E, 0x000000, 0xFFFFFF, + 0x005270, 0x005271, 0x000000, 0xFFFFFF, + 0x005273, 0x00527C, 0x000000, 0xFFFFFF, + 0x00527E, 0x00527E, 0x000000, 0xFFFFFF, + 0x005280, 0x005280, 0x000000, 0xFFFFFF, + 0x005283, 0x005287, 0x000000, 0xFFFFFF, + 0x005289, 0x00528F, 0x000000, 0xFFFFFF, + 0x005291, 0x005292, 0x000000, 0xFFFFFF, + 0x005294, 0x00529A, 0x000000, 0xFFFFFF, + 0x00529C, 0x00529C, 0x000000, 0xFFFFFF, + 0x0052A4, 0x0052A7, 0x000000, 0xFFFFFF, + 0x0052AE, 0x0052B0, 0x000000, 0xFFFFFF, + 0x0052B4, 0x0052BD, 0x000000, 0xFFFFFF, + 0x0052C0, 0x0052C2, 0x000000, 0xFFFFFF, + 0x0052C4, 0x0052C6, 0x000000, 0xFFFFFF, + 0x0052C8, 0x0052C8, 0x000000, 0xFFFFFF, + 0x0052CA, 0x0052CA, 0x000000, 0xFFFFFF, + 0x0052CC, 0x0052CF, 0x000000, 0xFFFFFF, + 0x0052D1, 0x0052D1, 0x000000, 0xFFFFFF, + 0x0052D3, 0x0052D5, 0x000000, 0xFFFFFF, + 0x0052D7, 0x0052D7, 0x000000, 0xFFFFFF, + 0x0052D9, 0x0052DE, 0x000000, 0xFFFFFF, + 0x0052E0, 0x0052E3, 0x000000, 0xFFFFFF, + 0x0052E5, 0x0052EF, 0x000000, 0xFFFFFF, + 0x0052F1, 0x0052F8, 0x000000, 0xFFFFFF, + 0x0052FB, 0x0052FD, 0x000000, 0xFFFFFF, + 0x005301, 0x005304, 0x000000, 0xFFFFFF, + 0x005307, 0x005307, 0x000000, 0xFFFFFF, + 0x005309, 0x00530C, 0x000000, 0xFFFFFF, + 0x00530E, 0x00530E, 0x000000, 0xFFFFFF, + 0x005311, 0x005314, 0x000000, 0xFFFFFF, + 0x005318, 0x005318, 0x000000, 0xFFFFFF, + 0x00531B, 0x00531C, 0x000000, 0xFFFFFF, + 0x00531E, 0x00531F, 0x000000, 0xFFFFFF, + 0x005322, 0x005322, 0x000000, 0xFFFFFF, + 0x005324, 0x005325, 0x000000, 0xFFFFFF, + 0x005327, 0x005329, 0x000000, 0xFFFFFF, + 0x00532B, 0x00532D, 0x000000, 0xFFFFFF, + 0x00532F, 0x005338, 0x000000, 0xFFFFFF, + 0x00533C, 0x00533D, 0x000000, 0xFFFFFF, + 0x005340, 0x005340, 0x000000, 0xFFFFFF, + 0x005342, 0x005342, 0x000000, 0xFFFFFF, + 0x005344, 0x005344, 0x000000, 0xFFFFFF, + 0x005346, 0x005346, 0x000000, 0xFFFFFF, + 0x00534B, 0x00534D, 0x000000, 0xFFFFFF, + 0x005350, 0x005350, 0x000000, 0xFFFFFF, + 0x005354, 0x005354, 0x000000, 0xFFFFFF, + 0x005358, 0x005359, 0x000000, 0xFFFFFF, + 0x00535B, 0x00535B, 0x000000, 0xFFFFFF, + 0x00535D, 0x00535D, 0x000000, 0xFFFFFF, + 0x005365, 0x005365, 0x000000, 0xFFFFFF, + 0x005368, 0x005368, 0x000000, 0xFFFFFF, + 0x00536A, 0x00536A, 0x000000, 0xFFFFFF, + 0x00536C, 0x00536D, 0x000000, 0xFFFFFF, + 0x005372, 0x005372, 0x000000, 0xFFFFFF, + 0x005376, 0x005376, 0x000000, 0xFFFFFF, + 0x005379, 0x005379, 0x000000, 0xFFFFFF, + 0x00537B, 0x00537E, 0x000000, 0xFFFFFF, + 0x005380, 0x005381, 0x000000, 0xFFFFFF, + 0x005383, 0x005383, 0x000000, 0xFFFFFF, + 0x005387, 0x005388, 0x000000, 0xFFFFFF, + 0x00538A, 0x00538A, 0x000000, 0xFFFFFF, + 0x00538E, 0x005394, 0x000000, 0xFFFFFF, + 0x005396, 0x005397, 0x000000, 0xFFFFFF, + 0x005399, 0x005399, 0x000000, 0xFFFFFF, + 0x00539B, 0x00539C, 0x000000, 0xFFFFFF, + 0x00539E, 0x00539E, 0x000000, 0xFFFFFF, + 0x0053A0, 0x0053A1, 0x000000, 0xFFFFFF, + 0x0053A4, 0x0053A4, 0x000000, 0xFFFFFF, + 0x0053A7, 0x0053A7, 0x000000, 0xFFFFFF, + 0x0053AA, 0x0053AD, 0x000000, 0xFFFFFF, + 0x0053AF, 0x0053B5, 0x000000, 0xFFFFFF, + 0x0053B7, 0x0053BA, 0x000000, 0xFFFFFF, + 0x0053BC, 0x0053BE, 0x000000, 0xFFFFFF, + 0x0053C0, 0x0053C0, 0x000000, 0xFFFFFF, + 0x0053C3, 0x0053C7, 0x000000, 0xFFFFFF, + 0x0053CE, 0x0053D0, 0x000000, 0xFFFFFF, + 0x0053D2, 0x0053D3, 0x000000, 0xFFFFFF, + 0x0053D5, 0x0053D5, 0x000000, 0xFFFFFF, + 0x0053DA, 0x0053DA, 0x000000, 0xFFFFFF, + 0x0053DC, 0x0053DE, 0x000000, 0xFFFFFF, + 0x0053E1, 0x0053E2, 0x000000, 0xFFFFFF, + 0x0053E7, 0x0053E7, 0x000000, 0xFFFFFF, + 0x0053F4, 0x0053F4, 0x000000, 0xFFFFFF, + 0x0053FA, 0x0053FA, 0x000000, 0xFFFFFF, + 0x0053FE, 0x005400, 0x000000, 0xFFFFFF, + 0x005402, 0x005402, 0x000000, 0xFFFFFF, + 0x005405, 0x005405, 0x000000, 0xFFFFFF, + 0x005407, 0x005407, 0x000000, 0xFFFFFF, + 0x00540B, 0x00540B, 0x000000, 0xFFFFFF, + 0x005414, 0x005414, 0x000000, 0xFFFFFF, + 0x005418, 0x00541A, 0x000000, 0xFFFFFF, + 0x00541C, 0x00541C, 0x000000, 0xFFFFFF, + 0x005422, 0x005422, 0x000000, 0xFFFFFF, + 0x005424, 0x005425, 0x000000, 0xFFFFFF, + 0x00542A, 0x00542A, 0x000000, 0xFFFFFF, + 0x005430, 0x005430, 0x000000, 0xFFFFFF, + 0x005433, 0x005433, 0x000000, 0xFFFFFF, + 0x005436, 0x005437, 0x000000, 0xFFFFFF, + 0x00543A, 0x00543A, 0x000000, 0xFFFFFF, + 0x00543D, 0x00543D, 0x000000, 0xFFFFFF, + 0x00543F, 0x00543F, 0x000000, 0xFFFFFF, + 0x005441, 0x005442, 0x000000, 0xFFFFFF, + 0x005444, 0x005445, 0x000000, 0xFFFFFF, + 0x005447, 0x005447, 0x000000, 0xFFFFFF, + 0x005449, 0x005449, 0x000000, 0xFFFFFF, + 0x00544C, 0x00544F, 0x000000, 0xFFFFFF, + 0x005451, 0x005451, 0x000000, 0xFFFFFF, + 0x00545A, 0x00545A, 0x000000, 0xFFFFFF, + 0x00545D, 0x005461, 0x000000, 0xFFFFFF, + 0x005463, 0x005463, 0x000000, 0xFFFFFF, + 0x005465, 0x005465, 0x000000, 0xFFFFFF, + 0x005467, 0x005467, 0x000000, 0xFFFFFF, + 0x005469, 0x005470, 0x000000, 0xFFFFFF, + 0x005474, 0x005474, 0x000000, 0xFFFFFF, + 0x005479, 0x00547A, 0x000000, 0xFFFFFF, + 0x00547E, 0x00547F, 0x000000, 0xFFFFFF, + 0x005481, 0x005481, 0x000000, 0xFFFFFF, + 0x005483, 0x005483, 0x000000, 0xFFFFFF, + 0x005485, 0x005485, 0x000000, 0xFFFFFF, + 0x005487, 0x00548A, 0x000000, 0xFFFFFF, + 0x00548D, 0x00548D, 0x000000, 0xFFFFFF, + 0x005491, 0x005491, 0x000000, 0xFFFFFF, + 0x005493, 0x005493, 0x000000, 0xFFFFFF, + 0x005497, 0x005498, 0x000000, 0xFFFFFF, + 0x00549C, 0x00549C, 0x000000, 0xFFFFFF, + 0x00549E, 0x0054A2, 0x000000, 0xFFFFFF, + 0x0054A5, 0x0054A5, 0x000000, 0xFFFFFF, + 0x0054AE, 0x0054AE, 0x000000, 0xFFFFFF, + 0x0054B0, 0x0054B0, 0x000000, 0xFFFFFF, + 0x0054B2, 0x0054B2, 0x000000, 0xFFFFFF, + 0x0054B5, 0x0054B7, 0x000000, 0xFFFFFF, + 0x0054B9, 0x0054BA, 0x000000, 0xFFFFFF, + 0x0054BC, 0x0054BC, 0x000000, 0xFFFFFF, + 0x0054BE, 0x0054BE, 0x000000, 0xFFFFFF, + 0x0054C3, 0x0054C3, 0x000000, 0xFFFFFF, + 0x0054C5, 0x0054C5, 0x000000, 0xFFFFFF, + 0x0054CA, 0x0054CB, 0x000000, 0xFFFFFF, + 0x0054D6, 0x0054D6, 0x000000, 0xFFFFFF, + 0x0054D8, 0x0054D8, 0x000000, 0xFFFFFF, + 0x0054DB, 0x0054DB, 0x000000, 0xFFFFFF, + 0x0054E0, 0x0054E4, 0x000000, 0xFFFFFF, + 0x0054EB, 0x0054EC, 0x000000, 0xFFFFFF, + 0x0054EF, 0x0054F1, 0x000000, 0xFFFFFF, + 0x0054F4, 0x0054F9, 0x000000, 0xFFFFFF, + 0x0054FB, 0x0054FB, 0x000000, 0xFFFFFF, + 0x0054FE, 0x0054FE, 0x000000, 0xFFFFFF, + 0x005500, 0x005500, 0x000000, 0xFFFFFF, + 0x005502, 0x005505, 0x000000, 0xFFFFFF, + 0x005508, 0x005508, 0x000000, 0xFFFFFF, + 0x00550A, 0x00550E, 0x000000, 0xFFFFFF, + 0x005512, 0x005513, 0x000000, 0xFFFFFF, + 0x005515, 0x00551A, 0x000000, 0xFFFFFF, + 0x00551C, 0x00551F, 0x000000, 0xFFFFFF, + 0x005521, 0x005521, 0x000000, 0xFFFFFF, + 0x005525, 0x005526, 0x000000, 0xFFFFFF, + 0x005528, 0x005529, 0x000000, 0xFFFFFF, + 0x00552B, 0x00552B, 0x000000, 0xFFFFFF, + 0x00552D, 0x00552D, 0x000000, 0xFFFFFF, + 0x005532, 0x005532, 0x000000, 0xFFFFFF, + 0x005534, 0x005536, 0x000000, 0xFFFFFF, + 0x005538, 0x00553B, 0x000000, 0xFFFFFF, + 0x00553D, 0x00553D, 0x000000, 0xFFFFFF, + 0x005540, 0x005540, 0x000000, 0xFFFFFF, + 0x005542, 0x005542, 0x000000, 0xFFFFFF, + 0x005545, 0x005545, 0x000000, 0xFFFFFF, + 0x005547, 0x005548, 0x000000, 0xFFFFFF, + 0x00554B, 0x00554F, 0x000000, 0xFFFFFF, + 0x005551, 0x005554, 0x000000, 0xFFFFFF, + 0x005557, 0x00555B, 0x000000, 0xFFFFFF, + 0x00555D, 0x005560, 0x000000, 0xFFFFFF, + 0x005562, 0x005563, 0x000000, 0xFFFFFF, + 0x005568, 0x005569, 0x000000, 0xFFFFFF, + 0x00556B, 0x00556B, 0x000000, 0xFFFFFF, + 0x00556F, 0x005574, 0x000000, 0xFFFFFF, + 0x005579, 0x00557A, 0x000000, 0xFFFFFF, + 0x00557D, 0x00557D, 0x000000, 0xFFFFFF, + 0x00557F, 0x00557F, 0x000000, 0xFFFFFF, + 0x005585, 0x005586, 0x000000, 0xFFFFFF, + 0x00558C, 0x00558E, 0x000000, 0xFFFFFF, + 0x005590, 0x005590, 0x000000, 0xFFFFFF, + 0x005592, 0x005593, 0x000000, 0xFFFFFF, + 0x005595, 0x005597, 0x000000, 0xFFFFFF, + 0x00559A, 0x00559B, 0x000000, 0xFFFFFF, + 0x00559E, 0x00559E, 0x000000, 0xFFFFFF, + 0x0055A0, 0x0055A6, 0x000000, 0xFFFFFF, + 0x0055A8, 0x0055B0, 0x000000, 0xFFFFFF, + 0x0055B2, 0x0055B2, 0x000000, 0xFFFFFF, + 0x0055B4, 0x0055B4, 0x000000, 0xFFFFFF, + 0x0055B6, 0x0055B6, 0x000000, 0xFFFFFF, + 0x0055B8, 0x0055B8, 0x000000, 0xFFFFFF, + 0x0055BA, 0x0055BA, 0x000000, 0xFFFFFF, + 0x0055BC, 0x0055BC, 0x000000, 0xFFFFFF, + 0x0055BF, 0x0055C3, 0x000000, 0xFFFFFF, + 0x0055C6, 0x0055C8, 0x000000, 0xFFFFFF, + 0x0055CA, 0x0055CB, 0x000000, 0xFFFFFF, + 0x0055CE, 0x0055D0, 0x000000, 0xFFFFFF, + 0x0055D5, 0x0055D5, 0x000000, 0xFFFFFF, + 0x0055D7, 0x0055DB, 0x000000, 0xFFFFFF, + 0x0055DE, 0x0055DE, 0x000000, 0xFFFFFF, + 0x0055E0, 0x0055E0, 0x000000, 0xFFFFFF, + 0x0055E2, 0x0055E2, 0x000000, 0xFFFFFF, + 0x0055E7, 0x0055E7, 0x000000, 0xFFFFFF, + 0x0055E9, 0x0055E9, 0x000000, 0xFFFFFF, + 0x0055ED, 0x0055EE, 0x000000, 0xFFFFFF, + 0x0055F0, 0x0055F1, 0x000000, 0xFFFFFF, + 0x0055F4, 0x0055F4, 0x000000, 0xFFFFFF, + 0x0055F6, 0x0055F6, 0x000000, 0xFFFFFF, + 0x0055F8, 0x0055FC, 0x000000, 0xFFFFFF, + 0x0055FF, 0x0055FF, 0x000000, 0xFFFFFF, + 0x005602, 0x005607, 0x000000, 0xFFFFFF, + 0x00560A, 0x00560B, 0x000000, 0xFFFFFF, + 0x00560D, 0x00560D, 0x000000, 0xFFFFFF, + 0x005610, 0x005617, 0x000000, 0xFFFFFF, + 0x005619, 0x00561A, 0x000000, 0xFFFFFF, + 0x00561C, 0x00561D, 0x000000, 0xFFFFFF, + 0x005620, 0x005622, 0x000000, 0xFFFFFF, + 0x005625, 0x005626, 0x000000, 0xFFFFFF, + 0x005628, 0x00562B, 0x000000, 0xFFFFFF, + 0x00562E, 0x005630, 0x000000, 0xFFFFFF, + 0x005633, 0x005633, 0x000000, 0xFFFFFF, + 0x005635, 0x005635, 0x000000, 0xFFFFFF, + 0x005637, 0x005638, 0x000000, 0xFFFFFF, + 0x00563A, 0x00563A, 0x000000, 0xFFFFFF, + 0x00563C, 0x00563E, 0x000000, 0xFFFFFF, + 0x005640, 0x00564B, 0x000000, 0xFFFFFF, + 0x00564F, 0x005653, 0x000000, 0xFFFFFF, + 0x005655, 0x005656, 0x000000, 0xFFFFFF, + 0x00565A, 0x00565B, 0x000000, 0xFFFFFF, + 0x00565D, 0x005661, 0x000000, 0xFFFFFF, + 0x005663, 0x005663, 0x000000, 0xFFFFFF, + 0x005665, 0x005667, 0x000000, 0xFFFFFF, + 0x00566D, 0x005670, 0x000000, 0xFFFFFF, + 0x005672, 0x005675, 0x000000, 0xFFFFFF, + 0x005677, 0x00567A, 0x000000, 0xFFFFFF, + 0x00567D, 0x005684, 0x000000, 0xFFFFFF, + 0x005687, 0x00568D, 0x000000, 0xFFFFFF, + 0x005690, 0x005692, 0x000000, 0xFFFFFF, + 0x005694, 0x0056A2, 0x000000, 0xFFFFFF, + 0x0056A4, 0x0056AE, 0x000000, 0xFFFFFF, + 0x0056B0, 0x0056B6, 0x000000, 0xFFFFFF, + 0x0056B8, 0x0056BB, 0x000000, 0xFFFFFF, + 0x0056BD, 0x0056C9, 0x000000, 0xFFFFFF, + 0x0056CB, 0x0056D3, 0x000000, 0xFFFFFF, + 0x0056D5, 0x0056D6, 0x000000, 0xFFFFFF, + 0x0056D8, 0x0056D9, 0x000000, 0xFFFFFF, + 0x0056DC, 0x0056DC, 0x000000, 0xFFFFFF, + 0x0056E3, 0x0056E3, 0x000000, 0xFFFFFF, + 0x0056E5, 0x0056EA, 0x000000, 0xFFFFFF, + 0x0056EC, 0x0056EC, 0x000000, 0xFFFFFF, + 0x0056EE, 0x0056EF, 0x000000, 0xFFFFFF, + 0x0056F2, 0x0056F3, 0x000000, 0xFFFFFF, + 0x0056F6, 0x0056F8, 0x000000, 0xFFFFFF, + 0x0056FB, 0x0056FC, 0x000000, 0xFFFFFF, + 0x005700, 0x005702, 0x000000, 0xFFFFFF, + 0x005705, 0x005705, 0x000000, 0xFFFFFF, + 0x005707, 0x005707, 0x000000, 0xFFFFFF, + 0x00570B, 0x00571B, 0x000000, 0xFFFFFF, + 0x00571D, 0x00571E, 0x000000, 0xFFFFFF, + 0x005720, 0x005722, 0x000000, 0xFFFFFF, + 0x005724, 0x005727, 0x000000, 0xFFFFFF, + 0x00572B, 0x00572B, 0x000000, 0xFFFFFF, + 0x005731, 0x005732, 0x000000, 0xFFFFFF, + 0x005734, 0x005738, 0x000000, 0xFFFFFF, + 0x00573C, 0x00573D, 0x000000, 0xFFFFFF, + 0x00573F, 0x00573F, 0x000000, 0xFFFFFF, + 0x005741, 0x005741, 0x000000, 0xFFFFFF, + 0x005743, 0x005746, 0x000000, 0xFFFFFF, + 0x005748, 0x005749, 0x000000, 0xFFFFFF, + 0x00574B, 0x00574B, 0x000000, 0xFFFFFF, + 0x005752, 0x005756, 0x000000, 0xFFFFFF, + 0x005758, 0x005759, 0x000000, 0xFFFFFF, + 0x005762, 0x005763, 0x000000, 0xFFFFFF, + 0x005765, 0x005765, 0x000000, 0xFFFFFF, + 0x005767, 0x005767, 0x000000, 0xFFFFFF, + 0x00576C, 0x00576C, 0x000000, 0xFFFFFF, + 0x00576E, 0x00576E, 0x000000, 0xFFFFFF, + 0x005770, 0x005772, 0x000000, 0xFFFFFF, + 0x005774, 0x005775, 0x000000, 0xFFFFFF, + 0x005778, 0x00577A, 0x000000, 0xFFFFFF, + 0x00577D, 0x005781, 0x000000, 0xFFFFFF, + 0x005787, 0x00578A, 0x000000, 0xFFFFFF, + 0x00578D, 0x005791, 0x000000, 0xFFFFFF, + 0x005794, 0x00579A, 0x000000, 0xFFFFFF, + 0x00579C, 0x00579F, 0x000000, 0xFFFFFF, + 0x0057A5, 0x0057A5, 0x000000, 0xFFFFFF, + 0x0057A8, 0x0057A8, 0x000000, 0xFFFFFF, + 0x0057AA, 0x0057AA, 0x000000, 0xFFFFFF, + 0x0057AC, 0x0057AC, 0x000000, 0xFFFFFF, + 0x0057AF, 0x0057B1, 0x000000, 0xFFFFFF, + 0x0057B3, 0x0057B3, 0x000000, 0xFFFFFF, + 0x0057B5, 0x0057B7, 0x000000, 0xFFFFFF, + 0x0057B9, 0x0057C1, 0x000000, 0xFFFFFF, + 0x0057C4, 0x0057CA, 0x000000, 0xFFFFFF, + 0x0057CC, 0x0057CD, 0x000000, 0xFFFFFF, + 0x0057D0, 0x0057D1, 0x000000, 0xFFFFFF, + 0x0057D3, 0x0057D3, 0x000000, 0xFFFFFF, + 0x0057D6, 0x0057D7, 0x000000, 0xFFFFFF, + 0x0057DB, 0x0057DC, 0x000000, 0xFFFFFF, + 0x0057DE, 0x0057DE, 0x000000, 0xFFFFFF, + 0x0057E1, 0x0057E3, 0x000000, 0xFFFFFF, + 0x0057E5, 0x0057EC, 0x000000, 0xFFFFFF, + 0x0057EE, 0x0057EE, 0x000000, 0xFFFFFF, + 0x0057F0, 0x0057F3, 0x000000, 0xFFFFFF, + 0x0057F5, 0x0057F7, 0x000000, 0xFFFFFF, + 0x0057FB, 0x0057FC, 0x000000, 0xFFFFFF, + 0x0057FE, 0x0057FF, 0x000000, 0xFFFFFF, + 0x005801, 0x005801, 0x000000, 0xFFFFFF, + 0x005803, 0x005805, 0x000000, 0xFFFFFF, + 0x005808, 0x00580A, 0x000000, 0xFFFFFF, + 0x00580C, 0x00580C, 0x000000, 0xFFFFFF, + 0x00580E, 0x005810, 0x000000, 0xFFFFFF, + 0x005812, 0x005814, 0x000000, 0xFFFFFF, + 0x005816, 0x005818, 0x000000, 0xFFFFFF, + 0x00581A, 0x00581D, 0x000000, 0xFFFFFF, + 0x00581F, 0x00581F, 0x000000, 0xFFFFFF, + 0x005822, 0x005823, 0x000000, 0xFFFFFF, + 0x005825, 0x005829, 0x000000, 0xFFFFFF, + 0x00582B, 0x00582F, 0x000000, 0xFFFFFF, + 0x005831, 0x005834, 0x000000, 0xFFFFFF, + 0x005836, 0x005843, 0x000000, 0xFFFFFF, + 0x005845, 0x00584B, 0x000000, 0xFFFFFF, + 0x00584E, 0x005850, 0x000000, 0xFFFFFF, + 0x005852, 0x005853, 0x000000, 0xFFFFFF, + 0x005855, 0x005857, 0x000000, 0xFFFFFF, + 0x005859, 0x00585D, 0x000000, 0xFFFFFF, + 0x00585F, 0x005864, 0x000000, 0xFFFFFF, + 0x005866, 0x00586A, 0x000000, 0xFFFFFF, + 0x00586D, 0x00587D, 0x000000, 0xFFFFFF, + 0x00587F, 0x00587F, 0x000000, 0xFFFFFF, + 0x005882, 0x005882, 0x000000, 0xFFFFFF, + 0x005884, 0x005884, 0x000000, 0xFFFFFF, + 0x005886, 0x005888, 0x000000, 0xFFFFFF, + 0x00588A, 0x005891, 0x000000, 0xFFFFFF, + 0x005894, 0x005898, 0x000000, 0xFFFFFF, + 0x00589B, 0x00589D, 0x000000, 0xFFFFFF, + 0x0058A0, 0x0058A7, 0x000000, 0xFFFFFF, + 0x0058AA, 0x0058BB, 0x000000, 0xFFFFFF, + 0x0058BD, 0x0058C0, 0x000000, 0xFFFFFF, + 0x0058C2, 0x0058C4, 0x000000, 0xFFFFFF, + 0x0058C6, 0x0058D0, 0x000000, 0xFFFFFF, + 0x0058D2, 0x0058D4, 0x000000, 0xFFFFFF, + 0x0058D6, 0x0058E3, 0x000000, 0xFFFFFF, + 0x0058E5, 0x0058EA, 0x000000, 0xFFFFFF, + 0x0058ED, 0x0058ED, 0x000000, 0xFFFFFF, + 0x0058EF, 0x0058EF, 0x000000, 0xFFFFFF, + 0x0058F1, 0x0058F2, 0x000000, 0xFFFFFF, + 0x0058F4, 0x0058F5, 0x000000, 0xFFFFFF, + 0x0058F7, 0x0058F8, 0x000000, 0xFFFFFF, + 0x0058FA, 0x005901, 0x000000, 0xFFFFFF, + 0x005903, 0x005903, 0x000000, 0xFFFFFF, + 0x005905, 0x005906, 0x000000, 0xFFFFFF, + 0x005908, 0x00590C, 0x000000, 0xFFFFFF, + 0x00590E, 0x00590E, 0x000000, 0xFFFFFF, + 0x005910, 0x005913, 0x000000, 0xFFFFFF, + 0x005917, 0x005918, 0x000000, 0xFFFFFF, + 0x00591B, 0x00591B, 0x000000, 0xFFFFFF, + 0x00591D, 0x00591E, 0x000000, 0xFFFFFF, + 0x005920, 0x005923, 0x000000, 0xFFFFFF, + 0x005926, 0x005926, 0x000000, 0xFFFFFF, + 0x005928, 0x005928, 0x000000, 0xFFFFFF, + 0x00592C, 0x00592C, 0x000000, 0xFFFFFF, + 0x005930, 0x005930, 0x000000, 0xFFFFFF, + 0x005932, 0x005933, 0x000000, 0xFFFFFF, + 0x005935, 0x005936, 0x000000, 0xFFFFFF, + 0x00593B, 0x00593B, 0x000000, 0xFFFFFF, + 0x00593D, 0x005940, 0x000000, 0xFFFFFF, + 0x005943, 0x005943, 0x000000, 0xFFFFFF, + 0x005945, 0x005946, 0x000000, 0xFFFFFF, + 0x00594A, 0x00594A, 0x000000, 0xFFFFFF, + 0x00594C, 0x00594D, 0x000000, 0xFFFFFF, + 0x005950, 0x005950, 0x000000, 0xFFFFFF, + 0x005952, 0x005953, 0x000000, 0xFFFFFF, + 0x005959, 0x005959, 0x000000, 0xFFFFFF, + 0x00595B, 0x00595F, 0x000000, 0xFFFFFF, + 0x005961, 0x005961, 0x000000, 0xFFFFFF, + 0x005963, 0x005964, 0x000000, 0xFFFFFF, + 0x005966, 0x005972, 0x000000, 0xFFFFFF, + 0x005975, 0x005975, 0x000000, 0xFFFFFF, + 0x005977, 0x005977, 0x000000, 0xFFFFFF, + 0x00597A, 0x00597C, 0x000000, 0xFFFFFF, + 0x00597E, 0x005980, 0x000000, 0xFFFFFF, + 0x005985, 0x005985, 0x000000, 0xFFFFFF, + 0x005989, 0x005989, 0x000000, 0xFFFFFF, + 0x00598B, 0x00598C, 0x000000, 0xFFFFFF, + 0x00598E, 0x005991, 0x000000, 0xFFFFFF, + 0x005994, 0x005995, 0x000000, 0xFFFFFF, + 0x005998, 0x005998, 0x000000, 0xFFFFFF, + 0x00599A, 0x00599D, 0x000000, 0xFFFFFF, + 0x00599F, 0x0059A2, 0x000000, 0xFFFFFF, + 0x0059A6, 0x0059A7, 0x000000, 0xFFFFFF, + 0x0059AC, 0x0059AD, 0x000000, 0xFFFFFF, + 0x0059B0, 0x0059B1, 0x000000, 0xFFFFFF, + 0x0059B3, 0x0059B8, 0x000000, 0xFFFFFF, + 0x0059BA, 0x0059BA, 0x000000, 0xFFFFFF, + 0x0059BC, 0x0059BD, 0x000000, 0xFFFFFF, + 0x0059BF, 0x0059C5, 0x000000, 0xFFFFFF, + 0x0059C7, 0x0059C9, 0x000000, 0xFFFFFF, + 0x0059CC, 0x0059CF, 0x000000, 0xFFFFFF, + 0x0059D5, 0x0059D6, 0x000000, 0xFFFFFF, + 0x0059D9, 0x0059D9, 0x000000, 0xFFFFFF, + 0x0059DB, 0x0059DB, 0x000000, 0xFFFFFF, + 0x0059DE, 0x0059E2, 0x000000, 0xFFFFFF, + 0x0059E4, 0x0059E4, 0x000000, 0xFFFFFF, + 0x0059E6, 0x0059E7, 0x000000, 0xFFFFFF, + 0x0059E9, 0x0059EB, 0x000000, 0xFFFFFF, + 0x0059ED, 0x0059F8, 0x000000, 0xFFFFFF, + 0x0059FA, 0x0059FA, 0x000000, 0xFFFFFF, + 0x0059FC, 0x0059FE, 0x000000, 0xFFFFFF, + 0x005A00, 0x005A00, 0x000000, 0xFFFFFF, + 0x005A02, 0x005A02, 0x000000, 0xFFFFFF, + 0x005A0A, 0x005A0B, 0x000000, 0xFFFFFF, + 0x005A0D, 0x005A10, 0x000000, 0xFFFFFF, + 0x005A12, 0x005A12, 0x000000, 0xFFFFFF, + 0x005A14, 0x005A17, 0x000000, 0xFFFFFF, + 0x005A19, 0x005A1B, 0x000000, 0xFFFFFF, + 0x005A1D, 0x005A1E, 0x000000, 0xFFFFFF, + 0x005A21, 0x005A22, 0x000000, 0xFFFFFF, + 0x005A24, 0x005A24, 0x000000, 0xFFFFFF, + 0x005A26, 0x005A28, 0x000000, 0xFFFFFF, + 0x005A2A, 0x005A30, 0x000000, 0xFFFFFF, + 0x005A33, 0x005A33, 0x000000, 0xFFFFFF, + 0x005A35, 0x005A35, 0x000000, 0xFFFFFF, + 0x005A37, 0x005A3B, 0x000000, 0xFFFFFF, + 0x005A3D, 0x005A3F, 0x000000, 0xFFFFFF, + 0x005A41, 0x005A45, 0x000000, 0xFFFFFF, + 0x005A47, 0x005A48, 0x000000, 0xFFFFFF, + 0x005A4B, 0x005A54, 0x000000, 0xFFFFFF, + 0x005A56, 0x005A59, 0x000000, 0xFFFFFF, + 0x005A5B, 0x005A61, 0x000000, 0xFFFFFF, + 0x005A63, 0x005A66, 0x000000, 0xFFFFFF, + 0x005A68, 0x005A69, 0x000000, 0xFFFFFF, + 0x005A6B, 0x005A73, 0x000000, 0xFFFFFF, + 0x005A78, 0x005A79, 0x000000, 0xFFFFFF, + 0x005A7B, 0x005A7E, 0x000000, 0xFFFFFF, + 0x005A80, 0x005A91, 0x000000, 0xFFFFFF, + 0x005A93, 0x005A99, 0x000000, 0xFFFFFF, + 0x005A9C, 0x005AA9, 0x000000, 0xFFFFFF, + 0x005AAB, 0x005AB1, 0x000000, 0xFFFFFF, + 0x005AB4, 0x005AB4, 0x000000, 0xFFFFFF, + 0x005AB6, 0x005AB7, 0x000000, 0xFFFFFF, + 0x005AB9, 0x005ABD, 0x000000, 0xFFFFFF, + 0x005ABF, 0x005AC0, 0x000000, 0xFFFFFF, + 0x005AC3, 0x005AC8, 0x000000, 0xFFFFFF, + 0x005ACA, 0x005ACB, 0x000000, 0xFFFFFF, + 0x005ACD, 0x005AD1, 0x000000, 0xFFFFFF, + 0x005AD3, 0x005AD3, 0x000000, 0xFFFFFF, + 0x005AD5, 0x005AD5, 0x000000, 0xFFFFFF, + 0x005AD7, 0x005AD7, 0x000000, 0xFFFFFF, + 0x005AD9, 0x005ADB, 0x000000, 0xFFFFFF, + 0x005ADD, 0x005ADF, 0x000000, 0xFFFFFF, + 0x005AE2, 0x005AE2, 0x000000, 0xFFFFFF, + 0x005AE4, 0x005AE5, 0x000000, 0xFFFFFF, + 0x005AE7, 0x005AE8, 0x000000, 0xFFFFFF, + 0x005AEA, 0x005AEA, 0x000000, 0xFFFFFF, + 0x005AEC, 0x005AF0, 0x000000, 0xFFFFFF, + 0x005AF2, 0x005B08, 0x000000, 0xFFFFFF, + 0x005B0A, 0x005B15, 0x000000, 0xFFFFFF, + 0x005B18, 0x005B31, 0x000000, 0xFFFFFF, + 0x005B33, 0x005B33, 0x000000, 0xFFFFFF, + 0x005B35, 0x005B36, 0x000000, 0xFFFFFF, + 0x005B38, 0x005B3F, 0x000000, 0xFFFFFF, + 0x005B41, 0x005B4F, 0x000000, 0xFFFFFF, + 0x005B52, 0x005B52, 0x000000, 0xFFFFFF, + 0x005B56, 0x005B56, 0x000000, 0xFFFFFF, + 0x005B5E, 0x005B5E, 0x000000, 0xFFFFFF, + 0x005B60, 0x005B61, 0x000000, 0xFFFFFF, + 0x005B67, 0x005B68, 0x000000, 0xFFFFFF, + 0x005B6B, 0x005B6B, 0x000000, 0xFFFFFF, + 0x005B6D, 0x005B6F, 0x000000, 0xFFFFFF, + 0x005B72, 0x005B72, 0x000000, 0xFFFFFF, + 0x005B74, 0x005B74, 0x000000, 0xFFFFFF, + 0x005B76, 0x005B79, 0x000000, 0xFFFFFF, + 0x005B7B, 0x005B7C, 0x000000, 0xFFFFFF, + 0x005B7E, 0x005B7F, 0x000000, 0xFFFFFF, + 0x005B82, 0x005B82, 0x000000, 0xFFFFFF, + 0x005B86, 0x005B86, 0x000000, 0xFFFFFF, + 0x005B8A, 0x005B8A, 0x000000, 0xFFFFFF, + 0x005B8D, 0x005B8E, 0x000000, 0xFFFFFF, + 0x005B90, 0x005B92, 0x000000, 0xFFFFFF, + 0x005B94, 0x005B94, 0x000000, 0xFFFFFF, + 0x005B96, 0x005B96, 0x000000, 0xFFFFFF, + 0x005B9F, 0x005B9F, 0x000000, 0xFFFFFF, + 0x005BA7, 0x005BA9, 0x000000, 0xFFFFFF, + 0x005BAC, 0x005BAF, 0x000000, 0xFFFFFF, + 0x005BB1, 0x005BB2, 0x000000, 0xFFFFFF, + 0x005BB7, 0x005BB7, 0x000000, 0xFFFFFF, + 0x005BBA, 0x005BBC, 0x000000, 0xFFFFFF, + 0x005BC0, 0x005BC1, 0x000000, 0xFFFFFF, + 0x005BC3, 0x005BC3, 0x000000, 0xFFFFFF, + 0x005BC8, 0x005BCB, 0x000000, 0xFFFFFF, + 0x005BCD, 0x005BCF, 0x000000, 0xFFFFFF, + 0x005BD1, 0x005BD1, 0x000000, 0xFFFFFF, + 0x005BD4, 0x005BDC, 0x000000, 0xFFFFFF, + 0x005BE0, 0x005BE0, 0x000000, 0xFFFFFF, + 0x005BE2, 0x005BE3, 0x000000, 0xFFFFFF, + 0x005BE6, 0x005BE7, 0x000000, 0xFFFFFF, + 0x005BE9, 0x005BED, 0x000000, 0xFFFFFF, + 0x005BEF, 0x005BEF, 0x000000, 0xFFFFFF, + 0x005BF1, 0x005BF7, 0x000000, 0xFFFFFF, + 0x005BFD, 0x005BFE, 0x000000, 0xFFFFFF, + 0x005C00, 0x005C00, 0x000000, 0xFFFFFF, + 0x005C02, 0x005C03, 0x000000, 0xFFFFFF, + 0x005C05, 0x005C05, 0x000000, 0xFFFFFF, + 0x005C07, 0x005C08, 0x000000, 0xFFFFFF, + 0x005C0B, 0x005C0E, 0x000000, 0xFFFFFF, + 0x005C10, 0x005C10, 0x000000, 0xFFFFFF, + 0x005C12, 0x005C13, 0x000000, 0xFFFFFF, + 0x005C17, 0x005C17, 0x000000, 0xFFFFFF, + 0x005C19, 0x005C19, 0x000000, 0xFFFFFF, + 0x005C1B, 0x005C1B, 0x000000, 0xFFFFFF, + 0x005C1E, 0x005C21, 0x000000, 0xFFFFFF, + 0x005C23, 0x005C23, 0x000000, 0xFFFFFF, + 0x005C26, 0x005C26, 0x000000, 0xFFFFFF, + 0x005C28, 0x005C2B, 0x000000, 0xFFFFFF, + 0x005C2D, 0x005C30, 0x000000, 0xFFFFFF, + 0x005C32, 0x005C33, 0x000000, 0xFFFFFF, + 0x005C35, 0x005C37, 0x000000, 0xFFFFFF, + 0x005C43, 0x005C44, 0x000000, 0xFFFFFF, + 0x005C46, 0x005C47, 0x000000, 0xFFFFFF, + 0x005C4C, 0x005C4D, 0x000000, 0xFFFFFF, + 0x005C52, 0x005C54, 0x000000, 0xFFFFFF, + 0x005C56, 0x005C58, 0x000000, 0xFFFFFF, + 0x005C5A, 0x005C5D, 0x000000, 0xFFFFFF, + 0x005C5F, 0x005C5F, 0x000000, 0xFFFFFF, + 0x005C62, 0x005C62, 0x000000, 0xFFFFFF, + 0x005C64, 0x005C64, 0x000000, 0xFFFFFF, + 0x005C67, 0x005C6D, 0x000000, 0xFFFFFF, + 0x005C70, 0x005C70, 0x000000, 0xFFFFFF, + 0x005C72, 0x005C78, 0x000000, 0xFFFFFF, + 0x005C7B, 0x005C7E, 0x000000, 0xFFFFFF, + 0x005C80, 0x005C80, 0x000000, 0xFFFFFF, + 0x005C83, 0x005C87, 0x000000, 0xFFFFFF, + 0x005C89, 0x005C8B, 0x000000, 0xFFFFFF, + 0x005C8E, 0x005C8F, 0x000000, 0xFFFFFF, + 0x005C92, 0x005C93, 0x000000, 0xFFFFFF, + 0x005C95, 0x005C95, 0x000000, 0xFFFFFF, + 0x005C9D, 0x005CA1, 0x000000, 0xFFFFFF, + 0x005CA4, 0x005CA8, 0x000000, 0xFFFFFF, + 0x005CAA, 0x005CAA, 0x000000, 0xFFFFFF, + 0x005CAE, 0x005CB0, 0x000000, 0xFFFFFF, + 0x005CB2, 0x005CB2, 0x000000, 0xFFFFFF, + 0x005CB4, 0x005CB4, 0x000000, 0xFFFFFF, + 0x005CB6, 0x005CB6, 0x000000, 0xFFFFFF, + 0x005CB9, 0x005CBC, 0x000000, 0xFFFFFF, + 0x005CBE, 0x005CBE, 0x000000, 0xFFFFFF, + 0x005CC0, 0x005CC0, 0x000000, 0xFFFFFF, + 0x005CC2, 0x005CC3, 0x000000, 0xFFFFFF, + 0x005CC5, 0x005CCA, 0x000000, 0xFFFFFF, + 0x005CCC, 0x005CD1, 0x000000, 0xFFFFFF, + 0x005CD3, 0x005CD8, 0x000000, 0xFFFFFF, + 0x005CDA, 0x005CE0, 0x000000, 0xFFFFFF, + 0x005CE2, 0x005CE3, 0x000000, 0xFFFFFF, + 0x005CE7, 0x005CE7, 0x000000, 0xFFFFFF, + 0x005CE9, 0x005CE9, 0x000000, 0xFFFFFF, + 0x005CEB, 0x005CEC, 0x000000, 0xFFFFFF, + 0x005CEE, 0x005CEF, 0x000000, 0xFFFFFF, + 0x005CF1, 0x005CFA, 0x000000, 0xFFFFFF, + 0x005CFC, 0x005D01, 0x000000, 0xFFFFFF, + 0x005D04, 0x005D05, 0x000000, 0xFFFFFF, + 0x005D08, 0x005D0D, 0x000000, 0xFFFFFF, + 0x005D0F, 0x005D13, 0x000000, 0xFFFFFF, + 0x005D15, 0x005D15, 0x000000, 0xFFFFFF, + 0x005D17, 0x005D1A, 0x000000, 0xFFFFFF, + 0x005D1C, 0x005D1D, 0x000000, 0xFFFFFF, + 0x005D1F, 0x005D23, 0x000000, 0xFFFFFF, + 0x005D25, 0x005D25, 0x000000, 0xFFFFFF, + 0x005D28, 0x005D28, 0x000000, 0xFFFFFF, + 0x005D2A, 0x005D2C, 0x000000, 0xFFFFFF, + 0x005D2F, 0x005D33, 0x000000, 0xFFFFFF, + 0x005D35, 0x005D3C, 0x000000, 0xFFFFFF, + 0x005D3F, 0x005D46, 0x000000, 0xFFFFFF, + 0x005D48, 0x005D49, 0x000000, 0xFFFFFF, + 0x005D4D, 0x005D57, 0x000000, 0xFFFFFF, + 0x005D59, 0x005D5A, 0x000000, 0xFFFFFF, + 0x005D5C, 0x005D5C, 0x000000, 0xFFFFFF, + 0x005D5E, 0x005D68, 0x000000, 0xFFFFFF, + 0x005D6A, 0x005D6A, 0x000000, 0xFFFFFF, + 0x005D6D, 0x005D6E, 0x000000, 0xFFFFFF, + 0x005D70, 0x005D73, 0x000000, 0xFFFFFF, + 0x005D75, 0x005D81, 0x000000, 0xFFFFFF, + 0x005D83, 0x005D98, 0x000000, 0xFFFFFF, + 0x005D9A, 0x005D9C, 0x000000, 0xFFFFFF, + 0x005D9E, 0x005DB6, 0x000000, 0xFFFFFF, + 0x005DB8, 0x005DC4, 0x000000, 0xFFFFFF, + 0x005DC6, 0x005DCC, 0x000000, 0xFFFFFF, + 0x005DCE, 0x005DDA, 0x000000, 0xFFFFFF, + 0x005DDC, 0x005DDC, 0x000000, 0xFFFFFF, + 0x005DDF, 0x005DE0, 0x000000, 0xFFFFFF, + 0x005DE3, 0x005DE4, 0x000000, 0xFFFFFF, + 0x005DEA, 0x005DEA, 0x000000, 0xFFFFFF, + 0x005DEC, 0x005DED, 0x000000, 0xFFFFFF, + 0x005DF0, 0x005DF0, 0x000000, 0xFFFFFF, + 0x005DF5, 0x005DF6, 0x000000, 0xFFFFFF, + 0x005DF8, 0x005DFC, 0x000000, 0xFFFFFF, + 0x005DFF, 0x005E00, 0x000000, 0xFFFFFF, + 0x005E04, 0x005E04, 0x000000, 0xFFFFFF, + 0x005E07, 0x005E07, 0x000000, 0xFFFFFF, + 0x005E09, 0x005E0B, 0x000000, 0xFFFFFF, + 0x005E0D, 0x005E0E, 0x000000, 0xFFFFFF, + 0x005E12, 0x005E13, 0x000000, 0xFFFFFF, + 0x005E17, 0x005E17, 0x000000, 0xFFFFFF, + 0x005E1E, 0x005E25, 0x000000, 0xFFFFFF, + 0x005E28, 0x005E2C, 0x000000, 0xFFFFFF, + 0x005E2F, 0x005E30, 0x000000, 0xFFFFFF, + 0x005E32, 0x005E36, 0x000000, 0xFFFFFF, + 0x005E39, 0x005E3A, 0x000000, 0xFFFFFF, + 0x005E3E, 0x005E41, 0x000000, 0xFFFFFF, + 0x005E43, 0x005E43, 0x000000, 0xFFFFFF, + 0x005E46, 0x005E4B, 0x000000, 0xFFFFFF, + 0x005E4D, 0x005E53, 0x000000, 0xFFFFFF, + 0x005E56, 0x005E5A, 0x000000, 0xFFFFFF, + 0x005E5C, 0x005E5D, 0x000000, 0xFFFFFF, + 0x005E5F, 0x005E60, 0x000000, 0xFFFFFF, + 0x005E63, 0x005E71, 0x000000, 0xFFFFFF, + 0x005E75, 0x005E75, 0x000000, 0xFFFFFF, + 0x005E77, 0x005E77, 0x000000, 0xFFFFFF, + 0x005E79, 0x005E79, 0x000000, 0xFFFFFF, + 0x005E7E, 0x005E7E, 0x000000, 0xFFFFFF, + 0x005E81, 0x005E83, 0x000000, 0xFFFFFF, + 0x005E85, 0x005E85, 0x000000, 0xFFFFFF, + 0x005E88, 0x005E89, 0x000000, 0xFFFFFF, + 0x005E8C, 0x005E8E, 0x000000, 0xFFFFFF, + 0x005E92, 0x005E92, 0x000000, 0xFFFFFF, + 0x005E98, 0x005E98, 0x000000, 0xFFFFFF, + 0x005E9B, 0x005E9B, 0x000000, 0xFFFFFF, + 0x005E9D, 0x005E9D, 0x000000, 0xFFFFFF, + 0x005EA1, 0x005EA4, 0x000000, 0xFFFFFF, + 0x005EA8, 0x005EAC, 0x000000, 0xFFFFFF, + 0x005EAE, 0x005EB2, 0x000000, 0xFFFFFF, + 0x005EB4, 0x005EB4, 0x000000, 0xFFFFFF, + 0x005EBA, 0x005EBD, 0x000000, 0xFFFFFF, + 0x005EBF, 0x005EC8, 0x000000, 0xFFFFFF, + 0x005ECB, 0x005ED0, 0x000000, 0xFFFFFF, + 0x005ED4, 0x005ED5, 0x000000, 0xFFFFFF, + 0x005ED7, 0x005EDA, 0x000000, 0xFFFFFF, + 0x005EDC, 0x005EE7, 0x000000, 0xFFFFFF, + 0x005EE9, 0x005EE9, 0x000000, 0xFFFFFF, + 0x005EEB, 0x005EF3, 0x000000, 0xFFFFFF, + 0x005EF5, 0x005EF5, 0x000000, 0xFFFFFF, + 0x005EF8, 0x005EF9, 0x000000, 0xFFFFFF, + 0x005EFB, 0x005EFD, 0x000000, 0xFFFFFF, + 0x005F05, 0x005F07, 0x000000, 0xFFFFFF, + 0x005F09, 0x005F09, 0x000000, 0xFFFFFF, + 0x005F0C, 0x005F0E, 0x000000, 0xFFFFFF, + 0x005F10, 0x005F10, 0x000000, 0xFFFFFF, + 0x005F12, 0x005F12, 0x000000, 0xFFFFFF, + 0x005F14, 0x005F14, 0x000000, 0xFFFFFF, + 0x005F16, 0x005F16, 0x000000, 0xFFFFFF, + 0x005F19, 0x005F1A, 0x000000, 0xFFFFFF, + 0x005F1C, 0x005F1E, 0x000000, 0xFFFFFF, + 0x005F21, 0x005F24, 0x000000, 0xFFFFFF, + 0x005F28, 0x005F28, 0x000000, 0xFFFFFF, + 0x005F2B, 0x005F2C, 0x000000, 0xFFFFFF, + 0x005F2E, 0x005F2E, 0x000000, 0xFFFFFF, + 0x005F30, 0x005F30, 0x000000, 0xFFFFFF, + 0x005F32, 0x005F38, 0x000000, 0xFFFFFF, + 0x005F3B, 0x005F3B, 0x000000, 0xFFFFFF, + 0x005F3D, 0x005F3F, 0x000000, 0xFFFFFF, + 0x005F41, 0x005F4F, 0x000000, 0xFFFFFF, + 0x005F51, 0x005F51, 0x000000, 0xFFFFFF, + 0x005F54, 0x005F54, 0x000000, 0xFFFFFF, + 0x005F59, 0x005F5C, 0x000000, 0xFFFFFF, + 0x005F5E, 0x005F60, 0x000000, 0xFFFFFF, + 0x005F63, 0x005F63, 0x000000, 0xFFFFFF, + 0x005F65, 0x005F65, 0x000000, 0xFFFFFF, + 0x005F67, 0x005F68, 0x000000, 0xFFFFFF, + 0x005F6B, 0x005F6B, 0x000000, 0xFFFFFF, + 0x005F6E, 0x005F6F, 0x000000, 0xFFFFFF, + 0x005F72, 0x005F72, 0x000000, 0xFFFFFF, + 0x005F74, 0x005F76, 0x000000, 0xFFFFFF, + 0x005F78, 0x005F78, 0x000000, 0xFFFFFF, + 0x005F7A, 0x005F7A, 0x000000, 0xFFFFFF, + 0x005F7D, 0x005F7F, 0x000000, 0xFFFFFF, + 0x005F83, 0x005F83, 0x000000, 0xFFFFFF, + 0x005F86, 0x005F86, 0x000000, 0xFFFFFF, + 0x005F8D, 0x005F8F, 0x000000, 0xFFFFFF, + 0x005F91, 0x005F91, 0x000000, 0xFFFFFF, + 0x005F93, 0x005F94, 0x000000, 0xFFFFFF, + 0x005F96, 0x005F96, 0x000000, 0xFFFFFF, + 0x005F9A, 0x005F9B, 0x000000, 0xFFFFFF, + 0x005F9D, 0x005FA0, 0x000000, 0xFFFFFF, + 0x005FA2, 0x005FA7, 0x000000, 0xFFFFFF, + 0x005FA9, 0x005FA9, 0x000000, 0xFFFFFF, + 0x005FAB, 0x005FAC, 0x000000, 0xFFFFFF, + 0x005FAF, 0x005FB4, 0x000000, 0xFFFFFF, + 0x005FB6, 0x005FB6, 0x000000, 0xFFFFFF, + 0x005FB8, 0x005FBB, 0x000000, 0xFFFFFF, + 0x005FBE, 0x005FC2, 0x000000, 0xFFFFFF, + 0x005FC7, 0x005FC8, 0x000000, 0xFFFFFF, + 0x005FCA, 0x005FCB, 0x000000, 0xFFFFFF, + 0x005FCE, 0x005FCE, 0x000000, 0xFFFFFF, + 0x005FD3, 0x005FD5, 0x000000, 0xFFFFFF, + 0x005FDA, 0x005FDC, 0x000000, 0xFFFFFF, + 0x005FDE, 0x005FDF, 0x000000, 0xFFFFFF, + 0x005FE2, 0x005FE3, 0x000000, 0xFFFFFF, + 0x005FE5, 0x005FE6, 0x000000, 0xFFFFFF, + 0x005FE8, 0x005FE9, 0x000000, 0xFFFFFF, + 0x005FEC, 0x005FEC, 0x000000, 0xFFFFFF, + 0x005FEF, 0x005FF0, 0x000000, 0xFFFFFF, + 0x005FF2, 0x005FF4, 0x000000, 0xFFFFFF, + 0x005FF6, 0x005FF7, 0x000000, 0xFFFFFF, + 0x005FF9, 0x005FFA, 0x000000, 0xFFFFFF, + 0x005FFC, 0x005FFC, 0x000000, 0xFFFFFF, + 0x006007, 0x006009, 0x000000, 0xFFFFFF, + 0x00600B, 0x00600C, 0x000000, 0xFFFFFF, + 0x006010, 0x006011, 0x000000, 0xFFFFFF, + 0x006013, 0x006013, 0x000000, 0xFFFFFF, + 0x006017, 0x006018, 0x000000, 0xFFFFFF, + 0x00601A, 0x00601A, 0x000000, 0xFFFFFF, + 0x00601E, 0x00601F, 0x000000, 0xFFFFFF, + 0x006022, 0x006024, 0x000000, 0xFFFFFF, + 0x00602C, 0x00602E, 0x000000, 0xFFFFFF, + 0x006030, 0x006034, 0x000000, 0xFFFFFF, + 0x006036, 0x00603A, 0x000000, 0xFFFFFF, + 0x00603D, 0x00603E, 0x000000, 0xFFFFFF, + 0x006040, 0x006040, 0x000000, 0xFFFFFF, + 0x006044, 0x00604A, 0x000000, 0xFFFFFF, + 0x00604C, 0x00604C, 0x000000, 0xFFFFFF, + 0x00604E, 0x00604F, 0x000000, 0xFFFFFF, + 0x006051, 0x006051, 0x000000, 0xFFFFFF, + 0x006053, 0x006054, 0x000000, 0xFFFFFF, + 0x006056, 0x006058, 0x000000, 0xFFFFFF, + 0x00605B, 0x00605C, 0x000000, 0xFFFFFF, + 0x00605E, 0x006061, 0x000000, 0xFFFFFF, + 0x006065, 0x006066, 0x000000, 0xFFFFFF, + 0x00606E, 0x00606E, 0x000000, 0xFFFFFF, + 0x006071, 0x006072, 0x000000, 0xFFFFFF, + 0x006074, 0x006075, 0x000000, 0xFFFFFF, + 0x006077, 0x006077, 0x000000, 0xFFFFFF, + 0x00607E, 0x00607E, 0x000000, 0xFFFFFF, + 0x006080, 0x006082, 0x000000, 0xFFFFFF, + 0x006085, 0x006088, 0x000000, 0xFFFFFF, + 0x00608A, 0x00608B, 0x000000, 0xFFFFFF, + 0x00608E, 0x006091, 0x000000, 0xFFFFFF, + 0x006093, 0x006093, 0x000000, 0xFFFFFF, + 0x006095, 0x006095, 0x000000, 0xFFFFFF, + 0x006097, 0x006099, 0x000000, 0xFFFFFF, + 0x00609C, 0x00609C, 0x000000, 0xFFFFFF, + 0x00609E, 0x00609E, 0x000000, 0xFFFFFF, + 0x0060A1, 0x0060A2, 0x000000, 0xFFFFFF, + 0x0060A4, 0x0060A5, 0x000000, 0xFFFFFF, + 0x0060A7, 0x0060A7, 0x000000, 0xFFFFFF, + 0x0060A9, 0x0060AA, 0x000000, 0xFFFFFF, + 0x0060AE, 0x0060AE, 0x000000, 0xFFFFFF, + 0x0060B0, 0x0060B0, 0x000000, 0xFFFFFF, + 0x0060B3, 0x0060B3, 0x000000, 0xFFFFFF, + 0x0060B5, 0x0060B7, 0x000000, 0xFFFFFF, + 0x0060B9, 0x0060BA, 0x000000, 0xFFFFFF, + 0x0060BD, 0x0060C4, 0x000000, 0xFFFFFF, + 0x0060C7, 0x0060C9, 0x000000, 0xFFFFFF, + 0x0060CC, 0x0060D0, 0x000000, 0xFFFFFF, + 0x0060D2, 0x0060D4, 0x000000, 0xFFFFFF, + 0x0060D6, 0x0060D7, 0x000000, 0xFFFFFF, + 0x0060D9, 0x0060D9, 0x000000, 0xFFFFFF, + 0x0060DB, 0x0060DB, 0x000000, 0xFFFFFF, + 0x0060DE, 0x0060DE, 0x000000, 0xFFFFFF, + 0x0060E1, 0x0060E5, 0x000000, 0xFFFFFF, + 0x0060EA, 0x0060EA, 0x000000, 0xFFFFFF, + 0x0060F1, 0x0060F2, 0x000000, 0xFFFFFF, + 0x0060F5, 0x0060F5, 0x000000, 0xFFFFFF, + 0x0060F7, 0x0060F8, 0x000000, 0xFFFFFF, + 0x0060FB, 0x0060FF, 0x000000, 0xFFFFFF, + 0x006102, 0x006105, 0x000000, 0xFFFFFF, + 0x006107, 0x006107, 0x000000, 0xFFFFFF, + 0x00610A, 0x00610C, 0x000000, 0xFFFFFF, + 0x006110, 0x006114, 0x000000, 0xFFFFFF, + 0x006116, 0x006119, 0x000000, 0xFFFFFF, + 0x00611B, 0x00611E, 0x000000, 0xFFFFFF, + 0x006121, 0x006122, 0x000000, 0xFFFFFF, + 0x006125, 0x006125, 0x000000, 0xFFFFFF, + 0x006128, 0x00612A, 0x000000, 0xFFFFFF, + 0x00612C, 0x00613E, 0x000000, 0xFFFFFF, + 0x006140, 0x006147, 0x000000, 0xFFFFFF, + 0x006149, 0x006149, 0x000000, 0xFFFFFF, + 0x00614B, 0x00614B, 0x000000, 0xFFFFFF, + 0x00614D, 0x00614D, 0x000000, 0xFFFFFF, + 0x00614F, 0x006150, 0x000000, 0xFFFFFF, + 0x006152, 0x006154, 0x000000, 0xFFFFFF, + 0x006156, 0x00615C, 0x000000, 0xFFFFFF, + 0x00615E, 0x006161, 0x000000, 0xFFFFFF, + 0x006163, 0x006166, 0x000000, 0xFFFFFF, + 0x006169, 0x00616F, 0x000000, 0xFFFFFF, + 0x006171, 0x006174, 0x000000, 0xFFFFFF, + 0x006176, 0x006176, 0x000000, 0xFFFFFF, + 0x006178, 0x00618A, 0x000000, 0xFFFFFF, + 0x00618C, 0x00618D, 0x000000, 0xFFFFFF, + 0x00618F, 0x006193, 0x000000, 0xFFFFFF, + 0x006195, 0x00619C, 0x000000, 0xFFFFFF, + 0x00619E, 0x0061A6, 0x000000, 0xFFFFFF, + 0x0061AA, 0x0061AB, 0x000000, 0xFFFFFF, + 0x0061AD, 0x0061B6, 0x000000, 0xFFFFFF, + 0x0061B8, 0x0061BD, 0x000000, 0xFFFFFF, + 0x0061BF, 0x0061C1, 0x000000, 0xFFFFFF, + 0x0061C3, 0x0061C7, 0x000000, 0xFFFFFF, + 0x0061C9, 0x0061C9, 0x000000, 0xFFFFFF, + 0x0061CC, 0x0061D0, 0x000000, 0xFFFFFF, + 0x0061D3, 0x0061D3, 0x000000, 0xFFFFFF, + 0x0061D5, 0x0061E5, 0x000000, 0xFFFFFF, + 0x0061E7, 0x0061F4, 0x000000, 0xFFFFFF, + 0x0061F6, 0x0061FE, 0x000000, 0xFFFFFF, + 0x006200, 0x006205, 0x000000, 0xFFFFFF, + 0x006207, 0x006207, 0x000000, 0xFFFFFF, + 0x006209, 0x006209, 0x000000, 0xFFFFFF, + 0x006213, 0x006214, 0x000000, 0xFFFFFF, + 0x006219, 0x006219, 0x000000, 0xFFFFFF, + 0x00621C, 0x00621E, 0x000000, 0xFFFFFF, + 0x006220, 0x006220, 0x000000, 0xFFFFFF, + 0x006223, 0x006223, 0x000000, 0xFFFFFF, + 0x006226, 0x006229, 0x000000, 0xFFFFFF, + 0x00622B, 0x00622B, 0x000000, 0xFFFFFF, + 0x00622D, 0x00622D, 0x000000, 0xFFFFFF, + 0x00622F, 0x006232, 0x000000, 0xFFFFFF, + 0x006235, 0x006236, 0x000000, 0xFFFFFF, + 0x006238, 0x00623C, 0x000000, 0xFFFFFF, + 0x006242, 0x006242, 0x000000, 0xFFFFFF, + 0x006244, 0x006246, 0x000000, 0xFFFFFF, + 0x00624A, 0x00624A, 0x000000, 0xFFFFFF, + 0x00624F, 0x006250, 0x000000, 0xFFFFFF, + 0x006255, 0x006257, 0x000000, 0xFFFFFF, + 0x006259, 0x00625A, 0x000000, 0xFFFFFF, + 0x00625C, 0x006262, 0x000000, 0xFFFFFF, + 0x006264, 0x006265, 0x000000, 0xFFFFFF, + 0x006268, 0x006268, 0x000000, 0xFFFFFF, + 0x006271, 0x006272, 0x000000, 0xFFFFFF, + 0x006274, 0x006275, 0x000000, 0xFFFFFF, + 0x006277, 0x006278, 0x000000, 0xFFFFFF, + 0x00627A, 0x00627B, 0x000000, 0xFFFFFF, + 0x00627D, 0x00627D, 0x000000, 0xFFFFFF, + 0x006281, 0x006283, 0x000000, 0xFFFFFF, + 0x006285, 0x006288, 0x000000, 0xFFFFFF, + 0x00628B, 0x006290, 0x000000, 0xFFFFFF, + 0x006294, 0x006294, 0x000000, 0xFFFFFF, + 0x006299, 0x006299, 0x000000, 0xFFFFFF, + 0x00629C, 0x00629E, 0x000000, 0xFFFFFF, + 0x0062A3, 0x0062A3, 0x000000, 0xFFFFFF, + 0x0062A6, 0x0062A7, 0x000000, 0xFFFFFF, + 0x0062A9, 0x0062AA, 0x000000, 0xFFFFFF, + 0x0062AD, 0x0062B0, 0x000000, 0xFFFFFF, + 0x0062B2, 0x0062B4, 0x000000, 0xFFFFFF, + 0x0062B6, 0x0062B8, 0x000000, 0xFFFFFF, + 0x0062BA, 0x0062BA, 0x000000, 0xFFFFFF, + 0x0062BE, 0x0062BE, 0x000000, 0xFFFFFF, + 0x0062C0, 0x0062C1, 0x000000, 0xFFFFFF, + 0x0062C3, 0x0062C3, 0x000000, 0xFFFFFF, + 0x0062CB, 0x0062CB, 0x000000, 0xFFFFFF, + 0x0062CF, 0x0062CF, 0x000000, 0xFFFFFF, + 0x0062D1, 0x0062D1, 0x000000, 0xFFFFFF, + 0x0062D5, 0x0062D5, 0x000000, 0xFFFFFF, + 0x0062DD, 0x0062DE, 0x000000, 0xFFFFFF, + 0x0062E0, 0x0062E1, 0x000000, 0xFFFFFF, + 0x0062E4, 0x0062E4, 0x000000, 0xFFFFFF, + 0x0062EA, 0x0062EB, 0x000000, 0xFFFFFF, + 0x0062F0, 0x0062F0, 0x000000, 0xFFFFFF, + 0x0062F2, 0x0062F2, 0x000000, 0xFFFFFF, + 0x0062F5, 0x0062F5, 0x000000, 0xFFFFFF, + 0x0062F8, 0x0062FB, 0x000000, 0xFFFFFF, + 0x006300, 0x006300, 0x000000, 0xFFFFFF, + 0x006303, 0x006306, 0x000000, 0xFFFFFF, + 0x00630A, 0x00630D, 0x000000, 0xFFFFFF, + 0x00630F, 0x006310, 0x000000, 0xFFFFFF, + 0x006312, 0x006315, 0x000000, 0xFFFFFF, + 0x006317, 0x006319, 0x000000, 0xFFFFFF, + 0x00631C, 0x00631C, 0x000000, 0xFFFFFF, + 0x006326, 0x006327, 0x000000, 0xFFFFFF, + 0x006329, 0x006329, 0x000000, 0xFFFFFF, + 0x00632C, 0x00632E, 0x000000, 0xFFFFFF, + 0x006330, 0x006331, 0x000000, 0xFFFFFF, + 0x006333, 0x006338, 0x000000, 0xFFFFFF, + 0x00633B, 0x00633C, 0x000000, 0xFFFFFF, + 0x00633E, 0x006341, 0x000000, 0xFFFFFF, + 0x006344, 0x006344, 0x000000, 0xFFFFFF, + 0x006347, 0x006348, 0x000000, 0xFFFFFF, + 0x00634A, 0x00634A, 0x000000, 0xFFFFFF, + 0x006351, 0x006354, 0x000000, 0xFFFFFF, + 0x006356, 0x00635D, 0x000000, 0xFFFFFF, + 0x006360, 0x006360, 0x000000, 0xFFFFFF, + 0x006364, 0x006366, 0x000000, 0xFFFFFF, + 0x006368, 0x006368, 0x000000, 0xFFFFFF, + 0x00636A, 0x00636C, 0x000000, 0xFFFFFF, + 0x00636F, 0x006370, 0x000000, 0xFFFFFF, + 0x006372, 0x006375, 0x000000, 0xFFFFFF, + 0x006378, 0x006379, 0x000000, 0xFFFFFF, + 0x00637C, 0x00637F, 0x000000, 0xFFFFFF, + 0x006381, 0x006381, 0x000000, 0xFFFFFF, + 0x006383, 0x006386, 0x000000, 0xFFFFFF, + 0x00638B, 0x00638B, 0x000000, 0xFFFFFF, + 0x00638D, 0x00638D, 0x000000, 0xFFFFFF, + 0x006391, 0x006391, 0x000000, 0xFFFFFF, + 0x006393, 0x006395, 0x000000, 0xFFFFFF, + 0x006397, 0x006397, 0x000000, 0xFFFFFF, + 0x006399, 0x00639F, 0x000000, 0xFFFFFF, + 0x0063A1, 0x0063A1, 0x000000, 0xFFFFFF, + 0x0063A4, 0x0063A4, 0x000000, 0xFFFFFF, + 0x0063A6, 0x0063A6, 0x000000, 0xFFFFFF, + 0x0063AB, 0x0063AB, 0x000000, 0xFFFFFF, + 0x0063AF, 0x0063AF, 0x000000, 0xFFFFFF, + 0x0063B1, 0x0063B2, 0x000000, 0xFFFFFF, + 0x0063B5, 0x0063B6, 0x000000, 0xFFFFFF, + 0x0063B9, 0x0063B9, 0x000000, 0xFFFFFF, + 0x0063BB, 0x0063BB, 0x000000, 0xFFFFFF, + 0x0063BD, 0x0063BD, 0x000000, 0xFFFFFF, + 0x0063BF, 0x0063C3, 0x000000, 0xFFFFFF, + 0x0063C5, 0x0063C5, 0x000000, 0xFFFFFF, + 0x0063C7, 0x0063C8, 0x000000, 0xFFFFFF, + 0x0063CA, 0x0063CC, 0x000000, 0xFFFFFF, + 0x0063D1, 0x0063D1, 0x000000, 0xFFFFFF, + 0x0063D3, 0x0063D5, 0x000000, 0xFFFFFF, + 0x0063D7, 0x0063DD, 0x000000, 0xFFFFFF, + 0x0063DF, 0x0063DF, 0x000000, 0xFFFFFF, + 0x0063E2, 0x0063E2, 0x000000, 0xFFFFFF, + 0x0063E4, 0x0063E8, 0x000000, 0xFFFFFF, + 0x0063EB, 0x0063EC, 0x000000, 0xFFFFFF, + 0x0063EE, 0x0063F1, 0x000000, 0xFFFFFF, + 0x0063F3, 0x0063F3, 0x000000, 0xFFFFFF, + 0x0063F5, 0x0063F5, 0x000000, 0xFFFFFF, + 0x0063F7, 0x0063F7, 0x000000, 0xFFFFFF, + 0x0063F9, 0x0063FC, 0x000000, 0xFFFFFF, + 0x0063FE, 0x0063FE, 0x000000, 0xFFFFFF, + 0x006403, 0x006404, 0x000000, 0xFFFFFF, + 0x006406, 0x00640A, 0x000000, 0xFFFFFF, + 0x00640D, 0x00640E, 0x000000, 0xFFFFFF, + 0x006411, 0x006412, 0x000000, 0xFFFFFF, + 0x006415, 0x00641A, 0x000000, 0xFFFFFF, + 0x00641D, 0x00641D, 0x000000, 0xFFFFFF, + 0x00641F, 0x00641F, 0x000000, 0xFFFFFF, + 0x006422, 0x006425, 0x000000, 0xFFFFFF, + 0x006427, 0x006429, 0x000000, 0xFFFFFF, + 0x00642B, 0x00642B, 0x000000, 0xFFFFFF, + 0x00642E, 0x006433, 0x000000, 0xFFFFFF, + 0x006435, 0x006439, 0x000000, 0xFFFFFF, + 0x00643B, 0x00643C, 0x000000, 0xFFFFFF, + 0x00643E, 0x00643E, 0x000000, 0xFFFFFF, + 0x006440, 0x006440, 0x000000, 0xFFFFFF, + 0x006442, 0x006443, 0x000000, 0xFFFFFF, + 0x006449, 0x006449, 0x000000, 0xFFFFFF, + 0x00644B, 0x006451, 0x000000, 0xFFFFFF, + 0x006453, 0x006453, 0x000000, 0xFFFFFF, + 0x006455, 0x006457, 0x000000, 0xFFFFFF, + 0x006459, 0x00645D, 0x000000, 0xFFFFFF, + 0x00645F, 0x006466, 0x000000, 0xFFFFFF, + 0x006468, 0x006468, 0x000000, 0xFFFFFF, + 0x00646A, 0x00646C, 0x000000, 0xFFFFFF, + 0x00646E, 0x006477, 0x000000, 0xFFFFFF, + 0x00647B, 0x006481, 0x000000, 0xFFFFFF, + 0x006483, 0x006483, 0x000000, 0xFFFFFF, + 0x006486, 0x006486, 0x000000, 0xFFFFFF, + 0x006488, 0x006490, 0x000000, 0xFFFFFF, + 0x006493, 0x006494, 0x000000, 0xFFFFFF, + 0x006497, 0x006498, 0x000000, 0xFFFFFF, + 0x00649A, 0x00649D, 0x000000, 0xFFFFFF, + 0x00649F, 0x0064A3, 0x000000, 0xFFFFFF, + 0x0064A5, 0x0064A8, 0x000000, 0xFFFFFF, + 0x0064AA, 0x0064AB, 0x000000, 0xFFFFFF, + 0x0064AF, 0x0064AF, 0x000000, 0xFFFFFF, + 0x0064B1, 0x0064B4, 0x000000, 0xFFFFFF, + 0x0064B6, 0x0064B6, 0x000000, 0xFFFFFF, + 0x0064B9, 0x0064B9, 0x000000, 0xFFFFFF, + 0x0064BB, 0x0064BB, 0x000000, 0xFFFFFF, + 0x0064BD, 0x0064BF, 0x000000, 0xFFFFFF, + 0x0064C1, 0x0064C1, 0x000000, 0xFFFFFF, + 0x0064C3, 0x0064C4, 0x000000, 0xFFFFFF, + 0x0064C6, 0x0064CC, 0x000000, 0xFFFFFF, + 0x0064CF, 0x0064CF, 0x000000, 0xFFFFFF, + 0x0064D1, 0x0064D1, 0x000000, 0xFFFFFF, + 0x0064D3, 0x0064D6, 0x000000, 0xFFFFFF, + 0x0064D9, 0x0064DD, 0x000000, 0xFFFFFF, + 0x0064DF, 0x0064E1, 0x000000, 0xFFFFFF, + 0x0064E3, 0x0064E3, 0x000000, 0xFFFFFF, + 0x0064E5, 0x0064E5, 0x000000, 0xFFFFFF, + 0x0064E7, 0x0064FF, 0x000000, 0xFFFFFF, + 0x006501, 0x006508, 0x000000, 0xFFFFFF, + 0x00650A, 0x006511, 0x000000, 0xFFFFFF, + 0x006513, 0x006517, 0x000000, 0xFFFFFF, + 0x006519, 0x006524, 0x000000, 0xFFFFFF, + 0x006526, 0x00652A, 0x000000, 0xFFFFFF, + 0x00652C, 0x00652D, 0x000000, 0xFFFFFF, + 0x006530, 0x006533, 0x000000, 0xFFFFFF, + 0x006537, 0x006537, 0x000000, 0xFFFFFF, + 0x00653A, 0x00653A, 0x000000, 0xFFFFFF, + 0x00653C, 0x00653D, 0x000000, 0xFFFFFF, + 0x006540, 0x006544, 0x000000, 0xFFFFFF, + 0x006546, 0x006547, 0x000000, 0xFFFFFF, + 0x00654A, 0x00654B, 0x000000, 0xFFFFFF, + 0x00654D, 0x00654E, 0x000000, 0xFFFFFF, + 0x006550, 0x006550, 0x000000, 0xFFFFFF, + 0x006552, 0x006554, 0x000000, 0xFFFFFF, + 0x006557, 0x006558, 0x000000, 0xFFFFFF, + 0x00655A, 0x00655A, 0x000000, 0xFFFFFF, + 0x00655C, 0x00655C, 0x000000, 0xFFFFFF, + 0x00655F, 0x006561, 0x000000, 0xFFFFFF, + 0x006564, 0x006565, 0x000000, 0xFFFFFF, + 0x006567, 0x00656A, 0x000000, 0xFFFFFF, + 0x00656D, 0x00656F, 0x000000, 0xFFFFFF, + 0x006571, 0x006571, 0x000000, 0xFFFFFF, + 0x006573, 0x006573, 0x000000, 0xFFFFFF, + 0x006575, 0x006576, 0x000000, 0xFFFFFF, + 0x006578, 0x006586, 0x000000, 0xFFFFFF, + 0x006588, 0x00658A, 0x000000, 0xFFFFFF, + 0x00658D, 0x00658F, 0x000000, 0xFFFFFF, + 0x006592, 0x006592, 0x000000, 0xFFFFFF, + 0x006594, 0x006596, 0x000000, 0xFFFFFF, + 0x006598, 0x006598, 0x000000, 0xFFFFFF, + 0x00659A, 0x00659A, 0x000000, 0xFFFFFF, + 0x00659D, 0x00659E, 0x000000, 0xFFFFFF, + 0x0065A0, 0x0065A0, 0x000000, 0xFFFFFF, + 0x0065A2, 0x0065A3, 0x000000, 0xFFFFFF, + 0x0065A6, 0x0065A6, 0x000000, 0xFFFFFF, + 0x0065A8, 0x0065A8, 0x000000, 0xFFFFFF, + 0x0065AA, 0x0065AA, 0x000000, 0xFFFFFF, + 0x0065AC, 0x0065AC, 0x000000, 0xFFFFFF, + 0x0065AE, 0x0065AE, 0x000000, 0xFFFFFF, + 0x0065B1, 0x0065B8, 0x000000, 0xFFFFFF, + 0x0065BA, 0x0065BB, 0x000000, 0xFFFFFF, + 0x0065BE, 0x0065C0, 0x000000, 0xFFFFFF, + 0x0065C2, 0x0065C2, 0x000000, 0xFFFFFF, + 0x0065C7, 0x0065CA, 0x000000, 0xFFFFFF, + 0x0065CD, 0x0065CD, 0x000000, 0xFFFFFF, + 0x0065D0, 0x0065D1, 0x000000, 0xFFFFFF, + 0x0065D3, 0x0065D5, 0x000000, 0xFFFFFF, + 0x0065D8, 0x0065DF, 0x000000, 0xFFFFFF, + 0x0065E1, 0x0065E1, 0x000000, 0xFFFFFF, + 0x0065E3, 0x0065E4, 0x000000, 0xFFFFFF, + 0x0065EA, 0x0065EB, 0x000000, 0xFFFFFF, + 0x0065F2, 0x0065F5, 0x000000, 0xFFFFFF, + 0x0065F8, 0x0065F9, 0x000000, 0xFFFFFF, + 0x0065FB, 0x0065FF, 0x000000, 0xFFFFFF, + 0x006601, 0x006601, 0x000000, 0xFFFFFF, + 0x006604, 0x006605, 0x000000, 0xFFFFFF, + 0x006607, 0x006609, 0x000000, 0xFFFFFF, + 0x00660B, 0x00660B, 0x000000, 0xFFFFFF, + 0x00660D, 0x00660D, 0x000000, 0xFFFFFF, + 0x006610, 0x006612, 0x000000, 0xFFFFFF, + 0x006616, 0x006618, 0x000000, 0xFFFFFF, + 0x00661A, 0x00661C, 0x000000, 0xFFFFFF, + 0x00661E, 0x00661E, 0x000000, 0xFFFFFF, + 0x006621, 0x006624, 0x000000, 0xFFFFFF, + 0x006626, 0x006626, 0x000000, 0xFFFFFF, + 0x006629, 0x00662C, 0x000000, 0xFFFFFF, + 0x00662E, 0x00662E, 0x000000, 0xFFFFFF, + 0x006630, 0x006630, 0x000000, 0xFFFFFF, + 0x006632, 0x006633, 0x000000, 0xFFFFFF, + 0x006637, 0x00663B, 0x000000, 0xFFFFFF, + 0x00663D, 0x00663D, 0x000000, 0xFFFFFF, + 0x00663F, 0x006640, 0x000000, 0xFFFFFF, + 0x006642, 0x006642, 0x000000, 0xFFFFFF, + 0x006644, 0x00664A, 0x000000, 0xFFFFFF, + 0x00664D, 0x00664E, 0x000000, 0xFFFFFF, + 0x006650, 0x006651, 0x000000, 0xFFFFFF, + 0x006658, 0x006659, 0x000000, 0xFFFFFF, + 0x00665B, 0x00665E, 0x000000, 0xFFFFFF, + 0x006660, 0x006660, 0x000000, 0xFFFFFF, + 0x006662, 0x006663, 0x000000, 0xFFFFFF, + 0x006665, 0x006665, 0x000000, 0xFFFFFF, + 0x006667, 0x006667, 0x000000, 0xFFFFFF, + 0x006669, 0x00666D, 0x000000, 0xFFFFFF, + 0x006671, 0x006673, 0x000000, 0xFFFFFF, + 0x006675, 0x006675, 0x000000, 0xFFFFFF, + 0x006678, 0x006679, 0x000000, 0xFFFFFF, + 0x00667B, 0x00667D, 0x000000, 0xFFFFFF, + 0x00667F, 0x006681, 0x000000, 0xFFFFFF, + 0x006683, 0x006683, 0x000000, 0xFFFFFF, + 0x006685, 0x006686, 0x000000, 0xFFFFFF, + 0x006688, 0x00668B, 0x000000, 0xFFFFFF, + 0x00668D, 0x006690, 0x000000, 0xFFFFFF, + 0x006692, 0x006695, 0x000000, 0xFFFFFF, + 0x006698, 0x00669C, 0x000000, 0xFFFFFF, + 0x00669E, 0x0066A6, 0x000000, 0xFFFFFF, + 0x0066A9, 0x0066AD, 0x000000, 0xFFFFFF, + 0x0066AF, 0x0066B3, 0x000000, 0xFFFFFF, + 0x0066B5, 0x0066B8, 0x000000, 0xFFFFFF, + 0x0066BA, 0x0066BD, 0x000000, 0xFFFFFF, + 0x0066BF, 0x0066D8, 0x000000, 0xFFFFFF, + 0x0066DA, 0x0066DA, 0x000000, 0xFFFFFF, + 0x0066DE, 0x0066E5, 0x000000, 0xFFFFFF, + 0x0066E7, 0x0066E8, 0x000000, 0xFFFFFF, + 0x0066EA, 0x0066EF, 0x000000, 0xFFFFFF, + 0x0066F1, 0x0066F1, 0x000000, 0xFFFFFF, + 0x0066F5, 0x0066F6, 0x000000, 0xFFFFFF, + 0x0066F8, 0x0066F8, 0x000000, 0xFFFFFF, + 0x0066FA, 0x0066FB, 0x000000, 0xFFFFFF, + 0x0066FD, 0x0066FD, 0x000000, 0xFFFFFF, + 0x006701, 0x006707, 0x000000, 0xFFFFFF, + 0x00670C, 0x00670C, 0x000000, 0xFFFFFF, + 0x00670E, 0x00670F, 0x000000, 0xFFFFFF, + 0x006711, 0x006713, 0x000000, 0xFFFFFF, + 0x006716, 0x006716, 0x000000, 0xFFFFFF, + 0x006718, 0x00671A, 0x000000, 0xFFFFFF, + 0x00671C, 0x00671C, 0x000000, 0xFFFFFF, + 0x00671E, 0x00671E, 0x000000, 0xFFFFFF, + 0x006720, 0x006725, 0x000000, 0xFFFFFF, + 0x006727, 0x006727, 0x000000, 0xFFFFFF, + 0x006729, 0x006729, 0x000000, 0xFFFFFF, + 0x00672E, 0x00672E, 0x000000, 0xFFFFFF, + 0x006730, 0x006730, 0x000000, 0xFFFFFF, + 0x006732, 0x006733, 0x000000, 0xFFFFFF, + 0x006736, 0x006739, 0x000000, 0xFFFFFF, + 0x00673B, 0x00673C, 0x000000, 0xFFFFFF, + 0x00673E, 0x00673F, 0x000000, 0xFFFFFF, + 0x006741, 0x006741, 0x000000, 0xFFFFFF, + 0x006744, 0x006745, 0x000000, 0xFFFFFF, + 0x006747, 0x006747, 0x000000, 0xFFFFFF, + 0x00674A, 0x00674B, 0x000000, 0xFFFFFF, + 0x00674D, 0x00674D, 0x000000, 0xFFFFFF, + 0x006752, 0x006752, 0x000000, 0xFFFFFF, + 0x006754, 0x006755, 0x000000, 0xFFFFFF, + 0x006757, 0x00675B, 0x000000, 0xFFFFFF, + 0x00675D, 0x00675D, 0x000000, 0xFFFFFF, + 0x006762, 0x006764, 0x000000, 0xFFFFFF, + 0x006766, 0x006767, 0x000000, 0xFFFFFF, + 0x00676B, 0x00676C, 0x000000, 0xFFFFFF, + 0x00676E, 0x00676E, 0x000000, 0xFFFFFF, + 0x006771, 0x006771, 0x000000, 0xFFFFFF, + 0x006774, 0x006774, 0x000000, 0xFFFFFF, + 0x006776, 0x006776, 0x000000, 0xFFFFFF, + 0x006778, 0x00677B, 0x000000, 0xFFFFFF, + 0x00677D, 0x00677D, 0x000000, 0xFFFFFF, + 0x006780, 0x006780, 0x000000, 0xFFFFFF, + 0x006782, 0x006783, 0x000000, 0xFFFFFF, + 0x006785, 0x006786, 0x000000, 0xFFFFFF, + 0x006788, 0x006788, 0x000000, 0xFFFFFF, + 0x00678A, 0x00678A, 0x000000, 0xFFFFFF, + 0x00678C, 0x00678F, 0x000000, 0xFFFFFF, + 0x006791, 0x006794, 0x000000, 0xFFFFFF, + 0x006796, 0x006796, 0x000000, 0xFFFFFF, + 0x006799, 0x006799, 0x000000, 0xFFFFFF, + 0x00679B, 0x00679B, 0x000000, 0xFFFFFF, + 0x00679F, 0x0067A1, 0x000000, 0xFFFFFF, + 0x0067A4, 0x0067A4, 0x000000, 0xFFFFFF, + 0x0067A6, 0x0067A6, 0x000000, 0xFFFFFF, + 0x0067A9, 0x0067A9, 0x000000, 0xFFFFFF, + 0x0067AC, 0x0067AC, 0x000000, 0xFFFFFF, + 0x0067AE, 0x0067AE, 0x000000, 0xFFFFFF, + 0x0067B1, 0x0067B2, 0x000000, 0xFFFFFF, + 0x0067B4, 0x0067B4, 0x000000, 0xFFFFFF, + 0x0067B9, 0x0067C0, 0x000000, 0xFFFFFF, + 0x0067C2, 0x0067C2, 0x000000, 0xFFFFFF, + 0x0067C5, 0x0067CE, 0x000000, 0xFFFFFF, + 0x0067D5, 0x0067D7, 0x000000, 0xFFFFFF, + 0x0067DB, 0x0067DB, 0x000000, 0xFFFFFF, + 0x0067DF, 0x0067DF, 0x000000, 0xFFFFFF, + 0x0067E1, 0x0067E1, 0x000000, 0xFFFFFF, + 0x0067E3, 0x0067E4, 0x000000, 0xFFFFFF, + 0x0067E6, 0x0067E8, 0x000000, 0xFFFFFF, + 0x0067EA, 0x0067EB, 0x000000, 0xFFFFFF, + 0x0067ED, 0x0067EE, 0x000000, 0xFFFFFF, + 0x0067F2, 0x0067F2, 0x000000, 0xFFFFFF, + 0x0067F5, 0x0067FC, 0x000000, 0xFFFFFF, + 0x0067FE, 0x0067FE, 0x000000, 0xFFFFFF, + 0x006801, 0x006804, 0x000000, 0xFFFFFF, + 0x006806, 0x006806, 0x000000, 0xFFFFFF, + 0x00680D, 0x00680D, 0x000000, 0xFFFFFF, + 0x006810, 0x006810, 0x000000, 0xFFFFFF, + 0x006812, 0x006812, 0x000000, 0xFFFFFF, + 0x006814, 0x006815, 0x000000, 0xFFFFFF, + 0x006818, 0x00681C, 0x000000, 0xFFFFFF, + 0x00681E, 0x006820, 0x000000, 0xFFFFFF, + 0x006822, 0x006828, 0x000000, 0xFFFFFF, + 0x00682B, 0x006831, 0x000000, 0xFFFFFF, + 0x006834, 0x006836, 0x000000, 0xFFFFFF, + 0x00683A, 0x00683B, 0x000000, 0xFFFFFF, + 0x00683F, 0x00683F, 0x000000, 0xFFFFFF, + 0x006847, 0x006847, 0x000000, 0xFFFFFF, + 0x00684B, 0x00684B, 0x000000, 0xFFFFFF, + 0x00684D, 0x00684D, 0x000000, 0xFFFFFF, + 0x00684F, 0x00684F, 0x000000, 0xFFFFFF, + 0x006852, 0x006852, 0x000000, 0xFFFFFF, + 0x006856, 0x00685F, 0x000000, 0xFFFFFF, + 0x00686A, 0x00686A, 0x000000, 0xFFFFFF, + 0x00686C, 0x006873, 0x000000, 0xFFFFFF, + 0x006875, 0x006875, 0x000000, 0xFFFFFF, + 0x006878, 0x006880, 0x000000, 0xFFFFFF, + 0x006882, 0x006882, 0x000000, 0xFFFFFF, + 0x006884, 0x006884, 0x000000, 0xFFFFFF, + 0x006887, 0x00688E, 0x000000, 0xFFFFFF, + 0x006890, 0x006892, 0x000000, 0xFFFFFF, + 0x006894, 0x006896, 0x000000, 0xFFFFFF, + 0x006898, 0x0068A1, 0x000000, 0xFFFFFF, + 0x0068A3, 0x0068A5, 0x000000, 0xFFFFFF, + 0x0068A9, 0x0068AC, 0x000000, 0xFFFFFF, + 0x0068AE, 0x0068AE, 0x000000, 0xFFFFFF, + 0x0068B1, 0x0068B2, 0x000000, 0xFFFFFF, + 0x0068B4, 0x0068B4, 0x000000, 0xFFFFFF, + 0x0068B6, 0x0068BF, 0x000000, 0xFFFFFF, + 0x0068C1, 0x0068C1, 0x000000, 0xFFFFFF, + 0x0068C3, 0x0068C8, 0x000000, 0xFFFFFF, + 0x0068CA, 0x0068CA, 0x000000, 0xFFFFFF, + 0x0068CC, 0x0068CC, 0x000000, 0xFFFFFF, + 0x0068CE, 0x0068D1, 0x000000, 0xFFFFFF, + 0x0068D3, 0x0068D4, 0x000000, 0xFFFFFF, + 0x0068D6, 0x0068D7, 0x000000, 0xFFFFFF, + 0x0068D9, 0x0068D9, 0x000000, 0xFFFFFF, + 0x0068DB, 0x0068DF, 0x000000, 0xFFFFFF, + 0x0068E1, 0x0068E2, 0x000000, 0xFFFFFF, + 0x0068E4, 0x0068ED, 0x000000, 0xFFFFFF, + 0x0068EF, 0x0068EF, 0x000000, 0xFFFFFF, + 0x0068F2, 0x0068F4, 0x000000, 0xFFFFFF, + 0x0068F6, 0x0068F8, 0x000000, 0xFFFFFF, + 0x0068FB, 0x0068FB, 0x000000, 0xFFFFFF, + 0x0068FD, 0x006900, 0x000000, 0xFFFFFF, + 0x006902, 0x006904, 0x000000, 0xFFFFFF, + 0x006906, 0x00690A, 0x000000, 0xFFFFFF, + 0x00690C, 0x00690C, 0x000000, 0xFFFFFF, + 0x00690F, 0x00690F, 0x000000, 0xFFFFFF, + 0x006911, 0x006911, 0x000000, 0xFFFFFF, + 0x006913, 0x00691E, 0x000000, 0xFFFFFF, + 0x006921, 0x006923, 0x000000, 0xFFFFFF, + 0x006925, 0x00692C, 0x000000, 0xFFFFFF, + 0x00692E, 0x00692F, 0x000000, 0xFFFFFF, + 0x006931, 0x006933, 0x000000, 0xFFFFFF, + 0x006935, 0x006938, 0x000000, 0xFFFFFF, + 0x00693A, 0x00693C, 0x000000, 0xFFFFFF, + 0x00693E, 0x00693E, 0x000000, 0xFFFFFF, + 0x006940, 0x006941, 0x000000, 0xFFFFFF, + 0x006943, 0x006953, 0x000000, 0xFFFFFF, + 0x006955, 0x006956, 0x000000, 0xFFFFFF, + 0x006958, 0x006959, 0x000000, 0xFFFFFF, + 0x00695B, 0x00695C, 0x000000, 0xFFFFFF, + 0x00695F, 0x00695F, 0x000000, 0xFFFFFF, + 0x006961, 0x006962, 0x000000, 0xFFFFFF, + 0x006964, 0x006965, 0x000000, 0xFFFFFF, + 0x006967, 0x00696A, 0x000000, 0xFFFFFF, + 0x00696C, 0x00696D, 0x000000, 0xFFFFFF, + 0x00696F, 0x006970, 0x000000, 0xFFFFFF, + 0x006972, 0x006976, 0x000000, 0xFFFFFF, + 0x00697A, 0x00697B, 0x000000, 0xFFFFFF, + 0x00697D, 0x00697F, 0x000000, 0xFFFFFF, + 0x006981, 0x006981, 0x000000, 0xFFFFFF, + 0x006983, 0x006983, 0x000000, 0xFFFFFF, + 0x006985, 0x006985, 0x000000, 0xFFFFFF, + 0x00698A, 0x00698C, 0x000000, 0xFFFFFF, + 0x00698E, 0x006993, 0x000000, 0xFFFFFF, + 0x006996, 0x006997, 0x000000, 0xFFFFFF, + 0x006999, 0x00699A, 0x000000, 0xFFFFFF, + 0x00699D, 0x0069A6, 0x000000, 0xFFFFFF, + 0x0069A9, 0x0069AA, 0x000000, 0xFFFFFF, + 0x0069AC, 0x0069AC, 0x000000, 0xFFFFFF, + 0x0069AE, 0x0069B0, 0x000000, 0xFFFFFF, + 0x0069B2, 0x0069B3, 0x000000, 0xFFFFFF, + 0x0069B5, 0x0069B6, 0x000000, 0xFFFFFF, + 0x0069B8, 0x0069BA, 0x000000, 0xFFFFFF, + 0x0069BC, 0x0069C0, 0x000000, 0xFFFFFF, + 0x0069C2, 0x0069C9, 0x000000, 0xFFFFFF, + 0x0069CB, 0x0069CB, 0x000000, 0xFFFFFF, + 0x0069CD, 0x0069CD, 0x000000, 0xFFFFFF, + 0x0069CF, 0x0069CF, 0x000000, 0xFFFFFF, + 0x0069D1, 0x0069D3, 0x000000, 0xFFFFFF, + 0x0069D5, 0x0069DA, 0x000000, 0xFFFFFF, + 0x0069DC, 0x0069DE, 0x000000, 0xFFFFFF, + 0x0069E1, 0x0069EC, 0x000000, 0xFFFFFF, + 0x0069EE, 0x0069F1, 0x000000, 0xFFFFFF, + 0x0069F3, 0x0069FC, 0x000000, 0xFFFFFF, + 0x0069FE, 0x0069FE, 0x000000, 0xFFFFFF, + 0x006A00, 0x006A09, 0x000000, 0xFFFFFF, + 0x006A0B, 0x006A16, 0x000000, 0xFFFFFF, + 0x006A19, 0x006A1E, 0x000000, 0xFFFFFF, + 0x006A20, 0x006A20, 0x000000, 0xFFFFFF, + 0x006A22, 0x006A27, 0x000000, 0xFFFFFF, + 0x006A29, 0x006A29, 0x000000, 0xFFFFFF, + 0x006A2B, 0x006A2E, 0x000000, 0xFFFFFF, + 0x006A30, 0x006A30, 0x000000, 0xFFFFFF, + 0x006A32, 0x006A34, 0x000000, 0xFFFFFF, + 0x006A36, 0x006A3C, 0x000000, 0xFFFFFF, + 0x006A3F, 0x006A43, 0x000000, 0xFFFFFF, + 0x006A45, 0x006A46, 0x000000, 0xFFFFFF, + 0x006A48, 0x006A4F, 0x000000, 0xFFFFFF, + 0x006A51, 0x006A57, 0x000000, 0xFFFFFF, + 0x006A5A, 0x006A5A, 0x000000, 0xFFFFFF, + 0x006A5C, 0x006A60, 0x000000, 0xFFFFFF, + 0x006A62, 0x006A64, 0x000000, 0xFFFFFF, + 0x006A66, 0x006A70, 0x000000, 0xFFFFFF, + 0x006A72, 0x006A78, 0x000000, 0xFFFFFF, + 0x006A7A, 0x006A7B, 0x000000, 0xFFFFFF, + 0x006A7D, 0x006A7F, 0x000000, 0xFFFFFF, + 0x006A81, 0x006A83, 0x000000, 0xFFFFFF, + 0x006A85, 0x006A8D, 0x000000, 0xFFFFFF, + 0x006A8F, 0x006A8F, 0x000000, 0xFFFFFF, + 0x006A92, 0x006A96, 0x000000, 0xFFFFFF, + 0x006A98, 0x006A9F, 0x000000, 0xFFFFFF, + 0x006AA1, 0x006AA8, 0x000000, 0xFFFFFF, + 0x006AAA, 0x006AAA, 0x000000, 0xFFFFFF, + 0x006AAD, 0x006B1F, 0x000000, 0xFFFFFF, + 0x006B25, 0x006B26, 0x000000, 0xFFFFFF, + 0x006B28, 0x006B31, 0x000000, 0xFFFFFF, + 0x006B33, 0x006B36, 0x000000, 0xFFFFFF, + 0x006B38, 0x006B38, 0x000000, 0xFFFFFF, + 0x006B3B, 0x006B3D, 0x000000, 0xFFFFFF, + 0x006B3F, 0x006B42, 0x000000, 0xFFFFFF, + 0x006B44, 0x006B45, 0x000000, 0xFFFFFF, + 0x006B48, 0x006B48, 0x000000, 0xFFFFFF, + 0x006B4A, 0x006B4B, 0x000000, 0xFFFFFF, + 0x006B4D, 0x006B58, 0x000000, 0xFFFFFF, + 0x006B5A, 0x006B61, 0x000000, 0xFFFFFF, + 0x006B68, 0x006B69, 0x000000, 0xFFFFFF, + 0x006B6B, 0x006B78, 0x000000, 0xFFFFFF, + 0x006B7A, 0x006B7A, 0x000000, 0xFFFFFF, + 0x006B7D, 0x006B80, 0x000000, 0xFFFFFF, + 0x006B85, 0x006B85, 0x000000, 0xFFFFFF, + 0x006B88, 0x006B88, 0x000000, 0xFFFFFF, + 0x006B8C, 0x006B8C, 0x000000, 0xFFFFFF, + 0x006B8E, 0x006B91, 0x000000, 0xFFFFFF, + 0x006B94, 0x006B95, 0x000000, 0xFFFFFF, + 0x006B97, 0x006B99, 0x000000, 0xFFFFFF, + 0x006B9C, 0x006BA0, 0x000000, 0xFFFFFF, + 0x006BA2, 0x006BA9, 0x000000, 0xFFFFFF, + 0x006BAB, 0x006BB2, 0x000000, 0xFFFFFF, + 0x006BB6, 0x006BB6, 0x000000, 0xFFFFFF, + 0x006BB8, 0x006BBE, 0x000000, 0xFFFFFF, + 0x006BC0, 0x006BC0, 0x000000, 0xFFFFFF, + 0x006BC3, 0x006BC4, 0x000000, 0xFFFFFF, + 0x006BC6, 0x006BCA, 0x000000, 0xFFFFFF, + 0x006BCC, 0x006BCC, 0x000000, 0xFFFFFF, + 0x006BCE, 0x006BCE, 0x000000, 0xFFFFFF, + 0x006BD0, 0x006BD1, 0x000000, 0xFFFFFF, + 0x006BD8, 0x006BD8, 0x000000, 0xFFFFFF, + 0x006BDA, 0x006BDA, 0x000000, 0xFFFFFF, + 0x006BDC, 0x006BE0, 0x000000, 0xFFFFFF, + 0x006BE2, 0x006BE9, 0x000000, 0xFFFFFF, + 0x006BEC, 0x006BEE, 0x000000, 0xFFFFFF, + 0x006BF0, 0x006BF2, 0x000000, 0xFFFFFF, + 0x006BF4, 0x006BF4, 0x000000, 0xFFFFFF, + 0x006BF6, 0x006BF8, 0x000000, 0xFFFFFF, + 0x006BFA, 0x006BFC, 0x000000, 0xFFFFFF, + 0x006BFE, 0x006C04, 0x000000, 0xFFFFFF, + 0x006C08, 0x006C0C, 0x000000, 0xFFFFFF, + 0x006C0E, 0x006C0E, 0x000000, 0xFFFFFF, + 0x006C12, 0x006C12, 0x000000, 0xFFFFFF, + 0x006C17, 0x006C17, 0x000000, 0xFFFFFF, + 0x006C1C, 0x006C1E, 0x000000, 0xFFFFFF, + 0x006C20, 0x006C20, 0x000000, 0xFFFFFF, + 0x006C23, 0x006C23, 0x000000, 0xFFFFFF, + 0x006C25, 0x006C25, 0x000000, 0xFFFFFF, + 0x006C2B, 0x006C2D, 0x000000, 0xFFFFFF, + 0x006C31, 0x006C31, 0x000000, 0xFFFFFF, + 0x006C33, 0x006C33, 0x000000, 0xFFFFFF, + 0x006C36, 0x006C37, 0x000000, 0xFFFFFF, + 0x006C39, 0x006C3C, 0x000000, 0xFFFFFF, + 0x006C3E, 0x006C3F, 0x000000, 0xFFFFFF, + 0x006C43, 0x006C45, 0x000000, 0xFFFFFF, + 0x006C48, 0x006C48, 0x000000, 0xFFFFFF, + 0x006C4B, 0x006C4F, 0x000000, 0xFFFFFF, + 0x006C51, 0x006C53, 0x000000, 0xFFFFFF, + 0x006C56, 0x006C56, 0x000000, 0xFFFFFF, + 0x006C58, 0x006C5A, 0x000000, 0xFFFFFF, + 0x006C62, 0x006C63, 0x000000, 0xFFFFFF, + 0x006C65, 0x006C67, 0x000000, 0xFFFFFF, + 0x006C6B, 0x006C6F, 0x000000, 0xFFFFFF, + 0x006C71, 0x006C71, 0x000000, 0xFFFFFF, + 0x006C73, 0x006C73, 0x000000, 0xFFFFFF, + 0x006C75, 0x006C75, 0x000000, 0xFFFFFF, + 0x006C77, 0x006C78, 0x000000, 0xFFFFFF, + 0x006C7A, 0x006C7C, 0x000000, 0xFFFFFF, + 0x006C7F, 0x006C80, 0x000000, 0xFFFFFF, + 0x006C84, 0x006C84, 0x000000, 0xFFFFFF, + 0x006C87, 0x006C87, 0x000000, 0xFFFFFF, + 0x006C8A, 0x006C8B, 0x000000, 0xFFFFFF, + 0x006C8D, 0x006C8E, 0x000000, 0xFFFFFF, + 0x006C91, 0x006C92, 0x000000, 0xFFFFFF, + 0x006C95, 0x006C98, 0x000000, 0xFFFFFF, + 0x006C9A, 0x006C9A, 0x000000, 0xFFFFFF, + 0x006C9C, 0x006C9E, 0x000000, 0xFFFFFF, + 0x006CA0, 0x006CA0, 0x000000, 0xFFFFFF, + 0x006CA2, 0x006CA2, 0x000000, 0xFFFFFF, + 0x006CA8, 0x006CA8, 0x000000, 0xFFFFFF, + 0x006CAC, 0x006CAC, 0x000000, 0xFFFFFF, + 0x006CAF, 0x006CB0, 0x000000, 0xFFFFFF, + 0x006CB4, 0x006CB7, 0x000000, 0xFFFFFF, + 0x006CBA, 0x006CBA, 0x000000, 0xFFFFFF, + 0x006CC0, 0x006CC3, 0x000000, 0xFFFFFF, + 0x006CC6, 0x006CC8, 0x000000, 0xFFFFFF, + 0x006CCB, 0x006CCB, 0x000000, 0xFFFFFF, + 0x006CCD, 0x006CCF, 0x000000, 0xFFFFFF, + 0x006CD1, 0x006CD2, 0x000000, 0xFFFFFF, + 0x006CD8, 0x006CDA, 0x000000, 0xFFFFFF, + 0x006CDC, 0x006CDD, 0x000000, 0xFFFFFF, + 0x006CDF, 0x006CDF, 0x000000, 0xFFFFFF, + 0x006CE4, 0x006CE4, 0x000000, 0xFFFFFF, + 0x006CE6, 0x006CE7, 0x000000, 0xFFFFFF, + 0x006CE9, 0x006CE9, 0x000000, 0xFFFFFF, + 0x006CEC, 0x006CED, 0x000000, 0xFFFFFF, + 0x006CF2, 0x006CF2, 0x000000, 0xFFFFFF, + 0x006CF4, 0x006CF4, 0x000000, 0xFFFFFF, + 0x006CF9, 0x006CF9, 0x000000, 0xFFFFFF, + 0x006CFF, 0x006D00, 0x000000, 0xFFFFFF, + 0x006D02, 0x006D03, 0x000000, 0xFFFFFF, + 0x006D05, 0x006D06, 0x000000, 0xFFFFFF, + 0x006D08, 0x006D0A, 0x000000, 0xFFFFFF, + 0x006D0D, 0x006D0D, 0x000000, 0xFFFFFF, + 0x006D0F, 0x006D11, 0x000000, 0xFFFFFF, + 0x006D13, 0x006D16, 0x000000, 0xFFFFFF, + 0x006D18, 0x006D18, 0x000000, 0xFFFFFF, + 0x006D1C, 0x006D1D, 0x000000, 0xFFFFFF, + 0x006D1F, 0x006D24, 0x000000, 0xFFFFFF, + 0x006D26, 0x006D26, 0x000000, 0xFFFFFF, + 0x006D28, 0x006D29, 0x000000, 0xFFFFFF, + 0x006D2C, 0x006D2D, 0x000000, 0xFFFFFF, + 0x006D2F, 0x006D30, 0x000000, 0xFFFFFF, + 0x006D34, 0x006D34, 0x000000, 0xFFFFFF, + 0x006D36, 0x006D38, 0x000000, 0xFFFFFF, + 0x006D3A, 0x006D3A, 0x000000, 0xFFFFFF, + 0x006D3F, 0x006D40, 0x000000, 0xFFFFFF, + 0x006D42, 0x006D42, 0x000000, 0xFFFFFF, + 0x006D44, 0x006D44, 0x000000, 0xFFFFFF, + 0x006D49, 0x006D49, 0x000000, 0xFFFFFF, + 0x006D4C, 0x006D4C, 0x000000, 0xFFFFFF, + 0x006D50, 0x006D50, 0x000000, 0xFFFFFF, + 0x006D55, 0x006D58, 0x000000, 0xFFFFFF, + 0x006D5B, 0x006D5B, 0x000000, 0xFFFFFF, + 0x006D5D, 0x006D5D, 0x000000, 0xFFFFFF, + 0x006D5F, 0x006D5F, 0x000000, 0xFFFFFF, + 0x006D61, 0x006D62, 0x000000, 0xFFFFFF, + 0x006D64, 0x006D65, 0x000000, 0xFFFFFF, + 0x006D67, 0x006D68, 0x000000, 0xFFFFFF, + 0x006D6B, 0x006D6D, 0x000000, 0xFFFFFF, + 0x006D70, 0x006D73, 0x000000, 0xFFFFFF, + 0x006D75, 0x006D76, 0x000000, 0xFFFFFF, + 0x006D79, 0x006D7B, 0x000000, 0xFFFFFF, + 0x006D7D, 0x006D81, 0x000000, 0xFFFFFF, + 0x006D83, 0x006D84, 0x000000, 0xFFFFFF, + 0x006D86, 0x006D87, 0x000000, 0xFFFFFF, + 0x006D8A, 0x006D8B, 0x000000, 0xFFFFFF, + 0x006D8D, 0x006D8D, 0x000000, 0xFFFFFF, + 0x006D8F, 0x006D90, 0x000000, 0xFFFFFF, + 0x006D92, 0x006D92, 0x000000, 0xFFFFFF, + 0x006D96, 0x006D9A, 0x000000, 0xFFFFFF, + 0x006D9C, 0x006D9C, 0x000000, 0xFFFFFF, + 0x006DA2, 0x006DA2, 0x000000, 0xFFFFFF, + 0x006DA5, 0x006DA5, 0x000000, 0xFFFFFF, + 0x006DAC, 0x006DAD, 0x000000, 0xFFFFFF, + 0x006DB0, 0x006DB1, 0x000000, 0xFFFFFF, + 0x006DB3, 0x006DB4, 0x000000, 0xFFFFFF, + 0x006DB6, 0x006DB7, 0x000000, 0xFFFFFF, + 0x006DB9, 0x006DBE, 0x000000, 0xFFFFFF, + 0x006DC1, 0x006DC3, 0x000000, 0xFFFFFF, + 0x006DC8, 0x006DCA, 0x000000, 0xFFFFFF, + 0x006DCD, 0x006DD0, 0x000000, 0xFFFFFF, + 0x006DD2, 0x006DD5, 0x000000, 0xFFFFFF, + 0x006DD7, 0x006DD7, 0x000000, 0xFFFFFF, + 0x006DDA, 0x006DDC, 0x000000, 0xFFFFFF, + 0x006DDF, 0x006DDF, 0x000000, 0xFFFFFF, + 0x006DE2, 0x006DE3, 0x000000, 0xFFFFFF, + 0x006DE5, 0x006DE5, 0x000000, 0xFFFFFF, + 0x006DE7, 0x006DEA, 0x000000, 0xFFFFFF, + 0x006DED, 0x006DED, 0x000000, 0xFFFFFF, + 0x006DEF, 0x006DF0, 0x000000, 0xFFFFFF, + 0x006DF2, 0x006DF2, 0x000000, 0xFFFFFF, + 0x006DF4, 0x006DF6, 0x000000, 0xFFFFFF, + 0x006DF8, 0x006DF8, 0x000000, 0xFFFFFF, + 0x006DFA, 0x006DFA, 0x000000, 0xFFFFFF, + 0x006DFD, 0x006E04, 0x000000, 0xFFFFFF, + 0x006E06, 0x006E09, 0x000000, 0xFFFFFF, + 0x006E0B, 0x006E0B, 0x000000, 0xFFFFFF, + 0x006E0F, 0x006E0F, 0x000000, 0xFFFFFF, + 0x006E12, 0x006E13, 0x000000, 0xFFFFFF, + 0x006E15, 0x006E15, 0x000000, 0xFFFFFF, + 0x006E18, 0x006E19, 0x000000, 0xFFFFFF, + 0x006E1B, 0x006E1C, 0x000000, 0xFFFFFF, + 0x006E1E, 0x006E1F, 0x000000, 0xFFFFFF, + 0x006E22, 0x006E22, 0x000000, 0xFFFFFF, + 0x006E26, 0x006E28, 0x000000, 0xFFFFFF, + 0x006E2A, 0x006E2A, 0x000000, 0xFFFFFF, + 0x006E2C, 0x006E2C, 0x000000, 0xFFFFFF, + 0x006E2E, 0x006E2E, 0x000000, 0xFFFFFF, + 0x006E30, 0x006E31, 0x000000, 0xFFFFFF, + 0x006E33, 0x006E33, 0x000000, 0xFFFFFF, + 0x006E35, 0x006E37, 0x000000, 0xFFFFFF, + 0x006E39, 0x006E39, 0x000000, 0xFFFFFF, + 0x006E3B, 0x006E42, 0x000000, 0xFFFFFF, + 0x006E45, 0x006E4C, 0x000000, 0xFFFFFF, + 0x006E4F, 0x006E52, 0x000000, 0xFFFFFF, + 0x006E55, 0x006E55, 0x000000, 0xFFFFFF, + 0x006E57, 0x006E57, 0x000000, 0xFFFFFF, + 0x006E59, 0x006E5A, 0x000000, 0xFFFFFF, + 0x006E5C, 0x006E5E, 0x000000, 0xFFFFFF, + 0x006E60, 0x006E6A, 0x000000, 0xFFFFFF, + 0x006E6C, 0x006E6D, 0x000000, 0xFFFFFF, + 0x006E6F, 0x006E7D, 0x000000, 0xFFFFFF, + 0x006E80, 0x006E82, 0x000000, 0xFFFFFF, + 0x006E84, 0x006E84, 0x000000, 0xFFFFFF, + 0x006E87, 0x006E88, 0x000000, 0xFFFFFF, + 0x006E8A, 0x006E8E, 0x000000, 0xFFFFFF, + 0x006E91, 0x006E97, 0x000000, 0xFFFFFF, + 0x006E99, 0x006E9B, 0x000000, 0xFFFFFF, + 0x006E9D, 0x006E9E, 0x000000, 0xFFFFFF, + 0x006EA0, 0x006EA1, 0x000000, 0xFFFFFF, + 0x006EA3, 0x006EA4, 0x000000, 0xFFFFFF, + 0x006EA6, 0x006EA6, 0x000000, 0xFFFFFF, + 0x006EA8, 0x006EA9, 0x000000, 0xFFFFFF, + 0x006EAB, 0x006EAE, 0x000000, 0xFFFFFF, + 0x006EB0, 0x006EB0, 0x000000, 0xFFFFFF, + 0x006EB3, 0x006EB3, 0x000000, 0xFFFFFF, + 0x006EB5, 0x006EB5, 0x000000, 0xFFFFFF, + 0x006EB8, 0x006EB9, 0x000000, 0xFFFFFF, + 0x006EBC, 0x006EBC, 0x000000, 0xFFFFFF, + 0x006EBE, 0x006EC0, 0x000000, 0xFFFFFF, + 0x006EC3, 0x006EC6, 0x000000, 0xFFFFFF, + 0x006EC8, 0x006ECA, 0x000000, 0xFFFFFF, + 0x006ECC, 0x006ECE, 0x000000, 0xFFFFFF, + 0x006ED0, 0x006ED0, 0x000000, 0xFFFFFF, + 0x006ED2, 0x006ED2, 0x000000, 0xFFFFFF, + 0x006ED6, 0x006ED6, 0x000000, 0xFFFFFF, + 0x006ED8, 0x006ED9, 0x000000, 0xFFFFFF, + 0x006EDB, 0x006EDD, 0x000000, 0xFFFFFF, + 0x006EE3, 0x006EE3, 0x000000, 0xFFFFFF, + 0x006EE7, 0x006EE7, 0x000000, 0xFFFFFF, + 0x006EEA, 0x006EF3, 0x000000, 0xFFFFFF, + 0x006EF5, 0x006EF8, 0x000000, 0xFFFFFF, + 0x006EFA, 0x006F01, 0x000000, 0xFFFFFF, + 0x006F03, 0x006F05, 0x000000, 0xFFFFFF, + 0x006F07, 0x006F08, 0x000000, 0xFFFFFF, + 0x006F0A, 0x006F0E, 0x000000, 0xFFFFFF, + 0x006F10, 0x006F12, 0x000000, 0xFFFFFF, + 0x006F16, 0x006F1F, 0x000000, 0xFFFFFF, + 0x006F21, 0x006F23, 0x000000, 0xFFFFFF, + 0x006F25, 0x006F28, 0x000000, 0xFFFFFF, + 0x006F2C, 0x006F2C, 0x000000, 0xFFFFFF, + 0x006F2E, 0x006F2E, 0x000000, 0xFFFFFF, + 0x006F30, 0x006F30, 0x000000, 0xFFFFFF, + 0x006F32, 0x006F32, 0x000000, 0xFFFFFF, + 0x006F34, 0x006F35, 0x000000, 0xFFFFFF, + 0x006F37, 0x006F3D, 0x000000, 0xFFFFFF, + 0x006F3F, 0x006F45, 0x000000, 0xFFFFFF, + 0x006F48, 0x006F4A, 0x000000, 0xFFFFFF, + 0x006F4C, 0x006F4C, 0x000000, 0xFFFFFF, + 0x006F4E, 0x006F57, 0x000000, 0xFFFFFF, + 0x006F59, 0x006F5B, 0x000000, 0xFFFFFF, + 0x006F5D, 0x006F5D, 0x000000, 0xFFFFFF, + 0x006F5F, 0x006F61, 0x000000, 0xFFFFFF, + 0x006F63, 0x006F65, 0x000000, 0xFFFFFF, + 0x006F67, 0x006F6C, 0x000000, 0xFFFFFF, + 0x006F6F, 0x006F71, 0x000000, 0xFFFFFF, + 0x006F73, 0x006F73, 0x000000, 0xFFFFFF, + 0x006F75, 0x006F77, 0x000000, 0xFFFFFF, + 0x006F79, 0x006F79, 0x000000, 0xFFFFFF, + 0x006F7B, 0x006F7B, 0x000000, 0xFFFFFF, + 0x006F7D, 0x006F83, 0x000000, 0xFFFFFF, + 0x006F85, 0x006F87, 0x000000, 0xFFFFFF, + 0x006F8A, 0x006F8B, 0x000000, 0xFFFFFF, + 0x006F8F, 0x006F9B, 0x000000, 0xFFFFFF, + 0x006F9D, 0x006FA0, 0x000000, 0xFFFFFF, + 0x006FA2, 0x006FA6, 0x000000, 0xFFFFFF, + 0x006FA8, 0x006FB2, 0x000000, 0xFFFFFF, + 0x006FB4, 0x006FB5, 0x000000, 0xFFFFFF, + 0x006FB7, 0x006FB8, 0x000000, 0xFFFFFF, + 0x006FBA, 0x006FBF, 0x000000, 0xFFFFFF, + 0x006FC1, 0x006FC1, 0x000000, 0xFFFFFF, + 0x006FC3, 0x006FC8, 0x000000, 0xFFFFFF, + 0x006FCA, 0x006FD0, 0x000000, 0xFFFFFF, + 0x006FD3, 0x006FDD, 0x000000, 0xFFFFFF, + 0x006FDF, 0x006FDF, 0x000000, 0xFFFFFF, + 0x006FE2, 0x006FED, 0x000000, 0xFFFFFF, + 0x006FF0, 0x007010, 0x000000, 0xFFFFFF, + 0x007012, 0x007019, 0x000000, 0xFFFFFF, + 0x00701C, 0x007022, 0x000000, 0xFFFFFF, + 0x007024, 0x007034, 0x000000, 0xFFFFFF, + 0x007036, 0x007038, 0x000000, 0xFFFFFF, + 0x00703A, 0x00704B, 0x000000, 0xFFFFFF, + 0x00704D, 0x00704E, 0x000000, 0xFFFFFF, + 0x007050, 0x00705D, 0x000000, 0xFFFFFF, + 0x00705F, 0x00706A, 0x000000, 0xFFFFFF, + 0x00706E, 0x00706E, 0x000000, 0xFFFFFF, + 0x007071, 0x007074, 0x000000, 0xFFFFFF, + 0x007077, 0x007077, 0x000000, 0xFFFFFF, + 0x007079, 0x00707B, 0x000000, 0xFFFFFF, + 0x00707D, 0x00707D, 0x000000, 0xFFFFFF, + 0x007081, 0x007084, 0x000000, 0xFFFFFF, + 0x007086, 0x007088, 0x000000, 0xFFFFFF, + 0x00708B, 0x00708D, 0x000000, 0xFFFFFF, + 0x00708F, 0x007091, 0x000000, 0xFFFFFF, + 0x007093, 0x007093, 0x000000, 0xFFFFFF, + 0x007097, 0x007098, 0x000000, 0xFFFFFF, + 0x00709A, 0x00709B, 0x000000, 0xFFFFFF, + 0x00709E, 0x0070AA, 0x000000, 0xFFFFFF, + 0x0070B0, 0x0070B0, 0x000000, 0xFFFFFF, + 0x0070B2, 0x0070B2, 0x000000, 0xFFFFFF, + 0x0070B4, 0x0070B6, 0x000000, 0xFFFFFF, + 0x0070BA, 0x0070BA, 0x000000, 0xFFFFFF, + 0x0070BE, 0x0070BF, 0x000000, 0xFFFFFF, + 0x0070C4, 0x0070C7, 0x000000, 0xFFFFFF, + 0x0070C9, 0x0070C9, 0x000000, 0xFFFFFF, + 0x0070CB, 0x0070D7, 0x000000, 0xFFFFFF, + 0x0070DA, 0x0070DA, 0x000000, 0xFFFFFF, + 0x0070DC, 0x0070DE, 0x000000, 0xFFFFFF, + 0x0070E0, 0x0070E3, 0x000000, 0xFFFFFF, + 0x0070E5, 0x0070E5, 0x000000, 0xFFFFFF, + 0x0070EA, 0x0070EA, 0x000000, 0xFFFFFF, + 0x0070EE, 0x0070EE, 0x000000, 0xFFFFFF, + 0x0070F0, 0x0070F6, 0x000000, 0xFFFFFF, + 0x0070F8, 0x0070F8, 0x000000, 0xFFFFFF, + 0x0070FA, 0x0070FC, 0x000000, 0xFFFFFF, + 0x0070FE, 0x007108, 0x000000, 0xFFFFFF, + 0x00710B, 0x00710F, 0x000000, 0xFFFFFF, + 0x007111, 0x007112, 0x000000, 0xFFFFFF, + 0x007114, 0x007114, 0x000000, 0xFFFFFF, + 0x007117, 0x007117, 0x000000, 0xFFFFFF, + 0x00711B, 0x007125, 0x000000, 0xFFFFFF, + 0x007127, 0x00712E, 0x000000, 0xFFFFFF, + 0x007132, 0x007135, 0x000000, 0xFFFFFF, + 0x007137, 0x007144, 0x000000, 0xFFFFFF, + 0x007146, 0x007149, 0x000000, 0xFFFFFF, + 0x00714B, 0x00714B, 0x000000, 0xFFFFFF, + 0x00714D, 0x00714D, 0x000000, 0xFFFFFF, + 0x00714F, 0x00715B, 0x000000, 0xFFFFFF, + 0x00715D, 0x00715D, 0x000000, 0xFFFFFF, + 0x00715F, 0x007163, 0x000000, 0xFFFFFF, + 0x007165, 0x007165, 0x000000, 0xFFFFFF, + 0x007169, 0x00716D, 0x000000, 0xFFFFFF, + 0x00716F, 0x007171, 0x000000, 0xFFFFFF, + 0x007174, 0x007177, 0x000000, 0xFFFFFF, + 0x007179, 0x007179, 0x000000, 0xFFFFFF, + 0x00717B, 0x00717C, 0x000000, 0xFFFFFF, + 0x00717E, 0x007183, 0x000000, 0xFFFFFF, + 0x007185, 0x007189, 0x000000, 0xFFFFFF, + 0x00718B, 0x00718E, 0x000000, 0xFFFFFF, + 0x007190, 0x007193, 0x000000, 0xFFFFFF, + 0x007195, 0x007197, 0x000000, 0xFFFFFF, + 0x00719A, 0x00719E, 0x000000, 0xFFFFFF, + 0x0071A1, 0x0071A7, 0x000000, 0xFFFFFF, + 0x0071A9, 0x0071AB, 0x000000, 0xFFFFFF, + 0x0071AD, 0x0071B2, 0x000000, 0xFFFFFF, + 0x0071B4, 0x0071B4, 0x000000, 0xFFFFFF, + 0x0071B6, 0x0071B8, 0x000000, 0xFFFFFF, + 0x0071BA, 0x0071C2, 0x000000, 0xFFFFFF, + 0x0071C4, 0x0071CD, 0x000000, 0xFFFFFF, + 0x0071CF, 0x0071D3, 0x000000, 0xFFFFFF, + 0x0071D6, 0x0071DF, 0x000000, 0xFFFFFF, + 0x0071E1, 0x0071E4, 0x000000, 0xFFFFFF, + 0x0071E6, 0x0071E6, 0x000000, 0xFFFFFF, + 0x0071E8, 0x0071ED, 0x000000, 0xFFFFFF, + 0x0071EF, 0x0071F8, 0x000000, 0xFFFFFF, + 0x0071FA, 0x007205, 0x000000, 0xFFFFFF, + 0x007207, 0x00721C, 0x000000, 0xFFFFFF, + 0x00721E, 0x007227, 0x000000, 0xFFFFFF, + 0x007229, 0x007229, 0x000000, 0xFFFFFF, + 0x00722B, 0x00722B, 0x000000, 0xFFFFFF, + 0x00722D, 0x00722F, 0x000000, 0xFFFFFF, + 0x007232, 0x007234, 0x000000, 0xFFFFFF, + 0x00723A, 0x00723A, 0x000000, 0xFFFFFF, + 0x00723C, 0x00723C, 0x000000, 0xFFFFFF, + 0x00723E, 0x00723E, 0x000000, 0xFFFFFF, + 0x007240, 0x007246, 0x000000, 0xFFFFFF, + 0x007249, 0x00724B, 0x000000, 0xFFFFFF, + 0x00724E, 0x007251, 0x000000, 0xFFFFFF, + 0x007253, 0x007255, 0x000000, 0xFFFFFF, + 0x007257, 0x007258, 0x000000, 0xFFFFFF, + 0x00725A, 0x00725A, 0x000000, 0xFFFFFF, + 0x00725C, 0x00725C, 0x000000, 0xFFFFFF, + 0x00725E, 0x00725E, 0x000000, 0xFFFFFF, + 0x007260, 0x007260, 0x000000, 0xFFFFFF, + 0x007263, 0x007265, 0x000000, 0xFFFFFF, + 0x007268, 0x007268, 0x000000, 0xFFFFFF, + 0x00726A, 0x00726D, 0x000000, 0xFFFFFF, + 0x007270, 0x007271, 0x000000, 0xFFFFFF, + 0x007273, 0x007274, 0x000000, 0xFFFFFF, + 0x007276, 0x007278, 0x000000, 0xFFFFFF, + 0x00727B, 0x00727D, 0x000000, 0xFFFFFF, + 0x007282, 0x007283, 0x000000, 0xFFFFFF, + 0x007285, 0x007289, 0x000000, 0xFFFFFF, + 0x00728C, 0x00728C, 0x000000, 0xFFFFFF, + 0x00728E, 0x00728E, 0x000000, 0xFFFFFF, + 0x007290, 0x007291, 0x000000, 0xFFFFFF, + 0x007293, 0x00729E, 0x000000, 0xFFFFFF, + 0x0072A0, 0x0072AB, 0x000000, 0xFFFFFF, + 0x0072AE, 0x0072AE, 0x000000, 0xFFFFFF, + 0x0072B1, 0x0072B3, 0x000000, 0xFFFFFF, + 0x0072B5, 0x0072B5, 0x000000, 0xFFFFFF, + 0x0072BA, 0x0072C0, 0x000000, 0xFFFFFF, + 0x0072C5, 0x0072C7, 0x000000, 0xFFFFFF, + 0x0072C9, 0x0072CC, 0x000000, 0xFFFFFF, + 0x0072CF, 0x0072CF, 0x000000, 0xFFFFFF, + 0x0072D1, 0x0072D1, 0x000000, 0xFFFFFF, + 0x0072D3, 0x0072D6, 0x000000, 0xFFFFFF, + 0x0072D8, 0x0072D8, 0x000000, 0xFFFFFF, + 0x0072DA, 0x0072DD, 0x000000, 0xFFFFFF, + 0x0072DF, 0x0072DF, 0x000000, 0xFFFFFF, + 0x0072E2, 0x0072E7, 0x000000, 0xFFFFFF, + 0x0072EA, 0x0072EB, 0x000000, 0xFFFFFF, + 0x0072F5, 0x0072F6, 0x000000, 0xFFFFFF, + 0x0072F9, 0x0072F9, 0x000000, 0xFFFFFF, + 0x0072FD, 0x007300, 0x000000, 0xFFFFFF, + 0x007302, 0x007302, 0x000000, 0xFFFFFF, + 0x007304, 0x007309, 0x000000, 0xFFFFFF, + 0x00730B, 0x00730D, 0x000000, 0xFFFFFF, + 0x00730F, 0x007312, 0x000000, 0xFFFFFF, + 0x007314, 0x007314, 0x000000, 0xFFFFFF, + 0x007318, 0x00731A, 0x000000, 0xFFFFFF, + 0x00731F, 0x007320, 0x000000, 0xFFFFFF, + 0x007323, 0x007324, 0x000000, 0xFFFFFF, + 0x007326, 0x007328, 0x000000, 0xFFFFFF, + 0x00732D, 0x00732D, 0x000000, 0xFFFFFF, + 0x00732F, 0x007330, 0x000000, 0xFFFFFF, + 0x007332, 0x007333, 0x000000, 0xFFFFFF, + 0x007335, 0x007336, 0x000000, 0xFFFFFF, + 0x00733A, 0x00733D, 0x000000, 0xFFFFFF, + 0x007340, 0x00734C, 0x000000, 0xFFFFFF, + 0x00734E, 0x00734F, 0x000000, 0xFFFFFF, + 0x007351, 0x007351, 0x000000, 0xFFFFFF, + 0x007353, 0x007356, 0x000000, 0xFFFFFF, + 0x007358, 0x00735F, 0x000000, 0xFFFFFF, + 0x007361, 0x00736B, 0x000000, 0xFFFFFF, + 0x00736E, 0x00736E, 0x000000, 0xFFFFFF, + 0x007370, 0x00737D, 0x000000, 0xFFFFFF, + 0x00737F, 0x007383, 0x000000, 0xFFFFFF, + 0x007385, 0x007386, 0x000000, 0xFFFFFF, + 0x007388, 0x007388, 0x000000, 0xFFFFFF, + 0x00738A, 0x00738A, 0x000000, 0xFFFFFF, + 0x00738C, 0x00738D, 0x000000, 0xFFFFFF, + 0x00738F, 0x007390, 0x000000, 0xFFFFFF, + 0x007392, 0x007395, 0x000000, 0xFFFFFF, + 0x007397, 0x00739A, 0x000000, 0xFFFFFF, + 0x00739C, 0x00739E, 0x000000, 0xFFFFFF, + 0x0073A0, 0x0073A1, 0x000000, 0xFFFFFF, + 0x0073A3, 0x0073A8, 0x000000, 0xFFFFFF, + 0x0073AA, 0x0073AA, 0x000000, 0xFFFFFF, + 0x0073AC, 0x0073AD, 0x000000, 0xFFFFFF, + 0x0073B1, 0x0073B1, 0x000000, 0xFFFFFF, + 0x0073B4, 0x0073B6, 0x000000, 0xFFFFFF, + 0x0073B8, 0x0073B9, 0x000000, 0xFFFFFF, + 0x0073BC, 0x0073BF, 0x000000, 0xFFFFFF, + 0x0073C1, 0x0073C1, 0x000000, 0xFFFFFF, + 0x0073C3, 0x0073C7, 0x000000, 0xFFFFFF, + 0x0073CB, 0x0073CC, 0x000000, 0xFFFFFF, + 0x0073CE, 0x0073CE, 0x000000, 0xFFFFFF, + 0x0073D2, 0x0073D8, 0x000000, 0xFFFFFF, + 0x0073DA, 0x0073DD, 0x000000, 0xFFFFFF, + 0x0073DF, 0x0073DF, 0x000000, 0xFFFFFF, + 0x0073E1, 0x0073E4, 0x000000, 0xFFFFFF, + 0x0073E6, 0x0073E6, 0x000000, 0xFFFFFF, + 0x0073E8, 0x0073E8, 0x000000, 0xFFFFFF, + 0x0073EA, 0x0073EC, 0x000000, 0xFFFFFF, + 0x0073EE, 0x0073F1, 0x000000, 0xFFFFFF, + 0x0073F3, 0x007402, 0x000000, 0xFFFFFF, + 0x007404, 0x007404, 0x000000, 0xFFFFFF, + 0x007407, 0x007408, 0x000000, 0xFFFFFF, + 0x00740B, 0x00740E, 0x000000, 0xFFFFFF, + 0x007411, 0x007419, 0x000000, 0xFFFFFF, + 0x00741C, 0x007421, 0x000000, 0xFFFFFF, + 0x007423, 0x007424, 0x000000, 0xFFFFFF, + 0x007427, 0x007427, 0x000000, 0xFFFFFF, + 0x007429, 0x007429, 0x000000, 0xFFFFFF, + 0x00742B, 0x00742B, 0x000000, 0xFFFFFF, + 0x00742D, 0x00742D, 0x000000, 0xFFFFFF, + 0x00742F, 0x00742F, 0x000000, 0xFFFFFF, + 0x007431, 0x007432, 0x000000, 0xFFFFFF, + 0x007437, 0x00743B, 0x000000, 0xFFFFFF, + 0x00743D, 0x007440, 0x000000, 0xFFFFFF, + 0x007442, 0x007454, 0x000000, 0xFFFFFF, + 0x007456, 0x007456, 0x000000, 0xFFFFFF, + 0x007458, 0x007458, 0x000000, 0xFFFFFF, + 0x00745D, 0x00745D, 0x000000, 0xFFFFFF, + 0x007460, 0x00746C, 0x000000, 0xFFFFFF, + 0x00746E, 0x00746F, 0x000000, 0xFFFFFF, + 0x007471, 0x007475, 0x000000, 0xFFFFFF, + 0x007478, 0x00747D, 0x000000, 0xFFFFFF, + 0x00747F, 0x00747F, 0x000000, 0xFFFFFF, + 0x007482, 0x007482, 0x000000, 0xFFFFFF, + 0x007484, 0x007486, 0x000000, 0xFFFFFF, + 0x007488, 0x00748A, 0x000000, 0xFFFFFF, + 0x00748C, 0x00748D, 0x000000, 0xFFFFFF, + 0x00748F, 0x00748F, 0x000000, 0xFFFFFF, + 0x007491, 0x00749B, 0x000000, 0xFFFFFF, + 0x00749D, 0x00749D, 0x000000, 0xFFFFFF, + 0x00749F, 0x0074A6, 0x000000, 0xFFFFFF, + 0x0074AA, 0x0074B9, 0x000000, 0xFFFFFF, + 0x0074BB, 0x0074D1, 0x000000, 0xFFFFFF, + 0x0074D3, 0x0074DB, 0x000000, 0xFFFFFF, + 0x0074DD, 0x0074DD, 0x000000, 0xFFFFFF, + 0x0074DF, 0x0074DF, 0x000000, 0xFFFFFF, + 0x0074E1, 0x0074E1, 0x000000, 0xFFFFFF, + 0x0074E5, 0x0074E5, 0x000000, 0xFFFFFF, + 0x0074E7, 0x0074ED, 0x000000, 0xFFFFFF, + 0x0074F0, 0x0074F3, 0x000000, 0xFFFFFF, + 0x0074F5, 0x0074F5, 0x000000, 0xFFFFFF, + 0x0074F8, 0x0074FE, 0x000000, 0xFFFFFF, + 0x007500, 0x007503, 0x000000, 0xFFFFFF, + 0x007505, 0x00750C, 0x000000, 0xFFFFFF, + 0x00750E, 0x00750E, 0x000000, 0xFFFFFF, + 0x007510, 0x007510, 0x000000, 0xFFFFFF, + 0x007512, 0x007512, 0x000000, 0xFFFFFF, + 0x007514, 0x007517, 0x000000, 0xFFFFFF, + 0x00751B, 0x00751B, 0x000000, 0xFFFFFF, + 0x00751D, 0x00751E, 0x000000, 0xFFFFFF, + 0x007520, 0x007524, 0x000000, 0xFFFFFF, + 0x007526, 0x007527, 0x000000, 0xFFFFFF, + 0x00752A, 0x00752A, 0x000000, 0xFFFFFF, + 0x00752E, 0x00752E, 0x000000, 0xFFFFFF, + 0x007534, 0x007534, 0x000000, 0xFFFFFF, + 0x007536, 0x007536, 0x000000, 0xFFFFFF, + 0x007539, 0x007539, 0x000000, 0xFFFFFF, + 0x00753C, 0x00753D, 0x000000, 0xFFFFFF, + 0x00753F, 0x00753F, 0x000000, 0xFFFFFF, + 0x007541, 0x007544, 0x000000, 0xFFFFFF, + 0x007546, 0x007547, 0x000000, 0xFFFFFF, + 0x007549, 0x00754A, 0x000000, 0xFFFFFF, + 0x00754D, 0x00754D, 0x000000, 0xFFFFFF, + 0x007550, 0x007553, 0x000000, 0xFFFFFF, + 0x007555, 0x007558, 0x000000, 0xFFFFFF, + 0x00755D, 0x007564, 0x000000, 0xFFFFFF, + 0x007567, 0x007569, 0x000000, 0xFFFFFF, + 0x00756B, 0x007571, 0x000000, 0xFFFFFF, + 0x007573, 0x007573, 0x000000, 0xFFFFFF, + 0x007575, 0x007577, 0x000000, 0xFFFFFF, + 0x00757A, 0x00757E, 0x000000, 0xFFFFFF, + 0x007580, 0x007582, 0x000000, 0xFFFFFF, + 0x007584, 0x007585, 0x000000, 0xFFFFFF, + 0x007587, 0x00758A, 0x000000, 0xFFFFFF, + 0x00758C, 0x00758E, 0x000000, 0xFFFFFF, + 0x007590, 0x007590, 0x000000, 0xFFFFFF, + 0x007593, 0x007593, 0x000000, 0xFFFFFF, + 0x007595, 0x007595, 0x000000, 0xFFFFFF, + 0x007598, 0x007598, 0x000000, 0xFFFFFF, + 0x00759B, 0x00759C, 0x000000, 0xFFFFFF, + 0x00759E, 0x00759E, 0x000000, 0xFFFFFF, + 0x0075A2, 0x0075A2, 0x000000, 0xFFFFFF, + 0x0075A6, 0x0075AA, 0x000000, 0xFFFFFF, + 0x0075AD, 0x0075AD, 0x000000, 0xFFFFFF, + 0x0075B6, 0x0075B7, 0x000000, 0xFFFFFF, + 0x0075BA, 0x0075BB, 0x000000, 0xFFFFFF, + 0x0075BF, 0x0075C1, 0x000000, 0xFFFFFF, + 0x0075C6, 0x0075C6, 0x000000, 0xFFFFFF, + 0x0075CB, 0x0075CC, 0x000000, 0xFFFFFF, + 0x0075CE, 0x0075D1, 0x000000, 0xFFFFFF, + 0x0075D3, 0x0075D3, 0x000000, 0xFFFFFF, + 0x0075D7, 0x0075D7, 0x000000, 0xFFFFFF, + 0x0075D9, 0x0075DA, 0x000000, 0xFFFFFF, + 0x0075DC, 0x0075DD, 0x000000, 0xFFFFFF, + 0x0075DF, 0x0075E1, 0x000000, 0xFFFFFF, + 0x0075E5, 0x0075E5, 0x000000, 0xFFFFFF, + 0x0075E9, 0x0075E9, 0x000000, 0xFFFFFF, + 0x0075EC, 0x0075EF, 0x000000, 0xFFFFFF, + 0x0075F2, 0x0075F3, 0x000000, 0xFFFFFF, + 0x0075F5, 0x0075F8, 0x000000, 0xFFFFFF, + 0x0075FA, 0x0075FB, 0x000000, 0xFFFFFF, + 0x0075FD, 0x0075FE, 0x000000, 0xFFFFFF, + 0x007602, 0x007602, 0x000000, 0xFFFFFF, + 0x007604, 0x007604, 0x000000, 0xFFFFFF, + 0x007606, 0x007609, 0x000000, 0xFFFFFF, + 0x00760B, 0x00760B, 0x000000, 0xFFFFFF, + 0x00760D, 0x00760F, 0x000000, 0xFFFFFF, + 0x007611, 0x007614, 0x000000, 0xFFFFFF, + 0x007616, 0x007616, 0x000000, 0xFFFFFF, + 0x00761A, 0x00761A, 0x000000, 0xFFFFFF, + 0x00761C, 0x00761E, 0x000000, 0xFFFFFF, + 0x007621, 0x007621, 0x000000, 0xFFFFFF, + 0x007623, 0x007623, 0x000000, 0xFFFFFF, + 0x007627, 0x007628, 0x000000, 0xFFFFFF, + 0x00762C, 0x00762C, 0x000000, 0xFFFFFF, + 0x00762E, 0x00762F, 0x000000, 0xFFFFFF, + 0x007631, 0x007632, 0x000000, 0xFFFFFF, + 0x007636, 0x007637, 0x000000, 0xFFFFFF, + 0x007639, 0x00763B, 0x000000, 0xFFFFFF, + 0x00763D, 0x00763D, 0x000000, 0xFFFFFF, + 0x007641, 0x007642, 0x000000, 0xFFFFFF, + 0x007644, 0x00764B, 0x000000, 0xFFFFFF, + 0x00764E, 0x007653, 0x000000, 0xFFFFFF, + 0x007655, 0x007655, 0x000000, 0xFFFFFF, + 0x007657, 0x00765B, 0x000000, 0xFFFFFF, + 0x00765D, 0x00765D, 0x000000, 0xFFFFFF, + 0x00765F, 0x007662, 0x000000, 0xFFFFFF, + 0x007664, 0x00766A, 0x000000, 0xFFFFFF, + 0x00766C, 0x00766E, 0x000000, 0xFFFFFF, + 0x007670, 0x007677, 0x000000, 0xFFFFFF, + 0x007679, 0x00767A, 0x000000, 0xFFFFFF, + 0x00767C, 0x00767C, 0x000000, 0xFFFFFF, + 0x00767F, 0x007681, 0x000000, 0xFFFFFF, + 0x007683, 0x007683, 0x000000, 0xFFFFFF, + 0x007685, 0x007685, 0x000000, 0xFFFFFF, + 0x007689, 0x00768A, 0x000000, 0xFFFFFF, + 0x00768C, 0x00768D, 0x000000, 0xFFFFFF, + 0x00768F, 0x007690, 0x000000, 0xFFFFFF, + 0x007692, 0x007692, 0x000000, 0xFFFFFF, + 0x007694, 0x007695, 0x000000, 0xFFFFFF, + 0x007697, 0x007698, 0x000000, 0xFFFFFF, + 0x00769A, 0x0076A3, 0x000000, 0xFFFFFF, + 0x0076A5, 0x0076AD, 0x000000, 0xFFFFFF, + 0x0076AF, 0x0076B0, 0x000000, 0xFFFFFF, + 0x0076B3, 0x0076B3, 0x000000, 0xFFFFFF, + 0x0076B5, 0x0076BE, 0x000000, 0xFFFFFF, + 0x0076C0, 0x0076C1, 0x000000, 0xFFFFFF, + 0x0076C3, 0x0076C4, 0x000000, 0xFFFFFF, + 0x0076C7, 0x0076C7, 0x000000, 0xFFFFFF, + 0x0076C9, 0x0076C9, 0x000000, 0xFFFFFF, + 0x0076CB, 0x0076CC, 0x000000, 0xFFFFFF, + 0x0076D3, 0x0076D3, 0x000000, 0xFFFFFF, + 0x0076D5, 0x0076D5, 0x000000, 0xFFFFFF, + 0x0076D9, 0x0076DA, 0x000000, 0xFFFFFF, + 0x0076DC, 0x0076DE, 0x000000, 0xFFFFFF, + 0x0076E0, 0x0076E4, 0x000000, 0xFFFFFF, + 0x0076E6, 0x0076ED, 0x000000, 0xFFFFFF, + 0x0076F0, 0x0076F0, 0x000000, 0xFFFFFF, + 0x0076F3, 0x0076F3, 0x000000, 0xFFFFFF, + 0x0076F5, 0x0076F7, 0x000000, 0xFFFFFF, + 0x0076FA, 0x0076FB, 0x000000, 0xFFFFFF, + 0x0076FD, 0x0076FD, 0x000000, 0xFFFFFF, + 0x0076FF, 0x007700, 0x000000, 0xFFFFFF, + 0x007702, 0x007703, 0x000000, 0xFFFFFF, + 0x007705, 0x007706, 0x000000, 0xFFFFFF, + 0x00770A, 0x00770A, 0x000000, 0xFFFFFF, + 0x00770C, 0x00770C, 0x000000, 0xFFFFFF, + 0x00770E, 0x007718, 0x000000, 0xFFFFFF, + 0x00771B, 0x00771E, 0x000000, 0xFFFFFF, + 0x007721, 0x007721, 0x000000, 0xFFFFFF, + 0x007723, 0x007725, 0x000000, 0xFFFFFF, + 0x007727, 0x007727, 0x000000, 0xFFFFFF, + 0x00772A, 0x00772C, 0x000000, 0xFFFFFF, + 0x00772E, 0x00772E, 0x000000, 0xFFFFFF, + 0x007730, 0x007734, 0x000000, 0xFFFFFF, + 0x007739, 0x007739, 0x000000, 0xFFFFFF, + 0x00773B, 0x00773B, 0x000000, 0xFFFFFF, + 0x00773D, 0x00773F, 0x000000, 0xFFFFFF, + 0x007742, 0x007742, 0x000000, 0xFFFFFF, + 0x007744, 0x007746, 0x000000, 0xFFFFFF, + 0x007748, 0x00774F, 0x000000, 0xFFFFFF, + 0x007752, 0x007759, 0x000000, 0xFFFFFF, + 0x00775C, 0x007760, 0x000000, 0xFFFFFF, + 0x007764, 0x007764, 0x000000, 0xFFFFFF, + 0x007767, 0x007767, 0x000000, 0xFFFFFF, + 0x007769, 0x00776A, 0x000000, 0xFFFFFF, + 0x00776D, 0x007778, 0x000000, 0xFFFFFF, + 0x00777A, 0x00777C, 0x000000, 0xFFFFFF, + 0x007781, 0x007783, 0x000000, 0xFFFFFF, + 0x007786, 0x00778B, 0x000000, 0xFFFFFF, + 0x00778F, 0x007790, 0x000000, 0xFFFFFF, + 0x007793, 0x00779E, 0x000000, 0xFFFFFF, + 0x0077A1, 0x0077A1, 0x000000, 0xFFFFFF, + 0x0077A3, 0x0077A4, 0x000000, 0xFFFFFF, + 0x0077A6, 0x0077A6, 0x000000, 0xFFFFFF, + 0x0077A8, 0x0077A8, 0x000000, 0xFFFFFF, + 0x0077AB, 0x0077AB, 0x000000, 0xFFFFFF, + 0x0077AD, 0x0077AF, 0x000000, 0xFFFFFF, + 0x0077B1, 0x0077B2, 0x000000, 0xFFFFFF, + 0x0077B4, 0x0077B4, 0x000000, 0xFFFFFF, + 0x0077B6, 0x0077BA, 0x000000, 0xFFFFFF, + 0x0077BC, 0x0077BC, 0x000000, 0xFFFFFF, + 0x0077BE, 0x0077BE, 0x000000, 0xFFFFFF, + 0x0077C0, 0x0077CC, 0x000000, 0xFFFFFF, + 0x0077CE, 0x0077D6, 0x000000, 0xFFFFFF, + 0x0077D8, 0x0077DA, 0x000000, 0xFFFFFF, + 0x0077DD, 0x0077E1, 0x000000, 0xFFFFFF, + 0x0077E4, 0x0077E4, 0x000000, 0xFFFFFF, + 0x0077E6, 0x0077E6, 0x000000, 0xFFFFFF, + 0x0077E8, 0x0077E8, 0x000000, 0xFFFFFF, + 0x0077EA, 0x0077EA, 0x000000, 0xFFFFFF, + 0x0077EF, 0x0077F2, 0x000000, 0xFFFFFF, + 0x0077F4, 0x0077F5, 0x000000, 0xFFFFFF, + 0x0077F7, 0x0077F7, 0x000000, 0xFFFFFF, + 0x0077F9, 0x0077FC, 0x000000, 0xFFFFFF, + 0x007803, 0x007808, 0x000000, 0xFFFFFF, + 0x00780A, 0x00780B, 0x000000, 0xFFFFFF, + 0x00780E, 0x007810, 0x000000, 0xFFFFFF, + 0x007813, 0x007813, 0x000000, 0xFFFFFF, + 0x007815, 0x007815, 0x000000, 0xFFFFFF, + 0x007819, 0x007819, 0x000000, 0xFFFFFF, + 0x00781B, 0x00781B, 0x000000, 0xFFFFFF, + 0x00781E, 0x00781E, 0x000000, 0xFFFFFF, + 0x007820, 0x007822, 0x000000, 0xFFFFFF, + 0x007824, 0x007824, 0x000000, 0xFFFFFF, + 0x007828, 0x007828, 0x000000, 0xFFFFFF, + 0x00782A, 0x00782B, 0x000000, 0xFFFFFF, + 0x00782E, 0x00782F, 0x000000, 0xFFFFFF, + 0x007831, 0x007833, 0x000000, 0xFFFFFF, + 0x007835, 0x007836, 0x000000, 0xFFFFFF, + 0x00783D, 0x00783D, 0x000000, 0xFFFFFF, + 0x00783F, 0x00783F, 0x000000, 0xFFFFFF, + 0x007841, 0x007844, 0x000000, 0xFFFFFF, + 0x007846, 0x007846, 0x000000, 0xFFFFFF, + 0x007848, 0x00784B, 0x000000, 0xFFFFFF, + 0x00784D, 0x00784D, 0x000000, 0xFFFFFF, + 0x00784F, 0x00784F, 0x000000, 0xFFFFFF, + 0x007851, 0x007851, 0x000000, 0xFFFFFF, + 0x007853, 0x007854, 0x000000, 0xFFFFFF, + 0x007858, 0x00785C, 0x000000, 0xFFFFFF, + 0x00785E, 0x007869, 0x000000, 0xFFFFFF, + 0x00786F, 0x007876, 0x000000, 0xFFFFFF, + 0x007878, 0x00787B, 0x000000, 0xFFFFFF, + 0x00787D, 0x007886, 0x000000, 0xFFFFFF, + 0x007888, 0x007888, 0x000000, 0xFFFFFF, + 0x00788A, 0x00788B, 0x000000, 0xFFFFFF, + 0x00788F, 0x007890, 0x000000, 0xFFFFFF, + 0x007892, 0x007892, 0x000000, 0xFFFFFF, + 0x007894, 0x007896, 0x000000, 0xFFFFFF, + 0x007899, 0x007899, 0x000000, 0xFFFFFF, + 0x00789D, 0x00789E, 0x000000, 0xFFFFFF, + 0x0078A0, 0x0078A0, 0x000000, 0xFFFFFF, + 0x0078A2, 0x0078A2, 0x000000, 0xFFFFFF, + 0x0078A4, 0x0078A4, 0x000000, 0xFFFFFF, + 0x0078A6, 0x0078A6, 0x000000, 0xFFFFFF, + 0x0078A8, 0x0078AF, 0x000000, 0xFFFFFF, + 0x0078B5, 0x0078B8, 0x000000, 0xFFFFFF, + 0x0078BA, 0x0078BD, 0x000000, 0xFFFFFF, + 0x0078BF, 0x0078C0, 0x000000, 0xFFFFFF, + 0x0078C2, 0x0078C4, 0x000000, 0xFFFFFF, + 0x0078C6, 0x0078C8, 0x000000, 0xFFFFFF, + 0x0078CC, 0x0078CF, 0x000000, 0xFFFFFF, + 0x0078D1, 0x0078D3, 0x000000, 0xFFFFFF, + 0x0078D6, 0x0078D8, 0x000000, 0xFFFFFF, + 0x0078DA, 0x0078E7, 0x000000, 0xFFFFFF, + 0x0078E9, 0x0078EB, 0x000000, 0xFFFFFF, + 0x0078ED, 0x0078F1, 0x000000, 0xFFFFFF, + 0x0078F3, 0x0078F3, 0x000000, 0xFFFFFF, + 0x0078F5, 0x0078F6, 0x000000, 0xFFFFFF, + 0x0078F8, 0x0078F9, 0x000000, 0xFFFFFF, + 0x0078FB, 0x007900, 0x000000, 0xFFFFFF, + 0x007902, 0x007904, 0x000000, 0xFFFFFF, + 0x007906, 0x007912, 0x000000, 0xFFFFFF, + 0x007914, 0x00791D, 0x000000, 0xFFFFFF, + 0x00791F, 0x007923, 0x000000, 0xFFFFFF, + 0x007925, 0x007933, 0x000000, 0xFFFFFF, + 0x007935, 0x007939, 0x000000, 0xFFFFFF, + 0x00793D, 0x00793D, 0x000000, 0xFFFFFF, + 0x00793F, 0x00793F, 0x000000, 0xFFFFFF, + 0x007942, 0x007945, 0x000000, 0xFFFFFF, + 0x007947, 0x007947, 0x000000, 0xFFFFFF, + 0x00794A, 0x007952, 0x000000, 0xFFFFFF, + 0x007954, 0x007955, 0x000000, 0xFFFFFF, + 0x007958, 0x007959, 0x000000, 0xFFFFFF, + 0x007961, 0x007961, 0x000000, 0xFFFFFF, + 0x007963, 0x007964, 0x000000, 0xFFFFFF, + 0x007966, 0x007966, 0x000000, 0xFFFFFF, + 0x007969, 0x00796C, 0x000000, 0xFFFFFF, + 0x00796E, 0x00796E, 0x000000, 0xFFFFFF, + 0x007970, 0x007976, 0x000000, 0xFFFFFF, + 0x007979, 0x007979, 0x000000, 0xFFFFFF, + 0x00797B, 0x00797F, 0x000000, 0xFFFFFF, + 0x007982, 0x007983, 0x000000, 0xFFFFFF, + 0x007986, 0x007989, 0x000000, 0xFFFFFF, + 0x00798B, 0x00798E, 0x000000, 0xFFFFFF, + 0x007990, 0x007999, 0x000000, 0xFFFFFF, + 0x00799B, 0x0079A6, 0x000000, 0xFFFFFF, + 0x0079A8, 0x0079B2, 0x000000, 0xFFFFFF, + 0x0079B4, 0x0079B8, 0x000000, 0xFFFFFF, + 0x0079BC, 0x0079BC, 0x000000, 0xFFFFFF, + 0x0079BF, 0x0079BF, 0x000000, 0xFFFFFF, + 0x0079C2, 0x0079C2, 0x000000, 0xFFFFFF, + 0x0079C4, 0x0079C5, 0x000000, 0xFFFFFF, + 0x0079C7, 0x0079C8, 0x000000, 0xFFFFFF, + 0x0079CA, 0x0079CA, 0x000000, 0xFFFFFF, + 0x0079CC, 0x0079CC, 0x000000, 0xFFFFFF, + 0x0079CE, 0x0079D0, 0x000000, 0xFFFFFF, + 0x0079D3, 0x0079D4, 0x000000, 0xFFFFFF, + 0x0079D6, 0x0079D7, 0x000000, 0xFFFFFF, + 0x0079D9, 0x0079DE, 0x000000, 0xFFFFFF, + 0x0079E0, 0x0079E2, 0x000000, 0xFFFFFF, + 0x0079E5, 0x0079E5, 0x000000, 0xFFFFFF, + 0x0079E8, 0x0079E8, 0x000000, 0xFFFFFF, + 0x0079EA, 0x0079EA, 0x000000, 0xFFFFFF, + 0x0079EC, 0x0079EC, 0x000000, 0xFFFFFF, + 0x0079EE, 0x0079EE, 0x000000, 0xFFFFFF, + 0x0079F1, 0x0079F7, 0x000000, 0xFFFFFF, + 0x0079F9, 0x0079FA, 0x000000, 0xFFFFFF, + 0x0079FC, 0x0079FC, 0x000000, 0xFFFFFF, + 0x0079FE, 0x0079FF, 0x000000, 0xFFFFFF, + 0x007A01, 0x007A01, 0x000000, 0xFFFFFF, + 0x007A04, 0x007A05, 0x000000, 0xFFFFFF, + 0x007A07, 0x007A0A, 0x000000, 0xFFFFFF, + 0x007A0C, 0x007A0C, 0x000000, 0xFFFFFF, + 0x007A0F, 0x007A13, 0x000000, 0xFFFFFF, + 0x007A15, 0x007A16, 0x000000, 0xFFFFFF, + 0x007A18, 0x007A19, 0x000000, 0xFFFFFF, + 0x007A1B, 0x007A1D, 0x000000, 0xFFFFFF, + 0x007A1F, 0x007A1F, 0x000000, 0xFFFFFF, + 0x007A21, 0x007A22, 0x000000, 0xFFFFFF, + 0x007A24, 0x007A32, 0x000000, 0xFFFFFF, + 0x007A34, 0x007A36, 0x000000, 0xFFFFFF, + 0x007A38, 0x007A38, 0x000000, 0xFFFFFF, + 0x007A3A, 0x007A3A, 0x000000, 0xFFFFFF, + 0x007A3E, 0x007A3E, 0x000000, 0xFFFFFF, + 0x007A40, 0x007A45, 0x000000, 0xFFFFFF, + 0x007A47, 0x007A50, 0x000000, 0xFFFFFF, + 0x007A52, 0x007A56, 0x000000, 0xFFFFFF, + 0x007A58, 0x007A6F, 0x000000, 0xFFFFFF, + 0x007A71, 0x007A73, 0x000000, 0xFFFFFF, + 0x007A75, 0x007A75, 0x000000, 0xFFFFFF, + 0x007A7B, 0x007A7E, 0x000000, 0xFFFFFF, + 0x007A82, 0x007A82, 0x000000, 0xFFFFFF, + 0x007A85, 0x007A85, 0x000000, 0xFFFFFF, + 0x007A87, 0x007A87, 0x000000, 0xFFFFFF, + 0x007A89, 0x007A8C, 0x000000, 0xFFFFFF, + 0x007A8E, 0x007A90, 0x000000, 0xFFFFFF, + 0x007A93, 0x007A94, 0x000000, 0xFFFFFF, + 0x007A99, 0x007A9B, 0x000000, 0xFFFFFF, + 0x007A9E, 0x007A9E, 0x000000, 0xFFFFFF, + 0x007AA1, 0x007AA4, 0x000000, 0xFFFFFF, + 0x007AA7, 0x007AA7, 0x000000, 0xFFFFFF, + 0x007AA9, 0x007AAB, 0x000000, 0xFFFFFF, + 0x007AAE, 0x007AB2, 0x000000, 0xFFFFFF, + 0x007AB4, 0x007ABE, 0x000000, 0xFFFFFF, + 0x007AC0, 0x007ACA, 0x000000, 0xFFFFFF, + 0x007ACC, 0x007AD5, 0x000000, 0xFFFFFF, + 0x007AD7, 0x007AD8, 0x000000, 0xFFFFFF, + 0x007ADA, 0x007ADD, 0x000000, 0xFFFFFF, + 0x007AE1, 0x007AE2, 0x000000, 0xFFFFFF, + 0x007AE4, 0x007AE4, 0x000000, 0xFFFFFF, + 0x007AE7, 0x007AEC, 0x000000, 0xFFFFFF, + 0x007AEE, 0x007AEE, 0x000000, 0xFFFFFF, + 0x007AF0, 0x007AF8, 0x000000, 0xFFFFFF, + 0x007AFB, 0x007AFC, 0x000000, 0xFFFFFF, + 0x007AFE, 0x007AFE, 0x000000, 0xFFFFFF, + 0x007B00, 0x007B02, 0x000000, 0xFFFFFF, + 0x007B05, 0x007B05, 0x000000, 0xFFFFFF, + 0x007B07, 0x007B07, 0x000000, 0xFFFFFF, + 0x007B09, 0x007B09, 0x000000, 0xFFFFFF, + 0x007B0C, 0x007B0E, 0x000000, 0xFFFFFF, + 0x007B10, 0x007B10, 0x000000, 0xFFFFFF, + 0x007B12, 0x007B13, 0x000000, 0xFFFFFF, + 0x007B16, 0x007B18, 0x000000, 0xFFFFFF, + 0x007B1A, 0x007B1A, 0x000000, 0xFFFFFF, + 0x007B1C, 0x007B1D, 0x000000, 0xFFFFFF, + 0x007B1F, 0x007B1F, 0x000000, 0xFFFFFF, + 0x007B21, 0x007B23, 0x000000, 0xFFFFFF, + 0x007B27, 0x007B27, 0x000000, 0xFFFFFF, + 0x007B29, 0x007B29, 0x000000, 0xFFFFFF, + 0x007B2D, 0x007B2D, 0x000000, 0xFFFFFF, + 0x007B2F, 0x007B30, 0x000000, 0xFFFFFF, + 0x007B32, 0x007B32, 0x000000, 0xFFFFFF, + 0x007B34, 0x007B37, 0x000000, 0xFFFFFF, + 0x007B39, 0x007B39, 0x000000, 0xFFFFFF, + 0x007B3B, 0x007B3B, 0x000000, 0xFFFFFF, + 0x007B3D, 0x007B3D, 0x000000, 0xFFFFFF, + 0x007B3F, 0x007B44, 0x000000, 0xFFFFFF, + 0x007B46, 0x007B46, 0x000000, 0xFFFFFF, + 0x007B48, 0x007B48, 0x000000, 0xFFFFFF, + 0x007B4A, 0x007B4A, 0x000000, 0xFFFFFF, + 0x007B4D, 0x007B4E, 0x000000, 0xFFFFFF, + 0x007B53, 0x007B53, 0x000000, 0xFFFFFF, + 0x007B55, 0x007B55, 0x000000, 0xFFFFFF, + 0x007B57, 0x007B57, 0x000000, 0xFFFFFF, + 0x007B59, 0x007B59, 0x000000, 0xFFFFFF, + 0x007B5C, 0x007B5C, 0x000000, 0xFFFFFF, + 0x007B5E, 0x007B5F, 0x000000, 0xFFFFFF, + 0x007B61, 0x007B61, 0x000000, 0xFFFFFF, + 0x007B63, 0x007B6D, 0x000000, 0xFFFFFF, + 0x007B6F, 0x007B70, 0x000000, 0xFFFFFF, + 0x007B73, 0x007B74, 0x000000, 0xFFFFFF, + 0x007B76, 0x007B76, 0x000000, 0xFFFFFF, + 0x007B78, 0x007B78, 0x000000, 0xFFFFFF, + 0x007B7A, 0x007B7A, 0x000000, 0xFFFFFF, + 0x007B7C, 0x007B7D, 0x000000, 0xFFFFFF, + 0x007B7F, 0x007B7F, 0x000000, 0xFFFFFF, + 0x007B81, 0x007B84, 0x000000, 0xFFFFFF, + 0x007B86, 0x007B8C, 0x000000, 0xFFFFFF, + 0x007B8E, 0x007B8F, 0x000000, 0xFFFFFF, + 0x007B91, 0x007B93, 0x000000, 0xFFFFFF, + 0x007B96, 0x007B96, 0x000000, 0xFFFFFF, + 0x007B98, 0x007B9B, 0x000000, 0xFFFFFF, + 0x007B9E, 0x007BA0, 0x000000, 0xFFFFFF, + 0x007BA3, 0x007BA5, 0x000000, 0xFFFFFF, + 0x007BAE, 0x007BB0, 0x000000, 0xFFFFFF, + 0x007BB2, 0x007BB3, 0x000000, 0xFFFFFF, + 0x007BB5, 0x007BB7, 0x000000, 0xFFFFFF, + 0x007BB9, 0x007BC0, 0x000000, 0xFFFFFF, + 0x007BC2, 0x007BC5, 0x000000, 0xFFFFFF, + 0x007BC8, 0x007BCB, 0x000000, 0xFFFFFF, + 0x007BCD, 0x007BD0, 0x000000, 0xFFFFFF, + 0x007BD2, 0x007BD2, 0x000000, 0xFFFFFF, + 0x007BD4, 0x007BD8, 0x000000, 0xFFFFFF, + 0x007BDB, 0x007BDC, 0x000000, 0xFFFFFF, + 0x007BDE, 0x007BE0, 0x000000, 0xFFFFFF, + 0x007BE2, 0x007BE4, 0x000000, 0xFFFFFF, + 0x007BE7, 0x007BE9, 0x000000, 0xFFFFFF, + 0x007BEB, 0x007BED, 0x000000, 0xFFFFFF, + 0x007BEF, 0x007BF0, 0x000000, 0xFFFFFF, + 0x007BF2, 0x007BF6, 0x000000, 0xFFFFFF, + 0x007BF8, 0x007BFB, 0x000000, 0xFFFFFF, + 0x007BFD, 0x007BFD, 0x000000, 0xFFFFFF, + 0x007BFF, 0x007C06, 0x000000, 0xFFFFFF, + 0x007C08, 0x007C0A, 0x000000, 0xFFFFFF, + 0x007C0D, 0x007C0E, 0x000000, 0xFFFFFF, + 0x007C10, 0x007C15, 0x000000, 0xFFFFFF, + 0x007C17, 0x007C1E, 0x000000, 0xFFFFFF, + 0x007C20, 0x007C25, 0x000000, 0xFFFFFF, + 0x007C28, 0x007C29, 0x000000, 0xFFFFFF, + 0x007C2B, 0x007C37, 0x000000, 0xFFFFFF, + 0x007C39, 0x007C3E, 0x000000, 0xFFFFFF, + 0x007C42, 0x007C4C, 0x000000, 0xFFFFFF, + 0x007C4E, 0x007C72, 0x000000, 0xFFFFFF, + 0x007C75, 0x007C7A, 0x000000, 0xFFFFFF, + 0x007C7E, 0x007C88, 0x000000, 0xFFFFFF, + 0x007C8A, 0x007C90, 0x000000, 0xFFFFFF, + 0x007C93, 0x007C94, 0x000000, 0xFFFFFF, + 0x007C96, 0x007C96, 0x000000, 0xFFFFFF, + 0x007C99, 0x007C9B, 0x000000, 0xFFFFFF, + 0x007CA0, 0x007CA1, 0x000000, 0xFFFFFF, + 0x007CA3, 0x007CA3, 0x000000, 0xFFFFFF, + 0x007CA6, 0x007CA9, 0x000000, 0xFFFFFF, + 0x007CAB, 0x007CAD, 0x000000, 0xFFFFFF, + 0x007CAF, 0x007CB0, 0x000000, 0xFFFFFF, + 0x007CB4, 0x007CB8, 0x000000, 0xFFFFFF, + 0x007CBA, 0x007CBB, 0x000000, 0xFFFFFF, + 0x007CBF, 0x007CC0, 0x000000, 0xFFFFFF, + 0x007CC2, 0x007CC4, 0x000000, 0xFFFFFF, + 0x007CC6, 0x007CC6, 0x000000, 0xFFFFFF, + 0x007CC9, 0x007CC9, 0x000000, 0xFFFFFF, + 0x007CCB, 0x007CCB, 0x000000, 0xFFFFFF, + 0x007CCE, 0x007CD4, 0x000000, 0xFFFFFF, + 0x007CD8, 0x007CD8, 0x000000, 0xFFFFFF, + 0x007CDA, 0x007CDB, 0x000000, 0xFFFFFF, + 0x007CDD, 0x007CDE, 0x000000, 0xFFFFFF, + 0x007CE1, 0x007CE7, 0x000000, 0xFFFFFF, + 0x007CE9, 0x007CEE, 0x000000, 0xFFFFFF, + 0x007CF0, 0x007CF7, 0x000000, 0xFFFFFF, + 0x007CF9, 0x007CFA, 0x000000, 0xFFFFFF, + 0x007CFC, 0x007D09, 0x000000, 0xFFFFFF, + 0x007D0B, 0x007D1F, 0x000000, 0xFFFFFF, + 0x007D21, 0x007D21, 0x000000, 0xFFFFFF, + 0x007D23, 0x007D26, 0x000000, 0xFFFFFF, + 0x007D28, 0x007D2A, 0x000000, 0xFFFFFF, + 0x007D2C, 0x007D2E, 0x000000, 0xFFFFFF, + 0x007D30, 0x007D6D, 0x000000, 0xFFFFFF, + 0x007D6F, 0x007D76, 0x000000, 0xFFFFFF, + 0x007D78, 0x007DA5, 0x000000, 0xFFFFFF, + 0x007DA7, 0x007DAD, 0x000000, 0xFFFFFF, + 0x007DAF, 0x007E3A, 0x000000, 0xFFFFFF, + 0x007E3C, 0x007E40, 0x000000, 0xFFFFFF, + 0x007E42, 0x007E46, 0x000000, 0xFFFFFF, + 0x007E48, 0x007E81, 0x000000, 0xFFFFFF, + 0x007E83, 0x007E9A, 0x000000, 0xFFFFFF, + 0x007E9C, 0x007E9E, 0x000000, 0xFFFFFF, + 0x007EAE, 0x007EAE, 0x000000, 0xFFFFFF, + 0x007EB4, 0x007EB4, 0x000000, 0xFFFFFF, + 0x007EBB, 0x007EBC, 0x000000, 0xFFFFFF, + 0x007ED6, 0x007ED6, 0x000000, 0xFFFFFF, + 0x007EE4, 0x007EE4, 0x000000, 0xFFFFFF, + 0x007EEC, 0x007EEC, 0x000000, 0xFFFFFF, + 0x007EF9, 0x007EF9, 0x000000, 0xFFFFFF, + 0x007F0A, 0x007F0A, 0x000000, 0xFFFFFF, + 0x007F10, 0x007F10, 0x000000, 0xFFFFFF, + 0x007F1E, 0x007F1E, 0x000000, 0xFFFFFF, + 0x007F37, 0x007F37, 0x000000, 0xFFFFFF, + 0x007F39, 0x007F39, 0x000000, 0xFFFFFF, + 0x007F3B, 0x007F41, 0x000000, 0xFFFFFF, + 0x007F43, 0x007F43, 0x000000, 0xFFFFFF, + 0x007F46, 0x007F4F, 0x000000, 0xFFFFFF, + 0x007F52, 0x007F53, 0x000000, 0xFFFFFF, + 0x007F56, 0x007F56, 0x000000, 0xFFFFFF, + 0x007F59, 0x007F59, 0x000000, 0xFFFFFF, + 0x007F5B, 0x007F5E, 0x000000, 0xFFFFFF, + 0x007F60, 0x007F60, 0x000000, 0xFFFFFF, + 0x007F63, 0x007F67, 0x000000, 0xFFFFFF, + 0x007F6B, 0x007F6D, 0x000000, 0xFFFFFF, + 0x007F6F, 0x007F70, 0x000000, 0xFFFFFF, + 0x007F73, 0x007F73, 0x000000, 0xFFFFFF, + 0x007F75, 0x007F78, 0x000000, 0xFFFFFF, + 0x007F7A, 0x007F7D, 0x000000, 0xFFFFFF, + 0x007F7F, 0x007F80, 0x000000, 0xFFFFFF, + 0x007F82, 0x007F89, 0x000000, 0xFFFFFF, + 0x007F8B, 0x007F8B, 0x000000, 0xFFFFFF, + 0x007F8D, 0x007F8D, 0x000000, 0xFFFFFF, + 0x007F8F, 0x007F93, 0x000000, 0xFFFFFF, + 0x007F95, 0x007F99, 0x000000, 0xFFFFFF, + 0x007F9B, 0x007F9C, 0x000000, 0xFFFFFF, + 0x007FA0, 0x007FA0, 0x000000, 0xFFFFFF, + 0x007FA2, 0x007FA3, 0x000000, 0xFFFFFF, + 0x007FA5, 0x007FA6, 0x000000, 0xFFFFFF, + 0x007FA8, 0x007FAE, 0x000000, 0xFFFFFF, + 0x007FB1, 0x007FB1, 0x000000, 0xFFFFFF, + 0x007FB3, 0x007FB7, 0x000000, 0xFFFFFF, + 0x007FBA, 0x007FBB, 0x000000, 0xFFFFFF, + 0x007FBE, 0x007FBE, 0x000000, 0xFFFFFF, + 0x007FC0, 0x007FC0, 0x000000, 0xFFFFFF, + 0x007FC2, 0x007FC4, 0x000000, 0xFFFFFF, + 0x007FC6, 0x007FC9, 0x000000, 0xFFFFFF, + 0x007FCB, 0x007FCB, 0x000000, 0xFFFFFF, + 0x007FCD, 0x007FCD, 0x000000, 0xFFFFFF, + 0x007FCF, 0x007FD3, 0x000000, 0xFFFFFF, + 0x007FD6, 0x007FD7, 0x000000, 0xFFFFFF, + 0x007FD9, 0x007FDE, 0x000000, 0xFFFFFF, + 0x007FE2, 0x007FE4, 0x000000, 0xFFFFFF, + 0x007FE7, 0x007FE8, 0x000000, 0xFFFFFF, + 0x007FEA, 0x007FED, 0x000000, 0xFFFFFF, + 0x007FEF, 0x007FEF, 0x000000, 0xFFFFFF, + 0x007FF2, 0x007FF2, 0x000000, 0xFFFFFF, + 0x007FF4, 0x007FFA, 0x000000, 0xFFFFFF, + 0x007FFD, 0x007FFF, 0x000000, 0xFFFFFF, + 0x008002, 0x008002, 0x000000, 0xFFFFFF, + 0x008007, 0x00800A, 0x000000, 0xFFFFFF, + 0x00800E, 0x00800F, 0x000000, 0xFFFFFF, + 0x008011, 0x008011, 0x000000, 0xFFFFFF, + 0x008013, 0x008013, 0x000000, 0xFFFFFF, + 0x00801A, 0x00801B, 0x000000, 0xFFFFFF, + 0x00801D, 0x00801F, 0x000000, 0xFFFFFF, + 0x008021, 0x008021, 0x000000, 0xFFFFFF, + 0x008023, 0x008024, 0x000000, 0xFFFFFF, + 0x00802B, 0x008030, 0x000000, 0xFFFFFF, + 0x008032, 0x008032, 0x000000, 0xFFFFFF, + 0x008034, 0x008034, 0x000000, 0xFFFFFF, + 0x008039, 0x00803A, 0x000000, 0xFFFFFF, + 0x00803C, 0x00803C, 0x000000, 0xFFFFFF, + 0x00803E, 0x00803E, 0x000000, 0xFFFFFF, + 0x008040, 0x008041, 0x000000, 0xFFFFFF, + 0x008044, 0x008045, 0x000000, 0xFFFFFF, + 0x008047, 0x008049, 0x000000, 0xFFFFFF, + 0x00804E, 0x008051, 0x000000, 0xFFFFFF, + 0x008053, 0x008053, 0x000000, 0xFFFFFF, + 0x008055, 0x008057, 0x000000, 0xFFFFFF, + 0x008059, 0x008059, 0x000000, 0xFFFFFF, + 0x00805B, 0x008068, 0x000000, 0xFFFFFF, + 0x00806B, 0x008070, 0x000000, 0xFFFFFF, + 0x008072, 0x00807E, 0x000000, 0xFFFFFF, + 0x008081, 0x008082, 0x000000, 0xFFFFFF, + 0x008085, 0x008085, 0x000000, 0xFFFFFF, + 0x008088, 0x008088, 0x000000, 0xFFFFFF, + 0x00808A, 0x00808A, 0x000000, 0xFFFFFF, + 0x00808D, 0x008092, 0x000000, 0xFFFFFF, + 0x008094, 0x008095, 0x000000, 0xFFFFFF, + 0x008097, 0x008097, 0x000000, 0xFFFFFF, + 0x008099, 0x008099, 0x000000, 0xFFFFFF, + 0x00809E, 0x00809E, 0x000000, 0xFFFFFF, + 0x0080A3, 0x0080A3, 0x000000, 0xFFFFFF, + 0x0080A6, 0x0080A8, 0x000000, 0xFFFFFF, + 0x0080AC, 0x0080AC, 0x000000, 0xFFFFFF, + 0x0080B0, 0x0080B0, 0x000000, 0xFFFFFF, + 0x0080B3, 0x0080B3, 0x000000, 0xFFFFFF, + 0x0080B5, 0x0080B6, 0x000000, 0xFFFFFF, + 0x0080B8, 0x0080B9, 0x000000, 0xFFFFFF, + 0x0080BB, 0x0080BB, 0x000000, 0xFFFFFF, + 0x0080C5, 0x0080C5, 0x000000, 0xFFFFFF, + 0x0080C7, 0x0080CB, 0x000000, 0xFFFFFF, + 0x0080CF, 0x0080D5, 0x000000, 0xFFFFFF, + 0x0080D8, 0x0080D8, 0x000000, 0xFFFFFF, + 0x0080DF, 0x0080E0, 0x000000, 0xFFFFFF, + 0x0080E2, 0x0080E3, 0x000000, 0xFFFFFF, + 0x0080E6, 0x0080E6, 0x000000, 0xFFFFFF, + 0x0080EE, 0x0080EE, 0x000000, 0xFFFFFF, + 0x0080F5, 0x0080F5, 0x000000, 0xFFFFFF, + 0x0080F7, 0x0080F7, 0x000000, 0xFFFFFF, + 0x0080F9, 0x0080F9, 0x000000, 0xFFFFFF, + 0x0080FB, 0x0080FB, 0x000000, 0xFFFFFF, + 0x0080FE, 0x008101, 0x000000, 0xFFFFFF, + 0x008103, 0x008105, 0x000000, 0xFFFFFF, + 0x008107, 0x008108, 0x000000, 0xFFFFFF, + 0x00810B, 0x00810C, 0x000000, 0xFFFFFF, + 0x008115, 0x008115, 0x000000, 0xFFFFFF, + 0x008117, 0x008117, 0x000000, 0xFFFFFF, + 0x008119, 0x008119, 0x000000, 0xFFFFFF, + 0x00811B, 0x00811D, 0x000000, 0xFFFFFF, + 0x00811F, 0x00812B, 0x000000, 0xFFFFFF, + 0x00812D, 0x00812E, 0x000000, 0xFFFFFF, + 0x008130, 0x008130, 0x000000, 0xFFFFFF, + 0x008133, 0x008135, 0x000000, 0xFFFFFF, + 0x008137, 0x008137, 0x000000, 0xFFFFFF, + 0x008139, 0x00813D, 0x000000, 0xFFFFFF, + 0x00813F, 0x008145, 0x000000, 0xFFFFFF, + 0x008147, 0x008147, 0x000000, 0xFFFFFF, + 0x008149, 0x008149, 0x000000, 0xFFFFFF, + 0x00814D, 0x00814F, 0x000000, 0xFFFFFF, + 0x008152, 0x008152, 0x000000, 0xFFFFFF, + 0x008156, 0x008158, 0x000000, 0xFFFFFF, + 0x00815B, 0x00815F, 0x000000, 0xFFFFFF, + 0x008161, 0x008164, 0x000000, 0xFFFFFF, + 0x008166, 0x008166, 0x000000, 0xFFFFFF, + 0x008168, 0x008168, 0x000000, 0xFFFFFF, + 0x00816A, 0x00816C, 0x000000, 0xFFFFFF, + 0x00816F, 0x00816F, 0x000000, 0xFFFFFF, + 0x008172, 0x008173, 0x000000, 0xFFFFFF, + 0x008175, 0x008178, 0x000000, 0xFFFFFF, + 0x008181, 0x008181, 0x000000, 0xFFFFFF, + 0x008183, 0x008187, 0x000000, 0xFFFFFF, + 0x008189, 0x008189, 0x000000, 0xFFFFFF, + 0x00818B, 0x00818E, 0x000000, 0xFFFFFF, + 0x008190, 0x008190, 0x000000, 0xFFFFFF, + 0x008192, 0x008197, 0x000000, 0xFFFFFF, + 0x008199, 0x00819A, 0x000000, 0xFFFFFF, + 0x00819E, 0x0081A2, 0x000000, 0xFFFFFF, + 0x0081A4, 0x0081A5, 0x000000, 0xFFFFFF, + 0x0081A7, 0x0081A7, 0x000000, 0xFFFFFF, + 0x0081A9, 0x0081A9, 0x000000, 0xFFFFFF, + 0x0081AB, 0x0081B2, 0x000000, 0xFFFFFF, + 0x0081B4, 0x0081B9, 0x000000, 0xFFFFFF, + 0x0081BC, 0x0081BF, 0x000000, 0xFFFFFF, + 0x0081C4, 0x0081C5, 0x000000, 0xFFFFFF, + 0x0081C7, 0x0081C9, 0x000000, 0xFFFFFF, + 0x0081CB, 0x0081CB, 0x000000, 0xFFFFFF, + 0x0081CD, 0x0081E2, 0x000000, 0xFFFFFF, + 0x0081E4, 0x0081E6, 0x000000, 0xFFFFFF, + 0x0081E8, 0x0081E9, 0x000000, 0xFFFFFF, + 0x0081EB, 0x0081EB, 0x000000, 0xFFFFFF, + 0x0081EE, 0x0081F2, 0x000000, 0xFFFFFF, + 0x0081F5, 0x0081FA, 0x000000, 0xFFFFFF, + 0x0081FD, 0x0081FD, 0x000000, 0xFFFFFF, + 0x0081FF, 0x0081FF, 0x000000, 0xFFFFFF, + 0x008203, 0x008203, 0x000000, 0xFFFFFF, + 0x008207, 0x00820B, 0x000000, 0xFFFFFF, + 0x00820E, 0x00820F, 0x000000, 0xFFFFFF, + 0x008211, 0x008211, 0x000000, 0xFFFFFF, + 0x008213, 0x008213, 0x000000, 0xFFFFFF, + 0x008215, 0x00821A, 0x000000, 0xFFFFFF, + 0x00821D, 0x00821D, 0x000000, 0xFFFFFF, + 0x008220, 0x008220, 0x000000, 0xFFFFFF, + 0x008224, 0x008227, 0x000000, 0xFFFFFF, + 0x008229, 0x008229, 0x000000, 0xFFFFFF, + 0x00822E, 0x00822E, 0x000000, 0xFFFFFF, + 0x008232, 0x008232, 0x000000, 0xFFFFFF, + 0x00823A, 0x00823A, 0x000000, 0xFFFFFF, + 0x00823C, 0x00823D, 0x000000, 0xFFFFFF, + 0x00823F, 0x008243, 0x000000, 0xFFFFFF, + 0x008245, 0x008246, 0x000000, 0xFFFFFF, + 0x008248, 0x008248, 0x000000, 0xFFFFFF, + 0x00824A, 0x00824A, 0x000000, 0xFFFFFF, + 0x00824C, 0x00824E, 0x000000, 0xFFFFFF, + 0x008250, 0x008257, 0x000000, 0xFFFFFF, + 0x008259, 0x008259, 0x000000, 0xFFFFFF, + 0x00825B, 0x00825E, 0x000000, 0xFFFFFF, + 0x008260, 0x008267, 0x000000, 0xFFFFFF, + 0x008269, 0x00826D, 0x000000, 0xFFFFFF, + 0x008271, 0x008271, 0x000000, 0xFFFFFF, + 0x008275, 0x008278, 0x000000, 0xFFFFFF, + 0x00827B, 0x00827C, 0x000000, 0xFFFFFF, + 0x008280, 0x008281, 0x000000, 0xFFFFFF, + 0x008283, 0x008283, 0x000000, 0xFFFFFF, + 0x008285, 0x008287, 0x000000, 0xFFFFFF, + 0x008289, 0x008289, 0x000000, 0xFFFFFF, + 0x00828C, 0x00828C, 0x000000, 0xFFFFFF, + 0x008290, 0x008290, 0x000000, 0xFFFFFF, + 0x008293, 0x008296, 0x000000, 0xFFFFFF, + 0x00829A, 0x00829B, 0x000000, 0xFFFFFF, + 0x00829E, 0x00829E, 0x000000, 0xFFFFFF, + 0x0082A0, 0x0082A0, 0x000000, 0xFFFFFF, + 0x0082A2, 0x0082A3, 0x000000, 0xFFFFFF, + 0x0082A7, 0x0082A7, 0x000000, 0xFFFFFF, + 0x0082B2, 0x0082B2, 0x000000, 0xFFFFFF, + 0x0082B5, 0x0082B6, 0x000000, 0xFFFFFF, + 0x0082BA, 0x0082BC, 0x000000, 0xFFFFFF, + 0x0082BF, 0x0082C0, 0x000000, 0xFFFFFF, + 0x0082C2, 0x0082C3, 0x000000, 0xFFFFFF, + 0x0082C5, 0x0082C6, 0x000000, 0xFFFFFF, + 0x0082C9, 0x0082C9, 0x000000, 0xFFFFFF, + 0x0082D0, 0x0082D0, 0x000000, 0xFFFFFF, + 0x0082D6, 0x0082D6, 0x000000, 0xFFFFFF, + 0x0082D9, 0x0082DA, 0x000000, 0xFFFFFF, + 0x0082DD, 0x0082DD, 0x000000, 0xFFFFFF, + 0x0082E2, 0x0082E2, 0x000000, 0xFFFFFF, + 0x0082E7, 0x0082EA, 0x000000, 0xFFFFFF, + 0x0082EC, 0x0082EE, 0x000000, 0xFFFFFF, + 0x0082F0, 0x0082F0, 0x000000, 0xFFFFFF, + 0x0082F2, 0x0082F3, 0x000000, 0xFFFFFF, + 0x0082F5, 0x0082F6, 0x000000, 0xFFFFFF, + 0x0082F8, 0x0082F8, 0x000000, 0xFFFFFF, + 0x0082FA, 0x0082FA, 0x000000, 0xFFFFFF, + 0x0082FC, 0x008300, 0x000000, 0xFFFFFF, + 0x00830A, 0x00830B, 0x000000, 0xFFFFFF, + 0x00830D, 0x00830D, 0x000000, 0xFFFFFF, + 0x008310, 0x008310, 0x000000, 0xFFFFFF, + 0x008312, 0x008313, 0x000000, 0xFFFFFF, + 0x008316, 0x008316, 0x000000, 0xFFFFFF, + 0x008318, 0x008319, 0x000000, 0xFFFFFF, + 0x00831D, 0x008326, 0x000000, 0xFFFFFF, + 0x008329, 0x00832A, 0x000000, 0xFFFFFF, + 0x00832E, 0x00832E, 0x000000, 0xFFFFFF, + 0x008330, 0x008330, 0x000000, 0xFFFFFF, + 0x008332, 0x008332, 0x000000, 0xFFFFFF, + 0x008337, 0x008337, 0x000000, 0xFFFFFF, + 0x00833B, 0x00833B, 0x000000, 0xFFFFFF, + 0x00833D, 0x00833F, 0x000000, 0xFFFFFF, + 0x008341, 0x008342, 0x000000, 0xFFFFFF, + 0x008344, 0x008345, 0x000000, 0xFFFFFF, + 0x008348, 0x008348, 0x000000, 0xFFFFFF, + 0x00834A, 0x00834E, 0x000000, 0xFFFFFF, + 0x008353, 0x008353, 0x000000, 0xFFFFFF, + 0x008355, 0x008359, 0x000000, 0xFFFFFF, + 0x00835D, 0x00835D, 0x000000, 0xFFFFFF, + 0x008362, 0x008362, 0x000000, 0xFFFFFF, + 0x008370, 0x008376, 0x000000, 0xFFFFFF, + 0x008379, 0x00837A, 0x000000, 0xFFFFFF, + 0x00837E, 0x008384, 0x000000, 0xFFFFFF, + 0x008387, 0x008388, 0x000000, 0xFFFFFF, + 0x00838A, 0x00838D, 0x000000, 0xFFFFFF, + 0x00838F, 0x008391, 0x000000, 0xFFFFFF, + 0x008394, 0x008397, 0x000000, 0xFFFFFF, + 0x008399, 0x00839A, 0x000000, 0xFFFFFF, + 0x00839D, 0x00839D, 0x000000, 0xFFFFFF, + 0x00839F, 0x00839F, 0x000000, 0xFFFFFF, + 0x0083A1, 0x0083A7, 0x000000, 0xFFFFFF, + 0x0083AC, 0x0083AF, 0x000000, 0xFFFFFF, + 0x0083B5, 0x0083B5, 0x000000, 0xFFFFFF, + 0x0083BB, 0x0083BB, 0x000000, 0xFFFFFF, + 0x0083BE, 0x0083BF, 0x000000, 0xFFFFFF, + 0x0083C2, 0x0083C4, 0x000000, 0xFFFFFF, + 0x0083C6, 0x0083C6, 0x000000, 0xFFFFFF, + 0x0083C8, 0x0083C9, 0x000000, 0xFFFFFF, + 0x0083CB, 0x0083CB, 0x000000, 0xFFFFFF, + 0x0083CD, 0x0083CE, 0x000000, 0xFFFFFF, + 0x0083D0, 0x0083D3, 0x000000, 0xFFFFFF, + 0x0083D5, 0x0083D5, 0x000000, 0xFFFFFF, + 0x0083D7, 0x0083D7, 0x000000, 0xFFFFFF, + 0x0083D9, 0x0083DB, 0x000000, 0xFFFFFF, + 0x0083DE, 0x0083DE, 0x000000, 0xFFFFFF, + 0x0083E2, 0x0083E4, 0x000000, 0xFFFFFF, + 0x0083E6, 0x0083E8, 0x000000, 0xFFFFFF, + 0x0083EB, 0x0083EF, 0x000000, 0xFFFFFF, + 0x0083F3, 0x0083F7, 0x000000, 0xFFFFFF, + 0x0083FA, 0x0083FC, 0x000000, 0xFFFFFF, + 0x0083FE, 0x008400, 0x000000, 0xFFFFFF, + 0x008402, 0x008402, 0x000000, 0xFFFFFF, + 0x008405, 0x008405, 0x000000, 0xFFFFFF, + 0x008407, 0x00840A, 0x000000, 0xFFFFFF, + 0x008410, 0x008410, 0x000000, 0xFFFFFF, + 0x008412, 0x008417, 0x000000, 0xFFFFFF, + 0x008419, 0x00841B, 0x000000, 0xFFFFFF, + 0x00841E, 0x008423, 0x000000, 0xFFFFFF, + 0x008429, 0x008430, 0x000000, 0xFFFFFF, + 0x008432, 0x008437, 0x000000, 0xFFFFFF, + 0x008439, 0x00843B, 0x000000, 0xFFFFFF, + 0x00843E, 0x008445, 0x000000, 0xFFFFFF, + 0x008447, 0x008450, 0x000000, 0xFFFFFF, + 0x008452, 0x008456, 0x000000, 0xFFFFFF, + 0x008458, 0x008458, 0x000000, 0xFFFFFF, + 0x00845D, 0x008460, 0x000000, 0xFFFFFF, + 0x008462, 0x008462, 0x000000, 0xFFFFFF, + 0x008464, 0x008468, 0x000000, 0xFFFFFF, + 0x00846A, 0x00846A, 0x000000, 0xFFFFFF, + 0x00846E, 0x008470, 0x000000, 0xFFFFFF, + 0x008472, 0x008472, 0x000000, 0xFFFFFF, + 0x008474, 0x008474, 0x000000, 0xFFFFFF, + 0x008477, 0x008477, 0x000000, 0xFFFFFF, + 0x008479, 0x008479, 0x000000, 0xFFFFFF, + 0x00847B, 0x008481, 0x000000, 0xFFFFFF, + 0x008483, 0x008486, 0x000000, 0xFFFFFF, + 0x00848A, 0x00848A, 0x000000, 0xFFFFFF, + 0x00848D, 0x00848D, 0x000000, 0xFFFFFF, + 0x00848F, 0x008496, 0x000000, 0xFFFFFF, + 0x008498, 0x008498, 0x000000, 0xFFFFFF, + 0x00849A, 0x00849B, 0x000000, 0xFFFFFF, + 0x00849D, 0x0084A0, 0x000000, 0xFFFFFF, + 0x0084A2, 0x0084AE, 0x000000, 0xFFFFFF, + 0x0084B0, 0x0084B1, 0x000000, 0xFFFFFF, + 0x0084B3, 0x0084B3, 0x000000, 0xFFFFFF, + 0x0084B5, 0x0084B7, 0x000000, 0xFFFFFF, + 0x0084BB, 0x0084BC, 0x000000, 0xFFFFFF, + 0x0084BE, 0x0084BE, 0x000000, 0xFFFFFF, + 0x0084C0, 0x0084C0, 0x000000, 0xFFFFFF, + 0x0084C2, 0x0084C3, 0x000000, 0xFFFFFF, + 0x0084C5, 0x0084C8, 0x000000, 0xFFFFFF, + 0x0084CB, 0x0084CC, 0x000000, 0xFFFFFF, + 0x0084CE, 0x0084CF, 0x000000, 0xFFFFFF, + 0x0084D2, 0x0084D2, 0x000000, 0xFFFFFF, + 0x0084D4, 0x0084D5, 0x000000, 0xFFFFFF, + 0x0084D7, 0x0084DC, 0x000000, 0xFFFFFF, + 0x0084DE, 0x0084DE, 0x000000, 0xFFFFFF, + 0x0084E1, 0x0084E2, 0x000000, 0xFFFFFF, + 0x0084E4, 0x0084E4, 0x000000, 0xFFFFFF, + 0x0084E7, 0x0084EB, 0x000000, 0xFFFFFF, + 0x0084ED, 0x0084EF, 0x000000, 0xFFFFFF, + 0x0084F1, 0x0084FB, 0x000000, 0xFFFFFF, + 0x0084FD, 0x0084FE, 0x000000, 0xFFFFFF, + 0x008500, 0x00850B, 0x000000, 0xFFFFFF, + 0x00850D, 0x008510, 0x000000, 0xFFFFFF, + 0x008512, 0x008512, 0x000000, 0xFFFFFF, + 0x008514, 0x008516, 0x000000, 0xFFFFFF, + 0x008518, 0x008519, 0x000000, 0xFFFFFF, + 0x00851B, 0x00851E, 0x000000, 0xFFFFFF, + 0x008520, 0x008520, 0x000000, 0xFFFFFF, + 0x008522, 0x00852A, 0x000000, 0xFFFFFF, + 0x00852D, 0x008536, 0x000000, 0xFFFFFF, + 0x00853E, 0x008542, 0x000000, 0xFFFFFF, + 0x008544, 0x008547, 0x000000, 0xFFFFFF, + 0x00854B, 0x008555, 0x000000, 0xFFFFFF, + 0x008557, 0x008558, 0x000000, 0xFFFFFF, + 0x00855A, 0x00855D, 0x000000, 0xFFFFFF, + 0x00855F, 0x008563, 0x000000, 0xFFFFFF, + 0x008565, 0x008567, 0x000000, 0xFFFFFF, + 0x008569, 0x008571, 0x000000, 0xFFFFFF, + 0x008573, 0x008573, 0x000000, 0xFFFFFF, + 0x008575, 0x008578, 0x000000, 0xFFFFFF, + 0x00857C, 0x00857D, 0x000000, 0xFFFFFF, + 0x00857F, 0x008583, 0x000000, 0xFFFFFF, + 0x008586, 0x008586, 0x000000, 0xFFFFFF, + 0x008588, 0x00858E, 0x000000, 0xFFFFFF, + 0x008590, 0x00859A, 0x000000, 0xFFFFFF, + 0x00859D, 0x0085A3, 0x000000, 0xFFFFFF, + 0x0085A5, 0x0085A7, 0x000000, 0xFFFFFF, + 0x0085A9, 0x0085A9, 0x000000, 0xFFFFFF, + 0x0085AB, 0x0085AD, 0x000000, 0xFFFFFF, + 0x0085B1, 0x0085B6, 0x000000, 0xFFFFFF, + 0x0085B8, 0x0085B8, 0x000000, 0xFFFFFF, + 0x0085BA, 0x0085C0, 0x000000, 0xFFFFFF, + 0x0085C2, 0x0085C8, 0x000000, 0xFFFFFF, + 0x0085CA, 0x0085CE, 0x000000, 0xFFFFFF, + 0x0085D1, 0x0085D2, 0x000000, 0xFFFFFF, + 0x0085D4, 0x0085D4, 0x000000, 0xFFFFFF, + 0x0085D6, 0x0085DB, 0x000000, 0xFFFFFF, + 0x0085DD, 0x0085E3, 0x000000, 0xFFFFFF, + 0x0085E5, 0x0085E8, 0x000000, 0xFFFFFF, + 0x0085EA, 0x0085FA, 0x000000, 0xFFFFFF, + 0x0085FC, 0x0085FE, 0x000000, 0xFFFFFF, + 0x008600, 0x008604, 0x000000, 0xFFFFFF, + 0x008606, 0x008610, 0x000000, 0xFFFFFF, + 0x008612, 0x008615, 0x000000, 0xFFFFFF, + 0x008617, 0x008626, 0x000000, 0xFFFFFF, + 0x008628, 0x008628, 0x000000, 0xFFFFFF, + 0x00862A, 0x008637, 0x000000, 0xFFFFFF, + 0x008639, 0x00863B, 0x000000, 0xFFFFFF, + 0x00863D, 0x00864C, 0x000000, 0xFFFFFF, + 0x008652, 0x008653, 0x000000, 0xFFFFFF, + 0x008655, 0x008659, 0x000000, 0xFFFFFF, + 0x00865B, 0x00865D, 0x000000, 0xFFFFFF, + 0x00865F, 0x008661, 0x000000, 0xFFFFFF, + 0x008663, 0x00866A, 0x000000, 0xFFFFFF, + 0x00866D, 0x00866D, 0x000000, 0xFFFFFF, + 0x00866F, 0x008670, 0x000000, 0xFFFFFF, + 0x008672, 0x008678, 0x000000, 0xFFFFFF, + 0x008683, 0x008689, 0x000000, 0xFFFFFF, + 0x00868E, 0x008692, 0x000000, 0xFFFFFF, + 0x008694, 0x008694, 0x000000, 0xFFFFFF, + 0x008696, 0x00869B, 0x000000, 0xFFFFFF, + 0x00869E, 0x0086A2, 0x000000, 0xFFFFFF, + 0x0086A5, 0x0086A6, 0x000000, 0xFFFFFF, + 0x0086AB, 0x0086AB, 0x000000, 0xFFFFFF, + 0x0086AD, 0x0086AE, 0x000000, 0xFFFFFF, + 0x0086B2, 0x0086B3, 0x000000, 0xFFFFFF, + 0x0086B7, 0x0086B9, 0x000000, 0xFFFFFF, + 0x0086BB, 0x0086BF, 0x000000, 0xFFFFFF, + 0x0086C1, 0x0086C3, 0x000000, 0xFFFFFF, + 0x0086C5, 0x0086C5, 0x000000, 0xFFFFFF, + 0x0086C8, 0x0086C8, 0x000000, 0xFFFFFF, + 0x0086CC, 0x0086CD, 0x000000, 0xFFFFFF, + 0x0086D2, 0x0086D3, 0x000000, 0xFFFFFF, + 0x0086D5, 0x0086D7, 0x000000, 0xFFFFFF, + 0x0086DA, 0x0086DA, 0x000000, 0xFFFFFF, + 0x0086DC, 0x0086DD, 0x000000, 0xFFFFFF, + 0x0086E0, 0x0086E3, 0x000000, 0xFFFFFF, + 0x0086E5, 0x0086E8, 0x000000, 0xFFFFFF, + 0x0086EA, 0x0086EC, 0x000000, 0xFFFFFF, + 0x0086EF, 0x0086EF, 0x000000, 0xFFFFFF, + 0x0086F5, 0x0086F7, 0x000000, 0xFFFFFF, + 0x0086FA, 0x0086FD, 0x000000, 0xFFFFFF, + 0x0086FF, 0x0086FF, 0x000000, 0xFFFFFF, + 0x008701, 0x008701, 0x000000, 0xFFFFFF, + 0x008704, 0x008706, 0x000000, 0xFFFFFF, + 0x00870B, 0x00870C, 0x000000, 0xFFFFFF, + 0x00870E, 0x008711, 0x000000, 0xFFFFFF, + 0x008714, 0x008714, 0x000000, 0xFFFFFF, + 0x008716, 0x008716, 0x000000, 0xFFFFFF, + 0x008719, 0x008719, 0x000000, 0xFFFFFF, + 0x00871B, 0x00871B, 0x000000, 0xFFFFFF, + 0x00871D, 0x00871D, 0x000000, 0xFFFFFF, + 0x00871F, 0x008720, 0x000000, 0xFFFFFF, + 0x008724, 0x008724, 0x000000, 0xFFFFFF, + 0x008726, 0x008728, 0x000000, 0xFFFFFF, + 0x00872A, 0x00872D, 0x000000, 0xFFFFFF, + 0x00872F, 0x008730, 0x000000, 0xFFFFFF, + 0x008732, 0x008733, 0x000000, 0xFFFFFF, + 0x008735, 0x008736, 0x000000, 0xFFFFFF, + 0x008738, 0x00873A, 0x000000, 0xFFFFFF, + 0x00873C, 0x00873D, 0x000000, 0xFFFFFF, + 0x008740, 0x008746, 0x000000, 0xFFFFFF, + 0x00874A, 0x00874B, 0x000000, 0xFFFFFF, + 0x00874D, 0x00874D, 0x000000, 0xFFFFFF, + 0x00874F, 0x008752, 0x000000, 0xFFFFFF, + 0x008754, 0x008756, 0x000000, 0xFFFFFF, + 0x008758, 0x008758, 0x000000, 0xFFFFFF, + 0x00875A, 0x00875F, 0x000000, 0xFFFFFF, + 0x008761, 0x008762, 0x000000, 0xFFFFFF, + 0x008766, 0x00876D, 0x000000, 0xFFFFFF, + 0x00876F, 0x00876F, 0x000000, 0xFFFFFF, + 0x008771, 0x008773, 0x000000, 0xFFFFFF, + 0x008775, 0x008775, 0x000000, 0xFFFFFF, + 0x008777, 0x00877A, 0x000000, 0xFFFFFF, + 0x00877F, 0x008781, 0x000000, 0xFFFFFF, + 0x008784, 0x008784, 0x000000, 0xFFFFFF, + 0x008786, 0x008787, 0x000000, 0xFFFFFF, + 0x008789, 0x00878A, 0x000000, 0xFFFFFF, + 0x00878C, 0x00878C, 0x000000, 0xFFFFFF, + 0x00878E, 0x008792, 0x000000, 0xFFFFFF, + 0x008794, 0x008796, 0x000000, 0xFFFFFF, + 0x008798, 0x00879E, 0x000000, 0xFFFFFF, + 0x0087A0, 0x0087A7, 0x000000, 0xFFFFFF, + 0x0087A9, 0x0087AA, 0x000000, 0xFFFFFF, + 0x0087AE, 0x0087AE, 0x000000, 0xFFFFFF, + 0x0087B0, 0x0087B2, 0x000000, 0xFFFFFF, + 0x0087B4, 0x0087B4, 0x000000, 0xFFFFFF, + 0x0087B6, 0x0087B9, 0x000000, 0xFFFFFF, + 0x0087BB, 0x0087BC, 0x000000, 0xFFFFFF, + 0x0087BE, 0x0087BF, 0x000000, 0xFFFFFF, + 0x0087C1, 0x0087C5, 0x000000, 0xFFFFFF, + 0x0087C7, 0x0087C9, 0x000000, 0xFFFFFF, + 0x0087CC, 0x0087D0, 0x000000, 0xFFFFFF, + 0x0087D4, 0x0087DA, 0x000000, 0xFFFFFF, + 0x0087DC, 0x0087DF, 0x000000, 0xFFFFFF, + 0x0087E1, 0x0087E4, 0x000000, 0xFFFFFF, + 0x0087E6, 0x0087E9, 0x000000, 0xFFFFFF, + 0x0087EB, 0x0087ED, 0x000000, 0xFFFFFF, + 0x0087EF, 0x0087F8, 0x000000, 0xFFFFFF, + 0x0087FA, 0x0087FD, 0x000000, 0xFFFFFF, + 0x0087FF, 0x008802, 0x000000, 0xFFFFFF, + 0x008804, 0x008809, 0x000000, 0xFFFFFF, + 0x00880B, 0x008812, 0x000000, 0xFFFFFF, + 0x008814, 0x008814, 0x000000, 0xFFFFFF, + 0x008817, 0x00881A, 0x000000, 0xFFFFFF, + 0x00881C, 0x008820, 0x000000, 0xFFFFFF, + 0x008823, 0x008831, 0x000000, 0xFFFFFF, + 0x008833, 0x008838, 0x000000, 0xFFFFFF, + 0x00883A, 0x00883B, 0x000000, 0xFFFFFF, + 0x00883D, 0x00883F, 0x000000, 0xFFFFFF, + 0x008841, 0x008843, 0x000000, 0xFFFFFF, + 0x008846, 0x00884B, 0x000000, 0xFFFFFF, + 0x00884E, 0x008853, 0x000000, 0xFFFFFF, + 0x008855, 0x008856, 0x000000, 0xFFFFFF, + 0x008858, 0x008858, 0x000000, 0xFFFFFF, + 0x00885A, 0x008860, 0x000000, 0xFFFFFF, + 0x008866, 0x008867, 0x000000, 0xFFFFFF, + 0x00886A, 0x00886A, 0x000000, 0xFFFFFF, + 0x00886D, 0x00886D, 0x000000, 0xFFFFFF, + 0x00886F, 0x00886F, 0x000000, 0xFFFFFF, + 0x008871, 0x008871, 0x000000, 0xFFFFFF, + 0x008873, 0x008876, 0x000000, 0xFFFFFF, + 0x008878, 0x00887C, 0x000000, 0xFFFFFF, + 0x008880, 0x008880, 0x000000, 0xFFFFFF, + 0x008883, 0x008883, 0x000000, 0xFFFFFF, + 0x008886, 0x008887, 0x000000, 0xFFFFFF, + 0x008889, 0x00888A, 0x000000, 0xFFFFFF, + 0x00888C, 0x00888C, 0x000000, 0xFFFFFF, + 0x00888E, 0x008891, 0x000000, 0xFFFFFF, + 0x008893, 0x008895, 0x000000, 0xFFFFFF, + 0x008897, 0x00889B, 0x000000, 0xFFFFFF, + 0x00889D, 0x0088A1, 0x000000, 0xFFFFFF, + 0x0088A3, 0x0088A3, 0x000000, 0xFFFFFF, + 0x0088A5, 0x0088AA, 0x000000, 0xFFFFFF, + 0x0088AC, 0x0088AC, 0x000000, 0xFFFFFF, + 0x0088AE, 0x0088B0, 0x000000, 0xFFFFFF, + 0x0088B2, 0x0088B6, 0x000000, 0xFFFFFF, + 0x0088B8, 0x0088BB, 0x000000, 0xFFFFFF, + 0x0088BD, 0x0088C0, 0x000000, 0xFFFFFF, + 0x0088C3, 0x0088C4, 0x000000, 0xFFFFFF, + 0x0088C7, 0x0088C8, 0x000000, 0xFFFFFF, + 0x0088CA, 0x0088CD, 0x000000, 0xFFFFFF, + 0x0088CF, 0x0088D1, 0x000000, 0xFFFFFF, + 0x0088D3, 0x0088D3, 0x000000, 0xFFFFFF, + 0x0088D6, 0x0088D7, 0x000000, 0xFFFFFF, + 0x0088DA, 0x0088DE, 0x000000, 0xFFFFFF, + 0x0088E0, 0x0088E1, 0x000000, 0xFFFFFF, + 0x0088E6, 0x0088E7, 0x000000, 0xFFFFFF, + 0x0088E9, 0x0088EF, 0x000000, 0xFFFFFF, + 0x0088F2, 0x0088F2, 0x000000, 0xFFFFFF, + 0x0088F5, 0x0088F7, 0x000000, 0xFFFFFF, + 0x0088FA, 0x0088FB, 0x000000, 0xFFFFFF, + 0x0088FD, 0x0088FD, 0x000000, 0xFFFFFF, + 0x0088FF, 0x008901, 0x000000, 0xFFFFFF, + 0x008903, 0x008909, 0x000000, 0xFFFFFF, + 0x00890B, 0x00890F, 0x000000, 0xFFFFFF, + 0x008911, 0x008911, 0x000000, 0xFFFFFF, + 0x008914, 0x008918, 0x000000, 0xFFFFFF, + 0x00891C, 0x008920, 0x000000, 0xFFFFFF, + 0x008922, 0x008924, 0x000000, 0xFFFFFF, + 0x008926, 0x008929, 0x000000, 0xFFFFFF, + 0x00892C, 0x00892F, 0x000000, 0xFFFFFF, + 0x008931, 0x008933, 0x000000, 0xFFFFFF, + 0x008935, 0x008935, 0x000000, 0xFFFFFF, + 0x008937, 0x008940, 0x000000, 0xFFFFFF, + 0x008942, 0x008943, 0x000000, 0xFFFFFF, + 0x008945, 0x00895D, 0x000000, 0xFFFFFF, + 0x008960, 0x008965, 0x000000, 0xFFFFFF, + 0x008967, 0x00897A, 0x000000, 0xFFFFFF, + 0x00897C, 0x00897E, 0x000000, 0xFFFFFF, + 0x008980, 0x008980, 0x000000, 0xFFFFFF, + 0x008982, 0x008982, 0x000000, 0xFFFFFF, + 0x008984, 0x008985, 0x000000, 0xFFFFFF, + 0x008987, 0x0089C0, 0x000000, 0xFFFFFF, + 0x0089C3, 0x0089C3, 0x000000, 0xFFFFFF, + 0x0089CD, 0x0089CD, 0x000000, 0xFFFFFF, + 0x0089D3, 0x0089D5, 0x000000, 0xFFFFFF, + 0x0089D7, 0x0089D9, 0x000000, 0xFFFFFF, + 0x0089DB, 0x0089DB, 0x000000, 0xFFFFFF, + 0x0089DD, 0x0089DD, 0x000000, 0xFFFFFF, + 0x0089DF, 0x0089E2, 0x000000, 0xFFFFFF, + 0x0089E4, 0x0089E4, 0x000000, 0xFFFFFF, + 0x0089E7, 0x0089EA, 0x000000, 0xFFFFFF, + 0x0089EC, 0x0089EE, 0x000000, 0xFFFFFF, + 0x0089F0, 0x0089F2, 0x000000, 0xFFFFFF, + 0x0089F4, 0x0089FF, 0x000000, 0xFFFFFF, + 0x008A01, 0x008A06, 0x000000, 0xFFFFFF, + 0x008A08, 0x008A3D, 0x000000, 0xFFFFFF, + 0x008A3F, 0x008A47, 0x000000, 0xFFFFFF, + 0x008A49, 0x008A78, 0x000000, 0xFFFFFF, + 0x008A7A, 0x008A88, 0x000000, 0xFFFFFF, + 0x008A8B, 0x008A92, 0x000000, 0xFFFFFF, + 0x008A94, 0x008B06, 0x000000, 0xFFFFFF, + 0x008B08, 0x008B25, 0x000000, 0xFFFFFF, + 0x008B27, 0x008B65, 0x000000, 0xFFFFFF, + 0x008B67, 0x008B6B, 0x000000, 0xFFFFFF, + 0x008B6D, 0x008B9F, 0x000000, 0xFFFFFF, + 0x008BAC, 0x008BAC, 0x000000, 0xFFFFFF, + 0x008BB1, 0x008BB1, 0x000000, 0xFFFFFF, + 0x008BBB, 0x008BBB, 0x000000, 0xFFFFFF, + 0x008BC7, 0x008BC7, 0x000000, 0xFFFFFF, + 0x008BD0, 0x008BD0, 0x000000, 0xFFFFFF, + 0x008BEA, 0x008BEA, 0x000000, 0xFFFFFF, + 0x008C09, 0x008C09, 0x000000, 0xFFFFFF, + 0x008C1E, 0x008C1E, 0x000000, 0xFFFFFF, + 0x008C38, 0x008C40, 0x000000, 0xFFFFFF, + 0x008C42, 0x008C45, 0x000000, 0xFFFFFF, + 0x008C48, 0x008C48, 0x000000, 0xFFFFFF, + 0x008C4A, 0x008C4B, 0x000000, 0xFFFFFF, + 0x008C4D, 0x008C54, 0x000000, 0xFFFFFF, + 0x008C56, 0x008C59, 0x000000, 0xFFFFFF, + 0x008C5B, 0x008C60, 0x000000, 0xFFFFFF, + 0x008C63, 0x008C69, 0x000000, 0xFFFFFF, + 0x008C6C, 0x008C72, 0x000000, 0xFFFFFF, + 0x008C74, 0x008C77, 0x000000, 0xFFFFFF, + 0x008C7B, 0x008C81, 0x000000, 0xFFFFFF, + 0x008C83, 0x008C84, 0x000000, 0xFFFFFF, + 0x008C86, 0x008C88, 0x000000, 0xFFFFFF, + 0x008C8B, 0x008C8B, 0x000000, 0xFFFFFF, + 0x008C8D, 0x008C93, 0x000000, 0xFFFFFF, + 0x008C95, 0x008C97, 0x000000, 0xFFFFFF, + 0x008C99, 0x008D1C, 0x000000, 0xFFFFFF, + 0x008D20, 0x008D20, 0x000000, 0xFFFFFF, + 0x008D51, 0x008D52, 0x000000, 0xFFFFFF, + 0x008D57, 0x008D57, 0x000000, 0xFFFFFF, + 0x008D5F, 0x008D5F, 0x000000, 0xFFFFFF, + 0x008D65, 0x008D65, 0x000000, 0xFFFFFF, + 0x008D68, 0x008D6A, 0x000000, 0xFFFFFF, + 0x008D6C, 0x008D6C, 0x000000, 0xFFFFFF, + 0x008D6E, 0x008D6F, 0x000000, 0xFFFFFF, + 0x008D71, 0x008D72, 0x000000, 0xFFFFFF, + 0x008D78, 0x008D80, 0x000000, 0xFFFFFF, + 0x008D82, 0x008D83, 0x000000, 0xFFFFFF, + 0x008D86, 0x008D89, 0x000000, 0xFFFFFF, + 0x008D8C, 0x008D90, 0x000000, 0xFFFFFF, + 0x008D92, 0x008D93, 0x000000, 0xFFFFFF, + 0x008D95, 0x008D9E, 0x000000, 0xFFFFFF, + 0x008DA0, 0x008DA2, 0x000000, 0xFFFFFF, + 0x008DA4, 0x008DB0, 0x000000, 0xFFFFFF, + 0x008DB2, 0x008DB2, 0x000000, 0xFFFFFF, + 0x008DB6, 0x008DB7, 0x000000, 0xFFFFFF, + 0x008DB9, 0x008DB9, 0x000000, 0xFFFFFF, + 0x008DBB, 0x008DBB, 0x000000, 0xFFFFFF, + 0x008DBD, 0x008DBD, 0x000000, 0xFFFFFF, + 0x008DC0, 0x008DC2, 0x000000, 0xFFFFFF, + 0x008DC5, 0x008DC5, 0x000000, 0xFFFFFF, + 0x008DC7, 0x008DCA, 0x000000, 0xFFFFFF, + 0x008DCD, 0x008DCD, 0x000000, 0xFFFFFF, + 0x008DD0, 0x008DD0, 0x000000, 0xFFFFFF, + 0x008DD2, 0x008DD5, 0x000000, 0xFFFFFF, + 0x008DD8, 0x008DD9, 0x000000, 0xFFFFFF, + 0x008DDC, 0x008DDC, 0x000000, 0xFFFFFF, + 0x008DE0, 0x008DE2, 0x000000, 0xFFFFFF, + 0x008DE5, 0x008DE7, 0x000000, 0xFFFFFF, + 0x008DE9, 0x008DE9, 0x000000, 0xFFFFFF, + 0x008DED, 0x008DEE, 0x000000, 0xFFFFFF, + 0x008DF0, 0x008DF2, 0x000000, 0xFFFFFF, + 0x008DF4, 0x008DF4, 0x000000, 0xFFFFFF, + 0x008DF6, 0x008DF6, 0x000000, 0xFFFFFF, + 0x008DFC, 0x008DFC, 0x000000, 0xFFFFFF, + 0x008DFE, 0x008E04, 0x000000, 0xFFFFFF, + 0x008E06, 0x008E08, 0x000000, 0xFFFFFF, + 0x008E0B, 0x008E0B, 0x000000, 0xFFFFFF, + 0x008E0D, 0x008E0E, 0x000000, 0xFFFFFF, + 0x008E10, 0x008E13, 0x000000, 0xFFFFFF, + 0x008E15, 0x008E1C, 0x000000, 0xFFFFFF, + 0x008E20, 0x008E21, 0x000000, 0xFFFFFF, + 0x008E24, 0x008E28, 0x000000, 0xFFFFFF, + 0x008E2B, 0x008E2B, 0x000000, 0xFFFFFF, + 0x008E2D, 0x008E2D, 0x000000, 0xFFFFFF, + 0x008E30, 0x008E30, 0x000000, 0xFFFFFF, + 0x008E32, 0x008E34, 0x000000, 0xFFFFFF, + 0x008E36, 0x008E38, 0x000000, 0xFFFFFF, + 0x008E3B, 0x008E3C, 0x000000, 0xFFFFFF, + 0x008E3E, 0x008E3F, 0x000000, 0xFFFFFF, + 0x008E43, 0x008E43, 0x000000, 0xFFFFFF, + 0x008E45, 0x008E46, 0x000000, 0xFFFFFF, + 0x008E4C, 0x008E50, 0x000000, 0xFFFFFF, + 0x008E53, 0x008E58, 0x000000, 0xFFFFFF, + 0x008E5A, 0x008E65, 0x000000, 0xFFFFFF, + 0x008E67, 0x008E68, 0x000000, 0xFFFFFF, + 0x008E6A, 0x008E6B, 0x000000, 0xFFFFFF, + 0x008E6E, 0x008E6E, 0x000000, 0xFFFFFF, + 0x008E71, 0x008E71, 0x000000, 0xFFFFFF, + 0x008E73, 0x008E73, 0x000000, 0xFFFFFF, + 0x008E75, 0x008E75, 0x000000, 0xFFFFFF, + 0x008E77, 0x008E7B, 0x000000, 0xFFFFFF, + 0x008E7D, 0x008E7E, 0x000000, 0xFFFFFF, + 0x008E80, 0x008E80, 0x000000, 0xFFFFFF, + 0x008E82, 0x008E84, 0x000000, 0xFFFFFF, + 0x008E86, 0x008E86, 0x000000, 0xFFFFFF, + 0x008E88, 0x008E8E, 0x000000, 0xFFFFFF, + 0x008E91, 0x008E93, 0x000000, 0xFFFFFF, + 0x008E95, 0x008E9B, 0x000000, 0xFFFFFF, + 0x008E9D, 0x008E9D, 0x000000, 0xFFFFFF, + 0x008E9F, 0x008EAA, 0x000000, 0xFFFFFF, + 0x008EAD, 0x008EAE, 0x000000, 0xFFFFFF, + 0x008EB0, 0x008EB1, 0x000000, 0xFFFFFF, + 0x008EB3, 0x008EB9, 0x000000, 0xFFFFFF, + 0x008EBB, 0x008ECD, 0x000000, 0xFFFFFF, + 0x008ECF, 0x008F65, 0x000000, 0xFFFFFF, + 0x008F6A, 0x008F6A, 0x000000, 0xFFFFFF, + 0x008F80, 0x008F80, 0x000000, 0xFFFFFF, + 0x008F8C, 0x008F8C, 0x000000, 0xFFFFFF, + 0x008F92, 0x008F92, 0x000000, 0xFFFFFF, + 0x008F9D, 0x008F9D, 0x000000, 0xFFFFFF, + 0x008FA0, 0x008FA2, 0x000000, 0xFFFFFF, + 0x008FA4, 0x008FA7, 0x000000, 0xFFFFFF, + 0x008FAA, 0x008FAA, 0x000000, 0xFFFFFF, + 0x008FAC, 0x008FAF, 0x000000, 0xFFFFFF, + 0x008FB2, 0x008FB5, 0x000000, 0xFFFFFF, + 0x008FB7, 0x008FB8, 0x000000, 0xFFFFFF, + 0x008FBA, 0x008FBC, 0x000000, 0xFFFFFF, + 0x008FBF, 0x008FC0, 0x000000, 0xFFFFFF, + 0x008FC3, 0x008FC3, 0x000000, 0xFFFFFF, + 0x008FC6, 0x008FC6, 0x000000, 0xFFFFFF, + 0x008FC9, 0x008FCD, 0x000000, 0xFFFFFF, + 0x008FCF, 0x008FCF, 0x000000, 0xFFFFFF, + 0x008FD2, 0x008FD2, 0x000000, 0xFFFFFF, + 0x008FD6, 0x008FD7, 0x000000, 0xFFFFFF, + 0x008FDA, 0x008FDA, 0x000000, 0xFFFFFF, + 0x008FE0, 0x008FE1, 0x000000, 0xFFFFFF, + 0x008FE3, 0x008FE3, 0x000000, 0xFFFFFF, + 0x008FE7, 0x008FE7, 0x000000, 0xFFFFFF, + 0x008FEC, 0x008FEC, 0x000000, 0xFFFFFF, + 0x008FEF, 0x008FEF, 0x000000, 0xFFFFFF, + 0x008FF1, 0x008FF2, 0x000000, 0xFFFFFF, + 0x008FF4, 0x008FF6, 0x000000, 0xFFFFFF, + 0x008FFA, 0x008FFC, 0x000000, 0xFFFFFF, + 0x008FFE, 0x008FFF, 0x000000, 0xFFFFFF, + 0x009007, 0x009008, 0x000000, 0xFFFFFF, + 0x00900C, 0x00900C, 0x000000, 0xFFFFFF, + 0x00900E, 0x00900E, 0x000000, 0xFFFFFF, + 0x009013, 0x009013, 0x000000, 0xFFFFFF, + 0x009015, 0x009015, 0x000000, 0xFFFFFF, + 0x009018, 0x009019, 0x000000, 0xFFFFFF, + 0x00901C, 0x00901C, 0x000000, 0xFFFFFF, + 0x009023, 0x009025, 0x000000, 0xFFFFFF, + 0x009027, 0x00902C, 0x000000, 0xFFFFFF, + 0x009030, 0x009034, 0x000000, 0xFFFFFF, + 0x009037, 0x009037, 0x000000, 0xFFFFFF, + 0x009039, 0x00903A, 0x000000, 0xFFFFFF, + 0x00903D, 0x00903D, 0x000000, 0xFFFFFF, + 0x00903F, 0x009040, 0x000000, 0xFFFFFF, + 0x009043, 0x009043, 0x000000, 0xFFFFFF, + 0x009045, 0x009046, 0x000000, 0xFFFFFF, + 0x009048, 0x00904C, 0x000000, 0xFFFFFF, + 0x00904E, 0x00904E, 0x000000, 0xFFFFFF, + 0x009054, 0x009056, 0x000000, 0xFFFFFF, + 0x009059, 0x00905A, 0x000000, 0xFFFFFF, + 0x00905C, 0x009061, 0x000000, 0xFFFFFF, + 0x009064, 0x009064, 0x000000, 0xFFFFFF, + 0x009066, 0x009067, 0x000000, 0xFFFFFF, + 0x009069, 0x00906C, 0x000000, 0xFFFFFF, + 0x00906F, 0x009073, 0x000000, 0xFFFFFF, + 0x009076, 0x00907C, 0x000000, 0xFFFFFF, + 0x00907E, 0x00907E, 0x000000, 0xFFFFFF, + 0x009081, 0x009081, 0x000000, 0xFFFFFF, + 0x009084, 0x009087, 0x000000, 0xFFFFFF, + 0x009089, 0x00908A, 0x000000, 0xFFFFFF, + 0x00908C, 0x009090, 0x000000, 0xFFFFFF, + 0x009092, 0x009092, 0x000000, 0xFFFFFF, + 0x009094, 0x009094, 0x000000, 0xFFFFFF, + 0x009096, 0x009096, 0x000000, 0xFFFFFF, + 0x009098, 0x009098, 0x000000, 0xFFFFFF, + 0x00909A, 0x00909A, 0x000000, 0xFFFFFF, + 0x00909C, 0x00909C, 0x000000, 0xFFFFFF, + 0x00909E, 0x0090A0, 0x000000, 0xFFFFFF, + 0x0090A4, 0x0090A5, 0x000000, 0xFFFFFF, + 0x0090A7, 0x0090A9, 0x000000, 0xFFFFFF, + 0x0090AB, 0x0090AB, 0x000000, 0xFFFFFF, + 0x0090AD, 0x0090AD, 0x000000, 0xFFFFFF, + 0x0090B2, 0x0090B2, 0x000000, 0xFFFFFF, + 0x0090B7, 0x0090B7, 0x000000, 0xFFFFFF, + 0x0090BC, 0x0090BD, 0x000000, 0xFFFFFF, + 0x0090BF, 0x0090C0, 0x000000, 0xFFFFFF, + 0x0090C2, 0x0090C3, 0x000000, 0xFFFFFF, + 0x0090C6, 0x0090C6, 0x000000, 0xFFFFFF, + 0x0090C8, 0x0090C9, 0x000000, 0xFFFFFF, + 0x0090CB, 0x0090CD, 0x000000, 0xFFFFFF, + 0x0090D2, 0x0090D2, 0x000000, 0xFFFFFF, + 0x0090D4, 0x0090D6, 0x000000, 0xFFFFFF, + 0x0090D8, 0x0090DA, 0x000000, 0xFFFFFF, + 0x0090DE, 0x0090E0, 0x000000, 0xFFFFFF, + 0x0090E3, 0x0090E5, 0x000000, 0xFFFFFF, + 0x0090E9, 0x0090EA, 0x000000, 0xFFFFFF, + 0x0090EC, 0x0090EC, 0x000000, 0xFFFFFF, + 0x0090EE, 0x0090EE, 0x000000, 0xFFFFFF, + 0x0090F0, 0x0090F3, 0x000000, 0xFFFFFF, + 0x0090F5, 0x0090F7, 0x000000, 0xFFFFFF, + 0x0090F9, 0x0090FC, 0x000000, 0xFFFFFF, + 0x0090FF, 0x009101, 0x000000, 0xFFFFFF, + 0x009103, 0x009103, 0x000000, 0xFFFFFF, + 0x009105, 0x009118, 0x000000, 0xFFFFFF, + 0x00911A, 0x00911D, 0x000000, 0xFFFFFF, + 0x00911F, 0x009121, 0x000000, 0xFFFFFF, + 0x009124, 0x00912E, 0x000000, 0xFFFFFF, + 0x009130, 0x009130, 0x000000, 0xFFFFFF, + 0x009132, 0x009138, 0x000000, 0xFFFFFF, + 0x00913A, 0x009142, 0x000000, 0xFFFFFF, + 0x009144, 0x009145, 0x000000, 0xFFFFFF, + 0x009147, 0x009148, 0x000000, 0xFFFFFF, + 0x009151, 0x009151, 0x000000, 0xFFFFFF, + 0x009153, 0x009156, 0x000000, 0xFFFFFF, + 0x009158, 0x009159, 0x000000, 0xFFFFFF, + 0x00915B, 0x00915C, 0x000000, 0xFFFFFF, + 0x00915F, 0x009160, 0x000000, 0xFFFFFF, + 0x009166, 0x009168, 0x000000, 0xFFFFFF, + 0x00916B, 0x00916B, 0x000000, 0xFFFFFF, + 0x00916D, 0x00916D, 0x000000, 0xFFFFFF, + 0x009173, 0x009173, 0x000000, 0xFFFFFF, + 0x00917A, 0x00917C, 0x000000, 0xFFFFFF, + 0x009180, 0x009184, 0x000000, 0xFFFFFF, + 0x009186, 0x009186, 0x000000, 0xFFFFFF, + 0x009188, 0x009188, 0x000000, 0xFFFFFF, + 0x00918A, 0x00918A, 0x000000, 0xFFFFFF, + 0x00918E, 0x00918F, 0x000000, 0xFFFFFF, + 0x009193, 0x009199, 0x000000, 0xFFFFFF, + 0x00919C, 0x0091A1, 0x000000, 0xFFFFFF, + 0x0091A4, 0x0091A9, 0x000000, 0xFFFFFF, + 0x0091AB, 0x0091AC, 0x000000, 0xFFFFFF, + 0x0091B0, 0x0091B3, 0x000000, 0xFFFFFF, + 0x0091B6, 0x0091B9, 0x000000, 0xFFFFFF, + 0x0091BB, 0x0091C6, 0x000000, 0xFFFFFF, + 0x0091C8, 0x0091C8, 0x000000, 0xFFFFFF, + 0x0091CB, 0x0091CB, 0x000000, 0xFFFFFF, + 0x0091D0, 0x0091D0, 0x000000, 0xFFFFFF, + 0x0091D2, 0x0091DB, 0x000000, 0xFFFFFF, + 0x0091DD, 0x009273, 0x000000, 0xFFFFFF, + 0x009275, 0x00928D, 0x000000, 0xFFFFFF, + 0x00928F, 0x0092AD, 0x000000, 0xFFFFFF, + 0x0092AF, 0x0092C7, 0x000000, 0xFFFFFF, + 0x0092C9, 0x00933D, 0x000000, 0xFFFFFF, + 0x00933F, 0x009369, 0x000000, 0xFFFFFF, + 0x00936B, 0x00938E, 0x000000, 0xFFFFFF, + 0x009390, 0x0093C9, 0x000000, 0xFFFFFF, + 0x0093CB, 0x0093D5, 0x000000, 0xFFFFFF, + 0x0093D7, 0x00943D, 0x000000, 0xFFFFFF, + 0x00943F, 0x00946A, 0x000000, 0xFFFFFF, + 0x00946C, 0x009484, 0x000000, 0xFFFFFF, + 0x009491, 0x009491, 0x000000, 0xFFFFFF, + 0x009496, 0x009496, 0x000000, 0xFFFFFF, + 0x009498, 0x009498, 0x000000, 0xFFFFFF, + 0x0094C7, 0x0094C7, 0x000000, 0xFFFFFF, + 0x0094CF, 0x0094CF, 0x000000, 0xFFFFFF, + 0x0094D3, 0x0094D4, 0x000000, 0xFFFFFF, + 0x0094DA, 0x0094DA, 0x000000, 0xFFFFFF, + 0x0094E6, 0x0094E6, 0x000000, 0xFFFFFF, + 0x0094FB, 0x0094FB, 0x000000, 0xFFFFFF, + 0x00951C, 0x00951C, 0x000000, 0xFFFFFF, + 0x009520, 0x009520, 0x000000, 0xFFFFFF, + 0x009527, 0x009527, 0x000000, 0xFFFFFF, + 0x009533, 0x009533, 0x000000, 0xFFFFFF, + 0x00953D, 0x00953D, 0x000000, 0xFFFFFF, + 0x009543, 0x009543, 0x000000, 0xFFFFFF, + 0x009548, 0x009548, 0x000000, 0xFFFFFF, + 0x00954B, 0x00954B, 0x000000, 0xFFFFFF, + 0x009555, 0x009555, 0x000000, 0xFFFFFF, + 0x00955A, 0x00955A, 0x000000, 0xFFFFFF, + 0x009560, 0x009560, 0x000000, 0xFFFFFF, + 0x00956E, 0x00956E, 0x000000, 0xFFFFFF, + 0x009574, 0x009575, 0x000000, 0xFFFFFF, + 0x009577, 0x00957E, 0x000000, 0xFFFFFF, + 0x009580, 0x0095E7, 0x000000, 0xFFFFFF, + 0x0095EC, 0x0095EC, 0x000000, 0xFFFFFF, + 0x0095FF, 0x0095FF, 0x000000, 0xFFFFFF, + 0x009607, 0x009607, 0x000000, 0xFFFFFF, + 0x009613, 0x009613, 0x000000, 0xFFFFFF, + 0x009618, 0x009618, 0x000000, 0xFFFFFF, + 0x00961B, 0x00961B, 0x000000, 0xFFFFFF, + 0x00961E, 0x00961E, 0x000000, 0xFFFFFF, + 0x009620, 0x009620, 0x000000, 0xFFFFFF, + 0x009623, 0x009629, 0x000000, 0xFFFFFF, + 0x00962B, 0x00962D, 0x000000, 0xFFFFFF, + 0x00962F, 0x009630, 0x000000, 0xFFFFFF, + 0x009637, 0x00963A, 0x000000, 0xFFFFFF, + 0x00963E, 0x00963E, 0x000000, 0xFFFFFF, + 0x009641, 0x009641, 0x000000, 0xFFFFFF, + 0x009643, 0x009643, 0x000000, 0xFFFFFF, + 0x00964A, 0x00964A, 0x000000, 0xFFFFFF, + 0x00964E, 0x00964F, 0x000000, 0xFFFFFF, + 0x009651, 0x009653, 0x000000, 0xFFFFFF, + 0x009656, 0x00965A, 0x000000, 0xFFFFFF, + 0x00965C, 0x00965E, 0x000000, 0xFFFFFF, + 0x009660, 0x009660, 0x000000, 0xFFFFFF, + 0x009663, 0x009663, 0x000000, 0xFFFFFF, + 0x009665, 0x009666, 0x000000, 0xFFFFFF, + 0x00966B, 0x00966B, 0x000000, 0xFFFFFF, + 0x00966D, 0x009671, 0x000000, 0xFFFFFF, + 0x009673, 0x009673, 0x000000, 0xFFFFFF, + 0x009678, 0x009684, 0x000000, 0xFFFFFF, + 0x009687, 0x009687, 0x000000, 0xFFFFFF, + 0x009689, 0x00968A, 0x000000, 0xFFFFFF, + 0x00968C, 0x00968C, 0x000000, 0xFFFFFF, + 0x00968E, 0x00968E, 0x000000, 0xFFFFFF, + 0x009691, 0x009693, 0x000000, 0xFFFFFF, + 0x009695, 0x009696, 0x000000, 0xFFFFFF, + 0x00969A, 0x00969B, 0x000000, 0xFFFFFF, + 0x00969D, 0x0096A6, 0x000000, 0xFFFFFF, + 0x0096A8, 0x0096AF, 0x000000, 0xFFFFFF, + 0x0096B1, 0x0096B2, 0x000000, 0xFFFFFF, + 0x0096B4, 0x0096B5, 0x000000, 0xFFFFFF, + 0x0096B7, 0x0096B8, 0x000000, 0xFFFFFF, + 0x0096BA, 0x0096BB, 0x000000, 0xFFFFFF, + 0x0096BF, 0x0096BF, 0x000000, 0xFFFFFF, + 0x0096C2, 0x0096C3, 0x000000, 0xFFFFFF, + 0x0096C8, 0x0096C8, 0x000000, 0xFFFFFF, + 0x0096CA, 0x0096CB, 0x000000, 0xFFFFFF, + 0x0096D0, 0x0096D1, 0x000000, 0xFFFFFF, + 0x0096D3, 0x0096D4, 0x000000, 0xFFFFFF, + 0x0096D6, 0x0096DF, 0x000000, 0xFFFFFF, + 0x0096E1, 0x0096E7, 0x000000, 0xFFFFFF, + 0x0096EB, 0x0096EE, 0x000000, 0xFFFFFF, + 0x0096F0, 0x0096F2, 0x000000, 0xFFFFFF, + 0x0096F4, 0x0096F5, 0x000000, 0xFFFFFF, + 0x0096F8, 0x0096F8, 0x000000, 0xFFFFFF, + 0x0096FA, 0x0096FD, 0x000000, 0xFFFFFF, + 0x0096FF, 0x0096FF, 0x000000, 0xFFFFFF, + 0x009702, 0x009703, 0x000000, 0xFFFFFF, + 0x009705, 0x009705, 0x000000, 0xFFFFFF, + 0x00970A, 0x00970C, 0x000000, 0xFFFFFF, + 0x009710, 0x009712, 0x000000, 0xFFFFFF, + 0x009714, 0x009715, 0x000000, 0xFFFFFF, + 0x009717, 0x00971B, 0x000000, 0xFFFFFF, + 0x00971D, 0x00971D, 0x000000, 0xFFFFFF, + 0x00971F, 0x009729, 0x000000, 0xFFFFFF, + 0x00972B, 0x00972C, 0x000000, 0xFFFFFF, + 0x00972E, 0x00972F, 0x000000, 0xFFFFFF, + 0x009731, 0x009731, 0x000000, 0xFFFFFF, + 0x009733, 0x009737, 0x000000, 0xFFFFFF, + 0x00973A, 0x00973D, 0x000000, 0xFFFFFF, + 0x00973F, 0x009751, 0x000000, 0xFFFFFF, + 0x009754, 0x009755, 0x000000, 0xFFFFFF, + 0x009757, 0x009758, 0x000000, 0xFFFFFF, + 0x00975A, 0x00975A, 0x000000, 0xFFFFFF, + 0x00975C, 0x00975D, 0x000000, 0xFFFFFF, + 0x00975F, 0x00975F, 0x000000, 0xFFFFFF, + 0x009763, 0x009764, 0x000000, 0xFFFFFF, + 0x009766, 0x009768, 0x000000, 0xFFFFFF, + 0x00976A, 0x009772, 0x000000, 0xFFFFFF, + 0x009775, 0x009775, 0x000000, 0xFFFFFF, + 0x009777, 0x00977B, 0x000000, 0xFFFFFF, + 0x00977D, 0x009784, 0x000000, 0xFFFFFF, + 0x009786, 0x00978A, 0x000000, 0xFFFFFF, + 0x00978C, 0x00978C, 0x000000, 0xFFFFFF, + 0x00978E, 0x009790, 0x000000, 0xFFFFFF, + 0x009793, 0x009793, 0x000000, 0xFFFFFF, + 0x009795, 0x009797, 0x000000, 0xFFFFFF, + 0x009799, 0x00979F, 0x000000, 0xFFFFFF, + 0x0097A1, 0x0097A2, 0x000000, 0xFFFFFF, + 0x0097A4, 0x0097AA, 0x000000, 0xFFFFFF, + 0x0097AC, 0x0097AC, 0x000000, 0xFFFFFF, + 0x0097AE, 0x0097AE, 0x000000, 0xFFFFFF, + 0x0097B0, 0x0097B1, 0x000000, 0xFFFFFF, + 0x0097B3, 0x0097B3, 0x000000, 0xFFFFFF, + 0x0097B5, 0x0097E5, 0x000000, 0xFFFFFF, + 0x0097E8, 0x0097E8, 0x000000, 0xFFFFFF, + 0x0097EE, 0x0097F2, 0x000000, 0xFFFFFF, + 0x0097F4, 0x0097F4, 0x000000, 0xFFFFFF, + 0x0097F7, 0x009874, 0x000000, 0xFFFFFF, + 0x00988B, 0x00988B, 0x000000, 0xFFFFFF, + 0x00988E, 0x00988E, 0x000000, 0xFFFFFF, + 0x009892, 0x009892, 0x000000, 0xFFFFFF, + 0x009895, 0x009895, 0x000000, 0xFFFFFF, + 0x009899, 0x009899, 0x000000, 0xFFFFFF, + 0x0098A3, 0x0098A3, 0x000000, 0xFFFFFF, + 0x0098A8, 0x0098CD, 0x000000, 0xFFFFFF, + 0x0098CF, 0x0098D0, 0x000000, 0xFFFFFF, + 0x0098D4, 0x0098D4, 0x000000, 0xFFFFFF, + 0x0098D6, 0x0098D7, 0x000000, 0xFFFFFF, + 0x0098DB, 0x0098DD, 0x000000, 0xFFFFFF, + 0x0098E0, 0x0098E6, 0x000000, 0xFFFFFF, + 0x0098E9, 0x00990C, 0x000000, 0xFFFFFF, + 0x00990E, 0x00990F, 0x000000, 0xFFFFFF, + 0x009911, 0x00992D, 0x000000, 0xFFFFFF, + 0x00992F, 0x009953, 0x000000, 0xFFFFFF, + 0x009956, 0x009962, 0x000000, 0xFFFFFF, + 0x009964, 0x009964, 0x000000, 0xFFFFFF, + 0x009966, 0x009966, 0x000000, 0xFFFFFF, + 0x009973, 0x009973, 0x000000, 0xFFFFFF, + 0x009978, 0x009979, 0x000000, 0xFFFFFF, + 0x00997B, 0x00997B, 0x000000, 0xFFFFFF, + 0x00997E, 0x00997E, 0x000000, 0xFFFFFF, + 0x009982, 0x009983, 0x000000, 0xFFFFFF, + 0x009989, 0x009989, 0x000000, 0xFFFFFF, + 0x00998C, 0x00998C, 0x000000, 0xFFFFFF, + 0x00998E, 0x00998E, 0x000000, 0xFFFFFF, + 0x00999A, 0x0099A4, 0x000000, 0xFFFFFF, + 0x0099A6, 0x0099A7, 0x000000, 0xFFFFFF, + 0x0099A9, 0x009A6B, 0x000000, 0xFFFFFF, + 0x009A72, 0x009A72, 0x000000, 0xFFFFFF, + 0x009A83, 0x009A83, 0x000000, 0xFFFFFF, + 0x009A89, 0x009A89, 0x000000, 0xFFFFFF, + 0x009A8D, 0x009A8E, 0x000000, 0xFFFFFF, + 0x009A94, 0x009A95, 0x000000, 0xFFFFFF, + 0x009A99, 0x009A99, 0x000000, 0xFFFFFF, + 0x009AA6, 0x009AA6, 0x000000, 0xFFFFFF, + 0x009AA9, 0x009AAF, 0x000000, 0xFFFFFF, + 0x009AB2, 0x009AB5, 0x000000, 0xFFFFFF, + 0x009AB9, 0x009AB9, 0x000000, 0xFFFFFF, + 0x009ABB, 0x009ABB, 0x000000, 0xFFFFFF, + 0x009ABD, 0x009ABF, 0x000000, 0xFFFFFF, + 0x009AC3, 0x009AC4, 0x000000, 0xFFFFFF, + 0x009AC6, 0x009ACA, 0x000000, 0xFFFFFF, + 0x009ACD, 0x009AD0, 0x000000, 0xFFFFFF, + 0x009AD2, 0x009AD2, 0x000000, 0xFFFFFF, + 0x009AD4, 0x009AD7, 0x000000, 0xFFFFFF, + 0x009AD9, 0x009ADE, 0x000000, 0xFFFFFF, + 0x009AE0, 0x009AE0, 0x000000, 0xFFFFFF, + 0x009AE2, 0x009AE5, 0x000000, 0xFFFFFF, + 0x009AE7, 0x009AEA, 0x000000, 0xFFFFFF, + 0x009AEC, 0x009AEC, 0x000000, 0xFFFFFF, + 0x009AEE, 0x009AEE, 0x000000, 0xFFFFFF, + 0x009AF0, 0x009AF8, 0x000000, 0xFFFFFF, + 0x009AFA, 0x009AFA, 0x000000, 0xFFFFFF, + 0x009AFC, 0x009B02, 0x000000, 0xFFFFFF, + 0x009B04, 0x009B07, 0x000000, 0xFFFFFF, + 0x009B09, 0x009B0E, 0x000000, 0xFFFFFF, + 0x009B10, 0x009B12, 0x000000, 0xFFFFFF, + 0x009B14, 0x009B1E, 0x000000, 0xFFFFFF, + 0x009B20, 0x009B22, 0x000000, 0xFFFFFF, + 0x009B24, 0x009B2E, 0x000000, 0xFFFFFF, + 0x009B30, 0x009B31, 0x000000, 0xFFFFFF, + 0x009B33, 0x009B3A, 0x000000, 0xFFFFFF, + 0x009B3D, 0x009B40, 0x000000, 0xFFFFFF, + 0x009B46, 0x009B46, 0x000000, 0xFFFFFF, + 0x009B4A, 0x009B4C, 0x000000, 0xFFFFFF, + 0x009B4E, 0x009B4E, 0x000000, 0xFFFFFF, + 0x009B50, 0x009B50, 0x000000, 0xFFFFFF, + 0x009B52, 0x009B53, 0x000000, 0xFFFFFF, + 0x009B55, 0x009C7B, 0x000000, 0xFFFFFF, + 0x009C7D, 0x009C7E, 0x000000, 0xFFFFFF, + 0x009C80, 0x009C80, 0x000000, 0xFFFFFF, + 0x009C83, 0x009C84, 0x000000, 0xFFFFFF, + 0x009C89, 0x009C8A, 0x000000, 0xFFFFFF, + 0x009C8C, 0x009C8C, 0x000000, 0xFFFFFF, + 0x009C8F, 0x009C8F, 0x000000, 0xFFFFFF, + 0x009C93, 0x009C93, 0x000000, 0xFFFFFF, + 0x009C96, 0x009C99, 0x000000, 0xFFFFFF, + 0x009C9D, 0x009C9D, 0x000000, 0xFFFFFF, + 0x009CAA, 0x009CAA, 0x000000, 0xFFFFFF, + 0x009CAC, 0x009CAC, 0x000000, 0xFFFFFF, + 0x009CAF, 0x009CAF, 0x000000, 0xFFFFFF, + 0x009CB9, 0x009CB9, 0x000000, 0xFFFFFF, + 0x009CBE, 0x009CC2, 0x000000, 0xFFFFFF, + 0x009CC8, 0x009CC9, 0x000000, 0xFFFFFF, + 0x009CD1, 0x009CD2, 0x000000, 0xFFFFFF, + 0x009CDA, 0x009CDB, 0x000000, 0xFFFFFF, + 0x009CE0, 0x009CE1, 0x000000, 0xFFFFFF, + 0x009CE3, 0x009E1E, 0x000000, 0xFFFFFF, + 0x009E24, 0x009E24, 0x000000, 0xFFFFFF, + 0x009E27, 0x009E27, 0x000000, 0xFFFFFF, + 0x009E2E, 0x009E2E, 0x000000, 0xFFFFFF, + 0x009E30, 0x009E30, 0x000000, 0xFFFFFF, + 0x009E34, 0x009E34, 0x000000, 0xFFFFFF, + 0x009E3B, 0x009E3C, 0x000000, 0xFFFFFF, + 0x009E40, 0x009E40, 0x000000, 0xFFFFFF, + 0x009E4D, 0x009E4D, 0x000000, 0xFFFFFF, + 0x009E50, 0x009E50, 0x000000, 0xFFFFFF, + 0x009E52, 0x009E54, 0x000000, 0xFFFFFF, + 0x009E56, 0x009E56, 0x000000, 0xFFFFFF, + 0x009E59, 0x009E59, 0x000000, 0xFFFFFF, + 0x009E5D, 0x009E5D, 0x000000, 0xFFFFFF, + 0x009E5F, 0x009E62, 0x000000, 0xFFFFFF, + 0x009E65, 0x009E65, 0x000000, 0xFFFFFF, + 0x009E6E, 0x009E6F, 0x000000, 0xFFFFFF, + 0x009E72, 0x009E72, 0x000000, 0xFFFFFF, + 0x009E74, 0x009E7D, 0x000000, 0xFFFFFF, + 0x009E80, 0x009E81, 0x000000, 0xFFFFFF, + 0x009E83, 0x009E86, 0x000000, 0xFFFFFF, + 0x009E89, 0x009E8A, 0x000000, 0xFFFFFF, + 0x009E8C, 0x009E91, 0x000000, 0xFFFFFF, + 0x009E94, 0x009E9C, 0x000000, 0xFFFFFF, + 0x009E9E, 0x009E9E, 0x000000, 0xFFFFFF, + 0x009EA0, 0x009EA5, 0x000000, 0xFFFFFF, + 0x009EA7, 0x009EB3, 0x000000, 0xFFFFFF, + 0x009EB5, 0x009EB7, 0x000000, 0xFFFFFF, + 0x009EB9, 0x009EBA, 0x000000, 0xFFFFFF, + 0x009EBC, 0x009EBC, 0x000000, 0xFFFFFF, + 0x009EBF, 0x009EC3, 0x000000, 0xFFFFFF, + 0x009EC5, 0x009EC8, 0x000000, 0xFFFFFF, + 0x009ECA, 0x009ECC, 0x000000, 0xFFFFFF, + 0x009ED0, 0x009ED0, 0x000000, 0xFFFFFF, + 0x009ED2, 0x009ED3, 0x000000, 0xFFFFFF, + 0x009ED5, 0x009ED7, 0x000000, 0xFFFFFF, + 0x009ED9, 0x009EDA, 0x000000, 0xFFFFFF, + 0x009EDE, 0x009EDE, 0x000000, 0xFFFFFF, + 0x009EE1, 0x009EE1, 0x000000, 0xFFFFFF, + 0x009EE3, 0x009EE4, 0x000000, 0xFFFFFF, + 0x009EE6, 0x009EE6, 0x000000, 0xFFFFFF, + 0x009EE8, 0x009EE8, 0x000000, 0xFFFFFF, + 0x009EEB, 0x009EEE, 0x000000, 0xFFFFFF, + 0x009EF0, 0x009EF8, 0x000000, 0xFFFFFF, + 0x009EFA, 0x009EFA, 0x000000, 0xFFFFFF, + 0x009EFD, 0x009EFD, 0x000000, 0xFFFFFF, + 0x009EFF, 0x009F0A, 0x000000, 0xFFFFFF, + 0x009F0C, 0x009F0C, 0x000000, 0xFFFFFF, + 0x009F0F, 0x009F0F, 0x000000, 0xFFFFFF, + 0x009F11, 0x009F12, 0x000000, 0xFFFFFF, + 0x009F14, 0x009F16, 0x000000, 0xFFFFFF, + 0x009F18, 0x009F18, 0x000000, 0xFFFFFF, + 0x009F1A, 0x009F1F, 0x000000, 0xFFFFFF, + 0x009F21, 0x009F21, 0x000000, 0xFFFFFF, + 0x009F23, 0x009F2B, 0x000000, 0xFFFFFF, + 0x009F2D, 0x009F2E, 0x000000, 0xFFFFFF, + 0x009F30, 0x009F36, 0x000000, 0xFFFFFF, + 0x009F38, 0x009F38, 0x000000, 0xFFFFFF, + 0x009F3A, 0x009F3A, 0x000000, 0xFFFFFF, + 0x009F3C, 0x009F3C, 0x000000, 0xFFFFFF, + 0x009F3F, 0x009F43, 0x000000, 0xFFFFFF, + 0x009F45, 0x009F4F, 0x000000, 0xFFFFFF, + 0x009F52, 0x009F7E, 0x000000, 0xFFFFFF, + 0x009F81, 0x009F82, 0x000000, 0xFFFFFF, + 0x009F8D, 0x009F98, 0x000000, 0xFFFFFF, + 0x009F9C, 0x009F9E, 0x000000, 0xFFFFFF, + 0x009FA1, 0x00FF00, 0x000000, 0xFFFFFF, + 0x00FF5F, 0x00FFDF, 0x000000, 0xFFFFFF, + 0x00FFE2, 0x00FFE2, 0x000000, 0xFFFFFF, + 0x00FFE4, 0x00FFE4, 0x000000, 0xFFFFFF, + 0x00FFE6, 0x1FFFFF, 0x000000, 0xFFFFFF, +); + +?> diff --git a/lib/php/monica/cnvtmap/ISO-8859-1.inc.php b/lib/php/monica/cnvtmap/ISO-8859-1.inc.php new file mode 100644 index 0000000..488da94 --- /dev/null +++ b/lib/php/monica/cnvtmap/ISO-8859-1.inc.php @@ -0,0 +1,13 @@ + +// Copyright: Copyright (C) 2005-2007 Pristine Communications + +// ISO-8859-1 +$CNVTMAP["ISO-8859-1"] = array( + 0x000100, 0x1FFFFF, 0x000000, 0xFFFFFF, +); + +?> diff --git a/lib/php/monica/cnvtmap/Shift-JIS.inc.php b/lib/php/monica/cnvtmap/Shift-JIS.inc.php new file mode 100644 index 0000000..77f9e7e --- /dev/null +++ b/lib/php/monica/cnvtmap/Shift-JIS.inc.php @@ -0,0 +1,4138 @@ + +// Copyright: Copyright (C) 2005-2007 Pristine Communications + +// Shift-JIS +$CNVTMAP["Shift-JIS"] = array( + 0x000080, 0x0000A1, 0x000000, 0xFFFFFF, + 0x0000A4, 0x0000A4, 0x000000, 0xFFFFFF, + 0x0000A6, 0x0000A6, 0x000000, 0xFFFFFF, + 0x0000A9, 0x0000AB, 0x000000, 0xFFFFFF, + 0x0000AD, 0x0000AF, 0x000000, 0xFFFFFF, + 0x0000B2, 0x0000B3, 0x000000, 0xFFFFFF, + 0x0000B5, 0x0000B5, 0x000000, 0xFFFFFF, + 0x0000B7, 0x0000D6, 0x000000, 0xFFFFFF, + 0x0000D8, 0x0000F6, 0x000000, 0xFFFFFF, + 0x0000F8, 0x000390, 0x000000, 0xFFFFFF, + 0x0003A2, 0x0003A2, 0x000000, 0xFFFFFF, + 0x0003AA, 0x0003B0, 0x000000, 0xFFFFFF, + 0x0003C2, 0x0003C2, 0x000000, 0xFFFFFF, + 0x0003CA, 0x000400, 0x000000, 0xFFFFFF, + 0x000402, 0x00040F, 0x000000, 0xFFFFFF, + 0x000450, 0x000450, 0x000000, 0xFFFFFF, + 0x000452, 0x00200F, 0x000000, 0xFFFFFF, + 0x002011, 0x002014, 0x000000, 0xFFFFFF, + 0x002017, 0x002017, 0x000000, 0xFFFFFF, + 0x00201A, 0x00201B, 0x000000, 0xFFFFFF, + 0x00201E, 0x00201F, 0x000000, 0xFFFFFF, + 0x002022, 0x002024, 0x000000, 0xFFFFFF, + 0x002027, 0x00202F, 0x000000, 0xFFFFFF, + 0x002031, 0x002031, 0x000000, 0xFFFFFF, + 0x002034, 0x00203A, 0x000000, 0xFFFFFF, + 0x00203C, 0x00203D, 0x000000, 0xFFFFFF, + 0x00203F, 0x002102, 0x000000, 0xFFFFFF, + 0x002104, 0x00212A, 0x000000, 0xFFFFFF, + 0x00212C, 0x00218F, 0x000000, 0xFFFFFF, + 0x002194, 0x0021D1, 0x000000, 0xFFFFFF, + 0x0021D3, 0x0021D3, 0x000000, 0xFFFFFF, + 0x0021D5, 0x0021FF, 0x000000, 0xFFFFFF, + 0x002201, 0x002201, 0x000000, 0xFFFFFF, + 0x002204, 0x002206, 0x000000, 0xFFFFFF, + 0x002209, 0x00220A, 0x000000, 0xFFFFFF, + 0x00220C, 0x002211, 0x000000, 0xFFFFFF, + 0x002213, 0x002219, 0x000000, 0xFFFFFF, + 0x00221B, 0x00221C, 0x000000, 0xFFFFFF, + 0x00221F, 0x00221F, 0x000000, 0xFFFFFF, + 0x002221, 0x002226, 0x000000, 0xFFFFFF, + 0x00222D, 0x002233, 0x000000, 0xFFFFFF, + 0x002236, 0x00223C, 0x000000, 0xFFFFFF, + 0x00223E, 0x002251, 0x000000, 0xFFFFFF, + 0x002253, 0x00225F, 0x000000, 0xFFFFFF, + 0x002262, 0x002265, 0x000000, 0xFFFFFF, + 0x002268, 0x002269, 0x000000, 0xFFFFFF, + 0x00226C, 0x002281, 0x000000, 0xFFFFFF, + 0x002284, 0x002285, 0x000000, 0xFFFFFF, + 0x002288, 0x0022A4, 0x000000, 0xFFFFFF, + 0x0022A6, 0x002311, 0x000000, 0xFFFFFF, + 0x002313, 0x0024FF, 0x000000, 0xFFFFFF, + 0x002504, 0x00250B, 0x000000, 0xFFFFFF, + 0x00250D, 0x00250E, 0x000000, 0xFFFFFF, + 0x002511, 0x002512, 0x000000, 0xFFFFFF, + 0x002515, 0x002516, 0x000000, 0xFFFFFF, + 0x002519, 0x00251A, 0x000000, 0xFFFFFF, + 0x00251E, 0x00251F, 0x000000, 0xFFFFFF, + 0x002521, 0x002522, 0x000000, 0xFFFFFF, + 0x002526, 0x002527, 0x000000, 0xFFFFFF, + 0x002529, 0x00252A, 0x000000, 0xFFFFFF, + 0x00252D, 0x00252E, 0x000000, 0xFFFFFF, + 0x002531, 0x002532, 0x000000, 0xFFFFFF, + 0x002535, 0x002536, 0x000000, 0xFFFFFF, + 0x002539, 0x00253A, 0x000000, 0xFFFFFF, + 0x00253D, 0x00253E, 0x000000, 0xFFFFFF, + 0x002540, 0x002541, 0x000000, 0xFFFFFF, + 0x002543, 0x00254A, 0x000000, 0xFFFFFF, + 0x00254C, 0x00259F, 0x000000, 0xFFFFFF, + 0x0025A2, 0x0025B1, 0x000000, 0xFFFFFF, + 0x0025B4, 0x0025BB, 0x000000, 0xFFFFFF, + 0x0025BE, 0x0025C5, 0x000000, 0xFFFFFF, + 0x0025C8, 0x0025CA, 0x000000, 0xFFFFFF, + 0x0025CC, 0x0025CD, 0x000000, 0xFFFFFF, + 0x0025D0, 0x0025EE, 0x000000, 0xFFFFFF, + 0x0025F0, 0x002604, 0x000000, 0xFFFFFF, + 0x002607, 0x00263F, 0x000000, 0xFFFFFF, + 0x002641, 0x002641, 0x000000, 0xFFFFFF, + 0x002643, 0x002669, 0x000000, 0xFFFFFF, + 0x00266B, 0x00266C, 0x000000, 0xFFFFFF, + 0x00266E, 0x00266E, 0x000000, 0xFFFFFF, + 0x002670, 0x002FFF, 0x000000, 0xFFFFFF, + 0x003004, 0x003004, 0x000000, 0xFFFFFF, + 0x003016, 0x00301B, 0x000000, 0xFFFFFF, + 0x00301D, 0x003040, 0x000000, 0xFFFFFF, + 0x003094, 0x00309A, 0x000000, 0xFFFFFF, + 0x00309F, 0x0030A0, 0x000000, 0xFFFFFF, + 0x0030F7, 0x0030FA, 0x000000, 0xFFFFFF, + 0x0030FF, 0x004DFF, 0x000000, 0xFFFFFF, + 0x004E02, 0x004E02, 0x000000, 0xFFFFFF, + 0x004E04, 0x004E06, 0x000000, 0xFFFFFF, + 0x004E0C, 0x004E0C, 0x000000, 0xFFFFFF, + 0x004E0F, 0x004E0F, 0x000000, 0xFFFFFF, + 0x004E12, 0x004E13, 0x000000, 0xFFFFFF, + 0x004E1A, 0x004E1D, 0x000000, 0xFFFFFF, + 0x004E1F, 0x004E20, 0x000000, 0xFFFFFF, + 0x004E22, 0x004E25, 0x000000, 0xFFFFFF, + 0x004E27, 0x004E29, 0x000000, 0xFFFFFF, + 0x004E2B, 0x004E2C, 0x000000, 0xFFFFFF, + 0x004E2E, 0x004E30, 0x000000, 0xFFFFFF, + 0x004E33, 0x004E35, 0x000000, 0xFFFFFF, + 0x004E37, 0x004E37, 0x000000, 0xFFFFFF, + 0x004E3A, 0x004E3A, 0x000000, 0xFFFFFF, + 0x004E3D, 0x004E3E, 0x000000, 0xFFFFFF, + 0x004E40, 0x004E41, 0x000000, 0xFFFFFF, + 0x004E44, 0x004E44, 0x000000, 0xFFFFFF, + 0x004E46, 0x004E4A, 0x000000, 0xFFFFFF, + 0x004E4C, 0x004E4C, 0x000000, 0xFFFFFF, + 0x004E50, 0x004E54, 0x000000, 0xFFFFFF, + 0x004E5A, 0x004E5C, 0x000000, 0xFFFFFF, + 0x004E60, 0x004E61, 0x000000, 0xFFFFFF, + 0x004E63, 0x004E70, 0x000000, 0xFFFFFF, + 0x004E72, 0x004E72, 0x000000, 0xFFFFFF, + 0x004E74, 0x004E7D, 0x000000, 0xFFFFFF, + 0x004E7F, 0x004E7F, 0x000000, 0xFFFFFF, + 0x004E81, 0x004E81, 0x000000, 0xFFFFFF, + 0x004E83, 0x004E84, 0x000000, 0xFFFFFF, + 0x004E87, 0x004E87, 0x000000, 0xFFFFFF, + 0x004E8D, 0x004E8D, 0x000000, 0xFFFFFF, + 0x004E8F, 0x004E90, 0x000000, 0xFFFFFF, + 0x004E93, 0x004E93, 0x000000, 0xFFFFFF, + 0x004E96, 0x004E97, 0x000000, 0xFFFFFF, + 0x004E9A, 0x004E9A, 0x000000, 0xFFFFFF, + 0x004E9D, 0x004E9D, 0x000000, 0xFFFFFF, + 0x004EA3, 0x004EA3, 0x000000, 0xFFFFFF, + 0x004EA7, 0x004EA7, 0x000000, 0xFFFFFF, + 0x004EA9, 0x004EAA, 0x000000, 0xFFFFFF, + 0x004EAF, 0x004EAF, 0x000000, 0xFFFFFF, + 0x004EB1, 0x004EB2, 0x000000, 0xFFFFFF, + 0x004EB4, 0x004EB5, 0x000000, 0xFFFFFF, + 0x004EB7, 0x004EB9, 0x000000, 0xFFFFFF, + 0x004EBB, 0x004EBF, 0x000000, 0xFFFFFF, + 0x004EC3, 0x004EC3, 0x000000, 0xFFFFFF, + 0x004EC5, 0x004EC5, 0x000000, 0xFFFFFF, + 0x004EC8, 0x004EC9, 0x000000, 0xFFFFFF, + 0x004ECC, 0x004ECC, 0x000000, 0xFFFFFF, + 0x004ED0, 0x004ED3, 0x000000, 0xFFFFFF, + 0x004EDA, 0x004EDC, 0x000000, 0xFFFFFF, + 0x004EE0, 0x004EE2, 0x000000, 0xFFFFFF, + 0x004EE6, 0x004EEC, 0x000000, 0xFFFFFF, + 0x004EEF, 0x004EEF, 0x000000, 0xFFFFFF, + 0x004EF1, 0x004EF1, 0x000000, 0xFFFFFF, + 0x004EF3, 0x004EF5, 0x000000, 0xFFFFFF, + 0x004EF8, 0x004EFA, 0x000000, 0xFFFFFF, + 0x004EFC, 0x004F00, 0x000000, 0xFFFFFF, + 0x004F02, 0x004F08, 0x000000, 0xFFFFFF, + 0x004F0B, 0x004F0C, 0x000000, 0xFFFFFF, + 0x004F12, 0x004F19, 0x000000, 0xFFFFFF, + 0x004F1B, 0x004F1B, 0x000000, 0xFFFFFF, + 0x004F1E, 0x004F2E, 0x000000, 0xFFFFFF, + 0x004F31, 0x004F33, 0x000000, 0xFFFFFF, + 0x004F35, 0x004F35, 0x000000, 0xFFFFFF, + 0x004F37, 0x004F37, 0x000000, 0xFFFFFF, + 0x004F39, 0x004F39, 0x000000, 0xFFFFFF, + 0x004F3B, 0x004F3B, 0x000000, 0xFFFFFF, + 0x004F3E, 0x004F42, 0x000000, 0xFFFFFF, + 0x004F44, 0x004F45, 0x000000, 0xFFFFFF, + 0x004F48, 0x004F4C, 0x000000, 0xFFFFFF, + 0x004F52, 0x004F52, 0x000000, 0xFFFFFF, + 0x004F54, 0x004F54, 0x000000, 0xFFFFFF, + 0x004F56, 0x004F56, 0x000000, 0xFFFFFF, + 0x004F58, 0x004F58, 0x000000, 0xFFFFFF, + 0x004F5F, 0x004F68, 0x000000, 0xFFFFFF, + 0x004F6A, 0x004F6E, 0x000000, 0xFFFFFF, + 0x004F71, 0x004F72, 0x000000, 0xFFFFFF, + 0x004F74, 0x004F74, 0x000000, 0xFFFFFF, + 0x004F77, 0x004F7A, 0x000000, 0xFFFFFF, + 0x004F7D, 0x004F7E, 0x000000, 0xFFFFFF, + 0x004F80, 0x004F82, 0x000000, 0xFFFFFF, + 0x004F84, 0x004F85, 0x000000, 0xFFFFFF, + 0x004F87, 0x004F87, 0x000000, 0xFFFFFF, + 0x004F89, 0x004F8A, 0x000000, 0xFFFFFF, + 0x004F8C, 0x004F8C, 0x000000, 0xFFFFFF, + 0x004F8E, 0x004F8E, 0x000000, 0xFFFFFF, + 0x004F90, 0x004F90, 0x000000, 0xFFFFFF, + 0x004F92, 0x004F95, 0x000000, 0xFFFFFF, + 0x004F97, 0x004F97, 0x000000, 0xFFFFFF, + 0x004F99, 0x004F9A, 0x000000, 0xFFFFFF, + 0x004F9C, 0x004F9C, 0x000000, 0xFFFFFF, + 0x004F9E, 0x004F9F, 0x000000, 0xFFFFFF, + 0x004FA2, 0x004FAA, 0x000000, 0xFFFFFF, + 0x004FAC, 0x004FAC, 0x000000, 0xFFFFFF, + 0x004FB0, 0x004FB4, 0x000000, 0xFFFFFF, + 0x004FB7, 0x004FBE, 0x000000, 0xFFFFFF, + 0x004FC0, 0x004FC1, 0x000000, 0xFFFFFF, + 0x004FC5, 0x004FC9, 0x000000, 0xFFFFFF, + 0x004FCB, 0x004FCD, 0x000000, 0xFFFFFF, + 0x004FCF, 0x004FCF, 0x000000, 0xFFFFFF, + 0x004FD2, 0x004FD3, 0x000000, 0xFFFFFF, + 0x004FD5, 0x004FD6, 0x000000, 0xFFFFFF, + 0x004FD9, 0x004FD9, 0x000000, 0xFFFFFF, + 0x004FDC, 0x004FDC, 0x000000, 0xFFFFFF, + 0x004FDE, 0x004FDE, 0x000000, 0xFFFFFF, + 0x004FE0, 0x004FE0, 0x000000, 0xFFFFFF, + 0x004FE2, 0x004FE2, 0x000000, 0xFFFFFF, + 0x004FE6, 0x004FED, 0x000000, 0xFFFFFF, + 0x004FF0, 0x004FF2, 0x000000, 0xFFFFFF, + 0x004FF4, 0x004FF4, 0x000000, 0xFFFFFF, + 0x004FF7, 0x004FF7, 0x000000, 0xFFFFFF, + 0x004FF9, 0x004FF9, 0x000000, 0xFFFFFF, + 0x004FFB, 0x004FFD, 0x000000, 0xFFFFFF, + 0x004FFF, 0x005004, 0x000000, 0xFFFFFF, + 0x005007, 0x005008, 0x000000, 0xFFFFFF, + 0x00500A, 0x00500A, 0x000000, 0xFFFFFF, + 0x00500C, 0x00500C, 0x000000, 0xFFFFFF, + 0x00500E, 0x00500E, 0x000000, 0xFFFFFF, + 0x005010, 0x005010, 0x000000, 0xFFFFFF, + 0x005013, 0x005013, 0x000000, 0xFFFFFF, + 0x005015, 0x005015, 0x000000, 0xFFFFFF, + 0x005017, 0x005018, 0x000000, 0xFFFFFF, + 0x00501B, 0x00501E, 0x000000, 0xFFFFFF, + 0x005020, 0x005020, 0x000000, 0xFFFFFF, + 0x005022, 0x005022, 0x000000, 0xFFFFFF, + 0x005027, 0x005027, 0x000000, 0xFFFFFF, + 0x00502E, 0x005035, 0x000000, 0xFFFFFF, + 0x005037, 0x005038, 0x000000, 0xFFFFFF, + 0x00503A, 0x005042, 0x000000, 0xFFFFFF, + 0x005044, 0x005046, 0x000000, 0xFFFFFF, + 0x00504A, 0x00504E, 0x000000, 0xFFFFFF, + 0x005051, 0x005054, 0x000000, 0xFFFFFF, + 0x005057, 0x005059, 0x000000, 0xFFFFFF, + 0x00505B, 0x00505B, 0x000000, 0xFFFFFF, + 0x00505D, 0x005064, 0x000000, 0xFFFFFF, + 0x005066, 0x00506B, 0x000000, 0xFFFFFF, + 0x00506D, 0x005071, 0x000000, 0xFFFFFF, + 0x005073, 0x005073, 0x000000, 0xFFFFFF, + 0x005077, 0x005077, 0x000000, 0xFFFFFF, + 0x005079, 0x00507C, 0x000000, 0xFFFFFF, + 0x00507E, 0x00507F, 0x000000, 0xFFFFFF, + 0x005081, 0x005084, 0x000000, 0xFFFFFF, + 0x005086, 0x00508C, 0x000000, 0xFFFFFF, + 0x00508E, 0x005090, 0x000000, 0xFFFFFF, + 0x005092, 0x005097, 0x000000, 0xFFFFFF, + 0x00509B, 0x0050AB, 0x000000, 0xFFFFFF, + 0x0050AE, 0x0050B1, 0x000000, 0xFFFFFF, + 0x0050B6, 0x0050B6, 0x000000, 0xFFFFFF, + 0x0050B8, 0x0050BD, 0x000000, 0xFFFFFF, + 0x0050BF, 0x0050C1, 0x000000, 0xFFFFFF, + 0x0050C3, 0x0050C4, 0x000000, 0xFFFFFF, + 0x0050C6, 0x0050C8, 0x000000, 0xFFFFFF, + 0x0050CB, 0x0050CC, 0x000000, 0xFFFFFF, + 0x0050CE, 0x0050CE, 0x000000, 0xFFFFFF, + 0x0050D0, 0x0050D0, 0x000000, 0xFFFFFF, + 0x0050D2, 0x0050D4, 0x000000, 0xFFFFFF, + 0x0050D7, 0x0050D9, 0x000000, 0xFFFFFF, + 0x0050DB, 0x0050DD, 0x000000, 0xFFFFFF, + 0x0050DF, 0x0050E2, 0x000000, 0xFFFFFF, + 0x0050E4, 0x0050E4, 0x000000, 0xFFFFFF, + 0x0050E6, 0x0050E6, 0x000000, 0xFFFFFF, + 0x0050E8, 0x0050EC, 0x000000, 0xFFFFFF, + 0x0050EF, 0x0050F4, 0x000000, 0xFFFFFF, + 0x0050F6, 0x0050F8, 0x000000, 0xFFFFFF, + 0x0050FA, 0x0050FA, 0x000000, 0xFFFFFF, + 0x0050FC, 0x0050FF, 0x000000, 0xFFFFFF, + 0x005103, 0x005103, 0x000000, 0xFFFFFF, + 0x005105, 0x005108, 0x000000, 0xFFFFFF, + 0x00510A, 0x005111, 0x000000, 0xFFFFFF, + 0x005113, 0x005113, 0x000000, 0xFFFFFF, + 0x005117, 0x005117, 0x000000, 0xFFFFFF, + 0x005119, 0x005119, 0x000000, 0xFFFFFF, + 0x00511B, 0x00511E, 0x000000, 0xFFFFFF, + 0x005120, 0x005120, 0x000000, 0xFFFFFF, + 0x005122, 0x005129, 0x000000, 0xFFFFFF, + 0x00512B, 0x005131, 0x000000, 0xFFFFFF, + 0x005133, 0x005136, 0x000000, 0xFFFFFF, + 0x005138, 0x005139, 0x000000, 0xFFFFFF, + 0x00513D, 0x00513E, 0x000000, 0xFFFFFF, + 0x005142, 0x005142, 0x000000, 0xFFFFFF, + 0x00514A, 0x00514A, 0x000000, 0xFFFFFF, + 0x00514F, 0x00514F, 0x000000, 0xFFFFFF, + 0x005151, 0x005151, 0x000000, 0xFFFFFF, + 0x005153, 0x005153, 0x000000, 0xFFFFFF, + 0x005155, 0x005159, 0x000000, 0xFFFFFF, + 0x00515B, 0x00515B, 0x000000, 0xFFFFFF, + 0x00515D, 0x005161, 0x000000, 0xFFFFFF, + 0x005163, 0x005164, 0x000000, 0xFFFFFF, + 0x005166, 0x005167, 0x000000, 0xFFFFFF, + 0x00516F, 0x005170, 0x000000, 0xFFFFFF, + 0x005172, 0x005174, 0x000000, 0xFFFFFF, + 0x005179, 0x00517B, 0x000000, 0xFFFFFF, + 0x00517D, 0x00517F, 0x000000, 0xFFFFFF, + 0x005181, 0x005181, 0x000000, 0xFFFFFF, + 0x005183, 0x005184, 0x000000, 0xFFFFFF, + 0x005187, 0x005188, 0x000000, 0xFFFFFF, + 0x00518B, 0x00518B, 0x000000, 0xFFFFFF, + 0x00518E, 0x00518E, 0x000000, 0xFFFFFF, + 0x005194, 0x005194, 0x000000, 0xFFFFFF, + 0x005198, 0x005198, 0x000000, 0xFFFFFF, + 0x00519A, 0x00519F, 0x000000, 0xFFFFFF, + 0x0051A1, 0x0051A1, 0x000000, 0xFFFFFF, + 0x0051A3, 0x0051A3, 0x000000, 0xFFFFFF, + 0x0051A7, 0x0051A7, 0x000000, 0xFFFFFF, + 0x0051AD, 0x0051AF, 0x000000, 0xFFFFFF, + 0x0051B8, 0x0051BC, 0x000000, 0xFFFFFF, + 0x0051BE, 0x0051C3, 0x000000, 0xFFFFFF, + 0x0051C7, 0x0051C8, 0x000000, 0xFFFFFF, + 0x0051CA, 0x0051CA, 0x000000, 0xFFFFFF, + 0x0051CE, 0x0051D5, 0x000000, 0xFFFFFF, + 0x0051D7, 0x0051DA, 0x000000, 0xFFFFFF, + 0x0051DE, 0x0051DF, 0x000000, 0xFFFFFF, + 0x0051E2, 0x0051E5, 0x000000, 0xFFFFFF, + 0x0051E8, 0x0051E8, 0x000000, 0xFFFFFF, + 0x0051EB, 0x0051EC, 0x000000, 0xFFFFFF, + 0x0051EE, 0x0051EF, 0x000000, 0xFFFFFF, + 0x0051F2, 0x0051F4, 0x000000, 0xFFFFFF, + 0x0051F7, 0x0051F7, 0x000000, 0xFFFFFF, + 0x0051FB, 0x0051FC, 0x000000, 0xFFFFFF, + 0x0051FF, 0x0051FF, 0x000000, 0xFFFFFF, + 0x005201, 0x005202, 0x000000, 0xFFFFFF, + 0x005205, 0x005205, 0x000000, 0xFFFFFF, + 0x005209, 0x005209, 0x000000, 0xFFFFFF, + 0x00520C, 0x00520D, 0x000000, 0xFFFFFF, + 0x00520F, 0x005210, 0x000000, 0xFFFFFF, + 0x005212, 0x005213, 0x000000, 0xFFFFFF, + 0x005215, 0x005216, 0x000000, 0xFFFFFF, + 0x005218, 0x00521C, 0x000000, 0xFFFFFF, + 0x00521E, 0x005223, 0x000000, 0xFFFFFF, + 0x005226, 0x005226, 0x000000, 0xFFFFFF, + 0x005228, 0x005228, 0x000000, 0xFFFFFF, + 0x00522B, 0x00522D, 0x000000, 0xFFFFFF, + 0x00522F, 0x00522F, 0x000000, 0xFFFFFF, + 0x005231, 0x005232, 0x000000, 0xFFFFFF, + 0x005234, 0x005235, 0x000000, 0xFFFFFF, + 0x00523C, 0x005242, 0x000000, 0xFFFFFF, + 0x005245, 0x005246, 0x000000, 0xFFFFFF, + 0x005248, 0x005249, 0x000000, 0xFFFFFF, + 0x00524E, 0x00524E, 0x000000, 0xFFFFFF, + 0x005250, 0x005253, 0x000000, 0xFFFFFF, + 0x005255, 0x005255, 0x000000, 0xFFFFFF, + 0x005257, 0x00525A, 0x000000, 0xFFFFFF, + 0x00525C, 0x00525D, 0x000000, 0xFFFFFF, + 0x00525F, 0x005262, 0x000000, 0xFFFFFF, + 0x005266, 0x005268, 0x000000, 0xFFFFFF, + 0x00526B, 0x00526E, 0x000000, 0xFFFFFF, + 0x005276, 0x00527C, 0x000000, 0xFFFFFF, + 0x00527E, 0x00527E, 0x000000, 0xFFFFFF, + 0x005280, 0x005282, 0x000000, 0xFFFFFF, + 0x005284, 0x005286, 0x000000, 0xFFFFFF, + 0x00528A, 0x00528C, 0x000000, 0xFFFFFF, + 0x00528E, 0x005290, 0x000000, 0xFFFFFF, + 0x005293, 0x005293, 0x000000, 0xFFFFFF, + 0x005295, 0x00529A, 0x000000, 0xFFFFFF, + 0x00529C, 0x00529E, 0x000000, 0xFFFFFF, + 0x0052A1, 0x0052A2, 0x000000, 0xFFFFFF, + 0x0052A4, 0x0052A8, 0x000000, 0xFFFFFF, + 0x0052AE, 0x0052B0, 0x000000, 0xFFFFFF, + 0x0052B2, 0x0052B3, 0x000000, 0xFFFFFF, + 0x0052B6, 0x0052B8, 0x000000, 0xFFFFFF, + 0x0052BA, 0x0052BB, 0x000000, 0xFFFFFF, + 0x0052BD, 0x0052BD, 0x000000, 0xFFFFFF, + 0x0052BF, 0x0052C0, 0x000000, 0xFFFFFF, + 0x0052C2, 0x0052C2, 0x000000, 0xFFFFFF, + 0x0052C4, 0x0052C4, 0x000000, 0xFFFFFF, + 0x0052C6, 0x0052C6, 0x000000, 0xFFFFFF, + 0x0052C8, 0x0052C8, 0x000000, 0xFFFFFF, + 0x0052CA, 0x0052CC, 0x000000, 0xFFFFFF, + 0x0052CE, 0x0052D1, 0x000000, 0xFFFFFF, + 0x0052D3, 0x0052D4, 0x000000, 0xFFFFFF, + 0x0052D6, 0x0052D6, 0x000000, 0xFFFFFF, + 0x0052DA, 0x0052DC, 0x000000, 0xFFFFFF, + 0x0052E1, 0x0052E1, 0x000000, 0xFFFFFF, + 0x0052E5, 0x0052E5, 0x000000, 0xFFFFFF, + 0x0052E8, 0x0052F1, 0x000000, 0xFFFFFF, + 0x0052F4, 0x0052F4, 0x000000, 0xFFFFFF, + 0x0052F6, 0x0052F7, 0x000000, 0xFFFFFF, + 0x0052FB, 0x0052FD, 0x000000, 0xFFFFFF, + 0x005300, 0x005300, 0x000000, 0xFFFFFF, + 0x005303, 0x005304, 0x000000, 0xFFFFFF, + 0x005307, 0x005307, 0x000000, 0xFFFFFF, + 0x005309, 0x00530C, 0x000000, 0xFFFFFF, + 0x00530E, 0x00530E, 0x000000, 0xFFFFFF, + 0x005311, 0x005314, 0x000000, 0xFFFFFF, + 0x005318, 0x005318, 0x000000, 0xFFFFFF, + 0x00531B, 0x00531C, 0x000000, 0xFFFFFF, + 0x00531E, 0x00531F, 0x000000, 0xFFFFFF, + 0x005322, 0x005322, 0x000000, 0xFFFFFF, + 0x005324, 0x005329, 0x000000, 0xFFFFFF, + 0x00532B, 0x00532E, 0x000000, 0xFFFFFF, + 0x005330, 0x005330, 0x000000, 0xFFFFFF, + 0x005332, 0x005332, 0x000000, 0xFFFFFF, + 0x005334, 0x005337, 0x000000, 0xFFFFFF, + 0x00533C, 0x00533E, 0x000000, 0xFFFFFF, + 0x005342, 0x005342, 0x000000, 0xFFFFFF, + 0x005344, 0x005344, 0x000000, 0xFFFFFF, + 0x00534B, 0x00534C, 0x000000, 0xFFFFFF, + 0x00534E, 0x005350, 0x000000, 0xFFFFFF, + 0x005355, 0x005356, 0x000000, 0xFFFFFF, + 0x005359, 0x005359, 0x000000, 0xFFFFFF, + 0x00535B, 0x00535B, 0x000000, 0xFFFFFF, + 0x00535D, 0x00535D, 0x000000, 0xFFFFFF, + 0x00535F, 0x00535F, 0x000000, 0xFFFFFF, + 0x005361, 0x005365, 0x000000, 0xFFFFFF, + 0x005367, 0x005368, 0x000000, 0xFFFFFF, + 0x00536A, 0x00536D, 0x000000, 0xFFFFFF, + 0x005372, 0x005372, 0x000000, 0xFFFFFF, + 0x005376, 0x005376, 0x000000, 0xFFFFFF, + 0x005379, 0x00537A, 0x000000, 0xFFFFFF, + 0x00537C, 0x00537E, 0x000000, 0xFFFFFF, + 0x005380, 0x005381, 0x000000, 0xFFFFFF, + 0x005383, 0x005383, 0x000000, 0xFFFFFF, + 0x005385, 0x005395, 0x000000, 0xFFFFFF, + 0x005397, 0x005397, 0x000000, 0xFFFFFF, + 0x005399, 0x005399, 0x000000, 0xFFFFFF, + 0x00539B, 0x00539E, 0x000000, 0xFFFFFF, + 0x0053A1, 0x0053A4, 0x000000, 0xFFFFFF, + 0x0053A7, 0x0053A7, 0x000000, 0xFFFFFF, + 0x0053AA, 0x0053AC, 0x000000, 0xFFFFFF, + 0x0053AF, 0x0053AF, 0x000000, 0xFFFFFF, + 0x0053B1, 0x0053B2, 0x000000, 0xFFFFFF, + 0x0053B4, 0x0053B5, 0x000000, 0xFFFFFF, + 0x0053B7, 0x0053BA, 0x000000, 0xFFFFFF, + 0x0053BC, 0x0053C1, 0x000000, 0xFFFFFF, + 0x0053C4, 0x0053C7, 0x000000, 0xFFFFFF, + 0x0053CF, 0x0053D3, 0x000000, 0xFFFFFF, + 0x0053D5, 0x0053D5, 0x000000, 0xFFFFFF, + 0x0053D8, 0x0053D8, 0x000000, 0xFFFFFF, + 0x0053DA, 0x0053DA, 0x000000, 0xFFFFFF, + 0x0053DC, 0x0053DE, 0x000000, 0xFFFFFF, + 0x0053E0, 0x0053E0, 0x000000, 0xFFFFFF, + 0x0053E6, 0x0053E7, 0x000000, 0xFFFFFF, + 0x0053F4, 0x0053F5, 0x000000, 0xFFFFFF, + 0x0053F9, 0x0053F9, 0x000000, 0xFFFFFF, + 0x0053FB, 0x005400, 0x000000, 0xFFFFFF, + 0x005402, 0x005402, 0x000000, 0xFFFFFF, + 0x005405, 0x005407, 0x000000, 0xFFFFFF, + 0x005412, 0x00541A, 0x000000, 0xFFFFFF, + 0x00541C, 0x00541C, 0x000000, 0xFFFFFF, + 0x00541E, 0x00541E, 0x000000, 0xFFFFFF, + 0x005421, 0x005425, 0x000000, 0xFFFFFF, + 0x005427, 0x005428, 0x000000, 0xFFFFFF, + 0x00542A, 0x00542A, 0x000000, 0xFFFFFF, + 0x00542F, 0x005435, 0x000000, 0xFFFFFF, + 0x005437, 0x005437, 0x000000, 0xFFFFFF, + 0x00543A, 0x00543A, 0x000000, 0xFFFFFF, + 0x00543F, 0x00543F, 0x000000, 0xFFFFFF, + 0x005441, 0x005441, 0x000000, 0xFFFFFF, + 0x005443, 0x005445, 0x000000, 0xFFFFFF, + 0x005447, 0x005447, 0x000000, 0xFFFFFF, + 0x00544B, 0x00544D, 0x000000, 0xFFFFFF, + 0x00544F, 0x005450, 0x000000, 0xFFFFFF, + 0x005452, 0x00545E, 0x000000, 0xFFFFFF, + 0x005460, 0x005467, 0x000000, 0xFFFFFF, + 0x005469, 0x005469, 0x000000, 0xFFFFFF, + 0x00546B, 0x00546F, 0x000000, 0xFFFFFF, + 0x005472, 0x005472, 0x000000, 0xFFFFFF, + 0x005474, 0x005474, 0x000000, 0xFFFFFF, + 0x005478, 0x00547A, 0x000000, 0xFFFFFF, + 0x00547E, 0x00547F, 0x000000, 0xFFFFFF, + 0x005481, 0x005483, 0x000000, 0xFFFFFF, + 0x005485, 0x005485, 0x000000, 0xFFFFFF, + 0x005487, 0x00548A, 0x000000, 0xFFFFFF, + 0x00548D, 0x00548D, 0x000000, 0xFFFFFF, + 0x005491, 0x005491, 0x000000, 0xFFFFFF, + 0x005493, 0x0054A1, 0x000000, 0xFFFFFF, + 0x0054A3, 0x0054A3, 0x000000, 0xFFFFFF, + 0x0054A6, 0x0054A7, 0x000000, 0xFFFFFF, + 0x0054A9, 0x0054AA, 0x000000, 0xFFFFFF, + 0x0054AD, 0x0054AE, 0x000000, 0xFFFFFF, + 0x0054B0, 0x0054B1, 0x000000, 0xFFFFFF, + 0x0054B4, 0x0054B7, 0x000000, 0xFFFFFF, + 0x0054B9, 0x0054BB, 0x000000, 0xFFFFFF, + 0x0054BF, 0x0054BF, 0x000000, 0xFFFFFF, + 0x0054C3, 0x0054C3, 0x000000, 0xFFFFFF, + 0x0054C5, 0x0054C6, 0x000000, 0xFFFFFF, + 0x0054CA, 0x0054D7, 0x000000, 0xFFFFFF, + 0x0054D9, 0x0054E0, 0x000000, 0xFFFFFF, + 0x0054E3, 0x0054E4, 0x000000, 0xFFFFFF, + 0x0054E7, 0x0054E7, 0x000000, 0xFFFFFF, + 0x0054EA, 0x0054EC, 0x000000, 0xFFFFFF, + 0x0054EF, 0x0054F1, 0x000000, 0xFFFFFF, + 0x0054F3, 0x0054F9, 0x000000, 0xFFFFFF, + 0x0054FB, 0x0054FC, 0x000000, 0xFFFFFF, + 0x0054FE, 0x005503, 0x000000, 0xFFFFFF, + 0x005505, 0x005505, 0x000000, 0xFFFFFF, + 0x005508, 0x00550E, 0x000000, 0xFFFFFF, + 0x005511, 0x005513, 0x000000, 0xFFFFFF, + 0x005515, 0x005515, 0x000000, 0xFFFFFF, + 0x005517, 0x00552D, 0x000000, 0xFFFFFF, + 0x005530, 0x005530, 0x000000, 0xFFFFFF, + 0x005532, 0x005532, 0x000000, 0xFFFFFF, + 0x005534, 0x005537, 0x000000, 0xFFFFFF, + 0x00553A, 0x00553D, 0x000000, 0xFFFFFF, + 0x00553F, 0x00553F, 0x000000, 0xFFFFFF, + 0x005541, 0x005543, 0x000000, 0xFFFFFF, + 0x005547, 0x00554B, 0x000000, 0xFFFFFF, + 0x00554D, 0x00554E, 0x000000, 0xFFFFFF, + 0x005550, 0x005552, 0x000000, 0xFFFFFF, + 0x005554, 0x005555, 0x000000, 0xFFFFFF, + 0x005558, 0x00555B, 0x000000, 0xFFFFFF, + 0x00555E, 0x005562, 0x000000, 0xFFFFFF, + 0x005564, 0x00557A, 0x000000, 0xFFFFFF, + 0x00557D, 0x00557D, 0x000000, 0xFFFFFF, + 0x00557F, 0x00557F, 0x000000, 0xFFFFFF, + 0x005581, 0x005582, 0x000000, 0xFFFFFF, + 0x005585, 0x005586, 0x000000, 0xFFFFFF, + 0x005588, 0x005588, 0x000000, 0xFFFFFF, + 0x00558C, 0x005597, 0x000000, 0xFFFFFF, + 0x00559B, 0x00559B, 0x000000, 0xFFFFFF, + 0x0055A0, 0x0055A6, 0x000000, 0xFFFFFF, + 0x0055AD, 0x0055AD, 0x000000, 0xFFFFFF, + 0x0055AF, 0x0055AF, 0x000000, 0xFFFFFF, + 0x0055B1, 0x0055B5, 0x000000, 0xFFFFFF, + 0x0055B7, 0x0055C3, 0x000000, 0xFFFFFF, + 0x0055C6, 0x0055C6, 0x000000, 0xFFFFFF, + 0x0055C8, 0x0055D3, 0x000000, 0xFFFFFF, + 0x0055D5, 0x0055D9, 0x000000, 0xFFFFFF, + 0x0055DB, 0x0055DB, 0x000000, 0xFFFFFF, + 0x0055DD, 0x0055DE, 0x000000, 0xFFFFFF, + 0x0055E0, 0x0055E2, 0x000000, 0xFFFFFF, + 0x0055E5, 0x0055F6, 0x000000, 0xFFFFFF, + 0x0055F8, 0x0055F8, 0x000000, 0xFFFFFF, + 0x0055FA, 0x0055FC, 0x000000, 0xFFFFFF, + 0x0055FF, 0x005605, 0x000000, 0xFFFFFF, + 0x005607, 0x005608, 0x000000, 0xFFFFFF, + 0x00560A, 0x005613, 0x000000, 0xFFFFFF, + 0x005615, 0x005615, 0x000000, 0xFFFFFF, + 0x005619, 0x00561A, 0x000000, 0xFFFFFF, + 0x00561C, 0x005628, 0x000000, 0xFFFFFF, + 0x00562A, 0x00562E, 0x000000, 0xFFFFFF, + 0x005630, 0x005630, 0x000000, 0xFFFFFF, + 0x005633, 0x005633, 0x000000, 0xFFFFFF, + 0x005635, 0x005635, 0x000000, 0xFFFFFF, + 0x005637, 0x005637, 0x000000, 0xFFFFFF, + 0x005639, 0x005641, 0x000000, 0xFFFFFF, + 0x005643, 0x00564B, 0x000000, 0xFFFFFF, + 0x00564D, 0x00564D, 0x000000, 0xFFFFFF, + 0x00564F, 0x00564F, 0x000000, 0xFFFFFF, + 0x005651, 0x00565A, 0x000000, 0xFFFFFF, + 0x00565C, 0x005663, 0x000000, 0xFFFFFF, + 0x005665, 0x005667, 0x000000, 0xFFFFFF, + 0x005669, 0x005669, 0x000000, 0xFFFFFF, + 0x00566D, 0x005673, 0x000000, 0xFFFFFF, + 0x005675, 0x005677, 0x000000, 0xFFFFFF, + 0x005679, 0x005679, 0x000000, 0xFFFFFF, + 0x00567B, 0x00567F, 0x000000, 0xFFFFFF, + 0x005681, 0x005685, 0x000000, 0xFFFFFF, + 0x005688, 0x005689, 0x000000, 0xFFFFFF, + 0x00568B, 0x00568E, 0x000000, 0xFFFFFF, + 0x005690, 0x005693, 0x000000, 0xFFFFFF, + 0x005695, 0x00569F, 0x000000, 0xFFFFFF, + 0x0056A1, 0x0056A1, 0x000000, 0xFFFFFF, + 0x0056A3, 0x0056A4, 0x000000, 0xFFFFFF, + 0x0056A6, 0x0056AD, 0x000000, 0xFFFFFF, + 0x0056AF, 0x0056B3, 0x000000, 0xFFFFFF, + 0x0056B5, 0x0056B5, 0x000000, 0xFFFFFF, + 0x0056B7, 0x0056BB, 0x000000, 0xFFFFFF, + 0x0056BD, 0x0056BF, 0x000000, 0xFFFFFF, + 0x0056C4, 0x0056C7, 0x000000, 0xFFFFFF, + 0x0056C9, 0x0056CD, 0x000000, 0xFFFFFF, + 0x0056CF, 0x0056D0, 0x000000, 0xFFFFFF, + 0x0056D2, 0x0056D2, 0x000000, 0xFFFFFF, + 0x0056D4, 0x0056D6, 0x000000, 0xFFFFFF, + 0x0056D9, 0x0056D9, 0x000000, 0xFFFFFF, + 0x0056DC, 0x0056DD, 0x000000, 0xFFFFFF, + 0x0056DF, 0x0056DF, 0x000000, 0xFFFFFF, + 0x0056E1, 0x0056E2, 0x000000, 0xFFFFFF, + 0x0056E4, 0x0056ED, 0x000000, 0xFFFFFF, + 0x0056EF, 0x0056EF, 0x000000, 0xFFFFFF, + 0x0056F1, 0x0056F1, 0x000000, 0xFFFFFF, + 0x0056F4, 0x0056F8, 0x000000, 0xFFFFFF, + 0x0056FB, 0x0056FC, 0x000000, 0xFFFFFF, + 0x0056FE, 0x0056FE, 0x000000, 0xFFFFFF, + 0x005701, 0x005702, 0x000000, 0xFFFFFF, + 0x005705, 0x005707, 0x000000, 0xFFFFFF, + 0x00570A, 0x00570A, 0x000000, 0xFFFFFF, + 0x00570C, 0x00570C, 0x000000, 0xFFFFFF, + 0x00570E, 0x00570E, 0x000000, 0xFFFFFF, + 0x005710, 0x005711, 0x000000, 0xFFFFFF, + 0x005714, 0x005715, 0x000000, 0xFFFFFF, + 0x005717, 0x005717, 0x000000, 0xFFFFFF, + 0x005719, 0x00571B, 0x000000, 0xFFFFFF, + 0x00571D, 0x00571E, 0x000000, 0xFFFFFF, + 0x005720, 0x005725, 0x000000, 0xFFFFFF, + 0x005729, 0x00572C, 0x000000, 0xFFFFFF, + 0x00572E, 0x00572F, 0x000000, 0xFFFFFF, + 0x005731, 0x005736, 0x000000, 0xFFFFFF, + 0x005739, 0x00573A, 0x000000, 0xFFFFFF, + 0x00573C, 0x00573F, 0x000000, 0xFFFFFF, + 0x005741, 0x005741, 0x000000, 0xFFFFFF, + 0x005743, 0x005746, 0x000000, 0xFFFFFF, + 0x005748, 0x005749, 0x000000, 0xFFFFFF, + 0x00574B, 0x00574D, 0x000000, 0xFFFFFF, + 0x005752, 0x005760, 0x000000, 0xFFFFFF, + 0x005762, 0x005763, 0x000000, 0xFFFFFF, + 0x005765, 0x005765, 0x000000, 0xFFFFFF, + 0x005767, 0x005768, 0x000000, 0xFFFFFF, + 0x00576B, 0x00577E, 0x000000, 0xFFFFFF, + 0x005780, 0x005781, 0x000000, 0xFFFFFF, + 0x005783, 0x005787, 0x000000, 0xFFFFFF, + 0x00578A, 0x00578A, 0x000000, 0xFFFFFF, + 0x00578C, 0x005792, 0x000000, 0xFFFFFF, + 0x005794, 0x00579F, 0x000000, 0xFFFFFF, + 0x0057A1, 0x0057A1, 0x000000, 0xFFFFFF, + 0x0057A5, 0x0057A9, 0x000000, 0xFFFFFF, + 0x0057AB, 0x0057AF, 0x000000, 0xFFFFFF, + 0x0057B1, 0x0057B2, 0x000000, 0xFFFFFF, + 0x0057B4, 0x0057BF, 0x000000, 0xFFFFFF, + 0x0057C1, 0x0057C2, 0x000000, 0xFFFFFF, + 0x0057C4, 0x0057C5, 0x000000, 0xFFFFFF, + 0x0057C7, 0x0057CA, 0x000000, 0xFFFFFF, + 0x0057CC, 0x0057CD, 0x000000, 0xFFFFFF, + 0x0057CF, 0x0057D1, 0x000000, 0xFFFFFF, + 0x0057D5, 0x0057D5, 0x000000, 0xFFFFFF, + 0x0057D7, 0x0057DB, 0x000000, 0xFFFFFF, + 0x0057DD, 0x0057DE, 0x000000, 0xFFFFFF, + 0x0057E1, 0x0057E2, 0x000000, 0xFFFFFF, + 0x0057E4, 0x0057F3, 0x000000, 0xFFFFFF, + 0x0057F5, 0x0057F6, 0x000000, 0xFFFFFF, + 0x0057F8, 0x0057F8, 0x000000, 0xFFFFFF, + 0x0057FB, 0x0057FB, 0x000000, 0xFFFFFF, + 0x0057FD, 0x0057FF, 0x000000, 0xFFFFFF, + 0x005801, 0x005801, 0x000000, 0xFFFFFF, + 0x005803, 0x005804, 0x000000, 0xFFFFFF, + 0x005807, 0x005809, 0x000000, 0xFFFFFF, + 0x00580C, 0x005814, 0x000000, 0xFFFFFF, + 0x005816, 0x005818, 0x000000, 0xFFFFFF, + 0x00581A, 0x00581C, 0x000000, 0xFFFFFF, + 0x00581E, 0x005820, 0x000000, 0xFFFFFF, + 0x005822, 0x005823, 0x000000, 0xFFFFFF, + 0x005825, 0x005829, 0x000000, 0xFFFFFF, + 0x00582B, 0x00582E, 0x000000, 0xFFFFFF, + 0x005832, 0x005833, 0x000000, 0xFFFFFF, + 0x005836, 0x005839, 0x000000, 0xFFFFFF, + 0x00583B, 0x00583C, 0x000000, 0xFFFFFF, + 0x00583E, 0x00583F, 0x000000, 0xFFFFFF, + 0x005842, 0x005849, 0x000000, 0xFFFFFF, + 0x00584C, 0x005850, 0x000000, 0xFFFFFF, + 0x005853, 0x005853, 0x000000, 0xFFFFFF, + 0x005855, 0x005856, 0x000000, 0xFFFFFF, + 0x00585B, 0x00585D, 0x000000, 0xFFFFFF, + 0x00585F, 0x005861, 0x000000, 0xFFFFFF, + 0x005863, 0x005868, 0x000000, 0xFFFFFF, + 0x00586A, 0x00586A, 0x000000, 0xFFFFFF, + 0x00586C, 0x00586F, 0x000000, 0xFFFFFF, + 0x005871, 0x005871, 0x000000, 0xFFFFFF, + 0x005873, 0x005874, 0x000000, 0xFFFFFF, + 0x005876, 0x005878, 0x000000, 0xFFFFFF, + 0x00587A, 0x00587D, 0x000000, 0xFFFFFF, + 0x00587F, 0x005882, 0x000000, 0xFFFFFF, + 0x005884, 0x005884, 0x000000, 0xFFFFFF, + 0x005886, 0x005892, 0x000000, 0xFFFFFF, + 0x005894, 0x005896, 0x000000, 0xFFFFFF, + 0x005898, 0x00589B, 0x000000, 0xFFFFFF, + 0x00589D, 0x00589E, 0x000000, 0xFFFFFF, + 0x0058A0, 0x0058A7, 0x000000, 0xFFFFFF, + 0x0058A9, 0x0058AA, 0x000000, 0xFFFFFF, + 0x0058AC, 0x0058AD, 0x000000, 0xFFFFFF, + 0x0058AF, 0x0058B2, 0x000000, 0xFFFFFF, + 0x0058B4, 0x0058B7, 0x000000, 0xFFFFFF, + 0x0058BC, 0x0058BD, 0x000000, 0xFFFFFF, + 0x0058BF, 0x0058C0, 0x000000, 0xFFFFFF, + 0x0058C2, 0x0058C4, 0x000000, 0xFFFFFF, + 0x0058C6, 0x0058C6, 0x000000, 0xFFFFFF, + 0x0058C8, 0x0058C9, 0x000000, 0xFFFFFF, + 0x0058CB, 0x0058CB, 0x000000, 0xFFFFFF, + 0x0058CD, 0x0058D0, 0x000000, 0xFFFFFF, + 0x0058D2, 0x0058D2, 0x000000, 0xFFFFFF, + 0x0058D4, 0x0058D4, 0x000000, 0xFFFFFF, + 0x0058D6, 0x0058D6, 0x000000, 0xFFFFFF, + 0x0058DA, 0x0058DB, 0x000000, 0xFFFFFF, + 0x0058DD, 0x0058DD, 0x000000, 0xFFFFFF, + 0x0058E0, 0x0058E3, 0x000000, 0xFFFFFF, + 0x0058E6, 0x0058EA, 0x000000, 0xFFFFFF, + 0x0058ED, 0x0058ED, 0x000000, 0xFFFFFF, + 0x0058F3, 0x0058F6, 0x000000, 0xFFFFFF, + 0x0058F8, 0x0058F8, 0x000000, 0xFFFFFF, + 0x0058FE, 0x005901, 0x000000, 0xFFFFFF, + 0x005903, 0x005908, 0x000000, 0xFFFFFF, + 0x00590B, 0x00590E, 0x000000, 0xFFFFFF, + 0x005911, 0x005914, 0x000000, 0xFFFFFF, + 0x005917, 0x005917, 0x000000, 0xFFFFFF, + 0x00591D, 0x005921, 0x000000, 0xFFFFFF, + 0x005923, 0x005924, 0x000000, 0xFFFFFF, + 0x005926, 0x005926, 0x000000, 0xFFFFFF, + 0x005928, 0x005928, 0x000000, 0xFFFFFF, + 0x00592F, 0x005930, 0x000000, 0xFFFFFF, + 0x005933, 0x005936, 0x000000, 0xFFFFFF, + 0x005939, 0x00593D, 0x000000, 0xFFFFFF, + 0x00593F, 0x005943, 0x000000, 0xFFFFFF, + 0x005945, 0x005946, 0x000000, 0xFFFFFF, + 0x00594A, 0x00594D, 0x000000, 0xFFFFFF, + 0x005952, 0x005953, 0x000000, 0xFFFFFF, + 0x005956, 0x005956, 0x000000, 0xFFFFFF, + 0x005959, 0x005959, 0x000000, 0xFFFFFF, + 0x00595B, 0x00595F, 0x000000, 0xFFFFFF, + 0x005961, 0x005961, 0x000000, 0xFFFFFF, + 0x005963, 0x005964, 0x000000, 0xFFFFFF, + 0x005966, 0x005966, 0x000000, 0xFFFFFF, + 0x00596B, 0x00596B, 0x000000, 0xFFFFFF, + 0x00596D, 0x00596D, 0x000000, 0xFFFFFF, + 0x00596F, 0x005972, 0x000000, 0xFFFFFF, + 0x005975, 0x005977, 0x000000, 0xFFFFFF, + 0x005979, 0x00597C, 0x000000, 0xFFFFFF, + 0x00597E, 0x005980, 0x000000, 0xFFFFFF, + 0x005985, 0x005989, 0x000000, 0xFFFFFF, + 0x00598B, 0x00598C, 0x000000, 0xFFFFFF, + 0x00598E, 0x005992, 0x000000, 0xFFFFFF, + 0x005994, 0x005995, 0x000000, 0xFFFFFF, + 0x005997, 0x005998, 0x000000, 0xFFFFFF, + 0x00599A, 0x00599A, 0x000000, 0xFFFFFF, + 0x00599C, 0x00599C, 0x000000, 0xFFFFFF, + 0x00599E, 0x0059A2, 0x000000, 0xFFFFFF, + 0x0059A4, 0x0059A4, 0x000000, 0xFFFFFF, + 0x0059A6, 0x0059A7, 0x000000, 0xFFFFFF, + 0x0059A9, 0x0059AB, 0x000000, 0xFFFFFF, + 0x0059AD, 0x0059B1, 0x000000, 0xFFFFFF, + 0x0059B3, 0x0059B8, 0x000000, 0xFFFFFF, + 0x0059BA, 0x0059BA, 0x000000, 0xFFFFFF, + 0x0059BC, 0x0059BD, 0x000000, 0xFFFFFF, + 0x0059BF, 0x0059C5, 0x000000, 0xFFFFFF, + 0x0059C7, 0x0059C8, 0x000000, 0xFFFFFF, + 0x0059CA, 0x0059CA, 0x000000, 0xFFFFFF, + 0x0059CC, 0x0059CF, 0x000000, 0xFFFFFF, + 0x0059D2, 0x0059D2, 0x000000, 0xFFFFFF, + 0x0059D5, 0x0059D8, 0x000000, 0xFFFFFF, + 0x0059DB, 0x0059DB, 0x000000, 0xFFFFFF, + 0x0059DD, 0x0059E4, 0x000000, 0xFFFFFF, + 0x0059E7, 0x0059E7, 0x000000, 0xFFFFFF, + 0x0059E9, 0x0059E9, 0x000000, 0xFFFFFF, + 0x0059EC, 0x0059F5, 0x000000, 0xFFFFFF, + 0x0059F7, 0x0059FA, 0x000000, 0xFFFFFF, + 0x0059FC, 0x0059FE, 0x000000, 0xFFFFFF, + 0x005A00, 0x005A00, 0x000000, 0xFFFFFF, + 0x005A02, 0x005A02, 0x000000, 0xFFFFFF, + 0x005A04, 0x005A08, 0x000000, 0xFFFFFF, + 0x005A0A, 0x005A10, 0x000000, 0xFFFFFF, + 0x005A12, 0x005A17, 0x000000, 0xFFFFFF, + 0x005A19, 0x005A19, 0x000000, 0xFFFFFF, + 0x005A1B, 0x005A1B, 0x000000, 0xFFFFFF, + 0x005A1D, 0x005A1E, 0x000000, 0xFFFFFF, + 0x005A21, 0x005A24, 0x000000, 0xFFFFFF, + 0x005A26, 0x005A28, 0x000000, 0xFFFFFF, + 0x005A2A, 0x005A2E, 0x000000, 0xFFFFFF, + 0x005A30, 0x005A34, 0x000000, 0xFFFFFF, + 0x005A37, 0x005A3B, 0x000000, 0xFFFFFF, + 0x005A3D, 0x005A3F, 0x000000, 0xFFFFFF, + 0x005A42, 0x005A45, 0x000000, 0xFFFFFF, + 0x005A47, 0x005A48, 0x000000, 0xFFFFFF, + 0x005A4A, 0x005A59, 0x000000, 0xFFFFFF, + 0x005A5B, 0x005A61, 0x000000, 0xFFFFFF, + 0x005A63, 0x005A65, 0x000000, 0xFFFFFF, + 0x005A67, 0x005A69, 0x000000, 0xFFFFFF, + 0x005A6B, 0x005A6B, 0x000000, 0xFFFFFF, + 0x005A6D, 0x005A7E, 0x000000, 0xFFFFFF, + 0x005A80, 0x005A91, 0x000000, 0xFFFFFF, + 0x005A93, 0x005A99, 0x000000, 0xFFFFFF, + 0x005A9C, 0x005ABB, 0x000000, 0xFFFFFF, + 0x005ABF, 0x005AC0, 0x000000, 0xFFFFFF, + 0x005AC3, 0x005AC8, 0x000000, 0xFFFFFF, + 0x005ACA, 0x005ACA, 0x000000, 0xFFFFFF, + 0x005ACD, 0x005ACF, 0x000000, 0xFFFFFF, + 0x005AD1, 0x005AD5, 0x000000, 0xFFFFFF, + 0x005AD8, 0x005AE0, 0x000000, 0xFFFFFF, + 0x005AE2, 0x005AE2, 0x000000, 0xFFFFFF, + 0x005AE4, 0x005AE5, 0x000000, 0xFFFFFF, + 0x005AE7, 0x005AE8, 0x000000, 0xFFFFFF, + 0x005AEA, 0x005AF9, 0x000000, 0xFFFFFF, + 0x005AFC, 0x005B08, 0x000000, 0xFFFFFF, + 0x005B0A, 0x005B0A, 0x000000, 0xFFFFFF, + 0x005B0D, 0x005B15, 0x000000, 0xFFFFFF, + 0x005B17, 0x005B21, 0x000000, 0xFFFFFF, + 0x005B23, 0x005B29, 0x000000, 0xFFFFFF, + 0x005B2B, 0x005B2B, 0x000000, 0xFFFFFF, + 0x005B2D, 0x005B2F, 0x000000, 0xFFFFFF, + 0x005B31, 0x005B31, 0x000000, 0xFFFFFF, + 0x005B33, 0x005B35, 0x000000, 0xFFFFFF, + 0x005B37, 0x005B3D, 0x000000, 0xFFFFFF, + 0x005B3F, 0x005B3F, 0x000000, 0xFFFFFF, + 0x005B41, 0x005B42, 0x000000, 0xFFFFFF, + 0x005B44, 0x005B44, 0x000000, 0xFFFFFF, + 0x005B46, 0x005B4F, 0x000000, 0xFFFFFF, + 0x005B52, 0x005B53, 0x000000, 0xFFFFFF, + 0x005B56, 0x005B56, 0x000000, 0xFFFFFF, + 0x005B59, 0x005B59, 0x000000, 0xFFFFFF, + 0x005B5E, 0x005B5E, 0x000000, 0xFFFFFF, + 0x005B60, 0x005B62, 0x000000, 0xFFFFFF, + 0x005B67, 0x005B68, 0x000000, 0xFFFFFF, + 0x005B6A, 0x005B6A, 0x000000, 0xFFFFFF, + 0x005B6C, 0x005B6F, 0x000000, 0xFFFFFF, + 0x005B72, 0x005B72, 0x000000, 0xFFFFFF, + 0x005B74, 0x005B74, 0x000000, 0xFFFFFF, + 0x005B76, 0x005B77, 0x000000, 0xFFFFFF, + 0x005B79, 0x005B79, 0x000000, 0xFFFFFF, + 0x005B7B, 0x005B7F, 0x000000, 0xFFFFFF, + 0x005B81, 0x005B82, 0x000000, 0xFFFFFF, + 0x005B84, 0x005B84, 0x000000, 0xFFFFFF, + 0x005B86, 0x005B86, 0x000000, 0xFFFFFF, + 0x005B8A, 0x005B8A, 0x000000, 0xFFFFFF, + 0x005B8E, 0x005B8E, 0x000000, 0xFFFFFF, + 0x005B90, 0x005B94, 0x000000, 0xFFFFFF, + 0x005B96, 0x005B96, 0x000000, 0xFFFFFF, + 0x005B9E, 0x005B9E, 0x000000, 0xFFFFFF, + 0x005BA0, 0x005BA1, 0x000000, 0xFFFFFF, + 0x005BA7, 0x005BAD, 0x000000, 0xFFFFFF, + 0x005BAF, 0x005BAF, 0x000000, 0xFFFFFF, + 0x005BB1, 0x005BB2, 0x000000, 0xFFFFFF, + 0x005BB7, 0x005BB7, 0x000000, 0xFFFFFF, + 0x005BBA, 0x005BBE, 0x000000, 0xFFFFFF, + 0x005BC0, 0x005BC1, 0x000000, 0xFFFFFF, + 0x005BC8, 0x005BC8, 0x000000, 0xFFFFFF, + 0x005BCA, 0x005BCB, 0x000000, 0xFFFFFF, + 0x005BCD, 0x005BCF, 0x000000, 0xFFFFFF, + 0x005BD1, 0x005BD1, 0x000000, 0xFFFFFF, + 0x005BD5, 0x005BDA, 0x000000, 0xFFFFFF, + 0x005BDC, 0x005BDC, 0x000000, 0xFFFFFF, + 0x005BE0, 0x005BE0, 0x000000, 0xFFFFFF, + 0x005BE3, 0x005BE3, 0x000000, 0xFFFFFF, + 0x005BEA, 0x005BEA, 0x000000, 0xFFFFFF, + 0x005BEC, 0x005BED, 0x000000, 0xFFFFFF, + 0x005BEF, 0x005BEF, 0x000000, 0xFFFFFF, + 0x005BF1, 0x005BF2, 0x000000, 0xFFFFFF, + 0x005BF4, 0x005BF4, 0x000000, 0xFFFFFF, + 0x005BF7, 0x005BF7, 0x000000, 0xFFFFFF, + 0x005BF9, 0x005BF9, 0x000000, 0xFFFFFF, + 0x005BFB, 0x005BFD, 0x000000, 0xFFFFFF, + 0x005C00, 0x005C00, 0x000000, 0xFFFFFF, + 0x005C03, 0x005C03, 0x000000, 0xFFFFFF, + 0x005C0C, 0x005C0C, 0x000000, 0xFFFFFF, + 0x005C10, 0x005C10, 0x000000, 0xFFFFFF, + 0x005C12, 0x005C12, 0x000000, 0xFFFFFF, + 0x005C14, 0x005C15, 0x000000, 0xFFFFFF, + 0x005C17, 0x005C19, 0x000000, 0xFFFFFF, + 0x005C1B, 0x005C1F, 0x000000, 0xFFFFFF, + 0x005C21, 0x005C21, 0x000000, 0xFFFFFF, + 0x005C23, 0x005C23, 0x000000, 0xFFFFFF, + 0x005C25, 0x005C27, 0x000000, 0xFFFFFF, + 0x005C29, 0x005C2C, 0x000000, 0xFFFFFF, + 0x005C2E, 0x005C30, 0x000000, 0xFFFFFF, + 0x005C32, 0x005C37, 0x000000, 0xFFFFFF, + 0x005C42, 0x005C44, 0x000000, 0xFFFFFF, + 0x005C47, 0x005C47, 0x000000, 0xFFFFFF, + 0x005C49, 0x005C49, 0x000000, 0xFFFFFF, + 0x005C4C, 0x005C4C, 0x000000, 0xFFFFFF, + 0x005C52, 0x005C52, 0x000000, 0xFFFFFF, + 0x005C54, 0x005C54, 0x000000, 0xFFFFFF, + 0x005C56, 0x005C5D, 0x000000, 0xFFFFFF, + 0x005C5F, 0x005C5F, 0x000000, 0xFFFFFF, + 0x005C62, 0x005C63, 0x000000, 0xFFFFFF, + 0x005C66, 0x005C6B, 0x000000, 0xFFFFFF, + 0x005C6D, 0x005C6D, 0x000000, 0xFFFFFF, + 0x005C70, 0x005C70, 0x000000, 0xFFFFFF, + 0x005C72, 0x005C75, 0x000000, 0xFFFFFF, + 0x005C77, 0x005C78, 0x000000, 0xFFFFFF, + 0x005C7A, 0x005C8B, 0x000000, 0xFFFFFF, + 0x005C8D, 0x005C8F, 0x000000, 0xFFFFFF, + 0x005C92, 0x005C93, 0x000000, 0xFFFFFF, + 0x005C95, 0x005CA0, 0x000000, 0xFFFFFF, + 0x005CA2, 0x005CA7, 0x000000, 0xFFFFFF, + 0x005CAA, 0x005CAA, 0x000000, 0xFFFFFF, + 0x005CAD, 0x005CB0, 0x000000, 0xFFFFFF, + 0x005CB2, 0x005CB2, 0x000000, 0xFFFFFF, + 0x005CB4, 0x005CB5, 0x000000, 0xFFFFFF, + 0x005CB9, 0x005CBA, 0x000000, 0xFFFFFF, + 0x005CBD, 0x005CBD, 0x000000, 0xFFFFFF, + 0x005CBF, 0x005CC4, 0x000000, 0xFFFFFF, + 0x005CC6, 0x005CC6, 0x000000, 0xFFFFFF, + 0x005CC8, 0x005CD8, 0x000000, 0xFFFFFF, + 0x005CDA, 0x005CDF, 0x000000, 0xFFFFFF, + 0x005CE2, 0x005CE7, 0x000000, 0xFFFFFF, + 0x005CEB, 0x005CEC, 0x000000, 0xFFFFFF, + 0x005CEE, 0x005CEE, 0x000000, 0xFFFFFF, + 0x005CF1, 0x005CF5, 0x000000, 0xFFFFFF, + 0x005CF7, 0x005CF9, 0x000000, 0xFFFFFF, + 0x005CFC, 0x005CFC, 0x000000, 0xFFFFFF, + 0x005CFE, 0x005D06, 0x000000, 0xFFFFFF, + 0x005D08, 0x005D0A, 0x000000, 0xFFFFFF, + 0x005D0C, 0x005D0D, 0x000000, 0xFFFFFF, + 0x005D0F, 0x005D10, 0x000000, 0xFFFFFF, + 0x005D12, 0x005D13, 0x000000, 0xFFFFFF, + 0x005D1C, 0x005D1E, 0x000000, 0xFFFFFF, + 0x005D20, 0x005D21, 0x000000, 0xFFFFFF, + 0x005D23, 0x005D28, 0x000000, 0xFFFFFF, + 0x005D2A, 0x005D4A, 0x000000, 0xFFFFFF, + 0x005D4D, 0x005D4D, 0x000000, 0xFFFFFF, + 0x005D4F, 0x005D4F, 0x000000, 0xFFFFFF, + 0x005D51, 0x005D51, 0x000000, 0xFFFFFF, + 0x005D53, 0x005D5B, 0x000000, 0xFFFFFF, + 0x005D5D, 0x005D68, 0x000000, 0xFFFFFF, + 0x005D6A, 0x005D6B, 0x000000, 0xFFFFFF, + 0x005D6D, 0x005D6E, 0x000000, 0xFFFFFF, + 0x005D70, 0x005D72, 0x000000, 0xFFFFFF, + 0x005D74, 0x005D75, 0x000000, 0xFFFFFF, + 0x005D77, 0x005D81, 0x000000, 0xFFFFFF, + 0x005D83, 0x005D83, 0x000000, 0xFFFFFF, + 0x005D85, 0x005D86, 0x000000, 0xFFFFFF, + 0x005D88, 0x005D8A, 0x000000, 0xFFFFFF, + 0x005D8D, 0x005D8F, 0x000000, 0xFFFFFF, + 0x005D91, 0x005D9C, 0x000000, 0xFFFFFF, + 0x005D9E, 0x005DA1, 0x000000, 0xFFFFFF, + 0x005DA3, 0x005DAB, 0x000000, 0xFFFFFF, + 0x005DAD, 0x005DAD, 0x000000, 0xFFFFFF, + 0x005DAF, 0x005DB6, 0x000000, 0xFFFFFF, + 0x005DB8, 0x005DB9, 0x000000, 0xFFFFFF, + 0x005DBB, 0x005DBB, 0x000000, 0xFFFFFF, + 0x005DBE, 0x005DC8, 0x000000, 0xFFFFFF, + 0x005DCA, 0x005DCB, 0x000000, 0xFFFFFF, + 0x005DCE, 0x005DD1, 0x000000, 0xFFFFFF, + 0x005DD4, 0x005DD5, 0x000000, 0xFFFFFF, + 0x005DD7, 0x005DDA, 0x000000, 0xFFFFFF, + 0x005DDC, 0x005DDC, 0x000000, 0xFFFFFF, + 0x005DDF, 0x005DE0, 0x000000, 0xFFFFFF, + 0x005DE2, 0x005DE2, 0x000000, 0xFFFFFF, + 0x005DE4, 0x005DE4, 0x000000, 0xFFFFFF, + 0x005DE9, 0x005DEA, 0x000000, 0xFFFFFF, + 0x005DEC, 0x005DED, 0x000000, 0xFFFFFF, + 0x005DEF, 0x005DF0, 0x000000, 0xFFFFFF, + 0x005DF6, 0x005DF6, 0x000000, 0xFFFFFF, + 0x005DF8, 0x005DFA, 0x000000, 0xFFFFFF, + 0x005DFC, 0x005DFC, 0x000000, 0xFFFFFF, + 0x005DFF, 0x005E01, 0x000000, 0xFFFFFF, + 0x005E04, 0x005E05, 0x000000, 0xFFFFFF, + 0x005E07, 0x005E0A, 0x000000, 0xFFFFFF, + 0x005E0D, 0x005E10, 0x000000, 0xFFFFFF, + 0x005E12, 0x005E15, 0x000000, 0xFFFFFF, + 0x005E17, 0x005E18, 0x000000, 0xFFFFFF, + 0x005E1C, 0x005E1C, 0x000000, 0xFFFFFF, + 0x005E1E, 0x005E24, 0x000000, 0xFFFFFF, + 0x005E26, 0x005E2A, 0x000000, 0xFFFFFF, + 0x005E2C, 0x005E2C, 0x000000, 0xFFFFFF, + 0x005E2E, 0x005E2E, 0x000000, 0xFFFFFF, + 0x005E31, 0x005E32, 0x000000, 0xFFFFFF, + 0x005E34, 0x005E35, 0x000000, 0xFFFFFF, + 0x005E39, 0x005E3C, 0x000000, 0xFFFFFF, + 0x005E3E, 0x005E3F, 0x000000, 0xFFFFFF, + 0x005E41, 0x005E42, 0x000000, 0xFFFFFF, + 0x005E46, 0x005E46, 0x000000, 0xFFFFFF, + 0x005E48, 0x005E4B, 0x000000, 0xFFFFFF, + 0x005E4D, 0x005E4D, 0x000000, 0xFFFFFF, + 0x005E4F, 0x005E53, 0x000000, 0xFFFFFF, + 0x005E56, 0x005E56, 0x000000, 0xFFFFFF, + 0x005E58, 0x005E5E, 0x000000, 0xFFFFFF, + 0x005E60, 0x005E60, 0x000000, 0xFFFFFF, + 0x005E65, 0x005E71, 0x000000, 0xFFFFFF, + 0x005E77, 0x005E77, 0x000000, 0xFFFFFF, + 0x005E80, 0x005E80, 0x000000, 0xFFFFFF, + 0x005E82, 0x005E82, 0x000000, 0xFFFFFF, + 0x005E85, 0x005E86, 0x000000, 0xFFFFFF, + 0x005E88, 0x005E89, 0x000000, 0xFFFFFF, + 0x005E8B, 0x005E8E, 0x000000, 0xFFFFFF, + 0x005E90, 0x005E94, 0x000000, 0xFFFFFF, + 0x005E98, 0x005E99, 0x000000, 0xFFFFFF, + 0x005E9B, 0x005E9B, 0x000000, 0xFFFFFF, + 0x005E9D, 0x005E9F, 0x000000, 0xFFFFFF, + 0x005EA1, 0x005EA5, 0x000000, 0xFFFFFF, + 0x005EA8, 0x005EAA, 0x000000, 0xFFFFFF, + 0x005EAC, 0x005EAC, 0x000000, 0xFFFFFF, + 0x005EAE, 0x005EB4, 0x000000, 0xFFFFFF, + 0x005EB9, 0x005EC0, 0x000000, 0xFFFFFF, + 0x005EC4, 0x005EC7, 0x000000, 0xFFFFFF, + 0x005ECB, 0x005ECE, 0x000000, 0xFFFFFF, + 0x005ED1, 0x005ED2, 0x000000, 0xFFFFFF, + 0x005ED4, 0x005ED5, 0x000000, 0xFFFFFF, + 0x005ED7, 0x005ED9, 0x000000, 0xFFFFFF, + 0x005EDC, 0x005EDC, 0x000000, 0xFFFFFF, + 0x005EDE, 0x005EDE, 0x000000, 0xFFFFFF, + 0x005EE4, 0x005EE7, 0x000000, 0xFFFFFF, + 0x005EEA, 0x005EEB, 0x000000, 0xFFFFFF, + 0x005EED, 0x005EEF, 0x000000, 0xFFFFFF, + 0x005EF2, 0x005EF2, 0x000000, 0xFFFFFF, + 0x005EF5, 0x005EF5, 0x000000, 0xFFFFFF, + 0x005EF9, 0x005EF9, 0x000000, 0xFFFFFF, + 0x005EFD, 0x005EFD, 0x000000, 0xFFFFFF, + 0x005F00, 0x005F00, 0x000000, 0xFFFFFF, + 0x005F02, 0x005F02, 0x000000, 0xFFFFFF, + 0x005F05, 0x005F08, 0x000000, 0xFFFFFF, + 0x005F0E, 0x005F0E, 0x000000, 0xFFFFFF, + 0x005F12, 0x005F12, 0x000000, 0xFFFFFF, + 0x005F19, 0x005F1A, 0x000000, 0xFFFFFF, + 0x005F1C, 0x005F1E, 0x000000, 0xFFFFFF, + 0x005F20, 0x005F24, 0x000000, 0xFFFFFF, + 0x005F28, 0x005F28, 0x000000, 0xFFFFFF, + 0x005F2A, 0x005F2C, 0x000000, 0xFFFFFF, + 0x005F2E, 0x005F2E, 0x000000, 0xFFFFFF, + 0x005F30, 0x005F30, 0x000000, 0xFFFFFF, + 0x005F32, 0x005F34, 0x000000, 0xFFFFFF, + 0x005F36, 0x005F36, 0x000000, 0xFFFFFF, + 0x005F39, 0x005F3B, 0x000000, 0xFFFFFF, + 0x005F3D, 0x005F3D, 0x000000, 0xFFFFFF, + 0x005F3F, 0x005F40, 0x000000, 0xFFFFFF, + 0x005F42, 0x005F47, 0x000000, 0xFFFFFF, + 0x005F49, 0x005F49, 0x000000, 0xFFFFFF, + 0x005F4B, 0x005F4B, 0x000000, 0xFFFFFF, + 0x005F4D, 0x005F4D, 0x000000, 0xFFFFFF, + 0x005F4F, 0x005F50, 0x000000, 0xFFFFFF, + 0x005F52, 0x005F52, 0x000000, 0xFFFFFF, + 0x005F54, 0x005F55, 0x000000, 0xFFFFFF, + 0x005F58, 0x005F58, 0x000000, 0xFFFFFF, + 0x005F5A, 0x005F5B, 0x000000, 0xFFFFFF, + 0x005F5E, 0x005F60, 0x000000, 0xFFFFFF, + 0x005F63, 0x005F65, 0x000000, 0xFFFFFF, + 0x005F67, 0x005F68, 0x000000, 0xFFFFFF, + 0x005F6E, 0x005F6F, 0x000000, 0xFFFFFF, + 0x005F72, 0x005F72, 0x000000, 0xFFFFFF, + 0x005F74, 0x005F76, 0x000000, 0xFFFFFF, + 0x005F78, 0x005F78, 0x000000, 0xFFFFFF, + 0x005F7A, 0x005F7B, 0x000000, 0xFFFFFF, + 0x005F7D, 0x005F7E, 0x000000, 0xFFFFFF, + 0x005F86, 0x005F86, 0x000000, 0xFFFFFF, + 0x005F89, 0x005F89, 0x000000, 0xFFFFFF, + 0x005F8D, 0x005F8F, 0x000000, 0xFFFFFF, + 0x005F94, 0x005F96, 0x000000, 0xFFFFFF, + 0x005F9A, 0x005F9D, 0x000000, 0xFFFFFF, + 0x005F9F, 0x005F9F, 0x000000, 0xFFFFFF, + 0x005FA2, 0x005FA7, 0x000000, 0xFFFFFF, + 0x005FAB, 0x005FAC, 0x000000, 0xFFFFFF, + 0x005FAF, 0x005FB2, 0x000000, 0xFFFFFF, + 0x005FB5, 0x005FB8, 0x000000, 0xFFFFFF, + 0x005FBA, 0x005FBB, 0x000000, 0xFFFFFF, + 0x005FBE, 0x005FC2, 0x000000, 0xFFFFFF, + 0x005FC4, 0x005FC4, 0x000000, 0xFFFFFF, + 0x005FC6, 0x005FCB, 0x000000, 0xFFFFFF, + 0x005FCE, 0x005FD5, 0x000000, 0xFFFFFF, + 0x005FDA, 0x005FDB, 0x000000, 0xFFFFFF, + 0x005FDE, 0x005FDF, 0x000000, 0xFFFFFF, + 0x005FE1, 0x005FE3, 0x000000, 0xFFFFFF, + 0x005FE5, 0x005FEA, 0x000000, 0xFFFFFF, + 0x005FEC, 0x005FEF, 0x000000, 0xFFFFFF, + 0x005FF2, 0x005FF4, 0x000000, 0xFFFFFF, + 0x005FF6, 0x005FF7, 0x000000, 0xFFFFFF, + 0x005FF9, 0x005FFA, 0x000000, 0xFFFFFF, + 0x005FFC, 0x005FFC, 0x000000, 0xFFFFFF, + 0x005FFE, 0x005FFE, 0x000000, 0xFFFFFF, + 0x006000, 0x00600D, 0x000000, 0xFFFFFF, + 0x006011, 0x006011, 0x000000, 0xFFFFFF, + 0x006013, 0x006014, 0x000000, 0xFFFFFF, + 0x006017, 0x006018, 0x000000, 0xFFFFFF, + 0x00601A, 0x00601A, 0x000000, 0xFFFFFF, + 0x00601E, 0x00601F, 0x000000, 0xFFFFFF, + 0x006022, 0x006024, 0x000000, 0xFFFFFF, + 0x00602C, 0x00602E, 0x000000, 0xFFFFFF, + 0x006030, 0x006030, 0x000000, 0xFFFFFF, + 0x006032, 0x006039, 0x000000, 0xFFFFFF, + 0x00603B, 0x006040, 0x000000, 0xFFFFFF, + 0x006044, 0x006045, 0x000000, 0xFFFFFF, + 0x006047, 0x006049, 0x000000, 0xFFFFFF, + 0x00604C, 0x00604C, 0x000000, 0xFFFFFF, + 0x00604E, 0x00604F, 0x000000, 0xFFFFFF, + 0x006051, 0x006051, 0x000000, 0xFFFFFF, + 0x006053, 0x006054, 0x000000, 0xFFFFFF, + 0x006056, 0x006058, 0x000000, 0xFFFFFF, + 0x00605B, 0x00605E, 0x000000, 0xFFFFFF, + 0x006061, 0x006061, 0x000000, 0xFFFFFF, + 0x006066, 0x006067, 0x000000, 0xFFFFFF, + 0x00606E, 0x00606E, 0x000000, 0xFFFFFF, + 0x006071, 0x006074, 0x000000, 0xFFFFFF, + 0x006076, 0x006076, 0x000000, 0xFFFFFF, + 0x006078, 0x006080, 0x000000, 0xFFFFFF, + 0x006082, 0x006082, 0x000000, 0xFFFFFF, + 0x006085, 0x006088, 0x000000, 0xFFFFFF, + 0x00608A, 0x00608A, 0x000000, 0xFFFFFF, + 0x00608E, 0x006091, 0x000000, 0xFFFFFF, + 0x006093, 0x006093, 0x000000, 0xFFFFFF, + 0x006095, 0x006095, 0x000000, 0xFFFFFF, + 0x006098, 0x006099, 0x000000, 0xFFFFFF, + 0x00609C, 0x00609E, 0x000000, 0xFFFFFF, + 0x0060A1, 0x0060A2, 0x000000, 0xFFFFFF, + 0x0060A4, 0x0060A5, 0x000000, 0xFFFFFF, + 0x0060A8, 0x0060A8, 0x000000, 0xFFFFFF, + 0x0060AB, 0x0060B1, 0x000000, 0xFFFFFF, + 0x0060B7, 0x0060B7, 0x000000, 0xFFFFFF, + 0x0060B9, 0x0060BB, 0x000000, 0xFFFFFF, + 0x0060BE, 0x0060C4, 0x000000, 0xFFFFFF, + 0x0060C8, 0x0060D0, 0x000000, 0xFFFFFF, + 0x0060D2, 0x0060D2, 0x000000, 0xFFFFFF, + 0x0060D4, 0x0060D7, 0x000000, 0xFFFFFF, + 0x0060D9, 0x0060D9, 0x000000, 0xFFFFFF, + 0x0060DB, 0x0060DB, 0x000000, 0xFFFFFF, + 0x0060DD, 0x0060DE, 0x000000, 0xFFFFFF, + 0x0060E2, 0x0060E2, 0x000000, 0xFFFFFF, + 0x0060E4, 0x0060E6, 0x000000, 0xFFFFFF, + 0x0060E9, 0x0060EF, 0x000000, 0xFFFFFF, + 0x0060F2, 0x0060F2, 0x000000, 0xFFFFFF, + 0x0060F5, 0x0060F5, 0x000000, 0xFFFFFF, + 0x0060F8, 0x0060F8, 0x000000, 0xFFFFFF, + 0x0060FC, 0x0060FF, 0x000000, 0xFFFFFF, + 0x006102, 0x006102, 0x000000, 0xFFFFFF, + 0x006104, 0x006105, 0x000000, 0xFFFFFF, + 0x006107, 0x006107, 0x000000, 0xFFFFFF, + 0x00610A, 0x00610C, 0x000000, 0xFFFFFF, + 0x006110, 0x006114, 0x000000, 0xFFFFFF, + 0x006116, 0x006119, 0x000000, 0xFFFFFF, + 0x00611C, 0x00611E, 0x000000, 0xFFFFFF, + 0x006120, 0x006120, 0x000000, 0xFFFFFF, + 0x006122, 0x006126, 0x000000, 0xFFFFFF, + 0x006129, 0x00612B, 0x000000, 0xFFFFFF, + 0x00612D, 0x006133, 0x000000, 0xFFFFFF, + 0x006135, 0x00613B, 0x000000, 0xFFFFFF, + 0x006140, 0x006141, 0x000000, 0xFFFFFF, + 0x006143, 0x006143, 0x000000, 0xFFFFFF, + 0x006145, 0x006146, 0x000000, 0xFFFFFF, + 0x006149, 0x006149, 0x000000, 0xFFFFFF, + 0x00614F, 0x006152, 0x000000, 0xFFFFFF, + 0x006154, 0x006154, 0x000000, 0xFFFFFF, + 0x006156, 0x006157, 0x000000, 0xFFFFFF, + 0x00615B, 0x00615C, 0x000000, 0xFFFFFF, + 0x00615E, 0x00615E, 0x000000, 0xFFFFFF, + 0x006160, 0x006161, 0x000000, 0xFFFFFF, + 0x006164, 0x006164, 0x000000, 0xFFFFFF, + 0x006166, 0x006166, 0x000000, 0xFFFFFF, + 0x006169, 0x00616A, 0x000000, 0xFFFFFF, + 0x00616C, 0x00616D, 0x000000, 0xFFFFFF, + 0x006172, 0x006172, 0x000000, 0xFFFFFF, + 0x006178, 0x00617D, 0x000000, 0xFFFFFF, + 0x00617F, 0x006181, 0x000000, 0xFFFFFF, + 0x006183, 0x006186, 0x000000, 0xFFFFFF, + 0x006188, 0x006189, 0x000000, 0xFFFFFF, + 0x00618B, 0x00618D, 0x000000, 0xFFFFFF, + 0x00618F, 0x00618F, 0x000000, 0xFFFFFF, + 0x006192, 0x006193, 0x000000, 0xFFFFFF, + 0x006195, 0x006195, 0x000000, 0xFFFFFF, + 0x006197, 0x006198, 0x000000, 0xFFFFFF, + 0x00619B, 0x0061A3, 0x000000, 0xFFFFFF, + 0x0061A5, 0x0061A6, 0x000000, 0xFFFFFF, + 0x0061A8, 0x0061A8, 0x000000, 0xFFFFFF, + 0x0061AA, 0x0061AA, 0x000000, 0xFFFFFF, + 0x0061AD, 0x0061AD, 0x000000, 0xFFFFFF, + 0x0061AF, 0x0061B1, 0x000000, 0xFFFFFF, + 0x0061B3, 0x0061B5, 0x000000, 0xFFFFFF, + 0x0061B7, 0x0061B9, 0x000000, 0xFFFFFF, + 0x0061BB, 0x0061BD, 0x000000, 0xFFFFFF, + 0x0061BF, 0x0061C2, 0x000000, 0xFFFFFF, + 0x0061C4, 0x0061C5, 0x000000, 0xFFFFFF, + 0x0061CE, 0x0061CF, 0x000000, 0xFFFFFF, + 0x0061D1, 0x0061E2, 0x000000, 0xFFFFFF, + 0x0061E4, 0x0061E5, 0x000000, 0xFFFFFF, + 0x0061E7, 0x0061F1, 0x000000, 0xFFFFFF, + 0x0061F3, 0x0061F3, 0x000000, 0xFFFFFF, + 0x0061F5, 0x0061F5, 0x000000, 0xFFFFFF, + 0x0061F9, 0x0061F9, 0x000000, 0xFFFFFF, + 0x0061FB, 0x0061FB, 0x000000, 0xFFFFFF, + 0x006201, 0x006207, 0x000000, 0xFFFFFF, + 0x00620B, 0x00620B, 0x000000, 0xFFFFFF, + 0x00620F, 0x00620F, 0x000000, 0xFFFFFF, + 0x006213, 0x006213, 0x000000, 0xFFFFFF, + 0x006215, 0x006215, 0x000000, 0xFFFFFF, + 0x006217, 0x006219, 0x000000, 0xFFFFFF, + 0x00621C, 0x00621C, 0x000000, 0xFFFFFF, + 0x006220, 0x006220, 0x000000, 0xFFFFFF, + 0x006222, 0x006225, 0x000000, 0xFFFFFF, + 0x006227, 0x006229, 0x000000, 0xFFFFFF, + 0x00622B, 0x00622D, 0x000000, 0xFFFFFF, + 0x006231, 0x006231, 0x000000, 0xFFFFFF, + 0x006235, 0x006237, 0x000000, 0xFFFFFF, + 0x006239, 0x00623A, 0x000000, 0xFFFFFF, + 0x00623C, 0x00623E, 0x000000, 0xFFFFFF, + 0x006242, 0x006246, 0x000000, 0xFFFFFF, + 0x00624A, 0x00624A, 0x000000, 0xFFFFFF, + 0x00624C, 0x00624C, 0x000000, 0xFFFFFF, + 0x00624F, 0x006252, 0x000000, 0xFFFFFF, + 0x006254, 0x006254, 0x000000, 0xFFFFFF, + 0x006256, 0x006257, 0x000000, 0xFFFFFF, + 0x006259, 0x00625A, 0x000000, 0xFFFFFF, + 0x00625C, 0x00625D, 0x000000, 0xFFFFFF, + 0x00625F, 0x00625F, 0x000000, 0xFFFFFF, + 0x006261, 0x006262, 0x000000, 0xFFFFFF, + 0x006264, 0x006267, 0x000000, 0xFFFFFF, + 0x006269, 0x00626D, 0x000000, 0xFFFFFF, + 0x00626F, 0x006270, 0x000000, 0xFFFFFF, + 0x006272, 0x006275, 0x000000, 0xFFFFFF, + 0x006277, 0x006278, 0x000000, 0xFFFFFF, + 0x00627A, 0x00627B, 0x000000, 0xFFFFFF, + 0x00627D, 0x00627D, 0x000000, 0xFFFFFF, + 0x006281, 0x006281, 0x000000, 0xFFFFFF, + 0x006285, 0x006288, 0x000000, 0xFFFFFF, + 0x00628B, 0x006290, 0x000000, 0xFFFFFF, + 0x006299, 0x00629A, 0x000000, 0xFFFFFF, + 0x00629D, 0x00629D, 0x000000, 0xFFFFFF, + 0x00629F, 0x0062AA, 0x000000, 0xFFFFFF, + 0x0062AD, 0x0062B0, 0x000000, 0xFFFFFF, + 0x0062B2, 0x0062B4, 0x000000, 0xFFFFFF, + 0x0062B6, 0x0062B8, 0x000000, 0xFFFFFF, + 0x0062BA, 0x0062BA, 0x000000, 0xFFFFFF, + 0x0062BE, 0x0062C1, 0x000000, 0xFFFFFF, + 0x0062C3, 0x0062C4, 0x000000, 0xFFFFFF, + 0x0062CB, 0x0062CB, 0x000000, 0xFFFFFF, + 0x0062CE, 0x0062CE, 0x000000, 0xFFFFFF, + 0x0062D5, 0x0062D6, 0x000000, 0xFFFFFF, + 0x0062DA, 0x0062DA, 0x000000, 0xFFFFFF, + 0x0062DE, 0x0062DF, 0x000000, 0xFFFFFF, + 0x0062E2, 0x0062EB, 0x000000, 0xFFFFFF, + 0x0062F0, 0x0062F0, 0x000000, 0xFFFFFF, + 0x0062F2, 0x0062F2, 0x000000, 0xFFFFFF, + 0x0062F4, 0x0062F4, 0x000000, 0xFFFFFF, + 0x0062F8, 0x0062FD, 0x000000, 0xFFFFFF, + 0x006300, 0x006300, 0x000000, 0xFFFFFF, + 0x006303, 0x006306, 0x000000, 0xFFFFFF, + 0x00630A, 0x00630B, 0x000000, 0xFFFFFF, + 0x00630D, 0x006310, 0x000000, 0xFFFFFF, + 0x006312, 0x006318, 0x000000, 0xFFFFFF, + 0x00631A, 0x00631E, 0x000000, 0xFFFFFF, + 0x006320, 0x006326, 0x000000, 0xFFFFFF, + 0x006329, 0x00632A, 0x000000, 0xFFFFFF, + 0x00632C, 0x00632E, 0x000000, 0xFFFFFF, + 0x006330, 0x006339, 0x000000, 0xFFFFFF, + 0x00633B, 0x00633C, 0x000000, 0xFFFFFF, + 0x006340, 0x006348, 0x000000, 0xFFFFFF, + 0x00634A, 0x00634B, 0x000000, 0xFFFFFF, + 0x00634E, 0x00634E, 0x000000, 0xFFFFFF, + 0x006351, 0x006354, 0x000000, 0xFFFFFF, + 0x006356, 0x006356, 0x000000, 0xFFFFFF, + 0x006358, 0x00635B, 0x000000, 0xFFFFFF, + 0x00635D, 0x006366, 0x000000, 0xFFFFFF, + 0x00636A, 0x00636A, 0x000000, 0xFFFFFF, + 0x00636C, 0x00636D, 0x000000, 0xFFFFFF, + 0x00636F, 0x006371, 0x000000, 0xFFFFFF, + 0x006373, 0x006375, 0x000000, 0xFFFFFF, + 0x006378, 0x006379, 0x000000, 0xFFFFFF, + 0x00637C, 0x00637F, 0x000000, 0xFFFFFF, + 0x006381, 0x006382, 0x000000, 0xFFFFFF, + 0x006384, 0x006387, 0x000000, 0xFFFFFF, + 0x00638A, 0x00638B, 0x000000, 0xFFFFFF, + 0x00638D, 0x00638D, 0x000000, 0xFFFFFF, + 0x006390, 0x006391, 0x000000, 0xFFFFFF, + 0x006393, 0x006395, 0x000000, 0xFFFFFF, + 0x006397, 0x006397, 0x000000, 0xFFFFFF, + 0x006399, 0x00639A, 0x000000, 0xFFFFFF, + 0x00639C, 0x00639E, 0x000000, 0xFFFFFF, + 0x0063A4, 0x0063A4, 0x000000, 0xFFFFFF, + 0x0063A6, 0x0063A6, 0x000000, 0xFFFFFF, + 0x0063AD, 0x0063B1, 0x000000, 0xFFFFFF, + 0x0063B3, 0x0063B3, 0x000000, 0xFFFFFF, + 0x0063B6, 0x0063BA, 0x000000, 0xFFFFFF, + 0x0063BC, 0x0063BD, 0x000000, 0xFFFFFF, + 0x0063BF, 0x0063BF, 0x000000, 0xFFFFFF, + 0x0063C1, 0x0063C2, 0x000000, 0xFFFFFF, + 0x0063C5, 0x0063C5, 0x000000, 0xFFFFFF, + 0x0063C7, 0x0063C8, 0x000000, 0xFFFFFF, + 0x0063CA, 0x0063CE, 0x000000, 0xFFFFFF, + 0x0063D1, 0x0063D1, 0x000000, 0xFFFFFF, + 0x0063D3, 0x0063D5, 0x000000, 0xFFFFFF, + 0x0063D7, 0x0063D9, 0x000000, 0xFFFFFF, + 0x0063DC, 0x0063E0, 0x000000, 0xFFFFFF, + 0x0063E2, 0x0063E2, 0x000000, 0xFFFFFF, + 0x0063E4, 0x0063E8, 0x000000, 0xFFFFFF, + 0x0063EA, 0x0063ED, 0x000000, 0xFFFFFF, + 0x0063EF, 0x0063F3, 0x000000, 0xFFFFFF, + 0x0063F5, 0x0063F5, 0x000000, 0xFFFFFF, + 0x0063F7, 0x0063F9, 0x000000, 0xFFFFFF, + 0x0063FB, 0x006405, 0x000000, 0xFFFFFF, + 0x006407, 0x00640C, 0x000000, 0xFFFFFF, + 0x00640E, 0x00640E, 0x000000, 0xFFFFFF, + 0x006410, 0x006412, 0x000000, 0xFFFFFF, + 0x006414, 0x006415, 0x000000, 0xFFFFFF, + 0x006418, 0x00641B, 0x000000, 0xFFFFFF, + 0x00641D, 0x006425, 0x000000, 0xFFFFFF, + 0x006427, 0x006427, 0x000000, 0xFFFFFF, + 0x006429, 0x00642B, 0x000000, 0xFFFFFF, + 0x00642E, 0x006433, 0x000000, 0xFFFFFF, + 0x006435, 0x006435, 0x000000, 0xFFFFFF, + 0x006437, 0x006439, 0x000000, 0xFFFFFF, + 0x00643B, 0x00643D, 0x000000, 0xFFFFFF, + 0x00643F, 0x006441, 0x000000, 0xFFFFFF, + 0x006443, 0x00644D, 0x000000, 0xFFFFFF, + 0x00644F, 0x006457, 0x000000, 0xFFFFFF, + 0x006459, 0x006466, 0x000000, 0xFFFFFF, + 0x006468, 0x006468, 0x000000, 0xFFFFFF, + 0x00646A, 0x00646E, 0x000000, 0xFFFFFF, + 0x006470, 0x006475, 0x000000, 0xFFFFFF, + 0x006477, 0x006477, 0x000000, 0xFFFFFF, + 0x006479, 0x006479, 0x000000, 0xFFFFFF, + 0x00647B, 0x006482, 0x000000, 0xFFFFFF, + 0x006484, 0x006487, 0x000000, 0xFFFFFF, + 0x006489, 0x006491, 0x000000, 0xFFFFFF, + 0x006494, 0x006494, 0x000000, 0xFFFFFF, + 0x006496, 0x006499, 0x000000, 0xFFFFFF, + 0x00649B, 0x00649D, 0x000000, 0xFFFFFF, + 0x00649F, 0x0064A3, 0x000000, 0xFFFFFF, + 0x0064A6, 0x0064A8, 0x000000, 0xFFFFFF, + 0x0064AA, 0x0064AA, 0x000000, 0xFFFFFF, + 0x0064AC, 0x0064AC, 0x000000, 0xFFFFFF, + 0x0064AF, 0x0064AF, 0x000000, 0xFFFFFF, + 0x0064B1, 0x0064B1, 0x000000, 0xFFFFFF, + 0x0064B3, 0x0064B8, 0x000000, 0xFFFFFF, + 0x0064BA, 0x0064BA, 0x000000, 0xFFFFFF, + 0x0064BD, 0x0064C0, 0x000000, 0xFFFFFF, + 0x0064C3, 0x0064C4, 0x000000, 0xFFFFFF, + 0x0064C6, 0x0064C6, 0x000000, 0xFFFFFF, + 0x0064C8, 0x0064CC, 0x000000, 0xFFFFFF, + 0x0064CE, 0x0064D1, 0x000000, 0xFFFFFF, + 0x0064D3, 0x0064D3, 0x000000, 0xFFFFFF, + 0x0064D5, 0x0064D7, 0x000000, 0xFFFFFF, + 0x0064D9, 0x0064D9, 0x000000, 0xFFFFFF, + 0x0064DB, 0x0064DF, 0x000000, 0xFFFFFF, + 0x0064E4, 0x0064E5, 0x000000, 0xFFFFFF, + 0x0064E8, 0x0064EB, 0x000000, 0xFFFFFF, + 0x0064ED, 0x0064EE, 0x000000, 0xFFFFFF, + 0x0064F0, 0x0064F0, 0x000000, 0xFFFFFF, + 0x0064F3, 0x0064F3, 0x000000, 0xFFFFFF, + 0x0064F5, 0x0064F5, 0x000000, 0xFFFFFF, + 0x0064F7, 0x0064F9, 0x000000, 0xFFFFFF, + 0x0064FB, 0x0064FC, 0x000000, 0xFFFFFF, + 0x0064FF, 0x0064FF, 0x000000, 0xFFFFFF, + 0x006501, 0x006504, 0x000000, 0xFFFFFF, + 0x006506, 0x006517, 0x000000, 0xFFFFFF, + 0x006519, 0x00651B, 0x000000, 0xFFFFFF, + 0x00651E, 0x006522, 0x000000, 0xFFFFFF, + 0x006525, 0x006529, 0x000000, 0xFFFFFF, + 0x00652D, 0x00652E, 0x000000, 0xFFFFFF, + 0x006530, 0x006533, 0x000000, 0xFFFFFF, + 0x00653A, 0x00653A, 0x000000, 0xFFFFFF, + 0x00653C, 0x00653D, 0x000000, 0xFFFFFF, + 0x006540, 0x006544, 0x000000, 0xFFFFFF, + 0x006546, 0x006547, 0x000000, 0xFFFFFF, + 0x006549, 0x00654C, 0x000000, 0xFFFFFF, + 0x00654E, 0x00654E, 0x000000, 0xFFFFFF, + 0x006550, 0x006550, 0x000000, 0xFFFFFF, + 0x006552, 0x006554, 0x000000, 0xFFFFFF, + 0x00655A, 0x00655C, 0x000000, 0xFFFFFF, + 0x00655F, 0x006561, 0x000000, 0xFFFFFF, + 0x006564, 0x006565, 0x000000, 0xFFFFFF, + 0x006567, 0x00656B, 0x000000, 0xFFFFFF, + 0x00656D, 0x00656F, 0x000000, 0xFFFFFF, + 0x006571, 0x006571, 0x000000, 0xFFFFFF, + 0x006573, 0x006573, 0x000000, 0xFFFFFF, + 0x006576, 0x006576, 0x000000, 0xFFFFFF, + 0x006579, 0x006581, 0x000000, 0xFFFFFF, + 0x006584, 0x006586, 0x000000, 0xFFFFFF, + 0x00658A, 0x00658B, 0x000000, 0xFFFFFF, + 0x00658D, 0x00658D, 0x000000, 0xFFFFFF, + 0x00658F, 0x00658F, 0x000000, 0xFFFFFF, + 0x006592, 0x006596, 0x000000, 0xFFFFFF, + 0x006598, 0x006598, 0x000000, 0xFFFFFF, + 0x00659A, 0x00659A, 0x000000, 0xFFFFFF, + 0x00659D, 0x00659E, 0x000000, 0xFFFFFF, + 0x0065A0, 0x0065A0, 0x000000, 0xFFFFFF, + 0x0065A2, 0x0065A3, 0x000000, 0xFFFFFF, + 0x0065A6, 0x0065A6, 0x000000, 0xFFFFFF, + 0x0065A8, 0x0065AA, 0x000000, 0xFFFFFF, + 0x0065AE, 0x0065AE, 0x000000, 0xFFFFFF, + 0x0065B1, 0x0065B6, 0x000000, 0xFFFFFF, + 0x0065B8, 0x0065B8, 0x000000, 0xFFFFFF, + 0x0065BA, 0x0065BB, 0x000000, 0xFFFFFF, + 0x0065BE, 0x0065C0, 0x000000, 0xFFFFFF, + 0x0065C2, 0x0065C2, 0x000000, 0xFFFFFF, + 0x0065C7, 0x0065CA, 0x000000, 0xFFFFFF, + 0x0065CD, 0x0065CE, 0x000000, 0xFFFFFF, + 0x0065D0, 0x0065D1, 0x000000, 0xFFFFFF, + 0x0065D3, 0x0065D6, 0x000000, 0xFFFFFF, + 0x0065D8, 0x0065D8, 0x000000, 0xFFFFFF, + 0x0065DA, 0x0065DA, 0x000000, 0xFFFFFF, + 0x0065DC, 0x0065DF, 0x000000, 0xFFFFFF, + 0x0065E3, 0x0065E4, 0x000000, 0xFFFFFF, + 0x0065EA, 0x0065EB, 0x000000, 0xFFFFFF, + 0x0065EE, 0x0065F0, 0x000000, 0xFFFFFF, + 0x0065F2, 0x0065F9, 0x000000, 0xFFFFFF, + 0x0065FC, 0x006601, 0x000000, 0xFFFFFF, + 0x006604, 0x006605, 0x000000, 0xFFFFFF, + 0x006608, 0x006609, 0x000000, 0xFFFFFF, + 0x00660B, 0x00660B, 0x000000, 0xFFFFFF, + 0x00660D, 0x00660D, 0x000000, 0xFFFFFF, + 0x006610, 0x006612, 0x000000, 0xFFFFFF, + 0x006615, 0x00661B, 0x000000, 0xFFFFFF, + 0x00661D, 0x00661E, 0x000000, 0xFFFFFF, + 0x006621, 0x006624, 0x000000, 0xFFFFFF, + 0x006626, 0x006626, 0x000000, 0xFFFFFF, + 0x006629, 0x00662C, 0x000000, 0xFFFFFF, + 0x00662E, 0x00662E, 0x000000, 0xFFFFFF, + 0x006630, 0x006633, 0x000000, 0xFFFFFF, + 0x006637, 0x00663B, 0x000000, 0xFFFFFF, + 0x00663D, 0x00663E, 0x000000, 0xFFFFFF, + 0x006640, 0x006640, 0x000000, 0xFFFFFF, + 0x006645, 0x006648, 0x000000, 0xFFFFFF, + 0x00664A, 0x00664A, 0x000000, 0xFFFFFF, + 0x00664C, 0x00664E, 0x000000, 0xFFFFFF, + 0x006650, 0x006651, 0x000000, 0xFFFFFF, + 0x006653, 0x00665C, 0x000000, 0xFFFFFF, + 0x006660, 0x006661, 0x000000, 0xFFFFFF, + 0x006663, 0x006663, 0x000000, 0xFFFFFF, + 0x006665, 0x006665, 0x000000, 0xFFFFFF, + 0x00666A, 0x00666D, 0x000000, 0xFFFFFF, + 0x006671, 0x006673, 0x000000, 0xFFFFFF, + 0x006675, 0x006675, 0x000000, 0xFFFFFF, + 0x006677, 0x006679, 0x000000, 0xFFFFFF, + 0x00667B, 0x006680, 0x000000, 0xFFFFFF, + 0x006682, 0x006682, 0x000000, 0xFFFFFF, + 0x006685, 0x006686, 0x000000, 0xFFFFFF, + 0x00668A, 0x00668D, 0x000000, 0xFFFFFF, + 0x00668F, 0x006690, 0x000000, 0xFFFFFF, + 0x006692, 0x006695, 0x000000, 0xFFFFFF, + 0x006699, 0x00669C, 0x000000, 0xFFFFFF, + 0x00669E, 0x0066A1, 0x000000, 0xFFFFFF, + 0x0066A3, 0x0066A5, 0x000000, 0xFFFFFF, + 0x0066A7, 0x0066AA, 0x000000, 0xFFFFFF, + 0x0066AC, 0x0066AD, 0x000000, 0xFFFFFF, + 0x0066AF, 0x0066B3, 0x000000, 0xFFFFFF, + 0x0066B5, 0x0066B7, 0x000000, 0xFFFFFF, + 0x0066BA, 0x0066BB, 0x000000, 0xFFFFFF, + 0x0066BD, 0x0066BD, 0x000000, 0xFFFFFF, + 0x0066BF, 0x0066C0, 0x000000, 0xFFFFFF, + 0x0066C2, 0x0066C3, 0x000000, 0xFFFFFF, + 0x0066C5, 0x0066C6, 0x000000, 0xFFFFFF, + 0x0066C8, 0x0066C8, 0x000000, 0xFFFFFF, + 0x0066CA, 0x0066D5, 0x000000, 0xFFFFFF, + 0x0066D7, 0x0066D8, 0x000000, 0xFFFFFF, + 0x0066DB, 0x0066DB, 0x000000, 0xFFFFFF, + 0x0066DE, 0x0066DF, 0x000000, 0xFFFFFF, + 0x0066E1, 0x0066E5, 0x000000, 0xFFFFFF, + 0x0066E7, 0x0066E8, 0x000000, 0xFFFFFF, + 0x0066EA, 0x0066EF, 0x000000, 0xFFFFFF, + 0x0066F1, 0x0066F1, 0x000000, 0xFFFFFF, + 0x0066F6, 0x0066F6, 0x000000, 0xFFFFFF, + 0x0066FA, 0x0066FB, 0x000000, 0xFFFFFF, + 0x006701, 0x006702, 0x000000, 0xFFFFFF, + 0x006704, 0x006707, 0x000000, 0xFFFFFF, + 0x00670A, 0x00670A, 0x000000, 0xFFFFFF, + 0x00670C, 0x00670C, 0x000000, 0xFFFFFF, + 0x00670E, 0x00670E, 0x000000, 0xFFFFFF, + 0x006710, 0x006713, 0x000000, 0xFFFFFF, + 0x006718, 0x00671A, 0x000000, 0xFFFFFF, + 0x00671C, 0x00671C, 0x000000, 0xFFFFFF, + 0x006720, 0x006725, 0x000000, 0xFFFFFF, + 0x006729, 0x006729, 0x000000, 0xFFFFFF, + 0x00672F, 0x006730, 0x000000, 0xFFFFFF, + 0x006732, 0x006733, 0x000000, 0xFFFFFF, + 0x006735, 0x006735, 0x000000, 0xFFFFFF, + 0x006739, 0x006739, 0x000000, 0xFFFFFF, + 0x00673B, 0x00673C, 0x000000, 0xFFFFFF, + 0x00673E, 0x00673E, 0x000000, 0xFFFFFF, + 0x006740, 0x006740, 0x000000, 0xFFFFFF, + 0x006742, 0x006745, 0x000000, 0xFFFFFF, + 0x006747, 0x006748, 0x000000, 0xFFFFFF, + 0x00674A, 0x00674D, 0x000000, 0xFFFFFF, + 0x006752, 0x006752, 0x000000, 0xFFFFFF, + 0x006754, 0x006755, 0x000000, 0xFFFFFF, + 0x006757, 0x006758, 0x000000, 0xFFFFFF, + 0x00675A, 0x00675B, 0x000000, 0xFFFFFF, + 0x00675D, 0x00675D, 0x000000, 0xFFFFFF, + 0x006766, 0x006769, 0x000000, 0xFFFFFF, + 0x00676B, 0x00676C, 0x000000, 0xFFFFFF, + 0x00676E, 0x00676E, 0x000000, 0xFFFFFF, + 0x006774, 0x006774, 0x000000, 0xFFFFFF, + 0x006776, 0x006776, 0x000000, 0xFFFFFF, + 0x006778, 0x00677B, 0x000000, 0xFFFFFF, + 0x00677D, 0x00677D, 0x000000, 0xFFFFFF, + 0x006780, 0x006784, 0x000000, 0xFFFFFF, + 0x006786, 0x006786, 0x000000, 0xFFFFFF, + 0x006788, 0x006788, 0x000000, 0xFFFFFF, + 0x00678A, 0x00678A, 0x000000, 0xFFFFFF, + 0x00678D, 0x00678F, 0x000000, 0xFFFFFF, + 0x006791, 0x006794, 0x000000, 0xFFFFFF, + 0x006796, 0x006796, 0x000000, 0xFFFFFF, + 0x006798, 0x006799, 0x000000, 0xFFFFFF, + 0x00679B, 0x00679B, 0x000000, 0xFFFFFF, + 0x00679E, 0x00679F, 0x000000, 0xFFFFFF, + 0x0067A3, 0x0067A5, 0x000000, 0xFFFFFF, + 0x0067A7, 0x0067A8, 0x000000, 0xFFFFFF, + 0x0067AA, 0x0067AE, 0x000000, 0xFFFFFF, + 0x0067B0, 0x0067B2, 0x000000, 0xFFFFFF, + 0x0067B5, 0x0067B5, 0x000000, 0xFFFFFF, + 0x0067BA, 0x0067C0, 0x000000, 0xFFFFFF, + 0x0067C2, 0x0067C3, 0x000000, 0xFFFFFF, + 0x0067C5, 0x0067C5, 0x000000, 0xFFFFFF, + 0x0067C7, 0x0067C9, 0x000000, 0xFFFFFF, + 0x0067CB, 0x0067CD, 0x000000, 0xFFFFFF, + 0x0067D2, 0x0067D2, 0x000000, 0xFFFFFF, + 0x0067D5, 0x0067D7, 0x000000, 0xFFFFFF, + 0x0067D9, 0x0067D9, 0x000000, 0xFFFFFF, + 0x0067DB, 0x0067DC, 0x000000, 0xFFFFFF, + 0x0067DF, 0x0067E1, 0x000000, 0xFFFFFF, + 0x0067E3, 0x0067E3, 0x000000, 0xFFFFFF, + 0x0067E5, 0x0067E6, 0x000000, 0xFFFFFF, + 0x0067E8, 0x0067E8, 0x000000, 0xFFFFFF, + 0x0067EA, 0x0067EB, 0x000000, 0xFFFFFF, + 0x0067ED, 0x0067ED, 0x000000, 0xFFFFFF, + 0x0067F0, 0x0067F0, 0x000000, 0xFFFFFF, + 0x0067F2, 0x0067F2, 0x000000, 0xFFFFFF, + 0x0067F6, 0x0067FA, 0x000000, 0xFFFFFF, + 0x0067FC, 0x0067FD, 0x000000, 0xFFFFFF, + 0x006800, 0x006801, 0x000000, 0xFFFFFF, + 0x006805, 0x006812, 0x000000, 0xFFFFFF, + 0x006814, 0x006815, 0x000000, 0xFFFFFF, + 0x006818, 0x00681D, 0x000000, 0xFFFFFF, + 0x00681F, 0x006820, 0x000000, 0xFFFFFF, + 0x006823, 0x006828, 0x000000, 0xFFFFFF, + 0x00682C, 0x006831, 0x000000, 0xFFFFFF, + 0x006833, 0x006833, 0x000000, 0xFFFFFF, + 0x006835, 0x006837, 0x000000, 0xFFFFFF, + 0x00683A, 0x00683B, 0x000000, 0xFFFFFF, + 0x00683E, 0x00683F, 0x000000, 0xFFFFFF, + 0x006844, 0x006845, 0x000000, 0xFFFFFF, + 0x006847, 0x006847, 0x000000, 0xFFFFFF, + 0x006849, 0x00684C, 0x000000, 0xFFFFFF, + 0x00684F, 0x00684F, 0x000000, 0xFFFFFF, + 0x006852, 0x006852, 0x000000, 0xFFFFFF, + 0x006855, 0x006858, 0x000000, 0xFFFFFF, + 0x00685A, 0x00685B, 0x000000, 0xFFFFFF, + 0x00685E, 0x00685E, 0x000000, 0xFFFFFF, + 0x006860, 0x006862, 0x000000, 0xFFFFFF, + 0x006864, 0x006866, 0x000000, 0xFFFFFF, + 0x006868, 0x006873, 0x000000, 0xFFFFFF, + 0x006875, 0x006875, 0x000000, 0xFFFFFF, + 0x006878, 0x00687D, 0x000000, 0xFFFFFF, + 0x006880, 0x006880, 0x000000, 0xFFFFFF, + 0x006882, 0x006882, 0x000000, 0xFFFFFF, + 0x006884, 0x006884, 0x000000, 0xFFFFFF, + 0x006886, 0x00688C, 0x000000, 0xFFFFFF, + 0x00688E, 0x00688E, 0x000000, 0xFFFFFF, + 0x006890, 0x006892, 0x000000, 0xFFFFFF, + 0x006895, 0x006896, 0x000000, 0xFFFFFF, + 0x006898, 0x00689A, 0x000000, 0xFFFFFF, + 0x00689C, 0x00689C, 0x000000, 0xFFFFFF, + 0x00689E, 0x00689E, 0x000000, 0xFFFFFF, + 0x0068A1, 0x0068A1, 0x000000, 0xFFFFFF, + 0x0068A3, 0x0068A5, 0x000000, 0xFFFFFF, + 0x0068A9, 0x0068AC, 0x000000, 0xFFFFFF, + 0x0068AE, 0x0068AE, 0x000000, 0xFFFFFF, + 0x0068B2, 0x0068B2, 0x000000, 0xFFFFFF, + 0x0068B4, 0x0068B4, 0x000000, 0xFFFFFF, + 0x0068B7, 0x0068B8, 0x000000, 0xFFFFFF, + 0x0068BB, 0x0068BB, 0x000000, 0xFFFFFF, + 0x0068BD, 0x0068C3, 0x000000, 0xFFFFFF, + 0x0068C5, 0x0068C5, 0x000000, 0xFFFFFF, + 0x0068C7, 0x0068C8, 0x000000, 0xFFFFFF, + 0x0068CC, 0x0068CC, 0x000000, 0xFFFFFF, + 0x0068CE, 0x0068D1, 0x000000, 0xFFFFFF, + 0x0068D3, 0x0068D3, 0x000000, 0xFFFFFF, + 0x0068D6, 0x0068D6, 0x000000, 0xFFFFFF, + 0x0068D9, 0x0068D9, 0x000000, 0xFFFFFF, + 0x0068DB, 0x0068DE, 0x000000, 0xFFFFFF, + 0x0068E2, 0x0068E2, 0x000000, 0xFFFFFF, + 0x0068E4, 0x0068E6, 0x000000, 0xFFFFFF, + 0x0068E8, 0x0068ED, 0x000000, 0xFFFFFF, + 0x0068F0, 0x0068F1, 0x000000, 0xFFFFFF, + 0x0068F3, 0x0068F8, 0x000000, 0xFFFFFF, + 0x0068FB, 0x0068FF, 0x000000, 0xFFFFFF, + 0x006902, 0x006903, 0x000000, 0xFFFFFF, + 0x006906, 0x006907, 0x000000, 0xFFFFFF, + 0x006909, 0x00690A, 0x000000, 0xFFFFFF, + 0x006910, 0x006911, 0x000000, 0xFFFFFF, + 0x006913, 0x006918, 0x000000, 0xFFFFFF, + 0x00691D, 0x006920, 0x000000, 0xFFFFFF, + 0x006924, 0x006924, 0x000000, 0xFFFFFF, + 0x006927, 0x006927, 0x000000, 0xFFFFFF, + 0x006929, 0x006929, 0x000000, 0xFFFFFF, + 0x00692B, 0x00692F, 0x000000, 0xFFFFFF, + 0x006931, 0x006933, 0x000000, 0xFFFFFF, + 0x006935, 0x006935, 0x000000, 0xFFFFFF, + 0x006937, 0x006938, 0x000000, 0xFFFFFF, + 0x00693A, 0x00693C, 0x000000, 0xFFFFFF, + 0x00693E, 0x00693E, 0x000000, 0xFFFFFF, + 0x006940, 0x006949, 0x000000, 0xFFFFFF, + 0x00694B, 0x006952, 0x000000, 0xFFFFFF, + 0x006956, 0x006958, 0x000000, 0xFFFFFF, + 0x00695B, 0x00695B, 0x000000, 0xFFFFFF, + 0x00695F, 0x00695F, 0x000000, 0xFFFFFF, + 0x006963, 0x006969, 0x000000, 0xFFFFFF, + 0x00696C, 0x00696C, 0x000000, 0xFFFFFF, + 0x006970, 0x006972, 0x000000, 0xFFFFFF, + 0x006976, 0x006976, 0x000000, 0xFFFFFF, + 0x00697A, 0x00697B, 0x000000, 0xFFFFFF, + 0x00697F, 0x006980, 0x000000, 0xFFFFFF, + 0x006983, 0x006989, 0x000000, 0xFFFFFF, + 0x00698B, 0x00698D, 0x000000, 0xFFFFFF, + 0x00698F, 0x006990, 0x000000, 0xFFFFFF, + 0x006992, 0x006993, 0x000000, 0xFFFFFF, + 0x006996, 0x00699A, 0x000000, 0xFFFFFF, + 0x00699D, 0x00699F, 0x000000, 0xFFFFFF, + 0x0069A1, 0x0069A6, 0x000000, 0xFFFFFF, + 0x0069A8, 0x0069AD, 0x000000, 0xFFFFFF, + 0x0069AF, 0x0069B0, 0x000000, 0xFFFFFF, + 0x0069B3, 0x0069B3, 0x000000, 0xFFFFFF, + 0x0069B5, 0x0069BA, 0x000000, 0xFFFFFF, + 0x0069BC, 0x0069BD, 0x000000, 0xFFFFFF, + 0x0069C0, 0x0069C0, 0x000000, 0xFFFFFF, + 0x0069C2, 0x0069C2, 0x000000, 0xFFFFFF, + 0x0069C4, 0x0069C6, 0x000000, 0xFFFFFF, + 0x0069C8, 0x0069C9, 0x000000, 0xFFFFFF, + 0x0069CF, 0x0069CF, 0x000000, 0xFFFFFF, + 0x0069D1, 0x0069D2, 0x000000, 0xFFFFFF, + 0x0069D4, 0x0069D7, 0x000000, 0xFFFFFF, + 0x0069DA, 0x0069DC, 0x000000, 0xFFFFFF, + 0x0069DF, 0x0069E6, 0x000000, 0xFFFFFF, + 0x0069E9, 0x0069EA, 0x000000, 0xFFFFFF, + 0x0069EC, 0x0069EC, 0x000000, 0xFFFFFF, + 0x0069EE, 0x0069F1, 0x000000, 0xFFFFFF, + 0x0069F3, 0x0069F8, 0x000000, 0xFFFFFF, + 0x0069FA, 0x0069FA, 0x000000, 0xFFFFFF, + 0x0069FC, 0x0069FC, 0x000000, 0xFFFFFF, + 0x0069FE, 0x0069FE, 0x000000, 0xFFFFFF, + 0x006A00, 0x006A01, 0x000000, 0xFFFFFF, + 0x006A03, 0x006A04, 0x000000, 0xFFFFFF, + 0x006A06, 0x006A09, 0x000000, 0xFFFFFF, + 0x006A0D, 0x006A11, 0x000000, 0xFFFFFF, + 0x006A15, 0x006A16, 0x000000, 0xFFFFFF, + 0x006A18, 0x006A18, 0x000000, 0xFFFFFF, + 0x006A1A, 0x006A1A, 0x000000, 0xFFFFFF, + 0x006A1C, 0x006A1D, 0x000000, 0xFFFFFF, + 0x006A20, 0x006A20, 0x000000, 0xFFFFFF, + 0x006A24, 0x006A28, 0x000000, 0xFFFFFF, + 0x006A2C, 0x006A2D, 0x000000, 0xFFFFFF, + 0x006A2F, 0x006A34, 0x000000, 0xFFFFFF, + 0x006A37, 0x006A37, 0x000000, 0xFFFFFF, + 0x006A3B, 0x006A3C, 0x000000, 0xFFFFFF, + 0x006A3E, 0x006A43, 0x000000, 0xFFFFFF, + 0x006A45, 0x006A46, 0x000000, 0xFFFFFF, + 0x006A49, 0x006A4A, 0x000000, 0xFFFFFF, + 0x006A4C, 0x006A57, 0x000000, 0xFFFFFF, + 0x006A5A, 0x006A5E, 0x000000, 0xFFFFFF, + 0x006A60, 0x006A60, 0x000000, 0xFFFFFF, + 0x006A63, 0x006A65, 0x000000, 0xFFFFFF, + 0x006A67, 0x006A71, 0x000000, 0xFFFFFF, + 0x006A73, 0x006A77, 0x000000, 0xFFFFFF, + 0x006A79, 0x006A7E, 0x000000, 0xFFFFFF, + 0x006A81, 0x006A83, 0x000000, 0xFFFFFF, + 0x006A85, 0x006A8C, 0x000000, 0xFFFFFF, + 0x006A8F, 0x006A8F, 0x000000, 0xFFFFFF, + 0x006A91, 0x006A96, 0x000000, 0xFFFFFF, + 0x006A98, 0x006A9B, 0x000000, 0xFFFFFF, + 0x006A9D, 0x006A9F, 0x000000, 0xFFFFFF, + 0x006AA1, 0x006AA1, 0x000000, 0xFFFFFF, + 0x006AA4, 0x006AA9, 0x000000, 0xFFFFFF, + 0x006AAB, 0x006AAB, 0x000000, 0xFFFFFF, + 0x006AAD, 0x006AAD, 0x000000, 0xFFFFFF, + 0x006AAF, 0x006AB2, 0x000000, 0xFFFFFF, + 0x006AB4, 0x006AB7, 0x000000, 0xFFFFFF, + 0x006AB9, 0x006ABA, 0x000000, 0xFFFFFF, + 0x006ABC, 0x006AC0, 0x000000, 0xFFFFFF, + 0x006AC4, 0x006AD0, 0x000000, 0xFFFFFF, + 0x006AD2, 0x006AD2, 0x000000, 0xFFFFFF, + 0x006AD4, 0x006AD9, 0x000000, 0xFFFFFF, + 0x006ADC, 0x006ADD, 0x000000, 0xFFFFFF, + 0x006AE0, 0x006AE7, 0x000000, 0xFFFFFF, + 0x006AE9, 0x006AE9, 0x000000, 0xFFFFFF, + 0x006AEB, 0x006AF9, 0x000000, 0xFFFFFF, + 0x006AFC, 0x006B03, 0x000000, 0xFFFFFF, + 0x006B06, 0x006B09, 0x000000, 0xFFFFFF, + 0x006B0B, 0x006B11, 0x000000, 0xFFFFFF, + 0x006B13, 0x006B15, 0x000000, 0xFFFFFF, + 0x006B17, 0x006B1C, 0x000000, 0xFFFFFF, + 0x006B1E, 0x006B1E, 0x000000, 0xFFFFFF, + 0x006B22, 0x006B22, 0x000000, 0xFFFFFF, + 0x006B24, 0x006B26, 0x000000, 0xFFFFFF, + 0x006B28, 0x006B31, 0x000000, 0xFFFFFF, + 0x006B33, 0x006B36, 0x000000, 0xFFFFFF, + 0x006B3B, 0x006B3C, 0x000000, 0xFFFFFF, + 0x006B3F, 0x006B42, 0x000000, 0xFFFFFF, + 0x006B44, 0x006B46, 0x000000, 0xFFFFFF, + 0x006B48, 0x006B48, 0x000000, 0xFFFFFF, + 0x006B4A, 0x006B4B, 0x000000, 0xFFFFFF, + 0x006B4D, 0x006B4D, 0x000000, 0xFFFFFF, + 0x006B4F, 0x006B4F, 0x000000, 0xFFFFFF, + 0x006B51, 0x006B52, 0x000000, 0xFFFFFF, + 0x006B55, 0x006B58, 0x000000, 0xFFFFFF, + 0x006B5A, 0x006B5A, 0x000000, 0xFFFFFF, + 0x006B5C, 0x006B5E, 0x000000, 0xFFFFFF, + 0x006B60, 0x006B60, 0x000000, 0xFFFFFF, + 0x006B65, 0x006B65, 0x000000, 0xFFFFFF, + 0x006B67, 0x006B68, 0x000000, 0xFFFFFF, + 0x006B6B, 0x006B6E, 0x000000, 0xFFFFFF, + 0x006B70, 0x006B72, 0x000000, 0xFFFFFF, + 0x006B75, 0x006B77, 0x000000, 0xFFFFFF, + 0x006B7A, 0x006B7A, 0x000000, 0xFFFFFF, + 0x006B7C, 0x006B7E, 0x000000, 0xFFFFFF, + 0x006B81, 0x006B82, 0x000000, 0xFFFFFF, + 0x006B85, 0x006B85, 0x000000, 0xFFFFFF, + 0x006B87, 0x006B88, 0x000000, 0xFFFFFF, + 0x006B8C, 0x006B8C, 0x000000, 0xFFFFFF, + 0x006B8E, 0x006B94, 0x000000, 0xFFFFFF, + 0x006B97, 0x006B97, 0x000000, 0xFFFFFF, + 0x006B99, 0x006B9D, 0x000000, 0xFFFFFF, + 0x006B9F, 0x006BA3, 0x000000, 0xFFFFFF, + 0x006BA5, 0x006BA9, 0x000000, 0xFFFFFF, + 0x006BAC, 0x006BAE, 0x000000, 0xFFFFFF, + 0x006BB0, 0x006BB0, 0x000000, 0xFFFFFF, + 0x006BB6, 0x006BB6, 0x000000, 0xFFFFFF, + 0x006BB8, 0x006BB9, 0x000000, 0xFFFFFF, + 0x006BBD, 0x006BBE, 0x000000, 0xFFFFFF, + 0x006BC1, 0x006BC4, 0x000000, 0xFFFFFF, + 0x006BC7, 0x006BCA, 0x000000, 0xFFFFFF, + 0x006BCC, 0x006BCC, 0x000000, 0xFFFFFF, + 0x006BCF, 0x006BD1, 0x000000, 0xFFFFFF, + 0x006BD5, 0x006BD7, 0x000000, 0xFFFFFF, + 0x006BD9, 0x006BDA, 0x000000, 0xFFFFFF, + 0x006BDC, 0x006BDE, 0x000000, 0xFFFFFF, + 0x006BE0, 0x006BEA, 0x000000, 0xFFFFFF, + 0x006BED, 0x006BEE, 0x000000, 0xFFFFFF, + 0x006BF0, 0x006BF2, 0x000000, 0xFFFFFF, + 0x006BF4, 0x006C07, 0x000000, 0xFFFFFF, + 0x006C09, 0x006C0E, 0x000000, 0xFFFFFF, + 0x006C10, 0x006C10, 0x000000, 0xFFFFFF, + 0x006C12, 0x006C12, 0x000000, 0xFFFFFF, + 0x006C15, 0x006C16, 0x000000, 0xFFFFFF, + 0x006C18, 0x006C1A, 0x000000, 0xFFFFFF, + 0x006C1C, 0x006C22, 0x000000, 0xFFFFFF, + 0x006C25, 0x006C33, 0x000000, 0xFFFFFF, + 0x006C35, 0x006C36, 0x000000, 0xFFFFFF, + 0x006C39, 0x006C3D, 0x000000, 0xFFFFFF, + 0x006C3F, 0x006C3F, 0x000000, 0xFFFFFF, + 0x006C43, 0x006C4D, 0x000000, 0xFFFFFF, + 0x006C4F, 0x006C4F, 0x000000, 0xFFFFFF, + 0x006C51, 0x006C54, 0x000000, 0xFFFFFF, + 0x006C56, 0x006C56, 0x000000, 0xFFFFFF, + 0x006C58, 0x006C59, 0x000000, 0xFFFFFF, + 0x006C5B, 0x006C5C, 0x000000, 0xFFFFFF, + 0x006C61, 0x006C61, 0x000000, 0xFFFFFF, + 0x006C63, 0x006C67, 0x000000, 0xFFFFFF, + 0x006C69, 0x006C69, 0x000000, 0xFFFFFF, + 0x006C6B, 0x006C6F, 0x000000, 0xFFFFFF, + 0x006C71, 0x006C71, 0x000000, 0xFFFFFF, + 0x006C74, 0x006C79, 0x000000, 0xFFFFFF, + 0x006C7B, 0x006C7C, 0x000000, 0xFFFFFF, + 0x006C7F, 0x006C80, 0x000000, 0xFFFFFF, + 0x006C84, 0x006C87, 0x000000, 0xFFFFFF, + 0x006C89, 0x006C8B, 0x000000, 0xFFFFFF, + 0x006C8E, 0x006C8F, 0x000000, 0xFFFFFF, + 0x006C91, 0x006C91, 0x000000, 0xFFFFFF, + 0x006C94, 0x006C95, 0x000000, 0xFFFFFF, + 0x006C97, 0x006C98, 0x000000, 0xFFFFFF, + 0x006C9C, 0x006CA0, 0x000000, 0xFFFFFF, + 0x006CA3, 0x006CAA, 0x000000, 0xFFFFFF, + 0x006CAC, 0x006CAD, 0x000000, 0xFFFFFF, + 0x006CAF, 0x006CB0, 0x000000, 0xFFFFFF, + 0x006CB2, 0x006CB2, 0x000000, 0xFFFFFF, + 0x006CB4, 0x006CB7, 0x000000, 0xFFFFFF, + 0x006CC0, 0x006CC0, 0x000000, 0xFFFFFF, + 0x006CC2, 0x006CC3, 0x000000, 0xFFFFFF, + 0x006CC6, 0x006CC8, 0x000000, 0xFFFFFF, + 0x006CCB, 0x006CCB, 0x000000, 0xFFFFFF, + 0x006CCD, 0x006CD2, 0x000000, 0xFFFFFF, + 0x006CD4, 0x006CD4, 0x000000, 0xFFFFFF, + 0x006CD6, 0x006CD6, 0x000000, 0xFFFFFF, + 0x006CD8, 0x006CD8, 0x000000, 0xFFFFFF, + 0x006CDA, 0x006CDA, 0x000000, 0xFFFFFF, + 0x006CDC, 0x006CDC, 0x000000, 0xFFFFFF, + 0x006CDE, 0x006CE0, 0x000000, 0xFFFFFF, + 0x006CE4, 0x006CE4, 0x000000, 0xFFFFFF, + 0x006CE6, 0x006CE7, 0x000000, 0xFFFFFF, + 0x006CE9, 0x006CE9, 0x000000, 0xFFFFFF, + 0x006CEB, 0x006CEE, 0x000000, 0xFFFFFF, + 0x006CF2, 0x006CF2, 0x000000, 0xFFFFFF, + 0x006CF4, 0x006D0A, 0x000000, 0xFFFFFF, + 0x006D0D, 0x006D11, 0x000000, 0xFFFFFF, + 0x006D13, 0x006D16, 0x000000, 0xFFFFFF, + 0x006D18, 0x006D18, 0x000000, 0xFFFFFF, + 0x006D1A, 0x006D1A, 0x000000, 0xFFFFFF, + 0x006D1C, 0x006D1D, 0x000000, 0xFFFFFF, + 0x006D20, 0x006D24, 0x000000, 0xFFFFFF, + 0x006D26, 0x006D28, 0x000000, 0xFFFFFF, + 0x006D2C, 0x006D31, 0x000000, 0xFFFFFF, + 0x006D34, 0x006D34, 0x000000, 0xFFFFFF, + 0x006D37, 0x006D37, 0x000000, 0xFFFFFF, + 0x006D39, 0x006D3A, 0x000000, 0xFFFFFF, + 0x006D3C, 0x006D3C, 0x000000, 0xFFFFFF, + 0x006D3F, 0x006D40, 0x000000, 0xFFFFFF, + 0x006D42, 0x006D43, 0x000000, 0xFFFFFF, + 0x006D46, 0x006D58, 0x000000, 0xFFFFFF, + 0x006D5B, 0x006D5B, 0x000000, 0xFFFFFF, + 0x006D5D, 0x006D62, 0x000000, 0xFFFFFF, + 0x006D65, 0x006D65, 0x000000, 0xFFFFFF, + 0x006D67, 0x006D68, 0x000000, 0xFFFFFF, + 0x006D6B, 0x006D6B, 0x000000, 0xFFFFFF, + 0x006D6D, 0x006D6D, 0x000000, 0xFFFFFF, + 0x006D6F, 0x006D73, 0x000000, 0xFFFFFF, + 0x006D75, 0x006D76, 0x000000, 0xFFFFFF, + 0x006D7A, 0x006D84, 0x000000, 0xFFFFFF, + 0x006D86, 0x006D87, 0x000000, 0xFFFFFF, + 0x006D89, 0x006D8B, 0x000000, 0xFFFFFF, + 0x006D8D, 0x006D8D, 0x000000, 0xFFFFFF, + 0x006D8F, 0x006D92, 0x000000, 0xFFFFFF, + 0x006D94, 0x006D94, 0x000000, 0xFFFFFF, + 0x006D96, 0x006D98, 0x000000, 0xFFFFFF, + 0x006D9A, 0x006D9A, 0x000000, 0xFFFFFF, + 0x006D9D, 0x006DAE, 0x000000, 0xFFFFFF, + 0x006DB0, 0x006DB1, 0x000000, 0xFFFFFF, + 0x006DB3, 0x006DB4, 0x000000, 0xFFFFFF, + 0x006DB6, 0x006DB7, 0x000000, 0xFFFFFF, + 0x006DB9, 0x006DBB, 0x000000, 0xFFFFFF, + 0x006DBD, 0x006DBF, 0x000000, 0xFFFFFF, + 0x006DC1, 0x006DC4, 0x000000, 0xFFFFFF, + 0x006DC8, 0x006DCA, 0x000000, 0xFFFFFF, + 0x006DCD, 0x006DD0, 0x000000, 0xFFFFFF, + 0x006DD3, 0x006DD4, 0x000000, 0xFFFFFF, + 0x006DD6, 0x006DD7, 0x000000, 0xFFFFFF, + 0x006DDA, 0x006DDD, 0x000000, 0xFFFFFF, + 0x006DDF, 0x006DE0, 0x000000, 0xFFFFFF, + 0x006DE2, 0x006DE3, 0x000000, 0xFFFFFF, + 0x006DE5, 0x006DE5, 0x000000, 0xFFFFFF, + 0x006DE7, 0x006DE7, 0x000000, 0xFFFFFF, + 0x006DE9, 0x006DE9, 0x000000, 0xFFFFFF, + 0x006DED, 0x006DED, 0x000000, 0xFFFFFF, + 0x006DEF, 0x006DF0, 0x000000, 0xFFFFFF, + 0x006DF2, 0x006DF2, 0x000000, 0xFFFFFF, + 0x006DF4, 0x006DF4, 0x000000, 0xFFFFFF, + 0x006DF6, 0x006DF6, 0x000000, 0xFFFFFF, + 0x006DF8, 0x006DF8, 0x000000, 0xFFFFFF, + 0x006DFC, 0x006E04, 0x000000, 0xFFFFFF, + 0x006E06, 0x006E06, 0x000000, 0xFFFFFF, + 0x006E0C, 0x006E12, 0x000000, 0xFFFFFF, + 0x006E14, 0x006E14, 0x000000, 0xFFFFFF, + 0x006E16, 0x006E18, 0x000000, 0xFFFFFF, + 0x006E1C, 0x006E1C, 0x000000, 0xFFFFFF, + 0x006E1E, 0x006E1E, 0x000000, 0xFFFFFF, + 0x006E22, 0x006E22, 0x000000, 0xFFFFFF, + 0x006E27, 0x006E28, 0x000000, 0xFFFFFF, + 0x006E2A, 0x006E2A, 0x000000, 0xFFFFFF, + 0x006E30, 0x006E37, 0x000000, 0xFFFFFF, + 0x006E39, 0x006E39, 0x000000, 0xFFFFFF, + 0x006E3B, 0x006E3D, 0x000000, 0xFFFFFF, + 0x006E3F, 0x006E42, 0x000000, 0xFFFFFF, + 0x006E44, 0x006E49, 0x000000, 0xFFFFFF, + 0x006E4B, 0x006E4C, 0x000000, 0xFFFFFF, + 0x006E4F, 0x006E55, 0x000000, 0xFFFFFF, + 0x006E57, 0x006E57, 0x000000, 0xFFFFFF, + 0x006E59, 0x006E5A, 0x000000, 0xFFFFFF, + 0x006E5C, 0x006E5E, 0x000000, 0xFFFFFF, + 0x006E60, 0x006E66, 0x000000, 0xFFFFFF, + 0x006E68, 0x006E6A, 0x000000, 0xFFFFFF, + 0x006E6C, 0x006E6D, 0x000000, 0xFFFFFF, + 0x006E70, 0x006E71, 0x000000, 0xFFFFFF, + 0x006E73, 0x006E75, 0x000000, 0xFFFFFF, + 0x006E77, 0x006E7D, 0x000000, 0xFFFFFF, + 0x006E81, 0x006E81, 0x000000, 0xFFFFFF, + 0x006E83, 0x006E8B, 0x000000, 0xFFFFFF, + 0x006E8D, 0x006E8E, 0x000000, 0xFFFFFF, + 0x006E91, 0x006E95, 0x000000, 0xFFFFFF, + 0x006E97, 0x006E97, 0x000000, 0xFFFFFF, + 0x006E99, 0x006E9B, 0x000000, 0xFFFFFF, + 0x006E9E, 0x006E9E, 0x000000, 0xFFFFFF, + 0x006EA0, 0x006EA1, 0x000000, 0xFFFFFF, + 0x006EA3, 0x006EA4, 0x000000, 0xFFFFFF, + 0x006EA6, 0x006EA9, 0x000000, 0xFFFFFF, + 0x006EAB, 0x006EAE, 0x000000, 0xFFFFFF, + 0x006EB0, 0x006EB1, 0x000000, 0xFFFFFF, + 0x006EB3, 0x006EB5, 0x000000, 0xFFFFFF, + 0x006EB8, 0x006EB9, 0x000000, 0xFFFFFF, + 0x006EBB, 0x006EBC, 0x000000, 0xFFFFFF, + 0x006EBE, 0x006EC1, 0x000000, 0xFFFFFF, + 0x006EC3, 0x006EC3, 0x000000, 0xFFFFFF, + 0x006EC6, 0x006EC8, 0x000000, 0xFFFFFF, + 0x006ECA, 0x006ECA, 0x000000, 0xFFFFFF, + 0x006ECD, 0x006ED0, 0x000000, 0xFFFFFF, + 0x006ED2, 0x006ED2, 0x000000, 0xFFFFFF, + 0x006ED6, 0x006EDC, 0x000000, 0xFFFFFF, + 0x006EDF, 0x006EEB, 0x000000, 0xFFFFFF, + 0x006EED, 0x006EEE, 0x000000, 0xFFFFFF, + 0x006EF0, 0x006EF1, 0x000000, 0xFFFFFF, + 0x006EF3, 0x006EF3, 0x000000, 0xFFFFFF, + 0x006EF5, 0x006EF6, 0x000000, 0xFFFFFF, + 0x006EF9, 0x006EFD, 0x000000, 0xFFFFFF, + 0x006F00, 0x006F00, 0x000000, 0xFFFFFF, + 0x006F03, 0x006F05, 0x000000, 0xFFFFFF, + 0x006F07, 0x006F08, 0x000000, 0xFFFFFF, + 0x006F0A, 0x006F0E, 0x000000, 0xFFFFFF, + 0x006F10, 0x006F10, 0x000000, 0xFFFFFF, + 0x006F12, 0x006F12, 0x000000, 0xFFFFFF, + 0x006F16, 0x006F1F, 0x000000, 0xFFFFFF, + 0x006F21, 0x006F21, 0x000000, 0xFFFFFF, + 0x006F24, 0x006F2A, 0x000000, 0xFFFFFF, + 0x006F2D, 0x006F30, 0x000000, 0xFFFFFF, + 0x006F33, 0x006F37, 0x000000, 0xFFFFFF, + 0x006F39, 0x006F3D, 0x000000, 0xFFFFFF, + 0x006F40, 0x006F40, 0x000000, 0xFFFFFF, + 0x006F42, 0x006F44, 0x000000, 0xFFFFFF, + 0x006F46, 0x006F53, 0x000000, 0xFFFFFF, + 0x006F55, 0x006F57, 0x000000, 0xFFFFFF, + 0x006F59, 0x006F5A, 0x000000, 0xFFFFFF, + 0x006F5D, 0x006F5E, 0x000000, 0xFFFFFF, + 0x006F60, 0x006F63, 0x000000, 0xFFFFFF, + 0x006F65, 0x006F65, 0x000000, 0xFFFFFF, + 0x006F67, 0x006F6C, 0x000000, 0xFFFFFF, + 0x006F71, 0x006F73, 0x000000, 0xFFFFFF, + 0x006F75, 0x006F77, 0x000000, 0xFFFFFF, + 0x006F79, 0x006F79, 0x000000, 0xFFFFFF, + 0x006F7B, 0x006F7B, 0x000000, 0xFFFFFF, + 0x006F7D, 0x006F7F, 0x000000, 0xFFFFFF, + 0x006F83, 0x006F83, 0x000000, 0xFFFFFF, + 0x006F85, 0x006F85, 0x000000, 0xFFFFFF, + 0x006F87, 0x006F8D, 0x000000, 0xFFFFFF, + 0x006F8F, 0x006F90, 0x000000, 0xFFFFFF, + 0x006F92, 0x006F96, 0x000000, 0xFFFFFF, + 0x006F98, 0x006FA0, 0x000000, 0xFFFFFF, + 0x006FA2, 0x006FA2, 0x000000, 0xFFFFFF, + 0x006FA5, 0x006FA9, 0x000000, 0xFFFFFF, + 0x006FAB, 0x006FB0, 0x000000, 0xFFFFFF, + 0x006FB2, 0x006FB2, 0x000000, 0xFFFFFF, + 0x006FB4, 0x006FB8, 0x000000, 0xFFFFFF, + 0x006FBA, 0x006FBF, 0x000000, 0xFFFFFF, + 0x006FC4, 0x006FC5, 0x000000, 0xFFFFFF, + 0x006FC7, 0x006FD3, 0x000000, 0xFFFFFF, + 0x006FD6, 0x006FD7, 0x000000, 0xFFFFFF, + 0x006FD9, 0x006FDA, 0x000000, 0xFFFFFF, + 0x006FDC, 0x006FDE, 0x000000, 0xFFFFFF, + 0x006FE2, 0x006FE3, 0x000000, 0xFFFFFF, + 0x006FE5, 0x006FEA, 0x000000, 0xFFFFFF, + 0x006FED, 0x006FED, 0x000000, 0xFFFFFF, + 0x006FF0, 0x006FF0, 0x000000, 0xFFFFFF, + 0x006FF2, 0x006FF2, 0x000000, 0xFFFFFF, + 0x006FF4, 0x006FF5, 0x000000, 0xFFFFFF, + 0x006FF7, 0x006FF9, 0x000000, 0xFFFFFF, + 0x006FFB, 0x006FFD, 0x000000, 0xFFFFFF, + 0x006FFF, 0x007000, 0x000000, 0xFFFFFF, + 0x007002, 0x007008, 0x000000, 0xFFFFFF, + 0x00700A, 0x00700A, 0x000000, 0xFFFFFF, + 0x00700C, 0x00700E, 0x000000, 0xFFFFFF, + 0x007010, 0x007010, 0x000000, 0xFFFFFF, + 0x007012, 0x007014, 0x000000, 0xFFFFFF, + 0x007016, 0x007017, 0x000000, 0xFFFFFF, + 0x007019, 0x007019, 0x000000, 0xFFFFFF, + 0x00701C, 0x00701C, 0x000000, 0xFFFFFF, + 0x007020, 0x007025, 0x000000, 0xFFFFFF, + 0x007028, 0x00702B, 0x000000, 0xFFFFFF, + 0x00702D, 0x00702F, 0x000000, 0xFFFFFF, + 0x007031, 0x007031, 0x000000, 0xFFFFFF, + 0x007033, 0x00703D, 0x000000, 0xFFFFFF, + 0x00703F, 0x00704B, 0x000000, 0xFFFFFF, + 0x00704D, 0x007050, 0x000000, 0xFFFFFF, + 0x007052, 0x007057, 0x000000, 0xFFFFFF, + 0x007059, 0x007062, 0x000000, 0xFFFFFF, + 0x007064, 0x00706A, 0x000000, 0xFFFFFF, + 0x00706C, 0x00706E, 0x000000, 0xFFFFFF, + 0x007071, 0x007077, 0x000000, 0xFFFFFF, + 0x007079, 0x00707B, 0x000000, 0xFFFFFF, + 0x00707E, 0x007088, 0x000000, 0xFFFFFF, + 0x00708B, 0x00708D, 0x000000, 0xFFFFFF, + 0x00708F, 0x007091, 0x000000, 0xFFFFFF, + 0x007093, 0x007098, 0x000000, 0xFFFFFF, + 0x00709A, 0x0070AB, 0x000000, 0xFFFFFF, + 0x0070B0, 0x0070B2, 0x000000, 0xFFFFFF, + 0x0070B4, 0x0070B7, 0x000000, 0xFFFFFF, + 0x0070BB, 0x0070C7, 0x000000, 0xFFFFFF, + 0x0070C9, 0x0070CA, 0x000000, 0xFFFFFF, + 0x0070CC, 0x0070CE, 0x000000, 0xFFFFFF, + 0x0070D0, 0x0070D8, 0x000000, 0xFFFFFF, + 0x0070DA, 0x0070DC, 0x000000, 0xFFFFFF, + 0x0070DE, 0x0070DE, 0x000000, 0xFFFFFF, + 0x0070E0, 0x0070F0, 0x000000, 0xFFFFFF, + 0x0070F2, 0x0070F8, 0x000000, 0xFFFFFF, + 0x0070FA, 0x0070FC, 0x000000, 0xFFFFFF, + 0x0070FE, 0x007108, 0x000000, 0xFFFFFF, + 0x00710A, 0x007113, 0x000000, 0xFFFFFF, + 0x007115, 0x007118, 0x000000, 0xFFFFFF, + 0x00711B, 0x00711B, 0x000000, 0xFFFFFF, + 0x00711D, 0x007120, 0x000000, 0xFFFFFF, + 0x007122, 0x007125, 0x000000, 0xFFFFFF, + 0x007127, 0x007135, 0x000000, 0xFFFFFF, + 0x007137, 0x00713B, 0x000000, 0xFFFFFF, + 0x00713D, 0x007148, 0x000000, 0xFFFFFF, + 0x00714A, 0x00714B, 0x000000, 0xFFFFFF, + 0x00714D, 0x00714D, 0x000000, 0xFFFFFF, + 0x00714F, 0x007154, 0x000000, 0xFFFFFF, + 0x007157, 0x007158, 0x000000, 0xFFFFFF, + 0x00715A, 0x007161, 0x000000, 0xFFFFFF, + 0x007163, 0x007163, 0x000000, 0xFFFFFF, + 0x007168, 0x007168, 0x000000, 0xFFFFFF, + 0x00716A, 0x00716B, 0x000000, 0xFFFFFF, + 0x00716D, 0x00716D, 0x000000, 0xFFFFFF, + 0x00716F, 0x00717C, 0x000000, 0xFFFFFF, + 0x00717E, 0x007183, 0x000000, 0xFFFFFF, + 0x007185, 0x007187, 0x000000, 0xFFFFFF, + 0x007189, 0x007189, 0x000000, 0xFFFFFF, + 0x00718B, 0x00718E, 0x000000, 0xFFFFFF, + 0x007190, 0x007193, 0x000000, 0xFFFFFF, + 0x007196, 0x007198, 0x000000, 0xFFFFFF, + 0x00719A, 0x00719E, 0x000000, 0xFFFFFF, + 0x0071A0, 0x0071A7, 0x000000, 0xFFFFFF, + 0x0071A9, 0x0071AB, 0x000000, 0xFFFFFF, + 0x0071AD, 0x0071B0, 0x000000, 0xFFFFFF, + 0x0071B2, 0x0071B8, 0x000000, 0xFFFFFF, + 0x0071BA, 0x0071BD, 0x000000, 0xFFFFFF, + 0x0071BF, 0x0071C2, 0x000000, 0xFFFFFF, + 0x0071C4, 0x0071C7, 0x000000, 0xFFFFFF, + 0x0071CA, 0x0071CD, 0x000000, 0xFFFFFF, + 0x0071CF, 0x0071CF, 0x000000, 0xFFFFFF, + 0x0071D1, 0x0071D1, 0x000000, 0xFFFFFF, + 0x0071D3, 0x0071D3, 0x000000, 0xFFFFFF, + 0x0071D6, 0x0071D6, 0x000000, 0xFFFFFF, + 0x0071D8, 0x0071DE, 0x000000, 0xFFFFFF, + 0x0071E1, 0x0071E4, 0x000000, 0xFFFFFF, + 0x0071E8, 0x0071EB, 0x000000, 0xFFFFFF, + 0x0071EF, 0x0071F4, 0x000000, 0xFFFFFF, + 0x0071F6, 0x0071F8, 0x000000, 0xFFFFFF, + 0x0071FA, 0x0071FA, 0x000000, 0xFFFFFF, + 0x0071FD, 0x0071FE, 0x000000, 0xFFFFFF, + 0x007200, 0x007205, 0x000000, 0xFFFFFF, + 0x007207, 0x00720C, 0x000000, 0xFFFFFF, + 0x00720E, 0x00720F, 0x000000, 0xFFFFFF, + 0x007211, 0x00721A, 0x000000, 0xFFFFFF, + 0x00721C, 0x007227, 0x000000, 0xFFFFFF, + 0x007229, 0x007229, 0x000000, 0xFFFFFF, + 0x00722B, 0x00722B, 0x000000, 0xFFFFFF, + 0x00722E, 0x00722F, 0x000000, 0xFFFFFF, + 0x007231, 0x007231, 0x000000, 0xFFFFFF, + 0x007233, 0x007234, 0x000000, 0xFFFFFF, + 0x007237, 0x007239, 0x000000, 0xFFFFFF, + 0x007241, 0x007245, 0x000000, 0xFFFFFF, + 0x007249, 0x00724A, 0x000000, 0xFFFFFF, + 0x00724D, 0x007251, 0x000000, 0xFFFFFF, + 0x007253, 0x007257, 0x000000, 0xFFFFFF, + 0x00725A, 0x00725A, 0x000000, 0xFFFFFF, + 0x00725C, 0x00725C, 0x000000, 0xFFFFFF, + 0x00725E, 0x00725E, 0x000000, 0xFFFFFF, + 0x007260, 0x007260, 0x000000, 0xFFFFFF, + 0x007263, 0x007266, 0x000000, 0xFFFFFF, + 0x007268, 0x007268, 0x000000, 0xFFFFFF, + 0x00726A, 0x007271, 0x000000, 0xFFFFFF, + 0x007273, 0x007273, 0x000000, 0xFFFFFF, + 0x007275, 0x007278, 0x000000, 0xFFFFFF, + 0x00727A, 0x00727C, 0x000000, 0xFFFFFF, + 0x00727F, 0x00727F, 0x000000, 0xFFFFFF, + 0x007283, 0x007286, 0x000000, 0xFFFFFF, + 0x007288, 0x007291, 0x000000, 0xFFFFFF, + 0x007293, 0x007295, 0x000000, 0xFFFFFF, + 0x007297, 0x00729F, 0x000000, 0xFFFFFF, + 0x0072A1, 0x0072A1, 0x000000, 0xFFFFFF, + 0x0072A3, 0x0072A6, 0x000000, 0xFFFFFF, + 0x0072A8, 0x0072AB, 0x000000, 0xFFFFFF, + 0x0072AD, 0x0072AE, 0x000000, 0xFFFFFF, + 0x0072B0, 0x0072B1, 0x000000, 0xFFFFFF, + 0x0072B3, 0x0072B5, 0x000000, 0xFFFFFF, + 0x0072B7, 0x0072B8, 0x000000, 0xFFFFFF, + 0x0072BA, 0x0072C1, 0x000000, 0xFFFFFF, + 0x0072C5, 0x0072C5, 0x000000, 0xFFFFFF, + 0x0072C7, 0x0072CD, 0x000000, 0xFFFFFF, + 0x0072CF, 0x0072CF, 0x000000, 0xFFFFFF, + 0x0072D1, 0x0072D1, 0x000000, 0xFFFFFF, + 0x0072D3, 0x0072D6, 0x000000, 0xFFFFFF, + 0x0072D8, 0x0072D8, 0x000000, 0xFFFFFF, + 0x0072DA, 0x0072DA, 0x000000, 0xFFFFFF, + 0x0072DC, 0x0072DF, 0x000000, 0xFFFFFF, + 0x0072E3, 0x0072E8, 0x000000, 0xFFFFFF, + 0x0072EA, 0x0072EB, 0x000000, 0xFFFFFF, + 0x0072EE, 0x0072F6, 0x000000, 0xFFFFFF, + 0x0072FA, 0x0072FB, 0x000000, 0xFFFFFF, + 0x0072FE, 0x007309, 0x000000, 0xFFFFFF, + 0x00730B, 0x007315, 0x000000, 0xFFFFFF, + 0x007318, 0x00731A, 0x000000, 0xFFFFFF, + 0x00731E, 0x00731E, 0x000000, 0xFFFFFF, + 0x007320, 0x007324, 0x000000, 0xFFFFFF, + 0x007326, 0x007328, 0x000000, 0xFFFFFF, + 0x00732C, 0x00732D, 0x000000, 0xFFFFFF, + 0x007330, 0x007333, 0x000000, 0xFFFFFF, + 0x007335, 0x007335, 0x000000, 0xFFFFFF, + 0x007338, 0x00733D, 0x000000, 0xFFFFFF, + 0x007340, 0x007343, 0x000000, 0xFFFFFF, + 0x007346, 0x00734D, 0x000000, 0xFFFFFF, + 0x007350, 0x007356, 0x000000, 0xFFFFFF, + 0x007358, 0x007362, 0x000000, 0xFFFFFF, + 0x007364, 0x007367, 0x000000, 0xFFFFFF, + 0x007369, 0x007369, 0x000000, 0xFFFFFF, + 0x00736B, 0x00736F, 0x000000, 0xFFFFFF, + 0x007371, 0x007371, 0x000000, 0xFFFFFF, + 0x007373, 0x007374, 0x000000, 0xFFFFFF, + 0x007376, 0x007377, 0x000000, 0xFFFFFF, + 0x007379, 0x007379, 0x000000, 0xFFFFFF, + 0x00737C, 0x007383, 0x000000, 0xFFFFFF, + 0x007385, 0x007386, 0x000000, 0xFFFFFF, + 0x007388, 0x007388, 0x000000, 0xFFFFFF, + 0x00738A, 0x00738A, 0x000000, 0xFFFFFF, + 0x00738C, 0x007395, 0x000000, 0xFFFFFF, + 0x007397, 0x0073A8, 0x000000, 0xFFFFFF, + 0x0073AA, 0x0073B1, 0x000000, 0xFFFFFF, + 0x0073B4, 0x0073BA, 0x000000, 0xFFFFFF, + 0x0073BC, 0x0073BF, 0x000000, 0xFFFFFF, + 0x0073C1, 0x0073C1, 0x000000, 0xFFFFFF, + 0x0073C3, 0x0073C7, 0x000000, 0xFFFFFF, + 0x0073C9, 0x0073C9, 0x000000, 0xFFFFFF, + 0x0073CB, 0x0073CC, 0x000000, 0xFFFFFF, + 0x0073CF, 0x0073DD, 0x000000, 0xFFFFFF, + 0x0073DF, 0x0073DF, 0x000000, 0xFFFFFF, + 0x0073E1, 0x0073E4, 0x000000, 0xFFFFFF, + 0x0073E6, 0x0073E9, 0x000000, 0xFFFFFF, + 0x0073EB, 0x0073EC, 0x000000, 0xFFFFFF, + 0x0073EF, 0x0073F0, 0x000000, 0xFFFFFF, + 0x0073F2, 0x0073F7, 0x000000, 0xFFFFFF, + 0x0073F9, 0x0073FD, 0x000000, 0xFFFFFF, + 0x0073FF, 0x007402, 0x000000, 0xFFFFFF, + 0x007404, 0x007404, 0x000000, 0xFFFFFF, + 0x007407, 0x007408, 0x000000, 0xFFFFFF, + 0x00740A, 0x007421, 0x000000, 0xFFFFFF, + 0x007423, 0x007424, 0x000000, 0xFFFFFF, + 0x007426, 0x007431, 0x000000, 0xFFFFFF, + 0x007437, 0x007439, 0x000000, 0xFFFFFF, + 0x00743B, 0x00743E, 0x000000, 0xFFFFFF, + 0x007440, 0x007440, 0x000000, 0xFFFFFF, + 0x007442, 0x007454, 0x000000, 0xFFFFFF, + 0x007456, 0x007458, 0x000000, 0xFFFFFF, + 0x00745D, 0x00745D, 0x000000, 0xFFFFFF, + 0x007461, 0x007462, 0x000000, 0xFFFFFF, + 0x007465, 0x007468, 0x000000, 0xFFFFFF, + 0x00746B, 0x00746E, 0x000000, 0xFFFFFF, + 0x007471, 0x007472, 0x000000, 0xFFFFFF, + 0x007474, 0x007475, 0x000000, 0xFFFFFF, + 0x007477, 0x00747D, 0x000000, 0xFFFFFF, + 0x00747F, 0x007482, 0x000000, 0xFFFFFF, + 0x007484, 0x00748A, 0x000000, 0xFFFFFF, + 0x00748C, 0x00749D, 0x000000, 0xFFFFFF, + 0x00749F, 0x0074A1, 0x000000, 0xFFFFFF, + 0x0074A3, 0x0074A6, 0x000000, 0xFFFFFF, + 0x0074A8, 0x0074AF, 0x000000, 0xFFFFFF, + 0x0074B1, 0x0074BC, 0x000000, 0xFFFFFF, + 0x0074BE, 0x0074C9, 0x000000, 0xFFFFFF, + 0x0074CB, 0x0074CE, 0x000000, 0xFFFFFF, + 0x0074D0, 0x0074D3, 0x000000, 0xFFFFFF, + 0x0074D5, 0x0074DB, 0x000000, 0xFFFFFF, + 0x0074DD, 0x0074DF, 0x000000, 0xFFFFFF, + 0x0074E1, 0x0074E1, 0x000000, 0xFFFFFF, + 0x0074E4, 0x0074E5, 0x000000, 0xFFFFFF, + 0x0074E8, 0x0074E8, 0x000000, 0xFFFFFF, + 0x0074EA, 0x0074ED, 0x000000, 0xFFFFFF, + 0x0074EF, 0x0074EF, 0x000000, 0xFFFFFF, + 0x0074F3, 0x0074F5, 0x000000, 0xFFFFFF, + 0x0074F9, 0x007502, 0x000000, 0xFFFFFF, + 0x007506, 0x00750B, 0x000000, 0xFFFFFF, + 0x00750F, 0x007510, 0x000000, 0xFFFFFF, + 0x007512, 0x007512, 0x000000, 0xFFFFFF, + 0x007514, 0x007514, 0x000000, 0xFFFFFF, + 0x007516, 0x007517, 0x000000, 0xFFFFFF, + 0x007519, 0x007519, 0x000000, 0xFFFFFF, + 0x00751B, 0x00751B, 0x000000, 0xFFFFFF, + 0x00751D, 0x00751D, 0x000000, 0xFFFFFF, + 0x007520, 0x007522, 0x000000, 0xFFFFFF, + 0x007524, 0x007524, 0x000000, 0xFFFFFF, + 0x007527, 0x007527, 0x000000, 0xFFFFFF, + 0x007529, 0x00752A, 0x000000, 0xFFFFFF, + 0x00752D, 0x00752F, 0x000000, 0xFFFFFF, + 0x007534, 0x007536, 0x000000, 0xFFFFFF, + 0x007539, 0x007539, 0x000000, 0xFFFFFF, + 0x00753D, 0x007543, 0x000000, 0xFFFFFF, + 0x007545, 0x007545, 0x000000, 0xFFFFFF, + 0x007547, 0x007548, 0x000000, 0xFFFFFF, + 0x00754E, 0x00754E, 0x000000, 0xFFFFFF, + 0x007550, 0x007550, 0x000000, 0xFFFFFF, + 0x007552, 0x007553, 0x000000, 0xFFFFFF, + 0x007555, 0x007558, 0x000000, 0xFFFFFF, + 0x00755E, 0x00755F, 0x000000, 0xFFFFFF, + 0x007561, 0x007561, 0x000000, 0xFFFFFF, + 0x007563, 0x007563, 0x000000, 0xFFFFFF, + 0x007568, 0x007568, 0x000000, 0xFFFFFF, + 0x00756C, 0x00756C, 0x000000, 0xFFFFFF, + 0x00756E, 0x00756F, 0x000000, 0xFFFFFF, + 0x007571, 0x007572, 0x000000, 0xFFFFFF, + 0x007575, 0x007575, 0x000000, 0xFFFFFF, + 0x007579, 0x00757E, 0x000000, 0xFFFFFF, + 0x007580, 0x007581, 0x000000, 0xFFFFFF, + 0x007583, 0x007585, 0x000000, 0xFFFFFF, + 0x007588, 0x007588, 0x000000, 0xFFFFFF, + 0x00758C, 0x00758D, 0x000000, 0xFFFFFF, + 0x007590, 0x007590, 0x000000, 0xFFFFFF, + 0x007592, 0x007593, 0x000000, 0xFFFFFF, + 0x007595, 0x007599, 0x000000, 0xFFFFFF, + 0x00759B, 0x00759C, 0x000000, 0xFFFFFF, + 0x00759E, 0x0075A2, 0x000000, 0xFFFFFF, + 0x0075A4, 0x0075A4, 0x000000, 0xFFFFFF, + 0x0075A6, 0x0075AA, 0x000000, 0xFFFFFF, + 0x0075AC, 0x0075B0, 0x000000, 0xFFFFFF, + 0x0075B4, 0x0075B4, 0x000000, 0xFFFFFF, + 0x0075B6, 0x0075B7, 0x000000, 0xFFFFFF, + 0x0075BA, 0x0075BB, 0x000000, 0xFFFFFF, + 0x0075BF, 0x0075C1, 0x000000, 0xFFFFFF, + 0x0075C4, 0x0075C4, 0x000000, 0xFFFFFF, + 0x0075C6, 0x0075C6, 0x000000, 0xFFFFFF, + 0x0075C8, 0x0075C9, 0x000000, 0xFFFFFF, + 0x0075CB, 0x0075CC, 0x000000, 0xFFFFFF, + 0x0075CE, 0x0075D1, 0x000000, 0xFFFFFF, + 0x0075D3, 0x0075D3, 0x000000, 0xFFFFFF, + 0x0075D6, 0x0075D7, 0x000000, 0xFFFFFF, + 0x0075DA, 0x0075DA, 0x000000, 0xFFFFFF, + 0x0075DC, 0x0075DD, 0x000000, 0xFFFFFF, + 0x0075DF, 0x0075E1, 0x000000, 0xFFFFFF, + 0x0075E4, 0x0075E8, 0x000000, 0xFFFFFF, + 0x0075EA, 0x0075EF, 0x000000, 0xFFFFFF, + 0x0075F1, 0x0075F1, 0x000000, 0xFFFFFF, + 0x0075F5, 0x0075F9, 0x000000, 0xFFFFFF, + 0x0075FB, 0x0075FB, 0x000000, 0xFFFFFF, + 0x0075FD, 0x0075FD, 0x000000, 0xFFFFFF, + 0x007600, 0x007600, 0x000000, 0xFFFFFF, + 0x007602, 0x007608, 0x000000, 0xFFFFFF, + 0x00760A, 0x00760A, 0x000000, 0xFFFFFF, + 0x00760C, 0x00760C, 0x000000, 0xFFFFFF, + 0x00760E, 0x00761E, 0x000000, 0xFFFFFF, + 0x007623, 0x007623, 0x000000, 0xFFFFFF, + 0x007625, 0x007626, 0x000000, 0xFFFFFF, + 0x007628, 0x00762F, 0x000000, 0xFFFFFF, + 0x007631, 0x007633, 0x000000, 0xFFFFFF, + 0x007635, 0x00763A, 0x000000, 0xFFFFFF, + 0x00763C, 0x007641, 0x000000, 0xFFFFFF, + 0x007643, 0x007645, 0x000000, 0xFFFFFF, + 0x007649, 0x00764B, 0x000000, 0xFFFFFF, + 0x00764D, 0x007651, 0x000000, 0xFFFFFF, + 0x007653, 0x007655, 0x000000, 0xFFFFFF, + 0x007657, 0x007657, 0x000000, 0xFFFFFF, + 0x007659, 0x00765B, 0x000000, 0xFFFFFF, + 0x00765D, 0x007660, 0x000000, 0xFFFFFF, + 0x007663, 0x007666, 0x000000, 0xFFFFFF, + 0x00766B, 0x00766B, 0x000000, 0xFFFFFF, + 0x00766D, 0x00766F, 0x000000, 0xFFFFFF, + 0x007671, 0x007671, 0x000000, 0xFFFFFF, + 0x007673, 0x007675, 0x000000, 0xFFFFFF, + 0x007677, 0x007677, 0x000000, 0xFFFFFF, + 0x007679, 0x007679, 0x000000, 0xFFFFFF, + 0x00767F, 0x00767F, 0x000000, 0xFFFFFF, + 0x007681, 0x007682, 0x000000, 0xFFFFFF, + 0x007685, 0x007685, 0x000000, 0xFFFFFF, + 0x007689, 0x00768A, 0x000000, 0xFFFFFF, + 0x00768C, 0x00768D, 0x000000, 0xFFFFFF, + 0x00768F, 0x00768F, 0x000000, 0xFFFFFF, + 0x007691, 0x007692, 0x000000, 0xFFFFFF, + 0x007694, 0x007695, 0x000000, 0xFFFFFF, + 0x007697, 0x007698, 0x000000, 0xFFFFFF, + 0x00769B, 0x0076AD, 0x000000, 0xFFFFFF, + 0x0076AF, 0x0076AF, 0x000000, 0xFFFFFF, + 0x0076B1, 0x0076B3, 0x000000, 0xFFFFFF, + 0x0076B5, 0x0076B6, 0x000000, 0xFFFFFF, + 0x0076BB, 0x0076BE, 0x000000, 0xFFFFFF, + 0x0076C0, 0x0076C1, 0x000000, 0xFFFFFF, + 0x0076C4, 0x0076C5, 0x000000, 0xFFFFFF, + 0x0076C7, 0x0076C7, 0x000000, 0xFFFFFF, + 0x0076C9, 0x0076C9, 0x000000, 0xFFFFFF, + 0x0076CB, 0x0076CC, 0x000000, 0xFFFFFF, + 0x0076CE, 0x0076D1, 0x000000, 0xFFFFFF, + 0x0076D3, 0x0076D5, 0x000000, 0xFFFFFF, + 0x0076D8, 0x0076DA, 0x000000, 0xFFFFFF, + 0x0076DD, 0x0076DD, 0x000000, 0xFFFFFF, + 0x0076E0, 0x0076E0, 0x000000, 0xFFFFFF, + 0x0076E2, 0x0076E2, 0x000000, 0xFFFFFF, + 0x0076E6, 0x0076E6, 0x000000, 0xFFFFFF, + 0x0076E8, 0x0076E9, 0x000000, 0xFFFFFF, + 0x0076EB, 0x0076ED, 0x000000, 0xFFFFFF, + 0x0076EF, 0x0076F1, 0x000000, 0xFFFFFF, + 0x0076F3, 0x0076F3, 0x000000, 0xFFFFFF, + 0x0076F5, 0x0076F7, 0x000000, 0xFFFFFF, + 0x0076F9, 0x0076FA, 0x000000, 0xFFFFFF, + 0x0076FC, 0x0076FD, 0x000000, 0xFFFFFF, + 0x0076FF, 0x007700, 0x000000, 0xFFFFFF, + 0x007702, 0x007703, 0x000000, 0xFFFFFF, + 0x007705, 0x007706, 0x000000, 0xFFFFFF, + 0x00770A, 0x00770A, 0x000000, 0xFFFFFF, + 0x00770D, 0x00771A, 0x000000, 0xFFFFFF, + 0x00771C, 0x00771D, 0x000000, 0xFFFFFF, + 0x007721, 0x007723, 0x000000, 0xFFFFFF, + 0x007727, 0x007728, 0x000000, 0xFFFFFF, + 0x00772A, 0x007736, 0x000000, 0xFFFFFF, + 0x007739, 0x007739, 0x000000, 0xFFFFFF, + 0x00773B, 0x00773B, 0x000000, 0xFFFFFF, + 0x00773D, 0x00773F, 0x000000, 0xFFFFFF, + 0x007741, 0x007746, 0x000000, 0xFFFFFF, + 0x007748, 0x007759, 0x000000, 0xFFFFFF, + 0x00775C, 0x007760, 0x000000, 0xFFFFFF, + 0x007762, 0x007762, 0x000000, 0xFFFFFF, + 0x007764, 0x007764, 0x000000, 0xFFFFFF, + 0x007767, 0x007767, 0x000000, 0xFFFFFF, + 0x007769, 0x00776A, 0x000000, 0xFFFFFF, + 0x00776C, 0x007778, 0x000000, 0xFFFFFF, + 0x00777A, 0x00777D, 0x000000, 0xFFFFFF, + 0x007780, 0x00778A, 0x000000, 0xFFFFFF, + 0x00778C, 0x00778D, 0x000000, 0xFFFFFF, + 0x00778F, 0x007790, 0x000000, 0xFFFFFF, + 0x007792, 0x00779D, 0x000000, 0xFFFFFF, + 0x00779F, 0x00779F, 0x000000, 0xFFFFFF, + 0x0077A1, 0x0077A4, 0x000000, 0xFFFFFF, + 0x0077A6, 0x0077AB, 0x000000, 0xFFFFFF, + 0x0077AE, 0x0077AF, 0x000000, 0xFFFFFF, + 0x0077B1, 0x0077B2, 0x000000, 0xFFFFFF, + 0x0077B4, 0x0077B5, 0x000000, 0xFFFFFF, + 0x0077B7, 0x0077B8, 0x000000, 0xFFFFFF, + 0x0077BA, 0x0077BA, 0x000000, 0xFFFFFF, + 0x0077BE, 0x0077BE, 0x000000, 0xFFFFFF, + 0x0077C0, 0x0077C6, 0x000000, 0xFFFFFF, + 0x0077C8, 0x0077CC, 0x000000, 0xFFFFFF, + 0x0077CE, 0x0077D6, 0x000000, 0xFFFFFF, + 0x0077D8, 0x0077D9, 0x000000, 0xFFFFFF, + 0x0077DD, 0x0077E1, 0x000000, 0xFFFFFF, + 0x0077E4, 0x0077E4, 0x000000, 0xFFFFFF, + 0x0077E6, 0x0077E6, 0x000000, 0xFFFFFF, + 0x0077E8, 0x0077E8, 0x000000, 0xFFFFFF, + 0x0077EA, 0x0077EC, 0x000000, 0xFFFFFF, + 0x0077F0, 0x0077F2, 0x000000, 0xFFFFFF, + 0x0077F4, 0x0077FB, 0x000000, 0xFFFFFF, + 0x0077FD, 0x007801, 0x000000, 0xFFFFFF, + 0x007803, 0x00780B, 0x000000, 0xFFFFFF, + 0x00780D, 0x007811, 0x000000, 0xFFFFFF, + 0x007813, 0x007813, 0x000000, 0xFFFFFF, + 0x007816, 0x00781F, 0x000000, 0xFFFFFF, + 0x007821, 0x007824, 0x000000, 0xFFFFFF, + 0x007828, 0x007831, 0x000000, 0xFFFFFF, + 0x007833, 0x007833, 0x000000, 0xFFFFFF, + 0x007835, 0x007839, 0x000000, 0xFFFFFF, + 0x00783B, 0x00783E, 0x000000, 0xFFFFFF, + 0x007840, 0x007844, 0x000000, 0xFFFFFF, + 0x007846, 0x00785C, 0x000000, 0xFFFFFF, + 0x00785E, 0x00786A, 0x000000, 0xFFFFFF, + 0x00786D, 0x00786E, 0x000000, 0xFFFFFF, + 0x007870, 0x007871, 0x000000, 0xFFFFFF, + 0x007873, 0x007873, 0x000000, 0xFFFFFF, + 0x007875, 0x00787B, 0x000000, 0xFFFFFF, + 0x00787D, 0x007880, 0x000000, 0xFFFFFF, + 0x007882, 0x007885, 0x000000, 0xFFFFFF, + 0x007888, 0x00788B, 0x000000, 0xFFFFFF, + 0x00788F, 0x007890, 0x000000, 0xFFFFFF, + 0x007892, 0x007892, 0x000000, 0xFFFFFF, + 0x007894, 0x007894, 0x000000, 0xFFFFFF, + 0x007896, 0x007896, 0x000000, 0xFFFFFF, + 0x007898, 0x007899, 0x000000, 0xFFFFFF, + 0x00789B, 0x0078A2, 0x000000, 0xFFFFFF, + 0x0078A4, 0x0078A6, 0x000000, 0xFFFFFF, + 0x0078A8, 0x0078A8, 0x000000, 0xFFFFFF, + 0x0078AB, 0x0078AE, 0x000000, 0xFFFFFF, + 0x0078B0, 0x0078B4, 0x000000, 0xFFFFFF, + 0x0078B6, 0x0078B9, 0x000000, 0xFFFFFF, + 0x0078BB, 0x0078BB, 0x000000, 0xFFFFFF, + 0x0078BD, 0x0078BD, 0x000000, 0xFFFFFF, + 0x0078BF, 0x0078C0, 0x000000, 0xFFFFFF, + 0x0078C2, 0x0078C4, 0x000000, 0xFFFFFF, + 0x0078C7, 0x0078C9, 0x000000, 0xFFFFFF, + 0x0078CC, 0x0078CF, 0x000000, 0xFFFFFF, + 0x0078D2, 0x0078D3, 0x000000, 0xFFFFFF, + 0x0078D5, 0x0078D9, 0x000000, 0xFFFFFF, + 0x0078DB, 0x0078E6, 0x000000, 0xFFFFFF, + 0x0078E9, 0x0078EB, 0x000000, 0xFFFFFF, + 0x0078ED, 0x0078EE, 0x000000, 0xFFFFFF, + 0x0078F0, 0x0078F3, 0x000000, 0xFFFFFF, + 0x0078F5, 0x0078FC, 0x000000, 0xFFFFFF, + 0x0078FE, 0x007900, 0x000000, 0xFFFFFF, + 0x007902, 0x007906, 0x000000, 0xFFFFFF, + 0x007908, 0x00790D, 0x000000, 0xFFFFFF, + 0x00790F, 0x007910, 0x000000, 0xFFFFFF, + 0x007913, 0x007918, 0x000000, 0xFFFFFF, + 0x00791A, 0x007925, 0x000000, 0xFFFFFF, + 0x007927, 0x007929, 0x000000, 0xFFFFFF, + 0x00792D, 0x007939, 0x000000, 0xFFFFFF, + 0x00793B, 0x00793B, 0x000000, 0xFFFFFF, + 0x00793D, 0x00793D, 0x000000, 0xFFFFFF, + 0x00793F, 0x00793F, 0x000000, 0xFFFFFF, + 0x007942, 0x007946, 0x000000, 0xFFFFFF, + 0x00794A, 0x00794F, 0x000000, 0xFFFFFF, + 0x007951, 0x007952, 0x000000, 0xFFFFFF, + 0x007954, 0x007954, 0x000000, 0xFFFFFF, + 0x007958, 0x007959, 0x000000, 0xFFFFFF, + 0x00795B, 0x00795C, 0x000000, 0xFFFFFF, + 0x007961, 0x007961, 0x000000, 0xFFFFFF, + 0x007963, 0x007964, 0x000000, 0xFFFFFF, + 0x007966, 0x007967, 0x000000, 0xFFFFFF, + 0x007969, 0x00796C, 0x000000, 0xFFFFFF, + 0x00796E, 0x007976, 0x000000, 0xFFFFFF, + 0x007978, 0x007979, 0x000000, 0xFFFFFF, + 0x00797B, 0x00797E, 0x000000, 0xFFFFFF, + 0x007982, 0x007983, 0x000000, 0xFFFFFF, + 0x007986, 0x007989, 0x000000, 0xFFFFFF, + 0x00798B, 0x00798C, 0x000000, 0xFFFFFF, + 0x007990, 0x00799C, 0x000000, 0xFFFFFF, + 0x00799E, 0x0079A5, 0x000000, 0xFFFFFF, + 0x0079A8, 0x0079A9, 0x000000, 0xFFFFFF, + 0x0079AB, 0x0079AD, 0x000000, 0xFFFFFF, + 0x0079AF, 0x0079AF, 0x000000, 0xFFFFFF, + 0x0079B1, 0x0079B2, 0x000000, 0xFFFFFF, + 0x0079B4, 0x0079B8, 0x000000, 0xFFFFFF, + 0x0079BB, 0x0079BC, 0x000000, 0xFFFFFF, + 0x0079C2, 0x0079C8, 0x000000, 0xFFFFFF, + 0x0079CA, 0x0079CA, 0x000000, 0xFFFFFF, + 0x0079CC, 0x0079D0, 0x000000, 0xFFFFFF, + 0x0079D3, 0x0079D4, 0x000000, 0xFFFFFF, + 0x0079D6, 0x0079D7, 0x000000, 0xFFFFFF, + 0x0079D9, 0x0079DE, 0x000000, 0xFFFFFF, + 0x0079E0, 0x0079E0, 0x000000, 0xFFFFFF, + 0x0079E2, 0x0079E2, 0x000000, 0xFFFFFF, + 0x0079E5, 0x0079E5, 0x000000, 0xFFFFFF, + 0x0079E8, 0x0079E8, 0x000000, 0xFFFFFF, + 0x0079EA, 0x0079EB, 0x000000, 0xFFFFFF, + 0x0079ED, 0x0079EF, 0x000000, 0xFFFFFF, + 0x0079F1, 0x0079FA, 0x000000, 0xFFFFFF, + 0x0079FC, 0x0079FF, 0x000000, 0xFFFFFF, + 0x007A01, 0x007A07, 0x000000, 0xFFFFFF, + 0x007A09, 0x007A0A, 0x000000, 0xFFFFFF, + 0x007A0C, 0x007A0C, 0x000000, 0xFFFFFF, + 0x007A0F, 0x007A13, 0x000000, 0xFFFFFF, + 0x007A15, 0x007A16, 0x000000, 0xFFFFFF, + 0x007A1B, 0x007A1B, 0x000000, 0xFFFFFF, + 0x007A1D, 0x007A1E, 0x000000, 0xFFFFFF, + 0x007A21, 0x007A2D, 0x000000, 0xFFFFFF, + 0x007A2F, 0x007A30, 0x000000, 0xFFFFFF, + 0x007A33, 0x007A36, 0x000000, 0xFFFFFF, + 0x007A38, 0x007A3A, 0x000000, 0xFFFFFF, + 0x007A41, 0x007A41, 0x000000, 0xFFFFFF, + 0x007A44, 0x007A45, 0x000000, 0xFFFFFF, + 0x007A47, 0x007A48, 0x000000, 0xFFFFFF, + 0x007A4A, 0x007A4C, 0x000000, 0xFFFFFF, + 0x007A51, 0x007A56, 0x000000, 0xFFFFFF, + 0x007A58, 0x007A60, 0x000000, 0xFFFFFF, + 0x007A64, 0x007A68, 0x000000, 0xFFFFFF, + 0x007A6A, 0x007A6A, 0x000000, 0xFFFFFF, + 0x007A6C, 0x007A6F, 0x000000, 0xFFFFFF, + 0x007A71, 0x007A73, 0x000000, 0xFFFFFF, + 0x007A75, 0x007A75, 0x000000, 0xFFFFFF, + 0x007A77, 0x007A78, 0x000000, 0xFFFFFF, + 0x007A7B, 0x007A7C, 0x000000, 0xFFFFFF, + 0x007A7E, 0x007A7E, 0x000000, 0xFFFFFF, + 0x007A80, 0x007A80, 0x000000, 0xFFFFFF, + 0x007A82, 0x007A82, 0x000000, 0xFFFFFF, + 0x007A85, 0x007A87, 0x000000, 0xFFFFFF, + 0x007A89, 0x007A91, 0x000000, 0xFFFFFF, + 0x007A94, 0x007A94, 0x000000, 0xFFFFFF, + 0x007A99, 0x007A9E, 0x000000, 0xFFFFFF, + 0x007AA0, 0x007AA8, 0x000000, 0xFFFFFF, + 0x007AAB, 0x007AAD, 0x000000, 0xFFFFFF, + 0x007AB1, 0x007AB5, 0x000000, 0xFFFFFF, + 0x007AB7, 0x007AB9, 0x000000, 0xFFFFFF, + 0x007ABB, 0x007ABE, 0x000000, 0xFFFFFF, + 0x007AC0, 0x007AC2, 0x000000, 0xFFFFFF, + 0x007AC6, 0x007AC6, 0x000000, 0xFFFFFF, + 0x007AC9, 0x007AC9, 0x000000, 0xFFFFFF, + 0x007ACC, 0x007ACC, 0x000000, 0xFFFFFF, + 0x007ACE, 0x007ACE, 0x000000, 0xFFFFFF, + 0x007AD0, 0x007AD1, 0x000000, 0xFFFFFF, + 0x007AD4, 0x007AD4, 0x000000, 0xFFFFFF, + 0x007AD6, 0x007AD8, 0x000000, 0xFFFFFF, + 0x007ADB, 0x007ADB, 0x000000, 0xFFFFFF, + 0x007ADE, 0x007ADE, 0x000000, 0xFFFFFF, + 0x007AE4, 0x007AE4, 0x000000, 0xFFFFFF, + 0x007AE7, 0x007AE9, 0x000000, 0xFFFFFF, + 0x007AEB, 0x007AEC, 0x000000, 0xFFFFFF, + 0x007AEE, 0x007AEE, 0x000000, 0xFFFFFF, + 0x007AF1, 0x007AF5, 0x000000, 0xFFFFFF, + 0x007AF7, 0x007AF7, 0x000000, 0xFFFFFF, + 0x007AFB, 0x007AFE, 0x000000, 0xFFFFFF, + 0x007B00, 0x007B01, 0x000000, 0xFFFFFF, + 0x007B03, 0x007B03, 0x000000, 0xFFFFFF, + 0x007B05, 0x007B05, 0x000000, 0xFFFFFF, + 0x007B07, 0x007B07, 0x000000, 0xFFFFFF, + 0x007B09, 0x007B09, 0x000000, 0xFFFFFF, + 0x007B0C, 0x007B0E, 0x000000, 0xFFFFFF, + 0x007B10, 0x007B10, 0x000000, 0xFFFFFF, + 0x007B12, 0x007B17, 0x000000, 0xFFFFFF, + 0x007B1A, 0x007B1A, 0x000000, 0xFFFFFF, + 0x007B1C, 0x007B1D, 0x000000, 0xFFFFFF, + 0x007B1F, 0x007B1F, 0x000000, 0xFFFFFF, + 0x007B21, 0x007B24, 0x000000, 0xFFFFFF, + 0x007B27, 0x007B27, 0x000000, 0xFFFFFF, + 0x007B29, 0x007B2B, 0x000000, 0xFFFFFF, + 0x007B2D, 0x007B32, 0x000000, 0xFFFFFF, + 0x007B34, 0x007B34, 0x000000, 0xFFFFFF, + 0x007B37, 0x007B38, 0x000000, 0xFFFFFF, + 0x007B3A, 0x007B44, 0x000000, 0xFFFFFF, + 0x007B47, 0x007B47, 0x000000, 0xFFFFFF, + 0x007B4A, 0x007B4A, 0x000000, 0xFFFFFF, + 0x007B4E, 0x007B4E, 0x000000, 0xFFFFFF, + 0x007B53, 0x007B53, 0x000000, 0xFFFFFF, + 0x007B55, 0x007B55, 0x000000, 0xFFFFFF, + 0x007B57, 0x007B5C, 0x000000, 0xFFFFFF, + 0x007B5E, 0x007B64, 0x000000, 0xFFFFFF, + 0x007B66, 0x007B66, 0x000000, 0xFFFFFF, + 0x007B68, 0x007B6B, 0x000000, 0xFFFFFF, + 0x007B6D, 0x007B6D, 0x000000, 0xFFFFFF, + 0x007B6F, 0x007B6F, 0x000000, 0xFFFFFF, + 0x007B72, 0x007B73, 0x000000, 0xFFFFFF, + 0x007B76, 0x007B79, 0x000000, 0xFFFFFF, + 0x007B7B, 0x007B85, 0x000000, 0xFFFFFF, + 0x007B88, 0x007B8A, 0x000000, 0xFFFFFF, + 0x007B8C, 0x007B8C, 0x000000, 0xFFFFFF, + 0x007B8E, 0x007B8E, 0x000000, 0xFFFFFF, + 0x007B90, 0x007B91, 0x000000, 0xFFFFFF, + 0x007B93, 0x007B93, 0x000000, 0xFFFFFF, + 0x007B96, 0x007B96, 0x000000, 0xFFFFFF, + 0x007B9B, 0x007B9B, 0x000000, 0xFFFFFF, + 0x007B9E, 0x007B9E, 0x000000, 0xFFFFFF, + 0x007BA0, 0x007BA0, 0x000000, 0xFFFFFF, + 0x007BA2, 0x007BA9, 0x000000, 0xFFFFFF, + 0x007BAB, 0x007BAC, 0x000000, 0xFFFFFF, + 0x007BAE, 0x007BB0, 0x000000, 0xFFFFFF, + 0x007BB2, 0x007BB3, 0x000000, 0xFFFFFF, + 0x007BB5, 0x007BB7, 0x000000, 0xFFFFFF, + 0x007BB9, 0x007BBF, 0x000000, 0xFFFFFF, + 0x007BC2, 0x007BC3, 0x000000, 0xFFFFFF, + 0x007BC5, 0x007BC5, 0x000000, 0xFFFFFF, + 0x007BC8, 0x007BC8, 0x000000, 0xFFFFFF, + 0x007BCA, 0x007BCA, 0x000000, 0xFFFFFF, + 0x007BCD, 0x007BCE, 0x000000, 0xFFFFFF, + 0x007BD0, 0x007BDC, 0x000000, 0xFFFFFF, + 0x007BDE, 0x007BDF, 0x000000, 0xFFFFFF, + 0x007BE1, 0x007BE3, 0x000000, 0xFFFFFF, + 0x007BE7, 0x007BE8, 0x000000, 0xFFFFFF, + 0x007BEA, 0x007BEC, 0x000000, 0xFFFFFF, + 0x007BEE, 0x007BF2, 0x000000, 0xFFFFFF, + 0x007BF4, 0x007BF5, 0x000000, 0xFFFFFF, + 0x007BF8, 0x007BFF, 0x000000, 0xFFFFFF, + 0x007C01, 0x007C06, 0x000000, 0xFFFFFF, + 0x007C08, 0x007C0C, 0x000000, 0xFFFFFF, + 0x007C0E, 0x007C10, 0x000000, 0xFFFFFF, + 0x007C15, 0x007C16, 0x000000, 0xFFFFFF, + 0x007C18, 0x007C1E, 0x000000, 0xFFFFFF, + 0x007C20, 0x007C20, 0x000000, 0xFFFFFF, + 0x007C22, 0x007C22, 0x000000, 0xFFFFFF, + 0x007C24, 0x007C26, 0x000000, 0xFFFFFF, + 0x007C28, 0x007C29, 0x000000, 0xFFFFFF, + 0x007C2C, 0x007C36, 0x000000, 0xFFFFFF, + 0x007C39, 0x007C3C, 0x000000, 0xFFFFFF, + 0x007C41, 0x007C42, 0x000000, 0xFFFFFF, + 0x007C44, 0x007C4B, 0x000000, 0xFFFFFF, + 0x007C4E, 0x007C4E, 0x000000, 0xFFFFFF, + 0x007C51, 0x007C53, 0x000000, 0xFFFFFF, + 0x007C55, 0x007C55, 0x000000, 0xFFFFFF, + 0x007C57, 0x007C57, 0x000000, 0xFFFFFF, + 0x007C59, 0x007C5E, 0x000000, 0xFFFFFF, + 0x007C61, 0x007C63, 0x000000, 0xFFFFFF, + 0x007C66, 0x007C6B, 0x000000, 0xFFFFFF, + 0x007C6D, 0x007C72, 0x000000, 0xFFFFFF, + 0x007C74, 0x007C74, 0x000000, 0xFFFFFF, + 0x007C76, 0x007C7D, 0x000000, 0xFFFFFF, + 0x007C7F, 0x007C80, 0x000000, 0xFFFFFF, + 0x007C84, 0x007C88, 0x000000, 0xFFFFFF, + 0x007C8A, 0x007C8A, 0x000000, 0xFFFFFF, + 0x007C8C, 0x007C8C, 0x000000, 0xFFFFFF, + 0x007C8E, 0x007C8F, 0x000000, 0xFFFFFF, + 0x007C91, 0x007C91, 0x000000, 0xFFFFFF, + 0x007C93, 0x007C94, 0x000000, 0xFFFFFF, + 0x007C96, 0x007C96, 0x000000, 0xFFFFFF, + 0x007C99, 0x007C9A, 0x000000, 0xFFFFFF, + 0x007C9C, 0x007C9E, 0x000000, 0xFFFFFF, + 0x007CA0, 0x007CA0, 0x000000, 0xFFFFFF, + 0x007CA3, 0x007CA3, 0x000000, 0xFFFFFF, + 0x007CA6, 0x007CA6, 0x000000, 0xFFFFFF, + 0x007CA9, 0x007CAA, 0x000000, 0xFFFFFF, + 0x007CAC, 0x007CAC, 0x000000, 0xFFFFFF, + 0x007CAF, 0x007CB0, 0x000000, 0xFFFFFF, + 0x007CB4, 0x007CB8, 0x000000, 0xFFFFFF, + 0x007CBA, 0x007CBC, 0x000000, 0xFFFFFF, + 0x007CBF, 0x007CBF, 0x000000, 0xFFFFFF, + 0x007CC1, 0x007CC1, 0x000000, 0xFFFFFF, + 0x007CC3, 0x007CC4, 0x000000, 0xFFFFFF, + 0x007CC6, 0x007CC9, 0x000000, 0xFFFFFF, + 0x007CCB, 0x007CCD, 0x000000, 0xFFFFFF, + 0x007CCF, 0x007CD1, 0x000000, 0xFFFFFF, + 0x007CD3, 0x007CD5, 0x000000, 0xFFFFFF, + 0x007CD7, 0x007CD7, 0x000000, 0xFFFFFF, + 0x007CD9, 0x007CDB, 0x000000, 0xFFFFFF, + 0x007CDD, 0x007CDD, 0x000000, 0xFFFFFF, + 0x007CE1, 0x007CE1, 0x000000, 0xFFFFFF, + 0x007CE3, 0x007CE6, 0x000000, 0xFFFFFF, + 0x007CE8, 0x007CEE, 0x000000, 0xFFFFFF, + 0x007CF0, 0x007CF1, 0x000000, 0xFFFFFF, + 0x007CF3, 0x007CF3, 0x000000, 0xFFFFFF, + 0x007CF5, 0x007CF5, 0x000000, 0xFFFFFF, + 0x007CF7, 0x007CF7, 0x000000, 0xFFFFFF, + 0x007CF9, 0x007CF9, 0x000000, 0xFFFFFF, + 0x007CFC, 0x007CFD, 0x000000, 0xFFFFFF, + 0x007CFF, 0x007CFF, 0x000000, 0xFFFFFF, + 0x007D01, 0x007D01, 0x000000, 0xFFFFFF, + 0x007D03, 0x007D03, 0x000000, 0xFFFFFF, + 0x007D07, 0x007D09, 0x000000, 0xFFFFFF, + 0x007D0C, 0x007D0C, 0x000000, 0xFFFFFF, + 0x007D0E, 0x007D0F, 0x000000, 0xFFFFFF, + 0x007D11, 0x007D13, 0x000000, 0xFFFFFF, + 0x007D16, 0x007D16, 0x000000, 0xFFFFFF, + 0x007D1D, 0x007D1F, 0x000000, 0xFFFFFF, + 0x007D23, 0x007D2A, 0x000000, 0xFFFFFF, + 0x007D2D, 0x007D2D, 0x000000, 0xFFFFFF, + 0x007D31, 0x007D31, 0x000000, 0xFFFFFF, + 0x007D34, 0x007D34, 0x000000, 0xFFFFFF, + 0x007D36, 0x007D38, 0x000000, 0xFFFFFF, + 0x007D3B, 0x007D3E, 0x000000, 0xFFFFFF, + 0x007D40, 0x007D41, 0x000000, 0xFFFFFF, + 0x007D47, 0x007D4A, 0x000000, 0xFFFFFF, + 0x007D4D, 0x007D4D, 0x000000, 0xFFFFFF, + 0x007D51, 0x007D55, 0x000000, 0xFFFFFF, + 0x007D57, 0x007D5A, 0x000000, 0xFFFFFF, + 0x007D5C, 0x007D5D, 0x000000, 0xFFFFFF, + 0x007D5F, 0x007D60, 0x000000, 0xFFFFFF, + 0x007D64, 0x007D65, 0x000000, 0xFFFFFF, + 0x007D67, 0x007D67, 0x000000, 0xFFFFFF, + 0x007D69, 0x007D6D, 0x000000, 0xFFFFFF, + 0x007D6F, 0x007D70, 0x000000, 0xFFFFFF, + 0x007D74, 0x007D74, 0x000000, 0xFFFFFF, + 0x007D77, 0x007D78, 0x000000, 0xFFFFFF, + 0x007D7A, 0x007D7C, 0x000000, 0xFFFFFF, + 0x007D7E, 0x007D88, 0x000000, 0xFFFFFF, + 0x007D8A, 0x007D8E, 0x000000, 0xFFFFFF, + 0x007D90, 0x007D92, 0x000000, 0xFFFFFF, + 0x007D94, 0x007D98, 0x000000, 0xFFFFFF, + 0x007D9D, 0x007D9E, 0x000000, 0xFFFFFF, + 0x007DA0, 0x007DA1, 0x000000, 0xFFFFFF, + 0x007DA4, 0x007DAA, 0x000000, 0xFFFFFF, + 0x007DB3, 0x007DB3, 0x000000, 0xFFFFFF, + 0x007DB6, 0x007DB7, 0x000000, 0xFFFFFF, + 0x007DB9, 0x007DB9, 0x000000, 0xFFFFFF, + 0x007DBC, 0x007DBC, 0x000000, 0xFFFFFF, + 0x007DC0, 0x007DC6, 0x000000, 0xFFFFFF, + 0x007DC8, 0x007DC9, 0x000000, 0xFFFFFF, + 0x007DCC, 0x007DCE, 0x000000, 0xFFFFFF, + 0x007DD0, 0x007DD0, 0x000000, 0xFFFFFF, + 0x007DD3, 0x007DD4, 0x000000, 0xFFFFFF, + 0x007DD6, 0x007DD7, 0x000000, 0xFFFFFF, + 0x007DD9, 0x007DD9, 0x000000, 0xFFFFFF, + 0x007DDB, 0x007DDB, 0x000000, 0xFFFFFF, + 0x007DDF, 0x007DDF, 0x000000, 0xFFFFFF, + 0x007DE2, 0x007DE3, 0x000000, 0xFFFFFF, + 0x007DE5, 0x007DE7, 0x000000, 0xFFFFFF, + 0x007DEA, 0x007DEB, 0x000000, 0xFFFFFF, + 0x007DED, 0x007DEE, 0x000000, 0xFFFFFF, + 0x007DF0, 0x007DF1, 0x000000, 0xFFFFFF, + 0x007DF3, 0x007DF3, 0x000000, 0xFFFFFF, + 0x007DF5, 0x007DFA, 0x000000, 0xFFFFFF, + 0x007DFC, 0x007E00, 0x000000, 0xFFFFFF, + 0x007E02, 0x007E03, 0x000000, 0xFFFFFF, + 0x007E06, 0x007E08, 0x000000, 0xFFFFFF, + 0x007E0C, 0x007E11, 0x000000, 0xFFFFFF, + 0x007E13, 0x007E1A, 0x000000, 0xFFFFFF, + 0x007E1C, 0x007E1D, 0x000000, 0xFFFFFF, + 0x007E20, 0x007E20, 0x000000, 0xFFFFFF, + 0x007E24, 0x007E25, 0x000000, 0xFFFFFF, + 0x007E27, 0x007E2A, 0x000000, 0xFFFFFF, + 0x007E2C, 0x007E2D, 0x000000, 0xFFFFFF, + 0x007E2F, 0x007E30, 0x000000, 0xFFFFFF, + 0x007E33, 0x007E34, 0x000000, 0xFFFFFF, + 0x007E36, 0x007E36, 0x000000, 0xFFFFFF, + 0x007E38, 0x007E38, 0x000000, 0xFFFFFF, + 0x007E3C, 0x007E3C, 0x000000, 0xFFFFFF, + 0x007E3F, 0x007E40, 0x000000, 0xFFFFFF, + 0x007E42, 0x007E42, 0x000000, 0xFFFFFF, + 0x007E44, 0x007E45, 0x000000, 0xFFFFFF, + 0x007E47, 0x007E49, 0x000000, 0xFFFFFF, + 0x007E4C, 0x007E4C, 0x000000, 0xFFFFFF, + 0x007E4E, 0x007E53, 0x000000, 0xFFFFFF, + 0x007E57, 0x007E58, 0x000000, 0xFFFFFF, + 0x007E5B, 0x007E5C, 0x000000, 0xFFFFFF, + 0x007E5F, 0x007E65, 0x000000, 0xFFFFFF, + 0x007E68, 0x007E68, 0x000000, 0xFFFFFF, + 0x007E6B, 0x007E6C, 0x000000, 0xFFFFFF, + 0x007E6E, 0x007E6F, 0x000000, 0xFFFFFF, + 0x007E71, 0x007E78, 0x000000, 0xFFFFFF, + 0x007E7A, 0x007E7A, 0x000000, 0xFFFFFF, + 0x007E7E, 0x007E7E, 0x000000, 0xFFFFFF, + 0x007E80, 0x007E81, 0x000000, 0xFFFFFF, + 0x007E84, 0x007E87, 0x000000, 0xFFFFFF, + 0x007E8A, 0x007E8B, 0x000000, 0xFFFFFF, + 0x007E8D, 0x007E8D, 0x000000, 0xFFFFFF, + 0x007E91, 0x007E91, 0x000000, 0xFFFFFF, + 0x007E95, 0x007E95, 0x000000, 0xFFFFFF, + 0x007E97, 0x007E9A, 0x000000, 0xFFFFFF, + 0x007E9D, 0x007F35, 0x000000, 0xFFFFFF, + 0x007F37, 0x007F37, 0x000000, 0xFFFFFF, + 0x007F39, 0x007F39, 0x000000, 0xFFFFFF, + 0x007F3B, 0x007F44, 0x000000, 0xFFFFFF, + 0x007F46, 0x007F4B, 0x000000, 0xFFFFFF, + 0x007F4F, 0x007F4F, 0x000000, 0xFFFFFF, + 0x007F52, 0x007F53, 0x000000, 0xFFFFFF, + 0x007F56, 0x007F57, 0x000000, 0xFFFFFF, + 0x007F59, 0x007F5E, 0x000000, 0xFFFFFF, + 0x007F61, 0x007F66, 0x000000, 0xFFFFFF, + 0x007F6C, 0x007F6D, 0x000000, 0xFFFFFF, + 0x007F6F, 0x007F6F, 0x000000, 0xFFFFFF, + 0x007F71, 0x007F71, 0x000000, 0xFFFFFF, + 0x007F73, 0x007F74, 0x000000, 0xFFFFFF, + 0x007F76, 0x007F76, 0x000000, 0xFFFFFF, + 0x007F7A, 0x007F81, 0x000000, 0xFFFFFF, + 0x007F84, 0x007F84, 0x000000, 0xFFFFFF, + 0x007F89, 0x007F89, 0x000000, 0xFFFFFF, + 0x007F8B, 0x007F8B, 0x000000, 0xFFFFFF, + 0x007F8D, 0x007F8D, 0x000000, 0xFFFFFF, + 0x007F8F, 0x007F93, 0x000000, 0xFFFFFF, + 0x007F95, 0x007F99, 0x000000, 0xFFFFFF, + 0x007F9B, 0x007F9C, 0x000000, 0xFFFFFF, + 0x007F9F, 0x007FA2, 0x000000, 0xFFFFFF, + 0x007FA5, 0x007FA7, 0x000000, 0xFFFFFF, + 0x007FAA, 0x007FAD, 0x000000, 0xFFFFFF, + 0x007FB0, 0x007FB1, 0x000000, 0xFFFFFF, + 0x007FB3, 0x007FB5, 0x000000, 0xFFFFFF, + 0x007FB7, 0x007FB7, 0x000000, 0xFFFFFF, + 0x007FBA, 0x007FBC, 0x000000, 0xFFFFFF, + 0x007FBE, 0x007FC0, 0x000000, 0xFFFFFF, + 0x007FC2, 0x007FC4, 0x000000, 0xFFFFFF, + 0x007FC7, 0x007FC9, 0x000000, 0xFFFFFF, + 0x007FCB, 0x007FCB, 0x000000, 0xFFFFFF, + 0x007FCD, 0x007FD1, 0x000000, 0xFFFFFF, + 0x007FD3, 0x007FD3, 0x000000, 0xFFFFFF, + 0x007FD6, 0x007FDF, 0x000000, 0xFFFFFF, + 0x007FE2, 0x007FE5, 0x000000, 0xFFFFFF, + 0x007FE7, 0x007FE8, 0x000000, 0xFFFFFF, + 0x007FEA, 0x007FEA, 0x000000, 0xFFFFFF, + 0x007FEC, 0x007FEF, 0x000000, 0xFFFFFF, + 0x007FF1, 0x007FF2, 0x000000, 0xFFFFFF, + 0x007FF4, 0x007FF8, 0x000000, 0xFFFFFF, + 0x007FFA, 0x007FFA, 0x000000, 0xFFFFFF, + 0x007FFD, 0x007FFF, 0x000000, 0xFFFFFF, + 0x008002, 0x008002, 0x000000, 0xFFFFFF, + 0x008007, 0x00800A, 0x000000, 0xFFFFFF, + 0x00800D, 0x00800F, 0x000000, 0xFFFFFF, + 0x008011, 0x008011, 0x000000, 0xFFFFFF, + 0x008013, 0x008014, 0x000000, 0xFFFFFF, + 0x008016, 0x008016, 0x000000, 0xFFFFFF, + 0x00801A, 0x00801B, 0x000000, 0xFFFFFF, + 0x00801D, 0x008020, 0x000000, 0xFFFFFF, + 0x008022, 0x008027, 0x000000, 0xFFFFFF, + 0x008029, 0x008032, 0x000000, 0xFFFFFF, + 0x008034, 0x008035, 0x000000, 0xFFFFFF, + 0x008037, 0x00803A, 0x000000, 0xFFFFFF, + 0x00803C, 0x00803C, 0x000000, 0xFFFFFF, + 0x00803E, 0x00803E, 0x000000, 0xFFFFFF, + 0x008040, 0x008045, 0x000000, 0xFFFFFF, + 0x008047, 0x008049, 0x000000, 0xFFFFFF, + 0x00804B, 0x008051, 0x000000, 0xFFFFFF, + 0x008053, 0x008055, 0x000000, 0xFFFFFF, + 0x008057, 0x008057, 0x000000, 0xFFFFFF, + 0x008059, 0x008059, 0x000000, 0xFFFFFF, + 0x00805B, 0x00805D, 0x000000, 0xFFFFFF, + 0x008060, 0x008060, 0x000000, 0xFFFFFF, + 0x008063, 0x008067, 0x000000, 0xFFFFFF, + 0x008069, 0x00806E, 0x000000, 0xFFFFFF, + 0x008071, 0x008071, 0x000000, 0xFFFFFF, + 0x008075, 0x008075, 0x000000, 0xFFFFFF, + 0x008078, 0x008078, 0x000000, 0xFFFFFF, + 0x00807A, 0x00807C, 0x000000, 0xFFFFFF, + 0x008080, 0x008083, 0x000000, 0xFFFFFF, + 0x008088, 0x008088, 0x000000, 0xFFFFFF, + 0x00808A, 0x00808A, 0x000000, 0xFFFFFF, + 0x00808D, 0x008092, 0x000000, 0xFFFFFF, + 0x008094, 0x008095, 0x000000, 0xFFFFFF, + 0x008097, 0x008097, 0x000000, 0xFFFFFF, + 0x008099, 0x008099, 0x000000, 0xFFFFFF, + 0x00809C, 0x00809C, 0x000000, 0xFFFFFF, + 0x00809E, 0x0080A0, 0x000000, 0xFFFFFF, + 0x0080A3, 0x0080A4, 0x000000, 0xFFFFFF, + 0x0080A6, 0x0080A8, 0x000000, 0xFFFFFF, + 0x0080AB, 0x0080AB, 0x000000, 0xFFFFFF, + 0x0080AE, 0x0080AE, 0x000000, 0xFFFFFF, + 0x0080B0, 0x0080B0, 0x000000, 0xFFFFFF, + 0x0080B3, 0x0080B3, 0x000000, 0xFFFFFF, + 0x0080B5, 0x0080B9, 0x000000, 0xFFFFFF, + 0x0080BB, 0x0080C2, 0x000000, 0xFFFFFF, + 0x0080C5, 0x0080C5, 0x000000, 0xFFFFFF, + 0x0080C7, 0x0080CB, 0x000000, 0xFFFFFF, + 0x0080CD, 0x0080CD, 0x000000, 0xFFFFFF, + 0x0080CF, 0x0080D5, 0x000000, 0xFFFFFF, + 0x0080D7, 0x0080D8, 0x000000, 0xFFFFFF, + 0x0080DC, 0x0080DC, 0x000000, 0xFFFFFF, + 0x0080DF, 0x0080E0, 0x000000, 0xFFFFFF, + 0x0080E2, 0x0080E3, 0x000000, 0xFFFFFF, + 0x0080E6, 0x0080EE, 0x000000, 0xFFFFFF, + 0x0080F0, 0x0080F0, 0x000000, 0xFFFFFF, + 0x0080F2, 0x0080F3, 0x000000, 0xFFFFFF, + 0x0080F5, 0x0080F7, 0x000000, 0xFFFFFF, + 0x0080F9, 0x0080FB, 0x000000, 0xFFFFFF, + 0x0080FE, 0x008101, 0x000000, 0xFFFFFF, + 0x008103, 0x008104, 0x000000, 0xFFFFFF, + 0x00810B, 0x008119, 0x000000, 0xFFFFFF, + 0x00811C, 0x008122, 0x000000, 0xFFFFFF, + 0x008124, 0x008128, 0x000000, 0xFFFFFF, + 0x00812A, 0x00812E, 0x000000, 0xFFFFFF, + 0x008130, 0x008130, 0x000000, 0xFFFFFF, + 0x008132, 0x008132, 0x000000, 0xFFFFFF, + 0x008134, 0x008138, 0x000000, 0xFFFFFF, + 0x00813A, 0x00813D, 0x000000, 0xFFFFFF, + 0x00813F, 0x008145, 0x000000, 0xFFFFFF, + 0x008147, 0x00814A, 0x000000, 0xFFFFFF, + 0x00814C, 0x00814D, 0x000000, 0xFFFFFF, + 0x00814F, 0x00814F, 0x000000, 0xFFFFFF, + 0x008152, 0x008152, 0x000000, 0xFFFFFF, + 0x008156, 0x00815E, 0x000000, 0xFFFFFF, + 0x008160, 0x008164, 0x000000, 0xFFFFFF, + 0x008167, 0x00816A, 0x000000, 0xFFFFFF, + 0x00816C, 0x00816D, 0x000000, 0xFFFFFF, + 0x00816F, 0x00816F, 0x000000, 0xFFFFFF, + 0x008172, 0x008173, 0x000000, 0xFFFFFF, + 0x008175, 0x008177, 0x000000, 0xFFFFFF, + 0x00817B, 0x00817E, 0x000000, 0xFFFFFF, + 0x008181, 0x008181, 0x000000, 0xFFFFFF, + 0x008184, 0x008187, 0x000000, 0xFFFFFF, + 0x008189, 0x008189, 0x000000, 0xFFFFFF, + 0x00818B, 0x00818E, 0x000000, 0xFFFFFF, + 0x008190, 0x008192, 0x000000, 0xFFFFFF, + 0x008194, 0x008194, 0x000000, 0xFFFFFF, + 0x008196, 0x008199, 0x000000, 0xFFFFFF, + 0x00819B, 0x00819B, 0x000000, 0xFFFFFF, + 0x00819E, 0x00819F, 0x000000, 0xFFFFFF, + 0x0081A1, 0x0081A2, 0x000000, 0xFFFFFF, + 0x0081A5, 0x0081A7, 0x000000, 0xFFFFFF, + 0x0081AA, 0x0081AF, 0x000000, 0xFFFFFF, + 0x0081B1, 0x0081B2, 0x000000, 0xFFFFFF, + 0x0081B4, 0x0081B4, 0x000000, 0xFFFFFF, + 0x0081B6, 0x0081B7, 0x000000, 0xFFFFFF, + 0x0081B9, 0x0081B9, 0x000000, 0xFFFFFF, + 0x0081BB, 0x0081BC, 0x000000, 0xFFFFFF, + 0x0081C1, 0x0081C1, 0x000000, 0xFFFFFF, + 0x0081C3, 0x0081C5, 0x000000, 0xFFFFFF, + 0x0081C7, 0x0081C7, 0x000000, 0xFFFFFF, + 0x0081CA, 0x0081CC, 0x000000, 0xFFFFFF, + 0x0081CE, 0x0081D0, 0x000000, 0xFFFFFF, + 0x0081D2, 0x0081D2, 0x000000, 0xFFFFFF, + 0x0081D4, 0x0081D7, 0x000000, 0xFFFFFF, + 0x0081DB, 0x0081DE, 0x000000, 0xFFFFFF, + 0x0081E1, 0x0081E2, 0x000000, 0xFFFFFF, + 0x0081E4, 0x0081E4, 0x000000, 0xFFFFFF, + 0x0081E6, 0x0081E6, 0x000000, 0xFFFFFF, + 0x0081E9, 0x0081E9, 0x000000, 0xFFFFFF, + 0x0081EB, 0x0081EC, 0x000000, 0xFFFFFF, + 0x0081EE, 0x0081F2, 0x000000, 0xFFFFFF, + 0x0081F5, 0x0081F9, 0x000000, 0xFFFFFF, + 0x0081FD, 0x0081FD, 0x000000, 0xFFFFFF, + 0x0081FF, 0x008200, 0x000000, 0xFFFFFF, + 0x008203, 0x008204, 0x000000, 0xFFFFFF, + 0x008206, 0x008206, 0x000000, 0xFFFFFF, + 0x00820B, 0x00820B, 0x000000, 0xFFFFFF, + 0x00820F, 0x00820F, 0x000000, 0xFFFFFF, + 0x008211, 0x008211, 0x000000, 0xFFFFFF, + 0x008213, 0x008215, 0x000000, 0xFFFFFF, + 0x008219, 0x00821A, 0x000000, 0xFFFFFF, + 0x00821D, 0x00821D, 0x000000, 0xFFFFFF, + 0x008220, 0x008228, 0x000000, 0xFFFFFF, + 0x00822D, 0x00822D, 0x000000, 0xFFFFFF, + 0x00822F, 0x008232, 0x000000, 0xFFFFFF, + 0x008234, 0x008234, 0x000000, 0xFFFFFF, + 0x00823A, 0x00823F, 0x000000, 0xFFFFFF, + 0x008241, 0x008246, 0x000000, 0xFFFFFF, + 0x008248, 0x008257, 0x000000, 0xFFFFFF, + 0x00825B, 0x00825C, 0x000000, 0xFFFFFF, + 0x00825E, 0x00825E, 0x000000, 0xFFFFFF, + 0x008260, 0x008261, 0x000000, 0xFFFFFF, + 0x008263, 0x008263, 0x000000, 0xFFFFFF, + 0x008265, 0x008265, 0x000000, 0xFFFFFF, + 0x008267, 0x008267, 0x000000, 0xFFFFFF, + 0x008269, 0x008269, 0x000000, 0xFFFFFF, + 0x00826C, 0x00826D, 0x000000, 0xFFFFFF, + 0x008270, 0x008270, 0x000000, 0xFFFFFF, + 0x008273, 0x008275, 0x000000, 0xFFFFFF, + 0x008279, 0x00827D, 0x000000, 0xFFFFFF, + 0x00827F, 0x00828A, 0x000000, 0xFFFFFF, + 0x00828C, 0x00828C, 0x000000, 0xFFFFFF, + 0x00828E, 0x008291, 0x000000, 0xFFFFFF, + 0x008293, 0x008298, 0x000000, 0xFFFFFF, + 0x00829A, 0x00829C, 0x000000, 0xFFFFFF, + 0x00829E, 0x00829E, 0x000000, 0xFFFFFF, + 0x0082A0, 0x0082A4, 0x000000, 0xFFFFFF, + 0x0082A7, 0x0082AA, 0x000000, 0xFFFFFF, + 0x0082AE, 0x0082AE, 0x000000, 0xFFFFFF, + 0x0082B0, 0x0082B0, 0x000000, 0xFFFFFF, + 0x0082B2, 0x0082B2, 0x000000, 0xFFFFFF, + 0x0082B4, 0x0082B7, 0x000000, 0xFFFFFF, + 0x0082BA, 0x0082BA, 0x000000, 0xFFFFFF, + 0x0082BC, 0x0082BC, 0x000000, 0xFFFFFF, + 0x0082BE, 0x0082C4, 0x000000, 0xFFFFFF, + 0x0082C6, 0x0082D0, 0x000000, 0xFFFFFF, + 0x0082D5, 0x0082D6, 0x000000, 0xFFFFFF, + 0x0082D8, 0x0082D8, 0x000000, 0xFFFFFF, + 0x0082DA, 0x0082DA, 0x000000, 0xFFFFFF, + 0x0082DD, 0x0082DD, 0x000000, 0xFFFFFF, + 0x0082E0, 0x0082E0, 0x000000, 0xFFFFFF, + 0x0082E2, 0x0082E2, 0x000000, 0xFFFFFF, + 0x0082E4, 0x0082E4, 0x000000, 0xFFFFFF, + 0x0082E8, 0x0082EA, 0x000000, 0xFFFFFF, + 0x0082EC, 0x0082F0, 0x000000, 0xFFFFFF, + 0x0082F2, 0x0082F2, 0x000000, 0xFFFFFF, + 0x0082F5, 0x0082F8, 0x000000, 0xFFFFFF, + 0x0082FC, 0x008301, 0x000000, 0xFFFFFF, + 0x008307, 0x008308, 0x000000, 0xFFFFFF, + 0x00830A, 0x00830D, 0x000000, 0xFFFFFF, + 0x00830F, 0x008315, 0x000000, 0xFFFFFF, + 0x008319, 0x00831B, 0x000000, 0xFFFFFF, + 0x00831D, 0x008322, 0x000000, 0xFFFFFF, + 0x008324, 0x008327, 0x000000, 0xFFFFFF, + 0x008329, 0x00832A, 0x000000, 0xFFFFFF, + 0x00832C, 0x00832E, 0x000000, 0xFFFFFF, + 0x008330, 0x008330, 0x000000, 0xFFFFFF, + 0x008333, 0x008333, 0x000000, 0xFFFFFF, + 0x008337, 0x008337, 0x000000, 0xFFFFFF, + 0x00833A, 0x00833F, 0x000000, 0xFFFFFF, + 0x008341, 0x008344, 0x000000, 0xFFFFFF, + 0x008346, 0x008348, 0x000000, 0xFFFFFF, + 0x00834B, 0x00834E, 0x000000, 0xFFFFFF, + 0x008351, 0x008351, 0x000000, 0xFFFFFF, + 0x008353, 0x008357, 0x000000, 0xFFFFFF, + 0x008359, 0x008372, 0x000000, 0xFFFFFF, + 0x008374, 0x008374, 0x000000, 0xFFFFFF, + 0x008376, 0x008376, 0x000000, 0xFFFFFF, + 0x008378, 0x00837A, 0x000000, 0xFFFFFF, + 0x00837D, 0x008384, 0x000000, 0xFFFFFF, + 0x008386, 0x008386, 0x000000, 0xFFFFFF, + 0x008388, 0x008388, 0x000000, 0xFFFFFF, + 0x00838B, 0x00838D, 0x000000, 0xFFFFFF, + 0x00838F, 0x008392, 0x000000, 0xFFFFFF, + 0x008394, 0x008395, 0x000000, 0xFFFFFF, + 0x008397, 0x008399, 0x000000, 0xFFFFFF, + 0x00839B, 0x00839D, 0x000000, 0xFFFFFF, + 0x0083A1, 0x0083A1, 0x000000, 0xFFFFFF, + 0x0083A3, 0x0083A7, 0x000000, 0xFFFFFF, + 0x0083A9, 0x0083A9, 0x000000, 0xFFFFFF, + 0x0083AC, 0x0083B0, 0x000000, 0xFFFFFF, + 0x0083B2, 0x0083B4, 0x000000, 0xFFFFFF, + 0x0083B6, 0x0083BC, 0x000000, 0xFFFFFF, + 0x0083BE, 0x0083C0, 0x000000, 0xFFFFFF, + 0x0083C2, 0x0083C4, 0x000000, 0xFFFFFF, + 0x0083C6, 0x0083C9, 0x000000, 0xFFFFFF, + 0x0083CB, 0x0083CB, 0x000000, 0xFFFFFF, + 0x0083CD, 0x0083CD, 0x000000, 0xFFFFFF, + 0x0083CF, 0x0083D2, 0x000000, 0xFFFFFF, + 0x0083D4, 0x0083D5, 0x000000, 0xFFFFFF, + 0x0083D7, 0x0083D7, 0x000000, 0xFFFFFF, + 0x0083D9, 0x0083DB, 0x000000, 0xFFFFFF, + 0x0083DD, 0x0083DE, 0x000000, 0xFFFFFF, + 0x0083E1, 0x0083E8, 0x000000, 0xFFFFFF, + 0x0083EA, 0x0083EA, 0x000000, 0xFFFFFF, + 0x0083EC, 0x0083EE, 0x000000, 0xFFFFFF, + 0x0083F3, 0x0083F3, 0x000000, 0xFFFFFF, + 0x0083F5, 0x0083F6, 0x000000, 0xFFFFFF, + 0x0083F8, 0x0083FA, 0x000000, 0xFFFFFF, + 0x0083FC, 0x0083FC, 0x000000, 0xFFFFFF, + 0x0083FE, 0x008402, 0x000000, 0xFFFFFF, + 0x008405, 0x008406, 0x000000, 0xFFFFFF, + 0x008408, 0x00840A, 0x000000, 0xFFFFFF, + 0x00840F, 0x008412, 0x000000, 0xFFFFFF, + 0x008414, 0x00841F, 0x000000, 0xFFFFFF, + 0x008421, 0x008421, 0x000000, 0xFFFFFF, + 0x008423, 0x008428, 0x000000, 0xFFFFFF, + 0x00842B, 0x00842B, 0x000000, 0xFFFFFF, + 0x00842D, 0x008430, 0x000000, 0xFFFFFF, + 0x008432, 0x008434, 0x000000, 0xFFFFFF, + 0x008436, 0x008437, 0x000000, 0xFFFFFF, + 0x008439, 0x00843B, 0x000000, 0xFFFFFF, + 0x00843E, 0x008445, 0x000000, 0xFFFFFF, + 0x008447, 0x008448, 0x000000, 0xFFFFFF, + 0x00844A, 0x00844D, 0x000000, 0xFFFFFF, + 0x00844F, 0x008456, 0x000000, 0xFFFFFF, + 0x008458, 0x00845A, 0x000000, 0xFFFFFF, + 0x00845C, 0x008460, 0x000000, 0xFFFFFF, + 0x008464, 0x008465, 0x000000, 0xFFFFFF, + 0x008467, 0x008468, 0x000000, 0xFFFFFF, + 0x00846A, 0x00846A, 0x000000, 0xFFFFFF, + 0x008470, 0x008470, 0x000000, 0xFFFFFF, + 0x008472, 0x008474, 0x000000, 0xFFFFFF, + 0x008476, 0x008476, 0x000000, 0xFFFFFF, + 0x008478, 0x008478, 0x000000, 0xFFFFFF, + 0x00847B, 0x008481, 0x000000, 0xFFFFFF, + 0x008483, 0x008483, 0x000000, 0xFFFFFF, + 0x008485, 0x00848A, 0x000000, 0xFFFFFF, + 0x00848C, 0x00848F, 0x000000, 0xFFFFFF, + 0x008491, 0x008493, 0x000000, 0xFFFFFF, + 0x008495, 0x008498, 0x000000, 0xFFFFFF, + 0x00849A, 0x00849B, 0x000000, 0xFFFFFF, + 0x00849D, 0x00849E, 0x000000, 0xFFFFFF, + 0x0084A0, 0x0084A0, 0x000000, 0xFFFFFF, + 0x0084A2, 0x0084AC, 0x000000, 0xFFFFFF, + 0x0084AE, 0x0084B1, 0x000000, 0xFFFFFF, + 0x0084B3, 0x0084B7, 0x000000, 0xFFFFFF, + 0x0084BA, 0x0084BA, 0x000000, 0xFFFFFF, + 0x0084BD, 0x0084BE, 0x000000, 0xFFFFFF, + 0x0084C0, 0x0084C0, 0x000000, 0xFFFFFF, + 0x0084C2, 0x0084C3, 0x000000, 0xFFFFFF, + 0x0084C5, 0x0084C5, 0x000000, 0xFFFFFF, + 0x0084C7, 0x0084C8, 0x000000, 0xFFFFFF, + 0x0084CC, 0x0084CC, 0x000000, 0xFFFFFF, + 0x0084CE, 0x0084CF, 0x000000, 0xFFFFFF, + 0x0084D2, 0x0084D5, 0x000000, 0xFFFFFF, + 0x0084D7, 0x0084D8, 0x000000, 0xFFFFFF, + 0x0084DB, 0x0084EB, 0x000000, 0xFFFFFF, + 0x0084ED, 0x0084ED, 0x000000, 0xFFFFFF, + 0x0084EF, 0x0084F3, 0x000000, 0xFFFFFF, + 0x0084F5, 0x0084FB, 0x000000, 0xFFFFFF, + 0x0084FD, 0x0084FE, 0x000000, 0xFFFFFF, + 0x008501, 0x008505, 0x000000, 0xFFFFFF, + 0x008507, 0x008510, 0x000000, 0xFFFFFF, + 0x008512, 0x008512, 0x000000, 0xFFFFFF, + 0x008516, 0x008516, 0x000000, 0xFFFFFF, + 0x008519, 0x008519, 0x000000, 0xFFFFFF, + 0x00851B, 0x00851E, 0x000000, 0xFFFFFF, + 0x008520, 0x008520, 0x000000, 0xFFFFFF, + 0x008522, 0x008525, 0x000000, 0xFFFFFF, + 0x008527, 0x00852B, 0x000000, 0xFFFFFF, + 0x00852E, 0x008534, 0x000000, 0xFFFFFF, + 0x008536, 0x00853C, 0x000000, 0xFFFFFF, + 0x00853E, 0x00853F, 0x000000, 0xFFFFFF, + 0x008542, 0x008542, 0x000000, 0xFFFFFF, + 0x008544, 0x008547, 0x000000, 0xFFFFFF, + 0x00854C, 0x00854D, 0x000000, 0xFFFFFF, + 0x00854F, 0x008554, 0x000000, 0xFFFFFF, + 0x008556, 0x008556, 0x000000, 0xFFFFFF, + 0x008559, 0x008559, 0x000000, 0xFFFFFF, + 0x00855B, 0x008562, 0x000000, 0xFFFFFF, + 0x008564, 0x008567, 0x000000, 0xFFFFFF, + 0x00856B, 0x00856C, 0x000000, 0xFFFFFF, + 0x00856E, 0x008576, 0x000000, 0xFFFFFF, + 0x008578, 0x00857D, 0x000000, 0xFFFFFF, + 0x00857F, 0x00857F, 0x000000, 0xFFFFFF, + 0x008581, 0x008583, 0x000000, 0xFFFFFF, + 0x008585, 0x008586, 0x000000, 0xFFFFFF, + 0x008589, 0x008589, 0x000000, 0xFFFFFF, + 0x00858B, 0x00858F, 0x000000, 0xFFFFFF, + 0x008592, 0x008593, 0x000000, 0xFFFFFF, + 0x008595, 0x008596, 0x000000, 0xFFFFFF, + 0x008598, 0x008598, 0x000000, 0xFFFFFF, + 0x00859A, 0x00859A, 0x000000, 0xFFFFFF, + 0x00859D, 0x0085A3, 0x000000, 0xFFFFFF, + 0x0085A5, 0x0085A5, 0x000000, 0xFFFFFF, + 0x0085A7, 0x0085A7, 0x000000, 0xFFFFFF, + 0x0085AD, 0x0085AD, 0x000000, 0xFFFFFF, + 0x0085B0, 0x0085B8, 0x000000, 0xFFFFFF, + 0x0085BB, 0x0085C0, 0x000000, 0xFFFFFF, + 0x0085C2, 0x0085C8, 0x000000, 0xFFFFFF, + 0x0085CA, 0x0085CC, 0x000000, 0xFFFFFF, + 0x0085CE, 0x0085CE, 0x000000, 0xFFFFFF, + 0x0085D1, 0x0085D4, 0x000000, 0xFFFFFF, + 0x0085D6, 0x0085DB, 0x000000, 0xFFFFFF, + 0x0085DE, 0x0085E3, 0x000000, 0xFFFFFF, + 0x0085E6, 0x0085E8, 0x000000, 0xFFFFFF, + 0x0085EB, 0x0085F6, 0x000000, 0xFFFFFF, + 0x0085F8, 0x0085F8, 0x000000, 0xFFFFFF, + 0x0085FC, 0x0085FD, 0x000000, 0xFFFFFF, + 0x0085FF, 0x008601, 0x000000, 0xFFFFFF, + 0x008603, 0x008605, 0x000000, 0xFFFFFF, + 0x008608, 0x008609, 0x000000, 0xFFFFFF, + 0x00860C, 0x008612, 0x000000, 0xFFFFFF, + 0x008614, 0x008615, 0x000000, 0xFFFFFF, + 0x008618, 0x008619, 0x000000, 0xFFFFFF, + 0x00861B, 0x008621, 0x000000, 0xFFFFFF, + 0x008623, 0x00862C, 0x000000, 0xFFFFFF, + 0x00862E, 0x00862E, 0x000000, 0xFFFFFF, + 0x008631, 0x00863E, 0x000000, 0xFFFFFF, + 0x008640, 0x00864C, 0x000000, 0xFFFFFF, + 0x00864F, 0x00864F, 0x000000, 0xFFFFFF, + 0x008651, 0x008653, 0x000000, 0xFFFFFF, + 0x008656, 0x008659, 0x000000, 0xFFFFFF, + 0x00865B, 0x00865B, 0x000000, 0xFFFFFF, + 0x00865D, 0x00865D, 0x000000, 0xFFFFFF, + 0x008660, 0x008666, 0x000000, 0xFFFFFF, + 0x008668, 0x00866A, 0x000000, 0xFFFFFF, + 0x00866C, 0x008670, 0x000000, 0xFFFFFF, + 0x008672, 0x008678, 0x000000, 0xFFFFFF, + 0x00867A, 0x00867A, 0x000000, 0xFFFFFF, + 0x00867C, 0x008689, 0x000000, 0xFFFFFF, + 0x00868D, 0x008692, 0x000000, 0xFFFFFF, + 0x008694, 0x008694, 0x000000, 0xFFFFFF, + 0x008696, 0x0086A2, 0x000000, 0xFFFFFF, + 0x0086A5, 0x0086A8, 0x000000, 0xFFFFFF, + 0x0086AC, 0x0086AE, 0x000000, 0xFFFFFF, + 0x0086B1, 0x0086B5, 0x000000, 0xFFFFFF, + 0x0086B7, 0x0086C3, 0x000000, 0xFFFFFF, + 0x0086C5, 0x0086C5, 0x000000, 0xFFFFFF, + 0x0086C8, 0x0086C8, 0x000000, 0xFFFFFF, + 0x0086CA, 0x0086CA, 0x000000, 0xFFFFFF, + 0x0086CC, 0x0086CC, 0x000000, 0xFFFFFF, + 0x0086CF, 0x0086D3, 0x000000, 0xFFFFFF, + 0x0086D5, 0x0086D8, 0x000000, 0xFFFFFF, + 0x0086DA, 0x0086DA, 0x000000, 0xFFFFFF, + 0x0086DC, 0x0086DD, 0x000000, 0xFFFFFF, + 0x0086E0, 0x0086E3, 0x000000, 0xFFFFFF, + 0x0086E5, 0x0086E8, 0x000000, 0xFFFFFF, + 0x0086EA, 0x0086EB, 0x000000, 0xFFFFFF, + 0x0086F0, 0x0086F7, 0x000000, 0xFFFFFF, + 0x0086FA, 0x0086FA, 0x000000, 0xFFFFFF, + 0x0086FC, 0x0086FD, 0x000000, 0xFFFFFF, + 0x0086FF, 0x0086FF, 0x000000, 0xFFFFFF, + 0x008701, 0x008701, 0x000000, 0xFFFFFF, + 0x008704, 0x008705, 0x000000, 0xFFFFFF, + 0x008707, 0x008707, 0x000000, 0xFFFFFF, + 0x00870B, 0x00870C, 0x000000, 0xFFFFFF, + 0x00870E, 0x008710, 0x000000, 0xFFFFFF, + 0x008713, 0x008717, 0x000000, 0xFFFFFF, + 0x008719, 0x008719, 0x000000, 0xFFFFFF, + 0x00871B, 0x00871B, 0x000000, 0xFFFFFF, + 0x00871D, 0x008724, 0x000000, 0xFFFFFF, + 0x008726, 0x008728, 0x000000, 0xFFFFFF, + 0x00872A, 0x008733, 0x000000, 0xFFFFFF, + 0x008735, 0x008736, 0x000000, 0xFFFFFF, + 0x008738, 0x00873A, 0x000000, 0xFFFFFF, + 0x00873C, 0x00873E, 0x000000, 0xFFFFFF, + 0x008740, 0x008748, 0x000000, 0xFFFFFF, + 0x00874A, 0x00874A, 0x000000, 0xFFFFFF, + 0x00874D, 0x00874D, 0x000000, 0xFFFFFF, + 0x00874F, 0x008752, 0x000000, 0xFFFFFF, + 0x008754, 0x008754, 0x000000, 0xFFFFFF, + 0x008756, 0x008756, 0x000000, 0xFFFFFF, + 0x008758, 0x008758, 0x000000, 0xFFFFFF, + 0x00875A, 0x00875E, 0x000000, 0xFFFFFF, + 0x008761, 0x008762, 0x000000, 0xFFFFFF, + 0x008764, 0x008765, 0x000000, 0xFFFFFF, + 0x008767, 0x008767, 0x000000, 0xFFFFFF, + 0x008769, 0x008769, 0x000000, 0xFFFFFF, + 0x00876B, 0x00876D, 0x000000, 0xFFFFFF, + 0x00876F, 0x008773, 0x000000, 0xFFFFFF, + 0x008775, 0x008775, 0x000000, 0xFFFFFF, + 0x008777, 0x008777, 0x000000, 0xFFFFFF, + 0x008779, 0x00877E, 0x000000, 0xFFFFFF, + 0x008780, 0x008781, 0x000000, 0xFFFFFF, + 0x008783, 0x00878C, 0x000000, 0xFFFFFF, + 0x00878E, 0x00879E, 0x000000, 0xFFFFFF, + 0x0087A0, 0x0087A1, 0x000000, 0xFFFFFF, + 0x0087A3, 0x0087AA, 0x000000, 0xFFFFFF, + 0x0087AC, 0x0087AE, 0x000000, 0xFFFFFF, + 0x0087B0, 0x0087B2, 0x000000, 0xFFFFFF, + 0x0087B4, 0x0087B9, 0x000000, 0xFFFFFF, + 0x0087BC, 0x0087BC, 0x000000, 0xFFFFFF, + 0x0087BE, 0x0087BF, 0x000000, 0xFFFFFF, + 0x0087C1, 0x0087C3, 0x000000, 0xFFFFFF, + 0x0087C5, 0x0087C5, 0x000000, 0xFFFFFF, + 0x0087C8, 0x0087CA, 0x000000, 0xFFFFFF, + 0x0087CC, 0x0087CF, 0x000000, 0xFFFFFF, + 0x0087D1, 0x0087D1, 0x000000, 0xFFFFFF, + 0x0087D3, 0x0087DF, 0x000000, 0xFFFFFF, + 0x0087E1, 0x0087EE, 0x000000, 0xFFFFFF, + 0x0087F0, 0x0087F1, 0x000000, 0xFFFFFF, + 0x0087F3, 0x0087F5, 0x000000, 0xFFFFFF, + 0x0087F8, 0x0087F8, 0x000000, 0xFFFFFF, + 0x0087FA, 0x0087FA, 0x000000, 0xFFFFFF, + 0x0087FC, 0x0087FD, 0x000000, 0xFFFFFF, + 0x0087FF, 0x008804, 0x000000, 0xFFFFFF, + 0x008806, 0x00880C, 0x000000, 0xFFFFFF, + 0x008810, 0x008810, 0x000000, 0xFFFFFF, + 0x008812, 0x008814, 0x000000, 0xFFFFFF, + 0x008817, 0x008820, 0x000000, 0xFFFFFF, + 0x008824, 0x008826, 0x000000, 0xFFFFFF, + 0x008828, 0x008830, 0x000000, 0xFFFFFF, + 0x008832, 0x008835, 0x000000, 0xFFFFFF, + 0x008837, 0x008838, 0x000000, 0xFFFFFF, + 0x00883A, 0x00883A, 0x000000, 0xFFFFFF, + 0x00883C, 0x00883F, 0x000000, 0xFFFFFF, + 0x008841, 0x008841, 0x000000, 0xFFFFFF, + 0x008843, 0x008843, 0x000000, 0xFFFFFF, + 0x008845, 0x008845, 0x000000, 0xFFFFFF, + 0x008847, 0x00884B, 0x000000, 0xFFFFFF, + 0x00884E, 0x008851, 0x000000, 0xFFFFFF, + 0x008854, 0x008856, 0x000000, 0xFFFFFF, + 0x008858, 0x008858, 0x000000, 0xFFFFFF, + 0x00885A, 0x00885A, 0x000000, 0xFFFFFF, + 0x00885C, 0x00885C, 0x000000, 0xFFFFFF, + 0x00885F, 0x008860, 0x000000, 0xFFFFFF, + 0x008864, 0x008867, 0x000000, 0xFFFFFF, + 0x008869, 0x00886A, 0x000000, 0xFFFFFF, + 0x00886C, 0x00886F, 0x000000, 0xFFFFFF, + 0x008871, 0x008871, 0x000000, 0xFFFFFF, + 0x008873, 0x008874, 0x000000, 0xFFFFFF, + 0x008876, 0x008876, 0x000000, 0xFFFFFF, + 0x008878, 0x00887C, 0x000000, 0xFFFFFF, + 0x008880, 0x008880, 0x000000, 0xFFFFFF, + 0x008883, 0x008887, 0x000000, 0xFFFFFF, + 0x008889, 0x00888A, 0x000000, 0xFFFFFF, + 0x00888C, 0x00888C, 0x000000, 0xFFFFFF, + 0x00888E, 0x008891, 0x000000, 0xFFFFFF, + 0x008893, 0x008895, 0x000000, 0xFFFFFF, + 0x008898, 0x008898, 0x000000, 0xFFFFFF, + 0x00889A, 0x00889D, 0x000000, 0xFFFFFF, + 0x00889F, 0x0088A1, 0x000000, 0xFFFFFF, + 0x0088A3, 0x0088A3, 0x000000, 0xFFFFFF, + 0x0088A5, 0x0088AA, 0x000000, 0xFFFFFF, + 0x0088AC, 0x0088AD, 0x000000, 0xFFFFFF, + 0x0088AF, 0x0088AF, 0x000000, 0xFFFFFF, + 0x0088B2, 0x0088B3, 0x000000, 0xFFFFFF, + 0x0088B6, 0x0088B6, 0x000000, 0xFFFFFF, + 0x0088B8, 0x0088BE, 0x000000, 0xFFFFFF, + 0x0088C0, 0x0088C0, 0x000000, 0xFFFFFF, + 0x0088C6, 0x0088CE, 0x000000, 0xFFFFFF, + 0x0088D0, 0x0088D3, 0x000000, 0xFFFFFF, + 0x0088D6, 0x0088D7, 0x000000, 0xFFFFFF, + 0x0088DA, 0x0088DB, 0x000000, 0xFFFFFF, + 0x0088DE, 0x0088DE, 0x000000, 0xFFFFFF, + 0x0088E0, 0x0088E0, 0x000000, 0xFFFFFF, + 0x0088E2, 0x0088E7, 0x000000, 0xFFFFFF, + 0x0088E9, 0x0088F1, 0x000000, 0xFFFFFF, + 0x0088F5, 0x0088F7, 0x000000, 0xFFFFFF, + 0x0088FA, 0x0088FB, 0x000000, 0xFFFFFF, + 0x0088FF, 0x008901, 0x000000, 0xFFFFFF, + 0x008903, 0x008903, 0x000000, 0xFFFFFF, + 0x008905, 0x008906, 0x000000, 0xFFFFFF, + 0x008908, 0x008909, 0x000000, 0xFFFFFF, + 0x00890B, 0x00890B, 0x000000, 0xFFFFFF, + 0x00890D, 0x00890F, 0x000000, 0xFFFFFF, + 0x008911, 0x008911, 0x000000, 0xFFFFFF, + 0x008914, 0x00891C, 0x000000, 0xFFFFFF, + 0x00891F, 0x008924, 0x000000, 0xFFFFFF, + 0x008926, 0x008929, 0x000000, 0xFFFFFF, + 0x00892C, 0x008935, 0x000000, 0xFFFFFF, + 0x008937, 0x008937, 0x000000, 0xFFFFFF, + 0x008939, 0x00893A, 0x000000, 0xFFFFFF, + 0x00893C, 0x008940, 0x000000, 0xFFFFFF, + 0x008942, 0x008942, 0x000000, 0xFFFFFF, + 0x008945, 0x00894B, 0x000000, 0xFFFFFF, + 0x00894E, 0x008955, 0x000000, 0xFFFFFF, + 0x008957, 0x00895D, 0x000000, 0xFFFFFF, + 0x008961, 0x008963, 0x000000, 0xFFFFFF, + 0x008965, 0x008965, 0x000000, 0xFFFFFF, + 0x008967, 0x008969, 0x000000, 0xFFFFFF, + 0x00896B, 0x00896C, 0x000000, 0xFFFFFF, + 0x00896E, 0x00896E, 0x000000, 0xFFFFFF, + 0x008970, 0x008971, 0x000000, 0xFFFFFF, + 0x008973, 0x008973, 0x000000, 0xFFFFFF, + 0x008975, 0x008976, 0x000000, 0xFFFFFF, + 0x008978, 0x00897D, 0x000000, 0xFFFFFF, + 0x008980, 0x008980, 0x000000, 0xFFFFFF, + 0x008982, 0x008982, 0x000000, 0xFFFFFF, + 0x008984, 0x008985, 0x000000, 0xFFFFFF, + 0x008989, 0x008989, 0x000000, 0xFFFFFF, + 0x00898C, 0x00898E, 0x000000, 0xFFFFFF, + 0x008990, 0x008992, 0x000000, 0xFFFFFF, + 0x008994, 0x008995, 0x000000, 0xFFFFFF, + 0x008999, 0x008999, 0x000000, 0xFFFFFF, + 0x00899B, 0x0089A0, 0x000000, 0xFFFFFF, + 0x0089A2, 0x0089A5, 0x000000, 0xFFFFFF, + 0x0089A8, 0x0089A8, 0x000000, 0xFFFFFF, + 0x0089AB, 0x0089AB, 0x000000, 0xFFFFFF, + 0x0089AD, 0x0089AE, 0x000000, 0xFFFFFF, + 0x0089B0, 0x0089B1, 0x000000, 0xFFFFFF, + 0x0089B4, 0x0089B9, 0x000000, 0xFFFFFF, + 0x0089BB, 0x0089BC, 0x000000, 0xFFFFFF, + 0x0089BE, 0x0089BE, 0x000000, 0xFFFFFF, + 0x0089C1, 0x0089D1, 0x000000, 0xFFFFFF, + 0x0089D3, 0x0089D9, 0x000000, 0xFFFFFF, + 0x0089DB, 0x0089DB, 0x000000, 0xFFFFFF, + 0x0089DE, 0x0089E2, 0x000000, 0xFFFFFF, + 0x0089E4, 0x0089E5, 0x000000, 0xFFFFFF, + 0x0089E8, 0x0089F3, 0x000000, 0xFFFFFF, + 0x0089F5, 0x0089F7, 0x000000, 0xFFFFFF, + 0x0089F9, 0x0089FF, 0x000000, 0xFFFFFF, + 0x008A01, 0x008A01, 0x000000, 0xFFFFFF, + 0x008A04, 0x008A07, 0x000000, 0xFFFFFF, + 0x008A09, 0x008A09, 0x000000, 0xFFFFFF, + 0x008A0B, 0x008A0B, 0x000000, 0xFFFFFF, + 0x008A0D, 0x008A0D, 0x000000, 0xFFFFFF, + 0x008A0F, 0x008A0F, 0x000000, 0xFFFFFF, + 0x008A11, 0x008A12, 0x000000, 0xFFFFFF, + 0x008A14, 0x008A15, 0x000000, 0xFFFFFF, + 0x008A19, 0x008A1A, 0x000000, 0xFFFFFF, + 0x008A1C, 0x008A1C, 0x000000, 0xFFFFFF, + 0x008A1E, 0x008A1E, 0x000000, 0xFFFFFF, + 0x008A20, 0x008A22, 0x000000, 0xFFFFFF, + 0x008A24, 0x008A24, 0x000000, 0xFFFFFF, + 0x008A26, 0x008A29, 0x000000, 0xFFFFFF, + 0x008A2B, 0x008A2C, 0x000000, 0xFFFFFF, + 0x008A2E, 0x008A30, 0x000000, 0xFFFFFF, + 0x008A32, 0x008A32, 0x000000, 0xFFFFFF, + 0x008A35, 0x008A35, 0x000000, 0xFFFFFF, + 0x008A37, 0x008A39, 0x000000, 0xFFFFFF, + 0x008A3D, 0x008A40, 0x000000, 0xFFFFFF, + 0x008A42, 0x008A45, 0x000000, 0xFFFFFF, + 0x008A47, 0x008A47, 0x000000, 0xFFFFFF, + 0x008A49, 0x008A4F, 0x000000, 0xFFFFFF, + 0x008A53, 0x008A53, 0x000000, 0xFFFFFF, + 0x008A56, 0x008A5A, 0x000000, 0xFFFFFF, + 0x008A5C, 0x008A5D, 0x000000, 0xFFFFFF, + 0x008A5F, 0x008A5F, 0x000000, 0xFFFFFF, + 0x008A61, 0x008A61, 0x000000, 0xFFFFFF, + 0x008A64, 0x008A65, 0x000000, 0xFFFFFF, + 0x008A67, 0x008A68, 0x000000, 0xFFFFFF, + 0x008A6A, 0x008A6A, 0x000000, 0xFFFFFF, + 0x008A6F, 0x008A6F, 0x000000, 0xFFFFFF, + 0x008A74, 0x008A7B, 0x000000, 0xFFFFFF, + 0x008A7D, 0x008A81, 0x000000, 0xFFFFFF, + 0x008A83, 0x008A83, 0x000000, 0xFFFFFF, + 0x008A86, 0x008A86, 0x000000, 0xFFFFFF, + 0x008A88, 0x008A88, 0x000000, 0xFFFFFF, + 0x008A8A, 0x008A8B, 0x000000, 0xFFFFFF, + 0x008A8E, 0x008A90, 0x000000, 0xFFFFFF, + 0x008A92, 0x008A92, 0x000000, 0xFFFFFF, + 0x008A94, 0x008A94, 0x000000, 0xFFFFFF, + 0x008A96, 0x008A97, 0x000000, 0xFFFFFF, + 0x008A99, 0x008A99, 0x000000, 0xFFFFFF, + 0x008A9B, 0x008A9D, 0x000000, 0xFFFFFF, + 0x008A9F, 0x008A9F, 0x000000, 0xFFFFFF, + 0x008AA2, 0x008AA2, 0x000000, 0xFFFFFF, + 0x008AA7, 0x008AA7, 0x000000, 0xFFFFFF, + 0x008AA9, 0x008AAB, 0x000000, 0xFFFFFF, + 0x008AAE, 0x008AAF, 0x000000, 0xFFFFFF, + 0x008AB1, 0x008AB1, 0x000000, 0xFFFFFF, + 0x008AB3, 0x008AB8, 0x000000, 0xFFFFFF, + 0x008ABA, 0x008ABB, 0x000000, 0xFFFFFF, + 0x008ABD, 0x008ABE, 0x000000, 0xFFFFFF, + 0x008AC0, 0x008AC1, 0x000000, 0xFFFFFF, + 0x008AC3, 0x008AC3, 0x000000, 0xFFFFFF, + 0x008AC5, 0x008AC6, 0x000000, 0xFFFFFF, + 0x008AC8, 0x008ACA, 0x000000, 0xFFFFFF, + 0x008ACE, 0x008ACE, 0x000000, 0xFFFFFF, + 0x008AD0, 0x008AD1, 0x000000, 0xFFFFFF, + 0x008AD3, 0x008AD5, 0x000000, 0xFFFFFF, + 0x008AD7, 0x008AD9, 0x000000, 0xFFFFFF, + 0x008ADD, 0x008ADD, 0x000000, 0xFFFFFF, + 0x008ADF, 0x008ADF, 0x000000, 0xFFFFFF, + 0x008AE3, 0x008AE3, 0x000000, 0xFFFFFF, + 0x008AE5, 0x008AE5, 0x000000, 0xFFFFFF, + 0x008AE8, 0x008AEA, 0x000000, 0xFFFFFF, + 0x008AEC, 0x008AEC, 0x000000, 0xFFFFFF, + 0x008AEF, 0x008AF0, 0x000000, 0xFFFFFF, + 0x008AF2, 0x008AF2, 0x000000, 0xFFFFFF, + 0x008AF4, 0x008AF6, 0x000000, 0xFFFFFF, + 0x008AF9, 0x008AF9, 0x000000, 0xFFFFFF, + 0x008AFB, 0x008AFD, 0x000000, 0xFFFFFF, + 0x008AFF, 0x008AFF, 0x000000, 0xFFFFFF, + 0x008B03, 0x008B03, 0x000000, 0xFFFFFF, + 0x008B05, 0x008B06, 0x000000, 0xFFFFFF, + 0x008B08, 0x008B0B, 0x000000, 0xFFFFFF, + 0x008B0D, 0x008B0D, 0x000000, 0xFFFFFF, + 0x008B0F, 0x008B0F, 0x000000, 0xFFFFFF, + 0x008B11, 0x008B13, 0x000000, 0xFFFFFF, + 0x008B15, 0x008B15, 0x000000, 0xFFFFFF, + 0x008B18, 0x008B18, 0x000000, 0xFFFFFF, + 0x008B1C, 0x008B1C, 0x000000, 0xFFFFFF, + 0x008B1E, 0x008B1F, 0x000000, 0xFFFFFF, + 0x008B22, 0x008B25, 0x000000, 0xFFFFFF, + 0x008B27, 0x008B27, 0x000000, 0xFFFFFF, + 0x008B29, 0x008B2A, 0x000000, 0xFFFFFF, + 0x008B2D, 0x008B32, 0x000000, 0xFFFFFF, + 0x008B34, 0x008B38, 0x000000, 0xFFFFFF, + 0x008B3A, 0x008B3D, 0x000000, 0xFFFFFF, + 0x008B3F, 0x008B40, 0x000000, 0xFFFFFF, + 0x008B42, 0x008B48, 0x000000, 0xFFFFFF, + 0x008B4A, 0x008B4B, 0x000000, 0xFFFFFF, + 0x008B4D, 0x008B4D, 0x000000, 0xFFFFFF, + 0x008B50, 0x008B55, 0x000000, 0xFFFFFF, + 0x008B57, 0x008B57, 0x000000, 0xFFFFFF, + 0x008B59, 0x008B59, 0x000000, 0xFFFFFF, + 0x008B5D, 0x008B5E, 0x000000, 0xFFFFFF, + 0x008B60, 0x008B65, 0x000000, 0xFFFFFF, + 0x008B67, 0x008B6A, 0x000000, 0xFFFFFF, + 0x008B6D, 0x008B6E, 0x000000, 0xFFFFFF, + 0x008B73, 0x008B73, 0x000000, 0xFFFFFF, + 0x008B75, 0x008B76, 0x000000, 0xFFFFFF, + 0x008B78, 0x008B7C, 0x000000, 0xFFFFFF, + 0x008B7E, 0x008B7F, 0x000000, 0xFFFFFF, + 0x008B81, 0x008B82, 0x000000, 0xFFFFFF, + 0x008B84, 0x008B89, 0x000000, 0xFFFFFF, + 0x008B8B, 0x008B8B, 0x000000, 0xFFFFFF, + 0x008B8D, 0x008B8D, 0x000000, 0xFFFFFF, + 0x008B8F, 0x008B8F, 0x000000, 0xFFFFFF, + 0x008B91, 0x008B91, 0x000000, 0xFFFFFF, + 0x008B94, 0x008B95, 0x000000, 0xFFFFFF, + 0x008B97, 0x008B98, 0x000000, 0xFFFFFF, + 0x008B9B, 0x008C36, 0x000000, 0xFFFFFF, + 0x008C38, 0x008C39, 0x000000, 0xFFFFFF, + 0x008C3B, 0x008C3E, 0x000000, 0xFFFFFF, + 0x008C40, 0x008C40, 0x000000, 0xFFFFFF, + 0x008C42, 0x008C45, 0x000000, 0xFFFFFF, + 0x008C47, 0x008C47, 0x000000, 0xFFFFFF, + 0x008C49, 0x008C49, 0x000000, 0xFFFFFF, + 0x008C4B, 0x008C4B, 0x000000, 0xFFFFFF, + 0x008C4D, 0x008C4D, 0x000000, 0xFFFFFF, + 0x008C4F, 0x008C4F, 0x000000, 0xFFFFFF, + 0x008C51, 0x008C54, 0x000000, 0xFFFFFF, + 0x008C56, 0x008C59, 0x000000, 0xFFFFFF, + 0x008C5B, 0x008C60, 0x000000, 0xFFFFFF, + 0x008C63, 0x008C69, 0x000000, 0xFFFFFF, + 0x008C6D, 0x008C77, 0x000000, 0xFFFFFF, + 0x008C7B, 0x008C7B, 0x000000, 0xFFFFFF, + 0x008C7D, 0x008C81, 0x000000, 0xFFFFFF, + 0x008C83, 0x008C84, 0x000000, 0xFFFFFF, + 0x008C86, 0x008C88, 0x000000, 0xFFFFFF, + 0x008C8B, 0x008C8B, 0x000000, 0xFFFFFF, + 0x008C8F, 0x008C93, 0x000000, 0xFFFFFF, + 0x008C95, 0x008C97, 0x000000, 0xFFFFFF, + 0x008C99, 0x008C9C, 0x000000, 0xFFFFFF, + 0x008C9F, 0x008C9F, 0x000000, 0xFFFFFF, + 0x008CA3, 0x008CA6, 0x000000, 0xFFFFFF, + 0x008CB1, 0x008CB1, 0x000000, 0xFFFFFF, + 0x008CB5, 0x008CB5, 0x000000, 0xFFFFFF, + 0x008CB9, 0x008CBA, 0x000000, 0xFFFFFF, + 0x008CBE, 0x008CBE, 0x000000, 0xFFFFFF, + 0x008CC5, 0x008CC6, 0x000000, 0xFFFFFF, + 0x008CC9, 0x008CC9, 0x000000, 0xFFFFFF, + 0x008CCB, 0x008CCC, 0x000000, 0xFFFFFF, + 0x008CCF, 0x008CD0, 0x000000, 0xFFFFFF, + 0x008CD2, 0x008CD2, 0x000000, 0xFFFFFF, + 0x008CD4, 0x008CD9, 0x000000, 0xFFFFFF, + 0x008CDD, 0x008CDD, 0x000000, 0xFFFFFF, + 0x008CDF, 0x008CDF, 0x000000, 0xFFFFFF, + 0x008CE1, 0x008CE1, 0x000000, 0xFFFFFF, + 0x008CE5, 0x008CE5, 0x000000, 0xFFFFFF, + 0x008CE7, 0x008CE9, 0x000000, 0xFFFFFF, + 0x008CEB, 0x008CEC, 0x000000, 0xFFFFFF, + 0x008CEE, 0x008CF9, 0x000000, 0xFFFFFF, + 0x008CFE, 0x008D03, 0x000000, 0xFFFFFF, + 0x008D06, 0x008D06, 0x000000, 0xFFFFFF, + 0x008D09, 0x008D09, 0x000000, 0xFFFFFF, + 0x008D0C, 0x008D0C, 0x000000, 0xFFFFFF, + 0x008D0E, 0x008D0E, 0x000000, 0xFFFFFF, + 0x008D11, 0x008D12, 0x000000, 0xFFFFFF, + 0x008D15, 0x008D15, 0x000000, 0xFFFFFF, + 0x008D17, 0x008D63, 0x000000, 0xFFFFFF, + 0x008D65, 0x008D65, 0x000000, 0xFFFFFF, + 0x008D68, 0x008D6A, 0x000000, 0xFFFFFF, + 0x008D6C, 0x008D6C, 0x000000, 0xFFFFFF, + 0x008D6E, 0x008D6F, 0x000000, 0xFFFFFF, + 0x008D72, 0x008D72, 0x000000, 0xFFFFFF, + 0x008D75, 0x008D76, 0x000000, 0xFFFFFF, + 0x008D78, 0x008D80, 0x000000, 0xFFFFFF, + 0x008D82, 0x008D84, 0x000000, 0xFFFFFF, + 0x008D86, 0x008D89, 0x000000, 0xFFFFFF, + 0x008D8B, 0x008D98, 0x000000, 0xFFFFFF, + 0x008D9A, 0x008DA2, 0x000000, 0xFFFFFF, + 0x008DA4, 0x008DA7, 0x000000, 0xFFFFFF, + 0x008DA9, 0x008DB2, 0x000000, 0xFFFFFF, + 0x008DB4, 0x008DB9, 0x000000, 0xFFFFFF, + 0x008DBB, 0x008DBD, 0x000000, 0xFFFFFF, + 0x008DBF, 0x008DC1, 0x000000, 0xFFFFFF, + 0x008DC3, 0x008DCA, 0x000000, 0xFFFFFF, + 0x008DCD, 0x008DCE, 0x000000, 0xFFFFFF, + 0x008DD0, 0x008DD5, 0x000000, 0xFFFFFF, + 0x008DD7, 0x008DD9, 0x000000, 0xFFFFFF, + 0x008DDC, 0x008DDC, 0x000000, 0xFFFFFF, + 0x008DDE, 0x008DDE, 0x000000, 0xFFFFFF, + 0x008DE0, 0x008DE0, 0x000000, 0xFFFFFF, + 0x008DE2, 0x008DE2, 0x000000, 0xFFFFFF, + 0x008DE4, 0x008DE7, 0x000000, 0xFFFFFF, + 0x008DE9, 0x008DE9, 0x000000, 0xFFFFFF, + 0x008DEC, 0x008DEE, 0x000000, 0xFFFFFF, + 0x008DF0, 0x008DF2, 0x000000, 0xFFFFFF, + 0x008DF4, 0x008DF4, 0x000000, 0xFFFFFF, + 0x008DF6, 0x008DFB, 0x000000, 0xFFFFFF, + 0x008DFD, 0x008DFE, 0x000000, 0xFFFFFF, + 0x008E00, 0x008E07, 0x000000, 0xFFFFFF, + 0x008E0B, 0x008E0E, 0x000000, 0xFFFFFF, + 0x008E11, 0x008E1C, 0x000000, 0xFFFFFF, + 0x008E20, 0x008E29, 0x000000, 0xFFFFFF, + 0x008E2B, 0x008E2F, 0x000000, 0xFFFFFF, + 0x008E31, 0x008E33, 0x000000, 0xFFFFFF, + 0x008E36, 0x008E41, 0x000000, 0xFFFFFF, + 0x008E43, 0x008E43, 0x000000, 0xFFFFFF, + 0x008E45, 0x008E46, 0x000000, 0xFFFFFF, + 0x008E4B, 0x008E4B, 0x000000, 0xFFFFFF, + 0x008E4D, 0x008E4F, 0x000000, 0xFFFFFF, + 0x008E51, 0x008E54, 0x000000, 0xFFFFFF, + 0x008E56, 0x008E58, 0x000000, 0xFFFFFF, + 0x008E5A, 0x008E5E, 0x000000, 0xFFFFFF, + 0x008E61, 0x008E62, 0x000000, 0xFFFFFF, + 0x008E65, 0x008E71, 0x000000, 0xFFFFFF, + 0x008E73, 0x008E73, 0x000000, 0xFFFFFF, + 0x008E75, 0x008E75, 0x000000, 0xFFFFFF, + 0x008E77, 0x008E7B, 0x000000, 0xFFFFFF, + 0x008E7D, 0x008E80, 0x000000, 0xFFFFFF, + 0x008E82, 0x008E83, 0x000000, 0xFFFFFF, + 0x008E86, 0x008E86, 0x000000, 0xFFFFFF, + 0x008E88, 0x008E89, 0x000000, 0xFFFFFF, + 0x008E8C, 0x008E8C, 0x000000, 0xFFFFFF, + 0x008E8E, 0x008E90, 0x000000, 0xFFFFFF, + 0x008E92, 0x008E92, 0x000000, 0xFFFFFF, + 0x008E95, 0x008E98, 0x000000, 0xFFFFFF, + 0x008E9A, 0x008EA0, 0x000000, 0xFFFFFF, + 0x008EA2, 0x008EA9, 0x000000, 0xFFFFFF, + 0x008EAD, 0x008EAE, 0x000000, 0xFFFFFF, + 0x008EB2, 0x008EBD, 0x000000, 0xFFFFFF, + 0x008EBF, 0x008EC4, 0x000000, 0xFFFFFF, + 0x008EC7, 0x008EC7, 0x000000, 0xFFFFFF, + 0x008EC9, 0x008EC9, 0x000000, 0xFFFFFF, + 0x008ECE, 0x008ED1, 0x000000, 0xFFFFFF, + 0x008ED3, 0x008EDA, 0x000000, 0xFFFFFF, + 0x008EDC, 0x008EDE, 0x000000, 0xFFFFFF, + 0x008EE0, 0x008EE1, 0x000000, 0xFFFFFF, + 0x008EE4, 0x008EEA, 0x000000, 0xFFFFFF, + 0x008EEC, 0x008EF7, 0x000000, 0xFFFFFF, + 0x008EF9, 0x008EFA, 0x000000, 0xFFFFFF, + 0x008EFF, 0x008F02, 0x000000, 0xFFFFFF, + 0x008F04, 0x008F04, 0x000000, 0xFFFFFF, + 0x008F06, 0x008F08, 0x000000, 0xFFFFFF, + 0x008F0B, 0x008F0B, 0x000000, 0xFFFFFF, + 0x008F0D, 0x008F11, 0x000000, 0xFFFFFF, + 0x008F16, 0x008F18, 0x000000, 0xFFFFFF, + 0x008F1A, 0x008F1A, 0x000000, 0xFFFFFF, + 0x008F1E, 0x008F1E, 0x000000, 0xFFFFFF, + 0x008F20, 0x008F25, 0x000000, 0xFFFFFF, + 0x008F27, 0x008F28, 0x000000, 0xFFFFFF, + 0x008F2B, 0x008F2E, 0x000000, 0xFFFFFF, + 0x008F30, 0x008F32, 0x000000, 0xFFFFFF, + 0x008F34, 0x008F37, 0x000000, 0xFFFFFF, + 0x008F3A, 0x008F3A, 0x000000, 0xFFFFFF, + 0x008F3C, 0x008F3D, 0x000000, 0xFFFFFF, + 0x008F40, 0x008F41, 0x000000, 0xFFFFFF, + 0x008F43, 0x008F43, 0x000000, 0xFFFFFF, + 0x008F47, 0x008F48, 0x000000, 0xFFFFFF, + 0x008F4A, 0x008F4B, 0x000000, 0xFFFFFF, + 0x008F4F, 0x008F56, 0x000000, 0xFFFFFF, + 0x008F58, 0x008F5B, 0x000000, 0xFFFFFF, + 0x008F5D, 0x008F5E, 0x000000, 0xFFFFFF, + 0x008F60, 0x008F60, 0x000000, 0xFFFFFF, + 0x008F65, 0x008F9A, 0x000000, 0xFFFFFF, + 0x008F9D, 0x008F9D, 0x000000, 0xFFFFFF, + 0x008FA0, 0x008FA2, 0x000000, 0xFFFFFF, + 0x008FA4, 0x008FA6, 0x000000, 0xFFFFFF, + 0x008FA9, 0x008FAC, 0x000000, 0xFFFFFF, + 0x008FB3, 0x008FB6, 0x000000, 0xFFFFFF, + 0x008FB8, 0x008FB9, 0x000000, 0xFFFFFF, + 0x008FBD, 0x008FBE, 0x000000, 0xFFFFFF, + 0x008FC0, 0x008FC1, 0x000000, 0xFFFFFF, + 0x008FC3, 0x008FC3, 0x000000, 0xFFFFFF, + 0x008FC6, 0x008FCD, 0x000000, 0xFFFFFF, + 0x008FCF, 0x008FD0, 0x000000, 0xFFFFFF, + 0x008FD2, 0x008FD3, 0x000000, 0xFFFFFF, + 0x008FD5, 0x008FD9, 0x000000, 0xFFFFFF, + 0x008FDB, 0x008FE1, 0x000000, 0xFFFFFF, + 0x008FE3, 0x008FE4, 0x000000, 0xFFFFFF, + 0x008FE7, 0x008FE8, 0x000000, 0xFFFFFF, + 0x008FEC, 0x008FEC, 0x000000, 0xFFFFFF, + 0x008FEE, 0x008FEE, 0x000000, 0xFFFFFF, + 0x008FF1, 0x008FF3, 0x000000, 0xFFFFFF, + 0x008FF5, 0x008FF6, 0x000000, 0xFFFFFF, + 0x008FFB, 0x008FFC, 0x000000, 0xFFFFFF, + 0x008FFE, 0x008FFF, 0x000000, 0xFFFFFF, + 0x009002, 0x009002, 0x000000, 0xFFFFFF, + 0x009004, 0x009004, 0x000000, 0xFFFFFF, + 0x009007, 0x00900A, 0x000000, 0xFFFFFF, + 0x00900C, 0x00900C, 0x000000, 0xFFFFFF, + 0x009012, 0x009012, 0x000000, 0xFFFFFF, + 0x009018, 0x009018, 0x000000, 0xFFFFFF, + 0x00901B, 0x00901C, 0x000000, 0xFFFFFF, + 0x009024, 0x009026, 0x000000, 0xFFFFFF, + 0x009028, 0x00902D, 0x000000, 0xFFFFFF, + 0x00902F, 0x009030, 0x000000, 0xFFFFFF, + 0x009033, 0x009034, 0x000000, 0xFFFFFF, + 0x009037, 0x009037, 0x000000, 0xFFFFFF, + 0x00903A, 0x00903B, 0x000000, 0xFFFFFF, + 0x00903D, 0x00903D, 0x000000, 0xFFFFFF, + 0x00903F, 0x009040, 0x000000, 0xFFFFFF, + 0x009043, 0x009044, 0x000000, 0xFFFFFF, + 0x009046, 0x009046, 0x000000, 0xFFFFFF, + 0x009048, 0x009048, 0x000000, 0xFFFFFF, + 0x00904C, 0x00904C, 0x000000, 0xFFFFFF, + 0x009057, 0x009057, 0x000000, 0xFFFFFF, + 0x00905A, 0x00905B, 0x000000, 0xFFFFFF, + 0x00905D, 0x00905D, 0x000000, 0xFFFFFF, + 0x00905F, 0x00905F, 0x000000, 0xFFFFFF, + 0x009062, 0x009062, 0x000000, 0xFFFFFF, + 0x009064, 0x009064, 0x000000, 0xFFFFFF, + 0x009066, 0x009067, 0x000000, 0xFFFFFF, + 0x00906A, 0x00906C, 0x000000, 0xFFFFFF, + 0x009070, 0x009071, 0x000000, 0xFFFFFF, + 0x009073, 0x009074, 0x000000, 0xFFFFFF, + 0x009079, 0x009079, 0x000000, 0xFFFFFF, + 0x00907B, 0x00907B, 0x000000, 0xFFFFFF, + 0x00907E, 0x00907E, 0x000000, 0xFFFFFF, + 0x009085, 0x009086, 0x000000, 0xFFFFFF, + 0x009088, 0x009088, 0x000000, 0xFFFFFF, + 0x00908B, 0x00908E, 0x000000, 0xFFFFFF, + 0x009090, 0x009090, 0x000000, 0xFFFFFF, + 0x009092, 0x0090A2, 0x000000, 0xFFFFFF, + 0x0090A4, 0x0090A5, 0x000000, 0xFFFFFF, + 0x0090A7, 0x0090A7, 0x000000, 0xFFFFFF, + 0x0090A9, 0x0090A9, 0x000000, 0xFFFFFF, + 0x0090AB, 0x0090AE, 0x000000, 0xFFFFFF, + 0x0090B0, 0x0090B0, 0x000000, 0xFFFFFF, + 0x0090B2, 0x0090B4, 0x000000, 0xFFFFFF, + 0x0090B6, 0x0090B7, 0x000000, 0xFFFFFF, + 0x0090B9, 0x0090C0, 0x000000, 0xFFFFFF, + 0x0090C2, 0x0090C9, 0x000000, 0xFFFFFF, + 0x0090CB, 0x0090CD, 0x000000, 0xFFFFFF, + 0x0090CF, 0x0090DA, 0x000000, 0xFFFFFF, + 0x0090DC, 0x0090E0, 0x000000, 0xFFFFFF, + 0x0090E3, 0x0090E3, 0x000000, 0xFFFFFF, + 0x0090E5, 0x0090E7, 0x000000, 0xFFFFFF, + 0x0090E9, 0x0090EC, 0x000000, 0xFFFFFF, + 0x0090EE, 0x0090F4, 0x000000, 0xFFFFFF, + 0x0090F6, 0x0090F6, 0x000000, 0xFFFFFF, + 0x0090F8, 0x0090FC, 0x000000, 0xFFFFFF, + 0x0090FE, 0x009101, 0x000000, 0xFFFFFF, + 0x009103, 0x009111, 0x000000, 0xFFFFFF, + 0x009113, 0x009118, 0x000000, 0xFFFFFF, + 0x00911A, 0x00912C, 0x000000, 0xFFFFFF, + 0x00912E, 0x00912F, 0x000000, 0xFFFFFF, + 0x009131, 0x009131, 0x000000, 0xFFFFFF, + 0x009133, 0x009148, 0x000000, 0xFFFFFF, + 0x00914F, 0x009151, 0x000000, 0xFFFFFF, + 0x009153, 0x009153, 0x000000, 0xFFFFFF, + 0x009155, 0x009155, 0x000000, 0xFFFFFF, + 0x009157, 0x009157, 0x000000, 0xFFFFFF, + 0x009159, 0x009161, 0x000000, 0xFFFFFF, + 0x009164, 0x009164, 0x000000, 0xFFFFFF, + 0x009166, 0x009168, 0x000000, 0xFFFFFF, + 0x00916B, 0x00916B, 0x000000, 0xFFFFFF, + 0x00916D, 0x009171, 0x000000, 0xFFFFFF, + 0x009174, 0x009174, 0x000000, 0xFFFFFF, + 0x009176, 0x009176, 0x000000, 0xFFFFFF, + 0x009179, 0x009181, 0x000000, 0xFFFFFF, + 0x009183, 0x009186, 0x000000, 0xFFFFFF, + 0x009188, 0x009188, 0x000000, 0xFFFFFF, + 0x00918A, 0x00918A, 0x000000, 0xFFFFFF, + 0x00918C, 0x00918C, 0x000000, 0xFFFFFF, + 0x00918E, 0x00918F, 0x000000, 0xFFFFFF, + 0x009191, 0x009191, 0x000000, 0xFFFFFF, + 0x009193, 0x009196, 0x000000, 0xFFFFFF, + 0x009198, 0x00919B, 0x000000, 0xFFFFFF, + 0x00919D, 0x0091A1, 0x000000, 0xFFFFFF, + 0x0091A3, 0x0091A3, 0x000000, 0xFFFFFF, + 0x0091A5, 0x0091A9, 0x000000, 0xFFFFFF, + 0x0091AC, 0x0091AE, 0x000000, 0xFFFFFF, + 0x0091B0, 0x0091B3, 0x000000, 0xFFFFFF, + 0x0091B6, 0x0091B7, 0x000000, 0xFFFFFF, + 0x0091B9, 0x0091B9, 0x000000, 0xFFFFFF, + 0x0091BB, 0x0091BF, 0x000000, 0xFFFFFF, + 0x0091C2, 0x0091C5, 0x000000, 0xFFFFFF, + 0x0091CA, 0x0091CA, 0x000000, 0xFFFFFF, + 0x0091D2, 0x0091D5, 0x000000, 0xFFFFFF, + 0x0091D7, 0x0091D7, 0x000000, 0xFFFFFF, + 0x0091D9, 0x0091DA, 0x000000, 0xFFFFFF, + 0x0091DE, 0x0091DE, 0x000000, 0xFFFFFF, + 0x0091E0, 0x0091E0, 0x000000, 0xFFFFFF, + 0x0091E2, 0x0091E2, 0x000000, 0xFFFFFF, + 0x0091E4, 0x0091E5, 0x000000, 0xFFFFFF, + 0x0091E8, 0x0091F4, 0x000000, 0xFFFFFF, + 0x0091F7, 0x0091FB, 0x000000, 0xFFFFFF, + 0x0091FD, 0x0091FE, 0x000000, 0xFFFFFF, + 0x009200, 0x00920C, 0x000000, 0xFFFFFF, + 0x00920F, 0x009210, 0x000000, 0xFFFFFF, + 0x009212, 0x009213, 0x000000, 0xFFFFFF, + 0x009216, 0x00921D, 0x000000, 0xFFFFFF, + 0x00921F, 0x009228, 0x000000, 0xFFFFFF, + 0x00922A, 0x00922B, 0x000000, 0xFFFFFF, + 0x00922D, 0x009233, 0x000000, 0xFFFFFF, + 0x009235, 0x009236, 0x000000, 0xFFFFFF, + 0x009238, 0x00923E, 0x000000, 0xFFFFFF, + 0x009240, 0x009243, 0x000000, 0xFFFFFF, + 0x009246, 0x009247, 0x000000, 0xFFFFFF, + 0x00924A, 0x00924A, 0x000000, 0xFFFFFF, + 0x00924C, 0x00924F, 0x000000, 0xFFFFFF, + 0x009251, 0x009256, 0x000000, 0xFFFFFF, + 0x009258, 0x009259, 0x000000, 0xFFFFFF, + 0x00925C, 0x00925D, 0x000000, 0xFFFFFF, + 0x00925F, 0x009261, 0x000000, 0xFFFFFF, + 0x009263, 0x009263, 0x000000, 0xFFFFFF, + 0x009265, 0x009265, 0x000000, 0xFFFFFF, + 0x009267, 0x009270, 0x000000, 0xFFFFFF, + 0x009272, 0x00927D, 0x000000, 0xFFFFFF, + 0x00927F, 0x00927F, 0x000000, 0xFFFFFF, + 0x009281, 0x009282, 0x000000, 0xFFFFFF, + 0x009284, 0x009284, 0x000000, 0xFFFFFF, + 0x009286, 0x009290, 0x000000, 0xFFFFFF, + 0x009292, 0x009292, 0x000000, 0xFFFFFF, + 0x009294, 0x009294, 0x000000, 0xFFFFFF, + 0x009297, 0x009297, 0x000000, 0xFFFFFF, + 0x009299, 0x009299, 0x000000, 0xFFFFFF, + 0x00929D, 0x0092AC, 0x000000, 0xFFFFFF, + 0x0092AE, 0x0092B6, 0x000000, 0xFFFFFF, + 0x0092B8, 0x0092B8, 0x000000, 0xFFFFFF, + 0x0092BA, 0x0092CE, 0x000000, 0xFFFFFF, + 0x0092D0, 0x0092D1, 0x000000, 0xFFFFFF, + 0x0092D3, 0x0092E3, 0x000000, 0xFFFFFF, + 0x0092E5, 0x0092E8, 0x000000, 0xFFFFFF, + 0x0092EB, 0x0092EC, 0x000000, 0xFFFFFF, + 0x0092EE, 0x0092F1, 0x000000, 0xFFFFFF, + 0x0092F4, 0x0092F7, 0x000000, 0xFFFFFF, + 0x0092F9, 0x0092F9, 0x000000, 0xFFFFFF, + 0x0092FB, 0x0092FB, 0x000000, 0xFFFFFF, + 0x0092FD, 0x009305, 0x000000, 0xFFFFFF, + 0x009307, 0x00930E, 0x000000, 0xFFFFFF, + 0x009311, 0x009317, 0x000000, 0xFFFFFF, + 0x00931B, 0x00931F, 0x000000, 0xFFFFFF, + 0x009321, 0x009321, 0x000000, 0xFFFFFF, + 0x009324, 0x009325, 0x000000, 0xFFFFFF, + 0x009327, 0x009327, 0x000000, 0xFFFFFF, + 0x009329, 0x00932A, 0x000000, 0xFFFFFF, + 0x00932D, 0x00932D, 0x000000, 0xFFFFFF, + 0x009330, 0x009331, 0x000000, 0xFFFFFF, + 0x009333, 0x009334, 0x000000, 0xFFFFFF, + 0x009336, 0x009339, 0x000000, 0xFFFFFF, + 0x00933C, 0x009343, 0x000000, 0xFFFFFF, + 0x009345, 0x00934A, 0x000000, 0xFFFFFF, + 0x00934C, 0x00934C, 0x000000, 0xFFFFFF, + 0x00934E, 0x009353, 0x000000, 0xFFFFFF, + 0x009355, 0x009355, 0x000000, 0xFFFFFF, + 0x009357, 0x00935A, 0x000000, 0xFFFFFF, + 0x00935D, 0x00935F, 0x000000, 0xFFFFFF, + 0x009361, 0x00936B, 0x000000, 0xFFFFFF, + 0x00936D, 0x00936D, 0x000000, 0xFFFFFF, + 0x00936F, 0x009374, 0x000000, 0xFFFFFF, + 0x009376, 0x00937B, 0x000000, 0xFFFFFF, + 0x00937D, 0x00937D, 0x000000, 0xFFFFFF, + 0x00937F, 0x00938B, 0x000000, 0xFFFFFF, + 0x00938D, 0x009393, 0x000000, 0xFFFFFF, + 0x009395, 0x009395, 0x000000, 0xFFFFFF, + 0x009398, 0x009399, 0x000000, 0xFFFFFF, + 0x00939B, 0x0093A6, 0x000000, 0xFFFFFF, + 0x0093A8, 0x0093AB, 0x000000, 0xFFFFFF, + 0x0093AF, 0x0093AF, 0x000000, 0xFFFFFF, + 0x0093B1, 0x0093B8, 0x000000, 0xFFFFFF, + 0x0093BA, 0x0093C2, 0x000000, 0xFFFFFF, + 0x0093C4, 0x0093C7, 0x000000, 0xFFFFFF, + 0x0093C9, 0x0093CF, 0x000000, 0xFFFFFF, + 0x0093D2, 0x0093D5, 0x000000, 0xFFFFFF, + 0x0093D9, 0x0093DC, 0x000000, 0xFFFFFF, + 0x0093DE, 0x0093E0, 0x000000, 0xFFFFFF, + 0x0093E2, 0x0093E3, 0x000000, 0xFFFFFF, + 0x0093E6, 0x0093E7, 0x000000, 0xFFFFFF, + 0x0093E9, 0x009402, 0x000000, 0xFFFFFF, + 0x009404, 0x009406, 0x000000, 0xFFFFFF, + 0x009408, 0x00940F, 0x000000, 0xFFFFFF, + 0x009411, 0x009412, 0x000000, 0xFFFFFF, + 0x009415, 0x009417, 0x000000, 0xFFFFFF, + 0x00941B, 0x009420, 0x000000, 0xFFFFFF, + 0x009422, 0x00942A, 0x000000, 0xFFFFFF, + 0x00942C, 0x009434, 0x000000, 0xFFFFFF, + 0x009437, 0x009437, 0x000000, 0xFFFFFF, + 0x009439, 0x009439, 0x000000, 0xFFFFFF, + 0x00943B, 0x009440, 0x000000, 0xFFFFFF, + 0x009442, 0x009443, 0x000000, 0xFFFFFF, + 0x009445, 0x009450, 0x000000, 0xFFFFFF, + 0x009454, 0x009459, 0x000000, 0xFFFFFF, + 0x00945C, 0x00945D, 0x000000, 0xFFFFFF, + 0x00945F, 0x00945F, 0x000000, 0xFFFFFF, + 0x009461, 0x009461, 0x000000, 0xFFFFFF, + 0x009463, 0x009469, 0x000000, 0xFFFFFF, + 0x00946B, 0x00946F, 0x000000, 0xFFFFFF, + 0x009471, 0x009474, 0x000000, 0xFFFFFF, + 0x009476, 0x009476, 0x000000, 0xFFFFFF, + 0x009478, 0x00947B, 0x000000, 0xFFFFFF, + 0x009480, 0x009480, 0x000000, 0xFFFFFF, + 0x009482, 0x009576, 0x000000, 0xFFFFFF, + 0x009578, 0x00957F, 0x000000, 0xFFFFFF, + 0x009581, 0x009581, 0x000000, 0xFFFFFF, + 0x009584, 0x009586, 0x000000, 0xFFFFFF, + 0x009588, 0x009588, 0x000000, 0xFFFFFF, + 0x00958C, 0x00958E, 0x000000, 0xFFFFFF, + 0x009590, 0x009590, 0x000000, 0xFFFFFF, + 0x009592, 0x009592, 0x000000, 0xFFFFFF, + 0x009595, 0x009595, 0x000000, 0xFFFFFF, + 0x009597, 0x009597, 0x000000, 0xFFFFFF, + 0x00959A, 0x00959F, 0x000000, 0xFFFFFF, + 0x0095A1, 0x0095A1, 0x000000, 0xFFFFFF, + 0x0095A6, 0x0095A6, 0x000000, 0xFFFFFF, + 0x0095A9, 0x0095AC, 0x000000, 0xFFFFFF, + 0x0095AE, 0x0095B1, 0x000000, 0xFFFFFF, + 0x0095B3, 0x0095B8, 0x000000, 0xFFFFFF, + 0x0095BA, 0x0095BA, 0x000000, 0xFFFFFF, + 0x0095BD, 0x0095BD, 0x000000, 0xFFFFFF, + 0x0095BF, 0x0095C2, 0x000000, 0xFFFFFF, + 0x0095C4, 0x0095C6, 0x000000, 0xFFFFFF, + 0x0095C8, 0x0095C9, 0x000000, 0xFFFFFF, + 0x0095CB, 0x0095CB, 0x000000, 0xFFFFFF, + 0x0095CE, 0x0095D3, 0x000000, 0xFFFFFF, + 0x0095D7, 0x0095D7, 0x000000, 0xFFFFFF, + 0x0095D9, 0x0095DB, 0x000000, 0xFFFFFF, + 0x0095DD, 0x0095E0, 0x000000, 0xFFFFFF, + 0x0095E3, 0x0095E4, 0x000000, 0xFFFFFF, + 0x0095E6, 0x00961B, 0x000000, 0xFFFFFF, + 0x00961D, 0x009620, 0x000000, 0xFFFFFF, + 0x009622, 0x009627, 0x000000, 0xFFFFFF, + 0x009629, 0x009629, 0x000000, 0xFFFFFF, + 0x00962B, 0x00962D, 0x000000, 0xFFFFFF, + 0x009630, 0x009631, 0x000000, 0xFFFFFF, + 0x009633, 0x00963A, 0x000000, 0xFFFFFF, + 0x00963C, 0x00963E, 0x000000, 0xFFFFFF, + 0x009641, 0x009641, 0x000000, 0xFFFFFF, + 0x009643, 0x009643, 0x000000, 0xFFFFFF, + 0x009645, 0x00964A, 0x000000, 0xFFFFFF, + 0x00964E, 0x00964E, 0x000000, 0xFFFFFF, + 0x009651, 0x00965A, 0x000000, 0xFFFFFF, + 0x009660, 0x009661, 0x000000, 0xFFFFFF, + 0x009667, 0x009669, 0x000000, 0xFFFFFF, + 0x00966B, 0x00966B, 0x000000, 0xFFFFFF, + 0x00966D, 0x00966F, 0x000000, 0xFFFFFF, + 0x009671, 0x009671, 0x000000, 0xFFFFFF, + 0x009674, 0x009674, 0x000000, 0xFFFFFF, + 0x009679, 0x009679, 0x000000, 0xFFFFFF, + 0x00967B, 0x00967C, 0x000000, 0xFFFFFF, + 0x00967E, 0x009684, 0x000000, 0xFFFFFF, + 0x009687, 0x009687, 0x000000, 0xFFFFFF, + 0x009689, 0x009689, 0x000000, 0xFFFFFF, + 0x00968C, 0x00968C, 0x000000, 0xFFFFFF, + 0x009690, 0x009693, 0x000000, 0xFFFFFF, + 0x009696, 0x009696, 0x000000, 0xFFFFFF, + 0x00969A, 0x00969A, 0x000000, 0xFFFFFF, + 0x00969D, 0x00969F, 0x000000, 0xFFFFFF, + 0x0096A1, 0x0096A2, 0x000000, 0xFFFFFF, + 0x0096A4, 0x0096A6, 0x000000, 0xFFFFFF, + 0x0096A9, 0x0096A9, 0x000000, 0xFFFFFF, + 0x0096AB, 0x0096AF, 0x000000, 0xFFFFFF, + 0x0096B3, 0x0096B3, 0x000000, 0xFFFFFF, + 0x0096B5, 0x0096B5, 0x000000, 0xFFFFFF, + 0x0096BA, 0x0096BA, 0x000000, 0xFFFFFF, + 0x0096BD, 0x0096BF, 0x000000, 0xFFFFFF, + 0x0096C2, 0x0096C3, 0x000000, 0xFFFFFF, + 0x0096C8, 0x0096C8, 0x000000, 0xFFFFFF, + 0x0096CA, 0x0096CA, 0x000000, 0xFFFFFF, + 0x0096CF, 0x0096D0, 0x000000, 0xFFFFFF, + 0x0096D2, 0x0096D4, 0x000000, 0xFFFFFF, + 0x0096D7, 0x0096D8, 0x000000, 0xFFFFFF, + 0x0096DA, 0x0096DA, 0x000000, 0xFFFFFF, + 0x0096DD, 0x0096E1, 0x000000, 0xFFFFFF, + 0x0096E4, 0x0096E7, 0x000000, 0xFFFFFF, + 0x0096E9, 0x0096E9, 0x000000, 0xFFFFFF, + 0x0096EC, 0x0096EF, 0x000000, 0xFFFFFF, + 0x0096F1, 0x0096F1, 0x000000, 0xFFFFFF, + 0x0096F3, 0x0096F5, 0x000000, 0xFFFFFF, + 0x0096F8, 0x0096F8, 0x000000, 0xFFFFFF, + 0x0096FA, 0x0096FA, 0x000000, 0xFFFFFF, + 0x0096FC, 0x0096FF, 0x000000, 0xFFFFFF, + 0x009701, 0x009703, 0x000000, 0xFFFFFF, + 0x009705, 0x009705, 0x000000, 0xFFFFFF, + 0x009709, 0x009709, 0x000000, 0xFFFFFF, + 0x00970B, 0x00970C, 0x000000, 0xFFFFFF, + 0x009710, 0x009710, 0x000000, 0xFFFFFF, + 0x009712, 0x009712, 0x000000, 0xFFFFFF, + 0x009714, 0x009715, 0x000000, 0xFFFFFF, + 0x009717, 0x009718, 0x000000, 0xFFFFFF, + 0x00971A, 0x00971B, 0x000000, 0xFFFFFF, + 0x00971D, 0x00971D, 0x000000, 0xFFFFFF, + 0x00971F, 0x009723, 0x000000, 0xFFFFFF, + 0x009725, 0x009726, 0x000000, 0xFFFFFF, + 0x009728, 0x009729, 0x000000, 0xFFFFFF, + 0x00972B, 0x00972F, 0x000000, 0xFFFFFF, + 0x009731, 0x009731, 0x000000, 0xFFFFFF, + 0x009733, 0x009737, 0x000000, 0xFFFFFF, + 0x00973A, 0x00973C, 0x000000, 0xFFFFFF, + 0x00973F, 0x009741, 0x000000, 0xFFFFFF, + 0x009743, 0x009743, 0x000000, 0xFFFFFF, + 0x009745, 0x009745, 0x000000, 0xFFFFFF, + 0x009747, 0x009747, 0x000000, 0xFFFFFF, + 0x00974A, 0x009751, 0x000000, 0xFFFFFF, + 0x009753, 0x009755, 0x000000, 0xFFFFFF, + 0x009757, 0x009758, 0x000000, 0xFFFFFF, + 0x00975A, 0x00975B, 0x000000, 0xFFFFFF, + 0x00975D, 0x00975D, 0x000000, 0xFFFFFF, + 0x00975F, 0x00975F, 0x000000, 0xFFFFFF, + 0x009763, 0x009763, 0x000000, 0xFFFFFF, + 0x009765, 0x009765, 0x000000, 0xFFFFFF, + 0x009767, 0x009767, 0x000000, 0xFFFFFF, + 0x00976A, 0x00976A, 0x000000, 0xFFFFFF, + 0x00976C, 0x00976C, 0x000000, 0xFFFFFF, + 0x00976E, 0x009770, 0x000000, 0xFFFFFF, + 0x009772, 0x009773, 0x000000, 0xFFFFFF, + 0x009775, 0x009778, 0x000000, 0xFFFFFF, + 0x00977B, 0x00977B, 0x000000, 0xFFFFFF, + 0x00977D, 0x009780, 0x000000, 0xFFFFFF, + 0x009782, 0x009783, 0x000000, 0xFFFFFF, + 0x009787, 0x00978A, 0x000000, 0xFFFFFF, + 0x00978C, 0x00978C, 0x000000, 0xFFFFFF, + 0x00978E, 0x00978E, 0x000000, 0xFFFFFF, + 0x009791, 0x009797, 0x000000, 0xFFFFFF, + 0x009799, 0x00979B, 0x000000, 0xFFFFFF, + 0x00979D, 0x00979F, 0x000000, 0xFFFFFF, + 0x0097A1, 0x0097A2, 0x000000, 0xFFFFFF, + 0x0097A4, 0x0097A5, 0x000000, 0xFFFFFF, + 0x0097A7, 0x0097A7, 0x000000, 0xFFFFFF, + 0x0097A9, 0x0097AA, 0x000000, 0xFFFFFF, + 0x0097AC, 0x0097AC, 0x000000, 0xFFFFFF, + 0x0097AE, 0x0097B2, 0x000000, 0xFFFFFF, + 0x0097B5, 0x0097C2, 0x000000, 0xFFFFFF, + 0x0097C4, 0x0097C5, 0x000000, 0xFFFFFF, + 0x0097C7, 0x0097C7, 0x000000, 0xFFFFFF, + 0x0097C9, 0x0097CA, 0x000000, 0xFFFFFF, + 0x0097CC, 0x0097D2, 0x000000, 0xFFFFFF, + 0x0097D4, 0x0097DB, 0x000000, 0xFFFFFF, + 0x0097DD, 0x0097EC, 0x000000, 0xFFFFFF, + 0x0097EF, 0x0097F1, 0x000000, 0xFFFFFF, + 0x0097F4, 0x0097F4, 0x000000, 0xFFFFFF, + 0x0097F7, 0x0097FA, 0x000000, 0xFFFFFF, + 0x0097FC, 0x0097FE, 0x000000, 0xFFFFFF, + 0x009800, 0x009800, 0x000000, 0xFFFFFF, + 0x009804, 0x009804, 0x000000, 0xFFFFFF, + 0x009807, 0x009807, 0x000000, 0xFFFFFF, + 0x009809, 0x00980B, 0x000000, 0xFFFFFF, + 0x00980D, 0x00980E, 0x000000, 0xFFFFFF, + 0x009814, 0x009816, 0x000000, 0xFFFFFF, + 0x009819, 0x009819, 0x000000, 0xFFFFFF, + 0x00981B, 0x009820, 0x000000, 0xFFFFFF, + 0x009822, 0x009823, 0x000000, 0xFFFFFF, + 0x009825, 0x00982B, 0x000000, 0xFFFFFF, + 0x00982E, 0x009833, 0x000000, 0xFFFFFF, + 0x009835, 0x009836, 0x000000, 0xFFFFFF, + 0x009839, 0x00983A, 0x000000, 0xFFFFFF, + 0x00983E, 0x009845, 0x000000, 0xFFFFFF, + 0x009847, 0x00984A, 0x000000, 0xFFFFFF, + 0x009850, 0x009853, 0x000000, 0xFFFFFF, + 0x009856, 0x009857, 0x000000, 0xFFFFFF, + 0x009859, 0x00985A, 0x000000, 0xFFFFFF, + 0x00985C, 0x00985D, 0x000000, 0xFFFFFF, + 0x00985F, 0x009866, 0x000000, 0xFFFFFF, + 0x009868, 0x00986A, 0x000000, 0xFFFFFF, + 0x00986C, 0x00986E, 0x000000, 0xFFFFFF, + 0x009872, 0x009872, 0x000000, 0xFFFFFF, + 0x009875, 0x0098A7, 0x000000, 0xFFFFFF, + 0x0098A9, 0x0098A9, 0x000000, 0xFFFFFF, + 0x0098AB, 0x0098AE, 0x000000, 0xFFFFFF, + 0x0098B0, 0x0098B0, 0x000000, 0xFFFFFF, + 0x0098B2, 0x0098B5, 0x000000, 0xFFFFFF, + 0x0098B7, 0x0098C2, 0x000000, 0xFFFFFF, + 0x0098C5, 0x0098C5, 0x000000, 0xFFFFFF, + 0x0098C7, 0x0098DA, 0x000000, 0xFFFFFF, + 0x0098DD, 0x0098DE, 0x000000, 0xFFFFFF, + 0x0098E0, 0x0098E1, 0x000000, 0xFFFFFF, + 0x0098E3, 0x0098E8, 0x000000, 0xFFFFFF, + 0x0098EA, 0x0098EA, 0x000000, 0xFFFFFF, + 0x0098EC, 0x0098EC, 0x000000, 0xFFFFFF, + 0x0098F0, 0x0098F1, 0x000000, 0xFFFFFF, + 0x0098F3, 0x0098F3, 0x000000, 0xFFFFFF, + 0x0098F5, 0x0098FB, 0x000000, 0xFFFFFF, + 0x0098FF, 0x009902, 0x000000, 0xFFFFFF, + 0x009904, 0x009904, 0x000000, 0xFFFFFF, + 0x009906, 0x009908, 0x000000, 0xFFFFFF, + 0x00990B, 0x00990B, 0x000000, 0xFFFFFF, + 0x00990D, 0x00990F, 0x000000, 0xFFFFFF, + 0x009911, 0x009911, 0x000000, 0xFFFFFF, + 0x009915, 0x009917, 0x000000, 0xFFFFFF, + 0x009919, 0x00991C, 0x000000, 0xFFFFFF, + 0x00991F, 0x00991F, 0x000000, 0xFFFFFF, + 0x009922, 0x009923, 0x000000, 0xFFFFFF, + 0x009925, 0x009927, 0x000000, 0xFFFFFF, + 0x009929, 0x00992B, 0x000000, 0xFFFFFF, + 0x00992D, 0x00992D, 0x000000, 0xFFFFFF, + 0x00992F, 0x00993C, 0x000000, 0xFFFFFF, + 0x00993F, 0x009941, 0x000000, 0xFFFFFF, + 0x009943, 0x009944, 0x000000, 0xFFFFFF, + 0x009946, 0x009948, 0x000000, 0xFFFFFF, + 0x00994A, 0x00994A, 0x000000, 0xFFFFFF, + 0x00994D, 0x00994F, 0x000000, 0xFFFFFF, + 0x009953, 0x009954, 0x000000, 0xFFFFFF, + 0x009956, 0x009956, 0x000000, 0xFFFFFF, + 0x009958, 0x009995, 0x000000, 0xFFFFFF, + 0x00999A, 0x0099A4, 0x000000, 0xFFFFFF, + 0x0099A6, 0x0099A7, 0x000000, 0xFFFFFF, + 0x0099A9, 0x0099AB, 0x000000, 0xFFFFFF, + 0x0099AF, 0x0099B2, 0x000000, 0xFFFFFF, + 0x0099B5, 0x0099BB, 0x000000, 0xFFFFFF, + 0x0099BD, 0x0099C0, 0x000000, 0xFFFFFF, + 0x0099C2, 0x0099C3, 0x000000, 0xFFFFFF, + 0x0099C7, 0x0099C7, 0x000000, 0xFFFFFF, + 0x0099C9, 0x0099CF, 0x000000, 0xFFFFFF, + 0x0099D3, 0x0099D4, 0x000000, 0xFFFFFF, + 0x0099D6, 0x0099D7, 0x000000, 0xFFFFFF, + 0x0099D9, 0x0099DA, 0x000000, 0xFFFFFF, + 0x0099DC, 0x0099DC, 0x000000, 0xFFFFFF, + 0x0099DE, 0x0099DE, 0x000000, 0xFFFFFF, + 0x0099E0, 0x0099E1, 0x000000, 0xFFFFFF, + 0x0099E3, 0x0099EC, 0x000000, 0xFFFFFF, + 0x0099EF, 0x0099F0, 0x000000, 0xFFFFFF, + 0x0099F3, 0x0099F7, 0x000000, 0xFFFFFF, + 0x0099F9, 0x0099FA, 0x000000, 0xFFFFFF, + 0x0099FC, 0x0099FE, 0x000000, 0xFFFFFF, + 0x009A00, 0x009A00, 0x000000, 0xFFFFFF, + 0x009A02, 0x009A04, 0x000000, 0xFFFFFF, + 0x009A06, 0x009A0D, 0x000000, 0xFFFFFF, + 0x009A10, 0x009A11, 0x000000, 0xFFFFFF, + 0x009A14, 0x009A18, 0x000000, 0xFFFFFF, + 0x009A1A, 0x009A27, 0x000000, 0xFFFFFF, + 0x009A29, 0x009A2A, 0x000000, 0xFFFFFF, + 0x009A2C, 0x009A2F, 0x000000, 0xFFFFFF, + 0x009A31, 0x009A36, 0x000000, 0xFFFFFF, + 0x009A38, 0x009A3D, 0x000000, 0xFFFFFF, + 0x009A3F, 0x009A3F, 0x000000, 0xFFFFFF, + 0x009A41, 0x009A41, 0x000000, 0xFFFFFF, + 0x009A44, 0x009A44, 0x000000, 0xFFFFFF, + 0x009A46, 0x009A4C, 0x000000, 0xFFFFFF, + 0x009A4E, 0x009A54, 0x000000, 0xFFFFFF, + 0x009A56, 0x009A56, 0x000000, 0xFFFFFF, + 0x009A58, 0x009A59, 0x000000, 0xFFFFFF, + 0x009A5C, 0x009A5E, 0x000000, 0xFFFFFF, + 0x009A60, 0x009A61, 0x000000, 0xFFFFFF, + 0x009A63, 0x009A63, 0x000000, 0xFFFFFF, + 0x009A66, 0x009A68, 0x000000, 0xFFFFFF, + 0x009A6C, 0x009AA7, 0x000000, 0xFFFFFF, + 0x009AA9, 0x009AAC, 0x000000, 0xFFFFFF, + 0x009AAE, 0x009AAF, 0x000000, 0xFFFFFF, + 0x009AB1, 0x009AB7, 0x000000, 0xFFFFFF, + 0x009AB9, 0x009ABB, 0x000000, 0xFFFFFF, + 0x009ABD, 0x009ABF, 0x000000, 0xFFFFFF, + 0x009AC1, 0x009AC3, 0x000000, 0xFFFFFF, + 0x009AC5, 0x009ACE, 0x000000, 0xFFFFFF, + 0x009AD0, 0x009AD0, 0x000000, 0xFFFFFF, + 0x009AD2, 0x009AD2, 0x000000, 0xFFFFFF, + 0x009AD5, 0x009AD7, 0x000000, 0xFFFFFF, + 0x009AD9, 0x009ADD, 0x000000, 0xFFFFFF, + 0x009AE0, 0x009AE1, 0x000000, 0xFFFFFF, + 0x009AE4, 0x009AE5, 0x000000, 0xFFFFFF, + 0x009AE7, 0x009AE9, 0x000000, 0xFFFFFF, + 0x009AEC, 0x009AEC, 0x000000, 0xFFFFFF, + 0x009AF0, 0x009AF0, 0x000000, 0xFFFFFF, + 0x009AF2, 0x009AF3, 0x000000, 0xFFFFFF, + 0x009AF5, 0x009AF6, 0x000000, 0xFFFFFF, + 0x009AF8, 0x009AFA, 0x000000, 0xFFFFFF, + 0x009AFC, 0x009B05, 0x000000, 0xFFFFFF, + 0x009B07, 0x009B17, 0x000000, 0xFFFFFF, + 0x009B19, 0x009B19, 0x000000, 0xFFFFFF, + 0x009B1B, 0x009B1E, 0x000000, 0xFFFFFF, + 0x009B20, 0x009B21, 0x000000, 0xFFFFFF, + 0x009B24, 0x009B24, 0x000000, 0xFFFFFF, + 0x009B26, 0x009B26, 0x000000, 0xFFFFFF, + 0x009B2B, 0x009B2D, 0x000000, 0xFFFFFF, + 0x009B30, 0x009B30, 0x000000, 0xFFFFFF, + 0x009B33, 0x009B3A, 0x000000, 0xFFFFFF, + 0x009B3D, 0x009B40, 0x000000, 0xFFFFFF, + 0x009B46, 0x009B4C, 0x000000, 0xFFFFFF, + 0x009B50, 0x009B50, 0x000000, 0xFFFFFF, + 0x009B52, 0x009B53, 0x000000, 0xFFFFFF, + 0x009B55, 0x009B57, 0x000000, 0xFFFFFF, + 0x009B59, 0x009B59, 0x000000, 0xFFFFFF, + 0x009B5B, 0x009B6E, 0x000000, 0xFFFFFF, + 0x009B70, 0x009B73, 0x000000, 0xFFFFFF, + 0x009B75, 0x009B82, 0x000000, 0xFFFFFF, + 0x009B84, 0x009B8D, 0x000000, 0xFFFFFF, + 0x009B8F, 0x009B90, 0x000000, 0xFFFFFF, + 0x009B94, 0x009B95, 0x000000, 0xFFFFFF, + 0x009B98, 0x009B9E, 0x000000, 0xFFFFFF, + 0x009BA1, 0x009BA7, 0x000000, 0xFFFFFF, + 0x009BA9, 0x009BA9, 0x000000, 0xFFFFFF, + 0x009BAC, 0x009BAC, 0x000000, 0xFFFFFF, + 0x009BAF, 0x009BB3, 0x000000, 0xFFFFFF, + 0x009BB5, 0x009BB8, 0x000000, 0xFFFFFF, + 0x009BBA, 0x009BBF, 0x000000, 0xFFFFFF, + 0x009BC1, 0x009BC5, 0x000000, 0xFFFFFF, + 0x009BC7, 0x009BC8, 0x000000, 0xFFFFFF, + 0x009BCB, 0x009BCE, 0x000000, 0xFFFFFF, + 0x009BD0, 0x009BD0, 0x000000, 0xFFFFFF, + 0x009BD3, 0x009BD3, 0x000000, 0xFFFFFF, + 0x009BD5, 0x009BD5, 0x000000, 0xFFFFFF, + 0x009BD7, 0x009BDA, 0x000000, 0xFFFFFF, + 0x009BDC, 0x009BE0, 0x000000, 0xFFFFFF, + 0x009BE5, 0x009BE7, 0x000000, 0xFFFFFF, + 0x009BE9, 0x009BEF, 0x000000, 0xFFFFFF, + 0x009BF3, 0x009BF4, 0x000000, 0xFFFFFF, + 0x009BF6, 0x009C03, 0x000000, 0xFFFFFF, + 0x009C05, 0x009C05, 0x000000, 0xFFFFFF, + 0x009C07, 0x009C07, 0x000000, 0xFFFFFF, + 0x009C0B, 0x009C0B, 0x000000, 0xFFFFFF, + 0x009C0E, 0x009C0F, 0x000000, 0xFFFFFF, + 0x009C11, 0x009C11, 0x000000, 0xFFFFFF, + 0x009C16, 0x009C1A, 0x000000, 0xFFFFFF, + 0x009C1C, 0x009C20, 0x000000, 0xFFFFFF, + 0x009C22, 0x009C23, 0x000000, 0xFFFFFF, + 0x009C26, 0x009C2C, 0x000000, 0xFFFFFF, + 0x009C31, 0x009C31, 0x000000, 0xFFFFFF, + 0x009C33, 0x009C38, 0x000000, 0xFFFFFF, + 0x009C3C, 0x009C3D, 0x000000, 0xFFFFFF, + 0x009C3F, 0x009C45, 0x000000, 0xFFFFFF, + 0x009C49, 0x009C51, 0x000000, 0xFFFFFF, + 0x009C53, 0x009C56, 0x000000, 0xFFFFFF, + 0x009C58, 0x009C59, 0x000000, 0xFFFFFF, + 0x009C5B, 0x009C5F, 0x000000, 0xFFFFFF, + 0x009C61, 0x009C66, 0x000000, 0xFFFFFF, + 0x009C68, 0x009C75, 0x000000, 0xFFFFFF, + 0x009C77, 0x009C77, 0x000000, 0xFFFFFF, + 0x009C79, 0x009CE4, 0x000000, 0xFFFFFF, + 0x009CE6, 0x009CE6, 0x000000, 0xFFFFFF, + 0x009CE8, 0x009CE8, 0x000000, 0xFFFFFF, + 0x009CEA, 0x009CEA, 0x000000, 0xFFFFFF, + 0x009CED, 0x009CEF, 0x000000, 0xFFFFFF, + 0x009CF1, 0x009CF2, 0x000000, 0xFFFFFF, + 0x009CF5, 0x009CF5, 0x000000, 0xFFFFFF, + 0x009CF7, 0x009D02, 0x000000, 0xFFFFFF, + 0x009D04, 0x009D05, 0x000000, 0xFFFFFF, + 0x009D0A, 0x009D0D, 0x000000, 0xFFFFFF, + 0x009D0F, 0x009D11, 0x000000, 0xFFFFFF, + 0x009D13, 0x009D14, 0x000000, 0xFFFFFF, + 0x009D16, 0x009D1A, 0x000000, 0xFFFFFF, + 0x009D1C, 0x009D1E, 0x000000, 0xFFFFFF, + 0x009D20, 0x009D22, 0x000000, 0xFFFFFF, + 0x009D24, 0x009D25, 0x000000, 0xFFFFFF, + 0x009D27, 0x009D27, 0x000000, 0xFFFFFF, + 0x009D29, 0x009D29, 0x000000, 0xFFFFFF, + 0x009D2D, 0x009D3A, 0x000000, 0xFFFFFF, + 0x009D3C, 0x009D3D, 0x000000, 0xFFFFFF, + 0x009D40, 0x009D40, 0x000000, 0xFFFFFF, + 0x009D42, 0x009D43, 0x000000, 0xFFFFFF, + 0x009D45, 0x009D45, 0x000000, 0xFFFFFF, + 0x009D47, 0x009D47, 0x000000, 0xFFFFFF, + 0x009D49, 0x009D4F, 0x000000, 0xFFFFFF, + 0x009D52, 0x009D58, 0x000000, 0xFFFFFF, + 0x009D5A, 0x009D5B, 0x000000, 0xFFFFFF, + 0x009D5F, 0x009D5F, 0x000000, 0xFFFFFF, + 0x009D62, 0x009D63, 0x000000, 0xFFFFFF, + 0x009D65, 0x009D6B, 0x000000, 0xFFFFFF, + 0x009D6D, 0x009D6E, 0x000000, 0xFFFFFF, + 0x009D70, 0x009D71, 0x000000, 0xFFFFFF, + 0x009D73, 0x009D79, 0x000000, 0xFFFFFF, + 0x009D7B, 0x009D86, 0x000000, 0xFFFFFF, + 0x009D88, 0x009D88, 0x000000, 0xFFFFFF, + 0x009D8A, 0x009D8E, 0x000000, 0xFFFFFF, + 0x009D90, 0x009D99, 0x000000, 0xFFFFFF, + 0x009D9B, 0x009DA3, 0x000000, 0xFFFFFF, + 0x009DA5, 0x009DA8, 0x000000, 0xFFFFFF, + 0x009DAA, 0x009DAA, 0x000000, 0xFFFFFF, + 0x009DAC, 0x009DAE, 0x000000, 0xFFFFFF, + 0x009DB0, 0x009DB1, 0x000000, 0xFFFFFF, + 0x009DB3, 0x009DB3, 0x000000, 0xFFFFFF, + 0x009DB5, 0x009DB7, 0x000000, 0xFFFFFF, + 0x009DB9, 0x009DB9, 0x000000, 0xFFFFFF, + 0x009DBC, 0x009DC0, 0x000000, 0xFFFFFF, + 0x009DC3, 0x009DC3, 0x000000, 0xFFFFFF, + 0x009DC5, 0x009DC5, 0x000000, 0xFFFFFF, + 0x009DC7, 0x009DCE, 0x000000, 0xFFFFFF, + 0x009DD0, 0x009DD2, 0x000000, 0xFFFFFF, + 0x009DD4, 0x009DD8, 0x000000, 0xFFFFFF, + 0x009DDA, 0x009DE5, 0x000000, 0xFFFFFF, + 0x009DE7, 0x009DEC, 0x000000, 0xFFFFFF, + 0x009DEE, 0x009DEE, 0x000000, 0xFFFFFF, + 0x009DF0, 0x009DF1, 0x000000, 0xFFFFFF, + 0x009DF3, 0x009DF7, 0x000000, 0xFFFFFF, + 0x009DFB, 0x009DFC, 0x000000, 0xFFFFFF, + 0x009DFE, 0x009E19, 0x000000, 0xFFFFFF, + 0x009E1C, 0x009E1D, 0x000000, 0xFFFFFF, + 0x009E1F, 0x009E74, 0x000000, 0xFFFFFF, + 0x009E76, 0x009E77, 0x000000, 0xFFFFFF, + 0x009E7A, 0x009E7C, 0x000000, 0xFFFFFF, + 0x009E7E, 0x009E7E, 0x000000, 0xFFFFFF, + 0x009E80, 0x009E80, 0x000000, 0xFFFFFF, + 0x009E82, 0x009E87, 0x000000, 0xFFFFFF, + 0x009E89, 0x009E8A, 0x000000, 0xFFFFFF, + 0x009E8D, 0x009E90, 0x000000, 0xFFFFFF, + 0x009E94, 0x009E94, 0x000000, 0xFFFFFF, + 0x009E96, 0x009E96, 0x000000, 0xFFFFFF, + 0x009E98, 0x009E9C, 0x000000, 0xFFFFFF, + 0x009E9E, 0x009E9E, 0x000000, 0xFFFFFF, + 0x009EA0, 0x009EA4, 0x000000, 0xFFFFFF, + 0x009EA7, 0x009EA8, 0x000000, 0xFFFFFF, + 0x009EAB, 0x009EAC, 0x000000, 0xFFFFFF, + 0x009EAE, 0x009EB7, 0x000000, 0xFFFFFF, + 0x009EBD, 0x009EBD, 0x000000, 0xFFFFFF, + 0x009EC0, 0x009EC3, 0x000000, 0xFFFFFF, + 0x009EC5, 0x009ECB, 0x000000, 0xFFFFFF, + 0x009ED1, 0x009ED1, 0x000000, 0xFFFFFF, + 0x009ED3, 0x009ED3, 0x000000, 0xFFFFFF, + 0x009ED5, 0x009ED7, 0x000000, 0xFFFFFF, + 0x009EDA, 0x009EDA, 0x000000, 0xFFFFFF, + 0x009EDF, 0x009EDF, 0x000000, 0xFFFFFF, + 0x009EE1, 0x009EE4, 0x000000, 0xFFFFFF, + 0x009EE6, 0x009EE7, 0x000000, 0xFFFFFF, + 0x009EE9, 0x009EEE, 0x000000, 0xFFFFFF, + 0x009EF0, 0x009EF3, 0x000000, 0xFFFFFF, + 0x009EF5, 0x009EF5, 0x000000, 0xFFFFFF, + 0x009EF8, 0x009EF8, 0x000000, 0xFFFFFF, + 0x009EFA, 0x009EFA, 0x000000, 0xFFFFFF, + 0x009EFE, 0x009F06, 0x000000, 0xFFFFFF, + 0x009F09, 0x009F0D, 0x000000, 0xFFFFFF, + 0x009F0F, 0x009F12, 0x000000, 0xFFFFFF, + 0x009F14, 0x009F14, 0x000000, 0xFFFFFF, + 0x009F16, 0x009F1F, 0x000000, 0xFFFFFF, + 0x009F22, 0x009F2B, 0x000000, 0xFFFFFF, + 0x009F2D, 0x009F3A, 0x000000, 0xFFFFFF, + 0x009F3C, 0x009F3D, 0x000000, 0xFFFFFF, + 0x009F3F, 0x009F49, 0x000000, 0xFFFFFF, + 0x009F4C, 0x009F4D, 0x000000, 0xFFFFFF, + 0x009F50, 0x009F51, 0x000000, 0xFFFFFF, + 0x009F53, 0x009F53, 0x000000, 0xFFFFFF, + 0x009F55, 0x009F5E, 0x000000, 0xFFFFFF, + 0x009F64, 0x009F65, 0x000000, 0xFFFFFF, + 0x009F68, 0x009F69, 0x000000, 0xFFFFFF, + 0x009F6B, 0x009F6B, 0x000000, 0xFFFFFF, + 0x009F6D, 0x009F71, 0x000000, 0xFFFFFF, + 0x009F73, 0x009F75, 0x000000, 0xFFFFFF, + 0x009F78, 0x009F8C, 0x000000, 0xFFFFFF, + 0x009F8E, 0x009F94, 0x000000, 0xFFFFFF, + 0x009F96, 0x009F9B, 0x000000, 0xFFFFFF, + 0x009F9E, 0x009F9F, 0x000000, 0xFFFFFF, + 0x009FA1, 0x00FF00, 0x000000, 0xFFFFFF, + 0x00FF02, 0x00FF02, 0x000000, 0xFFFFFF, + 0x00FF07, 0x00FF07, 0x000000, 0xFFFFFF, + 0x00FF0D, 0x00FF0D, 0x000000, 0xFFFFFF, + 0x00FF5E, 0x00FF60, 0x000000, 0xFFFFFF, + 0x00FFA0, 0x00FFDF, 0x000000, 0xFFFFFF, + 0x00FFE4, 0x00FFE4, 0x000000, 0xFFFFFF, + 0x00FFE6, 0x1FFFFF, 0x000000, 0xFFFFFF, +); + +?> diff --git a/lib/php/monica/cnvtmap/US-ASCII.inc.php b/lib/php/monica/cnvtmap/US-ASCII.inc.php new file mode 100644 index 0000000..c09f8a6 --- /dev/null +++ b/lib/php/monica/cnvtmap/US-ASCII.inc.php @@ -0,0 +1,13 @@ + +// Copyright: Copyright (C) 2005-2007 Pristine Communications + +// US-ASCII +$CNVTMAP["US-ASCII"] = array( + 0x000080, 0x1FFFFF, 0x000000, 0xFFFFFF, +); + +?> diff --git a/lib/php/monica/cnvtmap/invalid.inc.php b/lib/php/monica/cnvtmap/invalid.inc.php new file mode 100644 index 0000000..06c9269 --- /dev/null +++ b/lib/php/monica/cnvtmap/invalid.inc.php @@ -0,0 +1,13 @@ + +// Copyright: Copyright (C) 2008 Pristine Communications + +// Invalid unicode characters +$CNVTMAP["invalid"] = array( + 0x00D800, 0x00DFFF, 0x000000, 0xFFFFFF, +); + +?> diff --git a/lib/php/monica/cnvtmap/simp_to_trad.inc.php b/lib/php/monica/cnvtmap/simp_to_trad.inc.php new file mode 100644 index 0000000..db2146b --- /dev/null +++ b/lib/php/monica/cnvtmap/simp_to_trad.inc.php @@ -0,0 +1,270 @@ + +// Copyright: Copyright (C) 2005-2007 Pristine Communications + +// Simplified Chinese to Traditional Chinese +$CNVTMAP["simp_to_trad"] = array( + 0x3005, 0x3005, 0x0000, 0xFFFF, + 0x3016, 0x3017, 0x0000, 0xFFFF, + 0x2208, 0x2208, 0x0000, 0xFFFF, + 0x2237, 0x2237, 0x0000, 0xFFFF, + 0x2312, 0x2312, 0x0000, 0xFFFF, + 0x224C, 0x224C, 0x0000, 0xFFFF, + 0x223D, 0x223D, 0x0000, 0xFFFF, + 0x221D, 0x221D, 0x0000, 0xFFFF, + 0x226E, 0x226F, 0x0000, 0xFFFF, + 0x00A4, 0x00A4, 0x0000, 0xFFFF, + 0x2030, 0x2030, 0x0000, 0xFFFF, + 0x2116, 0x2116, 0x0000, 0xFFFF, + 0x3013, 0x3013, 0x0000, 0xFFFF, + 0x2488, 0x249B, 0x0000, 0xFFFF, + 0x2474, 0x2487, 0x0000, 0xFFFF, + 0x2460, 0x2469, 0x0000, 0xFFFF, + 0x3220, 0x3229, 0x0000, 0xFFFF, + 0x216A, 0x216B, 0x0000, 0xFFFF, + 0xFF07, 0xFF07, 0x0000, 0xFFFF, + 0xFF3E, 0xFF3E, 0x0000, 0xFFFF, + 0x3041, 0x3093, 0x0000, 0xFFFF, + 0x30A1, 0x30F6, 0x0000, 0xFFFF, + 0x0410, 0x0415, 0x0000, 0xFFFF, + 0x0401, 0x0401, 0x0000, 0xFFFF, + 0x0416, 0x0435, 0x0000, 0xFFFF, + 0x0451, 0x0451, 0x0000, 0xFFFF, + 0x0436, 0x044F, 0x0000, 0xFFFF, + 0x0101, 0x0101, 0x0000, 0xFFFF, + 0x00E1, 0x00E1, 0x0000, 0xFFFF, + 0x01CE, 0x01CE, 0x0000, 0xFFFF, + 0x00E0, 0x00E0, 0x0000, 0xFFFF, + 0x0113, 0x0113, 0x0000, 0xFFFF, + 0x00E9, 0x00E9, 0x0000, 0xFFFF, + 0x011B, 0x011B, 0x0000, 0xFFFF, + 0x00E8, 0x00E8, 0x0000, 0xFFFF, + 0x012B, 0x012B, 0x0000, 0xFFFF, + 0x00ED, 0x00ED, 0x0000, 0xFFFF, + 0x01D0, 0x01D0, 0x0000, 0xFFFF, + 0x00EC, 0x00EC, 0x0000, 0xFFFF, + 0x014D, 0x014D, 0x0000, 0xFFFF, + 0x00F3, 0x00F3, 0x0000, 0xFFFF, + 0x01D2, 0x01D2, 0x0000, 0xFFFF, + 0x00F2, 0x00F2, 0x0000, 0xFFFF, + 0x016B, 0x016B, 0x0000, 0xFFFF, + 0x00FA, 0x00FA, 0x0000, 0xFFFF, + 0x01D4, 0x01D4, 0x0000, 0xFFFF, + 0x00F9, 0x00F9, 0x0000, 0xFFFF, + 0x01D6, 0x01D6, 0x0000, 0xFFFF, + 0x01D8, 0x01D8, 0x0000, 0xFFFF, + 0x01DA, 0x01DA, 0x0000, 0xFFFF, + 0x01DC, 0x01DC, 0x0000, 0xFFFF, + 0x00FC, 0x00FC, 0x0000, 0xFFFF, + 0x00EA, 0x00EA, 0x0000, 0xFFFF, + 0x2504, 0x250B, 0x0000, 0xFFFF, + 0x250D, 0x250E, 0x0000, 0xFFFF, + 0x2511, 0x2512, 0x0000, 0xFFFF, + 0x2515, 0x2516, 0x0000, 0xFFFF, + 0x2519, 0x251A, 0x0000, 0xFFFF, + 0x251D, 0x2522, 0x0000, 0xFFFF, + 0x2525, 0x252A, 0x0000, 0xFFFF, + 0x252D, 0x2532, 0x0000, 0xFFFF, + 0x2535, 0x253A, 0x0000, 0xFFFF, + 0x253D, 0x254A, 0x0000, 0xFFFF, + 0x5088, 0x5088, 0x0000, 0xFFFF, + 0x9176, 0x9176, 0x0000, 0xFFFF, + 0x915E, 0x915E, 0x0000, 0xFFFF, + 0x9528, 0x9528, 0x0000, 0xFFFF, + 0x4E28, 0x4E28, 0x0000, 0xFFFF, + 0x4E3F, 0x4E3F, 0x0000, 0xFFFF, + 0x9F17, 0x9F17, 0x0000, 0xFFFF, + 0x4E36, 0x4E36, 0x0000, 0xFFFF, + 0x5290, 0x5290, 0x0000, 0xFFFF, + 0x5182, 0x5182, 0x0000, 0xFFFF, + 0x4EEB, 0x4EEB, 0x0000, 0xFFFF, + 0x52F9, 0x52F9, 0x0000, 0xFFFF, + 0x4EA0, 0x4EA0, 0x0000, 0xFFFF, + 0x51AB, 0x51AB, 0x0000, 0xFFFF, + 0x5196, 0x5196, 0x0000, 0xFFFF, + 0x52D0, 0x52D0, 0x0000, 0xFFFF, + 0x5EF4, 0x5EF4, 0x0000, 0xFFFF, + 0x57A1, 0x57A1, 0x0000, 0xFFFF, + 0x57A7, 0x57A7, 0x0000, 0xFFFF, + 0x57B4, 0x57B4, 0x0000, 0xFFFF, + 0x57EF, 0x57EF, 0x0000, 0xFFFF, + 0x57DD, 0x57DD, 0x0000, 0xFFFF, + 0x5844, 0x5844, 0x0000, 0xFFFF, + 0x586C, 0x586C, 0x0000, 0xFFFF, + 0x589A, 0x589A, 0x0000, 0xFFFF, + 0x82CA, 0x82CA, 0x0000, 0xFFFF, + 0x82AA, 0x82AA, 0x0000, 0xFFFF, + 0x82C4, 0x82C4, 0x0000, 0xFFFF, + 0x82F7, 0x82F7, 0x0000, 0xFFFF, + 0x82D8, 0x82D8, 0x0000, 0xFFFF, + 0x831A, 0x831A, 0x0000, 0xFFFF, + 0x836E, 0x836E, 0x0000, 0xFFFF, + 0x839C, 0x839C, 0x0000, 0xFFFF, + 0x8418, 0x8418, 0x0000, 0xFFFF, + 0x841C, 0x841C, 0x0000, 0xFFFF, + 0x845C, 0x845C, 0x0000, 0xFFFF, + 0x8488, 0x8488, 0x0000, 0xFFFF, + 0x84BD, 0x84BD, 0x0000, 0xFFFF, + 0x8538, 0x8538, 0x0000, 0xFFFF, + 0x85C1, 0x85C1, 0x0000, 0xFFFF, + 0x63F8, 0x63F8, 0x0000, 0xFFFF, + 0x63DE, 0x63DE, 0x0000, 0xFFFF, + 0x7519, 0x7519, 0x0000, 0xFFFF, + 0x535F, 0x535F, 0x0000, 0xFFFF, + 0x5416, 0x5416, 0x0000, 0xFFFF, + 0x544B, 0x544B, 0x0000, 0xFFFF, + 0x5421, 0x5421, 0x0000, 0xFFFF, + 0x5423, 0x5423, 0x0000, 0xFFFF, + 0x5432, 0x5432, 0x0000, 0xFFFF, + 0x5494, 0x5494, 0x0000, 0xFFFF, + 0x549D, 0x549D, 0x0000, 0xFFFF, + 0x54D0, 0x54D0, 0x0000, 0xFFFF, + 0x54B4, 0x54B4, 0x0000, 0xFFFF, + 0x54A3, 0x54A3, 0x0000, 0xFFFF, + 0x54DA, 0x54DA, 0x0000, 0xFFFF, + 0x54A4, 0x54A4, 0x0000, 0xFFFF, + 0x5523, 0x5523, 0x0000, 0xFFFF, + 0x5549, 0x5549, 0x0000, 0xFFFF, + 0x553F, 0x553F, 0x0000, 0xFFFF, + 0x55B9, 0x55B9, 0x0000, 0xFFFF, + 0x55EA, 0x55EA, 0x0000, 0xFFFF, + 0x55F5, 0x55F5, 0x0000, 0xFFFF, + 0x561E, 0x561E, 0x0000, 0xFFFF, + 0x5623, 0x5623, 0x0000, 0xFFFF, + 0x562D, 0x562D, 0x0000, 0xFFFF, + 0x564D, 0x564D, 0x0000, 0xFFFF, + 0x5654, 0x5654, 0x0000, 0xFFFF, + 0x567B, 0x567C, 0x0000, 0xFFFF, + 0x56AF, 0x56AF, 0x0000, 0xFFFF, + 0x5E5E, 0x5E5E, 0x0000, 0xFFFF, + 0x5C99, 0x5C99, 0x0000, 0xFFFF, + 0x5C9C, 0x5C9C, 0x0000, 0xFFFF, + 0x5CC1, 0x5CC1, 0x0000, 0xFFFF, + 0x5D3E, 0x5D3E, 0x0000, 0xFFFF, + 0x5D74, 0x5D74, 0x0000, 0xFFFF, + 0x5F61, 0x5F61, 0x0000, 0xFFFF, + 0x72B8, 0x72B8, 0x0000, 0xFFFF, + 0x72CD, 0x72CD, 0x0000, 0xFFFF, + 0x7339, 0x7339, 0x0000, 0xFFFF, + 0x7338, 0x7338, 0x0000, 0xFFFF, + 0x5902, 0x5902, 0x0000, 0xFFFF, + 0x9987, 0x9987, 0x0000, 0xFFFF, + 0x9993, 0x9993, 0x0000, 0xFFFF, + 0x9995, 0x9995, 0x0000, 0xFFFF, + 0x61B7, 0x61B7, 0x0000, 0xFFFF, + 0x6EBB, 0x6EBB, 0x0000, 0xFFFF, + 0x6F24, 0x6F24, 0x0000, 0xFFFF, + 0x5B80, 0x5B80, 0x0000, 0xFFFF, + 0x8FB6, 0x8FB6, 0x0000, 0xFFFF, + 0x5F50, 0x5F50, 0x0000, 0xFFFF, + 0x59F9, 0x59F9, 0x0000, 0xFFFF, + 0x80EC, 0x80EC, 0x0000, 0xFFFF, + 0x7EF1, 0x7EF1, 0x0000, 0xFFFF, + 0x5DDB, 0x5DDB, 0x0000, 0xFFFF, + 0x67A7, 0x67A7, 0x0000, 0xFFFF, + 0x6855, 0x6855, 0x0000, 0xFFFF, + 0x684A, 0x684A, 0x0000, 0xFFFF, + 0x6980, 0x6980, 0x0000, 0xFFFF, + 0x6AAB, 0x6AAB, 0x0000, 0xFFFF, + 0x8F71, 0x8F71, 0x0000, 0xFFFF, + 0x8F77, 0x8F77, 0x0000, 0xFFFF, + 0x8ECE, 0x8ECE, 0x0000, 0xFFFF, + 0x6657, 0x6657, 0x0000, 0xFFFF, + 0x729F, 0x729F, 0x0000, 0xFFFF, + 0x728F, 0x728F, 0x0000, 0xFFFF, + 0x6BEA, 0x6BEA, 0x0000, 0xFFFF, + 0x6535, 0x6535, 0x0000, 0xFFFF, + 0x656B, 0x656B, 0x0000, 0xFFFF, + 0x809F, 0x809F, 0x0000, 0xFFFF, + 0x80BC, 0x80BD, 0x0000, 0xFFFF, + 0x80B7, 0x80B7, 0x0000, 0xFFFF, + 0x80E8, 0x80E9, 0x0000, 0xFFFF, + 0x810E, 0x810E, 0x0000, 0xFFFF, + 0x8112, 0x8112, 0x0000, 0xFFFF, + 0x8148, 0x8148, 0x0000, 0xFFFF, + 0x8159, 0x815A, 0x0000, 0xFFFF, + 0x81AA, 0x81AA, 0x0000, 0xFFFF, + 0x81C1, 0x81C1, 0x0000, 0xFFFF, + 0x98DA, 0x98DA, 0x0000, 0xFFFF, + 0x70BB, 0x70BB, 0x0000, 0xFFFF, + 0x70C0, 0x70C0, 0x0000, 0xFFFF, + 0x7173, 0x7173, 0x0000, 0xFFFF, + 0x714A, 0x714A, 0x0000, 0xFFFF, + 0x717A, 0x717A, 0x0000, 0xFFFF, + 0x7198, 0x7198, 0x0000, 0xFFFF, + 0x7818, 0x7818, 0x0000, 0xFFFF, + 0x781C, 0x781C, 0x0000, 0xFFFF, + 0x7839, 0x7839, 0x0000, 0xFFFF, + 0x783C, 0x783C, 0x0000, 0xFFFF, + 0x7847, 0x7847, 0x0000, 0xFFFF, + 0x78B9, 0x78B9, 0x0000, 0xFFFF, + 0x78D9, 0x78D9, 0x0000, 0xFFFF, + 0x770D, 0x770D, 0x0000, 0xFFFF, + 0x7743, 0x7743, 0x0000, 0xFFFF, + 0x7583, 0x7583, 0x0000, 0xFFFF, + 0x7F71, 0x7F71, 0x0000, 0xFFFF, + 0x949A, 0x949A, 0x0000, 0xFFFF, + 0x94B7, 0x94B7, 0x0000, 0xFFFF, + 0x94D8, 0x94D8, 0x0000, 0xFFFF, + 0x94DE, 0x94DE, 0x0000, 0xFFFF, + 0x9503, 0x9503, 0x0000, 0xFFFF, + 0x950D, 0x950F, 0x0000, 0xFFFF, + 0x9518, 0x9518, 0x0000, 0xFFFF, + 0x951D, 0x951D, 0x0000, 0xFFFF, + 0x952A, 0x952B, 0x0000, 0xFFFF, + 0x953F, 0x953F, 0x0000, 0xFFFF, + 0x9545, 0x9545, 0x0000, 0xFFFF, + 0x954E, 0x954E, 0x0000, 0xFFFF, + 0x9562, 0x9562, 0x0000, 0xFFFF, + 0x9565, 0x9565, 0x0000, 0xFFFF, + 0x9569, 0x9569, 0x0000, 0xFFFF, + 0x9572, 0x9572, 0x0000, 0xFFFF, + 0x7A06, 0x7A06, 0x0000, 0xFFFF, + 0x9E4B, 0x9E4B, 0x0000, 0xFFFF, + 0x9E5B, 0x9E5B, 0x0000, 0xFFFF, + 0x9E71, 0x9E71, 0x0000, 0xFFFF, + 0x7592, 0x7592, 0x0000, 0xFFFF, + 0x75AC, 0x75AC, 0x0000, 0xFFFF, + 0x75C3, 0x75C3, 0x0000, 0xFFFF, + 0x75D6, 0x75D6, 0x0000, 0xFFFF, + 0x7640, 0x7640, 0x0000, 0xFFFF, + 0x764D, 0x764D, 0x0000, 0xFFFF, + 0x7654, 0x7654, 0x0000, 0xFFFF, + 0x766F, 0x766F, 0x0000, 0xFFFF, + 0x8020, 0x8020, 0x0000, 0xFFFF, + 0x8022, 0x8022, 0x0000, 0xFFFF, + 0x8025, 0x8025, 0x0000, 0xFFFF, + 0x8031, 0x8031, 0x0000, 0xFFFF, + 0x98A5, 0x98A5, 0x0000, 0xFFFF, + 0x877D, 0x877D, 0x0000, 0xFFFF, + 0x878B, 0x878B, 0x0000, 0xFFFF, + 0x87A8, 0x87A8, 0x0000, 0xFFFF, + 0x7B7B, 0x7B7B, 0x0000, 0xFFFF, + 0x7B62, 0x7B62, 0x0000, 0xFFFF, + 0x7BA2, 0x7BA2, 0x0000, 0xFFFF, + 0x7BFC, 0x7BFC, 0x0000, 0xFFFF, + 0x822D, 0x822D, 0x0000, 0xFFFF, + 0x823E, 0x823E, 0x0000, 0xFFFF, + 0x9170, 0x9170, 0x0000, 0xFFFF, + 0x918C, 0x918C, 0x0000, 0xFFFF, + 0x8E3A, 0x8E3A, 0x0000, 0xFFFF, + 0x943E, 0x943E, 0x0000, 0xFFFF, + 0x9C85, 0x9C86, 0x0000, 0xFFFF, + 0x9CB4, 0x9CB4, 0x0000, 0xFFFF, + 0x9CBA, 0x9CBA, 0x0000, 0xFFFF, + 0x9CBC, 0x9CBC, 0x0000, 0xFFFF, + 0x9CCA, 0x9CCB, 0x0000, 0xFFFF, + 0x9CD8, 0x9CD9, 0x0000, 0xFFFF, + 0x97B2, 0x97B2, 0x0000, 0xFFFF, + 0x97B4, 0x97B4, 0x0000, 0xFFFF, + 0x9AB6, 0x9AB6, 0x0000, 0xFFFF, + 0x9ABA, 0x9ABA, 0x0000, 0xFFFF, + 0x9B0F, 0x9B0F, 0x0000, 0xFFFF, + 0x9EE2, 0x9EE2, 0x0000, 0xFFFF, + 0x9F44, 0x9F44, 0x0000, 0xFFFF, +); + +?> diff --git a/lib/php/monica/cnvtmap/trad_to_simp.inc.php b/lib/php/monica/cnvtmap/trad_to_simp.inc.php new file mode 100644 index 0000000..2d3e692 --- /dev/null +++ b/lib/php/monica/cnvtmap/trad_to_simp.inc.php @@ -0,0 +1,3904 @@ + +// Copyright: Copyright (C) 2006-2007 Pristine Communications + +// Traditional Chinese to Simplified Chinese +$CNVTMAP["trad_to_simp"] = array( + 0x000080, 0x000080, 0x000000, 0xFFFFFF, + 0x0002CA, 0x0002CB, 0x000000, 0xFFFFFF, + 0x0002CD, 0x0002CD, 0x000000, 0xFFFFFF, + 0x0002D9, 0x0002D9, 0x000000, 0xFFFFFF, + 0x002013, 0x002014, 0x000000, 0xFFFFFF, + 0x0020AC, 0x0020AC, 0x000000, 0xFFFFFF, + 0x002105, 0x002105, 0x000000, 0xFFFFFF, + 0x002109, 0x002109, 0x000000, 0xFFFFFF, + 0x002196, 0x002199, 0x000000, 0xFFFFFF, + 0x002215, 0x002215, 0x000000, 0xFFFFFF, + 0x00221F, 0x00221F, 0x000000, 0xFFFFFF, + 0x002223, 0x002223, 0x000000, 0xFFFFFF, + 0x002295, 0x002295, 0x000000, 0xFFFFFF, + 0x0022BF, 0x0022BF, 0x000000, 0xFFFFFF, + 0x002550, 0x002570, 0x000000, 0xFFFFFF, + 0x002573, 0x002573, 0x000000, 0xFFFFFF, + 0x002581, 0x00258F, 0x000000, 0xFFFFFF, + 0x002593, 0x002595, 0x000000, 0xFFFFFF, + 0x0025BC, 0x0025BD, 0x000000, 0xFFFFFF, + 0x0025E2, 0x0025E5, 0x000000, 0xFFFFFF, + 0x003012, 0x003012, 0x000000, 0xFFFFFF, + 0x003021, 0x003029, 0x000000, 0xFFFFFF, + 0x0032A3, 0x0032A3, 0x000000, 0xFFFFFF, + 0x00338E, 0x00338F, 0x000000, 0xFFFFFF, + 0x00339C, 0x00339E, 0x000000, 0xFFFFFF, + 0x0033A1, 0x0033A1, 0x000000, 0xFFFFFF, + 0x0033C4, 0x0033C4, 0x000000, 0xFFFFFF, + 0x0033CE, 0x0033CE, 0x000000, 0xFFFFFF, + 0x0033D1, 0x0033D2, 0x000000, 0xFFFFFF, + 0x0033D5, 0x0033D5, 0x000000, 0xFFFFFF, + 0x004E0F, 0x004E0F, 0x000000, 0xFFFFFF, + 0x004E2E, 0x004E2E, 0x000000, 0xFFFFFF, + 0x004E31, 0x004E31, 0x000000, 0xFFFFFF, + 0x004E33, 0x004E33, 0x000000, 0xFFFFFF, + 0x004E42, 0x004E42, 0x000000, 0xFFFFFF, + 0x004E7F, 0x004E7F, 0x000000, 0xFFFFFF, + 0x004E83, 0x004E84, 0x000000, 0xFFFFFF, + 0x004EB6, 0x004EB6, 0x000000, 0xFFFFFF, + 0x004EB9, 0x004EB9, 0x000000, 0xFFFFFF, + 0x004EC8, 0x004EC8, 0x000000, 0xFFFFFF, + 0x004EDA, 0x004EDA, 0x000000, 0xFFFFFF, + 0x004EDC, 0x004EDC, 0x000000, 0xFFFFFF, + 0x004EE9, 0x004EE9, 0x000000, 0xFFFFFF, + 0x004EF1, 0x004EF1, 0x000000, 0xFFFFFF, + 0x004EF4, 0x004EF4, 0x000000, 0xFFFFFF, + 0x004F00, 0x004F00, 0x000000, 0xFFFFFF, + 0x004F02, 0x004F02, 0x000000, 0xFFFFFF, + 0x004F04, 0x004F05, 0x000000, 0xFFFFFF, + 0x004F08, 0x004F08, 0x000000, 0xFFFFFF, + 0x004F0B, 0x004F0B, 0x000000, 0xFFFFFF, + 0x004F12, 0x004F14, 0x000000, 0xFFFFFF, + 0x004F1D, 0x004F1D, 0x000000, 0xFFFFFF, + 0x004F2C, 0x004F2D, 0x000000, 0xFFFFFF, + 0x004F33, 0x004F33, 0x000000, 0xFFFFFF, + 0x004F3B, 0x004F3B, 0x000000, 0xFFFFFF, + 0x004F3E, 0x004F3F, 0x000000, 0xFFFFFF, + 0x004F41, 0x004F41, 0x000000, 0xFFFFFF, + 0x004F49, 0x004F49, 0x000000, 0xFFFFFF, + 0x004F4C, 0x004F4C, 0x000000, 0xFFFFFF, + 0x004F52, 0x004F52, 0x000000, 0xFFFFFF, + 0x004F56, 0x004F56, 0x000000, 0xFFFFFF, + 0x004F61, 0x004F62, 0x000000, 0xFFFFFF, + 0x004F6B, 0x004F6B, 0x000000, 0xFFFFFF, + 0x004F6E, 0x004F6E, 0x000000, 0xFFFFFF, + 0x004F77, 0x004F7A, 0x000000, 0xFFFFFF, + 0x004F7D, 0x004F7D, 0x000000, 0xFFFFFF, + 0x004F80, 0x004F82, 0x000000, 0xFFFFFF, + 0x004F85, 0x004F85, 0x000000, 0xFFFFFF, + 0x004F87, 0x004F87, 0x000000, 0xFFFFFF, + 0x004F90, 0x004F90, 0x000000, 0xFFFFFF, + 0x004F92, 0x004F92, 0x000000, 0xFFFFFF, + 0x004F95, 0x004F95, 0x000000, 0xFFFFFF, + 0x004F98, 0x004F98, 0x000000, 0xFFFFFF, + 0x004F9C, 0x004F9C, 0x000000, 0xFFFFFF, + 0x004F9E, 0x004F9E, 0x000000, 0xFFFFFF, + 0x004FB2, 0x004FB3, 0x000000, 0xFFFFFF, + 0x004FB9, 0x004FBB, 0x000000, 0xFFFFFF, + 0x004FC0, 0x004FC0, 0x000000, 0xFFFFFF, + 0x004FC7, 0x004FC7, 0x000000, 0xFFFFFF, + 0x004FC9, 0x004FC9, 0x000000, 0xFFFFFF, + 0x004FCB, 0x004FCB, 0x000000, 0xFFFFFF, + 0x004FCD, 0x004FCD, 0x000000, 0xFFFFFF, + 0x004FD3, 0x004FD4, 0x000000, 0xFFFFFF, + 0x004FD6, 0x004FD6, 0x000000, 0xFFFFFF, + 0x004FD9, 0x004FD9, 0x000000, 0xFFFFFF, + 0x004FDB, 0x004FDB, 0x000000, 0xFFFFFF, + 0x004FEC, 0x004FEC, 0x000000, 0xFFFFFF, + 0x004FF4, 0x004FF7, 0x000000, 0xFFFFFF, + 0x005005, 0x005005, 0x000000, 0xFFFFFF, + 0x005007, 0x005007, 0x000000, 0xFFFFFF, + 0x00500E, 0x00500E, 0x000000, 0xFFFFFF, + 0x005013, 0x005013, 0x000000, 0xFFFFFF, + 0x005015, 0x005015, 0x000000, 0xFFFFFF, + 0x005017, 0x005017, 0x000000, 0xFFFFFF, + 0x00501B, 0x00501B, 0x000000, 0xFFFFFF, + 0x00501E, 0x00501E, 0x000000, 0xFFFFFF, + 0x005020, 0x005020, 0x000000, 0xFFFFFF, + 0x005022, 0x005022, 0x000000, 0xFFFFFF, + 0x005027, 0x005027, 0x000000, 0xFFFFFF, + 0x00502F, 0x005031, 0x000000, 0xFFFFFF, + 0x005033, 0x005033, 0x000000, 0xFFFFFF, + 0x005035, 0x005035, 0x000000, 0xFFFFFF, + 0x005037, 0x005037, 0x000000, 0xFFFFFF, + 0x005040, 0x005041, 0x000000, 0xFFFFFF, + 0x005045, 0x005046, 0x000000, 0xFFFFFF, + 0x00504A, 0x00504B, 0x000000, 0xFFFFFF, + 0x00504D, 0x00504D, 0x000000, 0xFFFFFF, + 0x005051, 0x005051, 0x000000, 0xFFFFFF, + 0x005053, 0x005053, 0x000000, 0xFFFFFF, + 0x005057, 0x005057, 0x000000, 0xFFFFFF, + 0x00505B, 0x00505B, 0x000000, 0xFFFFFF, + 0x00505D, 0x005064, 0x000000, 0xFFFFFF, + 0x005068, 0x005069, 0x000000, 0xFFFFFF, + 0x00506B, 0x00506B, 0x000000, 0xFFFFFF, + 0x00506D, 0x005070, 0x000000, 0xFFFFFF, + 0x005072, 0x005073, 0x000000, 0xFFFFFF, + 0x005082, 0x005083, 0x000000, 0xFFFFFF, + 0x005087, 0x005087, 0x000000, 0xFFFFFF, + 0x00508B, 0x00508C, 0x000000, 0xFFFFFF, + 0x00508E, 0x00508E, 0x000000, 0xFFFFFF, + 0x005092, 0x005092, 0x000000, 0xFFFFFF, + 0x005094, 0x005095, 0x000000, 0xFFFFFF, + 0x00509B, 0x00509E, 0x000000, 0xFFFFFF, + 0x0050AE, 0x0050AE, 0x000000, 0xFFFFFF, + 0x0050B0, 0x0050B1, 0x000000, 0xFFFFFF, + 0x0050B6, 0x0050B6, 0x000000, 0xFFFFFF, + 0x0050B8, 0x0050B8, 0x000000, 0xFFFFFF, + 0x0050BD, 0x0050BD, 0x000000, 0xFFFFFF, + 0x0050BF, 0x0050BF, 0x000000, 0xFFFFFF, + 0x0050C1, 0x0050C1, 0x000000, 0xFFFFFF, + 0x0050C4, 0x0050C4, 0x000000, 0xFFFFFF, + 0x0050C6, 0x0050C8, 0x000000, 0xFFFFFF, + 0x0050CB, 0x0050CB, 0x000000, 0xFFFFFF, + 0x0050CE, 0x0050CE, 0x000000, 0xFFFFFF, + 0x0050D3, 0x0050D4, 0x000000, 0xFFFFFF, + 0x0050D7, 0x0050D7, 0x000000, 0xFFFFFF, + 0x0050DB, 0x0050DB, 0x000000, 0xFFFFFF, + 0x0050DD, 0x0050DD, 0x000000, 0xFFFFFF, + 0x0050E0, 0x0050E0, 0x000000, 0xFFFFFF, + 0x0050E4, 0x0050E4, 0x000000, 0xFFFFFF, + 0x0050E9, 0x0050EA, 0x000000, 0xFFFFFF, + 0x0050EF, 0x0050F0, 0x000000, 0xFFFFFF, + 0x0050F6, 0x0050F6, 0x000000, 0xFFFFFF, + 0x0050F8, 0x0050F8, 0x000000, 0xFFFFFF, + 0x0050FD, 0x0050FF, 0x000000, 0xFFFFFF, + 0x005103, 0x005103, 0x000000, 0xFFFFFF, + 0x00510A, 0x00510A, 0x000000, 0xFFFFFF, + 0x00510C, 0x00510C, 0x000000, 0xFFFFFF, + 0x005111, 0x005111, 0x000000, 0xFFFFFF, + 0x005113, 0x005113, 0x000000, 0xFFFFFF, + 0x005117, 0x005117, 0x000000, 0xFFFFFF, + 0x00511A, 0x00511A, 0x000000, 0xFFFFFF, + 0x00511C, 0x00511C, 0x000000, 0xFFFFFF, + 0x005120, 0x005120, 0x000000, 0xFFFFFF, + 0x005122, 0x005122, 0x000000, 0xFFFFFF, + 0x005124, 0x005126, 0x000000, 0xFFFFFF, + 0x005129, 0x005129, 0x000000, 0xFFFFFF, + 0x00512D, 0x00512E, 0x000000, 0xFFFFFF, + 0x005130, 0x005131, 0x000000, 0xFFFFFF, + 0x005133, 0x005135, 0x000000, 0xFFFFFF, + 0x005139, 0x005139, 0x000000, 0xFFFFFF, + 0x00513D, 0x00513D, 0x000000, 0xFFFFFF, + 0x005159, 0x005159, 0x000000, 0xFFFFFF, + 0x00515B, 0x00515B, 0x000000, 0xFFFFFF, + 0x00515D, 0x00515F, 0x000000, 0xFFFFFF, + 0x005161, 0x005161, 0x000000, 0xFFFFFF, + 0x005163, 0x005163, 0x000000, 0xFFFFFF, + 0x005187, 0x005187, 0x000000, 0xFFFFFF, + 0x00518F, 0x00518F, 0x000000, 0xFFFFFF, + 0x005193, 0x005194, 0x000000, 0xFFFFFF, + 0x005198, 0x005198, 0x000000, 0xFFFFFF, + 0x00519E, 0x00519E, 0x000000, 0xFFFFFF, + 0x0051B9, 0x0051B9, 0x000000, 0xFFFFFF, + 0x0051BE, 0x0051BE, 0x000000, 0xFFFFFF, + 0x0051CA, 0x0051CA, 0x000000, 0xFFFFFF, + 0x0051CE, 0x0051CE, 0x000000, 0xFFFFFF, + 0x0051D0, 0x0051D0, 0x000000, 0xFFFFFF, + 0x0051D4, 0x0051D4, 0x000000, 0xFFFFFF, + 0x0051D7, 0x0051D8, 0x000000, 0xFFFFFF, + 0x0051DE, 0x0051DE, 0x000000, 0xFFFFFF, + 0x005209, 0x005209, 0x000000, 0xFFFFFF, + 0x00520C, 0x00520C, 0x000000, 0xFFFFFF, + 0x005210, 0x005210, 0x000000, 0xFFFFFF, + 0x005213, 0x005213, 0x000000, 0xFFFFFF, + 0x00521C, 0x00521C, 0x000000, 0xFFFFFF, + 0x00521E, 0x00521E, 0x000000, 0xFFFFFF, + 0x005221, 0x005221, 0x000000, 0xFFFFFF, + 0x005231, 0x005232, 0x000000, 0xFFFFFF, + 0x005235, 0x005235, 0x000000, 0xFFFFFF, + 0x005246, 0x005246, 0x000000, 0xFFFFFF, + 0x005252, 0x005252, 0x000000, 0xFFFFFF, + 0x005255, 0x005255, 0x000000, 0xFFFFFF, + 0x00525A, 0x00525A, 0x000000, 0xFFFFFF, + 0x00525F, 0x00525F, 0x000000, 0xFFFFFF, + 0x005262, 0x005262, 0x000000, 0xFFFFFF, + 0x00526B, 0x00526D, 0x000000, 0xFFFFFF, + 0x005278, 0x005278, 0x000000, 0xFFFFFF, + 0x00527A, 0x00527C, 0x000000, 0xFFFFFF, + 0x005280, 0x005280, 0x000000, 0xFFFFFF, + 0x00528B, 0x00528B, 0x000000, 0xFFFFFF, + 0x005296, 0x005299, 0x000000, 0xFFFFFF, + 0x0052A6, 0x0052A6, 0x000000, 0xFFFFFF, + 0x0052AE, 0x0052AE, 0x000000, 0xFFFFFF, + 0x0052BC, 0x0052BC, 0x000000, 0xFFFFFF, + 0x0052C0, 0x0052C0, 0x000000, 0xFFFFFF, + 0x0052C2, 0x0052C2, 0x000000, 0xFFFFFF, + 0x0052CD, 0x0052CD, 0x000000, 0xFFFFFF, + 0x0052D3, 0x0052D3, 0x000000, 0xFFFFFF, + 0x0052E9, 0x0052E9, 0x000000, 0xFFFFFF, + 0x0052EB, 0x0052EB, 0x000000, 0xFFFFFF, + 0x0052EF, 0x0052EF, 0x000000, 0xFFFFFF, + 0x0052F4, 0x0052F4, 0x000000, 0xFFFFFF, + 0x0052F7, 0x0052F7, 0x000000, 0xFFFFFF, + 0x0052FC, 0x0052FC, 0x000000, 0xFFFFFF, + 0x005309, 0x00530A, 0x000000, 0xFFFFFF, + 0x00530E, 0x00530E, 0x000000, 0xFFFFFF, + 0x005311, 0x005312, 0x000000, 0xFFFFFF, + 0x00531C, 0x00531C, 0x000000, 0xFFFFFF, + 0x00531F, 0x00531F, 0x000000, 0xFFFFFF, + 0x005322, 0x005322, 0x000000, 0xFFFFFF, + 0x005330, 0x005330, 0x000000, 0xFFFFFF, + 0x005334, 0x005334, 0x000000, 0xFFFFFF, + 0x005337, 0x005337, 0x000000, 0xFFFFFF, + 0x00533C, 0x00533D, 0x000000, 0xFFFFFF, + 0x00534C, 0x00534D, 0x000000, 0xFFFFFF, + 0x005372, 0x005372, 0x000000, 0xFFFFFF, + 0x00537C, 0x00537C, 0x000000, 0xFFFFFF, + 0x00538A, 0x00538A, 0x000000, 0xFFFFFF, + 0x00538E, 0x00538F, 0x000000, 0xFFFFFF, + 0x005392, 0x005392, 0x000000, 0xFFFFFF, + 0x005394, 0x005394, 0x000000, 0xFFFFFF, + 0x005396, 0x005397, 0x000000, 0xFFFFFF, + 0x00539C, 0x00539C, 0x000000, 0xFFFFFF, + 0x00539E, 0x00539E, 0x000000, 0xFFFFFF, + 0x0053A4, 0x0053A4, 0x000000, 0xFFFFFF, + 0x0053A7, 0x0053A7, 0x000000, 0xFFFFFF, + 0x0053AC, 0x0053AC, 0x000000, 0xFFFFFF, + 0x0053B9, 0x0053B9, 0x000000, 0xFFFFFF, + 0x005407, 0x005407, 0x000000, 0xFFFFFF, + 0x005418, 0x005419, 0x000000, 0xFFFFFF, + 0x00541C, 0x00541C, 0x000000, 0xFFFFFF, + 0x005424, 0x005425, 0x000000, 0xFFFFFF, + 0x00542A, 0x00542A, 0x000000, 0xFFFFFF, + 0x005430, 0x005430, 0x000000, 0xFFFFFF, + 0x005437, 0x005437, 0x000000, 0xFFFFFF, + 0x00543D, 0x00543D, 0x000000, 0xFFFFFF, + 0x005441, 0x005441, 0x000000, 0xFFFFFF, + 0x005445, 0x005445, 0x000000, 0xFFFFFF, + 0x005447, 0x005447, 0x000000, 0xFFFFFF, + 0x00544F, 0x00544F, 0x000000, 0xFFFFFF, + 0x005460, 0x005461, 0x000000, 0xFFFFFF, + 0x005463, 0x005463, 0x000000, 0xFFFFFF, + 0x005465, 0x005465, 0x000000, 0xFFFFFF, + 0x005467, 0x005467, 0x000000, 0xFFFFFF, + 0x00546B, 0x00546C, 0x000000, 0xFFFFFF, + 0x00546F, 0x005470, 0x000000, 0xFFFFFF, + 0x005474, 0x005474, 0x000000, 0xFFFFFF, + 0x00547A, 0x00547A, 0x000000, 0xFFFFFF, + 0x00547E, 0x00547F, 0x000000, 0xFFFFFF, + 0x005481, 0x005481, 0x000000, 0xFFFFFF, + 0x005487, 0x005488, 0x000000, 0xFFFFFF, + 0x00548D, 0x00548D, 0x000000, 0xFFFFFF, + 0x005491, 0x005491, 0x000000, 0xFFFFFF, + 0x005498, 0x005498, 0x000000, 0xFFFFFF, + 0x0054A0, 0x0054A2, 0x000000, 0xFFFFFF, + 0x0054A5, 0x0054A5, 0x000000, 0xFFFFFF, + 0x0054AE, 0x0054AE, 0x000000, 0xFFFFFF, + 0x0054B0, 0x0054B0, 0x000000, 0xFFFFFF, + 0x0054B6, 0x0054B6, 0x000000, 0xFFFFFF, + 0x0054BA, 0x0054BA, 0x000000, 0xFFFFFF, + 0x0054BE, 0x0054BE, 0x000000, 0xFFFFFF, + 0x0054C3, 0x0054C3, 0x000000, 0xFFFFFF, + 0x0054C5, 0x0054C5, 0x000000, 0xFFFFFF, + 0x0054D6, 0x0054D6, 0x000000, 0xFFFFFF, + 0x0054E0, 0x0054E0, 0x000000, 0xFFFFFF, + 0x0054E2, 0x0054E2, 0x000000, 0xFFFFFF, + 0x0054E4, 0x0054E4, 0x000000, 0xFFFFFF, + 0x0054EB, 0x0054EB, 0x000000, 0xFFFFFF, + 0x0054F1, 0x0054F1, 0x000000, 0xFFFFFF, + 0x0054F7, 0x0054F8, 0x000000, 0xFFFFFF, + 0x0054FB, 0x0054FB, 0x000000, 0xFFFFFF, + 0x005503, 0x005503, 0x000000, 0xFFFFFF, + 0x005505, 0x005505, 0x000000, 0xFFFFFF, + 0x005508, 0x005508, 0x000000, 0xFFFFFF, + 0x00550A, 0x00550C, 0x000000, 0xFFFFFF, + 0x00550E, 0x00550E, 0x000000, 0xFFFFFF, + 0x005512, 0x005512, 0x000000, 0xFFFFFF, + 0x005517, 0x005517, 0x000000, 0xFFFFFF, + 0x00551A, 0x00551A, 0x000000, 0xFFFFFF, + 0x005526, 0x005526, 0x000000, 0xFFFFFF, + 0x00552D, 0x00552D, 0x000000, 0xFFFFFF, + 0x005532, 0x005532, 0x000000, 0xFFFFFF, + 0x005534, 0x005536, 0x000000, 0xFFFFFF, + 0x005539, 0x005539, 0x000000, 0xFFFFFF, + 0x00553B, 0x00553B, 0x000000, 0xFFFFFF, + 0x005540, 0x005540, 0x000000, 0xFFFFFF, + 0x005545, 0x005545, 0x000000, 0xFFFFFF, + 0x005548, 0x005548, 0x000000, 0xFFFFFF, + 0x00554B, 0x00554B, 0x000000, 0xFFFFFF, + 0x00554D, 0x00554E, 0x000000, 0xFFFFFF, + 0x005551, 0x005552, 0x000000, 0xFFFFFF, + 0x005562, 0x005562, 0x000000, 0xFFFFFF, + 0x00557D, 0x00557D, 0x000000, 0xFFFFFF, + 0x00557F, 0x00557F, 0x000000, 0xFFFFFF, + 0x00558C, 0x00558E, 0x000000, 0xFFFFFF, + 0x005592, 0x005593, 0x000000, 0xFFFFFF, + 0x005595, 0x005595, 0x000000, 0xFFFFFF, + 0x0055A1, 0x0055A6, 0x000000, 0xFFFFFF, + 0x0055A8, 0x0055A8, 0x000000, 0xFFFFFF, + 0x0055AD, 0x0055AD, 0x000000, 0xFFFFFF, + 0x0055BF, 0x0055C0, 0x000000, 0xFFFFFF, + 0x0055C2, 0x0055C3, 0x000000, 0xFFFFFF, + 0x0055C8, 0x0055C8, 0x000000, 0xFFFFFF, + 0x0055CA, 0x0055CB, 0x000000, 0xFFFFFF, + 0x0055CF, 0x0055D0, 0x000000, 0xFFFFFF, + 0x0055D5, 0x0055D5, 0x000000, 0xFFFFFF, + 0x0055D9, 0x0055D9, 0x000000, 0xFFFFFF, + 0x0055DB, 0x0055DB, 0x000000, 0xFFFFFF, + 0x0055E2, 0x0055E2, 0x000000, 0xFFFFFF, + 0x0055E7, 0x0055E7, 0x000000, 0xFFFFFF, + 0x0055F9, 0x0055FA, 0x000000, 0xFFFFFF, + 0x0055FC, 0x0055FC, 0x000000, 0xFFFFFF, + 0x0055FF, 0x0055FF, 0x000000, 0xFFFFFF, + 0x005602, 0x005602, 0x000000, 0xFFFFFF, + 0x005604, 0x005604, 0x000000, 0xFFFFFF, + 0x005610, 0x005610, 0x000000, 0xFFFFFF, + 0x005612, 0x005613, 0x000000, 0xFFFFFF, + 0x005615, 0x005615, 0x000000, 0xFFFFFF, + 0x00561D, 0x00561D, 0x000000, 0xFFFFFF, + 0x00562A, 0x00562A, 0x000000, 0xFFFFFF, + 0x005633, 0x005633, 0x000000, 0xFFFFFF, + 0x00563A, 0x00563A, 0x000000, 0xFFFFFF, + 0x00563D, 0x00563E, 0x000000, 0xFFFFFF, + 0x005640, 0x005640, 0x000000, 0xFFFFFF, + 0x005642, 0x005642, 0x000000, 0xFFFFFF, + 0x005645, 0x005646, 0x000000, 0xFFFFFF, + 0x005648, 0x00564A, 0x000000, 0xFFFFFF, + 0x00565A, 0x00565A, 0x000000, 0xFFFFFF, + 0x00565E, 0x00565E, 0x000000, 0xFFFFFF, + 0x005663, 0x005663, 0x000000, 0xFFFFFF, + 0x00566D, 0x00566E, 0x000000, 0xFFFFFF, + 0x005670, 0x005670, 0x000000, 0xFFFFFF, + 0x005673, 0x005673, 0x000000, 0xFFFFFF, + 0x005677, 0x005677, 0x000000, 0xFFFFFF, + 0x00567E, 0x00567F, 0x000000, 0xFFFFFF, + 0x005681, 0x005684, 0x000000, 0xFFFFFF, + 0x00568D, 0x00568D, 0x000000, 0xFFFFFF, + 0x005697, 0x005698, 0x000000, 0xFFFFFF, + 0x00569A, 0x00569A, 0x000000, 0xFFFFFF, + 0x00569C, 0x00569D, 0x000000, 0xFFFFFF, + 0x0056A7, 0x0056A7, 0x000000, 0xFFFFFF, + 0x0056AA, 0x0056AD, 0x000000, 0xFFFFFF, + 0x0056B2, 0x0056B2, 0x000000, 0xFFFFFF, + 0x0056B5, 0x0056B5, 0x000000, 0xFFFFFF, + 0x0056BD, 0x0056BE, 0x000000, 0xFFFFFF, + 0x0056C3, 0x0056C3, 0x000000, 0xFFFFFF, + 0x0056C6, 0x0056C6, 0x000000, 0xFFFFFF, + 0x0056CB, 0x0056CB, 0x000000, 0xFFFFFF, + 0x0056CD, 0x0056CD, 0x000000, 0xFFFFFF, + 0x0056E5, 0x0056E5, 0x000000, 0xFFFFFF, + 0x0056E7, 0x0056E7, 0x000000, 0xFFFFFF, + 0x0056EE, 0x0056EE, 0x000000, 0xFFFFFF, + 0x0056F7, 0x0056F7, 0x000000, 0xFFFFFF, + 0x005701, 0x005702, 0x000000, 0xFFFFFF, + 0x00570C, 0x00570C, 0x000000, 0xFFFFFF, + 0x005714, 0x005714, 0x000000, 0xFFFFFF, + 0x00571A, 0x00571B, 0x000000, 0xFFFFFF, + 0x00571E, 0x00571E, 0x000000, 0xFFFFFF, + 0x005720, 0x005720, 0x000000, 0xFFFFFF, + 0x005722, 0x005722, 0x000000, 0xFFFFFF, + 0x005734, 0x005734, 0x000000, 0xFFFFFF, + 0x005741, 0x005741, 0x000000, 0xFFFFFF, + 0x005745, 0x005745, 0x000000, 0xFFFFFF, + 0x005749, 0x005749, 0x000000, 0xFFFFFF, + 0x00574B, 0x00574B, 0x000000, 0xFFFFFF, + 0x005752, 0x005752, 0x000000, 0xFFFFFF, + 0x005762, 0x005762, 0x000000, 0xFFFFFF, + 0x005770, 0x005772, 0x000000, 0xFFFFFF, + 0x005774, 0x005774, 0x000000, 0xFFFFFF, + 0x00577D, 0x00577D, 0x000000, 0xFFFFFF, + 0x005780, 0x005780, 0x000000, 0xFFFFFF, + 0x00578F, 0x00578F, 0x000000, 0xFFFFFF, + 0x005794, 0x005795, 0x000000, 0xFFFFFF, + 0x005797, 0x00579A, 0x000000, 0xFFFFFF, + 0x00579D, 0x00579F, 0x000000, 0xFFFFFF, + 0x0057A5, 0x0057A5, 0x000000, 0xFFFFFF, + 0x0057B5, 0x0057B6, 0x000000, 0xFFFFFF, + 0x0057B9, 0x0057BA, 0x000000, 0xFFFFFF, + 0x0057BC, 0x0057BD, 0x000000, 0xFFFFFF, + 0x0057BF, 0x0057BF, 0x000000, 0xFFFFFF, + 0x0057C1, 0x0057C1, 0x000000, 0xFFFFFF, + 0x0057C6, 0x0057C7, 0x000000, 0xFFFFFF, + 0x0057CC, 0x0057CC, 0x000000, 0xFFFFFF, + 0x0057D0, 0x0057D0, 0x000000, 0xFFFFFF, + 0x0057E2, 0x0057E3, 0x000000, 0xFFFFFF, + 0x0057E5, 0x0057E5, 0x000000, 0xFFFFFF, + 0x0057E7, 0x0057E7, 0x000000, 0xFFFFFF, + 0x0057E9, 0x0057E9, 0x000000, 0xFFFFFF, + 0x0057EC, 0x0057EC, 0x000000, 0xFFFFFF, + 0x0057EE, 0x0057EE, 0x000000, 0xFFFFFF, + 0x0057F0, 0x0057F3, 0x000000, 0xFFFFFF, + 0x0057F5, 0x0057F6, 0x000000, 0xFFFFFF, + 0x0057FB, 0x0057FB, 0x000000, 0xFFFFFF, + 0x005801, 0x005801, 0x000000, 0xFFFFFF, + 0x005804, 0x005804, 0x000000, 0xFFFFFF, + 0x005808, 0x005809, 0x000000, 0xFFFFFF, + 0x00580C, 0x00580C, 0x000000, 0xFFFFFF, + 0x00580E, 0x00580E, 0x000000, 0xFFFFFF, + 0x005810, 0x005810, 0x000000, 0xFFFFFF, + 0x005814, 0x005814, 0x000000, 0xFFFFFF, + 0x00581B, 0x00581C, 0x000000, 0xFFFFFF, + 0x005823, 0x005823, 0x000000, 0xFFFFFF, + 0x005825, 0x005825, 0x000000, 0xFFFFFF, + 0x005827, 0x005829, 0x000000, 0xFFFFFF, + 0x00582C, 0x00582E, 0x000000, 0xFFFFFF, + 0x005832, 0x005833, 0x000000, 0xFFFFFF, + 0x005836, 0x005839, 0x000000, 0xFFFFFF, + 0x00583B, 0x00583B, 0x000000, 0xFFFFFF, + 0x00583D, 0x00583D, 0x000000, 0xFFFFFF, + 0x005848, 0x005849, 0x000000, 0xFFFFFF, + 0x00584E, 0x00584E, 0x000000, 0xFFFFFF, + 0x005853, 0x005853, 0x000000, 0xFFFFFF, + 0x005855, 0x005855, 0x000000, 0xFFFFFF, + 0x005859, 0x005859, 0x000000, 0xFFFFFF, + 0x00585B, 0x00585B, 0x000000, 0xFFFFFF, + 0x00585D, 0x00585D, 0x000000, 0xFFFFFF, + 0x005863, 0x005863, 0x000000, 0xFFFFFF, + 0x005868, 0x005868, 0x000000, 0xFFFFFF, + 0x00586D, 0x00586D, 0x000000, 0xFFFFFF, + 0x00586F, 0x00586F, 0x000000, 0xFFFFFF, + 0x005871, 0x005871, 0x000000, 0xFFFFFF, + 0x005874, 0x005874, 0x000000, 0xFFFFFF, + 0x005876, 0x005876, 0x000000, 0xFFFFFF, + 0x00587A, 0x00587D, 0x000000, 0xFFFFFF, + 0x00587F, 0x00587F, 0x000000, 0xFFFFFF, + 0x005882, 0x005882, 0x000000, 0xFFFFFF, + 0x005886, 0x005888, 0x000000, 0xFFFFFF, + 0x00588B, 0x00588B, 0x000000, 0xFFFFFF, + 0x00588E, 0x005890, 0x000000, 0xFFFFFF, + 0x005894, 0x005894, 0x000000, 0xFFFFFF, + 0x005898, 0x005898, 0x000000, 0xFFFFFF, + 0x00589D, 0x00589D, 0x000000, 0xFFFFFF, + 0x0058A0, 0x0058A1, 0x000000, 0xFFFFFF, + 0x0058A3, 0x0058A3, 0x000000, 0xFFFFFF, + 0x0058A5, 0x0058A6, 0x000000, 0xFFFFFF, + 0x0058AC, 0x0058AC, 0x000000, 0xFFFFFF, + 0x0058AF, 0x0058AF, 0x000000, 0xFFFFFF, + 0x0058B1, 0x0058B1, 0x000000, 0xFFFFFF, + 0x0058BA, 0x0058BA, 0x000000, 0xFFFFFF, + 0x0058BD, 0x0058BD, 0x000000, 0xFFFFFF, + 0x0058BF, 0x0058BF, 0x000000, 0xFFFFFF, + 0x0058C2, 0x0058C2, 0x000000, 0xFFFFFF, + 0x0058C6, 0x0058C6, 0x000000, 0xFFFFFF, + 0x0058C8, 0x0058C9, 0x000000, 0xFFFFFF, + 0x0058CF, 0x0058CF, 0x000000, 0xFFFFFF, + 0x0058D2, 0x0058D2, 0x000000, 0xFFFFFF, + 0x0058D4, 0x0058D4, 0x000000, 0xFFFFFF, + 0x0058D6, 0x0058D6, 0x000000, 0xFFFFFF, + 0x0058DB, 0x0058DB, 0x000000, 0xFFFFFF, + 0x0058DD, 0x0058DD, 0x000000, 0xFFFFFF, + 0x0058E3, 0x0058E3, 0x000000, 0xFFFFFF, + 0x0058E7, 0x0058E8, 0x000000, 0xFFFFFF, + 0x0058F4, 0x0058F4, 0x000000, 0xFFFFFF, + 0x0058FC, 0x0058FC, 0x000000, 0xFFFFFF, + 0x0058FE, 0x0058FF, 0x000000, 0xFFFFFF, + 0x005903, 0x005903, 0x000000, 0xFFFFFF, + 0x005906, 0x005906, 0x000000, 0xFFFFFF, + 0x00590C, 0x00590C, 0x000000, 0xFFFFFF, + 0x00590E, 0x00590E, 0x000000, 0xFFFFFF, + 0x005912, 0x005912, 0x000000, 0xFFFFFF, + 0x005917, 0x005917, 0x000000, 0xFFFFFF, + 0x00592C, 0x00592C, 0x000000, 0xFFFFFF, + 0x005940, 0x005940, 0x000000, 0xFFFFFF, + 0x005945, 0x005945, 0x000000, 0xFFFFFF, + 0x00594A, 0x00594A, 0x000000, 0xFFFFFF, + 0x005953, 0x005953, 0x000000, 0xFFFFFF, + 0x00595C, 0x00595C, 0x000000, 0xFFFFFF, + 0x005961, 0x005961, 0x000000, 0xFFFFFF, + 0x00596B, 0x00596B, 0x000000, 0xFFFFFF, + 0x00596D, 0x00596D, 0x000000, 0xFFFFFF, + 0x005970, 0x005972, 0x000000, 0xFFFFFF, + 0x005977, 0x005977, 0x000000, 0xFFFFFF, + 0x00597B, 0x00597C, 0x000000, 0xFFFFFF, + 0x00597E, 0x005980, 0x000000, 0xFFFFFF, + 0x005985, 0x005985, 0x000000, 0xFFFFFF, + 0x00598E, 0x005990, 0x000000, 0xFFFFFF, + 0x005998, 0x005998, 0x000000, 0xFFFFFF, + 0x0059A0, 0x0059A2, 0x000000, 0xFFFFFF, + 0x0059A6, 0x0059A7, 0x000000, 0xFFFFFF, + 0x0059B1, 0x0059B1, 0x000000, 0xFFFFFF, + 0x0059B4, 0x0059B6, 0x000000, 0xFFFFFF, + 0x0059BA, 0x0059BA, 0x000000, 0xFFFFFF, + 0x0059BC, 0x0059BD, 0x000000, 0xFFFFFF, + 0x0059C0, 0x0059C1, 0x000000, 0xFFFFFF, + 0x0059C3, 0x0059C3, 0x000000, 0xFFFFFF, + 0x0059C5, 0x0059C5, 0x000000, 0xFFFFFF, + 0x0059C7, 0x0059C8, 0x000000, 0xFFFFFF, + 0x0059CC, 0x0059CC, 0x000000, 0xFFFFFF, + 0x0059CE, 0x0059CF, 0x000000, 0xFFFFFF, + 0x0059D6, 0x0059D6, 0x000000, 0xFFFFFF, + 0x0059DB, 0x0059DB, 0x000000, 0xFFFFFF, + 0x0059DE, 0x0059DE, 0x000000, 0xFFFFFF, + 0x0059E0, 0x0059E1, 0x000000, 0xFFFFFF, + 0x0059E4, 0x0059E4, 0x000000, 0xFFFFFF, + 0x0059E9, 0x0059E9, 0x000000, 0xFFFFFF, + 0x0059ED, 0x0059EE, 0x000000, 0xFFFFFF, + 0x0059F1, 0x0059F7, 0x000000, 0xFFFFFF, + 0x0059FA, 0x0059FA, 0x000000, 0xFFFFFF, + 0x0059FC, 0x0059FE, 0x000000, 0xFFFFFF, + 0x005A00, 0x005A00, 0x000000, 0xFFFFFF, + 0x005A0A, 0x005A0A, 0x000000, 0xFFFFFF, + 0x005A0F, 0x005A0F, 0x000000, 0xFFFFFF, + 0x005A15, 0x005A17, 0x000000, 0xFFFFFF, + 0x005A19, 0x005A19, 0x000000, 0xFFFFFF, + 0x005A1E, 0x005A1E, 0x000000, 0xFFFFFF, + 0x005A2D, 0x005A2E, 0x000000, 0xFFFFFF, + 0x005A33, 0x005A33, 0x000000, 0xFFFFFF, + 0x005A35, 0x005A35, 0x000000, 0xFFFFFF, + 0x005A37, 0x005A39, 0x000000, 0xFFFFFF, + 0x005A3E, 0x005A3E, 0x000000, 0xFFFFFF, + 0x005A42, 0x005A44, 0x000000, 0xFFFFFF, + 0x005A47, 0x005A48, 0x000000, 0xFFFFFF, + 0x005A4C, 0x005A4D, 0x000000, 0xFFFFFF, + 0x005A50, 0x005A53, 0x000000, 0xFFFFFF, + 0x005A56, 0x005A58, 0x000000, 0xFFFFFF, + 0x005A5B, 0x005A60, 0x000000, 0xFFFFFF, + 0x005A64, 0x005A65, 0x000000, 0xFFFFFF, + 0x005A69, 0x005A69, 0x000000, 0xFFFFFF, + 0x005A70, 0x005A70, 0x000000, 0xFFFFFF, + 0x005A78, 0x005A78, 0x000000, 0xFFFFFF, + 0x005A7B, 0x005A7D, 0x000000, 0xFFFFFF, + 0x005A83, 0x005A84, 0x000000, 0xFFFFFF, + 0x005A8A, 0x005A8C, 0x000000, 0xFFFFFF, + 0x005A8E, 0x005A90, 0x000000, 0xFFFFFF, + 0x005A93, 0x005A95, 0x000000, 0xFFFFFF, + 0x005A97, 0x005A97, 0x000000, 0xFFFFFF, + 0x005A9C, 0x005A9F, 0x000000, 0xFFFFFF, + 0x005AA2, 0x005AA2, 0x000000, 0xFFFFFF, + 0x005AA5, 0x005AA6, 0x000000, 0xFFFFFF, + 0x005AA9, 0x005AA9, 0x000000, 0xFFFFFF, + 0x005AAC, 0x005AAC, 0x000000, 0xFFFFFF, + 0x005AB0, 0x005AB1, 0x000000, 0xFFFFFF, + 0x005AB4, 0x005AB4, 0x000000, 0xFFFFFF, + 0x005AB6, 0x005AB7, 0x000000, 0xFFFFFF, + 0x005AB9, 0x005ABB, 0x000000, 0xFFFFFF, + 0x005AC0, 0x005AC0, 0x000000, 0xFFFFFF, + 0x005AC4, 0x005AC4, 0x000000, 0xFFFFFF, + 0x005AC6, 0x005AC8, 0x000000, 0xFFFFFF, + 0x005ACA, 0x005ACA, 0x000000, 0xFFFFFF, + 0x005ACD, 0x005ACD, 0x000000, 0xFFFFFF, + 0x005AD5, 0x005AD5, 0x000000, 0xFFFFFF, + 0x005AD9, 0x005ADB, 0x000000, 0xFFFFFF, + 0x005ADD, 0x005ADF, 0x000000, 0xFFFFFF, + 0x005AE2, 0x005AE2, 0x000000, 0xFFFFFF, + 0x005AE5, 0x005AE5, 0x000000, 0xFFFFFF, + 0x005AE8, 0x005AE8, 0x000000, 0xFFFFFF, + 0x005AEA, 0x005AEA, 0x000000, 0xFFFFFF, + 0x005AEC, 0x005AEE, 0x000000, 0xFFFFFF, + 0x005AF3, 0x005AF4, 0x000000, 0xFFFFFF, + 0x005AF6, 0x005AFA, 0x000000, 0xFFFFFF, + 0x005AFD, 0x005AFD, 0x000000, 0xFFFFFF, + 0x005AFF, 0x005AFF, 0x000000, 0xFFFFFF, + 0x005B01, 0x005B03, 0x000000, 0xFFFFFF, + 0x005B05, 0x005B05, 0x000000, 0xFFFFFF, + 0x005B07, 0x005B07, 0x000000, 0xFFFFFF, + 0x005B0F, 0x005B10, 0x000000, 0xFFFFFF, + 0x005B13, 0x005B14, 0x000000, 0xFFFFFF, + 0x005B1A, 0x005B1B, 0x000000, 0xFFFFFF, + 0x005B1E, 0x005B1E, 0x000000, 0xFFFFFF, + 0x005B20, 0x005B20, 0x000000, 0xFFFFFF, + 0x005B23, 0x005B23, 0x000000, 0xFFFFFF, + 0x005B25, 0x005B28, 0x000000, 0xFFFFFF, + 0x005B2C, 0x005B2C, 0x000000, 0xFFFFFF, + 0x005B2E, 0x005B2F, 0x000000, 0xFFFFFF, + 0x005B3C, 0x005B3F, 0x000000, 0xFFFFFF, + 0x005B45, 0x005B45, 0x000000, 0xFFFFFF, + 0x005B47, 0x005B48, 0x000000, 0xFFFFFF, + 0x005B4B, 0x005B4B, 0x000000, 0xFFFFFF, + 0x005B4D, 0x005B4E, 0x000000, 0xFFFFFF, + 0x005B56, 0x005B56, 0x000000, 0xFFFFFF, + 0x005B6E, 0x005B6E, 0x000000, 0xFFFFFF, + 0x005B72, 0x005B72, 0x000000, 0xFFFFFF, + 0x005B77, 0x005B77, 0x000000, 0xFFFFFF, + 0x005B7B, 0x005B7B, 0x000000, 0xFFFFFF, + 0x005B8E, 0x005B8E, 0x000000, 0xFFFFFF, + 0x005B92, 0x005B92, 0x000000, 0xFFFFFF, + 0x005BA7, 0x005BA8, 0x000000, 0xFFFFFF, + 0x005BAC, 0x005BAD, 0x000000, 0xFFFFFF, + 0x005BC0, 0x005BC1, 0x000000, 0xFFFFFF, + 0x005BCA, 0x005BCB, 0x000000, 0xFFFFFF, + 0x005BCD, 0x005BCE, 0x000000, 0xFFFFFF, + 0x005BD1, 0x005BD1, 0x000000, 0xFFFFFF, + 0x005BD4, 0x005BD4, 0x000000, 0xFFFFFF, + 0x005BD6, 0x005BD6, 0x000000, 0xFFFFFF, + 0x005BD9, 0x005BD9, 0x000000, 0xFFFFFF, + 0x005BE0, 0x005BE0, 0x000000, 0xFFFFFF, + 0x005BE3, 0x005BE3, 0x000000, 0xFFFFFF, + 0x005BEA, 0x005BEA, 0x000000, 0xFFFFFF, + 0x005BEF, 0x005BEF, 0x000000, 0xFFFFFF, + 0x005BF1, 0x005BF2, 0x000000, 0xFFFFFF, + 0x005C03, 0x005C03, 0x000000, 0xFFFFFF, + 0x005C0C, 0x005C0C, 0x000000, 0xFFFFFF, + 0x005C10, 0x005C10, 0x000000, 0xFFFFFF, + 0x005C12, 0x005C12, 0x000000, 0xFFFFFF, + 0x005C1F, 0x005C1F, 0x000000, 0xFFFFFF, + 0x005C28, 0x005C28, 0x000000, 0xFFFFFF, + 0x005C2A, 0x005C2A, 0x000000, 0xFFFFFF, + 0x005C30, 0x005C30, 0x000000, 0xFFFFFF, + 0x005C33, 0x005C33, 0x000000, 0xFFFFFF, + 0x005C44, 0x005C44, 0x000000, 0xFFFFFF, + 0x005C47, 0x005C47, 0x000000, 0xFFFFFF, + 0x005C4C, 0x005C4C, 0x000000, 0xFFFFFF, + 0x005C54, 0x005C54, 0x000000, 0xFFFFFF, + 0x005C56, 0x005C56, 0x000000, 0xFFFFFF, + 0x005C58, 0x005C58, 0x000000, 0xFFFFFF, + 0x005C67, 0x005C67, 0x000000, 0xFFFFFF, + 0x005C69, 0x005C6A, 0x000000, 0xFFFFFF, + 0x005C6D, 0x005C6D, 0x000000, 0xFFFFFF, + 0x005C73, 0x005C74, 0x000000, 0xFFFFFF, + 0x005C7B, 0x005C7C, 0x000000, 0xFFFFFF, + 0x005C7E, 0x005C7E, 0x000000, 0xFFFFFF, + 0x005C86, 0x005C86, 0x000000, 0xFFFFFF, + 0x005C89, 0x005C8B, 0x000000, 0xFFFFFF, + 0x005C8F, 0x005C8F, 0x000000, 0xFFFFFF, + 0x005C92, 0x005C93, 0x000000, 0xFFFFFF, + 0x005C95, 0x005C95, 0x000000, 0xFFFFFF, + 0x005C9D, 0x005C9D, 0x000000, 0xFFFFFF, + 0x005C9F, 0x005CA0, 0x000000, 0xFFFFFF, + 0x005CA4, 0x005CA8, 0x000000, 0xFFFFFF, + 0x005CAA, 0x005CAA, 0x000000, 0xFFFFFF, + 0x005CAE, 0x005CB0, 0x000000, 0xFFFFFF, + 0x005CB6, 0x005CB6, 0x000000, 0xFFFFFF, + 0x005CC6, 0x005CCA, 0x000000, 0xFFFFFF, + 0x005CCC, 0x005CCC, 0x000000, 0xFFFFFF, + 0x005CCE, 0x005CD0, 0x000000, 0xFFFFFF, + 0x005CD3, 0x005CD4, 0x000000, 0xFFFFFF, + 0x005CD6, 0x005CD8, 0x000000, 0xFFFFFF, + 0x005CDA, 0x005CDB, 0x000000, 0xFFFFFF, + 0x005CDE, 0x005CDF, 0x000000, 0xFFFFFF, + 0x005CEC, 0x005CEC, 0x000000, 0xFFFFFF, + 0x005CEE, 0x005CEE, 0x000000, 0xFFFFFF, + 0x005CF1, 0x005CF1, 0x000000, 0xFFFFFF, + 0x005CF7, 0x005CF9, 0x000000, 0xFFFFFF, + 0x005CFF, 0x005D01, 0x000000, 0xFFFFFF, + 0x005D0B, 0x005D0C, 0x000000, 0xFFFFFF, + 0x005D0F, 0x005D0F, 0x000000, 0xFFFFFF, + 0x005D12, 0x005D12, 0x000000, 0xFFFFFF, + 0x005D1A, 0x005D1A, 0x000000, 0xFFFFFF, + 0x005D1D, 0x005D1D, 0x000000, 0xFFFFFF, + 0x005D1F, 0x005D1F, 0x000000, 0xFFFFFF, + 0x005D23, 0x005D23, 0x000000, 0xFFFFFF, + 0x005D25, 0x005D25, 0x000000, 0xFFFFFF, + 0x005D28, 0x005D28, 0x000000, 0xFFFFFF, + 0x005D30, 0x005D32, 0x000000, 0xFFFFFF, + 0x005D35, 0x005D3A, 0x000000, 0xFFFFFF, + 0x005D3C, 0x005D3C, 0x000000, 0xFFFFFF, + 0x005D3F, 0x005D43, 0x000000, 0xFFFFFF, + 0x005D45, 0x005D45, 0x000000, 0xFFFFFF, + 0x005D49, 0x005D49, 0x000000, 0xFFFFFF, + 0x005D4E, 0x005D4E, 0x000000, 0xFFFFFF, + 0x005D51, 0x005D51, 0x000000, 0xFFFFFF, + 0x005D55, 0x005D55, 0x000000, 0xFFFFFF, + 0x005D59, 0x005D59, 0x000000, 0xFFFFFF, + 0x005D5E, 0x005D5E, 0x000000, 0xFFFFFF, + 0x005D62, 0x005D63, 0x000000, 0xFFFFFF, + 0x005D65, 0x005D65, 0x000000, 0xFFFFFF, + 0x005D67, 0x005D68, 0x000000, 0xFFFFFF, + 0x005D71, 0x005D72, 0x000000, 0xFFFFFF, + 0x005D77, 0x005D77, 0x000000, 0xFFFFFF, + 0x005D79, 0x005D7A, 0x000000, 0xFFFFFF, + 0x005D7C, 0x005D80, 0x000000, 0xFFFFFF, + 0x005D86, 0x005D86, 0x000000, 0xFFFFFF, + 0x005D88, 0x005D8A, 0x000000, 0xFFFFFF, + 0x005D8D, 0x005D8D, 0x000000, 0xFFFFFF, + 0x005D92, 0x005D95, 0x000000, 0xFFFFFF, + 0x005D9A, 0x005D9A, 0x000000, 0xFFFFFF, + 0x005D9C, 0x005D9C, 0x000000, 0xFFFFFF, + 0x005D9E, 0x005D9F, 0x000000, 0xFFFFFF, + 0x005DA1, 0x005DA2, 0x000000, 0xFFFFFF, + 0x005DA8, 0x005DAA, 0x000000, 0xFFFFFF, + 0x005DAC, 0x005DB2, 0x000000, 0xFFFFFF, + 0x005DB4, 0x005DB5, 0x000000, 0xFFFFFF, + 0x005DC0, 0x005DC0, 0x000000, 0xFFFFFF, + 0x005DC2, 0x005DC3, 0x000000, 0xFFFFFF, + 0x005DC6, 0x005DC7, 0x000000, 0xFFFFFF, + 0x005DC9, 0x005DC9, 0x000000, 0xFFFFFF, + 0x005DCF, 0x005DCF, 0x000000, 0xFFFFFF, + 0x005DD1, 0x005DD1, 0x000000, 0xFFFFFF, + 0x005DD5, 0x005DD5, 0x000000, 0xFFFFFF, + 0x005DD8, 0x005DD8, 0x000000, 0xFFFFFF, + 0x005DDF, 0x005DE0, 0x000000, 0xFFFFFF, + 0x005DFF, 0x005DFF, 0x000000, 0xFFFFFF, + 0x005E04, 0x005E04, 0x000000, 0xFFFFFF, + 0x005E0A, 0x005E0A, 0x000000, 0xFFFFFF, + 0x005E0E, 0x005E0E, 0x000000, 0xFFFFFF, + 0x005E17, 0x005E17, 0x000000, 0xFFFFFF, + 0x005E1F, 0x005E24, 0x000000, 0xFFFFFF, + 0x005E28, 0x005E29, 0x000000, 0xFFFFFF, + 0x005E34, 0x005E34, 0x000000, 0xFFFFFF, + 0x005E3E, 0x005E3E, 0x000000, 0xFFFFFF, + 0x005E41, 0x005E41, 0x000000, 0xFFFFFF, + 0x005E4A, 0x005E4B, 0x000000, 0xFFFFFF, + 0x005E4D, 0x005E4F, 0x000000, 0xFFFFFF, + 0x005E53, 0x005E53, 0x000000, 0xFFFFFF, + 0x005E59, 0x005E59, 0x000000, 0xFFFFFF, + 0x005E5C, 0x005E5D, 0x000000, 0xFFFFFF, + 0x005E60, 0x005E60, 0x000000, 0xFFFFFF, + 0x005E66, 0x005E6A, 0x000000, 0xFFFFFF, + 0x005E6D, 0x005E70, 0x000000, 0xFFFFFF, + 0x005E88, 0x005E89, 0x000000, 0xFFFFFF, + 0x005E8C, 0x005E8D, 0x000000, 0xFFFFFF, + 0x005E9B, 0x005E9B, 0x000000, 0xFFFFFF, + 0x005EA2, 0x005EA4, 0x000000, 0xFFFFFF, + 0x005EA8, 0x005EA8, 0x000000, 0xFFFFFF, + 0x005EAA, 0x005EAA, 0x000000, 0xFFFFFF, + 0x005EAC, 0x005EAC, 0x000000, 0xFFFFFF, + 0x005EAE, 0x005EAE, 0x000000, 0xFFFFFF, + 0x005EB0, 0x005EB2, 0x000000, 0xFFFFFF, + 0x005EB4, 0x005EB4, 0x000000, 0xFFFFFF, + 0x005EC5, 0x005EC7, 0x000000, 0xFFFFFF, + 0x005ECB, 0x005ECC, 0x000000, 0xFFFFFF, + 0x005ECE, 0x005ECE, 0x000000, 0xFFFFFF, + 0x005ED4, 0x005ED5, 0x000000, 0xFFFFFF, + 0x005ED7, 0x005ED9, 0x000000, 0xFFFFFF, + 0x005EDC, 0x005EDC, 0x000000, 0xFFFFFF, + 0x005EDE, 0x005EDE, 0x000000, 0xFFFFFF, + 0x005EE5, 0x005EE7, 0x000000, 0xFFFFFF, + 0x005EEE, 0x005EEF, 0x000000, 0xFFFFFF, + 0x005EF2, 0x005EF2, 0x000000, 0xFFFFFF, + 0x005F05, 0x005F05, 0x000000, 0xFFFFFF, + 0x005F07, 0x005F07, 0x000000, 0xFFFFFF, + 0x005F1A, 0x005F1A, 0x000000, 0xFFFFFF, + 0x005F1D, 0x005F1D, 0x000000, 0xFFFFFF, + 0x005F22, 0x005F24, 0x000000, 0xFFFFFF, + 0x005F28, 0x005F28, 0x000000, 0xFFFFFF, + 0x005F2E, 0x005F2E, 0x000000, 0xFFFFFF, + 0x005F30, 0x005F30, 0x000000, 0xFFFFFF, + 0x005F36, 0x005F36, 0x000000, 0xFFFFFF, + 0x005F38, 0x005F38, 0x000000, 0xFFFFFF, + 0x005F43, 0x005F44, 0x000000, 0xFFFFFF, + 0x005F49, 0x005F49, 0x000000, 0xFFFFFF, + 0x005F4B, 0x005F4B, 0x000000, 0xFFFFFF, + 0x005F4F, 0x005F4F, 0x000000, 0xFFFFFF, + 0x005F54, 0x005F54, 0x000000, 0xFFFFFF, + 0x005F67, 0x005F67, 0x000000, 0xFFFFFF, + 0x005F6F, 0x005F6F, 0x000000, 0xFFFFFF, + 0x005F74, 0x005F74, 0x000000, 0xFFFFFF, + 0x005F76, 0x005F76, 0x000000, 0xFFFFFF, + 0x005F78, 0x005F78, 0x000000, 0xFFFFFF, + 0x005F7D, 0x005F7E, 0x000000, 0xFFFFFF, + 0x005F86, 0x005F86, 0x000000, 0xFFFFFF, + 0x005F96, 0x005F96, 0x000000, 0xFFFFFF, + 0x005F9B, 0x005F9B, 0x000000, 0xFFFFFF, + 0x005F9F, 0x005F9F, 0x000000, 0xFFFFFF, + 0x005FA5, 0x005FA6, 0x000000, 0xFFFFFF, + 0x005FAB, 0x005FAB, 0x000000, 0xFFFFFF, + 0x005FAF, 0x005FAF, 0x000000, 0xFFFFFF, + 0x005FB2, 0x005FB2, 0x000000, 0xFFFFFF, + 0x005FB6, 0x005FB6, 0x000000, 0xFFFFFF, + 0x005FBB, 0x005FBB, 0x000000, 0xFFFFFF, + 0x005FBE, 0x005FC1, 0x000000, 0xFFFFFF, + 0x005FD4, 0x005FD5, 0x000000, 0xFFFFFF, + 0x005FDE, 0x005FDE, 0x000000, 0xFFFFFF, + 0x005FE3, 0x005FE3, 0x000000, 0xFFFFFF, + 0x005FE5, 0x005FE5, 0x000000, 0xFFFFFF, + 0x005FE8, 0x005FE8, 0x000000, 0xFFFFFF, + 0x005FEF, 0x005FEF, 0x000000, 0xFFFFFF, + 0x005FF3, 0x005FF4, 0x000000, 0xFFFFFF, + 0x005FF7, 0x005FF7, 0x000000, 0xFFFFFF, + 0x005FFA, 0x005FFA, 0x000000, 0xFFFFFF, + 0x006009, 0x006009, 0x000000, 0xFFFFFF, + 0x00600B, 0x00600C, 0x000000, 0xFFFFFF, + 0x006010, 0x006011, 0x000000, 0xFFFFFF, + 0x006013, 0x006013, 0x000000, 0xFFFFFF, + 0x006017, 0x006017, 0x000000, 0xFFFFFF, + 0x00601A, 0x00601A, 0x000000, 0xFFFFFF, + 0x00601E, 0x00601E, 0x000000, 0xFFFFFF, + 0x006022, 0x006022, 0x000000, 0xFFFFFF, + 0x006024, 0x006024, 0x000000, 0xFFFFFF, + 0x00602C, 0x00602E, 0x000000, 0xFFFFFF, + 0x006032, 0x006034, 0x000000, 0xFFFFFF, + 0x006037, 0x006037, 0x000000, 0xFFFFFF, + 0x006039, 0x006039, 0x000000, 0xFFFFFF, + 0x006040, 0x006040, 0x000000, 0xFFFFFF, + 0x006044, 0x006045, 0x000000, 0xFFFFFF, + 0x006047, 0x006047, 0x000000, 0xFFFFFF, + 0x006049, 0x006049, 0x000000, 0xFFFFFF, + 0x00604C, 0x00604C, 0x000000, 0xFFFFFF, + 0x006053, 0x006054, 0x000000, 0xFFFFFF, + 0x006058, 0x006058, 0x000000, 0xFFFFFF, + 0x00605B, 0x00605B, 0x000000, 0xFFFFFF, + 0x00605E, 0x00605F, 0x000000, 0xFFFFFF, + 0x006066, 0x006066, 0x000000, 0xFFFFFF, + 0x00606E, 0x00606E, 0x000000, 0xFFFFFF, + 0x006072, 0x006072, 0x000000, 0xFFFFFF, + 0x006080, 0x006081, 0x000000, 0xFFFFFF, + 0x006086, 0x006088, 0x000000, 0xFFFFFF, + 0x00608A, 0x00608A, 0x000000, 0xFFFFFF, + 0x00608E, 0x00608E, 0x000000, 0xFFFFFF, + 0x006090, 0x006090, 0x000000, 0xFFFFFF, + 0x006095, 0x006095, 0x000000, 0xFFFFFF, + 0x006097, 0x006097, 0x000000, 0xFFFFFF, + 0x00609C, 0x00609C, 0x000000, 0xFFFFFF, + 0x0060A2, 0x0060A2, 0x000000, 0xFFFFFF, + 0x0060B0, 0x0060B0, 0x000000, 0xFFFFFF, + 0x0060B7, 0x0060B7, 0x000000, 0xFFFFFF, + 0x0060B9, 0x0060BA, 0x000000, 0xFFFFFF, + 0x0060BE, 0x0060C1, 0x000000, 0xFFFFFF, + 0x0060C3, 0x0060C4, 0x000000, 0xFFFFFF, + 0x0060C8, 0x0060C9, 0x000000, 0xFFFFFF, + 0x0060CC, 0x0060CF, 0x000000, 0xFFFFFF, + 0x0060D3, 0x0060D4, 0x000000, 0xFFFFFF, + 0x0060D9, 0x0060D9, 0x000000, 0xFFFFFF, + 0x0060DB, 0x0060DB, 0x000000, 0xFFFFFF, + 0x0060E2, 0x0060E2, 0x000000, 0xFFFFFF, + 0x0060E4, 0x0060E4, 0x000000, 0xFFFFFF, + 0x0060F5, 0x0060F5, 0x000000, 0xFFFFFF, + 0x0060F8, 0x0060F8, 0x000000, 0xFFFFFF, + 0x0060FC, 0x0060FC, 0x000000, 0xFFFFFF, + 0x0060FE, 0x0060FF, 0x000000, 0xFFFFFF, + 0x006103, 0x006105, 0x000000, 0xFFFFFF, + 0x00610A, 0x00610B, 0x000000, 0xFFFFFF, + 0x006110, 0x006110, 0x000000, 0xFFFFFF, + 0x006112, 0x006114, 0x000000, 0xFFFFFF, + 0x006116, 0x006116, 0x000000, 0xFFFFFF, + 0x006118, 0x006118, 0x000000, 0xFFFFFF, + 0x00611D, 0x00611D, 0x000000, 0xFFFFFF, + 0x006129, 0x006129, 0x000000, 0xFFFFFF, + 0x00612C, 0x00612C, 0x000000, 0xFFFFFF, + 0x00612E, 0x00612F, 0x000000, 0xFFFFFF, + 0x006132, 0x006132, 0x000000, 0xFFFFFF, + 0x006136, 0x006136, 0x000000, 0xFFFFFF, + 0x00613B, 0x00613B, 0x000000, 0xFFFFFF, + 0x006140, 0x006141, 0x000000, 0xFFFFFF, + 0x006145, 0x006146, 0x000000, 0xFFFFFF, + 0x006149, 0x006149, 0x000000, 0xFFFFFF, + 0x00614F, 0x00614F, 0x000000, 0xFFFFFF, + 0x006152, 0x006154, 0x000000, 0xFFFFFF, + 0x006156, 0x006156, 0x000000, 0xFFFFFF, + 0x00615B, 0x00615B, 0x000000, 0xFFFFFF, + 0x00615E, 0x00615E, 0x000000, 0xFFFFFF, + 0x006161, 0x006161, 0x000000, 0xFFFFFF, + 0x006165, 0x006166, 0x000000, 0xFFFFFF, + 0x00616C, 0x00616C, 0x000000, 0xFFFFFF, + 0x006171, 0x006172, 0x000000, 0xFFFFFF, + 0x006174, 0x006174, 0x000000, 0xFFFFFF, + 0x006179, 0x00617A, 0x000000, 0xFFFFFF, + 0x006180, 0x006180, 0x000000, 0xFFFFFF, + 0x006183, 0x006183, 0x000000, 0xFFFFFF, + 0x006189, 0x006189, 0x000000, 0xFFFFFF, + 0x00618C, 0x00618D, 0x000000, 0xFFFFFF, + 0x006193, 0x006193, 0x000000, 0xFFFFFF, + 0x006196, 0x006196, 0x000000, 0xFFFFFF, + 0x00619B, 0x00619B, 0x000000, 0xFFFFFF, + 0x00619F, 0x00619F, 0x000000, 0xFFFFFF, + 0x0061A1, 0x0061A2, 0x000000, 0xFFFFFF, + 0x0061AA, 0x0061AA, 0x000000, 0xFFFFFF, + 0x0061AD, 0x0061AD, 0x000000, 0xFFFFFF, + 0x0061AF, 0x0061B1, 0x000000, 0xFFFFFF, + 0x0061B3, 0x0061B5, 0x000000, 0xFFFFFF, + 0x0061B8, 0x0061B8, 0x000000, 0xFFFFFF, + 0x0061BA, 0x0061BA, 0x000000, 0xFFFFFF, + 0x0061BC, 0x0061BC, 0x000000, 0xFFFFFF, + 0x0061BF, 0x0061BF, 0x000000, 0xFFFFFF, + 0x0061C1, 0x0061C1, 0x000000, 0xFFFFFF, + 0x0061C5, 0x0061C6, 0x000000, 0xFFFFFF, + 0x0061D6, 0x0061D6, 0x000000, 0xFFFFFF, + 0x0061D8, 0x0061D8, 0x000000, 0xFFFFFF, + 0x0061E0, 0x0061E0, 0x000000, 0xFFFFFF, + 0x0061E4, 0x0061E5, 0x000000, 0xFFFFFF, + 0x0061E7, 0x0061E7, 0x000000, 0xFFFFFF, + 0x0061E9, 0x0061EB, 0x000000, 0xFFFFFF, + 0x0061ED, 0x0061EE, 0x000000, 0xFFFFFF, + 0x0061F0, 0x0061F1, 0x000000, 0xFFFFFF, + 0x0061F9, 0x0061F9, 0x000000, 0xFFFFFF, + 0x0061FB, 0x0061FB, 0x000000, 0xFFFFFF, + 0x0061FD, 0x0061FD, 0x000000, 0xFFFFFF, + 0x006201, 0x006201, 0x000000, 0xFFFFFF, + 0x006203, 0x006204, 0x000000, 0xFFFFFF, + 0x006219, 0x006219, 0x000000, 0xFFFFFF, + 0x006220, 0x006220, 0x000000, 0xFFFFFF, + 0x006223, 0x006223, 0x000000, 0xFFFFFF, + 0x00622B, 0x00622B, 0x000000, 0xFFFFFF, + 0x00622D, 0x00622D, 0x000000, 0xFFFFFF, + 0x00623A, 0x00623A, 0x000000, 0xFFFFFF, + 0x006242, 0x006242, 0x000000, 0xFFFFFF, + 0x006246, 0x006246, 0x000000, 0xFFFFFF, + 0x00624A, 0x00624A, 0x000000, 0xFFFFFF, + 0x006259, 0x00625A, 0x000000, 0xFFFFFF, + 0x00625C, 0x00625C, 0x000000, 0xFFFFFF, + 0x006260, 0x006262, 0x000000, 0xFFFFFF, + 0x006264, 0x006265, 0x000000, 0xFFFFFF, + 0x006272, 0x006272, 0x000000, 0xFFFFFF, + 0x006274, 0x006274, 0x000000, 0xFFFFFF, + 0x006277, 0x006277, 0x000000, 0xFFFFFF, + 0x00627B, 0x00627B, 0x000000, 0xFFFFFF, + 0x00627D, 0x00627D, 0x000000, 0xFFFFFF, + 0x006281, 0x006281, 0x000000, 0xFFFFFF, + 0x006286, 0x006288, 0x000000, 0xFFFFFF, + 0x00628C, 0x00628C, 0x000000, 0xFFFFFF, + 0x00628E, 0x00628F, 0x000000, 0xFFFFFF, + 0x0062A9, 0x0062AA, 0x000000, 0xFFFFFF, + 0x0062AD, 0x0062B0, 0x000000, 0xFFFFFF, + 0x0062B3, 0x0062B3, 0x000000, 0xFFFFFF, + 0x0062B6, 0x0062B6, 0x000000, 0xFFFFFF, + 0x0062B8, 0x0062B8, 0x000000, 0xFFFFFF, + 0x0062BE, 0x0062BE, 0x000000, 0xFFFFFF, + 0x0062CF, 0x0062CF, 0x000000, 0xFFFFFF, + 0x0062EB, 0x0062EB, 0x000000, 0xFFFFFF, + 0x0062F0, 0x0062F0, 0x000000, 0xFFFFFF, + 0x0062F2, 0x0062F2, 0x000000, 0xFFFFFF, + 0x0062F5, 0x0062F5, 0x000000, 0xFFFFFF, + 0x0062F8, 0x0062FB, 0x000000, 0xFFFFFF, + 0x006300, 0x006300, 0x000000, 0xFFFFFF, + 0x006303, 0x006303, 0x000000, 0xFFFFFF, + 0x00630B, 0x00630B, 0x000000, 0xFFFFFF, + 0x00630D, 0x00630D, 0x000000, 0xFFFFFF, + 0x00630F, 0x006310, 0x000000, 0xFFFFFF, + 0x006313, 0x006315, 0x000000, 0xFFFFFF, + 0x006329, 0x006329, 0x000000, 0xFFFFFF, + 0x00632C, 0x00632D, 0x000000, 0xFFFFFF, + 0x006333, 0x006334, 0x000000, 0xFFFFFF, + 0x006338, 0x006338, 0x000000, 0xFFFFFF, + 0x00633B, 0x00633C, 0x000000, 0xFFFFFF, + 0x006340, 0x006341, 0x000000, 0xFFFFFF, + 0x006344, 0x006344, 0x000000, 0xFFFFFF, + 0x006347, 0x006348, 0x000000, 0xFFFFFF, + 0x00634A, 0x00634A, 0x000000, 0xFFFFFF, + 0x006351, 0x006351, 0x000000, 0xFFFFFF, + 0x006354, 0x006354, 0x000000, 0xFFFFFF, + 0x006356, 0x00635A, 0x000000, 0xFFFFFF, + 0x006365, 0x006365, 0x000000, 0xFFFFFF, + 0x00636F, 0x006370, 0x000000, 0xFFFFFF, + 0x006375, 0x006375, 0x000000, 0xFFFFFF, + 0x006378, 0x006378, 0x000000, 0xFFFFFF, + 0x00637C, 0x00637D, 0x000000, 0xFFFFFF, + 0x006381, 0x006381, 0x000000, 0xFFFFFF, + 0x006385, 0x006385, 0x000000, 0xFFFFFF, + 0x00638D, 0x00638D, 0x000000, 0xFFFFFF, + 0x006391, 0x006391, 0x000000, 0xFFFFFF, + 0x006394, 0x006394, 0x000000, 0xFFFFFF, + 0x006397, 0x006397, 0x000000, 0xFFFFFF, + 0x00639C, 0x00639F, 0x000000, 0xFFFFFF, + 0x0063A4, 0x0063A4, 0x000000, 0xFFFFFF, + 0x0063AB, 0x0063AB, 0x000000, 0xFFFFFF, + 0x0063AF, 0x0063AF, 0x000000, 0xFFFFFF, + 0x0063B1, 0x0063B1, 0x000000, 0xFFFFFF, + 0x0063BD, 0x0063BD, 0x000000, 0xFFFFFF, + 0x0063C2, 0x0063C3, 0x000000, 0xFFFFFF, + 0x0063C5, 0x0063C5, 0x000000, 0xFFFFFF, + 0x0063C7, 0x0063C8, 0x000000, 0xFFFFFF, + 0x0063CA, 0x0063CC, 0x000000, 0xFFFFFF, + 0x0063D3, 0x0063D3, 0x000000, 0xFFFFFF, + 0x0063D5, 0x0063D5, 0x000000, 0xFFFFFF, + 0x0063D7, 0x0063D9, 0x000000, 0xFFFFFF, + 0x0063DC, 0x0063DD, 0x000000, 0xFFFFFF, + 0x0063DF, 0x0063DF, 0x000000, 0xFFFFFF, + 0x0063E4, 0x0063E5, 0x000000, 0xFFFFFF, + 0x0063E7, 0x0063E8, 0x000000, 0xFFFFFF, + 0x0063EB, 0x0063EB, 0x000000, 0xFFFFFF, + 0x0063EF, 0x0063F1, 0x000000, 0xFFFFFF, + 0x0063F3, 0x0063F3, 0x000000, 0xFFFFFF, + 0x0063F5, 0x0063F5, 0x000000, 0xFFFFFF, + 0x006409, 0x00640A, 0x000000, 0xFFFFFF, + 0x00640E, 0x00640E, 0x000000, 0xFFFFFF, + 0x006412, 0x006412, 0x000000, 0xFFFFFF, + 0x006415, 0x006415, 0x000000, 0xFFFFFF, + 0x006418, 0x006418, 0x000000, 0xFFFFFF, + 0x00641A, 0x00641A, 0x000000, 0xFFFFFF, + 0x006422, 0x006424, 0x000000, 0xFFFFFF, + 0x006427, 0x006427, 0x000000, 0xFFFFFF, + 0x00642B, 0x00642B, 0x000000, 0xFFFFFF, + 0x00642E, 0x00642E, 0x000000, 0xFFFFFF, + 0x006430, 0x006430, 0x000000, 0xFFFFFF, + 0x006433, 0x006433, 0x000000, 0xFFFFFF, + 0x006435, 0x006435, 0x000000, 0xFFFFFF, + 0x006437, 0x006437, 0x000000, 0xFFFFFF, + 0x006439, 0x006439, 0x000000, 0xFFFFFF, + 0x00644B, 0x00644B, 0x000000, 0xFFFFFF, + 0x00644D, 0x00644E, 0x000000, 0xFFFFFF, + 0x006450, 0x006450, 0x000000, 0xFFFFFF, + 0x006453, 0x006453, 0x000000, 0xFFFFFF, + 0x006459, 0x006459, 0x000000, 0xFFFFFF, + 0x00645B, 0x00645B, 0x000000, 0xFFFFFF, + 0x00645D, 0x00645D, 0x000000, 0xFFFFFF, + 0x006460, 0x006461, 0x000000, 0xFFFFFF, + 0x006465, 0x006466, 0x000000, 0xFFFFFF, + 0x006468, 0x006468, 0x000000, 0xFFFFFF, + 0x00646B, 0x00646C, 0x000000, 0xFFFFFF, + 0x00646E, 0x00646E, 0x000000, 0xFFFFFF, + 0x006470, 0x006470, 0x000000, 0xFFFFFF, + 0x006472, 0x006472, 0x000000, 0xFFFFFF, + 0x006474, 0x006475, 0x000000, 0xFFFFFF, + 0x006477, 0x006477, 0x000000, 0xFFFFFF, + 0x00647D, 0x00647D, 0x000000, 0xFFFFFF, + 0x00647F, 0x00647F, 0x000000, 0xFFFFFF, + 0x006489, 0x00648C, 0x000000, 0xFFFFFF, + 0x00648F, 0x00648F, 0x000000, 0xFFFFFF, + 0x006497, 0x006498, 0x000000, 0xFFFFFF, + 0x00649C, 0x00649D, 0x000000, 0xFFFFFF, + 0x0064A0, 0x0064A0, 0x000000, 0xFFFFFF, + 0x0064B1, 0x0064B1, 0x000000, 0xFFFFFF, + 0x0064BD, 0x0064BD, 0x000000, 0xFFFFFF, + 0x0064C3, 0x0064C3, 0x000000, 0xFFFFFF, + 0x0064C9, 0x0064C9, 0x000000, 0xFFFFFF, + 0x0064CF, 0x0064CF, 0x000000, 0xFFFFFF, + 0x0064D6, 0x0064D6, 0x000000, 0xFFFFFF, + 0x0064D9, 0x0064D9, 0x000000, 0xFFFFFF, + 0x0064DB, 0x0064DB, 0x000000, 0xFFFFFF, + 0x0064E8, 0x0064E9, 0x000000, 0xFFFFFF, + 0x0064EB, 0x0064EB, 0x000000, 0xFFFFFF, + 0x0064ED, 0x0064ED, 0x000000, 0xFFFFFF, + 0x0064F3, 0x0064F3, 0x000000, 0xFFFFFF, + 0x0064F8, 0x0064F8, 0x000000, 0xFFFFFF, + 0x0064FD, 0x0064FD, 0x000000, 0xFFFFFF, + 0x0064FF, 0x0064FF, 0x000000, 0xFFFFFF, + 0x006501, 0x006501, 0x000000, 0xFFFFFF, + 0x006503, 0x006503, 0x000000, 0xFFFFFF, + 0x006507, 0x006507, 0x000000, 0xFFFFFF, + 0x00650C, 0x00650E, 0x000000, 0xFFFFFF, + 0x006510, 0x006510, 0x000000, 0xFFFFFF, + 0x006513, 0x006513, 0x000000, 0xFFFFFF, + 0x006515, 0x006515, 0x000000, 0xFFFFFF, + 0x006517, 0x006517, 0x000000, 0xFFFFFF, + 0x006520, 0x006521, 0x000000, 0xFFFFFF, + 0x006526, 0x006526, 0x000000, 0xFFFFFF, + 0x006529, 0x006529, 0x000000, 0xFFFFFF, + 0x00652D, 0x00652D, 0x000000, 0xFFFFFF, + 0x006532, 0x006533, 0x000000, 0xFFFFFF, + 0x00653D, 0x00653D, 0x000000, 0xFFFFFF, + 0x006541, 0x006541, 0x000000, 0xFFFFFF, + 0x006543, 0x006543, 0x000000, 0xFFFFFF, + 0x006546, 0x006546, 0x000000, 0xFFFFFF, + 0x00654A, 0x00654A, 0x000000, 0xFFFFFF, + 0x006553, 0x006554, 0x000000, 0xFFFFFF, + 0x00655C, 0x00655C, 0x000000, 0xFFFFFF, + 0x006564, 0x006565, 0x000000, 0xFFFFFF, + 0x006567, 0x006568, 0x000000, 0xFFFFFF, + 0x00656A, 0x00656A, 0x000000, 0xFFFFFF, + 0x00656F, 0x00656F, 0x000000, 0xFFFFFF, + 0x006573, 0x006573, 0x000000, 0xFFFFFF, + 0x006576, 0x006576, 0x000000, 0xFFFFFF, + 0x006579, 0x00657C, 0x000000, 0xFFFFFF, + 0x00657F, 0x006581, 0x000000, 0xFFFFFF, + 0x006584, 0x006584, 0x000000, 0xFFFFFF, + 0x006592, 0x006592, 0x000000, 0xFFFFFF, + 0x006594, 0x006594, 0x000000, 0xFFFFFF, + 0x006596, 0x006596, 0x000000, 0xFFFFFF, + 0x00659D, 0x00659E, 0x000000, 0xFFFFFF, + 0x0065A0, 0x0065A0, 0x000000, 0xFFFFFF, + 0x0065A2, 0x0065A2, 0x000000, 0xFFFFFF, + 0x0065A8, 0x0065A8, 0x000000, 0xFFFFFF, + 0x0065AA, 0x0065AA, 0x000000, 0xFFFFFF, + 0x0065AE, 0x0065AE, 0x000000, 0xFFFFFF, + 0x0065B2, 0x0065B3, 0x000000, 0xFFFFFF, + 0x0065B6, 0x0065B6, 0x000000, 0xFFFFFF, + 0x0065B8, 0x0065B8, 0x000000, 0xFFFFFF, + 0x0065BB, 0x0065BB, 0x000000, 0xFFFFFF, + 0x0065BF, 0x0065BF, 0x000000, 0xFFFFFF, + 0x0065CD, 0x0065CD, 0x000000, 0xFFFFFF, + 0x0065D0, 0x0065D0, 0x000000, 0xFFFFFF, + 0x0065D3, 0x0065D3, 0x000000, 0xFFFFFF, + 0x0065DA, 0x0065DA, 0x000000, 0xFFFFFF, + 0x0065DD, 0x0065DF, 0x000000, 0xFFFFFF, + 0x0065E1, 0x0065E1, 0x000000, 0xFFFFFF, + 0x0065F2, 0x0065F5, 0x000000, 0xFFFFFF, + 0x0065FB, 0x0065FD, 0x000000, 0xFFFFFF, + 0x006604, 0x006605, 0x000000, 0xFFFFFF, + 0x006608, 0x006609, 0x000000, 0xFFFFFF, + 0x00660B, 0x00660B, 0x000000, 0xFFFFFF, + 0x00660D, 0x00660D, 0x000000, 0xFFFFFF, + 0x006610, 0x006612, 0x000000, 0xFFFFFF, + 0x00661C, 0x00661C, 0x000000, 0xFFFFFF, + 0x006621, 0x006622, 0x000000, 0xFFFFFF, + 0x006624, 0x006624, 0x000000, 0xFFFFFF, + 0x006626, 0x006626, 0x000000, 0xFFFFFF, + 0x00662B, 0x00662B, 0x000000, 0xFFFFFF, + 0x00662E, 0x00662E, 0x000000, 0xFFFFFF, + 0x006632, 0x006633, 0x000000, 0xFFFFFF, + 0x006639, 0x00663A, 0x000000, 0xFFFFFF, + 0x006645, 0x006645, 0x000000, 0xFFFFFF, + 0x006647, 0x006647, 0x000000, 0xFFFFFF, + 0x00664A, 0x00664A, 0x000000, 0xFFFFFF, + 0x006651, 0x006651, 0x000000, 0xFFFFFF, + 0x006659, 0x006659, 0x000000, 0xFFFFFF, + 0x00665B, 0x00665C, 0x000000, 0xFFFFFF, + 0x006665, 0x006665, 0x000000, 0xFFFFFF, + 0x00666A, 0x00666A, 0x000000, 0xFFFFFF, + 0x00666C, 0x00666C, 0x000000, 0xFFFFFF, + 0x006671, 0x006672, 0x000000, 0xFFFFFF, + 0x006678, 0x006679, 0x000000, 0xFFFFFF, + 0x00667C, 0x00667C, 0x000000, 0xFFFFFF, + 0x006680, 0x006680, 0x000000, 0xFFFFFF, + 0x006686, 0x006686, 0x000000, 0xFFFFFF, + 0x00668A, 0x00668B, 0x000000, 0xFFFFFF, + 0x00668D, 0x00668D, 0x000000, 0xFFFFFF, + 0x006690, 0x006690, 0x000000, 0xFFFFFF, + 0x006694, 0x006695, 0x000000, 0xFFFFFF, + 0x006699, 0x006699, 0x000000, 0xFFFFFF, + 0x00669F, 0x0066A1, 0x000000, 0xFFFFFF, + 0x0066A9, 0x0066AA, 0x000000, 0xFFFFFF, + 0x0066AF, 0x0066B0, 0x000000, 0xFFFFFF, + 0x0066B2, 0x0066B2, 0x000000, 0xFFFFFF, + 0x0066B5, 0x0066B5, 0x000000, 0xFFFFFF, + 0x0066B7, 0x0066B7, 0x000000, 0xFFFFFF, + 0x0066BA, 0x0066BB, 0x000000, 0xFFFFFF, + 0x0066BD, 0x0066BD, 0x000000, 0xFFFFFF, + 0x0066C0, 0x0066C0, 0x000000, 0xFFFFFF, + 0x0066C8, 0x0066C8, 0x000000, 0xFFFFFF, + 0x0066CA, 0x0066CC, 0x000000, 0xFFFFFF, + 0x0066D2, 0x0066D2, 0x000000, 0xFFFFFF, + 0x0066D8, 0x0066D8, 0x000000, 0xFFFFFF, + 0x0066DA, 0x0066DA, 0x000000, 0xFFFFFF, + 0x0066DE, 0x0066DE, 0x000000, 0xFFFFFF, + 0x0066E3, 0x0066E4, 0x000000, 0xFFFFFF, + 0x0066E8, 0x0066E8, 0x000000, 0xFFFFFF, + 0x0066EB, 0x0066EB, 0x000000, 0xFFFFFF, + 0x0066ED, 0x0066EE, 0x000000, 0xFFFFFF, + 0x0066F6, 0x0066F6, 0x000000, 0xFFFFFF, + 0x006701, 0x006701, 0x000000, 0xFFFFFF, + 0x006704, 0x006705, 0x000000, 0xFFFFFF, + 0x00670F, 0x00670F, 0x000000, 0xFFFFFF, + 0x006712, 0x006713, 0x000000, 0xFFFFFF, + 0x006718, 0x006718, 0x000000, 0xFFFFFF, + 0x006720, 0x006721, 0x000000, 0xFFFFFF, + 0x006723, 0x006723, 0x000000, 0xFFFFFF, + 0x006733, 0x006733, 0x000000, 0xFFFFFF, + 0x006738, 0x006739, 0x000000, 0xFFFFFF, + 0x00673B, 0x00673C, 0x000000, 0xFFFFFF, + 0x00673E, 0x00673F, 0x000000, 0xFFFFFF, + 0x006745, 0x006745, 0x000000, 0xFFFFFF, + 0x00674B, 0x00674B, 0x000000, 0xFFFFFF, + 0x00674D, 0x00674D, 0x000000, 0xFFFFFF, + 0x006755, 0x006755, 0x000000, 0xFFFFFF, + 0x006757, 0x006757, 0x000000, 0xFFFFFF, + 0x006759, 0x00675A, 0x000000, 0xFFFFFF, + 0x00675D, 0x00675D, 0x000000, 0xFFFFFF, + 0x00676C, 0x00676C, 0x000000, 0xFFFFFF, + 0x006774, 0x006774, 0x000000, 0xFFFFFF, + 0x006776, 0x006776, 0x000000, 0xFFFFFF, + 0x006778, 0x00677B, 0x000000, 0xFFFFFF, + 0x00677D, 0x00677D, 0x000000, 0xFFFFFF, + 0x006783, 0x006783, 0x000000, 0xFFFFFF, + 0x006785, 0x006786, 0x000000, 0xFFFFFF, + 0x00678C, 0x00678E, 0x000000, 0xFFFFFF, + 0x006791, 0x006794, 0x000000, 0xFFFFFF, + 0x006799, 0x006799, 0x000000, 0xFFFFFF, + 0x00679F, 0x00679F, 0x000000, 0xFFFFFF, + 0x0067AE, 0x0067AE, 0x000000, 0xFFFFFF, + 0x0067B2, 0x0067B2, 0x000000, 0xFFFFFF, + 0x0067B9, 0x0067BB, 0x000000, 0xFFFFFF, + 0x0067C0, 0x0067C0, 0x000000, 0xFFFFFF, + 0x0067C2, 0x0067C2, 0x000000, 0xFFFFFF, + 0x0067C5, 0x0067C6, 0x000000, 0xFFFFFF, + 0x0067C8, 0x0067CE, 0x000000, 0xFFFFFF, + 0x0067DB, 0x0067DB, 0x000000, 0xFFFFFF, + 0x0067DF, 0x0067DF, 0x000000, 0xFFFFFF, + 0x0067E3, 0x0067E4, 0x000000, 0xFFFFFF, + 0x0067E6, 0x0067E7, 0x000000, 0xFFFFFF, + 0x0067EA, 0x0067EB, 0x000000, 0xFFFFFF, + 0x0067ED, 0x0067EE, 0x000000, 0xFFFFFF, + 0x0067F2, 0x0067F2, 0x000000, 0xFFFFFF, + 0x0067F6, 0x0067F8, 0x000000, 0xFFFFFF, + 0x0067FC, 0x0067FC, 0x000000, 0xFFFFFF, + 0x006814, 0x006814, 0x000000, 0xFFFFFF, + 0x006818, 0x006818, 0x000000, 0xFFFFFF, + 0x00681A, 0x00681A, 0x000000, 0xFFFFFF, + 0x00681C, 0x00681C, 0x000000, 0xFFFFFF, + 0x00681F, 0x006820, 0x000000, 0xFFFFFF, + 0x006825, 0x006826, 0x000000, 0xFFFFFF, + 0x006828, 0x006828, 0x000000, 0xFFFFFF, + 0x00682B, 0x00682B, 0x000000, 0xFFFFFF, + 0x00682D, 0x00682F, 0x000000, 0xFFFFFF, + 0x006831, 0x006831, 0x000000, 0xFFFFFF, + 0x006834, 0x006835, 0x000000, 0xFFFFFF, + 0x00683A, 0x00683B, 0x000000, 0xFFFFFF, + 0x00684B, 0x00684B, 0x000000, 0xFFFFFF, + 0x00684D, 0x00684D, 0x000000, 0xFFFFFF, + 0x00684F, 0x00684F, 0x000000, 0xFFFFFF, + 0x00686D, 0x00686D, 0x000000, 0xFFFFFF, + 0x00686F, 0x00686F, 0x000000, 0xFFFFFF, + 0x006871, 0x006872, 0x000000, 0xFFFFFF, + 0x006875, 0x006875, 0x000000, 0xFFFFFF, + 0x006878, 0x006879, 0x000000, 0xFFFFFF, + 0x00687B, 0x00687E, 0x000000, 0xFFFFFF, + 0x006880, 0x006880, 0x000000, 0xFFFFFF, + 0x006882, 0x006882, 0x000000, 0xFFFFFF, + 0x006887, 0x006887, 0x000000, 0xFFFFFF, + 0x006889, 0x00688C, 0x000000, 0xFFFFFF, + 0x006890, 0x006892, 0x000000, 0xFFFFFF, + 0x006896, 0x006896, 0x000000, 0xFFFFFF, + 0x00689B, 0x00689C, 0x000000, 0xFFFFFF, + 0x0068A0, 0x0068A1, 0x000000, 0xFFFFFF, + 0x0068A3, 0x0068A4, 0x000000, 0xFFFFFF, + 0x0068A9, 0x0068AC, 0x000000, 0xFFFFFF, + 0x0068AE, 0x0068AE, 0x000000, 0xFFFFFF, + 0x0068B2, 0x0068B2, 0x000000, 0xFFFFFF, + 0x0068B4, 0x0068B4, 0x000000, 0xFFFFFF, + 0x0068C6, 0x0068C8, 0x000000, 0xFFFFFF, + 0x0068CC, 0x0068CC, 0x000000, 0xFFFFFF, + 0x0068CE, 0x0068CE, 0x000000, 0xFFFFFF, + 0x0068D0, 0x0068D1, 0x000000, 0xFFFFFF, + 0x0068D3, 0x0068D4, 0x000000, 0xFFFFFF, + 0x0068DC, 0x0068DE, 0x000000, 0xFFFFFF, + 0x0068E1, 0x0068E1, 0x000000, 0xFFFFFF, + 0x0068E4, 0x0068E4, 0x000000, 0xFFFFFF, + 0x0068E6, 0x0068E6, 0x000000, 0xFFFFFF, + 0x0068E8, 0x0068EC, 0x000000, 0xFFFFFF, + 0x0068EF, 0x0068EF, 0x000000, 0xFFFFFF, + 0x0068F3, 0x0068F4, 0x000000, 0xFFFFFF, + 0x0068F6, 0x0068F8, 0x000000, 0xFFFFFF, + 0x0068FB, 0x0068FB, 0x000000, 0xFFFFFF, + 0x0068FD, 0x0068FD, 0x000000, 0xFFFFFF, + 0x006904, 0x006904, 0x000000, 0xFFFFFF, + 0x006906, 0x006908, 0x000000, 0xFFFFFF, + 0x00690A, 0x00690A, 0x000000, 0xFFFFFF, + 0x00690C, 0x00690C, 0x000000, 0xFFFFFF, + 0x006911, 0x006911, 0x000000, 0xFFFFFF, + 0x006913, 0x006915, 0x000000, 0xFFFFFF, + 0x006917, 0x006917, 0x000000, 0xFFFFFF, + 0x006925, 0x006925, 0x000000, 0xFFFFFF, + 0x00692A, 0x00692A, 0x000000, 0xFFFFFF, + 0x00692F, 0x00692F, 0x000000, 0xFFFFFF, + 0x006932, 0x006933, 0x000000, 0xFFFFFF, + 0x006935, 0x006935, 0x000000, 0xFFFFFF, + 0x006937, 0x006938, 0x000000, 0xFFFFFF, + 0x00693B, 0x00693C, 0x000000, 0xFFFFFF, + 0x006940, 0x006941, 0x000000, 0xFFFFFF, + 0x006945, 0x006945, 0x000000, 0xFFFFFF, + 0x006948, 0x006949, 0x000000, 0xFFFFFF, + 0x00694B, 0x00694C, 0x000000, 0xFFFFFF, + 0x00694E, 0x00694F, 0x000000, 0xFFFFFF, + 0x006951, 0x006952, 0x000000, 0xFFFFFF, + 0x006956, 0x006956, 0x000000, 0xFFFFFF, + 0x006958, 0x006958, 0x000000, 0xFFFFFF, + 0x00695B, 0x00695B, 0x000000, 0xFFFFFF, + 0x00695F, 0x00695F, 0x000000, 0xFFFFFF, + 0x006962, 0x006962, 0x000000, 0xFFFFFF, + 0x006965, 0x006965, 0x000000, 0xFFFFFF, + 0x006969, 0x00696A, 0x000000, 0xFFFFFF, + 0x00696C, 0x00696C, 0x000000, 0xFFFFFF, + 0x00696F, 0x006970, 0x000000, 0xFFFFFF, + 0x006974, 0x006974, 0x000000, 0xFFFFFF, + 0x006976, 0x006976, 0x000000, 0xFFFFFF, + 0x00697A, 0x00697B, 0x000000, 0xFFFFFF, + 0x006983, 0x006983, 0x000000, 0xFFFFFF, + 0x00698E, 0x00698E, 0x000000, 0xFFFFFF, + 0x006990, 0x006991, 0x000000, 0xFFFFFF, + 0x006993, 0x006993, 0x000000, 0xFFFFFF, + 0x006996, 0x006997, 0x000000, 0xFFFFFF, + 0x006999, 0x00699A, 0x000000, 0xFFFFFF, + 0x00699E, 0x00699E, 0x000000, 0xFFFFFF, + 0x0069A0, 0x0069A1, 0x000000, 0xFFFFFF, + 0x0069A3, 0x0069A5, 0x000000, 0xFFFFFF, + 0x0069A9, 0x0069A9, 0x000000, 0xFFFFFF, + 0x0069AC, 0x0069AC, 0x000000, 0xFFFFFF, + 0x0069AF, 0x0069B0, 0x000000, 0xFFFFFF, + 0x0069B3, 0x0069B3, 0x000000, 0xFFFFFF, + 0x0069B5, 0x0069B6, 0x000000, 0xFFFFFF, + 0x0069B9, 0x0069B9, 0x000000, 0xFFFFFF, + 0x0069BC, 0x0069BE, 0x000000, 0xFFFFFF, + 0x0069C2, 0x0069C2, 0x000000, 0xFFFFFF, + 0x0069C4, 0x0069C4, 0x000000, 0xFFFFFF, + 0x0069C6, 0x0069C6, 0x000000, 0xFFFFFF, + 0x0069C9, 0x0069C9, 0x000000, 0xFFFFFF, + 0x0069CF, 0x0069CF, 0x000000, 0xFFFFFF, + 0x0069D9, 0x0069D9, 0x000000, 0xFFFFFF, + 0x0069E2, 0x0069E2, 0x000000, 0xFFFFFF, + 0x0069E4, 0x0069E6, 0x000000, 0xFFFFFF, + 0x0069EB, 0x0069EC, 0x000000, 0xFFFFFF, + 0x0069EE, 0x0069EE, 0x000000, 0xFFFFFF, + 0x0069F1, 0x0069F1, 0x000000, 0xFFFFFF, + 0x0069F4, 0x0069F4, 0x000000, 0xFFFFFF, + 0x0069F6, 0x0069F8, 0x000000, 0xFFFFFF, + 0x0069FB, 0x0069FC, 0x000000, 0xFFFFFF, + 0x0069FE, 0x0069FE, 0x000000, 0xFFFFFF, + 0x006A00, 0x006A00, 0x000000, 0xFFFFFF, + 0x006A04, 0x006A04, 0x000000, 0xFFFFFF, + 0x006A06, 0x006A09, 0x000000, 0xFFFFFF, + 0x006A0D, 0x006A0D, 0x000000, 0xFFFFFF, + 0x006A0F, 0x006A0F, 0x000000, 0xFFFFFF, + 0x006A14, 0x006A16, 0x000000, 0xFFFFFF, + 0x006A1B, 0x006A1B, 0x000000, 0xFFFFFF, + 0x006A1D, 0x006A1D, 0x000000, 0xFFFFFF, + 0x006A20, 0x006A20, 0x000000, 0xFFFFFF, + 0x006A25, 0x006A27, 0x000000, 0xFFFFFF, + 0x006A32, 0x006A32, 0x000000, 0xFFFFFF, + 0x006A34, 0x006A34, 0x000000, 0xFFFFFF, + 0x006A3B, 0x006A3C, 0x000000, 0xFFFFFF, + 0x006A3F, 0x006A41, 0x000000, 0xFFFFFF, + 0x006A46, 0x006A46, 0x000000, 0xFFFFFF, + 0x006A49, 0x006A49, 0x000000, 0xFFFFFF, + 0x006A4D, 0x006A4F, 0x000000, 0xFFFFFF, + 0x006A51, 0x006A51, 0x000000, 0xFFFFFF, + 0x006A54, 0x006A56, 0x000000, 0xFFFFFF, + 0x006A5A, 0x006A5A, 0x000000, 0xFFFFFF, + 0x006A5D, 0x006A5E, 0x000000, 0xFFFFFF, + 0x006A60, 0x006A60, 0x000000, 0xFFFFFF, + 0x006A64, 0x006A64, 0x000000, 0xFFFFFF, + 0x006A67, 0x006A6A, 0x000000, 0xFFFFFF, + 0x006A6D, 0x006A6D, 0x000000, 0xFFFFFF, + 0x006A6F, 0x006A6F, 0x000000, 0xFFFFFF, + 0x006A76, 0x006A76, 0x000000, 0xFFFFFF, + 0x006A7E, 0x006A7F, 0x000000, 0xFFFFFF, + 0x006A83, 0x006A83, 0x000000, 0xFFFFFF, + 0x006A85, 0x006A85, 0x000000, 0xFFFFFF, + 0x006A87, 0x006A87, 0x000000, 0xFFFFFF, + 0x006A8C, 0x006A8D, 0x000000, 0xFFFFFF, + 0x006A92, 0x006A93, 0x000000, 0xFFFFFF, + 0x006A95, 0x006A96, 0x000000, 0xFFFFFF, + 0x006A9A, 0x006A9B, 0x000000, 0xFFFFFF, + 0x006A9E, 0x006A9F, 0x000000, 0xFFFFFF, + 0x006AA1, 0x006AA1, 0x000000, 0xFFFFFF, + 0x006AA4, 0x006AA6, 0x000000, 0xFFFFFF, + 0x006AA8, 0x006AA8, 0x000000, 0xFFFFFF, + 0x006AAD, 0x006AAE, 0x000000, 0xFFFFFF, + 0x006AB4, 0x006AB4, 0x000000, 0xFFFFFF, + 0x006AB6, 0x006AB7, 0x000000, 0xFFFFFF, + 0x006AB9, 0x006ABA, 0x000000, 0xFFFFFF, + 0x006ABD, 0x006ABD, 0x000000, 0xFFFFFF, + 0x006AC5, 0x006AC7, 0x000000, 0xFFFFFF, + 0x006ACB, 0x006ACD, 0x000000, 0xFFFFFF, + 0x006ACF, 0x006ACF, 0x000000, 0xFFFFFF, + 0x006AD1, 0x006AD1, 0x000000, 0xFFFFFF, + 0x006AD9, 0x006AD9, 0x000000, 0xFFFFFF, + 0x006ADC, 0x006ADC, 0x000000, 0xFFFFFF, + 0x006AE0, 0x006AE1, 0x000000, 0xFFFFFF, + 0x006AEE, 0x006AF1, 0x000000, 0xFFFFFF, + 0x006AF9, 0x006AF9, 0x000000, 0xFFFFFF, + 0x006AFC, 0x006AFC, 0x000000, 0xFFFFFF, + 0x006B00, 0x006B00, 0x000000, 0xFFFFFF, + 0x006B02, 0x006B03, 0x000000, 0xFFFFFF, + 0x006B08, 0x006B09, 0x000000, 0xFFFFFF, + 0x006B0B, 0x006B0B, 0x000000, 0xFFFFFF, + 0x006B10, 0x006B11, 0x000000, 0xFFFFFF, + 0x006B13, 0x006B13, 0x000000, 0xFFFFFF, + 0x006B17, 0x006B1A, 0x000000, 0xFFFFFF, + 0x006B25, 0x006B25, 0x000000, 0xFFFFFF, + 0x006B28, 0x006B28, 0x000000, 0xFFFFFF, + 0x006B2C, 0x006B2D, 0x000000, 0xFFFFFF, + 0x006B2F, 0x006B2F, 0x000000, 0xFFFFFF, + 0x006B31, 0x006B31, 0x000000, 0xFFFFFF, + 0x006B33, 0x006B34, 0x000000, 0xFFFFFF, + 0x006B36, 0x006B36, 0x000000, 0xFFFFFF, + 0x006B3B, 0x006B3C, 0x000000, 0xFFFFFF, + 0x006B3F, 0x006B3F, 0x000000, 0xFFFFFF, + 0x006B41, 0x006B42, 0x000000, 0xFFFFFF, + 0x006B45, 0x006B45, 0x000000, 0xFFFFFF, + 0x006B48, 0x006B48, 0x000000, 0xFFFFFF, + 0x006B4A, 0x006B4B, 0x000000, 0xFFFFFF, + 0x006B4D, 0x006B4D, 0x000000, 0xFFFFFF, + 0x006B51, 0x006B51, 0x000000, 0xFFFFFF, + 0x006B54, 0x006B56, 0x000000, 0xFFFFFF, + 0x006B5B, 0x006B5C, 0x000000, 0xFFFFFF, + 0x006B5E, 0x006B5E, 0x000000, 0xFFFFFF, + 0x006B60, 0x006B60, 0x000000, 0xFFFFFF, + 0x006B6D, 0x006B6D, 0x000000, 0xFFFFFF, + 0x006B76, 0x006B76, 0x000000, 0xFFFFFF, + 0x006B7E, 0x006B7E, 0x000000, 0xFFFFFF, + 0x006B88, 0x006B88, 0x000000, 0xFFFFFF, + 0x006B8C, 0x006B8C, 0x000000, 0xFFFFFF, + 0x006B8E, 0x006B8F, 0x000000, 0xFFFFFF, + 0x006B91, 0x006B91, 0x000000, 0xFFFFFF, + 0x006B94, 0x006B95, 0x000000, 0xFFFFFF, + 0x006B97, 0x006B97, 0x000000, 0xFFFFFF, + 0x006B99, 0x006B99, 0x000000, 0xFFFFFF, + 0x006B9F, 0x006BA0, 0x000000, 0xFFFFFF, + 0x006BA2, 0x006BA3, 0x000000, 0xFFFFFF, + 0x006BA5, 0x006BA7, 0x000000, 0xFFFFFF, + 0x006BB0, 0x006BB0, 0x000000, 0xFFFFFF, + 0x006BB6, 0x006BB6, 0x000000, 0xFFFFFF, + 0x006BC3, 0x006BC4, 0x000000, 0xFFFFFF, + 0x006BC7, 0x006BCA, 0x000000, 0xFFFFFF, + 0x006BD0, 0x006BD0, 0x000000, 0xFFFFFF, + 0x006BDA, 0x006BDA, 0x000000, 0xFFFFFF, + 0x006BDE, 0x006BDE, 0x000000, 0xFFFFFF, + 0x006BE0, 0x006BE0, 0x000000, 0xFFFFFF, + 0x006BE2, 0x006BE4, 0x000000, 0xFFFFFF, + 0x006BE6, 0x006BE8, 0x000000, 0xFFFFFF, + 0x006BF0, 0x006BF0, 0x000000, 0xFFFFFF, + 0x006BF2, 0x006BF2, 0x000000, 0xFFFFFF, + 0x006BF7, 0x006BF8, 0x000000, 0xFFFFFF, + 0x006BFB, 0x006BFC, 0x000000, 0xFFFFFF, + 0x006BFE, 0x006BFE, 0x000000, 0xFFFFFF, + 0x006C00, 0x006C04, 0x000000, 0xFFFFFF, + 0x006C09, 0x006C09, 0x000000, 0xFFFFFF, + 0x006C0B, 0x006C0B, 0x000000, 0xFFFFFF, + 0x006C1D, 0x006C1D, 0x000000, 0xFFFFFF, + 0x006C20, 0x006C20, 0x000000, 0xFFFFFF, + 0x006C25, 0x006C25, 0x000000, 0xFFFFFF, + 0x006C36, 0x006C36, 0x000000, 0xFFFFFF, + 0x006C3B, 0x006C3B, 0x000000, 0xFFFFFF, + 0x006C3F, 0x006C3F, 0x000000, 0xFFFFFF, + 0x006C43, 0x006C43, 0x000000, 0xFFFFFF, + 0x006C4B, 0x006C4C, 0x000000, 0xFFFFFF, + 0x006C4F, 0x006C4F, 0x000000, 0xFFFFFF, + 0x006C52, 0x006C52, 0x000000, 0xFFFFFF, + 0x006C65, 0x006C67, 0x000000, 0xFFFFFF, + 0x006C6B, 0x006C6B, 0x000000, 0xFFFFFF, + 0x006C6D, 0x006C6D, 0x000000, 0xFFFFFF, + 0x006C6F, 0x006C6F, 0x000000, 0xFFFFFF, + 0x006C71, 0x006C71, 0x000000, 0xFFFFFF, + 0x006C73, 0x006C73, 0x000000, 0xFFFFFF, + 0x006C78, 0x006C78, 0x000000, 0xFFFFFF, + 0x006C7B, 0x006C7B, 0x000000, 0xFFFFFF, + 0x006C80, 0x006C80, 0x000000, 0xFFFFFF, + 0x006C84, 0x006C84, 0x000000, 0xFFFFFF, + 0x006C87, 0x006C87, 0x000000, 0xFFFFFF, + 0x006C8A, 0x006C8B, 0x000000, 0xFFFFFF, + 0x006C8E, 0x006C8E, 0x000000, 0xFFFFFF, + 0x006C95, 0x006C95, 0x000000, 0xFFFFFF, + 0x006C98, 0x006C98, 0x000000, 0xFFFFFF, + 0x006C9A, 0x006C9A, 0x000000, 0xFFFFFF, + 0x006C9C, 0x006C9D, 0x000000, 0xFFFFFF, + 0x006CAC, 0x006CAC, 0x000000, 0xFFFFFF, + 0x006CB0, 0x006CB0, 0x000000, 0xFFFFFF, + 0x006CB4, 0x006CB4, 0x000000, 0xFFFFFF, + 0x006CB6, 0x006CB7, 0x000000, 0xFFFFFF, + 0x006CBA, 0x006CBA, 0x000000, 0xFFFFFF, + 0x006CC0, 0x006CC0, 0x000000, 0xFFFFFF, + 0x006CC2, 0x006CC3, 0x000000, 0xFFFFFF, + 0x006CC6, 0x006CC7, 0x000000, 0xFFFFFF, + 0x006CCD, 0x006CCD, 0x000000, 0xFFFFFF, + 0x006CCF, 0x006CCF, 0x000000, 0xFFFFFF, + 0x006CD1, 0x006CD2, 0x000000, 0xFFFFFF, + 0x006CD9, 0x006CDA, 0x000000, 0xFFFFFF, + 0x006CDC, 0x006CDC, 0x000000, 0xFFFFFF, + 0x006CE7, 0x006CE7, 0x000000, 0xFFFFFF, + 0x006CE9, 0x006CE9, 0x000000, 0xFFFFFF, + 0x006CEC, 0x006CED, 0x000000, 0xFFFFFF, + 0x006CF2, 0x006CF2, 0x000000, 0xFFFFFF, + 0x006CF9, 0x006CF9, 0x000000, 0xFFFFFF, + 0x006D00, 0x006D00, 0x000000, 0xFFFFFF, + 0x006D03, 0x006D03, 0x000000, 0xFFFFFF, + 0x006D08, 0x006D0A, 0x000000, 0xFFFFFF, + 0x006D0D, 0x006D0D, 0x000000, 0xFFFFFF, + 0x006D0F, 0x006D11, 0x000000, 0xFFFFFF, + 0x006D16, 0x006D16, 0x000000, 0xFFFFFF, + 0x006D18, 0x006D18, 0x000000, 0xFFFFFF, + 0x006D1D, 0x006D1D, 0x000000, 0xFFFFFF, + 0x006D20, 0x006D20, 0x000000, 0xFFFFFF, + 0x006D22, 0x006D22, 0x000000, 0xFFFFFF, + 0x006D28, 0x006D28, 0x000000, 0xFFFFFF, + 0x006D2C, 0x006D2D, 0x000000, 0xFFFFFF, + 0x006D2F, 0x006D30, 0x000000, 0xFFFFFF, + 0x006D34, 0x006D34, 0x000000, 0xFFFFFF, + 0x006D37, 0x006D38, 0x000000, 0xFFFFFF, + 0x006D3A, 0x006D3A, 0x000000, 0xFFFFFF, + 0x006D3F, 0x006D40, 0x000000, 0xFFFFFF, + 0x006D42, 0x006D42, 0x000000, 0xFFFFFF, + 0x006D58, 0x006D58, 0x000000, 0xFFFFFF, + 0x006D5F, 0x006D5F, 0x000000, 0xFFFFFF, + 0x006D61, 0x006D62, 0x000000, 0xFFFFFF, + 0x006D64, 0x006D65, 0x000000, 0xFFFFFF, + 0x006D67, 0x006D68, 0x000000, 0xFFFFFF, + 0x006D6D, 0x006D6D, 0x000000, 0xFFFFFF, + 0x006D70, 0x006D70, 0x000000, 0xFFFFFF, + 0x006D75, 0x006D76, 0x000000, 0xFFFFFF, + 0x006D7A, 0x006D7B, 0x000000, 0xFFFFFF, + 0x006D7D, 0x006D80, 0x000000, 0xFFFFFF, + 0x006D83, 0x006D84, 0x000000, 0xFFFFFF, + 0x006D86, 0x006D86, 0x000000, 0xFFFFFF, + 0x006D8A, 0x006D8B, 0x000000, 0xFFFFFF, + 0x006D8D, 0x006D8D, 0x000000, 0xFFFFFF, + 0x006D90, 0x006D90, 0x000000, 0xFFFFFF, + 0x006D92, 0x006D92, 0x000000, 0xFFFFFF, + 0x006D97, 0x006D98, 0x000000, 0xFFFFFF, + 0x006DAC, 0x006DAC, 0x000000, 0xFFFFFF, + 0x006DB3, 0x006DB4, 0x000000, 0xFFFFFF, + 0x006DB7, 0x006DB7, 0x000000, 0xFFFFFF, + 0x006DBA, 0x006DBB, 0x000000, 0xFFFFFF, + 0x006DBD, 0x006DBE, 0x000000, 0xFFFFFF, + 0x006DC2, 0x006DC2, 0x000000, 0xFFFFFF, + 0x006DC8, 0x006DCA, 0x000000, 0xFFFFFF, + 0x006DCD, 0x006DCD, 0x000000, 0xFFFFFF, + 0x006DCF, 0x006DD0, 0x000000, 0xFFFFFF, + 0x006DD3, 0x006DD5, 0x000000, 0xFFFFFF, + 0x006DD7, 0x006DD7, 0x000000, 0xFFFFFF, + 0x006DDB, 0x006DDC, 0x000000, 0xFFFFFF, + 0x006DDF, 0x006DDF, 0x000000, 0xFFFFFF, + 0x006DE2, 0x006DE3, 0x000000, 0xFFFFFF, + 0x006DE9, 0x006DE9, 0x000000, 0xFFFFFF, + 0x006DED, 0x006DED, 0x000000, 0xFFFFFF, + 0x006DEF, 0x006DF0, 0x000000, 0xFFFFFF, + 0x006DF2, 0x006DF2, 0x000000, 0xFFFFFF, + 0x006DF4, 0x006DF4, 0x000000, 0xFFFFFF, + 0x006DFD, 0x006DFD, 0x000000, 0xFFFFFF, + 0x006E00, 0x006E00, 0x000000, 0xFFFFFF, + 0x006E03, 0x006E03, 0x000000, 0xFFFFFF, + 0x006E1C, 0x006E1C, 0x000000, 0xFFFFFF, + 0x006E1F, 0x006E1F, 0x000000, 0xFFFFFF, + 0x006E22, 0x006E22, 0x000000, 0xFFFFFF, + 0x006E27, 0x006E28, 0x000000, 0xFFFFFF, + 0x006E2E, 0x006E2E, 0x000000, 0xFFFFFF, + 0x006E30, 0x006E31, 0x000000, 0xFFFFFF, + 0x006E33, 0x006E33, 0x000000, 0xFFFFFF, + 0x006E35, 0x006E36, 0x000000, 0xFFFFFF, + 0x006E39, 0x006E39, 0x000000, 0xFFFFFF, + 0x006E3B, 0x006E3D, 0x000000, 0xFFFFFF, + 0x006E3F, 0x006E41, 0x000000, 0xFFFFFF, + 0x006E45, 0x006E47, 0x000000, 0xFFFFFF, + 0x006E49, 0x006E49, 0x000000, 0xFFFFFF, + 0x006E4B, 0x006E4B, 0x000000, 0xFFFFFF, + 0x006E51, 0x006E52, 0x000000, 0xFFFFFF, + 0x006E55, 0x006E55, 0x000000, 0xFFFFFF, + 0x006E5A, 0x006E5A, 0x000000, 0xFFFFFF, + 0x006E5C, 0x006E5D, 0x000000, 0xFFFFFF, + 0x006E60, 0x006E62, 0x000000, 0xFFFFFF, + 0x006E64, 0x006E66, 0x000000, 0xFFFFFF, + 0x006E68, 0x006E69, 0x000000, 0xFFFFFF, + 0x006E71, 0x006E74, 0x000000, 0xFFFFFF, + 0x006E77, 0x006E79, 0x000000, 0xFFFFFF, + 0x006E8D, 0x006E8E, 0x000000, 0xFFFFFF, + 0x006E92, 0x006E94, 0x000000, 0xFFFFFF, + 0x006E97, 0x006E97, 0x000000, 0xFFFFFF, + 0x006E99, 0x006E99, 0x000000, 0xFFFFFF, + 0x006E9B, 0x006E9B, 0x000000, 0xFFFFFF, + 0x006E9E, 0x006E9E, 0x000000, 0xFFFFFF, + 0x006EA0, 0x006EA1, 0x000000, 0xFFFFFF, + 0x006EA3, 0x006EA4, 0x000000, 0xFFFFFF, + 0x006EA6, 0x006EA6, 0x000000, 0xFFFFFF, + 0x006EAE, 0x006EAE, 0x000000, 0xFFFFFF, + 0x006EB0, 0x006EB0, 0x000000, 0xFFFFFF, + 0x006EB3, 0x006EB3, 0x000000, 0xFFFFFF, + 0x006EB9, 0x006EB9, 0x000000, 0xFFFFFF, + 0x006EBE, 0x006EC0, 0x000000, 0xFFFFFF, + 0x006EC3, 0x006EC3, 0x000000, 0xFFFFFF, + 0x006EC6, 0x006EC6, 0x000000, 0xFFFFFF, + 0x006EC8, 0x006ECA, 0x000000, 0xFFFFFF, + 0x006ECD, 0x006ECD, 0x000000, 0xFFFFFF, + 0x006ED0, 0x006ED0, 0x000000, 0xFFFFFF, + 0x006ED2, 0x006ED2, 0x000000, 0xFFFFFF, + 0x006ED6, 0x006ED6, 0x000000, 0xFFFFFF, + 0x006ED8, 0x006ED8, 0x000000, 0xFFFFFF, + 0x006EDC, 0x006EDC, 0x000000, 0xFFFFFF, + 0x006EEB, 0x006EEB, 0x000000, 0xFFFFFF, + 0x006EED, 0x006EEE, 0x000000, 0xFFFFFF, + 0x006EF1, 0x006EF1, 0x000000, 0xFFFFFF, + 0x006EF5, 0x006EF6, 0x000000, 0xFFFFFF, + 0x006EFB, 0x006EFD, 0x000000, 0xFFFFFF, + 0x006F00, 0x006F00, 0x000000, 0xFFFFFF, + 0x006F03, 0x006F03, 0x000000, 0xFFFFFF, + 0x006F05, 0x006F05, 0x000000, 0xFFFFFF, + 0x006F07, 0x006F08, 0x000000, 0xFFFFFF, + 0x006F0A, 0x006F0A, 0x000000, 0xFFFFFF, + 0x006F0D, 0x006F0E, 0x000000, 0xFFFFFF, + 0x006F12, 0x006F12, 0x000000, 0xFFFFFF, + 0x006F18, 0x006F19, 0x000000, 0xFFFFFF, + 0x006F1C, 0x006F1C, 0x000000, 0xFFFFFF, + 0x006F1E, 0x006F1F, 0x000000, 0xFFFFFF, + 0x006F21, 0x006F21, 0x000000, 0xFFFFFF, + 0x006F25, 0x006F27, 0x000000, 0xFFFFFF, + 0x006F2E, 0x006F2E, 0x000000, 0xFFFFFF, + 0x006F30, 0x006F30, 0x000000, 0xFFFFFF, + 0x006F37, 0x006F37, 0x000000, 0xFFFFFF, + 0x006F39, 0x006F3C, 0x000000, 0xFFFFFF, + 0x006F40, 0x006F40, 0x000000, 0xFFFFFF, + 0x006F43, 0x006F43, 0x000000, 0xFFFFFF, + 0x006F4E, 0x006F50, 0x000000, 0xFFFFFF, + 0x006F52, 0x006F53, 0x000000, 0xFFFFFF, + 0x006F55, 0x006F55, 0x000000, 0xFFFFFF, + 0x006F57, 0x006F57, 0x000000, 0xFFFFFF, + 0x006F5A, 0x006F5A, 0x000000, 0xFFFFFF, + 0x006F5D, 0x006F5D, 0x000000, 0xFFFFFF, + 0x006F60, 0x006F61, 0x000000, 0xFFFFFF, + 0x006F63, 0x006F63, 0x000000, 0xFFFFFF, + 0x006F67, 0x006F67, 0x000000, 0xFFFFFF, + 0x006F69, 0x006F6C, 0x000000, 0xFFFFFF, + 0x006F73, 0x006F73, 0x000000, 0xFFFFFF, + 0x006F76, 0x006F76, 0x000000, 0xFFFFFF, + 0x006F7B, 0x006F7B, 0x000000, 0xFFFFFF, + 0x006F7D, 0x006F7E, 0x000000, 0xFFFFFF, + 0x006F85, 0x006F85, 0x000000, 0xFFFFFF, + 0x006F8B, 0x006F8B, 0x000000, 0xFFFFFF, + 0x006F90, 0x006F90, 0x000000, 0xFFFFFF, + 0x006F92, 0x006F93, 0x000000, 0xFFFFFF, + 0x006F95, 0x006F96, 0x000000, 0xFFFFFF, + 0x006F9E, 0x006F9E, 0x000000, 0xFFFFFF, + 0x006FA2, 0x006FA3, 0x000000, 0xFFFFFF, + 0x006FA5, 0x006FA6, 0x000000, 0xFFFFFF, + 0x006FA8, 0x006FA8, 0x000000, 0xFFFFFF, + 0x006FAA, 0x006FAD, 0x000000, 0xFFFFFF, + 0x006FAF, 0x006FB0, 0x000000, 0xFFFFFF, + 0x006FB2, 0x006FB2, 0x000000, 0xFFFFFF, + 0x006FB4, 0x006FB4, 0x000000, 0xFFFFFF, + 0x006FB8, 0x006FB8, 0x000000, 0xFFFFFF, + 0x006FBA, 0x006FBA, 0x000000, 0xFFFFFF, + 0x006FBC, 0x006FBD, 0x000000, 0xFFFFFF, + 0x006FBF, 0x006FBF, 0x000000, 0xFFFFFF, + 0x006FC4, 0x006FC4, 0x000000, 0xFFFFFF, + 0x006FC6, 0x006FC8, 0x000000, 0xFFFFFF, + 0x006FCA, 0x006FCF, 0x000000, 0xFFFFFF, + 0x006FD4, 0x006FD4, 0x000000, 0xFFFFFF, + 0x006FDC, 0x006FDD, 0x000000, 0xFFFFFF, + 0x006FE2, 0x006FE3, 0x000000, 0xFFFFFF, + 0x006FE6, 0x006FE9, 0x000000, 0xFFFFFF, + 0x006FED, 0x006FED, 0x000000, 0xFFFFFF, + 0x006FF2, 0x006FF2, 0x000000, 0xFFFFFF, + 0x006FF4, 0x006FF4, 0x000000, 0xFFFFFF, + 0x006FF7, 0x006FF7, 0x000000, 0xFFFFFF, + 0x006FFB, 0x006FFB, 0x000000, 0xFFFFFF, + 0x006FFF, 0x007000, 0x000000, 0xFFFFFF, + 0x007004, 0x007004, 0x000000, 0xFFFFFF, + 0x007007, 0x007007, 0x000000, 0xFFFFFF, + 0x00700A, 0x00700A, 0x000000, 0xFFFFFF, + 0x00700C, 0x00700E, 0x000000, 0xFFFFFF, + 0x007014, 0x007014, 0x000000, 0xFFFFFF, + 0x007016, 0x007017, 0x000000, 0xFFFFFF, + 0x007019, 0x007019, 0x000000, 0xFFFFFF, + 0x00701C, 0x00701C, 0x000000, 0xFFFFFF, + 0x007021, 0x007022, 0x000000, 0xFFFFFF, + 0x007024, 0x007024, 0x000000, 0xFFFFFF, + 0x007029, 0x00702B, 0x000000, 0xFFFFFF, + 0x00702F, 0x00702F, 0x000000, 0xFFFFFF, + 0x007031, 0x007031, 0x000000, 0xFFFFFF, + 0x007033, 0x007034, 0x000000, 0xFFFFFF, + 0x007037, 0x007038, 0x000000, 0xFFFFFF, + 0x00703A, 0x00703C, 0x000000, 0xFFFFFF, + 0x00703F, 0x007042, 0x000000, 0xFFFFFF, + 0x007045, 0x007046, 0x000000, 0xFFFFFF, + 0x007048, 0x00704A, 0x000000, 0xFFFFFF, + 0x007052, 0x007052, 0x000000, 0xFFFFFF, + 0x007056, 0x007057, 0x000000, 0xFFFFFF, + 0x00705A, 0x00705B, 0x000000, 0xFFFFFF, + 0x00705F, 0x007062, 0x000000, 0xFFFFFF, + 0x007065, 0x007066, 0x000000, 0xFFFFFF, + 0x007068, 0x007068, 0x000000, 0xFFFFFF, + 0x00706A, 0x00706A, 0x000000, 0xFFFFFF, + 0x007071, 0x007071, 0x000000, 0xFFFFFF, + 0x007074, 0x007074, 0x000000, 0xFFFFFF, + 0x00707A, 0x00707A, 0x000000, 0xFFFFFF, + 0x007082, 0x007084, 0x000000, 0xFFFFFF, + 0x007086, 0x007086, 0x000000, 0xFFFFFF, + 0x007091, 0x007091, 0x000000, 0xFFFFFF, + 0x007093, 0x007093, 0x000000, 0xFFFFFF, + 0x007098, 0x007098, 0x000000, 0xFFFFFF, + 0x00709A, 0x00709A, 0x000000, 0xFFFFFF, + 0x00709F, 0x00709F, 0x000000, 0xFFFFFF, + 0x0070A1, 0x0070A1, 0x000000, 0xFFFFFF, + 0x0070A9, 0x0070A9, 0x000000, 0xFFFFFF, + 0x0070B4, 0x0070B5, 0x000000, 0xFFFFFF, + 0x0070BE, 0x0070BE, 0x000000, 0xFFFFFF, + 0x0070C5, 0x0070C7, 0x000000, 0xFFFFFF, + 0x0070CB, 0x0070CB, 0x000000, 0xFFFFFF, + 0x0070CD, 0x0070CE, 0x000000, 0xFFFFFF, + 0x0070D1, 0x0070D4, 0x000000, 0xFFFFFF, + 0x0070D7, 0x0070D7, 0x000000, 0xFFFFFF, + 0x0070DA, 0x0070DA, 0x000000, 0xFFFFFF, + 0x0070DC, 0x0070DE, 0x000000, 0xFFFFFF, + 0x0070E0, 0x0070E2, 0x000000, 0xFFFFFF, + 0x0070F0, 0x0070F0, 0x000000, 0xFFFFFF, + 0x0070F3, 0x0070F3, 0x000000, 0xFFFFFF, + 0x0070F6, 0x0070F6, 0x000000, 0xFFFFFF, + 0x0070F8, 0x0070F8, 0x000000, 0xFFFFFF, + 0x0070FA, 0x0070FC, 0x000000, 0xFFFFFF, + 0x0070FF, 0x007100, 0x000000, 0xFFFFFF, + 0x007102, 0x007102, 0x000000, 0xFFFFFF, + 0x007104, 0x007104, 0x000000, 0xFFFFFF, + 0x007106, 0x007106, 0x000000, 0xFFFFFF, + 0x00710B, 0x00710E, 0x000000, 0xFFFFFF, + 0x007117, 0x007117, 0x000000, 0xFFFFFF, + 0x00711B, 0x00711C, 0x000000, 0xFFFFFF, + 0x00711E, 0x007120, 0x000000, 0xFFFFFF, + 0x007122, 0x007123, 0x000000, 0xFFFFFF, + 0x007125, 0x007125, 0x000000, 0xFFFFFF, + 0x007128, 0x007128, 0x000000, 0xFFFFFF, + 0x00712E, 0x00712E, 0x000000, 0xFFFFFF, + 0x007132, 0x007132, 0x000000, 0xFFFFFF, + 0x00713A, 0x00713A, 0x000000, 0xFFFFFF, + 0x007141, 0x007144, 0x000000, 0xFFFFFF, + 0x007146, 0x007147, 0x000000, 0xFFFFFF, + 0x00714B, 0x00714B, 0x000000, 0xFFFFFF, + 0x00714D, 0x00714D, 0x000000, 0xFFFFFF, + 0x007150, 0x007150, 0x000000, 0xFFFFFF, + 0x007153, 0x007154, 0x000000, 0xFFFFFF, + 0x007158, 0x007158, 0x000000, 0xFFFFFF, + 0x00715A, 0x00715A, 0x000000, 0xFFFFFF, + 0x00715D, 0x00715D, 0x000000, 0xFFFFFF, + 0x00715F, 0x007161, 0x000000, 0xFFFFFF, + 0x007163, 0x007163, 0x000000, 0xFFFFFF, + 0x00716A, 0x00716A, 0x000000, 0xFFFFFF, + 0x007170, 0x007170, 0x000000, 0xFFFFFF, + 0x00717B, 0x00717B, 0x000000, 0xFFFFFF, + 0x007180, 0x007182, 0x000000, 0xFFFFFF, + 0x007185, 0x007187, 0x000000, 0xFFFFFF, + 0x007189, 0x007189, 0x000000, 0xFFFFFF, + 0x007190, 0x007190, 0x000000, 0xFFFFFF, + 0x00719A, 0x00719E, 0x000000, 0xFFFFFF, + 0x0071A1, 0x0071A1, 0x000000, 0xFFFFFF, + 0x0071A4, 0x0071A5, 0x000000, 0xFFFFFF, + 0x0071A7, 0x0071A7, 0x000000, 0xFFFFFF, + 0x0071A9, 0x0071AA, 0x000000, 0xFFFFFF, + 0x0071AF, 0x0071B0, 0x000000, 0xFFFFFF, + 0x0071B2, 0x0071B2, 0x000000, 0xFFFFFF, + 0x0071B8, 0x0071B8, 0x000000, 0xFFFFFF, + 0x0071BC, 0x0071BD, 0x000000, 0xFFFFFF, + 0x0071BF, 0x0071C0, 0x000000, 0xFFFFFF, + 0x0071C2, 0x0071C2, 0x000000, 0xFFFFFF, + 0x0071C5, 0x0071C7, 0x000000, 0xFFFFFF, + 0x0071CA, 0x0071CB, 0x000000, 0xFFFFFF, + 0x0071CF, 0x0071CF, 0x000000, 0xFFFFFF, + 0x0071D6, 0x0071D6, 0x000000, 0xFFFFFF, + 0x0071D8, 0x0071D8, 0x000000, 0xFFFFFF, + 0x0071DA, 0x0071DB, 0x000000, 0xFFFFFF, + 0x0071E1, 0x0071E2, 0x000000, 0xFFFFFF, + 0x0071E4, 0x0071E4, 0x000000, 0xFFFFFF, + 0x0071E8, 0x0071E8, 0x000000, 0xFFFFFF, + 0x0071F0, 0x0071F2, 0x000000, 0xFFFFFF, + 0x0071F8, 0x0071F8, 0x000000, 0xFFFFFF, + 0x0071FD, 0x0071FD, 0x000000, 0xFFFFFF, + 0x007201, 0x007203, 0x000000, 0xFFFFFF, + 0x007205, 0x007205, 0x000000, 0xFFFFFF, + 0x007207, 0x007207, 0x000000, 0xFFFFFF, + 0x00720A, 0x00720A, 0x000000, 0xFFFFFF, + 0x00720C, 0x00720C, 0x000000, 0xFFFFFF, + 0x007213, 0x007214, 0x000000, 0xFFFFFF, + 0x007219, 0x00721A, 0x000000, 0xFFFFFF, + 0x00721E, 0x00721F, 0x000000, 0xFFFFFF, + 0x007222, 0x007223, 0x000000, 0xFFFFFF, + 0x007226, 0x007227, 0x000000, 0xFFFFFF, + 0x007229, 0x007229, 0x000000, 0xFFFFFF, + 0x007241, 0x007242, 0x000000, 0xFFFFFF, + 0x007244, 0x007244, 0x000000, 0xFFFFFF, + 0x007249, 0x00724B, 0x000000, 0xFFFFFF, + 0x00724F, 0x00724F, 0x000000, 0xFFFFFF, + 0x007253, 0x007253, 0x000000, 0xFFFFFF, + 0x00725A, 0x00725A, 0x000000, 0xFFFFFF, + 0x00725E, 0x00725E, 0x000000, 0xFFFFFF, + 0x007263, 0x007263, 0x000000, 0xFFFFFF, + 0x00726A, 0x00726A, 0x000000, 0xFFFFFF, + 0x00726C, 0x00726C, 0x000000, 0xFFFFFF, + 0x007270, 0x007270, 0x000000, 0xFFFFFF, + 0x007273, 0x007273, 0x000000, 0xFFFFFF, + 0x007276, 0x007278, 0x000000, 0xFFFFFF, + 0x00727B, 0x00727C, 0x000000, 0xFFFFFF, + 0x007285, 0x007286, 0x000000, 0xFFFFFF, + 0x007288, 0x007289, 0x000000, 0xFFFFFF, + 0x00728C, 0x00728C, 0x000000, 0xFFFFFF, + 0x00728E, 0x00728E, 0x000000, 0xFFFFFF, + 0x007290, 0x007291, 0x000000, 0xFFFFFF, + 0x007293, 0x007293, 0x000000, 0xFFFFFF, + 0x007295, 0x007295, 0x000000, 0xFFFFFF, + 0x007297, 0x007298, 0x000000, 0xFFFFFF, + 0x00729A, 0x00729A, 0x000000, 0xFFFFFF, + 0x00729D, 0x00729E, 0x000000, 0xFFFFFF, + 0x0072A1, 0x0072A1, 0x000000, 0xFFFFFF, + 0x0072A3, 0x0072A6, 0x000000, 0xFFFFFF, + 0x0072A8, 0x0072AA, 0x000000, 0xFFFFFF, + 0x0072AE, 0x0072AE, 0x000000, 0xFFFFFF, + 0x0072B5, 0x0072B5, 0x000000, 0xFFFFFF, + 0x0072BA, 0x0072BA, 0x000000, 0xFFFFFF, + 0x0072BD, 0x0072BD, 0x000000, 0xFFFFFF, + 0x0072BF, 0x0072BF, 0x000000, 0xFFFFFF, + 0x0072C5, 0x0072C6, 0x000000, 0xFFFFFF, + 0x0072C9, 0x0072CC, 0x000000, 0xFFFFFF, + 0x0072D1, 0x0072D1, 0x000000, 0xFFFFFF, + 0x0072D4, 0x0072D4, 0x000000, 0xFFFFFF, + 0x0072D6, 0x0072D6, 0x000000, 0xFFFFFF, + 0x0072D8, 0x0072D8, 0x000000, 0xFFFFFF, + 0x0072DC, 0x0072DC, 0x000000, 0xFFFFFF, + 0x0072DF, 0x0072DF, 0x000000, 0xFFFFFF, + 0x0072E3, 0x0072E4, 0x000000, 0xFFFFFF, + 0x0072E6, 0x0072E6, 0x000000, 0xFFFFFF, + 0x0072EA, 0x0072EB, 0x000000, 0xFFFFFF, + 0x0072F6, 0x0072F6, 0x000000, 0xFFFFFF, + 0x0072FE, 0x007300, 0x000000, 0xFFFFFF, + 0x007307, 0x007308, 0x000000, 0xFFFFFF, + 0x00730B, 0x00730C, 0x000000, 0xFFFFFF, + 0x00730F, 0x00730F, 0x000000, 0xFFFFFF, + 0x007311, 0x007312, 0x000000, 0xFFFFFF, + 0x007318, 0x007318, 0x000000, 0xFFFFFF, + 0x007323, 0x007323, 0x000000, 0xFFFFFF, + 0x007326, 0x007327, 0x000000, 0xFFFFFF, + 0x00732D, 0x00732D, 0x000000, 0xFFFFFF, + 0x007330, 0x007330, 0x000000, 0xFFFFFF, + 0x007332, 0x007333, 0x000000, 0xFFFFFF, + 0x007335, 0x007335, 0x000000, 0xFFFFFF, + 0x00733A, 0x00733A, 0x000000, 0xFFFFFF, + 0x00733C, 0x00733C, 0x000000, 0xFFFFFF, + 0x007340, 0x007340, 0x000000, 0xFFFFFF, + 0x007342, 0x007342, 0x000000, 0xFFFFFF, + 0x007349, 0x00734A, 0x000000, 0xFFFFFF, + 0x00734C, 0x00734C, 0x000000, 0xFFFFFF, + 0x007351, 0x007351, 0x000000, 0xFFFFFF, + 0x007358, 0x00735B, 0x000000, 0xFFFFFF, + 0x00735D, 0x00735F, 0x000000, 0xFFFFFF, + 0x007361, 0x007362, 0x000000, 0xFFFFFF, + 0x007365, 0x007367, 0x000000, 0xFFFFFF, + 0x007369, 0x007369, 0x000000, 0xFFFFFF, + 0x00736E, 0x00736E, 0x000000, 0xFFFFFF, + 0x007373, 0x007373, 0x000000, 0xFFFFFF, + 0x007376, 0x007376, 0x000000, 0xFFFFFF, + 0x00737D, 0x00737D, 0x000000, 0xFFFFFF, + 0x00737F, 0x00737F, 0x000000, 0xFFFFFF, + 0x007381, 0x007383, 0x000000, 0xFFFFFF, + 0x007388, 0x007388, 0x000000, 0xFFFFFF, + 0x00738A, 0x00738A, 0x000000, 0xFFFFFF, + 0x007392, 0x007395, 0x000000, 0xFFFFFF, + 0x007397, 0x007397, 0x000000, 0xFFFFFF, + 0x00739D, 0x00739D, 0x000000, 0xFFFFFF, + 0x0073A0, 0x0073A1, 0x000000, 0xFFFFFF, + 0x0073A4, 0x0073A6, 0x000000, 0xFFFFFF, + 0x0073AC, 0x0073AD, 0x000000, 0xFFFFFF, + 0x0073B4, 0x0073B6, 0x000000, 0xFFFFFF, + 0x0073B8, 0x0073B9, 0x000000, 0xFFFFFF, + 0x0073BC, 0x0073BC, 0x000000, 0xFFFFFF, + 0x0073BE, 0x0073BF, 0x000000, 0xFFFFFF, + 0x0073C3, 0x0073C3, 0x000000, 0xFFFFFF, + 0x0073C5, 0x0073C7, 0x000000, 0xFFFFFF, + 0x0073CB, 0x0073CC, 0x000000, 0xFFFFFF, + 0x0073D2, 0x0073D4, 0x000000, 0xFFFFFF, + 0x0073D6, 0x0073D8, 0x000000, 0xFFFFFF, + 0x0073DA, 0x0073DD, 0x000000, 0xFFFFFF, + 0x0073E3, 0x0073E3, 0x000000, 0xFFFFFF, + 0x0073E8, 0x0073E8, 0x000000, 0xFFFFFF, + 0x0073EB, 0x0073EB, 0x000000, 0xFFFFFF, + 0x0073F4, 0x0073F6, 0x000000, 0xFFFFFF, + 0x0073F8, 0x0073F8, 0x000000, 0xFFFFFF, + 0x0073FA, 0x0073FA, 0x000000, 0xFFFFFF, + 0x0073FC, 0x0073FD, 0x000000, 0xFFFFFF, + 0x0073FF, 0x007401, 0x000000, 0xFFFFFF, + 0x007404, 0x007404, 0x000000, 0xFFFFFF, + 0x007407, 0x007408, 0x000000, 0xFFFFFF, + 0x00740B, 0x00740D, 0x000000, 0xFFFFFF, + 0x007416, 0x007416, 0x000000, 0xFFFFFF, + 0x00741D, 0x00741D, 0x000000, 0xFFFFFF, + 0x007420, 0x007421, 0x000000, 0xFFFFFF, + 0x007423, 0x007424, 0x000000, 0xFFFFFF, + 0x007429, 0x007429, 0x000000, 0xFFFFFF, + 0x00742B, 0x00742B, 0x000000, 0xFFFFFF, + 0x00742D, 0x00742D, 0x000000, 0xFFFFFF, + 0x00742F, 0x00742F, 0x000000, 0xFFFFFF, + 0x007432, 0x007432, 0x000000, 0xFFFFFF, + 0x007440, 0x007440, 0x000000, 0xFFFFFF, + 0x007442, 0x007442, 0x000000, 0xFFFFFF, + 0x007444, 0x007444, 0x000000, 0xFFFFFF, + 0x007446, 0x007446, 0x000000, 0xFFFFFF, + 0x00744A, 0x00744A, 0x000000, 0xFFFFFF, + 0x00744D, 0x007452, 0x000000, 0xFFFFFF, + 0x007454, 0x007454, 0x000000, 0xFFFFFF, + 0x007462, 0x007462, 0x000000, 0xFFFFFF, + 0x007467, 0x007467, 0x000000, 0xFFFFFF, + 0x00746E, 0x00746E, 0x000000, 0xFFFFFF, + 0x007471, 0x007473, 0x000000, 0xFFFFFF, + 0x007475, 0x007475, 0x000000, 0xFFFFFF, + 0x007479, 0x007479, 0x000000, 0xFFFFFF, + 0x00747C, 0x00747D, 0x000000, 0xFFFFFF, + 0x00747F, 0x00747F, 0x000000, 0xFFFFFF, + 0x007485, 0x007486, 0x000000, 0xFFFFFF, + 0x007488, 0x007488, 0x000000, 0xFFFFFF, + 0x00748A, 0x00748A, 0x000000, 0xFFFFFF, + 0x007492, 0x007492, 0x000000, 0xFFFFFF, + 0x007494, 0x007495, 0x000000, 0xFFFFFF, + 0x007497, 0x007498, 0x000000, 0xFFFFFF, + 0x00749A, 0x00749A, 0x000000, 0xFFFFFF, + 0x00749F, 0x0074A1, 0x000000, 0xFFFFFF, + 0x0074A5, 0x0074A5, 0x000000, 0xFFFFFF, + 0x0074AA, 0x0074AB, 0x000000, 0xFFFFFF, + 0x0074AD, 0x0074AD, 0x000000, 0xFFFFFF, + 0x0074AF, 0x0074AF, 0x000000, 0xFFFFFF, + 0x0074B1, 0x0074B2, 0x000000, 0xFFFFFF, + 0x0074B5, 0x0074B8, 0x000000, 0xFFFFFF, + 0x0074BB, 0x0074BB, 0x000000, 0xFFFFFF, + 0x0074BE, 0x0074BE, 0x000000, 0xFFFFFF, + 0x0074C0, 0x0074C3, 0x000000, 0xFFFFFF, + 0x0074C5, 0x0074C5, 0x000000, 0xFFFFFF, + 0x0074CB, 0x0074CB, 0x000000, 0xFFFFFF, + 0x0074D5, 0x0074D5, 0x000000, 0xFFFFFF, + 0x0074D7, 0x0074D9, 0x000000, 0xFFFFFF, + 0x0074DB, 0x0074DB, 0x000000, 0xFFFFFF, + 0x0074DD, 0x0074DD, 0x000000, 0xFFFFFF, + 0x0074DF, 0x0074DF, 0x000000, 0xFFFFFF, + 0x0074E1, 0x0074E1, 0x000000, 0xFFFFFF, + 0x0074E5, 0x0074E5, 0x000000, 0xFFFFFF, + 0x0074E8, 0x0074E9, 0x000000, 0xFFFFFF, + 0x0074EC, 0x0074EC, 0x000000, 0xFFFFFF, + 0x0074F5, 0x0074F5, 0x000000, 0xFFFFFF, + 0x0074FB, 0x0074FB, 0x000000, 0xFFFFFF, + 0x0074FD, 0x0074FE, 0x000000, 0xFFFFFF, + 0x007500, 0x007500, 0x000000, 0xFFFFFF, + 0x007502, 0x007503, 0x000000, 0xFFFFFF, + 0x007507, 0x007508, 0x000000, 0xFFFFFF, + 0x00750B, 0x00750B, 0x000000, 0xFFFFFF, + 0x007510, 0x007510, 0x000000, 0xFFFFFF, + 0x007512, 0x007512, 0x000000, 0xFFFFFF, + 0x007514, 0x007514, 0x000000, 0xFFFFFF, + 0x007516, 0x007517, 0x000000, 0xFFFFFF, + 0x00751D, 0x00751D, 0x000000, 0xFFFFFF, + 0x007521, 0x007521, 0x000000, 0xFFFFFF, + 0x00752E, 0x00752E, 0x000000, 0xFFFFFF, + 0x007539, 0x007539, 0x000000, 0xFFFFFF, + 0x00753D, 0x00753D, 0x000000, 0xFFFFFF, + 0x00753F, 0x00753F, 0x000000, 0xFFFFFF, + 0x007547, 0x007547, 0x000000, 0xFFFFFF, + 0x00755F, 0x00755F, 0x000000, 0xFFFFFF, + 0x007563, 0x007564, 0x000000, 0xFFFFFF, + 0x00756F, 0x00756F, 0x000000, 0xFFFFFF, + 0x007577, 0x007577, 0x000000, 0xFFFFFF, + 0x00757D, 0x00757E, 0x000000, 0xFFFFFF, + 0x007580, 0x007580, 0x000000, 0xFFFFFF, + 0x007584, 0x007584, 0x000000, 0xFFFFFF, + 0x00758C, 0x00758C, 0x000000, 0xFFFFFF, + 0x007590, 0x007590, 0x000000, 0xFFFFFF, + 0x007595, 0x007595, 0x000000, 0xFFFFFF, + 0x007598, 0x007598, 0x000000, 0xFFFFFF, + 0x0075A2, 0x0075A2, 0x000000, 0xFFFFFF, + 0x0075A7, 0x0075A7, 0x000000, 0xFFFFFF, + 0x0075AA, 0x0075AA, 0x000000, 0xFFFFFF, + 0x0075B6, 0x0075B6, 0x000000, 0xFFFFFF, + 0x0075BA, 0x0075BB, 0x000000, 0xFFFFFF, + 0x0075C0, 0x0075C1, 0x000000, 0xFFFFFF, + 0x0075CB, 0x0075CC, 0x000000, 0xFFFFFF, + 0x0075CE, 0x0075D1, 0x000000, 0xFFFFFF, + 0x0075D7, 0x0075D7, 0x000000, 0xFFFFFF, + 0x0075DA, 0x0075DA, 0x000000, 0xFFFFFF, + 0x0075DD, 0x0075DD, 0x000000, 0xFFFFFF, + 0x0075DF, 0x0075DF, 0x000000, 0xFFFFFF, + 0x0075E1, 0x0075E1, 0x000000, 0xFFFFFF, + 0x0075ED, 0x0075ED, 0x000000, 0xFFFFFF, + 0x0075EF, 0x0075EF, 0x000000, 0xFFFFFF, + 0x0075F5, 0x0075F8, 0x000000, 0xFFFFFF, + 0x0075FB, 0x0075FB, 0x000000, 0xFFFFFF, + 0x0075FD, 0x0075FD, 0x000000, 0xFFFFFF, + 0x007608, 0x007608, 0x000000, 0xFFFFFF, + 0x00760F, 0x00760F, 0x000000, 0xFFFFFF, + 0x007611, 0x007611, 0x000000, 0xFFFFFF, + 0x007614, 0x007614, 0x000000, 0xFFFFFF, + 0x007616, 0x007616, 0x000000, 0xFFFFFF, + 0x00761A, 0x00761A, 0x000000, 0xFFFFFF, + 0x00761C, 0x00761D, 0x000000, 0xFFFFFF, + 0x007623, 0x007623, 0x000000, 0xFFFFFF, + 0x007628, 0x007628, 0x000000, 0xFFFFFF, + 0x00762F, 0x00762F, 0x000000, 0xFFFFFF, + 0x007631, 0x007632, 0x000000, 0xFFFFFF, + 0x00763D, 0x00763D, 0x000000, 0xFFFFFF, + 0x007648, 0x007648, 0x000000, 0xFFFFFF, + 0x007650, 0x007650, 0x000000, 0xFFFFFF, + 0x007653, 0x007653, 0x000000, 0xFFFFFF, + 0x007657, 0x007657, 0x000000, 0xFFFFFF, + 0x007659, 0x00765A, 0x000000, 0xFFFFFF, + 0x007660, 0x007660, 0x000000, 0xFFFFFF, + 0x00766A, 0x00766A, 0x000000, 0xFFFFFF, + 0x007675, 0x007675, 0x000000, 0xFFFFFF, + 0x007679, 0x007679, 0x000000, 0xFFFFFF, + 0x00767F, 0x00767F, 0x000000, 0xFFFFFF, + 0x007689, 0x00768A, 0x000000, 0xFFFFFF, + 0x00768F, 0x00768F, 0x000000, 0xFFFFFF, + 0x007692, 0x007692, 0x000000, 0xFFFFFF, + 0x007695, 0x007695, 0x000000, 0xFFFFFF, + 0x00769B, 0x00769E, 0x000000, 0xFFFFFF, + 0x0076A6, 0x0076A6, 0x000000, 0xFFFFFF, + 0x0076AA, 0x0076AB, 0x000000, 0xFFFFFF, + 0x0076AD, 0x0076AD, 0x000000, 0xFFFFFF, + 0x0076AF, 0x0076AF, 0x000000, 0xFFFFFF, + 0x0076B5, 0x0076B5, 0x000000, 0xFFFFFF, + 0x0076BB, 0x0076BB, 0x000000, 0xFFFFFF, + 0x0076BD, 0x0076BE, 0x000000, 0xFFFFFF, + 0x0076C4, 0x0076C4, 0x000000, 0xFFFFFF, + 0x0076C9, 0x0076C9, 0x000000, 0xFFFFFF, + 0x0076D3, 0x0076D3, 0x000000, 0xFFFFFF, + 0x0076DA, 0x0076DA, 0x000000, 0xFFFFFF, + 0x0076DD, 0x0076DD, 0x000000, 0xFFFFFF, + 0x0076E6, 0x0076E6, 0x000000, 0xFFFFFF, + 0x0076E9, 0x0076E9, 0x000000, 0xFFFFFF, + 0x0076EC, 0x0076ED, 0x000000, 0xFFFFFF, + 0x0076F0, 0x0076F0, 0x000000, 0xFFFFFF, + 0x0076F3, 0x0076F3, 0x000000, 0xFFFFFF, + 0x0076F5, 0x0076F5, 0x000000, 0xFFFFFF, + 0x0076F7, 0x0076F7, 0x000000, 0xFFFFFF, + 0x0076FA, 0x0076FB, 0x000000, 0xFFFFFF, + 0x007703, 0x007703, 0x000000, 0xFFFFFF, + 0x007705, 0x007705, 0x000000, 0xFFFFFF, + 0x00770A, 0x00770A, 0x000000, 0xFFFFFF, + 0x007710, 0x007713, 0x000000, 0xFFFFFF, + 0x007715, 0x007715, 0x000000, 0xFFFFFF, + 0x00771B, 0x00771B, 0x000000, 0xFFFFFF, + 0x00771D, 0x00771D, 0x000000, 0xFFFFFF, + 0x007723, 0x007723, 0x000000, 0xFFFFFF, + 0x007727, 0x007727, 0x000000, 0xFFFFFF, + 0x007731, 0x007734, 0x000000, 0xFFFFFF, + 0x007739, 0x007739, 0x000000, 0xFFFFFF, + 0x00773B, 0x00773B, 0x000000, 0xFFFFFF, + 0x00773D, 0x00773D, 0x000000, 0xFFFFFF, + 0x007744, 0x007746, 0x000000, 0xFFFFFF, + 0x00774A, 0x00774E, 0x000000, 0xFFFFFF, + 0x007752, 0x007752, 0x000000, 0xFFFFFF, + 0x007754, 0x007756, 0x000000, 0xFFFFFF, + 0x007759, 0x007759, 0x000000, 0xFFFFFF, + 0x00775F, 0x007760, 0x000000, 0xFFFFFF, + 0x007767, 0x007767, 0x000000, 0xFFFFFF, + 0x007769, 0x007769, 0x000000, 0xFFFFFF, + 0x00776D, 0x00776F, 0x000000, 0xFFFFFF, + 0x00777C, 0x00777C, 0x000000, 0xFFFFFF, + 0x007781, 0x007783, 0x000000, 0xFFFFFF, + 0x007788, 0x007789, 0x000000, 0xFFFFFF, + 0x00778B, 0x00778B, 0x000000, 0xFFFFFF, + 0x00778F, 0x00778F, 0x000000, 0xFFFFFF, + 0x007795, 0x007795, 0x000000, 0xFFFFFF, + 0x007797, 0x007797, 0x000000, 0xFFFFFF, + 0x007799, 0x00779D, 0x000000, 0xFFFFFF, + 0x0077A1, 0x0077A1, 0x000000, 0xFFFFFF, + 0x0077A3, 0x0077A3, 0x000000, 0xFFFFFF, + 0x0077A8, 0x0077A8, 0x000000, 0xFFFFFF, + 0x0077AB, 0x0077AB, 0x000000, 0xFFFFFF, + 0x0077B1, 0x0077B2, 0x000000, 0xFFFFFF, + 0x0077B4, 0x0077B4, 0x000000, 0xFFFFFF, + 0x0077B6, 0x0077B7, 0x000000, 0xFFFFFF, + 0x0077BA, 0x0077BA, 0x000000, 0xFFFFFF, + 0x0077C2, 0x0077C2, 0x000000, 0xFFFFFF, + 0x0077C4, 0x0077C4, 0x000000, 0xFFFFFF, + 0x0077C9, 0x0077CA, 0x000000, 0xFFFFFF, + 0x0077CC, 0x0077CC, 0x000000, 0xFFFFFF, + 0x0077CE, 0x0077D0, 0x000000, 0xFFFFFF, + 0x0077D4, 0x0077D5, 0x000000, 0xFFFFFF, + 0x0077D8, 0x0077D9, 0x000000, 0xFFFFFF, + 0x0077DE, 0x0077DE, 0x000000, 0xFFFFFF, + 0x0077E0, 0x0077E0, 0x000000, 0xFFFFFF, + 0x0077E8, 0x0077E8, 0x000000, 0xFFFFFF, + 0x0077F0, 0x0077F2, 0x000000, 0xFFFFFF, + 0x0077F7, 0x0077F7, 0x000000, 0xFFFFFF, + 0x0077F9, 0x0077FC, 0x000000, 0xFFFFFF, + 0x007803, 0x007803, 0x000000, 0xFFFFFF, + 0x007805, 0x007806, 0x000000, 0xFFFFFF, + 0x00780E, 0x007810, 0x000000, 0xFFFFFF, + 0x007813, 0x007813, 0x000000, 0xFFFFFF, + 0x007820, 0x007822, 0x000000, 0xFFFFFF, + 0x007828, 0x007828, 0x000000, 0xFFFFFF, + 0x00782A, 0x00782B, 0x000000, 0xFFFFFF, + 0x00782E, 0x00782F, 0x000000, 0xFFFFFF, + 0x007831, 0x007831, 0x000000, 0xFFFFFF, + 0x007833, 0x007833, 0x000000, 0xFFFFFF, + 0x007835, 0x007835, 0x000000, 0xFFFFFF, + 0x007848, 0x00784A, 0x000000, 0xFFFFFF, + 0x00784D, 0x00784D, 0x000000, 0xFFFFFF, + 0x00785C, 0x00785C, 0x000000, 0xFFFFFF, + 0x00785E, 0x00785E, 0x000000, 0xFFFFFF, + 0x007860, 0x007860, 0x000000, 0xFFFFFF, + 0x007862, 0x007862, 0x000000, 0xFFFFFF, + 0x007865, 0x007865, 0x000000, 0xFFFFFF, + 0x007869, 0x007869, 0x000000, 0xFFFFFF, + 0x007870, 0x007871, 0x000000, 0xFFFFFF, + 0x007879, 0x007879, 0x000000, 0xFFFFFF, + 0x00787B, 0x00787B, 0x000000, 0xFFFFFF, + 0x00787E, 0x007880, 0x000000, 0xFFFFFF, + 0x007883, 0x007886, 0x000000, 0xFFFFFF, + 0x00788F, 0x00788F, 0x000000, 0xFFFFFF, + 0x007894, 0x007894, 0x000000, 0xFFFFFF, + 0x007896, 0x007896, 0x000000, 0xFFFFFF, + 0x007899, 0x007899, 0x000000, 0xFFFFFF, + 0x00789E, 0x00789E, 0x000000, 0xFFFFFF, + 0x0078A0, 0x0078A0, 0x000000, 0xFFFFFF, + 0x0078A2, 0x0078A2, 0x000000, 0xFFFFFF, + 0x0078A4, 0x0078A4, 0x000000, 0xFFFFFF, + 0x0078A8, 0x0078A8, 0x000000, 0xFFFFFF, + 0x0078AB, 0x0078AC, 0x000000, 0xFFFFFF, + 0x0078BB, 0x0078BB, 0x000000, 0xFFFFFF, + 0x0078C3, 0x0078C4, 0x000000, 0xFFFFFF, + 0x0078C8, 0x0078C8, 0x000000, 0xFFFFFF, + 0x0078CC, 0x0078CF, 0x000000, 0xFFFFFF, + 0x0078D1, 0x0078D1, 0x000000, 0xFFFFFF, + 0x0078DB, 0x0078DB, 0x000000, 0xFFFFFF, + 0x0078DD, 0x0078E2, 0x000000, 0xFFFFFF, + 0x0078E5, 0x0078E5, 0x000000, 0xFFFFFF, + 0x0078E9, 0x0078EA, 0x000000, 0xFFFFFF, + 0x0078ED, 0x0078ED, 0x000000, 0xFFFFFF, + 0x0078F3, 0x0078F3, 0x000000, 0xFFFFFF, + 0x0078F9, 0x0078F9, 0x000000, 0xFFFFFF, + 0x0078FB, 0x0078FC, 0x000000, 0xFFFFFF, + 0x0078FE, 0x0078FF, 0x000000, 0xFFFFFF, + 0x007902, 0x007902, 0x000000, 0xFFFFFF, + 0x007904, 0x007904, 0x000000, 0xFFFFFF, + 0x007909, 0x007909, 0x000000, 0xFFFFFF, + 0x00790C, 0x00790C, 0x000000, 0xFFFFFF, + 0x007910, 0x007912, 0x000000, 0xFFFFFF, + 0x007914, 0x007914, 0x000000, 0xFFFFFF, + 0x007917, 0x007917, 0x000000, 0xFFFFFF, + 0x00791B, 0x00791D, 0x000000, 0xFFFFFF, + 0x007923, 0x007923, 0x000000, 0xFFFFFF, + 0x007925, 0x007925, 0x000000, 0xFFFFFF, + 0x007927, 0x007929, 0x000000, 0xFFFFFF, + 0x00792D, 0x00792D, 0x000000, 0xFFFFFF, + 0x00792F, 0x00792F, 0x000000, 0xFFFFFF, + 0x007935, 0x007935, 0x000000, 0xFFFFFF, + 0x007938, 0x007939, 0x000000, 0xFFFFFF, + 0x00793D, 0x00793D, 0x000000, 0xFFFFFF, + 0x00793F, 0x00793F, 0x000000, 0xFFFFFF, + 0x007944, 0x007944, 0x000000, 0xFFFFFF, + 0x00794A, 0x00794C, 0x000000, 0xFFFFFF, + 0x00794F, 0x00794F, 0x000000, 0xFFFFFF, + 0x007951, 0x007952, 0x000000, 0xFFFFFF, + 0x007954, 0x007954, 0x000000, 0xFFFFFF, + 0x007961, 0x007961, 0x000000, 0xFFFFFF, + 0x007963, 0x007964, 0x000000, 0xFFFFFF, + 0x007969, 0x00796B, 0x000000, 0xFFFFFF, + 0x007970, 0x007970, 0x000000, 0xFFFFFF, + 0x007972, 0x007974, 0x000000, 0xFFFFFF, + 0x007979, 0x007979, 0x000000, 0xFFFFFF, + 0x00797D, 0x00797D, 0x000000, 0xFFFFFF, + 0x007982, 0x007982, 0x000000, 0xFFFFFF, + 0x007988, 0x007988, 0x000000, 0xFFFFFF, + 0x00798B, 0x00798B, 0x000000, 0xFFFFFF, + 0x007990, 0x007990, 0x000000, 0xFFFFFF, + 0x007992, 0x007998, 0x000000, 0xFFFFFF, + 0x00799B, 0x00799C, 0x000000, 0xFFFFFF, + 0x0079A0, 0x0079A2, 0x000000, 0xFFFFFF, + 0x0079A4, 0x0079A4, 0x000000, 0xFFFFFF, + 0x0079A8, 0x0079A8, 0x000000, 0xFFFFFF, + 0x0079AB, 0x0079AD, 0x000000, 0xFFFFFF, + 0x0079B2, 0x0079B2, 0x000000, 0xFFFFFF, + 0x0079B4, 0x0079B4, 0x000000, 0xFFFFFF, + 0x0079B6, 0x0079B8, 0x000000, 0xFFFFFF, + 0x0079C5, 0x0079C5, 0x000000, 0xFFFFFF, + 0x0079CE, 0x0079CE, 0x000000, 0xFFFFFF, + 0x0079D6, 0x0079D6, 0x000000, 0xFFFFFF, + 0x0079DC, 0x0079DE, 0x000000, 0xFFFFFF, + 0x0079E0, 0x0079E0, 0x000000, 0xFFFFFF, + 0x0079EA, 0x0079EA, 0x000000, 0xFFFFFF, + 0x0079EC, 0x0079EC, 0x000000, 0xFFFFFF, + 0x0079EE, 0x0079EE, 0x000000, 0xFFFFFF, + 0x0079F6, 0x0079F7, 0x000000, 0xFFFFFF, + 0x0079FA, 0x0079FA, 0x000000, 0xFFFFFF, + 0x007A04, 0x007A04, 0x000000, 0xFFFFFF, + 0x007A0A, 0x007A0A, 0x000000, 0xFFFFFF, + 0x007A0C, 0x007A0C, 0x000000, 0xFFFFFF, + 0x007A10, 0x007A13, 0x000000, 0xFFFFFF, + 0x007A15, 0x007A15, 0x000000, 0xFFFFFF, + 0x007A18, 0x007A19, 0x000000, 0xFFFFFF, + 0x007A1B, 0x007A1B, 0x000000, 0xFFFFFF, + 0x007A22, 0x007A22, 0x000000, 0xFFFFFF, + 0x007A26, 0x007A26, 0x000000, 0xFFFFFF, + 0x007A2B, 0x007A2B, 0x000000, 0xFFFFFF, + 0x007A2F, 0x007A30, 0x000000, 0xFFFFFF, + 0x007A44, 0x007A44, 0x000000, 0xFFFFFF, + 0x007A47, 0x007A48, 0x000000, 0xFFFFFF, + 0x007A4A, 0x007A4B, 0x000000, 0xFFFFFF, + 0x007A54, 0x007A54, 0x000000, 0xFFFFFF, + 0x007A56, 0x007A56, 0x000000, 0xFFFFFF, + 0x007A58, 0x007A58, 0x000000, 0xFFFFFF, + 0x007A5A, 0x007A5C, 0x000000, 0xFFFFFF, + 0x007A5F, 0x007A60, 0x000000, 0xFFFFFF, + 0x007A67, 0x007A67, 0x000000, 0xFFFFFF, + 0x007A6C, 0x007A6E, 0x000000, 0xFFFFFF, + 0x007A71, 0x007A71, 0x000000, 0xFFFFFF, + 0x007A75, 0x007A75, 0x000000, 0xFFFFFF, + 0x007A7B, 0x007A7B, 0x000000, 0xFFFFFF, + 0x007A7E, 0x007A7E, 0x000000, 0xFFFFFF, + 0x007A85, 0x007A85, 0x000000, 0xFFFFFF, + 0x007A87, 0x007A87, 0x000000, 0xFFFFFF, + 0x007A89, 0x007A8C, 0x000000, 0xFFFFFF, + 0x007A8F, 0x007A90, 0x000000, 0xFFFFFF, + 0x007A94, 0x007A94, 0x000000, 0xFFFFFF, + 0x007A99, 0x007A99, 0x000000, 0xFFFFFF, + 0x007A9E, 0x007A9E, 0x000000, 0xFFFFFF, + 0x007AA2, 0x007AA3, 0x000000, 0xFFFFFF, + 0x007AAB, 0x007AAB, 0x000000, 0xFFFFFF, + 0x007AB1, 0x007AB2, 0x000000, 0xFFFFFF, + 0x007AB4, 0x007AB5, 0x000000, 0xFFFFFF, + 0x007AB7, 0x007AB8, 0x000000, 0xFFFFFF, + 0x007ABE, 0x007ABE, 0x000000, 0xFFFFFF, + 0x007AC0, 0x007AC1, 0x000000, 0xFFFFFF, + 0x007AD1, 0x007AD1, 0x000000, 0xFFFFFF, + 0x007AD8, 0x007AD8, 0x000000, 0xFFFFFF, + 0x007AE4, 0x007AE4, 0x000000, 0xFFFFFF, + 0x007AEB, 0x007AEB, 0x000000, 0xFFFFFF, + 0x007AEE, 0x007AEE, 0x000000, 0xFFFFFF, + 0x007AF7, 0x007AF7, 0x000000, 0xFFFFFF, + 0x007AFB, 0x007AFB, 0x000000, 0xFFFFFF, + 0x007B00, 0x007B01, 0x000000, 0xFFFFFF, + 0x007B05, 0x007B05, 0x000000, 0xFFFFFF, + 0x007B09, 0x007B09, 0x000000, 0xFFFFFF, + 0x007B0E, 0x007B0E, 0x000000, 0xFFFFFF, + 0x007B10, 0x007B10, 0x000000, 0xFFFFFF, + 0x007B12, 0x007B13, 0x000000, 0xFFFFFF, + 0x007B18, 0x007B18, 0x000000, 0xFFFFFF, + 0x007B1A, 0x007B1A, 0x000000, 0xFFFFFF, + 0x007B1D, 0x007B1D, 0x000000, 0xFFFFFF, + 0x007B22, 0x007B23, 0x000000, 0xFFFFFF, + 0x007B2D, 0x007B2D, 0x000000, 0xFFFFFF, + 0x007B2F, 0x007B30, 0x000000, 0xFFFFFF, + 0x007B32, 0x007B32, 0x000000, 0xFFFFFF, + 0x007B34, 0x007B35, 0x000000, 0xFFFFFF, + 0x007B40, 0x007B40, 0x000000, 0xFFFFFF, + 0x007B44, 0x007B44, 0x000000, 0xFFFFFF, + 0x007B48, 0x007B48, 0x000000, 0xFFFFFF, + 0x007B4A, 0x007B4A, 0x000000, 0xFFFFFF, + 0x007B4E, 0x007B4E, 0x000000, 0xFFFFFF, + 0x007B61, 0x007B61, 0x000000, 0xFFFFFF, + 0x007B63, 0x007B66, 0x000000, 0xFFFFFF, + 0x007B69, 0x007B69, 0x000000, 0xFFFFFF, + 0x007B6D, 0x007B6D, 0x000000, 0xFFFFFF, + 0x007B70, 0x007B70, 0x000000, 0xFFFFFF, + 0x007B73, 0x007B73, 0x000000, 0xFFFFFF, + 0x007B76, 0x007B76, 0x000000, 0xFFFFFF, + 0x007B78, 0x007B78, 0x000000, 0xFFFFFF, + 0x007B82, 0x007B82, 0x000000, 0xFFFFFF, + 0x007B88, 0x007B88, 0x000000, 0xFFFFFF, + 0x007B8A, 0x007B8A, 0x000000, 0xFFFFFF, + 0x007B8C, 0x007B8C, 0x000000, 0xFFFFFF, + 0x007B8E, 0x007B8E, 0x000000, 0xFFFFFF, + 0x007B91, 0x007B91, 0x000000, 0xFFFFFF, + 0x007B96, 0x007B96, 0x000000, 0xFFFFFF, + 0x007B98, 0x007B99, 0x000000, 0xFFFFFF, + 0x007B9B, 0x007B9B, 0x000000, 0xFFFFFF, + 0x007BA4, 0x007BA4, 0x000000, 0xFFFFFF, + 0x007BAF, 0x007BAF, 0x000000, 0xFFFFFF, + 0x007BB5, 0x007BB5, 0x000000, 0xFFFFFF, + 0x007BB7, 0x007BB7, 0x000000, 0xFFFFFF, + 0x007BB9, 0x007BB9, 0x000000, 0xFFFFFF, + 0x007BBE, 0x007BBE, 0x000000, 0xFFFFFF, + 0x007BCA, 0x007BCA, 0x000000, 0xFFFFFF, + 0x007BCE, 0x007BCE, 0x000000, 0xFFFFFF, + 0x007BD4, 0x007BD5, 0x000000, 0xFFFFFF, + 0x007BD8, 0x007BD8, 0x000000, 0xFFFFFF, + 0x007BDC, 0x007BDC, 0x000000, 0xFFFFFF, + 0x007BDE, 0x007BDF, 0x000000, 0xFFFFFF, + 0x007BE2, 0x007BE3, 0x000000, 0xFFFFFF, + 0x007BE7, 0x007BE8, 0x000000, 0xFFFFFF, + 0x007BEB, 0x007BEB, 0x000000, 0xFFFFFF, + 0x007BF0, 0x007BF0, 0x000000, 0xFFFFFF, + 0x007BF4, 0x007BF4, 0x000000, 0xFFFFFF, + 0x007BF8, 0x007BF9, 0x000000, 0xFFFFFF, + 0x007BFB, 0x007BFB, 0x000000, 0xFFFFFF, + 0x007BFD, 0x007BFD, 0x000000, 0xFFFFFF, + 0x007BFF, 0x007BFF, 0x000000, 0xFFFFFF, + 0x007C01, 0x007C03, 0x000000, 0xFFFFFF, + 0x007C05, 0x007C06, 0x000000, 0xFFFFFF, + 0x007C09, 0x007C0A, 0x000000, 0xFFFFFF, + 0x007C0E, 0x007C0E, 0x000000, 0xFFFFFF, + 0x007C10, 0x007C10, 0x000000, 0xFFFFFF, + 0x007C19, 0x007C19, 0x000000, 0xFFFFFF, + 0x007C1C, 0x007C1D, 0x000000, 0xFFFFFF, + 0x007C20, 0x007C20, 0x000000, 0xFFFFFF, + 0x007C22, 0x007C22, 0x000000, 0xFFFFFF, + 0x007C25, 0x007C25, 0x000000, 0xFFFFFF, + 0x007C28, 0x007C29, 0x000000, 0xFFFFFF, + 0x007C2C, 0x007C2D, 0x000000, 0xFFFFFF, + 0x007C30, 0x007C30, 0x000000, 0xFFFFFF, + 0x007C33, 0x007C33, 0x000000, 0xFFFFFF, + 0x007C39, 0x007C39, 0x000000, 0xFFFFFF, + 0x007C3B, 0x007C3C, 0x000000, 0xFFFFFF, + 0x007C45, 0x007C45, 0x000000, 0xFFFFFF, + 0x007C47, 0x007C4A, 0x000000, 0xFFFFFF, + 0x007C53, 0x007C54, 0x000000, 0xFFFFFF, + 0x007C57, 0x007C57, 0x000000, 0xFFFFFF, + 0x007C59, 0x007C5B, 0x000000, 0xFFFFFF, + 0x007C63, 0x007C63, 0x000000, 0xFFFFFF, + 0x007C66, 0x007C67, 0x000000, 0xFFFFFF, + 0x007C6B, 0x007C6B, 0x000000, 0xFFFFFF, + 0x007C6F, 0x007C6F, 0x000000, 0xFFFFFF, + 0x007C75, 0x007C75, 0x000000, 0xFFFFFF, + 0x007C78, 0x007C7A, 0x000000, 0xFFFFFF, + 0x007C7F, 0x007C81, 0x000000, 0xFFFFFF, + 0x007C84, 0x007C85, 0x000000, 0xFFFFFF, + 0x007C88, 0x007C88, 0x000000, 0xFFFFFF, + 0x007C8A, 0x007C8A, 0x000000, 0xFFFFFF, + 0x007C8C, 0x007C8D, 0x000000, 0xFFFFFF, + 0x007C94, 0x007C94, 0x000000, 0xFFFFFF, + 0x007C96, 0x007C96, 0x000000, 0xFFFFFF, + 0x007CA1, 0x007CA1, 0x000000, 0xFFFFFF, + 0x007CA3, 0x007CA3, 0x000000, 0xFFFFFF, + 0x007CA8, 0x007CA8, 0x000000, 0xFFFFFF, + 0x007CAF, 0x007CAF, 0x000000, 0xFFFFFF, + 0x007CB4, 0x007CB4, 0x000000, 0xFFFFFF, + 0x007CBA, 0x007CBB, 0x000000, 0xFFFFFF, + 0x007CBF, 0x007CBF, 0x000000, 0xFFFFFF, + 0x007CCB, 0x007CCB, 0x000000, 0xFFFFFF, + 0x007CCE, 0x007CCE, 0x000000, 0xFFFFFF, + 0x007CD0, 0x007CD2, 0x000000, 0xFFFFFF, + 0x007CD4, 0x007CD4, 0x000000, 0xFFFFFF, + 0x007CEA, 0x007CEA, 0x000000, 0xFFFFFF, + 0x007CEC, 0x007CEC, 0x000000, 0xFFFFFF, + 0x007CEE, 0x007CEE, 0x000000, 0xFFFFFF, + 0x007CF1, 0x007CF1, 0x000000, 0xFFFFFF, + 0x007CF7, 0x007CF7, 0x000000, 0xFFFFFF, + 0x007CFD, 0x007CFD, 0x000000, 0xFFFFFF, + 0x007D01, 0x007D01, 0x000000, 0xFFFFFF, + 0x007D03, 0x007D03, 0x000000, 0xFFFFFF, + 0x007D0C, 0x007D0C, 0x000000, 0xFFFFFF, + 0x007D0E, 0x007D0F, 0x000000, 0xFFFFFF, + 0x007D11, 0x007D12, 0x000000, 0xFFFFFF, + 0x007D16, 0x007D16, 0x000000, 0xFFFFFF, + 0x007D18, 0x007D18, 0x000000, 0xFFFFFF, + 0x007D1D, 0x007D1F, 0x000000, 0xFFFFFF, + 0x007D28, 0x007D29, 0x000000, 0xFFFFFF, + 0x007D2C, 0x007D2C, 0x000000, 0xFFFFFF, + 0x007D35, 0x007D36, 0x000000, 0xFFFFFF, + 0x007D38, 0x007D38, 0x000000, 0xFFFFFF, + 0x007D3B, 0x007D3B, 0x000000, 0xFFFFFF, + 0x007D3D, 0x007D3E, 0x000000, 0xFFFFFF, + 0x007D41, 0x007D41, 0x000000, 0xFFFFFF, + 0x007D45, 0x007D45, 0x000000, 0xFFFFFF, + 0x007D47, 0x007D47, 0x000000, 0xFFFFFF, + 0x007D4A, 0x007D4A, 0x000000, 0xFFFFFF, + 0x007D4F, 0x007D4F, 0x000000, 0xFFFFFF, + 0x007D51, 0x007D54, 0x000000, 0xFFFFFF, + 0x007D56, 0x007D56, 0x000000, 0xFFFFFF, + 0x007D58, 0x007D58, 0x000000, 0xFFFFFF, + 0x007D5C, 0x007D5C, 0x000000, 0xFFFFFF, + 0x007D5F, 0x007D5F, 0x000000, 0xFFFFFF, + 0x007D63, 0x007D63, 0x000000, 0xFFFFFF, + 0x007D67, 0x007D67, 0x000000, 0xFFFFFF, + 0x007D69, 0x007D6B, 0x000000, 0xFFFFFF, + 0x007D6D, 0x007D6D, 0x000000, 0xFFFFFF, + 0x007D6F, 0x007D70, 0x000000, 0xFFFFFF, + 0x007D7A, 0x007D7D, 0x000000, 0xFFFFFF, + 0x007D7F, 0x007D80, 0x000000, 0xFFFFFF, + 0x007D84, 0x007D85, 0x000000, 0xFFFFFF, + 0x007D8C, 0x007D8E, 0x000000, 0xFFFFFF, + 0x007D92, 0x007D92, 0x000000, 0xFFFFFF, + 0x007D94, 0x007D94, 0x000000, 0xFFFFFF, + 0x007D96, 0x007D96, 0x000000, 0xFFFFFF, + 0x007D9D, 0x007D9D, 0x000000, 0xFFFFFF, + 0x007D9F, 0x007D9F, 0x000000, 0xFFFFFF, + 0x007DA1, 0x007DA1, 0x000000, 0xFFFFFF, + 0x007DA7, 0x007DA7, 0x000000, 0xFFFFFF, + 0x007DA9, 0x007DAA, 0x000000, 0xFFFFFF, + 0x007DAF, 0x007DAF, 0x000000, 0xFFFFFF, + 0x007DB7, 0x007DB7, 0x000000, 0xFFFFFF, + 0x007DBC, 0x007DBC, 0x000000, 0xFFFFFF, + 0x007DC0, 0x007DC2, 0x000000, 0xFFFFFF, + 0x007DC5, 0x007DC6, 0x000000, 0xFFFFFF, + 0x007DC9, 0x007DC9, 0x000000, 0xFFFFFF, + 0x007DCC, 0x007DCC, 0x000000, 0xFFFFFF, + 0x007DCE, 0x007DCE, 0x000000, 0xFFFFFF, + 0x007DDB, 0x007DDB, 0x000000, 0xFFFFFF, + 0x007DDF, 0x007DDF, 0x000000, 0xFFFFFF, + 0x007DE7, 0x007DE7, 0x000000, 0xFFFFFF, + 0x007DEA, 0x007DEA, 0x000000, 0xFFFFFF, + 0x007DEE, 0x007DEE, 0x000000, 0xFFFFFF, + 0x007DF0, 0x007DF0, 0x000000, 0xFFFFFF, + 0x007DF3, 0x007DF3, 0x000000, 0xFFFFFF, + 0x007DF7, 0x007DF7, 0x000000, 0xFFFFFF, + 0x007DFA, 0x007DFA, 0x000000, 0xFFFFFF, + 0x007E03, 0x007E03, 0x000000, 0xFFFFFF, + 0x007E0C, 0x007E0F, 0x000000, 0xFFFFFF, + 0x007E12, 0x007E17, 0x000000, 0xFFFFFF, + 0x007E1C, 0x007E1C, 0x000000, 0xFFFFFF, + 0x007E20, 0x007E22, 0x000000, 0xFFFFFF, + 0x007E24, 0x007E25, 0x000000, 0xFFFFFF, + 0x007E29, 0x007E2A, 0x000000, 0xFFFFFF, + 0x007E30, 0x007E30, 0x000000, 0xFFFFFF, + 0x007E38, 0x007E38, 0x000000, 0xFFFFFF, + 0x007E3A, 0x007E3A, 0x000000, 0xFFFFFF, + 0x007E3C, 0x007E3C, 0x000000, 0xFFFFFF, + 0x007E3F, 0x007E40, 0x000000, 0xFFFFFF, + 0x007E42, 0x007E42, 0x000000, 0xFFFFFF, + 0x007E44, 0x007E44, 0x000000, 0xFFFFFF, + 0x007E49, 0x007E49, 0x000000, 0xFFFFFF, + 0x007E4C, 0x007E4C, 0x000000, 0xFFFFFF, + 0x007E50, 0x007E51, 0x000000, 0xFFFFFF, + 0x007E53, 0x007E53, 0x000000, 0xFFFFFF, + 0x007E56, 0x007E58, 0x000000, 0xFFFFFF, + 0x007E5C, 0x007E5C, 0x000000, 0xFFFFFF, + 0x007E5F, 0x007E60, 0x000000, 0xFFFFFF, + 0x007E63, 0x007E63, 0x000000, 0xFFFFFF, + 0x007E68, 0x007E68, 0x000000, 0xFFFFFF, + 0x007E72, 0x007E72, 0x000000, 0xFFFFFF, + 0x007E74, 0x007E78, 0x000000, 0xFFFFFF, + 0x007E7A, 0x007E7B, 0x000000, 0xFFFFFF, + 0x007E80, 0x007E81, 0x000000, 0xFFFFFF, + 0x007E86, 0x007E87, 0x000000, 0xFFFFFF, + 0x007E8B, 0x007E8B, 0x000000, 0xFFFFFF, + 0x007E91, 0x007E91, 0x000000, 0xFFFFFF, + 0x007E95, 0x007E95, 0x000000, 0xFFFFFF, + 0x007E97, 0x007E97, 0x000000, 0xFFFFFF, + 0x007E99, 0x007E9A, 0x000000, 0xFFFFFF, + 0x007F39, 0x007F39, 0x000000, 0xFFFFFF, + 0x007F3F, 0x007F3F, 0x000000, 0xFFFFFF, + 0x007F43, 0x007F43, 0x000000, 0xFFFFFF, + 0x007F4A, 0x007F4B, 0x000000, 0xFFFFFF, + 0x007F4D, 0x007F4D, 0x000000, 0xFFFFFF, + 0x007F4F, 0x007F4F, 0x000000, 0xFFFFFF, + 0x007F5B, 0x007F5E, 0x000000, 0xFFFFFF, + 0x007F60, 0x007F60, 0x000000, 0xFFFFFF, + 0x007F63, 0x007F63, 0x000000, 0xFFFFFF, + 0x007F65, 0x007F65, 0x000000, 0xFFFFFF, + 0x007F67, 0x007F67, 0x000000, 0xFFFFFF, + 0x007F6B, 0x007F6D, 0x000000, 0xFFFFFF, + 0x007F73, 0x007F73, 0x000000, 0xFFFFFF, + 0x007F76, 0x007F76, 0x000000, 0xFFFFFF, + 0x007F7A, 0x007F7D, 0x000000, 0xFFFFFF, + 0x007F7F, 0x007F7F, 0x000000, 0xFFFFFF, + 0x007F83, 0x007F83, 0x000000, 0xFFFFFF, + 0x007F87, 0x007F87, 0x000000, 0xFFFFFF, + 0x007F89, 0x007F89, 0x000000, 0xFFFFFF, + 0x007F8D, 0x007F8D, 0x000000, 0xFFFFFF, + 0x007F91, 0x007F92, 0x000000, 0xFFFFFF, + 0x007F95, 0x007F96, 0x000000, 0xFFFFFF, + 0x007F9B, 0x007F9C, 0x000000, 0xFFFFFF, + 0x007FA0, 0x007FA0, 0x000000, 0xFFFFFF, + 0x007FA2, 0x007FA2, 0x000000, 0xFFFFFF, + 0x007FA6, 0x007FA6, 0x000000, 0xFFFFFF, + 0x007FAC, 0x007FAD, 0x000000, 0xFFFFFF, + 0x007FB1, 0x007FB1, 0x000000, 0xFFFFFF, + 0x007FB3, 0x007FB3, 0x000000, 0xFFFFFF, + 0x007FB5, 0x007FB5, 0x000000, 0xFFFFFF, + 0x007FB7, 0x007FB7, 0x000000, 0xFFFFFF, + 0x007FBA, 0x007FBB, 0x000000, 0xFFFFFF, + 0x007FBE, 0x007FBE, 0x000000, 0xFFFFFF, + 0x007FC0, 0x007FC0, 0x000000, 0xFFFFFF, + 0x007FC2, 0x007FC3, 0x000000, 0xFFFFFF, + 0x007FC7, 0x007FC7, 0x000000, 0xFFFFFF, + 0x007FC9, 0x007FC9, 0x000000, 0xFFFFFF, + 0x007FCB, 0x007FCB, 0x000000, 0xFFFFFF, + 0x007FCD, 0x007FCD, 0x000000, 0xFFFFFF, + 0x007FCF, 0x007FD1, 0x000000, 0xFFFFFF, + 0x007FD7, 0x007FD7, 0x000000, 0xFFFFFF, + 0x007FDB, 0x007FDC, 0x000000, 0xFFFFFF, + 0x007FDE, 0x007FDE, 0x000000, 0xFFFFFF, + 0x007FE2, 0x007FE3, 0x000000, 0xFFFFFF, + 0x007FE8, 0x007FE8, 0x000000, 0xFFFFFF, + 0x007FEA, 0x007FED, 0x000000, 0xFFFFFF, + 0x007FEF, 0x007FEF, 0x000000, 0xFFFFFF, + 0x007FF2, 0x007FF2, 0x000000, 0xFFFFFF, + 0x007FF4, 0x007FF5, 0x000000, 0xFFFFFF, + 0x007FF7, 0x007FF8, 0x000000, 0xFFFFFF, + 0x007FFD, 0x007FFF, 0x000000, 0xFFFFFF, + 0x008007, 0x008007, 0x000000, 0xFFFFFF, + 0x00800E, 0x00800F, 0x000000, 0xFFFFFF, + 0x00801B, 0x00801B, 0x000000, 0xFFFFFF, + 0x00801E, 0x00801F, 0x000000, 0xFFFFFF, + 0x008030, 0x008030, 0x000000, 0xFFFFFF, + 0x008034, 0x008034, 0x000000, 0xFFFFFF, + 0x008039, 0x008039, 0x000000, 0xFFFFFF, + 0x00803E, 0x00803E, 0x000000, 0xFFFFFF, + 0x008047, 0x008048, 0x000000, 0xFFFFFF, + 0x00804F, 0x008051, 0x000000, 0xFFFFFF, + 0x00805C, 0x00805D, 0x000000, 0xFFFFFF, + 0x008064, 0x008064, 0x000000, 0xFFFFFF, + 0x008067, 0x008067, 0x000000, 0xFFFFFF, + 0x00806C, 0x00806C, 0x000000, 0xFFFFFF, + 0x008078, 0x008078, 0x000000, 0xFFFFFF, + 0x008082, 0x008082, 0x000000, 0xFFFFFF, + 0x00808A, 0x00808A, 0x000000, 0xFFFFFF, + 0x008092, 0x008092, 0x000000, 0xFFFFFF, + 0x008095, 0x008095, 0x000000, 0xFFFFFF, + 0x008099, 0x008099, 0x000000, 0xFFFFFF, + 0x0080A3, 0x0080A3, 0x000000, 0xFFFFFF, + 0x0080B5, 0x0080B5, 0x000000, 0xFFFFFF, + 0x0080B8, 0x0080B8, 0x000000, 0xFFFFFF, + 0x0080C5, 0x0080C5, 0x000000, 0xFFFFFF, + 0x0080C8, 0x0080C9, 0x000000, 0xFFFFFF, + 0x0080CF, 0x0080D1, 0x000000, 0xFFFFFF, + 0x0080D4, 0x0080D5, 0x000000, 0xFFFFFF, + 0x0080D8, 0x0080D8, 0x000000, 0xFFFFFF, + 0x0080E0, 0x0080E0, 0x000000, 0xFFFFFF, + 0x0080E3, 0x0080E3, 0x000000, 0xFFFFFF, + 0x0080E6, 0x0080E6, 0x000000, 0xFFFFFF, + 0x0080F5, 0x0080F5, 0x000000, 0xFFFFFF, + 0x0080F9, 0x0080F9, 0x000000, 0xFFFFFF, + 0x0080FB, 0x0080FB, 0x000000, 0xFFFFFF, + 0x0080FE, 0x0080FE, 0x000000, 0xFFFFFF, + 0x008100, 0x008101, 0x000000, 0xFFFFFF, + 0x008115, 0x008115, 0x000000, 0xFFFFFF, + 0x008119, 0x008119, 0x000000, 0xFFFFFF, + 0x00811D, 0x00811D, 0x000000, 0xFFFFFF, + 0x00811F, 0x00811F, 0x000000, 0xFFFFFF, + 0x008121, 0x008122, 0x000000, 0xFFFFFF, + 0x008124, 0x008125, 0x000000, 0xFFFFFF, + 0x008127, 0x008127, 0x000000, 0xFFFFFF, + 0x00812D, 0x00812D, 0x000000, 0xFFFFFF, + 0x008130, 0x008130, 0x000000, 0xFFFFFF, + 0x00813A, 0x00813A, 0x000000, 0xFFFFFF, + 0x00813D, 0x00813D, 0x000000, 0xFFFFFF, + 0x008143, 0x008144, 0x000000, 0xFFFFFF, + 0x008147, 0x008147, 0x000000, 0xFFFFFF, + 0x00814D, 0x00814D, 0x000000, 0xFFFFFF, + 0x00814F, 0x00814F, 0x000000, 0xFFFFFF, + 0x008152, 0x008152, 0x000000, 0xFFFFFF, + 0x00815B, 0x00815C, 0x000000, 0xFFFFFF, + 0x00815E, 0x00815E, 0x000000, 0xFFFFFF, + 0x008162, 0x008162, 0x000000, 0xFFFFFF, + 0x008164, 0x008164, 0x000000, 0xFFFFFF, + 0x00816F, 0x00816F, 0x000000, 0xFFFFFF, + 0x008172, 0x008172, 0x000000, 0xFFFFFF, + 0x008176, 0x008177, 0x000000, 0xFFFFFF, + 0x008187, 0x008187, 0x000000, 0xFFFFFF, + 0x008189, 0x008189, 0x000000, 0xFFFFFF, + 0x00818B, 0x00818D, 0x000000, 0xFFFFFF, + 0x008195, 0x008195, 0x000000, 0xFFFFFF, + 0x008197, 0x008197, 0x000000, 0xFFFFFF, + 0x008199, 0x008199, 0x000000, 0xFFFFFF, + 0x00819E, 0x00819F, 0x000000, 0xFFFFFF, + 0x0081A2, 0x0081A2, 0x000000, 0xFFFFFF, + 0x0081A7, 0x0081A7, 0x000000, 0xFFFFFF, + 0x0081AB, 0x0081AC, 0x000000, 0xFFFFFF, + 0x0081AE, 0x0081AE, 0x000000, 0xFFFFFF, + 0x0081B0, 0x0081B2, 0x000000, 0xFFFFFF, + 0x0081B4, 0x0081B5, 0x000000, 0xFFFFFF, + 0x0081B7, 0x0081B7, 0x000000, 0xFFFFFF, + 0x0081B9, 0x0081B9, 0x000000, 0xFFFFFF, + 0x0081BC, 0x0081BC, 0x000000, 0xFFFFFF, + 0x0081C4, 0x0081C5, 0x000000, 0xFFFFFF, + 0x0081C7, 0x0081C7, 0x000000, 0xFFFFFF, + 0x0081D0, 0x0081D2, 0x000000, 0xFFFFFF, + 0x0081D7, 0x0081D7, 0x000000, 0xFFFFFF, + 0x0081DB, 0x0081DB, 0x000000, 0xFFFFFF, + 0x0081DD, 0x0081DE, 0x000000, 0xFFFFFF, + 0x0081E1, 0x0081E2, 0x000000, 0xFFFFFF, + 0x0081E6, 0x0081E6, 0x000000, 0xFFFFFF, + 0x0081E9, 0x0081E9, 0x000000, 0xFFFFFF, + 0x0081EE, 0x0081EE, 0x000000, 0xFFFFFF, + 0x0081F2, 0x0081F2, 0x000000, 0xFFFFFF, + 0x0081F7, 0x0081F9, 0x000000, 0xFFFFFF, + 0x0081FF, 0x0081FF, 0x000000, 0xFFFFFF, + 0x008211, 0x008211, 0x000000, 0xFFFFFF, + 0x008215, 0x008215, 0x000000, 0xFFFFFF, + 0x00821D, 0x00821D, 0x000000, 0xFFFFFF, + 0x008220, 0x008220, 0x000000, 0xFFFFFF, + 0x008225, 0x008225, 0x000000, 0xFFFFFF, + 0x008232, 0x008232, 0x000000, 0xFFFFFF, + 0x00823A, 0x00823A, 0x000000, 0xFFFFFF, + 0x00823C, 0x00823D, 0x000000, 0xFFFFFF, + 0x00823F, 0x008240, 0x000000, 0xFFFFFF, + 0x008242, 0x008242, 0x000000, 0xFFFFFF, + 0x008245, 0x008245, 0x000000, 0xFFFFFF, + 0x00824E, 0x00824E, 0x000000, 0xFFFFFF, + 0x008250, 0x008253, 0x000000, 0xFFFFFF, + 0x008255, 0x008257, 0x000000, 0xFFFFFF, + 0x00825B, 0x00825C, 0x000000, 0xFFFFFF, + 0x00825E, 0x00825E, 0x000000, 0xFFFFFF, + 0x008261, 0x008261, 0x000000, 0xFFFFFF, + 0x008269, 0x008269, 0x000000, 0xFFFFFF, + 0x00826C, 0x00826D, 0x000000, 0xFFFFFF, + 0x008275, 0x008275, 0x000000, 0xFFFFFF, + 0x00827C, 0x00827C, 0x000000, 0xFFFFFF, + 0x008280, 0x008280, 0x000000, 0xFFFFFF, + 0x008283, 0x008283, 0x000000, 0xFFFFFF, + 0x008285, 0x008285, 0x000000, 0xFFFFFF, + 0x008290, 0x008290, 0x000000, 0xFFFFFF, + 0x008293, 0x008294, 0x000000, 0xFFFFFF, + 0x00829A, 0x00829B, 0x000000, 0xFFFFFF, + 0x00829E, 0x00829E, 0x000000, 0xFFFFFF, + 0x0082A0, 0x0082A0, 0x000000, 0xFFFFFF, + 0x0082A2, 0x0082A3, 0x000000, 0xFFFFFF, + 0x0082A7, 0x0082A7, 0x000000, 0xFFFFFF, + 0x0082B5, 0x0082B6, 0x000000, 0xFFFFFF, + 0x0082BA, 0x0082BA, 0x000000, 0xFFFFFF, + 0x0082BC, 0x0082BC, 0x000000, 0xFFFFFF, + 0x0082C0, 0x0082C0, 0x000000, 0xFFFFFF, + 0x0082C2, 0x0082C3, 0x000000, 0xFFFFFF, + 0x0082D6, 0x0082D6, 0x000000, 0xFFFFFF, + 0x0082D9, 0x0082D9, 0x000000, 0xFFFFFF, + 0x0082E8, 0x0082E8, 0x000000, 0xFFFFFF, + 0x0082EA, 0x0082EA, 0x000000, 0xFFFFFF, + 0x0082EC, 0x0082ED, 0x000000, 0xFFFFFF, + 0x0082F0, 0x0082F0, 0x000000, 0xFFFFFF, + 0x0082F2, 0x0082F3, 0x000000, 0xFFFFFF, + 0x0082F5, 0x0082F6, 0x000000, 0xFFFFFF, + 0x0082FE, 0x0082FE, 0x000000, 0xFFFFFF, + 0x008300, 0x008300, 0x000000, 0xFFFFFF, + 0x008316, 0x008316, 0x000000, 0xFFFFFF, + 0x008319, 0x008319, 0x000000, 0xFFFFFF, + 0x00831E, 0x00831E, 0x000000, 0xFFFFFF, + 0x008320, 0x008320, 0x000000, 0xFFFFFF, + 0x008322, 0x008322, 0x000000, 0xFFFFFF, + 0x008324, 0x008326, 0x000000, 0xFFFFFF, + 0x008329, 0x00832A, 0x000000, 0xFFFFFF, + 0x008337, 0x008337, 0x000000, 0xFFFFFF, + 0x00833B, 0x00833B, 0x000000, 0xFFFFFF, + 0x00833F, 0x00833F, 0x000000, 0xFFFFFF, + 0x008341, 0x008342, 0x000000, 0xFFFFFF, + 0x008344, 0x008344, 0x000000, 0xFFFFFF, + 0x008348, 0x008348, 0x000000, 0xFFFFFF, + 0x00834B, 0x00834E, 0x000000, 0xFFFFFF, + 0x008353, 0x008353, 0x000000, 0xFFFFFF, + 0x008356, 0x008356, 0x000000, 0xFFFFFF, + 0x008374, 0x008376, 0x000000, 0xFFFFFF, + 0x00837A, 0x00837A, 0x000000, 0xFFFFFF, + 0x00837E, 0x00837F, 0x000000, 0xFFFFFF, + 0x008381, 0x008381, 0x000000, 0xFFFFFF, + 0x008383, 0x008383, 0x000000, 0xFFFFFF, + 0x008387, 0x008388, 0x000000, 0xFFFFFF, + 0x00838B, 0x00838D, 0x000000, 0xFFFFFF, + 0x00838F, 0x008390, 0x000000, 0xFFFFFF, + 0x008394, 0x008395, 0x000000, 0xFFFFFF, + 0x008397, 0x008397, 0x000000, 0xFFFFFF, + 0x008399, 0x00839A, 0x000000, 0xFFFFFF, + 0x00839D, 0x00839D, 0x000000, 0xFFFFFF, + 0x0083A3, 0x0083A6, 0x000000, 0xFFFFFF, + 0x0083AE, 0x0083AF, 0x000000, 0xFFFFFF, + 0x0083BF, 0x0083BF, 0x000000, 0xFFFFFF, + 0x0083C2, 0x0083C4, 0x000000, 0xFFFFFF, + 0x0083C6, 0x0083C6, 0x000000, 0xFFFFFF, + 0x0083C8, 0x0083C9, 0x000000, 0xFFFFFF, + 0x0083CB, 0x0083CB, 0x000000, 0xFFFFFF, + 0x0083CE, 0x0083CE, 0x000000, 0xFFFFFF, + 0x0083D1, 0x0083D1, 0x000000, 0xFFFFFF, + 0x0083D5, 0x0083D5, 0x000000, 0xFFFFFF, + 0x0083D7, 0x0083D7, 0x000000, 0xFFFFFF, + 0x0083D9, 0x0083D9, 0x000000, 0xFFFFFF, + 0x0083DB, 0x0083DB, 0x000000, 0xFFFFFF, + 0x0083DE, 0x0083DE, 0x000000, 0xFFFFFF, + 0x0083E2, 0x0083E4, 0x000000, 0xFFFFFF, + 0x0083E7, 0x0083E8, 0x000000, 0xFFFFFF, + 0x0083EC, 0x0083EC, 0x000000, 0xFFFFFF, + 0x0083EE, 0x0083EE, 0x000000, 0xFFFFFF, + 0x0083F3, 0x0083F3, 0x000000, 0xFFFFFF, + 0x0083F5, 0x0083F6, 0x000000, 0xFFFFFF, + 0x0083FA, 0x0083FC, 0x000000, 0xFFFFFF, + 0x0083FE, 0x0083FF, 0x000000, 0xFFFFFF, + 0x008409, 0x008409, 0x000000, 0xFFFFFF, + 0x008410, 0x008410, 0x000000, 0xFFFFFF, + 0x008412, 0x008413, 0x000000, 0xFFFFFF, + 0x00841B, 0x00841B, 0x000000, 0xFFFFFF, + 0x008423, 0x008423, 0x000000, 0xFFFFFF, + 0x008429, 0x008429, 0x000000, 0xFFFFFF, + 0x00842B, 0x00842B, 0x000000, 0xFFFFFF, + 0x00842D, 0x00842D, 0x000000, 0xFFFFFF, + 0x00842F, 0x008430, 0x000000, 0xFFFFFF, + 0x008432, 0x008434, 0x000000, 0xFFFFFF, + 0x008436, 0x008437, 0x000000, 0xFFFFFF, + 0x008439, 0x00843B, 0x000000, 0xFFFFFF, + 0x00843F, 0x008440, 0x000000, 0xFFFFFF, + 0x008442, 0x008445, 0x000000, 0xFFFFFF, + 0x008447, 0x008447, 0x000000, 0xFFFFFF, + 0x00844B, 0x00844E, 0x000000, 0xFFFFFF, + 0x008450, 0x008450, 0x000000, 0xFFFFFF, + 0x008454, 0x008454, 0x000000, 0xFFFFFF, + 0x008456, 0x008456, 0x000000, 0xFFFFFF, + 0x00845D, 0x008460, 0x000000, 0xFFFFFF, + 0x008465, 0x008465, 0x000000, 0xFFFFFF, + 0x008467, 0x008468, 0x000000, 0xFFFFFF, + 0x00846E, 0x00846E, 0x000000, 0xFFFFFF, + 0x008470, 0x008470, 0x000000, 0xFFFFFF, + 0x008474, 0x008474, 0x000000, 0xFFFFFF, + 0x008479, 0x008479, 0x000000, 0xFFFFFF, + 0x00847D, 0x00847E, 0x000000, 0xFFFFFF, + 0x008486, 0x008486, 0x000000, 0xFFFFFF, + 0x00848D, 0x00848D, 0x000000, 0xFFFFFF, + 0x00848F, 0x00848F, 0x000000, 0xFFFFFF, + 0x008491, 0x008491, 0x000000, 0xFFFFFF, + 0x008498, 0x008498, 0x000000, 0xFFFFFF, + 0x00849A, 0x00849B, 0x000000, 0xFFFFFF, + 0x00849D, 0x00849D, 0x000000, 0xFFFFFF, + 0x00849F, 0x0084A0, 0x000000, 0xFFFFFF, + 0x0084A2, 0x0084A2, 0x000000, 0xFFFFFF, + 0x0084A4, 0x0084A4, 0x000000, 0xFFFFFF, + 0x0084A7, 0x0084AC, 0x000000, 0xFFFFFF, + 0x0084AE, 0x0084AE, 0x000000, 0xFFFFFF, + 0x0084B0, 0x0084B1, 0x000000, 0xFFFFFF, + 0x0084B6, 0x0084B6, 0x000000, 0xFFFFFF, + 0x0084BB, 0x0084BB, 0x000000, 0xFFFFFF, + 0x0084C2, 0x0084C2, 0x000000, 0xFFFFFF, + 0x0084C5, 0x0084C5, 0x000000, 0xFFFFFF, + 0x0084C7, 0x0084C7, 0x000000, 0xFFFFFF, + 0x0084CC, 0x0084CC, 0x000000, 0xFFFFFF, + 0x0084CE, 0x0084CF, 0x000000, 0xFFFFFF, + 0x0084D2, 0x0084D2, 0x000000, 0xFFFFFF, + 0x0084D4, 0x0084D4, 0x000000, 0xFFFFFF, + 0x0084D7, 0x0084D7, 0x000000, 0xFFFFFF, + 0x0084DB, 0x0084DB, 0x000000, 0xFFFFFF, + 0x0084E7, 0x0084EB, 0x000000, 0xFFFFFF, + 0x0084F1, 0x0084F3, 0x000000, 0xFFFFFF, + 0x0084F6, 0x0084F7, 0x000000, 0xFFFFFF, + 0x0084F9, 0x0084FB, 0x000000, 0xFFFFFF, + 0x0084FE, 0x0084FE, 0x000000, 0xFFFFFF, + 0x008500, 0x008500, 0x000000, 0xFFFFFF, + 0x008502, 0x008502, 0x000000, 0xFFFFFF, + 0x008507, 0x00850B, 0x000000, 0xFFFFFF, + 0x00850D, 0x00850F, 0x000000, 0xFFFFFF, + 0x008512, 0x008512, 0x000000, 0xFFFFFF, + 0x008515, 0x008516, 0x000000, 0xFFFFFF, + 0x008518, 0x008519, 0x000000, 0xFFFFFF, + 0x00851C, 0x00851D, 0x000000, 0xFFFFFF, + 0x008520, 0x008520, 0x000000, 0xFFFFFF, + 0x008524, 0x008524, 0x000000, 0xFFFFFF, + 0x008527, 0x00852A, 0x000000, 0xFFFFFF, + 0x00852E, 0x008531, 0x000000, 0xFFFFFF, + 0x00853E, 0x00853E, 0x000000, 0xFFFFFF, + 0x008540, 0x008540, 0x000000, 0xFFFFFF, + 0x008544, 0x008545, 0x000000, 0xFFFFFF, + 0x008547, 0x008547, 0x000000, 0xFFFFFF, + 0x00854D, 0x00854D, 0x000000, 0xFFFFFF, + 0x008551, 0x008551, 0x000000, 0xFFFFFF, + 0x008554, 0x008554, 0x000000, 0xFFFFFF, + 0x008557, 0x008557, 0x000000, 0xFFFFFF, + 0x00855B, 0x00855B, 0x000000, 0xFFFFFF, + 0x00855D, 0x00855D, 0x000000, 0xFFFFFF, + 0x008560, 0x008561, 0x000000, 0xFFFFFF, + 0x008563, 0x008563, 0x000000, 0xFFFFFF, + 0x008565, 0x008567, 0x000000, 0xFFFFFF, + 0x00856B, 0x00856C, 0x000000, 0xFFFFFF, + 0x00856E, 0x00856E, 0x000000, 0xFFFFFF, + 0x008571, 0x008571, 0x000000, 0xFFFFFF, + 0x008575, 0x008576, 0x000000, 0xFFFFFF, + 0x008578, 0x008578, 0x000000, 0xFFFFFF, + 0x00857C, 0x00857C, 0x000000, 0xFFFFFF, + 0x008580, 0x008583, 0x000000, 0xFFFFFF, + 0x008586, 0x008586, 0x000000, 0xFFFFFF, + 0x008589, 0x008589, 0x000000, 0xFFFFFF, + 0x00858B, 0x00858B, 0x000000, 0xFFFFFF, + 0x00858D, 0x00858E, 0x000000, 0xFFFFFF, + 0x008590, 0x008590, 0x000000, 0xFFFFFF, + 0x008595, 0x008596, 0x000000, 0xFFFFFF, + 0x008598, 0x008598, 0x000000, 0xFFFFFF, + 0x00859A, 0x00859A, 0x000000, 0xFFFFFF, + 0x00859D, 0x00859E, 0x000000, 0xFFFFFF, + 0x0085A0, 0x0085A3, 0x000000, 0xFFFFFF, + 0x0085A7, 0x0085A7, 0x000000, 0xFFFFFF, + 0x0085B1, 0x0085B1, 0x000000, 0xFFFFFF, + 0x0085B3, 0x0085B6, 0x000000, 0xFFFFFF, + 0x0085B8, 0x0085B8, 0x000000, 0xFFFFFF, + 0x0085BD, 0x0085C0, 0x000000, 0xFFFFFF, + 0x0085C2, 0x0085C8, 0x000000, 0xFFFFFF, + 0x0085CB, 0x0085CB, 0x000000, 0xFFFFFF, + 0x0085D1, 0x0085D2, 0x000000, 0xFFFFFF, + 0x0085D7, 0x0085D9, 0x000000, 0xFFFFFF, + 0x0085DE, 0x0085DF, 0x000000, 0xFFFFFF, + 0x0085E1, 0x0085E3, 0x000000, 0xFFFFFF, + 0x0085E6, 0x0085E6, 0x000000, 0xFFFFFF, + 0x0085E8, 0x0085E8, 0x000000, 0xFFFFFF, + 0x0085EB, 0x0085ED, 0x000000, 0xFFFFFF, + 0x0085EF, 0x0085F2, 0x000000, 0xFFFFFF, + 0x0085F8, 0x0085F8, 0x000000, 0xFFFFFF, + 0x0085FD, 0x0085FE, 0x000000, 0xFFFFFF, + 0x008600, 0x008601, 0x000000, 0xFFFFFF, + 0x008609, 0x008609, 0x000000, 0xFFFFFF, + 0x00860C, 0x00860C, 0x000000, 0xFFFFFF, + 0x008618, 0x008619, 0x000000, 0xFFFFFF, + 0x00861B, 0x00861C, 0x000000, 0xFFFFFF, + 0x00861F, 0x008621, 0x000000, 0xFFFFFF, + 0x008623, 0x008626, 0x000000, 0xFFFFFF, + 0x00862A, 0x00862A, 0x000000, 0xFFFFFF, + 0x00862C, 0x00862C, 0x000000, 0xFFFFFF, + 0x00862E, 0x00862E, 0x000000, 0xFFFFFF, + 0x008631, 0x008636, 0x000000, 0xFFFFFF, + 0x008639, 0x008639, 0x000000, 0xFFFFFF, + 0x00863B, 0x00863B, 0x000000, 0xFFFFFF, + 0x00863E, 0x00863E, 0x000000, 0xFFFFFF, + 0x008640, 0x008640, 0x000000, 0xFFFFFF, + 0x008643, 0x008643, 0x000000, 0xFFFFFF, + 0x008646, 0x008648, 0x000000, 0xFFFFFF, + 0x00864B, 0x00864C, 0x000000, 0xFFFFFF, + 0x008652, 0x008653, 0x000000, 0xFFFFFF, + 0x008659, 0x008659, 0x000000, 0xFFFFFF, + 0x008661, 0x008661, 0x000000, 0xFFFFFF, + 0x008663, 0x008665, 0x000000, 0xFFFFFF, + 0x008668, 0x00866A, 0x000000, 0xFFFFFF, + 0x00866D, 0x00866D, 0x000000, 0xFFFFFF, + 0x008670, 0x008670, 0x000000, 0xFFFFFF, + 0x008673, 0x008674, 0x000000, 0xFFFFFF, + 0x008677, 0x008677, 0x000000, 0xFFFFFF, + 0x008685, 0x008687, 0x000000, 0xFFFFFF, + 0x00868E, 0x00868E, 0x000000, 0xFFFFFF, + 0x008690, 0x008691, 0x000000, 0xFFFFFF, + 0x008694, 0x008694, 0x000000, 0xFFFFFF, + 0x008696, 0x00869A, 0x000000, 0xFFFFFF, + 0x00869E, 0x00869E, 0x000000, 0xFFFFFF, + 0x0086A1, 0x0086A2, 0x000000, 0xFFFFFF, + 0x0086A5, 0x0086A5, 0x000000, 0xFFFFFF, + 0x0086B3, 0x0086B3, 0x000000, 0xFFFFFF, + 0x0086B7, 0x0086B9, 0x000000, 0xFFFFFF, + 0x0086BB, 0x0086BF, 0x000000, 0xFFFFFF, + 0x0086C1, 0x0086C3, 0x000000, 0xFFFFFF, + 0x0086C5, 0x0086C5, 0x000000, 0xFFFFFF, + 0x0086C8, 0x0086C8, 0x000000, 0xFFFFFF, + 0x0086CC, 0x0086CC, 0x000000, 0xFFFFFF, + 0x0086D3, 0x0086D3, 0x000000, 0xFFFFFF, + 0x0086D6, 0x0086D7, 0x000000, 0xFFFFFF, + 0x0086DA, 0x0086DA, 0x000000, 0xFFFFFF, + 0x0086DC, 0x0086DD, 0x000000, 0xFFFFFF, + 0x0086E2, 0x0086E3, 0x000000, 0xFFFFFF, + 0x0086E6, 0x0086E6, 0x000000, 0xFFFFFF, + 0x0086E8, 0x0086E8, 0x000000, 0xFFFFFF, + 0x0086EA, 0x0086EC, 0x000000, 0xFFFFFF, + 0x0086F5, 0x0086F7, 0x000000, 0xFFFFFF, + 0x008701, 0x008701, 0x000000, 0xFFFFFF, + 0x008704, 0x008705, 0x000000, 0xFFFFFF, + 0x00870B, 0x00870C, 0x000000, 0xFFFFFF, + 0x00870E, 0x00870E, 0x000000, 0xFFFFFF, + 0x008711, 0x008711, 0x000000, 0xFFFFFF, + 0x008719, 0x008719, 0x000000, 0xFFFFFF, + 0x00871B, 0x00871B, 0x000000, 0xFFFFFF, + 0x008720, 0x008720, 0x000000, 0xFFFFFF, + 0x008724, 0x008724, 0x000000, 0xFFFFFF, + 0x008726, 0x008728, 0x000000, 0xFFFFFF, + 0x00872A, 0x00872A, 0x000000, 0xFFFFFF, + 0x00872C, 0x00872D, 0x000000, 0xFFFFFF, + 0x008730, 0x008730, 0x000000, 0xFFFFFF, + 0x008732, 0x008733, 0x000000, 0xFFFFFF, + 0x008735, 0x008735, 0x000000, 0xFFFFFF, + 0x008738, 0x008738, 0x000000, 0xFFFFFF, + 0x00873C, 0x00873C, 0x000000, 0xFFFFFF, + 0x008740, 0x008743, 0x000000, 0xFFFFFF, + 0x008746, 0x008746, 0x000000, 0xFFFFFF, + 0x00874D, 0x00874D, 0x000000, 0xFFFFFF, + 0x00874F, 0x008752, 0x000000, 0xFFFFFF, + 0x008754, 0x008754, 0x000000, 0xFFFFFF, + 0x008756, 0x008756, 0x000000, 0xFFFFFF, + 0x008758, 0x008758, 0x000000, 0xFFFFFF, + 0x00875A, 0x00875E, 0x000000, 0xFFFFFF, + 0x008761, 0x008762, 0x000000, 0xFFFFFF, + 0x008767, 0x008767, 0x000000, 0xFFFFFF, + 0x008769, 0x00876D, 0x000000, 0xFFFFFF, + 0x00876F, 0x00876F, 0x000000, 0xFFFFFF, + 0x008773, 0x008773, 0x000000, 0xFFFFFF, + 0x008775, 0x008775, 0x000000, 0xFFFFFF, + 0x008777, 0x008777, 0x000000, 0xFFFFFF, + 0x008779, 0x00877A, 0x000000, 0xFFFFFF, + 0x008781, 0x008781, 0x000000, 0xFFFFFF, + 0x008787, 0x008787, 0x000000, 0xFFFFFF, + 0x008789, 0x008789, 0x000000, 0xFFFFFF, + 0x00878F, 0x008792, 0x000000, 0xFFFFFF, + 0x008794, 0x008794, 0x000000, 0xFFFFFF, + 0x008796, 0x008796, 0x000000, 0xFFFFFF, + 0x008798, 0x008798, 0x000000, 0xFFFFFF, + 0x00879A, 0x00879D, 0x000000, 0xFFFFFF, + 0x0087A3, 0x0087A4, 0x000000, 0xFFFFFF, + 0x0087AA, 0x0087AA, 0x000000, 0xFFFFFF, + 0x0087AE, 0x0087AE, 0x000000, 0xFFFFFF, + 0x0087B0, 0x0087B0, 0x000000, 0xFFFFFF, + 0x0087B2, 0x0087B2, 0x000000, 0xFFFFFF, + 0x0087B4, 0x0087B4, 0x000000, 0xFFFFFF, + 0x0087B6, 0x0087B9, 0x000000, 0xFFFFFF, + 0x0087BC, 0x0087BC, 0x000000, 0xFFFFFF, + 0x0087BE, 0x0087BF, 0x000000, 0xFFFFFF, + 0x0087C2, 0x0087C3, 0x000000, 0xFFFFFF, + 0x0087C5, 0x0087C5, 0x000000, 0xFFFFFF, + 0x0087C9, 0x0087C9, 0x000000, 0xFFFFFF, + 0x0087CC, 0x0087CC, 0x000000, 0xFFFFFF, + 0x0087D4, 0x0087D4, 0x000000, 0xFFFFFF, + 0x0087D7, 0x0087D9, 0x000000, 0xFFFFFF, + 0x0087DC, 0x0087DF, 0x000000, 0xFFFFFF, + 0x0087E1, 0x0087E2, 0x000000, 0xFFFFFF, + 0x0087E4, 0x0087E4, 0x000000, 0xFFFFFF, + 0x0087E6, 0x0087E8, 0x000000, 0xFFFFFF, + 0x0087EB, 0x0087EB, 0x000000, 0xFFFFFF, + 0x0087ED, 0x0087ED, 0x000000, 0xFFFFFF, + 0x0087F3, 0x0087F4, 0x000000, 0xFFFFFF, + 0x0087F7, 0x0087F7, 0x000000, 0xFFFFFF, + 0x0087FC, 0x0087FC, 0x000000, 0xFFFFFF, + 0x0087FF, 0x008802, 0x000000, 0xFFFFFF, + 0x008808, 0x008809, 0x000000, 0xFFFFFF, + 0x00880B, 0x00880C, 0x000000, 0xFFFFFF, + 0x008817, 0x008817, 0x000000, 0xFFFFFF, + 0x008819, 0x008819, 0x000000, 0xFFFFFF, + 0x00881C, 0x00881D, 0x000000, 0xFFFFFF, + 0x008820, 0x008820, 0x000000, 0xFFFFFF, + 0x008824, 0x008826, 0x000000, 0xFFFFFF, + 0x008828, 0x00882C, 0x000000, 0xFFFFFF, + 0x00882E, 0x008830, 0x000000, 0xFFFFFF, + 0x008833, 0x008833, 0x000000, 0xFFFFFF, + 0x008835, 0x008835, 0x000000, 0xFFFFFF, + 0x008838, 0x008838, 0x000000, 0xFFFFFF, + 0x00883D, 0x00883F, 0x000000, 0xFFFFFF, + 0x008841, 0x008841, 0x000000, 0xFFFFFF, + 0x008843, 0x008843, 0x000000, 0xFFFFFF, + 0x008848, 0x008848, 0x000000, 0xFFFFFF, + 0x00884B, 0x00884B, 0x000000, 0xFFFFFF, + 0x00884E, 0x00884E, 0x000000, 0xFFFFFF, + 0x008855, 0x008856, 0x000000, 0xFFFFFF, + 0x008867, 0x008867, 0x000000, 0xFFFFFF, + 0x00886A, 0x00886A, 0x000000, 0xFFFFFF, + 0x00886D, 0x00886D, 0x000000, 0xFFFFFF, + 0x00886F, 0x00886F, 0x000000, 0xFFFFFF, + 0x008871, 0x008871, 0x000000, 0xFFFFFF, + 0x008874, 0x008876, 0x000000, 0xFFFFFF, + 0x00887C, 0x00887C, 0x000000, 0xFFFFFF, + 0x008880, 0x008880, 0x000000, 0xFFFFFF, + 0x008883, 0x008883, 0x000000, 0xFFFFFF, + 0x008889, 0x008889, 0x000000, 0xFFFFFF, + 0x00888C, 0x00888C, 0x000000, 0xFFFFFF, + 0x00888E, 0x00888E, 0x000000, 0xFFFFFF, + 0x008891, 0x008891, 0x000000, 0xFFFFFF, + 0x008893, 0x008893, 0x000000, 0xFFFFFF, + 0x008895, 0x008895, 0x000000, 0xFFFFFF, + 0x008897, 0x00889B, 0x000000, 0xFFFFFF, + 0x00889F, 0x00889F, 0x000000, 0xFFFFFF, + 0x0088A1, 0x0088A1, 0x000000, 0xFFFFFF, + 0x0088A7, 0x0088A8, 0x000000, 0xFFFFFF, + 0x0088AC, 0x0088AC, 0x000000, 0xFFFFFF, + 0x0088B2, 0x0088B2, 0x000000, 0xFFFFFF, + 0x0088B6, 0x0088B6, 0x000000, 0xFFFFFF, + 0x0088B8, 0x0088BA, 0x000000, 0xFFFFFF, + 0x0088BD, 0x0088BE, 0x000000, 0xFFFFFF, + 0x0088C0, 0x0088C0, 0x000000, 0xFFFFFF, + 0x0088CB, 0x0088CD, 0x000000, 0xFFFFFF, + 0x0088D0, 0x0088D0, 0x000000, 0xFFFFFF, + 0x0088D6, 0x0088D7, 0x000000, 0xFFFFFF, + 0x0088DA, 0x0088DB, 0x000000, 0xFFFFFF, + 0x0088DE, 0x0088DE, 0x000000, 0xFFFFFF, + 0x0088E7, 0x0088E7, 0x000000, 0xFFFFFF, + 0x0088EB, 0x0088EC, 0x000000, 0xFFFFFF, + 0x0088EE, 0x0088EF, 0x000000, 0xFFFFFF, + 0x0088F2, 0x0088F2, 0x000000, 0xFFFFFF, + 0x0088F6, 0x0088F7, 0x000000, 0xFFFFFF, + 0x0088FA, 0x0088FB, 0x000000, 0xFFFFFF, + 0x008901, 0x008901, 0x000000, 0xFFFFFF, + 0x008905, 0x008906, 0x000000, 0xFFFFFF, + 0x008909, 0x008909, 0x000000, 0xFFFFFF, + 0x00890B, 0x00890C, 0x000000, 0xFFFFFF, + 0x008911, 0x008911, 0x000000, 0xFFFFFF, + 0x008914, 0x008918, 0x000000, 0xFFFFFF, + 0x00891E, 0x00891F, 0x000000, 0xFFFFFF, + 0x008922, 0x008923, 0x000000, 0xFFFFFF, + 0x008926, 0x008927, 0x000000, 0xFFFFFF, + 0x008929, 0x008929, 0x000000, 0xFFFFFF, + 0x00892C, 0x00892F, 0x000000, 0xFFFFFF, + 0x008931, 0x008931, 0x000000, 0xFFFFFF, + 0x008935, 0x008935, 0x000000, 0xFFFFFF, + 0x008937, 0x008937, 0x000000, 0xFFFFFF, + 0x00893C, 0x00893E, 0x000000, 0xFFFFFF, + 0x008942, 0x008942, 0x000000, 0xFFFFFF, + 0x008946, 0x008946, 0x000000, 0xFFFFFF, + 0x00894B, 0x00894C, 0x000000, 0xFFFFFF, + 0x00894F, 0x008953, 0x000000, 0xFFFFFF, + 0x008957, 0x00895C, 0x000000, 0xFFFFFF, + 0x008961, 0x008963, 0x000000, 0xFFFFFF, + 0x008969, 0x008969, 0x000000, 0xFFFFFF, + 0x00896B, 0x00896B, 0x000000, 0xFFFFFF, + 0x00896D, 0x00896E, 0x000000, 0xFFFFFF, + 0x008971, 0x008971, 0x000000, 0xFFFFFF, + 0x008973, 0x008974, 0x000000, 0xFFFFFF, + 0x008976, 0x008976, 0x000000, 0xFFFFFF, + 0x008979, 0x00897A, 0x000000, 0xFFFFFF, + 0x00897C, 0x00897C, 0x000000, 0xFFFFFF, + 0x008982, 0x008982, 0x000000, 0xFFFFFF, + 0x008985, 0x008985, 0x000000, 0xFFFFFF, + 0x008995, 0x008995, 0x000000, 0xFFFFFF, + 0x008997, 0x008997, 0x000000, 0xFFFFFF, + 0x00899B, 0x00899B, 0x000000, 0xFFFFFF, + 0x00899D, 0x00899F, 0x000000, 0xFFFFFF, + 0x0089A2, 0x0089A4, 0x000000, 0xFFFFFF, + 0x0089AD, 0x0089AE, 0x000000, 0xFFFFFF, + 0x0089B6, 0x0089B6, 0x000000, 0xFFFFFF, + 0x0089B9, 0x0089B9, 0x000000, 0xFFFFFF, + 0x0089BE, 0x0089BE, 0x000000, 0xFFFFFF, + 0x0089D3, 0x0089D3, 0x000000, 0xFFFFFF, + 0x0089D5, 0x0089D5, 0x000000, 0xFFFFFF, + 0x0089D9, 0x0089D9, 0x000000, 0xFFFFFF, + 0x0089DB, 0x0089DB, 0x000000, 0xFFFFFF, + 0x0089DF, 0x0089E2, 0x000000, 0xFFFFFF, + 0x0089E4, 0x0089E4, 0x000000, 0xFFFFFF, + 0x0089E8, 0x0089E9, 0x000000, 0xFFFFFF, + 0x0089EC, 0x0089ED, 0x000000, 0xFFFFFF, + 0x0089F0, 0x0089F2, 0x000000, 0xFFFFFF, + 0x0089F7, 0x0089F7, 0x000000, 0xFFFFFF, + 0x0089FA, 0x0089FC, 0x000000, 0xFFFFFF, + 0x0089FE, 0x0089FF, 0x000000, 0xFFFFFF, + 0x008A04, 0x008A04, 0x000000, 0xFFFFFF, + 0x008A0F, 0x008A0F, 0x000000, 0xFFFFFF, + 0x008A11, 0x008A12, 0x000000, 0xFFFFFF, + 0x008A1E, 0x008A1E, 0x000000, 0xFFFFFF, + 0x008A27, 0x008A27, 0x000000, 0xFFFFFF, + 0x008A2C, 0x008A2C, 0x000000, 0xFFFFFF, + 0x008A30, 0x008A30, 0x000000, 0xFFFFFF, + 0x008A39, 0x008A39, 0x000000, 0xFFFFFF, + 0x008A3F, 0x008A40, 0x000000, 0xFFFFFF, + 0x008A44, 0x008A45, 0x000000, 0xFFFFFF, + 0x008A4A, 0x008A4A, 0x000000, 0xFFFFFF, + 0x008A4C, 0x008A4D, 0x000000, 0xFFFFFF, + 0x008A4F, 0x008A4F, 0x000000, 0xFFFFFF, + 0x008A51, 0x008A51, 0x000000, 0xFFFFFF, + 0x008A56, 0x008A57, 0x000000, 0xFFFFFF, + 0x008A59, 0x008A59, 0x000000, 0xFFFFFF, + 0x008A68, 0x008A68, 0x000000, 0xFFFFFF, + 0x008A74, 0x008A74, 0x000000, 0xFFFFFF, + 0x008A77, 0x008A77, 0x000000, 0xFFFFFF, + 0x008A7A, 0x008A7A, 0x000000, 0xFFFFFF, + 0x008A81, 0x008A83, 0x000000, 0xFFFFFF, + 0x008A8B, 0x008A8B, 0x000000, 0xFFFFFF, + 0x008A8F, 0x008A8F, 0x000000, 0xFFFFFF, + 0x008A96, 0x008A96, 0x000000, 0xFFFFFF, + 0x008A99, 0x008A99, 0x000000, 0xFFFFFF, + 0x008AA7, 0x008AA7, 0x000000, 0xFFFFFF, + 0x008AAB, 0x008AAB, 0x000000, 0xFFFFFF, + 0x008AB8, 0x008AB8, 0x000000, 0xFFFFFF, + 0x008ABA, 0x008ABB, 0x000000, 0xFFFFFF, + 0x008ABD, 0x008ABE, 0x000000, 0xFFFFFF, + 0x008AC0, 0x008AC0, 0x000000, 0xFFFFFF, + 0x008AC3, 0x008AC3, 0x000000, 0xFFFFFF, + 0x008AC5, 0x008AC6, 0x000000, 0xFFFFFF, + 0x008AC8, 0x008AC8, 0x000000, 0xFFFFFF, + 0x008AD3, 0x008AD5, 0x000000, 0xFFFFFF, + 0x008AD8, 0x008AD9, 0x000000, 0xFFFFFF, + 0x008ADD, 0x008ADD, 0x000000, 0xFFFFFF, + 0x008ADF, 0x008ADF, 0x000000, 0xFFFFFF, + 0x008AE1, 0x008AE1, 0x000000, 0xFFFFFF, + 0x008AE8, 0x008AE8, 0x000000, 0xFFFFFF, + 0x008AEF, 0x008AF0, 0x000000, 0xFFFFFF, + 0x008AF2, 0x008AF2, 0x000000, 0xFFFFFF, + 0x008AF4, 0x008AF5, 0x000000, 0xFFFFFF, + 0x008AFB, 0x008AFB, 0x000000, 0xFFFFFF, + 0x008AFF, 0x008AFF, 0x000000, 0xFFFFFF, + 0x008B06, 0x008B06, 0x000000, 0xFFFFFF, + 0x008B08, 0x008B08, 0x000000, 0xFFFFFF, + 0x008B0B, 0x008B0B, 0x000000, 0xFFFFFF, + 0x008B0D, 0x008B0D, 0x000000, 0xFFFFFF, + 0x008B0F, 0x008B0F, 0x000000, 0xFFFFFF, + 0x008B11, 0x008B13, 0x000000, 0xFFFFFF, + 0x008B15, 0x008B15, 0x000000, 0xFFFFFF, + 0x008B18, 0x008B18, 0x000000, 0xFFFFFF, + 0x008B1C, 0x008B1C, 0x000000, 0xFFFFFF, + 0x008B1E, 0x008B1E, 0x000000, 0xFFFFFF, + 0x008B22, 0x008B25, 0x000000, 0xFFFFFF, + 0x008B27, 0x008B27, 0x000000, 0xFFFFFF, + 0x008B2A, 0x008B2A, 0x000000, 0xFFFFFF, + 0x008B2E, 0x008B31, 0x000000, 0xFFFFFF, + 0x008B35, 0x008B37, 0x000000, 0xFFFFFF, + 0x008B3A, 0x008B3B, 0x000000, 0xFFFFFF, + 0x008B3D, 0x008B3D, 0x000000, 0xFFFFFF, + 0x008B40, 0x008B40, 0x000000, 0xFFFFFF, + 0x008B42, 0x008B42, 0x000000, 0xFFFFFF, + 0x008B45, 0x008B45, 0x000000, 0xFFFFFF, + 0x008B47, 0x008B48, 0x000000, 0xFFFFFF, + 0x008B4A, 0x008B4B, 0x000000, 0xFFFFFF, + 0x008B50, 0x008B53, 0x000000, 0xFFFFFF, + 0x008B55, 0x008B55, 0x000000, 0xFFFFFF, + 0x008B57, 0x008B57, 0x000000, 0xFFFFFF, + 0x008B5D, 0x008B5D, 0x000000, 0xFFFFFF, + 0x008B60, 0x008B60, 0x000000, 0xFFFFFF, + 0x008B63, 0x008B63, 0x000000, 0xFFFFFF, + 0x008B65, 0x008B65, 0x000000, 0xFFFFFF, + 0x008B67, 0x008B68, 0x000000, 0xFFFFFF, + 0x008B6A, 0x008B6A, 0x000000, 0xFFFFFF, + 0x008B78, 0x008B7B, 0x000000, 0xFFFFFF, + 0x008B7F, 0x008B7F, 0x000000, 0xFFFFFF, + 0x008B82, 0x008B82, 0x000000, 0xFFFFFF, + 0x008B84, 0x008B86, 0x000000, 0xFFFFFF, + 0x008B88, 0x008B88, 0x000000, 0xFFFFFF, + 0x008B8B, 0x008B8B, 0x000000, 0xFFFFFF, + 0x008B94, 0x008B94, 0x000000, 0xFFFFFF, + 0x008B98, 0x008B99, 0x000000, 0xFFFFFF, + 0x008B9F, 0x008B9F, 0x000000, 0xFFFFFF, + 0x008C39, 0x008C39, 0x000000, 0xFFFFFF, + 0x008C3B, 0x008C3E, 0x000000, 0xFFFFFF, + 0x008C42, 0x008C43, 0x000000, 0xFFFFFF, + 0x008C45, 0x008C45, 0x000000, 0xFFFFFF, + 0x008C4A, 0x008C4B, 0x000000, 0xFFFFFF, + 0x008C4D, 0x008C4D, 0x000000, 0xFFFFFF, + 0x008C4F, 0x008C4F, 0x000000, 0xFFFFFF, + 0x008C57, 0x008C57, 0x000000, 0xFFFFFF, + 0x008C5C, 0x008C5D, 0x000000, 0xFFFFFF, + 0x008C5F, 0x008C5F, 0x000000, 0xFFFFFF, + 0x008C64, 0x008C66, 0x000000, 0xFFFFFF, + 0x008C68, 0x008C69, 0x000000, 0xFFFFFF, + 0x008C6D, 0x008C6D, 0x000000, 0xFFFFFF, + 0x008C6F, 0x008C72, 0x000000, 0xFFFFFF, + 0x008C75, 0x008C77, 0x000000, 0xFFFFFF, + 0x008C7B, 0x008C7B, 0x000000, 0xFFFFFF, + 0x008C7D, 0x008C7D, 0x000000, 0xFFFFFF, + 0x008C80, 0x008C81, 0x000000, 0xFFFFFF, + 0x008C84, 0x008C84, 0x000000, 0xFFFFFF, + 0x008C86, 0x008C86, 0x000000, 0xFFFFFF, + 0x008C8F, 0x008C92, 0x000000, 0xFFFFFF, + 0x008C95, 0x008C95, 0x000000, 0xFFFFFF, + 0x008C97, 0x008C97, 0x000000, 0xFFFFFF, + 0x008C99, 0x008C9A, 0x000000, 0xFFFFFF, + 0x008C9C, 0x008C9C, 0x000000, 0xFFFFFF, + 0x008CA3, 0x008CA5, 0x000000, 0xFFFFFF, + 0x008CB5, 0x008CB5, 0x000000, 0xFFFFFF, + 0x008CB9, 0x008CB9, 0x000000, 0xFFFFFF, + 0x008CBE, 0x008CBE, 0x000000, 0xFFFFFF, + 0x008CCC, 0x008CCC, 0x000000, 0xFFFFFF, + 0x008CCF, 0x008CCF, 0x000000, 0xFFFFFF, + 0x008CD7, 0x008CD7, 0x000000, 0xFFFFFF, + 0x008CDD, 0x008CDD, 0x000000, 0xFFFFFF, + 0x008CDF, 0x008CDF, 0x000000, 0xFFFFFF, + 0x008CE5, 0x008CE5, 0x000000, 0xFFFFFF, + 0x008CE8, 0x008CE8, 0x000000, 0xFFFFFF, + 0x008CEE, 0x008CEE, 0x000000, 0xFFFFFF, + 0x008CF0, 0x008CF1, 0x000000, 0xFFFFFF, + 0x008CF3, 0x008CF3, 0x000000, 0xFFFFFF, + 0x008CF5, 0x008CF5, 0x000000, 0xFFFFFF, + 0x008CF9, 0x008CF9, 0x000000, 0xFFFFFF, + 0x008D00, 0x008D00, 0x000000, 0xFFFFFF, + 0x008D02, 0x008D02, 0x000000, 0xFFFFFF, + 0x008D06, 0x008D07, 0x000000, 0xFFFFFF, + 0x008D09, 0x008D09, 0x000000, 0xFFFFFF, + 0x008D14, 0x008D15, 0x000000, 0xFFFFFF, + 0x008D19, 0x008D19, 0x000000, 0xFFFFFF, + 0x008D68, 0x008D69, 0x000000, 0xFFFFFF, + 0x008D6C, 0x008D6C, 0x000000, 0xFFFFFF, + 0x008D6E, 0x008D6F, 0x000000, 0xFFFFFF, + 0x008D72, 0x008D72, 0x000000, 0xFFFFFF, + 0x008D78, 0x008D79, 0x000000, 0xFFFFFF, + 0x008D7B, 0x008D7B, 0x000000, 0xFFFFFF, + 0x008D7D, 0x008D7D, 0x000000, 0xFFFFFF, + 0x008D80, 0x008D80, 0x000000, 0xFFFFFF, + 0x008D89, 0x008D89, 0x000000, 0xFFFFFF, + 0x008D8C, 0x008D90, 0x000000, 0xFFFFFF, + 0x008D92, 0x008D93, 0x000000, 0xFFFFFF, + 0x008D96, 0x008D96, 0x000000, 0xFFFFFF, + 0x008D9B, 0x008D9C, 0x000000, 0xFFFFFF, + 0x008DA0, 0x008DA1, 0x000000, 0xFFFFFF, + 0x008DA5, 0x008DA5, 0x000000, 0xFFFFFF, + 0x008DA7, 0x008DA7, 0x000000, 0xFFFFFF, + 0x008DAA, 0x008DAF, 0x000000, 0xFFFFFF, + 0x008DB6, 0x008DB7, 0x000000, 0xFFFFFF, + 0x008DB9, 0x008DB9, 0x000000, 0xFFFFFF, + 0x008DC1, 0x008DC2, 0x000000, 0xFFFFFF, + 0x008DC5, 0x008DC5, 0x000000, 0xFFFFFF, + 0x008DC7, 0x008DC8, 0x000000, 0xFFFFFF, + 0x008DCD, 0x008DCD, 0x000000, 0xFFFFFF, + 0x008DD0, 0x008DD0, 0x000000, 0xFFFFFF, + 0x008DD3, 0x008DD3, 0x000000, 0xFFFFFF, + 0x008DD5, 0x008DD5, 0x000000, 0xFFFFFF, + 0x008DD8, 0x008DD9, 0x000000, 0xFFFFFF, + 0x008DDC, 0x008DDC, 0x000000, 0xFFFFFF, + 0x008DE0, 0x008DE0, 0x000000, 0xFFFFFF, + 0x008DE2, 0x008DE2, 0x000000, 0xFFFFFF, + 0x008DE6, 0x008DE7, 0x000000, 0xFFFFFF, + 0x008DE9, 0x008DE9, 0x000000, 0xFFFFFF, + 0x008DEE, 0x008DEE, 0x000000, 0xFFFFFF, + 0x008DF0, 0x008DF2, 0x000000, 0xFFFFFF, + 0x008DF4, 0x008DF4, 0x000000, 0xFFFFFF, + 0x008DFE, 0x008E00, 0x000000, 0xFFFFFF, + 0x008E02, 0x008E04, 0x000000, 0xFFFFFF, + 0x008E06, 0x008E07, 0x000000, 0xFFFFFF, + 0x008E0D, 0x008E0D, 0x000000, 0xFFFFFF, + 0x008E11, 0x008E13, 0x000000, 0xFFFFFF, + 0x008E15, 0x008E1C, 0x000000, 0xFFFFFF, + 0x008E20, 0x008E20, 0x000000, 0xFFFFFF, + 0x008E24, 0x008E27, 0x000000, 0xFFFFFF, + 0x008E33, 0x008E33, 0x000000, 0xFFFFFF, + 0x008E36, 0x008E36, 0x000000, 0xFFFFFF, + 0x008E38, 0x008E38, 0x000000, 0xFFFFFF, + 0x008E3C, 0x008E3C, 0x000000, 0xFFFFFF, + 0x008E3E, 0x008E3F, 0x000000, 0xFFFFFF, + 0x008E45, 0x008E45, 0x000000, 0xFFFFFF, + 0x008E4D, 0x008E4E, 0x000000, 0xFFFFFF, + 0x008E50, 0x008E50, 0x000000, 0xFFFFFF, + 0x008E53, 0x008E54, 0x000000, 0xFFFFFF, + 0x008E56, 0x008E57, 0x000000, 0xFFFFFF, + 0x008E5A, 0x008E5E, 0x000000, 0xFFFFFF, + 0x008E61, 0x008E62, 0x000000, 0xFFFFFF, + 0x008E65, 0x008E65, 0x000000, 0xFFFFFF, + 0x008E6A, 0x008E6A, 0x000000, 0xFFFFFF, + 0x008E73, 0x008E73, 0x000000, 0xFFFFFF, + 0x008E78, 0x008E78, 0x000000, 0xFFFFFF, + 0x008E7B, 0x008E7B, 0x000000, 0xFFFFFF, + 0x008E82, 0x008E82, 0x000000, 0xFFFFFF, + 0x008E84, 0x008E84, 0x000000, 0xFFFFFF, + 0x008E86, 0x008E86, 0x000000, 0xFFFFFF, + 0x008E88, 0x008E88, 0x000000, 0xFFFFFF, + 0x008E8C, 0x008E8C, 0x000000, 0xFFFFFF, + 0x008E8E, 0x008E8E, 0x000000, 0xFFFFFF, + 0x008E96, 0x008E98, 0x000000, 0xFFFFFF, + 0x008E9D, 0x008E9D, 0x000000, 0xFFFFFF, + 0x008E9F, 0x008EA0, 0x000000, 0xFFFFFF, + 0x008EA3, 0x008EA4, 0x000000, 0xFFFFFF, + 0x008EA8, 0x008EA9, 0x000000, 0xFFFFFF, + 0x008EBD, 0x008EBD, 0x000000, 0xFFFFFF, + 0x008EC2, 0x008EC2, 0x000000, 0xFFFFFF, + 0x008EC9, 0x008EC9, 0x000000, 0xFFFFFF, + 0x008ECF, 0x008ECF, 0x000000, 0xFFFFFF, + 0x008ED1, 0x008ED1, 0x000000, 0xFFFFFF, + 0x008ED3, 0x008ED3, 0x000000, 0xFFFFFF, + 0x008ED7, 0x008ED8, 0x000000, 0xFFFFFF, + 0x008EDC, 0x008EDE, 0x000000, 0xFFFFFF, + 0x008EE0, 0x008EE1, 0x000000, 0xFFFFFF, + 0x008EE5, 0x008EE9, 0x000000, 0xFFFFFF, + 0x008EEC, 0x008EEC, 0x000000, 0xFFFFFF, + 0x008EEE, 0x008EEF, 0x000000, 0xFFFFFF, + 0x008EF1, 0x008EF1, 0x000000, 0xFFFFFF, + 0x008EF4, 0x008EF7, 0x000000, 0xFFFFFF, + 0x008EFF, 0x008F02, 0x000000, 0xFFFFFF, + 0x008F06, 0x008F06, 0x000000, 0xFFFFFF, + 0x008F08, 0x008F08, 0x000000, 0xFFFFFF, + 0x008F0B, 0x008F0B, 0x000000, 0xFFFFFF, + 0x008F0D, 0x008F0E, 0x000000, 0xFFFFFF, + 0x008F10, 0x008F11, 0x000000, 0xFFFFFF, + 0x008F16, 0x008F18, 0x000000, 0xFFFFFF, + 0x008F1A, 0x008F1A, 0x000000, 0xFFFFFF, + 0x008F20, 0x008F20, 0x000000, 0xFFFFFF, + 0x008F23, 0x008F24, 0x000000, 0xFFFFFF, + 0x008F2C, 0x008F2C, 0x000000, 0xFFFFFF, + 0x008F2E, 0x008F2E, 0x000000, 0xFFFFFF, + 0x008F32, 0x008F32, 0x000000, 0xFFFFFF, + 0x008F34, 0x008F37, 0x000000, 0xFFFFFF, + 0x008F39, 0x008F39, 0x000000, 0xFFFFFF, + 0x008F40, 0x008F40, 0x000000, 0xFFFFFF, + 0x008F43, 0x008F43, 0x000000, 0xFFFFFF, + 0x008F47, 0x008F48, 0x000000, 0xFFFFFF, + 0x008F4B, 0x008F4B, 0x000000, 0xFFFFFF, + 0x008F4F, 0x008F53, 0x000000, 0xFFFFFF, + 0x008F55, 0x008F5B, 0x000000, 0xFFFFFF, + 0x008F5D, 0x008F5E, 0x000000, 0xFFFFFF, + 0x008F60, 0x008F60, 0x000000, 0xFFFFFF, + 0x008F63, 0x008F63, 0x000000, 0xFFFFFF, + 0x008FB4, 0x008FB4, 0x000000, 0xFFFFFF, + 0x008FBF, 0x008FBF, 0x000000, 0xFFFFFF, + 0x008FC9, 0x008FC9, 0x000000, 0xFFFFFF, + 0x008FCB, 0x008FCB, 0x000000, 0xFFFFFF, + 0x008FCD, 0x008FCD, 0x000000, 0xFFFFFF, + 0x008FD2, 0x008FD2, 0x000000, 0xFFFFFF, + 0x008FD6, 0x008FD7, 0x000000, 0xFFFFFF, + 0x008FE0, 0x008FE1, 0x000000, 0xFFFFFF, + 0x008FE3, 0x008FE3, 0x000000, 0xFFFFFF, + 0x008FF5, 0x008FF6, 0x000000, 0xFFFFFF, + 0x008FFB, 0x008FFC, 0x000000, 0xFFFFFF, + 0x008FFE, 0x008FFF, 0x000000, 0xFFFFFF, + 0x00900C, 0x00900C, 0x000000, 0xFFFFFF, + 0x00901C, 0x00901C, 0x000000, 0xFFFFFF, + 0x009024, 0x009024, 0x000000, 0xFFFFFF, + 0x009034, 0x009034, 0x000000, 0xFFFFFF, + 0x00903D, 0x00903D, 0x000000, 0xFFFFFF, + 0x00903F, 0x00903F, 0x000000, 0xFFFFFF, + 0x009049, 0x009049, 0x000000, 0xFFFFFF, + 0x00905D, 0x00905D, 0x000000, 0xFFFFFF, + 0x009067, 0x009067, 0x000000, 0xFFFFFF, + 0x00906B, 0x00906B, 0x000000, 0xFFFFFF, + 0x00906F, 0x009070, 0x000000, 0xFFFFFF, + 0x009073, 0x009073, 0x000000, 0xFFFFFF, + 0x009076, 0x009076, 0x000000, 0xFFFFFF, + 0x009079, 0x009079, 0x000000, 0xFFFFFF, + 0x00907B, 0x00907B, 0x000000, 0xFFFFFF, + 0x00907E, 0x00907E, 0x000000, 0xFFFFFF, + 0x009085, 0x009086, 0x000000, 0xFFFFFF, + 0x00908D, 0x00908D, 0x000000, 0xFFFFFF, + 0x009094, 0x009094, 0x000000, 0xFFFFFF, + 0x009098, 0x009098, 0x000000, 0xFFFFFF, + 0x00909E, 0x0090A0, 0x000000, 0xFFFFFF, + 0x0090A5, 0x0090A5, 0x000000, 0xFFFFFF, + 0x0090A7, 0x0090A7, 0x000000, 0xFFFFFF, + 0x0090B2, 0x0090B2, 0x000000, 0xFFFFFF, + 0x0090BD, 0x0090BD, 0x000000, 0xFFFFFF, + 0x0090BF, 0x0090BF, 0x000000, 0xFFFFFF, + 0x0090C3, 0x0090C3, 0x000000, 0xFFFFFF, + 0x0090C8, 0x0090C8, 0x000000, 0xFFFFFF, + 0x0090CB, 0x0090CB, 0x000000, 0xFFFFFF, + 0x0090D4, 0x0090D6, 0x000000, 0xFFFFFF, + 0x0090D8, 0x0090DA, 0x000000, 0xFFFFFF, + 0x0090E0, 0x0090E0, 0x000000, 0xFFFFFF, + 0x0090E3, 0x0090E5, 0x000000, 0xFFFFFF, + 0x0090E9, 0x0090EA, 0x000000, 0xFFFFFF, + 0x0090EC, 0x0090EC, 0x000000, 0xFFFFFF, + 0x0090F0, 0x0090F3, 0x000000, 0xFFFFFF, + 0x0090F9, 0x0090FC, 0x000000, 0xFFFFFF, + 0x0090FF, 0x009101, 0x000000, 0xFFFFFF, + 0x009103, 0x009103, 0x000000, 0xFFFFFF, + 0x009105, 0x009105, 0x000000, 0xFFFFFF, + 0x009107, 0x009108, 0x000000, 0xFFFFFF, + 0x00910B, 0x00910B, 0x000000, 0xFFFFFF, + 0x00910D, 0x009111, 0x000000, 0xFFFFFF, + 0x009117, 0x009118, 0x000000, 0xFFFFFF, + 0x00911A, 0x00911D, 0x000000, 0xFFFFFF, + 0x00911F, 0x009121, 0x000000, 0xFFFFFF, + 0x009124, 0x009124, 0x000000, 0xFFFFFF, + 0x009126, 0x009126, 0x000000, 0xFFFFFF, + 0x009128, 0x00912C, 0x000000, 0xFFFFFF, + 0x00912E, 0x00912E, 0x000000, 0xFFFFFF, + 0x009133, 0x009133, 0x000000, 0xFFFFFF, + 0x009135, 0x009135, 0x000000, 0xFFFFFF, + 0x009138, 0x009138, 0x000000, 0xFFFFFF, + 0x00913B, 0x00913B, 0x000000, 0xFFFFFF, + 0x00913E, 0x009141, 0x000000, 0xFFFFFF, + 0x009144, 0x009145, 0x000000, 0xFFFFFF, + 0x009147, 0x009147, 0x000000, 0xFFFFFF, + 0x009153, 0x009153, 0x000000, 0xFFFFFF, + 0x009155, 0x009155, 0x000000, 0xFFFFFF, + 0x009158, 0x009158, 0x000000, 0xFFFFFF, + 0x00915F, 0x009160, 0x000000, 0xFFFFFF, + 0x009168, 0x009168, 0x000000, 0xFFFFFF, + 0x009173, 0x009173, 0x000000, 0xFFFFFF, + 0x00917A, 0x00917A, 0x000000, 0xFFFFFF, + 0x009180, 0x009182, 0x000000, 0xFFFFFF, + 0x009184, 0x009184, 0x000000, 0xFFFFFF, + 0x00918A, 0x00918A, 0x000000, 0xFFFFFF, + 0x00918F, 0x00918F, 0x000000, 0xFFFFFF, + 0x009193, 0x009193, 0x000000, 0xFFFFFF, + 0x009199, 0x009199, 0x000000, 0xFFFFFF, + 0x00919D, 0x00919D, 0x000000, 0xFFFFFF, + 0x00919F, 0x0091A1, 0x000000, 0xFFFFFF, + 0x0091A5, 0x0091A5, 0x000000, 0xFFFFFF, + 0x0091A7, 0x0091A8, 0x000000, 0xFFFFFF, + 0x0091B0, 0x0091B0, 0x000000, 0xFFFFFF, + 0x0091B2, 0x0091B3, 0x000000, 0xFFFFFF, + 0x0091B7, 0x0091B7, 0x000000, 0xFFFFFF, + 0x0091B9, 0x0091B9, 0x000000, 0xFFFFFF, + 0x0091BD, 0x0091BE, 0x000000, 0xFFFFFF, + 0x0091C2, 0x0091C2, 0x000000, 0xFFFFFF, + 0x0091DA, 0x0091DA, 0x000000, 0xFFFFFF, + 0x0091E2, 0x0091E2, 0x000000, 0xFFFFFF, + 0x0091E8, 0x0091E8, 0x000000, 0xFFFFFF, + 0x0091EA, 0x0091EB, 0x000000, 0xFFFFFF, + 0x0091ED, 0x0091EE, 0x000000, 0xFFFFFF, + 0x0091F1, 0x0091F1, 0x000000, 0xFFFFFF, + 0x0091F3, 0x0091F4, 0x000000, 0xFFFFFF, + 0x0091F8, 0x0091F8, 0x000000, 0xFFFFFF, + 0x0091FD, 0x0091FD, 0x000000, 0xFFFFFF, + 0x0091FF, 0x0091FF, 0x000000, 0xFFFFFF, + 0x009202, 0x009203, 0x000000, 0xFFFFFF, + 0x009205, 0x009207, 0x000000, 0xFFFFFF, + 0x00920A, 0x00920A, 0x000000, 0xFFFFFF, + 0x00920C, 0x00920C, 0x000000, 0xFFFFFF, + 0x00920F, 0x00920F, 0x000000, 0xFFFFFF, + 0x009212, 0x009212, 0x000000, 0xFFFFFF, + 0x009216, 0x009217, 0x000000, 0xFFFFFF, + 0x009219, 0x00921A, 0x000000, 0xFFFFFF, + 0x00921C, 0x00921C, 0x000000, 0xFFFFFF, + 0x009224, 0x009224, 0x000000, 0xFFFFFF, + 0x00922D, 0x00922D, 0x000000, 0xFFFFFF, + 0x009231, 0x009232, 0x000000, 0xFFFFFF, + 0x009236, 0x009236, 0x000000, 0xFFFFFF, + 0x00924A, 0x00924A, 0x000000, 0xFFFFFF, + 0x00924C, 0x00924C, 0x000000, 0xFFFFFF, + 0x00924E, 0x009250, 0x000000, 0xFFFFFF, + 0x009252, 0x009254, 0x000000, 0xFFFFFF, + 0x009256, 0x009256, 0x000000, 0xFFFFFF, + 0x009260, 0x009261, 0x000000, 0xFFFFFF, + 0x009263, 0x009263, 0x000000, 0xFFFFFF, + 0x009265, 0x009265, 0x000000, 0xFFFFFF, + 0x009267, 0x009267, 0x000000, 0xFFFFFF, + 0x00926F, 0x009270, 0x000000, 0xFFFFFF, + 0x009272, 0x009272, 0x000000, 0xFFFFFF, + 0x009276, 0x009276, 0x000000, 0xFFFFFF, + 0x009279, 0x009279, 0x000000, 0xFFFFFF, + 0x00927C, 0x00927E, 0x000000, 0xFFFFFF, + 0x009282, 0x009282, 0x000000, 0xFFFFFF, + 0x009286, 0x009288, 0x000000, 0xFFFFFF, + 0x00928A, 0x00928D, 0x000000, 0xFFFFFF, + 0x009294, 0x009295, 0x000000, 0xFFFFFF, + 0x009297, 0x009297, 0x000000, 0xFFFFFF, + 0x009299, 0x009299, 0x000000, 0xFFFFFF, + 0x00929B, 0x00929B, 0x000000, 0xFFFFFF, + 0x00929D, 0x00929D, 0x000000, 0xFFFFFF, + 0x0092A1, 0x0092A2, 0x000000, 0xFFFFFF, + 0x0092A4, 0x0092A4, 0x000000, 0xFFFFFF, + 0x0092A7, 0x0092A7, 0x000000, 0xFFFFFF, + 0x0092B4, 0x0092B6, 0x000000, 0xFFFFFF, + 0x0092C0, 0x0092C0, 0x000000, 0xFFFFFF, + 0x0092C2, 0x0092C2, 0x000000, 0xFFFFFF, + 0x0092C4, 0x0092C4, 0x000000, 0xFFFFFF, + 0x0092C6, 0x0092C6, 0x000000, 0xFFFFFF, + 0x0092C9, 0x0092CB, 0x000000, 0xFFFFFF, + 0x0092CD, 0x0092CE, 0x000000, 0xFFFFFF, + 0x0092D0, 0x0092D1, 0x000000, 0xFFFFFF, + 0x0092D3, 0x0092D3, 0x000000, 0xFFFFFF, + 0x0092D5, 0x0092D5, 0x000000, 0xFFFFFF, + 0x0092D7, 0x0092D9, 0x000000, 0xFFFFFF, + 0x0092DE, 0x0092DE, 0x000000, 0xFFFFFF, + 0x0092E0, 0x0092E1, 0x000000, 0xFFFFFF, + 0x0092E7, 0x0092E7, 0x000000, 0xFFFFFF, + 0x0092E9, 0x0092E9, 0x000000, 0xFFFFFF, + 0x0092F7, 0x0092F7, 0x000000, 0xFFFFFF, + 0x0092F9, 0x0092FA, 0x000000, 0xFFFFFF, + 0x0092FE, 0x009300, 0x000000, 0xFFFFFF, + 0x009302, 0x009302, 0x000000, 0xFFFFFF, + 0x009309, 0x009309, 0x000000, 0xFFFFFF, + 0x00930B, 0x00930F, 0x000000, 0xFFFFFF, + 0x009313, 0x009314, 0x000000, 0xFFFFFF, + 0x009316, 0x009316, 0x000000, 0xFFFFFF, + 0x00931D, 0x00931E, 0x000000, 0xFFFFFF, + 0x009321, 0x009321, 0x000000, 0xFFFFFF, + 0x009323, 0x009325, 0x000000, 0xFFFFFF, + 0x009327, 0x009327, 0x000000, 0xFFFFFF, + 0x009329, 0x00932A, 0x000000, 0xFFFFFF, + 0x00932D, 0x00932D, 0x000000, 0xFFFFFF, + 0x009334, 0x009335, 0x000000, 0xFFFFFF, + 0x009339, 0x009339, 0x000000, 0xFFFFFF, + 0x00933C, 0x00933C, 0x000000, 0xFFFFFF, + 0x009349, 0x009349, 0x000000, 0xFFFFFF, + 0x00934C, 0x00934C, 0x000000, 0xFFFFFF, + 0x00934E, 0x009352, 0x000000, 0xFFFFFF, + 0x009355, 0x009357, 0x000000, 0xFFFFFF, + 0x009359, 0x00935A, 0x000000, 0xFFFFFF, + 0x00935C, 0x00935C, 0x000000, 0xFFFFFF, + 0x00935E, 0x00935E, 0x000000, 0xFFFFFF, + 0x009360, 0x009361, 0x000000, 0xFFFFFF, + 0x009363, 0x009363, 0x000000, 0xFFFFFF, + 0x009367, 0x009367, 0x000000, 0xFFFFFF, + 0x00936D, 0x00936D, 0x000000, 0xFFFFFF, + 0x009371, 0x009371, 0x000000, 0xFFFFFF, + 0x009377, 0x009377, 0x000000, 0xFFFFFF, + 0x009379, 0x009379, 0x000000, 0xFFFFFF, + 0x00937B, 0x00937B, 0x000000, 0xFFFFFF, + 0x009380, 0x009380, 0x000000, 0xFFFFFF, + 0x009383, 0x009383, 0x000000, 0xFFFFFF, + 0x009388, 0x009389, 0x000000, 0xFFFFFF, + 0x00938D, 0x00938E, 0x000000, 0xFFFFFF, + 0x009391, 0x009392, 0x000000, 0xFFFFFF, + 0x009395, 0x009395, 0x000000, 0xFFFFFF, + 0x009399, 0x009399, 0x000000, 0xFFFFFF, + 0x00939B, 0x00939B, 0x000000, 0xFFFFFF, + 0x00939D, 0x00939F, 0x000000, 0xFFFFFF, + 0x0093A1, 0x0093A1, 0x000000, 0xFFFFFF, + 0x0093A4, 0x0093A5, 0x000000, 0xFFFFFF, + 0x0093A8, 0x0093A8, 0x000000, 0xFFFFFF, + 0x0093AF, 0x0093AF, 0x000000, 0xFFFFFF, + 0x0093B1, 0x0093B2, 0x000000, 0xFFFFFF, + 0x0093B4, 0x0093B4, 0x000000, 0xFFFFFF, + 0x0093B7, 0x0093B7, 0x000000, 0xFFFFFF, + 0x0093C0, 0x0093C0, 0x000000, 0xFFFFFF, + 0x0093C2, 0x0093C2, 0x000000, 0xFFFFFF, + 0x0093C4, 0x0093C4, 0x000000, 0xFFFFFF, + 0x0093CE, 0x0093D0, 0x000000, 0xFFFFFF, + 0x0093D2, 0x0093D2, 0x000000, 0xFFFFFF, + 0x0093D4, 0x0093D5, 0x000000, 0xFFFFFF, + 0x0093D9, 0x0093DA, 0x000000, 0xFFFFFF, + 0x0093E3, 0x0093E3, 0x000000, 0xFFFFFF, + 0x0093E6, 0x0093E7, 0x000000, 0xFFFFFF, + 0x0093EC, 0x0093EC, 0x000000, 0xFFFFFF, + 0x0093EE, 0x0093EE, 0x000000, 0xFFFFFF, + 0x0093F6, 0x0093F6, 0x000000, 0xFFFFFF, + 0x0093F8, 0x0093F8, 0x000000, 0xFFFFFF, + 0x0093FA, 0x0093FC, 0x000000, 0xFFFFFF, + 0x0093FE, 0x009400, 0x000000, 0xFFFFFF, + 0x009406, 0x009407, 0x000000, 0xFFFFFF, + 0x00940A, 0x00940A, 0x000000, 0xFFFFFF, + 0x00940C, 0x00940F, 0x000000, 0xFFFFFF, + 0x009411, 0x009411, 0x000000, 0xFFFFFF, + 0x009415, 0x009416, 0x000000, 0xFFFFFF, + 0x009429, 0x00942A, 0x000000, 0xFFFFFF, + 0x00942C, 0x00942C, 0x000000, 0xFFFFFF, + 0x009430, 0x009431, 0x000000, 0xFFFFFF, + 0x009437, 0x009437, 0x000000, 0xFFFFFF, + 0x009439, 0x009439, 0x000000, 0xFFFFFF, + 0x00943B, 0x00943D, 0x000000, 0xFFFFFF, + 0x009440, 0x009440, 0x000000, 0xFFFFFF, + 0x009445, 0x009449, 0x000000, 0xFFFFFF, + 0x00944B, 0x00944B, 0x000000, 0xFFFFFF, + 0x00944F, 0x009450, 0x000000, 0xFFFFFF, + 0x009455, 0x009455, 0x000000, 0xFFFFFF, + 0x009457, 0x009457, 0x000000, 0xFFFFFF, + 0x00945D, 0x00945E, 0x000000, 0xFFFFFF, + 0x009462, 0x009462, 0x000000, 0xFFFFFF, + 0x009468, 0x009469, 0x000000, 0xFFFFFF, + 0x00946E, 0x00946F, 0x000000, 0xFFFFFF, + 0x009471, 0x009471, 0x000000, 0xFFFFFF, + 0x009473, 0x009474, 0x000000, 0xFFFFFF, + 0x009476, 0x009476, 0x000000, 0xFFFFFF, + 0x009478, 0x009478, 0x000000, 0xFFFFFF, + 0x009480, 0x009483, 0x000000, 0xFFFFFF, + 0x00957A, 0x00957D, 0x000000, 0xFFFFFF, + 0x009588, 0x009588, 0x000000, 0xFFFFFF, + 0x00958D, 0x00958D, 0x000000, 0xFFFFFF, + 0x009590, 0x009590, 0x000000, 0xFFFFFF, + 0x00959B, 0x00959C, 0x000000, 0xFFFFFF, + 0x00959E, 0x00959F, 0x000000, 0xFFFFFF, + 0x0095AE, 0x0095AE, 0x000000, 0xFFFFFF, + 0x0095B0, 0x0095B0, 0x000000, 0xFFFFFF, + 0x0095B5, 0x0095B5, 0x000000, 0xFFFFFF, + 0x0095B7, 0x0095B7, 0x000000, 0xFFFFFF, + 0x0095BA, 0x0095BA, 0x000000, 0xFFFFFF, + 0x0095C0, 0x0095C0, 0x000000, 0xFFFFFF, + 0x0095C5, 0x0095C5, 0x000000, 0xFFFFFF, + 0x0095C9, 0x0095C9, 0x000000, 0xFFFFFF, + 0x0095CD, 0x0095CD, 0x000000, 0xFFFFFF, + 0x0095D1, 0x0095D3, 0x000000, 0xFFFFFF, + 0x0095DA, 0x0095DB, 0x000000, 0xFFFFFF, + 0x0095DF, 0x0095E0, 0x000000, 0xFFFFFF, + 0x0095E3, 0x0095E4, 0x000000, 0xFFFFFF, + 0x00961E, 0x00961E, 0x000000, 0xFFFFFF, + 0x009620, 0x009620, 0x000000, 0xFFFFFF, + 0x009623, 0x009624, 0x000000, 0xFFFFFF, + 0x00962D, 0x00962D, 0x000000, 0xFFFFFF, + 0x009630, 0x009630, 0x000000, 0xFFFFFF, + 0x009639, 0x00963A, 0x000000, 0xFFFFFF, + 0x009643, 0x009643, 0x000000, 0xFFFFFF, + 0x00964A, 0x00964A, 0x000000, 0xFFFFFF, + 0x00964E, 0x00964E, 0x000000, 0xFFFFFF, + 0x009651, 0x009651, 0x000000, 0xFFFFFF, + 0x009653, 0x009653, 0x000000, 0xFFFFFF, + 0x00965C, 0x00965C, 0x000000, 0xFFFFFF, + 0x00966B, 0x00966B, 0x000000, 0xFFFFFF, + 0x00966D, 0x00966D, 0x000000, 0xFFFFFF, + 0x00966F, 0x00966F, 0x000000, 0xFFFFFF, + 0x009671, 0x009671, 0x000000, 0xFFFFFF, + 0x00967C, 0x00967C, 0x000000, 0xFFFFFF, + 0x00967E, 0x00967E, 0x000000, 0xFFFFFF, + 0x009680, 0x009680, 0x000000, 0xFFFFFF, + 0x009683, 0x009683, 0x000000, 0xFFFFFF, + 0x009687, 0x009687, 0x000000, 0xFFFFFF, + 0x009691, 0x009693, 0x000000, 0xFFFFFF, + 0x00969E, 0x00969E, 0x000000, 0xFFFFFF, + 0x0096A1, 0x0096A2, 0x000000, 0xFFFFFF, + 0x0096A9, 0x0096A9, 0x000000, 0xFFFFFF, + 0x0096AC, 0x0096AC, 0x000000, 0xFFFFFF, + 0x0096AE, 0x0096AE, 0x000000, 0xFFFFFF, + 0x0096BF, 0x0096BF, 0x000000, 0xFFFFFF, + 0x0096C2, 0x0096C3, 0x000000, 0xFFFFFF, + 0x0096C8, 0x0096C8, 0x000000, 0xFFFFFF, + 0x0096CA, 0x0096CA, 0x000000, 0xFFFFFF, + 0x0096D3, 0x0096D4, 0x000000, 0xFFFFFF, + 0x0096D7, 0x0096D8, 0x000000, 0xFFFFFF, + 0x0096DA, 0x0096DA, 0x000000, 0xFFFFFF, + 0x0096DD, 0x0096DD, 0x000000, 0xFFFFFF, + 0x0096DF, 0x0096DF, 0x000000, 0xFFFFFF, + 0x0096E1, 0x0096E1, 0x000000, 0xFFFFFF, + 0x0096E5, 0x0096E5, 0x000000, 0xFFFFFF, + 0x0096F0, 0x0096F1, 0x000000, 0xFFFFFF, + 0x0096F5, 0x0096F5, 0x000000, 0xFFFFFF, + 0x0096F8, 0x0096F8, 0x000000, 0xFFFFFF, + 0x0096FA, 0x0096FA, 0x000000, 0xFFFFFF, + 0x0096FD, 0x0096FD, 0x000000, 0xFFFFFF, + 0x0096FF, 0x0096FF, 0x000000, 0xFFFFFF, + 0x009702, 0x009702, 0x000000, 0xFFFFFF, + 0x009705, 0x009705, 0x000000, 0xFFFFFF, + 0x00970B, 0x00970B, 0x000000, 0xFFFFFF, + 0x009710, 0x009710, 0x000000, 0xFFFFFF, + 0x009712, 0x009712, 0x000000, 0xFFFFFF, + 0x009718, 0x009719, 0x000000, 0xFFFFFF, + 0x00971D, 0x00971D, 0x000000, 0xFFFFFF, + 0x00971F, 0x009720, 0x000000, 0xFFFFFF, + 0x009722, 0x009723, 0x000000, 0xFFFFFF, + 0x009725, 0x009726, 0x000000, 0xFFFFFF, + 0x009728, 0x009729, 0x000000, 0xFFFFFF, + 0x00972B, 0x00972C, 0x000000, 0xFFFFFF, + 0x00972E, 0x00972F, 0x000000, 0xFFFFFF, + 0x009735, 0x009735, 0x000000, 0xFFFFFF, + 0x00973A, 0x00973A, 0x000000, 0xFFFFFF, + 0x00973F, 0x00973F, 0x000000, 0xFFFFFF, + 0x009743, 0x009743, 0x000000, 0xFFFFFF, + 0x009746, 0x009747, 0x000000, 0xFFFFFF, + 0x009749, 0x009749, 0x000000, 0xFFFFFF, + 0x00974B, 0x00974B, 0x000000, 0xFFFFFF, + 0x009758, 0x009758, 0x000000, 0xFFFFFF, + 0x00976A, 0x00976A, 0x000000, 0xFFFFFF, + 0x00976C, 0x00976C, 0x000000, 0xFFFFFF, + 0x00976E, 0x00976E, 0x000000, 0xFFFFFF, + 0x009770, 0x009770, 0x000000, 0xFFFFFF, + 0x009772, 0x009772, 0x000000, 0xFFFFFF, + 0x009777, 0x009778, 0x000000, 0xFFFFFF, + 0x00977A, 0x00977B, 0x000000, 0xFFFFFF, + 0x00977D, 0x009784, 0x000000, 0xFFFFFF, + 0x009788, 0x009788, 0x000000, 0xFFFFFF, + 0x00978A, 0x00978A, 0x000000, 0xFFFFFF, + 0x00978E, 0x00978E, 0x000000, 0xFFFFFF, + 0x009797, 0x009797, 0x000000, 0xFFFFFF, + 0x009799, 0x00979A, 0x000000, 0xFFFFFF, + 0x00979C, 0x00979E, 0x000000, 0xFFFFFF, + 0x0097A1, 0x0097A2, 0x000000, 0xFFFFFF, + 0x0097A4, 0x0097A5, 0x000000, 0xFFFFFF, + 0x0097A8, 0x0097A8, 0x000000, 0xFFFFFF, + 0x0097AA, 0x0097AA, 0x000000, 0xFFFFFF, + 0x0097AC, 0x0097AC, 0x000000, 0xFFFFFF, + 0x0097AE, 0x0097AE, 0x000000, 0xFFFFFF, + 0x0097B3, 0x0097B3, 0x000000, 0xFFFFFF, + 0x0097B6, 0x0097B7, 0x000000, 0xFFFFFF, + 0x0097B9, 0x0097B9, 0x000000, 0xFFFFFF, + 0x0097BB, 0x0097BB, 0x000000, 0xFFFFFF, + 0x0097BF, 0x0097BF, 0x000000, 0xFFFFFF, + 0x0097C4, 0x0097C5, 0x000000, 0xFFFFFF, + 0x0097C7, 0x0097C7, 0x000000, 0xFFFFFF, + 0x0097CD, 0x0097D0, 0x000000, 0xFFFFFF, + 0x0097D4, 0x0097D8, 0x000000, 0xFFFFFF, + 0x0097DD, 0x0097DD, 0x000000, 0xFFFFFF, + 0x0097DF, 0x0097DF, 0x000000, 0xFFFFFF, + 0x0097E1, 0x0097E1, 0x000000, 0xFFFFFF, + 0x0097E3, 0x0097E3, 0x000000, 0xFFFFFF, + 0x0097E5, 0x0097E5, 0x000000, 0xFFFFFF, + 0x0097F0, 0x0097F1, 0x000000, 0xFFFFFF, + 0x0097F8, 0x0097FA, 0x000000, 0xFFFFFF, + 0x0097FD, 0x0097FE, 0x000000, 0xFFFFFF, + 0x009800, 0x009800, 0x000000, 0xFFFFFF, + 0x009804, 0x009804, 0x000000, 0xFFFFFF, + 0x00980D, 0x00980D, 0x000000, 0xFFFFFF, + 0x009816, 0x009816, 0x000000, 0xFFFFFF, + 0x00981B, 0x00981B, 0x000000, 0xFFFFFF, + 0x00981D, 0x00981E, 0x000000, 0xFFFFFF, + 0x009820, 0x009820, 0x000000, 0xFFFFFF, + 0x009827, 0x009829, 0x000000, 0xFFFFFF, + 0x00982F, 0x00982F, 0x000000, 0xFFFFFF, + 0x009832, 0x009832, 0x000000, 0xFFFFFF, + 0x009835, 0x009835, 0x000000, 0xFFFFFF, + 0x009841, 0x009841, 0x000000, 0xFFFFFF, + 0x009843, 0x009845, 0x000000, 0xFFFFFF, + 0x009848, 0x00984A, 0x000000, 0xFFFFFF, + 0x009850, 0x009852, 0x000000, 0xFFFFFF, + 0x009857, 0x009857, 0x000000, 0xFFFFFF, + 0x00985C, 0x00985D, 0x000000, 0xFFFFFF, + 0x00985F, 0x009860, 0x000000, 0xFFFFFF, + 0x009863, 0x009864, 0x000000, 0xFFFFFF, + 0x009869, 0x00986A, 0x000000, 0xFFFFFF, + 0x009872, 0x009872, 0x000000, 0xFFFFFF, + 0x0098A9, 0x0098A9, 0x000000, 0xFFFFFF, + 0x0098AC, 0x0098AD, 0x000000, 0xFFFFFF, + 0x0098B2, 0x0098B2, 0x000000, 0xFFFFFF, + 0x0098B8, 0x0098B8, 0x000000, 0xFFFFFF, + 0x0098BB, 0x0098BB, 0x000000, 0xFFFFFF, + 0x0098BD, 0x0098C2, 0x000000, 0xFFFFFF, + 0x0098C9, 0x0098C9, 0x000000, 0xFFFFFF, + 0x0098CB, 0x0098CC, 0x000000, 0xFFFFFF, + 0x0098E3, 0x0098E3, 0x000000, 0xFFFFFF, + 0x0098E5, 0x0098E5, 0x000000, 0xFFFFFF, + 0x0098F6, 0x0098F6, 0x000000, 0xFFFFFF, + 0x0098F9, 0x0098FA, 0x000000, 0xFFFFFF, + 0x009900, 0x009900, 0x000000, 0xFFFFFF, + 0x009902, 0x009902, 0x000000, 0xFFFFFF, + 0x009907, 0x009907, 0x000000, 0xFFFFFF, + 0x009915, 0x009917, 0x000000, 0xFFFFFF, + 0x00991F, 0x00991F, 0x000000, 0xFFFFFF, + 0x009924, 0x009925, 0x000000, 0xFFFFFF, + 0x009927, 0x009927, 0x000000, 0xFFFFFF, + 0x009929, 0x00992B, 0x000000, 0xFFFFFF, + 0x00992D, 0x00992D, 0x000000, 0xFFFFFF, + 0x00992F, 0x009930, 0x000000, 0xFFFFFF, + 0x009932, 0x009932, 0x000000, 0xFFFFFF, + 0x00993A, 0x00993A, 0x000000, 0xFFFFFF, + 0x009941, 0x009941, 0x000000, 0xFFFFFF, + 0x009947, 0x009947, 0x000000, 0xFFFFFF, + 0x00994E, 0x00994E, 0x000000, 0xFFFFFF, + 0x009950, 0x009950, 0x000000, 0xFFFFFF, + 0x009953, 0x009953, 0x000000, 0xFFFFFF, + 0x009956, 0x009956, 0x000000, 0xFFFFFF, + 0x009958, 0x009959, 0x000000, 0xFFFFFF, + 0x00995B, 0x00995B, 0x000000, 0xFFFFFF, + 0x009961, 0x009961, 0x000000, 0xFFFFFF, + 0x00999C, 0x00999E, 0x000000, 0xFFFFFF, + 0x0099A1, 0x0099A1, 0x000000, 0xFFFFFF, + 0x0099A3, 0x0099A3, 0x000000, 0xFFFFFF, + 0x0099A6, 0x0099A7, 0x000000, 0xFFFFFF, + 0x0099AB, 0x0099AB, 0x000000, 0xFFFFFF, + 0x0099AF, 0x0099B0, 0x000000, 0xFFFFFF, + 0x0099B2, 0x0099B2, 0x000000, 0xFFFFFF, + 0x0099B5, 0x0099B5, 0x000000, 0xFFFFFF, + 0x0099B9, 0x0099BB, 0x000000, 0xFFFFFF, + 0x0099BD, 0x0099BD, 0x000000, 0xFFFFFF, + 0x0099C2, 0x0099C3, 0x000000, 0xFFFFFF, + 0x0099C7, 0x0099C7, 0x000000, 0xFFFFFF, + 0x0099C9, 0x0099C9, 0x000000, 0xFFFFFF, + 0x0099CB, 0x0099CF, 0x000000, 0xFFFFFF, + 0x0099D3, 0x0099D3, 0x000000, 0xFFFFFF, + 0x0099D6, 0x0099D7, 0x000000, 0xFFFFFF, + 0x0099DC, 0x0099DC, 0x000000, 0xFFFFFF, + 0x0099E3, 0x0099E5, 0x000000, 0xFFFFFF, + 0x0099E7, 0x0099E7, 0x000000, 0xFFFFFF, + 0x0099E9, 0x0099EA, 0x000000, 0xFFFFFF, + 0x0099EC, 0x0099EC, 0x000000, 0xFFFFFF, + 0x0099F0, 0x0099F0, 0x000000, 0xFFFFFF, + 0x0099F4, 0x0099F4, 0x000000, 0xFFFFFF, + 0x0099F6, 0x0099FE, 0x000000, 0xFFFFFF, + 0x009A02, 0x009A02, 0x000000, 0xFFFFFF, + 0x009A04, 0x009A04, 0x000000, 0xFFFFFF, + 0x009A06, 0x009A07, 0x000000, 0xFFFFFF, + 0x009A09, 0x009A0B, 0x000000, 0xFFFFFF, + 0x009A11, 0x009A11, 0x000000, 0xFFFFFF, + 0x009A14, 0x009A15, 0x000000, 0xFFFFFF, + 0x009A1A, 0x009A1E, 0x000000, 0xFFFFFF, + 0x009A20, 0x009A20, 0x000000, 0xFFFFFF, + 0x009A22, 0x009A22, 0x000000, 0xFFFFFF, + 0x009A24, 0x009A25, 0x000000, 0xFFFFFF, + 0x009A27, 0x009A27, 0x000000, 0xFFFFFF, + 0x009A29, 0x009A2A, 0x000000, 0xFFFFFF, + 0x009A2C, 0x009A2C, 0x000000, 0xFFFFFF, + 0x009A31, 0x009A32, 0x000000, 0xFFFFFF, + 0x009A34, 0x009A35, 0x000000, 0xFFFFFF, + 0x009A39, 0x009A3A, 0x000000, 0xFFFFFF, + 0x009A3D, 0x009A3D, 0x000000, 0xFFFFFF, + 0x009A3F, 0x009A3F, 0x000000, 0xFFFFFF, + 0x009A46, 0x009A46, 0x000000, 0xFFFFFF, + 0x009A48, 0x009A49, 0x000000, 0xFFFFFF, + 0x009A4C, 0x009A4C, 0x000000, 0xFFFFFF, + 0x009A4E, 0x009A4E, 0x000000, 0xFFFFFF, + 0x009A50, 0x009A50, 0x000000, 0xFFFFFF, + 0x009A52, 0x009A54, 0x000000, 0xFFFFFF, + 0x009A56, 0x009A56, 0x000000, 0xFFFFFF, + 0x009A59, 0x009A59, 0x000000, 0xFFFFFF, + 0x009A5E, 0x009A5E, 0x000000, 0xFFFFFF, + 0x009A60, 0x009A60, 0x000000, 0xFFFFFF, + 0x009A66, 0x009A69, 0x000000, 0xFFFFFF, + 0x009A6B, 0x009A6B, 0x000000, 0xFFFFFF, + 0x009AAB, 0x009AAB, 0x000000, 0xFFFFFF, + 0x009AAD, 0x009AAD, 0x000000, 0xFFFFFF, + 0x009AB3, 0x009AB4, 0x000000, 0xFFFFFF, + 0x009AB9, 0x009AB9, 0x000000, 0xFFFFFF, + 0x009ABB, 0x009ABB, 0x000000, 0xFFFFFF, + 0x009ABE, 0x009ABF, 0x000000, 0xFFFFFF, + 0x009AC6, 0x009AC7, 0x000000, 0xFFFFFF, + 0x009ACA, 0x009ACA, 0x000000, 0xFFFFFF, + 0x009ACD, 0x009ACD, 0x000000, 0xFFFFFF, + 0x009AD0, 0x009AD0, 0x000000, 0xFFFFFF, + 0x009ADC, 0x009ADC, 0x000000, 0xFFFFFF, + 0x009AE7, 0x009AE7, 0x000000, 0xFFFFFF, + 0x009AEC, 0x009AEC, 0x000000, 0xFFFFFF, + 0x009AF1, 0x009AF3, 0x000000, 0xFFFFFF, + 0x009AF6, 0x009AF7, 0x000000, 0xFFFFFF, + 0x009AFA, 0x009AFA, 0x000000, 0xFFFFFF, + 0x009AFC, 0x009AFE, 0x000000, 0xFFFFFF, + 0x009B01, 0x009B01, 0x000000, 0xFFFFFF, + 0x009B04, 0x009B05, 0x000000, 0xFFFFFF, + 0x009B0A, 0x009B0C, 0x000000, 0xFFFFFF, + 0x009B0E, 0x009B0E, 0x000000, 0xFFFFFF, + 0x009B10, 0x009B12, 0x000000, 0xFFFFFF, + 0x009B15, 0x009B19, 0x000000, 0xFFFFFF, + 0x009B1E, 0x009B1E, 0x000000, 0xFFFFFF, + 0x009B20, 0x009B20, 0x000000, 0xFFFFFF, + 0x009B24, 0x009B24, 0x000000, 0xFFFFFF, + 0x009B2B, 0x009B2B, 0x000000, 0xFFFFFF, + 0x009B33, 0x009B33, 0x000000, 0xFFFFFF, + 0x009B35, 0x009B35, 0x000000, 0xFFFFFF, + 0x009B37, 0x009B37, 0x000000, 0xFFFFFF, + 0x009B3A, 0x009B3A, 0x000000, 0xFFFFFF, + 0x009B3E, 0x009B3F, 0x000000, 0xFFFFFF, + 0x009B46, 0x009B46, 0x000000, 0xFFFFFF, + 0x009B4A, 0x009B4C, 0x000000, 0xFFFFFF, + 0x009B52, 0x009B52, 0x000000, 0xFFFFFF, + 0x009B55, 0x009B56, 0x000000, 0xFFFFFF, + 0x009B59, 0x009B59, 0x000000, 0xFFFFFF, + 0x009B5B, 0x009B5B, 0x000000, 0xFFFFFF, + 0x009B5F, 0x009B61, 0x000000, 0xFFFFFF, + 0x009B64, 0x009B64, 0x000000, 0xFFFFFF, + 0x009B66, 0x009B67, 0x000000, 0xFFFFFF, + 0x009B6C, 0x009B6C, 0x000000, 0xFFFFFF, + 0x009B70, 0x009B71, 0x000000, 0xFFFFFF, + 0x009B75, 0x009B76, 0x000000, 0xFFFFFF, + 0x009B7A, 0x009B7E, 0x000000, 0xFFFFFF, + 0x009B80, 0x009B80, 0x000000, 0xFFFFFF, + 0x009B82, 0x009B82, 0x000000, 0xFFFFFF, + 0x009B85, 0x009B88, 0x000000, 0xFFFFFF, + 0x009B93, 0x009B93, 0x000000, 0xFFFFFF, + 0x009B95, 0x009B95, 0x000000, 0xFFFFFF, + 0x009B9B, 0x009B9B, 0x000000, 0xFFFFFF, + 0x009BA0, 0x009BA2, 0x000000, 0xFFFFFF, + 0x009BA4, 0x009BA6, 0x000000, 0xFFFFFF, + 0x009BA8, 0x009BA8, 0x000000, 0xFFFFFF, + 0x009BAF, 0x009BAF, 0x000000, 0xFFFFFF, + 0x009BB5, 0x009BB6, 0x000000, 0xFFFFFF, + 0x009BB8, 0x009BB9, 0x000000, 0xFFFFFF, + 0x009BBD, 0x009BBD, 0x000000, 0xFFFFFF, + 0x009BBF, 0x009BBF, 0x000000, 0xFFFFFF, + 0x009BC3, 0x009BC4, 0x000000, 0xFFFFFF, + 0x009BC6, 0x009BC6, 0x000000, 0xFFFFFF, + 0x009BC8, 0x009BC8, 0x000000, 0xFFFFFF, + 0x009BD3, 0x009BD3, 0x000000, 0xFFFFFF, + 0x009BD5, 0x009BD5, 0x000000, 0xFFFFFF, + 0x009BD9, 0x009BDA, 0x000000, 0xFFFFFF, + 0x009BDC, 0x009BDC, 0x000000, 0xFFFFFF, + 0x009BDE, 0x009BDE, 0x000000, 0xFFFFFF, + 0x009BE0, 0x009BE0, 0x000000, 0xFFFFFF, + 0x009BE5, 0x009BE6, 0x000000, 0xFFFFFF, + 0x009BEC, 0x009BEC, 0x000000, 0xFFFFFF, + 0x009BF7, 0x009BF8, 0x000000, 0xFFFFFF, + 0x009C05, 0x009C07, 0x000000, 0xFFFFFF, + 0x009C0B, 0x009C0B, 0x000000, 0xFFFFFF, + 0x009C0E, 0x009C0E, 0x000000, 0xFFFFFF, + 0x009C14, 0x009C14, 0x000000, 0xFFFFFF, + 0x009C17, 0x009C17, 0x000000, 0xFFFFFF, + 0x009C1C, 0x009C1D, 0x000000, 0xFFFFFF, + 0x009C21, 0x009C21, 0x000000, 0xFFFFFF, + 0x009C24, 0x009C24, 0x000000, 0xFFFFFF, + 0x009C2B, 0x009C2C, 0x000000, 0xFFFFFF, + 0x009C34, 0x009C34, 0x000000, 0xFFFFFF, + 0x009C36, 0x009C36, 0x000000, 0xFFFFFF, + 0x009C3C, 0x009C3D, 0x000000, 0xFFFFFF, + 0x009C3F, 0x009C41, 0x000000, 0xFFFFFF, + 0x009C44, 0x009C44, 0x000000, 0xFFFFFF, + 0x009C46, 0x009C46, 0x000000, 0xFFFFFF, + 0x009C4A, 0x009C4E, 0x000000, 0xFFFFFF, + 0x009C50, 0x009C50, 0x000000, 0xFFFFFF, + 0x009C55, 0x009C55, 0x000000, 0xFFFFFF, + 0x009C59, 0x009C59, 0x000000, 0xFFFFFF, + 0x009C5E, 0x009C5E, 0x000000, 0xFFFFFF, + 0x009C60, 0x009C60, 0x000000, 0xFFFFFF, + 0x009C62, 0x009C63, 0x000000, 0xFFFFFF, + 0x009C66, 0x009C66, 0x000000, 0xFFFFFF, + 0x009C68, 0x009C68, 0x000000, 0xFFFFFF, + 0x009C6E, 0x009C6E, 0x000000, 0xFFFFFF, + 0x009C71, 0x009C71, 0x000000, 0xFFFFFF, + 0x009C73, 0x009C75, 0x000000, 0xFFFFFF, + 0x009C79, 0x009C79, 0x000000, 0xFFFFFF, + 0x009CE6, 0x009CE6, 0x000000, 0xFFFFFF, + 0x009CEA, 0x009CEA, 0x000000, 0xFFFFFF, + 0x009CED, 0x009CED, 0x000000, 0xFFFFFF, + 0x009CF1, 0x009CF2, 0x000000, 0xFFFFFF, + 0x009CF5, 0x009CF5, 0x000000, 0xFFFFFF, + 0x009CF7, 0x009CF7, 0x000000, 0xFFFFFF, + 0x009CF9, 0x009CFD, 0x000000, 0xFFFFFF, + 0x009CFF, 0x009D00, 0x000000, 0xFFFFFF, + 0x009D03, 0x009D05, 0x000000, 0xFFFFFF, + 0x009D10, 0x009D10, 0x000000, 0xFFFFFF, + 0x009D12, 0x009D12, 0x000000, 0xFFFFFF, + 0x009D14, 0x009D14, 0x000000, 0xFFFFFF, + 0x009D17, 0x009D19, 0x000000, 0xFFFFFF, + 0x009D1E, 0x009D1E, 0x000000, 0xFFFFFF, + 0x009D20, 0x009D20, 0x000000, 0xFFFFFF, + 0x009D22, 0x009D22, 0x000000, 0xFFFFFF, + 0x009D25, 0x009D25, 0x000000, 0xFFFFFF, + 0x009D29, 0x009D29, 0x000000, 0xFFFFFF, + 0x009D2D, 0x009D2E, 0x000000, 0xFFFFFF, + 0x009D31, 0x009D31, 0x000000, 0xFFFFFF, + 0x009D33, 0x009D33, 0x000000, 0xFFFFFF, + 0x009D36, 0x009D38, 0x000000, 0xFFFFFF, + 0x009D3D, 0x009D3E, 0x000000, 0xFFFFFF, + 0x009D40, 0x009D41, 0x000000, 0xFFFFFF, + 0x009D43, 0x009D43, 0x000000, 0xFFFFFF, + 0x009D45, 0x009D45, 0x000000, 0xFFFFFF, + 0x009D4A, 0x009D4C, 0x000000, 0xFFFFFF, + 0x009D4F, 0x009D4F, 0x000000, 0xFFFFFF, + 0x009D54, 0x009D54, 0x000000, 0xFFFFFF, + 0x009D56, 0x009D5B, 0x000000, 0xFFFFFF, + 0x009D5F, 0x009D5F, 0x000000, 0xFFFFFF, + 0x009D67, 0x009D69, 0x000000, 0xFFFFFF, + 0x009D6B, 0x009D6B, 0x000000, 0xFFFFFF, + 0x009D71, 0x009D71, 0x000000, 0xFFFFFF, + 0x009D73, 0x009D75, 0x000000, 0xFFFFFF, + 0x009D77, 0x009D79, 0x000000, 0xFFFFFF, + 0x009D7B, 0x009D7B, 0x000000, 0xFFFFFF, + 0x009D7D, 0x009D7D, 0x000000, 0xFFFFFF, + 0x009D7F, 0x009D82, 0x000000, 0xFFFFFF, + 0x009D84, 0x009D86, 0x000000, 0xFFFFFF, + 0x009D88, 0x009D88, 0x000000, 0xFFFFFF, + 0x009D8A, 0x009D8C, 0x000000, 0xFFFFFF, + 0x009D90, 0x009D90, 0x000000, 0xFFFFFF, + 0x009D92, 0x009D92, 0x000000, 0xFFFFFF, + 0x009D94, 0x009D94, 0x000000, 0xFFFFFF, + 0x009D96, 0x009D97, 0x000000, 0xFFFFFF, + 0x009D99, 0x009D99, 0x000000, 0xFFFFFF, + 0x009D9B, 0x009DA4, 0x000000, 0xFFFFFF, + 0x009DA6, 0x009DA8, 0x000000, 0xFFFFFF, + 0x009DAA, 0x009DAA, 0x000000, 0xFFFFFF, + 0x009DAC, 0x009DAD, 0x000000, 0xFFFFFF, + 0x009DB2, 0x009DB3, 0x000000, 0xFFFFFF, + 0x009DB5, 0x009DBA, 0x000000, 0xFFFFFF, + 0x009DBE, 0x009DBE, 0x000000, 0xFFFFFF, + 0x009DC1, 0x009DC1, 0x000000, 0xFFFFFF, + 0x009DC3, 0x009DC3, 0x000000, 0xFFFFFF, + 0x009DC5, 0x009DC5, 0x000000, 0xFFFFFF, + 0x009DC7, 0x009DC8, 0x000000, 0xFFFFFF, + 0x009DCA, 0x009DD2, 0x000000, 0xFFFFFF, + 0x009DD5, 0x009DD6, 0x000000, 0xFFFFFF, + 0x009DD8, 0x009DD8, 0x000000, 0xFFFFFF, + 0x009DDB, 0x009DDF, 0x000000, 0xFFFFFF, + 0x009DE1, 0x009DE4, 0x000000, 0xFFFFFF, + 0x009DE8, 0x009DE9, 0x000000, 0xFFFFFF, + 0x009DEB, 0x009DEE, 0x000000, 0xFFFFFF, + 0x009DF5, 0x009DF7, 0x000000, 0xFFFFFF, + 0x009DFB, 0x009DFB, 0x000000, 0xFFFFFF, + 0x009DFD, 0x009E07, 0x000000, 0xFFFFFF, + 0x009E09, 0x009E09, 0x000000, 0xFFFFFF, + 0x009E0B, 0x009E0B, 0x000000, 0xFFFFFF, + 0x009E0D, 0x009E0D, 0x000000, 0xFFFFFF, + 0x009E0F, 0x009E14, 0x000000, 0xFFFFFF, + 0x009E17, 0x009E17, 0x000000, 0xFFFFFF, + 0x009E19, 0x009E19, 0x000000, 0xFFFFFF, + 0x009E80, 0x009E80, 0x000000, 0xFFFFFF, + 0x009E83, 0x009E83, 0x000000, 0xFFFFFF, + 0x009E86, 0x009E86, 0x000000, 0xFFFFFF, + 0x009E89, 0x009E8A, 0x000000, 0xFFFFFF, + 0x009E8C, 0x009E8E, 0x000000, 0xFFFFFF, + 0x009E91, 0x009E91, 0x000000, 0xFFFFFF, + 0x009E94, 0x009E94, 0x000000, 0xFFFFFF, + 0x009E99, 0x009E9C, 0x000000, 0xFFFFFF, + 0x009EA0, 0x009EA1, 0x000000, 0xFFFFFF, + 0x009EA4, 0x009EA4, 0x000000, 0xFFFFFF, + 0x009EA7, 0x009EA7, 0x000000, 0xFFFFFF, + 0x009EAD, 0x009EAE, 0x000000, 0xFFFFFF, + 0x009EB0, 0x009EB0, 0x000000, 0xFFFFFF, + 0x009EB6, 0x009EB7, 0x000000, 0xFFFFFF, + 0x009EC0, 0x009EC0, 0x000000, 0xFFFFFF, + 0x009EC2, 0x009EC2, 0x000000, 0xFFFFFF, + 0x009EC8, 0x009EC8, 0x000000, 0xFFFFFF, + 0x009ED0, 0x009ED0, 0x000000, 0xFFFFFF, + 0x009ED3, 0x009ED3, 0x000000, 0xFFFFFF, + 0x009ED5, 0x009ED6, 0x000000, 0xFFFFFF, + 0x009EDA, 0x009EDA, 0x000000, 0xFFFFFF, + 0x009EE4, 0x009EE4, 0x000000, 0xFFFFFF, + 0x009EE6, 0x009EE6, 0x000000, 0xFFFFFF, + 0x009EEB, 0x009EEB, 0x000000, 0xFFFFFF, + 0x009EED, 0x009EEE, 0x000000, 0xFFFFFF, + 0x009EF0, 0x009EF0, 0x000000, 0xFFFFFF, + 0x009EF3, 0x009EF3, 0x000000, 0xFFFFFF, + 0x009EF5, 0x009EF6, 0x000000, 0xFFFFFF, + 0x009EFA, 0x009EFA, 0x000000, 0xFFFFFF, + 0x009F00, 0x009F01, 0x000000, 0xFFFFFF, + 0x009F06, 0x009F06, 0x000000, 0xFFFFFF, + 0x009F0A, 0x009F0A, 0x000000, 0xFFFFFF, + 0x009F0F, 0x009F0F, 0x000000, 0xFFFFFF, + 0x009F12, 0x009F12, 0x000000, 0xFFFFFF, + 0x009F16, 0x009F16, 0x000000, 0xFFFFFF, + 0x009F18, 0x009F18, 0x000000, 0xFFFFFF, + 0x009F1A, 0x009F1C, 0x000000, 0xFFFFFF, + 0x009F1E, 0x009F1E, 0x000000, 0xFFFFFF, + 0x009F23, 0x009F25, 0x000000, 0xFFFFFF, + 0x009F28, 0x009F2B, 0x000000, 0xFFFFFF, + 0x009F2D, 0x009F2E, 0x000000, 0xFFFFFF, + 0x009F30, 0x009F33, 0x000000, 0xFFFFFF, + 0x009F35, 0x009F36, 0x000000, 0xFFFFFF, + 0x009F38, 0x009F38, 0x000000, 0xFFFFFF, + 0x009F40, 0x009F43, 0x000000, 0xFFFFFF, + 0x009F46, 0x009F49, 0x000000, 0xFFFFFF, + 0x009F4C, 0x009F4D, 0x000000, 0xFFFFFF, + 0x009F55, 0x009F58, 0x000000, 0xFFFFFF, + 0x009F5B, 0x009F5B, 0x000000, 0xFFFFFF, + 0x009F5D, 0x009F5E, 0x000000, 0xFFFFFF, + 0x009F64, 0x009F65, 0x000000, 0xFFFFFF, + 0x009F6B, 0x009F6B, 0x000000, 0xFFFFFF, + 0x009F6E, 0x009F71, 0x000000, 0xFFFFFF, + 0x009F74, 0x009F75, 0x000000, 0xFFFFFF, + 0x009F78, 0x009F7B, 0x000000, 0xFFFFFF, + 0x009F7E, 0x009F7E, 0x000000, 0xFFFFFF, + 0x009F91, 0x009F92, 0x000000, 0xFFFFFF, + 0x009F98, 0x009F98, 0x000000, 0xFFFFFF, + 0x009FA4, 0x009FA4, 0x000000, 0xFFFFFF, + 0x00F6B1, 0x00F848, 0x000000, 0xFFFFFF, + 0x00FA0D, 0x00FA0D, 0x000000, 0xFFFFFF, + 0x00FE34, 0x00FE3E, 0x000000, 0xFFFFFF, + 0x00FE41, 0x00FE44, 0x000000, 0xFFFFFF, + 0x00FE49, 0x00FE4F, 0x000000, 0xFFFFFF, + 0x00FE68, 0x00FE68, 0x000000, 0xFFFFFF, +); + +?> diff --git a/lib/php/monica/commtext.inc.php b/lib/php/monica/commtext.inc.php new file mode 100644 index 0000000..8446a97 --- /dev/null +++ b/lib/php/monica/commtext.inc.php @@ -0,0 +1,39 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/gettext.inc.php"; + +// t_notset: Return a localed "(not set)" +function t_notset() +{ + return C_("(not set)"); +} + +// t_none: Return a localed "(none)" +function t_none() +{ + return C_("(none)"); +} + +// t_na: Return a localed "(N/A)" +function t_na() +{ + return C_("(N/A)"); +} + +// t_na: Return a localed "(blank)" +function t_blank() +{ + return C_("(blank)"); +} + +?> diff --git a/lib/php/monica/copyyear.inc.php b/lib/php/monica/copyyear.inc.php new file mode 100644 index 0000000..a24c26d --- /dev/null +++ b/lib/php/monica/copyyear.inc.php @@ -0,0 +1,27 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// copyyear: Return the copyright year +function copyyear($startyear) +{ + // Cache the result + static $cache; + // Return the cache + if (isset($cache)) { + return $cache; + } + $thisyear = date("Y"); + if ($thisyear == $startyear) { + $cache = $startyear; + } else { + $cache = $startyear . "-" . $thisyear; + } + return $cache; +} + + +?> diff --git a/lib/php/monica/country.inc.php b/lib/php/monica/country.inc.php new file mode 100644 index 0000000..684c22e --- /dev/null +++ b/lib/php/monica/country.inc.php @@ -0,0 +1,78 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/commtext.inc.php"; +require_once "monica/echoform.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/sql.inc.php"; + +// ctname: Obtain a country name +function ctname($id) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $id + if (is_null($id)) { + return t_notset(); + } + // Return the cache + if (array_key_exists($id, $cache)) { + return $cache[$id]; + } + + // Query + // Default language + if (getlang() == DEFAULT_LANG) { + $col = "name_" . getlang(LN_DATABASE) . " AS name"; + // Fall back to the default language + } else { + $thiscol = "name_" . getlang(LN_DATABASE); + $defcol = "name_" . ln(DEFAULT_LANG, LN_DATABASE); + $col = "COALESCE($thiscol, $defcol) AS name"; + } + $select = "SELECT $col FROM country" + . " WHERE id='" . sql_esctext($id) . "';\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$id] = t_na(); + return $cache[$id]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$id] = $row["name"]; + + return $cache[$id]; +} + +// country_options: Obtain a country options list +function country_options($value) +{ + // Default language + if (getlang() == DEFAULT_LANG) { + $content = "name_" . getlang(LN_DATABASE) . " AS content"; + // Fall back to the default language + } else { + $col = "name_" . getlang(LN_DATABASE); + $defcol = "name_" . ln(DEFAULT_LANG, LN_DATABASE); + $content = "COALESCE($col, $defcol) AS content"; + } + $select = "SELECT id AS value, $content FROM country" + . " WHERE " . sql_is_false("special") + . " ORDER BY content;\n"; + return opt_list($select, $value); +} + +?> diff --git a/lib/php/monica/cracklib.inc.php b/lib/php/monica/cracklib.inc.php new file mode 100644 index 0000000..3e1b712 --- /dev/null +++ b/lib/php/monica/cracklib.inc.php @@ -0,0 +1,54 @@ + +// Copyright: Copyright (C) 2007 Pristine Communications + +// Referenced subroutines +require_once "monica/runcmd.inc.php"; + +// Only do this when Cracklib extension is not loaded +if (!extension_loaded("crack")) { + +// The last message +$_CRACKLIB_LASTMMSG = null; + +// crack_check: Check password with Cracklib +function crack_check($passwd) +{ + // This is faster, but only available with Debian cracklib-runtime + if (file_exists("/usr/sbin/crack_testlib")) { + $cmd = array("/usr/sbin/crack_testlib"); + $out = xruncmd($cmd, "$passwd\n"); + $toremove = "enter potential passwords, one per line...\n$passwd: "; + if (substr($out, 0, strlen($toremove)) == $toremove) { + $out = substr($out, strlen($toremove)); + } + $out = preg_replace("/\s+$/", "", $out); + + // This is more portable + } else { + $cmd = array("/usr/bin/perl", "-e", + "use Crypt::Cracklib; print fascist_check();"); + $out = xruncmd($cmd, $passwd); + } + + if ($out == "ok") { + $GLOBALS["_CRACKLIB_LASTMMSG"] = "strong password"; + return true; + } else { + $GLOBALS["_CRACKLIB_LASTMMSG"] = $out; + return false; + } +} + +// crack_getlastmessage: Return the last message from Cracklib +function crack_getlastmessage() +{ + return $GLOBALS["_CRACKLIB_LASTMMSG"]; +} + +} + +?> diff --git a/lib/php/monica/curtime.inc.php b/lib/php/monica/curtime.inc.php new file mode 100644 index 0000000..bec3b03 --- /dev/null +++ b/lib/php/monica/curtime.inc.php @@ -0,0 +1,27 @@ + +// Copyright: Copyright (C) 2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/hires.inc.php"; + +// Settings +if (!defined("NOW")) { + define("NOW", time()); +} +if (!defined("TODAY")) { + define("TODAY", date("Y-m-d")); +} +// Log the start time +if (!defined("T_START")) { + define("T_START", time_hires()); +} + +?> diff --git a/lib/php/monica/decform.inc.php b/lib/php/monica/decform.inc.php new file mode 100644 index 0000000..84ca674 --- /dev/null +++ b/lib/php/monica/decform.inc.php @@ -0,0 +1,238 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/getlang.inc.php"; +require_once "monica/http.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/unicode.inc.php"; + +// Settings +$_DECFORM_TRY = array( + "US-ASCII", "Big5", "GB2312", "GB18030", "Shift-JIS", "UTF-8" +); + + +// decode_forms: Decode user input FORMs to UTF-8 +function decode_forms() +{ + // Don't redo + static $done; + if (isset($done)) { + return; + } + + global $ALL_LINGUAS; + + // Initialize the data deposit + $GLOBALS["USER_INPUT"] = array( + "GET_RAW" => $_GET, + "GET_UTF8" => $_GET, + "GET_CHARSET" => null, + "GET_CSERR" => true, + "GET_KEYS" => array_keys($_GET), + "POST_RAW" => $_POST, + "POST_UTF8" => $_POST, + "FILES_RAW" => $_FILES, + "FILES_UTF8" => $_FILES, + "POST_CHARSET" => null, + "POST_CSERR" => true, + ); + global $USER_INPUT; + + // The possible character sets of this website + $charsets_site = array(); + for ($l = 0; $l < count($ALL_LINGUAS); $l++) { + $charsets_site[] = ln($ALL_LINGUAS[$l], LN_CHARSET); + } + + // The GET arguments + // The character set candidates + $charsets = array(); + if (array_key_exists("charset", $_GET)) { + $charsets[] = $_GET["charset"]; + } + $charsets[] = getlang(LN_CHARSET); + $charsets = array_merge($charsets, $charsets_site); + $charsets = array_merge($charsets, $GLOBALS["_DECFORM_TRY"]); + $charsets = array_values(array_unique($charsets)); + // Check each character set + foreach ($charsets as $charset) { + $GET = $USER_INPUT["GET_RAW"]; + // In this character set + if (_decform_array2u8($GET, $charset)) { + $_GET = $GET; + $USER_INPUT["GET_UTF8"] = $GET; + $USER_INPUT["GET_CHARSET"] = $charset; + $USER_INPUT["GET_CSERR"] = false; + break; + } + } + + // The POSTed form + // The character set candidates + $cands = array(); + if (array_key_exists("charset", $_POST)) { + $cands[] = $_POST["charset"]; + } + $cands[] = getlang(LN_CHARSET); + $cands = array_merge($cands, $charsets_site); + $cands = array_merge($cands, $GLOBALS["_DECFORM_TRY"]); + $charsets = array(); + $lcharsets = array(); + foreach ($cands as $charset) { + $lcharset = strtolower($charset); + if (in_array($lcharset, $lcharsets)) { + continue; + } + $charsets[] = $charset; + $lcharsets[] = $lcharset; + switch (strtolower($lcharset)) { + case "big5": + $charsets[] = "CP950"; + $lcharsets[] = "cp950"; + break; + case "gb2312": + $charsets[] = "GB18030"; + $lcharsets[] = "gb18030"; + break; + } + } + // Check each character set + foreach ($charsets as $charset) { + $POST = $USER_INPUT["POST_RAW"]; + $FILES = $USER_INPUT["FILES_RAW"]; + // In this character set + if ( _decform_array2u8($POST, $charset) + && _decform_files2u8($FILES, $charset)) { + $_POST = $POST; + $_FILES = $FILES; + $USER_INPUT["POST_UTF8"] = $POST; + $USER_INPUT["FILES_UTF8"] = $FILES; + $USER_INPUT["POST_CHARSET"] = $charset; + $USER_INPUT["POST_CSERR"] = false; + break; + } + } + + // No valid character set was found + if ($USER_INPUT["GET_CSERR"] || $USER_INPUT["POST_CSERR"]) { + http_400("Unable to detect the character set of your submitted information. Please specify the input character set with charset= parameter."); + } + + $done = true; + return; +} + +// _decform_array2u8: Convert an array from a specific character set +// to UTF-8 +function _decform_array2u8(&$FORM, $charset) +{ + // Convert each column value + foreach (array_keys($FORM) as $col) { + // Try to decode the colume name first + $colu8 = h_decode($col, $charset); + // Found something not in this character set + if (is_null($colu8)) { + return false; + } + // Not a piece of valid unicode text + if (!is_valid_unicode($colu8)) { + return false; + } + // Change the key + if ($col != $colu8) { + $FORM[$colu8] =& $FORM[$col]; + unset($FORM[$col]); + $col = $colu8; + } + // An array of values + if (is_array($FORM[$col])) { + // Fail to decode this array + if (!_decform_array2u8($FORM[$col], $charset)) { + return false; + } + // A scalar value + } else { + $val = $FORM[$col]; + // Remove "\x00". This will cause error with sql_esctext() and sql_esclike(). + $val = str_replace("\x00", "", $val); + $val = h_decode($val, $charset); + // Found something not in this character set + if (is_null($val)) { + return false; + } + // Not a piece of valid unicode text + if (!is_valid_unicode($val)) { + return false; + } + $FORM[$col] = $val; + } + } + // Everything OK + return true; +} + +// _decform_files2u8: Convert the POSTed files from a specific character set +// to UTF-8 +function _decform_files2u8(&$FILES, $charset) +{ + // Convert each filename + foreach (array_keys($FILES) as $col) { + // Try to decode the colume name first + $colu8 = h_decode($col, $charset); + // Found something not in this character set + if (is_null($colu8)) { + return false; + } + // Not a piece of valid unicode text + if (!is_valid_unicode($colu8)) { + return false; + } + // Not a piece of valid unicode text + if (!is_valid_unicode($colu8)) { + return false; + } + // Change the key + if ($col != $colu8) { + $FORM[$colu8] =& $FORM[$col]; + unset($FORM[$col]); + $col = $colu8; + } + // An array of files + if ( !array_key_exists("tmp_name", $FILES[$col]) + || is_array($FILES[$col]["tmp_name"])) { + // Fail to decode this array + if (!_decform_files2u8($FILES[$col], $charset)) { + return false; + } + // A singular file + } else { + $val = $FILES[$col]["name"]; + // Remove "\x00". This will cause error with sql_esctext() and sql_esclike(). + $val = str_replace("\x00", "", $val); + $val = h_decode($val, $charset); + // Found something not in this character set + if (is_null($val)) { + return false; + } + // Not a piece of valid unicode text + if (!is_valid_unicode($val)) { + return false; + } + $FILES[$col]["name"] = $val; + } + } + // Everything OK + return true; +} + +?> diff --git a/lib/php/monica/echoform.inc.php b/lib/php/monica/echoform.inc.php new file mode 100644 index 0000000..a308388 --- /dev/null +++ b/lib/php/monica/echoform.inc.php @@ -0,0 +1,345 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// This file is in UTF-8 萬國碼 + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/callform.inc.php"; +require_once "monica/commtext.inc.php"; +require_once "monica/formfunc.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/htmlchar.inc.php"; +require_once "monica/markabbr.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/sql.inc.php"; + +// locale_date: Obtain a localed date representation +function locale_date($date, $lang = null) +{ + if (is_null($lang)) { + $lang = getlang(); + } + switch ($lang) { + case "zh-tw": + $d = localtime($date); + return sprintf("%d 年 %d 月 %d 日", + $d[5]+1900-1911, $d[4]+1, $d[3]); + case "de": + return date("F j Y", $date); + case "en": + default: + return date("F j Y", $date); + } + return; +} + +// locale_month: Obtain a localed month representation +function locale_month($date, $lang = null) +{ + if (is_null($lang)) { + $lang = getlang(); + } + switch ($lang) { + case "zh-tw": + $d = localtime($date); + return sprintf("%d 年 %d 月", + $d[5]+1900-1911, $d[4]+1); + case "de": + case "en": + default: + return date("F Y", $date); + } + return; +} + +// locale_year: Obtain a localed year representation +function locale_year($date, $lang = null) +{ + if (is_null($lang)) { + $lang = getlang(); + } + switch ($lang) { + case "zh-tw": + $d = localtime($date); + return sprintf("%d 年", $d[5]+1900-1911); + case "de": + case "en": + default: + return date("Y", $date); + } + return; +} + +// locale_amount: Obtain a localed amount representation +function locale_amount($amount, $lang = null) +{ + if (is_null($lang)) { + $lang = getlang(); + } + switch ($lang) { + case "zh-tw": + // 一萬以下 + if (mb_strlen($amount) <= 4) { + return $amount; + // 一億以下 + } elseif (mb_strlen($amount) <= 8) { + $sig = mb_substr($amount, 0, -4) . "." . mb_substr($amount, -4); + while (mb_substr($sig, -1) == "0") { + $sig = mb_substr($sig, 0, -1); + } + if (mb_substr($sig, -1) == ".") { + $sig = mb_substr($sig, 0, -1); + } + return sprintf("%s ( %s 萬)", + $amount, $sig); + // 一兆以下 + } elseif (mb_strlen($amount) <= 12) { + $sig = mb_substr($amount, 0, -8) . "." . mb_substr($amount, -8); + while (mb_substr($sig, -1) == "0") { + $sig = mb_substr($sig, 0, -1); + } + if (mb_substr($sig, -1) == ".") { + $sig = mb_substr($sig, 0, -1); + } + return sprintf("%s ( %s 億)", + $amount, $sig); + // 一兆以上 + } else { + $sig = mb_substr($amount, 0, -12) . "." . mb_substr($amount, -12); + while (mb_substr($sig, -1) == "0") { + $sig = mb_substr($sig, 0, -1); + } + if (mb_substr($sig, -1) == ".") { + $sig = mb_substr($sig, 0, -1); + } + return sprintf("%s ( %s 兆)", + $amount, $sig); + } + case "en": + // Less than one thousand + if (mb_strlen($amount) <= 3) { + return $amount; + // Less than one million + } elseif (mb_strlen($amount) <= 6) { + $sig = mb_substr($amount, 0, -3) . "." . mb_substr($amount, -3); + while (mb_substr($sig, -1) == "0") { + $sig = mb_substr($sig, 0, -1); + } + if (mb_substr($sig, -1) == ".") { + $sig = mb_substr($sig, 0, -1); + } + return sprintf("%s (%s thousands)", + $amount, $sig); + // Less than one billion + } elseif (mb_strlen($amount) <= 9) { + $sig = mb_substr($amount, 0, -6) . "." . mb_substr($amount, -6); + while (mb_substr($sig, -1) == "0") { + $sig = mb_substr($sig, 0, -1); + } + if (mb_substr($sig, -1) == ".") { + $sig = mb_substr($sig, 0, -1); + } + return sprintf("%s (%s millions)", + $amount, $sig); + // More than one billion + } else { + $sig = mb_substr($amount, 0, -9) . "." . mb_substr($amount, -9); + while (mb_substr($sig, -1) == "0") { + $sig = mb_substr($sig, 0, -1); + } + if (mb_substr($sig, -1) == ".") { + $sig = mb_substr($sig, 0, -1); + } + return sprintf("%s (%s billions)", + $amount, $sig); + } + } + return; +} + +// report_size: Obtain a human readable size +function report_size($size) +{ + // Get the size + $report = sprintf(C_("%s bytes"), number_format($size)); + + // Try to use KB as the unit + $kb = $size / 1024; + // Bounce if there are fewer than 3 digits in the rounded result + if (round($kb * 100, 0) < 100) { + return $report; + } + // Check the rounded result for each digit + for ($d = 2; $d >= 0; $d--) { + $digits = pow(10, $d); + $rounded = round($kb * $digits, 0); + // There are 3 significient digits in the rounded result + if ($rounded < 1000) { + return sprintf("%s (%.".$d."f KB)", + $report, $rounded / $digits); + } + } + + // Try to use MB as the unit + $mb = $kb / 1024; + // Check each digit + for ($d = 2; $d >= 0; $d--) { + $digits = pow(10, $d); + $rounded = round($mb * $digits, 0); + // There are 3 significient digits in the rounded result + if ($rounded < 1000) { + return sprintf("%s (%.".$d."f MB)", + $report, $rounded / $digits); + } + } + + // Try to use GB as the unit + $gb = $mb / 1024; + // Check each digit + for ($d = 2; $d >= 0; $d--) { + $digits = pow(10, $d); + $rounded = round($gb * $digits, 0); + // There are 3 significient digits in the rounded result + if ($rounded < 1000) { + return sprintf("%s (%.".$d."f GB)", + $report, $rounded / $digits); + } + } + + // Try to use TB as the unit + $tb = $gb / 1024; + // Check each digit + for ($d = 2; $d >= 0; $d--) { + $digits = pow(10, $d); + $rounded = round($tb * $digits, 0); + // There are 3 significient digits in the rounded result + if ($rounded < 1000) { + return sprintf("%s (%.".$d."f TB)", + $report, $rounded / $digits); + } + } + + // More than TB + return sprintf("%s (%s TB)", + $report, number_format(round($tb, 0))); +} + +// auto_keep_referer: If we should keep the referer information +function auto_keep_referer($auto_keep_referer = null) +{ + // Cache the result + static $cache; + // Set the value + if (!is_null($auto_keep_referer)) { + return ($cache = $auto_keep_referer); + } + // Return the cache + if (isset($cache)) { + return $cache; + } + + // Only work for forms + if (!is_form()) { + return ($cache = false); + } + // Not for called forms + if (is_called_form()) { + return ($cache = false); + } + // Only work for the first forms + if (!is_first_form()) { + return ($cache = false); + } + // Respect the specified referer + $FORM =& curform(); + if (array_key_exists("referer", $FORM)) { + return ($cache = false); + } + // Referer not specified + if (!array_key_exists("HTTP_REFERER", $_SERVER)) { + return ($cache = false); + } + + // Only keep referer from the same host + // Check the prefix of the referer + $prefix = REQUEST_HOSTPORT . "/"; + return ($cache = (substr($_SERVER["HTTP_REFERER"], 0, strlen($prefix)) == $prefix)); +} + +// opt_list: Return an options list +function opt_list($select, $curval) +{ + // Cache the result + $cache = array(); + + // Not cached yet + if (!array_key_exists($select, $cache)) { + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0, $opts = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $opts[] = array( + "value" => $row["value"], + "content" => $row["content"], + ); + } + // Obtain the HTML + $cache[$select] = opt_list_array($opts); + } + + return preselect_options($cache[$select], $curval); +} + +// opt_list_array: Return an options list from an array +function opt_list_array($opts) +{ + // Obtain the HTML + ob_start(); +?> + +"; + $pos = strpos($html, $option); + + // Not selected if there is no such value in the options + if ($pos === false) { + return $html; + } + + $prefix = substr($html, 0, $pos); + $suffix = substr($html, $pos + strlen($option)); + $selected = "
    + + +_cur)) { + return; + } +?> + _type != "cur") { + ?> class="th"_type == "cur") { + ?> colspan="2" scope="row">_mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cval_text($col); + if (!is_null($prompt)) { + echo "\n

    " . h_abbr($prompt) . "

    \n "; + } ?> + +_cur)) { + return; + } +?> + _type != "cur") { + ?> class="th"_type == "cur") { + ?> colspan="2" scope="row">_mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cval_textarea($col); + if (!is_null($prompt)) { + echo "\n

    " . h_abbr($prompt) . "

    \n "; + } ?> + +_cur)) { + return; + } + $text = $this->_cur[$col]? $true: $false; +?> + _type != "cur") { + ?> class="th"_type == "cur") { + ?> colspan="2" scope="row">_mark($col); echo h_abbr($label); ?> + _colspan(); ?>>" . h_abbr($prompt) . "

    \n "; + } ?> + +_cur)) { + return; + } +?> + _type != "cur") { + ?> class="th"_type == "cur") { + ?> colspan="2" scope="row">_mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur[$col])); + if (!is_null($prompt)) { + echo "\n

    " . h_abbr($prompt) . "

    \n "; + } ?> + +_cur)) { + return; + } + // We work with Unix epoch time + $date = $this->_cur[$col]; + if (is_null($date)) { + $date = t_none(); + } else { + $date = is_int($date)? $date: strtotime($date); + $date = date("Y-m-d", $date); + } +?> + _type != "cur") { + ?> class="th"_type == "cur") { + ?> colspan="2" scope="row">_mark($col); echo h_abbr($label); ?> + _colspan(); ?>>" . h_abbr($prompt) . "

    \n "; + } ?> + +_cur)) { + return; + } + // We work with Unix epoch time + $date = $this->_cur[$col]; + if (is_null($date)) { + $date = t_none(); + } else { + // ISO date-time with miniseconds cannot be read by strtotime() + if (preg_match("/^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}).(\d+)$/", $date, $m)) { + $date = strtotime($m[1]); + $nsec = ("0.".$m[2])*1000000; + // Unix epoch with miniseconds cannot be read by strtotime() + } elseif (preg_match("/^(\d+).(\d+)$/", $date, $m)) { + $date = $m[1]; + $nsec = ("0.".$m[2])*1000000; + } else { + $date = is_int($date)? $date: strtotime($date); + $nsec = null; + } + $date = date("Y-m-d H:i:s", $date); + if (!is_null($nsec)) { + $date .= ".$nsec"; + } + } +?> + _type != "cur") { + ?> class="th"_type == "cur") { + ?> colspan="2" scope="row">_mark($col); echo h_abbr($label); ?> + _colspan(); ?>>" . h_abbr($prompt) . "

    \n "; + } ?> + +_cur)) { + return; + } + $lang = !is_null($this->_cur[$col])? + ln($this->_cur[$col], LN_DESC_CURLC): t_none(); +?> + _type != "cur") { + ?> class="th"_type == "cur") { + ?> colspan="2" scope="row">_mark($col); echo h_abbr($label); ?> + _colspan(); ?>>" . h_abbr($prompt) . "

    \n "; + } ?> + +_cur)) { + return; + } +?> + _type != "cur") { + ?> class="th"_type == "cur") { + ?> colspan="2" scope="row">_mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur[$col])); + if (!is_null($prompt)) { + echo "\n

    " . h_abbr($prompt) . "

    \n "; + } ?> + +_cur)) { + return; + } +?> + _type != "cur") { + ?> class="th"_type == "cur") { + ?> colspan="2" scope="row">_mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur[$col])); + if (!is_null($prompt)) { + echo "\n

    " . h_abbr($prompt) . "

    \n "; + } ?> + +_cur)) { + return; + } +?> + _type != "cur") { + ?> class="th"_type == "cur") { + ?> colspan="2" scope="row">_mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur[$col] == $opts[$i]["val"]) { + $found = true; + echo h_abbr($opts[$i]["title"]); + break; + } + } + if (!$found) { + echo h_abbr(t_na()); + } ?> + +_type) { + // A form to create a new item + case "new": + $newalt = C_("Picture preview"); + $rows_new = 1; + if ( !is_null($this->_form($col . "pic")) + && pic_exists($this->_form($col . "pic"))) { + $rows_new = 2; + } +?> + rowspan="" scope="row"> +_form($col . "pic"))) { +?> _colspan(); ?>> +_form($col . "pic"))) { +?> _colspan(); ?>> + _colspan(); ?>>_val_text($col . "pic"); ?> /> + _form($col . "pic")]; + echopic($pic, $newalt, $pic["ratio"]); +?> + + + + + _colspan(); + ?>>_val_text($col . "cap", "piccap"); ?> /> + +_form($col . "pic")) + && pic_exists($this->_form($col . "pic"))) { + $rows_new = 2; + } + $rows_cur = 1; + if ( array_key_exists($col . "pic", $this->_cur) + && !is_null($this->_cur[$col . "pic"])) { + $rows_cur = 2; + } +?> + rowspan="" scope="row"> + rowspan="" scope="row"> + _colspan(); ?>>_cur[$col . "pic"])) { + echo h_abbr(t_none()); + } elseif ($this->_cur[$col . "pic"] === false) { + echo h_abbr(t_na()); + } else { + $pic =& $PICS[$this->_cur[$col . "pic"]]; + echopic($pic, $origalt, $pic["ratio"]); + echo " "; + } + ?> +_cur) + && !is_null($this->_cur[$col . "pic"])) { +?> + + _mark($col . "cap"); echo h_abbr(C_("Caption:")); ?> + _colspan(-1); ?>>_cval_text($col . "cap"); ?> + + + rowspan="" scope="row"> +_form($col . "pic"))) { +?> _colspan(); ?>> + +_form($col . "pic"))) { +?> _colspan(); ?>> + + _colspan(); ?>>_val_text($col . "pic"); ?> /> + _form($col . "pic")]; + echopic($pic, $newalt, $pic["ratio"]); +?> + + + + + _colspan(); + ?>>_val_text($col . "cap", "piccap"); ?> /> + + + rowspan="" scope="row">_mark($col . "pic"); echo h_abbr(sprintf(C_("Picture #%d:"), $i)); ?> + _colspan(); ?>>_cur[$col . "pic"])) { + echo h_abbr(t_none()); + } elseif ($this->_cur[$col . "pic"] === false) { + echo h_abbr(t_na()); + } else { + $pic =& $PICS[$this->_cur[$col . "pic"]]; + echopic($pic, $origalt, $pic["ratio"]); + echo " "; + ?> + + + _mark($col . "cap"); echo h_abbr(C_("Caption:")); ?> + _colspan(); ?>>_cval_text($col . "cap"); + } + ?> + + + _colspan_full(); + ?>>_val_check($col); ?> /> + +

    + + +_defsize; + $class = " class=\"text\""; + } else { + $class = ""; + } + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); + ?>> type="text" name="" size=""_val_text($col, $col); ?> />" . h_abbr($prompt) . "

    \n "; + } ?> + + +_mlcols) || getlang() == DEFAULT_LANG) { +?> + + + _colspan(); ?>>_cval_text($col . "_$lndbdef"); ?> + + + + _colspan(); ?>>_cval_text($col); ?> + + + +_mlcols) + && getlang() != DEFAULT_LANG + && is_null($this->_cur[$col . "_$lndbdef"])) { +?> _colspan(); ?>> + _colspan(); + ?>> type="text" name="" size=""_val_text($col, $col); ?> />" . h_abbr($prompt) . "

    \n "; + } ?> + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cval_text($col); ?> + +_defsize; + $class = " class=\"textnull\""; + } else { + $class = ""; + } + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); ?>>
      +
    • _val_radio($nullcol, "false"); ?> /> + type="text" name="" size=""_val_text($col, $col); ?> /> +
    • +
    • _val_radio($nullcol, "true"); ?> /> + +
    • +
    +

    + + +_is_first_form) { + $this->_form[$nullcol] = is_null($this->_form($col))? + "true": "false"; + } +?> + + + _colspan(); ?>>_cur[$col])? h($this->_cur[$col]): + h($nulllabel); ?> + + + + _colspan(); ?>>
      +
    • _val_radio($nullcol, "false"); ?> /> + type="text" name="" size=""_val_text($col, $col); ?> /> +
    • +
    • _val_radio($nullcol, "true"); ?> /> + +
    • +
    +

    + + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur[$col])? h($this->_cur[$col]): + h($nulllabel); ?> + +_defsize; + } + $id = ($col == "body"? "fbody": $col); + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); + ?>>" . h_abbr($prompt) . "

    \n "; + } ?> + + +_mlcols) || getlang() == DEFAULT_LANG) { +?> + + + _colspan(); ?>>_cval_textarea($col . "_$lndbdef"); ?> + + + + _colspan(); ?>>_cval_textarea($col); ?> + + + +_mlcols) + && getlang() != DEFAULT_LANG + && is_null($this->_cur[$col . "_$lndbdef"])) { +?> _colspan(); ?>> + _colspan(); + ?>>" . h_abbr($prompt) . "

    \n "; + } ?> + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cval_textarea($col); ?> + +_defsize; + } + $id = ($col == "body"? "fbody": $col); + $hide = C_("Hide"); + $show = C_("Show"); + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); + ?>>" . h_abbr($prompt) . "

    \n "; + } ?> + +_form) + || $this->_form[$col . "hidden"] != "no") { + $this->_form[$col . "hidden"] = "yes"; + } +?> +_mlcols) || getlang() == DEFAULT_LANG) { +?> +_form) + || $this->_form[$col . "defhidden"] != "no") { + $this->_form[$col . "defhidden"] = "yes"; + } +?> + + _colspan(); ?>>_val_text($col . "defhidden"); ?> />_form[$col . "defhidden"] == "yes") { + ?>
    +_cval_textarea($col . "_$lndbdef"); + } ?> + + + + _colspan(); ?>>_val_text($col . "hidden"); ?> />_form[$col . "hidden"] == "yes") { + ?>
    +_cval_textarea($col); + } ?> + + + +_mlcols) + && getlang() != DEFAULT_LANG + && is_null($this->_cur[$col . "_$lndbdef"])) { +?> _colspan(); ?>> + _colspan(); + ?>>" . h_abbr($prompt) . "

    \n "; + } ?> + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_form) + && !array_key_exists("hide$col", $this->_form)) { + ?>
    +_cval_textarea($col); + } else { + ?> + +_type) { + // A form to create a new item + case "new": +?> + + _colspan(); + ?>>_val_check($col); ?> /> + +

    + + + + + + _colspan(); ?>>_cur[$col]? $true: $false); ?> + + + + _colspan(); + ?>>_val_check($col); ?> /> + +

    + + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur[$col]? $true: $false); ?> + +_form) + && $this->_form[$col] == "") { + unset($this->_form[$col]); + } + $choose = C_("Choose"); + $delete = C_("Delete"); + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); + ?>> +_form($col))) { +?> + + _val_text($col); ?> /> +

    + + + + + + _colspan(); ?>>_cur[$col])); ?> + + + + _colspan(); + ?>> +_form($col))) { +?> + + _val_text($col); ?> /> +

    + + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur[$col])); ?> + +_form) + && $this->_form[$col] == "") { + unset($this->_form[$col]); + } + $choose = C_("Choose"); + $delete = C_("Delete"); + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); ?>>
      +
    • _val_radio($nullcol, "false"); ?> /> + +_form($col))) { +?> + + _val_text($col); ?> /> +
    • +
    • _val_radio($nullcol, "true"); ?> /> + +
    • +
    +

    + + +_is_first_form) { + $this->_form[$nullcol] = is_null($this->_form($col))? + "true": "false"; + } +?> + + + _colspan(); ?>>_cur[$col])? + h(call_user_func($titlefunc, $this->_cur[$col])): + h($nulllabel); ?> + + + + _colspan(); ?>>
      +
    • _val_radio($nullcol, "false"); ?> /> + +_form($col))) { +?> + + _val_text($col); ?> /> +
    • +
    • _val_radio($nullcol, "true"); ?> /> + +
    • +
    +

    + + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur[$col])? + h(call_user_func($titlefunc, $this->_cur[$col])): + h($nulllabel); ?> + +_form) + && $this->_form[$col] == "") { + unset($this->_form[$col]); + } + $choose = C_("Choose"); + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); ?>> + +

    + + +_is_first_form) { + $this->_form[$col . "userecent"] = "true"; + } +?> + + + _colspan(); ?>>_cur[$col])); ?> + + + + _colspan(); ?>> + +

    + + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur[$col])); ?> + +_type) { + // A form to create a new item + case "new": +?> + + _colspan(); + ?>> +

    + + + + + + _colspan(); ?>>_cur[$col])); ?> + + + + _colspan(); + ?>> +

    + + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur[$col])); ?> + +_form); $i++) { } + for ($i--; $i >= 0 && $this->_form["$col$i"] == ""; $i--) { }; + $count = $i + 3; + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); ?>>
  • +
  • + 0) { + $htmls[] = "
      \n" . implode("", $items) . "
    \n"; + } + if (!is_null($prompt)) { + $htmls[] = "

    " . h_abbr($prompt) . "

    \n"; + } + if (count($htmls) > 0) { + echo implode(" ", $htmls) . " "; + } ?> + + + + + _colspan(); ?>>_cur); $i++) { + $items[] = "
  • " . h($this->_cur["$col$i" . "title"]) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + + + + _colspan(); ?>>
  • +
  • + 0) { + $htmls[] = "
      \n" . implode("", $items) . "
    \n"; + } + if (!is_null($prompt)) { + $htmls[] = "

    " . h_abbr($prompt) . "

    \n"; + } + if (count($htmls) > 0) { + echo implode(" ", $htmls) . " "; + } ?> + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur); $i++) { + $items[] = "
  • " . h($this->_cur["$col$i" . "title"]) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + +_type) { + // A form to create a new item + case "new": + $coldef = $col . (array_key_exists("id", $opts[0])? + $opts[0]["id"]: $opts[0]["val"]); +?> + + _colspan(); ?>>
  • _val_radio($col, $val); ?> /> + +
  • + 0) { + $htmls[] = "\n" . implode("", $items) . " \n "; + } + if (!is_null($prompt)) { + $htmls[] = "

    " . h_abbr($prompt) . "

    \n"; + } + if (count($htmls) > 0) { + echo implode(" ", $htmls) . " "; + } ?> + + + + + _colspan(); ?>>_cur[$col] == $opts[$i]["val"]) { + $found = true; + echo h_abbr($opts[$i]["title"]); + break; + } + } + if (!$found) { + echo h_abbr(t_na()); + } ?> + + + + _colspan(); ?>>
  • _val_radio($col, $val); ?> /> + +
  • + 0) { + $htmls[] = "\n" . implode("", $items) . " \n "; + } + if (!is_null($prompt)) { + $htmls[] = "

    " . h_abbr($prompt) . "

    \n"; + } + if (count($htmls) > 0) { + echo implode(" ", $htmls) . " "; + } ?> + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur[$col] == $opts[$i]["val"]) { + $found = true; + echo h_abbr($opts[$i]["title"]); + break; + } + } + if (!$found) { + echo h_abbr(t_na()); + } ?> + +_defsize; + $class = " class=\"text\""; + } else { + $class = ""; + } + $delfile = C_("Delete this file"); + switch ($this->_type) { + // A form to create a new item + case "new": + $newrowspan = 2; + if ( !is_null($this->_form($col)) + && savefile_exists($this->_form($col))) { + $newrowspan += 2; + $newfile =& $FILES[$this->_form($col)]; + if (array_key_exists("name", $newfile)) { + $newrowspan++; + } + } +?> + rowspan="" scope="row"> +_form($col))) { +?> _colspan(); ?>> +_form($col))) { +?> _colspan(); ?>> + + _colspan(-1); + ?>> + + + + _colspan(-1); + ?>> + + + + _colspan(-1); + ?>> + + + _colspan(); + ?>> + + + _colspan(); ?>>_form) && !is_null($this->_form[$col])) { + ?>_val_text($col); ?> /> type="file" name="up" size="" />" . h_abbr($prompt) . "

    \n "; + } ?> + +_mlcols) && getlang() != DEFAULT_LANG) { + $srcrowspan = 1; + $coldef = $col . "_" . $lndbdef; + if (!is_null($this->_cur[$coldef])) { + $srcrowspan += 1; + $curfiledef =& $FILES[$this->_cur[$coldef]]; + if (array_key_exists("name", $curfiledef)) { + $srcrowspan++; + } + } + $rowspan += $srcrowspan; + } + $currowspan = 1; + if (!is_null($this->_cur[$col])) { + $currowspan += 1; + $curfile =& $FILES[$this->_cur[$col]]; + if (array_key_exists("name", $curfile)) { + $currowspan++; + } + } + $rowspan += $currowspan; + $newrowspan = 2; + // A multi-lingual column that is not in the default language, + // and the content for the default language is not available + if ( in_array($col, $this->_mlcols) + && getlang() != DEFAULT_LANG + && is_null($this->_cur[$coldef])) { + $newrowspan--; + } + if ( !is_null($this->_form($col)) + && savefile_exists($this->_form($col))) { + $newrowspan += 2; + $newfile =& $FILES[$this->_form($col)]; + if (array_key_exists("name", $newfile)) { + $newrowspan++; + } + } + $rowspan += $newrowspan; +?> + rowspan="" scope="row"> +_mlcols) && getlang() != DEFAULT_LANG) { +?> rowspan="" scope="row"> +_cur[$coldef])) { +?> _colspan(); ?>> + + + + _colspan(-1); + ?>> + + + + _colspan(-1); + ?>> + + + + _colspan(-1); + ?>> + + + rowspan="" scope="row"> +_cur[$col])) { +?> _colspan(); ?>> + + + _colspan(-1); + ?>> + + + + _colspan(-1); + ?>> + + + + _colspan(-1); + ?>> + + + rowspan="" scope="row"> +_mlcols) + && getlang() != DEFAULT_LANG + && is_null($this->_cur[$coldef])) { +?> _colspan(); ?>> + +_form($col))) { +?> _colspan(); ?>> +_form($col))) { +?> _colspan(); ?>> + + _colspan(-1); + ?>> + + + + _colspan(-1); + ?>> + + + + _colspan(-1); + ?>> + + + _colspan(); + ?>> + + + _colspan(); ?>>_form) && !is_null($this->_form[$col])) { + ?>_val_text($col); ?> /> type="file" name="up" size="" />" . h_abbr($prompt) . "

    \n "; + } ?> + +_cur[$col])) { + $currowspan += 1; + $curfile =& $FILES[$this->_cur[$col]]; + if (array_key_exists("name", $curfile)) { + $currowspan++; + } + } +?> + rowspan="" scope="row">_mark($col); echo h_abbr($label); ?> +_cur[$col])) { +?> _colspan(); ?>> + + + _colspan(-1); + ?>> + + + + _colspan(-1); + ?>> + + + + _colspan(-1); + ?>> + +_is_first_form && $this->_type == "new") { + $this->_form[$col] = date("Y-m-d"); + } + // We work with Unix epoch time + if (!is_null($this->_cur) && array_key_exists($col, $this->_cur)) { + $date = $this->_cur[$col]; + if (is_null($date)) { + $date = t_none(); + } else { + $date = is_int($date)? $date: strtotime($date); + $date = date("Y-m-d", $date); + } + $cur = $date; + } + + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); + ?>>_val_date($col, $col); ?> />" . h_abbr($prompt) . "

    \n "; + } ?> + + +_mlcols) || getlang() == DEFAULT_LANG) { +?> +_cur[$col . "_$lndbdef"]; + if (is_null($curdef)) { + $curdef = t_none(); + } else { + $curdef = is_int($curdef)? $curdef: strtotime($curdef); + $curdef = date("Y-m-d", $curdef); + } +?> + + _colspan(); ?>> + + + + _colspan(); ?>> + + + +_mlcols) + && getlang() != DEFAULT_LANG + && is_null($this->_cur[$col . "_$lndbdef"])) { +?> _colspan(); ?>> + _colspan(); + ?>>_val_date($col, $col); ?> />" . h_abbr($prompt) . "

    \n "; + } ?> + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>> + +_is_first_form && $this->_type == "new") { + $this->_form[$col] = date("Y-m-d"); + } + // We work with Unix epoch time + if (!is_null($this->_cur) && array_key_exists($col, $this->_cur)) { + $date = $this->_cur[$col]; + if (is_null($date)) { + $date = t_none(); + } else { + $date = is_int($date)? $date: strtotime($date); + $date = date("Y-m-d", $date); + } + $cur = $date; + } + + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); ?>>
      +
    • _val_radio($nullcol, "false"); ?> /> + _val_date($col, $col); ?> /> +
    • +
    • _val_radio($nullcol, "true"); ?> /> + +
    • +
    +

    + + +_is_first_form) { + $this->_form[$nullcol] = is_null($this->_form($col))? + "true": "false"; + } +?> + + + _colspan(); ?>> + + + + _colspan(); ?>>
      +
    • _val_radio($nullcol, "false"); ?> /> + _val_date($col, $col); ?> /> +
    • +
    • _val_radio($nullcol, "true"); ?> /> + +
    • +
    +

    + + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>> + +_is_first_form && $this->_type == "new") { + $this->_form[$col] = date("Y-m-d h:i:s"); + } + // We work with Unix epoch time + if (!is_null($this->_cur) && array_key_exists($col, $this->_cur)) { + $date = $this->_cur[$col]; + if (is_null($date)) { + $date = t_none(); + } elseif (is_int($date)) { + $date = date("Y-m-d h:i:s", $date); + } elseif (is_float($date)) { + $dec = $date - floor($date); + $date = floor($date); + settype($date, "integer"); + $date = date("Y-m-d h:i:s", $date); + if ($dec > 0) { + $date .= substr($dec, 1); + } + } + $cur = $date; + } + + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); + ?>>_val_text($col, $col); ?> />" . h_abbr($prompt) . "

    \n "; + } ?> + + +_mlcols) || getlang() == DEFAULT_LANG) { +?> +_cur[$col . "_$lndbdef"]; + if (is_null($curdef)) { + $curdef = t_none(); + } else { + $curdef = is_int($curdef)? $curdef: strtotime($curdef); + $curdef = date("Y-m-d", $curdef); + } +?> + + _colspan(); ?>> + + + + _colspan(); ?>> + + + +_mlcols) + && getlang() != DEFAULT_LANG + && is_null($this->_cur[$col . "_$lndbdef"])) { +?> _colspan(); ?>> + _colspan(); + ?>>_val_text($col, $col); ?> />" . h_abbr($prompt) . "

    \n "; + } ?> + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>> + +_is_first_form) { + if ($this->_type == "new") { + $this->_form[$col] = "http://"; + } elseif ($this->_type == "cur" && is_null($this->_form($col))) { + $this->_form[$col] = "http://"; + } + } + if (is_null($size)) { + $size = $this->_defsize; + $class = " class=\"text\""; + } else { + $class = ""; + } + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); + ?>> type="text" name="" size=""_val_text($col, $col); ?> />" . h_abbr($prompt) . "

    \n "; + } ?> + + +_mlcols) || getlang() == DEFAULT_LANG) { +?> + + + _colspan(); ?>>_cval_text($col . "_$lndbdef"); ?> + + + + _colspan(); ?>>_cval_text($col); ?> + + + +_mlcols) + && getlang() != DEFAULT_LANG + && is_null($this->_cur[$col . "_$lndbdef"])) { +?> _colspan(); ?>> + _colspan(); + ?>> type="text" name="" size=""_val_text($col, $col); ?> />" . h_abbr($prompt) . "

    \n "; + } ?> + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cval_text($col); ?> + +_type) { + // A form to create a new item + case "new": +?> + + _colspan(); + ?>>_val_text($col, $col); ?> />" . h_abbr($prompt) . "

    \n "; + } ?> + + +_mlcols) || getlang() == DEFAULT_LANG) { +?> + + + _colspan(); ?>>_cur[$col . "_$lndbdef"])); ?> + + + + _colspan(); ?>>_cur[$col])); ?> + + + +_mlcols) + && getlang() != DEFAULT_LANG + && is_null($this->_cur[$col . "_$lndbdef"])) { +?> _colspan(); ?>> + _colspan(); + ?>>_val_text($col, $col); ?> />" . h_abbr($prompt) . "

    \n "; + } ?> + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur[$col])); ?> + +_defsize; + $class = " class=\"text\""; + } else { + $class = ""; + } + $delpic = C_("Delete this picture"); + // Obtain the picture deposit + $PICS =& pic_deposit(); + switch ($this->_type) { + // A form to create a new item + case "new": + $newalt = C_("Picture preview"); +?> + + _colspan(); ?>>_form($col))) { + ?>_val_text($col); ?> /> + _form($col)]; + echopic($pic, $newalt, $pic["ratio"]); +?>
    + \n "; + } + ?> type="file" name="up" size="" /> +" . h_abbr($prompt) . "

    \n"; + } +?> + + + + + _colspan(); ?>>_cur[$col])) { + $pic =& $PICS[$this->_cur[$col]]; + echopic($pic, $origalt, $pic["ratio"]); + echo " "; + } else { + echo h_abbr(t_none()); + } ?> + + + + _colspan(); ?>>_form($col))) { + ?>_val_text($col); ?> /> + _form($col)]; + echopic($pic, $newalt, $pic["ratio"]); +?>
    + \n "; + } + ?> type="file" name="up" size="" /> +" . h_abbr($prompt) . "

    \n"; + } +?> + + + _mark($col); echo h_abbr($label); ?> + _colspan(); ?>>_cur[$col])) { + $pic =& $PICS[$this->_cur[$col]]; + echopic($pic, $origalt, $pic["ratio"]); + echo " "; + } else { + echo h_abbr(t_none()); + } ?> + +_html_coltmpl_textarea("addr", C_("Address:"), + C_("Fill in your address here."), null, 3); + } + + // _html_col_att: The attachment + function _html_col_att() + { + $this->_html_coltmpl_file("att", C_("Attachment:")); + if ( in_array("attdsc", sql_cols_nl($this->_table)) + && !is_null($this->_form("att")) + && savefile_exists($this->_form("att"))) { + $this->_html_coltmpl_text("attdsc", C_("Attachment description:")); + } + } + + // _html_col_bi_address: The address set: country, address + function _html_col_bi_address() + { + if (getlang(LN_COUNTRY_FIRST)) { + $this->_html_col_country(); + $this->_html_col_addr(); + } else { + $this->_html_col_addr(); + $this->_html_col_country(); + } + } + + // _html_col_body: The content body + function _html_col_body() + { + $this->_html_coltmpl_textarea("body", C_("Content:"), + C_("Fill in the content here.")); + } + + // _html_col_city: The city + function _html_col_city() + { + $this->_html_coltmpl_text("city", C_("City:")); + } + + // _html_col_content: The content body + function _html_col_content() + { + $this->_html_coltmpl_textarea("content", C_("Content:"), + C_("Fill in the content here.")); + } + + // _html_col_country: The country + function _html_col_country() + { + // Set the default country to the client country + if ($this->_type == "new" && !array_key_exists("country", $this->_form)) { + $this->_form["country"] = geoiplookup(); + } + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); ?>> + + + + + _colspan(); ?>>_cur["country"])); ?> + + + + _colspan(); ?>> + + + _mark("country"); echo h_abbr(C_("Country:")); ?> + _colspan(); ?>>_cur["country"])); ?> + +_html_coltmpl_ro_datetime("created", C_("Created:")); + } + + // _html_col_createdby: The creator + function _html_col_createdby() + { + $this->_html_coltmpl_ro_user("createdby", C_("Created by:")); + } + + // _html_col_ct: The country + function _html_col_ct() + { + $this->_html_coltmpl_ro_ct("ct", C_("Country:")); + } + + // _html_col_date: The date + function _html_col_date() + { + $this->_html_coltmpl_date("date", C_("Date:")); + } + + // _html_col_disabled: Disabled? + function _html_col_disabled() + { + $this->_html_coltmpl_bool("disabled", C_("Disabled?"), + C_("Disabled"), C_("Enabled"), C_("Disable it.")); + } + + // _html_col_dsc: The description + function _html_col_dsc() + { + $this->_html_coltmpl_textarea("dsc", C_("Description:"), + C_("Fill in the description here."), null, 5); + } + + // _html_col_email: The e-mail + function _html_col_email() + { + $this->_html_coltmpl_text("email", C_("E-mail:")); + } + + // _html_col_fax: The facsimile number + function _html_col_fax() + { + $this->_html_coltmpl_text("fax", C_("Fax:")); + } + + // _html_col_grp: The group + function _html_col_grp() + { + $this->_html_coltmpl_call("grp", C_("Group:"), "groupdsc"); + } + + // _html_col_hid: Hide? + function _html_col_hid() + { + $this->_html_coltmpl_bool("hid", C_("Hide?"), + C_("Hide it"), C_("Show it"), C_("Hide it currently.")); + } + + // _html_col_host: The host + function _html_col_host() + { + $this->_html_coltmpl_ro("host", C_("Host:")); + } + + // _html_col_html: HTML? + function _html_col_html() + { + $this->_html_coltmpl_bool("html", C_("HTML?"), + C_("HTML"), C_("Plain text"), C_("The submitted content is HTML.")); + } + + // _html_col_id: The ID. + function _html_col_id() + { + $this->_html_coltmpl_text("id", C_("ID.:")); + } + + // _html_col_intro: The introduction + function _html_col_intro() + { + $this->_html_coltmpl_textarea("intro", C_("Introduction:"), + C_("Fill in the introduction here.")); + } + + // _html_col_ip: The IP + function _html_col_ip() + { + $this->_html_coltmpl_ro("ip", C_("IP:")); + } + + // _html_col_kw: The keywords + function _html_col_kw() + { + $this->_html_coltmpl_text("kw", C_("Keywords:")); + } + + // _html_col_lang: The language + function _html_col_lang() + { + $this->_html_coltmpl_ro_lang("lang", C_("Language:")); + } + + // _html_col_massdel: The list of items for mass deletion + function _html_col_massdel() + { +?>
      +_cur); $i++) { +?>
    1. _cur["sn$i" . "title"])) { + echo h_abbr(t_na()); + } else { + echo h($this->_cur["sn$i" . "title"]); + } ?>_val_text("sn$i"); ?> />
    2. +
    +_html_coltmpl_text("name", C_("Name:")); + } + + // _html_col_ord: The order + function _html_col_ord() + { + // Set the default order to the half of the maximum + if ($this->_is_first_form && $this->_type == "new" && is_null($this->_form("ord"))) { + $this->_form["ord"] = pow(10, $this->_maxlens["ord"]) / 2; + } + $this->_html_coltmpl_text("ord", C_("Order:"), null, $this->_maxlens["ord"]); + } + + // _html_col_org: The organization + function _html_col_org() + { + $this->_html_coltmpl_text("org", C_("Organization:")); + } + + // _html_col_parent: The parent category + function _html_col_parent() + { + $this->_html_coltmpl_call_null("parent", C_("Parent category:"), + "topmost", C_("At the very top"), $this->_table . "_title"); + } + + // _html_col_passwd: The password + function _html_col_passwd() + { + $size = $this->_defsize; + $dummy = str_repeat("*", 16); + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); ?>>_form("passid"))) { + ?>_val_text("passid"); ?> /> + _val_scalar($dummy, "passwd"); ?> /> + _val_scalar(null, "passwd"); ?> /> + + + + _form("passid2"))) { + ?>_val_text("passid2"); ?> /> + _val_scalar($dummy, "passwd"); ?> /> + _val_scalar(null, "passwd"); ?> /> + + + + _colspan(); ?>>_form("passid"))) { + ?>_val_text("passid"); ?> /> + _val_scalar($dummy, "passwd"); ?> /> + _val_scalar(null, "passwd"); ?> /> + + + + _colspan(); ?>>_form("passid2"))) { + ?>_val_text("passid2"); ?> /> + _val_scalar($dummy, "passwd"); ?> /> +_val_scalar(null, "passwd"); ?> /> +

    + + + + _mark("passwd"); echo h_abbr(C_("Password:")); ?> + _colspan(); ?>> + +_is_first_form && $this->_type == "new") { + $this->_form["path"] = "/"; + } + $this->_html_coltmpl_text("path", C_("Page path:")); + } + + // _html_col_pdf: The PDF file + function _html_col_pdf() + { + $this->_html_coltmpl_file("pdf", C_("PDF. file:")); + } + + // _html_col_pic: The picture + function _html_col_pic() + { + global $PIC_VALID_POS; + // Obtain the picture deposit + $PICS =& pic_deposit(); + $setpic = C_("Set the picture"); + $delpic = C_("Delete this picture"); + $picposid_default = "picpos" . strtolower(PIC_POS_DEFAULT); + switch ($this->_type) { + // A form to create a new item + case "new": + $newalt = C_("Picture preview"); +?> + +_form("pic"))) { +?> _colspan(); ?>> +_form("pic"))) { +?> _colspan(); ?>> + _colspan(); ?>>_val_text("pic"); ?> /> + _form("pic")]; + echopic($pic, $newalt, $pic["ratio"]); +?> + + + + + _colspan(); + ?>>_val_text("piccap", "piccap"); ?> /> + + + + _colspan(); ?>>
      +
    • _val_radio("picpos", $pos, $default); ?> /> + +
    • +
    + + + + + + _colspan(); ?>>_cur["pic"])) { + echo h_abbr(t_none()); + } elseif ($this->_cur["pic"] === false) { + echo h_abbr(t_na()); + } else { + $pic =& $PICS[$this->_cur["pic"]]; + echopic($pic, $origalt, $pic["ratio"]); + echo " "; + } ?> + + + +_cur["pic"]) && getlang() != DEFAULT_LANG) { +?> _colspan(); ?>> +_form("pic"))) { +?> _colspan(); ?>> +_form("pic"))) { +?> _colspan(); ?>> + _colspan(); ?>>_val_text("pic"); ?> /> + _form("pic")]; + echopic($pic, $newalt, $pic["ratio"]); +?> + + + + + + + _colspan(); ?>>_cval_text("piccap_" . ln(DEFAULT_LANG, LN_DATABASE)); ?> + + + + _colspan(); ?>>_cval_text("piccap"); ?> + + + + _colspan(); + ?>>_val_text("piccap", "piccap"); ?> /> + + + + + _colspan(); ?>>_cur) || is_null($this->_cur["picpos"])) { + echo h_abbr(t_notset()); + } else { + echo h(picpos_label($this->_cur["picpos"])); + } ?> + + + + _colspan(); ?>>
      +
    • _val_radio("picpos", $pos, $default); ?> /> + +
    • +
    + + + + _mark("pic"); echo h_abbr(C_("Picture:")); ?> + _colspan(); ?>>_cur["pic"])) { + echo h_abbr(t_none()); + } elseif ($this->_cur["pic"] === false) { + echo h_abbr(t_na()); + } else { + $pic =& $PICS[$this->_cur["pic"]]; + echopic($pic, $origalt, $pic["ratio"]); +?> + + + _mark("pic"); echo h_abbr(C_("Pic. caption:")); ?> + _colspan(); ?>>_cval_text("piccap"); ?> + + + _mark("pic"); echo h_abbr(C_("Pic. position:")); ?> + _colspan(); ?>>_cur["picpos"])); + } + ?> + +_type) { + // A form to create a new item + case "new": +?> + + _colspan(); ?>>_form) + || $this->_form["chinese"] == "") { + echo h(C_("Please fill in the Chinese first.")); + } else { + $pinyins = zh2pys($this->_form["chinese"]); + for ($i = 0, $items = array(); $i < count($pinyins); $i++) { + ob_start(); +?>
  • _val_radio("pinyin", $pinyins[$i]); ?> /> + +
  • +\n" . implode("", $items) . " \n "; + } ?> + + + + + _colspan(); ?>>_cval_text("pinyin"); ?> + + + + _colspan(); ?>>_form) + || $this->_form["chinese"] == "") { + echo h(C_("Please fill in the Chinese first.")); + } else { + $pinyins = zh2pys($this->_form["chinese"]); + for ($i = 0, $items = array(); $i < count($pinyins); $i++) { + ob_start(); +?>
  • _val_radio("pinyin", $pinyins[$i]); ?> /> + +
  • +\n" . implode("", $items) . " \n "; + } ?> + + + _mark("pinyin"); echo h_abbr(C_("Pinyin:")); ?> + _colspan(); ?>>_cval_text("pinyin"); ?> + + + _type != "cur") { + ?> class="th"_type == "cur") { + ?> colspan="2" scope="row">_mark("scats"); echo h_abbr(dngettext(COMMONDOMAIN, + "Subcategory:", "Subcategories:", $this->_cur["scatcount"])); ?> + _colspan(); ?>>_cur["scatcount"]; $i++) { + $items[] = sprintf("
  • %3\$s\n" + . " (%4\$s)
  • \n", + h($this->_procurl), h($this->_cur["scat$i" . "sn"]), + h($this->_cur["scat$i" . "title"]), + h($this->_cur["scat$i" . "url"])); + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + +_html_coltmpl_text("script", C_("Script:")); + } + + // _html_col_sn: The serial number + function _html_col_sn() + { + $this->_html_coltmpl_ro("sn", C_("S/N:")); + } + + // _html_col_street: The street + function _html_col_street() + { + $this->_html_coltmpl_text("street", C_("Street:")); + } + + // _html_col_subject: The subject + function _html_col_subject() + { + $this->_html_coltmpl_text("subject", C_("Subject:")); + } + + // _html_col_tel: The telephone number + function _html_col_tel() + { + $this->_html_coltmpl_text("tel", C_("Telephone:")); + } + + // _html_col_tel: The cellular telephone number + function _html_col_telc() + { + $this->_html_coltmpl_text("telc", C_("Tel. (cell.):")); + } + + // _html_col_tel: The telephone number at home + function _html_col_telh() + { + $this->_html_coltmpl_text("telh", C_("Tel. (home):")); + } + + // _html_col_tel: The telephone number at the office + function _html_col_telo() + { + $this->_html_coltmpl_text("telo", C_("Tel. (office):")); + } + + // _html_col_title: The title + function _html_col_title() + { + $this->_html_coltmpl_text("title", C_("Title:")); + } + + // _html_col_tri_address: The address set: country, city, street + function _html_col_tri_address() + { + if (getlang(LN_COUNTRY_FIRST)) { + $this->_html_col_country(); + $this->_html_col_city(); + $this->_html_col_street(); + } else { + $this->_html_col_street(); + $this->_html_col_city(); + $this->_html_col_country(); + } + } + + // _html_col_value: The preference value + function _html_col_value() + { + $this->_html_coltmpl_text("value", C_("Value:")); + } + + // _html_col_visits: The visit count + function _html_col_visits() + { + $this->_html_coltmpl_ro("visits", C_("Visits:")); + } + + // _html_col_visited: The last-visited time + function _html_col_visited() + { + $this->_html_coltmpl_ro_datetime("visited", C_("Visited:")); + } + + // _html_col_updated: The The last-update time + function _html_col_updated() + { + $this->_html_coltmpl_ro_datetime("updated", C_("Updated:")); + } + + // _html_col_updatedby: The last maintainer + function _html_col_updatedby() + { + $this->_html_coltmpl_ro_user("updatedby", C_("Updated by:")); + } + + // _html_col_url: The URL. + function _html_col_url() + { + $this->_html_coltmpl_url("url", C_("URL.:")); + } + + // _html_col_zip: The zip code + function _html_col_zip() + { + $this->_html_coltmpl_text("zip", C_("Zip code:"), null, 5); + } + + + ///////////////////////// + // Private utility methods. Do not call them directly. + ///////////////////////// + // _cval_text: Output a current text value + function _cval_text($col) + { + echo is_null($this->_cur[$col])? h_abbr(t_none()): + h($this->_cur[$col]); + } + + // _cval_textarea: Output a current textarea value + function _cval_textarea($col) + { + echo is_null($this->_cur[$col])? h_abbr(t_none()): + a2html($this->_cur[$col]); + } + + // _val_text: Output a value + function _val_text($col, $maxcol = null) + { + if (!is_null($maxcol)) { + echo " maxlength=\"" . h($this->_maxlens[$maxcol]) . "\""; + } + if (array_key_exists($col, $this->_form)) { + echo " value=\"" . h($this->_form[$col]) . "\""; + } else { + echo " value=\"\""; + } + } + + // _val_scalar: Output a scalar value + function _val_scalar($val, $maxcol = null) + { + if (!is_null($maxcol)) { + echo " maxlength=\"" . h($this->_maxlens[$maxcol]) . "\""; + } + if (!is_null($val)) { + echo " value=\"" . h($val) . "\""; + } else { + echo " value=\"\""; + } + } + + // _val_date: Output a date value + function _val_date($col, $maxcol = null) + { + if (!is_null($maxcol)) { + echo " maxlength=\"" . h($this->_maxlens[$maxcol]) . "\""; + } + if (array_key_exists($col, $this->_form)) { + $val = $this->_form[$col]; + if (is_numeric($val)) { + $val = date("Y-m-d", $val); + } + echo " value=\"" . h($val) . "\""; + } else { + echo " value=\"\""; + } + } + + // _val_textarea: Output a value as a textarea content + function _val_textarea($col, $default) + { + echo array_key_exists($col, $this->_form) && $this->_form[$col] != ""? + h($this->_form[$col]): h($default); + } + + // _val_check: Output a value as a checkbox check value + function _val_check($col) + { + if (array_key_exists($col, $this->_form) && $this->_form[$col]) { + echo " checked=\"checked\""; + } + } + + // _val_radio: Output a value as a radio check value + function _val_radio($col, $valhere, $is_default = false) + { + // Value set, checked when same value + if (array_key_exists($col, $this->_form)) { + echo " value=\"" . h($valhere) . "\""; + if ($this->_form[$col] == $valhere) { + echo " checked=\"checked\""; + } + // Value not set, checked when default + } else { + echo " value=\"" . h($valhere) . "\""; + if ($is_default) { + echo " checked=\"checked\""; + } + } + } + + // _form: Return a specific form value, or null if not exists + function _form($col) + { + if (array_key_exists($col, $this->_form)) { + return $this->_form[$col]; + } + return null; + } + + // _colspan: Output the colspan phrase + function _colspan($addcols = 0) + { + $colspan = $this->_colspan + $addcols; + // Only output for many columns + if ($colspan > 1) { + ?> colspan=""_colspan + $addcols; + $colspan += ($this->_type == "cur")? 2: 1; + // Only output for many columns + if ($colspan > 1) { + ?> colspan=""_markcols) || is_null($this->_mark)) { + return; + } + if (in_array($col, $this->_markcols)) { + echo $this->_mark; + } + return; + } + + // _delcolcount: Obtain the number of items of a column for the deletion form + function _delcolcount($col) + { + // None-deletion form -- return 0 since the number of items is unknown + if ($this->_type != "del") { + return 0; + } + // Deletion form -- return the number of items + return $this->_cur[$col . "count"]; + } +} + +// _Form_MetaCols: Manage and output the meta form information +class _Form_MetaCols +{ + protected $_cols = array(); + + // add: Add a column + function add($type, $name, $value) + { + $this->_cols[] = array( + "type" => $type, + "name" => $name, + "value" => $value, + ); + return; + } + + // out: Output the columns + function out() + { + // Bounce for nothing + if (count($this->_cols) == 0) { + return; + } + $cols = $this->_cols; + // Output the first column + $col = array_shift($cols); +?>_out_attrs($col); ?> />_out_attrs($col); ?> />\""; + } else { + $attrs[] = "value=\"" . h($col["value"]) . "\""; + } + return join(" ", $attrs); + } +} + +// UserForm: Display a user form +class UserForm extends BaseForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + if (!array_key_exists("type", $args)) { + $args["type"] = form_type(); + } + if (!array_key_exists("table", $args)) { + $args["table"] = "users"; + } + if (!array_key_exists("deltext", $args)) { + $args["deltext"] = C_("Delete this user account"); + } + if (!array_key_exists("summary", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["summary"] = C_("This table provides you a form to add a new user account."); + break; + // A form to edit a current item + case "cur": + $args["summary"] = C_("This table provides you a form to update a current user account."); + break; + // A form to delete a current item + case "del": + $args["summary"] = C_("This table provides you a form to delete a user account."); + break; + } + } + if (!array_key_exists("cols", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["cols"] = array("id", "passwd", "name", + "disabled", "supgroup"); + break; + // A form to edit a current item + case "cur": + // A form to delete a current item + case "del": + $args["cols"] = array("sn", "id", "passwd", "name", + "disabled", "supgroup", + "admin", "lang", "visits", "visited", "ip", "host", "ct", + "fails", + "created", "createdby", "updated", "updatedby"); + break; + } + } + if (!array_key_exists("title", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["title"] = C_("Add a New User Account"); + break; + // A form to edit a current item + case "cur": + $args["title"] = C_("Update a Current User Account"); + break; + // A form to delete a current item + case "del": + $args["title"] = C_("Delete a User Account"); + break; + } + } + if (!array_key_exists("https", $args)) { + $args["https"] = ($args["type"] != "del"); + } + parent::__construct($status, $args); + $this->_maxlens["passwd"] = 100; + if ( $args["type"] == "cur" && !is_su() + && ($this->_cur["su"] || $this->_sn == get_login_sn())) { + $this->_nodelete = true; + if ($this->_cur["su"]) { + $this->_prefmsg[] = C_("This is a super-user. You can only change parts of her infomation."); + } + } + if ($this->_type == "cur") { + if (array_key_exists("datacount", $this->_cur) && $this->_cur["datacount"] > 0) { + $this->_nodelete = true; + $this->_prefmsg[] = dngettext(COMMONDOMAIN, + "This user has a datum. It cannot be deleted. To delete the user, its datum must first be deleted.", + "This user has data. It cannot be deleted. To delete the user, all of its data must first be deleted.", + $this->_cur["datacount"]); + } + } + // Set all the available belonging groups list + $this->_set_supgroup_list(); + } + + // _set_supgroup_list: Set all the available belonging groups list + function _set_supgroup_list() + { + // Get the list of checked groups + $checked = array(); + for ($i = 0; array_key_exists("supgroup$i" . "sn", $this->_form); $i++) { + if (array_key_exists("supgroup$i", $this->_form)) { + $checked[] = $this->_form["supgroup$i" . "sn"]; + } + } + + // Remove the old groups list + foreach (array_keys($this->_form) as $col) { + if (substr($col, 0, 8) == "supgroup") { + unset($this->_form[$col]); + } + } + + // Get the list of all groups + if (count($GLOBALS["ALL_LINGUAS"]) > 1) { + $lndb = getlang(LN_DATABASE); + if (getlang() == DEFAULT_LANG) { + $title = sql_strcat("id", "' ('", "dsc_$lndb", "')'"); + } else { + $lndbdef = ln(DEFAULT_LANG, LN_DATABASE); + $title = sql_strcat("id", "' ('", + "COALESCE(dsc_$lndb, dsc_$lndbdef)", "')'"); + } + } else { + $title = sql_strcat("id", "' ('", "dsc", "')'"); + } + $select = "SELECT sn AS sn, $title AS title FROM groups" + . " WHERE id!='" . sql_esctext(SU_GROUP) . "'" + . " AND id!='" . sql_esctext(ADMIN_GROUP) . "'" + . " AND id!='" . sql_esctext(ALLUSERS_GROUP) . "'" + . " ORDER BY id;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0; $i < $count; $i++) { + $row = sql_fetch_assoc($result); + // Set it + $this->_form["supgroup$i" . "sn"] = $row["sn"]; + $this->_form["supgroup$i" . "title"] = $row["title"]; + if (in_array($row["sn"], $checked)) { + $this->_form["supgroup$i"] = true; + } + } + return; + } + + // _html_col_admin: Is the user an administrator? + function _html_col_admin() + { + $this->_html_coltmpl_ro_bool("admin", C_("Administrator?"), + C_("Administrator"), C_("Non-administrator")); + } + + // _html_col_disabled: Disabled? + function _html_col_disabled() + { + // Read-only for a non-super-user editing herself or a super-user + if ( $this->_type == "cur" && !is_su() + && ($this->_cur["su"] || $this->_sn == get_login_sn())) { + $this->_html_coltmpl_ro_bool("disabled", C_("Disabled?"), + C_("Disabled"), C_("Enabled")); + } else { + $this->_html_coltmpl_bool("disabled", C_("Disabled?"), + C_("Disabled"), C_("Enabled"), C_("Disable this user account.")); + } + } + + // _html_col_id: The user ID. + function _html_col_id() + { + // Read-only for a non-super-user editing a super-user + if ($this->_type == "cur" && !is_su() && $this->_cur["su"]) { + $this->_html_coltmpl_ro("id", C_("User ID.:")); + } else { + $this->_html_coltmpl_text("id", C_("User ID.:")); + } + } + + // _html_col_lang: The preferred language + function _html_col_lang() + { + $this->_html_coltmpl_ro_lang("lang", C_("Pref. language:")); + } + + // _html_col_name: The user name + function _html_col_name() + { + $this->_html_coltmpl_text("name", C_("Full name:")); + } + + // _html_col_passwd: The password + function _html_col_passwd() + { + // Read-only for a non-super-user editing a super-user + if ($this->_type == "cur" && !is_su() && $this->_cur["su"]) { + $dummy = str_repeat("*", $this->_maxlens["passwd"]); +?> + + _colspan(); ?>> + +_type) { + // A form to create a new item + case "new": +?> + + _colspan(); ?>>_form("supgroup$i" . "sn")); $i++) { + ob_start(); +?>
  • _val_text("supgroup$i" . "sn"); ?> /> + _val_check("supgroup$i"); ?> /> + +
  • +
  • _val_check("su"); ?> /> +\n"; + } else { +?>
  • +\n"; + } + $items[] = ob_get_contents(); + ob_end_clean(); + } + // Attach the all-users group in any case + if (!is_null(groupsn(ALLUSERS_GROUP))) { + ob_start(); +?>
  • +\n"; + $items[] = ob_get_contents(); + ob_end_clean(); + } + echo "
      \n" . implode("", $items) . "
    \n "; + ?> + +_sn == get_login_sn()) { +?> + _mark("supgroup"); echo h_abbr(C_("Belonging to:")); ?> + _colspan(); ?>>_cur); $i++) { + $items[] = "
  • " . h($this->_cur["supgroup$i" . "title"]) . "
  • \n"; + } + if ($this->_cur["su"]) { + $items[] = "
  • " . group_opt_label(su_group_sn()) . "
  • \n"; + } + if (!is_null(groupsn(ALLUSERS_GROUP))) { + $items[] = "
  • " . group_opt_label(groupsn(ALLUSERS_GROUP)) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + + + + + _colspan(); ?>>_cur); $i++) { + $items[] = "
  • " . h($this->_cur["supgroup$i" . "title"]) . "
  • \n"; + } + if ($this->_cur["su"]) { + $items[] = "
  • " . group_opt_label(su_group_sn()) . "
  • \n"; + } + if (!is_null(groupsn(ALLUSERS_GROUP))) { + $items[] = "
  • " . group_opt_label(groupsn(ALLUSERS_GROUP)) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + + + + _colspan(); ?>>_form("supgroup$i" . "sn")); $i++) { + ob_start(); +?>
  • _val_text("supgroup$i" . "sn"); ?> /> + _val_check("supgroup$i"); ?> /> + +
  • +
  • _val_check("su"); ?> /> +\n"; + } else { +?>
  • _cur["su"]) { + ?> checked="checked" disabled="disabled" /> +\n"; + } + $items[] = ob_get_contents(); + ob_end_clean(); + } + // Attach the all-users group in any case + if (!is_null(groupsn(ALLUSERS_GROUP))) { + ob_start(); +?>
  • +\n"; + $items[] = ob_get_contents(); + ob_end_clean(); + } + echo "
      \n" . implode("", $items) . "
    \n "; + ?> + + + _mark("supgroup"); echo h_abbr(C_("Belonging to:")); ?> + _colspan(); ?>>_cur); $i++) { + $items[] = "
  • " . h($this->_cur["supgroup$i" . "title"]) . "
  • \n"; + } + if ($this->_cur["su"]) { + $items[] = "
  • " . group_opt_label(su_group_sn()) . "
  • \n"; + } + if (!is_null(groupsn(ALLUSERS_GROUP))) { + $items[] = "
  • " . group_opt_label(groupsn(ALLUSERS_GROUP)) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + +_type) { + // A form to create a new item + case "new": + // Nothing for a new form + break; + + // A form to edit a current item + case "cur": + $locked = false; + if ( defined("MAX_FAIL_LOGINS") + && MAX_FAIL_LOGINS !== false + && $this->_form("fails") >= MAX_FAIL_LOGINS) { + $locked = true; + } + if (!$locked) { +?> + _mark("fails"); echo h_abbr(C_("Fail logins:")); ?> + _colspan(); ?>>_cval_text("fails"); ?> + + + + + _colspan(); ?>>_cval_text("fails"); + echo h(C_("(Locked)")); ?> + + + + _colspan(); ?>>_val_check("failsreset"); ?> /> + + +_form("fails") >= MAX_FAIL_LOGINS) { + $locked = true; + } +?> + _mark("fails"); echo h_abbr(C_("Fail logins:")); ?> + _colspan(); ?>>_cval_text("fails"); + if ($locked) { + echo h(C_("(Locked)")); + } ?> + +_type == "cur" && !is_su() && $this->_cur["sn"] == su_group_sn()) { + $this->_nodelete = true; + $this->_prefmsg[] = C_("This is a super-user group. You can only change parts of its infomation."); + } + } + + // _html_col_id: The group ID. + function _html_col_id() + { + // Read-only for a non-super-user editing a super-user group + if ($this->_type == "cur" && !is_su() && $this->_sn == su_group_sn()) { + $this->_html_coltmpl_ro("id", C_("Group ID.:")); + } else { + $this->_html_coltmpl_text("id", C_("Group ID.:")); + } + } + + // _html_col_dsc: The description + function _html_col_dsc() + { + $this->_html_coltmpl_text("dsc", C_("Description:")); + } + + // _html_col_subuser: The child users + function _html_col_subuser() + { + $submit = C_("Add a user"); + switch ($this->_type) { + // A form to create a new item + case "new": +?> + + _colspan(); ?>>_form("subuser$i" . "sn")); $i++) { + ob_start(); + $label = user_opt_label($this->_form("subuser$i" . "sn"), "subuser$i"); + if (!is_null($label)) { +?>
  • _val_text("subuser$i" . "sn"); ?> /> + _val_check("subuser$i"); ?> /> +\n"; + } else { +?>
  • _val_text("subuser$i" . "sn"); ?> /> + +\n"; + } + $items[] = ob_get_contents(); + ob_end_clean(); + } + ob_start(); +?>
  • +\n" . implode("", $items) . " \n "; + ?> + +_sn == su_group_sn()) { +?> + _mark("subuser"); echo h_abbr(dngettext(COMMONDOMAIN, + "User member:", "User members:", $this->_cur["subusercount"])); ?> + _colspan(); ?>>_cur["subusercount"]; $i++) { + $items[] = "
  • " . h($this->_cur["subuser$i" . "title"]) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + + + + + + _colspan(); ?>>_cur["subusercount"]; $i++) { + $items[] = "
  • " . h($this->_cur["subuser$i" . "title"]) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + + + + _colspan(); ?>>_form("subuser$i" . "sn")); $i++) { + ob_start(); + $label = user_opt_label($this->_form("subuser$i" . "sn"), "subuser$i"); + if (!is_null($label)) { +?>
  • _val_text("subuser$i" . "sn"); ?> /> + _val_check("subuser$i"); ?> /> +\n"; + } else { +?>
  • _val_text("subuser$i" . "sn"); ?> /> + +\n"; + } + $items[] = ob_get_contents(); + ob_end_clean(); + } + ob_start(); +?>
  • +\n" . implode("", $items) . " \n "; + ?> + + + _mark("subuser"); echo h_abbr(dngettext(COMMONDOMAIN, + "User member:", "User members:", $this->_cur["subusercount"])); ?> + _colspan(); ?>>_cur["subusercount"]; $i++) { + $items[] = "
  • " . h($this->_cur["subuser$i" . "title"]) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + +_type) { + // A form to create a new item + case "new": +?> + + _colspan(); ?>>_form("subgroup$i" . "sn")); $i++) { + ob_start(); + $label = group_opt_label($this->_form("subgroup$i" . "sn"), "subgroup$i"); + if (!is_null($label)) { +?>
  • _val_text("subgroup$i" . "sn"); ?> /> + _val_check("subgroup$i"); ?> /> +\n"; + } else { +?>
  • _val_text("subgroup$i" . "sn"); ?> /> + +\n"; + } + $items[] = ob_get_contents(); + ob_end_clean(); + } + ob_start(); +?>
  • +\n" . implode("", $items) . " \n "; + ?> + +_sn == su_group_sn()) { +?> + _mark("subgroup"); echo h_abbr(dngettext(COMMONDOMAIN, + "Group member:", "Group members:", $this->_cur["subgroupcount"])); ?> + _colspan(); ?>>_cur["subgroupcount"]; $i++) { + $items[] = "
  • " . h($this->_cur["subgroup$i" . "title"]) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + + + + + _colspan(); ?>>_cur["subgroupcount"]; $i++) { + $items[] = "
  • " . h($this->_cur["subgroup$i" . "title"]) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + + + + _colspan(); ?>>_form("subgroup$i" . "sn")); $i++) { + ob_start(); + $label = group_opt_label($this->_form("subgroup$i" . "sn"), "subgroup$i"); + if (!is_null($label)) { +?>
  • _val_text("subgroup$i" . "sn"); ?> /> + _val_check("subgroup$i"); ?> /> +\n"; + } else { +?>
  • _val_text("subgroup$i" . "sn"); ?> /> + +\n"; + } + $items[] = ob_get_contents(); + ob_end_clean(); + } + ob_start(); +?>
  • +\n" . implode("", $items) . " \n "; + ?> + + + _mark("subgroup"); echo h_abbr(dngettext(COMMONDOMAIN, + "Group member:", "Group members:", $this->_cur["subgroupcount"])); ?> + _colspan(); ?>>_cur["subgroupcount"]; $i++) { + $items[] = "
  • " . h($this->_cur["subgroup$i" . "title"]) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + +_type) { + // A form to create a new item + case "new": +?> + + _colspan(); ?>>_form("supgroup$i" . "sn")); $i++) { + ob_start(); + $label = group_opt_label($this->_form("supgroup$i" . "sn"), "supgroup$i"); + if (!is_null($label)) { +?>
  • _val_text("supgroup$i" . "sn"); ?> /> + _val_check("supgroup$i"); ?> /> +\n"; + } else { +?>
  • _val_text("supgroup$i" . "sn"); ?> /> + +\n"; + } + $items[] = ob_get_contents(); + ob_end_clean(); + } + ob_start(); +?>
  • +\n" . implode("", $items) . " \n "; + ?> + +_sn == su_group_sn()) { +?> + _mark("supgroup"); echo h_abbr(C_("Belonging to:")); ?> + _colspan(); ?>>_cur); $i++) { + $items[] = "
  • " . h($this->_cur["supgroup$i" . "title"]) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + + + + + _colspan(); ?>>_cur); $i++) { + $items[] = "
  • " . h($this->_cur["supgroup$i" . "title"]) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + + + + _colspan(); ?>>_form("supgroup$i" . "sn")); $i++) { + ob_start(); + $label = group_opt_label($this->_form("supgroup$i" . "sn"), "supgroup$i"); + if (!is_null($label)) { +?>
  • _val_text("supgroup$i" . "sn"); ?> /> + _val_check("supgroup$i"); ?> /> +\n"; + } else { +?>
  • _val_text("supgroup$i" . "sn"); ?> /> + +\n"; + } + $items[] = ob_get_contents(); + ob_end_clean(); + } + ob_start(); +?>
  • +\n" . implode("", $items) . " \n "; + ?> + + + _mark("supgroup"); echo h_abbr(C_("Belonging to:")); ?> + _colspan(); ?>>_cur); $i++) { + $items[] = "
  • " . h($this->_cur["supgroup$i" . "title"]) . "
  • \n"; + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + +_html_coltmpl_call("member", C_("Member:"), "username"); + } +} + +// GroupMembershipForm: Display a group membership form +class GroupMembershipForm extends BaseForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + if (!array_key_exists("type", $args)) { + $args["type"] = form_type(); + } + if (!array_key_exists("table", $args)) { + $args["table"] = "groupmem"; + } + if (!array_key_exists("deltext", $args)) { + $args["deltext"] = C_("Delete this membership record"); + } + if (!array_key_exists("summary", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["summary"] = C_("This table provides you a form to add a new membership record."); + break; + // A form to edit a current item + case "cur": + $args["summary"] = C_("This table provides you a form to change a current membership record."); + break; + // A form to delete a current item + case "del": + $args["summary"] = C_("This table provides you a form to delete a membership record."); + break; + } + } + if (!array_key_exists("cols", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["cols"] = array("grp", "member"); + break; + // A form to edit a current item + case "cur": + // A form to delete a current item + case "del": + $args["cols"] = array("sn", "grp", "member", + "created", "createdby", "updated", "updatedby"); + break; + } + } + if (!array_key_exists("title", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["title"] = C_("Add a New Group Membership Record"); + break; + // A form to edit a current item + case "cur": + $args["title"] = C_("Change a Current Group Membership Record"); + break; + // A form to delete a current item + case "del": + $args["title"] = C_("Delete a Group Membership Record"); + break; + } + } + parent::__construct($status, $args); + } + + // _html_col_member: The member + function _html_col_member() + { + $this->_html_coltmpl_call("member", C_("Member:"), "groupdsc"); + } +} + +// UserPreferenceForm: Display a user preference form +class UserPreferenceForm extends BaseForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + if (!array_key_exists("type", $args)) { + $args["type"] = form_type(); + } + if (!array_key_exists("table", $args)) { + $args["table"] = "userpref"; + } + if (!array_key_exists("deltext", $args)) { + $args["deltext"] = C_("Delete this user preference"); + } + if (!array_key_exists("summary", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["summary"] = C_("This table provides you a form to add a new user preference."); + break; + // A form to edit a current item + case "cur": + $args["summary"] = C_("This table provides you a form to modify a current user preference."); + break; + // A form to delete a current item + case "del": + $args["summary"] = C_("This table provides you a form to delete a user preference."); + break; + } + } + if (!array_key_exists("cols", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["cols"] = array("usr", "domain", "name", "value"); + break; + // A form to edit a current item + case "cur": + // A form to delete a current item + case "del": + $args["cols"] = array("sn", "usr", "domain", "name", "value", + "created", "createdby", "updated", "updatedby"); + break; + } + } + if (!array_key_exists("title", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["title"] = C_("Add a New User Preference"); + break; + // A form to edit a current item + case "cur": + $args["title"] = C_("Modify a Current User Preference"); + break; + // A form to delete a current item + case "del": + $args["title"] = C_("Delete a User Preference"); + break; + } + } + parent::__construct($status, $args); + } + + // _html_col_usr: The user + function _html_col_usr() + { + $this->_html_coltmpl_call_null("usr", C_("User:"), + "everyone", C_("Everyone"), "username"); + } + + // _html_col_domain: The domain + function _html_col_domain() + { + $this->_html_coltmpl_text_null("domain", C_("Domain:"), + "everywhere", C_("Everywhere")); + } +} + +// ScriptPrivilegeForm: Display a script privilege form +class ScriptPrivilegeForm extends BaseForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + if (!array_key_exists("type", $args)) { + $args["type"] = form_type(); + } + if (!array_key_exists("table", $args)) { + $args["table"] = "scptpriv"; + } + if (!array_key_exists("deltext", $args)) { + $args["deltext"] = C_("Delete this script privilege record"); + } + if (!array_key_exists("summary", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["summary"] = C_("This table provides you a form to add a new script privilege record."); + break; + // A form to edit a current item + case "cur": + $args["summary"] = C_("This table provides you a form to change a current script privilege record."); + break; + // A form to delete a current item + case "del": + $args["summary"] = C_("This table provides you a form to delete a script privilege record."); + break; + } + } + if (!array_key_exists("cols", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["cols"] = array("script", "grp"); + break; + // A form to edit a current item + case "cur": + // A form to delete a current item + case "del": + $args["cols"] = array("sn", "script", "grp", + "created", "createdby", "updated", "updatedby"); + break; + } + } + if (!array_key_exists("title", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["title"] = C_("Add a New Script Privilege Record"); + break; + // A form to edit a current item + case "cur": + $args["title"] = C_("Change a Current Script Privilege Record"); + break; + // A form to delete a current item + case "del": + $args["title"] = C_("Delete a Script Privilege Record"); + break; + } + } + parent::__construct($status, $args); + } + + // _html_col_grp: The group + function _html_col_grp() + { + $this->_html_coltmpl_call("grp", C_("Privilege:"), "groupdsc"); + } +} + +// UserRequestForm: Display a user request form +class UserRequestForm extends BaseForm +{ + protected $_types = array(); + + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + if (!array_key_exists("type", $args)) { + $args["type"] = form_type(); + } + if (!array_key_exists("table", $args)) { + $args["table"] = "userreq"; + } + if (!array_key_exists("deltext", $args)) { + $args["deltext"] = C_("Delete this user request"); + } + if (!array_key_exists("summary", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["summary"] = C_("This table provides you a form to add a new user request."); + break; + // A form to edit a current item + case "cur": + $args["summary"] = C_("This table provides you a form to update a current user request."); + break; + // A form to delete a current item + case "del": + $args["summary"] = C_("This table provides you a form to delete a user request."); + break; + } + } + if (!array_key_exists("cols", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["cols"] = array("type", "usr", "args", "expire"); + break; + // A form to edit a current item + case "cur": + // A form to delete a current item + case "del": + $args["cols"] = array("sn", "type", "usr", "args", "expire", + "created", "createdby", "updated", "updatedby"); + break; + } + } + if (!array_key_exists("title", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["title"] = C_("Add a New User Request"); + break; + // A form to edit a current item + case "cur": + $args["title"] = C_("Update a Current User Request"); + break; + // A form to delete a current item + case "del": + $args["title"] = C_("Delete a User Request"); + break; + } + } + parent::__construct($status, $args); + $this->_types = array( + array( + "val" => "join", + "title" => C_("Join"), + ), + array( + "val" => "chgeml", + "title" => C_("Change e-mail"), + ), + array( + "val" => "rstpwd", + "title" => C_("Reset password"), + ), + ); + } + + // _html_col_expire: The expiration time + function _html_col_expire() + { + $this->_html_coltmpl_datetime("expire", C_("Expiration:")); + } + + // _html_col_type: The type + function _html_col_type() + { + $this->_html_coltmpl_radio("type", C_("Type:"), $this->_types); + } + + // _html_col_usr: The user + function _html_col_usr() + { + $this->_html_coltmpl_call_null("usr", C_("User:"), + "anonymous", C_("Anonymous"), "username"); + } + + // _html_col_args: The arguments + function _html_col_args() + { + $this->_html_coltmpl_textarea("args", C_("Arguments:"), + C_("Please fill in the request arguments list here."), null, 3); + } +} + +// BaseCategoryForm: Display a base category form +class BaseCategoryForm extends BaseForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + if (!array_key_exists("type", $args)) { + $args["type"] = form_type(); + } + if (!array_key_exists("deltext", $args)) { + $args["deltext"] = C_("Delete this category"); + } + if (!array_key_exists("summary", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["summary"] = C_("This table provides you a form to add a new category."); + break; + // A form to edit a current item + case "cur": + $args["summary"] = C_("This table provides you a form to edit a current category."); + break; + // A form to delete a current item + case "del": + $args["summary"] = C_("This table provides you a form to delete a category."); + break; + } + } + parent::__construct($status, $args); + $this->_maxlens["ord"] = 2; + if ($this->_type == "cur") { + if (array_key_exists("scatcount", $this->_cur) && $this->_cur["scatcount"] > 0) { + $this->_nodelete = true; + $this->_prefmsg[] = dngettext(COMMONDOMAIN, + "This category has a subcategory. It cannot be deleted. To delete the category, its subcategory must first be deleted.", + "This category has subcategories. It cannot be deleted. To delete the category, all of its subcategories must first be deleted.", + $this->_cur["scatcount"]); + } + } + } + + // _html_col_id: The ID. + function _html_col_id() + { + $this->_html_coltmpl_text("id", C_("ID.:"), null, 8); + } + + // _html_col_hid: Hide? + function _html_col_hid() + { + $this->_html_coltmpl_bool("hid", C_("Hide?"), + C_("Hide this category"), C_("Show this category"), C_("Hide this category currently.")); + } +} + +// BaseCategorizationForm: Display a base categorization record form +class BaseCategorizationForm extends BaseForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + if (!array_key_exists("type", $args)) { + $args["type"] = form_type(); + } + if (!array_key_exists("deltext", $args)) { + $args["deltext"] = C_("Delete this categorization record"); + } + if (!array_key_exists("summary", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["summary"] = C_("This table provides you a form to add a new categorization record."); + break; + // A form to edit a current item + case "cur": + $args["summary"] = C_("This table provides you a form to change a current categorization record."); + break; + // A form to delete a current item + case "del": + $args["summary"] = C_("This table provides you a form to delete a categorization record."); + break; + } + } + parent::__construct($status, $args); + } +} + +// LinkCategoryForm: Display a link category form +class LinkCategoryForm extends BaseCategoryForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + if (!array_key_exists("type", $args)) { + $args["type"] = form_type(); + } + if (!array_key_exists("table", $args)) { + $args["table"] = "linkcat"; + } + if (!array_key_exists("cols", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["cols"] = array("parent", "id", "ord", + "title", "kw", "hid"); + break; + // A form to edit a current item + case "cur": + // A form to delete a current item + case "del": + $args["cols"] = array("sn", "parent", "id", "ord", + "title", "kw", "hid", + "scats", "links", + "created", "createdby", "updated", "updatedby"); + break; + } + } + if (!array_key_exists("title", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["title"] = C_("Add a New Link Category"); + break; + // A form to edit a current item + case "cur": + $args["title"] = C_("Edit a Current Link Category"); + break; + // A form to delete a current item + case "del": + $args["title"] = C_("Delete a Link Category"); + break; + } + } + parent::__construct($status, $args); + $this->_maxlens["ord"] = 2; + if ($this->_type == "cur") { + if (array_key_exists("linkcount", $this->_cur) && $this->_cur["linkcount"] > 0) { + $this->_nodelete = true; + $this->_prefmsg[] = dngettext(COMMONDOMAIN, + "This category has a link. It cannot be deleted. To delete the category, its link must first be deleted.", + "This category has links. It cannot be deleted. To delete the category, all of its links must first be deleted.", + $this->_cur["linkcount"]); + } + } + } + + // _html_col_links: The links + function _html_col_links() + { +?> + _type != "cur") { + ?> class="th"_type == "cur") { + ?> colspan="2" scope="row">_mark("links"); echo h_abbr(dngettext(COMMONDOMAIN, + "Link:", "Links:", $this->_cur["linkcount"])); ?> + _colspan(); ?>>_cur["linkcount"]; $i++) { + $items[] = sprintf("
  • %2\$s\n" + . " (%3\$s)\n" + . "
  • \n", + h("links.php?form=cur&sn=" . $this->_cur["link$i" . "sn"]), + h($this->_cur["link$i" . "title"]), + h($this->_cur["link$i" . "url"])); + } + if (count($items) > 0) { + echo "
      \n" . implode("", $items) . "
    \n "; + } else { + echo h_abbr(t_none()); + } ?> + +_html_coltmpl_bool("hid", C_("Hide?"), + C_("Hide this link"), C_("Show this page"), C_("Hide this related link currently.")); + } + + // _html_col_cats: The categories + function _html_col_cats() + { + $this->_html_coltmpl_select_multi("cat", + dngettext(COMMONDOMAIN, "Category:", "Categories:", $this->_delcolcount("cat")), + "linkcat_options"); + } +} + +// LinkCategorizationForm: Display a link categorization record form +class LinkCategorizationForm extends BaseCategorizationForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + if (!array_key_exists("type", $args)) { + $args["type"] = form_type(); + } + if (!array_key_exists("table", $args)) { + $args["table"] = "linkcatz"; + } + if (!array_key_exists("cols", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["cols"] = array("cat", "link"); + break; + // A form to edit a current item + case "cur": + // A form to delete a current item + case "del": + $args["cols"] = array("sn", "cat", "link", + "created", "createdby", "updated", "updatedby"); + break; + } + } + if (!array_key_exists("title", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["title"] = C_("Add a New Link Categorization Record"); + break; + // A form to edit a current item + case "cur": + $args["title"] = C_("Change a Current Link Categorization Record"); + break; + // A form to delete a current item + case "del": + $args["title"] = C_("Delete a Link Categorization Record"); + break; + } + } + parent::__construct($status, $args); + } + + // _html_col_cat: The category + function _html_col_cat() + { + $this->_html_coltmpl_select("cat", C_("Category:"), + "linkcat_options", "linkcat_title"); + } + + // _html_col_link: The link + function _html_col_link() + { + $this->_html_coltmpl_call("link", C_("Link:"), "link_title"); + } +} + +// PageForm: Display a page form +class PageForm extends BaseForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + if (!array_key_exists("type", $args)) { + $args["type"] = form_type(); + } + if (!array_key_exists("table", $args)) { + $args["table"] = "pages"; + } + if (!array_key_exists("isupload", $args)) { + $args["isupload"] = true; + } + if (!array_key_exists("deltext", $args)) { + $args["deltext"] = C_("Delete this page"); + } + if (!array_key_exists("summary", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["summary"] = C_("This table provides you a form to write a new page."); + break; + // A form to edit a current item + case "cur": + $args["summary"] = C_("This table provides you a form to edit a current page."); + break; + // A form to delete a current item + case "del": + $args["summary"] = C_("This table provides you a form to delete a page."); + break; + } + } + if (!array_key_exists("cols", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["cols"] = array("path", "ord", "title", + "body", "kw", "pic", "html", "hid"); + break; + // A form to edit a current item + case "cur": + // A form to delete a current item + case "del": + $args["cols"] = array("sn", "path", "ord", "title", + "body", "kw", "pic", "html", "hid", + "created", "createdby", "updated", "updatedby"); + break; + } + } + if (!array_key_exists("title", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["title"] = C_("Write a New Page"); + break; + // A form to edit a current item + case "cur": + $args["title"] = C_("Edit a Current Page"); + break; + // A form to delete a current item + case "del": + $args["title"] = C_("Delete a Page"); + break; + } + } + if (!array_key_exists("preview", $args)) { + $args["preview"] = true; + } + if ($args["preview"] && !array_key_exists("prevmsg", $args)) { + $args["prevmsg"] = C_("Preview this page."); + } + parent::__construct($status, $args); + } + + // _html_col_hid: Hide? + function _html_col_hid() + { + $this->_html_coltmpl_bool("hid", C_("Hide?"), + C_("Hide this page"), C_("Show this page"), C_("Hide this page currently.")); + } +} + +// NewsForm: Display a news form +class NewsForm extends BaseForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + if (!array_key_exists("type", $args)) { + $args["type"] = form_type(); + } + if (!array_key_exists("table", $args)) { + $args["table"] = "news"; + } + if (!array_key_exists("isupload", $args)) { + $args["isupload"] = true; + } + if (!array_key_exists("deltext", $args)) { + $args["deltext"] = C_("Delete this news article"); + } + if (!array_key_exists("summary", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["summary"] = C_("This table provides you a form to write a new news article."); + break; + // A form to edit a current item + case "cur": + $args["summary"] = C_("This table provides you a form to edit a current news article."); + break; + // A form to delete a current item + case "del": + $args["summary"] = C_("This table provides you a form to delete a news article."); + break; + } + } + if (!array_key_exists("cols", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["cols"] = array("date", "title", + "body", "kw", "pic", "html", "hid"); + break; + // A form to edit a current item + case "cur": + // A form to delete a current item + case "del": + $args["cols"] = array("sn", "date", "ord", "title", + "body", "kw", "pic", "html", "hid", + "created", "createdby", "updated", "updatedby"); + break; + } + } + if (!array_key_exists("title", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["title"] = C_("Write a New News Article"); + break; + // A form to edit a current item + case "cur": + $args["title"] = C_("Edit a Current News Article"); + break; + // A form to delete a current item + case "del": + $args["title"] = C_("Delete a News Article"); + break; + } + } + if (!array_key_exists("preview", $args)) { + $args["preview"] = true; + } + if ($args["preview"] && !array_key_exists("prevmsg", $args)) { + $args["prevmsg"] = C_("Preview this news article."); + } + parent::__construct($status, $args); + } + + // _html_col_ord: The order + function _html_col_ord() + { + $this->_html_coltmpl_ro("ord", C_("Order:")); + } + + // _html_col_hid: Hide? + function _html_col_hid() + { + $this->_html_coltmpl_bool("hid", C_("Hide?"), + C_("Hide this news article"), C_("Show this news article"), C_("Hide this news article currently.")); + } +} + +// CountryForm: Display a country form +class CountryForm extends BaseForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + if (!array_key_exists("type", $args)) { + $args["type"] = form_type(); + } + if (!array_key_exists("table", $args)) { + $args["table"] = "country"; + } + if (!array_key_exists("deltext", $args)) { + $args["deltext"] = C_("Delete this country record"); + } + if (!array_key_exists("summary", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["summary"] = C_("This table provides you a form to add a new country record."); + break; + // A form to edit a current item + case "cur": + $args["summary"] = C_("This table provides you a form to edit a current country record."); + break; + // A form to delete a current item + case "del": + $args["summary"] = C_("This table provides you a form to delete a country record."); + break; + } + } + if (!array_key_exists("cols", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["cols"] = array("id", "name", "special"); + break; + // A form to edit a current item + case "cur": + // A form to delete a current item + case "del": + $args["cols"] = array("sn", "id", "name", "special", + "created", "createdby", "updated", "updatedby"); + break; + } + } + if (!array_key_exists("title", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["title"] = C_("Add a New Country Record"); + break; + // A form to edit a current item + case "cur": + $args["title"] = C_("Edit a Current Country Record"); + break; + // A form to delete a current item + case "del": + $args["title"] = C_("Delete a Country Record"); + break; + } + } + parent::__construct($status, $args); + } + + // _html_col_id: The ID. + function _html_col_id() + { + $this->_html_coltmpl_text("id", C_("ID.:"), null, 2); + } + + // _html_col_special: Special record? + function _html_col_special() + { + $this->_html_coltmpl_bool("special", C_("Special?"), + C_("A special record"), C_("A normal country"), C_("This is a special record.")); + } +} + +// PictureForm: Display a picture form +class PictureForm extends BaseForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + if (!array_key_exists("type", $args)) { + $args["type"] = form_type(); + } + if (!array_key_exists("valid_types", $args)) { + $args["valid_types"] = array("new", "cur"); + } + if (!array_key_exists("isupload", $args)) { + $args["isupload"] = true; + } + if (!array_key_exists("nodelete", $args)) { + $args["nodelete"] = true; + } + if (!array_key_exists("summary", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["summary"] = C_("This table provides you a form to add a new picture."); + break; + // A form to edit a current item + case "cur": + $args["summary"] = C_("This table provides you a form to modify a current picture."); + break; + } + } + if (!array_key_exists("cols", $args)) { + $args["cols"] = array("pic", "ratio", "uppic"); + } + if (!array_key_exists("title", $args)) { + switch ($args["type"]) { + // A form to create a new item + case "new": + $args["title"] = C_("Upload a New Picture"); + break; + // A form to edit a current item + case "cur": + $args["title"] = C_("Modify a Current Picture"); + break; + } + } + parent::__construct($status, $args); + $this->_maxlens["ratio"] = 4; + } + + // _html_col_pic: The picture preview + function _html_col_pic() + { + // Obtain the picture deposit + $PICS =& pic_deposit(); + switch ($this->_type) { + // A form to create a new item + case "new": + // No display if the picture is not submitted yet + if (is_null($this->_form("pic"))) { + return; + } +?> + _mark("pic"); echo h_abbr(C_("Picture:")); ?> + _colspan(); ?>>_form("pic"))) { + echo h_abbr(t_notset()); + } elseif (!pic_exists($this->_form("pic"))) { + ?>_val_text("pic"); ?> />_val_text("pic"); ?> /> + _form("pic")]; + $alt = C_("Picture preview"); + echopic($pic, $alt, $this->_form("ratio")); + echo " "; + } ?> + + + _mark("pic"); echo h_abbr(C_("Picture:")); ?> + + _colspan(); ?>>_cur["pic"]) + || !pic_exists($this->_cur["pic"])) { + echo h_abbr(t_na()); + } else { + $pic =& $PICS[$this->_cur["pic"]]; + echopic($pic, C_("Original picture preview"), $pic["ratio"]); + echo " "; + } ?> + + + + _colspan(); ?>>_form("pic")) + || !pic_exists($this->_form("pic"))) { + echo h_abbr(t_na()); + } else { + ?>_val_text("pic"); ?> /> + _form("pic")]; + echopic($pic, C_("New picture preview"), + $this->_form("ratio")); + echo " "; + } ?> + +_form("ratio"))) { + if (is_numeric($this->_form["ratio"])) { + $this->_form["ratio_input"] = number_format($this->_form["ratio"], 2); + } else { + $this->_form["ratio_input"] = $this->_form["ratio"]; + } + } + switch ($this->_type) { + // A form to create a new item + case "new": + // No display if the picture is not submitted yet + if ( is_null($this->_form("pic")) + && is_null($this->_form("ratio"))) { + return; + } +?> + + _colspan(); + ?>>_val_text("ratio_input", "ratio"); ?> /> + + + + + _colspan(); ?>>_cval_text("ratio_input"); ?> + + + + _colspan(); + ?>>_val_text("ratio_input", "ratio"); ?> /> + +_type) { + // A form to create a new item + case "new": +?> + + _colspan(); + ?>> type="file" name="uppic" size="40" /> + + + + + _colspan(); + ?>> type="file" name="uppic" size="40" /> + + null, + "value" => C_("Log in"), + ), + ); + } + if (!array_key_exists("auto_referer2", $args)) { + $args["auto_referer2"] = false; + } + parent::__construct($status, $args); + } + + // _html_col_id: The user ID. + function _html_col_id() + { + if ($this->_is_first_form) { + // Set the remember me value + if (array_key_exists(REMEMBER_COOKIE, $_COOKIE)) { + $id = decrypt($_COOKIE[REMEMBER_COOKIE]); + if (!is_null($id)) { + $this->_form["id"] = $id; + } + } + } + $this->_html_coltmpl_text("id", C_("User ID.:"), null, 20); + } + + // _html_col_passwd: The password + function _html_col_passwd() + { +?> + + _colspan(); + ?>>_val_scalar(null, "passwd"); ?> /> + +_is_first_form) { + // Set the remember me value + if (array_key_exists(REMEMBER_COOKIE, $_COOKIE)) { + $this->_form["remember"] = true; + } + } + $this->_html_coltmpl_act_bool("remember", C_("Remember me.")); + } +} + +// RebuildForm: Display a rebuild form +class RebuildForm extends BaseForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + // This is always a rebuild form + if (!array_key_exists("type", $args)) { + $args["type"] = "new"; + } + if (!array_key_exists("type_to_pass", $args)) { + $args["type_to_pass"] = null; + } + if (!array_key_exists("valid_types", $args)) { + $args["valid_types"] = array("new"); + } + if (!array_key_exists("cols", $args)) { + $args["cols"] = array("type"); + } + if (!array_key_exists("title", $args)) { + $args["title"] = C_("Rebuild the Pages"); + } + if (!array_key_exists("header_buttons", $args)) { + $args["header_buttons"] = array(); + } + if (!array_key_exists("footer_buttons", $args)) { + $args["footer_buttons"] = array( + array( + "name" => "confirm", + "value" => C_("Confirm"), + ), + array( + "name" => "cancel", + "value" => C_("Cancel"), + ), + ); + } + if (!array_key_exists("auto_referer2", $args)) { + $args["auto_referer2"] = false; + } + parent::__construct($status, $args); + } + + // _html_col_type: The page type + function _html_col_type() + { + $this->_html_coltmpl_select("type", C_("Type:"), + "rebuildtype_options", null); + } +} + +// LogOutForm: Display a log out form +class LogOutForm extends BaseForm +{ + // __construct: Initialize the form + function __construct($status = null, $args = null) + { + if (is_null($args)) { + $args = array(); + } + // This is always a rebuild form + if (!array_key_exists("type", $args)) { + $args["type"] = "new"; + } + if (!array_key_exists("type_to_pass", $args)) { + $args["type_to_pass"] = null; + } + if (!array_key_exists("valid_types", $args)) { + $args["valid_types"] = array("new"); + } + if (!array_key_exists("title", $args)) { + $args["title"] = C_("Log Out"); + } + if (!array_key_exists("header_buttons", $args)) { + $args["header_buttons"] = array(); + } + if (!array_key_exists("footer_buttons", $args)) { + $args["footer_buttons"] = array( + array( + "name" => "confirm", + "value" => C_("Log out"), + ), + array( + "name" => "cancel", + "value" => C_("Cancel"), + ), + ); + } + if (!array_key_exists("show_table", $args)) { + $args["show_table"] = false; + } + if (!array_key_exists("prefmsg", $args)) { + $args["prefmsg"] = array(); + } + $args["prefmsg"][] = C_("Are you sure you want to log out?"); + parent::__construct($status, $args); + } +} + +?> diff --git a/lib/php/monica/formfunc.inc.php b/lib/php/monica/formfunc.inc.php new file mode 100644 index 0000000..8b4837b --- /dev/null +++ b/lib/php/monica/formfunc.inc.php @@ -0,0 +1,155 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/callform.inc.php"; +require_once "monica/cgiemu.inc.php"; + +// get_or_post: whether the form data came from $_GET or $_POST +function &get_or_post() +{ + if ($_SERVER["REQUEST_METHOD"] == "POST") { + return $_POST; + } else { + return $_GET; + } +} + +// curform: Obtain the current form, either from the sent form or +// from the suspended form +function &curform() +{ + $FORM =& get_or_post(); + if ( defined("USE_SUSPEND_FORM") && USE_SUSPEND_FORM && + array_key_exists("formid", $FORM)) { + $FORM =& retrieve_form(); + } + return $FORM; +} + +// is_form: If a form is requested +function is_form($isform = null) +{ + // Cache the result + static $cache; + // Use "isform" to alter the cache + if (!is_null($isform)) { + // A status is provided + if (is_array($isform)) { + if (array_key_exists("isform", $isform)) { + $cache = $isform["isform"]; + settype($cache, "boolean"); + } + // A scalar value + } else { + $cache = $isform; + settype($cache, "boolean"); + } + } + // Return the cache + if (isset($cache)) { + return $cache; + } + + // Obtain the current form + $FORM =& curform(); + // No valid form infomation + if (!array_key_exists("form", $FORM)) { + $cache = false; + return $cache; + } + // "isform" was specified + $status =& retrieve_status(); + if (is_array($status) && array_key_exists("isform", $status)) { + $cache = $status["isform"]; + return $cache; + } + // Yes, we need a form here + $cache = true; + return $cache; +} + +// form_type: Return the form name (new, cur, del, listpref... etc) +function form_type($type = null) +{ + // Cache the result + static $cache; + // Set the form type + if (!is_null($type)) { + $cache = $type; + } + // Return the cache + if (isset($cache)) { + return $cache; + } + + // Obtain the current form + $FORM =& curform(); + // Form type specified in arguments + if (array_key_exists("form", $FORM)) { + $cache = $FORM["form"]; + + // No form source is found + } else { + $cache = null; + } + return $cache; +} + +// form_step: Return the form step number +function form_step($step = null) +{ + // Cache the result + static $cache; + // Set the form step + if (!is_null($step)) { + $cache = $step; + } + // Return the cache + if (isset($cache)) { + return $cache; + } + + // Obtain the current form + $FORM =& curform(); + // Form type specified in arguments + if (array_key_exists("step", $FORM)) { + $cache = $FORM["step"]; + // No form source is found + } else { + $cache = 1; + } + // Steps that are not sane are considered as 1 + if (!is_int($cache)) { + // Text strings may be convertable + if (is_string($cache)) { + if (preg_match("/^\d+$/", $cache)) { + // Convert its type to integer + settype($cache, "integer"); + } else { + $cache = 1; + } + // Others are not convertable + } else { + $cache = 1; + } + } + // "nextstep" specified + $status =& retrieve_status(); + if ( is_array($status) + && array_key_exists("nextstep", $status) + && $status["nextstep"]) { + $cache++; + } + return $cache; +} + +?> diff --git a/lib/php/monica/formreg.inc.php b/lib/php/monica/formreg.inc.php new file mode 100644 index 0000000..ab396d2 --- /dev/null +++ b/lib/php/monica/formreg.inc.php @@ -0,0 +1,37 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Settings +$_FORMREG = array(); + +// register_form: Register a form +function register_form($form, $path) +{ + global $_FORMREG; + // The counter + static $n = 0; + // Define the form + if (!defined($form)) { + // Find the next index that is not used + while (array_key_exists($n, $_FORMREG)) { + $n++; + } + define($form, $n); + } + $_FORMREG[$n] = $path; + return; +} + +// get_registered_form: Get a registered form +function get_registered_form($form) +{ + global $_FORMREG; + return array_key_exists($form, $_FORMREG)? + $_FORMREG[$form]: null; +} + +?> diff --git a/lib/php/monica/gb2312.inc.php b/lib/php/monica/gb2312.inc.php new file mode 100644 index 0000000..857beb6 --- /dev/null +++ b/lib/php/monica/gb2312.inc.php @@ -0,0 +1,134 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// 編碼規則: +// 區號值: 1-94 +// 位號值: 1-94 +// 字碼: 最高位元1 + (區號值+0x20(32)), 最高位元1 + (位號值+0x20(32)) +// 符號: 1-9區 +// 一級字: 16-55區(常用漢字) +// 二級字: 56-87區(次常用漢字) +// 空白區: 10-16區, 87-94區 + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/xfileio.inc.php"; + +// Settings +define("_GB2312_VAR", "/tmp/gb2312.var"); +$_GB2312 = null; + +// init_gb2312: Initialize the GB2312 characters array +function init_gb2312() +{ + global $_GB2312; + // Already initialized + if (!is_null($_GB2312)) { + return; + } + // Initialize from the existing table + if (file_exists(_GB2312_VAR)) { + eval(xfread(_GB2312_VAR)); + return; + } + // Initialize the characters + $_GB2312 = array( + // 符號 + "睫瘍" => _gb2312_gen_chars(1, 9), + // 一級字 + "珨撰趼" => _gb2312_gen_chars(16, 55), + // 二級字 + "媼撰趼" => _gb2312_gen_chars(56, 87), + ); + + // Save the result + $string = "\$_GB2312 = " . var_export($_GB2312, true) . ";\n"; + xfupdate(_GB2312_VAR, $string); + return; +} + +// _gb2312_gen_chars: Generate a range of GB2312 characters +function _gb2312_gen_chars($start, $end) +{ + $chars = array(); + for ($sec = $start, $pos = 1; $sec <= $end; ) { + $code = ((($sec+0x20)|0x80) << 8) | (($pos+0x20)|0x80); + $chars[] = pack("n", $code); + // Next character + $pos++; + // Carry 進位 + if ($pos > 94) { + $pos = 1; + $sec++; + } + // 不用的符號 + if ($sec == 2 && $pos == 1) { // 02,01-02,16 + $pos = 17; + } elseif ($sec == 2 && $pos == 67) { // 02,67-02,68 + $pos = 69; + } elseif ($sec == 2 && $pos == 79) { // 02,79-02,80 + $pos = 81; + } elseif ($sec == 2 && $pos == 93) { // 02,93-02,94 + $pos = 1; + $sec++; + } elseif ($sec == 4 && $pos == 84) { // 04,84-04,94 + $pos = 1; + $sec++; + } elseif ($sec == 5 && $pos == 87) { // 05,87-05,94 + $pos = 1; + $sec++; + } elseif ($sec == 6 && $pos == 25) { // 06,25-06,32 + $pos = 33; + } elseif ($sec == 6 && $pos == 57) { // 06,57-06,94 + $pos = 1; + $sec++; + } elseif ($sec == 7 && $pos == 34) { // 07,34-07,48 + $pos = 49; + } elseif ($sec == 7 && $pos == 82) { // 07,82-07,94 + $pos = 1; + $sec++; + } elseif ($sec == 8 && $pos == 27) { // 08,27-08,36 + $pos = 37; + } elseif ($sec == 8 && $pos == 74) { // 08,74-09,03 + $pos = 4; + $sec++; + } elseif ($sec == 9 && $pos == 80) { // 09,80-09,94 + break; + } + // 不用的一級字 + if ($sec == 55 && $pos == 90) { + break; + } + } + return $chars; +} + +// gb2312_punc_chars: Return the GB2312 punctuation characters +function gb2312_punc_chars() +{ + init_gb2312(); + return $GLOBALS["_GB2312"]["符號"]; +} + +// gb2312_feq_chars: Return the GB2312 frequently-used characters +function gb2312_feq_chars() +{ + init_gb2312(); + return $GLOBALS["_GB2312"]["一級字"]; +} + +// gb2312_nonfeq_chars: Return the GB2312 non-frequently-used characters +function gb2312_nonfeq_chars() +{ + init_gb2312(); + return $GLOBALS["_GB2312"]["二級字"]; +} + +?> diff --git a/lib/php/monica/geoip.inc.php b/lib/php/monica/geoip.inc.php new file mode 100644 index 0000000..df53c22 --- /dev/null +++ b/lib/php/monica/geoip.inc.php @@ -0,0 +1,49 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "GeoIP/geoip.inc"; +require_once "monica/cgiemu.inc.php"; +require_once "monica/ipv4addr.inc.php"; + +// Settings +define("GEOIP_DAT", "/usr/share/GeoIP/GeoIP.dat"); +define("GEOIP_CT_PRIVATE_NETWORK", "AA"); + +// geoiplookup: Query GeoIP for an IP +function geoiplookup($ip = null) +{ + // Default to the client address + if (is_null($ip)) { + $ip = $_SERVER["REMOTE_ADDR"]; + } + // Cache the handler + static $gi; + if (!isset($gi)) { + $gi = geoip_open(GEOIP_DAT, GEOIP_STANDARD); + } + // Look up in the GeoIP database + $ct = geoip_country_code_by_addr($gi, $ip); + if ($ct != "") { + return $ct; + } + // Check if it is in a private network + if ( ipv4_in_network("127.0.0.1/8", $ip) + || ipv4_in_network("10.0.0.0/8", $ip) + || ipv4_in_network("172.16.0.0/12", $ip) + || ipv4_in_network("192.168.0.0/16", $ip)) { + return GEOIP_CT_PRIVATE_NETWORK; + } + // Not found at all + return null; +} + +?> diff --git a/lib/php/monica/getlang.inc.php b/lib/php/monica/getlang.inc.php new file mode 100644 index 0000000..4edb4c1 --- /dev/null +++ b/lib/php/monica/getlang.inc.php @@ -0,0 +1,435 @@ + +// Copyright: Copyright (C) 2002-2010 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/cgiemu.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/requri.inc.php"; + +// getlang: Get the appropriate language from the user-agent. +// Input: type: the type of language information to be returned +// See lninfo.inc.php for the most current list of available types. +// LN_NAME: Language name +// LN_CHARSET: It's suggested character set +// LN_FILENAME: It's proper format as part of a file name +// LN_LOCALE: It's locale +// LN_DATABASE: It's proper format as part of a database field name +// LN_HTMLID: It's proper format as part of an HTML ID. +// LN_SPACE_BREAK: If this language break lines at spaces +// LN_IGNORE_CASE: If case can be ignored (can safely do strlower() and strupper()) +// LN_COUNTRY_FIRST: If country should be listed first in a mail address +// LN_DESC: It's long description, in English +// LN_DESC_CURLC: It's long description in the current language (UTF-8) +// LN_DESC_SELFLC: It's long description in its own language (UTF-8) +function getlang($type = null) +{ + $lang = _getlang_getlang(); + // Return in the proper data type + return !is_null($type)? ln($lang, $type): $lang; +} + +// getcharset: Get the appropriate character set from the user-agent. +function getcharset() +{ + static $charset; + // Obtained before + if (isset($charset)) { + return $charset; + } + + // Default character set of this language + $default = getlang(LN_CHARSET); + // Obtain all the available character sets + $all_charsets = _getlang_all_charsets(); + + // We have no choice + if (count($all_charsets) < 2) { + $charset = $all_charsets[0]; + return $charset; + } + // Parse the character set by the Accept-Charset header + $charset = _getlang_getcs_accept(); + if (!is_null($charset)) { + return $charset; + } + // Cannot parse - return the default + $lang = $default; + return $lang; +} + +// _getlang_getlang: The real subroutine +function _getlang_getlang() +{ + static $lang; + // Obtained before + if (isset($lang)) { + return $lang; + } + + // Default fallback settings + if (!array_key_exists("ALL_LINGUAS", $GLOBALS)) { + $GLOBALS["ALL_LINGUAS"] = array("en"); + } + global $ALL_LINGUAS; + if (!defined("DEFAULT_LANG")) { + define("DEFAULT_LANG", "en"); + } + + // Uni-lingual + if (count($ALL_LINGUAS) == 1) { + $lang = $ALL_LINGUAS[0]; + return $lang; + } + // Check the file name for specified language + // No setting environment in this case + $lang = _getlang_getlang_filename(); + if (!is_null($lang)) { + return $lang; + } + // Methods below should set the language in the environment + // Check the environment for specified language + $lang = _getlang_getlang_env(); + if (!is_null($lang)) { + _getlang_getlang_setenv($lang); + return $lang; + } + // Parse the language by the Accept-Language header + $lang = _getlang_getlang_accept(); + if (!is_null($lang)) { + _getlang_getlang_setenv($lang); + return $lang; + } + // Parse the language by the console locale + $lang = _getlang_getlang_locale(); + if (!is_null($lang)) { + _getlang_getlang_setenv($lang); + return $lang; + } + // Cannot parse - return the default + $lang = DEFAULT_LANG; + _getlang_getlang_setenv($lang); + return $lang; +} + +// _getlang_getlang_filename: Check the file name for specified language +function _getlang_getlang_filename() +{ + global $ALL_LINGUAS; + // Check the file name format + if (!preg_match("/\.([^\.\/]+)\.[^\.\/]+$/", REQUEST_PATH, $m)) { + return null; + } + $langfile = $m[1]; + // Check each language for its file name format + for ($l = 0, $map = array(); $l < count($ALL_LINGUAS); $l++) { + $lang = $ALL_LINGUAS[$l]; + if ($langfile == ln($lang, LN_FILENAME)) { + return $lang; + } + } + // Not found + return null; +} + +// _getlang_getlang_env: Check the environment for specified language +function _getlang_getlang_env() +{ + global $ALL_LINGUAS; + // Check the query string + if ( array_key_exists("lang", $_GET) + && in_array($_GET["lang"], $ALL_LINGUAS)) { + return $_GET["lang"]; + // Check the POSTed form + } elseif ( array_key_exists("lang", $_POST) + && in_array($_POST["lang"], $ALL_LINGUAS)) { + return $_POST["lang"]; + // Check the cookies + } elseif ( array_key_exists("lang", $_COOKIE) + && in_array($_COOKIE["lang"], $ALL_LINGUAS)) { + return $_COOKIE["lang"]; + // Check the session + } elseif ( isset($_SESSION) + && array_key_exists("lang", $_SESSION) + && in_array($_SESSION["lang"], $ALL_LINGUAS)) { + return $_SESSION["lang"]; + } + // Not set + return null; +} + +// _getlang_getlang_accept: Parse the language by the Accept-Language header +// Refer to HTTP/1.1 section 14.4 for this algorism +function _getlang_getlang_accept() +{ + // Accept-Language not set + if (!array_key_exists("HTTP_ACCEPT_LANGUAGE", $_SERVER)) { + return null; + } + global $ALL_LINGUAS; + + // Split into language ranges + $rngs = preg_split("/\s*,\s*/", trim($_SERVER["HTTP_ACCEPT_LANGUAGE"])); + $rngqf = array(); // User Assigned quality factor + foreach ($rngs as $range) { + // Split into attributes + $attrs = preg_split("/\s*;\s*/", trim($range)); + // First piece is the language range + $ln = array_shift($attrs); + // Lower-case it + $ln = strtolower($ln); + // Find the quality factor + foreach ($attrs as $attr) { + // A numeric quality factor found + if (strtolower(substr($attr, 0, 2)) == "q=" + && is_numeric(substr($attr, 2))) { + $rngqf[$ln] = substr($attr, 2) + 0; + } + } + // Default quality factor to 1 + if (!array_key_exists($ln, $rngqf)) { + $rngqf[$ln] = 1; + } + } + // The default quality factor + if (array_key_exists("*", $rngqf)) { + $defqf = $rngqf["*"]; + unset($rngqf["*"]); + } else { + $defqf = 0; + } + + // Language tags (what we have) + $tagqf = array(); // Calculated quality factor + for ($l = 0; $l < count($ALL_LINGUAS); $l++) { + $ln = $ALL_LINGUAS[$l]; + // Language tag, as specified in ISO + $tag = ln($ln, LN_NAME); + unset($match); // Matched range of the quality factor + // Language ranges (what the user sent to match us) + foreach (array_keys($rngqf) as $range) { + // Exactly match or match a prefix + if ( $tag == $range + || substr($tag, 0, strlen($range)+1) == "$range-") { + // Not matched yet + if (!isset($match)) { + $tagqf[$ln] = $rngqf[$range]; // Quality Factor + $match = $range; // Record the matched range + // A longer match range + } elseif (strlen($range) > strlen($match)) { + $tagqf[$ln] = $rngqf[$range]; // Quality Factor + $match = $range; // Record the matched range + } + } + } + // Not matched - apply a default quality factor + if (!array_key_exists($ln, $tagqf)) { + $tagqf[$ln] = $defqf; + } + } + + // Drop unacceptable languages + foreach (array_keys($tagqf) as $ln) { + if ($tagqf[$ln] <= 0) { + unset($tagqf[$ln]); + } + } + // Nothing acceptable + if (count($tagqf) == 0) { + return null; + } + + // Sort by the quality factor + $GLOBALS["_GETLANG_TAGQF"] =& $tagqf; + $GLOBALS["_GETLANG_DEFAULT"] = DEFAULT_LANG; + $ln = array_keys($tagqf); + usort($ln, "_getlang_cmp_tagqf"); + unset($GLOBALS["_GETLANG_TAGQF"]); + unset($GLOBALS["_GETLANG_DEFAULT"]); + // A preferred match + return $ln[0]; +} + +// _getlang_getlang_locale: Parse the language by the console locale +function _getlang_getlang_locale() +{ + // Only work on console + if (IS_CGI) { + return null; + } + // Check these environment variables in order + // See http://www.gnu.org/software/libc/manual/html_node/Using-gettextized-software.html + $envs = array("LANGUAGE", "LC_ALL", "LC_MESSAGES", "LANG"); + for ($i = 0, $lang = null; $i < count($envs); $i++) { + $locale = getenv($envs[$i]); + // Obtain the first valid one and discard the rest + if ($locale !== false && $locale != "") { + $lang = $locale; + break; + } + } + // No locale setting was found + if (is_null($lang)) { + return null; + } + // Remove the character set + $lang = preg_replace("/\..*$/", "", $lang); + // Lower-case it + $lang = strtolower($lang); + // Replace underscore with dash + $lang = str_replace("_", "-", $lang); + // en-us is en + if ($lang == "en-us") { + $lang = "en"; + } + // Not in our available languages list + if (!in_array($lang, $GLOBALS["ALL_LINGUAS"])) { + return null; + } + // Return it + return $lang; +} + +// _getlang_getlang_setenv: Set the language in the environment +function _getlang_getlang_setenv($lang) +{ + // Set the session variable + if ( isset($_SESSION) + && (!array_key_exists("lang", $_SESSION) + || $_SESSION["lang"] != $lang)) { + $_SESSION["lang"] = $lang; + } + // Set the cookie + if ( (!array_key_exists("lang", $_COOKIE) + || $_COOKIE["lang"] != $lang) + && !headers_sent()) { + setcookie("lang", $lang, time() + 86400 * 365, "/"); + } + return; +} + +// _getlang_getcs_accept: Parse the character set by the Accept-Charset header +// Refer to HTTP/1.1 section 14.2 for this algorism +function _getlang_getcs_accept() +{ + // Accept-Charset not set + if (!array_key_exists("HTTP_ACCEPT_CHARSET", $_SERVER)) { + return null; + } + // Obtain all the available character sets + $all_charsets = _getlang_all_charsets(); + + // Split into character set ranges + $rngs = preg_split("/\s*,\s*/", trim($_SERVER["HTTP_ACCEPT_CHARSET"])); + $rngqf = array(); // User Assigned quality factor + foreach ($rngs as $range) { + // Split into attributes + $attrs = preg_split("/\s*;\s*/", trim($range)); + // First piece is the character set range + $cs = array_shift($attrs); + // Lower-case it + $cs = strtolower($cs); + // Find the quality factor + foreach ($attrs as $attr) { + // A numeric quality factor found + if (strtolower(substr($attr, 0, 2)) == "q=" + && is_numeric(substr($attr, 2))) { + $rngqf[$cs] = substr($attr, 2) + 0; + } + } + // Default quality factor to 1 + if (!array_key_exists($cs, $rngqf)) { + $rngqf[$cs] = 1; + } + } + // The default quality factor + if (array_key_exists("*", $rngqf)) { + $defqf = $rngqf["*"]; + unset($rngqf["*"]); + } else { + // Default ISO-8859-1 to 1 + if (!array_key_exists("iso-8859-1", $rngqf)) { + $rngqf["iso-8859-1"] = 1; + } + $defqf = 0; + } + $tagqf = array(); // Calculated quality factor + // Character set tags (what we have) + for ($l = 0; $l < count($all_charsets); $l++) { + $cs = $all_charsets[$l]; + $tag = strtolower($cs); + // Character set ranges (what the user sent to match us) + foreach (array_keys($rngqf) as $range) { + // Matched + if ($tag == $range) { + $tagqf[$cs] = $rngqf[$range]; // Quality Factor + } + } + // Not matched - apply a default quality factor + if (!array_key_exists($cs, $tagqf)) { + $tagqf[$cs] = $defqf; + } + } + + // Drop unacceptable languages + foreach (array_keys($tagqf) as $cs) { + if ($tagqf[$cs] <= 0) { + unset($tagqf[$cs]); + } + } + // Nothing acceptable + if (count($tagqf) == 0) { + return null; + } + + // Sort by the quality factor + $GLOBALS["_GETLANG_TAGQF"] =& $tagqf; + $GLOBALS["_GETLANG_DEFAULT"] = getlang(LN_CHARSET); + $cs = array_keys($tagqf); + usort($cs, "_getlang_cmp_tagqf"); + unset($GLOBALS["_GETLANG_TAGQF"]); + unset($GLOBALS["_GETLANG_DEFAULT"]); + // A preferred match + return $cs[0]; +} + +// _getlang_all_charsets: Obtain all the available character sets +// Available character sets are the default character set of this +// language, and UTF-8 +function _getlang_all_charsets() +{ + static $charsets; + if (isset($charsets)) { + return $charsets; + } + $charsets = array(); + $charsets[] = getlang(LN_CHARSET); + $charsets[] = "UTF-8"; + $charsets = array_values(array_unique($charsets)); + return $charsets; +} + +// _getlang_cmp_tagqf: Compare the quality factor of the tags +function _getlang_cmp_tagqf($a, $b) +{ + global $_GETLANG_TAGQF, $_GETLANG_DEFAULT; + if ($_GETLANG_TAGQF[$a] != $_GETLANG_TAGQF[$b]) { + return $_GETLANG_TAGQF[$b] < $_GETLANG_TAGQF[$a]? -1: 1; + } + if ($a == $_GETLANG_DEFAULT) { + return -1; + } + if ($b == $_GETLANG_DEFAULT) { + return 1; + } + return 0; +} + +?> diff --git a/lib/php/monica/gettext.inc.php b/lib/php/monica/gettext.inc.php new file mode 100644 index 0000000..4aefcd1 --- /dev/null +++ b/lib/php/monica/gettext.inc.php @@ -0,0 +1,58 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Referenced subroutines +require_once "monica/requri.inc.php"; + +// Settings +if (!defined("COMMONDOMAIN")) { + define("COMMONDOMAIN", "monica"); +} +if (!defined("COMMONLOCALEDIR")) { + define("COMMONLOCALEDIR", dirname(dirname(dirname(dirname(__FILE__)))) . "/locale"); +} +if (!defined("LOCALEDIR")) { + define("LOCALEDIR", DOC_ROOT . "/admin/locale"); +} + +// _: gettext implementation +if (!function_exists("_")) { +function _($a) +{ + return $a; +} +} +// C_: shortcut to dgettext(COMMONDOMAIN, text) +function C_($a) +{ + return dgettext(COMMONDOMAIN, $a); +} + +// N_: null gettext implementation +if (!function_exists("N_")) { +function N_($a) +{ + return $a; +} +} +// Nn_: null plural gettext implementation +function Nn_($as, $ap, $n) +{ + return array($as, $ap, $n); +} +// NC_: null gettext implementation of dgettext(COMMONDOMAIN, text) +function NC_($a) +{ + return array(COMMONDOMAIN, $a); +} +// NCn_: null plural gettext implementation of dngettext(COMMONDOMAIN, singular, plural, number) +function NCn_($as, $ap, $n) +{ + return array(COMMONDOMAIN, $as, $ap, $n); +} + +?> diff --git a/lib/php/monica/guest.inc.php b/lib/php/monica/guest.inc.php new file mode 100644 index 0000000..6dca050 --- /dev/null +++ b/lib/php/monica/guest.inc.php @@ -0,0 +1,161 @@ + +// Copyright: Copyright (C) 2001-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/actlog.inc.php"; +require_once "monica/chkpriv.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/mkalldir.inc.php"; +require_once "monica/pagefunc.inc.php"; +require_once "monica/rmalldir.inc.php"; +require_once "monica/rmofile.inc.php"; +require_once "monica/runcmd.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/xfileio.inc.php"; + +// Constant symbols +if (!defined("GUEST_GROUP")) { + define("GUEST_GROUP", "guests"); +} + +// is_guest: If the user is a guest (by the user id) +function is_guest($user = null) +{ + // Cache the result + static $cache = array(); + // Default to the current logged-in user + if (is_null($user) || $user == get_login_sn()) { + return !is_su() && in_array(GUEST_GROUP, get_login_groups()); + } + // Return the cache + if (array_key_exists($user, $cache)) { + return $cache[$user]; + } + // Super user is never a guest + if (is_su($user)) { + $cache[$user] = false; + return false; + } + // Obtain the groups + $groups = user_parent_groups($user); + $cache[$user] = in_array(GUEST_GROUP, $groups); + return $cache[$user]; +} + +// gunlink: unlink() if the user is not a guest +function gunlink($file) +{ + if (!is_guest()) { + unlink($file); + } +} + +// gcopy: copy() if the user is not a guest +function gcopy($src, $dst) +{ + if (!is_guest()) { + copy($src, $dst); + } +} + +// gactlog: actlog() if the user is not a guest +function gactlog($msg, $user = null) +{ + if (!is_guest()) { + actlog($msg, $user); + } +} + +// gsql_query: sql_query() if the user is not a guest +function gsql_query($query) +{ + if (!is_guest()) { + sql_query($query); + } +} + +// gmkalldir: mkalldir() if the user is not a guest +function gmkalldir($dir) +{ + if (!is_guest()) { + mkalldir($dir); + } +} + +// grmalldir: rmalldir() if the user is not a guest +function grmalldir($dir) +{ + if (!is_guest()) { + rmalldir($dir); + } +} + +// grmoldpage: rmoldpage() if the user is not a guest +function grmoldpage($old, $new = null) +{ + if (!is_guest()) { + rmoldpage($old, $new); + } +} + +// grmoldfile: rmoldfile() if the user is not a guest +function grmoldfile($old, $new = null) +{ + if (!is_guest()) { + rmoldfile($old, $new); + } +} + +// goutpage: outpage() if the user is not a guest +function goutpage($html, $path, $lang = null) +{ + if (!is_guest()) { + outpage($html, $path, $lang); + } +} + +// gxfwrite: xfwrite() if the user is not a guest +function gxfwrite($dest, $content) +{ + if (!is_guest()) { + xfwrite($dest, $content); + } +} + +// gxfupdate: xfupdate() if the user is not a guest +function gxfupdate($file, $newcontent) +{ + if (!is_guest()) { + xfupdate($file, $newcontent); + } +} + +// gruncmd: runcmd() if the user is not a guest +function gruncmd($cmd, $stdin, &$stdout, &$stderr) +{ + if (!is_guest()) { + return runcmd($cmd, $stdin, $stdout, $stderr); + } else { + return 0; + } +} + +// gxruncmd: xruncmd() if the user is not a guest +function gxruncmd($cmd, $stdin) +{ + if (!is_guest()) { + return xruncmd($cmd, $stdin); + } else { + return ""; + } +} + +?> diff --git a/lib/php/monica/hires.inc.php b/lib/php/monica/hires.inc.php new file mode 100644 index 0000000..255fbd5 --- /dev/null +++ b/lib/php/monica/hires.inc.php @@ -0,0 +1,14 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// time_hires: Get a high resulution time +function time_hires() +{ + return array_sum(explode(" ", microtime())); +} + +?> diff --git a/lib/php/monica/html401.inc.php b/lib/php/monica/html401.inc.php new file mode 100644 index 0000000..e855b39 --- /dev/null +++ b/lib/php/monica/html401.inc.php @@ -0,0 +1,12 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + + +// ID or NAME. Section 6.2. +define("HTML401_ID", "[A-Za-z][A-Za-z\\d\\-_:\\.]*"); + +?> diff --git a/lib/php/monica/htmlchar.inc.php b/lib/php/monica/htmlchar.inc.php new file mode 100644 index 0000000..b9a9d09 --- /dev/null +++ b/lib/php/monica/htmlchar.inc.php @@ -0,0 +1,24 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// h: Shortcut to htmlspecialchars() +function h($a) +{ + return htmlspecialchars($a); +} + +// dh: Reverse htmlspecialchars() +function dh($a) +{ + $a = str_replace("<", "<", $a); + $a = str_replace(">", ">", $a); + $a = str_replace(""", "\"", $a); + $a = str_replace("&", "&", $a); + return $a; +} + +?> diff --git a/lib/php/monica/http.inc.php b/lib/php/monica/http.inc.php new file mode 100644 index 0000000..2b5719c --- /dev/null +++ b/lib/php/monica/http.inc.php @@ -0,0 +1,1130 @@ + +// Copyright: Copyright (C) 2001-2008 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/a2html.inc.php"; +require_once "monica/addget.inc.php"; +require_once "monica/cgiemu.inc.php"; +require_once "monica/chkpriv.inc.php"; +require_once "monica/curtime.inc.php"; +require_once "monica/altlang.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/geoip.inc.php"; +require_once "monica/hires.inc.php"; +require_once "monica/htmlchar.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/mail.inc.php"; +require_once "monica/page2rel.inc.php"; +require_once "monica/pagefunc.inc.php"; +require_once "monica/rel2abs.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/unicode.inc.php"; + +// Settings +$_HTTP_ERROR_TYPES = array ( + E_ERROR => "Error", + E_WARNING => "Warning", + E_PARSE => "Parsing Error", + E_NOTICE => "Notice", + E_CORE_ERROR => "Core Error", + E_CORE_WARNING => "Core Warning", + E_COMPILE_ERROR => "Compile Error", + E_COMPILE_WARNING => "Compile Warning", + E_USER_ERROR => "User Error", + E_USER_WARNING => "User Warning", + E_USER_NOTICE => "User Notice", + E_STRICT => "Runtime Notice", + E_RECOVERABLE_ERROR => "Catchable Fatal Error", +); + +// http_204: HTTP 204 No Content +function http_204() +{ + // Stop and clean the previous output buffering + if (!defined("LAST_OB_LEVEL")) { + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "")? 0: 1); + } + while (ob_get_level() > LAST_OB_LEVEL) { + ob_end_clean(); + } + // Output the status message + header("HTTP/1.1 204 No Content"); + header("Content-Length: 0"); + // Client cache + if (array_key_exists("LAST_MODIFIED", $GLOBALS)) { + if (!is_null(get_login_sn())) { + header("Cache-Control: private"); + } else { + header("Cache-Control: public"); + } + header("Last-Modified: " . date("r", $GLOBALS["LAST_MODIFIED"])); + } else { + header("Cache-Control: no-cache"); + } + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + // No need to return + exit; +} + +// http_301: HTTP 301 Moved Permanently +function http_301($url) +{ + // Stop and clean the previous output buffering + if (!defined("LAST_OB_LEVEL")) { + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "")? 0: 1); + } + while (ob_get_level() > LAST_OB_LEVEL) { + ob_end_clean(); + } + $url = rel2abs($url); + $url = _http_uri_add_sid($url); + + // Obtain the status message + $html = _http_get_custom_status_message(301); + if (is_null($html)) { + ob_start(); +?> + + + + +301 Moved Permanently + + +

    301 Moved Permanently

    +

    You should refer to the new location.

    + + 1 + && $_SERVER["REQUEST_METHOD"] != "POST" + && $_SERVER["REQUEST_METHOD"] != "PUT" + && !array_key_exists("lang", $_GET)) { + header("Content-Location: " . rel2abs(altlang(getlang(), page_param()))); + header("Vary: accept-language,cookie"); + } + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + // No need to return + exit; +} + +// http_303: HTTP 303 See Others +function http_303($url) +{ + // Stop and clean the previous output buffering + if (!defined("LAST_OB_LEVEL")) { + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "")? 0: 1); + } + while (ob_get_level() > LAST_OB_LEVEL) { + ob_end_clean(); + } + $url = rel2abs($url); + $url = _http_uri_add_sid($url); + + // Obtain the status message + $html = _http_get_custom_status_message(303); + if (is_null($html)) { + ob_start(); +?> + + + + +303 See Others + + +

    303 See Others

    +

    Please follow this location.

    + + 1 + && $_SERVER["REQUEST_METHOD"] != "POST" + && $_SERVER["REQUEST_METHOD"] != "PUT" + && !array_key_exists("lang", $_GET)) { + header("Content-Location: " . rel2abs(altlang(getlang(), page_param()))); + header("Vary: accept-language,cookie"); + } + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + // No need to return + exit; +} + +// http_304: HTTP 304 Not Modified +function http_304() +{ + // Stop and clean the previous output buffering + if (!defined("LAST_OB_LEVEL")) { + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "")? 0: 1); + } + while (ob_get_level() > LAST_OB_LEVEL) { + ob_end_clean(); + } + // Output the status message + // See HTTP/1.1 sec 10.3.5 for appropriate headers to send + header("HTTP/1.1 304 Not Modified"); + // We must send them + if (count($GLOBALS["ALL_LINGUAS"]) > 1) { + header("Content-Location: " . rel2abs(altlang(getlang(), page_param()))); + } + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + // No need to return + exit; +} + +// http_307: HTTP 307 Temporary Redirect +function http_307($url) +{ + // Stop and clean the previous output buffering + if (!defined("LAST_OB_LEVEL")) { + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "")? 0: 1); + } + while (ob_get_level() > LAST_OB_LEVEL) { + ob_end_clean(); + } + $url = rel2abs($url); + $url = _http_uri_add_sid($url); + + // Obtain the status message + $html = _http_get_custom_status_message(307); + if (is_null($html)) { + ob_start(); +?> + + + + +307 Temporary Redirect + + +

    307 Temporary Redirect

    +

    Please refer to the following location.

    + + 1 + && $_SERVER["REQUEST_METHOD"] != "POST" + && $_SERVER["REQUEST_METHOD"] != "PUT" + && !array_key_exists("lang", $_GET)) { + header("Content-Location: " . rel2abs(altlang(getlang(), page_param()))); + header("Vary: accept-language,cookie"); + } + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + // No need to return + exit; +} + +// http_400: HTTP 400 Bad Request +// False to disable error page output +function http_400($errmsg = null) +{ + // Stop and clean the previous output buffering + if (!defined("LAST_OB_LEVEL")) { + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "")? 0: 1); + } + while (ob_get_level() > LAST_OB_LEVEL) { + ob_end_clean(); + } + + // No error page output + if ($errmsg === false) { + $html = ""; + } else { + // Obtain the status message + $html = _http_get_custom_status_message(400); + if (is_null($html)) { + ob_start(); +?> + + + + +400 Bad Request + + +

    400 Bad Request

    + +

    Sorry, there is some error in your request.

    + +", is_null($errmsg)? "": h(C_($errmsg)), $html); + // Convert the URLs to relative + $html = page2rel($html, REQUEST_PATH); + // Encode the e-mail at-signs (@) + $html = str_replace("@", "@", $html); + // Decode the e-mail at-signs (@) of spamtrap + $html = str_replace("spamtrap@", "spamtrap@", $html); + // Convert to the desired character set + $html = page_encode($html); + } + + // Output the status message + header("HTTP/1.1 400 Bad Request"); + header("Content-Language: " . getlang()); + header("Content-Length: " . strlen($html)); + // Content negotiation, see HTTP/1.1 section 13.6 + if ( count($GLOBALS["ALL_LINGUAS"]) > 1 + && $_SERVER["REQUEST_METHOD"] != "POST" + && $_SERVER["REQUEST_METHOD"] != "PUT" + && !array_key_exists("lang", $_GET)) { + header("Content-Location: " . rel2abs(altlang(getlang(), page_param()))); + header("Vary: accept-language,cookie"); + } + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + + // Log the error message to the server error log + if (is_null($errmsg)) { + error_log("Bad Request: " . REQUEST_URI); + } elseif ($errmsg === false) { + $request = $_SERVER["REQUEST_METHOD"] . " " + . $_SERVER["REQUEST_URI"] . " " . $_SERVER["SERVER_PROTOCOL"]; + error_log("Invalid URI in request $request"); + } else { + error_log("Bad Request: " . REQUEST_URI . ": " . $errmsg); + } + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + // No need to return + exit; +} + +// http_403: HTTP 403 Forbidden +function http_403($errmsg = null) +{ + // Stop and clean the previous output buffering + if (!defined("LAST_OB_LEVEL")) { + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "")? 0: 1); + } + while (ob_get_level() > LAST_OB_LEVEL) { + ob_end_clean(); + } + + // No error page output + if ($errmsg === false) { + $html = ""; + } else { + // Obtain the status message + $html = _http_get_custom_status_message(403); + if (is_null($html)) { + ob_start(); +?> + + + + +403 Forbidden + + +

    403 Forbidden

    + +

    You are not allowed to enter here.

    + +", is_null($errmsg)? "": h(C_($errmsg)), $html); + // Convert the URLs to relative + $html = page2rel($html, REQUEST_PATH); + // Encode the e-mail at-signs (@) + $html = str_replace("@", "@", $html); + // Decode the e-mail at-signs (@) of spamtrap + $html = str_replace("spamtrap@", "spamtrap@", $html); + // Convert to the desired character set + $html = page_encode($html); + } + + // Output the status message + header("HTTP/1.1 403 Forbidden"); + header("Content-Language: " . getlang()); + header("Content-Length: " . strlen($html)); + // Content negotiation, see HTTP/1.1 section 13.6 + if ( count($GLOBALS["ALL_LINGUAS"]) > 1 + && $_SERVER["REQUEST_METHOD"] != "POST" + && $_SERVER["REQUEST_METHOD"] != "PUT" + && !array_key_exists("lang", $_GET)) { + header("Content-Location: " . rel2abs(altlang(getlang(), page_param()))); + header("Vary: accept-language,cookie"); + } + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + + // Log the error message to the server error log + if (is_null($errmsg)) { + error_log("Forbidden: " . REQUEST_URI); + } else { + error_log("Forbidden: " . REQUEST_URI . ": " . $errmsg); + } + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + // No need to return + exit; +} + +// http_404: HTTP 404 Not Found +function http_404() +{ + // Stop and clean the previous output buffering + if (!defined("LAST_OB_LEVEL")) { + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "")? 0: 1); + } + while (ob_get_level() > LAST_OB_LEVEL) { + ob_end_clean(); + } + + // Obtain the status message + $html = _http_get_custom_status_message(404); + if (is_null($html)) { + ob_start(); +?> + + + + +404 Not Found + + +

    404 Not Found

    +

    The document you requested was not found.

    + + 1 + && $_SERVER["REQUEST_METHOD"] != "POST" + && $_SERVER["REQUEST_METHOD"] != "PUT" + && !array_key_exists("lang", $_GET)) { + header("Content-Location: " . rel2abs(altlang(getlang(), page_param()))); + header("Vary: accept-language,cookie"); + } + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + + // Log the error message to the server error log + error_log("File does not exist: " . REQUEST_URI); + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + // No need to return + exit; +} + +// http_405: HTTP 405 Method Not Allowed +function http_405($allowed) +{ + // Stop and clean the previous output buffering + if (!defined("LAST_OB_LEVEL")) { + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "")? 0: 1); + } + while (ob_get_level() > LAST_OB_LEVEL) { + ob_end_clean(); + } + $allowed = implode(", ", $allowed); + + // Obtain the status message + $html = _http_get_custom_status_message(405); + if (is_null($html)) { + ob_start(); +?> + + + + +405 Method Not Allowed + + +

    405 Method Not Allowed

    +

    You should use the following methods: $allowed.

    + + 1 + && $_SERVER["REQUEST_METHOD"] != "POST" + && $_SERVER["REQUEST_METHOD"] != "PUT" + && !array_key_exists("lang", $_GET)) { + header("Content-Location: " . rel2abs(altlang(getlang(), page_param()))); + header("Vary: accept-language,cookie"); + } + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + + // Log the error message to the server error log + error_log("Method not allowed (" . $_SERVER["REQUEST_METHOD"] . "): " . REQUEST_URI); + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + // No need to return + exit; +} + +// http_410: HTTP 410 Gone +function http_410() +{ + // Stop and clean the previous output buffering + if (!defined("LAST_OB_LEVEL")) { + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "")? 0: 1); + } + while (ob_get_level() > LAST_OB_LEVEL) { + ob_end_clean(); + } + + // Obtain the status message + $html = _http_get_custom_status_message(410); + if (is_null($html)) { + ob_start(); +?> + + + + +410 Gone + + +

    410 Gone

    +

    Sorry, this page is removed permanently, and there is no forwarding address available. Please remove your bookmarks, and stop referring to this page any more. Thanks.

    + + 1 + && $_SERVER["REQUEST_METHOD"] != "POST" + && $_SERVER["REQUEST_METHOD"] != "PUT" + && !array_key_exists("lang", $_GET)) { + header("Content-Location: " . rel2abs(altlang(getlang(), page_param()))); + header("Vary: accept-language,cookie"); + } + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + + // Log error message into server error log + error_log("Gone: " . REQUEST_URI); + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + // No need to return + exit; +} + +// http_413: HTTP 413 Request Entity Too Large +function http_413() +{ + // Stop and clean the previous output buffering + if (!defined("LAST_OB_LEVEL")) { + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "")? 0: 1); + } + while (ob_get_level() > LAST_OB_LEVEL) { + ob_end_clean(); + } + + // Obtain the status message + $html = _http_get_custom_status_message(413); + if (is_null($html)) { + ob_start(); +?> + + + + +413 Request Entity Too Large + + +

    413 Request Entity Too Large

    +

    The server refuses to process your large submitted data.

    + + 1 + && $_SERVER["REQUEST_METHOD"] != "POST" + && $_SERVER["REQUEST_METHOD"] != "PUT" + && !array_key_exists("lang", $_GET)) { + header("Content-Location: " . rel2abs(altlang(getlang(), page_param()))); + header("Vary: accept-language,cookie"); + } + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + + // Log error message into server error log + error_log("Request Entity Too Large: " . REQUEST_URI); + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + // No need to return + exit; +} + +// http_500: HTTP 500 Internal Server Error +function http_500($errmsg) +{ + // Do not call the error handler recursively + if (defined("_HTTP_HTTP_500_IN_PROGRESS")) { + return; + } + define("_HTTP_HTTP_500_IN_PROGRESS", true); + + // Find out our context + $trace = debug_backtrace(); + // Obtain the caller information + for ($i = 0, $callers = array(); $i < count($trace); $i++) { + if (!array_key_exists("file", $trace[$i]) || !array_key_exists("line", $trace[$i])) { + continue; + } + $callers[] = $trace[$i]; + } + + // Stop and clean the previous output buffering + if (!defined("LAST_OB_LEVEL")) { + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "")? 0: 1); + } + while (ob_get_level() > LAST_OB_LEVEL) { + ob_end_clean(); + } + + // Get the environment infomation needed for error reporting + // Get the request information + $request = array(); + foreach (array_keys($_SERVER) as $name) { + if (substr($name, 0, 5) == "HTTP_") { + $name1 = substr($name, 5); + $name1 = strtolower($name1); + $name1 = str_replace("_", " ", $name1); + $name1 = ucwords($name1); + $name1 = str_replace(" ", "-", $name1); + $request[$name1] = $_SERVER[$name]; + } + } + if (!array_key_exists("Referer", $request)) { + $request["Referer"] = "(not set)"; + } + if (!array_key_exists("Accept-Language", $request)) { + $request["Accept-Language"] = "(not set)"; + } + if (!array_key_exists("User-Agent", $request)) { + $request["User-Agent"] = "(not set)"; + } + + // Mail the error message to the webmaster + if (!defined("MAIL_ERROR") || MAIL_ERROR) { + // Get the webmaster address to notify to + if (defined("WEBMASTER")) { + $webmaster = WEBMASTER; + } elseif (array_key_exists("SERVER_ADMIN", $_SERVER)) { + $webmaster = $_SERVER["SERVER_ADMIN"]; + } else { + $webmaster = "webmaster@" . $_SERVER["SERVER_NAME"]; + } + // Get the site name + $site = (defined("SITENAME_ABBR")? SITENAME_ABBR: + (defined("PACKAGE")? PACKAGE: + REQUEST_HOST)); + + $body = ""; + // Basic information + ob_start(); +?>[%s] HTTP 500 Server Error Report %s +============================== +* Time: %s +* URI: %s +* Request: %s %s %s +* Error Message: + +%s +%s. + +from("monica-http500@" . $_SERVER["SERVER_NAME"], "$site Website"); + $mail->to($webmaster, "$site Webmaster"); + $mail->subject(sprintf("[%s] HTTP 500 Server Error Report %s", $site, TODAY)); + $mail->body($body); + $mail->send(); + } + + // Obtain the status message + $html = _http_get_custom_status_message(500); + if (is_null($html)) { + ob_start(); +?> + + + + +500 Internal Server Error + + +

    500 Internal Server Error

    + + + +" . h($callers[$i]["file"]) . "
    line " . h($callers[$i]["line"]); + } + $html = str_replace("", "
    \n" . a2html($errmsg) . "
    \n" . implode("
    \n", $trace) . ".\n
    ", $html); + } else { + $html = str_replace("", "", $html); + } + // Convert the URLs to relative + $html = page2rel($html, REQUEST_PATH); + // Encode the e-mail at-signs (@) + $html = str_replace("@", "@", $html); + // Decode the e-mail at-signs (@) of spamtrap + $html = str_replace("spamtrap@", "spamtrap@", $html); + // Convert to the desired character set + $html = page_encode($html); + + // Output the status message + header("HTTP/1.1 500 Internal Server Error"); + header("Content-Language: " . getlang()); + header("Content-Length: " . strlen($html)); + // Content negotiation, see HTTP/1.1 section 13.6 + if ( count($GLOBALS["ALL_LINGUAS"]) > 1 + && $_SERVER["REQUEST_METHOD"] != "POST" + && $_SERVER["REQUEST_METHOD"] != "PUT" + && !array_key_exists("lang", $_GET)) { + header("Content-Location: " . rel2abs(altlang(getlang(), page_param()))); + header("Vary: accept-language,cookie"); + } + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + + // Log the error message to the server error log + for ($i = 0, $trace = array(); $i < count($callers); $i++) { + $trace[] = "at " . $callers[$i]["file"] . " line " . $callers[$i]["line"]; + } + error_log("$errmsg " . implode(" ", $trace) . "."); + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + // No need to return + exit; +} + +// http_503: HTTP 503 Service Unavailable +function http_503($errmsg = null) +{ + // Stop and clean the previous output buffering + if (!defined("LAST_OB_LEVEL")) { + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "")? 0: 1); + } + while (ob_get_level() > LAST_OB_LEVEL) { + ob_end_clean(); + } + + // Obtain the status message + $html = _http_get_custom_status_message(503); + if (is_null($html)) { + ob_start(); +?> + + + + +503 Service Unavailable + + +

    503 Service Unavailable

    + +

    Sorry, our service is currently not available. Please come back later.

    + +", is_null($errmsg)? "": h($errmsg), $html); + // Convert the URLs to relative + $html = page2rel($html, REQUEST_PATH); + // Encode the e-mail at-signs (@) + $html = str_replace("@", "@", $html); + // Decode the e-mail at-signs (@) of spamtrap + $html = str_replace("spamtrap@", "spamtrap@", $html); + // Convert to the desired character set + $html = page_encode($html); + + // Output the status message + header("HTTP/1.1 503 Service Unavailable"); + header("Content-Language: " . getlang()); + header("Content-Length: " . strlen($html)); + // Content negotiation, see HTTP/1.1 section 13.6 + if ( count($GLOBALS["ALL_LINGUAS"]) > 1 + && $_SERVER["REQUEST_METHOD"] != "POST" + && $_SERVER["REQUEST_METHOD"] != "PUT" + && !array_key_exists("lang", $_GET)) { + header("Content-Location: " . rel2abs(altlang(getlang(), page_param()))); + header("Vary: accept-language,cookie"); + } + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + + // Log the error message to the server error log + // No logging due to maintainance + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + // No need to return + exit; +} + +// http500_error_handler: Standard error handler for Monica +function http500_error_handler($no, $message, $file, $line, $context) +{ + $prefix = $no; + if (array_key_exists($no, $GLOBALS["_HTTP_ERROR_TYPES"])) { + $prefix .= " " . $GLOBALS["_HTTP_ERROR_TYPES"][$no]; + } + http_500("$prefix: $message"); + return; +} + +// _http_need_302: Is this browser capable of HTTP 303 and HTTP 307? +// Currently only older Netscape without Gecko (version <= 4.xx) +// is known of this problem. +// Return: +// false: Standard behavior to send HTTP 303 or 307. +// true: Browser lacks the capability of redirecting +// HTTP 303 and 307. Send HTTP 302 instead. +function _http_need_302() +{ + // Unable to identify User-Agent, default to the standard behavior. + if (!array_key_exists("HTTP_USER_AGENT", $_SERVER)) { + return false; + } + + $ua = $_SERVER["HTTP_USER_AGENT"]; + // Mozilla/Netscape series + if (preg_match("/^Mozilla\//", $ua)) { + // True Mozilla/Netscape + if (stristr($ua, "compatible") === false) { + // Netscape without Gecko (version <= 4.xx) + if (stristr($ua, "Gecko") === false) { + return true; + } + // Mozilla/Netscape with Gecko + return false; + } + // Netscape compatible + return false; + } + // Others + return false; +} + +// _http_uri_add_sid: Add session ID into an URI +function _http_uri_add_sid($url) +{ + // No session + if (!isset($_SESSION)) { + return $url; + } + // Session ID already set in the cookies + if (array_key_exists(session_name(), $_COOKIE)) { + return $url; + } + + // Add the session ID to the GET argument list + return add_get_arg($url, session_name(), session_id()); +} + +// _http_get_custom_status_message: Obtain the custom status message +function _http_get_custom_status_message($status) +{ + $langfile = getlang(LN_FILENAME); + unset($file); + if (is_file(DOC_ROOT . "/$langfile/errors/$status.html.xhtml")) { + $file = "/%s/errors/$status.html.xhtml"; + } elseif (is_file(DOC_ROOT . "/$langfile/errors/$status.html")) { + $file = "/%s/errors/$status.html"; + } elseif (is_file(DOC_ROOT . "/errors/$status.html.xhtml")) { + $file = "/errors/$status.html.xhtml"; + } elseif (is_file(DOC_ROOT . "/errors/$status.html")) { + $file = "/errors/$status.html"; + } + // Not found + if (!isset($file)) { + return null; + } + + $html = readpage($file); + if (is_null($html)) { + return null; + } + $charset = h(getlang(LN_CHARSET)); + $html = preg_replace("/(?<=\bencoding=\")$charset(?=\")/", "", $html); + $html = preg_replace("/(?<=\bcontent=\"text\/html; charset=)$charset(?=\")/", "", $html); + $html = preg_replace("/(?<=\bcontent=\"application\/xhtml\+xml; charset=)$charset(?=\")/", "", $html); + $html = preg_replace("/(?<=\btype=\"hidden\" name=\"charset\" value=\")$charset(?=\" \/>)/", "", $html); + $html = preg_replace("/(?<=\baccept-charset=\")$charset(?=\")/", "", $html); + return $html; +} + +?> diff --git a/lib/php/monica/https.inc.php b/lib/php/monica/https.inc.php new file mode 100644 index 0000000..7716f62 --- /dev/null +++ b/lib/php/monica/https.inc.php @@ -0,0 +1,79 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/cgiemu.inc.php"; +require_once "monica/server.inc.php"; + +// https_host: The default HTTPs host name +function https_host() +{ + // Respect the pre-defined setting + if (defined("HTTPS_HOST")) { + return HTTPS_HOST; + } + + // Use the fully-qualified domain name (FQDN) + define("HTTPS_HOST", fqdn()); + return HTTPS_HOST; +} + +// fqdn: The fully qualified domain name +function fqdn() +{ + // Cache the result + static $cache; + // Return the cache + if (isset($cache)) { + return $cache; + } + + // Use DNS look-up for the current host name + // Apaches implementation + if (is_apache()) { + $addr = $_SERVER["SERVER_ADDR"]; + // Microsoft IIS implementation + } elseif (is_iis()) { + $addr = $_SERVER["LOCAL_ADDR"]; + // Else, do DNS query + } else { + $addr = gethostbyname($_SERVER["SERVER_NAME"]); + } + // Reverse-DNS query for a fully-qualified domain name (FQDN) + $cache = gethostbyaddr($addr); + + return $cache; +} + +// is_https: Check if current scheme is HTTPS +function is_https() +{ + // Cache the result + static $cache; + // Return the cache + if (isset($cache)) { + return $cache; + } + // Apache implementation + if (is_apache()) { + $cache = array_key_exists("HTTPS", $_SERVER); + // Microsoft IIS implementation + } elseif (is_iis()) { + $cache = array_key_exists("SERVER_PORT_SECURE", $_SERVER); + // Well, set port 443 to https and others to http. + // This is a bad approach. Avoid it whenever possible. + } else { + $cache = ($_SERVER["SERVER_PORT"] == 443); + } + return $cache; +} + +?> diff --git a/lib/php/monica/incpath.inc.php b/lib/php/monica/incpath.inc.php new file mode 100644 index 0000000..a9a5e4b --- /dev/null +++ b/lib/php/monica/incpath.inc.php @@ -0,0 +1,31 @@ + +// Copyright: Copyright (C) 2007 Pristine Communications + +// This file is to be included by Monica core files before +// including other Monica core files + +// Set the include path +_incpath_set_include_path(); +define("INCPATH_SET", true); + +// _incpath_set_include_path: Set the include path +function _incpath_set_include_path() +{ + $oldpath = get_include_path(); + $paths = explode(PATH_SEPARATOR, $oldpath); + $dir = dirname(dirname(__FILE__)); + if (!in_array($dir, $paths)) { + $paths[] = $dir; + } + $newpath = implode(PATH_SEPARATOR, $paths); + if ($newpath != $oldpath) { + set_include_path(implode(PATH_SEPARATOR, $paths)); + } + return; +} + +?> diff --git a/lib/php/monica/init.inc.php b/lib/php/monica/init.inc.php new file mode 100644 index 0000000..e2d1f99 --- /dev/null +++ b/lib/php/monica/init.inc.php @@ -0,0 +1,667 @@ + +// Copyright: Copyright (C) 2002-2011 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/altlang.inc.php"; +require_once "monica/cgiemu.inc.php"; +require_once "monica/chkpriv.inc.php"; +require_once "monica/curtime.inc.php"; +require_once "monica/decform.inc.php"; +require_once "monica/errhndl.inc.php"; +require_once "monica/formfunc.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/hires.inc.php"; +require_once "monica/http.inc.php"; +require_once "monica/https.inc.php"; +require_once "monica/lastmodf.inc.php"; +require_once "monica/listpref.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/logout.inc.php"; +require_once "monica/page2rel.inc.php"; +require_once "monica/pagefunc.inc.php"; +require_once "monica/rel2abs.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/scptpriv.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/sqlconst.inc.php"; +require_once "monica/unauth.inc.php"; +require_once "monica/unicode.inc.php"; +require_once "monica/upload.inc.php"; +require_once "monica/xhtml.inc.php"; +require_once "monica/xfileio.inc.php"; + +// Settings +if (!defined("FIELD_HARD_LIMIT")) { + define("FIELD_HARD_LIMIT", 307200); +} +if (!defined("FORM_HARD_LIMIT")) { + define("FORM_HARD_LIMIT", 512000); +} + +// initenv: Initialize the script environment +// Input: +// $args: An associative array of arguments, where +// $args["allowed"]: The allowed request methods +// $args["restricted"]: Whether restricted to those permitted here +// $args["session"]: Whether to start a session (boolean) +// $args["sql"]: Which SQL (SQL_NONE, SQL_POSTGRESQL, SQL_MYSQL) +// $args["sql_lock"]: The SQL tables to lock in advance +function initenv($args) +{ + // The submitted data + $FORM =& get_or_post(); + + // Parse the arguments + $session = true; + if (array_key_exists("session", $args)) { + $session = $args["session"]; + } elseif (defined("START_SESSION")) { + $session = START_SESSION; + } + settype($session, "boolean"); + $sql = SQL_POSTGRESQL; + if ( array_key_exists("sql", $args) + && in_array($args["sql"], $GLOBALS["VALID_SQLS"])) { + $sql = $args["sql"]; + } elseif (defined("START_SQL") + && in_array(START_SQL, $GLOBALS["VALID_SQLS"])) { + $sql = START_SQL; + } + $GLOBALS["SQL_DBTYPE"] = $sql; + $restricted = false; + if (array_key_exists("restricted", $args)) { + $restricted = $args["restricted"]; + } + $lastmod = false; + if (array_key_exists("lastmod", $args)) { + $lastmod = $args["lastmod"]; + } + settype($lastmod, "boolean"); + $logtime = false; + if (array_key_exists("logtime", $args)) { + $logtime = $args["logtime"]; + } + settype($logtime, "boolean"); + define("LOGTIME", $logtime); + + // Set the custom error handler: http_500(): Standard error handler for Monica + set_error_handler("http500_error_handler"); + // Secure the script environment + secure_env(); + // Set the multi-byte environment + mb_internal_encoding("UTF-8"); + // Initial the gettext locale + _init_initgettext(); + // Check the last output buffering level + define("LAST_OB_LEVEL", (ini_get("output_buffering") == "" || !IS_CGI)? 0: 1); + // Start output buffering (till one level more than LAST_OB_LEVEL) + ob_start(); + + // Block FunWebProduct + // See http://www.networkworld.com/newsletters/web/2003/1208web2.html + if ( array_key_exists("HTTP_USER_AGENT", $_SERVER) + && strpos($_SERVER["HTTP_USER_AGENT"], "FunWebProduct") !== false) { + http_403(N_("Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) are are not welcome. It duplicates your request and produces high load and even crashes to our server. Please remove it first before you visit us.")); + } + // Block bad-behaved e-mail crawlers + // Some bad-behaved e-mail crawlers cannot deal with the parent + // directory ".." and ampersands, and attach them to the URI infinitely + if (strstr(REQUEST_PATH, "/..") !== false || strstr(REQUEST_URI, "&") !== false) { + http_400(false); + } + // Limit the request methods, default to GET, HEAD and POST + // Set to null for no check. Useful for testing and debugging + $allowed = array_key_exists("allowed", $args)? + $args["allowed"]: array("GET", "HEAD", "POST"); + if (!is_null($allowed) && !in_array($_SERVER["REQUEST_METHOD"], $allowed)) { + http_405($allowed); + } + // Block bad robots + _init_block_bad_robots(); + + // Initialize the session + if ($session) { + // Form processed with HTTPs + $https = false; + if (array_key_exists("https", $FORM)) { + $https = $FORM["https"]? true: false; + } + // We are HTTPS, processing a form that came from + // another non-HTTPS virtual host. + // Overriding the session ID. to keep the original session. + if ($https && is_https()) { + // Use the provided session ID + if (array_key_exists(session_name(), $FORM)) { + session_id($FORM[session_name()]); + } + } + // Avoid bad robots producing bad session ID. + $GLOBALS["php_errormsg"] = null; + set_error_handler("null_error_handler"); + session_start(); + if (!is_null($GLOBALS["php_errormsg"])) { + http_400($GLOBALS["php_errormsg"]); + } + restore_error_handler(); + } + // Prevent huge sized request + check_request_size(); + + // If client has not logged in on restricted area, we can + // bypass SQL connection to save our work + if (IS_CGI && is_null(get_login_sn()) && $restricted !== false) { + unauth(); + } + + // Initialize the SQL connection + if ($sql) { + if (defined("NODATABASE") && NODATABASE) { + http_503("Database shut down for maintainance."); + } + sql_connect(); + } + + // Only available on systems with membership turned on + if ($sql && use_users() && $session) { + // Update the log-in infomation + upd_login_info(); + // Check the client permission + if ($restricted !== false && !is_script_permitted($restricted)) { + unauth(); + } + // Check if this site is closed for policy + _init_check_nologin(); + } + + // Prepare the SQL tables to lock + if ($sql && array_key_exists("sql_lock", $args)) { + // Read-only on non-POSTed forms + if ($_SERVER["REQUEST_METHOD"] != "POST") { + foreach (array_keys($args["sql_lock"]) as $table) { + $args["sql_lock"][$table] = LOCK_SH; + } + // Add mtime to POSTed forms + } else { + if (in_array("mtime", sql_tables())) { + $args["sql_lock"]["mtime"] = LOCK_EX; + } + } + // Supply the default locks + if (use_users()) { + $default_locks = array("users", "groups", "scptpriv", "userpref", + "users AS createdby", "users AS updatedby"); + foreach ($default_locks as $table) { + if (!array_key_exists($table, $args["sql_lock"])) { + $args["sql_lock"][$table] = LOCK_SH; + } + } + } + } + + // Check the last modified + if ($lastmod) { + // Set the database tables to check + $tables = array(); + if (array_key_exists("lmtables", $args)) { + $tables = array_merge($tables, $args["lmtables"]); + } + // Add the locked tables automatically + if (array_key_exists("sql_lock", $args)) { + $tables = array_merge($tables, array_keys($args["sql_lock"])); + } + // Set the files to check + $files = array(); + if (array_key_exists("lmfiles", $args)) { + $files = array_merge($files, $args["lmfiles"]); + } + $callers = debug_backtrace(); + if (not_modified($tables, $files, + basename($callers[count($callers)-1]["file"]))) { + http_304(); + } + } + + // Lock the SQL tables + if ($sql && array_key_exists("sql_lock", $args)) { + sql_lock($args["sql_lock"]); + } + + // Fetch the current data + if (function_exists("fetch_current")) { + fetch_current(); + } + + // Decode user input FORMs to UTF-8 + decode_forms(); + + // Process the list preference form + if (form_type() == "listpref") { + if ( array_key_exists("domain", $_POST) + && class_exists($_POST["domain"])) { + $LIST = new $_POST["domain"]; + $LIST->set_listpref(); + } else { + $handler = new ListPreference($_POST); + $handler->main(); + } + } + + return; +} + +// restenv: Restore the script environment +function restenv() +{ + // Disconnect SQL + if ($GLOBALS["SQL_DBTYPE"] != SQL_NONE) { + sql_close(); + } + + // Print the page and end the output buffering, if it exists + if (ob_get_level() > LAST_OB_LEVEL) { + // Return from the innermost level to level 1 + while (ob_get_level() > LAST_OB_LEVEL + 1) { + ob_end_flush(); + } + // Obtain the final content + $html = ob_get_contents(); + ob_end_clean(); + // No content -- HTTP 204 + if ($html == "") { + http_204(); + } + + // The content type + $type = array_key_exists("CONTENT_TYPE", $GLOBALS)? + $GLOBALS["CONTENT_TYPE"]: xhtml_content_type(); + $is_html = preg_match("/^(?:text\/html|application\/xhtml\+xml)\b/", $type)? true: false; + $is_rss = $type == "application/rss+xml"; + // application/rss+xml is not supported yet + if ($is_rss) { + $type = "application/xml"; + } + $is_text = preg_match("/^(?:text\/plain)\b/", $type)? true: false; + $is_csv = preg_match("/^(?:text\/csv)\b/", $type)? true: false; + $is_js = preg_match("/^(?:text\/javascript)\b/", $type)? true: false; + $is_attach = array_key_exists("CONTENT_DISPOSITION", $GLOBALS) && + preg_match("/^attachment\b/", $GLOBALS["CONTENT_DISPOSITION"]); + + // Do the run-time replacements + if (($is_html || $is_rss || $is_text || $is_js) && function_exists("page_replacements")) { + $rep = page_replacements(); + foreach (array_keys($rep) as $key) { + $html = str_replace("", $rep[$key]["content"], $html); + } + } + + // Fix the HTML output + if ($is_html) { + if (preg_match("/; charset=([^ ;]+)/", $type, $m)) { + $charset = $m[1]; + } else { + $charset = getlang(LN_CHARSET); + $type .= "; charset=$charset"; + } + // Convert the URLs to relative + if ($is_attach) { + $html = page2abs($html, REQUEST_PATH); + } else { + $html = page2rel($html, REQUEST_PATH); + } + // Mung the e-mail at-signs (@) + $html = str_replace("@", "@", $html); + // Decode the e-mail at-signs (@) of spamtrap + $html = str_replace("spamtrap@", "spamtrap@", $html); + // Convert to the desired character set + $html = page_encode($html, $charset); + + // Fix the RSS output + } elseif ($is_rss) { + if (preg_match("/; charset=([^ ;]+)/", $type, $m)) { + $charset = $m[1]; + } else { + $charset = getlang(LN_CHARSET); + $type .= "; charset=$charset"; + } + // Mung the e-mail at-signs (@) + $html = str_replace("@", "@", $html); + // Decode the e-mail at-signs (@) of spamtrap + $html = str_replace("spamtrap@", "spamtrap@", $html); + // Convert to the desired character set + $html = page_encode($html, $charset); + + // Fix the plain text output + } elseif ($is_text) { + if (preg_match("/; charset=([^ ;]+)/", $type, $m)) { + $charset = $m[1]; + } else { + $charset = "UTF-8"; + $type .= "; charset=$charset"; + } + // Mung the e-mail at-signs (@) + $html = str_replace("@", "-at-", $html); + // Decode the e-mail at-signs (@) of spamtrap + $html = str_replace("spamtrap-at-", "spamtrap@", $html); + // Convert to the desired character set + $html = h_encode($html, $charset); + + // Fix the comma-seperated values output + } elseif ($is_csv) { + if (preg_match("/; charset=([^ ;]+)/", $type, $m)) { + $charset = $m[1]; + } else { + $charset = "UTF-8"; + $type .= "; charset=$charset"; + } + // Convert to the desired character set + $html = h_encode($html, $charset); + + // Fix the javascript output + } elseif ($is_js) { + if (preg_match("/; charset=([^ ;]+)/", $type, $m)) { + $charset = $m[1]; + } else { + $charset = getlang(LN_CHARSET); + $type .= "; charset=$charset"; + } + // Convert to the desired character set + $html = h_encode($html, $charset); + } + + header("Content-Type: $type"); + header("Content-Length: " . strlen($html)); + if (array_key_exists("CONTENT_DISPOSITION", $GLOBALS)) { + header("Content-Disposition: " . $GLOBALS["CONTENT_DISPOSITION"]); + } + header("Accept-Ranges: none"); + if ( substr($type, 0, 5) == "text/" + || $is_html + || substr($type, 0, 15) == "application/pdf") { + header("Content-Language: " . getlang(LN_NAME)); + } + // Client cache + if (array_key_exists("LAST_MODIFIED", $GLOBALS)) { + if (!is_null(get_login_sn())) { + header("Cache-Control: private"); + } else { + header("Cache-Control: public"); + } + header("Last-Modified: " . date("r", $GLOBALS["LAST_MODIFIED"])); + } else { + header("Cache-Control: no-cache"); + } + // Content negotiation, see HTTP/1.1 section 13.6 + if ( count($GLOBALS["ALL_LINGUAS"]) > 1 + && $_SERVER["REQUEST_METHOD"] != "POST" + && $_SERVER["REQUEST_METHOD"] != "PUT" + && !array_key_exists("lang", $_GET)) { + header("Content-Location: " . rel2abs(altlang(getlang(), page_param()))); + header("Vary: negotiate,accept,accept-language,cookie"); + } + + // Print the page body + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + } + + // Purge the file cache + if (isset($_SESSION) && array_key_exists("savefile", $_SESSION)) { + $FILES =& file_deposit(); + $total = 0; + foreach (array_keys($FILES) as $sn) { + // Not a normal record + if ( !is_array($FILES[$sn]) + || !array_key_exists("size", $FILES[$sn])) { + continue; + } + $total += $FILES[$sn]["size"]; + // Too larged + if ($total > UPLOAD_DEPOSIT_MAX) { + clear_file_deposit(); + break; + } + } + } + + // Print the processing time for debugging purpose + if (defined("LOGTIME") && LOGTIME) { + error_log("Process time: " . (time_hires() - T_START) . " sec."); + } + + return; +} + +// secure_env: Secure the script environment +function secure_env() +{ + $ENVLIST = array("PATH", "USER", "MAIL", "HOME", "USERNAME", + "LOGNAME", "PWD", "ENV", "KDEDIR"); + foreach ($ENVLIST as $env) { + if (getenv($env) !== false) { + putenv("$env="); + } + } + return; +} + +// check_request_size: Prevent huge sized request +function check_request_size() +{ + $len = _init_check_array_size($_GET); + if ($len === false) http_413(); + if ($len > FORM_HARD_LIMIT) http_413(); + $len = _init_check_array_size($_POST); + if ($len === false) http_413(); + if ($len > FORM_HARD_LIMIT) http_413(); + $len = _init_check_array_size($_COOKIE); + if ($len === false) http_413(); + if ($len > FORM_HARD_LIMIT) http_413(); + $len = _init_check_array_size($_SERVER); + if ($len === false) http_413(); + if ($len > FORM_HARD_LIMIT) http_413(); + return; +} +// _init_check_array_size: Recursively check the size of an array +function _init_check_array_size(&$a) +{ + // Check the array size + if (gettype($a) != "array") { + $len = strlen($a); + if ($len > FIELD_HARD_LIMIT) { + return false; + } + return $len; + } + // Check the array size + $len = 0; + foreach (array_keys($a) as $k) { + $len += strlen($k); + if (gettype($a[$k]) == "array") { + $len0 = _init_check_array_size($a[$k]); + if ($len0 === false) { + return false; + } + $len += $len0; + } else { + $len0 = strlen($a[$k]); + if ($len0 > FIELD_HARD_LIMIT) { + return false; + } + $len += $len0; + } + } + return $len; +} + +// _init_check_nologin: If this site is closed for policy +function _init_check_nologin() +{ + // Not logged in - no checks needed + if (is_null(get_login_sn())) { + return; + } + // NOLOGIN: Only super-users can log in now + if (defined("NOLOGIN") && NOLOGIN) { + // Only super-users can log into no-log-in websites + if (is_su()) { + return; + } + logout(); + // Deny access to the development site + ob_end_clean(); + ob_start(); + html_header(_("Log-In Closed")); + html_title(_("Log-In Closed")); + html_message(_("Log-in is temporarily closed for maintainance now. Please come again later. Sorry for the inconvienence.")); + html_footer(); + $html = ob_get_contents(); + ob_end_clean(); + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + // No need to return + exit; + + // CLOSEDEV: Only developers can log in now + } elseif (defined("CLOSEDEV") && CLOSEDEV) { + if (is_group("dev")) { + return; + } + logout(); + // Deny access to the development site + ob_end_clean(); + ob_start(); + html_header(_("Development Site Closed")); + html_title(_("Development Site Closed")); + html_message(_("Development site is closed. Please work on the live site.")); + html_footer(); + $html = ob_get_contents(); + ob_end_clean(); + if ($_SERVER["REQUEST_METHOD"] != "HEAD") { + echo $html; + } + // No need to return + exit; + } + +} + +// _init_block_bad_robots: Block bad robots +function _init_block_bad_robots() +{ + // User-Agent: was sent + if (array_key_exists("HTTP_USER_AGENT", $_SERVER)) { + // Check MSIE 6 and unbalanced brackets + if ($_SERVER["HTTP_USER_AGENT"] == "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1") { + http_403(); + } + // Check User-Agent in user-agent identification + if (substr($_SERVER["HTTP_USER_AGENT"], 0, 11) == "User-Agent:") { + http_403(); + } + // Check User-Agent in user-agent identification + if (strpos($_SERVER["HTTP_USER_AGENT"], "DTS Agent") !== false) { + http_403(false); + } + // MSIE 6 must be HTTP/1.1 + // -- disabled 2006-07-07. Lots of innocent set this way (why?) + // Opera pretends to be MSIE 6, and uses HTTP/1.0 (why?) + //if ( preg_match("/\bMSIE [456]/", $_SERVER["HTTP_USER_AGENT"]) + // && strstr($_SERVER["HTTP_USER_AGENT"], "Opera") === false + // && $_SERVER["SERVER_PROTOCOL"] != "HTTP/1.1") { + // http_403(); + //} + } + // Check huge amount of requests from a same host in a short time + if (IS_CGI) { + $file = ini_get("session.save_path") . "/ipacct.txt"; + $count = 0; + $newrecs = array(); + $lastseen = null; + // Check the current records + if (file_exists($file)) { + $fp = fopen($file, "r+"); + flock($fp, LOCK_EX); + $size = filesize($file); + // fread() does not allow reading of 0 bytes now + if ($size == 0) { + $content = ""; + } else { + $content = fread($fp, $size); + } + $currecs = explode("\n", $content); + foreach ($currecs as $record) { + // Drop invalid + if (!preg_match("/^(\d+) (\d+\.\d+\.\d+\.\d+) /", $record, $m)) { + continue; + } + // We only keep 30 minutes + if (NOW - $m[1] >= 1800) { + continue; + } + $newrecs[] = "$record\n"; + if ($m[2] == $_SERVER["REMOTE_ADDR"]) { + if (is_null($lastseen) || $lastseen > $m[1]) { + $lastseen = $m[1]; + } + $count++; + } + } + fseek($fp, 0, SEEK_SET); + ftruncate($fp, 0); + // No current records yet + } else { + $fp = fopen($file, "w"); + flock($fp, LOCK_EX); + } + // Add this record + if (is_null($lastseen)) { + $lastseen = NOW; + } + $newrecs[] = sprintf("%d %s %s\n", NOW, $_SERVER["REMOTE_ADDR"], + date("Y-m-d H:i:s", NOW)); + $count++; + // Update the accounting + fwrite($fp, implode("", $newrecs)); + flock($fp, LOCK_UN); + fclose($fp); + /* Debug + if (array_key_exists("debug_reqid", $_GET)) { + error_log(sprintf("req=%s NOW=%d lastseen=%d count=%d avg=%.2f block=%s", + $_GET["debug_reqid"], NOW, $lastseen, $count, + $count / ((NOW == $lastseen)? 1: NOW - $lastseen), + ($count / ((NOW == $lastseen)? 1: NOW - $lastseen) > 2? "yes": "no"))); + } */ + // Averagely 2 script requests in 1 second from a same host - that is too much. + if ($count / ((NOW == $lastseen)? 1: NOW - $lastseen) > 2) { + http_503("Request too fast."); + } + } +} + +// _init_initgettext: Initialize the gettext locale +function _init_initgettext() +{ + putenv("LANG=" . getlang(LN_LOCALE)); + putenv("LANGUAGE=" . getlang(LN_LOCALE)); + putenv("LC_ALL=" . getlang(LN_LOCALE)); + setlocale(LC_ALL, ""); + bindtextdomain(COMMONDOMAIN, COMMONLOCALEDIR); + if (defined("PACKAGE")) { + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + } +} + +?> diff --git a/lib/php/monica/ipv4addr.inc.php b/lib/php/monica/ipv4addr.inc.php new file mode 100644 index 0000000..36cd621 --- /dev/null +++ b/lib/php/monica/ipv4addr.inc.php @@ -0,0 +1,56 @@ + +// Copyright: Copyright (C) 2007 Pristine Communications + +// ipv4_in_network: If an IP is in a network +function ipv4_in_network($network, $ip) +{ + // Network in ddd.ddd.ddd.ddd/mm format + if (preg_match("/^(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)$/", $network, $m)) { + // Sanity check + settype($m[5], "integer"); + if ($m[5] > 32) { + return null; + } + for ($i = 1; $i <= 4; $i++) { + settype($m[$i], "integer"); + if ($m[$i] > 255) { + return null; + } + } + // Get the subnetwork mask + $masklen = $m[5]; + for ($i = 0, $submask = 0; $i < $masklen; $i++) { + $submask |= 1 << (31 - $i); + } + $network = ip2long(sprintf("%d.%d.%d.%d", $m[1], $m[2], $m[3], $m[4])); + $network &= $submask; + + // Malformed network + } else { + return null; + } + + // IP in ddd.ddd.ddd.ddd format + if (preg_match("/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/", $ip, $m)) { + // Sanity check + for ($i = 1; $i <= 4; $i++) { + settype($m[$i], "integer"); + if ($m[$i] > 255) { + return null; + } + } + $ip = ip2long(sprintf("%d.%d.%d.%d", $m[1], $m[2], $m[3], $m[4])); + + // Malformed IP + } else { + return null; + } + + return (($ip & $submask) == $network); +} + +?> diff --git a/lib/php/monica/lastmodf.inc.php b/lib/php/monica/lastmodf.inc.php new file mode 100644 index 0000000..9178eb3 --- /dev/null +++ b/lib/php/monica/lastmodf.inc.php @@ -0,0 +1,154 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/cgiemu.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/sqlconst.inc.php"; + +// not_modified: Check if we should send "HTTP/1.1 304 Not Modified" +function not_modified($tables, $files, $this_file) +{ + // HTTP/1.1 304 only works for GET or HEAD + if (!in_array($_SERVER["REQUEST_METHOD"], array("GET", "HEAD"))) { + return false; + } + + // Find the last-modified time + find_last_modified($tables, $files, $this_file); + // If-Modified-Since not supplied. The client had not cached yet. + if (!array_key_exists("HTTP_IF_MODIFIED_SINCE", $_SERVER)) { + return false; + } + // Malformed If-Modified-Since value + $cachemodf = strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]); + if ($cachemodf == -1) { + return false; + } + // We are newer than the cache + if ($GLOBALS["LAST_MODIFIED"] > $cachemodf) { + return false; + } + // Yes, use the cache + return true; + return; +} + +// find_last_modified: Find the last-modified time +function find_last_modified($tables, $files, $this_file) +{ + // Checked before + if (array_key_exists("LAST_MODIFIED", $GLOBALS)) { + return; + } + + // Remove duplicates + $tables = array_values(array_unique($tables)); + $files = array_values(array_unique($files)); + + // Start with EPOCH 1970-01-01 00:00:00 + $GLOBALS["LAST_MODIFIED"] = 0; + global $LAST_MODIFIED; + + // Check myself + updmtime_file($this_file); + // Check mtime from the included modules and gettext MO files + check_inc(); + // Check the supplied data files + foreach ($files as $file) { + if (file_exists($file)) { + updmtime_file($file); + } + } + // Check the supplied data tables + updmtime_tables($tables); +} + +// check_inc: Check mtime from the included modules and gettext MO files +function check_inc() +{ + // Check the included modules + foreach (get_included_files() as $file) { + updmtime_file($file); + } + + // Check the header and footer + $incdir = DOC_ROOT . "/admin/include"; + $files = array(); + $files[] = $incdir . "/header." . getlang(LN_FILENAME) . ".html"; + $files[] = $incdir . "/footer." . getlang(LN_FILENAME) . ".html"; + $files[] = $incdir . "/header.html"; + $files[] = $incdir . "/footer.html"; + foreach ($files as $file) { + if (file_exists($file)) { + updmtime_file($file); + } + } + + // Check the gettext mo files + if (defined("PACKAGE") && is_dir(LOCALEDIR)) { + $dh = opendir(LOCALEDIR); + while (($ent = readdir($dh)) !== false) { + $file = LOCALEDIR . "/$ent/LC_MESSAGES/" . PACKAGE . ".mo"; + if (file_exists($file)) { + updmtime_file($file); + } + } + closedir($dh); + } + $dh = opendir(COMMONLOCALEDIR); + while (($ent = readdir($dh)) !== false) { + $file = COMMONLOCALEDIR . "/$ent/LC_MESSAGES/" . COMMONDOMAIN . ".mo"; + if (file_exists($file)) { + updmtime_file($file); + } + } + closedir($dh); + return; +} + +// updmtime_tables: Update the $LAST_MODIFIED with the mtime of tables +function updmtime_tables($tables) +{ + // Only work when using database + if ($GLOBALS["SQL_DBTYPE"] == SQL_NONE) { + return; + } + $lastupd = sql_lastupd($tables); + if (is_null($lastupd)) { + return; + } + if (!is_numeric($lastupd)) { + $lastupd = preg_replace("/\.\d+$/", "", $lastupd); + $lastupd = strtotime($lastupd); + } + settype($lastupd, "integer"); + if ($GLOBALS["LAST_MODIFIED"] < $lastupd) { + $GLOBALS["LAST_MODIFIED"] = $lastupd; + } + return; +} + +// updmtime_file: Update the $LAST_MODIFIED with the mtime of a file +function updmtime_file($file) +{ + $stat = stat($file); + if ($GLOBALS["LAST_MODIFIED"] < $stat[9]) { + $GLOBALS["LAST_MODIFIED"] = $stat[9]; + } + return; +} + +?> diff --git a/lib/php/monica/links.inc.php b/lib/php/monica/links.inc.php new file mode 100644 index 0000000..e40061a --- /dev/null +++ b/lib/php/monica/links.inc.php @@ -0,0 +1,384 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/chkfunc.inc.php"; +require_once "monica/commtext.inc.php"; +require_once "monica/echoform.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/sql.inc.php"; + +// linkcat_title: Obtain a link category title +function linkcat_title($sn) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $sn + if (is_null($sn)) { + return t_notset(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + + // Check the serial number first + if (!check_sn($sn)) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Query + // Unilingual + if (count($GLOBALS["ALL_LINGUAS"]) == 1) { + $col = "linkcat_fulltitle(parent, title) AS title"; + // Multilingual + } else { + $thiscol = "title_" . getlang(LN_DATABASE); + $lang = getlang(); + // Default language + if ($lang == DEFAULT_LANG) { + $col = "linkcat_fulltitle('$lang', parent, $thiscol) AS title"; + // Fall back to the default language + } else { + $defcol = "title_" . ln(DEFAULT_LANG, LN_DATABASE); + $col = "linkcat_fulltitle('$lang', parent, COALESCE($thiscol, $defcol)) AS title"; + } + } + $select = "SELECT $col FROM linkcat WHERE sn=$sn;\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$sn] = $row["title"]; + + return $cache[$sn]; +} + +// linkcat_path: Obtain a link category path +function linkcat_path($sn) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $sn + if (is_null($sn)) { + return t_notset(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + + // Check the serial number first + if (!check_sn($sn)) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Query + $select = "SELECT linkcat_path(sn, id, parent) AS path FROM linkcat" + . " WHERE sn=$sn;\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$sn] = $row["path"]; + $cache[$sn] = preg_replace("/(?:\/|\.html)$/", "", $cache[$sn]); + + return $cache[$sn]; +} + +// linkcat_options: Obtain a link category options list +function linkcat_options($value) +{ + // Unilingual + if (count($GLOBALS["ALL_LINGUAS"]) == 1) { + $content = "linkcat_fulltitle(parent, title) AS content"; + // Multilingual + } else { + $thiscol = "title_" . getlang(LN_DATABASE); + $lang = getlang(); + // Default language + if ($lang == DEFAULT_LANG) { + $content = "linkcat_fulltitle('$lang', parent, $thiscol) AS content"; + // Fall back to the default language + } else { + $defcol = "title_" . ln(DEFAULT_LANG, LN_DATABASE); + $content = "linkcat_fulltitle('$lang', parent, COALESCE($thiscol, $defcol)) AS content"; + } + } + $select = "SELECT sn AS value, $content FROM linkcat" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + return opt_list($select, $value); +} + +// link_title: Obtain a link title +function link_title($sn) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $sn + if (is_null($sn)) { + return t_notset(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + + // Check the serial number first + if (!check_sn($sn)) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Query + // Unilingual + if (count($GLOBALS["ALL_LINGUAS"]) == 1) { + $col = "title"; + // Multilingual + } else { + $thiscol = "title_" . getlang(LN_DATABASE); + // Default language + if (getlang() == DEFAULT_LANG) { + $col = "$thiscol AS title"; + // Fall back to the default language + } else { + $defcol = "title_" . ln(DEFAULT_LANG, LN_DATABASE); + $col = "COALESCE($thiscol, $defcol) AS title"; + } + } + $select = "SELECT $col FROM links WHERE sn=$sn;\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$sn] = $row["title"]; + + return $cache[$sn]; +} + +// link_url: Obtain a link URL. +function link_url($sn) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $sn + if (is_null($sn)) { + return t_notset(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + + // Check the serial number first + if (!check_sn($sn)) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Query + $select = "SELECT url FROM links WHERE sn=$sn;\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$sn] = $row["url"]; + + return $cache[$sn]; +} + +// links_shown_parts: Obtain the shown links parts +function links_shown_parts() +{ + $r = array(); + + // Obtain the shown categories + $path = "linkcat_path(sn, id, parent) AS path"; + $select = "SELECT sn, $path FROM linkcat" + . " WHERE linkcat_isshown(sn, hid, parent)" + . " ORDER BY linkcat_fullord(parent, ord);\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0, $r["catspath"] = array(), $r["cats"] = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $r["cats"][] = $row["sn"]; + $r["catspath"][] = $row["path"]; + } + sort($r["cats"]); + sort($r["catspath"]); + + return $r; +} + + +///////////////////////// +// Subroutines about link categories +///////////////////////// +// link_tree_full: Get the full page tree of the links +function link_tree_full($lang, $preview = null) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($lang, $cache)) { + return $cache[$lang]; + } + + // Initialize the result + $tree = array(); + + $lnpref = (count($GLOBALS["ALL_LINGUAS"]) == 1)? + "": "/" . ln($lang, LN_FILENAME); + $tree["index"] = array( + "path" => "$lnpref/links/", + "_path" => "/links/", + "title" => C_("Related Links"), + ); + + // Get the link tree + $pages =& _link_subtree("/links", null, $lang, $preview); + if (!is_null($pages)) { + $tree["pages"] =& $pages; + } + + return $tree; +} + +// _link_subtree: Get the page subtree of the links +function &_link_subtree($path, $parent, $lang, $preview = null) +{ + // Set the language + $lndb = ln($lang, LN_DATABASE); + $langfile = ln($lang, LN_FILENAME); + + // Check if there is any link below this category + $has_links = false; + if (!is_null($parent)) { + $select = "SELECT links.sn FROM links" + . " INNER JOIN linkcatz ON linkcatz.link=links.sn" + . " WHERE linkcatz.cat=$parent" + . " AND " . sql_is_false("links.hid") + . " LIMIT 1;\n"; + $result = sql_query($select); + $has_links = (sql_num_rows($result) > 0); + // Check the preview + if (!$has_links && !is_null($preview)) { + $has_links = in_array($parent, $preview["cats"]); + } + } + + // Obtain the subcategories + $cols = array(); + $cols[] = "sn AS sn"; + $cols[] = "id AS id"; + if (count($GLOBALS["ALL_LINGUAS"]) > 1) { + if ($lang == DEFAULT_LANG) { + $cols[] = "title_$lndb AS title"; + } else { + $lndbdef = ln(DEFAULT_LANG, LN_DATABASE); + $cols[] = "COALESCE(title_$lndb, title_$lndbdef)" + . " AS title"; + } + } else { + $cols[] = "title AS title"; + } + $cols[] = "ord AS ord"; + $conds = array(); + if (is_null($parent)) { + $conds[] = "parent IS NULL"; + } else { + $conds[] = "parent=$parent"; + } + $conds[] = sql_is_false("hid"); + if (!is_null($preview) && array_key_exists("sn", $preview)) { + $conds[] = "sn!=" . $preview["sn"]; + } + $select = "SELECT " . implode(", ", $cols) . " FROM linkcat" + . " WHERE " . implode(" AND ", $conds) + . " ORDER BY ord;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + $lnpref = (count($GLOBALS["ALL_LINGUAS"]) == 1)? + "": "/" . ln($lang, LN_FILENAME); + for ($i = 0, $pages = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $subpages =& _link_subtree($path . "/" . $row["id"], + $row["sn"], $lang, $preview); + // Only create subtree that has some content + if (!is_null($subpages)) { + // No subcategories -- create it as a ".html" page + if (count($subpages) == 0) { + $subpath = $path . "/" . $row["id"] . ".html"; + $pages[] = array( + "path" => $lnpref . $subpath, + "_path" => $subpath, + "title" => $row["title"], + "ord" => $row["ord"], + ); + // There are subcatgories -- create it as a directory + } else { + $subpath = $path . "/" . $row["id"] . "/"; + $pages[] = array( + "path" => $lnpref . $subpath, + "_path" => $subpath, + "title" => $row["title"], + "ord" => $row["ord"], + "sub" => array( + "index" => array( + "path" => $lnpref . $subpath, + "_path" => $subpath, + "title" => $row["title"], + ), + "pages" => $subpages, + ), + ); + } + } + } + + // No content below + if (!$has_links && count($pages) == 0) { + $pages = null; + return $pages; + } + + return $pages; +} + +?> diff --git a/lib/php/monica/list.inc.php b/lib/php/monica/list.inc.php new file mode 100644 index 0000000..44ea70b --- /dev/null +++ b/lib/php/monica/list.inc.php @@ -0,0 +1,3774 @@ + +// Copyright: Copyright (C) 2002-2013 Pristine Communications + +// This file is in UTF-8 萬國碼 + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/a2html.inc.php"; +require_once "monica/actlog.inc.php"; +require_once "monica/addget.inc.php"; +require_once "monica/addslash.inc.php"; +require_once "monica/chkfunc.inc.php"; +require_once "monica/commtext.inc.php"; +require_once "monica/echoform.inc.php"; +require_once "monica/errmsg.inc.php"; +require_once "monica/formfunc.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/htmlchar.inc.php"; +require_once "monica/listpref.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/markabbr.inc.php"; +require_once "monica/pagefunc.inc.php"; +require_once "monica/pic.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/runcmd.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/sqlconst.inc.php"; +require_once "monica/userpref.inc.php"; + + +// _list_cmp_range: Compare the abstract ranges for usort() +function _list_cmp_range($a, $b) +{ + if ($a["start"] != $a["end"]) { + return $a["start"] - $b["start"]; + } else { + return $a["end"] - $b["end"]; + } +} + +// _list_cmp_query: Compare the query phrases for usort() +function _list_cmp_query($a, $b) +{ + return mb_strlen($b) - mb_strlen($a); +} + +// list_type: Return the list name +function list_type($type = null) +{ + // Cache the result + static $cache; + // Set the list type + if (!is_null($type)) { + $cache = $type; + } + // Return the cache + if (isset($cache)) { + return $cache; + } + + // Obtain the current form + $FORM =& curform(); + // Form type specified in arguments + if (array_key_exists("list", $FORM)) { + $cache = $FORM["list"]; + + // No form source is found + } else { + $cache = null; + } + return $cache; +} + +// parse_query: Parse the query string into multiple search phrases +function parse_query($query) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($query, $cache)) { + return $cache[$query]; + } + $phrases = array(); + $query = trim($query); + while ($query != "") { + // Non-quoted word + if (preg_match("/^([^\s\"']+)\s*(.*?)$/", $query, $m)) { + $phrases[] = $m[1]; + $query = $m[2]; + // Double-quoted string + } elseif (preg_match("/^(?:\"((?:[^\\\\\"]|\\\\.)+)\"?)\s*(.*?)$/", $query, $m)) { + $m[1] = str_replace("$", "\\$", $m[1]); + eval("\$phrases[] = \"$m[1]\";"); + $query = $m[2]; + // Single-quoted string + } elseif (preg_match("/^(?:'((?:[^\\\\']|\\\\.)+)'?)\s*(.*?)$/", $query, $m)) { + eval("\$phrases[] = '$m[1]';"); + $query = $m[2]; + // Empty quoted strings + } elseif (preg_match("/^(?:\"\"?|''?)\s*(.*?)$/", $query, $m)) { + $query = $m[1]; + } + } + sort($phrases); + // Cache it + $cache[$query] = $phrases; + return $phrases; +} + + +// urlcheck: Perform URL. checks on the current list +function urlcheck(&$current) +{ + // Check the URL. format and gather those to check the availibility. + $tocheck = array(); + $stdin = ""; + for ($i = 0; $i < count($current); $i++) { + if (is_null($current[$i]["_urlcheck"])) { + $current[$i]["_urlcheck"] = t_notset(); + } elseif (!is_url_wellformed($current[$i]["_urlcheck"])) { + $current[$i]["_urlcheck"] = C_("Malformed"); + } else { + $tocheck[count($tocheck)] =& $current[$i]; + $stdin .= $current[$i]["_urlcheck"] . "\n"; + } + } + + // Nothing to check further + if (count($tocheck) == 0) { + return; + } + + // Preserve the original timeout + $timeout = ini_get("max_execution_time"); + ini_set("max_execution_time", 0); + // Run the command and obtain the output + $cmd = array(dirname(__FILE__) . "/urlcheck"); + $out = xruncmd($cmd, $stdin); + // Restore the timeout + ini_set("max_execution_time", $timeout); + + // Save the result + $result = explode("\n", $out); + for ($i = 0; $i < count($tocheck); $i++) { + $tocheck[$i]["_urlcheck"] = $result[$i]? + C_("OK"): C_("Unreachable"); + } + return; +} + + +///////////////////////// +// New Object-Oriented List Handler +// By imacat 2004-05-30 +///////////////////////// +// BaseList: Base list handler class +class BaseList +{ + // Parameters to be set by the user + // The default number of rows per page when user preference is unavailable. + // Don't set to null. + // This is not to set the number of rows. Set $_pagesize instead. + protected $_DEFAULT_LIST_SIZE = 10; + protected $_DEFAULT_LIST_COLS = array("sn"); + // The default sort order -- for non-VIEW lists only + protected $_DEFAULT_SORTBY = null; + // The list brief size + protected $_DEFAULT_BRIEF_LEN = 15; + // The query abstract span from the found phrase + protected $_QABS_SPAN = 30; + // The maximum query abstract length + protected $_QABS_MAXLEN = 200; + // The picture thumbnail size + protected $_PIC_THUMBNAIL_SIZE = 70; + + // Default settings + // Known columns that should not be displayed (has a special purpose) + protected $_COLS_NO_DISPLAY = array("_viewurl", "_sel", "_selurl", "_statord"); + // Known columns that should never be searched against + protected $_COLS_NO_SEARCH = array("pic", "att", "pdf", "_urlcheck", "_viewurl", "_sel", "_selurl", "_statord"); + // Known columns that should not be sorted with + protected $_COLS_NO_SORT_BY = array("_urlcheck", "_viewurl", "_sel", "_selurl", "_statord"); + // Columns that should display its brief instead + protected $_COLS_BRIEF = array(); + + // The page title for the current list + public $title = null; + // The error status after fetching the list + public $error = null; + // The switch for different lists + public $lists_switch = null; + // The number of total/matching records + public $total = null; + + // Whether we have fetched the list + protected $_fetched = false; + // Whether we need mass deletion checkers + protected $_massdel = false; + // Whether we need preceding numbering + protected $_nonumber = false; + // Whether we need selection links + protected $_noselect = false; + // Whether we need sorting links + protected $_nosortby = false; + // Whether the list should be in a reversed order + protected $_reverse = false; + // Whether these are static pages + protected $_static = false; + // The file name pattern of the static pages + protected $_static_filepat = "%04d.html"; + protected $_static_lastfile = "last.html"; + + // Query arguments + protected $_form = null; + protected $_query = null; + protected $_pageno = null; + protected $_sortby = null; + protected $_limit = null; + // Select parameters + protected $_is_called_form = null; + protected $_caller = null; + protected $_cformid = null; + // The language to use + protected $_lang = null; + // If this is a multi-lingual table + protected $_is_ml_table = null; + + // Column labels to be used in _html_list() and _html_listprefform() + protected $_col_labels = array(); + + // This shall be set when initializing the handler + protected $_useview; + protected $_seltext; + protected $_selurl_tmpl; + + // The parsing results + protected $_table = null; + protected $_view = null; + protected $_select = null; + protected $_select_total = null; + protected $_current = null; + protected $_cols = null; + protected $_lastpage = null; + // The number of rows per page. Set to false to disable paging. + protected $_pagesize = null; + protected $_startno = null; + protected $_endno = null; + + // Intermediate parsing results when fetching a list + protected $_coldefs = array(); + protected $_sortkeys = array(); + protected $_query_phrases = array(); + protected $_listcols = array(); + + // __construct: Initialize the handler + // We only set up the environment, but do not really initialize + // the object here. This way we can configure the environment + // in the beginning before we pass its arguments in the middle + // of the script + function __construct($FORM, $table) + { + // The default value + if (is_null($FORM)) { + $FORM = curform(); + } + + // Set the environment + if ($GLOBALS["SQL_DBTYPE"] != SQL_NONE) { + $this->_useview = sql_support(SQL_FEATURE_VIEW); + } + + // Set the parameters + $this->_form =& $FORM; + $this->_table = $table; + $this->_pageno = array_key_exists("pageno", $this->_form)? + $this->_form["pageno"]: null; + $this->_sortby = array_key_exists("sortby", $this->_form)? + $this->_form["sortby"]: null; + $this->_query = array_key_exists("query", $this->_form)? + $this->_form["query"]: null; + if ($this->_query == C_("(query phrase)")) { + $this->_query = ""; + } + $this->_lang = array_key_exists("lang", $this->_form) + && in_array($this->_form["lang"], $GLOBALS["ALL_LINGUAS"])? + $this->_form["lang"]: getlang(); + + // The default column labels + $this->_col_labels(array( + // Common labels shared by all list handlers + "sn" => C_("S/N"), + "created" => C_("Created"), + "createdby" => C_("Created by"), + "updated" => C_("Updated"), + "updatedby" => C_("Updated by"), + // Other commonly-seen column labels + "body" => C_("Content"), + "cat" => C_("Category"), + "cov" => C_("Coverage"), + "date" => C_("Date"), + "disabled" => C_("Disabled?"), + "dsc" => C_("Description"), + "email" => C_("E-mail"), + "hid" => C_("Hidden?"), + "html" => C_("HTML?"), + "id" => C_("ID."), + "kw" => C_("Keywords"), + "name" => C_("Name"), + "ord" => C_("Order"), + "path" => C_("Page path"), + "pic" => C_("Picture"), + "picratio" => C_("Pic. ratio"), + "piccap" => C_("Pic. caption"), + "picpos" => C_("Pic. position"), + "subject" => C_("Subject"), + "title" => C_("Title"), + "url" => C_("URL."), + "_urlcheck" => C_("Status (slow)"), + )); + + // Parameters for the called forms + $this->_is_called_form = array_key_exists("caller", $this->_form) + && array_key_exists("cformid", $this->_form); + if ($this->_is_called_form) { + $this->_caller = $this->_form["caller"]; + $this->_cformid = $this->_form["cformid"]; + $this->_seltext = C_("Select"); + $this->_selurl_tmpl = $this->_caller + . "?formid=" . $this->_cformid . "&selsn=%d"; + $this->_title = C_("Select a Data Record"); + } else { + $this->_caller = null; + $this->_cformid = null; + $this->_seltext = C_("Edit"); + $this->_selurl_tmpl = REQUEST_FILE . "?form=cur&sn=%d"; + $this->_title = C_("Manage Data"); + } + + // The default of the multi-lingual status + $this->_is_ml_table = null; + } + + // fetch: Fetch the current list. + // We dispatch here for different query engines + function fetch() + { + // Fetched before + if ($this->_fetched) { + return $this->error; + } + $this->_fetched = true; + // Initialize the error status + $this->error = null; + + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_MYSQL: + return $this->_fetch_offset(); + case SQL_POSTGRESQL: + return $this->_fetch_once(); + } + } + + // page_param: Obtain page parameters + function page_param() + { + // Fetch the current list if not fetched yet + if (!$this->_fetched) { + $this->fetch(); + } + + // Don't show the list + if (is_null($this->total)) { + return null; + } + // No record to be listed + if ($this->total == 0) { + return null; + } + + $args = array(); + $baseurl = rem_get_arg(REQUEST_FILEQS, "pageno"); + // The first page -- only meaningful when there is more than one page + if ($this->_lastpage > 1) { + if ($this->_static) { + $args["first"] = sprintf($this->_static_filepat, 1); + } elseif ($this->_reverse) { + $args["first"] = add_get_arg($baseurl, "pageno", 1, DUP_OK); + } else { + $args["first"] = $baseurl; + } + } + // The previous page + if ($this->_pageno > 1) { + if ($this->_static) { + $args["prev"] = sprintf($this->_static_filepat, $this->_pageno - 1); + } elseif ($this->_reverse || $this->_pageno - 1 != 1) { + $args["prev"] = add_get_arg($baseurl, "pageno", $this->_pageno - 1, DUP_OK); + } else { + $args["prev"] = $baseurl; + } + } + // The next page + if ($this->_pageno < $this->_lastpage) { + if ($this->_static) { + if ( !is_null($this->_static_lastfile) + && $this->_pageno + 1 == $this->_lastpage) { + $args["next"] = $this->_static_lastfile; + } else { + $args["next"] = sprintf($this->_static_filepat, $this->_pageno + 1); + } + } elseif (!$this->_reverse || $this->_pageno + 1 != $this->_lastpage) { + $args["next"] = add_get_arg($baseurl, "pageno", $this->_pageno + 1, DUP_OK); + } else { + $args["next"] = $baseurl; + } + } + // The last page -- only meaningful when there is more than one page + if ($this->_lastpage > 1) { + if ($this->_static) { + if (!is_null($this->_static_lastfile)) { + $args["last"] = $this->_static_lastfile; + } else { + $args["last"] = sprintf($this->_static_filepat, $this->_lastpage); + } + } elseif (!$this->_reverse) { + $args["last"] = add_get_arg($baseurl, "pageno", $this->_lastpage, DUP_OK); + } else { + $args["last"] = $baseurl; + } + } + return $args; + } + + // html: Output the list + function html() + { + // Fetch the current list if not fetched yet + if (!$this->_fetched) { + $this->fetch(); + } + + // Display the title + $this->_html_title(); + // Display the error message + $this->_html_errmsg(); + // Display the switch for different lists + $this->_html_lists_switch(); + // Display a link to add a new item + $this->_html_newlink(); + // Display the search box + $this->_html_search(); + // Display the list status message + $this->_html_liststat(); + // Display the page bar at the beginning + $this->_html_pagebar(); + // List the items + $this->_html_list(); + // Display the page bar at the end + $this->_html_pagebar(); + // Display a form to change the list preference + $this->_html_listprefform(); + + return; + } + + // set_listpref: Set the list preference + function set_listpref() + { + $handler = new ListPreference($this->_form); + $handler->main(); + } + + ///////////////////////// + // Methods belows are private. Do not call them directly. + // Override them when needed. + ///////////////////////// + // _fetch_once: Fetch the current list in once. + // Fetching the list in one query: Query everything, fetch + // the total and only the wanted portion. + // This is faster in PostgreSQL but slower in MySQL. + function _fetch_once() + { + // See if we need to use views or not. + // Views make things much faster and easier, but some DBMS has no views. + if ($this->_useview) { + $r = $this->_select_with_view(); + } else { + $r = $this->_select_without_view(); + } + $this->_select = sprintf("SELECT %s FROM %s%s%s%s;\n", + $r["cols"], $r["table"], $r["where"], $r["orderby"], $r["limit"]); + $result = sql_query($this->_select); + $this->total = sql_num_rows($result); + + // The number of rows per page + if (is_null($this->_pagesize)) { + $this->_pagesize = userpref("listsize", get_class($this)); + if (is_null($this->_pagesize)) { + $this->_pagesize = $this->_DEFAULT_LIST_SIZE; + } + } + // Paging not in use + if ($this->_pagesize === false) { + $this->_lastpage = 1; + $this->_startno = 0; + $this->_endno = $this->total - 1; + // If endno is -1 (when total is 0), set to 0 + if ($this->_endno < 0) { + $this->_endno = 0; + } + + // Fetch everything + for ($i = 0, $this->_current = array(); $i < $this->total; $i++) { + $this->_current[] = sql_fetch_assoc($result); + } + // Set the columns to be displayed + $this->_check_listcols(); + // Done + return $this->error; + } + + $this->_lastpage = floor(($this->total - 1) / $this->_pagesize) + 1; + // The output type of floor() is float + settype($this->_lastpage, "integer"); + // If last page is 0 (when total is 0), set to page 1 + if ($this->_lastpage < 1) { + $this->_lastpage = 1; + } + + // Check the page number + $error = $this->_check_pageno(); + if (!is_null($error) && is_null($this->error)) { + $this->error = $error; + } + + // Calculate the start and end record number + $this->_startno = ($this->_pageno - 1) * $this->_pagesize; + $this->_endno = $this->_pageno * $this->_pagesize - 1; + // If there are not enough remaining records, set to the last one + if ($this->_endno > $this->total - 1) { + $this->_endno = $this->total - 1; + } + // If the last record is -1 (when total is 0), set to 0 + if ($this->_endno < 0) { + $this->_endno = 0; + } + // Go to that page + $this->_current = array(); + // If not empty + if ($this->total > 0) { + // Move to startno + sql_seek($result, $this->_startno); + // Fetch until endno + for ($i = $this->_startno; $i <= $this->_endno; $i++) { + $this->_current[] = sql_fetch_assoc($result); + } + } + + // Set the columns to be displayed + $this->_check_listcols(); + // Done + return $this->error; + } + + // _fetch_offset: Fetch the current list with LIMIT and OFFSET. + // Fetching the list in 2 queries: First query the total with count(*) + // and then query only the wanted portion with LIMIT and OFFSET. + // This is faster in MySQL but slower in PostgreSQL. + function _fetch_offset() + { + // See if we need to use views or not. + // Views make things much faster and easier, but some DBMS has no views. + if ($this->_useview) { + $r = $this->_select_with_view(); + } else { + $r = $this->_select_without_view(); + } + + // The number of rows per page + if (is_null($this->_pagesize)) { + $this->_pagesize = userpref("listsize", get_class($this)); + if (is_null($this->_pagesize)) { + $this->_pagesize = $this->_DEFAULT_LIST_SIZE; + } + } + // Paging not in use + if ($this->_pagesize === false) { + $this->_select = sprintf("SELECT %s FROM %s%s%s%s;\n", + $r["cols"], $r["table"], $r["where"], $r["orderby"], $r["limit"]); + $result = sql_query($this->_select); + + // Fetch everything + for ($i = 0, $this->_current = array(); $i < $this->total; $i++) { + $this->_current[] = sql_fetch_assoc($result); + } + + $this->total = sql_num_rows($result); + $this->_lastpage = 1; + $this->_startno = 0; + $this->_endno = $this->total - 1; + // If endno is -1 (when total is 0), set to 0 + if ($this->_endno < 0) { + $this->_endno = 0; + } + + // Set the columns to be displayed + $this->_check_listcols(); + // Done + return $this->error; + } + + // Obtain the total number + $this->_select_total = sprintf("SELECT count(*) AS count FROM %s%s%s;\n", + $r["table"], $r["where"], $r["limit"]); + $result = sql_query($this->_select_total); + $row = sql_fetch_assoc($result); + $this->total = $row["count"]; + $this->_lastpage = floor(($this->total - 1) / $this->_pagesize) + 1; + // The output type of floor() is float + settype($this->_lastpage, "integer"); + // If last page is 0 (when total is 0), set to page 1 + if ($this->_lastpage < 1) { + $this->_lastpage = 1; + } + + // Check the page number + $error = $this->_check_pageno(); + if (!is_null($error) && is_null($this->error)) { + $this->error = $error; + } + + // Calculate the start and end record number + $this->_startno = ($this->_pageno - 1) * $this->_pagesize; + $this->_endno = $this->_pageno * $this->_pagesize - 1; + // If there are not enough remaining records, set to the last one + if ($this->_endno > $this->total - 1) { + $this->_endno = $this->total - 1; + } + // If the last record is -1 (when total is 0), set to 0 + if ($this->_endno < 0) { + $this->_endno = 0; + } + + // Obtain everything in this page + $this->_current = array(); + if (!$this->_reverse) { + $this->_select = sprintf("SELECT %s FROM %s%s%s LIMIT %d OFFSET %d;\n", + $r["cols"], $r["table"], $r["where"], $r["orderby"], + $this->_endno - $this->_startno + 1, + $this->_startno); + } else { + $this->_select = sprintf("SELECT %s FROM %s%s%s LIMIT %d OFFSET %d;\n", + $r["cols"], $r["table"], $r["where"], $r["orderby"], + $this->_endno - $this->_startno + 1, + $this->total - $this->_endno - 1); + } + // If not empty + if ($this->total > 0) { + $result = sql_query($this->_select); + $count = sql_num_rows($result); + for ($i = 0; $i < $count; $i++) { + $this->_current[] = sql_fetch_assoc($result); + } + } + + // Set the columns to be displayed + $this->_check_listcols(); + // Done + return $this->error; + } + + // _sql_cols: Obtain the SQL columns list phase + function _sql_cols() + { + // Obtain the columns to list + for ( $i = 0, $this->_coldefs = array(), $cols = array(); + $i < count($this->_cols); $i++) { + $def = $this->_coldef($this->_cols[$i]); + $this->_coldefs[] = array( + "def" => $def, + "alias" => $this->_cols[$i]); + $cols[] = $def . " AS " . $this->_cols[$i]; + } + return implode(", ", $cols); + } + + // _coldef: Column definition for non-view usage + function _coldef($col) + { + // Obtain the column definition + switch ($col) { + case "createdby": + case "updatedby": + return $col . ".name"; + default: + // Multi-lingual columns + if (in_array($col, sql_cols_ml($this->_table))) { + // Default language + if ($this->_lang == DEFAULT_LANG) { + return $this->_table . "." . $col . "_" + . ln($this->_lang, LN_DATABASE); + // Fall back to the default language + } else { + $thiscol = $this->_table . "." . $col . "_" + . ln($this->_lang, LN_DATABASE); + $defcol = $this->_table . "." . $col . "_" + . ln(DEFAULT_LANG, LN_DATABASE); + return "COALESCE(" . $thiscol . ", " . $defcol . ")"; + } + // Ordinary columns + } else { + return $this->_table . "." . $col; + } + } + } + + // _sql_join: Get the SQL JOIN phase + function _sql_join() + { + $join = ""; + $cols = sql_cols_nl($this->_table); + if (in_array("createdby", $cols)) { + $join .= " LEFT JOIN users AS createdby ON " + . $this->_table . ".createdby=createdby.sn"; + } + if (in_array("updatedby", $cols)) { + $join .= " LEFT JOIN users AS updatedby ON " + . $this->_table . ".updatedby=updatedby.sn"; + } + return $join; + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Empty comes from a query + if (!is_null($this->_query)) { + return C_("Nothing found. Please try another query."); + // Empty database + } else { + return C_("The database is empty."); + } + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s record.", + "Your query found %s records.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s record.", + "%s records.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s record, listing %s to %s.", + "Your query found %s records, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s record, listing %s to %s.", + "%s records, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } + + // _echo_colval: Output a list column value + function _echo_colval($col, &$row) + { + // Null/no value + if (is_null($row[$col])) { + echo h_abbr(t_notset()); + + // A brief should be displayed instead + } elseif ( in_array($col, $this->_COLS_BRIEF) + && mb_strlen($row[$col]) > $this->_DEFAULT_BRIEF_LEN) { + // Strip the HTML tags + $text = $row[$col]; + if ( array_key_exists("html", $row) + && $row["html"]) { + $text = strip_tags($text); + } + echo h(mb_substr($text, 0, $this->_DEFAULT_BRIEF_LEN)) . "…"; + + // Always display "pic" column as a thumbnail preview + } elseif ($col == "pic") { + $alt = C_("Picture preview"); + $picid = readpic_content($row[$col], + array("max" => $this->_PIC_THUMBNAIL_SIZE), + $row["sn"], $this->_table); + $PICS =& pic_deposit(); + $pic = $PICS[$picid]; + echopic_thumbnail($pic, $alt); + + // Always display "att" and "pdf" columns as their sizes + } elseif ($col == "att" || $col == "pdf") { + echo h_abbr(report_size(strlen($row[$col]))); + + // Always display "_urlcheck" column as URL. checking status + } elseif ($col == "_urlcheck") { + echo h($row[$col]); + + // Ordinary columns + } else { + echo h($row[$col]); + } + return; + } + + ///////////////////////// + // Methods belows are private. Do not call them directly. + // Do not override them, either. + ///////////////////////// + // _check_pageno: Check the page number + function _check_pageno() + { + // Save it elsewhere and replace with default value temporarily + $pageno = $this->_pageno; + $this->_pageno = !$this->_reverse? 1: $this->_lastpage; + // Page number not specified + if (is_null($pageno)) { + return null; + } + // Text string + if (is_string($pageno)) { + // If it is too long or too short + if (strlen($pageno) > 9) { + return array("msg"=>NC_("Page number (%s) invalid. Please specify a valid page number."), + "margs"=>array($pageno)); + } + // If it is all-digits + if (!preg_match("/^\d+$/", $pageno)) { + return array("msg"=>NC_("Page number (%s) invalid. Please specify a valid page number."), + "margs"=>array($pageno)); + } + // If it is all-digits + if (preg_match("/^0+$/", $pageno)) { + return array("msg"=>NC_("Page number (%s) invalid. Please specify a valid page number."), + "margs"=>array($pageno)); + } + // Convert its type to integer + settype($pageno, "integer"); + } + + // Not an integer still + if (!is_int($pageno)) { + return array("msg"=>NC_("Page number (%s) invalid. Please specify a valid page number."), + "margs"=>array($pageno)); + } + // Out of range + if (!is_null($this->_lastpage) && $pageno > $this->_lastpage) { + return array("msg"=>NC_("Page number (%d) out of range. Please specify a number between 1 and %d."), + "margs"=>array($pageno, $this->_lastpage)); + } + // OK + $this->_pageno = $pageno; + return null; + } + + // _select_with_view: Obtain the SQL statement with views + // This makes life easier *^_^* + function _select_with_view() + { + // Obtain the view name + if (is_null($this->_view)) { + $this->_view = $this->_table . "_list"; + if (count($GLOBALS["ALL_LINGUAS"]) > 1) { + $this->_view .= "_" . ln($this->_lang, LN_DATABASE); + } + } + // Obtain the available columns + if (is_null($this->_cols)) { + $this->_cols = sql_cols($this->_view); + } + + // Obtain the SQL WHERE phase + $where = $this->_sql_filter(); + // Obtain the SQL ORDER BY phase + $orderby = $this->_sql_orderby(); + // Obtain the LIMIT phase + $limit = !is_null($this->_limit)? " LIMIT " . $this->_limit: ""; + + // Compose the SQL query + return array( + "cols" => "*", + "table" => $this->_view, + "where" => $where, + "orderby" => $orderby, + "limit" => $limit, + ); + } + + // _select_without_view: Obtain the SQL statement manually without views + // SQL DBMS without views are to be cursed -- old MySQL does + function _select_without_view() + { + // Obtain the available columns + $this->_cols = sql_cols_nl($this->_table); + $this->_cols = array_diff($this->_cols, array("mtime")); + // _sql_cols() set the column definitions and may alter + // $this->_cols to to get the final columns list + $cols = $this->_sql_cols(); + // Obtain the SQL JOIN phase + $join = $this->_sql_join(); + // Obtain the SQL WHERE phase + $where = $this->_sql_filter(); + // Obtain the SQL ORDER BY phase + $orderby = $this->_sql_orderby(); + // Obtain the LIMIT phase + $limit = !is_null($this->_limit)? " LIMIT " . $this->_limit: ""; + + // Compose the SQL query + return array( + "cols" => $cols, + "table" => $this->_table . $join, + "where" => $where, + "orderby" => $orderby, + "limit" => $limit, + ); + } + + // _sql_filter: Get the SQL WHERE phase + // The returned SQL phrase is always in UTF-8 + function _sql_filter() + { + // No query, return empty string + if (is_null($this->_query)) { + if ( method_exists($this, "_pre_filter") + && !is_null($this->_pre_filter())) { + return " WHERE " . $this->_pre_filter(); + } + return ""; + } + + // Regularize it + $this->_query = trim($this->_query); + // Check if it is filled + if ($this->_query == "") { + $this->error = array("msg"=>NC_("Please fill in your query.")); + if ( method_exists($this, "_pre_filter") + && !is_null($this->_pre_filter())) { + return " WHERE " . $this->_pre_filter(); + } + return ""; + } + + $this->_query_phrases = parse_query($this->_query); + // Bounce if nothing to query + if (count($this->_query_phrases) == 0) { + if ( method_exists($this, "_pre_filter") + && !is_null($this->_pre_filter())) { + return " WHERE " . $this->_pre_filter(); + } + return ""; + } + + // Obtain the columns to query + if ($this->_useview) { + $cols = array_diff($this->_cols, $this->_COLS_NO_SEARCH); + // Use the column definition kept so far + } else { + for ($i = 0, $cols = array(); $i < count($this->_coldefs); $i++) { + // Columns that should not be searched against + if (in_array($this->_coldefs[$i]["alias"], $this->_COLS_NO_SEARCH)) { + continue; + } + $cols[] = $this->_coldefs[$i]["def"]; + } + } + + // Compose the query condition + $conds = array(); + // Obtain each phase + foreach ($this->_query_phrases as $phrase) { + $subconds = array(); + foreach ($cols as $col) { + if ($GLOBALS["SQL_DBTYPE"] == SQL_POSTGRESQL) { + $subconds[] = "cast($col AS text) ILIKE '%" . sql_esclike($phrase) . "%'"; + } else { + $subconds[] = "cast($col AS text) LIKE '%" . sql_esclike($phrase) . "%'"; + } + } + $conds[] = implode(" OR ", $subconds); + } + // Append the the pre-defined filter + if ( method_exists($this, "_pre_filter") + && !is_null($this->_pre_filter())) { + $conds[] = $this->_pre_filter(); + } + // Compose the statement + if (count($conds) == 1) { + $sql = $conds[0]; + } else { + $conds0 = array(); + foreach ($conds as $cond) { + $conds0[] = "($cond)"; + } + $sql = implode(" AND ", $conds0); + } + // Append WHERE + return " WHERE " . $sql; + } + + // _compose_query_key: Compose the query key from the query phrases + function _compose_query_key() + { + // Bounce if there is no query phrases + if (count($this->_query_phrases) == 0) { + return ""; + } + for ($i = 0, $phrases = array(); $i < count($this->_query_phrases); $i++) { + $phreses[] = "\"" . addslashes($this->_query_phrases[$i]) . "\""; + } + return implode(",", $phreses); + } + + // _sql_orderby: Get the SQL ORDER BY phase + function _sql_orderby() + { + // Parse the "sortby" argument + $this->_parse_sortby($this->_sortby); + // Check the sort keys, and empty them if invalid + $error = $this->_check_sortkeys(); + if (!is_null($error)) { + if (is_null($this->error)) { + $this->error = $error; + } + $this->_sortkeys = array(); + } + // Apply _DEFAULT_SORTBY if not in a view + if ( count($this->_sortkeys) == 0 + && !$this->_useview + && !is_null($this->_DEFAULT_SORTBY)) { + // Parse the _DEFAULT_SORTBY argument + $this->_parse_sortby($this->_DEFAULT_SORTBY); + // Check the sort keys, and empty them if invalid + $error = $this->_check_sortkeys(); + if (!is_null($error)) { + if (is_null($this->error)) { + $this->error = $error; + } + $this->_sortkeys = array(); + } + } + // Set the "sortby" attribute + $this->_compose_sortby(); + + // Bounce if there is no sorting key + if (count($this->_sortkeys) == 0) { + return ""; + } + + // Obtain the corresponding SQL phrase + for ($i = 0, $phrases = array(); $i < count($this->_sortkeys); $i++) { + $phrases[] = $this->_sortkeys[$i]["sql"]; + } + $sql = " ORDER BY " . implode(", ", $phrases); + + return $sql; + } + + // _parse_sortby: Parse the "sortby" argument + // $sortby argument should be specified as "key1,-key2,...", + // where initial minus (-) before the key means decreasing. + function _parse_sortby($sortby) + { + $this->_sortkeys = array(); + // Bounce for nothing + if (is_null($sortby)) { + return; + } + $sortby = trim($sortby); + // Bounce if $sortby is empty + if ($sortby == "") { + return; + } + + // Split by comma + $phrases = explode(",", $sortby); + for ($i = 0; $i < count($phrases); $i++) { + // Compose the sort key + $key = trim($phrases[$i]); + $desc = false; + $sql = $key; + // Check the decreasing flag with the initial "-" sign + if (substr($key, 0, 1) == "-") { + $key = trim(substr($key, 1)); + $desc = true; + $sql = "$key DESC"; + } + // Add this sort key + $this->_sortkeys[] = array( + "key" => $key, + "desc" => $desc, + "sql" => $sql, + ); + } + + return; + } + + // _check_sortkeys: Check if the sorting keys are valid + function _check_sortkeys() + { + // Skip if nothing to check + if (count($this->_sortkeys) == 0) { + return null; + } + + // Obtain the valid sorting keys + if ($this->_useview) { + $validkeys = array_diff($this->_cols, $this->_COLS_NO_SORT_BY); + // Check each candidate + for ($i = 0; $i < count($this->_sortkeys); $i++) { + if (!in_array($this->_sortkeys[$i]["key"], $validkeys)) { + return array("msg"=>NC_("You cannot sort by \"%s\"."), + "margs"=>array($this->_sortkeys[$i]["key"])); + } + } + // Use the column definition kept so far + } else { + // Turn to associative array + for ($i = 0, $coldefs = array(); $i < count($this->_coldefs); $i++) { + $coldefs[$this->_coldefs[$i]["alias"]] = $this->_coldefs[$i]["def"]; + } + // Check each candidate + for ($i = 0; $i < count($this->_sortkeys); $i++) { + if (!array_key_exists($this->_sortkeys[$i]["key"], $coldefs)) { + return array("msg"=>NC_("You cannot sort by \"%s\"."), + "margs"=>array($this->_sortkeys[$i]["key"])); + } + // Reset the SQL according to the column definition + $this->_sortkeys[$i]["sql"] = $coldefs[$this->_sortkeys[$i]["key"]]; + if ($this->_sortkeys[$i]["desc"]) { + $this->_sortkeys[$i]["sql"] .= " DESC"; + } + } + } + + // OK + return null; + } + + // _compose_sortby: Compose the "sortby" argument from sorting keys + function _compose_sortby() + { + // Bounce if there is no sorting keys + if (count($this->_sortkeys) == 0) { + $this->_sortby = ""; + return; + } + for ($i = 0, $sortbys = array(); $i < count($this->_sortkeys); $i++) { + if ($this->_sortkeys[$i]["desc"]) { + $sortbys[] = "-" . $this->_sortkeys[$i]["key"]; + } else { + $sortbys[] = $this->_sortkeys[$i]["key"]; + } + } + $this->_sortby = implode(",", $sortbys); + return; + } + + // _cols: Obtain the list columns + // To be removed. Use $this->_cols instead. + function _cols() + { + // Obtain the available column list when not set yet + if (is_null($this->_cols)) { + $this->_cols = sql_cols_nl($this->_table); + } + return $this->_cols; + } + + // _col_labels: Set the column labels + function _col_labels($labels) + { + $this->_col_labels = array_merge($this->_col_labels, $labels); + } + + // _check_listcols: Set the columns to be displayed + function _check_listcols() + { + // The columns to be displayed + $userpref = userpref("listcols", get_class($this)); + if (!is_null($userpref)) { + $listcols = explode(" ", $userpref); + } else { + $listcols = $this->_DEFAULT_LIST_COLS; + } + // Obtain the columns to list + $validcols = array_diff($this->_cols, $this->_COLS_NO_DISPLAY); + $this->_listcols = array_intersect($listcols, $validcols); + return; + } + + // _query_abstract: Get the abstract regarding to the query phrase + // It always work on the "body" column + function _query_abstract($body, $html = false, $queries = null) + { + // Default to the current query phrases + if (is_null($queries)) { + $queries = $this->_query_phrases; + } + // A single query phrase is provided + if (!is_array($queries)) { + $queries = array($queries); + } + // Return nothing if body is empty + if (is_null($body)) { + return null; + } + // Strip the HTML tags + if ($html) { + $body = str_replace("", "\"", $body); + $body = str_replace("", "\"", $body); + $body = strip_tags($body); + $body = dh($body); + } + // Trim excess spaces + $body = preg_replace("/\s+/", " ", $body); + // Sort the query phrases by their lengths, shortest first + usort($queries, "_list_cmp_query"); + // Gather the abstract of each query phrase + $bodylen = mb_strlen($body); + for ($i = 0, $ranges = array(); $i < count($queries); $i++) { + $len = mb_strlen($queries[$i]); + $base = 0; + $query = addslashes_re_php($queries[$i]); + // Gather each match + while (preg_match("/^(.*?)$query/i", + mb_substr($body, $base), $m)) { + $pos = $base + mb_strlen($m[1]); + $start = $pos - $this->_QABS_SPAN; + if ($start < 0) { + $start = 0; + } + $end = $pos + $len + $this->_QABS_SPAN; + if ($end >= $bodylen) { + $end = $bodylen - 1; + } + $ranges[] = array( + "start" => $start, + "end" => $end, + ); + $base = $pos + $len; + } + } + // Sanity check + if (count($ranges) == 0) { + return null; + } + // Sort the ranges + usort($ranges, "_list_cmp_range"); + + // Get the union of the ranges + $union = array(); + $i = 0; + $start = $ranges[0]["start"]; + $end = $ranges[0]["end"]; + while (true) { + // Find the next segment that exceeds the current segment + for ( ; $i < count($ranges) && $ranges[$i]["end"] <= $end; $i++) {}; + // Meet the last entry + if ($i == count($ranges)) { + // Save the last segment + $union[] = array( + "start" => $start, + "end" => $end, + "len" => $end - $start, + "text" => mb_substr($body, $start, $end - $start), + ); + break; + } + // A new segment seperated from the current segment + if ($ranges[$i]["start"] > $end) { + // Save the last segment + $union[] = array( + "start" => $start, + "end" => $end, + "len" => $end - $start, + "text" => mb_substr($body, $start, $end - $start), + ); + // Start a new segment + $start = $ranges[$i]["start"]; + $end = $ranges[$i]["end"]; + continue; + } + // Expend the current segment + $end = $ranges[$i]["end"]; + continue; + } + + // Trim the union + $len_andsoon = 1; + $len = 0; + if ($union[0]["start"] != 0) { + $len += $len_andsoon; + } + $reached_maximum = false; + for ($i = 0; $i < count($union) - 1; $i++) { + $needlen = $union[$i]["len"] + $len_andsoon; + // Not even enough for an abstract section + if ($len + $len_andsoon > $this->_QABS_MAXLEN) { + $reached_maximum = true; + // Discard the rest sections + while (count($union) > $i) { + array_pop($union); + } + break; + + // Reached the maximum + } elseif ($len + $needlen > $this->_QABS_MAXLEN) { + $reached_maximum = true; + $union[$i]["len"] = $this->_QABS_MAXLEN - $len - $len_andsoon; + $union[$i]["end"] = $union[$i]["start"] + $union[$i]["len"]; + $union[$i]["text"] = mb_substr($body, $union[$i]["start"], + $union[$i]["len"]); + // Discard the rest sections + while (count($union) > $i + 1) { + array_pop($union); + } + break; + } + // Not reached the maximum yet + $len += $union[$i]["len"] + $len_andsoon; + } + // Not reached the maximum yet - check the last section + if (!$reached_maximum) { + $i = count($union) - 1; + $needlen = $union[$i]["len"]; + if ($union[$i]["end"] != $bodylen) { + $needlen += $len_andsoon; + } + // Not even enough for an abstract section + if ($len + $len_andsoon > $this->_QABS_MAXLEN) { + // Forget it. We can do nothing now. + array_pop($union); + + // Reached the maximum + } elseif ($len + $needlen > $this->_QABS_MAXLEN) { + $union[$i]["len"] = $this->_QABS_MAXLEN - $len - $len_andsoon; + $union[$i]["end"] = $union[$i]["start"] + $union[$i]["len"]; + $union[$i]["text"] = mb_substr($body, $union[$i]["start"], + $union[$i]["len"]); + } + // Not reached the maximum yet + } + + // Mark the query phrases + for ($i = 0, $union_text = array(); $i < count($union); $i++) { + $pieces = array( + array( + "text" => $union[$i]["text"], + "is_match" => false, + ), + ); + // Mark each query phrase + for ($j = 0; $j < count($queries); $j++) { + $query = addslashes_re_php($queries[$j]); + for ($k = 0; $k < count($pieces); $k++) { + // Skip matches of other query phrases + if ($pieces[$k]["is_match"]) { + continue; + } + // Skip if not matched + if (!preg_match("/^(.*?)($query)(.*)$/i", + $pieces[$k]["text"], $m)) { + continue; + } + $pieces = array_merge( + array_slice($pieces, 0, $k), + array( + array( + "text" => $m[1], + "is_match" => false, + ), + array( + "text" => $m[2], + "is_match" => true, + ), + array( + "text" => $m[3], + "is_match" => false, + ), + ), + array_slice($pieces, $k + 1) + ); + $k++; + } + } + for ($j = 0, $text = ""; $j < count($pieces); $j++) { + if ($pieces[$j]["is_match"]) { + $text .= "" . h($pieces[$j]["text"]) . ""; + } else { + $text .= h($pieces[$j]["text"]); + } + } + $union_text[] = $text; + } + + // Join these segments + $abstract = implode("…", $union_text); + if ($union[0]["start"] != 0) { + $abstract = "…" . $abstract; + } + if ($union[count($union)-1]["end"] != $bodylen) { + $abstract .= "…"; + } + + return $abstract; + } + + // _html_title: Display the title + // Make it a null function + function _html_title() + { + return; + } + + // _html_errmsg: Display the error message + function _html_errmsg() + { + if (is_null($this->error)) { + return; + } + $message = err2msg($this->error); +?>

    + +lists_switch) || count($this->lists_switch) == 0) { + return; + } + +?>
    +lists_switch); $i++) { + $htmls[] = " lists_switch[$i]["url"]) . "\">" + . h($this->lists_switch[$i]["title"]) . ""; + } + echo implode(" |\n", $htmls); +?>
    + +_is_called_form) { + return; + } + if (is_null($prompt) || $prompt === false) { + return; + } + // Start from the default language + $is_ml_table = !is_null($this->_is_ml_table)? $this->_is_ml_table: + sql_is_ml_table($this->_table); + if ($is_ml_table && $this->_lang != DEFAULT_LANG) { + return; + } + $url = REQUEST_FILEQS; + // Remove list parameters + $url = rem_get_arg($url, array("query", "sortby", "pageno", "form", "formid", "statid")); + $url = add_get_arg($url, "form", "new", DUP_OK); +?>

    + +_fetched + && !is_null($this->total) && $this->total == 0 + && is_null($this->_query)) { + return; + } + + $label = C_("Search"); + +?>
    + +
    + +total)) { + return; + } + $message = $this->_liststat_message(); + if (is_null($message)) { + return; + } +?>

    + +total)) { + return; + } + // Fit in one page - paging is not needed + if ($this->_lastpage <= 1) { + return; + } + + // Cache the result + static $cache; + // Cached before + if (isset($cache)) { + echo $cache; + return; + } + + // Fewer than 5 pages + if ($this->_lastpage <= 5) { + $startpage = 1; + $endpage = $this->_lastpage; + // Near the beginning + } elseif ($this->_pageno < 3) { + $startpage = 1; + $endpage = 5; + // Near the end + } elseif ($this->_pageno > $this->_lastpage - 2) { + $startpage = $this->_lastpage - 4; + $endpage = $this->_lastpage; + // Normal, at the middle + } else { + $startpage = $this->_pageno - 2; + $endpage = $this->_pageno + 2; + } + + // Start output + // Cache it! + ob_start(); + // Static page -- Display the index + if ($this->_static) { +?>
    + | +
    +
    +_is_called_form) { +?> + +_query)) { +?> +_sortby) && $this->_sortby != "") { +?> +_pageno != 1) { + if ($this->_static) { + $url = sprintf($this->_static_filepat, 1); + } elseif ($this->_reverse) { + $url = add_get_arg($baseurl, "pageno", 1, DUP_OK); + } else { + $url = $baseurl; + } + $cell = "" . $cell . ""; + } + echo " $cell |\n"; + // The previous page + $cell = h(C_("Previous")); + if ($this->_pageno != 1) { + if ($this->_static) { + $url = sprintf($this->_static_filepat, $this->_pageno - 1); + } elseif ($this->_reverse || $this->_pageno - 1 != 1) { + $url = add_get_arg($baseurl, "pageno", $this->_pageno - 1, DUP_OK); + } else { + $url = $baseurl; + } + $cell = "" . $cell . ""; + } + echo " $cell |\n"; + + // Pages before + for ($i = $startpage; $i < $this->_pageno; $i++) { + $cell = h($i); + if ($this->_static) { + $url = sprintf($this->_static_filepat, $i); + } elseif ($this->_reverse || $i != 1) { + $url = add_get_arg($baseurl, "pageno", $i, DUP_OK); + } else { + $url = $baseurl; + } + $cell = "" . $cell . ""; + echo " $cell |\n"; + } + // Current page + $cell = h($this->_pageno); + echo " $cell |\n"; + // Pages after + for ($i = $this->_pageno + 1; $i <= $endpage; $i++) { + $cell = h($i); + if ($this->_static) { + if ( !is_null($this->_static_lastfile) + && $i == $this->_lastpage) { + $url = $this->_static_lastfile; + } else { + $url = sprintf($this->_static_filepat, $i); + } + } elseif (!$this->_reverse || $i != $this->_lastpage) { + $url = add_get_arg($baseurl, "pageno", $i, DUP_OK); + } else { + $url = $baseurl; + } + $cell = "" . $cell . ""; + echo " $cell |\n"; + } + + // The next page + $cell = h(C_("Next")); + if ($this->_pageno != $this->_lastpage) { + if ($this->_static) { + if ( !is_null($this->_static_lastfile) + && $this->_pageno + 1 == $this->_lastpage) { + $url = $this->_static_lastfile; + } else { + $url = sprintf($this->_static_filepat, $this->_pageno + 1); + } + } elseif (!$this->_reverse || $this->_pageno + 1 != $this->_lastpage) { + $url = add_get_arg($baseurl, "pageno", $this->_pageno + 1, DUP_OK); + } else { + $url = $baseurl; + } + $cell = "" . $cell . ""; + } + echo " $cell |\n"; + // The last page + $cell = h(C_("Last")); + if ($this->_pageno != $this->_lastpage) { + if ($this->_static) { + if (!is_null($this->_static_lastfile)) { + $url = $this->_static_lastfile; + } else { + $url = sprintf($this->_static_filepat, $this->_lastpage); + } + } elseif (!$this->_reverse) { + $url = add_get_arg($baseurl, "pageno", $this->_lastpage, DUP_OK); + } else { + $url = $baseurl; + } + $cell = "" . $cell . ""; + } + echo " $cell\n"; + + if ($this->_static) { +?>
    + + + + +
    + + +total)) { + return; + } + // No record to be listed + if ($this->total == 0) { + return; + } + + // Remove "sortby" from the URL. first + $baseurl = REQUEST_FILEQS; + $baseurl = rem_get_arg($baseurl, array("formid", "statid", "sortby", "pageno")); + + // Check the URL. first + if (in_array("_urlcheck", $this->_listcols)) { + urlcheck($this->_current); + } + // Mass deletion -- surround it with a form + if ($this->_massdel && !$this->_is_called_form) { + $massdel = C_("Delete the selected items."); +?>
    +
    + +_nonumber) { + echo ""; + } + if ($this->_massdel && !$this->_is_called_form) { + echo ""; + } + if (in_array("_viewurl", $this->_cols) && !$this->_is_called_form) { + echo ""; + } + if (!$this->_noselect) { + echo ""; + } + for ($i = 0; $i < count($this->_listcols); $i++) { + echo ""; + } +?> + + +_nonumber) { +?> +_massdel && !$this->_is_called_form) { +?> +_cols) && !$this->_is_called_form) { +?> +_noselect) { +?> +_listcols as $col) { + $label = array_key_exists($col, $this->_col_labels)? + $this->_col_labels[$col]: $col; + if ($this->_nosortby || in_array($col, $this->_COLS_NO_SORT_BY)) { +?> +_sortby == $col)? "-" . $col: $col), DUP_OK); +?> + + + +_current); $i++) { + $no = $this->_startno + $i + 1; + $rowclass = ($i % 2 == 0)? "evenrow": "oddrow"; + $current =& $this->_current[$i]; + $issel = ((!in_array("_sel", $this->_cols) || $current["_sel"]) + && !$this->_noselect); + // The URL. to handle the selection + if ($issel) { + if ( array_key_exists("_selurl", $current) + && !$this->_is_called_form) { + $selurl = $current["_selurl"]; + } else { + $selurl = sprintf($this->_selurl_tmpl, $current["sn"]); + } + } + +?> +_nonumber) { +?> +_massdel && !$this->_is_called_form) { + $name = "delsn" . $current["sn"]; +?> +_cols) && !$this->_is_called_form) { + if (is_null($current["_viewurl"])) { +?> + +_noselect) { +?> +_listcols as $col) { +?> + + +
    _seltext); ?>
    _seltext); ?>_echo_colval($col, $current); ?>
    + +_massdel && !$this->_is_called_form) { + $massdel = C_("Delete the selected items."); +?>
    +
    + +_col_labels)? + $this->_col_labels[$col]: $col; + if ($this->_nosortby || in_array($col, $this->_COLS_NO_SORT_BY)) { +?> +_sortby == $col)? "-" . $col: $col), DUP_OK); +?> +total)) { + return; + } + // No record to be listed + if ($this->total == 0) { + return; + } + // Return if users preferences are not available + if (!use_users() || !isset($_SESSION) || is_null(get_login_sn())) { + return; + } + $submit = C_("Set"); + // The referer + $referer = rem_get_arg(REQUEST_FULLURI, "statid"); + + // Obtain the columns to list + $validcols = array_diff($this->_cols, $this->_COLS_NO_DISPLAY); + +?>
    +

    + + + + +_col_labels)? $this->_col_labels[$col]: + $col; + $name = "listcols_" . $col; +?>_listcols)) { + echo " checked=\"checked\""; + } +?> /> +

    +
    + +title = $this->_is_called_form? C_("Select a User"): + C_("Manage Users"); + // The default sort order + $this->_DEFAULT_SORTBY = "id"; + // Column labels + $this->_col_labels(array( + "id" => C_("User ID."), + "name" => C_("Full name"), + "deleted" => C_("Deleted?"), + "lang" => C_("Pref. language"), + "visits" => C_("Visits"), + "visited" => C_("Visited"), + "ip" => C_("IP"), + "host" => C_("Host"), + "ct" => C_("From country"), + "fails" => C_("Fail logins"), + )); + } + + // _sql_cols: Obtain the SQL columns list phase + function _sql_cols() + { + // Adjust the column list + $this->_cols = array_values(array_diff($this->_cols, + array("passwd"))); + // Run the parent method + return parent::_sql_cols(); + } + + // _coldef: Column definition for non-view usage + function _coldef($col) + { + // Obtain the column definition + switch ($col) { + case "lang": + $cases = array(); + foreach (array_keys($GLOBALS["LNINFO"]) as $lang) { + $cases[] = "WHEN '" . sql_esctext($lang) . "'" + . " THEN '" . sql_esctext(ln($lang, LN_DESC_CURLC)) . "'"; + } + return "CASE " . $this->_table . "." . $col . " " + . implode(" ", $cases) . " END"; + case "disabled": + return "CASE WHEN " . sql_is_true($this->_table . "." . $col) + . " THEN '" . sql_esctext(C_("Disabled")) . "'" + . " ELSE '' END"; + case "deleted": + return "CASE WHEN " . sql_is_true($this->_table . "." . $col) + . " THEN '" . sql_esctext(C_("Deleted")) . "'" + . " ELSE '' END"; + default: + return parent::_coldef($col); + } + } + + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Add a new user account."); + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for a user:"); + } + // Run the parent method + return parent::_html_search($prompt); + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s user.", + "Your query found %s users.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s user.", + "%s users.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s user, listing %s to %s.", + "Your query found %s users, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s user, listing %s to %s.", + "%s users, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } +} + +// GroupsList: Groups list handler class +class GroupsList extends BaseList +{ + // __construct: Initialize the handler + function __construct($FORM = null, $table = "groups") + { + parent::__construct($FORM, $table); + // The page title + $this->title = $this->_is_called_form? C_("Select a Group"): + C_("Manage Groups"); + // The default sort order + $this->_DEFAULT_SORTBY = "id"; + // Column labels + $this->_col_labels(array( + "id" => C_("Group ID."), + )); + } + + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Add a new group."); + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for a group:"); + } + // Run the parent method + return parent::_html_search($prompt); + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s group.", + "Your query found %s groups.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s group.", + "%s groups.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s group, listing %s to %s.", + "Your query found %s groups, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s group, listing %s to %s.", + "%s groups, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } +} + +// UserMembershipsList: User memberships list handler class +class UserMembershipsList extends BaseList +{ + // __construct: Initialize the handler + function __construct($FORM = null, $table = "usermem") + { + parent::__construct($FORM, $table); + // The page title + $this->title = $this->_is_called_form? + C_("Select a User Membership Record"): + C_("Manage User Membership"); + // The default sort order + $this->_DEFAULT_SORTBY = "grp,member"; + // Column labels + $this->_col_labels(array( + "grp" => C_("Group"), + "member" => C_("Member"), + )); + } + + // _coldef: Column definition for non-view usage + function _coldef($col) + { + // Obtain the column definition + switch ($col) { + case "grp": + // Default language + if ($this->_lang == DEFAULT_LANG) { + return sql_strcat("groups.id", "' ('", + "groups.dsc_" . ln($this->_lang, LN_DATABASE), "')'"); + // Fall back to the default language + } else { + $thiscol = "groups.dsc_" + . ln($this->_lang, LN_DATABASE); + $defcol = "groups.dsc_" + . ln(DEFAULT_LANG, LN_DATABASE); + return sql_strcat("groups.id", "' ('", + "COALESCE($thiscol, $defcol)", "')'"); + } + case "member": + return sql_strcat("usrmembers.id", "' ('", "usrmembers.name", "')'"); + default: + return parent::_coldef($col); + } + } + + // _sql_join: Get the SQL JOIN phase + function _sql_join() + { + $join = ""; + $join .= " LEFT JOIN groups ON " . $this->_table . ".grp=groups.sn"; + $join .= " LEFT JOIN users AS usrmembers ON " . $this->_table . ".member=usrmembers.sn"; + return $join . parent::_sql_join(); + } + + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Add a new membership record."); + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for a membership record:"); + } + // Run the parent method + return parent::_html_search($prompt); + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s membership record.", + "Your query found %s membership records.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s membership record.", + "%s membership records.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s membership record, listing %s to %s.", + "Your query found %s membership records, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s membership record, listing %s to %s.", + "%s membership records, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } +} + +// GroupMembershipsList: Group memberships list handler class +class GroupMembershipsList extends BaseList +{ + // __construct: Initialize the handler + function __construct($FORM = null, $table = "groupmem") + { + parent::__construct($FORM, $table); + // The page title + $this->title = $this->_is_called_form? + C_("Select a Group Membership Record"): + C_("Manage Group Membership"); + // The default sort order + $this->_DEFAULT_SORTBY = "grp,member"; + // Column labels + $this->_col_labels(array( + "grp" => C_("Group"), + "member" => C_("Member"), + )); + } + + // _coldef: Column definition for non-view usage + function _coldef($col) + { + // Obtain the column definition + switch ($col) { + case "grp": + // Default language + if ($this->_lang == DEFAULT_LANG) { + return sql_strcat("groups.id", "' ('", + "groups.dsc_" . ln($this->_lang, LN_DATABASE), "')'"); + // Fall back to the default language + } else { + $thiscol = "groups.dsc_" . ln($this->_lang, LN_DATABASE); + $defcol = "groups.dsc_" . ln(DEFAULT_LANG, LN_DATABASE); + return sql_strcat("groups.id", "' ('", + "COALESCE($thiscol, $defcol)", "')'"); + } + case "member": + // Default language + if ($this->_lang == DEFAULT_LANG) { + return sql_strcat("grpmembers.id", "' ('", + "grpmembers.dsc_" . ln($this->_lang, LN_DATABASE), "')'"); + // Fall back to the default language + } else { + $thiscol = "grpmembers.dsc_" . ln($this->_lang, LN_DATABASE); + $defcol = "grpmembers.dsc_" . ln(DEFAULT_LANG, LN_DATABASE); + return sql_strcat("grpmembers.id", "' ('", + "COALESCE($thiscol, $defcol)", "')'"); + } + default: + return parent::_coldef($col); + } + } + + // _sql_join: Get the SQL JOIN phase + function _sql_join() + { + $join = ""; + $join .= " LEFT JOIN groups ON " . $this->_table . ".grp=groups.sn"; + $join .= " LEFT JOIN groups AS grpmembers ON " . $this->_table . ".member=grpmembers.sn"; + return $join . parent::_sql_join(); + } + + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Add a new membership record."); + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for a membership record:"); + } + // Run the parent method + return parent::_html_search($prompt); + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s membership record.", + "Your query found %s membership records.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s membership record.", + "%s membership records.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s membership record, listing %s to %s.", + "Your query found %s membership records, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s membership record, listing %s to %s.", + "%s membership records, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } +} + +// ScriptPrivilegesList: Script privileges list handler class +class ScriptPrivilegesList extends BaseList +{ + // __construct: Initialize the handler + function __construct($FORM = null, $table = "scptpriv") + { + parent::__construct($FORM, $table); + // The page title + $this->title = $this->_is_called_form? + C_("Select a Script Privilege Record"): + C_("Manage Script Privileges"); + // The default sort order + $this->_DEFAULT_SORTBY = "script,grp"; + // Column labels + $this->_col_labels(array( + "script" => C_("Script"), + "grp" => C_("Privilege"), + )); + } + + // _coldef: Column definition for non-view usage + function _coldef($col) + { + // Obtain the column definition + switch ($col) { + case "grp": + // Default language + if ($this->_lang == DEFAULT_LANG) { + return sql_strcat("groups.id", "' ('", + "groups.dsc_" . ln($this->_lang, LN_DATABASE), "')'"); + // Fall back to the default language + } else { + $thiscol = "groups.dsc_" . ln($this->_lang, LN_DATABASE); + $defcol = "groups.dsc_" . ln(DEFAULT_LANG, LN_DATABASE); + return sql_strcat("groups.id", "' ('", + "COALESCE($thiscol, $defcol)", "')'"); + } + default: + return parent::_coldef($col); + } + } + + // _sql_join: Get the SQL JOIN phase + function _sql_join() + { + $join = ""; + $join .= " LEFT JOIN groups ON " . $this->_table . ".grp=groups.sn"; + return $join . parent::_sql_join(); + } + + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Add a new script privilege record."); + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for a script privilege record:"); + } + // Run the parent method + return parent::_html_search($prompt); + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s script privilege record.", + "Your query found %s script privilege records.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s script privilege record.", + "%s script privilege records.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s script privilege record, listing %s to %s.", + "Your query found %s script privilege records, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s script privilege record, listing %s to %s.", + "%s script privilege records, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } +} + +// UserPreferencesList: User preferences list handler class +class UserPreferencesList extends BaseList +{ + // __construct: Initialize the handler + function __construct($FORM = null, $table = "userpref") + { + parent::__construct($FORM, $table); + // The page title + $this->title = $this->_is_called_form? + C_("Select a User Preference"): + C_("Manage User Preferences"); + // The default sort order + $this->_DEFAULT_SORTBY = "domain,usr,name"; + // Columns that should display its brief instead + $this->_COLS_BRIEF = array("value"); + // Column labels + $this->_col_labels(array( + "usr" => C_("User"), + "domain" => C_("Domain"), + "value" => C_("Value"), + )); + } + + // _coldef: Column definition for non-view usage + function _coldef($col) + { + // Obtain the column definition + switch ($col) { + case "usr": + return "CASE WHEN " . $this->_table . ".usr IS NOT NULL" + . " THEN users.name" + . " ELSE '" . sql_esctext(C_("Everyone")) . "' END"; + case "domain": + return "CASE WHEN " . $this->_table . ".domain IS NOT NULL" + . " THEN " . $this->_table . ".domain" + . " ELSE '" . sql_esctext(C_("Everywhere")) . "' END"; + default: + return parent::_coldef($col); + } + } + + // _sql_join: Get the SQL JOIN phase + function _sql_join() + { + $join = ""; + $join = " LEFT JOIN users ON " . $this->_table . ".usr=users.sn"; + return $join . parent::_sql_join(); + } + + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Add a new user preference."); + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for a user preference:"); + } + // Run the parent method + return parent::_html_search($prompt); + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s user preference.", + "Your query found %s user preferences.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s user preference.", + "%s user preferences.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s user preference, listing %s to %s.", + "Your query found %s user preferences, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s user preference, listing %s to %s.", + "%s user preferences, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } +} + +// UserRequestsList: User requests list handler class +class UserRequestsList extends BaseList +{ + // __construct: Initialize the handler + function __construct($FORM = null, $table = "userreq") + { + parent::__construct($FORM, $table); + // The page title + $this->title = $this->_is_called_form? C_("Select a User Request"): + C_("Manage User Requests"); + // Columns that should display its brief instead + $this->_COLS_BRIEF = array("args"); + // Column labels + $this->_col_labels(array( + "type" => C_("Type"), + "usr" => C_("User"), + "args" => C_("Arguments"), + "expire" => C_("Expiration"), + )); + } + + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Add a new user request."); + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for a user request:"); + } + // Run the parent method + return parent::_html_search($prompt); + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query) && $this->_query != "") { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s user request.", + "Your query found %s user requests.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s user request.", + "%s user requests.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query) && $this->_query != "") { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s user request, listing %s to %s.", + "Your query found %s user requests, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s user request, listing %s to %s.", + "%s user requests, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } +} + +// BaseCategoriesList: Base categories list handler class +class BaseCategoriesList extends BaseList +{ + // __construct: Initialize the handler + function __construct($FORM = null, $table = null) + { + parent::__construct($FORM, $table); + // The default sort order + $this->_DEFAULT_SORTBY = "ord,id"; + } + + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Add a new category."); + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for a category:"); + } + // Run the parent method + return parent::_html_search($prompt); + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query) && $this->_query != "") { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s category.", + "Your query found %s categories.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s category.", + "%s categories.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query) && $this->_query != "") { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s category, listing %s to %s.", + "Your query found %s categories, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s category, listing %s to %s.", + "%s categories, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } +} + +// BaseCategorizationList: Base categorization records list handler class +class BaseCategorizationList extends BaseList +{ + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Add a new categorization record."); + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for a categorization record:"); + } + // Run the parent method + return parent::_html_search($prompt); + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query) && $this->_query != "") { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s categorization record.", + "Your query found %s categorization records.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s categorization record.", + "%s categorization records.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query) && $this->_query != "") { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s categorization record, listing %s to %s.", + "Your query found %s categorization records, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s categorization record, listing %s to %s.", + "%s categorization records, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } +} + +// PagesList: Pages list handler class +class PagesList extends BaseList +{ + // __construct: Initialize the handler + function __construct($FORM = null, $table = "pages") + { + parent::__construct($FORM, $table); + // The page title + $this->title = $this->_is_called_form? C_("Select a Page"): + C_("Manage Pages"); + // The default sort order + $this->_DEFAULT_SORTBY = "path"; + // Columns that should display its brief instead + $this->_COLS_BRIEF = array("body"); + } + + // _sql_cols: Obtain the SQL columns list phase + function _sql_cols() + { + // Adjust the column list + $this->_cols = array_merge(array("_viewurl"), $this->_cols); + // Run the parent method + return parent::_sql_cols(); + } + + // _coldef: Column definition for non-view usage + function _coldef($col) + { + // Obtain the column definition + switch ($col) { + case "_viewurl": + return sql_strcat( "'/" . ln($this->_lang, LN_FILENAME) . "'", + $this->_table . ".path"); + case "html": + return "CASE WHEN " . sql_is_true($this->_table . "." . $col) + . " THEN '" . sql_esctext(C_("HTML")) . "'" + . " ELSE '" . sql_esctext(C_("Plain text")) . "' END"; + case "hid": + return "CASE WHEN " . sql_is_true($this->_table . "." . $col) + . " THEN '" . sql_esctext(C_("Hidden")) . "'" + . " ELSE '" . sql_esctext(C_("Shown")) . "' END"; + default: + return parent::_coldef($col); + } + } + + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Write a new page."); + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for a page:"); + } + // Run the parent method + return parent::_html_search($prompt); + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s page.", + "Your query found %s pages.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s page.", + "%s pages.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s page, listing %s to %s.", + "Your query found %s pages, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s page, listing %s to %s.", + "%s pages, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } +} + +// NewsList: News list handler class +class NewsList extends BaseList +{ + // __construct: Initialize the handler + function __construct($FORM = null, $table = "news") + { + parent::__construct($FORM, $table); + // The page title + $this->title = $this->_is_called_form? C_("Select a News Article"): + C_("Manage News"); + // The default sort order + $this->_DEFAULT_SORTBY = "-date,-ord"; + // Columns that should display its brief instead + $this->_COLS_BRIEF = array("body"); + } + + // _sql_cols: Obtain the SQL columns list phase + function _sql_cols() + { + // Adjust the column list + $this->_cols = array_merge(array("_viewurl"), $this->_cols); + // Run the parent method + return parent::_sql_cols(); + } + + // _coldef: Column definition for non-view usage + function _coldef($col) + { + // Obtain the column definition + switch ($col) { + case "_viewurl": + return sql_strcat( "'/" . ln($this->_lang, LN_FILENAME) . "/news'", + $this->_table . ".date"); + case "html": + return "CASE WHEN " . sql_is_true($this->_table . "." . $col) + . " THEN '" . sql_esctext(C_("HTML")) . "'" + . " ELSE '" . sql_esctext(C_("Plain text")) . "' END"; + case "hid": + return "CASE WHEN " . sql_is_true($this->_table . "." . $col) + . " THEN '" . sql_esctext(C_("Hidden")) . "'" + . " ELSE '" . sql_esctext(C_("Shown")) . "' END"; + default: + return parent::_coldef($col); + } + } + + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Write a new news article."); + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for a news article:"); + } + // Run the parent method + return parent::_html_search($prompt); + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s news article.", + "Your query found %s news articles.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s news article.", + "%s news articles.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s news article, listing %s to %s.", + "Your query found %s news articles, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s news article, listing %s to %s.", + "%s news articles, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } +} + +// LinkCategoriesList: Link categories list handler class +class LinkCategoriesList extends BaseCategoriesList +{ + // __construct: Initialize the handler + function __construct($FORM = null, $table = "linkcat") + { + parent::__construct($FORM, $table); + // The page title + $this->title = $this->_is_called_form? C_("Select a Link Category"): + C_("Manage Link Categories"); + } + + // _coldef: Column definition for non-view usage + function _coldef($col) + { + // Obtain the column definition + switch ($col) { + case "parent": + // Default language + if ($this->_lang == DEFAULT_LANG) { + $title = "parent.title_" . ln($this->_lang, LN_DATABASE); + // Fall back to the default language + } else { + $thiscol = "parent.title_" . ln($this->_lang, LN_DATABASE); + $thiscol = "parent.title_" . ln(DEFAULT_LANG, LN_DATABASE); + $title = "COALESCE(" . $thiscol . ", " . $defcol . ")"; + } + return "CASE WHEN " . $this->_table . ".parent IS NOT NULL" + . " THEN $title" + . " ELSE '" . sql_esctext(t_none()) . "' END"; + case "hid": + return "CASE WHEN " . sql_is_true($this->_table . "." . $col) + . " THEN '" . sql_esctext(C_("Hidden")) . "'" + . " ELSE '" . sql_esctext(C_("Shown")) . "' END"; + default: + return parent::_coldef($col); + } + } + + // _sql_join: Get the SQL JOIN phase + function _sql_join() + { + $join = ""; + $join .= " LEFT JOIN links AS parent ON " . $this->_table . ".parent=parent.sn"; + return $join . parent::_sql_join(); + } +} + +// LinksList: Links list handler class +class LinksList extends BaseList +{ + // __construct: Initialize the handler + function __construct($FORM = null, $table = "links") + { + parent::__construct($FORM, $table); + // The page title + $this->title = $this->_is_called_form? C_("Select a Link"): + C_("Manage Links"); + // The default sort order + $this->_DEFAULT_SORTBY = "title"; + // Columns that should display its brief instead + $this->_COLS_BRIEF = array("dsc"); + } + + // _sql_cols: Obtain the SQL columns list phase + function _sql_cols() + { + // Adjust the column list + $this->_cols = array_merge(array("_viewurl"), $this->_cols); + for ($i = 0; $i < count($this->_cols); $i++) { + switch ($this->_cols[$i]) { + // Insert a URL. checker + case "url": + $this->_cols = array_merge( + array_slice($this->_cols, 0, $i+1), + array("_urlcheck"), + array_slice($this->_cols, $i+1)); + $i++; + break; + } + } + // Run the parent method + return parent::_sql_cols(); + } + + // _coldef: Column definition for non-view usage + function _coldef($col) + { + // Obtain the column definition + switch ($col) { + case "_viewurl": + return $this->_table . ".url"; + case "_urlcheck": + return $this->_table . ".url"; + case "hid": + return "CASE WHEN " . sql_is_true($this->_table . "." . $col) + . " THEN '" . sql_esctext(C_("Hidden")) . "'" + . " ELSE '" . sql_esctext(C_("Shown")) . "' END"; + default: + return parent::_coldef($col); + } + } + + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Add a new related link."); + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for a related link:"); + } + // Run the parent method + return parent::_html_search($prompt); + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s related link.", + "Your query found %s related links.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s related link.", + "%s related links.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s related link, listing %s to %s.", + "Your query found %s related links, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s related link, listing %s to %s.", + "%s related links, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } +} + +// LinkCategorizationList: Link categorization records list handler class +class LinkCategorizationList extends BaseCategorizationList +{ + // __construct: Initialize the handler + function __construct($FORM = null, $table = "linkcatz") + { + parent::__construct($FORM, $table); + // The page title + $this->title = $this->_is_called_form? + C_("Select a Link Categorization Record"): + C_("Manage Link Categorization"); + // The default sort order + $this->_DEFAULT_SORTBY = "cat,link"; + // Column labels + $this->_col_labels(array( + "link" => C_("Link"), + )); + } + + // _coldef: Column definition for non-view usage + function _coldef($col) + { + // Obtain the column definition + switch ($col) { + case "cat": + // Default language + if ($this->_lang == DEFAULT_LANG) { + return "linkcat.title_" . ln($this->_lang, LN_DATABASE); + // Fall back to the default language + } else { + $thiscol = "linkcat.title_" . ln($this->_lang, LN_DATABASE); + $thiscol = "linkcat.title_" . ln(DEFAULT_LANG, LN_DATABASE); + return "COALESCE(" . $thiscol . ", " . $defcol . ")"; + } + case "link": + // Default language + if ($this->_lang == DEFAULT_LANG) { + return "links.title_" . ln($this->_lang, LN_DATABASE); + // Fall back to the default language + } else { + $thiscol = "links.title_" . ln($this->_lang, LN_DATABASE); + $thiscol = "links.title_" . ln(DEFAULT_LANG, LN_DATABASE); + return "COALESCE(" . $thiscol . ", " . $defcol . ")"; + } + case "hid": + return "CASE WHEN " . sql_is_true($this->_table . "." . $col) + . " THEN '" . sql_esctext(C_("Hidden")) . "'" + . " ELSE '" . sql_esctext(C_("Shown")) . "' END"; + default: + return parent::_coldef($col); + } + } + + // _sql_join: Get the SQL JOIN phase + function _sql_join() + { + $join = ""; + $join .= " LEFT JOIN linkcat ON " . $this->_table . ".cat=linkcat.sn"; + $join .= " LEFT JOIN links ON " . $this->_table . ".link=links.sn"; + return $join . parent::_sql_join(); + } +} + +// CountriesList: Countries list handler class +class CountriesList extends BaseList +{ + // __construct: Initialize the handler + function __construct($FORM = null, $table = "country") + { + parent::__construct($FORM, $table); + // The page title + $this->title = $this->_is_called_form? C_("Select a Country"): + C_("Manage Country Data"); + // The default sort order + $this->_DEFAULT_SORTBY = "title"; + // Column labels + $this->_col_labels(array( + "id" => C_("Code"), + "name" => C_("Country name"), + "special" => C_("Special?"), + )); + } + + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Add a new country record."); + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for a country:"); + } + // Run the parent method + return parent::_html_search($prompt); + } + + // _liststat_message: Return the current list statistics message + function _liststat_message() + { + // No record to list + if ($this->total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s country.", + "Your query found %s countries.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s country.", + "%s countries.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s country, listing %s to %s.", + "Your query found %s countries, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s country, listing %s to %s.", + "%s countries, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } +} + +// ActivityLogList: Activity log list handler class +class ActivityLogList extends BaseList +{ + protected $_rdgt = 4; + protected $_rows = 4; + + // __construct: Initialize the handler + function __construct($FORM = null, $table = null) + { + parent::__construct($FORM, $table); + // The page title + $this->title = C_("Browse the Activity Log"); + $this->_rows = array_key_exists("rows", $this->_form)? + $this->_form["rows"]: null; + $this->_reverse = true; + } + + // fetch: Fetch the current list. + function fetch() + { + // Fetched before + if ($this->_fetched) { + return $this->error; + } + $this->_fetched = true; + // Initialize the error status + $this->error = null; + + // Check the query phrases + $this->_check_query(); + // Check the number of rows to display + $error = $this->_check_pagesize(); + if (!is_null($error)) { + if (is_null($this->error)) { + $this->error = $error; + } + $this->_pagesize = $this->_DEFAULT_LIST_SIZE; + } elseif (is_null($this->_rows)) { + $this->_pagesize = $this->_DEFAULT_LIST_SIZE; + } else { + $this->_pagesize = $this->_rows; + } + + $fp = fopen(ACTLOG, "r"); + flock($fp, LOCK_SH); + $this->_current = array(); + // Obtain all the log entries + if (count($this->_query_phrases) == 0) { + while (!feof($fp)) { + $line = fgets($fp); + if ($line === false) { + break; + } + $this->_current[] = $line; + } + // Obtain all the matched log entries + } else { + while (!feof($fp)) { + $line = fgets($fp); + if ($line === false) { + break; + } + for ($i = 0, $matched = true; $i < count($this->_query_phrases); $i++) { + if (stripos($line, $this->_query_phrases[$i]) === false) { + $matched = false; + break; + } + } + if ($matched) { + $this->_current[] = $line; + } + } + } + flock($fp, LOCK_UN); + fclose($fp); + $this->total = count($this->_current); + $this->_endno = $this->total - 1; + $this->_startno = 1; + if ($this->total > $this->_pagesize) { + $this->_startno = $this->_endno - $this->_pagesize + 1; + $this->_current = array_slice($this->_current, $this->_startno); + } + $this->_current = array_reverse($this->_current); + + // Done + return $this->error; + } + + // _check_query: Check the query phrases + function _check_query() + { + // No query, return + if (is_null($this->_query)) { + return; + } + + // Regularize it + $this->_query = trim($this->_query); + // Check if it is filled + if ($this->_query == "") { + $this->_query = null; + return; + } + + $this->_query_phrases = parse_query($this->_query); + return; + } + + // _check_pagesize: Check the number of rows to display + function _check_pagesize() + { + // No rows, return + if (is_null($this->_rows)) { + return null; + } + $min = 0; + $max = pow(10, $this->_rdgt) - 1; + // Text string + if (is_string($this->_rows)) { + // Regularize it + $this->_rows = trim($this->_rows); + // Check if it is filled + if ($this->_rows == "") { + return array("msg"=>NC_("Please fill in the number of rows to display.")); + } + // Check the length + if (sql_strlen($this->_rows) > $this->_rdgt) { + return array("msg"=>NC_("This number of rows to display is too long. (Max. length %d)"), + "margs"=>array($this->_rdgt)); + } + // If there is any non-digit character + if (preg_match("/\D/", $this->_rows)) { + return array("msg"=>NC_("Please fill in a positive integer number of rows to display.")); + } + // Check if it is in the valid range + if ($this->_rows < $min) { + return array("msg"=>NC_("The number of rows to display is too small. Please fill in a larger number of rows to display between %d and %d."), + "margs"=>array($min, $max)); + } + // It is not possible to be too large now. + // Convert its type to integer + settype($this->_rows, "integer"); + // Integer + } elseif (is_int($this->_rows)) { + // Check if it is in the valid range + if ($this->_rows < $min) { + return array("msg"=>NC_("The number of rows to display is too small. Please fill in a larger number of rows to display between %d and %d."), + "margs"=>array($min, $max)); + } + if ($this->_rows > $max) { + return array("msg"=>NC_("The number of rows to display is too large. Please fill in a smaller number of rows to display between %d and %d."), + "margs"=>array($min, $max)); + } + // Other types are non-sense + } else { + trigger_error("Unknown type for column \"rows\"", E_USER_ERROR); + } + // OK + return null; + } + + // _html_newlink: Display a link to add a new item + function _html_newlink($prompt = false) + { + if ($prompt === false) { + $prompt = null; + } + // Run the parent method + return parent::_html_newlink($prompt); + } + + // _html_search: Display the search box + function _html_search($prompt = false) + { + if ($prompt === false) { + $prompt = C_("Search for log entries:"); + } + + $label = C_("Display"); + $defquery = C_("(query phrase)"); + $query = !is_null($this->_query) && $this->_query != ""? + $this->_query: $defquery; + $rows = (!is_null($this->_rows)? + $this->_rows: $this->_DEFAULT_LIST_SIZE); + +?>
    + +
    + +total == 0) { + // Inherit the empty list statistics message + return parent::_liststat_message(); + // Fit in one page + } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { + // Result comes from a query + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s log entry.", + "Your query found %s log entries.", + $this->total), + number_format($this->total)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s log entry.", + "%s log entries.", + $this->total), + number_format($this->total)); + } + // More than one page + } else { + if (!is_null($this->_query)) { + return sprintf(dngettext(COMMONDOMAIN, + "Your query found %s log entry, listing %s to %s.", + "Your query found %s log entries, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + // List result + } else { + return sprintf(dngettext(COMMONDOMAIN, + "%s log entry, listing %s to %s.", + "%s log entries, listing %s to %s.", + $this->total), + number_format($this->total), + number_format($this->_startno+1), + number_format($this->_endno+1)); + } + } + } + + // _html_pagebar: Display a page navigation bar + // Make it a null function + function _html_pagebar() + { + return; + } + + // _html_list: List the items + function _html_list() + { + // Don't show the list + if (is_null($this->total)) { + return; + } + // No record to be listed + if ($this->total == 0) { + return; + } + + $html = implode("", $this->_current); + $html = preg_replace_callback("/([\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F])/", + function ($matches) { + return sprintf("\\x%02x", ord($matches[1])); + }, $html); +?>
    +
    + + diff --git a/lib/php/monica/listpref.inc.php b/lib/php/monica/listpref.inc.php new file mode 100644 index 0000000..21bb688 --- /dev/null +++ b/lib/php/monica/listpref.inc.php @@ -0,0 +1,136 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/addget.inc.php"; +require_once "monica/addslash.inc.php"; +require_once "monica/callform.inc.php"; +require_once "monica/checker.inc.php"; +require_once "monica/http.inc.php"; +require_once "monica/process.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/userpref.inc.php"; + +// ListPreference: The list preference handler +class ListPreference +{ + protected $_form = array(); + protected $_referer = null; + protected $_domain = null; + protected $_listcols = null; + + // __construct: Initialize the handler + function __construct(&$form) + { + $this->_form =& $form; + // Set the referer, the domain and the list columns + $this->_set_referer(); + $this->_set_domain(); + } + + // main: Change the list preference + function main() + { + // Lock the necessary tables + $locktable = array("userpref" => LOCK_EX); + sql_lock($locktable); + + $error = $this->_check_post(); + // If an error occurs + if (!is_null($error)) { + $error["isform"] = false; + error_redirect($error); + + // Else, save the data + } else { + $processor = new ListPreferenceProcessor($_POST); + $success = $processor->process(); + http_303($this->_referer); + } + } + + // _check_post: Check the list preference form + function _check_post() + { + // Run the checker + $checker = new ListPreferenceChecker($this->_form); + $error = $checker->check(array("domain", "listcols", "listsize")); + if (!is_null($error)) { + return $error; + } + // OK + return null; + } + + // _set_referer: Obtain the referer to return to + function _set_referer() + { + // Obtained before + if (!is_null($this->_referer)) { + return $this->_referer; + } + // Obtain the source referer + $this->_referer = $this->_source_referer(); + // Remove the status from the referer + $this->_referer = rem_get_arg($this->_referer, "statid"); + return $this->_referer; + } + + // _source_referer: Obtain the source referer + function _source_referer() + { + // Use the POSTed referer + if (array_key_exists("referer", $this->_form)) { + return $this->_form["referer"]; + // Use the referer from the request + } elseif (array_key_exists("HTTP_REFERER", $_SERVER)) { + return $_SERVER["HTTP_REFERER"]; + // Fall back to the myself + } else { + return REQUEST_FULLURI; + } + } + + // _set_domain: Obtain the domain this preference belongs to + function _set_domain() + { + // Obtained before + if (!is_null($this->_domain)) { + return $this->_domain; + } + // Return the supplied domain + if (array_key_exists("domain", $this->_form)) { + $this->_domain = $this->_form["domain"]; + return $this->_domain; + } + // Obtain the referer first + $this->_set_referer(); + // Return the current script path for the most cases + if ($this->_referer == REQUEST_FULLURI) { + $this->_domain = REQUEST_PATH; + $this->_form["domain"] = $this->_domain; + return $this->_domain; + } + + // Parse the referer to get the script path + $url = parse_url($this->_referer); + // Fall back to the root directory if there is no script part + $this->_domain = array_key_exists("path", $url)? $url["path"]: "/"; + // Strip the leading root difference + $ROOTDIFF_RE = addslashes_re_php(ROOT_DIFF); + $this->_domain = preg_replace("/^$ROOTDIFF_RE/", "", $this->_domain); + $this->_form["domain"] = $this->_domain; + return $this->_domain; + } +} + +?> diff --git a/lib/php/monica/lninfo.inc.php b/lib/php/monica/lninfo.inc.php new file mode 100644 index 0000000..f8641ed --- /dev/null +++ b/lib/php/monica/lninfo.inc.php @@ -0,0 +1,381 @@ + +// Copyright: Copyright (C) 2002-2018 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Related subroutines +require_once "monica/getlang.inc.php"; +require_once "monica/gettext.inc.php"; + +// Settings +$LNINFO = array( + "en" => array( + "name" => "en-us", + "filename" => "en", + "charset" => "UTF-8", + "db" => "en", + "htmlid" => "en", + "locale" => "en_US", + "sp_break" => true, + "icase" => true, + "ctfirst" => false, + "longdesc" => N_("English")), + "zh-tw" => array( + "name" => "zh-tw", + "filename" => "zh-tw", + "charset" => "UTF-8", + "db" => "zhtw", + "htmlid" => "zhtw", + "locale" => "zh_TW", + "sp_break" => false, + "icase" => false, + "ctfirst" => true, + "longdesc" => N_("Traditional Chinese")), + "zh-cn" => array( + "name" => "zh-cn", + "filename" => "zh-cn", + "charset" => "UTF-8", + "db" => "zhcn", + "htmlid" => "zhcn", + "locale" => "zh_CN", + "sp_break" => false, + "icase" => false, + "ctfirst" => true, + "longdesc" => N_("Simplified Chinese")), + "zh" => array( + "name" => "zh-tw", + "filename" => "zh", + "charset" => "UTF-8", + "db" => "zh", + "htmlid" => "zh", + "locale" => "zh_TW", + "sp_break" => false, + "icase" => false, + "ctfirst" => true, + "longdesc" => N_("Chinese")), + "ja" => array( + "name" => "ja", + "filename" => "ja", + "charset" => "UTF-8", + "db" => "ja", + "htmlid" => "ja", + "locale" => "ja_JP", + "sp_break" => false, + "icase" => false, + "ctfirst" => true, + "longdesc" => N_("Japanese")), + "ko" => array( + "name" => "ko", + "filename" => "ko", + "charset" => "UTF-8", + "db" => "ko", + "htmlid" => "ko", + "locale" => "ko_KR", + "sp_break" => false, + "icase" => false, + "ctfirst" => true, + "longdesc" => N_("Korean")), + "de" => array( + "name" => "de", + "filename" => "de", + "charset" => "UTF-8", + "db" => "de", + "htmlid" => "de", + "locale" => "de_DE", + "sp_break" => true, + "icase" => true, + "ctfirst" => false, + "longdesc" => N_("German")), + "es" => array( + "name" => "es", + "filename" => "es", + "charset" => "UTF-8", + "db" => "es", + "htmlid" => "es", + "locale" => "es_ES", + "sp_break" => true, + "icase" => true, + "ctfirst" => false, + "longdesc" => N_("Spanish")) +); + +// Constant symbols +define("LN_NAME", 0); +define("LN_CHARSET", 1); +define("LN_FILENAME", 2); +define("LN_LOCALE", 3); +define("LN_DATABASE", 4); +define("LN_HTMLID", 5); +define("LN_SPACE_BREAK", 6); +define("LN_IGNORE_CASE", 7); +define("LN_COUNTRY_FIRST", 8); +define("LN_DESC", 9); +define("LN_DESC_CURLC", 10); +define("LN_DESC_SELFLC", 11); +define("LN_SWITCH_TITLE", 12); + + +// Subroutines +// ln: Uniformed wrapper for everything +function ln($lang, $type) +{ + switch ($type) { + case LN_NAME: + return _lninfo_name($lang); + case LN_CHARSET: + return _lninfo_charset($lang); + case LN_FILENAME: + return _lninfo_filename($lang); + case LN_LOCALE: + return _lninfo_lc($lang); + case LN_DATABASE: + return _lninfo_db($lang); + case LN_HTMLID: + return _lninfo_htmlid($lang); + case LN_SPACE_BREAK: + return _lninfo_space_break($lang); + case LN_IGNORE_CASE: + return _lninfo_ignore_case($lang); + case LN_COUNTRY_FIRST: + return _lninfo_country_first($lang); + case LN_DESC: + return _lninfo_desc($lang); + case LN_DESC_CURLC: + return _lninfo_desc_curlc($lang); + case LN_DESC_SELFLC: + return _lninfo_desc_selflc($lang); + case LN_SWITCH_TITLE: + return _lninfo_switch_title($lang); + default: + return $lang; + } +} + +// selflc: Return the text in its own locale +function selflc($text, $lang) +{ + // Cache the result + static $cache = array(); + // Obtain the language variants of that text + if (!array_key_exists($text, $cache)) { + global $LNINFO; + $curlc = getenv("LANG"); + if ($curlc === false || $curlc == "") { + $curlc = getlang(LN_LOCALE); + } + $cache[$text] = array(); + foreach (array_keys($LNINFO) as $l) { + // Switch the locale + $locale = _lninfo_lc($l); + $charset = _lninfo_charset($l); + putenv("LANG=$locale"); + putenv("LANGUAGE=$locale"); + setlocale(LC_ALL, ""); + // Obtain the localed text + $cache[$text][$l] = _($text); + } + // Return the current locale + putenv("LANG=$curlc"); + putenv("LANGUAGE=$curlc"); + setlocale(LC_ALL, ""); + } + // Not found -- return itself instead + if (!array_key_exists($lang, $cache[$text])) { + return $text; + } + // Return the localed text + return $cache[$text][$lang]; +} + +// _lninfo_name: Language complete name +function _lninfo_name($lang) +{ + global $LNINFO; + return array_key_exists($lang, $LNINFO) + && array_key_exists("name", $LNINFO[$lang])? + $LNINFO[$lang]["name"]: $lang; +} + +// _lninfo_charset: Long description +// Most common charset that is used with the specified language +function _lninfo_charset($lang) +{ + global $LNINFO; + return array_key_exists($lang, $LNINFO) + && array_key_exists("charset", $LNINFO[$lang])? + $LNINFO[$lang]["charset"]: $lang; +} + +// _lninfo_filename: File system name +function _lninfo_filename($lang) +{ + global $LNINFO; + return array_key_exists($lang, $LNINFO) + && array_key_exists("filename", $LNINFO[$lang])? + $LNINFO[$lang]["filename"]: $lang; +} + +// _lninfo_lc: Locale used by GNU glibc and gettext +// Replace hyphens with underscores, and upper-case the district divisions, +// as used in GNU glibc +function _lninfo_lc($lang) +{ + global $LNINFO; + if ( array_key_exists($lang, $LNINFO) + && array_key_exists("locale", $LNINFO[$lang])) { + return $LNINFO[$lang]["locale"]; + } + $pos = strpos($lang, "-"); + if ($pos !== false) { + return substr($lang, 0, $pos) . "_" + . strtoupper(substr($lang, $pos + 1)); + } + return $lang; +} + +// _lninfo_db: Database column name +// Hyphens are not allowed, to avoid confusion +// with the substraction operator "-" +function _lninfo_db($lang) +{ + global $LNINFO; + if ( array_key_exists($lang, $LNINFO) + && array_key_exists("db", $LNINFO[$lang])) { + return $LNINFO[$lang]["db"]; + } + return str_replace("-", "", $lang); +} + +// _lninfo_htmlid: HTML id value +// Hyphens are not allowed, as specified in HTML 4.01 specification +function _lninfo_htmlid($lang) +{ + global $LNINFO; + if ( array_key_exists($lang, $LNINFO) + && array_key_exists("htmlid", $LNINFO[$lang])) { + return $LNINFO[$lang]["htmlid"]; + } + return str_replace("-", "", $lang); +} + +// _lninfo_space_break: Whether words are seperated at spaces +function _lninfo_space_break($lang) +{ + global $LNINFO; + // Default to true, for alphabetic languages + return array_key_exists($lang, $LNINFO) + && array_key_exists("sp_break", $LNINFO[$lang])? + $LNINFO[$lang]["sp_break"]: true; +} + +// _lninfo_ignore_case: Whether case can be ignored +function _lninfo_ignore_case($lang) +{ + global $LNINFO; + // Default to true, for European languages + return array_key_exists($lang, $LNINFO) + && array_key_exists("icase", $LNINFO[$lang])? + $LNINFO[$lang]["icase"]: true; +} + +// _lninfo_country_first: Whether country should be listed first in a mail address +function _lninfo_country_first($lang) +{ + global $LNINFO; + // Default to false, for European languages + return array_key_exists($lang, $LNINFO) + && array_key_exists("ctfirst", $LNINFO[$lang])? + $LNINFO[$lang]["ctfirst"]: false; +} + +// _lninfo_desc: Long description +function _lninfo_desc($lang) +{ + global $LNINFO; + return array_key_exists($lang, $LNINFO) + && array_key_exists("longdesc", $LNINFO[$lang])? + $LNINFO[$lang]["longdesc"]: $lang; +} + +// _lninfo_desc_curlc: Long description in the current locale +function _lninfo_desc_curlc($lang) +{ + return C_(_lninfo_desc($lang)); +} + +// _lninfo_desc_selflc: Long description in its own locale +function _lninfo_desc_selflc($lang) +{ + // Cache the result + static $desc; + // Obtain the description list + if (!isset($desc)) { + global $LNINFO; + $curlc = getenv("LANG"); + if ($curlc === false || $curlc == "") { + $curlc = getlang(LN_LOCALE); + } + $desc = array(); + foreach (array_keys($LNINFO) as $l) { + // Switch the locale + $locale = _lninfo_lc($l); + $charset = _lninfo_charset($l); + putenv("LANG=$locale"); + putenv("LANGUAGE=$locale"); + setlocale(LC_ALL, ""); + // Obtain the long description + $desc[$l] = _lninfo_desc_curlc($l); + } + // Return the current locale + putenv("LANG=$curlc"); + putenv("LANGUAGE=$curlc"); + setlocale(LC_ALL, ""); + } + // Return the proper description + return array_key_exists($lang, $desc)? + $desc[$lang]: $lang; +} + +// _lninfo_switch_title: Title of the language switch +function _lninfo_switch_title($lang) +{ + // Cache the result + static $title; + // Obtain the title list + if (!isset($title)) { + global $LNINFO; + $curlc = getenv("LANG"); + if ($curlc === false || $curlc == "") { + $curlc = getlang(LN_LOCALE); + } + $title = array(); + foreach (array_keys($LNINFO) as $l) { + // Switch the locale + $locale = _lninfo_lc($l); + $charset = _lninfo_charset($l); + putenv("LANG=$locale"); + putenv("LANGUAGE=$locale"); + setlocale(LC_ALL, ""); + // Obtain the title + $title[$l] = C_("Switch to the %s version of this page."); + } + // Return the current locale + putenv("LANG=$curlc"); + putenv("LANGUAGE=$curlc"); + setlocale(LC_ALL, ""); + } + // Not found -- use description in its own locale instead + if (!array_key_exists($lang, $title)) { + return _lninfo_desc_selflc($lang); + } + // Return the proper title + return sprintf($title[$lang], _lninfo_desc_selflc($lang)); +} + +?> diff --git a/lib/php/monica/login.inc.php b/lib/php/monica/login.inc.php new file mode 100644 index 0000000..07226f3 --- /dev/null +++ b/lib/php/monica/login.inc.php @@ -0,0 +1,209 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/cgiemu.inc.php"; +require_once "monica/chkpriv.inc.php"; +require_once "monica/encrypt.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/guest.inc.php"; +require_once "monica/http.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/logout.inc.php"; +require_once "monica/scptpriv.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/userhome.inc.php"; +require_once "monica/usrconst.inc.php"; + +if (!defined("REMEMBER_COOKIE")) { + define("REMEMBER_COOKIE", "qySxnXvjNxv0aDAs"); +} +if (!defined("FAILURE_DELAY")) { + define("FAILURE_DELAY", 5); +} + +// use_users: Use user/membership system +function use_users() +{ + // Cache the result + static $cache; + // Return the cache + if (isset($cache)) { + return $cache; + } + + // Find in the available tables + $cache = in_array("users", sql_tables()); + + return $cache; +} + +// userinfo_url: The URL to update the user information +function userinfo_url() +{ + // Cache the result + static $cache; + // Return the cache + if (isset($cache)) { + return $cache; + } + + $is_admin = is_guest()? is_admin_script(): is_admin(); + if ($is_admin) { + $args = array(); + $args[] = "form=cur"; + $args[] = "sn=" . urlencode(get_login_sn()); + $cache = userhome() . "users.php?" . implode("&", $args); + } else { + $cache = userhome() . "myinfo.php"; + } + + return $cache; +} + +// get_login_sn: Obtain the user serial number or the current logged-in user +function get_login_sn() +{ + return isset($_SESSION) && array_key_exists("usersn", $_SESSION)? + $_SESSION["usersn"]: null; +} + +// get_login_id: Obtain the user ID. of the current logged-in user +function get_login_id() +{ + return isset($_SESSION) && array_key_exists("userid", $_SESSION)? + $_SESSION["userid"]: null; +} + +// get_login_name: Obtain the full name of the current logged-in user +function get_login_name() +{ + return isset($_SESSION) && array_key_exists("username", $_SESSION)? + $_SESSION["username"]: null; +} + +// get_login_groups: Obtain the groups of the current logged-in user +function get_login_groups() +{ + return isset($_SESSION) && array_key_exists("groups", $_SESSION)? + $_SESSION["groups"]: array(); +} + +// upd_login_info: Update the logged-in infomation +function upd_login_info() +{ + // Return if not logged-in from the web yet + if (IS_CGI && is_null(get_login_sn())) { + return; + } + + // Lock the necessary tables + $locks = array("users" => LOCK_EX, "groups" => LOCK_SH, "usermem" => LOCK_SH, "groupmem" => LOCK_SH); + sql_lock($locks); + + // Begin the SQL transaction + sql_begin(); + + // Lock the necessary tables + $locks = array("users" => LOCK_EX, "groups" => LOCK_SH, "usermem" => LOCK_SH, "groupmem" => LOCK_SH); + sql_lock($locks); + + // Web applications save the login information in session as user S/N + if (IS_CGI) { + // Fetch the user infomation + $found = false; + if (!preg_match("/^[1-9]\d{8}$/", get_login_sn())) { + $found = false; + } else { + $select = "SELECT * FROM users" + . " WHERE sn=" . get_login_sn() . ";\n"; + $result = sql_query($select); + $found = (sql_num_rows($result) == 1); + } + // User does not exist anymore + if (!$found) { + logout(); + if ($_SERVER["REQUEST_METHOD"] == "POST") { + http_303("/" . getlang(LN_FILENAME) . "/misc/loginchanged.html"); + } else { + http_307("/" . getlang(LN_FILENAME) . "/misc/loginchanged.html"); + } + // No need to return + exit; + } + + // Act as the current user on the console + } else { + $pwent = posix_getpwuid(posix_geteuid()); + // Password entry is gone for this user + if ($pwent === false) { + if ($_SERVER["REQUEST_METHOD"] == "POST") { + http_303("/" . getlang(LN_FILENAME) . "/misc/loginchanged.html"); + } else { + http_307("/" . getlang(LN_FILENAME) . "/misc/loginchanged.html"); + } + } + $userid = $pwent["name"]; + // Fetch the user infomation + $select = "SELECT * FROM users" + . " WHERE id='" . sql_esctext($userid) . "';\n"; + $result = sql_query($select); + // This user is not in the list of the users for the current package + if (sql_num_rows($result) != 1) { + http_403(); + } + } + + $row = sql_fetch_assoc($result); + + // Remember the user + if (array_key_exists("remember", $_SESSION)) { + // Remember me + if ($_SESSION["remember"]) { + setcookie(REMEMBER_COOKIE, encrypt($row["id"]), time() + 86400 * 365, "/"); + // Forget me + } else { + setcookie(REMEMBER_COOKIE, "", time() - 1, "/"); + } + unset($_SESSION["remember"]); + // Update the remembered user ID + } elseif (array_key_exists(REMEMBER_COOKIE, $_COOKIE) + && decrypt($_COOKIE[REMEMBER_COOKIE]) !== $row["id"]) { + setcookie(REMEMBER_COOKIE, encrypt($row["id"]), time() + 86400 * 365, "/"); + } + + // Update the user ID and full name + $_SESSION["usersn"] = $row["sn"]; + $_SESSION["userid"] = $row["id"]; + $_SESSION["username"] = $row["name"]; + + // Update the preferred language + $lang = getlang(); + if ($row["lang"] != $lang) { + $update = "UPDATE users SET lang='" . sql_esctext($lang) . "'" + . " WHERE sn=" . get_login_sn() . ";\n"; + sql_query($update); + } + + // Update the groups + $_SESSION["groups"] = user_parent_groups(get_login_sn()); + $_SESSION["guest"] = in_array(GUEST_GROUP, $_SESSION["groups"]); + $_SESSION["admin"] = in_array(ADMIN_GROUP, $_SESSION["groups"]); + + // Commit the SQL transaction + sql_commit(); + + // Unlock the previously locked SQL tables + sql_lock(); + return; +} + +?> diff --git a/lib/php/monica/logout.inc.php b/lib/php/monica/logout.inc.php new file mode 100644 index 0000000..390d82d --- /dev/null +++ b/lib/php/monica/logout.inc.php @@ -0,0 +1,22 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// logout: Log out a user +function logout() +{ + unset($_SESSION["usersn"]); + unset($_SESSION["userid"]); + unset($_SESSION["username"]); + unset($_SESSION["userpref"]); + unset($_SESSION["groups"]); + unset($_SESSION["admin"]); + unset($_SESSION["guest"]); + unset($_SESSION["bylogin"]); + return; +} + +?> diff --git a/lib/php/monica/mail.inc.php b/lib/php/monica/mail.inc.php new file mode 100644 index 0000000..bec4bb7 --- /dev/null +++ b/lib/php/monica/mail.inc.php @@ -0,0 +1,1341 @@ + +// Copyright: Copyright (C) 2002-2009 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/cgiemu.inc.php"; +require_once "monica/curtime.inc.php"; +require_once "monica/errhndl.inc.php"; +require_once "monica/geoip.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/guest.inc.php"; +require_once "monica/https.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/md5.inc.php"; +require_once "monica/mimeenc.inc.php"; +require_once "monica/mimetype.inc.php"; +require_once "monica/rfc1521.inc.php"; +require_once "monica/rfc822.inc.php"; +require_once "monica/server.inc.php"; +require_once "monica/unicode.inc.php"; +require_once "monica/upload.inc.php"; +require_once "monica/xfileio.inc.php"; + +// References: +// RFC 821 SIMPLE MAIL TRANSFER PROTOCOL +// RFC 822 STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES +// RFC 1521 MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Specifying and Describing the Format of Internet Message Bodies +// RFC 1766 Tags for the Identification of Languages +// RFC 1806 Communicating Presentation Information in Internet Messages: The Content-Disposition Header +// RFC 1864 The Content-MD5 Header Field +// RFC 2183 Communicating Presentation Information in Internet Messages: The Content-Disposition Header Field +// RFC 2369 The Use of URLs as Meta-Syntax for Core Mail List Commands and their Transport through Message Header Fields +// RFC 2919 List-Id: A Structured Field and Namespace for the Identification of Mailing Lists + +// Mail: An RFC-822 e-mail message +// 2005-05-06: All input information must be in UTF-8 +class Mail +{ + protected $_body = null; + protected $_parts = array(); + protected $_charset = null; + protected $_modified = false; + protected $_output = null; + protected $_attaches = array(); + + // RFC 821 headers/properties + protected $_mail_from = null; + protected $_rcpt_to = null; + // RFC 822 headers/properties + protected $_from = null; + protected $_subject = null; + protected $_sender = null; + protected $_to = null; + protected $_cc = null; + protected $_bcc = null; + protected $_reply_to = null; + // RFC 1521 MIME headers/properties + protected $_type = "text/plain"; + protected $_id = null; + // RFC 1766 Content-Language + protected $_lang = null; + // RFC 1806/2183 Content-Disposition + protected $_disposition = null; + protected $_filename = null; + protected $_filemtime = null; + protected $_filesize = null; + // RFC 1864 Content-MD5 + protected $_md5 = false; + // RFC 2387 MIME multipart/related headers/properties + protected $_related_type = null; + protected $_related_start = null; + // RFC 2369/2919 Mailing Lists headers/properties + protected $_list_id = null; + protected $_list_help = null; + protected $_list_subscribe = null; + protected $_list_unsubscribe = null; + protected $_list_post = null; + protected $_list_owner = null; + protected $_list_archive = null; + // Non-standard headers + protected $_errors_to = null; + protected $_precedence = null; + protected $_mailer = "Monica mail.inc.php http://www.pristine.com.tw/"; + protected $_any_header = array(); + + protected $_boundary_len = 32; + + // __construct: Initialize the e-mail message + function __construct() + { + // Nothing to initialize + } + + // RFC 821 headers/properties + // mail_from: Set/retrieve the MAIL FROM: sender + function mail_from($email = null) + { + if (func_num_args() > 0) { + $this->_mail_from = $email; + $this->_modified = true; + } + return $this->_mail_from; + } + // rcpt_to: Set/retrieve the RCPT TO: recipients (to be used in send()) + function rcpt_to($email = null) + { + if (func_num_args() > 0) { + // Reset it + if (is_null($email)) { + $this->_rcpt_to = null; + // Add it + } else { + if (!is_array($this->_rcpt_to)) { + $this->_rcpt_to = array(); + } + if (!in_array($email, $this->_rcpt_to)) { + $this->_rcpt_to[] = $email; + } + } + } + return is_null($this->_rcpt_to)? null: + implode(",", $this->_rcpt_to); + } + + // RFC 822 headers/properties + // from: Set/retrieve the From: header + function from($email = null, $name = null) + { + if (func_num_args() > 0) { + $this->_add_addr($this->_from, $email, $name); + } + return $this->_ret_addrs($this->_from); + } + // subject: Set/retrieve the subject + function subject($subject = null) + { + if (func_num_args() > 0) { + $this->_subject = $subject; + $this->_modified = true; + } + return $this->_subject; + } + // sender: Set/retrieve the Sender: header + function sender($email = null, $name = null) + { + if (func_num_args() > 0) { + $this->_set_addr($this->_sender, $email, $name); + } + return $this->_ret_addr($this->_sender); + } + // to: Set/retrieve the To: header + function to($email = null, $name = null) + { + if (func_num_args() > 0) { + $this->_add_addr($this->_to, $email, $name); + } + return $this->_ret_addrs($this->_to); + } + // cc: Set/retrieve the Cc: header + function cc($email = null, $name = null) + { + if (func_num_args() > 0) { + $this->_add_addr($this->_cc, $email, $name); + } + return $this->_ret_addrs($this->_cc); + } + // bcc: Set/retrieve the Bcc: header + function bcc($email = null, $name = null) + { + if (func_num_args() > 0) { + $this->_add_addr($this->_bcc, $email, $name); + } + return $this->_ret_addrs($this->_bcc); + } + // reply_to: Set/retrieve the Reply-To: header + function reply_to($email = null, $name = null) + { + if (func_num_args() > 0) { + $this->_add_addr($this->_reply_to, $email, $name); + } + return $this->_ret_addrs($this->_reply_to); + } + + // RFC 1521 MIME headers/properties + // charset: Set/retrieve the desired character set + // Note that this is the desired character set. The input information + // should still in UTF-8 + function charset($charset = null) + { + if (func_num_args() > 0) { + $this->_charset = $charset; + $this->_modified = true; + } + return $this->_charset; + } + // type: Set/retrieve the MIME content type + function type($type = null) + { + if (func_num_args() > 0) { + $this->_type = $type; + $this->_modified = true; + } + return $this->_type; + } + // id: Set/retrieve the content ID. + function id($id = true) + { + if (func_num_args() > 0) { + // Set a content ID. + if ($id) { + if (is_null($this->_id)) { + $this->_id = $this->_new_msgid(); + $this->_modified = true; + } + // Unset the content ID. + } else { + if (!is_null($this->_id)) { + $this->_id = null; + $this->_modified = true; + } + } + } + return $this->_id; + } + + // RFC 1766 Content-Language + // lang: Set/retrieve the language + function lang($lang = null) + { + if (func_num_args() > 0) { + // Reset it + if (is_null($lang)) { + $this->_lang = null; + // Add it + } else { + if (!is_array($this->_lang)) { + $this->_lang = array(); + } + $this->_lang[] = $lang; + } + $this->_modified = true; + } + if (is_null($this->_lang)) { + return null; + } else { + $langs = array(); + for ($i = 0; $i < count($this->_lang); $i++) { + $langs[] = ln($this->_lang[$i], LN_NAME); + } + return implode(", ", $this->_lang); + } + } + + // RFC 1806/2183 Content-Disposition + // disposition: Set/retrieve the MIME content disposition + // "inline" or "attachment" + function disposition($disposition = null) + { + if (func_num_args() > 0) { + if (is_null($disposition)) { + $this->_disposition = null; + } else { + switch ($disposition) { + case "inline": + case "attachment": + $this->_disposition = $disposition; + break; + default: + trigger_error("bad content disposition $disposition", E_USER_ERROR); + break; + } + } + $this->_modified = true; + } + return $this->_disposition; + } + // filename: Set/retrieve the MIME content disposition filename + function filename($filename = null) + { + if (func_num_args() > 0) { + $this->_filename = $filename; + $this->_modified = true; + } + return $this->_filename; + } + // filemtime: Set/retrieve the MIME content disposition modification time + function filemtime($mtime = null) + { + if (func_num_args() > 0) { + $this->_filemtime = $mtime; + $this->_modified = true; + } + return $this->_filemtime; + } + // filesize: Set/retrieve the MIME content disposition size + function filesize($size = null) + { + if (func_num_args() > 0) { + $this->_filesize = $size; + $this->_modified = true; + } + return $this->_filesize; + } + + // RFC 1864 Content-MD5 + // md5: Set/retrieve the MD5 digest flag + function md5($md5 = true) + { + if (func_num_args() > 0) { + $this->_md5 = $md5? true: false; + $this->_modified = true; + } + return $this->_md5; + } + + // RFC 2387 MIME multipart/related headers/properties + // related_type: Set/retrieve the multipart/related type + function related_type($reltype = null) + { + if (func_num_args() > 0) { + $this->_related_type = $reltype; + $this->_modified = true; + } + return $this->_related_type; + } + // related_start: Set/retrieve the multipart/related start + function related_start($relstart = null) + { + if (func_num_args() > 0) { + $this->_related_start = $relstart; + $this->_modified = true; + } + return $this->_related_start; + } + + // RFC 2369/2919 Mailing Lists headers/properties + // list_id: Set/retrieve the list ID. + function list_id($id = null, $phrase = null) + { + if (func_num_args() > 0) { + // Reset it + if (is_null($id)) { + $this->_list_id = null; + // Set it + } else { + $this->_list_id = array( + "id" => $id, + "phrase" => $phrase, + ); + } + $this->_modified = true; + } + if (is_null($this->_list_id)) { + return null; + } + $ret = "<" . $this->_list_id["id"] . ">"; + if (!is_null($this->_list_id["phrase"])) { + $phrase = $this->_list_id["phrase"]; + if (rfc822_phrase_need_quoting($phrase)) { + $phrase = "\"" . addslashes($phrase) . "\""; + } + $ret = "$phrase $ret"; + } + return $ret; + } + // list_help: Set/retrieve the list help address + function list_help($url = null) + { + if (func_num_args() > 0) { + $this->_add_list_url($this->_list_help, $url); + } + return $this->_ret_list_urls($this->_list_help); + } + // list_subscribe: Set/retrieve the list subscribe address + function list_subscribe($url = null) + { + if (func_num_args() > 0) { + $this->_add_list_url($this->_list_subscribe, $url); + } + return $this->_ret_list_urls($this->_list_subscribe); + } + // list_unsubscribe: Set/retrieve the list unsubscribe address + function list_unsubscribe($url = null) + { + if (func_num_args() > 0) { + $this->_add_list_url($this->_list_unsubscribe, $url); + } + return $this->_ret_list_urls($this->_list_unsubscribe); + } + // list_post: Set/retrieve the list post address + // False means "List-Post: NO" + function list_post($url = null) + { + if (func_num_args() > 0) { + if ($url === false) { + $this->_list_post = false; + } else { + $this->_add_list_url($this->_list_post, $url); + } + } + if ($this->_list_post === false) { + return "NO"; + } else { + return $this->_ret_list_urls($this->_list_post); + } + } + // list_owner: Set/retrieve the list owner address + function list_owner($url = null) + { + if (func_num_args() > 0) { + $this->_add_list_url($this->_list_owner, $url); + } + return $this->_ret_list_urls($this->_list_owner); + } + // list_archive: Set/retrieve the list archive address + function list_archive($url = null) + { + if (func_num_args() > 0) { + $this->_add_list_url($this->_list_archive, $url); + } + return $this->_ret_list_urls($this->_list_archive); + } + + // Non-standard headers + // errors_to: Set/retrieve the Errors-To: header + function errors_to($email = null) + { + if (func_num_args() > 0) { + if (is_null($email)) { + $this->_errors_to = null; + } else { + if (!is_array($this->_errors_to)) { + $this->_errors_to = array(); + } + $this->_errors_to[] = $email; + } + $this->_modified = true; + } + return is_null($this->_errors_to)? null: + implode(", ", $this->_errors_to); + } + // precedence: Set/retrieve the precedence, mentioned in RFC 2076 + // "bulk" or "first-class" + function precedence($precedence = null) + { + if (func_num_args() > 0) { + if (is_null($precedence)) { + $this->_precedence = null; + } else { + switch ($precedence) { + case "bulk": + case "first-class": + $this->_precedence = $precedence; + break; + default: + trigger_error("bad precedence $precedence", E_USER_ERROR); + break; + } + } + $this->_modified = true; + } + return $this->_precedence; + } + + // mailer: Set/retrieve the mailer + function mailer($mailer = null) + { + if (func_num_args() > 0) { + $this->_mailer = $mailer; + $this->_modified = true; + } + return $this->_mailer; + } + + // any_header: Set/retrieve any header + function any_header($name, $value = null) + { + // Find the index of that header + unset($ndx); + for ($i = 0; $i < count($this->_any_header); $i++) { + if ($this->_any_header[$i]["name"] = $name) { + $ndx = $i; + break; + } + } + // Set the value + if (func_num_args() > 1) { + if (isset($ndx)) { + $this->_any_header[$ndx]["value"] = $value; + } else { + // Only add a non-null value + if (!is_null($value)) { + $this->_any_header[] = array( + "name" => $name, + "value" => $value, + ); + } + } + $this->_modified = true; + return $value; + // Retrieve the value + } else { + if (isset($ndx)) { + return $this->_any_header[$ndx]["value"]; + } else { + return null; + } + } + } + + // body: Set/retrieve the body + function body($body = null) + { + if (func_num_args() > 0) { + $this->_body = $body; + $this->_modified = true; + } + return $this->_body; + } + + // addpart: Add an MIME part + // $mail is a Mail object + function addpart($mail) + { + if (is_null($mail)) { + $this->_parts = array(); + } else { + $this->_parts[] = $mail; + } + $this->_modified = true; + return $mail; + } + + // from_file: Set the mail from a file + function from_file($file) + { + $this->_type = check_mime_type($file); + $this->_body = xfread($file); + $this->_modified = true; + return; + } + + // as_attach: Set the mail as an attachment + function as_attach($file, $filename = null) + { + $this->_type = check_mime_type($file); + $this->_disposition = "attachment"; + $this->_filename = !is_null($filename)? $filename: + basename($file); + $this->_filemtime = filemtime($file); + $this->_filesize = filesize($file); + $this->_body = xfread($file); + $this->_modified = true; + return $this->_body; + } + + // as_attach_upload: Set the an attachment from $_SESSION + function as_attach_upload($sn) + { + $FILES =& file_deposit(); + $file =& $FILES[$sn]; + $this->_charset = getlang(LN_CHARSET); + $this->_type = $file["type"]; + $this->_disposition = "attachment"; + $this->_filename = $file["name"]; + $this->_filesize = $file["size"]; + $this->_body = $file["content"]; + $this->_modified = true; + return $this->_body; + } + + // add_attach: Add an attachment + function add_attach($file, $filename = null) + { + if (is_null($file)) { + $this->_attaches = array(); + } else { + // Create the attachment + $attach = new Mail(); + $attach->as_attach($file, $filename); + $this->_attaches[] = $attach; + } + $this->_modified = true; + return; + } + + // add_attach_upload: Add an attachment from $_SESSION + function add_attach_upload($sn) + { + if (is_null($sn)) { + $this->_attaches = array(); + } else { + // Create the attachment + $attach = new Mail(); + $attach->as_attach_upload($sn); + $this->_attaches[] = $attach; + } + $this->_modified = true; + return; + } + + // output: Output the mail message + function output($is_full_msg = true) + { + // Output before + if (!is_null($this->_output) && !$this->_modified) { + return $this->_output; + } + // Preserve the original timeout + $timeout = ini_get("max_execution_time"); + ini_set("max_execution_time", 0); + + // Set the attachment + $mail = $this->_get_attached_mail(); + + // Check the message + if ($is_full_msg) { + $mail->_check(); + } + + // Set the mail body + // Set the body first, since we need to know Content-Transfer-Encoding + // and MIME multipart boundary first + $body = ""; + unset($content_transfer_encoding); + // A single content + if ( is_null($mail->_type) + || substr($mail->_type, 0, 10) != "multipart/") { + if (!is_null($mail->_body)) { + $body = $mail->_body; + // A text message + if (substr($mail->_type, 0, 5) == "text/") { + // Convert to the desired character set + // This piece of code shall be refined + if ( $mail->_type == "text/plain" + && !is_usascii_printable($body) + && !is_null($this->_charset) + && $this->_charset != "UTF-8") { + $body = iconv("UTF-8", $this->_charset, $body); + } + $body = str_replace("\r\n", "\n", $body); + $body = str_replace("\n", "\r\n", $body); + if ($mail->_md5) { + $md5 = md5_base64($body); + } + // Not in US-ASCII, containing long lines, or MD5 is in use + if ( !is_usascii_printable_text($body) + || preg_match("/[^\r\n]{76}/", $body) + || $mail->_md5) { + $body = qpencode($body); + $content_transfer_encoding = "quoted-printable"; + } + + // A piece of RFC-822 e-mail message + } elseif (substr($mail->_type, 0, 8) == "message/") { + // Do nothing + + // A piece of binary data + } else { + if ($mail->_md5) { + $md5 = md5_base64($body); + } + $body = base64_encode($body); + $body = preg_replace("/(.{76})/", "$1\r\n", $body); + $content_transfer_encoding = "base64"; + } + } + + // A multipart MIME content + } else { + $parts = array(); + for ($i = 0; $i < count($mail->_parts); $i++) { + $parts[] = $mail->_parts[$i]->output(false); + } + $everything = implode("", $parts); + // Create a boundary + do { + $boundary = "=_"; + while (strlen($boundary) < $mail->_boundary_len) { + switch (mt_rand(0, 2)) { + case 0: + $boundary .= chr(mt_rand(0, 9) + ord("0")); + break; + case 1: + $boundary .= chr(mt_rand(0, 25) + ord("A")); + break; + case 2: + $boundary .= chr(mt_rand(0, 25) + ord("a")); + break; + } + } + } while (strpos($everything, $boundary) !== false); + // Add the boundary + for ($i = 0; $i < count($parts); $i++) { + $parts[$i] = "--$boundary\r\n" . $parts[$i] . "\r\n"; + } + // Compose the body + $body = implode("", $parts) . "--$boundary--\r\n"; + } + // Ensure a CRLF is in the end + if (substr($body, -2) != "\r\n") { + $body .= "\r\n"; + } + + $headers = array(); + + // RFC 822 headers + // RFC-822 suggests the header order as: + // "Return-Path", "Received", "Date", "From", "Subject", "Sender", + // "To", "cc", etc. + // We do not set the Received: header. It is added before mail is sent. + // Set the Date: header + if ($is_full_msg) { + $headers[] = "Date: " . date("r", NOW) . "\r\n"; + } + // Set the From: header + if (!is_null($mail->_from)) { + $headers[] = "From: " . $mail->_out_addrs($mail->_from) . "\r\n"; + } elseif ($is_full_msg) { + $pwent = posix_getpwuid(posix_geteuid()); + $addr = array( + "name" => $pwent["gecos"], + "email" => $pwent["name"] . "@" . fqdn(), + ); + $headers[] = "From: " . $mail->_out_addr($addr) . "\r\n"; + } + // Set the Subject: header + if (!is_null($mail->_subject)) { + $subject = $this->_subject; + $subject = b64hdr_encode($subject, $this->_charset); + $headers[] = "Subject: $subject\r\n"; + } + // Set the Sender: header + if (!is_null($mail->_sender)) { + $need = false; + // Multiple From: + if (count($mail->_from) > 1) { + $need = true; + // Different than the only From: + } elseif ( $mail->_from[0]["email"] !== $mail->_sender["email"] + || $mail->_from[0]["name"] !== $mail->_sender["name"]) { + $need = true; + } + if ($need) { + $headers[] = "Sender: " . $mail->_out_addr($mail->_sender) . "\r\n"; + } + } + // Set the To: header + if (!is_null($mail->_to)) { + $headers[] = "To: " . $mail->_out_addrs($mail->_to) . "\r\n"; + } + // Set the Cc: header + if (!is_null($mail->_cc)) { + $headers[] = "Cc: " . $mail->_out_addrs($mail->_cc) . "\r\n"; + } + // Set the Bcc: header + if (!is_null($mail->_bcc)) { + $headers[] = "Bcc: " . $mail->_out_addrs($mail->_bcc) . "\r\n"; + } + // Destination must exist (by RFC 822 4.1) + /* if ( $is_full_msg + && is_null($mail->_to) + && is_null($mail->_cc) + && is_null($mail->_bcc)) { + $headers[] = "Bcc: \r\n"; + } */ + // Set the Reply-To: header + if (!is_null($mail->_reply_to)) { + $headers[] = "Reply-To: " . $mail->_out_addrs($mail->_reply_to) . "\r\n"; + } + // Set the Message-ID: header + if ($is_full_msg) { + $id = !is_null($mail->_id)? $mail->_id: $mail->_new_msgid(); + $headers[] = "Message-ID: <$id>\r\n"; + } + + // RFC 1521 MIME headers + // Set the MIME-Version: header + if ($is_full_msg && !is_null($mail->_type)) { + $headers[] = "MIME-Version: 1.0\r\n"; + } + // Set the Content-Type: header + if (!is_null($mail->_type)) { + $type = $mail->_type; + if (substr($type, 0, 5) == "text/" && !is_null($mail->_charset)) { + $type .= "; charset=" . $mail->_charset; + } + // Attachment filename -- deprecated + /* if (!is_null($mail->_filename)) { + $filename = $mail->_filename; + $filename = b64hdr_encode($filename, $this->_charset); + if (rfc1521_value_need_quoting($filename)) { + $filename = "\"" . addslashes($filename) . "\""; + } + $type .= ";\r\n name=$filename"; + } */ + if (substr($type, 0, 10) == "multipart/") { + // Add type and start parameter to multipart/related + if ($type == "multipart/related") { + $reltype = $mail->_related_type; + if (is_null($reltype)) { + $reltype = $mail->_parts[0]->type(); + } + $type .= ";\r\n type=\"$reltype\""; + // "start" parameter is broken in most e-mail client (??? why?) + /* $relstart = $mail->_related_start; + if (is_null($relstart)) { + $relstart = $mail->_parts[0]->id(true); + } + $type .= ";\r\n start=\"$relstart\""; */ + } + $type .= ";\r\n boundary=\"$boundary\""; + } + $headers[] = "Content-Type: $type\r\n"; + } + // Set the Content-ID: header + // Do not generate Content-ID for complete messages. Complete + // messages has Message-ID instead. + if (!$is_full_msg && !is_null($mail->_id)) { + $headers[] = "Content-ID: <" . $mail->_id . ">\r\n"; + } + // Set the Content-Transfer-Encoding: header + if (isset($content_transfer_encoding)) { + $headers[] = "Content-Transfer-Encoding: $content_transfer_encoding\r\n"; + } + + // RFC 1766 Content-Language + if (!is_null($mail->_lang)) { + $langs = array(); + for ($i = 0; $i < count($mail->_lang); $i++) { + $langs[] = ln($mail->_lang[$i], LN_NAME); + } + $headers[] = "Content-Language: " . implode(", ", $langs) . "\r\n"; + } + + // RFC 1806/2183 Content-Disposition + if (!is_null($mail->_disposition)) { + $disposition = $mail->_disposition; + if (!is_null($mail->_filename)) { + $filename = $mail->_filename; + // Note: Eudora cannot handle encoded MIME parameter values + $filename = b64hdr_encode($filename, $this->_charset); + if (rfc1521_value_need_quoting($filename)) { + $filename = "\"" . addslashes($filename) . "\""; + } + $disposition .= ";\r\n filename=$filename"; + } + if (!is_null($mail->_filemtime)) { + $disposition .= ";\r\n modification-date=\"" + . date("r", $mail->_filemtime) . "\""; + } + if (!is_null($mail->_filesize)) { + $disposition .= ";\r\n size=" . $mail->_filesize; + } + $headers[] = "Content-Disposition: $disposition\r\n"; + } + // RFC 1864 Content-MD5 + if ($mail->_md5) { + $headers[] = "Content-MD5: $md5\r\n"; + } + + // RFC 2369/2919 Mailing Lists headers + // Set the List-ID: header + if (!is_null($mail->_list_id)) { + $list_id = "<" . $mail->_list_id["id"] . ">"; + if (!is_null($mail->_list_id["phrase"])) { + $phrase = $mail->_list_id["phrase"]; + if (rfc822_phrase_need_quoting($phrase)) { + $phrase = "\"" . addslashes($phrase) . "\""; + } + $phrase = b64hdr_encode($phrase, $this->_charset); + $list_id = "$phrase $list_id"; + } + $headers[] = "List-ID: $list_id\r\n"; + } + // Set the List-Help: header + if (!is_null($mail->_list_help)) { + $headers[] = "List-Help: " + . $mail->_out_list_urls($mail->_list_help) . "\r\n"; + } + // Set the List-Subscribe: header + if (!is_null($mail->_list_subscribe)) { + $headers[] = "List-Subscribe: " + . $mail->_out_list_urls($mail->_list_subscribe) . "\r\n"; + } + // Set the List-Unsubscribe: header + if (!is_null($mail->_list_unsubscribe)) { + $headers[] = "List-Unsubscribe: " + . $mail->_out_list_urls($mail->_list_unsubscribe) . "\r\n"; + } + // Set the List-Post: header + if (!is_null($mail->_list_post)) { + $list_post = ($mail->_list_post !== false)? + $mail->_out_list_urls($mail->_list_post): "NO"; + $headers[] = "List-Post: $list_post\r\n"; + } + // Set the List-Owner: header + if (!is_null($mail->_list_owner)) { + $headers[] = "List-Owner: " + . $mail->_out_list_urls($mail->_list_owner) . "\r\n"; + } + // Set the List-Archive: header + if (!is_null($mail->_list_archive)) { + $headers[] = "List-Archive: " + . $mail->_out_list_urls($mail->_list_archive) . "\r\n"; + } + + // Set the Errors-To: header + if ($is_full_msg && !is_null($mail->_errors_to)) { + $headers[] = "Errors-To: " . implode(", ", $mail->_errors_to) . "\r\n"; + } + + // Set the Precedence: header + if ($is_full_msg && !is_null($mail->_precedence)) { + $headers[] = "Precedence: " . $mail->_precedence . "\r\n"; + } + + // Set the X-Mailer: header + if ($is_full_msg && !is_null($mail->_mailer)) { + $headers[] = "X-Mailer: " . $mail->_mailer . "\r\n"; + } + + // Compose it + $this->_output = implode("", $headers) . "\r\n" . $body; + $this->_modified = false; + // Restore the timeout + ini_set("max_execution_time", $timeout); + return $this->_output; + } + + // send: Send the mail message + function send() + { + // Send the mail with sendmail + return $this->_send_with_sendmail(); + } + + // gsend: Send the mail message if the user is not a guest + function gsend() + { + if (!is_guest()) { + return $this->send(); + } + } + + // _new_msgid: Obtain a new message ID. + function _new_msgid() + { + static $MSGIDS = array(); + // Epoch time and minisecond + list($msec, $sec) = explode(" ", microtime()); + settype($sec, "integer"); + $msec *= 1000000; + settype($msec, "integer"); + // A random serial number + do { + $sn = mt_rand(0, 9999); + } while (in_array($sn, $MSGIDS)); + $MSGIDS[] = $sn; + // Compose it + return sprintf("%10d.%06d.%05d.%04d.monica@%s", + $sec, $msec, getmypid(), $sn, fqdn()); + } + + // _get_attached_mail: Get the mail with its attachment + // Actually, this will convert the mail to multipart/mixed + // and add the attachments + function _get_attached_mail() + { + // Make a copy of myself + $mail = $this; + + // Return myself if there is no attachment + if (count($mail->_attaches) == 0) { + return $mail; + } + + // Not multipart/mixed -- convert to multipart/mixed + if (is_null($mail->_type) || $mail->_type != "multipart/mixed") { + // Pass the content to the body part + $body = new Mail(); + $body->_charset = $mail->_charset; + $body->_type = $mail->_type; + $body->_id = $mail->_id; + $body->_lang = $mail->_lang; + $body->_md5 = $mail->_md5; + // Set the body + // The origin is multipart/xxx + if (!is_null($mail->_type) && substr($mail->_type, 0, 10) == "multipart/") { + $body->_parts = $mail->_parts; + } else { + $body->_body = $mail->_body; + } + // Reset these values + $mail->_parts = array(); + $mail->_body = null; + $mail->_type = "multipart/mixed"; + $mail->_id = null; + $mail->_lang = null; + $mail->_md5 = false; + $mail->addpart($body); + } + + // Add each attachment + foreach ($mail->_attaches as $attach) { + $mail->addpart($attach); + } + + return $mail; + } + + // _set_addr: Set an address + function _set_addr(&$addr, $email, $name) + { + // Reset it + if (is_null($email)) { + $addr = null; + // Set it + } else { + $addr = array( + "name" => $name, + "email" => $email, + ); + } + $this->_modified = true; + } + // _add_addr: Add an address to an address list + function _add_addr(&$list, $email, $name) + { + // Reset it + if (is_null($email)) { + $list = null; + // Add it + } else { + if (!is_array($list)) { + $list = array(); + } + $list[] = array( + "name" => $name, + "email" => $email, + ); + } + $this->_modified = true; + } + + // _ret_addr: Return an address + function _ret_addr($addr) + { + if (is_null($addr)) { + return null; + } elseif (is_null($addr["name"])) { + return $addr["email"]; + } else { + $name = $addr["name"]; + if (rfc822_phrase_need_quoting($name)) { + $name = "\"" . addslashes($name) . "\""; + } + return sprintf("%s <%s>", $name, $addr["email"]); + } + } + // _ret_addrs: Return a list of addresses + function _ret_addrs(&$list) + { + if (is_null($list)) { + return null; + } else { + $addrs = array(); + for ($i = 0; $i < count($list); $i++) { + $addrs[] = $this->_ret_addr($list[$i]); + } + return implode(", ", $addrs); + } + } + + // _out_addr: Output an address + function _out_addr($addr) + { + $out = $addr["email"]; + if (!is_null($addr["name"])) { + $name = $addr["name"]; + if (rfc822_phrase_need_quoting($name)) { + $name = "\"" . addslashes($name) . "\""; + } + $name = b64hdr_encode($name, $this->_charset); + $out = "$name <$out>"; + } + return $out; + } + // _out_addrs: Output a list of addresses + function _out_addrs(&$list) + { + $addrs = array(); + for ($i = 0; $i < count($list); $i++) { + $addrs[] = $this->_out_addr($list[$i]); + } + return implode(",\r\n ", $addrs); + } + + // _add_list_url: Add a list URL to a list URL list + function _add_list_url(&$list, $url) + { + // Reset it + if (is_null($url)) { + $list = null; + // Add it + } else { + if (!is_array($list)) { + $list = array(); + } + $list[] = $url; + } + $this->_modified = true; + } + // _ret_list_urls: Return a list of list URLs + function _ret_list_urls(&$list) + { + if (is_null($list)) { + return null; + } else { + $urls = array(); + for ($i = 0; $i < count($list); $i++) { + $urls[] = "<" . $list[$i] . ">"; + } + return implode(", ", $urls); + } + } + // _out_list_urls: Output a list of list URLs + function _out_list_urls(&$list) + { + $urls = array(); + for ($i = 0; $i < count($list); $i++) { + $urls[] = "<" . $list[$i] . ">"; + } + return implode(",\r\n ", $urls); + } + // _out_trace: Output the trace information (the Received: header) + // See RFC 2821 4.4 Trace Information + function _out_trace() + { + // The trace information + $trace_info = array(); + + // From-domain + $from_tcpinfo_domain = gethostbyaddr($_SERVER["REMOTE_ADDR"]); + if ($from_tcpinfo_domain == $_SERVER["REMOTE_ADDR"]) { + $from_tcpinfo_domain = null; + } + if (is_null($from_tcpinfo_domain)) { + $from_tcp_info = sprintf("[%s]", $_SERVER["REMOTE_ADDR"]); + } else { + $from_tcp_info = sprintf("%s [%s]", + $from_tcpinfo_domain, $_SERVER["REMOTE_ADDR"]); + } + $trace_info[] = "from webclient ($from_tcp_info)"; + + // The invoking user, as a from comment + if (is_null(get_login_sn())) { + $from_comment = "invoked by anonymous web user" + . " country " . geoiplookup(); + } else { + $from_comment = "invoked by web user " . get_login_id() + . " S/N " . get_login_sn() + . " country " . geoiplookup(); + } + $trace_info[] = "($from_comment)"; + + // By-domain + // Apache implementation + if (is_apache()) { + $by_address_literal = $_SERVER["SERVER_ADDR"]; + // Microsoft IIS implementation + } elseif (is_iis()) { + $by_address_literal = $_SERVER["LOCAL_ADDR"]; + // Else, do DNS query + } else { + $by_address_literal = gethostbyname($_SERVER["SERVER_NAME"]); + } + if (array_key_exists("HTTP_HOST", $_SERVER)) { + $by_domain = preg_replace("/:\d+$/", "", $_SERVER["HTTP_HOST"]); + } else { + $by_domain = $by_address_literal; + } + $by_tcpinfo_domain = gethostbyaddr($by_address_literal); + if ($by_tcpinfo_domain == $by_address_literal) { + $by_tcpinfo_domain = null; + } + if (is_null($by_tcpinfo_domain)) { + $by_tcp_info = sprintf("[%s]", $by_address_literal); + } else { + $by_tcp_info = sprintf("%s [%s]", + $by_tcpinfo_domain, $by_address_literal); + } + $trace_info[] = sprintf("by %s (%s)", $by_domain, $by_tcp_info); + + // VIA Link and WITH Protocol + $trace_info[] = "via TCP with HTTP"; + + // For recipients + $rcpts = $this->_get_rcpts(); + if (count($rcpts) > 0) { + for ($i = 0; $i < count($rcpts); $i++) { + $rcpts[$i] = "<" . $rcpts[$i] . ">"; + } + $trace_info[] = "for " . implode(" ", $rcpts); + } + + return sprintf("Received: %s ;\r\n\t%s\r\n", + implode("\r\n\t", $trace_info), date("r", NOW)); + } + + // _check: Check if it is ready to be output + // Refer to RFC 822 + function _check() + { + // When no valid From: exists, default to the current user of the running process + // Check if a valid Sender: exists with multiple From: + if ( !is_null($this->_from) + && count($this->_from) > 1 + && is_null($this->_sender)) { + trigger_error("Multiple From: without a valid Sender: (RFC-822)", E_USER_ERROR); + } + // Check if valid contents exist + if ( !is_null($this->_type) + && substr($this->_type, 0, 10) == "multipart/" + && count($this->_parts) == 0) { + trigger_error("MIME Multipart without any valid part", E_USER_ERROR); + } + } + + // _get_sender: Obtain the sender + function _get_sender($fallback = false) + { + // MAIL FROM: specified + if (!is_null($this->_mail_from)) { + return $this->_mail_from; + // Sender specified + } elseif (!is_null($this->_sender)) { + return $this->_sender["email"]; + // Obtain the sender from From: + } elseif (!is_null($this->_from)) { + return $this->_from[0]["email"]; + // Nothing left + } elseif (!$fallback) { + return null; + // Use the current user + } else { + $pwent = posix_getpwuid(posix_geteuid()); + return $pwent["name"] . "@" . fqdn(); + } + } + + // _get_rcpts: Collect the recipients list + function _get_rcpts() + { + // Recipients specified + if (!is_null($this->_rcpt_to)) { + return $this->_rcpt_to; + } + + // Obtain the recipients from To:, Cc: and Bcc: + $rcpts = array(); + for ($i = 0; $i < count($this->_to); $i++) { + if (!in_array($this->_to[$i]["email"], $rcpts)) { + $rcpts[] = $this->_to[$i]["email"]; + } + } + for ($i = 0; $i < count($this->_cc); $i++) { + if (!in_array($this->_cc[$i]["email"], $rcpts)) { + $rcpts[] = $this->_cc[$i]["email"]; + } + } + for ($i = 0; $i < count($this->_bcc); $i++) { + if (!in_array($this->_bcc[$i]["email"], $rcpts)) { + $rcpts[] = $this->_bcc[$i]["email"]; + } + } + return $rcpts; + } + + // _send_with_sendmail: Send the mail with Sendmail + function _send_with_sendmail() + { + // Obtain the sender + $sender = $this->_get_sender(); + // Collect the Recipients list + $rcpts = $this->_get_rcpts(); + // No recipients found + if (count($rcpts) == 0) { + trigger_error("No recipients found", E_USER_ERROR); + } + + // Send with Sendmail + $sendmail = array("/usr/sbin/sendmail", "-odb"); + if (!is_null($sender)) { + $sendmail = array_merge($sendmail, array("-f", $sender)); + } + $sendmail = array_merge($sendmail, $rcpts); + $mail = $this->_out_trace() . $this->output(); + // Sendmail must escape "." on a line. See RFC 821 SMTP 4.5.2 + $mail = preg_replace("/^(\.+)\r$/m", ".$1", $mail); + return gxruncmd($sendmail, $mail); + } +} + +// b64hdr_encode: Encode a piece of header text with Base-64 +// Refer to RFC-1522 4.1 +function b64hdr_encode($text, $charset) +{ + // US-ASCII printable -- no need to encode it + if (is_usascii_printable($text)) { + return $text; + } + // No desired character set available + if (is_null($charset)) { + return $text; + } + // Desired character set not UTF-8 + if ($charset != "UTF-8") { + // Try to convert into the desired character set + $GLOBALS["php_errormsg"] = null; + set_error_handler("null_error_handler"); + $converted = iconv("UTF-8", $charset, $text); + restore_error_handler(); + // Conversion OK -- in the desired character set + if (is_null($GLOBALS["php_errormsg"])) { + return "=?$charset?B?" . base64_encode($converted) . "?="; + } + } + // Else -- send in UTF-8 + return "=?UTF-8?B?" . base64_encode($text) . "?="; +} + +?> diff --git a/lib/php/monica/markabbr.inc.php b/lib/php/monica/markabbr.inc.php new file mode 100644 index 0000000..678837a --- /dev/null +++ b/lib/php/monica/markabbr.inc.php @@ -0,0 +1,69 @@ + +// Copyright: Copyright (C) 2006-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/echoform.inc.php"; +require_once "monica/htmlchar.inc.php"; + +// h_abbr: Shortcut to markabbr(h()) +function h_abbr($text) +{ + return markabbr(h($text)); +} + +// markabbr: Mark the abbreviation +function markabbr($text) +{ + // FAQ + $text = preg_replace("/\b(FAQ)\b(?!<\/abbr>|<\/acronym>)/", "$1", $text); + $text = preg_replace("/\b(FAQ)s\b(?!<\/abbr>|<\/acronym>)/", "$1s", $text); + // HTTP + $text = preg_replace("/\b(HTTP)\b(?!<\/abbr>|<\/acronym>)/", "$1", $text); + // HTML + $text = preg_replace("/\b(HTML)\b(?!<\/abbr>|<\/acronym>)/", "$1", $text); + // CGI + $text = preg_replace("/\b(CGI)\b(?!<\/abbr>|<\/acronym>)/", "$1", $text); + // SSL + $text = preg_replace("/\b(SSL)\b(?!<\/abbr>|<\/acronym>)/", "$1", $text); + // PDF + $text = preg_replace("/\b(PDF\b\.?)(?!<\/abbr>|<\/acronym>)/", "$1", $text); + // IP + $text = preg_replace("/\b(IP)\b(?!<\/abbr>|<\/acronym>)/", "$1", $text); + // S/N + $text = preg_replace("/\b(S\/N)\b(?!<\/abbr>|<\/acronym>)/", "$1", $text); + // No. + $text = preg_replace("/\b(No\.|Num\.)(?!<\/abbr>|<\/acronym>)/", "$1", $text); + // ID. + $text = preg_replace("/\b(ID\.)(?!<\/abbr>|<\/acronym>)/", "$1", $text); + // Pic. + $text = preg_replace("/\b(Pic\.)(?!<\/abbr>|<\/acronym>)/", "$1", $text); + // URL. + $text = preg_replace("/\b(URL\b\.?)(?!<\/abbr>|<\/acronym>)/", "$1", $text); + // E-mail. + $text = preg_replace("/\b(E-?mail)\b(?!<\/abbr>|<\/acronym>)/i", "$1", $text); + // MIME + $text = preg_replace("/\b(MIME\b\.?)(?!<\/abbr>|<\/acronym>)/", "$1", $text); + // KB/MB/GB/TB from report_size() + $text = preg_replace("/(\d+) KB\)/", "$1 KB)", $text); + $text = preg_replace("/(\d+) MB\)/", "$1 MB)", $text); + $text = preg_replace("/(\d+) GB\)/", "$1 GB)", $text); + $text = preg_replace("/(\d+) TB\)/", "$1 TB)", $text); + // MRTG + $text = preg_replace("/\b(MRTG)\b(?!<\/abbr>|<\/acronym>)/", "$1", $text); + // Load the local extension + // Load it at last to prevent mark-up recursion + if (function_exists("markabbr_site")) { + $text = markabbr_site($text); + } + return $text; +} + +?> diff --git a/lib/php/monica/md5.inc.php b/lib/php/monica/md5.inc.php new file mode 100644 index 0000000..6f1a686 --- /dev/null +++ b/lib/php/monica/md5.inc.php @@ -0,0 +1,24 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// md5_raw: Return the raw MD5 binary digest +function md5_raw($content) +{ + $md5hex = md5($content); + for ($i = 0, $md5 = ""; $i < strlen($md5hex); $i += 2) { + $md5 .= chr(hexdec(substr($md5hex, $i, 2))); + } + return $md5; +} + +// md5_base64: Return the Base64-encoded MD5 digest +function md5_base64($content) +{ + return base64_encode(md5_raw($content)); +} + +?> diff --git a/lib/php/monica/mimeenc.inc.php b/lib/php/monica/mimeenc.inc.php new file mode 100644 index 0000000..519e859 --- /dev/null +++ b/lib/php/monica/mimeenc.inc.php @@ -0,0 +1,89 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// b64encode_header: Encode a piece of header text with Base-64 +// Refer to RFC-1522 4.1 +function b64encode_header($text, $charset) +{ + return "=?$charset?B?" . base64_encode($text) . "?="; +} + +// qpencode: Encode a piece of text with Quoted-Printable +// Refer to RFC-1521 5.1 +function qpencode($source) +{ + // Convert to RFC-822 CRLF (Rule #4) + $source = str_replace("\r\n", "\n", $source); + $source = str_replace("\n", "\r\n", $source); + $result = ""; + // Convert each character + for ($i = 0, $linelen = 0; $i < strlen($source); $i++) { + // Rule #4 (Line Breaks) + if (substr($source, $i, 2) == "\r\n") { + $result .= "\r\n"; + $linelen = 0; + $i++; + continue; + } + $c = substr($source, $i, 1); + $o = ord($c); + // Rule #2 (Literal representation) + if (($o >= 33 && $o <= 60) || ($o >= 62 && $o <= 126)) { + $char = $c; + // Rule #4 (Line Breaks) + } elseif ($c == "\r" || $c == "\n") { + $char = $c; + // Rule #3 (White Space) + } elseif ($o == 9 || $o == 32) { + // At the end of line + if ($i+1 == strlen($source) || substr($source, $i+1) == "\r") { + $char = sprintf("=%02X", $o); + // Not at the end of line + } else { + $char = $c; + } + // Rule #1 (General 8-bit representation) + } else { + $char = sprintf("=%02X", $o); + } + // Rule #5 (Soft Line Breaks) + if ($linelen + strlen($char) > 75) { + $result .= "=\r\n"; + $linelen = 0; + } + $result .= $char; + $linelen += strlen($char); + } + return $result; +} + +// qpencode_header: Encode a piece of header text with Quoted-Printable +// Refer to RFC-1522 4.2 +function qpencode_header($source, $charset) +{ + $result = ""; + // Convert each character + for ($i = 0; $i < strlen($source); $i++) { + $c = substr($source, $i, 1); + $o = ord($c); + // 4.2.3 + if ($o >= 33 && $o <= 126 && $c != "=" && $c != "?" && $c != "_" && $o != 32) { + $char = $c; + // 4.2.2 + } elseif ($o == 32) { + $char = "_"; + // 4.2.1 + } else { + $char = sprintf("=%02X", $o); + } + $result .= $char; + } + $result = "=?$charset?Q?$result?="; + return $result; +} + +?> diff --git a/lib/php/monica/mimetype.inc.php b/lib/php/monica/mimetype.inc.php new file mode 100644 index 0000000..03bfebd --- /dev/null +++ b/lib/php/monica/mimetype.inc.php @@ -0,0 +1,247 @@ + +// Copyright: Copyright (C) 2005-2009 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/runcmd.inc.php"; +require_once "monica/xfileio.inc.php"; + +// The fileinfo resource +$_MIMETYPE_FINFO = null; + +// check_mime_type: Try to decide the MIME type as possible +function check_mime_type($file, $name = null, $sugtype = null) +{ + // Default to the name of the file + if (is_null($name)) { + $name = $file; + } + // Obtain the file name suffix + $suffix = null; + if (!is_null($name)) { + $suffix = preg_match("/^.*(\.[^\.]*)$/", $name, $m)? strtolower($m[1]): ""; + } + // application/octet-stream is no difference to none + if (!is_null($sugtype) && $sugtype == "application/octet-stream") { + $sugtype = null; + } + + // Check the magic number first + if (is_null($GLOBALS["_MIMETYPE_FINFO"])) { + $GLOBALS["_MIMETYPE_FINFO"] = finfo_open(FILEINFO_MIME); + } + $type = preg_replace("/;.*$/", "", + finfo_file($GLOBALS["_MIMETYPE_FINFO"], $file)); + // Fix the known errors returned from magic checking + $type = _mimetype_fix_magic($type, $sugtype, $suffix); + // OK + return $type; +} + +// check_mime_type_content: Try to decide the MIME type as possible, from the file content +function check_mime_type_content(&$content, $name = null, $sugtype = null) +{ + // Obtain the file name suffix + $suffix = null; + if (!is_null($name)) { + $suffix = preg_match("/^.*(\.[^\.]*)$/", $name, $m)? strtolower($m[1]): ""; + } + // application/octet-stream is no difference to none + if (!is_null($sugtype) && $sugtype == "application/octet-stream") { + $sugtype = null; + } + + // Check the magic number first + if (is_null($GLOBALS["_MIMETYPE_FINFO"])) { + $GLOBALS["_MIMETYPE_FINFO"] = finfo_open(FILEINFO_MIME); + } + $type = preg_replace("/;.*$/", "", + finfo_buffer($GLOBALS["_MIMETYPE_FINFO"], $content)); + // Fix the known errors returned from magic checking + $type = _mimetype_fix_magic($type, $sugtype, $suffix); + // OK + return $type; +} + +// _mimetype_fix_magic: Fix the known errors returned from magic checking +function _mimetype_fix_magic($type, $sugtype = null, $suffix = null) +{ + // Fix known errors + switch ($type) { + // MS-Excel, MS-PowerPoint files are always recognized as application/msword + case "application/msword": + // Starting from Debian Lenny 5.0.0 (libmagic1 4.26-1), they are sometimes + // unrecognizable. By imacat 2009-03-26. + case false: + // There is a suggested type submitted. It should be trusted + if (!is_null($sugtype)) { + switch ($sugtype) { + case "application/msexcell": + case "application/vnd.ms-excel": + return "application/vnd.ms-excel"; + break; + case "application/vnd.ms-powerpoint": + return "application/vnd.ms-powerpoint"; + break; + case "application/msword": + return "application/msword"; + break; + } + } + // Check the file name suffix + if (!is_null($suffix)) { + switch ($suffix) { + case ".xls": + case ".xlt": + return "application/vnd.ms-excel"; + break; + case ".ppt": + case ".pot": + return "application/vnd.ms-powerpoint"; + break; + case ".doc": + case ".dot": + return "application/msword"; + break; + } + } + // We have no choice but to trust the magic number check result + return $type; + break; + + // OpenOffice.org documents are always recognized as application/x-zip + case "application/x-zip": + // There is a suggested type submitted. It should be trusted + if (!is_null($sugtype)) { + switch ($sugtype) { + case "application/vnd.oasis.opendocument.text": + case "application/vnd.oasis.opendocument.text-template": + case "application/vnd.oasis.opendocument.spreadsheet": + case "application/vnd.oasis.opendocument.spreadsheet-template": + case "application/vnd.oasis.opendocument.presentation": + case "application/vnd.oasis.opendocument.presentation-template": + case "application/vnd.sun.xml.writer": + case "application/vnd.sun.xml.writer.template": + case "application/vnd.sun.xml.calc": + case "application/vnd.sun.xml.calc.template": + case "application/vnd.sun.xml.impress": + case "application/vnd.sun.xml.impress.template": + case "application/x-zip": + return $sugtype; + break; + } + } + // Check the file name suffix + if (!is_null($suffix)) { + switch ($suffix) { + case ".odt": + return "application/vnd.oasis.opendocument.text"; + break; + case ".ott": + return "application/vnd.oasis.opendocument.text-template"; + break; + case ".ods": + return "application/vnd.oasis.opendocument.spreadsheet"; + break; + case ".ots": + return "application/vnd.oasis.opendocument.spreadsheet-template"; + break; + case ".odp": + return "application/vnd.oasis.opendocument.presentation"; + break; + case ".otp": + return "application/vnd.oasis.opendocument.presentation-template"; + break; + case ".sxw": + return "application/vnd.sun.xml.writer"; + break; + case ".stw": + return "application/vnd.sun.xml.writer.template"; + break; + case ".stc": + return "application/vnd.sun.xml.calc"; + break; + case ".sxc": + return "application/vnd.sun.xml.calc.template"; + break; + case ".sxi": + return "application/vnd.sun.xml.impress"; + break; + case ".sti": + return "application/vnd.sun.xml.impress.template"; + break; + case ".zip": + return "application/x-zip"; + break; + } + } + // We have no choice but to trust the magic number check result + return $type; + break; + + // Default to trust the magic number check result + default: + return $type; + break; + } +} + +// Only do this when fileinfo extension is not loaded +if (!extension_loaded("fileinfo")) { + +if (!defined("FILEINFO_MIME")) { + define("FILEINFO_MIME", true); +} + +// finfo_open: Create a new fileinfo resource +function finfo_open($options) +{ + return null; +} + +// finfo_file: Return information about a file +function finfo_file($finfo, $file_name) +{ + return mime_content_type($file_name); +} + +// finfo_buffer: Return information about a string buffer +function finfo_buffer($finfo, $string) +{ + // Check the MIME type from the file content with /usr/bin/file + // The result is not countable with MS-Excel files. + // Use mime_content_type() to obtain a consistent result to fed to + // _mimetype_fix_magic(). + //$type = _mimetype_check_content_with_file($content); + $file = tempnam(session_save_path(), + PACKAGE . "-" . basename(__FILE__) . "-finfo_buffer-"); + // xfupdate() is not working with files created with tempnam() (why?) + xfupdate($file, $string); + $type = mime_content_type($file); + unlink($file); +} + +// _mimetype_check_content_with_file: Check the MIME type from the file content with /usr/bin/file +function _mimetype_check_content_with_file(&$content) +{ + // Use the file utility to do this + $cmd = array("/usr/bin/file", "-i", "-"); + $output = xruncmd($cmd, $content); + // Remove the filename (should be "standard input:") + $type = preg_replace("/^[^:]+:\s+/", "", $output); + // Remove the trailing space (and maybe a suffix description) + $type = preg_replace("/(?:,.+)?\n$/", "", $type); + return $type; + +} + +} + +?> diff --git a/lib/php/monica/mkalldir.inc.php b/lib/php/monica/mkalldir.inc.php new file mode 100644 index 0000000..8b54014 --- /dev/null +++ b/lib/php/monica/mkalldir.inc.php @@ -0,0 +1,38 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/rel2abs.inc.php"; + +// mkalldir: Create all the components of a directory +// Input: Directory name $dir. It won't check at all. +// Output: true if success, false if failed +function mkalldir($dir) +{ + // Standardize it + $dir = stdpath($dir); + // Directories to create + $dirs = array(); + // Find all the directories to create + while ($dir != "" && !file_exists($dir)) { + $dirs[] = $dir; + $dir = dirname($dir); + } + // Create from the last one + for ($i = count($dirs) - 1; $i >= 0; $i--) { + if (mkdir($dirs[$i], 0755) === false) { + return false; + } + } + return true; +} + +?> diff --git a/lib/php/monica/mkdtemp.inc.php b/lib/php/monica/mkdtemp.inc.php new file mode 100644 index 0000000..3d72e68 --- /dev/null +++ b/lib/php/monica/mkdtemp.inc.php @@ -0,0 +1,28 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// mkdtemp: create a temporarily working directory +function mkdtemp() +{ + // Find out our context + $trace = debug_backtrace(); + $func = (count($trace) > 1? $trace[1]["function"]: "_GLOBAL"); + $file = preg_replace("/\..*$/", "", basename($trace[0]["file"])); + $pkg = (defined("PACKAGE")? PACKAGE: "unknown"); + $prefix = sprintf("monica-%s-%s-%s-", $pkg, $file, $func); + $dir = session_save_path(); + if ($dir == "") { + $dir = "/tmp"; + } + $result = tempnam($dir, $prefix); + unlink($result); + mkdir($result); + chmod($result, 0700); + return $result; +} + +?> diff --git a/lib/php/monica/monica.inc.php b/lib/php/monica/monica.inc.php new file mode 100644 index 0000000..ecfaea3 --- /dev/null +++ b/lib/php/monica/monica.inc.php @@ -0,0 +1,117 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// All the monica files +require_once "monica/a2html.inc.php"; +require_once "monica/actlog.inc.php"; +require_once "monica/addcol.inc.php"; +require_once "monica/addget.inc.php"; +require_once "monica/addslash.inc.php"; +require_once "monica/altlang.inc.php"; +require_once "monica/big5.inc.php"; +require_once "monica/callform.inc.php"; +require_once "monica/captitle.inc.php"; +require_once "monica/cgiemu.inc.php"; +require_once "monica/checker.inc.php"; +require_once "monica/chkfunc.inc.php"; +require_once "monica/chkpriv.inc.php"; +require_once "monica/chkwrite.inc.php"; +require_once "monica/commtext.inc.php"; +require_once "monica/copyyear.inc.php"; +require_once "monica/country.inc.php"; +require_once "monica/cracklib.inc.php"; +require_once "monica/curtime.inc.php"; +require_once "monica/decform.inc.php"; +require_once "monica/echoform.inc.php"; +require_once "monica/email.inc.php"; +require_once "monica/encrypt.inc.php"; +require_once "monica/errmsg.inc.php"; +require_once "monica/errhndl.inc.php"; +require_once "monica/fetchrec.inc.php"; +require_once "monica/form.inc.php"; +require_once "monica/formfunc.inc.php"; +require_once "monica/formreg.inc.php"; +require_once "monica/gb2312.inc.php"; +require_once "monica/geoip.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/guest.inc.php"; +require_once "monica/hires.inc.php"; +require_once "monica/htmlchar.inc.php"; +require_once "monica/html401.inc.php"; +require_once "monica/http.inc.php"; +require_once "monica/https.inc.php"; +require_once "monica/init.inc.php"; +require_once "monica/ipv4addr.inc.php"; +require_once "monica/lastmodf.inc.php"; +require_once "monica/links.inc.php"; +require_once "monica/list.inc.php"; +require_once "monica/listpref.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/logout.inc.php"; +require_once "monica/mail.inc.php"; +require_once "monica/markabbr.inc.php"; +require_once "monica/md5.inc.php"; +require_once "monica/mkalldir.inc.php"; +require_once "monica/mkdtemp.inc.php"; +require_once "monica/mimetype.inc.php"; +require_once "monica/mimeenc.inc.php"; +require_once "monica/mysql.inc.php"; +require_once "monica/newpass.inc.php"; +require_once "monica/news.inc.php"; +require_once "monica/newsn.inc.php"; +require_once "monica/page.inc.php"; +require_once "monica/page2rel.inc.php"; +require_once "monica/pagefunc.inc.php"; +require_once "monica/parseurl.inc.php"; +require_once "monica/passwd.inc.php"; +require_once "monica/pic.inc.php"; +require_once "monica/pinyin.inc.php"; +require_once "monica/postgres.inc.php"; +require_once "monica/preview.inc.php"; +require_once "monica/process.inc.php"; +require_once "monica/rel2abs.inc.php"; +require_once "monica/request.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/rfc1521.inc.php"; +require_once "monica/rfc1738.inc.php"; +require_once "monica/rfc2396.inc.php"; +require_once "monica/rfc822.inc.php"; +require_once "monica/rmalldir.inc.php"; +require_once "monica/rmofile.inc.php"; +require_once "monica/runcmd.inc.php"; +require_once "monica/scptpriv.inc.php"; +require_once "monica/server.inc.php"; +require_once "monica/sitesize.inc.php"; +require_once "monica/spltline.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/sqlconst.inc.php"; +require_once "monica/sqllogin.inc.php"; +require_once "monica/timezone.inc.php"; +require_once "monica/trimtext.inc.php"; +require_once "monica/unauth.inc.php"; +require_once "monica/unicode.inc.php"; +require_once "monica/upload.inc.php"; +require_once "monica/urlregex.inc.php"; +require_once "monica/userhome.inc.php"; +require_once "monica/username.inc.php"; +require_once "monica/userpref.inc.php"; +require_once "monica/usrconst.inc.php"; +require_once "monica/validate.inc.php"; +require_once "monica/xfileio.inc.php"; +require_once "monica/xhtml.inc.php"; +require_once "monica/zh2py.inc.php"; +require_once "monica/zhnum.inc.php"; +// Subroutines that are not used +//require_once "monica/unused.inc.php"; + +?> diff --git a/lib/php/monica/mysql.inc.php b/lib/php/monica/mysql.inc.php new file mode 100644 index 0000000..1e38ff0 --- /dev/null +++ b/lib/php/monica/mysql.inc.php @@ -0,0 +1,628 @@ + +// Copyright: Copyright (C) 2001-2008 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines with high precedence +require_once "monica/sqlconst.inc.php"; +// Referenced subroutines +require_once "monica/errhndl.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/sqllogin.inc.php"; + +// Settings +$_MYSQL_CONN = null; + +// xmysql_connect: Connect to the MySQL database +function xmysql_connect($database = null) +{ + global $_MYSQL_CONN; + // Connected + if (!is_null($_MYSQL_CONN)) { + return; + } + // Obtain the SQL log-in information + if (is_null($database)) { + if (getenv("MYSQL_DB") !== false) { + $database = getenv("MYSQL_DB"); + } elseif (defined("PACKAGE")) { + $database = PACKAGE; + } + } + if (getenv("MYSQL_HOST") !== false) { + $host = getenv("MYSQL_HOST"); + } else { + $host = null; + } + + // Login with from SQLLOGIN environment variable as a web application + // php-cgi does not have STDIN and STDERR even on console + if (PHP_SAPI != "cli") { + $r = get_sql_login_info(SQL_MYSQL, $database, $host); + // Connect it + $_MYSQL_CONN = mysql_connect($r["MYSQL_HOST"], $r["MYSQL_USER"], $r["MYSQL_PW"]); + if ($_MYSQL_CONN === false) { + $_MYSQL_CONN = null; + trigger_error("Failed connecting to the MySQL server.\n" + . mysql_errno() . " " . mysql_error(), E_USER_ERROR); + } + + // Ask the password from the console + } else { + $user = null; + $subseq = false; + set_error_handler("null_error_handler"); + $_MYSQL_CONN = mysql_connect(); + restore_error_handler(); + while ($_MYSQL_CONN === false) { + if ($subseq) { + fprintf(STDERR, "%s\n", $GLOBALS["php_errormsg"]); + sleep(5); + } + // Obtain the current login user + if ( is_null($user) + && preg_match("/ denied for user '(.+?)'\@'.+?'/", $GLOBALS["php_errormsg"], $m)) { + $user = $m[1]; + } + $subseq = true; + // Disable console echo + system("/bin/stty -echo"); + fprintf(STDERR, !is_null($user)? "MySQL password for $user: ": + "MySQL password: "); + $passwd = fgets(STDIN); + fprintf(STDERR, "\n"); + // Restore console echo status + system("/bin/stty echo"); + // STDIN is not available + if ($passwd === false) { + die(THIS_FILE . ": Failed connecting to the PostgreSQL server\n"); + } + $passwd = trim($passwd); + set_error_handler("null_error_handler"); + $_MYSQL_CONN = mysql_connect(null, null, $passwd); + restore_error_handler(); + } + } + + // Select the database + $result = mysql_select_db($database); + if ($result === false) { + trigger_error("Failed mysql_select_db(\"$database\").\n" + . mysql_errno() . " " . mysql_error(), E_USER_ERROR); + } + + // Set the character set + $charset = defined("SQL_CHARSET")? SQL_CHARSET: "utf8"; + $set = "SET NAMES '" . mysql_escape_string($charset) . "';\n"; + xmysql_query($set); + + return; +} + +// xmysql_close: Disconnect from the MySQL database +function xmysql_close() +{ + global $_MYSQL_CONN; + if (is_null($_MYSQL_CONN)) { + return; + } + $result = mysql_close($_MYSQL_CONN); + if ($result !== true) { + trigger_error("Failed disconnecting from the MySQL server.\n" + . mysql_errno() . " " . mysql_error(), E_USER_ERROR); + } + $_MYSQL_CONN = null; + return; +} + + +///////////////////////// +// Concurrency Control: Transactions and Locks +///////////////////////// +$_MYSQL_IN_TRANSACTION = false; +// mysql_begin: Begin a MySQL transaction +function mysql_begin() +{ + if (!$GLOBALS["_MYSQL_IN_TRANSACTION"]) { + $begin = "START TRANSACTION;\n"; + xmysql_query($begin); + $GLOBALS["_MYSQL_IN_TRANSACTION"] = true; + } +} +// mysql_commit: Commit a MySQL transaction +function mysql_commit() +{ + if ($GLOBALS["_MYSQL_IN_TRANSACTION"]) { + $commit = "COMMIT;\n"; + xmysql_query($commit); + $GLOBALS["_MYSQL_IN_TRANSACTION"] = false; + } +} +// mysql_rollback: Rollback a MySQL transaction +function mysql_rollback() +{ + if ($GLOBALS["_MYSQL_IN_TRANSACTION"]) { + $rollback = "ROLLBACK;\n"; + // This generate errors under MyIASM + //xmysql_query($rollback); + mysql_query($rollback); + $GLOBALS["_MYSQL_IN_TRANSACTION"] = false; + } +} + +// mysql_lock: MySQL table-locking handler +// We need this to wrok around the stupid MySQL table locking mechanism +// Input: An associative array, where its keys are the tables to lock, +// and its values can be one of the following: +// LOCK_SH: Request a read lock +// LOCK_EX: Request a write lock +// LOCK_UN: Unlock the previously obtained lock +// Or null to unlock everything. +// Return: None. Errors are directed to error handlers +function mysql_lock($newlocks = null) +{ + // Keep the current lock table static + static $curlocks = array(); + + // Save the previous locks + $lastlocks = $curlocks; + + // Unlock everything + if (is_null($newlocks)) { + $curlocks = array(); + } else { + // Adjust the current lock table + foreach (array_keys($newlocks) as $table) { + switch ($newlocks[$table]) { + case LOCK_SH: + case LOCK_EX: + $curlocks[$table] = $newlocks[$table]; + break; + case LOCK_UN: + unset($curlocks[$table]); + break; + default: + trigger_error("Bad SQL lock request: \"$newlocks[$table]\" on table \"$table\".", E_USER_ERROR); + } + } + } + + $lockstr = _mysql_locks2str($curlocks); + // Return if nothing is changed + if ($lockstr == _mysql_locks2str($lastlocks)) { + return; + } + + // Rollback everything if not committed yet + // LOCK TABLE/UNLOCK TABLE implicitly COMMIT the previous transaction. + // This is bad. + if ($GLOBALS["_MYSQL_IN_TRANSACTION"]) { + mysql_rollback(); + } + + // Has something to lock + if ($lockstr !== "") { + $locktable = "LOCK TABLES $lockstr;\n"; + // Nothing to lock - release all locks + } else { + $locktable = "UNLOCK TABLES;\n"; + } + xmysql_query($locktable); + + return; +} + +// xmysql_query: Do a MySQL query and report the error +function xmysql_query($query) +{ + $result = mysql_query($query); + if ($result === false) { + trigger_error("Failed mysql_query().\n$query\n" + . mysql_errno() . " " . mysql_error(), E_USER_ERROR); + } + return $result; +} + +// mysql_seek: Move the MySQL result pointer +function mysql_seek($result, $offset) +{ + $result = mysql_data_seek($result, $offset); + if ($result === false) { + trigger_error("Failed mysql_data_seek().\n" + . mysql_errno() . " " . mysql_error(), E_USER_ERROR); + } + return $result; +} + +// xmysql_fetch_assoc: Return a MySQL row as an associative array +function xmysql_fetch_assoc($result) +{ + // Fetch the raw data now + $row = mysql_fetch_assoc($result); + // Return the error + if (!is_array($row)) { + return $row; + } + + // Adjust the boolean columns + foreach (mysql_cols_of_type($result, SQL_TYPE_BOOLEAN, SQL_FETCH_ASSOC) as $col) { + $row[$col] = !is_null($row[$col]); + } + // Adjust the integer columns + foreach (mysql_cols_of_type($result, SQL_TYPE_INTEGER, SQL_FETCH_ASSOC) as $col) { + if (!is_null($row[$col])) { + settype($row[$col], "integer"); + } + } + // Adjust the big integer columns + foreach (mysql_cols_of_type($result, SQL_TYPE_BIGINT, SQL_FETCH_ASSOC) as $col) { + if ( !is_null($row[$col]) + && $row[$col] >= -2147483647 + && $row[$col] <= 2147483647) { + settype($row[$col], "integer"); + } + } + // Adjust the float columns + foreach (mysql_cols_of_type($result, SQL_TYPE_FLOAT, SQL_FETCH_ASSOC) as $col) { + if (!is_null($row[$col])) { + settype($row[$col], "float"); + } + } + + return $row; +} + +// xmysql_fetch_row: Return a MySQL row as an numeric array +function xmysql_fetch_row($result) +{ + // Fetch the raw data now + $row = mysql_fetch_row($result); + // Return the error + if (!is_array($row)) { + return $row; + } + + // Adjust the boolean columns + foreach (mysql_cols_of_type($result, SQL_TYPE_BOOLEAN, SQL_FETCH_ROW) as $col) { + $row[$col] = !is_null($row[$col]); + } + // Adjust the integer columns + foreach (mysql_cols_of_type($result, SQL_TYPE_INTEGER, SQL_FETCH_ROW) as $col) { + if (!is_null($row[$col])) { + settype($row[$col], "integer"); + } + } + // Adjust the big integer columns + foreach (mysql_cols_of_type($result, SQL_TYPE_BIGINT, SQL_FETCH_ROW) as $col) { + if ( !is_null($row[$col]) + && $row[$col] >= -2147483647 + && $row[$col] <= 2147483647) { + settype($row[$col], "integer"); + } + } + // Adjust the float columns + foreach (mysql_cols_of_type($result, SQL_TYPE_FLOAT, SQL_FETCH_ROW) as $col) { + if (!is_null($row[$col])) { + settype($row[$col], "float"); + } + } + + return $row; +} + +// mysql_tables: Obtain a list of available MySQL tables +// and report the error +function mysql_tables($db = null) +{ + if (is_null($db)) { + $select = "SHOW TABLES;\n"; + } else { + $select = "SHOW TABLES FROM $db;\n"; + } + $result = xmysql_query($select); + $count = mysql_num_rows($result); + for ($i = 0, $tables = array(); $i < $count; $i++) { + $row = mysql_fetch_row($result); + $tables[] = $row[0]; + } + sort($tables); + return $tables; +} + +// mysql_cols: Obtain the column list of a MySQL table +function mysql_cols($table) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($table, $cache)) { + return $cache[$table]; + } + + $select = "SHOW COLUMNS FROM $table;\n"; + $result = xmysql_query($select); + $count = mysql_num_rows($result); + for ($i = 0, $cache[$table] = array(); $i < $count; $i++) { + $row = mysql_fetch_row($result); + $cache[$table][] = $row[0]; + } + return $cache[$table]; +} + +// mysql_cols_ml: Return a list of multi-lingual columns in a MySQL table +function mysql_cols_ml($table) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($table, $cache)) { + return $cache[$table]; + } + + // Get the columns that have language variants + $cols = mysql_cols($table); + $cache[$table] = array(); + $suffix = "_" . getlang(LN_DATABASE); + $len = strlen($suffix); + for ($i = 0; $i < count($cols); $i++) { + // It has a language suffix + if (substr($cols[$i], -$len) == $suffix) { + $cache[$table][] = substr($cols[$i], 0, -$len); + } + } + + return $cache[$table]; +} + +// mysql_cols_nl: Return a list of columns without their multi-lingual +// deviants in a MySQL table +function mysql_cols_nl($table) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($table, $cache)) { + return $cache[$table]; + } + + // Get the columns that have language variants + $cols = mysql_cols($table); + $langcols = mysql_cols_ml($table); + + // Remove those language variants + $cache[$table] = array(); + for ($i = 0; $i < count($cols); $i++) { + $pos = strrpos($cols[$i], "_"); + // No suffix + if ($pos === false) { + $cache[$table][] = $cols[$i]; + // Check the prefix + } else { + $prefix = substr($cols[$i], 0, $pos); + // The prefix is one of the language columns + if (in_array($prefix, $langcols)) { + // Not counted yet + if (!in_array($prefix, $cache[$table])) { + $cache[$table][] = $prefix; + } + // An ordinary prefix + } else { + $cache[$table][] = $cols[$i]; + } + } + } + + return $cache[$table]; +} + +// mysql_cols_of_type: Return the columns in a certain data type +function mysql_cols_of_type($result, $type, $format = SQL_FETCH_ASSOC) +{ + $result_key = _mysql_result_hashkey($result); + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($result_key, $cache)) { + return $cache[$result_key][$type][$format]; + } + + // Check each field type + $count = mysql_num_fields($result); + $cols = array( + SQL_TYPE_BOOLEAN => array( + SQL_FETCH_ASSOC => array(), + SQL_FETCH_ROW => array(), + ), + SQL_TYPE_BLOB => array( + SQL_FETCH_ASSOC => array(), + SQL_FETCH_ROW => array(), + ), + SQL_TYPE_INTEGER => array( + SQL_FETCH_ASSOC => array(), + SQL_FETCH_ROW => array(), + ), + SQL_TYPE_BIGINT => array( + SQL_FETCH_ASSOC => array(), + SQL_FETCH_ROW => array(), + ), + SQL_TYPE_FLOAT => array( + SQL_FETCH_ASSOC => array(), + SQL_FETCH_ROW => array(), + ), + ); + for ($i = 0; $i < $count; $i++) { + $coltype = mysql_field_type($result, $i); + $colname = mysql_field_name($result, $i); + $collen = mysql_field_len($result, $i); + if ($coltype == "string" && $collen == 0) { + $cols[SQL_TYPE_BOOLEAN][SQL_FETCH_ROW][] = $i; + $cols[SQL_TYPE_BOOLEAN][SQL_FETCH_ASSOC][] = $colname; + } elseif ($coltype == "blob") { + $cols[SQL_TYPE_BLOB][SQL_FETCH_ROW][] = $i; + $cols[SQL_TYPE_BLOB][SQL_FETCH_ASSOC][] = $colname; + } elseif ($coltype == "int" && $collen <= 11) { + $cols[SQL_TYPE_INTEGER][SQL_FETCH_ROW][] = $i; + $cols[SQL_TYPE_INTEGER][SQL_FETCH_ASSOC][] = $colname; + } elseif ($coltype == "int" && $collen == 20) { + $cols[SQL_TYPE_BIGINT][SQL_FETCH_ROW][] = $i; + $cols[SQL_TYPE_BIGINT][SQL_FETCH_ASSOC][] = $colname; + } elseif ($coltype == "real") { + $cols[SQL_TYPE_FLOAT][SQL_FETCH_ROW][] = $i; + $cols[SQL_TYPE_FLOAT][SQL_FETCH_ASSOC][] = $colname; + } + } + + // Cache it + $cache[$result_key] = $cols; + return $cols[$type][$format]; +} + +// mysql_col_lens: Obtain the column lengths of a MySQL table +function mysql_col_lens($table) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($table, $cache)) { + return $cache[$table]; + } + + $select = "SELECT * FROM $table LIMIT 1;\n"; + $result = xmysql_query($select); + $count = mysql_num_fields($result); + for ($i = 0, $cache[$table] = array(); $i < $count; $i++) { + $cache[$table][mysql_field_name($result, $i)] = mysql_field_len($result, $i); + } + + // Hash the multi-lingual columns + $lndb = getlang(LN_DATABASE); + foreach (mysql_cols_ml($table) as $col) { + $cache[$table][$col] = $cache[$table][$col . "_" . $lndb]; + } + + return $cache[$table]; +} + +// mysql_strcat: Concatenate strings in MySQL +// MySQL uses the CONCAT() function to concatenate strings +function mysql_strcat() +{ + $strs = func_get_args(); + return "CONCAT(" . implode(", ", $strs) . ")"; +} + +// mysql_lastupd: Obtain the last updated time of a list of tables +function mysql_lastupd($tables) +{ + // Bounce if no tables supplied + if (is_null($tables) || count($tables) == 0) { + return; + } + // Remove duplicates + $tables = array_values(array_unique($tables)); + // Query + $conds = array(); + foreach ($tables as $table) { + $conds[] = "tabname='" . mysql_escape_string($table) . "'"; + } + $select = "SELECT mtime FROM mtime" + . " WHERE " . implode(" OR ", $conds) + . " ORDER BY mtime DESC LIMIT 1;\n"; + $result = xmysql_query($select); + // Bounce if no data found + if (mysql_num_rows($result) != 1) { + return; + } + // Return the result + $row = xmysql_fetch_assoc($result); + return $row["mtime"]; +} + +// mysql_dbsize: Obtain the size of the database +function mysql_dbsize() +{ + $select = "SHOW TABLE STATUS;\n"; + $result = xmysql_query($select); + $count = mysql_num_rows($result); + for ($i = 0, $size = 0; $i < $count; $i++) { + $row = xmysql_fetch_row($result); + $size += $row["Data_length"]; + } + return $size; +} + +// mysql_date: Return date in a predefined format +function mysql_date($expr, $format) +{ + switch ($format) { + case SQL_YYYYMMDD: + return "DATE_FORMAT($expr, '%Y%m%d')"; + case SQL_YYYY_YYYYMMDD: + return "DATE_FORMAT($expr, '%Y/%Y%m%d')"; + case SQL_MM_DD: + return "DATE_FORMAT($expr, '%m-%d')"; + case SQL_M_D_EN: + return "DATE_FORMAT($expr, '%c/%e')"; + case SQL_M_D_ZHTW: + return "DATE_FORMAT($expr, '%c月%e日')"; + case SQL_M_D_DE: + return "DATE_FORMAT($expr, '%e.%c')"; + case SQL_HH_MM: + return "TIME_FORMAT($expr, '%H:%i')"; + } +} + +// mysql_re: Return the MySQL regular expression operator +function mysql_re() +{ + return "REGEXP"; +} + +// _mysql_result_hashkey: Generate a hash key from a MySQL query result +function _mysql_result_hashkey($result) +{ + // Use the output of var_dump + ob_start(); + var_dump($result); + $key = ob_get_contents(); + ob_end_clean(); + return $key; +} + +// _mysql_locks2str: Convert lock array to SQL text string +function _mysql_locks2str($locks) +{ + $reads = array(); + $writes = array(); + // Adjust the current lock table + foreach (array_keys($locks) as $table) { + switch ($locks[$table]) { + case LOCK_SH: + $reads[] = $table; + break; + case LOCK_EX: + $writes[] = $table; + break; + } + } + sort($reads); + sort($writes); + $phrases = array(); + foreach ($writes as $table) { + $phrases[] = "$table WRITE"; + } + foreach ($reads as $table) { + $phrases[] = "$table READ"; + } + return implode(", ", $phrases); +} + +?> diff --git a/lib/php/monica/newpass.inc.php b/lib/php/monica/newpass.inc.php new file mode 100644 index 0000000..16a8ef8 --- /dev/null +++ b/lib/php/monica/newpass.inc.php @@ -0,0 +1,114 @@ + +// Copyright: Copyright (C) 2004-2009 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/cracklib.inc.php"; +require_once "monica/runcmd.inc.php"; + +// Settings +define("NEWPASS_PRONOUNCABLE", 0); +define("NEWPASS_RANDOM", 1); + +define("_NEWPASS_RANDOM_LEN", 8); +$_NEWPASS_APG = array("/usr/bin/apg", "-n", "1", "-d"); +$_NEWPASS_BAD_CHARS = array("0", "O", "1", "l", "I", "|"); + + +// newpass: Generate a new password +function newpass($mode = NEWPASS_PRONOUNCABLE) +{ + switch ($mode) { + // A random password + case NEWPASS_RANDOM: + return _newpass_random(); + break; + + // A pronouncable password + case NEWPASS_PRONOUNCABLE: + default: + return _newpass_pronouncable(); + break; + } +} + +// _newpass_pronouncable: Generate a new pronouncable password +function _newpass_pronouncable() +{ + global $_NEWPASS_BAD_CHARS, $_NEWPASS_APG; + // Loop until we get a good password + while (true) { + $passwd = xruncmd($_NEWPASS_APG, ""); + // Avoid bad characters + if (_newpass_bad_char($passwd)) { + continue; + } + // Check the password strength with Cracklib + if (!crack_check($passwd)) { + continue; + } + return $passwd; + } +} + +// _newpass_random: Generate a new random password +function _newpass_random() +{ + global $_NEWPASS_BAD_CHARS; + // Loop until we get a good password + while (true) { + // Generate a password + $passwd = ""; + while (strlen($passwd) < _NEWPASS_RANDOM_LEN) { + $type = mt_rand(0, 2); + switch ($type) { + // Number + case 0: + $c = mt_rand(0, 9); + break; + // Lower-case character + case 1: + $c = chr(ord("a") + mt_rand(0, 25)); + break; + // Upper-case character + case 2: + $c = chr(ord("A") + mt_rand(0, 25)); + break; + } + // Avoid bad characters + if (in_array($c, $_NEWPASS_BAD_CHARS)) { + continue; + } + $passwd .= $c; + } + // Check the password strength with Cracklib + if (!crack_check($passwd)) { + continue; + } + return $passwd; + } +} + +// _newpass_bad_char: If the new password contains a bad character +function _newpass_bad_char($passwd) +{ + global $_NEWPASS_BAD_CHARS; + for ($i = 0; $i < strlen($passwd); $i++) { + $c = substr($passwd, $i, 1); + // Found + if (in_array($c, $_NEWPASS_BAD_CHARS)) { + return true; + } + } + // Not found + return false; +} + +?> diff --git a/lib/php/monica/news.inc.php b/lib/php/monica/news.inc.php new file mode 100644 index 0000000..5888dc3 --- /dev/null +++ b/lib/php/monica/news.inc.php @@ -0,0 +1,112 @@ + +// Copyright: Copyright (C) 2006-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/chkfunc.inc.php"; +require_once "monica/commtext.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/sql.inc.php"; + +// news_title: Obtain the news article title +function news_title($sn) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $sn + if (is_null($sn)) { + return t_notset(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + + // Check the serial number first + if (!check_sn($sn)) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Query + $lndb = getlang(LN_DATABASE); + // Default language + if (getlang() == DEFAULT_LANG) { + $title = sql_strcat("to_char(date, 'YYYY-MM-DD')", "' '", + "title_$lndb") . " AS title"; + // Fall back to the default language + } else { + $lndbdef = ln(DEFAULT_LANG, LN_DATABASE); + $title = sql_strcat("to_char(date, 'YYYY-MM-DD')", "' '", + "COALESCE(title_$lndb, title_$lndbdef)") . " AS title"; + } + $select = "SELECT $title FROM news" + . " WHERE sn=$sn;\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$sn] = $row["title"]; + + return $cache[$sn]; +} + +// news_id: Obtain the news article ID. +function news_id($sn) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $sn + if (is_null($sn)) { + return t_notset(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + + // Check the serial number first + if (!check_sn($sn)) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Query + $select = "SELECT date, ord FROM news" + . " WHERE sn=$sn;\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$sn] = newsid_compose($row["date"], $row["ord"]); + + return $cache[$sn]; +} + +// newsid_compose: Compose the news article ID +function newsid_compose($date, $ord) +{ + return date("Ymd", strtotime($date)) . sprintf("%02d", $ord); +} + +?> diff --git a/lib/php/monica/newsn.inc.php b/lib/php/monica/newsn.inc.php new file mode 100644 index 0000000..dc3376a --- /dev/null +++ b/lib/php/monica/newsn.inc.php @@ -0,0 +1,40 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/sql.inc.php"; + +// new_sn: Generate a new random serial number for an SQL table +function new_sn($table) +{ + // S/N is always 9 digits + do { + // Generate a random serial number + $sn = mt_rand(100000000, 999999999); + // Check if this serial number exists + $select = "SELECT sn FROM $table WHERE sn=$sn;\n"; + $result = sql_query($select); + } while (sql_num_rows($result) > 0); + return $sn; +} + +// new_sn_assoc: Generate a new random serial number for an associative array +function new_sn_assoc(&$assoc) +{ + // S/N is always 9 digits + do { + // Generate a random serial number + $sn = mt_rand(100000000, 999999999); + } while (array_key_exists($sn, $assoc)); + return $sn; +} + +?> diff --git a/lib/php/monica/page.inc.php b/lib/php/monica/page.inc.php new file mode 100644 index 0000000..fad40f1 --- /dev/null +++ b/lib/php/monica/page.inc.php @@ -0,0 +1,329 @@ + +// Copyright: Copyright (C) 2005-2008 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/getlang.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/sql.inc.php"; + +// Page: A web page +class Page +{ + protected $_title; + protected $_path; + protected $_ord; + protected $_lang; + protected $_sitemap; + protected $_sub; + + // __construct: Initiate the web page + function __construct($args) + { + // An array of arguments + if (is_array($args)) { + // Set the title + if (!array_key_exists("title", $args)) { + trigger_error("Please specify the page title.", E_USER_ERROR); + } + $this->title($args["title"]); + // Set the page path + if (!array_key_exists("path", $args)) { + trigger_error("Please specify the page path.", E_USER_ERROR); + } + $this->path($args["path"]); + // Set the order + $this->ord(array_key_exists("ord", $args)? $args["ord"]: 5000); + // Set the language + $this->lang(array_key_exists("lang", $args)? $args["lang"]: null); + // Set if this page is to be shown on the site map + $this->sitemap(array_key_exists("sitemap", $args)? + $args["sitemap"]: true); + + // A Page object + } elseif (strtolower(get_class($args)) == "page") { + $this->title($args->title()); + $this->path($args->path()); + $this->ord($args->ord()); + $this->lang($args->lang()); + $this->sitemap($args->sitemap()); + + // Invalid argument + } else { + trigger_error("Please specify the page arguments.", E_USER_ERROR); + } + } + + // title: Set/return the page title + function title($title = null) + { + if (func_num_args() > 0) { + $this->_title = $title; + } + return $this->_title; + } + + // path: Set/return the page path + function path($path = null) + { + if (func_num_args() > 0) { + $this->_path = $path; + } + return $this->_path; + } + + // ord: Set/return the page order + function ord($ord = null) + { + if (func_num_args() > 0) { + $this->_ord = $ord; + } + return $this->_ord; + } + + // lang: Set/return the page language + function lang($lang = null) + { + if (func_num_args() > 0) { + // Delete it + if (is_null($lang)) { + $this->_lang = null; + // Set it + } else { + $this->_lang = $lang; + } + } + return $this->_lang; + } + + // sitemap: Set/return if this page is to be shown on the site map + function sitemap($sitemap = true) + { + if (func_num_args() > 0) { + $this->_sitemap = $sitemap; + } + return $this->_sitemap; + } + + // sub: Set/return the pages under this page + function sub($pagelist = null) + { + if (func_num_args() > 0) { + // Delete it + if (is_null($pagelist)) { + $this->_sub = null; + // Set it + } else { + // We only accept a PageList object + if (strtolower(get_class($pagelist)) != "pagelist") { + trigger_error("The sub() method of a Page object only accepts a PageList object.", E_USER_ERROR); + } + $this->_sub = $pagelist; + $index = new Page($this); + $index->sub(null); + $this->_sub->index($index); + } + } + return $this->_sub; + } + + // compare_to: Compare the order with another page + function compare_to($another) + { + // We only compare to another Selima::Page object + if (strtolower(get_class($another)) != "page") { + trigger_error("The compare_to() method of a Page object only accepts another Page object.", E_USER_ERROR); + } + // Check the page order + if ($this->ord() != $another->ord()) { + return ($this->ord() < $another->ord()? -1: 1); + } + // Check the page path + if ($this->path() != $another->path()) { + return strcmp($this->path(), $another->path()); + } + // Check the page title (should not) + if ($this->title() != $another->title()) { + return strcmp($this->title(), $another->title()); + } + // Equal + return 0; + } + + // fetch_subtree: Fetch the sub page tree from the database + function fetch_subtree() + { + // Not a directory - there is no sub page tree for them + if (substr($this->path(), -1) != "/") { + return; + } + // Compose the SQL statement + $cols = array(); + if (count($GLOBALS["ALL_LINGUAS"]) > 1) { + $lndb = ln($this->lang(), LN_DATABASE); + $cols[] = "title_$lndb AS title"; + } else { + $cols[] = "title AS title"; + } + $cols[] = "ord AS ord"; + $cols[] = "path AS path"; + if (count($GLOBALS["ALL_LINGUAS"]) > 1) { + $cols[] = "'" . sql_esctext($this->lang()) . "' AS lang"; + } else { + $cols[] = "'" . sql_esctext(getlang()) . "' AS lang"; + } + + $select = "SELECT " . implode(", ", $cols) . " FROM pages" + . " WHERE " . sql_is_false("hid") + . " AND path LIKE '" . sql_esclike($this->path()) . "_%'" + . " AND path NOT LIKE '" . sql_esclike($this->path()) . "_%/_%';\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0, $pages = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $pages[] = new Page($row); + } + // Recursively fetch the sub page tree + for ($i = 0; $i < count($pages); $i++) { + $pages[$i]->fetch_subtree(); + } + // Save it + $this->sub(new PageList($pages)); + return; + } + + // fetch_full_page_tree: Fetch the full page tree from the database + static function fetch_full_page_tree($lang = null) + { + // Get the available language list + global $ALL_LINGUAS; + // Cache the result + static $tree = null; + // The language + if (is_null($lang)) { + $lang = getlang(); + } + + // Multi-lingual - obtain each language tree + if (count($ALL_LINGUAS) > 0) { + if (is_null($tree)) { + $tree = array(); + } + // Not cached yet + if (!array_key_exists($lang, $tree)) { + $tree[$lang] = new Page(array( + "title" => "", + "path" => "/", + "ord" => 5000, + "lang" => $lang, + )); + $tree[$lang]->fetch_subtree(); + } + return $tree[$lang]; + + // Uni-lingual + } else { + // Not cached yet + if (is_null($tree)) { + $tree = new Page(array( + "title" => "", + "path" => "/", + "ord" => 5000, + "lang" => $lang, + )); + $tree->fetch_subtree(); + } + return $tree; + } + } + + // neighbor_pages: Obtain the neighbor pages for a specific page path + static function neighbor_pages($path, $lang = null) + { + // Obtain the full apge tree + $tree = self::fetch_full_page_tree($lang); + // Obtain each level of directories + $dirs = array(); + while ($path = preg_replace("/\/[^\/]+\/?$/", "/", $path)) { + array_unshift($dirs, $path); + } + // Nothing - path is "/" (root directory) + if (count($dirs) == 0) { + return $tree->sub(); + } + + } +} + +// PageList: A list of web pages +class PageList +{ + protected $_index = null; + protected $_pages = array(); + + // __construct: Initiate the list of web pages + function __construct($pages) + { + $this->_pages = array(); + $this->add($pages); + } + + // add: Add web pages to the page list + function add($pages) + { + // Add all the pages + for ($i = 0; $i < count($pages); $i++) { + // We only accept Page objects + if (strtolower(get_class($pages[$i])) != "page") { + trigger_error("The add() method of a PageList object only accepts Page objects.", E_USER_ERROR); + } + // Find the page after the added page + for ($j = 0; $j < count($this->_pages); $j++) { + if ($pages[$i]->compare_to($this->_pages[$j]) < 0) { + break; + } + } + // Insert the page + $this->_pages = array_merge( + array_slice($this->_pages, 0, $j), + array($pages[$i]), + array_slice($this->_pages, $j) + ); + } + return; + } + + // index: Set/return the index page + function index($page) + { + if (func_num_args() > 0) { + // Delete it + if (is_null($page)) { + $this->_index = null; + // Set it + } else { + // We only accept a Page object + if (strtolower(get_class($page)) != "page") { + trigger_error("The index() method of a PageList object only accepts a Page object.", E_USER_ERROR); + } + $this->_index = $page; + } + } + return $this->_index; + } + + // pages: Return the pages + function pages() + { + return $this->_pages; + } +} + +?> diff --git a/lib/php/monica/page2rel.inc.php b/lib/php/monica/page2rel.inc.php new file mode 100644 index 0000000..d9c04b7 --- /dev/null +++ b/lib/php/monica/page2rel.inc.php @@ -0,0 +1,331 @@ + +// Copyright: Copyright (C) 2003-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/htmlchar.inc.php"; +require_once "monica/rel2abs.inc.php"; + +// Settings +define("_PAGE2REL_2REL", true); +define("_PAGE2REL_2ABS", false); + +// page2rel: Convert URLs in a page to relative +function page2rel($html, $base) +{ + return _page2rel_cnvturl($html, $base, _PAGE2REL_2REL, null); +} + +// page2abs: Convert URLs in a page to absolute +function page2abs($html, $base, $rdiff = REL2ABS_RDIFF_KEEP) +{ + return _page2rel_cnvturl($html, $base, _PAGE2REL_2ABS, $rdiff); +} + +// _page2rel_cnvturl: Convert URLs in a page to relative/absolute +function _page2rel_cnvturl($source, $base, $is_rel, $rdiff) +{ + $result = ""; + while (preg_match("/^(.*?)(|<[a-z]+\d?(?:\s+[a-z\-]+=(?:\"[^\"]*\"|'[^']*'|[^\"'\s<>]+))*(?:\s+\/)?>|<\?xml-stylesheet(?:\s+[a-z\-]+=(?:\"[^\"]*\"|'[^']*'|[^\"'\s<>]+))*\s*\?>)(.*)$/is", $source, $m)) { + $result .= $m[1]; + $ele = $m[2]; + $source = $m[3]; + // Skip if not a relevant element + if ( !preg_match("/^<((a|applet|area|base|embed|form|frame|img|input|link|object|param|script|style)\s+)(.+?)>$/is", $ele, $m) + && !preg_match("/^<((\?xml-stylesheet)\s+)(.+?)\?>$/s", $ele, $m)) { + $result .= $ele; + continue; + } + $elepref = $m[1]; + $elename = $m[2]; + $elebody = $m[3]; + switch (strtolower($elename)) { + case "a": + case "area": + case "base": + case "link": + $elebody = _page2rel_cnvtatt($elebody, "href", $base, $is_rel, $rdiff); + $result .= "<" . $elepref . $elebody . ">"; + break; + + case "img": + case "input": + case "embed": + case "frame": + $elebody = _page2rel_cnvtatt($elebody, "src", $base, $is_rel, $rdiff); + $result .= "<" . $elepref . $elebody . ">"; + break; + + case "form": + $elebody = _page2rel_cnvtatt($elebody, "action", $base, $is_rel, $rdiff); + $result .= "<" . $elepref . $elebody . ">"; + break; + + case "applet": + $elebody = _page2rel_cnvtatt($elebody, "codebase", $base, $is_rel, $rdiff); + $result .= "<" . $elepref . $elebody . ">"; + break; + + case "object": + $elebody = _page2rel_cnvtatt($elebody, "classid", $base, $is_rel, $rdiff); + $elebody = _page2rel_cnvtatt($elebody, "codebase", $base, $is_rel, $rdiff); + $elebody = _page2rel_cnvtatt($elebody, "data", $base, $is_rel, $rdiff); + $result .= "<" . $elepref . $elebody . ">"; + break; + + case "script": + $elebody = _page2rel_cnvtatt($elebody, "src", $base, $is_rel, $rdiff); + $result .= "<" . $elepref . $elebody . ">"; + $type = strtolower(_page2rel_attval($elebody, "type")); + // Compatibility with the old "language" attribute + if (is_null($type)) { + $scptlang = strtolower(_page2rel_attval($elebody, "language")); + switch ($scptlang) { + case "javascript": + $type = "text/javascript"; + break; + case "vbscript": + case "vbs": + $type = "text/vbscript"; + break; + case "perlscript": + $type = "text/perlscript"; + break; + } + } + switch ($type) { + case "text/javascript": + default: + $m = _page2rel_foreign_js($source); + break; + case "text/vbscript": + case "text/vbs": + $m = _page2rel_foreign_vbs($source); + break; + case "text/perlscript": + $m = _page2rel_foreign_pls($source); + break; + } + $result .= $m[0]; + $source = $m[1]; + break; + + case "style": + $result .= $ele; + $type = strtolower(_page2rel_attval($elebody, "type")); + switch ($type) { + case "text/css": + default: + $m = _page2rel_foreign_css($source, $base, $is_rel, $rdiff); + break; + case "text/javascript": + $m = _page2rel_foreign_jsss($source); + break; + } + $result .= $m[0]; + $source = $m[1]; + break; + + case "param": + $name = strtolower(_page2rel_attval($elebody, "name")); + if (in_array($name, array("src", "movie", "filename"))) { + $elebody = _page2rel_cnvtatt($elebody, "value", $base, $is_rel, $rdiff); + } + $result .= "<" . $elepref . $elebody . ">"; + break; + + case "?xml-stylesheet": + $elebody = _page2rel_cnvtatt($elebody, "href", $base, $is_rel, $rdiff); + $result .= "<" . $elepref . $elebody . "?>"; + break; + } + } + // Append the remains + $result .= $source; + return $result; +} + +// _page2rel_cnvtatt: Convert URLs in HTML abbitutes to relative/absolute +function _page2rel_cnvtatt($source, $att, $base, $is_rel, $rdiff) +{ + $result = ""; + while ($source != "" && preg_match("/^([^\"'\s]*(?:(?:\"[^\"]*\"|'[^']*')[^\"'\s]*)*)(\s*)(.*?)$/s", $source, $m)) { + $piece = $m[1]; + $sep = $m[2]; + $source = $m[3]; + // Skip if not in the attribute="value" format + if ( !(preg_match("/^($att)=(\")([^\"]*)\"$/i", $piece, $m) + || preg_match("/^($att)=(')([^']*)'$/i", $piece, $m) + || preg_match("/^($att)=()([^\"']+)$/i", $piece, $m))) { + $result .= $piece . $sep; + continue; + } + $thisatt = $m[1]; + $quote = $m[2]; + $url = $m[3]; + // $url is a variable to be replaces dynamically, as in error pages + if ($url != "\$url") { + $url = $is_rel? abs2rel($url, $base): + rel2abs($url, $base, REL2ABS_SKIP_FRAGMENT, REL2ABS_NO_HOST, $rdiff); + } + $result .= $thisatt . "=" . $quote . $url . $quote. $sep; + } + return $result; +} + +// _page2rel_attval: Obtain the value of a attribute +function _page2rel_attval($elebody, $att) +{ + $att = strtolower($att); + $val = null; + while ($elebody != "" && preg_match("/^([^\"'\s]*(?:(?:\"[^\"]*\"|'[^']*')[^\"'\s]*)*)(\s*)(.*?)$/s", $elebody, $m)) { + $piece = $m[1]; + $elebody = $m[3]; + // Skip if not in the attribute="value" format + if ( !(preg_match("/^($att)=(\")([^\"]*)\"$/i", $piece, $m) + || preg_match("/^($att)=(')([^']*)'$/i", $piece, $m) + || preg_match("/^($att)=()([^\"']+)$/i", $piece, $m))) { + continue; + } + $thisatt = $m[1]; + $thisval = dh($m[3]); + if (strtolower($thisatt) == $att) { + $val = $thisval; + } + } + return $val; +} + +// _page2rel_foreign_js: Skip the next javascript block +function _page2rel_foreign_js($html) +{ + $block = ""; + $ended = false; + while (preg_match("/^(.*?)(\"(?:[^\\\\\"]|\\\\.)*\"|'(?:[^\\\\']|\\\\.)*'|\/\*.*?\*\/|\/\/[^\n]*|<\/script>)(.*)$/is", $html, $m)) { + // The end of the block + if (strtolower($m[2]) == "") { + $block .= $m[1]; + $html = $m[2] . $m[3]; + $ended = true; + break; + } + // Add this block + $block .= $m[1] . $m[2]; + $html = $m[3]; + } + // Not ended at last + if (!$ended) { + $block .= $html; + $html = ""; + } + return array($block, $html); +} + +// _page2rel_foreign_vbs: Skip the next vbscript block +function _page2rel_foreign_vbs($html) +{ + $block = ""; + $ended = false; + while (preg_match("/^(.*?)(\"(?:[^\"]|\"\")*\"|[:\n]\s*Rem\b[^\n]*|'[^\n]*|<\/script>)(.*)$/is", $html, $m)) { + // The end of the block + if (strtolower($m[2]) == "") { + $block .= $m[1]; + $html = $m[2] . $m[3]; + $ended = true; + break; + } + // Add this block + $block .= $m[1] . $m[2]; + $html = $m[3]; + } + // Not ended at last + if (!$ended) { + $block .= $html; + $html = ""; + } + return array($block, $html); +} + +// _page2rel_foreign_css: Skip the next cascading stylesheet block +function _page2rel_foreign_css($html, $base, $is_rel, $rdiff) +{ + $block = ""; + $ended = false; + while (preg_match("/^(.*?)(\"(?:[^\\\\\"]|\\\\.)*\"|'(?:[^\\\\']|\\\\.)*'|\/\*.*?\*\/|<\/style>)(.*)$/is", $html, $m)) { + // The end of the block + if (strtolower($m[2]) == "") { + $block .= $m[1]; + $html = $m[2] . $m[3]; + $ended = true; + break; + } + // Add this block + $block .= $m[1] . $m[2]; + $html = $m[3]; + } + // Not ended at last + if (!$ended) { + $block .= $html; + $html = ""; + } + // Convert URLs in the CSS block + $block = _page2rel_foreign_cssurls($block, $base, $is_rel, $rdiff); + return array($block, $html); +} + +// _page2rel_foreign_cssurls: Convert URLs in a CSS block +function _page2rel_foreign_cssurls($source, $base, $is_rel, $rdiff) +{ + $result = ""; + while (preg_match("/^(.*?)(\burl\([^\"']*\)|\burl\(\"(?:[^\\\\\"]|\\\\.)*\"\)|\burl\('(?:[^\\\\']|\\\\.)*'\)|\"(?:[^\\\\\"]|\\\\.)*\"|'(?:[^\\\\']|\\\\.)*'|\/\*.*?\*\/)(.*)$/is", $source, $m)) { + $result .= $m[1]; + $piece = $m[2]; + $source = $m[3]; + // An URL + if ( preg_match("/^(url\()(\")((?:[^\\\\\"]|\\\\.)*)\"(\))$/i", $piece, $m) + || preg_match("/^(url\()(')((?:[^\\\\']|\\\\.)*)'(\))$/i", $piece, $m) + || preg_match("/^(url\()()([^\"']*)(\))$/i", $piece, $m)) { + $m[3] = $is_rel? abs2rel($m[3], $base): + rel2abs($m[3], $base, REL2ABS_SKIP_FRAGMENT, REL2ABS_NO_HOST, $rdiff); + $piece = $m[1] . $m[2] . $m[3] . $m[2] . $m[4]; + } + $result .= $piece; + } + // Append the remains + $result .= $source; + return $result; +} + +// _page2rel_foreign_jsss: Skip the next javascript stylesheet block +function _page2rel_foreign_jsss($html) +{ + $block = ""; + $ended = false; + while (preg_match("/^(.*?)(\"(?:[^\\\\\"]|\\\\.)*\"|'(?:[^\\\\']|\\\\.)*'|\/\*.*?\*\/|\/\/[^\n]*|<\/script>)(.*)$/is", $html, $m)) { + // The end of the block + if (strtolower($m[2]) == "") { + $block .= $m[1]; + $html = $m[2] . $m[3]; + $ended = true; + break; + } + // Add this block + $block .= $m[1] . $m[2]; + $html = $m[3]; + } + // Not ended at last + if (!$ended) { + $block .= $html; + $html = ""; + } + return array($block, $html); +} + +?> diff --git a/lib/php/monica/pagefunc.inc.php b/lib/php/monica/pagefunc.inc.php new file mode 100644 index 0000000..dc411e6 --- /dev/null +++ b/lib/php/monica/pagefunc.inc.php @@ -0,0 +1,775 @@ + +// Copyright: Copyright (C) 2003-2009 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/altlang.inc.php"; +require_once "monica/chkfunc.inc.php"; +require_once "monica/commtext.inc.php"; +require_once "monica/echoform.inc.php"; +require_once "monica/errhndl.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/mkalldir.inc.php"; +require_once "monica/page2rel.inc.php"; +require_once "monica/rel2abs.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/rmalldir.inc.php"; +require_once "monica/scptpriv.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/unicode.inc.php"; +require_once "monica/xfileio.inc.php"; + +// page_param: Gather the HTML parameters +function page_param($args = null) +{ + // Default to an empty array + if (is_null($args)) { + $args = array(); + } + // It is already fixed + if (array_key_exists(".fixed", $args)) { + return $args; + } + + // Obtain page parameters + if (array_key_exists("PAGE_PARAM", $GLOBALS)) { + $args = array_merge($args, $GLOBALS["PAGE_PARAM"]); + } + if (array_key_exists("ALT_PAGE_PARAM", $GLOBALS)) { + $args = array_merge($args, $GLOBALS["ALT_PAGE_PARAM"]); + } + + // Set the path + if (!array_key_exists("path", $args)) { + $args["path"] = REQUEST_PATH; + } + // Set the language + if (!array_key_exists("lang", $args)) { + $args["lang"] = getlang(); + } + // Set if static or not + if (!array_key_exists("static", $args)) { + $args["static"] = false; + } + // Set if show a pretty result or not + if (!array_key_exists("clean", $args)) { + $args["clean"] = false; + } + // Set if this page is administrative + if (!array_key_exists("admin", $args)) { + $args["admin"] = is_admin_script($args["path"]); + } + // Set if UTF-8 or not + if (!array_key_exists("utf8", $args)) { + $args["utf8"] = false; + } + // Set if this is a preview page or not + if (!array_key_exists("preview", $args)) { + $args["preview"] = null; + } + // Set if we shoud show the tite in html_header() or not + if (!array_key_exists("no_auto_title", $args)) { + $args["no_auto_title"] = false; + } + // Set if MathML is used or not + if (!array_key_exists("mathml", $args)) { + if ( !is_null($args["preview"]) + && array_key_exists("mathml", $args["preview"])) { + $args["mathml"] = $args["preview"]? true: false; + } else { + $args["mathml"] = false; + } + } + // Set all the available languages + if (!array_key_exists("all_linguas", $args)) { + $args["all_linguas"] = $GLOBALS["ALL_LINGUAS"]; + } + // Set the language of the title + if (!array_key_exists("title_lang", $args)) { + $args["title_lang"] = $args["lang"]; + } + // The upper level index page + if (!array_key_exists("up", $args)) { + $langfile = ln($args["lang"], LN_FILENAME); + // Certain pages that has no upper level index page + $rootdir = preg_replace("/^\/$langfile\/([^\/]*\/?).*?$/", "$1", $args["path"]); + switch ($rootdir) { + case "errors/": + case "longdesc/": + break; + default: + // See the directory where I belongs + $args["up"] = preg_replace("/[^\/]+\/?$/", "", $args["path"]); + // The home page path + $home = count($GLOBALS["ALL_LINGUAS"]) > 1? "/$langfile/": "/"; + // Above the home -- go to the home page + if (substr($args["up"], 0, strlen($home)) != $home) { + $args["up"] = $home; + } + } + } + // Set the URLs of the language variants + if (!array_key_exists("altlang", $args)) { + set_altlang_urls($args); + } + + // Load the local extension + if (function_exists("page_param_site")) { + $args = page_param_site($args); + } + if (function_exists("page_param_script")) { + $args = page_param_script($args); + } + + // Tag that we have fixed this + $args[".fixed"] = true; + return $args; +} + +// page_tree: Get the page tree in a directory +function page_tree($path, $lang, $preview = null) +{ + // Get the available language list + global $ALL_LINGUAS; + // Set the language + $langfile = ln($lang, LN_FILENAME); + $lndb = ln($lang, LN_DATABASE); + $islnpre = preg_match("/^\/$langfile\//", $path)? true: false; + $lnpre = $islnpre? "/$langfile": ""; + // Obtain the directory + $dir = preg_replace("/[^\/]*$/", "", $path); + if ($islnpre) { + $dir = preg_replace("/^\/$langfile/", "", $dir); + } + + // Cache the result + static $cache = array(); + // Initialize the directory array + if (!array_key_exists($dir, $cache)) { + $cache[$dir] = array(); + } + // Return the cache + if (array_key_exists($lang, $cache[$dir])) { + return $cache[$dir][$lang]; + } + + // Initialize the result + $tree = array(); + + // Disable the page tree of error documents + if ($dir == "/errors/") { + $_path = $path; + if ($islnpre) { + $_path = preg_replace("/^\/$langfile/", "", $_path); + } + $title = count($ALL_LINGUAS) > 1? "title_$lndb": "title"; + $select = "SELECT $title AS title from pages" + . " WHERE path='" . sql_esctext($_path) . "';\n"; + $result = sql_query($select); + $row = sql_fetch_assoc($result); + $tree["index"] = array( + "path" => $path, + "_path" => $_path, + "title" => $row["title"]); + return $tree; + } + + // Get the index page + $conds = array(); + $conds[] = "path='" . sql_esctext($dir) . "'"; + if (count($ALL_LINGUAS) > 1) { + $conds[] = "title_$lndb IS NOT NULL"; + } + $conds[] = sql_is_false("hid"); + $select = "SELECT * from pages" + . " WHERE " . implode(" AND ", $conds) . ";\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + // Index page exists + if ($count == 1) { + $row = sql_fetch_assoc($result); + $tree["index"] = array( + "path" => $lnpre . $dir, + "_path" => $dir, + "title" => count($ALL_LINGUAS) > 1? + $row["title_$lndb"]: $row["title"]); + } + + // Get the page tree + $pages = _page_tree($dir, $lang, $lnpre, $preview); + if (!is_null($pages)) { + $tree["pages"] =& $pages; + } + + // Nothing found + if ( !array_key_exists("index", $tree) + && !array_key_exists("pages", $tree)) { + $cache[$dir][$lang] = null; + return null; + } + // Cache it + $cache[$dir][$lang] = $tree; + return $tree; +} + +// _page_tree: Get the page tree +function _page_tree($dir, $lang, $lnpre, $preview = null) +{ + // Get the available language list + global $ALL_LINGUAS; + // Cache the result + static $cache = array(); + // Initialize the directory array + if (!array_key_exists($dir, $cache)) { + $cache[$dir] = array(); + } + // Return the cache + if (array_key_exists($lang, $cache[$dir])) { + return $cache[$dir][$lang]; + } + + // Set the language + $lndb = ln($lang, LN_DATABASE); + + // Get the related pages + $tree = array(); + // Set the columns list + $cols = array(); + if ($lnpre == "") { + $cols[] = "path AS path"; + } else { + $cols[] = sql_strcat("'$lnpre'", "path") . " AS path"; + } + $cols[] = "path AS _path"; + if (count($ALL_LINGUAS) > 1) { + $cols[] = "title_$lndb AS title"; + } else { + $cols[] = "title AS title"; + } + $cols[] = "ord AS ord"; + // Set the criteria + $conds = array(); + $conds[] = "path LIKE '" . sql_esclike($dir) . "_%'"; + $conds[] = "path NOT LIKE '" . sql_esclike($dir) . "_%/_%'"; + if (count($ALL_LINGUAS) > 1) { + $conds[] = "title_$lndb IS NOT NULL"; + } + // Skip the original file + if (!is_null($preview) && array_key_exists("sn", $preview)) { + $conds[] = "sn!=" . $preview["sn"]; + } + // Set the order key + $orderbys = array(); + $orderbys[] = "ord"; + if (count($ALL_LINGUAS) > 1) { + $orderbys[] = "title_$lndb"; + } else { + $orderbys[] = "title"; + } + $orderbys[] = "path"; + $conds[] = sql_is_false("hid"); + $select = "SELECT " . implode(", ", $cols) . " FROM pages" + . " WHERE " . implode(" AND ", $conds) + . " ORDER BY " . implode(", ", $orderbys) . ";\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0; $i < $count; $i++) { + $tree[] = sql_fetch_assoc($result); + } + + // Insert the preview + if (!is_null($preview) && dirname($preview["path"]) . "/" == $dir) { + array_push($tree, array( + "path" => $lnpre . $preview["path"], + "_path" => $preview["path"], + "title" => $preview["title"], + "ord" => $preview["ord"] + )); + // Sort again + usort($tree, "cmp_page_tree"); + } + + // Recur into subdirectories + for ($i = 0; $i < count($tree); $i++) { + if (substr($tree[$i]["path"], -1) != "/") { + continue; + } + $tree[$i]["sub"] = array(); + $tree[$i]["sub"]["index"] = array( + "path" => $tree[$i]["path"], + "_path" => $tree[$i]["_path"], + "title" => $tree[$i]["title"] + ); + $subtree = _page_tree($tree[$i]["_path"], $lang, $lnpre, $preview); + if (!is_null($subtree)) { + $tree[$i]["sub"]["pages"] = $subtree; + } + } + + // Nothing found + if (count($tree) == 0) { + $cache[$dir][$lang] = null; + return null; + } + // Cache it + $cache[$dir][$lang] = $tree; + return $tree; +} + +// cmp_page_tree: Sort the page tree again after inserting a preview +function cmp_page_tree($page1, $page2) +{ + // Compare the order + if ($page1["ord"] != $page2["ord"]) { + return $page1["ord"] - $page2["ord"]; + } + // Compare the title + if ($page1["title"] != $page2["title"]) { + return strcmp($page1["title"], $page2["title"]); + } + // Compare the path + return strcmp($page1["path"], $page2["path"]); +} + +// hash_tree: Make a hash of the page tree +function hash_tree(&$tree) +{ + $hash = array(); + // The index page + if (array_key_exists("index", $tree)) { + $hash[$tree["index"]["path"]] =& $tree; + } + // Track the subdirectories + if (array_key_exists("pages", $tree)) { + for ($i = 0; $i < count($tree["pages"]); $i++) { + // A subdirectory exists + if (array_key_exists("sub", $tree["pages"][$i])) { + $hash = array_merge($hash, + hash_tree($tree["pages"][$i]["sub"])); + } + } + } + return $hash; +} + +// hash_page: Make a hash of the page tree +function hash_page(&$tree) +{ + $hash = array(); + // The index page + if (array_key_exists("index", $tree)) { + $hash[$tree["index"]["path"]] =& $tree["index"]; + } + // Track the subdirectories + if (array_key_exists("pages", $tree)) { + for ($i = 0; $i < count($tree["pages"]); $i++) { + // A plain page + if (!array_key_exists("sub", $tree["pages"][$i])) { + $hash[$tree["pages"][$i]["path"]] =& $tree["pages"][$i]; + // A subdirectory + } else { + $hash = array_merge($hash, + hash_page($tree["pages"][$i]["sub"])); + } + } + } + return $hash; +} + +// page_all_linguas: Get the available languages for this page +function page_all_linguas($page) +{ + // Get the available language list + global $ALL_LINGUAS; + + // It is specified + if (array_key_exists("all_linguas", $page)) { + return $page["all_linguas"]; + } + + // Preview + if (array_key_exists("preview", $page) && $page["preview"]) { + // Uni-lingual + if (!sql_is_ml_table(THIS_TABLE)) { + return array(getlang()); + } + // Find the page + if (!array_key_exists("sn", $page)) { + return array(getlang()); + } + $select = "SELECT * FROM " . THIS_TABLE + . " WHERE sn=" . $page["sn"] . ";\n"; + $result = sql_query($select); + // If this record exist + if (sql_num_rows($result) == 0) { + return array(getlang()); + } + $row = sql_fetch_assoc($result); + // Check each language + $page_all_linguas = array(); + for ($l = 0; $l < count($ALL_LINGUAS); $l++) { + $lang = $ALL_LINGUAS[$l]; + $lndb = ln($lang, LN_DATABASE); + // Add it if the content in this language exists + if (!is_null($row["title_$lndb"]) || $lang == getlang()) { + $page_all_linguas[] = $lang; + } + } + return $page_all_linguas; + } + + // $page is uni-lingual + if (array_key_exists("title", $page)) { + return array(getlang()); + } + + // $page is multi-lingual + // Check each language + $page_all_linguas = array(); + for ($l = 0; $l < count($ALL_LINGUAS); $l++) { + $lang = $ALL_LINGUAS[$l]; + $lndb = ln($lang, LN_DATABASE); + // Add it if the content in this language exists + if (!is_null($page["title_$lndb"])) { + $page_all_linguas[] = $lang; + } + } + return $page_all_linguas; +} + +// outpage: Output a page +function outpage($content, $path, $lang = null) +{ + if (is_null($lang)) { + $lang = getlang(); + } + $langfile = ln($lang, LN_FILENAME); + + // An HTML file or directory index + if (substr($path, -5) == ".html" || substr($path, -1) == "/") { + // The page path in multi-lingual context + $lnpath = (count($GLOBALS["ALL_LINGUAS"]) > 1)? + "/$langfile$path": $path; + // Convert the URLs to relative + if (substr($path, 0, 8) == "/errors/") { + $content = page2abs($content, $lnpath, REL2ABS_RDIFF_STRIP); + // $url variable is handled inside of page2abs(); + } else { + $content = page2rel($content, $lnpath); + } + // Encode the e-mail at-signs (@) + $content = str_replace("@", "@", $content); + // Decode the e-mail at-signs (@) of spamtrap + $content = str_replace("spamtrap@", "spamtrap@", $content); + // Encode the page to the target character set + $content = page_encode($content, ln($lang, LN_CHARSET)); + // Obtain the real file name + $file = DOC_ROOT . $lnpath; + if (substr($file, -1) == "/") { + $file .= "index.html"; + } + // Create the necessary directories + mkalldir(dirname($file)); + // Write the file + xfupdate_template("$file.xhtml", $content); + // Make the symbolic link for the text/html + $targfile = basename("$file.xhtml"); + $linkfile = "$file.html"; + if (!is_link($linkfile) || readlink($linkfile) != $targfile) { + if (file_exists($linkfile)) { + if (is_dir($linkfile)) { + rmalldir($linkfile); + } else { + unlink($linkfile); + } + } + symlink($targfile, $linkfile); + } + + // An RSS file or OpenSearch description document + } elseif (substr($path, -8) == "/rss.xml" || substr($path, -7) == "osd.xml") { + // The page path in multi-lingual context + $lnpath = (count($GLOBALS["ALL_LINGUAS"]) > 1)? + "/$langfile$path": $path; + // Encode the e-mail at-signs (@) + $content = str_replace("@", "@", $content); + // Decode the e-mail at-signs (@) of spamtrap + $content = str_replace("spamtrap@", "spamtrap@", $content); + // Encode the page to the target character set + // XML is not HTML, so HTML character entity reference should not be used. + $content = page_encode($content, ln($lang, LN_CHARSET), UNICODE_NO_HCEREF); + // Obtain the real file name + $file = DOC_ROOT . $lnpath; + // Create the necessary directories + mkalldir(dirname($file)); + // Write the file + xfupdate_template($file, $content); + + // A text file + } elseif (substr($path, -4) == ".txt") { + // The page path in multi-lingual context + $lnpath = (count($GLOBALS["ALL_LINGUAS"]) > 1)? + "/$langfile$path": $path; + // We do not encode to a target character set. This is not always + // possible for plain text files and hence not quite useful. + // Hence the output are always in UTF-8. + // Encode the e-mail at-signs (@) + $content = str_replace("@", "-at-", $content); + // Obtain the real file name + $file = DOC_ROOT . $lnpath; + // Create the necessary directories + mkalldir(dirname($file)); + // Write the file + xfupdate_template($file, $content); + + // A PDF file + } elseif (substr($path, -4) == ".pdf") { + // The page path in multi-lingual context + $lnpath = (count($GLOBALS["ALL_LINGUAS"]) > 1)? + "/$langfile$path": $path; + // Obtain the real file name + $file = DOC_ROOT . $lnpath; + // Create the necessary directories + mkalldir(dirname($file)); + // Write the file + xfupdate($file, $content); + + // A JavaScript file + } elseif (substr($path, -3) == ".js") { + // The page path in multi-lingual context + $lnpath = (count($GLOBALS["ALL_LINGUAS"]) > 1)? + substr($path, 0, -3) . ".$langfile.js": $path; + // Encode the e-mail at-signs (@) + $content = str_replace("@", "@", $content); + // Encode the page to the target character set + $content = page_encode($content, ln($lang, LN_CHARSET)); + // Obtain the real file name + $file = DOC_ROOT . $lnpath; + // Create the necessary directories + mkalldir(dirname($file)); + // Write the file + xfupdate_template($file, $content); + } + + return; +} + +// readpage: Read from an include page +function readpage($path, $lang = null) +{ + if (is_null($lang)) { + $lang = getlang(); + } + $charset = ln($lang, LN_CHARSET); + $file = DOC_ROOT . $path; + if (count($GLOBALS["ALL_LINGUAS"]) > 1) { + $file = sprintf($file, ln($lang, LN_FILENAME)); + } + $content = xfread($file); + + // Try to decode with the specified encoding + $GLOBALS["php_errormsg"] = null; + set_error_handler("null_error_handler"); + $content = iconv($charset, "UTF-8", $content); + restore_error_handler(); + // Wrong encoding + if (!is_null($GLOBALS["php_errormsg"])) { + trigger_error("Failed decoding $file as $charset", E_USER_ERROR); + // In case when error handler is disabled + return null; + } + + // An HTML file or XHTML file + if (substr($file, -5) == ".html" || substr($file, -6) == ".xhtml") { + // Decode the HTML character references + $content = a_hcref2char($content); + } + + return $content; +} + +// array_keys_ml: Return a list of multi-lingual keys in an associative array +function array_keys_ml(&$arr) +{ + // Get the columns that have language variants + $suffix = "_" . getlang(LN_DATABASE); + $len = strlen($suffix); + $keys = array_keys($arr); + $mlkeys = array(); + for ($i = 0; $i < count($keys); $i++) { + // It has a language suffix + if (substr($keys[$i], -$len) == $suffix) { + $mlkeys[] = substr($keys[$i], 0, -$len); + } + } + return $mlkeys; +} + +// array_keys_nl: Return a list of keys without their multi-lingual +// deviants in an associative array +function array_keys_nl(&$arr) +{ + $keys = array_keys($arr); + $mlkeys = array_keys_ml($arr); + + // Remove those language variants + $nlkeys = array(); + for ($i = 0; $i < count($keys); $i++) { + $pos = strrpos($keys[$i], "_"); + // No suffix + if ($pos === false) { + $nlkeys[] = $keys[$i]; + // Check the prefix + } else { + $prefix = substr($keys[$i], 0, $pos); + // The prefix is one of the language columns + if (in_array($prefix, $mlkeys)) { + // Not counted yet + if (!in_array($prefix, $nlkeys)) { + $nlkeys[] = $prefix; + } + // An ordinary prefix + } else { + $nlkeys[] = $keys[$i]; + } + } + } + + return $nlkeys; +} + +// page_title: Obtain a page title +function page_title($sn) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $sn + if (is_null($sn)) { + return t_notset(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + + // Check the serial number first + if (!check_sn($sn)) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Query + // Default language + if (getlang() == DEFAULT_LANG) { + $title = "title_" . getlang(LN_DATABASE) . " AS title"; + // Fall back to the default language + } else { + $title = "COALESCE(title_" . getlang(LN_DATABASE) . "," + . " title_" . ln(DEFAULT_LANG, LN_DATABASE) . ") AS title"; + } + $select = "SELECT $title FROM pages" + . " WHERE sn=$sn;\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$sn] = $row["title"]; + + return $cache[$sn]; +} + +// page_path: Obtain a page path +function page_path($sn) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $sn + if (is_null($sn)) { + return t_notset(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + + // Check the serial number first + if (!check_sn($sn)) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Query + $select = "SELECT path FROM pages WHERE sn=$sn;\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$sn] = $row["path"]; + + return $cache[$sn]; +} + +// rebuildtype_options: Obtain a rebuild type options list +function rebuildtype_options($value) +{ + // The type labels + $labels = array( + "pages" => C_("Web pages"), + "news" => C_("News"), + "links" => C_("Related links"), + "home" => C_("Home page"), + "all" => C_("Whole web site"), + ); + if (array_key_exists("REBUILD_LABELS", $GLOBALS)) { + global $REBUILD_LABELS; + foreach (array_keys($REBUILD_LABELS) as $type) { + $labels[$type] = _($REBUILD_LABELS[$type]); + } + } + // Get the available rebuild types + $allfuncs = get_defined_functions(); + $opts = array(); + foreach ($allfuncs["user"] as $func) { + if (substr($func, 0, 8) == "rebuild_") { + $type = substr($func, 8); + // Skip rebuild_a_page() + // To be removed -- only for DK-Taipei now. + if ($type == "a_page") { + continue; + } + $label = array_key_exists($type, $labels)? + $labels[$type]: $type; + $opts[] = array( + "value" => $type, + "content" => $label, + ); + } + } + // Obtain the HTML + $html = opt_list_array($opts); + + return preselect_options($html, $value); +} + +?> diff --git a/lib/php/monica/parseurl.inc.php b/lib/php/monica/parseurl.inc.php new file mode 100644 index 0000000..d007adc --- /dev/null +++ b/lib/php/monica/parseurl.inc.php @@ -0,0 +1,124 @@ + +// Copyright: Copyright (C) 2004-2010 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/errhndl.inc.php"; + +// parse_url_rfc1808: Our own parse_url(), in order to confirm to RFC 1808 +function parse_url_rfc1808($url) +{ + // Try PHP parse_url() first + $GLOBALS["php_errormsg"] = null; + set_error_handler("null_error_handler"); + $url_php = parse_url($url); + restore_error_handler(); + // Error parsing the URL + if (!is_null($GLOBALS["php_errormsg"])) { + return null; + } + + // Compose the network location/login (net_loc) + if (!is_array($url_php)) { + $url_php = array(); + } + if (array_key_exists("host", $url_php)) { + $net_loc = $url_php["host"]; + // Add the user and password if they exists + if (array_key_exists("user", $url_php)) { + if (array_key_exists("pass", $url_php)) { + $net_loc = $url_php["user"] . ":" . $url_php["pass"] . "@" . $net_loc; + } else { + $net_loc = $url_php["user"] . "@" . $net_loc; + } + } + // Add the port + if (array_key_exists("port", $url_php)) { + $need_port = true; + // Skip the default port + if (array_key_exists("scheme", $url_php)) { + switch (strtolower($url_php["scheme"])) { + case "http": + if ($url_php["port"] == 80) { + $need_port = false; + } + break; + case "https": + if ($url_php["port"] == 443) { + $need_port = false; + } + break; + case "ftp": + if ($url_php["port"] == 21) { + $need_port = false; + } + break; + case "ftps": + if ($url_php["port"] == 990) { + $need_port = false; + } + break; + case "gopher": + if ($url_php["port"] == 70) { + $need_port = false; + } + break; + case "prospero": + if ($url_php["port"] == 191) { + $need_port = false; + } + break; + case "wais": + if ($url_php["port"] == 210) { + $need_port = false; + } + break; + } + } + // We need to specify the port + if ($need_port) { + $net_loc .= ":" . $url_php["port"]; + } + } + } + // Seperate the params from the path + if (array_key_exists("path", $url_php)) { + $pos = strpos($url_php["path"], ";"); + if ($pos !== false) { + $url_php["params"] = substr($url_php["path"], $pos+1); + $url_php["path"] = substr($url_php["path"], 0, $pos); + } + } + + // Compose the URL parts by RFC 1808 + $url = array(); + if (array_key_exists("scheme", $url_php)) { + $url["scheme"] = $url_php["scheme"]; + } + if (isset($net_loc)) { + $url["net_loc"] = $net_loc; + } + if (array_key_exists("path", $url_php)) { + $url["path"] = $url_php["path"]; + } + if (array_key_exists("params", $url_php)) { + $url["params"] = $url_php["params"]; + } + if (array_key_exists("query", $url_php)) { + $url["query"] = $url_php["query"]; + } + if (array_key_exists("fragment", $url_php)) { + $url["fragment"] = $url_php["fragment"]; + } + + return $url; +} + +?> diff --git a/lib/php/monica/passwd.inc.php b/lib/php/monica/passwd.inc.php new file mode 100644 index 0000000..ed4bd2f --- /dev/null +++ b/lib/php/monica/passwd.inc.php @@ -0,0 +1,104 @@ + +// Copyright: Copyright (C) 2003-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/encrypt.inc.php"; +require_once "monica/newsn.inc.php"; + +// sync_saved_passwd: Set the passwords with the password registry +function sync_saved_passwd(&$FORM, $dummy) +{ + // Do not process again + if (array_key_exists("_sync_saved_passwd", $FORM)) { + return; + } + // The passwd field + if (array_key_exists("passwd", $FORM)) { + // Empty password is provided. Restore to the old password. + if ($FORM["passwd"] == "") { + unset($FORM["passid"]); + // A new password is provided + } elseif ($FORM["passwd"] != $dummy) { + $FORM["passid"] = _passwd_suspend($FORM["passwd"]); + // A previous valid password exists + } elseif (_passwd_prev_valid("passid", $FORM)) { + $FORM["passwd"] = _passwd_ret($FORM["passid"]); + // Invalid previous password. Restore to the old password. + } else { + unset($FORM["passid"]); + $FORM["passwd"] = ""; + } + } + // The passwd2 field + if (array_key_exists("passwd2", $FORM)) { + // Empty password is provided. Restore to the old password. + if ($FORM["passwd2"] == "") { + unset($FORM["passid2"]); + // A new password is provided + } elseif ($FORM["passwd2"] != $dummy) { + $FORM["passid2"] = _passwd_suspend($FORM["passwd2"]); + // A previous valid password exists + } elseif (_passwd_prev_valid("passid2", $FORM)) { + $FORM["passwd2"] = _passwd_ret($FORM["passid2"]); + // Invalid previous password. Restore to the old password. + } else { + unset($FORM["passid2"]); + $FORM["passwd2"] = ""; + } + } + $FORM["_sync_saved_passwd"] = true; + return; +} + +// _passwd_suspend: Suspend a password +function _passwd_suspend($password) +{ + // Initialize the password registry + if (!array_key_exists("savepass", $_SESSION)) { + $_SESSION["savepass"] = array(); + } + + // Generate a new random password ID + $passid = new_sn_assoc($_SESSION["savepass"]); + $_SESSION["savepass"][$passid] = encrypt($password); + return $passid; +} + +// _passwd_ret: Retrieve a password +function _passwd_ret($passid) +{ + return decrypt($_SESSION["savepass"][$passid]); +} + +// _passwd_prev_valid: If there is a previously-saved password +function _passwd_prev_valid($col, $FORM) +{ + // Password ID does not exist + if (!array_key_exists($col, $FORM)) { + return false; + } + // Password registry not initialized yet + if (!array_key_exists("savepass", $_SESSION)) { + return false; + } + // Password does not exists in the registry + if (!array_key_exists($FORM[$col], $_SESSION["savepass"])) { + return false; + } + // We can't decrypt it + $passwd = decrypt($_SESSION["savepass"][$FORM[$col]]); + if (is_null($passwd)) { + return false; + } + return true; +} + +?> diff --git a/lib/php/monica/pic.inc.php b/lib/php/monica/pic.inc.php new file mode 100644 index 0000000..0b5669e --- /dev/null +++ b/lib/php/monica/pic.inc.php @@ -0,0 +1,549 @@ + +// Copyright: Copyright (C) 2002-2009 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/chkfunc.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/htmlchar.inc.php"; +require_once "monica/newsn.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/scptpriv.inc.php"; +require_once "monica/xfileio.inc.php"; + +// Settings +if (!defined("PIC_MAX_WIDTH")) { + define("PIC_MAX_WIDTH", 800); +} +if (!defined("PIC_MAX_HEIGHT")) { + define("PIC_MAX_HEIGHT", 1024); +} +if (!defined("PIC_MAX_RATIO")) { + define("PIC_MAX_RATIO", 9.99); +} +$PIC_VALID_TYPES = array("image/png", "image/jpeg", "image/gif"); +$PIC_VALID_SUFS = array("png", "jpg", "gif"); +$PIC_TYPESUF_MAP = array( + "image/png" => "png", + "image/jpeg" => "jpg", + "image/gif" => "gif"); +$PIC_VALID_POS = array("L", "R"); +$PIC_POS_LABEL = array( + "L" => N_("Left-aligned"), + "R" => N_("Right-aligned")); +$PIC_POS_CSS = array( + "L" => "float: left;", + "R" => "float: right;"); +if (!defined("PIC_POS_DEFAULT")) { + define("PIC_POS_DEFAULT", "L"); +} +if (!defined("SHOWPIC_SCRIPT")) { + define("SHOWPIC_SCRIPT", "/admin/showpic.php"); +} +if (!defined("SHOWPIC_PUBLIC_SCRIPT")) { + define("SHOWPIC_PUBLIC_SCRIPT", "/showpic.php"); +} + +// suspend_pic: Suspend a picture to $_SESSION +function suspend_pic(&$pic) +{ + $PICS =& pic_deposit(); + // Generate a new random picture ID + $picid = new_sn_assoc($PICS); + $pic["sn"] = $picid; + // Save the current picture + $PICS[$picid] =& $pic; + // Return the picture ID + return $picid; +} + +// check_picfile: Check the uploaded picture file +function check_picfile($column = "picfile") +{ + $picfile =& $_FILES[$column]; + // Check the file upload status + switch ($picfile["error"]) { + case UPLOAD_ERR_INI_SIZE: + return array("msg"=>NC_("This picture file is too large (Max %s)."), + "margs"=>array(get_cfg_var("upload_max_filesize"))); + case UPLOAD_ERR_FORM_SIZE: + return array("msg"=>NC_("This picture file is too large (Max %s)."), + "margs"=>array(UPLOAD_ERR_FORM_SIZE)); + case UPLOAD_ERR_PARTIAL: + return array("msg"=>NC_("Upload not completed. Disk may be full or connection may be closed in the half. You may try to upload again, or contact the system administrator for this problem.")); + case UPLOAD_ERR_NO_FILE: + return array("msg"=>NC_("Please upload the picture.")); + default: + return array("msg"=>NC_("Upload failed with an unknown error (%d)."), + "margs"=>array($picfile["error"])); + case UPLOAD_ERR_OK: + } + + // Check the file type + $picfile["type"] = check_mime_type($picfile["tmp_name"]); + if (!in_array($picfile["type"], $GLOBALS["PIC_VALID_TYPES"])) { + return array("msg"=>NC_("Please upload only PNG, JPEG or GIF files.")); + } + // OK + return null; +} + +// picurl: Get the picture display URL +function picurl(&$pic, $ratio = null) +{ + // Default ratio to the picture ratio + if (is_null($ratio)) { + // Set the default picture ratio to 1 + if (!array_key_exists("ratio", $pic)) { + $pic["ration"] = 1; + } + $ratio = $pic["ratio"]; + } + $ratio = sprintf("%0.13F", $ratio); + $ratio = preg_replace("/(\.[0-9]*?)0+$/", "$1", $ratio); + $ratio = preg_replace("/\.$/", "", $ratio); + $showpic = is_admin_script()? SHOWPIC_SCRIPT: SHOWPIC_PUBLIC_SCRIPT; + // Compose the fields list + $cols = array(); + // Add the columns + $cols[] = "sn=" . urlencode($pic["sn"]); + $cols[] = "ratio=" . urlencode($ratio); + return $showpic . "?" . implode("&", $cols); +} + +// pictype_from_content: Get the picture type from its octet content +// Refer to the mime.magic file +function pictype_from_content(&$content) +{ + // PNG + if (substr($content, 0, 4) == "\x89PNG") { + return "image/png"; + } + // JPEG + if (substr($content, 0, 2) == "\xFF\xD8") { + return "image/jpeg"; + } + // GIF + if (substr($content, 0, 4) == "GIF8") { + return "image/gif"; + } + // No other formats are supported now + return null; +} + +// picinfo: Return the picture infomation +function picinfo(&$pic, $ratio = 1) +{ + // Original size not recorded yet + if ( !array_key_exists("width", $pic) + || !array_key_exists("height", $pic)) { + $img = imagecreatefromstring($pic["content"]); + $pic["width"] = imagesx($img); + $pic["height"] = imagesy($img); + } + $x = newpicx($pic, $ratio); + $y = newpicy($pic, $ratio); + return sprintf(C_("Width: %d, height: %d, ratio: %0.2f"), $x, $y, $ratio); +} + +// picstyle: Return the picture style +function picstyle(&$pic, $ratio = 1) +{ + // Original size not recorded yet + if ( !array_key_exists("width", $pic) + || !array_key_exists("height", $pic)) { + $img = imagecreatefromstring($pic["content"]); + $pic["width"] = imagesx($img); + $pic["height"] = imagesy($img); + } + $x = newpicx($pic, $ratio); + $y = newpicy($pic, $ratio); + return sprintf("height: %dpx; width: %dpx;", $y, $x); +} + +// check_pic_ratio: Check the sanity of the picture ratio +function check_pic_ratio(&$pic, &$ratio) +{ + // Check if the resize ratio is valid + if (!is_numeric($ratio)) { + return array("msg"=>NC_("Please specify a numeric ratio.")); + } + settype($ratio, "float"); + if ($ratio <= 0) { + return array("msg"=>NC_("Please specify a positive ratio.")); + } + if ($ratio > PIC_MAX_RATIO) { + return array("msg"=>NC_("Please specify a ratio less than or equal to %0.2f."), + "margs"=>array(PIC_MAX_RATIO)); + } + // The resulted picture is over the limit + if ( newpicx($pic, $ratio) > PIC_MAX_WIDTH + || newpicy($pic, $ratio) > PIC_MAX_HEIGHT) { + return array("msg"=>NC_("This image is too large to display.")); + } + // OK + return null; +} + +// best_pic_ratio: Get the best ratio of a picture +function best_pic_ratio(&$pic) +{ + // Cache the result + static $cache; + // Return the cache + if (isset($cache)) { + return $cache; + } + + // Original size not recorded yet + if ( !array_key_exists("width", $pic) + || !array_key_exists("height", $pic)) { + $img = imagecreatefromstring($pic["content"]); + $pic["width"] = imagesx($img); + $pic["height"] = imagesy($img); + } + // Good + if ( PIC_MAX_RATIO >= 1 + && $pic["width"] <= PIC_MAX_WIDTH + && $pic["height"] <= PIC_MAX_HEIGHT) { + $cache = 1; + return $cache; + } + // Too large + // Find the largest proper ratio + $rx = floor(PIC_MAX_WIDTH*100 / $pic["width"])/100; + $ry = floor(PIC_MAX_HEIGHT*100 / $pic["height"])/100; + // Use the smallest among them + $cache = min($rx, $ry, PIC_MAX_RATIO); + return $cache; +} + +// newpicx: Calculate the new picture x +function newpicx(&$pic, $ratio = 1) +{ + // Original size not recorded yet + if (!array_key_exists("width", $pic)) { + $img = imagecreatefromstring($pic["content"]); + $pic["width"] = imagesx($img); + } + // No calculation needed + if ($ratio == 1) { + return $pic["width"]; + } + $x = round($pic["width"] * $ratio); + // Smallest 1 + if ($x == 0) { + $x = 1; + } + return $x; +} + +// newpicy: Calculate the new picture y +function newpicy(&$pic, $ratio = 1) +{ + // Original size not recorded yet + if (!array_key_exists("height", $pic)) { + $img = imagecreatefromstring($pic["content"]); + $pic["height"] = imagesy($img); + } + // No calculation needed + if ($ratio == 1) { + return $pic["height"]; + } + $y = round($pic["height"] * $ratio); + // Smallest 1 + if ($y == 0) { + $y = 1; + } + return $y; +} + +// pic_exists: Check if a picture exists +function pic_exists($sn) +{ + // Check the validity of the serial number first + if (!check_sn($sn)) { + return false; + } + if (!array_key_exists($sn, pic_deposit())) { + return false; + } + return true; +} + +// echopic: Output a picture +function echopic(&$pic, $alt, $ratio = null) +{ + if (is_null($ratio)) { + $ratio = best_pic_ratio($pic); + } else { + $error = check_pic_ratio($pic, $ratio); + if (!is_null($error)) { + $ratio = best_pic_ratio($pic); + } + } + $style = picstyle($pic, $ratio); + $picinfo = picinfo($pic, $ratio); + ?><?php echo h($alt); ?> +

    +<?php echo h($alt); ?> diff --git a/lib/php/monica/pinyin.inc.php b/lib/php/monica/pinyin.inc.php new file mode 100644 index 0000000..b7bed9b --- /dev/null +++ b/lib/php/monica/pinyin.inc.php @@ -0,0 +1,225 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/chkwrite.inc.php"; +require_once "monica/mkalldir.inc.php"; +require_once "monica/xfileio.inc.php"; + +// Settings +if (!defined("DBMDIR")) { + define("DBMDIR", dirname(dirname(dirname(__FILE__))) . "/" . php_uname("m")); +} +define("_PINYIN_PINYIN2BIG5", dirname(__FILE__) . "/pinyin2big5"); +define("_PINYIN_B52PY_DB", DBMDIR . "/b52py.db"); + +$_PINYIN_DB = null; +define("_PINYIN_DBTYPE_DBA", 1); +define("_PINYIN_DBTYPE_ARRAY", 2); +$_PINYIN_SUP = array( + " " => " ", + "#" => "#", + "﹟" => "#", + "兙" => "shi2 ke4", + "兛" => "qian1 ke4", + "兞" => "mao2 ke4", + "兝\" => "fen1 ke4", + "兡" => "bai3 ke4", + "兣" => "li2 ke4", + "嗧" => "jia1 lun2", + "瓩" => "qian1 wa3", + "糎" => "li2 mi3", +); + +// b52py: Convert Traditional Chinese to Pinyin +function b52py($big5) +{ + global $_PINYIN_DB; + // Initialize the database + _init_b52py(); + + // Split into pieces + $pieces = array(); + $remains = $big5; + while (preg_match("/^([\\x01-\\x7F]+|(?:[\\x80-\\xFE].)+)(.*)$/s", $remains, $m)) { + $pieces[] = $m[1]; + $remains = $m[2]; + } + + // Process each piece + switch (_PINYIN_DBTYPE) { + // Using a DB file + case _PINYIN_DBTYPE_DBA: + for ($i = 0; $i < count($pieces); $i++) { + // Big5 piece + if (preg_match("/^[\\x80-\\xFF]/", $pieces[$i])) { + for ($j = 0, $words = array(); $j < strlen($pieces[$i]); $j += 2) { + $char = substr($pieces[$i], $j, 2); + if (dba_exists($char, $_PINYIN_DB)) { + $words[] = dba_fetch($char, $_PINYIN_DB); + } else { + $words[] = $char; + } + } + $pieces[$i] = implode(" ", $words); + } + } + break; + + // Using an array + case _PINYIN_DBTYPE_ARRAY: + for ($i = 0; $i < count($pieces); $i++) { + // Big5 piece + if (preg_match("/^[\\x80-\\xFF]/", $pieces[$i])) { + for ($j = 0, $words = array(); $j < strlen($pieces[$i]); $j += 2) { + $char = substr($pieces[$i], $j, 2); + if (array_key_exists($char, $_PINYIN_DB)) { + $words[] = $_PINYIN_DB[$char]; + } else { + $words[] = $char; + } + } + $pieces[$i] = implode(" ", $words); + } + } + break; + } + + $pinyin = $pieces[0]; + for ($i = 1; $i < count($pieces); $i++) { + // Insert a space + if ( !preg_match("/\s$/", $pieces[$i-1]) + && !preg_match("/^\s/", $pieces[$i])) { + $pinyin .= " "; + } + $pinyin .= $pieces[$i]; + } + + return $pinyin; +} + +// _init_b52py: Initialize the Big5 to Pinyin database +function _init_b52py() +{ + global $_PINYIN_DB, $_PINYIN_SUP; + // Already initialized + if (defined("_PINYIN_DBTYPE")) { + return; + } + + // Decide the action to do + if (file_exists(_PINYIN_B52PY_DB)) { + // Not a file + if (!is_file(_PINYIN_B52PY_DB)) { + define("_PINYIN_DBTYPE", _PINYIN_DBTYPE_ARRAY); + // Not readable + } elseif (!is_readable(_PINYIN_B52PY_DB)) { + define("_PINYIN_DBTYPE", _PINYIN_DBTYPE_ARRAY); + // Not writable -- read only + } elseif (!is_writable(_PINYIN_B52PY_DB)) { + $_PINYIN_DB = dba_open(_PINYIN_B52PY_DB, "r", "gdbm"); + // No data + if (dba_firstkey($_PINYIN_DB) === false) { + dba_close($_PINYIN_DB); + define("_PINYIN_DBTYPE", _PINYIN_DBTYPE_ARRAY); + // OK + } else { + define("_PINYIN_DBTYPE", _PINYIN_DBTYPE_DBA); + return; + } + // Writable + } else { + $_PINYIN_DB = dba_open(_PINYIN_B52PY_DB, "w", "gdbm"); + // No data - initialize the data + if (dba_firstkey($_PINYIN_DB) === false) { + define("_PINYIN_DBTYPE", _PINYIN_DBTYPE_DBA); + // OK + } else { + define("_PINYIN_DBTYPE", _PINYIN_DBTYPE_DBA); + return; + } + } + // File does not exist + } else { + // Not creatable + $error = check_writable(_PINYIN_B52PY_DB); + if (!is_null($error)) { + define("_PINYIN_DBTYPE", _PINYIN_DBTYPE_ARRAY); + // Creatable + } else { + mkalldir(dirname(_PINYIN_B52PY_DB)); + $_PINYIN_DB = dba_open(_PINYIN_B52PY_DB, "c", "gdbm"); + define("_PINYIN_DBTYPE", _PINYIN_DBTYPE_DBA); + } + } + + // Initialize the database + switch (_PINYIN_DBTYPE) { + // Initialize it as a DB file + case _PINYIN_DBTYPE_DBA: + $lines = explode("\n", xfread(_PINYIN_PINYIN2BIG5)); + foreach ($lines as $line) { + // Skip comments + if (substr($line, 0, 1) == "#") { + continue; + } + // Skip empty lines + if (!preg_match("/\S/", $line)) { + continue; + } + $chars = explode(" ", $line); + // First item is pinyin + $pinyin = array_shift($chars); + foreach ($chars as $char) { + if (!dba_exists($char, $_PINYIN_DB)) { + dba_insert($char, $pinyin, $_PINYIN_DB); + } + } + } + // Special meta characters + foreach (array_keys($_PINYIN_SUP) as $char) { + if (!dba_exists($char, $_PINYIN_DB)) { + dba_insert($char, $_PINYIN_SUP[$char], $_PINYIN_DB); + } + } + break; + + // Initialize it as an array + case _PINYIN_DBTYPE_ARRAY: + $_PINYIN_DB = array(); + $lines = explode("\n", xfread(_PINYIN_PINYIN2BIG5)); + foreach ($lines as $line) { + // Skip comments + if (substr($line, 0, 1) == "#") { + continue; + } + // Skip empty lines + if (!preg_match("/\S/", $line)) { + continue; + } + $chars = explode(" ", $line); + // First item is pinyin + $pinyin = array_shift($chars); + foreach ($chars as $char) { + $_PINYIN_DB[$char] = $pinyin; + } + } + // Special meta characters + foreach (array_keys($_PINYIN_SUP) as $char) { + $_PINYIN_DB[$char] = $_PINYIN_SUP[$char]; + } + break; + } + + return; +} + +?> diff --git a/lib/php/monica/pinyin2big5 b/lib/php/monica/pinyin2big5 new file mode 100644 index 0000000..0b407cf --- /dev/null +++ b/lib/php/monica/pinyin2big5 @@ -0,0 +1,1555 @@ +# Pinyin to Big5 mapping table prepared by Pristine Communications 19990202 + +a1 +a2 +a4 +ai1 s J u M +ai2 J c +ai3 G ħ G H d +ai4 R ê i @ W إ T i T | M I +an1 w b g O u Φ r L P +an2 u +an3 { ٣ ~ +an4 t f C } Ӱ i +ang1 +ang2 W +ang3 B +ang4 s +ao1 W b +ao2 C g R } v m l W j j +ao3 ͽ D +ao4 D M ش j +b1 t +ba1 K J z a T +ba2 [ Y n ɥ n Z +ba3 v j +ba4 } Q f +ba5 a } ] I +bai1 T +bai2 +bai3 \ y x +bai4 a x +ban1 Z h { I W ݽ x +ban3 O z I +ban4 b r ä b ̭ +bang1 } W +bang3 ] j H +bang4 S F r +bao1 ] M c R U U +bao2 r n +bao3 O _ ̯ ؿ +bao4 z \ j S ^ X ۭ s o I +bei1 I M d O S t | յ ɸ s +bei3 _ +bei4 Q I u V H _ ڪ O X t X Ϻ +ben1 b N I +ben3 c f +ben4 ^ ʬ +beng1 Y ^ [ M y ] +beng2 +beng3 f f } Ծ O +beng4 { n n g +bi1 G Y M D +bi2 +bi3 P ] Y Ӽ p _ D +bi4 z u A c p @ ] t { q X D N S h n z K A ҥ u l } G ղ ] ڷ ت c t ʯ } g L r G Z X W t v z ~ Ͷ K s ~ q J +bian1 s @ H x _ t +bian3 S G +bian4 K M G X | K q Z +biao1 C t d I @ n l ܭ I d H [ l +biao3 D t F +biao4 +bie1 x ž +bie2 O D v o +bie3 ç ס +bie4 +bin1 l b y } x ˬ @ g R ɢ ~ y +bin4 l K +bing1 L B | +bing3 [ ` } @ ׮ ~ ε +bing4 f } x R +bo1 g ׷ [ q Y Q i +bo2 B f y k i K Y ` J J c W a f ` c Ѵ ު ߴ w c R { +bo3 _ ð װ +bo4 ð B +bu1 ժ l +bu2 +bu3 H R { +bu4 B G ï Z O +c1 +ca1 g +ca3 } +ca4 +cai1 q +cai2 ~ ] +cai3 m B s ٽ +cai4 +can1 \ | +can2 F [ +can3 G ٩ v +can4 G T D +cang1 a a V +cang2 t +cao1 W +cao2 ] +cao3 { Z J +cao4 W ͫ +ce4 U Z l I | +cen1 շ +cen2 K պ H X +ceng1 +ceng2 h e U +ceng4 O +ch1 +cha1 t e C X j ` +cha2 d g A h Q ͤ +cha3 +cha4 b t Ю ˲ L +chai1 t [ +chai2 [ +chai4 +chan1 e ˦ ~ V +chan2 I a ` ` G s G d ^ U R x @ +chan3 A C ˱ L | o s s A +chan4 b _ +chang1 s @ K u I @ ڨ +chang2 ` n v z Z u | ^ +chang3 t +chang4 Z J C +chao1 r W p ̢ +chao2 _ J H q +chao3 n +chao4 f +che1 s +che3 +che4 M w \ K ж +chen1 ` Q ݧ Ԯ +chen2 I W f p Ӳ } Y B q j ɯ +chen3 w ^ +chen4 X Ũ h @ +cheng1 e W ڥ a Կ g Y +cheng2 { e g J ٳ s h к L գ m u ] o I W ή +cheng3 x ѭ G +cheng4 W g +chi1 Y E è ^ ] ګ Z ֲ w j u +chi2 U W ӳ ר z Y Ӣ A b N w +chi3 ` ݶ ӿ j ^ N ɭ { +chi4 w K ܿ ̸ U S L k ` K r +chong1 R R r E +chong2 R e ܣ ӵ ֡ +chong3 d +chong4 o +chou1 o ݱ l +chou2 T w S Y C å v A W ۬ E P +chou3 | p +chou4 h { +chu1 X +chu2 x p S o Q ] q ` +chu3 B x ¦ S u G +chu4 B IJ b J z H M ڢ b G +chua1 +chuai2 D +chuai3 +chuai4 D +chuan1 t J ޸ +chuan2 +chuan3 Ӷ +chuan4 k @ U +chuang1 H w y +chuang2 l +chuang3 m +chuang4 [ ޯ +chui1 j +chui2 l ݴ i | P [ x ߡ +chui4 j +chun1 K Y s +chun2 B J E ] L z B +chun3 e b +chuo1 W +chuo4 ؽ [ Y ] N \ w u M +ci1 θ t l +ci2 O Z Y [ M +ci3 ˽ u ү l ֦ +ci4 Z ˵ ۴ l +cong1 ^ o q w { v k p z e +cong2 q O F z U O +cong4 +cou4 s +cu1 +cu2 e u +cu4 P L L T ` k B +cuan1 O } +cuan2 +cuan4 « y y +cui1 R Z Q g i I +cui2 +cui3 A +cui4 A | u f X c Q Z +cun1 r +cun2 s +cun3 k +cun4 o T G +cuo1 b R O e +cuo2 ڵ D h +cuo3 L +cuo4 V k +d1 x +da1 f U +da2 F Ŷ D H ӯ T | b b { ϯ X +da3 +da4 j +dai1 b +dai3 e +dai4 N a U p L U j e Դ g L o @ c s +dan1 ° X C H E +dan3 x n ܳ P ɿ l d d +dan4 H J u F ~ v D l H y \ I C c x E P L +dang1 L h @ N +dang3 m +dang4 X ۥ ~ f E ] a m +dao1 M o { ͱ [ +dao3 q ë o r +dao4 D _ s A C q +de2 o w +de5 o +dei3 o +deng1 n O h S f ] +deng3 u +deng4 H j E L I +di1 C w z w ׾ } a i +di2 } f C @ S { ܫ ` t _ +di3 C k s c E +di4 a l X ڻ A j ` a M Щ I Z k i +dia1 +dian1 A q i Y \ h e +dian3 I K ک G +dian4 q l } Q f e J N +diao1 J N I M p n ڤ K ע +diao3 x +diao4 Q s K ɹ +die1 R +die2 ^ | Ҽ S آ k { ] y E T x G D +ding1 B v m o n E x M +ding3 C +ding4 w q v H a ~ E _ r +diu1 +dong1 F V N ] Ф l ϵ ۪ +dong3 \ Q +dong4 } ѯ i +dou1 +dou3 ~ B U w +dou4 r k u ^ e M Ū +du1 G +du2 Ū W r | A p } u p Z \ r +du3 @ w { E E +du4 { h +duan1 B e k +duan3 u +duan4 q _ v | b +dui1 +dui4 I P U X d v +dun1 [ +dun3 Ļ +dun4 y w P L P y Q W ʭ ɶ T { +duo1 h G ө +duo2 M s @ t i է j M +duo3 ئ W ֣ c +duo4 k Z F W O m O ײ +e1 Σ +e2 B _ Z Z @ o m X ʧ x H r x i ڸ +e3 M +e4 c j X k K s E c j m ˮ K ~ F إ i خ Y G ݦ h _ +ei1 +en1 +en4 ݮ +eng1 +er1 +er2 ϥ S k w l F Ӵ Ԣ { +er3 | ҭ b z Ω t +er4 G L ˹ F ֬ +f1 w +fa1 o +fa2 F @ | ӫ +fa3 k v +fa4 k W +fan1 f ½ º n | ` Z ] +fan2 Z c | s ÿ d ͨ \ O E S c D y s G _ h +fan3 +fan4 d S c x o J U +fang1 { D ˨ B b C K +fang2 { +fang3 X +fang4 +fei1 D v m n P W +fei2 x +fei3 B ^ I K +fei4 o O m p Q a u W M +fen1 ^ h j ܨ w d V +fen2 X I W F n V ʷ Z b t c +fen3 +fen4 T \ ʮ x +feng1 p W l Z ߱ ީ ʲ J g G v +feng2 { _ ʰ I ذ ߧ +feng3 w +feng4 ^ _ c +fiao4 +fo2 +fong4 +fou2 M R +fou3 _ o +fu1 l S i y [ @ ˪ i ` f T u +fu2 A B T R { M e g Ӻ վ Ӭ { Z X p ߦ l m ߶ ׷ t Q N R f Y G y { ] z +fu3 G j y @ X F ̹ d f r k D +fu4 t I I _ J u t r L { ^ n F ` b ק T Υ ۽ P +g1 | +ga1 +ga2 +ga4 +gai1 u ˴ y j U [ +gai3 +gai4 \ t @ v b G +gan1 z x a X i h z Ц Q +gan3 P z A u x +gan4 F B h m G +gang1 ^ z \ t i ٻ Զ k +gang3 ^ +gang4 b +gao1 | I t o S A R \ +gao3 Z d ` X R +gao4 i p { +ge1 q F v Ϸ ] O +ge2 j f J @ u Ө C \ } +ge3 S } +ge4 U Ш +ge5 +gei3 +gen1 +gen2 +gen3 +gen4 ӣ +geng1 e ü N ۩ X +geng3 C X G d +geng4 } +gong1 u \ c ` } G t p c Z +gong3 d E @ Ҭ q { ѱ ۻ +gong4 @ ^ P ݢ +gou1 y _ e +gou3 A c e e Q ӭ ׭ +gou4 c b p z l o U +gu1 h t d B f ۣ K G T l ^ @ ` V W ~ Z T I U +gu2 +gu3 j \ Y S L [ ¢ S a ת W F ` F L B X k +gu4 G T U D i L _ D +gua1 A h ~ g ߢ ߲ A a +gua3 l +gua4 o h G E o +guai1 +guai3 ^ b +guai4 J [ s M +guan1 x [ a ` ` +guan3 ] _ F E +guan4 D e d | a [ c u V q +guang1 Ү Y Ӥ [ | +guang3 s x +guang4 } R t +gui1 k W t c ^ ص D и t +gui3 y o s V ɣ i w ֿ ۹ F +gui4 Q d ` P @ k +gun3 u O X l @ ե R +gun4 k +guo1 O ԭ b +guo2 ~ U Q A +guo3 G q K _ t ] e +guo4 L +h1 ~ +ha1 +ha2 +ha3 +hai1 y +hai2 e +hai3 W +hai4 ` b +han1 o M F w ܬ P { +han2 H t [ R m r U +han3 u D U D +han4 ~ k X v F c թ C ھ r Z _ A T g _ F p F u +hang1 q +hang2 C \ ͳ ͬ ӹ +hang3 +hang4 Y +hao1 U Q +hao2 @ Į z b H M +hao3 n q +hao4 E q U n P V R E D Ѯ +he1 F Ϋ +he2 X M e T U r \ N P } { ] Q [ Z ] ] +he4 P M b ~ q { t w +he5 M +hei1 K H +hei3 +hen2 +hen3 +hen4 +heng1 P +heng2 Ҳ d m K h ˼ +heng4 Ԧ Z +hong1 F M б ʡ n H F ` +hong2 x E i l R b d A T c G ^ g f R r l C X D R t o } +hong3 +hong4 i E +hou1 +hou2 U J j S o +hou3 q +hou4 p Z m M ^ п Z Ϭ +hu1 I G p | v O p R } z A +hu2 J k G M [ z } p ݬ | t V m ` R +hu3 [ q \ \ +hu4 @ } | C ɼ ̲ [ ^ j Q q l h c z +hua1 M r +hua2 E M ~ @ b +hua4 e T _ p E +huai2 h a i ˿ w v T f +huai4 a e E +huan1 w N a [ +huan2 U ` l X J { { w ѳ l | S ܥ +huan3 w p ں d +huan4 w A M R ޽ I | +huang1 W w Ъ +huang2 a q ® X D G N C h t J I A v ر ] o R } L +huang3 E ̤ a g S +huang4 A +hui1 u Z Z o k Ϥ s k A +hui2 ^ j w ֤ +hui3 k t +hui4 | f ø z J © k c } P F J r n n ^ Y U [ _ P I V [ Q h w j _ +hun1 B N _ ݼ +hun2 _ V L I +hun3 V +hun4 V T I @ +huo1 +huo2 d ߪ +huo3 d +huo4 ì M b N f i | t ֺ F ] n C ~ E _ R O +huo5 M +i1 +ie1 +j1 +ji1 n Z E V ] F L j E Y X T B R Q ~ A ~ D ۵ F \ j p l ~ @ +ji2 Y e y N I A V E Y C D a Ϳ D k ˸ K c O O y i ϡ S Ͽ B d H n o X @ n ѹ ո \ +ji3 X v u L q P +ji4 p O J ~ u H ô [ M V ^ E k Ŵ g ɫ [ ا ߽ x r \ ^ ɾ S E L x @ D A ` p +jia1 a [ { E P m X @ J j S r X ަ +jia2 U H | I h ճ q U @ ֳ +jia3 [ a K z H +jia4 [ r [ ɲ +jian1 y } l p q ̱ y f J ^ ޥ i e T l F Y ݸ ۢ ܩ T ~ b Z h +jian3 ² z õ P Z c V ج _ u Q ¥ I ޹ +jian4 Ų b C ĥ ų ^ x q e t Ͻ Ҷ h } ] r ^ D ^ V +jiang1 N æ L ŷ l E s X o ~ +jiang3 C +jiang4 K N z L +jiao1 ź J b G t B M k N ` w j S d h +jiao2 Z +jiao3 } ú B ˳ Q ѿ @ ޢ +jiao4 s ı u C i ҫ ] P N +jie1 n n N x ٬ a ~ +jie2 ` T I N e P ~ m K U ^ j Q D f C P _ ѹ g r +jie3 j n +jie4 | z n k z ʥ ɲ ѣ X P +jin1 T z y o ~ Ҵ V W j d +jin3 A @ D X Ի j ί +jin4 i T l u ʵ R H ݨ ͯ h ] c n S E ɻ a +jing1 g H e R ը ɰ a +jing3 ĵ V [ m d L X +jing4 q R b v w | t l H j E ߼ y +jiong1 +jiong3 ~ ~ ޣ R u j b ʨ q +jiu1 G G y V B Я j ۮ +jiu3 E [ s h v b +jiu4 N s ^ S l \ ѵ +ju1 ~ s q j I u _ ^ ٹ L ڡ c | +ju2 ѷ | ] B v پ K D Ͼ ն V ާ { \ J ^ +ju3 | x C q L ټ @ +ju4 y @ E Z d £ U ~ _ \ u N ̥ ] ~ H ^ K l +juan1 S Y O կ O +juan3 ԯ d +juan4 h m Ѧ X ] ڿ R β J r +jue1 +jue2 M ı Z Z U w n ũ i } T D R n ͸ T i | Z n Գ +jue3 +jue4 +jun1 x g v d Y t +jun3 ~ +jun4 T p m m @ C s ڭ M Ѹ Y ] լ ʣ j +k1 } +ka1 @ +ka3 d y a +ka4 +kai1 } { | ˴ +kai3 n _ Z Z m t +kai4 n Z t y q n +kan1 Z ` +kan3 r e Թ B t +kan4 E Ы e +kang1 d B R n t y +kang2 +kang3 B +kang4 ʩ f z ˧ p +kao1 u +kao3 N Ϣ +kao4 a R +ke1 _ V O W H a \ ^ H Τ ި +ke2 y +ke3 i V e u _ +ke4 J g E y N ݤ +ken3 i V +ken4 v ֶ +keng1 | ^ \ [ +keng3 +kong1 S O T Q +kong3 +kong4 +kou1 ׼ c +kou3 f +kou4 F n M F ̪ n +ku1 \ ] u \ +ku3 W +ku4 w A } +kua1 j f ӡ ˺ Z +kua3 ˺ +kua4 m +kuai1 J { +kuai3 +kuai4 | _ D z D a V +kuan1 e b +kuan3 +kuang1 J F o +kuang2 g +kuang3 +kuang4 p q m K R i v +kui1 s w ѧ J x k J +kui2 } f t U Z P +kui3 i y Ρ +kui4 \ X J ± | D ~ B ` ַ l +kun1 X [ b C O խ t c c +kun3 i Ѩ @ +kun4 x t e +kuo3 +kuo4 A X J r b z +l1 { +la1 X i +la2 f +la3 +la4 þ N f K ݷ +la5 +lai2 t ] ٷ J Ԩ +lai4 u ţ _ +lan2 x d i İ P +lan3 i V l I _ X _ +lan4 l S +lang1 j +lang2 T Y w } [ հ G c q +lang3 ά Ѣ N H +lang4 J +lao1 +lao2 c G R H b c +lao3 W L { y +lao4 O T o U +le4 U M { R ѻ } ɪ ɤ B ͧ +le5 F +lei1 +lei2 p J ý ] D O v A d +lei3 S w U L O W s O T | W | { K E +lei4 \ t +leng2 W ٱ U +leng3 N +leng4 h D +li1 +li2 X z p v W u q ռ I N x } z M u N +li3 z § @ U [ Z C Ŀ Y U T ~ +li4 O Q R c F y r Y E w t O X W g ~ Ű | U B R e t g Ҫ s k E v ` z q H l в ` ש d S t V H r F U x Y ݹ K C y d +lia3 +lian2 s p G î I ſ r U T i I C Z +lian3 y L ܶ +lian4 m k F K V ߵ ة +liang2 } q ³ D d x G Y +liang3 R y +liang4 q G g D y W N Ѣ +liao1 +liao2 d I · V y c { l g v S s Q +liao3 F A d B m +liao4 A R S b +lie1 +lie4 C P H y c a { ~ d u J ۶ q q +lin2 L { F O M C Y b M Z ` s z Y i x S o v z P B +lin3 o ۫ ܱ j +lin4 [ n ĩ M e +ling1 +ling2 s F a d D o M Ҿ ~ W F a I d S A B R e v A ̰ S +ling3 v +ling4 O t ϶ +liu1 +liu2 B y d [ h s F ~ a e u ^ F U W +liu3 h q g +liu4 H y a +long2 s Ţ V Ť n g K ] t S P F D u P R M +long3 l b +long4 @ ձ +lou1 O +lou2 \ ܼ o ~ n K y +lou3 M O \ +lou4 | S b +lu1 P +lu2 c Ī f Ĥ l ` y t G j C F D V G O B +lu3 | r f s i [ +lu4 S S L S O F O u x i F r ^ ڣ t w S Z p ֵ j F \ c +lu:2 j [ q B +lu:3 f i Q T \ M ~ e +lu:4 v { o J w +lu:an2 p +lu:an3 +lu:e4 n +luan2 r q } e C k +luan3 Z +luan4 J +lun1 +lun2 _ [ Ԭ C e K ۡ F +lun3 A +lun4 j +luo1 o +luo2 ù r Y [ o z m +luo3 r s +luo4 d O T _ B ָ p Ϊ +m1 v +ma1 +ma2 s +ma3 X b V M +ma4 | X Y +ma5 +mai2 I ŵ +mai3 R G h +mai4 +man2 Z C f O ѫ +man3 ^ +man4 C p g [ r B ܻ +mang2 ~ ] ʾ Q ʱ A v l ` ] ڳ \ x B +mang3 x \ i +mao1 +mao2 T i ͻ ب ] \ U +mao3 f } g +mao4 U _ T Z ع ͻ A H Z +mei2 S T C ` D У S ث ޻ Q q z u _ K +mei3 C Z T +mei4 f A K N y z L ڶ q +men1 e +men2 ۯ +men3 +men4 e T V +meng2 X é a c j _ { j p f E w ` +meng3 r g S j +meng4 s q x +mi1 } N +mi2 g j S G n ^ +mi3 ֩ w ߾ k Q +mi4 K e V c Q W m Y ΢ X m L C G +mian2 v ض Q z v +mian3 K j q Y S B \ _ M M y +mian4 +miao1 p +miao2 ] y ^ +miao3 z H W +miao4 q [ +mie1 A +mie4 G N B ݩ G z w +min2 Т x B ^ J ~ +min3 { { C ] I n j ݼ ^ +ming2 W P \ U H y @ y Q +ming3 ֮ q o +ming4 R \ +miu1 +miu4 +mo1 N +mo2 i U ] Ĩ r +mo3 +mo4 q z S \ j [ Z i p n w ֯ ~ m E E h ۾ K f r M +mo5 +mou2 [ ۿ Ϩ N +mou3 Y N ^ +mu2 +mu3 a d i ϼ Ψ +mu4 } p N ` V A Ӿ ~ q +n1 z +na2 Ѳ +na3 +na4 o [ u R Ͱ ʴ +nai2 +nai3 D i ` C N +nai4 @ ` q U n +nan1 _ +nan2 n k I x +nan3 i v k +nan4 +nang1 +nang2 n +nang3 +nang4 +nao1 o +nao2 L q ̬ ` +nao3 o +nao4 x +ne1 O +ne5 O +nei3 k N +nei4 +nen4 +neng2 +neng4 +ng1 +ni2 d g O e N D ] F O b k +ni3 A p F ̻ o P +ni4 f d E | д +nian2 ~ H p D +nian3 [ V G U +nian4 +niang2 Q ] +niang4 C +niao3 r s +niao4 +nie1 E n +nie2 | +nie4 ^ \ ¿ h I A n ܡ j v A s Q X X Q +nin2 z +nin3 +ning2 { f ڬ ] k +ning3 +ning4 +niu1 +niu2 +niu3 s c U p +niu4 +nong2 A @ w ª T +nong4 +nou2 c +nou4 U +nu2 q V +nu3 V +nu4 +nu:3 k F +nu:4 ~ +nu:e4 h +nuan3 x N +nuo2 R { +nuo3 +nuo4 z ݫ ѽ +o1 +o2 @ +ou1 ^ e _ P +ou2 ʡ +ou3 ~ B x +ou4 x +p1 u +pa1 w r +pa2 ] I +pa4 ׽ +pai1 +pai2 P r l +pai3 x +pai4 +pan1 k +pan2 L Y D n \ +pan3 +pan4 P q ` ׵ K N d X ϸ +pang1 S +pang2 e H K ʾ ܧ x Y +pang3 +pang4 D +pao1 K +pao2 T H S ϲ ҽ +pao3 ] +pao4 w p C +pei1 F A [ B _ N +pei2 p I y +pei3 ڦ +pei4 t K \ n S ů r ɵ +pen1 Q +pen2 K +pen3 { +peng1 y i { q +peng2 B ^ N P O ˢ @ L ܽ X h ~ L +peng3 ֥ +peng4 I Ը k ٮ +pi1 A R Q A ` _ e ̮ m | +pi2 h \ J t s ] @ } g e i ˭ ׯ h A f w f p f +pi3 _ l С y +pi4 Ĵ P B @ } I W \ v Y +pian1 g ؾ +pian2 K c k +pian4 F M +piao1 } _ ܸ +piao2 ] A +piao3 } g e g p O n +piao4 } Y N [ +pie1 h J ~ +pie3 J +pin1 c +pin2 h x W I y +pin3 ~ +pin4 u +ping1 \ { +ping2 ~ ī W i ΰ n u n m з M [ ۲ ӱ ߩ ϰ +ping3 +po1 i Y @ +po2 C I x +po3 r +po4 } z y j s +pou1 } +pou2 h Ѽ +pou3 ٫ +pu1 Q P ڱ _ ̷ +pu2 Z \ m @ r z Y N +pu3 H E P V +pu4 Q r n E +q1 +qi1 C d ~ Y m P N P Q N H ԧ N h Q r +qi2 _ X M R T a [ X Q _ N K u N B m Y ] g ӽ դ D C Q k c Y +qi3 _ Z ^ ] v s } U ͼ ʦ +qi4 T _ W r E l t d d y ӽ a y +qia1 t +qia3 d a +qia4 α K +qian1 d ] E ñ o O a H ^ S r I L d ˡ R j m C N t I V +qian2 e r X @ x z a H ̵ y ߰ ɰ F K +qian3 L V +qian4 p g } S d f H +qiang1 j m f ٪ B { N +qiang2 j R b | p +qiang3 j m u h f +qiang4 v +qiao1 V T K k t d t p J j u W +qiao2 @ ¼ L k N V B H X K +qiao3 s N N +qiao4 ¼ ¬ N k T s +qie1 P +qie2 X G +qie3 B +qie4 c g ۷ h ^ +qin1 I ] k \ \ j +qin2 ^ V ^ t A h ͭ ܤ +qin3 ` ʫ H +qin4 G k +qing1 M C B f J ԫ g +qing2 +qing3 +qing4 y j v k S M j բ +qiong1 | +qiong2 a ã | r ۼ F T c r v ߳ +qiu1 C L Z _ t D +qiu2 D y } } A s X [ M G S ڹ g N а ɦ D u v Z G \ y +qiu3 +qu1 } X I £ ׶ ] X ` B ̶ v \ q +qu2 W T £ C W y k E Q a ۧ +qu3 T Ϧ +qu4 h @ m +quan1 Ѫ ٯ μ W +quan2 v u l ҡ y h A h t ޾ p +quan3 e n F Q +quan4 U Ң y +que1 +que2 a +que4 o T N e | O [ i +qun1 _ n +qun2 s g +r1 +ran2 M U w ף פ ׹ +ran3 V T w \ I { +rang2 c š [ { m +rang3 W [ c +rang4 J +rao2 c +rao3 Z +rao4 ¶ +re3 S o Y +re4 +ren2 H Q I +ren3 Z P e +ren4 { b b M ѡ Q ` t +reng1 +reng2 r } +reng3 +ri4 s +rong2 e a T _ A x C g v S D ` y c n +rong3 _ D +rou2 X | ɨ q +rou3 M n +rou4 +ru2 p į } } ] Ѳ w δ Q +ru3 d k +ru4 J d v P @ +ruan2 أ +ruan3 n į R A } +rui2 B o +rui3 u ս +rui4 U ͺ U +run1 i +run4 | +ruo4 Y z k Y x d +s1 +sa1 e +sa3 x s +sa4 +sai1 | B l +sai4 +san1 T M +san3 o X +san4 { +sang1 +sang3 ݺ b { +sang4 +sao1 b k i R +sao3 A Ե +sao4 M +se4 ¨ O l p Z u +sen1 x i x +seng1 +sh1 +sha1 F T گ j ң F q +sha2 ԣ +sha3 +sha4 K H Q | g l +shai1 z +shai3 +shai4 +shan1 s m R û Q \ k s ݵ U h } [ +shan3 { E ٥ +shan4 µ T S ĺ b M Q l R +shang1 N Y +shang3 +shang4 W | s g +shang5 n +shao1 N y ߥ z v K ݾ e f K +shao2 @ c Ϲ +shao3 +shao4 l s o ׸ ڼ L +she1 a B +she2 D e ` +she3 +she4 ] g A j e i Q B +shei2 +shen1 ` D W E M g P ~ ] k [ X P p +shen2 +shen3 H f T n Z { { ˩ T +shen4 V G ߸ ̽ z +sheng1 n @ c N ʢ d T d +sheng2 ÷ I z h +sheng3 f +sheng4 t O o +shi1 I v N r ߭ й O i w H k ˥ +shi2 Q B k g A M c +shi3 l v p +shi4 O @ h A } u K U I a غ b ] K i f l m r r +shi5 +shou1 ӧ +shou2 +shou3 u S F +shou4 ~ G +shu1 V g _ Y +shu2 Q ū E Z a +shu3 p L a I r +shu4 N z p f @ o o } +shua1 | m +shua3 A +shuai1 L I +shuai3 +shuai4 v O +shuan1 C +shuan4 R +shuang1 \ +shuang3 n +shuang4 f +shui2 O +shui3 +shui4 | t X +shun3 m p +shun4 H v +shuo1 +shuo4 { v } q T c x | a +si1 q p r R B T z Ӹ @ G W S @ | +si3 +si4 | } x v S r x q o ] N Y A I +song1 Q P S C p e ] C +song3 q n [ +song4 e | ^ w +sou1 j B ` ` Y I ޮ \ ^ +sou3 ] +sou4 +su1 Ĭ d p q Z +su2 U +su4 D t J g H h A P F P \ S { Y e B ɧ Z ϩ W M y +suan1 m ҩ +suan3 +suan4 [ H +sui1 k A F h B ֪ g C c o D +sui2 H s +sui3 g a r +sui4 E H J G ` g a Խ H ^ I D +sun1 ] ^ ެ ݻ _ N +sun3 l g i h +sun4 +suo1 Y P u T f b a V +suo3 c @ +suo4 +t1 y +ta1 L o e | ͢ +ta3 G X +ta4 f á ݭ ľ k Y l O Z k o N +tai1 L a +tai2 x O a ` i ϱ | +tai4 A O g ` ^ y V +tan1 g y u ~ ̾ R d +tan2 u » \ z ^ G g +tan3 Z R e J T +tan4 Լ E +tang1 A +tang2 } e F ] _ x +tang3 l I \ f +tang4 S +tao1 Ź q l ݰ m O [ { E +tao2 k ^ v h B p ` f A +tao3 Q +tao4 M +te4 S | i +teng2 k f +ti1 I +ti2 D { w N V x J g +ti3 ^ W +ti4 P c O K V R | +tian1 K Z _ +tian2 ۰ +tian3 Q f S b ٧ +tian4 m l +tiao1 D ֽ ι o +tiao2 | m g q U L k f +tiao3 D K w +tiao4 f m +tie1 K ̣ +tie3 K R +tie4 K צ +ting1 ť U չ K ͪ +ting2 x F ^ @ l M ߬ W ^ +ting3 m [ p M o X n +ting4 ť +tong1 q f ֢ ϵ k +tong2 P c ˾ ֻ w Ӧ u h i Y n @ J +tong3 Ѷ T J o +tong4 h E I +tou1 +tou2 Y ޤ +tou3 D Y o +tou4 z +tou5 Y +tu1 r ` ա +tu2 ~ { O Y \ E ~ r ߫ ̨ Y L P b w S +tu3 g R A z G +tu4 R +tuan1 ~ +tuan2 { w q a +tuan4 ν +tui1 a +tui2 Z R +tui3 L +tui4 h a a +tun1 ] t K +tun2 y b v ͵ ʤ +tun3 ʤ +tun4 a +tuo1 U ح Ѿ ~ K +tuo2 m b k Y @ ] W s [ e ײ O +tuo3 I W +tuo4 l +u1 +u:1 +w1 +wa1 z K E q H C p +wa2 +wa3 _ +wa4 +wai1 n +wai3 +wai4 ~ +wan1 W s d ɽ U +wan2 x Y K ˣ J +wan3 J { Y p F d ` { V ١ w N d +wan4 U { ɺ d E c g +wang1 L ʿ q +wang2 ` +wang3 P S I ٤ v R +wang4 k Z +wei1 Q ߻ ~ j k D O m | Z P a +wei2 L M H c R W I W Q t \ Ϫ a o b N +wei3 e n T m U ޳ q C ߯ ~ L ߤ ͷ | z y p B ַ C +wei4 Q G L L } B ؼ b s t ^ Y c q u +wen1 E g +wen2 D A L T Ͳ ڧ J +wen3 í k F +wen4 D Z K ݯ o ʹ +weng1 o S +weng3 c [ f +weng4 | +wo1 s A +wo3 զ +wo4 U W S Q R _ +wu1 Q d z r d c j w z h +wu2 L d ^ z ` \ k f m O l b i d +wu3 Z R V M a K u ɮ q ݳ Ԥ T m V +wu4 c ~ a E c B ظ W t | Q ܪ V O | ; ڲ g J +x1 +xi1 l H } x R H ^ R f h Q O L E X D m ] c Q Q { D W R ^ \ G r ѩ ִ r P k w e ξ ο ] j i o ܾ j \ о I G M +xi2 u @ ŧ V D g K b i ٶ _ O { R y +xi3 ~ p â u V C q C ҧ +xi4 Y t ô i ͥ b ͮ Q g \ W r m ̧ [ ] M y b +xia1 M +xia2 v l L U X E I \ j ߣ ݡ z һ x E +xia4 U L ~ H v y g +xian1 P A k C _ y D [ I W j w G l ܹ H s G ҹ +xian2 w _ C ~ w } p ߺ V ۸ G y q ԡ +xian3 I A ~ n d h K ` d P @ v ݣ z B B +xian4 { u m r ` A s ի ڽ W | b e V b v +xiang1 m c ^ [ R ߹ H +xiang2 +xiang3 Q T W Y +xiang4 V H Q A m M _ +xiao1 P t d p ­ v ] Ż N J i ` c F n ӷ ڰ } A m Q ڴ ߿ ] W d G u Ԫ r +xiao2 m B +xiao3 p N Q +xiao4 S v S Z +xie1 t +xie2 c e ^ E H F q \ D Z j ݲ ޺ _ +xie3 g +xie4 h m n P k b r ط c c ^ _ Z L g ʶ J W a [ [ +xin1 s ~ Y N Q ` c ` t ʻ F +xin2 V +xin3 ɳ +xin4 H ] \ ʻ v X +xing1 P V { i X z ޼ ` S | +xing2 D x O ˶ x ϭ n { P +xing3 +xing4 m Ӯ c +xiong1 S I F +xiong2 \ +xiong4 +xiu1 κ Z p V Ӫ t +xiu3 J +xiu4 q ¸ S J q ҵ ɧ h i +xu1 Ž N V E X S w Y h d F S c +xu2 } +xu3 \ H J Y ҷ r +xu4 W B b f z ͹ m [ w ̡ T C | E +xuan1 a ޱ y S U ~ J P i m u +xuan2 a x { f K o z +xuan3 j +xuan4 x t ֭ b ױ | ` T a ״ X E +xue1 u f { +xue2 ` b O P +xue3 +xue4 d e ~ \ ׳ +xun1 t H } O e e { +xun2 M ` ұ } K { J н X b O g C @ +xun4 T V S A +ya1 r ~ n X ٲ +ya2 P H b ɷ +ya3 o V ܦ +ya4 Y ] G Y P g o K +yai2 V ԩ +yan1 j T M | a P Y I k m Ҹ ` \ +yan2 C Y u Q ò F Ժ w w r ^ n g Z J z +yan3 t l n ^ k L λ j V Q f J } k ٰ j | L b X V +yan4 P b T v V x | ` @ u ] o Ŭ i j E v I K [ m m Q ܵ E [ A v z x +yang1 o m t f K b G +yang2 v L G z R ۱ ޴ ҳ ֱ ػ +yang3 i o W b ϴ ̿ } +yang4 i ~ y +yao1 n y \ [ m ߷ +yao2 n c a \ f d ޭ ] \ Ұ W b l ` l o r +yao3 r H ʼ ̳ Х P J U E +yao4 n ģ ` _ c F @ x M +ye1 C O +ye2 C x ^ +ye3 ] M Ա +ye4 ~ ] | M g o g E e O e +yi1 @ a v T U I W ϫ H ۺ v b w ^ +yi2 y i M ~ x ^ [ U e l f p Y D Q A Χ ֫ B ˷ Э M ۦ ҿ ׻ C ۳ ݿ h e o l G L +yi3 H w A o w Ѱ Y c A ܯ ^ \ x H ٨ +yi4 N q ij q Ķ G l h w ö ~ c z H t r i k Ѻ m @ | } H ѥ h C Է a @ A J f J T ܲ \ E Y m p ^ ɩ h ~ { U ̴ a ] ٦ Q ԰ L n m [ Z L m ^ γ | g +yin1 ] f ء e X M ϧ h L +yin2 u G ] i Ҥ C U l H { h y P d m +yin3 } C v U i X h A V L +yin4 L N J x W P y u +ying1 ^ N a t x X Ģ L w } V t c R Q +ying2 Ĺ s l ^ m ] D D F +ying3 v o r _ ջ V +ying4 w M j T +yo1 +yong1 e l s V ` H v o u R +yong2 q Q M x +yong3 a i i v s M \ U F Ѥ +yong4 +you1 u ~ y N M ̫ ׫ +you2 C o l S \ ץ O { ɬ O [ a _ +you3 K N O } k v D ߮ +you4 S k c V ^ r n \ έ ϻ +yu1 J @ P ͦ ֧ +yu2 r T l _ M E O \ p f j ڮ L g Y ܢ ٿ i ߨ Ҩ S B B \ } m a Ь ԥ ؤ ز O m +yu3 P y B t h F ܺ @ ޷ O Y ּ { [ J +yu4 | J w U A D J m P s { ~ ¡ R L \ n { ܮ f K y ٵ H g @ H O ٭ R z q M } S s R g Ѭ P k w +yuan1 W p { u B i +yuan2 t D K J G X ʹ E F ˫ ʺ ` ӻ [ _ C u ޫ D d +yuan3 S +yuan4 | @ b D ޶ @ d p C +yue1 A _ +yue4 V \ f D ģ _ ` G e ͣ T c b ^ | v +yun1 w r I j d +yun2 a e X N ʳ ɴ ] +yun3 k f e v p e u ˰ +yun4 B ĭ Y @ w P y +z1 +za1 ` s N +za2 { +zai1 a v +zai3 J _ +zai4 b A +zan1 ¯ +zan2 +zan3 s e +zan4 g f o +zang1 ż B } N +zang3 +zang4 Ŧ N +zao1 D V ܷ +zao2 w +zao3 Ħ D j +zao4 y m ķ _ ļ q T +ze2 h d A V Q е +ze3 +ze4 z +zei2 +zen3 +zen4 +zeng1 W ¹ y e +zeng4 p +zh1 +zha1 d f H t ̼ +zha2 h Z ׬ C +zha3 w z u x +zha4 ^ ] B E c K Q \ K z +zhai1 K N +zhai2 v C +zhai3 h +zhai4 d q ֹ +zhan1 g ¤ L ĸ S e v L +zhan3 i ݪ ~ \ R Z ^ +zhan4 e Ÿ E Y X J N +zhang1 i s k h ܴ ` R +zhang3 x S A +zhang4 V M b ` } H +zhao1 L l J x O +zhao2 +zhao3 h ۨ +zhao4 l n F @ E g U U } +zhe1 B ծ w +zhe2 P K G B ծ s Q Ч M s +zhe3 +zhe4 o C v p [ +zhe5 B ծ w +zhen1 u w s r e z d E ް L e z W ޲ س +zhen3 E E l H ׿ h [ ̺ G a +zhen4 } _ E } _ ֨ W մ J +zheng1 ] C x u W p m M ϳ B B +zheng3 @ ɡ ͩ +zheng4 G F g V +zhi1 ´ K u s j L O g ݥ | [ C Y +zhi2 ¾ Y ˻ h ŭ Բ T P j z ޿ [ H +zhi3 u } x k L T ˯ ܰ @ t ʪ C V +zhi4 v s P m x X o m n i c o F I Ů K ˤ ζ d z л ~ _ j P x W ׺ ~ Ҧ ~ l p ϣ E η г U d B +zhong1 J n ɱ ʸ y ` ޡ q X +zhong3 ~ +zhong4 F d \ د +zhou1 P g { w y N z v | E Һ P M +zhou2 b o +zhou3 y +zhou4 K z ` G ó C @ ̦ H B +zhu1 ] x м U L ־ } @ s +zhu2 v v Ľ T b b C z +zhu3 D N J Z f G _ [ F +zhu4 U ` n W E ű Ϯ R V } r M w K g +zhua1 f +zhua3 +zhuai1 +zhuai3 m +zhuai4 +zhuan1 M j B F W l m @ +zhuan3 +zhuan4 f W ޵ { +zhuang1 +zhuang3 N +zhuang4 Y +zhui1 l @ A ߡ +zhui3 D +zhui4 Y m ] p +zhun1 ʽ +zhun3 G ԭ b +zhun4 +zhuo1 g +zhuo2 _ B u ` N Z | տ ٸ Z @ H U ٺ ~ k a +zi1 s t Y d h F h ۤ r E ^ S @ +zi2 l +zi3 l J T d ӥ E ~ I ͡ B I +zi4 r { ְ F I H ~ +zong1 v a O q H w G I +zong3 ` p z +zong4 a q r +zou1 Q p h _ i ٴ i +zou3 +zou4 J ~ +zu1 +zu2 j A +zu3 [ A +zuan1 p p +zuan3 ġ p @ +zuan4 p +zui1 p n +zui3 L F C Z +zui4 o K ٢ I P b +zun1 L J d m b S +zun3 J +zun4 T ` W Q +zuo2 Q @ O +zuo3 w +zuo4 @ y ` w g ̩ _ Y + +# Punctuation + @ +, A B M N +. C D E O P +; F Q +: G J L R +? H S +! I T +... K +| U W Y +- V X +_ Z +( ] _ } +) ^ ` ~ +{ a c +} b d +[ e g i k +] f h j l +<< m o +>> n p +< q s +> r t +" u v w x +` y { +' z | +# +& +* +$ C L ++ += +~ +log +ln +/ A +\ @ B +% H M +@ I N +mil O +mm P +cm Q +km R +KM S +m2 T +mg U +kg V +cc W +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +I +II +III +IV +V +VI +VII +VIII +IX +X +A +B +C +D +E +F +G +H +J +K +L +M +N +O +P +Q +R +S +T +U +W +Y +Z +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w @ +x A +y B +z C +Alpha D +Beta E +Gamma F +Delta G +Epsilon H +Zeta I +Eta J +Theta K +Iota L +Kappa M +Lambda N +Mu O +Nu P +Xi Q +Omicron R +Pi S +Rho T +Sigma U +Tau V +Upsilon W +Phi X +Chi Y +Psi Z +Omega [ +alpha \ +beta ] +gamma ^ +delta _ +epsilon ` +zeta a +eta b +theta c +iota d +kappa e +lambda f +mu g +nu h +xi i +omicron j +pi k +rho l +sigma m +tau n +upsilon o +phi p +chi q +psi r +omega s +b1 t +p1 u +m1 v +f1 w +d1 x +t1 y +n1 z +l1 { +g1 | +k1 } +h1 ~ +j1 +q1 +x1 +zh1 +ch1 +sh1 +r1 +z1 +c1 +s1 +a1 +o1 +e1 +ai1 +ei1 +ao1 +ou1 +an1 +en1 +ang1 +eng1 +er1 +i1 +u1 + +# "Rare" homonyms (not to be caught on first match) + +# ba4 B +# chan2 +# chong2 +# dan4 +# gong1 @ +# gu1 a +# han4 M +# hang2 +# hang4 +# hua1 +# hui3 | +# ji1 _ +# jia3 L +# jiang4 j +# juan1 +# li2 R +# liang2 q +# ou1 +# shang3 W +# shen1 H +# shi2 +# shu3 +# xiao2 +# xin2 M +# ying1 diff --git a/lib/php/monica/postgres.inc.php b/lib/php/monica/postgres.inc.php new file mode 100644 index 0000000..58a0011 --- /dev/null +++ b/lib/php/monica/postgres.inc.php @@ -0,0 +1,708 @@ + +// Copyright: Copyright (C) 2004-2008 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines with high precedence +require_once "monica/sqlconst.inc.php"; +// Referenced subroutines +require_once "monica/errhndl.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/sqllogin.inc.php"; + +// Settings +$_PG_CONN = null; + +// xpg_connect: Connect to the PostgreSQL database +function xpg_connect($database = null) +{ + global $_PG_CONN; + // Connected + if (!is_null($_PG_CONN)) { + return; + } + // Obtain the SQL log-in information + if (is_null($database)) { + if (getenv("PGDATABASE") !== false) { + $database = getenv("PGDATABASE"); + } elseif (defined("PACKAGE")) { + $database = PACKAGE; + } + } + if (getenv("PGHOST") !== false) { + $host = getenv("PGHOST"); + } else { + $host = null; + } + + // Login with from SQLLOGIN environment variable as a web application + // php-cgi does not have STDIN and STDERR even on console + if (PHP_SAPI != "cli") { + $r = get_sql_login_info(SQL_POSTGRESQL, $database, $host); + // Connect it + $_PG_CONN = pg_connect(sprintf("host=%s dbname=%s user=%s password=%s", + $r["PGHOST"], $r["PGDATABASE"], $r["PGUSER"], $r["PGPASSWORD"])); + if ($_PG_CONN === false) { + $_PG_CONN = null; + trigger_error("Failed connecting to the PostgreSQL server.\n" + . $GLOBALS["php_errormsg"], E_USER_ERROR); + } + + // Ask the password from the console + } else { + $user = null; + $subseq = false; + set_error_handler("null_error_handler"); + $_PG_CONN = pg_connect("dbname=$database"); + restore_error_handler(); + while ($_PG_CONN === false) { + global $php_errormsg; + if ($subseq) { + fprintf(STDERR, "%s\n", $GLOBALS["php_errormsg"]); + sleep(5); + } + $subseq = true; + // Obtain the current login user + if ( is_null($user) + && preg_match("/ failed for user \"(.+?)\"/", $GLOBALS["php_errormsg"], $m)) { + $user = $m[1]; + } + // Disable console echo + system("/bin/stty -echo"); + fprintf(STDERR, !is_null($user)? "PostgreSQL password for $user: ": + "PostgreSQL password: "); + $passwd = fgets(STDIN); + fprintf(STDERR, "\n"); + // Restore console echo status + system("/bin/stty echo"); + // STDIN is not available + if ($passwd === false) { + die(THIS_FILE . ": Failed connecting to the PostgreSQL server\n"); + } + $passwd = trim($passwd); + set_error_handler("null_error_handler"); + $_PG_CONN = pg_connect("dbname=$database password=$passwd"); + restore_error_handler(); + } + } + + // Set the client encoding + $chaset = defined("SQL_CHARSET")? SQL_CHARSET: "utf8"; + $result = pg_set_client_encoding($_PG_CONN, $chaset); + if ($result == -1) { + trigger_error("Failed setting client encoding to $chaset.\n" + . (pg_last_error()? pg_last_error(): $GLOBALS["php_errormsg"]), E_USER_ERROR); + } + return; +} + +// xpg_close: Disconnect from the PostgreSQL database +function xpg_close() +{ + global $_PG_CONN; + if (is_null($_PG_CONN)) { + return; + } + $result = pg_close($_PG_CONN); + if ($result !== true) { + trigger_error("Failed disconnecting from the PostgreSQL server.\n" + . (pg_last_error()? pg_last_error(): $GLOBALS["php_errormsg"]), E_USER_ERROR); + } + $_PG_CONN = null; + return; +} + + +///////////////////////// +// Concurrency Control: Transactions and Locks +///////////////////////// +$_PG_IN_TRANSACTION = false; +// pg_begin: Begin a PostgreSQL transaction +function pg_begin() +{ + if (!$GLOBALS["_PG_IN_TRANSACTION"]) { + $begin = "START TRANSACTION;\n"; + xpg_query($begin); + $GLOBALS["_PG_IN_TRANSACTION"] = true; + } +} +// pg_commit: Commit a PostgreSQL transaction +function pg_commit() +{ + if ($GLOBALS["_PG_IN_TRANSACTION"]) { + $commit = "COMMIT;\n"; + xpg_query($commit); + $GLOBALS["_PG_IN_TRANSACTION"] = false; + } +} +// pg_rollback: Rollback a PostgreSQL transaction +function pg_rollback() +{ + if ($GLOBALS["_PG_IN_TRANSACTION"]) { + $rollback = "ROLLBACK;\n"; + xpg_query($rollback); + $GLOBALS["_PG_IN_TRANSACTION"] = false; + } +} + +// pg_lock: PostgreSQL table-locking handler +// PostgreSQL has no unlock +// Input: An associative array, where its keys are the tables to lock, +// and its values can be one of the following: +// LOCK_SH: Request a read lock +// LOCK_EX: Request a write lock +// LOCK_UN: No effect +// null has no effect here. +// Return: None. Errors are directed to error handlers +function pg_lock($locks = null) +{ + // Bounce for nothing + if (is_null($locks) || count($locks) == 0) { + return; + } + + // Remove the table aliases - compatibility with stupid MySQL + $abslocks = array(); + foreach (array_keys($locks) as $origtable) { + // Remove the table aliases + $abstable = preg_replace("/\s+AS\s+.+?$/i", "", $origtable); + // No override previous write lock + if ( array_key_exists($abstable, $abslocks) + && $abslocks[$abstable] == LOCK_EX) { + continue; + } + // Set the lock + $abslocks[$abstable] = $locks[$origtable]; + } + $locks = $abslocks; + + // Split into different lock modes + $reads = array(); + $writes = array(); + foreach (array_keys($locks) as $table) { + switch ($locks[$table]) { + case LOCK_SH: + $reads[] = $table; + break; + case LOCK_EX: + $writes[] = $table; + break; + default: + trigger_error("Bad SQL lock request: \"$locks[$table]\" on table \"$table\".", E_USER_ERROR); + } + } + + // Start transaction if not started yet. Table locks cannot + // live outside of transactions at all. + if (!$GLOBALS["_PG_IN_TRANSACTION"]) { + pg_begin(); + } + + // Request the locks + if (count($reads) > 0) { + $locktable = "LOCK TABLE " . implode(", ", $reads) + . " IN SHARE MODE;\n"; + xpg_query($locktable); + } + if (count($writes) > 0) { + $locktable = "LOCK TABLE " . implode(", ", $writes) + . " IN ACCESS EXCLUSIVE MODE;\n"; + xpg_query($locktable); + } + + return; +} + +// xpg_query: Do a PostgreSQL query and report the error +function xpg_query($query) +{ + set_error_handler("null_error_handler"); + $result = pg_query($query); + restore_error_handler(); + if ($result === false) { + trigger_error("Failed pg_query().\n$query\n" + . (pg_last_error()? pg_last_error(): $GLOBALS["php_errormsg"]), E_USER_ERROR); + } + return $result; +} + +// pg_seek: Move the PostgreSQL result pointer +function pg_seek($result, $offset) +{ + $result = pg_result_seek($result, $offset); + if ($result === false) { + trigger_error("Failed pg_result_seek().\n" + . (pg_last_error()? pg_last_error(): $GLOBALS["php_errormsg"]), E_USER_ERROR); + } + return $result; +} + +// xpg_fetch_assoc: Return a PostgreSQL row as an associative array +function xpg_fetch_assoc($result) +{ + // Fetch the raw data now + $row = pg_fetch_assoc($result); + // Return the error + if (!is_array($row)) { + return $row; + } + + // Adjust the boolean columns + foreach (pg_cols_of_type($result, SQL_TYPE_BOOLEAN, SQL_FETCH_ASSOC) as $col) { + if (!is_null($row[$col])) { + $row[$col] = ($row[$col] == "t"); + } + } + // Adjust the bytea columns + foreach (pg_cols_of_type($result, SQL_TYPE_BLOB, SQL_FETCH_ASSOC) as $col) { + if (!is_null($row[$col])) { + $row[$col] = pg_unescape_bytea($row[$col]); + } + } + // Adjust the integer columns + foreach (pg_cols_of_type($result, SQL_TYPE_INTEGER, SQL_FETCH_ASSOC) as $col) { + if (!is_null($row[$col])) { + settype($row[$col], "integer"); + } + } + // Adjust the big integer columns + foreach (pg_cols_of_type($result, SQL_TYPE_BIGINT, SQL_FETCH_ASSOC) as $col) { + if ( !is_null($row[$col]) + && $row[$col] >= -2147483647 + && $row[$col] <= 2147483647) { + settype($row[$col], "integer"); + } + } + // Adjust the float columns + foreach (pg_cols_of_type($result, SQL_TYPE_FLOAT, SQL_FETCH_ASSOC) as $col) { + if (!is_null($row[$col])) { + settype($row[$col], "float"); + } + } + + return $row; +} + +// xpg_fetch_row: Return a PostgreSQL row as an numeric array +function xpg_fetch_row($result) +{ + // Fetch the raw data now + $row = pg_fetch_row($result); + // Return the error + if (!is_array($row)) { + return $row; + } + + // Adjust the boolean columns + foreach (pg_cols_of_type($result, SQL_TYPE_BOOLEAN, SQL_FETCH_ROW) as $col) { + if (!is_null($row[$col])) { + $row[$col] = ($row[$col] == "t"); + } + } + // Adjust the bytea columns + foreach (pg_cols_of_type($result, SQL_TYPE_BLOB, SQL_FETCH_ROW) as $col) { + if (!is_null($row[$col])) { + $row[$col] = pg_unescape_bytea($row[$col]); + } + } + // Adjust the integer columns + foreach (pg_cols_of_type($result, SQL_TYPE_INTEGER, SQL_FETCH_ROW) as $col) { + if (!is_null($row[$col])) { + settype($row[$col], "integer"); + } + } + // Adjust the big integer columns + foreach (pg_cols_of_type($result, SQL_TYPE_BIGINT, SQL_FETCH_ROW) as $col) { + if ( !is_null($row[$col]) + && $row[$col] >= -2147483647 + && $row[$col] <= 2147483647) { + settype($row[$col], "integer"); + } + } + // Adjust the float columns + foreach (pg_cols_of_type($result, SQL_TYPE_FLOAT, SQL_FETCH_ROW) as $col) { + if (!is_null($row[$col])) { + settype($row[$col], "float"); + } + } + + return $row; +} + +// pg_tables: Obtain a list of available PostgreSQL tables +// and report the error +function pg_tables($schema = null) +{ + // Default to the current schema + if (is_null($schema)) { + $schema = _pg_current_schema(); + } + $select = "SELECT tablename FROM pg_tables" + . " WHERE schemaname='" . pg_escape_string($schema) . "'" + . " ORDER BY tablename;\n"; + $result = xpg_query($select); + $count = pg_num_rows($result); + for ($i = 0, $tables = array(); $i < $count; $i++) { + $row = pg_fetch_row($result); + $tables[] = $row[0]; + } + return $tables; +} + +// pg_cols: Obtain the column list of a PostgreSQL table +function pg_cols($table) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($table, $cache)) { + return $cache[$table]; + } + global $_PG_CONN; + // Use pg_meta_data(). This is marked as experimental in PHP documentation yet. + $result = pg_meta_data($_PG_CONN, $table); + if ($result === false) { + trigger_error("Failed pg_meta_data(\$PG_CONN, \"$table\").\n" + . (pg_last_error()? pg_last_error(): $GLOBALS["php_errormsg"]), E_USER_ERROR); + } + $cache[$table] = array_keys($result); + return $cache[$table]; +} + +// pg_cols_ml: Return a list of multi-lingual columns in a PostgreSQL table +function pg_cols_ml($table) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($table, $cache)) { + return $cache[$table]; + } + + // Get the columns that have language variants + $cols = pg_cols($table); + $cache[$table] = array(); + $suffix = "_" . getlang(LN_DATABASE); + $len = strlen($suffix); + for ($i = 0; $i < count($cols); $i++) { + // It has a language suffix + if (substr($cols[$i], -$len) == $suffix) { + $cache[$table][] = substr($cols[$i], 0, -$len); + } + } + + return $cache[$table]; +} + +// pg_cols_nl: Return a list of columns without their multi-lingual +// deviants in a PostgreSQL table +function pg_cols_nl($table) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($table, $cache)) { + return $cache[$table]; + } + + // Get the columns that have language variants + $cols = pg_cols($table); + $langcols = pg_cols_ml($table); + + // Remove those language variants + $cache[$table] = array(); + for ($i = 0; $i < count($cols); $i++) { + $pos = strrpos($cols[$i], "_"); + // No suffix + if ($pos === false) { + $cache[$table][] = $cols[$i]; + // Check the prefix + } else { + $prefix = substr($cols[$i], 0, $pos); + // The prefix is one of the language columns + if (in_array($prefix, $langcols)) { + // Not counted yet + if (!in_array($prefix, $cache[$table])) { + $cache[$table][] = $prefix; + } + // An ordinary prefix + } else { + $cache[$table][] = $cols[$i]; + } + } + } + + return $cache[$table]; +} + +// pg_cols_of_type: Return the columns in a certain data type +function pg_cols_of_type($result, $type, $format = SQL_FETCH_ASSOC) +{ + $result_key = _pg_result_hashkey($result); + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($result_key, $cache)) { + return $cache[$result_key][$type][$format]; + } + + // Check each field type + $count = pg_num_fields($result); + $cols = array( + SQL_TYPE_BOOLEAN => array( + SQL_FETCH_ASSOC => array(), + SQL_FETCH_ROW => array(), + ), + SQL_TYPE_BLOB => array( + SQL_FETCH_ASSOC => array(), + SQL_FETCH_ROW => array(), + ), + SQL_TYPE_INTEGER => array( + SQL_FETCH_ASSOC => array(), + SQL_FETCH_ROW => array(), + ), + SQL_TYPE_BIGINT => array( + SQL_FETCH_ASSOC => array(), + SQL_FETCH_ROW => array(), + ), + SQL_TYPE_FLOAT => array( + SQL_FETCH_ASSOC => array(), + SQL_FETCH_ROW => array(), + ), + ); + for ($i = 0; $i < $count; $i++) { + $coltype = pg_field_type($result, $i); + $colname = pg_field_name($result, $i); + switch ($coltype) { + case "bool": + $cols[SQL_TYPE_BOOLEAN][SQL_FETCH_ROW][] = $i; + $cols[SQL_TYPE_BOOLEAN][SQL_FETCH_ASSOC][] = $colname; + break; + case "bytea": + $cols[SQL_TYPE_BLOB][SQL_FETCH_ROW][] = $i; + $cols[SQL_TYPE_BLOB][SQL_FETCH_ASSOC][] = $colname; + break; + case "int2": + case "int4": + $cols[SQL_TYPE_INTEGER][SQL_FETCH_ROW][] = $i; + $cols[SQL_TYPE_INTEGER][SQL_FETCH_ASSOC][] = $colname; + break; + case "int8": + $cols[SQL_TYPE_BIGINT][SQL_FETCH_ROW][] = $i; + $cols[SQL_TYPE_BIGINT][SQL_FETCH_ASSOC][] = $colname; + break; + case "float4": + case "float8": + $cols[SQL_TYPE_FLOAT][SQL_FETCH_ROW][] = $i; + $cols[SQL_TYPE_FLOAT][SQL_FETCH_ASSOC][] = $colname; + break; + } + } + + // Cache it + $cache[$result_key] = $cols; + return $cols[$type][$format]; +} + +// pg_col_lens: Obtain the column lengths of a PostgreSQL table +function pg_col_lens($table) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($table, $cache)) { + return $cache[$table]; + } + $schema = _pg_current_schema(); + $select = "SELECT pg_attribute.attname AS col," + . " pg_type.typname AS type," + . " pg_attribute.attlen AS len," + . " pg_attribute.atttypmod AS typmod" + . " FROM pg_attribute" + . " INNER JOIN pg_class ON pg_attribute.attrelid=pg_class.oid" + . " INNER JOIN pg_type ON pg_attribute.atttypid=pg_type.oid" + . " INNER JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid" + . " WHERE pg_namespace.nspname='" . pg_escape_string($schema) . "'" + . " AND pg_class.relname='" . pg_escape_string($table) . "'" + . " AND pg_class.relkind='r'" + . " AND pg_attribute.attnum>0" + . " ORDER BY pg_attribute.attnum;\n"; + $result = xpg_query($select); + $count = pg_num_rows($result); + for ($i = 0, $cache[$table] = array(); $i < $count; $i++) { + $row = pg_fetch_assoc($result); + switch ($row["type"]) { + // Integer -- Digits of the largest number - 1 + case "int2": + case "int4": + case "int8": + $cache[$table][$row["col"]] = floor(log10(pow(256, $row["len"]))); + settype($cache[$table][$row["col"]], "integer"); + break; + // Refer to typmod for char and varchar + case "varchar": + case "bpchar": + $cache[$table][$row["col"]] = $row["typmod"] - 4; + break; + // Set text and bytea to 4294967296 (2^32) (infinite actually) + case "text": + case "bytea": + $cache[$table][$row["col"]] = 4294967296; + break; + // Set timestamp to 19 + case "timestamp": + $cache[$table][$row["col"]] = 26; + break; + // Set date to 10 + case "date": + $cache[$table][$row["col"]] = 10; + break; + // Set time to 8 + case "time": + $cache[$table][$row["col"]] = 8; + break; + // Set numeric to precision + 1 decimal point + // Refer to http://archives.postgresql.org/pgsql-hackers/1999-01/msg00127.php + case "numeric": + $typmod = $row["typmod"] - 4; + $scale = $typmod & 0xFFFF; + $precision = $typmod >> 16; + $cache[$table][$row["col"]] = $precision + 1; + break; + // Set boolean to 1 + case "bool": + $cache[$table][$row["col"]] = 1; + break; + // Set inet to 18 (nnn.nnn.nnn.nnn/nn) + case "inet": + $cache[$table][$row["col"]] = 18; + break; + // Bounce for other columns, so that we know to fix it here + default: + trigger_error("Unknown column type " . $row["type"] + . " for table $table", E_USER_ERROR); + break; + } + } + + // Hash the multi-lingual columns + $lndb = getlang(LN_DATABASE); + foreach (pg_cols_ml($table) as $col) { + $cache[$table][$col] = $cache[$table][$col . "_" . $lndb]; + } + + return $cache[$table]; +} + +// pg_strcat: Concatenate strings in PostgreSQL +// PostgreSQL uses the || operator to concatenate strings +function pg_strcat() +{ + $strs = func_get_args(); + return implode(" || ", $strs); +} + +// pg_lastupd: Obtain the last updated time of a list of tables +function pg_lastupd($tables) +{ + // Bounce if no tables supplied + if (is_null($tables) || count($tables) == 0) { + return; + } + // Remove the table aliases + for ($i = 0; $i < count($tables); $i++) { + $tables[$i] = preg_replace("/\s+AS\s+.+?$/i", "", $tables[$i]); + } + // Remove duplicates + $tables = array_values(array_unique($tables)); + // Query + $conds = array(); + foreach ($tables as $table) { + $conds[] = "tabname='" . pg_escape_string($table) . "'"; + } + $select = "SELECT mtime FROM mtime" + . " WHERE " . implode(" OR ", $conds) + . " ORDER BY mtime DESC LIMIT 1;\n"; + $result = xpg_query($select); + // Bounce if no data found + if (pg_num_rows($result) != 1) { + return; + } + // Return the result + $row = xpg_fetch_assoc($result); + return $row["mtime"]; +} + +// pg_dbsize: Obtain the size of the database +function pg_dbsize() +{ + $select = "SELECT pg_database_size(datname) FROM pg_database" + . " WHERE datname=current_database();\n"; + $result = xpg_query($select); + $row = xpg_fetch_row($result); + return $row[0]; +} + +// pg_date: Return date in a predefined format format +function pg_date($expr, $format) +{ + switch ($format) { + case SQL_YYYYMMDD: + return "to_char($expr, 'YYYYMMDD')"; + case SQL_YYYY_YYYYMMDD: + return "to_char($expr, 'YYYY/YYYYMMDD')"; + case SQL_MM_DD: + return "to_char($expr, 'MM-DD')"; + case SQL_M_D_EN: + return "to_char($expr, 'FMMM/FMDD')"; + case SQL_M_D_ZHTW: + return "to_char($expr, 'FMMM月FMDD日')"; + case SQL_M_D_DE: + return "to_char($expr, 'FMDD.FMMM')"; + case SQL_HH_MM: + return "to_char($expr, 'HH24:MI')"; + } +} + +// pg_re: Return the PostgreSQL regular expression operator +function pg_re() +{ + return "~"; +} + +// _pg_result_hashkey: Generate a hash key from a PostgreSQL query result +function _pg_result_hashkey($result) +{ + // Use the output of var_dump + ob_start(); + var_dump($result); + $key = ob_get_contents(); + ob_end_clean(); + return $key; +} + +// _pg_current_schema: Obtain the current schema +function _pg_current_schema() +{ + // Cache the result + static $cache; + // Return the cache + if (isset($cache)) { + return $cache; + } + $select = "SELECT current_schema();\n"; + $result = xpg_query($select); + $row = pg_fetch_row($result); + $cache = $row[0]; + return $cache; +} + +?> diff --git a/lib/php/monica/preview.inc.php b/lib/php/monica/preview.inc.php new file mode 100644 index 0000000..5c2aeca --- /dev/null +++ b/lib/php/monica/preview.inc.php @@ -0,0 +1,155 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/callform.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/htmlchar.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/page2rel.inc.php"; +require_once "monica/pagefunc.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/sql.inc.php"; + +// fetch_preview: Retrieve a previously suspended preview from, +// from $_SESSION or database +function fetch_preview() +{ + // S/N not specified + if (!array_key_exists("sn", $_GET)) { + return array("msg"=>NC_("The following field was not received: \"%s\"."), + "margs"=>array("sn"), + "isform"=>false); + } + // Check the source to retrieve the preview form + $source = "session"; + if (array_key_exists("source", $_GET)) { + switch ($_GET["source"]) { + // Retrieve from the database + case "db": + $source = "db"; + break; + // Retrieve from the $_SESSION saveform + case "session": + $source = "session"; + break; + // Other preview sources + default: + return array("msg"=>NC_("Unknown preview source: \"%s\"."), + "margs"=>array($_GET["source"]), + "isform"=>false); + break; + } + } + + // Retrieve the preview form + switch ($source) { + // Retrieve from the database + case "db": + // Fetch with fetch_curitem() + fetch_curitem(); + $GLOBALS["PREVIEW"] =& $GLOBALS["CURRENT"]; + break; + // Retrieve from the $_SESSION saveform + case "session": + $GLOBALS["PREVIEW"] =& retrieve_form($_GET["sn"]); + if (count($GLOBALS["PREVIEW"]) == 0) { + unset($GLOBALS["PREVIEW"]); + return array("msg"=>NC_("Unknown preview form: %d."), + "margs"=>array($_GET["sn"]), + "isform"=>false); + } + break; + } + // Tag that this is a preview content + $GLOBALS["PREVIEW"]["preview"] = true; + // OK + return null; +} + +// html_preview: Display the preview +function html_preview() +{ + // Lock the required tables + if (array_key_exists("REBUILD_TABLES", $GLOBALS)) { + $sql_lock = array(); + foreach ($GLOBALS["REBUILD_TABLES"] as $table) { + $sql_lock[$table] = LOCK_SH; + } + } + sql_lock($sql_lock); + global $PREVIEW; + $html = compose_page($PREVIEW); + $path = $PREVIEW["path"]; + // A multi-lingual website + if (count($GLOBALS["ALL_LINGUAS"]) > 1 && !preg_match("/\.php\?/", $path)) { + $path = "/" . getlang(LN_FILENAME) . $path; + } + $html = page2rel(page2abs($html, $path), REQUEST_PATH); + echo $html; + return; +} + +// html_preview_mark: Print the HTML preview mark +function html_preview_mark($args = null) +{ + // Obtain page parameters + $args = page_param($args); + // This is only for the preview + if (is_null($args["preview"])) { + return; + } + + // Decide the data source + $source = "session"; + if (array_key_exists("source", $_GET)) { + switch ($_GET["source"]) { + // Retrieve from the database + case "db": + $source = "db"; + break; + // Retrieve from the $_SESSION saveform + case "session": + $source = "session"; + break; + // Other preview sources + default: + trigger_error("Unknown preview source: \"" . $_GET["source"] . "\"", + E_USER_ERROR); + break; + } + } + + // Set the query arguments + switch ($source) { + // Retrieve from the database + case "db": + $url = REQUEST_PATH . "?form=cur&sn=" . $_GET["sn"]; + break; + // Retrieve from the $_SESSION saveform + case "session": + $url = REQUEST_PATH . "?formid=" . $_GET["sn"]; + break; + } + $areatitle = C_("Preview Mark Area"); + +?>
    +

    +

    +
    + + diff --git a/lib/php/monica/process.inc.php b/lib/php/monica/process.inc.php new file mode 100644 index 0000000..8fadbaa --- /dev/null +++ b/lib/php/monica/process.inc.php @@ -0,0 +1,2565 @@ + +// Copyright: Copyright (C) 2005-2011 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/actlog.inc.php"; +require_once "monica/addcol.inc.php"; +require_once "monica/cgiemu.inc.php"; +require_once "monica/chkpriv.inc.php"; +require_once "monica/commtext.inc.php"; +require_once "monica/geoip.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/guest.inc.php"; +require_once "monica/hires.inc.php"; +require_once "monica/http.inc.php"; +require_once "monica/links.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/logout.inc.php"; +require_once "monica/news.inc.php"; +require_once "monica/pic.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/scptpriv.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/unicode.inc.php"; +require_once "monica/username.inc.php"; +require_once "monica/userpref.inc.php"; +require_once "monica/usrconst.inc.php"; + +// Settings + +// BaseProcessor: Base form processor class +class BaseProcessor +{ + // Accessible by other processors + public $_sn = null; + + protected $_form = array(); + protected $_cur = array(); + protected $_req = array(); + protected $_table = null; + protected $_type = null; + protected $_step = null; + protected $_cols = null; + protected $_pres = array(); + protected $_subs = array(); + + protected $_is_sql = true; + protected $_update_timestamp = true; + protected $_modified = null; + + protected $_curshown = null; + protected $_newshown = null; + + // __construct: Initialize the processor + function __construct(&$form, $table = null) + { + $this->_form =& $form; + $this->_table = $table; + $this->_pres = array(); + $this->_subs = array(); + if (!is_null($this->_form("form"))) { + $this->_type = $this->_form["form"]; + } + if (!is_null($this->_form("step"))) { + $this->_step = $this->_form["step"]; + } + if (!is_null($this->_form("sn"))) { + $this->_sn = $this->_form["sn"]; + } + // The current item + if (array_key_exists("CURRENT", $GLOBALS)) { + $this->_cur =& $GLOBALS["CURRENT"]; + } + // The user request + if (array_key_exists("REQUEST", $GLOBALS)) { + $this->_req =& $GLOBALS["REQUEST"]; + } + return; + } + + // process: Process the form, fully + function process() + { + // Submitted but not confirmed yet + if (is_null($this->_form("confirm"))) { + return array("preview"=>true); + } + + // Save the column deposit + $this->_save_cols(); + // Not modified + if (!$this->_modified()) { + return $this->_ret_status(); + } + + // Begin the SQL transaction + if ($this->_is_sql) { + sql_begin(); + } + // Update the columns + $this->_update_cols(); + // Rebuild a limited part of pages + $this->_rebuild_partial_pages(); + // Send mails + $this->_send_mails(); + // Perform tasks other than column updates + $this->_other_tasks(); + // Commit the SQL transaction + if ($this->_is_sql) { + sql_commit(); + } + + // Log and return the process status + $this->_actlog(); + return $this->_ret_status(); + } + + ///////////////////////// + // Methods belows are private. Do not call them directly. + // Override them when needed. + ///////////////////////// + // _save_cols: Save the column deposit + function _save_cols() + { + if (is_null($this->_type)) { + return; + } + switch ($this->_type) { + // A form to create a new item + case "new": + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + $this->_cols->addnum("sn", $this->_sn); + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + break; + } + return; + } + + // _update_cols: Update the columns + function _update_cols() + { + // Run the pre-processing sub-processors + for ($i = 0; $i < count($this->_pres); $i++) { + if ($this->_pres[$i]->_modified()) { + $this->_pres[$i]->_update_cols(); + } + } + + // Process the update + if ($this->_is_sql && !is_null($this->_type)) { + switch ($this->_type) { + // A form to create a new item + case "new": + if (!is_null($this->_cols)) { + $insert = "INSERT INTO " . $this->_table + . " " . $this->_cols->ret($this->_update_timestamp) . ";\n"; + gsql_query($insert); + } + break; + + // A form to edit a current item + case "cur": + if (!is_null($this->_cols) && !is_null($this->_sn)) { + $update = "UPDATE " . $this->_table + . " " . $this->_cols->ret($this->_update_timestamp) + . " WHERE sn=" . $this->_sn . ";\n"; + gsql_query($update); + } + break; + + // A form to delete a current item + case "del": + if (!is_null($this->_sn)) { + $delete = "DELETE FROM " . $this->_table + . " WHERE sn=" . $this->_sn . ";\n"; + gsql_query($delete); + } + break; + } + } + + // Run the sub-processors + for ($i = 0; $i < count($this->_subs); $i++) { + if ($this->_subs[$i]->_modified()) { + $this->_subs[$i]->_update_cols(); + } + } + return; + } + + // _rebuild_partial_pages: Rebuild a limited part of pages + // Empty by default. Put page building code here. + function _rebuild_partial_pages() + { + return; + } + + // _send_mails: Send the mails + // Empty by default. + function _send_mails() + { + return; + } + + // _other_tasks: Perform tasks other than column updates + // Empty by default. + function _other_tasks() + { + return; + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + return gactlog("Create a record with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + return gactlog("Update the record with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + return gactlog("Delete the record with s/n " . $this->_sn . "."); + } + } + + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This record was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This record has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This record has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This record has been successfully deleted."), + "isform"=>false); + } + } + + // _form: Return a specific form value + // Return null if that column is empty + function _form($name) + { + return array_key_exists($name, $this->_form)? + $this->_form[$name]: null; + } + + // _mcur: Return a specific current value, for use in e-mail notification + // Return (blank) if that column is empty + // Override it to obtain certain values for certain columns + function _mcur($name) + { + return array_key_exists($name, $this->_cur) + && !is_null($this->_cur[$name]) + && $this->_cur[$name] != ""? + $this->_cur[$name]: t_blank(); + } + + // _mform: Return a specific form value, for use in e-mail notification + // Return (blank) if that column is empty + // Override it to obtain certain values for certain columns + function _mform($name) + { + return array_key_exists($name, $this->_form) + && !is_null($this->_form[$name]) + && $this->_form[$name] != ""? + $this->_form[$name]: t_blank(); + } + + ///////////////////////// + // Methods belows are private. Do not call them directly. + // Do not override them, either. + ///////////////////////// + // _modified: If the item is modified + function _modified() + { + // Modification status checked before + if (!is_null($this->_modified)) { + return $this->_modified; + } + // Return true for addition and deletion processors + if (!is_null($this->_type) && $this->_type != "cur") { + $this->_modified = true; + return $this->_modified; + } + // Return true if the columns are modified + if (!is_null($this->_cols) && $this->_cols->modified()) { + $this->_modified = true; + return $this->_modified; + } + // Return true if any of the subprocessors is modified + for ($i = 0; $i < count($this->_pres); $i++) { + if ($this->_pres[$i]->_modified()) { + $this->_modified = true; + return $this->_modified; + } + } + for ($i = 0; $i < count($this->_subs); $i++) { + if ($this->_subs[$i]->_modified()) { + $this->_modified = true; + return $this->_modified; + } + } + // Not modified + $this->_modified = false; + return $this->_modified; + } + + // _zhsync: Automatic Traditional Chinese to Simplified Chinese conversion + function _zhsync() + { + // Get the available languages list + global $ALL_LINGUAS; + // Skip unless multilingual + if (count($ALL_LINGUAS) == 1) { + return; + } + // Skip unless we are in Traditional Chinese, and there is Simplified Chinese + if (getlang() != "zh-tw" || !in_array("zh-cn", $ALL_LINGUAS)) { + return; + } + switch ($this->_type) { + // A form to create a new item + case "new": + foreach (sql_cols_ml($this->_table) as $col) { + if (!is_null($this->_form($col))) { + $this->_cols->addstr($col . "_zhcn", trad_to_simp($this->_form[$col])); + } + } + break; + // A form to edit a current item + case "cur": + foreach (sql_cols_ml($this->_table) as $col) { + if (!is_null($this->_form($col))) { + $this->_cols->addstr($col . "_zhcn", trad_to_simp($this->_form[$col]), $this->_cur[$col . "_zhcn"]); + } + } + break; + } + } + + // _new_sn: Generate a new random serial number for an SQL table + function _new_sn() + { + // S/N is always 9 digits + do { + // Generate a random serial number + $sn = mt_rand(100000000, 999999999); + // Check if this serial number exists + $select = "SELECT sn FROM " . $this->_table + . " WHERE sn=$sn;\n"; + $result = sql_query($select); + } while (sql_num_rows($result) > 0); + return $sn; + } + + // _req_hostport: Find the host-port of the POSTer, to be used in the e-mail. + // This may not be the same as myself, since user may pass to + // an SSL handler from a non-SSL form. + function _req_hostport() + { + // Cache the resuit + static $cache; + // Return the cache + if (isset($cache)) { + return $cache; + } + if (!is_null($this->_form("referer"))) { + $ref = $this->_form["referer"]; + } elseif (array_key_exists("HTTP_REFERER", $_SERVER)) { + $ref = $_SERVER["HTTP_REFERER"]; + } + if ( isset($ref) + && substr($ref, -strlen(REQUEST_PATH)) == REQUEST_PATH) { + $cache = substr($ref, 0, -strlen(REQUEST_PATH)); + } else { + $cache = REQUEST_HOSTPORT; + } + return $cache; + } +} + +// BaseCategoryProcessor: Base category form processor class +class BaseCategoryProcessor extends BaseProcessor +{ + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This category was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This category has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This category has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This category has been successfully deleted."), + "isform"=>false); + } + } +} + +// BaseCategorizationProcessor: Base categorization record form processor class +class BaseCategorizationProcessor extends BaseProcessor +{ + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This categorization record was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This categorization record has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This categorization record has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This categorization record has been successfully deleted."), + "isform"=>false); + } + } +} + +// DeletionProcessor: Deletion form processor class +// Deletion condition is the value of the "cond" column in the form +class DeletionProcessor extends BaseProcessor +{ + protected $_cond = null; + + // __construct: Initialize the processor + function __construct(&$form, $table = null) + { + $form["form"] = "del"; + parent::__construct($form, $table); + $this->_cond = $this->_form["cond"]; + } + + // _update_cols: Update the columns + function _update_cols() + { + // Process the update + $delete = "DELETE FROM " . $this->_table + . " WHERE " . $this->_cond . ";\n"; + gsql_query($delete); + return; + } +} + +// ListPreferenceProcessor: List preference form processor class +class ListPreferenceProcessor extends BaseProcessor +{ + protected $_names = array(); + + // __construct: Initialize the processor + function __construct(&$form, $table = null) + { + parent::__construct($form, $table); + if (is_guest()) { + $this->_is_sql = false; + } + $this->_names = array("listsize", "listcols"); + } + + // process: Process the form, fully + function process() + { + // Use the parent processor for ordinary users + // Users without Cookies turned on may have an empty log-in S/N + if (!is_null(get_login_sn()) && !is_guest()) { + return parent::process(); + } + + // Guest preferences are saved in $_SESSION + if (!array_key_exists("userpref", $_SESSION)) { + $_SESSION["userpref"] = array(); + } + if (!array_key_exists($this->_form["domain"], $_SESSION["userpref"])) { + $_SESSION["userpref"][$this->_form["domain"]] = array(); + } + + foreach ($this->_names as $name) { + $_SESSION["userpref"][$this->_form["domain"]][$name] = $this->_prefval($name); + } + return; + } + + // _save_cols: Save the column deposit + function _save_cols() + { + for ($i = 0; $i < count($this->_names); $i++) { + // Obtain the preference value + $val = $this->_prefval($this->_names[$i]); + // Only update if value is different + if (userpref($this->_names[$i], $this->_form["domain"]) == $val) { + continue; + } + + // Check if there is already an existing user preference + $select = "SELECT * FROM userpref" + . " WHERE usr=" . get_login_sn() + . " AND domain='" . sql_esctext($this->_form["domain"]) . "'" + . " AND name='" . sql_esctext($this->_names[$i]) . "';\n"; + $result = sql_query($select); + // There is an existing user preference + if (sql_num_rows($result) == 1) { + $row = sql_fetch_assoc($result); + unset($GLOBALS["CURRENT"]); + $GLOBALS["CURRENT"] = array( + "sn" => $row["sn"], + "usr" => $row["usr"], + "domain" => $row["domain"], + "name" => $row["name"], + "value" => $row["value"], + ); + unset($FORM); + $FORM = array(); + $FORM["form"] = "cur"; + $FORM["sn"] = $row["sn"]; + $FORM["usr"] = get_login_sn(); + $FORM["domain"] = $this->_form("domain"); + $FORM["name"] = $this->_names[$i]; + $FORM["value"] = $val; + $processor = new UserPreferenceProcessor($FORM); + $processor->_save_cols(); + $this->_subs[] = $processor; + unset($GLOBALS["CURRENT"]); + if (!is_null($this->_cur)) { + $GLOBALS["CURRENT"] =& $this->_cur; + } + + // There is no existing user preference + } else { + unset($FORM); + $FORM = array(); + $FORM["form"] = "new"; + $FORM["usr"] = get_login_sn(); + $FORM["domain"] = $this->_form("domain"); + $FORM["name"] = $this->_names[$i]; + $FORM["value"] = $val; + $processor = new UserPreferenceProcessor($FORM); + $processor->_save_cols(); + $this->_subs[] = $processor; + } + } + return; + } + + // _actlog: Log the activity + function _actlog() + { + // Run the sub-processors + for ($i = 0; $i < count($this->_subs); $i++) { + if ($this->_subs[$i]->_modified()) { + $this->_subs[$i]->_actlog(); + } + } + } + + // _prefval: Obtain the preference value + function _prefval($name) + { + // Specified + if (!is_null($this->_form($name))) { + return $this->_form[$name]; + } + // No need to check the validility. Invalids are simply ignored. + $cols = array(); + foreach (array_keys($this->_form) as $key) { + if (preg_match("/^" . $name . "_(.+)$/", $key, $m)) { + $cols[] = $m[1]; + } + } + // Compose the preference value + return implode(" ", $cols); + } +} + +// UserProcessor: User form processor class +class UserProcessor extends BaseProcessor +{ + // If it is a user editing herself (return from confirmation mail) + public $_is_self = false; + // If we should update the groups + public $_no_set_groups = false; + // If we need to purge the user's password + public $_purge_passwd = null; + + // __construct: Initialize the processor + function __construct(&$form, $table = "users") + { + parent::__construct($form, $table); + // Non-super-users editing herself are not allowed to update the groups + if (!is_null($this->_sn) && !is_su() && $this->_sn == get_login_sn()) { + $this->_no_set_groups = true; + } + } + + // _save_cols: Save the column deposit + function _save_cols() + { + switch ($this->_type) { + // A form to create a new item + case "new": + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + if ($this->_is_self && is_null(get_login_sn())) { + $this->_cols->login = $this->_sn; + } + $this->_cols->addnum("sn", $this->_sn); + $this->_cols->addstr("id", $this->_form("id")); + $this->_cols->addpass("passwd", $this->_purge_passwd(), $this->_form("passwd")); + $this->_cols->addstr("name", $this->_form("name")); + $this->_cols->addbool("disabled", $this->_form("disabled")); + + // Find the changed items + if (!$this->_no_set_groups) { + $additems = array(); + for ($i = 0; !is_null($this->_form("supgroup$i" . "sn")); $i++) { + if (!is_null($this->_form("supgroup$i"))) { + $additems[] = $this->_form["supgroup$i" . "sn"]; + } + } + // Super users can set the super-user privilege + if (is_su()) { + // Super user privilege is added + if (!is_null($this->_form("su"))) { + $additems[] = su_group_sn(); + } + } + foreach ($additems as $item) { + unset($FORM); + $FORM = array(); + $FORM["form"] = "new"; + $FORM["grp"] = $item; + $FORM["member"] = $this->_sn; + $processor = new UserMembershipProcessor($FORM); + $processor->_save_cols(); + $this->_subs[] = $processor; + } + } + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + if ($this->_is_self && is_null(get_login_sn())) { + $this->_cols->login = $this->_sn; + } + // Skip for non-super-user editing a super-user + if (!(!is_su() && $this->_cur["su"])) { + $this->_cols->addstr("id", $this->_form("id"), $this->_cur["id"]); + $this->_cols->addpass("passwd", $this->_purge_passwd(), $this->_form("passwd"), $this->_cur["passwd"]); + } + $this->_cols->addstr("name", $this->_form("name"), $this->_cur["name"]); + // Skip for non-super-user editing herself or a super-user + if (!(!is_su() && ($this->_cur["su"] || $this->_sn == get_login_sn()))) { + $this->_cols->addbool("disabled", $this->_form("disabled"), $this->_cur["disabled"]); + } + if (!is_null($this->_form("failsreset"))) { + $this->_cols->addnum("fails", 0, $this->_cur["fails"]); + } + + // Find the changed items + if (!$this->_no_set_groups) { + $olditems = array(); + $newitems = array(); + for ($i = 0; array_key_exists("supgroup$i" . "sn", $this->_cur); $i++) { + $olditems[] = $this->_cur["supgroup$i" . "sn"]; + } + for ($i = 0; !is_null($this->_form("supgroup$i" . "sn")); $i++) { + if (!is_null($this->_form("supgroup$i"))) { + $newitems[] = $this->_form["supgroup$i" . "sn"]; + } + } + $delitems = array_values(array_diff($olditems, $newitems)); + $additems = array_values(array_diff($newitems, $olditems)); + // Super users can set the super-user privilege + if (is_su()) { + // Super user privilege is added + if (!$this->_cur["su"] && !is_null($this->_form("su"))) { + $additems[] = su_group_sn(); + // Super user privilege is removed + } elseif ($this->_cur["su"] && is_null($this->_form("su"))) { + $delitems[] = su_group_sn(); + } + } + foreach ($additems as $item) { + unset($FORM); + $FORM = array(); + $FORM["form"] = "new"; + $FORM["grp"] = $item; + $FORM["member"] = $this->_sn; + $processor = new UserMembershipProcessor($FORM); + $processor->_save_cols(); + $this->_subs[] = $processor; + } + if (count($delitems) > 0) { + for ($i = 0; $i < count($delitems); $i++) { + $delitems[$i] = "grp=" . $delitems[$i]; + } + $cond = implode(" OR ", $delitems); + if (count($delitems) > 1) { + $cond = "($cond)"; + } + unset($FORM); + $FORM = array(); + $FORM["cond"] = $cond . " AND member=" . $this->_sn; + $this->_subs[] = new DeletionProcessor($FORM, "usermem"); + } + } + break; + + // A form to delete a current item + case "del": + // Find the changed items + if ($this->_cur["supgroupcount"] > 0) { + unset($FORM); + $FORM = array(); + $FORM["cond"] = "member=" . $this->_sn; + $this->_subs[] = new DeletionProcessor($FORM, "usermem"); + } + + unset($FORM); + $FORM = array(); + $FORM["cond"] = "usr=" . $this->_sn; + $this->_pres[] = new DeletionProcessor($FORM, "userpref"); + break; + } + return; + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + return gactlog("Create a user account " . $this->_form["id"] + . " with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + return gactlog("Update the user account " + . (!is_null($this->_form("id"))? $this->_form["id"]: $this->_cur["id"]) + . " with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + return gactlog("Delete the user account " . $this->_cur["id"] + . " with s/n " . $this->_sn . "."); + } + } + + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This user account was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This user account has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This user account has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This user account has been successfully deleted."), + "isform"=>false); + } + } + + // _purge_passwd: If we need to purge the password of the user + function _purge_passwd() + { + // Checked before + if (!is_null($this->_purge_passwd)) { + return $this->_purge_passwd; + } + // Purge password for guests + if (!$this->_no_set_groups) { + for ($i = 0; !is_null($this->_form("supgroup$i" . "sn")); $i++) { + // Skip unselected groups + if (is_null($this->_form("supgroup$i"))) { + continue; + } + // Check if this is the guest group + if (groupid($this->_form["supgroup$i" . "sn"]) == GUEST_GROUP) { + $this->_purge_passwd = true; + return true; + } + } + } + // No guest group was found + $this->_purge_passwd = false; + return false; + } +} + +// GroupProcessor: Group form processor class +class GroupProcessor extends BaseProcessor +{ + // __construct: Initialize the processor + function __construct(&$form, $table = "groups") + { + parent::__construct($form, $table); + } + + // _save_cols: Save the column deposit + function _save_cols() + { + switch ($this->_type) { + // A form to create a new item + case "new": + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + $this->_cols->addnum("sn", $this->_sn); + $this->_cols->addstr("id", $this->_form("id")); + $this->_cols->addstr("dsc", $this->_form("dsc")); + + // Find the changed items + $additems = array(); + for ($i = 0; !is_null($this->_form("subuser$i" . "sn")); $i++) { + if (!is_null($this->_form("subuser$i"))) { + $additems[] = $this->_form["subuser$i" . "sn"]; + } + } + foreach ($additems as $item) { + unset($FORM); + $FORM = array(); + $FORM["form"] = "new"; + $FORM["grp"] = $this->_sn; + $FORM["member"] = $item; + $processor = new UserMembershipProcessor($FORM); + $processor->_save_cols(); + $this->_subs[] = $processor; + } + + $additems = array(); + for ($i = 0; !is_null($this->_form("subgroup$i" . "sn")); $i++) { + if (!is_null($this->_form("subgroup$i"))) { + $additems[] = $this->_form["subgroup$i" . "sn"]; + } + } + foreach ($additems as $item) { + unset($FORM); + $FORM = array(); + $FORM["form"] = "new"; + $FORM["grp"] = $this->_sn; + $FORM["member"] = $item; + $processor = new GroupMembershipProcessor($FORM); + $processor->_save_cols(); + $this->_subs[] = $processor; + } + + $additems = array(); + for ($i = 0; !is_null($this->_form("supgroup$i" . "sn")); $i++) { + if (!is_null($this->_form("supgroup$i"))) { + $additems[] = $this->_form["supgroup$i" . "sn"]; + } + } + foreach ($additems as $item) { + unset($FORM); + $FORM = array(); + $FORM["form"] = "new"; + $FORM["grp"] = $item; + $FORM["member"] = $this->_sn; + $processor = new GroupMembershipProcessor($FORM); + $processor->_save_cols(); + $this->_subs[] = $processor; + } + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + // Skip for a non-super-user editing a super-user group + if (!(!is_su() && $this->_sn == su_group_sn())) { + $this->_cols->addstr("id", $this->_form("id"), $this->_cur["id"]); + } + $this->_cols->addstr("dsc", $this->_form("dsc"), $this->_cur["dsc"]); + + // Find the changed items + $olditems = array(); + $newitems = array(); + // Skip for a non-super-user editing a super-user group + if (!(!is_su() && $this->_sn == su_group_sn())) { + for ($i = 0; array_key_exists("subuser$i" . "sn", $this->_cur); $i++) { + $olditems[] = $this->_cur["subuser$i" . "sn"]; + } + for ($i = 0; !is_null($this->_form("subuser$i" . "sn")); $i++) { + if (!is_null($this->_form("subuser$i"))) { + $newitems[] = $this->_form["subuser$i" . "sn"]; + } + } + } + $delitems = array_values(array_diff($olditems, $newitems)); + $additems = array_values(array_diff($newitems, $olditems)); + foreach ($additems as $item) { + unset($FORM); + $FORM = array(); + $FORM["form"] = "new"; + $FORM["grp"] = $this->_sn; + $FORM["member"] = $item; + $processor = new UserMembershipProcessor($FORM); + $processor->_save_cols(); + $this->_subs[] = $processor; + } + if (count($delitems) > 0) { + for ($i = 0; $i < count($delitems); $i++) { + $delitems[$i] = "member=" . $delitems[$i]; + } + $cond = implode(" OR ", $delitems); + if (count($delitems) > 1) { + $cond = "($cond)"; + } + unset($FORM); + $FORM = array(); + $FORM["cond"] = $cond . " AND grp=" . $this->_sn; + $this->_subs[] = new DeletionProcessor($FORM, "usermem"); + } + + $olditems = array(); + $newitems = array(); + // Skip for a non-super-user editing a super-user group + if (!(!is_su() && $this->_sn == su_group_sn())) { + for ($i = 0; array_key_exists("subgroup$i" . "sn", $this->_cur); $i++) { + $olditems[] = $this->_cur["subgroup$i" . "sn"]; + } + for ($i = 0; !is_null($this->_form("subgroup$i" . "sn")); $i++) { + if (!is_null($this->_form("subgroup$i"))) { + $newitems[] = $this->_form["subgroup$i" . "sn"]; + } + } + } + $delitems = array_values(array_diff($olditems, $newitems)); + $additems = array_values(array_diff($newitems, $olditems)); + foreach ($additems as $item) { + unset($FORM); + $FORM = array(); + $FORM["form"] = "new"; + $FORM["grp"] = $this->_sn; + $FORM["member"] = $item; + $processor = new GroupMembershipProcessor($FORM); + $processor->_save_cols(); + $this->_subs[] = $processor; + } + if (count($delitems) > 0) { + for ($i = 0; $i < count($delitems); $i++) { + $delitems[$i] = "member=" . $delitems[$i]; + } + $cond = implode(" OR ", $delitems); + if (count($delitems) > 1) { + $cond = "($cond)"; + } + unset($FORM); + $FORM = array(); + $FORM["cond"] = $cond . " AND grp=" . $this->_sn; + $this->_subs[] = new DeletionProcessor($FORM, "groupmem"); + } + + $olditems = array(); + $newitems = array(); + // Skip for a non-super-user editing a super-user group + if (!(!is_su() && $this->_sn == su_group_sn())) { + for ($i = 0; array_key_exists("supgroup$i" . "sn", $this->_cur); $i++) { + $olditems[] = $this->_cur["supgroup$i" . "sn"]; + } + for ($i = 0; !is_null($this->_form("supgroup$i" . "sn")); $i++) { + if (!is_null($this->_form("supgroup$i"))) { + $newitems[] = $this->_form["supgroup$i" . "sn"]; + } + } + } + $delitems = array_values(array_diff($olditems, $newitems)); + $additems = array_values(array_diff($newitems, $olditems)); + foreach ($additems as $item) { + unset($FORM); + $FORM = array(); + $FORM["form"] = "new"; + $FORM["grp"] = $item; + $FORM["member"] = $this->_sn; + $processor = new GroupMembershipProcessor($FORM); + $processor->_save_cols(); + $this->_subs[] = $processor; + } + if (count($delitems) > 0) { + for ($i = 0; $i < count($delitems); $i++) { + $delitems[$i] = "grp=" . $delitems[$i]; + } + $cond = implode(" OR ", $delitems); + if (count($delitems) > 1) { + $cond = "($cond)"; + } + unset($FORM); + $FORM = array(); + $FORM["cond"] = $cond . " AND member=" . $this->_sn; + $this->_subs[] = new DeletionProcessor($FORM, "groupmem"); + } + break; + + // A form to delete a current item + case "del": + // Find the changed items + if ($this->_cur["subusercount"] > 0) { + unset($FORM); + $FORM = array(); + $FORM["cond"] = "grp=" . $this->_sn; + $this->_subs[] = new DeletionProcessor($FORM, "usermem"); + } + + if ($this->_cur["subgroupcount"] + $this->_cur["supgroupcount"] > 0) { + unset($FORM); + $FORM = array(); + $FORM["cond"] = "grp=" . $this->_sn . " OR member=" . $this->_sn; + $this->_subs[] = new DeletionProcessor($FORM, "groupmem"); + } + break; + } + return; + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + return gactlog("Create a group " . $this->_form["id"] + . " with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + return gactlog("Update the group " . $this->_form["id"] + . " with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + return gactlog("Delete the group " . $this->_cur["id"] + . " with s/n " . $this->_sn . "."); + } + } + + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This group was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This group has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This group has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This group has been successfully deleted."), + "isform"=>false); + } + } +} + +// UserMembershipProcessor: User membership form processor class +class UserMembershipProcessor extends BaseProcessor +{ + // __construct: Initialize the processor + function __construct(&$form, $table = "usermem") + { + parent::__construct($form, $table); + } + + // _save_cols: Save the column deposit + function _save_cols() + { + switch ($this->_type) { + // A form to create a new item + case "new": + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + $this->_cols->addnum("sn", $this->_sn); + $this->_cols->addnum("grp", $this->_form("grp")); + $this->_cols->addnum("member", $this->_form("member")); + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + $this->_cols->addnum("grp", $this->_form("grp"), $this->_cur["grp"]); + $this->_cols->addnum("member", $this->_form("member"), $this->_cur["member"]); + break; + } + return; + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + return gactlog("Create a user membership record " . userid($this->_form["member"]) + . " in group " . groupid($this->_form["grp"]) + . " with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + return gactlog("Update the user membership record " . userid($this->_form["member"]) + . " in group " . groupid($this->_form["grp"]) + . " with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + return gactlog("Delete the user membership record " . userid($this->_cur["member"]) + . " in group " . groupid($this->_cur["grp"]) + . " with s/n " . $this->_sn . "."); + } + } + + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This membership record was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This membership record has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This membership record has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This membership record has been successfully deleted."), + "isform"=>false); + } + } +} + +// GroupMembershipProcessor Group membership form processor class +class GroupMembershipProcessor extends BaseProcessor +{ + // __construct: Initialize the processor + function __construct(&$form, $table = "groupmem") + { + parent::__construct($form, $table); + } + + // _save_cols: Save the column deposit + function _save_cols() + { + switch ($this->_type) { + // A form to create a new item + case "new": + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + $this->_cols->addnum("sn", $this->_sn); + $this->_cols->addnum("grp", $this->_form("grp")); + $this->_cols->addnum("member", $this->_form("member")); + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + $this->_cols->addnum("grp", $this->_form("grp"), $this->_cur["grp"]); + $this->_cols->addnum("member", $this->_form("member"), $this->_cur["member"]); + break; + } + return; + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + return gactlog("Create a group membership record " . groupid($this->_form["member"]) + . " in group " . groupid($this->_form["grp"]) + . " with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + return gactlog("Update the group membership record " . groupid($this->_form["member"]) + . " in group " . groupid($this->_form["grp"]) + . " with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + return gactlog("Delete the group membership record " . groupid($this->_cur["member"]) + . " in group " . groupid($this->_cur["grp"]) + . " with s/n " . $this->_sn . "."); + } + } + + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This membership record was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This membership record has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This membership record has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This membership record has been successfully deleted."), + "isform"=>false); + } + } +} + +// ScriptPrivilegeProcessor: Script privilege form processor class +class ScriptPrivilegeProcessor extends BaseProcessor +{ + // __construct: Initialize the processor + function __construct(&$form, $table = "scptpriv") + { + parent::__construct($form, $table); + } + + // _save_cols: Save the column deposit + function _save_cols() + { + switch ($this->_type) { + // A form to create a new item + case "new": + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + $this->_cols->addnum("sn", $this->_sn); + $this->_cols->addstr("script", $this->_form("script")); + $this->_cols->addnum("grp", $this->_form("grp")); + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + $this->_cols->addstr("script", $this->_form("script"), $this->_cur["script"]); + $this->_cols->addnum("grp", $this->_form("grp"), $this->_cur["grp"]); + break; + } + return; + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + return gactlog("Create a script privilege record " . $this->_form["script"] + . " for group " . groupid($this->_form["grp"]) + . " with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + return gactlog("Update the script privilege record " . $this->_form["script"] + . " for group " . groupid($this->_form["grp"]) + . " with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + return gactlog("Delete the script privilege record " . $this->_cur["script"] + . " for group " . groupid($this->_cur["grp"]) + . " with s/n " . $this->_sn . "."); + } + } + + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This script privilege record was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This script privilege record has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This script privilege record has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This script privilege record has been successfully deleted."), + "isform"=>false); + } + } +} + +// UserPreferenceProcessor: User preference form processor class +class UserPreferenceProcessor extends BaseProcessor +{ + // __construct: Initialize the processor + function __construct(&$form, $table = "userpref") + { + parent::__construct($form, $table); + } + + // _save_cols: Save the column deposit + function _save_cols() + { + if ($this->_type != "del") { + // Set the "everyone" user + if ( !is_null($this->_form("everyone")) + && $this->_form["everyone"] == "true") { + unset($this->_form["usr"]); + } + // Set the "everywhere" domain + if ( !is_null($this->_form("everywhere")) + && $this->_form["everywhere"] == "true") { + unset($this->_form["domain"]); + } + } + switch ($this->_type) { + // A form to create a new item + case "new": + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + $this->_cols->addnum("sn", $this->_sn); + $this->_cols->addnum("usr", $this->_form("usr")); + $this->_cols->addstr("domain", $this->_form("domain")); + $this->_cols->addstr("name", $this->_form("name")); + $this->_cols->addstr_empty("value", $this->_form("value")); + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + $this->_cols->addnum("usr", $this->_form("usr"), $this->_cur["usr"]); + $this->_cols->addstr("domain", $this->_form("domain"), $this->_cur["domain"]); + $this->_cols->addstr("name", $this->_form("name"), $this->_cur["name"]); + $this->_cols->addstr_empty("value", $this->_form("value"), $this->_cur["value"]); + break; + } + return; + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + if ( !is_null($this->_form("everyone")) + && $this->_form["everyone"] == "true") { + $user = "everyone"; + } elseif (is_null($this->_form("usr"))) { + $user = "everyone"; + } else { + $user = userid($this->_form["usr"]); + } + if ( !is_null($this->_form("everywhere")) + && $this->_form["everywhere"] == "true") { + $domain = "everywhere"; + } elseif (is_null($this->_form("domain"))) { + $domain = "everywhere"; + } else { + $domain = $this->_form["domain"]; + } + return gactlog("Create a user preference \"" . $this->_form["name"] . "\"" + . " of $user for $domain" + . " with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + if ( !is_null($this->_form("everyone")) + && $this->_form["everyone"] == "true") { + $user = "everyone"; + } elseif (is_null($this->_form("usr"))) { + $user = "everyone"; + } else { + $user = userid($this->_form["usr"]); + } + if ( !is_null($this->_form("everywhere")) + && $this->_form["everywhere"] == "true") { + $domain = "everywhere"; + } elseif (is_null($this->_form("domain"))) { + $domain = "everywhere"; + } else { + $domain = $this->_form["domain"]; + } + return gactlog("Update the user preference \"" . $this->_form["name"] . "\"" + . " of $user for $domain" + . " with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + $user = !is_null($this->_cur["usr"])? + userid($this->_cur["usr"]): "everyone"; + $domain = !is_null($this->_cur["domain"])? + $this->_cur["domain"]: "everywhere"; + return gactlog("Delete the user preference \"" . $this->_cur["name"] . "\"" + . " of $user for $domain" + . " with s/n " . $this->_sn . "."); + } + } + + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This user preference was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This user preference has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This user preference has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This user preference has been successfully deleted."), + "isform"=>false); + } + } +} + +// UserRequestProcessor: User request form processor class +class UserRequestProcessor extends BaseProcessor +{ + public $_expire_is_expr = false; + + // __construct: Initialize the processor + function __construct(&$form, $table = "userreq") + { + parent::__construct($form, $table); + } + + // _save_cols: Save the column deposit + function _save_cols() + { + if ($this->_type != "del") { + // Set the "anonymous" user + if ( !is_null($this->_form("anonymous")) + && $this->_form["anonymous"] == "true") { + unset($this->_form["usr"]); + } + } + switch ($this->_type) { + // A form to create a new item + case "new": + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + // Anonymous user joining the member + if ( is_null(get_login_sn()) + && in_array($this->_form["type"], array("join", "rstpwd"))) { + $this->_cols->login = usersn(ANONYMOUS_USER); + } + $this->_cols->addnum("sn", $this->_sn); + $this->_cols->addstr("type", $this->_form("type")); + $this->_cols->addnum("usr", $this->_form("usr")); + $this->_cols->addstr("args", $this->_form("args")); + if ($this->_expire_is_expr) { + $this->_cols->addexpr("expire", $this->_form("expire")); + } else { + $this->_cols->adddate("expire", $this->_form("expire")); + } + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + $this->_cols->addstr("type", $this->_form("type"), $this->_cur["type"]); + $this->_cols->addnum("usr", $this->_form("usr"), $this->_cur["usr"]); + $this->_cols->addstr("args", $this->_form("args"), $this->_cur["args"]); + if ($this->_expire_is_expr) { + $this->_cols->addexpr("expire", $this->_form("expire")); + } else { + $this->_cols->adddate("expire", $this->_form("expire"), $this->_cur["expire"]); + } + break; + } + return; + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + if ( !is_null($this->_form("anonymous")) + && $this->_form["anonymous"] == "true") { + $user = "anonymous"; + } elseif (is_null($this->_form("usr"))) { + $user = "anonymous"; + } else { + $user = userid($this->_form["usr"]); + } + return gactlog("Create a user request " . $this->_form["type"] + . " from $user" + . " with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + if ( !is_null($this->_form("anonymous")) + && $this->_form["anonymous"] == "true") { + $user = "anonymous"; + } elseif (is_null($this->_form("usr"))) { + $user = "anonymous"; + } else { + $user = userid($this->_form["usr"]); + } + return gactlog("Update the user request " . $this->_form["type"] + . " from $user" + . " with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + $user = !is_null($this->_cur["usr"])? + userid($this->_cur["usr"]): "anonymous"; + return gactlog("Delete the user request " . $this->_cur["type"] + . " from $user" + . " with s/n " . $this->_sn . "."); + } + } + + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This user request was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This user request has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This user request has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This user request has been successfully deleted."), + "isform"=>false); + } + } +} + +// BasePageProcessor: Base page form processor class +class BasePageProcessor extends BaseProcessor +{ + // __construct: Initialize the processor + function __construct(&$form, $table = "pages") + { + parent::__construct($form, $table); + } + + // _save_cols: Save the column deposit + function _save_cols() + { + // Get the available languages list + global $ALL_LINGUAS; + // Obtain the picture deposit + $PICS =& pic_deposit(); + switch ($this->_type) { + // A form to create a new item + case "new": + // Set the picture information + if (!is_null($this->_form("pic"))) { + $picratio = $PICS[$this->_form("pic")]["ratio"]; + $piccap = $this->_form("piccap"); + $picpos = $this->_form("picpos"); + } else { + $picratio = null; + $piccap = null; + $picpos = null; + } + + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + $this->_cols->addnum("sn", $this->_sn); + $this->_cols->addstr("path", $this->_form("path")); + $this->_cols->addnum("ord", $this->_form("ord")); + $this->_cols->addstr("title", $this->_form("title")); + $this->_cols->addstr("body", $this->_form("body")); + $this->_cols->addstr("kw", $this->_form("kw")); + $this->_cols->addpic("pic", $this->_form("pic")); + $this->_cols->addnum("picratio", $picratio); + $this->_cols->addstr("piccap", $piccap); + $this->_cols->addstr("picpos", $picpos); + $this->_cols->addbool("html", $this->_form("html")); + $this->_cols->addbool("hid", $this->_form("hid")); + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + $this->_cols->addstr("path", $this->_form("path"), $this->_cur["path"]); + $this->_cols->addnum("ord", $this->_form("ord"), $this->_cur["ord"]); + $this->_cols->addstr("title", $this->_form("title"), $this->_cur["title"]); + $this->_cols->addstr("body", $this->_form("body"), $this->_cur["body"]); + $this->_cols->addstr("kw", $this->_form("kw"), $this->_cur["kw"]); + // Special rules to update the picture + $this->_cols->addpic("pic", $this->_form("pic"), $this->_cur["pic"]); + // Delete everything about this picture + if (is_null($this->_form("pic"))) { + $this->_cols->addstr("picratio", null, $this->_cur["picratio"]); + if (count($ALL_LINGUAS) > 1) { + for ($l = 0; $l < count($ALL_LINGUAS); $l++) { + $lndb = ln($ALL_LINGUAS[$l], LN_DATABASE); + $this->_cols->addstr("piccap_$lndb", null, $this->_cur["piccap_$lndb"]); + } + } else { + $this->_cols->addstr("piccap", null, $this->_cur["piccap"]); + } + $this->_cols->addstr("picpos", null, $this->_cur["picpos"]); + // Normal processing + } else { + $picratio = $PICS[$this->_form("pic")]["ratio"]; + $this->_cols->addnum("picratio", $picratio, $this->_cur["picratio"]); + $this->_cols->addstr("piccap", $this->_form("piccap"), $this->_cur["piccap"]); + $this->_cols->addstr("picpos", $this->_form("picpos"), $this->_cur["picpos"]); + } + $this->_cols->addbool("html", $this->_form("html"), $this->_cur["html"]); + $this->_cols->addbool("hid", $this->_form("hid"), $this->_cur["hid"]); + break; + } + return; + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + return gactlog("Create a page at " . $this->_form["path"] + . " with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + return gactlog("Update the page at " . $this->_form["path"] + . " with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + return gactlog("Delete the page at " . $this->_cur["path"] + . " with s/n " . $this->_sn . "."); + } + } + + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This page was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This page has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This page has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This page has been successfully deleted."), + "isform"=>false); + } + } + + // _remove_curfile: Remove the unwanted pages + // This has to be explicitly run from _rebuild_partial_pages() + function _remove_curfile() + { + // Nothing to remove if there is no current page + if ($this->_type == "new" || $this->_cur["hid"]) { + return; + // A current page to be deleted or hidden + } elseif ( $this->_type == "del" + || !is_null($this->_form("hid"))) { + grmoldpage($this->_cur["path"]); + // A shown page update with a new page path to check with + } else { + grmoldpage($this->_cur["path"], $this->_form["path"]); + } + return; + } + + // _remove_curpic: Remove the unwanted picture + // This has to be explicitly run from _rebuild_partial_pages() + function _remove_curpic() + { + // Nothing to remove if there is no current picture + if ( $this->_type == "new" + || $this->_cur["hid"] + || is_null($this->_cur["pic"])) { + return; + } + + $pathpat = DOC_ROOT . PAGEPIC_PATH . "/" . $this->_sn . ".%s"; + // A current picture to be deleted, hidden or removed + if ( $this->_type == "del" + || !is_null($this->_form("hid")) + || !array_key_exists("pic", $this->_form)) { + foreach ($GLOBALS["PIC_VALID_SUFS"] as $suf) { + $file = sprintf($pathpat, $suf); + if (file_exists($file)) { + gunlink($file); + } + } + + // A shown picture update + } else { + $PICS =& pic_deposit(); + $curpic =& $PICS[$this->_cur["pic"]]; + $curpic =& resize_pic($curpic, $curpic["ratio"]); + $newpic =& $PICS[$this->_form["pic"]]; + $newpic =& resize_pic($newpic, $newpic["ratio"]); + // Skip when having the same type (and hence file name suffix) + if ($curpic["type"] == $newpic["type"]) { + return; + } + $newfile = sprintf($pathpat, + $GLOBALS["PIC_TYPESUF_MAP"][$newpic["type"]]); + foreach ($GLOBALS["PIC_VALID_SUFS"] as $suf) { + $file = sprintf($pathpat, $suf); + if (file_exists($file) && $file != $newfile) { + gunlink($file); + } + } + } + return; + } +} + +// BaseNewsProcessor: Base news form processor class +class BaseNewsProcessor extends BaseProcessor +{ + // __construct: Initialize the processor + function __construct(&$form, $table = "news") + { + parent::__construct($form, $table); + } + + // _save_cols: Save the column deposit + function _save_cols() + { + // Get the available languages list + global $ALL_LINGUAS; + // Obtain the picture deposit + $PICS =& pic_deposit(); + switch ($this->_type) { + // A form to create a new item + case "new": + // Set the picture information + if (!is_null($this->_form("pic"))) { + $picratio = $PICS[$this->_form("pic")]["ratio"]; + $piccap = $this->_form("piccap"); + $picpos = $this->_form("picpos"); + } else { + $picratio = null; + $piccap = null; + $picpos = null; + } + + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + $this->_cols->addnum("sn", $this->_sn); + $this->_cols->adddate("date", $this->_form("date")); + $this->_cols->addnum("ord", $this->_form("ord")); + $this->_cols->addstr("title", $this->_form("title")); + $this->_cols->addstr("body", $this->_form("body")); + $this->_cols->addstr("kw", $this->_form("kw")); + $this->_cols->addpic("pic", $this->_form("pic")); + $this->_cols->addnum("picratio", $picratio); + $this->_cols->addstr("piccap", $piccap); + $this->_cols->addstr("picpos", $picpos); + $this->_cols->addbool("html", $this->_form("html")); + $this->_cols->addbool("hid", $this->_form("hid")); + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + $this->_cols->adddate("date", $this->_form("date"), $this->_cur["date"]); + $this->_cols->addnum("ord", $this->_form("ord"), $this->_cur["ord"]); + $this->_cols->addstr("title", $this->_form("title"), $this->_cur["title"]); + $this->_cols->addstr("body", $this->_form("body"), $this->_cur["body"]); + $this->_cols->addstr("kw", $this->_form("kw"), $this->_cur["kw"]); + // Special rules to update the picture + $this->_cols->addpic("pic", $this->_form("pic"), $this->_cur["pic"]); + // Delete everything about this picture + if (is_null($this->_form("pic"))) { + $this->_cols->addstr("picratio", null, $this->_cur["picratio"]); + if (count($ALL_LINGUAS) > 1) { + for ($l = 0; $l < count($ALL_LINGUAS); $l++) { + $lndb = ln($ALL_LINGUAS[$l], LN_DATABASE); + $this->_cols->addstr("piccap_$lndb", null, $this->_cur["piccap_$lndb"]); + } + } else { + $this->_cols->addstr("piccap", null, $this->_cur["piccap"]); + } + $this->_cols->addstr("picpos", null, $this->_cur["picpos"]); + // Normal processing + } else { + $picratio = $PICS[$this->_form("pic")]["ratio"]; + $this->_cols->addnum("picratio", $picratio, $this->_cur["picratio"]); + $this->_cols->addstr("piccap", $this->_form("piccap"), $this->_cur["piccap"]); + $this->_cols->addstr("picpos", $this->_form("picpos"), $this->_cur["picpos"]); + } + $this->_cols->addbool("html", $this->_form("html"), $this->_cur["html"]); + $this->_cols->addbool("hid", $this->_form("hid"), $this->_cur["hid"]); + break; + } + return; + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + return gactlog("Create a news article " . newsid_compose($this->_form["date"], $this->_form["ord"]) + . " with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + return gactlog("Update the news article " . newsid_compose($this->_form["date"], $this->_form["ord"]) + . " with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + return gactlog("Delete the news article " . newsid_compose($this->_cur["date"], $this->_cur["ord"]) + . " with s/n " . $this->_sn . "."); + } + } + + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This news article was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This news article has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This news article has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This news article has been successfully deleted."), + "isform"=>false); + } + } + + // _remove_curpic: Remove the unwanted picture + // This has to be explicitly run from _rebuild_partial_pages() + function _remove_curpic() + { + // Nothing to remove if there is no current picture + if ( $this->_type == "new" + || $this->_cur["hid"] + || is_null($this->_cur["pic"])) { + return; + } + + $pathpat = DOC_ROOT . NEWSPIC_PATH . "/" . $this->_sn . ".%s"; + // A current picture to be deleted, hidden or removed + if ( $this->_type == "del" + || !is_null($this->_form("hid")) + || is_null($this->_form("pic"))) { + foreach ($GLOBALS["PIC_VALID_SUFS"] as $suf) { + $file = sprintf($pathpat, $suf); + if (file_exists($file)) { + gunlink($file); + } + } + + // A shown picture update + } else { + $PICS =& pic_deposit(); + $curpic =& $PICS[$this->_cur["pic"]]; + $curpic =& resize_pic($curpic, $curpic["ratio"]); + $newpic =& $PICS[$this->_form["pic"]]; + $newpic =& resize_pic($newpic, $newpic["ratio"]); + // Skip when having the same type (and hence file name suffix) + if ($curpic["type"] == $newpic["type"]) { + return; + } + $newfile = sprintf($pathpat, + $GLOBALS["PIC_TYPESUF_MAP"][$newpic["type"]]); + foreach ($GLOBALS["PIC_VALID_SUFS"] as $suf) { + $file = sprintf($pathpat, $suf); + if (file_exists($file) && $file != $newfile) { + gunlink($file); + } + } + } + return; + } +} + +// CountryProcessor: Country form processor class +class CountryProcessor extends BaseProcessor +{ + // __construct: Initialize the processor + function __construct(&$form, $table = "country") + { + parent::__construct($form, $table); + } + + // _save_cols: Save the column deposit + function _save_cols() + { + switch ($this->_type) { + // A form to create a new item + case "new": + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + $this->_cols->addnum("sn", $this->_sn); + $this->_cols->addstr("id", $this->_form("id")); + $this->_cols->addstr("name", $this->_form("name")); + $this->_cols->addbool("special", $this->_form("special")); + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + $this->_cols->addstr("id", $this->_form("id"), $this->_cur["id"]); + $this->_cols->addstr("name", $this->_form("name"), $this->_cur["name"]); + $this->_cols->addbool("special", $this->_form("special"), $this->_cur["special"]); + break; + } + return; + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + return gactlog("Create a country " . $this->_form["id"] + . " with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + return gactlog("Update the country " . $this->_form["id"] + . " with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + return gactlog("Delete the country " . $this->_cur["id"] + . " with s/n " . $this->_sn . "."); + } + } + + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This country was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This country has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This country has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This country has been successfully deleted."), + "isform"=>false); + } + } +} + +// PictureProcessor: Picture form processor class +class PictureProcessor extends BaseProcessor +{ + // __construct: Initialize the processor + function __construct(&$form, $table = null) + { + parent::__construct($form, $table); + $this->_modified = true; + } + + // _other_tasks: Perform tasks other than column updates + function _other_tasks() + { + // Obtain the picture deposit + $PICS =& pic_deposit(); + switch ($this->_type) { + // A form to create a new item + case "new": + $PICS[$this->_form["pic"]]["ratio"] = $this->_form("ratio"); + $PICS[$this->_form["pic"]]["ratio_input"] = + number_format($this->_form["ratio"], 2); + + $cols = array(); + // Add the columns + $selurl = $this->_form["caller"]; + $cols[] = "formid=" . urlencode($this->_form["cformid"]); + $cols[] = "selsn=" . urlencode($this->_form["pic"]); + $url = $this->_form["caller"] . "?" . implode("&", $cols); + http_303($url); + // No return + + // A form to edit a current item + case "cur": + $PICS[$this->_form["pic"]]["ratio"] = $this->_form("ratio"); + $PICS[$this->_form["pic"]]["ratio_input"] = + number_format($this->_form["ratio"], 2); + + $cols = array(); + // Add the columns + $selurl = $this->_form["caller"]; + $cols[] = "formid=" . urlencode($this->_form["cformid"]); + $cols[] = "selsn=" . urlencode($this->_form["pic"]); + $url = $this->_form["caller"] . "?" . implode("&", $cols); + http_303($url); + // No return + } + } +} + +// RebuildProcessor: Rebuild form processor class +class RebuildProcessor extends BaseProcessor +{ + protected $_t_start = null; + protected $_t_end = null; + + // __construct: Initialize the processor + function __construct(&$form, $table = null) + { + parent::__construct($form, $table); + $this->_modified = true; + } + + // _other_tasks: Perform tasks other than column updates + function _other_tasks() + { + // Rebuild the pages + $this->_t_start = time_hires(); + call_user_func("rebuild_" . $this->_form["type"]); + $this->_t_end = time_hires(); + } + + // _actlog: Log the activity + function _actlog() + { + return gactlog("Rebuild pages of type \"" . $this->_form["type"] . "\"."); + } + + // _ret_status: Return the process status + function _ret_status() + { + return array("msg"=>NC_("The specified web pages have been successfully rebuilt. (%0.3f seconds)"), + "margs"=>array($this->_t_end-$this->_t_start)); + } +} + +// LogInProcessor: Log in form processor class +class LogInProcessor extends BaseProcessor +{ + // __construct: Initialize the processor + function __construct(&$form, $table = "users") + { + $form["form"] = "cur"; + parent::__construct($form, $table); + $this->_sn = $this->_cur["sn"]; + $this->_update_timestamp = false; + } + + // _save_cols: Save the column deposit + function _save_cols() + { + // Look up the host name + $host = gethostbyaddr($_SERVER["REMOTE_ADDR"]); + if ($host == $_SERVER["REMOTE_ADDR"]) { + $host = null; + } + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + // Add the visits count + $this->_cols->addexpr("visits", "visits+1"); + // Record the timestamp and the remote IP + $this->_cols->addexpr("visited", "now()"); + $this->_cols->addstr("ip", $_SERVER["REMOTE_ADDR"], $this->_cur["ip"]); + $this->_cols->addstr("host", $host, $this->_cur["host"]); + $this->_cols->addstr("ct", geoiplookup(), $this->_cur["ct"]); + // Reset the fail login count + $this->_cols->addnum("fails", 0); + return; + } + + // _other_tasks: Perform tasks other than column updates + function _other_tasks() + { + // Register the logged-in id + $_SESSION["usersn"] = $this->_sn; + // Set the log-in information + upd_login_info(); + // Remember the user + $_SESSION["remember"] = !is_null($this->_form("remember")); + // Reset the by-login data deposit + unset($_SESSION["bylogin"]); + } + + // _actlog: Log the activity + function _actlog() + { + // Log the guest log in, too + return actlog("Log in with s/n " . $this->_sn . "."); + } + + // _ret_status: Return the process status + function _ret_status() + { + return array("msg"=>NC_("Welcome, %s!"), + "margs"=>array("_USERNAME"), + "isform"=>false); + } +} + +// LogOutProcessor: Log out form processor class +class LogOutProcessor extends BaseProcessor +{ + protected $_is_admin = null; + protected $_userid = null; + + // __construct: Initialize the processor + function __construct(&$form, $table = null) + { + parent::__construct($form, $table); + $this->_sn = get_login_sn(); + $this->_is_sql = false; + $this->_modified = true; + $this->_is_admin = is_guest()? is_admin_script(): is_admin(); + } + + // _save_cols: Save the column deposit + // Make it a null function + function _save_cols() + { + return; + } + + // _other_tasks: Perform tasks other than column updates + function _other_tasks() + { + $this->_userid = get_login_id(); + logout(); + } + + // _actlog: Log the activity + function _actlog() + { + // Log the guest log out, too + return actlog("Log out with s/n " . $this->_sn . ".", $this->_userid); + } + + // _ret_status: Return the process status + function _ret_status() + { + return array("msg"=>NC_("You have successfully logged out."), + "isform"=>false, + "is_admin"=>$this->_is_admin); + } +} + +// BaseLinkCategoryProcessor: Base link category form processor class +class BaseLinkCategoryProcessor extends BaseCategoryProcessor +{ + // __construct: Initialize the processor + function __construct(&$form, $table = "linkcat") + { + parent::__construct($form, $table); + } + + // _save_cols: Save the column deposit + function _save_cols() + { + if ($this->_type != "del") { + // Set the "topmost" parent + if ( !is_null($this->_form("topmost")) + && $this->_form["topmost"] == "true") { + unset($this->_form["parent"]); + } + } + switch ($this->_type) { + // A form to create a new item + case "new": + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + $this->_cols->addnum("sn", $this->_sn); + $this->_cols->addnum("parent", $this->_form("parent")); + $this->_cols->addstr("id", $this->_form("id")); + $this->_cols->addnum("ord", $this->_form("ord")); + $this->_cols->addstr("title", $this->_form("title")); + $this->_cols->addstr("kw", $this->_form("kw")); + $this->_cols->addbool("hid", $this->_form("hid")); + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + $this->_cols->addnum("parent", $this->_form("parent"), $this->_cur["parent"]); + $this->_cols->addstr("id", $this->_form("id"), $this->_cur["id"]); + $this->_cols->addnum("ord", $this->_form("ord"), $this->_cur["ord"]); + $this->_cols->addstr("title", $this->_form("title"), $this->_cur["title"]); + $this->_cols->addstr("kw", $this->_form("kw"), $this->_cur["kw"]); + $this->_cols->addbool("hid", $this->_form("hid"), $this->_cur["hid"]); + break; + } + return; + } + + // _update_cols: Update the columns + function _update_cols() + { + $this->_curshown = $this->_shown_parts(); + parent::_update_cols(); + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + return gactlog("Create a link category " . linkcat_path($this->_sn) + . " with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + return gactlog("Update the link category " . linkcat_path($this->_sn) + . " with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + return gactlog("Delete the link category " . $this->_cur["path"] + . " with s/n " . $this->_sn . "."); + } + } + + // _remove_curfile: Remove the unwanted page + function _remove_curfile() + { + // Remove the unwanted category files + foreach (array_diff($this->_curshown["catspath"], $this->_newshown["catspath"]) as $page) { + grmoldpage("/links$page"); + } + return; + } + + // _shown_parts: Obtain the shown parts + function _shown_parts() + { + $shown = links_shown_parts(); + // Check if myself is shown + $select = "SELECT sn FROM linkcat" + . " WHERE sn=" . $this->_sn + . " AND linkcat_isshown(sn, hid, parent);\n"; + $result = sql_query($select); + $shown["self"] = (sql_num_rows($result) > 0); + return $shown; + } +} + +// BaseLinkProcessor: Base link form processor class +class BaseLinkProcessor extends BaseProcessor +{ + // __construct: Initialize the processor + function __construct(&$form, $table = "links") + { + parent::__construct($form, $table); + } + + // _save_cols: Save the column deposit + function _save_cols() + { + switch ($this->_type) { + // A form to create a new item + case "new": + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + $this->_cols->addnum("sn", $this->_sn); + $this->_cols->addstr("title", $this->_form("title")); + $this->_cols->addurl("url", $this->_form("url")); + $this->_cols->addstr("dsc", $this->_form("dsc")); + $this->_cols->addbool("hid", $this->_form("hid")); + + // Find the changed items + $additems = array(); + for ($i = 0; !is_null($this->_form("cat$i")); $i++) { + if ($this->_form["cat$i"] != "") { + $additems[] = $this->_form["cat$i"]; + } + } + foreach ($additems as $item) { + unset($FORM); + $FORM = array(); + $FORM["form"] = "new"; + $FORM["cat"] = $item; + $FORM["link"] = $this->_sn; + $processor = new BaseLinkCategorizationProcessor($FORM); + $processor->_save_cols(); + $this->_subs[] = $processor; + } + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + $this->_cols->addstr("title", $this->_form("title"), $this->_cur["title"]); + $this->_cols->addurl("url", $this->_form("url"), $this->_cur["url"]); + $this->_cols->addstr("dsc", $this->_form("dsc"), $this->_cur["dsc"]); + $this->_cols->addbool("hid", $this->_form("hid"), $this->_cur["hid"]); + + // Find the changed items + $olditems = array(); + $newitems = array(); + for ($i = 0; $i < $this->_cur["catcount"]; $i++) { + $olditems[] = $this->_cur["cat$i"]; + } + for ($i = 0; !is_null($this->_form("cat$i")); $i++) { + if ($this->_form["cat$i"] != "") { + $newitems[] = $this->_form["cat$i"]; + } + } + $delitems = array_values(array_diff($olditems, $newitems)); + $additems = array_values(array_diff($newitems, $olditems)); + foreach ($additems as $item) { + unset($FORM); + $FORM = array(); + $FORM["form"] = "new"; + $FORM["cat"] = $item; + $FORM["link"] = $this->_sn; + $processor = new BaseLinkCategorizationProcessor($FORM); + $processor->_save_cols(); + $this->_subs[] = $processor; + } + if (count($delitems) > 0) { + for ($i = 0; $i < count($delitems); $i++) { + $delitems[$i] = "cat=" . $delitems[$i]; + } + $cond = implode(" OR ", $delitems); + if (count($delitems) > 1) { + $cond = "($cond)"; + } + unset($FORM); + $FORM = array(); + $FORM["cond"] = $cond . " AND link=" . $this->_sn; + $this->_subs[] = new DeletionProcessor($FORM, "linkcatz"); + } + break; + + // A form to delete a current item + case "del": + // Find the changed items + if ($this->_cur["catcount"] > 0) { + unset($FORM); + $FORM = array(); + $FORM["cond"] = "link=" . $this->_sn; + $this->_subs[] = new DeletionProcessor($FORM, "linkcatz"); + } + break; + } + return; + } + + // _update_cols: Update the columns + function _update_cols() + { + $this->_curshown = $this->_shown_parts(); + parent::_update_cols(); + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + return gactlog("Create a related link " . $this->_form["url"] + . " with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + return gactlog("Update the related link " . $this->_form["url"] + . " with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + return gactlog("Delete the related link " . $this->_cur["url"] + . " with s/n " . $this->_sn . "."); + } + } + + // _ret_status: Return the process status + function _ret_status() + { + if (!$this->_modified()) { + return array("msg"=>NC_("This related link was not modified."), + "isform"=>false); + } + switch ($this->_type) { + // A form to create a new item + case "new": + return array("msg"=>NC_("This related link has been successfully added."), + "isform"=>false); + // A form to edit a current item + case "cur": + return array("msg"=>NC_("This related link has been successfully updated."), + "isform"=>false); + // A form to delete a current item + case "del": + return array("msg"=>NC_("This related link has been successfully deleted."), + "isform"=>false); + } + } + + // _remove_curfile: Remove the unwanted page + function _remove_curfile() + { + // Remove the unwanted category files + foreach (array_diff($this->_curshown["catspath"], $this->_newshown["catspath"]) as $page) { + grmoldpage("/links$page"); + } + return; + } + + // _shown_parts: Obtain the shown parts + function _shown_parts() + { + return links_shown_parts(); + } +} + +// BaseLinkCategorizationProcessor: Base link categorization form processor class +class BaseLinkCategorizationProcessor extends BaseCategorizationProcessor +{ + // __construct: Initialize the processor + function __construct(&$form, $table = "linkcatz") + { + parent::__construct($form, $table); + } + + // _save_cols: Save the column deposit + function _save_cols() + { + switch ($this->_type) { + // A form to create a new item + case "new": + $this->_sn = $this->_new_sn(); + $this->_cols = new AddCol($this->_table, ADDCOL_INSERT); + $this->_cols->addnum("sn", $this->_sn); + $this->_cols->addnum("cat", $this->_form("cat")); + $this->_cols->addnum("link", $this->_form("link")); + break; + + // A form to edit a current item + case "cur": + $this->_cols = new AddCol($this->_table, ADDCOL_UPDATE); + $this->_cols->addnum("cat", $this->_form("cat"), $this->_cur["cat"]); + $this->_cols->addnum("link", $this->_form("link"), $this->_cur["link"]); + break; + } + return; + } + + // _update_cols: Update the columns + function _update_cols() + { + $this->_curshown = $this->_shown_parts(); + parent::_update_cols(); + } + + // _actlog: Log the activity + function _actlog() + { + switch ($this->_type) { + // A form to create a new item + case "new": + return gactlog("Create a link categorization record " . link_url($this->_form["link"]) + . " in category " . linkcat_path($this->_form["cat"]) + . " with s/n " . $this->_sn . "."); + // A form to edit a current item + case "cur": + return gactlog("Update the link categorization record " . link_url($this->_form["link"]) + . " in category " . linkcat_path($this->_form["cat"]) + . " with s/n " . $this->_sn . "."); + // A form to delete a current item + case "del": + return gactlog("Delete the link categorization record " . link_url($this->_cur["link"]) + . " in category " . linkcat_path($this->_cur["cat"]) + . " with s/n " . $this->_sn . "."); + } + } + + // _remove_curfile: Remove the unwanted page + function _remove_curfile() + { + // Remove the unwanted category files + foreach (array_diff($this->_curshown["catspath"], $this->_newshown["catspath"]) as $page) { + grmoldpage("/links$page"); + } + return; + } + + // _shown_parts: Obtain the shown parts + function _shown_parts() + { + return links_shown_parts(); + } +} + +?> diff --git a/lib/php/monica/rel2abs.inc.php b/lib/php/monica/rel2abs.inc.php new file mode 100644 index 0000000..0d9966e --- /dev/null +++ b/lib/php/monica/rel2abs.inc.php @@ -0,0 +1,309 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Refer to RFC 1808 + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/parseurl.inc.php"; +require_once "monica/requri.inc.php"; + +// Settings +define("REL2ABS_SKIP_FRAGMENT", true); +define("REL2ABS_NO_HOST", true); +define("REL2ABS_RDIFF_KEEP", true); +define("REL2ABS_RDIFF_STRIP", false); + +// rel2abs: Conver a relative URL to an absolute URL +// Refer to RFC 1808 +function rel2abs($rel, $base = null, $skip_fragment = false, $no_host = false, $rdiff = true) +{ + // Keep the original. We may need to bounce intact later. + $rel_o = $rel; + // Make the base absolute first + if (!is_null($base)) { + $base = rel2abs($base); + // Default base to the current URL + } else { + $base = REQUEST_FULLURI; + } + // Skip the fragment + if (substr($rel, 0, 1) == "#" && $skip_fragment) { + return $rel; + } + // Return if it is completely empty (RFC 1808, 4, step 2, a) + if ($rel == "") { + return $base; + } + // Parse the URL first + $rel_a = parse_url_rfc1808($rel); + // Fail to parse - bounce intact + if (is_null($rel_a)) { + return $rel_o; + } + if ( !array_key_exists("net_loc", $rel_a) + && array_key_exists("path", $rel_a) + && substr($rel_a["path"], 0, 1) == "/" + && $rdiff) { + $rel_a["path"] = ROOT_DIFF . $rel_a["path"]; + } + $base_a = parse_url_rfc1808($base); + // Fail to parse - bounce intact + if (is_null($base_a)) { + return $rel_o; + } + if (!array_key_exists("path", $base_a)) { + $base_a["path"] = "/"; + } + if (!array_key_exists("scheme", $base_a)) { + $base_a["scheme"] = "http"; + } + // Return if it starts with a scheme (RFC 1808, 4, step 2, b) + if (array_key_exists("scheme", $rel_a)) { + return $rel; + } + // Inherit the scheme of the base URL (RFC 1808, 4, step 2, c) + $rel_a["scheme"] = $base_a["scheme"]; + $skip_to_7 = false; + // The net_loc is not empty (RFC 1808, 4, step 3) + if (array_key_exists("net_loc", $rel_a)) { + $skip_to_7 = true; + // Inherit the net_loc of the base URL (if any) + } else { + if (array_key_exists("net_loc", $base_a)) { + $rel_a["net_loc"] = $base_a["net_loc"]; + } + // The path is not relative (RFC 1808, 4, step 4) + if ( array_key_exists("path", $rel_a) + && substr($rel_a["path"], 0, 1) == "/") { + $skip_to_7 = true; + } else { + // The path is empty (RFC 1808, 4, step 5) + if (!array_key_exists("path", $rel_a)) { + $rel_a["path"] = $base_a["path"]; + // The params is not empty (RFC 1808, 4, step 5, a) + if (array_key_exists("params", $rel_a)) { + $skip_to_7 = true; + } else { + if (array_key_exists("params", $base_a)) { + $rel_a["params"] = $base_a["params"]; + } + // The query is not empty (RFC 1808, 4, step 5, b) + if (array_key_exists("query", $rel_a)) { + $skip_to_7 = true; + } else { + if (array_key_exists("query", $base_a)) { + $rel_a["query"] = $base_a["query"]; + } + $skip_to_7 = true; + } + } + } + } + } + // Resolve the path (RFC 1808, 4, step 6) + if (!$skip_to_7) { + $rel_a["path"] = preg_replace("/[^\/]+$/", "", $base_a["path"]) + . $rel_a["path"]; + $rel_a["path"] = stdpath($rel_a["path"]); + } + + // Compose the URL (RFC 1808, 4, step 7) + $abs = ""; + if (!$no_host) { + $abs .= $rel_a["scheme"] . ":"; + if (array_key_exists("net_loc", $rel_a)) { + $abs .= "//" . $rel_a["net_loc"]; + } + } + $abs .= $rel_a["path"]; + if (array_key_exists("params", $rel_a)) { + $abs .= ";" . $rel_a["params"]; + } + if (array_key_exists("query", $rel_a)) { + $abs .= "?" . $rel_a["query"]; + } + if (array_key_exists("fragment", $rel_a)) { + $abs .= "#" . $rel_a["fragment"]; + } + + return $abs; +} + +// abs2rel: Conver an absolute URL to a relative URL +function abs2rel($abs, $base = null) +{ + // Keep the original. We may need to bounce intact later. + $abs_o = $abs; + // Make the base absolute first + if (!is_null($base)) { + $base = rel2abs($base); + // Default base to the current URL + } else { + $base = REQUEST_FULLURI; + } + $abs = rel2abs($abs, $base); + // Parse the URL first + $abs_a = parse_url_rfc1808($abs); + // Fail to parse - bounce intact + if (is_null($abs_a)) { + return $abs_o; + } + if (!array_key_exists("path", $abs_a)) { + $abs_a["path"] = "/"; + } + $base_a = parse_url_rfc1808($base); + // Fail to parse - bounce intact + if (is_null($base_a)) { + return $abs_o; + } + // Return if not the same scheme + if ($abs_a["scheme"] != $base_a["scheme"]) { + return $abs; + } + unset($abs_a["scheme"]); + // Return if not the same network location (net_loc) + if ( !((!array_key_exists("net_loc", $abs_a) + && !array_key_exists("net_loc", $base_a)) + || (array_key_exists("net_loc", $abs_a) + && array_key_exists("net_loc", $base_a) + && $abs_a["net_loc"] == $base_a["net_loc"]))) { + return $abs; + } + unset($abs_a["net_loc"]); + if (!array_key_exists("path", $abs_a)) { + $abs_a["path"] = "/"; + } + // Different path -- find the path difference + if ($abs_a["path"] != $base_a["path"]) { + // Remove the last segment from the base URL + $base_path = preg_replace("/[^\/]+$/", "", $base_a["path"]); + $abs_path = $abs_a["path"]; + // Remove the leading absolute slash + $base_path = preg_replace("/^\//", "", $base_path); + $abs_path = preg_replace("/^\//", "", $abs_path); + // Check each path segment from the left + while (preg_match("/^([^\/]+\/)(.*)$/", $base_path, $m)) { + // Not sharing the same path segment + if (substr($abs_path, 0, strlen($m[1])) != $m[1]) { + break; + } + $base_path = $m[2]; + $abs_path = substr($abs_path, strlen($m[1])); + // Nothing left, but false is not what we want + if ($abs_path === false) { + $abs_path = ""; + break; + } + } + // Turn each remaining segment to ".." and prepend it to the path + $abs_a["path"] = preg_replace("/[^\/]+/", "..", $base_path) . $abs_path; + // Remove the trailing slash of the ancestor directories + if ( $abs_a["path"] == "../" + || preg_match("/\/\.\.\/$/", $abs_a["path"])) { + $abs_a["path"] = substr($abs_a["path"], 0, -1); + } + // Nothing left means the current directory + if ($abs_a["path"] == "") { + $abs_a["path"] = "."; + } + + // Same path + } else { + // Different params + if ( !((!array_key_exists("params", $abs_a) + && !array_key_exists("params", $base_a)) + || (array_key_exists("params", $abs_a) + && array_key_exists("params", $base_a) + && $abs_a["params"] == $base_a["params"]))) { + // No further checks + // Keep the last segment of the path + $abs_a["path"] = preg_replace("/^\/(?:[^\/]+\/)*/", "", $abs_a["path"]); + if ($abs_a["path"] == "") { + $abs_a["path"] = "."; + } + + // Same params + } else { + // Different query + if ( !((!array_key_exists("query", $abs_a) + && !array_key_exists("query", $base_a)) + || (array_key_exists("query", $abs_a) + && array_key_exists("query", $base_a) + && $abs_a["query"] == $base_a["query"]))) { + // No further checks + // Keep the last segment of the path + $abs_a["path"] = preg_replace("/^\/(?:[^\/]+\/)*/", "", $abs_a["path"]); + if ($abs_a["path"] == "") { + $abs_a["path"] = "."; + } + + // Same query + } else { + // Everything is the same (fragment not counted) + // Keep only the fragment if there is a fragment + if (array_key_exists("fragment", $abs_a)) { + unset($abs_a["path"]); + unset($abs_a["params"]); + unset($abs_a["query"]); + + // No fragment + } else { + // Keep the last segment of the path + $abs_a["path"] = preg_replace("/^\/(?:[^\/]+\/)*/", "", $abs_a["path"]); + if ($abs_a["path"] == "") { + $abs_a["path"] = "."; + } + } + } + } + } + + // Compose the URL + $rel = ""; + if (array_key_exists("path", $abs_a)) { + $rel .= $abs_a["path"]; + } + if (array_key_exists("params", $abs_a)) { + $rel .= ";" . $abs_a["params"]; + } + if (array_key_exists("query", $abs_a)) { + $rel .= "?" . $abs_a["query"]; + } + if (array_key_exists("fragment", $abs_a)) { + $rel .= "#" . $abs_a["fragment"]; + } + + return $rel; +} + +// stdpath: Standardize a path name +// Refer to RFC 1808, 4, step 6 +function stdpath($path) +{ + // Remove all the "./" (RFC 1808, 4, step 6, a) + $path = preg_replace("/(?<=\/)\.\//", "", $path); + $path = preg_replace("/^\.\//", "", $path); + // Remove the trailing "." (RFC 1808, 4, step 6, b) + $path = preg_replace("/(?<=\/)\.$/", "", $path); + // Remove all the "/../" (RFC 1808, 4, step 6, c) + while ( preg_match("/^(.*?)([^\/]+)\/\.\.\/(.*)$/", $path, $m) + && $m[2] != "..") { + $path = $m[1] . $m[3]; + } + // Remove the trailing "/.." (RFC 1808, 4, step 6, d) + while ( preg_match("/^(.*?)([^\/]+)\/\.\.$/", $path, $m) + && $m[2] != "..") { + $path = $m[1]; + } + return $path; +} + +?> diff --git a/lib/php/monica/request.inc.php b/lib/php/monica/request.inc.php new file mode 100644 index 0000000..cce37ec --- /dev/null +++ b/lib/php/monica/request.inc.php @@ -0,0 +1,139 @@ + +// Copyright: Copyright (C) 2006-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/callform.inc.php"; +require_once "monica/chkfunc.inc.php"; +require_once "monica/formfunc.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/guest.inc.php"; +require_once "monica/sql.inc.php"; + +// Settings +if (!defined("USER_REQ_EXPIRE")) { + define("USER_REQ_EXPIRE", 72); +} + +// fetch_curreq: Fetch the current request +function fetch_curreq() +{ + // The error status + static $error = null; + // Fetched before + if (array_key_exists("REQUEST", $GLOBALS)) { + return $error; + } + // Obtain the current form + $FORM =& curform(); + // No item specified + if (!array_key_exists("req", $FORM)) { + $error = array("msg"=>NC_("Please specify the request."), + "isform"=>false); + return $error; + } + $sn =& $FORM["req"]; + + // Find the record + if (!check_sn($sn)) { + $error = array("msg"=>NC_("Invalid request S/N: %s."), + "margs"=>array($FORM["req"]), + "isform"=>false); + return $error; + } + $cols = array(); + $select = "SELECT * FROM userreq WHERE sn=$sn;\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 1) { + $error = array("msg"=>NC_("Invalid request S/N: %s."), + "margs"=>array($FORM["req"]), + "isform"=>false); + return $error; + } + + $row = sql_fetch_assoc($result); + // Obtain the request arguments + $row["_args"] = $row["args"]; + parse_str($row["_args"], $row["args"]); + // Obtain the user information + if (!is_null($row["usr"])) { + $row["_usr"] = $row["usr"]; + $select = "SELECT * FROM users WHERE sn=" . $row["_usr"] . ";\n"; + $result = sql_query($select); + $row["usr"] = sql_fetch_assoc($result); + } + + // Local extension + if (function_exists("fetch_curreq_script")) { + $row = fetch_curreq_script($row); + } + $GLOBALS["REQUEST"] = $row; + is_form(true); + if ( !array_key_exists("step", curform()) + && array_key_exists("step", $row["args"])) { + form_step($row["args"]["step"]); + } + // OK + return null; +} + +// is_userreq: If a request is requested +function is_userreq($isreq = null) +{ + // Cache the result + static $cache; + // Use "isreq" to alter the cache + if (!is_null($isreq)) { + // A status is provided + if (is_array($isreq)) { + if (array_key_exists("isreq", $isreq)) { + $cache = $isreq["isreq"]; + settype($cache, "boolean"); + } + // A scalar value + } else { + $cache = $isreq; + settype($cache, "boolean"); + } + } + // Return the cache + if (isset($cache)) { + return $cache; + } + + // Obtain the current form + $FORM =& curform(); + // No valid form infomation + if (!array_key_exists("req", $FORM)) { + $cache = false; + return $cache; + } + // "isreq" was specified + $status =& retrieve_status(); + if (is_array($status) && array_key_exists("isreq", $status)) { + $cache = $status["isreq"]; + return $cache; + } + // Yes, we have a request here + $cache = true; + return $cache; +} + +// expire_userreq: Expire user requests +function expire_userreq() +{ + $delete = "DELETE FROM userreq" + . " WHERE expire IS NOT NULL" + . " AND expire diff --git a/lib/php/monica/requri.inc.php b/lib/php/monica/requri.inc.php new file mode 100644 index 0000000..509cc1e --- /dev/null +++ b/lib/php/monica/requri.inc.php @@ -0,0 +1,216 @@ + +// Copyright: Copyright (C) 2002-2008 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/cgiemu.inc.php"; +require_once "monica/https.inc.php"; +require_once "monica/parseurl.inc.php"; +require_once "monica/server.inc.php"; + +// Initialize it +if (!defined("REQUEST_URI")) { + _requri_init(); +} + +// _requri_init: Obtain the REQUEST_URI +function _requri_init() +{ + // Get the name of the script + // The last calling stack + $callers = debug_backtrace(); + define("THIS_FILE", basename($callers[count($callers)-1]["file"])); + + // Build the document root + // config.inc.php should always be put at /admin/lib/php/config.inc.php + if (defined("CONFIG_INC")) { + if (substr(CONFIG_INC, -29) == "/admin/lib/php/config.inc.php") { + define("DOC_ROOT", substr(CONFIG_INC, 0, -29)); + } + } + if (!defined("DOC_ROOT")) { + define("DOC_ROOT", $_SERVER["DOCUMENT_ROOT"]); + } + // Find the root difference + // Apache's implementation + if (is_apache()) { + // Both mod_php5 and CGI use SCRIPT_FILENAME now + $file = $_SERVER["SCRIPT_FILENAME"]; + // Microsoft IIS' implementation + } elseif (is_iis()) { + $file = $_SERVER["PATH_TRANSLATED"]; + } + if (isset($file)) { + $len = strlen(DOC_ROOT); + if (substr($file, 0, $len) == DOC_ROOT) { + $script = substr($file, $len); + } + } + if (isset($script)) { + $len = strlen($script); + // Both mod_php5 and CGI use SCRIPT_NAME now + $script_name = is_apache()? $_SERVER["SCRIPT_NAME"]: + $_SERVER["PATH_INFO"]; + if (substr($script_name, -$len) == $script) { + define("ROOT_DIFF", substr($script_name, 0, -$len)); + } elseif (substr($script_name, -($len-4)) . ".php" == $script) { + define("ROOT_DIFF", substr($script_name, 0, -($len-4))); + } + } + // Assume no root difference if that is not available + if (!defined("ROOT_DIFF")) { + define("ROOT_DIFF", ""); + } + + // Build the REQUEST_PATH first + // Apache REQUEST_URI exists. Use it for simplicity and accuracy. + if (array_key_exists("REQUEST_URI", $_SERVER)) { + define("REQUEST_URI", $_SERVER["REQUEST_URI"]); + // If $_SERVER["REQUEST_URI"] contains a ":" somewhere (in query, + // for example), PHP's parse_url() will treat it as a port seperator + // and make a wrong parse result. We prevent this by adding a dummy + // scheme and net_loc to avoid this kinds of mistakes. + if (substr(REQUEST_URI, 0, 1) == "/") { + $url = parse_url_rfc1808("http://somewhere" . REQUEST_URI); + unset($url["scheme"]); + unset($url["net_loc"]); + } else { + $url = parse_url_rfc1808(REQUEST_URI); + } + $path = array_key_exists("path", $url)? $url["path"]: "/"; + + // Construct the REQUEST_PATH from scratches + // Avoid it whenever possible, since its result is not always right, + // especially for directory indices, like index.php. + } else { + $path = $_SERVER["SCRIPT_NAME"]; + if ( !_requri_path_info_is_broken() + && array_key_exists("PATH_INFO", $_SERVER) + && $_SERVER["PATH_INFO"] != "") { + $path .= $_SERVER["PATH_INFO"]; + } + $url = array(); + } + $len = strlen(ROOT_DIFF); + define("REQUEST_PATH", $path == ""? "/": + (substr($path, 0, $len) == ROOT_DIFF? + substr($path, $len): $path)); + + // Set the REQUEST_FILE from REQUEST_PATH + $file = preg_replace("/^.*\//", "", REQUEST_PATH); + // Set to "." for directories, since we do not know what + // exact file name it should be + define("REQUEST_FILE", ($file == "")? ".": $file); + + // Construct the REQUEST_URI + // REQUEST_URI is raw. All arguments are kept. + if (!defined("REQUEST_URI")) { + define("REQUEST_URI", REQUEST_PATH + . ((array_key_exists("QUERY_STRING", $_SERVER) + && $_SERVER["QUERY_STRING"] != "")? + "?" . $_SERVER["QUERY_STRING"]: "")); + } + // Strip the unwanted arguments from the query string + $query = ""; + if ( array_key_exists("QUERY_STRING", $_SERVER) + && $_SERVER["QUERY_STRING"] != "") { + $query = _requri_clean_qs($_SERVER["QUERY_STRING"]); + } + // Construct the REQUEST_URI + define("REQUEST_FILEQS", REQUEST_FILE . $query); + + // Construct the REQUEST_FULLURI, with the scheme and the host name + define("REQUEST_SCHEME", array_key_exists("scheme", $url)? $url["scheme"]: + (is_https()? "https": "http")); + if ( array_key_exists("net_loc", $url)) { + $net_loc = $url["net_loc"]; + define("REQUEST_HOST", preg_replace("/:\d+$/", "", $net_loc)); + } else { + define("REQUEST_HOST", array_key_exists("HTTP_HOST", $_SERVER)? + preg_replace("/:\d+$/", "", $_SERVER["HTTP_HOST"]): + $_SERVER["SERVER_NAME"]); + $net_loc = REQUEST_HOST; + if (is_https()) { + if ($_SERVER["SERVER_PORT"] != 443) { + $net_loc .= ":" . $_SERVER["SERVER_PORT"]; + } + } else { + if ($_SERVER["SERVER_PORT"] != 80) { + $net_loc .= ":" . $_SERVER["SERVER_PORT"]; + } + } + } + define("REQUEST_HOSTPORT", REQUEST_SCHEME . "://$net_loc" . ROOT_DIFF); + define("REQUEST_HOSTPATH", REQUEST_HOSTPORT . REQUEST_PATH); + if (substr(REQUEST_URI, 0, 1) != "/") { + define("REQUEST_FULLURI", REQUEST_URI); + } else { + define("REQUEST_FULLURI", REQUEST_SCHEME . "://$net_loc" . REQUEST_URI); + } + + // Construct the cononical server name + if (!defined("CANONICAL_SERVER_NAME")) { + $host = (is_https()? "https": "http") . "://" + . preg_replace("/:\d+$/", "", $_SERVER["SERVER_NAME"]); + if (is_https()) { + if ($_SERVER["SERVER_PORT"] != 443) { + $host .= ":" . $_SERVER["SERVER_PORT"]; + } + } else { + if ($_SERVER["SERVER_PORT"] != 80) { + $host .= ":" . $_SERVER["SERVER_PORT"]; + } + } + define("CANONICAL_SERVER_NAME", $host); + } + + return; +} + +// _requri_clean_qs: Remove "lang" and session_name() from the query string +function _requri_clean_qs($qs) +{ + $args = explode("&", $qs); + for ($i = 0; $i < count($args); $i++) { + // Only check well-formed query strings + if (preg_match("/^([^=]*)=(.*)$/", $args[$i], $m)) { + $name = urldecode($m[1]); + $val = urldecode($m[2]); + switch ($name) { + case "lang": + case session_name(): + $args = array_merge( + array_slice($args, 0, $i), + array_slice($args, $i + 1) + ); + $i--; + break; + default: + $args[$i] = rawurlencode($name) . "=" . rawurlencode($val); + break; + } + } else { + $args[$i] = rawurlencode(urldecode($args[$i])); + } + } + if (count($args) == 0) { + return ""; + } + return "?" . implode("&", $args); +} + +// _requri_path_info_is_broken: If PATH_INFO is broken +function _requri_path_info_is_broken() +{ + // PATH_INFO is broken in Microsoft-IIS + return is_iis(); +} + +?> diff --git a/lib/php/monica/rfc1521.inc.php b/lib/php/monica/rfc1521.inc.php new file mode 100644 index 0000000..54da348 --- /dev/null +++ b/lib/php/monica/rfc1521.inc.php @@ -0,0 +1,29 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/rfc822.inc.php"; + +define("RFC1521_TSPECIALS", "[()<>@,;:\\\\\"\\/\\[\\]?=]"); +define("RFC1521_TOKEN", "[^()<>@,;:\\\\\"\\/\\[\\]?= \\x01-\\x1F\\x7F]"); + +define("RFC1521_ATTRIBUTE", RFC1521_TOKEN); +define("RFC1521_VALUE", "(?:" . RFC1521_TOKEN . "|" . RFC822_QUOTED_STR . ")"); +define("RFC1521_PARAMETER", RFC1521_ATTRIBUTE . "=" . RFC1521_VALUE); + +// rfc1521_value_need_quoting: Whether a value need to be quoted by RFC-1521 +function rfc1521_value_need_quoting($a) +{ + return preg_match("/[()<>@,;:\\\\\"\\/\\[\\]?= \\x01-\\x1F\\x7F]/", $a)? + true: false; +} + +?> diff --git a/lib/php/monica/rfc1738.inc.php b/lib/php/monica/rfc1738.inc.php new file mode 100644 index 0000000..86ffa63 --- /dev/null +++ b/lib/php/monica/rfc1738.inc.php @@ -0,0 +1,110 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/rfc822.inc.php"; +require_once "monica/html401.inc.php"; + +define("RFC1738_ALPHA", "[A-Za-z]"); +define("RFC1738_DIGIT", "\\d"); +define("RFC1738_DIGITS", "\\d+"); +define("RFC1738_HEX", "[\\dA-Fa-f]"); +define("RFC1738_ALPHADIGIT", "[A-Za-z\\d]"); +define("RFC1738_SAFE", "[$\\-_\\.+]"); +define("RFC1738_EXTRA", "[!*'(),]"); +define("RFC1738_ESCAPE", "%" . RFC1738_HEX . "{2}"); +define("RFC1738_RESERVED", "[;\\/?:@&=]"); +// Alpha, digit, safe, extra +define("RFC1738_UNRESERVED", "[A-Za-z\\d$\\-_\\.+!*'(),]"); +// Unreserved, reserved, escape +define("RFC1738_XCHAR", "(?:[A-Za-z\\d$\\-_\\.+!*'(),;\\/?:@&=]|" . RFC1738_ESCAPE . ")"); +define("RFC1738_UCHAR", "(?:" . RFC1738_UNRESERVED . "|" . RFC1738_ESCAPE . ")"); + +define("RFC1738_SCHEME", "[A-Za-z\\d+\\-\\.]+"); +define("RFC1738_DOMAINLABEL", "(?:" . RFC1738_ALPHADIGIT . "|" + . RFC1738_ALPHADIGIT . "(?:" . RFC1738_ALPHADIGIT . "|-)*" . RFC1738_ALPHADIGIT . ")"); +define("RFC1738_TOPLABEL", "(?:" . RFC1738_ALPHA . "(?:" . RFC1738_ALPHADIGIT . "|-)*" . RFC1738_ALPHADIGIT . "|" + . RFC1738_ALPHA . ")"); +define("RFC1738_HOSTNAME", "(?:" . RFC1738_DOMAINLABEL . "\\.)*" . RFC1738_TOPLABEL); +define("RFC1738_HOSTNUMBER", "\\d+\\.\\d+\\.\\d+\\.\\d+"); +define("RFC1738_HOST", "(?:" . RFC1738_HOSTNAME . "|" . RFC1738_HOSTNUMBER . ")"); +define("RFC1738_PORT", RFC1738_DIGITS); +define("RFC1738_USER", "(?:" . RFC1738_UCHAR . "|[;?&=])*"); +define("RFC1738_PASSWORD", "(?:" . RFC1738_UCHAR . "|[;?&=])*"); +define("RFC1738_HOSTPORT", RFC1738_HOST . "(?::" . RFC1738_PORT . ")?"); +define("RFC1738_LOGIN", "(?:" . RFC1738_USER . "(?::" . RFC1738_PASSWORD . ")?@)?" . RFC1738_HOSTPORT); + +// FTP, also section 3.2 +define("RFC1738_FTPTYPE", "[AIDaid]"); +define("RFC1738_FSEGMENT", "(?:" . RFC1738_UCHAR . "|[?:@&=])*"); +define("RFC1738_FPATH", RFC1738_FSEGMENT . "(?:\\/" . RFC1738_FSEGMENT . ")*"); +define("RFC1738_FTPURL", "[fF][tT][pP]:\\/\\/" . RFC1738_LOGIN . "(?:\\/" . RFC1738_FPATH . "(?:;type=" . RFC1738_FTPTYPE . ")?)?"); + +// FILE +define("RFC1738_FILEURL", "[fF][iI][lL][eE]:\\/\\/(?:" . RFC1738_HOST . "|localhost)?\\/" . RFC1738_FPATH); + +// HTTP, also section 3.3 +define("RFC1738_HSEGMENT", "(?:" . RFC1738_UCHAR . "|[;:@&=])*"); +define("RFC1738_SEARCH", "(?:" . RFC1738_UCHAR . "|[;:@&=])*"); +define("RFC1738_HPATH", RFC1738_HSEGMENT . "(?:\\/" . RFC1738_HSEGMENT . ")*"); +// hostport should be login +define("RFC1738_HTTPURL", "[hH][tT][tT][pP]:\\/\\/" . RFC1738_HOSTPORT . "(?:\\/" . RFC1738_HPATH . "(?:\\?" . RFC1738_SEARCH . ")?)?"); + +// Local fix to HTTP URL +// hsegment does not include the tide "~" character (users' home direcories). +// It is a common practice now. +define("RFC1738_LOCAL_HSEGMENT", "(?:" . RFC1738_UCHAR . "|[;:@&=~])*"); +// hostport should be login +define("RFC1738_LOCAL_HTTPURL", str_replace(RFC1738_HOSTPORT, RFC1738_LOGIN, + str_replace(RFC1738_HSEGMENT, RFC1738_LOCAL_HSEGMENT, RFC1738_HTTPURL)) + . "(?:#" . HTML401_ID . ")?"); +// HTTPS does not exist in RFC 1738 +define("RFC1738_LOCAL_HTTPSURL", str_replace("[hH][tT][tT][pP]:", "[hH][tT][tT][pP][sS]:", RFC1738_HTTPURL)); + +// GOPHER +define("RFC1738_GTYPE", RFC1738_XCHAR); +define("RFC1738_SELECTOR", RFC1738_XCHAR . "*"); +define("RFC1738_GOPHERP_STRING", RFC1738_XCHAR . "*"); +define("RFC1738_GOPHERURL", "[gG][oO][pP][hH][eE][rR]:\\/\\/" . RFC1738_HOSTPORT . "(?:\\/(?:" . RFC1738_GTYPE . "(?:" . RFC1738_SELECTOR . "(?:%09" . RFC1738_SEARCH . "(?:" . RFC1738_GOPHERP_STRING . ")?)?)?)?)?"); + +// MAILTO +define("RFC1738_MAILTOURL", "[mM][aA][iI][lL][tT][oO]:" . RFC822_ADDR_SPEC); + +// NEWS +define("RFC1738_GROUP", RFC1738_ALPHA . "[A-Za-z\\d\\-\\.+_]*"); +define("RFC1738_ARTICLE", "(?:" . RFC1738_UCHAR . "|[;\\/?:&=])+@" . RFC1738_HOST); +define("RFC1738_GROUPPART", "(?:\\*|" . RFC1738_GROUP . "|" . RFC1738_ARTICLE . ")"); +define("RFC1738_NEWSURL", "[nN][eE][wW][sS]:" . RFC1738_GROUPPART); + +// NNTP +define("RFC1738_NNTPURL", "[nN][nN][tT][pP]:\\/\\/" . RFC1738_HOSTPORT . "\\/" . RFC1738_GROUP . "(?:\\/\\d+)?"); + +// TELNET +define("RFC1738_TELNETURL", "[tT][eE][lL][nN][eE][tT]:\\/\\/" . RFC1738_LOGIN . "\\/?"); + +// WAIS +define("RFC1738_DATABASE", RFC1738_UCHAR . "*"); +define("RFC1738_WTYPE", RFC1738_UCHAR . "*"); +define("RFC1738_WPATH", RFC1738_UCHAR . "*"); +define("RFC1738_WAISDATABASE", "[wW][aA][iI][sS]:\\/\\/" . RFC1738_HOSTPORT . "\\/" . RFC1738_DATABASE); +define("RFC1738_WAISINDEX", "[wW][aA][iI][sS]:\\/\\/" . RFC1738_HOSTPORT . "\\/" . RFC1738_DATABASE . "\\?" . RFC1738_SEARCH); +define("RFC1738_WAISDOC", "[wW][aA][iI][sS]:\\/\\/" . RFC1738_HOSTPORT . "\\/" . RFC1738_DATABASE . "\\/" . RFC1738_WTYPE . "\\/" . RFC1738_WPATH); +define("RFC1738_WAISURL", "(?:" . RFC1738_WAISDOC . "|" . RFC1738_WAISINDEX . "|" . RFC1738_WAISDATABASE . ")"); + +// PROSPERO +define("RFC1738_FIELDNAME", "(?:" . RFC1738_UCHAR . "|[?:@&])*"); +define("RFC1738_FIELDVALUE", "(?:" . RFC1738_UCHAR . "|[?:@&])*"); +define("RFC1738_FIELDSPEC", ";" . RFC1738_FIELDNAME . "=" . RFC1738_FIELDVALUE); +define("RFC1738_PSEGMENT", "(?:" . RFC1738_UCHAR . "|[?:@&=])*"); +define("RFC1738_PPATH", RFC1738_PSEGMENT . "(?:\\/" . RFC1738_PSEGMENT . ")*"); +define("RFC1738_PROSPEROURL", "[pP][rR][oO][sS][pP][eE][rR][oO]:\\/\\/" . RFC1738_HOSTPORT . "\\/" . RFC1738_PPATH . "(?:" . RFC1738_FIELDSPEC . ")*"); + +?> diff --git a/lib/php/monica/rfc2396.inc.php b/lib/php/monica/rfc2396.inc.php new file mode 100644 index 0000000..56ad9e5 --- /dev/null +++ b/lib/php/monica/rfc2396.inc.php @@ -0,0 +1,63 @@ + +// Copyright: Copyright (C) 2005-2007 Pristine Communications + +// Section 1.6 +define("RFC2396_LOWALPHA", "[a-z]"); +define("RFC2396_UPALPHA", "[A-Z]"); +define("RFC2396_ALPHA", "[A-Za-z]"); +define("RFC2396_DIGIT", "\\d"); +define("RFC2396_ALPHANUM", "[A-Za-z\\d]"); +// Section 2.2 +define("RFC2396_RESERVED", "[;\\/?:@&=+$,]"); +// Section 2.3 +define("RFC2396_MARK", "[\\-_\\.!~*'()]"); +// alphanum, mark +define("RFC2396_UNRESERVED", "[A-Za-z\\d\\-_\\.!~*'()]"); +// Section 2.4.1 +define("RFC2396_HEX", "[\\dA-Fa-f]"); +define("RFC2396_ESCAPED", "%" . RFC2396_HEX . "{2}"); +// Chapter 2 +define("RFC2396_URIC", "(?:" . RFC2396_RESERVED . "|" . RFC2396_UNRESERVED . "|" . RFC2396_ESCAPED . ")"); +// Section 2.4.3 +define("RFC2396_CONTROL", "[\\x00-\\x1F\\x7F]"); +define("RFC2396_SPACE", " "); +define("RFC2396_DELIMS", "[<>#%\"]"); +define("RFC2396_UNWISE", "[{}|\\\\^\\[\\]`]"); +// Section 3.1 +define("RFC2396_SCHEME", "[A-Za-z][A-Za-z+\\-\\.]*"); +// Section 3.2.1 +define("RFC2396_REG_NAME", "(?:" . RFC2396_UNRESERVED . "|" . RFC2396_ESCAPED . "|[$,;:@&=+])+"); +// Section 3.2.2 +define("RFC2396_DOMAINLABEL", RFC2396_ALPHANUM . "(?:[A-Za-z\\d\\-]*" . RFC2396_ALPHANUM . ")?"); +define("RFC2396_TOPLABEL", RFC2396_ALPHA . "(?:[A-Za-z\\d\\-]*" . RFC2396_ALPHANUM . ")?"); +define("RFC2396_HOSTNAME", "(?:" . RFC2396_DOMAINLABEL . "\\.)*" . RFC2396_TOPLABEL . "\\.?"); +define("RFC2396_IPV4ADDRESS", "\\d+\\.\\d+\\.\\d+\\.\\d+"); +define("RFC2396_HOST", "(?:" . RFC2396_HOSTNAME . "|" . RFC2396_IPV4ADDRESS . ")"); +define("RFC2396_PORT", "\\d*"); +define("RFC2396_HOSTPORT", RFC2396_HOST . "(?::" . RFC2396_PORT . ")?"); +define("RFC2396_USERINFO", "(?:" . RFC2396_UNRESERVED . "|" . RFC2396_ESCAPED . "|[;:&=+$,])*"); +define("RFC2396_SERVER", "(?:(?:" . RFC2396_USERINFO . ")?" . RFC2396_HOSTPORT . ")?"); +// Section 3.2 +define("RFC2396_AUTHORITY", "(?:" . RFC2396_SERVER . "|" . RFC2396_REG_NAME . ")"); +// Section 3.3 +define("RFC2396_PCHAR", "(?:" . RFC2396_UNRESERVED . "|" . RFC2396_ESCAPED . "|[:@&=+$,])"); +define("RFC2396_PARAM", RFC2396_PCHAR . "*"); +define("RFC2396_SEGMENT", RFC2396_PCHAR . "*(?:;" . RFC2396_PARAM . ")*"); +define("RFC2396_PATH_SEGMENTS", RFC2396_SEGMENT . "(?:\\/" . RFC2396_SEGMENT . ")*"); +// Section 3.4 +define("RFC2396_QUERY", RFC2396_URIC . "*"); +// Chapter 3 +define("RFC2396_URIC_NO_SLASH", "(?:" . RFC2396_UNRESERVED . "|" . RFC2396_ESCAPED . "|[;?:@&=+$,])"); +define("RFC2396_OPAQUE_PART", RFC2396_URIC_NO_SLASH . "(?:" . RFC2396_URIC . "*)"); +define("RFC2396_ABS_PATH", "\\/" . RFC2396_PATH_SEGMENTS); +define("RFC2396_NET_PATH", "\\/\\/" . RFC2396_AUTHORITY . "(?:" . RFC2396_ABS_PATH . ")?"); +define("RFC2396_HIER_PART", "(?:" . RFC2396_NET_PATH . "|" . RFC2396_ABS_PATH . ")"); +define("RFC2396_ABSOLUTEURI", RFC2396_SCHEME . ":(?:" . RFC2396_HIER_PART . "|" . RFC2396_OPAQUE_PART .")(?:\\?" . RFC2396_QUERY . ")?"); +// Section 3.3 +define("RFC2396_PATH", "(?:" . RFC2396_ABS_PATH . "|" . RFC2396_OPAQUE_PART . ")?"); + +?> diff --git a/lib/php/monica/rfc822.inc.php b/lib/php/monica/rfc822.inc.php new file mode 100644 index 0000000..3948093 --- /dev/null +++ b/lib/php/monica/rfc822.inc.php @@ -0,0 +1,31 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +define("RFC822_CTL", "[\\x01-\\x1F\\x7F]"); +define("RFC822_SPECIALS", "[()<>@,;:\\\\\".\\[\\]]"); +define("RFC822_ATOM", "[\\x21\\x23-\\x27\\x2A-\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x41-\\x5A\\x5E-\\x7E]+"); +define("RFC822_DTEXT", "[^\"\\\\\r]"); +define("RFC822_QUOTED_PAIR", "\\\\[\\x01-\\xFF]"); + +define("RFC822_DOMAIN_REF", RFC822_ATOM); +define("RFC822_DOMAIN_LITERAL", "\\[(?:" . RFC822_DTEXT . "|" . RFC822_QUOTED_PAIR . ")*\\]"); +define("RFC822_SUB_DOMAIN", "(?:" . RFC822_DOMAIN_REF . "|" . RFC822_DOMAIN_LITERAL . ")"); +define("RFC822_DOMAIN", RFC822_SUB_DOMAIN . "(?:\." . RFC822_SUB_DOMAIN . ")*"); +define("RFC822_QUOTED_STR", "\"(?:" . RFC822_DTEXT . "|" . RFC822_QUOTED_PAIR . ")*\""); +define("RFC822_WORD", "(?:" . RFC822_ATOM . "|" . RFC822_QUOTED_STR . ")"); +define("RFC822_LOCAL_PART", RFC822_WORD . "(?:\." . RFC822_WORD . ")*"); + +define("RFC822_ADDR_SPEC", RFC822_LOCAL_PART . "@" . RFC822_DOMAIN); + +// rfc822_phrase_need_quoting: Whether a phrase need to be quoted by RFC-822 +function rfc822_phrase_need_quoting($a) +{ + return preg_match("/[()<>@,;:\\\\\".\\[\\]\\x01-\\x1F\\x7F]/", $a)? + true: false; +} + +?> diff --git a/lib/php/monica/rmalldir.inc.php b/lib/php/monica/rmalldir.inc.php new file mode 100644 index 0000000..37e1fa7 --- /dev/null +++ b/lib/php/monica/rmalldir.inc.php @@ -0,0 +1,40 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// rmalldir: Remove a whole directory +// Input: The directory $dir to be removed. It won't check at all +// Output: none +function rmalldir($dir) +{ + // Non-existing + if (!file_exists($dir)) { + return; + } + // Get everything inside + $ents = array(); + $dh = opendir($dir); + while (($ent = readdir($dh)) !== false) { + // Not a real entry + if ($ent == "." || $ent == "..") { + continue; + } + $ents[] = "$dir/$ent"; + } + closedir($dh); + // Remove them + foreach ($ents as $ent) { + if (is_dir($ent)) { + rmalldir($ent); + } else { + unlink($ent); + } + } + rmdir($dir); + return; +} + +?> diff --git a/lib/php/monica/rmofile.inc.php b/lib/php/monica/rmofile.inc.php new file mode 100644 index 0000000..b3ce4ba --- /dev/null +++ b/lib/php/monica/rmofile.inc.php @@ -0,0 +1,134 @@ + +// Copyright: Copyright (C) 2003-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/lninfo.inc.php"; +require_once "monica/rel2abs.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/xfileio.inc.php"; + +// rmoldpage: Remove the old page before creating a new one +// Input: The old page path $oldpage to be removed, and an optional new page +// path $newpage to be compared with. It won't check at all. +// Path is without DOC_ROOT +function rmoldpage($oldpage, $newpage = null) +{ + // Get the available languages list + global $ALL_LINGUAS; + // Standardize it + $oldpage = stdpath($oldpage); + if (substr($oldpage, -1) == "/") { + $oldpage .= "index.html"; + } + // The new file is supplied to be compared with + if (!is_null($newpage)) { + // Standardize it + $newpage = stdpath($newpage); + if (substr($newpage, -1) == "/") { + $newpage .= "index.html"; + } + // Return if unchanged + if ($oldpage == $newpage) { + return; + } + } + + // Unilingual + if (count($ALL_LINGUAS) == 1) { + $oldfile = DOC_ROOT . $oldpage; + if (!is_null($newpage)) { + $newfile = DOC_ROOT . $newpage; + rmoldfile($oldfile, $newfile); + } else { + rmoldfile($oldfile); + } + + // Multilingual + } else { + for ($l = 0; $l < count($ALL_LINGUAS); $l++) { + $langfile = ln($ALL_LINGUAS[$l], LN_FILENAME); + $oldfile = DOC_ROOT . "/$langfile$oldpage"; + if (!is_null($newpage)) { + $newfile = DOC_ROOT . "/$langfile$newpage"; + rmoldfile($oldfile, $newfile); + } else { + rmoldfile($oldfile); + } + } + } +} + +// rmoldfile: the real function +function rmoldfile($oldfile, $newfile = null) +{ + // Obtain the parent directory + $parent = dirname($oldfile); + // Return if its parent is not a directory + if (!is_dir($parent)) { + return; + } + // Remove the file and its variants + $files = preg_match("/\.html$/", $oldfile)? + array($oldfile, "$oldfile.html", "$oldfile.xhtml"): array($oldfile); + foreach ($files as $file) { + if (!is_file($file) && !is_link($file)) { + continue; + } + // We can delete this file + if (is_writable($parent)) { + unlink($file); + // We cannot delete the file -- Empty it if possible + } else { + if (is_file($file) && is_writable($file)) { + xfwrite($file, ""); + } + } + } + + // Remove the parents as much as possible and necessary + while ($parent != "/") { + $dir = $parent; + // Coincident with the new path ends + if (!is_null($newfile) && substr($newfile, 0, strlen($dir) + 1) == $dir . "/") { + return; + } + // Obtain the parent directory + $parent = dirname($dir); + // Skip to the next parent if directory not exists + if (!file_exists($dir)) { + continue; + } + // We cannot remove, or the directory is not empty + if (!is_writable($parent) || !is_dir($dir) || _rmofile_dir_not_empty($dir)) { + return; + } + // Remove this directory + rmdir($dir); + } +} + +// _rmofile_dir_not_empty: Check if a directory is empty +function _rmofile_dir_not_empty($dir) +{ + $dh = opendir($dir); + while (($ent = readdir($dh)) !== false) { + // A real entry is found + if ($ent != "." && $ent != "..") { + closedir($dh); + return true; + } + } + // No real entry was found + closedir($dh); + return false; +} + +?> diff --git a/lib/php/monica/runcmd.inc.php b/lib/php/monica/runcmd.inc.php new file mode 100644 index 0000000..6ac8dba --- /dev/null +++ b/lib/php/monica/runcmd.inc.php @@ -0,0 +1,77 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// xruncmd: Entended runcmd, which produce error when errno != 0 +// Output: STDOUT +function xruncmd($cmd, $stdin) +{ + // Deal with shell argument escapes + if (is_array($cmd)) { + $args = array(); + foreach ($cmd as $arg) { + $args[] = escapeshellarg($arg); + } + $cmd = implode(" ", $args); + } + + // Run the command + $exitno = runcmd($cmd, $stdin, $stdout, $stderr); + if ($exitno != 0) { + trigger_error("Failed executing command:\n$cmd\n" + . $stdout . $stderr . "exit no: $exitno", E_USER_ERROR); + } + return $stdout; +} + +// runcmd: Run a command, return the exit code, STDOUT and STDERR +// Output: The exit return number +function runcmd($cmd, $stdin, &$stdout, &$stderr) +{ + // Deal with shell argument escapes + if (is_array($cmd)) { + $args = array(); + foreach ($cmd as $arg) { + $args[] = escapeshellarg($arg); + } + $cmd = implode(" ", $args); + } + + // Run the command + $descriptorspec = array( + 0 => array("pipe", "r"), // STDIN + 1 => array("pipe", "w"), // STDOUT + 2 => array("pipe", "w"), // STDERR + ); + $proc = proc_open($cmd, $descriptorspec, $pipes); + + // Send to STDIN + if (!is_null($stdin) && $stdin !== "") { + fwrite($pipes[0], $stdin); + } + fclose($pipes[0]); + + // Read from STDOUT + $stdout = ""; + while(!feof($pipes[1])) { + $stdout .= fread($pipes[1], 1024); + } + fclose($pipes[1]); + + // Read from STDERR + $stderr = ""; + while(!feof($pipes[2])) { + $stderr .= fread($pipes[2], 1024); + } + fclose($pipes[2]); + + // Get the return code + $retval = proc_close($proc); + + return $retval; +} + +?> diff --git a/lib/php/monica/scptpriv.inc.php b/lib/php/monica/scptpriv.inc.php new file mode 100644 index 0000000..07ef68e --- /dev/null +++ b/lib/php/monica/scptpriv.inc.php @@ -0,0 +1,105 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/chkpriv.inc.php"; +require_once "monica/guest.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/server.inc.php"; +require_once "monica/sql.inc.php"; + +// is_script_permitted: Check the script privilege +function is_script_permitted($script = null) +{ + // Cache the result + static $cache = array(); + // Default to the current script + if (is_null($script) || $script === true) { + // If Apache SCRIPT_FILENAME exists, use it with DOC_ROOT to decide the current script + if ( is_apache() + && array_key_exists("SCRIPT_FILENAME", $_SERVER) + && substr($_SERVER["SCRIPT_FILENAME"], 0, strlen(DOC_ROOT)) == DOC_ROOT) { + $script = substr($_SERVER["SCRIPT_FILENAME"], strlen(DOC_ROOT)); + if (substr($script, -10) == "/index.php") { + $script = substr($script, 0, -9); + } + } else { + $script = REQUEST_PATH; + } + } + // Return the cache + if (array_key_exists($script, $cache)) { + return $cache[$script]; + } + + // Always true for super users + if (is_su()) { + $cache[$script] = true; + return $cache[$script]; + } + + // Obtain the permitted groups + $select = "SELECT groups.id AS grp FROM scptpriv" + . " INNER JOIN groups ON scptpriv.grp=groups.sn" + . " WHERE scptpriv.script='" . sql_esctext($script) . "';\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + for ($i = 0, $permgroups = array(); $i < $count; $i++) { + $row = sql_fetch_assoc($result); + $permgroups[] = $row["grp"]; + } + + // Only true for guests to act like ordinary administrators + if (is_guest() && count($permgroups) > 0) { + $cache[$script] = true; + return $cache[$script]; + } + + // Obtain the belonged groups + $curgroups = get_login_groups(); + // If there is any intersection + if (count(array_intersect($curgroups, $permgroups)) > 0) { + $cache[$script] = true; + return $cache[$script]; + } + + // Default to false + $cache[$script] = false; + return $cache[$script]; +} + +// is_admin_script: If this is an administrative script +function is_admin_script($script = null) +{ + // Cache the result + static $cache = array(); + // Default to the current script + if (is_null($script)) { + $script = REQUEST_PATH; + } + // Return the cache + if (array_key_exists($script, $cache)) { + return $cache[$script]; + } + // Respect the local checker + if (function_exists("is_admin_script_local")) { + $cache[$script] = is_admin_script_local($script); + + // Else, check the "/admin/" prefix + } else { + $cache[$script] = substr($script, 0, 7) == "/admin/"; + } + + return $cache[$script]; +} + +?> diff --git a/lib/php/monica/server.inc.php b/lib/php/monica/server.inc.php new file mode 100644 index 0000000..2b565ef --- /dev/null +++ b/lib/php/monica/server.inc.php @@ -0,0 +1,29 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/cgiemu.inc.php"; + +// is_apache: If this server is Apache +function is_apache() +{ + return array_key_exists("SERVER_SOFTWARE", $_SERVER) + && preg_match("/^Apache\b/", $_SERVER["SERVER_SOFTWARE"]); +} + +// is_iis: If this server is Microsoft IIS +function is_iis() +{ + return array_key_exists("SERVER_SOFTWARE", $_SERVER) + && preg_match("/^Microsoft-(IIS|PWS)\b/", $_SERVER["SERVER_SOFTWARE"]); +} + +?> diff --git a/lib/php/monica/sitesize.inc.php b/lib/php/monica/sitesize.inc.php new file mode 100644 index 0000000..c8ecbf3 --- /dev/null +++ b/lib/php/monica/sitesize.inc.php @@ -0,0 +1,89 @@ + +// Copyright: Copyright (C) 2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/echoform.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/htmlchar.inc.php"; +require_once "monica/markabbr.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/sql.inc.php"; + +// Settings +// This is true for almost all the cases +define("_SITESIZE_BLKSIZE", 512); + +// sitesize: Calculate and return the size of the website +function sitesize() +{ + $files = _sitesize_dirsize(DOC_ROOT); + $data = sql_dbsize(); + return array( + "files" => $files, + "data" => $data, + "total" => $files + $data, + ); +} + +// html_sitesize: Print the size usage of the website +function html_sitesize() +{ + $size = sitesize(); + if ($size["data"] == 0) { +?>

    + +

    + + diff --git a/lib/php/monica/spltline.inc.php b/lib/php/monica/spltline.inc.php new file mode 100644 index 0000000..a3aef57 --- /dev/null +++ b/lib/php/monica/spltline.inc.php @@ -0,0 +1,46 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// split_long_lines: Split long lines (English only) +function split_long_lines($source, $line_width) +{ + $pos = 0; + $result = ""; + while (preg_match("/^(\S+[^\n\S]*|[^\n\S]+|\n+)/s", $source, $m)) { + $piece = $m[1]; + // Text token + if (preg_match("/^\S/", $piece)) { + // Split line + if ($pos + strlen($piece) > $line_width) { + $result .= "\n"; + $pos = 0; + } + $result .= $piece; + $pos += strlen($piece); + + // Space token -- skip if over $line_width + } elseif (preg_match("/^[^\n\S]/", $piece)) { + // Split line + if ($pos + strlen($piece) > $line_width) { + $result .= "\n"; + $pos = 0; + } else { + $result .= $piece; + $pos += strlen($piece); + } + + // New-line token -- add it and reset the position + } else { + $result .= $piece; + $pos = 0; + } + $source = substr($source, strlen($piece)); + } + return $result; +} + +?> diff --git a/lib/php/monica/sql.inc.php b/lib/php/monica/sql.inc.php new file mode 100644 index 0000000..18f596a --- /dev/null +++ b/lib/php/monica/sql.inc.php @@ -0,0 +1,439 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines with high precedence +require_once "monica/sqlconst.inc.php"; +// Referenced subroutines +require_once "monica/mysql.inc.php"; +require_once "monica/postgres.inc.php"; + +// Settings +// Settings are moved to sqlconst.inc.php + +// sql_connect: Connect to the SQL database +function sql_connect() +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return xpg_connect(); + break; + case SQL_MYSQL: + return xmysql_connect(); + break; + } +} + +// sql_close: Disconnect from the SQL database +function sql_close() +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return xpg_close(); + case SQL_MYSQL: + return xmysql_close(); + } +} + + +///////////////////////// +// Concurrency Control: Transactions and Locks +///////////////////////// +// sql_begin: Begin an SQL transaction +function sql_begin() +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_begin(); + case SQL_MYSQL: + return mysql_begin(); + } +} +// sql_commit: Commit an SQL transaction +function sql_commit() +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_commit(); + case SQL_MYSQL: + return mysql_commit(); + } +} +// sql_rollback: Rollback an SQL transaction +function sql_rollback() +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_rollback(); + case SQL_MYSQL: + return mysql_rollback(); + } +} + +// sql_lock: Lock and unlock the SQL tables +function sql_lock($locks = null) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_lock($locks); + case SQL_MYSQL: + return mysql_lock($locks); + } +} + +// sql_query: Do an SQL query and report the error +function sql_query($query) +{ + static $use_mtime; + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + if (!isset($use_mtime)) { + $use_mtime = in_array("mtime", pg_tables()); + } + $result = xpg_query($query); + // Update the mtime + if ($use_mtime) { + if (preg_match("/^(?:INSERT\s+INTO|UPDATE|DELETE\s+FROM)\s+(\S+)/i", $query, $m)) { + $table = $m[1]; + $select_mtime = "SELECT * FROM mtime" + . " WHERE tabname='" . pg_escape_string($table) . "';\n"; + $result_mtime = xpg_query($select_mtime); + // Found + if (pg_num_rows($result_mtime) == 1) { + // Update the mtime + $update = "UPDATE mtime SET mtime=now()" + . " WHERE tabname='" . pg_escape_string($table) . "';\n"; + xpg_query($update); + // Not found + } else { + // Set the mtime + $insert = "INSERT INTO mtime (tabname, mtime) VALUES" + . "('" . pg_escape_string($table) . "', now());\n"; + xpg_query($insert); + } + } + } + return $result; + + case SQL_MYSQL: + if (!isset($use_mtime)) { + $use_mtime = in_array("mtime", mysql_tables()); + } + $result = xmysql_query($query); + // Update the mtime + if ($use_mtime) { + if (preg_match("/^(?:INSERT\s+INTO|UPDATE|DELETE\s+FROM)\s+(\S+)/i", $query, $m)) { + $table = $m[1]; + $select_mtime = "SELECT * FROM mtime" + . " WHERE tabname='" . mysql_escape_string($table) . "';\n"; + $result_mtime = xmysql_query($select_mtime); + // Found + if (mysql_num_rows($result_mtime) == 1) { + // Update the mtime + $update = "UPDATE mtime SET mtime=now()" + . " WHERE tabname='" . mysql_escape_string($table) . "';\n"; + xmysql_query($update); + // Not found + } else { + // Set the mtime + $insert = "INSERT INTO mtime (tabname, mtime) VALUES" + . "('" . mysql_escape_string($table) . "', now());\n"; + xmysql_query($insert); + } + } + } + return $result; + } +} + +// sql_seek: Move the SQL result pointer +function sql_seek($query, $offset) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_seek($query, $offset); + case SQL_MYSQL: + return mysql_seek($query, $offset); + } +} + +// sql_num_rows: Return the number of rows +function sql_num_rows($result) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_num_rows($result); + case SQL_MYSQL: + return mysql_num_rows($result); + } +} + +// sql_fetch_assoc: Return a row as an associative array +function sql_fetch_assoc($result) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return xpg_fetch_assoc($result); + case SQL_MYSQL: + return xmysql_fetch_assoc($result); + } +} + +// sql_fetch_row: Return a row as an numeric array +function sql_fetch_row($result) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return xpg_fetch_row($result); + case SQL_MYSQL: + return xmysql_fetch_row($result); + } +} + +// sql_tables: Return a list of available tables +function sql_tables($schema = null) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_tables($schema); + case SQL_MYSQL: + return mysql_tables($schema); + } +} + +// sql_is_ml_table: Return if a table is multi-lingual +function sql_is_ml_table($table) +{ + return (count(sql_cols_ml($table)) > 0); +} + +// sql_cols: Return a list of available columns in a table +function sql_cols($table) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_cols($table); + case SQL_MYSQL: + return mysql_cols($table); + } +} + +// sql_cols_ml: Return a list of multi-lingual columns in a table +function sql_cols_ml($table) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_cols_ml($table); + case SQL_MYSQL: + return mysql_cols_ml($table); + } +} + +// sql_cols_nl: Return a list of columns without their multi-lingual +// deviants in a table +function sql_cols_nl($table) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_cols_nl($table); + case SQL_MYSQL: + return mysql_cols_nl($table); + } +} + +// sql_cols_of_type: Return the columns in a certain data type +function sql_cols_of_type($result, $type, $format = SQL_FETCH_ASSOC) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_cols_of_type($result, $type, $format); + case SQL_MYSQL: + return mysql_cols_of_type($result, $type, $format); + } +} + +// sql_col_lens: Return the column length in a table +function sql_col_lens($table) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_col_lens($table); + case SQL_MYSQL: + return mysql_col_lens($table); + } +} + +// sql_strcat: Concatenate strings +function sql_strcat() +{ + $strs = func_get_args(); + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return call_user_func_array("pg_strcat", $strs); + case SQL_MYSQL: + return call_user_func_array("mysql_strcat", $strs); + } +} + +// sql_lastupd: Obtain the last updated time of a list of tables +function sql_lastupd($tables) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_lastupd($tables); + case SQL_MYSQL: + return mysql_lastupd($tables); + } +} + +// sql_dbsize: Obtain the size of the database +function sql_dbsize() +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_NONE: + return 0; + case SQL_POSTGRESQL: + return pg_dbsize(); + case SQL_MYSQL: + return mysql_dbsize(); + } +} + +// sql_date: Return date in a predefined format +function sql_date($expr, $format) +{ + $strs = func_get_args(); + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_date($expr, $format); + case SQL_MYSQL: + return mysql_date($expr, $format); + } +} + +// sql_re: Return the SQL regular expression operator +function sql_re() +{ + $strs = func_get_args(); + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_re(); + case SQL_MYSQL: + return mysql_re(); + } +} + +// sql_escblob: Escape a piece of BLOB octet +function sql_escblob($blob) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_escape_bytea($blob); + case SQL_MYSQL: + return mysql_escape_string($blob); + } +} + +// sql_esctext: Escape a piece of text +function sql_esctext($text) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + return pg_escape_string($text); + case SQL_MYSQL: + return mysql_escape_string($text); + } +} + +// sql_strlen: Calculate the length of a text string +// MySQL once used strlen(), but now mb_strlen() since 4.1 +function sql_strlen($text) +{ + switch ($GLOBALS["SQL_DBTYPE"]) { + case SQL_POSTGRESQL: + case SQL_MYSQL: + return mb_strlen($text); + } +} + +// sql_support: Return if this SQL supports views +function sql_support($feature) +{ + switch ($feature) { + // If view is supported + // MySQL once did not support, but support now since 5.0 + case SQL_FEATURE_VIEW: + return true; + + // If boolean data type is supported + case SQL_FEATURE_BOOLEAN: + if ($GLOBALS["SQL_DBTYPE"] == SQL_MYSQL) { + return false; + } + return true; + + // Default to yes. ^^; We assume everyone is a good guy + default: + return true; + } +} + +// sql_is_true: Return the expression for a boolean true +function sql_is_true($expr) +{ + if (!sql_support(SQL_FEATURE_BOOLEAN)) { + return "$expr IS NOT NULL"; + } + return $expr; +} + +// sql_is_false: Return the expression for a boolean false +function sql_is_false($expr) +{ + if (!sql_support(SQL_FEATURE_BOOLEAN)) { + return "$expr IS NULL"; + } + return "NOT $expr"; +} + +// sql_true: Return the boolean true value +function sql_true() +{ + if (!sql_support(SQL_FEATURE_BOOLEAN)) { + return "''"; + } + return "TRUE"; +} + +// sql_false: Return the boolean false value +function sql_false() +{ + if (!sql_support(SQL_FEATURE_BOOLEAN)) { + return "NULL"; + } + return "FALSE"; +} + +// sql_esclike: Escape a phrase by the LIKE matching rule +// Double quote should never be used, according to +// the column name rules in the SQL standard. +function sql_esclike($phrase) +{ + $phrase = str_replace("\\", "\\\\\\\\", $phrase); + $phrase = str_replace("%", "\\\\%", $phrase); + $phrase = str_replace("_", "\\\\_", $phrase); + // By the SQL standard + $phrase = str_replace("'", "''", $phrase); + // Loose way that works for some overly-simple, non-standard DBMS, like MySQL + //$phrase = str_replace("'", "\\\\\\'", $phrase); + return $phrase; +} + +?> diff --git a/lib/php/monica/sqlconst.inc.php b/lib/php/monica/sqlconst.inc.php new file mode 100644 index 0000000..fb9cbf4 --- /dev/null +++ b/lib/php/monica/sqlconst.inc.php @@ -0,0 +1,38 @@ + +// Copyright: Copyright (C) 2006-2007 Pristine Communications + +// Settings +// SQL types +define("SQL_NONE", false); +define("SQL_POSTGRESQL", "PostgreSQL"); +define("SQL_MYSQL", "MySQL"); +$VALID_SQLS = array(SQL_NONE, SQL_POSTGRESQL, SQL_MYSQL); +$SQL_DBTYPE = SQL_NONE; +define("SQL_MLCOLS_NONE", false); +define("SQL_MLCOLS_SET", 1); +// SQL features +define("SQL_FEATURE_VIEW", "view"); +define("SQL_FEATURE_BOOLEAN", "boolean"); +// SQL data types +define("SQL_TYPE_BOOLEAN", "boolean"); +define("SQL_TYPE_BLOB", "blob"); +define("SQL_TYPE_INTEGER", "integer"); +define("SQL_TYPE_BIGINT", "big_integer"); +define("SQL_TYPE_FLOAT", "float"); +// SQL fetch format +define("SQL_FETCH_ASSOC", "assoc"); +define("SQL_FETCH_ROW", "row"); +// SQL date format +define("SQL_YYYYMMDD", "YYYYMMDD"); +define("SQL_YYYY_YYYYMMDD", "YYYY/YYYYMMDD"); +define("SQL_MM_DD", "MM-DD"); +define("SQL_M_D_EN", "M/D en"); +define("SQL_M_D_ZHTW", "M/D zh-tw"); +define("SQL_M_D_DE", "M/D de"); +define("SQL_HH_MM", "HH:MM"); + +?> diff --git a/lib/php/monica/sqllogin.inc.php b/lib/php/monica/sqllogin.inc.php new file mode 100644 index 0000000..6658d7e --- /dev/null +++ b/lib/php/monica/sqllogin.inc.php @@ -0,0 +1,139 @@ + +// Copyright: Copyright (C) 2006-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/sqlconst.inc.php"; + +// get_sql_login_info: Obtain the SQL log-in information +function get_sql_login_info($type, $database = null, $host = null, $user = null) +{ + // DBMS naming convension + switch ($type) { + case SQL_POSTGRESQL: + $names = array("PGHOST", "PGUSER", "PGPASSWORD", "PGDATABASE"); + break; + case SQL_MYSQL: + $names = array("MYSQL_HOST", "MYSQL_USER", "MYSQL_PW", "MYSQL_DB"); + break; + } + // Initialize the return values + $login = array( + $names[0] => null, + $names[1] => null, + $names[2] => null, + $names[3] => null, + ); + + // Obtain the SQL log-in information from the environment + $sqllogin = getenv("SQLLOGIN"); + if ($sqllogin !== false) { + // Parse the SQL log-in information + // The first matched line is used, so put the default first + $sqllogin = base64_decode($sqllogin); + // Find all the matching records + $matches = array(); + $lineno = 0; + $lines = explode("\n", $sqllogin); + foreach ($lines as $line) { + $cols = explode("\t", $line); + if (count($cols) == 4) { + $cols[] = ""; + } + // Skip malformed lines + if (count($cols) != 5) { + continue; + } + // Not this DBMS type + if ($cols[0] != $type) { + continue; + } + for ($i = 0; $i < count($cols); $i++) { + if ($cols[$i] == "") { + $cols[$i] = null; + } + } + $count = 0; + $score = 0; + // Match this database? + if (is_null($database) || is_null($cols[4])) { + } elseif ($cols[4] == $database) { + $count++; + $score += 3; + } else { + continue; + } + // Match this user? + if (is_null($user) || is_null($cols[2])) { + } elseif ($cols[2] == $user) { + $count++; + $score += 2; + } else { + continue; + } + // Match this host? + if (is_null($host) || is_null($cols[1])) { + } elseif ($cols[1] == $host) { + $count++; + $score += 1; + } else { + continue; + } + $matches[] = array( + "host" => $cols[1], + "user" => $cols[2], + "password" => $cols[3], + "database" => $cols[4], + "matches" => $count, + "score" => $score, + "lineno" => ++$lineno, + ); + } + if (count($matches) > 0) { + usort($matches, "_sqllogin_sort_matches"); + $login[$names[0]] = $matches[0]["host"]; + $login[$names[1]] = $matches[0]["user"]; + $login[$names[2]] = $matches[0]["password"]; + $login[$names[3]] = $matches[0]["database"]; + } + } + + // Apply the specified information + if (!is_null($database) && is_null($login[$names[3]])) { + $login[$names[3]] = $database; + } + if (!is_null($host) && is_null($login[$names[0]])) { + $login[$names[0]] = $host; + } + if (!is_null($user) && is_null($login[$names[1]])) { + $login[$names[1]] = $user; + } + + // PostgreSQL database name cannot be empty + if ($type == SQL_POSTGRESQL && is_null($login[$names[3]])) { + $login[$names[3]] = "test"; + } + + return $login; +} + +// _sqllogin_sort_matches: sort the matching lines +function _sqllogin_sort_matches($a, $b) +{ + if ($a["matches"] != $b["matches"]) { + return $b["matches"] - $a["matches"]; + } + if ($a["score"] != $b["score"]) { + return $b["score"] - $a["score"]; + } + return $a["lineno"] - $b["lineno"]; +} + +?> diff --git a/lib/php/monica/timezone.inc.php b/lib/php/monica/timezone.inc.php new file mode 100644 index 0000000..d653896 --- /dev/null +++ b/lib/php/monica/timezone.inc.php @@ -0,0 +1,32 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// timezone_iso: Return the timezone in ISO 8601 format +function timezone_iso() +{ + // Cache the result + static $cache; + // Return the cache + if (isset($cache)) { + return $cache; + } + + // Calculate the time zone string + $tzsec = date("Z"); + $tzsign = ($tzsec >= 0? "+": "-"); + $tzsec = abs($tzsec); + $tzmin = floor($tzsec / 60); + $tzsec = $tzsec % 60; + $tzhr = floor($tzmin / 60); + $tzmin = $tzmin % 60; + $tz = sprintf("%s%02d:%02d", $tzsign, $tzhr, $tzmin); + // Cache it + $cache = $tz; + return $tz; +} + +?> diff --git a/lib/php/monica/trimtext.inc.php b/lib/php/monica/trimtext.inc.php new file mode 100644 index 0000000..e63385c --- /dev/null +++ b/lib/php/monica/trimtext.inc.php @@ -0,0 +1,22 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// trimtext: Trim a textarea input, remove excess spaces +function trimtext($a) +{ + // Format the textarea input to UNIX text format + $a = str_replace("\r\n", "\n", $a); + // Trim the excess leading and trailing lines and spaces + // This is not working. Long articles may overload the PCRE limit. + //$a = preg_replace("/^(?:[^\S\n]*\n)*(.*?)\s*$/us", "\\1", $a); + $a = preg_replace("/^(?:[^\S\n]*\n)+/s", "", rtrim($a)); + // Remove the excess spaces at the end of each line + $a = preg_replace("/[^\S\n]+\n/", "\n", $a); + return $a; +} + +?> diff --git a/lib/php/monica/unauth.inc.php b/lib/php/monica/unauth.inc.php new file mode 100644 index 0000000..1a023c0 --- /dev/null +++ b/lib/php/monica/unauth.inc.php @@ -0,0 +1,52 @@ + +// Copyright: Copyright (C) 2004-2008 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/cgiemu.inc.php"; +require_once "monica/formfunc.inc.php"; +require_once "monica/http.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/userhome.inc.php"; + +// unauth: User is not authorized +function unauth($msg = null) +{ + // Not logged in yet -- log in + if (is_null(get_login_sn())) { + $url = userhome(); + $args = array(); + // Referer not needed for users' home pages + if (!in_array(REQUEST_PATH, array(ADMIN_HOME, NONADMIN_HOME))) { + $args[] = "referer=" . urlencode(REQUEST_FULLURI); + // Referer not recorded -- keep the status message + } else { + $FORM =& get_or_post(); + if (array_key_exists("statid", $FORM)) { + $args[] = "statid=" . urlencode($FORM["statid"]); + } + } + if (count($args) > 0) { + $url .= "?" . implode("&", $args); + } + if ($_SERVER["REQUEST_METHOD"] == "POST") { + http_303($url); + } else { + http_307($url); + } + + // Logged in but privilege not enough + } else { + http_403($msg); + } +} + +?> diff --git a/lib/php/monica/unicode.inc.php b/lib/php/monica/unicode.inc.php new file mode 100644 index 0000000..dc96900 --- /dev/null +++ b/lib/php/monica/unicode.inc.php @@ -0,0 +1,286 @@ + +// Copyright: Copyright (C) 2002-2008 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/errhndl.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/htmlchar.inc.php"; +require_once "monica/lninfo.inc.php"; + +// Settings +if (!defined("DBMDIR")) { + define("DBMDIR", dirname(dirname(dirname(__FILE__))) . "/" . php_uname("m")); +} +define("UNICODE_HTML_CHAR_ENT_REF", "&[A-Za-z]{2,8}\\d{0,2};"); +define("_UNICODE_ENT2U8_DB", DBMDIR . "/ent2u8.db"); +define("_UNICODE_U82ENT_DB", DBMDIR . "/u82ent.db"); +define("_UNICODE_HNC2HCE_DB", DBMDIR . "/hnc2hce.db"); +define("UNICODE_NO_HCEREF", true); + +// Character set conversion maps - +// Obtain them with the above mb_encode_numericentity_cnvtmap(). +$CNVTMAP = array(); +// Character set conversion map definitions are in seperated files +// and are loaded only when it is used, to reduce the size of data +// to be loaded into the memory. Look into the cnvtmap/ subdirectory +// for these maps. + +// in_charset: If a piece of text is in a certain character set +function in_charset($text, $charset) +{ + $GLOBALS["php_errormsg"] = null; + set_error_handler("null_error_handler"); + iconv("UTF-8", $charset, $text); + restore_error_handler(); + return is_null($GLOBALS["php_errormsg"]); +} + +// is_usascii: If a piece of text is US-ASCII +function is_usascii($text) +{ + return preg_match("/[\\x80-\\xFF]/", $text)? false: true; +} + +// is_usascii_printable: If a piece of text is US-ASCII printable +function is_usascii_printable($a) +{ + // An array + if (is_array($a)) { + foreach (array_keys($a) as $k) { + if (!is_usascii_printable($k) || !is_usascii_printable($a[$k])) { + return false; + } + } + return true; + + // A piece of text + } else { + return preg_match("/^[\\x20-\\x7E]+$/", $a)? true: false; + } +} + +// is_usascii_printable_text: If a piece of multi-line text is US-ASCII printable +function is_usascii_printable_text($a) +{ + // An array + if (is_array($a)) { + foreach (array_keys($a) as $k) { + if (!is_usascii_printable_text($k) || !is_usascii_printable_text($a[$k])) { + return false; + } + } + return true; + + // A piece of text + } else { + return preg_match("/^[\\x20-\\x7E\s]+$/", $a)? true: false; + } +} + +// is_valid_unicode: If a piece of text is valid in unicode +function is_valid_unicode($text) +{ + // Try to encode the invalid characters and see if there is any + global $CNVTMAP; + require_once "monica/cnvtmap/invalid.inc.php"; + return $text == mb_encode_numericentity($text, $CNVTMAP["invalid"], "UTF-8"); +} + + +///////////////////////// +// Traditiona-Simplified Chinese conversion +///////////////////////// +// trad_to_simp: Convert Traditional Chinese to Simplified Chinese +function trad_to_simp($a) +{ + // Encode Big5 characters that are not available in GB2312 + global $CNVTMAP; + require_once "monica/cnvtmap/trad_to_simp.inc.php"; + $a = mb_encode_numericentity($a, $CNVTMAP["trad_to_simp"], "UTF-8"); + + $a = h_encode($a, "Big5"); + $a = iconv("Big5", "GB2312", $a); + $a = h_decode($a, "GB2312"); + return $a; +} + +// simp_to_trad: Convert Simplified Chinese to Traditional Chinese +function simp_to_trad($a) +{ + // Encode GB2312 characters that are not available in Big5 + global $CNVTMAP; + require_once "monica/cnvtmap/simp_to_trad.inc.php"; + $a = mb_encode_numericentity($a, $CNVTMAP["simp_to_trad"], "UTF-8"); + + $a = h_encode($a, "GB2312"); + $a = iconv("GB2312", "Big5", $a); + $a = h_decode($a, "Big5"); + return $a; +} + + +///////////////////////// +// Dealing with encodings and HTML character references +// Refer to HTML 4.01 specification +///////////////////////// +// h_encode: Encode UTF-8 text to octets with HTML character entity references +function h_encode($html, $charset = null, $nohce = false) +{ + // Default distination character set to the current character set + if (is_null($charset)) { + $charset = getlang(LN_CHARSET); + } + // Destination is UTF-8 -- Conversion is not needed + if ($charset == "UTF-8") { + return $html; + } + // Load the conversion map + global $CNVTMAP; + require_once "monica/cnvtmap/$charset.inc.php"; + // Convert it and return + + // Preserve the original timeout + $timeout = ini_get("max_execution_time"); + ini_set("max_execution_time", 0); + if (!$nohce) { + $r = iconv("UTF-8", $charset, + text_hnc2hce(mb_encode_numericentity($html, $CNVTMAP[$charset], "UTF-8"))); + } else { + $r = iconv("UTF-8", $charset, + mb_encode_numericentity($html, $CNVTMAP[$charset], "UTF-8")); + } + // Restore the timeout + ini_set("max_execution_time", $timeout); + return $r; +} + +// h_decode: Decode octets and HTML character references to UTF-8 text +// The output is in UTF-8 +function h_decode($html, $charset = null) +{ + // Default to the current character set + if (is_null($charset)) { + $charset = getlang(LN_CHARSET); + } + // Whether source is in UTF-8 or not does not matter. + // We still have to check if it is really in UTF-8, and decode + // the HTML character references. + // Try to decode with the specified encoding + $GLOBALS["php_errormsg"] = null; + set_error_handler("null_error_handler"); + $html = iconv($charset, "UTF-8", $html); + restore_error_handler(); + // Wrong encoding + if (!is_null($GLOBALS["php_errormsg"])) { + return null; + } + // Decode the HTML character references + return a_hcref2char($html); +} + +// page_encode: h_encode() an HTML page +function page_encode($html, $charset = null, $nohce = false) +{ + // Default to the current character set + if (is_null($charset)) { + $charset = getlang(LN_CHARSET); + } + $html = h_encode($html, $charset, $nohce); + if (is_null($html)) { + return null; + } + $html = str_replace("", h($charset), $html); + return $html; +} + +// a_hcref2char: Decode HTML character entity references in a piece of text +// to its corresponding characters, in UTF-8 +// The input and output should both be in UTF-8 +// It preserves encoded US-ASCII characters. US-ASCII characters do +// not need to be encoded. There must be some reason to encode them. +// (like @/@, </<, >/>, etc.) +function a_hcref2char($a) +{ + // Numeric character references (decimal) + $a = preg_replace_callback("/&#(\d{1,10});/", + create_function("\$m", + "\$c = iconv(\"UTF-32LE\", \"UTF-8\", pack(\"V\", \$m[1]));\n" + . "return !is_usascii_printable(\$c)? \$c: \$m[0];\n"), + $a); + + // Numeric character references (hexadecimal) + $a = preg_replace_callback("/&#x([0-9a-f]{1,8});/i", + create_function("\$m", + "\$c = iconv(\"UTF-32LE\", \"UTF-8\", pack(\"V\", hexdec(\$m[1])));\n" + . "return !is_usascii_printable(\$c)? \$c: \$m[0];\n"), + $a); + + // Character entity references + $a = preg_replace_callback("/" . UNICODE_HTML_CHAR_ENT_REF . "/", + create_function("\$m", + "\$c = hceref2char(\$m[0]);\n" + . "return (mb_strlen(\$c) > 1? \$c: (!is_usascii_printable(\$c)? \$c: \$m[0]));\n"), + $a); + + return $a; +} + +// hceref2char: Decode an HTML character entity reference +// to its corresponding character, in UTF-8 +// The output is in UTF-8 +function hceref2char($hceref) +{ + // Cache the result + static $cache = array(); + // Return the cache + if (array_key_exists($hceref, $cache)) { + return $cache[$hceref]; + } + + static $ENT2U8; + // Open the character entity reference mapping database + if (!isset($ENT2U8)) { + $ENT2U8 = dba_open(_UNICODE_ENT2U8_DB, "r", "gdbm"); + } + // Look for it + $cache[$hceref] = dba_exists($hceref, $ENT2U8)? + dba_fetch($hceref, $ENT2U8): $hceref; + + return $cache[$hceref]; +} + +// text_hnc2hce: Convert HTML numeric character referenecs +// to HTML character entity references +// in a piece of text +function text_hnc2hce($text) +{ + return preg_replace_callback("/&#(?:\d{1,10}|x[0-9a-f]{1,8});/i", + "_unicode_char_hnc2hce", $text); +} + +// _unicode_char_hnc2hce: Convert a HTML numeric character referenec +// to a HTML character entity reference +function _unicode_char_hnc2hce($m) +{ + static $HNC2HCE; + // Open the character entity reference mapping database + if (!isset($HNC2HCE)) { + $HNC2HCE = dba_open(_UNICODE_HNC2HCE_DB, "r", "gdbm"); + } + // Found + if (dba_exists($m[0], $HNC2HCE)) { + return dba_fetch($m[0], $HNC2HCE); + } + // Not found -- return untouched + return $m[0]; +} + +?> diff --git a/lib/php/monica/unused.inc.php b/lib/php/monica/unused.inc.php new file mode 100644 index 0000000..3dd4c1a --- /dev/null +++ b/lib/php/monica/unused.inc.php @@ -0,0 +1,467 @@ + +// Copyright: Copyright (C) 2007-2008 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/addcol.inc.php"; +require_once "monica/errhndl.inc.php"; +require_once "monica/hires.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/unicode.inc.php"; +require_once "monica/zh2py.inc.php"; + +// +// cnvtmap.inc.php +// +// cnvtmap.inc.php is removed now. It contains only this unsed +// mb_encode_numericentity_cnvtmap(). +// mb_encode_numericentity_cnvtmap: Obtain the cnvtmap of a character set +// to be used in mb_encode_numericentity() +// This is an occational maintainance subroutine. Do not call it +// regularily. The result should be saved. +function mb_encode_numericentity_cnvtmap($charset, $archive = false) +{ + // Preserve the original timeout + $timeout = ini_get("max_execution_time"); + ini_set("max_execution_time", 0); + // Find the characters that does not fit into that character set + for ($i = 0, $ords = array(); $i < 65536 * 32; $i++) { + $c = iconv("UTF-32LE", "UTF-8", pack("V", $i)); + $GLOBALS["php_errormsg"] = null; + set_error_handler("null_error_handler"); + iconv("UTF-8", $charset, $c); + restore_error_handler(); + if (!is_null($GLOBALS["php_errormsg"])) { + $ords[] = $i; + } + } + + // Get the ranges + for ($i = 0, $prev = -2, $ranges = array(); $i < count($ords); $i++) { + // A new range + if ($ords[$i] != $prev + 1) { + $ranges[] = array($ords[$i], $ords[$i]); + } + // Adjust the end point + $ranges[count($ranges) - 1][1] = $ords[$i]; + $prev = $ords[$i]; + } + + // Convert the ranges to cnvtmap for mb_encode_numericentity() + for ($i = 0, $cnvtmap = array(); $i < count($ranges); $i++) { + $cnvtmap[] = $ranges[$i][0]; + $cnvtmap[] = $ranges[$i][1]; + $cnvtmap[] = 0x000000; + $cnvtmap[] = 0xFFFFFF; + } + + // Output it in a format suitable to be archived + if ($archive) { + echo "\$CNVTMAP[\"$charset\"] = array(\n"; + for ($i = 0; $i < count($cnvtmap); $i += 4) { + printf(" 0x%06X, 0x%06X, 0x%06X, 0x%06X,\n", + $cnvtmap[$i], $cnvtmap[$i+1], $cnvtmap[$i+2], $cnvtmap[$i+3]); + } + echo ");\n"; + } + + // Restore the timeout + ini_set("max_execution_time", $timeout); + return $cnvtmap; +} + +// mb_encode_numericentity_invalid_cnvtmap: Obtain the cnvtmap of invalid unicode characters +// This is an occational maintainance subroutine. Do not call it +// regularily. The result should be saved. +function mb_encode_numericentity_invalid_cnvtmap($archive = false) +{ + // Preserve the original timeout + $timeout = ini_get("max_execution_time"); + ini_set("max_execution_time", 0); + // Find the characters that does not fit into that character set + for ($i = 0, $ords = array(); $i < 65536; $i++) { + $c = iconv("UTF-32LE", "UTF-8", pack("V", $i)); + $GLOBALS["php_errormsg"] = null; + set_error_handler("null_error_handler"); + //iconv("UTF-8", $charset, $c); + $result = pg_query("SELECT '" . sql_esctext($c) . "';\n"); + restore_error_handler(); + if ($result === false) { + $ords[] = $i; + } + } + + // Get the ranges + for ($i = 0, $prev = -2, $ranges = array(); $i < count($ords); $i++) { + // A new range + if ($ords[$i] != $prev + 1) { + $ranges[] = array($ords[$i], $ords[$i]); + } + // Adjust the end point + $ranges[count($ranges) - 1][1] = $ords[$i]; + $prev = $ords[$i]; + } + + // Convert the ranges to cnvtmap for mb_encode_numericentity() + for ($i = 0, $cnvtmap = array(); $i < count($ranges); $i++) { + $cnvtmap[] = $ranges[$i][0]; + $cnvtmap[] = $ranges[$i][1]; + $cnvtmap[] = 0x000000; + $cnvtmap[] = 0xFFFFFF; + } + + // Output it in a format suitable to be archived + if ($archive) { + echo "\$CNVTMAP[\"invalid\"] = array(\n"; + for ($i = 0; $i < count($cnvtmap); $i += 4) { + printf(" 0x%06X, 0x%06X, 0x%06X, 0x%06X,\n", + $cnvtmap[$i], $cnvtmap[$i+1], $cnvtmap[$i+2], $cnvtmap[$i+3]); + } + echo ");\n"; + } + + // Restore the timeout + ini_set("max_execution_time", $timeout); + return $cnvtmap; +} + + +// +// unicode.inc.php +// +// rest_hcerefs: Restore HTML character entities references in the database +// This is an occational maintainance subroutine. Do not call it +// regularily. Also this will replace all HTML character entities +// references. Stop if you want to preserve any of them. +function rest_hcerefs() +{ + // Preserve the original timeout + $timeout = ini_get("max_execution_time"); + ini_set("max_execution_time", 0); + $t0 = time_hires(); + + // Lock the tables + $tables = sql_tables(); + $locks = array(); + foreach ($tables as $table) { + $locks[$table] = LOCK_EX; + } + sql_lock($locks); + + $sqls = array(); + // Loop each table + foreach ($tables as $table) { + $select = "SELECT * FROM $table;\n"; + $result = sql_query($select); + $count = sql_num_rows($result); + // Loop each record + for ($i = 0; $i < $count; $i++) { + $cur = sql_fetch_assoc($result); + $new = $cur; + $cols = new AddCol($table, ADDCOL_UPDATE); + // Loop each column + foreach (sql_cols($table) as $col) { + // Skip non-string (numbers, boolean) columns + if (!is_string($new[$col])) { + continue; + } + // Read the character references with a_hcref2char() + $new[$col] = a_hcref2char($new[$col]); + $cols->addstr($col, $new[$col], $cur[$col]); + } + if ($cols->modified()) { + printf("%s - %s\n", $table, $cur["sn"]); + $sqls[] = "UPDATE $table " . $cols->ret() + . " WHERE sn=" . $cur["sn"] . ";\n"; + } + } + } + + // Update it + sql_begin(); + for ($i = 0; $i < count($sqls); $i++) { + sql_query($sqls[$i]); + } + sql_commit(); + + // Restore the timeout + ini_set("max_execution_time", $timeout); + $t1 = time_hires(); + printf("[%s] Done. %0.10f seconds elapsed\n", date("Y-m-d H:i:s"), $t1-$t0); + return; +} + + +// +// zh2py.inc.php +// +// The SQLite version - we are not using it + +// test_zh2py_sqlite: Run tests on the speed of GDBM vs. SQLite +function test_zh2py_sqlite() +{ + // Settings + if (!defined("_ZH2PY_SQLITE_DB")) { + define("_ZH2PY_SQLITE_DB", "/tmp/zh2py.db"); + } + $GLOBALS["_ZH2PY_SQLITE"] = null; + + if (!file_exists(_ZH2PY_SQLITE_DB)) { + zh2pydb_gdbm2sqlite(); + } + $phrases = explode(" ", "臺北大塞車 我是依瑪貓 廚王爭霸戰 甜心酥餅 一口接一口 蒙大拿牛仔妹 恐龍入侵台灣 綠巨人玉米醬 小魚的故事 玉山銀行 我的一顆心 牛伯伯沙茶醬 王建民大勝利"); + $count = 4; + $used = array(); + $idx = rand(0, count($phrases) - 1); + $used[] = $idx; + // Open the connection first + zh2pys($phrases[$idx]); + zh2pys_sqlite($phrases[$idx]); + + $suites = array( + array(1, 1), + array(5, 1), + array(1, 4), + array(5, 4), + ); + foreach ($suites as $suite) { + for ($idxs = array(); count($idxs) < $suite[0]; ) { + $idx = rand(0, count($phrases) - 1); + if (!in_array($idx, $used)) { + $used[] = $idx; + $idxs[] = $idx; + } + } + for ($i = 0, $testphrases = array(); $i < count($idxs); $i++) { + $testphrases[] = $phrases[$idxs[$i]]; + } + test_zh2py_sqlite_onetest($testphrases, $suite[1]); + } + + return; +} + +// test_zh2py_sqlite_onetest: Run one GDBM vs. SQLite test suite +function test_zh2py_sqlite_onetest($phrases, $count) +{ + printf("=== Phrase %s for %d times ...\n", join(", ", $phrases), $count); + $t0 = time_hires(); + for ($i = 0; $i < $count; $i++) { + for ($j = 0; $j < count($phrases); $j++) { + zh2pys($phrases[$j]); + } + } + printf("%-16s %0.10f seconds elapsed.\n", "zh2pys():", time_hires()-$t0); + $t0 = time_hires(); + for ($i = 0; $i < $count; $i++) { + for ($j = 0; $j < count($phrases); $j++) { + zh2pys_sqlite($phrases[$j]); + } + } + printf("%-16s %0.10f seconds elapsed.\n", "zh2pys_sqlite():", time_hires()-$t0); + return; +} + +// zh2pydb_gdbm2sqlite: Initialize the zh2py SQLite database from the GDBM database +function zh2pydb_gdbm2sqlite() +{ + global $_ZH2PY, $_ZH2PY_SQLITE; + // Start the database + if (is_null($_ZH2PY)) { + $_ZH2PY = dba_open(_ZH2PY_DB, "r", "gdbm"); + } + // Start the database + if (!is_null($_ZH2PY_SQLITE)) { + sqlite_close($_ZH2PY_SQLITE); + unset($_ZH2PY_SQLITE); + } + if (file_exists(_ZH2PY_SQLITE_DB)) { + unlink(_ZH2PY_SQLITE_DB); + } + if (is_null($_ZH2PY_SQLITE)) { + $error = null; + $_ZH2PY_SQLITE = sqlite_open(_ZH2PY_SQLITE_DB, 0666, $error); + if ($_ZH2PY_SQLITE === false) { + trigger_error("Failed sqlite_open().\n$error", E_USER_ERROR); + } + $error = null; + $create = "CREATE TABLE zh2py (ch varchar(3) NOT NULL, ord int NOT NULL, pinyin varchar(7) NOT NULL);\n"; + $r = sqlite_exec($_ZH2PY_SQLITE, $create, $error); + if ($r === false) { + trigger_error("Failed sqlite_exec().\n$create\n$error", E_USER_ERROR); + } + } + $char = dba_firstkey($_ZH2PY); + while ($char !== false) { + $pinyins = explode("|", dba_fetch($char, $_ZH2PY)); + for ($i = 0; $i < count($pinyins); $i++) { + $error = null; + $insert = "INSERT INTO zh2py (ch, ord, pinyin)" + . " VALUES ('" . sqlite_escape_string($char) . "', $i, '" . sqlite_escape_string($pinyins[$i]) . "');\n"; + $r = sqlite_exec($_ZH2PY_SQLITE, $insert, $error); + if ($r === false) { + trigger_error("Failed sqlite_exec().\n$insert\n$error", E_USER_ERROR); + } + } + $char = dba_nextkey($_ZH2PY); + } + $error = null; + $create = "CREATE INDEX zh2py_char ON zh2py (ch);\n"; + $r = sqlite_exec($_ZH2PY_SQLITE, $create, $error); + if ($r === false) { + trigger_error("Failed sqlite_exec().\n$create\n$error", E_USER_ERROR); + } + return; +} + +// zh2pys_sqlite: Convert Chinese to pinyin, return all possibly pinyins +function zh2pys_sqlite($chinese) +{ + // Bounce the empty text + if ($chinese == "") { + return ""; + } + + // Split text into Chinese or non-Chinese piecess + $pieces = _zh2py_sqlite_split_text($chinese); + + // Convert each piece into a proper printf pattern + $chars = array(); + for ($i = 0; $i < count($pieces); $i++) { + // A Chinese piece + if ($pieces[$i]["is_chinese"]) { + $patterns = array(); + for ($j = 0; $j < mb_strlen($pieces[$i]["text"]); $j++) { + $char = mb_substr($pieces[$i]["text"], $j, 1); + $chars[] = $char; + $patterns[] = "%s"; + } + $pieces[$i]["text"] = implode(" ", $patterns); + // A non-Chinese piece + } else { + // Escape the printf metacharacter + $pieces[$i]["text"] = str_replace("%", "%%", $pieces[$i]["text"]); + } + } + + // Concatenate text pieces + $pinyin = $pieces[0]["text"]; + for ($i = 1; $i < count($pieces); $i++) { + // Insert a space + if ( !preg_match("/\s$/", $pieces[$i-1]["text"]) + && !preg_match("/^\s/", $pieces[$i]["text"])) { + $pinyin .= " "; + } + $pinyin .= $pieces[$i]["text"]; + } + + // Get all the possible pinyins + $chars = _zh2py_sqlite_chars2py($chars); + + $pinyins = array(); + for ($i = 0; $i < count($chars); $i++) { + $pinyins[] = vsprintf($pinyin, $chars[$i]); + } + + return $pinyins; +} + +// _zh2py_sqlite_split_text: Split text into Chinese or non-Chinese piecess +function _zh2py_sqlite_split_text($text) +{ + global $_ZH2PY_SQLITE; + // Start the database + if (is_null($_ZH2PY_SQLITE)) { + $error = null; + $_ZH2PY_SQLITE = sqlite_open(_ZH2PY_SQLITE_DB, 0666, $error); + if ($_ZH2PY_SQLITE === false) { + trigger_error("Failed sqlite_open().\n$error", E_USER_ERROR); + } + } + + // Split into pieces + for ($i = 0, $chars = array(); $i < mb_strlen($text); $i++) { + $chars[] = mb_substr($text, $i, 1); + } + $pieces = array(); + // Tag the first phrase + $error = null; + $select = "SELECT pinyin FROM zh2py" + . " WHERE ch='" . sqlite_escape_string($chars[0]) . "'" + . " LIMIT 1;\n"; + $result = sqlite_query($select, $_ZH2PY_SQLITE, SQLITE_ASSOC, $error); + if ($result === false) { + trigger_error("Failed sqlite_query().\n$select\n$error", E_USER_ERROR); + } + $pieces[] = array( + "is_chinese" => sqlite_num_rows($result) > 0, + "text" => "", + ); + foreach ($chars as $char) { + $error = null; + $select = "SELECT pinyin FROM zh2py" + . " WHERE ch='" . sqlite_escape_string($char) . "'" + . " LIMIT 1;\n"; + $result = sqlite_query($select, $_ZH2PY_SQLITE, SQLITE_ASSOC, $error); + if ($result === false) { + trigger_error("Failed sqlite_query().\n$select\n$error", E_USER_ERROR); + } + // Chinese status changed + if (sqlite_num_rows($result) > 0 xor $pieces[count($pieces)-1]["is_chinese"]) { + // Start a new piece + $pieces[] = array( + "is_chinese" => sqlite_num_rows($result) > 0, + "text" => $char, + ); + } else { + // Append to the current piece + $pieces[count($pieces)-1]["text"] .= $char; + } + } + return $pieces; +} + +// _zh2py_sqlite_chars2py: Loop up a series of Chinese characters +// and return all possible pinyins +function _zh2py_sqlite_chars2py($chars) +{ + global $_ZH2PY_SQLITE; + + // No more characters to work with + if (count($chars) == 0) { + return array(array()); + } + + $char = array_shift($chars); + $error = null; + $select = "SELECT pinyin FROM zh2py" + . " WHERE ch='" . sqlite_escape_string($char) . "'" + . " ORDER BY ord;\n"; + $result = sqlite_query($select, $_ZH2PY_SQLITE, SQLITE_ASSOC, $error); + if ($result === false) { + trigger_error("Failed sqlite_query().\n$select\n$error", E_USER_ERROR); + } + $count = sqlite_num_rows($result); + for ($i = 0, $pinyins = array(); $i < $count; $i++) { + $row = sqlite_fetch_array($result, SQLITE_ASSOC); + $pinyins[] = $row["pinyin"]; + } + $follows = _ZH2PY_SQLITE_chars2py($chars); + $results = array(); + for ($i = 0; $i < count($pinyins); $i++) { + for ($j = 0; $j < count($follows); $j++) { + $results[] = array_merge(array($pinyins[$i]), $follows[$j]); + } + } + + return $results; +} + +?> diff --git a/lib/php/monica/upload.inc.php b/lib/php/monica/upload.inc.php new file mode 100644 index 0000000..adb4390 --- /dev/null +++ b/lib/php/monica/upload.inc.php @@ -0,0 +1,150 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/chkfunc.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/htmlchar.inc.php"; +require_once "monica/newsn.inc.php"; +require_once "monica/mimetype.inc.php"; +require_once "monica/requri.inc.php"; + +// Settings +if (!defined("UPLOAD_DEPOSIT_MAX")) { + define("UPLOAD_DEPOSIT_MAX", 20971520); +} +$FILE_TYPESUF_MAP = array( + "application/vnd.oasis.opendocument.text" => "odt", + "application/vnd.oasis.opendocument.spreadsheet" => "ods", + "application/vnd.oasis.opendocument.presentation" => "odp", + "application/vnd.sun.xml.writer" => "sxw", + "application/vnd.sun.xml.calc" => "sxc", + "application/vnd.sun.xml.impress" => "sxi", + "application/msword" => "doc", + "application/vnd.ms-excel" => "xls", + "application/vnd.ms-powerpoint" => "ppt", + "image/png" => "png", + "image/jpeg" => "jpg", + "image/gif" => "gif", + "application/pdf" => "pdf", + "application/x-zip" => "zip"); + +// suspend_file: Suspend a file to $_SESSION +function suspend_file($file) +{ + $FILES =& file_deposit(); + // Generate a new random file ID + $fileid = new_sn_assoc($FILES); + $file["sn"] = $fileid; + // Save the current file + $FILES[$fileid] =& $file; + // Return the file ID + return $fileid; +} + +// savefile_exists: Check if a file exists +function savefile_exists($sn) +{ + // Check the validity of the serial number first + if (!check_sn($sn)) { + return false; + } + if (!array_key_exists($sn, file_deposit())) { + return false; + } + return true; +} + +// echo_file: Output a file element +function echo_file($file) +{ + $lines = array(); + $lines[] = sprintf(h(C_("MIME file type: %s")), h($file["type"])); + $lines[] = sprintf(h(C_("File name: %s")), h($file["name"])); + $lines[] = sprintf(h(C_("File size: %s bytes")), h($file["size"])); + echo implode("
    \n ", $lines); + return; +} + +// file_deposit: Return the file deposit +function &file_deposit() +{ + // Session in use + if (isset($_SESSION)) { + if (!array_key_exists("savefile", $_SESSION)) { + $_SESSION["savefile"] = array(); + } + return $_SESSION["savefile"]; + + // Session not in use + } else { + static $FILES = array(); + return $FILES; + } +} + +// clear_file_deposit: Clear the file deposit +function clear_file_deposit() +{ + $FILES =& file_deposit(); + $FILES = array(); + return; +} + +// filecache: Return an appropriate fule cache +function &filecache($table) +{ + $FILES =& file_deposit(); + // Package specified + $package = defined("PACKAGE")? PACKAGE: REQUEST_HOST; + if (!array_key_exists("_cache", $FILES)) { + $FILES["_cache"] = array(); + } + if (!array_key_exists($package, $FILES["_cache"])) { + $FILES["_cache"][$package] = array(); + } + if (!array_key_exists($table, $FILES["_cache"][$package])) { + $FILES["_cache"][$package][$table] = array(); + } + return $FILES["_cache"][$package][$table]; +} + +// readfile_content: Read a file from its content into the file deposit +// and return the fileid +function readfile_content($data, $filename, $sugtype, $sn, $table) +{ + $FILES =& file_deposit(); + $filecache =& filecache($table); + + // Cached + if ( array_key_exists($sn, $filecache) + && $data == $FILES[$filecache[$sn]]["content"]) { + $fileid = $filecache[$sn]; + + } else { + // Create the file + $file = array(); + $file["content"] = $data; + $file["type"] = check_mime_type_content($data, $filename, $sugtype); + $file["size"] = strlen($data); + if (!is_null($filename)) { + $file["name"] = $filename; + } + + // Suspend the created picture + $fileid = suspend_file($file); + $filecache[$sn] = $fileid; + } + + return $fileid; +} + +?> diff --git a/lib/php/monica/urlcheck b/lib/php/monica/urlcheck new file mode 100755 index 0000000..9d37e1f --- /dev/null +++ b/lib/php/monica/urlcheck @@ -0,0 +1,100 @@ +#! /usr/bin/perl -w +# {ɦW: urlcheck +# {: Selima ˬd}{ +# {@: ̺ imacat +# Z: 2004-11-06 +# vr: vҦ (c) 2004 ̺ + +use 5.008; +use strict; +use warnings; +use threads; +use threads::shared; +# Prototype declaration +sub main(); +sub check_urls(); +sub check_urls_nonthread(); +sub check_urls_in_a_thread(); +sub is_reachable($); + +use Config qw(%Config); +use LWP::UserAgent; +use Net::Telnet; +use URI; + +our ($CURINDEX, @URLS) : shared; +$CURINDEX = 0; +@URLS = qw(); + + +main; +exit 0; + +sub main() { + local ($_, %_); + + @URLS = ; + chomp foreach @URLS; + check_urls; + print join "", map "$_\n", @URLS; + + return; +} + +# check_urls: Proform URL checks (with threading) +sub check_urls() { + local ($_, %_); + # Run check_urls_nonthread() if ithread is not available + return check_urls_nonthread + if !defined $Config{"useithreads"}; + # Start the thread workers + for ($_ = 0, @_ = qw(); $_ < 10; $_++) { + push @_, threads->new(\&check_urls_in_a_thread) + } + # Wait for everyone to end + $_->join foreach @_; + # Return the result + return; +} + +# check_urls_nonthread: Proform URL checks without threading +sub check_urls_nonthread() { + local ($_, %_); + @URLS = map is_reachable($_), @URLS; + return; +} + +# check_urls_in_a_thread: Proform URL checks in a thread +sub check_urls_in_a_thread() { + local ($_, %_); + # Check until the end + while (($_ = $CURINDEX++) < @URLS) { + $URLS[$_] = is_reachable($URLS[$_]); + } + return; +} + +# is_reachable: Check if the target of an URL is reachable +sub is_reachable($) { + local ($_, %_); + my ($uri, $UA, $r); + $_ = $_[0]; + # Check if it is available + # LWP::UserAgent cannot handle telnet. We check it with Net::Telnet. + if (/^telnet:\/\//) { + $uri = new URI($_); + %_ = ( + Host => $uri->host, + Port => $uri->port, + ); + eval { new Net::Telnet(%_) }; + return ($@ eq ""? 1: 0); + + # Use LWP::UserAgent + } else { + $UA = new LWP::UserAgent; + $UA->timeout(20); + $r = $UA->get($_); + return (!$r->is_error? 1: 0); + } +} diff --git a/lib/php/monica/urlregex.inc.php b/lib/php/monica/urlregex.inc.php new file mode 100644 index 0000000..5a40dbc --- /dev/null +++ b/lib/php/monica/urlregex.inc.php @@ -0,0 +1,38 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/html401.inc.php"; +require_once "monica/rfc1738.inc.php"; +require_once "monica/rfc2396.inc.php"; +require_once "monica/rfc822.inc.php"; + +define("URLREGEX_SCHEME", RFC1738_SCHEME); + +define("URLREGEX_FTP", RFC1738_FTPURL); +define("URLREGEX_FILE", RFC1738_FILEURL); +define("URLREGEX_HTTP", "[hH][tT][tT][pP]:\\/\\/" . RFC2396_SERVER . "(?:" . RFC2396_ABS_PATH . ")?(?:\\?" . RFC2396_QUERY . ")?(?:#" . HTML401_ID . ")?"); +define("URLREGEX_HTTPS", "[hH][tT][tT][pP][sS]:\\/\\/" . RFC2396_SERVER . "(?:" . RFC2396_ABS_PATH . ")?(?:\\?" . RFC2396_QUERY . ")?(?:#" . HTML401_ID . ")?"); +define("URLREGEX_GOPHER", RFC1738_GOPHERURL); +define("URLREGEX_MAILTO", RFC1738_MAILTOURL); +define("URLREGEX_NEWS", RFC1738_NEWSURL); +define("URLREGEX_NNTP", RFC1738_NNTPURL); +define("URLREGEX_TELNET", RFC1738_TELNETURL); +define("URLREGEX_WAIS", RFC1738_WAISURL); +define("URLREGEX_PROSPERO", RFC1738_PROSPEROURL); + +define("URLREGEX_URL", "(?:" . URLREGEX_FTP . "|" . URLREGEX_FILE + . "|" . URLREGEX_HTTP . "|" . URLREGEX_HTTPS . "|" . URLREGEX_GOPHER + . "|" . URLREGEX_MAILTO . "|" . URLREGEX_NEWS . "|" . URLREGEX_NNTP + . "|" . URLREGEX_TELNET . "|" . URLREGEX_WAIS . "|" . URLREGEX_PROSPERO . ")"); +define("URLREGEX_EMAIL", RFC822_ADDR_SPEC); + +?> diff --git a/lib/php/monica/userhome.inc.php b/lib/php/monica/userhome.inc.php new file mode 100644 index 0000000..667a9de --- /dev/null +++ b/lib/php/monica/userhome.inc.php @@ -0,0 +1,41 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/chkpriv.inc.php"; +require_once "monica/guest.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/scptpriv.inc.php"; + +// Administrator's home +if (!defined("NONADMIN_HOME")) { + define("NONADMIN_HOME", "/members/"); +} +if (!defined("ADMIN_HOME")) { + define("ADMIN_HOME", "/admin/"); +} + +// userhome: Return the default user's home +function userhome() +{ + // Not logged-in yet + if (is_null(get_login_sn())) { + return (is_admin_script()? ADMIN_HOME: NONADMIN_HOME) . "login.php"; + // Guest + } elseif (is_guest()) { + return is_admin_script()? ADMIN_HOME: NONADMIN_HOME; + // Ordinary logged-in users + } else { + return is_admin()? ADMIN_HOME: NONADMIN_HOME; + } +} + +?> diff --git a/lib/php/monica/username.inc.php b/lib/php/monica/username.inc.php new file mode 100644 index 0000000..960b1c1 --- /dev/null +++ b/lib/php/monica/username.inc.php @@ -0,0 +1,341 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/chkfunc.inc.php"; +require_once "monica/commtext.inc.php"; +require_once "monica/getlang.inc.php"; +require_once "monica/htmlchar.inc.php"; +require_once "monica/lninfo.inc.php"; +require_once "monica/sql.inc.php"; +require_once "monica/usrconst.inc.php"; + +// username: Obtain a user name +function username($sn) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $sn + if (is_null($sn)) { + return t_notset(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + + // Check the serial number first + if (!check_sn($sn)) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Query + $select = "SELECT name FROM users WHERE sn=$sn;\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$sn] = $row["name"]; + + return $cache[$sn]; +} + +// userid: Obtain a user ID +function userid($sn) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $sn + if (is_null($sn)) { + return t_notset(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + + // Check the serial number first + if (!check_sn($sn)) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Query + $select = "SELECT id FROM users WHERE sn=$sn;\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$sn] = $row["id"]; + + return $cache[$sn]; +} + +// usersn: Obtain a user S/N +// Return null if not available +function usersn($id) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $id + if (is_null($id)) { + return null; + } + // Return the cache + if (array_key_exists($id, $cache)) { + return $cache[$id]; + } + + // Query + $select = "SELECT sn FROM users" + . " WHERE id='" . sql_esctext($id) . "';\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$id] = null; + return $cache[$id]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$id] = $row["sn"]; + + return $cache[$id]; +} + +// groupid: Obtain a group ID +function groupid($sn) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $sn + if (is_null($sn)) { + return t_notset(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + + // Check the serial number first + if (!check_sn($sn)) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Query + $select = "SELECT id FROM groups WHERE sn=$sn;\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$sn] = $row["id"]; + + return $cache[$sn]; +} + +// groupdsc: Obtain a group description +function groupdsc($sn) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $sn + if (is_null($sn)) { + return t_notset(); + } + // Return the cache + if (array_key_exists($sn, $cache)) { + return $cache[$sn]; + } + + // Check the serial number first + if (!check_sn($sn)) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Query + // Unilingual + if (count($GLOBALS["ALL_LINGUAS"]) == 1) { + $col = "dsc AS dsc"; + // Multilingual + } else { + // Default language + if (getlang() == DEFAULT_LANG) { + $col = "dsc_" . getlang(LN_DATABASE) . " AS dsc"; + // Fall back to the default language + } else { + $thiscol = "dsc_" . getlang(LN_DATABASE); + $defcol = "dsc_" . ln(DEFAULT_LANG, LN_DATABASE); + $col = "COALESCE($thiscol, $defcol) AS dsc"; + } + } + $select = "SELECT $col FROM groups WHERE sn=$sn;\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$sn] = t_na(); + return $cache[$sn]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$sn] = $row["dsc"]; + + return $cache[$sn]; +} + +// groupsn: Obtain a group S/N +// Return null if not available +function groupsn($id) +{ + // Cache the result + static $cache = array(); + // Bounce if there is any problem with $id + if (is_null($id)) { + return null; + } + // Return the cache + if (array_key_exists($id, $cache)) { + return $cache[$id]; + } + + // Query + $select = "SELECT sn FROM groups" + . " WHERE id='" . sql_esctext($id) . "';\n"; + $result = sql_query($select); + + // Not found + if (sql_num_rows($result) != 1) { + $cache[$id] = null; + return $cache[$id]; + } + + // Found + $row = sql_fetch_assoc($result); + $cache[$id] = $row["sn"]; + + return $cache[$id]; +} + +// user_opt_label: Obtain a user option label +// Return null when not found +function user_opt_label($sn, $for = null) +{ + // Check the validity of the serial number first + if (!check_sn($sn)) { + return null; + } + $select = "SELECT id, name FROM users" + . " WHERE sn=$sn;\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 1) { + return null; + } + $row = sql_fetch_assoc($result); + if (!is_null($for)) { + return sprintf("", + h($for), h($row["id"]), h($row["name"])); + } else { + return sprintf("%s (%s)", + h($row["id"]), h($row["name"])); + } +} + +// group_opt_label: Obtain a group option label +function group_opt_label($sn, $for = null) +{ + // Check the validity of the serial number first + if (!check_sn($sn)) { + return t_na(); + } + if (count($GLOBALS["ALL_LINGUAS"]) > 1) { + $lndb = getlang(LN_DATABASE); + if (getlang() == DEFAULT_LANG) { + $dsc = "dsc_$lndb AS dsc"; + } else { + $lndbdef = ln(DEFAULT_LANG, LN_DATABASE); + $dsc = "COALESCE(dsc_$lndb, dsc_$lndbdef) AS dsc"; + } + } else { + $dsc = "dsc AS dsc"; + } + $select = "SELECT id, $dsc FROM groups" + . " WHERE sn=$sn;\n"; + $result = sql_query($select); + if (sql_num_rows($result) != 1) { + return t_na(); + } + $row = sql_fetch_assoc($result); + if (!is_null($for)) { + return sprintf("", + h($for), h($row["id"]), h($row["dsc"])); + } else { + return sprintf("%s (%s)", + h($row["id"]), h($row["dsc"])); + } +} + +// su_group_id: Return the ID. of the super user group +function su_group_id() +{ + return SU_GROUP; +} + +// su_group_sn: Return the S/N of the super user group +function su_group_sn() +{ + // Cache the result + static $cache; + // Return the cache + if (isset($cache)) { + return $cache; + } + + // Query + $select = "SELECT * FROM groups" + . " WHERE id='" . sql_esctext(SU_GROUP) . "';\n"; + $result = sql_query($select); + + // Found + if (sql_num_rows($result) == 1) { + $row = sql_fetch_assoc($result); + $cache = $row["sn"]; + // Not found + } else { + $cache = null; + } + + return $cache; +} + +?> diff --git a/lib/php/monica/userpref.inc.php b/lib/php/monica/userpref.inc.php new file mode 100644 index 0000000..d2b2dcb --- /dev/null +++ b/lib/php/monica/userpref.inc.php @@ -0,0 +1,123 @@ + +// Copyright: Copyright (C) 2002-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/guest.inc.php"; +require_once "monica/login.inc.php"; +require_once "monica/requri.inc.php"; +require_once "monica/sql.inc.php"; + +// userpref: Obtain the specified user preference +function userpref($name, $domain = null) +{ + // Cache the result + static $cache = array(); + // Set the default domain + if (is_null($domain)) { + $domain = REQUEST_PATH; + } + // Initialize the cache + if (!array_key_exists($domain, $cache)) { + $cache[$domain] = array(); + } + // Return the cache + if (array_key_exists($name, $cache[$domain])) { + return $cache[$domain][$name]; + } + + // User system not available + if (!use_users() || !isset($_SESSION)) { + if ( array_key_exists("USERPREF", $GLOBALS) + && array_key_exists($domain, $GLOBALS["USERPREF"]) + && array_key_exists($name, $GLOBALS["USERPREF"][$domain])) { + $cache[$domain][$name] = $GLOBALS["USERPREF"][$domain][$name]; + return $cache[$domain][$name]; + } + $cache[$domain][$name] = null; + return null; + } + + // User system is in use + // Check guest preferences in $_SESSION + if (is_guest()) { + // Check the preference on this domain + if ( array_key_exists("userpref", $_SESSION) + && array_key_exists($domain, $_SESSION["userpref"]) + && array_key_exists($name, $_SESSION["userpref"][$domain])) { + $cache[$domain][$name] = $_SESSION["userpref"][$domain][$name]; + return $cache[$domain][$name]; + } + // Check the default preference + if ( array_key_exists("userpref", $_SESSION) + && array_key_exists("*", $_SESSION["userpref"]) + && array_key_exists($name, $_SESSION["userpref"]["*"])) { + $cache[$domain][$name] = $_SESSION["userpref"]["*"][$name]; + return $cache[$domain][$name]; + } + } + + // Already logged in -- check the user preference + if (!is_null(get_login_sn())) { + // Check the user preference on this domain + $select = "SELECT value FROM userpref" + . " WHERE usr=" . get_login_sn() + . " AND domain='" . sql_esctext($domain) . "'" + . " AND name='" . sql_esctext($name) . "';\n"; + $result = sql_query($select); + if (sql_num_rows($result) == 1) { + $row = sql_fetch_assoc($result); + $cache[$domain][$name] = $row["value"]; + return $cache[$domain][$name]; + } + + // Check the default preference of this user + $select = "SELECT value FROM userpref" + . " WHERE usr=" . get_login_sn() + . " AND domain IS NULL" + . " AND name='" . sql_esctext($name) . "';\n"; + $result = sql_query($select); + if (sql_num_rows($result) == 1) { + $row = sql_fetch_assoc($result); + $cache[$domain][$name] = $row["value"]; + return $cache[$domain][$name]; + } + } + + // Check the default preference on this domain + $select = "SELECT value FROM userpref" + . " WHERE usr IS NULL" + . " AND domain='" . sql_esctext($domain) . "'" + . " AND name='" . sql_esctext($name) . "';\n"; + $result = sql_query($select); + if (sql_num_rows($result) == 1) { + $row = sql_fetch_assoc($result); + $cache[$domain][$name] = $row["value"]; + return $cache[$domain][$name]; + } + + // Check the default preference for everything + $select = "SELECT value FROM userpref" + . " WHERE usr IS NULL" + . " AND domain IS NULL" + . " AND name='" . sql_esctext($name) . "';\n"; + $result = sql_query($select); + if (sql_num_rows($result) == 1) { + $row = sql_fetch_assoc($result); + $cache[$domain][$name] = $row["value"]; + return $cache[$domain][$name]; + } + + // Preference not found + $cache[$domain][$name] = null; + return null; +} + +?> diff --git a/lib/php/monica/usrconst.inc.php b/lib/php/monica/usrconst.inc.php new file mode 100644 index 0000000..d309f82 --- /dev/null +++ b/lib/php/monica/usrconst.inc.php @@ -0,0 +1,22 @@ + +// Copyright: Copyright (C) 2006-2007 Pristine Communications + +// Settings +if (!defined("SU_GROUP")) { + define("SU_GROUP", "root"); +} +if (!defined("ADMIN_GROUP")) { + define("ADMIN_GROUP", "admin"); +} +if (!defined("ALLUSERS_GROUP")) { + define("ALLUSERS_GROUP", "users"); +} +if (!defined("ANONYMOUS_USER")) { + define("ANONYMOUS_USER", "anonymous"); +} + +?> diff --git a/lib/php/monica/validate.inc.php b/lib/php/monica/validate.inc.php new file mode 100644 index 0000000..9df0bd3 --- /dev/null +++ b/lib/php/monica/validate.inc.php @@ -0,0 +1,152 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/addget.inc.php"; +require_once "monica/cgiemu.inc.php"; +require_once "monica/gettext.inc.php"; +require_once "monica/htmlchar.inc.php"; +require_once "monica/https.inc.php"; +require_once "monica/ipv4addr.inc.php"; +require_once "monica/pagefunc.inc.php"; +require_once "monica/requri.inc.php"; + +// html_validator: Print the HTML validator buttons +function html_validator($args = null) +{ + // Obtain page parameters + $args = page_param($args); + // This is only for the preview and development website + if ( !(!is_null($args["preview"]) + || (defined("IS_PROD") && !IS_PROD))) { + return; + } + + // Non-static or preview pages - use the validator in the client network + if (!$args["static"] || !is_null($args["preview"])) { + // The client is in the Pristine Network + if ( ipv4_in_network("172.16.168.0/24", $_SERVER["REMOTE_ADDR"]) + || ipv4_in_network("211.78.169.160/29", $_SERVER["REMOTE_ADDR"])) { + $html_validator = "html-validator.pristine.com.tw"; + // The client is in imacat's Network + } elseif ( ipv4_in_network("10.0.0.0/24", $_SERVER["REMOTE_ADDR"]) + || ipv4_in_network("211.20.30.96/29", $_SERVER["REMOTE_ADDR"])) { + $html_validator = "html-validator.imacat.idv.tw"; + // Elsewhere + } else { + $html_validator = "validator.w3.org"; + } + // Static pages on the development site - use the validator in the server network + } elseif (defined("IS_PROD") && !IS_PROD) { + // The server is in the Pristine Network + if ( ipv4_in_network("172.16.168.0/24", $_SERVER["SERVER_ADDR"]) + || ipv4_in_network("211.78.169.160/29", $_SERVER["SERVER_ADDR"])) { + $html_validator = "html-validator.pristine.com.tw"; + // The server is in imacat's Network + } elseif ( ipv4_in_network("10.0.0.0/24", $_SERVER["SERVER_ADDR"]) + || ipv4_in_network("211.20.30.96/29", $_SERVER["SERVER_ADDR"])) { + $html_validator = "html-validator.imacat.idv.tw"; + // Elsewhere + } else { + $html_validator = "validator.w3.org"; + } + } + + // Set the picture host to our same host + $pic_host = REQUEST_SCHEME . "://" . REQUEST_HOST; + if (is_https()) { + if ($_SERVER["SERVER_PORT"] != 443) { + $pic_host .= ":" . $_SERVER["SERVER_PORT"]; + } + } else { + if ($_SERVER["SERVER_PORT"] != 80) { + $pic_host .= ":" . $_SERVER["SERVER_PORT"]; + } + } + + // The HTML version + $htmlver = "XHTML 1.1"; + if (defined("HTML_VERSION")) { + $htmlver = HTML_VERSION; + } + switch ($htmlver) { + // Default to XHTML 1.1 + case "XHTML 1.1": + default: + $htmlbut = "http://$html_validator/images/vxhtml10"; + $htmlver = "XHTML 1.1"; + break; + case "XHTML 1.1": + $htmlbut = "http://$html_validator/images/vxhtml11"; + break; + case "HTML 4.01": + $htmlbut = "http://$html_validator/images/vh401"; + break; + case "HTML 4.0": + $htmlbut = "http://$html_validator/images/vh40"; + break; + case "HTML 3.2": + $htmlbut = "http://$html_validator/images/vh32"; + break; + case "HTML 3.0": + $htmlbut = "http://$html_validator/images/vh30"; + break; + case "HTML 2.0": + $htmlbut = "http://$html_validator/images/vh20"; + break; + } + + if ($args["static"] && is_null($args["preview"])) { + $hvurl = "http://$html_validator/check/referer"; + } else { + $url = REQUEST_FULLURI; + if (isset($_SESSION)) { + $url = add_get_arg($url, session_name(), session_id()); + } + $hvurl = "http://$html_validator/check?uri=" . urlencode($url); + } + $areatitle = C_("HTML Validatior Logo Area"); + $vhtmltitle = C_("HTML validation result of this page"); + $vhtmlalt = sprintf(C_("Valid %s!"), $htmlver); + $vcsstitle = C_("CSS validation result of this page"); + $vcssalt = C_("Valid CSS!"); + $wcag1title = C_("Explanation of Level Triple-A Conformance"); + $wcag1alt = C_("Level Triple-A conformance icon, W3C-WAI Web Content Accessibility Guidelines 1.0"); + +?>
    + hreflang="en"><?php echo h($vhtmlalt); ?>| hreflang="en"><?php echo h($vcssalt); ?>| hreflang="en"><?php echo h($wcag1alt); ?> +
    + + diff --git a/lib/php/monica/xfileio.inc.php b/lib/php/monica/xfileio.inc.php new file mode 100644 index 0000000..62658a9 --- /dev/null +++ b/lib/php/monica/xfileio.inc.php @@ -0,0 +1,173 @@ + +// Copyright: Copyright (C) 2002-2009 Pristine Communications + +// xfread: Read from file +// Input: the file path $file +// Output: the file content +function xfread($file) +{ + $size = filesize($file); + // fread() does not allow reading of 0 bytes now + if ($size == 0) { + return ""; + } + $fp = fopen($file, "r"); + flock($fp, LOCK_SH); + $content = fread($fp, $size); + flock($fp, LOCK_UN); + fclose($fp); + return $content; +} + +// xfwrite: Write to a file +// Input: the file path $file and the file content $content +// Output: none +function xfwrite($file, $content) +{ + $fp = fopen($file, "w"); + flock($fp, LOCK_EX); + fwrite($fp, $content); + flock($fp, LOCK_UN); + fclose($fp); + return; +} + +// xfappend: Append to a file +// Input: the file path $file and the file content $content +// Output: none +function xfappend($file, $content) +{ + // File not exists - create it with xfwrite() + if (!file_exists($file)) { + return xfwrite($file, $content); + } + $fp = fopen($file, "a"); + flock($fp, LOCK_EX); + fwrite($fp, $content); + flock($fp, LOCK_UN); + fclose($fp); + return; +} + +// xfupdate: Update a file +// Input: the file path $file and the file content $newcontent +// Output: none +function xfupdate($file, $newcontent) +{ + // Write as a new file if the old file does not exist + if (!file_exists($file) || filesize($file) != strlen($newcontent)) { + xfwrite($file, $newcontent); + + // Old file exists -- compare the content and update only if necessary + } else { + $size = filesize($file); + $fp = fopen($file, "r+"); + flock($fp, LOCK_EX); + // fread() does not allow reading of 0 bytes now + if ($size == 0) { + $oldcontent = ""; + } else { + $oldcontent = fread($fp, $size); + } + if ($oldcontent != $newcontent) { + fseek($fp, 0, SEEK_SET); + ftruncate($fp, 0); + fwrite($fp, $newcontent); + } + flock($fp, LOCK_UN); + fclose($fp); + } + + // Clear the stat cache to avoid future mistakes like MIME types. + clearstatcache(); + return; +} + +// xfupdate_template: Update a file comparing with a template +// Input: the file path $file, the new content template $tmpl +// and its replacements $rep +// Output: none +function xfupdate_template($file, $tmpl, $rep = null) +{ + // Obtain the replacements + if (is_null($rep)) { + $rep = function_exists("page_replacements")? page_replacements(): + array(); + } + // Write as a new file if the old file does not exist + if (!file_exists($file)) { + $new = $tmpl; + foreach (array_keys($rep) as $key) { + $new = str_replace("", $rep[$key]["content"], $new); + } + xfwrite($file, $new); + + // Old file exists -- compare the content and update only if necessary + } else { + $size = filesize($file); + $fp = fopen($file, "r+"); + flock($fp, LOCK_EX); + if ($size == 0) { + $old = ""; + } else { + $old = fread($fp, filesize($file)); + } + // Not matched + if (_xfileio_template_updated($old, $tmpl, $rep)) { + $new = $tmpl; + foreach (array_keys($rep) as $key) { + $new = str_replace("", $rep[$key]["content"], $new); + } + fseek($fp, 0, SEEK_SET); + ftruncate($fp, 0); + fwrite($fp, $new); + } + flock($fp, LOCK_UN); + fclose($fp); + } + return; +} + +// _xfileio_template_updated: If a page is updated comparing to the template +function _xfileio_template_updated($old, $tmpl, $rep) +{ + // Process piece by piece + while (preg_match("/^(.*?)()(.*)$/s", $tmpl, $m)) { + $plain = $m[1]; + $repsec = $m[2]; + $key = $m[3]; + $tmpl = $m[4]; + + // Try to match the plain text part + if (substr($old, 0, strlen($plain)) != $plain) { + return true; + } + $old = substr($old, strlen($plain)); + + // A valid replacement is found -- try to match the pattern + if (array_key_exists($key, $rep)) { + if (!preg_match("/^" . $rep[$key]["pattern"] . "(.*)$/s", $old, $m)) { + return true; + } + $old = $m[1]; + + // Not a valid replacement -- treat it as a plain text part + } else { + if (substr($old, 0, strlen($repsec)) != $repsec) { + return true; + } + $old = substr($old, strlen($plain)); + } + } + // Check the remains as a plain text part + if ($old != $tmpl) { + return true; + } + return false; +} + +?> diff --git a/lib/php/monica/xhtml.inc.php b/lib/php/monica/xhtml.inc.php new file mode 100644 index 0000000..e604668 --- /dev/null +++ b/lib/php/monica/xhtml.inc.php @@ -0,0 +1,28 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// xhtml_content_type: Check whether application/xhtml+xml or text/html +// should be sent to the client +function xhtml_content_type() +{ + // Browsers that claim to support application/xhtml+xml explicitly + if ( array_key_exists("HTTP_ACCEPT", $_SERVER) + && strpos($_SERVER["HTTP_ACCEPT"], "application/xhtml+xml") !== false) { + return "application/xhtml+xml"; + } + // Browsers that are known to support application/xhtml+xml + if (array_key_exists("HTTP_USER_AGENT", $_SERVER)) { + // W3C validator can recognize application/xhtml+xml + if (substr($_SERVER["HTTP_USER_AGENT"], 0, 13) == "W3C_Validator") { + return "application/xhtml+xml"; + } + } + // Else, we assume that application/xhtml+xml is not supported + return "text/html"; +} + +?> diff --git a/lib/php/monica/zh2py.inc.php b/lib/php/monica/zh2py.inc.php new file mode 100644 index 0000000..9b06f44 --- /dev/null +++ b/lib/php/monica/zh2py.inc.php @@ -0,0 +1,185 @@ + +// Copyright: Copyright (C) 2004-2007 Pristine Communications + +// We use GDBM but not SQLite. SQLite is cross-platform, but it is a lot +// slower than GDBM. SQLite only wins GDBM in connection open speed. + +// Set the include path +if (!defined("INCPATH_SET")) { + require_once dirname(__FILE__) . "/incpath.inc.php"; +} +// Referenced subroutines +require_once "monica/addslash.inc.php"; + +// Settings +if (!defined("DBMDIR")) { + define("DBMDIR", dirname(dirname(dirname(__FILE__))) . "/" . php_uname("m")); +} +define("_ZH2PY_DB", DBMDIR . "/zh2py.db"); +define("_ZH2PY_CHARPAT", "(?:[a-z]|\\xC3[\\xAA\\xBC]){1,6}[1-5]"); +$_ZH2PY = null; + +// zh2py: Convert Chinese to pinyin +function zh2py($chinese) +{ + // Use first result from zh2pys() + $pinyins = zh2pys($chinese); + return $pinyins[0]; +} + +// zh2pys: Convert Chinese to pinyin, return all possibly pinyins +function zh2pys($chinese) +{ + // Bounce the empty text + if ($chinese == "") { + return ""; + } + + // Split text into Chinese or non-Chinese piecess + $pieces = _zh2py_split_text($chinese); + + // Convert each piece into a proper printf pattern + $chars = array(); + for ($i = 0; $i < count($pieces); $i++) { + // A Chinese piece + if ($pieces[$i]["is_chinese"]) { + $patterns = array(); + for ($j = 0; $j < mb_strlen($pieces[$i]["text"]); $j++) { + $char = mb_substr($pieces[$i]["text"], $j, 1); + $chars[] = $char; + $patterns[] = "%s"; + } + $pieces[$i]["text"] = implode(" ", $patterns); + // A non-Chinese piece + } else { + // Escape the printf metacharacter + $pieces[$i]["text"] = str_replace("%", "%%", $pieces[$i]["text"]); + } + } + + // Concatenate text pieces + $pinyin = $pieces[0]["text"]; + for ($i = 1; $i < count($pieces); $i++) { + // Insert a space + if ( !preg_match("/\s$/", $pieces[$i-1]["text"]) + && !preg_match("/^\s/", $pieces[$i]["text"])) { + $pinyin .= " "; + } + $pinyin .= $pieces[$i]["text"]; + } + + // Get all the possible pinyins + $chars = _zh2py_chars2py($chars); + + $pinyins = array(); + for ($i = 0; $i < count($chars); $i++) { + $pinyins[] = vsprintf($pinyin, $chars[$i]); + } + + return $pinyins; +} + +// pinyin_match_chinese: If the pinyin matches the Chinese +function pinyin_match_chinese($chinese, $pinyin) +{ + // Split text into Chinese or non-Chinese piecess + $pieces = _zh2py_split_text($chinese); + + // Convert each piece into a proper perl regular expression pattern + for ($i = 0; $i < count($pieces); $i++) { + // A Chinese piece + if ($pieces[$i]["is_chinese"]) { + $patterns = array(); + for ($j = 0; $j < mb_strlen($pieces[$i]["text"]); $j++) { + $patterns[] = _ZH2PY_CHARPAT; + } + $pieces[$i]["text"] = implode(" ", $patterns); + // A non-Chinese piece + } else { + // Escape the perl regular expression metacharacter + $pieces[$i]["text"] = addslashes_re_php($pieces[$i]["text"]); + } + } + + // Concatenate text pieces + $pattern = $pieces[0]["text"]; + for ($i = 1; $i < count($pieces); $i++) { + // Insert a space + if ( !preg_match("/(?:\s|\\\\[rnt])$/", $pieces[$i-1]["text"]) + && !preg_match("/^(?:\s|\\\\[rnt])/", $pieces[$i]["text"])) { + $pattern .= " "; + } + $pattern .= $pieces[$i]["text"]; + } + + return preg_match("/^$pattern$/", $pinyin)? true: false; +} + +// _zh2py_split_text: Split text into Chinese or non-Chinese piecess +function _zh2py_split_text($text) +{ + global $_ZH2PY; + // Start the database + if (is_null($_ZH2PY)) { + $_ZH2PY = dba_open(_ZH2PY_DB, "r", "gdbm"); + } + + // Split into pieces + for ($i = 0, $chars = array(); $i < mb_strlen($text); $i++) { + $chars[] = mb_substr($text, $i, 1); + } + $pieces = array(); + // Tag the first phrase + $pieces[] = array( + "is_chinese" => dba_exists($chars[0], $_ZH2PY), + "text" => "", + ); + foreach ($chars as $char) { + // Chinese status changed + if (dba_exists($char, $_ZH2PY) xor $pieces[count($pieces)-1]["is_chinese"]) { + // Start a new piece + $pieces[] = array( + "is_chinese" => dba_exists($char, $_ZH2PY), + "text" => $char, + ); + } else { + // Append to the current piece + $pieces[count($pieces)-1]["text"] .= $char; + } + } + return $pieces; +} + +// _zh2py_chars2py: Loop up a series of Chinese characters +// and return all possible pinyins +function _zh2py_chars2py($chars) +{ + global $_ZH2PY; + + // No more characters to work with + if (count($chars) == 0) { + return array(array()); + } + + $char = array_shift($chars); + $pinyins = explode("|", dba_fetch($char, $_ZH2PY)); + $follows = _zh2py_chars2py($chars); + $results = array(); + for ($i = 0; $i < count($pinyins); $i++) { + for ($j = 0; $j < count($follows); $j++) { + $results[] = array_merge(array($pinyins[$i]), $follows[$j]); + } + } + + return $results; +} + +// The SQLite version - we are not using it +// SQLite is not as efficient as GDBM in this case. +// See unused.inc.php + +?> diff --git a/lib/php/monica/zhnum.inc.php b/lib/php/monica/zhnum.inc.php new file mode 100644 index 0000000..0730da6 --- /dev/null +++ b/lib/php/monica/zhnum.inc.php @@ -0,0 +1,115 @@ + +// Copyright: Copyright (C) 2004-2012 Pristine Communications + +// This file is in UTF-8 萬國碼 + +// Settings +define("ZHNUM_DIG", "(?:一|二|三|四|五|六|七|八|九)"); +define("ZHNUM_NUM1D", ZHNUM_DIG); +define("ZHNUM_NUM2D", ZHNUM_DIG . "?十" . ZHNUM_DIG . "?"); +define("ZHNUM_NUM3D", ZHNUM_DIG . "百(?:零" . ZHNUM_DIG . "|十" . ZHNUM_DIG . "?|" . ZHNUM_DIG . "十" . ZHNUM_DIG . "?)?"); +$_ZHNUM = array( + // From Chinese to Arabic number + "一" => 1, + "二" => 2, + "三" => 3, + "四" => 4, + "五" => 5, + "六" => 6, + "七" => 7, + "八" => 8, + "九" => 9, + // From Arabic number to Chinese + 1 => "一", + 2 => "二", + 3 => "三", + 4 => "四", + 5 => "五", + 6 => "六", + 7 => "七", + 8 => "八", + 9 => "九", +); + +// read_zhnum: Read the Chinese number +// Currently we only process 2 digit numbers, 1-99 +function read_zhnum($zhnum) +{ + global $_ZHNUM; + // One digit + if (preg_match("/^" . ZHNUM_DIG . "$/", $zhnum)) { + return $_ZHNUM[$zhnum]; + // Two digits + } elseif (preg_match("/^(" . ZHNUM_DIG . "?)十(" . ZHNUM_DIG . "?)$/", $zhnum, $m)) { + $d2 = ($m[1] == "")? 1: $_ZHNUM[$m[1]]; + $d1 = ($m[2] == "")? 0: $_ZHNUM[$m[2]]; + return $d2 * 10 + $d1; + // Three digits + } elseif (preg_match("/^(" . ZHNUM_DIG . ")百((?:零" . ZHNUM_DIG . "|十" . ZHNUM_DIG . "?|" . ZHNUM_DIG . "十" . ZHNUM_DIG . "?)?)$/", $zhnum, $m)) { + $d3 = $_ZHNUM[$m[1]]; + $r = 0; + if ($m[2] != "") { + $r = $m[2]; + if (substr($r, 0, strlen("零")) == "零") { + $r = substr($r, strlen("零")); + } + $r = read_zhnum($r); + if (!is_integer($r)) { + return $zhnum; + } + } + return $d3 * 100 + $r; + // Bounce others -- we cannot handle them + } else { + return $zhnum; + } +} + +// out_zhnum: Output the Chinese number +// Currently we only process 2 digit numbers, 1-99 +function out_zhnum($num) +{ + global $_ZHNUM; + // One digit + if ($num < 10) { + return $_ZHNUM[$num]; + // Two digits + } elseif ($num < 100) { + $d1 = $num % 10; + $d2 = ($num - $d1) / 10; + $zhnum = ""; + if ($d2 > 1) { + $zhnum .= $_ZHNUM[$d2]; + } + $zhnum .= "十"; + if ($d1 != 0) { + $zhnum .= $_ZHNUM[$d1]; + } + return $zhnum; + // Three digits + } elseif ($num < 1000) { + $r = $num % 100; + $d3 = ($num - $r) / 100; + $zhnum = ""; + $zhnum .= $_ZHNUM[$d3] . "百"; + if ($r < 10 && $r != 0) { + $zhnum .= "零"; + } + if ($r >= 10 && $r < 20) { + $zhnum .= "一"; + } + if ($r != 0) { + $zhnum .= out_zhnum($r); + } + return $zhnum; + // Bounce others -- we cannot handle them + } else { + return $num; + } +} + +?> diff --git a/lib/x86_64/all2simp.db b/lib/x86_64/all2simp.db new file mode 100644 index 0000000..448b440 Binary files /dev/null and b/lib/x86_64/all2simp.db differ diff --git a/lib/x86_64/all2trad.db b/lib/x86_64/all2trad.db new file mode 100644 index 0000000..1836213 Binary files /dev/null and b/lib/x86_64/all2trad.db differ diff --git a/lib/x86_64/b52py.db b/lib/x86_64/b52py.db new file mode 100644 index 0000000..f2525f4 Binary files /dev/null and b/lib/x86_64/b52py.db differ diff --git a/lib/x86_64/ent2u8.db b/lib/x86_64/ent2u8.db new file mode 100644 index 0000000..6a9ff7b Binary files /dev/null and b/lib/x86_64/ent2u8.db differ diff --git a/lib/x86_64/gdbmdump b/lib/x86_64/gdbmdump new file mode 100755 index 0000000..5e69343 --- /dev/null +++ b/lib/x86_64/gdbmdump @@ -0,0 +1,211 @@ +#! /usr/bin/perl -w +# Filename: gdbmdump +# Description: Perl script to load/dump the GDBM database +# Author: imacat +# Date: 2006-05-12 +# Copyright: (c) 2006 imacat + +use 5.6.0; +use strict; +use warnings; +use Data::Dumper qw(); +use Fcntl qw(:flock :seek); +use File::Basename qw(basename); +use GDBM_File qw(GDBM_READER GDBM_WRCREAT); +use Getopt::Long qw(GetOptions); +# Prototype declaration +sub main(); +sub parse_args(); +sub gdbmdump($$); +sub gdbmload($$); +sub xfread($); +sub xfupdate($$); + +use vars qw($THIS_FILE $VERSION $VERBOSE); +$THIS_FILE = basename($0); +$VERSION = "1.10"; +$VERBOSE = 1; + +use vars qw($IS_DUMP $SOURCE $TARGET); + +use vars qw($VERMSG $SHORTHELP $HELPMSG); +$VERMSG = "$THIS_FILE v$VERSION by imacat "; +$SHORTHELP = "Try `$THIS_FILE --help' for more information."; +$HELPMSG = << "EOT"; +Usage: $THIS_FILE --dump|--load [options] source target +Dump/load the GDBM database between different machine types. + + --dump Dump the source GDBM file to the target Data::Dumper output. + --load Load the source Data::Dumper output to the target GDBM file. + -d,--debug Display debug messages. Multiple --debug to debug more. + -q,--quiet Disable debug messages. An opposite that cancels the + effect of --debug. + -h,--help Display this help. + -v,--version Display version number. + source The source file. + target The target file. + +EOT + +main; + +exit 0; + +sub main() { + local ($_, %_); + + # Parse the arguments + parse_args; + + if ($IS_DUMP) { + gdbmdump $SOURCE, $TARGET; + } else { + gdbmload $SOURCE, $TARGET; + } + + print STDERR "Done. " . (time - $^T) . " seconds elapsed.\n" + if $VERBOSE > 0; + return; +} + +# parse_args: Parse the arguments +sub parse_args() { + local ($_, %_); + + # Get the arguments oѼ + eval { + local $SIG{__WARN__} = sub { die $_[0]; }; + Getopt::Long::Configure(qw(no_auto_abbrev bundling)); + GetOptions( "dump"=>sub { $IS_DUMP = 1; }, + "load"=>sub { $IS_DUMP = 0; }, + "debug|d+"=>\$VERBOSE, + "quiet|q"=>sub { $VERBOSE-- if $VERBOSE > 0; }, + "help|h"=>sub { print $HELPMSG; exit 0; }, + "version|v"=>sub { print "$VERMSG\n"; exit 0; }); + }; + die "$THIS_FILE: $@$SHORTHELP\n" if $@ ne ""; + + # Show progress + $| = 1 if $VERBOSE > 2; + + # Check the action type + die "$THIS_FILE: Please specify the action (--dump/--load)\n$SHORTHELP\n" + unless defined $IS_DUMP; + + # Set the source and target directory + die "$THIS_FILE: Please specify the source file\n$SHORTHELP\n" + if @ARGV == 0; + $SOURCE = shift @ARGV; + die "$THIS_FILE: Please specify the target file\n$SHORTHELP\n" + if @ARGV == 0; + $TARGET = shift @ARGV; + + die "$THIS_FILE: Too many arguments: $ARGV[0]\n$SHORTHELP\n" + if @ARGV > 0; + + return; +} + +# gdbmdump: Dump a GDBM database to a Data::Dumper output +sub gdbmdump($$) { + local ($_, %_); + my ($source, $target); + ($source, $target) = @_; + + tie %_, "GDBM_File", $source, &GDBM_READER, 0444 + or die "$THIS_FILE: $source: $!"; + $_ = {%_}; + untie %_; + + xfupdate $target, Data::Dumper->Dump([$_], [qw($_)]); + + return; +} + +# gdbmload: Load a Data::Dumper output to a GDBM database +sub gdbmload($$) { + local ($_, %_); + my ($source, $target); + ($source, $target) = @_; + + eval xfread $source; + + tie %_, "GDBM_File", $target, &GDBM_WRCREAT, 0444 + or die "$THIS_FILE: $source: $!"; + %_ = %$_; + untie %_; + + return; +} + +# xfread: Read from a file +sub xfread($) { + local ($_, %_); + my ($FH, $file); + $file = $_[0]; + + # Return as lines + if (wantarray) { + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + @_ = <$FH>; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return @_; + + # A scalar file content + } else { + # Regular files + if (-f $file) { + my $size; + @_ = stat $file or die "$THIS_FILE: $file: $!"; + $size = $_[7]; + return "" if $size == 0; + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + read $FH, $_, $size or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return $_; + + # Special files + } else { + open $FH, $file or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + $_ = join "", <$FH>; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + return $_; + } + } +} + +# xfupdate: Update a file +sub xfupdate($$) { + local ($_, %_); + my ($FH, $file, $content); + ($file, $content) = @_; + + if (-e $file) { + open $FH, "+<$file" or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_SH or die "$THIS_FILE: $file: $!"; + $_ = join "", <$FH>; + if ($_ ne $content) { + seek $FH, 0, SEEK_SET or die "$THIS_FILE: $file: $!"; + truncate $FH, 0 or die "$THIS_FILE: $file: $!"; + print $FH $content or die "$THIS_FILE: $file: $!"; + } + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + + } else { + open $FH, ">$file" or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_EX or die "$THIS_FILE: $file: $!"; + print $FH $content or die "$THIS_FILE: $file: $!"; + flock $FH, LOCK_UN or die "$THIS_FILE: $file: $!"; + close $FH or die "$THIS_FILE: $file: $!"; + } + return; +} + +__END__ diff --git a/lib/x86_64/hnc2hce.db b/lib/x86_64/hnc2hce.db new file mode 100644 index 0000000..116ea70 Binary files /dev/null and b/lib/x86_64/hnc2hce.db differ diff --git a/lib/x86_64/u82ent.db b/lib/x86_64/u82ent.db new file mode 100644 index 0000000..c4f3ccd Binary files /dev/null and b/lib/x86_64/u82ent.db differ diff --git a/lib/x86_64/zh2py.db b/lib/x86_64/zh2py.db new file mode 100644 index 0000000..5c78bed Binary files /dev/null and b/lib/x86_64/zh2py.db differ diff --git a/lib/x86_64/zh2zy.db b/lib/x86_64/zh2zy.db new file mode 100644 index 0000000..bac6303 Binary files /dev/null and b/lib/x86_64/zh2zy.db differ diff --git a/locale/de_DE/LC_MESSAGES/monica.mo b/locale/de_DE/LC_MESSAGES/monica.mo new file mode 100644 index 0000000..9f95491 Binary files /dev/null and b/locale/de_DE/LC_MESSAGES/monica.mo differ diff --git a/locale/es_ES/LC_MESSAGES/monica.mo b/locale/es_ES/LC_MESSAGES/monica.mo new file mode 100644 index 0000000..8a500f3 Binary files /dev/null and b/locale/es_ES/LC_MESSAGES/monica.mo differ diff --git a/locale/ja_JP/LC_MESSAGES/monica.mo b/locale/ja_JP/LC_MESSAGES/monica.mo new file mode 100644 index 0000000..e4a1580 Binary files /dev/null and b/locale/ja_JP/LC_MESSAGES/monica.mo differ diff --git a/locale/ko_KR/LC_MESSAGES/monica.mo b/locale/ko_KR/LC_MESSAGES/monica.mo new file mode 100644 index 0000000..4ae88a7 Binary files /dev/null and b/locale/ko_KR/LC_MESSAGES/monica.mo differ diff --git a/locale/zh_CN/LC_MESSAGES/monica.mo b/locale/zh_CN/LC_MESSAGES/monica.mo new file mode 100644 index 0000000..77f3dca Binary files /dev/null and b/locale/zh_CN/LC_MESSAGES/monica.mo differ diff --git a/locale/zh_CN/LC_MESSAGES/selima.mo b/locale/zh_CN/LC_MESSAGES/selima.mo new file mode 100644 index 0000000..a235308 Binary files /dev/null and b/locale/zh_CN/LC_MESSAGES/selima.mo differ diff --git a/locale/zh_TW/LC_MESSAGES/monica.mo b/locale/zh_TW/LC_MESSAGES/monica.mo new file mode 100644 index 0000000..f979ebf Binary files /dev/null and b/locale/zh_TW/LC_MESSAGES/monica.mo differ diff --git a/locale/zh_TW/LC_MESSAGES/selima.mo b/locale/zh_TW/LC_MESSAGES/selima.mo new file mode 100644 index 0000000..722fe55 Binary files /dev/null and b/locale/zh_TW/LC_MESSAGES/selima.mo differ diff --git a/po/monica/Makefile b/po/monica/Makefile new file mode 100644 index 0000000..573c9b1 --- /dev/null +++ b/po/monica/Makefile @@ -0,0 +1,53 @@ +# Possible make targets: +# all: Compile the PO files and copy the binary MO files +# into the appropriate directories +# xgettext: Obtain the newest PO template file $(PACKAGE).pot +# from the source programs, and do msgmerge to compare +# the $(PACKAGE).pot and existing PO files to obtain +# the newest POX files to work with + + +PACKAGE = monica +ALLLINGUAS = zh_TW zh_CN de_DE ja_JP ko_KR es_ES +PKGROOT = ../.. +PODIR = po/monica +LOCALEDIR = $(PKGROOT)/locale +CATEGORY = LC_MESSAGES +PROGRAMS = lib/php/monica/*.inc.php + +all: + opencc -c tw2sp.json -i zh_TW.po -o /dev/stdout \ + | sed "s/^# Traditional Chinese PO file for the /# Simplified Chinese PO file for the /" \ + | sed "s/^\"PO-Revision-Date: .*\"/\"PO-Revision-Date: `date \"+%Y-%m-%d %H:%M%z\"`\\\\n\"/" \ + > zh_CN.po; \ + for ln in $(ALLLINGUAS); do \ + msgfmt $$ln.po -o $$ln.gmo; \ + test -d $(LOCALEDIR) || \ + (rm -rf $(LOCALEDIR) && \ + mkdir $(LOCALEDIR)); \ + test -d $(LOCALEDIR)/$$ln || \ + (rm -rf $(LOCALEDIR)/$$ln && \ + mkdir $(LOCALEDIR)/$$ln); \ + test -d $(LOCALEDIR)/$$ln/$(CATEGORY) || \ + (rm -rf $(LOCALEDIR)/$$ln/$(CATEGORY) && \ + mkdir $(LOCALEDIR)/$$ln/$(CATEGORY)); \ + rm -f $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + cp $$ln.gmo $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + done + +xgettext: + cd $(PKGROOT); \ + xgettext --keyword=_ --keyword=C_ --keyword=N_ --keyword=NC_ --keyword=Nn_:1,2 --keyword=NCn_:1,2 -p $(PODIR)/ -o $(PACKAGE).pot \ + --language=c $(PROGRAMS); \ + cd $(PODIR); \ + for ln in $(ALLLINGUAS); do \ + case $$ln in \ + ja_JP) \ + msgmerge $$ln.utf8.po $(PACKAGE).pot > $$ln.utf8.pox; ;; \ + *) \ + msgmerge $$ln.po $(PACKAGE).pot > $$ln.pox; ;; \ + esac; \ + done + +clean: + rm -f *.gmo diff --git a/po/monica/de_DE.gmo b/po/monica/de_DE.gmo new file mode 100644 index 0000000..9f95491 Binary files /dev/null and b/po/monica/de_DE.gmo differ diff --git a/po/monica/de_DE.po b/po/monica/de_DE.po new file mode 100644 index 0000000..43fdca6 --- /dev/null +++ b/po/monica/de_DE.po @@ -0,0 +1,3763 @@ +# German PO file for the monica core +# Copyright (C) 2003-2018 Pristine Commnications +# This file is distributed under the same license as the monica package. +# imacat , 2003-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: monica 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 12:42+0800\n" +"PO-Revision-Date: 2018-11-02 01:22+0800\n" +"Last-Translator: Volker Lehmacher \n" +"Language-Team: German \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: lib/php/monica/checker.inc.php:159 +msgid "Please select a user." +msgstr "Bitte Anwender wählen" + +#: lib/php/monica/checker.inc.php:163 +msgid "This user does not exist anymore. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:181 +msgid "Please select a group." +msgstr "Bitte wählen Sie eine Gruppe." + +# admin/userpriv.php:266, admin/groups.php:724 +#: lib/php/monica/checker.inc.php:185 +msgid "This group does not exist anymore. Please select another one." +msgstr "Diese Gruppe existiert nicht mehr. Wählen Sie bitte eine andere." + +#: lib/php/monica/checker.inc.php:203 +#, fuzzy +msgid "Please fill in the script." +msgstr "Bitte Beschreibung eingeben." + +#: lib/php/monica/checker.inc.php:207 +#, c-format +msgid "This script is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für dieses Script ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:212 +msgid "This script is not a valid script. Please specify another one." +msgstr "Dieses Script ist kein gültiges Script. Wählen Sie bitte ein anderes." + +#: lib/php/monica/checker.inc.php:230 +msgid "Please fill in the date." +msgstr "Bitte geben Sie das Datum ein. " + +#: lib/php/monica/checker.inc.php:234 lib/php/monica/checker.inc.php:238 +#: lib/php/monica/checker.inc.php:241 +#, fuzzy +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "Bitte geben Sie das Enddatum im Format YYYY-MM-DD ein." + +#: lib/php/monica/checker.inc.php:259 +msgid "Please fill in the ID." +msgstr "Bitte ID eingeben." + +#: lib/php/monica/checker.inc.php:263 +#, c-format +msgid "This ID. is too long. (Max. length %d)" +msgstr "Die Eingabe für diese ID ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:267 +#, c-format +msgid "This ID. is too short. (Min. length %d)" +msgstr "Die Eingabe für diese ID ist zu kurz (Die minimale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:272 +#, fuzzy +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "" +"Die ID darf nur aus klein geschriebenen Buchstaben und Unterstrichen " +"bestehen." + +#: lib/php/monica/checker.inc.php:294 +msgid "Please fill in the order." +msgstr "Bitte geben Sie die Reihenfolge ein." + +#: lib/php/monica/checker.inc.php:298 +#, c-format +msgid "This order is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Reihenfolge ist zu lang. (Die maximale Länge beträgt %" +"d)" + +#: lib/php/monica/checker.inc.php:303 +#, fuzzy +msgid "Please fill in a positive integer order." +msgstr "Bitte geben Sie die Reihenfolge ein." + +#: lib/php/monica/checker.inc.php:307 lib/php/monica/checker.inc.php:317 +#, c-format +msgid "" +"The order is too small. Please fill in a larger order between %d and %d." +msgstr "" +"Die Eingabe für die Reihenfolge ist zu klein. Bitte geben Sie eine größere " +"Reihenfolge zwischen %d und %d ein." + +#: lib/php/monica/checker.inc.php:321 +#, c-format +msgid "" +"The order is too large. Please fill in a smaller order between %d and %d." +msgstr "" +"Die Eingabe für die Reihenfolge ist zu lang. Bitte geben Sie eine kleinere " +"Reihenfolge zwischen %d und %d ein." + +#: lib/php/monica/checker.inc.php:348 +#, fuzzy +msgid "Please fill in the page path." +msgstr "Bitte geben Sie den Speicherplatz ein." + +#: lib/php/monica/checker.inc.php:352 +#, fuzzy, c-format +msgid "This page path is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Speicherplatz ist zu lang (Die maximale Länge beträgt " +"%d)." + +#: lib/php/monica/checker.inc.php:365 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "Diese Seite besteht bereits. Sie können kein Duplikat erstellen." + +#: lib/php/monica/checker.inc.php:369 +#, fuzzy +msgid "Please fill in an absolute page path." +msgstr "Bitte geben Sie den Speicherplatz ein." + +#: lib/php/monica/checker.inc.php:373 +#, fuzzy +msgid "Please fill in a valid page path." +msgstr "Bitte geben Sie ein gültiges Enddatum ein." + +#: lib/php/monica/checker.inc.php:377 +msgid "You cannot overwrite the cover home page." +msgstr "Sie können die Titelseite nicht überschreiben." + +#: lib/php/monica/checker.inc.php:381 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "" + +#: lib/php/monica/checker.inc.php:422 lib/php/monica/checker.inc.php:428 +#, fuzzy +msgid "Please fill in the attachment description." +msgstr "Bitte Beschreibung eingeben." + +#: lib/php/monica/checker.inc.php:432 +#, fuzzy, c-format +msgid "This attachment description is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für die Beschreibung ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:449 +#, fuzzy +msgid "This PDF. file does not exist anymore. Please upload another one." +msgstr "Dieser Bereich existiert nicht mehr. Wählen Sie bitte einen anderen." + +#: lib/php/monica/checker.inc.php:456 +#, fuzzy, c-format +msgid "This PDF. file is too large. (Max. size %s)" +msgstr "" +"Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:461 +#, fuzzy +msgid "Please upload only PDF. file." +msgstr "Bitte geben Sie den Titel ein." + +#: lib/php/monica/checker.inc.php:479 +msgid "Please fill in the title." +msgstr "Bitte geben Sie den Titel ein." + +#: lib/php/monica/checker.inc.php:483 +#, c-format +msgid "This title is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:502 +#, fuzzy +msgid "Please fill in the subject." +msgstr "Bitte die Kursgebühren eingeben." + +#: lib/php/monica/checker.inc.php:506 +#, fuzzy, c-format +msgid "This subject is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für dieses Script ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:524 lib/php/monica/form.inc.php:3159 +#: lib/php/monica/form.inc.php:3172 +#, fuzzy +msgid "Fill in the content here." +msgstr "Bitte geben Sie den Inhalt ein." + +#: lib/php/monica/checker.inc.php:528 +msgid "Please fill in the content." +msgstr "Bitte geben Sie den Inhalt ein." + +#: lib/php/monica/checker.inc.php:532 +#, c-format +msgid "This content is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Inhalt ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:551 +msgid "Please fill in the keywords." +msgstr "Bitte geben Sie die Stichwörter ein." + +#: lib/php/monica/checker.inc.php:555 +#, c-format +msgid "This keyword list is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Stichwörter ist zu lang (Die maximale Länge beträgt %" +"d)." + +#: lib/php/monica/checker.inc.php:572 +#, fuzzy +msgid "Please select a proper pinyin." +msgstr "Bitte wählen Sie eine Gruppe." + +#: lib/php/monica/checker.inc.php:578 +#, fuzzy, c-format +msgid "This pinyin is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Inhalt ist zu lang (Die maximale Länge beträgt %d)." + +# admin/userpriv.php:266, admin/groups.php:724 +#: lib/php/monica/checker.inc.php:583 +#, fuzzy +msgid "" +"This pinyin does not match the Chinese. Please select a proper pinyin from " +"the list." +msgstr "Diese Gruppe existiert nicht mehr. Wählen Sie bitte eine andere." + +#: lib/php/monica/checker.inc.php:609 lib/php/monica/pic.inc.php:82 +#, fuzzy +msgid "Please upload the picture." +msgstr "Bitte Kategorie wählen." + +#: lib/php/monica/checker.inc.php:616 lib/php/monica/checker.inc.php:3214 +#, fuzzy +msgid "This picture does not exist anymore. Please upload another one." +msgstr "Dieser Bereich existiert nicht mehr. Wählen Sie bitte einen anderen." + +#: lib/php/monica/checker.inc.php:622 +#, fuzzy, c-format +msgid "This picture is too large. Please upload another one. (Max. size %d)" +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:639 lib/php/monica/form.inc.php:3588 +#, fuzzy, c-format +msgid "Please upload a new picture from %s." +msgstr "Bitte neue Seite aus %s erschaffen." + +#: lib/php/monica/checker.inc.php:664 lib/php/monica/checker.inc.php:727 +#, fuzzy +msgid "Please fill in the picture caption." +msgstr "Bitte geben Sie die Einführung ein." + +#: lib/php/monica/checker.inc.php:668 lib/php/monica/checker.inc.php:731 +#, fuzzy, c-format +msgid "This picture caption is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Einführung ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:686 lib/php/monica/checker.inc.php:749 +#, fuzzy +msgid "Please select the picture position." +msgstr "Bitte Kategorie wählen." + +#: lib/php/monica/checker.inc.php:692 lib/php/monica/checker.inc.php:755 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:791 lib/php/monica/checker.inc.php:794 +#, fuzzy, c-format +msgid "Your uploaded file is too large (Max %s)." +msgstr "" +"Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:797 lib/php/monica/pic.inc.php:80 +msgid "" +"Upload not completed. Disk may be full or connection may be closed in the " +"half. You may try to upload again, or contact the system administrator for " +"this problem." +msgstr "" + +#: lib/php/monica/checker.inc.php:799 lib/php/monica/pic.inc.php:84 +#, c-format +msgid "Upload failed with an unknown error (%d)." +msgstr "" + +#: lib/php/monica/checker.inc.php:1183 lib/php/monica/chkfunc.inc.php:59 +#: lib/php/monica/chkfunc.inc.php:72 lib/php/monica/preview.inc.php:29 +#, c-format +msgid "The following field was not received: \"%s\"." +msgstr "Das folgende Feld wurde nicht erhalten: \"%s\"." + +#: lib/php/monica/checker.inc.php:1262 +msgid "Please fill in the user ID." +msgstr "Bitte Benutzernamen eingeben." + +#: lib/php/monica/checker.inc.php:1266 +#, c-format +msgid "This user ID. is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Benutzernamen ist zu lang (Die maximale Länge beträgt " +"%d)." + +#: lib/php/monica/checker.inc.php:1270 +#, c-format +msgid "This user ID. is too short. (Min. length %d)" +msgstr "" +"Die Eingabe für diesen Benutzernamen ist zu kurz (Die minimale Länge beträgt " +"%d)." + +#: lib/php/monica/checker.inc.php:1275 +#, fuzzy +msgid "" +"Only lower-case English letters, numbers, at-signs, dots, dashes and " +"underscores are allowed for the user ID." +msgstr "" +"Die ID darf nur aus klein geschriebenen Buchstaben und Unterstrichen " +"bestehen." + +#: lib/php/monica/checker.inc.php:1287 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "" +"Dieser Anwender hat bereits einen Account. Sie können kein Duplikat " +"erstellen." + +#: lib/php/monica/checker.inc.php:1317 +msgid "Please fill in the password." +msgstr "Bitte Passwort eingeben." + +#: lib/php/monica/checker.inc.php:1320 +msgid "Please confirm the password." +msgstr "Bitte Passwort bestätigen." + +#: lib/php/monica/checker.inc.php:1324 +#, c-format +msgid "This password is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für dieses Passwort ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:1329 +#, c-format +msgid "This password is too short. (Min. length %d)" +msgstr "" +"Die Eingabe für dieses Passwort ist zu kurz (Die minimale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:1334 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "" + +#: lib/php/monica/checker.inc.php:1345 +msgid "This password is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1360 +msgid "This password does not contain enough different characters." +msgstr "" + +#: lib/php/monica/checker.inc.php:1364 +msgid "This password is too simplistic/systematic." +msgstr "" + +#: lib/php/monica/checker.inc.php:1368 +msgid "This password is based on a dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1370 +msgid "This password is based on a (reversed) dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1372 +#, fuzzy +msgid "This password is too simple." +msgstr "" +"Die Eingabe für dieses Passwort ist zu kurz (Die minimale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:1378 +#, fuzzy +msgid "You cannot use a password that is based on the user ID." +msgstr "" +"Die ID darf nur aus klein geschriebenen Buchstaben und Unterstrichen " +"bestehen." + +#: lib/php/monica/checker.inc.php:1397 +#, fuzzy +msgid "Please fill in the name." +msgstr "Bitte geben Sie das Datum ein. " + +#: lib/php/monica/checker.inc.php:1401 +#, fuzzy, c-format +msgid "This name is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen vollen Namen ist zu lang (Die maximale Länge beträgt %" +"d)." + +#: lib/php/monica/checker.inc.php:1420 +#, fuzzy +msgid "Please fill in the e-mail." +msgstr "Bitte geben Sie den Titel ein." + +#: lib/php/monica/checker.inc.php:1424 +#, fuzzy, c-format +msgid "This e-mail is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:1428 +#, fuzzy, c-format +msgid "This e-mail is too short. (Min. length %d)" +msgstr "Die Eingabe für diese ID ist zu kurz (Die minimale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:1437 +#, fuzzy +msgid "Please fill in a valid e-mail address." +msgstr "Bitte geben Sie ein gültiges Enddatum ein." + +#: lib/php/monica/checker.inc.php:1439 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:1461 lib/php/monica/checker.inc.php:1655 +#, fuzzy +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#: lib/php/monica/checker.inc.php:1478 +msgid "You cannot submit the super-user group along with other groups." +msgstr "" + +#: lib/php/monica/checker.inc.php:1480 +msgid "You cannot set the administrators group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1482 +#, fuzzy +msgid "You cannot set the all-users group." +msgstr "Sie können die Titelseite nicht überschreiben." + +#: lib/php/monica/checker.inc.php:1515 +msgid "Please fill in the group ID." +msgstr "Geben Sie bitte die Gruppen-ID ein." + +#: lib/php/monica/checker.inc.php:1519 +#, c-format +msgid "This group ID. is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Gruppen-ID ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:1523 +#, fuzzy, c-format +msgid "This group ID. is too short. (Min. length %d)" +msgstr "Die Eingabe für diese ID ist zu kurz (Die minimale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:1528 +#, fuzzy +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "" +"Die ID darf nur aus klein geschriebenen Buchstaben und Unterstrichen " +"bestehen." + +#: lib/php/monica/checker.inc.php:1540 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#: lib/php/monica/checker.inc.php:1558 +msgid "Please fill in the privilege description." +msgstr "Geben Sie bitte die Berechtigungs-Beschreibung ein." + +#: lib/php/monica/checker.inc.php:1562 +#, c-format +msgid "This privilege description is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Berechtigungs-Beschreibung ist zu lang. (Die maximale " +"Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:1585 +#, fuzzy +msgid "This user member is duplicated. You cannot set duplicated ones." +msgstr "" +"Dieser Anwender hat bereits einen Account. Sie können kein Duplikat " +"erstellen." + +#: lib/php/monica/checker.inc.php:1620 +#, fuzzy +msgid "This group member is duplicated. You cannot set duplicated ones." +msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#: lib/php/monica/checker.inc.php:1747 lib/php/monica/checker.inc.php:1855 +#, fuzzy +msgid "Please select a member." +msgstr "Bitte Anwender wählen" + +#: lib/php/monica/checker.inc.php:1751 lib/php/monica/checker.inc.php:1859 +#, fuzzy +msgid "This member does not exist anymore. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:1770 lib/php/monica/checker.inc.php:1883 +#, fuzzy +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "" +"Diese Anwender-Einstellung existiert bereits. Sie können kein Duplikat " +"erstellen." + +#: lib/php/monica/checker.inc.php:1837 +#, fuzzy +msgid "Please select a different belonging group." +msgstr "Bitte Gruppe auswählen." + +#: lib/php/monica/checker.inc.php:1864 +#, fuzzy +msgid "Please select a different group member." +msgstr "Bitte wählen Sie eine Gruppe." + +#: lib/php/monica/checker.inc.php:1958 +msgid "" +"This script privilege already exists. You cannot create a duplicated one." +msgstr "" +"Diese Script-Berechtigung existiert bereits. Sie können kein Duplikat " +"erstellen." + +#: lib/php/monica/checker.inc.php:1996 lib/php/monica/checker.inc.php:2184 +msgid "Please select the user." +msgstr "Bitte Anwender wählen." + +# admin/userpriv.php:266, admin/groups.php:724 +#: lib/php/monica/checker.inc.php:2002 lib/php/monica/checker.inc.php:2190 +#, fuzzy +msgid "This option is invalid. Please select a proper user." +msgstr "Diese Gruppe existiert nicht mehr. Wählen Sie bitte eine andere." + +#: lib/php/monica/checker.inc.php:2020 +#, fuzzy +msgid "Please set the preference domain." +msgstr "Bitte einen Einstellungs-Namen eingeben." + +# admin/userpriv.php:266, admin/groups.php:724 +#: lib/php/monica/checker.inc.php:2026 +#, fuzzy +msgid "This option is invalid. Please set a proper preference domain." +msgstr "Diese Gruppe existiert nicht mehr. Wählen Sie bitte eine andere." + +#: lib/php/monica/checker.inc.php:2039 lib/php/monica/checker.inc.php:2295 +#, fuzzy +msgid "Please fill in the preference domain." +msgstr "Bitte einen Einstellungs-Namen eingeben." + +#: lib/php/monica/checker.inc.php:2043 lib/php/monica/checker.inc.php:2299 +#, fuzzy, c-format +msgid "This preference domain is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Einstellungs-Namen ist zu lang (Die maximale Länge " +"beträgt %d)." + +#: lib/php/monica/checker.inc.php:2063 +msgid "Please fill in the preference name." +msgstr "Bitte einen Einstellungs-Namen eingeben." + +#: lib/php/monica/checker.inc.php:2067 +#, c-format +msgid "This preference name is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Einstellungs-Namen ist zu lang (Die maximale Länge " +"beträgt %d)." + +#: lib/php/monica/checker.inc.php:2086 +msgid "Please fill in the preference value." +msgstr "Bitte einen Einstellungs-Wert eingeben." + +#: lib/php/monica/checker.inc.php:2090 +#, c-format +msgid "This preference value is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Einstellungs-Wert ist zu lang (Die maximale Länge " +"beträgt %d)." + +#: lib/php/monica/checker.inc.php:2119 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "" +"Diese Anwender-Einstellung existiert bereits. Sie können kein Duplikat " +"erstellen." + +#: lib/php/monica/checker.inc.php:2167 +#, fuzzy +msgid "Please select the request type." +msgstr "Bitte Anwender wählen." + +# admin/userpriv.php:266, admin/groups.php:724 +#: lib/php/monica/checker.inc.php:2173 +#, fuzzy +msgid "This option is invalid. Please select a proper request type." +msgstr "Diese Gruppe existiert nicht mehr. Wählen Sie bitte eine andere." + +#: lib/php/monica/checker.inc.php:2194 +msgid "You must choose anonymous for join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2197 +msgid "You cannot choose anonymous for non-join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2221 lib/php/monica/form.inc.php:5484 +#, fuzzy +msgid "Please fill in the request arguments list here." +msgstr "Bitte einen Einstellungs-Wert eingeben." + +#: lib/php/monica/checker.inc.php:2229 +#, fuzzy, c-format +msgid "This request arguments list is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Stichwörter ist zu lang (Die maximale Länge beträgt %" +"d)." + +#: lib/php/monica/checker.inc.php:2349 +#, fuzzy +msgid "Please fill in the number of rows per page." +msgstr "Bitte Benutzernamen eingeben." + +#: lib/php/monica/checker.inc.php:2353 +#, fuzzy, c-format +msgid "This number of rows per page is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Reihenfolge ist zu lang. (Die maximale Länge beträgt %" +"d)" + +#: lib/php/monica/checker.inc.php:2358 +#, fuzzy +msgid "Please fill in a positive integer number of rows per page." +msgstr "Bitte geben Sie die Reihenfolge ein." + +#: lib/php/monica/checker.inc.php:2362 lib/php/monica/checker.inc.php:2372 +#, fuzzy, c-format +msgid "" +"The number of rows per page is too small. Please fill in a larger number of " +"rows per page between %d and %d." +msgstr "" +"Die Eingabe für die Reihenfolge ist zu klein. Bitte geben Sie eine größere " +"Reihenfolge zwischen %d und %d ein." + +#: lib/php/monica/checker.inc.php:2376 +#, fuzzy, c-format +msgid "" +"The number of rows per page is too large. Please fill in a smaller number " +"of rows per page between %d and %d." +msgstr "" +"Die Eingabe für die Reihenfolge ist zu lang. Bitte geben Sie eine kleinere " +"Reihenfolge zwischen %d und %d ein." + +#: lib/php/monica/checker.inc.php:2443 +msgid "Please fill in your user ID." +msgstr "Bitte Benutzernamen eingeben." + +#: lib/php/monica/checker.inc.php:2451 lib/php/monica/checker.inc.php:2458 +#: lib/php/monica/checker.inc.php:2475 lib/php/monica/checker.inc.php:2508 +#: lib/php/monica/checker.inc.php:2540 lib/php/monica/checker.inc.php:2548 +#: lib/php/monica/checker.inc.php:2558 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "" +"Anmeldung fehlgeschlagen. Der Benutzername oder das Passwort stimmt nicht." + +#: lib/php/monica/checker.inc.php:2495 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "" +"Ihr Account wurde deaktiviert. Wenden Sie sich an Ihren Systemadministrator." + +#: lib/php/monica/checker.inc.php:2531 +msgid "Please fill in your password." +msgstr "Bitte Passwort eingeben." + +#: lib/php/monica/checker.inc.php:2581 +#, fuzzy +msgid "You are not an administrator so may not log in here." +msgstr "Sie sind kein Administrator und können sich hier nicht anmelden." + +#: lib/php/monica/checker.inc.php:2600 +#, fuzzy +msgid "You are an administrator so may not log in here." +msgstr "Sie sind kein Administrator und können sich hier nicht anmelden." + +#: lib/php/monica/checker.inc.php:2751 +#, fuzzy +msgid "Please fill in the code." +msgstr "Bitte geben Sie die Reihenfolge ein." + +#: lib/php/monica/checker.inc.php:2755 +#, c-format +msgid "You must fill in a %d-letters code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2760 +#, fuzzy +msgid "You can only use upper letters and for the code." +msgstr "" +"Die ID darf nur aus klein geschriebenen Buchstaben und Unterstrichen " +"bestehen." + +#: lib/php/monica/checker.inc.php:2772 +#, fuzzy +msgid "This code is duplicated. You cannot create a duplicated one." +msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#: lib/php/monica/checker.inc.php:2790 +#, fuzzy +msgid "Please fill in the country name." +msgstr "Bitte vollen Namen eintragen." + +#: lib/php/monica/checker.inc.php:2794 +#, fuzzy, c-format +msgid "This country name is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen vollen Namen ist zu lang (Die maximale Länge beträgt %" +"d)." + +#: lib/php/monica/checker.inc.php:2822 lib/php/monica/checker.inc.php:2841 +#, fuzzy +msgid "Please select a parent category." +msgstr "Bitte Anwender wählen" + +# admin/userpriv.php:266, admin/groups.php:724 +#: lib/php/monica/checker.inc.php:2828 +#, fuzzy +msgid "This option is invalid. Please select a proper parent category." +msgstr "Diese Gruppe existiert nicht mehr. Wählen Sie bitte eine andere." + +#: lib/php/monica/checker.inc.php:2845 +#, fuzzy +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:2850 +#, fuzzy +msgid "A category cannot belong to itself. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:2858 +#, fuzzy +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:2876 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:2894 +#, fuzzy +msgid "This category already exists. You cannot create a duplicated one." +msgstr "Diese Seite besteht bereits. Sie können kein Duplikat erstellen." + +#: lib/php/monica/checker.inc.php:2941 +#, fuzzy +msgid "Please fill in the URL.." +msgstr "Bitte URL eingeben." + +#: lib/php/monica/checker.inc.php:2945 +#, fuzzy, c-format +msgid "This URL. is too long. (Max. length %d)" +msgstr "Die Eingabe für diese URL ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:2950 +#, fuzzy +msgid "Please fill in a valid URL.." +msgstr "Bitte geben Sie ein gültiges Enddatum ein." + +#: lib/php/monica/checker.inc.php:2962 +#, fuzzy +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "" +"Dieser Programm-Link existiert bereits. Sie können kein Duplikat erstellen." + +#: lib/php/monica/checker.inc.php:2967 +msgid "This URL. is not reachable. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:2984 lib/php/monica/form.inc.php:3261 +#, fuzzy +msgid "Fill in the description here." +msgstr "Bitte Beschreibung eingeben." + +#: lib/php/monica/checker.inc.php:2988 +msgid "Please fill in the description." +msgstr "Bitte Beschreibung eingeben." + +#: lib/php/monica/checker.inc.php:2992 +#, c-format +msgid "This description is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für die Beschreibung ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:3012 +#, fuzzy +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#: lib/php/monica/checker.inc.php:3016 lib/php/monica/checker.inc.php:3072 +msgid "This category does not exist anymore. Please select another one." +msgstr "Dieser Kategorie existiert nicht mehr. Bitte wählen Sie eine andere." + +#: lib/php/monica/checker.inc.php:3022 lib/php/monica/checker.inc.php:3068 +#, fuzzy +msgid "Please select a category." +msgstr "Bitte Anwender wählen" + +#: lib/php/monica/checker.inc.php:3090 +#, fuzzy +msgid "Please select a related link." +msgstr "Bitte wählen Sie einen zulässigen Monat." + +#: lib/php/monica/checker.inc.php:3094 +#, fuzzy +msgid "This link does not exist anymore. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:3113 +#, fuzzy +msgid "" +"This link categorization already exists. You cannot create a duplicated one." +msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#: lib/php/monica/checker.inc.php:3154 +#, fuzzy +msgid "Please select the type." +msgstr "Bitte Anwender wählen." + +#: lib/php/monica/checker.inc.php:3158 +#, fuzzy +msgid "This type does not exist anymore. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:3185 lib/php/monica/list.inc.php:961 +#, fuzzy +msgid "Please fill in your query." +msgstr "Bitte Benutzernamen eingeben." + +#: lib/php/monica/checker.inc.php:3210 +#, fuzzy +msgid "Please submit the picture." +msgstr "Bitte Kategorie wählen." + +#: lib/php/monica/checker.inc.php:3237 lib/php/monica/checker.inc.php:3328 +msgid "Please fill in the resize ratio." +msgstr "Bitte geben sie den Aspekt für die Größenänderung ein." + +#: lib/php/monica/checker.inc.php:3305 +msgid "Please specify a valid picture." +msgstr "Bitte wählen Sie ein gültiges Bild." + +#: lib/php/monica/chkfunc.inc.php:156 lib/php/monica/chkfunc.inc.php:160 +#: lib/php/monica/chkfunc.inc.php:163 lib/php/monica/chkfunc.inc.php:166 +msgid "Please select a legal year." +msgstr "Bitte wählen Sie ein zulässiges Jahr." + +#: lib/php/monica/chkfunc.inc.php:171 lib/php/monica/chkfunc.inc.php:175 +#: lib/php/monica/chkfunc.inc.php:178 +msgid "Please select a legal month." +msgstr "Bitte wählen Sie einen zulässigen Monat." + +#: lib/php/monica/chkfunc.inc.php:183 lib/php/monica/chkfunc.inc.php:187 +#: lib/php/monica/chkfunc.inc.php:193 +msgid "Please select a legal day." +msgstr "Bitte wählen Sie einen zulässigen Tag." + +#: lib/php/monica/chkwrite.inc.php:27 +#, c-format +msgid "%s: It is not a file." +msgstr "%s: Dies ist keine Datei." + +#: lib/php/monica/chkwrite.inc.php:32 +#, c-format +msgid "%s: You have no permission to overwrite this file." +msgstr "%s: Sie haben keine Erlaubnis, diese Datei zu überschreiben." + +#: lib/php/monica/chkwrite.inc.php:45 +#, c-format +msgid "%s: You cannot create anything under the root directory." +msgstr "%s: Sie können in dem Stammverzeichnis nichts erstellen." + +#: lib/php/monica/chkwrite.inc.php:50 +#, c-format +msgid "" +"%s: One of the parents of this file (%s) is not a directory. You cannot " +"create any new file inside." +msgstr "" +"%s: Einer der Vorgänger dieser Datei (%s) ist kein Verzeichnis. Sie können " +"keine neuen Dateien darin erstellen." + +#: lib/php/monica/chkwrite.inc.php:55 +#, c-format +msgid "%s: You have no permission to create any file under %s." +msgstr "%s: Sie haben keine Erlaubnis, Dateien unter %s zu erstellen." + +#: lib/php/monica/commtext.inc.php:18 +msgid "(not set)" +msgstr "(nicht eingestellt)" + +#: lib/php/monica/commtext.inc.php:24 +msgid "(none)" +msgstr "(keine)" + +#: lib/php/monica/commtext.inc.php:30 +msgid "(N/A)" +msgstr "(N/A)" + +#: lib/php/monica/commtext.inc.php:36 +msgid "(blank)" +msgstr "" + +#: lib/php/monica/echoform.inc.php:173 +#, c-format +msgid "%s bytes" +msgstr "" + +#: lib/php/monica/form.inc.php:168 +#, fuzzy +msgid "Delete it" +msgstr "Gelöscht" + +#: lib/php/monica/form.inc.php:174 +msgid "Are you sure you want to delete it? It cannot be recovered." +msgstr "" + +#: lib/php/monica/form.inc.php:188 +msgid "*" +msgstr "" + +#: lib/php/monica/form.inc.php:224 +msgid "This table provides you a form to add a new data record." +msgstr "" + +#: lib/php/monica/form.inc.php:228 +msgid "This table provides you a form to update a current data record." +msgstr "" + +#: lib/php/monica/form.inc.php:232 +msgid "This table provides you a form to delete a data record." +msgstr "" + +#: lib/php/monica/form.inc.php:281 +msgid "Add a New Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:285 +msgid "Update a Current Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:289 +msgid "Delete a Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:301 +msgid "Preview it." +msgstr "" + +#: lib/php/monica/form.inc.php:500 lib/php/monica/form.inc.php:506 +#: lib/php/monica/form.inc.php:691 lib/php/monica/form.inc.php:697 +#: lib/php/monica/preview.inc.php:146 +#, fuzzy +msgid "Preview" +msgstr "< Vorherige" + +#: lib/php/monica/form.inc.php:501 lib/php/monica/form.inc.php:507 +#: lib/php/monica/form.inc.php:692 lib/php/monica/form.inc.php:698 +#, fuzzy +msgid "Confirm and submit" +msgstr "Passwort bestätigen:" + +#: lib/php/monica/form.inc.php:708 lib/php/monica/form.inc.php:1692 +#: lib/php/monica/form.inc.php:1778 lib/php/monica/list.inc.php:1809 +msgid "Delete" +msgstr "Löschen" + +#: lib/php/monica/form.inc.php:709 lib/php/monica/form.inc.php:6419 +#: lib/php/monica/form.inc.php:6470 +msgid "Cancel" +msgstr "Abbruch" + +#: lib/php/monica/form.inc.php:1042 lib/php/monica/form.inc.php:3499 +msgid "Set the picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1043 lib/php/monica/form.inc.php:3031 +#: lib/php/monica/form.inc.php:3500 +msgid "Delete this picture" +msgstr "Bild löschen" + +#: lib/php/monica/form.inc.php:1048 lib/php/monica/form.inc.php:1178 +#: lib/php/monica/form.inc.php:3037 lib/php/monica/form.inc.php:3104 +#: lib/php/monica/form.inc.php:3505 lib/php/monica/form.inc.php:3677 +#: lib/php/monica/form.inc.php:6163 lib/php/monica/list.inc.php:814 +msgid "Picture preview" +msgstr "Vorschau neues Bild" + +#: lib/php/monica/form.inc.php:1059 lib/php/monica/form.inc.php:1109 +#: lib/php/monica/form.inc.php:1185 +#, fuzzy, c-format +msgid "Picture #%d:" +msgstr "Bild:" + +#: lib/php/monica/form.inc.php:1080 lib/php/monica/form.inc.php:1131 +#: lib/php/monica/form.inc.php:1166 lib/php/monica/form.inc.php:1199 +#, fuzzy +msgid "Caption:" +msgstr "Speicherplatz:" + +#: lib/php/monica/form.inc.php:1092 lib/php/monica/form.inc.php:3064 +#: lib/php/monica/form.inc.php:3566 lib/php/monica/form.inc.php:6183 +msgid "Original picture preview" +msgstr "Vorschau Originalbild" + +#: lib/php/monica/form.inc.php:1093 lib/php/monica/form.inc.php:3065 +#: lib/php/monica/form.inc.php:3567 lib/php/monica/form.inc.php:6197 +msgid "New picture preview" +msgstr "Vorschau neues Bild" + +#: lib/php/monica/form.inc.php:1113 lib/php/monica/form.inc.php:1276 +#: lib/php/monica/form.inc.php:1363 lib/php/monica/form.inc.php:1451 +#: lib/php/monica/form.inc.php:1560 lib/php/monica/form.inc.php:1650 +#: lib/php/monica/form.inc.php:1727 lib/php/monica/form.inc.php:1825 +#: lib/php/monica/form.inc.php:1916 lib/php/monica/form.inc.php:1977 +#: lib/php/monica/form.inc.php:2053 lib/php/monica/form.inc.php:2159 +#: lib/php/monica/form.inc.php:2391 lib/php/monica/form.inc.php:2592 +#: lib/php/monica/form.inc.php:2689 lib/php/monica/form.inc.php:2800 +#: lib/php/monica/form.inc.php:2897 lib/php/monica/form.inc.php:2980 +#: lib/php/monica/form.inc.php:3069 lib/php/monica/form.inc.php:3200 +#: lib/php/monica/form.inc.php:3571 lib/php/monica/form.inc.php:3627 +#: lib/php/monica/form.inc.php:3640 lib/php/monica/form.inc.php:3747 +#: lib/php/monica/form.inc.php:4423 lib/php/monica/form.inc.php:4533 +#: lib/php/monica/form.inc.php:4729 lib/php/monica/form.inc.php:4866 +#: lib/php/monica/form.inc.php:5000 lib/php/monica/form.inc.php:6176 +#: lib/php/monica/form.inc.php:6243 +msgid "Original:" +msgstr "Original:" + +#: lib/php/monica/form.inc.php:1141 lib/php/monica/form.inc.php:1281 +#: lib/php/monica/form.inc.php:1369 lib/php/monica/form.inc.php:1456 +#: lib/php/monica/form.inc.php:1575 lib/php/monica/form.inc.php:1655 +#: lib/php/monica/form.inc.php:1732 lib/php/monica/form.inc.php:1832 +#: lib/php/monica/form.inc.php:1921 lib/php/monica/form.inc.php:1982 +#: lib/php/monica/form.inc.php:2065 lib/php/monica/form.inc.php:2173 +#: lib/php/monica/form.inc.php:2422 lib/php/monica/form.inc.php:2597 +#: lib/php/monica/form.inc.php:2694 lib/php/monica/form.inc.php:2805 +#: lib/php/monica/form.inc.php:2902 lib/php/monica/form.inc.php:2985 +#: lib/php/monica/form.inc.php:3080 lib/php/monica/form.inc.php:3205 +#: lib/php/monica/form.inc.php:3584 lib/php/monica/form.inc.php:3632 +#: lib/php/monica/form.inc.php:3649 lib/php/monica/form.inc.php:3752 +#: lib/php/monica/form.inc.php:4442 lib/php/monica/form.inc.php:4543 +#: lib/php/monica/form.inc.php:4742 lib/php/monica/form.inc.php:4879 +#: lib/php/monica/form.inc.php:5013 lib/php/monica/form.inc.php:6188 +#: lib/php/monica/form.inc.php:6248 lib/php/monica/form.inc.php:6278 +msgid "New:" +msgstr "Neu:" + +#: lib/php/monica/form.inc.php:1269 lib/php/monica/form.inc.php:1444 +#: lib/php/monica/form.inc.php:1543 lib/php/monica/form.inc.php:2358 +#: lib/php/monica/form.inc.php:2585 lib/php/monica/form.inc.php:2793 +#: lib/php/monica/form.inc.php:2890 lib/php/monica/form.inc.php:2973 +#: lib/php/monica/form.inc.php:3620 +msgid "Source:" +msgstr "Quelle:" + +#: lib/php/monica/form.inc.php:1289 lib/php/monica/form.inc.php:1464 +#: lib/php/monica/form.inc.php:1583 lib/php/monica/form.inc.php:2605 +#: lib/php/monica/form.inc.php:2813 lib/php/monica/form.inc.php:2910 +#: lib/php/monica/form.inc.php:2993 +#, fuzzy, c-format +msgid "Please set it from %s." +msgstr "Bitte neue Seite aus %s erschaffen." + +#: lib/php/monica/form.inc.php:1501 +#, fuzzy +msgid "Hide" +msgstr "Verbergen?" + +#: lib/php/monica/form.inc.php:1502 +#, fuzzy +msgid "Show" +msgstr "Angezeigt" + +#: lib/php/monica/form.inc.php:1691 lib/php/monica/form.inc.php:1777 +#: lib/php/monica/form.inc.php:1887 +msgid "Choose" +msgstr "Auswählen" + +#: lib/php/monica/form.inc.php:2237 +msgid "Delete this file" +msgstr "" + +#: lib/php/monica/form.inc.php:2267 lib/php/monica/form.inc.php:2368 +#: lib/php/monica/form.inc.php:2400 lib/php/monica/form.inc.php:2445 +#: lib/php/monica/form.inc.php:2506 +#, fuzzy +msgid "File name:" +msgstr "Voller Name" + +#: lib/php/monica/form.inc.php:2274 lib/php/monica/form.inc.php:2375 +#: lib/php/monica/form.inc.php:2407 lib/php/monica/form.inc.php:2452 +#: lib/php/monica/form.inc.php:2513 +msgid "MIME file type:" +msgstr "" + +#: lib/php/monica/form.inc.php:2279 lib/php/monica/form.inc.php:2380 +#: lib/php/monica/form.inc.php:2412 lib/php/monica/form.inc.php:2457 +#: lib/php/monica/form.inc.php:2518 +#, fuzzy +msgid "File size:" +msgstr "Seitengröße:" + +#: lib/php/monica/form.inc.php:2430 +#, fuzzy, c-format +msgid "Please upload it from %s." +msgstr "Bitte neue Seite aus %s erschaffen." + +#: lib/php/monica/form.inc.php:3128 +msgid "Address:" +msgstr "" + +#: lib/php/monica/form.inc.php:3129 +#, fuzzy +msgid "Fill in your address here." +msgstr "Bitte Passwort eingeben." + +#: lib/php/monica/form.inc.php:3135 +msgid "Attachment:" +msgstr "" + +#: lib/php/monica/form.inc.php:3139 +#, fuzzy +msgid "Attachment description:" +msgstr "Beschreibung:" + +#: lib/php/monica/form.inc.php:3158 lib/php/monica/form.inc.php:3171 +msgid "Content:" +msgstr "Inhalt:" + +#: lib/php/monica/form.inc.php:3165 +msgid "City:" +msgstr "" + +#: lib/php/monica/form.inc.php:3187 lib/php/monica/form.inc.php:3199 +#: lib/php/monica/form.inc.php:3217 lib/php/monica/form.inc.php:3241 +msgid "Country:" +msgstr "" + +#: lib/php/monica/form.inc.php:3229 +msgid "Created:" +msgstr "Erschaffen:" + +#: lib/php/monica/form.inc.php:3235 +msgid "Created by:" +msgstr "Erschaffen von:" + +#: lib/php/monica/form.inc.php:3247 +msgid "Date:" +msgstr "Datum:" + +#: lib/php/monica/form.inc.php:3253 lib/php/monica/form.inc.php:4292 +#: lib/php/monica/form.inc.php:4295 lib/php/monica/list.inc.php:310 +msgid "Disabled?" +msgstr "Deaktiviert?" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 lib/php/monica/list.inc.php:2020 +msgid "Disabled" +msgstr "Deaktiviert" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 +msgid "Enabled" +msgstr "Aktiviert" + +#: lib/php/monica/form.inc.php:3254 +#, fuzzy +msgid "Disable it." +msgstr "Deaktiviert" + +#: lib/php/monica/form.inc.php:3260 lib/php/monica/form.inc.php:4657 +msgid "Description:" +msgstr "Beschreibung:" + +#: lib/php/monica/form.inc.php:3267 +msgid "E-mail:" +msgstr "" + +#: lib/php/monica/form.inc.php:3273 +msgid "Fax:" +msgstr "" + +#: lib/php/monica/form.inc.php:3279 +#, fuzzy +msgid "Group:" +msgstr "Gruppen-ID" + +#: lib/php/monica/form.inc.php:3285 lib/php/monica/form.inc.php:5541 +#: lib/php/monica/form.inc.php:5747 lib/php/monica/form.inc.php:5905 +#: lib/php/monica/form.inc.php:5998 +msgid "Hide?" +msgstr "Verbergen?" + +#: lib/php/monica/form.inc.php:3286 +#, fuzzy +msgid "Hide it" +msgstr "Verborgen" + +#: lib/php/monica/form.inc.php:3286 +#, fuzzy +msgid "Show it" +msgstr "Angezeigt" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it currently." +msgstr "" + +#: lib/php/monica/form.inc.php:3292 +msgid "Host:" +msgstr "" + +#: lib/php/monica/form.inc.php:3298 lib/php/monica/list.inc.php:314 +msgid "HTML?" +msgstr "HTML?" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2948 +#: lib/php/monica/list.inc.php:3062 +msgid "HTML" +msgstr "HTML" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2949 +#: lib/php/monica/list.inc.php:3063 +msgid "Plain text" +msgstr "Nur Text" + +#: lib/php/monica/form.inc.php:3299 +msgid "The submitted content is HTML." +msgstr "Der eingegebene Inhalt ist in HTML-Format." + +#: lib/php/monica/form.inc.php:3305 lib/php/monica/form.inc.php:5535 +#: lib/php/monica/form.inc.php:6074 +msgid "ID.:" +msgstr "ID.:" + +#: lib/php/monica/form.inc.php:3311 +msgid "Introduction:" +msgstr "Einführung:" + +#: lib/php/monica/form.inc.php:3312 +#, fuzzy +msgid "Fill in the introduction here." +msgstr "Bitte Beschreibung eingeben." + +#: lib/php/monica/form.inc.php:3318 +msgid "IP:" +msgstr "" + +#: lib/php/monica/form.inc.php:3324 +msgid "Keywords:" +msgstr "Stichwörter:" + +#: lib/php/monica/form.inc.php:3330 +#, fuzzy +msgid "Language:" +msgstr "Bev. Sprache" + +#: lib/php/monica/form.inc.php:3355 +msgid "Name:" +msgstr "" + +#: lib/php/monica/form.inc.php:3365 lib/php/monica/form.inc.php:5992 +msgid "Order:" +msgstr "Reihenfolge:" + +#: lib/php/monica/form.inc.php:3371 +msgid "Organization:" +msgstr "" + +#: lib/php/monica/form.inc.php:3377 +#, fuzzy +msgid "Parent category:" +msgstr "Kategorie:" + +#: lib/php/monica/form.inc.php:3378 +msgid "At the very top" +msgstr "" + +#: lib/php/monica/form.inc.php:3391 lib/php/monica/form.inc.php:3428 +#: lib/php/monica/form.inc.php:3468 lib/php/monica/form.inc.php:4330 +#: lib/php/monica/form.inc.php:6362 +msgid "Password:" +msgstr "Passwort:" + +#: lib/php/monica/form.inc.php:3407 lib/php/monica/form.inc.php:3444 +msgid "Confirm password:" +msgstr "Passwort bestätigen:" + +#: lib/php/monica/form.inc.php:3458 +msgid "(Leave them blank if you don't plan to change your password.)" +msgstr "" + +#: lib/php/monica/form.inc.php:3484 +#, fuzzy +msgid "Page path:" +msgstr "Seitengröße:" + +#: lib/php/monica/form.inc.php:3490 +msgid "PDF. file:" +msgstr "" + +#: lib/php/monica/form.inc.php:3508 lib/php/monica/form.inc.php:3570 +#: lib/php/monica/form.inc.php:3680 lib/php/monica/form.inc.php:6151 +#: lib/php/monica/form.inc.php:6175 +msgid "Picture:" +msgstr "Bild:" + +#: lib/php/monica/form.inc.php:3531 lib/php/monica/form.inc.php:3615 +#: lib/php/monica/form.inc.php:3619 lib/php/monica/form.inc.php:3693 +msgid "Pic. caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:3538 lib/php/monica/form.inc.php:3639 +#: lib/php/monica/form.inc.php:3699 +msgid "Pic. position:" +msgstr "" + +#: lib/php/monica/form.inc.php:3718 lib/php/monica/form.inc.php:3746 +#: lib/php/monica/form.inc.php:3780 +msgid "Pinyin:" +msgstr "" + +#: lib/php/monica/form.inc.php:3722 lib/php/monica/form.inc.php:3756 +#, fuzzy +msgid "Please fill in the Chinese first." +msgstr "Bitte geben sie den Aspekt für die Größenänderung ein." + +#: lib/php/monica/form.inc.php:3801 +#, fuzzy +msgid "Subcategory:" +msgid_plural "Subcategories:" +msgstr[0] "Kategorie:" +msgstr[1] "Kategorie:" + +#: lib/php/monica/form.inc.php:3823 +msgid "Script:" +msgstr "Script:" + +#: lib/php/monica/form.inc.php:3829 +msgid "S/N:" +msgstr "S/N:" + +#: lib/php/monica/form.inc.php:3835 +#, fuzzy +msgid "Street:" +msgstr "Auswählen" + +#: lib/php/monica/form.inc.php:3841 +msgid "Subject:" +msgstr "" + +#: lib/php/monica/form.inc.php:3847 +msgid "Telephone:" +msgstr "" + +#: lib/php/monica/form.inc.php:3853 +msgid "Tel. (cell.):" +msgstr "" + +#: lib/php/monica/form.inc.php:3859 +msgid "Tel. (home):" +msgstr "" + +#: lib/php/monica/form.inc.php:3865 +msgid "Tel. (office):" +msgstr "" + +#: lib/php/monica/form.inc.php:3871 +msgid "Title:" +msgstr "Titel:" + +#: lib/php/monica/form.inc.php:3891 +msgid "Value:" +msgstr "" + +#: lib/php/monica/form.inc.php:3897 +msgid "Visits:" +msgstr "Besuche:" + +#: lib/php/monica/form.inc.php:3903 +msgid "Visited:" +msgstr "Besucht:" + +#: lib/php/monica/form.inc.php:3909 +msgid "Updated:" +msgstr "Aktualisiert:" + +#: lib/php/monica/form.inc.php:3915 +msgid "Updated by:" +msgstr "Aktualisiert von:" + +#: lib/php/monica/form.inc.php:3921 +#, fuzzy +msgid "URL.:" +msgstr "URL:" + +#: lib/php/monica/form.inc.php:3927 +msgid "Zip code:" +msgstr "" + +#: lib/php/monica/form.inc.php:4151 +msgid "Delete this user account" +msgstr "Anwender-Account löschen" + +#: lib/php/monica/form.inc.php:4157 +msgid "This table provides you a form to add a new user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4161 +msgid "This table provides you a form to update a current user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4165 +msgid "This table provides you a form to delete a user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4192 +msgid "Add a New User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4196 +msgid "Update a Current User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4200 +msgid "Delete a User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4213 +msgid "This is a super-user. You can only change parts of her infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4220 +msgid "" +"This user has a datum. It cannot be deleted. To delete the user, its datum " +"must first be deleted." +msgid_plural "" +"This user has data. It cannot be deleted. To delete the user, all of its " +"data must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4282 +msgid "Administrator?" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Non-administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4296 +msgid "Disable this user account." +msgstr "Diesen Anwender-Account deaktivieren." + +#: lib/php/monica/form.inc.php:4305 lib/php/monica/form.inc.php:4307 +#: lib/php/monica/form.inc.php:6354 +msgid "User ID.:" +msgstr "Benutzername:" + +#: lib/php/monica/form.inc.php:4314 +msgid "Pref. language:" +msgstr "Bev. Sprache:" + +#: lib/php/monica/form.inc.php:4320 +msgid "Full name:" +msgstr "Voller Name:" + +#: lib/php/monica/form.inc.php:4348 lib/php/monica/form.inc.php:4400 +#: lib/php/monica/form.inc.php:4422 lib/php/monica/form.inc.php:4496 +#: lib/php/monica/form.inc.php:4944 lib/php/monica/form.inc.php:4983 +#: lib/php/monica/form.inc.php:4999 lib/php/monica/form.inc.php:5051 +msgid "Belonging to:" +msgstr "" + +#: lib/php/monica/form.inc.php:4532 lib/php/monica/form.inc.php:4554 +msgid "Fail logins:" +msgstr "" + +#: lib/php/monica/form.inc.php:4539 lib/php/monica/form.inc.php:4560 +msgid "(Locked)" +msgstr "" + +#: lib/php/monica/form.inc.php:4585 +msgid "Delete this group" +msgstr "Diese Gruppe löschen" + +#: lib/php/monica/form.inc.php:4591 +msgid "This table provides you a form to add a new group." +msgstr "" + +#: lib/php/monica/form.inc.php:4595 +msgid "This table provides you a form to update a current group." +msgstr "" + +#: lib/php/monica/form.inc.php:4599 +msgid "This table provides you a form to delete a group." +msgstr "" + +#: lib/php/monica/form.inc.php:4624 +msgid "Add a New Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4628 +msgid "Update a Current Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4632 +#, fuzzy +msgid "Delete a Group" +msgstr "Bitte wählen Sie eine Gruppe." + +#: lib/php/monica/form.inc.php:4639 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "" +"Dies ist eine Super-Benutzer-Gruppe. Sie können nur Teile der Informationen " +"ändern." + +#: lib/php/monica/form.inc.php:4648 lib/php/monica/form.inc.php:4650 +msgid "Group ID.:" +msgstr "Gruppen-ID:" + +#: lib/php/monica/form.inc.php:4663 +msgid "Add a user" +msgstr "Anwender hinzufügen" + +#: lib/php/monica/form.inc.php:4670 lib/php/monica/form.inc.php:4710 +#: lib/php/monica/form.inc.php:4728 lib/php/monica/form.inc.php:4781 +#, fuzzy +msgid "User member:" +msgid_plural "User members:" +msgstr[0] "Gruppen-ID" +msgstr[1] "Gruppen-ID" + +#: lib/php/monica/form.inc.php:4801 lib/php/monica/form.inc.php:4938 +#, fuzzy +msgid "Add a group" +msgstr "%s Gruppe." + +#: lib/php/monica/form.inc.php:4808 lib/php/monica/form.inc.php:4848 +#: lib/php/monica/form.inc.php:4865 lib/php/monica/form.inc.php:4918 +#, fuzzy +msgid "Group member:" +msgid_plural "Group members:" +msgstr[0] "Gruppen-ID" +msgstr[1] "Gruppen-ID" + +#: lib/php/monica/form.inc.php:5085 lib/php/monica/form.inc.php:5160 +#, fuzzy +msgid "Delete this membership record" +msgstr "%s Script-Berechtigung." + +#: lib/php/monica/form.inc.php:5091 lib/php/monica/form.inc.php:5166 +#, fuzzy +msgid "This table provides you a form to add a new membership record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5095 lib/php/monica/form.inc.php:5170 +#, fuzzy +msgid "This table provides you a form to change a current membership record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5099 lib/php/monica/form.inc.php:5174 +#, fuzzy +msgid "This table provides you a form to delete a membership record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5122 +msgid "Add a New User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5126 +msgid "Change a Current User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5130 +msgid "Delete a User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5140 lib/php/monica/form.inc.php:5215 +msgid "Member:" +msgstr "" + +#: lib/php/monica/form.inc.php:5197 +msgid "Add a New Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5201 +msgid "Change a Current Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5205 +msgid "Delete a Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5235 +msgid "Delete this user preference" +msgstr "Anwender-Einstellung löschen" + +#: lib/php/monica/form.inc.php:5241 +#, fuzzy +msgid "This table provides you a form to add a new user preference." +msgstr "" +"Klicken Sie hier um eine neue Anwender-Einstellung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5245 +msgid "This table provides you a form to modify a current user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5249 +msgid "This table provides you a form to delete a user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5272 +#, fuzzy +msgid "Add a New User Preference" +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/form.inc.php:5276 +msgid "Modify a Current User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5280 +#, fuzzy +msgid "Delete a User Preference" +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/form.inc.php:5290 lib/php/monica/form.inc.php:5476 +msgid "User:" +msgstr "Anwender:" + +#: lib/php/monica/form.inc.php:5291 lib/php/monica/list.inc.php:2588 +msgid "Everyone" +msgstr "Alle" + +#: lib/php/monica/form.inc.php:5297 +msgid "Domain:" +msgstr "" + +#: lib/php/monica/form.inc.php:5298 lib/php/monica/list.inc.php:2592 +#, fuzzy +msgid "Everywhere" +msgstr "Alle" + +#: lib/php/monica/form.inc.php:5318 +#, fuzzy +msgid "Delete this script privilege record" +msgstr "%s Script-Berechtigung." + +#: lib/php/monica/form.inc.php:5324 +#, fuzzy +msgid "This table provides you a form to add a new script privilege record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5328 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5332 +msgid "This table provides you a form to delete a script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5355 +msgid "Add a New Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5359 +msgid "Change a Current Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5363 +msgid "Delete a Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5373 +msgid "Privilege:" +msgstr "Berechtigung:" + +#: lib/php/monica/form.inc.php:5395 +#, fuzzy +msgid "Delete this user request" +msgstr "Anwender-Account löschen" + +#: lib/php/monica/form.inc.php:5401 +#, fuzzy +msgid "This table provides you a form to add a new user request." +msgstr "" +"Klicken Sie hier um eine neue Anwender-Einstellung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5405 +#, fuzzy +msgid "This table provides you a form to update a current user request." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5409 +#, fuzzy +msgid "This table provides you a form to delete a user request." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5432 +#, fuzzy +msgid "Add a New User Request" +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/form.inc.php:5436 +#, fuzzy +msgid "Update a Current User Request" +msgstr "Anwender verwalten" + +#: lib/php/monica/form.inc.php:5440 +#, fuzzy +msgid "Delete a User Request" +msgstr "Bitte Anwender wählen" + +#: lib/php/monica/form.inc.php:5448 +msgid "Join" +msgstr "" + +#: lib/php/monica/form.inc.php:5452 +msgid "Change e-mail" +msgstr "" + +#: lib/php/monica/form.inc.php:5456 +#, fuzzy +msgid "Reset password" +msgstr "Bitte Passwort eingeben." + +#: lib/php/monica/form.inc.php:5464 +msgid "Expiration:" +msgstr "" + +#: lib/php/monica/form.inc.php:5470 lib/php/monica/form.inc.php:6432 +msgid "Type:" +msgstr "" + +#: lib/php/monica/form.inc.php:5477 +msgid "Anonymous" +msgstr "" + +#: lib/php/monica/form.inc.php:5483 +msgid "Arguments:" +msgstr "" + +#: lib/php/monica/form.inc.php:5501 +msgid "Delete this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5507 +msgid "This table provides you a form to add a new category." +msgstr "" + +#: lib/php/monica/form.inc.php:5511 +msgid "This table provides you a form to edit a current category." +msgstr "" + +#: lib/php/monica/form.inc.php:5515 +msgid "This table provides you a form to delete a category." +msgstr "" + +#: lib/php/monica/form.inc.php:5525 +msgid "" +"This category has a subcategory. It cannot be deleted. To delete the " +"category, its subcategory must first be deleted." +msgid_plural "" +"This category has subcategories. It cannot be deleted. To delete the " +"category, all of its subcategories must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Show this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5559 +msgid "Delete this categorization record" +msgstr "" + +#: lib/php/monica/form.inc.php:5565 +msgid "This table provides you a form to add a new categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5569 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5573 +msgid "This table provides you a form to delete a categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5618 +msgid "Add a New Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5622 +msgid "Edit a Current Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5626 +msgid "Delete a Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5636 +msgid "" +"This category has a link. It cannot be deleted. To delete the category, " +"its link must first be deleted." +msgid_plural "" +"This category has links. It cannot be deleted. To delete the category, all " +"of its links must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5655 lib/php/monica/form.inc.php:5819 +msgid "Link:" +msgid_plural "Links:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5692 +msgid "Delete this related link" +msgstr "" + +#: lib/php/monica/form.inc.php:5698 +msgid "This table provides you a form to add a new related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5702 +msgid "This table provides you a form to edit a current related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5706 +msgid "This table provides you a form to delete a related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5729 +msgid "Add a New Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5733 +msgid "Edit a Current Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5737 +msgid "Delete a Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 lib/php/monica/form.inc.php:5906 +msgid "Show this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this related link currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5755 lib/php/monica/form.inc.php:5812 +#, fuzzy +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "Kategorie:" +msgstr[1] "Kategorie:" + +#: lib/php/monica/form.inc.php:5794 +msgid "Add a New Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5798 +msgid "Change a Current Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5802 +msgid "Delete a Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5842 +msgid "Delete this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5848 +msgid "This table provides you a form to write a new page." +msgstr "" + +#: lib/php/monica/form.inc.php:5852 +msgid "This table provides you a form to edit a current page." +msgstr "" + +#: lib/php/monica/form.inc.php:5856 +msgid "This table provides you a form to delete a page." +msgstr "" + +#: lib/php/monica/form.inc.php:5881 +msgid "Write a New Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5885 +msgid "Edit a Current Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5889 +#, fuzzy +msgid "Delete a Page" +msgstr "Gelöscht" + +#: lib/php/monica/form.inc.php:5897 +msgid "Preview this page." +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5929 +msgid "Delete this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5935 +msgid "This table provides you a form to write a new news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5939 +msgid "This table provides you a form to edit a current news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5943 +msgid "This table provides you a form to delete a news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5968 +msgid "Write a New News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5972 +msgid "Edit a Current News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5976 +msgid "Delete a News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5984 +msgid "Preview this news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Show this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article currently." +msgstr "" + +#: lib/php/monica/form.inc.php:6019 +#, fuzzy +msgid "Delete this country record" +msgstr "%s Script-Berechtigung." + +#: lib/php/monica/form.inc.php:6025 +#, fuzzy +msgid "This table provides you a form to add a new country record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:6029 +#, fuzzy +msgid "This table provides you a form to edit a current country record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:6033 +#, fuzzy +msgid "This table provides you a form to delete a country record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:6056 +msgid "Add a New Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6060 +msgid "Edit a Current Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6064 +msgid "Delete a Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6080 lib/php/monica/list.inc.php:3391 +msgid "Special?" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A special record" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +#, fuzzy +msgid "A normal country" +msgstr "Anwender suchen:" + +#: lib/php/monica/form.inc.php:6081 +msgid "This is a special record." +msgstr "" + +#: lib/php/monica/form.inc.php:6110 +msgid "This table provides you a form to add a new picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6114 +msgid "This table provides you a form to modify a current picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6125 +#, fuzzy +msgid "Upload a New Picture" +msgstr "Bitte neue Seite aus %s erschaffen." + +#: lib/php/monica/form.inc.php:6129 +#, fuzzy +msgid "Modify a Current Picture" +msgstr "Bitte neue Seite aus %s erschaffen." + +#: lib/php/monica/form.inc.php:6230 lib/php/monica/form.inc.php:6242 +msgid "Ratio:" +msgstr "" + +#: lib/php/monica/form.inc.php:6267 lib/php/monica/form.inc.php:6277 +msgid "Upload:" +msgstr "" + +#: lib/php/monica/form.inc.php:6308 +msgid "This table provides you a form to log in." +msgstr "" + +#: lib/php/monica/form.inc.php:6314 +msgid "Identify Yourself" +msgstr "Geben Sie Ihre Benutzerkennung ein" + +#: lib/php/monica/form.inc.php:6323 lib/php/monica/init.inc.php:505 +msgid "" +"Log-in is temporarily closed for maintainance now. Please come again " +"later. Sorry for the inconvienence." +msgstr "" + +#: lib/php/monica/form.inc.php:6332 +msgid "Log in" +msgstr "" + +#: lib/php/monica/form.inc.php:6379 +msgid "Remember me." +msgstr "Einstellungen merken." + +#: lib/php/monica/form.inc.php:6406 +msgid "Rebuild the Pages" +msgstr "" + +#: lib/php/monica/form.inc.php:6415 +msgid "Confirm" +msgstr "" + +#: lib/php/monica/form.inc.php:6457 +msgid "Log Out" +msgstr "Abmelden" + +#: lib/php/monica/form.inc.php:6466 +msgid "Log out" +msgstr "Abmelden" + +#: lib/php/monica/form.inc.php:6480 +msgid "Are you sure you want to log out?" +msgstr "" + +#: lib/php/monica/init.inc.php:114 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" + +#: lib/php/monica/init.inc.php:503 lib/php/monica/init.inc.php:504 +msgid "Log-In Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:524 lib/php/monica/init.inc.php:525 +msgid "Development Site Closed" +msgstr "Entwicklungsseite geschlossen" + +#: lib/php/monica/init.inc.php:526 +msgid "Development site is closed. Please work on the live site." +msgstr "" +"Die Entwicklungsseite ist geschlossen. Arbeiten Sie bitte auf der Live-Seite." + +#: lib/php/monica/links.inc.php:271 +msgid "Related Links" +msgstr "" + +#: lib/php/monica/list.inc.php:130 +msgid "Malformed" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "OK" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "Unreachable" +msgstr "" + +#: lib/php/monica/list.inc.php:290 lib/php/monica/list.inc.php:1534 +#: lib/php/monica/list.inc.php:3642 +msgid "(query phrase)" +msgstr "" + +#: lib/php/monica/list.inc.php:300 +msgid "S/N" +msgstr "S/N" + +#: lib/php/monica/list.inc.php:301 +msgid "Created" +msgstr "Erschaffen" + +#: lib/php/monica/list.inc.php:302 +msgid "Created by" +msgstr "Erschaffen durch" + +#: lib/php/monica/list.inc.php:303 +msgid "Updated" +msgstr "Aktualisiert" + +#: lib/php/monica/list.inc.php:304 +msgid "Updated by" +msgstr "Aktualisiert durch" + +#: lib/php/monica/list.inc.php:306 +msgid "Content" +msgstr "Inhalt" + +#: lib/php/monica/list.inc.php:307 +msgid "Category" +msgstr "Kategorie" + +#: lib/php/monica/list.inc.php:308 +msgid "Coverage" +msgstr "" + +#: lib/php/monica/list.inc.php:309 +msgid "Date" +msgstr "Datum" + +#: lib/php/monica/list.inc.php:311 +msgid "Description" +msgstr "Beschreibung" + +#: lib/php/monica/list.inc.php:312 +msgid "E-mail" +msgstr "" + +#: lib/php/monica/list.inc.php:313 +msgid "Hidden?" +msgstr "Verborgen?" + +#: lib/php/monica/list.inc.php:315 +msgid "ID." +msgstr "ID." + +#: lib/php/monica/list.inc.php:316 +msgid "Keywords" +msgstr "Stichwörter" + +#: lib/php/monica/list.inc.php:317 +#, fuzzy +msgid "Name" +msgstr "Voller Name" + +#: lib/php/monica/list.inc.php:318 +msgid "Order" +msgstr "Reihenfolge" + +#: lib/php/monica/list.inc.php:319 +msgid "Page path" +msgstr "" + +#: lib/php/monica/list.inc.php:320 +msgid "Picture" +msgstr "" + +#: lib/php/monica/list.inc.php:321 +msgid "Pic. ratio" +msgstr "" + +#: lib/php/monica/list.inc.php:322 +#, fuzzy +msgid "Pic. caption" +msgstr "Speicherplatz" + +#: lib/php/monica/list.inc.php:323 +msgid "Pic. position" +msgstr "" + +#: lib/php/monica/list.inc.php:324 +#, fuzzy +msgid "Subject" +msgstr "Auswählen" + +#: lib/php/monica/list.inc.php:325 +msgid "Title" +msgstr "Titel" + +#: lib/php/monica/list.inc.php:326 +#, fuzzy +msgid "URL." +msgstr "URL" + +#: lib/php/monica/list.inc.php:327 +msgid "Status (slow)" +msgstr "" + +#: lib/php/monica/list.inc.php:336 +msgid "Select" +msgstr "Auswählen" + +#: lib/php/monica/list.inc.php:339 +msgid "Select a Data Record" +msgstr "" + +#: lib/php/monica/list.inc.php:343 +msgid "Edit" +msgstr "Bearbeiten" + +#: lib/php/monica/list.inc.php:345 +msgid "Manage Data" +msgstr "" + +#: lib/php/monica/list.inc.php:749 +msgid "Nothing found. Please try another query." +msgstr "Kein Ergebnis gefunden. Versuchen Sie eine andere Abfrage." + +#: lib/php/monica/list.inc.php:752 +msgid "The database is empty." +msgstr "Die Datenbank ist leer." + +#: lib/php/monica/list.inc.php:759 +#, c-format +msgid "Your query found %s record." +msgid_plural "Your query found %s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:766 +#, c-format +msgid "%s record." +msgid_plural "%s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:775 +#, c-format +msgid "Your query found %s record, listing %s to %s." +msgid_plural "Your query found %s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:784 +#, c-format +msgid "%s record, listing %s to %s." +msgid_plural "%s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:855 lib/php/monica/list.inc.php:860 +#: lib/php/monica/list.inc.php:869 +#, c-format +msgid "Page number (%s) invalid. Please specify a valid page number." +msgstr "" +"Die Seitennummer (%s) ist ungültig. Geben Sie bitte eine gültige " +"Seitennummer ein." + +#: lib/php/monica/list.inc.php:874 +#, fuzzy, c-format +msgid "" +"Page number (%d) out of range. Please specify a number between 1 and %d." +msgstr "" +"Die Seitennummer (%d) liegt außerhalb des erlaubten Rahmens. Bitte geben Sie " +"eine Seitenzahl zwischen 1 und %d ein." + +#: lib/php/monica/list.inc.php:1138 lib/php/monica/list.inc.php:1151 +#, c-format +msgid "You cannot sort by \"%s\"." +msgstr "" + +#: lib/php/monica/list.inc.php:1512 +msgid "Search" +msgstr "Suchen" + +#: lib/php/monica/list.inc.php:1610 +msgid "Index" +msgstr "" + +#: lib/php/monica/list.inc.php:1634 +#, fuzzy +msgid "First" +msgstr "<< Erste" + +#: lib/php/monica/list.inc.php:1647 +#, fuzzy +msgid "Previous" +msgstr "< Vorherige" + +#: lib/php/monica/list.inc.php:1696 +#, fuzzy +msgid "Next" +msgstr "Nächste >" + +#: lib/php/monica/list.inc.php:1714 +#, fuzzy +msgid "Last" +msgstr "Letzte >>" + +#: lib/php/monica/list.inc.php:1736 +#, fuzzy +msgid "Page:" +msgstr "Seitengröße:" + +#: lib/php/monica/list.inc.php:1776 lib/php/monica/list.inc.php:1900 +#, fuzzy +msgid "Delete the selected items." +msgstr "Bitte Anwender wählen." + +#: lib/php/monica/list.inc.php:1805 +msgid "No." +msgstr "Nr." + +#: lib/php/monica/list.inc.php:1813 lib/php/monica/list.inc.php:1873 +msgid "View" +msgstr "Anzeigen" + +#: lib/php/monica/list.inc.php:1925 +msgid "Set" +msgstr "Einstellen" + +#: lib/php/monica/list.inc.php:1941 +msgid "Rows per page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1946 +msgid "Display columns:" +msgstr "Spalten anzeigen:" + +#: lib/php/monica/list.inc.php:1976 +#, fuzzy +msgid "Select a User" +msgstr "Bitte Anwender wählen" + +#: lib/php/monica/list.inc.php:1977 +msgid "Manage Users" +msgstr "Anwender verwalten" + +#: lib/php/monica/list.inc.php:1982 +msgid "User ID." +msgstr "Benutzername" + +#: lib/php/monica/list.inc.php:1983 +#, fuzzy +msgid "Full name" +msgstr "Voller Name:" + +#: lib/php/monica/list.inc.php:1984 +msgid "Deleted?" +msgstr "Gelöscht?" + +#: lib/php/monica/list.inc.php:1985 +#, fuzzy +msgid "Pref. language" +msgstr "Bev. Sprache:" + +#: lib/php/monica/list.inc.php:1986 +msgid "Visits" +msgstr "Besuche" + +#: lib/php/monica/list.inc.php:1987 +msgid "Visited" +msgstr "Besucht" + +#: lib/php/monica/list.inc.php:1988 +msgid "IP" +msgstr "" + +#: lib/php/monica/list.inc.php:1989 +msgid "Host" +msgstr "" + +#: lib/php/monica/list.inc.php:1990 +#, fuzzy +msgid "From country" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:1991 +msgid "Fail logins" +msgstr "" + +#: lib/php/monica/list.inc.php:2024 +msgid "Deleted" +msgstr "Gelöscht" + +#: lib/php/monica/list.inc.php:2035 +msgid "Add a new user account." +msgstr "" + +#: lib/php/monica/list.inc.php:2045 +msgid "Search for a user:" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:2063 +#, c-format +msgid "Your query found %s user." +msgid_plural "Your query found %s users." +msgstr[0] "Ihr Anfrage ergab %s Anwender." +msgstr[1] "Ihr Anfrage ergab %s Anwender." + +#: lib/php/monica/list.inc.php:2070 +#, c-format +msgid "%s user." +msgid_plural "%s users." +msgstr[0] "%s Anwender." +msgstr[1] "%s Anwender." + +#: lib/php/monica/list.inc.php:2079 +#, c-format +msgid "Your query found %s user, listing %s to %s." +msgid_plural "Your query found %s users, listing %s to %s." +msgstr[0] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." +msgstr[1] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2088 +#, c-format +msgid "%s user, listing %s to %s." +msgid_plural "%s users, listing %s to %s." +msgstr[0] "%s Anwender, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2107 +#, fuzzy +msgid "Select a Group" +msgstr "Bitte wählen Sie eine Gruppe." + +#: lib/php/monica/list.inc.php:2108 +msgid "Manage Groups" +msgstr "Gruppen verwalten" + +#: lib/php/monica/list.inc.php:2113 +msgid "Group ID." +msgstr "Gruppen-ID" + +#: lib/php/monica/list.inc.php:2121 +msgid "Add a new group." +msgstr "" + +#: lib/php/monica/list.inc.php:2131 +msgid "Search for a group:" +msgstr "Gruppe suchen:" + +#: lib/php/monica/list.inc.php:2149 +#, c-format +msgid "Your query found %s group." +msgid_plural "Your query found %s groups." +msgstr[0] "Ihre Abfrage ergab %s Gruppe." +msgstr[1] "Ihre Abfrage ergab %s Gruppen." + +#: lib/php/monica/list.inc.php:2156 +#, c-format +msgid "%s group." +msgid_plural "%s groups." +msgstr[0] "%s Gruppe." +msgstr[1] "%s Gruppen." + +#: lib/php/monica/list.inc.php:2165 +#, c-format +msgid "Your query found %s group, listing %s to %s." +msgid_plural "Your query found %s groups, listing %s to %s." +msgstr[0] "Ihre Abfrage ergab %s Gruppe, angezeigt werden %s bis %s." +msgstr[1] "Ihre Abfrage ergab %s Gruppen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2174 +#, c-format +msgid "%s group, listing %s to %s." +msgid_plural "%s groups, listing %s to %s." +msgstr[0] "%s Gruppe, angezeigt werden %s bis %s." +msgstr[1] "%s Gruppen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2194 +msgid "Select a User Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2195 +msgid "Manage User Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2200 lib/php/monica/list.inc.php:2323 +msgid "Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2201 lib/php/monica/list.inc.php:2324 +msgid "Member" +msgstr "" + +#: lib/php/monica/list.inc.php:2244 lib/php/monica/list.inc.php:2375 +#, fuzzy +msgid "Add a new membership record." +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/list.inc.php:2254 lib/php/monica/list.inc.php:2385 +#, fuzzy +msgid "Search for a membership record:" +msgstr "Anwender-Einstellung suchen:" + +#: lib/php/monica/list.inc.php:2272 lib/php/monica/list.inc.php:2403 +#, fuzzy, c-format +msgid "Your query found %s membership record." +msgid_plural "Your query found %s membership records." +msgstr[0] "Ihre Anfrage ergab %s Anwender-Einstellung." +msgstr[1] "Ihre Anfrage ergab %s Anwender-Einstellungen." + +#: lib/php/monica/list.inc.php:2279 lib/php/monica/list.inc.php:2410 +#, fuzzy, c-format +msgid "%s membership record." +msgid_plural "%s membership records." +msgstr[0] "%s Anwender-Einstellung." +msgstr[1] "%s Anwender-Einstellungen." + +#: lib/php/monica/list.inc.php:2288 lib/php/monica/list.inc.php:2419 +#, fuzzy, c-format +msgid "Your query found %s membership record, listing %s to %s." +msgid_plural "Your query found %s membership records, listing %s to %s." +msgstr[0] "" +"Ihre Anfrage ergab %s Anwender-Einstellung, angezeigt werden %s bis %s." +msgstr[1] "" +"Ihre Anfrage ergab %s Anwender-Einstellungen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2297 lib/php/monica/list.inc.php:2428 +#, fuzzy, c-format +msgid "%s membership record, listing %s to %s." +msgid_plural "%s membership records, listing %s to %s." +msgstr[0] "%s Anwender-Einstellung, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender-Einstellungen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2317 +msgid "Select a Group Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2318 +msgid "Manage Group Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2448 +#, fuzzy +msgid "Select a Script Privilege Record" +msgstr "Script-Berechtigung suchen:" + +#: lib/php/monica/list.inc.php:2449 +#, fuzzy +msgid "Manage Script Privileges" +msgstr "%s Script-Berechtigung." + +#: lib/php/monica/list.inc.php:2454 +msgid "Script" +msgstr "Script" + +#: lib/php/monica/list.inc.php:2455 +msgid "Privilege" +msgstr "Berechtigung" + +#: lib/php/monica/list.inc.php:2493 +#, fuzzy +msgid "Add a new script privilege record." +msgstr "%s Script-Berechtigung." + +#: lib/php/monica/list.inc.php:2503 +#, fuzzy +msgid "Search for a script privilege record:" +msgstr "Script-Berechtigung suchen:" + +#: lib/php/monica/list.inc.php:2521 +#, fuzzy, c-format +msgid "Your query found %s script privilege record." +msgid_plural "Your query found %s script privilege records." +msgstr[0] "Ihre Anfrage ergab %s Script-Berechtigung." +msgstr[1] "Ihre Anfrage ergab %s Script-Berechtigungen." + +#: lib/php/monica/list.inc.php:2528 +#, fuzzy, c-format +msgid "%s script privilege record." +msgid_plural "%s script privilege records." +msgstr[0] "%s Script-Berechtigung." +msgstr[1] "%s Script-Berechtigungen." + +#: lib/php/monica/list.inc.php:2537 +#, fuzzy, c-format +msgid "Your query found %s script privilege record, listing %s to %s." +msgid_plural "Your query found %s script privilege records, listing %s to %s." +msgstr[0] "" +"Ihre Anfrage ergab %s Script-Berechtigung, angezeigt werden %s bis %s." +msgstr[1] "" +"Ihre Anfrage ergab %s Script-Berechtigungen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2546 +#, fuzzy, c-format +msgid "%s script privilege record, listing %s to %s." +msgid_plural "%s script privilege records, listing %s to %s." +msgstr[0] "%s Script-Berechtigung, angezeigt werden %s bis %s." +msgstr[1] "%s Script-Berechtigungen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2566 +#, fuzzy +msgid "Select a User Preference" +msgstr "Anwender-Einstellung suchen:" + +#: lib/php/monica/list.inc.php:2567 +#, fuzzy +msgid "Manage User Preferences" +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/list.inc.php:2574 lib/php/monica/list.inc.php:2689 +msgid "User" +msgstr "Anwender" + +#: lib/php/monica/list.inc.php:2575 +msgid "Domain" +msgstr "" + +#: lib/php/monica/list.inc.php:2576 +#, fuzzy +msgid "Value" +msgstr "Pref. Wert" + +#: lib/php/monica/list.inc.php:2610 +#, fuzzy +msgid "Add a new user preference." +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/list.inc.php:2620 +msgid "Search for a user preference:" +msgstr "Anwender-Einstellung suchen:" + +#: lib/php/monica/list.inc.php:2638 +#, c-format +msgid "Your query found %s user preference." +msgid_plural "Your query found %s user preferences." +msgstr[0] "Ihre Anfrage ergab %s Anwender-Einstellung." +msgstr[1] "Ihre Anfrage ergab %s Anwender-Einstellungen." + +#: lib/php/monica/list.inc.php:2645 +#, c-format +msgid "%s user preference." +msgid_plural "%s user preferences." +msgstr[0] "%s Anwender-Einstellung." +msgstr[1] "%s Anwender-Einstellungen." + +#: lib/php/monica/list.inc.php:2654 +#, c-format +msgid "Your query found %s user preference, listing %s to %s." +msgid_plural "Your query found %s user preferences, listing %s to %s." +msgstr[0] "" +"Ihre Anfrage ergab %s Anwender-Einstellung, angezeigt werden %s bis %s." +msgstr[1] "" +"Ihre Anfrage ergab %s Anwender-Einstellungen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2663 +#, c-format +msgid "%s user preference, listing %s to %s." +msgid_plural "%s user preferences, listing %s to %s." +msgstr[0] "%s Anwender-Einstellung, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender-Einstellungen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2682 +#, fuzzy +msgid "Select a User Request" +msgstr "Bitte Anwender wählen" + +#: lib/php/monica/list.inc.php:2683 +#, fuzzy +msgid "Manage User Requests" +msgstr "Anwender verwalten" + +#: lib/php/monica/list.inc.php:2688 +msgid "Type" +msgstr "" + +#: lib/php/monica/list.inc.php:2690 +msgid "Arguments" +msgstr "" + +#: lib/php/monica/list.inc.php:2691 +msgid "Expiration" +msgstr "" + +#: lib/php/monica/list.inc.php:2699 +#, fuzzy +msgid "Add a new user request." +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/list.inc.php:2709 +#, fuzzy +msgid "Search for a user request:" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:2727 +#, fuzzy, c-format +msgid "Your query found %s user request." +msgid_plural "Your query found %s user requests." +msgstr[0] "Ihr Anfrage ergab %s Anwender." +msgstr[1] "Ihr Anfrage ergab %s Anwender." + +#: lib/php/monica/list.inc.php:2734 +#, fuzzy, c-format +msgid "%s user request." +msgid_plural "%s user requests." +msgstr[0] "%s Anwender-Einstellung." +msgstr[1] "%s Anwender-Einstellungen." + +#: lib/php/monica/list.inc.php:2743 +#, fuzzy, c-format +msgid "Your query found %s user request, listing %s to %s." +msgid_plural "Your query found %s user requests, listing %s to %s." +msgstr[0] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." +msgstr[1] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2752 +#, fuzzy, c-format +msgid "%s user request, listing %s to %s." +msgid_plural "%s user requests, listing %s to %s." +msgstr[0] "%s Anwender, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2778 +msgid "Add a new category." +msgstr "" + +#: lib/php/monica/list.inc.php:2788 +#, fuzzy +msgid "Search for a category:" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:2806 +#, fuzzy, c-format +msgid "Your query found %s category." +msgid_plural "Your query found %s categories." +msgstr[0] "Ihr Anfrage ergab %s Anwender." +msgstr[1] "Ihr Anfrage ergab %s Anwender." + +#: lib/php/monica/list.inc.php:2813 +#, fuzzy, c-format +msgid "%s category." +msgid_plural "%s categories." +msgstr[0] "%s Seite." +msgstr[1] "%s Seiten." + +#: lib/php/monica/list.inc.php:2822 +#, fuzzy, c-format +msgid "Your query found %s category, listing %s to %s." +msgid_plural "Your query found %s categories, listing %s to %s." +msgstr[0] "Ihre Anfrage ergab %s Seite, angezeigt werden %s bis %s." +msgstr[1] "Ihre Anfrage ergab %s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2831 +#, fuzzy, c-format +msgid "%s category, listing %s to %s." +msgid_plural "%s categories, listing %s to %s." +msgstr[0] "%s Seite, angezeigt werden %s bis %s." +msgstr[1] "%s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2849 +msgid "Add a new categorization record." +msgstr "" + +#: lib/php/monica/list.inc.php:2859 +#, fuzzy +msgid "Search for a categorization record:" +msgstr "Script-Berechtigung suchen:" + +#: lib/php/monica/list.inc.php:2877 +#, fuzzy, c-format +msgid "Your query found %s categorization record." +msgid_plural "Your query found %s categorization records." +msgstr[0] "Ihre Anfrage ergab %s Seite." +msgstr[1] "Ihre Anfrage ergab %s Seiten." + +#: lib/php/monica/list.inc.php:2884 +#, c-format +msgid "%s categorization record." +msgid_plural "%s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2893 +#, fuzzy, c-format +msgid "Your query found %s categorization record, listing %s to %s." +msgid_plural "Your query found %s categorization records, listing %s to %s." +msgstr[0] "Ihre Anfrage ergab %s Seite, angezeigt werden %s bis %s." +msgstr[1] "Ihre Anfrage ergab %s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2902 +#, fuzzy, c-format +msgid "%s categorization record, listing %s to %s." +msgid_plural "%s categorization records, listing %s to %s." +msgstr[0] "%s Seite, angezeigt werden %s bis %s." +msgstr[1] "%s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2921 +#, fuzzy +msgid "Select a Page" +msgstr "Auswählen" + +#: lib/php/monica/list.inc.php:2922 +msgid "Manage Pages" +msgstr "Seiten verwalten" + +#: lib/php/monica/list.inc.php:2952 lib/php/monica/list.inc.php:3066 +#: lib/php/monica/list.inc.php:3173 lib/php/monica/list.inc.php:3237 +#: lib/php/monica/list.inc.php:3358 +msgid "Hidden" +msgstr "Verborgen" + +#: lib/php/monica/list.inc.php:2953 lib/php/monica/list.inc.php:3067 +#: lib/php/monica/list.inc.php:3174 lib/php/monica/list.inc.php:3238 +#: lib/php/monica/list.inc.php:3359 +msgid "Shown" +msgstr "Angezeigt" + +#: lib/php/monica/list.inc.php:2963 +msgid "Write a new page." +msgstr "" + +#: lib/php/monica/list.inc.php:2973 +msgid "Search for a page:" +msgstr "Seite suchen:" + +#: lib/php/monica/list.inc.php:2991 +#, c-format +msgid "Your query found %s page." +msgid_plural "Your query found %s pages." +msgstr[0] "Ihre Anfrage ergab %s Seite." +msgstr[1] "Ihre Anfrage ergab %s Seiten." + +#: lib/php/monica/list.inc.php:2998 +#, c-format +msgid "%s page." +msgid_plural "%s pages." +msgstr[0] "%s Seite." +msgstr[1] "%s Seiten." + +#: lib/php/monica/list.inc.php:3007 +#, c-format +msgid "Your query found %s page, listing %s to %s." +msgid_plural "Your query found %s pages, listing %s to %s." +msgstr[0] "Ihre Anfrage ergab %s Seite, angezeigt werden %s bis %s." +msgstr[1] "Ihre Anfrage ergab %s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3016 +#, c-format +msgid "%s page, listing %s to %s." +msgid_plural "%s pages, listing %s to %s." +msgstr[0] "%s Seite, angezeigt werden %s bis %s." +msgstr[1] "%s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3035 +msgid "Select a News Article" +msgstr "" + +#: lib/php/monica/list.inc.php:3036 +msgid "Manage News" +msgstr "" + +#: lib/php/monica/list.inc.php:3077 +msgid "Write a new news article." +msgstr "" + +#: lib/php/monica/list.inc.php:3087 +#, fuzzy +msgid "Search for a news article:" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:3105 +#, fuzzy, c-format +msgid "Your query found %s news article." +msgid_plural "Your query found %s news articles." +msgstr[0] "Ihr Anfrage ergab %s Anwender." +msgstr[1] "Ihr Anfrage ergab %s Anwender." + +#: lib/php/monica/list.inc.php:3112 +#, c-format +msgid "%s news article." +msgid_plural "%s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3121 +#, fuzzy, c-format +msgid "Your query found %s news article, listing %s to %s." +msgid_plural "Your query found %s news articles, listing %s to %s." +msgstr[0] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." +msgstr[1] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3130 +#, fuzzy, c-format +msgid "%s news article, listing %s to %s." +msgid_plural "%s news articles, listing %s to %s." +msgstr[0] "%s Anwender, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3149 +msgid "Select a Link Category" +msgstr "" + +#: lib/php/monica/list.inc.php:3150 +msgid "Manage Link Categories" +msgstr "" + +#: lib/php/monica/list.inc.php:3197 +#, fuzzy +msgid "Select a Link" +msgstr "Auswählen" + +#: lib/php/monica/list.inc.php:3198 +msgid "Manage Links" +msgstr "" + +#: lib/php/monica/list.inc.php:3248 +msgid "Add a new related link." +msgstr "" + +#: lib/php/monica/list.inc.php:3258 +#, fuzzy +msgid "Search for a related link:" +msgstr "Seite suchen:" + +#: lib/php/monica/list.inc.php:3276 +#, fuzzy, c-format +msgid "Your query found %s related link." +msgid_plural "Your query found %s related links." +msgstr[0] "Ihre Anfrage ergab %s Seite." +msgstr[1] "Ihre Anfrage ergab %s Seiten." + +#: lib/php/monica/list.inc.php:3283 +#, c-format +msgid "%s related link." +msgid_plural "%s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3292 +#, fuzzy, c-format +msgid "Your query found %s related link, listing %s to %s." +msgid_plural "Your query found %s related links, listing %s to %s." +msgstr[0] "Ihre Anfrage ergab %s Seite, angezeigt werden %s bis %s." +msgstr[1] "Ihre Anfrage ergab %s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3301 +#, fuzzy, c-format +msgid "%s related link, listing %s to %s." +msgid_plural "%s related links, listing %s to %s." +msgstr[0] "%s Seite, angezeigt werden %s bis %s." +msgstr[1] "%s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3321 +msgid "Select a Link Categorization Record" +msgstr "" + +#: lib/php/monica/list.inc.php:3322 +msgid "Manage Link Categorization" +msgstr "" + +#: lib/php/monica/list.inc.php:3327 +msgid "Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3383 +msgid "Select a Country" +msgstr "" + +#: lib/php/monica/list.inc.php:3384 +msgid "Manage Country Data" +msgstr "" + +#: lib/php/monica/list.inc.php:3389 +msgid "Code" +msgstr "Code" + +#: lib/php/monica/list.inc.php:3390 +msgid "Country name" +msgstr "" + +#: lib/php/monica/list.inc.php:3399 +#, fuzzy +msgid "Add a new country record." +msgstr "%s Script-Berechtigung." + +#: lib/php/monica/list.inc.php:3409 +#, fuzzy +msgid "Search for a country:" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:3427 +#, fuzzy, c-format +msgid "Your query found %s country." +msgid_plural "Your query found %s countries." +msgstr[0] "Ihr Anfrage ergab %s Anwender." +msgstr[1] "Ihr Anfrage ergab %s Anwender." + +#: lib/php/monica/list.inc.php:3434 +#, fuzzy, c-format +msgid "%s country." +msgid_plural "%s countries." +msgstr[0] "%s Anwender." +msgstr[1] "%s Anwender." + +#: lib/php/monica/list.inc.php:3443 +#, fuzzy, c-format +msgid "Your query found %s country, listing %s to %s." +msgid_plural "Your query found %s countries, listing %s to %s." +msgstr[0] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." +msgstr[1] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3452 +#, fuzzy, c-format +msgid "%s country, listing %s to %s." +msgid_plural "%s countries, listing %s to %s." +msgstr[0] "%s Anwender, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3474 +msgid "Browse the Activity Log" +msgstr "" + +#: lib/php/monica/list.inc.php:3586 +#, fuzzy +msgid "Please fill in the number of rows to display." +msgstr "Bitte Benutzernamen eingeben." + +#: lib/php/monica/list.inc.php:3590 +#, fuzzy, c-format +msgid "This number of rows to display is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Reihenfolge ist zu lang. (Die maximale Länge beträgt %" +"d)" + +#: lib/php/monica/list.inc.php:3595 +#, fuzzy +msgid "Please fill in a positive integer number of rows to display." +msgstr "Bitte geben Sie die Reihenfolge ein." + +#: lib/php/monica/list.inc.php:3599 lib/php/monica/list.inc.php:3609 +#, fuzzy, c-format +msgid "" +"The number of rows to display is too small. Please fill in a larger number " +"of rows to display between %d and %d." +msgstr "" +"Die Eingabe für die Reihenfolge ist zu klein. Bitte geben Sie eine größere " +"Reihenfolge zwischen %d und %d ein." + +#: lib/php/monica/list.inc.php:3613 +#, fuzzy, c-format +msgid "" +"The number of rows to display is too large. Please fill in a smaller number " +"of rows to display between %d and %d." +msgstr "" +"Die Eingabe für die Reihenfolge ist zu lang. Bitte geben Sie eine kleinere " +"Reihenfolge zwischen %d und %d ein." + +#: lib/php/monica/list.inc.php:3638 +#, fuzzy +msgid "Search for log entries:" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:3641 +#, fuzzy +msgid "Display" +msgstr "Spalten anzeigen:" + +#: lib/php/monica/list.inc.php:3654 +#, fuzzy +msgid "Display rows:" +msgstr "Spalten anzeigen:" + +#: lib/php/monica/list.inc.php:3677 +#, fuzzy, c-format +msgid "Your query found %s log entry." +msgid_plural "Your query found %s log entries." +msgstr[0] "Ihr Anfrage ergab %s Anwender." +msgstr[1] "Ihr Anfrage ergab %s Anwender." + +#: lib/php/monica/list.inc.php:3684 +#, fuzzy, c-format +msgid "%s log entry." +msgid_plural "%s log entries." +msgstr[0] "%s Anwender." +msgstr[1] "%s Anwender." + +#: lib/php/monica/list.inc.php:3693 +#, fuzzy, c-format +msgid "Your query found %s log entry, listing %s to %s." +msgid_plural "Your query found %s log entries, listing %s to %s." +msgstr[0] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." +msgstr[1] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3702 +#, fuzzy, c-format +msgid "%s log entry, listing %s to %s." +msgid_plural "%s log entries, listing %s to %s." +msgstr[0] "%s Anwender, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/lninfo.inc.php:28 +msgid "English" +msgstr "Englisch" + +#: lib/php/monica/lninfo.inc.php:39 +msgid "Traditional Chinese" +msgstr "Traditionelles Chinesisch" + +#: lib/php/monica/lninfo.inc.php:50 +msgid "Simplified Chinese" +msgstr "Vereinfachtes Chinesisch" + +#: lib/php/monica/lninfo.inc.php:61 +msgid "Chinese" +msgstr "Chinesische" + +#: lib/php/monica/lninfo.inc.php:72 +msgid "Japanese" +msgstr "Japanisch" + +#: lib/php/monica/lninfo.inc.php:83 +msgid "Korean" +msgstr "Koreanisch" + +#: lib/php/monica/lninfo.inc.php:94 +msgid "German" +msgstr "Deutsch" + +#: lib/php/monica/lninfo.inc.php:105 +msgid "Spanish" +msgstr "Spanische" + +#: lib/php/monica/lninfo.inc.php:366 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:738 +msgid "Web pages" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:739 +#, fuzzy +msgid "News" +msgstr "Neu:" + +#: lib/php/monica/pagefunc.inc.php:740 +msgid "Related links" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:741 +msgid "Home page" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:742 +msgid "Whole web site" +msgstr "" + +#: lib/php/monica/pic.inc.php:39 +msgid "Left-aligned" +msgstr "Linksbündig" + +#: lib/php/monica/pic.inc.php:40 +msgid "Right-aligned" +msgstr "Rechtsbündig" + +#: lib/php/monica/pic.inc.php:74 lib/php/monica/pic.inc.php:77 +#, fuzzy, c-format +msgid "This picture file is too large (Max %s)." +msgstr "" +"Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/pic.inc.php:92 +msgid "Please upload only PNG, JPEG or GIF files." +msgstr "" + +#: lib/php/monica/pic.inc.php:153 +#, c-format +msgid "Width: %d, height: %d, ratio: %0.2f" +msgstr "Breite: %d, Höhe: %d, Aspekt: %0.2f" + +#: lib/php/monica/pic.inc.php:176 +msgid "Please specify a numeric ratio." +msgstr "Bitte geben Sie eine numerische Aspektrate ein." + +#: lib/php/monica/pic.inc.php:180 +msgid "Please specify a positive ratio." +msgstr "Bitte geben Sie eine positive Aspektrate ein." + +#: lib/php/monica/pic.inc.php:183 +#, c-format +msgid "Please specify a ratio less than or equal to %0.2f." +msgstr "Bitte geben Sie eine Aspektrate kleiner oder gleich %0.2f ein." + +#: lib/php/monica/pic.inc.php:189 +msgid "This image is too large to display." +msgstr "Das Bild ist zu gro?um angezeigt zu werden." + +#: lib/php/monica/preview.inc.php:47 +#, c-format +msgid "Unknown preview source: \"%s\"." +msgstr "" + +#: lib/php/monica/preview.inc.php:67 +#, c-format +msgid "Unknown preview form: %d." +msgstr "" + +#: lib/php/monica/preview.inc.php:143 +msgid "Preview Mark Area" +msgstr "" + +#: lib/php/monica/preview.inc.php:148 +msgid "Finish preview and return." +msgstr "" + +#: lib/php/monica/process.inc.php:237 +msgid "This record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:243 +msgid "This record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:247 +msgid "This record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:251 +msgid "This record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:406 +#, fuzzy +msgid "This category was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:412 +#, fuzzy +msgid "This category has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:416 +#, fuzzy +msgid "This category has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:420 +#, fuzzy +msgid "This category has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:433 +#, fuzzy +msgid "This categorization record was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:439 +#, fuzzy +msgid "This categorization record has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:443 +#, fuzzy +msgid "This categorization record has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:447 +#, fuzzy +msgid "This categorization record has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:782 +msgid "This user account was not modified." +msgstr "Dieser Anwender-Account wurde nicht verändert." + +#: lib/php/monica/process.inc.php:788 +msgid "This user account has been successfully added." +msgstr "Dieser Anwender-Account wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:792 +msgid "This user account has been successfully updated." +msgstr "Dieser Anwender-Account wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:796 +msgid "This user account has been successfully deleted." +msgstr "Dieser Anwender-Account wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1074 +msgid "This group was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1080 +msgid "This group has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1084 +msgid "This group has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1088 +msgid "This group has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1152 lib/php/monica/process.inc.php:1230 +#, fuzzy +msgid "This membership record was not modified." +msgstr "Diese Anwender-Einstellung wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1158 lib/php/monica/process.inc.php:1236 +#, fuzzy +msgid "This membership record has been successfully added." +msgstr "Diese Anwender-Einstellung wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1162 lib/php/monica/process.inc.php:1240 +#, fuzzy +msgid "This membership record has been successfully updated." +msgstr "Diese Anwender-Einstellung wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1166 lib/php/monica/process.inc.php:1244 +#, fuzzy +msgid "This membership record has been successfully deleted." +msgstr "Diese Anwender-Einstellung wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1308 +#, fuzzy +msgid "This script privilege record was not modified." +msgstr "Die Script-Berechtigung wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1314 +#, fuzzy +msgid "This script privilege record has been successfully added." +msgstr "Die Script-Berechtigung wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1318 +#, fuzzy +msgid "This script privilege record has been successfully updated." +msgstr "Die Script-Berechtigung wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1322 +#, fuzzy +msgid "This script privilege record has been successfully deleted." +msgstr "Die Script-Berechtigung wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1438 +msgid "This user preference was not modified." +msgstr "Diese Anwender-Einstellung wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1444 +msgid "This user preference has been successfully added." +msgstr "Diese Anwender-Einstellung wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1448 +msgid "This user preference has been successfully updated." +msgstr "Diese Anwender-Einstellung wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1452 +msgid "This user preference has been successfully deleted." +msgstr "Diese Anwender-Einstellung wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1560 +#, fuzzy +msgid "This user request was not modified." +msgstr "Dieser Anwender-Account wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1566 +#, fuzzy +msgid "This user request has been successfully added." +msgstr "Dieser Anwender-Account wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1570 +#, fuzzy +msgid "This user request has been successfully updated." +msgstr "Dieser Anwender-Account wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1574 +#, fuzzy +msgid "This user request has been successfully deleted." +msgstr "Dieser Anwender-Account wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1685 +#, fuzzy +msgid "This page was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1691 +#, fuzzy +msgid "This page has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1695 +#, fuzzy +msgid "This page has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1699 +#, fuzzy +msgid "This page has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1874 +#, fuzzy +msgid "This news article was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1880 +#, fuzzy +msgid "This news article has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1884 +#, fuzzy +msgid "This news article has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1888 +#, fuzzy +msgid "This news article has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1997 +#, fuzzy +msgid "This country was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:2003 +#, fuzzy +msgid "This country has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:2007 +#, fuzzy +msgid "This country has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:2011 +#, fuzzy +msgid "This country has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:2097 +#, fuzzy, c-format +msgid "" +"The specified web pages have been successfully rebuilt. (%0.3f seconds)" +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:2158 +#, c-format +msgid "Welcome, %s!" +msgstr "Herzlich Willkommen, %s!" + +#: lib/php/monica/process.inc.php:2204 +msgid "You have successfully logged out." +msgstr "Sie haben sich erfolgreich abgemeldet." + +#: lib/php/monica/process.inc.php:2439 +#, fuzzy +msgid "This related link was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:2445 +#, fuzzy +msgid "This related link has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:2449 +#, fuzzy +msgid "This related link has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:2453 +#, fuzzy +msgid "This related link has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/request.inc.php:38 +#, fuzzy +msgid "Please specify the request." +msgstr "Bitte Anwender wählen." + +#: lib/php/monica/request.inc.php:46 lib/php/monica/request.inc.php:55 +#, c-format +msgid "Invalid request S/N: %s." +msgstr "" + +#: lib/php/monica/sitesize.inc.php:41 +#, c-format +msgid "Currently using files %s.\n" +msgstr "" + +#: lib/php/monica/sitesize.inc.php:46 +#, c-format +msgid "Currently using files %s, database %s, total %s.\n" +msgstr "" + +#: lib/php/monica/upload.inc.php:70 +#, c-format +msgid "MIME file type: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:71 +#, c-format +msgid "File name: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:72 +#, c-format +msgid "File size: %s bytes" +msgstr "" + +#: lib/php/monica/validate.inc.php:116 +msgid "HTML Validatior Logo Area" +msgstr "" + +#: lib/php/monica/validate.inc.php:117 +msgid "HTML validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:118 +#, c-format +msgid "Valid %s!" +msgstr "" + +#: lib/php/monica/validate.inc.php:119 +msgid "CSS validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:120 +msgid "Valid CSS!" +msgstr "" + +#: lib/php/monica/validate.inc.php:121 +msgid "Explanation of Level Triple-A Conformance" +msgstr "" + +#: lib/php/monica/validate.inc.php:122 +msgid "" +"Level Triple-A conformance icon, W3C-WAI Web Content Accessibility " +"Guidelines 1.0" +msgstr "" + +#, fuzzy +#~ msgid "This file does not exist anymore. Please upload another one." +#~ msgstr "" +#~ "Dieser Bereich existiert nicht mehr. Wählen Sie bitte einen anderen." + +#, fuzzy +#~ msgid "This file is too large. (Max. size %s)" +#~ msgstr "" +#~ "Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#~ msgid "%s..." +#~ msgstr "%s..." + +#~ msgid "..." +#~ msgstr "..." + +#, fuzzy +#~ msgid "Please select the section to rebuild." +#~ msgstr "Bitte Anwender wählen." + +#, fuzzy +#~ msgid "This section does not exist anymore. Please select another one." +#~ msgstr "" +#~ "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#, fuzzy +#~ msgid "" +#~ "This group membership already exists. You cannot create a duplicated one." +#~ msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#, fuzzy +#~ msgid "Search for a group membership record:" +#~ msgstr "Gruppe suchen:" + +#, fuzzy +#~ msgid "Your query found %s group membership record." +#~ msgid_plural "Your query found %s group membership records." +#~ msgstr[0] "Ihre Abfrage ergab %s Gruppe." +#~ msgstr[1] "Ihre Abfrage ergab %s Gruppen." + +#, fuzzy +#~ msgid "Your query found %s group membership record, listing %s to %s." +#~ msgid_plural "" +#~ "Your query found %s group membership records, listing %s to %s." +#~ msgstr[0] "Ihre Abfrage ergab %s Gruppe, angezeigt werden %s bis %s." +#~ msgstr[1] "Ihre Abfrage ergab %s Gruppen, angezeigt werden %s bis %s." + +#, fuzzy +#~ msgid "%s group membership record, listing %s to %s." +#~ msgid_plural "%s group membership records, listing %s to %s." +#~ msgstr[0] "%s Gruppe, angezeigt werden %s bis %s." +#~ msgstr[1] "%s Gruppen, angezeigt werden %s bis %s." + +#, fuzzy +#~ msgid "This group membership was not modified." +#~ msgstr "Diese Anwender-Einstellung wurde nicht verändert." + +#, fuzzy +#~ msgid "This group membership has been successfully added." +#~ msgstr "Diese Anwender-Einstellung wurde erfolgreich hinzugefügt." + +#, fuzzy +#~ msgid "This group membership has been successfully updated." +#~ msgstr "Diese Anwender-Einstellung wurde erfolgreich aktualisiert." + +#, fuzzy +#~ msgid "This group membership has been successfully deleted." +#~ msgstr "Diese Anwender-Einstellung wurde erfolgreich gelöscht." + +#~ msgid "Links:" +#~ msgstr "Links:" + +#, fuzzy +#~ msgid "This PDF. file is too large. (Max. size %s bytes)" +#~ msgstr "" +#~ "Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#~ msgid "Full Name" +#~ msgstr "Voller Name" + +#~ msgid "Pref. Language" +#~ msgstr "Bev. Sprache" + +#, fuzzy +#~ msgid "Country?" +#~ msgstr "%s Anwender." + +#, fuzzy +#~ msgid "Please fill in the page size." +#~ msgstr "Bitte geben Sie das Datum ein. " + +#, fuzzy +#~ msgid "This page size is too long. (Max. length %d)" +#~ msgstr "" +#~ "Die Eingabe für das Datum ist zu lang (Die maximale Länge beträgt %d)." + +#, fuzzy +#~ msgid "Please fill in a positive integer page size." +#~ msgstr "Geben Sie bitte die Berechtigungs-Beschreibung ein." + +#, fuzzy +#~ msgid "" +#~ "The page size is too small. Please fill in a larger page size between %d " +#~ "and %d." +#~ msgstr "" +#~ "Die Kursgebühr ist zu klein. Bitte geben Sie eine größere Kursgebühr " +#~ "zwischen %d und %d ein." + +#, fuzzy +#~ msgid "" +#~ "The page size is too large. Please fill in a smaller page size between %" +#~ "d and %d." +#~ msgstr "" +#~ "Die Kursgebühr ist zu gro? Bitte geben Sie eine kleinere Kursgebühr " +#~ "zwischen %d und %d ein." + +#~ msgid "Page size:" +#~ msgstr "Seitengröße:" + +#, fuzzy +#~ msgid "Submit and preview" +#~ msgstr "Vorschau neues Bild" + +#~ msgid "Submit" +#~ msgstr "Vorschau" + +#~ msgid "Save" +#~ msgstr "Speichern" + +#~ msgid "Click here to add a new user." +#~ msgstr "" +#~ "Klicken Sie hier um einen neuen Anwender hinzuzufügen." + +#~ msgid "Click here to add a new group." +#~ msgstr "" +#~ "Klicken Sie hier um eine neue Gruppe hinzuzufügen." + +#~ msgid "Pref. Name" +#~ msgstr "Pref. Name" + +#~ msgid "Click here to add a new page." +#~ msgstr "" +#~ "Klicken Sie hier um eine neue Seite hinzuzufügen." diff --git a/po/monica/de_DE.pox b/po/monica/de_DE.pox new file mode 100644 index 0000000..43fdca6 --- /dev/null +++ b/po/monica/de_DE.pox @@ -0,0 +1,3763 @@ +# German PO file for the monica core +# Copyright (C) 2003-2018 Pristine Commnications +# This file is distributed under the same license as the monica package. +# imacat , 2003-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: monica 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 12:42+0800\n" +"PO-Revision-Date: 2018-11-02 01:22+0800\n" +"Last-Translator: Volker Lehmacher \n" +"Language-Team: German \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: lib/php/monica/checker.inc.php:159 +msgid "Please select a user." +msgstr "Bitte Anwender wählen" + +#: lib/php/monica/checker.inc.php:163 +msgid "This user does not exist anymore. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:181 +msgid "Please select a group." +msgstr "Bitte wählen Sie eine Gruppe." + +# admin/userpriv.php:266, admin/groups.php:724 +#: lib/php/monica/checker.inc.php:185 +msgid "This group does not exist anymore. Please select another one." +msgstr "Diese Gruppe existiert nicht mehr. Wählen Sie bitte eine andere." + +#: lib/php/monica/checker.inc.php:203 +#, fuzzy +msgid "Please fill in the script." +msgstr "Bitte Beschreibung eingeben." + +#: lib/php/monica/checker.inc.php:207 +#, c-format +msgid "This script is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für dieses Script ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:212 +msgid "This script is not a valid script. Please specify another one." +msgstr "Dieses Script ist kein gültiges Script. Wählen Sie bitte ein anderes." + +#: lib/php/monica/checker.inc.php:230 +msgid "Please fill in the date." +msgstr "Bitte geben Sie das Datum ein. " + +#: lib/php/monica/checker.inc.php:234 lib/php/monica/checker.inc.php:238 +#: lib/php/monica/checker.inc.php:241 +#, fuzzy +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "Bitte geben Sie das Enddatum im Format YYYY-MM-DD ein." + +#: lib/php/monica/checker.inc.php:259 +msgid "Please fill in the ID." +msgstr "Bitte ID eingeben." + +#: lib/php/monica/checker.inc.php:263 +#, c-format +msgid "This ID. is too long. (Max. length %d)" +msgstr "Die Eingabe für diese ID ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:267 +#, c-format +msgid "This ID. is too short. (Min. length %d)" +msgstr "Die Eingabe für diese ID ist zu kurz (Die minimale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:272 +#, fuzzy +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "" +"Die ID darf nur aus klein geschriebenen Buchstaben und Unterstrichen " +"bestehen." + +#: lib/php/monica/checker.inc.php:294 +msgid "Please fill in the order." +msgstr "Bitte geben Sie die Reihenfolge ein." + +#: lib/php/monica/checker.inc.php:298 +#, c-format +msgid "This order is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Reihenfolge ist zu lang. (Die maximale Länge beträgt %" +"d)" + +#: lib/php/monica/checker.inc.php:303 +#, fuzzy +msgid "Please fill in a positive integer order." +msgstr "Bitte geben Sie die Reihenfolge ein." + +#: lib/php/monica/checker.inc.php:307 lib/php/monica/checker.inc.php:317 +#, c-format +msgid "" +"The order is too small. Please fill in a larger order between %d and %d." +msgstr "" +"Die Eingabe für die Reihenfolge ist zu klein. Bitte geben Sie eine größere " +"Reihenfolge zwischen %d und %d ein." + +#: lib/php/monica/checker.inc.php:321 +#, c-format +msgid "" +"The order is too large. Please fill in a smaller order between %d and %d." +msgstr "" +"Die Eingabe für die Reihenfolge ist zu lang. Bitte geben Sie eine kleinere " +"Reihenfolge zwischen %d und %d ein." + +#: lib/php/monica/checker.inc.php:348 +#, fuzzy +msgid "Please fill in the page path." +msgstr "Bitte geben Sie den Speicherplatz ein." + +#: lib/php/monica/checker.inc.php:352 +#, fuzzy, c-format +msgid "This page path is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Speicherplatz ist zu lang (Die maximale Länge beträgt " +"%d)." + +#: lib/php/monica/checker.inc.php:365 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "Diese Seite besteht bereits. Sie können kein Duplikat erstellen." + +#: lib/php/monica/checker.inc.php:369 +#, fuzzy +msgid "Please fill in an absolute page path." +msgstr "Bitte geben Sie den Speicherplatz ein." + +#: lib/php/monica/checker.inc.php:373 +#, fuzzy +msgid "Please fill in a valid page path." +msgstr "Bitte geben Sie ein gültiges Enddatum ein." + +#: lib/php/monica/checker.inc.php:377 +msgid "You cannot overwrite the cover home page." +msgstr "Sie können die Titelseite nicht überschreiben." + +#: lib/php/monica/checker.inc.php:381 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "" + +#: lib/php/monica/checker.inc.php:422 lib/php/monica/checker.inc.php:428 +#, fuzzy +msgid "Please fill in the attachment description." +msgstr "Bitte Beschreibung eingeben." + +#: lib/php/monica/checker.inc.php:432 +#, fuzzy, c-format +msgid "This attachment description is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für die Beschreibung ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:449 +#, fuzzy +msgid "This PDF. file does not exist anymore. Please upload another one." +msgstr "Dieser Bereich existiert nicht mehr. Wählen Sie bitte einen anderen." + +#: lib/php/monica/checker.inc.php:456 +#, fuzzy, c-format +msgid "This PDF. file is too large. (Max. size %s)" +msgstr "" +"Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:461 +#, fuzzy +msgid "Please upload only PDF. file." +msgstr "Bitte geben Sie den Titel ein." + +#: lib/php/monica/checker.inc.php:479 +msgid "Please fill in the title." +msgstr "Bitte geben Sie den Titel ein." + +#: lib/php/monica/checker.inc.php:483 +#, c-format +msgid "This title is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:502 +#, fuzzy +msgid "Please fill in the subject." +msgstr "Bitte die Kursgebühren eingeben." + +#: lib/php/monica/checker.inc.php:506 +#, fuzzy, c-format +msgid "This subject is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für dieses Script ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:524 lib/php/monica/form.inc.php:3159 +#: lib/php/monica/form.inc.php:3172 +#, fuzzy +msgid "Fill in the content here." +msgstr "Bitte geben Sie den Inhalt ein." + +#: lib/php/monica/checker.inc.php:528 +msgid "Please fill in the content." +msgstr "Bitte geben Sie den Inhalt ein." + +#: lib/php/monica/checker.inc.php:532 +#, c-format +msgid "This content is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Inhalt ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:551 +msgid "Please fill in the keywords." +msgstr "Bitte geben Sie die Stichwörter ein." + +#: lib/php/monica/checker.inc.php:555 +#, c-format +msgid "This keyword list is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Stichwörter ist zu lang (Die maximale Länge beträgt %" +"d)." + +#: lib/php/monica/checker.inc.php:572 +#, fuzzy +msgid "Please select a proper pinyin." +msgstr "Bitte wählen Sie eine Gruppe." + +#: lib/php/monica/checker.inc.php:578 +#, fuzzy, c-format +msgid "This pinyin is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Inhalt ist zu lang (Die maximale Länge beträgt %d)." + +# admin/userpriv.php:266, admin/groups.php:724 +#: lib/php/monica/checker.inc.php:583 +#, fuzzy +msgid "" +"This pinyin does not match the Chinese. Please select a proper pinyin from " +"the list." +msgstr "Diese Gruppe existiert nicht mehr. Wählen Sie bitte eine andere." + +#: lib/php/monica/checker.inc.php:609 lib/php/monica/pic.inc.php:82 +#, fuzzy +msgid "Please upload the picture." +msgstr "Bitte Kategorie wählen." + +#: lib/php/monica/checker.inc.php:616 lib/php/monica/checker.inc.php:3214 +#, fuzzy +msgid "This picture does not exist anymore. Please upload another one." +msgstr "Dieser Bereich existiert nicht mehr. Wählen Sie bitte einen anderen." + +#: lib/php/monica/checker.inc.php:622 +#, fuzzy, c-format +msgid "This picture is too large. Please upload another one. (Max. size %d)" +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:639 lib/php/monica/form.inc.php:3588 +#, fuzzy, c-format +msgid "Please upload a new picture from %s." +msgstr "Bitte neue Seite aus %s erschaffen." + +#: lib/php/monica/checker.inc.php:664 lib/php/monica/checker.inc.php:727 +#, fuzzy +msgid "Please fill in the picture caption." +msgstr "Bitte geben Sie die Einführung ein." + +#: lib/php/monica/checker.inc.php:668 lib/php/monica/checker.inc.php:731 +#, fuzzy, c-format +msgid "This picture caption is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Einführung ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:686 lib/php/monica/checker.inc.php:749 +#, fuzzy +msgid "Please select the picture position." +msgstr "Bitte Kategorie wählen." + +#: lib/php/monica/checker.inc.php:692 lib/php/monica/checker.inc.php:755 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:791 lib/php/monica/checker.inc.php:794 +#, fuzzy, c-format +msgid "Your uploaded file is too large (Max %s)." +msgstr "" +"Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:797 lib/php/monica/pic.inc.php:80 +msgid "" +"Upload not completed. Disk may be full or connection may be closed in the " +"half. You may try to upload again, or contact the system administrator for " +"this problem." +msgstr "" + +#: lib/php/monica/checker.inc.php:799 lib/php/monica/pic.inc.php:84 +#, c-format +msgid "Upload failed with an unknown error (%d)." +msgstr "" + +#: lib/php/monica/checker.inc.php:1183 lib/php/monica/chkfunc.inc.php:59 +#: lib/php/monica/chkfunc.inc.php:72 lib/php/monica/preview.inc.php:29 +#, c-format +msgid "The following field was not received: \"%s\"." +msgstr "Das folgende Feld wurde nicht erhalten: \"%s\"." + +#: lib/php/monica/checker.inc.php:1262 +msgid "Please fill in the user ID." +msgstr "Bitte Benutzernamen eingeben." + +#: lib/php/monica/checker.inc.php:1266 +#, c-format +msgid "This user ID. is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Benutzernamen ist zu lang (Die maximale Länge beträgt " +"%d)." + +#: lib/php/monica/checker.inc.php:1270 +#, c-format +msgid "This user ID. is too short. (Min. length %d)" +msgstr "" +"Die Eingabe für diesen Benutzernamen ist zu kurz (Die minimale Länge beträgt " +"%d)." + +#: lib/php/monica/checker.inc.php:1275 +#, fuzzy +msgid "" +"Only lower-case English letters, numbers, at-signs, dots, dashes and " +"underscores are allowed for the user ID." +msgstr "" +"Die ID darf nur aus klein geschriebenen Buchstaben und Unterstrichen " +"bestehen." + +#: lib/php/monica/checker.inc.php:1287 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "" +"Dieser Anwender hat bereits einen Account. Sie können kein Duplikat " +"erstellen." + +#: lib/php/monica/checker.inc.php:1317 +msgid "Please fill in the password." +msgstr "Bitte Passwort eingeben." + +#: lib/php/monica/checker.inc.php:1320 +msgid "Please confirm the password." +msgstr "Bitte Passwort bestätigen." + +#: lib/php/monica/checker.inc.php:1324 +#, c-format +msgid "This password is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für dieses Passwort ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:1329 +#, c-format +msgid "This password is too short. (Min. length %d)" +msgstr "" +"Die Eingabe für dieses Passwort ist zu kurz (Die minimale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:1334 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "" + +#: lib/php/monica/checker.inc.php:1345 +msgid "This password is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1360 +msgid "This password does not contain enough different characters." +msgstr "" + +#: lib/php/monica/checker.inc.php:1364 +msgid "This password is too simplistic/systematic." +msgstr "" + +#: lib/php/monica/checker.inc.php:1368 +msgid "This password is based on a dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1370 +msgid "This password is based on a (reversed) dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1372 +#, fuzzy +msgid "This password is too simple." +msgstr "" +"Die Eingabe für dieses Passwort ist zu kurz (Die minimale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:1378 +#, fuzzy +msgid "You cannot use a password that is based on the user ID." +msgstr "" +"Die ID darf nur aus klein geschriebenen Buchstaben und Unterstrichen " +"bestehen." + +#: lib/php/monica/checker.inc.php:1397 +#, fuzzy +msgid "Please fill in the name." +msgstr "Bitte geben Sie das Datum ein. " + +#: lib/php/monica/checker.inc.php:1401 +#, fuzzy, c-format +msgid "This name is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen vollen Namen ist zu lang (Die maximale Länge beträgt %" +"d)." + +#: lib/php/monica/checker.inc.php:1420 +#, fuzzy +msgid "Please fill in the e-mail." +msgstr "Bitte geben Sie den Titel ein." + +#: lib/php/monica/checker.inc.php:1424 +#, fuzzy, c-format +msgid "This e-mail is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:1428 +#, fuzzy, c-format +msgid "This e-mail is too short. (Min. length %d)" +msgstr "Die Eingabe für diese ID ist zu kurz (Die minimale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:1437 +#, fuzzy +msgid "Please fill in a valid e-mail address." +msgstr "Bitte geben Sie ein gültiges Enddatum ein." + +#: lib/php/monica/checker.inc.php:1439 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:1461 lib/php/monica/checker.inc.php:1655 +#, fuzzy +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#: lib/php/monica/checker.inc.php:1478 +msgid "You cannot submit the super-user group along with other groups." +msgstr "" + +#: lib/php/monica/checker.inc.php:1480 +msgid "You cannot set the administrators group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1482 +#, fuzzy +msgid "You cannot set the all-users group." +msgstr "Sie können die Titelseite nicht überschreiben." + +#: lib/php/monica/checker.inc.php:1515 +msgid "Please fill in the group ID." +msgstr "Geben Sie bitte die Gruppen-ID ein." + +#: lib/php/monica/checker.inc.php:1519 +#, c-format +msgid "This group ID. is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Gruppen-ID ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:1523 +#, fuzzy, c-format +msgid "This group ID. is too short. (Min. length %d)" +msgstr "Die Eingabe für diese ID ist zu kurz (Die minimale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:1528 +#, fuzzy +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "" +"Die ID darf nur aus klein geschriebenen Buchstaben und Unterstrichen " +"bestehen." + +#: lib/php/monica/checker.inc.php:1540 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#: lib/php/monica/checker.inc.php:1558 +msgid "Please fill in the privilege description." +msgstr "Geben Sie bitte die Berechtigungs-Beschreibung ein." + +#: lib/php/monica/checker.inc.php:1562 +#, c-format +msgid "This privilege description is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Berechtigungs-Beschreibung ist zu lang. (Die maximale " +"Länge beträgt %d)" + +#: lib/php/monica/checker.inc.php:1585 +#, fuzzy +msgid "This user member is duplicated. You cannot set duplicated ones." +msgstr "" +"Dieser Anwender hat bereits einen Account. Sie können kein Duplikat " +"erstellen." + +#: lib/php/monica/checker.inc.php:1620 +#, fuzzy +msgid "This group member is duplicated. You cannot set duplicated ones." +msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#: lib/php/monica/checker.inc.php:1747 lib/php/monica/checker.inc.php:1855 +#, fuzzy +msgid "Please select a member." +msgstr "Bitte Anwender wählen" + +#: lib/php/monica/checker.inc.php:1751 lib/php/monica/checker.inc.php:1859 +#, fuzzy +msgid "This member does not exist anymore. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:1770 lib/php/monica/checker.inc.php:1883 +#, fuzzy +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "" +"Diese Anwender-Einstellung existiert bereits. Sie können kein Duplikat " +"erstellen." + +#: lib/php/monica/checker.inc.php:1837 +#, fuzzy +msgid "Please select a different belonging group." +msgstr "Bitte Gruppe auswählen." + +#: lib/php/monica/checker.inc.php:1864 +#, fuzzy +msgid "Please select a different group member." +msgstr "Bitte wählen Sie eine Gruppe." + +#: lib/php/monica/checker.inc.php:1958 +msgid "" +"This script privilege already exists. You cannot create a duplicated one." +msgstr "" +"Diese Script-Berechtigung existiert bereits. Sie können kein Duplikat " +"erstellen." + +#: lib/php/monica/checker.inc.php:1996 lib/php/monica/checker.inc.php:2184 +msgid "Please select the user." +msgstr "Bitte Anwender wählen." + +# admin/userpriv.php:266, admin/groups.php:724 +#: lib/php/monica/checker.inc.php:2002 lib/php/monica/checker.inc.php:2190 +#, fuzzy +msgid "This option is invalid. Please select a proper user." +msgstr "Diese Gruppe existiert nicht mehr. Wählen Sie bitte eine andere." + +#: lib/php/monica/checker.inc.php:2020 +#, fuzzy +msgid "Please set the preference domain." +msgstr "Bitte einen Einstellungs-Namen eingeben." + +# admin/userpriv.php:266, admin/groups.php:724 +#: lib/php/monica/checker.inc.php:2026 +#, fuzzy +msgid "This option is invalid. Please set a proper preference domain." +msgstr "Diese Gruppe existiert nicht mehr. Wählen Sie bitte eine andere." + +#: lib/php/monica/checker.inc.php:2039 lib/php/monica/checker.inc.php:2295 +#, fuzzy +msgid "Please fill in the preference domain." +msgstr "Bitte einen Einstellungs-Namen eingeben." + +#: lib/php/monica/checker.inc.php:2043 lib/php/monica/checker.inc.php:2299 +#, fuzzy, c-format +msgid "This preference domain is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Einstellungs-Namen ist zu lang (Die maximale Länge " +"beträgt %d)." + +#: lib/php/monica/checker.inc.php:2063 +msgid "Please fill in the preference name." +msgstr "Bitte einen Einstellungs-Namen eingeben." + +#: lib/php/monica/checker.inc.php:2067 +#, c-format +msgid "This preference name is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Einstellungs-Namen ist zu lang (Die maximale Länge " +"beträgt %d)." + +#: lib/php/monica/checker.inc.php:2086 +msgid "Please fill in the preference value." +msgstr "Bitte einen Einstellungs-Wert eingeben." + +#: lib/php/monica/checker.inc.php:2090 +#, c-format +msgid "This preference value is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen Einstellungs-Wert ist zu lang (Die maximale Länge " +"beträgt %d)." + +#: lib/php/monica/checker.inc.php:2119 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "" +"Diese Anwender-Einstellung existiert bereits. Sie können kein Duplikat " +"erstellen." + +#: lib/php/monica/checker.inc.php:2167 +#, fuzzy +msgid "Please select the request type." +msgstr "Bitte Anwender wählen." + +# admin/userpriv.php:266, admin/groups.php:724 +#: lib/php/monica/checker.inc.php:2173 +#, fuzzy +msgid "This option is invalid. Please select a proper request type." +msgstr "Diese Gruppe existiert nicht mehr. Wählen Sie bitte eine andere." + +#: lib/php/monica/checker.inc.php:2194 +msgid "You must choose anonymous for join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2197 +msgid "You cannot choose anonymous for non-join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2221 lib/php/monica/form.inc.php:5484 +#, fuzzy +msgid "Please fill in the request arguments list here." +msgstr "Bitte einen Einstellungs-Wert eingeben." + +#: lib/php/monica/checker.inc.php:2229 +#, fuzzy, c-format +msgid "This request arguments list is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Stichwörter ist zu lang (Die maximale Länge beträgt %" +"d)." + +#: lib/php/monica/checker.inc.php:2349 +#, fuzzy +msgid "Please fill in the number of rows per page." +msgstr "Bitte Benutzernamen eingeben." + +#: lib/php/monica/checker.inc.php:2353 +#, fuzzy, c-format +msgid "This number of rows per page is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Reihenfolge ist zu lang. (Die maximale Länge beträgt %" +"d)" + +#: lib/php/monica/checker.inc.php:2358 +#, fuzzy +msgid "Please fill in a positive integer number of rows per page." +msgstr "Bitte geben Sie die Reihenfolge ein." + +#: lib/php/monica/checker.inc.php:2362 lib/php/monica/checker.inc.php:2372 +#, fuzzy, c-format +msgid "" +"The number of rows per page is too small. Please fill in a larger number of " +"rows per page between %d and %d." +msgstr "" +"Die Eingabe für die Reihenfolge ist zu klein. Bitte geben Sie eine größere " +"Reihenfolge zwischen %d und %d ein." + +#: lib/php/monica/checker.inc.php:2376 +#, fuzzy, c-format +msgid "" +"The number of rows per page is too large. Please fill in a smaller number " +"of rows per page between %d and %d." +msgstr "" +"Die Eingabe für die Reihenfolge ist zu lang. Bitte geben Sie eine kleinere " +"Reihenfolge zwischen %d und %d ein." + +#: lib/php/monica/checker.inc.php:2443 +msgid "Please fill in your user ID." +msgstr "Bitte Benutzernamen eingeben." + +#: lib/php/monica/checker.inc.php:2451 lib/php/monica/checker.inc.php:2458 +#: lib/php/monica/checker.inc.php:2475 lib/php/monica/checker.inc.php:2508 +#: lib/php/monica/checker.inc.php:2540 lib/php/monica/checker.inc.php:2548 +#: lib/php/monica/checker.inc.php:2558 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "" +"Anmeldung fehlgeschlagen. Der Benutzername oder das Passwort stimmt nicht." + +#: lib/php/monica/checker.inc.php:2495 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "" +"Ihr Account wurde deaktiviert. Wenden Sie sich an Ihren Systemadministrator." + +#: lib/php/monica/checker.inc.php:2531 +msgid "Please fill in your password." +msgstr "Bitte Passwort eingeben." + +#: lib/php/monica/checker.inc.php:2581 +#, fuzzy +msgid "You are not an administrator so may not log in here." +msgstr "Sie sind kein Administrator und können sich hier nicht anmelden." + +#: lib/php/monica/checker.inc.php:2600 +#, fuzzy +msgid "You are an administrator so may not log in here." +msgstr "Sie sind kein Administrator und können sich hier nicht anmelden." + +#: lib/php/monica/checker.inc.php:2751 +#, fuzzy +msgid "Please fill in the code." +msgstr "Bitte geben Sie die Reihenfolge ein." + +#: lib/php/monica/checker.inc.php:2755 +#, c-format +msgid "You must fill in a %d-letters code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2760 +#, fuzzy +msgid "You can only use upper letters and for the code." +msgstr "" +"Die ID darf nur aus klein geschriebenen Buchstaben und Unterstrichen " +"bestehen." + +#: lib/php/monica/checker.inc.php:2772 +#, fuzzy +msgid "This code is duplicated. You cannot create a duplicated one." +msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#: lib/php/monica/checker.inc.php:2790 +#, fuzzy +msgid "Please fill in the country name." +msgstr "Bitte vollen Namen eintragen." + +#: lib/php/monica/checker.inc.php:2794 +#, fuzzy, c-format +msgid "This country name is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diesen vollen Namen ist zu lang (Die maximale Länge beträgt %" +"d)." + +#: lib/php/monica/checker.inc.php:2822 lib/php/monica/checker.inc.php:2841 +#, fuzzy +msgid "Please select a parent category." +msgstr "Bitte Anwender wählen" + +# admin/userpriv.php:266, admin/groups.php:724 +#: lib/php/monica/checker.inc.php:2828 +#, fuzzy +msgid "This option is invalid. Please select a proper parent category." +msgstr "Diese Gruppe existiert nicht mehr. Wählen Sie bitte eine andere." + +#: lib/php/monica/checker.inc.php:2845 +#, fuzzy +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:2850 +#, fuzzy +msgid "A category cannot belong to itself. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:2858 +#, fuzzy +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:2876 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:2894 +#, fuzzy +msgid "This category already exists. You cannot create a duplicated one." +msgstr "Diese Seite besteht bereits. Sie können kein Duplikat erstellen." + +#: lib/php/monica/checker.inc.php:2941 +#, fuzzy +msgid "Please fill in the URL.." +msgstr "Bitte URL eingeben." + +#: lib/php/monica/checker.inc.php:2945 +#, fuzzy, c-format +msgid "This URL. is too long. (Max. length %d)" +msgstr "Die Eingabe für diese URL ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:2950 +#, fuzzy +msgid "Please fill in a valid URL.." +msgstr "Bitte geben Sie ein gültiges Enddatum ein." + +#: lib/php/monica/checker.inc.php:2962 +#, fuzzy +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "" +"Dieser Programm-Link existiert bereits. Sie können kein Duplikat erstellen." + +#: lib/php/monica/checker.inc.php:2967 +msgid "This URL. is not reachable. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:2984 lib/php/monica/form.inc.php:3261 +#, fuzzy +msgid "Fill in the description here." +msgstr "Bitte Beschreibung eingeben." + +#: lib/php/monica/checker.inc.php:2988 +msgid "Please fill in the description." +msgstr "Bitte Beschreibung eingeben." + +#: lib/php/monica/checker.inc.php:2992 +#, c-format +msgid "This description is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für die Beschreibung ist zu lang (Die maximale Länge beträgt %d)." + +#: lib/php/monica/checker.inc.php:3012 +#, fuzzy +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#: lib/php/monica/checker.inc.php:3016 lib/php/monica/checker.inc.php:3072 +msgid "This category does not exist anymore. Please select another one." +msgstr "Dieser Kategorie existiert nicht mehr. Bitte wählen Sie eine andere." + +#: lib/php/monica/checker.inc.php:3022 lib/php/monica/checker.inc.php:3068 +#, fuzzy +msgid "Please select a category." +msgstr "Bitte Anwender wählen" + +#: lib/php/monica/checker.inc.php:3090 +#, fuzzy +msgid "Please select a related link." +msgstr "Bitte wählen Sie einen zulässigen Monat." + +#: lib/php/monica/checker.inc.php:3094 +#, fuzzy +msgid "This link does not exist anymore. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:3113 +#, fuzzy +msgid "" +"This link categorization already exists. You cannot create a duplicated one." +msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#: lib/php/monica/checker.inc.php:3154 +#, fuzzy +msgid "Please select the type." +msgstr "Bitte Anwender wählen." + +#: lib/php/monica/checker.inc.php:3158 +#, fuzzy +msgid "This type does not exist anymore. Please select another one." +msgstr "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#: lib/php/monica/checker.inc.php:3185 lib/php/monica/list.inc.php:961 +#, fuzzy +msgid "Please fill in your query." +msgstr "Bitte Benutzernamen eingeben." + +#: lib/php/monica/checker.inc.php:3210 +#, fuzzy +msgid "Please submit the picture." +msgstr "Bitte Kategorie wählen." + +#: lib/php/monica/checker.inc.php:3237 lib/php/monica/checker.inc.php:3328 +msgid "Please fill in the resize ratio." +msgstr "Bitte geben sie den Aspekt für die Größenänderung ein." + +#: lib/php/monica/checker.inc.php:3305 +msgid "Please specify a valid picture." +msgstr "Bitte wählen Sie ein gültiges Bild." + +#: lib/php/monica/chkfunc.inc.php:156 lib/php/monica/chkfunc.inc.php:160 +#: lib/php/monica/chkfunc.inc.php:163 lib/php/monica/chkfunc.inc.php:166 +msgid "Please select a legal year." +msgstr "Bitte wählen Sie ein zulässiges Jahr." + +#: lib/php/monica/chkfunc.inc.php:171 lib/php/monica/chkfunc.inc.php:175 +#: lib/php/monica/chkfunc.inc.php:178 +msgid "Please select a legal month." +msgstr "Bitte wählen Sie einen zulässigen Monat." + +#: lib/php/monica/chkfunc.inc.php:183 lib/php/monica/chkfunc.inc.php:187 +#: lib/php/monica/chkfunc.inc.php:193 +msgid "Please select a legal day." +msgstr "Bitte wählen Sie einen zulässigen Tag." + +#: lib/php/monica/chkwrite.inc.php:27 +#, c-format +msgid "%s: It is not a file." +msgstr "%s: Dies ist keine Datei." + +#: lib/php/monica/chkwrite.inc.php:32 +#, c-format +msgid "%s: You have no permission to overwrite this file." +msgstr "%s: Sie haben keine Erlaubnis, diese Datei zu überschreiben." + +#: lib/php/monica/chkwrite.inc.php:45 +#, c-format +msgid "%s: You cannot create anything under the root directory." +msgstr "%s: Sie können in dem Stammverzeichnis nichts erstellen." + +#: lib/php/monica/chkwrite.inc.php:50 +#, c-format +msgid "" +"%s: One of the parents of this file (%s) is not a directory. You cannot " +"create any new file inside." +msgstr "" +"%s: Einer der Vorgänger dieser Datei (%s) ist kein Verzeichnis. Sie können " +"keine neuen Dateien darin erstellen." + +#: lib/php/monica/chkwrite.inc.php:55 +#, c-format +msgid "%s: You have no permission to create any file under %s." +msgstr "%s: Sie haben keine Erlaubnis, Dateien unter %s zu erstellen." + +#: lib/php/monica/commtext.inc.php:18 +msgid "(not set)" +msgstr "(nicht eingestellt)" + +#: lib/php/monica/commtext.inc.php:24 +msgid "(none)" +msgstr "(keine)" + +#: lib/php/monica/commtext.inc.php:30 +msgid "(N/A)" +msgstr "(N/A)" + +#: lib/php/monica/commtext.inc.php:36 +msgid "(blank)" +msgstr "" + +#: lib/php/monica/echoform.inc.php:173 +#, c-format +msgid "%s bytes" +msgstr "" + +#: lib/php/monica/form.inc.php:168 +#, fuzzy +msgid "Delete it" +msgstr "Gelöscht" + +#: lib/php/monica/form.inc.php:174 +msgid "Are you sure you want to delete it? It cannot be recovered." +msgstr "" + +#: lib/php/monica/form.inc.php:188 +msgid "*" +msgstr "" + +#: lib/php/monica/form.inc.php:224 +msgid "This table provides you a form to add a new data record." +msgstr "" + +#: lib/php/monica/form.inc.php:228 +msgid "This table provides you a form to update a current data record." +msgstr "" + +#: lib/php/monica/form.inc.php:232 +msgid "This table provides you a form to delete a data record." +msgstr "" + +#: lib/php/monica/form.inc.php:281 +msgid "Add a New Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:285 +msgid "Update a Current Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:289 +msgid "Delete a Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:301 +msgid "Preview it." +msgstr "" + +#: lib/php/monica/form.inc.php:500 lib/php/monica/form.inc.php:506 +#: lib/php/monica/form.inc.php:691 lib/php/monica/form.inc.php:697 +#: lib/php/monica/preview.inc.php:146 +#, fuzzy +msgid "Preview" +msgstr "< Vorherige" + +#: lib/php/monica/form.inc.php:501 lib/php/monica/form.inc.php:507 +#: lib/php/monica/form.inc.php:692 lib/php/monica/form.inc.php:698 +#, fuzzy +msgid "Confirm and submit" +msgstr "Passwort bestätigen:" + +#: lib/php/monica/form.inc.php:708 lib/php/monica/form.inc.php:1692 +#: lib/php/monica/form.inc.php:1778 lib/php/monica/list.inc.php:1809 +msgid "Delete" +msgstr "Löschen" + +#: lib/php/monica/form.inc.php:709 lib/php/monica/form.inc.php:6419 +#: lib/php/monica/form.inc.php:6470 +msgid "Cancel" +msgstr "Abbruch" + +#: lib/php/monica/form.inc.php:1042 lib/php/monica/form.inc.php:3499 +msgid "Set the picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1043 lib/php/monica/form.inc.php:3031 +#: lib/php/monica/form.inc.php:3500 +msgid "Delete this picture" +msgstr "Bild löschen" + +#: lib/php/monica/form.inc.php:1048 lib/php/monica/form.inc.php:1178 +#: lib/php/monica/form.inc.php:3037 lib/php/monica/form.inc.php:3104 +#: lib/php/monica/form.inc.php:3505 lib/php/monica/form.inc.php:3677 +#: lib/php/monica/form.inc.php:6163 lib/php/monica/list.inc.php:814 +msgid "Picture preview" +msgstr "Vorschau neues Bild" + +#: lib/php/monica/form.inc.php:1059 lib/php/monica/form.inc.php:1109 +#: lib/php/monica/form.inc.php:1185 +#, fuzzy, c-format +msgid "Picture #%d:" +msgstr "Bild:" + +#: lib/php/monica/form.inc.php:1080 lib/php/monica/form.inc.php:1131 +#: lib/php/monica/form.inc.php:1166 lib/php/monica/form.inc.php:1199 +#, fuzzy +msgid "Caption:" +msgstr "Speicherplatz:" + +#: lib/php/monica/form.inc.php:1092 lib/php/monica/form.inc.php:3064 +#: lib/php/monica/form.inc.php:3566 lib/php/monica/form.inc.php:6183 +msgid "Original picture preview" +msgstr "Vorschau Originalbild" + +#: lib/php/monica/form.inc.php:1093 lib/php/monica/form.inc.php:3065 +#: lib/php/monica/form.inc.php:3567 lib/php/monica/form.inc.php:6197 +msgid "New picture preview" +msgstr "Vorschau neues Bild" + +#: lib/php/monica/form.inc.php:1113 lib/php/monica/form.inc.php:1276 +#: lib/php/monica/form.inc.php:1363 lib/php/monica/form.inc.php:1451 +#: lib/php/monica/form.inc.php:1560 lib/php/monica/form.inc.php:1650 +#: lib/php/monica/form.inc.php:1727 lib/php/monica/form.inc.php:1825 +#: lib/php/monica/form.inc.php:1916 lib/php/monica/form.inc.php:1977 +#: lib/php/monica/form.inc.php:2053 lib/php/monica/form.inc.php:2159 +#: lib/php/monica/form.inc.php:2391 lib/php/monica/form.inc.php:2592 +#: lib/php/monica/form.inc.php:2689 lib/php/monica/form.inc.php:2800 +#: lib/php/monica/form.inc.php:2897 lib/php/monica/form.inc.php:2980 +#: lib/php/monica/form.inc.php:3069 lib/php/monica/form.inc.php:3200 +#: lib/php/monica/form.inc.php:3571 lib/php/monica/form.inc.php:3627 +#: lib/php/monica/form.inc.php:3640 lib/php/monica/form.inc.php:3747 +#: lib/php/monica/form.inc.php:4423 lib/php/monica/form.inc.php:4533 +#: lib/php/monica/form.inc.php:4729 lib/php/monica/form.inc.php:4866 +#: lib/php/monica/form.inc.php:5000 lib/php/monica/form.inc.php:6176 +#: lib/php/monica/form.inc.php:6243 +msgid "Original:" +msgstr "Original:" + +#: lib/php/monica/form.inc.php:1141 lib/php/monica/form.inc.php:1281 +#: lib/php/monica/form.inc.php:1369 lib/php/monica/form.inc.php:1456 +#: lib/php/monica/form.inc.php:1575 lib/php/monica/form.inc.php:1655 +#: lib/php/monica/form.inc.php:1732 lib/php/monica/form.inc.php:1832 +#: lib/php/monica/form.inc.php:1921 lib/php/monica/form.inc.php:1982 +#: lib/php/monica/form.inc.php:2065 lib/php/monica/form.inc.php:2173 +#: lib/php/monica/form.inc.php:2422 lib/php/monica/form.inc.php:2597 +#: lib/php/monica/form.inc.php:2694 lib/php/monica/form.inc.php:2805 +#: lib/php/monica/form.inc.php:2902 lib/php/monica/form.inc.php:2985 +#: lib/php/monica/form.inc.php:3080 lib/php/monica/form.inc.php:3205 +#: lib/php/monica/form.inc.php:3584 lib/php/monica/form.inc.php:3632 +#: lib/php/monica/form.inc.php:3649 lib/php/monica/form.inc.php:3752 +#: lib/php/monica/form.inc.php:4442 lib/php/monica/form.inc.php:4543 +#: lib/php/monica/form.inc.php:4742 lib/php/monica/form.inc.php:4879 +#: lib/php/monica/form.inc.php:5013 lib/php/monica/form.inc.php:6188 +#: lib/php/monica/form.inc.php:6248 lib/php/monica/form.inc.php:6278 +msgid "New:" +msgstr "Neu:" + +#: lib/php/monica/form.inc.php:1269 lib/php/monica/form.inc.php:1444 +#: lib/php/monica/form.inc.php:1543 lib/php/monica/form.inc.php:2358 +#: lib/php/monica/form.inc.php:2585 lib/php/monica/form.inc.php:2793 +#: lib/php/monica/form.inc.php:2890 lib/php/monica/form.inc.php:2973 +#: lib/php/monica/form.inc.php:3620 +msgid "Source:" +msgstr "Quelle:" + +#: lib/php/monica/form.inc.php:1289 lib/php/monica/form.inc.php:1464 +#: lib/php/monica/form.inc.php:1583 lib/php/monica/form.inc.php:2605 +#: lib/php/monica/form.inc.php:2813 lib/php/monica/form.inc.php:2910 +#: lib/php/monica/form.inc.php:2993 +#, fuzzy, c-format +msgid "Please set it from %s." +msgstr "Bitte neue Seite aus %s erschaffen." + +#: lib/php/monica/form.inc.php:1501 +#, fuzzy +msgid "Hide" +msgstr "Verbergen?" + +#: lib/php/monica/form.inc.php:1502 +#, fuzzy +msgid "Show" +msgstr "Angezeigt" + +#: lib/php/monica/form.inc.php:1691 lib/php/monica/form.inc.php:1777 +#: lib/php/monica/form.inc.php:1887 +msgid "Choose" +msgstr "Auswählen" + +#: lib/php/monica/form.inc.php:2237 +msgid "Delete this file" +msgstr "" + +#: lib/php/monica/form.inc.php:2267 lib/php/monica/form.inc.php:2368 +#: lib/php/monica/form.inc.php:2400 lib/php/monica/form.inc.php:2445 +#: lib/php/monica/form.inc.php:2506 +#, fuzzy +msgid "File name:" +msgstr "Voller Name" + +#: lib/php/monica/form.inc.php:2274 lib/php/monica/form.inc.php:2375 +#: lib/php/monica/form.inc.php:2407 lib/php/monica/form.inc.php:2452 +#: lib/php/monica/form.inc.php:2513 +msgid "MIME file type:" +msgstr "" + +#: lib/php/monica/form.inc.php:2279 lib/php/monica/form.inc.php:2380 +#: lib/php/monica/form.inc.php:2412 lib/php/monica/form.inc.php:2457 +#: lib/php/monica/form.inc.php:2518 +#, fuzzy +msgid "File size:" +msgstr "Seitengröße:" + +#: lib/php/monica/form.inc.php:2430 +#, fuzzy, c-format +msgid "Please upload it from %s." +msgstr "Bitte neue Seite aus %s erschaffen." + +#: lib/php/monica/form.inc.php:3128 +msgid "Address:" +msgstr "" + +#: lib/php/monica/form.inc.php:3129 +#, fuzzy +msgid "Fill in your address here." +msgstr "Bitte Passwort eingeben." + +#: lib/php/monica/form.inc.php:3135 +msgid "Attachment:" +msgstr "" + +#: lib/php/monica/form.inc.php:3139 +#, fuzzy +msgid "Attachment description:" +msgstr "Beschreibung:" + +#: lib/php/monica/form.inc.php:3158 lib/php/monica/form.inc.php:3171 +msgid "Content:" +msgstr "Inhalt:" + +#: lib/php/monica/form.inc.php:3165 +msgid "City:" +msgstr "" + +#: lib/php/monica/form.inc.php:3187 lib/php/monica/form.inc.php:3199 +#: lib/php/monica/form.inc.php:3217 lib/php/monica/form.inc.php:3241 +msgid "Country:" +msgstr "" + +#: lib/php/monica/form.inc.php:3229 +msgid "Created:" +msgstr "Erschaffen:" + +#: lib/php/monica/form.inc.php:3235 +msgid "Created by:" +msgstr "Erschaffen von:" + +#: lib/php/monica/form.inc.php:3247 +msgid "Date:" +msgstr "Datum:" + +#: lib/php/monica/form.inc.php:3253 lib/php/monica/form.inc.php:4292 +#: lib/php/monica/form.inc.php:4295 lib/php/monica/list.inc.php:310 +msgid "Disabled?" +msgstr "Deaktiviert?" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 lib/php/monica/list.inc.php:2020 +msgid "Disabled" +msgstr "Deaktiviert" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 +msgid "Enabled" +msgstr "Aktiviert" + +#: lib/php/monica/form.inc.php:3254 +#, fuzzy +msgid "Disable it." +msgstr "Deaktiviert" + +#: lib/php/monica/form.inc.php:3260 lib/php/monica/form.inc.php:4657 +msgid "Description:" +msgstr "Beschreibung:" + +#: lib/php/monica/form.inc.php:3267 +msgid "E-mail:" +msgstr "" + +#: lib/php/monica/form.inc.php:3273 +msgid "Fax:" +msgstr "" + +#: lib/php/monica/form.inc.php:3279 +#, fuzzy +msgid "Group:" +msgstr "Gruppen-ID" + +#: lib/php/monica/form.inc.php:3285 lib/php/monica/form.inc.php:5541 +#: lib/php/monica/form.inc.php:5747 lib/php/monica/form.inc.php:5905 +#: lib/php/monica/form.inc.php:5998 +msgid "Hide?" +msgstr "Verbergen?" + +#: lib/php/monica/form.inc.php:3286 +#, fuzzy +msgid "Hide it" +msgstr "Verborgen" + +#: lib/php/monica/form.inc.php:3286 +#, fuzzy +msgid "Show it" +msgstr "Angezeigt" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it currently." +msgstr "" + +#: lib/php/monica/form.inc.php:3292 +msgid "Host:" +msgstr "" + +#: lib/php/monica/form.inc.php:3298 lib/php/monica/list.inc.php:314 +msgid "HTML?" +msgstr "HTML?" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2948 +#: lib/php/monica/list.inc.php:3062 +msgid "HTML" +msgstr "HTML" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2949 +#: lib/php/monica/list.inc.php:3063 +msgid "Plain text" +msgstr "Nur Text" + +#: lib/php/monica/form.inc.php:3299 +msgid "The submitted content is HTML." +msgstr "Der eingegebene Inhalt ist in HTML-Format." + +#: lib/php/monica/form.inc.php:3305 lib/php/monica/form.inc.php:5535 +#: lib/php/monica/form.inc.php:6074 +msgid "ID.:" +msgstr "ID.:" + +#: lib/php/monica/form.inc.php:3311 +msgid "Introduction:" +msgstr "Einführung:" + +#: lib/php/monica/form.inc.php:3312 +#, fuzzy +msgid "Fill in the introduction here." +msgstr "Bitte Beschreibung eingeben." + +#: lib/php/monica/form.inc.php:3318 +msgid "IP:" +msgstr "" + +#: lib/php/monica/form.inc.php:3324 +msgid "Keywords:" +msgstr "Stichwörter:" + +#: lib/php/monica/form.inc.php:3330 +#, fuzzy +msgid "Language:" +msgstr "Bev. Sprache" + +#: lib/php/monica/form.inc.php:3355 +msgid "Name:" +msgstr "" + +#: lib/php/monica/form.inc.php:3365 lib/php/monica/form.inc.php:5992 +msgid "Order:" +msgstr "Reihenfolge:" + +#: lib/php/monica/form.inc.php:3371 +msgid "Organization:" +msgstr "" + +#: lib/php/monica/form.inc.php:3377 +#, fuzzy +msgid "Parent category:" +msgstr "Kategorie:" + +#: lib/php/monica/form.inc.php:3378 +msgid "At the very top" +msgstr "" + +#: lib/php/monica/form.inc.php:3391 lib/php/monica/form.inc.php:3428 +#: lib/php/monica/form.inc.php:3468 lib/php/monica/form.inc.php:4330 +#: lib/php/monica/form.inc.php:6362 +msgid "Password:" +msgstr "Passwort:" + +#: lib/php/monica/form.inc.php:3407 lib/php/monica/form.inc.php:3444 +msgid "Confirm password:" +msgstr "Passwort bestätigen:" + +#: lib/php/monica/form.inc.php:3458 +msgid "(Leave them blank if you don't plan to change your password.)" +msgstr "" + +#: lib/php/monica/form.inc.php:3484 +#, fuzzy +msgid "Page path:" +msgstr "Seitengröße:" + +#: lib/php/monica/form.inc.php:3490 +msgid "PDF. file:" +msgstr "" + +#: lib/php/monica/form.inc.php:3508 lib/php/monica/form.inc.php:3570 +#: lib/php/monica/form.inc.php:3680 lib/php/monica/form.inc.php:6151 +#: lib/php/monica/form.inc.php:6175 +msgid "Picture:" +msgstr "Bild:" + +#: lib/php/monica/form.inc.php:3531 lib/php/monica/form.inc.php:3615 +#: lib/php/monica/form.inc.php:3619 lib/php/monica/form.inc.php:3693 +msgid "Pic. caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:3538 lib/php/monica/form.inc.php:3639 +#: lib/php/monica/form.inc.php:3699 +msgid "Pic. position:" +msgstr "" + +#: lib/php/monica/form.inc.php:3718 lib/php/monica/form.inc.php:3746 +#: lib/php/monica/form.inc.php:3780 +msgid "Pinyin:" +msgstr "" + +#: lib/php/monica/form.inc.php:3722 lib/php/monica/form.inc.php:3756 +#, fuzzy +msgid "Please fill in the Chinese first." +msgstr "Bitte geben sie den Aspekt für die Größenänderung ein." + +#: lib/php/monica/form.inc.php:3801 +#, fuzzy +msgid "Subcategory:" +msgid_plural "Subcategories:" +msgstr[0] "Kategorie:" +msgstr[1] "Kategorie:" + +#: lib/php/monica/form.inc.php:3823 +msgid "Script:" +msgstr "Script:" + +#: lib/php/monica/form.inc.php:3829 +msgid "S/N:" +msgstr "S/N:" + +#: lib/php/monica/form.inc.php:3835 +#, fuzzy +msgid "Street:" +msgstr "Auswählen" + +#: lib/php/monica/form.inc.php:3841 +msgid "Subject:" +msgstr "" + +#: lib/php/monica/form.inc.php:3847 +msgid "Telephone:" +msgstr "" + +#: lib/php/monica/form.inc.php:3853 +msgid "Tel. (cell.):" +msgstr "" + +#: lib/php/monica/form.inc.php:3859 +msgid "Tel. (home):" +msgstr "" + +#: lib/php/monica/form.inc.php:3865 +msgid "Tel. (office):" +msgstr "" + +#: lib/php/monica/form.inc.php:3871 +msgid "Title:" +msgstr "Titel:" + +#: lib/php/monica/form.inc.php:3891 +msgid "Value:" +msgstr "" + +#: lib/php/monica/form.inc.php:3897 +msgid "Visits:" +msgstr "Besuche:" + +#: lib/php/monica/form.inc.php:3903 +msgid "Visited:" +msgstr "Besucht:" + +#: lib/php/monica/form.inc.php:3909 +msgid "Updated:" +msgstr "Aktualisiert:" + +#: lib/php/monica/form.inc.php:3915 +msgid "Updated by:" +msgstr "Aktualisiert von:" + +#: lib/php/monica/form.inc.php:3921 +#, fuzzy +msgid "URL.:" +msgstr "URL:" + +#: lib/php/monica/form.inc.php:3927 +msgid "Zip code:" +msgstr "" + +#: lib/php/monica/form.inc.php:4151 +msgid "Delete this user account" +msgstr "Anwender-Account löschen" + +#: lib/php/monica/form.inc.php:4157 +msgid "This table provides you a form to add a new user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4161 +msgid "This table provides you a form to update a current user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4165 +msgid "This table provides you a form to delete a user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4192 +msgid "Add a New User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4196 +msgid "Update a Current User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4200 +msgid "Delete a User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4213 +msgid "This is a super-user. You can only change parts of her infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4220 +msgid "" +"This user has a datum. It cannot be deleted. To delete the user, its datum " +"must first be deleted." +msgid_plural "" +"This user has data. It cannot be deleted. To delete the user, all of its " +"data must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4282 +msgid "Administrator?" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Non-administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4296 +msgid "Disable this user account." +msgstr "Diesen Anwender-Account deaktivieren." + +#: lib/php/monica/form.inc.php:4305 lib/php/monica/form.inc.php:4307 +#: lib/php/monica/form.inc.php:6354 +msgid "User ID.:" +msgstr "Benutzername:" + +#: lib/php/monica/form.inc.php:4314 +msgid "Pref. language:" +msgstr "Bev. Sprache:" + +#: lib/php/monica/form.inc.php:4320 +msgid "Full name:" +msgstr "Voller Name:" + +#: lib/php/monica/form.inc.php:4348 lib/php/monica/form.inc.php:4400 +#: lib/php/monica/form.inc.php:4422 lib/php/monica/form.inc.php:4496 +#: lib/php/monica/form.inc.php:4944 lib/php/monica/form.inc.php:4983 +#: lib/php/monica/form.inc.php:4999 lib/php/monica/form.inc.php:5051 +msgid "Belonging to:" +msgstr "" + +#: lib/php/monica/form.inc.php:4532 lib/php/monica/form.inc.php:4554 +msgid "Fail logins:" +msgstr "" + +#: lib/php/monica/form.inc.php:4539 lib/php/monica/form.inc.php:4560 +msgid "(Locked)" +msgstr "" + +#: lib/php/monica/form.inc.php:4585 +msgid "Delete this group" +msgstr "Diese Gruppe löschen" + +#: lib/php/monica/form.inc.php:4591 +msgid "This table provides you a form to add a new group." +msgstr "" + +#: lib/php/monica/form.inc.php:4595 +msgid "This table provides you a form to update a current group." +msgstr "" + +#: lib/php/monica/form.inc.php:4599 +msgid "This table provides you a form to delete a group." +msgstr "" + +#: lib/php/monica/form.inc.php:4624 +msgid "Add a New Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4628 +msgid "Update a Current Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4632 +#, fuzzy +msgid "Delete a Group" +msgstr "Bitte wählen Sie eine Gruppe." + +#: lib/php/monica/form.inc.php:4639 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "" +"Dies ist eine Super-Benutzer-Gruppe. Sie können nur Teile der Informationen " +"ändern." + +#: lib/php/monica/form.inc.php:4648 lib/php/monica/form.inc.php:4650 +msgid "Group ID.:" +msgstr "Gruppen-ID:" + +#: lib/php/monica/form.inc.php:4663 +msgid "Add a user" +msgstr "Anwender hinzufügen" + +#: lib/php/monica/form.inc.php:4670 lib/php/monica/form.inc.php:4710 +#: lib/php/monica/form.inc.php:4728 lib/php/monica/form.inc.php:4781 +#, fuzzy +msgid "User member:" +msgid_plural "User members:" +msgstr[0] "Gruppen-ID" +msgstr[1] "Gruppen-ID" + +#: lib/php/monica/form.inc.php:4801 lib/php/monica/form.inc.php:4938 +#, fuzzy +msgid "Add a group" +msgstr "%s Gruppe." + +#: lib/php/monica/form.inc.php:4808 lib/php/monica/form.inc.php:4848 +#: lib/php/monica/form.inc.php:4865 lib/php/monica/form.inc.php:4918 +#, fuzzy +msgid "Group member:" +msgid_plural "Group members:" +msgstr[0] "Gruppen-ID" +msgstr[1] "Gruppen-ID" + +#: lib/php/monica/form.inc.php:5085 lib/php/monica/form.inc.php:5160 +#, fuzzy +msgid "Delete this membership record" +msgstr "%s Script-Berechtigung." + +#: lib/php/monica/form.inc.php:5091 lib/php/monica/form.inc.php:5166 +#, fuzzy +msgid "This table provides you a form to add a new membership record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5095 lib/php/monica/form.inc.php:5170 +#, fuzzy +msgid "This table provides you a form to change a current membership record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5099 lib/php/monica/form.inc.php:5174 +#, fuzzy +msgid "This table provides you a form to delete a membership record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5122 +msgid "Add a New User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5126 +msgid "Change a Current User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5130 +msgid "Delete a User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5140 lib/php/monica/form.inc.php:5215 +msgid "Member:" +msgstr "" + +#: lib/php/monica/form.inc.php:5197 +msgid "Add a New Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5201 +msgid "Change a Current Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5205 +msgid "Delete a Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5235 +msgid "Delete this user preference" +msgstr "Anwender-Einstellung löschen" + +#: lib/php/monica/form.inc.php:5241 +#, fuzzy +msgid "This table provides you a form to add a new user preference." +msgstr "" +"Klicken Sie hier um eine neue Anwender-Einstellung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5245 +msgid "This table provides you a form to modify a current user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5249 +msgid "This table provides you a form to delete a user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5272 +#, fuzzy +msgid "Add a New User Preference" +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/form.inc.php:5276 +msgid "Modify a Current User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5280 +#, fuzzy +msgid "Delete a User Preference" +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/form.inc.php:5290 lib/php/monica/form.inc.php:5476 +msgid "User:" +msgstr "Anwender:" + +#: lib/php/monica/form.inc.php:5291 lib/php/monica/list.inc.php:2588 +msgid "Everyone" +msgstr "Alle" + +#: lib/php/monica/form.inc.php:5297 +msgid "Domain:" +msgstr "" + +#: lib/php/monica/form.inc.php:5298 lib/php/monica/list.inc.php:2592 +#, fuzzy +msgid "Everywhere" +msgstr "Alle" + +#: lib/php/monica/form.inc.php:5318 +#, fuzzy +msgid "Delete this script privilege record" +msgstr "%s Script-Berechtigung." + +#: lib/php/monica/form.inc.php:5324 +#, fuzzy +msgid "This table provides you a form to add a new script privilege record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5328 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5332 +msgid "This table provides you a form to delete a script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5355 +msgid "Add a New Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5359 +msgid "Change a Current Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5363 +msgid "Delete a Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5373 +msgid "Privilege:" +msgstr "Berechtigung:" + +#: lib/php/monica/form.inc.php:5395 +#, fuzzy +msgid "Delete this user request" +msgstr "Anwender-Account löschen" + +#: lib/php/monica/form.inc.php:5401 +#, fuzzy +msgid "This table provides you a form to add a new user request." +msgstr "" +"Klicken Sie hier um eine neue Anwender-Einstellung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5405 +#, fuzzy +msgid "This table provides you a form to update a current user request." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5409 +#, fuzzy +msgid "This table provides you a form to delete a user request." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:5432 +#, fuzzy +msgid "Add a New User Request" +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/form.inc.php:5436 +#, fuzzy +msgid "Update a Current User Request" +msgstr "Anwender verwalten" + +#: lib/php/monica/form.inc.php:5440 +#, fuzzy +msgid "Delete a User Request" +msgstr "Bitte Anwender wählen" + +#: lib/php/monica/form.inc.php:5448 +msgid "Join" +msgstr "" + +#: lib/php/monica/form.inc.php:5452 +msgid "Change e-mail" +msgstr "" + +#: lib/php/monica/form.inc.php:5456 +#, fuzzy +msgid "Reset password" +msgstr "Bitte Passwort eingeben." + +#: lib/php/monica/form.inc.php:5464 +msgid "Expiration:" +msgstr "" + +#: lib/php/monica/form.inc.php:5470 lib/php/monica/form.inc.php:6432 +msgid "Type:" +msgstr "" + +#: lib/php/monica/form.inc.php:5477 +msgid "Anonymous" +msgstr "" + +#: lib/php/monica/form.inc.php:5483 +msgid "Arguments:" +msgstr "" + +#: lib/php/monica/form.inc.php:5501 +msgid "Delete this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5507 +msgid "This table provides you a form to add a new category." +msgstr "" + +#: lib/php/monica/form.inc.php:5511 +msgid "This table provides you a form to edit a current category." +msgstr "" + +#: lib/php/monica/form.inc.php:5515 +msgid "This table provides you a form to delete a category." +msgstr "" + +#: lib/php/monica/form.inc.php:5525 +msgid "" +"This category has a subcategory. It cannot be deleted. To delete the " +"category, its subcategory must first be deleted." +msgid_plural "" +"This category has subcategories. It cannot be deleted. To delete the " +"category, all of its subcategories must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Show this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5559 +msgid "Delete this categorization record" +msgstr "" + +#: lib/php/monica/form.inc.php:5565 +msgid "This table provides you a form to add a new categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5569 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5573 +msgid "This table provides you a form to delete a categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5618 +msgid "Add a New Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5622 +msgid "Edit a Current Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5626 +msgid "Delete a Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5636 +msgid "" +"This category has a link. It cannot be deleted. To delete the category, " +"its link must first be deleted." +msgid_plural "" +"This category has links. It cannot be deleted. To delete the category, all " +"of its links must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5655 lib/php/monica/form.inc.php:5819 +msgid "Link:" +msgid_plural "Links:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5692 +msgid "Delete this related link" +msgstr "" + +#: lib/php/monica/form.inc.php:5698 +msgid "This table provides you a form to add a new related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5702 +msgid "This table provides you a form to edit a current related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5706 +msgid "This table provides you a form to delete a related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5729 +msgid "Add a New Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5733 +msgid "Edit a Current Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5737 +msgid "Delete a Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 lib/php/monica/form.inc.php:5906 +msgid "Show this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this related link currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5755 lib/php/monica/form.inc.php:5812 +#, fuzzy +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "Kategorie:" +msgstr[1] "Kategorie:" + +#: lib/php/monica/form.inc.php:5794 +msgid "Add a New Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5798 +msgid "Change a Current Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5802 +msgid "Delete a Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5842 +msgid "Delete this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5848 +msgid "This table provides you a form to write a new page." +msgstr "" + +#: lib/php/monica/form.inc.php:5852 +msgid "This table provides you a form to edit a current page." +msgstr "" + +#: lib/php/monica/form.inc.php:5856 +msgid "This table provides you a form to delete a page." +msgstr "" + +#: lib/php/monica/form.inc.php:5881 +msgid "Write a New Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5885 +msgid "Edit a Current Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5889 +#, fuzzy +msgid "Delete a Page" +msgstr "Gelöscht" + +#: lib/php/monica/form.inc.php:5897 +msgid "Preview this page." +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5929 +msgid "Delete this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5935 +msgid "This table provides you a form to write a new news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5939 +msgid "This table provides you a form to edit a current news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5943 +msgid "This table provides you a form to delete a news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5968 +msgid "Write a New News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5972 +msgid "Edit a Current News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5976 +msgid "Delete a News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5984 +msgid "Preview this news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Show this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article currently." +msgstr "" + +#: lib/php/monica/form.inc.php:6019 +#, fuzzy +msgid "Delete this country record" +msgstr "%s Script-Berechtigung." + +#: lib/php/monica/form.inc.php:6025 +#, fuzzy +msgid "This table provides you a form to add a new country record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:6029 +#, fuzzy +msgid "This table provides you a form to edit a current country record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:6033 +#, fuzzy +msgid "This table provides you a form to delete a country record." +msgstr "" +"Klicken Sie hier um eine neue Script-Berechtigung " +"hinzuzufügen." + +#: lib/php/monica/form.inc.php:6056 +msgid "Add a New Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6060 +msgid "Edit a Current Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6064 +msgid "Delete a Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6080 lib/php/monica/list.inc.php:3391 +msgid "Special?" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A special record" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +#, fuzzy +msgid "A normal country" +msgstr "Anwender suchen:" + +#: lib/php/monica/form.inc.php:6081 +msgid "This is a special record." +msgstr "" + +#: lib/php/monica/form.inc.php:6110 +msgid "This table provides you a form to add a new picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6114 +msgid "This table provides you a form to modify a current picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6125 +#, fuzzy +msgid "Upload a New Picture" +msgstr "Bitte neue Seite aus %s erschaffen." + +#: lib/php/monica/form.inc.php:6129 +#, fuzzy +msgid "Modify a Current Picture" +msgstr "Bitte neue Seite aus %s erschaffen." + +#: lib/php/monica/form.inc.php:6230 lib/php/monica/form.inc.php:6242 +msgid "Ratio:" +msgstr "" + +#: lib/php/monica/form.inc.php:6267 lib/php/monica/form.inc.php:6277 +msgid "Upload:" +msgstr "" + +#: lib/php/monica/form.inc.php:6308 +msgid "This table provides you a form to log in." +msgstr "" + +#: lib/php/monica/form.inc.php:6314 +msgid "Identify Yourself" +msgstr "Geben Sie Ihre Benutzerkennung ein" + +#: lib/php/monica/form.inc.php:6323 lib/php/monica/init.inc.php:505 +msgid "" +"Log-in is temporarily closed for maintainance now. Please come again " +"later. Sorry for the inconvienence." +msgstr "" + +#: lib/php/monica/form.inc.php:6332 +msgid "Log in" +msgstr "" + +#: lib/php/monica/form.inc.php:6379 +msgid "Remember me." +msgstr "Einstellungen merken." + +#: lib/php/monica/form.inc.php:6406 +msgid "Rebuild the Pages" +msgstr "" + +#: lib/php/monica/form.inc.php:6415 +msgid "Confirm" +msgstr "" + +#: lib/php/monica/form.inc.php:6457 +msgid "Log Out" +msgstr "Abmelden" + +#: lib/php/monica/form.inc.php:6466 +msgid "Log out" +msgstr "Abmelden" + +#: lib/php/monica/form.inc.php:6480 +msgid "Are you sure you want to log out?" +msgstr "" + +#: lib/php/monica/init.inc.php:114 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" + +#: lib/php/monica/init.inc.php:503 lib/php/monica/init.inc.php:504 +msgid "Log-In Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:524 lib/php/monica/init.inc.php:525 +msgid "Development Site Closed" +msgstr "Entwicklungsseite geschlossen" + +#: lib/php/monica/init.inc.php:526 +msgid "Development site is closed. Please work on the live site." +msgstr "" +"Die Entwicklungsseite ist geschlossen. Arbeiten Sie bitte auf der Live-Seite." + +#: lib/php/monica/links.inc.php:271 +msgid "Related Links" +msgstr "" + +#: lib/php/monica/list.inc.php:130 +msgid "Malformed" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "OK" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "Unreachable" +msgstr "" + +#: lib/php/monica/list.inc.php:290 lib/php/monica/list.inc.php:1534 +#: lib/php/monica/list.inc.php:3642 +msgid "(query phrase)" +msgstr "" + +#: lib/php/monica/list.inc.php:300 +msgid "S/N" +msgstr "S/N" + +#: lib/php/monica/list.inc.php:301 +msgid "Created" +msgstr "Erschaffen" + +#: lib/php/monica/list.inc.php:302 +msgid "Created by" +msgstr "Erschaffen durch" + +#: lib/php/monica/list.inc.php:303 +msgid "Updated" +msgstr "Aktualisiert" + +#: lib/php/monica/list.inc.php:304 +msgid "Updated by" +msgstr "Aktualisiert durch" + +#: lib/php/monica/list.inc.php:306 +msgid "Content" +msgstr "Inhalt" + +#: lib/php/monica/list.inc.php:307 +msgid "Category" +msgstr "Kategorie" + +#: lib/php/monica/list.inc.php:308 +msgid "Coverage" +msgstr "" + +#: lib/php/monica/list.inc.php:309 +msgid "Date" +msgstr "Datum" + +#: lib/php/monica/list.inc.php:311 +msgid "Description" +msgstr "Beschreibung" + +#: lib/php/monica/list.inc.php:312 +msgid "E-mail" +msgstr "" + +#: lib/php/monica/list.inc.php:313 +msgid "Hidden?" +msgstr "Verborgen?" + +#: lib/php/monica/list.inc.php:315 +msgid "ID." +msgstr "ID." + +#: lib/php/monica/list.inc.php:316 +msgid "Keywords" +msgstr "Stichwörter" + +#: lib/php/monica/list.inc.php:317 +#, fuzzy +msgid "Name" +msgstr "Voller Name" + +#: lib/php/monica/list.inc.php:318 +msgid "Order" +msgstr "Reihenfolge" + +#: lib/php/monica/list.inc.php:319 +msgid "Page path" +msgstr "" + +#: lib/php/monica/list.inc.php:320 +msgid "Picture" +msgstr "" + +#: lib/php/monica/list.inc.php:321 +msgid "Pic. ratio" +msgstr "" + +#: lib/php/monica/list.inc.php:322 +#, fuzzy +msgid "Pic. caption" +msgstr "Speicherplatz" + +#: lib/php/monica/list.inc.php:323 +msgid "Pic. position" +msgstr "" + +#: lib/php/monica/list.inc.php:324 +#, fuzzy +msgid "Subject" +msgstr "Auswählen" + +#: lib/php/monica/list.inc.php:325 +msgid "Title" +msgstr "Titel" + +#: lib/php/monica/list.inc.php:326 +#, fuzzy +msgid "URL." +msgstr "URL" + +#: lib/php/monica/list.inc.php:327 +msgid "Status (slow)" +msgstr "" + +#: lib/php/monica/list.inc.php:336 +msgid "Select" +msgstr "Auswählen" + +#: lib/php/monica/list.inc.php:339 +msgid "Select a Data Record" +msgstr "" + +#: lib/php/monica/list.inc.php:343 +msgid "Edit" +msgstr "Bearbeiten" + +#: lib/php/monica/list.inc.php:345 +msgid "Manage Data" +msgstr "" + +#: lib/php/monica/list.inc.php:749 +msgid "Nothing found. Please try another query." +msgstr "Kein Ergebnis gefunden. Versuchen Sie eine andere Abfrage." + +#: lib/php/monica/list.inc.php:752 +msgid "The database is empty." +msgstr "Die Datenbank ist leer." + +#: lib/php/monica/list.inc.php:759 +#, c-format +msgid "Your query found %s record." +msgid_plural "Your query found %s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:766 +#, c-format +msgid "%s record." +msgid_plural "%s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:775 +#, c-format +msgid "Your query found %s record, listing %s to %s." +msgid_plural "Your query found %s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:784 +#, c-format +msgid "%s record, listing %s to %s." +msgid_plural "%s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:855 lib/php/monica/list.inc.php:860 +#: lib/php/monica/list.inc.php:869 +#, c-format +msgid "Page number (%s) invalid. Please specify a valid page number." +msgstr "" +"Die Seitennummer (%s) ist ungültig. Geben Sie bitte eine gültige " +"Seitennummer ein." + +#: lib/php/monica/list.inc.php:874 +#, fuzzy, c-format +msgid "" +"Page number (%d) out of range. Please specify a number between 1 and %d." +msgstr "" +"Die Seitennummer (%d) liegt außerhalb des erlaubten Rahmens. Bitte geben Sie " +"eine Seitenzahl zwischen 1 und %d ein." + +#: lib/php/monica/list.inc.php:1138 lib/php/monica/list.inc.php:1151 +#, c-format +msgid "You cannot sort by \"%s\"." +msgstr "" + +#: lib/php/monica/list.inc.php:1512 +msgid "Search" +msgstr "Suchen" + +#: lib/php/monica/list.inc.php:1610 +msgid "Index" +msgstr "" + +#: lib/php/monica/list.inc.php:1634 +#, fuzzy +msgid "First" +msgstr "<< Erste" + +#: lib/php/monica/list.inc.php:1647 +#, fuzzy +msgid "Previous" +msgstr "< Vorherige" + +#: lib/php/monica/list.inc.php:1696 +#, fuzzy +msgid "Next" +msgstr "Nächste >" + +#: lib/php/monica/list.inc.php:1714 +#, fuzzy +msgid "Last" +msgstr "Letzte >>" + +#: lib/php/monica/list.inc.php:1736 +#, fuzzy +msgid "Page:" +msgstr "Seitengröße:" + +#: lib/php/monica/list.inc.php:1776 lib/php/monica/list.inc.php:1900 +#, fuzzy +msgid "Delete the selected items." +msgstr "Bitte Anwender wählen." + +#: lib/php/monica/list.inc.php:1805 +msgid "No." +msgstr "Nr." + +#: lib/php/monica/list.inc.php:1813 lib/php/monica/list.inc.php:1873 +msgid "View" +msgstr "Anzeigen" + +#: lib/php/monica/list.inc.php:1925 +msgid "Set" +msgstr "Einstellen" + +#: lib/php/monica/list.inc.php:1941 +msgid "Rows per page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1946 +msgid "Display columns:" +msgstr "Spalten anzeigen:" + +#: lib/php/monica/list.inc.php:1976 +#, fuzzy +msgid "Select a User" +msgstr "Bitte Anwender wählen" + +#: lib/php/monica/list.inc.php:1977 +msgid "Manage Users" +msgstr "Anwender verwalten" + +#: lib/php/monica/list.inc.php:1982 +msgid "User ID." +msgstr "Benutzername" + +#: lib/php/monica/list.inc.php:1983 +#, fuzzy +msgid "Full name" +msgstr "Voller Name:" + +#: lib/php/monica/list.inc.php:1984 +msgid "Deleted?" +msgstr "Gelöscht?" + +#: lib/php/monica/list.inc.php:1985 +#, fuzzy +msgid "Pref. language" +msgstr "Bev. Sprache:" + +#: lib/php/monica/list.inc.php:1986 +msgid "Visits" +msgstr "Besuche" + +#: lib/php/monica/list.inc.php:1987 +msgid "Visited" +msgstr "Besucht" + +#: lib/php/monica/list.inc.php:1988 +msgid "IP" +msgstr "" + +#: lib/php/monica/list.inc.php:1989 +msgid "Host" +msgstr "" + +#: lib/php/monica/list.inc.php:1990 +#, fuzzy +msgid "From country" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:1991 +msgid "Fail logins" +msgstr "" + +#: lib/php/monica/list.inc.php:2024 +msgid "Deleted" +msgstr "Gelöscht" + +#: lib/php/monica/list.inc.php:2035 +msgid "Add a new user account." +msgstr "" + +#: lib/php/monica/list.inc.php:2045 +msgid "Search for a user:" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:2063 +#, c-format +msgid "Your query found %s user." +msgid_plural "Your query found %s users." +msgstr[0] "Ihr Anfrage ergab %s Anwender." +msgstr[1] "Ihr Anfrage ergab %s Anwender." + +#: lib/php/monica/list.inc.php:2070 +#, c-format +msgid "%s user." +msgid_plural "%s users." +msgstr[0] "%s Anwender." +msgstr[1] "%s Anwender." + +#: lib/php/monica/list.inc.php:2079 +#, c-format +msgid "Your query found %s user, listing %s to %s." +msgid_plural "Your query found %s users, listing %s to %s." +msgstr[0] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." +msgstr[1] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2088 +#, c-format +msgid "%s user, listing %s to %s." +msgid_plural "%s users, listing %s to %s." +msgstr[0] "%s Anwender, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2107 +#, fuzzy +msgid "Select a Group" +msgstr "Bitte wählen Sie eine Gruppe." + +#: lib/php/monica/list.inc.php:2108 +msgid "Manage Groups" +msgstr "Gruppen verwalten" + +#: lib/php/monica/list.inc.php:2113 +msgid "Group ID." +msgstr "Gruppen-ID" + +#: lib/php/monica/list.inc.php:2121 +msgid "Add a new group." +msgstr "" + +#: lib/php/monica/list.inc.php:2131 +msgid "Search for a group:" +msgstr "Gruppe suchen:" + +#: lib/php/monica/list.inc.php:2149 +#, c-format +msgid "Your query found %s group." +msgid_plural "Your query found %s groups." +msgstr[0] "Ihre Abfrage ergab %s Gruppe." +msgstr[1] "Ihre Abfrage ergab %s Gruppen." + +#: lib/php/monica/list.inc.php:2156 +#, c-format +msgid "%s group." +msgid_plural "%s groups." +msgstr[0] "%s Gruppe." +msgstr[1] "%s Gruppen." + +#: lib/php/monica/list.inc.php:2165 +#, c-format +msgid "Your query found %s group, listing %s to %s." +msgid_plural "Your query found %s groups, listing %s to %s." +msgstr[0] "Ihre Abfrage ergab %s Gruppe, angezeigt werden %s bis %s." +msgstr[1] "Ihre Abfrage ergab %s Gruppen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2174 +#, c-format +msgid "%s group, listing %s to %s." +msgid_plural "%s groups, listing %s to %s." +msgstr[0] "%s Gruppe, angezeigt werden %s bis %s." +msgstr[1] "%s Gruppen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2194 +msgid "Select a User Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2195 +msgid "Manage User Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2200 lib/php/monica/list.inc.php:2323 +msgid "Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2201 lib/php/monica/list.inc.php:2324 +msgid "Member" +msgstr "" + +#: lib/php/monica/list.inc.php:2244 lib/php/monica/list.inc.php:2375 +#, fuzzy +msgid "Add a new membership record." +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/list.inc.php:2254 lib/php/monica/list.inc.php:2385 +#, fuzzy +msgid "Search for a membership record:" +msgstr "Anwender-Einstellung suchen:" + +#: lib/php/monica/list.inc.php:2272 lib/php/monica/list.inc.php:2403 +#, fuzzy, c-format +msgid "Your query found %s membership record." +msgid_plural "Your query found %s membership records." +msgstr[0] "Ihre Anfrage ergab %s Anwender-Einstellung." +msgstr[1] "Ihre Anfrage ergab %s Anwender-Einstellungen." + +#: lib/php/monica/list.inc.php:2279 lib/php/monica/list.inc.php:2410 +#, fuzzy, c-format +msgid "%s membership record." +msgid_plural "%s membership records." +msgstr[0] "%s Anwender-Einstellung." +msgstr[1] "%s Anwender-Einstellungen." + +#: lib/php/monica/list.inc.php:2288 lib/php/monica/list.inc.php:2419 +#, fuzzy, c-format +msgid "Your query found %s membership record, listing %s to %s." +msgid_plural "Your query found %s membership records, listing %s to %s." +msgstr[0] "" +"Ihre Anfrage ergab %s Anwender-Einstellung, angezeigt werden %s bis %s." +msgstr[1] "" +"Ihre Anfrage ergab %s Anwender-Einstellungen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2297 lib/php/monica/list.inc.php:2428 +#, fuzzy, c-format +msgid "%s membership record, listing %s to %s." +msgid_plural "%s membership records, listing %s to %s." +msgstr[0] "%s Anwender-Einstellung, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender-Einstellungen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2317 +msgid "Select a Group Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2318 +msgid "Manage Group Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2448 +#, fuzzy +msgid "Select a Script Privilege Record" +msgstr "Script-Berechtigung suchen:" + +#: lib/php/monica/list.inc.php:2449 +#, fuzzy +msgid "Manage Script Privileges" +msgstr "%s Script-Berechtigung." + +#: lib/php/monica/list.inc.php:2454 +msgid "Script" +msgstr "Script" + +#: lib/php/monica/list.inc.php:2455 +msgid "Privilege" +msgstr "Berechtigung" + +#: lib/php/monica/list.inc.php:2493 +#, fuzzy +msgid "Add a new script privilege record." +msgstr "%s Script-Berechtigung." + +#: lib/php/monica/list.inc.php:2503 +#, fuzzy +msgid "Search for a script privilege record:" +msgstr "Script-Berechtigung suchen:" + +#: lib/php/monica/list.inc.php:2521 +#, fuzzy, c-format +msgid "Your query found %s script privilege record." +msgid_plural "Your query found %s script privilege records." +msgstr[0] "Ihre Anfrage ergab %s Script-Berechtigung." +msgstr[1] "Ihre Anfrage ergab %s Script-Berechtigungen." + +#: lib/php/monica/list.inc.php:2528 +#, fuzzy, c-format +msgid "%s script privilege record." +msgid_plural "%s script privilege records." +msgstr[0] "%s Script-Berechtigung." +msgstr[1] "%s Script-Berechtigungen." + +#: lib/php/monica/list.inc.php:2537 +#, fuzzy, c-format +msgid "Your query found %s script privilege record, listing %s to %s." +msgid_plural "Your query found %s script privilege records, listing %s to %s." +msgstr[0] "" +"Ihre Anfrage ergab %s Script-Berechtigung, angezeigt werden %s bis %s." +msgstr[1] "" +"Ihre Anfrage ergab %s Script-Berechtigungen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2546 +#, fuzzy, c-format +msgid "%s script privilege record, listing %s to %s." +msgid_plural "%s script privilege records, listing %s to %s." +msgstr[0] "%s Script-Berechtigung, angezeigt werden %s bis %s." +msgstr[1] "%s Script-Berechtigungen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2566 +#, fuzzy +msgid "Select a User Preference" +msgstr "Anwender-Einstellung suchen:" + +#: lib/php/monica/list.inc.php:2567 +#, fuzzy +msgid "Manage User Preferences" +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/list.inc.php:2574 lib/php/monica/list.inc.php:2689 +msgid "User" +msgstr "Anwender" + +#: lib/php/monica/list.inc.php:2575 +msgid "Domain" +msgstr "" + +#: lib/php/monica/list.inc.php:2576 +#, fuzzy +msgid "Value" +msgstr "Pref. Wert" + +#: lib/php/monica/list.inc.php:2610 +#, fuzzy +msgid "Add a new user preference." +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/list.inc.php:2620 +msgid "Search for a user preference:" +msgstr "Anwender-Einstellung suchen:" + +#: lib/php/monica/list.inc.php:2638 +#, c-format +msgid "Your query found %s user preference." +msgid_plural "Your query found %s user preferences." +msgstr[0] "Ihre Anfrage ergab %s Anwender-Einstellung." +msgstr[1] "Ihre Anfrage ergab %s Anwender-Einstellungen." + +#: lib/php/monica/list.inc.php:2645 +#, c-format +msgid "%s user preference." +msgid_plural "%s user preferences." +msgstr[0] "%s Anwender-Einstellung." +msgstr[1] "%s Anwender-Einstellungen." + +#: lib/php/monica/list.inc.php:2654 +#, c-format +msgid "Your query found %s user preference, listing %s to %s." +msgid_plural "Your query found %s user preferences, listing %s to %s." +msgstr[0] "" +"Ihre Anfrage ergab %s Anwender-Einstellung, angezeigt werden %s bis %s." +msgstr[1] "" +"Ihre Anfrage ergab %s Anwender-Einstellungen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2663 +#, c-format +msgid "%s user preference, listing %s to %s." +msgid_plural "%s user preferences, listing %s to %s." +msgstr[0] "%s Anwender-Einstellung, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender-Einstellungen, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2682 +#, fuzzy +msgid "Select a User Request" +msgstr "Bitte Anwender wählen" + +#: lib/php/monica/list.inc.php:2683 +#, fuzzy +msgid "Manage User Requests" +msgstr "Anwender verwalten" + +#: lib/php/monica/list.inc.php:2688 +msgid "Type" +msgstr "" + +#: lib/php/monica/list.inc.php:2690 +msgid "Arguments" +msgstr "" + +#: lib/php/monica/list.inc.php:2691 +msgid "Expiration" +msgstr "" + +#: lib/php/monica/list.inc.php:2699 +#, fuzzy +msgid "Add a new user request." +msgstr "%s Anwender-Einstellung." + +#: lib/php/monica/list.inc.php:2709 +#, fuzzy +msgid "Search for a user request:" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:2727 +#, fuzzy, c-format +msgid "Your query found %s user request." +msgid_plural "Your query found %s user requests." +msgstr[0] "Ihr Anfrage ergab %s Anwender." +msgstr[1] "Ihr Anfrage ergab %s Anwender." + +#: lib/php/monica/list.inc.php:2734 +#, fuzzy, c-format +msgid "%s user request." +msgid_plural "%s user requests." +msgstr[0] "%s Anwender-Einstellung." +msgstr[1] "%s Anwender-Einstellungen." + +#: lib/php/monica/list.inc.php:2743 +#, fuzzy, c-format +msgid "Your query found %s user request, listing %s to %s." +msgid_plural "Your query found %s user requests, listing %s to %s." +msgstr[0] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." +msgstr[1] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2752 +#, fuzzy, c-format +msgid "%s user request, listing %s to %s." +msgid_plural "%s user requests, listing %s to %s." +msgstr[0] "%s Anwender, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2778 +msgid "Add a new category." +msgstr "" + +#: lib/php/monica/list.inc.php:2788 +#, fuzzy +msgid "Search for a category:" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:2806 +#, fuzzy, c-format +msgid "Your query found %s category." +msgid_plural "Your query found %s categories." +msgstr[0] "Ihr Anfrage ergab %s Anwender." +msgstr[1] "Ihr Anfrage ergab %s Anwender." + +#: lib/php/monica/list.inc.php:2813 +#, fuzzy, c-format +msgid "%s category." +msgid_plural "%s categories." +msgstr[0] "%s Seite." +msgstr[1] "%s Seiten." + +#: lib/php/monica/list.inc.php:2822 +#, fuzzy, c-format +msgid "Your query found %s category, listing %s to %s." +msgid_plural "Your query found %s categories, listing %s to %s." +msgstr[0] "Ihre Anfrage ergab %s Seite, angezeigt werden %s bis %s." +msgstr[1] "Ihre Anfrage ergab %s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2831 +#, fuzzy, c-format +msgid "%s category, listing %s to %s." +msgid_plural "%s categories, listing %s to %s." +msgstr[0] "%s Seite, angezeigt werden %s bis %s." +msgstr[1] "%s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2849 +msgid "Add a new categorization record." +msgstr "" + +#: lib/php/monica/list.inc.php:2859 +#, fuzzy +msgid "Search for a categorization record:" +msgstr "Script-Berechtigung suchen:" + +#: lib/php/monica/list.inc.php:2877 +#, fuzzy, c-format +msgid "Your query found %s categorization record." +msgid_plural "Your query found %s categorization records." +msgstr[0] "Ihre Anfrage ergab %s Seite." +msgstr[1] "Ihre Anfrage ergab %s Seiten." + +#: lib/php/monica/list.inc.php:2884 +#, c-format +msgid "%s categorization record." +msgid_plural "%s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2893 +#, fuzzy, c-format +msgid "Your query found %s categorization record, listing %s to %s." +msgid_plural "Your query found %s categorization records, listing %s to %s." +msgstr[0] "Ihre Anfrage ergab %s Seite, angezeigt werden %s bis %s." +msgstr[1] "Ihre Anfrage ergab %s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2902 +#, fuzzy, c-format +msgid "%s categorization record, listing %s to %s." +msgid_plural "%s categorization records, listing %s to %s." +msgstr[0] "%s Seite, angezeigt werden %s bis %s." +msgstr[1] "%s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:2921 +#, fuzzy +msgid "Select a Page" +msgstr "Auswählen" + +#: lib/php/monica/list.inc.php:2922 +msgid "Manage Pages" +msgstr "Seiten verwalten" + +#: lib/php/monica/list.inc.php:2952 lib/php/monica/list.inc.php:3066 +#: lib/php/monica/list.inc.php:3173 lib/php/monica/list.inc.php:3237 +#: lib/php/monica/list.inc.php:3358 +msgid "Hidden" +msgstr "Verborgen" + +#: lib/php/monica/list.inc.php:2953 lib/php/monica/list.inc.php:3067 +#: lib/php/monica/list.inc.php:3174 lib/php/monica/list.inc.php:3238 +#: lib/php/monica/list.inc.php:3359 +msgid "Shown" +msgstr "Angezeigt" + +#: lib/php/monica/list.inc.php:2963 +msgid "Write a new page." +msgstr "" + +#: lib/php/monica/list.inc.php:2973 +msgid "Search for a page:" +msgstr "Seite suchen:" + +#: lib/php/monica/list.inc.php:2991 +#, c-format +msgid "Your query found %s page." +msgid_plural "Your query found %s pages." +msgstr[0] "Ihre Anfrage ergab %s Seite." +msgstr[1] "Ihre Anfrage ergab %s Seiten." + +#: lib/php/monica/list.inc.php:2998 +#, c-format +msgid "%s page." +msgid_plural "%s pages." +msgstr[0] "%s Seite." +msgstr[1] "%s Seiten." + +#: lib/php/monica/list.inc.php:3007 +#, c-format +msgid "Your query found %s page, listing %s to %s." +msgid_plural "Your query found %s pages, listing %s to %s." +msgstr[0] "Ihre Anfrage ergab %s Seite, angezeigt werden %s bis %s." +msgstr[1] "Ihre Anfrage ergab %s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3016 +#, c-format +msgid "%s page, listing %s to %s." +msgid_plural "%s pages, listing %s to %s." +msgstr[0] "%s Seite, angezeigt werden %s bis %s." +msgstr[1] "%s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3035 +msgid "Select a News Article" +msgstr "" + +#: lib/php/monica/list.inc.php:3036 +msgid "Manage News" +msgstr "" + +#: lib/php/monica/list.inc.php:3077 +msgid "Write a new news article." +msgstr "" + +#: lib/php/monica/list.inc.php:3087 +#, fuzzy +msgid "Search for a news article:" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:3105 +#, fuzzy, c-format +msgid "Your query found %s news article." +msgid_plural "Your query found %s news articles." +msgstr[0] "Ihr Anfrage ergab %s Anwender." +msgstr[1] "Ihr Anfrage ergab %s Anwender." + +#: lib/php/monica/list.inc.php:3112 +#, c-format +msgid "%s news article." +msgid_plural "%s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3121 +#, fuzzy, c-format +msgid "Your query found %s news article, listing %s to %s." +msgid_plural "Your query found %s news articles, listing %s to %s." +msgstr[0] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." +msgstr[1] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3130 +#, fuzzy, c-format +msgid "%s news article, listing %s to %s." +msgid_plural "%s news articles, listing %s to %s." +msgstr[0] "%s Anwender, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3149 +msgid "Select a Link Category" +msgstr "" + +#: lib/php/monica/list.inc.php:3150 +msgid "Manage Link Categories" +msgstr "" + +#: lib/php/monica/list.inc.php:3197 +#, fuzzy +msgid "Select a Link" +msgstr "Auswählen" + +#: lib/php/monica/list.inc.php:3198 +msgid "Manage Links" +msgstr "" + +#: lib/php/monica/list.inc.php:3248 +msgid "Add a new related link." +msgstr "" + +#: lib/php/monica/list.inc.php:3258 +#, fuzzy +msgid "Search for a related link:" +msgstr "Seite suchen:" + +#: lib/php/monica/list.inc.php:3276 +#, fuzzy, c-format +msgid "Your query found %s related link." +msgid_plural "Your query found %s related links." +msgstr[0] "Ihre Anfrage ergab %s Seite." +msgstr[1] "Ihre Anfrage ergab %s Seiten." + +#: lib/php/monica/list.inc.php:3283 +#, c-format +msgid "%s related link." +msgid_plural "%s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3292 +#, fuzzy, c-format +msgid "Your query found %s related link, listing %s to %s." +msgid_plural "Your query found %s related links, listing %s to %s." +msgstr[0] "Ihre Anfrage ergab %s Seite, angezeigt werden %s bis %s." +msgstr[1] "Ihre Anfrage ergab %s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3301 +#, fuzzy, c-format +msgid "%s related link, listing %s to %s." +msgid_plural "%s related links, listing %s to %s." +msgstr[0] "%s Seite, angezeigt werden %s bis %s." +msgstr[1] "%s Seiten, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3321 +msgid "Select a Link Categorization Record" +msgstr "" + +#: lib/php/monica/list.inc.php:3322 +msgid "Manage Link Categorization" +msgstr "" + +#: lib/php/monica/list.inc.php:3327 +msgid "Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3383 +msgid "Select a Country" +msgstr "" + +#: lib/php/monica/list.inc.php:3384 +msgid "Manage Country Data" +msgstr "" + +#: lib/php/monica/list.inc.php:3389 +msgid "Code" +msgstr "Code" + +#: lib/php/monica/list.inc.php:3390 +msgid "Country name" +msgstr "" + +#: lib/php/monica/list.inc.php:3399 +#, fuzzy +msgid "Add a new country record." +msgstr "%s Script-Berechtigung." + +#: lib/php/monica/list.inc.php:3409 +#, fuzzy +msgid "Search for a country:" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:3427 +#, fuzzy, c-format +msgid "Your query found %s country." +msgid_plural "Your query found %s countries." +msgstr[0] "Ihr Anfrage ergab %s Anwender." +msgstr[1] "Ihr Anfrage ergab %s Anwender." + +#: lib/php/monica/list.inc.php:3434 +#, fuzzy, c-format +msgid "%s country." +msgid_plural "%s countries." +msgstr[0] "%s Anwender." +msgstr[1] "%s Anwender." + +#: lib/php/monica/list.inc.php:3443 +#, fuzzy, c-format +msgid "Your query found %s country, listing %s to %s." +msgid_plural "Your query found %s countries, listing %s to %s." +msgstr[0] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." +msgstr[1] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3452 +#, fuzzy, c-format +msgid "%s country, listing %s to %s." +msgid_plural "%s countries, listing %s to %s." +msgstr[0] "%s Anwender, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3474 +msgid "Browse the Activity Log" +msgstr "" + +#: lib/php/monica/list.inc.php:3586 +#, fuzzy +msgid "Please fill in the number of rows to display." +msgstr "Bitte Benutzernamen eingeben." + +#: lib/php/monica/list.inc.php:3590 +#, fuzzy, c-format +msgid "This number of rows to display is too long. (Max. length %d)" +msgstr "" +"Die Eingabe für diese Reihenfolge ist zu lang. (Die maximale Länge beträgt %" +"d)" + +#: lib/php/monica/list.inc.php:3595 +#, fuzzy +msgid "Please fill in a positive integer number of rows to display." +msgstr "Bitte geben Sie die Reihenfolge ein." + +#: lib/php/monica/list.inc.php:3599 lib/php/monica/list.inc.php:3609 +#, fuzzy, c-format +msgid "" +"The number of rows to display is too small. Please fill in a larger number " +"of rows to display between %d and %d." +msgstr "" +"Die Eingabe für die Reihenfolge ist zu klein. Bitte geben Sie eine größere " +"Reihenfolge zwischen %d und %d ein." + +#: lib/php/monica/list.inc.php:3613 +#, fuzzy, c-format +msgid "" +"The number of rows to display is too large. Please fill in a smaller number " +"of rows to display between %d and %d." +msgstr "" +"Die Eingabe für die Reihenfolge ist zu lang. Bitte geben Sie eine kleinere " +"Reihenfolge zwischen %d und %d ein." + +#: lib/php/monica/list.inc.php:3638 +#, fuzzy +msgid "Search for log entries:" +msgstr "Anwender suchen:" + +#: lib/php/monica/list.inc.php:3641 +#, fuzzy +msgid "Display" +msgstr "Spalten anzeigen:" + +#: lib/php/monica/list.inc.php:3654 +#, fuzzy +msgid "Display rows:" +msgstr "Spalten anzeigen:" + +#: lib/php/monica/list.inc.php:3677 +#, fuzzy, c-format +msgid "Your query found %s log entry." +msgid_plural "Your query found %s log entries." +msgstr[0] "Ihr Anfrage ergab %s Anwender." +msgstr[1] "Ihr Anfrage ergab %s Anwender." + +#: lib/php/monica/list.inc.php:3684 +#, fuzzy, c-format +msgid "%s log entry." +msgid_plural "%s log entries." +msgstr[0] "%s Anwender." +msgstr[1] "%s Anwender." + +#: lib/php/monica/list.inc.php:3693 +#, fuzzy, c-format +msgid "Your query found %s log entry, listing %s to %s." +msgid_plural "Your query found %s log entries, listing %s to %s." +msgstr[0] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." +msgstr[1] "Ihr Anfrage ergab %s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/list.inc.php:3702 +#, fuzzy, c-format +msgid "%s log entry, listing %s to %s." +msgid_plural "%s log entries, listing %s to %s." +msgstr[0] "%s Anwender, angezeigt werden %s bis %s." +msgstr[1] "%s Anwender, angezeigt werden %s bis %s." + +#: lib/php/monica/lninfo.inc.php:28 +msgid "English" +msgstr "Englisch" + +#: lib/php/monica/lninfo.inc.php:39 +msgid "Traditional Chinese" +msgstr "Traditionelles Chinesisch" + +#: lib/php/monica/lninfo.inc.php:50 +msgid "Simplified Chinese" +msgstr "Vereinfachtes Chinesisch" + +#: lib/php/monica/lninfo.inc.php:61 +msgid "Chinese" +msgstr "Chinesische" + +#: lib/php/monica/lninfo.inc.php:72 +msgid "Japanese" +msgstr "Japanisch" + +#: lib/php/monica/lninfo.inc.php:83 +msgid "Korean" +msgstr "Koreanisch" + +#: lib/php/monica/lninfo.inc.php:94 +msgid "German" +msgstr "Deutsch" + +#: lib/php/monica/lninfo.inc.php:105 +msgid "Spanish" +msgstr "Spanische" + +#: lib/php/monica/lninfo.inc.php:366 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:738 +msgid "Web pages" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:739 +#, fuzzy +msgid "News" +msgstr "Neu:" + +#: lib/php/monica/pagefunc.inc.php:740 +msgid "Related links" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:741 +msgid "Home page" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:742 +msgid "Whole web site" +msgstr "" + +#: lib/php/monica/pic.inc.php:39 +msgid "Left-aligned" +msgstr "Linksbündig" + +#: lib/php/monica/pic.inc.php:40 +msgid "Right-aligned" +msgstr "Rechtsbündig" + +#: lib/php/monica/pic.inc.php:74 lib/php/monica/pic.inc.php:77 +#, fuzzy, c-format +msgid "This picture file is too large (Max %s)." +msgstr "" +"Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#: lib/php/monica/pic.inc.php:92 +msgid "Please upload only PNG, JPEG or GIF files." +msgstr "" + +#: lib/php/monica/pic.inc.php:153 +#, c-format +msgid "Width: %d, height: %d, ratio: %0.2f" +msgstr "Breite: %d, Höhe: %d, Aspekt: %0.2f" + +#: lib/php/monica/pic.inc.php:176 +msgid "Please specify a numeric ratio." +msgstr "Bitte geben Sie eine numerische Aspektrate ein." + +#: lib/php/monica/pic.inc.php:180 +msgid "Please specify a positive ratio." +msgstr "Bitte geben Sie eine positive Aspektrate ein." + +#: lib/php/monica/pic.inc.php:183 +#, c-format +msgid "Please specify a ratio less than or equal to %0.2f." +msgstr "Bitte geben Sie eine Aspektrate kleiner oder gleich %0.2f ein." + +#: lib/php/monica/pic.inc.php:189 +msgid "This image is too large to display." +msgstr "Das Bild ist zu gro?um angezeigt zu werden." + +#: lib/php/monica/preview.inc.php:47 +#, c-format +msgid "Unknown preview source: \"%s\"." +msgstr "" + +#: lib/php/monica/preview.inc.php:67 +#, c-format +msgid "Unknown preview form: %d." +msgstr "" + +#: lib/php/monica/preview.inc.php:143 +msgid "Preview Mark Area" +msgstr "" + +#: lib/php/monica/preview.inc.php:148 +msgid "Finish preview and return." +msgstr "" + +#: lib/php/monica/process.inc.php:237 +msgid "This record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:243 +msgid "This record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:247 +msgid "This record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:251 +msgid "This record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:406 +#, fuzzy +msgid "This category was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:412 +#, fuzzy +msgid "This category has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:416 +#, fuzzy +msgid "This category has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:420 +#, fuzzy +msgid "This category has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:433 +#, fuzzy +msgid "This categorization record was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:439 +#, fuzzy +msgid "This categorization record has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:443 +#, fuzzy +msgid "This categorization record has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:447 +#, fuzzy +msgid "This categorization record has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:782 +msgid "This user account was not modified." +msgstr "Dieser Anwender-Account wurde nicht verändert." + +#: lib/php/monica/process.inc.php:788 +msgid "This user account has been successfully added." +msgstr "Dieser Anwender-Account wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:792 +msgid "This user account has been successfully updated." +msgstr "Dieser Anwender-Account wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:796 +msgid "This user account has been successfully deleted." +msgstr "Dieser Anwender-Account wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1074 +msgid "This group was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1080 +msgid "This group has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1084 +msgid "This group has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1088 +msgid "This group has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1152 lib/php/monica/process.inc.php:1230 +#, fuzzy +msgid "This membership record was not modified." +msgstr "Diese Anwender-Einstellung wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1158 lib/php/monica/process.inc.php:1236 +#, fuzzy +msgid "This membership record has been successfully added." +msgstr "Diese Anwender-Einstellung wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1162 lib/php/monica/process.inc.php:1240 +#, fuzzy +msgid "This membership record has been successfully updated." +msgstr "Diese Anwender-Einstellung wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1166 lib/php/monica/process.inc.php:1244 +#, fuzzy +msgid "This membership record has been successfully deleted." +msgstr "Diese Anwender-Einstellung wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1308 +#, fuzzy +msgid "This script privilege record was not modified." +msgstr "Die Script-Berechtigung wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1314 +#, fuzzy +msgid "This script privilege record has been successfully added." +msgstr "Die Script-Berechtigung wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1318 +#, fuzzy +msgid "This script privilege record has been successfully updated." +msgstr "Die Script-Berechtigung wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1322 +#, fuzzy +msgid "This script privilege record has been successfully deleted." +msgstr "Die Script-Berechtigung wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1438 +msgid "This user preference was not modified." +msgstr "Diese Anwender-Einstellung wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1444 +msgid "This user preference has been successfully added." +msgstr "Diese Anwender-Einstellung wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1448 +msgid "This user preference has been successfully updated." +msgstr "Diese Anwender-Einstellung wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1452 +msgid "This user preference has been successfully deleted." +msgstr "Diese Anwender-Einstellung wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1560 +#, fuzzy +msgid "This user request was not modified." +msgstr "Dieser Anwender-Account wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1566 +#, fuzzy +msgid "This user request has been successfully added." +msgstr "Dieser Anwender-Account wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1570 +#, fuzzy +msgid "This user request has been successfully updated." +msgstr "Dieser Anwender-Account wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1574 +#, fuzzy +msgid "This user request has been successfully deleted." +msgstr "Dieser Anwender-Account wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1685 +#, fuzzy +msgid "This page was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1691 +#, fuzzy +msgid "This page has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1695 +#, fuzzy +msgid "This page has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1699 +#, fuzzy +msgid "This page has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1874 +#, fuzzy +msgid "This news article was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:1880 +#, fuzzy +msgid "This news article has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:1884 +#, fuzzy +msgid "This news article has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:1888 +#, fuzzy +msgid "This news article has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:1997 +#, fuzzy +msgid "This country was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:2003 +#, fuzzy +msgid "This country has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:2007 +#, fuzzy +msgid "This country has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:2011 +#, fuzzy +msgid "This country has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:2097 +#, fuzzy, c-format +msgid "" +"The specified web pages have been successfully rebuilt. (%0.3f seconds)" +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/process.inc.php:2158 +#, c-format +msgid "Welcome, %s!" +msgstr "Herzlich Willkommen, %s!" + +#: lib/php/monica/process.inc.php:2204 +msgid "You have successfully logged out." +msgstr "Sie haben sich erfolgreich abgemeldet." + +#: lib/php/monica/process.inc.php:2439 +#, fuzzy +msgid "This related link was not modified." +msgstr "Die Gruppe wurde nicht verändert." + +#: lib/php/monica/process.inc.php:2445 +#, fuzzy +msgid "This related link has been successfully added." +msgstr "Die Gruppe wurde erfolgreich hinzugefügt." + +#: lib/php/monica/process.inc.php:2449 +#, fuzzy +msgid "This related link has been successfully updated." +msgstr "Die Gruppe wurde erfolgreich aktualisiert." + +#: lib/php/monica/process.inc.php:2453 +#, fuzzy +msgid "This related link has been successfully deleted." +msgstr "Die Gruppe wurde erfolgreich gelöscht." + +#: lib/php/monica/request.inc.php:38 +#, fuzzy +msgid "Please specify the request." +msgstr "Bitte Anwender wählen." + +#: lib/php/monica/request.inc.php:46 lib/php/monica/request.inc.php:55 +#, c-format +msgid "Invalid request S/N: %s." +msgstr "" + +#: lib/php/monica/sitesize.inc.php:41 +#, c-format +msgid "Currently using files %s.\n" +msgstr "" + +#: lib/php/monica/sitesize.inc.php:46 +#, c-format +msgid "Currently using files %s, database %s, total %s.\n" +msgstr "" + +#: lib/php/monica/upload.inc.php:70 +#, c-format +msgid "MIME file type: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:71 +#, c-format +msgid "File name: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:72 +#, c-format +msgid "File size: %s bytes" +msgstr "" + +#: lib/php/monica/validate.inc.php:116 +msgid "HTML Validatior Logo Area" +msgstr "" + +#: lib/php/monica/validate.inc.php:117 +msgid "HTML validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:118 +#, c-format +msgid "Valid %s!" +msgstr "" + +#: lib/php/monica/validate.inc.php:119 +msgid "CSS validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:120 +msgid "Valid CSS!" +msgstr "" + +#: lib/php/monica/validate.inc.php:121 +msgid "Explanation of Level Triple-A Conformance" +msgstr "" + +#: lib/php/monica/validate.inc.php:122 +msgid "" +"Level Triple-A conformance icon, W3C-WAI Web Content Accessibility " +"Guidelines 1.0" +msgstr "" + +#, fuzzy +#~ msgid "This file does not exist anymore. Please upload another one." +#~ msgstr "" +#~ "Dieser Bereich existiert nicht mehr. Wählen Sie bitte einen anderen." + +#, fuzzy +#~ msgid "This file is too large. (Max. size %s)" +#~ msgstr "" +#~ "Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#~ msgid "%s..." +#~ msgstr "%s..." + +#~ msgid "..." +#~ msgstr "..." + +#, fuzzy +#~ msgid "Please select the section to rebuild." +#~ msgstr "Bitte Anwender wählen." + +#, fuzzy +#~ msgid "This section does not exist anymore. Please select another one." +#~ msgstr "" +#~ "Dieser Anwender existiert nicht mehr. Bitte wählen Sie einen anderen." + +#, fuzzy +#~ msgid "" +#~ "This group membership already exists. You cannot create a duplicated one." +#~ msgstr "Diese Gruppe besteht bereits. Sie können kein Dulplikat erstellen." + +#, fuzzy +#~ msgid "Search for a group membership record:" +#~ msgstr "Gruppe suchen:" + +#, fuzzy +#~ msgid "Your query found %s group membership record." +#~ msgid_plural "Your query found %s group membership records." +#~ msgstr[0] "Ihre Abfrage ergab %s Gruppe." +#~ msgstr[1] "Ihre Abfrage ergab %s Gruppen." + +#, fuzzy +#~ msgid "Your query found %s group membership record, listing %s to %s." +#~ msgid_plural "" +#~ "Your query found %s group membership records, listing %s to %s." +#~ msgstr[0] "Ihre Abfrage ergab %s Gruppe, angezeigt werden %s bis %s." +#~ msgstr[1] "Ihre Abfrage ergab %s Gruppen, angezeigt werden %s bis %s." + +#, fuzzy +#~ msgid "%s group membership record, listing %s to %s." +#~ msgid_plural "%s group membership records, listing %s to %s." +#~ msgstr[0] "%s Gruppe, angezeigt werden %s bis %s." +#~ msgstr[1] "%s Gruppen, angezeigt werden %s bis %s." + +#, fuzzy +#~ msgid "This group membership was not modified." +#~ msgstr "Diese Anwender-Einstellung wurde nicht verändert." + +#, fuzzy +#~ msgid "This group membership has been successfully added." +#~ msgstr "Diese Anwender-Einstellung wurde erfolgreich hinzugefügt." + +#, fuzzy +#~ msgid "This group membership has been successfully updated." +#~ msgstr "Diese Anwender-Einstellung wurde erfolgreich aktualisiert." + +#, fuzzy +#~ msgid "This group membership has been successfully deleted." +#~ msgstr "Diese Anwender-Einstellung wurde erfolgreich gelöscht." + +#~ msgid "Links:" +#~ msgstr "Links:" + +#, fuzzy +#~ msgid "This PDF. file is too large. (Max. size %s bytes)" +#~ msgstr "" +#~ "Die Eingabe für diesen Titel ist zu lang. (Die maximale Länge beträgt %d)" + +#~ msgid "Full Name" +#~ msgstr "Voller Name" + +#~ msgid "Pref. Language" +#~ msgstr "Bev. Sprache" + +#, fuzzy +#~ msgid "Country?" +#~ msgstr "%s Anwender." + +#, fuzzy +#~ msgid "Please fill in the page size." +#~ msgstr "Bitte geben Sie das Datum ein. " + +#, fuzzy +#~ msgid "This page size is too long. (Max. length %d)" +#~ msgstr "" +#~ "Die Eingabe für das Datum ist zu lang (Die maximale Länge beträgt %d)." + +#, fuzzy +#~ msgid "Please fill in a positive integer page size." +#~ msgstr "Geben Sie bitte die Berechtigungs-Beschreibung ein." + +#, fuzzy +#~ msgid "" +#~ "The page size is too small. Please fill in a larger page size between %d " +#~ "and %d." +#~ msgstr "" +#~ "Die Kursgebühr ist zu klein. Bitte geben Sie eine größere Kursgebühr " +#~ "zwischen %d und %d ein." + +#, fuzzy +#~ msgid "" +#~ "The page size is too large. Please fill in a smaller page size between %" +#~ "d and %d." +#~ msgstr "" +#~ "Die Kursgebühr ist zu gro? Bitte geben Sie eine kleinere Kursgebühr " +#~ "zwischen %d und %d ein." + +#~ msgid "Page size:" +#~ msgstr "Seitengröße:" + +#, fuzzy +#~ msgid "Submit and preview" +#~ msgstr "Vorschau neues Bild" + +#~ msgid "Submit" +#~ msgstr "Vorschau" + +#~ msgid "Save" +#~ msgstr "Speichern" + +#~ msgid "Click here to add a new user." +#~ msgstr "" +#~ "Klicken Sie hier um einen neuen Anwender hinzuzufügen." + +#~ msgid "Click here to add a new group." +#~ msgstr "" +#~ "Klicken Sie hier um eine neue Gruppe hinzuzufügen." + +#~ msgid "Pref. Name" +#~ msgstr "Pref. Name" + +#~ msgid "Click here to add a new page." +#~ msgstr "" +#~ "Klicken Sie hier um eine neue Seite hinzuzufügen." diff --git a/po/monica/es_ES.gmo b/po/monica/es_ES.gmo new file mode 100644 index 0000000..8a500f3 Binary files /dev/null and b/po/monica/es_ES.gmo differ diff --git a/po/monica/es_ES.po b/po/monica/es_ES.po new file mode 100644 index 0000000..05383d3 --- /dev/null +++ b/po/monica/es_ES.po @@ -0,0 +1,3297 @@ +# German PO file for the monica core +# Copyright (C) 2007-2018 Pristine Commnications +# This file is distributed under the same license as the monica package. +# imacat , 2007-2018. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: monica 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 12:42+0800\n" +"PO-Revision-Date: 2018-11-02 01:22+0800\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: lib/php/monica/checker.inc.php:159 +msgid "Please select a user." +msgstr "" + +#: lib/php/monica/checker.inc.php:163 +msgid "This user does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:181 +msgid "Please select a group." +msgstr "" + +#: lib/php/monica/checker.inc.php:185 +msgid "This group does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:203 +msgid "Please fill in the script." +msgstr "" + +#: lib/php/monica/checker.inc.php:207 +#, c-format +msgid "This script is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:212 +msgid "This script is not a valid script. Please specify another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:230 +msgid "Please fill in the date." +msgstr "" + +#: lib/php/monica/checker.inc.php:234 lib/php/monica/checker.inc.php:238 +#: lib/php/monica/checker.inc.php:241 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "" + +#: lib/php/monica/checker.inc.php:259 +msgid "Please fill in the ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:263 +#, c-format +msgid "This ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:267 +#, c-format +msgid "This ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:272 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:294 +msgid "Please fill in the order." +msgstr "" + +#: lib/php/monica/checker.inc.php:298 +#, c-format +msgid "This order is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:303 +msgid "Please fill in a positive integer order." +msgstr "" + +#: lib/php/monica/checker.inc.php:307 lib/php/monica/checker.inc.php:317 +#, c-format +msgid "" +"The order is too small. Please fill in a larger order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:321 +#, c-format +msgid "" +"The order is too large. Please fill in a smaller order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:348 +msgid "Please fill in the page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:352 +#, c-format +msgid "This page path is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:365 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:369 +msgid "Please fill in an absolute page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:373 +msgid "Please fill in a valid page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:377 +msgid "You cannot overwrite the cover home page." +msgstr "" + +#: lib/php/monica/checker.inc.php:381 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "" + +#: lib/php/monica/checker.inc.php:422 lib/php/monica/checker.inc.php:428 +msgid "Please fill in the attachment description." +msgstr "" + +#: lib/php/monica/checker.inc.php:432 +#, c-format +msgid "This attachment description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:449 +msgid "This PDF. file does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:456 +#, c-format +msgid "This PDF. file is too large. (Max. size %s)" +msgstr "" + +#: lib/php/monica/checker.inc.php:461 +msgid "Please upload only PDF. file." +msgstr "" + +#: lib/php/monica/checker.inc.php:479 +msgid "Please fill in the title." +msgstr "" + +#: lib/php/monica/checker.inc.php:483 +#, c-format +msgid "This title is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:502 +msgid "Please fill in the subject." +msgstr "" + +#: lib/php/monica/checker.inc.php:506 +#, c-format +msgid "This subject is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:524 lib/php/monica/form.inc.php:3159 +#: lib/php/monica/form.inc.php:3172 +msgid "Fill in the content here." +msgstr "" + +#: lib/php/monica/checker.inc.php:528 +msgid "Please fill in the content." +msgstr "" + +#: lib/php/monica/checker.inc.php:532 +#, c-format +msgid "This content is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:551 +msgid "Please fill in the keywords." +msgstr "" + +#: lib/php/monica/checker.inc.php:555 +#, c-format +msgid "This keyword list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:572 +msgid "Please select a proper pinyin." +msgstr "" + +#: lib/php/monica/checker.inc.php:578 +#, c-format +msgid "This pinyin is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:583 +msgid "" +"This pinyin does not match the Chinese. Please select a proper pinyin from " +"the list." +msgstr "" + +#: lib/php/monica/checker.inc.php:609 lib/php/monica/pic.inc.php:82 +msgid "Please upload the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:616 lib/php/monica/checker.inc.php:3214 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:622 +#, c-format +msgid "This picture is too large. Please upload another one. (Max. size %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:639 lib/php/monica/form.inc.php:3588 +#, c-format +msgid "Please upload a new picture from %s." +msgstr "" + +#: lib/php/monica/checker.inc.php:664 lib/php/monica/checker.inc.php:727 +msgid "Please fill in the picture caption." +msgstr "" + +#: lib/php/monica/checker.inc.php:668 lib/php/monica/checker.inc.php:731 +#, c-format +msgid "This picture caption is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:686 lib/php/monica/checker.inc.php:749 +msgid "Please select the picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:692 lib/php/monica/checker.inc.php:755 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:791 lib/php/monica/checker.inc.php:794 +#, c-format +msgid "Your uploaded file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/checker.inc.php:797 lib/php/monica/pic.inc.php:80 +msgid "" +"Upload not completed. Disk may be full or connection may be closed in the " +"half. You may try to upload again, or contact the system administrator for " +"this problem." +msgstr "" + +#: lib/php/monica/checker.inc.php:799 lib/php/monica/pic.inc.php:84 +#, c-format +msgid "Upload failed with an unknown error (%d)." +msgstr "" + +#: lib/php/monica/checker.inc.php:1183 lib/php/monica/chkfunc.inc.php:59 +#: lib/php/monica/chkfunc.inc.php:72 lib/php/monica/preview.inc.php:29 +#, c-format +msgid "The following field was not received: \"%s\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:1262 +msgid "Please fill in the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1266 +#, c-format +msgid "This user ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1270 +#, c-format +msgid "This user ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1275 +msgid "" +"Only lower-case English letters, numbers, at-signs, dots, dashes and " +"underscores are allowed for the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1287 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1317 +msgid "Please fill in the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1320 +msgid "Please confirm the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1324 +#, c-format +msgid "This password is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1329 +#, c-format +msgid "This password is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1334 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "" + +#: lib/php/monica/checker.inc.php:1345 +msgid "This password is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1360 +msgid "This password does not contain enough different characters." +msgstr "" + +#: lib/php/monica/checker.inc.php:1364 +msgid "This password is too simplistic/systematic." +msgstr "" + +#: lib/php/monica/checker.inc.php:1368 +msgid "This password is based on a dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1370 +msgid "This password is based on a (reversed) dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1372 +msgid "This password is too simple." +msgstr "" + +#: lib/php/monica/checker.inc.php:1378 +msgid "You cannot use a password that is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1397 +msgid "Please fill in the name." +msgstr "" + +#: lib/php/monica/checker.inc.php:1401 +#, c-format +msgid "This name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1420 +msgid "Please fill in the e-mail." +msgstr "" + +#: lib/php/monica/checker.inc.php:1424 +#, c-format +msgid "This e-mail is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1428 +#, c-format +msgid "This e-mail is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1437 +msgid "Please fill in a valid e-mail address." +msgstr "" + +#: lib/php/monica/checker.inc.php:1439 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:1461 lib/php/monica/checker.inc.php:1655 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1478 +msgid "You cannot submit the super-user group along with other groups." +msgstr "" + +#: lib/php/monica/checker.inc.php:1480 +msgid "You cannot set the administrators group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1482 +msgid "You cannot set the all-users group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1515 +msgid "Please fill in the group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1519 +#, c-format +msgid "This group ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1523 +#, c-format +msgid "This group ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1528 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1540 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1558 +msgid "Please fill in the privilege description." +msgstr "" + +#: lib/php/monica/checker.inc.php:1562 +#, c-format +msgid "This privilege description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1585 +msgid "This user member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1620 +msgid "This group member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1747 lib/php/monica/checker.inc.php:1855 +msgid "Please select a member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1751 lib/php/monica/checker.inc.php:1859 +msgid "This member does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1770 lib/php/monica/checker.inc.php:1883 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1837 +msgid "Please select a different belonging group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1864 +msgid "Please select a different group member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1958 +msgid "" +"This script privilege already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1996 lib/php/monica/checker.inc.php:2184 +msgid "Please select the user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2002 lib/php/monica/checker.inc.php:2190 +msgid "This option is invalid. Please select a proper user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2020 +msgid "Please set the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2026 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2039 lib/php/monica/checker.inc.php:2295 +msgid "Please fill in the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2043 lib/php/monica/checker.inc.php:2299 +#, c-format +msgid "This preference domain is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2063 +msgid "Please fill in the preference name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2067 +#, c-format +msgid "This preference name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2086 +msgid "Please fill in the preference value." +msgstr "" + +#: lib/php/monica/checker.inc.php:2090 +#, c-format +msgid "This preference value is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2119 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2167 +msgid "Please select the request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2173 +msgid "This option is invalid. Please select a proper request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2194 +msgid "You must choose anonymous for join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2197 +msgid "You cannot choose anonymous for non-join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2221 lib/php/monica/form.inc.php:5484 +msgid "Please fill in the request arguments list here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2229 +#, c-format +msgid "This request arguments list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2349 +msgid "Please fill in the number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2353 +#, c-format +msgid "This number of rows per page is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2358 +msgid "Please fill in a positive integer number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2362 lib/php/monica/checker.inc.php:2372 +#, c-format +msgid "" +"The number of rows per page is too small. Please fill in a larger number of " +"rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2376 +#, c-format +msgid "" +"The number of rows per page is too large. Please fill in a smaller number " +"of rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2443 +msgid "Please fill in your user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:2451 lib/php/monica/checker.inc.php:2458 +#: lib/php/monica/checker.inc.php:2475 lib/php/monica/checker.inc.php:2508 +#: lib/php/monica/checker.inc.php:2540 lib/php/monica/checker.inc.php:2548 +#: lib/php/monica/checker.inc.php:2558 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "" + +#: lib/php/monica/checker.inc.php:2495 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "" + +#: lib/php/monica/checker.inc.php:2531 +msgid "Please fill in your password." +msgstr "" + +#: lib/php/monica/checker.inc.php:2581 +msgid "You are not an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2600 +msgid "You are an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2751 +msgid "Please fill in the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2755 +#, c-format +msgid "You must fill in a %d-letters code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2760 +msgid "You can only use upper letters and for the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2772 +msgid "This code is duplicated. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2790 +msgid "Please fill in the country name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2794 +#, c-format +msgid "This country name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2822 lib/php/monica/checker.inc.php:2841 +msgid "Please select a parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2828 +msgid "This option is invalid. Please select a proper parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2845 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2850 +msgid "A category cannot belong to itself. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2858 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2876 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:2894 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2941 +msgid "Please fill in the URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2945 +#, c-format +msgid "This URL. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2950 +msgid "Please fill in a valid URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2962 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2967 +msgid "This URL. is not reachable. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:2984 lib/php/monica/form.inc.php:3261 +msgid "Fill in the description here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2988 +msgid "Please fill in the description." +msgstr "" + +#: lib/php/monica/checker.inc.php:2992 +#, c-format +msgid "This description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:3012 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:3016 lib/php/monica/checker.inc.php:3072 +msgid "This category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3022 lib/php/monica/checker.inc.php:3068 +msgid "Please select a category." +msgstr "" + +#: lib/php/monica/checker.inc.php:3090 +msgid "Please select a related link." +msgstr "" + +#: lib/php/monica/checker.inc.php:3094 +msgid "This link does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3113 +msgid "" +"This link categorization already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3154 +msgid "Please select the type." +msgstr "" + +#: lib/php/monica/checker.inc.php:3158 +msgid "This type does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3185 lib/php/monica/list.inc.php:961 +msgid "Please fill in your query." +msgstr "" + +#: lib/php/monica/checker.inc.php:3210 +msgid "Please submit the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:3237 lib/php/monica/checker.inc.php:3328 +msgid "Please fill in the resize ratio." +msgstr "" + +#: lib/php/monica/checker.inc.php:3305 +msgid "Please specify a valid picture." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:156 lib/php/monica/chkfunc.inc.php:160 +#: lib/php/monica/chkfunc.inc.php:163 lib/php/monica/chkfunc.inc.php:166 +msgid "Please select a legal year." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:171 lib/php/monica/chkfunc.inc.php:175 +#: lib/php/monica/chkfunc.inc.php:178 +msgid "Please select a legal month." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:183 lib/php/monica/chkfunc.inc.php:187 +#: lib/php/monica/chkfunc.inc.php:193 +msgid "Please select a legal day." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:27 +#, c-format +msgid "%s: It is not a file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:32 +#, c-format +msgid "%s: You have no permission to overwrite this file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:45 +#, c-format +msgid "%s: You cannot create anything under the root directory." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:50 +#, c-format +msgid "" +"%s: One of the parents of this file (%s) is not a directory. You cannot " +"create any new file inside." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:55 +#, c-format +msgid "%s: You have no permission to create any file under %s." +msgstr "" + +#: lib/php/monica/commtext.inc.php:18 +msgid "(not set)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:24 +msgid "(none)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:30 +msgid "(N/A)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:36 +msgid "(blank)" +msgstr "" + +#: lib/php/monica/echoform.inc.php:173 +#, c-format +msgid "%s bytes" +msgstr "" + +#: lib/php/monica/form.inc.php:168 +msgid "Delete it" +msgstr "" + +#: lib/php/monica/form.inc.php:174 +msgid "Are you sure you want to delete it? It cannot be recovered." +msgstr "" + +#: lib/php/monica/form.inc.php:188 +msgid "*" +msgstr "" + +#: lib/php/monica/form.inc.php:224 +msgid "This table provides you a form to add a new data record." +msgstr "" + +#: lib/php/monica/form.inc.php:228 +msgid "This table provides you a form to update a current data record." +msgstr "" + +#: lib/php/monica/form.inc.php:232 +msgid "This table provides you a form to delete a data record." +msgstr "" + +#: lib/php/monica/form.inc.php:281 +msgid "Add a New Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:285 +msgid "Update a Current Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:289 +msgid "Delete a Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:301 +msgid "Preview it." +msgstr "" + +#: lib/php/monica/form.inc.php:500 lib/php/monica/form.inc.php:506 +#: lib/php/monica/form.inc.php:691 lib/php/monica/form.inc.php:697 +#: lib/php/monica/preview.inc.php:146 +msgid "Preview" +msgstr "" + +#: lib/php/monica/form.inc.php:501 lib/php/monica/form.inc.php:507 +#: lib/php/monica/form.inc.php:692 lib/php/monica/form.inc.php:698 +msgid "Confirm and submit" +msgstr "" + +#: lib/php/monica/form.inc.php:708 lib/php/monica/form.inc.php:1692 +#: lib/php/monica/form.inc.php:1778 lib/php/monica/list.inc.php:1809 +msgid "Delete" +msgstr "" + +#: lib/php/monica/form.inc.php:709 lib/php/monica/form.inc.php:6419 +#: lib/php/monica/form.inc.php:6470 +msgid "Cancel" +msgstr "" + +#: lib/php/monica/form.inc.php:1042 lib/php/monica/form.inc.php:3499 +msgid "Set the picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1043 lib/php/monica/form.inc.php:3031 +#: lib/php/monica/form.inc.php:3500 +msgid "Delete this picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1048 lib/php/monica/form.inc.php:1178 +#: lib/php/monica/form.inc.php:3037 lib/php/monica/form.inc.php:3104 +#: lib/php/monica/form.inc.php:3505 lib/php/monica/form.inc.php:3677 +#: lib/php/monica/form.inc.php:6163 lib/php/monica/list.inc.php:814 +msgid "Picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1059 lib/php/monica/form.inc.php:1109 +#: lib/php/monica/form.inc.php:1185 +#, c-format +msgid "Picture #%d:" +msgstr "" + +#: lib/php/monica/form.inc.php:1080 lib/php/monica/form.inc.php:1131 +#: lib/php/monica/form.inc.php:1166 lib/php/monica/form.inc.php:1199 +msgid "Caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:1092 lib/php/monica/form.inc.php:3064 +#: lib/php/monica/form.inc.php:3566 lib/php/monica/form.inc.php:6183 +msgid "Original picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1093 lib/php/monica/form.inc.php:3065 +#: lib/php/monica/form.inc.php:3567 lib/php/monica/form.inc.php:6197 +msgid "New picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1113 lib/php/monica/form.inc.php:1276 +#: lib/php/monica/form.inc.php:1363 lib/php/monica/form.inc.php:1451 +#: lib/php/monica/form.inc.php:1560 lib/php/monica/form.inc.php:1650 +#: lib/php/monica/form.inc.php:1727 lib/php/monica/form.inc.php:1825 +#: lib/php/monica/form.inc.php:1916 lib/php/monica/form.inc.php:1977 +#: lib/php/monica/form.inc.php:2053 lib/php/monica/form.inc.php:2159 +#: lib/php/monica/form.inc.php:2391 lib/php/monica/form.inc.php:2592 +#: lib/php/monica/form.inc.php:2689 lib/php/monica/form.inc.php:2800 +#: lib/php/monica/form.inc.php:2897 lib/php/monica/form.inc.php:2980 +#: lib/php/monica/form.inc.php:3069 lib/php/monica/form.inc.php:3200 +#: lib/php/monica/form.inc.php:3571 lib/php/monica/form.inc.php:3627 +#: lib/php/monica/form.inc.php:3640 lib/php/monica/form.inc.php:3747 +#: lib/php/monica/form.inc.php:4423 lib/php/monica/form.inc.php:4533 +#: lib/php/monica/form.inc.php:4729 lib/php/monica/form.inc.php:4866 +#: lib/php/monica/form.inc.php:5000 lib/php/monica/form.inc.php:6176 +#: lib/php/monica/form.inc.php:6243 +msgid "Original:" +msgstr "" + +#: lib/php/monica/form.inc.php:1141 lib/php/monica/form.inc.php:1281 +#: lib/php/monica/form.inc.php:1369 lib/php/monica/form.inc.php:1456 +#: lib/php/monica/form.inc.php:1575 lib/php/monica/form.inc.php:1655 +#: lib/php/monica/form.inc.php:1732 lib/php/monica/form.inc.php:1832 +#: lib/php/monica/form.inc.php:1921 lib/php/monica/form.inc.php:1982 +#: lib/php/monica/form.inc.php:2065 lib/php/monica/form.inc.php:2173 +#: lib/php/monica/form.inc.php:2422 lib/php/monica/form.inc.php:2597 +#: lib/php/monica/form.inc.php:2694 lib/php/monica/form.inc.php:2805 +#: lib/php/monica/form.inc.php:2902 lib/php/monica/form.inc.php:2985 +#: lib/php/monica/form.inc.php:3080 lib/php/monica/form.inc.php:3205 +#: lib/php/monica/form.inc.php:3584 lib/php/monica/form.inc.php:3632 +#: lib/php/monica/form.inc.php:3649 lib/php/monica/form.inc.php:3752 +#: lib/php/monica/form.inc.php:4442 lib/php/monica/form.inc.php:4543 +#: lib/php/monica/form.inc.php:4742 lib/php/monica/form.inc.php:4879 +#: lib/php/monica/form.inc.php:5013 lib/php/monica/form.inc.php:6188 +#: lib/php/monica/form.inc.php:6248 lib/php/monica/form.inc.php:6278 +msgid "New:" +msgstr "" + +#: lib/php/monica/form.inc.php:1269 lib/php/monica/form.inc.php:1444 +#: lib/php/monica/form.inc.php:1543 lib/php/monica/form.inc.php:2358 +#: lib/php/monica/form.inc.php:2585 lib/php/monica/form.inc.php:2793 +#: lib/php/monica/form.inc.php:2890 lib/php/monica/form.inc.php:2973 +#: lib/php/monica/form.inc.php:3620 +msgid "Source:" +msgstr "" + +#: lib/php/monica/form.inc.php:1289 lib/php/monica/form.inc.php:1464 +#: lib/php/monica/form.inc.php:1583 lib/php/monica/form.inc.php:2605 +#: lib/php/monica/form.inc.php:2813 lib/php/monica/form.inc.php:2910 +#: lib/php/monica/form.inc.php:2993 +#, c-format +msgid "Please set it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:1501 +msgid "Hide" +msgstr "" + +#: lib/php/monica/form.inc.php:1502 +msgid "Show" +msgstr "" + +#: lib/php/monica/form.inc.php:1691 lib/php/monica/form.inc.php:1777 +#: lib/php/monica/form.inc.php:1887 +msgid "Choose" +msgstr "" + +#: lib/php/monica/form.inc.php:2237 +msgid "Delete this file" +msgstr "" + +#: lib/php/monica/form.inc.php:2267 lib/php/monica/form.inc.php:2368 +#: lib/php/monica/form.inc.php:2400 lib/php/monica/form.inc.php:2445 +#: lib/php/monica/form.inc.php:2506 +msgid "File name:" +msgstr "" + +#: lib/php/monica/form.inc.php:2274 lib/php/monica/form.inc.php:2375 +#: lib/php/monica/form.inc.php:2407 lib/php/monica/form.inc.php:2452 +#: lib/php/monica/form.inc.php:2513 +msgid "MIME file type:" +msgstr "" + +#: lib/php/monica/form.inc.php:2279 lib/php/monica/form.inc.php:2380 +#: lib/php/monica/form.inc.php:2412 lib/php/monica/form.inc.php:2457 +#: lib/php/monica/form.inc.php:2518 +msgid "File size:" +msgstr "" + +#: lib/php/monica/form.inc.php:2430 +#, c-format +msgid "Please upload it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:3128 +msgid "Address:" +msgstr "" + +#: lib/php/monica/form.inc.php:3129 +msgid "Fill in your address here." +msgstr "" + +#: lib/php/monica/form.inc.php:3135 +msgid "Attachment:" +msgstr "" + +#: lib/php/monica/form.inc.php:3139 +msgid "Attachment description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3158 lib/php/monica/form.inc.php:3171 +msgid "Content:" +msgstr "" + +#: lib/php/monica/form.inc.php:3165 +msgid "City:" +msgstr "" + +#: lib/php/monica/form.inc.php:3187 lib/php/monica/form.inc.php:3199 +#: lib/php/monica/form.inc.php:3217 lib/php/monica/form.inc.php:3241 +msgid "Country:" +msgstr "" + +#: lib/php/monica/form.inc.php:3229 +msgid "Created:" +msgstr "" + +#: lib/php/monica/form.inc.php:3235 +msgid "Created by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3247 +msgid "Date:" +msgstr "" + +#: lib/php/monica/form.inc.php:3253 lib/php/monica/form.inc.php:4292 +#: lib/php/monica/form.inc.php:4295 lib/php/monica/list.inc.php:310 +msgid "Disabled?" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 lib/php/monica/list.inc.php:2020 +msgid "Disabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 +msgid "Enabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 +msgid "Disable it." +msgstr "" + +#: lib/php/monica/form.inc.php:3260 lib/php/monica/form.inc.php:4657 +msgid "Description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3267 +msgid "E-mail:" +msgstr "" + +#: lib/php/monica/form.inc.php:3273 +msgid "Fax:" +msgstr "" + +#: lib/php/monica/form.inc.php:3279 +msgid "Group:" +msgstr "" + +#: lib/php/monica/form.inc.php:3285 lib/php/monica/form.inc.php:5541 +#: lib/php/monica/form.inc.php:5747 lib/php/monica/form.inc.php:5905 +#: lib/php/monica/form.inc.php:5998 +msgid "Hide?" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Show it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it currently." +msgstr "" + +#: lib/php/monica/form.inc.php:3292 +msgid "Host:" +msgstr "" + +#: lib/php/monica/form.inc.php:3298 lib/php/monica/list.inc.php:314 +msgid "HTML?" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2948 +#: lib/php/monica/list.inc.php:3062 +msgid "HTML" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2949 +#: lib/php/monica/list.inc.php:3063 +msgid "Plain text" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 +msgid "The submitted content is HTML." +msgstr "" + +#: lib/php/monica/form.inc.php:3305 lib/php/monica/form.inc.php:5535 +#: lib/php/monica/form.inc.php:6074 +msgid "ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3311 +msgid "Introduction:" +msgstr "" + +#: lib/php/monica/form.inc.php:3312 +msgid "Fill in the introduction here." +msgstr "" + +#: lib/php/monica/form.inc.php:3318 +msgid "IP:" +msgstr "" + +#: lib/php/monica/form.inc.php:3324 +msgid "Keywords:" +msgstr "" + +#: lib/php/monica/form.inc.php:3330 +msgid "Language:" +msgstr "" + +#: lib/php/monica/form.inc.php:3355 +msgid "Name:" +msgstr "" + +#: lib/php/monica/form.inc.php:3365 lib/php/monica/form.inc.php:5992 +msgid "Order:" +msgstr "" + +#: lib/php/monica/form.inc.php:3371 +msgid "Organization:" +msgstr "" + +#: lib/php/monica/form.inc.php:3377 +msgid "Parent category:" +msgstr "" + +#: lib/php/monica/form.inc.php:3378 +msgid "At the very top" +msgstr "" + +#: lib/php/monica/form.inc.php:3391 lib/php/monica/form.inc.php:3428 +#: lib/php/monica/form.inc.php:3468 lib/php/monica/form.inc.php:4330 +#: lib/php/monica/form.inc.php:6362 +msgid "Password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3407 lib/php/monica/form.inc.php:3444 +msgid "Confirm password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3458 +msgid "(Leave them blank if you don't plan to change your password.)" +msgstr "" + +#: lib/php/monica/form.inc.php:3484 +msgid "Page path:" +msgstr "" + +#: lib/php/monica/form.inc.php:3490 +msgid "PDF. file:" +msgstr "" + +#: lib/php/monica/form.inc.php:3508 lib/php/monica/form.inc.php:3570 +#: lib/php/monica/form.inc.php:3680 lib/php/monica/form.inc.php:6151 +#: lib/php/monica/form.inc.php:6175 +msgid "Picture:" +msgstr "" + +#: lib/php/monica/form.inc.php:3531 lib/php/monica/form.inc.php:3615 +#: lib/php/monica/form.inc.php:3619 lib/php/monica/form.inc.php:3693 +msgid "Pic. caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:3538 lib/php/monica/form.inc.php:3639 +#: lib/php/monica/form.inc.php:3699 +msgid "Pic. position:" +msgstr "" + +#: lib/php/monica/form.inc.php:3718 lib/php/monica/form.inc.php:3746 +#: lib/php/monica/form.inc.php:3780 +msgid "Pinyin:" +msgstr "" + +#: lib/php/monica/form.inc.php:3722 lib/php/monica/form.inc.php:3756 +msgid "Please fill in the Chinese first." +msgstr "" + +#: lib/php/monica/form.inc.php:3801 +msgid "Subcategory:" +msgid_plural "Subcategories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:3823 +msgid "Script:" +msgstr "" + +#: lib/php/monica/form.inc.php:3829 +msgid "S/N:" +msgstr "" + +#: lib/php/monica/form.inc.php:3835 +msgid "Street:" +msgstr "" + +#: lib/php/monica/form.inc.php:3841 +msgid "Subject:" +msgstr "" + +#: lib/php/monica/form.inc.php:3847 +msgid "Telephone:" +msgstr "" + +#: lib/php/monica/form.inc.php:3853 +msgid "Tel. (cell.):" +msgstr "" + +#: lib/php/monica/form.inc.php:3859 +msgid "Tel. (home):" +msgstr "" + +#: lib/php/monica/form.inc.php:3865 +msgid "Tel. (office):" +msgstr "" + +#: lib/php/monica/form.inc.php:3871 +msgid "Title:" +msgstr "" + +#: lib/php/monica/form.inc.php:3891 +msgid "Value:" +msgstr "" + +#: lib/php/monica/form.inc.php:3897 +msgid "Visits:" +msgstr "" + +#: lib/php/monica/form.inc.php:3903 +msgid "Visited:" +msgstr "" + +#: lib/php/monica/form.inc.php:3909 +msgid "Updated:" +msgstr "" + +#: lib/php/monica/form.inc.php:3915 +msgid "Updated by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3921 +msgid "URL.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3927 +msgid "Zip code:" +msgstr "" + +#: lib/php/monica/form.inc.php:4151 +msgid "Delete this user account" +msgstr "" + +#: lib/php/monica/form.inc.php:4157 +msgid "This table provides you a form to add a new user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4161 +msgid "This table provides you a form to update a current user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4165 +msgid "This table provides you a form to delete a user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4192 +msgid "Add a New User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4196 +msgid "Update a Current User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4200 +msgid "Delete a User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4213 +msgid "This is a super-user. You can only change parts of her infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4220 +msgid "" +"This user has a datum. It cannot be deleted. To delete the user, its datum " +"must first be deleted." +msgid_plural "" +"This user has data. It cannot be deleted. To delete the user, all of its " +"data must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4282 +msgid "Administrator?" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Non-administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4296 +msgid "Disable this user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4305 lib/php/monica/form.inc.php:4307 +#: lib/php/monica/form.inc.php:6354 +msgid "User ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4314 +msgid "Pref. language:" +msgstr "" + +#: lib/php/monica/form.inc.php:4320 +msgid "Full name:" +msgstr "" + +#: lib/php/monica/form.inc.php:4348 lib/php/monica/form.inc.php:4400 +#: lib/php/monica/form.inc.php:4422 lib/php/monica/form.inc.php:4496 +#: lib/php/monica/form.inc.php:4944 lib/php/monica/form.inc.php:4983 +#: lib/php/monica/form.inc.php:4999 lib/php/monica/form.inc.php:5051 +msgid "Belonging to:" +msgstr "" + +#: lib/php/monica/form.inc.php:4532 lib/php/monica/form.inc.php:4554 +msgid "Fail logins:" +msgstr "" + +#: lib/php/monica/form.inc.php:4539 lib/php/monica/form.inc.php:4560 +msgid "(Locked)" +msgstr "" + +#: lib/php/monica/form.inc.php:4585 +msgid "Delete this group" +msgstr "" + +#: lib/php/monica/form.inc.php:4591 +msgid "This table provides you a form to add a new group." +msgstr "" + +#: lib/php/monica/form.inc.php:4595 +msgid "This table provides you a form to update a current group." +msgstr "" + +#: lib/php/monica/form.inc.php:4599 +msgid "This table provides you a form to delete a group." +msgstr "" + +#: lib/php/monica/form.inc.php:4624 +msgid "Add a New Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4628 +msgid "Update a Current Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4632 +msgid "Delete a Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4639 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4648 lib/php/monica/form.inc.php:4650 +msgid "Group ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4663 +msgid "Add a user" +msgstr "" + +#: lib/php/monica/form.inc.php:4670 lib/php/monica/form.inc.php:4710 +#: lib/php/monica/form.inc.php:4728 lib/php/monica/form.inc.php:4781 +msgid "User member:" +msgid_plural "User members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4801 lib/php/monica/form.inc.php:4938 +msgid "Add a group" +msgstr "" + +#: lib/php/monica/form.inc.php:4808 lib/php/monica/form.inc.php:4848 +#: lib/php/monica/form.inc.php:4865 lib/php/monica/form.inc.php:4918 +msgid "Group member:" +msgid_plural "Group members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5085 lib/php/monica/form.inc.php:5160 +msgid "Delete this membership record" +msgstr "" + +#: lib/php/monica/form.inc.php:5091 lib/php/monica/form.inc.php:5166 +msgid "This table provides you a form to add a new membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5095 lib/php/monica/form.inc.php:5170 +msgid "This table provides you a form to change a current membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5099 lib/php/monica/form.inc.php:5174 +msgid "This table provides you a form to delete a membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5122 +msgid "Add a New User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5126 +msgid "Change a Current User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5130 +msgid "Delete a User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5140 lib/php/monica/form.inc.php:5215 +msgid "Member:" +msgstr "" + +#: lib/php/monica/form.inc.php:5197 +msgid "Add a New Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5201 +msgid "Change a Current Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5205 +msgid "Delete a Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5235 +msgid "Delete this user preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5241 +msgid "This table provides you a form to add a new user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5245 +msgid "This table provides you a form to modify a current user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5249 +msgid "This table provides you a form to delete a user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5272 +msgid "Add a New User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5276 +msgid "Modify a Current User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5280 +msgid "Delete a User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5290 lib/php/monica/form.inc.php:5476 +msgid "User:" +msgstr "" + +#: lib/php/monica/form.inc.php:5291 lib/php/monica/list.inc.php:2588 +msgid "Everyone" +msgstr "" + +#: lib/php/monica/form.inc.php:5297 +msgid "Domain:" +msgstr "" + +#: lib/php/monica/form.inc.php:5298 lib/php/monica/list.inc.php:2592 +msgid "Everywhere" +msgstr "" + +#: lib/php/monica/form.inc.php:5318 +msgid "Delete this script privilege record" +msgstr "" + +#: lib/php/monica/form.inc.php:5324 +msgid "This table provides you a form to add a new script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5328 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5332 +msgid "This table provides you a form to delete a script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5355 +msgid "Add a New Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5359 +msgid "Change a Current Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5363 +msgid "Delete a Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5373 +msgid "Privilege:" +msgstr "" + +#: lib/php/monica/form.inc.php:5395 +msgid "Delete this user request" +msgstr "" + +#: lib/php/monica/form.inc.php:5401 +msgid "This table provides you a form to add a new user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5405 +msgid "This table provides you a form to update a current user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5409 +msgid "This table provides you a form to delete a user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5432 +msgid "Add a New User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5436 +msgid "Update a Current User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5440 +msgid "Delete a User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5448 +msgid "Join" +msgstr "" + +#: lib/php/monica/form.inc.php:5452 +msgid "Change e-mail" +msgstr "" + +#: lib/php/monica/form.inc.php:5456 +msgid "Reset password" +msgstr "" + +#: lib/php/monica/form.inc.php:5464 +msgid "Expiration:" +msgstr "" + +#: lib/php/monica/form.inc.php:5470 lib/php/monica/form.inc.php:6432 +msgid "Type:" +msgstr "" + +#: lib/php/monica/form.inc.php:5477 +msgid "Anonymous" +msgstr "" + +#: lib/php/monica/form.inc.php:5483 +msgid "Arguments:" +msgstr "" + +#: lib/php/monica/form.inc.php:5501 +msgid "Delete this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5507 +msgid "This table provides you a form to add a new category." +msgstr "" + +#: lib/php/monica/form.inc.php:5511 +msgid "This table provides you a form to edit a current category." +msgstr "" + +#: lib/php/monica/form.inc.php:5515 +msgid "This table provides you a form to delete a category." +msgstr "" + +#: lib/php/monica/form.inc.php:5525 +msgid "" +"This category has a subcategory. It cannot be deleted. To delete the " +"category, its subcategory must first be deleted." +msgid_plural "" +"This category has subcategories. It cannot be deleted. To delete the " +"category, all of its subcategories must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Show this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5559 +msgid "Delete this categorization record" +msgstr "" + +#: lib/php/monica/form.inc.php:5565 +msgid "This table provides you a form to add a new categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5569 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5573 +msgid "This table provides you a form to delete a categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5618 +msgid "Add a New Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5622 +msgid "Edit a Current Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5626 +msgid "Delete a Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5636 +msgid "" +"This category has a link. It cannot be deleted. To delete the category, " +"its link must first be deleted." +msgid_plural "" +"This category has links. It cannot be deleted. To delete the category, all " +"of its links must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5655 lib/php/monica/form.inc.php:5819 +msgid "Link:" +msgid_plural "Links:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5692 +msgid "Delete this related link" +msgstr "" + +#: lib/php/monica/form.inc.php:5698 +msgid "This table provides you a form to add a new related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5702 +msgid "This table provides you a form to edit a current related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5706 +msgid "This table provides you a form to delete a related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5729 +msgid "Add a New Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5733 +msgid "Edit a Current Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5737 +msgid "Delete a Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 lib/php/monica/form.inc.php:5906 +msgid "Show this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this related link currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5755 lib/php/monica/form.inc.php:5812 +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5794 +msgid "Add a New Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5798 +msgid "Change a Current Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5802 +msgid "Delete a Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5842 +msgid "Delete this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5848 +msgid "This table provides you a form to write a new page." +msgstr "" + +#: lib/php/monica/form.inc.php:5852 +msgid "This table provides you a form to edit a current page." +msgstr "" + +#: lib/php/monica/form.inc.php:5856 +msgid "This table provides you a form to delete a page." +msgstr "" + +#: lib/php/monica/form.inc.php:5881 +msgid "Write a New Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5885 +msgid "Edit a Current Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5889 +msgid "Delete a Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5897 +msgid "Preview this page." +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5929 +msgid "Delete this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5935 +msgid "This table provides you a form to write a new news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5939 +msgid "This table provides you a form to edit a current news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5943 +msgid "This table provides you a form to delete a news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5968 +msgid "Write a New News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5972 +msgid "Edit a Current News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5976 +msgid "Delete a News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5984 +msgid "Preview this news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Show this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article currently." +msgstr "" + +#: lib/php/monica/form.inc.php:6019 +msgid "Delete this country record" +msgstr "" + +#: lib/php/monica/form.inc.php:6025 +msgid "This table provides you a form to add a new country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6029 +msgid "This table provides you a form to edit a current country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6033 +msgid "This table provides you a form to delete a country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6056 +msgid "Add a New Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6060 +msgid "Edit a Current Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6064 +msgid "Delete a Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6080 lib/php/monica/list.inc.php:3391 +msgid "Special?" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A special record" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A normal country" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "This is a special record." +msgstr "" + +#: lib/php/monica/form.inc.php:6110 +msgid "This table provides you a form to add a new picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6114 +msgid "This table provides you a form to modify a current picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6125 +msgid "Upload a New Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6129 +msgid "Modify a Current Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6230 lib/php/monica/form.inc.php:6242 +msgid "Ratio:" +msgstr "" + +#: lib/php/monica/form.inc.php:6267 lib/php/monica/form.inc.php:6277 +msgid "Upload:" +msgstr "" + +#: lib/php/monica/form.inc.php:6308 +msgid "This table provides you a form to log in." +msgstr "" + +#: lib/php/monica/form.inc.php:6314 +msgid "Identify Yourself" +msgstr "" + +#: lib/php/monica/form.inc.php:6323 lib/php/monica/init.inc.php:505 +msgid "" +"Log-in is temporarily closed for maintainance now. Please come again " +"later. Sorry for the inconvienence." +msgstr "" + +#: lib/php/monica/form.inc.php:6332 +msgid "Log in" +msgstr "" + +#: lib/php/monica/form.inc.php:6379 +msgid "Remember me." +msgstr "" + +#: lib/php/monica/form.inc.php:6406 +msgid "Rebuild the Pages" +msgstr "" + +#: lib/php/monica/form.inc.php:6415 +msgid "Confirm" +msgstr "" + +#: lib/php/monica/form.inc.php:6457 +msgid "Log Out" +msgstr "" + +#: lib/php/monica/form.inc.php:6466 +msgid "Log out" +msgstr "" + +#: lib/php/monica/form.inc.php:6480 +msgid "Are you sure you want to log out?" +msgstr "" + +#: lib/php/monica/init.inc.php:114 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" + +#: lib/php/monica/init.inc.php:503 lib/php/monica/init.inc.php:504 +msgid "Log-In Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:524 lib/php/monica/init.inc.php:525 +msgid "Development Site Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:526 +msgid "Development site is closed. Please work on the live site." +msgstr "" + +#: lib/php/monica/links.inc.php:271 +msgid "Related Links" +msgstr "" + +#: lib/php/monica/list.inc.php:130 +msgid "Malformed" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "OK" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "Unreachable" +msgstr "" + +#: lib/php/monica/list.inc.php:290 lib/php/monica/list.inc.php:1534 +#: lib/php/monica/list.inc.php:3642 +msgid "(query phrase)" +msgstr "" + +#: lib/php/monica/list.inc.php:300 +msgid "S/N" +msgstr "" + +#: lib/php/monica/list.inc.php:301 +msgid "Created" +msgstr "" + +#: lib/php/monica/list.inc.php:302 +msgid "Created by" +msgstr "" + +#: lib/php/monica/list.inc.php:303 +msgid "Updated" +msgstr "" + +#: lib/php/monica/list.inc.php:304 +msgid "Updated by" +msgstr "" + +#: lib/php/monica/list.inc.php:306 +msgid "Content" +msgstr "" + +#: lib/php/monica/list.inc.php:307 +msgid "Category" +msgstr "" + +#: lib/php/monica/list.inc.php:308 +msgid "Coverage" +msgstr "" + +#: lib/php/monica/list.inc.php:309 +msgid "Date" +msgstr "" + +#: lib/php/monica/list.inc.php:311 +msgid "Description" +msgstr "" + +#: lib/php/monica/list.inc.php:312 +msgid "E-mail" +msgstr "" + +#: lib/php/monica/list.inc.php:313 +msgid "Hidden?" +msgstr "" + +#: lib/php/monica/list.inc.php:315 +msgid "ID." +msgstr "" + +#: lib/php/monica/list.inc.php:316 +msgid "Keywords" +msgstr "" + +#: lib/php/monica/list.inc.php:317 +msgid "Name" +msgstr "" + +#: lib/php/monica/list.inc.php:318 +msgid "Order" +msgstr "" + +#: lib/php/monica/list.inc.php:319 +msgid "Page path" +msgstr "" + +#: lib/php/monica/list.inc.php:320 +msgid "Picture" +msgstr "" + +#: lib/php/monica/list.inc.php:321 +msgid "Pic. ratio" +msgstr "" + +#: lib/php/monica/list.inc.php:322 +msgid "Pic. caption" +msgstr "" + +#: lib/php/monica/list.inc.php:323 +msgid "Pic. position" +msgstr "" + +#: lib/php/monica/list.inc.php:324 +msgid "Subject" +msgstr "" + +#: lib/php/monica/list.inc.php:325 +msgid "Title" +msgstr "" + +#: lib/php/monica/list.inc.php:326 +msgid "URL." +msgstr "" + +#: lib/php/monica/list.inc.php:327 +msgid "Status (slow)" +msgstr "" + +#: lib/php/monica/list.inc.php:336 +msgid "Select" +msgstr "" + +#: lib/php/monica/list.inc.php:339 +msgid "Select a Data Record" +msgstr "" + +#: lib/php/monica/list.inc.php:343 +msgid "Edit" +msgstr "" + +#: lib/php/monica/list.inc.php:345 +msgid "Manage Data" +msgstr "" + +#: lib/php/monica/list.inc.php:749 +msgid "Nothing found. Please try another query." +msgstr "" + +#: lib/php/monica/list.inc.php:752 +msgid "The database is empty." +msgstr "" + +#: lib/php/monica/list.inc.php:759 +#, c-format +msgid "Your query found %s record." +msgid_plural "Your query found %s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:766 +#, c-format +msgid "%s record." +msgid_plural "%s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:775 +#, c-format +msgid "Your query found %s record, listing %s to %s." +msgid_plural "Your query found %s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:784 +#, c-format +msgid "%s record, listing %s to %s." +msgid_plural "%s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:855 lib/php/monica/list.inc.php:860 +#: lib/php/monica/list.inc.php:869 +#, c-format +msgid "Page number (%s) invalid. Please specify a valid page number." +msgstr "" + +#: lib/php/monica/list.inc.php:874 +#, c-format +msgid "" +"Page number (%d) out of range. Please specify a number between 1 and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:1138 lib/php/monica/list.inc.php:1151 +#, c-format +msgid "You cannot sort by \"%s\"." +msgstr "" + +#: lib/php/monica/list.inc.php:1512 +msgid "Search" +msgstr "" + +#: lib/php/monica/list.inc.php:1610 +msgid "Index" +msgstr "" + +#: lib/php/monica/list.inc.php:1634 +msgid "First" +msgstr "" + +#: lib/php/monica/list.inc.php:1647 +msgid "Previous" +msgstr "" + +#: lib/php/monica/list.inc.php:1696 +msgid "Next" +msgstr "" + +#: lib/php/monica/list.inc.php:1714 +msgid "Last" +msgstr "" + +#: lib/php/monica/list.inc.php:1736 +msgid "Page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1776 lib/php/monica/list.inc.php:1900 +msgid "Delete the selected items." +msgstr "" + +#: lib/php/monica/list.inc.php:1805 +msgid "No." +msgstr "" + +#: lib/php/monica/list.inc.php:1813 lib/php/monica/list.inc.php:1873 +msgid "View" +msgstr "" + +#: lib/php/monica/list.inc.php:1925 +msgid "Set" +msgstr "" + +#: lib/php/monica/list.inc.php:1941 +msgid "Rows per page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1946 +msgid "Display columns:" +msgstr "" + +#: lib/php/monica/list.inc.php:1976 +msgid "Select a User" +msgstr "" + +#: lib/php/monica/list.inc.php:1977 +msgid "Manage Users" +msgstr "" + +#: lib/php/monica/list.inc.php:1982 +msgid "User ID." +msgstr "" + +#: lib/php/monica/list.inc.php:1983 +msgid "Full name" +msgstr "" + +#: lib/php/monica/list.inc.php:1984 +msgid "Deleted?" +msgstr "" + +#: lib/php/monica/list.inc.php:1985 +msgid "Pref. language" +msgstr "" + +#: lib/php/monica/list.inc.php:1986 +msgid "Visits" +msgstr "" + +#: lib/php/monica/list.inc.php:1987 +msgid "Visited" +msgstr "" + +#: lib/php/monica/list.inc.php:1988 +msgid "IP" +msgstr "" + +#: lib/php/monica/list.inc.php:1989 +msgid "Host" +msgstr "" + +#: lib/php/monica/list.inc.php:1990 +msgid "From country" +msgstr "" + +#: lib/php/monica/list.inc.php:1991 +msgid "Fail logins" +msgstr "" + +#: lib/php/monica/list.inc.php:2024 +msgid "Deleted" +msgstr "" + +#: lib/php/monica/list.inc.php:2035 +msgid "Add a new user account." +msgstr "" + +#: lib/php/monica/list.inc.php:2045 +msgid "Search for a user:" +msgstr "" + +#: lib/php/monica/list.inc.php:2063 +#, c-format +msgid "Your query found %s user." +msgid_plural "Your query found %s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2070 +#, c-format +msgid "%s user." +msgid_plural "%s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2079 +#, c-format +msgid "Your query found %s user, listing %s to %s." +msgid_plural "Your query found %s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2088 +#, c-format +msgid "%s user, listing %s to %s." +msgid_plural "%s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2107 +msgid "Select a Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2108 +msgid "Manage Groups" +msgstr "" + +#: lib/php/monica/list.inc.php:2113 +msgid "Group ID." +msgstr "" + +#: lib/php/monica/list.inc.php:2121 +msgid "Add a new group." +msgstr "" + +#: lib/php/monica/list.inc.php:2131 +msgid "Search for a group:" +msgstr "" + +#: lib/php/monica/list.inc.php:2149 +#, c-format +msgid "Your query found %s group." +msgid_plural "Your query found %s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2156 +#, c-format +msgid "%s group." +msgid_plural "%s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2165 +#, c-format +msgid "Your query found %s group, listing %s to %s." +msgid_plural "Your query found %s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2174 +#, c-format +msgid "%s group, listing %s to %s." +msgid_plural "%s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2194 +msgid "Select a User Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2195 +msgid "Manage User Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2200 lib/php/monica/list.inc.php:2323 +msgid "Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2201 lib/php/monica/list.inc.php:2324 +msgid "Member" +msgstr "" + +#: lib/php/monica/list.inc.php:2244 lib/php/monica/list.inc.php:2375 +msgid "Add a new membership record." +msgstr "" + +#: lib/php/monica/list.inc.php:2254 lib/php/monica/list.inc.php:2385 +msgid "Search for a membership record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2272 lib/php/monica/list.inc.php:2403 +#, c-format +msgid "Your query found %s membership record." +msgid_plural "Your query found %s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2279 lib/php/monica/list.inc.php:2410 +#, c-format +msgid "%s membership record." +msgid_plural "%s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2288 lib/php/monica/list.inc.php:2419 +#, c-format +msgid "Your query found %s membership record, listing %s to %s." +msgid_plural "Your query found %s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2297 lib/php/monica/list.inc.php:2428 +#, c-format +msgid "%s membership record, listing %s to %s." +msgid_plural "%s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2317 +msgid "Select a Group Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2318 +msgid "Manage Group Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2448 +msgid "Select a Script Privilege Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2449 +msgid "Manage Script Privileges" +msgstr "" + +#: lib/php/monica/list.inc.php:2454 +msgid "Script" +msgstr "" + +#: lib/php/monica/list.inc.php:2455 +msgid "Privilege" +msgstr "" + +#: lib/php/monica/list.inc.php:2493 +msgid "Add a new script privilege record." +msgstr "" + +#: lib/php/monica/list.inc.php:2503 +msgid "Search for a script privilege record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2521 +#, c-format +msgid "Your query found %s script privilege record." +msgid_plural "Your query found %s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2528 +#, c-format +msgid "%s script privilege record." +msgid_plural "%s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2537 +#, c-format +msgid "Your query found %s script privilege record, listing %s to %s." +msgid_plural "Your query found %s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2546 +#, c-format +msgid "%s script privilege record, listing %s to %s." +msgid_plural "%s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2566 +msgid "Select a User Preference" +msgstr "" + +#: lib/php/monica/list.inc.php:2567 +msgid "Manage User Preferences" +msgstr "" + +#: lib/php/monica/list.inc.php:2574 lib/php/monica/list.inc.php:2689 +msgid "User" +msgstr "" + +#: lib/php/monica/list.inc.php:2575 +msgid "Domain" +msgstr "" + +#: lib/php/monica/list.inc.php:2576 +msgid "Value" +msgstr "" + +#: lib/php/monica/list.inc.php:2610 +msgid "Add a new user preference." +msgstr "" + +#: lib/php/monica/list.inc.php:2620 +msgid "Search for a user preference:" +msgstr "" + +#: lib/php/monica/list.inc.php:2638 +#, c-format +msgid "Your query found %s user preference." +msgid_plural "Your query found %s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2645 +#, c-format +msgid "%s user preference." +msgid_plural "%s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2654 +#, c-format +msgid "Your query found %s user preference, listing %s to %s." +msgid_plural "Your query found %s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2663 +#, c-format +msgid "%s user preference, listing %s to %s." +msgid_plural "%s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2682 +msgid "Select a User Request" +msgstr "" + +#: lib/php/monica/list.inc.php:2683 +msgid "Manage User Requests" +msgstr "" + +#: lib/php/monica/list.inc.php:2688 +msgid "Type" +msgstr "" + +#: lib/php/monica/list.inc.php:2690 +msgid "Arguments" +msgstr "" + +#: lib/php/monica/list.inc.php:2691 +msgid "Expiration" +msgstr "" + +#: lib/php/monica/list.inc.php:2699 +msgid "Add a new user request." +msgstr "" + +#: lib/php/monica/list.inc.php:2709 +msgid "Search for a user request:" +msgstr "" + +#: lib/php/monica/list.inc.php:2727 +#, c-format +msgid "Your query found %s user request." +msgid_plural "Your query found %s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2734 +#, c-format +msgid "%s user request." +msgid_plural "%s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2743 +#, c-format +msgid "Your query found %s user request, listing %s to %s." +msgid_plural "Your query found %s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2752 +#, c-format +msgid "%s user request, listing %s to %s." +msgid_plural "%s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2778 +msgid "Add a new category." +msgstr "" + +#: lib/php/monica/list.inc.php:2788 +msgid "Search for a category:" +msgstr "" + +#: lib/php/monica/list.inc.php:2806 +#, c-format +msgid "Your query found %s category." +msgid_plural "Your query found %s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2813 +#, c-format +msgid "%s category." +msgid_plural "%s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2822 +#, c-format +msgid "Your query found %s category, listing %s to %s." +msgid_plural "Your query found %s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2831 +#, c-format +msgid "%s category, listing %s to %s." +msgid_plural "%s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2849 +msgid "Add a new categorization record." +msgstr "" + +#: lib/php/monica/list.inc.php:2859 +msgid "Search for a categorization record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2877 +#, c-format +msgid "Your query found %s categorization record." +msgid_plural "Your query found %s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2884 +#, c-format +msgid "%s categorization record." +msgid_plural "%s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2893 +#, c-format +msgid "Your query found %s categorization record, listing %s to %s." +msgid_plural "Your query found %s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2902 +#, c-format +msgid "%s categorization record, listing %s to %s." +msgid_plural "%s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2921 +msgid "Select a Page" +msgstr "" + +#: lib/php/monica/list.inc.php:2922 +msgid "Manage Pages" +msgstr "" + +#: lib/php/monica/list.inc.php:2952 lib/php/monica/list.inc.php:3066 +#: lib/php/monica/list.inc.php:3173 lib/php/monica/list.inc.php:3237 +#: lib/php/monica/list.inc.php:3358 +msgid "Hidden" +msgstr "" + +#: lib/php/monica/list.inc.php:2953 lib/php/monica/list.inc.php:3067 +#: lib/php/monica/list.inc.php:3174 lib/php/monica/list.inc.php:3238 +#: lib/php/monica/list.inc.php:3359 +msgid "Shown" +msgstr "" + +#: lib/php/monica/list.inc.php:2963 +msgid "Write a new page." +msgstr "" + +#: lib/php/monica/list.inc.php:2973 +msgid "Search for a page:" +msgstr "" + +#: lib/php/monica/list.inc.php:2991 +#, c-format +msgid "Your query found %s page." +msgid_plural "Your query found %s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2998 +#, c-format +msgid "%s page." +msgid_plural "%s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3007 +#, c-format +msgid "Your query found %s page, listing %s to %s." +msgid_plural "Your query found %s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3016 +#, c-format +msgid "%s page, listing %s to %s." +msgid_plural "%s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3035 +msgid "Select a News Article" +msgstr "" + +#: lib/php/monica/list.inc.php:3036 +msgid "Manage News" +msgstr "" + +#: lib/php/monica/list.inc.php:3077 +msgid "Write a new news article." +msgstr "" + +#: lib/php/monica/list.inc.php:3087 +msgid "Search for a news article:" +msgstr "" + +#: lib/php/monica/list.inc.php:3105 +#, c-format +msgid "Your query found %s news article." +msgid_plural "Your query found %s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3112 +#, c-format +msgid "%s news article." +msgid_plural "%s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3121 +#, c-format +msgid "Your query found %s news article, listing %s to %s." +msgid_plural "Your query found %s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3130 +#, c-format +msgid "%s news article, listing %s to %s." +msgid_plural "%s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3149 +msgid "Select a Link Category" +msgstr "" + +#: lib/php/monica/list.inc.php:3150 +msgid "Manage Link Categories" +msgstr "" + +#: lib/php/monica/list.inc.php:3197 +msgid "Select a Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3198 +msgid "Manage Links" +msgstr "" + +#: lib/php/monica/list.inc.php:3248 +msgid "Add a new related link." +msgstr "" + +#: lib/php/monica/list.inc.php:3258 +msgid "Search for a related link:" +msgstr "" + +#: lib/php/monica/list.inc.php:3276 +#, c-format +msgid "Your query found %s related link." +msgid_plural "Your query found %s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3283 +#, c-format +msgid "%s related link." +msgid_plural "%s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3292 +#, c-format +msgid "Your query found %s related link, listing %s to %s." +msgid_plural "Your query found %s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3301 +#, c-format +msgid "%s related link, listing %s to %s." +msgid_plural "%s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3321 +msgid "Select a Link Categorization Record" +msgstr "" + +#: lib/php/monica/list.inc.php:3322 +msgid "Manage Link Categorization" +msgstr "" + +#: lib/php/monica/list.inc.php:3327 +msgid "Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3383 +msgid "Select a Country" +msgstr "" + +#: lib/php/monica/list.inc.php:3384 +msgid "Manage Country Data" +msgstr "" + +#: lib/php/monica/list.inc.php:3389 +msgid "Code" +msgstr "" + +#: lib/php/monica/list.inc.php:3390 +msgid "Country name" +msgstr "" + +#: lib/php/monica/list.inc.php:3399 +msgid "Add a new country record." +msgstr "" + +#: lib/php/monica/list.inc.php:3409 +msgid "Search for a country:" +msgstr "" + +#: lib/php/monica/list.inc.php:3427 +#, c-format +msgid "Your query found %s country." +msgid_plural "Your query found %s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3434 +#, c-format +msgid "%s country." +msgid_plural "%s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3443 +#, c-format +msgid "Your query found %s country, listing %s to %s." +msgid_plural "Your query found %s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3452 +#, c-format +msgid "%s country, listing %s to %s." +msgid_plural "%s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3474 +msgid "Browse the Activity Log" +msgstr "" + +#: lib/php/monica/list.inc.php:3586 +msgid "Please fill in the number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3590 +#, c-format +msgid "This number of rows to display is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/list.inc.php:3595 +msgid "Please fill in a positive integer number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3599 lib/php/monica/list.inc.php:3609 +#, c-format +msgid "" +"The number of rows to display is too small. Please fill in a larger number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3613 +#, c-format +msgid "" +"The number of rows to display is too large. Please fill in a smaller number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3638 +msgid "Search for log entries:" +msgstr "" + +#: lib/php/monica/list.inc.php:3641 +msgid "Display" +msgstr "" + +#: lib/php/monica/list.inc.php:3654 +msgid "Display rows:" +msgstr "" + +#: lib/php/monica/list.inc.php:3677 +#, c-format +msgid "Your query found %s log entry." +msgid_plural "Your query found %s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3684 +#, c-format +msgid "%s log entry." +msgid_plural "%s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3693 +#, c-format +msgid "Your query found %s log entry, listing %s to %s." +msgid_plural "Your query found %s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3702 +#, c-format +msgid "%s log entry, listing %s to %s." +msgid_plural "%s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/lninfo.inc.php:28 +msgid "English" +msgstr "Inglés" + +#: lib/php/monica/lninfo.inc.php:39 +msgid "Traditional Chinese" +msgstr "Chino tradicional" + +#: lib/php/monica/lninfo.inc.php:50 +msgid "Simplified Chinese" +msgstr "Chino simplificado" + +#: lib/php/monica/lninfo.inc.php:61 +msgid "Chinese" +msgstr "Chino" + +#: lib/php/monica/lninfo.inc.php:72 +msgid "Japanese" +msgstr "Japonés" + +#: lib/php/monica/lninfo.inc.php:83 +msgid "Korean" +msgstr "Coreano" + +#: lib/php/monica/lninfo.inc.php:94 +msgid "German" +msgstr "Alemán" + +#: lib/php/monica/lninfo.inc.php:105 +msgid "Spanish" +msgstr "Español" + +#: lib/php/monica/lninfo.inc.php:366 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:738 +msgid "Web pages" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:739 +msgid "News" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:740 +msgid "Related links" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:741 +msgid "Home page" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:742 +msgid "Whole web site" +msgstr "" + +#: lib/php/monica/pic.inc.php:39 +msgid "Left-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:40 +msgid "Right-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:74 lib/php/monica/pic.inc.php:77 +#, c-format +msgid "This picture file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/pic.inc.php:92 +msgid "Please upload only PNG, JPEG or GIF files." +msgstr "" + +#: lib/php/monica/pic.inc.php:153 +#, c-format +msgid "Width: %d, height: %d, ratio: %0.2f" +msgstr "" + +#: lib/php/monica/pic.inc.php:176 +msgid "Please specify a numeric ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:180 +msgid "Please specify a positive ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:183 +#, c-format +msgid "Please specify a ratio less than or equal to %0.2f." +msgstr "" + +#: lib/php/monica/pic.inc.php:189 +msgid "This image is too large to display." +msgstr "" + +#: lib/php/monica/preview.inc.php:47 +#, c-format +msgid "Unknown preview source: \"%s\"." +msgstr "" + +#: lib/php/monica/preview.inc.php:67 +#, c-format +msgid "Unknown preview form: %d." +msgstr "" + +#: lib/php/monica/preview.inc.php:143 +msgid "Preview Mark Area" +msgstr "" + +#: lib/php/monica/preview.inc.php:148 +msgid "Finish preview and return." +msgstr "" + +#: lib/php/monica/process.inc.php:237 +msgid "This record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:243 +msgid "This record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:247 +msgid "This record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:251 +msgid "This record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:406 +msgid "This category was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:412 +msgid "This category has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:416 +msgid "This category has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:420 +msgid "This category has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:433 +msgid "This categorization record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:439 +msgid "This categorization record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:443 +msgid "This categorization record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:447 +msgid "This categorization record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:782 +msgid "This user account was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:788 +msgid "This user account has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:792 +msgid "This user account has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:796 +msgid "This user account has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1074 +msgid "This group was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1080 +msgid "This group has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1084 +msgid "This group has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1088 +msgid "This group has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1152 lib/php/monica/process.inc.php:1230 +msgid "This membership record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1158 lib/php/monica/process.inc.php:1236 +msgid "This membership record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1162 lib/php/monica/process.inc.php:1240 +msgid "This membership record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1166 lib/php/monica/process.inc.php:1244 +msgid "This membership record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1308 +msgid "This script privilege record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1314 +msgid "This script privilege record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1318 +msgid "This script privilege record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1322 +msgid "This script privilege record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1438 +msgid "This user preference was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1444 +msgid "This user preference has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1448 +msgid "This user preference has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1452 +msgid "This user preference has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1560 +msgid "This user request was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1566 +msgid "This user request has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1570 +msgid "This user request has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1574 +msgid "This user request has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1685 +msgid "This page was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1691 +msgid "This page has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1695 +msgid "This page has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1699 +msgid "This page has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1874 +msgid "This news article was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1880 +msgid "This news article has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1884 +msgid "This news article has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1888 +msgid "This news article has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1997 +msgid "This country was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2003 +msgid "This country has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2007 +msgid "This country has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2011 +msgid "This country has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:2097 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. (%0.3f seconds)" +msgstr "" + +#: lib/php/monica/process.inc.php:2158 +#, c-format +msgid "Welcome, %s!" +msgstr "" + +#: lib/php/monica/process.inc.php:2204 +msgid "You have successfully logged out." +msgstr "" + +#: lib/php/monica/process.inc.php:2439 +msgid "This related link was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2445 +msgid "This related link has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2449 +msgid "This related link has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2453 +msgid "This related link has been successfully deleted." +msgstr "" + +#: lib/php/monica/request.inc.php:38 +msgid "Please specify the request." +msgstr "" + +#: lib/php/monica/request.inc.php:46 lib/php/monica/request.inc.php:55 +#, c-format +msgid "Invalid request S/N: %s." +msgstr "" + +#: lib/php/monica/sitesize.inc.php:41 +#, c-format +msgid "Currently using files %s.\n" +msgstr "" + +#: lib/php/monica/sitesize.inc.php:46 +#, c-format +msgid "Currently using files %s, database %s, total %s.\n" +msgstr "" + +#: lib/php/monica/upload.inc.php:70 +#, c-format +msgid "MIME file type: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:71 +#, c-format +msgid "File name: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:72 +#, c-format +msgid "File size: %s bytes" +msgstr "" + +#: lib/php/monica/validate.inc.php:116 +msgid "HTML Validatior Logo Area" +msgstr "" + +#: lib/php/monica/validate.inc.php:117 +msgid "HTML validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:118 +#, c-format +msgid "Valid %s!" +msgstr "" + +#: lib/php/monica/validate.inc.php:119 +msgid "CSS validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:120 +msgid "Valid CSS!" +msgstr "" + +#: lib/php/monica/validate.inc.php:121 +msgid "Explanation of Level Triple-A Conformance" +msgstr "" + +#: lib/php/monica/validate.inc.php:122 +msgid "" +"Level Triple-A conformance icon, W3C-WAI Web Content Accessibility " +"Guidelines 1.0" +msgstr "" diff --git a/po/monica/es_ES.pox b/po/monica/es_ES.pox new file mode 100644 index 0000000..05383d3 --- /dev/null +++ b/po/monica/es_ES.pox @@ -0,0 +1,3297 @@ +# German PO file for the monica core +# Copyright (C) 2007-2018 Pristine Commnications +# This file is distributed under the same license as the monica package. +# imacat , 2007-2018. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: monica 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 12:42+0800\n" +"PO-Revision-Date: 2018-11-02 01:22+0800\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: lib/php/monica/checker.inc.php:159 +msgid "Please select a user." +msgstr "" + +#: lib/php/monica/checker.inc.php:163 +msgid "This user does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:181 +msgid "Please select a group." +msgstr "" + +#: lib/php/monica/checker.inc.php:185 +msgid "This group does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:203 +msgid "Please fill in the script." +msgstr "" + +#: lib/php/monica/checker.inc.php:207 +#, c-format +msgid "This script is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:212 +msgid "This script is not a valid script. Please specify another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:230 +msgid "Please fill in the date." +msgstr "" + +#: lib/php/monica/checker.inc.php:234 lib/php/monica/checker.inc.php:238 +#: lib/php/monica/checker.inc.php:241 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "" + +#: lib/php/monica/checker.inc.php:259 +msgid "Please fill in the ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:263 +#, c-format +msgid "This ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:267 +#, c-format +msgid "This ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:272 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:294 +msgid "Please fill in the order." +msgstr "" + +#: lib/php/monica/checker.inc.php:298 +#, c-format +msgid "This order is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:303 +msgid "Please fill in a positive integer order." +msgstr "" + +#: lib/php/monica/checker.inc.php:307 lib/php/monica/checker.inc.php:317 +#, c-format +msgid "" +"The order is too small. Please fill in a larger order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:321 +#, c-format +msgid "" +"The order is too large. Please fill in a smaller order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:348 +msgid "Please fill in the page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:352 +#, c-format +msgid "This page path is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:365 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:369 +msgid "Please fill in an absolute page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:373 +msgid "Please fill in a valid page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:377 +msgid "You cannot overwrite the cover home page." +msgstr "" + +#: lib/php/monica/checker.inc.php:381 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "" + +#: lib/php/monica/checker.inc.php:422 lib/php/monica/checker.inc.php:428 +msgid "Please fill in the attachment description." +msgstr "" + +#: lib/php/monica/checker.inc.php:432 +#, c-format +msgid "This attachment description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:449 +msgid "This PDF. file does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:456 +#, c-format +msgid "This PDF. file is too large. (Max. size %s)" +msgstr "" + +#: lib/php/monica/checker.inc.php:461 +msgid "Please upload only PDF. file." +msgstr "" + +#: lib/php/monica/checker.inc.php:479 +msgid "Please fill in the title." +msgstr "" + +#: lib/php/monica/checker.inc.php:483 +#, c-format +msgid "This title is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:502 +msgid "Please fill in the subject." +msgstr "" + +#: lib/php/monica/checker.inc.php:506 +#, c-format +msgid "This subject is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:524 lib/php/monica/form.inc.php:3159 +#: lib/php/monica/form.inc.php:3172 +msgid "Fill in the content here." +msgstr "" + +#: lib/php/monica/checker.inc.php:528 +msgid "Please fill in the content." +msgstr "" + +#: lib/php/monica/checker.inc.php:532 +#, c-format +msgid "This content is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:551 +msgid "Please fill in the keywords." +msgstr "" + +#: lib/php/monica/checker.inc.php:555 +#, c-format +msgid "This keyword list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:572 +msgid "Please select a proper pinyin." +msgstr "" + +#: lib/php/monica/checker.inc.php:578 +#, c-format +msgid "This pinyin is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:583 +msgid "" +"This pinyin does not match the Chinese. Please select a proper pinyin from " +"the list." +msgstr "" + +#: lib/php/monica/checker.inc.php:609 lib/php/monica/pic.inc.php:82 +msgid "Please upload the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:616 lib/php/monica/checker.inc.php:3214 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:622 +#, c-format +msgid "This picture is too large. Please upload another one. (Max. size %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:639 lib/php/monica/form.inc.php:3588 +#, c-format +msgid "Please upload a new picture from %s." +msgstr "" + +#: lib/php/monica/checker.inc.php:664 lib/php/monica/checker.inc.php:727 +msgid "Please fill in the picture caption." +msgstr "" + +#: lib/php/monica/checker.inc.php:668 lib/php/monica/checker.inc.php:731 +#, c-format +msgid "This picture caption is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:686 lib/php/monica/checker.inc.php:749 +msgid "Please select the picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:692 lib/php/monica/checker.inc.php:755 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:791 lib/php/monica/checker.inc.php:794 +#, c-format +msgid "Your uploaded file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/checker.inc.php:797 lib/php/monica/pic.inc.php:80 +msgid "" +"Upload not completed. Disk may be full or connection may be closed in the " +"half. You may try to upload again, or contact the system administrator for " +"this problem." +msgstr "" + +#: lib/php/monica/checker.inc.php:799 lib/php/monica/pic.inc.php:84 +#, c-format +msgid "Upload failed with an unknown error (%d)." +msgstr "" + +#: lib/php/monica/checker.inc.php:1183 lib/php/monica/chkfunc.inc.php:59 +#: lib/php/monica/chkfunc.inc.php:72 lib/php/monica/preview.inc.php:29 +#, c-format +msgid "The following field was not received: \"%s\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:1262 +msgid "Please fill in the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1266 +#, c-format +msgid "This user ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1270 +#, c-format +msgid "This user ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1275 +msgid "" +"Only lower-case English letters, numbers, at-signs, dots, dashes and " +"underscores are allowed for the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1287 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1317 +msgid "Please fill in the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1320 +msgid "Please confirm the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1324 +#, c-format +msgid "This password is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1329 +#, c-format +msgid "This password is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1334 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "" + +#: lib/php/monica/checker.inc.php:1345 +msgid "This password is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1360 +msgid "This password does not contain enough different characters." +msgstr "" + +#: lib/php/monica/checker.inc.php:1364 +msgid "This password is too simplistic/systematic." +msgstr "" + +#: lib/php/monica/checker.inc.php:1368 +msgid "This password is based on a dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1370 +msgid "This password is based on a (reversed) dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1372 +msgid "This password is too simple." +msgstr "" + +#: lib/php/monica/checker.inc.php:1378 +msgid "You cannot use a password that is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1397 +msgid "Please fill in the name." +msgstr "" + +#: lib/php/monica/checker.inc.php:1401 +#, c-format +msgid "This name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1420 +msgid "Please fill in the e-mail." +msgstr "" + +#: lib/php/monica/checker.inc.php:1424 +#, c-format +msgid "This e-mail is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1428 +#, c-format +msgid "This e-mail is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1437 +msgid "Please fill in a valid e-mail address." +msgstr "" + +#: lib/php/monica/checker.inc.php:1439 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:1461 lib/php/monica/checker.inc.php:1655 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1478 +msgid "You cannot submit the super-user group along with other groups." +msgstr "" + +#: lib/php/monica/checker.inc.php:1480 +msgid "You cannot set the administrators group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1482 +msgid "You cannot set the all-users group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1515 +msgid "Please fill in the group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1519 +#, c-format +msgid "This group ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1523 +#, c-format +msgid "This group ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1528 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1540 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1558 +msgid "Please fill in the privilege description." +msgstr "" + +#: lib/php/monica/checker.inc.php:1562 +#, c-format +msgid "This privilege description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1585 +msgid "This user member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1620 +msgid "This group member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1747 lib/php/monica/checker.inc.php:1855 +msgid "Please select a member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1751 lib/php/monica/checker.inc.php:1859 +msgid "This member does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1770 lib/php/monica/checker.inc.php:1883 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1837 +msgid "Please select a different belonging group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1864 +msgid "Please select a different group member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1958 +msgid "" +"This script privilege already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1996 lib/php/monica/checker.inc.php:2184 +msgid "Please select the user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2002 lib/php/monica/checker.inc.php:2190 +msgid "This option is invalid. Please select a proper user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2020 +msgid "Please set the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2026 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2039 lib/php/monica/checker.inc.php:2295 +msgid "Please fill in the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2043 lib/php/monica/checker.inc.php:2299 +#, c-format +msgid "This preference domain is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2063 +msgid "Please fill in the preference name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2067 +#, c-format +msgid "This preference name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2086 +msgid "Please fill in the preference value." +msgstr "" + +#: lib/php/monica/checker.inc.php:2090 +#, c-format +msgid "This preference value is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2119 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2167 +msgid "Please select the request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2173 +msgid "This option is invalid. Please select a proper request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2194 +msgid "You must choose anonymous for join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2197 +msgid "You cannot choose anonymous for non-join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2221 lib/php/monica/form.inc.php:5484 +msgid "Please fill in the request arguments list here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2229 +#, c-format +msgid "This request arguments list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2349 +msgid "Please fill in the number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2353 +#, c-format +msgid "This number of rows per page is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2358 +msgid "Please fill in a positive integer number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2362 lib/php/monica/checker.inc.php:2372 +#, c-format +msgid "" +"The number of rows per page is too small. Please fill in a larger number of " +"rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2376 +#, c-format +msgid "" +"The number of rows per page is too large. Please fill in a smaller number " +"of rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2443 +msgid "Please fill in your user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:2451 lib/php/monica/checker.inc.php:2458 +#: lib/php/monica/checker.inc.php:2475 lib/php/monica/checker.inc.php:2508 +#: lib/php/monica/checker.inc.php:2540 lib/php/monica/checker.inc.php:2548 +#: lib/php/monica/checker.inc.php:2558 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "" + +#: lib/php/monica/checker.inc.php:2495 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "" + +#: lib/php/monica/checker.inc.php:2531 +msgid "Please fill in your password." +msgstr "" + +#: lib/php/monica/checker.inc.php:2581 +msgid "You are not an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2600 +msgid "You are an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2751 +msgid "Please fill in the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2755 +#, c-format +msgid "You must fill in a %d-letters code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2760 +msgid "You can only use upper letters and for the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2772 +msgid "This code is duplicated. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2790 +msgid "Please fill in the country name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2794 +#, c-format +msgid "This country name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2822 lib/php/monica/checker.inc.php:2841 +msgid "Please select a parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2828 +msgid "This option is invalid. Please select a proper parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2845 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2850 +msgid "A category cannot belong to itself. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2858 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2876 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:2894 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2941 +msgid "Please fill in the URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2945 +#, c-format +msgid "This URL. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2950 +msgid "Please fill in a valid URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2962 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2967 +msgid "This URL. is not reachable. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:2984 lib/php/monica/form.inc.php:3261 +msgid "Fill in the description here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2988 +msgid "Please fill in the description." +msgstr "" + +#: lib/php/monica/checker.inc.php:2992 +#, c-format +msgid "This description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:3012 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:3016 lib/php/monica/checker.inc.php:3072 +msgid "This category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3022 lib/php/monica/checker.inc.php:3068 +msgid "Please select a category." +msgstr "" + +#: lib/php/monica/checker.inc.php:3090 +msgid "Please select a related link." +msgstr "" + +#: lib/php/monica/checker.inc.php:3094 +msgid "This link does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3113 +msgid "" +"This link categorization already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3154 +msgid "Please select the type." +msgstr "" + +#: lib/php/monica/checker.inc.php:3158 +msgid "This type does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3185 lib/php/monica/list.inc.php:961 +msgid "Please fill in your query." +msgstr "" + +#: lib/php/monica/checker.inc.php:3210 +msgid "Please submit the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:3237 lib/php/monica/checker.inc.php:3328 +msgid "Please fill in the resize ratio." +msgstr "" + +#: lib/php/monica/checker.inc.php:3305 +msgid "Please specify a valid picture." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:156 lib/php/monica/chkfunc.inc.php:160 +#: lib/php/monica/chkfunc.inc.php:163 lib/php/monica/chkfunc.inc.php:166 +msgid "Please select a legal year." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:171 lib/php/monica/chkfunc.inc.php:175 +#: lib/php/monica/chkfunc.inc.php:178 +msgid "Please select a legal month." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:183 lib/php/monica/chkfunc.inc.php:187 +#: lib/php/monica/chkfunc.inc.php:193 +msgid "Please select a legal day." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:27 +#, c-format +msgid "%s: It is not a file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:32 +#, c-format +msgid "%s: You have no permission to overwrite this file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:45 +#, c-format +msgid "%s: You cannot create anything under the root directory." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:50 +#, c-format +msgid "" +"%s: One of the parents of this file (%s) is not a directory. You cannot " +"create any new file inside." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:55 +#, c-format +msgid "%s: You have no permission to create any file under %s." +msgstr "" + +#: lib/php/monica/commtext.inc.php:18 +msgid "(not set)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:24 +msgid "(none)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:30 +msgid "(N/A)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:36 +msgid "(blank)" +msgstr "" + +#: lib/php/monica/echoform.inc.php:173 +#, c-format +msgid "%s bytes" +msgstr "" + +#: lib/php/monica/form.inc.php:168 +msgid "Delete it" +msgstr "" + +#: lib/php/monica/form.inc.php:174 +msgid "Are you sure you want to delete it? It cannot be recovered." +msgstr "" + +#: lib/php/monica/form.inc.php:188 +msgid "*" +msgstr "" + +#: lib/php/monica/form.inc.php:224 +msgid "This table provides you a form to add a new data record." +msgstr "" + +#: lib/php/monica/form.inc.php:228 +msgid "This table provides you a form to update a current data record." +msgstr "" + +#: lib/php/monica/form.inc.php:232 +msgid "This table provides you a form to delete a data record." +msgstr "" + +#: lib/php/monica/form.inc.php:281 +msgid "Add a New Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:285 +msgid "Update a Current Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:289 +msgid "Delete a Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:301 +msgid "Preview it." +msgstr "" + +#: lib/php/monica/form.inc.php:500 lib/php/monica/form.inc.php:506 +#: lib/php/monica/form.inc.php:691 lib/php/monica/form.inc.php:697 +#: lib/php/monica/preview.inc.php:146 +msgid "Preview" +msgstr "" + +#: lib/php/monica/form.inc.php:501 lib/php/monica/form.inc.php:507 +#: lib/php/monica/form.inc.php:692 lib/php/monica/form.inc.php:698 +msgid "Confirm and submit" +msgstr "" + +#: lib/php/monica/form.inc.php:708 lib/php/monica/form.inc.php:1692 +#: lib/php/monica/form.inc.php:1778 lib/php/monica/list.inc.php:1809 +msgid "Delete" +msgstr "" + +#: lib/php/monica/form.inc.php:709 lib/php/monica/form.inc.php:6419 +#: lib/php/monica/form.inc.php:6470 +msgid "Cancel" +msgstr "" + +#: lib/php/monica/form.inc.php:1042 lib/php/monica/form.inc.php:3499 +msgid "Set the picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1043 lib/php/monica/form.inc.php:3031 +#: lib/php/monica/form.inc.php:3500 +msgid "Delete this picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1048 lib/php/monica/form.inc.php:1178 +#: lib/php/monica/form.inc.php:3037 lib/php/monica/form.inc.php:3104 +#: lib/php/monica/form.inc.php:3505 lib/php/monica/form.inc.php:3677 +#: lib/php/monica/form.inc.php:6163 lib/php/monica/list.inc.php:814 +msgid "Picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1059 lib/php/monica/form.inc.php:1109 +#: lib/php/monica/form.inc.php:1185 +#, c-format +msgid "Picture #%d:" +msgstr "" + +#: lib/php/monica/form.inc.php:1080 lib/php/monica/form.inc.php:1131 +#: lib/php/monica/form.inc.php:1166 lib/php/monica/form.inc.php:1199 +msgid "Caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:1092 lib/php/monica/form.inc.php:3064 +#: lib/php/monica/form.inc.php:3566 lib/php/monica/form.inc.php:6183 +msgid "Original picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1093 lib/php/monica/form.inc.php:3065 +#: lib/php/monica/form.inc.php:3567 lib/php/monica/form.inc.php:6197 +msgid "New picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1113 lib/php/monica/form.inc.php:1276 +#: lib/php/monica/form.inc.php:1363 lib/php/monica/form.inc.php:1451 +#: lib/php/monica/form.inc.php:1560 lib/php/monica/form.inc.php:1650 +#: lib/php/monica/form.inc.php:1727 lib/php/monica/form.inc.php:1825 +#: lib/php/monica/form.inc.php:1916 lib/php/monica/form.inc.php:1977 +#: lib/php/monica/form.inc.php:2053 lib/php/monica/form.inc.php:2159 +#: lib/php/monica/form.inc.php:2391 lib/php/monica/form.inc.php:2592 +#: lib/php/monica/form.inc.php:2689 lib/php/monica/form.inc.php:2800 +#: lib/php/monica/form.inc.php:2897 lib/php/monica/form.inc.php:2980 +#: lib/php/monica/form.inc.php:3069 lib/php/monica/form.inc.php:3200 +#: lib/php/monica/form.inc.php:3571 lib/php/monica/form.inc.php:3627 +#: lib/php/monica/form.inc.php:3640 lib/php/monica/form.inc.php:3747 +#: lib/php/monica/form.inc.php:4423 lib/php/monica/form.inc.php:4533 +#: lib/php/monica/form.inc.php:4729 lib/php/monica/form.inc.php:4866 +#: lib/php/monica/form.inc.php:5000 lib/php/monica/form.inc.php:6176 +#: lib/php/monica/form.inc.php:6243 +msgid "Original:" +msgstr "" + +#: lib/php/monica/form.inc.php:1141 lib/php/monica/form.inc.php:1281 +#: lib/php/monica/form.inc.php:1369 lib/php/monica/form.inc.php:1456 +#: lib/php/monica/form.inc.php:1575 lib/php/monica/form.inc.php:1655 +#: lib/php/monica/form.inc.php:1732 lib/php/monica/form.inc.php:1832 +#: lib/php/monica/form.inc.php:1921 lib/php/monica/form.inc.php:1982 +#: lib/php/monica/form.inc.php:2065 lib/php/monica/form.inc.php:2173 +#: lib/php/monica/form.inc.php:2422 lib/php/monica/form.inc.php:2597 +#: lib/php/monica/form.inc.php:2694 lib/php/monica/form.inc.php:2805 +#: lib/php/monica/form.inc.php:2902 lib/php/monica/form.inc.php:2985 +#: lib/php/monica/form.inc.php:3080 lib/php/monica/form.inc.php:3205 +#: lib/php/monica/form.inc.php:3584 lib/php/monica/form.inc.php:3632 +#: lib/php/monica/form.inc.php:3649 lib/php/monica/form.inc.php:3752 +#: lib/php/monica/form.inc.php:4442 lib/php/monica/form.inc.php:4543 +#: lib/php/monica/form.inc.php:4742 lib/php/monica/form.inc.php:4879 +#: lib/php/monica/form.inc.php:5013 lib/php/monica/form.inc.php:6188 +#: lib/php/monica/form.inc.php:6248 lib/php/monica/form.inc.php:6278 +msgid "New:" +msgstr "" + +#: lib/php/monica/form.inc.php:1269 lib/php/monica/form.inc.php:1444 +#: lib/php/monica/form.inc.php:1543 lib/php/monica/form.inc.php:2358 +#: lib/php/monica/form.inc.php:2585 lib/php/monica/form.inc.php:2793 +#: lib/php/monica/form.inc.php:2890 lib/php/monica/form.inc.php:2973 +#: lib/php/monica/form.inc.php:3620 +msgid "Source:" +msgstr "" + +#: lib/php/monica/form.inc.php:1289 lib/php/monica/form.inc.php:1464 +#: lib/php/monica/form.inc.php:1583 lib/php/monica/form.inc.php:2605 +#: lib/php/monica/form.inc.php:2813 lib/php/monica/form.inc.php:2910 +#: lib/php/monica/form.inc.php:2993 +#, c-format +msgid "Please set it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:1501 +msgid "Hide" +msgstr "" + +#: lib/php/monica/form.inc.php:1502 +msgid "Show" +msgstr "" + +#: lib/php/monica/form.inc.php:1691 lib/php/monica/form.inc.php:1777 +#: lib/php/monica/form.inc.php:1887 +msgid "Choose" +msgstr "" + +#: lib/php/monica/form.inc.php:2237 +msgid "Delete this file" +msgstr "" + +#: lib/php/monica/form.inc.php:2267 lib/php/monica/form.inc.php:2368 +#: lib/php/monica/form.inc.php:2400 lib/php/monica/form.inc.php:2445 +#: lib/php/monica/form.inc.php:2506 +msgid "File name:" +msgstr "" + +#: lib/php/monica/form.inc.php:2274 lib/php/monica/form.inc.php:2375 +#: lib/php/monica/form.inc.php:2407 lib/php/monica/form.inc.php:2452 +#: lib/php/monica/form.inc.php:2513 +msgid "MIME file type:" +msgstr "" + +#: lib/php/monica/form.inc.php:2279 lib/php/monica/form.inc.php:2380 +#: lib/php/monica/form.inc.php:2412 lib/php/monica/form.inc.php:2457 +#: lib/php/monica/form.inc.php:2518 +msgid "File size:" +msgstr "" + +#: lib/php/monica/form.inc.php:2430 +#, c-format +msgid "Please upload it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:3128 +msgid "Address:" +msgstr "" + +#: lib/php/monica/form.inc.php:3129 +msgid "Fill in your address here." +msgstr "" + +#: lib/php/monica/form.inc.php:3135 +msgid "Attachment:" +msgstr "" + +#: lib/php/monica/form.inc.php:3139 +msgid "Attachment description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3158 lib/php/monica/form.inc.php:3171 +msgid "Content:" +msgstr "" + +#: lib/php/monica/form.inc.php:3165 +msgid "City:" +msgstr "" + +#: lib/php/monica/form.inc.php:3187 lib/php/monica/form.inc.php:3199 +#: lib/php/monica/form.inc.php:3217 lib/php/monica/form.inc.php:3241 +msgid "Country:" +msgstr "" + +#: lib/php/monica/form.inc.php:3229 +msgid "Created:" +msgstr "" + +#: lib/php/monica/form.inc.php:3235 +msgid "Created by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3247 +msgid "Date:" +msgstr "" + +#: lib/php/monica/form.inc.php:3253 lib/php/monica/form.inc.php:4292 +#: lib/php/monica/form.inc.php:4295 lib/php/monica/list.inc.php:310 +msgid "Disabled?" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 lib/php/monica/list.inc.php:2020 +msgid "Disabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 +msgid "Enabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 +msgid "Disable it." +msgstr "" + +#: lib/php/monica/form.inc.php:3260 lib/php/monica/form.inc.php:4657 +msgid "Description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3267 +msgid "E-mail:" +msgstr "" + +#: lib/php/monica/form.inc.php:3273 +msgid "Fax:" +msgstr "" + +#: lib/php/monica/form.inc.php:3279 +msgid "Group:" +msgstr "" + +#: lib/php/monica/form.inc.php:3285 lib/php/monica/form.inc.php:5541 +#: lib/php/monica/form.inc.php:5747 lib/php/monica/form.inc.php:5905 +#: lib/php/monica/form.inc.php:5998 +msgid "Hide?" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Show it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it currently." +msgstr "" + +#: lib/php/monica/form.inc.php:3292 +msgid "Host:" +msgstr "" + +#: lib/php/monica/form.inc.php:3298 lib/php/monica/list.inc.php:314 +msgid "HTML?" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2948 +#: lib/php/monica/list.inc.php:3062 +msgid "HTML" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2949 +#: lib/php/monica/list.inc.php:3063 +msgid "Plain text" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 +msgid "The submitted content is HTML." +msgstr "" + +#: lib/php/monica/form.inc.php:3305 lib/php/monica/form.inc.php:5535 +#: lib/php/monica/form.inc.php:6074 +msgid "ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3311 +msgid "Introduction:" +msgstr "" + +#: lib/php/monica/form.inc.php:3312 +msgid "Fill in the introduction here." +msgstr "" + +#: lib/php/monica/form.inc.php:3318 +msgid "IP:" +msgstr "" + +#: lib/php/monica/form.inc.php:3324 +msgid "Keywords:" +msgstr "" + +#: lib/php/monica/form.inc.php:3330 +msgid "Language:" +msgstr "" + +#: lib/php/monica/form.inc.php:3355 +msgid "Name:" +msgstr "" + +#: lib/php/monica/form.inc.php:3365 lib/php/monica/form.inc.php:5992 +msgid "Order:" +msgstr "" + +#: lib/php/monica/form.inc.php:3371 +msgid "Organization:" +msgstr "" + +#: lib/php/monica/form.inc.php:3377 +msgid "Parent category:" +msgstr "" + +#: lib/php/monica/form.inc.php:3378 +msgid "At the very top" +msgstr "" + +#: lib/php/monica/form.inc.php:3391 lib/php/monica/form.inc.php:3428 +#: lib/php/monica/form.inc.php:3468 lib/php/monica/form.inc.php:4330 +#: lib/php/monica/form.inc.php:6362 +msgid "Password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3407 lib/php/monica/form.inc.php:3444 +msgid "Confirm password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3458 +msgid "(Leave them blank if you don't plan to change your password.)" +msgstr "" + +#: lib/php/monica/form.inc.php:3484 +msgid "Page path:" +msgstr "" + +#: lib/php/monica/form.inc.php:3490 +msgid "PDF. file:" +msgstr "" + +#: lib/php/monica/form.inc.php:3508 lib/php/monica/form.inc.php:3570 +#: lib/php/monica/form.inc.php:3680 lib/php/monica/form.inc.php:6151 +#: lib/php/monica/form.inc.php:6175 +msgid "Picture:" +msgstr "" + +#: lib/php/monica/form.inc.php:3531 lib/php/monica/form.inc.php:3615 +#: lib/php/monica/form.inc.php:3619 lib/php/monica/form.inc.php:3693 +msgid "Pic. caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:3538 lib/php/monica/form.inc.php:3639 +#: lib/php/monica/form.inc.php:3699 +msgid "Pic. position:" +msgstr "" + +#: lib/php/monica/form.inc.php:3718 lib/php/monica/form.inc.php:3746 +#: lib/php/monica/form.inc.php:3780 +msgid "Pinyin:" +msgstr "" + +#: lib/php/monica/form.inc.php:3722 lib/php/monica/form.inc.php:3756 +msgid "Please fill in the Chinese first." +msgstr "" + +#: lib/php/monica/form.inc.php:3801 +msgid "Subcategory:" +msgid_plural "Subcategories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:3823 +msgid "Script:" +msgstr "" + +#: lib/php/monica/form.inc.php:3829 +msgid "S/N:" +msgstr "" + +#: lib/php/monica/form.inc.php:3835 +msgid "Street:" +msgstr "" + +#: lib/php/monica/form.inc.php:3841 +msgid "Subject:" +msgstr "" + +#: lib/php/monica/form.inc.php:3847 +msgid "Telephone:" +msgstr "" + +#: lib/php/monica/form.inc.php:3853 +msgid "Tel. (cell.):" +msgstr "" + +#: lib/php/monica/form.inc.php:3859 +msgid "Tel. (home):" +msgstr "" + +#: lib/php/monica/form.inc.php:3865 +msgid "Tel. (office):" +msgstr "" + +#: lib/php/monica/form.inc.php:3871 +msgid "Title:" +msgstr "" + +#: lib/php/monica/form.inc.php:3891 +msgid "Value:" +msgstr "" + +#: lib/php/monica/form.inc.php:3897 +msgid "Visits:" +msgstr "" + +#: lib/php/monica/form.inc.php:3903 +msgid "Visited:" +msgstr "" + +#: lib/php/monica/form.inc.php:3909 +msgid "Updated:" +msgstr "" + +#: lib/php/monica/form.inc.php:3915 +msgid "Updated by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3921 +msgid "URL.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3927 +msgid "Zip code:" +msgstr "" + +#: lib/php/monica/form.inc.php:4151 +msgid "Delete this user account" +msgstr "" + +#: lib/php/monica/form.inc.php:4157 +msgid "This table provides you a form to add a new user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4161 +msgid "This table provides you a form to update a current user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4165 +msgid "This table provides you a form to delete a user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4192 +msgid "Add a New User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4196 +msgid "Update a Current User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4200 +msgid "Delete a User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4213 +msgid "This is a super-user. You can only change parts of her infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4220 +msgid "" +"This user has a datum. It cannot be deleted. To delete the user, its datum " +"must first be deleted." +msgid_plural "" +"This user has data. It cannot be deleted. To delete the user, all of its " +"data must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4282 +msgid "Administrator?" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Non-administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4296 +msgid "Disable this user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4305 lib/php/monica/form.inc.php:4307 +#: lib/php/monica/form.inc.php:6354 +msgid "User ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4314 +msgid "Pref. language:" +msgstr "" + +#: lib/php/monica/form.inc.php:4320 +msgid "Full name:" +msgstr "" + +#: lib/php/monica/form.inc.php:4348 lib/php/monica/form.inc.php:4400 +#: lib/php/monica/form.inc.php:4422 lib/php/monica/form.inc.php:4496 +#: lib/php/monica/form.inc.php:4944 lib/php/monica/form.inc.php:4983 +#: lib/php/monica/form.inc.php:4999 lib/php/monica/form.inc.php:5051 +msgid "Belonging to:" +msgstr "" + +#: lib/php/monica/form.inc.php:4532 lib/php/monica/form.inc.php:4554 +msgid "Fail logins:" +msgstr "" + +#: lib/php/monica/form.inc.php:4539 lib/php/monica/form.inc.php:4560 +msgid "(Locked)" +msgstr "" + +#: lib/php/monica/form.inc.php:4585 +msgid "Delete this group" +msgstr "" + +#: lib/php/monica/form.inc.php:4591 +msgid "This table provides you a form to add a new group." +msgstr "" + +#: lib/php/monica/form.inc.php:4595 +msgid "This table provides you a form to update a current group." +msgstr "" + +#: lib/php/monica/form.inc.php:4599 +msgid "This table provides you a form to delete a group." +msgstr "" + +#: lib/php/monica/form.inc.php:4624 +msgid "Add a New Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4628 +msgid "Update a Current Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4632 +msgid "Delete a Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4639 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4648 lib/php/monica/form.inc.php:4650 +msgid "Group ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4663 +msgid "Add a user" +msgstr "" + +#: lib/php/monica/form.inc.php:4670 lib/php/monica/form.inc.php:4710 +#: lib/php/monica/form.inc.php:4728 lib/php/monica/form.inc.php:4781 +msgid "User member:" +msgid_plural "User members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4801 lib/php/monica/form.inc.php:4938 +msgid "Add a group" +msgstr "" + +#: lib/php/monica/form.inc.php:4808 lib/php/monica/form.inc.php:4848 +#: lib/php/monica/form.inc.php:4865 lib/php/monica/form.inc.php:4918 +msgid "Group member:" +msgid_plural "Group members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5085 lib/php/monica/form.inc.php:5160 +msgid "Delete this membership record" +msgstr "" + +#: lib/php/monica/form.inc.php:5091 lib/php/monica/form.inc.php:5166 +msgid "This table provides you a form to add a new membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5095 lib/php/monica/form.inc.php:5170 +msgid "This table provides you a form to change a current membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5099 lib/php/monica/form.inc.php:5174 +msgid "This table provides you a form to delete a membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5122 +msgid "Add a New User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5126 +msgid "Change a Current User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5130 +msgid "Delete a User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5140 lib/php/monica/form.inc.php:5215 +msgid "Member:" +msgstr "" + +#: lib/php/monica/form.inc.php:5197 +msgid "Add a New Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5201 +msgid "Change a Current Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5205 +msgid "Delete a Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5235 +msgid "Delete this user preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5241 +msgid "This table provides you a form to add a new user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5245 +msgid "This table provides you a form to modify a current user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5249 +msgid "This table provides you a form to delete a user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5272 +msgid "Add a New User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5276 +msgid "Modify a Current User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5280 +msgid "Delete a User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5290 lib/php/monica/form.inc.php:5476 +msgid "User:" +msgstr "" + +#: lib/php/monica/form.inc.php:5291 lib/php/monica/list.inc.php:2588 +msgid "Everyone" +msgstr "" + +#: lib/php/monica/form.inc.php:5297 +msgid "Domain:" +msgstr "" + +#: lib/php/monica/form.inc.php:5298 lib/php/monica/list.inc.php:2592 +msgid "Everywhere" +msgstr "" + +#: lib/php/monica/form.inc.php:5318 +msgid "Delete this script privilege record" +msgstr "" + +#: lib/php/monica/form.inc.php:5324 +msgid "This table provides you a form to add a new script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5328 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5332 +msgid "This table provides you a form to delete a script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5355 +msgid "Add a New Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5359 +msgid "Change a Current Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5363 +msgid "Delete a Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5373 +msgid "Privilege:" +msgstr "" + +#: lib/php/monica/form.inc.php:5395 +msgid "Delete this user request" +msgstr "" + +#: lib/php/monica/form.inc.php:5401 +msgid "This table provides you a form to add a new user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5405 +msgid "This table provides you a form to update a current user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5409 +msgid "This table provides you a form to delete a user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5432 +msgid "Add a New User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5436 +msgid "Update a Current User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5440 +msgid "Delete a User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5448 +msgid "Join" +msgstr "" + +#: lib/php/monica/form.inc.php:5452 +msgid "Change e-mail" +msgstr "" + +#: lib/php/monica/form.inc.php:5456 +msgid "Reset password" +msgstr "" + +#: lib/php/monica/form.inc.php:5464 +msgid "Expiration:" +msgstr "" + +#: lib/php/monica/form.inc.php:5470 lib/php/monica/form.inc.php:6432 +msgid "Type:" +msgstr "" + +#: lib/php/monica/form.inc.php:5477 +msgid "Anonymous" +msgstr "" + +#: lib/php/monica/form.inc.php:5483 +msgid "Arguments:" +msgstr "" + +#: lib/php/monica/form.inc.php:5501 +msgid "Delete this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5507 +msgid "This table provides you a form to add a new category." +msgstr "" + +#: lib/php/monica/form.inc.php:5511 +msgid "This table provides you a form to edit a current category." +msgstr "" + +#: lib/php/monica/form.inc.php:5515 +msgid "This table provides you a form to delete a category." +msgstr "" + +#: lib/php/monica/form.inc.php:5525 +msgid "" +"This category has a subcategory. It cannot be deleted. To delete the " +"category, its subcategory must first be deleted." +msgid_plural "" +"This category has subcategories. It cannot be deleted. To delete the " +"category, all of its subcategories must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Show this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5559 +msgid "Delete this categorization record" +msgstr "" + +#: lib/php/monica/form.inc.php:5565 +msgid "This table provides you a form to add a new categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5569 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5573 +msgid "This table provides you a form to delete a categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5618 +msgid "Add a New Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5622 +msgid "Edit a Current Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5626 +msgid "Delete a Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5636 +msgid "" +"This category has a link. It cannot be deleted. To delete the category, " +"its link must first be deleted." +msgid_plural "" +"This category has links. It cannot be deleted. To delete the category, all " +"of its links must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5655 lib/php/monica/form.inc.php:5819 +msgid "Link:" +msgid_plural "Links:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5692 +msgid "Delete this related link" +msgstr "" + +#: lib/php/monica/form.inc.php:5698 +msgid "This table provides you a form to add a new related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5702 +msgid "This table provides you a form to edit a current related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5706 +msgid "This table provides you a form to delete a related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5729 +msgid "Add a New Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5733 +msgid "Edit a Current Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5737 +msgid "Delete a Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 lib/php/monica/form.inc.php:5906 +msgid "Show this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this related link currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5755 lib/php/monica/form.inc.php:5812 +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5794 +msgid "Add a New Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5798 +msgid "Change a Current Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5802 +msgid "Delete a Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5842 +msgid "Delete this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5848 +msgid "This table provides you a form to write a new page." +msgstr "" + +#: lib/php/monica/form.inc.php:5852 +msgid "This table provides you a form to edit a current page." +msgstr "" + +#: lib/php/monica/form.inc.php:5856 +msgid "This table provides you a form to delete a page." +msgstr "" + +#: lib/php/monica/form.inc.php:5881 +msgid "Write a New Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5885 +msgid "Edit a Current Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5889 +msgid "Delete a Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5897 +msgid "Preview this page." +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5929 +msgid "Delete this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5935 +msgid "This table provides you a form to write a new news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5939 +msgid "This table provides you a form to edit a current news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5943 +msgid "This table provides you a form to delete a news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5968 +msgid "Write a New News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5972 +msgid "Edit a Current News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5976 +msgid "Delete a News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5984 +msgid "Preview this news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Show this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article currently." +msgstr "" + +#: lib/php/monica/form.inc.php:6019 +msgid "Delete this country record" +msgstr "" + +#: lib/php/monica/form.inc.php:6025 +msgid "This table provides you a form to add a new country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6029 +msgid "This table provides you a form to edit a current country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6033 +msgid "This table provides you a form to delete a country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6056 +msgid "Add a New Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6060 +msgid "Edit a Current Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6064 +msgid "Delete a Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6080 lib/php/monica/list.inc.php:3391 +msgid "Special?" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A special record" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A normal country" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "This is a special record." +msgstr "" + +#: lib/php/monica/form.inc.php:6110 +msgid "This table provides you a form to add a new picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6114 +msgid "This table provides you a form to modify a current picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6125 +msgid "Upload a New Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6129 +msgid "Modify a Current Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6230 lib/php/monica/form.inc.php:6242 +msgid "Ratio:" +msgstr "" + +#: lib/php/monica/form.inc.php:6267 lib/php/monica/form.inc.php:6277 +msgid "Upload:" +msgstr "" + +#: lib/php/monica/form.inc.php:6308 +msgid "This table provides you a form to log in." +msgstr "" + +#: lib/php/monica/form.inc.php:6314 +msgid "Identify Yourself" +msgstr "" + +#: lib/php/monica/form.inc.php:6323 lib/php/monica/init.inc.php:505 +msgid "" +"Log-in is temporarily closed for maintainance now. Please come again " +"later. Sorry for the inconvienence." +msgstr "" + +#: lib/php/monica/form.inc.php:6332 +msgid "Log in" +msgstr "" + +#: lib/php/monica/form.inc.php:6379 +msgid "Remember me." +msgstr "" + +#: lib/php/monica/form.inc.php:6406 +msgid "Rebuild the Pages" +msgstr "" + +#: lib/php/monica/form.inc.php:6415 +msgid "Confirm" +msgstr "" + +#: lib/php/monica/form.inc.php:6457 +msgid "Log Out" +msgstr "" + +#: lib/php/monica/form.inc.php:6466 +msgid "Log out" +msgstr "" + +#: lib/php/monica/form.inc.php:6480 +msgid "Are you sure you want to log out?" +msgstr "" + +#: lib/php/monica/init.inc.php:114 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" + +#: lib/php/monica/init.inc.php:503 lib/php/monica/init.inc.php:504 +msgid "Log-In Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:524 lib/php/monica/init.inc.php:525 +msgid "Development Site Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:526 +msgid "Development site is closed. Please work on the live site." +msgstr "" + +#: lib/php/monica/links.inc.php:271 +msgid "Related Links" +msgstr "" + +#: lib/php/monica/list.inc.php:130 +msgid "Malformed" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "OK" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "Unreachable" +msgstr "" + +#: lib/php/monica/list.inc.php:290 lib/php/monica/list.inc.php:1534 +#: lib/php/monica/list.inc.php:3642 +msgid "(query phrase)" +msgstr "" + +#: lib/php/monica/list.inc.php:300 +msgid "S/N" +msgstr "" + +#: lib/php/monica/list.inc.php:301 +msgid "Created" +msgstr "" + +#: lib/php/monica/list.inc.php:302 +msgid "Created by" +msgstr "" + +#: lib/php/monica/list.inc.php:303 +msgid "Updated" +msgstr "" + +#: lib/php/monica/list.inc.php:304 +msgid "Updated by" +msgstr "" + +#: lib/php/monica/list.inc.php:306 +msgid "Content" +msgstr "" + +#: lib/php/monica/list.inc.php:307 +msgid "Category" +msgstr "" + +#: lib/php/monica/list.inc.php:308 +msgid "Coverage" +msgstr "" + +#: lib/php/monica/list.inc.php:309 +msgid "Date" +msgstr "" + +#: lib/php/monica/list.inc.php:311 +msgid "Description" +msgstr "" + +#: lib/php/monica/list.inc.php:312 +msgid "E-mail" +msgstr "" + +#: lib/php/monica/list.inc.php:313 +msgid "Hidden?" +msgstr "" + +#: lib/php/monica/list.inc.php:315 +msgid "ID." +msgstr "" + +#: lib/php/monica/list.inc.php:316 +msgid "Keywords" +msgstr "" + +#: lib/php/monica/list.inc.php:317 +msgid "Name" +msgstr "" + +#: lib/php/monica/list.inc.php:318 +msgid "Order" +msgstr "" + +#: lib/php/monica/list.inc.php:319 +msgid "Page path" +msgstr "" + +#: lib/php/monica/list.inc.php:320 +msgid "Picture" +msgstr "" + +#: lib/php/monica/list.inc.php:321 +msgid "Pic. ratio" +msgstr "" + +#: lib/php/monica/list.inc.php:322 +msgid "Pic. caption" +msgstr "" + +#: lib/php/monica/list.inc.php:323 +msgid "Pic. position" +msgstr "" + +#: lib/php/monica/list.inc.php:324 +msgid "Subject" +msgstr "" + +#: lib/php/monica/list.inc.php:325 +msgid "Title" +msgstr "" + +#: lib/php/monica/list.inc.php:326 +msgid "URL." +msgstr "" + +#: lib/php/monica/list.inc.php:327 +msgid "Status (slow)" +msgstr "" + +#: lib/php/monica/list.inc.php:336 +msgid "Select" +msgstr "" + +#: lib/php/monica/list.inc.php:339 +msgid "Select a Data Record" +msgstr "" + +#: lib/php/monica/list.inc.php:343 +msgid "Edit" +msgstr "" + +#: lib/php/monica/list.inc.php:345 +msgid "Manage Data" +msgstr "" + +#: lib/php/monica/list.inc.php:749 +msgid "Nothing found. Please try another query." +msgstr "" + +#: lib/php/monica/list.inc.php:752 +msgid "The database is empty." +msgstr "" + +#: lib/php/monica/list.inc.php:759 +#, c-format +msgid "Your query found %s record." +msgid_plural "Your query found %s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:766 +#, c-format +msgid "%s record." +msgid_plural "%s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:775 +#, c-format +msgid "Your query found %s record, listing %s to %s." +msgid_plural "Your query found %s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:784 +#, c-format +msgid "%s record, listing %s to %s." +msgid_plural "%s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:855 lib/php/monica/list.inc.php:860 +#: lib/php/monica/list.inc.php:869 +#, c-format +msgid "Page number (%s) invalid. Please specify a valid page number." +msgstr "" + +#: lib/php/monica/list.inc.php:874 +#, c-format +msgid "" +"Page number (%d) out of range. Please specify a number between 1 and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:1138 lib/php/monica/list.inc.php:1151 +#, c-format +msgid "You cannot sort by \"%s\"." +msgstr "" + +#: lib/php/monica/list.inc.php:1512 +msgid "Search" +msgstr "" + +#: lib/php/monica/list.inc.php:1610 +msgid "Index" +msgstr "" + +#: lib/php/monica/list.inc.php:1634 +msgid "First" +msgstr "" + +#: lib/php/monica/list.inc.php:1647 +msgid "Previous" +msgstr "" + +#: lib/php/monica/list.inc.php:1696 +msgid "Next" +msgstr "" + +#: lib/php/monica/list.inc.php:1714 +msgid "Last" +msgstr "" + +#: lib/php/monica/list.inc.php:1736 +msgid "Page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1776 lib/php/monica/list.inc.php:1900 +msgid "Delete the selected items." +msgstr "" + +#: lib/php/monica/list.inc.php:1805 +msgid "No." +msgstr "" + +#: lib/php/monica/list.inc.php:1813 lib/php/monica/list.inc.php:1873 +msgid "View" +msgstr "" + +#: lib/php/monica/list.inc.php:1925 +msgid "Set" +msgstr "" + +#: lib/php/monica/list.inc.php:1941 +msgid "Rows per page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1946 +msgid "Display columns:" +msgstr "" + +#: lib/php/monica/list.inc.php:1976 +msgid "Select a User" +msgstr "" + +#: lib/php/monica/list.inc.php:1977 +msgid "Manage Users" +msgstr "" + +#: lib/php/monica/list.inc.php:1982 +msgid "User ID." +msgstr "" + +#: lib/php/monica/list.inc.php:1983 +msgid "Full name" +msgstr "" + +#: lib/php/monica/list.inc.php:1984 +msgid "Deleted?" +msgstr "" + +#: lib/php/monica/list.inc.php:1985 +msgid "Pref. language" +msgstr "" + +#: lib/php/monica/list.inc.php:1986 +msgid "Visits" +msgstr "" + +#: lib/php/monica/list.inc.php:1987 +msgid "Visited" +msgstr "" + +#: lib/php/monica/list.inc.php:1988 +msgid "IP" +msgstr "" + +#: lib/php/monica/list.inc.php:1989 +msgid "Host" +msgstr "" + +#: lib/php/monica/list.inc.php:1990 +msgid "From country" +msgstr "" + +#: lib/php/monica/list.inc.php:1991 +msgid "Fail logins" +msgstr "" + +#: lib/php/monica/list.inc.php:2024 +msgid "Deleted" +msgstr "" + +#: lib/php/monica/list.inc.php:2035 +msgid "Add a new user account." +msgstr "" + +#: lib/php/monica/list.inc.php:2045 +msgid "Search for a user:" +msgstr "" + +#: lib/php/monica/list.inc.php:2063 +#, c-format +msgid "Your query found %s user." +msgid_plural "Your query found %s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2070 +#, c-format +msgid "%s user." +msgid_plural "%s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2079 +#, c-format +msgid "Your query found %s user, listing %s to %s." +msgid_plural "Your query found %s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2088 +#, c-format +msgid "%s user, listing %s to %s." +msgid_plural "%s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2107 +msgid "Select a Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2108 +msgid "Manage Groups" +msgstr "" + +#: lib/php/monica/list.inc.php:2113 +msgid "Group ID." +msgstr "" + +#: lib/php/monica/list.inc.php:2121 +msgid "Add a new group." +msgstr "" + +#: lib/php/monica/list.inc.php:2131 +msgid "Search for a group:" +msgstr "" + +#: lib/php/monica/list.inc.php:2149 +#, c-format +msgid "Your query found %s group." +msgid_plural "Your query found %s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2156 +#, c-format +msgid "%s group." +msgid_plural "%s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2165 +#, c-format +msgid "Your query found %s group, listing %s to %s." +msgid_plural "Your query found %s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2174 +#, c-format +msgid "%s group, listing %s to %s." +msgid_plural "%s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2194 +msgid "Select a User Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2195 +msgid "Manage User Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2200 lib/php/monica/list.inc.php:2323 +msgid "Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2201 lib/php/monica/list.inc.php:2324 +msgid "Member" +msgstr "" + +#: lib/php/monica/list.inc.php:2244 lib/php/monica/list.inc.php:2375 +msgid "Add a new membership record." +msgstr "" + +#: lib/php/monica/list.inc.php:2254 lib/php/monica/list.inc.php:2385 +msgid "Search for a membership record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2272 lib/php/monica/list.inc.php:2403 +#, c-format +msgid "Your query found %s membership record." +msgid_plural "Your query found %s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2279 lib/php/monica/list.inc.php:2410 +#, c-format +msgid "%s membership record." +msgid_plural "%s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2288 lib/php/monica/list.inc.php:2419 +#, c-format +msgid "Your query found %s membership record, listing %s to %s." +msgid_plural "Your query found %s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2297 lib/php/monica/list.inc.php:2428 +#, c-format +msgid "%s membership record, listing %s to %s." +msgid_plural "%s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2317 +msgid "Select a Group Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2318 +msgid "Manage Group Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2448 +msgid "Select a Script Privilege Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2449 +msgid "Manage Script Privileges" +msgstr "" + +#: lib/php/monica/list.inc.php:2454 +msgid "Script" +msgstr "" + +#: lib/php/monica/list.inc.php:2455 +msgid "Privilege" +msgstr "" + +#: lib/php/monica/list.inc.php:2493 +msgid "Add a new script privilege record." +msgstr "" + +#: lib/php/monica/list.inc.php:2503 +msgid "Search for a script privilege record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2521 +#, c-format +msgid "Your query found %s script privilege record." +msgid_plural "Your query found %s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2528 +#, c-format +msgid "%s script privilege record." +msgid_plural "%s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2537 +#, c-format +msgid "Your query found %s script privilege record, listing %s to %s." +msgid_plural "Your query found %s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2546 +#, c-format +msgid "%s script privilege record, listing %s to %s." +msgid_plural "%s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2566 +msgid "Select a User Preference" +msgstr "" + +#: lib/php/monica/list.inc.php:2567 +msgid "Manage User Preferences" +msgstr "" + +#: lib/php/monica/list.inc.php:2574 lib/php/monica/list.inc.php:2689 +msgid "User" +msgstr "" + +#: lib/php/monica/list.inc.php:2575 +msgid "Domain" +msgstr "" + +#: lib/php/monica/list.inc.php:2576 +msgid "Value" +msgstr "" + +#: lib/php/monica/list.inc.php:2610 +msgid "Add a new user preference." +msgstr "" + +#: lib/php/monica/list.inc.php:2620 +msgid "Search for a user preference:" +msgstr "" + +#: lib/php/monica/list.inc.php:2638 +#, c-format +msgid "Your query found %s user preference." +msgid_plural "Your query found %s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2645 +#, c-format +msgid "%s user preference." +msgid_plural "%s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2654 +#, c-format +msgid "Your query found %s user preference, listing %s to %s." +msgid_plural "Your query found %s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2663 +#, c-format +msgid "%s user preference, listing %s to %s." +msgid_plural "%s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2682 +msgid "Select a User Request" +msgstr "" + +#: lib/php/monica/list.inc.php:2683 +msgid "Manage User Requests" +msgstr "" + +#: lib/php/monica/list.inc.php:2688 +msgid "Type" +msgstr "" + +#: lib/php/monica/list.inc.php:2690 +msgid "Arguments" +msgstr "" + +#: lib/php/monica/list.inc.php:2691 +msgid "Expiration" +msgstr "" + +#: lib/php/monica/list.inc.php:2699 +msgid "Add a new user request." +msgstr "" + +#: lib/php/monica/list.inc.php:2709 +msgid "Search for a user request:" +msgstr "" + +#: lib/php/monica/list.inc.php:2727 +#, c-format +msgid "Your query found %s user request." +msgid_plural "Your query found %s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2734 +#, c-format +msgid "%s user request." +msgid_plural "%s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2743 +#, c-format +msgid "Your query found %s user request, listing %s to %s." +msgid_plural "Your query found %s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2752 +#, c-format +msgid "%s user request, listing %s to %s." +msgid_plural "%s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2778 +msgid "Add a new category." +msgstr "" + +#: lib/php/monica/list.inc.php:2788 +msgid "Search for a category:" +msgstr "" + +#: lib/php/monica/list.inc.php:2806 +#, c-format +msgid "Your query found %s category." +msgid_plural "Your query found %s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2813 +#, c-format +msgid "%s category." +msgid_plural "%s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2822 +#, c-format +msgid "Your query found %s category, listing %s to %s." +msgid_plural "Your query found %s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2831 +#, c-format +msgid "%s category, listing %s to %s." +msgid_plural "%s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2849 +msgid "Add a new categorization record." +msgstr "" + +#: lib/php/monica/list.inc.php:2859 +msgid "Search for a categorization record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2877 +#, c-format +msgid "Your query found %s categorization record." +msgid_plural "Your query found %s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2884 +#, c-format +msgid "%s categorization record." +msgid_plural "%s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2893 +#, c-format +msgid "Your query found %s categorization record, listing %s to %s." +msgid_plural "Your query found %s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2902 +#, c-format +msgid "%s categorization record, listing %s to %s." +msgid_plural "%s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2921 +msgid "Select a Page" +msgstr "" + +#: lib/php/monica/list.inc.php:2922 +msgid "Manage Pages" +msgstr "" + +#: lib/php/monica/list.inc.php:2952 lib/php/monica/list.inc.php:3066 +#: lib/php/monica/list.inc.php:3173 lib/php/monica/list.inc.php:3237 +#: lib/php/monica/list.inc.php:3358 +msgid "Hidden" +msgstr "" + +#: lib/php/monica/list.inc.php:2953 lib/php/monica/list.inc.php:3067 +#: lib/php/monica/list.inc.php:3174 lib/php/monica/list.inc.php:3238 +#: lib/php/monica/list.inc.php:3359 +msgid "Shown" +msgstr "" + +#: lib/php/monica/list.inc.php:2963 +msgid "Write a new page." +msgstr "" + +#: lib/php/monica/list.inc.php:2973 +msgid "Search for a page:" +msgstr "" + +#: lib/php/monica/list.inc.php:2991 +#, c-format +msgid "Your query found %s page." +msgid_plural "Your query found %s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2998 +#, c-format +msgid "%s page." +msgid_plural "%s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3007 +#, c-format +msgid "Your query found %s page, listing %s to %s." +msgid_plural "Your query found %s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3016 +#, c-format +msgid "%s page, listing %s to %s." +msgid_plural "%s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3035 +msgid "Select a News Article" +msgstr "" + +#: lib/php/monica/list.inc.php:3036 +msgid "Manage News" +msgstr "" + +#: lib/php/monica/list.inc.php:3077 +msgid "Write a new news article." +msgstr "" + +#: lib/php/monica/list.inc.php:3087 +msgid "Search for a news article:" +msgstr "" + +#: lib/php/monica/list.inc.php:3105 +#, c-format +msgid "Your query found %s news article." +msgid_plural "Your query found %s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3112 +#, c-format +msgid "%s news article." +msgid_plural "%s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3121 +#, c-format +msgid "Your query found %s news article, listing %s to %s." +msgid_plural "Your query found %s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3130 +#, c-format +msgid "%s news article, listing %s to %s." +msgid_plural "%s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3149 +msgid "Select a Link Category" +msgstr "" + +#: lib/php/monica/list.inc.php:3150 +msgid "Manage Link Categories" +msgstr "" + +#: lib/php/monica/list.inc.php:3197 +msgid "Select a Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3198 +msgid "Manage Links" +msgstr "" + +#: lib/php/monica/list.inc.php:3248 +msgid "Add a new related link." +msgstr "" + +#: lib/php/monica/list.inc.php:3258 +msgid "Search for a related link:" +msgstr "" + +#: lib/php/monica/list.inc.php:3276 +#, c-format +msgid "Your query found %s related link." +msgid_plural "Your query found %s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3283 +#, c-format +msgid "%s related link." +msgid_plural "%s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3292 +#, c-format +msgid "Your query found %s related link, listing %s to %s." +msgid_plural "Your query found %s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3301 +#, c-format +msgid "%s related link, listing %s to %s." +msgid_plural "%s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3321 +msgid "Select a Link Categorization Record" +msgstr "" + +#: lib/php/monica/list.inc.php:3322 +msgid "Manage Link Categorization" +msgstr "" + +#: lib/php/monica/list.inc.php:3327 +msgid "Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3383 +msgid "Select a Country" +msgstr "" + +#: lib/php/monica/list.inc.php:3384 +msgid "Manage Country Data" +msgstr "" + +#: lib/php/monica/list.inc.php:3389 +msgid "Code" +msgstr "" + +#: lib/php/monica/list.inc.php:3390 +msgid "Country name" +msgstr "" + +#: lib/php/monica/list.inc.php:3399 +msgid "Add a new country record." +msgstr "" + +#: lib/php/monica/list.inc.php:3409 +msgid "Search for a country:" +msgstr "" + +#: lib/php/monica/list.inc.php:3427 +#, c-format +msgid "Your query found %s country." +msgid_plural "Your query found %s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3434 +#, c-format +msgid "%s country." +msgid_plural "%s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3443 +#, c-format +msgid "Your query found %s country, listing %s to %s." +msgid_plural "Your query found %s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3452 +#, c-format +msgid "%s country, listing %s to %s." +msgid_plural "%s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3474 +msgid "Browse the Activity Log" +msgstr "" + +#: lib/php/monica/list.inc.php:3586 +msgid "Please fill in the number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3590 +#, c-format +msgid "This number of rows to display is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/list.inc.php:3595 +msgid "Please fill in a positive integer number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3599 lib/php/monica/list.inc.php:3609 +#, c-format +msgid "" +"The number of rows to display is too small. Please fill in a larger number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3613 +#, c-format +msgid "" +"The number of rows to display is too large. Please fill in a smaller number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3638 +msgid "Search for log entries:" +msgstr "" + +#: lib/php/monica/list.inc.php:3641 +msgid "Display" +msgstr "" + +#: lib/php/monica/list.inc.php:3654 +msgid "Display rows:" +msgstr "" + +#: lib/php/monica/list.inc.php:3677 +#, c-format +msgid "Your query found %s log entry." +msgid_plural "Your query found %s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3684 +#, c-format +msgid "%s log entry." +msgid_plural "%s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3693 +#, c-format +msgid "Your query found %s log entry, listing %s to %s." +msgid_plural "Your query found %s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3702 +#, c-format +msgid "%s log entry, listing %s to %s." +msgid_plural "%s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/lninfo.inc.php:28 +msgid "English" +msgstr "Inglés" + +#: lib/php/monica/lninfo.inc.php:39 +msgid "Traditional Chinese" +msgstr "Chino tradicional" + +#: lib/php/monica/lninfo.inc.php:50 +msgid "Simplified Chinese" +msgstr "Chino simplificado" + +#: lib/php/monica/lninfo.inc.php:61 +msgid "Chinese" +msgstr "Chino" + +#: lib/php/monica/lninfo.inc.php:72 +msgid "Japanese" +msgstr "Japonés" + +#: lib/php/monica/lninfo.inc.php:83 +msgid "Korean" +msgstr "Coreano" + +#: lib/php/monica/lninfo.inc.php:94 +msgid "German" +msgstr "Alemán" + +#: lib/php/monica/lninfo.inc.php:105 +msgid "Spanish" +msgstr "Español" + +#: lib/php/monica/lninfo.inc.php:366 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:738 +msgid "Web pages" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:739 +msgid "News" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:740 +msgid "Related links" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:741 +msgid "Home page" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:742 +msgid "Whole web site" +msgstr "" + +#: lib/php/monica/pic.inc.php:39 +msgid "Left-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:40 +msgid "Right-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:74 lib/php/monica/pic.inc.php:77 +#, c-format +msgid "This picture file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/pic.inc.php:92 +msgid "Please upload only PNG, JPEG or GIF files." +msgstr "" + +#: lib/php/monica/pic.inc.php:153 +#, c-format +msgid "Width: %d, height: %d, ratio: %0.2f" +msgstr "" + +#: lib/php/monica/pic.inc.php:176 +msgid "Please specify a numeric ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:180 +msgid "Please specify a positive ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:183 +#, c-format +msgid "Please specify a ratio less than or equal to %0.2f." +msgstr "" + +#: lib/php/monica/pic.inc.php:189 +msgid "This image is too large to display." +msgstr "" + +#: lib/php/monica/preview.inc.php:47 +#, c-format +msgid "Unknown preview source: \"%s\"." +msgstr "" + +#: lib/php/monica/preview.inc.php:67 +#, c-format +msgid "Unknown preview form: %d." +msgstr "" + +#: lib/php/monica/preview.inc.php:143 +msgid "Preview Mark Area" +msgstr "" + +#: lib/php/monica/preview.inc.php:148 +msgid "Finish preview and return." +msgstr "" + +#: lib/php/monica/process.inc.php:237 +msgid "This record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:243 +msgid "This record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:247 +msgid "This record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:251 +msgid "This record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:406 +msgid "This category was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:412 +msgid "This category has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:416 +msgid "This category has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:420 +msgid "This category has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:433 +msgid "This categorization record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:439 +msgid "This categorization record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:443 +msgid "This categorization record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:447 +msgid "This categorization record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:782 +msgid "This user account was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:788 +msgid "This user account has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:792 +msgid "This user account has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:796 +msgid "This user account has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1074 +msgid "This group was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1080 +msgid "This group has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1084 +msgid "This group has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1088 +msgid "This group has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1152 lib/php/monica/process.inc.php:1230 +msgid "This membership record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1158 lib/php/monica/process.inc.php:1236 +msgid "This membership record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1162 lib/php/monica/process.inc.php:1240 +msgid "This membership record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1166 lib/php/monica/process.inc.php:1244 +msgid "This membership record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1308 +msgid "This script privilege record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1314 +msgid "This script privilege record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1318 +msgid "This script privilege record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1322 +msgid "This script privilege record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1438 +msgid "This user preference was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1444 +msgid "This user preference has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1448 +msgid "This user preference has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1452 +msgid "This user preference has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1560 +msgid "This user request was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1566 +msgid "This user request has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1570 +msgid "This user request has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1574 +msgid "This user request has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1685 +msgid "This page was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1691 +msgid "This page has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1695 +msgid "This page has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1699 +msgid "This page has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1874 +msgid "This news article was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1880 +msgid "This news article has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1884 +msgid "This news article has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1888 +msgid "This news article has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1997 +msgid "This country was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2003 +msgid "This country has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2007 +msgid "This country has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2011 +msgid "This country has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:2097 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. (%0.3f seconds)" +msgstr "" + +#: lib/php/monica/process.inc.php:2158 +#, c-format +msgid "Welcome, %s!" +msgstr "" + +#: lib/php/monica/process.inc.php:2204 +msgid "You have successfully logged out." +msgstr "" + +#: lib/php/monica/process.inc.php:2439 +msgid "This related link was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2445 +msgid "This related link has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2449 +msgid "This related link has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2453 +msgid "This related link has been successfully deleted." +msgstr "" + +#: lib/php/monica/request.inc.php:38 +msgid "Please specify the request." +msgstr "" + +#: lib/php/monica/request.inc.php:46 lib/php/monica/request.inc.php:55 +#, c-format +msgid "Invalid request S/N: %s." +msgstr "" + +#: lib/php/monica/sitesize.inc.php:41 +#, c-format +msgid "Currently using files %s.\n" +msgstr "" + +#: lib/php/monica/sitesize.inc.php:46 +#, c-format +msgid "Currently using files %s, database %s, total %s.\n" +msgstr "" + +#: lib/php/monica/upload.inc.php:70 +#, c-format +msgid "MIME file type: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:71 +#, c-format +msgid "File name: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:72 +#, c-format +msgid "File size: %s bytes" +msgstr "" + +#: lib/php/monica/validate.inc.php:116 +msgid "HTML Validatior Logo Area" +msgstr "" + +#: lib/php/monica/validate.inc.php:117 +msgid "HTML validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:118 +#, c-format +msgid "Valid %s!" +msgstr "" + +#: lib/php/monica/validate.inc.php:119 +msgid "CSS validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:120 +msgid "Valid CSS!" +msgstr "" + +#: lib/php/monica/validate.inc.php:121 +msgid "Explanation of Level Triple-A Conformance" +msgstr "" + +#: lib/php/monica/validate.inc.php:122 +msgid "" +"Level Triple-A conformance icon, W3C-WAI Web Content Accessibility " +"Guidelines 1.0" +msgstr "" diff --git a/po/monica/ja_JP.gmo b/po/monica/ja_JP.gmo new file mode 100644 index 0000000..e4a1580 Binary files /dev/null and b/po/monica/ja_JP.gmo differ diff --git a/po/monica/ja_JP.po b/po/monica/ja_JP.po new file mode 100644 index 0000000..cb0fc28 --- /dev/null +++ b/po/monica/ja_JP.po @@ -0,0 +1,3296 @@ +# Japanese PO file for the monica core +# Copyright (C) 2007-2018 Pristine Communcations +# This file is distributed under the same license as the monica package. +# imacat , 2007-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: monica 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 12:42+0800\n" +"PO-Revision-Date: 2018-11-02 01:22+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Japanese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: lib/php/monica/checker.inc.php:159 +msgid "Please select a user." +msgstr "" + +#: lib/php/monica/checker.inc.php:163 +msgid "This user does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:181 +msgid "Please select a group." +msgstr "" + +#: lib/php/monica/checker.inc.php:185 +msgid "This group does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:203 +msgid "Please fill in the script." +msgstr "" + +#: lib/php/monica/checker.inc.php:207 +#, c-format +msgid "This script is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:212 +msgid "This script is not a valid script. Please specify another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:230 +msgid "Please fill in the date." +msgstr "" + +#: lib/php/monica/checker.inc.php:234 lib/php/monica/checker.inc.php:238 +#: lib/php/monica/checker.inc.php:241 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "" + +#: lib/php/monica/checker.inc.php:259 +msgid "Please fill in the ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:263 +#, c-format +msgid "This ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:267 +#, c-format +msgid "This ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:272 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:294 +msgid "Please fill in the order." +msgstr "" + +#: lib/php/monica/checker.inc.php:298 +#, c-format +msgid "This order is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:303 +msgid "Please fill in a positive integer order." +msgstr "" + +#: lib/php/monica/checker.inc.php:307 lib/php/monica/checker.inc.php:317 +#, c-format +msgid "" +"The order is too small. Please fill in a larger order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:321 +#, c-format +msgid "" +"The order is too large. Please fill in a smaller order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:348 +msgid "Please fill in the page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:352 +#, c-format +msgid "This page path is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:365 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:369 +msgid "Please fill in an absolute page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:373 +msgid "Please fill in a valid page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:377 +msgid "You cannot overwrite the cover home page." +msgstr "" + +#: lib/php/monica/checker.inc.php:381 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "" + +#: lib/php/monica/checker.inc.php:422 lib/php/monica/checker.inc.php:428 +msgid "Please fill in the attachment description." +msgstr "" + +#: lib/php/monica/checker.inc.php:432 +#, c-format +msgid "This attachment description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:449 +msgid "This PDF. file does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:456 +#, c-format +msgid "This PDF. file is too large. (Max. size %s)" +msgstr "" + +#: lib/php/monica/checker.inc.php:461 +msgid "Please upload only PDF. file." +msgstr "" + +#: lib/php/monica/checker.inc.php:479 +msgid "Please fill in the title." +msgstr "" + +#: lib/php/monica/checker.inc.php:483 +#, c-format +msgid "This title is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:502 +msgid "Please fill in the subject." +msgstr "" + +#: lib/php/monica/checker.inc.php:506 +#, c-format +msgid "This subject is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:524 lib/php/monica/form.inc.php:3159 +#: lib/php/monica/form.inc.php:3172 +msgid "Fill in the content here." +msgstr "" + +#: lib/php/monica/checker.inc.php:528 +msgid "Please fill in the content." +msgstr "" + +#: lib/php/monica/checker.inc.php:532 +#, c-format +msgid "This content is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:551 +msgid "Please fill in the keywords." +msgstr "" + +#: lib/php/monica/checker.inc.php:555 +#, c-format +msgid "This keyword list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:572 +msgid "Please select a proper pinyin." +msgstr "" + +#: lib/php/monica/checker.inc.php:578 +#, c-format +msgid "This pinyin is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:583 +msgid "" +"This pinyin does not match the Chinese. Please select a proper pinyin from " +"the list." +msgstr "" + +#: lib/php/monica/checker.inc.php:609 lib/php/monica/pic.inc.php:82 +msgid "Please upload the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:616 lib/php/monica/checker.inc.php:3214 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:622 +#, c-format +msgid "This picture is too large. Please upload another one. (Max. size %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:639 lib/php/monica/form.inc.php:3588 +#, c-format +msgid "Please upload a new picture from %s." +msgstr "" + +#: lib/php/monica/checker.inc.php:664 lib/php/monica/checker.inc.php:727 +msgid "Please fill in the picture caption." +msgstr "" + +#: lib/php/monica/checker.inc.php:668 lib/php/monica/checker.inc.php:731 +#, c-format +msgid "This picture caption is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:686 lib/php/monica/checker.inc.php:749 +msgid "Please select the picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:692 lib/php/monica/checker.inc.php:755 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:791 lib/php/monica/checker.inc.php:794 +#, c-format +msgid "Your uploaded file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/checker.inc.php:797 lib/php/monica/pic.inc.php:80 +msgid "" +"Upload not completed. Disk may be full or connection may be closed in the " +"half. You may try to upload again, or contact the system administrator for " +"this problem." +msgstr "" + +#: lib/php/monica/checker.inc.php:799 lib/php/monica/pic.inc.php:84 +#, c-format +msgid "Upload failed with an unknown error (%d)." +msgstr "" + +#: lib/php/monica/checker.inc.php:1183 lib/php/monica/chkfunc.inc.php:59 +#: lib/php/monica/chkfunc.inc.php:72 lib/php/monica/preview.inc.php:29 +#, c-format +msgid "The following field was not received: \"%s\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:1262 +msgid "Please fill in the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1266 +#, c-format +msgid "This user ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1270 +#, c-format +msgid "This user ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1275 +msgid "" +"Only lower-case English letters, numbers, at-signs, dots, dashes and " +"underscores are allowed for the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1287 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1317 +msgid "Please fill in the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1320 +msgid "Please confirm the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1324 +#, c-format +msgid "This password is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1329 +#, c-format +msgid "This password is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1334 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "" + +#: lib/php/monica/checker.inc.php:1345 +msgid "This password is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1360 +msgid "This password does not contain enough different characters." +msgstr "" + +#: lib/php/monica/checker.inc.php:1364 +msgid "This password is too simplistic/systematic." +msgstr "" + +#: lib/php/monica/checker.inc.php:1368 +msgid "This password is based on a dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1370 +msgid "This password is based on a (reversed) dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1372 +msgid "This password is too simple." +msgstr "" + +#: lib/php/monica/checker.inc.php:1378 +msgid "You cannot use a password that is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1397 +msgid "Please fill in the name." +msgstr "" + +#: lib/php/monica/checker.inc.php:1401 +#, c-format +msgid "This name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1420 +msgid "Please fill in the e-mail." +msgstr "" + +#: lib/php/monica/checker.inc.php:1424 +#, c-format +msgid "This e-mail is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1428 +#, c-format +msgid "This e-mail is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1437 +msgid "Please fill in a valid e-mail address." +msgstr "" + +#: lib/php/monica/checker.inc.php:1439 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:1461 lib/php/monica/checker.inc.php:1655 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1478 +msgid "You cannot submit the super-user group along with other groups." +msgstr "" + +#: lib/php/monica/checker.inc.php:1480 +msgid "You cannot set the administrators group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1482 +msgid "You cannot set the all-users group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1515 +msgid "Please fill in the group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1519 +#, c-format +msgid "This group ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1523 +#, c-format +msgid "This group ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1528 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1540 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1558 +msgid "Please fill in the privilege description." +msgstr "" + +#: lib/php/monica/checker.inc.php:1562 +#, c-format +msgid "This privilege description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1585 +msgid "This user member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1620 +msgid "This group member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1747 lib/php/monica/checker.inc.php:1855 +msgid "Please select a member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1751 lib/php/monica/checker.inc.php:1859 +msgid "This member does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1770 lib/php/monica/checker.inc.php:1883 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1837 +msgid "Please select a different belonging group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1864 +msgid "Please select a different group member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1958 +msgid "" +"This script privilege already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1996 lib/php/monica/checker.inc.php:2184 +msgid "Please select the user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2002 lib/php/monica/checker.inc.php:2190 +msgid "This option is invalid. Please select a proper user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2020 +msgid "Please set the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2026 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2039 lib/php/monica/checker.inc.php:2295 +msgid "Please fill in the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2043 lib/php/monica/checker.inc.php:2299 +#, c-format +msgid "This preference domain is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2063 +msgid "Please fill in the preference name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2067 +#, c-format +msgid "This preference name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2086 +msgid "Please fill in the preference value." +msgstr "" + +#: lib/php/monica/checker.inc.php:2090 +#, c-format +msgid "This preference value is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2119 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2167 +msgid "Please select the request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2173 +msgid "This option is invalid. Please select a proper request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2194 +msgid "You must choose anonymous for join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2197 +msgid "You cannot choose anonymous for non-join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2221 lib/php/monica/form.inc.php:5484 +msgid "Please fill in the request arguments list here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2229 +#, c-format +msgid "This request arguments list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2349 +msgid "Please fill in the number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2353 +#, c-format +msgid "This number of rows per page is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2358 +msgid "Please fill in a positive integer number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2362 lib/php/monica/checker.inc.php:2372 +#, c-format +msgid "" +"The number of rows per page is too small. Please fill in a larger number of " +"rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2376 +#, c-format +msgid "" +"The number of rows per page is too large. Please fill in a smaller number " +"of rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2443 +msgid "Please fill in your user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:2451 lib/php/monica/checker.inc.php:2458 +#: lib/php/monica/checker.inc.php:2475 lib/php/monica/checker.inc.php:2508 +#: lib/php/monica/checker.inc.php:2540 lib/php/monica/checker.inc.php:2548 +#: lib/php/monica/checker.inc.php:2558 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "" + +#: lib/php/monica/checker.inc.php:2495 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "" + +#: lib/php/monica/checker.inc.php:2531 +msgid "Please fill in your password." +msgstr "" + +#: lib/php/monica/checker.inc.php:2581 +msgid "You are not an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2600 +msgid "You are an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2751 +msgid "Please fill in the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2755 +#, c-format +msgid "You must fill in a %d-letters code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2760 +msgid "You can only use upper letters and for the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2772 +msgid "This code is duplicated. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2790 +msgid "Please fill in the country name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2794 +#, c-format +msgid "This country name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2822 lib/php/monica/checker.inc.php:2841 +msgid "Please select a parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2828 +msgid "This option is invalid. Please select a proper parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2845 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2850 +msgid "A category cannot belong to itself. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2858 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2876 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:2894 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2941 +msgid "Please fill in the URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2945 +#, c-format +msgid "This URL. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2950 +msgid "Please fill in a valid URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2962 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2967 +msgid "This URL. is not reachable. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:2984 lib/php/monica/form.inc.php:3261 +msgid "Fill in the description here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2988 +msgid "Please fill in the description." +msgstr "" + +#: lib/php/monica/checker.inc.php:2992 +#, c-format +msgid "This description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:3012 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:3016 lib/php/monica/checker.inc.php:3072 +msgid "This category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3022 lib/php/monica/checker.inc.php:3068 +msgid "Please select a category." +msgstr "" + +#: lib/php/monica/checker.inc.php:3090 +msgid "Please select a related link." +msgstr "" + +#: lib/php/monica/checker.inc.php:3094 +msgid "This link does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3113 +msgid "" +"This link categorization already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3154 +msgid "Please select the type." +msgstr "" + +#: lib/php/monica/checker.inc.php:3158 +msgid "This type does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3185 lib/php/monica/list.inc.php:961 +msgid "Please fill in your query." +msgstr "" + +#: lib/php/monica/checker.inc.php:3210 +msgid "Please submit the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:3237 lib/php/monica/checker.inc.php:3328 +msgid "Please fill in the resize ratio." +msgstr "" + +#: lib/php/monica/checker.inc.php:3305 +msgid "Please specify a valid picture." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:156 lib/php/monica/chkfunc.inc.php:160 +#: lib/php/monica/chkfunc.inc.php:163 lib/php/monica/chkfunc.inc.php:166 +msgid "Please select a legal year." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:171 lib/php/monica/chkfunc.inc.php:175 +#: lib/php/monica/chkfunc.inc.php:178 +msgid "Please select a legal month." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:183 lib/php/monica/chkfunc.inc.php:187 +#: lib/php/monica/chkfunc.inc.php:193 +msgid "Please select a legal day." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:27 +#, c-format +msgid "%s: It is not a file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:32 +#, c-format +msgid "%s: You have no permission to overwrite this file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:45 +#, c-format +msgid "%s: You cannot create anything under the root directory." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:50 +#, c-format +msgid "" +"%s: One of the parents of this file (%s) is not a directory. You cannot " +"create any new file inside." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:55 +#, c-format +msgid "%s: You have no permission to create any file under %s." +msgstr "" + +#: lib/php/monica/commtext.inc.php:18 +msgid "(not set)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:24 +msgid "(none)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:30 +msgid "(N/A)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:36 +msgid "(blank)" +msgstr "" + +#: lib/php/monica/echoform.inc.php:173 +#, c-format +msgid "%s bytes" +msgstr "" + +#: lib/php/monica/form.inc.php:168 +msgid "Delete it" +msgstr "" + +#: lib/php/monica/form.inc.php:174 +msgid "Are you sure you want to delete it? It cannot be recovered." +msgstr "" + +#: lib/php/monica/form.inc.php:188 +msgid "*" +msgstr "" + +#: lib/php/monica/form.inc.php:224 +msgid "This table provides you a form to add a new data record." +msgstr "" + +#: lib/php/monica/form.inc.php:228 +msgid "This table provides you a form to update a current data record." +msgstr "" + +#: lib/php/monica/form.inc.php:232 +msgid "This table provides you a form to delete a data record." +msgstr "" + +#: lib/php/monica/form.inc.php:281 +msgid "Add a New Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:285 +msgid "Update a Current Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:289 +msgid "Delete a Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:301 +msgid "Preview it." +msgstr "" + +#: lib/php/monica/form.inc.php:500 lib/php/monica/form.inc.php:506 +#: lib/php/monica/form.inc.php:691 lib/php/monica/form.inc.php:697 +#: lib/php/monica/preview.inc.php:146 +msgid "Preview" +msgstr "" + +#: lib/php/monica/form.inc.php:501 lib/php/monica/form.inc.php:507 +#: lib/php/monica/form.inc.php:692 lib/php/monica/form.inc.php:698 +msgid "Confirm and submit" +msgstr "" + +#: lib/php/monica/form.inc.php:708 lib/php/monica/form.inc.php:1692 +#: lib/php/monica/form.inc.php:1778 lib/php/monica/list.inc.php:1809 +msgid "Delete" +msgstr "" + +#: lib/php/monica/form.inc.php:709 lib/php/monica/form.inc.php:6419 +#: lib/php/monica/form.inc.php:6470 +msgid "Cancel" +msgstr "" + +#: lib/php/monica/form.inc.php:1042 lib/php/monica/form.inc.php:3499 +msgid "Set the picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1043 lib/php/monica/form.inc.php:3031 +#: lib/php/monica/form.inc.php:3500 +msgid "Delete this picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1048 lib/php/monica/form.inc.php:1178 +#: lib/php/monica/form.inc.php:3037 lib/php/monica/form.inc.php:3104 +#: lib/php/monica/form.inc.php:3505 lib/php/monica/form.inc.php:3677 +#: lib/php/monica/form.inc.php:6163 lib/php/monica/list.inc.php:814 +msgid "Picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1059 lib/php/monica/form.inc.php:1109 +#: lib/php/monica/form.inc.php:1185 +#, c-format +msgid "Picture #%d:" +msgstr "" + +#: lib/php/monica/form.inc.php:1080 lib/php/monica/form.inc.php:1131 +#: lib/php/monica/form.inc.php:1166 lib/php/monica/form.inc.php:1199 +msgid "Caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:1092 lib/php/monica/form.inc.php:3064 +#: lib/php/monica/form.inc.php:3566 lib/php/monica/form.inc.php:6183 +msgid "Original picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1093 lib/php/monica/form.inc.php:3065 +#: lib/php/monica/form.inc.php:3567 lib/php/monica/form.inc.php:6197 +msgid "New picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1113 lib/php/monica/form.inc.php:1276 +#: lib/php/monica/form.inc.php:1363 lib/php/monica/form.inc.php:1451 +#: lib/php/monica/form.inc.php:1560 lib/php/monica/form.inc.php:1650 +#: lib/php/monica/form.inc.php:1727 lib/php/monica/form.inc.php:1825 +#: lib/php/monica/form.inc.php:1916 lib/php/monica/form.inc.php:1977 +#: lib/php/monica/form.inc.php:2053 lib/php/monica/form.inc.php:2159 +#: lib/php/monica/form.inc.php:2391 lib/php/monica/form.inc.php:2592 +#: lib/php/monica/form.inc.php:2689 lib/php/monica/form.inc.php:2800 +#: lib/php/monica/form.inc.php:2897 lib/php/monica/form.inc.php:2980 +#: lib/php/monica/form.inc.php:3069 lib/php/monica/form.inc.php:3200 +#: lib/php/monica/form.inc.php:3571 lib/php/monica/form.inc.php:3627 +#: lib/php/monica/form.inc.php:3640 lib/php/monica/form.inc.php:3747 +#: lib/php/monica/form.inc.php:4423 lib/php/monica/form.inc.php:4533 +#: lib/php/monica/form.inc.php:4729 lib/php/monica/form.inc.php:4866 +#: lib/php/monica/form.inc.php:5000 lib/php/monica/form.inc.php:6176 +#: lib/php/monica/form.inc.php:6243 +msgid "Original:" +msgstr "" + +#: lib/php/monica/form.inc.php:1141 lib/php/monica/form.inc.php:1281 +#: lib/php/monica/form.inc.php:1369 lib/php/monica/form.inc.php:1456 +#: lib/php/monica/form.inc.php:1575 lib/php/monica/form.inc.php:1655 +#: lib/php/monica/form.inc.php:1732 lib/php/monica/form.inc.php:1832 +#: lib/php/monica/form.inc.php:1921 lib/php/monica/form.inc.php:1982 +#: lib/php/monica/form.inc.php:2065 lib/php/monica/form.inc.php:2173 +#: lib/php/monica/form.inc.php:2422 lib/php/monica/form.inc.php:2597 +#: lib/php/monica/form.inc.php:2694 lib/php/monica/form.inc.php:2805 +#: lib/php/monica/form.inc.php:2902 lib/php/monica/form.inc.php:2985 +#: lib/php/monica/form.inc.php:3080 lib/php/monica/form.inc.php:3205 +#: lib/php/monica/form.inc.php:3584 lib/php/monica/form.inc.php:3632 +#: lib/php/monica/form.inc.php:3649 lib/php/monica/form.inc.php:3752 +#: lib/php/monica/form.inc.php:4442 lib/php/monica/form.inc.php:4543 +#: lib/php/monica/form.inc.php:4742 lib/php/monica/form.inc.php:4879 +#: lib/php/monica/form.inc.php:5013 lib/php/monica/form.inc.php:6188 +#: lib/php/monica/form.inc.php:6248 lib/php/monica/form.inc.php:6278 +msgid "New:" +msgstr "" + +#: lib/php/monica/form.inc.php:1269 lib/php/monica/form.inc.php:1444 +#: lib/php/monica/form.inc.php:1543 lib/php/monica/form.inc.php:2358 +#: lib/php/monica/form.inc.php:2585 lib/php/monica/form.inc.php:2793 +#: lib/php/monica/form.inc.php:2890 lib/php/monica/form.inc.php:2973 +#: lib/php/monica/form.inc.php:3620 +msgid "Source:" +msgstr "" + +#: lib/php/monica/form.inc.php:1289 lib/php/monica/form.inc.php:1464 +#: lib/php/monica/form.inc.php:1583 lib/php/monica/form.inc.php:2605 +#: lib/php/monica/form.inc.php:2813 lib/php/monica/form.inc.php:2910 +#: lib/php/monica/form.inc.php:2993 +#, c-format +msgid "Please set it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:1501 +msgid "Hide" +msgstr "" + +#: lib/php/monica/form.inc.php:1502 +msgid "Show" +msgstr "" + +#: lib/php/monica/form.inc.php:1691 lib/php/monica/form.inc.php:1777 +#: lib/php/monica/form.inc.php:1887 +msgid "Choose" +msgstr "" + +#: lib/php/monica/form.inc.php:2237 +msgid "Delete this file" +msgstr "" + +#: lib/php/monica/form.inc.php:2267 lib/php/monica/form.inc.php:2368 +#: lib/php/monica/form.inc.php:2400 lib/php/monica/form.inc.php:2445 +#: lib/php/monica/form.inc.php:2506 +msgid "File name:" +msgstr "" + +#: lib/php/monica/form.inc.php:2274 lib/php/monica/form.inc.php:2375 +#: lib/php/monica/form.inc.php:2407 lib/php/monica/form.inc.php:2452 +#: lib/php/monica/form.inc.php:2513 +msgid "MIME file type:" +msgstr "" + +#: lib/php/monica/form.inc.php:2279 lib/php/monica/form.inc.php:2380 +#: lib/php/monica/form.inc.php:2412 lib/php/monica/form.inc.php:2457 +#: lib/php/monica/form.inc.php:2518 +msgid "File size:" +msgstr "" + +#: lib/php/monica/form.inc.php:2430 +#, c-format +msgid "Please upload it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:3128 +msgid "Address:" +msgstr "" + +#: lib/php/monica/form.inc.php:3129 +msgid "Fill in your address here." +msgstr "" + +#: lib/php/monica/form.inc.php:3135 +msgid "Attachment:" +msgstr "" + +#: lib/php/monica/form.inc.php:3139 +msgid "Attachment description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3158 lib/php/monica/form.inc.php:3171 +msgid "Content:" +msgstr "" + +#: lib/php/monica/form.inc.php:3165 +msgid "City:" +msgstr "" + +#: lib/php/monica/form.inc.php:3187 lib/php/monica/form.inc.php:3199 +#: lib/php/monica/form.inc.php:3217 lib/php/monica/form.inc.php:3241 +msgid "Country:" +msgstr "" + +#: lib/php/monica/form.inc.php:3229 +msgid "Created:" +msgstr "" + +#: lib/php/monica/form.inc.php:3235 +msgid "Created by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3247 +msgid "Date:" +msgstr "" + +#: lib/php/monica/form.inc.php:3253 lib/php/monica/form.inc.php:4292 +#: lib/php/monica/form.inc.php:4295 lib/php/monica/list.inc.php:310 +msgid "Disabled?" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 lib/php/monica/list.inc.php:2020 +msgid "Disabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 +msgid "Enabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 +msgid "Disable it." +msgstr "" + +#: lib/php/monica/form.inc.php:3260 lib/php/monica/form.inc.php:4657 +msgid "Description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3267 +msgid "E-mail:" +msgstr "" + +#: lib/php/monica/form.inc.php:3273 +msgid "Fax:" +msgstr "" + +#: lib/php/monica/form.inc.php:3279 +msgid "Group:" +msgstr "" + +#: lib/php/monica/form.inc.php:3285 lib/php/monica/form.inc.php:5541 +#: lib/php/monica/form.inc.php:5747 lib/php/monica/form.inc.php:5905 +#: lib/php/monica/form.inc.php:5998 +msgid "Hide?" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Show it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it currently." +msgstr "" + +#: lib/php/monica/form.inc.php:3292 +msgid "Host:" +msgstr "" + +#: lib/php/monica/form.inc.php:3298 lib/php/monica/list.inc.php:314 +msgid "HTML?" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2948 +#: lib/php/monica/list.inc.php:3062 +msgid "HTML" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2949 +#: lib/php/monica/list.inc.php:3063 +msgid "Plain text" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 +msgid "The submitted content is HTML." +msgstr "" + +#: lib/php/monica/form.inc.php:3305 lib/php/monica/form.inc.php:5535 +#: lib/php/monica/form.inc.php:6074 +msgid "ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3311 +msgid "Introduction:" +msgstr "" + +#: lib/php/monica/form.inc.php:3312 +msgid "Fill in the introduction here." +msgstr "" + +#: lib/php/monica/form.inc.php:3318 +msgid "IP:" +msgstr "" + +#: lib/php/monica/form.inc.php:3324 +msgid "Keywords:" +msgstr "" + +#: lib/php/monica/form.inc.php:3330 +msgid "Language:" +msgstr "" + +#: lib/php/monica/form.inc.php:3355 +msgid "Name:" +msgstr "" + +#: lib/php/monica/form.inc.php:3365 lib/php/monica/form.inc.php:5992 +msgid "Order:" +msgstr "" + +#: lib/php/monica/form.inc.php:3371 +msgid "Organization:" +msgstr "" + +#: lib/php/monica/form.inc.php:3377 +msgid "Parent category:" +msgstr "" + +#: lib/php/monica/form.inc.php:3378 +msgid "At the very top" +msgstr "" + +#: lib/php/monica/form.inc.php:3391 lib/php/monica/form.inc.php:3428 +#: lib/php/monica/form.inc.php:3468 lib/php/monica/form.inc.php:4330 +#: lib/php/monica/form.inc.php:6362 +msgid "Password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3407 lib/php/monica/form.inc.php:3444 +msgid "Confirm password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3458 +msgid "(Leave them blank if you don't plan to change your password.)" +msgstr "" + +#: lib/php/monica/form.inc.php:3484 +msgid "Page path:" +msgstr "" + +#: lib/php/monica/form.inc.php:3490 +msgid "PDF. file:" +msgstr "" + +#: lib/php/monica/form.inc.php:3508 lib/php/monica/form.inc.php:3570 +#: lib/php/monica/form.inc.php:3680 lib/php/monica/form.inc.php:6151 +#: lib/php/monica/form.inc.php:6175 +msgid "Picture:" +msgstr "" + +#: lib/php/monica/form.inc.php:3531 lib/php/monica/form.inc.php:3615 +#: lib/php/monica/form.inc.php:3619 lib/php/monica/form.inc.php:3693 +msgid "Pic. caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:3538 lib/php/monica/form.inc.php:3639 +#: lib/php/monica/form.inc.php:3699 +msgid "Pic. position:" +msgstr "" + +#: lib/php/monica/form.inc.php:3718 lib/php/monica/form.inc.php:3746 +#: lib/php/monica/form.inc.php:3780 +msgid "Pinyin:" +msgstr "" + +#: lib/php/monica/form.inc.php:3722 lib/php/monica/form.inc.php:3756 +msgid "Please fill in the Chinese first." +msgstr "" + +#: lib/php/monica/form.inc.php:3801 +msgid "Subcategory:" +msgid_plural "Subcategories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:3823 +msgid "Script:" +msgstr "" + +#: lib/php/monica/form.inc.php:3829 +msgid "S/N:" +msgstr "" + +#: lib/php/monica/form.inc.php:3835 +msgid "Street:" +msgstr "" + +#: lib/php/monica/form.inc.php:3841 +msgid "Subject:" +msgstr "" + +#: lib/php/monica/form.inc.php:3847 +msgid "Telephone:" +msgstr "" + +#: lib/php/monica/form.inc.php:3853 +msgid "Tel. (cell.):" +msgstr "" + +#: lib/php/monica/form.inc.php:3859 +msgid "Tel. (home):" +msgstr "" + +#: lib/php/monica/form.inc.php:3865 +msgid "Tel. (office):" +msgstr "" + +#: lib/php/monica/form.inc.php:3871 +msgid "Title:" +msgstr "" + +#: lib/php/monica/form.inc.php:3891 +msgid "Value:" +msgstr "" + +#: lib/php/monica/form.inc.php:3897 +msgid "Visits:" +msgstr "" + +#: lib/php/monica/form.inc.php:3903 +msgid "Visited:" +msgstr "" + +#: lib/php/monica/form.inc.php:3909 +msgid "Updated:" +msgstr "" + +#: lib/php/monica/form.inc.php:3915 +msgid "Updated by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3921 +msgid "URL.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3927 +msgid "Zip code:" +msgstr "" + +#: lib/php/monica/form.inc.php:4151 +msgid "Delete this user account" +msgstr "" + +#: lib/php/monica/form.inc.php:4157 +msgid "This table provides you a form to add a new user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4161 +msgid "This table provides you a form to update a current user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4165 +msgid "This table provides you a form to delete a user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4192 +msgid "Add a New User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4196 +msgid "Update a Current User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4200 +msgid "Delete a User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4213 +msgid "This is a super-user. You can only change parts of her infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4220 +msgid "" +"This user has a datum. It cannot be deleted. To delete the user, its datum " +"must first be deleted." +msgid_plural "" +"This user has data. It cannot be deleted. To delete the user, all of its " +"data must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4282 +msgid "Administrator?" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Non-administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4296 +msgid "Disable this user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4305 lib/php/monica/form.inc.php:4307 +#: lib/php/monica/form.inc.php:6354 +msgid "User ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4314 +msgid "Pref. language:" +msgstr "" + +#: lib/php/monica/form.inc.php:4320 +msgid "Full name:" +msgstr "" + +#: lib/php/monica/form.inc.php:4348 lib/php/monica/form.inc.php:4400 +#: lib/php/monica/form.inc.php:4422 lib/php/monica/form.inc.php:4496 +#: lib/php/monica/form.inc.php:4944 lib/php/monica/form.inc.php:4983 +#: lib/php/monica/form.inc.php:4999 lib/php/monica/form.inc.php:5051 +msgid "Belonging to:" +msgstr "" + +#: lib/php/monica/form.inc.php:4532 lib/php/monica/form.inc.php:4554 +msgid "Fail logins:" +msgstr "" + +#: lib/php/monica/form.inc.php:4539 lib/php/monica/form.inc.php:4560 +msgid "(Locked)" +msgstr "" + +#: lib/php/monica/form.inc.php:4585 +msgid "Delete this group" +msgstr "" + +#: lib/php/monica/form.inc.php:4591 +msgid "This table provides you a form to add a new group." +msgstr "" + +#: lib/php/monica/form.inc.php:4595 +msgid "This table provides you a form to update a current group." +msgstr "" + +#: lib/php/monica/form.inc.php:4599 +msgid "This table provides you a form to delete a group." +msgstr "" + +#: lib/php/monica/form.inc.php:4624 +msgid "Add a New Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4628 +msgid "Update a Current Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4632 +msgid "Delete a Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4639 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4648 lib/php/monica/form.inc.php:4650 +msgid "Group ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4663 +msgid "Add a user" +msgstr "" + +#: lib/php/monica/form.inc.php:4670 lib/php/monica/form.inc.php:4710 +#: lib/php/monica/form.inc.php:4728 lib/php/monica/form.inc.php:4781 +msgid "User member:" +msgid_plural "User members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4801 lib/php/monica/form.inc.php:4938 +msgid "Add a group" +msgstr "" + +#: lib/php/monica/form.inc.php:4808 lib/php/monica/form.inc.php:4848 +#: lib/php/monica/form.inc.php:4865 lib/php/monica/form.inc.php:4918 +msgid "Group member:" +msgid_plural "Group members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5085 lib/php/monica/form.inc.php:5160 +msgid "Delete this membership record" +msgstr "" + +#: lib/php/monica/form.inc.php:5091 lib/php/monica/form.inc.php:5166 +msgid "This table provides you a form to add a new membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5095 lib/php/monica/form.inc.php:5170 +msgid "This table provides you a form to change a current membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5099 lib/php/monica/form.inc.php:5174 +msgid "This table provides you a form to delete a membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5122 +msgid "Add a New User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5126 +msgid "Change a Current User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5130 +msgid "Delete a User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5140 lib/php/monica/form.inc.php:5215 +msgid "Member:" +msgstr "" + +#: lib/php/monica/form.inc.php:5197 +msgid "Add a New Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5201 +msgid "Change a Current Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5205 +msgid "Delete a Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5235 +msgid "Delete this user preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5241 +msgid "This table provides you a form to add a new user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5245 +msgid "This table provides you a form to modify a current user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5249 +msgid "This table provides you a form to delete a user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5272 +msgid "Add a New User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5276 +msgid "Modify a Current User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5280 +msgid "Delete a User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5290 lib/php/monica/form.inc.php:5476 +msgid "User:" +msgstr "" + +#: lib/php/monica/form.inc.php:5291 lib/php/monica/list.inc.php:2588 +msgid "Everyone" +msgstr "" + +#: lib/php/monica/form.inc.php:5297 +msgid "Domain:" +msgstr "" + +#: lib/php/monica/form.inc.php:5298 lib/php/monica/list.inc.php:2592 +msgid "Everywhere" +msgstr "" + +#: lib/php/monica/form.inc.php:5318 +msgid "Delete this script privilege record" +msgstr "" + +#: lib/php/monica/form.inc.php:5324 +msgid "This table provides you a form to add a new script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5328 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5332 +msgid "This table provides you a form to delete a script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5355 +msgid "Add a New Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5359 +msgid "Change a Current Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5363 +msgid "Delete a Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5373 +msgid "Privilege:" +msgstr "" + +#: lib/php/monica/form.inc.php:5395 +msgid "Delete this user request" +msgstr "" + +#: lib/php/monica/form.inc.php:5401 +msgid "This table provides you a form to add a new user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5405 +msgid "This table provides you a form to update a current user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5409 +msgid "This table provides you a form to delete a user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5432 +msgid "Add a New User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5436 +msgid "Update a Current User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5440 +msgid "Delete a User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5448 +msgid "Join" +msgstr "" + +#: lib/php/monica/form.inc.php:5452 +msgid "Change e-mail" +msgstr "" + +#: lib/php/monica/form.inc.php:5456 +msgid "Reset password" +msgstr "" + +#: lib/php/monica/form.inc.php:5464 +msgid "Expiration:" +msgstr "" + +#: lib/php/monica/form.inc.php:5470 lib/php/monica/form.inc.php:6432 +msgid "Type:" +msgstr "" + +#: lib/php/monica/form.inc.php:5477 +msgid "Anonymous" +msgstr "" + +#: lib/php/monica/form.inc.php:5483 +msgid "Arguments:" +msgstr "" + +#: lib/php/monica/form.inc.php:5501 +msgid "Delete this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5507 +msgid "This table provides you a form to add a new category." +msgstr "" + +#: lib/php/monica/form.inc.php:5511 +msgid "This table provides you a form to edit a current category." +msgstr "" + +#: lib/php/monica/form.inc.php:5515 +msgid "This table provides you a form to delete a category." +msgstr "" + +#: lib/php/monica/form.inc.php:5525 +msgid "" +"This category has a subcategory. It cannot be deleted. To delete the " +"category, its subcategory must first be deleted." +msgid_plural "" +"This category has subcategories. It cannot be deleted. To delete the " +"category, all of its subcategories must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Show this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5559 +msgid "Delete this categorization record" +msgstr "" + +#: lib/php/monica/form.inc.php:5565 +msgid "This table provides you a form to add a new categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5569 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5573 +msgid "This table provides you a form to delete a categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5618 +msgid "Add a New Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5622 +msgid "Edit a Current Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5626 +msgid "Delete a Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5636 +msgid "" +"This category has a link. It cannot be deleted. To delete the category, " +"its link must first be deleted." +msgid_plural "" +"This category has links. It cannot be deleted. To delete the category, all " +"of its links must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5655 lib/php/monica/form.inc.php:5819 +msgid "Link:" +msgid_plural "Links:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5692 +msgid "Delete this related link" +msgstr "" + +#: lib/php/monica/form.inc.php:5698 +msgid "This table provides you a form to add a new related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5702 +msgid "This table provides you a form to edit a current related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5706 +msgid "This table provides you a form to delete a related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5729 +msgid "Add a New Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5733 +msgid "Edit a Current Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5737 +msgid "Delete a Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 lib/php/monica/form.inc.php:5906 +msgid "Show this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this related link currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5755 lib/php/monica/form.inc.php:5812 +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5794 +msgid "Add a New Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5798 +msgid "Change a Current Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5802 +msgid "Delete a Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5842 +msgid "Delete this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5848 +msgid "This table provides you a form to write a new page." +msgstr "" + +#: lib/php/monica/form.inc.php:5852 +msgid "This table provides you a form to edit a current page." +msgstr "" + +#: lib/php/monica/form.inc.php:5856 +msgid "This table provides you a form to delete a page." +msgstr "" + +#: lib/php/monica/form.inc.php:5881 +msgid "Write a New Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5885 +msgid "Edit a Current Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5889 +msgid "Delete a Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5897 +msgid "Preview this page." +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5929 +msgid "Delete this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5935 +msgid "This table provides you a form to write a new news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5939 +msgid "This table provides you a form to edit a current news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5943 +msgid "This table provides you a form to delete a news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5968 +msgid "Write a New News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5972 +msgid "Edit a Current News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5976 +msgid "Delete a News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5984 +msgid "Preview this news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Show this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article currently." +msgstr "" + +#: lib/php/monica/form.inc.php:6019 +msgid "Delete this country record" +msgstr "" + +#: lib/php/monica/form.inc.php:6025 +msgid "This table provides you a form to add a new country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6029 +msgid "This table provides you a form to edit a current country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6033 +msgid "This table provides you a form to delete a country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6056 +msgid "Add a New Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6060 +msgid "Edit a Current Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6064 +msgid "Delete a Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6080 lib/php/monica/list.inc.php:3391 +msgid "Special?" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A special record" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A normal country" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "This is a special record." +msgstr "" + +#: lib/php/monica/form.inc.php:6110 +msgid "This table provides you a form to add a new picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6114 +msgid "This table provides you a form to modify a current picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6125 +msgid "Upload a New Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6129 +msgid "Modify a Current Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6230 lib/php/monica/form.inc.php:6242 +msgid "Ratio:" +msgstr "" + +#: lib/php/monica/form.inc.php:6267 lib/php/monica/form.inc.php:6277 +msgid "Upload:" +msgstr "" + +#: lib/php/monica/form.inc.php:6308 +msgid "This table provides you a form to log in." +msgstr "" + +#: lib/php/monica/form.inc.php:6314 +msgid "Identify Yourself" +msgstr "" + +#: lib/php/monica/form.inc.php:6323 lib/php/monica/init.inc.php:505 +msgid "" +"Log-in is temporarily closed for maintainance now. Please come again " +"later. Sorry for the inconvienence." +msgstr "" + +#: lib/php/monica/form.inc.php:6332 +msgid "Log in" +msgstr "" + +#: lib/php/monica/form.inc.php:6379 +msgid "Remember me." +msgstr "" + +#: lib/php/monica/form.inc.php:6406 +msgid "Rebuild the Pages" +msgstr "" + +#: lib/php/monica/form.inc.php:6415 +msgid "Confirm" +msgstr "" + +#: lib/php/monica/form.inc.php:6457 +msgid "Log Out" +msgstr "" + +#: lib/php/monica/form.inc.php:6466 +msgid "Log out" +msgstr "" + +#: lib/php/monica/form.inc.php:6480 +msgid "Are you sure you want to log out?" +msgstr "" + +#: lib/php/monica/init.inc.php:114 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" + +#: lib/php/monica/init.inc.php:503 lib/php/monica/init.inc.php:504 +msgid "Log-In Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:524 lib/php/monica/init.inc.php:525 +msgid "Development Site Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:526 +msgid "Development site is closed. Please work on the live site." +msgstr "" + +#: lib/php/monica/links.inc.php:271 +msgid "Related Links" +msgstr "" + +#: lib/php/monica/list.inc.php:130 +msgid "Malformed" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "OK" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "Unreachable" +msgstr "" + +#: lib/php/monica/list.inc.php:290 lib/php/monica/list.inc.php:1534 +#: lib/php/monica/list.inc.php:3642 +msgid "(query phrase)" +msgstr "" + +#: lib/php/monica/list.inc.php:300 +msgid "S/N" +msgstr "" + +#: lib/php/monica/list.inc.php:301 +msgid "Created" +msgstr "" + +#: lib/php/monica/list.inc.php:302 +msgid "Created by" +msgstr "" + +#: lib/php/monica/list.inc.php:303 +msgid "Updated" +msgstr "" + +#: lib/php/monica/list.inc.php:304 +msgid "Updated by" +msgstr "" + +#: lib/php/monica/list.inc.php:306 +msgid "Content" +msgstr "" + +#: lib/php/monica/list.inc.php:307 +msgid "Category" +msgstr "" + +#: lib/php/monica/list.inc.php:308 +msgid "Coverage" +msgstr "" + +#: lib/php/monica/list.inc.php:309 +msgid "Date" +msgstr "" + +#: lib/php/monica/list.inc.php:311 +msgid "Description" +msgstr "" + +#: lib/php/monica/list.inc.php:312 +msgid "E-mail" +msgstr "" + +#: lib/php/monica/list.inc.php:313 +msgid "Hidden?" +msgstr "" + +#: lib/php/monica/list.inc.php:315 +msgid "ID." +msgstr "" + +#: lib/php/monica/list.inc.php:316 +msgid "Keywords" +msgstr "" + +#: lib/php/monica/list.inc.php:317 +msgid "Name" +msgstr "" + +#: lib/php/monica/list.inc.php:318 +msgid "Order" +msgstr "" + +#: lib/php/monica/list.inc.php:319 +msgid "Page path" +msgstr "" + +#: lib/php/monica/list.inc.php:320 +msgid "Picture" +msgstr "" + +#: lib/php/monica/list.inc.php:321 +msgid "Pic. ratio" +msgstr "" + +#: lib/php/monica/list.inc.php:322 +msgid "Pic. caption" +msgstr "" + +#: lib/php/monica/list.inc.php:323 +msgid "Pic. position" +msgstr "" + +#: lib/php/monica/list.inc.php:324 +msgid "Subject" +msgstr "" + +#: lib/php/monica/list.inc.php:325 +msgid "Title" +msgstr "" + +#: lib/php/monica/list.inc.php:326 +msgid "URL." +msgstr "" + +#: lib/php/monica/list.inc.php:327 +msgid "Status (slow)" +msgstr "" + +#: lib/php/monica/list.inc.php:336 +msgid "Select" +msgstr "" + +#: lib/php/monica/list.inc.php:339 +msgid "Select a Data Record" +msgstr "" + +#: lib/php/monica/list.inc.php:343 +msgid "Edit" +msgstr "" + +#: lib/php/monica/list.inc.php:345 +msgid "Manage Data" +msgstr "" + +#: lib/php/monica/list.inc.php:749 +msgid "Nothing found. Please try another query." +msgstr "" + +#: lib/php/monica/list.inc.php:752 +msgid "The database is empty." +msgstr "" + +#: lib/php/monica/list.inc.php:759 +#, c-format +msgid "Your query found %s record." +msgid_plural "Your query found %s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:766 +#, c-format +msgid "%s record." +msgid_plural "%s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:775 +#, c-format +msgid "Your query found %s record, listing %s to %s." +msgid_plural "Your query found %s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:784 +#, c-format +msgid "%s record, listing %s to %s." +msgid_plural "%s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:855 lib/php/monica/list.inc.php:860 +#: lib/php/monica/list.inc.php:869 +#, c-format +msgid "Page number (%s) invalid. Please specify a valid page number." +msgstr "" + +#: lib/php/monica/list.inc.php:874 +#, c-format +msgid "" +"Page number (%d) out of range. Please specify a number between 1 and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:1138 lib/php/monica/list.inc.php:1151 +#, c-format +msgid "You cannot sort by \"%s\"." +msgstr "" + +#: lib/php/monica/list.inc.php:1512 +msgid "Search" +msgstr "" + +#: lib/php/monica/list.inc.php:1610 +msgid "Index" +msgstr "" + +#: lib/php/monica/list.inc.php:1634 +msgid "First" +msgstr "" + +#: lib/php/monica/list.inc.php:1647 +msgid "Previous" +msgstr "" + +#: lib/php/monica/list.inc.php:1696 +msgid "Next" +msgstr "" + +#: lib/php/monica/list.inc.php:1714 +msgid "Last" +msgstr "" + +#: lib/php/monica/list.inc.php:1736 +msgid "Page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1776 lib/php/monica/list.inc.php:1900 +msgid "Delete the selected items." +msgstr "" + +#: lib/php/monica/list.inc.php:1805 +msgid "No." +msgstr "" + +#: lib/php/monica/list.inc.php:1813 lib/php/monica/list.inc.php:1873 +msgid "View" +msgstr "" + +#: lib/php/monica/list.inc.php:1925 +msgid "Set" +msgstr "" + +#: lib/php/monica/list.inc.php:1941 +msgid "Rows per page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1946 +msgid "Display columns:" +msgstr "" + +#: lib/php/monica/list.inc.php:1976 +msgid "Select a User" +msgstr "" + +#: lib/php/monica/list.inc.php:1977 +msgid "Manage Users" +msgstr "" + +#: lib/php/monica/list.inc.php:1982 +msgid "User ID." +msgstr "" + +#: lib/php/monica/list.inc.php:1983 +msgid "Full name" +msgstr "" + +#: lib/php/monica/list.inc.php:1984 +msgid "Deleted?" +msgstr "" + +#: lib/php/monica/list.inc.php:1985 +msgid "Pref. language" +msgstr "" + +#: lib/php/monica/list.inc.php:1986 +msgid "Visits" +msgstr "" + +#: lib/php/monica/list.inc.php:1987 +msgid "Visited" +msgstr "" + +#: lib/php/monica/list.inc.php:1988 +msgid "IP" +msgstr "" + +#: lib/php/monica/list.inc.php:1989 +msgid "Host" +msgstr "" + +#: lib/php/monica/list.inc.php:1990 +msgid "From country" +msgstr "" + +#: lib/php/monica/list.inc.php:1991 +msgid "Fail logins" +msgstr "" + +#: lib/php/monica/list.inc.php:2024 +msgid "Deleted" +msgstr "" + +#: lib/php/monica/list.inc.php:2035 +msgid "Add a new user account." +msgstr "" + +#: lib/php/monica/list.inc.php:2045 +msgid "Search for a user:" +msgstr "" + +#: lib/php/monica/list.inc.php:2063 +#, c-format +msgid "Your query found %s user." +msgid_plural "Your query found %s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2070 +#, c-format +msgid "%s user." +msgid_plural "%s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2079 +#, c-format +msgid "Your query found %s user, listing %s to %s." +msgid_plural "Your query found %s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2088 +#, c-format +msgid "%s user, listing %s to %s." +msgid_plural "%s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2107 +msgid "Select a Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2108 +msgid "Manage Groups" +msgstr "" + +#: lib/php/monica/list.inc.php:2113 +msgid "Group ID." +msgstr "" + +#: lib/php/monica/list.inc.php:2121 +msgid "Add a new group." +msgstr "" + +#: lib/php/monica/list.inc.php:2131 +msgid "Search for a group:" +msgstr "" + +#: lib/php/monica/list.inc.php:2149 +#, c-format +msgid "Your query found %s group." +msgid_plural "Your query found %s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2156 +#, c-format +msgid "%s group." +msgid_plural "%s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2165 +#, c-format +msgid "Your query found %s group, listing %s to %s." +msgid_plural "Your query found %s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2174 +#, c-format +msgid "%s group, listing %s to %s." +msgid_plural "%s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2194 +msgid "Select a User Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2195 +msgid "Manage User Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2200 lib/php/monica/list.inc.php:2323 +msgid "Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2201 lib/php/monica/list.inc.php:2324 +msgid "Member" +msgstr "" + +#: lib/php/monica/list.inc.php:2244 lib/php/monica/list.inc.php:2375 +msgid "Add a new membership record." +msgstr "" + +#: lib/php/monica/list.inc.php:2254 lib/php/monica/list.inc.php:2385 +msgid "Search for a membership record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2272 lib/php/monica/list.inc.php:2403 +#, c-format +msgid "Your query found %s membership record." +msgid_plural "Your query found %s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2279 lib/php/monica/list.inc.php:2410 +#, c-format +msgid "%s membership record." +msgid_plural "%s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2288 lib/php/monica/list.inc.php:2419 +#, c-format +msgid "Your query found %s membership record, listing %s to %s." +msgid_plural "Your query found %s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2297 lib/php/monica/list.inc.php:2428 +#, c-format +msgid "%s membership record, listing %s to %s." +msgid_plural "%s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2317 +msgid "Select a Group Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2318 +msgid "Manage Group Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2448 +msgid "Select a Script Privilege Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2449 +msgid "Manage Script Privileges" +msgstr "" + +#: lib/php/monica/list.inc.php:2454 +msgid "Script" +msgstr "" + +#: lib/php/monica/list.inc.php:2455 +msgid "Privilege" +msgstr "" + +#: lib/php/monica/list.inc.php:2493 +msgid "Add a new script privilege record." +msgstr "" + +#: lib/php/monica/list.inc.php:2503 +msgid "Search for a script privilege record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2521 +#, c-format +msgid "Your query found %s script privilege record." +msgid_plural "Your query found %s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2528 +#, c-format +msgid "%s script privilege record." +msgid_plural "%s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2537 +#, c-format +msgid "Your query found %s script privilege record, listing %s to %s." +msgid_plural "Your query found %s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2546 +#, c-format +msgid "%s script privilege record, listing %s to %s." +msgid_plural "%s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2566 +msgid "Select a User Preference" +msgstr "" + +#: lib/php/monica/list.inc.php:2567 +msgid "Manage User Preferences" +msgstr "" + +#: lib/php/monica/list.inc.php:2574 lib/php/monica/list.inc.php:2689 +msgid "User" +msgstr "" + +#: lib/php/monica/list.inc.php:2575 +msgid "Domain" +msgstr "" + +#: lib/php/monica/list.inc.php:2576 +msgid "Value" +msgstr "" + +#: lib/php/monica/list.inc.php:2610 +msgid "Add a new user preference." +msgstr "" + +#: lib/php/monica/list.inc.php:2620 +msgid "Search for a user preference:" +msgstr "" + +#: lib/php/monica/list.inc.php:2638 +#, c-format +msgid "Your query found %s user preference." +msgid_plural "Your query found %s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2645 +#, c-format +msgid "%s user preference." +msgid_plural "%s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2654 +#, c-format +msgid "Your query found %s user preference, listing %s to %s." +msgid_plural "Your query found %s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2663 +#, c-format +msgid "%s user preference, listing %s to %s." +msgid_plural "%s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2682 +msgid "Select a User Request" +msgstr "" + +#: lib/php/monica/list.inc.php:2683 +msgid "Manage User Requests" +msgstr "" + +#: lib/php/monica/list.inc.php:2688 +msgid "Type" +msgstr "" + +#: lib/php/monica/list.inc.php:2690 +msgid "Arguments" +msgstr "" + +#: lib/php/monica/list.inc.php:2691 +msgid "Expiration" +msgstr "" + +#: lib/php/monica/list.inc.php:2699 +msgid "Add a new user request." +msgstr "" + +#: lib/php/monica/list.inc.php:2709 +msgid "Search for a user request:" +msgstr "" + +#: lib/php/monica/list.inc.php:2727 +#, c-format +msgid "Your query found %s user request." +msgid_plural "Your query found %s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2734 +#, c-format +msgid "%s user request." +msgid_plural "%s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2743 +#, c-format +msgid "Your query found %s user request, listing %s to %s." +msgid_plural "Your query found %s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2752 +#, c-format +msgid "%s user request, listing %s to %s." +msgid_plural "%s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2778 +msgid "Add a new category." +msgstr "" + +#: lib/php/monica/list.inc.php:2788 +msgid "Search for a category:" +msgstr "" + +#: lib/php/monica/list.inc.php:2806 +#, c-format +msgid "Your query found %s category." +msgid_plural "Your query found %s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2813 +#, c-format +msgid "%s category." +msgid_plural "%s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2822 +#, c-format +msgid "Your query found %s category, listing %s to %s." +msgid_plural "Your query found %s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2831 +#, c-format +msgid "%s category, listing %s to %s." +msgid_plural "%s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2849 +msgid "Add a new categorization record." +msgstr "" + +#: lib/php/monica/list.inc.php:2859 +msgid "Search for a categorization record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2877 +#, c-format +msgid "Your query found %s categorization record." +msgid_plural "Your query found %s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2884 +#, c-format +msgid "%s categorization record." +msgid_plural "%s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2893 +#, c-format +msgid "Your query found %s categorization record, listing %s to %s." +msgid_plural "Your query found %s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2902 +#, c-format +msgid "%s categorization record, listing %s to %s." +msgid_plural "%s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2921 +msgid "Select a Page" +msgstr "" + +#: lib/php/monica/list.inc.php:2922 +msgid "Manage Pages" +msgstr "" + +#: lib/php/monica/list.inc.php:2952 lib/php/monica/list.inc.php:3066 +#: lib/php/monica/list.inc.php:3173 lib/php/monica/list.inc.php:3237 +#: lib/php/monica/list.inc.php:3358 +msgid "Hidden" +msgstr "" + +#: lib/php/monica/list.inc.php:2953 lib/php/monica/list.inc.php:3067 +#: lib/php/monica/list.inc.php:3174 lib/php/monica/list.inc.php:3238 +#: lib/php/monica/list.inc.php:3359 +msgid "Shown" +msgstr "" + +#: lib/php/monica/list.inc.php:2963 +msgid "Write a new page." +msgstr "" + +#: lib/php/monica/list.inc.php:2973 +msgid "Search for a page:" +msgstr "" + +#: lib/php/monica/list.inc.php:2991 +#, c-format +msgid "Your query found %s page." +msgid_plural "Your query found %s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2998 +#, c-format +msgid "%s page." +msgid_plural "%s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3007 +#, c-format +msgid "Your query found %s page, listing %s to %s." +msgid_plural "Your query found %s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3016 +#, c-format +msgid "%s page, listing %s to %s." +msgid_plural "%s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3035 +msgid "Select a News Article" +msgstr "" + +#: lib/php/monica/list.inc.php:3036 +msgid "Manage News" +msgstr "" + +#: lib/php/monica/list.inc.php:3077 +msgid "Write a new news article." +msgstr "" + +#: lib/php/monica/list.inc.php:3087 +msgid "Search for a news article:" +msgstr "" + +#: lib/php/monica/list.inc.php:3105 +#, c-format +msgid "Your query found %s news article." +msgid_plural "Your query found %s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3112 +#, c-format +msgid "%s news article." +msgid_plural "%s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3121 +#, c-format +msgid "Your query found %s news article, listing %s to %s." +msgid_plural "Your query found %s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3130 +#, c-format +msgid "%s news article, listing %s to %s." +msgid_plural "%s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3149 +msgid "Select a Link Category" +msgstr "" + +#: lib/php/monica/list.inc.php:3150 +msgid "Manage Link Categories" +msgstr "" + +#: lib/php/monica/list.inc.php:3197 +msgid "Select a Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3198 +msgid "Manage Links" +msgstr "" + +#: lib/php/monica/list.inc.php:3248 +msgid "Add a new related link." +msgstr "" + +#: lib/php/monica/list.inc.php:3258 +msgid "Search for a related link:" +msgstr "" + +#: lib/php/monica/list.inc.php:3276 +#, c-format +msgid "Your query found %s related link." +msgid_plural "Your query found %s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3283 +#, c-format +msgid "%s related link." +msgid_plural "%s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3292 +#, c-format +msgid "Your query found %s related link, listing %s to %s." +msgid_plural "Your query found %s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3301 +#, c-format +msgid "%s related link, listing %s to %s." +msgid_plural "%s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3321 +msgid "Select a Link Categorization Record" +msgstr "" + +#: lib/php/monica/list.inc.php:3322 +msgid "Manage Link Categorization" +msgstr "" + +#: lib/php/monica/list.inc.php:3327 +msgid "Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3383 +msgid "Select a Country" +msgstr "" + +#: lib/php/monica/list.inc.php:3384 +msgid "Manage Country Data" +msgstr "" + +#: lib/php/monica/list.inc.php:3389 +msgid "Code" +msgstr "" + +#: lib/php/monica/list.inc.php:3390 +msgid "Country name" +msgstr "" + +#: lib/php/monica/list.inc.php:3399 +msgid "Add a new country record." +msgstr "" + +#: lib/php/monica/list.inc.php:3409 +msgid "Search for a country:" +msgstr "" + +#: lib/php/monica/list.inc.php:3427 +#, c-format +msgid "Your query found %s country." +msgid_plural "Your query found %s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3434 +#, c-format +msgid "%s country." +msgid_plural "%s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3443 +#, c-format +msgid "Your query found %s country, listing %s to %s." +msgid_plural "Your query found %s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3452 +#, c-format +msgid "%s country, listing %s to %s." +msgid_plural "%s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3474 +msgid "Browse the Activity Log" +msgstr "" + +#: lib/php/monica/list.inc.php:3586 +msgid "Please fill in the number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3590 +#, c-format +msgid "This number of rows to display is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/list.inc.php:3595 +msgid "Please fill in a positive integer number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3599 lib/php/monica/list.inc.php:3609 +#, c-format +msgid "" +"The number of rows to display is too small. Please fill in a larger number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3613 +#, c-format +msgid "" +"The number of rows to display is too large. Please fill in a smaller number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3638 +msgid "Search for log entries:" +msgstr "" + +#: lib/php/monica/list.inc.php:3641 +msgid "Display" +msgstr "" + +#: lib/php/monica/list.inc.php:3654 +msgid "Display rows:" +msgstr "" + +#: lib/php/monica/list.inc.php:3677 +#, c-format +msgid "Your query found %s log entry." +msgid_plural "Your query found %s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3684 +#, c-format +msgid "%s log entry." +msgid_plural "%s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3693 +#, c-format +msgid "Your query found %s log entry, listing %s to %s." +msgid_plural "Your query found %s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3702 +#, c-format +msgid "%s log entry, listing %s to %s." +msgid_plural "%s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/lninfo.inc.php:28 +msgid "English" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:39 +msgid "Traditional Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:50 +msgid "Simplified Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:61 +msgid "Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:72 +msgid "Japanese" +msgstr "日本語" + +#: lib/php/monica/lninfo.inc.php:83 +msgid "Korean" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:94 +msgid "German" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:105 +msgid "Spanish" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:366 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:738 +msgid "Web pages" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:739 +msgid "News" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:740 +msgid "Related links" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:741 +msgid "Home page" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:742 +msgid "Whole web site" +msgstr "" + +#: lib/php/monica/pic.inc.php:39 +msgid "Left-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:40 +msgid "Right-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:74 lib/php/monica/pic.inc.php:77 +#, c-format +msgid "This picture file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/pic.inc.php:92 +msgid "Please upload only PNG, JPEG or GIF files." +msgstr "" + +#: lib/php/monica/pic.inc.php:153 +#, c-format +msgid "Width: %d, height: %d, ratio: %0.2f" +msgstr "" + +#: lib/php/monica/pic.inc.php:176 +msgid "Please specify a numeric ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:180 +msgid "Please specify a positive ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:183 +#, c-format +msgid "Please specify a ratio less than or equal to %0.2f." +msgstr "" + +#: lib/php/monica/pic.inc.php:189 +msgid "This image is too large to display." +msgstr "" + +#: lib/php/monica/preview.inc.php:47 +#, c-format +msgid "Unknown preview source: \"%s\"." +msgstr "" + +#: lib/php/monica/preview.inc.php:67 +#, c-format +msgid "Unknown preview form: %d." +msgstr "" + +#: lib/php/monica/preview.inc.php:143 +msgid "Preview Mark Area" +msgstr "" + +#: lib/php/monica/preview.inc.php:148 +msgid "Finish preview and return." +msgstr "" + +#: lib/php/monica/process.inc.php:237 +msgid "This record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:243 +msgid "This record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:247 +msgid "This record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:251 +msgid "This record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:406 +msgid "This category was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:412 +msgid "This category has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:416 +msgid "This category has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:420 +msgid "This category has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:433 +msgid "This categorization record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:439 +msgid "This categorization record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:443 +msgid "This categorization record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:447 +msgid "This categorization record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:782 +msgid "This user account was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:788 +msgid "This user account has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:792 +msgid "This user account has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:796 +msgid "This user account has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1074 +msgid "This group was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1080 +msgid "This group has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1084 +msgid "This group has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1088 +msgid "This group has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1152 lib/php/monica/process.inc.php:1230 +msgid "This membership record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1158 lib/php/monica/process.inc.php:1236 +msgid "This membership record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1162 lib/php/monica/process.inc.php:1240 +msgid "This membership record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1166 lib/php/monica/process.inc.php:1244 +msgid "This membership record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1308 +msgid "This script privilege record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1314 +msgid "This script privilege record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1318 +msgid "This script privilege record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1322 +msgid "This script privilege record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1438 +msgid "This user preference was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1444 +msgid "This user preference has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1448 +msgid "This user preference has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1452 +msgid "This user preference has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1560 +msgid "This user request was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1566 +msgid "This user request has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1570 +msgid "This user request has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1574 +msgid "This user request has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1685 +msgid "This page was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1691 +msgid "This page has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1695 +msgid "This page has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1699 +msgid "This page has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1874 +msgid "This news article was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1880 +msgid "This news article has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1884 +msgid "This news article has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1888 +msgid "This news article has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1997 +msgid "This country was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2003 +msgid "This country has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2007 +msgid "This country has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2011 +msgid "This country has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:2097 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. (%0.3f seconds)" +msgstr "" + +#: lib/php/monica/process.inc.php:2158 +#, c-format +msgid "Welcome, %s!" +msgstr "" + +#: lib/php/monica/process.inc.php:2204 +msgid "You have successfully logged out." +msgstr "" + +#: lib/php/monica/process.inc.php:2439 +msgid "This related link was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2445 +msgid "This related link has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2449 +msgid "This related link has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2453 +msgid "This related link has been successfully deleted." +msgstr "" + +#: lib/php/monica/request.inc.php:38 +msgid "Please specify the request." +msgstr "" + +#: lib/php/monica/request.inc.php:46 lib/php/monica/request.inc.php:55 +#, c-format +msgid "Invalid request S/N: %s." +msgstr "" + +#: lib/php/monica/sitesize.inc.php:41 +#, c-format +msgid "Currently using files %s.\n" +msgstr "" + +#: lib/php/monica/sitesize.inc.php:46 +#, c-format +msgid "Currently using files %s, database %s, total %s.\n" +msgstr "" + +#: lib/php/monica/upload.inc.php:70 +#, c-format +msgid "MIME file type: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:71 +#, c-format +msgid "File name: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:72 +#, c-format +msgid "File size: %s bytes" +msgstr "" + +#: lib/php/monica/validate.inc.php:116 +msgid "HTML Validatior Logo Area" +msgstr "" + +#: lib/php/monica/validate.inc.php:117 +msgid "HTML validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:118 +#, c-format +msgid "Valid %s!" +msgstr "" + +#: lib/php/monica/validate.inc.php:119 +msgid "CSS validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:120 +msgid "Valid CSS!" +msgstr "" + +#: lib/php/monica/validate.inc.php:121 +msgid "Explanation of Level Triple-A Conformance" +msgstr "" + +#: lib/php/monica/validate.inc.php:122 +msgid "" +"Level Triple-A conformance icon, W3C-WAI Web Content Accessibility " +"Guidelines 1.0" +msgstr "" diff --git a/po/monica/ja_JP.pox b/po/monica/ja_JP.pox new file mode 100644 index 0000000..cb0fc28 --- /dev/null +++ b/po/monica/ja_JP.pox @@ -0,0 +1,3296 @@ +# Japanese PO file for the monica core +# Copyright (C) 2007-2018 Pristine Communcations +# This file is distributed under the same license as the monica package. +# imacat , 2007-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: monica 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 12:42+0800\n" +"PO-Revision-Date: 2018-11-02 01:22+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Japanese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: lib/php/monica/checker.inc.php:159 +msgid "Please select a user." +msgstr "" + +#: lib/php/monica/checker.inc.php:163 +msgid "This user does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:181 +msgid "Please select a group." +msgstr "" + +#: lib/php/monica/checker.inc.php:185 +msgid "This group does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:203 +msgid "Please fill in the script." +msgstr "" + +#: lib/php/monica/checker.inc.php:207 +#, c-format +msgid "This script is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:212 +msgid "This script is not a valid script. Please specify another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:230 +msgid "Please fill in the date." +msgstr "" + +#: lib/php/monica/checker.inc.php:234 lib/php/monica/checker.inc.php:238 +#: lib/php/monica/checker.inc.php:241 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "" + +#: lib/php/monica/checker.inc.php:259 +msgid "Please fill in the ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:263 +#, c-format +msgid "This ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:267 +#, c-format +msgid "This ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:272 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:294 +msgid "Please fill in the order." +msgstr "" + +#: lib/php/monica/checker.inc.php:298 +#, c-format +msgid "This order is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:303 +msgid "Please fill in a positive integer order." +msgstr "" + +#: lib/php/monica/checker.inc.php:307 lib/php/monica/checker.inc.php:317 +#, c-format +msgid "" +"The order is too small. Please fill in a larger order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:321 +#, c-format +msgid "" +"The order is too large. Please fill in a smaller order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:348 +msgid "Please fill in the page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:352 +#, c-format +msgid "This page path is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:365 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:369 +msgid "Please fill in an absolute page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:373 +msgid "Please fill in a valid page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:377 +msgid "You cannot overwrite the cover home page." +msgstr "" + +#: lib/php/monica/checker.inc.php:381 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "" + +#: lib/php/monica/checker.inc.php:422 lib/php/monica/checker.inc.php:428 +msgid "Please fill in the attachment description." +msgstr "" + +#: lib/php/monica/checker.inc.php:432 +#, c-format +msgid "This attachment description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:449 +msgid "This PDF. file does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:456 +#, c-format +msgid "This PDF. file is too large. (Max. size %s)" +msgstr "" + +#: lib/php/monica/checker.inc.php:461 +msgid "Please upload only PDF. file." +msgstr "" + +#: lib/php/monica/checker.inc.php:479 +msgid "Please fill in the title." +msgstr "" + +#: lib/php/monica/checker.inc.php:483 +#, c-format +msgid "This title is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:502 +msgid "Please fill in the subject." +msgstr "" + +#: lib/php/monica/checker.inc.php:506 +#, c-format +msgid "This subject is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:524 lib/php/monica/form.inc.php:3159 +#: lib/php/monica/form.inc.php:3172 +msgid "Fill in the content here." +msgstr "" + +#: lib/php/monica/checker.inc.php:528 +msgid "Please fill in the content." +msgstr "" + +#: lib/php/monica/checker.inc.php:532 +#, c-format +msgid "This content is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:551 +msgid "Please fill in the keywords." +msgstr "" + +#: lib/php/monica/checker.inc.php:555 +#, c-format +msgid "This keyword list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:572 +msgid "Please select a proper pinyin." +msgstr "" + +#: lib/php/monica/checker.inc.php:578 +#, c-format +msgid "This pinyin is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:583 +msgid "" +"This pinyin does not match the Chinese. Please select a proper pinyin from " +"the list." +msgstr "" + +#: lib/php/monica/checker.inc.php:609 lib/php/monica/pic.inc.php:82 +msgid "Please upload the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:616 lib/php/monica/checker.inc.php:3214 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:622 +#, c-format +msgid "This picture is too large. Please upload another one. (Max. size %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:639 lib/php/monica/form.inc.php:3588 +#, c-format +msgid "Please upload a new picture from %s." +msgstr "" + +#: lib/php/monica/checker.inc.php:664 lib/php/monica/checker.inc.php:727 +msgid "Please fill in the picture caption." +msgstr "" + +#: lib/php/monica/checker.inc.php:668 lib/php/monica/checker.inc.php:731 +#, c-format +msgid "This picture caption is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:686 lib/php/monica/checker.inc.php:749 +msgid "Please select the picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:692 lib/php/monica/checker.inc.php:755 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:791 lib/php/monica/checker.inc.php:794 +#, c-format +msgid "Your uploaded file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/checker.inc.php:797 lib/php/monica/pic.inc.php:80 +msgid "" +"Upload not completed. Disk may be full or connection may be closed in the " +"half. You may try to upload again, or contact the system administrator for " +"this problem." +msgstr "" + +#: lib/php/monica/checker.inc.php:799 lib/php/monica/pic.inc.php:84 +#, c-format +msgid "Upload failed with an unknown error (%d)." +msgstr "" + +#: lib/php/monica/checker.inc.php:1183 lib/php/monica/chkfunc.inc.php:59 +#: lib/php/monica/chkfunc.inc.php:72 lib/php/monica/preview.inc.php:29 +#, c-format +msgid "The following field was not received: \"%s\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:1262 +msgid "Please fill in the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1266 +#, c-format +msgid "This user ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1270 +#, c-format +msgid "This user ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1275 +msgid "" +"Only lower-case English letters, numbers, at-signs, dots, dashes and " +"underscores are allowed for the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1287 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1317 +msgid "Please fill in the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1320 +msgid "Please confirm the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1324 +#, c-format +msgid "This password is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1329 +#, c-format +msgid "This password is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1334 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "" + +#: lib/php/monica/checker.inc.php:1345 +msgid "This password is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1360 +msgid "This password does not contain enough different characters." +msgstr "" + +#: lib/php/monica/checker.inc.php:1364 +msgid "This password is too simplistic/systematic." +msgstr "" + +#: lib/php/monica/checker.inc.php:1368 +msgid "This password is based on a dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1370 +msgid "This password is based on a (reversed) dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1372 +msgid "This password is too simple." +msgstr "" + +#: lib/php/monica/checker.inc.php:1378 +msgid "You cannot use a password that is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1397 +msgid "Please fill in the name." +msgstr "" + +#: lib/php/monica/checker.inc.php:1401 +#, c-format +msgid "This name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1420 +msgid "Please fill in the e-mail." +msgstr "" + +#: lib/php/monica/checker.inc.php:1424 +#, c-format +msgid "This e-mail is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1428 +#, c-format +msgid "This e-mail is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1437 +msgid "Please fill in a valid e-mail address." +msgstr "" + +#: lib/php/monica/checker.inc.php:1439 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:1461 lib/php/monica/checker.inc.php:1655 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1478 +msgid "You cannot submit the super-user group along with other groups." +msgstr "" + +#: lib/php/monica/checker.inc.php:1480 +msgid "You cannot set the administrators group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1482 +msgid "You cannot set the all-users group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1515 +msgid "Please fill in the group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1519 +#, c-format +msgid "This group ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1523 +#, c-format +msgid "This group ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1528 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1540 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1558 +msgid "Please fill in the privilege description." +msgstr "" + +#: lib/php/monica/checker.inc.php:1562 +#, c-format +msgid "This privilege description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1585 +msgid "This user member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1620 +msgid "This group member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1747 lib/php/monica/checker.inc.php:1855 +msgid "Please select a member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1751 lib/php/monica/checker.inc.php:1859 +msgid "This member does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1770 lib/php/monica/checker.inc.php:1883 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1837 +msgid "Please select a different belonging group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1864 +msgid "Please select a different group member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1958 +msgid "" +"This script privilege already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1996 lib/php/monica/checker.inc.php:2184 +msgid "Please select the user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2002 lib/php/monica/checker.inc.php:2190 +msgid "This option is invalid. Please select a proper user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2020 +msgid "Please set the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2026 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2039 lib/php/monica/checker.inc.php:2295 +msgid "Please fill in the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2043 lib/php/monica/checker.inc.php:2299 +#, c-format +msgid "This preference domain is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2063 +msgid "Please fill in the preference name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2067 +#, c-format +msgid "This preference name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2086 +msgid "Please fill in the preference value." +msgstr "" + +#: lib/php/monica/checker.inc.php:2090 +#, c-format +msgid "This preference value is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2119 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2167 +msgid "Please select the request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2173 +msgid "This option is invalid. Please select a proper request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2194 +msgid "You must choose anonymous for join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2197 +msgid "You cannot choose anonymous for non-join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2221 lib/php/monica/form.inc.php:5484 +msgid "Please fill in the request arguments list here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2229 +#, c-format +msgid "This request arguments list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2349 +msgid "Please fill in the number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2353 +#, c-format +msgid "This number of rows per page is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2358 +msgid "Please fill in a positive integer number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2362 lib/php/monica/checker.inc.php:2372 +#, c-format +msgid "" +"The number of rows per page is too small. Please fill in a larger number of " +"rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2376 +#, c-format +msgid "" +"The number of rows per page is too large. Please fill in a smaller number " +"of rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2443 +msgid "Please fill in your user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:2451 lib/php/monica/checker.inc.php:2458 +#: lib/php/monica/checker.inc.php:2475 lib/php/monica/checker.inc.php:2508 +#: lib/php/monica/checker.inc.php:2540 lib/php/monica/checker.inc.php:2548 +#: lib/php/monica/checker.inc.php:2558 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "" + +#: lib/php/monica/checker.inc.php:2495 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "" + +#: lib/php/monica/checker.inc.php:2531 +msgid "Please fill in your password." +msgstr "" + +#: lib/php/monica/checker.inc.php:2581 +msgid "You are not an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2600 +msgid "You are an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2751 +msgid "Please fill in the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2755 +#, c-format +msgid "You must fill in a %d-letters code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2760 +msgid "You can only use upper letters and for the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2772 +msgid "This code is duplicated. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2790 +msgid "Please fill in the country name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2794 +#, c-format +msgid "This country name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2822 lib/php/monica/checker.inc.php:2841 +msgid "Please select a parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2828 +msgid "This option is invalid. Please select a proper parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2845 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2850 +msgid "A category cannot belong to itself. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2858 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2876 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:2894 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2941 +msgid "Please fill in the URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2945 +#, c-format +msgid "This URL. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2950 +msgid "Please fill in a valid URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2962 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2967 +msgid "This URL. is not reachable. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:2984 lib/php/monica/form.inc.php:3261 +msgid "Fill in the description here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2988 +msgid "Please fill in the description." +msgstr "" + +#: lib/php/monica/checker.inc.php:2992 +#, c-format +msgid "This description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:3012 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:3016 lib/php/monica/checker.inc.php:3072 +msgid "This category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3022 lib/php/monica/checker.inc.php:3068 +msgid "Please select a category." +msgstr "" + +#: lib/php/monica/checker.inc.php:3090 +msgid "Please select a related link." +msgstr "" + +#: lib/php/monica/checker.inc.php:3094 +msgid "This link does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3113 +msgid "" +"This link categorization already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3154 +msgid "Please select the type." +msgstr "" + +#: lib/php/monica/checker.inc.php:3158 +msgid "This type does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3185 lib/php/monica/list.inc.php:961 +msgid "Please fill in your query." +msgstr "" + +#: lib/php/monica/checker.inc.php:3210 +msgid "Please submit the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:3237 lib/php/monica/checker.inc.php:3328 +msgid "Please fill in the resize ratio." +msgstr "" + +#: lib/php/monica/checker.inc.php:3305 +msgid "Please specify a valid picture." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:156 lib/php/monica/chkfunc.inc.php:160 +#: lib/php/monica/chkfunc.inc.php:163 lib/php/monica/chkfunc.inc.php:166 +msgid "Please select a legal year." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:171 lib/php/monica/chkfunc.inc.php:175 +#: lib/php/monica/chkfunc.inc.php:178 +msgid "Please select a legal month." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:183 lib/php/monica/chkfunc.inc.php:187 +#: lib/php/monica/chkfunc.inc.php:193 +msgid "Please select a legal day." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:27 +#, c-format +msgid "%s: It is not a file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:32 +#, c-format +msgid "%s: You have no permission to overwrite this file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:45 +#, c-format +msgid "%s: You cannot create anything under the root directory." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:50 +#, c-format +msgid "" +"%s: One of the parents of this file (%s) is not a directory. You cannot " +"create any new file inside." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:55 +#, c-format +msgid "%s: You have no permission to create any file under %s." +msgstr "" + +#: lib/php/monica/commtext.inc.php:18 +msgid "(not set)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:24 +msgid "(none)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:30 +msgid "(N/A)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:36 +msgid "(blank)" +msgstr "" + +#: lib/php/monica/echoform.inc.php:173 +#, c-format +msgid "%s bytes" +msgstr "" + +#: lib/php/monica/form.inc.php:168 +msgid "Delete it" +msgstr "" + +#: lib/php/monica/form.inc.php:174 +msgid "Are you sure you want to delete it? It cannot be recovered." +msgstr "" + +#: lib/php/monica/form.inc.php:188 +msgid "*" +msgstr "" + +#: lib/php/monica/form.inc.php:224 +msgid "This table provides you a form to add a new data record." +msgstr "" + +#: lib/php/monica/form.inc.php:228 +msgid "This table provides you a form to update a current data record." +msgstr "" + +#: lib/php/monica/form.inc.php:232 +msgid "This table provides you a form to delete a data record." +msgstr "" + +#: lib/php/monica/form.inc.php:281 +msgid "Add a New Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:285 +msgid "Update a Current Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:289 +msgid "Delete a Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:301 +msgid "Preview it." +msgstr "" + +#: lib/php/monica/form.inc.php:500 lib/php/monica/form.inc.php:506 +#: lib/php/monica/form.inc.php:691 lib/php/monica/form.inc.php:697 +#: lib/php/monica/preview.inc.php:146 +msgid "Preview" +msgstr "" + +#: lib/php/monica/form.inc.php:501 lib/php/monica/form.inc.php:507 +#: lib/php/monica/form.inc.php:692 lib/php/monica/form.inc.php:698 +msgid "Confirm and submit" +msgstr "" + +#: lib/php/monica/form.inc.php:708 lib/php/monica/form.inc.php:1692 +#: lib/php/monica/form.inc.php:1778 lib/php/monica/list.inc.php:1809 +msgid "Delete" +msgstr "" + +#: lib/php/monica/form.inc.php:709 lib/php/monica/form.inc.php:6419 +#: lib/php/monica/form.inc.php:6470 +msgid "Cancel" +msgstr "" + +#: lib/php/monica/form.inc.php:1042 lib/php/monica/form.inc.php:3499 +msgid "Set the picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1043 lib/php/monica/form.inc.php:3031 +#: lib/php/monica/form.inc.php:3500 +msgid "Delete this picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1048 lib/php/monica/form.inc.php:1178 +#: lib/php/monica/form.inc.php:3037 lib/php/monica/form.inc.php:3104 +#: lib/php/monica/form.inc.php:3505 lib/php/monica/form.inc.php:3677 +#: lib/php/monica/form.inc.php:6163 lib/php/monica/list.inc.php:814 +msgid "Picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1059 lib/php/monica/form.inc.php:1109 +#: lib/php/monica/form.inc.php:1185 +#, c-format +msgid "Picture #%d:" +msgstr "" + +#: lib/php/monica/form.inc.php:1080 lib/php/monica/form.inc.php:1131 +#: lib/php/monica/form.inc.php:1166 lib/php/monica/form.inc.php:1199 +msgid "Caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:1092 lib/php/monica/form.inc.php:3064 +#: lib/php/monica/form.inc.php:3566 lib/php/monica/form.inc.php:6183 +msgid "Original picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1093 lib/php/monica/form.inc.php:3065 +#: lib/php/monica/form.inc.php:3567 lib/php/monica/form.inc.php:6197 +msgid "New picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1113 lib/php/monica/form.inc.php:1276 +#: lib/php/monica/form.inc.php:1363 lib/php/monica/form.inc.php:1451 +#: lib/php/monica/form.inc.php:1560 lib/php/monica/form.inc.php:1650 +#: lib/php/monica/form.inc.php:1727 lib/php/monica/form.inc.php:1825 +#: lib/php/monica/form.inc.php:1916 lib/php/monica/form.inc.php:1977 +#: lib/php/monica/form.inc.php:2053 lib/php/monica/form.inc.php:2159 +#: lib/php/monica/form.inc.php:2391 lib/php/monica/form.inc.php:2592 +#: lib/php/monica/form.inc.php:2689 lib/php/monica/form.inc.php:2800 +#: lib/php/monica/form.inc.php:2897 lib/php/monica/form.inc.php:2980 +#: lib/php/monica/form.inc.php:3069 lib/php/monica/form.inc.php:3200 +#: lib/php/monica/form.inc.php:3571 lib/php/monica/form.inc.php:3627 +#: lib/php/monica/form.inc.php:3640 lib/php/monica/form.inc.php:3747 +#: lib/php/monica/form.inc.php:4423 lib/php/monica/form.inc.php:4533 +#: lib/php/monica/form.inc.php:4729 lib/php/monica/form.inc.php:4866 +#: lib/php/monica/form.inc.php:5000 lib/php/monica/form.inc.php:6176 +#: lib/php/monica/form.inc.php:6243 +msgid "Original:" +msgstr "" + +#: lib/php/monica/form.inc.php:1141 lib/php/monica/form.inc.php:1281 +#: lib/php/monica/form.inc.php:1369 lib/php/monica/form.inc.php:1456 +#: lib/php/monica/form.inc.php:1575 lib/php/monica/form.inc.php:1655 +#: lib/php/monica/form.inc.php:1732 lib/php/monica/form.inc.php:1832 +#: lib/php/monica/form.inc.php:1921 lib/php/monica/form.inc.php:1982 +#: lib/php/monica/form.inc.php:2065 lib/php/monica/form.inc.php:2173 +#: lib/php/monica/form.inc.php:2422 lib/php/monica/form.inc.php:2597 +#: lib/php/monica/form.inc.php:2694 lib/php/monica/form.inc.php:2805 +#: lib/php/monica/form.inc.php:2902 lib/php/monica/form.inc.php:2985 +#: lib/php/monica/form.inc.php:3080 lib/php/monica/form.inc.php:3205 +#: lib/php/monica/form.inc.php:3584 lib/php/monica/form.inc.php:3632 +#: lib/php/monica/form.inc.php:3649 lib/php/monica/form.inc.php:3752 +#: lib/php/monica/form.inc.php:4442 lib/php/monica/form.inc.php:4543 +#: lib/php/monica/form.inc.php:4742 lib/php/monica/form.inc.php:4879 +#: lib/php/monica/form.inc.php:5013 lib/php/monica/form.inc.php:6188 +#: lib/php/monica/form.inc.php:6248 lib/php/monica/form.inc.php:6278 +msgid "New:" +msgstr "" + +#: lib/php/monica/form.inc.php:1269 lib/php/monica/form.inc.php:1444 +#: lib/php/monica/form.inc.php:1543 lib/php/monica/form.inc.php:2358 +#: lib/php/monica/form.inc.php:2585 lib/php/monica/form.inc.php:2793 +#: lib/php/monica/form.inc.php:2890 lib/php/monica/form.inc.php:2973 +#: lib/php/monica/form.inc.php:3620 +msgid "Source:" +msgstr "" + +#: lib/php/monica/form.inc.php:1289 lib/php/monica/form.inc.php:1464 +#: lib/php/monica/form.inc.php:1583 lib/php/monica/form.inc.php:2605 +#: lib/php/monica/form.inc.php:2813 lib/php/monica/form.inc.php:2910 +#: lib/php/monica/form.inc.php:2993 +#, c-format +msgid "Please set it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:1501 +msgid "Hide" +msgstr "" + +#: lib/php/monica/form.inc.php:1502 +msgid "Show" +msgstr "" + +#: lib/php/monica/form.inc.php:1691 lib/php/monica/form.inc.php:1777 +#: lib/php/monica/form.inc.php:1887 +msgid "Choose" +msgstr "" + +#: lib/php/monica/form.inc.php:2237 +msgid "Delete this file" +msgstr "" + +#: lib/php/monica/form.inc.php:2267 lib/php/monica/form.inc.php:2368 +#: lib/php/monica/form.inc.php:2400 lib/php/monica/form.inc.php:2445 +#: lib/php/monica/form.inc.php:2506 +msgid "File name:" +msgstr "" + +#: lib/php/monica/form.inc.php:2274 lib/php/monica/form.inc.php:2375 +#: lib/php/monica/form.inc.php:2407 lib/php/monica/form.inc.php:2452 +#: lib/php/monica/form.inc.php:2513 +msgid "MIME file type:" +msgstr "" + +#: lib/php/monica/form.inc.php:2279 lib/php/monica/form.inc.php:2380 +#: lib/php/monica/form.inc.php:2412 lib/php/monica/form.inc.php:2457 +#: lib/php/monica/form.inc.php:2518 +msgid "File size:" +msgstr "" + +#: lib/php/monica/form.inc.php:2430 +#, c-format +msgid "Please upload it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:3128 +msgid "Address:" +msgstr "" + +#: lib/php/monica/form.inc.php:3129 +msgid "Fill in your address here." +msgstr "" + +#: lib/php/monica/form.inc.php:3135 +msgid "Attachment:" +msgstr "" + +#: lib/php/monica/form.inc.php:3139 +msgid "Attachment description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3158 lib/php/monica/form.inc.php:3171 +msgid "Content:" +msgstr "" + +#: lib/php/monica/form.inc.php:3165 +msgid "City:" +msgstr "" + +#: lib/php/monica/form.inc.php:3187 lib/php/monica/form.inc.php:3199 +#: lib/php/monica/form.inc.php:3217 lib/php/monica/form.inc.php:3241 +msgid "Country:" +msgstr "" + +#: lib/php/monica/form.inc.php:3229 +msgid "Created:" +msgstr "" + +#: lib/php/monica/form.inc.php:3235 +msgid "Created by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3247 +msgid "Date:" +msgstr "" + +#: lib/php/monica/form.inc.php:3253 lib/php/monica/form.inc.php:4292 +#: lib/php/monica/form.inc.php:4295 lib/php/monica/list.inc.php:310 +msgid "Disabled?" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 lib/php/monica/list.inc.php:2020 +msgid "Disabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 +msgid "Enabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 +msgid "Disable it." +msgstr "" + +#: lib/php/monica/form.inc.php:3260 lib/php/monica/form.inc.php:4657 +msgid "Description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3267 +msgid "E-mail:" +msgstr "" + +#: lib/php/monica/form.inc.php:3273 +msgid "Fax:" +msgstr "" + +#: lib/php/monica/form.inc.php:3279 +msgid "Group:" +msgstr "" + +#: lib/php/monica/form.inc.php:3285 lib/php/monica/form.inc.php:5541 +#: lib/php/monica/form.inc.php:5747 lib/php/monica/form.inc.php:5905 +#: lib/php/monica/form.inc.php:5998 +msgid "Hide?" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Show it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it currently." +msgstr "" + +#: lib/php/monica/form.inc.php:3292 +msgid "Host:" +msgstr "" + +#: lib/php/monica/form.inc.php:3298 lib/php/monica/list.inc.php:314 +msgid "HTML?" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2948 +#: lib/php/monica/list.inc.php:3062 +msgid "HTML" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2949 +#: lib/php/monica/list.inc.php:3063 +msgid "Plain text" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 +msgid "The submitted content is HTML." +msgstr "" + +#: lib/php/monica/form.inc.php:3305 lib/php/monica/form.inc.php:5535 +#: lib/php/monica/form.inc.php:6074 +msgid "ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3311 +msgid "Introduction:" +msgstr "" + +#: lib/php/monica/form.inc.php:3312 +msgid "Fill in the introduction here." +msgstr "" + +#: lib/php/monica/form.inc.php:3318 +msgid "IP:" +msgstr "" + +#: lib/php/monica/form.inc.php:3324 +msgid "Keywords:" +msgstr "" + +#: lib/php/monica/form.inc.php:3330 +msgid "Language:" +msgstr "" + +#: lib/php/monica/form.inc.php:3355 +msgid "Name:" +msgstr "" + +#: lib/php/monica/form.inc.php:3365 lib/php/monica/form.inc.php:5992 +msgid "Order:" +msgstr "" + +#: lib/php/monica/form.inc.php:3371 +msgid "Organization:" +msgstr "" + +#: lib/php/monica/form.inc.php:3377 +msgid "Parent category:" +msgstr "" + +#: lib/php/monica/form.inc.php:3378 +msgid "At the very top" +msgstr "" + +#: lib/php/monica/form.inc.php:3391 lib/php/monica/form.inc.php:3428 +#: lib/php/monica/form.inc.php:3468 lib/php/monica/form.inc.php:4330 +#: lib/php/monica/form.inc.php:6362 +msgid "Password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3407 lib/php/monica/form.inc.php:3444 +msgid "Confirm password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3458 +msgid "(Leave them blank if you don't plan to change your password.)" +msgstr "" + +#: lib/php/monica/form.inc.php:3484 +msgid "Page path:" +msgstr "" + +#: lib/php/monica/form.inc.php:3490 +msgid "PDF. file:" +msgstr "" + +#: lib/php/monica/form.inc.php:3508 lib/php/monica/form.inc.php:3570 +#: lib/php/monica/form.inc.php:3680 lib/php/monica/form.inc.php:6151 +#: lib/php/monica/form.inc.php:6175 +msgid "Picture:" +msgstr "" + +#: lib/php/monica/form.inc.php:3531 lib/php/monica/form.inc.php:3615 +#: lib/php/monica/form.inc.php:3619 lib/php/monica/form.inc.php:3693 +msgid "Pic. caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:3538 lib/php/monica/form.inc.php:3639 +#: lib/php/monica/form.inc.php:3699 +msgid "Pic. position:" +msgstr "" + +#: lib/php/monica/form.inc.php:3718 lib/php/monica/form.inc.php:3746 +#: lib/php/monica/form.inc.php:3780 +msgid "Pinyin:" +msgstr "" + +#: lib/php/monica/form.inc.php:3722 lib/php/monica/form.inc.php:3756 +msgid "Please fill in the Chinese first." +msgstr "" + +#: lib/php/monica/form.inc.php:3801 +msgid "Subcategory:" +msgid_plural "Subcategories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:3823 +msgid "Script:" +msgstr "" + +#: lib/php/monica/form.inc.php:3829 +msgid "S/N:" +msgstr "" + +#: lib/php/monica/form.inc.php:3835 +msgid "Street:" +msgstr "" + +#: lib/php/monica/form.inc.php:3841 +msgid "Subject:" +msgstr "" + +#: lib/php/monica/form.inc.php:3847 +msgid "Telephone:" +msgstr "" + +#: lib/php/monica/form.inc.php:3853 +msgid "Tel. (cell.):" +msgstr "" + +#: lib/php/monica/form.inc.php:3859 +msgid "Tel. (home):" +msgstr "" + +#: lib/php/monica/form.inc.php:3865 +msgid "Tel. (office):" +msgstr "" + +#: lib/php/monica/form.inc.php:3871 +msgid "Title:" +msgstr "" + +#: lib/php/monica/form.inc.php:3891 +msgid "Value:" +msgstr "" + +#: lib/php/monica/form.inc.php:3897 +msgid "Visits:" +msgstr "" + +#: lib/php/monica/form.inc.php:3903 +msgid "Visited:" +msgstr "" + +#: lib/php/monica/form.inc.php:3909 +msgid "Updated:" +msgstr "" + +#: lib/php/monica/form.inc.php:3915 +msgid "Updated by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3921 +msgid "URL.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3927 +msgid "Zip code:" +msgstr "" + +#: lib/php/monica/form.inc.php:4151 +msgid "Delete this user account" +msgstr "" + +#: lib/php/monica/form.inc.php:4157 +msgid "This table provides you a form to add a new user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4161 +msgid "This table provides you a form to update a current user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4165 +msgid "This table provides you a form to delete a user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4192 +msgid "Add a New User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4196 +msgid "Update a Current User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4200 +msgid "Delete a User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4213 +msgid "This is a super-user. You can only change parts of her infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4220 +msgid "" +"This user has a datum. It cannot be deleted. To delete the user, its datum " +"must first be deleted." +msgid_plural "" +"This user has data. It cannot be deleted. To delete the user, all of its " +"data must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4282 +msgid "Administrator?" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Non-administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4296 +msgid "Disable this user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4305 lib/php/monica/form.inc.php:4307 +#: lib/php/monica/form.inc.php:6354 +msgid "User ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4314 +msgid "Pref. language:" +msgstr "" + +#: lib/php/monica/form.inc.php:4320 +msgid "Full name:" +msgstr "" + +#: lib/php/monica/form.inc.php:4348 lib/php/monica/form.inc.php:4400 +#: lib/php/monica/form.inc.php:4422 lib/php/monica/form.inc.php:4496 +#: lib/php/monica/form.inc.php:4944 lib/php/monica/form.inc.php:4983 +#: lib/php/monica/form.inc.php:4999 lib/php/monica/form.inc.php:5051 +msgid "Belonging to:" +msgstr "" + +#: lib/php/monica/form.inc.php:4532 lib/php/monica/form.inc.php:4554 +msgid "Fail logins:" +msgstr "" + +#: lib/php/monica/form.inc.php:4539 lib/php/monica/form.inc.php:4560 +msgid "(Locked)" +msgstr "" + +#: lib/php/monica/form.inc.php:4585 +msgid "Delete this group" +msgstr "" + +#: lib/php/monica/form.inc.php:4591 +msgid "This table provides you a form to add a new group." +msgstr "" + +#: lib/php/monica/form.inc.php:4595 +msgid "This table provides you a form to update a current group." +msgstr "" + +#: lib/php/monica/form.inc.php:4599 +msgid "This table provides you a form to delete a group." +msgstr "" + +#: lib/php/monica/form.inc.php:4624 +msgid "Add a New Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4628 +msgid "Update a Current Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4632 +msgid "Delete a Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4639 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4648 lib/php/monica/form.inc.php:4650 +msgid "Group ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4663 +msgid "Add a user" +msgstr "" + +#: lib/php/monica/form.inc.php:4670 lib/php/monica/form.inc.php:4710 +#: lib/php/monica/form.inc.php:4728 lib/php/monica/form.inc.php:4781 +msgid "User member:" +msgid_plural "User members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4801 lib/php/monica/form.inc.php:4938 +msgid "Add a group" +msgstr "" + +#: lib/php/monica/form.inc.php:4808 lib/php/monica/form.inc.php:4848 +#: lib/php/monica/form.inc.php:4865 lib/php/monica/form.inc.php:4918 +msgid "Group member:" +msgid_plural "Group members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5085 lib/php/monica/form.inc.php:5160 +msgid "Delete this membership record" +msgstr "" + +#: lib/php/monica/form.inc.php:5091 lib/php/monica/form.inc.php:5166 +msgid "This table provides you a form to add a new membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5095 lib/php/monica/form.inc.php:5170 +msgid "This table provides you a form to change a current membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5099 lib/php/monica/form.inc.php:5174 +msgid "This table provides you a form to delete a membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5122 +msgid "Add a New User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5126 +msgid "Change a Current User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5130 +msgid "Delete a User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5140 lib/php/monica/form.inc.php:5215 +msgid "Member:" +msgstr "" + +#: lib/php/monica/form.inc.php:5197 +msgid "Add a New Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5201 +msgid "Change a Current Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5205 +msgid "Delete a Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5235 +msgid "Delete this user preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5241 +msgid "This table provides you a form to add a new user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5245 +msgid "This table provides you a form to modify a current user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5249 +msgid "This table provides you a form to delete a user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5272 +msgid "Add a New User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5276 +msgid "Modify a Current User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5280 +msgid "Delete a User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5290 lib/php/monica/form.inc.php:5476 +msgid "User:" +msgstr "" + +#: lib/php/monica/form.inc.php:5291 lib/php/monica/list.inc.php:2588 +msgid "Everyone" +msgstr "" + +#: lib/php/monica/form.inc.php:5297 +msgid "Domain:" +msgstr "" + +#: lib/php/monica/form.inc.php:5298 lib/php/monica/list.inc.php:2592 +msgid "Everywhere" +msgstr "" + +#: lib/php/monica/form.inc.php:5318 +msgid "Delete this script privilege record" +msgstr "" + +#: lib/php/monica/form.inc.php:5324 +msgid "This table provides you a form to add a new script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5328 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5332 +msgid "This table provides you a form to delete a script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5355 +msgid "Add a New Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5359 +msgid "Change a Current Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5363 +msgid "Delete a Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5373 +msgid "Privilege:" +msgstr "" + +#: lib/php/monica/form.inc.php:5395 +msgid "Delete this user request" +msgstr "" + +#: lib/php/monica/form.inc.php:5401 +msgid "This table provides you a form to add a new user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5405 +msgid "This table provides you a form to update a current user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5409 +msgid "This table provides you a form to delete a user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5432 +msgid "Add a New User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5436 +msgid "Update a Current User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5440 +msgid "Delete a User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5448 +msgid "Join" +msgstr "" + +#: lib/php/monica/form.inc.php:5452 +msgid "Change e-mail" +msgstr "" + +#: lib/php/monica/form.inc.php:5456 +msgid "Reset password" +msgstr "" + +#: lib/php/monica/form.inc.php:5464 +msgid "Expiration:" +msgstr "" + +#: lib/php/monica/form.inc.php:5470 lib/php/monica/form.inc.php:6432 +msgid "Type:" +msgstr "" + +#: lib/php/monica/form.inc.php:5477 +msgid "Anonymous" +msgstr "" + +#: lib/php/monica/form.inc.php:5483 +msgid "Arguments:" +msgstr "" + +#: lib/php/monica/form.inc.php:5501 +msgid "Delete this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5507 +msgid "This table provides you a form to add a new category." +msgstr "" + +#: lib/php/monica/form.inc.php:5511 +msgid "This table provides you a form to edit a current category." +msgstr "" + +#: lib/php/monica/form.inc.php:5515 +msgid "This table provides you a form to delete a category." +msgstr "" + +#: lib/php/monica/form.inc.php:5525 +msgid "" +"This category has a subcategory. It cannot be deleted. To delete the " +"category, its subcategory must first be deleted." +msgid_plural "" +"This category has subcategories. It cannot be deleted. To delete the " +"category, all of its subcategories must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Show this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5559 +msgid "Delete this categorization record" +msgstr "" + +#: lib/php/monica/form.inc.php:5565 +msgid "This table provides you a form to add a new categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5569 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5573 +msgid "This table provides you a form to delete a categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5618 +msgid "Add a New Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5622 +msgid "Edit a Current Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5626 +msgid "Delete a Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5636 +msgid "" +"This category has a link. It cannot be deleted. To delete the category, " +"its link must first be deleted." +msgid_plural "" +"This category has links. It cannot be deleted. To delete the category, all " +"of its links must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5655 lib/php/monica/form.inc.php:5819 +msgid "Link:" +msgid_plural "Links:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5692 +msgid "Delete this related link" +msgstr "" + +#: lib/php/monica/form.inc.php:5698 +msgid "This table provides you a form to add a new related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5702 +msgid "This table provides you a form to edit a current related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5706 +msgid "This table provides you a form to delete a related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5729 +msgid "Add a New Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5733 +msgid "Edit a Current Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5737 +msgid "Delete a Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 lib/php/monica/form.inc.php:5906 +msgid "Show this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this related link currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5755 lib/php/monica/form.inc.php:5812 +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5794 +msgid "Add a New Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5798 +msgid "Change a Current Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5802 +msgid "Delete a Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5842 +msgid "Delete this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5848 +msgid "This table provides you a form to write a new page." +msgstr "" + +#: lib/php/monica/form.inc.php:5852 +msgid "This table provides you a form to edit a current page." +msgstr "" + +#: lib/php/monica/form.inc.php:5856 +msgid "This table provides you a form to delete a page." +msgstr "" + +#: lib/php/monica/form.inc.php:5881 +msgid "Write a New Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5885 +msgid "Edit a Current Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5889 +msgid "Delete a Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5897 +msgid "Preview this page." +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5929 +msgid "Delete this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5935 +msgid "This table provides you a form to write a new news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5939 +msgid "This table provides you a form to edit a current news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5943 +msgid "This table provides you a form to delete a news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5968 +msgid "Write a New News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5972 +msgid "Edit a Current News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5976 +msgid "Delete a News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5984 +msgid "Preview this news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Show this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article currently." +msgstr "" + +#: lib/php/monica/form.inc.php:6019 +msgid "Delete this country record" +msgstr "" + +#: lib/php/monica/form.inc.php:6025 +msgid "This table provides you a form to add a new country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6029 +msgid "This table provides you a form to edit a current country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6033 +msgid "This table provides you a form to delete a country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6056 +msgid "Add a New Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6060 +msgid "Edit a Current Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6064 +msgid "Delete a Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6080 lib/php/monica/list.inc.php:3391 +msgid "Special?" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A special record" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A normal country" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "This is a special record." +msgstr "" + +#: lib/php/monica/form.inc.php:6110 +msgid "This table provides you a form to add a new picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6114 +msgid "This table provides you a form to modify a current picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6125 +msgid "Upload a New Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6129 +msgid "Modify a Current Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6230 lib/php/monica/form.inc.php:6242 +msgid "Ratio:" +msgstr "" + +#: lib/php/monica/form.inc.php:6267 lib/php/monica/form.inc.php:6277 +msgid "Upload:" +msgstr "" + +#: lib/php/monica/form.inc.php:6308 +msgid "This table provides you a form to log in." +msgstr "" + +#: lib/php/monica/form.inc.php:6314 +msgid "Identify Yourself" +msgstr "" + +#: lib/php/monica/form.inc.php:6323 lib/php/monica/init.inc.php:505 +msgid "" +"Log-in is temporarily closed for maintainance now. Please come again " +"later. Sorry for the inconvienence." +msgstr "" + +#: lib/php/monica/form.inc.php:6332 +msgid "Log in" +msgstr "" + +#: lib/php/monica/form.inc.php:6379 +msgid "Remember me." +msgstr "" + +#: lib/php/monica/form.inc.php:6406 +msgid "Rebuild the Pages" +msgstr "" + +#: lib/php/monica/form.inc.php:6415 +msgid "Confirm" +msgstr "" + +#: lib/php/monica/form.inc.php:6457 +msgid "Log Out" +msgstr "" + +#: lib/php/monica/form.inc.php:6466 +msgid "Log out" +msgstr "" + +#: lib/php/monica/form.inc.php:6480 +msgid "Are you sure you want to log out?" +msgstr "" + +#: lib/php/monica/init.inc.php:114 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" + +#: lib/php/monica/init.inc.php:503 lib/php/monica/init.inc.php:504 +msgid "Log-In Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:524 lib/php/monica/init.inc.php:525 +msgid "Development Site Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:526 +msgid "Development site is closed. Please work on the live site." +msgstr "" + +#: lib/php/monica/links.inc.php:271 +msgid "Related Links" +msgstr "" + +#: lib/php/monica/list.inc.php:130 +msgid "Malformed" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "OK" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "Unreachable" +msgstr "" + +#: lib/php/monica/list.inc.php:290 lib/php/monica/list.inc.php:1534 +#: lib/php/monica/list.inc.php:3642 +msgid "(query phrase)" +msgstr "" + +#: lib/php/monica/list.inc.php:300 +msgid "S/N" +msgstr "" + +#: lib/php/monica/list.inc.php:301 +msgid "Created" +msgstr "" + +#: lib/php/monica/list.inc.php:302 +msgid "Created by" +msgstr "" + +#: lib/php/monica/list.inc.php:303 +msgid "Updated" +msgstr "" + +#: lib/php/monica/list.inc.php:304 +msgid "Updated by" +msgstr "" + +#: lib/php/monica/list.inc.php:306 +msgid "Content" +msgstr "" + +#: lib/php/monica/list.inc.php:307 +msgid "Category" +msgstr "" + +#: lib/php/monica/list.inc.php:308 +msgid "Coverage" +msgstr "" + +#: lib/php/monica/list.inc.php:309 +msgid "Date" +msgstr "" + +#: lib/php/monica/list.inc.php:311 +msgid "Description" +msgstr "" + +#: lib/php/monica/list.inc.php:312 +msgid "E-mail" +msgstr "" + +#: lib/php/monica/list.inc.php:313 +msgid "Hidden?" +msgstr "" + +#: lib/php/monica/list.inc.php:315 +msgid "ID." +msgstr "" + +#: lib/php/monica/list.inc.php:316 +msgid "Keywords" +msgstr "" + +#: lib/php/monica/list.inc.php:317 +msgid "Name" +msgstr "" + +#: lib/php/monica/list.inc.php:318 +msgid "Order" +msgstr "" + +#: lib/php/monica/list.inc.php:319 +msgid "Page path" +msgstr "" + +#: lib/php/monica/list.inc.php:320 +msgid "Picture" +msgstr "" + +#: lib/php/monica/list.inc.php:321 +msgid "Pic. ratio" +msgstr "" + +#: lib/php/monica/list.inc.php:322 +msgid "Pic. caption" +msgstr "" + +#: lib/php/monica/list.inc.php:323 +msgid "Pic. position" +msgstr "" + +#: lib/php/monica/list.inc.php:324 +msgid "Subject" +msgstr "" + +#: lib/php/monica/list.inc.php:325 +msgid "Title" +msgstr "" + +#: lib/php/monica/list.inc.php:326 +msgid "URL." +msgstr "" + +#: lib/php/monica/list.inc.php:327 +msgid "Status (slow)" +msgstr "" + +#: lib/php/monica/list.inc.php:336 +msgid "Select" +msgstr "" + +#: lib/php/monica/list.inc.php:339 +msgid "Select a Data Record" +msgstr "" + +#: lib/php/monica/list.inc.php:343 +msgid "Edit" +msgstr "" + +#: lib/php/monica/list.inc.php:345 +msgid "Manage Data" +msgstr "" + +#: lib/php/monica/list.inc.php:749 +msgid "Nothing found. Please try another query." +msgstr "" + +#: lib/php/monica/list.inc.php:752 +msgid "The database is empty." +msgstr "" + +#: lib/php/monica/list.inc.php:759 +#, c-format +msgid "Your query found %s record." +msgid_plural "Your query found %s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:766 +#, c-format +msgid "%s record." +msgid_plural "%s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:775 +#, c-format +msgid "Your query found %s record, listing %s to %s." +msgid_plural "Your query found %s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:784 +#, c-format +msgid "%s record, listing %s to %s." +msgid_plural "%s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:855 lib/php/monica/list.inc.php:860 +#: lib/php/monica/list.inc.php:869 +#, c-format +msgid "Page number (%s) invalid. Please specify a valid page number." +msgstr "" + +#: lib/php/monica/list.inc.php:874 +#, c-format +msgid "" +"Page number (%d) out of range. Please specify a number between 1 and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:1138 lib/php/monica/list.inc.php:1151 +#, c-format +msgid "You cannot sort by \"%s\"." +msgstr "" + +#: lib/php/monica/list.inc.php:1512 +msgid "Search" +msgstr "" + +#: lib/php/monica/list.inc.php:1610 +msgid "Index" +msgstr "" + +#: lib/php/monica/list.inc.php:1634 +msgid "First" +msgstr "" + +#: lib/php/monica/list.inc.php:1647 +msgid "Previous" +msgstr "" + +#: lib/php/monica/list.inc.php:1696 +msgid "Next" +msgstr "" + +#: lib/php/monica/list.inc.php:1714 +msgid "Last" +msgstr "" + +#: lib/php/monica/list.inc.php:1736 +msgid "Page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1776 lib/php/monica/list.inc.php:1900 +msgid "Delete the selected items." +msgstr "" + +#: lib/php/monica/list.inc.php:1805 +msgid "No." +msgstr "" + +#: lib/php/monica/list.inc.php:1813 lib/php/monica/list.inc.php:1873 +msgid "View" +msgstr "" + +#: lib/php/monica/list.inc.php:1925 +msgid "Set" +msgstr "" + +#: lib/php/monica/list.inc.php:1941 +msgid "Rows per page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1946 +msgid "Display columns:" +msgstr "" + +#: lib/php/monica/list.inc.php:1976 +msgid "Select a User" +msgstr "" + +#: lib/php/monica/list.inc.php:1977 +msgid "Manage Users" +msgstr "" + +#: lib/php/monica/list.inc.php:1982 +msgid "User ID." +msgstr "" + +#: lib/php/monica/list.inc.php:1983 +msgid "Full name" +msgstr "" + +#: lib/php/monica/list.inc.php:1984 +msgid "Deleted?" +msgstr "" + +#: lib/php/monica/list.inc.php:1985 +msgid "Pref. language" +msgstr "" + +#: lib/php/monica/list.inc.php:1986 +msgid "Visits" +msgstr "" + +#: lib/php/monica/list.inc.php:1987 +msgid "Visited" +msgstr "" + +#: lib/php/monica/list.inc.php:1988 +msgid "IP" +msgstr "" + +#: lib/php/monica/list.inc.php:1989 +msgid "Host" +msgstr "" + +#: lib/php/monica/list.inc.php:1990 +msgid "From country" +msgstr "" + +#: lib/php/monica/list.inc.php:1991 +msgid "Fail logins" +msgstr "" + +#: lib/php/monica/list.inc.php:2024 +msgid "Deleted" +msgstr "" + +#: lib/php/monica/list.inc.php:2035 +msgid "Add a new user account." +msgstr "" + +#: lib/php/monica/list.inc.php:2045 +msgid "Search for a user:" +msgstr "" + +#: lib/php/monica/list.inc.php:2063 +#, c-format +msgid "Your query found %s user." +msgid_plural "Your query found %s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2070 +#, c-format +msgid "%s user." +msgid_plural "%s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2079 +#, c-format +msgid "Your query found %s user, listing %s to %s." +msgid_plural "Your query found %s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2088 +#, c-format +msgid "%s user, listing %s to %s." +msgid_plural "%s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2107 +msgid "Select a Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2108 +msgid "Manage Groups" +msgstr "" + +#: lib/php/monica/list.inc.php:2113 +msgid "Group ID." +msgstr "" + +#: lib/php/monica/list.inc.php:2121 +msgid "Add a new group." +msgstr "" + +#: lib/php/monica/list.inc.php:2131 +msgid "Search for a group:" +msgstr "" + +#: lib/php/monica/list.inc.php:2149 +#, c-format +msgid "Your query found %s group." +msgid_plural "Your query found %s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2156 +#, c-format +msgid "%s group." +msgid_plural "%s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2165 +#, c-format +msgid "Your query found %s group, listing %s to %s." +msgid_plural "Your query found %s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2174 +#, c-format +msgid "%s group, listing %s to %s." +msgid_plural "%s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2194 +msgid "Select a User Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2195 +msgid "Manage User Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2200 lib/php/monica/list.inc.php:2323 +msgid "Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2201 lib/php/monica/list.inc.php:2324 +msgid "Member" +msgstr "" + +#: lib/php/monica/list.inc.php:2244 lib/php/monica/list.inc.php:2375 +msgid "Add a new membership record." +msgstr "" + +#: lib/php/monica/list.inc.php:2254 lib/php/monica/list.inc.php:2385 +msgid "Search for a membership record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2272 lib/php/monica/list.inc.php:2403 +#, c-format +msgid "Your query found %s membership record." +msgid_plural "Your query found %s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2279 lib/php/monica/list.inc.php:2410 +#, c-format +msgid "%s membership record." +msgid_plural "%s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2288 lib/php/monica/list.inc.php:2419 +#, c-format +msgid "Your query found %s membership record, listing %s to %s." +msgid_plural "Your query found %s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2297 lib/php/monica/list.inc.php:2428 +#, c-format +msgid "%s membership record, listing %s to %s." +msgid_plural "%s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2317 +msgid "Select a Group Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2318 +msgid "Manage Group Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2448 +msgid "Select a Script Privilege Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2449 +msgid "Manage Script Privileges" +msgstr "" + +#: lib/php/monica/list.inc.php:2454 +msgid "Script" +msgstr "" + +#: lib/php/monica/list.inc.php:2455 +msgid "Privilege" +msgstr "" + +#: lib/php/monica/list.inc.php:2493 +msgid "Add a new script privilege record." +msgstr "" + +#: lib/php/monica/list.inc.php:2503 +msgid "Search for a script privilege record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2521 +#, c-format +msgid "Your query found %s script privilege record." +msgid_plural "Your query found %s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2528 +#, c-format +msgid "%s script privilege record." +msgid_plural "%s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2537 +#, c-format +msgid "Your query found %s script privilege record, listing %s to %s." +msgid_plural "Your query found %s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2546 +#, c-format +msgid "%s script privilege record, listing %s to %s." +msgid_plural "%s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2566 +msgid "Select a User Preference" +msgstr "" + +#: lib/php/monica/list.inc.php:2567 +msgid "Manage User Preferences" +msgstr "" + +#: lib/php/monica/list.inc.php:2574 lib/php/monica/list.inc.php:2689 +msgid "User" +msgstr "" + +#: lib/php/monica/list.inc.php:2575 +msgid "Domain" +msgstr "" + +#: lib/php/monica/list.inc.php:2576 +msgid "Value" +msgstr "" + +#: lib/php/monica/list.inc.php:2610 +msgid "Add a new user preference." +msgstr "" + +#: lib/php/monica/list.inc.php:2620 +msgid "Search for a user preference:" +msgstr "" + +#: lib/php/monica/list.inc.php:2638 +#, c-format +msgid "Your query found %s user preference." +msgid_plural "Your query found %s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2645 +#, c-format +msgid "%s user preference." +msgid_plural "%s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2654 +#, c-format +msgid "Your query found %s user preference, listing %s to %s." +msgid_plural "Your query found %s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2663 +#, c-format +msgid "%s user preference, listing %s to %s." +msgid_plural "%s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2682 +msgid "Select a User Request" +msgstr "" + +#: lib/php/monica/list.inc.php:2683 +msgid "Manage User Requests" +msgstr "" + +#: lib/php/monica/list.inc.php:2688 +msgid "Type" +msgstr "" + +#: lib/php/monica/list.inc.php:2690 +msgid "Arguments" +msgstr "" + +#: lib/php/monica/list.inc.php:2691 +msgid "Expiration" +msgstr "" + +#: lib/php/monica/list.inc.php:2699 +msgid "Add a new user request." +msgstr "" + +#: lib/php/monica/list.inc.php:2709 +msgid "Search for a user request:" +msgstr "" + +#: lib/php/monica/list.inc.php:2727 +#, c-format +msgid "Your query found %s user request." +msgid_plural "Your query found %s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2734 +#, c-format +msgid "%s user request." +msgid_plural "%s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2743 +#, c-format +msgid "Your query found %s user request, listing %s to %s." +msgid_plural "Your query found %s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2752 +#, c-format +msgid "%s user request, listing %s to %s." +msgid_plural "%s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2778 +msgid "Add a new category." +msgstr "" + +#: lib/php/monica/list.inc.php:2788 +msgid "Search for a category:" +msgstr "" + +#: lib/php/monica/list.inc.php:2806 +#, c-format +msgid "Your query found %s category." +msgid_plural "Your query found %s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2813 +#, c-format +msgid "%s category." +msgid_plural "%s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2822 +#, c-format +msgid "Your query found %s category, listing %s to %s." +msgid_plural "Your query found %s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2831 +#, c-format +msgid "%s category, listing %s to %s." +msgid_plural "%s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2849 +msgid "Add a new categorization record." +msgstr "" + +#: lib/php/monica/list.inc.php:2859 +msgid "Search for a categorization record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2877 +#, c-format +msgid "Your query found %s categorization record." +msgid_plural "Your query found %s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2884 +#, c-format +msgid "%s categorization record." +msgid_plural "%s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2893 +#, c-format +msgid "Your query found %s categorization record, listing %s to %s." +msgid_plural "Your query found %s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2902 +#, c-format +msgid "%s categorization record, listing %s to %s." +msgid_plural "%s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2921 +msgid "Select a Page" +msgstr "" + +#: lib/php/monica/list.inc.php:2922 +msgid "Manage Pages" +msgstr "" + +#: lib/php/monica/list.inc.php:2952 lib/php/monica/list.inc.php:3066 +#: lib/php/monica/list.inc.php:3173 lib/php/monica/list.inc.php:3237 +#: lib/php/monica/list.inc.php:3358 +msgid "Hidden" +msgstr "" + +#: lib/php/monica/list.inc.php:2953 lib/php/monica/list.inc.php:3067 +#: lib/php/monica/list.inc.php:3174 lib/php/monica/list.inc.php:3238 +#: lib/php/monica/list.inc.php:3359 +msgid "Shown" +msgstr "" + +#: lib/php/monica/list.inc.php:2963 +msgid "Write a new page." +msgstr "" + +#: lib/php/monica/list.inc.php:2973 +msgid "Search for a page:" +msgstr "" + +#: lib/php/monica/list.inc.php:2991 +#, c-format +msgid "Your query found %s page." +msgid_plural "Your query found %s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2998 +#, c-format +msgid "%s page." +msgid_plural "%s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3007 +#, c-format +msgid "Your query found %s page, listing %s to %s." +msgid_plural "Your query found %s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3016 +#, c-format +msgid "%s page, listing %s to %s." +msgid_plural "%s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3035 +msgid "Select a News Article" +msgstr "" + +#: lib/php/monica/list.inc.php:3036 +msgid "Manage News" +msgstr "" + +#: lib/php/monica/list.inc.php:3077 +msgid "Write a new news article." +msgstr "" + +#: lib/php/monica/list.inc.php:3087 +msgid "Search for a news article:" +msgstr "" + +#: lib/php/monica/list.inc.php:3105 +#, c-format +msgid "Your query found %s news article." +msgid_plural "Your query found %s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3112 +#, c-format +msgid "%s news article." +msgid_plural "%s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3121 +#, c-format +msgid "Your query found %s news article, listing %s to %s." +msgid_plural "Your query found %s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3130 +#, c-format +msgid "%s news article, listing %s to %s." +msgid_plural "%s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3149 +msgid "Select a Link Category" +msgstr "" + +#: lib/php/monica/list.inc.php:3150 +msgid "Manage Link Categories" +msgstr "" + +#: lib/php/monica/list.inc.php:3197 +msgid "Select a Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3198 +msgid "Manage Links" +msgstr "" + +#: lib/php/monica/list.inc.php:3248 +msgid "Add a new related link." +msgstr "" + +#: lib/php/monica/list.inc.php:3258 +msgid "Search for a related link:" +msgstr "" + +#: lib/php/monica/list.inc.php:3276 +#, c-format +msgid "Your query found %s related link." +msgid_plural "Your query found %s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3283 +#, c-format +msgid "%s related link." +msgid_plural "%s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3292 +#, c-format +msgid "Your query found %s related link, listing %s to %s." +msgid_plural "Your query found %s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3301 +#, c-format +msgid "%s related link, listing %s to %s." +msgid_plural "%s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3321 +msgid "Select a Link Categorization Record" +msgstr "" + +#: lib/php/monica/list.inc.php:3322 +msgid "Manage Link Categorization" +msgstr "" + +#: lib/php/monica/list.inc.php:3327 +msgid "Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3383 +msgid "Select a Country" +msgstr "" + +#: lib/php/monica/list.inc.php:3384 +msgid "Manage Country Data" +msgstr "" + +#: lib/php/monica/list.inc.php:3389 +msgid "Code" +msgstr "" + +#: lib/php/monica/list.inc.php:3390 +msgid "Country name" +msgstr "" + +#: lib/php/monica/list.inc.php:3399 +msgid "Add a new country record." +msgstr "" + +#: lib/php/monica/list.inc.php:3409 +msgid "Search for a country:" +msgstr "" + +#: lib/php/monica/list.inc.php:3427 +#, c-format +msgid "Your query found %s country." +msgid_plural "Your query found %s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3434 +#, c-format +msgid "%s country." +msgid_plural "%s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3443 +#, c-format +msgid "Your query found %s country, listing %s to %s." +msgid_plural "Your query found %s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3452 +#, c-format +msgid "%s country, listing %s to %s." +msgid_plural "%s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3474 +msgid "Browse the Activity Log" +msgstr "" + +#: lib/php/monica/list.inc.php:3586 +msgid "Please fill in the number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3590 +#, c-format +msgid "This number of rows to display is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/list.inc.php:3595 +msgid "Please fill in a positive integer number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3599 lib/php/monica/list.inc.php:3609 +#, c-format +msgid "" +"The number of rows to display is too small. Please fill in a larger number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3613 +#, c-format +msgid "" +"The number of rows to display is too large. Please fill in a smaller number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3638 +msgid "Search for log entries:" +msgstr "" + +#: lib/php/monica/list.inc.php:3641 +msgid "Display" +msgstr "" + +#: lib/php/monica/list.inc.php:3654 +msgid "Display rows:" +msgstr "" + +#: lib/php/monica/list.inc.php:3677 +#, c-format +msgid "Your query found %s log entry." +msgid_plural "Your query found %s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3684 +#, c-format +msgid "%s log entry." +msgid_plural "%s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3693 +#, c-format +msgid "Your query found %s log entry, listing %s to %s." +msgid_plural "Your query found %s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3702 +#, c-format +msgid "%s log entry, listing %s to %s." +msgid_plural "%s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/lninfo.inc.php:28 +msgid "English" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:39 +msgid "Traditional Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:50 +msgid "Simplified Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:61 +msgid "Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:72 +msgid "Japanese" +msgstr "日本語" + +#: lib/php/monica/lninfo.inc.php:83 +msgid "Korean" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:94 +msgid "German" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:105 +msgid "Spanish" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:366 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:738 +msgid "Web pages" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:739 +msgid "News" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:740 +msgid "Related links" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:741 +msgid "Home page" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:742 +msgid "Whole web site" +msgstr "" + +#: lib/php/monica/pic.inc.php:39 +msgid "Left-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:40 +msgid "Right-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:74 lib/php/monica/pic.inc.php:77 +#, c-format +msgid "This picture file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/pic.inc.php:92 +msgid "Please upload only PNG, JPEG or GIF files." +msgstr "" + +#: lib/php/monica/pic.inc.php:153 +#, c-format +msgid "Width: %d, height: %d, ratio: %0.2f" +msgstr "" + +#: lib/php/monica/pic.inc.php:176 +msgid "Please specify a numeric ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:180 +msgid "Please specify a positive ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:183 +#, c-format +msgid "Please specify a ratio less than or equal to %0.2f." +msgstr "" + +#: lib/php/monica/pic.inc.php:189 +msgid "This image is too large to display." +msgstr "" + +#: lib/php/monica/preview.inc.php:47 +#, c-format +msgid "Unknown preview source: \"%s\"." +msgstr "" + +#: lib/php/monica/preview.inc.php:67 +#, c-format +msgid "Unknown preview form: %d." +msgstr "" + +#: lib/php/monica/preview.inc.php:143 +msgid "Preview Mark Area" +msgstr "" + +#: lib/php/monica/preview.inc.php:148 +msgid "Finish preview and return." +msgstr "" + +#: lib/php/monica/process.inc.php:237 +msgid "This record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:243 +msgid "This record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:247 +msgid "This record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:251 +msgid "This record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:406 +msgid "This category was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:412 +msgid "This category has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:416 +msgid "This category has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:420 +msgid "This category has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:433 +msgid "This categorization record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:439 +msgid "This categorization record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:443 +msgid "This categorization record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:447 +msgid "This categorization record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:782 +msgid "This user account was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:788 +msgid "This user account has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:792 +msgid "This user account has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:796 +msgid "This user account has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1074 +msgid "This group was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1080 +msgid "This group has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1084 +msgid "This group has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1088 +msgid "This group has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1152 lib/php/monica/process.inc.php:1230 +msgid "This membership record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1158 lib/php/monica/process.inc.php:1236 +msgid "This membership record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1162 lib/php/monica/process.inc.php:1240 +msgid "This membership record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1166 lib/php/monica/process.inc.php:1244 +msgid "This membership record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1308 +msgid "This script privilege record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1314 +msgid "This script privilege record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1318 +msgid "This script privilege record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1322 +msgid "This script privilege record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1438 +msgid "This user preference was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1444 +msgid "This user preference has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1448 +msgid "This user preference has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1452 +msgid "This user preference has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1560 +msgid "This user request was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1566 +msgid "This user request has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1570 +msgid "This user request has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1574 +msgid "This user request has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1685 +msgid "This page was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1691 +msgid "This page has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1695 +msgid "This page has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1699 +msgid "This page has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1874 +msgid "This news article was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1880 +msgid "This news article has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1884 +msgid "This news article has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1888 +msgid "This news article has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1997 +msgid "This country was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2003 +msgid "This country has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2007 +msgid "This country has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2011 +msgid "This country has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:2097 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. (%0.3f seconds)" +msgstr "" + +#: lib/php/monica/process.inc.php:2158 +#, c-format +msgid "Welcome, %s!" +msgstr "" + +#: lib/php/monica/process.inc.php:2204 +msgid "You have successfully logged out." +msgstr "" + +#: lib/php/monica/process.inc.php:2439 +msgid "This related link was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2445 +msgid "This related link has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2449 +msgid "This related link has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2453 +msgid "This related link has been successfully deleted." +msgstr "" + +#: lib/php/monica/request.inc.php:38 +msgid "Please specify the request." +msgstr "" + +#: lib/php/monica/request.inc.php:46 lib/php/monica/request.inc.php:55 +#, c-format +msgid "Invalid request S/N: %s." +msgstr "" + +#: lib/php/monica/sitesize.inc.php:41 +#, c-format +msgid "Currently using files %s.\n" +msgstr "" + +#: lib/php/monica/sitesize.inc.php:46 +#, c-format +msgid "Currently using files %s, database %s, total %s.\n" +msgstr "" + +#: lib/php/monica/upload.inc.php:70 +#, c-format +msgid "MIME file type: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:71 +#, c-format +msgid "File name: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:72 +#, c-format +msgid "File size: %s bytes" +msgstr "" + +#: lib/php/monica/validate.inc.php:116 +msgid "HTML Validatior Logo Area" +msgstr "" + +#: lib/php/monica/validate.inc.php:117 +msgid "HTML validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:118 +#, c-format +msgid "Valid %s!" +msgstr "" + +#: lib/php/monica/validate.inc.php:119 +msgid "CSS validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:120 +msgid "Valid CSS!" +msgstr "" + +#: lib/php/monica/validate.inc.php:121 +msgid "Explanation of Level Triple-A Conformance" +msgstr "" + +#: lib/php/monica/validate.inc.php:122 +msgid "" +"Level Triple-A conformance icon, W3C-WAI Web Content Accessibility " +"Guidelines 1.0" +msgstr "" diff --git a/po/monica/ko_KR.gmo b/po/monica/ko_KR.gmo new file mode 100644 index 0000000..4ae88a7 Binary files /dev/null and b/po/monica/ko_KR.gmo differ diff --git a/po/monica/ko_KR.po b/po/monica/ko_KR.po new file mode 100644 index 0000000..f6a5725 --- /dev/null +++ b/po/monica/ko_KR.po @@ -0,0 +1,3296 @@ +# Korean PO file for the monica core +# Copyright (C) 2007-2018 Pristine Communcations +# This file is distributed under the same license as the monica package. +# imacat , 2007-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: monica 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 12:42+0800\n" +"PO-Revision-Date: 2018-11-02 01:22+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Korean \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: lib/php/monica/checker.inc.php:159 +msgid "Please select a user." +msgstr "" + +#: lib/php/monica/checker.inc.php:163 +msgid "This user does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:181 +msgid "Please select a group." +msgstr "" + +#: lib/php/monica/checker.inc.php:185 +msgid "This group does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:203 +msgid "Please fill in the script." +msgstr "" + +#: lib/php/monica/checker.inc.php:207 +#, c-format +msgid "This script is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:212 +msgid "This script is not a valid script. Please specify another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:230 +msgid "Please fill in the date." +msgstr "" + +#: lib/php/monica/checker.inc.php:234 lib/php/monica/checker.inc.php:238 +#: lib/php/monica/checker.inc.php:241 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "" + +#: lib/php/monica/checker.inc.php:259 +msgid "Please fill in the ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:263 +#, c-format +msgid "This ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:267 +#, c-format +msgid "This ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:272 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:294 +msgid "Please fill in the order." +msgstr "" + +#: lib/php/monica/checker.inc.php:298 +#, c-format +msgid "This order is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:303 +msgid "Please fill in a positive integer order." +msgstr "" + +#: lib/php/monica/checker.inc.php:307 lib/php/monica/checker.inc.php:317 +#, c-format +msgid "" +"The order is too small. Please fill in a larger order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:321 +#, c-format +msgid "" +"The order is too large. Please fill in a smaller order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:348 +msgid "Please fill in the page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:352 +#, c-format +msgid "This page path is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:365 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:369 +msgid "Please fill in an absolute page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:373 +msgid "Please fill in a valid page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:377 +msgid "You cannot overwrite the cover home page." +msgstr "" + +#: lib/php/monica/checker.inc.php:381 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "" + +#: lib/php/monica/checker.inc.php:422 lib/php/monica/checker.inc.php:428 +msgid "Please fill in the attachment description." +msgstr "" + +#: lib/php/monica/checker.inc.php:432 +#, c-format +msgid "This attachment description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:449 +msgid "This PDF. file does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:456 +#, c-format +msgid "This PDF. file is too large. (Max. size %s)" +msgstr "" + +#: lib/php/monica/checker.inc.php:461 +msgid "Please upload only PDF. file." +msgstr "" + +#: lib/php/monica/checker.inc.php:479 +msgid "Please fill in the title." +msgstr "" + +#: lib/php/monica/checker.inc.php:483 +#, c-format +msgid "This title is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:502 +msgid "Please fill in the subject." +msgstr "" + +#: lib/php/monica/checker.inc.php:506 +#, c-format +msgid "This subject is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:524 lib/php/monica/form.inc.php:3159 +#: lib/php/monica/form.inc.php:3172 +msgid "Fill in the content here." +msgstr "" + +#: lib/php/monica/checker.inc.php:528 +msgid "Please fill in the content." +msgstr "" + +#: lib/php/monica/checker.inc.php:532 +#, c-format +msgid "This content is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:551 +msgid "Please fill in the keywords." +msgstr "" + +#: lib/php/monica/checker.inc.php:555 +#, c-format +msgid "This keyword list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:572 +msgid "Please select a proper pinyin." +msgstr "" + +#: lib/php/monica/checker.inc.php:578 +#, c-format +msgid "This pinyin is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:583 +msgid "" +"This pinyin does not match the Chinese. Please select a proper pinyin from " +"the list." +msgstr "" + +#: lib/php/monica/checker.inc.php:609 lib/php/monica/pic.inc.php:82 +msgid "Please upload the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:616 lib/php/monica/checker.inc.php:3214 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:622 +#, c-format +msgid "This picture is too large. Please upload another one. (Max. size %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:639 lib/php/monica/form.inc.php:3588 +#, c-format +msgid "Please upload a new picture from %s." +msgstr "" + +#: lib/php/monica/checker.inc.php:664 lib/php/monica/checker.inc.php:727 +msgid "Please fill in the picture caption." +msgstr "" + +#: lib/php/monica/checker.inc.php:668 lib/php/monica/checker.inc.php:731 +#, c-format +msgid "This picture caption is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:686 lib/php/monica/checker.inc.php:749 +msgid "Please select the picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:692 lib/php/monica/checker.inc.php:755 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:791 lib/php/monica/checker.inc.php:794 +#, c-format +msgid "Your uploaded file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/checker.inc.php:797 lib/php/monica/pic.inc.php:80 +msgid "" +"Upload not completed. Disk may be full or connection may be closed in the " +"half. You may try to upload again, or contact the system administrator for " +"this problem." +msgstr "" + +#: lib/php/monica/checker.inc.php:799 lib/php/monica/pic.inc.php:84 +#, c-format +msgid "Upload failed with an unknown error (%d)." +msgstr "" + +#: lib/php/monica/checker.inc.php:1183 lib/php/monica/chkfunc.inc.php:59 +#: lib/php/monica/chkfunc.inc.php:72 lib/php/monica/preview.inc.php:29 +#, c-format +msgid "The following field was not received: \"%s\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:1262 +msgid "Please fill in the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1266 +#, c-format +msgid "This user ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1270 +#, c-format +msgid "This user ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1275 +msgid "" +"Only lower-case English letters, numbers, at-signs, dots, dashes and " +"underscores are allowed for the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1287 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1317 +msgid "Please fill in the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1320 +msgid "Please confirm the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1324 +#, c-format +msgid "This password is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1329 +#, c-format +msgid "This password is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1334 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "" + +#: lib/php/monica/checker.inc.php:1345 +msgid "This password is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1360 +msgid "This password does not contain enough different characters." +msgstr "" + +#: lib/php/monica/checker.inc.php:1364 +msgid "This password is too simplistic/systematic." +msgstr "" + +#: lib/php/monica/checker.inc.php:1368 +msgid "This password is based on a dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1370 +msgid "This password is based on a (reversed) dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1372 +msgid "This password is too simple." +msgstr "" + +#: lib/php/monica/checker.inc.php:1378 +msgid "You cannot use a password that is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1397 +msgid "Please fill in the name." +msgstr "" + +#: lib/php/monica/checker.inc.php:1401 +#, c-format +msgid "This name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1420 +msgid "Please fill in the e-mail." +msgstr "" + +#: lib/php/monica/checker.inc.php:1424 +#, c-format +msgid "This e-mail is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1428 +#, c-format +msgid "This e-mail is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1437 +msgid "Please fill in a valid e-mail address." +msgstr "" + +#: lib/php/monica/checker.inc.php:1439 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:1461 lib/php/monica/checker.inc.php:1655 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1478 +msgid "You cannot submit the super-user group along with other groups." +msgstr "" + +#: lib/php/monica/checker.inc.php:1480 +msgid "You cannot set the administrators group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1482 +msgid "You cannot set the all-users group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1515 +msgid "Please fill in the group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1519 +#, c-format +msgid "This group ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1523 +#, c-format +msgid "This group ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1528 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1540 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1558 +msgid "Please fill in the privilege description." +msgstr "" + +#: lib/php/monica/checker.inc.php:1562 +#, c-format +msgid "This privilege description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1585 +msgid "This user member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1620 +msgid "This group member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1747 lib/php/monica/checker.inc.php:1855 +msgid "Please select a member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1751 lib/php/monica/checker.inc.php:1859 +msgid "This member does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1770 lib/php/monica/checker.inc.php:1883 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1837 +msgid "Please select a different belonging group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1864 +msgid "Please select a different group member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1958 +msgid "" +"This script privilege already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1996 lib/php/monica/checker.inc.php:2184 +msgid "Please select the user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2002 lib/php/monica/checker.inc.php:2190 +msgid "This option is invalid. Please select a proper user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2020 +msgid "Please set the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2026 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2039 lib/php/monica/checker.inc.php:2295 +msgid "Please fill in the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2043 lib/php/monica/checker.inc.php:2299 +#, c-format +msgid "This preference domain is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2063 +msgid "Please fill in the preference name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2067 +#, c-format +msgid "This preference name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2086 +msgid "Please fill in the preference value." +msgstr "" + +#: lib/php/monica/checker.inc.php:2090 +#, c-format +msgid "This preference value is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2119 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2167 +msgid "Please select the request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2173 +msgid "This option is invalid. Please select a proper request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2194 +msgid "You must choose anonymous for join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2197 +msgid "You cannot choose anonymous for non-join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2221 lib/php/monica/form.inc.php:5484 +msgid "Please fill in the request arguments list here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2229 +#, c-format +msgid "This request arguments list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2349 +msgid "Please fill in the number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2353 +#, c-format +msgid "This number of rows per page is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2358 +msgid "Please fill in a positive integer number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2362 lib/php/monica/checker.inc.php:2372 +#, c-format +msgid "" +"The number of rows per page is too small. Please fill in a larger number of " +"rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2376 +#, c-format +msgid "" +"The number of rows per page is too large. Please fill in a smaller number " +"of rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2443 +msgid "Please fill in your user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:2451 lib/php/monica/checker.inc.php:2458 +#: lib/php/monica/checker.inc.php:2475 lib/php/monica/checker.inc.php:2508 +#: lib/php/monica/checker.inc.php:2540 lib/php/monica/checker.inc.php:2548 +#: lib/php/monica/checker.inc.php:2558 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "" + +#: lib/php/monica/checker.inc.php:2495 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "" + +#: lib/php/monica/checker.inc.php:2531 +msgid "Please fill in your password." +msgstr "" + +#: lib/php/monica/checker.inc.php:2581 +msgid "You are not an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2600 +msgid "You are an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2751 +msgid "Please fill in the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2755 +#, c-format +msgid "You must fill in a %d-letters code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2760 +msgid "You can only use upper letters and for the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2772 +msgid "This code is duplicated. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2790 +msgid "Please fill in the country name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2794 +#, c-format +msgid "This country name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2822 lib/php/monica/checker.inc.php:2841 +msgid "Please select a parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2828 +msgid "This option is invalid. Please select a proper parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2845 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2850 +msgid "A category cannot belong to itself. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2858 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2876 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:2894 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2941 +msgid "Please fill in the URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2945 +#, c-format +msgid "This URL. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2950 +msgid "Please fill in a valid URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2962 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2967 +msgid "This URL. is not reachable. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:2984 lib/php/monica/form.inc.php:3261 +msgid "Fill in the description here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2988 +msgid "Please fill in the description." +msgstr "" + +#: lib/php/monica/checker.inc.php:2992 +#, c-format +msgid "This description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:3012 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:3016 lib/php/monica/checker.inc.php:3072 +msgid "This category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3022 lib/php/monica/checker.inc.php:3068 +msgid "Please select a category." +msgstr "" + +#: lib/php/monica/checker.inc.php:3090 +msgid "Please select a related link." +msgstr "" + +#: lib/php/monica/checker.inc.php:3094 +msgid "This link does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3113 +msgid "" +"This link categorization already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3154 +msgid "Please select the type." +msgstr "" + +#: lib/php/monica/checker.inc.php:3158 +msgid "This type does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3185 lib/php/monica/list.inc.php:961 +msgid "Please fill in your query." +msgstr "" + +#: lib/php/monica/checker.inc.php:3210 +msgid "Please submit the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:3237 lib/php/monica/checker.inc.php:3328 +msgid "Please fill in the resize ratio." +msgstr "" + +#: lib/php/monica/checker.inc.php:3305 +msgid "Please specify a valid picture." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:156 lib/php/monica/chkfunc.inc.php:160 +#: lib/php/monica/chkfunc.inc.php:163 lib/php/monica/chkfunc.inc.php:166 +msgid "Please select a legal year." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:171 lib/php/monica/chkfunc.inc.php:175 +#: lib/php/monica/chkfunc.inc.php:178 +msgid "Please select a legal month." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:183 lib/php/monica/chkfunc.inc.php:187 +#: lib/php/monica/chkfunc.inc.php:193 +msgid "Please select a legal day." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:27 +#, c-format +msgid "%s: It is not a file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:32 +#, c-format +msgid "%s: You have no permission to overwrite this file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:45 +#, c-format +msgid "%s: You cannot create anything under the root directory." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:50 +#, c-format +msgid "" +"%s: One of the parents of this file (%s) is not a directory. You cannot " +"create any new file inside." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:55 +#, c-format +msgid "%s: You have no permission to create any file under %s." +msgstr "" + +#: lib/php/monica/commtext.inc.php:18 +msgid "(not set)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:24 +msgid "(none)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:30 +msgid "(N/A)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:36 +msgid "(blank)" +msgstr "" + +#: lib/php/monica/echoform.inc.php:173 +#, c-format +msgid "%s bytes" +msgstr "" + +#: lib/php/monica/form.inc.php:168 +msgid "Delete it" +msgstr "" + +#: lib/php/monica/form.inc.php:174 +msgid "Are you sure you want to delete it? It cannot be recovered." +msgstr "" + +#: lib/php/monica/form.inc.php:188 +msgid "*" +msgstr "" + +#: lib/php/monica/form.inc.php:224 +msgid "This table provides you a form to add a new data record." +msgstr "" + +#: lib/php/monica/form.inc.php:228 +msgid "This table provides you a form to update a current data record." +msgstr "" + +#: lib/php/monica/form.inc.php:232 +msgid "This table provides you a form to delete a data record." +msgstr "" + +#: lib/php/monica/form.inc.php:281 +msgid "Add a New Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:285 +msgid "Update a Current Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:289 +msgid "Delete a Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:301 +msgid "Preview it." +msgstr "" + +#: lib/php/monica/form.inc.php:500 lib/php/monica/form.inc.php:506 +#: lib/php/monica/form.inc.php:691 lib/php/monica/form.inc.php:697 +#: lib/php/monica/preview.inc.php:146 +msgid "Preview" +msgstr "" + +#: lib/php/monica/form.inc.php:501 lib/php/monica/form.inc.php:507 +#: lib/php/monica/form.inc.php:692 lib/php/monica/form.inc.php:698 +msgid "Confirm and submit" +msgstr "" + +#: lib/php/monica/form.inc.php:708 lib/php/monica/form.inc.php:1692 +#: lib/php/monica/form.inc.php:1778 lib/php/monica/list.inc.php:1809 +msgid "Delete" +msgstr "" + +#: lib/php/monica/form.inc.php:709 lib/php/monica/form.inc.php:6419 +#: lib/php/monica/form.inc.php:6470 +msgid "Cancel" +msgstr "" + +#: lib/php/monica/form.inc.php:1042 lib/php/monica/form.inc.php:3499 +msgid "Set the picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1043 lib/php/monica/form.inc.php:3031 +#: lib/php/monica/form.inc.php:3500 +msgid "Delete this picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1048 lib/php/monica/form.inc.php:1178 +#: lib/php/monica/form.inc.php:3037 lib/php/monica/form.inc.php:3104 +#: lib/php/monica/form.inc.php:3505 lib/php/monica/form.inc.php:3677 +#: lib/php/monica/form.inc.php:6163 lib/php/monica/list.inc.php:814 +msgid "Picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1059 lib/php/monica/form.inc.php:1109 +#: lib/php/monica/form.inc.php:1185 +#, c-format +msgid "Picture #%d:" +msgstr "" + +#: lib/php/monica/form.inc.php:1080 lib/php/monica/form.inc.php:1131 +#: lib/php/monica/form.inc.php:1166 lib/php/monica/form.inc.php:1199 +msgid "Caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:1092 lib/php/monica/form.inc.php:3064 +#: lib/php/monica/form.inc.php:3566 lib/php/monica/form.inc.php:6183 +msgid "Original picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1093 lib/php/monica/form.inc.php:3065 +#: lib/php/monica/form.inc.php:3567 lib/php/monica/form.inc.php:6197 +msgid "New picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1113 lib/php/monica/form.inc.php:1276 +#: lib/php/monica/form.inc.php:1363 lib/php/monica/form.inc.php:1451 +#: lib/php/monica/form.inc.php:1560 lib/php/monica/form.inc.php:1650 +#: lib/php/monica/form.inc.php:1727 lib/php/monica/form.inc.php:1825 +#: lib/php/monica/form.inc.php:1916 lib/php/monica/form.inc.php:1977 +#: lib/php/monica/form.inc.php:2053 lib/php/monica/form.inc.php:2159 +#: lib/php/monica/form.inc.php:2391 lib/php/monica/form.inc.php:2592 +#: lib/php/monica/form.inc.php:2689 lib/php/monica/form.inc.php:2800 +#: lib/php/monica/form.inc.php:2897 lib/php/monica/form.inc.php:2980 +#: lib/php/monica/form.inc.php:3069 lib/php/monica/form.inc.php:3200 +#: lib/php/monica/form.inc.php:3571 lib/php/monica/form.inc.php:3627 +#: lib/php/monica/form.inc.php:3640 lib/php/monica/form.inc.php:3747 +#: lib/php/monica/form.inc.php:4423 lib/php/monica/form.inc.php:4533 +#: lib/php/monica/form.inc.php:4729 lib/php/monica/form.inc.php:4866 +#: lib/php/monica/form.inc.php:5000 lib/php/monica/form.inc.php:6176 +#: lib/php/monica/form.inc.php:6243 +msgid "Original:" +msgstr "" + +#: lib/php/monica/form.inc.php:1141 lib/php/monica/form.inc.php:1281 +#: lib/php/monica/form.inc.php:1369 lib/php/monica/form.inc.php:1456 +#: lib/php/monica/form.inc.php:1575 lib/php/monica/form.inc.php:1655 +#: lib/php/monica/form.inc.php:1732 lib/php/monica/form.inc.php:1832 +#: lib/php/monica/form.inc.php:1921 lib/php/monica/form.inc.php:1982 +#: lib/php/monica/form.inc.php:2065 lib/php/monica/form.inc.php:2173 +#: lib/php/monica/form.inc.php:2422 lib/php/monica/form.inc.php:2597 +#: lib/php/monica/form.inc.php:2694 lib/php/monica/form.inc.php:2805 +#: lib/php/monica/form.inc.php:2902 lib/php/monica/form.inc.php:2985 +#: lib/php/monica/form.inc.php:3080 lib/php/monica/form.inc.php:3205 +#: lib/php/monica/form.inc.php:3584 lib/php/monica/form.inc.php:3632 +#: lib/php/monica/form.inc.php:3649 lib/php/monica/form.inc.php:3752 +#: lib/php/monica/form.inc.php:4442 lib/php/monica/form.inc.php:4543 +#: lib/php/monica/form.inc.php:4742 lib/php/monica/form.inc.php:4879 +#: lib/php/monica/form.inc.php:5013 lib/php/monica/form.inc.php:6188 +#: lib/php/monica/form.inc.php:6248 lib/php/monica/form.inc.php:6278 +msgid "New:" +msgstr "" + +#: lib/php/monica/form.inc.php:1269 lib/php/monica/form.inc.php:1444 +#: lib/php/monica/form.inc.php:1543 lib/php/monica/form.inc.php:2358 +#: lib/php/monica/form.inc.php:2585 lib/php/monica/form.inc.php:2793 +#: lib/php/monica/form.inc.php:2890 lib/php/monica/form.inc.php:2973 +#: lib/php/monica/form.inc.php:3620 +msgid "Source:" +msgstr "" + +#: lib/php/monica/form.inc.php:1289 lib/php/monica/form.inc.php:1464 +#: lib/php/monica/form.inc.php:1583 lib/php/monica/form.inc.php:2605 +#: lib/php/monica/form.inc.php:2813 lib/php/monica/form.inc.php:2910 +#: lib/php/monica/form.inc.php:2993 +#, c-format +msgid "Please set it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:1501 +msgid "Hide" +msgstr "" + +#: lib/php/monica/form.inc.php:1502 +msgid "Show" +msgstr "" + +#: lib/php/monica/form.inc.php:1691 lib/php/monica/form.inc.php:1777 +#: lib/php/monica/form.inc.php:1887 +msgid "Choose" +msgstr "" + +#: lib/php/monica/form.inc.php:2237 +msgid "Delete this file" +msgstr "" + +#: lib/php/monica/form.inc.php:2267 lib/php/monica/form.inc.php:2368 +#: lib/php/monica/form.inc.php:2400 lib/php/monica/form.inc.php:2445 +#: lib/php/monica/form.inc.php:2506 +msgid "File name:" +msgstr "" + +#: lib/php/monica/form.inc.php:2274 lib/php/monica/form.inc.php:2375 +#: lib/php/monica/form.inc.php:2407 lib/php/monica/form.inc.php:2452 +#: lib/php/monica/form.inc.php:2513 +msgid "MIME file type:" +msgstr "" + +#: lib/php/monica/form.inc.php:2279 lib/php/monica/form.inc.php:2380 +#: lib/php/monica/form.inc.php:2412 lib/php/monica/form.inc.php:2457 +#: lib/php/monica/form.inc.php:2518 +msgid "File size:" +msgstr "" + +#: lib/php/monica/form.inc.php:2430 +#, c-format +msgid "Please upload it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:3128 +msgid "Address:" +msgstr "" + +#: lib/php/monica/form.inc.php:3129 +msgid "Fill in your address here." +msgstr "" + +#: lib/php/monica/form.inc.php:3135 +msgid "Attachment:" +msgstr "" + +#: lib/php/monica/form.inc.php:3139 +msgid "Attachment description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3158 lib/php/monica/form.inc.php:3171 +msgid "Content:" +msgstr "" + +#: lib/php/monica/form.inc.php:3165 +msgid "City:" +msgstr "" + +#: lib/php/monica/form.inc.php:3187 lib/php/monica/form.inc.php:3199 +#: lib/php/monica/form.inc.php:3217 lib/php/monica/form.inc.php:3241 +msgid "Country:" +msgstr "" + +#: lib/php/monica/form.inc.php:3229 +msgid "Created:" +msgstr "" + +#: lib/php/monica/form.inc.php:3235 +msgid "Created by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3247 +msgid "Date:" +msgstr "" + +#: lib/php/monica/form.inc.php:3253 lib/php/monica/form.inc.php:4292 +#: lib/php/monica/form.inc.php:4295 lib/php/monica/list.inc.php:310 +msgid "Disabled?" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 lib/php/monica/list.inc.php:2020 +msgid "Disabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 +msgid "Enabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 +msgid "Disable it." +msgstr "" + +#: lib/php/monica/form.inc.php:3260 lib/php/monica/form.inc.php:4657 +msgid "Description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3267 +msgid "E-mail:" +msgstr "" + +#: lib/php/monica/form.inc.php:3273 +msgid "Fax:" +msgstr "" + +#: lib/php/monica/form.inc.php:3279 +msgid "Group:" +msgstr "" + +#: lib/php/monica/form.inc.php:3285 lib/php/monica/form.inc.php:5541 +#: lib/php/monica/form.inc.php:5747 lib/php/monica/form.inc.php:5905 +#: lib/php/monica/form.inc.php:5998 +msgid "Hide?" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Show it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it currently." +msgstr "" + +#: lib/php/monica/form.inc.php:3292 +msgid "Host:" +msgstr "" + +#: lib/php/monica/form.inc.php:3298 lib/php/monica/list.inc.php:314 +msgid "HTML?" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2948 +#: lib/php/monica/list.inc.php:3062 +msgid "HTML" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2949 +#: lib/php/monica/list.inc.php:3063 +msgid "Plain text" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 +msgid "The submitted content is HTML." +msgstr "" + +#: lib/php/monica/form.inc.php:3305 lib/php/monica/form.inc.php:5535 +#: lib/php/monica/form.inc.php:6074 +msgid "ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3311 +msgid "Introduction:" +msgstr "" + +#: lib/php/monica/form.inc.php:3312 +msgid "Fill in the introduction here." +msgstr "" + +#: lib/php/monica/form.inc.php:3318 +msgid "IP:" +msgstr "" + +#: lib/php/monica/form.inc.php:3324 +msgid "Keywords:" +msgstr "" + +#: lib/php/monica/form.inc.php:3330 +msgid "Language:" +msgstr "" + +#: lib/php/monica/form.inc.php:3355 +msgid "Name:" +msgstr "" + +#: lib/php/monica/form.inc.php:3365 lib/php/monica/form.inc.php:5992 +msgid "Order:" +msgstr "" + +#: lib/php/monica/form.inc.php:3371 +msgid "Organization:" +msgstr "" + +#: lib/php/monica/form.inc.php:3377 +msgid "Parent category:" +msgstr "" + +#: lib/php/monica/form.inc.php:3378 +msgid "At the very top" +msgstr "" + +#: lib/php/monica/form.inc.php:3391 lib/php/monica/form.inc.php:3428 +#: lib/php/monica/form.inc.php:3468 lib/php/monica/form.inc.php:4330 +#: lib/php/monica/form.inc.php:6362 +msgid "Password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3407 lib/php/monica/form.inc.php:3444 +msgid "Confirm password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3458 +msgid "(Leave them blank if you don't plan to change your password.)" +msgstr "" + +#: lib/php/monica/form.inc.php:3484 +msgid "Page path:" +msgstr "" + +#: lib/php/monica/form.inc.php:3490 +msgid "PDF. file:" +msgstr "" + +#: lib/php/monica/form.inc.php:3508 lib/php/monica/form.inc.php:3570 +#: lib/php/monica/form.inc.php:3680 lib/php/monica/form.inc.php:6151 +#: lib/php/monica/form.inc.php:6175 +msgid "Picture:" +msgstr "" + +#: lib/php/monica/form.inc.php:3531 lib/php/monica/form.inc.php:3615 +#: lib/php/monica/form.inc.php:3619 lib/php/monica/form.inc.php:3693 +msgid "Pic. caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:3538 lib/php/monica/form.inc.php:3639 +#: lib/php/monica/form.inc.php:3699 +msgid "Pic. position:" +msgstr "" + +#: lib/php/monica/form.inc.php:3718 lib/php/monica/form.inc.php:3746 +#: lib/php/monica/form.inc.php:3780 +msgid "Pinyin:" +msgstr "" + +#: lib/php/monica/form.inc.php:3722 lib/php/monica/form.inc.php:3756 +msgid "Please fill in the Chinese first." +msgstr "" + +#: lib/php/monica/form.inc.php:3801 +msgid "Subcategory:" +msgid_plural "Subcategories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:3823 +msgid "Script:" +msgstr "" + +#: lib/php/monica/form.inc.php:3829 +msgid "S/N:" +msgstr "" + +#: lib/php/monica/form.inc.php:3835 +msgid "Street:" +msgstr "" + +#: lib/php/monica/form.inc.php:3841 +msgid "Subject:" +msgstr "" + +#: lib/php/monica/form.inc.php:3847 +msgid "Telephone:" +msgstr "" + +#: lib/php/monica/form.inc.php:3853 +msgid "Tel. (cell.):" +msgstr "" + +#: lib/php/monica/form.inc.php:3859 +msgid "Tel. (home):" +msgstr "" + +#: lib/php/monica/form.inc.php:3865 +msgid "Tel. (office):" +msgstr "" + +#: lib/php/monica/form.inc.php:3871 +msgid "Title:" +msgstr "" + +#: lib/php/monica/form.inc.php:3891 +msgid "Value:" +msgstr "" + +#: lib/php/monica/form.inc.php:3897 +msgid "Visits:" +msgstr "" + +#: lib/php/monica/form.inc.php:3903 +msgid "Visited:" +msgstr "" + +#: lib/php/monica/form.inc.php:3909 +msgid "Updated:" +msgstr "" + +#: lib/php/monica/form.inc.php:3915 +msgid "Updated by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3921 +msgid "URL.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3927 +msgid "Zip code:" +msgstr "" + +#: lib/php/monica/form.inc.php:4151 +msgid "Delete this user account" +msgstr "" + +#: lib/php/monica/form.inc.php:4157 +msgid "This table provides you a form to add a new user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4161 +msgid "This table provides you a form to update a current user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4165 +msgid "This table provides you a form to delete a user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4192 +msgid "Add a New User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4196 +msgid "Update a Current User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4200 +msgid "Delete a User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4213 +msgid "This is a super-user. You can only change parts of her infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4220 +msgid "" +"This user has a datum. It cannot be deleted. To delete the user, its datum " +"must first be deleted." +msgid_plural "" +"This user has data. It cannot be deleted. To delete the user, all of its " +"data must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4282 +msgid "Administrator?" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Non-administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4296 +msgid "Disable this user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4305 lib/php/monica/form.inc.php:4307 +#: lib/php/monica/form.inc.php:6354 +msgid "User ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4314 +msgid "Pref. language:" +msgstr "" + +#: lib/php/monica/form.inc.php:4320 +msgid "Full name:" +msgstr "" + +#: lib/php/monica/form.inc.php:4348 lib/php/monica/form.inc.php:4400 +#: lib/php/monica/form.inc.php:4422 lib/php/monica/form.inc.php:4496 +#: lib/php/monica/form.inc.php:4944 lib/php/monica/form.inc.php:4983 +#: lib/php/monica/form.inc.php:4999 lib/php/monica/form.inc.php:5051 +msgid "Belonging to:" +msgstr "" + +#: lib/php/monica/form.inc.php:4532 lib/php/monica/form.inc.php:4554 +msgid "Fail logins:" +msgstr "" + +#: lib/php/monica/form.inc.php:4539 lib/php/monica/form.inc.php:4560 +msgid "(Locked)" +msgstr "" + +#: lib/php/monica/form.inc.php:4585 +msgid "Delete this group" +msgstr "" + +#: lib/php/monica/form.inc.php:4591 +msgid "This table provides you a form to add a new group." +msgstr "" + +#: lib/php/monica/form.inc.php:4595 +msgid "This table provides you a form to update a current group." +msgstr "" + +#: lib/php/monica/form.inc.php:4599 +msgid "This table provides you a form to delete a group." +msgstr "" + +#: lib/php/monica/form.inc.php:4624 +msgid "Add a New Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4628 +msgid "Update a Current Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4632 +msgid "Delete a Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4639 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4648 lib/php/monica/form.inc.php:4650 +msgid "Group ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4663 +msgid "Add a user" +msgstr "" + +#: lib/php/monica/form.inc.php:4670 lib/php/monica/form.inc.php:4710 +#: lib/php/monica/form.inc.php:4728 lib/php/monica/form.inc.php:4781 +msgid "User member:" +msgid_plural "User members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4801 lib/php/monica/form.inc.php:4938 +msgid "Add a group" +msgstr "" + +#: lib/php/monica/form.inc.php:4808 lib/php/monica/form.inc.php:4848 +#: lib/php/monica/form.inc.php:4865 lib/php/monica/form.inc.php:4918 +msgid "Group member:" +msgid_plural "Group members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5085 lib/php/monica/form.inc.php:5160 +msgid "Delete this membership record" +msgstr "" + +#: lib/php/monica/form.inc.php:5091 lib/php/monica/form.inc.php:5166 +msgid "This table provides you a form to add a new membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5095 lib/php/monica/form.inc.php:5170 +msgid "This table provides you a form to change a current membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5099 lib/php/monica/form.inc.php:5174 +msgid "This table provides you a form to delete a membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5122 +msgid "Add a New User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5126 +msgid "Change a Current User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5130 +msgid "Delete a User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5140 lib/php/monica/form.inc.php:5215 +msgid "Member:" +msgstr "" + +#: lib/php/monica/form.inc.php:5197 +msgid "Add a New Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5201 +msgid "Change a Current Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5205 +msgid "Delete a Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5235 +msgid "Delete this user preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5241 +msgid "This table provides you a form to add a new user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5245 +msgid "This table provides you a form to modify a current user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5249 +msgid "This table provides you a form to delete a user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5272 +msgid "Add a New User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5276 +msgid "Modify a Current User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5280 +msgid "Delete a User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5290 lib/php/monica/form.inc.php:5476 +msgid "User:" +msgstr "" + +#: lib/php/monica/form.inc.php:5291 lib/php/monica/list.inc.php:2588 +msgid "Everyone" +msgstr "" + +#: lib/php/monica/form.inc.php:5297 +msgid "Domain:" +msgstr "" + +#: lib/php/monica/form.inc.php:5298 lib/php/monica/list.inc.php:2592 +msgid "Everywhere" +msgstr "" + +#: lib/php/monica/form.inc.php:5318 +msgid "Delete this script privilege record" +msgstr "" + +#: lib/php/monica/form.inc.php:5324 +msgid "This table provides you a form to add a new script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5328 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5332 +msgid "This table provides you a form to delete a script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5355 +msgid "Add a New Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5359 +msgid "Change a Current Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5363 +msgid "Delete a Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5373 +msgid "Privilege:" +msgstr "" + +#: lib/php/monica/form.inc.php:5395 +msgid "Delete this user request" +msgstr "" + +#: lib/php/monica/form.inc.php:5401 +msgid "This table provides you a form to add a new user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5405 +msgid "This table provides you a form to update a current user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5409 +msgid "This table provides you a form to delete a user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5432 +msgid "Add a New User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5436 +msgid "Update a Current User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5440 +msgid "Delete a User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5448 +msgid "Join" +msgstr "" + +#: lib/php/monica/form.inc.php:5452 +msgid "Change e-mail" +msgstr "" + +#: lib/php/monica/form.inc.php:5456 +msgid "Reset password" +msgstr "" + +#: lib/php/monica/form.inc.php:5464 +msgid "Expiration:" +msgstr "" + +#: lib/php/monica/form.inc.php:5470 lib/php/monica/form.inc.php:6432 +msgid "Type:" +msgstr "" + +#: lib/php/monica/form.inc.php:5477 +msgid "Anonymous" +msgstr "" + +#: lib/php/monica/form.inc.php:5483 +msgid "Arguments:" +msgstr "" + +#: lib/php/monica/form.inc.php:5501 +msgid "Delete this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5507 +msgid "This table provides you a form to add a new category." +msgstr "" + +#: lib/php/monica/form.inc.php:5511 +msgid "This table provides you a form to edit a current category." +msgstr "" + +#: lib/php/monica/form.inc.php:5515 +msgid "This table provides you a form to delete a category." +msgstr "" + +#: lib/php/monica/form.inc.php:5525 +msgid "" +"This category has a subcategory. It cannot be deleted. To delete the " +"category, its subcategory must first be deleted." +msgid_plural "" +"This category has subcategories. It cannot be deleted. To delete the " +"category, all of its subcategories must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Show this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5559 +msgid "Delete this categorization record" +msgstr "" + +#: lib/php/monica/form.inc.php:5565 +msgid "This table provides you a form to add a new categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5569 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5573 +msgid "This table provides you a form to delete a categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5618 +msgid "Add a New Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5622 +msgid "Edit a Current Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5626 +msgid "Delete a Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5636 +msgid "" +"This category has a link. It cannot be deleted. To delete the category, " +"its link must first be deleted." +msgid_plural "" +"This category has links. It cannot be deleted. To delete the category, all " +"of its links must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5655 lib/php/monica/form.inc.php:5819 +msgid "Link:" +msgid_plural "Links:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5692 +msgid "Delete this related link" +msgstr "" + +#: lib/php/monica/form.inc.php:5698 +msgid "This table provides you a form to add a new related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5702 +msgid "This table provides you a form to edit a current related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5706 +msgid "This table provides you a form to delete a related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5729 +msgid "Add a New Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5733 +msgid "Edit a Current Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5737 +msgid "Delete a Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 lib/php/monica/form.inc.php:5906 +msgid "Show this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this related link currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5755 lib/php/monica/form.inc.php:5812 +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5794 +msgid "Add a New Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5798 +msgid "Change a Current Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5802 +msgid "Delete a Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5842 +msgid "Delete this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5848 +msgid "This table provides you a form to write a new page." +msgstr "" + +#: lib/php/monica/form.inc.php:5852 +msgid "This table provides you a form to edit a current page." +msgstr "" + +#: lib/php/monica/form.inc.php:5856 +msgid "This table provides you a form to delete a page." +msgstr "" + +#: lib/php/monica/form.inc.php:5881 +msgid "Write a New Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5885 +msgid "Edit a Current Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5889 +msgid "Delete a Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5897 +msgid "Preview this page." +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5929 +msgid "Delete this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5935 +msgid "This table provides you a form to write a new news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5939 +msgid "This table provides you a form to edit a current news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5943 +msgid "This table provides you a form to delete a news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5968 +msgid "Write a New News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5972 +msgid "Edit a Current News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5976 +msgid "Delete a News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5984 +msgid "Preview this news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Show this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article currently." +msgstr "" + +#: lib/php/monica/form.inc.php:6019 +msgid "Delete this country record" +msgstr "" + +#: lib/php/monica/form.inc.php:6025 +msgid "This table provides you a form to add a new country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6029 +msgid "This table provides you a form to edit a current country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6033 +msgid "This table provides you a form to delete a country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6056 +msgid "Add a New Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6060 +msgid "Edit a Current Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6064 +msgid "Delete a Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6080 lib/php/monica/list.inc.php:3391 +msgid "Special?" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A special record" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A normal country" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "This is a special record." +msgstr "" + +#: lib/php/monica/form.inc.php:6110 +msgid "This table provides you a form to add a new picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6114 +msgid "This table provides you a form to modify a current picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6125 +msgid "Upload a New Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6129 +msgid "Modify a Current Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6230 lib/php/monica/form.inc.php:6242 +msgid "Ratio:" +msgstr "" + +#: lib/php/monica/form.inc.php:6267 lib/php/monica/form.inc.php:6277 +msgid "Upload:" +msgstr "" + +#: lib/php/monica/form.inc.php:6308 +msgid "This table provides you a form to log in." +msgstr "" + +#: lib/php/monica/form.inc.php:6314 +msgid "Identify Yourself" +msgstr "" + +#: lib/php/monica/form.inc.php:6323 lib/php/monica/init.inc.php:505 +msgid "" +"Log-in is temporarily closed for maintainance now. Please come again " +"later. Sorry for the inconvienence." +msgstr "" + +#: lib/php/monica/form.inc.php:6332 +msgid "Log in" +msgstr "" + +#: lib/php/monica/form.inc.php:6379 +msgid "Remember me." +msgstr "" + +#: lib/php/monica/form.inc.php:6406 +msgid "Rebuild the Pages" +msgstr "" + +#: lib/php/monica/form.inc.php:6415 +msgid "Confirm" +msgstr "" + +#: lib/php/monica/form.inc.php:6457 +msgid "Log Out" +msgstr "" + +#: lib/php/monica/form.inc.php:6466 +msgid "Log out" +msgstr "" + +#: lib/php/monica/form.inc.php:6480 +msgid "Are you sure you want to log out?" +msgstr "" + +#: lib/php/monica/init.inc.php:114 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" + +#: lib/php/monica/init.inc.php:503 lib/php/monica/init.inc.php:504 +msgid "Log-In Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:524 lib/php/monica/init.inc.php:525 +msgid "Development Site Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:526 +msgid "Development site is closed. Please work on the live site." +msgstr "" + +#: lib/php/monica/links.inc.php:271 +msgid "Related Links" +msgstr "" + +#: lib/php/monica/list.inc.php:130 +msgid "Malformed" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "OK" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "Unreachable" +msgstr "" + +#: lib/php/monica/list.inc.php:290 lib/php/monica/list.inc.php:1534 +#: lib/php/monica/list.inc.php:3642 +msgid "(query phrase)" +msgstr "" + +#: lib/php/monica/list.inc.php:300 +msgid "S/N" +msgstr "" + +#: lib/php/monica/list.inc.php:301 +msgid "Created" +msgstr "" + +#: lib/php/monica/list.inc.php:302 +msgid "Created by" +msgstr "" + +#: lib/php/monica/list.inc.php:303 +msgid "Updated" +msgstr "" + +#: lib/php/monica/list.inc.php:304 +msgid "Updated by" +msgstr "" + +#: lib/php/monica/list.inc.php:306 +msgid "Content" +msgstr "" + +#: lib/php/monica/list.inc.php:307 +msgid "Category" +msgstr "" + +#: lib/php/monica/list.inc.php:308 +msgid "Coverage" +msgstr "" + +#: lib/php/monica/list.inc.php:309 +msgid "Date" +msgstr "" + +#: lib/php/monica/list.inc.php:311 +msgid "Description" +msgstr "" + +#: lib/php/monica/list.inc.php:312 +msgid "E-mail" +msgstr "" + +#: lib/php/monica/list.inc.php:313 +msgid "Hidden?" +msgstr "" + +#: lib/php/monica/list.inc.php:315 +msgid "ID." +msgstr "" + +#: lib/php/monica/list.inc.php:316 +msgid "Keywords" +msgstr "" + +#: lib/php/monica/list.inc.php:317 +msgid "Name" +msgstr "" + +#: lib/php/monica/list.inc.php:318 +msgid "Order" +msgstr "" + +#: lib/php/monica/list.inc.php:319 +msgid "Page path" +msgstr "" + +#: lib/php/monica/list.inc.php:320 +msgid "Picture" +msgstr "" + +#: lib/php/monica/list.inc.php:321 +msgid "Pic. ratio" +msgstr "" + +#: lib/php/monica/list.inc.php:322 +msgid "Pic. caption" +msgstr "" + +#: lib/php/monica/list.inc.php:323 +msgid "Pic. position" +msgstr "" + +#: lib/php/monica/list.inc.php:324 +msgid "Subject" +msgstr "" + +#: lib/php/monica/list.inc.php:325 +msgid "Title" +msgstr "" + +#: lib/php/monica/list.inc.php:326 +msgid "URL." +msgstr "" + +#: lib/php/monica/list.inc.php:327 +msgid "Status (slow)" +msgstr "" + +#: lib/php/monica/list.inc.php:336 +msgid "Select" +msgstr "" + +#: lib/php/monica/list.inc.php:339 +msgid "Select a Data Record" +msgstr "" + +#: lib/php/monica/list.inc.php:343 +msgid "Edit" +msgstr "" + +#: lib/php/monica/list.inc.php:345 +msgid "Manage Data" +msgstr "" + +#: lib/php/monica/list.inc.php:749 +msgid "Nothing found. Please try another query." +msgstr "" + +#: lib/php/monica/list.inc.php:752 +msgid "The database is empty." +msgstr "" + +#: lib/php/monica/list.inc.php:759 +#, c-format +msgid "Your query found %s record." +msgid_plural "Your query found %s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:766 +#, c-format +msgid "%s record." +msgid_plural "%s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:775 +#, c-format +msgid "Your query found %s record, listing %s to %s." +msgid_plural "Your query found %s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:784 +#, c-format +msgid "%s record, listing %s to %s." +msgid_plural "%s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:855 lib/php/monica/list.inc.php:860 +#: lib/php/monica/list.inc.php:869 +#, c-format +msgid "Page number (%s) invalid. Please specify a valid page number." +msgstr "" + +#: lib/php/monica/list.inc.php:874 +#, c-format +msgid "" +"Page number (%d) out of range. Please specify a number between 1 and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:1138 lib/php/monica/list.inc.php:1151 +#, c-format +msgid "You cannot sort by \"%s\"." +msgstr "" + +#: lib/php/monica/list.inc.php:1512 +msgid "Search" +msgstr "" + +#: lib/php/monica/list.inc.php:1610 +msgid "Index" +msgstr "" + +#: lib/php/monica/list.inc.php:1634 +msgid "First" +msgstr "" + +#: lib/php/monica/list.inc.php:1647 +msgid "Previous" +msgstr "" + +#: lib/php/monica/list.inc.php:1696 +msgid "Next" +msgstr "" + +#: lib/php/monica/list.inc.php:1714 +msgid "Last" +msgstr "" + +#: lib/php/monica/list.inc.php:1736 +msgid "Page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1776 lib/php/monica/list.inc.php:1900 +msgid "Delete the selected items." +msgstr "" + +#: lib/php/monica/list.inc.php:1805 +msgid "No." +msgstr "" + +#: lib/php/monica/list.inc.php:1813 lib/php/monica/list.inc.php:1873 +msgid "View" +msgstr "" + +#: lib/php/monica/list.inc.php:1925 +msgid "Set" +msgstr "" + +#: lib/php/monica/list.inc.php:1941 +msgid "Rows per page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1946 +msgid "Display columns:" +msgstr "" + +#: lib/php/monica/list.inc.php:1976 +msgid "Select a User" +msgstr "" + +#: lib/php/monica/list.inc.php:1977 +msgid "Manage Users" +msgstr "" + +#: lib/php/monica/list.inc.php:1982 +msgid "User ID." +msgstr "" + +#: lib/php/monica/list.inc.php:1983 +msgid "Full name" +msgstr "" + +#: lib/php/monica/list.inc.php:1984 +msgid "Deleted?" +msgstr "" + +#: lib/php/monica/list.inc.php:1985 +msgid "Pref. language" +msgstr "" + +#: lib/php/monica/list.inc.php:1986 +msgid "Visits" +msgstr "" + +#: lib/php/monica/list.inc.php:1987 +msgid "Visited" +msgstr "" + +#: lib/php/monica/list.inc.php:1988 +msgid "IP" +msgstr "" + +#: lib/php/monica/list.inc.php:1989 +msgid "Host" +msgstr "" + +#: lib/php/monica/list.inc.php:1990 +msgid "From country" +msgstr "" + +#: lib/php/monica/list.inc.php:1991 +msgid "Fail logins" +msgstr "" + +#: lib/php/monica/list.inc.php:2024 +msgid "Deleted" +msgstr "" + +#: lib/php/monica/list.inc.php:2035 +msgid "Add a new user account." +msgstr "" + +#: lib/php/monica/list.inc.php:2045 +msgid "Search for a user:" +msgstr "" + +#: lib/php/monica/list.inc.php:2063 +#, c-format +msgid "Your query found %s user." +msgid_plural "Your query found %s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2070 +#, c-format +msgid "%s user." +msgid_plural "%s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2079 +#, c-format +msgid "Your query found %s user, listing %s to %s." +msgid_plural "Your query found %s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2088 +#, c-format +msgid "%s user, listing %s to %s." +msgid_plural "%s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2107 +msgid "Select a Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2108 +msgid "Manage Groups" +msgstr "" + +#: lib/php/monica/list.inc.php:2113 +msgid "Group ID." +msgstr "" + +#: lib/php/monica/list.inc.php:2121 +msgid "Add a new group." +msgstr "" + +#: lib/php/monica/list.inc.php:2131 +msgid "Search for a group:" +msgstr "" + +#: lib/php/monica/list.inc.php:2149 +#, c-format +msgid "Your query found %s group." +msgid_plural "Your query found %s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2156 +#, c-format +msgid "%s group." +msgid_plural "%s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2165 +#, c-format +msgid "Your query found %s group, listing %s to %s." +msgid_plural "Your query found %s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2174 +#, c-format +msgid "%s group, listing %s to %s." +msgid_plural "%s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2194 +msgid "Select a User Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2195 +msgid "Manage User Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2200 lib/php/monica/list.inc.php:2323 +msgid "Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2201 lib/php/monica/list.inc.php:2324 +msgid "Member" +msgstr "" + +#: lib/php/monica/list.inc.php:2244 lib/php/monica/list.inc.php:2375 +msgid "Add a new membership record." +msgstr "" + +#: lib/php/monica/list.inc.php:2254 lib/php/monica/list.inc.php:2385 +msgid "Search for a membership record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2272 lib/php/monica/list.inc.php:2403 +#, c-format +msgid "Your query found %s membership record." +msgid_plural "Your query found %s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2279 lib/php/monica/list.inc.php:2410 +#, c-format +msgid "%s membership record." +msgid_plural "%s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2288 lib/php/monica/list.inc.php:2419 +#, c-format +msgid "Your query found %s membership record, listing %s to %s." +msgid_plural "Your query found %s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2297 lib/php/monica/list.inc.php:2428 +#, c-format +msgid "%s membership record, listing %s to %s." +msgid_plural "%s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2317 +msgid "Select a Group Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2318 +msgid "Manage Group Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2448 +msgid "Select a Script Privilege Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2449 +msgid "Manage Script Privileges" +msgstr "" + +#: lib/php/monica/list.inc.php:2454 +msgid "Script" +msgstr "" + +#: lib/php/monica/list.inc.php:2455 +msgid "Privilege" +msgstr "" + +#: lib/php/monica/list.inc.php:2493 +msgid "Add a new script privilege record." +msgstr "" + +#: lib/php/monica/list.inc.php:2503 +msgid "Search for a script privilege record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2521 +#, c-format +msgid "Your query found %s script privilege record." +msgid_plural "Your query found %s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2528 +#, c-format +msgid "%s script privilege record." +msgid_plural "%s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2537 +#, c-format +msgid "Your query found %s script privilege record, listing %s to %s." +msgid_plural "Your query found %s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2546 +#, c-format +msgid "%s script privilege record, listing %s to %s." +msgid_plural "%s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2566 +msgid "Select a User Preference" +msgstr "" + +#: lib/php/monica/list.inc.php:2567 +msgid "Manage User Preferences" +msgstr "" + +#: lib/php/monica/list.inc.php:2574 lib/php/monica/list.inc.php:2689 +msgid "User" +msgstr "" + +#: lib/php/monica/list.inc.php:2575 +msgid "Domain" +msgstr "" + +#: lib/php/monica/list.inc.php:2576 +msgid "Value" +msgstr "" + +#: lib/php/monica/list.inc.php:2610 +msgid "Add a new user preference." +msgstr "" + +#: lib/php/monica/list.inc.php:2620 +msgid "Search for a user preference:" +msgstr "" + +#: lib/php/monica/list.inc.php:2638 +#, c-format +msgid "Your query found %s user preference." +msgid_plural "Your query found %s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2645 +#, c-format +msgid "%s user preference." +msgid_plural "%s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2654 +#, c-format +msgid "Your query found %s user preference, listing %s to %s." +msgid_plural "Your query found %s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2663 +#, c-format +msgid "%s user preference, listing %s to %s." +msgid_plural "%s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2682 +msgid "Select a User Request" +msgstr "" + +#: lib/php/monica/list.inc.php:2683 +msgid "Manage User Requests" +msgstr "" + +#: lib/php/monica/list.inc.php:2688 +msgid "Type" +msgstr "" + +#: lib/php/monica/list.inc.php:2690 +msgid "Arguments" +msgstr "" + +#: lib/php/monica/list.inc.php:2691 +msgid "Expiration" +msgstr "" + +#: lib/php/monica/list.inc.php:2699 +msgid "Add a new user request." +msgstr "" + +#: lib/php/monica/list.inc.php:2709 +msgid "Search for a user request:" +msgstr "" + +#: lib/php/monica/list.inc.php:2727 +#, c-format +msgid "Your query found %s user request." +msgid_plural "Your query found %s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2734 +#, c-format +msgid "%s user request." +msgid_plural "%s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2743 +#, c-format +msgid "Your query found %s user request, listing %s to %s." +msgid_plural "Your query found %s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2752 +#, c-format +msgid "%s user request, listing %s to %s." +msgid_plural "%s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2778 +msgid "Add a new category." +msgstr "" + +#: lib/php/monica/list.inc.php:2788 +msgid "Search for a category:" +msgstr "" + +#: lib/php/monica/list.inc.php:2806 +#, c-format +msgid "Your query found %s category." +msgid_plural "Your query found %s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2813 +#, c-format +msgid "%s category." +msgid_plural "%s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2822 +#, c-format +msgid "Your query found %s category, listing %s to %s." +msgid_plural "Your query found %s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2831 +#, c-format +msgid "%s category, listing %s to %s." +msgid_plural "%s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2849 +msgid "Add a new categorization record." +msgstr "" + +#: lib/php/monica/list.inc.php:2859 +msgid "Search for a categorization record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2877 +#, c-format +msgid "Your query found %s categorization record." +msgid_plural "Your query found %s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2884 +#, c-format +msgid "%s categorization record." +msgid_plural "%s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2893 +#, c-format +msgid "Your query found %s categorization record, listing %s to %s." +msgid_plural "Your query found %s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2902 +#, c-format +msgid "%s categorization record, listing %s to %s." +msgid_plural "%s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2921 +msgid "Select a Page" +msgstr "" + +#: lib/php/monica/list.inc.php:2922 +msgid "Manage Pages" +msgstr "" + +#: lib/php/monica/list.inc.php:2952 lib/php/monica/list.inc.php:3066 +#: lib/php/monica/list.inc.php:3173 lib/php/monica/list.inc.php:3237 +#: lib/php/monica/list.inc.php:3358 +msgid "Hidden" +msgstr "" + +#: lib/php/monica/list.inc.php:2953 lib/php/monica/list.inc.php:3067 +#: lib/php/monica/list.inc.php:3174 lib/php/monica/list.inc.php:3238 +#: lib/php/monica/list.inc.php:3359 +msgid "Shown" +msgstr "" + +#: lib/php/monica/list.inc.php:2963 +msgid "Write a new page." +msgstr "" + +#: lib/php/monica/list.inc.php:2973 +msgid "Search for a page:" +msgstr "" + +#: lib/php/monica/list.inc.php:2991 +#, c-format +msgid "Your query found %s page." +msgid_plural "Your query found %s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2998 +#, c-format +msgid "%s page." +msgid_plural "%s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3007 +#, c-format +msgid "Your query found %s page, listing %s to %s." +msgid_plural "Your query found %s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3016 +#, c-format +msgid "%s page, listing %s to %s." +msgid_plural "%s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3035 +msgid "Select a News Article" +msgstr "" + +#: lib/php/monica/list.inc.php:3036 +msgid "Manage News" +msgstr "" + +#: lib/php/monica/list.inc.php:3077 +msgid "Write a new news article." +msgstr "" + +#: lib/php/monica/list.inc.php:3087 +msgid "Search for a news article:" +msgstr "" + +#: lib/php/monica/list.inc.php:3105 +#, c-format +msgid "Your query found %s news article." +msgid_plural "Your query found %s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3112 +#, c-format +msgid "%s news article." +msgid_plural "%s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3121 +#, c-format +msgid "Your query found %s news article, listing %s to %s." +msgid_plural "Your query found %s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3130 +#, c-format +msgid "%s news article, listing %s to %s." +msgid_plural "%s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3149 +msgid "Select a Link Category" +msgstr "" + +#: lib/php/monica/list.inc.php:3150 +msgid "Manage Link Categories" +msgstr "" + +#: lib/php/monica/list.inc.php:3197 +msgid "Select a Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3198 +msgid "Manage Links" +msgstr "" + +#: lib/php/monica/list.inc.php:3248 +msgid "Add a new related link." +msgstr "" + +#: lib/php/monica/list.inc.php:3258 +msgid "Search for a related link:" +msgstr "" + +#: lib/php/monica/list.inc.php:3276 +#, c-format +msgid "Your query found %s related link." +msgid_plural "Your query found %s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3283 +#, c-format +msgid "%s related link." +msgid_plural "%s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3292 +#, c-format +msgid "Your query found %s related link, listing %s to %s." +msgid_plural "Your query found %s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3301 +#, c-format +msgid "%s related link, listing %s to %s." +msgid_plural "%s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3321 +msgid "Select a Link Categorization Record" +msgstr "" + +#: lib/php/monica/list.inc.php:3322 +msgid "Manage Link Categorization" +msgstr "" + +#: lib/php/monica/list.inc.php:3327 +msgid "Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3383 +msgid "Select a Country" +msgstr "" + +#: lib/php/monica/list.inc.php:3384 +msgid "Manage Country Data" +msgstr "" + +#: lib/php/monica/list.inc.php:3389 +msgid "Code" +msgstr "" + +#: lib/php/monica/list.inc.php:3390 +msgid "Country name" +msgstr "" + +#: lib/php/monica/list.inc.php:3399 +msgid "Add a new country record." +msgstr "" + +#: lib/php/monica/list.inc.php:3409 +msgid "Search for a country:" +msgstr "" + +#: lib/php/monica/list.inc.php:3427 +#, c-format +msgid "Your query found %s country." +msgid_plural "Your query found %s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3434 +#, c-format +msgid "%s country." +msgid_plural "%s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3443 +#, c-format +msgid "Your query found %s country, listing %s to %s." +msgid_plural "Your query found %s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3452 +#, c-format +msgid "%s country, listing %s to %s." +msgid_plural "%s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3474 +msgid "Browse the Activity Log" +msgstr "" + +#: lib/php/monica/list.inc.php:3586 +msgid "Please fill in the number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3590 +#, c-format +msgid "This number of rows to display is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/list.inc.php:3595 +msgid "Please fill in a positive integer number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3599 lib/php/monica/list.inc.php:3609 +#, c-format +msgid "" +"The number of rows to display is too small. Please fill in a larger number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3613 +#, c-format +msgid "" +"The number of rows to display is too large. Please fill in a smaller number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3638 +msgid "Search for log entries:" +msgstr "" + +#: lib/php/monica/list.inc.php:3641 +msgid "Display" +msgstr "" + +#: lib/php/monica/list.inc.php:3654 +msgid "Display rows:" +msgstr "" + +#: lib/php/monica/list.inc.php:3677 +#, c-format +msgid "Your query found %s log entry." +msgid_plural "Your query found %s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3684 +#, c-format +msgid "%s log entry." +msgid_plural "%s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3693 +#, c-format +msgid "Your query found %s log entry, listing %s to %s." +msgid_plural "Your query found %s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3702 +#, c-format +msgid "%s log entry, listing %s to %s." +msgid_plural "%s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/lninfo.inc.php:28 +msgid "English" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:39 +msgid "Traditional Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:50 +msgid "Simplified Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:61 +msgid "Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:72 +msgid "Japanese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:83 +msgid "Korean" +msgstr "한국어" + +#: lib/php/monica/lninfo.inc.php:94 +msgid "German" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:105 +msgid "Spanish" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:366 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:738 +msgid "Web pages" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:739 +msgid "News" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:740 +msgid "Related links" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:741 +msgid "Home page" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:742 +msgid "Whole web site" +msgstr "" + +#: lib/php/monica/pic.inc.php:39 +msgid "Left-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:40 +msgid "Right-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:74 lib/php/monica/pic.inc.php:77 +#, c-format +msgid "This picture file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/pic.inc.php:92 +msgid "Please upload only PNG, JPEG or GIF files." +msgstr "" + +#: lib/php/monica/pic.inc.php:153 +#, c-format +msgid "Width: %d, height: %d, ratio: %0.2f" +msgstr "" + +#: lib/php/monica/pic.inc.php:176 +msgid "Please specify a numeric ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:180 +msgid "Please specify a positive ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:183 +#, c-format +msgid "Please specify a ratio less than or equal to %0.2f." +msgstr "" + +#: lib/php/monica/pic.inc.php:189 +msgid "This image is too large to display." +msgstr "" + +#: lib/php/monica/preview.inc.php:47 +#, c-format +msgid "Unknown preview source: \"%s\"." +msgstr "" + +#: lib/php/monica/preview.inc.php:67 +#, c-format +msgid "Unknown preview form: %d." +msgstr "" + +#: lib/php/monica/preview.inc.php:143 +msgid "Preview Mark Area" +msgstr "" + +#: lib/php/monica/preview.inc.php:148 +msgid "Finish preview and return." +msgstr "" + +#: lib/php/monica/process.inc.php:237 +msgid "This record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:243 +msgid "This record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:247 +msgid "This record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:251 +msgid "This record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:406 +msgid "This category was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:412 +msgid "This category has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:416 +msgid "This category has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:420 +msgid "This category has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:433 +msgid "This categorization record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:439 +msgid "This categorization record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:443 +msgid "This categorization record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:447 +msgid "This categorization record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:782 +msgid "This user account was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:788 +msgid "This user account has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:792 +msgid "This user account has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:796 +msgid "This user account has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1074 +msgid "This group was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1080 +msgid "This group has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1084 +msgid "This group has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1088 +msgid "This group has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1152 lib/php/monica/process.inc.php:1230 +msgid "This membership record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1158 lib/php/monica/process.inc.php:1236 +msgid "This membership record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1162 lib/php/monica/process.inc.php:1240 +msgid "This membership record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1166 lib/php/monica/process.inc.php:1244 +msgid "This membership record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1308 +msgid "This script privilege record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1314 +msgid "This script privilege record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1318 +msgid "This script privilege record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1322 +msgid "This script privilege record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1438 +msgid "This user preference was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1444 +msgid "This user preference has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1448 +msgid "This user preference has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1452 +msgid "This user preference has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1560 +msgid "This user request was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1566 +msgid "This user request has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1570 +msgid "This user request has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1574 +msgid "This user request has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1685 +msgid "This page was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1691 +msgid "This page has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1695 +msgid "This page has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1699 +msgid "This page has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1874 +msgid "This news article was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1880 +msgid "This news article has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1884 +msgid "This news article has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1888 +msgid "This news article has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1997 +msgid "This country was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2003 +msgid "This country has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2007 +msgid "This country has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2011 +msgid "This country has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:2097 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. (%0.3f seconds)" +msgstr "" + +#: lib/php/monica/process.inc.php:2158 +#, c-format +msgid "Welcome, %s!" +msgstr "" + +#: lib/php/monica/process.inc.php:2204 +msgid "You have successfully logged out." +msgstr "" + +#: lib/php/monica/process.inc.php:2439 +msgid "This related link was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2445 +msgid "This related link has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2449 +msgid "This related link has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2453 +msgid "This related link has been successfully deleted." +msgstr "" + +#: lib/php/monica/request.inc.php:38 +msgid "Please specify the request." +msgstr "" + +#: lib/php/monica/request.inc.php:46 lib/php/monica/request.inc.php:55 +#, c-format +msgid "Invalid request S/N: %s." +msgstr "" + +#: lib/php/monica/sitesize.inc.php:41 +#, c-format +msgid "Currently using files %s.\n" +msgstr "" + +#: lib/php/monica/sitesize.inc.php:46 +#, c-format +msgid "Currently using files %s, database %s, total %s.\n" +msgstr "" + +#: lib/php/monica/upload.inc.php:70 +#, c-format +msgid "MIME file type: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:71 +#, c-format +msgid "File name: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:72 +#, c-format +msgid "File size: %s bytes" +msgstr "" + +#: lib/php/monica/validate.inc.php:116 +msgid "HTML Validatior Logo Area" +msgstr "" + +#: lib/php/monica/validate.inc.php:117 +msgid "HTML validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:118 +#, c-format +msgid "Valid %s!" +msgstr "" + +#: lib/php/monica/validate.inc.php:119 +msgid "CSS validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:120 +msgid "Valid CSS!" +msgstr "" + +#: lib/php/monica/validate.inc.php:121 +msgid "Explanation of Level Triple-A Conformance" +msgstr "" + +#: lib/php/monica/validate.inc.php:122 +msgid "" +"Level Triple-A conformance icon, W3C-WAI Web Content Accessibility " +"Guidelines 1.0" +msgstr "" diff --git a/po/monica/ko_KR.pox b/po/monica/ko_KR.pox new file mode 100644 index 0000000..f6a5725 --- /dev/null +++ b/po/monica/ko_KR.pox @@ -0,0 +1,3296 @@ +# Korean PO file for the monica core +# Copyright (C) 2007-2018 Pristine Communcations +# This file is distributed under the same license as the monica package. +# imacat , 2007-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: monica 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 12:42+0800\n" +"PO-Revision-Date: 2018-11-02 01:22+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Korean \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: lib/php/monica/checker.inc.php:159 +msgid "Please select a user." +msgstr "" + +#: lib/php/monica/checker.inc.php:163 +msgid "This user does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:181 +msgid "Please select a group." +msgstr "" + +#: lib/php/monica/checker.inc.php:185 +msgid "This group does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:203 +msgid "Please fill in the script." +msgstr "" + +#: lib/php/monica/checker.inc.php:207 +#, c-format +msgid "This script is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:212 +msgid "This script is not a valid script. Please specify another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:230 +msgid "Please fill in the date." +msgstr "" + +#: lib/php/monica/checker.inc.php:234 lib/php/monica/checker.inc.php:238 +#: lib/php/monica/checker.inc.php:241 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "" + +#: lib/php/monica/checker.inc.php:259 +msgid "Please fill in the ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:263 +#, c-format +msgid "This ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:267 +#, c-format +msgid "This ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:272 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:294 +msgid "Please fill in the order." +msgstr "" + +#: lib/php/monica/checker.inc.php:298 +#, c-format +msgid "This order is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:303 +msgid "Please fill in a positive integer order." +msgstr "" + +#: lib/php/monica/checker.inc.php:307 lib/php/monica/checker.inc.php:317 +#, c-format +msgid "" +"The order is too small. Please fill in a larger order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:321 +#, c-format +msgid "" +"The order is too large. Please fill in a smaller order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:348 +msgid "Please fill in the page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:352 +#, c-format +msgid "This page path is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:365 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:369 +msgid "Please fill in an absolute page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:373 +msgid "Please fill in a valid page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:377 +msgid "You cannot overwrite the cover home page." +msgstr "" + +#: lib/php/monica/checker.inc.php:381 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "" + +#: lib/php/monica/checker.inc.php:422 lib/php/monica/checker.inc.php:428 +msgid "Please fill in the attachment description." +msgstr "" + +#: lib/php/monica/checker.inc.php:432 +#, c-format +msgid "This attachment description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:449 +msgid "This PDF. file does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:456 +#, c-format +msgid "This PDF. file is too large. (Max. size %s)" +msgstr "" + +#: lib/php/monica/checker.inc.php:461 +msgid "Please upload only PDF. file." +msgstr "" + +#: lib/php/monica/checker.inc.php:479 +msgid "Please fill in the title." +msgstr "" + +#: lib/php/monica/checker.inc.php:483 +#, c-format +msgid "This title is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:502 +msgid "Please fill in the subject." +msgstr "" + +#: lib/php/monica/checker.inc.php:506 +#, c-format +msgid "This subject is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:524 lib/php/monica/form.inc.php:3159 +#: lib/php/monica/form.inc.php:3172 +msgid "Fill in the content here." +msgstr "" + +#: lib/php/monica/checker.inc.php:528 +msgid "Please fill in the content." +msgstr "" + +#: lib/php/monica/checker.inc.php:532 +#, c-format +msgid "This content is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:551 +msgid "Please fill in the keywords." +msgstr "" + +#: lib/php/monica/checker.inc.php:555 +#, c-format +msgid "This keyword list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:572 +msgid "Please select a proper pinyin." +msgstr "" + +#: lib/php/monica/checker.inc.php:578 +#, c-format +msgid "This pinyin is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:583 +msgid "" +"This pinyin does not match the Chinese. Please select a proper pinyin from " +"the list." +msgstr "" + +#: lib/php/monica/checker.inc.php:609 lib/php/monica/pic.inc.php:82 +msgid "Please upload the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:616 lib/php/monica/checker.inc.php:3214 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:622 +#, c-format +msgid "This picture is too large. Please upload another one. (Max. size %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:639 lib/php/monica/form.inc.php:3588 +#, c-format +msgid "Please upload a new picture from %s." +msgstr "" + +#: lib/php/monica/checker.inc.php:664 lib/php/monica/checker.inc.php:727 +msgid "Please fill in the picture caption." +msgstr "" + +#: lib/php/monica/checker.inc.php:668 lib/php/monica/checker.inc.php:731 +#, c-format +msgid "This picture caption is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:686 lib/php/monica/checker.inc.php:749 +msgid "Please select the picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:692 lib/php/monica/checker.inc.php:755 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:791 lib/php/monica/checker.inc.php:794 +#, c-format +msgid "Your uploaded file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/checker.inc.php:797 lib/php/monica/pic.inc.php:80 +msgid "" +"Upload not completed. Disk may be full or connection may be closed in the " +"half. You may try to upload again, or contact the system administrator for " +"this problem." +msgstr "" + +#: lib/php/monica/checker.inc.php:799 lib/php/monica/pic.inc.php:84 +#, c-format +msgid "Upload failed with an unknown error (%d)." +msgstr "" + +#: lib/php/monica/checker.inc.php:1183 lib/php/monica/chkfunc.inc.php:59 +#: lib/php/monica/chkfunc.inc.php:72 lib/php/monica/preview.inc.php:29 +#, c-format +msgid "The following field was not received: \"%s\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:1262 +msgid "Please fill in the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1266 +#, c-format +msgid "This user ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1270 +#, c-format +msgid "This user ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1275 +msgid "" +"Only lower-case English letters, numbers, at-signs, dots, dashes and " +"underscores are allowed for the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1287 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1317 +msgid "Please fill in the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1320 +msgid "Please confirm the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1324 +#, c-format +msgid "This password is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1329 +#, c-format +msgid "This password is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1334 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "" + +#: lib/php/monica/checker.inc.php:1345 +msgid "This password is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1360 +msgid "This password does not contain enough different characters." +msgstr "" + +#: lib/php/monica/checker.inc.php:1364 +msgid "This password is too simplistic/systematic." +msgstr "" + +#: lib/php/monica/checker.inc.php:1368 +msgid "This password is based on a dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1370 +msgid "This password is based on a (reversed) dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1372 +msgid "This password is too simple." +msgstr "" + +#: lib/php/monica/checker.inc.php:1378 +msgid "You cannot use a password that is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1397 +msgid "Please fill in the name." +msgstr "" + +#: lib/php/monica/checker.inc.php:1401 +#, c-format +msgid "This name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1420 +msgid "Please fill in the e-mail." +msgstr "" + +#: lib/php/monica/checker.inc.php:1424 +#, c-format +msgid "This e-mail is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1428 +#, c-format +msgid "This e-mail is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1437 +msgid "Please fill in a valid e-mail address." +msgstr "" + +#: lib/php/monica/checker.inc.php:1439 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:1461 lib/php/monica/checker.inc.php:1655 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1478 +msgid "You cannot submit the super-user group along with other groups." +msgstr "" + +#: lib/php/monica/checker.inc.php:1480 +msgid "You cannot set the administrators group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1482 +msgid "You cannot set the all-users group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1515 +msgid "Please fill in the group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1519 +#, c-format +msgid "This group ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1523 +#, c-format +msgid "This group ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1528 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1540 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1558 +msgid "Please fill in the privilege description." +msgstr "" + +#: lib/php/monica/checker.inc.php:1562 +#, c-format +msgid "This privilege description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1585 +msgid "This user member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1620 +msgid "This group member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1747 lib/php/monica/checker.inc.php:1855 +msgid "Please select a member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1751 lib/php/monica/checker.inc.php:1859 +msgid "This member does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1770 lib/php/monica/checker.inc.php:1883 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1837 +msgid "Please select a different belonging group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1864 +msgid "Please select a different group member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1958 +msgid "" +"This script privilege already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1996 lib/php/monica/checker.inc.php:2184 +msgid "Please select the user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2002 lib/php/monica/checker.inc.php:2190 +msgid "This option is invalid. Please select a proper user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2020 +msgid "Please set the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2026 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2039 lib/php/monica/checker.inc.php:2295 +msgid "Please fill in the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2043 lib/php/monica/checker.inc.php:2299 +#, c-format +msgid "This preference domain is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2063 +msgid "Please fill in the preference name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2067 +#, c-format +msgid "This preference name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2086 +msgid "Please fill in the preference value." +msgstr "" + +#: lib/php/monica/checker.inc.php:2090 +#, c-format +msgid "This preference value is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2119 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2167 +msgid "Please select the request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2173 +msgid "This option is invalid. Please select a proper request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2194 +msgid "You must choose anonymous for join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2197 +msgid "You cannot choose anonymous for non-join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2221 lib/php/monica/form.inc.php:5484 +msgid "Please fill in the request arguments list here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2229 +#, c-format +msgid "This request arguments list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2349 +msgid "Please fill in the number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2353 +#, c-format +msgid "This number of rows per page is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2358 +msgid "Please fill in a positive integer number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2362 lib/php/monica/checker.inc.php:2372 +#, c-format +msgid "" +"The number of rows per page is too small. Please fill in a larger number of " +"rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2376 +#, c-format +msgid "" +"The number of rows per page is too large. Please fill in a smaller number " +"of rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2443 +msgid "Please fill in your user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:2451 lib/php/monica/checker.inc.php:2458 +#: lib/php/monica/checker.inc.php:2475 lib/php/monica/checker.inc.php:2508 +#: lib/php/monica/checker.inc.php:2540 lib/php/monica/checker.inc.php:2548 +#: lib/php/monica/checker.inc.php:2558 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "" + +#: lib/php/monica/checker.inc.php:2495 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "" + +#: lib/php/monica/checker.inc.php:2531 +msgid "Please fill in your password." +msgstr "" + +#: lib/php/monica/checker.inc.php:2581 +msgid "You are not an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2600 +msgid "You are an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2751 +msgid "Please fill in the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2755 +#, c-format +msgid "You must fill in a %d-letters code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2760 +msgid "You can only use upper letters and for the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2772 +msgid "This code is duplicated. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2790 +msgid "Please fill in the country name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2794 +#, c-format +msgid "This country name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2822 lib/php/monica/checker.inc.php:2841 +msgid "Please select a parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2828 +msgid "This option is invalid. Please select a proper parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2845 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2850 +msgid "A category cannot belong to itself. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2858 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2876 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:2894 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2941 +msgid "Please fill in the URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2945 +#, c-format +msgid "This URL. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2950 +msgid "Please fill in a valid URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2962 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2967 +msgid "This URL. is not reachable. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:2984 lib/php/monica/form.inc.php:3261 +msgid "Fill in the description here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2988 +msgid "Please fill in the description." +msgstr "" + +#: lib/php/monica/checker.inc.php:2992 +#, c-format +msgid "This description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:3012 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:3016 lib/php/monica/checker.inc.php:3072 +msgid "This category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3022 lib/php/monica/checker.inc.php:3068 +msgid "Please select a category." +msgstr "" + +#: lib/php/monica/checker.inc.php:3090 +msgid "Please select a related link." +msgstr "" + +#: lib/php/monica/checker.inc.php:3094 +msgid "This link does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3113 +msgid "" +"This link categorization already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3154 +msgid "Please select the type." +msgstr "" + +#: lib/php/monica/checker.inc.php:3158 +msgid "This type does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3185 lib/php/monica/list.inc.php:961 +msgid "Please fill in your query." +msgstr "" + +#: lib/php/monica/checker.inc.php:3210 +msgid "Please submit the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:3237 lib/php/monica/checker.inc.php:3328 +msgid "Please fill in the resize ratio." +msgstr "" + +#: lib/php/monica/checker.inc.php:3305 +msgid "Please specify a valid picture." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:156 lib/php/monica/chkfunc.inc.php:160 +#: lib/php/monica/chkfunc.inc.php:163 lib/php/monica/chkfunc.inc.php:166 +msgid "Please select a legal year." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:171 lib/php/monica/chkfunc.inc.php:175 +#: lib/php/monica/chkfunc.inc.php:178 +msgid "Please select a legal month." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:183 lib/php/monica/chkfunc.inc.php:187 +#: lib/php/monica/chkfunc.inc.php:193 +msgid "Please select a legal day." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:27 +#, c-format +msgid "%s: It is not a file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:32 +#, c-format +msgid "%s: You have no permission to overwrite this file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:45 +#, c-format +msgid "%s: You cannot create anything under the root directory." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:50 +#, c-format +msgid "" +"%s: One of the parents of this file (%s) is not a directory. You cannot " +"create any new file inside." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:55 +#, c-format +msgid "%s: You have no permission to create any file under %s." +msgstr "" + +#: lib/php/monica/commtext.inc.php:18 +msgid "(not set)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:24 +msgid "(none)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:30 +msgid "(N/A)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:36 +msgid "(blank)" +msgstr "" + +#: lib/php/monica/echoform.inc.php:173 +#, c-format +msgid "%s bytes" +msgstr "" + +#: lib/php/monica/form.inc.php:168 +msgid "Delete it" +msgstr "" + +#: lib/php/monica/form.inc.php:174 +msgid "Are you sure you want to delete it? It cannot be recovered." +msgstr "" + +#: lib/php/monica/form.inc.php:188 +msgid "*" +msgstr "" + +#: lib/php/monica/form.inc.php:224 +msgid "This table provides you a form to add a new data record." +msgstr "" + +#: lib/php/monica/form.inc.php:228 +msgid "This table provides you a form to update a current data record." +msgstr "" + +#: lib/php/monica/form.inc.php:232 +msgid "This table provides you a form to delete a data record." +msgstr "" + +#: lib/php/monica/form.inc.php:281 +msgid "Add a New Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:285 +msgid "Update a Current Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:289 +msgid "Delete a Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:301 +msgid "Preview it." +msgstr "" + +#: lib/php/monica/form.inc.php:500 lib/php/monica/form.inc.php:506 +#: lib/php/monica/form.inc.php:691 lib/php/monica/form.inc.php:697 +#: lib/php/monica/preview.inc.php:146 +msgid "Preview" +msgstr "" + +#: lib/php/monica/form.inc.php:501 lib/php/monica/form.inc.php:507 +#: lib/php/monica/form.inc.php:692 lib/php/monica/form.inc.php:698 +msgid "Confirm and submit" +msgstr "" + +#: lib/php/monica/form.inc.php:708 lib/php/monica/form.inc.php:1692 +#: lib/php/monica/form.inc.php:1778 lib/php/monica/list.inc.php:1809 +msgid "Delete" +msgstr "" + +#: lib/php/monica/form.inc.php:709 lib/php/monica/form.inc.php:6419 +#: lib/php/monica/form.inc.php:6470 +msgid "Cancel" +msgstr "" + +#: lib/php/monica/form.inc.php:1042 lib/php/monica/form.inc.php:3499 +msgid "Set the picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1043 lib/php/monica/form.inc.php:3031 +#: lib/php/monica/form.inc.php:3500 +msgid "Delete this picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1048 lib/php/monica/form.inc.php:1178 +#: lib/php/monica/form.inc.php:3037 lib/php/monica/form.inc.php:3104 +#: lib/php/monica/form.inc.php:3505 lib/php/monica/form.inc.php:3677 +#: lib/php/monica/form.inc.php:6163 lib/php/monica/list.inc.php:814 +msgid "Picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1059 lib/php/monica/form.inc.php:1109 +#: lib/php/monica/form.inc.php:1185 +#, c-format +msgid "Picture #%d:" +msgstr "" + +#: lib/php/monica/form.inc.php:1080 lib/php/monica/form.inc.php:1131 +#: lib/php/monica/form.inc.php:1166 lib/php/monica/form.inc.php:1199 +msgid "Caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:1092 lib/php/monica/form.inc.php:3064 +#: lib/php/monica/form.inc.php:3566 lib/php/monica/form.inc.php:6183 +msgid "Original picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1093 lib/php/monica/form.inc.php:3065 +#: lib/php/monica/form.inc.php:3567 lib/php/monica/form.inc.php:6197 +msgid "New picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1113 lib/php/monica/form.inc.php:1276 +#: lib/php/monica/form.inc.php:1363 lib/php/monica/form.inc.php:1451 +#: lib/php/monica/form.inc.php:1560 lib/php/monica/form.inc.php:1650 +#: lib/php/monica/form.inc.php:1727 lib/php/monica/form.inc.php:1825 +#: lib/php/monica/form.inc.php:1916 lib/php/monica/form.inc.php:1977 +#: lib/php/monica/form.inc.php:2053 lib/php/monica/form.inc.php:2159 +#: lib/php/monica/form.inc.php:2391 lib/php/monica/form.inc.php:2592 +#: lib/php/monica/form.inc.php:2689 lib/php/monica/form.inc.php:2800 +#: lib/php/monica/form.inc.php:2897 lib/php/monica/form.inc.php:2980 +#: lib/php/monica/form.inc.php:3069 lib/php/monica/form.inc.php:3200 +#: lib/php/monica/form.inc.php:3571 lib/php/monica/form.inc.php:3627 +#: lib/php/monica/form.inc.php:3640 lib/php/monica/form.inc.php:3747 +#: lib/php/monica/form.inc.php:4423 lib/php/monica/form.inc.php:4533 +#: lib/php/monica/form.inc.php:4729 lib/php/monica/form.inc.php:4866 +#: lib/php/monica/form.inc.php:5000 lib/php/monica/form.inc.php:6176 +#: lib/php/monica/form.inc.php:6243 +msgid "Original:" +msgstr "" + +#: lib/php/monica/form.inc.php:1141 lib/php/monica/form.inc.php:1281 +#: lib/php/monica/form.inc.php:1369 lib/php/monica/form.inc.php:1456 +#: lib/php/monica/form.inc.php:1575 lib/php/monica/form.inc.php:1655 +#: lib/php/monica/form.inc.php:1732 lib/php/monica/form.inc.php:1832 +#: lib/php/monica/form.inc.php:1921 lib/php/monica/form.inc.php:1982 +#: lib/php/monica/form.inc.php:2065 lib/php/monica/form.inc.php:2173 +#: lib/php/monica/form.inc.php:2422 lib/php/monica/form.inc.php:2597 +#: lib/php/monica/form.inc.php:2694 lib/php/monica/form.inc.php:2805 +#: lib/php/monica/form.inc.php:2902 lib/php/monica/form.inc.php:2985 +#: lib/php/monica/form.inc.php:3080 lib/php/monica/form.inc.php:3205 +#: lib/php/monica/form.inc.php:3584 lib/php/monica/form.inc.php:3632 +#: lib/php/monica/form.inc.php:3649 lib/php/monica/form.inc.php:3752 +#: lib/php/monica/form.inc.php:4442 lib/php/monica/form.inc.php:4543 +#: lib/php/monica/form.inc.php:4742 lib/php/monica/form.inc.php:4879 +#: lib/php/monica/form.inc.php:5013 lib/php/monica/form.inc.php:6188 +#: lib/php/monica/form.inc.php:6248 lib/php/monica/form.inc.php:6278 +msgid "New:" +msgstr "" + +#: lib/php/monica/form.inc.php:1269 lib/php/monica/form.inc.php:1444 +#: lib/php/monica/form.inc.php:1543 lib/php/monica/form.inc.php:2358 +#: lib/php/monica/form.inc.php:2585 lib/php/monica/form.inc.php:2793 +#: lib/php/monica/form.inc.php:2890 lib/php/monica/form.inc.php:2973 +#: lib/php/monica/form.inc.php:3620 +msgid "Source:" +msgstr "" + +#: lib/php/monica/form.inc.php:1289 lib/php/monica/form.inc.php:1464 +#: lib/php/monica/form.inc.php:1583 lib/php/monica/form.inc.php:2605 +#: lib/php/monica/form.inc.php:2813 lib/php/monica/form.inc.php:2910 +#: lib/php/monica/form.inc.php:2993 +#, c-format +msgid "Please set it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:1501 +msgid "Hide" +msgstr "" + +#: lib/php/monica/form.inc.php:1502 +msgid "Show" +msgstr "" + +#: lib/php/monica/form.inc.php:1691 lib/php/monica/form.inc.php:1777 +#: lib/php/monica/form.inc.php:1887 +msgid "Choose" +msgstr "" + +#: lib/php/monica/form.inc.php:2237 +msgid "Delete this file" +msgstr "" + +#: lib/php/monica/form.inc.php:2267 lib/php/monica/form.inc.php:2368 +#: lib/php/monica/form.inc.php:2400 lib/php/monica/form.inc.php:2445 +#: lib/php/monica/form.inc.php:2506 +msgid "File name:" +msgstr "" + +#: lib/php/monica/form.inc.php:2274 lib/php/monica/form.inc.php:2375 +#: lib/php/monica/form.inc.php:2407 lib/php/monica/form.inc.php:2452 +#: lib/php/monica/form.inc.php:2513 +msgid "MIME file type:" +msgstr "" + +#: lib/php/monica/form.inc.php:2279 lib/php/monica/form.inc.php:2380 +#: lib/php/monica/form.inc.php:2412 lib/php/monica/form.inc.php:2457 +#: lib/php/monica/form.inc.php:2518 +msgid "File size:" +msgstr "" + +#: lib/php/monica/form.inc.php:2430 +#, c-format +msgid "Please upload it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:3128 +msgid "Address:" +msgstr "" + +#: lib/php/monica/form.inc.php:3129 +msgid "Fill in your address here." +msgstr "" + +#: lib/php/monica/form.inc.php:3135 +msgid "Attachment:" +msgstr "" + +#: lib/php/monica/form.inc.php:3139 +msgid "Attachment description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3158 lib/php/monica/form.inc.php:3171 +msgid "Content:" +msgstr "" + +#: lib/php/monica/form.inc.php:3165 +msgid "City:" +msgstr "" + +#: lib/php/monica/form.inc.php:3187 lib/php/monica/form.inc.php:3199 +#: lib/php/monica/form.inc.php:3217 lib/php/monica/form.inc.php:3241 +msgid "Country:" +msgstr "" + +#: lib/php/monica/form.inc.php:3229 +msgid "Created:" +msgstr "" + +#: lib/php/monica/form.inc.php:3235 +msgid "Created by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3247 +msgid "Date:" +msgstr "" + +#: lib/php/monica/form.inc.php:3253 lib/php/monica/form.inc.php:4292 +#: lib/php/monica/form.inc.php:4295 lib/php/monica/list.inc.php:310 +msgid "Disabled?" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 lib/php/monica/list.inc.php:2020 +msgid "Disabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 +msgid "Enabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 +msgid "Disable it." +msgstr "" + +#: lib/php/monica/form.inc.php:3260 lib/php/monica/form.inc.php:4657 +msgid "Description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3267 +msgid "E-mail:" +msgstr "" + +#: lib/php/monica/form.inc.php:3273 +msgid "Fax:" +msgstr "" + +#: lib/php/monica/form.inc.php:3279 +msgid "Group:" +msgstr "" + +#: lib/php/monica/form.inc.php:3285 lib/php/monica/form.inc.php:5541 +#: lib/php/monica/form.inc.php:5747 lib/php/monica/form.inc.php:5905 +#: lib/php/monica/form.inc.php:5998 +msgid "Hide?" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Show it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it currently." +msgstr "" + +#: lib/php/monica/form.inc.php:3292 +msgid "Host:" +msgstr "" + +#: lib/php/monica/form.inc.php:3298 lib/php/monica/list.inc.php:314 +msgid "HTML?" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2948 +#: lib/php/monica/list.inc.php:3062 +msgid "HTML" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2949 +#: lib/php/monica/list.inc.php:3063 +msgid "Plain text" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 +msgid "The submitted content is HTML." +msgstr "" + +#: lib/php/monica/form.inc.php:3305 lib/php/monica/form.inc.php:5535 +#: lib/php/monica/form.inc.php:6074 +msgid "ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3311 +msgid "Introduction:" +msgstr "" + +#: lib/php/monica/form.inc.php:3312 +msgid "Fill in the introduction here." +msgstr "" + +#: lib/php/monica/form.inc.php:3318 +msgid "IP:" +msgstr "" + +#: lib/php/monica/form.inc.php:3324 +msgid "Keywords:" +msgstr "" + +#: lib/php/monica/form.inc.php:3330 +msgid "Language:" +msgstr "" + +#: lib/php/monica/form.inc.php:3355 +msgid "Name:" +msgstr "" + +#: lib/php/monica/form.inc.php:3365 lib/php/monica/form.inc.php:5992 +msgid "Order:" +msgstr "" + +#: lib/php/monica/form.inc.php:3371 +msgid "Organization:" +msgstr "" + +#: lib/php/monica/form.inc.php:3377 +msgid "Parent category:" +msgstr "" + +#: lib/php/monica/form.inc.php:3378 +msgid "At the very top" +msgstr "" + +#: lib/php/monica/form.inc.php:3391 lib/php/monica/form.inc.php:3428 +#: lib/php/monica/form.inc.php:3468 lib/php/monica/form.inc.php:4330 +#: lib/php/monica/form.inc.php:6362 +msgid "Password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3407 lib/php/monica/form.inc.php:3444 +msgid "Confirm password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3458 +msgid "(Leave them blank if you don't plan to change your password.)" +msgstr "" + +#: lib/php/monica/form.inc.php:3484 +msgid "Page path:" +msgstr "" + +#: lib/php/monica/form.inc.php:3490 +msgid "PDF. file:" +msgstr "" + +#: lib/php/monica/form.inc.php:3508 lib/php/monica/form.inc.php:3570 +#: lib/php/monica/form.inc.php:3680 lib/php/monica/form.inc.php:6151 +#: lib/php/monica/form.inc.php:6175 +msgid "Picture:" +msgstr "" + +#: lib/php/monica/form.inc.php:3531 lib/php/monica/form.inc.php:3615 +#: lib/php/monica/form.inc.php:3619 lib/php/monica/form.inc.php:3693 +msgid "Pic. caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:3538 lib/php/monica/form.inc.php:3639 +#: lib/php/monica/form.inc.php:3699 +msgid "Pic. position:" +msgstr "" + +#: lib/php/monica/form.inc.php:3718 lib/php/monica/form.inc.php:3746 +#: lib/php/monica/form.inc.php:3780 +msgid "Pinyin:" +msgstr "" + +#: lib/php/monica/form.inc.php:3722 lib/php/monica/form.inc.php:3756 +msgid "Please fill in the Chinese first." +msgstr "" + +#: lib/php/monica/form.inc.php:3801 +msgid "Subcategory:" +msgid_plural "Subcategories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:3823 +msgid "Script:" +msgstr "" + +#: lib/php/monica/form.inc.php:3829 +msgid "S/N:" +msgstr "" + +#: lib/php/monica/form.inc.php:3835 +msgid "Street:" +msgstr "" + +#: lib/php/monica/form.inc.php:3841 +msgid "Subject:" +msgstr "" + +#: lib/php/monica/form.inc.php:3847 +msgid "Telephone:" +msgstr "" + +#: lib/php/monica/form.inc.php:3853 +msgid "Tel. (cell.):" +msgstr "" + +#: lib/php/monica/form.inc.php:3859 +msgid "Tel. (home):" +msgstr "" + +#: lib/php/monica/form.inc.php:3865 +msgid "Tel. (office):" +msgstr "" + +#: lib/php/monica/form.inc.php:3871 +msgid "Title:" +msgstr "" + +#: lib/php/monica/form.inc.php:3891 +msgid "Value:" +msgstr "" + +#: lib/php/monica/form.inc.php:3897 +msgid "Visits:" +msgstr "" + +#: lib/php/monica/form.inc.php:3903 +msgid "Visited:" +msgstr "" + +#: lib/php/monica/form.inc.php:3909 +msgid "Updated:" +msgstr "" + +#: lib/php/monica/form.inc.php:3915 +msgid "Updated by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3921 +msgid "URL.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3927 +msgid "Zip code:" +msgstr "" + +#: lib/php/monica/form.inc.php:4151 +msgid "Delete this user account" +msgstr "" + +#: lib/php/monica/form.inc.php:4157 +msgid "This table provides you a form to add a new user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4161 +msgid "This table provides you a form to update a current user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4165 +msgid "This table provides you a form to delete a user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4192 +msgid "Add a New User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4196 +msgid "Update a Current User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4200 +msgid "Delete a User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4213 +msgid "This is a super-user. You can only change parts of her infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4220 +msgid "" +"This user has a datum. It cannot be deleted. To delete the user, its datum " +"must first be deleted." +msgid_plural "" +"This user has data. It cannot be deleted. To delete the user, all of its " +"data must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4282 +msgid "Administrator?" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Non-administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4296 +msgid "Disable this user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4305 lib/php/monica/form.inc.php:4307 +#: lib/php/monica/form.inc.php:6354 +msgid "User ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4314 +msgid "Pref. language:" +msgstr "" + +#: lib/php/monica/form.inc.php:4320 +msgid "Full name:" +msgstr "" + +#: lib/php/monica/form.inc.php:4348 lib/php/monica/form.inc.php:4400 +#: lib/php/monica/form.inc.php:4422 lib/php/monica/form.inc.php:4496 +#: lib/php/monica/form.inc.php:4944 lib/php/monica/form.inc.php:4983 +#: lib/php/monica/form.inc.php:4999 lib/php/monica/form.inc.php:5051 +msgid "Belonging to:" +msgstr "" + +#: lib/php/monica/form.inc.php:4532 lib/php/monica/form.inc.php:4554 +msgid "Fail logins:" +msgstr "" + +#: lib/php/monica/form.inc.php:4539 lib/php/monica/form.inc.php:4560 +msgid "(Locked)" +msgstr "" + +#: lib/php/monica/form.inc.php:4585 +msgid "Delete this group" +msgstr "" + +#: lib/php/monica/form.inc.php:4591 +msgid "This table provides you a form to add a new group." +msgstr "" + +#: lib/php/monica/form.inc.php:4595 +msgid "This table provides you a form to update a current group." +msgstr "" + +#: lib/php/monica/form.inc.php:4599 +msgid "This table provides you a form to delete a group." +msgstr "" + +#: lib/php/monica/form.inc.php:4624 +msgid "Add a New Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4628 +msgid "Update a Current Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4632 +msgid "Delete a Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4639 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4648 lib/php/monica/form.inc.php:4650 +msgid "Group ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4663 +msgid "Add a user" +msgstr "" + +#: lib/php/monica/form.inc.php:4670 lib/php/monica/form.inc.php:4710 +#: lib/php/monica/form.inc.php:4728 lib/php/monica/form.inc.php:4781 +msgid "User member:" +msgid_plural "User members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4801 lib/php/monica/form.inc.php:4938 +msgid "Add a group" +msgstr "" + +#: lib/php/monica/form.inc.php:4808 lib/php/monica/form.inc.php:4848 +#: lib/php/monica/form.inc.php:4865 lib/php/monica/form.inc.php:4918 +msgid "Group member:" +msgid_plural "Group members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5085 lib/php/monica/form.inc.php:5160 +msgid "Delete this membership record" +msgstr "" + +#: lib/php/monica/form.inc.php:5091 lib/php/monica/form.inc.php:5166 +msgid "This table provides you a form to add a new membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5095 lib/php/monica/form.inc.php:5170 +msgid "This table provides you a form to change a current membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5099 lib/php/monica/form.inc.php:5174 +msgid "This table provides you a form to delete a membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5122 +msgid "Add a New User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5126 +msgid "Change a Current User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5130 +msgid "Delete a User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5140 lib/php/monica/form.inc.php:5215 +msgid "Member:" +msgstr "" + +#: lib/php/monica/form.inc.php:5197 +msgid "Add a New Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5201 +msgid "Change a Current Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5205 +msgid "Delete a Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5235 +msgid "Delete this user preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5241 +msgid "This table provides you a form to add a new user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5245 +msgid "This table provides you a form to modify a current user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5249 +msgid "This table provides you a form to delete a user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5272 +msgid "Add a New User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5276 +msgid "Modify a Current User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5280 +msgid "Delete a User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5290 lib/php/monica/form.inc.php:5476 +msgid "User:" +msgstr "" + +#: lib/php/monica/form.inc.php:5291 lib/php/monica/list.inc.php:2588 +msgid "Everyone" +msgstr "" + +#: lib/php/monica/form.inc.php:5297 +msgid "Domain:" +msgstr "" + +#: lib/php/monica/form.inc.php:5298 lib/php/monica/list.inc.php:2592 +msgid "Everywhere" +msgstr "" + +#: lib/php/monica/form.inc.php:5318 +msgid "Delete this script privilege record" +msgstr "" + +#: lib/php/monica/form.inc.php:5324 +msgid "This table provides you a form to add a new script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5328 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5332 +msgid "This table provides you a form to delete a script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5355 +msgid "Add a New Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5359 +msgid "Change a Current Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5363 +msgid "Delete a Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5373 +msgid "Privilege:" +msgstr "" + +#: lib/php/monica/form.inc.php:5395 +msgid "Delete this user request" +msgstr "" + +#: lib/php/monica/form.inc.php:5401 +msgid "This table provides you a form to add a new user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5405 +msgid "This table provides you a form to update a current user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5409 +msgid "This table provides you a form to delete a user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5432 +msgid "Add a New User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5436 +msgid "Update a Current User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5440 +msgid "Delete a User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5448 +msgid "Join" +msgstr "" + +#: lib/php/monica/form.inc.php:5452 +msgid "Change e-mail" +msgstr "" + +#: lib/php/monica/form.inc.php:5456 +msgid "Reset password" +msgstr "" + +#: lib/php/monica/form.inc.php:5464 +msgid "Expiration:" +msgstr "" + +#: lib/php/monica/form.inc.php:5470 lib/php/monica/form.inc.php:6432 +msgid "Type:" +msgstr "" + +#: lib/php/monica/form.inc.php:5477 +msgid "Anonymous" +msgstr "" + +#: lib/php/monica/form.inc.php:5483 +msgid "Arguments:" +msgstr "" + +#: lib/php/monica/form.inc.php:5501 +msgid "Delete this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5507 +msgid "This table provides you a form to add a new category." +msgstr "" + +#: lib/php/monica/form.inc.php:5511 +msgid "This table provides you a form to edit a current category." +msgstr "" + +#: lib/php/monica/form.inc.php:5515 +msgid "This table provides you a form to delete a category." +msgstr "" + +#: lib/php/monica/form.inc.php:5525 +msgid "" +"This category has a subcategory. It cannot be deleted. To delete the " +"category, its subcategory must first be deleted." +msgid_plural "" +"This category has subcategories. It cannot be deleted. To delete the " +"category, all of its subcategories must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Show this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "Hide this category currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5559 +msgid "Delete this categorization record" +msgstr "" + +#: lib/php/monica/form.inc.php:5565 +msgid "This table provides you a form to add a new categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5569 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5573 +msgid "This table provides you a form to delete a categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5618 +msgid "Add a New Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5622 +msgid "Edit a Current Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5626 +msgid "Delete a Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5636 +msgid "" +"This category has a link. It cannot be deleted. To delete the category, " +"its link must first be deleted." +msgid_plural "" +"This category has links. It cannot be deleted. To delete the category, all " +"of its links must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5655 lib/php/monica/form.inc.php:5819 +msgid "Link:" +msgid_plural "Links:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5692 +msgid "Delete this related link" +msgstr "" + +#: lib/php/monica/form.inc.php:5698 +msgid "This table provides you a form to add a new related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5702 +msgid "This table provides you a form to edit a current related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5706 +msgid "This table provides you a form to delete a related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5729 +msgid "Add a New Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5733 +msgid "Edit a Current Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5737 +msgid "Delete a Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this link" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 lib/php/monica/form.inc.php:5906 +msgid "Show this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5748 +msgid "Hide this related link currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5755 lib/php/monica/form.inc.php:5812 +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5794 +msgid "Add a New Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5798 +msgid "Change a Current Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5802 +msgid "Delete a Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5842 +msgid "Delete this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5848 +msgid "This table provides you a form to write a new page." +msgstr "" + +#: lib/php/monica/form.inc.php:5852 +msgid "This table provides you a form to edit a current page." +msgstr "" + +#: lib/php/monica/form.inc.php:5856 +msgid "This table provides you a form to delete a page." +msgstr "" + +#: lib/php/monica/form.inc.php:5881 +msgid "Write a New Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5885 +msgid "Edit a Current Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5889 +msgid "Delete a Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5897 +msgid "Preview this page." +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Hide this page currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5929 +msgid "Delete this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5935 +msgid "This table provides you a form to write a new news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5939 +msgid "This table provides you a form to edit a current news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5943 +msgid "This table provides you a form to delete a news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5968 +msgid "Write a New News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5972 +msgid "Edit a Current News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5976 +msgid "Delete a News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5984 +msgid "Preview this news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Show this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5999 +msgid "Hide this news article currently." +msgstr "" + +#: lib/php/monica/form.inc.php:6019 +msgid "Delete this country record" +msgstr "" + +#: lib/php/monica/form.inc.php:6025 +msgid "This table provides you a form to add a new country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6029 +msgid "This table provides you a form to edit a current country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6033 +msgid "This table provides you a form to delete a country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6056 +msgid "Add a New Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6060 +msgid "Edit a Current Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6064 +msgid "Delete a Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6080 lib/php/monica/list.inc.php:3391 +msgid "Special?" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A special record" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "A normal country" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "This is a special record." +msgstr "" + +#: lib/php/monica/form.inc.php:6110 +msgid "This table provides you a form to add a new picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6114 +msgid "This table provides you a form to modify a current picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6125 +msgid "Upload a New Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6129 +msgid "Modify a Current Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6230 lib/php/monica/form.inc.php:6242 +msgid "Ratio:" +msgstr "" + +#: lib/php/monica/form.inc.php:6267 lib/php/monica/form.inc.php:6277 +msgid "Upload:" +msgstr "" + +#: lib/php/monica/form.inc.php:6308 +msgid "This table provides you a form to log in." +msgstr "" + +#: lib/php/monica/form.inc.php:6314 +msgid "Identify Yourself" +msgstr "" + +#: lib/php/monica/form.inc.php:6323 lib/php/monica/init.inc.php:505 +msgid "" +"Log-in is temporarily closed for maintainance now. Please come again " +"later. Sorry for the inconvienence." +msgstr "" + +#: lib/php/monica/form.inc.php:6332 +msgid "Log in" +msgstr "" + +#: lib/php/monica/form.inc.php:6379 +msgid "Remember me." +msgstr "" + +#: lib/php/monica/form.inc.php:6406 +msgid "Rebuild the Pages" +msgstr "" + +#: lib/php/monica/form.inc.php:6415 +msgid "Confirm" +msgstr "" + +#: lib/php/monica/form.inc.php:6457 +msgid "Log Out" +msgstr "" + +#: lib/php/monica/form.inc.php:6466 +msgid "Log out" +msgstr "" + +#: lib/php/monica/form.inc.php:6480 +msgid "Are you sure you want to log out?" +msgstr "" + +#: lib/php/monica/init.inc.php:114 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" + +#: lib/php/monica/init.inc.php:503 lib/php/monica/init.inc.php:504 +msgid "Log-In Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:524 lib/php/monica/init.inc.php:525 +msgid "Development Site Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:526 +msgid "Development site is closed. Please work on the live site." +msgstr "" + +#: lib/php/monica/links.inc.php:271 +msgid "Related Links" +msgstr "" + +#: lib/php/monica/list.inc.php:130 +msgid "Malformed" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "OK" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "Unreachable" +msgstr "" + +#: lib/php/monica/list.inc.php:290 lib/php/monica/list.inc.php:1534 +#: lib/php/monica/list.inc.php:3642 +msgid "(query phrase)" +msgstr "" + +#: lib/php/monica/list.inc.php:300 +msgid "S/N" +msgstr "" + +#: lib/php/monica/list.inc.php:301 +msgid "Created" +msgstr "" + +#: lib/php/monica/list.inc.php:302 +msgid "Created by" +msgstr "" + +#: lib/php/monica/list.inc.php:303 +msgid "Updated" +msgstr "" + +#: lib/php/monica/list.inc.php:304 +msgid "Updated by" +msgstr "" + +#: lib/php/monica/list.inc.php:306 +msgid "Content" +msgstr "" + +#: lib/php/monica/list.inc.php:307 +msgid "Category" +msgstr "" + +#: lib/php/monica/list.inc.php:308 +msgid "Coverage" +msgstr "" + +#: lib/php/monica/list.inc.php:309 +msgid "Date" +msgstr "" + +#: lib/php/monica/list.inc.php:311 +msgid "Description" +msgstr "" + +#: lib/php/monica/list.inc.php:312 +msgid "E-mail" +msgstr "" + +#: lib/php/monica/list.inc.php:313 +msgid "Hidden?" +msgstr "" + +#: lib/php/monica/list.inc.php:315 +msgid "ID." +msgstr "" + +#: lib/php/monica/list.inc.php:316 +msgid "Keywords" +msgstr "" + +#: lib/php/monica/list.inc.php:317 +msgid "Name" +msgstr "" + +#: lib/php/monica/list.inc.php:318 +msgid "Order" +msgstr "" + +#: lib/php/monica/list.inc.php:319 +msgid "Page path" +msgstr "" + +#: lib/php/monica/list.inc.php:320 +msgid "Picture" +msgstr "" + +#: lib/php/monica/list.inc.php:321 +msgid "Pic. ratio" +msgstr "" + +#: lib/php/monica/list.inc.php:322 +msgid "Pic. caption" +msgstr "" + +#: lib/php/monica/list.inc.php:323 +msgid "Pic. position" +msgstr "" + +#: lib/php/monica/list.inc.php:324 +msgid "Subject" +msgstr "" + +#: lib/php/monica/list.inc.php:325 +msgid "Title" +msgstr "" + +#: lib/php/monica/list.inc.php:326 +msgid "URL." +msgstr "" + +#: lib/php/monica/list.inc.php:327 +msgid "Status (slow)" +msgstr "" + +#: lib/php/monica/list.inc.php:336 +msgid "Select" +msgstr "" + +#: lib/php/monica/list.inc.php:339 +msgid "Select a Data Record" +msgstr "" + +#: lib/php/monica/list.inc.php:343 +msgid "Edit" +msgstr "" + +#: lib/php/monica/list.inc.php:345 +msgid "Manage Data" +msgstr "" + +#: lib/php/monica/list.inc.php:749 +msgid "Nothing found. Please try another query." +msgstr "" + +#: lib/php/monica/list.inc.php:752 +msgid "The database is empty." +msgstr "" + +#: lib/php/monica/list.inc.php:759 +#, c-format +msgid "Your query found %s record." +msgid_plural "Your query found %s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:766 +#, c-format +msgid "%s record." +msgid_plural "%s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:775 +#, c-format +msgid "Your query found %s record, listing %s to %s." +msgid_plural "Your query found %s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:784 +#, c-format +msgid "%s record, listing %s to %s." +msgid_plural "%s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:855 lib/php/monica/list.inc.php:860 +#: lib/php/monica/list.inc.php:869 +#, c-format +msgid "Page number (%s) invalid. Please specify a valid page number." +msgstr "" + +#: lib/php/monica/list.inc.php:874 +#, c-format +msgid "" +"Page number (%d) out of range. Please specify a number between 1 and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:1138 lib/php/monica/list.inc.php:1151 +#, c-format +msgid "You cannot sort by \"%s\"." +msgstr "" + +#: lib/php/monica/list.inc.php:1512 +msgid "Search" +msgstr "" + +#: lib/php/monica/list.inc.php:1610 +msgid "Index" +msgstr "" + +#: lib/php/monica/list.inc.php:1634 +msgid "First" +msgstr "" + +#: lib/php/monica/list.inc.php:1647 +msgid "Previous" +msgstr "" + +#: lib/php/monica/list.inc.php:1696 +msgid "Next" +msgstr "" + +#: lib/php/monica/list.inc.php:1714 +msgid "Last" +msgstr "" + +#: lib/php/monica/list.inc.php:1736 +msgid "Page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1776 lib/php/monica/list.inc.php:1900 +msgid "Delete the selected items." +msgstr "" + +#: lib/php/monica/list.inc.php:1805 +msgid "No." +msgstr "" + +#: lib/php/monica/list.inc.php:1813 lib/php/monica/list.inc.php:1873 +msgid "View" +msgstr "" + +#: lib/php/monica/list.inc.php:1925 +msgid "Set" +msgstr "" + +#: lib/php/monica/list.inc.php:1941 +msgid "Rows per page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1946 +msgid "Display columns:" +msgstr "" + +#: lib/php/monica/list.inc.php:1976 +msgid "Select a User" +msgstr "" + +#: lib/php/monica/list.inc.php:1977 +msgid "Manage Users" +msgstr "" + +#: lib/php/monica/list.inc.php:1982 +msgid "User ID." +msgstr "" + +#: lib/php/monica/list.inc.php:1983 +msgid "Full name" +msgstr "" + +#: lib/php/monica/list.inc.php:1984 +msgid "Deleted?" +msgstr "" + +#: lib/php/monica/list.inc.php:1985 +msgid "Pref. language" +msgstr "" + +#: lib/php/monica/list.inc.php:1986 +msgid "Visits" +msgstr "" + +#: lib/php/monica/list.inc.php:1987 +msgid "Visited" +msgstr "" + +#: lib/php/monica/list.inc.php:1988 +msgid "IP" +msgstr "" + +#: lib/php/monica/list.inc.php:1989 +msgid "Host" +msgstr "" + +#: lib/php/monica/list.inc.php:1990 +msgid "From country" +msgstr "" + +#: lib/php/monica/list.inc.php:1991 +msgid "Fail logins" +msgstr "" + +#: lib/php/monica/list.inc.php:2024 +msgid "Deleted" +msgstr "" + +#: lib/php/monica/list.inc.php:2035 +msgid "Add a new user account." +msgstr "" + +#: lib/php/monica/list.inc.php:2045 +msgid "Search for a user:" +msgstr "" + +#: lib/php/monica/list.inc.php:2063 +#, c-format +msgid "Your query found %s user." +msgid_plural "Your query found %s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2070 +#, c-format +msgid "%s user." +msgid_plural "%s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2079 +#, c-format +msgid "Your query found %s user, listing %s to %s." +msgid_plural "Your query found %s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2088 +#, c-format +msgid "%s user, listing %s to %s." +msgid_plural "%s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2107 +msgid "Select a Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2108 +msgid "Manage Groups" +msgstr "" + +#: lib/php/monica/list.inc.php:2113 +msgid "Group ID." +msgstr "" + +#: lib/php/monica/list.inc.php:2121 +msgid "Add a new group." +msgstr "" + +#: lib/php/monica/list.inc.php:2131 +msgid "Search for a group:" +msgstr "" + +#: lib/php/monica/list.inc.php:2149 +#, c-format +msgid "Your query found %s group." +msgid_plural "Your query found %s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2156 +#, c-format +msgid "%s group." +msgid_plural "%s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2165 +#, c-format +msgid "Your query found %s group, listing %s to %s." +msgid_plural "Your query found %s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2174 +#, c-format +msgid "%s group, listing %s to %s." +msgid_plural "%s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2194 +msgid "Select a User Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2195 +msgid "Manage User Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2200 lib/php/monica/list.inc.php:2323 +msgid "Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2201 lib/php/monica/list.inc.php:2324 +msgid "Member" +msgstr "" + +#: lib/php/monica/list.inc.php:2244 lib/php/monica/list.inc.php:2375 +msgid "Add a new membership record." +msgstr "" + +#: lib/php/monica/list.inc.php:2254 lib/php/monica/list.inc.php:2385 +msgid "Search for a membership record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2272 lib/php/monica/list.inc.php:2403 +#, c-format +msgid "Your query found %s membership record." +msgid_plural "Your query found %s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2279 lib/php/monica/list.inc.php:2410 +#, c-format +msgid "%s membership record." +msgid_plural "%s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2288 lib/php/monica/list.inc.php:2419 +#, c-format +msgid "Your query found %s membership record, listing %s to %s." +msgid_plural "Your query found %s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2297 lib/php/monica/list.inc.php:2428 +#, c-format +msgid "%s membership record, listing %s to %s." +msgid_plural "%s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2317 +msgid "Select a Group Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2318 +msgid "Manage Group Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2448 +msgid "Select a Script Privilege Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2449 +msgid "Manage Script Privileges" +msgstr "" + +#: lib/php/monica/list.inc.php:2454 +msgid "Script" +msgstr "" + +#: lib/php/monica/list.inc.php:2455 +msgid "Privilege" +msgstr "" + +#: lib/php/monica/list.inc.php:2493 +msgid "Add a new script privilege record." +msgstr "" + +#: lib/php/monica/list.inc.php:2503 +msgid "Search for a script privilege record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2521 +#, c-format +msgid "Your query found %s script privilege record." +msgid_plural "Your query found %s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2528 +#, c-format +msgid "%s script privilege record." +msgid_plural "%s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2537 +#, c-format +msgid "Your query found %s script privilege record, listing %s to %s." +msgid_plural "Your query found %s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2546 +#, c-format +msgid "%s script privilege record, listing %s to %s." +msgid_plural "%s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2566 +msgid "Select a User Preference" +msgstr "" + +#: lib/php/monica/list.inc.php:2567 +msgid "Manage User Preferences" +msgstr "" + +#: lib/php/monica/list.inc.php:2574 lib/php/monica/list.inc.php:2689 +msgid "User" +msgstr "" + +#: lib/php/monica/list.inc.php:2575 +msgid "Domain" +msgstr "" + +#: lib/php/monica/list.inc.php:2576 +msgid "Value" +msgstr "" + +#: lib/php/monica/list.inc.php:2610 +msgid "Add a new user preference." +msgstr "" + +#: lib/php/monica/list.inc.php:2620 +msgid "Search for a user preference:" +msgstr "" + +#: lib/php/monica/list.inc.php:2638 +#, c-format +msgid "Your query found %s user preference." +msgid_plural "Your query found %s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2645 +#, c-format +msgid "%s user preference." +msgid_plural "%s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2654 +#, c-format +msgid "Your query found %s user preference, listing %s to %s." +msgid_plural "Your query found %s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2663 +#, c-format +msgid "%s user preference, listing %s to %s." +msgid_plural "%s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2682 +msgid "Select a User Request" +msgstr "" + +#: lib/php/monica/list.inc.php:2683 +msgid "Manage User Requests" +msgstr "" + +#: lib/php/monica/list.inc.php:2688 +msgid "Type" +msgstr "" + +#: lib/php/monica/list.inc.php:2690 +msgid "Arguments" +msgstr "" + +#: lib/php/monica/list.inc.php:2691 +msgid "Expiration" +msgstr "" + +#: lib/php/monica/list.inc.php:2699 +msgid "Add a new user request." +msgstr "" + +#: lib/php/monica/list.inc.php:2709 +msgid "Search for a user request:" +msgstr "" + +#: lib/php/monica/list.inc.php:2727 +#, c-format +msgid "Your query found %s user request." +msgid_plural "Your query found %s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2734 +#, c-format +msgid "%s user request." +msgid_plural "%s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2743 +#, c-format +msgid "Your query found %s user request, listing %s to %s." +msgid_plural "Your query found %s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2752 +#, c-format +msgid "%s user request, listing %s to %s." +msgid_plural "%s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2778 +msgid "Add a new category." +msgstr "" + +#: lib/php/monica/list.inc.php:2788 +msgid "Search for a category:" +msgstr "" + +#: lib/php/monica/list.inc.php:2806 +#, c-format +msgid "Your query found %s category." +msgid_plural "Your query found %s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2813 +#, c-format +msgid "%s category." +msgid_plural "%s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2822 +#, c-format +msgid "Your query found %s category, listing %s to %s." +msgid_plural "Your query found %s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2831 +#, c-format +msgid "%s category, listing %s to %s." +msgid_plural "%s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2849 +msgid "Add a new categorization record." +msgstr "" + +#: lib/php/monica/list.inc.php:2859 +msgid "Search for a categorization record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2877 +#, c-format +msgid "Your query found %s categorization record." +msgid_plural "Your query found %s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2884 +#, c-format +msgid "%s categorization record." +msgid_plural "%s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2893 +#, c-format +msgid "Your query found %s categorization record, listing %s to %s." +msgid_plural "Your query found %s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2902 +#, c-format +msgid "%s categorization record, listing %s to %s." +msgid_plural "%s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2921 +msgid "Select a Page" +msgstr "" + +#: lib/php/monica/list.inc.php:2922 +msgid "Manage Pages" +msgstr "" + +#: lib/php/monica/list.inc.php:2952 lib/php/monica/list.inc.php:3066 +#: lib/php/monica/list.inc.php:3173 lib/php/monica/list.inc.php:3237 +#: lib/php/monica/list.inc.php:3358 +msgid "Hidden" +msgstr "" + +#: lib/php/monica/list.inc.php:2953 lib/php/monica/list.inc.php:3067 +#: lib/php/monica/list.inc.php:3174 lib/php/monica/list.inc.php:3238 +#: lib/php/monica/list.inc.php:3359 +msgid "Shown" +msgstr "" + +#: lib/php/monica/list.inc.php:2963 +msgid "Write a new page." +msgstr "" + +#: lib/php/monica/list.inc.php:2973 +msgid "Search for a page:" +msgstr "" + +#: lib/php/monica/list.inc.php:2991 +#, c-format +msgid "Your query found %s page." +msgid_plural "Your query found %s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2998 +#, c-format +msgid "%s page." +msgid_plural "%s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3007 +#, c-format +msgid "Your query found %s page, listing %s to %s." +msgid_plural "Your query found %s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3016 +#, c-format +msgid "%s page, listing %s to %s." +msgid_plural "%s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3035 +msgid "Select a News Article" +msgstr "" + +#: lib/php/monica/list.inc.php:3036 +msgid "Manage News" +msgstr "" + +#: lib/php/monica/list.inc.php:3077 +msgid "Write a new news article." +msgstr "" + +#: lib/php/monica/list.inc.php:3087 +msgid "Search for a news article:" +msgstr "" + +#: lib/php/monica/list.inc.php:3105 +#, c-format +msgid "Your query found %s news article." +msgid_plural "Your query found %s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3112 +#, c-format +msgid "%s news article." +msgid_plural "%s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3121 +#, c-format +msgid "Your query found %s news article, listing %s to %s." +msgid_plural "Your query found %s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3130 +#, c-format +msgid "%s news article, listing %s to %s." +msgid_plural "%s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3149 +msgid "Select a Link Category" +msgstr "" + +#: lib/php/monica/list.inc.php:3150 +msgid "Manage Link Categories" +msgstr "" + +#: lib/php/monica/list.inc.php:3197 +msgid "Select a Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3198 +msgid "Manage Links" +msgstr "" + +#: lib/php/monica/list.inc.php:3248 +msgid "Add a new related link." +msgstr "" + +#: lib/php/monica/list.inc.php:3258 +msgid "Search for a related link:" +msgstr "" + +#: lib/php/monica/list.inc.php:3276 +#, c-format +msgid "Your query found %s related link." +msgid_plural "Your query found %s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3283 +#, c-format +msgid "%s related link." +msgid_plural "%s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3292 +#, c-format +msgid "Your query found %s related link, listing %s to %s." +msgid_plural "Your query found %s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3301 +#, c-format +msgid "%s related link, listing %s to %s." +msgid_plural "%s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3321 +msgid "Select a Link Categorization Record" +msgstr "" + +#: lib/php/monica/list.inc.php:3322 +msgid "Manage Link Categorization" +msgstr "" + +#: lib/php/monica/list.inc.php:3327 +msgid "Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3383 +msgid "Select a Country" +msgstr "" + +#: lib/php/monica/list.inc.php:3384 +msgid "Manage Country Data" +msgstr "" + +#: lib/php/monica/list.inc.php:3389 +msgid "Code" +msgstr "" + +#: lib/php/monica/list.inc.php:3390 +msgid "Country name" +msgstr "" + +#: lib/php/monica/list.inc.php:3399 +msgid "Add a new country record." +msgstr "" + +#: lib/php/monica/list.inc.php:3409 +msgid "Search for a country:" +msgstr "" + +#: lib/php/monica/list.inc.php:3427 +#, c-format +msgid "Your query found %s country." +msgid_plural "Your query found %s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3434 +#, c-format +msgid "%s country." +msgid_plural "%s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3443 +#, c-format +msgid "Your query found %s country, listing %s to %s." +msgid_plural "Your query found %s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3452 +#, c-format +msgid "%s country, listing %s to %s." +msgid_plural "%s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3474 +msgid "Browse the Activity Log" +msgstr "" + +#: lib/php/monica/list.inc.php:3586 +msgid "Please fill in the number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3590 +#, c-format +msgid "This number of rows to display is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/list.inc.php:3595 +msgid "Please fill in a positive integer number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3599 lib/php/monica/list.inc.php:3609 +#, c-format +msgid "" +"The number of rows to display is too small. Please fill in a larger number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3613 +#, c-format +msgid "" +"The number of rows to display is too large. Please fill in a smaller number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3638 +msgid "Search for log entries:" +msgstr "" + +#: lib/php/monica/list.inc.php:3641 +msgid "Display" +msgstr "" + +#: lib/php/monica/list.inc.php:3654 +msgid "Display rows:" +msgstr "" + +#: lib/php/monica/list.inc.php:3677 +#, c-format +msgid "Your query found %s log entry." +msgid_plural "Your query found %s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3684 +#, c-format +msgid "%s log entry." +msgid_plural "%s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3693 +#, c-format +msgid "Your query found %s log entry, listing %s to %s." +msgid_plural "Your query found %s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3702 +#, c-format +msgid "%s log entry, listing %s to %s." +msgid_plural "%s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/lninfo.inc.php:28 +msgid "English" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:39 +msgid "Traditional Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:50 +msgid "Simplified Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:61 +msgid "Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:72 +msgid "Japanese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:83 +msgid "Korean" +msgstr "한국어" + +#: lib/php/monica/lninfo.inc.php:94 +msgid "German" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:105 +msgid "Spanish" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:366 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:738 +msgid "Web pages" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:739 +msgid "News" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:740 +msgid "Related links" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:741 +msgid "Home page" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:742 +msgid "Whole web site" +msgstr "" + +#: lib/php/monica/pic.inc.php:39 +msgid "Left-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:40 +msgid "Right-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:74 lib/php/monica/pic.inc.php:77 +#, c-format +msgid "This picture file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/pic.inc.php:92 +msgid "Please upload only PNG, JPEG or GIF files." +msgstr "" + +#: lib/php/monica/pic.inc.php:153 +#, c-format +msgid "Width: %d, height: %d, ratio: %0.2f" +msgstr "" + +#: lib/php/monica/pic.inc.php:176 +msgid "Please specify a numeric ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:180 +msgid "Please specify a positive ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:183 +#, c-format +msgid "Please specify a ratio less than or equal to %0.2f." +msgstr "" + +#: lib/php/monica/pic.inc.php:189 +msgid "This image is too large to display." +msgstr "" + +#: lib/php/monica/preview.inc.php:47 +#, c-format +msgid "Unknown preview source: \"%s\"." +msgstr "" + +#: lib/php/monica/preview.inc.php:67 +#, c-format +msgid "Unknown preview form: %d." +msgstr "" + +#: lib/php/monica/preview.inc.php:143 +msgid "Preview Mark Area" +msgstr "" + +#: lib/php/monica/preview.inc.php:148 +msgid "Finish preview and return." +msgstr "" + +#: lib/php/monica/process.inc.php:237 +msgid "This record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:243 +msgid "This record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:247 +msgid "This record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:251 +msgid "This record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:406 +msgid "This category was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:412 +msgid "This category has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:416 +msgid "This category has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:420 +msgid "This category has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:433 +msgid "This categorization record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:439 +msgid "This categorization record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:443 +msgid "This categorization record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:447 +msgid "This categorization record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:782 +msgid "This user account was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:788 +msgid "This user account has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:792 +msgid "This user account has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:796 +msgid "This user account has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1074 +msgid "This group was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1080 +msgid "This group has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1084 +msgid "This group has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1088 +msgid "This group has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1152 lib/php/monica/process.inc.php:1230 +msgid "This membership record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1158 lib/php/monica/process.inc.php:1236 +msgid "This membership record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1162 lib/php/monica/process.inc.php:1240 +msgid "This membership record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1166 lib/php/monica/process.inc.php:1244 +msgid "This membership record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1308 +msgid "This script privilege record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1314 +msgid "This script privilege record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1318 +msgid "This script privilege record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1322 +msgid "This script privilege record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1438 +msgid "This user preference was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1444 +msgid "This user preference has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1448 +msgid "This user preference has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1452 +msgid "This user preference has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1560 +msgid "This user request was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1566 +msgid "This user request has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1570 +msgid "This user request has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1574 +msgid "This user request has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1685 +msgid "This page was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1691 +msgid "This page has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1695 +msgid "This page has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1699 +msgid "This page has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1874 +msgid "This news article was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1880 +msgid "This news article has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1884 +msgid "This news article has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1888 +msgid "This news article has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1997 +msgid "This country was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2003 +msgid "This country has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2007 +msgid "This country has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2011 +msgid "This country has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:2097 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. (%0.3f seconds)" +msgstr "" + +#: lib/php/monica/process.inc.php:2158 +#, c-format +msgid "Welcome, %s!" +msgstr "" + +#: lib/php/monica/process.inc.php:2204 +msgid "You have successfully logged out." +msgstr "" + +#: lib/php/monica/process.inc.php:2439 +msgid "This related link was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2445 +msgid "This related link has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2449 +msgid "This related link has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2453 +msgid "This related link has been successfully deleted." +msgstr "" + +#: lib/php/monica/request.inc.php:38 +msgid "Please specify the request." +msgstr "" + +#: lib/php/monica/request.inc.php:46 lib/php/monica/request.inc.php:55 +#, c-format +msgid "Invalid request S/N: %s." +msgstr "" + +#: lib/php/monica/sitesize.inc.php:41 +#, c-format +msgid "Currently using files %s.\n" +msgstr "" + +#: lib/php/monica/sitesize.inc.php:46 +#, c-format +msgid "Currently using files %s, database %s, total %s.\n" +msgstr "" + +#: lib/php/monica/upload.inc.php:70 +#, c-format +msgid "MIME file type: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:71 +#, c-format +msgid "File name: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:72 +#, c-format +msgid "File size: %s bytes" +msgstr "" + +#: lib/php/monica/validate.inc.php:116 +msgid "HTML Validatior Logo Area" +msgstr "" + +#: lib/php/monica/validate.inc.php:117 +msgid "HTML validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:118 +#, c-format +msgid "Valid %s!" +msgstr "" + +#: lib/php/monica/validate.inc.php:119 +msgid "CSS validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:120 +msgid "Valid CSS!" +msgstr "" + +#: lib/php/monica/validate.inc.php:121 +msgid "Explanation of Level Triple-A Conformance" +msgstr "" + +#: lib/php/monica/validate.inc.php:122 +msgid "" +"Level Triple-A conformance icon, W3C-WAI Web Content Accessibility " +"Guidelines 1.0" +msgstr "" diff --git a/po/monica/monica.pot b/po/monica/monica.pot new file mode 100644 index 0000000..ae8b074 --- /dev/null +++ b/po/monica/monica.pot @@ -0,0 +1,3302 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 12:55+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: lib/php/monica/checker.inc.php:159 +msgid "Please select a user." +msgstr "" + +#: lib/php/monica/checker.inc.php:163 +msgid "This user does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:181 +msgid "Please select a group." +msgstr "" + +#: lib/php/monica/checker.inc.php:185 +msgid "This group does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:203 +msgid "Please fill in the script." +msgstr "" + +#: lib/php/monica/checker.inc.php:207 +#, c-format +msgid "This script is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:212 +msgid "This script is not a valid script. Please specify another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:230 +msgid "Please fill in the date." +msgstr "" + +#: lib/php/monica/checker.inc.php:234 lib/php/monica/checker.inc.php:238 +#: lib/php/monica/checker.inc.php:241 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "" + +#: lib/php/monica/checker.inc.php:259 +msgid "Please fill in the ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:263 +#, c-format +msgid "This ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:267 +#, c-format +msgid "This ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:272 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:294 +msgid "Please fill in the order." +msgstr "" + +#: lib/php/monica/checker.inc.php:298 +#, c-format +msgid "This order is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:303 +msgid "Please fill in a positive integer order." +msgstr "" + +#: lib/php/monica/checker.inc.php:307 lib/php/monica/checker.inc.php:317 +#, c-format +msgid "" +"The order is too small. Please fill in a larger order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:321 +#, c-format +msgid "" +"The order is too large. Please fill in a smaller order between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:348 +msgid "Please fill in the page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:352 +#, c-format +msgid "This page path is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:365 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:369 +msgid "Please fill in an absolute page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:373 +msgid "Please fill in a valid page path." +msgstr "" + +#: lib/php/monica/checker.inc.php:377 +msgid "You cannot overwrite the cover home page." +msgstr "" + +#: lib/php/monica/checker.inc.php:381 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "" + +#: lib/php/monica/checker.inc.php:422 lib/php/monica/checker.inc.php:428 +msgid "Please fill in the attachment description." +msgstr "" + +#: lib/php/monica/checker.inc.php:432 +#, c-format +msgid "This attachment description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:449 +msgid "This PDF. file does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:456 +#, c-format +msgid "This PDF. file is too large. (Max. size %s)" +msgstr "" + +#: lib/php/monica/checker.inc.php:461 +msgid "Please upload only PDF. file." +msgstr "" + +#: lib/php/monica/checker.inc.php:479 +msgid "Please fill in the title." +msgstr "" + +#: lib/php/monica/checker.inc.php:483 +#, c-format +msgid "This title is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:502 +msgid "Please fill in the subject." +msgstr "" + +#: lib/php/monica/checker.inc.php:506 +#, c-format +msgid "This subject is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:524 lib/php/monica/form.inc.php:3159 +#: lib/php/monica/form.inc.php:3172 +msgid "Fill in the content here." +msgstr "" + +#: lib/php/monica/checker.inc.php:528 +msgid "Please fill in the content." +msgstr "" + +#: lib/php/monica/checker.inc.php:532 +#, c-format +msgid "This content is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:551 +msgid "Please fill in the keywords." +msgstr "" + +#: lib/php/monica/checker.inc.php:555 +#, c-format +msgid "This keyword list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:572 +msgid "Please select a proper pinyin." +msgstr "" + +#: lib/php/monica/checker.inc.php:578 +#, c-format +msgid "This pinyin is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:583 +msgid "" +"This pinyin does not match the Chinese. Please select a proper pinyin from " +"the list." +msgstr "" + +#: lib/php/monica/checker.inc.php:609 lib/php/monica/pic.inc.php:82 +msgid "Please upload the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:616 lib/php/monica/checker.inc.php:3215 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:622 +#, c-format +msgid "This picture is too large. Please upload another one. (Max. size %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:639 lib/php/monica/form.inc.php:3588 +#, c-format +msgid "Please upload a new picture from %s." +msgstr "" + +#: lib/php/monica/checker.inc.php:664 lib/php/monica/checker.inc.php:727 +msgid "Please fill in the picture caption." +msgstr "" + +#: lib/php/monica/checker.inc.php:668 lib/php/monica/checker.inc.php:731 +#, c-format +msgid "This picture caption is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:686 lib/php/monica/checker.inc.php:749 +msgid "Please select the picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:692 lib/php/monica/checker.inc.php:755 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "" + +#: lib/php/monica/checker.inc.php:791 lib/php/monica/checker.inc.php:794 +#, c-format +msgid "Your uploaded file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/checker.inc.php:797 lib/php/monica/pic.inc.php:80 +msgid "" +"Upload not completed. Disk may be full or connection may be closed in the " +"half. You may try to upload again, or contact the system administrator for " +"this problem." +msgstr "" + +#: lib/php/monica/checker.inc.php:799 lib/php/monica/pic.inc.php:84 +#, c-format +msgid "Upload failed with an unknown error (%d)." +msgstr "" + +#: lib/php/monica/checker.inc.php:1183 lib/php/monica/chkfunc.inc.php:59 +#: lib/php/monica/chkfunc.inc.php:72 lib/php/monica/preview.inc.php:29 +#, c-format +msgid "The following field was not received: \"%s\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:1262 +msgid "Please fill in the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1266 +#, c-format +msgid "This user ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1270 +#, c-format +msgid "This user ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1275 +msgid "" +"Only lower-case English letters, numbers, at-signs, dots, dashes and " +"underscores are allowed for the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1287 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1317 +msgid "Please fill in the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1320 +msgid "Please confirm the password." +msgstr "" + +#: lib/php/monica/checker.inc.php:1324 +#, c-format +msgid "This password is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1329 +#, c-format +msgid "This password is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1334 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "" + +#: lib/php/monica/checker.inc.php:1345 +msgid "This password is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1360 +msgid "This password does not contain enough different characters." +msgstr "" + +#: lib/php/monica/checker.inc.php:1364 +msgid "This password is too simplistic/systematic." +msgstr "" + +#: lib/php/monica/checker.inc.php:1368 +msgid "This password is based on a dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1370 +msgid "This password is based on a (reversed) dictionary word." +msgstr "" + +#: lib/php/monica/checker.inc.php:1372 +msgid "This password is too simple." +msgstr "" + +#: lib/php/monica/checker.inc.php:1378 +msgid "You cannot use a password that is based on the user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1397 +msgid "Please fill in the name." +msgstr "" + +#: lib/php/monica/checker.inc.php:1401 +#, c-format +msgid "This name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1420 +msgid "Please fill in the e-mail." +msgstr "" + +#: lib/php/monica/checker.inc.php:1424 +#, c-format +msgid "This e-mail is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1428 +#, c-format +msgid "This e-mail is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1437 +msgid "Please fill in a valid e-mail address." +msgstr "" + +#: lib/php/monica/checker.inc.php:1439 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:1461 lib/php/monica/checker.inc.php:1655 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1478 +msgid "You cannot submit the super-user group along with other groups." +msgstr "" + +#: lib/php/monica/checker.inc.php:1480 +msgid "You cannot set the administrators group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1482 +msgid "You cannot set the all-users group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1515 +msgid "Please fill in the group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1519 +#, c-format +msgid "This group ID. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1523 +#, c-format +msgid "This group ID. is too short. (Min. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1528 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:1540 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1558 +msgid "Please fill in the privilege description." +msgstr "" + +#: lib/php/monica/checker.inc.php:1562 +#, c-format +msgid "This privilege description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:1585 +msgid "This user member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1620 +msgid "This group member is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:1747 lib/php/monica/checker.inc.php:1855 +msgid "Please select a member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1751 lib/php/monica/checker.inc.php:1859 +msgid "This member does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1770 lib/php/monica/checker.inc.php:1883 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1837 +msgid "Please select a different belonging group." +msgstr "" + +#: lib/php/monica/checker.inc.php:1864 +msgid "Please select a different group member." +msgstr "" + +#: lib/php/monica/checker.inc.php:1958 +msgid "" +"This script privilege already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:1996 lib/php/monica/checker.inc.php:2184 +msgid "Please select the user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2002 lib/php/monica/checker.inc.php:2190 +msgid "This option is invalid. Please select a proper user." +msgstr "" + +#: lib/php/monica/checker.inc.php:2020 +msgid "Please set the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2026 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2039 lib/php/monica/checker.inc.php:2295 +msgid "Please fill in the preference domain." +msgstr "" + +#: lib/php/monica/checker.inc.php:2043 lib/php/monica/checker.inc.php:2299 +#, c-format +msgid "This preference domain is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2063 +msgid "Please fill in the preference name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2067 +#, c-format +msgid "This preference name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2086 +msgid "Please fill in the preference value." +msgstr "" + +#: lib/php/monica/checker.inc.php:2090 +#, c-format +msgid "This preference value is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2119 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2167 +msgid "Please select the request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2173 +msgid "This option is invalid. Please select a proper request type." +msgstr "" + +#: lib/php/monica/checker.inc.php:2194 +msgid "You must choose anonymous for join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2197 +msgid "You cannot choose anonymous for non-join requests." +msgstr "" + +#: lib/php/monica/checker.inc.php:2221 lib/php/monica/form.inc.php:5501 +msgid "Please fill in the request arguments list here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2229 +#, c-format +msgid "This request arguments list is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2349 +msgid "Please fill in the number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2353 +#, c-format +msgid "This number of rows per page is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2358 +msgid "Please fill in a positive integer number of rows per page." +msgstr "" + +#: lib/php/monica/checker.inc.php:2362 lib/php/monica/checker.inc.php:2372 +#, c-format +msgid "" +"The number of rows per page is too small. Please fill in a larger number of " +"rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2376 +#, c-format +msgid "" +"The number of rows per page is too large. Please fill in a smaller number " +"of rows per page between %d and %d." +msgstr "" + +#: lib/php/monica/checker.inc.php:2443 +msgid "Please fill in your user ID." +msgstr "" + +#: lib/php/monica/checker.inc.php:2451 lib/php/monica/checker.inc.php:2458 +#: lib/php/monica/checker.inc.php:2475 lib/php/monica/checker.inc.php:2508 +#: lib/php/monica/checker.inc.php:2540 lib/php/monica/checker.inc.php:2548 +#: lib/php/monica/checker.inc.php:2558 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "" + +#: lib/php/monica/checker.inc.php:2495 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "" + +#: lib/php/monica/checker.inc.php:2531 +msgid "Please fill in your password." +msgstr "" + +#: lib/php/monica/checker.inc.php:2581 +msgid "You are not an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2600 +msgid "You are an administrator so may not log in here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2752 +msgid "Please fill in the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2756 +#, c-format +msgid "You must fill in a %d-letters code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2761 +msgid "You can only use upper letters and for the code." +msgstr "" + +#: lib/php/monica/checker.inc.php:2773 +msgid "This code is duplicated. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2791 +msgid "Please fill in the country name." +msgstr "" + +#: lib/php/monica/checker.inc.php:2795 +#, c-format +msgid "This country name is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2823 lib/php/monica/checker.inc.php:2842 +msgid "Please select a parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2829 +msgid "This option is invalid. Please select a proper parent category." +msgstr "" + +#: lib/php/monica/checker.inc.php:2846 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2851 +msgid "A category cannot belong to itself. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2859 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2877 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "" + +#: lib/php/monica/checker.inc.php:2895 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2942 +msgid "Please fill in the URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2946 +#, c-format +msgid "This URL. is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:2951 +msgid "Please fill in a valid URL.." +msgstr "" + +#: lib/php/monica/checker.inc.php:2963 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:2968 +msgid "This URL. is not reachable. Check if there is any typo in it." +msgstr "" + +#: lib/php/monica/checker.inc.php:2985 lib/php/monica/form.inc.php:3261 +msgid "Fill in the description here." +msgstr "" + +#: lib/php/monica/checker.inc.php:2989 +msgid "Please fill in the description." +msgstr "" + +#: lib/php/monica/checker.inc.php:2993 +#, c-format +msgid "This description is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/checker.inc.php:3013 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/php/monica/checker.inc.php:3017 lib/php/monica/checker.inc.php:3073 +msgid "This category does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3023 lib/php/monica/checker.inc.php:3069 +msgid "Please select a category." +msgstr "" + +#: lib/php/monica/checker.inc.php:3091 +msgid "Please select a related link." +msgstr "" + +#: lib/php/monica/checker.inc.php:3095 +msgid "This link does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3114 +msgid "" +"This link categorization already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3155 +msgid "Please select the type." +msgstr "" + +#: lib/php/monica/checker.inc.php:3159 +msgid "This type does not exist anymore. Please select another one." +msgstr "" + +#: lib/php/monica/checker.inc.php:3186 lib/php/monica/list.inc.php:961 +msgid "Please fill in your query." +msgstr "" + +#: lib/php/monica/checker.inc.php:3211 +msgid "Please submit the picture." +msgstr "" + +#: lib/php/monica/checker.inc.php:3238 lib/php/monica/checker.inc.php:3329 +msgid "Please fill in the resize ratio." +msgstr "" + +#: lib/php/monica/checker.inc.php:3306 +msgid "Please specify a valid picture." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:156 lib/php/monica/chkfunc.inc.php:160 +#: lib/php/monica/chkfunc.inc.php:163 lib/php/monica/chkfunc.inc.php:166 +msgid "Please select a legal year." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:171 lib/php/monica/chkfunc.inc.php:175 +#: lib/php/monica/chkfunc.inc.php:178 +msgid "Please select a legal month." +msgstr "" + +#: lib/php/monica/chkfunc.inc.php:183 lib/php/monica/chkfunc.inc.php:187 +#: lib/php/monica/chkfunc.inc.php:193 +msgid "Please select a legal day." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:27 +#, c-format +msgid "%s: It is not a file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:32 +#, c-format +msgid "%s: You have no permission to overwrite this file." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:45 +#, c-format +msgid "%s: You cannot create anything under the root directory." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:50 +#, c-format +msgid "" +"%s: One of the parents of this file (%s) is not a directory. You cannot " +"create any new file inside." +msgstr "" + +#: lib/php/monica/chkwrite.inc.php:55 +#, c-format +msgid "%s: You have no permission to create any file under %s." +msgstr "" + +#: lib/php/monica/commtext.inc.php:18 +msgid "(not set)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:24 +msgid "(none)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:30 +msgid "(N/A)" +msgstr "" + +#: lib/php/monica/commtext.inc.php:36 +msgid "(blank)" +msgstr "" + +#: lib/php/monica/echoform.inc.php:173 +#, c-format +msgid "%s bytes" +msgstr "" + +#: lib/php/monica/form.inc.php:168 +msgid "Delete it" +msgstr "" + +#: lib/php/monica/form.inc.php:174 +msgid "Are you sure you want to delete it? It cannot be recovered." +msgstr "" + +#: lib/php/monica/form.inc.php:188 +msgid "*" +msgstr "" + +#: lib/php/monica/form.inc.php:224 +msgid "This table provides you a form to add a new data record." +msgstr "" + +#: lib/php/monica/form.inc.php:228 +msgid "This table provides you a form to update a current data record." +msgstr "" + +#: lib/php/monica/form.inc.php:232 +msgid "This table provides you a form to delete a data record." +msgstr "" + +#: lib/php/monica/form.inc.php:281 +msgid "Add a New Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:285 +msgid "Update a Current Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:289 +msgid "Delete a Data Record" +msgstr "" + +#: lib/php/monica/form.inc.php:301 +msgid "Preview it." +msgstr "" + +#: lib/php/monica/form.inc.php:500 lib/php/monica/form.inc.php:506 +#: lib/php/monica/form.inc.php:691 lib/php/monica/form.inc.php:697 +#: lib/php/monica/preview.inc.php:146 +msgid "Preview" +msgstr "" + +#: lib/php/monica/form.inc.php:501 lib/php/monica/form.inc.php:507 +#: lib/php/monica/form.inc.php:692 lib/php/monica/form.inc.php:698 +msgid "Confirm and submit" +msgstr "" + +#: lib/php/monica/form.inc.php:708 lib/php/monica/form.inc.php:1692 +#: lib/php/monica/form.inc.php:1778 lib/php/monica/list.inc.php:1809 +msgid "Delete" +msgstr "" + +#: lib/php/monica/form.inc.php:709 lib/php/monica/form.inc.php:6436 +#: lib/php/monica/form.inc.php:6487 +msgid "Cancel" +msgstr "" + +#: lib/php/monica/form.inc.php:1042 lib/php/monica/form.inc.php:3499 +msgid "Set the picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1043 lib/php/monica/form.inc.php:3031 +#: lib/php/monica/form.inc.php:3500 +msgid "Delete this picture" +msgstr "" + +#: lib/php/monica/form.inc.php:1048 lib/php/monica/form.inc.php:1178 +#: lib/php/monica/form.inc.php:3037 lib/php/monica/form.inc.php:3104 +#: lib/php/monica/form.inc.php:3505 lib/php/monica/form.inc.php:3677 +#: lib/php/monica/form.inc.php:6180 lib/php/monica/list.inc.php:814 +msgid "Picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1059 lib/php/monica/form.inc.php:1109 +#: lib/php/monica/form.inc.php:1185 +#, c-format +msgid "Picture #%d:" +msgstr "" + +#: lib/php/monica/form.inc.php:1080 lib/php/monica/form.inc.php:1131 +#: lib/php/monica/form.inc.php:1166 lib/php/monica/form.inc.php:1199 +msgid "Caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:1092 lib/php/monica/form.inc.php:3064 +#: lib/php/monica/form.inc.php:3566 lib/php/monica/form.inc.php:6200 +msgid "Original picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1093 lib/php/monica/form.inc.php:3065 +#: lib/php/monica/form.inc.php:3567 lib/php/monica/form.inc.php:6214 +msgid "New picture preview" +msgstr "" + +#: lib/php/monica/form.inc.php:1113 lib/php/monica/form.inc.php:1276 +#: lib/php/monica/form.inc.php:1363 lib/php/monica/form.inc.php:1451 +#: lib/php/monica/form.inc.php:1560 lib/php/monica/form.inc.php:1650 +#: lib/php/monica/form.inc.php:1727 lib/php/monica/form.inc.php:1825 +#: lib/php/monica/form.inc.php:1916 lib/php/monica/form.inc.php:1977 +#: lib/php/monica/form.inc.php:2053 lib/php/monica/form.inc.php:2159 +#: lib/php/monica/form.inc.php:2391 lib/php/monica/form.inc.php:2592 +#: lib/php/monica/form.inc.php:2689 lib/php/monica/form.inc.php:2800 +#: lib/php/monica/form.inc.php:2897 lib/php/monica/form.inc.php:2980 +#: lib/php/monica/form.inc.php:3069 lib/php/monica/form.inc.php:3200 +#: lib/php/monica/form.inc.php:3571 lib/php/monica/form.inc.php:3627 +#: lib/php/monica/form.inc.php:3640 lib/php/monica/form.inc.php:3747 +#: lib/php/monica/form.inc.php:4423 lib/php/monica/form.inc.php:4548 +#: lib/php/monica/form.inc.php:4746 lib/php/monica/form.inc.php:4883 +#: lib/php/monica/form.inc.php:5017 lib/php/monica/form.inc.php:6193 +#: lib/php/monica/form.inc.php:6260 +msgid "Original:" +msgstr "" + +#: lib/php/monica/form.inc.php:1141 lib/php/monica/form.inc.php:1281 +#: lib/php/monica/form.inc.php:1369 lib/php/monica/form.inc.php:1456 +#: lib/php/monica/form.inc.php:1575 lib/php/monica/form.inc.php:1655 +#: lib/php/monica/form.inc.php:1732 lib/php/monica/form.inc.php:1832 +#: lib/php/monica/form.inc.php:1921 lib/php/monica/form.inc.php:1982 +#: lib/php/monica/form.inc.php:2065 lib/php/monica/form.inc.php:2173 +#: lib/php/monica/form.inc.php:2422 lib/php/monica/form.inc.php:2597 +#: lib/php/monica/form.inc.php:2694 lib/php/monica/form.inc.php:2805 +#: lib/php/monica/form.inc.php:2902 lib/php/monica/form.inc.php:2985 +#: lib/php/monica/form.inc.php:3080 lib/php/monica/form.inc.php:3205 +#: lib/php/monica/form.inc.php:3584 lib/php/monica/form.inc.php:3632 +#: lib/php/monica/form.inc.php:3649 lib/php/monica/form.inc.php:3752 +#: lib/php/monica/form.inc.php:4442 lib/php/monica/form.inc.php:4554 +#: lib/php/monica/form.inc.php:4759 lib/php/monica/form.inc.php:4896 +#: lib/php/monica/form.inc.php:5030 lib/php/monica/form.inc.php:6205 +#: lib/php/monica/form.inc.php:6265 lib/php/monica/form.inc.php:6295 +msgid "New:" +msgstr "" + +#: lib/php/monica/form.inc.php:1269 lib/php/monica/form.inc.php:1444 +#: lib/php/monica/form.inc.php:1543 lib/php/monica/form.inc.php:2358 +#: lib/php/monica/form.inc.php:2585 lib/php/monica/form.inc.php:2793 +#: lib/php/monica/form.inc.php:2890 lib/php/monica/form.inc.php:2973 +#: lib/php/monica/form.inc.php:3620 +msgid "Source:" +msgstr "" + +#: lib/php/monica/form.inc.php:1289 lib/php/monica/form.inc.php:1464 +#: lib/php/monica/form.inc.php:1583 lib/php/monica/form.inc.php:2605 +#: lib/php/monica/form.inc.php:2813 lib/php/monica/form.inc.php:2910 +#: lib/php/monica/form.inc.php:2993 +#, c-format +msgid "Please set it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:1501 +msgid "Hide" +msgstr "" + +#: lib/php/monica/form.inc.php:1502 +msgid "Show" +msgstr "" + +#: lib/php/monica/form.inc.php:1691 lib/php/monica/form.inc.php:1777 +#: lib/php/monica/form.inc.php:1887 +msgid "Choose" +msgstr "" + +#: lib/php/monica/form.inc.php:2237 +msgid "Delete this file" +msgstr "" + +#: lib/php/monica/form.inc.php:2267 lib/php/monica/form.inc.php:2368 +#: lib/php/monica/form.inc.php:2400 lib/php/monica/form.inc.php:2445 +#: lib/php/monica/form.inc.php:2506 +msgid "File name:" +msgstr "" + +#: lib/php/monica/form.inc.php:2274 lib/php/monica/form.inc.php:2375 +#: lib/php/monica/form.inc.php:2407 lib/php/monica/form.inc.php:2452 +#: lib/php/monica/form.inc.php:2513 +msgid "MIME file type:" +msgstr "" + +#: lib/php/monica/form.inc.php:2279 lib/php/monica/form.inc.php:2380 +#: lib/php/monica/form.inc.php:2412 lib/php/monica/form.inc.php:2457 +#: lib/php/monica/form.inc.php:2518 +msgid "File size:" +msgstr "" + +#: lib/php/monica/form.inc.php:2430 +#, c-format +msgid "Please upload it from %s." +msgstr "" + +#: lib/php/monica/form.inc.php:3128 +msgid "Address:" +msgstr "" + +#: lib/php/monica/form.inc.php:3129 +msgid "Fill in your address here." +msgstr "" + +#: lib/php/monica/form.inc.php:3135 +msgid "Attachment:" +msgstr "" + +#: lib/php/monica/form.inc.php:3139 +msgid "Attachment description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3158 lib/php/monica/form.inc.php:3171 +msgid "Content:" +msgstr "" + +#: lib/php/monica/form.inc.php:3165 +msgid "City:" +msgstr "" + +#: lib/php/monica/form.inc.php:3187 lib/php/monica/form.inc.php:3199 +#: lib/php/monica/form.inc.php:3217 lib/php/monica/form.inc.php:3241 +msgid "Country:" +msgstr "" + +#: lib/php/monica/form.inc.php:3229 +msgid "Created:" +msgstr "" + +#: lib/php/monica/form.inc.php:3235 +msgid "Created by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3247 +msgid "Date:" +msgstr "" + +#: lib/php/monica/form.inc.php:3253 lib/php/monica/form.inc.php:4292 +#: lib/php/monica/form.inc.php:4295 lib/php/monica/list.inc.php:310 +msgid "Disabled?" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 lib/php/monica/list.inc.php:2020 +msgid "Disabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 +msgid "Enabled" +msgstr "" + +#: lib/php/monica/form.inc.php:3254 +msgid "Disable it." +msgstr "" + +#: lib/php/monica/form.inc.php:3260 lib/php/monica/form.inc.php:4674 +msgid "Description:" +msgstr "" + +#: lib/php/monica/form.inc.php:3267 +msgid "E-mail:" +msgstr "" + +#: lib/php/monica/form.inc.php:3273 +msgid "Fax:" +msgstr "" + +#: lib/php/monica/form.inc.php:3279 +msgid "Group:" +msgstr "" + +#: lib/php/monica/form.inc.php:3285 lib/php/monica/form.inc.php:5558 +#: lib/php/monica/form.inc.php:5764 lib/php/monica/form.inc.php:5922 +#: lib/php/monica/form.inc.php:6015 +msgid "Hide?" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Show it" +msgstr "" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it currently." +msgstr "" + +#: lib/php/monica/form.inc.php:3292 +msgid "Host:" +msgstr "" + +#: lib/php/monica/form.inc.php:3298 lib/php/monica/list.inc.php:314 +msgid "HTML?" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2948 +#: lib/php/monica/list.inc.php:3062 +msgid "HTML" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2949 +#: lib/php/monica/list.inc.php:3063 +msgid "Plain text" +msgstr "" + +#: lib/php/monica/form.inc.php:3299 +msgid "The submitted content is HTML." +msgstr "" + +#: lib/php/monica/form.inc.php:3305 lib/php/monica/form.inc.php:5552 +#: lib/php/monica/form.inc.php:6091 +msgid "ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3311 +msgid "Introduction:" +msgstr "" + +#: lib/php/monica/form.inc.php:3312 +msgid "Fill in the introduction here." +msgstr "" + +#: lib/php/monica/form.inc.php:3318 +msgid "IP:" +msgstr "" + +#: lib/php/monica/form.inc.php:3324 +msgid "Keywords:" +msgstr "" + +#: lib/php/monica/form.inc.php:3330 +msgid "Language:" +msgstr "" + +#: lib/php/monica/form.inc.php:3355 +msgid "Name:" +msgstr "" + +#: lib/php/monica/form.inc.php:3365 lib/php/monica/form.inc.php:6009 +msgid "Order:" +msgstr "" + +#: lib/php/monica/form.inc.php:3371 +msgid "Organization:" +msgstr "" + +#: lib/php/monica/form.inc.php:3377 +msgid "Parent category:" +msgstr "" + +#: lib/php/monica/form.inc.php:3378 +msgid "At the very top" +msgstr "" + +#: lib/php/monica/form.inc.php:3391 lib/php/monica/form.inc.php:3428 +#: lib/php/monica/form.inc.php:3468 lib/php/monica/form.inc.php:4330 +#: lib/php/monica/form.inc.php:6379 +msgid "Password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3407 lib/php/monica/form.inc.php:3444 +msgid "Confirm password:" +msgstr "" + +#: lib/php/monica/form.inc.php:3458 +msgid "(Leave them blank if you don't plan to change your password.)" +msgstr "" + +#: lib/php/monica/form.inc.php:3484 +msgid "Page path:" +msgstr "" + +#: lib/php/monica/form.inc.php:3490 +msgid "PDF. file:" +msgstr "" + +#: lib/php/monica/form.inc.php:3508 lib/php/monica/form.inc.php:3570 +#: lib/php/monica/form.inc.php:3680 lib/php/monica/form.inc.php:6168 +#: lib/php/monica/form.inc.php:6192 +msgid "Picture:" +msgstr "" + +#: lib/php/monica/form.inc.php:3531 lib/php/monica/form.inc.php:3615 +#: lib/php/monica/form.inc.php:3619 lib/php/monica/form.inc.php:3693 +msgid "Pic. caption:" +msgstr "" + +#: lib/php/monica/form.inc.php:3538 lib/php/monica/form.inc.php:3639 +#: lib/php/monica/form.inc.php:3699 +msgid "Pic. position:" +msgstr "" + +#: lib/php/monica/form.inc.php:3718 lib/php/monica/form.inc.php:3746 +#: lib/php/monica/form.inc.php:3780 +msgid "Pinyin:" +msgstr "" + +#: lib/php/monica/form.inc.php:3722 lib/php/monica/form.inc.php:3756 +msgid "Please fill in the Chinese first." +msgstr "" + +#: lib/php/monica/form.inc.php:3801 +msgid "Subcategory:" +msgid_plural "Subcategories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:3823 +msgid "Script:" +msgstr "" + +#: lib/php/monica/form.inc.php:3829 +msgid "S/N:" +msgstr "" + +#: lib/php/monica/form.inc.php:3835 +msgid "Street:" +msgstr "" + +#: lib/php/monica/form.inc.php:3841 +msgid "Subject:" +msgstr "" + +#: lib/php/monica/form.inc.php:3847 +msgid "Telephone:" +msgstr "" + +#: lib/php/monica/form.inc.php:3853 +msgid "Tel. (cell.):" +msgstr "" + +#: lib/php/monica/form.inc.php:3859 +msgid "Tel. (home):" +msgstr "" + +#: lib/php/monica/form.inc.php:3865 +msgid "Tel. (office):" +msgstr "" + +#: lib/php/monica/form.inc.php:3871 +msgid "Title:" +msgstr "" + +#: lib/php/monica/form.inc.php:3891 +msgid "Value:" +msgstr "" + +#: lib/php/monica/form.inc.php:3897 +msgid "Visits:" +msgstr "" + +#: lib/php/monica/form.inc.php:3903 +msgid "Visited:" +msgstr "" + +#: lib/php/monica/form.inc.php:3909 +msgid "Updated:" +msgstr "" + +#: lib/php/monica/form.inc.php:3915 +msgid "Updated by:" +msgstr "" + +#: lib/php/monica/form.inc.php:3921 +msgid "URL.:" +msgstr "" + +#: lib/php/monica/form.inc.php:3927 +msgid "Zip code:" +msgstr "" + +#: lib/php/monica/form.inc.php:4151 +msgid "Delete this user account" +msgstr "" + +#: lib/php/monica/form.inc.php:4157 +msgid "This table provides you a form to add a new user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4161 +msgid "This table provides you a form to update a current user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4165 +msgid "This table provides you a form to delete a user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4192 +msgid "Add a New User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4196 +msgid "Update a Current User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4200 +msgid "Delete a User Account" +msgstr "" + +#: lib/php/monica/form.inc.php:4213 +msgid "This is a super-user. You can only change parts of her infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4220 +msgid "" +"This user has a datum. It cannot be deleted. To delete the user, its datum " +"must first be deleted." +msgid_plural "" +"This user has data. It cannot be deleted. To delete the user, all of its " +"data must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4282 +msgid "Administrator?" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4283 +msgid "Non-administrator" +msgstr "" + +#: lib/php/monica/form.inc.php:4296 +msgid "Disable this user account." +msgstr "" + +#: lib/php/monica/form.inc.php:4305 lib/php/monica/form.inc.php:4307 +#: lib/php/monica/form.inc.php:6371 +msgid "User ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4314 +msgid "Pref. language:" +msgstr "" + +#: lib/php/monica/form.inc.php:4320 +msgid "Full name:" +msgstr "" + +#: lib/php/monica/form.inc.php:4348 lib/php/monica/form.inc.php:4400 +#: lib/php/monica/form.inc.php:4422 lib/php/monica/form.inc.php:4496 +#: lib/php/monica/form.inc.php:4961 lib/php/monica/form.inc.php:5000 +#: lib/php/monica/form.inc.php:5016 lib/php/monica/form.inc.php:5068 +msgid "Belonging to:" +msgstr "" + +#: lib/php/monica/form.inc.php:4539 lib/php/monica/form.inc.php:4547 +#: lib/php/monica/form.inc.php:4573 +msgid "Fail logins:" +msgstr "" + +#: lib/php/monica/form.inc.php:4551 lib/php/monica/form.inc.php:4577 +msgid "(Locked)" +msgstr "" + +#: lib/php/monica/form.inc.php:4557 +msgid "Reset the counter and activate the account" +msgstr "" + +#: lib/php/monica/form.inc.php:4602 +msgid "Delete this group" +msgstr "" + +#: lib/php/monica/form.inc.php:4608 +msgid "This table provides you a form to add a new group." +msgstr "" + +#: lib/php/monica/form.inc.php:4612 +msgid "This table provides you a form to update a current group." +msgstr "" + +#: lib/php/monica/form.inc.php:4616 +msgid "This table provides you a form to delete a group." +msgstr "" + +#: lib/php/monica/form.inc.php:4641 +msgid "Add a New Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4645 +msgid "Update a Current Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4649 +msgid "Delete a Group" +msgstr "" + +#: lib/php/monica/form.inc.php:4656 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "" + +#: lib/php/monica/form.inc.php:4665 lib/php/monica/form.inc.php:4667 +msgid "Group ID.:" +msgstr "" + +#: lib/php/monica/form.inc.php:4680 +msgid "Add a user" +msgstr "" + +#: lib/php/monica/form.inc.php:4687 lib/php/monica/form.inc.php:4727 +#: lib/php/monica/form.inc.php:4745 lib/php/monica/form.inc.php:4798 +msgid "User member:" +msgid_plural "User members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:4818 lib/php/monica/form.inc.php:4955 +msgid "Add a group" +msgstr "" + +#: lib/php/monica/form.inc.php:4825 lib/php/monica/form.inc.php:4865 +#: lib/php/monica/form.inc.php:4882 lib/php/monica/form.inc.php:4935 +msgid "Group member:" +msgid_plural "Group members:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5102 lib/php/monica/form.inc.php:5177 +msgid "Delete this membership record" +msgstr "" + +#: lib/php/monica/form.inc.php:5108 lib/php/monica/form.inc.php:5183 +msgid "This table provides you a form to add a new membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5112 lib/php/monica/form.inc.php:5187 +msgid "This table provides you a form to change a current membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5116 lib/php/monica/form.inc.php:5191 +msgid "This table provides you a form to delete a membership record." +msgstr "" + +#: lib/php/monica/form.inc.php:5139 +msgid "Add a New User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5143 +msgid "Change a Current User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5147 +msgid "Delete a User Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5157 lib/php/monica/form.inc.php:5232 +msgid "Member:" +msgstr "" + +#: lib/php/monica/form.inc.php:5214 +msgid "Add a New Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5218 +msgid "Change a Current Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5222 +msgid "Delete a Group Membership Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5252 +msgid "Delete this user preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5258 +msgid "This table provides you a form to add a new user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5262 +msgid "This table provides you a form to modify a current user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5266 +msgid "This table provides you a form to delete a user preference." +msgstr "" + +#: lib/php/monica/form.inc.php:5289 +msgid "Add a New User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5293 +msgid "Modify a Current User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5297 +msgid "Delete a User Preference" +msgstr "" + +#: lib/php/monica/form.inc.php:5307 lib/php/monica/form.inc.php:5493 +msgid "User:" +msgstr "" + +#: lib/php/monica/form.inc.php:5308 lib/php/monica/list.inc.php:2588 +msgid "Everyone" +msgstr "" + +#: lib/php/monica/form.inc.php:5314 +msgid "Domain:" +msgstr "" + +#: lib/php/monica/form.inc.php:5315 lib/php/monica/list.inc.php:2592 +msgid "Everywhere" +msgstr "" + +#: lib/php/monica/form.inc.php:5335 +msgid "Delete this script privilege record" +msgstr "" + +#: lib/php/monica/form.inc.php:5341 +msgid "This table provides you a form to add a new script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5345 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5349 +msgid "This table provides you a form to delete a script privilege record." +msgstr "" + +#: lib/php/monica/form.inc.php:5372 +msgid "Add a New Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5376 +msgid "Change a Current Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5380 +msgid "Delete a Script Privilege Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5390 +msgid "Privilege:" +msgstr "" + +#: lib/php/monica/form.inc.php:5412 +msgid "Delete this user request" +msgstr "" + +#: lib/php/monica/form.inc.php:5418 +msgid "This table provides you a form to add a new user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5422 +msgid "This table provides you a form to update a current user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5426 +msgid "This table provides you a form to delete a user request." +msgstr "" + +#: lib/php/monica/form.inc.php:5449 +msgid "Add a New User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5453 +msgid "Update a Current User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5457 +msgid "Delete a User Request" +msgstr "" + +#: lib/php/monica/form.inc.php:5465 +msgid "Join" +msgstr "" + +#: lib/php/monica/form.inc.php:5469 +msgid "Change e-mail" +msgstr "" + +#: lib/php/monica/form.inc.php:5473 +msgid "Reset password" +msgstr "" + +#: lib/php/monica/form.inc.php:5481 +msgid "Expiration:" +msgstr "" + +#: lib/php/monica/form.inc.php:5487 lib/php/monica/form.inc.php:6449 +msgid "Type:" +msgstr "" + +#: lib/php/monica/form.inc.php:5494 +msgid "Anonymous" +msgstr "" + +#: lib/php/monica/form.inc.php:5500 +msgid "Arguments:" +msgstr "" + +#: lib/php/monica/form.inc.php:5518 +msgid "Delete this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5524 +msgid "This table provides you a form to add a new category." +msgstr "" + +#: lib/php/monica/form.inc.php:5528 +msgid "This table provides you a form to edit a current category." +msgstr "" + +#: lib/php/monica/form.inc.php:5532 +msgid "This table provides you a form to delete a category." +msgstr "" + +#: lib/php/monica/form.inc.php:5542 +msgid "" +"This category has a subcategory. It cannot be deleted. To delete the " +"category, its subcategory must first be deleted." +msgid_plural "" +"This category has subcategories. It cannot be deleted. To delete the " +"category, all of its subcategories must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5559 +msgid "Hide this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5559 +msgid "Show this category" +msgstr "" + +#: lib/php/monica/form.inc.php:5559 +msgid "Hide this category currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5576 +msgid "Delete this categorization record" +msgstr "" + +#: lib/php/monica/form.inc.php:5582 +msgid "This table provides you a form to add a new categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5586 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5590 +msgid "This table provides you a form to delete a categorization record." +msgstr "" + +#: lib/php/monica/form.inc.php:5635 +msgid "Add a New Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5639 +msgid "Edit a Current Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5643 +msgid "Delete a Link Category" +msgstr "" + +#: lib/php/monica/form.inc.php:5653 +msgid "" +"This category has a link. It cannot be deleted. To delete the category, " +"its link must first be deleted." +msgid_plural "" +"This category has links. It cannot be deleted. To delete the category, all " +"of its links must first be deleted." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5672 lib/php/monica/form.inc.php:5836 +msgid "Link:" +msgid_plural "Links:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5709 +msgid "Delete this related link" +msgstr "" + +#: lib/php/monica/form.inc.php:5715 +msgid "This table provides you a form to add a new related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5719 +msgid "This table provides you a form to edit a current related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5723 +msgid "This table provides you a form to delete a related link." +msgstr "" + +#: lib/php/monica/form.inc.php:5746 +msgid "Add a New Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5750 +msgid "Edit a Current Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5754 +msgid "Delete a Related Link" +msgstr "" + +#: lib/php/monica/form.inc.php:5765 +msgid "Hide this link" +msgstr "" + +#: lib/php/monica/form.inc.php:5765 lib/php/monica/form.inc.php:5923 +msgid "Show this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5765 +msgid "Hide this related link currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5772 lib/php/monica/form.inc.php:5829 +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/form.inc.php:5811 +msgid "Add a New Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5815 +msgid "Change a Current Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5819 +msgid "Delete a Link Categorization Record" +msgstr "" + +#: lib/php/monica/form.inc.php:5859 +msgid "Delete this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5865 +msgid "This table provides you a form to write a new page." +msgstr "" + +#: lib/php/monica/form.inc.php:5869 +msgid "This table provides you a form to edit a current page." +msgstr "" + +#: lib/php/monica/form.inc.php:5873 +msgid "This table provides you a form to delete a page." +msgstr "" + +#: lib/php/monica/form.inc.php:5898 +msgid "Write a New Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5902 +msgid "Edit a Current Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5906 +msgid "Delete a Page" +msgstr "" + +#: lib/php/monica/form.inc.php:5914 +msgid "Preview this page." +msgstr "" + +#: lib/php/monica/form.inc.php:5923 +msgid "Hide this page" +msgstr "" + +#: lib/php/monica/form.inc.php:5923 +msgid "Hide this page currently." +msgstr "" + +#: lib/php/monica/form.inc.php:5946 +msgid "Delete this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:5952 +msgid "This table provides you a form to write a new news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5956 +msgid "This table provides you a form to edit a current news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5960 +msgid "This table provides you a form to delete a news article." +msgstr "" + +#: lib/php/monica/form.inc.php:5985 +msgid "Write a New News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5989 +msgid "Edit a Current News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:5993 +msgid "Delete a News Article" +msgstr "" + +#: lib/php/monica/form.inc.php:6001 +msgid "Preview this news article." +msgstr "" + +#: lib/php/monica/form.inc.php:6016 +msgid "Hide this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:6016 +msgid "Show this news article" +msgstr "" + +#: lib/php/monica/form.inc.php:6016 +msgid "Hide this news article currently." +msgstr "" + +#: lib/php/monica/form.inc.php:6036 +msgid "Delete this country record" +msgstr "" + +#: lib/php/monica/form.inc.php:6042 +msgid "This table provides you a form to add a new country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6046 +msgid "This table provides you a form to edit a current country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6050 +msgid "This table provides you a form to delete a country record." +msgstr "" + +#: lib/php/monica/form.inc.php:6073 +msgid "Add a New Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6077 +msgid "Edit a Current Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6081 +msgid "Delete a Country Record" +msgstr "" + +#: lib/php/monica/form.inc.php:6097 lib/php/monica/list.inc.php:3391 +msgid "Special?" +msgstr "" + +#: lib/php/monica/form.inc.php:6098 +msgid "A special record" +msgstr "" + +#: lib/php/monica/form.inc.php:6098 +msgid "A normal country" +msgstr "" + +#: lib/php/monica/form.inc.php:6098 +msgid "This is a special record." +msgstr "" + +#: lib/php/monica/form.inc.php:6127 +msgid "This table provides you a form to add a new picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6131 +msgid "This table provides you a form to modify a current picture." +msgstr "" + +#: lib/php/monica/form.inc.php:6142 +msgid "Upload a New Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6146 +msgid "Modify a Current Picture" +msgstr "" + +#: lib/php/monica/form.inc.php:6247 lib/php/monica/form.inc.php:6259 +msgid "Ratio:" +msgstr "" + +#: lib/php/monica/form.inc.php:6284 lib/php/monica/form.inc.php:6294 +msgid "Upload:" +msgstr "" + +#: lib/php/monica/form.inc.php:6325 +msgid "This table provides you a form to log in." +msgstr "" + +#: lib/php/monica/form.inc.php:6331 +msgid "Identify Yourself" +msgstr "" + +#: lib/php/monica/form.inc.php:6340 lib/php/monica/init.inc.php:505 +msgid "" +"Log-in is temporarily closed for maintainance now. Please come again " +"later. Sorry for the inconvienence." +msgstr "" + +#: lib/php/monica/form.inc.php:6349 +msgid "Log in" +msgstr "" + +#: lib/php/monica/form.inc.php:6396 +msgid "Remember me." +msgstr "" + +#: lib/php/monica/form.inc.php:6423 +msgid "Rebuild the Pages" +msgstr "" + +#: lib/php/monica/form.inc.php:6432 +msgid "Confirm" +msgstr "" + +#: lib/php/monica/form.inc.php:6474 +msgid "Log Out" +msgstr "" + +#: lib/php/monica/form.inc.php:6483 +msgid "Log out" +msgstr "" + +#: lib/php/monica/form.inc.php:6497 +msgid "Are you sure you want to log out?" +msgstr "" + +#: lib/php/monica/init.inc.php:114 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" + +#: lib/php/monica/init.inc.php:503 lib/php/monica/init.inc.php:504 +msgid "Log-In Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:524 lib/php/monica/init.inc.php:525 +msgid "Development Site Closed" +msgstr "" + +#: lib/php/monica/init.inc.php:526 +msgid "Development site is closed. Please work on the live site." +msgstr "" + +#: lib/php/monica/links.inc.php:271 +msgid "Related Links" +msgstr "" + +#: lib/php/monica/list.inc.php:130 +msgid "Malformed" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "OK" +msgstr "" + +#: lib/php/monica/list.inc.php:155 +msgid "Unreachable" +msgstr "" + +#: lib/php/monica/list.inc.php:290 lib/php/monica/list.inc.php:1534 +#: lib/php/monica/list.inc.php:3642 +msgid "(query phrase)" +msgstr "" + +#: lib/php/monica/list.inc.php:300 +msgid "S/N" +msgstr "" + +#: lib/php/monica/list.inc.php:301 +msgid "Created" +msgstr "" + +#: lib/php/monica/list.inc.php:302 +msgid "Created by" +msgstr "" + +#: lib/php/monica/list.inc.php:303 +msgid "Updated" +msgstr "" + +#: lib/php/monica/list.inc.php:304 +msgid "Updated by" +msgstr "" + +#: lib/php/monica/list.inc.php:306 +msgid "Content" +msgstr "" + +#: lib/php/monica/list.inc.php:307 +msgid "Category" +msgstr "" + +#: lib/php/monica/list.inc.php:308 +msgid "Coverage" +msgstr "" + +#: lib/php/monica/list.inc.php:309 +msgid "Date" +msgstr "" + +#: lib/php/monica/list.inc.php:311 +msgid "Description" +msgstr "" + +#: lib/php/monica/list.inc.php:312 +msgid "E-mail" +msgstr "" + +#: lib/php/monica/list.inc.php:313 +msgid "Hidden?" +msgstr "" + +#: lib/php/monica/list.inc.php:315 +msgid "ID." +msgstr "" + +#: lib/php/monica/list.inc.php:316 +msgid "Keywords" +msgstr "" + +#: lib/php/monica/list.inc.php:317 +msgid "Name" +msgstr "" + +#: lib/php/monica/list.inc.php:318 +msgid "Order" +msgstr "" + +#: lib/php/monica/list.inc.php:319 +msgid "Page path" +msgstr "" + +#: lib/php/monica/list.inc.php:320 +msgid "Picture" +msgstr "" + +#: lib/php/monica/list.inc.php:321 +msgid "Pic. ratio" +msgstr "" + +#: lib/php/monica/list.inc.php:322 +msgid "Pic. caption" +msgstr "" + +#: lib/php/monica/list.inc.php:323 +msgid "Pic. position" +msgstr "" + +#: lib/php/monica/list.inc.php:324 +msgid "Subject" +msgstr "" + +#: lib/php/monica/list.inc.php:325 +msgid "Title" +msgstr "" + +#: lib/php/monica/list.inc.php:326 +msgid "URL." +msgstr "" + +#: lib/php/monica/list.inc.php:327 +msgid "Status (slow)" +msgstr "" + +#: lib/php/monica/list.inc.php:336 +msgid "Select" +msgstr "" + +#: lib/php/monica/list.inc.php:339 +msgid "Select a Data Record" +msgstr "" + +#: lib/php/monica/list.inc.php:343 +msgid "Edit" +msgstr "" + +#: lib/php/monica/list.inc.php:345 +msgid "Manage Data" +msgstr "" + +#: lib/php/monica/list.inc.php:749 +msgid "Nothing found. Please try another query." +msgstr "" + +#: lib/php/monica/list.inc.php:752 +msgid "The database is empty." +msgstr "" + +#: lib/php/monica/list.inc.php:759 +#, c-format +msgid "Your query found %s record." +msgid_plural "Your query found %s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:766 +#, c-format +msgid "%s record." +msgid_plural "%s records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:775 +#, c-format +msgid "Your query found %s record, listing %s to %s." +msgid_plural "Your query found %s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:784 +#, c-format +msgid "%s record, listing %s to %s." +msgid_plural "%s records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:855 lib/php/monica/list.inc.php:860 +#: lib/php/monica/list.inc.php:869 +#, c-format +msgid "Page number (%s) invalid. Please specify a valid page number." +msgstr "" + +#: lib/php/monica/list.inc.php:874 +#, c-format +msgid "" +"Page number (%d) out of range. Please specify a number between 1 and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:1138 lib/php/monica/list.inc.php:1151 +#, c-format +msgid "You cannot sort by \"%s\"." +msgstr "" + +#: lib/php/monica/list.inc.php:1512 +msgid "Search" +msgstr "" + +#: lib/php/monica/list.inc.php:1610 +msgid "Index" +msgstr "" + +#: lib/php/monica/list.inc.php:1634 +msgid "First" +msgstr "" + +#: lib/php/monica/list.inc.php:1647 +msgid "Previous" +msgstr "" + +#: lib/php/monica/list.inc.php:1696 +msgid "Next" +msgstr "" + +#: lib/php/monica/list.inc.php:1714 +msgid "Last" +msgstr "" + +#: lib/php/monica/list.inc.php:1736 +msgid "Page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1776 lib/php/monica/list.inc.php:1900 +msgid "Delete the selected items." +msgstr "" + +#: lib/php/monica/list.inc.php:1805 +msgid "No." +msgstr "" + +#: lib/php/monica/list.inc.php:1813 lib/php/monica/list.inc.php:1873 +msgid "View" +msgstr "" + +#: lib/php/monica/list.inc.php:1925 +msgid "Set" +msgstr "" + +#: lib/php/monica/list.inc.php:1941 +msgid "Rows per page:" +msgstr "" + +#: lib/php/monica/list.inc.php:1946 +msgid "Display columns:" +msgstr "" + +#: lib/php/monica/list.inc.php:1976 +msgid "Select a User" +msgstr "" + +#: lib/php/monica/list.inc.php:1977 +msgid "Manage Users" +msgstr "" + +#: lib/php/monica/list.inc.php:1982 +msgid "User ID." +msgstr "" + +#: lib/php/monica/list.inc.php:1983 +msgid "Full name" +msgstr "" + +#: lib/php/monica/list.inc.php:1984 +msgid "Deleted?" +msgstr "" + +#: lib/php/monica/list.inc.php:1985 +msgid "Pref. language" +msgstr "" + +#: lib/php/monica/list.inc.php:1986 +msgid "Visits" +msgstr "" + +#: lib/php/monica/list.inc.php:1987 +msgid "Visited" +msgstr "" + +#: lib/php/monica/list.inc.php:1988 +msgid "IP" +msgstr "" + +#: lib/php/monica/list.inc.php:1989 +msgid "Host" +msgstr "" + +#: lib/php/monica/list.inc.php:1990 +msgid "From country" +msgstr "" + +#: lib/php/monica/list.inc.php:1991 +msgid "Fail logins" +msgstr "" + +#: lib/php/monica/list.inc.php:2024 +msgid "Deleted" +msgstr "" + +#: lib/php/monica/list.inc.php:2035 +msgid "Add a new user account." +msgstr "" + +#: lib/php/monica/list.inc.php:2045 +msgid "Search for a user:" +msgstr "" + +#: lib/php/monica/list.inc.php:2063 +#, c-format +msgid "Your query found %s user." +msgid_plural "Your query found %s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2070 +#, c-format +msgid "%s user." +msgid_plural "%s users." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2079 +#, c-format +msgid "Your query found %s user, listing %s to %s." +msgid_plural "Your query found %s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2088 +#, c-format +msgid "%s user, listing %s to %s." +msgid_plural "%s users, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2107 +msgid "Select a Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2108 +msgid "Manage Groups" +msgstr "" + +#: lib/php/monica/list.inc.php:2113 +msgid "Group ID." +msgstr "" + +#: lib/php/monica/list.inc.php:2121 +msgid "Add a new group." +msgstr "" + +#: lib/php/monica/list.inc.php:2131 +msgid "Search for a group:" +msgstr "" + +#: lib/php/monica/list.inc.php:2149 +#, c-format +msgid "Your query found %s group." +msgid_plural "Your query found %s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2156 +#, c-format +msgid "%s group." +msgid_plural "%s groups." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2165 +#, c-format +msgid "Your query found %s group, listing %s to %s." +msgid_plural "Your query found %s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2174 +#, c-format +msgid "%s group, listing %s to %s." +msgid_plural "%s groups, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2194 +msgid "Select a User Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2195 +msgid "Manage User Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2200 lib/php/monica/list.inc.php:2323 +msgid "Group" +msgstr "" + +#: lib/php/monica/list.inc.php:2201 lib/php/monica/list.inc.php:2324 +msgid "Member" +msgstr "" + +#: lib/php/monica/list.inc.php:2244 lib/php/monica/list.inc.php:2375 +msgid "Add a new membership record." +msgstr "" + +#: lib/php/monica/list.inc.php:2254 lib/php/monica/list.inc.php:2385 +msgid "Search for a membership record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2272 lib/php/monica/list.inc.php:2403 +#, c-format +msgid "Your query found %s membership record." +msgid_plural "Your query found %s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2279 lib/php/monica/list.inc.php:2410 +#, c-format +msgid "%s membership record." +msgid_plural "%s membership records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2288 lib/php/monica/list.inc.php:2419 +#, c-format +msgid "Your query found %s membership record, listing %s to %s." +msgid_plural "Your query found %s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2297 lib/php/monica/list.inc.php:2428 +#, c-format +msgid "%s membership record, listing %s to %s." +msgid_plural "%s membership records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2317 +msgid "Select a Group Membership Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2318 +msgid "Manage Group Membership" +msgstr "" + +#: lib/php/monica/list.inc.php:2448 +msgid "Select a Script Privilege Record" +msgstr "" + +#: lib/php/monica/list.inc.php:2449 +msgid "Manage Script Privileges" +msgstr "" + +#: lib/php/monica/list.inc.php:2454 +msgid "Script" +msgstr "" + +#: lib/php/monica/list.inc.php:2455 +msgid "Privilege" +msgstr "" + +#: lib/php/monica/list.inc.php:2493 +msgid "Add a new script privilege record." +msgstr "" + +#: lib/php/monica/list.inc.php:2503 +msgid "Search for a script privilege record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2521 +#, c-format +msgid "Your query found %s script privilege record." +msgid_plural "Your query found %s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2528 +#, c-format +msgid "%s script privilege record." +msgid_plural "%s script privilege records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2537 +#, c-format +msgid "Your query found %s script privilege record, listing %s to %s." +msgid_plural "Your query found %s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2546 +#, c-format +msgid "%s script privilege record, listing %s to %s." +msgid_plural "%s script privilege records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2566 +msgid "Select a User Preference" +msgstr "" + +#: lib/php/monica/list.inc.php:2567 +msgid "Manage User Preferences" +msgstr "" + +#: lib/php/monica/list.inc.php:2574 lib/php/monica/list.inc.php:2689 +msgid "User" +msgstr "" + +#: lib/php/monica/list.inc.php:2575 +msgid "Domain" +msgstr "" + +#: lib/php/monica/list.inc.php:2576 +msgid "Value" +msgstr "" + +#: lib/php/monica/list.inc.php:2610 +msgid "Add a new user preference." +msgstr "" + +#: lib/php/monica/list.inc.php:2620 +msgid "Search for a user preference:" +msgstr "" + +#: lib/php/monica/list.inc.php:2638 +#, c-format +msgid "Your query found %s user preference." +msgid_plural "Your query found %s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2645 +#, c-format +msgid "%s user preference." +msgid_plural "%s user preferences." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2654 +#, c-format +msgid "Your query found %s user preference, listing %s to %s." +msgid_plural "Your query found %s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2663 +#, c-format +msgid "%s user preference, listing %s to %s." +msgid_plural "%s user preferences, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2682 +msgid "Select a User Request" +msgstr "" + +#: lib/php/monica/list.inc.php:2683 +msgid "Manage User Requests" +msgstr "" + +#: lib/php/monica/list.inc.php:2688 +msgid "Type" +msgstr "" + +#: lib/php/monica/list.inc.php:2690 +msgid "Arguments" +msgstr "" + +#: lib/php/monica/list.inc.php:2691 +msgid "Expiration" +msgstr "" + +#: lib/php/monica/list.inc.php:2699 +msgid "Add a new user request." +msgstr "" + +#: lib/php/monica/list.inc.php:2709 +msgid "Search for a user request:" +msgstr "" + +#: lib/php/monica/list.inc.php:2727 +#, c-format +msgid "Your query found %s user request." +msgid_plural "Your query found %s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2734 +#, c-format +msgid "%s user request." +msgid_plural "%s user requests." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2743 +#, c-format +msgid "Your query found %s user request, listing %s to %s." +msgid_plural "Your query found %s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2752 +#, c-format +msgid "%s user request, listing %s to %s." +msgid_plural "%s user requests, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2778 +msgid "Add a new category." +msgstr "" + +#: lib/php/monica/list.inc.php:2788 +msgid "Search for a category:" +msgstr "" + +#: lib/php/monica/list.inc.php:2806 +#, c-format +msgid "Your query found %s category." +msgid_plural "Your query found %s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2813 +#, c-format +msgid "%s category." +msgid_plural "%s categories." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2822 +#, c-format +msgid "Your query found %s category, listing %s to %s." +msgid_plural "Your query found %s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2831 +#, c-format +msgid "%s category, listing %s to %s." +msgid_plural "%s categories, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2849 +msgid "Add a new categorization record." +msgstr "" + +#: lib/php/monica/list.inc.php:2859 +msgid "Search for a categorization record:" +msgstr "" + +#: lib/php/monica/list.inc.php:2877 +#, c-format +msgid "Your query found %s categorization record." +msgid_plural "Your query found %s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2884 +#, c-format +msgid "%s categorization record." +msgid_plural "%s categorization records." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2893 +#, c-format +msgid "Your query found %s categorization record, listing %s to %s." +msgid_plural "Your query found %s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2902 +#, c-format +msgid "%s categorization record, listing %s to %s." +msgid_plural "%s categorization records, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2921 +msgid "Select a Page" +msgstr "" + +#: lib/php/monica/list.inc.php:2922 +msgid "Manage Pages" +msgstr "" + +#: lib/php/monica/list.inc.php:2952 lib/php/monica/list.inc.php:3066 +#: lib/php/monica/list.inc.php:3173 lib/php/monica/list.inc.php:3237 +#: lib/php/monica/list.inc.php:3358 +msgid "Hidden" +msgstr "" + +#: lib/php/monica/list.inc.php:2953 lib/php/monica/list.inc.php:3067 +#: lib/php/monica/list.inc.php:3174 lib/php/monica/list.inc.php:3238 +#: lib/php/monica/list.inc.php:3359 +msgid "Shown" +msgstr "" + +#: lib/php/monica/list.inc.php:2963 +msgid "Write a new page." +msgstr "" + +#: lib/php/monica/list.inc.php:2973 +msgid "Search for a page:" +msgstr "" + +#: lib/php/monica/list.inc.php:2991 +#, c-format +msgid "Your query found %s page." +msgid_plural "Your query found %s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:2998 +#, c-format +msgid "%s page." +msgid_plural "%s pages." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3007 +#, c-format +msgid "Your query found %s page, listing %s to %s." +msgid_plural "Your query found %s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3016 +#, c-format +msgid "%s page, listing %s to %s." +msgid_plural "%s pages, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3035 +msgid "Select a News Article" +msgstr "" + +#: lib/php/monica/list.inc.php:3036 +msgid "Manage News" +msgstr "" + +#: lib/php/monica/list.inc.php:3077 +msgid "Write a new news article." +msgstr "" + +#: lib/php/monica/list.inc.php:3087 +msgid "Search for a news article:" +msgstr "" + +#: lib/php/monica/list.inc.php:3105 +#, c-format +msgid "Your query found %s news article." +msgid_plural "Your query found %s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3112 +#, c-format +msgid "%s news article." +msgid_plural "%s news articles." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3121 +#, c-format +msgid "Your query found %s news article, listing %s to %s." +msgid_plural "Your query found %s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3130 +#, c-format +msgid "%s news article, listing %s to %s." +msgid_plural "%s news articles, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3149 +msgid "Select a Link Category" +msgstr "" + +#: lib/php/monica/list.inc.php:3150 +msgid "Manage Link Categories" +msgstr "" + +#: lib/php/monica/list.inc.php:3197 +msgid "Select a Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3198 +msgid "Manage Links" +msgstr "" + +#: lib/php/monica/list.inc.php:3248 +msgid "Add a new related link." +msgstr "" + +#: lib/php/monica/list.inc.php:3258 +msgid "Search for a related link:" +msgstr "" + +#: lib/php/monica/list.inc.php:3276 +#, c-format +msgid "Your query found %s related link." +msgid_plural "Your query found %s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3283 +#, c-format +msgid "%s related link." +msgid_plural "%s related links." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3292 +#, c-format +msgid "Your query found %s related link, listing %s to %s." +msgid_plural "Your query found %s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3301 +#, c-format +msgid "%s related link, listing %s to %s." +msgid_plural "%s related links, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3321 +msgid "Select a Link Categorization Record" +msgstr "" + +#: lib/php/monica/list.inc.php:3322 +msgid "Manage Link Categorization" +msgstr "" + +#: lib/php/monica/list.inc.php:3327 +msgid "Link" +msgstr "" + +#: lib/php/monica/list.inc.php:3383 +msgid "Select a Country" +msgstr "" + +#: lib/php/monica/list.inc.php:3384 +msgid "Manage Country Data" +msgstr "" + +#: lib/php/monica/list.inc.php:3389 +msgid "Code" +msgstr "" + +#: lib/php/monica/list.inc.php:3390 +msgid "Country name" +msgstr "" + +#: lib/php/monica/list.inc.php:3399 +msgid "Add a new country record." +msgstr "" + +#: lib/php/monica/list.inc.php:3409 +msgid "Search for a country:" +msgstr "" + +#: lib/php/monica/list.inc.php:3427 +#, c-format +msgid "Your query found %s country." +msgid_plural "Your query found %s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3434 +#, c-format +msgid "%s country." +msgid_plural "%s countries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3443 +#, c-format +msgid "Your query found %s country, listing %s to %s." +msgid_plural "Your query found %s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3452 +#, c-format +msgid "%s country, listing %s to %s." +msgid_plural "%s countries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3474 +msgid "Browse the Activity Log" +msgstr "" + +#: lib/php/monica/list.inc.php:3586 +msgid "Please fill in the number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3590 +#, c-format +msgid "This number of rows to display is too long. (Max. length %d)" +msgstr "" + +#: lib/php/monica/list.inc.php:3595 +msgid "Please fill in a positive integer number of rows to display." +msgstr "" + +#: lib/php/monica/list.inc.php:3599 lib/php/monica/list.inc.php:3609 +#, c-format +msgid "" +"The number of rows to display is too small. Please fill in a larger number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3613 +#, c-format +msgid "" +"The number of rows to display is too large. Please fill in a smaller number " +"of rows to display between %d and %d." +msgstr "" + +#: lib/php/monica/list.inc.php:3638 +msgid "Search for log entries:" +msgstr "" + +#: lib/php/monica/list.inc.php:3641 +msgid "Display" +msgstr "" + +#: lib/php/monica/list.inc.php:3654 +msgid "Display rows:" +msgstr "" + +#: lib/php/monica/list.inc.php:3677 +#, c-format +msgid "Your query found %s log entry." +msgid_plural "Your query found %s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3684 +#, c-format +msgid "%s log entry." +msgid_plural "%s log entries." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3693 +#, c-format +msgid "Your query found %s log entry, listing %s to %s." +msgid_plural "Your query found %s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/list.inc.php:3702 +#, c-format +msgid "%s log entry, listing %s to %s." +msgid_plural "%s log entries, listing %s to %s." +msgstr[0] "" +msgstr[1] "" + +#: lib/php/monica/lninfo.inc.php:28 +msgid "English" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:39 +msgid "Traditional Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:50 +msgid "Simplified Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:61 +msgid "Chinese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:72 +msgid "Japanese" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:83 +msgid "Korean" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:94 +msgid "German" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:105 +msgid "Spanish" +msgstr "" + +#: lib/php/monica/lninfo.inc.php:366 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:738 +msgid "Web pages" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:739 +msgid "News" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:740 +msgid "Related links" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:741 +msgid "Home page" +msgstr "" + +#: lib/php/monica/pagefunc.inc.php:742 +msgid "Whole web site" +msgstr "" + +#: lib/php/monica/pic.inc.php:39 +msgid "Left-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:40 +msgid "Right-aligned" +msgstr "" + +#: lib/php/monica/pic.inc.php:74 lib/php/monica/pic.inc.php:77 +#, c-format +msgid "This picture file is too large (Max %s)." +msgstr "" + +#: lib/php/monica/pic.inc.php:92 +msgid "Please upload only PNG, JPEG or GIF files." +msgstr "" + +#: lib/php/monica/pic.inc.php:153 +#, c-format +msgid "Width: %d, height: %d, ratio: %0.2f" +msgstr "" + +#: lib/php/monica/pic.inc.php:176 +msgid "Please specify a numeric ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:180 +msgid "Please specify a positive ratio." +msgstr "" + +#: lib/php/monica/pic.inc.php:183 +#, c-format +msgid "Please specify a ratio less than or equal to %0.2f." +msgstr "" + +#: lib/php/monica/pic.inc.php:189 +msgid "This image is too large to display." +msgstr "" + +#: lib/php/monica/preview.inc.php:47 +#, c-format +msgid "Unknown preview source: \"%s\"." +msgstr "" + +#: lib/php/monica/preview.inc.php:67 +#, c-format +msgid "Unknown preview form: %d." +msgstr "" + +#: lib/php/monica/preview.inc.php:143 +msgid "Preview Mark Area" +msgstr "" + +#: lib/php/monica/preview.inc.php:148 +msgid "Finish preview and return." +msgstr "" + +#: lib/php/monica/process.inc.php:237 +msgid "This record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:243 +msgid "This record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:247 +msgid "This record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:251 +msgid "This record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:406 +msgid "This category was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:412 +msgid "This category has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:416 +msgid "This category has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:420 +msgid "This category has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:433 +msgid "This categorization record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:439 +msgid "This categorization record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:443 +msgid "This categorization record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:447 +msgid "This categorization record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:782 +msgid "This user account was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:788 +msgid "This user account has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:792 +msgid "This user account has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:796 +msgid "This user account has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1074 +msgid "This group was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1080 +msgid "This group has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1084 +msgid "This group has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1088 +msgid "This group has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1152 lib/php/monica/process.inc.php:1230 +msgid "This membership record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1158 lib/php/monica/process.inc.php:1236 +msgid "This membership record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1162 lib/php/monica/process.inc.php:1240 +msgid "This membership record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1166 lib/php/monica/process.inc.php:1244 +msgid "This membership record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1308 +msgid "This script privilege record was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1314 +msgid "This script privilege record has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1318 +msgid "This script privilege record has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1322 +msgid "This script privilege record has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1438 +msgid "This user preference was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1444 +msgid "This user preference has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1448 +msgid "This user preference has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1452 +msgid "This user preference has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1560 +msgid "This user request was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1566 +msgid "This user request has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1570 +msgid "This user request has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1574 +msgid "This user request has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1685 +msgid "This page was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1691 +msgid "This page has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1695 +msgid "This page has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1699 +msgid "This page has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1874 +msgid "This news article was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:1880 +msgid "This news article has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:1884 +msgid "This news article has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:1888 +msgid "This news article has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:1997 +msgid "This country was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2003 +msgid "This country has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2007 +msgid "This country has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2011 +msgid "This country has been successfully deleted." +msgstr "" + +#: lib/php/monica/process.inc.php:2097 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. (%0.3f seconds)" +msgstr "" + +#: lib/php/monica/process.inc.php:2158 +#, c-format +msgid "Welcome, %s!" +msgstr "" + +#: lib/php/monica/process.inc.php:2204 +msgid "You have successfully logged out." +msgstr "" + +#: lib/php/monica/process.inc.php:2439 +msgid "This related link was not modified." +msgstr "" + +#: lib/php/monica/process.inc.php:2445 +msgid "This related link has been successfully added." +msgstr "" + +#: lib/php/monica/process.inc.php:2449 +msgid "This related link has been successfully updated." +msgstr "" + +#: lib/php/monica/process.inc.php:2453 +msgid "This related link has been successfully deleted." +msgstr "" + +#: lib/php/monica/request.inc.php:38 +msgid "Please specify the request." +msgstr "" + +#: lib/php/monica/request.inc.php:46 lib/php/monica/request.inc.php:55 +#, c-format +msgid "Invalid request S/N: %s." +msgstr "" + +#: lib/php/monica/sitesize.inc.php:41 +#, c-format +msgid "Currently using files %s.\n" +msgstr "" + +#: lib/php/monica/sitesize.inc.php:46 +#, c-format +msgid "Currently using files %s, database %s, total %s.\n" +msgstr "" + +#: lib/php/monica/upload.inc.php:70 +#, c-format +msgid "MIME file type: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:71 +#, c-format +msgid "File name: %s" +msgstr "" + +#: lib/php/monica/upload.inc.php:72 +#, c-format +msgid "File size: %s bytes" +msgstr "" + +#: lib/php/monica/validate.inc.php:116 +msgid "HTML Validatior Logo Area" +msgstr "" + +#: lib/php/monica/validate.inc.php:117 +msgid "HTML validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:118 +#, c-format +msgid "Valid %s!" +msgstr "" + +#: lib/php/monica/validate.inc.php:119 +msgid "CSS validation result of this page" +msgstr "" + +#: lib/php/monica/validate.inc.php:120 +msgid "Valid CSS!" +msgstr "" + +#: lib/php/monica/validate.inc.php:121 +msgid "Explanation of Level Triple-A Conformance" +msgstr "" + +#: lib/php/monica/validate.inc.php:122 +msgid "" +"Level Triple-A conformance icon, W3C-WAI Web Content Accessibility " +"Guidelines 1.0" +msgstr "" diff --git a/po/monica/zh_CN.gmo b/po/monica/zh_CN.gmo new file mode 100644 index 0000000..77f3dca Binary files /dev/null and b/po/monica/zh_CN.gmo differ diff --git a/po/monica/zh_CN.po b/po/monica/zh_CN.po new file mode 100644 index 0000000..3783f5a --- /dev/null +++ b/po/monica/zh_CN.po @@ -0,0 +1,3243 @@ +# Simplified Chinese PO file for the monica core +# Copyright (C) 2002-2018 Pristine Communcations +# This file is distributed under the same license as the monica package. +# imacat , 2002-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: monica 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 12:53+0800\n" +"PO-Revision-Date: 2018-11-02 01:26+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: lib/php/monica/checker.inc.php:159 +msgid "Please select a user." +msgstr "请选择用户。" + +#: lib/php/monica/checker.inc.php:163 +msgid "This user does not exist anymore. Please select another one." +msgstr "查无此人,请重新选择。" + +#: lib/php/monica/checker.inc.php:181 +msgid "Please select a group." +msgstr "请选择群组。" + +#: lib/php/monica/checker.inc.php:185 +msgid "This group does not exist anymore. Please select another one." +msgstr "查无此群组,请重新选择。" + +#: lib/php/monica/checker.inc.php:203 +msgid "Please fill in the script." +msgstr "请填上程序文件名。" + +#: lib/php/monica/checker.inc.php:207 +#, c-format +msgid "This script is too long. (Max. length %d)" +msgstr "程序文件名太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:212 +msgid "This script is not a valid script. Please specify another one." +msgstr "查无此程序,请重新设置运行的程序。" + +#: lib/php/monica/checker.inc.php:230 +msgid "Please fill in the date." +msgstr "请填上日期。" + +#: lib/php/monica/checker.inc.php:234 lib/php/monica/checker.inc.php:238 +#: lib/php/monica/checker.inc.php:241 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期请以 YYYY-MM-DD 格式正确填写。" + +#: lib/php/monica/checker.inc.php:259 +msgid "Please fill in the ID." +msgstr "请填上代号。" + +#: lib/php/monica/checker.inc.php:263 +#, c-format +msgid "This ID. is too long. (Max. length %d)" +msgstr "代号太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:267 +#, c-format +msgid "This ID. is too short. (Min. length %d)" +msgstr "代号太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:272 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "代号限用小写英文本母、数字和底线。" + +#: lib/php/monica/checker.inc.php:294 +msgid "Please fill in the order." +msgstr "请填上先后次序。" + +#: lib/php/monica/checker.inc.php:298 +#, c-format +msgid "This order is too long. (Max. length %d)" +msgstr "次序太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:303 +msgid "Please fill in a positive integer order." +msgstr "次序请填正整数。" + +#: lib/php/monica/checker.inc.php:307 lib/php/monica/checker.inc.php:317 +#, c-format +msgid "" +"The order is too small. Please fill in a larger order between %d and %d." +msgstr "次序太小了,请设置在 %d 到 %d 之间。" + +#: lib/php/monica/checker.inc.php:321 +#, c-format +msgid "" +"The order is too large. Please fill in a smaller order between %d and %d." +msgstr "次序太大了,请设置在 %d 到 %d 之间。" + +#: lib/php/monica/checker.inc.php:348 +msgid "Please fill in the page path." +msgstr "请填上网页路径。" + +#: lib/php/monica/checker.inc.php:352 +#, c-format +msgid "This page path is too long. (Max. length %d)" +msgstr "网页路径太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:365 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "已有同一网页,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:369 +msgid "Please fill in an absolute page path." +msgstr "网页路径请填上绝对路径。" + +#: lib/php/monica/checker.inc.php:373 +msgid "Please fill in a valid page path." +msgstr "网页路径请填上正确路径。" + +#: lib/php/monica/checker.inc.php:377 +msgid "You cannot overwrite the cover home page." +msgstr "不可以程序设置首页。" + +#: lib/php/monica/checker.inc.php:381 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "网页路径限填 HTML 地址( *.html )。" + +#: lib/php/monica/checker.inc.php:422 lib/php/monica/checker.inc.php:428 +msgid "Please fill in the attachment description." +msgstr "请填上附件说明。" + +#: lib/php/monica/checker.inc.php:432 +#, c-format +msgid "This attachment description is too long. (Max. length %d)" +msgstr "附件说明太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:449 +msgid "This PDF. file does not exist anymore. Please upload another one." +msgstr "查无此 PDF. 档,请重新上传文件。" + +#: lib/php/monica/checker.inc.php:456 +#, c-format +msgid "This PDF. file is too large. (Max. size %s)" +msgstr "文件太大。(上限 %s )" + +#: lib/php/monica/checker.inc.php:461 +msgid "Please upload only PDF. file." +msgstr "限上传 PDF. 档。" + +#: lib/php/monica/checker.inc.php:479 +msgid "Please fill in the title." +msgstr "请填上标题。" + +#: lib/php/monica/checker.inc.php:483 +#, c-format +msgid "This title is too long. (Max. length %d)" +msgstr "标题太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:502 +msgid "Please fill in the subject." +msgstr "请填上主题。" + +#: lib/php/monica/checker.inc.php:506 +#, c-format +msgid "This subject is too long. (Max. length %d)" +msgstr "主题太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:524 lib/php/monica/form.inc.php:3159 +#: lib/php/monica/form.inc.php:3172 +msgid "Fill in the content here." +msgstr "请填上内文。" + +#: lib/php/monica/checker.inc.php:528 +msgid "Please fill in the content." +msgstr "请填上内文。" + +#: lib/php/monica/checker.inc.php:532 +#, c-format +msgid "This content is too long. (Max. length %d)" +msgstr "内文太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:551 +msgid "Please fill in the keywords." +msgstr "请填上关键字。" + +#: lib/php/monica/checker.inc.php:555 +#, c-format +msgid "This keyword list is too long. (Max. length %d)" +msgstr "关键字太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:572 +msgid "Please select a proper pinyin." +msgstr "请选择符合的拼音。" + +#: lib/php/monica/checker.inc.php:578 +#, c-format +msgid "This pinyin is too long. (Max. length %d)" +msgstr "拼音太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:583 +msgid "" +"This pinyin does not match the Chinese. Please select a proper pinyin from " +"the list." +msgstr "拼音与中文不合,请重新于列表中选择。" + +#: lib/php/monica/checker.inc.php:609 lib/php/monica/pic.inc.php:82 +msgid "Please upload the picture." +msgstr "请上传图档。" + +#: lib/php/monica/checker.inc.php:616 lib/php/monica/checker.inc.php:3214 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "查无此图,请重新上传图档。" + +#: lib/php/monica/checker.inc.php:622 +#, c-format +msgid "This picture is too large. Please upload another one. (Max. size %d)" +msgstr "图档太大,请重新上传图档(最大 %d )。" + +#: lib/php/monica/checker.inc.php:639 lib/php/monica/form.inc.php:3588 +#, c-format +msgid "Please upload a new picture from %s." +msgstr "请由%s建新图片。" + +#: lib/php/monica/checker.inc.php:664 lib/php/monica/checker.inc.php:727 +msgid "Please fill in the picture caption." +msgstr "请填上图片标题。" + +#: lib/php/monica/checker.inc.php:668 lib/php/monica/checker.inc.php:731 +#, c-format +msgid "This picture caption is too long. (Max. length %d)" +msgstr "图片标题太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:686 lib/php/monica/checker.inc.php:749 +msgid "Please select the picture position." +msgstr "请设置图片位置。" + +#: lib/php/monica/checker.inc.php:692 lib/php/monica/checker.inc.php:755 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "图片位置无效。请由表上选择适当的图片位置。" + +#: lib/php/monica/checker.inc.php:791 lib/php/monica/checker.inc.php:794 +#, c-format +msgid "Your uploaded file is too large (Max %s)." +msgstr "上传文件太大。(上限 %s )" + +#: lib/php/monica/checker.inc.php:797 lib/php/monica/pic.inc.php:80 +msgid "" +"Upload not completed. Disk may be full or connection may be closed in the " +"half. You may try to upload again, or contact the system administrator for " +"this problem." +msgstr "" +"上传失败。可能是服务器磁盘满了,或传到一半网络断线。请重新上传一次,或洽网站" +"系统管理人员处理。" + +#: lib/php/monica/checker.inc.php:799 lib/php/monica/pic.inc.php:84 +#, c-format +msgid "Upload failed with an unknown error (%d)." +msgstr "上传失败,原因不明。( %d )" + +#: lib/php/monica/checker.inc.php:1183 lib/php/monica/chkfunc.inc.php:59 +#: lib/php/monica/chkfunc.inc.php:72 lib/php/monica/preview.inc.php:29 +#, c-format +msgid "The following field was not received: \"%s\"." +msgstr "程序没有收到下列字段:「 %s 」" + +#: lib/php/monica/checker.inc.php:1262 +msgid "Please fill in the user ID." +msgstr "请填上帐号。" + +#: lib/php/monica/checker.inc.php:1266 +#, c-format +msgid "This user ID. is too long. (Max. length %d)" +msgstr "帐号太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:1270 +#, c-format +msgid "This user ID. is too short. (Min. length %d)" +msgstr "帐号太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1275 +msgid "" +"Only lower-case English letters, numbers, at-signs, dots, dashes and " +"underscores are allowed for the user ID." +msgstr "帐号限用小写英文本母、数字、 @ 号、点、横线和底线。" + +#: lib/php/monica/checker.inc.php:1287 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "该用户已有帐号,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:1317 +msgid "Please fill in the password." +msgstr "请填上密码。" + +#: lib/php/monica/checker.inc.php:1320 +msgid "Please confirm the password." +msgstr "请确认密码。" + +#: lib/php/monica/checker.inc.php:1324 +#, c-format +msgid "This password is too long. (Max. length %d)" +msgstr "密码太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:1329 +#, c-format +msgid "This password is too short. (Min. length %d)" +msgstr "密码太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1334 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "两次密码不合,请重新设置密码。" + +#: lib/php/monica/checker.inc.php:1345 +msgid "This password is based on the user ID." +msgstr "密码不可由帐号组成。" + +#: lib/php/monica/checker.inc.php:1360 +msgid "This password does not contain enough different characters." +msgstr "密码重复的字符太多。" + +#: lib/php/monica/checker.inc.php:1364 +msgid "This password is too simplistic/systematic." +msgstr "密码结构太简单。" + +#: lib/php/monica/checker.inc.php:1368 +msgid "This password is based on a dictionary word." +msgstr "密码不可由字典单字组成。" + +#: lib/php/monica/checker.inc.php:1370 +msgid "This password is based on a (reversed) dictionary word." +msgstr "密码不可由倒过来的字典单字组成。" + +#: lib/php/monica/checker.inc.php:1372 +msgid "This password is too simple." +msgstr "密码太简单。" + +#: lib/php/monica/checker.inc.php:1378 +msgid "You cannot use a password that is based on the user ID." +msgstr "密码不可由帐号组成。" + +#: lib/php/monica/checker.inc.php:1397 +msgid "Please fill in the name." +msgstr "请填上姓名。" + +#: lib/php/monica/checker.inc.php:1401 +#, c-format +msgid "This name is too long. (Max. length %d)" +msgstr "姓名太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:1420 +msgid "Please fill in the e-mail." +msgstr "请填上 E-mail 信箱。" + +#: lib/php/monica/checker.inc.php:1424 +#, c-format +msgid "This e-mail is too long. (Max. length %d)" +msgstr "E-mail 信箱太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:1428 +#, c-format +msgid "This e-mail is too short. (Min. length %d)" +msgstr "E-mail 信箱太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1437 +msgid "Please fill in a valid e-mail address." +msgstr "请填上正确的 E-mail 信箱。" + +#: lib/php/monica/checker.inc.php:1439 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "查无这个信箱的所属网域,请检查有没有拼错。" + +#: lib/php/monica/checker.inc.php:1461 lib/php/monica/checker.inc.php:1655 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "隶属群组重复,请勿重复设置。" + +#: lib/php/monica/checker.inc.php:1478 +msgid "You cannot submit the super-user group along with other groups." +msgstr "总管理员群组不可与其它群组一起设置。" + +#: lib/php/monica/checker.inc.php:1480 +msgid "You cannot set the administrators group." +msgstr "不可设置所有网站管理员群组" + +#: lib/php/monica/checker.inc.php:1482 +msgid "You cannot set the all-users group." +msgstr "不可设置所有登录用户群组。" + +#: lib/php/monica/checker.inc.php:1515 +msgid "Please fill in the group ID." +msgstr "请填上群组代号。" + +#: lib/php/monica/checker.inc.php:1519 +#, c-format +msgid "This group ID. is too long. (Max. length %d)" +msgstr "群组代号太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:1523 +#, c-format +msgid "This group ID. is too short. (Min. length %d)" +msgstr "群组代号太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1528 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "群组代号限用小写英文本母、数字和底线。" + +#: lib/php/monica/checker.inc.php:1540 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "已有同一群组,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:1558 +msgid "Please fill in the privilege description." +msgstr "请填上权限说明。" + +#: lib/php/monica/checker.inc.php:1562 +#, c-format +msgid "This privilege description is too long. (Max. length %d)" +msgstr "权限说明太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:1585 +msgid "This user member is duplicated. You cannot set duplicated ones." +msgstr "用户成员重复,请勿重复设置。" + +#: lib/php/monica/checker.inc.php:1620 +msgid "This group member is duplicated. You cannot set duplicated ones." +msgstr "群组成员重复,请勿重复设置。" + +#: lib/php/monica/checker.inc.php:1747 lib/php/monica/checker.inc.php:1855 +msgid "Please select a member." +msgstr "请选择成员。" + +#: lib/php/monica/checker.inc.php:1751 lib/php/monica/checker.inc.php:1859 +msgid "This member does not exist anymore. Please select another one." +msgstr "查无此成员,请重新选择。" + +#: lib/php/monica/checker.inc.php:1770 lib/php/monica/checker.inc.php:1883 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "已有同一成员关系,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:1837 +msgid "Please select a different belonging group." +msgstr "隶属群组请选择别的群组。" + +#: lib/php/monica/checker.inc.php:1864 +msgid "Please select a different group member." +msgstr "群组成员请选择别的群组。" + +#: lib/php/monica/checker.inc.php:1958 +msgid "" +"This script privilege already exists. You cannot create a duplicated one." +msgstr "已有同一程序权限,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:1996 lib/php/monica/checker.inc.php:2184 +msgid "Please select the user." +msgstr "请选择用户。" + +#: lib/php/monica/checker.inc.php:2002 lib/php/monica/checker.inc.php:2190 +msgid "This option is invalid. Please select a proper user." +msgstr "用户选项无效,请由表上选择适当的用户。" + +#: lib/php/monica/checker.inc.php:2020 +msgid "Please set the preference domain." +msgstr "请设置适用范围。" + +#: lib/php/monica/checker.inc.php:2026 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "适用范围选项无效,请设置适当的适用范围。" + +#: lib/php/monica/checker.inc.php:2039 lib/php/monica/checker.inc.php:2295 +msgid "Please fill in the preference domain." +msgstr "请填上偏好的适用范围。" + +#: lib/php/monica/checker.inc.php:2043 lib/php/monica/checker.inc.php:2299 +#, c-format +msgid "This preference domain is too long. (Max. length %d)" +msgstr "偏好适用范围太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2063 +msgid "Please fill in the preference name." +msgstr "请填上偏好的名称。" + +#: lib/php/monica/checker.inc.php:2067 +#, c-format +msgid "This preference name is too long. (Max. length %d)" +msgstr "偏好名称太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2086 +msgid "Please fill in the preference value." +msgstr "请填上偏好的值。" + +#: lib/php/monica/checker.inc.php:2090 +#, c-format +msgid "This preference value is too long. (Max. length %d)" +msgstr "偏好值太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2119 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "已有同一用户偏好,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:2167 +msgid "Please select the request type." +msgstr "请选择申请类别。" + +#: lib/php/monica/checker.inc.php:2173 +msgid "This option is invalid. Please select a proper request type." +msgstr "申请类别选项无效,请由表上选择适当的申请类别。" + +#: lib/php/monica/checker.inc.php:2194 +msgid "You must choose anonymous for join requests." +msgstr "加入申请不可具名。" + +#: lib/php/monica/checker.inc.php:2197 +msgid "You cannot choose anonymous for non-join requests." +msgstr "非加入申请必须具名。" + +#: lib/php/monica/checker.inc.php:2221 lib/php/monica/form.inc.php:5502 +msgid "Please fill in the request arguments list here." +msgstr "请填上备注数据。" + +#: lib/php/monica/checker.inc.php:2229 +#, c-format +msgid "This request arguments list is too long. (Max. length %d)" +msgstr "申请备注数据太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2349 +msgid "Please fill in the number of rows per page." +msgstr "请填上每页显示笔数。" + +#: lib/php/monica/checker.inc.php:2353 +#, c-format +msgid "This number of rows per page is too long. (Max. length %d)" +msgstr "每页显示笔数太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2358 +msgid "Please fill in a positive integer number of rows per page." +msgstr "每页显示笔数请填正整数。" + +#: lib/php/monica/checker.inc.php:2362 lib/php/monica/checker.inc.php:2372 +#, c-format +msgid "" +"The number of rows per page is too small. Please fill in a larger number of " +"rows per page between %d and %d." +msgstr "每页显示笔数太小了,请设置在 %d 到 %d 之间。" + +#: lib/php/monica/checker.inc.php:2376 +#, c-format +msgid "" +"The number of rows per page is too large. Please fill in a smaller number " +"of rows per page between %d and %d." +msgstr "每页显示笔数太大了,请设置在 %d 到 %d 之间。" + +#: lib/php/monica/checker.inc.php:2443 +msgid "Please fill in your user ID." +msgstr "请填上你的帐号。" + +#: lib/php/monica/checker.inc.php:2451 lib/php/monica/checker.inc.php:2458 +#: lib/php/monica/checker.inc.php:2475 lib/php/monica/checker.inc.php:2508 +#: lib/php/monica/checker.inc.php:2540 lib/php/monica/checker.inc.php:2548 +#: lib/php/monica/checker.inc.php:2558 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "登录错误,用户代号或密码有误。" + +#: lib/php/monica/checker.inc.php:2495 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "帐号停用中,请洽系统管理员。" + +#: lib/php/monica/checker.inc.php:2531 +msgid "Please fill in your password." +msgstr "请填上你的密码。" + +#: lib/php/monica/checker.inc.php:2581 +msgid "You are not an administrator so may not log in here." +msgstr "非管理员勿入。" + +#: lib/php/monica/checker.inc.php:2600 +msgid "You are an administrator so may not log in here." +msgstr "管理人员勿入。" + +#: lib/php/monica/checker.inc.php:2751 +msgid "Please fill in the code." +msgstr "请填上代码。" + +#: lib/php/monica/checker.inc.php:2755 +#, c-format +msgid "You must fill in a %d-letters code." +msgstr "代码限为两个字母。" + +#: lib/php/monica/checker.inc.php:2760 +msgid "You can only use upper letters and for the code." +msgstr "代码限用大写英文本母。" + +#: lib/php/monica/checker.inc.php:2772 +msgid "This code is duplicated. You cannot create a duplicated one." +msgstr "代码重复,请勿重复设置。" + +#: lib/php/monica/checker.inc.php:2790 +msgid "Please fill in the country name." +msgstr "请填上国名。" + +#: lib/php/monica/checker.inc.php:2794 +#, c-format +msgid "This country name is too long. (Max. length %d)" +msgstr "国名太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2822 lib/php/monica/checker.inc.php:2841 +msgid "Please select a parent category." +msgstr "请选择所属的大类。" + +#: lib/php/monica/checker.inc.php:2828 +msgid "This option is invalid. Please select a proper parent category." +msgstr "大类选项无效,请由表上选择适当的大类。" + +#: lib/php/monica/checker.inc.php:2845 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "查无此大类,请重新选择。" + +#: lib/php/monica/checker.inc.php:2850 +msgid "A category cannot belong to itself. Please select another one." +msgstr "分类不可属于自己本身,请重新选择。" + +#: lib/php/monica/checker.inc.php:2858 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "分类不可属于自己的子类,请重新选择。" + +#: lib/php/monica/checker.inc.php:2876 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "「 index 」为目录档 index.html 专用,代号不可设为「 index 」。" + +#: lib/php/monica/checker.inc.php:2894 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "已有同一分类,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:2941 +msgid "Please fill in the URL.." +msgstr "请填上网址。" + +#: lib/php/monica/checker.inc.php:2945 +#, c-format +msgid "This URL. is too long. (Max. length %d)" +msgstr "网址太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2950 +msgid "Please fill in a valid URL.." +msgstr "请填上正确网址。" + +#: lib/php/monica/checker.inc.php:2962 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "已有同一相关链接,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:2967 +msgid "This URL. is not reachable. Check if there is any typo in it." +msgstr "这个网址连不上,请检查有没有拼错。" + +#: lib/php/monica/checker.inc.php:2984 lib/php/monica/form.inc.php:3261 +msgid "Fill in the description here." +msgstr "请填上说明。" + +#: lib/php/monica/checker.inc.php:2988 +msgid "Please fill in the description." +msgstr "请填上说明。" + +#: lib/php/monica/checker.inc.php:2992 +#, c-format +msgid "This description is too long. (Max. length %d)" +msgstr "说明太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:3012 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "分类重复,请勿重复设置。。" + +#: lib/php/monica/checker.inc.php:3016 lib/php/monica/checker.inc.php:3072 +msgid "This category does not exist anymore. Please select another one." +msgstr "查无此分类,请重新选择。" + +#: lib/php/monica/checker.inc.php:3022 lib/php/monica/checker.inc.php:3068 +msgid "Please select a category." +msgstr "请选择分类。" + +#: lib/php/monica/checker.inc.php:3090 +msgid "Please select a related link." +msgstr "请选择相关链接。" + +#: lib/php/monica/checker.inc.php:3094 +msgid "This link does not exist anymore. Please select another one." +msgstr "查无此相关链接,请重新选择。" + +#: lib/php/monica/checker.inc.php:3113 +msgid "" +"This link categorization already exists. You cannot create a duplicated one." +msgstr "已有同一链接分类数据,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:3154 +msgid "Please select the type." +msgstr "请选择类型。" + +#: lib/php/monica/checker.inc.php:3158 +msgid "This type does not exist anymore. Please select another one." +msgstr "查无此类型,请重新选择。" + +#: lib/php/monica/checker.inc.php:3185 lib/php/monica/list.inc.php:961 +msgid "Please fill in your query." +msgstr "请填上查找的内容。" + +#: lib/php/monica/checker.inc.php:3210 +msgid "Please submit the picture." +msgstr "请上传图档。" + +#: lib/php/monica/checker.inc.php:3237 lib/php/monica/checker.inc.php:3328 +msgid "Please fill in the resize ratio." +msgstr "请填上缩放比例。" + +#: lib/php/monica/checker.inc.php:3305 +msgid "Please specify a valid picture." +msgstr "您上传的不是图档,请重新上传图档。" + +#: lib/php/monica/chkfunc.inc.php:156 lib/php/monica/chkfunc.inc.php:160 +#: lib/php/monica/chkfunc.inc.php:163 lib/php/monica/chkfunc.inc.php:166 +msgid "Please select a legal year." +msgstr "请选一个正确的年份。" + +#: lib/php/monica/chkfunc.inc.php:171 lib/php/monica/chkfunc.inc.php:175 +#: lib/php/monica/chkfunc.inc.php:178 +msgid "Please select a legal month." +msgstr "请选一个正确的月份。" + +#: lib/php/monica/chkfunc.inc.php:183 lib/php/monica/chkfunc.inc.php:187 +#: lib/php/monica/chkfunc.inc.php:193 +msgid "Please select a legal day." +msgstr "请选一个正确的日期。" + +#: lib/php/monica/chkwrite.inc.php:27 +#, c-format +msgid "%s: It is not a file." +msgstr "%s: 这不是文件。" + +#: lib/php/monica/chkwrite.inc.php:32 +#, c-format +msgid "%s: You have no permission to overwrite this file." +msgstr "%s: 存盘的权限不足,无法存盘。" + +#: lib/php/monica/chkwrite.inc.php:45 +#, c-format +msgid "%s: You cannot create anything under the root directory." +msgstr "%s: 不可在根目录下建档。" + +#: lib/php/monica/chkwrite.inc.php:50 +#, c-format +msgid "" +"%s: One of the parents of this file (%s) is not a directory. You cannot " +"create any new file inside." +msgstr "%s: 路径中间有一部份( %s )不是目录,无法往下建档。" + +#: lib/php/monica/chkwrite.inc.php:55 +#, c-format +msgid "%s: You have no permission to create any file under %s." +msgstr "%s: 权限不足,无法在 %s 建档。" + +#: lib/php/monica/commtext.inc.php:18 +msgid "(not set)" +msgstr "(未设置)" + +#: lib/php/monica/commtext.inc.php:24 +msgid "(none)" +msgstr "(无)" + +#: lib/php/monica/commtext.inc.php:30 +msgid "(N/A)" +msgstr "(不可考)" + +#: lib/php/monica/commtext.inc.php:36 +msgid "(blank)" +msgstr "(留白)" + +#: lib/php/monica/echoform.inc.php:173 +#, c-format +msgid "%s bytes" +msgstr "%s 字节" + +#: lib/php/monica/form.inc.php:168 +msgid "Delete it" +msgstr "删掉" + +#: lib/php/monica/form.inc.php:174 +msgid "Are you sure you want to delete it? It cannot be recovered." +msgstr "你真的要删掉吗?数据删掉就救不回来了。" + +#: lib/php/monica/form.inc.php:188 +msgid "*" +msgstr "" + +#: lib/php/monica/form.inc.php:224 +msgid "This table provides you a form to add a new data record." +msgstr "本表提供建新数据的表单。" + +#: lib/php/monica/form.inc.php:228 +msgid "This table provides you a form to update a current data record." +msgstr "本表提供异动数据的表单。" + +#: lib/php/monica/form.inc.php:232 +msgid "This table provides you a form to delete a data record." +msgstr "本表提供删除数据的表单。" + +#: lib/php/monica/form.inc.php:281 +msgid "Add a New Data Record" +msgstr "建新数据" + +#: lib/php/monica/form.inc.php:285 +msgid "Update a Current Data Record" +msgstr "异动数据" + +#: lib/php/monica/form.inc.php:289 +msgid "Delete a Data Record" +msgstr "删除数据" + +#: lib/php/monica/form.inc.php:301 +msgid "Preview it." +msgstr "预览。" + +#: lib/php/monica/form.inc.php:500 lib/php/monica/form.inc.php:506 +#: lib/php/monica/form.inc.php:691 lib/php/monica/form.inc.php:697 +#: lib/php/monica/preview.inc.php:146 +msgid "Preview" +msgstr "预览" + +#: lib/php/monica/form.inc.php:501 lib/php/monica/form.inc.php:507 +#: lib/php/monica/form.inc.php:692 lib/php/monica/form.inc.php:698 +msgid "Confirm and submit" +msgstr "确认发送" + +#: lib/php/monica/form.inc.php:708 lib/php/monica/form.inc.php:1692 +#: lib/php/monica/form.inc.php:1778 lib/php/monica/list.inc.php:1809 +msgid "Delete" +msgstr "删除" + +#: lib/php/monica/form.inc.php:709 lib/php/monica/form.inc.php:6437 +#: lib/php/monica/form.inc.php:6488 +msgid "Cancel" +msgstr "取消" + +#: lib/php/monica/form.inc.php:1042 lib/php/monica/form.inc.php:3499 +msgid "Set the picture" +msgstr "设置图片" + +#: lib/php/monica/form.inc.php:1043 lib/php/monica/form.inc.php:3031 +#: lib/php/monica/form.inc.php:3500 +msgid "Delete this picture" +msgstr "删掉图片" + +#: lib/php/monica/form.inc.php:1048 lib/php/monica/form.inc.php:1178 +#: lib/php/monica/form.inc.php:3037 lib/php/monica/form.inc.php:3104 +#: lib/php/monica/form.inc.php:3505 lib/php/monica/form.inc.php:3677 +#: lib/php/monica/form.inc.php:6181 lib/php/monica/list.inc.php:814 +msgid "Picture preview" +msgstr "图片预览" + +#: lib/php/monica/form.inc.php:1059 lib/php/monica/form.inc.php:1109 +#: lib/php/monica/form.inc.php:1185 +#, c-format +msgid "Picture #%d:" +msgstr "图片 %d :" + +#: lib/php/monica/form.inc.php:1080 lib/php/monica/form.inc.php:1131 +#: lib/php/monica/form.inc.php:1166 lib/php/monica/form.inc.php:1199 +msgid "Caption:" +msgstr "标题:" + +#: lib/php/monica/form.inc.php:1092 lib/php/monica/form.inc.php:3064 +#: lib/php/monica/form.inc.php:3566 lib/php/monica/form.inc.php:6201 +msgid "Original picture preview" +msgstr "原图片预览" + +#: lib/php/monica/form.inc.php:1093 lib/php/monica/form.inc.php:3065 +#: lib/php/monica/form.inc.php:3567 lib/php/monica/form.inc.php:6215 +msgid "New picture preview" +msgstr "新图片预览" + +#: lib/php/monica/form.inc.php:1113 lib/php/monica/form.inc.php:1276 +#: lib/php/monica/form.inc.php:1363 lib/php/monica/form.inc.php:1451 +#: lib/php/monica/form.inc.php:1560 lib/php/monica/form.inc.php:1650 +#: lib/php/monica/form.inc.php:1727 lib/php/monica/form.inc.php:1825 +#: lib/php/monica/form.inc.php:1916 lib/php/monica/form.inc.php:1977 +#: lib/php/monica/form.inc.php:2053 lib/php/monica/form.inc.php:2159 +#: lib/php/monica/form.inc.php:2391 lib/php/monica/form.inc.php:2592 +#: lib/php/monica/form.inc.php:2689 lib/php/monica/form.inc.php:2800 +#: lib/php/monica/form.inc.php:2897 lib/php/monica/form.inc.php:2980 +#: lib/php/monica/form.inc.php:3069 lib/php/monica/form.inc.php:3200 +#: lib/php/monica/form.inc.php:3571 lib/php/monica/form.inc.php:3627 +#: lib/php/monica/form.inc.php:3640 lib/php/monica/form.inc.php:3747 +#: lib/php/monica/form.inc.php:4423 lib/php/monica/form.inc.php:4548 +#: lib/php/monica/form.inc.php:4747 lib/php/monica/form.inc.php:4884 +#: lib/php/monica/form.inc.php:5018 lib/php/monica/form.inc.php:6194 +#: lib/php/monica/form.inc.php:6261 +msgid "Original:" +msgstr "原:" + +#: lib/php/monica/form.inc.php:1141 lib/php/monica/form.inc.php:1281 +#: lib/php/monica/form.inc.php:1369 lib/php/monica/form.inc.php:1456 +#: lib/php/monica/form.inc.php:1575 lib/php/monica/form.inc.php:1655 +#: lib/php/monica/form.inc.php:1732 lib/php/monica/form.inc.php:1832 +#: lib/php/monica/form.inc.php:1921 lib/php/monica/form.inc.php:1982 +#: lib/php/monica/form.inc.php:2065 lib/php/monica/form.inc.php:2173 +#: lib/php/monica/form.inc.php:2422 lib/php/monica/form.inc.php:2597 +#: lib/php/monica/form.inc.php:2694 lib/php/monica/form.inc.php:2805 +#: lib/php/monica/form.inc.php:2902 lib/php/monica/form.inc.php:2985 +#: lib/php/monica/form.inc.php:3080 lib/php/monica/form.inc.php:3205 +#: lib/php/monica/form.inc.php:3584 lib/php/monica/form.inc.php:3632 +#: lib/php/monica/form.inc.php:3649 lib/php/monica/form.inc.php:3752 +#: lib/php/monica/form.inc.php:4442 lib/php/monica/form.inc.php:4554 +#: lib/php/monica/form.inc.php:4760 lib/php/monica/form.inc.php:4897 +#: lib/php/monica/form.inc.php:5031 lib/php/monica/form.inc.php:6206 +#: lib/php/monica/form.inc.php:6266 lib/php/monica/form.inc.php:6296 +msgid "New:" +msgstr "新:" + +#: lib/php/monica/form.inc.php:1269 lib/php/monica/form.inc.php:1444 +#: lib/php/monica/form.inc.php:1543 lib/php/monica/form.inc.php:2358 +#: lib/php/monica/form.inc.php:2585 lib/php/monica/form.inc.php:2793 +#: lib/php/monica/form.inc.php:2890 lib/php/monica/form.inc.php:2973 +#: lib/php/monica/form.inc.php:3620 +msgid "Source:" +msgstr "原文:" + +#: lib/php/monica/form.inc.php:1289 lib/php/monica/form.inc.php:1464 +#: lib/php/monica/form.inc.php:1583 lib/php/monica/form.inc.php:2605 +#: lib/php/monica/form.inc.php:2813 lib/php/monica/form.inc.php:2910 +#: lib/php/monica/form.inc.php:2993 +#, c-format +msgid "Please set it from %s." +msgstr "请由%s设置。" + +#: lib/php/monica/form.inc.php:1501 +msgid "Hide" +msgstr "隐藏" + +#: lib/php/monica/form.inc.php:1502 +msgid "Show" +msgstr "秀出" + +#: lib/php/monica/form.inc.php:1691 lib/php/monica/form.inc.php:1777 +#: lib/php/monica/form.inc.php:1887 +msgid "Choose" +msgstr "挑选" + +#: lib/php/monica/form.inc.php:2237 +msgid "Delete this file" +msgstr "删掉文件" + +#: lib/php/monica/form.inc.php:2267 lib/php/monica/form.inc.php:2368 +#: lib/php/monica/form.inc.php:2400 lib/php/monica/form.inc.php:2445 +#: lib/php/monica/form.inc.php:2506 +msgid "File name:" +msgstr "文件名:" + +#: lib/php/monica/form.inc.php:2274 lib/php/monica/form.inc.php:2375 +#: lib/php/monica/form.inc.php:2407 lib/php/monica/form.inc.php:2452 +#: lib/php/monica/form.inc.php:2513 +msgid "MIME file type:" +msgstr "MIME 文件格式:" + +#: lib/php/monica/form.inc.php:2279 lib/php/monica/form.inc.php:2380 +#: lib/php/monica/form.inc.php:2412 lib/php/monica/form.inc.php:2457 +#: lib/php/monica/form.inc.php:2518 +msgid "File size:" +msgstr "文件大小:" + +#: lib/php/monica/form.inc.php:2430 +#, c-format +msgid "Please upload it from %s." +msgstr "请由%s上传。" + +#: lib/php/monica/form.inc.php:3128 +msgid "Address:" +msgstr "地址:" + +#: lib/php/monica/form.inc.php:3129 +msgid "Fill in your address here." +msgstr "请填上地址。" + +#: lib/php/monica/form.inc.php:3135 +msgid "Attachment:" +msgstr "附件:" + +#: lib/php/monica/form.inc.php:3139 +msgid "Attachment description:" +msgstr "附件说明:" + +#: lib/php/monica/form.inc.php:3158 lib/php/monica/form.inc.php:3171 +msgid "Content:" +msgstr "内文:" + +#: lib/php/monica/form.inc.php:3165 +msgid "City:" +msgstr "城市:" + +#: lib/php/monica/form.inc.php:3187 lib/php/monica/form.inc.php:3199 +#: lib/php/monica/form.inc.php:3217 lib/php/monica/form.inc.php:3241 +msgid "Country:" +msgstr "国家:" + +#: lib/php/monica/form.inc.php:3229 +msgid "Created:" +msgstr "建档日期:" + +#: lib/php/monica/form.inc.php:3235 +msgid "Created by:" +msgstr "建档者:" + +#: lib/php/monica/form.inc.php:3247 +msgid "Date:" +msgstr "日期:" + +#: lib/php/monica/form.inc.php:3253 lib/php/monica/form.inc.php:4292 +#: lib/php/monica/form.inc.php:4295 lib/php/monica/list.inc.php:310 +msgid "Disabled?" +msgstr "停用?" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 lib/php/monica/list.inc.php:2020 +msgid "Disabled" +msgstr "停用" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 +msgid "Enabled" +msgstr "未停用" + +#: lib/php/monica/form.inc.php:3254 +msgid "Disable it." +msgstr "停掉。" + +#: lib/php/monica/form.inc.php:3260 lib/php/monica/form.inc.php:4675 +msgid "Description:" +msgstr "说明:" + +#: lib/php/monica/form.inc.php:3267 +msgid "E-mail:" +msgstr "E-mail:" + +#: lib/php/monica/form.inc.php:3273 +msgid "Fax:" +msgstr "传真:" + +#: lib/php/monica/form.inc.php:3279 +msgid "Group:" +msgstr "群组:" + +#: lib/php/monica/form.inc.php:3285 lib/php/monica/form.inc.php:5559 +#: lib/php/monica/form.inc.php:5765 lib/php/monica/form.inc.php:5923 +#: lib/php/monica/form.inc.php:6016 +msgid "Hide?" +msgstr "隐藏?" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it" +msgstr "隐藏起来" + +#: lib/php/monica/form.inc.php:3286 +msgid "Show it" +msgstr "秀出来" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it currently." +msgstr "暂勿秀出。" + +#: lib/php/monica/form.inc.php:3292 +msgid "Host:" +msgstr "主机:" + +#: lib/php/monica/form.inc.php:3298 lib/php/monica/list.inc.php:314 +msgid "HTML?" +msgstr "HTML ?" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2948 +#: lib/php/monica/list.inc.php:3062 +msgid "HTML" +msgstr "HTML" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2949 +#: lib/php/monica/list.inc.php:3063 +msgid "Plain text" +msgstr "纯文本" + +#: lib/php/monica/form.inc.php:3299 +msgid "The submitted content is HTML." +msgstr "以上内文为 HTML 格式。" + +#: lib/php/monica/form.inc.php:3305 lib/php/monica/form.inc.php:5553 +#: lib/php/monica/form.inc.php:6092 +msgid "ID.:" +msgstr "代号:" + +#: lib/php/monica/form.inc.php:3311 +msgid "Introduction:" +msgstr "简介:" + +#: lib/php/monica/form.inc.php:3312 +msgid "Fill in the introduction here." +msgstr "请填上简介。" + +#: lib/php/monica/form.inc.php:3318 +msgid "IP:" +msgstr "IP :" + +#: lib/php/monica/form.inc.php:3324 +msgid "Keywords:" +msgstr "关键字:" + +#: lib/php/monica/form.inc.php:3330 +msgid "Language:" +msgstr "语言:" + +#: lib/php/monica/form.inc.php:3355 +msgid "Name:" +msgstr "名称:" + +#: lib/php/monica/form.inc.php:3365 lib/php/monica/form.inc.php:6010 +msgid "Order:" +msgstr "次序:" + +#: lib/php/monica/form.inc.php:3371 +msgid "Organization:" +msgstr "所属单位:" + +#: lib/php/monica/form.inc.php:3377 +msgid "Parent category:" +msgstr "大类:" + +#: lib/php/monica/form.inc.php:3378 +msgid "At the very top" +msgstr "最上层" + +#: lib/php/monica/form.inc.php:3391 lib/php/monica/form.inc.php:3428 +#: lib/php/monica/form.inc.php:3468 lib/php/monica/form.inc.php:4330 +#: lib/php/monica/form.inc.php:6380 +msgid "Password:" +msgstr "密码:" + +#: lib/php/monica/form.inc.php:3407 lib/php/monica/form.inc.php:3444 +msgid "Confirm password:" +msgstr "确认密码:" + +#: lib/php/monica/form.inc.php:3458 +msgid "(Leave them blank if you don't plan to change your password.)" +msgstr "(若你没有要更改密码,密码栏请留白。)" + +#: lib/php/monica/form.inc.php:3484 +msgid "Page path:" +msgstr "网页路径:" + +#: lib/php/monica/form.inc.php:3490 +msgid "PDF. file:" +msgstr "PDF. 档:" + +#: lib/php/monica/form.inc.php:3508 lib/php/monica/form.inc.php:3570 +#: lib/php/monica/form.inc.php:3680 lib/php/monica/form.inc.php:6169 +#: lib/php/monica/form.inc.php:6193 +msgid "Picture:" +msgstr "图片:" + +#: lib/php/monica/form.inc.php:3531 lib/php/monica/form.inc.php:3615 +#: lib/php/monica/form.inc.php:3619 lib/php/monica/form.inc.php:3693 +msgid "Pic. caption:" +msgstr "图片标题:" + +#: lib/php/monica/form.inc.php:3538 lib/php/monica/form.inc.php:3639 +#: lib/php/monica/form.inc.php:3699 +msgid "Pic. position:" +msgstr "图片位置:" + +#: lib/php/monica/form.inc.php:3718 lib/php/monica/form.inc.php:3746 +#: lib/php/monica/form.inc.php:3780 +msgid "Pinyin:" +msgstr "拼音:" + +#: lib/php/monica/form.inc.php:3722 lib/php/monica/form.inc.php:3756 +msgid "Please fill in the Chinese first." +msgstr "请先填上中文。" + +#: lib/php/monica/form.inc.php:3801 +msgid "Subcategory:" +msgid_plural "Subcategories:" +msgstr[0] "子类:" + +#: lib/php/monica/form.inc.php:3823 +msgid "Script:" +msgstr "程序:" + +#: lib/php/monica/form.inc.php:3829 +msgid "S/N:" +msgstr "编号:" + +#: lib/php/monica/form.inc.php:3835 +msgid "Street:" +msgstr "街号:" + +#: lib/php/monica/form.inc.php:3841 +msgid "Subject:" +msgstr "主题:" + +#: lib/php/monica/form.inc.php:3847 +msgid "Telephone:" +msgstr "电话:" + +#: lib/php/monica/form.inc.php:3853 +msgid "Tel. (cell.):" +msgstr "移动电话:" + +#: lib/php/monica/form.inc.php:3859 +msgid "Tel. (home):" +msgstr "电话(宅):" + +#: lib/php/monica/form.inc.php:3865 +msgid "Tel. (office):" +msgstr "电话(公):" + +#: lib/php/monica/form.inc.php:3871 +msgid "Title:" +msgstr "标题:" + +#: lib/php/monica/form.inc.php:3891 +msgid "Value:" +msgstr "值:" + +#: lib/php/monica/form.inc.php:3897 +msgid "Visits:" +msgstr "上站次数:" + +#: lib/php/monica/form.inc.php:3903 +msgid "Visited:" +msgstr "上站日期:" + +#: lib/php/monica/form.inc.php:3909 +msgid "Updated:" +msgstr "维护日期:" + +#: lib/php/monica/form.inc.php:3915 +msgid "Updated by:" +msgstr "维护者:" + +#: lib/php/monica/form.inc.php:3921 +msgid "URL.:" +msgstr "网址:" + +#: lib/php/monica/form.inc.php:3927 +msgid "Zip code:" +msgstr "邮递区号:" + +#: lib/php/monica/form.inc.php:4151 +msgid "Delete this user account" +msgstr "删掉帐号" + +#: lib/php/monica/form.inc.php:4157 +msgid "This table provides you a form to add a new user account." +msgstr "本表提供建新帐号的表单。" + +#: lib/php/monica/form.inc.php:4161 +msgid "This table provides you a form to update a current user account." +msgstr "本表提供设置帐号的表单。" + +#: lib/php/monica/form.inc.php:4165 +msgid "This table provides you a form to delete a user account." +msgstr "本表提供删除帐号的表单。" + +#: lib/php/monica/form.inc.php:4192 +msgid "Add a New User Account" +msgstr "建新帐号" + +#: lib/php/monica/form.inc.php:4196 +msgid "Update a Current User Account" +msgstr "设置帐号" + +#: lib/php/monica/form.inc.php:4200 +msgid "Delete a User Account" +msgstr "删除帐号" + +#: lib/php/monica/form.inc.php:4213 +msgid "This is a super-user. You can only change parts of her infomation." +msgstr "这个人是总管理员,你只能设置她部份的数据。" + +#: lib/php/monica/form.inc.php:4220 +msgid "" +"This user has a datum. It cannot be deleted. To delete the user, its datum " +"must first be deleted." +msgid_plural "" +"This user has data. It cannot be deleted. To delete the user, all of its " +"data must first be deleted." +msgstr[0] "本帐号下有数据,不可直接删除。要删除帐号,请先删除其下的数据。" + +#: lib/php/monica/form.inc.php:4282 +msgid "Administrator?" +msgstr "网站管理员?" + +#: lib/php/monica/form.inc.php:4283 +msgid "Administrator" +msgstr "网站管理员" + +#: lib/php/monica/form.inc.php:4283 +msgid "Non-administrator" +msgstr "普通用户" + +#: lib/php/monica/form.inc.php:4296 +msgid "Disable this user account." +msgstr "帐号停用。" + +#: lib/php/monica/form.inc.php:4305 lib/php/monica/form.inc.php:4307 +#: lib/php/monica/form.inc.php:6372 +msgid "User ID.:" +msgstr "用户代号:" + +#: lib/php/monica/form.inc.php:4314 +msgid "Pref. language:" +msgstr "语言偏好:" + +#: lib/php/monica/form.inc.php:4320 +msgid "Full name:" +msgstr "姓名:" + +#: lib/php/monica/form.inc.php:4348 lib/php/monica/form.inc.php:4400 +#: lib/php/monica/form.inc.php:4422 lib/php/monica/form.inc.php:4496 +#: lib/php/monica/form.inc.php:4962 lib/php/monica/form.inc.php:5001 +#: lib/php/monica/form.inc.php:5017 lib/php/monica/form.inc.php:5069 +msgid "Belonging to:" +msgstr "隶属群组:" + +#: lib/php/monica/form.inc.php:4539 lib/php/monica/form.inc.php:4547 +#: lib/php/monica/form.inc.php:4574 +msgid "Fail logins:" +msgstr "登录失败:" + +#: lib/php/monica/form.inc.php:4551 lib/php/monica/form.inc.php:4578 +msgid "(Locked)" +msgstr "(锁住)" + +#: lib/php/monica/form.inc.php:4557 +msgid "Reset the counter and activate the account" +msgstr "归零并重启帐号。" + +#: lib/php/monica/form.inc.php:4603 +msgid "Delete this group" +msgstr "删掉群组" + +#: lib/php/monica/form.inc.php:4609 +msgid "This table provides you a form to add a new group." +msgstr "本表提供建新群组的表单。" + +#: lib/php/monica/form.inc.php:4613 +msgid "This table provides you a form to update a current group." +msgstr "本表提供设置群组的表单。" + +#: lib/php/monica/form.inc.php:4617 +msgid "This table provides you a form to delete a group." +msgstr "本表提供删除群组的表单。" + +#: lib/php/monica/form.inc.php:4642 +msgid "Add a New Group" +msgstr "建新群组" + +#: lib/php/monica/form.inc.php:4646 +msgid "Update a Current Group" +msgstr "设置群组" + +#: lib/php/monica/form.inc.php:4650 +msgid "Delete a Group" +msgstr "删除群组" + +#: lib/php/monica/form.inc.php:4657 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "这是最高管理员的群组,你只能设置它部份的数据。" + +#: lib/php/monica/form.inc.php:4666 lib/php/monica/form.inc.php:4668 +msgid "Group ID.:" +msgstr "群组代号:" + +#: lib/php/monica/form.inc.php:4681 +msgid "Add a user" +msgstr "增加成员" + +#: lib/php/monica/form.inc.php:4688 lib/php/monica/form.inc.php:4728 +#: lib/php/monica/form.inc.php:4746 lib/php/monica/form.inc.php:4799 +msgid "User member:" +msgid_plural "User members:" +msgstr[0] "用户成员:" + +#: lib/php/monica/form.inc.php:4819 lib/php/monica/form.inc.php:4956 +msgid "Add a group" +msgstr "增加群组" + +#: lib/php/monica/form.inc.php:4826 lib/php/monica/form.inc.php:4866 +#: lib/php/monica/form.inc.php:4883 lib/php/monica/form.inc.php:4936 +msgid "Group member:" +msgid_plural "Group members:" +msgstr[0] "群组成员:" + +#: lib/php/monica/form.inc.php:5103 lib/php/monica/form.inc.php:5178 +msgid "Delete this membership record" +msgstr "删掉这笔成员关系" + +#: lib/php/monica/form.inc.php:5109 lib/php/monica/form.inc.php:5184 +msgid "This table provides you a form to add a new membership record." +msgstr "本表提供建新成员关系的表单。" + +#: lib/php/monica/form.inc.php:5113 lib/php/monica/form.inc.php:5188 +msgid "This table provides you a form to change a current membership record." +msgstr "本表提供变更成员关系的表单。" + +#: lib/php/monica/form.inc.php:5117 lib/php/monica/form.inc.php:5192 +msgid "This table provides you a form to delete a membership record." +msgstr "本表提供删除成员关系的表单。" + +#: lib/php/monica/form.inc.php:5140 +msgid "Add a New User Membership Record" +msgstr "建新用户成员关系" + +#: lib/php/monica/form.inc.php:5144 +msgid "Change a Current User Membership Record" +msgstr "变更用户成员关系" + +#: lib/php/monica/form.inc.php:5148 +msgid "Delete a User Membership Record" +msgstr "删除用户成员关系" + +#: lib/php/monica/form.inc.php:5158 lib/php/monica/form.inc.php:5233 +msgid "Member:" +msgstr "成员:" + +#: lib/php/monica/form.inc.php:5215 +msgid "Add a New Group Membership Record" +msgstr "建新群组成员关系" + +#: lib/php/monica/form.inc.php:5219 +msgid "Change a Current Group Membership Record" +msgstr "变更群组成员关系" + +#: lib/php/monica/form.inc.php:5223 +msgid "Delete a Group Membership Record" +msgstr "删除群组成员关系" + +#: lib/php/monica/form.inc.php:5253 +msgid "Delete this user preference" +msgstr "删掉这笔用户偏好" + +#: lib/php/monica/form.inc.php:5259 +msgid "This table provides you a form to add a new user preference." +msgstr "本表提供建新用户偏好的表单。" + +#: lib/php/monica/form.inc.php:5263 +msgid "This table provides you a form to modify a current user preference." +msgstr "本表提供修改用户偏好的表单。" + +#: lib/php/monica/form.inc.php:5267 +msgid "This table provides you a form to delete a user preference." +msgstr "本表提供删除用户偏好的表单。" + +#: lib/php/monica/form.inc.php:5290 +msgid "Add a New User Preference" +msgstr "建新用户偏好" + +#: lib/php/monica/form.inc.php:5294 +msgid "Modify a Current User Preference" +msgstr "修改用户偏好" + +#: lib/php/monica/form.inc.php:5298 +msgid "Delete a User Preference" +msgstr "删除用户偏好" + +#: lib/php/monica/form.inc.php:5308 lib/php/monica/form.inc.php:5494 +msgid "User:" +msgstr "用户:" + +#: lib/php/monica/form.inc.php:5309 lib/php/monica/list.inc.php:2588 +msgid "Everyone" +msgstr "所有人" + +#: lib/php/monica/form.inc.php:5315 +msgid "Domain:" +msgstr "适用范围:" + +#: lib/php/monica/form.inc.php:5316 lib/php/monica/list.inc.php:2592 +msgid "Everywhere" +msgstr "所有地方" + +#: lib/php/monica/form.inc.php:5336 +msgid "Delete this script privilege record" +msgstr "删掉这笔程序权限数据" + +#: lib/php/monica/form.inc.php:5342 +msgid "This table provides you a form to add a new script privilege record." +msgstr "本表提供建新程序权限数据的表单。" + +#: lib/php/monica/form.inc.php:5346 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "本表提供变更程序权限数据的表单。" + +#: lib/php/monica/form.inc.php:5350 +msgid "This table provides you a form to delete a script privilege record." +msgstr "本表提供删除程序权限数据的表单。" + +#: lib/php/monica/form.inc.php:5373 +msgid "Add a New Script Privilege Record" +msgstr "建新程序权限数据" + +#: lib/php/monica/form.inc.php:5377 +msgid "Change a Current Script Privilege Record" +msgstr "变更程序权限数据" + +#: lib/php/monica/form.inc.php:5381 +msgid "Delete a Script Privilege Record" +msgstr "删除程序权限数据" + +#: lib/php/monica/form.inc.php:5391 +msgid "Privilege:" +msgstr "权限:" + +#: lib/php/monica/form.inc.php:5413 +msgid "Delete this user request" +msgstr "删掉这笔用户申请" + +#: lib/php/monica/form.inc.php:5419 +msgid "This table provides you a form to add a new user request." +msgstr "本表提供建新用户申请的表单。" + +#: lib/php/monica/form.inc.php:5423 +msgid "This table provides you a form to update a current user request." +msgstr "本表提供更新用户申请的表单。" + +#: lib/php/monica/form.inc.php:5427 +msgid "This table provides you a form to delete a user request." +msgstr "本表提供删除用户申请的表单。" + +#: lib/php/monica/form.inc.php:5450 +msgid "Add a New User Request" +msgstr "建新用户申请" + +#: lib/php/monica/form.inc.php:5454 +msgid "Update a Current User Request" +msgstr "更新用户申请" + +#: lib/php/monica/form.inc.php:5458 +msgid "Delete a User Request" +msgstr "删除用户申请" + +#: lib/php/monica/form.inc.php:5466 +msgid "Join" +msgstr "加入" + +#: lib/php/monica/form.inc.php:5470 +msgid "Change e-mail" +msgstr "变更 E-mail" + +#: lib/php/monica/form.inc.php:5474 +msgid "Reset password" +msgstr "重设密码" + +#: lib/php/monica/form.inc.php:5482 +msgid "Expiration:" +msgstr "到期日:" + +#: lib/php/monica/form.inc.php:5488 lib/php/monica/form.inc.php:6450 +msgid "Type:" +msgstr "类型:" + +#: lib/php/monica/form.inc.php:5495 +msgid "Anonymous" +msgstr "未具名" + +#: lib/php/monica/form.inc.php:5501 +msgid "Arguments:" +msgstr "备注数据:" + +#: lib/php/monica/form.inc.php:5519 +msgid "Delete this category" +msgstr "删掉这个分类" + +#: lib/php/monica/form.inc.php:5525 +msgid "This table provides you a form to add a new category." +msgstr "本表提供建新分类的表单。" + +#: lib/php/monica/form.inc.php:5529 +msgid "This table provides you a form to edit a current category." +msgstr "本表提供编辑分类的表单。" + +#: lib/php/monica/form.inc.php:5533 +msgid "This table provides you a form to delete a category." +msgstr "本表提供删除分类的表单。" + +#: lib/php/monica/form.inc.php:5543 +msgid "" +"This category has a subcategory. It cannot be deleted. To delete the " +"category, its subcategory must first be deleted." +msgid_plural "" +"This category has subcategories. It cannot be deleted. To delete the " +"category, all of its subcategories must first be deleted." +msgstr[0] "本分类下有子类,不可直接删除。要删除本分类,请先删除其下的子类。" + +#: lib/php/monica/form.inc.php:5560 +msgid "Hide this category" +msgstr "隐藏本类" + +#: lib/php/monica/form.inc.php:5560 +msgid "Show this category" +msgstr "秀出本类" + +#: lib/php/monica/form.inc.php:5560 +msgid "Hide this category currently." +msgstr "暂勿秀出本类。" + +#: lib/php/monica/form.inc.php:5577 +msgid "Delete this categorization record" +msgstr "删掉这笔分类数据" + +#: lib/php/monica/form.inc.php:5583 +msgid "This table provides you a form to add a new categorization record." +msgstr "本表提供建新分类数据的表单。" + +#: lib/php/monica/form.inc.php:5587 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "本表提供变更分类数据的表单。" + +#: lib/php/monica/form.inc.php:5591 +msgid "This table provides you a form to delete a categorization record." +msgstr "本表提供删除分类数据的表单。" + +#: lib/php/monica/form.inc.php:5636 +msgid "Add a New Link Category" +msgstr "建新链接分类" + +#: lib/php/monica/form.inc.php:5640 +msgid "Edit a Current Link Category" +msgstr "编辑链接分类" + +#: lib/php/monica/form.inc.php:5644 +msgid "Delete a Link Category" +msgstr "删除链接分类" + +#: lib/php/monica/form.inc.php:5654 +msgid "" +"This category has a link. It cannot be deleted. To delete the category, " +"its link must first be deleted." +msgid_plural "" +"This category has links. It cannot be deleted. To delete the category, all " +"of its links must first be deleted." +msgstr[0] "本分类下有链接,不可直接删除。要删除本分类,请先删除其下的链接。" + +#: lib/php/monica/form.inc.php:5673 lib/php/monica/form.inc.php:5837 +msgid "Link:" +msgid_plural "Links:" +msgstr[0] "链接:" + +#: lib/php/monica/form.inc.php:5710 +msgid "Delete this related link" +msgstr "删掉这笔相关链接" + +#: lib/php/monica/form.inc.php:5716 +msgid "This table provides you a form to add a new related link." +msgstr "本表提供建新相关链接的表单。" + +#: lib/php/monica/form.inc.php:5720 +msgid "This table provides you a form to edit a current related link." +msgstr "本表提供编辑相关链接的表单。" + +#: lib/php/monica/form.inc.php:5724 +msgid "This table provides you a form to delete a related link." +msgstr "本表提供删除相关链接的表单。" + +#: lib/php/monica/form.inc.php:5747 +msgid "Add a New Related Link" +msgstr "建新相关链接" + +#: lib/php/monica/form.inc.php:5751 +msgid "Edit a Current Related Link" +msgstr "编辑相关链接" + +#: lib/php/monica/form.inc.php:5755 +msgid "Delete a Related Link" +msgstr "删除相关链接" + +#: lib/php/monica/form.inc.php:5766 +msgid "Hide this link" +msgstr "隐藏本链接" + +#: lib/php/monica/form.inc.php:5766 lib/php/monica/form.inc.php:5924 +msgid "Show this page" +msgstr "秀出本页" + +#: lib/php/monica/form.inc.php:5766 +msgid "Hide this related link currently." +msgstr "暂勿秀出本相关链接。" + +#: lib/php/monica/form.inc.php:5773 lib/php/monica/form.inc.php:5830 +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "分类:" + +#: lib/php/monica/form.inc.php:5812 +msgid "Add a New Link Categorization Record" +msgstr "建新链接分类数据" + +#: lib/php/monica/form.inc.php:5816 +msgid "Change a Current Link Categorization Record" +msgstr "变更链接分类数据" + +#: lib/php/monica/form.inc.php:5820 +msgid "Delete a Link Categorization Record" +msgstr "删除链接分类数据" + +#: lib/php/monica/form.inc.php:5860 +msgid "Delete this page" +msgstr "删掉这一页" + +#: lib/php/monica/form.inc.php:5866 +msgid "This table provides you a form to write a new page." +msgstr "本表提供撰写网页的表单。" + +#: lib/php/monica/form.inc.php:5870 +msgid "This table provides you a form to edit a current page." +msgstr "本表提供编辑网页的表单。" + +#: lib/php/monica/form.inc.php:5874 +msgid "This table provides you a form to delete a page." +msgstr "本表提供删除网页的表单。" + +#: lib/php/monica/form.inc.php:5899 +msgid "Write a New Page" +msgstr "撰写网页" + +#: lib/php/monica/form.inc.php:5903 +msgid "Edit a Current Page" +msgstr "编辑网页" + +#: lib/php/monica/form.inc.php:5907 +msgid "Delete a Page" +msgstr "删除网页" + +#: lib/php/monica/form.inc.php:5915 +msgid "Preview this page." +msgstr "预览本页。" + +#: lib/php/monica/form.inc.php:5924 +msgid "Hide this page" +msgstr "隐藏本页" + +#: lib/php/monica/form.inc.php:5924 +msgid "Hide this page currently." +msgstr "暂勿秀出本页。" + +#: lib/php/monica/form.inc.php:5947 +msgid "Delete this news article" +msgstr "删掉这则新闻" + +#: lib/php/monica/form.inc.php:5953 +msgid "This table provides you a form to write a new news article." +msgstr "本表提供撰写新闻的表单。" + +#: lib/php/monica/form.inc.php:5957 +msgid "This table provides you a form to edit a current news article." +msgstr "本表提供编辑新闻的表单。" + +#: lib/php/monica/form.inc.php:5961 +msgid "This table provides you a form to delete a news article." +msgstr "本表提供删除新闻的表单。" + +#: lib/php/monica/form.inc.php:5986 +msgid "Write a New News Article" +msgstr "撰写新闻" + +#: lib/php/monica/form.inc.php:5990 +msgid "Edit a Current News Article" +msgstr "编辑新闻" + +#: lib/php/monica/form.inc.php:5994 +msgid "Delete a News Article" +msgstr "删除新闻" + +#: lib/php/monica/form.inc.php:6002 +msgid "Preview this news article." +msgstr "预览这则新闻。" + +#: lib/php/monica/form.inc.php:6017 +msgid "Hide this news article" +msgstr "隐藏这则新闻" + +#: lib/php/monica/form.inc.php:6017 +msgid "Show this news article" +msgstr "秀出这则新闻" + +#: lib/php/monica/form.inc.php:6017 +msgid "Hide this news article currently." +msgstr "暂勿秀出这则新闻。" + +#: lib/php/monica/form.inc.php:6037 +msgid "Delete this country record" +msgstr "删掉这笔国家数据" + +#: lib/php/monica/form.inc.php:6043 +msgid "This table provides you a form to add a new country record." +msgstr "本表提供建新国家数据的表单。" + +#: lib/php/monica/form.inc.php:6047 +msgid "This table provides you a form to edit a current country record." +msgstr "本表提供编辑国家数据的表单。" + +#: lib/php/monica/form.inc.php:6051 +msgid "This table provides you a form to delete a country record." +msgstr "本表提供删除国家数据的表单。" + +#: lib/php/monica/form.inc.php:6074 +msgid "Add a New Country Record" +msgstr "建新国家数据" + +#: lib/php/monica/form.inc.php:6078 +msgid "Edit a Current Country Record" +msgstr "编辑国家数据" + +#: lib/php/monica/form.inc.php:6082 +msgid "Delete a Country Record" +msgstr "删除国家数据" + +#: lib/php/monica/form.inc.php:6098 lib/php/monica/list.inc.php:3391 +msgid "Special?" +msgstr "特殊?" + +#: lib/php/monica/form.inc.php:6099 +msgid "A special record" +msgstr "特殊记录" + +#: lib/php/monica/form.inc.php:6099 +msgid "A normal country" +msgstr "一般国家" + +#: lib/php/monica/form.inc.php:6099 +msgid "This is a special record." +msgstr "这一笔是特殊记录。" + +#: lib/php/monica/form.inc.php:6128 +msgid "This table provides you a form to add a new picture." +msgstr "本表提供建新图片的表单。" + +#: lib/php/monica/form.inc.php:6132 +msgid "This table provides you a form to modify a current picture." +msgstr "本表提供修改图片的表单。" + +#: lib/php/monica/form.inc.php:6143 +msgid "Upload a New Picture" +msgstr "建新图片" + +#: lib/php/monica/form.inc.php:6147 +msgid "Modify a Current Picture" +msgstr "修改图片" + +#: lib/php/monica/form.inc.php:6248 lib/php/monica/form.inc.php:6260 +msgid "Ratio:" +msgstr "比例:" + +#: lib/php/monica/form.inc.php:6285 lib/php/monica/form.inc.php:6295 +msgid "Upload:" +msgstr "上传:" + +#: lib/php/monica/form.inc.php:6326 +msgid "This table provides you a form to log in." +msgstr "本表提供登录的表单。" + +#: lib/php/monica/form.inc.php:6332 +msgid "Identify Yourself" +msgstr "请出示身份" + +#: lib/php/monica/form.inc.php:6341 lib/php/monica/init.inc.php:505 +msgid "" +"Log-in is temporarily closed for maintainance now. Please come again " +"later. Sorry for the inconvienence." +msgstr "网站维护中,暂请勿入。造成任何不便,敬请见谅。" + +#: lib/php/monica/form.inc.php:6350 +msgid "Log in" +msgstr "登录" + +#: lib/php/monica/form.inc.php:6397 +msgid "Remember me." +msgstr "勿忘我。" + +#: lib/php/monica/form.inc.php:6424 +msgid "Rebuild the Pages" +msgstr "重制网页" + +#: lib/php/monica/form.inc.php:6433 +msgid "Confirm" +msgstr "确认" + +#: lib/php/monica/form.inc.php:6475 +msgid "Log Out" +msgstr "注销" + +#: lib/php/monica/form.inc.php:6484 +msgid "Log out" +msgstr "注销" + +#: lib/php/monica/form.inc.php:6498 +msgid "Are you sure you want to log out?" +msgstr "你确定要注销吗?" + +#: lib/php/monica/init.inc.php:114 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" +"抱歉,我们不欢迎加装 FunWebProduct 插件(如 Smiley Central 、 PopSwatter 、 " +"Spin4Dough 、 My Mail Signature 、 My Mail Stationery 、 My Mail Stamp 、 " +"Cursor Mania ……等等)的浏览器。 FunWebProduct 会重抓你看过的每一页网页,造" +"成网站负荷加倍,甚至当机。请先移除 FunWebProduct ,再上来浏览。" + +#: lib/php/monica/init.inc.php:503 lib/php/monica/init.inc.php:504 +msgid "Log-In Closed" +msgstr "暂请勿入" + +#: lib/php/monica/init.inc.php:524 lib/php/monica/init.inc.php:525 +msgid "Development Site Closed" +msgstr "研发网站已关闭" + +#: lib/php/monica/init.inc.php:526 +msgid "Development site is closed. Please work on the live site." +msgstr "研发网站已关闭,请勿在此登录。" + +#: lib/php/monica/links.inc.php:271 +msgid "Related Links" +msgstr "相关链接" + +#: lib/php/monica/list.inc.php:130 +msgid "Malformed" +msgstr "格式错乱" + +#: lib/php/monica/list.inc.php:155 +msgid "OK" +msgstr "好" + +#: lib/php/monica/list.inc.php:155 +msgid "Unreachable" +msgstr "连不上" + +#: lib/php/monica/list.inc.php:290 lib/php/monica/list.inc.php:1534 +#: lib/php/monica/list.inc.php:3642 +msgid "(query phrase)" +msgstr "(检索字词)" + +#: lib/php/monica/list.inc.php:300 +msgid "S/N" +msgstr "编号" + +#: lib/php/monica/list.inc.php:301 +msgid "Created" +msgstr "建档日期" + +#: lib/php/monica/list.inc.php:302 +msgid "Created by" +msgstr "建档者" + +#: lib/php/monica/list.inc.php:303 +msgid "Updated" +msgstr "维护日期" + +#: lib/php/monica/list.inc.php:304 +msgid "Updated by" +msgstr "维护者" + +#: lib/php/monica/list.inc.php:306 +msgid "Content" +msgstr "内文" + +#: lib/php/monica/list.inc.php:307 +msgid "Category" +msgstr "分类" + +#: lib/php/monica/list.inc.php:308 +msgid "Coverage" +msgstr "涵盖范围" + +#: lib/php/monica/list.inc.php:309 +msgid "Date" +msgstr "日期" + +#: lib/php/monica/list.inc.php:311 +msgid "Description" +msgstr "说明" + +#: lib/php/monica/list.inc.php:312 +msgid "E-mail" +msgstr "E-mail" + +#: lib/php/monica/list.inc.php:313 +msgid "Hidden?" +msgstr "隐藏?" + +#: lib/php/monica/list.inc.php:315 +msgid "ID." +msgstr "代号" + +#: lib/php/monica/list.inc.php:316 +msgid "Keywords" +msgstr "关键字" + +#: lib/php/monica/list.inc.php:317 +msgid "Name" +msgstr "名称" + +#: lib/php/monica/list.inc.php:318 +msgid "Order" +msgstr "次序" + +#: lib/php/monica/list.inc.php:319 +msgid "Page path" +msgstr "网页路径" + +#: lib/php/monica/list.inc.php:320 +msgid "Picture" +msgstr "图片" + +#: lib/php/monica/list.inc.php:321 +msgid "Pic. ratio" +msgstr "图片比例" + +#: lib/php/monica/list.inc.php:322 +msgid "Pic. caption" +msgstr "图片标题" + +#: lib/php/monica/list.inc.php:323 +msgid "Pic. position" +msgstr "图片位置" + +#: lib/php/monica/list.inc.php:324 +msgid "Subject" +msgstr "主题" + +#: lib/php/monica/list.inc.php:325 +msgid "Title" +msgstr "标题" + +#: lib/php/monica/list.inc.php:326 +msgid "URL." +msgstr "网址" + +#: lib/php/monica/list.inc.php:327 +msgid "Status (slow)" +msgstr "状态(慢)" + +#: lib/php/monica/list.inc.php:336 +msgid "Select" +msgstr "选择" + +#: lib/php/monica/list.inc.php:339 +msgid "Select a Data Record" +msgstr "选择数据" + +#: lib/php/monica/list.inc.php:343 +msgid "Edit" +msgstr "设置" + +#: lib/php/monica/list.inc.php:345 +msgid "Manage Data" +msgstr "管理数据" + +#: lib/php/monica/list.inc.php:749 +msgid "Nothing found. Please try another query." +msgstr "查无相符的数据,请重新搜索。" + +#: lib/php/monica/list.inc.php:752 +msgid "The database is empty." +msgstr "现无任何数据。" + +#: lib/php/monica/list.inc.php:759 +#, c-format +msgid "Your query found %s record." +msgid_plural "Your query found %s records." +msgstr[0] "共 %s 笔相符的数据。" + +#: lib/php/monica/list.inc.php:766 +#, c-format +msgid "%s record." +msgid_plural "%s records." +msgstr[0] "共 %s 笔数据。" + +#: lib/php/monica/list.inc.php:775 +#, c-format +msgid "Your query found %s record, listing %s to %s." +msgid_plural "Your query found %s records, listing %s to %s." +msgstr[0] "共 %s 笔相符的数据,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:784 +#, c-format +msgid "%s record, listing %s to %s." +msgid_plural "%s records, listing %s to %s." +msgstr[0] "共 %s 笔数据,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:855 lib/php/monica/list.inc.php:860 +#: lib/php/monica/list.inc.php:869 +#, c-format +msgid "Page number (%s) invalid. Please specify a valid page number." +msgstr "页数( %s )无效,请设成有效的数字。" + +#: lib/php/monica/list.inc.php:874 +#, c-format +msgid "" +"Page number (%d) out of range. Please specify a number between 1 and %d." +msgstr "页数( %d )超出范围,请设在 1 到 %d 之间。" + +#: lib/php/monica/list.inc.php:1138 lib/php/monica/list.inc.php:1151 +#, c-format +msgid "You cannot sort by \"%s\"." +msgstr "无法以 %s 排序。" + +#: lib/php/monica/list.inc.php:1512 +msgid "Search" +msgstr "搜索" + +#: lib/php/monica/list.inc.php:1610 +msgid "Index" +msgstr "目录" + +#: lib/php/monica/list.inc.php:1634 +msgid "First" +msgstr "第一页" + +#: lib/php/monica/list.inc.php:1647 +msgid "Previous" +msgstr "前一页" + +#: lib/php/monica/list.inc.php:1696 +msgid "Next" +msgstr "下一页" + +#: lib/php/monica/list.inc.php:1714 +msgid "Last" +msgstr "最末页" + +#: lib/php/monica/list.inc.php:1736 +msgid "Page:" +msgstr "页:" + +#: lib/php/monica/list.inc.php:1776 lib/php/monica/list.inc.php:1900 +msgid "Delete the selected items." +msgstr "删除勾选的项目。" + +#: lib/php/monica/list.inc.php:1805 +msgid "No." +msgstr "编号" + +#: lib/php/monica/list.inc.php:1813 lib/php/monica/list.inc.php:1873 +msgid "View" +msgstr "浏览" + +#: lib/php/monica/list.inc.php:1925 +msgid "Set" +msgstr "设置" + +#: lib/php/monica/list.inc.php:1941 +msgid "Rows per page:" +msgstr "每页显示笔数:" + +#: lib/php/monica/list.inc.php:1946 +msgid "Display columns:" +msgstr "显示字段:" + +#: lib/php/monica/list.inc.php:1976 +msgid "Select a User" +msgstr "选择帐号" + +#: lib/php/monica/list.inc.php:1977 +msgid "Manage Users" +msgstr "管理帐号" + +#: lib/php/monica/list.inc.php:1982 +msgid "User ID." +msgstr "用户代号" + +#: lib/php/monica/list.inc.php:1983 +msgid "Full name" +msgstr "姓名" + +#: lib/php/monica/list.inc.php:1984 +msgid "Deleted?" +msgstr "已删?" + +#: lib/php/monica/list.inc.php:1985 +msgid "Pref. language" +msgstr "语言偏好" + +#: lib/php/monica/list.inc.php:1986 +msgid "Visits" +msgstr "上站次数" + +#: lib/php/monica/list.inc.php:1987 +msgid "Visited" +msgstr "上站日期" + +#: lib/php/monica/list.inc.php:1988 +msgid "IP" +msgstr "IP" + +#: lib/php/monica/list.inc.php:1989 +msgid "Host" +msgstr "主机" + +#: lib/php/monica/list.inc.php:1990 +msgid "From country" +msgstr "上站国家" + +#: lib/php/monica/list.inc.php:1991 +msgid "Fail logins" +msgstr "登录失败" + +#: lib/php/monica/list.inc.php:2024 +msgid "Deleted" +msgstr "已删" + +#: lib/php/monica/list.inc.php:2035 +msgid "Add a new user account." +msgstr "建新帐号。" + +#: lib/php/monica/list.inc.php:2045 +msgid "Search for a user:" +msgstr "搜索用户:" + +#: lib/php/monica/list.inc.php:2063 +#, c-format +msgid "Your query found %s user." +msgid_plural "Your query found %s users." +msgstr[0] "共 %s 个相符的用户。" + +#: lib/php/monica/list.inc.php:2070 +#, c-format +msgid "%s user." +msgid_plural "%s users." +msgstr[0] "共 %s 个用户。" + +#: lib/php/monica/list.inc.php:2079 +#, c-format +msgid "Your query found %s user, listing %s to %s." +msgid_plural "Your query found %s users, listing %s to %s." +msgstr[0] "共 %s 个相符的用户,列出第 %s 个到第 %s 个。" + +#: lib/php/monica/list.inc.php:2088 +#, c-format +msgid "%s user, listing %s to %s." +msgid_plural "%s users, listing %s to %s." +msgstr[0] "共 %s 个用户,列出第 %s 个到第 %s 个。" + +#: lib/php/monica/list.inc.php:2107 +msgid "Select a Group" +msgstr "选择群组" + +#: lib/php/monica/list.inc.php:2108 +msgid "Manage Groups" +msgstr "管理群组" + +#: lib/php/monica/list.inc.php:2113 +msgid "Group ID." +msgstr "群组代号" + +#: lib/php/monica/list.inc.php:2121 +msgid "Add a new group." +msgstr "建新群组。" + +#: lib/php/monica/list.inc.php:2131 +msgid "Search for a group:" +msgstr "搜索群组:" + +#: lib/php/monica/list.inc.php:2149 +#, c-format +msgid "Your query found %s group." +msgid_plural "Your query found %s groups." +msgstr[0] "共 %s 个相符的群组。" + +#: lib/php/monica/list.inc.php:2156 +#, c-format +msgid "%s group." +msgid_plural "%s groups." +msgstr[0] "共 %s 个群组。" + +#: lib/php/monica/list.inc.php:2165 +#, c-format +msgid "Your query found %s group, listing %s to %s." +msgid_plural "Your query found %s groups, listing %s to %s." +msgstr[0] "共 %s 个相符的群组,列出第 %s 个到第 %s 个。" + +#: lib/php/monica/list.inc.php:2174 +#, c-format +msgid "%s group, listing %s to %s." +msgid_plural "%s groups, listing %s to %s." +msgstr[0] "共 %s 个群组,列出第 %s 个到第 %s 个。" + +#: lib/php/monica/list.inc.php:2194 +msgid "Select a User Membership Record" +msgstr "选择用户成员关系" + +#: lib/php/monica/list.inc.php:2195 +msgid "Manage User Membership" +msgstr "管理用户成员关系" + +#: lib/php/monica/list.inc.php:2200 lib/php/monica/list.inc.php:2323 +msgid "Group" +msgstr "群组" + +#: lib/php/monica/list.inc.php:2201 lib/php/monica/list.inc.php:2324 +msgid "Member" +msgstr "成员" + +#: lib/php/monica/list.inc.php:2244 lib/php/monica/list.inc.php:2375 +msgid "Add a new membership record." +msgstr "建新成员关系。" + +#: lib/php/monica/list.inc.php:2254 lib/php/monica/list.inc.php:2385 +msgid "Search for a membership record:" +msgstr "搜索成员关系:" + +#: lib/php/monica/list.inc.php:2272 lib/php/monica/list.inc.php:2403 +#, c-format +msgid "Your query found %s membership record." +msgid_plural "Your query found %s membership records." +msgstr[0] "共 %s 笔相符的成员关系。" + +#: lib/php/monica/list.inc.php:2279 lib/php/monica/list.inc.php:2410 +#, c-format +msgid "%s membership record." +msgid_plural "%s membership records." +msgstr[0] "共 %s 笔成员关系。" + +#: lib/php/monica/list.inc.php:2288 lib/php/monica/list.inc.php:2419 +#, c-format +msgid "Your query found %s membership record, listing %s to %s." +msgid_plural "Your query found %s membership records, listing %s to %s." +msgstr[0] "共 %s 笔相符的成员关系,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2297 lib/php/monica/list.inc.php:2428 +#, c-format +msgid "%s membership record, listing %s to %s." +msgid_plural "%s membership records, listing %s to %s." +msgstr[0] "共 %s 笔成员关系,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2317 +msgid "Select a Group Membership Record" +msgstr "选择群组成员关系" + +#: lib/php/monica/list.inc.php:2318 +msgid "Manage Group Membership" +msgstr "管理群组成员关系" + +#: lib/php/monica/list.inc.php:2448 +msgid "Select a Script Privilege Record" +msgstr "选择程序权限" + +#: lib/php/monica/list.inc.php:2449 +msgid "Manage Script Privileges" +msgstr "管理程序权限" + +#: lib/php/monica/list.inc.php:2454 +msgid "Script" +msgstr "程序" + +#: lib/php/monica/list.inc.php:2455 +msgid "Privilege" +msgstr "权限" + +#: lib/php/monica/list.inc.php:2493 +msgid "Add a new script privilege record." +msgstr "建新程序权限数据。" + +#: lib/php/monica/list.inc.php:2503 +msgid "Search for a script privilege record:" +msgstr "搜索程序权限:" + +#: lib/php/monica/list.inc.php:2521 +#, c-format +msgid "Your query found %s script privilege record." +msgid_plural "Your query found %s script privilege records." +msgstr[0] "共 %s 笔相符的程序权限。" + +#: lib/php/monica/list.inc.php:2528 +#, c-format +msgid "%s script privilege record." +msgid_plural "%s script privilege records." +msgstr[0] "共 %s 笔程序权限。" + +#: lib/php/monica/list.inc.php:2537 +#, c-format +msgid "Your query found %s script privilege record, listing %s to %s." +msgid_plural "Your query found %s script privilege records, listing %s to %s." +msgstr[0] "共 %s 笔相符的程序权限,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2546 +#, c-format +msgid "%s script privilege record, listing %s to %s." +msgid_plural "%s script privilege records, listing %s to %s." +msgstr[0] "共 %s 笔程序权限,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2566 +msgid "Select a User Preference" +msgstr "选择用户偏好" + +#: lib/php/monica/list.inc.php:2567 +msgid "Manage User Preferences" +msgstr "管理用户偏好" + +#: lib/php/monica/list.inc.php:2574 lib/php/monica/list.inc.php:2689 +msgid "User" +msgstr "用户" + +#: lib/php/monica/list.inc.php:2575 +msgid "Domain" +msgstr "适用范围" + +#: lib/php/monica/list.inc.php:2576 +msgid "Value" +msgstr "值" + +#: lib/php/monica/list.inc.php:2610 +msgid "Add a new user preference." +msgstr "建新用户偏好。" + +#: lib/php/monica/list.inc.php:2620 +msgid "Search for a user preference:" +msgstr "搜索用户偏好:" + +#: lib/php/monica/list.inc.php:2638 +#, c-format +msgid "Your query found %s user preference." +msgid_plural "Your query found %s user preferences." +msgstr[0] "共 %s 笔相符的用户偏好。" + +#: lib/php/monica/list.inc.php:2645 +#, c-format +msgid "%s user preference." +msgid_plural "%s user preferences." +msgstr[0] "共 %s 笔用户偏好。" + +#: lib/php/monica/list.inc.php:2654 +#, c-format +msgid "Your query found %s user preference, listing %s to %s." +msgid_plural "Your query found %s user preferences, listing %s to %s." +msgstr[0] "共 %s 笔相符的用户偏好,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2663 +#, c-format +msgid "%s user preference, listing %s to %s." +msgid_plural "%s user preferences, listing %s to %s." +msgstr[0] "共 %s 笔用户偏好,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2682 +msgid "Select a User Request" +msgstr "选择用户申请" + +#: lib/php/monica/list.inc.php:2683 +msgid "Manage User Requests" +msgstr "管理用户申请" + +#: lib/php/monica/list.inc.php:2688 +msgid "Type" +msgstr "类别" + +#: lib/php/monica/list.inc.php:2690 +msgid "Arguments" +msgstr "备注数据" + +#: lib/php/monica/list.inc.php:2691 +msgid "Expiration" +msgstr "到期日" + +#: lib/php/monica/list.inc.php:2699 +msgid "Add a new user request." +msgstr "建新用户申请。" + +#: lib/php/monica/list.inc.php:2709 +msgid "Search for a user request:" +msgstr "搜索用户申请:" + +#: lib/php/monica/list.inc.php:2727 +#, c-format +msgid "Your query found %s user request." +msgid_plural "Your query found %s user requests." +msgstr[0] "共 %s 笔相符的用户申请。" + +#: lib/php/monica/list.inc.php:2734 +#, c-format +msgid "%s user request." +msgid_plural "%s user requests." +msgstr[0] "共 %s 笔用户申请。" + +#: lib/php/monica/list.inc.php:2743 +#, c-format +msgid "Your query found %s user request, listing %s to %s." +msgid_plural "Your query found %s user requests, listing %s to %s." +msgstr[0] "共 %s 笔相符的用户申请,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2752 +#, c-format +msgid "%s user request, listing %s to %s." +msgid_plural "%s user requests, listing %s to %s." +msgstr[0] "共 %s 笔用户申请,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2778 +msgid "Add a new category." +msgstr "建新分类。" + +#: lib/php/monica/list.inc.php:2788 +msgid "Search for a category:" +msgstr "搜索分类:" + +#: lib/php/monica/list.inc.php:2806 +#, c-format +msgid "Your query found %s category." +msgid_plural "Your query found %s categories." +msgstr[0] "共 %s 类相符的分类。" + +#: lib/php/monica/list.inc.php:2813 +#, c-format +msgid "%s category." +msgid_plural "%s categories." +msgstr[0] "共 %s 类分类。" + +#: lib/php/monica/list.inc.php:2822 +#, c-format +msgid "Your query found %s category, listing %s to %s." +msgid_plural "Your query found %s categories, listing %s to %s." +msgstr[0] "共 %s 类相符的分类,列出第 %s 类到第 %s 类。" + +#: lib/php/monica/list.inc.php:2831 +#, c-format +msgid "%s category, listing %s to %s." +msgid_plural "%s categories, listing %s to %s." +msgstr[0] "共 %s 类分类,列出第 %s 类到第 %s 类。" + +#: lib/php/monica/list.inc.php:2849 +msgid "Add a new categorization record." +msgstr "建新分类数据。" + +#: lib/php/monica/list.inc.php:2859 +msgid "Search for a categorization record:" +msgstr "搜索分类数据:" + +#: lib/php/monica/list.inc.php:2877 +#, c-format +msgid "Your query found %s categorization record." +msgid_plural "Your query found %s categorization records." +msgstr[0] "共 %s 笔相符的分类数据。" + +#: lib/php/monica/list.inc.php:2884 +#, c-format +msgid "%s categorization record." +msgid_plural "%s categorization records." +msgstr[0] "共 %s 笔分类数据。" + +#: lib/php/monica/list.inc.php:2893 +#, c-format +msgid "Your query found %s categorization record, listing %s to %s." +msgid_plural "Your query found %s categorization records, listing %s to %s." +msgstr[0] "共 %s 笔相符的分类数据,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2902 +#, c-format +msgid "%s categorization record, listing %s to %s." +msgid_plural "%s categorization records, listing %s to %s." +msgstr[0] "共 %s 笔分类数据,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2921 +msgid "Select a Page" +msgstr "选择网页" + +#: lib/php/monica/list.inc.php:2922 +msgid "Manage Pages" +msgstr "管理网页" + +#: lib/php/monica/list.inc.php:2952 lib/php/monica/list.inc.php:3066 +#: lib/php/monica/list.inc.php:3173 lib/php/monica/list.inc.php:3237 +#: lib/php/monica/list.inc.php:3358 +msgid "Hidden" +msgstr "隐藏" + +#: lib/php/monica/list.inc.php:2953 lib/php/monica/list.inc.php:3067 +#: lib/php/monica/list.inc.php:3174 lib/php/monica/list.inc.php:3238 +#: lib/php/monica/list.inc.php:3359 +msgid "Shown" +msgstr "秀出" + +#: lib/php/monica/list.inc.php:2963 +msgid "Write a new page." +msgstr "撰写网页。" + +#: lib/php/monica/list.inc.php:2973 +msgid "Search for a page:" +msgstr "搜索网页:" + +#: lib/php/monica/list.inc.php:2991 +#, c-format +msgid "Your query found %s page." +msgid_plural "Your query found %s pages." +msgstr[0] "共 %s 页相符的网页。" + +#: lib/php/monica/list.inc.php:2998 +#, c-format +msgid "%s page." +msgid_plural "%s pages." +msgstr[0] "共 %s 页网页。" + +#: lib/php/monica/list.inc.php:3007 +#, c-format +msgid "Your query found %s page, listing %s to %s." +msgid_plural "Your query found %s pages, listing %s to %s." +msgstr[0] "共 %s 页相符的网页,列出第 %s 页到第 %s 页。" + +#: lib/php/monica/list.inc.php:3016 +#, c-format +msgid "%s page, listing %s to %s." +msgid_plural "%s pages, listing %s to %s." +msgstr[0] "共 %s 页网页,列出第 %s 页到第 %s 页。" + +#: lib/php/monica/list.inc.php:3035 +msgid "Select a News Article" +msgstr "选择新闻" + +#: lib/php/monica/list.inc.php:3036 +msgid "Manage News" +msgstr "管理新闻" + +#: lib/php/monica/list.inc.php:3077 +msgid "Write a new news article." +msgstr "撰写新闻。" + +#: lib/php/monica/list.inc.php:3087 +msgid "Search for a news article:" +msgstr "搜索新闻:" + +#: lib/php/monica/list.inc.php:3105 +#, c-format +msgid "Your query found %s news article." +msgid_plural "Your query found %s news articles." +msgstr[0] "共 %s 则相符的新闻。" + +#: lib/php/monica/list.inc.php:3112 +#, c-format +msgid "%s news article." +msgid_plural "%s news articles." +msgstr[0] "共 %s 则新闻。" + +#: lib/php/monica/list.inc.php:3121 +#, c-format +msgid "Your query found %s news article, listing %s to %s." +msgid_plural "Your query found %s news articles, listing %s to %s." +msgstr[0] "共 %s 则相符的新闻,列出第 %s 则到第 %s 则。" + +#: lib/php/monica/list.inc.php:3130 +#, c-format +msgid "%s news article, listing %s to %s." +msgid_plural "%s news articles, listing %s to %s." +msgstr[0] "共 %s 则新闻,列出第 %s 则到第 %s 则。" + +#: lib/php/monica/list.inc.php:3149 +msgid "Select a Link Category" +msgstr "选择链接分类" + +#: lib/php/monica/list.inc.php:3150 +msgid "Manage Link Categories" +msgstr "管理链接分类" + +#: lib/php/monica/list.inc.php:3197 +msgid "Select a Link" +msgstr "选择链接" + +#: lib/php/monica/list.inc.php:3198 +msgid "Manage Links" +msgstr "管理链接" + +#: lib/php/monica/list.inc.php:3248 +msgid "Add a new related link." +msgstr "建新相关链接。" + +#: lib/php/monica/list.inc.php:3258 +msgid "Search for a related link:" +msgstr "搜索相关链接:" + +#: lib/php/monica/list.inc.php:3276 +#, c-format +msgid "Your query found %s related link." +msgid_plural "Your query found %s related links." +msgstr[0] "共 %s 笔相符的相关链接。" + +#: lib/php/monica/list.inc.php:3283 +#, c-format +msgid "%s related link." +msgid_plural "%s related links." +msgstr[0] "共 %s 笔相关链接" + +#: lib/php/monica/list.inc.php:3292 +#, c-format +msgid "Your query found %s related link, listing %s to %s." +msgid_plural "Your query found %s related links, listing %s to %s." +msgstr[0] "共 %s 笔相符的相关链接,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:3301 +#, c-format +msgid "%s related link, listing %s to %s." +msgid_plural "%s related links, listing %s to %s." +msgstr[0] "共 %s 笔相关链接,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:3321 +msgid "Select a Link Categorization Record" +msgstr "选择链接分类数据" + +#: lib/php/monica/list.inc.php:3322 +msgid "Manage Link Categorization" +msgstr "管理链接分类表" + +#: lib/php/monica/list.inc.php:3327 +msgid "Link" +msgstr "链接" + +#: lib/php/monica/list.inc.php:3383 +msgid "Select a Country" +msgstr "选择国家" + +#: lib/php/monica/list.inc.php:3384 +msgid "Manage Country Data" +msgstr "管理国家数据" + +#: lib/php/monica/list.inc.php:3389 +msgid "Code" +msgstr "代码" + +#: lib/php/monica/list.inc.php:3390 +msgid "Country name" +msgstr "国名" + +#: lib/php/monica/list.inc.php:3399 +msgid "Add a new country record." +msgstr "建新国家数据。" + +#: lib/php/monica/list.inc.php:3409 +msgid "Search for a country:" +msgstr "搜索国家:" + +#: lib/php/monica/list.inc.php:3427 +#, c-format +msgid "Your query found %s country." +msgid_plural "Your query found %s countries." +msgstr[0] "共 %s 个相符的国家。" + +#: lib/php/monica/list.inc.php:3434 +#, c-format +msgid "%s country." +msgid_plural "%s countries." +msgstr[0] "共 %s 个国家。" + +#: lib/php/monica/list.inc.php:3443 +#, c-format +msgid "Your query found %s country, listing %s to %s." +msgid_plural "Your query found %s countries, listing %s to %s." +msgstr[0] "共 %s 个相符的国家,列出第 %s 个到第 %s 个。" + +#: lib/php/monica/list.inc.php:3452 +#, c-format +msgid "%s country, listing %s to %s." +msgid_plural "%s countries, listing %s to %s." +msgstr[0] "共 %s 个国家,列出第 %s 个到第 %s 个。" + +#: lib/php/monica/list.inc.php:3474 +msgid "Browse the Activity Log" +msgstr "查阅网站活动日志" + +#: lib/php/monica/list.inc.php:3586 +msgid "Please fill in the number of rows to display." +msgstr "请填上显示笔数。" + +#: lib/php/monica/list.inc.php:3590 +#, c-format +msgid "This number of rows to display is too long. (Max. length %d)" +msgstr "显示笔数太长了。(最长 %d )" + +#: lib/php/monica/list.inc.php:3595 +msgid "Please fill in a positive integer number of rows to display." +msgstr "显示笔数请填正整数。" + +#: lib/php/monica/list.inc.php:3599 lib/php/monica/list.inc.php:3609 +#, c-format +msgid "" +"The number of rows to display is too small. Please fill in a larger number " +"of rows to display between %d and %d." +msgstr "显示笔数太小了,请设置在 %d 到 %d 之间。" + +#: lib/php/monica/list.inc.php:3613 +#, c-format +msgid "" +"The number of rows to display is too large. Please fill in a smaller number " +"of rows to display between %d and %d." +msgstr "显示笔数太大了,请设置在 %d 到 %d 之间。" + +#: lib/php/monica/list.inc.php:3638 +msgid "Search for log entries:" +msgstr "搜索记录:" + +#: lib/php/monica/list.inc.php:3641 +msgid "Display" +msgstr "显示" + +#: lib/php/monica/list.inc.php:3654 +msgid "Display rows:" +msgstr "显示笔数:" + +#: lib/php/monica/list.inc.php:3677 +#, c-format +msgid "Your query found %s log entry." +msgid_plural "Your query found %s log entries." +msgstr[0] "共 %s 笔相符的记录。" + +#: lib/php/monica/list.inc.php:3684 +#, c-format +msgid "%s log entry." +msgid_plural "%s log entries." +msgstr[0] "共 %s 笔记录。" + +#: lib/php/monica/list.inc.php:3693 +#, c-format +msgid "Your query found %s log entry, listing %s to %s." +msgid_plural "Your query found %s log entries, listing %s to %s." +msgstr[0] "共 %s 笔相符的记录,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:3702 +#, c-format +msgid "%s log entry, listing %s to %s." +msgid_plural "%s log entries, listing %s to %s." +msgstr[0] "共 %s 笔记录,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/lninfo.inc.php:28 +msgid "English" +msgstr "英文" + +#: lib/php/monica/lninfo.inc.php:39 +msgid "Traditional Chinese" +msgstr "繁体中文" + +#: lib/php/monica/lninfo.inc.php:50 +msgid "Simplified Chinese" +msgstr "简体中文" + +#: lib/php/monica/lninfo.inc.php:61 +msgid "Chinese" +msgstr "中文" + +#: lib/php/monica/lninfo.inc.php:72 +msgid "Japanese" +msgstr "日文" + +#: lib/php/monica/lninfo.inc.php:83 +msgid "Korean" +msgstr "韩文" + +#: lib/php/monica/lninfo.inc.php:94 +msgid "German" +msgstr "德文" + +#: lib/php/monica/lninfo.inc.php:105 +msgid "Spanish" +msgstr "西班牙文" + +#: lib/php/monica/lninfo.inc.php:366 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "切换到本页的%s版。" + +#: lib/php/monica/pagefunc.inc.php:738 +msgid "Web pages" +msgstr "网页" + +#: lib/php/monica/pagefunc.inc.php:739 +msgid "News" +msgstr "新闻" + +#: lib/php/monica/pagefunc.inc.php:740 +msgid "Related links" +msgstr "相关链接" + +#: lib/php/monica/pagefunc.inc.php:741 +msgid "Home page" +msgstr "首页" + +#: lib/php/monica/pagefunc.inc.php:742 +msgid "Whole web site" +msgstr "整个网站" + +#: lib/php/monica/pic.inc.php:39 +msgid "Left-aligned" +msgstr "靠左" + +#: lib/php/monica/pic.inc.php:40 +msgid "Right-aligned" +msgstr "靠右" + +#: lib/php/monica/pic.inc.php:74 lib/php/monica/pic.inc.php:77 +#, c-format +msgid "This picture file is too large (Max %s)." +msgstr "图档太大。(上限 %s )" + +#: lib/php/monica/pic.inc.php:92 +msgid "Please upload only PNG, JPEG or GIF files." +msgstr "限上传 PNG 、 JPEG 或 GIF 图档。" + +#: lib/php/monica/pic.inc.php:153 +#, c-format +msgid "Width: %d, height: %d, ratio: %0.2f" +msgstr "宽: %d ,高: %d ,比例: %0.2f" + +#: lib/php/monica/pic.inc.php:176 +msgid "Please specify a numeric ratio." +msgstr "比例请设置数字。" + +#: lib/php/monica/pic.inc.php:180 +msgid "Please specify a positive ratio." +msgstr "比例请设置正数。" + +#: lib/php/monica/pic.inc.php:183 +#, c-format +msgid "Please specify a ratio less than or equal to %0.2f." +msgstr "比例请勿大于 %0.2f 。" + +#: lib/php/monica/pic.inc.php:189 +msgid "This image is too large to display." +msgstr "图片太大,无法显示。" + +#: lib/php/monica/preview.inc.php:47 +#, c-format +msgid "Unknown preview source: \"%s\"." +msgstr "预览数据源不明:「 %s 」。" + +#: lib/php/monica/preview.inc.php:67 +#, c-format +msgid "Unknown preview form: %d." +msgstr "预览表格不明: %d 。" + +#: lib/php/monica/preview.inc.php:143 +msgid "Preview Mark Area" +msgstr "预览标志区" + +#: lib/php/monica/preview.inc.php:148 +msgid "Finish preview and return." +msgstr "结束预览回前页。" + +#: lib/php/monica/process.inc.php:237 +msgid "This record was not modified." +msgstr "数据未异动。" + +#: lib/php/monica/process.inc.php:243 +msgid "This record has been successfully added." +msgstr "数据建好了。" + +#: lib/php/monica/process.inc.php:247 +msgid "This record has been successfully updated." +msgstr "数据存好了。" + +#: lib/php/monica/process.inc.php:251 +msgid "This record has been successfully deleted." +msgstr "数据删掉了。" + +#: lib/php/monica/process.inc.php:406 +msgid "This category was not modified." +msgstr "分类未异动。" + +#: lib/php/monica/process.inc.php:412 +msgid "This category has been successfully added." +msgstr "分类建好了。" + +#: lib/php/monica/process.inc.php:416 +msgid "This category has been successfully updated." +msgstr "分类存好了。" + +#: lib/php/monica/process.inc.php:420 +msgid "This category has been successfully deleted." +msgstr "分类删掉了。" + +#: lib/php/monica/process.inc.php:433 +msgid "This categorization record was not modified." +msgstr "分类数据未异动。" + +#: lib/php/monica/process.inc.php:439 +msgid "This categorization record has been successfully added." +msgstr "分类数据建好了。" + +#: lib/php/monica/process.inc.php:443 +msgid "This categorization record has been successfully updated." +msgstr "分类数据存好了。" + +#: lib/php/monica/process.inc.php:447 +msgid "This categorization record has been successfully deleted." +msgstr "分类数据删掉了。" + +#: lib/php/monica/process.inc.php:782 +msgid "This user account was not modified." +msgstr "帐号未异动。" + +#: lib/php/monica/process.inc.php:788 +msgid "This user account has been successfully added." +msgstr "帐号建好了。" + +#: lib/php/monica/process.inc.php:792 +msgid "This user account has been successfully updated." +msgstr "帐号存好了。" + +#: lib/php/monica/process.inc.php:796 +msgid "This user account has been successfully deleted." +msgstr "帐号删掉了。" + +#: lib/php/monica/process.inc.php:1074 +msgid "This group was not modified." +msgstr "群组未异动。" + +#: lib/php/monica/process.inc.php:1080 +msgid "This group has been successfully added." +msgstr "群组建好了。" + +#: lib/php/monica/process.inc.php:1084 +msgid "This group has been successfully updated." +msgstr "群组存好了。" + +#: lib/php/monica/process.inc.php:1088 +msgid "This group has been successfully deleted." +msgstr "群组删掉了。" + +#: lib/php/monica/process.inc.php:1152 lib/php/monica/process.inc.php:1230 +msgid "This membership record was not modified." +msgstr "成员关系未异动。" + +#: lib/php/monica/process.inc.php:1158 lib/php/monica/process.inc.php:1236 +msgid "This membership record has been successfully added." +msgstr "成员关系建好了。" + +#: lib/php/monica/process.inc.php:1162 lib/php/monica/process.inc.php:1240 +msgid "This membership record has been successfully updated." +msgstr "成员关系存好了。" + +#: lib/php/monica/process.inc.php:1166 lib/php/monica/process.inc.php:1244 +msgid "This membership record has been successfully deleted." +msgstr "成员关系删掉了。" + +#: lib/php/monica/process.inc.php:1308 +msgid "This script privilege record was not modified." +msgstr "程序权限未异动。" + +#: lib/php/monica/process.inc.php:1314 +msgid "This script privilege record has been successfully added." +msgstr "程序权限建好了。" + +#: lib/php/monica/process.inc.php:1318 +msgid "This script privilege record has been successfully updated." +msgstr "程序权限存好了。" + +#: lib/php/monica/process.inc.php:1322 +msgid "This script privilege record has been successfully deleted." +msgstr "程序权限删掉了。" + +#: lib/php/monica/process.inc.php:1438 +msgid "This user preference was not modified." +msgstr "用户偏好未异动。" + +#: lib/php/monica/process.inc.php:1444 +msgid "This user preference has been successfully added." +msgstr "用户偏好建好了。" + +#: lib/php/monica/process.inc.php:1448 +msgid "This user preference has been successfully updated." +msgstr "用户偏好存好了。" + +#: lib/php/monica/process.inc.php:1452 +msgid "This user preference has been successfully deleted." +msgstr "用户偏好删掉了。" + +#: lib/php/monica/process.inc.php:1560 +msgid "This user request was not modified." +msgstr "用户申请未异动。" + +#: lib/php/monica/process.inc.php:1566 +msgid "This user request has been successfully added." +msgstr "用户申请建好了。" + +#: lib/php/monica/process.inc.php:1570 +msgid "This user request has been successfully updated." +msgstr "用户申请存好了。" + +#: lib/php/monica/process.inc.php:1574 +msgid "This user request has been successfully deleted." +msgstr "用户申请删掉了。" + +#: lib/php/monica/process.inc.php:1685 +msgid "This page was not modified." +msgstr "网页未异动。" + +#: lib/php/monica/process.inc.php:1691 +msgid "This page has been successfully added." +msgstr "网页建好了。" + +#: lib/php/monica/process.inc.php:1695 +msgid "This page has been successfully updated." +msgstr "网页存好了。" + +#: lib/php/monica/process.inc.php:1699 +msgid "This page has been successfully deleted." +msgstr "网页删掉了。" + +#: lib/php/monica/process.inc.php:1874 +msgid "This news article was not modified." +msgstr "新闻未异动。" + +#: lib/php/monica/process.inc.php:1880 +msgid "This news article has been successfully added." +msgstr "新闻建好了。" + +#: lib/php/monica/process.inc.php:1884 +msgid "This news article has been successfully updated." +msgstr "新闻存好了。" + +#: lib/php/monica/process.inc.php:1888 +msgid "This news article has been successfully deleted." +msgstr "新闻删掉了。" + +#: lib/php/monica/process.inc.php:1997 +msgid "This country was not modified." +msgstr "国家未异动。" + +#: lib/php/monica/process.inc.php:2003 +msgid "This country has been successfully added." +msgstr "国家建好了。" + +#: lib/php/monica/process.inc.php:2007 +msgid "This country has been successfully updated." +msgstr "国家存好了。" + +#: lib/php/monica/process.inc.php:2011 +msgid "This country has been successfully deleted." +msgstr "国家删掉了。" + +#: lib/php/monica/process.inc.php:2097 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. (%0.3f seconds)" +msgstr "该类网页重制好了。( %0.3f 秒)" + +#: lib/php/monica/process.inc.php:2158 +#, c-format +msgid "Welcome, %s!" +msgstr "%s,你好。" + +#: lib/php/monica/process.inc.php:2204 +msgid "You have successfully logged out." +msgstr "注销好了。" + +#: lib/php/monica/process.inc.php:2439 +msgid "This related link was not modified." +msgstr "相关链接未异动。" + +#: lib/php/monica/process.inc.php:2445 +msgid "This related link has been successfully added." +msgstr "相关链接建好了。" + +#: lib/php/monica/process.inc.php:2449 +msgid "This related link has been successfully updated." +msgstr "相关链接存好了。" + +#: lib/php/monica/process.inc.php:2453 +msgid "This related link has been successfully deleted." +msgstr "相关链接删掉了。" + +#: lib/php/monica/request.inc.php:38 +msgid "Please specify the request." +msgstr "请设置申请编号。" + +#: lib/php/monica/request.inc.php:46 lib/php/monica/request.inc.php:55 +#, c-format +msgid "Invalid request S/N: %s." +msgstr "申请编号无效: %s 。" + +#: lib/php/monica/sitesize.inc.php:41 +#, c-format +msgid "Currently using files %s.\n" +msgstr "现用文件 %s。\n" + +#: lib/php/monica/sitesize.inc.php:46 +#, c-format +msgid "Currently using files %s, database %s, total %s.\n" +msgstr "现用文件 %s ,数据库 %s ,合计 %s 。\n" + +#: lib/php/monica/upload.inc.php:70 +#, c-format +msgid "MIME file type: %s" +msgstr "MIME 文件格式: %s" + +#: lib/php/monica/upload.inc.php:71 +#, c-format +msgid "File name: %s" +msgstr "文件名: %s" + +#: lib/php/monica/upload.inc.php:72 +#, c-format +msgid "File size: %s bytes" +msgstr "文件大小: %s 字节" + +#: lib/php/monica/validate.inc.php:116 +msgid "HTML Validatior Logo Area" +msgstr "HTML 验证标志区" + +#: lib/php/monica/validate.inc.php:117 +msgid "HTML validation result of this page" +msgstr "本页的 HTML 验证结果" + +#: lib/php/monica/validate.inc.php:118 +#, c-format +msgid "Valid %s!" +msgstr "%s 正确!" + +#: lib/php/monica/validate.inc.php:119 +msgid "CSS validation result of this page" +msgstr "本页的 CSS 验证结果" + +#: lib/php/monica/validate.inc.php:120 +msgid "Valid CSS!" +msgstr "CSS 正确!" + +#: lib/php/monica/validate.inc.php:121 +msgid "Explanation of Level Triple-A Conformance" +msgstr "无障碍三 A 级标准说明" + +#: lib/php/monica/validate.inc.php:122 +msgid "" +"Level Triple-A conformance icon, W3C-WAI Web Content Accessibility " +"Guidelines 1.0" +msgstr "W3C 无障碍网页规范 1.0 三 A 级标准标章" diff --git a/po/monica/zh_CN.pox b/po/monica/zh_CN.pox new file mode 100644 index 0000000..a2d0489 --- /dev/null +++ b/po/monica/zh_CN.pox @@ -0,0 +1,3243 @@ +# Simplified Chinese PO file for the monica core +# Copyright (C) 2002-2018 Pristine Communcations +# This file is distributed under the same license as the monica package. +# imacat , 2002-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: monica 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 12:53+0800\n" +"PO-Revision-Date: 2018-11-02 01:25+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: lib/php/monica/checker.inc.php:159 +msgid "Please select a user." +msgstr "请选择用户。" + +#: lib/php/monica/checker.inc.php:163 +msgid "This user does not exist anymore. Please select another one." +msgstr "查无此人,请重新选择。" + +#: lib/php/monica/checker.inc.php:181 +msgid "Please select a group." +msgstr "请选择群组。" + +#: lib/php/monica/checker.inc.php:185 +msgid "This group does not exist anymore. Please select another one." +msgstr "查无此群组,请重新选择。" + +#: lib/php/monica/checker.inc.php:203 +msgid "Please fill in the script." +msgstr "请填上程序文件名。" + +#: lib/php/monica/checker.inc.php:207 +#, c-format +msgid "This script is too long. (Max. length %d)" +msgstr "程序文件名太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:212 +msgid "This script is not a valid script. Please specify another one." +msgstr "查无此程序,请重新设置运行的程序。" + +#: lib/php/monica/checker.inc.php:230 +msgid "Please fill in the date." +msgstr "请填上日期。" + +#: lib/php/monica/checker.inc.php:234 lib/php/monica/checker.inc.php:238 +#: lib/php/monica/checker.inc.php:241 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期请以 YYYY-MM-DD 格式正确填写。" + +#: lib/php/monica/checker.inc.php:259 +msgid "Please fill in the ID." +msgstr "请填上代号。" + +#: lib/php/monica/checker.inc.php:263 +#, c-format +msgid "This ID. is too long. (Max. length %d)" +msgstr "代号太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:267 +#, c-format +msgid "This ID. is too short. (Min. length %d)" +msgstr "代号太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:272 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "代号限用小写英文本母、数字和底线。" + +#: lib/php/monica/checker.inc.php:294 +msgid "Please fill in the order." +msgstr "请填上先后次序。" + +#: lib/php/monica/checker.inc.php:298 +#, c-format +msgid "This order is too long. (Max. length %d)" +msgstr "次序太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:303 +msgid "Please fill in a positive integer order." +msgstr "次序请填正整数。" + +#: lib/php/monica/checker.inc.php:307 lib/php/monica/checker.inc.php:317 +#, c-format +msgid "" +"The order is too small. Please fill in a larger order between %d and %d." +msgstr "次序太小了,请设置在 %d 到 %d 之间。" + +#: lib/php/monica/checker.inc.php:321 +#, c-format +msgid "" +"The order is too large. Please fill in a smaller order between %d and %d." +msgstr "次序太大了,请设置在 %d 到 %d 之间。" + +#: lib/php/monica/checker.inc.php:348 +msgid "Please fill in the page path." +msgstr "请填上网页路径。" + +#: lib/php/monica/checker.inc.php:352 +#, c-format +msgid "This page path is too long. (Max. length %d)" +msgstr "网页路径太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:365 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "已有同一网页,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:369 +msgid "Please fill in an absolute page path." +msgstr "网页路径请填上绝对路径。" + +#: lib/php/monica/checker.inc.php:373 +msgid "Please fill in a valid page path." +msgstr "网页路径请填上正确路径。" + +#: lib/php/monica/checker.inc.php:377 +msgid "You cannot overwrite the cover home page." +msgstr "不可以程序设置首页。" + +#: lib/php/monica/checker.inc.php:381 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "网页路径限填 HTML 地址( *.html )。" + +#: lib/php/monica/checker.inc.php:422 lib/php/monica/checker.inc.php:428 +msgid "Please fill in the attachment description." +msgstr "请填上附件说明。" + +#: lib/php/monica/checker.inc.php:432 +#, c-format +msgid "This attachment description is too long. (Max. length %d)" +msgstr "附件说明太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:449 +msgid "This PDF. file does not exist anymore. Please upload another one." +msgstr "查无此 PDF. 档,请重新上传文件。" + +#: lib/php/monica/checker.inc.php:456 +#, c-format +msgid "This PDF. file is too large. (Max. size %s)" +msgstr "文件太大。(上限 %s )" + +#: lib/php/monica/checker.inc.php:461 +msgid "Please upload only PDF. file." +msgstr "限上传 PDF. 档。" + +#: lib/php/monica/checker.inc.php:479 +msgid "Please fill in the title." +msgstr "请填上标题。" + +#: lib/php/monica/checker.inc.php:483 +#, c-format +msgid "This title is too long. (Max. length %d)" +msgstr "标题太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:502 +msgid "Please fill in the subject." +msgstr "请填上主题。" + +#: lib/php/monica/checker.inc.php:506 +#, c-format +msgid "This subject is too long. (Max. length %d)" +msgstr "主题太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:524 lib/php/monica/form.inc.php:3159 +#: lib/php/monica/form.inc.php:3172 +msgid "Fill in the content here." +msgstr "请填上内文。" + +#: lib/php/monica/checker.inc.php:528 +msgid "Please fill in the content." +msgstr "请填上内文。" + +#: lib/php/monica/checker.inc.php:532 +#, c-format +msgid "This content is too long. (Max. length %d)" +msgstr "内文太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:551 +msgid "Please fill in the keywords." +msgstr "请填上关键字。" + +#: lib/php/monica/checker.inc.php:555 +#, c-format +msgid "This keyword list is too long. (Max. length %d)" +msgstr "关键字太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:572 +msgid "Please select a proper pinyin." +msgstr "请选择符合的拼音。" + +#: lib/php/monica/checker.inc.php:578 +#, c-format +msgid "This pinyin is too long. (Max. length %d)" +msgstr "拼音太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:583 +msgid "" +"This pinyin does not match the Chinese. Please select a proper pinyin from " +"the list." +msgstr "拼音与中文不合,请重新于列表中选择。" + +#: lib/php/monica/checker.inc.php:609 lib/php/monica/pic.inc.php:82 +msgid "Please upload the picture." +msgstr "请上传图档。" + +#: lib/php/monica/checker.inc.php:616 lib/php/monica/checker.inc.php:3214 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "查无此图,请重新上传图档。" + +#: lib/php/monica/checker.inc.php:622 +#, c-format +msgid "This picture is too large. Please upload another one. (Max. size %d)" +msgstr "图档太大,请重新上传图档(最大 %d )。" + +#: lib/php/monica/checker.inc.php:639 lib/php/monica/form.inc.php:3588 +#, c-format +msgid "Please upload a new picture from %s." +msgstr "请由%s建新图片。" + +#: lib/php/monica/checker.inc.php:664 lib/php/monica/checker.inc.php:727 +msgid "Please fill in the picture caption." +msgstr "请填上图片标题。" + +#: lib/php/monica/checker.inc.php:668 lib/php/monica/checker.inc.php:731 +#, c-format +msgid "This picture caption is too long. (Max. length %d)" +msgstr "图片标题太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:686 lib/php/monica/checker.inc.php:749 +msgid "Please select the picture position." +msgstr "请设置图片位置。" + +#: lib/php/monica/checker.inc.php:692 lib/php/monica/checker.inc.php:755 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "图片位置无效。请由表上选择适当的图片位置。" + +#: lib/php/monica/checker.inc.php:791 lib/php/monica/checker.inc.php:794 +#, c-format +msgid "Your uploaded file is too large (Max %s)." +msgstr "上传文件太大。(上限 %s )" + +#: lib/php/monica/checker.inc.php:797 lib/php/monica/pic.inc.php:80 +msgid "" +"Upload not completed. Disk may be full or connection may be closed in the " +"half. You may try to upload again, or contact the system administrator for " +"this problem." +msgstr "" +"上传失败。可能是服务器磁盘满了,或传到一半网络断线。请重新上传一次,或洽网站" +"系统管理人员处理。" + +#: lib/php/monica/checker.inc.php:799 lib/php/monica/pic.inc.php:84 +#, c-format +msgid "Upload failed with an unknown error (%d)." +msgstr "上传失败,原因不明。( %d )" + +#: lib/php/monica/checker.inc.php:1183 lib/php/monica/chkfunc.inc.php:59 +#: lib/php/monica/chkfunc.inc.php:72 lib/php/monica/preview.inc.php:29 +#, c-format +msgid "The following field was not received: \"%s\"." +msgstr "程序没有收到下列字段:「 %s 」" + +#: lib/php/monica/checker.inc.php:1262 +msgid "Please fill in the user ID." +msgstr "请填上帐号。" + +#: lib/php/monica/checker.inc.php:1266 +#, c-format +msgid "This user ID. is too long. (Max. length %d)" +msgstr "帐号太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:1270 +#, c-format +msgid "This user ID. is too short. (Min. length %d)" +msgstr "帐号太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1275 +msgid "" +"Only lower-case English letters, numbers, at-signs, dots, dashes and " +"underscores are allowed for the user ID." +msgstr "帐号限用小写英文本母、数字、 @ 号、点、横线和底线。" + +#: lib/php/monica/checker.inc.php:1287 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "该用户已有帐号,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:1317 +msgid "Please fill in the password." +msgstr "请填上密码。" + +#: lib/php/monica/checker.inc.php:1320 +msgid "Please confirm the password." +msgstr "请确认密码。" + +#: lib/php/monica/checker.inc.php:1324 +#, c-format +msgid "This password is too long. (Max. length %d)" +msgstr "密码太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:1329 +#, c-format +msgid "This password is too short. (Min. length %d)" +msgstr "密码太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1334 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "两次密码不合,请重新设置密码。" + +#: lib/php/monica/checker.inc.php:1345 +msgid "This password is based on the user ID." +msgstr "密码不可由帐号组成。" + +#: lib/php/monica/checker.inc.php:1360 +msgid "This password does not contain enough different characters." +msgstr "密码重复的字符太多。" + +#: lib/php/monica/checker.inc.php:1364 +msgid "This password is too simplistic/systematic." +msgstr "密码结构太简单。" + +#: lib/php/monica/checker.inc.php:1368 +msgid "This password is based on a dictionary word." +msgstr "密码不可由字典单字组成。" + +#: lib/php/monica/checker.inc.php:1370 +msgid "This password is based on a (reversed) dictionary word." +msgstr "密码不可由倒过来的字典单字组成。" + +#: lib/php/monica/checker.inc.php:1372 +msgid "This password is too simple." +msgstr "密码太简单。" + +#: lib/php/monica/checker.inc.php:1378 +msgid "You cannot use a password that is based on the user ID." +msgstr "密码不可由帐号组成。" + +#: lib/php/monica/checker.inc.php:1397 +msgid "Please fill in the name." +msgstr "请填上姓名。" + +#: lib/php/monica/checker.inc.php:1401 +#, c-format +msgid "This name is too long. (Max. length %d)" +msgstr "姓名太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:1420 +msgid "Please fill in the e-mail." +msgstr "请填上 E-mail 信箱。" + +#: lib/php/monica/checker.inc.php:1424 +#, c-format +msgid "This e-mail is too long. (Max. length %d)" +msgstr "E-mail 信箱太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:1428 +#, c-format +msgid "This e-mail is too short. (Min. length %d)" +msgstr "E-mail 信箱太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1437 +msgid "Please fill in a valid e-mail address." +msgstr "请填上正确的 E-mail 信箱。" + +#: lib/php/monica/checker.inc.php:1439 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "查无这个信箱的所属网域,请检查有没有拼错。" + +#: lib/php/monica/checker.inc.php:1461 lib/php/monica/checker.inc.php:1655 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "隶属群组重复,请勿重复设置。" + +#: lib/php/monica/checker.inc.php:1478 +msgid "You cannot submit the super-user group along with other groups." +msgstr "总管理员群组不可与其它群组一起设置。" + +#: lib/php/monica/checker.inc.php:1480 +msgid "You cannot set the administrators group." +msgstr "不可设置所有网站管理员群组" + +#: lib/php/monica/checker.inc.php:1482 +msgid "You cannot set the all-users group." +msgstr "不可设置所有登录用户群组。" + +#: lib/php/monica/checker.inc.php:1515 +msgid "Please fill in the group ID." +msgstr "请填上群组代号。" + +#: lib/php/monica/checker.inc.php:1519 +#, c-format +msgid "This group ID. is too long. (Max. length %d)" +msgstr "群组代号太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:1523 +#, c-format +msgid "This group ID. is too short. (Min. length %d)" +msgstr "群组代号太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1528 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "群组代号限用小写英文本母、数字和底线。" + +#: lib/php/monica/checker.inc.php:1540 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "已有同一群组,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:1558 +msgid "Please fill in the privilege description." +msgstr "请填上权限说明。" + +#: lib/php/monica/checker.inc.php:1562 +#, c-format +msgid "This privilege description is too long. (Max. length %d)" +msgstr "权限说明太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:1585 +msgid "This user member is duplicated. You cannot set duplicated ones." +msgstr "用户成员重复,请勿重复设置。" + +#: lib/php/monica/checker.inc.php:1620 +msgid "This group member is duplicated. You cannot set duplicated ones." +msgstr "群组成员重复,请勿重复设置。" + +#: lib/php/monica/checker.inc.php:1747 lib/php/monica/checker.inc.php:1855 +msgid "Please select a member." +msgstr "请选择成员。" + +#: lib/php/monica/checker.inc.php:1751 lib/php/monica/checker.inc.php:1859 +msgid "This member does not exist anymore. Please select another one." +msgstr "查无此成员,请重新选择。" + +#: lib/php/monica/checker.inc.php:1770 lib/php/monica/checker.inc.php:1883 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "已有同一成员关系,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:1837 +msgid "Please select a different belonging group." +msgstr "隶属群组请选择别的群组。" + +#: lib/php/monica/checker.inc.php:1864 +msgid "Please select a different group member." +msgstr "群组成员请选择别的群组。" + +#: lib/php/monica/checker.inc.php:1958 +msgid "" +"This script privilege already exists. You cannot create a duplicated one." +msgstr "已有同一程序权限,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:1996 lib/php/monica/checker.inc.php:2184 +msgid "Please select the user." +msgstr "请选择用户。" + +#: lib/php/monica/checker.inc.php:2002 lib/php/monica/checker.inc.php:2190 +msgid "This option is invalid. Please select a proper user." +msgstr "用户选项无效,请由表上选择适当的用户。" + +#: lib/php/monica/checker.inc.php:2020 +msgid "Please set the preference domain." +msgstr "请设置适用范围。" + +#: lib/php/monica/checker.inc.php:2026 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "适用范围选项无效,请设置适当的适用范围。" + +#: lib/php/monica/checker.inc.php:2039 lib/php/monica/checker.inc.php:2295 +msgid "Please fill in the preference domain." +msgstr "请填上偏好的适用范围。" + +#: lib/php/monica/checker.inc.php:2043 lib/php/monica/checker.inc.php:2299 +#, c-format +msgid "This preference domain is too long. (Max. length %d)" +msgstr "偏好适用范围太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2063 +msgid "Please fill in the preference name." +msgstr "请填上偏好的名称。" + +#: lib/php/monica/checker.inc.php:2067 +#, c-format +msgid "This preference name is too long. (Max. length %d)" +msgstr "偏好名称太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2086 +msgid "Please fill in the preference value." +msgstr "请填上偏好的值。" + +#: lib/php/monica/checker.inc.php:2090 +#, c-format +msgid "This preference value is too long. (Max. length %d)" +msgstr "偏好值太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2119 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "已有同一用户偏好,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:2167 +msgid "Please select the request type." +msgstr "请选择申请类别。" + +#: lib/php/monica/checker.inc.php:2173 +msgid "This option is invalid. Please select a proper request type." +msgstr "申请类别选项无效,请由表上选择适当的申请类别。" + +#: lib/php/monica/checker.inc.php:2194 +msgid "You must choose anonymous for join requests." +msgstr "加入申请不可具名。" + +#: lib/php/monica/checker.inc.php:2197 +msgid "You cannot choose anonymous for non-join requests." +msgstr "非加入申请必须具名。" + +#: lib/php/monica/checker.inc.php:2221 lib/php/monica/form.inc.php:5502 +msgid "Please fill in the request arguments list here." +msgstr "请填上备注数据。" + +#: lib/php/monica/checker.inc.php:2229 +#, c-format +msgid "This request arguments list is too long. (Max. length %d)" +msgstr "申请备注数据太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2349 +msgid "Please fill in the number of rows per page." +msgstr "请填上每页显示笔数。" + +#: lib/php/monica/checker.inc.php:2353 +#, c-format +msgid "This number of rows per page is too long. (Max. length %d)" +msgstr "每页显示笔数太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2358 +msgid "Please fill in a positive integer number of rows per page." +msgstr "每页显示笔数请填正整数。" + +#: lib/php/monica/checker.inc.php:2362 lib/php/monica/checker.inc.php:2372 +#, c-format +msgid "" +"The number of rows per page is too small. Please fill in a larger number of " +"rows per page between %d and %d." +msgstr "每页显示笔数太小了,请设置在 %d 到 %d 之间。" + +#: lib/php/monica/checker.inc.php:2376 +#, c-format +msgid "" +"The number of rows per page is too large. Please fill in a smaller number " +"of rows per page between %d and %d." +msgstr "每页显示笔数太大了,请设置在 %d 到 %d 之间。" + +#: lib/php/monica/checker.inc.php:2443 +msgid "Please fill in your user ID." +msgstr "请填上你的帐号。" + +#: lib/php/monica/checker.inc.php:2451 lib/php/monica/checker.inc.php:2458 +#: lib/php/monica/checker.inc.php:2475 lib/php/monica/checker.inc.php:2508 +#: lib/php/monica/checker.inc.php:2540 lib/php/monica/checker.inc.php:2548 +#: lib/php/monica/checker.inc.php:2558 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "登录错误,用户代号或密码有误。" + +#: lib/php/monica/checker.inc.php:2495 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "帐号停用中,请洽系统管理员。" + +#: lib/php/monica/checker.inc.php:2531 +msgid "Please fill in your password." +msgstr "请填上你的密码。" + +#: lib/php/monica/checker.inc.php:2581 +msgid "You are not an administrator so may not log in here." +msgstr "非管理员勿入。" + +#: lib/php/monica/checker.inc.php:2600 +msgid "You are an administrator so may not log in here." +msgstr "管理人员勿入。" + +#: lib/php/monica/checker.inc.php:2751 +msgid "Please fill in the code." +msgstr "请填上代码。" + +#: lib/php/monica/checker.inc.php:2755 +#, c-format +msgid "You must fill in a %d-letters code." +msgstr "代码限为两个字母。" + +#: lib/php/monica/checker.inc.php:2760 +msgid "You can only use upper letters and for the code." +msgstr "代码限用大写英文本母。" + +#: lib/php/monica/checker.inc.php:2772 +msgid "This code is duplicated. You cannot create a duplicated one." +msgstr "代码重复,请勿重复设置。" + +#: lib/php/monica/checker.inc.php:2790 +msgid "Please fill in the country name." +msgstr "请填上国名。" + +#: lib/php/monica/checker.inc.php:2794 +#, c-format +msgid "This country name is too long. (Max. length %d)" +msgstr "国名太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2822 lib/php/monica/checker.inc.php:2841 +msgid "Please select a parent category." +msgstr "请选择所属的大类。" + +#: lib/php/monica/checker.inc.php:2828 +msgid "This option is invalid. Please select a proper parent category." +msgstr "大类选项无效,请由表上选择适当的大类。" + +#: lib/php/monica/checker.inc.php:2845 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "查无此大类,请重新选择。" + +#: lib/php/monica/checker.inc.php:2850 +msgid "A category cannot belong to itself. Please select another one." +msgstr "分类不可属于自己本身,请重新选择。" + +#: lib/php/monica/checker.inc.php:2858 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "分类不可属于自己的子类,请重新选择。" + +#: lib/php/monica/checker.inc.php:2876 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "「 index 」为目录档 index.html 专用,代号不可设为「 index 」。" + +#: lib/php/monica/checker.inc.php:2894 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "已有同一分类,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:2941 +msgid "Please fill in the URL.." +msgstr "请填上网址。" + +#: lib/php/monica/checker.inc.php:2945 +#, c-format +msgid "This URL. is too long. (Max. length %d)" +msgstr "网址太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:2950 +msgid "Please fill in a valid URL.." +msgstr "请填上正确网址。" + +#: lib/php/monica/checker.inc.php:2962 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "已有同一相关链接,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:2967 +msgid "This URL. is not reachable. Check if there is any typo in it." +msgstr "这个网址连不上,请检查有没有拼错。" + +#: lib/php/monica/checker.inc.php:2984 lib/php/monica/form.inc.php:3261 +msgid "Fill in the description here." +msgstr "请填上说明。" + +#: lib/php/monica/checker.inc.php:2988 +msgid "Please fill in the description." +msgstr "请填上说明。" + +#: lib/php/monica/checker.inc.php:2992 +#, c-format +msgid "This description is too long. (Max. length %d)" +msgstr "说明太长了。(最长 %d )" + +#: lib/php/monica/checker.inc.php:3012 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "分类重复,请勿重复设置。。" + +#: lib/php/monica/checker.inc.php:3016 lib/php/monica/checker.inc.php:3072 +msgid "This category does not exist anymore. Please select another one." +msgstr "查无此分类,请重新选择。" + +#: lib/php/monica/checker.inc.php:3022 lib/php/monica/checker.inc.php:3068 +msgid "Please select a category." +msgstr "请选择分类。" + +#: lib/php/monica/checker.inc.php:3090 +msgid "Please select a related link." +msgstr "请选择相关链接。" + +#: lib/php/monica/checker.inc.php:3094 +msgid "This link does not exist anymore. Please select another one." +msgstr "查无此相关链接,请重新选择。" + +#: lib/php/monica/checker.inc.php:3113 +msgid "" +"This link categorization already exists. You cannot create a duplicated one." +msgstr "已有同一链接分类数据,请勿重复建档。" + +#: lib/php/monica/checker.inc.php:3154 +msgid "Please select the type." +msgstr "请选择类型。" + +#: lib/php/monica/checker.inc.php:3158 +msgid "This type does not exist anymore. Please select another one." +msgstr "查无此类型,请重新选择。" + +#: lib/php/monica/checker.inc.php:3185 lib/php/monica/list.inc.php:961 +msgid "Please fill in your query." +msgstr "请填上查找的内容。" + +#: lib/php/monica/checker.inc.php:3210 +msgid "Please submit the picture." +msgstr "请上传图档。" + +#: lib/php/monica/checker.inc.php:3237 lib/php/monica/checker.inc.php:3328 +msgid "Please fill in the resize ratio." +msgstr "请填上缩放比例。" + +#: lib/php/monica/checker.inc.php:3305 +msgid "Please specify a valid picture." +msgstr "您上传的不是图档,请重新上传图档。" + +#: lib/php/monica/chkfunc.inc.php:156 lib/php/monica/chkfunc.inc.php:160 +#: lib/php/monica/chkfunc.inc.php:163 lib/php/monica/chkfunc.inc.php:166 +msgid "Please select a legal year." +msgstr "请选一个正确的年份。" + +#: lib/php/monica/chkfunc.inc.php:171 lib/php/monica/chkfunc.inc.php:175 +#: lib/php/monica/chkfunc.inc.php:178 +msgid "Please select a legal month." +msgstr "请选一个正确的月份。" + +#: lib/php/monica/chkfunc.inc.php:183 lib/php/monica/chkfunc.inc.php:187 +#: lib/php/monica/chkfunc.inc.php:193 +msgid "Please select a legal day." +msgstr "请选一个正确的日期。" + +#: lib/php/monica/chkwrite.inc.php:27 +#, c-format +msgid "%s: It is not a file." +msgstr "%s: 这不是文件。" + +#: lib/php/monica/chkwrite.inc.php:32 +#, c-format +msgid "%s: You have no permission to overwrite this file." +msgstr "%s: 存盘的权限不足,无法存盘。" + +#: lib/php/monica/chkwrite.inc.php:45 +#, c-format +msgid "%s: You cannot create anything under the root directory." +msgstr "%s: 不可在根目录下建档。" + +#: lib/php/monica/chkwrite.inc.php:50 +#, c-format +msgid "" +"%s: One of the parents of this file (%s) is not a directory. You cannot " +"create any new file inside." +msgstr "%s: 路径中间有一部份( %s )不是目录,无法往下建档。" + +#: lib/php/monica/chkwrite.inc.php:55 +#, c-format +msgid "%s: You have no permission to create any file under %s." +msgstr "%s: 权限不足,无法在 %s 建档。" + +#: lib/php/monica/commtext.inc.php:18 +msgid "(not set)" +msgstr "(未设置)" + +#: lib/php/monica/commtext.inc.php:24 +msgid "(none)" +msgstr "(无)" + +#: lib/php/monica/commtext.inc.php:30 +msgid "(N/A)" +msgstr "(不可考)" + +#: lib/php/monica/commtext.inc.php:36 +msgid "(blank)" +msgstr "(留白)" + +#: lib/php/monica/echoform.inc.php:173 +#, c-format +msgid "%s bytes" +msgstr "%s 字节" + +#: lib/php/monica/form.inc.php:168 +msgid "Delete it" +msgstr "删掉" + +#: lib/php/monica/form.inc.php:174 +msgid "Are you sure you want to delete it? It cannot be recovered." +msgstr "你真的要删掉吗?数据删掉就救不回来了。" + +#: lib/php/monica/form.inc.php:188 +msgid "*" +msgstr "" + +#: lib/php/monica/form.inc.php:224 +msgid "This table provides you a form to add a new data record." +msgstr "本表提供建新数据的表单。" + +#: lib/php/monica/form.inc.php:228 +msgid "This table provides you a form to update a current data record." +msgstr "本表提供异动数据的表单。" + +#: lib/php/monica/form.inc.php:232 +msgid "This table provides you a form to delete a data record." +msgstr "本表提供删除数据的表单。" + +#: lib/php/monica/form.inc.php:281 +msgid "Add a New Data Record" +msgstr "建新数据" + +#: lib/php/monica/form.inc.php:285 +msgid "Update a Current Data Record" +msgstr "异动数据" + +#: lib/php/monica/form.inc.php:289 +msgid "Delete a Data Record" +msgstr "删除数据" + +#: lib/php/monica/form.inc.php:301 +msgid "Preview it." +msgstr "预览。" + +#: lib/php/monica/form.inc.php:500 lib/php/monica/form.inc.php:506 +#: lib/php/monica/form.inc.php:691 lib/php/monica/form.inc.php:697 +#: lib/php/monica/preview.inc.php:146 +msgid "Preview" +msgstr "预览" + +#: lib/php/monica/form.inc.php:501 lib/php/monica/form.inc.php:507 +#: lib/php/monica/form.inc.php:692 lib/php/monica/form.inc.php:698 +msgid "Confirm and submit" +msgstr "确认发送" + +#: lib/php/monica/form.inc.php:708 lib/php/monica/form.inc.php:1692 +#: lib/php/monica/form.inc.php:1778 lib/php/monica/list.inc.php:1809 +msgid "Delete" +msgstr "删除" + +#: lib/php/monica/form.inc.php:709 lib/php/monica/form.inc.php:6437 +#: lib/php/monica/form.inc.php:6488 +msgid "Cancel" +msgstr "取消" + +#: lib/php/monica/form.inc.php:1042 lib/php/monica/form.inc.php:3499 +msgid "Set the picture" +msgstr "设置图片" + +#: lib/php/monica/form.inc.php:1043 lib/php/monica/form.inc.php:3031 +#: lib/php/monica/form.inc.php:3500 +msgid "Delete this picture" +msgstr "删掉图片" + +#: lib/php/monica/form.inc.php:1048 lib/php/monica/form.inc.php:1178 +#: lib/php/monica/form.inc.php:3037 lib/php/monica/form.inc.php:3104 +#: lib/php/monica/form.inc.php:3505 lib/php/monica/form.inc.php:3677 +#: lib/php/monica/form.inc.php:6181 lib/php/monica/list.inc.php:814 +msgid "Picture preview" +msgstr "图片预览" + +#: lib/php/monica/form.inc.php:1059 lib/php/monica/form.inc.php:1109 +#: lib/php/monica/form.inc.php:1185 +#, c-format +msgid "Picture #%d:" +msgstr "图片 %d :" + +#: lib/php/monica/form.inc.php:1080 lib/php/monica/form.inc.php:1131 +#: lib/php/monica/form.inc.php:1166 lib/php/monica/form.inc.php:1199 +msgid "Caption:" +msgstr "标题:" + +#: lib/php/monica/form.inc.php:1092 lib/php/monica/form.inc.php:3064 +#: lib/php/monica/form.inc.php:3566 lib/php/monica/form.inc.php:6201 +msgid "Original picture preview" +msgstr "原图片预览" + +#: lib/php/monica/form.inc.php:1093 lib/php/monica/form.inc.php:3065 +#: lib/php/monica/form.inc.php:3567 lib/php/monica/form.inc.php:6215 +msgid "New picture preview" +msgstr "新图片预览" + +#: lib/php/monica/form.inc.php:1113 lib/php/monica/form.inc.php:1276 +#: lib/php/monica/form.inc.php:1363 lib/php/monica/form.inc.php:1451 +#: lib/php/monica/form.inc.php:1560 lib/php/monica/form.inc.php:1650 +#: lib/php/monica/form.inc.php:1727 lib/php/monica/form.inc.php:1825 +#: lib/php/monica/form.inc.php:1916 lib/php/monica/form.inc.php:1977 +#: lib/php/monica/form.inc.php:2053 lib/php/monica/form.inc.php:2159 +#: lib/php/monica/form.inc.php:2391 lib/php/monica/form.inc.php:2592 +#: lib/php/monica/form.inc.php:2689 lib/php/monica/form.inc.php:2800 +#: lib/php/monica/form.inc.php:2897 lib/php/monica/form.inc.php:2980 +#: lib/php/monica/form.inc.php:3069 lib/php/monica/form.inc.php:3200 +#: lib/php/monica/form.inc.php:3571 lib/php/monica/form.inc.php:3627 +#: lib/php/monica/form.inc.php:3640 lib/php/monica/form.inc.php:3747 +#: lib/php/monica/form.inc.php:4423 lib/php/monica/form.inc.php:4548 +#: lib/php/monica/form.inc.php:4747 lib/php/monica/form.inc.php:4884 +#: lib/php/monica/form.inc.php:5018 lib/php/monica/form.inc.php:6194 +#: lib/php/monica/form.inc.php:6261 +msgid "Original:" +msgstr "原:" + +#: lib/php/monica/form.inc.php:1141 lib/php/monica/form.inc.php:1281 +#: lib/php/monica/form.inc.php:1369 lib/php/monica/form.inc.php:1456 +#: lib/php/monica/form.inc.php:1575 lib/php/monica/form.inc.php:1655 +#: lib/php/monica/form.inc.php:1732 lib/php/monica/form.inc.php:1832 +#: lib/php/monica/form.inc.php:1921 lib/php/monica/form.inc.php:1982 +#: lib/php/monica/form.inc.php:2065 lib/php/monica/form.inc.php:2173 +#: lib/php/monica/form.inc.php:2422 lib/php/monica/form.inc.php:2597 +#: lib/php/monica/form.inc.php:2694 lib/php/monica/form.inc.php:2805 +#: lib/php/monica/form.inc.php:2902 lib/php/monica/form.inc.php:2985 +#: lib/php/monica/form.inc.php:3080 lib/php/monica/form.inc.php:3205 +#: lib/php/monica/form.inc.php:3584 lib/php/monica/form.inc.php:3632 +#: lib/php/monica/form.inc.php:3649 lib/php/monica/form.inc.php:3752 +#: lib/php/monica/form.inc.php:4442 lib/php/monica/form.inc.php:4554 +#: lib/php/monica/form.inc.php:4760 lib/php/monica/form.inc.php:4897 +#: lib/php/monica/form.inc.php:5031 lib/php/monica/form.inc.php:6206 +#: lib/php/monica/form.inc.php:6266 lib/php/monica/form.inc.php:6296 +msgid "New:" +msgstr "新:" + +#: lib/php/monica/form.inc.php:1269 lib/php/monica/form.inc.php:1444 +#: lib/php/monica/form.inc.php:1543 lib/php/monica/form.inc.php:2358 +#: lib/php/monica/form.inc.php:2585 lib/php/monica/form.inc.php:2793 +#: lib/php/monica/form.inc.php:2890 lib/php/monica/form.inc.php:2973 +#: lib/php/monica/form.inc.php:3620 +msgid "Source:" +msgstr "原文:" + +#: lib/php/monica/form.inc.php:1289 lib/php/monica/form.inc.php:1464 +#: lib/php/monica/form.inc.php:1583 lib/php/monica/form.inc.php:2605 +#: lib/php/monica/form.inc.php:2813 lib/php/monica/form.inc.php:2910 +#: lib/php/monica/form.inc.php:2993 +#, c-format +msgid "Please set it from %s." +msgstr "请由%s设置。" + +#: lib/php/monica/form.inc.php:1501 +msgid "Hide" +msgstr "隐藏" + +#: lib/php/monica/form.inc.php:1502 +msgid "Show" +msgstr "秀出" + +#: lib/php/monica/form.inc.php:1691 lib/php/monica/form.inc.php:1777 +#: lib/php/monica/form.inc.php:1887 +msgid "Choose" +msgstr "挑选" + +#: lib/php/monica/form.inc.php:2237 +msgid "Delete this file" +msgstr "删掉文件" + +#: lib/php/monica/form.inc.php:2267 lib/php/monica/form.inc.php:2368 +#: lib/php/monica/form.inc.php:2400 lib/php/monica/form.inc.php:2445 +#: lib/php/monica/form.inc.php:2506 +msgid "File name:" +msgstr "文件名:" + +#: lib/php/monica/form.inc.php:2274 lib/php/monica/form.inc.php:2375 +#: lib/php/monica/form.inc.php:2407 lib/php/monica/form.inc.php:2452 +#: lib/php/monica/form.inc.php:2513 +msgid "MIME file type:" +msgstr "MIME 文件格式:" + +#: lib/php/monica/form.inc.php:2279 lib/php/monica/form.inc.php:2380 +#: lib/php/monica/form.inc.php:2412 lib/php/monica/form.inc.php:2457 +#: lib/php/monica/form.inc.php:2518 +msgid "File size:" +msgstr "文件大小:" + +#: lib/php/monica/form.inc.php:2430 +#, c-format +msgid "Please upload it from %s." +msgstr "请由%s上传。" + +#: lib/php/monica/form.inc.php:3128 +msgid "Address:" +msgstr "地址:" + +#: lib/php/monica/form.inc.php:3129 +msgid "Fill in your address here." +msgstr "请填上地址。" + +#: lib/php/monica/form.inc.php:3135 +msgid "Attachment:" +msgstr "附件:" + +#: lib/php/monica/form.inc.php:3139 +msgid "Attachment description:" +msgstr "附件说明:" + +#: lib/php/monica/form.inc.php:3158 lib/php/monica/form.inc.php:3171 +msgid "Content:" +msgstr "内文:" + +#: lib/php/monica/form.inc.php:3165 +msgid "City:" +msgstr "城市:" + +#: lib/php/monica/form.inc.php:3187 lib/php/monica/form.inc.php:3199 +#: lib/php/monica/form.inc.php:3217 lib/php/monica/form.inc.php:3241 +msgid "Country:" +msgstr "国家:" + +#: lib/php/monica/form.inc.php:3229 +msgid "Created:" +msgstr "建档日期:" + +#: lib/php/monica/form.inc.php:3235 +msgid "Created by:" +msgstr "建档者:" + +#: lib/php/monica/form.inc.php:3247 +msgid "Date:" +msgstr "日期:" + +#: lib/php/monica/form.inc.php:3253 lib/php/monica/form.inc.php:4292 +#: lib/php/monica/form.inc.php:4295 lib/php/monica/list.inc.php:310 +msgid "Disabled?" +msgstr "停用?" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 lib/php/monica/list.inc.php:2020 +msgid "Disabled" +msgstr "停用" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 +msgid "Enabled" +msgstr "未停用" + +#: lib/php/monica/form.inc.php:3254 +msgid "Disable it." +msgstr "停掉。" + +#: lib/php/monica/form.inc.php:3260 lib/php/monica/form.inc.php:4675 +msgid "Description:" +msgstr "说明:" + +#: lib/php/monica/form.inc.php:3267 +msgid "E-mail:" +msgstr "E-mail:" + +#: lib/php/monica/form.inc.php:3273 +msgid "Fax:" +msgstr "传真:" + +#: lib/php/monica/form.inc.php:3279 +msgid "Group:" +msgstr "群组:" + +#: lib/php/monica/form.inc.php:3285 lib/php/monica/form.inc.php:5559 +#: lib/php/monica/form.inc.php:5765 lib/php/monica/form.inc.php:5923 +#: lib/php/monica/form.inc.php:6016 +msgid "Hide?" +msgstr "隐藏?" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it" +msgstr "隐藏起来" + +#: lib/php/monica/form.inc.php:3286 +msgid "Show it" +msgstr "秀出来" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it currently." +msgstr "暂勿秀出。" + +#: lib/php/monica/form.inc.php:3292 +msgid "Host:" +msgstr "主机:" + +#: lib/php/monica/form.inc.php:3298 lib/php/monica/list.inc.php:314 +msgid "HTML?" +msgstr "HTML ?" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2948 +#: lib/php/monica/list.inc.php:3062 +msgid "HTML" +msgstr "HTML" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2949 +#: lib/php/monica/list.inc.php:3063 +msgid "Plain text" +msgstr "纯文本" + +#: lib/php/monica/form.inc.php:3299 +msgid "The submitted content is HTML." +msgstr "以上内文为 HTML 格式。" + +#: lib/php/monica/form.inc.php:3305 lib/php/monica/form.inc.php:5553 +#: lib/php/monica/form.inc.php:6092 +msgid "ID.:" +msgstr "代号:" + +#: lib/php/monica/form.inc.php:3311 +msgid "Introduction:" +msgstr "简介:" + +#: lib/php/monica/form.inc.php:3312 +msgid "Fill in the introduction here." +msgstr "请填上简介。" + +#: lib/php/monica/form.inc.php:3318 +msgid "IP:" +msgstr "IP :" + +#: lib/php/monica/form.inc.php:3324 +msgid "Keywords:" +msgstr "关键字:" + +#: lib/php/monica/form.inc.php:3330 +msgid "Language:" +msgstr "语言:" + +#: lib/php/monica/form.inc.php:3355 +msgid "Name:" +msgstr "名称:" + +#: lib/php/monica/form.inc.php:3365 lib/php/monica/form.inc.php:6010 +msgid "Order:" +msgstr "次序:" + +#: lib/php/monica/form.inc.php:3371 +msgid "Organization:" +msgstr "所属单位:" + +#: lib/php/monica/form.inc.php:3377 +msgid "Parent category:" +msgstr "大类:" + +#: lib/php/monica/form.inc.php:3378 +msgid "At the very top" +msgstr "最上层" + +#: lib/php/monica/form.inc.php:3391 lib/php/monica/form.inc.php:3428 +#: lib/php/monica/form.inc.php:3468 lib/php/monica/form.inc.php:4330 +#: lib/php/monica/form.inc.php:6380 +msgid "Password:" +msgstr "密码:" + +#: lib/php/monica/form.inc.php:3407 lib/php/monica/form.inc.php:3444 +msgid "Confirm password:" +msgstr "确认密码:" + +#: lib/php/monica/form.inc.php:3458 +msgid "(Leave them blank if you don't plan to change your password.)" +msgstr "(若你没有要更改密码,密码栏请留白。)" + +#: lib/php/monica/form.inc.php:3484 +msgid "Page path:" +msgstr "网页路径:" + +#: lib/php/monica/form.inc.php:3490 +msgid "PDF. file:" +msgstr "PDF. 档:" + +#: lib/php/monica/form.inc.php:3508 lib/php/monica/form.inc.php:3570 +#: lib/php/monica/form.inc.php:3680 lib/php/monica/form.inc.php:6169 +#: lib/php/monica/form.inc.php:6193 +msgid "Picture:" +msgstr "图片:" + +#: lib/php/monica/form.inc.php:3531 lib/php/monica/form.inc.php:3615 +#: lib/php/monica/form.inc.php:3619 lib/php/monica/form.inc.php:3693 +msgid "Pic. caption:" +msgstr "图片标题:" + +#: lib/php/monica/form.inc.php:3538 lib/php/monica/form.inc.php:3639 +#: lib/php/monica/form.inc.php:3699 +msgid "Pic. position:" +msgstr "图片位置:" + +#: lib/php/monica/form.inc.php:3718 lib/php/monica/form.inc.php:3746 +#: lib/php/monica/form.inc.php:3780 +msgid "Pinyin:" +msgstr "拼音:" + +#: lib/php/monica/form.inc.php:3722 lib/php/monica/form.inc.php:3756 +msgid "Please fill in the Chinese first." +msgstr "请先填上中文。" + +#: lib/php/monica/form.inc.php:3801 +msgid "Subcategory:" +msgid_plural "Subcategories:" +msgstr[0] "子类:" + +#: lib/php/monica/form.inc.php:3823 +msgid "Script:" +msgstr "程序:" + +#: lib/php/monica/form.inc.php:3829 +msgid "S/N:" +msgstr "编号:" + +#: lib/php/monica/form.inc.php:3835 +msgid "Street:" +msgstr "街号:" + +#: lib/php/monica/form.inc.php:3841 +msgid "Subject:" +msgstr "主题:" + +#: lib/php/monica/form.inc.php:3847 +msgid "Telephone:" +msgstr "电话:" + +#: lib/php/monica/form.inc.php:3853 +msgid "Tel. (cell.):" +msgstr "移动电话:" + +#: lib/php/monica/form.inc.php:3859 +msgid "Tel. (home):" +msgstr "电话(宅):" + +#: lib/php/monica/form.inc.php:3865 +msgid "Tel. (office):" +msgstr "电话(公):" + +#: lib/php/monica/form.inc.php:3871 +msgid "Title:" +msgstr "标题:" + +#: lib/php/monica/form.inc.php:3891 +msgid "Value:" +msgstr "值:" + +#: lib/php/monica/form.inc.php:3897 +msgid "Visits:" +msgstr "上站次数:" + +#: lib/php/monica/form.inc.php:3903 +msgid "Visited:" +msgstr "上站日期:" + +#: lib/php/monica/form.inc.php:3909 +msgid "Updated:" +msgstr "维护日期:" + +#: lib/php/monica/form.inc.php:3915 +msgid "Updated by:" +msgstr "维护者:" + +#: lib/php/monica/form.inc.php:3921 +msgid "URL.:" +msgstr "网址:" + +#: lib/php/monica/form.inc.php:3927 +msgid "Zip code:" +msgstr "邮递区号:" + +#: lib/php/monica/form.inc.php:4151 +msgid "Delete this user account" +msgstr "删掉帐号" + +#: lib/php/monica/form.inc.php:4157 +msgid "This table provides you a form to add a new user account." +msgstr "本表提供建新帐号的表单。" + +#: lib/php/monica/form.inc.php:4161 +msgid "This table provides you a form to update a current user account." +msgstr "本表提供设置帐号的表单。" + +#: lib/php/monica/form.inc.php:4165 +msgid "This table provides you a form to delete a user account." +msgstr "本表提供删除帐号的表单。" + +#: lib/php/monica/form.inc.php:4192 +msgid "Add a New User Account" +msgstr "建新帐号" + +#: lib/php/monica/form.inc.php:4196 +msgid "Update a Current User Account" +msgstr "设置帐号" + +#: lib/php/monica/form.inc.php:4200 +msgid "Delete a User Account" +msgstr "删除帐号" + +#: lib/php/monica/form.inc.php:4213 +msgid "This is a super-user. You can only change parts of her infomation." +msgstr "这个人是总管理员,你只能设置她部份的数据。" + +#: lib/php/monica/form.inc.php:4220 +msgid "" +"This user has a datum. It cannot be deleted. To delete the user, its datum " +"must first be deleted." +msgid_plural "" +"This user has data. It cannot be deleted. To delete the user, all of its " +"data must first be deleted." +msgstr[0] "本帐号下有数据,不可直接删除。要删除帐号,请先删除其下的数据。" + +#: lib/php/monica/form.inc.php:4282 +msgid "Administrator?" +msgstr "网站管理员?" + +#: lib/php/monica/form.inc.php:4283 +msgid "Administrator" +msgstr "网站管理员" + +#: lib/php/monica/form.inc.php:4283 +msgid "Non-administrator" +msgstr "普通用户" + +#: lib/php/monica/form.inc.php:4296 +msgid "Disable this user account." +msgstr "帐号停用。" + +#: lib/php/monica/form.inc.php:4305 lib/php/monica/form.inc.php:4307 +#: lib/php/monica/form.inc.php:6372 +msgid "User ID.:" +msgstr "用户代号:" + +#: lib/php/monica/form.inc.php:4314 +msgid "Pref. language:" +msgstr "语言偏好:" + +#: lib/php/monica/form.inc.php:4320 +msgid "Full name:" +msgstr "姓名:" + +#: lib/php/monica/form.inc.php:4348 lib/php/monica/form.inc.php:4400 +#: lib/php/monica/form.inc.php:4422 lib/php/monica/form.inc.php:4496 +#: lib/php/monica/form.inc.php:4962 lib/php/monica/form.inc.php:5001 +#: lib/php/monica/form.inc.php:5017 lib/php/monica/form.inc.php:5069 +msgid "Belonging to:" +msgstr "隶属群组:" + +#: lib/php/monica/form.inc.php:4539 lib/php/monica/form.inc.php:4547 +#: lib/php/monica/form.inc.php:4574 +msgid "Fail logins:" +msgstr "登录失败:" + +#: lib/php/monica/form.inc.php:4551 lib/php/monica/form.inc.php:4578 +msgid "(Locked)" +msgstr "(锁住)" + +#: lib/php/monica/form.inc.php:4557 +msgid "Reset the counter and activate the account" +msgstr "归零并重启帐号。" + +#: lib/php/monica/form.inc.php:4603 +msgid "Delete this group" +msgstr "删掉群组" + +#: lib/php/monica/form.inc.php:4609 +msgid "This table provides you a form to add a new group." +msgstr "本表提供建新群组的表单。" + +#: lib/php/monica/form.inc.php:4613 +msgid "This table provides you a form to update a current group." +msgstr "本表提供设置群组的表单。" + +#: lib/php/monica/form.inc.php:4617 +msgid "This table provides you a form to delete a group." +msgstr "本表提供删除群组的表单。" + +#: lib/php/monica/form.inc.php:4642 +msgid "Add a New Group" +msgstr "建新群组" + +#: lib/php/monica/form.inc.php:4646 +msgid "Update a Current Group" +msgstr "设置群组" + +#: lib/php/monica/form.inc.php:4650 +msgid "Delete a Group" +msgstr "删除群组" + +#: lib/php/monica/form.inc.php:4657 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "这是最高管理员的群组,你只能设置它部份的数据。" + +#: lib/php/monica/form.inc.php:4666 lib/php/monica/form.inc.php:4668 +msgid "Group ID.:" +msgstr "群组代号:" + +#: lib/php/monica/form.inc.php:4681 +msgid "Add a user" +msgstr "增加成员" + +#: lib/php/monica/form.inc.php:4688 lib/php/monica/form.inc.php:4728 +#: lib/php/monica/form.inc.php:4746 lib/php/monica/form.inc.php:4799 +msgid "User member:" +msgid_plural "User members:" +msgstr[0] "用户成员:" + +#: lib/php/monica/form.inc.php:4819 lib/php/monica/form.inc.php:4956 +msgid "Add a group" +msgstr "增加群组" + +#: lib/php/monica/form.inc.php:4826 lib/php/monica/form.inc.php:4866 +#: lib/php/monica/form.inc.php:4883 lib/php/monica/form.inc.php:4936 +msgid "Group member:" +msgid_plural "Group members:" +msgstr[0] "群组成员:" + +#: lib/php/monica/form.inc.php:5103 lib/php/monica/form.inc.php:5178 +msgid "Delete this membership record" +msgstr "删掉这笔成员关系" + +#: lib/php/monica/form.inc.php:5109 lib/php/monica/form.inc.php:5184 +msgid "This table provides you a form to add a new membership record." +msgstr "本表提供建新成员关系的表单。" + +#: lib/php/monica/form.inc.php:5113 lib/php/monica/form.inc.php:5188 +msgid "This table provides you a form to change a current membership record." +msgstr "本表提供变更成员关系的表单。" + +#: lib/php/monica/form.inc.php:5117 lib/php/monica/form.inc.php:5192 +msgid "This table provides you a form to delete a membership record." +msgstr "本表提供删除成员关系的表单。" + +#: lib/php/monica/form.inc.php:5140 +msgid "Add a New User Membership Record" +msgstr "建新用户成员关系" + +#: lib/php/monica/form.inc.php:5144 +msgid "Change a Current User Membership Record" +msgstr "变更用户成员关系" + +#: lib/php/monica/form.inc.php:5148 +msgid "Delete a User Membership Record" +msgstr "删除用户成员关系" + +#: lib/php/monica/form.inc.php:5158 lib/php/monica/form.inc.php:5233 +msgid "Member:" +msgstr "成员:" + +#: lib/php/monica/form.inc.php:5215 +msgid "Add a New Group Membership Record" +msgstr "建新群组成员关系" + +#: lib/php/monica/form.inc.php:5219 +msgid "Change a Current Group Membership Record" +msgstr "变更群组成员关系" + +#: lib/php/monica/form.inc.php:5223 +msgid "Delete a Group Membership Record" +msgstr "删除群组成员关系" + +#: lib/php/monica/form.inc.php:5253 +msgid "Delete this user preference" +msgstr "删掉这笔用户偏好" + +#: lib/php/monica/form.inc.php:5259 +msgid "This table provides you a form to add a new user preference." +msgstr "本表提供建新用户偏好的表单。" + +#: lib/php/monica/form.inc.php:5263 +msgid "This table provides you a form to modify a current user preference." +msgstr "本表提供修改用户偏好的表单。" + +#: lib/php/monica/form.inc.php:5267 +msgid "This table provides you a form to delete a user preference." +msgstr "本表提供删除用户偏好的表单。" + +#: lib/php/monica/form.inc.php:5290 +msgid "Add a New User Preference" +msgstr "建新用户偏好" + +#: lib/php/monica/form.inc.php:5294 +msgid "Modify a Current User Preference" +msgstr "修改用户偏好" + +#: lib/php/monica/form.inc.php:5298 +msgid "Delete a User Preference" +msgstr "删除用户偏好" + +#: lib/php/monica/form.inc.php:5308 lib/php/monica/form.inc.php:5494 +msgid "User:" +msgstr "用户:" + +#: lib/php/monica/form.inc.php:5309 lib/php/monica/list.inc.php:2588 +msgid "Everyone" +msgstr "所有人" + +#: lib/php/monica/form.inc.php:5315 +msgid "Domain:" +msgstr "适用范围:" + +#: lib/php/monica/form.inc.php:5316 lib/php/monica/list.inc.php:2592 +msgid "Everywhere" +msgstr "所有地方" + +#: lib/php/monica/form.inc.php:5336 +msgid "Delete this script privilege record" +msgstr "删掉这笔程序权限数据" + +#: lib/php/monica/form.inc.php:5342 +msgid "This table provides you a form to add a new script privilege record." +msgstr "本表提供建新程序权限数据的表单。" + +#: lib/php/monica/form.inc.php:5346 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "本表提供变更程序权限数据的表单。" + +#: lib/php/monica/form.inc.php:5350 +msgid "This table provides you a form to delete a script privilege record." +msgstr "本表提供删除程序权限数据的表单。" + +#: lib/php/monica/form.inc.php:5373 +msgid "Add a New Script Privilege Record" +msgstr "建新程序权限数据" + +#: lib/php/monica/form.inc.php:5377 +msgid "Change a Current Script Privilege Record" +msgstr "变更程序权限数据" + +#: lib/php/monica/form.inc.php:5381 +msgid "Delete a Script Privilege Record" +msgstr "删除程序权限数据" + +#: lib/php/monica/form.inc.php:5391 +msgid "Privilege:" +msgstr "权限:" + +#: lib/php/monica/form.inc.php:5413 +msgid "Delete this user request" +msgstr "删掉这笔用户申请" + +#: lib/php/monica/form.inc.php:5419 +msgid "This table provides you a form to add a new user request." +msgstr "本表提供建新用户申请的表单。" + +#: lib/php/monica/form.inc.php:5423 +msgid "This table provides you a form to update a current user request." +msgstr "本表提供更新用户申请的表单。" + +#: lib/php/monica/form.inc.php:5427 +msgid "This table provides you a form to delete a user request." +msgstr "本表提供删除用户申请的表单。" + +#: lib/php/monica/form.inc.php:5450 +msgid "Add a New User Request" +msgstr "建新用户申请" + +#: lib/php/monica/form.inc.php:5454 +msgid "Update a Current User Request" +msgstr "更新用户申请" + +#: lib/php/monica/form.inc.php:5458 +msgid "Delete a User Request" +msgstr "删除用户申请" + +#: lib/php/monica/form.inc.php:5466 +msgid "Join" +msgstr "加入" + +#: lib/php/monica/form.inc.php:5470 +msgid "Change e-mail" +msgstr "变更 E-mail" + +#: lib/php/monica/form.inc.php:5474 +msgid "Reset password" +msgstr "重设密码" + +#: lib/php/monica/form.inc.php:5482 +msgid "Expiration:" +msgstr "到期日:" + +#: lib/php/monica/form.inc.php:5488 lib/php/monica/form.inc.php:6450 +msgid "Type:" +msgstr "类型:" + +#: lib/php/monica/form.inc.php:5495 +msgid "Anonymous" +msgstr "未具名" + +#: lib/php/monica/form.inc.php:5501 +msgid "Arguments:" +msgstr "备注数据:" + +#: lib/php/monica/form.inc.php:5519 +msgid "Delete this category" +msgstr "删掉这个分类" + +#: lib/php/monica/form.inc.php:5525 +msgid "This table provides you a form to add a new category." +msgstr "本表提供建新分类的表单。" + +#: lib/php/monica/form.inc.php:5529 +msgid "This table provides you a form to edit a current category." +msgstr "本表提供编辑分类的表单。" + +#: lib/php/monica/form.inc.php:5533 +msgid "This table provides you a form to delete a category." +msgstr "本表提供删除分类的表单。" + +#: lib/php/monica/form.inc.php:5543 +msgid "" +"This category has a subcategory. It cannot be deleted. To delete the " +"category, its subcategory must first be deleted." +msgid_plural "" +"This category has subcategories. It cannot be deleted. To delete the " +"category, all of its subcategories must first be deleted." +msgstr[0] "本分类下有子类,不可直接删除。要删除本分类,请先删除其下的子类。" + +#: lib/php/monica/form.inc.php:5560 +msgid "Hide this category" +msgstr "隐藏本类" + +#: lib/php/monica/form.inc.php:5560 +msgid "Show this category" +msgstr "秀出本类" + +#: lib/php/monica/form.inc.php:5560 +msgid "Hide this category currently." +msgstr "暂勿秀出本类。" + +#: lib/php/monica/form.inc.php:5577 +msgid "Delete this categorization record" +msgstr "删掉这笔分类数据" + +#: lib/php/monica/form.inc.php:5583 +msgid "This table provides you a form to add a new categorization record." +msgstr "本表提供建新分类数据的表单。" + +#: lib/php/monica/form.inc.php:5587 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "本表提供变更分类数据的表单。" + +#: lib/php/monica/form.inc.php:5591 +msgid "This table provides you a form to delete a categorization record." +msgstr "本表提供删除分类数据的表单。" + +#: lib/php/monica/form.inc.php:5636 +msgid "Add a New Link Category" +msgstr "建新链接分类" + +#: lib/php/monica/form.inc.php:5640 +msgid "Edit a Current Link Category" +msgstr "编辑链接分类" + +#: lib/php/monica/form.inc.php:5644 +msgid "Delete a Link Category" +msgstr "删除链接分类" + +#: lib/php/monica/form.inc.php:5654 +msgid "" +"This category has a link. It cannot be deleted. To delete the category, " +"its link must first be deleted." +msgid_plural "" +"This category has links. It cannot be deleted. To delete the category, all " +"of its links must first be deleted." +msgstr[0] "本分类下有链接,不可直接删除。要删除本分类,请先删除其下的链接。" + +#: lib/php/monica/form.inc.php:5673 lib/php/monica/form.inc.php:5837 +msgid "Link:" +msgid_plural "Links:" +msgstr[0] "链接:" + +#: lib/php/monica/form.inc.php:5710 +msgid "Delete this related link" +msgstr "删掉这笔相关链接" + +#: lib/php/monica/form.inc.php:5716 +msgid "This table provides you a form to add a new related link." +msgstr "本表提供建新相关链接的表单。" + +#: lib/php/monica/form.inc.php:5720 +msgid "This table provides you a form to edit a current related link." +msgstr "本表提供编辑相关链接的表单。" + +#: lib/php/monica/form.inc.php:5724 +msgid "This table provides you a form to delete a related link." +msgstr "本表提供删除相关链接的表单。" + +#: lib/php/monica/form.inc.php:5747 +msgid "Add a New Related Link" +msgstr "建新相关链接" + +#: lib/php/monica/form.inc.php:5751 +msgid "Edit a Current Related Link" +msgstr "编辑相关链接" + +#: lib/php/monica/form.inc.php:5755 +msgid "Delete a Related Link" +msgstr "删除相关链接" + +#: lib/php/monica/form.inc.php:5766 +msgid "Hide this link" +msgstr "隐藏本链接" + +#: lib/php/monica/form.inc.php:5766 lib/php/monica/form.inc.php:5924 +msgid "Show this page" +msgstr "秀出本页" + +#: lib/php/monica/form.inc.php:5766 +msgid "Hide this related link currently." +msgstr "暂勿秀出本相关链接。" + +#: lib/php/monica/form.inc.php:5773 lib/php/monica/form.inc.php:5830 +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "分类:" + +#: lib/php/monica/form.inc.php:5812 +msgid "Add a New Link Categorization Record" +msgstr "建新链接分类数据" + +#: lib/php/monica/form.inc.php:5816 +msgid "Change a Current Link Categorization Record" +msgstr "变更链接分类数据" + +#: lib/php/monica/form.inc.php:5820 +msgid "Delete a Link Categorization Record" +msgstr "删除链接分类数据" + +#: lib/php/monica/form.inc.php:5860 +msgid "Delete this page" +msgstr "删掉这一页" + +#: lib/php/monica/form.inc.php:5866 +msgid "This table provides you a form to write a new page." +msgstr "本表提供撰写网页的表单。" + +#: lib/php/monica/form.inc.php:5870 +msgid "This table provides you a form to edit a current page." +msgstr "本表提供编辑网页的表单。" + +#: lib/php/monica/form.inc.php:5874 +msgid "This table provides you a form to delete a page." +msgstr "本表提供删除网页的表单。" + +#: lib/php/monica/form.inc.php:5899 +msgid "Write a New Page" +msgstr "撰写网页" + +#: lib/php/monica/form.inc.php:5903 +msgid "Edit a Current Page" +msgstr "编辑网页" + +#: lib/php/monica/form.inc.php:5907 +msgid "Delete a Page" +msgstr "删除网页" + +#: lib/php/monica/form.inc.php:5915 +msgid "Preview this page." +msgstr "预览本页。" + +#: lib/php/monica/form.inc.php:5924 +msgid "Hide this page" +msgstr "隐藏本页" + +#: lib/php/monica/form.inc.php:5924 +msgid "Hide this page currently." +msgstr "暂勿秀出本页。" + +#: lib/php/monica/form.inc.php:5947 +msgid "Delete this news article" +msgstr "删掉这则新闻" + +#: lib/php/monica/form.inc.php:5953 +msgid "This table provides you a form to write a new news article." +msgstr "本表提供撰写新闻的表单。" + +#: lib/php/monica/form.inc.php:5957 +msgid "This table provides you a form to edit a current news article." +msgstr "本表提供编辑新闻的表单。" + +#: lib/php/monica/form.inc.php:5961 +msgid "This table provides you a form to delete a news article." +msgstr "本表提供删除新闻的表单。" + +#: lib/php/monica/form.inc.php:5986 +msgid "Write a New News Article" +msgstr "撰写新闻" + +#: lib/php/monica/form.inc.php:5990 +msgid "Edit a Current News Article" +msgstr "编辑新闻" + +#: lib/php/monica/form.inc.php:5994 +msgid "Delete a News Article" +msgstr "删除新闻" + +#: lib/php/monica/form.inc.php:6002 +msgid "Preview this news article." +msgstr "预览这则新闻。" + +#: lib/php/monica/form.inc.php:6017 +msgid "Hide this news article" +msgstr "隐藏这则新闻" + +#: lib/php/monica/form.inc.php:6017 +msgid "Show this news article" +msgstr "秀出这则新闻" + +#: lib/php/monica/form.inc.php:6017 +msgid "Hide this news article currently." +msgstr "暂勿秀出这则新闻。" + +#: lib/php/monica/form.inc.php:6037 +msgid "Delete this country record" +msgstr "删掉这笔国家数据" + +#: lib/php/monica/form.inc.php:6043 +msgid "This table provides you a form to add a new country record." +msgstr "本表提供建新国家数据的表单。" + +#: lib/php/monica/form.inc.php:6047 +msgid "This table provides you a form to edit a current country record." +msgstr "本表提供编辑国家数据的表单。" + +#: lib/php/monica/form.inc.php:6051 +msgid "This table provides you a form to delete a country record." +msgstr "本表提供删除国家数据的表单。" + +#: lib/php/monica/form.inc.php:6074 +msgid "Add a New Country Record" +msgstr "建新国家数据" + +#: lib/php/monica/form.inc.php:6078 +msgid "Edit a Current Country Record" +msgstr "编辑国家数据" + +#: lib/php/monica/form.inc.php:6082 +msgid "Delete a Country Record" +msgstr "删除国家数据" + +#: lib/php/monica/form.inc.php:6098 lib/php/monica/list.inc.php:3391 +msgid "Special?" +msgstr "特殊?" + +#: lib/php/monica/form.inc.php:6099 +msgid "A special record" +msgstr "特殊记录" + +#: lib/php/monica/form.inc.php:6099 +msgid "A normal country" +msgstr "一般国家" + +#: lib/php/monica/form.inc.php:6099 +msgid "This is a special record." +msgstr "这一笔是特殊记录。" + +#: lib/php/monica/form.inc.php:6128 +msgid "This table provides you a form to add a new picture." +msgstr "本表提供建新图片的表单。" + +#: lib/php/monica/form.inc.php:6132 +msgid "This table provides you a form to modify a current picture." +msgstr "本表提供修改图片的表单。" + +#: lib/php/monica/form.inc.php:6143 +msgid "Upload a New Picture" +msgstr "建新图片" + +#: lib/php/monica/form.inc.php:6147 +msgid "Modify a Current Picture" +msgstr "修改图片" + +#: lib/php/monica/form.inc.php:6248 lib/php/monica/form.inc.php:6260 +msgid "Ratio:" +msgstr "比例:" + +#: lib/php/monica/form.inc.php:6285 lib/php/monica/form.inc.php:6295 +msgid "Upload:" +msgstr "上传:" + +#: lib/php/monica/form.inc.php:6326 +msgid "This table provides you a form to log in." +msgstr "本表提供登录的表单。" + +#: lib/php/monica/form.inc.php:6332 +msgid "Identify Yourself" +msgstr "请出示身份" + +#: lib/php/monica/form.inc.php:6341 lib/php/monica/init.inc.php:505 +msgid "" +"Log-in is temporarily closed for maintainance now. Please come again " +"later. Sorry for the inconvienence." +msgstr "网站维护中,暂请勿入。造成任何不便,敬请见谅。" + +#: lib/php/monica/form.inc.php:6350 +msgid "Log in" +msgstr "登录" + +#: lib/php/monica/form.inc.php:6397 +msgid "Remember me." +msgstr "勿忘我。" + +#: lib/php/monica/form.inc.php:6424 +msgid "Rebuild the Pages" +msgstr "重制网页" + +#: lib/php/monica/form.inc.php:6433 +msgid "Confirm" +msgstr "确认" + +#: lib/php/monica/form.inc.php:6475 +msgid "Log Out" +msgstr "注销" + +#: lib/php/monica/form.inc.php:6484 +msgid "Log out" +msgstr "注销" + +#: lib/php/monica/form.inc.php:6498 +msgid "Are you sure you want to log out?" +msgstr "你确定要注销吗?" + +#: lib/php/monica/init.inc.php:114 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" +"抱歉,我们不欢迎加装 FunWebProduct 插件(如 Smiley Central 、 PopSwatter 、 " +"Spin4Dough 、 My Mail Signature 、 My Mail Stationery 、 My Mail Stamp 、 " +"Cursor Mania ……等等)的浏览器。 FunWebProduct 会重抓你看过的每一页网页,造" +"成网站负荷加倍,甚至当机。请先移除 FunWebProduct ,再上来浏览。" + +#: lib/php/monica/init.inc.php:503 lib/php/monica/init.inc.php:504 +msgid "Log-In Closed" +msgstr "暂请勿入" + +#: lib/php/monica/init.inc.php:524 lib/php/monica/init.inc.php:525 +msgid "Development Site Closed" +msgstr "研发网站已关闭" + +#: lib/php/monica/init.inc.php:526 +msgid "Development site is closed. Please work on the live site." +msgstr "研发网站已关闭,请勿在此登录。" + +#: lib/php/monica/links.inc.php:271 +msgid "Related Links" +msgstr "相关链接" + +#: lib/php/monica/list.inc.php:130 +msgid "Malformed" +msgstr "格式错乱" + +#: lib/php/monica/list.inc.php:155 +msgid "OK" +msgstr "好" + +#: lib/php/monica/list.inc.php:155 +msgid "Unreachable" +msgstr "连不上" + +#: lib/php/monica/list.inc.php:290 lib/php/monica/list.inc.php:1534 +#: lib/php/monica/list.inc.php:3642 +msgid "(query phrase)" +msgstr "(检索字词)" + +#: lib/php/monica/list.inc.php:300 +msgid "S/N" +msgstr "编号" + +#: lib/php/monica/list.inc.php:301 +msgid "Created" +msgstr "建档日期" + +#: lib/php/monica/list.inc.php:302 +msgid "Created by" +msgstr "建档者" + +#: lib/php/monica/list.inc.php:303 +msgid "Updated" +msgstr "维护日期" + +#: lib/php/monica/list.inc.php:304 +msgid "Updated by" +msgstr "维护者" + +#: lib/php/monica/list.inc.php:306 +msgid "Content" +msgstr "内文" + +#: lib/php/monica/list.inc.php:307 +msgid "Category" +msgstr "分类" + +#: lib/php/monica/list.inc.php:308 +msgid "Coverage" +msgstr "涵盖范围" + +#: lib/php/monica/list.inc.php:309 +msgid "Date" +msgstr "日期" + +#: lib/php/monica/list.inc.php:311 +msgid "Description" +msgstr "说明" + +#: lib/php/monica/list.inc.php:312 +msgid "E-mail" +msgstr "E-mail" + +#: lib/php/monica/list.inc.php:313 +msgid "Hidden?" +msgstr "隐藏?" + +#: lib/php/monica/list.inc.php:315 +msgid "ID." +msgstr "代号" + +#: lib/php/monica/list.inc.php:316 +msgid "Keywords" +msgstr "关键字" + +#: lib/php/monica/list.inc.php:317 +msgid "Name" +msgstr "名称" + +#: lib/php/monica/list.inc.php:318 +msgid "Order" +msgstr "次序" + +#: lib/php/monica/list.inc.php:319 +msgid "Page path" +msgstr "网页路径" + +#: lib/php/monica/list.inc.php:320 +msgid "Picture" +msgstr "图片" + +#: lib/php/monica/list.inc.php:321 +msgid "Pic. ratio" +msgstr "图片比例" + +#: lib/php/monica/list.inc.php:322 +msgid "Pic. caption" +msgstr "图片标题" + +#: lib/php/monica/list.inc.php:323 +msgid "Pic. position" +msgstr "图片位置" + +#: lib/php/monica/list.inc.php:324 +msgid "Subject" +msgstr "主题" + +#: lib/php/monica/list.inc.php:325 +msgid "Title" +msgstr "标题" + +#: lib/php/monica/list.inc.php:326 +msgid "URL." +msgstr "网址" + +#: lib/php/monica/list.inc.php:327 +msgid "Status (slow)" +msgstr "状态(慢)" + +#: lib/php/monica/list.inc.php:336 +msgid "Select" +msgstr "选择" + +#: lib/php/monica/list.inc.php:339 +msgid "Select a Data Record" +msgstr "选择数据" + +#: lib/php/monica/list.inc.php:343 +msgid "Edit" +msgstr "设置" + +#: lib/php/monica/list.inc.php:345 +msgid "Manage Data" +msgstr "管理数据" + +#: lib/php/monica/list.inc.php:749 +msgid "Nothing found. Please try another query." +msgstr "查无相符的数据,请重新搜索。" + +#: lib/php/monica/list.inc.php:752 +msgid "The database is empty." +msgstr "现无任何数据。" + +#: lib/php/monica/list.inc.php:759 +#, c-format +msgid "Your query found %s record." +msgid_plural "Your query found %s records." +msgstr[0] "共 %s 笔相符的数据。" + +#: lib/php/monica/list.inc.php:766 +#, c-format +msgid "%s record." +msgid_plural "%s records." +msgstr[0] "共 %s 笔数据。" + +#: lib/php/monica/list.inc.php:775 +#, c-format +msgid "Your query found %s record, listing %s to %s." +msgid_plural "Your query found %s records, listing %s to %s." +msgstr[0] "共 %s 笔相符的数据,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:784 +#, c-format +msgid "%s record, listing %s to %s." +msgid_plural "%s records, listing %s to %s." +msgstr[0] "共 %s 笔数据,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:855 lib/php/monica/list.inc.php:860 +#: lib/php/monica/list.inc.php:869 +#, c-format +msgid "Page number (%s) invalid. Please specify a valid page number." +msgstr "页数( %s )无效,请设成有效的数字。" + +#: lib/php/monica/list.inc.php:874 +#, c-format +msgid "" +"Page number (%d) out of range. Please specify a number between 1 and %d." +msgstr "页数( %d )超出范围,请设在 1 到 %d 之间。" + +#: lib/php/monica/list.inc.php:1138 lib/php/monica/list.inc.php:1151 +#, c-format +msgid "You cannot sort by \"%s\"." +msgstr "无法以 %s 排序。" + +#: lib/php/monica/list.inc.php:1512 +msgid "Search" +msgstr "搜索" + +#: lib/php/monica/list.inc.php:1610 +msgid "Index" +msgstr "目录" + +#: lib/php/monica/list.inc.php:1634 +msgid "First" +msgstr "第一页" + +#: lib/php/monica/list.inc.php:1647 +msgid "Previous" +msgstr "前一页" + +#: lib/php/monica/list.inc.php:1696 +msgid "Next" +msgstr "下一页" + +#: lib/php/monica/list.inc.php:1714 +msgid "Last" +msgstr "最末页" + +#: lib/php/monica/list.inc.php:1736 +msgid "Page:" +msgstr "页:" + +#: lib/php/monica/list.inc.php:1776 lib/php/monica/list.inc.php:1900 +msgid "Delete the selected items." +msgstr "删除勾选的项目。" + +#: lib/php/monica/list.inc.php:1805 +msgid "No." +msgstr "编号" + +#: lib/php/monica/list.inc.php:1813 lib/php/monica/list.inc.php:1873 +msgid "View" +msgstr "浏览" + +#: lib/php/monica/list.inc.php:1925 +msgid "Set" +msgstr "设置" + +#: lib/php/monica/list.inc.php:1941 +msgid "Rows per page:" +msgstr "每页显示笔数:" + +#: lib/php/monica/list.inc.php:1946 +msgid "Display columns:" +msgstr "显示字段:" + +#: lib/php/monica/list.inc.php:1976 +msgid "Select a User" +msgstr "选择帐号" + +#: lib/php/monica/list.inc.php:1977 +msgid "Manage Users" +msgstr "管理帐号" + +#: lib/php/monica/list.inc.php:1982 +msgid "User ID." +msgstr "用户代号" + +#: lib/php/monica/list.inc.php:1983 +msgid "Full name" +msgstr "姓名" + +#: lib/php/monica/list.inc.php:1984 +msgid "Deleted?" +msgstr "已删?" + +#: lib/php/monica/list.inc.php:1985 +msgid "Pref. language" +msgstr "语言偏好" + +#: lib/php/monica/list.inc.php:1986 +msgid "Visits" +msgstr "上站次数" + +#: lib/php/monica/list.inc.php:1987 +msgid "Visited" +msgstr "上站日期" + +#: lib/php/monica/list.inc.php:1988 +msgid "IP" +msgstr "IP" + +#: lib/php/monica/list.inc.php:1989 +msgid "Host" +msgstr "主机" + +#: lib/php/monica/list.inc.php:1990 +msgid "From country" +msgstr "上站国家" + +#: lib/php/monica/list.inc.php:1991 +msgid "Fail logins" +msgstr "登录失败" + +#: lib/php/monica/list.inc.php:2024 +msgid "Deleted" +msgstr "已删" + +#: lib/php/monica/list.inc.php:2035 +msgid "Add a new user account." +msgstr "建新帐号。" + +#: lib/php/monica/list.inc.php:2045 +msgid "Search for a user:" +msgstr "搜索用户:" + +#: lib/php/monica/list.inc.php:2063 +#, c-format +msgid "Your query found %s user." +msgid_plural "Your query found %s users." +msgstr[0] "共 %s 个相符的用户。" + +#: lib/php/monica/list.inc.php:2070 +#, c-format +msgid "%s user." +msgid_plural "%s users." +msgstr[0] "共 %s 个用户。" + +#: lib/php/monica/list.inc.php:2079 +#, c-format +msgid "Your query found %s user, listing %s to %s." +msgid_plural "Your query found %s users, listing %s to %s." +msgstr[0] "共 %s 个相符的用户,列出第 %s 个到第 %s 个。" + +#: lib/php/monica/list.inc.php:2088 +#, c-format +msgid "%s user, listing %s to %s." +msgid_plural "%s users, listing %s to %s." +msgstr[0] "共 %s 个用户,列出第 %s 个到第 %s 个。" + +#: lib/php/monica/list.inc.php:2107 +msgid "Select a Group" +msgstr "选择群组" + +#: lib/php/monica/list.inc.php:2108 +msgid "Manage Groups" +msgstr "管理群组" + +#: lib/php/monica/list.inc.php:2113 +msgid "Group ID." +msgstr "群组代号" + +#: lib/php/monica/list.inc.php:2121 +msgid "Add a new group." +msgstr "建新群组。" + +#: lib/php/monica/list.inc.php:2131 +msgid "Search for a group:" +msgstr "搜索群组:" + +#: lib/php/monica/list.inc.php:2149 +#, c-format +msgid "Your query found %s group." +msgid_plural "Your query found %s groups." +msgstr[0] "共 %s 个相符的群组。" + +#: lib/php/monica/list.inc.php:2156 +#, c-format +msgid "%s group." +msgid_plural "%s groups." +msgstr[0] "共 %s 个群组。" + +#: lib/php/monica/list.inc.php:2165 +#, c-format +msgid "Your query found %s group, listing %s to %s." +msgid_plural "Your query found %s groups, listing %s to %s." +msgstr[0] "共 %s 个相符的群组,列出第 %s 个到第 %s 个。" + +#: lib/php/monica/list.inc.php:2174 +#, c-format +msgid "%s group, listing %s to %s." +msgid_plural "%s groups, listing %s to %s." +msgstr[0] "共 %s 个群组,列出第 %s 个到第 %s 个。" + +#: lib/php/monica/list.inc.php:2194 +msgid "Select a User Membership Record" +msgstr "选择用户成员关系" + +#: lib/php/monica/list.inc.php:2195 +msgid "Manage User Membership" +msgstr "管理用户成员关系" + +#: lib/php/monica/list.inc.php:2200 lib/php/monica/list.inc.php:2323 +msgid "Group" +msgstr "群组" + +#: lib/php/monica/list.inc.php:2201 lib/php/monica/list.inc.php:2324 +msgid "Member" +msgstr "成员" + +#: lib/php/monica/list.inc.php:2244 lib/php/monica/list.inc.php:2375 +msgid "Add a new membership record." +msgstr "建新成员关系。" + +#: lib/php/monica/list.inc.php:2254 lib/php/monica/list.inc.php:2385 +msgid "Search for a membership record:" +msgstr "搜索成员关系:" + +#: lib/php/monica/list.inc.php:2272 lib/php/monica/list.inc.php:2403 +#, c-format +msgid "Your query found %s membership record." +msgid_plural "Your query found %s membership records." +msgstr[0] "共 %s 笔相符的成员关系。" + +#: lib/php/monica/list.inc.php:2279 lib/php/monica/list.inc.php:2410 +#, c-format +msgid "%s membership record." +msgid_plural "%s membership records." +msgstr[0] "共 %s 笔成员关系。" + +#: lib/php/monica/list.inc.php:2288 lib/php/monica/list.inc.php:2419 +#, c-format +msgid "Your query found %s membership record, listing %s to %s." +msgid_plural "Your query found %s membership records, listing %s to %s." +msgstr[0] "共 %s 笔相符的成员关系,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2297 lib/php/monica/list.inc.php:2428 +#, c-format +msgid "%s membership record, listing %s to %s." +msgid_plural "%s membership records, listing %s to %s." +msgstr[0] "共 %s 笔成员关系,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2317 +msgid "Select a Group Membership Record" +msgstr "选择群组成员关系" + +#: lib/php/monica/list.inc.php:2318 +msgid "Manage Group Membership" +msgstr "管理群组成员关系" + +#: lib/php/monica/list.inc.php:2448 +msgid "Select a Script Privilege Record" +msgstr "选择程序权限" + +#: lib/php/monica/list.inc.php:2449 +msgid "Manage Script Privileges" +msgstr "管理程序权限" + +#: lib/php/monica/list.inc.php:2454 +msgid "Script" +msgstr "程序" + +#: lib/php/monica/list.inc.php:2455 +msgid "Privilege" +msgstr "权限" + +#: lib/php/monica/list.inc.php:2493 +msgid "Add a new script privilege record." +msgstr "建新程序权限数据。" + +#: lib/php/monica/list.inc.php:2503 +msgid "Search for a script privilege record:" +msgstr "搜索程序权限:" + +#: lib/php/monica/list.inc.php:2521 +#, c-format +msgid "Your query found %s script privilege record." +msgid_plural "Your query found %s script privilege records." +msgstr[0] "共 %s 笔相符的程序权限。" + +#: lib/php/monica/list.inc.php:2528 +#, c-format +msgid "%s script privilege record." +msgid_plural "%s script privilege records." +msgstr[0] "共 %s 笔程序权限。" + +#: lib/php/monica/list.inc.php:2537 +#, c-format +msgid "Your query found %s script privilege record, listing %s to %s." +msgid_plural "Your query found %s script privilege records, listing %s to %s." +msgstr[0] "共 %s 笔相符的程序权限,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2546 +#, c-format +msgid "%s script privilege record, listing %s to %s." +msgid_plural "%s script privilege records, listing %s to %s." +msgstr[0] "共 %s 笔程序权限,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2566 +msgid "Select a User Preference" +msgstr "选择用户偏好" + +#: lib/php/monica/list.inc.php:2567 +msgid "Manage User Preferences" +msgstr "管理用户偏好" + +#: lib/php/monica/list.inc.php:2574 lib/php/monica/list.inc.php:2689 +msgid "User" +msgstr "用户" + +#: lib/php/monica/list.inc.php:2575 +msgid "Domain" +msgstr "适用范围" + +#: lib/php/monica/list.inc.php:2576 +msgid "Value" +msgstr "值" + +#: lib/php/monica/list.inc.php:2610 +msgid "Add a new user preference." +msgstr "建新用户偏好。" + +#: lib/php/monica/list.inc.php:2620 +msgid "Search for a user preference:" +msgstr "搜索用户偏好:" + +#: lib/php/monica/list.inc.php:2638 +#, c-format +msgid "Your query found %s user preference." +msgid_plural "Your query found %s user preferences." +msgstr[0] "共 %s 笔相符的用户偏好。" + +#: lib/php/monica/list.inc.php:2645 +#, c-format +msgid "%s user preference." +msgid_plural "%s user preferences." +msgstr[0] "共 %s 笔用户偏好。" + +#: lib/php/monica/list.inc.php:2654 +#, c-format +msgid "Your query found %s user preference, listing %s to %s." +msgid_plural "Your query found %s user preferences, listing %s to %s." +msgstr[0] "共 %s 笔相符的用户偏好,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2663 +#, c-format +msgid "%s user preference, listing %s to %s." +msgid_plural "%s user preferences, listing %s to %s." +msgstr[0] "共 %s 笔用户偏好,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2682 +msgid "Select a User Request" +msgstr "选择用户申请" + +#: lib/php/monica/list.inc.php:2683 +msgid "Manage User Requests" +msgstr "管理用户申请" + +#: lib/php/monica/list.inc.php:2688 +msgid "Type" +msgstr "类别" + +#: lib/php/monica/list.inc.php:2690 +msgid "Arguments" +msgstr "备注数据" + +#: lib/php/monica/list.inc.php:2691 +msgid "Expiration" +msgstr "到期日" + +#: lib/php/monica/list.inc.php:2699 +msgid "Add a new user request." +msgstr "建新用户申请。" + +#: lib/php/monica/list.inc.php:2709 +msgid "Search for a user request:" +msgstr "搜索用户申请:" + +#: lib/php/monica/list.inc.php:2727 +#, c-format +msgid "Your query found %s user request." +msgid_plural "Your query found %s user requests." +msgstr[0] "共 %s 笔相符的用户申请。" + +#: lib/php/monica/list.inc.php:2734 +#, c-format +msgid "%s user request." +msgid_plural "%s user requests." +msgstr[0] "共 %s 笔用户申请。" + +#: lib/php/monica/list.inc.php:2743 +#, c-format +msgid "Your query found %s user request, listing %s to %s." +msgid_plural "Your query found %s user requests, listing %s to %s." +msgstr[0] "共 %s 笔相符的用户申请,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2752 +#, c-format +msgid "%s user request, listing %s to %s." +msgid_plural "%s user requests, listing %s to %s." +msgstr[0] "共 %s 笔用户申请,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2778 +msgid "Add a new category." +msgstr "建新分类。" + +#: lib/php/monica/list.inc.php:2788 +msgid "Search for a category:" +msgstr "搜索分类:" + +#: lib/php/monica/list.inc.php:2806 +#, c-format +msgid "Your query found %s category." +msgid_plural "Your query found %s categories." +msgstr[0] "共 %s 类相符的分类。" + +#: lib/php/monica/list.inc.php:2813 +#, c-format +msgid "%s category." +msgid_plural "%s categories." +msgstr[0] "共 %s 类分类。" + +#: lib/php/monica/list.inc.php:2822 +#, c-format +msgid "Your query found %s category, listing %s to %s." +msgid_plural "Your query found %s categories, listing %s to %s." +msgstr[0] "共 %s 类相符的分类,列出第 %s 类到第 %s 类。" + +#: lib/php/monica/list.inc.php:2831 +#, c-format +msgid "%s category, listing %s to %s." +msgid_plural "%s categories, listing %s to %s." +msgstr[0] "共 %s 类分类,列出第 %s 类到第 %s 类。" + +#: lib/php/monica/list.inc.php:2849 +msgid "Add a new categorization record." +msgstr "建新分类数据。" + +#: lib/php/monica/list.inc.php:2859 +msgid "Search for a categorization record:" +msgstr "搜索分类数据:" + +#: lib/php/monica/list.inc.php:2877 +#, c-format +msgid "Your query found %s categorization record." +msgid_plural "Your query found %s categorization records." +msgstr[0] "共 %s 笔相符的分类数据。" + +#: lib/php/monica/list.inc.php:2884 +#, c-format +msgid "%s categorization record." +msgid_plural "%s categorization records." +msgstr[0] "共 %s 笔分类数据。" + +#: lib/php/monica/list.inc.php:2893 +#, c-format +msgid "Your query found %s categorization record, listing %s to %s." +msgid_plural "Your query found %s categorization records, listing %s to %s." +msgstr[0] "共 %s 笔相符的分类数据,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2902 +#, c-format +msgid "%s categorization record, listing %s to %s." +msgid_plural "%s categorization records, listing %s to %s." +msgstr[0] "共 %s 笔分类数据,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:2921 +msgid "Select a Page" +msgstr "选择网页" + +#: lib/php/monica/list.inc.php:2922 +msgid "Manage Pages" +msgstr "管理网页" + +#: lib/php/monica/list.inc.php:2952 lib/php/monica/list.inc.php:3066 +#: lib/php/monica/list.inc.php:3173 lib/php/monica/list.inc.php:3237 +#: lib/php/monica/list.inc.php:3358 +msgid "Hidden" +msgstr "隐藏" + +#: lib/php/monica/list.inc.php:2953 lib/php/monica/list.inc.php:3067 +#: lib/php/monica/list.inc.php:3174 lib/php/monica/list.inc.php:3238 +#: lib/php/monica/list.inc.php:3359 +msgid "Shown" +msgstr "秀出" + +#: lib/php/monica/list.inc.php:2963 +msgid "Write a new page." +msgstr "撰写网页。" + +#: lib/php/monica/list.inc.php:2973 +msgid "Search for a page:" +msgstr "搜索网页:" + +#: lib/php/monica/list.inc.php:2991 +#, c-format +msgid "Your query found %s page." +msgid_plural "Your query found %s pages." +msgstr[0] "共 %s 页相符的网页。" + +#: lib/php/monica/list.inc.php:2998 +#, c-format +msgid "%s page." +msgid_plural "%s pages." +msgstr[0] "共 %s 页网页。" + +#: lib/php/monica/list.inc.php:3007 +#, c-format +msgid "Your query found %s page, listing %s to %s." +msgid_plural "Your query found %s pages, listing %s to %s." +msgstr[0] "共 %s 页相符的网页,列出第 %s 页到第 %s 页。" + +#: lib/php/monica/list.inc.php:3016 +#, c-format +msgid "%s page, listing %s to %s." +msgid_plural "%s pages, listing %s to %s." +msgstr[0] "共 %s 页网页,列出第 %s 页到第 %s 页。" + +#: lib/php/monica/list.inc.php:3035 +msgid "Select a News Article" +msgstr "选择新闻" + +#: lib/php/monica/list.inc.php:3036 +msgid "Manage News" +msgstr "管理新闻" + +#: lib/php/monica/list.inc.php:3077 +msgid "Write a new news article." +msgstr "撰写新闻。" + +#: lib/php/monica/list.inc.php:3087 +msgid "Search for a news article:" +msgstr "搜索新闻:" + +#: lib/php/monica/list.inc.php:3105 +#, c-format +msgid "Your query found %s news article." +msgid_plural "Your query found %s news articles." +msgstr[0] "共 %s 则相符的新闻。" + +#: lib/php/monica/list.inc.php:3112 +#, c-format +msgid "%s news article." +msgid_plural "%s news articles." +msgstr[0] "共 %s 则新闻。" + +#: lib/php/monica/list.inc.php:3121 +#, c-format +msgid "Your query found %s news article, listing %s to %s." +msgid_plural "Your query found %s news articles, listing %s to %s." +msgstr[0] "共 %s 则相符的新闻,列出第 %s 则到第 %s 则。" + +#: lib/php/monica/list.inc.php:3130 +#, c-format +msgid "%s news article, listing %s to %s." +msgid_plural "%s news articles, listing %s to %s." +msgstr[0] "共 %s 则新闻,列出第 %s 则到第 %s 则。" + +#: lib/php/monica/list.inc.php:3149 +msgid "Select a Link Category" +msgstr "选择链接分类" + +#: lib/php/monica/list.inc.php:3150 +msgid "Manage Link Categories" +msgstr "管理链接分类" + +#: lib/php/monica/list.inc.php:3197 +msgid "Select a Link" +msgstr "选择链接" + +#: lib/php/monica/list.inc.php:3198 +msgid "Manage Links" +msgstr "管理链接" + +#: lib/php/monica/list.inc.php:3248 +msgid "Add a new related link." +msgstr "建新相关链接。" + +#: lib/php/monica/list.inc.php:3258 +msgid "Search for a related link:" +msgstr "搜索相关链接:" + +#: lib/php/monica/list.inc.php:3276 +#, c-format +msgid "Your query found %s related link." +msgid_plural "Your query found %s related links." +msgstr[0] "共 %s 笔相符的相关链接。" + +#: lib/php/monica/list.inc.php:3283 +#, c-format +msgid "%s related link." +msgid_plural "%s related links." +msgstr[0] "共 %s 笔相关链接" + +#: lib/php/monica/list.inc.php:3292 +#, c-format +msgid "Your query found %s related link, listing %s to %s." +msgid_plural "Your query found %s related links, listing %s to %s." +msgstr[0] "共 %s 笔相符的相关链接,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:3301 +#, c-format +msgid "%s related link, listing %s to %s." +msgid_plural "%s related links, listing %s to %s." +msgstr[0] "共 %s 笔相关链接,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:3321 +msgid "Select a Link Categorization Record" +msgstr "选择链接分类数据" + +#: lib/php/monica/list.inc.php:3322 +msgid "Manage Link Categorization" +msgstr "管理链接分类表" + +#: lib/php/monica/list.inc.php:3327 +msgid "Link" +msgstr "链接" + +#: lib/php/monica/list.inc.php:3383 +msgid "Select a Country" +msgstr "选择国家" + +#: lib/php/monica/list.inc.php:3384 +msgid "Manage Country Data" +msgstr "管理国家数据" + +#: lib/php/monica/list.inc.php:3389 +msgid "Code" +msgstr "代码" + +#: lib/php/monica/list.inc.php:3390 +msgid "Country name" +msgstr "国名" + +#: lib/php/monica/list.inc.php:3399 +msgid "Add a new country record." +msgstr "建新国家数据。" + +#: lib/php/monica/list.inc.php:3409 +msgid "Search for a country:" +msgstr "搜索国家:" + +#: lib/php/monica/list.inc.php:3427 +#, c-format +msgid "Your query found %s country." +msgid_plural "Your query found %s countries." +msgstr[0] "共 %s 个相符的国家。" + +#: lib/php/monica/list.inc.php:3434 +#, c-format +msgid "%s country." +msgid_plural "%s countries." +msgstr[0] "共 %s 个国家。" + +#: lib/php/monica/list.inc.php:3443 +#, c-format +msgid "Your query found %s country, listing %s to %s." +msgid_plural "Your query found %s countries, listing %s to %s." +msgstr[0] "共 %s 个相符的国家,列出第 %s 个到第 %s 个。" + +#: lib/php/monica/list.inc.php:3452 +#, c-format +msgid "%s country, listing %s to %s." +msgid_plural "%s countries, listing %s to %s." +msgstr[0] "共 %s 个国家,列出第 %s 个到第 %s 个。" + +#: lib/php/monica/list.inc.php:3474 +msgid "Browse the Activity Log" +msgstr "查阅网站活动日志" + +#: lib/php/monica/list.inc.php:3586 +msgid "Please fill in the number of rows to display." +msgstr "请填上显示笔数。" + +#: lib/php/monica/list.inc.php:3590 +#, c-format +msgid "This number of rows to display is too long. (Max. length %d)" +msgstr "显示笔数太长了。(最长 %d )" + +#: lib/php/monica/list.inc.php:3595 +msgid "Please fill in a positive integer number of rows to display." +msgstr "显示笔数请填正整数。" + +#: lib/php/monica/list.inc.php:3599 lib/php/monica/list.inc.php:3609 +#, c-format +msgid "" +"The number of rows to display is too small. Please fill in a larger number " +"of rows to display between %d and %d." +msgstr "显示笔数太小了,请设置在 %d 到 %d 之间。" + +#: lib/php/monica/list.inc.php:3613 +#, c-format +msgid "" +"The number of rows to display is too large. Please fill in a smaller number " +"of rows to display between %d and %d." +msgstr "显示笔数太大了,请设置在 %d 到 %d 之间。" + +#: lib/php/monica/list.inc.php:3638 +msgid "Search for log entries:" +msgstr "搜索记录:" + +#: lib/php/monica/list.inc.php:3641 +msgid "Display" +msgstr "显示" + +#: lib/php/monica/list.inc.php:3654 +msgid "Display rows:" +msgstr "显示笔数:" + +#: lib/php/monica/list.inc.php:3677 +#, c-format +msgid "Your query found %s log entry." +msgid_plural "Your query found %s log entries." +msgstr[0] "共 %s 笔相符的记录。" + +#: lib/php/monica/list.inc.php:3684 +#, c-format +msgid "%s log entry." +msgid_plural "%s log entries." +msgstr[0] "共 %s 笔记录。" + +#: lib/php/monica/list.inc.php:3693 +#, c-format +msgid "Your query found %s log entry, listing %s to %s." +msgid_plural "Your query found %s log entries, listing %s to %s." +msgstr[0] "共 %s 笔相符的记录,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/list.inc.php:3702 +#, c-format +msgid "%s log entry, listing %s to %s." +msgid_plural "%s log entries, listing %s to %s." +msgstr[0] "共 %s 笔记录,列出第 %s 笔到第 %s 笔。" + +#: lib/php/monica/lninfo.inc.php:28 +msgid "English" +msgstr "英文" + +#: lib/php/monica/lninfo.inc.php:39 +msgid "Traditional Chinese" +msgstr "繁体中文" + +#: lib/php/monica/lninfo.inc.php:50 +msgid "Simplified Chinese" +msgstr "简体中文" + +#: lib/php/monica/lninfo.inc.php:61 +msgid "Chinese" +msgstr "中文" + +#: lib/php/monica/lninfo.inc.php:72 +msgid "Japanese" +msgstr "日文" + +#: lib/php/monica/lninfo.inc.php:83 +msgid "Korean" +msgstr "韩文" + +#: lib/php/monica/lninfo.inc.php:94 +msgid "German" +msgstr "德文" + +#: lib/php/monica/lninfo.inc.php:105 +msgid "Spanish" +msgstr "西班牙文" + +#: lib/php/monica/lninfo.inc.php:366 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "切换到本页的%s版。" + +#: lib/php/monica/pagefunc.inc.php:738 +msgid "Web pages" +msgstr "网页" + +#: lib/php/monica/pagefunc.inc.php:739 +msgid "News" +msgstr "新闻" + +#: lib/php/monica/pagefunc.inc.php:740 +msgid "Related links" +msgstr "相关链接" + +#: lib/php/monica/pagefunc.inc.php:741 +msgid "Home page" +msgstr "首页" + +#: lib/php/monica/pagefunc.inc.php:742 +msgid "Whole web site" +msgstr "整个网站" + +#: lib/php/monica/pic.inc.php:39 +msgid "Left-aligned" +msgstr "靠左" + +#: lib/php/monica/pic.inc.php:40 +msgid "Right-aligned" +msgstr "靠右" + +#: lib/php/monica/pic.inc.php:74 lib/php/monica/pic.inc.php:77 +#, c-format +msgid "This picture file is too large (Max %s)." +msgstr "图档太大。(上限 %s )" + +#: lib/php/monica/pic.inc.php:92 +msgid "Please upload only PNG, JPEG or GIF files." +msgstr "限上传 PNG 、 JPEG 或 GIF 图档。" + +#: lib/php/monica/pic.inc.php:153 +#, c-format +msgid "Width: %d, height: %d, ratio: %0.2f" +msgstr "宽: %d ,高: %d ,比例: %0.2f" + +#: lib/php/monica/pic.inc.php:176 +msgid "Please specify a numeric ratio." +msgstr "比例请设置数字。" + +#: lib/php/monica/pic.inc.php:180 +msgid "Please specify a positive ratio." +msgstr "比例请设置正数。" + +#: lib/php/monica/pic.inc.php:183 +#, c-format +msgid "Please specify a ratio less than or equal to %0.2f." +msgstr "比例请勿大于 %0.2f 。" + +#: lib/php/monica/pic.inc.php:189 +msgid "This image is too large to display." +msgstr "图片太大,无法显示。" + +#: lib/php/monica/preview.inc.php:47 +#, c-format +msgid "Unknown preview source: \"%s\"." +msgstr "预览数据源不明:「 %s 」。" + +#: lib/php/monica/preview.inc.php:67 +#, c-format +msgid "Unknown preview form: %d." +msgstr "预览表格不明: %d 。" + +#: lib/php/monica/preview.inc.php:143 +msgid "Preview Mark Area" +msgstr "预览标志区" + +#: lib/php/monica/preview.inc.php:148 +msgid "Finish preview and return." +msgstr "结束预览回前页。" + +#: lib/php/monica/process.inc.php:237 +msgid "This record was not modified." +msgstr "数据未异动。" + +#: lib/php/monica/process.inc.php:243 +msgid "This record has been successfully added." +msgstr "数据建好了。" + +#: lib/php/monica/process.inc.php:247 +msgid "This record has been successfully updated." +msgstr "数据存好了。" + +#: lib/php/monica/process.inc.php:251 +msgid "This record has been successfully deleted." +msgstr "数据删掉了。" + +#: lib/php/monica/process.inc.php:406 +msgid "This category was not modified." +msgstr "分类未异动。" + +#: lib/php/monica/process.inc.php:412 +msgid "This category has been successfully added." +msgstr "分类建好了。" + +#: lib/php/monica/process.inc.php:416 +msgid "This category has been successfully updated." +msgstr "分类存好了。" + +#: lib/php/monica/process.inc.php:420 +msgid "This category has been successfully deleted." +msgstr "分类删掉了。" + +#: lib/php/monica/process.inc.php:433 +msgid "This categorization record was not modified." +msgstr "分类数据未异动。" + +#: lib/php/monica/process.inc.php:439 +msgid "This categorization record has been successfully added." +msgstr "分类数据建好了。" + +#: lib/php/monica/process.inc.php:443 +msgid "This categorization record has been successfully updated." +msgstr "分类数据存好了。" + +#: lib/php/monica/process.inc.php:447 +msgid "This categorization record has been successfully deleted." +msgstr "分类数据删掉了。" + +#: lib/php/monica/process.inc.php:782 +msgid "This user account was not modified." +msgstr "帐号未异动。" + +#: lib/php/monica/process.inc.php:788 +msgid "This user account has been successfully added." +msgstr "帐号建好了。" + +#: lib/php/monica/process.inc.php:792 +msgid "This user account has been successfully updated." +msgstr "帐号存好了。" + +#: lib/php/monica/process.inc.php:796 +msgid "This user account has been successfully deleted." +msgstr "帐号删掉了。" + +#: lib/php/monica/process.inc.php:1074 +msgid "This group was not modified." +msgstr "群组未异动。" + +#: lib/php/monica/process.inc.php:1080 +msgid "This group has been successfully added." +msgstr "群组建好了。" + +#: lib/php/monica/process.inc.php:1084 +msgid "This group has been successfully updated." +msgstr "群组存好了。" + +#: lib/php/monica/process.inc.php:1088 +msgid "This group has been successfully deleted." +msgstr "群组删掉了。" + +#: lib/php/monica/process.inc.php:1152 lib/php/monica/process.inc.php:1230 +msgid "This membership record was not modified." +msgstr "成员关系未异动。" + +#: lib/php/monica/process.inc.php:1158 lib/php/monica/process.inc.php:1236 +msgid "This membership record has been successfully added." +msgstr "成员关系建好了。" + +#: lib/php/monica/process.inc.php:1162 lib/php/monica/process.inc.php:1240 +msgid "This membership record has been successfully updated." +msgstr "成员关系存好了。" + +#: lib/php/monica/process.inc.php:1166 lib/php/monica/process.inc.php:1244 +msgid "This membership record has been successfully deleted." +msgstr "成员关系删掉了。" + +#: lib/php/monica/process.inc.php:1308 +msgid "This script privilege record was not modified." +msgstr "程序权限未异动。" + +#: lib/php/monica/process.inc.php:1314 +msgid "This script privilege record has been successfully added." +msgstr "程序权限建好了。" + +#: lib/php/monica/process.inc.php:1318 +msgid "This script privilege record has been successfully updated." +msgstr "程序权限存好了。" + +#: lib/php/monica/process.inc.php:1322 +msgid "This script privilege record has been successfully deleted." +msgstr "程序权限删掉了。" + +#: lib/php/monica/process.inc.php:1438 +msgid "This user preference was not modified." +msgstr "用户偏好未异动。" + +#: lib/php/monica/process.inc.php:1444 +msgid "This user preference has been successfully added." +msgstr "用户偏好建好了。" + +#: lib/php/monica/process.inc.php:1448 +msgid "This user preference has been successfully updated." +msgstr "用户偏好存好了。" + +#: lib/php/monica/process.inc.php:1452 +msgid "This user preference has been successfully deleted." +msgstr "用户偏好删掉了。" + +#: lib/php/monica/process.inc.php:1560 +msgid "This user request was not modified." +msgstr "用户申请未异动。" + +#: lib/php/monica/process.inc.php:1566 +msgid "This user request has been successfully added." +msgstr "用户申请建好了。" + +#: lib/php/monica/process.inc.php:1570 +msgid "This user request has been successfully updated." +msgstr "用户申请存好了。" + +#: lib/php/monica/process.inc.php:1574 +msgid "This user request has been successfully deleted." +msgstr "用户申请删掉了。" + +#: lib/php/monica/process.inc.php:1685 +msgid "This page was not modified." +msgstr "网页未异动。" + +#: lib/php/monica/process.inc.php:1691 +msgid "This page has been successfully added." +msgstr "网页建好了。" + +#: lib/php/monica/process.inc.php:1695 +msgid "This page has been successfully updated." +msgstr "网页存好了。" + +#: lib/php/monica/process.inc.php:1699 +msgid "This page has been successfully deleted." +msgstr "网页删掉了。" + +#: lib/php/monica/process.inc.php:1874 +msgid "This news article was not modified." +msgstr "新闻未异动。" + +#: lib/php/monica/process.inc.php:1880 +msgid "This news article has been successfully added." +msgstr "新闻建好了。" + +#: lib/php/monica/process.inc.php:1884 +msgid "This news article has been successfully updated." +msgstr "新闻存好了。" + +#: lib/php/monica/process.inc.php:1888 +msgid "This news article has been successfully deleted." +msgstr "新闻删掉了。" + +#: lib/php/monica/process.inc.php:1997 +msgid "This country was not modified." +msgstr "国家未异动。" + +#: lib/php/monica/process.inc.php:2003 +msgid "This country has been successfully added." +msgstr "国家建好了。" + +#: lib/php/monica/process.inc.php:2007 +msgid "This country has been successfully updated." +msgstr "国家存好了。" + +#: lib/php/monica/process.inc.php:2011 +msgid "This country has been successfully deleted." +msgstr "国家删掉了。" + +#: lib/php/monica/process.inc.php:2097 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. (%0.3f seconds)" +msgstr "该类网页重制好了。( %0.3f 秒)" + +#: lib/php/monica/process.inc.php:2158 +#, c-format +msgid "Welcome, %s!" +msgstr "%s,你好。" + +#: lib/php/monica/process.inc.php:2204 +msgid "You have successfully logged out." +msgstr "注销好了。" + +#: lib/php/monica/process.inc.php:2439 +msgid "This related link was not modified." +msgstr "相关链接未异动。" + +#: lib/php/monica/process.inc.php:2445 +msgid "This related link has been successfully added." +msgstr "相关链接建好了。" + +#: lib/php/monica/process.inc.php:2449 +msgid "This related link has been successfully updated." +msgstr "相关链接存好了。" + +#: lib/php/monica/process.inc.php:2453 +msgid "This related link has been successfully deleted." +msgstr "相关链接删掉了。" + +#: lib/php/monica/request.inc.php:38 +msgid "Please specify the request." +msgstr "请设置申请编号。" + +#: lib/php/monica/request.inc.php:46 lib/php/monica/request.inc.php:55 +#, c-format +msgid "Invalid request S/N: %s." +msgstr "申请编号无效: %s 。" + +#: lib/php/monica/sitesize.inc.php:41 +#, c-format +msgid "Currently using files %s.\n" +msgstr "现用文件 %s。\n" + +#: lib/php/monica/sitesize.inc.php:46 +#, c-format +msgid "Currently using files %s, database %s, total %s.\n" +msgstr "现用文件 %s ,数据库 %s ,合计 %s 。\n" + +#: lib/php/monica/upload.inc.php:70 +#, c-format +msgid "MIME file type: %s" +msgstr "MIME 文件格式: %s" + +#: lib/php/monica/upload.inc.php:71 +#, c-format +msgid "File name: %s" +msgstr "文件名: %s" + +#: lib/php/monica/upload.inc.php:72 +#, c-format +msgid "File size: %s bytes" +msgstr "文件大小: %s 字节" + +#: lib/php/monica/validate.inc.php:116 +msgid "HTML Validatior Logo Area" +msgstr "HTML 验证标志区" + +#: lib/php/monica/validate.inc.php:117 +msgid "HTML validation result of this page" +msgstr "本页的 HTML 验证结果" + +#: lib/php/monica/validate.inc.php:118 +#, c-format +msgid "Valid %s!" +msgstr "%s 正确!" + +#: lib/php/monica/validate.inc.php:119 +msgid "CSS validation result of this page" +msgstr "本页的 CSS 验证结果" + +#: lib/php/monica/validate.inc.php:120 +msgid "Valid CSS!" +msgstr "CSS 正确!" + +#: lib/php/monica/validate.inc.php:121 +msgid "Explanation of Level Triple-A Conformance" +msgstr "无障碍三 A 级标准说明" + +#: lib/php/monica/validate.inc.php:122 +msgid "" +"Level Triple-A conformance icon, W3C-WAI Web Content Accessibility " +"Guidelines 1.0" +msgstr "W3C 无障碍网页规范 1.0 三 A 级标准标章" diff --git a/po/monica/zh_TW.gmo b/po/monica/zh_TW.gmo new file mode 100644 index 0000000..f979ebf Binary files /dev/null and b/po/monica/zh_TW.gmo differ diff --git a/po/monica/zh_TW.po b/po/monica/zh_TW.po new file mode 100644 index 0000000..9b7e739 --- /dev/null +++ b/po/monica/zh_TW.po @@ -0,0 +1,3243 @@ +# Traditional Chinese PO file for the monica core +# Copyright (C) 2002-2018 Pristine Communcations +# This file is distributed under the same license as the monica package. +# imacat , 2002-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: monica 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 12:53+0800\n" +"PO-Revision-Date: 2018-11-02 01:22+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: lib/php/monica/checker.inc.php:159 +msgid "Please select a user." +msgstr "請選擇使用者。" + +#: lib/php/monica/checker.inc.php:163 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: lib/php/monica/checker.inc.php:181 +msgid "Please select a group." +msgstr "請選擇群組。" + +#: lib/php/monica/checker.inc.php:185 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: lib/php/monica/checker.inc.php:203 +msgid "Please fill in the script." +msgstr "請填上程式檔名。" + +#: lib/php/monica/checker.inc.php:207 +#, c-format +msgid "This script is too long. (Max. length %d)" +msgstr "程式檔名太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:212 +msgid "This script is not a valid script. Please specify another one." +msgstr "查無此程式,請重新設定執行的程式。" + +#: lib/php/monica/checker.inc.php:230 +msgid "Please fill in the date." +msgstr "請填上日期。" + +#: lib/php/monica/checker.inc.php:234 lib/php/monica/checker.inc.php:238 +#: lib/php/monica/checker.inc.php:241 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期請以 YYYY-MM-DD 格式正確填寫。" + +#: lib/php/monica/checker.inc.php:259 +msgid "Please fill in the ID." +msgstr "請填上代號。" + +#: lib/php/monica/checker.inc.php:263 +#, c-format +msgid "This ID. is too long. (Max. length %d)" +msgstr "代號太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:267 +#, c-format +msgid "This ID. is too short. (Min. length %d)" +msgstr "代號太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:272 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "代號限用小寫英文字母、數字和底線。" + +#: lib/php/monica/checker.inc.php:294 +msgid "Please fill in the order." +msgstr "請填上先後次序。" + +#: lib/php/monica/checker.inc.php:298 +#, c-format +msgid "This order is too long. (Max. length %d)" +msgstr "次序太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:303 +msgid "Please fill in a positive integer order." +msgstr "次序請填正整數。" + +#: lib/php/monica/checker.inc.php:307 lib/php/monica/checker.inc.php:317 +#, c-format +msgid "" +"The order is too small. Please fill in a larger order between %d and %d." +msgstr "次序太小了,請設定在 %d 到 %d 之間。" + +#: lib/php/monica/checker.inc.php:321 +#, c-format +msgid "" +"The order is too large. Please fill in a smaller order between %d and %d." +msgstr "次序太大了,請設定在 %d 到 %d 之間。" + +#: lib/php/monica/checker.inc.php:348 +msgid "Please fill in the page path." +msgstr "請填上網頁路徑。" + +#: lib/php/monica/checker.inc.php:352 +#, c-format +msgid "This page path is too long. (Max. length %d)" +msgstr "網頁路徑太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:365 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "已有同一網頁,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:369 +msgid "Please fill in an absolute page path." +msgstr "網頁路徑請填上絕對路徑。" + +#: lib/php/monica/checker.inc.php:373 +msgid "Please fill in a valid page path." +msgstr "網頁路徑請填上正確路徑。" + +#: lib/php/monica/checker.inc.php:377 +msgid "You cannot overwrite the cover home page." +msgstr "不可以程式設定首頁。" + +#: lib/php/monica/checker.inc.php:381 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "網頁路徑限填 HTML 位址( *.html )。" + +#: lib/php/monica/checker.inc.php:422 lib/php/monica/checker.inc.php:428 +msgid "Please fill in the attachment description." +msgstr "請填上附件說明。" + +#: lib/php/monica/checker.inc.php:432 +#, c-format +msgid "This attachment description is too long. (Max. length %d)" +msgstr "附件說明太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:449 +msgid "This PDF. file does not exist anymore. Please upload another one." +msgstr "查無此 PDF. 檔,請重新上傳檔案。" + +#: lib/php/monica/checker.inc.php:456 +#, c-format +msgid "This PDF. file is too large. (Max. size %s)" +msgstr "檔案太大。(上限 %s )" + +#: lib/php/monica/checker.inc.php:461 +msgid "Please upload only PDF. file." +msgstr "限上傳 PDF. 檔。" + +#: lib/php/monica/checker.inc.php:479 +msgid "Please fill in the title." +msgstr "請填上標題。" + +#: lib/php/monica/checker.inc.php:483 +#, c-format +msgid "This title is too long. (Max. length %d)" +msgstr "標題太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:502 +msgid "Please fill in the subject." +msgstr "請填上主題。" + +#: lib/php/monica/checker.inc.php:506 +#, c-format +msgid "This subject is too long. (Max. length %d)" +msgstr "主題太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:524 lib/php/monica/form.inc.php:3159 +#: lib/php/monica/form.inc.php:3172 +msgid "Fill in the content here." +msgstr "請填上內文。" + +#: lib/php/monica/checker.inc.php:528 +msgid "Please fill in the content." +msgstr "請填上內文。" + +#: lib/php/monica/checker.inc.php:532 +#, c-format +msgid "This content is too long. (Max. length %d)" +msgstr "內文太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:551 +msgid "Please fill in the keywords." +msgstr "請填上關鍵字。" + +#: lib/php/monica/checker.inc.php:555 +#, c-format +msgid "This keyword list is too long. (Max. length %d)" +msgstr "關鍵字太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:572 +msgid "Please select a proper pinyin." +msgstr "請選擇符合的拼音。" + +#: lib/php/monica/checker.inc.php:578 +#, c-format +msgid "This pinyin is too long. (Max. length %d)" +msgstr "拼音太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:583 +msgid "" +"This pinyin does not match the Chinese. Please select a proper pinyin from " +"the list." +msgstr "拼音與中文不合,請重新於列表中選擇。" + +#: lib/php/monica/checker.inc.php:609 lib/php/monica/pic.inc.php:82 +msgid "Please upload the picture." +msgstr "請上傳圖檔。" + +#: lib/php/monica/checker.inc.php:616 lib/php/monica/checker.inc.php:3214 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "查無此圖,請重新上傳圖檔。" + +#: lib/php/monica/checker.inc.php:622 +#, c-format +msgid "This picture is too large. Please upload another one. (Max. size %d)" +msgstr "圖檔太大,請重新上傳圖檔(最大 %d )。" + +#: lib/php/monica/checker.inc.php:639 lib/php/monica/form.inc.php:3588 +#, c-format +msgid "Please upload a new picture from %s." +msgstr "請由%s建新圖片。" + +#: lib/php/monica/checker.inc.php:664 lib/php/monica/checker.inc.php:727 +msgid "Please fill in the picture caption." +msgstr "請填上圖片標題。" + +#: lib/php/monica/checker.inc.php:668 lib/php/monica/checker.inc.php:731 +#, c-format +msgid "This picture caption is too long. (Max. length %d)" +msgstr "圖片標題太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:686 lib/php/monica/checker.inc.php:749 +msgid "Please select the picture position." +msgstr "請設定圖片位置。" + +#: lib/php/monica/checker.inc.php:692 lib/php/monica/checker.inc.php:755 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "圖片位置無效。請由表上選擇適當的圖片位置。" + +#: lib/php/monica/checker.inc.php:791 lib/php/monica/checker.inc.php:794 +#, c-format +msgid "Your uploaded file is too large (Max %s)." +msgstr "上傳檔案太大。(上限 %s )" + +#: lib/php/monica/checker.inc.php:797 lib/php/monica/pic.inc.php:80 +msgid "" +"Upload not completed. Disk may be full or connection may be closed in the " +"half. You may try to upload again, or contact the system administrator for " +"this problem." +msgstr "" +"上傳失敗。可能是伺服器磁碟滿了,或傳到一半網路斷線。請重新上傳一次,或洽網站" +"系統管理人員處理。" + +#: lib/php/monica/checker.inc.php:799 lib/php/monica/pic.inc.php:84 +#, c-format +msgid "Upload failed with an unknown error (%d)." +msgstr "上傳失敗,原因不明。( %d )" + +#: lib/php/monica/checker.inc.php:1183 lib/php/monica/chkfunc.inc.php:59 +#: lib/php/monica/chkfunc.inc.php:72 lib/php/monica/preview.inc.php:29 +#, c-format +msgid "The following field was not received: \"%s\"." +msgstr "程式沒有收到下列欄位:「 %s 」" + +#: lib/php/monica/checker.inc.php:1262 +msgid "Please fill in the user ID." +msgstr "請填上帳號。" + +#: lib/php/monica/checker.inc.php:1266 +#, c-format +msgid "This user ID. is too long. (Max. length %d)" +msgstr "帳號太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:1270 +#, c-format +msgid "This user ID. is too short. (Min. length %d)" +msgstr "帳號太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1275 +msgid "" +"Only lower-case English letters, numbers, at-signs, dots, dashes and " +"underscores are allowed for the user ID." +msgstr "帳號限用小寫英文字母、數字、 @ 號、點、橫線和底線。" + +#: lib/php/monica/checker.inc.php:1287 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "該使用者已有帳號,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:1317 +msgid "Please fill in the password." +msgstr "請填上密碼。" + +#: lib/php/monica/checker.inc.php:1320 +msgid "Please confirm the password." +msgstr "請確認密碼。" + +#: lib/php/monica/checker.inc.php:1324 +#, c-format +msgid "This password is too long. (Max. length %d)" +msgstr "密碼太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:1329 +#, c-format +msgid "This password is too short. (Min. length %d)" +msgstr "密碼太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1334 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "兩次密碼不合,請重新設定密碼。" + +#: lib/php/monica/checker.inc.php:1345 +msgid "This password is based on the user ID." +msgstr "密碼不可由帳號組成。" + +#: lib/php/monica/checker.inc.php:1360 +msgid "This password does not contain enough different characters." +msgstr "密碼重複的字元太多。" + +#: lib/php/monica/checker.inc.php:1364 +msgid "This password is too simplistic/systematic." +msgstr "密碼結構太簡單。" + +#: lib/php/monica/checker.inc.php:1368 +msgid "This password is based on a dictionary word." +msgstr "密碼不可由字典單字組成。" + +#: lib/php/monica/checker.inc.php:1370 +msgid "This password is based on a (reversed) dictionary word." +msgstr "密碼不可由倒過來的字典單字組成。" + +#: lib/php/monica/checker.inc.php:1372 +msgid "This password is too simple." +msgstr "密碼太簡單。" + +#: lib/php/monica/checker.inc.php:1378 +msgid "You cannot use a password that is based on the user ID." +msgstr "密碼不可由帳號組成。" + +#: lib/php/monica/checker.inc.php:1397 +msgid "Please fill in the name." +msgstr "請填上姓名。" + +#: lib/php/monica/checker.inc.php:1401 +#, c-format +msgid "This name is too long. (Max. length %d)" +msgstr "姓名太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:1420 +msgid "Please fill in the e-mail." +msgstr "請填上 E-mail 信箱。" + +#: lib/php/monica/checker.inc.php:1424 +#, c-format +msgid "This e-mail is too long. (Max. length %d)" +msgstr "E-mail 信箱太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:1428 +#, c-format +msgid "This e-mail is too short. (Min. length %d)" +msgstr "E-mail 信箱太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1437 +msgid "Please fill in a valid e-mail address." +msgstr "請填上正確的 E-mail 信箱。" + +#: lib/php/monica/checker.inc.php:1439 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "查無這個信箱的所屬網域,請檢查有沒有拼錯。" + +#: lib/php/monica/checker.inc.php:1461 lib/php/monica/checker.inc.php:1655 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "隸屬群組重複,請勿重複設定。" + +#: lib/php/monica/checker.inc.php:1478 +msgid "You cannot submit the super-user group along with other groups." +msgstr "總管理員群組不可與其它群組一起設定。" + +#: lib/php/monica/checker.inc.php:1480 +msgid "You cannot set the administrators group." +msgstr "不可設定所有網站管理員群組" + +#: lib/php/monica/checker.inc.php:1482 +msgid "You cannot set the all-users group." +msgstr "不可設定所有登入使用者群組。" + +#: lib/php/monica/checker.inc.php:1515 +msgid "Please fill in the group ID." +msgstr "請填上群組代號。" + +#: lib/php/monica/checker.inc.php:1519 +#, c-format +msgid "This group ID. is too long. (Max. length %d)" +msgstr "群組代號太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:1523 +#, c-format +msgid "This group ID. is too short. (Min. length %d)" +msgstr "群組代號太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1528 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "群組代號限用小寫英文字母、數字和底線。" + +#: lib/php/monica/checker.inc.php:1540 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "已有同一群組,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:1558 +msgid "Please fill in the privilege description." +msgstr "請填上權限說明。" + +#: lib/php/monica/checker.inc.php:1562 +#, c-format +msgid "This privilege description is too long. (Max. length %d)" +msgstr "權限說明太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:1585 +msgid "This user member is duplicated. You cannot set duplicated ones." +msgstr "使用者成員重複,請勿重複設定。" + +#: lib/php/monica/checker.inc.php:1620 +msgid "This group member is duplicated. You cannot set duplicated ones." +msgstr "群組成員重複,請勿重複設定。" + +#: lib/php/monica/checker.inc.php:1747 lib/php/monica/checker.inc.php:1855 +msgid "Please select a member." +msgstr "請選擇成員。" + +#: lib/php/monica/checker.inc.php:1751 lib/php/monica/checker.inc.php:1859 +msgid "This member does not exist anymore. Please select another one." +msgstr "查無此成員,請重新選擇。" + +#: lib/php/monica/checker.inc.php:1770 lib/php/monica/checker.inc.php:1883 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "已有同一成員關係,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:1837 +msgid "Please select a different belonging group." +msgstr "隸屬群組請選擇別的群組。" + +#: lib/php/monica/checker.inc.php:1864 +msgid "Please select a different group member." +msgstr "群組成員請選擇別的群組。" + +#: lib/php/monica/checker.inc.php:1958 +msgid "" +"This script privilege already exists. You cannot create a duplicated one." +msgstr "已有同一程式權限,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:1996 lib/php/monica/checker.inc.php:2184 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: lib/php/monica/checker.inc.php:2002 lib/php/monica/checker.inc.php:2190 +msgid "This option is invalid. Please select a proper user." +msgstr "使用者選項無效,請由表上選擇適當的使用者。" + +#: lib/php/monica/checker.inc.php:2020 +msgid "Please set the preference domain." +msgstr "請設定適用範圍。" + +#: lib/php/monica/checker.inc.php:2026 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "適用範圍選項無效,請設定適當的適用範圍。" + +#: lib/php/monica/checker.inc.php:2039 lib/php/monica/checker.inc.php:2295 +msgid "Please fill in the preference domain." +msgstr "請填上偏好的適用範圍。" + +#: lib/php/monica/checker.inc.php:2043 lib/php/monica/checker.inc.php:2299 +#, c-format +msgid "This preference domain is too long. (Max. length %d)" +msgstr "偏好適用範圍太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2063 +msgid "Please fill in the preference name." +msgstr "請填上偏好的名稱。" + +#: lib/php/monica/checker.inc.php:2067 +#, c-format +msgid "This preference name is too long. (Max. length %d)" +msgstr "偏好名稱太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2086 +msgid "Please fill in the preference value." +msgstr "請填上偏好的值。" + +#: lib/php/monica/checker.inc.php:2090 +#, c-format +msgid "This preference value is too long. (Max. length %d)" +msgstr "偏好值太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2119 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "已有同一使用者偏好,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:2167 +msgid "Please select the request type." +msgstr "請選擇申請類別。" + +#: lib/php/monica/checker.inc.php:2173 +msgid "This option is invalid. Please select a proper request type." +msgstr "申請類別選項無效,請由表上選擇適當的申請類別。" + +#: lib/php/monica/checker.inc.php:2194 +msgid "You must choose anonymous for join requests." +msgstr "加入申請不可具名。" + +#: lib/php/monica/checker.inc.php:2197 +msgid "You cannot choose anonymous for non-join requests." +msgstr "非加入申請必須具名。" + +#: lib/php/monica/checker.inc.php:2221 lib/php/monica/form.inc.php:5502 +msgid "Please fill in the request arguments list here." +msgstr "請填上備註資料。" + +#: lib/php/monica/checker.inc.php:2229 +#, c-format +msgid "This request arguments list is too long. (Max. length %d)" +msgstr "申請備註資料太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2349 +msgid "Please fill in the number of rows per page." +msgstr "請填上每頁顯示筆數。" + +#: lib/php/monica/checker.inc.php:2353 +#, c-format +msgid "This number of rows per page is too long. (Max. length %d)" +msgstr "每頁顯示筆數太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2358 +msgid "Please fill in a positive integer number of rows per page." +msgstr "每頁顯示筆數請填正整數。" + +#: lib/php/monica/checker.inc.php:2362 lib/php/monica/checker.inc.php:2372 +#, c-format +msgid "" +"The number of rows per page is too small. Please fill in a larger number of " +"rows per page between %d and %d." +msgstr "每頁顯示筆數太小了,請設定在 %d 到 %d 之間。" + +#: lib/php/monica/checker.inc.php:2376 +#, c-format +msgid "" +"The number of rows per page is too large. Please fill in a smaller number " +"of rows per page between %d and %d." +msgstr "每頁顯示筆數太大了,請設定在 %d 到 %d 之間。" + +#: lib/php/monica/checker.inc.php:2443 +msgid "Please fill in your user ID." +msgstr "請填上你的帳號。" + +#: lib/php/monica/checker.inc.php:2451 lib/php/monica/checker.inc.php:2458 +#: lib/php/monica/checker.inc.php:2475 lib/php/monica/checker.inc.php:2508 +#: lib/php/monica/checker.inc.php:2540 lib/php/monica/checker.inc.php:2548 +#: lib/php/monica/checker.inc.php:2558 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "登入錯誤,使用者代號或密碼有誤。" + +#: lib/php/monica/checker.inc.php:2495 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "帳號停用中,請洽系統管理員。" + +#: lib/php/monica/checker.inc.php:2531 +msgid "Please fill in your password." +msgstr "請填上你的密碼。" + +#: lib/php/monica/checker.inc.php:2581 +msgid "You are not an administrator so may not log in here." +msgstr "非管理員勿入。" + +#: lib/php/monica/checker.inc.php:2600 +msgid "You are an administrator so may not log in here." +msgstr "管理人員勿入。" + +#: lib/php/monica/checker.inc.php:2751 +msgid "Please fill in the code." +msgstr "請填上代碼。" + +#: lib/php/monica/checker.inc.php:2755 +#, c-format +msgid "You must fill in a %d-letters code." +msgstr "代碼限為兩個字母。" + +#: lib/php/monica/checker.inc.php:2760 +msgid "You can only use upper letters and for the code." +msgstr "代碼限用大寫英文字母。" + +#: lib/php/monica/checker.inc.php:2772 +msgid "This code is duplicated. You cannot create a duplicated one." +msgstr "代碼重複,請勿重複設定。" + +#: lib/php/monica/checker.inc.php:2790 +msgid "Please fill in the country name." +msgstr "請填上國名。" + +#: lib/php/monica/checker.inc.php:2794 +#, c-format +msgid "This country name is too long. (Max. length %d)" +msgstr "國名太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2822 lib/php/monica/checker.inc.php:2841 +msgid "Please select a parent category." +msgstr "請選擇所屬的大類。" + +#: lib/php/monica/checker.inc.php:2828 +msgid "This option is invalid. Please select a proper parent category." +msgstr "大類選項無效,請由表上選擇適當的大類。" + +#: lib/php/monica/checker.inc.php:2845 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "查無此大類,請重新選擇。" + +#: lib/php/monica/checker.inc.php:2850 +msgid "A category cannot belong to itself. Please select another one." +msgstr "分類不可屬於自己本身,請重新選擇。" + +#: lib/php/monica/checker.inc.php:2858 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "分類不可屬於自己的子類,請重新選擇。" + +#: lib/php/monica/checker.inc.php:2876 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "「 index 」為目錄檔 index.html 專用,代號不可設為「 index 」。" + +#: lib/php/monica/checker.inc.php:2894 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "已有同一分類,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:2941 +msgid "Please fill in the URL.." +msgstr "請填上網址。" + +#: lib/php/monica/checker.inc.php:2945 +#, c-format +msgid "This URL. is too long. (Max. length %d)" +msgstr "網址太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2950 +msgid "Please fill in a valid URL.." +msgstr "請填上正確網址。" + +#: lib/php/monica/checker.inc.php:2962 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "已有同一相關連結,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:2967 +msgid "This URL. is not reachable. Check if there is any typo in it." +msgstr "這個網址連不上,請檢查有沒有拼錯。" + +#: lib/php/monica/checker.inc.php:2984 lib/php/monica/form.inc.php:3261 +msgid "Fill in the description here." +msgstr "請填上說明。" + +#: lib/php/monica/checker.inc.php:2988 +msgid "Please fill in the description." +msgstr "請填上說明。" + +#: lib/php/monica/checker.inc.php:2992 +#, c-format +msgid "This description is too long. (Max. length %d)" +msgstr "說明太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:3012 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "分類重複,請勿重複設定。。" + +#: lib/php/monica/checker.inc.php:3016 lib/php/monica/checker.inc.php:3072 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: lib/php/monica/checker.inc.php:3022 lib/php/monica/checker.inc.php:3068 +msgid "Please select a category." +msgstr "請選擇分類。" + +#: lib/php/monica/checker.inc.php:3090 +msgid "Please select a related link." +msgstr "請選擇相關連結。" + +#: lib/php/monica/checker.inc.php:3094 +msgid "This link does not exist anymore. Please select another one." +msgstr "查無此相關連結,請重新選擇。" + +#: lib/php/monica/checker.inc.php:3113 +msgid "" +"This link categorization already exists. You cannot create a duplicated one." +msgstr "已有同一連結分類資料,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:3154 +msgid "Please select the type." +msgstr "請選擇類型。" + +#: lib/php/monica/checker.inc.php:3158 +msgid "This type does not exist anymore. Please select another one." +msgstr "查無此類型,請重新選擇。" + +#: lib/php/monica/checker.inc.php:3185 lib/php/monica/list.inc.php:961 +msgid "Please fill in your query." +msgstr "請填上查詢的內容。" + +#: lib/php/monica/checker.inc.php:3210 +msgid "Please submit the picture." +msgstr "請上傳圖檔。" + +#: lib/php/monica/checker.inc.php:3237 lib/php/monica/checker.inc.php:3328 +msgid "Please fill in the resize ratio." +msgstr "請填上縮放比例。" + +#: lib/php/monica/checker.inc.php:3305 +msgid "Please specify a valid picture." +msgstr "您上傳的不是圖檔,請重新上傳圖檔。" + +#: lib/php/monica/chkfunc.inc.php:156 lib/php/monica/chkfunc.inc.php:160 +#: lib/php/monica/chkfunc.inc.php:163 lib/php/monica/chkfunc.inc.php:166 +msgid "Please select a legal year." +msgstr "請選一個正確的年份。" + +#: lib/php/monica/chkfunc.inc.php:171 lib/php/monica/chkfunc.inc.php:175 +#: lib/php/monica/chkfunc.inc.php:178 +msgid "Please select a legal month." +msgstr "請選一個正確的月份。" + +#: lib/php/monica/chkfunc.inc.php:183 lib/php/monica/chkfunc.inc.php:187 +#: lib/php/monica/chkfunc.inc.php:193 +msgid "Please select a legal day." +msgstr "請選一個正確的日期。" + +#: lib/php/monica/chkwrite.inc.php:27 +#, c-format +msgid "%s: It is not a file." +msgstr "%s: 這不是檔案。" + +#: lib/php/monica/chkwrite.inc.php:32 +#, c-format +msgid "%s: You have no permission to overwrite this file." +msgstr "%s: 存檔的權限不足,無法存檔。" + +#: lib/php/monica/chkwrite.inc.php:45 +#, c-format +msgid "%s: You cannot create anything under the root directory." +msgstr "%s: 不可在根目錄下建檔。" + +#: lib/php/monica/chkwrite.inc.php:50 +#, c-format +msgid "" +"%s: One of the parents of this file (%s) is not a directory. You cannot " +"create any new file inside." +msgstr "%s: 路徑中間有一部份( %s )不是目錄,無法往下建檔。" + +#: lib/php/monica/chkwrite.inc.php:55 +#, c-format +msgid "%s: You have no permission to create any file under %s." +msgstr "%s: 權限不足,無法在 %s 建檔。" + +#: lib/php/monica/commtext.inc.php:18 +msgid "(not set)" +msgstr "(未設定)" + +#: lib/php/monica/commtext.inc.php:24 +msgid "(none)" +msgstr "(無)" + +#: lib/php/monica/commtext.inc.php:30 +msgid "(N/A)" +msgstr "(不可考)" + +#: lib/php/monica/commtext.inc.php:36 +msgid "(blank)" +msgstr "(留白)" + +#: lib/php/monica/echoform.inc.php:173 +#, c-format +msgid "%s bytes" +msgstr "%s 位元組" + +#: lib/php/monica/form.inc.php:168 +msgid "Delete it" +msgstr "刪掉" + +#: lib/php/monica/form.inc.php:174 +msgid "Are you sure you want to delete it? It cannot be recovered." +msgstr "你真的要刪掉嗎?資料刪掉就救不回來了。" + +#: lib/php/monica/form.inc.php:188 +msgid "*" +msgstr "" + +#: lib/php/monica/form.inc.php:224 +msgid "This table provides you a form to add a new data record." +msgstr "本表提供建新資料的表單。" + +#: lib/php/monica/form.inc.php:228 +msgid "This table provides you a form to update a current data record." +msgstr "本表提供異動資料的表單。" + +#: lib/php/monica/form.inc.php:232 +msgid "This table provides you a form to delete a data record." +msgstr "本表提供刪除資料的表單。" + +#: lib/php/monica/form.inc.php:281 +msgid "Add a New Data Record" +msgstr "建新資料" + +#: lib/php/monica/form.inc.php:285 +msgid "Update a Current Data Record" +msgstr "異動資料" + +#: lib/php/monica/form.inc.php:289 +msgid "Delete a Data Record" +msgstr "刪除資料" + +#: lib/php/monica/form.inc.php:301 +msgid "Preview it." +msgstr "預覽。" + +#: lib/php/monica/form.inc.php:500 lib/php/monica/form.inc.php:506 +#: lib/php/monica/form.inc.php:691 lib/php/monica/form.inc.php:697 +#: lib/php/monica/preview.inc.php:146 +msgid "Preview" +msgstr "預覽" + +#: lib/php/monica/form.inc.php:501 lib/php/monica/form.inc.php:507 +#: lib/php/monica/form.inc.php:692 lib/php/monica/form.inc.php:698 +msgid "Confirm and submit" +msgstr "確認傳送" + +#: lib/php/monica/form.inc.php:708 lib/php/monica/form.inc.php:1692 +#: lib/php/monica/form.inc.php:1778 lib/php/monica/list.inc.php:1809 +msgid "Delete" +msgstr "刪除" + +#: lib/php/monica/form.inc.php:709 lib/php/monica/form.inc.php:6437 +#: lib/php/monica/form.inc.php:6488 +msgid "Cancel" +msgstr "取消" + +#: lib/php/monica/form.inc.php:1042 lib/php/monica/form.inc.php:3499 +msgid "Set the picture" +msgstr "設定圖片" + +#: lib/php/monica/form.inc.php:1043 lib/php/monica/form.inc.php:3031 +#: lib/php/monica/form.inc.php:3500 +msgid "Delete this picture" +msgstr "刪掉圖片" + +#: lib/php/monica/form.inc.php:1048 lib/php/monica/form.inc.php:1178 +#: lib/php/monica/form.inc.php:3037 lib/php/monica/form.inc.php:3104 +#: lib/php/monica/form.inc.php:3505 lib/php/monica/form.inc.php:3677 +#: lib/php/monica/form.inc.php:6181 lib/php/monica/list.inc.php:814 +msgid "Picture preview" +msgstr "圖片預覽" + +#: lib/php/monica/form.inc.php:1059 lib/php/monica/form.inc.php:1109 +#: lib/php/monica/form.inc.php:1185 +#, c-format +msgid "Picture #%d:" +msgstr "圖片 %d :" + +#: lib/php/monica/form.inc.php:1080 lib/php/monica/form.inc.php:1131 +#: lib/php/monica/form.inc.php:1166 lib/php/monica/form.inc.php:1199 +msgid "Caption:" +msgstr "標題:" + +#: lib/php/monica/form.inc.php:1092 lib/php/monica/form.inc.php:3064 +#: lib/php/monica/form.inc.php:3566 lib/php/monica/form.inc.php:6201 +msgid "Original picture preview" +msgstr "原圖片預覽" + +#: lib/php/monica/form.inc.php:1093 lib/php/monica/form.inc.php:3065 +#: lib/php/monica/form.inc.php:3567 lib/php/monica/form.inc.php:6215 +msgid "New picture preview" +msgstr "新圖片預覽" + +#: lib/php/monica/form.inc.php:1113 lib/php/monica/form.inc.php:1276 +#: lib/php/monica/form.inc.php:1363 lib/php/monica/form.inc.php:1451 +#: lib/php/monica/form.inc.php:1560 lib/php/monica/form.inc.php:1650 +#: lib/php/monica/form.inc.php:1727 lib/php/monica/form.inc.php:1825 +#: lib/php/monica/form.inc.php:1916 lib/php/monica/form.inc.php:1977 +#: lib/php/monica/form.inc.php:2053 lib/php/monica/form.inc.php:2159 +#: lib/php/monica/form.inc.php:2391 lib/php/monica/form.inc.php:2592 +#: lib/php/monica/form.inc.php:2689 lib/php/monica/form.inc.php:2800 +#: lib/php/monica/form.inc.php:2897 lib/php/monica/form.inc.php:2980 +#: lib/php/monica/form.inc.php:3069 lib/php/monica/form.inc.php:3200 +#: lib/php/monica/form.inc.php:3571 lib/php/monica/form.inc.php:3627 +#: lib/php/monica/form.inc.php:3640 lib/php/monica/form.inc.php:3747 +#: lib/php/monica/form.inc.php:4423 lib/php/monica/form.inc.php:4548 +#: lib/php/monica/form.inc.php:4747 lib/php/monica/form.inc.php:4884 +#: lib/php/monica/form.inc.php:5018 lib/php/monica/form.inc.php:6194 +#: lib/php/monica/form.inc.php:6261 +msgid "Original:" +msgstr "原:" + +#: lib/php/monica/form.inc.php:1141 lib/php/monica/form.inc.php:1281 +#: lib/php/monica/form.inc.php:1369 lib/php/monica/form.inc.php:1456 +#: lib/php/monica/form.inc.php:1575 lib/php/monica/form.inc.php:1655 +#: lib/php/monica/form.inc.php:1732 lib/php/monica/form.inc.php:1832 +#: lib/php/monica/form.inc.php:1921 lib/php/monica/form.inc.php:1982 +#: lib/php/monica/form.inc.php:2065 lib/php/monica/form.inc.php:2173 +#: lib/php/monica/form.inc.php:2422 lib/php/monica/form.inc.php:2597 +#: lib/php/monica/form.inc.php:2694 lib/php/monica/form.inc.php:2805 +#: lib/php/monica/form.inc.php:2902 lib/php/monica/form.inc.php:2985 +#: lib/php/monica/form.inc.php:3080 lib/php/monica/form.inc.php:3205 +#: lib/php/monica/form.inc.php:3584 lib/php/monica/form.inc.php:3632 +#: lib/php/monica/form.inc.php:3649 lib/php/monica/form.inc.php:3752 +#: lib/php/monica/form.inc.php:4442 lib/php/monica/form.inc.php:4554 +#: lib/php/monica/form.inc.php:4760 lib/php/monica/form.inc.php:4897 +#: lib/php/monica/form.inc.php:5031 lib/php/monica/form.inc.php:6206 +#: lib/php/monica/form.inc.php:6266 lib/php/monica/form.inc.php:6296 +msgid "New:" +msgstr "新:" + +#: lib/php/monica/form.inc.php:1269 lib/php/monica/form.inc.php:1444 +#: lib/php/monica/form.inc.php:1543 lib/php/monica/form.inc.php:2358 +#: lib/php/monica/form.inc.php:2585 lib/php/monica/form.inc.php:2793 +#: lib/php/monica/form.inc.php:2890 lib/php/monica/form.inc.php:2973 +#: lib/php/monica/form.inc.php:3620 +msgid "Source:" +msgstr "原文:" + +#: lib/php/monica/form.inc.php:1289 lib/php/monica/form.inc.php:1464 +#: lib/php/monica/form.inc.php:1583 lib/php/monica/form.inc.php:2605 +#: lib/php/monica/form.inc.php:2813 lib/php/monica/form.inc.php:2910 +#: lib/php/monica/form.inc.php:2993 +#, c-format +msgid "Please set it from %s." +msgstr "請由%s設定。" + +#: lib/php/monica/form.inc.php:1501 +msgid "Hide" +msgstr "隱藏" + +#: lib/php/monica/form.inc.php:1502 +msgid "Show" +msgstr "秀出" + +#: lib/php/monica/form.inc.php:1691 lib/php/monica/form.inc.php:1777 +#: lib/php/monica/form.inc.php:1887 +msgid "Choose" +msgstr "挑選" + +#: lib/php/monica/form.inc.php:2237 +msgid "Delete this file" +msgstr "刪掉檔案" + +#: lib/php/monica/form.inc.php:2267 lib/php/monica/form.inc.php:2368 +#: lib/php/monica/form.inc.php:2400 lib/php/monica/form.inc.php:2445 +#: lib/php/monica/form.inc.php:2506 +msgid "File name:" +msgstr "檔名:" + +#: lib/php/monica/form.inc.php:2274 lib/php/monica/form.inc.php:2375 +#: lib/php/monica/form.inc.php:2407 lib/php/monica/form.inc.php:2452 +#: lib/php/monica/form.inc.php:2513 +msgid "MIME file type:" +msgstr "MIME 檔案格式:" + +#: lib/php/monica/form.inc.php:2279 lib/php/monica/form.inc.php:2380 +#: lib/php/monica/form.inc.php:2412 lib/php/monica/form.inc.php:2457 +#: lib/php/monica/form.inc.php:2518 +msgid "File size:" +msgstr "檔案大小:" + +#: lib/php/monica/form.inc.php:2430 +#, c-format +msgid "Please upload it from %s." +msgstr "請由%s上傳。" + +#: lib/php/monica/form.inc.php:3128 +msgid "Address:" +msgstr "地址:" + +#: lib/php/monica/form.inc.php:3129 +msgid "Fill in your address here." +msgstr "請填上地址。" + +#: lib/php/monica/form.inc.php:3135 +msgid "Attachment:" +msgstr "附件:" + +#: lib/php/monica/form.inc.php:3139 +msgid "Attachment description:" +msgstr "附件說明:" + +#: lib/php/monica/form.inc.php:3158 lib/php/monica/form.inc.php:3171 +msgid "Content:" +msgstr "內文:" + +#: lib/php/monica/form.inc.php:3165 +msgid "City:" +msgstr "城市:" + +#: lib/php/monica/form.inc.php:3187 lib/php/monica/form.inc.php:3199 +#: lib/php/monica/form.inc.php:3217 lib/php/monica/form.inc.php:3241 +msgid "Country:" +msgstr "國家:" + +#: lib/php/monica/form.inc.php:3229 +msgid "Created:" +msgstr "建檔日期:" + +#: lib/php/monica/form.inc.php:3235 +msgid "Created by:" +msgstr "建檔者:" + +#: lib/php/monica/form.inc.php:3247 +msgid "Date:" +msgstr "日期:" + +#: lib/php/monica/form.inc.php:3253 lib/php/monica/form.inc.php:4292 +#: lib/php/monica/form.inc.php:4295 lib/php/monica/list.inc.php:310 +msgid "Disabled?" +msgstr "停用?" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 lib/php/monica/list.inc.php:2020 +msgid "Disabled" +msgstr "停用" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 +msgid "Enabled" +msgstr "未停用" + +#: lib/php/monica/form.inc.php:3254 +msgid "Disable it." +msgstr "停掉。" + +#: lib/php/monica/form.inc.php:3260 lib/php/monica/form.inc.php:4675 +msgid "Description:" +msgstr "說明:" + +#: lib/php/monica/form.inc.php:3267 +msgid "E-mail:" +msgstr "E-mail:" + +#: lib/php/monica/form.inc.php:3273 +msgid "Fax:" +msgstr "傳真:" + +#: lib/php/monica/form.inc.php:3279 +msgid "Group:" +msgstr "群組:" + +#: lib/php/monica/form.inc.php:3285 lib/php/monica/form.inc.php:5559 +#: lib/php/monica/form.inc.php:5765 lib/php/monica/form.inc.php:5923 +#: lib/php/monica/form.inc.php:6016 +msgid "Hide?" +msgstr "隱藏?" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it" +msgstr "隱藏起來" + +#: lib/php/monica/form.inc.php:3286 +msgid "Show it" +msgstr "秀出來" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it currently." +msgstr "暫勿秀出。" + +#: lib/php/monica/form.inc.php:3292 +msgid "Host:" +msgstr "主機:" + +#: lib/php/monica/form.inc.php:3298 lib/php/monica/list.inc.php:314 +msgid "HTML?" +msgstr "HTML ?" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2948 +#: lib/php/monica/list.inc.php:3062 +msgid "HTML" +msgstr "HTML" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2949 +#: lib/php/monica/list.inc.php:3063 +msgid "Plain text" +msgstr "純文字" + +#: lib/php/monica/form.inc.php:3299 +msgid "The submitted content is HTML." +msgstr "以上內文為 HTML 格式。" + +#: lib/php/monica/form.inc.php:3305 lib/php/monica/form.inc.php:5553 +#: lib/php/monica/form.inc.php:6092 +msgid "ID.:" +msgstr "代號:" + +#: lib/php/monica/form.inc.php:3311 +msgid "Introduction:" +msgstr "簡介:" + +#: lib/php/monica/form.inc.php:3312 +msgid "Fill in the introduction here." +msgstr "請填上簡介。" + +#: lib/php/monica/form.inc.php:3318 +msgid "IP:" +msgstr "IP :" + +#: lib/php/monica/form.inc.php:3324 +msgid "Keywords:" +msgstr "關鍵字:" + +#: lib/php/monica/form.inc.php:3330 +msgid "Language:" +msgstr "語言:" + +#: lib/php/monica/form.inc.php:3355 +msgid "Name:" +msgstr "名稱:" + +#: lib/php/monica/form.inc.php:3365 lib/php/monica/form.inc.php:6010 +msgid "Order:" +msgstr "次序:" + +#: lib/php/monica/form.inc.php:3371 +msgid "Organization:" +msgstr "所屬單位:" + +#: lib/php/monica/form.inc.php:3377 +msgid "Parent category:" +msgstr "大類:" + +#: lib/php/monica/form.inc.php:3378 +msgid "At the very top" +msgstr "最上層" + +#: lib/php/monica/form.inc.php:3391 lib/php/monica/form.inc.php:3428 +#: lib/php/monica/form.inc.php:3468 lib/php/monica/form.inc.php:4330 +#: lib/php/monica/form.inc.php:6380 +msgid "Password:" +msgstr "密碼:" + +#: lib/php/monica/form.inc.php:3407 lib/php/monica/form.inc.php:3444 +msgid "Confirm password:" +msgstr "確認密碼:" + +#: lib/php/monica/form.inc.php:3458 +msgid "(Leave them blank if you don't plan to change your password.)" +msgstr "(若你沒有要更改密碼,密碼欄請留白。)" + +#: lib/php/monica/form.inc.php:3484 +msgid "Page path:" +msgstr "網頁路徑:" + +#: lib/php/monica/form.inc.php:3490 +msgid "PDF. file:" +msgstr "PDF. 檔:" + +#: lib/php/monica/form.inc.php:3508 lib/php/monica/form.inc.php:3570 +#: lib/php/monica/form.inc.php:3680 lib/php/monica/form.inc.php:6169 +#: lib/php/monica/form.inc.php:6193 +msgid "Picture:" +msgstr "圖片:" + +#: lib/php/monica/form.inc.php:3531 lib/php/monica/form.inc.php:3615 +#: lib/php/monica/form.inc.php:3619 lib/php/monica/form.inc.php:3693 +msgid "Pic. caption:" +msgstr "圖片標題:" + +#: lib/php/monica/form.inc.php:3538 lib/php/monica/form.inc.php:3639 +#: lib/php/monica/form.inc.php:3699 +msgid "Pic. position:" +msgstr "圖片位置:" + +#: lib/php/monica/form.inc.php:3718 lib/php/monica/form.inc.php:3746 +#: lib/php/monica/form.inc.php:3780 +msgid "Pinyin:" +msgstr "拼音:" + +#: lib/php/monica/form.inc.php:3722 lib/php/monica/form.inc.php:3756 +msgid "Please fill in the Chinese first." +msgstr "請先填上中文。" + +#: lib/php/monica/form.inc.php:3801 +msgid "Subcategory:" +msgid_plural "Subcategories:" +msgstr[0] "子類:" + +#: lib/php/monica/form.inc.php:3823 +msgid "Script:" +msgstr "程式:" + +#: lib/php/monica/form.inc.php:3829 +msgid "S/N:" +msgstr "編號:" + +#: lib/php/monica/form.inc.php:3835 +msgid "Street:" +msgstr "街號:" + +#: lib/php/monica/form.inc.php:3841 +msgid "Subject:" +msgstr "主題:" + +#: lib/php/monica/form.inc.php:3847 +msgid "Telephone:" +msgstr "電話:" + +#: lib/php/monica/form.inc.php:3853 +msgid "Tel. (cell.):" +msgstr "行動電話:" + +#: lib/php/monica/form.inc.php:3859 +msgid "Tel. (home):" +msgstr "電話(宅):" + +#: lib/php/monica/form.inc.php:3865 +msgid "Tel. (office):" +msgstr "電話(公):" + +#: lib/php/monica/form.inc.php:3871 +msgid "Title:" +msgstr "標題:" + +#: lib/php/monica/form.inc.php:3891 +msgid "Value:" +msgstr "值:" + +#: lib/php/monica/form.inc.php:3897 +msgid "Visits:" +msgstr "上站次數:" + +#: lib/php/monica/form.inc.php:3903 +msgid "Visited:" +msgstr "上站日期:" + +#: lib/php/monica/form.inc.php:3909 +msgid "Updated:" +msgstr "維護日期:" + +#: lib/php/monica/form.inc.php:3915 +msgid "Updated by:" +msgstr "維護者:" + +#: lib/php/monica/form.inc.php:3921 +msgid "URL.:" +msgstr "網址:" + +#: lib/php/monica/form.inc.php:3927 +msgid "Zip code:" +msgstr "郵遞區號:" + +#: lib/php/monica/form.inc.php:4151 +msgid "Delete this user account" +msgstr "刪掉帳號" + +#: lib/php/monica/form.inc.php:4157 +msgid "This table provides you a form to add a new user account." +msgstr "本表提供建新帳號的表單。" + +#: lib/php/monica/form.inc.php:4161 +msgid "This table provides you a form to update a current user account." +msgstr "本表提供設定帳號的表單。" + +#: lib/php/monica/form.inc.php:4165 +msgid "This table provides you a form to delete a user account." +msgstr "本表提供刪除帳號的表單。" + +#: lib/php/monica/form.inc.php:4192 +msgid "Add a New User Account" +msgstr "建新帳號" + +#: lib/php/monica/form.inc.php:4196 +msgid "Update a Current User Account" +msgstr "設定帳號" + +#: lib/php/monica/form.inc.php:4200 +msgid "Delete a User Account" +msgstr "刪除帳號" + +#: lib/php/monica/form.inc.php:4213 +msgid "This is a super-user. You can only change parts of her infomation." +msgstr "這個人是總管理員,你只能設定她部份的資料。" + +#: lib/php/monica/form.inc.php:4220 +msgid "" +"This user has a datum. It cannot be deleted. To delete the user, its datum " +"must first be deleted." +msgid_plural "" +"This user has data. It cannot be deleted. To delete the user, all of its " +"data must first be deleted." +msgstr[0] "本帳號下有資料,不可直接刪除。要刪除帳號,請先刪除其下的資料。" + +#: lib/php/monica/form.inc.php:4282 +msgid "Administrator?" +msgstr "網站管理員?" + +#: lib/php/monica/form.inc.php:4283 +msgid "Administrator" +msgstr "網站管理員" + +#: lib/php/monica/form.inc.php:4283 +msgid "Non-administrator" +msgstr "普通使用者" + +#: lib/php/monica/form.inc.php:4296 +msgid "Disable this user account." +msgstr "帳號停用。" + +#: lib/php/monica/form.inc.php:4305 lib/php/monica/form.inc.php:4307 +#: lib/php/monica/form.inc.php:6372 +msgid "User ID.:" +msgstr "使用者代號:" + +#: lib/php/monica/form.inc.php:4314 +msgid "Pref. language:" +msgstr "語言偏好:" + +#: lib/php/monica/form.inc.php:4320 +msgid "Full name:" +msgstr "姓名:" + +#: lib/php/monica/form.inc.php:4348 lib/php/monica/form.inc.php:4400 +#: lib/php/monica/form.inc.php:4422 lib/php/monica/form.inc.php:4496 +#: lib/php/monica/form.inc.php:4962 lib/php/monica/form.inc.php:5001 +#: lib/php/monica/form.inc.php:5017 lib/php/monica/form.inc.php:5069 +msgid "Belonging to:" +msgstr "隸屬群組:" + +#: lib/php/monica/form.inc.php:4539 lib/php/monica/form.inc.php:4547 +#: lib/php/monica/form.inc.php:4574 +msgid "Fail logins:" +msgstr "登入失敗:" + +#: lib/php/monica/form.inc.php:4551 lib/php/monica/form.inc.php:4578 +msgid "(Locked)" +msgstr "(鎖住)" + +#: lib/php/monica/form.inc.php:4557 +msgid "Reset the counter and activate the account" +msgstr "歸零並重啟帳號。" + +#: lib/php/monica/form.inc.php:4603 +msgid "Delete this group" +msgstr "刪掉群組" + +#: lib/php/monica/form.inc.php:4609 +msgid "This table provides you a form to add a new group." +msgstr "本表提供建新群組的表單。" + +#: lib/php/monica/form.inc.php:4613 +msgid "This table provides you a form to update a current group." +msgstr "本表提供設定群組的表單。" + +#: lib/php/monica/form.inc.php:4617 +msgid "This table provides you a form to delete a group." +msgstr "本表提供刪除群組的表單。" + +#: lib/php/monica/form.inc.php:4642 +msgid "Add a New Group" +msgstr "建新群組" + +#: lib/php/monica/form.inc.php:4646 +msgid "Update a Current Group" +msgstr "設定群組" + +#: lib/php/monica/form.inc.php:4650 +msgid "Delete a Group" +msgstr "刪除群組" + +#: lib/php/monica/form.inc.php:4657 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "這是最高管理員的群組,你只能設定它部份的資料。" + +#: lib/php/monica/form.inc.php:4666 lib/php/monica/form.inc.php:4668 +msgid "Group ID.:" +msgstr "群組代號:" + +#: lib/php/monica/form.inc.php:4681 +msgid "Add a user" +msgstr "增加成員" + +#: lib/php/monica/form.inc.php:4688 lib/php/monica/form.inc.php:4728 +#: lib/php/monica/form.inc.php:4746 lib/php/monica/form.inc.php:4799 +msgid "User member:" +msgid_plural "User members:" +msgstr[0] "使用者成員:" + +#: lib/php/monica/form.inc.php:4819 lib/php/monica/form.inc.php:4956 +msgid "Add a group" +msgstr "增加群組" + +#: lib/php/monica/form.inc.php:4826 lib/php/monica/form.inc.php:4866 +#: lib/php/monica/form.inc.php:4883 lib/php/monica/form.inc.php:4936 +msgid "Group member:" +msgid_plural "Group members:" +msgstr[0] "群組成員:" + +#: lib/php/monica/form.inc.php:5103 lib/php/monica/form.inc.php:5178 +msgid "Delete this membership record" +msgstr "刪掉這筆成員關係" + +#: lib/php/monica/form.inc.php:5109 lib/php/monica/form.inc.php:5184 +msgid "This table provides you a form to add a new membership record." +msgstr "本表提供建新成員關係的表單。" + +#: lib/php/monica/form.inc.php:5113 lib/php/monica/form.inc.php:5188 +msgid "This table provides you a form to change a current membership record." +msgstr "本表提供變更成員關係的表單。" + +#: lib/php/monica/form.inc.php:5117 lib/php/monica/form.inc.php:5192 +msgid "This table provides you a form to delete a membership record." +msgstr "本表提供刪除成員關係的表單。" + +#: lib/php/monica/form.inc.php:5140 +msgid "Add a New User Membership Record" +msgstr "建新使用者成員關係" + +#: lib/php/monica/form.inc.php:5144 +msgid "Change a Current User Membership Record" +msgstr "變更使用者成員關係" + +#: lib/php/monica/form.inc.php:5148 +msgid "Delete a User Membership Record" +msgstr "刪除使用者成員關係" + +#: lib/php/monica/form.inc.php:5158 lib/php/monica/form.inc.php:5233 +msgid "Member:" +msgstr "成員:" + +#: lib/php/monica/form.inc.php:5215 +msgid "Add a New Group Membership Record" +msgstr "建新群組成員關係" + +#: lib/php/monica/form.inc.php:5219 +msgid "Change a Current Group Membership Record" +msgstr "變更群組成員關係" + +#: lib/php/monica/form.inc.php:5223 +msgid "Delete a Group Membership Record" +msgstr "刪除群組成員關係" + +#: lib/php/monica/form.inc.php:5253 +msgid "Delete this user preference" +msgstr "刪掉這筆使用者偏好" + +#: lib/php/monica/form.inc.php:5259 +msgid "This table provides you a form to add a new user preference." +msgstr "本表提供建新使用者偏好的表單。" + +#: lib/php/monica/form.inc.php:5263 +msgid "This table provides you a form to modify a current user preference." +msgstr "本表提供修改使用者偏好的表單。" + +#: lib/php/monica/form.inc.php:5267 +msgid "This table provides you a form to delete a user preference." +msgstr "本表提供刪除使用者偏好的表單。" + +#: lib/php/monica/form.inc.php:5290 +msgid "Add a New User Preference" +msgstr "建新使用者偏好" + +#: lib/php/monica/form.inc.php:5294 +msgid "Modify a Current User Preference" +msgstr "修改使用者偏好" + +#: lib/php/monica/form.inc.php:5298 +msgid "Delete a User Preference" +msgstr "刪除使用者偏好" + +#: lib/php/monica/form.inc.php:5308 lib/php/monica/form.inc.php:5494 +msgid "User:" +msgstr "使用者:" + +#: lib/php/monica/form.inc.php:5309 lib/php/monica/list.inc.php:2588 +msgid "Everyone" +msgstr "所有人" + +#: lib/php/monica/form.inc.php:5315 +msgid "Domain:" +msgstr "適用範圍:" + +#: lib/php/monica/form.inc.php:5316 lib/php/monica/list.inc.php:2592 +msgid "Everywhere" +msgstr "所有地方" + +#: lib/php/monica/form.inc.php:5336 +msgid "Delete this script privilege record" +msgstr "刪掉這筆程式權限資料" + +#: lib/php/monica/form.inc.php:5342 +msgid "This table provides you a form to add a new script privilege record." +msgstr "本表提供建新程式權限資料的表單。" + +#: lib/php/monica/form.inc.php:5346 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "本表提供變更程式權限資料的表單。" + +#: lib/php/monica/form.inc.php:5350 +msgid "This table provides you a form to delete a script privilege record." +msgstr "本表提供刪除程式權限資料的表單。" + +#: lib/php/monica/form.inc.php:5373 +msgid "Add a New Script Privilege Record" +msgstr "建新程式權限資料" + +#: lib/php/monica/form.inc.php:5377 +msgid "Change a Current Script Privilege Record" +msgstr "變更程式權限資料" + +#: lib/php/monica/form.inc.php:5381 +msgid "Delete a Script Privilege Record" +msgstr "刪除程式權限資料" + +#: lib/php/monica/form.inc.php:5391 +msgid "Privilege:" +msgstr "權限:" + +#: lib/php/monica/form.inc.php:5413 +msgid "Delete this user request" +msgstr "刪掉這筆使用者申請" + +#: lib/php/monica/form.inc.php:5419 +msgid "This table provides you a form to add a new user request." +msgstr "本表提供建新使用者申請的表單。" + +#: lib/php/monica/form.inc.php:5423 +msgid "This table provides you a form to update a current user request." +msgstr "本表提供更新使用者申請的表單。" + +#: lib/php/monica/form.inc.php:5427 +msgid "This table provides you a form to delete a user request." +msgstr "本表提供刪除使用者申請的表單。" + +#: lib/php/monica/form.inc.php:5450 +msgid "Add a New User Request" +msgstr "建新使用者申請" + +#: lib/php/monica/form.inc.php:5454 +msgid "Update a Current User Request" +msgstr "更新使用者申請" + +#: lib/php/monica/form.inc.php:5458 +msgid "Delete a User Request" +msgstr "刪除使用者申請" + +#: lib/php/monica/form.inc.php:5466 +msgid "Join" +msgstr "加入" + +#: lib/php/monica/form.inc.php:5470 +msgid "Change e-mail" +msgstr "變更 E-mail" + +#: lib/php/monica/form.inc.php:5474 +msgid "Reset password" +msgstr "重設密碼" + +#: lib/php/monica/form.inc.php:5482 +msgid "Expiration:" +msgstr "到期日:" + +#: lib/php/monica/form.inc.php:5488 lib/php/monica/form.inc.php:6450 +msgid "Type:" +msgstr "類型:" + +#: lib/php/monica/form.inc.php:5495 +msgid "Anonymous" +msgstr "未具名" + +#: lib/php/monica/form.inc.php:5501 +msgid "Arguments:" +msgstr "備註資料:" + +#: lib/php/monica/form.inc.php:5519 +msgid "Delete this category" +msgstr "刪掉這個分類" + +#: lib/php/monica/form.inc.php:5525 +msgid "This table provides you a form to add a new category." +msgstr "本表提供建新分類的表單。" + +#: lib/php/monica/form.inc.php:5529 +msgid "This table provides you a form to edit a current category." +msgstr "本表提供編輯分類的表單。" + +#: lib/php/monica/form.inc.php:5533 +msgid "This table provides you a form to delete a category." +msgstr "本表提供刪除分類的表單。" + +#: lib/php/monica/form.inc.php:5543 +msgid "" +"This category has a subcategory. It cannot be deleted. To delete the " +"category, its subcategory must first be deleted." +msgid_plural "" +"This category has subcategories. It cannot be deleted. To delete the " +"category, all of its subcategories must first be deleted." +msgstr[0] "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: lib/php/monica/form.inc.php:5560 +msgid "Hide this category" +msgstr "隱藏本類" + +#: lib/php/monica/form.inc.php:5560 +msgid "Show this category" +msgstr "秀出本類" + +#: lib/php/monica/form.inc.php:5560 +msgid "Hide this category currently." +msgstr "暫勿秀出本類。" + +#: lib/php/monica/form.inc.php:5577 +msgid "Delete this categorization record" +msgstr "刪掉這筆分類資料" + +#: lib/php/monica/form.inc.php:5583 +msgid "This table provides you a form to add a new categorization record." +msgstr "本表提供建新分類資料的表單。" + +#: lib/php/monica/form.inc.php:5587 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "本表提供變更分類資料的表單。" + +#: lib/php/monica/form.inc.php:5591 +msgid "This table provides you a form to delete a categorization record." +msgstr "本表提供刪除分類資料的表單。" + +#: lib/php/monica/form.inc.php:5636 +msgid "Add a New Link Category" +msgstr "建新連結分類" + +#: lib/php/monica/form.inc.php:5640 +msgid "Edit a Current Link Category" +msgstr "編輯連結分類" + +#: lib/php/monica/form.inc.php:5644 +msgid "Delete a Link Category" +msgstr "刪除連結分類" + +#: lib/php/monica/form.inc.php:5654 +msgid "" +"This category has a link. It cannot be deleted. To delete the category, " +"its link must first be deleted." +msgid_plural "" +"This category has links. It cannot be deleted. To delete the category, all " +"of its links must first be deleted." +msgstr[0] "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: lib/php/monica/form.inc.php:5673 lib/php/monica/form.inc.php:5837 +msgid "Link:" +msgid_plural "Links:" +msgstr[0] "連結:" + +#: lib/php/monica/form.inc.php:5710 +msgid "Delete this related link" +msgstr "刪掉這筆相關連結" + +#: lib/php/monica/form.inc.php:5716 +msgid "This table provides you a form to add a new related link." +msgstr "本表提供建新相關連結的表單。" + +#: lib/php/monica/form.inc.php:5720 +msgid "This table provides you a form to edit a current related link." +msgstr "本表提供編輯相關連結的表單。" + +#: lib/php/monica/form.inc.php:5724 +msgid "This table provides you a form to delete a related link." +msgstr "本表提供刪除相關連結的表單。" + +#: lib/php/monica/form.inc.php:5747 +msgid "Add a New Related Link" +msgstr "建新相關連結" + +#: lib/php/monica/form.inc.php:5751 +msgid "Edit a Current Related Link" +msgstr "編輯相關連結" + +#: lib/php/monica/form.inc.php:5755 +msgid "Delete a Related Link" +msgstr "刪除相關連結" + +#: lib/php/monica/form.inc.php:5766 +msgid "Hide this link" +msgstr "隱藏本連結" + +#: lib/php/monica/form.inc.php:5766 lib/php/monica/form.inc.php:5924 +msgid "Show this page" +msgstr "秀出本頁" + +#: lib/php/monica/form.inc.php:5766 +msgid "Hide this related link currently." +msgstr "暫勿秀出本相關連結。" + +#: lib/php/monica/form.inc.php:5773 lib/php/monica/form.inc.php:5830 +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "分類:" + +#: lib/php/monica/form.inc.php:5812 +msgid "Add a New Link Categorization Record" +msgstr "建新連結分類資料" + +#: lib/php/monica/form.inc.php:5816 +msgid "Change a Current Link Categorization Record" +msgstr "變更連結分類資料" + +#: lib/php/monica/form.inc.php:5820 +msgid "Delete a Link Categorization Record" +msgstr "刪除連結分類資料" + +#: lib/php/monica/form.inc.php:5860 +msgid "Delete this page" +msgstr "刪掉這一頁" + +#: lib/php/monica/form.inc.php:5866 +msgid "This table provides you a form to write a new page." +msgstr "本表提供撰寫網頁的表單。" + +#: lib/php/monica/form.inc.php:5870 +msgid "This table provides you a form to edit a current page." +msgstr "本表提供編輯網頁的表單。" + +#: lib/php/monica/form.inc.php:5874 +msgid "This table provides you a form to delete a page." +msgstr "本表提供刪除網頁的表單。" + +#: lib/php/monica/form.inc.php:5899 +msgid "Write a New Page" +msgstr "撰寫網頁" + +#: lib/php/monica/form.inc.php:5903 +msgid "Edit a Current Page" +msgstr "編輯網頁" + +#: lib/php/monica/form.inc.php:5907 +msgid "Delete a Page" +msgstr "刪除網頁" + +#: lib/php/monica/form.inc.php:5915 +msgid "Preview this page." +msgstr "預覽本頁。" + +#: lib/php/monica/form.inc.php:5924 +msgid "Hide this page" +msgstr "隱藏本頁" + +#: lib/php/monica/form.inc.php:5924 +msgid "Hide this page currently." +msgstr "暫勿秀出本頁。" + +#: lib/php/monica/form.inc.php:5947 +msgid "Delete this news article" +msgstr "刪掉這則新聞" + +#: lib/php/monica/form.inc.php:5953 +msgid "This table provides you a form to write a new news article." +msgstr "本表提供撰寫新聞的表單。" + +#: lib/php/monica/form.inc.php:5957 +msgid "This table provides you a form to edit a current news article." +msgstr "本表提供編輯新聞的表單。" + +#: lib/php/monica/form.inc.php:5961 +msgid "This table provides you a form to delete a news article." +msgstr "本表提供刪除新聞的表單。" + +#: lib/php/monica/form.inc.php:5986 +msgid "Write a New News Article" +msgstr "撰寫新聞" + +#: lib/php/monica/form.inc.php:5990 +msgid "Edit a Current News Article" +msgstr "編輯新聞" + +#: lib/php/monica/form.inc.php:5994 +msgid "Delete a News Article" +msgstr "刪除新聞" + +#: lib/php/monica/form.inc.php:6002 +msgid "Preview this news article." +msgstr "預覽這則新聞。" + +#: lib/php/monica/form.inc.php:6017 +msgid "Hide this news article" +msgstr "隱藏這則新聞" + +#: lib/php/monica/form.inc.php:6017 +msgid "Show this news article" +msgstr "秀出這則新聞" + +#: lib/php/monica/form.inc.php:6017 +msgid "Hide this news article currently." +msgstr "暫勿秀出這則新聞。" + +#: lib/php/monica/form.inc.php:6037 +msgid "Delete this country record" +msgstr "刪掉這筆國家資料" + +#: lib/php/monica/form.inc.php:6043 +msgid "This table provides you a form to add a new country record." +msgstr "本表提供建新國家資料的表單。" + +#: lib/php/monica/form.inc.php:6047 +msgid "This table provides you a form to edit a current country record." +msgstr "本表提供編輯國家資料的表單。" + +#: lib/php/monica/form.inc.php:6051 +msgid "This table provides you a form to delete a country record." +msgstr "本表提供刪除國家資料的表單。" + +#: lib/php/monica/form.inc.php:6074 +msgid "Add a New Country Record" +msgstr "建新國家資料" + +#: lib/php/monica/form.inc.php:6078 +msgid "Edit a Current Country Record" +msgstr "編輯國家資料" + +#: lib/php/monica/form.inc.php:6082 +msgid "Delete a Country Record" +msgstr "刪除國家資料" + +#: lib/php/monica/form.inc.php:6098 lib/php/monica/list.inc.php:3391 +msgid "Special?" +msgstr "特殊?" + +#: lib/php/monica/form.inc.php:6099 +msgid "A special record" +msgstr "特殊記錄" + +#: lib/php/monica/form.inc.php:6099 +msgid "A normal country" +msgstr "一般國家" + +#: lib/php/monica/form.inc.php:6099 +msgid "This is a special record." +msgstr "這一筆是特殊記錄。" + +#: lib/php/monica/form.inc.php:6128 +msgid "This table provides you a form to add a new picture." +msgstr "本表提供建新圖片的表單。" + +#: lib/php/monica/form.inc.php:6132 +msgid "This table provides you a form to modify a current picture." +msgstr "本表提供修改圖片的表單。" + +#: lib/php/monica/form.inc.php:6143 +msgid "Upload a New Picture" +msgstr "建新圖片" + +#: lib/php/monica/form.inc.php:6147 +msgid "Modify a Current Picture" +msgstr "修改圖片" + +#: lib/php/monica/form.inc.php:6248 lib/php/monica/form.inc.php:6260 +msgid "Ratio:" +msgstr "比例:" + +#: lib/php/monica/form.inc.php:6285 lib/php/monica/form.inc.php:6295 +msgid "Upload:" +msgstr "上傳:" + +#: lib/php/monica/form.inc.php:6326 +msgid "This table provides you a form to log in." +msgstr "本表提供登入的表單。" + +#: lib/php/monica/form.inc.php:6332 +msgid "Identify Yourself" +msgstr "請出示身份" + +#: lib/php/monica/form.inc.php:6341 lib/php/monica/init.inc.php:505 +msgid "" +"Log-in is temporarily closed for maintainance now. Please come again " +"later. Sorry for the inconvienence." +msgstr "網站維護中,暫請勿入。造成任何不便,敬請見諒。" + +#: lib/php/monica/form.inc.php:6350 +msgid "Log in" +msgstr "登入" + +#: lib/php/monica/form.inc.php:6397 +msgid "Remember me." +msgstr "勿忘我。" + +#: lib/php/monica/form.inc.php:6424 +msgid "Rebuild the Pages" +msgstr "重製網頁" + +#: lib/php/monica/form.inc.php:6433 +msgid "Confirm" +msgstr "確認" + +#: lib/php/monica/form.inc.php:6475 +msgid "Log Out" +msgstr "登出" + +#: lib/php/monica/form.inc.php:6484 +msgid "Log out" +msgstr "登出" + +#: lib/php/monica/form.inc.php:6498 +msgid "Are you sure you want to log out?" +msgstr "你確定要登出嗎?" + +#: lib/php/monica/init.inc.php:114 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" +"抱歉,我們不歡迎加裝 FunWebProduct 外掛(如 Smiley Central 、 PopSwatter 、 " +"Spin4Dough 、 My Mail Signature 、 My Mail Stationery 、 My Mail Stamp 、 " +"Cursor Mania ……等等)的瀏覽器。 FunWebProduct 會重抓你看過的每一頁網頁,造" +"成網站負荷加倍,甚至當機。請先移除 FunWebProduct ,再上來瀏覽。" + +#: lib/php/monica/init.inc.php:503 lib/php/monica/init.inc.php:504 +msgid "Log-In Closed" +msgstr "暫請勿入" + +#: lib/php/monica/init.inc.php:524 lib/php/monica/init.inc.php:525 +msgid "Development Site Closed" +msgstr "研發網站已關閉" + +#: lib/php/monica/init.inc.php:526 +msgid "Development site is closed. Please work on the live site." +msgstr "研發網站已關閉,請勿在此登入。" + +#: lib/php/monica/links.inc.php:271 +msgid "Related Links" +msgstr "相關連結" + +#: lib/php/monica/list.inc.php:130 +msgid "Malformed" +msgstr "格式錯亂" + +#: lib/php/monica/list.inc.php:155 +msgid "OK" +msgstr "好" + +#: lib/php/monica/list.inc.php:155 +msgid "Unreachable" +msgstr "連不上" + +#: lib/php/monica/list.inc.php:290 lib/php/monica/list.inc.php:1534 +#: lib/php/monica/list.inc.php:3642 +msgid "(query phrase)" +msgstr "(檢索字詞)" + +#: lib/php/monica/list.inc.php:300 +msgid "S/N" +msgstr "編號" + +#: lib/php/monica/list.inc.php:301 +msgid "Created" +msgstr "建檔日期" + +#: lib/php/monica/list.inc.php:302 +msgid "Created by" +msgstr "建檔者" + +#: lib/php/monica/list.inc.php:303 +msgid "Updated" +msgstr "維護日期" + +#: lib/php/monica/list.inc.php:304 +msgid "Updated by" +msgstr "維護者" + +#: lib/php/monica/list.inc.php:306 +msgid "Content" +msgstr "內文" + +#: lib/php/monica/list.inc.php:307 +msgid "Category" +msgstr "分類" + +#: lib/php/monica/list.inc.php:308 +msgid "Coverage" +msgstr "涵蓋範圍" + +#: lib/php/monica/list.inc.php:309 +msgid "Date" +msgstr "日期" + +#: lib/php/monica/list.inc.php:311 +msgid "Description" +msgstr "說明" + +#: lib/php/monica/list.inc.php:312 +msgid "E-mail" +msgstr "E-mail" + +#: lib/php/monica/list.inc.php:313 +msgid "Hidden?" +msgstr "隱藏?" + +#: lib/php/monica/list.inc.php:315 +msgid "ID." +msgstr "代號" + +#: lib/php/monica/list.inc.php:316 +msgid "Keywords" +msgstr "關鍵字" + +#: lib/php/monica/list.inc.php:317 +msgid "Name" +msgstr "名稱" + +#: lib/php/monica/list.inc.php:318 +msgid "Order" +msgstr "次序" + +#: lib/php/monica/list.inc.php:319 +msgid "Page path" +msgstr "網頁路徑" + +#: lib/php/monica/list.inc.php:320 +msgid "Picture" +msgstr "圖片" + +#: lib/php/monica/list.inc.php:321 +msgid "Pic. ratio" +msgstr "圖片比例" + +#: lib/php/monica/list.inc.php:322 +msgid "Pic. caption" +msgstr "圖片標題" + +#: lib/php/monica/list.inc.php:323 +msgid "Pic. position" +msgstr "圖片位置" + +#: lib/php/monica/list.inc.php:324 +msgid "Subject" +msgstr "主題" + +#: lib/php/monica/list.inc.php:325 +msgid "Title" +msgstr "標題" + +#: lib/php/monica/list.inc.php:326 +msgid "URL." +msgstr "網址" + +#: lib/php/monica/list.inc.php:327 +msgid "Status (slow)" +msgstr "狀態(慢)" + +#: lib/php/monica/list.inc.php:336 +msgid "Select" +msgstr "選擇" + +#: lib/php/monica/list.inc.php:339 +msgid "Select a Data Record" +msgstr "選擇資料" + +#: lib/php/monica/list.inc.php:343 +msgid "Edit" +msgstr "設定" + +#: lib/php/monica/list.inc.php:345 +msgid "Manage Data" +msgstr "管理資料" + +#: lib/php/monica/list.inc.php:749 +msgid "Nothing found. Please try another query." +msgstr "查無相符的資料,請重新搜尋。" + +#: lib/php/monica/list.inc.php:752 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: lib/php/monica/list.inc.php:759 +#, c-format +msgid "Your query found %s record." +msgid_plural "Your query found %s records." +msgstr[0] "共 %s 筆相符的資料。" + +#: lib/php/monica/list.inc.php:766 +#, c-format +msgid "%s record." +msgid_plural "%s records." +msgstr[0] "共 %s 筆資料。" + +#: lib/php/monica/list.inc.php:775 +#, c-format +msgid "Your query found %s record, listing %s to %s." +msgid_plural "Your query found %s records, listing %s to %s." +msgstr[0] "共 %s 筆相符的資料,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:784 +#, c-format +msgid "%s record, listing %s to %s." +msgid_plural "%s records, listing %s to %s." +msgstr[0] "共 %s 筆資料,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:855 lib/php/monica/list.inc.php:860 +#: lib/php/monica/list.inc.php:869 +#, c-format +msgid "Page number (%s) invalid. Please specify a valid page number." +msgstr "頁數( %s )無效,請設成有效的數字。" + +#: lib/php/monica/list.inc.php:874 +#, c-format +msgid "" +"Page number (%d) out of range. Please specify a number between 1 and %d." +msgstr "頁數( %d )超出範圍,請設在 1 到 %d 之間。" + +#: lib/php/monica/list.inc.php:1138 lib/php/monica/list.inc.php:1151 +#, c-format +msgid "You cannot sort by \"%s\"." +msgstr "無法以 %s 排序。" + +#: lib/php/monica/list.inc.php:1512 +msgid "Search" +msgstr "搜尋" + +#: lib/php/monica/list.inc.php:1610 +msgid "Index" +msgstr "目錄" + +#: lib/php/monica/list.inc.php:1634 +msgid "First" +msgstr "第一頁" + +#: lib/php/monica/list.inc.php:1647 +msgid "Previous" +msgstr "前一頁" + +#: lib/php/monica/list.inc.php:1696 +msgid "Next" +msgstr "下一頁" + +#: lib/php/monica/list.inc.php:1714 +msgid "Last" +msgstr "最末頁" + +#: lib/php/monica/list.inc.php:1736 +msgid "Page:" +msgstr "頁:" + +#: lib/php/monica/list.inc.php:1776 lib/php/monica/list.inc.php:1900 +msgid "Delete the selected items." +msgstr "刪除勾選的項目。" + +#: lib/php/monica/list.inc.php:1805 +msgid "No." +msgstr "編號" + +#: lib/php/monica/list.inc.php:1813 lib/php/monica/list.inc.php:1873 +msgid "View" +msgstr "瀏覽" + +#: lib/php/monica/list.inc.php:1925 +msgid "Set" +msgstr "設定" + +#: lib/php/monica/list.inc.php:1941 +msgid "Rows per page:" +msgstr "每頁顯示筆數:" + +#: lib/php/monica/list.inc.php:1946 +msgid "Display columns:" +msgstr "顯示欄位:" + +#: lib/php/monica/list.inc.php:1976 +msgid "Select a User" +msgstr "選擇帳號" + +#: lib/php/monica/list.inc.php:1977 +msgid "Manage Users" +msgstr "管理帳號" + +#: lib/php/monica/list.inc.php:1982 +msgid "User ID." +msgstr "使用者代號" + +#: lib/php/monica/list.inc.php:1983 +msgid "Full name" +msgstr "姓名" + +#: lib/php/monica/list.inc.php:1984 +msgid "Deleted?" +msgstr "已刪?" + +#: lib/php/monica/list.inc.php:1985 +msgid "Pref. language" +msgstr "語言偏好" + +#: lib/php/monica/list.inc.php:1986 +msgid "Visits" +msgstr "上站次數" + +#: lib/php/monica/list.inc.php:1987 +msgid "Visited" +msgstr "上站日期" + +#: lib/php/monica/list.inc.php:1988 +msgid "IP" +msgstr "IP" + +#: lib/php/monica/list.inc.php:1989 +msgid "Host" +msgstr "主機" + +#: lib/php/monica/list.inc.php:1990 +msgid "From country" +msgstr "上站國家" + +#: lib/php/monica/list.inc.php:1991 +msgid "Fail logins" +msgstr "登入失敗" + +#: lib/php/monica/list.inc.php:2024 +msgid "Deleted" +msgstr "已刪" + +#: lib/php/monica/list.inc.php:2035 +msgid "Add a new user account." +msgstr "建新帳號。" + +#: lib/php/monica/list.inc.php:2045 +msgid "Search for a user:" +msgstr "搜尋使用者:" + +#: lib/php/monica/list.inc.php:2063 +#, c-format +msgid "Your query found %s user." +msgid_plural "Your query found %s users." +msgstr[0] "共 %s 個相符的使用者。" + +#: lib/php/monica/list.inc.php:2070 +#, c-format +msgid "%s user." +msgid_plural "%s users." +msgstr[0] "共 %s 個使用者。" + +#: lib/php/monica/list.inc.php:2079 +#, c-format +msgid "Your query found %s user, listing %s to %s." +msgid_plural "Your query found %s users, listing %s to %s." +msgstr[0] "共 %s 個相符的使用者,列出第 %s 個到第 %s 個。" + +#: lib/php/monica/list.inc.php:2088 +#, c-format +msgid "%s user, listing %s to %s." +msgid_plural "%s users, listing %s to %s." +msgstr[0] "共 %s 個使用者,列出第 %s 個到第 %s 個。" + +#: lib/php/monica/list.inc.php:2107 +msgid "Select a Group" +msgstr "選擇群組" + +#: lib/php/monica/list.inc.php:2108 +msgid "Manage Groups" +msgstr "管理群組" + +#: lib/php/monica/list.inc.php:2113 +msgid "Group ID." +msgstr "群組代號" + +#: lib/php/monica/list.inc.php:2121 +msgid "Add a new group." +msgstr "建新群組。" + +#: lib/php/monica/list.inc.php:2131 +msgid "Search for a group:" +msgstr "搜尋群組:" + +#: lib/php/monica/list.inc.php:2149 +#, c-format +msgid "Your query found %s group." +msgid_plural "Your query found %s groups." +msgstr[0] "共 %s 個相符的群組。" + +#: lib/php/monica/list.inc.php:2156 +#, c-format +msgid "%s group." +msgid_plural "%s groups." +msgstr[0] "共 %s 個群組。" + +#: lib/php/monica/list.inc.php:2165 +#, c-format +msgid "Your query found %s group, listing %s to %s." +msgid_plural "Your query found %s groups, listing %s to %s." +msgstr[0] "共 %s 個相符的群組,列出第 %s 個到第 %s 個。" + +#: lib/php/monica/list.inc.php:2174 +#, c-format +msgid "%s group, listing %s to %s." +msgid_plural "%s groups, listing %s to %s." +msgstr[0] "共 %s 個群組,列出第 %s 個到第 %s 個。" + +#: lib/php/monica/list.inc.php:2194 +msgid "Select a User Membership Record" +msgstr "選擇使用者成員關係" + +#: lib/php/monica/list.inc.php:2195 +msgid "Manage User Membership" +msgstr "管理使用者成員關係" + +#: lib/php/monica/list.inc.php:2200 lib/php/monica/list.inc.php:2323 +msgid "Group" +msgstr "群組" + +#: lib/php/monica/list.inc.php:2201 lib/php/monica/list.inc.php:2324 +msgid "Member" +msgstr "成員" + +#: lib/php/monica/list.inc.php:2244 lib/php/monica/list.inc.php:2375 +msgid "Add a new membership record." +msgstr "建新成員關係。" + +#: lib/php/monica/list.inc.php:2254 lib/php/monica/list.inc.php:2385 +msgid "Search for a membership record:" +msgstr "搜尋成員關係:" + +#: lib/php/monica/list.inc.php:2272 lib/php/monica/list.inc.php:2403 +#, c-format +msgid "Your query found %s membership record." +msgid_plural "Your query found %s membership records." +msgstr[0] "共 %s 筆相符的成員關係。" + +#: lib/php/monica/list.inc.php:2279 lib/php/monica/list.inc.php:2410 +#, c-format +msgid "%s membership record." +msgid_plural "%s membership records." +msgstr[0] "共 %s 筆成員關係。" + +#: lib/php/monica/list.inc.php:2288 lib/php/monica/list.inc.php:2419 +#, c-format +msgid "Your query found %s membership record, listing %s to %s." +msgid_plural "Your query found %s membership records, listing %s to %s." +msgstr[0] "共 %s 筆相符的成員關係,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2297 lib/php/monica/list.inc.php:2428 +#, c-format +msgid "%s membership record, listing %s to %s." +msgid_plural "%s membership records, listing %s to %s." +msgstr[0] "共 %s 筆成員關係,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2317 +msgid "Select a Group Membership Record" +msgstr "選擇群組成員關係" + +#: lib/php/monica/list.inc.php:2318 +msgid "Manage Group Membership" +msgstr "管理群組成員關係" + +#: lib/php/monica/list.inc.php:2448 +msgid "Select a Script Privilege Record" +msgstr "選擇程式權限" + +#: lib/php/monica/list.inc.php:2449 +msgid "Manage Script Privileges" +msgstr "管理程式權限" + +#: lib/php/monica/list.inc.php:2454 +msgid "Script" +msgstr "程式" + +#: lib/php/monica/list.inc.php:2455 +msgid "Privilege" +msgstr "權限" + +#: lib/php/monica/list.inc.php:2493 +msgid "Add a new script privilege record." +msgstr "建新程式權限資料。" + +#: lib/php/monica/list.inc.php:2503 +msgid "Search for a script privilege record:" +msgstr "搜尋程式權限:" + +#: lib/php/monica/list.inc.php:2521 +#, c-format +msgid "Your query found %s script privilege record." +msgid_plural "Your query found %s script privilege records." +msgstr[0] "共 %s 筆相符的程式權限。" + +#: lib/php/monica/list.inc.php:2528 +#, c-format +msgid "%s script privilege record." +msgid_plural "%s script privilege records." +msgstr[0] "共 %s 筆程式權限。" + +#: lib/php/monica/list.inc.php:2537 +#, c-format +msgid "Your query found %s script privilege record, listing %s to %s." +msgid_plural "Your query found %s script privilege records, listing %s to %s." +msgstr[0] "共 %s 筆相符的程式權限,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2546 +#, c-format +msgid "%s script privilege record, listing %s to %s." +msgid_plural "%s script privilege records, listing %s to %s." +msgstr[0] "共 %s 筆程式權限,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2566 +msgid "Select a User Preference" +msgstr "選擇使用者偏好" + +#: lib/php/monica/list.inc.php:2567 +msgid "Manage User Preferences" +msgstr "管理使用者偏好" + +#: lib/php/monica/list.inc.php:2574 lib/php/monica/list.inc.php:2689 +msgid "User" +msgstr "使用者" + +#: lib/php/monica/list.inc.php:2575 +msgid "Domain" +msgstr "適用範圍" + +#: lib/php/monica/list.inc.php:2576 +msgid "Value" +msgstr "值" + +#: lib/php/monica/list.inc.php:2610 +msgid "Add a new user preference." +msgstr "建新使用者偏好。" + +#: lib/php/monica/list.inc.php:2620 +msgid "Search for a user preference:" +msgstr "搜尋使用者偏好:" + +#: lib/php/monica/list.inc.php:2638 +#, c-format +msgid "Your query found %s user preference." +msgid_plural "Your query found %s user preferences." +msgstr[0] "共 %s 筆相符的使用者偏好。" + +#: lib/php/monica/list.inc.php:2645 +#, c-format +msgid "%s user preference." +msgid_plural "%s user preferences." +msgstr[0] "共 %s 筆使用者偏好。" + +#: lib/php/monica/list.inc.php:2654 +#, c-format +msgid "Your query found %s user preference, listing %s to %s." +msgid_plural "Your query found %s user preferences, listing %s to %s." +msgstr[0] "共 %s 筆相符的使用者偏好,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2663 +#, c-format +msgid "%s user preference, listing %s to %s." +msgid_plural "%s user preferences, listing %s to %s." +msgstr[0] "共 %s 筆使用者偏好,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2682 +msgid "Select a User Request" +msgstr "選擇使用者申請" + +#: lib/php/monica/list.inc.php:2683 +msgid "Manage User Requests" +msgstr "管理使用者申請" + +#: lib/php/monica/list.inc.php:2688 +msgid "Type" +msgstr "類別" + +#: lib/php/monica/list.inc.php:2690 +msgid "Arguments" +msgstr "備註資料" + +#: lib/php/monica/list.inc.php:2691 +msgid "Expiration" +msgstr "到期日" + +#: lib/php/monica/list.inc.php:2699 +msgid "Add a new user request." +msgstr "建新使用者申請。" + +#: lib/php/monica/list.inc.php:2709 +msgid "Search for a user request:" +msgstr "搜尋使用者申請:" + +#: lib/php/monica/list.inc.php:2727 +#, c-format +msgid "Your query found %s user request." +msgid_plural "Your query found %s user requests." +msgstr[0] "共 %s 筆相符的使用者申請。" + +#: lib/php/monica/list.inc.php:2734 +#, c-format +msgid "%s user request." +msgid_plural "%s user requests." +msgstr[0] "共 %s 筆使用者申請。" + +#: lib/php/monica/list.inc.php:2743 +#, c-format +msgid "Your query found %s user request, listing %s to %s." +msgid_plural "Your query found %s user requests, listing %s to %s." +msgstr[0] "共 %s 筆相符的使用者申請,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2752 +#, c-format +msgid "%s user request, listing %s to %s." +msgid_plural "%s user requests, listing %s to %s." +msgstr[0] "共 %s 筆使用者申請,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2778 +msgid "Add a new category." +msgstr "建新分類。" + +#: lib/php/monica/list.inc.php:2788 +msgid "Search for a category:" +msgstr "搜尋分類:" + +#: lib/php/monica/list.inc.php:2806 +#, c-format +msgid "Your query found %s category." +msgid_plural "Your query found %s categories." +msgstr[0] "共 %s 類相符的分類。" + +#: lib/php/monica/list.inc.php:2813 +#, c-format +msgid "%s category." +msgid_plural "%s categories." +msgstr[0] "共 %s 類分類。" + +#: lib/php/monica/list.inc.php:2822 +#, c-format +msgid "Your query found %s category, listing %s to %s." +msgid_plural "Your query found %s categories, listing %s to %s." +msgstr[0] "共 %s 類相符的分類,列出第 %s 類到第 %s 類。" + +#: lib/php/monica/list.inc.php:2831 +#, c-format +msgid "%s category, listing %s to %s." +msgid_plural "%s categories, listing %s to %s." +msgstr[0] "共 %s 類分類,列出第 %s 類到第 %s 類。" + +#: lib/php/monica/list.inc.php:2849 +msgid "Add a new categorization record." +msgstr "建新分類資料。" + +#: lib/php/monica/list.inc.php:2859 +msgid "Search for a categorization record:" +msgstr "搜尋分類資料:" + +#: lib/php/monica/list.inc.php:2877 +#, c-format +msgid "Your query found %s categorization record." +msgid_plural "Your query found %s categorization records." +msgstr[0] "共 %s 筆相符的分類資料。" + +#: lib/php/monica/list.inc.php:2884 +#, c-format +msgid "%s categorization record." +msgid_plural "%s categorization records." +msgstr[0] "共 %s 筆分類資料。" + +#: lib/php/monica/list.inc.php:2893 +#, c-format +msgid "Your query found %s categorization record, listing %s to %s." +msgid_plural "Your query found %s categorization records, listing %s to %s." +msgstr[0] "共 %s 筆相符的分類資料,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2902 +#, c-format +msgid "%s categorization record, listing %s to %s." +msgid_plural "%s categorization records, listing %s to %s." +msgstr[0] "共 %s 筆分類資料,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2921 +msgid "Select a Page" +msgstr "選擇網頁" + +#: lib/php/monica/list.inc.php:2922 +msgid "Manage Pages" +msgstr "管理網頁" + +#: lib/php/monica/list.inc.php:2952 lib/php/monica/list.inc.php:3066 +#: lib/php/monica/list.inc.php:3173 lib/php/monica/list.inc.php:3237 +#: lib/php/monica/list.inc.php:3358 +msgid "Hidden" +msgstr "隱藏" + +#: lib/php/monica/list.inc.php:2953 lib/php/monica/list.inc.php:3067 +#: lib/php/monica/list.inc.php:3174 lib/php/monica/list.inc.php:3238 +#: lib/php/monica/list.inc.php:3359 +msgid "Shown" +msgstr "秀出" + +#: lib/php/monica/list.inc.php:2963 +msgid "Write a new page." +msgstr "撰寫網頁。" + +#: lib/php/monica/list.inc.php:2973 +msgid "Search for a page:" +msgstr "搜尋網頁:" + +#: lib/php/monica/list.inc.php:2991 +#, c-format +msgid "Your query found %s page." +msgid_plural "Your query found %s pages." +msgstr[0] "共 %s 頁相符的網頁。" + +#: lib/php/monica/list.inc.php:2998 +#, c-format +msgid "%s page." +msgid_plural "%s pages." +msgstr[0] "共 %s 頁網頁。" + +#: lib/php/monica/list.inc.php:3007 +#, c-format +msgid "Your query found %s page, listing %s to %s." +msgid_plural "Your query found %s pages, listing %s to %s." +msgstr[0] "共 %s 頁相符的網頁,列出第 %s 頁到第 %s 頁。" + +#: lib/php/monica/list.inc.php:3016 +#, c-format +msgid "%s page, listing %s to %s." +msgid_plural "%s pages, listing %s to %s." +msgstr[0] "共 %s 頁網頁,列出第 %s 頁到第 %s 頁。" + +#: lib/php/monica/list.inc.php:3035 +msgid "Select a News Article" +msgstr "選擇新聞" + +#: lib/php/monica/list.inc.php:3036 +msgid "Manage News" +msgstr "管理新聞" + +#: lib/php/monica/list.inc.php:3077 +msgid "Write a new news article." +msgstr "撰寫新聞。" + +#: lib/php/monica/list.inc.php:3087 +msgid "Search for a news article:" +msgstr "搜尋新聞:" + +#: lib/php/monica/list.inc.php:3105 +#, c-format +msgid "Your query found %s news article." +msgid_plural "Your query found %s news articles." +msgstr[0] "共 %s 則相符的新聞。" + +#: lib/php/monica/list.inc.php:3112 +#, c-format +msgid "%s news article." +msgid_plural "%s news articles." +msgstr[0] "共 %s 則新聞。" + +#: lib/php/monica/list.inc.php:3121 +#, c-format +msgid "Your query found %s news article, listing %s to %s." +msgid_plural "Your query found %s news articles, listing %s to %s." +msgstr[0] "共 %s 則相符的新聞,列出第 %s 則到第 %s 則。" + +#: lib/php/monica/list.inc.php:3130 +#, c-format +msgid "%s news article, listing %s to %s." +msgid_plural "%s news articles, listing %s to %s." +msgstr[0] "共 %s 則新聞,列出第 %s 則到第 %s 則。" + +#: lib/php/monica/list.inc.php:3149 +msgid "Select a Link Category" +msgstr "選擇連結分類" + +#: lib/php/monica/list.inc.php:3150 +msgid "Manage Link Categories" +msgstr "管理連結分類" + +#: lib/php/monica/list.inc.php:3197 +msgid "Select a Link" +msgstr "選擇連結" + +#: lib/php/monica/list.inc.php:3198 +msgid "Manage Links" +msgstr "管理連結" + +#: lib/php/monica/list.inc.php:3248 +msgid "Add a new related link." +msgstr "建新相關連結。" + +#: lib/php/monica/list.inc.php:3258 +msgid "Search for a related link:" +msgstr "搜尋相關連結:" + +#: lib/php/monica/list.inc.php:3276 +#, c-format +msgid "Your query found %s related link." +msgid_plural "Your query found %s related links." +msgstr[0] "共 %s 筆相符的相關連結。" + +#: lib/php/monica/list.inc.php:3283 +#, c-format +msgid "%s related link." +msgid_plural "%s related links." +msgstr[0] "共 %s 筆相關連結" + +#: lib/php/monica/list.inc.php:3292 +#, c-format +msgid "Your query found %s related link, listing %s to %s." +msgid_plural "Your query found %s related links, listing %s to %s." +msgstr[0] "共 %s 筆相符的相關連結,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:3301 +#, c-format +msgid "%s related link, listing %s to %s." +msgid_plural "%s related links, listing %s to %s." +msgstr[0] "共 %s 筆相關連結,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:3321 +msgid "Select a Link Categorization Record" +msgstr "選擇連結分類資料" + +#: lib/php/monica/list.inc.php:3322 +msgid "Manage Link Categorization" +msgstr "管理連結分類表" + +#: lib/php/monica/list.inc.php:3327 +msgid "Link" +msgstr "連結" + +#: lib/php/monica/list.inc.php:3383 +msgid "Select a Country" +msgstr "選擇國家" + +#: lib/php/monica/list.inc.php:3384 +msgid "Manage Country Data" +msgstr "管理國家資料" + +#: lib/php/monica/list.inc.php:3389 +msgid "Code" +msgstr "代碼" + +#: lib/php/monica/list.inc.php:3390 +msgid "Country name" +msgstr "國名" + +#: lib/php/monica/list.inc.php:3399 +msgid "Add a new country record." +msgstr "建新國家資料。" + +#: lib/php/monica/list.inc.php:3409 +msgid "Search for a country:" +msgstr "搜尋國家:" + +#: lib/php/monica/list.inc.php:3427 +#, c-format +msgid "Your query found %s country." +msgid_plural "Your query found %s countries." +msgstr[0] "共 %s 個相符的國家。" + +#: lib/php/monica/list.inc.php:3434 +#, c-format +msgid "%s country." +msgid_plural "%s countries." +msgstr[0] "共 %s 個國家。" + +#: lib/php/monica/list.inc.php:3443 +#, c-format +msgid "Your query found %s country, listing %s to %s." +msgid_plural "Your query found %s countries, listing %s to %s." +msgstr[0] "共 %s 個相符的國家,列出第 %s 個到第 %s 個。" + +#: lib/php/monica/list.inc.php:3452 +#, c-format +msgid "%s country, listing %s to %s." +msgid_plural "%s countries, listing %s to %s." +msgstr[0] "共 %s 個國家,列出第 %s 個到第 %s 個。" + +#: lib/php/monica/list.inc.php:3474 +msgid "Browse the Activity Log" +msgstr "查閱網站活動日誌" + +#: lib/php/monica/list.inc.php:3586 +msgid "Please fill in the number of rows to display." +msgstr "請填上顯示筆數。" + +#: lib/php/monica/list.inc.php:3590 +#, c-format +msgid "This number of rows to display is too long. (Max. length %d)" +msgstr "顯示筆數太長了。(最長 %d )" + +#: lib/php/monica/list.inc.php:3595 +msgid "Please fill in a positive integer number of rows to display." +msgstr "顯示筆數請填正整數。" + +#: lib/php/monica/list.inc.php:3599 lib/php/monica/list.inc.php:3609 +#, c-format +msgid "" +"The number of rows to display is too small. Please fill in a larger number " +"of rows to display between %d and %d." +msgstr "顯示筆數太小了,請設定在 %d 到 %d 之間。" + +#: lib/php/monica/list.inc.php:3613 +#, c-format +msgid "" +"The number of rows to display is too large. Please fill in a smaller number " +"of rows to display between %d and %d." +msgstr "顯示筆數太大了,請設定在 %d 到 %d 之間。" + +#: lib/php/monica/list.inc.php:3638 +msgid "Search for log entries:" +msgstr "搜尋記錄:" + +#: lib/php/monica/list.inc.php:3641 +msgid "Display" +msgstr "顯示" + +#: lib/php/monica/list.inc.php:3654 +msgid "Display rows:" +msgstr "顯示筆數:" + +#: lib/php/monica/list.inc.php:3677 +#, c-format +msgid "Your query found %s log entry." +msgid_plural "Your query found %s log entries." +msgstr[0] "共 %s 筆相符的記錄。" + +#: lib/php/monica/list.inc.php:3684 +#, c-format +msgid "%s log entry." +msgid_plural "%s log entries." +msgstr[0] "共 %s 筆記錄。" + +#: lib/php/monica/list.inc.php:3693 +#, c-format +msgid "Your query found %s log entry, listing %s to %s." +msgid_plural "Your query found %s log entries, listing %s to %s." +msgstr[0] "共 %s 筆相符的記錄,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:3702 +#, c-format +msgid "%s log entry, listing %s to %s." +msgid_plural "%s log entries, listing %s to %s." +msgstr[0] "共 %s 筆記錄,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/lninfo.inc.php:28 +msgid "English" +msgstr "英文" + +#: lib/php/monica/lninfo.inc.php:39 +msgid "Traditional Chinese" +msgstr "繁體中文" + +#: lib/php/monica/lninfo.inc.php:50 +msgid "Simplified Chinese" +msgstr "簡體中文" + +#: lib/php/monica/lninfo.inc.php:61 +msgid "Chinese" +msgstr "中文" + +#: lib/php/monica/lninfo.inc.php:72 +msgid "Japanese" +msgstr "日文" + +#: lib/php/monica/lninfo.inc.php:83 +msgid "Korean" +msgstr "韓文" + +#: lib/php/monica/lninfo.inc.php:94 +msgid "German" +msgstr "德文" + +#: lib/php/monica/lninfo.inc.php:105 +msgid "Spanish" +msgstr "西班牙文" + +#: lib/php/monica/lninfo.inc.php:366 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "切換到本頁的%s版。" + +#: lib/php/monica/pagefunc.inc.php:738 +msgid "Web pages" +msgstr "網頁" + +#: lib/php/monica/pagefunc.inc.php:739 +msgid "News" +msgstr "新聞" + +#: lib/php/monica/pagefunc.inc.php:740 +msgid "Related links" +msgstr "相關連結" + +#: lib/php/monica/pagefunc.inc.php:741 +msgid "Home page" +msgstr "首頁" + +#: lib/php/monica/pagefunc.inc.php:742 +msgid "Whole web site" +msgstr "整個網站" + +#: lib/php/monica/pic.inc.php:39 +msgid "Left-aligned" +msgstr "靠左" + +#: lib/php/monica/pic.inc.php:40 +msgid "Right-aligned" +msgstr "靠右" + +#: lib/php/monica/pic.inc.php:74 lib/php/monica/pic.inc.php:77 +#, c-format +msgid "This picture file is too large (Max %s)." +msgstr "圖檔太大。(上限 %s )" + +#: lib/php/monica/pic.inc.php:92 +msgid "Please upload only PNG, JPEG or GIF files." +msgstr "限上傳 PNG 、 JPEG 或 GIF 圖檔。" + +#: lib/php/monica/pic.inc.php:153 +#, c-format +msgid "Width: %d, height: %d, ratio: %0.2f" +msgstr "寬: %d ,高: %d ,比例: %0.2f" + +#: lib/php/monica/pic.inc.php:176 +msgid "Please specify a numeric ratio." +msgstr "比例請設定數字。" + +#: lib/php/monica/pic.inc.php:180 +msgid "Please specify a positive ratio." +msgstr "比例請設定正數。" + +#: lib/php/monica/pic.inc.php:183 +#, c-format +msgid "Please specify a ratio less than or equal to %0.2f." +msgstr "比例請勿大於 %0.2f 。" + +#: lib/php/monica/pic.inc.php:189 +msgid "This image is too large to display." +msgstr "圖片太大,無法顯示。" + +#: lib/php/monica/preview.inc.php:47 +#, c-format +msgid "Unknown preview source: \"%s\"." +msgstr "預覽資料源不明:「 %s 」。" + +#: lib/php/monica/preview.inc.php:67 +#, c-format +msgid "Unknown preview form: %d." +msgstr "預覽表格不明: %d 。" + +#: lib/php/monica/preview.inc.php:143 +msgid "Preview Mark Area" +msgstr "預覽標誌區" + +#: lib/php/monica/preview.inc.php:148 +msgid "Finish preview and return." +msgstr "結束預覽回前頁。" + +#: lib/php/monica/process.inc.php:237 +msgid "This record was not modified." +msgstr "資料未異動。" + +#: lib/php/monica/process.inc.php:243 +msgid "This record has been successfully added." +msgstr "資料建好了。" + +#: lib/php/monica/process.inc.php:247 +msgid "This record has been successfully updated." +msgstr "資料存好了。" + +#: lib/php/monica/process.inc.php:251 +msgid "This record has been successfully deleted." +msgstr "資料刪掉了。" + +#: lib/php/monica/process.inc.php:406 +msgid "This category was not modified." +msgstr "分類未異動。" + +#: lib/php/monica/process.inc.php:412 +msgid "This category has been successfully added." +msgstr "分類建好了。" + +#: lib/php/monica/process.inc.php:416 +msgid "This category has been successfully updated." +msgstr "分類存好了。" + +#: lib/php/monica/process.inc.php:420 +msgid "This category has been successfully deleted." +msgstr "分類刪掉了。" + +#: lib/php/monica/process.inc.php:433 +msgid "This categorization record was not modified." +msgstr "分類資料未異動。" + +#: lib/php/monica/process.inc.php:439 +msgid "This categorization record has been successfully added." +msgstr "分類資料建好了。" + +#: lib/php/monica/process.inc.php:443 +msgid "This categorization record has been successfully updated." +msgstr "分類資料存好了。" + +#: lib/php/monica/process.inc.php:447 +msgid "This categorization record has been successfully deleted." +msgstr "分類資料刪掉了。" + +#: lib/php/monica/process.inc.php:782 +msgid "This user account was not modified." +msgstr "帳號未異動。" + +#: lib/php/monica/process.inc.php:788 +msgid "This user account has been successfully added." +msgstr "帳號建好了。" + +#: lib/php/monica/process.inc.php:792 +msgid "This user account has been successfully updated." +msgstr "帳號存好了。" + +#: lib/php/monica/process.inc.php:796 +msgid "This user account has been successfully deleted." +msgstr "帳號刪掉了。" + +#: lib/php/monica/process.inc.php:1074 +msgid "This group was not modified." +msgstr "群組未異動。" + +#: lib/php/monica/process.inc.php:1080 +msgid "This group has been successfully added." +msgstr "群組建好了。" + +#: lib/php/monica/process.inc.php:1084 +msgid "This group has been successfully updated." +msgstr "群組存好了。" + +#: lib/php/monica/process.inc.php:1088 +msgid "This group has been successfully deleted." +msgstr "群組刪掉了。" + +#: lib/php/monica/process.inc.php:1152 lib/php/monica/process.inc.php:1230 +msgid "This membership record was not modified." +msgstr "成員關係未異動。" + +#: lib/php/monica/process.inc.php:1158 lib/php/monica/process.inc.php:1236 +msgid "This membership record has been successfully added." +msgstr "成員關係建好了。" + +#: lib/php/monica/process.inc.php:1162 lib/php/monica/process.inc.php:1240 +msgid "This membership record has been successfully updated." +msgstr "成員關係存好了。" + +#: lib/php/monica/process.inc.php:1166 lib/php/monica/process.inc.php:1244 +msgid "This membership record has been successfully deleted." +msgstr "成員關係刪掉了。" + +#: lib/php/monica/process.inc.php:1308 +msgid "This script privilege record was not modified." +msgstr "程式權限未異動。" + +#: lib/php/monica/process.inc.php:1314 +msgid "This script privilege record has been successfully added." +msgstr "程式權限建好了。" + +#: lib/php/monica/process.inc.php:1318 +msgid "This script privilege record has been successfully updated." +msgstr "程式權限存好了。" + +#: lib/php/monica/process.inc.php:1322 +msgid "This script privilege record has been successfully deleted." +msgstr "程式權限刪掉了。" + +#: lib/php/monica/process.inc.php:1438 +msgid "This user preference was not modified." +msgstr "使用者偏好未異動。" + +#: lib/php/monica/process.inc.php:1444 +msgid "This user preference has been successfully added." +msgstr "使用者偏好建好了。" + +#: lib/php/monica/process.inc.php:1448 +msgid "This user preference has been successfully updated." +msgstr "使用者偏好存好了。" + +#: lib/php/monica/process.inc.php:1452 +msgid "This user preference has been successfully deleted." +msgstr "使用者偏好刪掉了。" + +#: lib/php/monica/process.inc.php:1560 +msgid "This user request was not modified." +msgstr "使用者申請未異動。" + +#: lib/php/monica/process.inc.php:1566 +msgid "This user request has been successfully added." +msgstr "使用者申請建好了。" + +#: lib/php/monica/process.inc.php:1570 +msgid "This user request has been successfully updated." +msgstr "使用者申請存好了。" + +#: lib/php/monica/process.inc.php:1574 +msgid "This user request has been successfully deleted." +msgstr "使用者申請刪掉了。" + +#: lib/php/monica/process.inc.php:1685 +msgid "This page was not modified." +msgstr "網頁未異動。" + +#: lib/php/monica/process.inc.php:1691 +msgid "This page has been successfully added." +msgstr "網頁建好了。" + +#: lib/php/monica/process.inc.php:1695 +msgid "This page has been successfully updated." +msgstr "網頁存好了。" + +#: lib/php/monica/process.inc.php:1699 +msgid "This page has been successfully deleted." +msgstr "網頁刪掉了。" + +#: lib/php/monica/process.inc.php:1874 +msgid "This news article was not modified." +msgstr "新聞未異動。" + +#: lib/php/monica/process.inc.php:1880 +msgid "This news article has been successfully added." +msgstr "新聞建好了。" + +#: lib/php/monica/process.inc.php:1884 +msgid "This news article has been successfully updated." +msgstr "新聞存好了。" + +#: lib/php/monica/process.inc.php:1888 +msgid "This news article has been successfully deleted." +msgstr "新聞刪掉了。" + +#: lib/php/monica/process.inc.php:1997 +msgid "This country was not modified." +msgstr "國家未異動。" + +#: lib/php/monica/process.inc.php:2003 +msgid "This country has been successfully added." +msgstr "國家建好了。" + +#: lib/php/monica/process.inc.php:2007 +msgid "This country has been successfully updated." +msgstr "國家存好了。" + +#: lib/php/monica/process.inc.php:2011 +msgid "This country has been successfully deleted." +msgstr "國家刪掉了。" + +#: lib/php/monica/process.inc.php:2097 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. (%0.3f seconds)" +msgstr "該類網頁重製好了。( %0.3f 秒)" + +#: lib/php/monica/process.inc.php:2158 +#, c-format +msgid "Welcome, %s!" +msgstr "%s,你好。" + +#: lib/php/monica/process.inc.php:2204 +msgid "You have successfully logged out." +msgstr "登出好了。" + +#: lib/php/monica/process.inc.php:2439 +msgid "This related link was not modified." +msgstr "相關連結未異動。" + +#: lib/php/monica/process.inc.php:2445 +msgid "This related link has been successfully added." +msgstr "相關連結建好了。" + +#: lib/php/monica/process.inc.php:2449 +msgid "This related link has been successfully updated." +msgstr "相關連結存好了。" + +#: lib/php/monica/process.inc.php:2453 +msgid "This related link has been successfully deleted." +msgstr "相關連結刪掉了。" + +#: lib/php/monica/request.inc.php:38 +msgid "Please specify the request." +msgstr "請設定申請編號。" + +#: lib/php/monica/request.inc.php:46 lib/php/monica/request.inc.php:55 +#, c-format +msgid "Invalid request S/N: %s." +msgstr "申請編號無效: %s 。" + +#: lib/php/monica/sitesize.inc.php:41 +#, c-format +msgid "Currently using files %s.\n" +msgstr "現用檔案 %s。\n" + +#: lib/php/monica/sitesize.inc.php:46 +#, c-format +msgid "Currently using files %s, database %s, total %s.\n" +msgstr "現用檔案 %s ,資料庫 %s ,合計 %s 。\n" + +#: lib/php/monica/upload.inc.php:70 +#, c-format +msgid "MIME file type: %s" +msgstr "MIME 檔案格式: %s" + +#: lib/php/monica/upload.inc.php:71 +#, c-format +msgid "File name: %s" +msgstr "檔名: %s" + +#: lib/php/monica/upload.inc.php:72 +#, c-format +msgid "File size: %s bytes" +msgstr "檔案大小: %s 位元組" + +#: lib/php/monica/validate.inc.php:116 +msgid "HTML Validatior Logo Area" +msgstr "HTML 驗證標誌區" + +#: lib/php/monica/validate.inc.php:117 +msgid "HTML validation result of this page" +msgstr "本頁的 HTML 驗證結果" + +#: lib/php/monica/validate.inc.php:118 +#, c-format +msgid "Valid %s!" +msgstr "%s 正確!" + +#: lib/php/monica/validate.inc.php:119 +msgid "CSS validation result of this page" +msgstr "本頁的 CSS 驗證結果" + +#: lib/php/monica/validate.inc.php:120 +msgid "Valid CSS!" +msgstr "CSS 正確!" + +#: lib/php/monica/validate.inc.php:121 +msgid "Explanation of Level Triple-A Conformance" +msgstr "無障礙三 A 級標準說明" + +#: lib/php/monica/validate.inc.php:122 +msgid "" +"Level Triple-A conformance icon, W3C-WAI Web Content Accessibility " +"Guidelines 1.0" +msgstr "W3C 無障礙網頁規範 1.0 三 A 級標準標章" diff --git a/po/monica/zh_TW.pox b/po/monica/zh_TW.pox new file mode 100644 index 0000000..9b7e739 --- /dev/null +++ b/po/monica/zh_TW.pox @@ -0,0 +1,3243 @@ +# Traditional Chinese PO file for the monica core +# Copyright (C) 2002-2018 Pristine Communcations +# This file is distributed under the same license as the monica package. +# imacat , 2002-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: monica 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 12:53+0800\n" +"PO-Revision-Date: 2018-11-02 01:22+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: lib/php/monica/checker.inc.php:159 +msgid "Please select a user." +msgstr "請選擇使用者。" + +#: lib/php/monica/checker.inc.php:163 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: lib/php/monica/checker.inc.php:181 +msgid "Please select a group." +msgstr "請選擇群組。" + +#: lib/php/monica/checker.inc.php:185 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: lib/php/monica/checker.inc.php:203 +msgid "Please fill in the script." +msgstr "請填上程式檔名。" + +#: lib/php/monica/checker.inc.php:207 +#, c-format +msgid "This script is too long. (Max. length %d)" +msgstr "程式檔名太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:212 +msgid "This script is not a valid script. Please specify another one." +msgstr "查無此程式,請重新設定執行的程式。" + +#: lib/php/monica/checker.inc.php:230 +msgid "Please fill in the date." +msgstr "請填上日期。" + +#: lib/php/monica/checker.inc.php:234 lib/php/monica/checker.inc.php:238 +#: lib/php/monica/checker.inc.php:241 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期請以 YYYY-MM-DD 格式正確填寫。" + +#: lib/php/monica/checker.inc.php:259 +msgid "Please fill in the ID." +msgstr "請填上代號。" + +#: lib/php/monica/checker.inc.php:263 +#, c-format +msgid "This ID. is too long. (Max. length %d)" +msgstr "代號太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:267 +#, c-format +msgid "This ID. is too short. (Min. length %d)" +msgstr "代號太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:272 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "代號限用小寫英文字母、數字和底線。" + +#: lib/php/monica/checker.inc.php:294 +msgid "Please fill in the order." +msgstr "請填上先後次序。" + +#: lib/php/monica/checker.inc.php:298 +#, c-format +msgid "This order is too long. (Max. length %d)" +msgstr "次序太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:303 +msgid "Please fill in a positive integer order." +msgstr "次序請填正整數。" + +#: lib/php/monica/checker.inc.php:307 lib/php/monica/checker.inc.php:317 +#, c-format +msgid "" +"The order is too small. Please fill in a larger order between %d and %d." +msgstr "次序太小了,請設定在 %d 到 %d 之間。" + +#: lib/php/monica/checker.inc.php:321 +#, c-format +msgid "" +"The order is too large. Please fill in a smaller order between %d and %d." +msgstr "次序太大了,請設定在 %d 到 %d 之間。" + +#: lib/php/monica/checker.inc.php:348 +msgid "Please fill in the page path." +msgstr "請填上網頁路徑。" + +#: lib/php/monica/checker.inc.php:352 +#, c-format +msgid "This page path is too long. (Max. length %d)" +msgstr "網頁路徑太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:365 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "已有同一網頁,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:369 +msgid "Please fill in an absolute page path." +msgstr "網頁路徑請填上絕對路徑。" + +#: lib/php/monica/checker.inc.php:373 +msgid "Please fill in a valid page path." +msgstr "網頁路徑請填上正確路徑。" + +#: lib/php/monica/checker.inc.php:377 +msgid "You cannot overwrite the cover home page." +msgstr "不可以程式設定首頁。" + +#: lib/php/monica/checker.inc.php:381 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "網頁路徑限填 HTML 位址( *.html )。" + +#: lib/php/monica/checker.inc.php:422 lib/php/monica/checker.inc.php:428 +msgid "Please fill in the attachment description." +msgstr "請填上附件說明。" + +#: lib/php/monica/checker.inc.php:432 +#, c-format +msgid "This attachment description is too long. (Max. length %d)" +msgstr "附件說明太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:449 +msgid "This PDF. file does not exist anymore. Please upload another one." +msgstr "查無此 PDF. 檔,請重新上傳檔案。" + +#: lib/php/monica/checker.inc.php:456 +#, c-format +msgid "This PDF. file is too large. (Max. size %s)" +msgstr "檔案太大。(上限 %s )" + +#: lib/php/monica/checker.inc.php:461 +msgid "Please upload only PDF. file." +msgstr "限上傳 PDF. 檔。" + +#: lib/php/monica/checker.inc.php:479 +msgid "Please fill in the title." +msgstr "請填上標題。" + +#: lib/php/monica/checker.inc.php:483 +#, c-format +msgid "This title is too long. (Max. length %d)" +msgstr "標題太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:502 +msgid "Please fill in the subject." +msgstr "請填上主題。" + +#: lib/php/monica/checker.inc.php:506 +#, c-format +msgid "This subject is too long. (Max. length %d)" +msgstr "主題太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:524 lib/php/monica/form.inc.php:3159 +#: lib/php/monica/form.inc.php:3172 +msgid "Fill in the content here." +msgstr "請填上內文。" + +#: lib/php/monica/checker.inc.php:528 +msgid "Please fill in the content." +msgstr "請填上內文。" + +#: lib/php/monica/checker.inc.php:532 +#, c-format +msgid "This content is too long. (Max. length %d)" +msgstr "內文太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:551 +msgid "Please fill in the keywords." +msgstr "請填上關鍵字。" + +#: lib/php/monica/checker.inc.php:555 +#, c-format +msgid "This keyword list is too long. (Max. length %d)" +msgstr "關鍵字太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:572 +msgid "Please select a proper pinyin." +msgstr "請選擇符合的拼音。" + +#: lib/php/monica/checker.inc.php:578 +#, c-format +msgid "This pinyin is too long. (Max. length %d)" +msgstr "拼音太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:583 +msgid "" +"This pinyin does not match the Chinese. Please select a proper pinyin from " +"the list." +msgstr "拼音與中文不合,請重新於列表中選擇。" + +#: lib/php/monica/checker.inc.php:609 lib/php/monica/pic.inc.php:82 +msgid "Please upload the picture." +msgstr "請上傳圖檔。" + +#: lib/php/monica/checker.inc.php:616 lib/php/monica/checker.inc.php:3214 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "查無此圖,請重新上傳圖檔。" + +#: lib/php/monica/checker.inc.php:622 +#, c-format +msgid "This picture is too large. Please upload another one. (Max. size %d)" +msgstr "圖檔太大,請重新上傳圖檔(最大 %d )。" + +#: lib/php/monica/checker.inc.php:639 lib/php/monica/form.inc.php:3588 +#, c-format +msgid "Please upload a new picture from %s." +msgstr "請由%s建新圖片。" + +#: lib/php/monica/checker.inc.php:664 lib/php/monica/checker.inc.php:727 +msgid "Please fill in the picture caption." +msgstr "請填上圖片標題。" + +#: lib/php/monica/checker.inc.php:668 lib/php/monica/checker.inc.php:731 +#, c-format +msgid "This picture caption is too long. (Max. length %d)" +msgstr "圖片標題太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:686 lib/php/monica/checker.inc.php:749 +msgid "Please select the picture position." +msgstr "請設定圖片位置。" + +#: lib/php/monica/checker.inc.php:692 lib/php/monica/checker.inc.php:755 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "圖片位置無效。請由表上選擇適當的圖片位置。" + +#: lib/php/monica/checker.inc.php:791 lib/php/monica/checker.inc.php:794 +#, c-format +msgid "Your uploaded file is too large (Max %s)." +msgstr "上傳檔案太大。(上限 %s )" + +#: lib/php/monica/checker.inc.php:797 lib/php/monica/pic.inc.php:80 +msgid "" +"Upload not completed. Disk may be full or connection may be closed in the " +"half. You may try to upload again, or contact the system administrator for " +"this problem." +msgstr "" +"上傳失敗。可能是伺服器磁碟滿了,或傳到一半網路斷線。請重新上傳一次,或洽網站" +"系統管理人員處理。" + +#: lib/php/monica/checker.inc.php:799 lib/php/monica/pic.inc.php:84 +#, c-format +msgid "Upload failed with an unknown error (%d)." +msgstr "上傳失敗,原因不明。( %d )" + +#: lib/php/monica/checker.inc.php:1183 lib/php/monica/chkfunc.inc.php:59 +#: lib/php/monica/chkfunc.inc.php:72 lib/php/monica/preview.inc.php:29 +#, c-format +msgid "The following field was not received: \"%s\"." +msgstr "程式沒有收到下列欄位:「 %s 」" + +#: lib/php/monica/checker.inc.php:1262 +msgid "Please fill in the user ID." +msgstr "請填上帳號。" + +#: lib/php/monica/checker.inc.php:1266 +#, c-format +msgid "This user ID. is too long. (Max. length %d)" +msgstr "帳號太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:1270 +#, c-format +msgid "This user ID. is too short. (Min. length %d)" +msgstr "帳號太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1275 +msgid "" +"Only lower-case English letters, numbers, at-signs, dots, dashes and " +"underscores are allowed for the user ID." +msgstr "帳號限用小寫英文字母、數字、 @ 號、點、橫線和底線。" + +#: lib/php/monica/checker.inc.php:1287 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "該使用者已有帳號,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:1317 +msgid "Please fill in the password." +msgstr "請填上密碼。" + +#: lib/php/monica/checker.inc.php:1320 +msgid "Please confirm the password." +msgstr "請確認密碼。" + +#: lib/php/monica/checker.inc.php:1324 +#, c-format +msgid "This password is too long. (Max. length %d)" +msgstr "密碼太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:1329 +#, c-format +msgid "This password is too short. (Min. length %d)" +msgstr "密碼太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1334 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "兩次密碼不合,請重新設定密碼。" + +#: lib/php/monica/checker.inc.php:1345 +msgid "This password is based on the user ID." +msgstr "密碼不可由帳號組成。" + +#: lib/php/monica/checker.inc.php:1360 +msgid "This password does not contain enough different characters." +msgstr "密碼重複的字元太多。" + +#: lib/php/monica/checker.inc.php:1364 +msgid "This password is too simplistic/systematic." +msgstr "密碼結構太簡單。" + +#: lib/php/monica/checker.inc.php:1368 +msgid "This password is based on a dictionary word." +msgstr "密碼不可由字典單字組成。" + +#: lib/php/monica/checker.inc.php:1370 +msgid "This password is based on a (reversed) dictionary word." +msgstr "密碼不可由倒過來的字典單字組成。" + +#: lib/php/monica/checker.inc.php:1372 +msgid "This password is too simple." +msgstr "密碼太簡單。" + +#: lib/php/monica/checker.inc.php:1378 +msgid "You cannot use a password that is based on the user ID." +msgstr "密碼不可由帳號組成。" + +#: lib/php/monica/checker.inc.php:1397 +msgid "Please fill in the name." +msgstr "請填上姓名。" + +#: lib/php/monica/checker.inc.php:1401 +#, c-format +msgid "This name is too long. (Max. length %d)" +msgstr "姓名太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:1420 +msgid "Please fill in the e-mail." +msgstr "請填上 E-mail 信箱。" + +#: lib/php/monica/checker.inc.php:1424 +#, c-format +msgid "This e-mail is too long. (Max. length %d)" +msgstr "E-mail 信箱太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:1428 +#, c-format +msgid "This e-mail is too short. (Min. length %d)" +msgstr "E-mail 信箱太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1437 +msgid "Please fill in a valid e-mail address." +msgstr "請填上正確的 E-mail 信箱。" + +#: lib/php/monica/checker.inc.php:1439 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "查無這個信箱的所屬網域,請檢查有沒有拼錯。" + +#: lib/php/monica/checker.inc.php:1461 lib/php/monica/checker.inc.php:1655 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "隸屬群組重複,請勿重複設定。" + +#: lib/php/monica/checker.inc.php:1478 +msgid "You cannot submit the super-user group along with other groups." +msgstr "總管理員群組不可與其它群組一起設定。" + +#: lib/php/monica/checker.inc.php:1480 +msgid "You cannot set the administrators group." +msgstr "不可設定所有網站管理員群組" + +#: lib/php/monica/checker.inc.php:1482 +msgid "You cannot set the all-users group." +msgstr "不可設定所有登入使用者群組。" + +#: lib/php/monica/checker.inc.php:1515 +msgid "Please fill in the group ID." +msgstr "請填上群組代號。" + +#: lib/php/monica/checker.inc.php:1519 +#, c-format +msgid "This group ID. is too long. (Max. length %d)" +msgstr "群組代號太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:1523 +#, c-format +msgid "This group ID. is too short. (Min. length %d)" +msgstr "群組代號太短了。(最短 %d )" + +#: lib/php/monica/checker.inc.php:1528 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "群組代號限用小寫英文字母、數字和底線。" + +#: lib/php/monica/checker.inc.php:1540 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "已有同一群組,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:1558 +msgid "Please fill in the privilege description." +msgstr "請填上權限說明。" + +#: lib/php/monica/checker.inc.php:1562 +#, c-format +msgid "This privilege description is too long. (Max. length %d)" +msgstr "權限說明太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:1585 +msgid "This user member is duplicated. You cannot set duplicated ones." +msgstr "使用者成員重複,請勿重複設定。" + +#: lib/php/monica/checker.inc.php:1620 +msgid "This group member is duplicated. You cannot set duplicated ones." +msgstr "群組成員重複,請勿重複設定。" + +#: lib/php/monica/checker.inc.php:1747 lib/php/monica/checker.inc.php:1855 +msgid "Please select a member." +msgstr "請選擇成員。" + +#: lib/php/monica/checker.inc.php:1751 lib/php/monica/checker.inc.php:1859 +msgid "This member does not exist anymore. Please select another one." +msgstr "查無此成員,請重新選擇。" + +#: lib/php/monica/checker.inc.php:1770 lib/php/monica/checker.inc.php:1883 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "已有同一成員關係,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:1837 +msgid "Please select a different belonging group." +msgstr "隸屬群組請選擇別的群組。" + +#: lib/php/monica/checker.inc.php:1864 +msgid "Please select a different group member." +msgstr "群組成員請選擇別的群組。" + +#: lib/php/monica/checker.inc.php:1958 +msgid "" +"This script privilege already exists. You cannot create a duplicated one." +msgstr "已有同一程式權限,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:1996 lib/php/monica/checker.inc.php:2184 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: lib/php/monica/checker.inc.php:2002 lib/php/monica/checker.inc.php:2190 +msgid "This option is invalid. Please select a proper user." +msgstr "使用者選項無效,請由表上選擇適當的使用者。" + +#: lib/php/monica/checker.inc.php:2020 +msgid "Please set the preference domain." +msgstr "請設定適用範圍。" + +#: lib/php/monica/checker.inc.php:2026 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "適用範圍選項無效,請設定適當的適用範圍。" + +#: lib/php/monica/checker.inc.php:2039 lib/php/monica/checker.inc.php:2295 +msgid "Please fill in the preference domain." +msgstr "請填上偏好的適用範圍。" + +#: lib/php/monica/checker.inc.php:2043 lib/php/monica/checker.inc.php:2299 +#, c-format +msgid "This preference domain is too long. (Max. length %d)" +msgstr "偏好適用範圍太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2063 +msgid "Please fill in the preference name." +msgstr "請填上偏好的名稱。" + +#: lib/php/monica/checker.inc.php:2067 +#, c-format +msgid "This preference name is too long. (Max. length %d)" +msgstr "偏好名稱太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2086 +msgid "Please fill in the preference value." +msgstr "請填上偏好的值。" + +#: lib/php/monica/checker.inc.php:2090 +#, c-format +msgid "This preference value is too long. (Max. length %d)" +msgstr "偏好值太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2119 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "已有同一使用者偏好,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:2167 +msgid "Please select the request type." +msgstr "請選擇申請類別。" + +#: lib/php/monica/checker.inc.php:2173 +msgid "This option is invalid. Please select a proper request type." +msgstr "申請類別選項無效,請由表上選擇適當的申請類別。" + +#: lib/php/monica/checker.inc.php:2194 +msgid "You must choose anonymous for join requests." +msgstr "加入申請不可具名。" + +#: lib/php/monica/checker.inc.php:2197 +msgid "You cannot choose anonymous for non-join requests." +msgstr "非加入申請必須具名。" + +#: lib/php/monica/checker.inc.php:2221 lib/php/monica/form.inc.php:5502 +msgid "Please fill in the request arguments list here." +msgstr "請填上備註資料。" + +#: lib/php/monica/checker.inc.php:2229 +#, c-format +msgid "This request arguments list is too long. (Max. length %d)" +msgstr "申請備註資料太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2349 +msgid "Please fill in the number of rows per page." +msgstr "請填上每頁顯示筆數。" + +#: lib/php/monica/checker.inc.php:2353 +#, c-format +msgid "This number of rows per page is too long. (Max. length %d)" +msgstr "每頁顯示筆數太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2358 +msgid "Please fill in a positive integer number of rows per page." +msgstr "每頁顯示筆數請填正整數。" + +#: lib/php/monica/checker.inc.php:2362 lib/php/monica/checker.inc.php:2372 +#, c-format +msgid "" +"The number of rows per page is too small. Please fill in a larger number of " +"rows per page between %d and %d." +msgstr "每頁顯示筆數太小了,請設定在 %d 到 %d 之間。" + +#: lib/php/monica/checker.inc.php:2376 +#, c-format +msgid "" +"The number of rows per page is too large. Please fill in a smaller number " +"of rows per page between %d and %d." +msgstr "每頁顯示筆數太大了,請設定在 %d 到 %d 之間。" + +#: lib/php/monica/checker.inc.php:2443 +msgid "Please fill in your user ID." +msgstr "請填上你的帳號。" + +#: lib/php/monica/checker.inc.php:2451 lib/php/monica/checker.inc.php:2458 +#: lib/php/monica/checker.inc.php:2475 lib/php/monica/checker.inc.php:2508 +#: lib/php/monica/checker.inc.php:2540 lib/php/monica/checker.inc.php:2548 +#: lib/php/monica/checker.inc.php:2558 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "登入錯誤,使用者代號或密碼有誤。" + +#: lib/php/monica/checker.inc.php:2495 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "帳號停用中,請洽系統管理員。" + +#: lib/php/monica/checker.inc.php:2531 +msgid "Please fill in your password." +msgstr "請填上你的密碼。" + +#: lib/php/monica/checker.inc.php:2581 +msgid "You are not an administrator so may not log in here." +msgstr "非管理員勿入。" + +#: lib/php/monica/checker.inc.php:2600 +msgid "You are an administrator so may not log in here." +msgstr "管理人員勿入。" + +#: lib/php/monica/checker.inc.php:2751 +msgid "Please fill in the code." +msgstr "請填上代碼。" + +#: lib/php/monica/checker.inc.php:2755 +#, c-format +msgid "You must fill in a %d-letters code." +msgstr "代碼限為兩個字母。" + +#: lib/php/monica/checker.inc.php:2760 +msgid "You can only use upper letters and for the code." +msgstr "代碼限用大寫英文字母。" + +#: lib/php/monica/checker.inc.php:2772 +msgid "This code is duplicated. You cannot create a duplicated one." +msgstr "代碼重複,請勿重複設定。" + +#: lib/php/monica/checker.inc.php:2790 +msgid "Please fill in the country name." +msgstr "請填上國名。" + +#: lib/php/monica/checker.inc.php:2794 +#, c-format +msgid "This country name is too long. (Max. length %d)" +msgstr "國名太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2822 lib/php/monica/checker.inc.php:2841 +msgid "Please select a parent category." +msgstr "請選擇所屬的大類。" + +#: lib/php/monica/checker.inc.php:2828 +msgid "This option is invalid. Please select a proper parent category." +msgstr "大類選項無效,請由表上選擇適當的大類。" + +#: lib/php/monica/checker.inc.php:2845 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "查無此大類,請重新選擇。" + +#: lib/php/monica/checker.inc.php:2850 +msgid "A category cannot belong to itself. Please select another one." +msgstr "分類不可屬於自己本身,請重新選擇。" + +#: lib/php/monica/checker.inc.php:2858 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "分類不可屬於自己的子類,請重新選擇。" + +#: lib/php/monica/checker.inc.php:2876 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "「 index 」為目錄檔 index.html 專用,代號不可設為「 index 」。" + +#: lib/php/monica/checker.inc.php:2894 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "已有同一分類,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:2941 +msgid "Please fill in the URL.." +msgstr "請填上網址。" + +#: lib/php/monica/checker.inc.php:2945 +#, c-format +msgid "This URL. is too long. (Max. length %d)" +msgstr "網址太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:2950 +msgid "Please fill in a valid URL.." +msgstr "請填上正確網址。" + +#: lib/php/monica/checker.inc.php:2962 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "已有同一相關連結,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:2967 +msgid "This URL. is not reachable. Check if there is any typo in it." +msgstr "這個網址連不上,請檢查有沒有拼錯。" + +#: lib/php/monica/checker.inc.php:2984 lib/php/monica/form.inc.php:3261 +msgid "Fill in the description here." +msgstr "請填上說明。" + +#: lib/php/monica/checker.inc.php:2988 +msgid "Please fill in the description." +msgstr "請填上說明。" + +#: lib/php/monica/checker.inc.php:2992 +#, c-format +msgid "This description is too long. (Max. length %d)" +msgstr "說明太長了。(最長 %d )" + +#: lib/php/monica/checker.inc.php:3012 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "分類重複,請勿重複設定。。" + +#: lib/php/monica/checker.inc.php:3016 lib/php/monica/checker.inc.php:3072 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: lib/php/monica/checker.inc.php:3022 lib/php/monica/checker.inc.php:3068 +msgid "Please select a category." +msgstr "請選擇分類。" + +#: lib/php/monica/checker.inc.php:3090 +msgid "Please select a related link." +msgstr "請選擇相關連結。" + +#: lib/php/monica/checker.inc.php:3094 +msgid "This link does not exist anymore. Please select another one." +msgstr "查無此相關連結,請重新選擇。" + +#: lib/php/monica/checker.inc.php:3113 +msgid "" +"This link categorization already exists. You cannot create a duplicated one." +msgstr "已有同一連結分類資料,請勿重複建檔。" + +#: lib/php/monica/checker.inc.php:3154 +msgid "Please select the type." +msgstr "請選擇類型。" + +#: lib/php/monica/checker.inc.php:3158 +msgid "This type does not exist anymore. Please select another one." +msgstr "查無此類型,請重新選擇。" + +#: lib/php/monica/checker.inc.php:3185 lib/php/monica/list.inc.php:961 +msgid "Please fill in your query." +msgstr "請填上查詢的內容。" + +#: lib/php/monica/checker.inc.php:3210 +msgid "Please submit the picture." +msgstr "請上傳圖檔。" + +#: lib/php/monica/checker.inc.php:3237 lib/php/monica/checker.inc.php:3328 +msgid "Please fill in the resize ratio." +msgstr "請填上縮放比例。" + +#: lib/php/monica/checker.inc.php:3305 +msgid "Please specify a valid picture." +msgstr "您上傳的不是圖檔,請重新上傳圖檔。" + +#: lib/php/monica/chkfunc.inc.php:156 lib/php/monica/chkfunc.inc.php:160 +#: lib/php/monica/chkfunc.inc.php:163 lib/php/monica/chkfunc.inc.php:166 +msgid "Please select a legal year." +msgstr "請選一個正確的年份。" + +#: lib/php/monica/chkfunc.inc.php:171 lib/php/monica/chkfunc.inc.php:175 +#: lib/php/monica/chkfunc.inc.php:178 +msgid "Please select a legal month." +msgstr "請選一個正確的月份。" + +#: lib/php/monica/chkfunc.inc.php:183 lib/php/monica/chkfunc.inc.php:187 +#: lib/php/monica/chkfunc.inc.php:193 +msgid "Please select a legal day." +msgstr "請選一個正確的日期。" + +#: lib/php/monica/chkwrite.inc.php:27 +#, c-format +msgid "%s: It is not a file." +msgstr "%s: 這不是檔案。" + +#: lib/php/monica/chkwrite.inc.php:32 +#, c-format +msgid "%s: You have no permission to overwrite this file." +msgstr "%s: 存檔的權限不足,無法存檔。" + +#: lib/php/monica/chkwrite.inc.php:45 +#, c-format +msgid "%s: You cannot create anything under the root directory." +msgstr "%s: 不可在根目錄下建檔。" + +#: lib/php/monica/chkwrite.inc.php:50 +#, c-format +msgid "" +"%s: One of the parents of this file (%s) is not a directory. You cannot " +"create any new file inside." +msgstr "%s: 路徑中間有一部份( %s )不是目錄,無法往下建檔。" + +#: lib/php/monica/chkwrite.inc.php:55 +#, c-format +msgid "%s: You have no permission to create any file under %s." +msgstr "%s: 權限不足,無法在 %s 建檔。" + +#: lib/php/monica/commtext.inc.php:18 +msgid "(not set)" +msgstr "(未設定)" + +#: lib/php/monica/commtext.inc.php:24 +msgid "(none)" +msgstr "(無)" + +#: lib/php/monica/commtext.inc.php:30 +msgid "(N/A)" +msgstr "(不可考)" + +#: lib/php/monica/commtext.inc.php:36 +msgid "(blank)" +msgstr "(留白)" + +#: lib/php/monica/echoform.inc.php:173 +#, c-format +msgid "%s bytes" +msgstr "%s 位元組" + +#: lib/php/monica/form.inc.php:168 +msgid "Delete it" +msgstr "刪掉" + +#: lib/php/monica/form.inc.php:174 +msgid "Are you sure you want to delete it? It cannot be recovered." +msgstr "你真的要刪掉嗎?資料刪掉就救不回來了。" + +#: lib/php/monica/form.inc.php:188 +msgid "*" +msgstr "" + +#: lib/php/monica/form.inc.php:224 +msgid "This table provides you a form to add a new data record." +msgstr "本表提供建新資料的表單。" + +#: lib/php/monica/form.inc.php:228 +msgid "This table provides you a form to update a current data record." +msgstr "本表提供異動資料的表單。" + +#: lib/php/monica/form.inc.php:232 +msgid "This table provides you a form to delete a data record." +msgstr "本表提供刪除資料的表單。" + +#: lib/php/monica/form.inc.php:281 +msgid "Add a New Data Record" +msgstr "建新資料" + +#: lib/php/monica/form.inc.php:285 +msgid "Update a Current Data Record" +msgstr "異動資料" + +#: lib/php/monica/form.inc.php:289 +msgid "Delete a Data Record" +msgstr "刪除資料" + +#: lib/php/monica/form.inc.php:301 +msgid "Preview it." +msgstr "預覽。" + +#: lib/php/monica/form.inc.php:500 lib/php/monica/form.inc.php:506 +#: lib/php/monica/form.inc.php:691 lib/php/monica/form.inc.php:697 +#: lib/php/monica/preview.inc.php:146 +msgid "Preview" +msgstr "預覽" + +#: lib/php/monica/form.inc.php:501 lib/php/monica/form.inc.php:507 +#: lib/php/monica/form.inc.php:692 lib/php/monica/form.inc.php:698 +msgid "Confirm and submit" +msgstr "確認傳送" + +#: lib/php/monica/form.inc.php:708 lib/php/monica/form.inc.php:1692 +#: lib/php/monica/form.inc.php:1778 lib/php/monica/list.inc.php:1809 +msgid "Delete" +msgstr "刪除" + +#: lib/php/monica/form.inc.php:709 lib/php/monica/form.inc.php:6437 +#: lib/php/monica/form.inc.php:6488 +msgid "Cancel" +msgstr "取消" + +#: lib/php/monica/form.inc.php:1042 lib/php/monica/form.inc.php:3499 +msgid "Set the picture" +msgstr "設定圖片" + +#: lib/php/monica/form.inc.php:1043 lib/php/monica/form.inc.php:3031 +#: lib/php/monica/form.inc.php:3500 +msgid "Delete this picture" +msgstr "刪掉圖片" + +#: lib/php/monica/form.inc.php:1048 lib/php/monica/form.inc.php:1178 +#: lib/php/monica/form.inc.php:3037 lib/php/monica/form.inc.php:3104 +#: lib/php/monica/form.inc.php:3505 lib/php/monica/form.inc.php:3677 +#: lib/php/monica/form.inc.php:6181 lib/php/monica/list.inc.php:814 +msgid "Picture preview" +msgstr "圖片預覽" + +#: lib/php/monica/form.inc.php:1059 lib/php/monica/form.inc.php:1109 +#: lib/php/monica/form.inc.php:1185 +#, c-format +msgid "Picture #%d:" +msgstr "圖片 %d :" + +#: lib/php/monica/form.inc.php:1080 lib/php/monica/form.inc.php:1131 +#: lib/php/monica/form.inc.php:1166 lib/php/monica/form.inc.php:1199 +msgid "Caption:" +msgstr "標題:" + +#: lib/php/monica/form.inc.php:1092 lib/php/monica/form.inc.php:3064 +#: lib/php/monica/form.inc.php:3566 lib/php/monica/form.inc.php:6201 +msgid "Original picture preview" +msgstr "原圖片預覽" + +#: lib/php/monica/form.inc.php:1093 lib/php/monica/form.inc.php:3065 +#: lib/php/monica/form.inc.php:3567 lib/php/monica/form.inc.php:6215 +msgid "New picture preview" +msgstr "新圖片預覽" + +#: lib/php/monica/form.inc.php:1113 lib/php/monica/form.inc.php:1276 +#: lib/php/monica/form.inc.php:1363 lib/php/monica/form.inc.php:1451 +#: lib/php/monica/form.inc.php:1560 lib/php/monica/form.inc.php:1650 +#: lib/php/monica/form.inc.php:1727 lib/php/monica/form.inc.php:1825 +#: lib/php/monica/form.inc.php:1916 lib/php/monica/form.inc.php:1977 +#: lib/php/monica/form.inc.php:2053 lib/php/monica/form.inc.php:2159 +#: lib/php/monica/form.inc.php:2391 lib/php/monica/form.inc.php:2592 +#: lib/php/monica/form.inc.php:2689 lib/php/monica/form.inc.php:2800 +#: lib/php/monica/form.inc.php:2897 lib/php/monica/form.inc.php:2980 +#: lib/php/monica/form.inc.php:3069 lib/php/monica/form.inc.php:3200 +#: lib/php/monica/form.inc.php:3571 lib/php/monica/form.inc.php:3627 +#: lib/php/monica/form.inc.php:3640 lib/php/monica/form.inc.php:3747 +#: lib/php/monica/form.inc.php:4423 lib/php/monica/form.inc.php:4548 +#: lib/php/monica/form.inc.php:4747 lib/php/monica/form.inc.php:4884 +#: lib/php/monica/form.inc.php:5018 lib/php/monica/form.inc.php:6194 +#: lib/php/monica/form.inc.php:6261 +msgid "Original:" +msgstr "原:" + +#: lib/php/monica/form.inc.php:1141 lib/php/monica/form.inc.php:1281 +#: lib/php/monica/form.inc.php:1369 lib/php/monica/form.inc.php:1456 +#: lib/php/monica/form.inc.php:1575 lib/php/monica/form.inc.php:1655 +#: lib/php/monica/form.inc.php:1732 lib/php/monica/form.inc.php:1832 +#: lib/php/monica/form.inc.php:1921 lib/php/monica/form.inc.php:1982 +#: lib/php/monica/form.inc.php:2065 lib/php/monica/form.inc.php:2173 +#: lib/php/monica/form.inc.php:2422 lib/php/monica/form.inc.php:2597 +#: lib/php/monica/form.inc.php:2694 lib/php/monica/form.inc.php:2805 +#: lib/php/monica/form.inc.php:2902 lib/php/monica/form.inc.php:2985 +#: lib/php/monica/form.inc.php:3080 lib/php/monica/form.inc.php:3205 +#: lib/php/monica/form.inc.php:3584 lib/php/monica/form.inc.php:3632 +#: lib/php/monica/form.inc.php:3649 lib/php/monica/form.inc.php:3752 +#: lib/php/monica/form.inc.php:4442 lib/php/monica/form.inc.php:4554 +#: lib/php/monica/form.inc.php:4760 lib/php/monica/form.inc.php:4897 +#: lib/php/monica/form.inc.php:5031 lib/php/monica/form.inc.php:6206 +#: lib/php/monica/form.inc.php:6266 lib/php/monica/form.inc.php:6296 +msgid "New:" +msgstr "新:" + +#: lib/php/monica/form.inc.php:1269 lib/php/monica/form.inc.php:1444 +#: lib/php/monica/form.inc.php:1543 lib/php/monica/form.inc.php:2358 +#: lib/php/monica/form.inc.php:2585 lib/php/monica/form.inc.php:2793 +#: lib/php/monica/form.inc.php:2890 lib/php/monica/form.inc.php:2973 +#: lib/php/monica/form.inc.php:3620 +msgid "Source:" +msgstr "原文:" + +#: lib/php/monica/form.inc.php:1289 lib/php/monica/form.inc.php:1464 +#: lib/php/monica/form.inc.php:1583 lib/php/monica/form.inc.php:2605 +#: lib/php/monica/form.inc.php:2813 lib/php/monica/form.inc.php:2910 +#: lib/php/monica/form.inc.php:2993 +#, c-format +msgid "Please set it from %s." +msgstr "請由%s設定。" + +#: lib/php/monica/form.inc.php:1501 +msgid "Hide" +msgstr "隱藏" + +#: lib/php/monica/form.inc.php:1502 +msgid "Show" +msgstr "秀出" + +#: lib/php/monica/form.inc.php:1691 lib/php/monica/form.inc.php:1777 +#: lib/php/monica/form.inc.php:1887 +msgid "Choose" +msgstr "挑選" + +#: lib/php/monica/form.inc.php:2237 +msgid "Delete this file" +msgstr "刪掉檔案" + +#: lib/php/monica/form.inc.php:2267 lib/php/monica/form.inc.php:2368 +#: lib/php/monica/form.inc.php:2400 lib/php/monica/form.inc.php:2445 +#: lib/php/monica/form.inc.php:2506 +msgid "File name:" +msgstr "檔名:" + +#: lib/php/monica/form.inc.php:2274 lib/php/monica/form.inc.php:2375 +#: lib/php/monica/form.inc.php:2407 lib/php/monica/form.inc.php:2452 +#: lib/php/monica/form.inc.php:2513 +msgid "MIME file type:" +msgstr "MIME 檔案格式:" + +#: lib/php/monica/form.inc.php:2279 lib/php/monica/form.inc.php:2380 +#: lib/php/monica/form.inc.php:2412 lib/php/monica/form.inc.php:2457 +#: lib/php/monica/form.inc.php:2518 +msgid "File size:" +msgstr "檔案大小:" + +#: lib/php/monica/form.inc.php:2430 +#, c-format +msgid "Please upload it from %s." +msgstr "請由%s上傳。" + +#: lib/php/monica/form.inc.php:3128 +msgid "Address:" +msgstr "地址:" + +#: lib/php/monica/form.inc.php:3129 +msgid "Fill in your address here." +msgstr "請填上地址。" + +#: lib/php/monica/form.inc.php:3135 +msgid "Attachment:" +msgstr "附件:" + +#: lib/php/monica/form.inc.php:3139 +msgid "Attachment description:" +msgstr "附件說明:" + +#: lib/php/monica/form.inc.php:3158 lib/php/monica/form.inc.php:3171 +msgid "Content:" +msgstr "內文:" + +#: lib/php/monica/form.inc.php:3165 +msgid "City:" +msgstr "城市:" + +#: lib/php/monica/form.inc.php:3187 lib/php/monica/form.inc.php:3199 +#: lib/php/monica/form.inc.php:3217 lib/php/monica/form.inc.php:3241 +msgid "Country:" +msgstr "國家:" + +#: lib/php/monica/form.inc.php:3229 +msgid "Created:" +msgstr "建檔日期:" + +#: lib/php/monica/form.inc.php:3235 +msgid "Created by:" +msgstr "建檔者:" + +#: lib/php/monica/form.inc.php:3247 +msgid "Date:" +msgstr "日期:" + +#: lib/php/monica/form.inc.php:3253 lib/php/monica/form.inc.php:4292 +#: lib/php/monica/form.inc.php:4295 lib/php/monica/list.inc.php:310 +msgid "Disabled?" +msgstr "停用?" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 lib/php/monica/list.inc.php:2020 +msgid "Disabled" +msgstr "停用" + +#: lib/php/monica/form.inc.php:3254 lib/php/monica/form.inc.php:4293 +#: lib/php/monica/form.inc.php:4296 +msgid "Enabled" +msgstr "未停用" + +#: lib/php/monica/form.inc.php:3254 +msgid "Disable it." +msgstr "停掉。" + +#: lib/php/monica/form.inc.php:3260 lib/php/monica/form.inc.php:4675 +msgid "Description:" +msgstr "說明:" + +#: lib/php/monica/form.inc.php:3267 +msgid "E-mail:" +msgstr "E-mail:" + +#: lib/php/monica/form.inc.php:3273 +msgid "Fax:" +msgstr "傳真:" + +#: lib/php/monica/form.inc.php:3279 +msgid "Group:" +msgstr "群組:" + +#: lib/php/monica/form.inc.php:3285 lib/php/monica/form.inc.php:5559 +#: lib/php/monica/form.inc.php:5765 lib/php/monica/form.inc.php:5923 +#: lib/php/monica/form.inc.php:6016 +msgid "Hide?" +msgstr "隱藏?" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it" +msgstr "隱藏起來" + +#: lib/php/monica/form.inc.php:3286 +msgid "Show it" +msgstr "秀出來" + +#: lib/php/monica/form.inc.php:3286 +msgid "Hide it currently." +msgstr "暫勿秀出。" + +#: lib/php/monica/form.inc.php:3292 +msgid "Host:" +msgstr "主機:" + +#: lib/php/monica/form.inc.php:3298 lib/php/monica/list.inc.php:314 +msgid "HTML?" +msgstr "HTML ?" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2948 +#: lib/php/monica/list.inc.php:3062 +msgid "HTML" +msgstr "HTML" + +#: lib/php/monica/form.inc.php:3299 lib/php/monica/list.inc.php:2949 +#: lib/php/monica/list.inc.php:3063 +msgid "Plain text" +msgstr "純文字" + +#: lib/php/monica/form.inc.php:3299 +msgid "The submitted content is HTML." +msgstr "以上內文為 HTML 格式。" + +#: lib/php/monica/form.inc.php:3305 lib/php/monica/form.inc.php:5553 +#: lib/php/monica/form.inc.php:6092 +msgid "ID.:" +msgstr "代號:" + +#: lib/php/monica/form.inc.php:3311 +msgid "Introduction:" +msgstr "簡介:" + +#: lib/php/monica/form.inc.php:3312 +msgid "Fill in the introduction here." +msgstr "請填上簡介。" + +#: lib/php/monica/form.inc.php:3318 +msgid "IP:" +msgstr "IP :" + +#: lib/php/monica/form.inc.php:3324 +msgid "Keywords:" +msgstr "關鍵字:" + +#: lib/php/monica/form.inc.php:3330 +msgid "Language:" +msgstr "語言:" + +#: lib/php/monica/form.inc.php:3355 +msgid "Name:" +msgstr "名稱:" + +#: lib/php/monica/form.inc.php:3365 lib/php/monica/form.inc.php:6010 +msgid "Order:" +msgstr "次序:" + +#: lib/php/monica/form.inc.php:3371 +msgid "Organization:" +msgstr "所屬單位:" + +#: lib/php/monica/form.inc.php:3377 +msgid "Parent category:" +msgstr "大類:" + +#: lib/php/monica/form.inc.php:3378 +msgid "At the very top" +msgstr "最上層" + +#: lib/php/monica/form.inc.php:3391 lib/php/monica/form.inc.php:3428 +#: lib/php/monica/form.inc.php:3468 lib/php/monica/form.inc.php:4330 +#: lib/php/monica/form.inc.php:6380 +msgid "Password:" +msgstr "密碼:" + +#: lib/php/monica/form.inc.php:3407 lib/php/monica/form.inc.php:3444 +msgid "Confirm password:" +msgstr "確認密碼:" + +#: lib/php/monica/form.inc.php:3458 +msgid "(Leave them blank if you don't plan to change your password.)" +msgstr "(若你沒有要更改密碼,密碼欄請留白。)" + +#: lib/php/monica/form.inc.php:3484 +msgid "Page path:" +msgstr "網頁路徑:" + +#: lib/php/monica/form.inc.php:3490 +msgid "PDF. file:" +msgstr "PDF. 檔:" + +#: lib/php/monica/form.inc.php:3508 lib/php/monica/form.inc.php:3570 +#: lib/php/monica/form.inc.php:3680 lib/php/monica/form.inc.php:6169 +#: lib/php/monica/form.inc.php:6193 +msgid "Picture:" +msgstr "圖片:" + +#: lib/php/monica/form.inc.php:3531 lib/php/monica/form.inc.php:3615 +#: lib/php/monica/form.inc.php:3619 lib/php/monica/form.inc.php:3693 +msgid "Pic. caption:" +msgstr "圖片標題:" + +#: lib/php/monica/form.inc.php:3538 lib/php/monica/form.inc.php:3639 +#: lib/php/monica/form.inc.php:3699 +msgid "Pic. position:" +msgstr "圖片位置:" + +#: lib/php/monica/form.inc.php:3718 lib/php/monica/form.inc.php:3746 +#: lib/php/monica/form.inc.php:3780 +msgid "Pinyin:" +msgstr "拼音:" + +#: lib/php/monica/form.inc.php:3722 lib/php/monica/form.inc.php:3756 +msgid "Please fill in the Chinese first." +msgstr "請先填上中文。" + +#: lib/php/monica/form.inc.php:3801 +msgid "Subcategory:" +msgid_plural "Subcategories:" +msgstr[0] "子類:" + +#: lib/php/monica/form.inc.php:3823 +msgid "Script:" +msgstr "程式:" + +#: lib/php/monica/form.inc.php:3829 +msgid "S/N:" +msgstr "編號:" + +#: lib/php/monica/form.inc.php:3835 +msgid "Street:" +msgstr "街號:" + +#: lib/php/monica/form.inc.php:3841 +msgid "Subject:" +msgstr "主題:" + +#: lib/php/monica/form.inc.php:3847 +msgid "Telephone:" +msgstr "電話:" + +#: lib/php/monica/form.inc.php:3853 +msgid "Tel. (cell.):" +msgstr "行動電話:" + +#: lib/php/monica/form.inc.php:3859 +msgid "Tel. (home):" +msgstr "電話(宅):" + +#: lib/php/monica/form.inc.php:3865 +msgid "Tel. (office):" +msgstr "電話(公):" + +#: lib/php/monica/form.inc.php:3871 +msgid "Title:" +msgstr "標題:" + +#: lib/php/monica/form.inc.php:3891 +msgid "Value:" +msgstr "值:" + +#: lib/php/monica/form.inc.php:3897 +msgid "Visits:" +msgstr "上站次數:" + +#: lib/php/monica/form.inc.php:3903 +msgid "Visited:" +msgstr "上站日期:" + +#: lib/php/monica/form.inc.php:3909 +msgid "Updated:" +msgstr "維護日期:" + +#: lib/php/monica/form.inc.php:3915 +msgid "Updated by:" +msgstr "維護者:" + +#: lib/php/monica/form.inc.php:3921 +msgid "URL.:" +msgstr "網址:" + +#: lib/php/monica/form.inc.php:3927 +msgid "Zip code:" +msgstr "郵遞區號:" + +#: lib/php/monica/form.inc.php:4151 +msgid "Delete this user account" +msgstr "刪掉帳號" + +#: lib/php/monica/form.inc.php:4157 +msgid "This table provides you a form to add a new user account." +msgstr "本表提供建新帳號的表單。" + +#: lib/php/monica/form.inc.php:4161 +msgid "This table provides you a form to update a current user account." +msgstr "本表提供設定帳號的表單。" + +#: lib/php/monica/form.inc.php:4165 +msgid "This table provides you a form to delete a user account." +msgstr "本表提供刪除帳號的表單。" + +#: lib/php/monica/form.inc.php:4192 +msgid "Add a New User Account" +msgstr "建新帳號" + +#: lib/php/monica/form.inc.php:4196 +msgid "Update a Current User Account" +msgstr "設定帳號" + +#: lib/php/monica/form.inc.php:4200 +msgid "Delete a User Account" +msgstr "刪除帳號" + +#: lib/php/monica/form.inc.php:4213 +msgid "This is a super-user. You can only change parts of her infomation." +msgstr "這個人是總管理員,你只能設定她部份的資料。" + +#: lib/php/monica/form.inc.php:4220 +msgid "" +"This user has a datum. It cannot be deleted. To delete the user, its datum " +"must first be deleted." +msgid_plural "" +"This user has data. It cannot be deleted. To delete the user, all of its " +"data must first be deleted." +msgstr[0] "本帳號下有資料,不可直接刪除。要刪除帳號,請先刪除其下的資料。" + +#: lib/php/monica/form.inc.php:4282 +msgid "Administrator?" +msgstr "網站管理員?" + +#: lib/php/monica/form.inc.php:4283 +msgid "Administrator" +msgstr "網站管理員" + +#: lib/php/monica/form.inc.php:4283 +msgid "Non-administrator" +msgstr "普通使用者" + +#: lib/php/monica/form.inc.php:4296 +msgid "Disable this user account." +msgstr "帳號停用。" + +#: lib/php/monica/form.inc.php:4305 lib/php/monica/form.inc.php:4307 +#: lib/php/monica/form.inc.php:6372 +msgid "User ID.:" +msgstr "使用者代號:" + +#: lib/php/monica/form.inc.php:4314 +msgid "Pref. language:" +msgstr "語言偏好:" + +#: lib/php/monica/form.inc.php:4320 +msgid "Full name:" +msgstr "姓名:" + +#: lib/php/monica/form.inc.php:4348 lib/php/monica/form.inc.php:4400 +#: lib/php/monica/form.inc.php:4422 lib/php/monica/form.inc.php:4496 +#: lib/php/monica/form.inc.php:4962 lib/php/monica/form.inc.php:5001 +#: lib/php/monica/form.inc.php:5017 lib/php/monica/form.inc.php:5069 +msgid "Belonging to:" +msgstr "隸屬群組:" + +#: lib/php/monica/form.inc.php:4539 lib/php/monica/form.inc.php:4547 +#: lib/php/monica/form.inc.php:4574 +msgid "Fail logins:" +msgstr "登入失敗:" + +#: lib/php/monica/form.inc.php:4551 lib/php/monica/form.inc.php:4578 +msgid "(Locked)" +msgstr "(鎖住)" + +#: lib/php/monica/form.inc.php:4557 +msgid "Reset the counter and activate the account" +msgstr "歸零並重啟帳號。" + +#: lib/php/monica/form.inc.php:4603 +msgid "Delete this group" +msgstr "刪掉群組" + +#: lib/php/monica/form.inc.php:4609 +msgid "This table provides you a form to add a new group." +msgstr "本表提供建新群組的表單。" + +#: lib/php/monica/form.inc.php:4613 +msgid "This table provides you a form to update a current group." +msgstr "本表提供設定群組的表單。" + +#: lib/php/monica/form.inc.php:4617 +msgid "This table provides you a form to delete a group." +msgstr "本表提供刪除群組的表單。" + +#: lib/php/monica/form.inc.php:4642 +msgid "Add a New Group" +msgstr "建新群組" + +#: lib/php/monica/form.inc.php:4646 +msgid "Update a Current Group" +msgstr "設定群組" + +#: lib/php/monica/form.inc.php:4650 +msgid "Delete a Group" +msgstr "刪除群組" + +#: lib/php/monica/form.inc.php:4657 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "這是最高管理員的群組,你只能設定它部份的資料。" + +#: lib/php/monica/form.inc.php:4666 lib/php/monica/form.inc.php:4668 +msgid "Group ID.:" +msgstr "群組代號:" + +#: lib/php/monica/form.inc.php:4681 +msgid "Add a user" +msgstr "增加成員" + +#: lib/php/monica/form.inc.php:4688 lib/php/monica/form.inc.php:4728 +#: lib/php/monica/form.inc.php:4746 lib/php/monica/form.inc.php:4799 +msgid "User member:" +msgid_plural "User members:" +msgstr[0] "使用者成員:" + +#: lib/php/monica/form.inc.php:4819 lib/php/monica/form.inc.php:4956 +msgid "Add a group" +msgstr "增加群組" + +#: lib/php/monica/form.inc.php:4826 lib/php/monica/form.inc.php:4866 +#: lib/php/monica/form.inc.php:4883 lib/php/monica/form.inc.php:4936 +msgid "Group member:" +msgid_plural "Group members:" +msgstr[0] "群組成員:" + +#: lib/php/monica/form.inc.php:5103 lib/php/monica/form.inc.php:5178 +msgid "Delete this membership record" +msgstr "刪掉這筆成員關係" + +#: lib/php/monica/form.inc.php:5109 lib/php/monica/form.inc.php:5184 +msgid "This table provides you a form to add a new membership record." +msgstr "本表提供建新成員關係的表單。" + +#: lib/php/monica/form.inc.php:5113 lib/php/monica/form.inc.php:5188 +msgid "This table provides you a form to change a current membership record." +msgstr "本表提供變更成員關係的表單。" + +#: lib/php/monica/form.inc.php:5117 lib/php/monica/form.inc.php:5192 +msgid "This table provides you a form to delete a membership record." +msgstr "本表提供刪除成員關係的表單。" + +#: lib/php/monica/form.inc.php:5140 +msgid "Add a New User Membership Record" +msgstr "建新使用者成員關係" + +#: lib/php/monica/form.inc.php:5144 +msgid "Change a Current User Membership Record" +msgstr "變更使用者成員關係" + +#: lib/php/monica/form.inc.php:5148 +msgid "Delete a User Membership Record" +msgstr "刪除使用者成員關係" + +#: lib/php/monica/form.inc.php:5158 lib/php/monica/form.inc.php:5233 +msgid "Member:" +msgstr "成員:" + +#: lib/php/monica/form.inc.php:5215 +msgid "Add a New Group Membership Record" +msgstr "建新群組成員關係" + +#: lib/php/monica/form.inc.php:5219 +msgid "Change a Current Group Membership Record" +msgstr "變更群組成員關係" + +#: lib/php/monica/form.inc.php:5223 +msgid "Delete a Group Membership Record" +msgstr "刪除群組成員關係" + +#: lib/php/monica/form.inc.php:5253 +msgid "Delete this user preference" +msgstr "刪掉這筆使用者偏好" + +#: lib/php/monica/form.inc.php:5259 +msgid "This table provides you a form to add a new user preference." +msgstr "本表提供建新使用者偏好的表單。" + +#: lib/php/monica/form.inc.php:5263 +msgid "This table provides you a form to modify a current user preference." +msgstr "本表提供修改使用者偏好的表單。" + +#: lib/php/monica/form.inc.php:5267 +msgid "This table provides you a form to delete a user preference." +msgstr "本表提供刪除使用者偏好的表單。" + +#: lib/php/monica/form.inc.php:5290 +msgid "Add a New User Preference" +msgstr "建新使用者偏好" + +#: lib/php/monica/form.inc.php:5294 +msgid "Modify a Current User Preference" +msgstr "修改使用者偏好" + +#: lib/php/monica/form.inc.php:5298 +msgid "Delete a User Preference" +msgstr "刪除使用者偏好" + +#: lib/php/monica/form.inc.php:5308 lib/php/monica/form.inc.php:5494 +msgid "User:" +msgstr "使用者:" + +#: lib/php/monica/form.inc.php:5309 lib/php/monica/list.inc.php:2588 +msgid "Everyone" +msgstr "所有人" + +#: lib/php/monica/form.inc.php:5315 +msgid "Domain:" +msgstr "適用範圍:" + +#: lib/php/monica/form.inc.php:5316 lib/php/monica/list.inc.php:2592 +msgid "Everywhere" +msgstr "所有地方" + +#: lib/php/monica/form.inc.php:5336 +msgid "Delete this script privilege record" +msgstr "刪掉這筆程式權限資料" + +#: lib/php/monica/form.inc.php:5342 +msgid "This table provides you a form to add a new script privilege record." +msgstr "本表提供建新程式權限資料的表單。" + +#: lib/php/monica/form.inc.php:5346 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "本表提供變更程式權限資料的表單。" + +#: lib/php/monica/form.inc.php:5350 +msgid "This table provides you a form to delete a script privilege record." +msgstr "本表提供刪除程式權限資料的表單。" + +#: lib/php/monica/form.inc.php:5373 +msgid "Add a New Script Privilege Record" +msgstr "建新程式權限資料" + +#: lib/php/monica/form.inc.php:5377 +msgid "Change a Current Script Privilege Record" +msgstr "變更程式權限資料" + +#: lib/php/monica/form.inc.php:5381 +msgid "Delete a Script Privilege Record" +msgstr "刪除程式權限資料" + +#: lib/php/monica/form.inc.php:5391 +msgid "Privilege:" +msgstr "權限:" + +#: lib/php/monica/form.inc.php:5413 +msgid "Delete this user request" +msgstr "刪掉這筆使用者申請" + +#: lib/php/monica/form.inc.php:5419 +msgid "This table provides you a form to add a new user request." +msgstr "本表提供建新使用者申請的表單。" + +#: lib/php/monica/form.inc.php:5423 +msgid "This table provides you a form to update a current user request." +msgstr "本表提供更新使用者申請的表單。" + +#: lib/php/monica/form.inc.php:5427 +msgid "This table provides you a form to delete a user request." +msgstr "本表提供刪除使用者申請的表單。" + +#: lib/php/monica/form.inc.php:5450 +msgid "Add a New User Request" +msgstr "建新使用者申請" + +#: lib/php/monica/form.inc.php:5454 +msgid "Update a Current User Request" +msgstr "更新使用者申請" + +#: lib/php/monica/form.inc.php:5458 +msgid "Delete a User Request" +msgstr "刪除使用者申請" + +#: lib/php/monica/form.inc.php:5466 +msgid "Join" +msgstr "加入" + +#: lib/php/monica/form.inc.php:5470 +msgid "Change e-mail" +msgstr "變更 E-mail" + +#: lib/php/monica/form.inc.php:5474 +msgid "Reset password" +msgstr "重設密碼" + +#: lib/php/monica/form.inc.php:5482 +msgid "Expiration:" +msgstr "到期日:" + +#: lib/php/monica/form.inc.php:5488 lib/php/monica/form.inc.php:6450 +msgid "Type:" +msgstr "類型:" + +#: lib/php/monica/form.inc.php:5495 +msgid "Anonymous" +msgstr "未具名" + +#: lib/php/monica/form.inc.php:5501 +msgid "Arguments:" +msgstr "備註資料:" + +#: lib/php/monica/form.inc.php:5519 +msgid "Delete this category" +msgstr "刪掉這個分類" + +#: lib/php/monica/form.inc.php:5525 +msgid "This table provides you a form to add a new category." +msgstr "本表提供建新分類的表單。" + +#: lib/php/monica/form.inc.php:5529 +msgid "This table provides you a form to edit a current category." +msgstr "本表提供編輯分類的表單。" + +#: lib/php/monica/form.inc.php:5533 +msgid "This table provides you a form to delete a category." +msgstr "本表提供刪除分類的表單。" + +#: lib/php/monica/form.inc.php:5543 +msgid "" +"This category has a subcategory. It cannot be deleted. To delete the " +"category, its subcategory must first be deleted." +msgid_plural "" +"This category has subcategories. It cannot be deleted. To delete the " +"category, all of its subcategories must first be deleted." +msgstr[0] "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: lib/php/monica/form.inc.php:5560 +msgid "Hide this category" +msgstr "隱藏本類" + +#: lib/php/monica/form.inc.php:5560 +msgid "Show this category" +msgstr "秀出本類" + +#: lib/php/monica/form.inc.php:5560 +msgid "Hide this category currently." +msgstr "暫勿秀出本類。" + +#: lib/php/monica/form.inc.php:5577 +msgid "Delete this categorization record" +msgstr "刪掉這筆分類資料" + +#: lib/php/monica/form.inc.php:5583 +msgid "This table provides you a form to add a new categorization record." +msgstr "本表提供建新分類資料的表單。" + +#: lib/php/monica/form.inc.php:5587 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "本表提供變更分類資料的表單。" + +#: lib/php/monica/form.inc.php:5591 +msgid "This table provides you a form to delete a categorization record." +msgstr "本表提供刪除分類資料的表單。" + +#: lib/php/monica/form.inc.php:5636 +msgid "Add a New Link Category" +msgstr "建新連結分類" + +#: lib/php/monica/form.inc.php:5640 +msgid "Edit a Current Link Category" +msgstr "編輯連結分類" + +#: lib/php/monica/form.inc.php:5644 +msgid "Delete a Link Category" +msgstr "刪除連結分類" + +#: lib/php/monica/form.inc.php:5654 +msgid "" +"This category has a link. It cannot be deleted. To delete the category, " +"its link must first be deleted." +msgid_plural "" +"This category has links. It cannot be deleted. To delete the category, all " +"of its links must first be deleted." +msgstr[0] "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: lib/php/monica/form.inc.php:5673 lib/php/monica/form.inc.php:5837 +msgid "Link:" +msgid_plural "Links:" +msgstr[0] "連結:" + +#: lib/php/monica/form.inc.php:5710 +msgid "Delete this related link" +msgstr "刪掉這筆相關連結" + +#: lib/php/monica/form.inc.php:5716 +msgid "This table provides you a form to add a new related link." +msgstr "本表提供建新相關連結的表單。" + +#: lib/php/monica/form.inc.php:5720 +msgid "This table provides you a form to edit a current related link." +msgstr "本表提供編輯相關連結的表單。" + +#: lib/php/monica/form.inc.php:5724 +msgid "This table provides you a form to delete a related link." +msgstr "本表提供刪除相關連結的表單。" + +#: lib/php/monica/form.inc.php:5747 +msgid "Add a New Related Link" +msgstr "建新相關連結" + +#: lib/php/monica/form.inc.php:5751 +msgid "Edit a Current Related Link" +msgstr "編輯相關連結" + +#: lib/php/monica/form.inc.php:5755 +msgid "Delete a Related Link" +msgstr "刪除相關連結" + +#: lib/php/monica/form.inc.php:5766 +msgid "Hide this link" +msgstr "隱藏本連結" + +#: lib/php/monica/form.inc.php:5766 lib/php/monica/form.inc.php:5924 +msgid "Show this page" +msgstr "秀出本頁" + +#: lib/php/monica/form.inc.php:5766 +msgid "Hide this related link currently." +msgstr "暫勿秀出本相關連結。" + +#: lib/php/monica/form.inc.php:5773 lib/php/monica/form.inc.php:5830 +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "分類:" + +#: lib/php/monica/form.inc.php:5812 +msgid "Add a New Link Categorization Record" +msgstr "建新連結分類資料" + +#: lib/php/monica/form.inc.php:5816 +msgid "Change a Current Link Categorization Record" +msgstr "變更連結分類資料" + +#: lib/php/monica/form.inc.php:5820 +msgid "Delete a Link Categorization Record" +msgstr "刪除連結分類資料" + +#: lib/php/monica/form.inc.php:5860 +msgid "Delete this page" +msgstr "刪掉這一頁" + +#: lib/php/monica/form.inc.php:5866 +msgid "This table provides you a form to write a new page." +msgstr "本表提供撰寫網頁的表單。" + +#: lib/php/monica/form.inc.php:5870 +msgid "This table provides you a form to edit a current page." +msgstr "本表提供編輯網頁的表單。" + +#: lib/php/monica/form.inc.php:5874 +msgid "This table provides you a form to delete a page." +msgstr "本表提供刪除網頁的表單。" + +#: lib/php/monica/form.inc.php:5899 +msgid "Write a New Page" +msgstr "撰寫網頁" + +#: lib/php/monica/form.inc.php:5903 +msgid "Edit a Current Page" +msgstr "編輯網頁" + +#: lib/php/monica/form.inc.php:5907 +msgid "Delete a Page" +msgstr "刪除網頁" + +#: lib/php/monica/form.inc.php:5915 +msgid "Preview this page." +msgstr "預覽本頁。" + +#: lib/php/monica/form.inc.php:5924 +msgid "Hide this page" +msgstr "隱藏本頁" + +#: lib/php/monica/form.inc.php:5924 +msgid "Hide this page currently." +msgstr "暫勿秀出本頁。" + +#: lib/php/monica/form.inc.php:5947 +msgid "Delete this news article" +msgstr "刪掉這則新聞" + +#: lib/php/monica/form.inc.php:5953 +msgid "This table provides you a form to write a new news article." +msgstr "本表提供撰寫新聞的表單。" + +#: lib/php/monica/form.inc.php:5957 +msgid "This table provides you a form to edit a current news article." +msgstr "本表提供編輯新聞的表單。" + +#: lib/php/monica/form.inc.php:5961 +msgid "This table provides you a form to delete a news article." +msgstr "本表提供刪除新聞的表單。" + +#: lib/php/monica/form.inc.php:5986 +msgid "Write a New News Article" +msgstr "撰寫新聞" + +#: lib/php/monica/form.inc.php:5990 +msgid "Edit a Current News Article" +msgstr "編輯新聞" + +#: lib/php/monica/form.inc.php:5994 +msgid "Delete a News Article" +msgstr "刪除新聞" + +#: lib/php/monica/form.inc.php:6002 +msgid "Preview this news article." +msgstr "預覽這則新聞。" + +#: lib/php/monica/form.inc.php:6017 +msgid "Hide this news article" +msgstr "隱藏這則新聞" + +#: lib/php/monica/form.inc.php:6017 +msgid "Show this news article" +msgstr "秀出這則新聞" + +#: lib/php/monica/form.inc.php:6017 +msgid "Hide this news article currently." +msgstr "暫勿秀出這則新聞。" + +#: lib/php/monica/form.inc.php:6037 +msgid "Delete this country record" +msgstr "刪掉這筆國家資料" + +#: lib/php/monica/form.inc.php:6043 +msgid "This table provides you a form to add a new country record." +msgstr "本表提供建新國家資料的表單。" + +#: lib/php/monica/form.inc.php:6047 +msgid "This table provides you a form to edit a current country record." +msgstr "本表提供編輯國家資料的表單。" + +#: lib/php/monica/form.inc.php:6051 +msgid "This table provides you a form to delete a country record." +msgstr "本表提供刪除國家資料的表單。" + +#: lib/php/monica/form.inc.php:6074 +msgid "Add a New Country Record" +msgstr "建新國家資料" + +#: lib/php/monica/form.inc.php:6078 +msgid "Edit a Current Country Record" +msgstr "編輯國家資料" + +#: lib/php/monica/form.inc.php:6082 +msgid "Delete a Country Record" +msgstr "刪除國家資料" + +#: lib/php/monica/form.inc.php:6098 lib/php/monica/list.inc.php:3391 +msgid "Special?" +msgstr "特殊?" + +#: lib/php/monica/form.inc.php:6099 +msgid "A special record" +msgstr "特殊記錄" + +#: lib/php/monica/form.inc.php:6099 +msgid "A normal country" +msgstr "一般國家" + +#: lib/php/monica/form.inc.php:6099 +msgid "This is a special record." +msgstr "這一筆是特殊記錄。" + +#: lib/php/monica/form.inc.php:6128 +msgid "This table provides you a form to add a new picture." +msgstr "本表提供建新圖片的表單。" + +#: lib/php/monica/form.inc.php:6132 +msgid "This table provides you a form to modify a current picture." +msgstr "本表提供修改圖片的表單。" + +#: lib/php/monica/form.inc.php:6143 +msgid "Upload a New Picture" +msgstr "建新圖片" + +#: lib/php/monica/form.inc.php:6147 +msgid "Modify a Current Picture" +msgstr "修改圖片" + +#: lib/php/monica/form.inc.php:6248 lib/php/monica/form.inc.php:6260 +msgid "Ratio:" +msgstr "比例:" + +#: lib/php/monica/form.inc.php:6285 lib/php/monica/form.inc.php:6295 +msgid "Upload:" +msgstr "上傳:" + +#: lib/php/monica/form.inc.php:6326 +msgid "This table provides you a form to log in." +msgstr "本表提供登入的表單。" + +#: lib/php/monica/form.inc.php:6332 +msgid "Identify Yourself" +msgstr "請出示身份" + +#: lib/php/monica/form.inc.php:6341 lib/php/monica/init.inc.php:505 +msgid "" +"Log-in is temporarily closed for maintainance now. Please come again " +"later. Sorry for the inconvienence." +msgstr "網站維護中,暫請勿入。造成任何不便,敬請見諒。" + +#: lib/php/monica/form.inc.php:6350 +msgid "Log in" +msgstr "登入" + +#: lib/php/monica/form.inc.php:6397 +msgid "Remember me." +msgstr "勿忘我。" + +#: lib/php/monica/form.inc.php:6424 +msgid "Rebuild the Pages" +msgstr "重製網頁" + +#: lib/php/monica/form.inc.php:6433 +msgid "Confirm" +msgstr "確認" + +#: lib/php/monica/form.inc.php:6475 +msgid "Log Out" +msgstr "登出" + +#: lib/php/monica/form.inc.php:6484 +msgid "Log out" +msgstr "登出" + +#: lib/php/monica/form.inc.php:6498 +msgid "Are you sure you want to log out?" +msgstr "你確定要登出嗎?" + +#: lib/php/monica/init.inc.php:114 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" +"抱歉,我們不歡迎加裝 FunWebProduct 外掛(如 Smiley Central 、 PopSwatter 、 " +"Spin4Dough 、 My Mail Signature 、 My Mail Stationery 、 My Mail Stamp 、 " +"Cursor Mania ……等等)的瀏覽器。 FunWebProduct 會重抓你看過的每一頁網頁,造" +"成網站負荷加倍,甚至當機。請先移除 FunWebProduct ,再上來瀏覽。" + +#: lib/php/monica/init.inc.php:503 lib/php/monica/init.inc.php:504 +msgid "Log-In Closed" +msgstr "暫請勿入" + +#: lib/php/monica/init.inc.php:524 lib/php/monica/init.inc.php:525 +msgid "Development Site Closed" +msgstr "研發網站已關閉" + +#: lib/php/monica/init.inc.php:526 +msgid "Development site is closed. Please work on the live site." +msgstr "研發網站已關閉,請勿在此登入。" + +#: lib/php/monica/links.inc.php:271 +msgid "Related Links" +msgstr "相關連結" + +#: lib/php/monica/list.inc.php:130 +msgid "Malformed" +msgstr "格式錯亂" + +#: lib/php/monica/list.inc.php:155 +msgid "OK" +msgstr "好" + +#: lib/php/monica/list.inc.php:155 +msgid "Unreachable" +msgstr "連不上" + +#: lib/php/monica/list.inc.php:290 lib/php/monica/list.inc.php:1534 +#: lib/php/monica/list.inc.php:3642 +msgid "(query phrase)" +msgstr "(檢索字詞)" + +#: lib/php/monica/list.inc.php:300 +msgid "S/N" +msgstr "編號" + +#: lib/php/monica/list.inc.php:301 +msgid "Created" +msgstr "建檔日期" + +#: lib/php/monica/list.inc.php:302 +msgid "Created by" +msgstr "建檔者" + +#: lib/php/monica/list.inc.php:303 +msgid "Updated" +msgstr "維護日期" + +#: lib/php/monica/list.inc.php:304 +msgid "Updated by" +msgstr "維護者" + +#: lib/php/monica/list.inc.php:306 +msgid "Content" +msgstr "內文" + +#: lib/php/monica/list.inc.php:307 +msgid "Category" +msgstr "分類" + +#: lib/php/monica/list.inc.php:308 +msgid "Coverage" +msgstr "涵蓋範圍" + +#: lib/php/monica/list.inc.php:309 +msgid "Date" +msgstr "日期" + +#: lib/php/monica/list.inc.php:311 +msgid "Description" +msgstr "說明" + +#: lib/php/monica/list.inc.php:312 +msgid "E-mail" +msgstr "E-mail" + +#: lib/php/monica/list.inc.php:313 +msgid "Hidden?" +msgstr "隱藏?" + +#: lib/php/monica/list.inc.php:315 +msgid "ID." +msgstr "代號" + +#: lib/php/monica/list.inc.php:316 +msgid "Keywords" +msgstr "關鍵字" + +#: lib/php/monica/list.inc.php:317 +msgid "Name" +msgstr "名稱" + +#: lib/php/monica/list.inc.php:318 +msgid "Order" +msgstr "次序" + +#: lib/php/monica/list.inc.php:319 +msgid "Page path" +msgstr "網頁路徑" + +#: lib/php/monica/list.inc.php:320 +msgid "Picture" +msgstr "圖片" + +#: lib/php/monica/list.inc.php:321 +msgid "Pic. ratio" +msgstr "圖片比例" + +#: lib/php/monica/list.inc.php:322 +msgid "Pic. caption" +msgstr "圖片標題" + +#: lib/php/monica/list.inc.php:323 +msgid "Pic. position" +msgstr "圖片位置" + +#: lib/php/monica/list.inc.php:324 +msgid "Subject" +msgstr "主題" + +#: lib/php/monica/list.inc.php:325 +msgid "Title" +msgstr "標題" + +#: lib/php/monica/list.inc.php:326 +msgid "URL." +msgstr "網址" + +#: lib/php/monica/list.inc.php:327 +msgid "Status (slow)" +msgstr "狀態(慢)" + +#: lib/php/monica/list.inc.php:336 +msgid "Select" +msgstr "選擇" + +#: lib/php/monica/list.inc.php:339 +msgid "Select a Data Record" +msgstr "選擇資料" + +#: lib/php/monica/list.inc.php:343 +msgid "Edit" +msgstr "設定" + +#: lib/php/monica/list.inc.php:345 +msgid "Manage Data" +msgstr "管理資料" + +#: lib/php/monica/list.inc.php:749 +msgid "Nothing found. Please try another query." +msgstr "查無相符的資料,請重新搜尋。" + +#: lib/php/monica/list.inc.php:752 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: lib/php/monica/list.inc.php:759 +#, c-format +msgid "Your query found %s record." +msgid_plural "Your query found %s records." +msgstr[0] "共 %s 筆相符的資料。" + +#: lib/php/monica/list.inc.php:766 +#, c-format +msgid "%s record." +msgid_plural "%s records." +msgstr[0] "共 %s 筆資料。" + +#: lib/php/monica/list.inc.php:775 +#, c-format +msgid "Your query found %s record, listing %s to %s." +msgid_plural "Your query found %s records, listing %s to %s." +msgstr[0] "共 %s 筆相符的資料,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:784 +#, c-format +msgid "%s record, listing %s to %s." +msgid_plural "%s records, listing %s to %s." +msgstr[0] "共 %s 筆資料,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:855 lib/php/monica/list.inc.php:860 +#: lib/php/monica/list.inc.php:869 +#, c-format +msgid "Page number (%s) invalid. Please specify a valid page number." +msgstr "頁數( %s )無效,請設成有效的數字。" + +#: lib/php/monica/list.inc.php:874 +#, c-format +msgid "" +"Page number (%d) out of range. Please specify a number between 1 and %d." +msgstr "頁數( %d )超出範圍,請設在 1 到 %d 之間。" + +#: lib/php/monica/list.inc.php:1138 lib/php/monica/list.inc.php:1151 +#, c-format +msgid "You cannot sort by \"%s\"." +msgstr "無法以 %s 排序。" + +#: lib/php/monica/list.inc.php:1512 +msgid "Search" +msgstr "搜尋" + +#: lib/php/monica/list.inc.php:1610 +msgid "Index" +msgstr "目錄" + +#: lib/php/monica/list.inc.php:1634 +msgid "First" +msgstr "第一頁" + +#: lib/php/monica/list.inc.php:1647 +msgid "Previous" +msgstr "前一頁" + +#: lib/php/monica/list.inc.php:1696 +msgid "Next" +msgstr "下一頁" + +#: lib/php/monica/list.inc.php:1714 +msgid "Last" +msgstr "最末頁" + +#: lib/php/monica/list.inc.php:1736 +msgid "Page:" +msgstr "頁:" + +#: lib/php/monica/list.inc.php:1776 lib/php/monica/list.inc.php:1900 +msgid "Delete the selected items." +msgstr "刪除勾選的項目。" + +#: lib/php/monica/list.inc.php:1805 +msgid "No." +msgstr "編號" + +#: lib/php/monica/list.inc.php:1813 lib/php/monica/list.inc.php:1873 +msgid "View" +msgstr "瀏覽" + +#: lib/php/monica/list.inc.php:1925 +msgid "Set" +msgstr "設定" + +#: lib/php/monica/list.inc.php:1941 +msgid "Rows per page:" +msgstr "每頁顯示筆數:" + +#: lib/php/monica/list.inc.php:1946 +msgid "Display columns:" +msgstr "顯示欄位:" + +#: lib/php/monica/list.inc.php:1976 +msgid "Select a User" +msgstr "選擇帳號" + +#: lib/php/monica/list.inc.php:1977 +msgid "Manage Users" +msgstr "管理帳號" + +#: lib/php/monica/list.inc.php:1982 +msgid "User ID." +msgstr "使用者代號" + +#: lib/php/monica/list.inc.php:1983 +msgid "Full name" +msgstr "姓名" + +#: lib/php/monica/list.inc.php:1984 +msgid "Deleted?" +msgstr "已刪?" + +#: lib/php/monica/list.inc.php:1985 +msgid "Pref. language" +msgstr "語言偏好" + +#: lib/php/monica/list.inc.php:1986 +msgid "Visits" +msgstr "上站次數" + +#: lib/php/monica/list.inc.php:1987 +msgid "Visited" +msgstr "上站日期" + +#: lib/php/monica/list.inc.php:1988 +msgid "IP" +msgstr "IP" + +#: lib/php/monica/list.inc.php:1989 +msgid "Host" +msgstr "主機" + +#: lib/php/monica/list.inc.php:1990 +msgid "From country" +msgstr "上站國家" + +#: lib/php/monica/list.inc.php:1991 +msgid "Fail logins" +msgstr "登入失敗" + +#: lib/php/monica/list.inc.php:2024 +msgid "Deleted" +msgstr "已刪" + +#: lib/php/monica/list.inc.php:2035 +msgid "Add a new user account." +msgstr "建新帳號。" + +#: lib/php/monica/list.inc.php:2045 +msgid "Search for a user:" +msgstr "搜尋使用者:" + +#: lib/php/monica/list.inc.php:2063 +#, c-format +msgid "Your query found %s user." +msgid_plural "Your query found %s users." +msgstr[0] "共 %s 個相符的使用者。" + +#: lib/php/monica/list.inc.php:2070 +#, c-format +msgid "%s user." +msgid_plural "%s users." +msgstr[0] "共 %s 個使用者。" + +#: lib/php/monica/list.inc.php:2079 +#, c-format +msgid "Your query found %s user, listing %s to %s." +msgid_plural "Your query found %s users, listing %s to %s." +msgstr[0] "共 %s 個相符的使用者,列出第 %s 個到第 %s 個。" + +#: lib/php/monica/list.inc.php:2088 +#, c-format +msgid "%s user, listing %s to %s." +msgid_plural "%s users, listing %s to %s." +msgstr[0] "共 %s 個使用者,列出第 %s 個到第 %s 個。" + +#: lib/php/monica/list.inc.php:2107 +msgid "Select a Group" +msgstr "選擇群組" + +#: lib/php/monica/list.inc.php:2108 +msgid "Manage Groups" +msgstr "管理群組" + +#: lib/php/monica/list.inc.php:2113 +msgid "Group ID." +msgstr "群組代號" + +#: lib/php/monica/list.inc.php:2121 +msgid "Add a new group." +msgstr "建新群組。" + +#: lib/php/monica/list.inc.php:2131 +msgid "Search for a group:" +msgstr "搜尋群組:" + +#: lib/php/monica/list.inc.php:2149 +#, c-format +msgid "Your query found %s group." +msgid_plural "Your query found %s groups." +msgstr[0] "共 %s 個相符的群組。" + +#: lib/php/monica/list.inc.php:2156 +#, c-format +msgid "%s group." +msgid_plural "%s groups." +msgstr[0] "共 %s 個群組。" + +#: lib/php/monica/list.inc.php:2165 +#, c-format +msgid "Your query found %s group, listing %s to %s." +msgid_plural "Your query found %s groups, listing %s to %s." +msgstr[0] "共 %s 個相符的群組,列出第 %s 個到第 %s 個。" + +#: lib/php/monica/list.inc.php:2174 +#, c-format +msgid "%s group, listing %s to %s." +msgid_plural "%s groups, listing %s to %s." +msgstr[0] "共 %s 個群組,列出第 %s 個到第 %s 個。" + +#: lib/php/monica/list.inc.php:2194 +msgid "Select a User Membership Record" +msgstr "選擇使用者成員關係" + +#: lib/php/monica/list.inc.php:2195 +msgid "Manage User Membership" +msgstr "管理使用者成員關係" + +#: lib/php/monica/list.inc.php:2200 lib/php/monica/list.inc.php:2323 +msgid "Group" +msgstr "群組" + +#: lib/php/monica/list.inc.php:2201 lib/php/monica/list.inc.php:2324 +msgid "Member" +msgstr "成員" + +#: lib/php/monica/list.inc.php:2244 lib/php/monica/list.inc.php:2375 +msgid "Add a new membership record." +msgstr "建新成員關係。" + +#: lib/php/monica/list.inc.php:2254 lib/php/monica/list.inc.php:2385 +msgid "Search for a membership record:" +msgstr "搜尋成員關係:" + +#: lib/php/monica/list.inc.php:2272 lib/php/monica/list.inc.php:2403 +#, c-format +msgid "Your query found %s membership record." +msgid_plural "Your query found %s membership records." +msgstr[0] "共 %s 筆相符的成員關係。" + +#: lib/php/monica/list.inc.php:2279 lib/php/monica/list.inc.php:2410 +#, c-format +msgid "%s membership record." +msgid_plural "%s membership records." +msgstr[0] "共 %s 筆成員關係。" + +#: lib/php/monica/list.inc.php:2288 lib/php/monica/list.inc.php:2419 +#, c-format +msgid "Your query found %s membership record, listing %s to %s." +msgid_plural "Your query found %s membership records, listing %s to %s." +msgstr[0] "共 %s 筆相符的成員關係,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2297 lib/php/monica/list.inc.php:2428 +#, c-format +msgid "%s membership record, listing %s to %s." +msgid_plural "%s membership records, listing %s to %s." +msgstr[0] "共 %s 筆成員關係,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2317 +msgid "Select a Group Membership Record" +msgstr "選擇群組成員關係" + +#: lib/php/monica/list.inc.php:2318 +msgid "Manage Group Membership" +msgstr "管理群組成員關係" + +#: lib/php/monica/list.inc.php:2448 +msgid "Select a Script Privilege Record" +msgstr "選擇程式權限" + +#: lib/php/monica/list.inc.php:2449 +msgid "Manage Script Privileges" +msgstr "管理程式權限" + +#: lib/php/monica/list.inc.php:2454 +msgid "Script" +msgstr "程式" + +#: lib/php/monica/list.inc.php:2455 +msgid "Privilege" +msgstr "權限" + +#: lib/php/monica/list.inc.php:2493 +msgid "Add a new script privilege record." +msgstr "建新程式權限資料。" + +#: lib/php/monica/list.inc.php:2503 +msgid "Search for a script privilege record:" +msgstr "搜尋程式權限:" + +#: lib/php/monica/list.inc.php:2521 +#, c-format +msgid "Your query found %s script privilege record." +msgid_plural "Your query found %s script privilege records." +msgstr[0] "共 %s 筆相符的程式權限。" + +#: lib/php/monica/list.inc.php:2528 +#, c-format +msgid "%s script privilege record." +msgid_plural "%s script privilege records." +msgstr[0] "共 %s 筆程式權限。" + +#: lib/php/monica/list.inc.php:2537 +#, c-format +msgid "Your query found %s script privilege record, listing %s to %s." +msgid_plural "Your query found %s script privilege records, listing %s to %s." +msgstr[0] "共 %s 筆相符的程式權限,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2546 +#, c-format +msgid "%s script privilege record, listing %s to %s." +msgid_plural "%s script privilege records, listing %s to %s." +msgstr[0] "共 %s 筆程式權限,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2566 +msgid "Select a User Preference" +msgstr "選擇使用者偏好" + +#: lib/php/monica/list.inc.php:2567 +msgid "Manage User Preferences" +msgstr "管理使用者偏好" + +#: lib/php/monica/list.inc.php:2574 lib/php/monica/list.inc.php:2689 +msgid "User" +msgstr "使用者" + +#: lib/php/monica/list.inc.php:2575 +msgid "Domain" +msgstr "適用範圍" + +#: lib/php/monica/list.inc.php:2576 +msgid "Value" +msgstr "值" + +#: lib/php/monica/list.inc.php:2610 +msgid "Add a new user preference." +msgstr "建新使用者偏好。" + +#: lib/php/monica/list.inc.php:2620 +msgid "Search for a user preference:" +msgstr "搜尋使用者偏好:" + +#: lib/php/monica/list.inc.php:2638 +#, c-format +msgid "Your query found %s user preference." +msgid_plural "Your query found %s user preferences." +msgstr[0] "共 %s 筆相符的使用者偏好。" + +#: lib/php/monica/list.inc.php:2645 +#, c-format +msgid "%s user preference." +msgid_plural "%s user preferences." +msgstr[0] "共 %s 筆使用者偏好。" + +#: lib/php/monica/list.inc.php:2654 +#, c-format +msgid "Your query found %s user preference, listing %s to %s." +msgid_plural "Your query found %s user preferences, listing %s to %s." +msgstr[0] "共 %s 筆相符的使用者偏好,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2663 +#, c-format +msgid "%s user preference, listing %s to %s." +msgid_plural "%s user preferences, listing %s to %s." +msgstr[0] "共 %s 筆使用者偏好,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2682 +msgid "Select a User Request" +msgstr "選擇使用者申請" + +#: lib/php/monica/list.inc.php:2683 +msgid "Manage User Requests" +msgstr "管理使用者申請" + +#: lib/php/monica/list.inc.php:2688 +msgid "Type" +msgstr "類別" + +#: lib/php/monica/list.inc.php:2690 +msgid "Arguments" +msgstr "備註資料" + +#: lib/php/monica/list.inc.php:2691 +msgid "Expiration" +msgstr "到期日" + +#: lib/php/monica/list.inc.php:2699 +msgid "Add a new user request." +msgstr "建新使用者申請。" + +#: lib/php/monica/list.inc.php:2709 +msgid "Search for a user request:" +msgstr "搜尋使用者申請:" + +#: lib/php/monica/list.inc.php:2727 +#, c-format +msgid "Your query found %s user request." +msgid_plural "Your query found %s user requests." +msgstr[0] "共 %s 筆相符的使用者申請。" + +#: lib/php/monica/list.inc.php:2734 +#, c-format +msgid "%s user request." +msgid_plural "%s user requests." +msgstr[0] "共 %s 筆使用者申請。" + +#: lib/php/monica/list.inc.php:2743 +#, c-format +msgid "Your query found %s user request, listing %s to %s." +msgid_plural "Your query found %s user requests, listing %s to %s." +msgstr[0] "共 %s 筆相符的使用者申請,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2752 +#, c-format +msgid "%s user request, listing %s to %s." +msgid_plural "%s user requests, listing %s to %s." +msgstr[0] "共 %s 筆使用者申請,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2778 +msgid "Add a new category." +msgstr "建新分類。" + +#: lib/php/monica/list.inc.php:2788 +msgid "Search for a category:" +msgstr "搜尋分類:" + +#: lib/php/monica/list.inc.php:2806 +#, c-format +msgid "Your query found %s category." +msgid_plural "Your query found %s categories." +msgstr[0] "共 %s 類相符的分類。" + +#: lib/php/monica/list.inc.php:2813 +#, c-format +msgid "%s category." +msgid_plural "%s categories." +msgstr[0] "共 %s 類分類。" + +#: lib/php/monica/list.inc.php:2822 +#, c-format +msgid "Your query found %s category, listing %s to %s." +msgid_plural "Your query found %s categories, listing %s to %s." +msgstr[0] "共 %s 類相符的分類,列出第 %s 類到第 %s 類。" + +#: lib/php/monica/list.inc.php:2831 +#, c-format +msgid "%s category, listing %s to %s." +msgid_plural "%s categories, listing %s to %s." +msgstr[0] "共 %s 類分類,列出第 %s 類到第 %s 類。" + +#: lib/php/monica/list.inc.php:2849 +msgid "Add a new categorization record." +msgstr "建新分類資料。" + +#: lib/php/monica/list.inc.php:2859 +msgid "Search for a categorization record:" +msgstr "搜尋分類資料:" + +#: lib/php/monica/list.inc.php:2877 +#, c-format +msgid "Your query found %s categorization record." +msgid_plural "Your query found %s categorization records." +msgstr[0] "共 %s 筆相符的分類資料。" + +#: lib/php/monica/list.inc.php:2884 +#, c-format +msgid "%s categorization record." +msgid_plural "%s categorization records." +msgstr[0] "共 %s 筆分類資料。" + +#: lib/php/monica/list.inc.php:2893 +#, c-format +msgid "Your query found %s categorization record, listing %s to %s." +msgid_plural "Your query found %s categorization records, listing %s to %s." +msgstr[0] "共 %s 筆相符的分類資料,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2902 +#, c-format +msgid "%s categorization record, listing %s to %s." +msgid_plural "%s categorization records, listing %s to %s." +msgstr[0] "共 %s 筆分類資料,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:2921 +msgid "Select a Page" +msgstr "選擇網頁" + +#: lib/php/monica/list.inc.php:2922 +msgid "Manage Pages" +msgstr "管理網頁" + +#: lib/php/monica/list.inc.php:2952 lib/php/monica/list.inc.php:3066 +#: lib/php/monica/list.inc.php:3173 lib/php/monica/list.inc.php:3237 +#: lib/php/monica/list.inc.php:3358 +msgid "Hidden" +msgstr "隱藏" + +#: lib/php/monica/list.inc.php:2953 lib/php/monica/list.inc.php:3067 +#: lib/php/monica/list.inc.php:3174 lib/php/monica/list.inc.php:3238 +#: lib/php/monica/list.inc.php:3359 +msgid "Shown" +msgstr "秀出" + +#: lib/php/monica/list.inc.php:2963 +msgid "Write a new page." +msgstr "撰寫網頁。" + +#: lib/php/monica/list.inc.php:2973 +msgid "Search for a page:" +msgstr "搜尋網頁:" + +#: lib/php/monica/list.inc.php:2991 +#, c-format +msgid "Your query found %s page." +msgid_plural "Your query found %s pages." +msgstr[0] "共 %s 頁相符的網頁。" + +#: lib/php/monica/list.inc.php:2998 +#, c-format +msgid "%s page." +msgid_plural "%s pages." +msgstr[0] "共 %s 頁網頁。" + +#: lib/php/monica/list.inc.php:3007 +#, c-format +msgid "Your query found %s page, listing %s to %s." +msgid_plural "Your query found %s pages, listing %s to %s." +msgstr[0] "共 %s 頁相符的網頁,列出第 %s 頁到第 %s 頁。" + +#: lib/php/monica/list.inc.php:3016 +#, c-format +msgid "%s page, listing %s to %s." +msgid_plural "%s pages, listing %s to %s." +msgstr[0] "共 %s 頁網頁,列出第 %s 頁到第 %s 頁。" + +#: lib/php/monica/list.inc.php:3035 +msgid "Select a News Article" +msgstr "選擇新聞" + +#: lib/php/monica/list.inc.php:3036 +msgid "Manage News" +msgstr "管理新聞" + +#: lib/php/monica/list.inc.php:3077 +msgid "Write a new news article." +msgstr "撰寫新聞。" + +#: lib/php/monica/list.inc.php:3087 +msgid "Search for a news article:" +msgstr "搜尋新聞:" + +#: lib/php/monica/list.inc.php:3105 +#, c-format +msgid "Your query found %s news article." +msgid_plural "Your query found %s news articles." +msgstr[0] "共 %s 則相符的新聞。" + +#: lib/php/monica/list.inc.php:3112 +#, c-format +msgid "%s news article." +msgid_plural "%s news articles." +msgstr[0] "共 %s 則新聞。" + +#: lib/php/monica/list.inc.php:3121 +#, c-format +msgid "Your query found %s news article, listing %s to %s." +msgid_plural "Your query found %s news articles, listing %s to %s." +msgstr[0] "共 %s 則相符的新聞,列出第 %s 則到第 %s 則。" + +#: lib/php/monica/list.inc.php:3130 +#, c-format +msgid "%s news article, listing %s to %s." +msgid_plural "%s news articles, listing %s to %s." +msgstr[0] "共 %s 則新聞,列出第 %s 則到第 %s 則。" + +#: lib/php/monica/list.inc.php:3149 +msgid "Select a Link Category" +msgstr "選擇連結分類" + +#: lib/php/monica/list.inc.php:3150 +msgid "Manage Link Categories" +msgstr "管理連結分類" + +#: lib/php/monica/list.inc.php:3197 +msgid "Select a Link" +msgstr "選擇連結" + +#: lib/php/monica/list.inc.php:3198 +msgid "Manage Links" +msgstr "管理連結" + +#: lib/php/monica/list.inc.php:3248 +msgid "Add a new related link." +msgstr "建新相關連結。" + +#: lib/php/monica/list.inc.php:3258 +msgid "Search for a related link:" +msgstr "搜尋相關連結:" + +#: lib/php/monica/list.inc.php:3276 +#, c-format +msgid "Your query found %s related link." +msgid_plural "Your query found %s related links." +msgstr[0] "共 %s 筆相符的相關連結。" + +#: lib/php/monica/list.inc.php:3283 +#, c-format +msgid "%s related link." +msgid_plural "%s related links." +msgstr[0] "共 %s 筆相關連結" + +#: lib/php/monica/list.inc.php:3292 +#, c-format +msgid "Your query found %s related link, listing %s to %s." +msgid_plural "Your query found %s related links, listing %s to %s." +msgstr[0] "共 %s 筆相符的相關連結,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:3301 +#, c-format +msgid "%s related link, listing %s to %s." +msgid_plural "%s related links, listing %s to %s." +msgstr[0] "共 %s 筆相關連結,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:3321 +msgid "Select a Link Categorization Record" +msgstr "選擇連結分類資料" + +#: lib/php/monica/list.inc.php:3322 +msgid "Manage Link Categorization" +msgstr "管理連結分類表" + +#: lib/php/monica/list.inc.php:3327 +msgid "Link" +msgstr "連結" + +#: lib/php/monica/list.inc.php:3383 +msgid "Select a Country" +msgstr "選擇國家" + +#: lib/php/monica/list.inc.php:3384 +msgid "Manage Country Data" +msgstr "管理國家資料" + +#: lib/php/monica/list.inc.php:3389 +msgid "Code" +msgstr "代碼" + +#: lib/php/monica/list.inc.php:3390 +msgid "Country name" +msgstr "國名" + +#: lib/php/monica/list.inc.php:3399 +msgid "Add a new country record." +msgstr "建新國家資料。" + +#: lib/php/monica/list.inc.php:3409 +msgid "Search for a country:" +msgstr "搜尋國家:" + +#: lib/php/monica/list.inc.php:3427 +#, c-format +msgid "Your query found %s country." +msgid_plural "Your query found %s countries." +msgstr[0] "共 %s 個相符的國家。" + +#: lib/php/monica/list.inc.php:3434 +#, c-format +msgid "%s country." +msgid_plural "%s countries." +msgstr[0] "共 %s 個國家。" + +#: lib/php/monica/list.inc.php:3443 +#, c-format +msgid "Your query found %s country, listing %s to %s." +msgid_plural "Your query found %s countries, listing %s to %s." +msgstr[0] "共 %s 個相符的國家,列出第 %s 個到第 %s 個。" + +#: lib/php/monica/list.inc.php:3452 +#, c-format +msgid "%s country, listing %s to %s." +msgid_plural "%s countries, listing %s to %s." +msgstr[0] "共 %s 個國家,列出第 %s 個到第 %s 個。" + +#: lib/php/monica/list.inc.php:3474 +msgid "Browse the Activity Log" +msgstr "查閱網站活動日誌" + +#: lib/php/monica/list.inc.php:3586 +msgid "Please fill in the number of rows to display." +msgstr "請填上顯示筆數。" + +#: lib/php/monica/list.inc.php:3590 +#, c-format +msgid "This number of rows to display is too long. (Max. length %d)" +msgstr "顯示筆數太長了。(最長 %d )" + +#: lib/php/monica/list.inc.php:3595 +msgid "Please fill in a positive integer number of rows to display." +msgstr "顯示筆數請填正整數。" + +#: lib/php/monica/list.inc.php:3599 lib/php/monica/list.inc.php:3609 +#, c-format +msgid "" +"The number of rows to display is too small. Please fill in a larger number " +"of rows to display between %d and %d." +msgstr "顯示筆數太小了,請設定在 %d 到 %d 之間。" + +#: lib/php/monica/list.inc.php:3613 +#, c-format +msgid "" +"The number of rows to display is too large. Please fill in a smaller number " +"of rows to display between %d and %d." +msgstr "顯示筆數太大了,請設定在 %d 到 %d 之間。" + +#: lib/php/monica/list.inc.php:3638 +msgid "Search for log entries:" +msgstr "搜尋記錄:" + +#: lib/php/monica/list.inc.php:3641 +msgid "Display" +msgstr "顯示" + +#: lib/php/monica/list.inc.php:3654 +msgid "Display rows:" +msgstr "顯示筆數:" + +#: lib/php/monica/list.inc.php:3677 +#, c-format +msgid "Your query found %s log entry." +msgid_plural "Your query found %s log entries." +msgstr[0] "共 %s 筆相符的記錄。" + +#: lib/php/monica/list.inc.php:3684 +#, c-format +msgid "%s log entry." +msgid_plural "%s log entries." +msgstr[0] "共 %s 筆記錄。" + +#: lib/php/monica/list.inc.php:3693 +#, c-format +msgid "Your query found %s log entry, listing %s to %s." +msgid_plural "Your query found %s log entries, listing %s to %s." +msgstr[0] "共 %s 筆相符的記錄,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/list.inc.php:3702 +#, c-format +msgid "%s log entry, listing %s to %s." +msgid_plural "%s log entries, listing %s to %s." +msgstr[0] "共 %s 筆記錄,列出第 %s 筆到第 %s 筆。" + +#: lib/php/monica/lninfo.inc.php:28 +msgid "English" +msgstr "英文" + +#: lib/php/monica/lninfo.inc.php:39 +msgid "Traditional Chinese" +msgstr "繁體中文" + +#: lib/php/monica/lninfo.inc.php:50 +msgid "Simplified Chinese" +msgstr "簡體中文" + +#: lib/php/monica/lninfo.inc.php:61 +msgid "Chinese" +msgstr "中文" + +#: lib/php/monica/lninfo.inc.php:72 +msgid "Japanese" +msgstr "日文" + +#: lib/php/monica/lninfo.inc.php:83 +msgid "Korean" +msgstr "韓文" + +#: lib/php/monica/lninfo.inc.php:94 +msgid "German" +msgstr "德文" + +#: lib/php/monica/lninfo.inc.php:105 +msgid "Spanish" +msgstr "西班牙文" + +#: lib/php/monica/lninfo.inc.php:366 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "切換到本頁的%s版。" + +#: lib/php/monica/pagefunc.inc.php:738 +msgid "Web pages" +msgstr "網頁" + +#: lib/php/monica/pagefunc.inc.php:739 +msgid "News" +msgstr "新聞" + +#: lib/php/monica/pagefunc.inc.php:740 +msgid "Related links" +msgstr "相關連結" + +#: lib/php/monica/pagefunc.inc.php:741 +msgid "Home page" +msgstr "首頁" + +#: lib/php/monica/pagefunc.inc.php:742 +msgid "Whole web site" +msgstr "整個網站" + +#: lib/php/monica/pic.inc.php:39 +msgid "Left-aligned" +msgstr "靠左" + +#: lib/php/monica/pic.inc.php:40 +msgid "Right-aligned" +msgstr "靠右" + +#: lib/php/monica/pic.inc.php:74 lib/php/monica/pic.inc.php:77 +#, c-format +msgid "This picture file is too large (Max %s)." +msgstr "圖檔太大。(上限 %s )" + +#: lib/php/monica/pic.inc.php:92 +msgid "Please upload only PNG, JPEG or GIF files." +msgstr "限上傳 PNG 、 JPEG 或 GIF 圖檔。" + +#: lib/php/monica/pic.inc.php:153 +#, c-format +msgid "Width: %d, height: %d, ratio: %0.2f" +msgstr "寬: %d ,高: %d ,比例: %0.2f" + +#: lib/php/monica/pic.inc.php:176 +msgid "Please specify a numeric ratio." +msgstr "比例請設定數字。" + +#: lib/php/monica/pic.inc.php:180 +msgid "Please specify a positive ratio." +msgstr "比例請設定正數。" + +#: lib/php/monica/pic.inc.php:183 +#, c-format +msgid "Please specify a ratio less than or equal to %0.2f." +msgstr "比例請勿大於 %0.2f 。" + +#: lib/php/monica/pic.inc.php:189 +msgid "This image is too large to display." +msgstr "圖片太大,無法顯示。" + +#: lib/php/monica/preview.inc.php:47 +#, c-format +msgid "Unknown preview source: \"%s\"." +msgstr "預覽資料源不明:「 %s 」。" + +#: lib/php/monica/preview.inc.php:67 +#, c-format +msgid "Unknown preview form: %d." +msgstr "預覽表格不明: %d 。" + +#: lib/php/monica/preview.inc.php:143 +msgid "Preview Mark Area" +msgstr "預覽標誌區" + +#: lib/php/monica/preview.inc.php:148 +msgid "Finish preview and return." +msgstr "結束預覽回前頁。" + +#: lib/php/monica/process.inc.php:237 +msgid "This record was not modified." +msgstr "資料未異動。" + +#: lib/php/monica/process.inc.php:243 +msgid "This record has been successfully added." +msgstr "資料建好了。" + +#: lib/php/monica/process.inc.php:247 +msgid "This record has been successfully updated." +msgstr "資料存好了。" + +#: lib/php/monica/process.inc.php:251 +msgid "This record has been successfully deleted." +msgstr "資料刪掉了。" + +#: lib/php/monica/process.inc.php:406 +msgid "This category was not modified." +msgstr "分類未異動。" + +#: lib/php/monica/process.inc.php:412 +msgid "This category has been successfully added." +msgstr "分類建好了。" + +#: lib/php/monica/process.inc.php:416 +msgid "This category has been successfully updated." +msgstr "分類存好了。" + +#: lib/php/monica/process.inc.php:420 +msgid "This category has been successfully deleted." +msgstr "分類刪掉了。" + +#: lib/php/monica/process.inc.php:433 +msgid "This categorization record was not modified." +msgstr "分類資料未異動。" + +#: lib/php/monica/process.inc.php:439 +msgid "This categorization record has been successfully added." +msgstr "分類資料建好了。" + +#: lib/php/monica/process.inc.php:443 +msgid "This categorization record has been successfully updated." +msgstr "分類資料存好了。" + +#: lib/php/monica/process.inc.php:447 +msgid "This categorization record has been successfully deleted." +msgstr "分類資料刪掉了。" + +#: lib/php/monica/process.inc.php:782 +msgid "This user account was not modified." +msgstr "帳號未異動。" + +#: lib/php/monica/process.inc.php:788 +msgid "This user account has been successfully added." +msgstr "帳號建好了。" + +#: lib/php/monica/process.inc.php:792 +msgid "This user account has been successfully updated." +msgstr "帳號存好了。" + +#: lib/php/monica/process.inc.php:796 +msgid "This user account has been successfully deleted." +msgstr "帳號刪掉了。" + +#: lib/php/monica/process.inc.php:1074 +msgid "This group was not modified." +msgstr "群組未異動。" + +#: lib/php/monica/process.inc.php:1080 +msgid "This group has been successfully added." +msgstr "群組建好了。" + +#: lib/php/monica/process.inc.php:1084 +msgid "This group has been successfully updated." +msgstr "群組存好了。" + +#: lib/php/monica/process.inc.php:1088 +msgid "This group has been successfully deleted." +msgstr "群組刪掉了。" + +#: lib/php/monica/process.inc.php:1152 lib/php/monica/process.inc.php:1230 +msgid "This membership record was not modified." +msgstr "成員關係未異動。" + +#: lib/php/monica/process.inc.php:1158 lib/php/monica/process.inc.php:1236 +msgid "This membership record has been successfully added." +msgstr "成員關係建好了。" + +#: lib/php/monica/process.inc.php:1162 lib/php/monica/process.inc.php:1240 +msgid "This membership record has been successfully updated." +msgstr "成員關係存好了。" + +#: lib/php/monica/process.inc.php:1166 lib/php/monica/process.inc.php:1244 +msgid "This membership record has been successfully deleted." +msgstr "成員關係刪掉了。" + +#: lib/php/monica/process.inc.php:1308 +msgid "This script privilege record was not modified." +msgstr "程式權限未異動。" + +#: lib/php/monica/process.inc.php:1314 +msgid "This script privilege record has been successfully added." +msgstr "程式權限建好了。" + +#: lib/php/monica/process.inc.php:1318 +msgid "This script privilege record has been successfully updated." +msgstr "程式權限存好了。" + +#: lib/php/monica/process.inc.php:1322 +msgid "This script privilege record has been successfully deleted." +msgstr "程式權限刪掉了。" + +#: lib/php/monica/process.inc.php:1438 +msgid "This user preference was not modified." +msgstr "使用者偏好未異動。" + +#: lib/php/monica/process.inc.php:1444 +msgid "This user preference has been successfully added." +msgstr "使用者偏好建好了。" + +#: lib/php/monica/process.inc.php:1448 +msgid "This user preference has been successfully updated." +msgstr "使用者偏好存好了。" + +#: lib/php/monica/process.inc.php:1452 +msgid "This user preference has been successfully deleted." +msgstr "使用者偏好刪掉了。" + +#: lib/php/monica/process.inc.php:1560 +msgid "This user request was not modified." +msgstr "使用者申請未異動。" + +#: lib/php/monica/process.inc.php:1566 +msgid "This user request has been successfully added." +msgstr "使用者申請建好了。" + +#: lib/php/monica/process.inc.php:1570 +msgid "This user request has been successfully updated." +msgstr "使用者申請存好了。" + +#: lib/php/monica/process.inc.php:1574 +msgid "This user request has been successfully deleted." +msgstr "使用者申請刪掉了。" + +#: lib/php/monica/process.inc.php:1685 +msgid "This page was not modified." +msgstr "網頁未異動。" + +#: lib/php/monica/process.inc.php:1691 +msgid "This page has been successfully added." +msgstr "網頁建好了。" + +#: lib/php/monica/process.inc.php:1695 +msgid "This page has been successfully updated." +msgstr "網頁存好了。" + +#: lib/php/monica/process.inc.php:1699 +msgid "This page has been successfully deleted." +msgstr "網頁刪掉了。" + +#: lib/php/monica/process.inc.php:1874 +msgid "This news article was not modified." +msgstr "新聞未異動。" + +#: lib/php/monica/process.inc.php:1880 +msgid "This news article has been successfully added." +msgstr "新聞建好了。" + +#: lib/php/monica/process.inc.php:1884 +msgid "This news article has been successfully updated." +msgstr "新聞存好了。" + +#: lib/php/monica/process.inc.php:1888 +msgid "This news article has been successfully deleted." +msgstr "新聞刪掉了。" + +#: lib/php/monica/process.inc.php:1997 +msgid "This country was not modified." +msgstr "國家未異動。" + +#: lib/php/monica/process.inc.php:2003 +msgid "This country has been successfully added." +msgstr "國家建好了。" + +#: lib/php/monica/process.inc.php:2007 +msgid "This country has been successfully updated." +msgstr "國家存好了。" + +#: lib/php/monica/process.inc.php:2011 +msgid "This country has been successfully deleted." +msgstr "國家刪掉了。" + +#: lib/php/monica/process.inc.php:2097 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. (%0.3f seconds)" +msgstr "該類網頁重製好了。( %0.3f 秒)" + +#: lib/php/monica/process.inc.php:2158 +#, c-format +msgid "Welcome, %s!" +msgstr "%s,你好。" + +#: lib/php/monica/process.inc.php:2204 +msgid "You have successfully logged out." +msgstr "登出好了。" + +#: lib/php/monica/process.inc.php:2439 +msgid "This related link was not modified." +msgstr "相關連結未異動。" + +#: lib/php/monica/process.inc.php:2445 +msgid "This related link has been successfully added." +msgstr "相關連結建好了。" + +#: lib/php/monica/process.inc.php:2449 +msgid "This related link has been successfully updated." +msgstr "相關連結存好了。" + +#: lib/php/monica/process.inc.php:2453 +msgid "This related link has been successfully deleted." +msgstr "相關連結刪掉了。" + +#: lib/php/monica/request.inc.php:38 +msgid "Please specify the request." +msgstr "請設定申請編號。" + +#: lib/php/monica/request.inc.php:46 lib/php/monica/request.inc.php:55 +#, c-format +msgid "Invalid request S/N: %s." +msgstr "申請編號無效: %s 。" + +#: lib/php/monica/sitesize.inc.php:41 +#, c-format +msgid "Currently using files %s.\n" +msgstr "現用檔案 %s。\n" + +#: lib/php/monica/sitesize.inc.php:46 +#, c-format +msgid "Currently using files %s, database %s, total %s.\n" +msgstr "現用檔案 %s ,資料庫 %s ,合計 %s 。\n" + +#: lib/php/monica/upload.inc.php:70 +#, c-format +msgid "MIME file type: %s" +msgstr "MIME 檔案格式: %s" + +#: lib/php/monica/upload.inc.php:71 +#, c-format +msgid "File name: %s" +msgstr "檔名: %s" + +#: lib/php/monica/upload.inc.php:72 +#, c-format +msgid "File size: %s bytes" +msgstr "檔案大小: %s 位元組" + +#: lib/php/monica/validate.inc.php:116 +msgid "HTML Validatior Logo Area" +msgstr "HTML 驗證標誌區" + +#: lib/php/monica/validate.inc.php:117 +msgid "HTML validation result of this page" +msgstr "本頁的 HTML 驗證結果" + +#: lib/php/monica/validate.inc.php:118 +#, c-format +msgid "Valid %s!" +msgstr "%s 正確!" + +#: lib/php/monica/validate.inc.php:119 +msgid "CSS validation result of this page" +msgstr "本頁的 CSS 驗證結果" + +#: lib/php/monica/validate.inc.php:120 +msgid "Valid CSS!" +msgstr "CSS 正確!" + +#: lib/php/monica/validate.inc.php:121 +msgid "Explanation of Level Triple-A Conformance" +msgstr "無障礙三 A 級標準說明" + +#: lib/php/monica/validate.inc.php:122 +msgid "" +"Level Triple-A conformance icon, W3C-WAI Web Content Accessibility " +"Guidelines 1.0" +msgstr "W3C 無障礙網頁規範 1.0 三 A 級標準標章" diff --git a/po/selima/Makefile b/po/selima/Makefile new file mode 100644 index 0000000..e0e557d --- /dev/null +++ b/po/selima/Makefile @@ -0,0 +1,49 @@ +# Possible make targets: +# all: Compile the PO files and copy the binary MO files +# into the appropriate directories +# xgettext: Obtain the newest PO template file $(PACKAGE).pot +# from the source programs, and do msgmerge to compare +# the $(PACKAGE).pot and existing PO files to obtain +# the newest POX files to work with + + +PACKAGE = selima +#ALLLINGUAS = en_US zh_TW zh_CN +ALLLINGUAS = zh_TW zh_CN +PKGROOT = ../.. +PODIR = po/selima +LOCALEDIR = $(PKGROOT)/locale +CATEGORY = LC_MESSAGES +PROGRAMS = lib/perl5/*.pm lib/perl5/*/*.pm lib/perl5/*/*/*.pm lib/perl5/*/*/*/*.pm lib/perl5/*/*/*/*/*.pm lib/perl5/*/*/*/*/*/*.pm + +all: + opencc -c tw2sp.json -i zh_TW.po -o /dev/stdout \ + | sed "s/^# Traditional Chinese PO file for the /# Simplified Chinese PO file for the /" \ + | sed "s/^\"PO-Revision-Date: .*\"/\"PO-Revision-Date: `date \"+%Y-%m-%d %H:%M%z\"`\\\\n\"/" \ + > zh_CN.po; \ + for ln in $(ALLLINGUAS); do \ + msgfmt $$ln.po -o $$ln.gmo; \ + test -d $(LOCALEDIR) || \ + (rm -rf $(LOCALEDIR) && \ + mkdir $(LOCALEDIR)); \ + test -d $(LOCALEDIR)/$$ln || \ + (rm -rf $(LOCALEDIR)/$$ln && \ + mkdir $(LOCALEDIR)/$$ln); \ + test -d $(LOCALEDIR)/$$ln/$(CATEGORY) || \ + (rm -rf $(LOCALEDIR)/$$ln/$(CATEGORY) && \ + mkdir $(LOCALEDIR)/$$ln/$(CATEGORY)); \ + rm -f $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + cp $$ln.gmo $(LOCALEDIR)/$$ln/$(CATEGORY)/$(PACKAGE).mo; \ + done + +xgettext: + cd $(PKGROOT); \ + xgettext --keyword=C_ --keyword=F_ --keyword=N_ -p $(PODIR)/ -o $(PACKAGE).pot \ + --language=c $(PROGRAMS); \ + cd $(PODIR); \ + for ln in $(ALLLINGUAS); do \ + msgmerge $$ln.po $(PACKAGE).pot > $$ln.pox; \ + done + +clean: + rm -f *.gmo diff --git a/po/selima/selima.pot b/po/selima/selima.pot new file mode 100644 index 0000000..7dce58d --- /dev/null +++ b/po/selima/selima.pot @@ -0,0 +1,3366 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-02-17 11:07+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: lib/perl5/Selima/Checker.pm:130 +msgid "Please select a user." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:133 +msgid "This user does not exist anymore. Please select another one." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:151 +msgid "Please select a group." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:154 +msgid "This group does not exist anymore. Please select another one." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:172 +msgid "Please fill in the script." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:175 +msgid "This script is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:179 +msgid "This script is not a valid script. Please specify another one." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:197 +msgid "Please fill in the author." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:200 +msgid "This author is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:220 lib/perl5/Selima/Form.pm:1700 +msgid "Fill in the content here." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:221 +msgid "Please fill in the content." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:224 +msgid "This content is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:243 +msgid "Please fill in a date." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:246 lib/perl5/Selima/Checker.pm:249 +#: lib/perl5/Selima/Checker.pm:251 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:270 lib/perl5/Selima/Form.pm:1756 +msgid "Fill in the description here." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:271 +msgid "Please fill in the description." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:274 +msgid "This description is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:293 +msgid "Please fill in the ID." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:296 +msgid "This ID. is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:299 +msgid "This ID. is too short. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:303 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:321 +msgid "Please fill in the keywords." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:324 +msgid "This keyword list is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:344 lib/perl5/Selima/Form.pm:1830 +msgid "Fill in the message here." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:345 +msgid "Please fill in the message." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:348 +msgid "This message is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:367 +msgid "Please fill in the order." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:370 +msgid "This order is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:374 +msgid "Please fill in a positive integer order." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:400 +msgid "Please fill in the page path." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:403 +msgid "This page path is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:414 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:417 +msgid "Please fill in an absolute page path." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:420 +msgid "Please fill in a valid page path." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:423 +msgid "You cannot overwrite the cover home page." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:426 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:454 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:458 +msgid "" +"This picture is too large. Please upload another one. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:482 +msgid "Please fill in the picture caption." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:485 +msgid "This picture caption is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:509 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:527 +msgid "Please fill in the title." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:530 +msgid "This title is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:549 +msgid "Please fill in the English title." +msgstr "" + +#: lib/perl5/Selima/Checker.pm:552 +msgid "This English title is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker.pm:699 lib/perl5/Selima/Preview.pm:38 +msgid "The following field was not received: \"[_1]\"." +msgstr "" + +#: lib/perl5/Selima/ChkWrite.pm:35 +msgid "[_1]: It is not a file." +msgstr "" + +#: lib/perl5/Selima/ChkWrite.pm:39 +msgid "[_1]: You have no permission to overwrite this file." +msgstr "" + +#: lib/perl5/Selima/ChkWrite.pm:50 +msgid "[_1]: You cannot create anything under the root directory." +msgstr "" + +#: lib/perl5/Selima/ChkWrite.pm:54 +msgid "" +"[_1]: One of the parents of this file ([_2]) is not a directory. You cannot " +"create any new file inside." +msgstr "" + +#: lib/perl5/Selima/ChkWrite.pm:58 +msgid "[_1]: You have no permission to create any file under [_2]." +msgstr "" + +#: lib/perl5/Selima/CommText.pm:24 +msgid "(not set)" +msgstr "" + +#: lib/perl5/Selima/CommText.pm:25 +msgid "(none)" +msgstr "" + +#: lib/perl5/Selima/CommText.pm:26 +msgid "(N/A)" +msgstr "" + +#: lib/perl5/Selima/Format.pm:48 +msgid "[#,_1] bytes" +msgstr "" + +#: lib/perl5/Selima/Form.pm:116 +msgid "Delete it." +msgstr "" + +#: lib/perl5/Selima/Form.pm:119 +msgid "*" +msgstr "" + +#: lib/perl5/Selima/Form.pm:140 +msgid "This table provides you a form to add a new data record." +msgstr "" + +#: lib/perl5/Selima/Form.pm:143 +msgid "This table provides you a form to update a current data record." +msgstr "" + +#: lib/perl5/Selima/Form.pm:146 +msgid "This table provides you a form to delete a data record." +msgstr "" + +#: lib/perl5/Selima/Form.pm:185 +msgid "Add a New Data Record" +msgstr "" + +#: lib/perl5/Selima/Form.pm:188 +msgid "Update a Current Data Record" +msgstr "" + +#: lib/perl5/Selima/Form.pm:191 +msgid "Delete a Data Record" +msgstr "" + +#: lib/perl5/Selima/Form.pm:212 +msgid "Preview it." +msgstr "" + +#: lib/perl5/Selima/Form.pm:271 lib/perl5/Selima/Form.pm:284 +msgid "Convert from Simplified Chinese" +msgstr "" + +#: lib/perl5/Selima/Form.pm:273 lib/perl5/Selima/Form.pm:286 +msgid "Convert from Traditional Chinese" +msgstr "" + +#: lib/perl5/Selima/Form.pm:447 lib/perl5/Selima/Form.pm:451 +#: lib/perl5/Selima/Form.pm:559 lib/perl5/Selima/Form.pm:563 +#: lib/perl5/Selima/Form/AcctTrx.pm:89 lib/perl5/Selima/Form/AcctTrx.pm:94 +msgid "Submit" +msgstr "" + +#: lib/perl5/Selima/Form.pm:448 lib/perl5/Selima/Form.pm:452 +#: lib/perl5/Selima/Form.pm:560 lib/perl5/Selima/Form.pm:564 +#: lib/perl5/Selima/Form/AcctTrx.pm:90 lib/perl5/Selima/Form/AcctTrx.pm:95 +msgid "Save" +msgstr "" + +#: lib/perl5/Selima/Form.pm:571 lib/perl5/Selima/Form.pm:1139 +#: lib/perl5/Selima/Form.pm:1229 lib/perl5/Selima/List.pm:1390 +msgid "Delete" +msgstr "" + +#: lib/perl5/Selima/Form.pm:572 lib/perl5/Selima/Form/Rebuild.pm:42 +msgid "Cancel" +msgstr "" + +#: lib/perl5/Selima/Form.pm:577 +msgid "" +"Are you sure you want to delete this data? You cannot recover it if you do " +"so." +msgstr "" + +#: lib/perl5/Selima/Form.pm:855 lib/perl5/Selima/Form.pm:951 +#: lib/perl5/Selima/Form.pm:1013 lib/perl5/Selima/Form.pm:1097 +#: lib/perl5/Selima/Form.pm:1175 lib/perl5/Selima/Form.pm:1282 +#: lib/perl5/Selima/Form.pm:1362 lib/perl5/Selima/Form.pm:1435 +#: lib/perl5/Selima/Form.pm:1528 lib/perl5/Selima/Form.pm:1620 +#: lib/perl5/Selima/Form.pm:2057 lib/perl5/Selima/Form/AcctRec.pm:122 +#: lib/perl5/Selima/Form/AcctTrx.pm:519 lib/perl5/Selima/Form/Group.pm:165 +#: lib/perl5/Selima/Form/Group.pm:294 lib/perl5/Selima/Form/Group.pm:421 +#: lib/perl5/Selima/Form/Link.pm:138 lib/perl5/Selima/Form/User.pm:291 +msgid "Original:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:856 lib/perl5/Selima/Form.pm:952 +#: lib/perl5/Selima/Form.pm:1014 lib/perl5/Selima/Form.pm:1098 +#: lib/perl5/Selima/Form.pm:1176 lib/perl5/Selima/Form.pm:1283 +#: lib/perl5/Selima/Form.pm:1363 lib/perl5/Selima/Form.pm:1436 +#: lib/perl5/Selima/Form.pm:1529 lib/perl5/Selima/Form.pm:1621 +#: lib/perl5/Selima/Form.pm:2058 lib/perl5/Selima/Form/AcctRec.pm:123 +#: lib/perl5/Selima/Form/AcctTrx.pm:520 lib/perl5/Selima/Form/Group.pm:166 +#: lib/perl5/Selima/Form/Group.pm:295 lib/perl5/Selima/Form/Group.pm:422 +#: lib/perl5/Selima/Form/Link.pm:139 lib/perl5/Selima/Form/User.pm:292 +msgid "New:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:860 lib/perl5/Selima/Form.pm:1018 +#: lib/perl5/Selima/Form.pm:1625 lib/perl5/Selima/Form.pm:2122 +msgid "Source:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1138 lib/perl5/Selima/Form.pm:1228 +#: lib/perl5/Selima/Form/AcctRec.pm:100 lib/perl5/Selima/Form/AcctTrx.pm:214 +msgid "Choose" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1689 +msgid "Address:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1694 +msgid "Author:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1699 +msgid "Content:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1713 +msgid "Current Website:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1718 +msgid "Enter your website URL here." +msgstr "" + +#: lib/perl5/Selima/Form.pm:1734 +msgid "Created:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1739 +msgid "Created by:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1744 lib/perl5/Selima/List.pm:167 +#: lib/perl5/Selima/Form/User.pm:160 lib/perl5/Selima/Form/User.pm:163 +msgid "Disabled?" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1745 lib/perl5/Selima/Form/User.pm:161 +#: lib/perl5/Selima/Form/User.pm:164 +msgid "Disabled" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1745 lib/perl5/Selima/Form/User.pm:161 +#: lib/perl5/Selima/Form/User.pm:164 +msgid "Enabled" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1745 +msgid "Disable it." +msgstr "" + +#: lib/perl5/Selima/Form.pm:1750 +msgid "Date:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1755 lib/perl5/Selima/Form/Group.pm:97 +msgid "Description:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1761 +msgid "E-mail:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1766 +msgid "Fax.:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1771 +msgid "Group:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1776 lib/perl5/Selima/Form/Guestbook.pm:82 +#: lib/perl5/Selima/Form/LinkCat.pm:88 lib/perl5/Selima/Form/Link.pm:87 +#: lib/perl5/Selima/Form/Page.pm:81 +msgid "Hide?" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Hide it" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Show it" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Hide it currently." +msgstr "" + +#: lib/perl5/Selima/Form.pm:1782 lib/perl5/Selima/List.pm:171 +msgid "HTML?" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "HTML" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "Plain text" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "The submitted content is HTML." +msgstr "" + +#: lib/perl5/Selima/Form.pm:1788 +msgid "Host:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1793 lib/perl5/Selima/Form/LinkCat.pm:95 +msgid "ID.:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1798 +msgid "Identity:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1803 +msgid "Introduction:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1804 +msgid "Fill in the introduction here." +msgstr "" + +#: lib/perl5/Selima/Form.pm:1809 +msgid "IP:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1814 +msgid "Keywords:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1819 +msgid "Language:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1824 +msgid "Location:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1829 +msgid "Message:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1835 +msgid "Name:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1847 lib/perl5/Selima/Form/AcctTrx.pm:319 +msgid "Order:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1853 +msgid "Parent category:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1854 lib/perl5/Selima/Form/AcctSubj.pm:94 +msgid "At the very top" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1866 lib/perl5/Selima/Form/User.pm:201 +msgid "Password:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1867 +msgid "Confirm password:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1978 +msgid "Page path:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1992 +msgid "Picture:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1993 +msgid "Pic. caption:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1994 +msgid "Pic. position:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1997 +msgid "Set the picture" +msgstr "" + +#: lib/perl5/Selima/Form.pm:1998 +msgid "Delete this picture" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2003 lib/perl5/Selima/Form.pm:2178 +msgid "Picture preview" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2059 +msgid "Original picture preview" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2060 +msgid "New picture preview" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2078 +msgid "Please upload a new picture from [_1]." +msgstr "" + +#: lib/perl5/Selima/Form.pm:2228 +msgid "[numerate,_1,Subcategory,Subcategories]:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2256 +msgid "Script:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2261 +msgid "S/N:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2266 +msgid "Tel.:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2271 +msgid "Title:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2276 +msgid "English title:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2281 +msgid "Updated:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2286 +msgid "Updated by:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2291 +msgid "URL:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2296 lib/perl5/Selima/Form/UserPref.pm:94 +msgid "Value:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2301 +msgid "Visited:" +msgstr "" + +#: lib/perl5/Selima/Form.pm:2306 +msgid "Visits:" +msgstr "" + +#: lib/perl5/Selima/Init.pm:216 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" + +#: lib/perl5/Selima/Links.pm:242 +msgid "Related Links" +msgstr "" + +#: lib/perl5/Selima/List.pm:109 +msgid "Select" +msgstr "" + +#: lib/perl5/Selima/List.pm:112 +msgid "Select A Data Record" +msgstr "" + +#: lib/perl5/Selima/List.pm:114 +msgid "Edit" +msgstr "" + +#: lib/perl5/Selima/List.pm:116 +msgid "Manage Data" +msgstr "" + +#: lib/perl5/Selima/List.pm:158 +msgid "S/N" +msgstr "" + +#: lib/perl5/Selima/List.pm:159 +msgid "Created" +msgstr "" + +#: lib/perl5/Selima/List.pm:160 +msgid "Created by" +msgstr "" + +#: lib/perl5/Selima/List.pm:161 +msgid "Updated" +msgstr "" + +#: lib/perl5/Selima/List.pm:162 +msgid "Updated by" +msgstr "" + +#: lib/perl5/Selima/List.pm:164 +msgid "Content" +msgstr "" + +#: lib/perl5/Selima/List.pm:165 +msgid "Category" +msgstr "" + +#: lib/perl5/Selima/List.pm:166 +msgid "Date" +msgstr "" + +#: lib/perl5/Selima/List.pm:168 lib/perl5/Selima/List/Groups.pm:30 +msgid "Description" +msgstr "" + +#: lib/perl5/Selima/List.pm:169 lib/perl5/Selima/List/Guestbook/Public.pm:138 +msgid "E-mail" +msgstr "" + +#: lib/perl5/Selima/List.pm:170 +msgid "Hidden?" +msgstr "" + +#: lib/perl5/Selima/List.pm:172 +msgid "ID." +msgstr "" + +#: lib/perl5/Selima/List.pm:173 +msgid "Keywords" +msgstr "" + +#: lib/perl5/Selima/List.pm:174 +msgid "Name" +msgstr "" + +#: lib/perl5/Selima/List.pm:175 +msgid "Order" +msgstr "" + +#: lib/perl5/Selima/List.pm:176 lib/perl5/Selima/List/Pages.pm:32 +msgid "Page path" +msgstr "" + +#: lib/perl5/Selima/List.pm:177 +msgid "Picture" +msgstr "" + +#: lib/perl5/Selima/List.pm:178 +msgid "Pic. ratio" +msgstr "" + +#: lib/perl5/Selima/List.pm:179 +msgid "Pic. caption" +msgstr "" + +#: lib/perl5/Selima/List.pm:180 +msgid "Pic. position" +msgstr "" + +#: lib/perl5/Selima/List.pm:181 +msgid "Title" +msgstr "" + +#: lib/perl5/Selima/List.pm:182 +msgid "English title" +msgstr "" + +#: lib/perl5/Selima/List.pm:183 +msgid "URL." +msgstr "" + +#: lib/perl5/Selima/List.pm:184 +msgid "Status (slow)" +msgstr "" + +#: lib/perl5/Selima/List.pm:423 +msgid "Nothing found. Please try another query." +msgstr "" + +#: lib/perl5/Selima/List.pm:426 +msgid "The database is empty." +msgstr "" + +#: lib/perl5/Selima/List.pm:432 +msgid "Your query found [*,_1,record]." +msgstr "" + +#: lib/perl5/Selima/List.pm:435 +msgid "[*,_1,record]." +msgstr "" + +#: lib/perl5/Selima/List.pm:441 +msgid "Your query found [*,_1,record], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List.pm:445 +msgid "[*,_1,record], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List.pm:456 +msgid "First" +msgstr "" + +#: lib/perl5/Selima/List.pm:457 +msgid "Previous" +msgstr "" + +#: lib/perl5/Selima/List.pm:458 +msgid "Next" +msgstr "" + +#: lib/perl5/Selima/List.pm:459 +msgid "Last" +msgstr "" + +#: lib/perl5/Selima/List.pm:502 +msgid "Picture unavailable" +msgstr "" + +#: lib/perl5/Selima/List.pm:530 +msgid "Page number ([_1]) invalid. Please specify a valid page number." +msgstr "" + +#: lib/perl5/Selima/List.pm:536 +msgid "" +"Page number ([#,_1]) out of range. Please specify between 1 and [#,_2]." +msgstr "" + +#: lib/perl5/Selima/List.pm:613 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:61 +msgid "Please fill in your query." +msgstr "" + +#: lib/perl5/Selima/List.pm:749 lib/perl5/Selima/List.pm:759 +msgid "You cannot sort by \"[_1]\"." +msgstr "" + +#: lib/perl5/Selima/List.pm:1082 +#: lib/perl5/Selima/List/Accounting/Reports.pm:412 +msgid "Search" +msgstr "" + +#: lib/perl5/Selima/List.pm:1181 +msgid "Index" +msgstr "" + +#: lib/perl5/Selima/List.pm:1319 +msgid "Page:" +msgstr "" + +#: lib/perl5/Selima/List.pm:1320 lib/perl5/Selima/List.pm:1392 +#: lib/perl5/Selima/List.pm:1449 +msgid "View" +msgstr "" + +#: lib/perl5/Selima/List.pm:1364 lib/perl5/Selima/List.pm:1476 +msgid "Delete the selected items." +msgstr "" + +#: lib/perl5/Selima/List.pm:1389 +msgid "No." +msgstr "" + +#: lib/perl5/Selima/List.pm:1500 +#: lib/perl5/Selima/List/Accounting/Reports.pm:587 +msgid "Set" +msgstr "" + +#: lib/perl5/Selima/List.pm:1521 +#: lib/perl5/Selima/List/Accounting/Reports.pm:604 +msgid "Rows per page:" +msgstr "" + +#: lib/perl5/Selima/List.pm:1529 +msgid "Display columns:" +msgstr "" + +#: lib/perl5/Selima/List.pm:1564 +msgid "Malformed" +msgstr "" + +#: lib/perl5/Selima/List.pm:1598 +msgid "OK" +msgstr "" + +#: lib/perl5/Selima/List.pm:1598 +msgid "Unreachable" +msgstr "" + +#: lib/perl5/Selima/LnInfo.pm:49 +msgid "Traditional Chinese" +msgstr "" + +#: lib/perl5/Selima/LnInfo.pm:59 +msgid "Simplified Chinese" +msgstr "" + +#: lib/perl5/Selima/LnInfo.pm:69 +msgid "English" +msgstr "" + +#: lib/perl5/Selima/LnInfo.pm:79 +msgid "Japanese" +msgstr "" + +#: lib/perl5/Selima/LnInfo.pm:89 +msgid "German" +msgstr "" + +#: lib/perl5/Selima/LnInfo.pm:242 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "" + +#: lib/perl5/Selima/PageFunc.pm:221 +msgid "Web pages" +msgstr "" + +#: lib/perl5/Selima/PageFunc.pm:222 +msgid "News" +msgstr "" + +#: lib/perl5/Selima/PageFunc.pm:223 +msgid "Related links" +msgstr "" + +#: lib/perl5/Selima/PageFunc.pm:224 +msgid "Home page" +msgstr "" + +#: lib/perl5/Selima/PageFunc.pm:225 +msgid "Whole web site" +msgstr "" + +#: lib/perl5/Selima/Picture.pm:49 +msgid "Left-aligned" +msgstr "" + +#: lib/perl5/Selima/Picture.pm:50 +msgid "Right-aligned" +msgstr "" + +#: lib/perl5/Selima/Picture.pm:87 +#, c-format +msgid "Width: [#,_1], height: [#,_2], ratio: [sprintf,%0.2f,_3]" +msgstr "" + +#: lib/perl5/Selima/Picture.pm:113 +msgid "Please specify a numeric ratio." +msgstr "" + +#: lib/perl5/Selima/Picture.pm:116 +msgid "Please specify a positive ratio." +msgstr "" + +#: lib/perl5/Selima/Picture.pm:118 +#, c-format +msgid "Please specify a ratio less than or equal to [sprintf,%0.2f,_1]." +msgstr "" + +#: lib/perl5/Selima/Picture.pm:122 +msgid "This image is too large to display." +msgstr "" + +#: lib/perl5/Selima/Preview.pm:53 lib/perl5/Selima/Preview.pm:115 +msgid "Unknown preview source: \"[_1]\"." +msgstr "" + +#: lib/perl5/Selima/Preview.pm:69 +msgid "Unknown preview form: \"[_1]\"." +msgstr "" + +#: lib/perl5/Selima/Preview.pm:126 +msgid "Preview" +msgstr "" + +#: lib/perl5/Selima/Preview.pm:127 +msgid "Finish preview and return." +msgstr "" + +#: lib/perl5/Selima/Processor.pm:203 +msgid "This record was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor.pm:207 +msgid "This record has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor.pm:211 +msgid "This record has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor.pm:215 +msgid "This record has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctRec.pm:41 +msgid "Please select a accounting transaction." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctRec.pm:44 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctRec.pm:62 +msgid "This option is invalid. Please select a proper type." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctRec.pm:83 +msgid "Please select a accounting subject." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctRec.pm:86 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctRec.pm:93 +msgid "" +"Only a last-level accounting subject is allowed for an accounting subject." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctRec.pm:113 +msgid "This summary is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/AcctRec.pm:137 +msgid "Please fill in the amount." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctRec.pm:140 +msgid "This amount is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/AcctRec.pm:144 +msgid "Please fill in a positive integer amount." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:39 +msgid "Please fill in the code." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:42 +msgid "This code is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:46 +msgid "Only numbers are allowed for the code." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:56 +msgid "" +"This accounting subject already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:65 +msgid "" +"Accounting subject [_1] does not exist. You cannot create a subject under " +"that." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:80 +#: lib/perl5/Selima/Checker/AcctSubj.pm:101 +msgid "Please select a parent accounting subject." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:85 +msgid "" +"This option is invalid. Please select a proper parent accounting subject." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:92 +msgid "" +"An accounting subject having its code with a single digit must not have a " +"parent." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:104 +msgid "" +"An accounting subject cannot belong to itself. Please select another one." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:108 +msgid "" +"This parent accounting subject does not exist anymore. Please select " +"another one." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:113 +msgid "" +"The parent accounting subject of accounting subject [_1] must be of code " +"[_2], not [_3]." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:122 +msgid "" +"An accounting subject having its code with more than one digit must have a " +"parent." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:53 +msgid "This form suptype is invalid. Please specify a proper user." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:73 +msgid "Please fill in the credit side of the accounting transaction." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:75 +#: lib/perl5/Selima/Checker/AcctTrx.pm:98 +msgid "Please fill in the accounting transaction content." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:96 +msgid "Please fill in the debit side of the accounting transaction." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:162 +msgid "" +"The total amounts of the debit side and the credit side are not balanced " +"(debit [_1], credit [_2]." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:182 +#: lib/perl5/Selima/Form/AcctTrx.pm:802 +msgid "Fill in the note here." +msgstr "" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:185 +msgid "This note is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/GroupMem.pm:54 +msgid "Please select a different belonging group." +msgstr "" + +#: lib/perl5/Selima/Checker/GroupMem.pm:74 +#: lib/perl5/Selima/Checker/UserMem.pm:59 +msgid "Please select a member." +msgstr "" + +#: lib/perl5/Selima/Checker/GroupMem.pm:77 +#: lib/perl5/Selima/Checker/UserMem.pm:62 +msgid "This member does not exist anymore. Please select another one." +msgstr "" + +#: lib/perl5/Selima/Checker/GroupMem.pm:80 +msgid "Please select a different group member." +msgstr "" + +#: lib/perl5/Selima/Checker/GroupMem.pm:103 +#: lib/perl5/Selima/Checker/UserMem.pm:83 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/perl5/Selima/Checker/Group.pm:45 +msgid "Please fill in the group ID." +msgstr "" + +#: lib/perl5/Selima/Checker/Group.pm:48 +msgid "This group ID. is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Group.pm:51 +msgid "This group ID. is too short. (Min. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Group.pm:55 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "" + +#: lib/perl5/Selima/Checker/Group.pm:65 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/perl5/Selima/Checker/Group.pm:83 +msgid "Please fill in the privilege description." +msgstr "" + +#: lib/perl5/Selima/Checker/Group.pm:86 +msgid "This privilege description is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook.pm:38 +#: lib/perl5/Selima/Checker/Guestbook.pm:60 +msgid "This signature is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook.pm:57 +msgid "Please fill in the signature." +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook.pm:79 +msgid "This identity is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook.pm:98 +msgid "This location is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook.pm:117 +#: lib/perl5/Selima/Checker/Link.pm:92 lib/perl5/Selima/Checker/User.pm:229 +msgid "This e-mail is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook.pm:136 +msgid "This website URL is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/LinkCat.pm:40 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "" + +#: lib/perl5/Selima/Checker/LinkCat.pm:56 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/perl5/Selima/Checker/LinkCat.pm:70 +#: lib/perl5/Selima/Checker/LinkCat.pm:85 +msgid "Please select a parent category." +msgstr "" + +#: lib/perl5/Selima/Checker/LinkCat.pm:75 +msgid "This option is invalid. Please select a proper parent category." +msgstr "" + +#: lib/perl5/Selima/Checker/LinkCat.pm:88 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "" + +#: lib/perl5/Selima/Checker/LinkCat.pm:92 +msgid "A category cannot belong to itself. Please select another one." +msgstr "" + +#: lib/perl5/Selima/Checker/LinkCat.pm:99 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:56 lib/perl5/Selima/Checker/Link.pm:72 +msgid "Please select a category." +msgstr "" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:59 lib/perl5/Selima/Checker/Link.pm:67 +msgid "This category does not exist anymore. Please select another one." +msgstr "" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:77 +msgid "Please select a related link." +msgstr "" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:80 +msgid "This related link does not exist anymore. Please select another one." +msgstr "" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:101 +msgid "" +"This categorization record already exists. You cannot create a duplicated " +"one." +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:44 +msgid "This address is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:64 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:95 lib/perl5/Selima/Checker/User.pm:232 +msgid "This e-mail is too short. (Min. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:99 lib/perl5/Selima/Checker/MailTo.pm:36 +#: lib/perl5/Selima/Checker/User.pm:236 +msgid "Please fill in a valid e-mail address." +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:101 lib/perl5/Selima/Checker/MailTo.pm:38 +#: lib/perl5/Selima/Checker/User.pm:238 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:122 +msgid "This facsimile number is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:143 +msgid "This link icon URL is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:147 +msgid "Please fill in a valid link icon URL." +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:150 +msgid "This link icon URL is not reachable. Check if there is any typo in it." +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:171 +msgid "This telephone number is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:192 +msgid "This 2nd language title is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:211 +msgid "Please fill in the URL." +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:214 +msgid "This URL is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:218 +msgid "Please fill in a valid URL." +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:228 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/perl5/Selima/Checker/Link.pm:231 +msgid "This URL is not reachable. Check if there is any typo in it." +msgstr "" + +#: lib/perl5/Selima/Checker/ListPref.pm:42 +#: lib/perl5/Selima/Checker/UserPref.pm:88 +msgid "Please fill in the preference domain." +msgstr "" + +#: lib/perl5/Selima/Checker/ListPref.pm:45 +#: lib/perl5/Selima/Checker/UserPref.pm:91 +msgid "This preference domain is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/ListPref.pm:90 +msgid "Please fill in the number of rows per page." +msgstr "" + +#: lib/perl5/Selima/Checker/ListPref.pm:93 +msgid "Please fill in a positive integer number of rows per page." +msgstr "" + +#: lib/perl5/Selima/Checker/ListPref.pm:100 +msgid "This number of rows per page is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/LogIn.pm:63 +msgid "Please fill in your user ID." +msgstr "" + +#: lib/perl5/Selima/Checker/LogIn.pm:70 lib/perl5/Selima/Checker/LogIn.pm:76 +#: lib/perl5/Selima/Checker/LogIn.pm:91 lib/perl5/Selima/Checker/LogIn.pm:136 +#: lib/perl5/Selima/Checker/LogIn.pm:142 lib/perl5/Selima/Checker/LogIn.pm:151 +#: lib/perl5/Selima/Checker/LogIn.pm:178 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "" + +#: lib/perl5/Selima/Checker/LogIn.pm:109 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "" + +#: lib/perl5/Selima/Checker/LogIn.pm:129 +msgid "Please fill in your password." +msgstr "" + +#: lib/perl5/Selima/Checker/LogIn.pm:199 +msgid "You are not an administrator and cannot log into here." +msgstr "" + +#: lib/perl5/Selima/Checker/LogIn.pm:218 +msgid "You are an administrator and cannot log into here." +msgstr "" + +#: lib/perl5/Selima/Checker/MailTo.pm:29 lib/perl5/Selima/Checker/User.pm:226 +msgid "Please fill in the e-mail." +msgstr "" + +#: lib/perl5/Selima/Checker/Rebuild.pm:28 +msgid "Please select the type." +msgstr "" + +#: lib/perl5/Selima/Checker/Rebuild.pm:31 +msgid "This type does not exist anymore. Please select another one." +msgstr "" + +#: lib/perl5/Selima/Checker/ScptPriv.pm:63 +msgid "" +"This script privilege record already exists. You cannot create a duplicated " +"one." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:85 +msgid "Please fill in the user ID." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:88 +msgid "This user ID. is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:91 +msgid "This user ID. is too short. (Min. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:95 +msgid "" +"Only English letters, numbers, at-signs, dots, dashes and underscores are " +"allowed for the user ID." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:105 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:129 +msgid "Please fill in the password." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:131 +msgid "Please confirm the password." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:134 +msgid "This password is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:137 +msgid "This password is too short. (Min. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:142 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:151 +msgid "This password is based on the user ID." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:166 +msgid "This password does not contain enough different characters." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:170 +msgid "This password is too simplistic/systematic." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:174 +msgid "This password is based on a dictionary word." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:176 +msgid "This password is based on a (reversed) dictionary word." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:178 +msgid "This password is too simple." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:183 +msgid "You cannot use a password that is based on your user ID." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:203 +msgid "Please fill in the name." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:206 +msgid "This name is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:259 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:271 +msgid "You cannot submit the super-user group along with other groups." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:273 +msgid "You cannot set the administrators group." +msgstr "" + +#: lib/perl5/Selima/Checker/User.pm:275 +msgid "You cannot set the all-users group." +msgstr "" + +#: lib/perl5/Selima/Checker/UserPref.pm:50 +msgid "Please select the user." +msgstr "" + +#: lib/perl5/Selima/Checker/UserPref.pm:55 +msgid "This option is invalid. Please select a proper user." +msgstr "" + +#: lib/perl5/Selima/Checker/UserPref.pm:73 +msgid "Please set the preference domain." +msgstr "" + +#: lib/perl5/Selima/Checker/UserPref.pm:78 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "" + +#: lib/perl5/Selima/Checker/UserPref.pm:111 +msgid "Please fill in the preference name." +msgstr "" + +#: lib/perl5/Selima/Checker/UserPref.pm:114 +msgid "This preference name is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/UserPref.pm:133 +msgid "Please fill in the preference value." +msgstr "" + +#: lib/perl5/Selima/Checker/UserPref.pm:136 +msgid "This preference value is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/UserPref.pm:167 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:33 +msgid "Delete this accounting record" +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:38 +msgid "This table provides you a form to add a new accounting record." +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:41 +msgid "This table provides you a form to edit a current accounting record." +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:44 +msgid "This table provides you a form to delete an accounting record." +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:61 +msgid "Add a New Accounting Record" +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:64 +msgid "Edit a Current Accounting Record" +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:67 +msgid "Delete an Accounting Record" +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:76 +msgid "Accounting transaction:" +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:85 lib/perl5/Selima/Form/AcctTrx.pm:334 +#: lib/perl5/Selima/List/Accounting/Reports.pm:75 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:233 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:226 +msgid "Debit" +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:87 lib/perl5/Selima/Form/AcctTrx.pm:335 +#: lib/perl5/Selima/List/Accounting/Reports.pm:76 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:237 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:230 +msgid "Credit" +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:88 lib/perl5/Selima/Form/Rebuild.pm:52 +msgid "Type:" +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:99 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:284 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:268 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:328 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:284 +msgid "Accounting subject:" +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:157 +msgid "Summary:" +msgstr "" + +#: lib/perl5/Selima/Form/AcctRec.pm:162 +msgid "Amount:" +msgstr "" + +#: lib/perl5/Selima/Form/AcctSubj.pm:34 +msgid "Delete this accounting subject" +msgstr "" + +#: lib/perl5/Selima/Form/AcctSubj.pm:39 +msgid "This table provides you a form to add a new accounting subject." +msgstr "" + +#: lib/perl5/Selima/Form/AcctSubj.pm:42 +msgid "This table provides you a form to edit a current accounting subject." +msgstr "" + +#: lib/perl5/Selima/Form/AcctSubj.pm:45 +msgid "This table provides you a form to delete an accounting subject." +msgstr "" + +#: lib/perl5/Selima/Form/AcctSubj.pm:62 +msgid "Add a New Accounting Subject" +msgstr "" + +#: lib/perl5/Selima/Form/AcctSubj.pm:65 +msgid "Edit a Current Accounting Subject" +msgstr "" + +#: lib/perl5/Selima/Form/AcctSubj.pm:68 +msgid "Delete an Accounting Subject" +msgstr "" + +#: lib/perl5/Selima/Form/AcctSubj.pm:75 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the accounting " +"subject, [numerate,_1,its accounting sub-subject,all of its accounting sub-" +"subjects] must first be deleted." +msgstr "" + +#: lib/perl5/Selima/Form/AcctSubj.pm:79 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the accounting subject, " +"[numerate,_1,its accounting record,all of its accounting records] must first " +"be deleted." +msgstr "" + +#: lib/perl5/Selima/Form/AcctSubj.pm:87 +msgid "Code:" +msgstr "" + +#: lib/perl5/Selima/Form/AcctSubj.pm:93 +msgid "Parent subject:" +msgstr "" + +#: lib/perl5/Selima/Form/AcctSubj.pm:106 +msgid "[numerate,_1,Sub-subject,Sub-subjects]:" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:37 +msgid "Delete this accounting transaction" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:43 +msgid "This table provides you a form to add a new accounting transaction." +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:46 +msgid "" +"This table provides you a form to edit a current accounting transaction." +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:49 +msgid "This table provides you a form to delete an accounting transaction." +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:92 lib/perl5/Selima/Form/AcctTrx.pm:97 +msgid "Convert to a transfer transaction" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:102 +msgid "Add a New Cache Expense Transaction" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:104 +msgid "Add a New Cache Income Transaction" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:106 +msgid "Add a New Transfer Transaction" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:111 +msgid "Edit a Current Cache Expense Transaction" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:113 +msgid "Edit a Current Cache Income Transaction" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:115 +msgid "Edit a Current Transfer Transaction" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:120 +msgid "Delete a Cache Expense Transaction" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:122 +msgid "Delete a Cache Income Transaction" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:124 +msgid "Delete a Transfer Transaction" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:336 +#: lib/perl5/Selima/List/Accounting/Records.pm:35 +#: lib/perl5/Selima/List/Accounting/Reports.pm:73 +msgid "Accounting subject" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:337 +#: lib/perl5/Selima/List/Accounting/Records.pm:36 +#: lib/perl5/Selima/List/Accounting/Reports.pm:74 +msgid "Summary" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:338 +#: lib/perl5/Selima/List/Accounting/Records.pm:37 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:40 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:41 +msgid "Amount" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:339 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:173 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:196 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:200 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:152 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:130 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:151 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:177 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:166 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:189 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:144 +msgid "Total" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:379 lib/perl5/Selima/Form/AcctTrx.pm:518 +#: lib/perl5/Selima/Form/AcctTrx.pm:708 +msgid "[numerate,_1,Content]:" +msgstr "" + +#: lib/perl5/Selima/Form/AcctTrx.pm:801 +msgid "Note:" +msgstr "" + +#: lib/perl5/Selima/Form/GroupMem.pm:33 lib/perl5/Selima/Form/UserMem.pm:33 +msgid "Delete this membership record" +msgstr "" + +#: lib/perl5/Selima/Form/GroupMem.pm:38 lib/perl5/Selima/Form/UserMem.pm:38 +msgid "This table provides you a form to add a new membership record." +msgstr "" + +#: lib/perl5/Selima/Form/GroupMem.pm:41 lib/perl5/Selima/Form/UserMem.pm:41 +msgid "This table provides you a form to change a current membership record." +msgstr "" + +#: lib/perl5/Selima/Form/GroupMem.pm:44 lib/perl5/Selima/Form/UserMem.pm:44 +msgid "This table provides you a form to delete a membership record." +msgstr "" + +#: lib/perl5/Selima/Form/GroupMem.pm:61 +msgid "Add A New Group Membership Record" +msgstr "" + +#: lib/perl5/Selima/Form/GroupMem.pm:64 +msgid "Change a Current Group Membership Record" +msgstr "" + +#: lib/perl5/Selima/Form/GroupMem.pm:67 +msgid "Delete a Group Membership Record" +msgstr "" + +#: lib/perl5/Selima/Form/GroupMem.pm:76 lib/perl5/Selima/Form/UserMem.pm:76 +msgid "Member:" +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:37 +msgid "Delete this group" +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:42 +msgid "This table provides you a form to add a new group." +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:45 +msgid "This table provides you a form to update a current group." +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:48 +msgid "This table provides you a form to delete a group." +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:65 +msgid "Add a New Group" +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:68 +msgid "Update a Current Group" +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:71 +msgid "Delete a Group" +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:77 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:89 lib/perl5/Selima/Form/Group.pm:91 +msgid "Group ID.:" +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:110 +msgid "Add a user" +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:114 lib/perl5/Selima/Form/Group.pm:148 +#: lib/perl5/Selima/Form/Group.pm:164 lib/perl5/Selima/Form/Group.pm:211 +msgid "[numerate,_1,User member]:" +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:239 lib/perl5/Selima/Form/Group.pm:369 +msgid "Add a group" +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:243 lib/perl5/Selima/Form/Group.pm:277 +#: lib/perl5/Selima/Form/Group.pm:293 lib/perl5/Selima/Form/Group.pm:340 +msgid "[numerate,_1,Group member]:" +msgstr "" + +#: lib/perl5/Selima/Form/Group.pm:368 lib/perl5/Selima/Form/User.pm:223 +msgid "Belonging to:" +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:32 +msgid "Delete this message" +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:37 +msgid "This table provides you a form to add a new message." +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:40 +msgid "This table provides you a form to edit a current message." +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:43 +msgid "This table provides you a form to delete a message." +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:61 +msgid "Write a New Message" +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:64 +msgid "Edit a Current Message" +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:67 +msgid "Delete a Message" +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:77 lib/perl5/Selima/Form/User.pm:149 +msgid "Country:" +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:83 +msgid "Hide this message" +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:83 +msgid "Show this message" +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:84 +msgid "Hide this message currently." +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:89 +msgid "Signature:" +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:94 +msgid "Old page no.:" +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook.pm:99 +msgid "Page no.:" +msgstr "" + +#: lib/perl5/Selima/Form/LinkCat.pm:33 +msgid "Delete this category" +msgstr "" + +#: lib/perl5/Selima/Form/LinkCat.pm:38 +msgid "This table provides you a form to add a new category." +msgstr "" + +#: lib/perl5/Selima/Form/LinkCat.pm:41 +msgid "This table provides you a form to edit a current category." +msgstr "" + +#: lib/perl5/Selima/Form/LinkCat.pm:44 +msgid "This table provides you a form to delete a category." +msgstr "" + +#: lib/perl5/Selima/Form/LinkCat.pm:62 +msgid "Add a New Link Category" +msgstr "" + +#: lib/perl5/Selima/Form/LinkCat.pm:65 +msgid "Edit a Current Link Category" +msgstr "" + +#: lib/perl5/Selima/Form/LinkCat.pm:68 +msgid "Delete a Link Category" +msgstr "" + +#: lib/perl5/Selima/Form/LinkCat.pm:76 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "" + +#: lib/perl5/Selima/Form/LinkCat.pm:80 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "" + +#: lib/perl5/Selima/Form/LinkCat.pm:89 +msgid "Hide this category" +msgstr "" + +#: lib/perl5/Selima/Form/LinkCat.pm:89 +msgid "Show this category" +msgstr "" + +#: lib/perl5/Selima/Form/LinkCat.pm:90 +msgid "Hide this category currently." +msgstr "" + +#: lib/perl5/Selima/Form/LinkCat.pm:106 +msgid "[numerate,_1,Link,Links]:" +msgstr "" + +#: lib/perl5/Selima/Form/LinkCatz.pm:33 +msgid "Delete this categorization record" +msgstr "" + +#: lib/perl5/Selima/Form/LinkCatz.pm:38 +msgid "This table provides you a form to add a new categorization record." +msgstr "" + +#: lib/perl5/Selima/Form/LinkCatz.pm:41 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "" + +#: lib/perl5/Selima/Form/LinkCatz.pm:44 +msgid "This table provides you a form to delete a categorization record." +msgstr "" + +#: lib/perl5/Selima/Form/LinkCatz.pm:61 +msgid "Add A New Link Categorization Record" +msgstr "" + +#: lib/perl5/Selima/Form/LinkCatz.pm:64 +msgid "Change a Current Link Categorization Record" +msgstr "" + +#: lib/perl5/Selima/Form/LinkCatz.pm:67 +msgid "Delete a Link Categorization Record" +msgstr "" + +#: lib/perl5/Selima/Form/LinkCatz.pm:76 +msgid "Category:" +msgstr "" + +#: lib/perl5/Selima/Form/LinkCatz.pm:81 +msgid "Link:" +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:35 +msgid "Delete this related link" +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:40 +msgid "This table provides you a form to add a new related link." +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:43 +msgid "This table provides you a form to edit a current related link." +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:46 +msgid "This table provides you a form to delete a related link." +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:65 +msgid "Add a New Related Link" +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:68 +msgid "Edit a Current Related Link" +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:71 +msgid "Delete a Related Link" +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:81 +msgid "[numerate,_1,Category,Categories]:" +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:88 +msgid "Hide this related link" +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:88 +msgid "Show this related link" +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:89 +msgid "Hide this related link currently." +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:100 +msgid "Link icon:" +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:101 +msgid "Link icon unavailable" +msgstr "" + +#: lib/perl5/Selima/Form/Link.pm:173 +msgid "2nd language title:" +msgstr "" + +#: lib/perl5/Selima/Form/Page.pm:32 +msgid "Delete this page" +msgstr "" + +#: lib/perl5/Selima/Form/Page.pm:37 +msgid "This table provides you a form to write a new page." +msgstr "" + +#: lib/perl5/Selima/Form/Page.pm:40 +msgid "This table provides you a form to edit a current page." +msgstr "" + +#: lib/perl5/Selima/Form/Page.pm:43 +msgid "This table provides you a form to delete a page." +msgstr "" + +#: lib/perl5/Selima/Form/Page.pm:60 +msgid "Write a New Page" +msgstr "" + +#: lib/perl5/Selima/Form/Page.pm:63 +msgid "Edit a Current Page" +msgstr "" + +#: lib/perl5/Selima/Form/Page.pm:66 +msgid "Delete a Page" +msgstr "" + +#: lib/perl5/Selima/Form/Page.pm:73 +msgid "Preview this page." +msgstr "" + +#: lib/perl5/Selima/Form/Page.pm:82 +msgid "Hide this page" +msgstr "" + +#: lib/perl5/Selima/Form/Page.pm:82 +msgid "Show this page" +msgstr "" + +#: lib/perl5/Selima/Form/Page.pm:83 +msgid "Hide this page currently." +msgstr "" + +#: lib/perl5/Selima/Form/Rebuild.pm:36 +msgid "Rebuild the Pages" +msgstr "" + +#: lib/perl5/Selima/Form/Rebuild.pm:41 +msgid "Confirm" +msgstr "" + +#: lib/perl5/Selima/Form/ScptPriv.pm:33 +msgid "Delete this script privilege record" +msgstr "" + +#: lib/perl5/Selima/Form/ScptPriv.pm:38 +msgid "This table provides you a form to add a new script privilege record." +msgstr "" + +#: lib/perl5/Selima/Form/ScptPriv.pm:41 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "" + +#: lib/perl5/Selima/Form/ScptPriv.pm:44 +msgid "This table provides you a form to delete a script privilege record." +msgstr "" + +#: lib/perl5/Selima/Form/ScptPriv.pm:61 +msgid "Add A New Script Privilege Record" +msgstr "" + +#: lib/perl5/Selima/Form/ScptPriv.pm:64 +msgid "Change a Current Script Privilege Record" +msgstr "" + +#: lib/perl5/Selima/Form/ScptPriv.pm:67 +msgid "Delete a Script Privilege Record" +msgstr "" + +#: lib/perl5/Selima/Form/ScptPriv.pm:76 +msgid "Privilege:" +msgstr "" + +#: lib/perl5/Selima/Form/UserMem.pm:61 +msgid "Add A New User Membership Record" +msgstr "" + +#: lib/perl5/Selima/Form/UserMem.pm:64 +msgid "Change a Current User Membership Record" +msgstr "" + +#: lib/perl5/Selima/Form/UserMem.pm:67 +msgid "Delete a User Membership Record" +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:39 +msgid "Delete this user account" +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:46 +msgid "This table provides you a form to add a new user account." +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:49 +msgid "This table provides you a form to update a current user account." +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:52 +msgid "This table provides you a form to delete a user account." +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:70 +msgid "Add a New User Account" +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:73 +msgid "Update a Current User Account" +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:76 +msgid "Delete a User Account" +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:84 +msgid "This is a super-user. You can only change parts of her/his infomation." +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:143 +msgid "Administrator?" +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:144 +msgid "Administrator" +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:144 +msgid "Non-administrator" +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:165 +msgid "Disable this user account." +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:176 lib/perl5/Selima/Form/User.pm:178 +msgid "User ID.:" +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:184 +msgid "Pref. language:" +msgstr "" + +#: lib/perl5/Selima/Form/User.pm:189 +msgid "Full name:" +msgstr "" + +#: lib/perl5/Selima/Form/UserPref.pm:35 +msgid "Delete this user preference" +msgstr "" + +#: lib/perl5/Selima/Form/UserPref.pm:40 +msgid "This table provides you a form to add a new user preference." +msgstr "" + +#: lib/perl5/Selima/Form/UserPref.pm:43 +msgid "This table provides you a form to modify a current user preference." +msgstr "" + +#: lib/perl5/Selima/Form/UserPref.pm:46 +msgid "This table provides you a form to delete a user preference." +msgstr "" + +#: lib/perl5/Selima/Form/UserPref.pm:63 +msgid "Add A New User Preference" +msgstr "" + +#: lib/perl5/Selima/Form/UserPref.pm:66 +msgid "Modify a Current User Preference" +msgstr "" + +#: lib/perl5/Selima/Form/UserPref.pm:69 +msgid "Delete a User Preference" +msgstr "" + +#: lib/perl5/Selima/Form/UserPref.pm:82 +msgid "Domain:" +msgstr "" + +#: lib/perl5/Selima/Form/UserPref.pm:83 +msgid "Everywhere" +msgstr "" + +#: lib/perl5/Selima/Form/UserPref.pm:88 +msgid "User:" +msgstr "" + +#: lib/perl5/Selima/Form/UserPref.pm:89 +msgid "Everyone" +msgstr "" + +#: lib/perl5/Selima/List/ActLog.pm:31 +msgid "Browse the Activity Log" +msgstr "" + +#: lib/perl5/Selima/List/ActLog.pm:132 +msgid "Please fill in the number of rows to display." +msgstr "" + +#: lib/perl5/Selima/List/ActLog.pm:135 +msgid "Please fill in a positive integer number of rows to display." +msgstr "" + +#: lib/perl5/Selima/List/ActLog.pm:140 +msgid "This number of rows to display is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/List/ActLog.pm:157 +msgid "Search for log entries:" +msgstr "" + +#: lib/perl5/Selima/List/ActLog.pm:162 +msgid "Display" +msgstr "" + +#: lib/perl5/Selima/List/ActLog.pm:163 +msgid "Display rows:" +msgstr "" + +#: lib/perl5/Selima/List/ActLog.pm:198 +msgid "Your query found [*,_1,log entry,log entries]." +msgstr "" + +#: lib/perl5/Selima/List/ActLog.pm:201 +msgid "[*,_1,log entry,log entries]." +msgstr "" + +#: lib/perl5/Selima/List/ActLog.pm:207 +msgid "" +"Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/ActLog.pm:211 +msgid "[*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Category.pm:18 +msgid "Add a new category." +msgstr "" + +#: lib/perl5/Selima/List/Category.pm:24 +msgid "Search for a category:" +msgstr "" + +#: lib/perl5/Selima/List/Category.pm:41 +msgid "Your query found [*,_1,category,categories]." +msgstr "" + +#: lib/perl5/Selima/List/Category.pm:44 +msgid "[*,_1,category,categories]." +msgstr "" + +#: lib/perl5/Selima/List/Category.pm:50 +msgid "Your query found [*,_1,category,categories], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Category.pm:54 +msgid "[*,_1,category,categories], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Categorz.pm:18 +msgid "Add a new categorization record." +msgstr "" + +#: lib/perl5/Selima/List/Categorz.pm:24 +msgid "Search for a categorization record:" +msgstr "" + +#: lib/perl5/Selima/List/Categorz.pm:41 +msgid "Your query found [*,_1,categorization record]." +msgstr "" + +#: lib/perl5/Selima/List/Categorz.pm:44 +msgid "[*,_1,categorization record]." +msgstr "" + +#: lib/perl5/Selima/List/Categorz.pm:50 +msgid "" +"Your query found [*,_1,categorization record], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Categorz.pm:54 +msgid "[*,_1,categorization record], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/GroupMem.pm:24 +msgid "Select a Group Membership Record" +msgstr "" + +#: lib/perl5/Selima/List/GroupMem.pm:25 +msgid "Manage Group Membership" +msgstr "" + +#: lib/perl5/Selima/List/GroupMem.pm:30 lib/perl5/Selima/List/UserMem.pm:30 +msgid "Group" +msgstr "" + +#: lib/perl5/Selima/List/GroupMem.pm:31 lib/perl5/Selima/List/UserMem.pm:31 +msgid "Member" +msgstr "" + +#: lib/perl5/Selima/List/GroupMem.pm:39 lib/perl5/Selima/List/UserMem.pm:39 +msgid "Add a new membership record." +msgstr "" + +#: lib/perl5/Selima/List/GroupMem.pm:45 lib/perl5/Selima/List/UserMem.pm:45 +msgid "Search for a membership record:" +msgstr "" + +#: lib/perl5/Selima/List/GroupMem.pm:62 lib/perl5/Selima/List/UserMem.pm:62 +msgid "Your query found [*,_1,membership record]." +msgstr "" + +#: lib/perl5/Selima/List/GroupMem.pm:65 lib/perl5/Selima/List/UserMem.pm:65 +msgid "[*,_1,membership record]." +msgstr "" + +#: lib/perl5/Selima/List/GroupMem.pm:71 lib/perl5/Selima/List/UserMem.pm:71 +msgid "Your query found [*,_1,membership record], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/GroupMem.pm:75 lib/perl5/Selima/List/UserMem.pm:75 +msgid "[*,_1,membership record], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Groups.pm:23 +msgid "Select a Group" +msgstr "" + +#: lib/perl5/Selima/List/Groups.pm:24 +msgid "Manage Groups" +msgstr "" + +#: lib/perl5/Selima/List/Groups.pm:29 +msgid "Group ID." +msgstr "" + +#: lib/perl5/Selima/List/Groups.pm:38 +msgid "Add a new group." +msgstr "" + +#: lib/perl5/Selima/List/Groups.pm:44 +msgid "Search for a group:" +msgstr "" + +#: lib/perl5/Selima/List/Groups.pm:61 +msgid "Your query found [*,_1,group]." +msgstr "" + +#: lib/perl5/Selima/List/Groups.pm:64 +msgid "[*,_1,group]." +msgstr "" + +#: lib/perl5/Selima/List/Groups.pm:70 +msgid "Your query found [*,_1,group], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Groups.pm:74 +msgid "[*,_1,group], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:26 +msgid "Select a Message" +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:27 +msgid "Manage Guestbook" +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:38 +msgid "Signature" +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:39 +msgid "Identity" +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:40 +msgid "Location" +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:41 +msgid "Message" +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:42 lib/perl5/Selima/List/Users.pm:35 +msgid "IP" +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:43 lib/perl5/Selima/List/Users.pm:36 +msgid "Host" +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:44 lib/perl5/Selima/List/Users.pm:37 +msgid "Country" +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:45 +msgid "Page No." +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:46 +msgid "Old page No." +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:54 +msgid "Write a new message." +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:60 +msgid "Search for a message:" +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:77 +msgid "Your query found [*,_1,message]." +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:80 +msgid "[*,_1,message]." +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:86 +msgid "Your query found [*,_1,message], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Guestbook.pm:90 +msgid "[*,_1,message], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/LinkCat.pm:24 +msgid "Select a Link Category" +msgstr "" + +#: lib/perl5/Selima/List/LinkCat.pm:25 +msgid "Manage Link Categories" +msgstr "" + +#: lib/perl5/Selima/List/LinkCatz.pm:24 +msgid "Select a Link Categorization Record" +msgstr "" + +#: lib/perl5/Selima/List/LinkCatz.pm:25 +msgid "Manage Link Categorization" +msgstr "" + +#: lib/perl5/Selima/List/LinkCatz.pm:30 +msgid "Link" +msgstr "" + +#: lib/perl5/Selima/List/Links.pm:24 +msgid "Select a Related Link" +msgstr "" + +#: lib/perl5/Selima/List/Links.pm:25 +msgid "Manage Related Links" +msgstr "" + +#: lib/perl5/Selima/List/Links.pm:32 +msgid "2nd language title" +msgstr "" + +#: lib/perl5/Selima/List/Links.pm:33 +msgid "Link icon" +msgstr "" + +#: lib/perl5/Selima/List/Links.pm:34 +msgid "Address" +msgstr "" + +#: lib/perl5/Selima/List/Links.pm:35 +msgid "Tel." +msgstr "" + +#: lib/perl5/Selima/List/Links.pm:36 +msgid "Fax." +msgstr "" + +#: lib/perl5/Selima/List/Links.pm:44 +msgid "Add a new related link." +msgstr "" + +#: lib/perl5/Selima/List/Links.pm:50 +msgid "Search for a related link:" +msgstr "" + +#: lib/perl5/Selima/List/Links.pm:67 +msgid "Your query found [*,_1,related link]." +msgstr "" + +#: lib/perl5/Selima/List/Links.pm:70 +msgid "[*,_1,related link]." +msgstr "" + +#: lib/perl5/Selima/List/Links.pm:76 +msgid "Your query found [*,_1,related link], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Links.pm:80 +msgid "[*,_1,related link], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Pages.pm:24 +msgid "Select a Page" +msgstr "" + +#: lib/perl5/Selima/List/Pages.pm:25 +msgid "Manage Pages" +msgstr "" + +#: lib/perl5/Selima/List/Pages.pm:40 +msgid "Write a new page." +msgstr "" + +#: lib/perl5/Selima/List/Pages.pm:46 +msgid "Search for a page:" +msgstr "" + +#: lib/perl5/Selima/List/Pages.pm:63 +msgid "Your query found [*,_1,page]." +msgstr "" + +#: lib/perl5/Selima/List/Pages.pm:66 +msgid "[*,_1,page]." +msgstr "" + +#: lib/perl5/Selima/List/Pages.pm:72 +msgid "Your query found [*,_1,page], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Pages.pm:76 +msgid "[*,_1,page], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/ScptPriv.pm:24 +msgid "Select a Script Privilege Record" +msgstr "" + +#: lib/perl5/Selima/List/ScptPriv.pm:25 +msgid "Manage Script Privileges" +msgstr "" + +#: lib/perl5/Selima/List/ScptPriv.pm:30 +msgid "Script" +msgstr "" + +#: lib/perl5/Selima/List/ScptPriv.pm:31 +msgid "Privilege" +msgstr "" + +#: lib/perl5/Selima/List/ScptPriv.pm:39 +msgid "Add a new script privilege record." +msgstr "" + +#: lib/perl5/Selima/List/ScptPriv.pm:45 +msgid "Search for a script privilege record:" +msgstr "" + +#: lib/perl5/Selima/List/ScptPriv.pm:62 +msgid "Your query found [*,_1,script privilege record]." +msgstr "" + +#: lib/perl5/Selima/List/ScptPriv.pm:65 +msgid "[*,_1,script privilege record]." +msgstr "" + +#: lib/perl5/Selima/List/ScptPriv.pm:71 +msgid "" +"Your query found [*,_1,script privilege record], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/ScptPriv.pm:75 +msgid "[*,_1,script privilege record], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/UserMem.pm:24 +msgid "Select a User Membership Record" +msgstr "" + +#: lib/perl5/Selima/List/UserMem.pm:25 +msgid "Manage User Membership" +msgstr "" + +#: lib/perl5/Selima/List/UserPref.pm:24 +msgid "Select a User Preference" +msgstr "" + +#: lib/perl5/Selima/List/UserPref.pm:25 +msgid "Manage User Preferences" +msgstr "" + +#: lib/perl5/Selima/List/UserPref.pm:30 +msgid "User" +msgstr "" + +#: lib/perl5/Selima/List/UserPref.pm:31 +msgid "Domain" +msgstr "" + +#: lib/perl5/Selima/List/UserPref.pm:32 +msgid "Value" +msgstr "" + +#: lib/perl5/Selima/List/UserPref.pm:40 +msgid "Add a new user preference." +msgstr "" + +#: lib/perl5/Selima/List/UserPref.pm:46 +msgid "Search for a user preference:" +msgstr "" + +#: lib/perl5/Selima/List/UserPref.pm:63 +msgid "Your query found [*,_1,user preference]." +msgstr "" + +#: lib/perl5/Selima/List/UserPref.pm:66 +msgid "[*,_1,user preference]." +msgstr "" + +#: lib/perl5/Selima/List/UserPref.pm:72 +msgid "Your query found [*,_1,user preference], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/UserPref.pm:76 +msgid "[*,_1,user preference], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:23 +msgid "Select a User" +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:24 +msgid "Manage Users" +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:29 +msgid "User ID." +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:30 +msgid "Full name" +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:31 +msgid "Deleted?" +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:32 +msgid "Pref. language" +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:33 +msgid "Visits" +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:34 +msgid "Visited" +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:45 +msgid "Add a new user account." +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:51 +msgid "Search for a user:" +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:68 +msgid "Your query found [*,_1,user]." +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:71 +msgid "[*,_1,user]." +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:77 +msgid "Your query found [*,_1,user], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Users.pm:81 +msgid "[*,_1,user], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/Processor/AcctRec.pm:103 +msgid "This accounting record was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/AcctRec.pm:107 +msgid "This accounting record has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/AcctRec.pm:111 +msgid "This accounting record has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/AcctRec.pm:115 +msgid "This accounting record has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:86 +msgid "This accounting subject was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:90 +msgid "This accounting subject has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:94 +msgid "This accounting subject has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:98 +msgid "This accounting subject has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:418 +msgid "This accounting transaction was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:422 +msgid "This accounting transaction has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:426 +msgid "This accounting transaction has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:430 +msgid "This accounting transaction has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Processor/Category.pm:20 +msgid "This category was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/Category.pm:24 +msgid "This category has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/Category.pm:28 +msgid "This category has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/Category.pm:32 +msgid "This category has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Processor/Categorz.pm:20 +msgid "This categorization record was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/Categorz.pm:24 +msgid "This categorization record has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/Categorz.pm:28 +msgid "This categorization record has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/Categorz.pm:32 +msgid "This categorization record has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Processor/GroupMem.pm:79 +msgid "This group membership record was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/GroupMem.pm:83 +msgid "This group membership record has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/GroupMem.pm:87 +msgid "This group membership record has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/GroupMem.pm:91 +msgid "This group membership record has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Processor/Group.pm:253 +msgid "This group was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/Group.pm:257 +msgid "This group has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/Group.pm:261 +msgid "This group has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/Group.pm:265 +msgid "This group has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Processor/Guestbook.pm:117 +msgid "This message was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/Guestbook.pm:121 +msgid "This message has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/Guestbook.pm:125 +msgid "This message has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/Guestbook.pm:129 +msgid "This message has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Processor/Link.pm:168 +msgid "This related link was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/Link.pm:172 +msgid "This related link has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/Link.pm:176 +msgid "This related link has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/Link.pm:180 +msgid "This related link has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Processor/LogOut.pm:52 +msgid "You have successfully logged out." +msgstr "" + +#: lib/perl5/Selima/Processor/Page.pm:89 +msgid "This page was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/Page.pm:93 +msgid "This page has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/Page.pm:97 +msgid "This page has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/Page.pm:101 +msgid "This page has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Processor/Rebuild.pm:48 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. ([sprintf,%0.3f,_1] " +"seconds)" +msgstr "" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:79 +msgid "This script privilege record was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:83 +msgid "This script privilege record has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:87 +msgid "This script privilege record has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:91 +msgid "This script privilege record has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Processor/UserMem.pm:79 +msgid "This user membership record was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/UserMem.pm:83 +msgid "This user membership record has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/UserMem.pm:87 +msgid "This user membership record has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/UserMem.pm:91 +msgid "This user membership record has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Processor/User.pm:185 +msgid "This user account was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/User.pm:189 +msgid "This user account has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/User.pm:193 +msgid "This user account has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/User.pm:197 +msgid "This user account has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Processor/UserPref.pm:128 +msgid "This user preference was not modified." +msgstr "" + +#: lib/perl5/Selima/Processor/UserPref.pm:132 +msgid "This user preference has been successfully added." +msgstr "" + +#: lib/perl5/Selima/Processor/UserPref.pm:136 +msgid "This user preference has been successfully updated." +msgstr "" + +#: lib/perl5/Selima/Processor/UserPref.pm:140 +msgid "This user preference has been successfully deleted." +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:37 +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:59 +msgid "Your signature is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:56 +msgid "Please fill in your signature." +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:80 +msgid "Your identity is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:101 +msgid "Your location is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:122 +msgid "Your e-mail is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:143 +msgid "Your website URL is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:163 +#: lib/perl5/Selima/Form/Guestbook/Public.pm:60 +msgid "Fill in your message here." +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:164 +msgid "Please fill in your message." +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:167 +msgid "Your message is too long. (Max. length [#,_1])" +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:186 +msgid "You can post at most 5 messages in 1 hour." +msgstr "" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:204 +msgid "Your message is already posted." +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook/Public.pm:40 +msgid "Leave a messsage" +msgstr "" + +#: lib/perl5/Selima/Form/Guestbook/Public.pm:42 +msgid "This table provides you a form to leave a message." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Records.pm:27 +msgid "Select an Accounting Record" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Records.pm:28 +msgid "Manage Accounting Records" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Records.pm:33 +msgid "Accounting transaction" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Records.pm:34 +msgid "Debit/credit" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Records.pm:46 +msgid "Add a new accounting record." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Records.pm:52 +msgid "Search for an accounting record:" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Records.pm:69 +#: lib/perl5/Selima/List/Accounting/Reports.pm:634 +msgid "Your query found [*,_1,accounting record]." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Records.pm:72 +#: lib/perl5/Selima/List/Accounting/Reports.pm:637 +msgid "[*,_1,accounting record]." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Records.pm:78 +#: lib/perl5/Selima/List/Accounting/Reports.pm:643 +msgid "Your query found [*,_1,accounting record], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Records.pm:82 +#: lib/perl5/Selima/List/Accounting/Reports.pm:647 +msgid "[*,_1,accounting record], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:31 +msgid "View the Accounting Reports" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:72 +msgid "Month" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:77 +msgid "Income" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:78 +msgid "Expense" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:79 +msgid "Balance" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:137 +msgid "Please specify a month." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:141 +msgid "Please specify a valid month in YYYY-MM format." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:176 +msgid "Please specify a year." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:180 +msgid "Please specify a valid year in YYYY format." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:211 +msgid "Please specify the start date." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:215 +msgid "Please specify a valid start date in YYYY-MM-DD format." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:226 +msgid "Please specify the end date." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:229 +msgid "Please specify a valid end date in YYYY-MM-DD format." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:250 +msgid "This option is invalid. Please select a proper date range." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:319 +#: lib/perl5/Selima/List/Accounting/Transacts.pm:53 +msgid "" +"Add a new cash expense transaction, add a new cash income transaction or add a new " +"transfer transaction." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:339 +msgid "Report type:" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:343 +msgid "Cash book" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:347 +msgid "Cash book summary" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:351 +msgid "Ledger" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:355 +msgid "Ledger summary" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:359 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:31 +msgid "Journal" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:363 +msgid "Trial balance" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:367 +msgid "Income statement" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:371 +msgid "Balance sheet" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:408 +msgid "Search the accounting records:" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:442 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:297 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:253 +msgid "Query" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:443 +msgid "Date range:" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:444 +msgid "By month:" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:445 +msgid "By year:" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:446 +msgid "Specified date range:" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:447 +msgid "All" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:448 +msgid "From" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:449 +msgid "to" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:563 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:332 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:326 +msgid "From [_1] to [_2]." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:24 +msgid "Select an Accounting Subject" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:25 +msgid "Manage Accounting Subjects" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:30 +msgid "Parent subject" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:31 +msgid "Code" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:39 +msgid "Add a new accounting subject." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:45 +msgid "Search for an accounting subject:" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:62 +msgid "Your query found [*,_1,accounting subject]." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:65 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:355 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:349 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:251 +msgid "[*,_1,accounting subject]." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:71 +msgid "Your query found [*,_1,accounting subject], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:75 +msgid "[*,_1,accounting subject], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:26 +msgid "Select an Accounting Transaction" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:27 +msgid "Manage Accounting Transactions" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:32 +msgid "Number" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:33 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:42 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:40 +msgid "Note" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:66 +msgid "Search for an accounting transaction:" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:83 +msgid "Your query found [*,_1,accounting transaction]." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:86 +msgid "[*,_1,accounting transaction]." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:92 +msgid "" +"Your query found [*,_1,accounting transaction], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:96 +msgid "[*,_1,accounting transaction], listing [#,_2] to [#,_3]." +msgstr "" + +#: lib/perl5/Selima/List/Guestbook/Public.pm:196 +msgid "~[Edit~]" +msgstr "" + +#: lib/perl5/Selima/List/Guestbook/Public.pm:205 +msgid "The message entry seperator" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:29 +msgid "Balance Sheet" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:40 +msgid "Assets accounting subject" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:41 +msgid "Assets amount" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:42 +msgid "Liabilities accounting subject" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:43 +msgid "Liabilities amount" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:289 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:379 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:283 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:273 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:351 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:204 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:421 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:366 +msgid "Download the data as a CSV file." +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:45 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:150 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:339 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:40 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:383 +msgid "current assets and liabilities" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:48 +msgid "Cash book - [_1]" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:29 +msgid "Income Statement" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:187 +msgid "Gross income" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:189 +msgid "Operating income" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:191 +msgid "Before tax income" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:193 +msgid "After tax income" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:41 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:39 +msgid "Transaction Number" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:127 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:138 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:151 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:162 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:126 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:140 +msgid "Brought forward" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:46 +msgid "Ledger - [_1]" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:26 +msgid "Search the Accounting Records" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:28 +msgid "Search Result" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:28 +msgid "Trial Balance" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:43 +msgid "Cash Book Summary - [_1]" +msgstr "" + +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:41 +msgid "Ledger Summary - [_1]" +msgstr "" diff --git a/po/selima/zh_CN.gmo b/po/selima/zh_CN.gmo new file mode 100644 index 0000000..a235308 Binary files /dev/null and b/po/selima/zh_CN.gmo differ diff --git a/po/selima/zh_CN.po b/po/selima/zh_CN.po new file mode 100644 index 0000000..d913a57 --- /dev/null +++ b/po/selima/zh_CN.po @@ -0,0 +1,3376 @@ +# Simplified Chinese PO file for the Selima common subroutines. +# Copyright (C) 2003-2018 imacat +# This file is distributed under the same license as the selima package. +# imacat , 2003-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: selima 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-02-17 11:07+0800\n" +"PO-Revision-Date: 2018-11-02 01:04+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: lib/perl5/Selima/Checker.pm:130 +msgid "Please select a user." +msgstr "请选择用户。" + +#: lib/perl5/Selima/Checker.pm:133 +msgid "This user does not exist anymore. Please select another one." +msgstr "查无此人,请重新选择。" + +#: lib/perl5/Selima/Checker.pm:151 +msgid "Please select a group." +msgstr "请选择群组。" + +#: lib/perl5/Selima/Checker.pm:154 +msgid "This group does not exist anymore. Please select another one." +msgstr "查无此群组,请重新选择。" + +#: lib/perl5/Selima/Checker.pm:172 +msgid "Please fill in the script." +msgstr "请填上程序文件名。" + +#: lib/perl5/Selima/Checker.pm:175 +msgid "This script is too long. (Max. length [#,_1])" +msgstr "程序文件名太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:179 +msgid "This script is not a valid script. Please specify another one." +msgstr "查无此程序,请重新设置运行的程序。" + +#: lib/perl5/Selima/Checker.pm:197 +msgid "Please fill in the author." +msgstr "请填上作者。" + +#: lib/perl5/Selima/Checker.pm:200 +msgid "This author is too long. (Max. length [#,_1])" +msgstr "作者太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:220 lib/perl5/Selima/Form.pm:1700 +msgid "Fill in the content here." +msgstr "请填上内文。" + +#: lib/perl5/Selima/Checker.pm:221 +msgid "Please fill in the content." +msgstr "请填上内文。" + +#: lib/perl5/Selima/Checker.pm:224 +msgid "This content is too long. (Max. length [#,_1])" +msgstr "内文太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:243 +msgid "Please fill in a date." +msgstr "请填上日期。" + +#: lib/perl5/Selima/Checker.pm:246 lib/perl5/Selima/Checker.pm:249 +#: lib/perl5/Selima/Checker.pm:251 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期请以 YYYY-MM-DD 格式正确填写。" + +#: lib/perl5/Selima/Checker.pm:270 lib/perl5/Selima/Form.pm:1756 +msgid "Fill in the description here." +msgstr "请填上说明。" + +#: lib/perl5/Selima/Checker.pm:271 +msgid "Please fill in the description." +msgstr "请填上说明。" + +#: lib/perl5/Selima/Checker.pm:274 +msgid "This description is too long. (Max. length [#,_1])" +msgstr "说明太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:293 +msgid "Please fill in the ID." +msgstr "请填上代号。" + +#: lib/perl5/Selima/Checker.pm:296 +msgid "This ID. is too long. (Max. length [#,_1])" +msgstr "代号太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:299 +msgid "This ID. is too short. (Max. length [#,_1])" +msgstr "代号太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:303 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "代号限用小写英文本母、数字和底线。" + +#: lib/perl5/Selima/Checker.pm:321 +msgid "Please fill in the keywords." +msgstr "请填上关键字。" + +#: lib/perl5/Selima/Checker.pm:324 +msgid "This keyword list is too long. (Max. length [#,_1])" +msgstr "关键字太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:344 lib/perl5/Selima/Form.pm:1830 +msgid "Fill in the message here." +msgstr "请填上留言。" + +#: lib/perl5/Selima/Checker.pm:345 +msgid "Please fill in the message." +msgstr "请填上留言。" + +#: lib/perl5/Selima/Checker.pm:348 +msgid "This message is too long. (Max. length [#,_1])" +msgstr "留言太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:367 +msgid "Please fill in the order." +msgstr "请填上先后次序。" + +#: lib/perl5/Selima/Checker.pm:370 +msgid "This order is too long. (Max. length [#,_1])" +msgstr "次序太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:374 +msgid "Please fill in a positive integer order." +msgstr "次序请填正整数。" + +#: lib/perl5/Selima/Checker.pm:400 +msgid "Please fill in the page path." +msgstr "请填上网页路径。" + +#: lib/perl5/Selima/Checker.pm:403 +msgid "This page path is too long. (Max. length [#,_1])" +msgstr "网页路径太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:414 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "已有同一网页,请勿重复建档。" + +#: lib/perl5/Selima/Checker.pm:417 +msgid "Please fill in an absolute page path." +msgstr "网页路径请填上绝对路径。" + +#: lib/perl5/Selima/Checker.pm:420 +msgid "Please fill in a valid page path." +msgstr "网页路径请填上正确路径。" + +#: lib/perl5/Selima/Checker.pm:423 +msgid "You cannot overwrite the cover home page." +msgstr "不可以程序设置首页。" + +#: lib/perl5/Selima/Checker.pm:426 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "网页路径限填 HTML 地址( *.html )。" + +#: lib/perl5/Selima/Checker.pm:454 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "查无此图,请重新上传图档。" + +#: lib/perl5/Selima/Checker.pm:458 +msgid "" +"This picture is too large. Please upload another one. (Max. length [#,_1])" +msgstr "图档太大,请重新上传图档(最大 [#,_1] )。" + +#: lib/perl5/Selima/Checker.pm:482 +msgid "Please fill in the picture caption." +msgstr "请填上图片标题。" + +#: lib/perl5/Selima/Checker.pm:485 +msgid "This picture caption is too long. (Max. length [#,_1])" +msgstr "图片标题太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:509 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "图片位置无效。请由表上选择适当的图片位置。" + +#: lib/perl5/Selima/Checker.pm:527 +msgid "Please fill in the title." +msgstr "请填上标题。" + +#: lib/perl5/Selima/Checker.pm:530 +msgid "This title is too long. (Max. length [#,_1])" +msgstr "标题太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:549 +msgid "Please fill in the English title." +msgstr "请填上英文标题。" + +#: lib/perl5/Selima/Checker.pm:552 +msgid "This English title is too long. (Max. length [#,_1])" +msgstr "英文标题太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:699 lib/perl5/Selima/Preview.pm:38 +msgid "The following field was not received: \"[_1]\"." +msgstr "程序没有收到下列字段:「 [_1] 」" + +#: lib/perl5/Selima/ChkWrite.pm:35 +msgid "[_1]: It is not a file." +msgstr "[_1]: 这不是文件。" + +#: lib/perl5/Selima/ChkWrite.pm:39 +msgid "[_1]: You have no permission to overwrite this file." +msgstr "[_1]: 存盘的权限不足,无法存盘。" + +#: lib/perl5/Selima/ChkWrite.pm:50 +msgid "[_1]: You cannot create anything under the root directory." +msgstr "[_1]: 不可在根目录下建档。" + +#: lib/perl5/Selima/ChkWrite.pm:54 +msgid "" +"[_1]: One of the parents of this file ([_2]) is not a directory. You cannot " +"create any new file inside." +msgstr "[_1]: 路径中间有一部份( [_2] )不是目录,无法往下建档。" + +#: lib/perl5/Selima/ChkWrite.pm:58 +msgid "[_1]: You have no permission to create any file under [_2]." +msgstr "[_1]: 权限不足,无法在 [_2] 建档。" + +#: lib/perl5/Selima/CommText.pm:24 +msgid "(not set)" +msgstr "(未设置)" + +#: lib/perl5/Selima/CommText.pm:25 +msgid "(none)" +msgstr "(无)" + +#: lib/perl5/Selima/CommText.pm:26 +msgid "(N/A)" +msgstr "(不可考)" + +#: lib/perl5/Selima/Format.pm:48 +msgid "[#,_1] bytes" +msgstr "[#,_1] 字节" + +#: lib/perl5/Selima/Form.pm:116 +msgid "Delete it." +msgstr "删掉" + +#: lib/perl5/Selima/Form.pm:119 +msgid "*" +msgstr "" + +#: lib/perl5/Selima/Form.pm:140 +msgid "This table provides you a form to add a new data record." +msgstr "本表提供建新数据的表单。" + +#: lib/perl5/Selima/Form.pm:143 +msgid "This table provides you a form to update a current data record." +msgstr "本表提供异动数据的表单。" + +#: lib/perl5/Selima/Form.pm:146 +msgid "This table provides you a form to delete a data record." +msgstr "本表提供删除数据的表单。" + +#: lib/perl5/Selima/Form.pm:185 +msgid "Add a New Data Record" +msgstr "建新数据" + +#: lib/perl5/Selima/Form.pm:188 +msgid "Update a Current Data Record" +msgstr "异动数据" + +#: lib/perl5/Selima/Form.pm:191 +msgid "Delete a Data Record" +msgstr "删除数据" + +#: lib/perl5/Selima/Form.pm:212 +msgid "Preview it." +msgstr "预览。" + +#: lib/perl5/Selima/Form.pm:271 lib/perl5/Selima/Form.pm:284 +msgid "Convert from Simplified Chinese" +msgstr "转自简体中文" + +#: lib/perl5/Selima/Form.pm:273 lib/perl5/Selima/Form.pm:286 +msgid "Convert from Traditional Chinese" +msgstr "转自正体中文" + +#: lib/perl5/Selima/Form.pm:447 lib/perl5/Selima/Form.pm:451 +#: lib/perl5/Selima/Form.pm:559 lib/perl5/Selima/Form.pm:563 +#: lib/perl5/Selima/Form/AcctTrx.pm:89 lib/perl5/Selima/Form/AcctTrx.pm:94 +msgid "Submit" +msgstr "发送" + +#: lib/perl5/Selima/Form.pm:448 lib/perl5/Selima/Form.pm:452 +#: lib/perl5/Selima/Form.pm:560 lib/perl5/Selima/Form.pm:564 +#: lib/perl5/Selima/Form/AcctTrx.pm:90 lib/perl5/Selima/Form/AcctTrx.pm:95 +msgid "Save" +msgstr "存盘" + +#: lib/perl5/Selima/Form.pm:571 lib/perl5/Selima/Form.pm:1139 +#: lib/perl5/Selima/Form.pm:1229 lib/perl5/Selima/List.pm:1390 +msgid "Delete" +msgstr "删除" + +#: lib/perl5/Selima/Form.pm:572 lib/perl5/Selima/Form/Rebuild.pm:42 +msgid "Cancel" +msgstr "取消" + +#: lib/perl5/Selima/Form.pm:577 +msgid "" +"Are you sure you want to delete this data? You cannot recover it if you do " +"so." +msgstr "妳真的要删掉吗?数据删掉就救不回来了。" + +#: lib/perl5/Selima/Form.pm:855 lib/perl5/Selima/Form.pm:951 +#: lib/perl5/Selima/Form.pm:1013 lib/perl5/Selima/Form.pm:1097 +#: lib/perl5/Selima/Form.pm:1175 lib/perl5/Selima/Form.pm:1282 +#: lib/perl5/Selima/Form.pm:1362 lib/perl5/Selima/Form.pm:1435 +#: lib/perl5/Selima/Form.pm:1528 lib/perl5/Selima/Form.pm:1620 +#: lib/perl5/Selima/Form.pm:2057 lib/perl5/Selima/Form/AcctRec.pm:122 +#: lib/perl5/Selima/Form/AcctTrx.pm:519 lib/perl5/Selima/Form/Group.pm:165 +#: lib/perl5/Selima/Form/Group.pm:294 lib/perl5/Selima/Form/Group.pm:421 +#: lib/perl5/Selima/Form/Link.pm:138 lib/perl5/Selima/Form/User.pm:291 +msgid "Original:" +msgstr "原:" + +#: lib/perl5/Selima/Form.pm:856 lib/perl5/Selima/Form.pm:952 +#: lib/perl5/Selima/Form.pm:1014 lib/perl5/Selima/Form.pm:1098 +#: lib/perl5/Selima/Form.pm:1176 lib/perl5/Selima/Form.pm:1283 +#: lib/perl5/Selima/Form.pm:1363 lib/perl5/Selima/Form.pm:1436 +#: lib/perl5/Selima/Form.pm:1529 lib/perl5/Selima/Form.pm:1621 +#: lib/perl5/Selima/Form.pm:2058 lib/perl5/Selima/Form/AcctRec.pm:123 +#: lib/perl5/Selima/Form/AcctTrx.pm:520 lib/perl5/Selima/Form/Group.pm:166 +#: lib/perl5/Selima/Form/Group.pm:295 lib/perl5/Selima/Form/Group.pm:422 +#: lib/perl5/Selima/Form/Link.pm:139 lib/perl5/Selima/Form/User.pm:292 +msgid "New:" +msgstr "新:" + +#: lib/perl5/Selima/Form.pm:860 lib/perl5/Selima/Form.pm:1018 +#: lib/perl5/Selima/Form.pm:1625 lib/perl5/Selima/Form.pm:2122 +msgid "Source:" +msgstr "原文:" + +#: lib/perl5/Selima/Form.pm:1138 lib/perl5/Selima/Form.pm:1228 +#: lib/perl5/Selima/Form/AcctRec.pm:100 lib/perl5/Selima/Form/AcctTrx.pm:214 +msgid "Choose" +msgstr "挑选" + +#: lib/perl5/Selima/Form.pm:1689 +msgid "Address:" +msgstr "地址:" + +#: lib/perl5/Selima/Form.pm:1694 +msgid "Author:" +msgstr "作者:" + +#: lib/perl5/Selima/Form.pm:1699 +msgid "Content:" +msgstr "内文:" + +#: lib/perl5/Selima/Form.pm:1713 +msgid "Current Website:" +msgstr "目前网站:" + +#: lib/perl5/Selima/Form.pm:1718 +msgid "Enter your website URL here." +msgstr "请填上妳的网站网址。" + +#: lib/perl5/Selima/Form.pm:1734 +msgid "Created:" +msgstr "建档日期:" + +#: lib/perl5/Selima/Form.pm:1739 +msgid "Created by:" +msgstr "建档者:" + +#: lib/perl5/Selima/Form.pm:1744 lib/perl5/Selima/List.pm:167 +#: lib/perl5/Selima/Form/User.pm:160 lib/perl5/Selima/Form/User.pm:163 +msgid "Disabled?" +msgstr "停用?" + +#: lib/perl5/Selima/Form.pm:1745 lib/perl5/Selima/Form/User.pm:161 +#: lib/perl5/Selima/Form/User.pm:164 +msgid "Disabled" +msgstr "停用" + +#: lib/perl5/Selima/Form.pm:1745 lib/perl5/Selima/Form/User.pm:161 +#: lib/perl5/Selima/Form/User.pm:164 +msgid "Enabled" +msgstr "未停用" + +#: lib/perl5/Selima/Form.pm:1745 +msgid "Disable it." +msgstr "停用。" + +#: lib/perl5/Selima/Form.pm:1750 +msgid "Date:" +msgstr "日期:" + +#: lib/perl5/Selima/Form.pm:1755 lib/perl5/Selima/Form/Group.pm:97 +msgid "Description:" +msgstr "说明:" + +#: lib/perl5/Selima/Form.pm:1761 +msgid "E-mail:" +msgstr "E-mail :" + +#: lib/perl5/Selima/Form.pm:1766 +msgid "Fax.:" +msgstr "传真:" + +#: lib/perl5/Selima/Form.pm:1771 +msgid "Group:" +msgstr "群组:" + +#: lib/perl5/Selima/Form.pm:1776 lib/perl5/Selima/Form/Guestbook.pm:82 +#: lib/perl5/Selima/Form/LinkCat.pm:88 lib/perl5/Selima/Form/Link.pm:87 +#: lib/perl5/Selima/Form/Page.pm:81 +msgid "Hide?" +msgstr "隐藏?" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Hide it" +msgstr "隐藏起来" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Show it" +msgstr "秀出来" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Hide it currently." +msgstr "暂勿秀出。" + +#: lib/perl5/Selima/Form.pm:1782 lib/perl5/Selima/List.pm:171 +msgid "HTML?" +msgstr "HTML ?" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "HTML" +msgstr "HTML" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "Plain text" +msgstr "纯文本" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "The submitted content is HTML." +msgstr "以上内文为 HTML 格式。" + +#: lib/perl5/Selima/Form.pm:1788 +msgid "Host:" +msgstr "主机:" + +#: lib/perl5/Selima/Form.pm:1793 lib/perl5/Selima/Form/LinkCat.pm:95 +msgid "ID.:" +msgstr "代号:" + +#: lib/perl5/Selima/Form.pm:1798 +msgid "Identity:" +msgstr "身份:" + +#: lib/perl5/Selima/Form.pm:1803 +msgid "Introduction:" +msgstr "简介:" + +#: lib/perl5/Selima/Form.pm:1804 +msgid "Fill in the introduction here." +msgstr "请填上简介。" + +#: lib/perl5/Selima/Form.pm:1809 +msgid "IP:" +msgstr "IP :" + +#: lib/perl5/Selima/Form.pm:1814 +msgid "Keywords:" +msgstr "关键字:" + +#: lib/perl5/Selima/Form.pm:1819 +msgid "Language:" +msgstr "语言:" + +#: lib/perl5/Selima/Form.pm:1824 +msgid "Location:" +msgstr "所在地:" + +#: lib/perl5/Selima/Form.pm:1829 +msgid "Message:" +msgstr "留言:" + +#: lib/perl5/Selima/Form.pm:1835 +msgid "Name:" +msgstr "名字:" + +#: lib/perl5/Selima/Form.pm:1847 lib/perl5/Selima/Form/AcctTrx.pm:319 +msgid "Order:" +msgstr "次序:" + +#: lib/perl5/Selima/Form.pm:1853 +msgid "Parent category:" +msgstr "大类:" + +#: lib/perl5/Selima/Form.pm:1854 lib/perl5/Selima/Form/AcctSubj.pm:94 +msgid "At the very top" +msgstr "最上层" + +#: lib/perl5/Selima/Form.pm:1866 lib/perl5/Selima/Form/User.pm:201 +msgid "Password:" +msgstr "密码:" + +#: lib/perl5/Selima/Form.pm:1867 +msgid "Confirm password:" +msgstr "确认密码:" + +#: lib/perl5/Selima/Form.pm:1978 +msgid "Page path:" +msgstr "网页路径:" + +#: lib/perl5/Selima/Form.pm:1992 +msgid "Picture:" +msgstr "图片:" + +#: lib/perl5/Selima/Form.pm:1993 +msgid "Pic. caption:" +msgstr "图片标题:" + +#: lib/perl5/Selima/Form.pm:1994 +msgid "Pic. position:" +msgstr "图片位置:" + +#: lib/perl5/Selima/Form.pm:1997 +msgid "Set the picture" +msgstr "设置图片" + +#: lib/perl5/Selima/Form.pm:1998 +msgid "Delete this picture" +msgstr "删掉图片" + +#: lib/perl5/Selima/Form.pm:2003 lib/perl5/Selima/Form.pm:2178 +msgid "Picture preview" +msgstr "图片预览" + +#: lib/perl5/Selima/Form.pm:2059 +msgid "Original picture preview" +msgstr "原图片预览" + +#: lib/perl5/Selima/Form.pm:2060 +msgid "New picture preview" +msgstr "新图片预览" + +#: lib/perl5/Selima/Form.pm:2078 +msgid "Please upload a new picture from [_1]." +msgstr "请由[_1]建新图片。" + +#: lib/perl5/Selima/Form.pm:2228 +msgid "[numerate,_1,Subcategory,Subcategories]:" +msgstr "子类:" + +#: lib/perl5/Selima/Form.pm:2256 +msgid "Script:" +msgstr "程序:" + +#: lib/perl5/Selima/Form.pm:2261 +msgid "S/N:" +msgstr "编号:" + +#: lib/perl5/Selima/Form.pm:2266 +msgid "Tel.:" +msgstr "电话:" + +#: lib/perl5/Selima/Form.pm:2271 +msgid "Title:" +msgstr "标题:" + +#: lib/perl5/Selima/Form.pm:2276 +msgid "English title:" +msgstr "英文标题:" + +#: lib/perl5/Selima/Form.pm:2281 +msgid "Updated:" +msgstr "维护日期:" + +#: lib/perl5/Selima/Form.pm:2286 +msgid "Updated by:" +msgstr "维护者:" + +#: lib/perl5/Selima/Form.pm:2291 +msgid "URL:" +msgstr "网址:" + +#: lib/perl5/Selima/Form.pm:2296 lib/perl5/Selima/Form/UserPref.pm:94 +msgid "Value:" +msgstr "值:" + +#: lib/perl5/Selima/Form.pm:2301 +msgid "Visited:" +msgstr "上站日期:" + +#: lib/perl5/Selima/Form.pm:2306 +msgid "Visits:" +msgstr "上站次数:" + +#: lib/perl5/Selima/Init.pm:216 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" +"抱歉,我们不欢迎加装 FunWebProduct 插件(如 Smiley Central 、 PopSwatter 、 " +"Spin4Dough 、 My Mail Signature 、 My Mail Stationery 、 My Mail Stamp 、 " +"Cursor Mania ……等等)的浏览器。 FunWebProduct 会重抓你看过的每一页网页,造" +"成网站负荷加倍,甚至当机。请先移除 FunWebProduct ,再上来浏览。" + +#: lib/perl5/Selima/Links.pm:242 +msgid "Related Links" +msgstr "相关网站链接" + +#: lib/perl5/Selima/List.pm:109 +msgid "Select" +msgstr "选择" + +#: lib/perl5/Selima/List.pm:112 +msgid "Select A Data Record" +msgstr "选择数据" + +#: lib/perl5/Selima/List.pm:114 +msgid "Edit" +msgstr "设置" + +#: lib/perl5/Selima/List.pm:116 +msgid "Manage Data" +msgstr "管理数据" + +#: lib/perl5/Selima/List.pm:158 +msgid "S/N" +msgstr "编号" + +#: lib/perl5/Selima/List.pm:159 +msgid "Created" +msgstr "建档日期" + +#: lib/perl5/Selima/List.pm:160 +msgid "Created by" +msgstr "建档者" + +#: lib/perl5/Selima/List.pm:161 +msgid "Updated" +msgstr "维护日期" + +#: lib/perl5/Selima/List.pm:162 +msgid "Updated by" +msgstr "维护者" + +#: lib/perl5/Selima/List.pm:164 +msgid "Content" +msgstr "内文" + +#: lib/perl5/Selima/List.pm:165 +msgid "Category" +msgstr "分类" + +#: lib/perl5/Selima/List.pm:166 +msgid "Date" +msgstr "日期" + +#: lib/perl5/Selima/List.pm:168 lib/perl5/Selima/List/Groups.pm:30 +msgid "Description" +msgstr "说明" + +#: lib/perl5/Selima/List.pm:169 lib/perl5/Selima/List/Guestbook/Public.pm:138 +msgid "E-mail" +msgstr "E-mail" + +#: lib/perl5/Selima/List.pm:170 +msgid "Hidden?" +msgstr "隐藏?" + +#: lib/perl5/Selima/List.pm:172 +msgid "ID." +msgstr "代号" + +#: lib/perl5/Selima/List.pm:173 +msgid "Keywords" +msgstr "关键字" + +#: lib/perl5/Selima/List.pm:174 +msgid "Name" +msgstr "名字" + +#: lib/perl5/Selima/List.pm:175 +msgid "Order" +msgstr "次序" + +#: lib/perl5/Selima/List.pm:176 lib/perl5/Selima/List/Pages.pm:32 +msgid "Page path" +msgstr "网页路径" + +#: lib/perl5/Selima/List.pm:177 +msgid "Picture" +msgstr "图片" + +#: lib/perl5/Selima/List.pm:178 +msgid "Pic. ratio" +msgstr "图片比例" + +#: lib/perl5/Selima/List.pm:179 +msgid "Pic. caption" +msgstr "图片标题" + +#: lib/perl5/Selima/List.pm:180 +msgid "Pic. position" +msgstr "图片位置" + +#: lib/perl5/Selima/List.pm:181 +msgid "Title" +msgstr "标题" + +#: lib/perl5/Selima/List.pm:182 +msgid "English title" +msgstr "英文标题" + +#: lib/perl5/Selima/List.pm:183 +msgid "URL." +msgstr "网址" + +#: lib/perl5/Selima/List.pm:184 +msgid "Status (slow)" +msgstr "状态(慢)" + +#: lib/perl5/Selima/List.pm:423 +msgid "Nothing found. Please try another query." +msgstr "查无相符的数据,请重新搜索。" + +#: lib/perl5/Selima/List.pm:426 +msgid "The database is empty." +msgstr "现无任何数据。" + +#: lib/perl5/Selima/List.pm:432 +msgid "Your query found [*,_1,record]." +msgstr "共 [#,_1] 笔相符的数据。" + +#: lib/perl5/Selima/List.pm:435 +msgid "[*,_1,record]." +msgstr "共 [#,_1] 笔数据。" + +#: lib/perl5/Selima/List.pm:441 +msgid "Your query found [*,_1,record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的数据,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List.pm:445 +msgid "[*,_1,record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔数据,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List.pm:456 +msgid "First" +msgstr "第一页" + +#: lib/perl5/Selima/List.pm:457 +msgid "Previous" +msgstr "前一页" + +#: lib/perl5/Selima/List.pm:458 +msgid "Next" +msgstr "下一页" + +#: lib/perl5/Selima/List.pm:459 +msgid "Last" +msgstr "最末页" + +#: lib/perl5/Selima/List.pm:502 +msgid "Picture unavailable" +msgstr "图片无法显示" + +#: lib/perl5/Selima/List.pm:530 +msgid "Page number ([_1]) invalid. Please specify a valid page number." +msgstr "页数([_1])无效,请设成有效的数字。" + +#: lib/perl5/Selima/List.pm:536 +msgid "" +"Page number ([#,_1]) out of range. Please specify between 1 and [#,_2]." +msgstr "页数([#,_1])超出范围,请设在 1 到 [#,_2] 之间。" + +#: lib/perl5/Selima/List.pm:613 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:61 +msgid "Please fill in your query." +msgstr "请填上查找的内容。" + +#: lib/perl5/Selima/List.pm:749 lib/perl5/Selima/List.pm:759 +msgid "You cannot sort by \"[_1]\"." +msgstr "无法以「 [_1] 」排序。" + +#: lib/perl5/Selima/List.pm:1082 +#: lib/perl5/Selima/List/Accounting/Reports.pm:412 +msgid "Search" +msgstr "搜索" + +#: lib/perl5/Selima/List.pm:1181 +msgid "Index" +msgstr "目录" + +#: lib/perl5/Selima/List.pm:1319 +msgid "Page:" +msgstr "页:" + +#: lib/perl5/Selima/List.pm:1320 lib/perl5/Selima/List.pm:1392 +#: lib/perl5/Selima/List.pm:1449 +msgid "View" +msgstr "浏览" + +#: lib/perl5/Selima/List.pm:1364 lib/perl5/Selima/List.pm:1476 +msgid "Delete the selected items." +msgstr "删除勾选的项目。" + +#: lib/perl5/Selima/List.pm:1389 +msgid "No." +msgstr "编号" + +#: lib/perl5/Selima/List.pm:1500 +#: lib/perl5/Selima/List/Accounting/Reports.pm:587 +msgid "Set" +msgstr "设置" + +#: lib/perl5/Selima/List.pm:1521 +#: lib/perl5/Selima/List/Accounting/Reports.pm:604 +msgid "Rows per page:" +msgstr "每页显示笔数:" + +#: lib/perl5/Selima/List.pm:1529 +msgid "Display columns:" +msgstr "显示字段:" + +#: lib/perl5/Selima/List.pm:1564 +msgid "Malformed" +msgstr "格式错乱" + +#: lib/perl5/Selima/List.pm:1598 +msgid "OK" +msgstr "好" + +#: lib/perl5/Selima/List.pm:1598 +msgid "Unreachable" +msgstr "连不上" + +#: lib/perl5/Selima/LnInfo.pm:49 +msgid "Traditional Chinese" +msgstr "正体中文" + +#: lib/perl5/Selima/LnInfo.pm:59 +msgid "Simplified Chinese" +msgstr "简体中文" + +#: lib/perl5/Selima/LnInfo.pm:69 +msgid "English" +msgstr "英文" + +#: lib/perl5/Selima/LnInfo.pm:79 +msgid "Japanese" +msgstr "日文" + +#: lib/perl5/Selima/LnInfo.pm:89 +msgid "German" +msgstr "德文" + +#: lib/perl5/Selima/LnInfo.pm:242 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "切换到本页的%s版。" + +#: lib/perl5/Selima/PageFunc.pm:221 +msgid "Web pages" +msgstr "网页" + +#: lib/perl5/Selima/PageFunc.pm:222 +msgid "News" +msgstr "新闻" + +#: lib/perl5/Selima/PageFunc.pm:223 +msgid "Related links" +msgstr "相关链接" + +#: lib/perl5/Selima/PageFunc.pm:224 +msgid "Home page" +msgstr "首页" + +#: lib/perl5/Selima/PageFunc.pm:225 +msgid "Whole web site" +msgstr "整个网站" + +#: lib/perl5/Selima/Picture.pm:49 +msgid "Left-aligned" +msgstr "靠左" + +#: lib/perl5/Selima/Picture.pm:50 +msgid "Right-aligned" +msgstr "靠右" + +#: lib/perl5/Selima/Picture.pm:87 +#, c-format +msgid "Width: [#,_1], height: [#,_2], ratio: [sprintf,%0.2f,_3]" +msgstr "宽: [#,_1] ,高: [#,_2] ,比例: [sprintf,%0.2f,_3]" + +#: lib/perl5/Selima/Picture.pm:113 +msgid "Please specify a numeric ratio." +msgstr "比例请设置数字。" + +#: lib/perl5/Selima/Picture.pm:116 +msgid "Please specify a positive ratio." +msgstr "比例请设置正数。" + +#: lib/perl5/Selima/Picture.pm:118 +#, c-format +msgid "Please specify a ratio less than or equal to [sprintf,%0.2f,_1]." +msgstr "比例请勿大于 [sprintf,%0.2f,_1] 。" + +#: lib/perl5/Selima/Picture.pm:122 +msgid "This image is too large to display." +msgstr "图片太大,无法显示。" + +#: lib/perl5/Selima/Preview.pm:53 lib/perl5/Selima/Preview.pm:115 +msgid "Unknown preview source: \"[_1]\"." +msgstr "预览数据源不明:「 [_1] 」。" + +#: lib/perl5/Selima/Preview.pm:69 +msgid "Unknown preview form: \"[_1]\"." +msgstr "预览表格不明: [_1] 。" + +#: lib/perl5/Selima/Preview.pm:126 +msgid "Preview" +msgstr "预览" + +#: lib/perl5/Selima/Preview.pm:127 +msgid "Finish preview and return." +msgstr "结束预览回前页。" + +#: lib/perl5/Selima/Processor.pm:203 +msgid "This record was not modified." +msgstr "数据未异动。" + +#: lib/perl5/Selima/Processor.pm:207 +msgid "This record has been successfully added." +msgstr "数据建好了。" + +#: lib/perl5/Selima/Processor.pm:211 +msgid "This record has been successfully updated." +msgstr "数据存好了。" + +#: lib/perl5/Selima/Processor.pm:215 +msgid "This record has been successfully deleted." +msgstr "数据删掉了。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:41 +msgid "Please select a accounting transaction." +msgstr "请选择会计传票。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:44 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "查无此会计传票,请重新选择。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:62 +msgid "This option is invalid. Please select a proper type." +msgstr "类型选项无效,请由表上选择适当的类型。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:83 +msgid "Please select a accounting subject." +msgstr "请选择会计科目。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:86 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "查无此会计科目,请重新选择。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:93 +msgid "" +"Only a last-level accounting subject is allowed for an accounting subject." +msgstr "限选最下层的会计科目。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:113 +msgid "This summary is too long. (Max. length [#,_1])" +msgstr "摘要太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/AcctRec.pm:137 +msgid "Please fill in the amount." +msgstr "请填上金额。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:140 +msgid "This amount is too long. (Max. length [#,_1])" +msgstr "金额太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/AcctRec.pm:144 +msgid "Please fill in a positive integer amount." +msgstr "金额请填正整数。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:39 +msgid "Please fill in the code." +msgstr "请填上代码。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:42 +msgid "This code is too long. (Max. length [#,_1])" +msgstr "代码太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:46 +msgid "Only numbers are allowed for the code." +msgstr "代码限用数字。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:56 +msgid "" +"This accounting subject already exists. You cannot create a duplicated one." +msgstr "已有该会计科目,请勿重复建档。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:65 +msgid "" +"Accounting subject [_1] does not exist. You cannot create a subject under " +"that." +msgstr "查无会计科目 [_1] ,请勿创建其下的科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:80 +#: lib/perl5/Selima/Checker/AcctSubj.pm:101 +msgid "Please select a parent accounting subject." +msgstr "请选择所属的大会计科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:85 +msgid "" +"This option is invalid. Please select a proper parent accounting subject." +msgstr "大会计科目选项无效,请由表上选择适当的大会计科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:92 +msgid "" +"An accounting subject having its code with a single digit must not have a " +"parent." +msgstr "会计科目代码一位数时,不可设所属的大会计科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:104 +msgid "" +"An accounting subject cannot belong to itself. Please select another one." +msgstr "科目不可属于自己本身,请重新选择。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:108 +msgid "" +"This parent accounting subject does not exist anymore. Please select " +"another one." +msgstr "查无此大会计科目,请重新选择。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:113 +msgid "" +"The parent accounting subject of accounting subject [_1] must be of code " +"[_2], not [_3]." +msgstr "会计科目 [_1] 所属的大会计科目代码须为 [_2] ,不可为 [_3] 。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:122 +msgid "" +"An accounting subject having its code with more than one digit must have a " +"parent." +msgstr "会计科目代码两位数或以上时,须设所属的大会计科目。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:53 +msgid "This form suptype is invalid. Please specify a proper user." +msgstr "子表单无效,请设置适当的子表单。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:73 +msgid "Please fill in the credit side of the accounting transaction." +msgstr "请填上会计传票的贷方。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:75 +#: lib/perl5/Selima/Checker/AcctTrx.pm:98 +msgid "Please fill in the accounting transaction content." +msgstr "请填上会计传票内容。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:96 +msgid "Please fill in the debit side of the accounting transaction." +msgstr "请填上会计传票的借方。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:162 +msgid "" +"The total amounts of the debit side and the credit side are not balanced " +"(debit [_1], credit [_2]." +msgstr "借方和贷方总金额未平衡。(借方合计 [_1] ,贷方合计 [_2] )" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:182 +#: lib/perl5/Selima/Form/AcctTrx.pm:802 +msgid "Fill in the note here." +msgstr "请填上注记。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:185 +msgid "This note is too long. (Max. length [#,_1])" +msgstr "注记太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/GroupMem.pm:54 +msgid "Please select a different belonging group." +msgstr "隶属群组请选择别的群组。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:74 +#: lib/perl5/Selima/Checker/UserMem.pm:59 +msgid "Please select a member." +msgstr "请选择成员。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:77 +#: lib/perl5/Selima/Checker/UserMem.pm:62 +msgid "This member does not exist anymore. Please select another one." +msgstr "查无此成员,请重新选择。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:80 +msgid "Please select a different group member." +msgstr "群组成员请选择别的群组。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:103 +#: lib/perl5/Selima/Checker/UserMem.pm:83 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "已有同一成员关系,请勿重复建档。" + +#: lib/perl5/Selima/Checker/Group.pm:45 +msgid "Please fill in the group ID." +msgstr "请填上群组代号。" + +#: lib/perl5/Selima/Checker/Group.pm:48 +msgid "This group ID. is too long. (Max. length [#,_1])" +msgstr "群组代号太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Group.pm:51 +msgid "This group ID. is too short. (Min. length [#,_1])" +msgstr "群组代号太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/Group.pm:55 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "群组代号限用小写英文本母、数字和底线。" + +#: lib/perl5/Selima/Checker/Group.pm:65 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "已有同一群组,请勿重复建档。" + +#: lib/perl5/Selima/Checker/Group.pm:83 +msgid "Please fill in the privilege description." +msgstr "请填上权限说明。" + +#: lib/perl5/Selima/Checker/Group.pm:86 +msgid "This privilege description is too long. (Max. length [#,_1])" +msgstr "权限说明太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:38 +#: lib/perl5/Selima/Checker/Guestbook.pm:60 +msgid "This signature is too long. (Max. length [#,_1])" +msgstr "签名太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:57 +msgid "Please fill in the signature." +msgstr "请填上签名。" + +#: lib/perl5/Selima/Checker/Guestbook.pm:79 +msgid "This identity is too long. (Max. length [#,_1])" +msgstr "身份太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:98 +msgid "This location is too long. (Max. length [#,_1])" +msgstr "所在地太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:117 +#: lib/perl5/Selima/Checker/Link.pm:92 lib/perl5/Selima/Checker/User.pm:229 +msgid "This e-mail is too long. (Max. length [#,_1])" +msgstr "E-mail 信箱太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:136 +msgid "This website URL is too long. (Max. length [#,_1])" +msgstr "网站网址太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/LinkCat.pm:40 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "「 index 」为目录档 index.html 专用,代号不可设为「 index 」。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:56 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "已有同一分类,请勿重复建档。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:70 +#: lib/perl5/Selima/Checker/LinkCat.pm:85 +msgid "Please select a parent category." +msgstr "请选择所属的大类。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:75 +msgid "This option is invalid. Please select a proper parent category." +msgstr "大类选项无效,请由表上选择适当的大类。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:88 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "查无此大类,请重新选择。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:92 +msgid "A category cannot belong to itself. Please select another one." +msgstr "分类不可属于自己本身,请重新选择。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:99 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "分类不可属于自己的子类,请重新选择。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:56 lib/perl5/Selima/Checker/Link.pm:72 +msgid "Please select a category." +msgstr "请选择分类。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:59 lib/perl5/Selima/Checker/Link.pm:67 +msgid "This category does not exist anymore. Please select another one." +msgstr "查无此分类,请重新选择。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:77 +msgid "Please select a related link." +msgstr "请选择相关链接。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:80 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查无此相关链接,请重新选择。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:101 +msgid "" +"This categorization record already exists. You cannot create a duplicated " +"one." +msgstr "已有同一分类数据,请勿重复建档。" + +#: lib/perl5/Selima/Checker/Link.pm:44 +msgid "This address is too long. (Max. length [#,_1])" +msgstr "地址太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:64 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "分类重复,请勿重复设置。" + +#: lib/perl5/Selima/Checker/Link.pm:95 lib/perl5/Selima/Checker/User.pm:232 +msgid "This e-mail is too short. (Min. length [#,_1])" +msgstr "E-mail 信箱太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:99 lib/perl5/Selima/Checker/MailTo.pm:36 +#: lib/perl5/Selima/Checker/User.pm:236 +msgid "Please fill in a valid e-mail address." +msgstr "请填上正确的 E-mail 信箱。" + +#: lib/perl5/Selima/Checker/Link.pm:101 lib/perl5/Selima/Checker/MailTo.pm:38 +#: lib/perl5/Selima/Checker/User.pm:238 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "查无这个信箱的所属网域,请检查有没有拼错。" + +#: lib/perl5/Selima/Checker/Link.pm:122 +msgid "This facsimile number is too long. (Max. length [#,_1])" +msgstr "传真号码太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:143 +msgid "This link icon URL is too long. (Max. length [#,_1])" +msgstr "链接小图网址太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:147 +msgid "Please fill in a valid link icon URL." +msgstr "请填上正确的链接小图网址。" + +#: lib/perl5/Selima/Checker/Link.pm:150 +msgid "This link icon URL is not reachable. Check if there is any typo in it." +msgstr "链接小图连不上,请检查有没有拼错。" + +#: lib/perl5/Selima/Checker/Link.pm:171 +msgid "This telephone number is too long. (Max. length [#,_1])" +msgstr "电话号码太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:192 +msgid "This 2nd language title is too long. (Max. length [#,_1])" +msgstr "第二语言标题太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:211 +msgid "Please fill in the URL." +msgstr "请填上网址。" + +#: lib/perl5/Selima/Checker/Link.pm:214 +msgid "This URL is too long. (Max. length [#,_1])" +msgstr "网址太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:218 +msgid "Please fill in a valid URL." +msgstr "请填上正确的网址。" + +#: lib/perl5/Selima/Checker/Link.pm:228 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "已有同一相关链接,请勿重复建档。" + +#: lib/perl5/Selima/Checker/Link.pm:231 +msgid "This URL is not reachable. Check if there is any typo in it." +msgstr "这个网址连不上,请检查有没有拼错。" + +#: lib/perl5/Selima/Checker/ListPref.pm:42 +#: lib/perl5/Selima/Checker/UserPref.pm:88 +msgid "Please fill in the preference domain." +msgstr "请填上偏好的适用范围。" + +#: lib/perl5/Selima/Checker/ListPref.pm:45 +#: lib/perl5/Selima/Checker/UserPref.pm:91 +msgid "This preference domain is too long. (Max. length [#,_1])" +msgstr "偏好适用范围太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/ListPref.pm:90 +msgid "Please fill in the number of rows per page." +msgstr "请填上每页显示笔数。" + +#: lib/perl5/Selima/Checker/ListPref.pm:93 +msgid "Please fill in a positive integer number of rows per page." +msgstr "每页显示笔数请填正整数。" + +#: lib/perl5/Selima/Checker/ListPref.pm:100 +msgid "This number of rows per page is too long. (Max. length [#,_1])" +msgstr "每页显示笔数太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/LogIn.pm:63 +msgid "Please fill in your user ID." +msgstr "请填上妳的帐号。" + +#: lib/perl5/Selima/Checker/LogIn.pm:70 lib/perl5/Selima/Checker/LogIn.pm:76 +#: lib/perl5/Selima/Checker/LogIn.pm:91 lib/perl5/Selima/Checker/LogIn.pm:136 +#: lib/perl5/Selima/Checker/LogIn.pm:142 lib/perl5/Selima/Checker/LogIn.pm:151 +#: lib/perl5/Selima/Checker/LogIn.pm:178 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "登录错误,用户代号或密码有误。" + +#: lib/perl5/Selima/Checker/LogIn.pm:109 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "帐号停用中,请洽系统管理员。" + +#: lib/perl5/Selima/Checker/LogIn.pm:129 +msgid "Please fill in your password." +msgstr "请填上妳的密码。" + +#: lib/perl5/Selima/Checker/LogIn.pm:199 +msgid "You are not an administrator and cannot log into here." +msgstr "非管理员勿入。" + +#: lib/perl5/Selima/Checker/LogIn.pm:218 +msgid "You are an administrator and cannot log into here." +msgstr "管理人员勿入。" + +#: lib/perl5/Selima/Checker/MailTo.pm:29 lib/perl5/Selima/Checker/User.pm:226 +msgid "Please fill in the e-mail." +msgstr "请填上 E-mail 信箱。" + +#: lib/perl5/Selima/Checker/Rebuild.pm:28 +msgid "Please select the type." +msgstr "请选择类型。" + +#: lib/perl5/Selima/Checker/Rebuild.pm:31 +msgid "This type does not exist anymore. Please select another one." +msgstr "查无此类型,请重新选择。" + +#: lib/perl5/Selima/Checker/ScptPriv.pm:63 +msgid "" +"This script privilege record already exists. You cannot create a duplicated " +"one." +msgstr "已有同一程序权限数据,请勿重复建档。" + +#: lib/perl5/Selima/Checker/User.pm:85 +msgid "Please fill in the user ID." +msgstr "请填上帐号。" + +#: lib/perl5/Selima/Checker/User.pm:88 +msgid "This user ID. is too long. (Max. length [#,_1])" +msgstr "帐号太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:91 +msgid "This user ID. is too short. (Min. length [#,_1])" +msgstr "帐号太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:95 +msgid "" +"Only English letters, numbers, at-signs, dots, dashes and underscores are " +"allowed for the user ID." +msgstr "帐号限用英文本母、数字、 @ 号、点、横线和底线。" + +#: lib/perl5/Selima/Checker/User.pm:105 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "该用户已有帐号,请勿重复建档。" + +#: lib/perl5/Selima/Checker/User.pm:129 +msgid "Please fill in the password." +msgstr "请填上密码。" + +#: lib/perl5/Selima/Checker/User.pm:131 +msgid "Please confirm the password." +msgstr "请确认密码。" + +#: lib/perl5/Selima/Checker/User.pm:134 +msgid "This password is too long. (Max. length [#,_1])" +msgstr "密码太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:137 +msgid "This password is too short. (Min. length [#,_1])" +msgstr "密码太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:142 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "两次密码不合,请重新设置密码。" + +#: lib/perl5/Selima/Checker/User.pm:151 +msgid "This password is based on the user ID." +msgstr "密码不可由帐号组成。" + +#: lib/perl5/Selima/Checker/User.pm:166 +msgid "This password does not contain enough different characters." +msgstr "密码重复的字符太多。" + +#: lib/perl5/Selima/Checker/User.pm:170 +msgid "This password is too simplistic/systematic." +msgstr "密码结构太简单。" + +#: lib/perl5/Selima/Checker/User.pm:174 +msgid "This password is based on a dictionary word." +msgstr "密码不可由字典单字组成。" + +#: lib/perl5/Selima/Checker/User.pm:176 +msgid "This password is based on a (reversed) dictionary word." +msgstr "密码不可由倒过来的字典单字组成。" + +#: lib/perl5/Selima/Checker/User.pm:178 +msgid "This password is too simple." +msgstr "密码太简单。" + +#: lib/perl5/Selima/Checker/User.pm:183 +msgid "You cannot use a password that is based on your user ID." +msgstr "密码不可由帐号组成。" + +#: lib/perl5/Selima/Checker/User.pm:203 +msgid "Please fill in the name." +msgstr "请填上姓名。" + +#: lib/perl5/Selima/Checker/User.pm:206 +msgid "This name is too long. (Max. length [#,_1])" +msgstr "姓名太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:259 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "隶属群组重复,请勿重复设置。" + +#: lib/perl5/Selima/Checker/User.pm:271 +msgid "You cannot submit the super-user group along with other groups." +msgstr "总管理员群组不可与其它群组一起设置。" + +#: lib/perl5/Selima/Checker/User.pm:273 +msgid "You cannot set the administrators group." +msgstr "不可设置所有网站管理员群组" + +#: lib/perl5/Selima/Checker/User.pm:275 +msgid "You cannot set the all-users group." +msgstr "不可设置所有登录用户群组。" + +#: lib/perl5/Selima/Checker/UserPref.pm:50 +msgid "Please select the user." +msgstr "请选择用户。" + +#: lib/perl5/Selima/Checker/UserPref.pm:55 +msgid "This option is invalid. Please select a proper user." +msgstr "用户选项无效,请由表上选择适当的用户。" + +#: lib/perl5/Selima/Checker/UserPref.pm:73 +msgid "Please set the preference domain." +msgstr "请设置适用范围。" + +#: lib/perl5/Selima/Checker/UserPref.pm:78 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "适用范围选项无效,请设置适当的适用范围。" + +#: lib/perl5/Selima/Checker/UserPref.pm:111 +msgid "Please fill in the preference name." +msgstr "请填上偏好的名称。" + +#: lib/perl5/Selima/Checker/UserPref.pm:114 +msgid "This preference name is too long. (Max. length [#,_1])" +msgstr "偏好名称太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/UserPref.pm:133 +msgid "Please fill in the preference value." +msgstr "请填上偏好的值。" + +#: lib/perl5/Selima/Checker/UserPref.pm:136 +msgid "This preference value is too long. (Max. length [#,_1])" +msgstr "偏好值太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/UserPref.pm:167 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "已有同一用户偏好,请勿重复建档。" + +#: lib/perl5/Selima/Form/AcctRec.pm:33 +msgid "Delete this accounting record" +msgstr "删掉这笔会计分录" + +#: lib/perl5/Selima/Form/AcctRec.pm:38 +msgid "This table provides you a form to add a new accounting record." +msgstr "本表提供建新会计分录的表单。" + +#: lib/perl5/Selima/Form/AcctRec.pm:41 +msgid "This table provides you a form to edit a current accounting record." +msgstr "本表提供编辑会计分录的表单。" + +#: lib/perl5/Selima/Form/AcctRec.pm:44 +msgid "This table provides you a form to delete an accounting record." +msgstr "本表提供删除会计分录的表单。" + +#: lib/perl5/Selima/Form/AcctRec.pm:61 +msgid "Add a New Accounting Record" +msgstr "建新会计分录。" + +#: lib/perl5/Selima/Form/AcctRec.pm:64 +msgid "Edit a Current Accounting Record" +msgstr "编辑会计分录" + +#: lib/perl5/Selima/Form/AcctRec.pm:67 +msgid "Delete an Accounting Record" +msgstr "删除会计分录" + +#: lib/perl5/Selima/Form/AcctRec.pm:76 +msgid "Accounting transaction:" +msgstr "会计传票:" + +#: lib/perl5/Selima/Form/AcctRec.pm:85 lib/perl5/Selima/Form/AcctTrx.pm:334 +#: lib/perl5/Selima/List/Accounting/Reports.pm:75 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:233 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:226 +msgid "Debit" +msgstr "借方" + +#: lib/perl5/Selima/Form/AcctRec.pm:87 lib/perl5/Selima/Form/AcctTrx.pm:335 +#: lib/perl5/Selima/List/Accounting/Reports.pm:76 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:237 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:230 +msgid "Credit" +msgstr "贷方" + +#: lib/perl5/Selima/Form/AcctRec.pm:88 lib/perl5/Selima/Form/Rebuild.pm:52 +msgid "Type:" +msgstr "类型:" + +#: lib/perl5/Selima/Form/AcctRec.pm:99 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:284 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:268 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:328 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:284 +msgid "Accounting subject:" +msgstr "会计科目:" + +#: lib/perl5/Selima/Form/AcctRec.pm:157 +msgid "Summary:" +msgstr "摘要:" + +#: lib/perl5/Selima/Form/AcctRec.pm:162 +msgid "Amount:" +msgstr "金额:" + +#: lib/perl5/Selima/Form/AcctSubj.pm:34 +msgid "Delete this accounting subject" +msgstr "删掉这个会计科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:39 +msgid "This table provides you a form to add a new accounting subject." +msgstr "本表提供建新会计科目的表单。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:42 +msgid "This table provides you a form to edit a current accounting subject." +msgstr "本表提供编辑会计科目的表单。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:45 +msgid "This table provides you a form to delete an accounting subject." +msgstr "本表提供删除会计科目的表单。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:62 +msgid "Add a New Accounting Subject" +msgstr "建新会计科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:65 +msgid "Edit a Current Accounting Subject" +msgstr "编辑会计科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:68 +msgid "Delete an Accounting Subject" +msgstr "删除会计科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:75 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the accounting " +"subject, [numerate,_1,its accounting sub-subject,all of its accounting sub-" +"subjects] must first be deleted." +msgstr "" +"本会计科目下有子会计科目,不可直接删除。要删除本科目,请先删除其下的子会计科" +"目。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:79 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the accounting subject, " +"[numerate,_1,its accounting record,all of its accounting records] must first " +"be deleted." +msgstr "" +"本会计科目下有会计分录,不可直接删除。要删除本会计科目,请先删除其下的会计分" +"录。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:87 +msgid "Code:" +msgstr "代码:" + +#: lib/perl5/Selima/Form/AcctSubj.pm:93 +msgid "Parent subject:" +msgstr "大科目:" + +#: lib/perl5/Selima/Form/AcctSubj.pm:106 +msgid "[numerate,_1,Sub-subject,Sub-subjects]:" +msgstr "子科目:" + +#: lib/perl5/Selima/Form/AcctTrx.pm:37 +msgid "Delete this accounting transaction" +msgstr "删掉这笔会计传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:43 +msgid "This table provides you a form to add a new accounting transaction." +msgstr "本表提供建新会计传票的表单。" + +#: lib/perl5/Selima/Form/AcctTrx.pm:46 +msgid "" +"This table provides you a form to edit a current accounting transaction." +msgstr "本表提供编辑会计传票的表单。" + +#: lib/perl5/Selima/Form/AcctTrx.pm:49 +msgid "This table provides you a form to delete an accounting transaction." +msgstr "本表提供删除会计传票的表单。" + +#: lib/perl5/Selima/Form/AcctTrx.pm:92 lib/perl5/Selima/Form/AcctTrx.pm:97 +msgid "Convert to a transfer transaction" +msgstr "转为转帐传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:102 +msgid "Add a New Cache Expense Transaction" +msgstr "建新现金支出传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:104 +msgid "Add a New Cache Income Transaction" +msgstr "建新现金收入传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:106 +msgid "Add a New Transfer Transaction" +msgstr "建新转帐传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:111 +msgid "Edit a Current Cache Expense Transaction" +msgstr "编辑现金支出传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:113 +msgid "Edit a Current Cache Income Transaction" +msgstr "编辑现金收入传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:115 +msgid "Edit a Current Transfer Transaction" +msgstr "编辑转帐传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:120 +msgid "Delete a Cache Expense Transaction" +msgstr "删除现金支出传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:122 +msgid "Delete a Cache Income Transaction" +msgstr "删除现金收入传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:124 +msgid "Delete a Transfer Transaction" +msgstr "删掉转帐传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:336 +#: lib/perl5/Selima/List/Accounting/Records.pm:35 +#: lib/perl5/Selima/List/Accounting/Reports.pm:73 +msgid "Accounting subject" +msgstr "会计科目" + +#: lib/perl5/Selima/Form/AcctTrx.pm:337 +#: lib/perl5/Selima/List/Accounting/Records.pm:36 +#: lib/perl5/Selima/List/Accounting/Reports.pm:74 +msgid "Summary" +msgstr "摘要" + +#: lib/perl5/Selima/Form/AcctTrx.pm:338 +#: lib/perl5/Selima/List/Accounting/Records.pm:37 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:40 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:41 +msgid "Amount" +msgstr "金额" + +#: lib/perl5/Selima/Form/AcctTrx.pm:339 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:173 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:196 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:200 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:152 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:130 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:151 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:177 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:166 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:189 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:144 +msgid "Total" +msgstr "合计" + +#: lib/perl5/Selima/Form/AcctTrx.pm:379 lib/perl5/Selima/Form/AcctTrx.pm:518 +#: lib/perl5/Selima/Form/AcctTrx.pm:708 +msgid "[numerate,_1,Content]:" +msgstr "内容:" + +#: lib/perl5/Selima/Form/AcctTrx.pm:801 +msgid "Note:" +msgstr "注记:" + +#: lib/perl5/Selima/Form/GroupMem.pm:33 lib/perl5/Selima/Form/UserMem.pm:33 +msgid "Delete this membership record" +msgstr "删掉这笔成员关系" + +#: lib/perl5/Selima/Form/GroupMem.pm:38 lib/perl5/Selima/Form/UserMem.pm:38 +msgid "This table provides you a form to add a new membership record." +msgstr "本表提供建新成员关系的表单。" + +#: lib/perl5/Selima/Form/GroupMem.pm:41 lib/perl5/Selima/Form/UserMem.pm:41 +msgid "This table provides you a form to change a current membership record." +msgstr "本表提供变更成员关系的表单。" + +#: lib/perl5/Selima/Form/GroupMem.pm:44 lib/perl5/Selima/Form/UserMem.pm:44 +msgid "This table provides you a form to delete a membership record." +msgstr "本表提供删除成员关系的表单。" + +#: lib/perl5/Selima/Form/GroupMem.pm:61 +msgid "Add A New Group Membership Record" +msgstr "建新群组成员关系" + +#: lib/perl5/Selima/Form/GroupMem.pm:64 +msgid "Change a Current Group Membership Record" +msgstr "变更群组成员关系" + +#: lib/perl5/Selima/Form/GroupMem.pm:67 +msgid "Delete a Group Membership Record" +msgstr "删除群组成员关系" + +#: lib/perl5/Selima/Form/GroupMem.pm:76 lib/perl5/Selima/Form/UserMem.pm:76 +msgid "Member:" +msgstr "成员:" + +#: lib/perl5/Selima/Form/Group.pm:37 +msgid "Delete this group" +msgstr "删掉这个群组" + +#: lib/perl5/Selima/Form/Group.pm:42 +msgid "This table provides you a form to add a new group." +msgstr "本表提供建新群组的表单。" + +#: lib/perl5/Selima/Form/Group.pm:45 +msgid "This table provides you a form to update a current group." +msgstr "本表提供设置群组的表单。" + +#: lib/perl5/Selima/Form/Group.pm:48 +msgid "This table provides you a form to delete a group." +msgstr "本表提供删除群组的表单。" + +#: lib/perl5/Selima/Form/Group.pm:65 +msgid "Add a New Group" +msgstr "建新群组" + +#: lib/perl5/Selima/Form/Group.pm:68 +msgid "Update a Current Group" +msgstr "设置群组" + +#: lib/perl5/Selima/Form/Group.pm:71 +msgid "Delete a Group" +msgstr "删除群组" + +#: lib/perl5/Selima/Form/Group.pm:77 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "这是最高管理员的群组,妳只能设置它部份的数据。" + +#: lib/perl5/Selima/Form/Group.pm:89 lib/perl5/Selima/Form/Group.pm:91 +msgid "Group ID.:" +msgstr "群组代号:" + +#: lib/perl5/Selima/Form/Group.pm:110 +msgid "Add a user" +msgstr "增加成员" + +#: lib/perl5/Selima/Form/Group.pm:114 lib/perl5/Selima/Form/Group.pm:148 +#: lib/perl5/Selima/Form/Group.pm:164 lib/perl5/Selima/Form/Group.pm:211 +msgid "[numerate,_1,User member]:" +msgstr "用户成员:" + +#: lib/perl5/Selima/Form/Group.pm:239 lib/perl5/Selima/Form/Group.pm:369 +msgid "Add a group" +msgstr "增加群组" + +#: lib/perl5/Selima/Form/Group.pm:243 lib/perl5/Selima/Form/Group.pm:277 +#: lib/perl5/Selima/Form/Group.pm:293 lib/perl5/Selima/Form/Group.pm:340 +msgid "[numerate,_1,Group member]:" +msgstr "群组成员:" + +#: lib/perl5/Selima/Form/Group.pm:368 lib/perl5/Selima/Form/User.pm:223 +msgid "Belonging to:" +msgstr "隶属群组:" + +#: lib/perl5/Selima/Form/Guestbook.pm:32 +msgid "Delete this message" +msgstr "删掉这则留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:37 +msgid "This table provides you a form to add a new message." +msgstr "本表提供写新留言的表单。" + +#: lib/perl5/Selima/Form/Guestbook.pm:40 +msgid "This table provides you a form to edit a current message." +msgstr "本表提供编辑留言的表单。" + +#: lib/perl5/Selima/Form/Guestbook.pm:43 +msgid "This table provides you a form to delete a message." +msgstr "本表提供删除留言的表单。" + +#: lib/perl5/Selima/Form/Guestbook.pm:61 +msgid "Write a New Message" +msgstr "写新留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:64 +msgid "Edit a Current Message" +msgstr "编辑留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:67 +msgid "Delete a Message" +msgstr "删除留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:77 lib/perl5/Selima/Form/User.pm:149 +msgid "Country:" +msgstr "国家:" + +#: lib/perl5/Selima/Form/Guestbook.pm:83 +msgid "Hide this message" +msgstr "隐藏这则留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:83 +msgid "Show this message" +msgstr "秀出这则留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:84 +msgid "Hide this message currently." +msgstr "暂勿秀出这则留言。" + +#: lib/perl5/Selima/Form/Guestbook.pm:89 +msgid "Signature:" +msgstr "签名:" + +#: lib/perl5/Selima/Form/Guestbook.pm:94 +msgid "Old page no.:" +msgstr "旧页数:" + +#: lib/perl5/Selima/Form/Guestbook.pm:99 +msgid "Page no.:" +msgstr "页数:" + +#: lib/perl5/Selima/Form/LinkCat.pm:33 +msgid "Delete this category" +msgstr "删掉这个分类" + +#: lib/perl5/Selima/Form/LinkCat.pm:38 +msgid "This table provides you a form to add a new category." +msgstr "本表提供建新分类的表单。" + +#: lib/perl5/Selima/Form/LinkCat.pm:41 +msgid "This table provides you a form to edit a current category." +msgstr "本表提供编辑分类的表单。" + +#: lib/perl5/Selima/Form/LinkCat.pm:44 +msgid "This table provides you a form to delete a category." +msgstr "本表提供删除分类的表单。" + +#: lib/perl5/Selima/Form/LinkCat.pm:62 +msgid "Add a New Link Category" +msgstr "建新链接分类" + +#: lib/perl5/Selima/Form/LinkCat.pm:65 +msgid "Edit a Current Link Category" +msgstr "编辑链接分类" + +#: lib/perl5/Selima/Form/LinkCat.pm:68 +msgid "Delete a Link Category" +msgstr "删除链接分类" + +#: lib/perl5/Selima/Form/LinkCat.pm:76 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分类下有子类,不可直接删除。要删除本分类,请先删除其下的子类。" + +#: lib/perl5/Selima/Form/LinkCat.pm:80 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分类下有链接,不可直接删除。要删除本分类,请先删除其下的链接。" + +#: lib/perl5/Selima/Form/LinkCat.pm:89 +msgid "Hide this category" +msgstr "隐藏这个分类" + +#: lib/perl5/Selima/Form/LinkCat.pm:89 +msgid "Show this category" +msgstr "秀出这个分类" + +#: lib/perl5/Selima/Form/LinkCat.pm:90 +msgid "Hide this category currently." +msgstr "暂勿秀出这个分类。" + +#: lib/perl5/Selima/Form/LinkCat.pm:106 +msgid "[numerate,_1,Link,Links]:" +msgstr "链接:" + +#: lib/perl5/Selima/Form/LinkCatz.pm:33 +msgid "Delete this categorization record" +msgstr "删掉这笔分类数据" + +#: lib/perl5/Selima/Form/LinkCatz.pm:38 +msgid "This table provides you a form to add a new categorization record." +msgstr "本表提供建新分类数据的表单。" + +#: lib/perl5/Selima/Form/LinkCatz.pm:41 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "本表提供变更分类数据的表单。" + +#: lib/perl5/Selima/Form/LinkCatz.pm:44 +msgid "This table provides you a form to delete a categorization record." +msgstr "本表提供删除分类数据的表单。" + +#: lib/perl5/Selima/Form/LinkCatz.pm:61 +msgid "Add A New Link Categorization Record" +msgstr "建新链接分类数据" + +#: lib/perl5/Selima/Form/LinkCatz.pm:64 +msgid "Change a Current Link Categorization Record" +msgstr "变更链接分类数据" + +#: lib/perl5/Selima/Form/LinkCatz.pm:67 +msgid "Delete a Link Categorization Record" +msgstr "删除链接分类数据" + +#: lib/perl5/Selima/Form/LinkCatz.pm:76 +msgid "Category:" +msgstr "分类:" + +#: lib/perl5/Selima/Form/LinkCatz.pm:81 +msgid "Link:" +msgstr "链接:" + +#: lib/perl5/Selima/Form/Link.pm:35 +msgid "Delete this related link" +msgstr "删掉这笔相关链接" + +#: lib/perl5/Selima/Form/Link.pm:40 +msgid "This table provides you a form to add a new related link." +msgstr "本表提供建新相关链接的表单。" + +#: lib/perl5/Selima/Form/Link.pm:43 +msgid "This table provides you a form to edit a current related link." +msgstr "本表提供编辑相关链接的表单。" + +#: lib/perl5/Selima/Form/Link.pm:46 +msgid "This table provides you a form to delete a related link." +msgstr "本表提供删除相关链接的表单。" + +#: lib/perl5/Selima/Form/Link.pm:65 +msgid "Add a New Related Link" +msgstr "建新相关链接" + +#: lib/perl5/Selima/Form/Link.pm:68 +msgid "Edit a Current Related Link" +msgstr "编辑相关链接" + +#: lib/perl5/Selima/Form/Link.pm:71 +msgid "Delete a Related Link" +msgstr "删除相关链接" + +#: lib/perl5/Selima/Form/Link.pm:81 +msgid "[numerate,_1,Category,Categories]:" +msgstr "分类:" + +#: lib/perl5/Selima/Form/Link.pm:88 +msgid "Hide this related link" +msgstr "隐藏这笔相关链接" + +#: lib/perl5/Selima/Form/Link.pm:88 +msgid "Show this related link" +msgstr "秀出这笔相关链接" + +#: lib/perl5/Selima/Form/Link.pm:89 +msgid "Hide this related link currently." +msgstr "暂勿秀出这笔相关链接。" + +#: lib/perl5/Selima/Form/Link.pm:100 +msgid "Link icon:" +msgstr "链接小图:" + +#: lib/perl5/Selima/Form/Link.pm:101 +msgid "Link icon unavailable" +msgstr "链接小图无法显示" + +#: lib/perl5/Selima/Form/Link.pm:173 +msgid "2nd language title:" +msgstr "第二语言标题:" + +#: lib/perl5/Selima/Form/Page.pm:32 +msgid "Delete this page" +msgstr "删掉这一页" + +#: lib/perl5/Selima/Form/Page.pm:37 +msgid "This table provides you a form to write a new page." +msgstr "本表提供写新网页的表单。" + +#: lib/perl5/Selima/Form/Page.pm:40 +msgid "This table provides you a form to edit a current page." +msgstr "本表提供编辑网页的表单。" + +#: lib/perl5/Selima/Form/Page.pm:43 +msgid "This table provides you a form to delete a page." +msgstr "本表提供删除网页的表单。" + +#: lib/perl5/Selima/Form/Page.pm:60 +msgid "Write a New Page" +msgstr "写新网页" + +#: lib/perl5/Selima/Form/Page.pm:63 +msgid "Edit a Current Page" +msgstr "编辑网页" + +#: lib/perl5/Selima/Form/Page.pm:66 +msgid "Delete a Page" +msgstr "删除网页" + +#: lib/perl5/Selima/Form/Page.pm:73 +msgid "Preview this page." +msgstr "预览本页。" + +#: lib/perl5/Selima/Form/Page.pm:82 +msgid "Hide this page" +msgstr "隐藏这页网页" + +#: lib/perl5/Selima/Form/Page.pm:82 +msgid "Show this page" +msgstr "秀出这页网页" + +#: lib/perl5/Selima/Form/Page.pm:83 +msgid "Hide this page currently." +msgstr "暂勿秀出这页网页。" + +#: lib/perl5/Selima/Form/Rebuild.pm:36 +msgid "Rebuild the Pages" +msgstr "重制网页" + +#: lib/perl5/Selima/Form/Rebuild.pm:41 +msgid "Confirm" +msgstr "确定" + +#: lib/perl5/Selima/Form/ScptPriv.pm:33 +msgid "Delete this script privilege record" +msgstr "删掉这笔程序权限数据" + +#: lib/perl5/Selima/Form/ScptPriv.pm:38 +msgid "This table provides you a form to add a new script privilege record." +msgstr "本表提供建新程序权限数据的表单。" + +#: lib/perl5/Selima/Form/ScptPriv.pm:41 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "本表提供变更程序权限数据的表单。" + +#: lib/perl5/Selima/Form/ScptPriv.pm:44 +msgid "This table provides you a form to delete a script privilege record." +msgstr "本表提供删除程序权限数据的表单。" + +#: lib/perl5/Selima/Form/ScptPriv.pm:61 +msgid "Add A New Script Privilege Record" +msgstr "建新程序权限数据" + +#: lib/perl5/Selima/Form/ScptPriv.pm:64 +msgid "Change a Current Script Privilege Record" +msgstr "变更程序权限数据" + +#: lib/perl5/Selima/Form/ScptPriv.pm:67 +msgid "Delete a Script Privilege Record" +msgstr "删除程序权限数据" + +#: lib/perl5/Selima/Form/ScptPriv.pm:76 +msgid "Privilege:" +msgstr "权限:" + +#: lib/perl5/Selima/Form/UserMem.pm:61 +msgid "Add A New User Membership Record" +msgstr "建新用户成员关系" + +#: lib/perl5/Selima/Form/UserMem.pm:64 +msgid "Change a Current User Membership Record" +msgstr "变更用户成员关系" + +#: lib/perl5/Selima/Form/UserMem.pm:67 +msgid "Delete a User Membership Record" +msgstr "删除用户成员关系" + +#: lib/perl5/Selima/Form/User.pm:39 +msgid "Delete this user account" +msgstr "删掉这个帐号" + +#: lib/perl5/Selima/Form/User.pm:46 +msgid "This table provides you a form to add a new user account." +msgstr "本表提供建新帐号的表单。" + +#: lib/perl5/Selima/Form/User.pm:49 +msgid "This table provides you a form to update a current user account." +msgstr "本表提供设置帐号的表单。" + +#: lib/perl5/Selima/Form/User.pm:52 +msgid "This table provides you a form to delete a user account." +msgstr "本表提供删除帐号的表单。" + +#: lib/perl5/Selima/Form/User.pm:70 +msgid "Add a New User Account" +msgstr "建新帐号" + +#: lib/perl5/Selima/Form/User.pm:73 +msgid "Update a Current User Account" +msgstr "设置帐号" + +#: lib/perl5/Selima/Form/User.pm:76 +msgid "Delete a User Account" +msgstr "删除帐号" + +#: lib/perl5/Selima/Form/User.pm:84 +msgid "This is a super-user. You can only change parts of her/his infomation." +msgstr "这个人是总管理员,妳只能设置她/他部份的数据。" + +#: lib/perl5/Selima/Form/User.pm:143 +msgid "Administrator?" +msgstr "网站管理员?" + +#: lib/perl5/Selima/Form/User.pm:144 +msgid "Administrator" +msgstr "网站管理员" + +#: lib/perl5/Selima/Form/User.pm:144 +msgid "Non-administrator" +msgstr "普通用户" + +#: lib/perl5/Selima/Form/User.pm:165 +msgid "Disable this user account." +msgstr "帐号停用。" + +#: lib/perl5/Selima/Form/User.pm:176 lib/perl5/Selima/Form/User.pm:178 +msgid "User ID.:" +msgstr "用户代号:" + +#: lib/perl5/Selima/Form/User.pm:184 +msgid "Pref. language:" +msgstr "语言偏好:" + +#: lib/perl5/Selima/Form/User.pm:189 +msgid "Full name:" +msgstr "姓名:" + +#: lib/perl5/Selima/Form/UserPref.pm:35 +msgid "Delete this user preference" +msgstr "删掉这笔用户偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:40 +msgid "This table provides you a form to add a new user preference." +msgstr "本表提供建新用户偏好的表单。" + +#: lib/perl5/Selima/Form/UserPref.pm:43 +msgid "This table provides you a form to modify a current user preference." +msgstr "本表提供设置用户偏好的表单。" + +#: lib/perl5/Selima/Form/UserPref.pm:46 +msgid "This table provides you a form to delete a user preference." +msgstr "本表提供删除用户偏好的表单。" + +#: lib/perl5/Selima/Form/UserPref.pm:63 +msgid "Add A New User Preference" +msgstr "建新用户偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:66 +msgid "Modify a Current User Preference" +msgstr "设置用户偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:69 +msgid "Delete a User Preference" +msgstr "删除用户偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:82 +msgid "Domain:" +msgstr "适用范围:" + +#: lib/perl5/Selima/Form/UserPref.pm:83 +msgid "Everywhere" +msgstr "所有地方" + +#: lib/perl5/Selima/Form/UserPref.pm:88 +msgid "User:" +msgstr "用户:" + +#: lib/perl5/Selima/Form/UserPref.pm:89 +msgid "Everyone" +msgstr "所有人" + +#: lib/perl5/Selima/List/ActLog.pm:31 +msgid "Browse the Activity Log" +msgstr "查阅网站活动日志" + +#: lib/perl5/Selima/List/ActLog.pm:132 +msgid "Please fill in the number of rows to display." +msgstr "请填上显示笔数。" + +#: lib/perl5/Selima/List/ActLog.pm:135 +msgid "Please fill in a positive integer number of rows to display." +msgstr "显示笔数请填正整数。" + +#: lib/perl5/Selima/List/ActLog.pm:140 +msgid "This number of rows to display is too long. (Max. length [#,_1])" +msgstr "显示笔数太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/List/ActLog.pm:157 +msgid "Search for log entries:" +msgstr "搜索记录:" + +#: lib/perl5/Selima/List/ActLog.pm:162 +msgid "Display" +msgstr "显示" + +#: lib/perl5/Selima/List/ActLog.pm:163 +msgid "Display rows:" +msgstr "显示笔数:" + +#: lib/perl5/Selima/List/ActLog.pm:198 +msgid "Your query found [*,_1,log entry,log entries]." +msgstr "共 [#,_1] 笔相符的记录。" + +#: lib/perl5/Selima/List/ActLog.pm:201 +msgid "[*,_1,log entry,log entries]." +msgstr "共 [#,_1] 笔记录。" + +#: lib/perl5/Selima/List/ActLog.pm:207 +msgid "" +"Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的记录,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/ActLog.pm:211 +msgid "[*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔记录,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Category.pm:18 +msgid "Add a new category." +msgstr "建新链接分类。" + +#: lib/perl5/Selima/List/Category.pm:24 +msgid "Search for a category:" +msgstr "搜索分类:" + +#: lib/perl5/Selima/List/Category.pm:41 +msgid "Your query found [*,_1,category,categories]." +msgstr "共 [#,_1] 个相符的分类。" + +#: lib/perl5/Selima/List/Category.pm:44 +msgid "[*,_1,category,categories]." +msgstr "共 [#,_1] 个分类。" + +#: lib/perl5/Selima/List/Category.pm:50 +msgid "Your query found [*,_1,category,categories], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个相符的分类,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: lib/perl5/Selima/List/Category.pm:54 +msgid "[*,_1,category,categories], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个分类,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: lib/perl5/Selima/List/Categorz.pm:18 +msgid "Add a new categorization record." +msgstr "建新分类数据。" + +#: lib/perl5/Selima/List/Categorz.pm:24 +msgid "Search for a categorization record:" +msgstr "搜索分类数据:" + +#: lib/perl5/Selima/List/Categorz.pm:41 +msgid "Your query found [*,_1,categorization record]." +msgstr "共 [#,_1] 笔相符的分类数据。" + +#: lib/perl5/Selima/List/Categorz.pm:44 +msgid "[*,_1,categorization record]." +msgstr "共 [#,_1] 笔分类数据。" + +#: lib/perl5/Selima/List/Categorz.pm:50 +msgid "" +"Your query found [*,_1,categorization record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的分类数据,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Categorz.pm:54 +msgid "[*,_1,categorization record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔分类数据,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/GroupMem.pm:24 +msgid "Select a Group Membership Record" +msgstr "选择群组成员关系" + +#: lib/perl5/Selima/List/GroupMem.pm:25 +msgid "Manage Group Membership" +msgstr "管理群组成员关系" + +#: lib/perl5/Selima/List/GroupMem.pm:30 lib/perl5/Selima/List/UserMem.pm:30 +msgid "Group" +msgstr "群组" + +#: lib/perl5/Selima/List/GroupMem.pm:31 lib/perl5/Selima/List/UserMem.pm:31 +msgid "Member" +msgstr "成员" + +#: lib/perl5/Selima/List/GroupMem.pm:39 lib/perl5/Selima/List/UserMem.pm:39 +msgid "Add a new membership record." +msgstr "建新成员关系。" + +#: lib/perl5/Selima/List/GroupMem.pm:45 lib/perl5/Selima/List/UserMem.pm:45 +msgid "Search for a membership record:" +msgstr "搜索成员关系:" + +#: lib/perl5/Selima/List/GroupMem.pm:62 lib/perl5/Selima/List/UserMem.pm:62 +msgid "Your query found [*,_1,membership record]." +msgstr "共 [#,_1] 笔相符的成员关系。" + +#: lib/perl5/Selima/List/GroupMem.pm:65 lib/perl5/Selima/List/UserMem.pm:65 +msgid "[*,_1,membership record]." +msgstr "共 [#,_1] 笔成员关系。" + +#: lib/perl5/Selima/List/GroupMem.pm:71 lib/perl5/Selima/List/UserMem.pm:71 +msgid "Your query found [*,_1,membership record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的成员关系,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/GroupMem.pm:75 lib/perl5/Selima/List/UserMem.pm:75 +msgid "[*,_1,membership record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔成员关系,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Groups.pm:23 +msgid "Select a Group" +msgstr "选择群组" + +#: lib/perl5/Selima/List/Groups.pm:24 +msgid "Manage Groups" +msgstr "管理群组" + +#: lib/perl5/Selima/List/Groups.pm:29 +msgid "Group ID." +msgstr "群组代号" + +#: lib/perl5/Selima/List/Groups.pm:38 +msgid "Add a new group." +msgstr "建新群组。" + +#: lib/perl5/Selima/List/Groups.pm:44 +msgid "Search for a group:" +msgstr "搜索群组:" + +#: lib/perl5/Selima/List/Groups.pm:61 +msgid "Your query found [*,_1,group]." +msgstr "共 [#,_1] 个相符的群组。" + +#: lib/perl5/Selima/List/Groups.pm:64 +msgid "[*,_1,group]." +msgstr "共 [#,_1] 个群组。" + +#: lib/perl5/Selima/List/Groups.pm:70 +msgid "Your query found [*,_1,group], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个相符的群组,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: lib/perl5/Selima/List/Groups.pm:74 +msgid "[*,_1,group], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个群组,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: lib/perl5/Selima/List/Guestbook.pm:26 +msgid "Select a Message" +msgstr "选择留言" + +#: lib/perl5/Selima/List/Guestbook.pm:27 +msgid "Manage Guestbook" +msgstr "管理留言簿" + +#: lib/perl5/Selima/List/Guestbook.pm:38 +msgid "Signature" +msgstr "签名" + +#: lib/perl5/Selima/List/Guestbook.pm:39 +msgid "Identity" +msgstr "身份" + +#: lib/perl5/Selima/List/Guestbook.pm:40 +msgid "Location" +msgstr "所在地" + +#: lib/perl5/Selima/List/Guestbook.pm:41 +msgid "Message" +msgstr "留言" + +#: lib/perl5/Selima/List/Guestbook.pm:42 lib/perl5/Selima/List/Users.pm:35 +msgid "IP" +msgstr "IP" + +#: lib/perl5/Selima/List/Guestbook.pm:43 lib/perl5/Selima/List/Users.pm:36 +msgid "Host" +msgstr "主机" + +#: lib/perl5/Selima/List/Guestbook.pm:44 lib/perl5/Selima/List/Users.pm:37 +msgid "Country" +msgstr "国家" + +#: lib/perl5/Selima/List/Guestbook.pm:45 +msgid "Page No." +msgstr "页数" + +#: lib/perl5/Selima/List/Guestbook.pm:46 +msgid "Old page No." +msgstr "旧页数" + +#: lib/perl5/Selima/List/Guestbook.pm:54 +msgid "Write a new message." +msgstr "写新留言。" + +#: lib/perl5/Selima/List/Guestbook.pm:60 +msgid "Search for a message:" +msgstr "搜索留言:" + +#: lib/perl5/Selima/List/Guestbook.pm:77 +msgid "Your query found [*,_1,message]." +msgstr "共 [#,_1] 则相符的留言。" + +#: lib/perl5/Selima/List/Guestbook.pm:80 +msgid "[*,_1,message]." +msgstr "共 [#,_1] 则留言。" + +#: lib/perl5/Selima/List/Guestbook.pm:86 +msgid "Your query found [*,_1,message], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 则相符的留言,列出第 [#,_2] 则到第 [#,_3] 则。" + +#: lib/perl5/Selima/List/Guestbook.pm:90 +msgid "[*,_1,message], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 则留言,列出第 [#,_2] 则到第 [#,_3] 则。" + +#: lib/perl5/Selima/List/LinkCat.pm:24 +msgid "Select a Link Category" +msgstr "选择链接分类" + +#: lib/perl5/Selima/List/LinkCat.pm:25 +msgid "Manage Link Categories" +msgstr "管理链接分类" + +#: lib/perl5/Selima/List/LinkCatz.pm:24 +msgid "Select a Link Categorization Record" +msgstr "选择链接分类数据" + +#: lib/perl5/Selima/List/LinkCatz.pm:25 +msgid "Manage Link Categorization" +msgstr "管理链接分类表" + +#: lib/perl5/Selima/List/LinkCatz.pm:30 +msgid "Link" +msgstr "链接" + +#: lib/perl5/Selima/List/Links.pm:24 +msgid "Select a Related Link" +msgstr "选择相关链接" + +#: lib/perl5/Selima/List/Links.pm:25 +msgid "Manage Related Links" +msgstr "管理相关链接" + +#: lib/perl5/Selima/List/Links.pm:32 +msgid "2nd language title" +msgstr "第二语言标题" + +#: lib/perl5/Selima/List/Links.pm:33 +msgid "Link icon" +msgstr "链接小图" + +#: lib/perl5/Selima/List/Links.pm:34 +msgid "Address" +msgstr "地址" + +#: lib/perl5/Selima/List/Links.pm:35 +msgid "Tel." +msgstr "电话" + +#: lib/perl5/Selima/List/Links.pm:36 +msgid "Fax." +msgstr "传真" + +#: lib/perl5/Selima/List/Links.pm:44 +msgid "Add a new related link." +msgstr "建新相关链接。" + +#: lib/perl5/Selima/List/Links.pm:50 +msgid "Search for a related link:" +msgstr "搜索相关链接:" + +#: lib/perl5/Selima/List/Links.pm:67 +msgid "Your query found [*,_1,related link]." +msgstr "共 [#,_1] 笔相符的相关链接。" + +#: lib/perl5/Selima/List/Links.pm:70 +msgid "[*,_1,related link]." +msgstr "共 [#,_1] 笔相关链接。" + +#: lib/perl5/Selima/List/Links.pm:76 +msgid "Your query found [*,_1,related link], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的相关链接,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Links.pm:80 +msgid "[*,_1,related link], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相关链接,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Pages.pm:24 +msgid "Select a Page" +msgstr "选择网页" + +#: lib/perl5/Selima/List/Pages.pm:25 +msgid "Manage Pages" +msgstr "管理网页" + +#: lib/perl5/Selima/List/Pages.pm:40 +msgid "Write a new page." +msgstr "写新网页。" + +#: lib/perl5/Selima/List/Pages.pm:46 +msgid "Search for a page:" +msgstr "搜索网页:" + +#: lib/perl5/Selima/List/Pages.pm:63 +msgid "Your query found [*,_1,page]." +msgstr "共 [#,_1] 页相符的网页。" + +#: lib/perl5/Selima/List/Pages.pm:66 +msgid "[*,_1,page]." +msgstr "共 [#,_1] 页网页。" + +#: lib/perl5/Selima/List/Pages.pm:72 +msgid "Your query found [*,_1,page], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 页相符的网页,列出第 [#,_2] 页到第 [#,_3] 页。" + +#: lib/perl5/Selima/List/Pages.pm:76 +msgid "[*,_1,page], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 页网页,列出第 [#,_2] 页到第 [#,_3] 页。" + +#: lib/perl5/Selima/List/ScptPriv.pm:24 +msgid "Select a Script Privilege Record" +msgstr "选择程序权限数据" + +#: lib/perl5/Selima/List/ScptPriv.pm:25 +msgid "Manage Script Privileges" +msgstr "管理程序权限表" + +#: lib/perl5/Selima/List/ScptPriv.pm:30 +msgid "Script" +msgstr "程序" + +#: lib/perl5/Selima/List/ScptPriv.pm:31 +msgid "Privilege" +msgstr "权限说明" + +#: lib/perl5/Selima/List/ScptPriv.pm:39 +msgid "Add a new script privilege record." +msgstr "建新程序权限数据。" + +#: lib/perl5/Selima/List/ScptPriv.pm:45 +msgid "Search for a script privilege record:" +msgstr "搜索程序权限数据:" + +#: lib/perl5/Selima/List/ScptPriv.pm:62 +msgid "Your query found [*,_1,script privilege record]." +msgstr "共 [#,_1] 笔相符的程序权限数据。" + +#: lib/perl5/Selima/List/ScptPriv.pm:65 +msgid "[*,_1,script privilege record]." +msgstr "共 [#,_1] 笔程序权限数据。" + +#: lib/perl5/Selima/List/ScptPriv.pm:71 +msgid "" +"Your query found [*,_1,script privilege record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的程序权限数据,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/ScptPriv.pm:75 +msgid "[*,_1,script privilege record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔程序权限数据,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/UserMem.pm:24 +msgid "Select a User Membership Record" +msgstr "选择用户成员关系" + +#: lib/perl5/Selima/List/UserMem.pm:25 +msgid "Manage User Membership" +msgstr "管理用户成员关系" + +#: lib/perl5/Selima/List/UserPref.pm:24 +msgid "Select a User Preference" +msgstr "选择用户偏好" + +#: lib/perl5/Selima/List/UserPref.pm:25 +msgid "Manage User Preferences" +msgstr "管理用户偏好" + +#: lib/perl5/Selima/List/UserPref.pm:30 +msgid "User" +msgstr "用户" + +#: lib/perl5/Selima/List/UserPref.pm:31 +msgid "Domain" +msgstr "适用范围" + +#: lib/perl5/Selima/List/UserPref.pm:32 +msgid "Value" +msgstr "值" + +#: lib/perl5/Selima/List/UserPref.pm:40 +msgid "Add a new user preference." +msgstr "建新用户偏好。" + +#: lib/perl5/Selima/List/UserPref.pm:46 +msgid "Search for a user preference:" +msgstr "搜索用户偏好:" + +#: lib/perl5/Selima/List/UserPref.pm:63 +msgid "Your query found [*,_1,user preference]." +msgstr "共 [#,_1] 笔相符的用户偏好。" + +#: lib/perl5/Selima/List/UserPref.pm:66 +msgid "[*,_1,user preference]." +msgstr "共 [#,_1] 笔用户偏好。" + +#: lib/perl5/Selima/List/UserPref.pm:72 +msgid "Your query found [*,_1,user preference], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的用户偏好,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/UserPref.pm:76 +msgid "[*,_1,user preference], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔用户偏好,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Users.pm:23 +msgid "Select a User" +msgstr "选择用户" + +#: lib/perl5/Selima/List/Users.pm:24 +msgid "Manage Users" +msgstr "管理帐号" + +#: lib/perl5/Selima/List/Users.pm:29 +msgid "User ID." +msgstr "用户代号" + +#: lib/perl5/Selima/List/Users.pm:30 +msgid "Full name" +msgstr "姓名" + +#: lib/perl5/Selima/List/Users.pm:31 +msgid "Deleted?" +msgstr "已删?" + +#: lib/perl5/Selima/List/Users.pm:32 +msgid "Pref. language" +msgstr "语言偏好" + +#: lib/perl5/Selima/List/Users.pm:33 +msgid "Visits" +msgstr "上站次数" + +#: lib/perl5/Selima/List/Users.pm:34 +msgid "Visited" +msgstr "上站日期" + +#: lib/perl5/Selima/List/Users.pm:45 +msgid "Add a new user account." +msgstr "建新帐号。" + +#: lib/perl5/Selima/List/Users.pm:51 +msgid "Search for a user:" +msgstr "搜索用户:" + +#: lib/perl5/Selima/List/Users.pm:68 +msgid "Your query found [*,_1,user]." +msgstr "共 [#,_1] 位相符的用户。" + +#: lib/perl5/Selima/List/Users.pm:71 +msgid "[*,_1,user]." +msgstr "共 [#,_1] 位用户。" + +#: lib/perl5/Selima/List/Users.pm:77 +msgid "Your query found [*,_1,user], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位相符的用户,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: lib/perl5/Selima/List/Users.pm:81 +msgid "[*,_1,user], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位用户,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:103 +msgid "This accounting record was not modified." +msgstr "会计分录未异动。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:107 +msgid "This accounting record has been successfully added." +msgstr "会计分录建好了。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:111 +msgid "This accounting record has been successfully updated." +msgstr "会计分录存好了。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:115 +msgid "This accounting record has been successfully deleted." +msgstr "会计分录删掉了。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:86 +msgid "This accounting subject was not modified." +msgstr "会计科目未异动。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:90 +msgid "This accounting subject has been successfully added." +msgstr "会计科目建好了。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:94 +msgid "This accounting subject has been successfully updated." +msgstr "会计科目存好了。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:98 +msgid "This accounting subject has been successfully deleted." +msgstr "会计科目删掉了。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:418 +msgid "This accounting transaction was not modified." +msgstr "会计传票未异动。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:422 +msgid "This accounting transaction has been successfully added." +msgstr "会计传票建好了。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:426 +msgid "This accounting transaction has been successfully updated." +msgstr "会计传票存好了。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:430 +msgid "This accounting transaction has been successfully deleted." +msgstr "会计传票删掉了。" + +#: lib/perl5/Selima/Processor/Category.pm:20 +msgid "This category was not modified." +msgstr "分类未异动。" + +#: lib/perl5/Selima/Processor/Category.pm:24 +msgid "This category has been successfully added." +msgstr "分类建好了。" + +#: lib/perl5/Selima/Processor/Category.pm:28 +msgid "This category has been successfully updated." +msgstr "分类存好了。" + +#: lib/perl5/Selima/Processor/Category.pm:32 +msgid "This category has been successfully deleted." +msgstr "分类删掉了。" + +#: lib/perl5/Selima/Processor/Categorz.pm:20 +msgid "This categorization record was not modified." +msgstr "分类数据未异动。" + +#: lib/perl5/Selima/Processor/Categorz.pm:24 +msgid "This categorization record has been successfully added." +msgstr "分类数据建好了。" + +#: lib/perl5/Selima/Processor/Categorz.pm:28 +msgid "This categorization record has been successfully updated." +msgstr "分类数据存好了。" + +#: lib/perl5/Selima/Processor/Categorz.pm:32 +msgid "This categorization record has been successfully deleted." +msgstr "分类数据删掉了。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:79 +msgid "This group membership record was not modified." +msgstr "群组成员关系未异动。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:83 +msgid "This group membership record has been successfully added." +msgstr "群组成员关系建好了。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:87 +msgid "This group membership record has been successfully updated." +msgstr "群组成员关系存好了。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:91 +msgid "This group membership record has been successfully deleted." +msgstr "群组成员关系删掉了。" + +#: lib/perl5/Selima/Processor/Group.pm:253 +msgid "This group was not modified." +msgstr "群组未异动。" + +#: lib/perl5/Selima/Processor/Group.pm:257 +msgid "This group has been successfully added." +msgstr "群组建好了。" + +#: lib/perl5/Selima/Processor/Group.pm:261 +msgid "This group has been successfully updated." +msgstr "群组存好了。" + +#: lib/perl5/Selima/Processor/Group.pm:265 +msgid "This group has been successfully deleted." +msgstr "群组删掉了。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:117 +msgid "This message was not modified." +msgstr "留言未异动。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:121 +msgid "This message has been successfully added." +msgstr "留言写好了。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:125 +msgid "This message has been successfully updated." +msgstr "留言存好了。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:129 +msgid "This message has been successfully deleted." +msgstr "留言删掉了。" + +#: lib/perl5/Selima/Processor/Link.pm:168 +msgid "This related link was not modified." +msgstr "相关链接未异动。" + +#: lib/perl5/Selima/Processor/Link.pm:172 +msgid "This related link has been successfully added." +msgstr "相关链接建好了。" + +#: lib/perl5/Selima/Processor/Link.pm:176 +msgid "This related link has been successfully updated." +msgstr "相关链接存好了。" + +#: lib/perl5/Selima/Processor/Link.pm:180 +msgid "This related link has been successfully deleted." +msgstr "相关链接删掉了。" + +#: lib/perl5/Selima/Processor/LogOut.pm:52 +msgid "You have successfully logged out." +msgstr "注销了。" + +#: lib/perl5/Selima/Processor/Page.pm:89 +msgid "This page was not modified." +msgstr "网页未异动。" + +#: lib/perl5/Selima/Processor/Page.pm:93 +msgid "This page has been successfully added." +msgstr "网页写好了。" + +#: lib/perl5/Selima/Processor/Page.pm:97 +msgid "This page has been successfully updated." +msgstr "网页存好了。" + +#: lib/perl5/Selima/Processor/Page.pm:101 +msgid "This page has been successfully deleted." +msgstr "网页删掉了。" + +#: lib/perl5/Selima/Processor/Rebuild.pm:48 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. ([sprintf,%0.3f,_1] " +"seconds)" +msgstr "指定的网页重制好了。( [sprintf,%0.3f,_1] 秒)" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:79 +msgid "This script privilege record was not modified." +msgstr "程序权限未异动。" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:83 +msgid "This script privilege record has been successfully added." +msgstr "程序权限建好了。" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:87 +msgid "This script privilege record has been successfully updated." +msgstr "程序权限存好了。" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:91 +msgid "This script privilege record has been successfully deleted." +msgstr "程序权限删掉了。" + +#: lib/perl5/Selima/Processor/UserMem.pm:79 +msgid "This user membership record was not modified." +msgstr "用户成员关系未异动。" + +#: lib/perl5/Selima/Processor/UserMem.pm:83 +msgid "This user membership record has been successfully added." +msgstr "用户成员关系建好了。" + +#: lib/perl5/Selima/Processor/UserMem.pm:87 +msgid "This user membership record has been successfully updated." +msgstr "用户成员关系存好了。" + +#: lib/perl5/Selima/Processor/UserMem.pm:91 +msgid "This user membership record has been successfully deleted." +msgstr "用户成员关系删掉了。" + +#: lib/perl5/Selima/Processor/User.pm:185 +msgid "This user account was not modified." +msgstr "帐号未异动。" + +#: lib/perl5/Selima/Processor/User.pm:189 +msgid "This user account has been successfully added." +msgstr "帐号建好了。" + +#: lib/perl5/Selima/Processor/User.pm:193 +msgid "This user account has been successfully updated." +msgstr "帐号存好了。" + +#: lib/perl5/Selima/Processor/User.pm:197 +msgid "This user account has been successfully deleted." +msgstr "帐号删掉了。" + +#: lib/perl5/Selima/Processor/UserPref.pm:128 +msgid "This user preference was not modified." +msgstr "用户偏好未异动。" + +#: lib/perl5/Selima/Processor/UserPref.pm:132 +msgid "This user preference has been successfully added." +msgstr "用户偏好建好了。" + +#: lib/perl5/Selima/Processor/UserPref.pm:136 +msgid "This user preference has been successfully updated." +msgstr "用户偏好存好了。" + +#: lib/perl5/Selima/Processor/UserPref.pm:140 +msgid "This user preference has been successfully deleted." +msgstr "用户偏好删掉了。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:37 +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:59 +msgid "Your signature is too long. (Max. length [#,_1])" +msgstr "妳的签名太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:56 +msgid "Please fill in your signature." +msgstr "请填上妳的签名。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:80 +msgid "Your identity is too long. (Max. length [#,_1])" +msgstr "妳的身份太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:101 +msgid "Your location is too long. (Max. length [#,_1])" +msgstr "妳的所在地太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:122 +msgid "Your e-mail is too long. (Max. length [#,_1])" +msgstr "妳的 E-mail 信箱太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:143 +msgid "Your website URL is too long. (Max. length [#,_1])" +msgstr "妳的网站网址太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:163 +#: lib/perl5/Selima/Form/Guestbook/Public.pm:60 +msgid "Fill in your message here." +msgstr "请填上妳的留言。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:164 +msgid "Please fill in your message." +msgstr "请填上妳的留言。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:167 +msgid "Your message is too long. (Max. length [#,_1])" +msgstr "妳的留言太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:186 +msgid "You can post at most 5 messages in 1 hour." +msgstr "一小时最多只能留五篇留言。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:204 +msgid "Your message is already posted." +msgstr "留言已经留了。" + +#: lib/perl5/Selima/Form/Guestbook/Public.pm:40 +msgid "Leave a messsage" +msgstr "留言" + +#: lib/perl5/Selima/Form/Guestbook/Public.pm:42 +msgid "This table provides you a form to leave a message." +msgstr "本表提供留言的表单。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:27 +msgid "Select an Accounting Record" +msgstr "选择会计分录" + +#: lib/perl5/Selima/List/Accounting/Records.pm:28 +msgid "Manage Accounting Records" +msgstr "管理会计分录" + +#: lib/perl5/Selima/List/Accounting/Records.pm:33 +msgid "Accounting transaction" +msgstr "会计传票" + +#: lib/perl5/Selima/List/Accounting/Records.pm:34 +msgid "Debit/credit" +msgstr "借/贷" + +#: lib/perl5/Selima/List/Accounting/Records.pm:46 +msgid "Add a new accounting record." +msgstr "建新会计分录。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:52 +msgid "Search for an accounting record:" +msgstr "搜索会计分录:" + +#: lib/perl5/Selima/List/Accounting/Records.pm:69 +#: lib/perl5/Selima/List/Accounting/Reports.pm:634 +msgid "Your query found [*,_1,accounting record]." +msgstr "共 [#,_1] 笔相符的会计分录。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:72 +#: lib/perl5/Selima/List/Accounting/Reports.pm:637 +msgid "[*,_1,accounting record]." +msgstr "共 [#,_1] 笔会计分录。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:78 +#: lib/perl5/Selima/List/Accounting/Reports.pm:643 +msgid "Your query found [*,_1,accounting record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的会计分录,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:82 +#: lib/perl5/Selima/List/Accounting/Reports.pm:647 +msgid "[*,_1,accounting record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔会计分录,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:31 +msgid "View the Accounting Reports" +msgstr "浏览会计报表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:72 +msgid "Month" +msgstr "月份" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:77 +msgid "Income" +msgstr "收入" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:78 +msgid "Expense" +msgstr "支出" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:79 +msgid "Balance" +msgstr "余额" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:137 +msgid "Please specify a month." +msgstr "请设置月份。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:141 +msgid "Please specify a valid month in YYYY-MM format." +msgstr "月份请以 YYYY-MM 格式正确设置。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:176 +msgid "Please specify a year." +msgstr "请设置年份。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:180 +msgid "Please specify a valid year in YYYY format." +msgstr "年份请以 YYYY 格式正确设置。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:211 +msgid "Please specify the start date." +msgstr "请设置启始日期。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:215 +msgid "Please specify a valid start date in YYYY-MM-DD format." +msgstr "启始日期请以 YYYY-MM-DD 格式正确填写。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:226 +msgid "Please specify the end date." +msgstr "请设置结束日期。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:229 +msgid "Please specify a valid end date in YYYY-MM-DD format." +msgstr "结束日期请以 YYYY-MM-DD 格式正确填写。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:250 +msgid "This option is invalid. Please select a proper date range." +msgstr "日期范围选项无效,请由表上选择适当的日期范围。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:319 +#: lib/perl5/Selima/List/Accounting/Transacts.pm:53 +msgid "" +"Add a new cash expense transaction, add a new cash income transaction or add a new " +"transfer transaction." +msgstr "" +"建新现金支出传票建新现金收入传票" +"或建新转帐传票。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:339 +msgid "Report type:" +msgstr "报表类型:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:343 +msgid "Cash book" +msgstr "现金帐" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:347 +msgid "Cash book summary" +msgstr "现金帐摘要" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:351 +msgid "Ledger" +msgstr "分类帐" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:355 +msgid "Ledger summary" +msgstr "分类帐摘要" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:359 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:31 +msgid "Journal" +msgstr "日记簿" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:363 +msgid "Trial balance" +msgstr "试算表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:367 +msgid "Income statement" +msgstr "损益表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:371 +msgid "Balance sheet" +msgstr "资产负债表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:408 +msgid "Search the accounting records:" +msgstr "帐目检索:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:442 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:297 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:253 +msgid "Query" +msgstr "查找" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:443 +msgid "Date range:" +msgstr "日期范围:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:444 +msgid "By month:" +msgstr "依月份:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:445 +msgid "By year:" +msgstr "依年度:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:446 +msgid "Specified date range:" +msgstr "特定期间:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:447 +msgid "All" +msgstr "全部" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:448 +msgid "From" +msgstr "自" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:449 +msgid "to" +msgstr "至" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:563 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:332 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:326 +msgid "From [_1] to [_2]." +msgstr "自 [_1] 至 [_2] 。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:24 +msgid "Select an Accounting Subject" +msgstr "选择会计科目" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:25 +msgid "Manage Accounting Subjects" +msgstr "管理会计科目" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:30 +msgid "Parent subject" +msgstr "大科目" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:31 +msgid "Code" +msgstr "代码" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:39 +msgid "Add a new accounting subject." +msgstr "建新会计科目。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:45 +msgid "Search for an accounting subject:" +msgstr "搜索会计科目:" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:62 +msgid "Your query found [*,_1,accounting subject]." +msgstr "共 [#,_1] 个相符的会计科目。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:65 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:355 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:349 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:251 +msgid "[*,_1,accounting subject]." +msgstr "[#,_1] 个会计科目。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:71 +msgid "Your query found [*,_1,accounting subject], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个相符的会计科目,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:75 +msgid "[*,_1,accounting subject], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个会计科目,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:26 +msgid "Select an Accounting Transaction" +msgstr "选择会计传票" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:27 +msgid "Manage Accounting Transactions" +msgstr "管理会计传票" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:32 +msgid "Number" +msgstr "编号" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:33 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:42 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:40 +msgid "Note" +msgstr "注记" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:66 +msgid "Search for an accounting transaction:" +msgstr "搜索会计传票:" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:83 +msgid "Your query found [*,_1,accounting transaction]." +msgstr "共 [#,_1] 笔相符的会计传票。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:86 +msgid "[*,_1,accounting transaction]." +msgstr "[#,_1] 笔会计传票。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:92 +msgid "" +"Your query found [*,_1,accounting transaction], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的会计传票,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:96 +msgid "[*,_1,accounting transaction], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔会计传票,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Guestbook/Public.pm:196 +msgid "~[Edit~]" +msgstr "~[编辑~]" + +#: lib/perl5/Selima/List/Guestbook/Public.pm:205 +msgid "The message entry seperator" +msgstr "留言分隔线" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:29 +msgid "Balance Sheet" +msgstr "资产负债表" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:40 +msgid "Assets accounting subject" +msgstr "资产会计科目" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:41 +msgid "Assets amount" +msgstr "资产金额" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:42 +msgid "Liabilities accounting subject" +msgstr "负债会计科目" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:43 +msgid "Liabilities amount" +msgstr "负债金额" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:289 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:379 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:283 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:273 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:351 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:204 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:421 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:366 +msgid "Download the data as a CSV file." +msgstr "下载 CSV 格式数据档。" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:45 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:150 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:339 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:40 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:383 +msgid "current assets and liabilities" +msgstr "流动资产与负债" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:48 +msgid "Cash book - [_1]" +msgstr "现金帐 - [_1]" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:29 +msgid "Income Statement" +msgstr "损益表" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:187 +msgid "Gross income" +msgstr "营业毛利" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:189 +msgid "Operating income" +msgstr "营业净利" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:191 +msgid "Before tax income" +msgstr "税前净利" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:193 +msgid "After tax income" +msgstr "税后净利" + +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:41 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:39 +msgid "Transaction Number" +msgstr "传票编号" + +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:127 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:138 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:151 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:162 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:126 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:140 +msgid "Brought forward" +msgstr "上期结转" + +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:46 +msgid "Ledger - [_1]" +msgstr "分类帐 - [_1]" + +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:26 +msgid "Search the Accounting Records" +msgstr "帐目检索" + +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:28 +msgid "Search Result" +msgstr "检索结果" + +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:28 +msgid "Trial Balance" +msgstr "试算表" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:43 +msgid "Cash Book Summary - [_1]" +msgstr "现金帐摘要 - [_1]" + +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:41 +msgid "Ledger Summary - [_1]" +msgstr "分类帐摘要 - [_1]" diff --git a/po/selima/zh_CN.pox b/po/selima/zh_CN.pox new file mode 100644 index 0000000..18c8863 --- /dev/null +++ b/po/selima/zh_CN.pox @@ -0,0 +1,3376 @@ +# Simplified Chinese PO file for the Selima common subroutines. +# Copyright (C) 2003-2018 imacat +# This file is distributed under the same license as the selima package. +# imacat , 2003-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: selima 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-02-17 11:07+0800\n" +"PO-Revision-Date: 2018-11-02 01:04+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: lib/perl5/Selima/Checker.pm:130 +msgid "Please select a user." +msgstr "请选择使用者。" + +#: lib/perl5/Selima/Checker.pm:133 +msgid "This user does not exist anymore. Please select another one." +msgstr "查无此人,请重新选择。" + +#: lib/perl5/Selima/Checker.pm:151 +msgid "Please select a group." +msgstr "请选择群组。" + +#: lib/perl5/Selima/Checker.pm:154 +msgid "This group does not exist anymore. Please select another one." +msgstr "查无此群组,请重新选择。" + +#: lib/perl5/Selima/Checker.pm:172 +msgid "Please fill in the script." +msgstr "请填上程式档名。" + +#: lib/perl5/Selima/Checker.pm:175 +msgid "This script is too long. (Max. length [#,_1])" +msgstr "程式档名太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:179 +msgid "This script is not a valid script. Please specify another one." +msgstr "查无此程式,请重新设定执行的程式。" + +#: lib/perl5/Selima/Checker.pm:197 +msgid "Please fill in the author." +msgstr "请填上作者。" + +#: lib/perl5/Selima/Checker.pm:200 +msgid "This author is too long. (Max. length [#,_1])" +msgstr "作者太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:220 lib/perl5/Selima/Form.pm:1700 +msgid "Fill in the content here." +msgstr "请填上内文。" + +#: lib/perl5/Selima/Checker.pm:221 +msgid "Please fill in the content." +msgstr "请填上内文。" + +#: lib/perl5/Selima/Checker.pm:224 +msgid "This content is too long. (Max. length [#,_1])" +msgstr "内文太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:243 +msgid "Please fill in a date." +msgstr "请填上日期。" + +#: lib/perl5/Selima/Checker.pm:246 lib/perl5/Selima/Checker.pm:249 +#: lib/perl5/Selima/Checker.pm:251 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期请以 YYYY-MM-DD 格式正确填写。" + +#: lib/perl5/Selima/Checker.pm:270 lib/perl5/Selima/Form.pm:1756 +msgid "Fill in the description here." +msgstr "请填上说明。" + +#: lib/perl5/Selima/Checker.pm:271 +msgid "Please fill in the description." +msgstr "请填上说明。" + +#: lib/perl5/Selima/Checker.pm:274 +msgid "This description is too long. (Max. length [#,_1])" +msgstr "说明太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:293 +msgid "Please fill in the ID." +msgstr "请填上代号。" + +#: lib/perl5/Selima/Checker.pm:296 +msgid "This ID. is too long. (Max. length [#,_1])" +msgstr "代号太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:299 +msgid "This ID. is too short. (Max. length [#,_1])" +msgstr "代号太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:303 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "代号限用小写英文字母、数字和底线。" + +#: lib/perl5/Selima/Checker.pm:321 +msgid "Please fill in the keywords." +msgstr "请填上关键字。" + +#: lib/perl5/Selima/Checker.pm:324 +msgid "This keyword list is too long. (Max. length [#,_1])" +msgstr "关键字太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:344 lib/perl5/Selima/Form.pm:1830 +msgid "Fill in the message here." +msgstr "请填上留言。" + +#: lib/perl5/Selima/Checker.pm:345 +msgid "Please fill in the message." +msgstr "请填上留言。" + +#: lib/perl5/Selima/Checker.pm:348 +msgid "This message is too long. (Max. length [#,_1])" +msgstr "留言太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:367 +msgid "Please fill in the order." +msgstr "请填上先后次序。" + +#: lib/perl5/Selima/Checker.pm:370 +msgid "This order is too long. (Max. length [#,_1])" +msgstr "次序太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:374 +msgid "Please fill in a positive integer order." +msgstr "次序请填正整数。" + +#: lib/perl5/Selima/Checker.pm:400 +msgid "Please fill in the page path." +msgstr "请填上网页路径。" + +#: lib/perl5/Selima/Checker.pm:403 +msgid "This page path is too long. (Max. length [#,_1])" +msgstr "网页路径太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:414 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "已有同一网页,请勿重复建档。" + +#: lib/perl5/Selima/Checker.pm:417 +msgid "Please fill in an absolute page path." +msgstr "网页路径请填上绝对路径。" + +#: lib/perl5/Selima/Checker.pm:420 +msgid "Please fill in a valid page path." +msgstr "网页路径请填上正确路径。" + +#: lib/perl5/Selima/Checker.pm:423 +msgid "You cannot overwrite the cover home page." +msgstr "不可以程式设定首页。" + +#: lib/perl5/Selima/Checker.pm:426 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "网页路径限填 HTML 位址( *.html )。" + +#: lib/perl5/Selima/Checker.pm:454 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "查无此图,请重新上传图档。" + +#: lib/perl5/Selima/Checker.pm:458 +msgid "" +"This picture is too large. Please upload another one. (Max. length [#,_1])" +msgstr "图档太大,请重新上传图档(最大 [#,_1] )。" + +#: lib/perl5/Selima/Checker.pm:482 +msgid "Please fill in the picture caption." +msgstr "请填上图片标题。" + +#: lib/perl5/Selima/Checker.pm:485 +msgid "This picture caption is too long. (Max. length [#,_1])" +msgstr "图片标题太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:509 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "图片位置无效。请由表上选择适当的图片位置。" + +#: lib/perl5/Selima/Checker.pm:527 +msgid "Please fill in the title." +msgstr "请填上标题。" + +#: lib/perl5/Selima/Checker.pm:530 +msgid "This title is too long. (Max. length [#,_1])" +msgstr "标题太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:549 +msgid "Please fill in the English title." +msgstr "请填上英文标题。" + +#: lib/perl5/Selima/Checker.pm:552 +msgid "This English title is too long. (Max. length [#,_1])" +msgstr "英文标题太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:699 lib/perl5/Selima/Preview.pm:38 +msgid "The following field was not received: \"[_1]\"." +msgstr "程式没有收到下列栏位:「 [_1] 」" + +#: lib/perl5/Selima/ChkWrite.pm:35 +msgid "[_1]: It is not a file." +msgstr "[_1]: 这不是档案。" + +#: lib/perl5/Selima/ChkWrite.pm:39 +msgid "[_1]: You have no permission to overwrite this file." +msgstr "[_1]: 存档的权限不足,无法存档。" + +#: lib/perl5/Selima/ChkWrite.pm:50 +msgid "[_1]: You cannot create anything under the root directory." +msgstr "[_1]: 不可在根目录下建档。" + +#: lib/perl5/Selima/ChkWrite.pm:54 +msgid "" +"[_1]: One of the parents of this file ([_2]) is not a directory. You cannot " +"create any new file inside." +msgstr "[_1]: 路径中间有一部份( [_2] )不是目录,无法往下建档。" + +#: lib/perl5/Selima/ChkWrite.pm:58 +msgid "[_1]: You have no permission to create any file under [_2]." +msgstr "[_1]: 权限不足,无法在 [_2] 建档。" + +#: lib/perl5/Selima/CommText.pm:24 +msgid "(not set)" +msgstr "(未设定)" + +#: lib/perl5/Selima/CommText.pm:25 +msgid "(none)" +msgstr "(无)" + +#: lib/perl5/Selima/CommText.pm:26 +msgid "(N/A)" +msgstr "(不可考)" + +#: lib/perl5/Selima/Format.pm:48 +msgid "[#,_1] bytes" +msgstr "[#,_1] 位元组" + +#: lib/perl5/Selima/Form.pm:116 +msgid "Delete it." +msgstr "删掉" + +#: lib/perl5/Selima/Form.pm:119 +msgid "*" +msgstr "" + +#: lib/perl5/Selima/Form.pm:140 +msgid "This table provides you a form to add a new data record." +msgstr "本表提供建新资料的表单。" + +#: lib/perl5/Selima/Form.pm:143 +msgid "This table provides you a form to update a current data record." +msgstr "本表提供异动资料的表单。" + +#: lib/perl5/Selima/Form.pm:146 +msgid "This table provides you a form to delete a data record." +msgstr "本表提供删除资料的表单。" + +#: lib/perl5/Selima/Form.pm:185 +msgid "Add a New Data Record" +msgstr "建新资料" + +#: lib/perl5/Selima/Form.pm:188 +msgid "Update a Current Data Record" +msgstr "异动资料" + +#: lib/perl5/Selima/Form.pm:191 +msgid "Delete a Data Record" +msgstr "删除资料" + +#: lib/perl5/Selima/Form.pm:212 +msgid "Preview it." +msgstr "预览。" + +#: lib/perl5/Selima/Form.pm:271 lib/perl5/Selima/Form.pm:284 +msgid "Convert from Simplified Chinese" +msgstr "转自简体中文" + +#: lib/perl5/Selima/Form.pm:273 lib/perl5/Selima/Form.pm:286 +msgid "Convert from Traditional Chinese" +msgstr "转自正体中文" + +#: lib/perl5/Selima/Form.pm:447 lib/perl5/Selima/Form.pm:451 +#: lib/perl5/Selima/Form.pm:559 lib/perl5/Selima/Form.pm:563 +#: lib/perl5/Selima/Form/AcctTrx.pm:89 lib/perl5/Selima/Form/AcctTrx.pm:94 +msgid "Submit" +msgstr "传送" + +#: lib/perl5/Selima/Form.pm:448 lib/perl5/Selima/Form.pm:452 +#: lib/perl5/Selima/Form.pm:560 lib/perl5/Selima/Form.pm:564 +#: lib/perl5/Selima/Form/AcctTrx.pm:90 lib/perl5/Selima/Form/AcctTrx.pm:95 +msgid "Save" +msgstr "存档" + +#: lib/perl5/Selima/Form.pm:571 lib/perl5/Selima/Form.pm:1139 +#: lib/perl5/Selima/Form.pm:1229 lib/perl5/Selima/List.pm:1390 +msgid "Delete" +msgstr "删除" + +#: lib/perl5/Selima/Form.pm:572 lib/perl5/Selima/Form/Rebuild.pm:42 +msgid "Cancel" +msgstr "取消" + +#: lib/perl5/Selima/Form.pm:577 +msgid "" +"Are you sure you want to delete this data? You cannot recover it if you do " +"so." +msgstr "你真的要删掉吗?资料删掉就救不回来了。" + +#: lib/perl5/Selima/Form.pm:855 lib/perl5/Selima/Form.pm:951 +#: lib/perl5/Selima/Form.pm:1013 lib/perl5/Selima/Form.pm:1097 +#: lib/perl5/Selima/Form.pm:1175 lib/perl5/Selima/Form.pm:1282 +#: lib/perl5/Selima/Form.pm:1362 lib/perl5/Selima/Form.pm:1435 +#: lib/perl5/Selima/Form.pm:1528 lib/perl5/Selima/Form.pm:1620 +#: lib/perl5/Selima/Form.pm:2057 lib/perl5/Selima/Form/AcctRec.pm:122 +#: lib/perl5/Selima/Form/AcctTrx.pm:519 lib/perl5/Selima/Form/Group.pm:165 +#: lib/perl5/Selima/Form/Group.pm:294 lib/perl5/Selima/Form/Group.pm:421 +#: lib/perl5/Selima/Form/Link.pm:138 lib/perl5/Selima/Form/User.pm:291 +msgid "Original:" +msgstr "原:" + +#: lib/perl5/Selima/Form.pm:856 lib/perl5/Selima/Form.pm:952 +#: lib/perl5/Selima/Form.pm:1014 lib/perl5/Selima/Form.pm:1098 +#: lib/perl5/Selima/Form.pm:1176 lib/perl5/Selima/Form.pm:1283 +#: lib/perl5/Selima/Form.pm:1363 lib/perl5/Selima/Form.pm:1436 +#: lib/perl5/Selima/Form.pm:1529 lib/perl5/Selima/Form.pm:1621 +#: lib/perl5/Selima/Form.pm:2058 lib/perl5/Selima/Form/AcctRec.pm:123 +#: lib/perl5/Selima/Form/AcctTrx.pm:520 lib/perl5/Selima/Form/Group.pm:166 +#: lib/perl5/Selima/Form/Group.pm:295 lib/perl5/Selima/Form/Group.pm:422 +#: lib/perl5/Selima/Form/Link.pm:139 lib/perl5/Selima/Form/User.pm:292 +msgid "New:" +msgstr "新:" + +#: lib/perl5/Selima/Form.pm:860 lib/perl5/Selima/Form.pm:1018 +#: lib/perl5/Selima/Form.pm:1625 lib/perl5/Selima/Form.pm:2122 +msgid "Source:" +msgstr "原文:" + +#: lib/perl5/Selima/Form.pm:1138 lib/perl5/Selima/Form.pm:1228 +#: lib/perl5/Selima/Form/AcctRec.pm:100 lib/perl5/Selima/Form/AcctTrx.pm:214 +msgid "Choose" +msgstr "挑选" + +#: lib/perl5/Selima/Form.pm:1689 +msgid "Address:" +msgstr "地址:" + +#: lib/perl5/Selima/Form.pm:1694 +msgid "Author:" +msgstr "作者:" + +#: lib/perl5/Selima/Form.pm:1699 +msgid "Content:" +msgstr "内文:" + +#: lib/perl5/Selima/Form.pm:1713 +msgid "Current Website:" +msgstr "目前网站:" + +#: lib/perl5/Selima/Form.pm:1718 +msgid "Enter your website URL here." +msgstr "请填上你的网站网址。" + +#: lib/perl5/Selima/Form.pm:1734 +msgid "Created:" +msgstr "建档日期:" + +#: lib/perl5/Selima/Form.pm:1739 +msgid "Created by:" +msgstr "建档者:" + +#: lib/perl5/Selima/Form.pm:1744 lib/perl5/Selima/List.pm:167 +#: lib/perl5/Selima/Form/User.pm:160 lib/perl5/Selima/Form/User.pm:163 +msgid "Disabled?" +msgstr "停用?" + +#: lib/perl5/Selima/Form.pm:1745 lib/perl5/Selima/Form/User.pm:161 +#: lib/perl5/Selima/Form/User.pm:164 +msgid "Disabled" +msgstr "停用" + +#: lib/perl5/Selima/Form.pm:1745 lib/perl5/Selima/Form/User.pm:161 +#: lib/perl5/Selima/Form/User.pm:164 +msgid "Enabled" +msgstr "未停用" + +#: lib/perl5/Selima/Form.pm:1745 +msgid "Disable it." +msgstr "停用。" + +#: lib/perl5/Selima/Form.pm:1750 +msgid "Date:" +msgstr "日期:" + +#: lib/perl5/Selima/Form.pm:1755 lib/perl5/Selima/Form/Group.pm:97 +msgid "Description:" +msgstr "说明:" + +#: lib/perl5/Selima/Form.pm:1761 +msgid "E-mail:" +msgstr "E-mail :" + +#: lib/perl5/Selima/Form.pm:1766 +msgid "Fax.:" +msgstr "传真:" + +#: lib/perl5/Selima/Form.pm:1771 +msgid "Group:" +msgstr "群组:" + +#: lib/perl5/Selima/Form.pm:1776 lib/perl5/Selima/Form/Guestbook.pm:82 +#: lib/perl5/Selima/Form/LinkCat.pm:88 lib/perl5/Selima/Form/Link.pm:87 +#: lib/perl5/Selima/Form/Page.pm:81 +msgid "Hide?" +msgstr "隐藏?" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Hide it" +msgstr "隐藏起来" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Show it" +msgstr "秀出来" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Hide it currently." +msgstr "暂勿秀出。" + +#: lib/perl5/Selima/Form.pm:1782 lib/perl5/Selima/List.pm:171 +msgid "HTML?" +msgstr "HTML ?" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "HTML" +msgstr "HTML" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "Plain text" +msgstr "纯文字" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "The submitted content is HTML." +msgstr "以上内文为 HTML 格式。" + +#: lib/perl5/Selima/Form.pm:1788 +msgid "Host:" +msgstr "主机:" + +#: lib/perl5/Selima/Form.pm:1793 lib/perl5/Selima/Form/LinkCat.pm:95 +msgid "ID.:" +msgstr "代号:" + +#: lib/perl5/Selima/Form.pm:1798 +msgid "Identity:" +msgstr "身份:" + +#: lib/perl5/Selima/Form.pm:1803 +msgid "Introduction:" +msgstr "简介:" + +#: lib/perl5/Selima/Form.pm:1804 +msgid "Fill in the introduction here." +msgstr "请填上简介。" + +#: lib/perl5/Selima/Form.pm:1809 +msgid "IP:" +msgstr "IP :" + +#: lib/perl5/Selima/Form.pm:1814 +msgid "Keywords:" +msgstr "关键字:" + +#: lib/perl5/Selima/Form.pm:1819 +msgid "Language:" +msgstr "语言:" + +#: lib/perl5/Selima/Form.pm:1824 +msgid "Location:" +msgstr "所在地:" + +#: lib/perl5/Selima/Form.pm:1829 +msgid "Message:" +msgstr "留言:" + +#: lib/perl5/Selima/Form.pm:1835 +msgid "Name:" +msgstr "名字:" + +#: lib/perl5/Selima/Form.pm:1847 lib/perl5/Selima/Form/AcctTrx.pm:319 +msgid "Order:" +msgstr "次序:" + +#: lib/perl5/Selima/Form.pm:1853 +msgid "Parent category:" +msgstr "大类:" + +#: lib/perl5/Selima/Form.pm:1854 lib/perl5/Selima/Form/AcctSubj.pm:94 +msgid "At the very top" +msgstr "最上层" + +#: lib/perl5/Selima/Form.pm:1866 lib/perl5/Selima/Form/User.pm:201 +msgid "Password:" +msgstr "密码:" + +#: lib/perl5/Selima/Form.pm:1867 +msgid "Confirm password:" +msgstr "确认密码:" + +#: lib/perl5/Selima/Form.pm:1978 +msgid "Page path:" +msgstr "网页路径:" + +#: lib/perl5/Selima/Form.pm:1992 +msgid "Picture:" +msgstr "图片:" + +#: lib/perl5/Selima/Form.pm:1993 +msgid "Pic. caption:" +msgstr "图片标题:" + +#: lib/perl5/Selima/Form.pm:1994 +msgid "Pic. position:" +msgstr "图片位置:" + +#: lib/perl5/Selima/Form.pm:1997 +msgid "Set the picture" +msgstr "设定图片" + +#: lib/perl5/Selima/Form.pm:1998 +msgid "Delete this picture" +msgstr "删掉图片" + +#: lib/perl5/Selima/Form.pm:2003 lib/perl5/Selima/Form.pm:2178 +msgid "Picture preview" +msgstr "图片预览" + +#: lib/perl5/Selima/Form.pm:2059 +msgid "Original picture preview" +msgstr "原图片预览" + +#: lib/perl5/Selima/Form.pm:2060 +msgid "New picture preview" +msgstr "新图片预览" + +#: lib/perl5/Selima/Form.pm:2078 +msgid "Please upload a new picture from [_1]." +msgstr "请由[_1]建新图片。" + +#: lib/perl5/Selima/Form.pm:2228 +msgid "[numerate,_1,Subcategory,Subcategories]:" +msgstr "子类:" + +#: lib/perl5/Selima/Form.pm:2256 +msgid "Script:" +msgstr "程式:" + +#: lib/perl5/Selima/Form.pm:2261 +msgid "S/N:" +msgstr "编号:" + +#: lib/perl5/Selima/Form.pm:2266 +msgid "Tel.:" +msgstr "电话:" + +#: lib/perl5/Selima/Form.pm:2271 +msgid "Title:" +msgstr "标题:" + +#: lib/perl5/Selima/Form.pm:2276 +msgid "English title:" +msgstr "英文标题:" + +#: lib/perl5/Selima/Form.pm:2281 +msgid "Updated:" +msgstr "维护日期:" + +#: lib/perl5/Selima/Form.pm:2286 +msgid "Updated by:" +msgstr "维护者:" + +#: lib/perl5/Selima/Form.pm:2291 +msgid "URL:" +msgstr "网址:" + +#: lib/perl5/Selima/Form.pm:2296 lib/perl5/Selima/Form/UserPref.pm:94 +msgid "Value:" +msgstr "值:" + +#: lib/perl5/Selima/Form.pm:2301 +msgid "Visited:" +msgstr "上站日期:" + +#: lib/perl5/Selima/Form.pm:2306 +msgid "Visits:" +msgstr "上站次数:" + +#: lib/perl5/Selima/Init.pm:216 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" +"抱歉,我们不欢迎加装 FunWebProduct 外挂(如 Smiley Central 、 PopSwatter 、 " +"Spin4Dough 、 My Mail Signature 、 My Mail Stationery 、 My Mail Stamp 、 " +"Cursor Mania ……等等)的浏览器。 FunWebProduct 会重抓你看过的每一页网页,造" +"成网站负荷加倍,甚至当机。请先移除 FunWebProduct ,再上来浏览。" + +#: lib/perl5/Selima/Links.pm:242 +msgid "Related Links" +msgstr "相关网站连结" + +#: lib/perl5/Selima/List.pm:109 +msgid "Select" +msgstr "选择" + +#: lib/perl5/Selima/List.pm:112 +msgid "Select A Data Record" +msgstr "选择资料" + +#: lib/perl5/Selima/List.pm:114 +msgid "Edit" +msgstr "设定" + +#: lib/perl5/Selima/List.pm:116 +msgid "Manage Data" +msgstr "管理资料" + +#: lib/perl5/Selima/List.pm:158 +msgid "S/N" +msgstr "编号" + +#: lib/perl5/Selima/List.pm:159 +msgid "Created" +msgstr "建档日期" + +#: lib/perl5/Selima/List.pm:160 +msgid "Created by" +msgstr "建档者" + +#: lib/perl5/Selima/List.pm:161 +msgid "Updated" +msgstr "维护日期" + +#: lib/perl5/Selima/List.pm:162 +msgid "Updated by" +msgstr "维护者" + +#: lib/perl5/Selima/List.pm:164 +msgid "Content" +msgstr "内文" + +#: lib/perl5/Selima/List.pm:165 +msgid "Category" +msgstr "分类" + +#: lib/perl5/Selima/List.pm:166 +msgid "Date" +msgstr "日期" + +#: lib/perl5/Selima/List.pm:168 lib/perl5/Selima/List/Groups.pm:30 +msgid "Description" +msgstr "说明" + +#: lib/perl5/Selima/List.pm:169 lib/perl5/Selima/List/Guestbook/Public.pm:138 +msgid "E-mail" +msgstr "E-mail" + +#: lib/perl5/Selima/List.pm:170 +msgid "Hidden?" +msgstr "隐藏?" + +#: lib/perl5/Selima/List.pm:172 +msgid "ID." +msgstr "代号" + +#: lib/perl5/Selima/List.pm:173 +msgid "Keywords" +msgstr "关键字" + +#: lib/perl5/Selima/List.pm:174 +msgid "Name" +msgstr "名字" + +#: lib/perl5/Selima/List.pm:175 +msgid "Order" +msgstr "次序" + +#: lib/perl5/Selima/List.pm:176 lib/perl5/Selima/List/Pages.pm:32 +msgid "Page path" +msgstr "网页路径" + +#: lib/perl5/Selima/List.pm:177 +msgid "Picture" +msgstr "图片" + +#: lib/perl5/Selima/List.pm:178 +msgid "Pic. ratio" +msgstr "图片比例" + +#: lib/perl5/Selima/List.pm:179 +msgid "Pic. caption" +msgstr "图片标题" + +#: lib/perl5/Selima/List.pm:180 +msgid "Pic. position" +msgstr "图片位置" + +#: lib/perl5/Selima/List.pm:181 +msgid "Title" +msgstr "标题" + +#: lib/perl5/Selima/List.pm:182 +msgid "English title" +msgstr "英文标题" + +#: lib/perl5/Selima/List.pm:183 +msgid "URL." +msgstr "网址" + +#: lib/perl5/Selima/List.pm:184 +msgid "Status (slow)" +msgstr "状态(慢)" + +#: lib/perl5/Selima/List.pm:423 +msgid "Nothing found. Please try another query." +msgstr "查无相符的资料,请重新搜寻。" + +#: lib/perl5/Selima/List.pm:426 +msgid "The database is empty." +msgstr "现无任何资料。" + +#: lib/perl5/Selima/List.pm:432 +msgid "Your query found [*,_1,record]." +msgstr "共 [#,_1] 笔相符的资料。" + +#: lib/perl5/Selima/List.pm:435 +msgid "[*,_1,record]." +msgstr "共 [#,_1] 笔资料。" + +#: lib/perl5/Selima/List.pm:441 +msgid "Your query found [*,_1,record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的资料,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List.pm:445 +msgid "[*,_1,record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔资料,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List.pm:456 +msgid "First" +msgstr "第一页" + +#: lib/perl5/Selima/List.pm:457 +msgid "Previous" +msgstr "前一页" + +#: lib/perl5/Selima/List.pm:458 +msgid "Next" +msgstr "下一页" + +#: lib/perl5/Selima/List.pm:459 +msgid "Last" +msgstr "最末页" + +#: lib/perl5/Selima/List.pm:502 +msgid "Picture unavailable" +msgstr "图片无法显示" + +#: lib/perl5/Selima/List.pm:530 +msgid "Page number ([_1]) invalid. Please specify a valid page number." +msgstr "页数([_1])无效,请设成有效的数字。" + +#: lib/perl5/Selima/List.pm:536 +msgid "" +"Page number ([#,_1]) out of range. Please specify between 1 and [#,_2]." +msgstr "页数([#,_1])超出范围,请设在 1 到 [#,_2] 之间。" + +#: lib/perl5/Selima/List.pm:613 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:61 +msgid "Please fill in your query." +msgstr "请填上查询的内容。" + +#: lib/perl5/Selima/List.pm:749 lib/perl5/Selima/List.pm:759 +msgid "You cannot sort by \"[_1]\"." +msgstr "无法以「 [_1] 」排序。" + +#: lib/perl5/Selima/List.pm:1082 +#: lib/perl5/Selima/List/Accounting/Reports.pm:412 +msgid "Search" +msgstr "搜寻" + +#: lib/perl5/Selima/List.pm:1181 +msgid "Index" +msgstr "目录" + +#: lib/perl5/Selima/List.pm:1319 +msgid "Page:" +msgstr "页:" + +#: lib/perl5/Selima/List.pm:1320 lib/perl5/Selima/List.pm:1392 +#: lib/perl5/Selima/List.pm:1449 +msgid "View" +msgstr "浏览" + +#: lib/perl5/Selima/List.pm:1364 lib/perl5/Selima/List.pm:1476 +msgid "Delete the selected items." +msgstr "删除勾选的项目。" + +#: lib/perl5/Selima/List.pm:1389 +msgid "No." +msgstr "编号" + +#: lib/perl5/Selima/List.pm:1500 +#: lib/perl5/Selima/List/Accounting/Reports.pm:587 +msgid "Set" +msgstr "设定" + +#: lib/perl5/Selima/List.pm:1521 +#: lib/perl5/Selima/List/Accounting/Reports.pm:604 +msgid "Rows per page:" +msgstr "每页显示笔数:" + +#: lib/perl5/Selima/List.pm:1529 +msgid "Display columns:" +msgstr "显示栏位:" + +#: lib/perl5/Selima/List.pm:1564 +msgid "Malformed" +msgstr "格式错乱" + +#: lib/perl5/Selima/List.pm:1598 +msgid "OK" +msgstr "好" + +#: lib/perl5/Selima/List.pm:1598 +msgid "Unreachable" +msgstr "连不上" + +#: lib/perl5/Selima/LnInfo.pm:49 +msgid "Traditional Chinese" +msgstr "正体中文" + +#: lib/perl5/Selima/LnInfo.pm:59 +msgid "Simplified Chinese" +msgstr "简体中文" + +#: lib/perl5/Selima/LnInfo.pm:69 +msgid "English" +msgstr "英文" + +#: lib/perl5/Selima/LnInfo.pm:79 +msgid "Japanese" +msgstr "日文" + +#: lib/perl5/Selima/LnInfo.pm:89 +msgid "German" +msgstr "德文" + +#: lib/perl5/Selima/LnInfo.pm:242 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "切换到本页的%s版。" + +#: lib/perl5/Selima/PageFunc.pm:221 +msgid "Web pages" +msgstr "网页" + +#: lib/perl5/Selima/PageFunc.pm:222 +msgid "News" +msgstr "新闻" + +#: lib/perl5/Selima/PageFunc.pm:223 +msgid "Related links" +msgstr "相关连结" + +#: lib/perl5/Selima/PageFunc.pm:224 +msgid "Home page" +msgstr "首页" + +#: lib/perl5/Selima/PageFunc.pm:225 +msgid "Whole web site" +msgstr "整个网站" + +#: lib/perl5/Selima/Picture.pm:49 +msgid "Left-aligned" +msgstr "靠左" + +#: lib/perl5/Selima/Picture.pm:50 +msgid "Right-aligned" +msgstr "靠右" + +#: lib/perl5/Selima/Picture.pm:87 +#, c-format +msgid "Width: [#,_1], height: [#,_2], ratio: [sprintf,%0.2f,_3]" +msgstr "宽: [#,_1] ,高: [#,_2] ,比例: [sprintf,%0.2f,_3]" + +#: lib/perl5/Selima/Picture.pm:113 +msgid "Please specify a numeric ratio." +msgstr "比例请设定数字。" + +#: lib/perl5/Selima/Picture.pm:116 +msgid "Please specify a positive ratio." +msgstr "比例请设定正数。" + +#: lib/perl5/Selima/Picture.pm:118 +#, c-format +msgid "Please specify a ratio less than or equal to [sprintf,%0.2f,_1]." +msgstr "比例请勿大於 [sprintf,%0.2f,_1] 。" + +#: lib/perl5/Selima/Picture.pm:122 +msgid "This image is too large to display." +msgstr "图片太大,无法显示。" + +#: lib/perl5/Selima/Preview.pm:53 lib/perl5/Selima/Preview.pm:115 +msgid "Unknown preview source: \"[_1]\"." +msgstr "预览资料源不明:「 [_1] 」。" + +#: lib/perl5/Selima/Preview.pm:69 +msgid "Unknown preview form: \"[_1]\"." +msgstr "预览表格不明: [_1] 。" + +#: lib/perl5/Selima/Preview.pm:126 +msgid "Preview" +msgstr "预览" + +#: lib/perl5/Selima/Preview.pm:127 +msgid "Finish preview and return." +msgstr "结束预览回前页。" + +#: lib/perl5/Selima/Processor.pm:203 +msgid "This record was not modified." +msgstr "资料未异动。" + +#: lib/perl5/Selima/Processor.pm:207 +msgid "This record has been successfully added." +msgstr "资料建好了。" + +#: lib/perl5/Selima/Processor.pm:211 +msgid "This record has been successfully updated." +msgstr "资料存好了。" + +#: lib/perl5/Selima/Processor.pm:215 +msgid "This record has been successfully deleted." +msgstr "资料删掉了。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:41 +msgid "Please select a accounting transaction." +msgstr "请选择会计传票。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:44 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "查无此会计传票,请重新选择。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:62 +msgid "This option is invalid. Please select a proper type." +msgstr "类型选项无效,请由表上选择适当的类型。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:83 +msgid "Please select a accounting subject." +msgstr "请选择会计科目。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:86 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "查无此会计科目,请重新选择。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:93 +msgid "" +"Only a last-level accounting subject is allowed for an accounting subject." +msgstr "限选最下层的会计科目。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:113 +msgid "This summary is too long. (Max. length [#,_1])" +msgstr "摘要太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/AcctRec.pm:137 +msgid "Please fill in the amount." +msgstr "请填上金额。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:140 +msgid "This amount is too long. (Max. length [#,_1])" +msgstr "金额太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/AcctRec.pm:144 +msgid "Please fill in a positive integer amount." +msgstr "金额请填正整数。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:39 +msgid "Please fill in the code." +msgstr "请填上代码。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:42 +msgid "This code is too long. (Max. length [#,_1])" +msgstr "代码太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:46 +msgid "Only numbers are allowed for the code." +msgstr "代码限用数字。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:56 +msgid "" +"This accounting subject already exists. You cannot create a duplicated one." +msgstr "已有该会计科目,请勿重复建档。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:65 +msgid "" +"Accounting subject [_1] does not exist. You cannot create a subject under " +"that." +msgstr "查无会计科目 [_1] ,请勿建立其下的科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:80 +#: lib/perl5/Selima/Checker/AcctSubj.pm:101 +msgid "Please select a parent accounting subject." +msgstr "请选择所属的大会计科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:85 +msgid "" +"This option is invalid. Please select a proper parent accounting subject." +msgstr "大会计科目选项无效,请由表上选择适当的大会计科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:92 +msgid "" +"An accounting subject having its code with a single digit must not have a " +"parent." +msgstr "会计科目代码一位数时,不可设所属的大会计科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:104 +msgid "" +"An accounting subject cannot belong to itself. Please select another one." +msgstr "科目不可属於自己本身,请重新选择。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:108 +msgid "" +"This parent accounting subject does not exist anymore. Please select " +"another one." +msgstr "查无此大会计科目,请重新选择。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:113 +msgid "" +"The parent accounting subject of accounting subject [_1] must be of code " +"[_2], not [_3]." +msgstr "会计科目 [_1] 所属的大会计科目代码须为 [_2] ,不可为 [_3] 。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:122 +msgid "" +"An accounting subject having its code with more than one digit must have a " +"parent." +msgstr "会计科目代码两位数或以上时,须设所属的大会计科目。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:53 +msgid "This form suptype is invalid. Please specify a proper user." +msgstr "子表单无效,请设定适当的子表单。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:73 +msgid "Please fill in the credit side of the accounting transaction." +msgstr "请填上会计传票的贷方。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:75 +#: lib/perl5/Selima/Checker/AcctTrx.pm:98 +msgid "Please fill in the accounting transaction content." +msgstr "请填上会计传票内容。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:96 +msgid "Please fill in the debit side of the accounting transaction." +msgstr "请填上会计传票的借方。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:162 +msgid "" +"The total amounts of the debit side and the credit side are not balanced " +"(debit [_1], credit [_2]." +msgstr "借方和贷方总金额未平衡。(借方合计 [_1] ,贷方合计 [_2] )" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:182 +#: lib/perl5/Selima/Form/AcctTrx.pm:802 +msgid "Fill in the note here." +msgstr "请填上注记。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:185 +msgid "This note is too long. (Max. length [#,_1])" +msgstr "注记太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/GroupMem.pm:54 +msgid "Please select a different belonging group." +msgstr "隶属群组请选择别的群组。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:74 +#: lib/perl5/Selima/Checker/UserMem.pm:59 +msgid "Please select a member." +msgstr "请选择成员。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:77 +#: lib/perl5/Selima/Checker/UserMem.pm:62 +msgid "This member does not exist anymore. Please select another one." +msgstr "查无此成员,请重新选择。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:80 +msgid "Please select a different group member." +msgstr "群组成员请选择别的群组。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:103 +#: lib/perl5/Selima/Checker/UserMem.pm:83 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "已有同一成员关系,请勿重复建档。" + +#: lib/perl5/Selima/Checker/Group.pm:45 +msgid "Please fill in the group ID." +msgstr "请填上群组代号。" + +#: lib/perl5/Selima/Checker/Group.pm:48 +msgid "This group ID. is too long. (Max. length [#,_1])" +msgstr "群组代号太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Group.pm:51 +msgid "This group ID. is too short. (Min. length [#,_1])" +msgstr "群组代号太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/Group.pm:55 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "群组代号限用小写英文字母、数字和底线。" + +#: lib/perl5/Selima/Checker/Group.pm:65 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "已有同一群组,请勿重复建档。" + +#: lib/perl5/Selima/Checker/Group.pm:83 +msgid "Please fill in the privilege description." +msgstr "请填上权限说明。" + +#: lib/perl5/Selima/Checker/Group.pm:86 +msgid "This privilege description is too long. (Max. length [#,_1])" +msgstr "权限说明太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:38 +#: lib/perl5/Selima/Checker/Guestbook.pm:60 +msgid "This signature is too long. (Max. length [#,_1])" +msgstr "签名太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:57 +msgid "Please fill in the signature." +msgstr "请填上签名。" + +#: lib/perl5/Selima/Checker/Guestbook.pm:79 +msgid "This identity is too long. (Max. length [#,_1])" +msgstr "身份太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:98 +msgid "This location is too long. (Max. length [#,_1])" +msgstr "所在地太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:117 +#: lib/perl5/Selima/Checker/Link.pm:92 lib/perl5/Selima/Checker/User.pm:229 +msgid "This e-mail is too long. (Max. length [#,_1])" +msgstr "E-mail 信箱太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:136 +msgid "This website URL is too long. (Max. length [#,_1])" +msgstr "网站网址太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/LinkCat.pm:40 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "「 index 」为目录档 index.html 专用,代号不可设为「 index 」。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:56 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "已有同一分类,请勿重复建档。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:70 +#: lib/perl5/Selima/Checker/LinkCat.pm:85 +msgid "Please select a parent category." +msgstr "请选择所属的大类。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:75 +msgid "This option is invalid. Please select a proper parent category." +msgstr "大类选项无效,请由表上选择适当的大类。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:88 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "查无此大类,请重新选择。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:92 +msgid "A category cannot belong to itself. Please select another one." +msgstr "分类不可属於自己本身,请重新选择。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:99 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "分类不可属於自己的子类,请重新选择。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:56 lib/perl5/Selima/Checker/Link.pm:72 +msgid "Please select a category." +msgstr "请选择分类。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:59 lib/perl5/Selima/Checker/Link.pm:67 +msgid "This category does not exist anymore. Please select another one." +msgstr "查无此分类,请重新选择。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:77 +msgid "Please select a related link." +msgstr "请选择相关连结。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:80 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查无此相关连结,请重新选择。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:101 +msgid "" +"This categorization record already exists. You cannot create a duplicated " +"one." +msgstr "已有同一分类资料,请勿重复建档。" + +#: lib/perl5/Selima/Checker/Link.pm:44 +msgid "This address is too long. (Max. length [#,_1])" +msgstr "地址太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:64 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "分类重复,请勿重复设定。" + +#: lib/perl5/Selima/Checker/Link.pm:95 lib/perl5/Selima/Checker/User.pm:232 +msgid "This e-mail is too short. (Min. length [#,_1])" +msgstr "E-mail 信箱太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:99 lib/perl5/Selima/Checker/MailTo.pm:36 +#: lib/perl5/Selima/Checker/User.pm:236 +msgid "Please fill in a valid e-mail address." +msgstr "请填上正确的 E-mail 信箱。" + +#: lib/perl5/Selima/Checker/Link.pm:101 lib/perl5/Selima/Checker/MailTo.pm:38 +#: lib/perl5/Selima/Checker/User.pm:238 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "查无这个信箱的所属网域,请检查有没有拼错。" + +#: lib/perl5/Selima/Checker/Link.pm:122 +msgid "This facsimile number is too long. (Max. length [#,_1])" +msgstr "传真号码太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:143 +msgid "This link icon URL is too long. (Max. length [#,_1])" +msgstr "连结小图网址太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:147 +msgid "Please fill in a valid link icon URL." +msgstr "请填上正确的连结小图网址。" + +#: lib/perl5/Selima/Checker/Link.pm:150 +msgid "This link icon URL is not reachable. Check if there is any typo in it." +msgstr "连结小图连不上,请检查有没有拼错。" + +#: lib/perl5/Selima/Checker/Link.pm:171 +msgid "This telephone number is too long. (Max. length [#,_1])" +msgstr "电话号码太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:192 +msgid "This 2nd language title is too long. (Max. length [#,_1])" +msgstr "第二语言标题太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:211 +msgid "Please fill in the URL." +msgstr "请填上网址。" + +#: lib/perl5/Selima/Checker/Link.pm:214 +msgid "This URL is too long. (Max. length [#,_1])" +msgstr "网址太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:218 +msgid "Please fill in a valid URL." +msgstr "请填上正确的网址。" + +#: lib/perl5/Selima/Checker/Link.pm:228 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "已有同一相关连结,请勿重复建档。" + +#: lib/perl5/Selima/Checker/Link.pm:231 +msgid "This URL is not reachable. Check if there is any typo in it." +msgstr "这个网址连不上,请检查有没有拼错。" + +#: lib/perl5/Selima/Checker/ListPref.pm:42 +#: lib/perl5/Selima/Checker/UserPref.pm:88 +msgid "Please fill in the preference domain." +msgstr "请填上偏好的适用范围。" + +#: lib/perl5/Selima/Checker/ListPref.pm:45 +#: lib/perl5/Selima/Checker/UserPref.pm:91 +msgid "This preference domain is too long. (Max. length [#,_1])" +msgstr "偏好适用范围太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/ListPref.pm:90 +msgid "Please fill in the number of rows per page." +msgstr "请填上每页显示笔数。" + +#: lib/perl5/Selima/Checker/ListPref.pm:93 +msgid "Please fill in a positive integer number of rows per page." +msgstr "每页显示笔数请填正整数。" + +#: lib/perl5/Selima/Checker/ListPref.pm:100 +msgid "This number of rows per page is too long. (Max. length [#,_1])" +msgstr "每页显示笔数太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/LogIn.pm:63 +msgid "Please fill in your user ID." +msgstr "请填上你的帐号。" + +#: lib/perl5/Selima/Checker/LogIn.pm:70 lib/perl5/Selima/Checker/LogIn.pm:76 +#: lib/perl5/Selima/Checker/LogIn.pm:91 lib/perl5/Selima/Checker/LogIn.pm:136 +#: lib/perl5/Selima/Checker/LogIn.pm:142 lib/perl5/Selima/Checker/LogIn.pm:151 +#: lib/perl5/Selima/Checker/LogIn.pm:178 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "登入错误,使用者代号或密码有误。" + +#: lib/perl5/Selima/Checker/LogIn.pm:109 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "帐号停用中,请洽系统管理员。" + +#: lib/perl5/Selima/Checker/LogIn.pm:129 +msgid "Please fill in your password." +msgstr "请填上你的密码。" + +#: lib/perl5/Selima/Checker/LogIn.pm:199 +msgid "You are not an administrator and cannot log into here." +msgstr "非管理员勿入。" + +#: lib/perl5/Selima/Checker/LogIn.pm:218 +msgid "You are an administrator and cannot log into here." +msgstr "管理人员勿入。" + +#: lib/perl5/Selima/Checker/MailTo.pm:29 lib/perl5/Selima/Checker/User.pm:226 +msgid "Please fill in the e-mail." +msgstr "请填上 E-mail 信箱。" + +#: lib/perl5/Selima/Checker/Rebuild.pm:28 +msgid "Please select the type." +msgstr "请选择类型。" + +#: lib/perl5/Selima/Checker/Rebuild.pm:31 +msgid "This type does not exist anymore. Please select another one." +msgstr "查无此类型,请重新选择。" + +#: lib/perl5/Selima/Checker/ScptPriv.pm:63 +msgid "" +"This script privilege record already exists. You cannot create a duplicated " +"one." +msgstr "已有同一程式权限资料,请勿重复建档。" + +#: lib/perl5/Selima/Checker/User.pm:85 +msgid "Please fill in the user ID." +msgstr "请填上帐号。" + +#: lib/perl5/Selima/Checker/User.pm:88 +msgid "This user ID. is too long. (Max. length [#,_1])" +msgstr "帐号太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:91 +msgid "This user ID. is too short. (Min. length [#,_1])" +msgstr "帐号太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:95 +msgid "" +"Only English letters, numbers, at-signs, dots, dashes and underscores are " +"allowed for the user ID." +msgstr "帐号限用英文字母、数字、 @ 号、点、横线和底线。" + +#: lib/perl5/Selima/Checker/User.pm:105 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "该使用者已有帐号,请勿重复建档。" + +#: lib/perl5/Selima/Checker/User.pm:129 +msgid "Please fill in the password." +msgstr "请填上密码。" + +#: lib/perl5/Selima/Checker/User.pm:131 +msgid "Please confirm the password." +msgstr "请确认密码。" + +#: lib/perl5/Selima/Checker/User.pm:134 +msgid "This password is too long. (Max. length [#,_1])" +msgstr "密码太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:137 +msgid "This password is too short. (Min. length [#,_1])" +msgstr "密码太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:142 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "两次密码不合,请重新设定密码。" + +#: lib/perl5/Selima/Checker/User.pm:151 +msgid "This password is based on the user ID." +msgstr "密码不可由帐号组成。" + +#: lib/perl5/Selima/Checker/User.pm:166 +msgid "This password does not contain enough different characters." +msgstr "密码重复的字元太多。" + +#: lib/perl5/Selima/Checker/User.pm:170 +msgid "This password is too simplistic/systematic." +msgstr "密码结构太简单。" + +#: lib/perl5/Selima/Checker/User.pm:174 +msgid "This password is based on a dictionary word." +msgstr "密码不可由字典单字组成。" + +#: lib/perl5/Selima/Checker/User.pm:176 +msgid "This password is based on a (reversed) dictionary word." +msgstr "密码不可由倒过来的字典单字组成。" + +#: lib/perl5/Selima/Checker/User.pm:178 +msgid "This password is too simple." +msgstr "密码太简单。" + +#: lib/perl5/Selima/Checker/User.pm:183 +msgid "You cannot use a password that is based on your user ID." +msgstr "密码不可由帐号组成。" + +#: lib/perl5/Selima/Checker/User.pm:203 +msgid "Please fill in the name." +msgstr "请填上姓名。" + +#: lib/perl5/Selima/Checker/User.pm:206 +msgid "This name is too long. (Max. length [#,_1])" +msgstr "姓名太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:259 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "隶属群组重复,请勿重复设定。" + +#: lib/perl5/Selima/Checker/User.pm:271 +msgid "You cannot submit the super-user group along with other groups." +msgstr "总管理员群组不可与其它群组一起设定。" + +#: lib/perl5/Selima/Checker/User.pm:273 +msgid "You cannot set the administrators group." +msgstr "不可设定所有网站管理员群组" + +#: lib/perl5/Selima/Checker/User.pm:275 +msgid "You cannot set the all-users group." +msgstr "不可设定所有登入使用者群组。" + +#: lib/perl5/Selima/Checker/UserPref.pm:50 +msgid "Please select the user." +msgstr "请选择使用者。" + +#: lib/perl5/Selima/Checker/UserPref.pm:55 +msgid "This option is invalid. Please select a proper user." +msgstr "使用者选项无效,请由表上选择适当的使用者。" + +#: lib/perl5/Selima/Checker/UserPref.pm:73 +msgid "Please set the preference domain." +msgstr "请设定适用范围。" + +#: lib/perl5/Selima/Checker/UserPref.pm:78 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "适用范围选项无效,请设定适当的适用范围。" + +#: lib/perl5/Selima/Checker/UserPref.pm:111 +msgid "Please fill in the preference name." +msgstr "请填上偏好的名称。" + +#: lib/perl5/Selima/Checker/UserPref.pm:114 +msgid "This preference name is too long. (Max. length [#,_1])" +msgstr "偏好名称太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/UserPref.pm:133 +msgid "Please fill in the preference value." +msgstr "请填上偏好的值。" + +#: lib/perl5/Selima/Checker/UserPref.pm:136 +msgid "This preference value is too long. (Max. length [#,_1])" +msgstr "偏好值太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/UserPref.pm:167 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "已有同一使用者偏好,请勿重复建档。" + +#: lib/perl5/Selima/Form/AcctRec.pm:33 +msgid "Delete this accounting record" +msgstr "删掉这笔会计分录" + +#: lib/perl5/Selima/Form/AcctRec.pm:38 +msgid "This table provides you a form to add a new accounting record." +msgstr "本表提供建新会计分录的表单。" + +#: lib/perl5/Selima/Form/AcctRec.pm:41 +msgid "This table provides you a form to edit a current accounting record." +msgstr "本表提供编辑会计分录的表单。" + +#: lib/perl5/Selima/Form/AcctRec.pm:44 +msgid "This table provides you a form to delete an accounting record." +msgstr "本表提供删除会计分录的表单。" + +#: lib/perl5/Selima/Form/AcctRec.pm:61 +msgid "Add a New Accounting Record" +msgstr "建新会计分录。" + +#: lib/perl5/Selima/Form/AcctRec.pm:64 +msgid "Edit a Current Accounting Record" +msgstr "编辑会计分录" + +#: lib/perl5/Selima/Form/AcctRec.pm:67 +msgid "Delete an Accounting Record" +msgstr "删除会计分录" + +#: lib/perl5/Selima/Form/AcctRec.pm:76 +msgid "Accounting transaction:" +msgstr "会计传票:" + +#: lib/perl5/Selima/Form/AcctRec.pm:85 lib/perl5/Selima/Form/AcctTrx.pm:334 +#: lib/perl5/Selima/List/Accounting/Reports.pm:75 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:233 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:226 +msgid "Debit" +msgstr "借方" + +#: lib/perl5/Selima/Form/AcctRec.pm:87 lib/perl5/Selima/Form/AcctTrx.pm:335 +#: lib/perl5/Selima/List/Accounting/Reports.pm:76 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:237 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:230 +msgid "Credit" +msgstr "贷方" + +#: lib/perl5/Selima/Form/AcctRec.pm:88 lib/perl5/Selima/Form/Rebuild.pm:52 +msgid "Type:" +msgstr "类型:" + +#: lib/perl5/Selima/Form/AcctRec.pm:99 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:284 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:268 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:328 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:284 +msgid "Accounting subject:" +msgstr "会计科目:" + +#: lib/perl5/Selima/Form/AcctRec.pm:157 +msgid "Summary:" +msgstr "摘要:" + +#: lib/perl5/Selima/Form/AcctRec.pm:162 +msgid "Amount:" +msgstr "金额:" + +#: lib/perl5/Selima/Form/AcctSubj.pm:34 +msgid "Delete this accounting subject" +msgstr "删掉这个会计科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:39 +msgid "This table provides you a form to add a new accounting subject." +msgstr "本表提供建新会计科目的表单。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:42 +msgid "This table provides you a form to edit a current accounting subject." +msgstr "本表提供编辑会计科目的表单。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:45 +msgid "This table provides you a form to delete an accounting subject." +msgstr "本表提供删除会计科目的表单。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:62 +msgid "Add a New Accounting Subject" +msgstr "建新会计科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:65 +msgid "Edit a Current Accounting Subject" +msgstr "编辑会计科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:68 +msgid "Delete an Accounting Subject" +msgstr "删除会计科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:75 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the accounting " +"subject, [numerate,_1,its accounting sub-subject,all of its accounting sub-" +"subjects] must first be deleted." +msgstr "" +"本会计科目下有子会计科目,不可直接删除。要删除本科目,请先删除其下的子会计科" +"目。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:79 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the accounting subject, " +"[numerate,_1,its accounting record,all of its accounting records] must first " +"be deleted." +msgstr "" +"本会计科目下有会计分录,不可直接删除。要删除本会计科目,请先删除其下的会计分" +"录。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:87 +msgid "Code:" +msgstr "代码:" + +#: lib/perl5/Selima/Form/AcctSubj.pm:93 +msgid "Parent subject:" +msgstr "大科目:" + +#: lib/perl5/Selima/Form/AcctSubj.pm:106 +msgid "[numerate,_1,Sub-subject,Sub-subjects]:" +msgstr "子科目:" + +#: lib/perl5/Selima/Form/AcctTrx.pm:37 +msgid "Delete this accounting transaction" +msgstr "删掉这笔会计传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:43 +msgid "This table provides you a form to add a new accounting transaction." +msgstr "本表提供建新会计传票的表单。" + +#: lib/perl5/Selima/Form/AcctTrx.pm:46 +msgid "" +"This table provides you a form to edit a current accounting transaction." +msgstr "本表提供编辑会计传票的表单。" + +#: lib/perl5/Selima/Form/AcctTrx.pm:49 +msgid "This table provides you a form to delete an accounting transaction." +msgstr "本表提供删除会计传票的表单。" + +#: lib/perl5/Selima/Form/AcctTrx.pm:92 lib/perl5/Selima/Form/AcctTrx.pm:97 +msgid "Convert to a transfer transaction" +msgstr "转为转帐传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:102 +msgid "Add a New Cache Expense Transaction" +msgstr "建新现金支出传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:104 +msgid "Add a New Cache Income Transaction" +msgstr "建新现金收入传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:106 +msgid "Add a New Transfer Transaction" +msgstr "建新转帐传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:111 +msgid "Edit a Current Cache Expense Transaction" +msgstr "编辑现金支出传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:113 +msgid "Edit a Current Cache Income Transaction" +msgstr "编辑现金收入传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:115 +msgid "Edit a Current Transfer Transaction" +msgstr "编辑转帐传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:120 +msgid "Delete a Cache Expense Transaction" +msgstr "删除现金支出传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:122 +msgid "Delete a Cache Income Transaction" +msgstr "删除现金收入传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:124 +msgid "Delete a Transfer Transaction" +msgstr "删掉转帐传票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:336 +#: lib/perl5/Selima/List/Accounting/Records.pm:35 +#: lib/perl5/Selima/List/Accounting/Reports.pm:73 +msgid "Accounting subject" +msgstr "会计科目" + +#: lib/perl5/Selima/Form/AcctTrx.pm:337 +#: lib/perl5/Selima/List/Accounting/Records.pm:36 +#: lib/perl5/Selima/List/Accounting/Reports.pm:74 +msgid "Summary" +msgstr "摘要" + +#: lib/perl5/Selima/Form/AcctTrx.pm:338 +#: lib/perl5/Selima/List/Accounting/Records.pm:37 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:40 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:41 +msgid "Amount" +msgstr "金额" + +#: lib/perl5/Selima/Form/AcctTrx.pm:339 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:173 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:196 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:200 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:152 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:130 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:151 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:177 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:166 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:189 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:144 +msgid "Total" +msgstr "合计" + +#: lib/perl5/Selima/Form/AcctTrx.pm:379 lib/perl5/Selima/Form/AcctTrx.pm:518 +#: lib/perl5/Selima/Form/AcctTrx.pm:708 +msgid "[numerate,_1,Content]:" +msgstr "内容:" + +#: lib/perl5/Selima/Form/AcctTrx.pm:801 +msgid "Note:" +msgstr "注记:" + +#: lib/perl5/Selima/Form/GroupMem.pm:33 lib/perl5/Selima/Form/UserMem.pm:33 +msgid "Delete this membership record" +msgstr "删掉这笔成员关系" + +#: lib/perl5/Selima/Form/GroupMem.pm:38 lib/perl5/Selima/Form/UserMem.pm:38 +msgid "This table provides you a form to add a new membership record." +msgstr "本表提供建新成员关系的表单。" + +#: lib/perl5/Selima/Form/GroupMem.pm:41 lib/perl5/Selima/Form/UserMem.pm:41 +msgid "This table provides you a form to change a current membership record." +msgstr "本表提供变更成员关系的表单。" + +#: lib/perl5/Selima/Form/GroupMem.pm:44 lib/perl5/Selima/Form/UserMem.pm:44 +msgid "This table provides you a form to delete a membership record." +msgstr "本表提供删除成员关系的表单。" + +#: lib/perl5/Selima/Form/GroupMem.pm:61 +msgid "Add A New Group Membership Record" +msgstr "建新群组成员关系" + +#: lib/perl5/Selima/Form/GroupMem.pm:64 +msgid "Change a Current Group Membership Record" +msgstr "变更群组成员关系" + +#: lib/perl5/Selima/Form/GroupMem.pm:67 +msgid "Delete a Group Membership Record" +msgstr "删除群组成员关系" + +#: lib/perl5/Selima/Form/GroupMem.pm:76 lib/perl5/Selima/Form/UserMem.pm:76 +msgid "Member:" +msgstr "成员:" + +#: lib/perl5/Selima/Form/Group.pm:37 +msgid "Delete this group" +msgstr "删掉这个群组" + +#: lib/perl5/Selima/Form/Group.pm:42 +msgid "This table provides you a form to add a new group." +msgstr "本表提供建新群组的表单。" + +#: lib/perl5/Selima/Form/Group.pm:45 +msgid "This table provides you a form to update a current group." +msgstr "本表提供设定群组的表单。" + +#: lib/perl5/Selima/Form/Group.pm:48 +msgid "This table provides you a form to delete a group." +msgstr "本表提供删除群组的表单。" + +#: lib/perl5/Selima/Form/Group.pm:65 +msgid "Add a New Group" +msgstr "建新群组" + +#: lib/perl5/Selima/Form/Group.pm:68 +msgid "Update a Current Group" +msgstr "设定群组" + +#: lib/perl5/Selima/Form/Group.pm:71 +msgid "Delete a Group" +msgstr "删除群组" + +#: lib/perl5/Selima/Form/Group.pm:77 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "这是最高管理员的群组,你只能设定它部份的资料。" + +#: lib/perl5/Selima/Form/Group.pm:89 lib/perl5/Selima/Form/Group.pm:91 +msgid "Group ID.:" +msgstr "群组代号:" + +#: lib/perl5/Selima/Form/Group.pm:110 +msgid "Add a user" +msgstr "增加成员" + +#: lib/perl5/Selima/Form/Group.pm:114 lib/perl5/Selima/Form/Group.pm:148 +#: lib/perl5/Selima/Form/Group.pm:164 lib/perl5/Selima/Form/Group.pm:211 +msgid "[numerate,_1,User member]:" +msgstr "使用者成员:" + +#: lib/perl5/Selima/Form/Group.pm:239 lib/perl5/Selima/Form/Group.pm:369 +msgid "Add a group" +msgstr "增加群组" + +#: lib/perl5/Selima/Form/Group.pm:243 lib/perl5/Selima/Form/Group.pm:277 +#: lib/perl5/Selima/Form/Group.pm:293 lib/perl5/Selima/Form/Group.pm:340 +msgid "[numerate,_1,Group member]:" +msgstr "群组成员:" + +#: lib/perl5/Selima/Form/Group.pm:368 lib/perl5/Selima/Form/User.pm:223 +msgid "Belonging to:" +msgstr "隶属群组:" + +#: lib/perl5/Selima/Form/Guestbook.pm:32 +msgid "Delete this message" +msgstr "删掉这则留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:37 +msgid "This table provides you a form to add a new message." +msgstr "本表提供写新留言的表单。" + +#: lib/perl5/Selima/Form/Guestbook.pm:40 +msgid "This table provides you a form to edit a current message." +msgstr "本表提供编辑留言的表单。" + +#: lib/perl5/Selima/Form/Guestbook.pm:43 +msgid "This table provides you a form to delete a message." +msgstr "本表提供删除留言的表单。" + +#: lib/perl5/Selima/Form/Guestbook.pm:61 +msgid "Write a New Message" +msgstr "写新留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:64 +msgid "Edit a Current Message" +msgstr "编辑留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:67 +msgid "Delete a Message" +msgstr "删除留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:77 lib/perl5/Selima/Form/User.pm:149 +msgid "Country:" +msgstr "国家:" + +#: lib/perl5/Selima/Form/Guestbook.pm:83 +msgid "Hide this message" +msgstr "隐藏这则留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:83 +msgid "Show this message" +msgstr "秀出这则留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:84 +msgid "Hide this message currently." +msgstr "暂勿秀出这则留言。" + +#: lib/perl5/Selima/Form/Guestbook.pm:89 +msgid "Signature:" +msgstr "签名:" + +#: lib/perl5/Selima/Form/Guestbook.pm:94 +msgid "Old page no.:" +msgstr "旧页数:" + +#: lib/perl5/Selima/Form/Guestbook.pm:99 +msgid "Page no.:" +msgstr "页数:" + +#: lib/perl5/Selima/Form/LinkCat.pm:33 +msgid "Delete this category" +msgstr "删掉这个分类" + +#: lib/perl5/Selima/Form/LinkCat.pm:38 +msgid "This table provides you a form to add a new category." +msgstr "本表提供建新分类的表单。" + +#: lib/perl5/Selima/Form/LinkCat.pm:41 +msgid "This table provides you a form to edit a current category." +msgstr "本表提供编辑分类的表单。" + +#: lib/perl5/Selima/Form/LinkCat.pm:44 +msgid "This table provides you a form to delete a category." +msgstr "本表提供删除分类的表单。" + +#: lib/perl5/Selima/Form/LinkCat.pm:62 +msgid "Add a New Link Category" +msgstr "建新连结分类" + +#: lib/perl5/Selima/Form/LinkCat.pm:65 +msgid "Edit a Current Link Category" +msgstr "编辑连结分类" + +#: lib/perl5/Selima/Form/LinkCat.pm:68 +msgid "Delete a Link Category" +msgstr "删除连结分类" + +#: lib/perl5/Selima/Form/LinkCat.pm:76 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分类下有子类,不可直接删除。要删除本分类,请先删除其下的子类。" + +#: lib/perl5/Selima/Form/LinkCat.pm:80 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分类下有连结,不可直接删除。要删除本分类,请先删除其下的连结。" + +#: lib/perl5/Selima/Form/LinkCat.pm:89 +msgid "Hide this category" +msgstr "隐藏这个分类" + +#: lib/perl5/Selima/Form/LinkCat.pm:89 +msgid "Show this category" +msgstr "秀出这个分类" + +#: lib/perl5/Selima/Form/LinkCat.pm:90 +msgid "Hide this category currently." +msgstr "暂勿秀出这个分类。" + +#: lib/perl5/Selima/Form/LinkCat.pm:106 +msgid "[numerate,_1,Link,Links]:" +msgstr "连结:" + +#: lib/perl5/Selima/Form/LinkCatz.pm:33 +msgid "Delete this categorization record" +msgstr "删掉这笔分类资料" + +#: lib/perl5/Selima/Form/LinkCatz.pm:38 +msgid "This table provides you a form to add a new categorization record." +msgstr "本表提供建新分类资料的表单。" + +#: lib/perl5/Selima/Form/LinkCatz.pm:41 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "本表提供变更分类资料的表单。" + +#: lib/perl5/Selima/Form/LinkCatz.pm:44 +msgid "This table provides you a form to delete a categorization record." +msgstr "本表提供删除分类资料的表单。" + +#: lib/perl5/Selima/Form/LinkCatz.pm:61 +msgid "Add A New Link Categorization Record" +msgstr "建新连结分类资料" + +#: lib/perl5/Selima/Form/LinkCatz.pm:64 +msgid "Change a Current Link Categorization Record" +msgstr "变更连结分类资料" + +#: lib/perl5/Selima/Form/LinkCatz.pm:67 +msgid "Delete a Link Categorization Record" +msgstr "删除连结分类资料" + +#: lib/perl5/Selima/Form/LinkCatz.pm:76 +msgid "Category:" +msgstr "分类:" + +#: lib/perl5/Selima/Form/LinkCatz.pm:81 +msgid "Link:" +msgstr "连结:" + +#: lib/perl5/Selima/Form/Link.pm:35 +msgid "Delete this related link" +msgstr "删掉这笔相关连结" + +#: lib/perl5/Selima/Form/Link.pm:40 +msgid "This table provides you a form to add a new related link." +msgstr "本表提供建新相关连结的表单。" + +#: lib/perl5/Selima/Form/Link.pm:43 +msgid "This table provides you a form to edit a current related link." +msgstr "本表提供编辑相关连结的表单。" + +#: lib/perl5/Selima/Form/Link.pm:46 +msgid "This table provides you a form to delete a related link." +msgstr "本表提供删除相关连结的表单。" + +#: lib/perl5/Selima/Form/Link.pm:65 +msgid "Add a New Related Link" +msgstr "建新相关连结" + +#: lib/perl5/Selima/Form/Link.pm:68 +msgid "Edit a Current Related Link" +msgstr "编辑相关连结" + +#: lib/perl5/Selima/Form/Link.pm:71 +msgid "Delete a Related Link" +msgstr "删除相关连结" + +#: lib/perl5/Selima/Form/Link.pm:81 +msgid "[numerate,_1,Category,Categories]:" +msgstr "分类:" + +#: lib/perl5/Selima/Form/Link.pm:88 +msgid "Hide this related link" +msgstr "隐藏这笔相关连结" + +#: lib/perl5/Selima/Form/Link.pm:88 +msgid "Show this related link" +msgstr "秀出这笔相关连结" + +#: lib/perl5/Selima/Form/Link.pm:89 +msgid "Hide this related link currently." +msgstr "暂勿秀出这笔相关连结。" + +#: lib/perl5/Selima/Form/Link.pm:100 +msgid "Link icon:" +msgstr "连结小图:" + +#: lib/perl5/Selima/Form/Link.pm:101 +msgid "Link icon unavailable" +msgstr "连结小图无法显示" + +#: lib/perl5/Selima/Form/Link.pm:173 +msgid "2nd language title:" +msgstr "第二语言标题:" + +#: lib/perl5/Selima/Form/Page.pm:32 +msgid "Delete this page" +msgstr "删掉这一页" + +#: lib/perl5/Selima/Form/Page.pm:37 +msgid "This table provides you a form to write a new page." +msgstr "本表提供写新网页的表单。" + +#: lib/perl5/Selima/Form/Page.pm:40 +msgid "This table provides you a form to edit a current page." +msgstr "本表提供编辑网页的表单。" + +#: lib/perl5/Selima/Form/Page.pm:43 +msgid "This table provides you a form to delete a page." +msgstr "本表提供删除网页的表单。" + +#: lib/perl5/Selima/Form/Page.pm:60 +msgid "Write a New Page" +msgstr "写新网页" + +#: lib/perl5/Selima/Form/Page.pm:63 +msgid "Edit a Current Page" +msgstr "编辑网页" + +#: lib/perl5/Selima/Form/Page.pm:66 +msgid "Delete a Page" +msgstr "删除网页" + +#: lib/perl5/Selima/Form/Page.pm:73 +msgid "Preview this page." +msgstr "预览本页。" + +#: lib/perl5/Selima/Form/Page.pm:82 +msgid "Hide this page" +msgstr "隐藏这页网页" + +#: lib/perl5/Selima/Form/Page.pm:82 +msgid "Show this page" +msgstr "秀出这页网页" + +#: lib/perl5/Selima/Form/Page.pm:83 +msgid "Hide this page currently." +msgstr "暂勿秀出这页网页。" + +#: lib/perl5/Selima/Form/Rebuild.pm:36 +msgid "Rebuild the Pages" +msgstr "重制网页" + +#: lib/perl5/Selima/Form/Rebuild.pm:41 +msgid "Confirm" +msgstr "确定" + +#: lib/perl5/Selima/Form/ScptPriv.pm:33 +msgid "Delete this script privilege record" +msgstr "删掉这笔程式权限资料" + +#: lib/perl5/Selima/Form/ScptPriv.pm:38 +msgid "This table provides you a form to add a new script privilege record." +msgstr "本表提供建新程式权限资料的表单。" + +#: lib/perl5/Selima/Form/ScptPriv.pm:41 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "本表提供变更程式权限资料的表单。" + +#: lib/perl5/Selima/Form/ScptPriv.pm:44 +msgid "This table provides you a form to delete a script privilege record." +msgstr "本表提供删除程式权限资料的表单。" + +#: lib/perl5/Selima/Form/ScptPriv.pm:61 +msgid "Add A New Script Privilege Record" +msgstr "建新程式权限资料" + +#: lib/perl5/Selima/Form/ScptPriv.pm:64 +msgid "Change a Current Script Privilege Record" +msgstr "变更程式权限资料" + +#: lib/perl5/Selima/Form/ScptPriv.pm:67 +msgid "Delete a Script Privilege Record" +msgstr "删除程式权限资料" + +#: lib/perl5/Selima/Form/ScptPriv.pm:76 +msgid "Privilege:" +msgstr "权限:" + +#: lib/perl5/Selima/Form/UserMem.pm:61 +msgid "Add A New User Membership Record" +msgstr "建新使用者成员关系" + +#: lib/perl5/Selima/Form/UserMem.pm:64 +msgid "Change a Current User Membership Record" +msgstr "变更使用者成员关系" + +#: lib/perl5/Selima/Form/UserMem.pm:67 +msgid "Delete a User Membership Record" +msgstr "删除使用者成员关系" + +#: lib/perl5/Selima/Form/User.pm:39 +msgid "Delete this user account" +msgstr "删掉这个帐号" + +#: lib/perl5/Selima/Form/User.pm:46 +msgid "This table provides you a form to add a new user account." +msgstr "本表提供建新帐号的表单。" + +#: lib/perl5/Selima/Form/User.pm:49 +msgid "This table provides you a form to update a current user account." +msgstr "本表提供设定帐号的表单。" + +#: lib/perl5/Selima/Form/User.pm:52 +msgid "This table provides you a form to delete a user account." +msgstr "本表提供删除帐号的表单。" + +#: lib/perl5/Selima/Form/User.pm:70 +msgid "Add a New User Account" +msgstr "建新帐号" + +#: lib/perl5/Selima/Form/User.pm:73 +msgid "Update a Current User Account" +msgstr "设定帐号" + +#: lib/perl5/Selima/Form/User.pm:76 +msgid "Delete a User Account" +msgstr "删除帐号" + +#: lib/perl5/Selima/Form/User.pm:84 +msgid "This is a super-user. You can only change parts of her/his infomation." +msgstr "这个人是总管理员,你只能设定她/他部份的资料。" + +#: lib/perl5/Selima/Form/User.pm:143 +msgid "Administrator?" +msgstr "网站管理员?" + +#: lib/perl5/Selima/Form/User.pm:144 +msgid "Administrator" +msgstr "网站管理员" + +#: lib/perl5/Selima/Form/User.pm:144 +msgid "Non-administrator" +msgstr "普通使用者" + +#: lib/perl5/Selima/Form/User.pm:165 +msgid "Disable this user account." +msgstr "帐号停用。" + +#: lib/perl5/Selima/Form/User.pm:176 lib/perl5/Selima/Form/User.pm:178 +msgid "User ID.:" +msgstr "使用者代号:" + +#: lib/perl5/Selima/Form/User.pm:184 +msgid "Pref. language:" +msgstr "语言偏好:" + +#: lib/perl5/Selima/Form/User.pm:189 +msgid "Full name:" +msgstr "姓名:" + +#: lib/perl5/Selima/Form/UserPref.pm:35 +msgid "Delete this user preference" +msgstr "删掉这笔使用者偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:40 +msgid "This table provides you a form to add a new user preference." +msgstr "本表提供建新使用者偏好的表单。" + +#: lib/perl5/Selima/Form/UserPref.pm:43 +msgid "This table provides you a form to modify a current user preference." +msgstr "本表提供设定使用者偏好的表单。" + +#: lib/perl5/Selima/Form/UserPref.pm:46 +msgid "This table provides you a form to delete a user preference." +msgstr "本表提供删除使用者偏好的表单。" + +#: lib/perl5/Selima/Form/UserPref.pm:63 +msgid "Add A New User Preference" +msgstr "建新使用者偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:66 +msgid "Modify a Current User Preference" +msgstr "设定使用者偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:69 +msgid "Delete a User Preference" +msgstr "删除使用者偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:82 +msgid "Domain:" +msgstr "适用范围:" + +#: lib/perl5/Selima/Form/UserPref.pm:83 +msgid "Everywhere" +msgstr "所有地方" + +#: lib/perl5/Selima/Form/UserPref.pm:88 +msgid "User:" +msgstr "使用者:" + +#: lib/perl5/Selima/Form/UserPref.pm:89 +msgid "Everyone" +msgstr "所有人" + +#: lib/perl5/Selima/List/ActLog.pm:31 +msgid "Browse the Activity Log" +msgstr "查阅网站活动日志" + +#: lib/perl5/Selima/List/ActLog.pm:132 +msgid "Please fill in the number of rows to display." +msgstr "请填上显示笔数。" + +#: lib/perl5/Selima/List/ActLog.pm:135 +msgid "Please fill in a positive integer number of rows to display." +msgstr "显示笔数请填正整数。" + +#: lib/perl5/Selima/List/ActLog.pm:140 +msgid "This number of rows to display is too long. (Max. length [#,_1])" +msgstr "显示笔数太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/List/ActLog.pm:157 +msgid "Search for log entries:" +msgstr "搜寻记录:" + +#: lib/perl5/Selima/List/ActLog.pm:162 +msgid "Display" +msgstr "显示" + +#: lib/perl5/Selima/List/ActLog.pm:163 +msgid "Display rows:" +msgstr "显示笔数:" + +#: lib/perl5/Selima/List/ActLog.pm:198 +msgid "Your query found [*,_1,log entry,log entries]." +msgstr "共 [#,_1] 笔相符的记录。" + +#: lib/perl5/Selima/List/ActLog.pm:201 +msgid "[*,_1,log entry,log entries]." +msgstr "共 [#,_1] 笔记录。" + +#: lib/perl5/Selima/List/ActLog.pm:207 +msgid "" +"Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的记录,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/ActLog.pm:211 +msgid "[*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔记录,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Category.pm:18 +msgid "Add a new category." +msgstr "建新连结分类。" + +#: lib/perl5/Selima/List/Category.pm:24 +msgid "Search for a category:" +msgstr "搜寻分类:" + +#: lib/perl5/Selima/List/Category.pm:41 +msgid "Your query found [*,_1,category,categories]." +msgstr "共 [#,_1] 个相符的分类。" + +#: lib/perl5/Selima/List/Category.pm:44 +msgid "[*,_1,category,categories]." +msgstr "共 [#,_1] 个分类。" + +#: lib/perl5/Selima/List/Category.pm:50 +msgid "Your query found [*,_1,category,categories], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个相符的分类,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: lib/perl5/Selima/List/Category.pm:54 +msgid "[*,_1,category,categories], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个分类,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: lib/perl5/Selima/List/Categorz.pm:18 +msgid "Add a new categorization record." +msgstr "建新分类资料。" + +#: lib/perl5/Selima/List/Categorz.pm:24 +msgid "Search for a categorization record:" +msgstr "搜寻分类资料:" + +#: lib/perl5/Selima/List/Categorz.pm:41 +msgid "Your query found [*,_1,categorization record]." +msgstr "共 [#,_1] 笔相符的分类资料。" + +#: lib/perl5/Selima/List/Categorz.pm:44 +msgid "[*,_1,categorization record]." +msgstr "共 [#,_1] 笔分类资料。" + +#: lib/perl5/Selima/List/Categorz.pm:50 +msgid "" +"Your query found [*,_1,categorization record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的分类资料,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Categorz.pm:54 +msgid "[*,_1,categorization record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔分类资料,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/GroupMem.pm:24 +msgid "Select a Group Membership Record" +msgstr "选择群组成员关系" + +#: lib/perl5/Selima/List/GroupMem.pm:25 +msgid "Manage Group Membership" +msgstr "管理群组成员关系" + +#: lib/perl5/Selima/List/GroupMem.pm:30 lib/perl5/Selima/List/UserMem.pm:30 +msgid "Group" +msgstr "群组" + +#: lib/perl5/Selima/List/GroupMem.pm:31 lib/perl5/Selima/List/UserMem.pm:31 +msgid "Member" +msgstr "成员" + +#: lib/perl5/Selima/List/GroupMem.pm:39 lib/perl5/Selima/List/UserMem.pm:39 +msgid "Add a new membership record." +msgstr "建新成员关系。" + +#: lib/perl5/Selima/List/GroupMem.pm:45 lib/perl5/Selima/List/UserMem.pm:45 +msgid "Search for a membership record:" +msgstr "搜寻成员关系:" + +#: lib/perl5/Selima/List/GroupMem.pm:62 lib/perl5/Selima/List/UserMem.pm:62 +msgid "Your query found [*,_1,membership record]." +msgstr "共 [#,_1] 笔相符的成员关系。" + +#: lib/perl5/Selima/List/GroupMem.pm:65 lib/perl5/Selima/List/UserMem.pm:65 +msgid "[*,_1,membership record]." +msgstr "共 [#,_1] 笔成员关系。" + +#: lib/perl5/Selima/List/GroupMem.pm:71 lib/perl5/Selima/List/UserMem.pm:71 +msgid "Your query found [*,_1,membership record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的成员关系,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/GroupMem.pm:75 lib/perl5/Selima/List/UserMem.pm:75 +msgid "[*,_1,membership record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔成员关系,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Groups.pm:23 +msgid "Select a Group" +msgstr "选择群组" + +#: lib/perl5/Selima/List/Groups.pm:24 +msgid "Manage Groups" +msgstr "管理群组" + +#: lib/perl5/Selima/List/Groups.pm:29 +msgid "Group ID." +msgstr "群组代号" + +#: lib/perl5/Selima/List/Groups.pm:38 +msgid "Add a new group." +msgstr "建新群组。" + +#: lib/perl5/Selima/List/Groups.pm:44 +msgid "Search for a group:" +msgstr "搜寻群组:" + +#: lib/perl5/Selima/List/Groups.pm:61 +msgid "Your query found [*,_1,group]." +msgstr "共 [#,_1] 个相符的群组。" + +#: lib/perl5/Selima/List/Groups.pm:64 +msgid "[*,_1,group]." +msgstr "共 [#,_1] 个群组。" + +#: lib/perl5/Selima/List/Groups.pm:70 +msgid "Your query found [*,_1,group], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个相符的群组,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: lib/perl5/Selima/List/Groups.pm:74 +msgid "[*,_1,group], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个群组,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: lib/perl5/Selima/List/Guestbook.pm:26 +msgid "Select a Message" +msgstr "选择留言" + +#: lib/perl5/Selima/List/Guestbook.pm:27 +msgid "Manage Guestbook" +msgstr "管理留言簿" + +#: lib/perl5/Selima/List/Guestbook.pm:38 +msgid "Signature" +msgstr "签名" + +#: lib/perl5/Selima/List/Guestbook.pm:39 +msgid "Identity" +msgstr "身份" + +#: lib/perl5/Selima/List/Guestbook.pm:40 +msgid "Location" +msgstr "所在地" + +#: lib/perl5/Selima/List/Guestbook.pm:41 +msgid "Message" +msgstr "留言" + +#: lib/perl5/Selima/List/Guestbook.pm:42 lib/perl5/Selima/List/Users.pm:35 +msgid "IP" +msgstr "IP" + +#: lib/perl5/Selima/List/Guestbook.pm:43 lib/perl5/Selima/List/Users.pm:36 +msgid "Host" +msgstr "主机" + +#: lib/perl5/Selima/List/Guestbook.pm:44 lib/perl5/Selima/List/Users.pm:37 +msgid "Country" +msgstr "国家" + +#: lib/perl5/Selima/List/Guestbook.pm:45 +msgid "Page No." +msgstr "页数" + +#: lib/perl5/Selima/List/Guestbook.pm:46 +msgid "Old page No." +msgstr "旧页数" + +#: lib/perl5/Selima/List/Guestbook.pm:54 +msgid "Write a new message." +msgstr "写新留言。" + +#: lib/perl5/Selima/List/Guestbook.pm:60 +msgid "Search for a message:" +msgstr "搜寻留言:" + +#: lib/perl5/Selima/List/Guestbook.pm:77 +msgid "Your query found [*,_1,message]." +msgstr "共 [#,_1] 则相符的留言。" + +#: lib/perl5/Selima/List/Guestbook.pm:80 +msgid "[*,_1,message]." +msgstr "共 [#,_1] 则留言。" + +#: lib/perl5/Selima/List/Guestbook.pm:86 +msgid "Your query found [*,_1,message], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 则相符的留言,列出第 [#,_2] 则到第 [#,_3] 则。" + +#: lib/perl5/Selima/List/Guestbook.pm:90 +msgid "[*,_1,message], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 则留言,列出第 [#,_2] 则到第 [#,_3] 则。" + +#: lib/perl5/Selima/List/LinkCat.pm:24 +msgid "Select a Link Category" +msgstr "选择连结分类" + +#: lib/perl5/Selima/List/LinkCat.pm:25 +msgid "Manage Link Categories" +msgstr "管理连结分类" + +#: lib/perl5/Selima/List/LinkCatz.pm:24 +msgid "Select a Link Categorization Record" +msgstr "选择连结分类资料" + +#: lib/perl5/Selima/List/LinkCatz.pm:25 +msgid "Manage Link Categorization" +msgstr "管理连结分类表" + +#: lib/perl5/Selima/List/LinkCatz.pm:30 +msgid "Link" +msgstr "连结" + +#: lib/perl5/Selima/List/Links.pm:24 +msgid "Select a Related Link" +msgstr "选择相关连结" + +#: lib/perl5/Selima/List/Links.pm:25 +msgid "Manage Related Links" +msgstr "管理相关连结" + +#: lib/perl5/Selima/List/Links.pm:32 +msgid "2nd language title" +msgstr "第二语言标题" + +#: lib/perl5/Selima/List/Links.pm:33 +msgid "Link icon" +msgstr "连结小图" + +#: lib/perl5/Selima/List/Links.pm:34 +msgid "Address" +msgstr "地址" + +#: lib/perl5/Selima/List/Links.pm:35 +msgid "Tel." +msgstr "电话" + +#: lib/perl5/Selima/List/Links.pm:36 +msgid "Fax." +msgstr "传真" + +#: lib/perl5/Selima/List/Links.pm:44 +msgid "Add a new related link." +msgstr "建新相关连结。" + +#: lib/perl5/Selima/List/Links.pm:50 +msgid "Search for a related link:" +msgstr "搜寻相关连结:" + +#: lib/perl5/Selima/List/Links.pm:67 +msgid "Your query found [*,_1,related link]." +msgstr "共 [#,_1] 笔相符的相关连结。" + +#: lib/perl5/Selima/List/Links.pm:70 +msgid "[*,_1,related link]." +msgstr "共 [#,_1] 笔相关连结。" + +#: lib/perl5/Selima/List/Links.pm:76 +msgid "Your query found [*,_1,related link], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的相关连结,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Links.pm:80 +msgid "[*,_1,related link], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相关连结,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Pages.pm:24 +msgid "Select a Page" +msgstr "选择网页" + +#: lib/perl5/Selima/List/Pages.pm:25 +msgid "Manage Pages" +msgstr "管理网页" + +#: lib/perl5/Selima/List/Pages.pm:40 +msgid "Write a new page." +msgstr "写新网页。" + +#: lib/perl5/Selima/List/Pages.pm:46 +msgid "Search for a page:" +msgstr "搜寻网页:" + +#: lib/perl5/Selima/List/Pages.pm:63 +msgid "Your query found [*,_1,page]." +msgstr "共 [#,_1] 页相符的网页。" + +#: lib/perl5/Selima/List/Pages.pm:66 +msgid "[*,_1,page]." +msgstr "共 [#,_1] 页网页。" + +#: lib/perl5/Selima/List/Pages.pm:72 +msgid "Your query found [*,_1,page], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 页相符的网页,列出第 [#,_2] 页到第 [#,_3] 页。" + +#: lib/perl5/Selima/List/Pages.pm:76 +msgid "[*,_1,page], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 页网页,列出第 [#,_2] 页到第 [#,_3] 页。" + +#: lib/perl5/Selima/List/ScptPriv.pm:24 +msgid "Select a Script Privilege Record" +msgstr "选择程式权限资料" + +#: lib/perl5/Selima/List/ScptPriv.pm:25 +msgid "Manage Script Privileges" +msgstr "管理程式权限表" + +#: lib/perl5/Selima/List/ScptPriv.pm:30 +msgid "Script" +msgstr "程式" + +#: lib/perl5/Selima/List/ScptPriv.pm:31 +msgid "Privilege" +msgstr "权限说明" + +#: lib/perl5/Selima/List/ScptPriv.pm:39 +msgid "Add a new script privilege record." +msgstr "建新程式权限资料。" + +#: lib/perl5/Selima/List/ScptPriv.pm:45 +msgid "Search for a script privilege record:" +msgstr "搜寻程式权限资料:" + +#: lib/perl5/Selima/List/ScptPriv.pm:62 +msgid "Your query found [*,_1,script privilege record]." +msgstr "共 [#,_1] 笔相符的程式权限资料。" + +#: lib/perl5/Selima/List/ScptPriv.pm:65 +msgid "[*,_1,script privilege record]." +msgstr "共 [#,_1] 笔程式权限资料。" + +#: lib/perl5/Selima/List/ScptPriv.pm:71 +msgid "" +"Your query found [*,_1,script privilege record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的程式权限资料,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/ScptPriv.pm:75 +msgid "[*,_1,script privilege record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔程式权限资料,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/UserMem.pm:24 +msgid "Select a User Membership Record" +msgstr "选择使用者成员关系" + +#: lib/perl5/Selima/List/UserMem.pm:25 +msgid "Manage User Membership" +msgstr "管理使用者成员关系" + +#: lib/perl5/Selima/List/UserPref.pm:24 +msgid "Select a User Preference" +msgstr "选择使用者偏好" + +#: lib/perl5/Selima/List/UserPref.pm:25 +msgid "Manage User Preferences" +msgstr "管理使用者偏好" + +#: lib/perl5/Selima/List/UserPref.pm:30 +msgid "User" +msgstr "使用者" + +#: lib/perl5/Selima/List/UserPref.pm:31 +msgid "Domain" +msgstr "适用范围" + +#: lib/perl5/Selima/List/UserPref.pm:32 +msgid "Value" +msgstr "值" + +#: lib/perl5/Selima/List/UserPref.pm:40 +msgid "Add a new user preference." +msgstr "建新使用者偏好。" + +#: lib/perl5/Selima/List/UserPref.pm:46 +msgid "Search for a user preference:" +msgstr "搜寻使用者偏好:" + +#: lib/perl5/Selima/List/UserPref.pm:63 +msgid "Your query found [*,_1,user preference]." +msgstr "共 [#,_1] 笔相符的使用者偏好。" + +#: lib/perl5/Selima/List/UserPref.pm:66 +msgid "[*,_1,user preference]." +msgstr "共 [#,_1] 笔使用者偏好。" + +#: lib/perl5/Selima/List/UserPref.pm:72 +msgid "Your query found [*,_1,user preference], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的使用者偏好,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/UserPref.pm:76 +msgid "[*,_1,user preference], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔使用者偏好,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Users.pm:23 +msgid "Select a User" +msgstr "选择使用者" + +#: lib/perl5/Selima/List/Users.pm:24 +msgid "Manage Users" +msgstr "管理帐号" + +#: lib/perl5/Selima/List/Users.pm:29 +msgid "User ID." +msgstr "使用者代号" + +#: lib/perl5/Selima/List/Users.pm:30 +msgid "Full name" +msgstr "姓名" + +#: lib/perl5/Selima/List/Users.pm:31 +msgid "Deleted?" +msgstr "已删?" + +#: lib/perl5/Selima/List/Users.pm:32 +msgid "Pref. language" +msgstr "语言偏好" + +#: lib/perl5/Selima/List/Users.pm:33 +msgid "Visits" +msgstr "上站次数" + +#: lib/perl5/Selima/List/Users.pm:34 +msgid "Visited" +msgstr "上站日期" + +#: lib/perl5/Selima/List/Users.pm:45 +msgid "Add a new user account." +msgstr "建新帐号。" + +#: lib/perl5/Selima/List/Users.pm:51 +msgid "Search for a user:" +msgstr "搜寻使用者:" + +#: lib/perl5/Selima/List/Users.pm:68 +msgid "Your query found [*,_1,user]." +msgstr "共 [#,_1] 位相符的使用者。" + +#: lib/perl5/Selima/List/Users.pm:71 +msgid "[*,_1,user]." +msgstr "共 [#,_1] 位使用者。" + +#: lib/perl5/Selima/List/Users.pm:77 +msgid "Your query found [*,_1,user], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位相符的使用者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: lib/perl5/Selima/List/Users.pm:81 +msgid "[*,_1,user], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位使用者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:103 +msgid "This accounting record was not modified." +msgstr "会计分录未异动。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:107 +msgid "This accounting record has been successfully added." +msgstr "会计分录建好了。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:111 +msgid "This accounting record has been successfully updated." +msgstr "会计分录存好了。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:115 +msgid "This accounting record has been successfully deleted." +msgstr "会计分录删掉了。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:86 +msgid "This accounting subject was not modified." +msgstr "会计科目未异动。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:90 +msgid "This accounting subject has been successfully added." +msgstr "会计科目建好了。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:94 +msgid "This accounting subject has been successfully updated." +msgstr "会计科目存好了。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:98 +msgid "This accounting subject has been successfully deleted." +msgstr "会计科目删掉了。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:418 +msgid "This accounting transaction was not modified." +msgstr "会计传票未异动。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:422 +msgid "This accounting transaction has been successfully added." +msgstr "会计传票建好了。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:426 +msgid "This accounting transaction has been successfully updated." +msgstr "会计传票存好了。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:430 +msgid "This accounting transaction has been successfully deleted." +msgstr "会计传票删掉了。" + +#: lib/perl5/Selima/Processor/Category.pm:20 +msgid "This category was not modified." +msgstr "分类未异动。" + +#: lib/perl5/Selima/Processor/Category.pm:24 +msgid "This category has been successfully added." +msgstr "分类建好了。" + +#: lib/perl5/Selima/Processor/Category.pm:28 +msgid "This category has been successfully updated." +msgstr "分类存好了。" + +#: lib/perl5/Selima/Processor/Category.pm:32 +msgid "This category has been successfully deleted." +msgstr "分类删掉了。" + +#: lib/perl5/Selima/Processor/Categorz.pm:20 +msgid "This categorization record was not modified." +msgstr "分类资料未异动。" + +#: lib/perl5/Selima/Processor/Categorz.pm:24 +msgid "This categorization record has been successfully added." +msgstr "分类资料建好了。" + +#: lib/perl5/Selima/Processor/Categorz.pm:28 +msgid "This categorization record has been successfully updated." +msgstr "分类资料存好了。" + +#: lib/perl5/Selima/Processor/Categorz.pm:32 +msgid "This categorization record has been successfully deleted." +msgstr "分类资料删掉了。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:79 +msgid "This group membership record was not modified." +msgstr "群组成员关系未异动。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:83 +msgid "This group membership record has been successfully added." +msgstr "群组成员关系建好了。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:87 +msgid "This group membership record has been successfully updated." +msgstr "群组成员关系存好了。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:91 +msgid "This group membership record has been successfully deleted." +msgstr "群组成员关系删掉了。" + +#: lib/perl5/Selima/Processor/Group.pm:253 +msgid "This group was not modified." +msgstr "群组未异动。" + +#: lib/perl5/Selima/Processor/Group.pm:257 +msgid "This group has been successfully added." +msgstr "群组建好了。" + +#: lib/perl5/Selima/Processor/Group.pm:261 +msgid "This group has been successfully updated." +msgstr "群组存好了。" + +#: lib/perl5/Selima/Processor/Group.pm:265 +msgid "This group has been successfully deleted." +msgstr "群组删掉了。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:117 +msgid "This message was not modified." +msgstr "留言未异动。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:121 +msgid "This message has been successfully added." +msgstr "留言写好了。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:125 +msgid "This message has been successfully updated." +msgstr "留言存好了。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:129 +msgid "This message has been successfully deleted." +msgstr "留言删掉了。" + +#: lib/perl5/Selima/Processor/Link.pm:168 +msgid "This related link was not modified." +msgstr "相关连结未异动。" + +#: lib/perl5/Selima/Processor/Link.pm:172 +msgid "This related link has been successfully added." +msgstr "相关连结建好了。" + +#: lib/perl5/Selima/Processor/Link.pm:176 +msgid "This related link has been successfully updated." +msgstr "相关连结存好了。" + +#: lib/perl5/Selima/Processor/Link.pm:180 +msgid "This related link has been successfully deleted." +msgstr "相关连结删掉了。" + +#: lib/perl5/Selima/Processor/LogOut.pm:52 +msgid "You have successfully logged out." +msgstr "登出了。" + +#: lib/perl5/Selima/Processor/Page.pm:89 +msgid "This page was not modified." +msgstr "网页未异动。" + +#: lib/perl5/Selima/Processor/Page.pm:93 +msgid "This page has been successfully added." +msgstr "网页写好了。" + +#: lib/perl5/Selima/Processor/Page.pm:97 +msgid "This page has been successfully updated." +msgstr "网页存好了。" + +#: lib/perl5/Selima/Processor/Page.pm:101 +msgid "This page has been successfully deleted." +msgstr "网页删掉了。" + +#: lib/perl5/Selima/Processor/Rebuild.pm:48 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. ([sprintf,%0.3f,_1] " +"seconds)" +msgstr "指定的网页重制好了。( [sprintf,%0.3f,_1] 秒)" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:79 +msgid "This script privilege record was not modified." +msgstr "程式权限未异动。" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:83 +msgid "This script privilege record has been successfully added." +msgstr "程式权限建好了。" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:87 +msgid "This script privilege record has been successfully updated." +msgstr "程式权限存好了。" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:91 +msgid "This script privilege record has been successfully deleted." +msgstr "程式权限删掉了。" + +#: lib/perl5/Selima/Processor/UserMem.pm:79 +msgid "This user membership record was not modified." +msgstr "使用者成员关系未异动。" + +#: lib/perl5/Selima/Processor/UserMem.pm:83 +msgid "This user membership record has been successfully added." +msgstr "使用者成员关系建好了。" + +#: lib/perl5/Selima/Processor/UserMem.pm:87 +msgid "This user membership record has been successfully updated." +msgstr "使用者成员关系存好了。" + +#: lib/perl5/Selima/Processor/UserMem.pm:91 +msgid "This user membership record has been successfully deleted." +msgstr "使用者成员关系删掉了。" + +#: lib/perl5/Selima/Processor/User.pm:185 +msgid "This user account was not modified." +msgstr "帐号未异动。" + +#: lib/perl5/Selima/Processor/User.pm:189 +msgid "This user account has been successfully added." +msgstr "帐号建好了。" + +#: lib/perl5/Selima/Processor/User.pm:193 +msgid "This user account has been successfully updated." +msgstr "帐号存好了。" + +#: lib/perl5/Selima/Processor/User.pm:197 +msgid "This user account has been successfully deleted." +msgstr "帐号删掉了。" + +#: lib/perl5/Selima/Processor/UserPref.pm:128 +msgid "This user preference was not modified." +msgstr "使用者偏好未异动。" + +#: lib/perl5/Selima/Processor/UserPref.pm:132 +msgid "This user preference has been successfully added." +msgstr "使用者偏好建好了。" + +#: lib/perl5/Selima/Processor/UserPref.pm:136 +msgid "This user preference has been successfully updated." +msgstr "使用者偏好存好了。" + +#: lib/perl5/Selima/Processor/UserPref.pm:140 +msgid "This user preference has been successfully deleted." +msgstr "使用者偏好删掉了。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:37 +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:59 +msgid "Your signature is too long. (Max. length [#,_1])" +msgstr "你的签名太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:56 +msgid "Please fill in your signature." +msgstr "请填上你的签名。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:80 +msgid "Your identity is too long. (Max. length [#,_1])" +msgstr "你的身份太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:101 +msgid "Your location is too long. (Max. length [#,_1])" +msgstr "你的所在地太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:122 +msgid "Your e-mail is too long. (Max. length [#,_1])" +msgstr "你的 E-mail 信箱太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:143 +msgid "Your website URL is too long. (Max. length [#,_1])" +msgstr "你的网站网址太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:163 +#: lib/perl5/Selima/Form/Guestbook/Public.pm:60 +msgid "Fill in your message here." +msgstr "请填上你的留言。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:164 +msgid "Please fill in your message." +msgstr "请填上你的留言。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:167 +msgid "Your message is too long. (Max. length [#,_1])" +msgstr "你的留言太长了。(最长 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:186 +msgid "You can post at most 5 messages in 1 hour." +msgstr "一小时最多只能留五篇留言。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:204 +msgid "Your message is already posted." +msgstr "留言已经留了。" + +#: lib/perl5/Selima/Form/Guestbook/Public.pm:40 +msgid "Leave a messsage" +msgstr "留言" + +#: lib/perl5/Selima/Form/Guestbook/Public.pm:42 +msgid "This table provides you a form to leave a message." +msgstr "本表提供留言的表单。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:27 +msgid "Select an Accounting Record" +msgstr "选择会计分录" + +#: lib/perl5/Selima/List/Accounting/Records.pm:28 +msgid "Manage Accounting Records" +msgstr "管理会计分录" + +#: lib/perl5/Selima/List/Accounting/Records.pm:33 +msgid "Accounting transaction" +msgstr "会计传票" + +#: lib/perl5/Selima/List/Accounting/Records.pm:34 +msgid "Debit/credit" +msgstr "借/贷" + +#: lib/perl5/Selima/List/Accounting/Records.pm:46 +msgid "Add a new accounting record." +msgstr "建新会计分录。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:52 +msgid "Search for an accounting record:" +msgstr "搜寻会计分录:" + +#: lib/perl5/Selima/List/Accounting/Records.pm:69 +#: lib/perl5/Selima/List/Accounting/Reports.pm:634 +msgid "Your query found [*,_1,accounting record]." +msgstr "共 [#,_1] 笔相符的会计分录。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:72 +#: lib/perl5/Selima/List/Accounting/Reports.pm:637 +msgid "[*,_1,accounting record]." +msgstr "共 [#,_1] 笔会计分录。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:78 +#: lib/perl5/Selima/List/Accounting/Reports.pm:643 +msgid "Your query found [*,_1,accounting record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的会计分录,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:82 +#: lib/perl5/Selima/List/Accounting/Reports.pm:647 +msgid "[*,_1,accounting record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔会计分录,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:31 +msgid "View the Accounting Reports" +msgstr "浏览会计报表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:72 +msgid "Month" +msgstr "月份" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:77 +msgid "Income" +msgstr "收入" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:78 +msgid "Expense" +msgstr "支出" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:79 +msgid "Balance" +msgstr "余额" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:137 +msgid "Please specify a month." +msgstr "请设定月份。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:141 +msgid "Please specify a valid month in YYYY-MM format." +msgstr "月份请以 YYYY-MM 格式正确设定。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:176 +msgid "Please specify a year." +msgstr "请设定年份。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:180 +msgid "Please specify a valid year in YYYY format." +msgstr "年份请以 YYYY 格式正确设定。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:211 +msgid "Please specify the start date." +msgstr "请设定启始日期。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:215 +msgid "Please specify a valid start date in YYYY-MM-DD format." +msgstr "启始日期请以 YYYY-MM-DD 格式正确填写。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:226 +msgid "Please specify the end date." +msgstr "请设定结束日期。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:229 +msgid "Please specify a valid end date in YYYY-MM-DD format." +msgstr "结束日期请以 YYYY-MM-DD 格式正确填写。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:250 +msgid "This option is invalid. Please select a proper date range." +msgstr "日期范围选项无效,请由表上选择适当的日期范围。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:319 +#: lib/perl5/Selima/List/Accounting/Transacts.pm:53 +msgid "" +"Add a new cash expense transaction, add a new cash income transaction or add a new " +"transfer transaction." +msgstr "" +"建新现金支出传票建新现金收入传票" +"或建新转帐传票。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:339 +msgid "Report type:" +msgstr "报表类型:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:343 +msgid "Cash book" +msgstr "现金帐" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:347 +msgid "Cash book summary" +msgstr "现金帐摘要" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:351 +msgid "Ledger" +msgstr "分类帐" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:355 +msgid "Ledger summary" +msgstr "分类帐摘要" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:359 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:31 +msgid "Journal" +msgstr "日记簿" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:363 +msgid "Trial balance" +msgstr "试算表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:367 +msgid "Income statement" +msgstr "损益表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:371 +msgid "Balance sheet" +msgstr "资产负债表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:408 +msgid "Search the accounting records:" +msgstr "帐目检索:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:442 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:297 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:253 +msgid "Query" +msgstr "查询" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:443 +msgid "Date range:" +msgstr "日期范围:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:444 +msgid "By month:" +msgstr "依月份:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:445 +msgid "By year:" +msgstr "依年度:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:446 +msgid "Specified date range:" +msgstr "特定期间:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:447 +msgid "All" +msgstr "全部" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:448 +msgid "From" +msgstr "自" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:449 +msgid "to" +msgstr "至" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:563 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:332 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:326 +msgid "From [_1] to [_2]." +msgstr "自 [_1] 至 [_2] 。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:24 +msgid "Select an Accounting Subject" +msgstr "选择会计科目" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:25 +msgid "Manage Accounting Subjects" +msgstr "管理会计科目" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:30 +msgid "Parent subject" +msgstr "大科目" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:31 +msgid "Code" +msgstr "代码" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:39 +msgid "Add a new accounting subject." +msgstr "建新会计科目。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:45 +msgid "Search for an accounting subject:" +msgstr "搜寻会计科目:" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:62 +msgid "Your query found [*,_1,accounting subject]." +msgstr "共 [#,_1] 个相符的会计科目。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:65 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:355 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:349 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:251 +msgid "[*,_1,accounting subject]." +msgstr "[#,_1] 个会计科目。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:71 +msgid "Your query found [*,_1,accounting subject], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个相符的会计科目,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:75 +msgid "[*,_1,accounting subject], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 个会计科目,列出第 [#,_2] 个到第 [#,_3] 个。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:26 +msgid "Select an Accounting Transaction" +msgstr "选择会计传票" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:27 +msgid "Manage Accounting Transactions" +msgstr "管理会计传票" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:32 +msgid "Number" +msgstr "编号" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:33 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:42 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:40 +msgid "Note" +msgstr "注记" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:66 +msgid "Search for an accounting transaction:" +msgstr "搜寻会计传票:" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:83 +msgid "Your query found [*,_1,accounting transaction]." +msgstr "共 [#,_1] 笔相符的会计传票。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:86 +msgid "[*,_1,accounting transaction]." +msgstr "[#,_1] 笔会计传票。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:92 +msgid "" +"Your query found [*,_1,accounting transaction], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔相符的会计传票,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:96 +msgid "[*,_1,accounting transaction], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 笔会计传票,列出第 [#,_2] 笔到第 [#,_3] 笔。" + +#: lib/perl5/Selima/List/Guestbook/Public.pm:196 +msgid "~[Edit~]" +msgstr "~[编辑~]" + +#: lib/perl5/Selima/List/Guestbook/Public.pm:205 +msgid "The message entry seperator" +msgstr "留言分隔线" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:29 +msgid "Balance Sheet" +msgstr "资产负债表" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:40 +msgid "Assets accounting subject" +msgstr "资产会计科目" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:41 +msgid "Assets amount" +msgstr "资产金额" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:42 +msgid "Liabilities accounting subject" +msgstr "负债会计科目" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:43 +msgid "Liabilities amount" +msgstr "负债金额" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:289 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:379 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:283 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:273 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:351 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:204 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:421 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:366 +msgid "Download the data as a CSV file." +msgstr "下载 CSV 格式资料档。" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:45 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:150 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:339 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:40 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:383 +msgid "current assets and liabilities" +msgstr "流动资产与负债" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:48 +msgid "Cash book - [_1]" +msgstr "现金帐 - [_1]" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:29 +msgid "Income Statement" +msgstr "损益表" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:187 +msgid "Gross income" +msgstr "营业毛利" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:189 +msgid "Operating income" +msgstr "营业净利" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:191 +msgid "Before tax income" +msgstr "税前净利" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:193 +msgid "After tax income" +msgstr "税后净利" + +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:41 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:39 +msgid "Transaction Number" +msgstr "传票编号" + +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:127 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:138 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:151 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:162 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:126 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:140 +msgid "Brought forward" +msgstr "上期结转" + +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:46 +msgid "Ledger - [_1]" +msgstr "分类帐 - [_1]" + +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:26 +msgid "Search the Accounting Records" +msgstr "帐目检索" + +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:28 +msgid "Search Result" +msgstr "检索结果" + +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:28 +msgid "Trial Balance" +msgstr "试算表" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:43 +msgid "Cash Book Summary - [_1]" +msgstr "现金帐摘要 - [_1]" + +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:41 +msgid "Ledger Summary - [_1]" +msgstr "分类帐摘要 - [_1]" diff --git a/po/selima/zh_TW.gmo b/po/selima/zh_TW.gmo new file mode 100644 index 0000000..722fe55 Binary files /dev/null and b/po/selima/zh_TW.gmo differ diff --git a/po/selima/zh_TW.po b/po/selima/zh_TW.po new file mode 100644 index 0000000..767dc92 --- /dev/null +++ b/po/selima/zh_TW.po @@ -0,0 +1,3376 @@ +# Traditional Chinese PO file for the Selima common subroutines. +# Copyright (C) 2003-2018 imacat +# This file is distributed under the same license as the selima package. +# imacat , 2003-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: selima 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-02-17 11:07+0800\n" +"PO-Revision-Date: 2018-11-02 01:03+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: lib/perl5/Selima/Checker.pm:130 +msgid "Please select a user." +msgstr "請選擇使用者。" + +#: lib/perl5/Selima/Checker.pm:133 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: lib/perl5/Selima/Checker.pm:151 +msgid "Please select a group." +msgstr "請選擇群組。" + +#: lib/perl5/Selima/Checker.pm:154 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: lib/perl5/Selima/Checker.pm:172 +msgid "Please fill in the script." +msgstr "請填上程式檔名。" + +#: lib/perl5/Selima/Checker.pm:175 +msgid "This script is too long. (Max. length [#,_1])" +msgstr "程式檔名太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:179 +msgid "This script is not a valid script. Please specify another one." +msgstr "查無此程式,請重新設定執行的程式。" + +#: lib/perl5/Selima/Checker.pm:197 +msgid "Please fill in the author." +msgstr "請填上作者。" + +#: lib/perl5/Selima/Checker.pm:200 +msgid "This author is too long. (Max. length [#,_1])" +msgstr "作者太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:220 lib/perl5/Selima/Form.pm:1700 +msgid "Fill in the content here." +msgstr "請填上內文。" + +#: lib/perl5/Selima/Checker.pm:221 +msgid "Please fill in the content." +msgstr "請填上內文。" + +#: lib/perl5/Selima/Checker.pm:224 +msgid "This content is too long. (Max. length [#,_1])" +msgstr "內文太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:243 +msgid "Please fill in a date." +msgstr "請填上日期。" + +#: lib/perl5/Selima/Checker.pm:246 lib/perl5/Selima/Checker.pm:249 +#: lib/perl5/Selima/Checker.pm:251 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期請以 YYYY-MM-DD 格式正確填寫。" + +#: lib/perl5/Selima/Checker.pm:270 lib/perl5/Selima/Form.pm:1756 +msgid "Fill in the description here." +msgstr "請填上說明。" + +#: lib/perl5/Selima/Checker.pm:271 +msgid "Please fill in the description." +msgstr "請填上說明。" + +#: lib/perl5/Selima/Checker.pm:274 +msgid "This description is too long. (Max. length [#,_1])" +msgstr "說明太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:293 +msgid "Please fill in the ID." +msgstr "請填上代號。" + +#: lib/perl5/Selima/Checker.pm:296 +msgid "This ID. is too long. (Max. length [#,_1])" +msgstr "代號太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:299 +msgid "This ID. is too short. (Max. length [#,_1])" +msgstr "代號太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:303 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "代號限用小寫英文字母、數字和底線。" + +#: lib/perl5/Selima/Checker.pm:321 +msgid "Please fill in the keywords." +msgstr "請填上關鍵字。" + +#: lib/perl5/Selima/Checker.pm:324 +msgid "This keyword list is too long. (Max. length [#,_1])" +msgstr "關鍵字太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:344 lib/perl5/Selima/Form.pm:1830 +msgid "Fill in the message here." +msgstr "請填上留言。" + +#: lib/perl5/Selima/Checker.pm:345 +msgid "Please fill in the message." +msgstr "請填上留言。" + +#: lib/perl5/Selima/Checker.pm:348 +msgid "This message is too long. (Max. length [#,_1])" +msgstr "留言太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:367 +msgid "Please fill in the order." +msgstr "請填上先後次序。" + +#: lib/perl5/Selima/Checker.pm:370 +msgid "This order is too long. (Max. length [#,_1])" +msgstr "次序太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:374 +msgid "Please fill in a positive integer order." +msgstr "次序請填正整數。" + +#: lib/perl5/Selima/Checker.pm:400 +msgid "Please fill in the page path." +msgstr "請填上網頁路徑。" + +#: lib/perl5/Selima/Checker.pm:403 +msgid "This page path is too long. (Max. length [#,_1])" +msgstr "網頁路徑太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:414 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "已有同一網頁,請勿重複建檔。" + +#: lib/perl5/Selima/Checker.pm:417 +msgid "Please fill in an absolute page path." +msgstr "網頁路徑請填上絕對路徑。" + +#: lib/perl5/Selima/Checker.pm:420 +msgid "Please fill in a valid page path." +msgstr "網頁路徑請填上正確路徑。" + +#: lib/perl5/Selima/Checker.pm:423 +msgid "You cannot overwrite the cover home page." +msgstr "不可以程式設定首頁。" + +#: lib/perl5/Selima/Checker.pm:426 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "網頁路徑限填 HTML 位址( *.html )。" + +#: lib/perl5/Selima/Checker.pm:454 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "查無此圖,請重新上傳圖檔。" + +#: lib/perl5/Selima/Checker.pm:458 +msgid "" +"This picture is too large. Please upload another one. (Max. length [#,_1])" +msgstr "圖檔太大,請重新上傳圖檔(最大 [#,_1] )。" + +#: lib/perl5/Selima/Checker.pm:482 +msgid "Please fill in the picture caption." +msgstr "請填上圖片標題。" + +#: lib/perl5/Selima/Checker.pm:485 +msgid "This picture caption is too long. (Max. length [#,_1])" +msgstr "圖片標題太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:509 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "圖片位置無效。請由表上選擇適當的圖片位置。" + +#: lib/perl5/Selima/Checker.pm:527 +msgid "Please fill in the title." +msgstr "請填上標題。" + +#: lib/perl5/Selima/Checker.pm:530 +msgid "This title is too long. (Max. length [#,_1])" +msgstr "標題太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:549 +msgid "Please fill in the English title." +msgstr "請填上英文標題。" + +#: lib/perl5/Selima/Checker.pm:552 +msgid "This English title is too long. (Max. length [#,_1])" +msgstr "英文標題太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:699 lib/perl5/Selima/Preview.pm:38 +msgid "The following field was not received: \"[_1]\"." +msgstr "程式沒有收到下列欄位:「 [_1] 」" + +#: lib/perl5/Selima/ChkWrite.pm:35 +msgid "[_1]: It is not a file." +msgstr "[_1]: 這不是檔案。" + +#: lib/perl5/Selima/ChkWrite.pm:39 +msgid "[_1]: You have no permission to overwrite this file." +msgstr "[_1]: 存檔的權限不足,無法存檔。" + +#: lib/perl5/Selima/ChkWrite.pm:50 +msgid "[_1]: You cannot create anything under the root directory." +msgstr "[_1]: 不可在根目錄下建檔。" + +#: lib/perl5/Selima/ChkWrite.pm:54 +msgid "" +"[_1]: One of the parents of this file ([_2]) is not a directory. You cannot " +"create any new file inside." +msgstr "[_1]: 路徑中間有一部份( [_2] )不是目錄,無法往下建檔。" + +#: lib/perl5/Selima/ChkWrite.pm:58 +msgid "[_1]: You have no permission to create any file under [_2]." +msgstr "[_1]: 權限不足,無法在 [_2] 建檔。" + +#: lib/perl5/Selima/CommText.pm:24 +msgid "(not set)" +msgstr "(未設定)" + +#: lib/perl5/Selima/CommText.pm:25 +msgid "(none)" +msgstr "(無)" + +#: lib/perl5/Selima/CommText.pm:26 +msgid "(N/A)" +msgstr "(不可考)" + +#: lib/perl5/Selima/Format.pm:48 +msgid "[#,_1] bytes" +msgstr "[#,_1] 位元組" + +#: lib/perl5/Selima/Form.pm:116 +msgid "Delete it." +msgstr "刪掉" + +#: lib/perl5/Selima/Form.pm:119 +msgid "*" +msgstr "" + +#: lib/perl5/Selima/Form.pm:140 +msgid "This table provides you a form to add a new data record." +msgstr "本表提供建新資料的表單。" + +#: lib/perl5/Selima/Form.pm:143 +msgid "This table provides you a form to update a current data record." +msgstr "本表提供異動資料的表單。" + +#: lib/perl5/Selima/Form.pm:146 +msgid "This table provides you a form to delete a data record." +msgstr "本表提供刪除資料的表單。" + +#: lib/perl5/Selima/Form.pm:185 +msgid "Add a New Data Record" +msgstr "建新資料" + +#: lib/perl5/Selima/Form.pm:188 +msgid "Update a Current Data Record" +msgstr "異動資料" + +#: lib/perl5/Selima/Form.pm:191 +msgid "Delete a Data Record" +msgstr "刪除資料" + +#: lib/perl5/Selima/Form.pm:212 +msgid "Preview it." +msgstr "預覽。" + +#: lib/perl5/Selima/Form.pm:271 lib/perl5/Selima/Form.pm:284 +msgid "Convert from Simplified Chinese" +msgstr "轉自簡體中文" + +#: lib/perl5/Selima/Form.pm:273 lib/perl5/Selima/Form.pm:286 +msgid "Convert from Traditional Chinese" +msgstr "轉自正體中文" + +#: lib/perl5/Selima/Form.pm:447 lib/perl5/Selima/Form.pm:451 +#: lib/perl5/Selima/Form.pm:559 lib/perl5/Selima/Form.pm:563 +#: lib/perl5/Selima/Form/AcctTrx.pm:89 lib/perl5/Selima/Form/AcctTrx.pm:94 +msgid "Submit" +msgstr "傳送" + +#: lib/perl5/Selima/Form.pm:448 lib/perl5/Selima/Form.pm:452 +#: lib/perl5/Selima/Form.pm:560 lib/perl5/Selima/Form.pm:564 +#: lib/perl5/Selima/Form/AcctTrx.pm:90 lib/perl5/Selima/Form/AcctTrx.pm:95 +msgid "Save" +msgstr "存檔" + +#: lib/perl5/Selima/Form.pm:571 lib/perl5/Selima/Form.pm:1139 +#: lib/perl5/Selima/Form.pm:1229 lib/perl5/Selima/List.pm:1390 +msgid "Delete" +msgstr "刪除" + +#: lib/perl5/Selima/Form.pm:572 lib/perl5/Selima/Form/Rebuild.pm:42 +msgid "Cancel" +msgstr "取消" + +#: lib/perl5/Selima/Form.pm:577 +msgid "" +"Are you sure you want to delete this data? You cannot recover it if you do " +"so." +msgstr "妳真的要刪掉嗎?資料刪掉就救不回來了。" + +#: lib/perl5/Selima/Form.pm:855 lib/perl5/Selima/Form.pm:951 +#: lib/perl5/Selima/Form.pm:1013 lib/perl5/Selima/Form.pm:1097 +#: lib/perl5/Selima/Form.pm:1175 lib/perl5/Selima/Form.pm:1282 +#: lib/perl5/Selima/Form.pm:1362 lib/perl5/Selima/Form.pm:1435 +#: lib/perl5/Selima/Form.pm:1528 lib/perl5/Selima/Form.pm:1620 +#: lib/perl5/Selima/Form.pm:2057 lib/perl5/Selima/Form/AcctRec.pm:122 +#: lib/perl5/Selima/Form/AcctTrx.pm:519 lib/perl5/Selima/Form/Group.pm:165 +#: lib/perl5/Selima/Form/Group.pm:294 lib/perl5/Selima/Form/Group.pm:421 +#: lib/perl5/Selima/Form/Link.pm:138 lib/perl5/Selima/Form/User.pm:291 +msgid "Original:" +msgstr "原:" + +#: lib/perl5/Selima/Form.pm:856 lib/perl5/Selima/Form.pm:952 +#: lib/perl5/Selima/Form.pm:1014 lib/perl5/Selima/Form.pm:1098 +#: lib/perl5/Selima/Form.pm:1176 lib/perl5/Selima/Form.pm:1283 +#: lib/perl5/Selima/Form.pm:1363 lib/perl5/Selima/Form.pm:1436 +#: lib/perl5/Selima/Form.pm:1529 lib/perl5/Selima/Form.pm:1621 +#: lib/perl5/Selima/Form.pm:2058 lib/perl5/Selima/Form/AcctRec.pm:123 +#: lib/perl5/Selima/Form/AcctTrx.pm:520 lib/perl5/Selima/Form/Group.pm:166 +#: lib/perl5/Selima/Form/Group.pm:295 lib/perl5/Selima/Form/Group.pm:422 +#: lib/perl5/Selima/Form/Link.pm:139 lib/perl5/Selima/Form/User.pm:292 +msgid "New:" +msgstr "新:" + +#: lib/perl5/Selima/Form.pm:860 lib/perl5/Selima/Form.pm:1018 +#: lib/perl5/Selima/Form.pm:1625 lib/perl5/Selima/Form.pm:2122 +msgid "Source:" +msgstr "原文:" + +#: lib/perl5/Selima/Form.pm:1138 lib/perl5/Selima/Form.pm:1228 +#: lib/perl5/Selima/Form/AcctRec.pm:100 lib/perl5/Selima/Form/AcctTrx.pm:214 +msgid "Choose" +msgstr "挑選" + +#: lib/perl5/Selima/Form.pm:1689 +msgid "Address:" +msgstr "地址:" + +#: lib/perl5/Selima/Form.pm:1694 +msgid "Author:" +msgstr "作者:" + +#: lib/perl5/Selima/Form.pm:1699 +msgid "Content:" +msgstr "內文:" + +#: lib/perl5/Selima/Form.pm:1713 +msgid "Current Website:" +msgstr "目前網站:" + +#: lib/perl5/Selima/Form.pm:1718 +msgid "Enter your website URL here." +msgstr "請填上妳的網站網址。" + +#: lib/perl5/Selima/Form.pm:1734 +msgid "Created:" +msgstr "建檔日期:" + +#: lib/perl5/Selima/Form.pm:1739 +msgid "Created by:" +msgstr "建檔者:" + +#: lib/perl5/Selima/Form.pm:1744 lib/perl5/Selima/List.pm:167 +#: lib/perl5/Selima/Form/User.pm:160 lib/perl5/Selima/Form/User.pm:163 +msgid "Disabled?" +msgstr "停用?" + +#: lib/perl5/Selima/Form.pm:1745 lib/perl5/Selima/Form/User.pm:161 +#: lib/perl5/Selima/Form/User.pm:164 +msgid "Disabled" +msgstr "停用" + +#: lib/perl5/Selima/Form.pm:1745 lib/perl5/Selima/Form/User.pm:161 +#: lib/perl5/Selima/Form/User.pm:164 +msgid "Enabled" +msgstr "未停用" + +#: lib/perl5/Selima/Form.pm:1745 +msgid "Disable it." +msgstr "停用。" + +#: lib/perl5/Selima/Form.pm:1750 +msgid "Date:" +msgstr "日期:" + +#: lib/perl5/Selima/Form.pm:1755 lib/perl5/Selima/Form/Group.pm:97 +msgid "Description:" +msgstr "說明:" + +#: lib/perl5/Selima/Form.pm:1761 +msgid "E-mail:" +msgstr "E-mail :" + +#: lib/perl5/Selima/Form.pm:1766 +msgid "Fax.:" +msgstr "傳真:" + +#: lib/perl5/Selima/Form.pm:1771 +msgid "Group:" +msgstr "群組:" + +#: lib/perl5/Selima/Form.pm:1776 lib/perl5/Selima/Form/Guestbook.pm:82 +#: lib/perl5/Selima/Form/LinkCat.pm:88 lib/perl5/Selima/Form/Link.pm:87 +#: lib/perl5/Selima/Form/Page.pm:81 +msgid "Hide?" +msgstr "隱藏?" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Hide it" +msgstr "隱藏起來" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Show it" +msgstr "秀出來" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Hide it currently." +msgstr "暫勿秀出。" + +#: lib/perl5/Selima/Form.pm:1782 lib/perl5/Selima/List.pm:171 +msgid "HTML?" +msgstr "HTML ?" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "HTML" +msgstr "HTML" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "Plain text" +msgstr "純文字" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "The submitted content is HTML." +msgstr "以上內文為 HTML 格式。" + +#: lib/perl5/Selima/Form.pm:1788 +msgid "Host:" +msgstr "主機:" + +#: lib/perl5/Selima/Form.pm:1793 lib/perl5/Selima/Form/LinkCat.pm:95 +msgid "ID.:" +msgstr "代號:" + +#: lib/perl5/Selima/Form.pm:1798 +msgid "Identity:" +msgstr "身份:" + +#: lib/perl5/Selima/Form.pm:1803 +msgid "Introduction:" +msgstr "簡介:" + +#: lib/perl5/Selima/Form.pm:1804 +msgid "Fill in the introduction here." +msgstr "請填上簡介。" + +#: lib/perl5/Selima/Form.pm:1809 +msgid "IP:" +msgstr "IP :" + +#: lib/perl5/Selima/Form.pm:1814 +msgid "Keywords:" +msgstr "關鍵字:" + +#: lib/perl5/Selima/Form.pm:1819 +msgid "Language:" +msgstr "語言:" + +#: lib/perl5/Selima/Form.pm:1824 +msgid "Location:" +msgstr "所在地:" + +#: lib/perl5/Selima/Form.pm:1829 +msgid "Message:" +msgstr "留言:" + +#: lib/perl5/Selima/Form.pm:1835 +msgid "Name:" +msgstr "名字:" + +#: lib/perl5/Selima/Form.pm:1847 lib/perl5/Selima/Form/AcctTrx.pm:319 +msgid "Order:" +msgstr "次序:" + +#: lib/perl5/Selima/Form.pm:1853 +msgid "Parent category:" +msgstr "大類:" + +#: lib/perl5/Selima/Form.pm:1854 lib/perl5/Selima/Form/AcctSubj.pm:94 +msgid "At the very top" +msgstr "最上層" + +#: lib/perl5/Selima/Form.pm:1866 lib/perl5/Selima/Form/User.pm:201 +msgid "Password:" +msgstr "密碼:" + +#: lib/perl5/Selima/Form.pm:1867 +msgid "Confirm password:" +msgstr "確認密碼:" + +#: lib/perl5/Selima/Form.pm:1978 +msgid "Page path:" +msgstr "網頁路徑:" + +#: lib/perl5/Selima/Form.pm:1992 +msgid "Picture:" +msgstr "圖片:" + +#: lib/perl5/Selima/Form.pm:1993 +msgid "Pic. caption:" +msgstr "圖片標題:" + +#: lib/perl5/Selima/Form.pm:1994 +msgid "Pic. position:" +msgstr "圖片位置:" + +#: lib/perl5/Selima/Form.pm:1997 +msgid "Set the picture" +msgstr "設定圖片" + +#: lib/perl5/Selima/Form.pm:1998 +msgid "Delete this picture" +msgstr "刪掉圖片" + +#: lib/perl5/Selima/Form.pm:2003 lib/perl5/Selima/Form.pm:2178 +msgid "Picture preview" +msgstr "圖片預覽" + +#: lib/perl5/Selima/Form.pm:2059 +msgid "Original picture preview" +msgstr "原圖片預覽" + +#: lib/perl5/Selima/Form.pm:2060 +msgid "New picture preview" +msgstr "新圖片預覽" + +#: lib/perl5/Selima/Form.pm:2078 +msgid "Please upload a new picture from [_1]." +msgstr "請由[_1]建新圖片。" + +#: lib/perl5/Selima/Form.pm:2228 +msgid "[numerate,_1,Subcategory,Subcategories]:" +msgstr "子類:" + +#: lib/perl5/Selima/Form.pm:2256 +msgid "Script:" +msgstr "程式:" + +#: lib/perl5/Selima/Form.pm:2261 +msgid "S/N:" +msgstr "編號:" + +#: lib/perl5/Selima/Form.pm:2266 +msgid "Tel.:" +msgstr "電話:" + +#: lib/perl5/Selima/Form.pm:2271 +msgid "Title:" +msgstr "標題:" + +#: lib/perl5/Selima/Form.pm:2276 +msgid "English title:" +msgstr "英文標題:" + +#: lib/perl5/Selima/Form.pm:2281 +msgid "Updated:" +msgstr "維護日期:" + +#: lib/perl5/Selima/Form.pm:2286 +msgid "Updated by:" +msgstr "維護者:" + +#: lib/perl5/Selima/Form.pm:2291 +msgid "URL:" +msgstr "網址:" + +#: lib/perl5/Selima/Form.pm:2296 lib/perl5/Selima/Form/UserPref.pm:94 +msgid "Value:" +msgstr "值:" + +#: lib/perl5/Selima/Form.pm:2301 +msgid "Visited:" +msgstr "上站日期:" + +#: lib/perl5/Selima/Form.pm:2306 +msgid "Visits:" +msgstr "上站次數:" + +#: lib/perl5/Selima/Init.pm:216 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" +"抱歉,我們不歡迎加裝 FunWebProduct 外掛(如 Smiley Central 、 PopSwatter 、 " +"Spin4Dough 、 My Mail Signature 、 My Mail Stationery 、 My Mail Stamp 、 " +"Cursor Mania ……等等)的瀏覽器。 FunWebProduct 會重抓你看過的每一頁網頁,造" +"成網站負荷加倍,甚至當機。請先移除 FunWebProduct ,再上來瀏覽。" + +#: lib/perl5/Selima/Links.pm:242 +msgid "Related Links" +msgstr "相關網站連結" + +#: lib/perl5/Selima/List.pm:109 +msgid "Select" +msgstr "選擇" + +#: lib/perl5/Selima/List.pm:112 +msgid "Select A Data Record" +msgstr "選擇資料" + +#: lib/perl5/Selima/List.pm:114 +msgid "Edit" +msgstr "設定" + +#: lib/perl5/Selima/List.pm:116 +msgid "Manage Data" +msgstr "管理資料" + +#: lib/perl5/Selima/List.pm:158 +msgid "S/N" +msgstr "編號" + +#: lib/perl5/Selima/List.pm:159 +msgid "Created" +msgstr "建檔日期" + +#: lib/perl5/Selima/List.pm:160 +msgid "Created by" +msgstr "建檔者" + +#: lib/perl5/Selima/List.pm:161 +msgid "Updated" +msgstr "維護日期" + +#: lib/perl5/Selima/List.pm:162 +msgid "Updated by" +msgstr "維護者" + +#: lib/perl5/Selima/List.pm:164 +msgid "Content" +msgstr "內文" + +#: lib/perl5/Selima/List.pm:165 +msgid "Category" +msgstr "分類" + +#: lib/perl5/Selima/List.pm:166 +msgid "Date" +msgstr "日期" + +#: lib/perl5/Selima/List.pm:168 lib/perl5/Selima/List/Groups.pm:30 +msgid "Description" +msgstr "說明" + +#: lib/perl5/Selima/List.pm:169 lib/perl5/Selima/List/Guestbook/Public.pm:138 +msgid "E-mail" +msgstr "E-mail" + +#: lib/perl5/Selima/List.pm:170 +msgid "Hidden?" +msgstr "隱藏?" + +#: lib/perl5/Selima/List.pm:172 +msgid "ID." +msgstr "代號" + +#: lib/perl5/Selima/List.pm:173 +msgid "Keywords" +msgstr "關鍵字" + +#: lib/perl5/Selima/List.pm:174 +msgid "Name" +msgstr "名字" + +#: lib/perl5/Selima/List.pm:175 +msgid "Order" +msgstr "次序" + +#: lib/perl5/Selima/List.pm:176 lib/perl5/Selima/List/Pages.pm:32 +msgid "Page path" +msgstr "網頁路徑" + +#: lib/perl5/Selima/List.pm:177 +msgid "Picture" +msgstr "圖片" + +#: lib/perl5/Selima/List.pm:178 +msgid "Pic. ratio" +msgstr "圖片比例" + +#: lib/perl5/Selima/List.pm:179 +msgid "Pic. caption" +msgstr "圖片標題" + +#: lib/perl5/Selima/List.pm:180 +msgid "Pic. position" +msgstr "圖片位置" + +#: lib/perl5/Selima/List.pm:181 +msgid "Title" +msgstr "標題" + +#: lib/perl5/Selima/List.pm:182 +msgid "English title" +msgstr "英文標題" + +#: lib/perl5/Selima/List.pm:183 +msgid "URL." +msgstr "網址" + +#: lib/perl5/Selima/List.pm:184 +msgid "Status (slow)" +msgstr "狀態(慢)" + +#: lib/perl5/Selima/List.pm:423 +msgid "Nothing found. Please try another query." +msgstr "查無相符的資料,請重新搜尋。" + +#: lib/perl5/Selima/List.pm:426 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: lib/perl5/Selima/List.pm:432 +msgid "Your query found [*,_1,record]." +msgstr "共 [#,_1] 筆相符的資料。" + +#: lib/perl5/Selima/List.pm:435 +msgid "[*,_1,record]." +msgstr "共 [#,_1] 筆資料。" + +#: lib/perl5/Selima/List.pm:441 +msgid "Your query found [*,_1,record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的資料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List.pm:445 +msgid "[*,_1,record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆資料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List.pm:456 +msgid "First" +msgstr "第一頁" + +#: lib/perl5/Selima/List.pm:457 +msgid "Previous" +msgstr "前一頁" + +#: lib/perl5/Selima/List.pm:458 +msgid "Next" +msgstr "下一頁" + +#: lib/perl5/Selima/List.pm:459 +msgid "Last" +msgstr "最末頁" + +#: lib/perl5/Selima/List.pm:502 +msgid "Picture unavailable" +msgstr "圖片無法顯示" + +#: lib/perl5/Selima/List.pm:530 +msgid "Page number ([_1]) invalid. Please specify a valid page number." +msgstr "頁數([_1])無效,請設成有效的數字。" + +#: lib/perl5/Selima/List.pm:536 +msgid "" +"Page number ([#,_1]) out of range. Please specify between 1 and [#,_2]." +msgstr "頁數([#,_1])超出範圍,請設在 1 到 [#,_2] 之間。" + +#: lib/perl5/Selima/List.pm:613 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:61 +msgid "Please fill in your query." +msgstr "請填上查詢的內容。" + +#: lib/perl5/Selima/List.pm:749 lib/perl5/Selima/List.pm:759 +msgid "You cannot sort by \"[_1]\"." +msgstr "無法以「 [_1] 」排序。" + +#: lib/perl5/Selima/List.pm:1082 +#: lib/perl5/Selima/List/Accounting/Reports.pm:412 +msgid "Search" +msgstr "搜尋" + +#: lib/perl5/Selima/List.pm:1181 +msgid "Index" +msgstr "目錄" + +#: lib/perl5/Selima/List.pm:1319 +msgid "Page:" +msgstr "頁:" + +#: lib/perl5/Selima/List.pm:1320 lib/perl5/Selima/List.pm:1392 +#: lib/perl5/Selima/List.pm:1449 +msgid "View" +msgstr "瀏覽" + +#: lib/perl5/Selima/List.pm:1364 lib/perl5/Selima/List.pm:1476 +msgid "Delete the selected items." +msgstr "刪除勾選的項目。" + +#: lib/perl5/Selima/List.pm:1389 +msgid "No." +msgstr "編號" + +#: lib/perl5/Selima/List.pm:1500 +#: lib/perl5/Selima/List/Accounting/Reports.pm:587 +msgid "Set" +msgstr "設定" + +#: lib/perl5/Selima/List.pm:1521 +#: lib/perl5/Selima/List/Accounting/Reports.pm:604 +msgid "Rows per page:" +msgstr "每頁顯示筆數:" + +#: lib/perl5/Selima/List.pm:1529 +msgid "Display columns:" +msgstr "顯示欄位:" + +#: lib/perl5/Selima/List.pm:1564 +msgid "Malformed" +msgstr "格式錯亂" + +#: lib/perl5/Selima/List.pm:1598 +msgid "OK" +msgstr "好" + +#: lib/perl5/Selima/List.pm:1598 +msgid "Unreachable" +msgstr "連不上" + +#: lib/perl5/Selima/LnInfo.pm:49 +msgid "Traditional Chinese" +msgstr "正體中文" + +#: lib/perl5/Selima/LnInfo.pm:59 +msgid "Simplified Chinese" +msgstr "簡體中文" + +#: lib/perl5/Selima/LnInfo.pm:69 +msgid "English" +msgstr "英文" + +#: lib/perl5/Selima/LnInfo.pm:79 +msgid "Japanese" +msgstr "日文" + +#: lib/perl5/Selima/LnInfo.pm:89 +msgid "German" +msgstr "德文" + +#: lib/perl5/Selima/LnInfo.pm:242 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "切換到本頁的%s版。" + +#: lib/perl5/Selima/PageFunc.pm:221 +msgid "Web pages" +msgstr "網頁" + +#: lib/perl5/Selima/PageFunc.pm:222 +msgid "News" +msgstr "新聞" + +#: lib/perl5/Selima/PageFunc.pm:223 +msgid "Related links" +msgstr "相關連結" + +#: lib/perl5/Selima/PageFunc.pm:224 +msgid "Home page" +msgstr "首頁" + +#: lib/perl5/Selima/PageFunc.pm:225 +msgid "Whole web site" +msgstr "整個網站" + +#: lib/perl5/Selima/Picture.pm:49 +msgid "Left-aligned" +msgstr "靠左" + +#: lib/perl5/Selima/Picture.pm:50 +msgid "Right-aligned" +msgstr "靠右" + +#: lib/perl5/Selima/Picture.pm:87 +#, c-format +msgid "Width: [#,_1], height: [#,_2], ratio: [sprintf,%0.2f,_3]" +msgstr "寬: [#,_1] ,高: [#,_2] ,比例: [sprintf,%0.2f,_3]" + +#: lib/perl5/Selima/Picture.pm:113 +msgid "Please specify a numeric ratio." +msgstr "比例請設定數字。" + +#: lib/perl5/Selima/Picture.pm:116 +msgid "Please specify a positive ratio." +msgstr "比例請設定正數。" + +#: lib/perl5/Selima/Picture.pm:118 +#, c-format +msgid "Please specify a ratio less than or equal to [sprintf,%0.2f,_1]." +msgstr "比例請勿大於 [sprintf,%0.2f,_1] 。" + +#: lib/perl5/Selima/Picture.pm:122 +msgid "This image is too large to display." +msgstr "圖片太大,無法顯示。" + +#: lib/perl5/Selima/Preview.pm:53 lib/perl5/Selima/Preview.pm:115 +msgid "Unknown preview source: \"[_1]\"." +msgstr "預覽資料源不明:「 [_1] 」。" + +#: lib/perl5/Selima/Preview.pm:69 +msgid "Unknown preview form: \"[_1]\"." +msgstr "預覽表格不明: [_1] 。" + +#: lib/perl5/Selima/Preview.pm:126 +msgid "Preview" +msgstr "預覽" + +#: lib/perl5/Selima/Preview.pm:127 +msgid "Finish preview and return." +msgstr "結束預覽回前頁。" + +#: lib/perl5/Selima/Processor.pm:203 +msgid "This record was not modified." +msgstr "資料未異動。" + +#: lib/perl5/Selima/Processor.pm:207 +msgid "This record has been successfully added." +msgstr "資料建好了。" + +#: lib/perl5/Selima/Processor.pm:211 +msgid "This record has been successfully updated." +msgstr "資料存好了。" + +#: lib/perl5/Selima/Processor.pm:215 +msgid "This record has been successfully deleted." +msgstr "資料刪掉了。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:41 +msgid "Please select a accounting transaction." +msgstr "請選擇會計傳票。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:44 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "查無此會計傳票,請重新選擇。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:62 +msgid "This option is invalid. Please select a proper type." +msgstr "類型選項無效,請由表上選擇適當的類型。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:83 +msgid "Please select a accounting subject." +msgstr "請選擇會計科目。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:86 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "查無此會計科目,請重新選擇。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:93 +msgid "" +"Only a last-level accounting subject is allowed for an accounting subject." +msgstr "限選最下層的會計科目。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:113 +msgid "This summary is too long. (Max. length [#,_1])" +msgstr "摘要太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/AcctRec.pm:137 +msgid "Please fill in the amount." +msgstr "請填上金額。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:140 +msgid "This amount is too long. (Max. length [#,_1])" +msgstr "金額太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/AcctRec.pm:144 +msgid "Please fill in a positive integer amount." +msgstr "金額請填正整數。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:39 +msgid "Please fill in the code." +msgstr "請填上代碼。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:42 +msgid "This code is too long. (Max. length [#,_1])" +msgstr "代碼太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:46 +msgid "Only numbers are allowed for the code." +msgstr "代碼限用數字。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:56 +msgid "" +"This accounting subject already exists. You cannot create a duplicated one." +msgstr "已有該會計科目,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:65 +msgid "" +"Accounting subject [_1] does not exist. You cannot create a subject under " +"that." +msgstr "查無會計科目 [_1] ,請勿建立其下的科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:80 +#: lib/perl5/Selima/Checker/AcctSubj.pm:101 +msgid "Please select a parent accounting subject." +msgstr "請選擇所屬的大會計科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:85 +msgid "" +"This option is invalid. Please select a proper parent accounting subject." +msgstr "大會計科目選項無效,請由表上選擇適當的大會計科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:92 +msgid "" +"An accounting subject having its code with a single digit must not have a " +"parent." +msgstr "會計科目代碼一位數時,不可設所屬的大會計科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:104 +msgid "" +"An accounting subject cannot belong to itself. Please select another one." +msgstr "科目不可屬於自己本身,請重新選擇。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:108 +msgid "" +"This parent accounting subject does not exist anymore. Please select " +"another one." +msgstr "查無此大會計科目,請重新選擇。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:113 +msgid "" +"The parent accounting subject of accounting subject [_1] must be of code " +"[_2], not [_3]." +msgstr "會計科目 [_1] 所屬的大會計科目代碼須為 [_2] ,不可為 [_3] 。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:122 +msgid "" +"An accounting subject having its code with more than one digit must have a " +"parent." +msgstr "會計科目代碼兩位數或以上時,須設所屬的大會計科目。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:53 +msgid "This form suptype is invalid. Please specify a proper user." +msgstr "子表單無效,請設定適當的子表單。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:73 +msgid "Please fill in the credit side of the accounting transaction." +msgstr "請填上會計傳票的貸方。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:75 +#: lib/perl5/Selima/Checker/AcctTrx.pm:98 +msgid "Please fill in the accounting transaction content." +msgstr "請填上會計傳票內容。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:96 +msgid "Please fill in the debit side of the accounting transaction." +msgstr "請填上會計傳票的借方。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:162 +msgid "" +"The total amounts of the debit side and the credit side are not balanced " +"(debit [_1], credit [_2]." +msgstr "借方和貸方總金額未平衡。(借方合計 [_1] ,貸方合計 [_2] )" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:182 +#: lib/perl5/Selima/Form/AcctTrx.pm:802 +msgid "Fill in the note here." +msgstr "請填上註記。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:185 +msgid "This note is too long. (Max. length [#,_1])" +msgstr "註記太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/GroupMem.pm:54 +msgid "Please select a different belonging group." +msgstr "隸屬群組請選擇別的群組。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:74 +#: lib/perl5/Selima/Checker/UserMem.pm:59 +msgid "Please select a member." +msgstr "請選擇成員。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:77 +#: lib/perl5/Selima/Checker/UserMem.pm:62 +msgid "This member does not exist anymore. Please select another one." +msgstr "查無此成員,請重新選擇。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:80 +msgid "Please select a different group member." +msgstr "群組成員請選擇別的群組。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:103 +#: lib/perl5/Selima/Checker/UserMem.pm:83 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "已有同一成員關係,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/Group.pm:45 +msgid "Please fill in the group ID." +msgstr "請填上群組代號。" + +#: lib/perl5/Selima/Checker/Group.pm:48 +msgid "This group ID. is too long. (Max. length [#,_1])" +msgstr "群組代號太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Group.pm:51 +msgid "This group ID. is too short. (Min. length [#,_1])" +msgstr "群組代號太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/Group.pm:55 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "群組代號限用小寫英文字母、數字和底線。" + +#: lib/perl5/Selima/Checker/Group.pm:65 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "已有同一群組,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/Group.pm:83 +msgid "Please fill in the privilege description." +msgstr "請填上權限說明。" + +#: lib/perl5/Selima/Checker/Group.pm:86 +msgid "This privilege description is too long. (Max. length [#,_1])" +msgstr "權限說明太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:38 +#: lib/perl5/Selima/Checker/Guestbook.pm:60 +msgid "This signature is too long. (Max. length [#,_1])" +msgstr "簽名太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:57 +msgid "Please fill in the signature." +msgstr "請填上簽名。" + +#: lib/perl5/Selima/Checker/Guestbook.pm:79 +msgid "This identity is too long. (Max. length [#,_1])" +msgstr "身份太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:98 +msgid "This location is too long. (Max. length [#,_1])" +msgstr "所在地太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:117 +#: lib/perl5/Selima/Checker/Link.pm:92 lib/perl5/Selima/Checker/User.pm:229 +msgid "This e-mail is too long. (Max. length [#,_1])" +msgstr "E-mail 信箱太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:136 +msgid "This website URL is too long. (Max. length [#,_1])" +msgstr "網站網址太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/LinkCat.pm:40 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "「 index 」為目錄檔 index.html 專用,代號不可設為「 index 」。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:56 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "已有同一分類,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:70 +#: lib/perl5/Selima/Checker/LinkCat.pm:85 +msgid "Please select a parent category." +msgstr "請選擇所屬的大類。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:75 +msgid "This option is invalid. Please select a proper parent category." +msgstr "大類選項無效,請由表上選擇適當的大類。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:88 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "查無此大類,請重新選擇。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:92 +msgid "A category cannot belong to itself. Please select another one." +msgstr "分類不可屬於自己本身,請重新選擇。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:99 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "分類不可屬於自己的子類,請重新選擇。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:56 lib/perl5/Selima/Checker/Link.pm:72 +msgid "Please select a category." +msgstr "請選擇分類。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:59 lib/perl5/Selima/Checker/Link.pm:67 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:77 +msgid "Please select a related link." +msgstr "請選擇相關連結。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:80 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查無此相關連結,請重新選擇。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:101 +msgid "" +"This categorization record already exists. You cannot create a duplicated " +"one." +msgstr "已有同一分類資料,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/Link.pm:44 +msgid "This address is too long. (Max. length [#,_1])" +msgstr "地址太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:64 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "分類重複,請勿重複設定。" + +#: lib/perl5/Selima/Checker/Link.pm:95 lib/perl5/Selima/Checker/User.pm:232 +msgid "This e-mail is too short. (Min. length [#,_1])" +msgstr "E-mail 信箱太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:99 lib/perl5/Selima/Checker/MailTo.pm:36 +#: lib/perl5/Selima/Checker/User.pm:236 +msgid "Please fill in a valid e-mail address." +msgstr "請填上正確的 E-mail 信箱。" + +#: lib/perl5/Selima/Checker/Link.pm:101 lib/perl5/Selima/Checker/MailTo.pm:38 +#: lib/perl5/Selima/Checker/User.pm:238 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "查無這個信箱的所屬網域,請檢查有沒有拼錯。" + +#: lib/perl5/Selima/Checker/Link.pm:122 +msgid "This facsimile number is too long. (Max. length [#,_1])" +msgstr "傳真號碼太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:143 +msgid "This link icon URL is too long. (Max. length [#,_1])" +msgstr "連結小圖網址太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:147 +msgid "Please fill in a valid link icon URL." +msgstr "請填上正確的連結小圖網址。" + +#: lib/perl5/Selima/Checker/Link.pm:150 +msgid "This link icon URL is not reachable. Check if there is any typo in it." +msgstr "連結小圖連不上,請檢查有沒有拼錯。" + +#: lib/perl5/Selima/Checker/Link.pm:171 +msgid "This telephone number is too long. (Max. length [#,_1])" +msgstr "電話號碼太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:192 +msgid "This 2nd language title is too long. (Max. length [#,_1])" +msgstr "第二語言標題太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:211 +msgid "Please fill in the URL." +msgstr "請填上網址。" + +#: lib/perl5/Selima/Checker/Link.pm:214 +msgid "This URL is too long. (Max. length [#,_1])" +msgstr "網址太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:218 +msgid "Please fill in a valid URL." +msgstr "請填上正確的網址。" + +#: lib/perl5/Selima/Checker/Link.pm:228 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "已有同一相關連結,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/Link.pm:231 +msgid "This URL is not reachable. Check if there is any typo in it." +msgstr "這個網址連不上,請檢查有沒有拼錯。" + +#: lib/perl5/Selima/Checker/ListPref.pm:42 +#: lib/perl5/Selima/Checker/UserPref.pm:88 +msgid "Please fill in the preference domain." +msgstr "請填上偏好的適用範圍。" + +#: lib/perl5/Selima/Checker/ListPref.pm:45 +#: lib/perl5/Selima/Checker/UserPref.pm:91 +msgid "This preference domain is too long. (Max. length [#,_1])" +msgstr "偏好適用範圍太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/ListPref.pm:90 +msgid "Please fill in the number of rows per page." +msgstr "請填上每頁顯示筆數。" + +#: lib/perl5/Selima/Checker/ListPref.pm:93 +msgid "Please fill in a positive integer number of rows per page." +msgstr "每頁顯示筆數請填正整數。" + +#: lib/perl5/Selima/Checker/ListPref.pm:100 +msgid "This number of rows per page is too long. (Max. length [#,_1])" +msgstr "每頁顯示筆數太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/LogIn.pm:63 +msgid "Please fill in your user ID." +msgstr "請填上妳的帳號。" + +#: lib/perl5/Selima/Checker/LogIn.pm:70 lib/perl5/Selima/Checker/LogIn.pm:76 +#: lib/perl5/Selima/Checker/LogIn.pm:91 lib/perl5/Selima/Checker/LogIn.pm:136 +#: lib/perl5/Selima/Checker/LogIn.pm:142 lib/perl5/Selima/Checker/LogIn.pm:151 +#: lib/perl5/Selima/Checker/LogIn.pm:178 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "登入錯誤,使用者代號或密碼有誤。" + +#: lib/perl5/Selima/Checker/LogIn.pm:109 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "帳號停用中,請洽系統管理員。" + +#: lib/perl5/Selima/Checker/LogIn.pm:129 +msgid "Please fill in your password." +msgstr "請填上妳的密碼。" + +#: lib/perl5/Selima/Checker/LogIn.pm:199 +msgid "You are not an administrator and cannot log into here." +msgstr "非管理員勿入。" + +#: lib/perl5/Selima/Checker/LogIn.pm:218 +msgid "You are an administrator and cannot log into here." +msgstr "管理人員勿入。" + +#: lib/perl5/Selima/Checker/MailTo.pm:29 lib/perl5/Selima/Checker/User.pm:226 +msgid "Please fill in the e-mail." +msgstr "請填上 E-mail 信箱。" + +#: lib/perl5/Selima/Checker/Rebuild.pm:28 +msgid "Please select the type." +msgstr "請選擇類型。" + +#: lib/perl5/Selima/Checker/Rebuild.pm:31 +msgid "This type does not exist anymore. Please select another one." +msgstr "查無此類型,請重新選擇。" + +#: lib/perl5/Selima/Checker/ScptPriv.pm:63 +msgid "" +"This script privilege record already exists. You cannot create a duplicated " +"one." +msgstr "已有同一程式權限資料,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/User.pm:85 +msgid "Please fill in the user ID." +msgstr "請填上帳號。" + +#: lib/perl5/Selima/Checker/User.pm:88 +msgid "This user ID. is too long. (Max. length [#,_1])" +msgstr "帳號太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:91 +msgid "This user ID. is too short. (Min. length [#,_1])" +msgstr "帳號太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:95 +msgid "" +"Only English letters, numbers, at-signs, dots, dashes and underscores are " +"allowed for the user ID." +msgstr "帳號限用英文字母、數字、 @ 號、點、橫線和底線。" + +#: lib/perl5/Selima/Checker/User.pm:105 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "該使用者已有帳號,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/User.pm:129 +msgid "Please fill in the password." +msgstr "請填上密碼。" + +#: lib/perl5/Selima/Checker/User.pm:131 +msgid "Please confirm the password." +msgstr "請確認密碼。" + +#: lib/perl5/Selima/Checker/User.pm:134 +msgid "This password is too long. (Max. length [#,_1])" +msgstr "密碼太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:137 +msgid "This password is too short. (Min. length [#,_1])" +msgstr "密碼太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:142 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "兩次密碼不合,請重新設定密碼。" + +#: lib/perl5/Selima/Checker/User.pm:151 +msgid "This password is based on the user ID." +msgstr "密碼不可由帳號組成。" + +#: lib/perl5/Selima/Checker/User.pm:166 +msgid "This password does not contain enough different characters." +msgstr "密碼重複的字元太多。" + +#: lib/perl5/Selima/Checker/User.pm:170 +msgid "This password is too simplistic/systematic." +msgstr "密碼結構太簡單。" + +#: lib/perl5/Selima/Checker/User.pm:174 +msgid "This password is based on a dictionary word." +msgstr "密碼不可由字典單字組成。" + +#: lib/perl5/Selima/Checker/User.pm:176 +msgid "This password is based on a (reversed) dictionary word." +msgstr "密碼不可由倒過來的字典單字組成。" + +#: lib/perl5/Selima/Checker/User.pm:178 +msgid "This password is too simple." +msgstr "密碼太簡單。" + +#: lib/perl5/Selima/Checker/User.pm:183 +msgid "You cannot use a password that is based on your user ID." +msgstr "密碼不可由帳號組成。" + +#: lib/perl5/Selima/Checker/User.pm:203 +msgid "Please fill in the name." +msgstr "請填上姓名。" + +#: lib/perl5/Selima/Checker/User.pm:206 +msgid "This name is too long. (Max. length [#,_1])" +msgstr "姓名太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:259 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "隸屬群組重複,請勿重複設定。" + +#: lib/perl5/Selima/Checker/User.pm:271 +msgid "You cannot submit the super-user group along with other groups." +msgstr "總管理員群組不可與其它群組一起設定。" + +#: lib/perl5/Selima/Checker/User.pm:273 +msgid "You cannot set the administrators group." +msgstr "不可設定所有網站管理員群組" + +#: lib/perl5/Selima/Checker/User.pm:275 +msgid "You cannot set the all-users group." +msgstr "不可設定所有登入使用者群組。" + +#: lib/perl5/Selima/Checker/UserPref.pm:50 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: lib/perl5/Selima/Checker/UserPref.pm:55 +msgid "This option is invalid. Please select a proper user." +msgstr "使用者選項無效,請由表上選擇適當的使用者。" + +#: lib/perl5/Selima/Checker/UserPref.pm:73 +msgid "Please set the preference domain." +msgstr "請設定適用範圍。" + +#: lib/perl5/Selima/Checker/UserPref.pm:78 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "適用範圍選項無效,請設定適當的適用範圍。" + +#: lib/perl5/Selima/Checker/UserPref.pm:111 +msgid "Please fill in the preference name." +msgstr "請填上偏好的名稱。" + +#: lib/perl5/Selima/Checker/UserPref.pm:114 +msgid "This preference name is too long. (Max. length [#,_1])" +msgstr "偏好名稱太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/UserPref.pm:133 +msgid "Please fill in the preference value." +msgstr "請填上偏好的值。" + +#: lib/perl5/Selima/Checker/UserPref.pm:136 +msgid "This preference value is too long. (Max. length [#,_1])" +msgstr "偏好值太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/UserPref.pm:167 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "已有同一使用者偏好,請勿重複建檔。" + +#: lib/perl5/Selima/Form/AcctRec.pm:33 +msgid "Delete this accounting record" +msgstr "刪掉這筆會計分錄" + +#: lib/perl5/Selima/Form/AcctRec.pm:38 +msgid "This table provides you a form to add a new accounting record." +msgstr "本表提供建新會計分錄的表單。" + +#: lib/perl5/Selima/Form/AcctRec.pm:41 +msgid "This table provides you a form to edit a current accounting record." +msgstr "本表提供編輯會計分錄的表單。" + +#: lib/perl5/Selima/Form/AcctRec.pm:44 +msgid "This table provides you a form to delete an accounting record." +msgstr "本表提供刪除會計分錄的表單。" + +#: lib/perl5/Selima/Form/AcctRec.pm:61 +msgid "Add a New Accounting Record" +msgstr "建新會計分錄。" + +#: lib/perl5/Selima/Form/AcctRec.pm:64 +msgid "Edit a Current Accounting Record" +msgstr "編輯會計分錄" + +#: lib/perl5/Selima/Form/AcctRec.pm:67 +msgid "Delete an Accounting Record" +msgstr "刪除會計分錄" + +#: lib/perl5/Selima/Form/AcctRec.pm:76 +msgid "Accounting transaction:" +msgstr "會計傳票:" + +#: lib/perl5/Selima/Form/AcctRec.pm:85 lib/perl5/Selima/Form/AcctTrx.pm:334 +#: lib/perl5/Selima/List/Accounting/Reports.pm:75 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:233 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:226 +msgid "Debit" +msgstr "借方" + +#: lib/perl5/Selima/Form/AcctRec.pm:87 lib/perl5/Selima/Form/AcctTrx.pm:335 +#: lib/perl5/Selima/List/Accounting/Reports.pm:76 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:237 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:230 +msgid "Credit" +msgstr "貸方" + +#: lib/perl5/Selima/Form/AcctRec.pm:88 lib/perl5/Selima/Form/Rebuild.pm:52 +msgid "Type:" +msgstr "類型:" + +#: lib/perl5/Selima/Form/AcctRec.pm:99 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:284 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:268 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:328 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:284 +msgid "Accounting subject:" +msgstr "會計科目:" + +#: lib/perl5/Selima/Form/AcctRec.pm:157 +msgid "Summary:" +msgstr "摘要:" + +#: lib/perl5/Selima/Form/AcctRec.pm:162 +msgid "Amount:" +msgstr "金額:" + +#: lib/perl5/Selima/Form/AcctSubj.pm:34 +msgid "Delete this accounting subject" +msgstr "刪掉這個會計科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:39 +msgid "This table provides you a form to add a new accounting subject." +msgstr "本表提供建新會計科目的表單。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:42 +msgid "This table provides you a form to edit a current accounting subject." +msgstr "本表提供編輯會計科目的表單。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:45 +msgid "This table provides you a form to delete an accounting subject." +msgstr "本表提供刪除會計科目的表單。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:62 +msgid "Add a New Accounting Subject" +msgstr "建新會計科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:65 +msgid "Edit a Current Accounting Subject" +msgstr "編輯會計科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:68 +msgid "Delete an Accounting Subject" +msgstr "刪除會計科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:75 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the accounting " +"subject, [numerate,_1,its accounting sub-subject,all of its accounting sub-" +"subjects] must first be deleted." +msgstr "" +"本會計科目下有子會計科目,不可直接刪除。要刪除本科目,請先刪除其下的子會計科" +"目。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:79 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the accounting subject, " +"[numerate,_1,its accounting record,all of its accounting records] must first " +"be deleted." +msgstr "" +"本會計科目下有會計分錄,不可直接刪除。要刪除本會計科目,請先刪除其下的會計分" +"錄。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:87 +msgid "Code:" +msgstr "代碼:" + +#: lib/perl5/Selima/Form/AcctSubj.pm:93 +msgid "Parent subject:" +msgstr "大科目:" + +#: lib/perl5/Selima/Form/AcctSubj.pm:106 +msgid "[numerate,_1,Sub-subject,Sub-subjects]:" +msgstr "子科目:" + +#: lib/perl5/Selima/Form/AcctTrx.pm:37 +msgid "Delete this accounting transaction" +msgstr "刪掉這筆會計傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:43 +msgid "This table provides you a form to add a new accounting transaction." +msgstr "本表提供建新會計傳票的表單。" + +#: lib/perl5/Selima/Form/AcctTrx.pm:46 +msgid "" +"This table provides you a form to edit a current accounting transaction." +msgstr "本表提供編輯會計傳票的表單。" + +#: lib/perl5/Selima/Form/AcctTrx.pm:49 +msgid "This table provides you a form to delete an accounting transaction." +msgstr "本表提供刪除會計傳票的表單。" + +#: lib/perl5/Selima/Form/AcctTrx.pm:92 lib/perl5/Selima/Form/AcctTrx.pm:97 +msgid "Convert to a transfer transaction" +msgstr "轉為轉帳傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:102 +msgid "Add a New Cache Expense Transaction" +msgstr "建新現金支出傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:104 +msgid "Add a New Cache Income Transaction" +msgstr "建新現金收入傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:106 +msgid "Add a New Transfer Transaction" +msgstr "建新轉帳傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:111 +msgid "Edit a Current Cache Expense Transaction" +msgstr "編輯現金支出傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:113 +msgid "Edit a Current Cache Income Transaction" +msgstr "編輯現金收入傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:115 +msgid "Edit a Current Transfer Transaction" +msgstr "編輯轉帳傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:120 +msgid "Delete a Cache Expense Transaction" +msgstr "刪除現金支出傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:122 +msgid "Delete a Cache Income Transaction" +msgstr "刪除現金收入傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:124 +msgid "Delete a Transfer Transaction" +msgstr "刪掉轉帳傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:336 +#: lib/perl5/Selima/List/Accounting/Records.pm:35 +#: lib/perl5/Selima/List/Accounting/Reports.pm:73 +msgid "Accounting subject" +msgstr "會計科目" + +#: lib/perl5/Selima/Form/AcctTrx.pm:337 +#: lib/perl5/Selima/List/Accounting/Records.pm:36 +#: lib/perl5/Selima/List/Accounting/Reports.pm:74 +msgid "Summary" +msgstr "摘要" + +#: lib/perl5/Selima/Form/AcctTrx.pm:338 +#: lib/perl5/Selima/List/Accounting/Records.pm:37 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:40 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:41 +msgid "Amount" +msgstr "金額" + +#: lib/perl5/Selima/Form/AcctTrx.pm:339 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:173 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:196 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:200 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:152 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:130 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:151 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:177 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:166 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:189 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:144 +msgid "Total" +msgstr "合計" + +#: lib/perl5/Selima/Form/AcctTrx.pm:379 lib/perl5/Selima/Form/AcctTrx.pm:518 +#: lib/perl5/Selima/Form/AcctTrx.pm:708 +msgid "[numerate,_1,Content]:" +msgstr "內容:" + +#: lib/perl5/Selima/Form/AcctTrx.pm:801 +msgid "Note:" +msgstr "註記:" + +#: lib/perl5/Selima/Form/GroupMem.pm:33 lib/perl5/Selima/Form/UserMem.pm:33 +msgid "Delete this membership record" +msgstr "刪掉這筆成員關係" + +#: lib/perl5/Selima/Form/GroupMem.pm:38 lib/perl5/Selima/Form/UserMem.pm:38 +msgid "This table provides you a form to add a new membership record." +msgstr "本表提供建新成員關係的表單。" + +#: lib/perl5/Selima/Form/GroupMem.pm:41 lib/perl5/Selima/Form/UserMem.pm:41 +msgid "This table provides you a form to change a current membership record." +msgstr "本表提供變更成員關係的表單。" + +#: lib/perl5/Selima/Form/GroupMem.pm:44 lib/perl5/Selima/Form/UserMem.pm:44 +msgid "This table provides you a form to delete a membership record." +msgstr "本表提供刪除成員關係的表單。" + +#: lib/perl5/Selima/Form/GroupMem.pm:61 +msgid "Add A New Group Membership Record" +msgstr "建新群組成員關係" + +#: lib/perl5/Selima/Form/GroupMem.pm:64 +msgid "Change a Current Group Membership Record" +msgstr "變更群組成員關係" + +#: lib/perl5/Selima/Form/GroupMem.pm:67 +msgid "Delete a Group Membership Record" +msgstr "刪除群組成員關係" + +#: lib/perl5/Selima/Form/GroupMem.pm:76 lib/perl5/Selima/Form/UserMem.pm:76 +msgid "Member:" +msgstr "成員:" + +#: lib/perl5/Selima/Form/Group.pm:37 +msgid "Delete this group" +msgstr "刪掉這個群組" + +#: lib/perl5/Selima/Form/Group.pm:42 +msgid "This table provides you a form to add a new group." +msgstr "本表提供建新群組的表單。" + +#: lib/perl5/Selima/Form/Group.pm:45 +msgid "This table provides you a form to update a current group." +msgstr "本表提供設定群組的表單。" + +#: lib/perl5/Selima/Form/Group.pm:48 +msgid "This table provides you a form to delete a group." +msgstr "本表提供刪除群組的表單。" + +#: lib/perl5/Selima/Form/Group.pm:65 +msgid "Add a New Group" +msgstr "建新群組" + +#: lib/perl5/Selima/Form/Group.pm:68 +msgid "Update a Current Group" +msgstr "設定群組" + +#: lib/perl5/Selima/Form/Group.pm:71 +msgid "Delete a Group" +msgstr "刪除群組" + +#: lib/perl5/Selima/Form/Group.pm:77 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "這是最高管理員的群組,妳只能設定它部份的資料。" + +#: lib/perl5/Selima/Form/Group.pm:89 lib/perl5/Selima/Form/Group.pm:91 +msgid "Group ID.:" +msgstr "群組代號:" + +#: lib/perl5/Selima/Form/Group.pm:110 +msgid "Add a user" +msgstr "增加成員" + +#: lib/perl5/Selima/Form/Group.pm:114 lib/perl5/Selima/Form/Group.pm:148 +#: lib/perl5/Selima/Form/Group.pm:164 lib/perl5/Selima/Form/Group.pm:211 +msgid "[numerate,_1,User member]:" +msgstr "使用者成員:" + +#: lib/perl5/Selima/Form/Group.pm:239 lib/perl5/Selima/Form/Group.pm:369 +msgid "Add a group" +msgstr "增加群組" + +#: lib/perl5/Selima/Form/Group.pm:243 lib/perl5/Selima/Form/Group.pm:277 +#: lib/perl5/Selima/Form/Group.pm:293 lib/perl5/Selima/Form/Group.pm:340 +msgid "[numerate,_1,Group member]:" +msgstr "群組成員:" + +#: lib/perl5/Selima/Form/Group.pm:368 lib/perl5/Selima/Form/User.pm:223 +msgid "Belonging to:" +msgstr "隸屬群組:" + +#: lib/perl5/Selima/Form/Guestbook.pm:32 +msgid "Delete this message" +msgstr "刪掉這則留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:37 +msgid "This table provides you a form to add a new message." +msgstr "本表提供寫新留言的表單。" + +#: lib/perl5/Selima/Form/Guestbook.pm:40 +msgid "This table provides you a form to edit a current message." +msgstr "本表提供編輯留言的表單。" + +#: lib/perl5/Selima/Form/Guestbook.pm:43 +msgid "This table provides you a form to delete a message." +msgstr "本表提供刪除留言的表單。" + +#: lib/perl5/Selima/Form/Guestbook.pm:61 +msgid "Write a New Message" +msgstr "寫新留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:64 +msgid "Edit a Current Message" +msgstr "編輯留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:67 +msgid "Delete a Message" +msgstr "刪除留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:77 lib/perl5/Selima/Form/User.pm:149 +msgid "Country:" +msgstr "國家:" + +#: lib/perl5/Selima/Form/Guestbook.pm:83 +msgid "Hide this message" +msgstr "隱藏這則留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:83 +msgid "Show this message" +msgstr "秀出這則留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:84 +msgid "Hide this message currently." +msgstr "暫勿秀出這則留言。" + +#: lib/perl5/Selima/Form/Guestbook.pm:89 +msgid "Signature:" +msgstr "簽名:" + +#: lib/perl5/Selima/Form/Guestbook.pm:94 +msgid "Old page no.:" +msgstr "舊頁數:" + +#: lib/perl5/Selima/Form/Guestbook.pm:99 +msgid "Page no.:" +msgstr "頁數:" + +#: lib/perl5/Selima/Form/LinkCat.pm:33 +msgid "Delete this category" +msgstr "刪掉這個分類" + +#: lib/perl5/Selima/Form/LinkCat.pm:38 +msgid "This table provides you a form to add a new category." +msgstr "本表提供建新分類的表單。" + +#: lib/perl5/Selima/Form/LinkCat.pm:41 +msgid "This table provides you a form to edit a current category." +msgstr "本表提供編輯分類的表單。" + +#: lib/perl5/Selima/Form/LinkCat.pm:44 +msgid "This table provides you a form to delete a category." +msgstr "本表提供刪除分類的表單。" + +#: lib/perl5/Selima/Form/LinkCat.pm:62 +msgid "Add a New Link Category" +msgstr "建新連結分類" + +#: lib/perl5/Selima/Form/LinkCat.pm:65 +msgid "Edit a Current Link Category" +msgstr "編輯連結分類" + +#: lib/perl5/Selima/Form/LinkCat.pm:68 +msgid "Delete a Link Category" +msgstr "刪除連結分類" + +#: lib/perl5/Selima/Form/LinkCat.pm:76 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: lib/perl5/Selima/Form/LinkCat.pm:80 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: lib/perl5/Selima/Form/LinkCat.pm:89 +msgid "Hide this category" +msgstr "隱藏這個分類" + +#: lib/perl5/Selima/Form/LinkCat.pm:89 +msgid "Show this category" +msgstr "秀出這個分類" + +#: lib/perl5/Selima/Form/LinkCat.pm:90 +msgid "Hide this category currently." +msgstr "暫勿秀出這個分類。" + +#: lib/perl5/Selima/Form/LinkCat.pm:106 +msgid "[numerate,_1,Link,Links]:" +msgstr "連結:" + +#: lib/perl5/Selima/Form/LinkCatz.pm:33 +msgid "Delete this categorization record" +msgstr "刪掉這筆分類資料" + +#: lib/perl5/Selima/Form/LinkCatz.pm:38 +msgid "This table provides you a form to add a new categorization record." +msgstr "本表提供建新分類資料的表單。" + +#: lib/perl5/Selima/Form/LinkCatz.pm:41 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "本表提供變更分類資料的表單。" + +#: lib/perl5/Selima/Form/LinkCatz.pm:44 +msgid "This table provides you a form to delete a categorization record." +msgstr "本表提供刪除分類資料的表單。" + +#: lib/perl5/Selima/Form/LinkCatz.pm:61 +msgid "Add A New Link Categorization Record" +msgstr "建新連結分類資料" + +#: lib/perl5/Selima/Form/LinkCatz.pm:64 +msgid "Change a Current Link Categorization Record" +msgstr "變更連結分類資料" + +#: lib/perl5/Selima/Form/LinkCatz.pm:67 +msgid "Delete a Link Categorization Record" +msgstr "刪除連結分類資料" + +#: lib/perl5/Selima/Form/LinkCatz.pm:76 +msgid "Category:" +msgstr "分類:" + +#: lib/perl5/Selima/Form/LinkCatz.pm:81 +msgid "Link:" +msgstr "連結:" + +#: lib/perl5/Selima/Form/Link.pm:35 +msgid "Delete this related link" +msgstr "刪掉這筆相關連結" + +#: lib/perl5/Selima/Form/Link.pm:40 +msgid "This table provides you a form to add a new related link." +msgstr "本表提供建新相關連結的表單。" + +#: lib/perl5/Selima/Form/Link.pm:43 +msgid "This table provides you a form to edit a current related link." +msgstr "本表提供編輯相關連結的表單。" + +#: lib/perl5/Selima/Form/Link.pm:46 +msgid "This table provides you a form to delete a related link." +msgstr "本表提供刪除相關連結的表單。" + +#: lib/perl5/Selima/Form/Link.pm:65 +msgid "Add a New Related Link" +msgstr "建新相關連結" + +#: lib/perl5/Selima/Form/Link.pm:68 +msgid "Edit a Current Related Link" +msgstr "編輯相關連結" + +#: lib/perl5/Selima/Form/Link.pm:71 +msgid "Delete a Related Link" +msgstr "刪除相關連結" + +#: lib/perl5/Selima/Form/Link.pm:81 +msgid "[numerate,_1,Category,Categories]:" +msgstr "分類:" + +#: lib/perl5/Selima/Form/Link.pm:88 +msgid "Hide this related link" +msgstr "隱藏這筆相關連結" + +#: lib/perl5/Selima/Form/Link.pm:88 +msgid "Show this related link" +msgstr "秀出這筆相關連結" + +#: lib/perl5/Selima/Form/Link.pm:89 +msgid "Hide this related link currently." +msgstr "暫勿秀出這筆相關連結。" + +#: lib/perl5/Selima/Form/Link.pm:100 +msgid "Link icon:" +msgstr "連結小圖:" + +#: lib/perl5/Selima/Form/Link.pm:101 +msgid "Link icon unavailable" +msgstr "連結小圖無法顯示" + +#: lib/perl5/Selima/Form/Link.pm:173 +msgid "2nd language title:" +msgstr "第二語言標題:" + +#: lib/perl5/Selima/Form/Page.pm:32 +msgid "Delete this page" +msgstr "刪掉這一頁" + +#: lib/perl5/Selima/Form/Page.pm:37 +msgid "This table provides you a form to write a new page." +msgstr "本表提供寫新網頁的表單。" + +#: lib/perl5/Selima/Form/Page.pm:40 +msgid "This table provides you a form to edit a current page." +msgstr "本表提供編輯網頁的表單。" + +#: lib/perl5/Selima/Form/Page.pm:43 +msgid "This table provides you a form to delete a page." +msgstr "本表提供刪除網頁的表單。" + +#: lib/perl5/Selima/Form/Page.pm:60 +msgid "Write a New Page" +msgstr "寫新網頁" + +#: lib/perl5/Selima/Form/Page.pm:63 +msgid "Edit a Current Page" +msgstr "編輯網頁" + +#: lib/perl5/Selima/Form/Page.pm:66 +msgid "Delete a Page" +msgstr "刪除網頁" + +#: lib/perl5/Selima/Form/Page.pm:73 +msgid "Preview this page." +msgstr "預覽本頁。" + +#: lib/perl5/Selima/Form/Page.pm:82 +msgid "Hide this page" +msgstr "隱藏這頁網頁" + +#: lib/perl5/Selima/Form/Page.pm:82 +msgid "Show this page" +msgstr "秀出這頁網頁" + +#: lib/perl5/Selima/Form/Page.pm:83 +msgid "Hide this page currently." +msgstr "暫勿秀出這頁網頁。" + +#: lib/perl5/Selima/Form/Rebuild.pm:36 +msgid "Rebuild the Pages" +msgstr "重製網頁" + +#: lib/perl5/Selima/Form/Rebuild.pm:41 +msgid "Confirm" +msgstr "確定" + +#: lib/perl5/Selima/Form/ScptPriv.pm:33 +msgid "Delete this script privilege record" +msgstr "刪掉這筆程式權限資料" + +#: lib/perl5/Selima/Form/ScptPriv.pm:38 +msgid "This table provides you a form to add a new script privilege record." +msgstr "本表提供建新程式權限資料的表單。" + +#: lib/perl5/Selima/Form/ScptPriv.pm:41 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "本表提供變更程式權限資料的表單。" + +#: lib/perl5/Selima/Form/ScptPriv.pm:44 +msgid "This table provides you a form to delete a script privilege record." +msgstr "本表提供刪除程式權限資料的表單。" + +#: lib/perl5/Selima/Form/ScptPriv.pm:61 +msgid "Add A New Script Privilege Record" +msgstr "建新程式權限資料" + +#: lib/perl5/Selima/Form/ScptPriv.pm:64 +msgid "Change a Current Script Privilege Record" +msgstr "變更程式權限資料" + +#: lib/perl5/Selima/Form/ScptPriv.pm:67 +msgid "Delete a Script Privilege Record" +msgstr "刪除程式權限資料" + +#: lib/perl5/Selima/Form/ScptPriv.pm:76 +msgid "Privilege:" +msgstr "權限:" + +#: lib/perl5/Selima/Form/UserMem.pm:61 +msgid "Add A New User Membership Record" +msgstr "建新使用者成員關係" + +#: lib/perl5/Selima/Form/UserMem.pm:64 +msgid "Change a Current User Membership Record" +msgstr "變更使用者成員關係" + +#: lib/perl5/Selima/Form/UserMem.pm:67 +msgid "Delete a User Membership Record" +msgstr "刪除使用者成員關係" + +#: lib/perl5/Selima/Form/User.pm:39 +msgid "Delete this user account" +msgstr "刪掉這個帳號" + +#: lib/perl5/Selima/Form/User.pm:46 +msgid "This table provides you a form to add a new user account." +msgstr "本表提供建新帳號的表單。" + +#: lib/perl5/Selima/Form/User.pm:49 +msgid "This table provides you a form to update a current user account." +msgstr "本表提供設定帳號的表單。" + +#: lib/perl5/Selima/Form/User.pm:52 +msgid "This table provides you a form to delete a user account." +msgstr "本表提供刪除帳號的表單。" + +#: lib/perl5/Selima/Form/User.pm:70 +msgid "Add a New User Account" +msgstr "建新帳號" + +#: lib/perl5/Selima/Form/User.pm:73 +msgid "Update a Current User Account" +msgstr "設定帳號" + +#: lib/perl5/Selima/Form/User.pm:76 +msgid "Delete a User Account" +msgstr "刪除帳號" + +#: lib/perl5/Selima/Form/User.pm:84 +msgid "This is a super-user. You can only change parts of her/his infomation." +msgstr "這個人是總管理員,妳只能設定她/他部份的資料。" + +#: lib/perl5/Selima/Form/User.pm:143 +msgid "Administrator?" +msgstr "網站管理員?" + +#: lib/perl5/Selima/Form/User.pm:144 +msgid "Administrator" +msgstr "網站管理員" + +#: lib/perl5/Selima/Form/User.pm:144 +msgid "Non-administrator" +msgstr "普通使用者" + +#: lib/perl5/Selima/Form/User.pm:165 +msgid "Disable this user account." +msgstr "帳號停用。" + +#: lib/perl5/Selima/Form/User.pm:176 lib/perl5/Selima/Form/User.pm:178 +msgid "User ID.:" +msgstr "使用者代號:" + +#: lib/perl5/Selima/Form/User.pm:184 +msgid "Pref. language:" +msgstr "語言偏好:" + +#: lib/perl5/Selima/Form/User.pm:189 +msgid "Full name:" +msgstr "姓名:" + +#: lib/perl5/Selima/Form/UserPref.pm:35 +msgid "Delete this user preference" +msgstr "刪掉這筆使用者偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:40 +msgid "This table provides you a form to add a new user preference." +msgstr "本表提供建新使用者偏好的表單。" + +#: lib/perl5/Selima/Form/UserPref.pm:43 +msgid "This table provides you a form to modify a current user preference." +msgstr "本表提供設定使用者偏好的表單。" + +#: lib/perl5/Selima/Form/UserPref.pm:46 +msgid "This table provides you a form to delete a user preference." +msgstr "本表提供刪除使用者偏好的表單。" + +#: lib/perl5/Selima/Form/UserPref.pm:63 +msgid "Add A New User Preference" +msgstr "建新使用者偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:66 +msgid "Modify a Current User Preference" +msgstr "設定使用者偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:69 +msgid "Delete a User Preference" +msgstr "刪除使用者偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:82 +msgid "Domain:" +msgstr "適用範圍:" + +#: lib/perl5/Selima/Form/UserPref.pm:83 +msgid "Everywhere" +msgstr "所有地方" + +#: lib/perl5/Selima/Form/UserPref.pm:88 +msgid "User:" +msgstr "使用者:" + +#: lib/perl5/Selima/Form/UserPref.pm:89 +msgid "Everyone" +msgstr "所有人" + +#: lib/perl5/Selima/List/ActLog.pm:31 +msgid "Browse the Activity Log" +msgstr "查閱網站活動日誌" + +#: lib/perl5/Selima/List/ActLog.pm:132 +msgid "Please fill in the number of rows to display." +msgstr "請填上顯示筆數。" + +#: lib/perl5/Selima/List/ActLog.pm:135 +msgid "Please fill in a positive integer number of rows to display." +msgstr "顯示筆數請填正整數。" + +#: lib/perl5/Selima/List/ActLog.pm:140 +msgid "This number of rows to display is too long. (Max. length [#,_1])" +msgstr "顯示筆數太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/List/ActLog.pm:157 +msgid "Search for log entries:" +msgstr "搜尋記錄:" + +#: lib/perl5/Selima/List/ActLog.pm:162 +msgid "Display" +msgstr "顯示" + +#: lib/perl5/Selima/List/ActLog.pm:163 +msgid "Display rows:" +msgstr "顯示筆數:" + +#: lib/perl5/Selima/List/ActLog.pm:198 +msgid "Your query found [*,_1,log entry,log entries]." +msgstr "共 [#,_1] 筆相符的記錄。" + +#: lib/perl5/Selima/List/ActLog.pm:201 +msgid "[*,_1,log entry,log entries]." +msgstr "共 [#,_1] 筆記錄。" + +#: lib/perl5/Selima/List/ActLog.pm:207 +msgid "" +"Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的記錄,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/ActLog.pm:211 +msgid "[*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆記錄,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Category.pm:18 +msgid "Add a new category." +msgstr "建新連結分類。" + +#: lib/perl5/Selima/List/Category.pm:24 +msgid "Search for a category:" +msgstr "搜尋分類:" + +#: lib/perl5/Selima/List/Category.pm:41 +msgid "Your query found [*,_1,category,categories]." +msgstr "共 [#,_1] 個相符的分類。" + +#: lib/perl5/Selima/List/Category.pm:44 +msgid "[*,_1,category,categories]." +msgstr "共 [#,_1] 個分類。" + +#: lib/perl5/Selima/List/Category.pm:50 +msgid "Your query found [*,_1,category,categories], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個相符的分類,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: lib/perl5/Selima/List/Category.pm:54 +msgid "[*,_1,category,categories], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個分類,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: lib/perl5/Selima/List/Categorz.pm:18 +msgid "Add a new categorization record." +msgstr "建新分類資料。" + +#: lib/perl5/Selima/List/Categorz.pm:24 +msgid "Search for a categorization record:" +msgstr "搜尋分類資料:" + +#: lib/perl5/Selima/List/Categorz.pm:41 +msgid "Your query found [*,_1,categorization record]." +msgstr "共 [#,_1] 筆相符的分類資料。" + +#: lib/perl5/Selima/List/Categorz.pm:44 +msgid "[*,_1,categorization record]." +msgstr "共 [#,_1] 筆分類資料。" + +#: lib/perl5/Selima/List/Categorz.pm:50 +msgid "" +"Your query found [*,_1,categorization record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的分類資料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Categorz.pm:54 +msgid "[*,_1,categorization record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆分類資料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/GroupMem.pm:24 +msgid "Select a Group Membership Record" +msgstr "選擇群組成員關係" + +#: lib/perl5/Selima/List/GroupMem.pm:25 +msgid "Manage Group Membership" +msgstr "管理群組成員關係" + +#: lib/perl5/Selima/List/GroupMem.pm:30 lib/perl5/Selima/List/UserMem.pm:30 +msgid "Group" +msgstr "群組" + +#: lib/perl5/Selima/List/GroupMem.pm:31 lib/perl5/Selima/List/UserMem.pm:31 +msgid "Member" +msgstr "成員" + +#: lib/perl5/Selima/List/GroupMem.pm:39 lib/perl5/Selima/List/UserMem.pm:39 +msgid "Add a new membership record." +msgstr "建新成員關係。" + +#: lib/perl5/Selima/List/GroupMem.pm:45 lib/perl5/Selima/List/UserMem.pm:45 +msgid "Search for a membership record:" +msgstr "搜尋成員關係:" + +#: lib/perl5/Selima/List/GroupMem.pm:62 lib/perl5/Selima/List/UserMem.pm:62 +msgid "Your query found [*,_1,membership record]." +msgstr "共 [#,_1] 筆相符的成員關係。" + +#: lib/perl5/Selima/List/GroupMem.pm:65 lib/perl5/Selima/List/UserMem.pm:65 +msgid "[*,_1,membership record]." +msgstr "共 [#,_1] 筆成員關係。" + +#: lib/perl5/Selima/List/GroupMem.pm:71 lib/perl5/Selima/List/UserMem.pm:71 +msgid "Your query found [*,_1,membership record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的成員關係,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/GroupMem.pm:75 lib/perl5/Selima/List/UserMem.pm:75 +msgid "[*,_1,membership record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆成員關係,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Groups.pm:23 +msgid "Select a Group" +msgstr "選擇群組" + +#: lib/perl5/Selima/List/Groups.pm:24 +msgid "Manage Groups" +msgstr "管理群組" + +#: lib/perl5/Selima/List/Groups.pm:29 +msgid "Group ID." +msgstr "群組代號" + +#: lib/perl5/Selima/List/Groups.pm:38 +msgid "Add a new group." +msgstr "建新群組。" + +#: lib/perl5/Selima/List/Groups.pm:44 +msgid "Search for a group:" +msgstr "搜尋群組:" + +#: lib/perl5/Selima/List/Groups.pm:61 +msgid "Your query found [*,_1,group]." +msgstr "共 [#,_1] 個相符的群組。" + +#: lib/perl5/Selima/List/Groups.pm:64 +msgid "[*,_1,group]." +msgstr "共 [#,_1] 個群組。" + +#: lib/perl5/Selima/List/Groups.pm:70 +msgid "Your query found [*,_1,group], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個相符的群組,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: lib/perl5/Selima/List/Groups.pm:74 +msgid "[*,_1,group], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個群組,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: lib/perl5/Selima/List/Guestbook.pm:26 +msgid "Select a Message" +msgstr "選擇留言" + +#: lib/perl5/Selima/List/Guestbook.pm:27 +msgid "Manage Guestbook" +msgstr "管理留言簿" + +#: lib/perl5/Selima/List/Guestbook.pm:38 +msgid "Signature" +msgstr "簽名" + +#: lib/perl5/Selima/List/Guestbook.pm:39 +msgid "Identity" +msgstr "身份" + +#: lib/perl5/Selima/List/Guestbook.pm:40 +msgid "Location" +msgstr "所在地" + +#: lib/perl5/Selima/List/Guestbook.pm:41 +msgid "Message" +msgstr "留言" + +#: lib/perl5/Selima/List/Guestbook.pm:42 lib/perl5/Selima/List/Users.pm:35 +msgid "IP" +msgstr "IP" + +#: lib/perl5/Selima/List/Guestbook.pm:43 lib/perl5/Selima/List/Users.pm:36 +msgid "Host" +msgstr "主機" + +#: lib/perl5/Selima/List/Guestbook.pm:44 lib/perl5/Selima/List/Users.pm:37 +msgid "Country" +msgstr "國家" + +#: lib/perl5/Selima/List/Guestbook.pm:45 +msgid "Page No." +msgstr "頁數" + +#: lib/perl5/Selima/List/Guestbook.pm:46 +msgid "Old page No." +msgstr "舊頁數" + +#: lib/perl5/Selima/List/Guestbook.pm:54 +msgid "Write a new message." +msgstr "寫新留言。" + +#: lib/perl5/Selima/List/Guestbook.pm:60 +msgid "Search for a message:" +msgstr "搜尋留言:" + +#: lib/perl5/Selima/List/Guestbook.pm:77 +msgid "Your query found [*,_1,message]." +msgstr "共 [#,_1] 則相符的留言。" + +#: lib/perl5/Selima/List/Guestbook.pm:80 +msgid "[*,_1,message]." +msgstr "共 [#,_1] 則留言。" + +#: lib/perl5/Selima/List/Guestbook.pm:86 +msgid "Your query found [*,_1,message], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則相符的留言,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: lib/perl5/Selima/List/Guestbook.pm:90 +msgid "[*,_1,message], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則留言,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: lib/perl5/Selima/List/LinkCat.pm:24 +msgid "Select a Link Category" +msgstr "選擇連結分類" + +#: lib/perl5/Selima/List/LinkCat.pm:25 +msgid "Manage Link Categories" +msgstr "管理連結分類" + +#: lib/perl5/Selima/List/LinkCatz.pm:24 +msgid "Select a Link Categorization Record" +msgstr "選擇連結分類資料" + +#: lib/perl5/Selima/List/LinkCatz.pm:25 +msgid "Manage Link Categorization" +msgstr "管理連結分類表" + +#: lib/perl5/Selima/List/LinkCatz.pm:30 +msgid "Link" +msgstr "連結" + +#: lib/perl5/Selima/List/Links.pm:24 +msgid "Select a Related Link" +msgstr "選擇相關連結" + +#: lib/perl5/Selima/List/Links.pm:25 +msgid "Manage Related Links" +msgstr "管理相關連結" + +#: lib/perl5/Selima/List/Links.pm:32 +msgid "2nd language title" +msgstr "第二語言標題" + +#: lib/perl5/Selima/List/Links.pm:33 +msgid "Link icon" +msgstr "連結小圖" + +#: lib/perl5/Selima/List/Links.pm:34 +msgid "Address" +msgstr "地址" + +#: lib/perl5/Selima/List/Links.pm:35 +msgid "Tel." +msgstr "電話" + +#: lib/perl5/Selima/List/Links.pm:36 +msgid "Fax." +msgstr "傳真" + +#: lib/perl5/Selima/List/Links.pm:44 +msgid "Add a new related link." +msgstr "建新相關連結。" + +#: lib/perl5/Selima/List/Links.pm:50 +msgid "Search for a related link:" +msgstr "搜尋相關連結:" + +#: lib/perl5/Selima/List/Links.pm:67 +msgid "Your query found [*,_1,related link]." +msgstr "共 [#,_1] 筆相符的相關連結。" + +#: lib/perl5/Selima/List/Links.pm:70 +msgid "[*,_1,related link]." +msgstr "共 [#,_1] 筆相關連結。" + +#: lib/perl5/Selima/List/Links.pm:76 +msgid "Your query found [*,_1,related link], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的相關連結,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Links.pm:80 +msgid "[*,_1,related link], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相關連結,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Pages.pm:24 +msgid "Select a Page" +msgstr "選擇網頁" + +#: lib/perl5/Selima/List/Pages.pm:25 +msgid "Manage Pages" +msgstr "管理網頁" + +#: lib/perl5/Selima/List/Pages.pm:40 +msgid "Write a new page." +msgstr "寫新網頁。" + +#: lib/perl5/Selima/List/Pages.pm:46 +msgid "Search for a page:" +msgstr "搜尋網頁:" + +#: lib/perl5/Selima/List/Pages.pm:63 +msgid "Your query found [*,_1,page]." +msgstr "共 [#,_1] 頁相符的網頁。" + +#: lib/perl5/Selima/List/Pages.pm:66 +msgid "[*,_1,page]." +msgstr "共 [#,_1] 頁網頁。" + +#: lib/perl5/Selima/List/Pages.pm:72 +msgid "Your query found [*,_1,page], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 頁相符的網頁,列出第 [#,_2] 頁到第 [#,_3] 頁。" + +#: lib/perl5/Selima/List/Pages.pm:76 +msgid "[*,_1,page], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 頁網頁,列出第 [#,_2] 頁到第 [#,_3] 頁。" + +#: lib/perl5/Selima/List/ScptPriv.pm:24 +msgid "Select a Script Privilege Record" +msgstr "選擇程式權限資料" + +#: lib/perl5/Selima/List/ScptPriv.pm:25 +msgid "Manage Script Privileges" +msgstr "管理程式權限表" + +#: lib/perl5/Selima/List/ScptPriv.pm:30 +msgid "Script" +msgstr "程式" + +#: lib/perl5/Selima/List/ScptPriv.pm:31 +msgid "Privilege" +msgstr "權限說明" + +#: lib/perl5/Selima/List/ScptPriv.pm:39 +msgid "Add a new script privilege record." +msgstr "建新程式權限資料。" + +#: lib/perl5/Selima/List/ScptPriv.pm:45 +msgid "Search for a script privilege record:" +msgstr "搜尋程式權限資料:" + +#: lib/perl5/Selima/List/ScptPriv.pm:62 +msgid "Your query found [*,_1,script privilege record]." +msgstr "共 [#,_1] 筆相符的程式權限資料。" + +#: lib/perl5/Selima/List/ScptPriv.pm:65 +msgid "[*,_1,script privilege record]." +msgstr "共 [#,_1] 筆程式權限資料。" + +#: lib/perl5/Selima/List/ScptPriv.pm:71 +msgid "" +"Your query found [*,_1,script privilege record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的程式權限資料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/ScptPriv.pm:75 +msgid "[*,_1,script privilege record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆程式權限資料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/UserMem.pm:24 +msgid "Select a User Membership Record" +msgstr "選擇使用者成員關係" + +#: lib/perl5/Selima/List/UserMem.pm:25 +msgid "Manage User Membership" +msgstr "管理使用者成員關係" + +#: lib/perl5/Selima/List/UserPref.pm:24 +msgid "Select a User Preference" +msgstr "選擇使用者偏好" + +#: lib/perl5/Selima/List/UserPref.pm:25 +msgid "Manage User Preferences" +msgstr "管理使用者偏好" + +#: lib/perl5/Selima/List/UserPref.pm:30 +msgid "User" +msgstr "使用者" + +#: lib/perl5/Selima/List/UserPref.pm:31 +msgid "Domain" +msgstr "適用範圍" + +#: lib/perl5/Selima/List/UserPref.pm:32 +msgid "Value" +msgstr "值" + +#: lib/perl5/Selima/List/UserPref.pm:40 +msgid "Add a new user preference." +msgstr "建新使用者偏好。" + +#: lib/perl5/Selima/List/UserPref.pm:46 +msgid "Search for a user preference:" +msgstr "搜尋使用者偏好:" + +#: lib/perl5/Selima/List/UserPref.pm:63 +msgid "Your query found [*,_1,user preference]." +msgstr "共 [#,_1] 筆相符的使用者偏好。" + +#: lib/perl5/Selima/List/UserPref.pm:66 +msgid "[*,_1,user preference]." +msgstr "共 [#,_1] 筆使用者偏好。" + +#: lib/perl5/Selima/List/UserPref.pm:72 +msgid "Your query found [*,_1,user preference], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的使用者偏好,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/UserPref.pm:76 +msgid "[*,_1,user preference], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆使用者偏好,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Users.pm:23 +msgid "Select a User" +msgstr "選擇使用者" + +#: lib/perl5/Selima/List/Users.pm:24 +msgid "Manage Users" +msgstr "管理帳號" + +#: lib/perl5/Selima/List/Users.pm:29 +msgid "User ID." +msgstr "使用者代號" + +#: lib/perl5/Selima/List/Users.pm:30 +msgid "Full name" +msgstr "姓名" + +#: lib/perl5/Selima/List/Users.pm:31 +msgid "Deleted?" +msgstr "已刪?" + +#: lib/perl5/Selima/List/Users.pm:32 +msgid "Pref. language" +msgstr "語言偏好" + +#: lib/perl5/Selima/List/Users.pm:33 +msgid "Visits" +msgstr "上站次數" + +#: lib/perl5/Selima/List/Users.pm:34 +msgid "Visited" +msgstr "上站日期" + +#: lib/perl5/Selima/List/Users.pm:45 +msgid "Add a new user account." +msgstr "建新帳號。" + +#: lib/perl5/Selima/List/Users.pm:51 +msgid "Search for a user:" +msgstr "搜尋使用者:" + +#: lib/perl5/Selima/List/Users.pm:68 +msgid "Your query found [*,_1,user]." +msgstr "共 [#,_1] 位相符的使用者。" + +#: lib/perl5/Selima/List/Users.pm:71 +msgid "[*,_1,user]." +msgstr "共 [#,_1] 位使用者。" + +#: lib/perl5/Selima/List/Users.pm:77 +msgid "Your query found [*,_1,user], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位相符的使用者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: lib/perl5/Selima/List/Users.pm:81 +msgid "[*,_1,user], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位使用者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:103 +msgid "This accounting record was not modified." +msgstr "會計分錄未異動。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:107 +msgid "This accounting record has been successfully added." +msgstr "會計分錄建好了。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:111 +msgid "This accounting record has been successfully updated." +msgstr "會計分錄存好了。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:115 +msgid "This accounting record has been successfully deleted." +msgstr "會計分錄刪掉了。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:86 +msgid "This accounting subject was not modified." +msgstr "會計科目未異動。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:90 +msgid "This accounting subject has been successfully added." +msgstr "會計科目建好了。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:94 +msgid "This accounting subject has been successfully updated." +msgstr "會計科目存好了。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:98 +msgid "This accounting subject has been successfully deleted." +msgstr "會計科目刪掉了。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:418 +msgid "This accounting transaction was not modified." +msgstr "會計傳票未異動。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:422 +msgid "This accounting transaction has been successfully added." +msgstr "會計傳票建好了。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:426 +msgid "This accounting transaction has been successfully updated." +msgstr "會計傳票存好了。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:430 +msgid "This accounting transaction has been successfully deleted." +msgstr "會計傳票刪掉了。" + +#: lib/perl5/Selima/Processor/Category.pm:20 +msgid "This category was not modified." +msgstr "分類未異動。" + +#: lib/perl5/Selima/Processor/Category.pm:24 +msgid "This category has been successfully added." +msgstr "分類建好了。" + +#: lib/perl5/Selima/Processor/Category.pm:28 +msgid "This category has been successfully updated." +msgstr "分類存好了。" + +#: lib/perl5/Selima/Processor/Category.pm:32 +msgid "This category has been successfully deleted." +msgstr "分類刪掉了。" + +#: lib/perl5/Selima/Processor/Categorz.pm:20 +msgid "This categorization record was not modified." +msgstr "分類資料未異動。" + +#: lib/perl5/Selima/Processor/Categorz.pm:24 +msgid "This categorization record has been successfully added." +msgstr "分類資料建好了。" + +#: lib/perl5/Selima/Processor/Categorz.pm:28 +msgid "This categorization record has been successfully updated." +msgstr "分類資料存好了。" + +#: lib/perl5/Selima/Processor/Categorz.pm:32 +msgid "This categorization record has been successfully deleted." +msgstr "分類資料刪掉了。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:79 +msgid "This group membership record was not modified." +msgstr "群組成員關係未異動。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:83 +msgid "This group membership record has been successfully added." +msgstr "群組成員關係建好了。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:87 +msgid "This group membership record has been successfully updated." +msgstr "群組成員關係存好了。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:91 +msgid "This group membership record has been successfully deleted." +msgstr "群組成員關係刪掉了。" + +#: lib/perl5/Selima/Processor/Group.pm:253 +msgid "This group was not modified." +msgstr "群組未異動。" + +#: lib/perl5/Selima/Processor/Group.pm:257 +msgid "This group has been successfully added." +msgstr "群組建好了。" + +#: lib/perl5/Selima/Processor/Group.pm:261 +msgid "This group has been successfully updated." +msgstr "群組存好了。" + +#: lib/perl5/Selima/Processor/Group.pm:265 +msgid "This group has been successfully deleted." +msgstr "群組刪掉了。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:117 +msgid "This message was not modified." +msgstr "留言未異動。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:121 +msgid "This message has been successfully added." +msgstr "留言寫好了。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:125 +msgid "This message has been successfully updated." +msgstr "留言存好了。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:129 +msgid "This message has been successfully deleted." +msgstr "留言刪掉了。" + +#: lib/perl5/Selima/Processor/Link.pm:168 +msgid "This related link was not modified." +msgstr "相關連結未異動。" + +#: lib/perl5/Selima/Processor/Link.pm:172 +msgid "This related link has been successfully added." +msgstr "相關連結建好了。" + +#: lib/perl5/Selima/Processor/Link.pm:176 +msgid "This related link has been successfully updated." +msgstr "相關連結存好了。" + +#: lib/perl5/Selima/Processor/Link.pm:180 +msgid "This related link has been successfully deleted." +msgstr "相關連結刪掉了。" + +#: lib/perl5/Selima/Processor/LogOut.pm:52 +msgid "You have successfully logged out." +msgstr "登出了。" + +#: lib/perl5/Selima/Processor/Page.pm:89 +msgid "This page was not modified." +msgstr "網頁未異動。" + +#: lib/perl5/Selima/Processor/Page.pm:93 +msgid "This page has been successfully added." +msgstr "網頁寫好了。" + +#: lib/perl5/Selima/Processor/Page.pm:97 +msgid "This page has been successfully updated." +msgstr "網頁存好了。" + +#: lib/perl5/Selima/Processor/Page.pm:101 +msgid "This page has been successfully deleted." +msgstr "網頁刪掉了。" + +#: lib/perl5/Selima/Processor/Rebuild.pm:48 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. ([sprintf,%0.3f,_1] " +"seconds)" +msgstr "指定的網頁重製好了。( [sprintf,%0.3f,_1] 秒)" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:79 +msgid "This script privilege record was not modified." +msgstr "程式權限未異動。" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:83 +msgid "This script privilege record has been successfully added." +msgstr "程式權限建好了。" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:87 +msgid "This script privilege record has been successfully updated." +msgstr "程式權限存好了。" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:91 +msgid "This script privilege record has been successfully deleted." +msgstr "程式權限刪掉了。" + +#: lib/perl5/Selima/Processor/UserMem.pm:79 +msgid "This user membership record was not modified." +msgstr "使用者成員關係未異動。" + +#: lib/perl5/Selima/Processor/UserMem.pm:83 +msgid "This user membership record has been successfully added." +msgstr "使用者成員關係建好了。" + +#: lib/perl5/Selima/Processor/UserMem.pm:87 +msgid "This user membership record has been successfully updated." +msgstr "使用者成員關係存好了。" + +#: lib/perl5/Selima/Processor/UserMem.pm:91 +msgid "This user membership record has been successfully deleted." +msgstr "使用者成員關係刪掉了。" + +#: lib/perl5/Selima/Processor/User.pm:185 +msgid "This user account was not modified." +msgstr "帳號未異動。" + +#: lib/perl5/Selima/Processor/User.pm:189 +msgid "This user account has been successfully added." +msgstr "帳號建好了。" + +#: lib/perl5/Selima/Processor/User.pm:193 +msgid "This user account has been successfully updated." +msgstr "帳號存好了。" + +#: lib/perl5/Selima/Processor/User.pm:197 +msgid "This user account has been successfully deleted." +msgstr "帳號刪掉了。" + +#: lib/perl5/Selima/Processor/UserPref.pm:128 +msgid "This user preference was not modified." +msgstr "使用者偏好未異動。" + +#: lib/perl5/Selima/Processor/UserPref.pm:132 +msgid "This user preference has been successfully added." +msgstr "使用者偏好建好了。" + +#: lib/perl5/Selima/Processor/UserPref.pm:136 +msgid "This user preference has been successfully updated." +msgstr "使用者偏好存好了。" + +#: lib/perl5/Selima/Processor/UserPref.pm:140 +msgid "This user preference has been successfully deleted." +msgstr "使用者偏好刪掉了。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:37 +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:59 +msgid "Your signature is too long. (Max. length [#,_1])" +msgstr "妳的簽名太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:56 +msgid "Please fill in your signature." +msgstr "請填上妳的簽名。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:80 +msgid "Your identity is too long. (Max. length [#,_1])" +msgstr "妳的身份太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:101 +msgid "Your location is too long. (Max. length [#,_1])" +msgstr "妳的所在地太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:122 +msgid "Your e-mail is too long. (Max. length [#,_1])" +msgstr "妳的 E-mail 信箱太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:143 +msgid "Your website URL is too long. (Max. length [#,_1])" +msgstr "妳的網站網址太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:163 +#: lib/perl5/Selima/Form/Guestbook/Public.pm:60 +msgid "Fill in your message here." +msgstr "請填上妳的留言。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:164 +msgid "Please fill in your message." +msgstr "請填上妳的留言。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:167 +msgid "Your message is too long. (Max. length [#,_1])" +msgstr "妳的留言太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:186 +msgid "You can post at most 5 messages in 1 hour." +msgstr "一小時最多只能留五篇留言。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:204 +msgid "Your message is already posted." +msgstr "留言已經留了。" + +#: lib/perl5/Selima/Form/Guestbook/Public.pm:40 +msgid "Leave a messsage" +msgstr "留言" + +#: lib/perl5/Selima/Form/Guestbook/Public.pm:42 +msgid "This table provides you a form to leave a message." +msgstr "本表提供留言的表單。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:27 +msgid "Select an Accounting Record" +msgstr "選擇會計分錄" + +#: lib/perl5/Selima/List/Accounting/Records.pm:28 +msgid "Manage Accounting Records" +msgstr "管理會計分錄" + +#: lib/perl5/Selima/List/Accounting/Records.pm:33 +msgid "Accounting transaction" +msgstr "會計傳票" + +#: lib/perl5/Selima/List/Accounting/Records.pm:34 +msgid "Debit/credit" +msgstr "借/貸" + +#: lib/perl5/Selima/List/Accounting/Records.pm:46 +msgid "Add a new accounting record." +msgstr "建新會計分錄。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:52 +msgid "Search for an accounting record:" +msgstr "搜尋會計分錄:" + +#: lib/perl5/Selima/List/Accounting/Records.pm:69 +#: lib/perl5/Selima/List/Accounting/Reports.pm:634 +msgid "Your query found [*,_1,accounting record]." +msgstr "共 [#,_1] 筆相符的會計分錄。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:72 +#: lib/perl5/Selima/List/Accounting/Reports.pm:637 +msgid "[*,_1,accounting record]." +msgstr "共 [#,_1] 筆會計分錄。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:78 +#: lib/perl5/Selima/List/Accounting/Reports.pm:643 +msgid "Your query found [*,_1,accounting record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的會計分錄,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:82 +#: lib/perl5/Selima/List/Accounting/Reports.pm:647 +msgid "[*,_1,accounting record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆會計分錄,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:31 +msgid "View the Accounting Reports" +msgstr "瀏覽會計報表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:72 +msgid "Month" +msgstr "月份" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:77 +msgid "Income" +msgstr "收入" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:78 +msgid "Expense" +msgstr "支出" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:79 +msgid "Balance" +msgstr "餘額" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:137 +msgid "Please specify a month." +msgstr "請設定月份。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:141 +msgid "Please specify a valid month in YYYY-MM format." +msgstr "月份請以 YYYY-MM 格式正確設定。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:176 +msgid "Please specify a year." +msgstr "請設定年份。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:180 +msgid "Please specify a valid year in YYYY format." +msgstr "年份請以 YYYY 格式正確設定。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:211 +msgid "Please specify the start date." +msgstr "請設定啟始日期。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:215 +msgid "Please specify a valid start date in YYYY-MM-DD format." +msgstr "啟始日期請以 YYYY-MM-DD 格式正確填寫。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:226 +msgid "Please specify the end date." +msgstr "請設定結束日期。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:229 +msgid "Please specify a valid end date in YYYY-MM-DD format." +msgstr "結束日期請以 YYYY-MM-DD 格式正確填寫。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:250 +msgid "This option is invalid. Please select a proper date range." +msgstr "日期範圍選項無效,請由表上選擇適當的日期範圍。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:319 +#: lib/perl5/Selima/List/Accounting/Transacts.pm:53 +msgid "" +"Add a new cash expense transaction, add a new cash income transaction or add a new " +"transfer transaction." +msgstr "" +"建新現金支出傳票建新現金收入傳票" +"或建新轉帳傳票。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:339 +msgid "Report type:" +msgstr "報表類型:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:343 +msgid "Cash book" +msgstr "現金帳" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:347 +msgid "Cash book summary" +msgstr "現金帳摘要" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:351 +msgid "Ledger" +msgstr "分類帳" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:355 +msgid "Ledger summary" +msgstr "分類帳摘要" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:359 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:31 +msgid "Journal" +msgstr "日記簿" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:363 +msgid "Trial balance" +msgstr "試算表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:367 +msgid "Income statement" +msgstr "損益表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:371 +msgid "Balance sheet" +msgstr "資產負債表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:408 +msgid "Search the accounting records:" +msgstr "帳目檢索:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:442 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:297 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:253 +msgid "Query" +msgstr "查詢" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:443 +msgid "Date range:" +msgstr "日期範圍:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:444 +msgid "By month:" +msgstr "依月份:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:445 +msgid "By year:" +msgstr "依年度:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:446 +msgid "Specified date range:" +msgstr "特定期間:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:447 +msgid "All" +msgstr "全部" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:448 +msgid "From" +msgstr "自" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:449 +msgid "to" +msgstr "至" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:563 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:332 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:326 +msgid "From [_1] to [_2]." +msgstr "自 [_1] 至 [_2] 。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:24 +msgid "Select an Accounting Subject" +msgstr "選擇會計科目" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:25 +msgid "Manage Accounting Subjects" +msgstr "管理會計科目" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:30 +msgid "Parent subject" +msgstr "大科目" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:31 +msgid "Code" +msgstr "代碼" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:39 +msgid "Add a new accounting subject." +msgstr "建新會計科目。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:45 +msgid "Search for an accounting subject:" +msgstr "搜尋會計科目:" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:62 +msgid "Your query found [*,_1,accounting subject]." +msgstr "共 [#,_1] 個相符的會計科目。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:65 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:355 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:349 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:251 +msgid "[*,_1,accounting subject]." +msgstr "[#,_1] 個會計科目。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:71 +msgid "Your query found [*,_1,accounting subject], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個相符的會計科目,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:75 +msgid "[*,_1,accounting subject], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個會計科目,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:26 +msgid "Select an Accounting Transaction" +msgstr "選擇會計傳票" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:27 +msgid "Manage Accounting Transactions" +msgstr "管理會計傳票" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:32 +msgid "Number" +msgstr "編號" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:33 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:42 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:40 +msgid "Note" +msgstr "註記" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:66 +msgid "Search for an accounting transaction:" +msgstr "搜尋會計傳票:" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:83 +msgid "Your query found [*,_1,accounting transaction]." +msgstr "共 [#,_1] 筆相符的會計傳票。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:86 +msgid "[*,_1,accounting transaction]." +msgstr "[#,_1] 筆會計傳票。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:92 +msgid "" +"Your query found [*,_1,accounting transaction], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的會計傳票,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:96 +msgid "[*,_1,accounting transaction], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆會計傳票,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Guestbook/Public.pm:196 +msgid "~[Edit~]" +msgstr "~[編輯~]" + +#: lib/perl5/Selima/List/Guestbook/Public.pm:205 +msgid "The message entry seperator" +msgstr "留言分隔線" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:29 +msgid "Balance Sheet" +msgstr "資產負債表" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:40 +msgid "Assets accounting subject" +msgstr "資產會計科目" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:41 +msgid "Assets amount" +msgstr "資產金額" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:42 +msgid "Liabilities accounting subject" +msgstr "負債會計科目" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:43 +msgid "Liabilities amount" +msgstr "負債金額" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:289 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:379 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:283 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:273 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:351 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:204 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:421 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:366 +msgid "Download the data as a CSV file." +msgstr "下載 CSV 格式資料檔。" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:45 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:150 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:339 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:40 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:383 +msgid "current assets and liabilities" +msgstr "流動資產與負債" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:48 +msgid "Cash book - [_1]" +msgstr "現金帳 - [_1]" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:29 +msgid "Income Statement" +msgstr "損益表" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:187 +msgid "Gross income" +msgstr "營業毛利" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:189 +msgid "Operating income" +msgstr "營業淨利" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:191 +msgid "Before tax income" +msgstr "稅前淨利" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:193 +msgid "After tax income" +msgstr "稅後淨利" + +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:41 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:39 +msgid "Transaction Number" +msgstr "傳票編號" + +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:127 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:138 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:151 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:162 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:126 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:140 +msgid "Brought forward" +msgstr "上期結轉" + +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:46 +msgid "Ledger - [_1]" +msgstr "分類帳 - [_1]" + +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:26 +msgid "Search the Accounting Records" +msgstr "帳目檢索" + +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:28 +msgid "Search Result" +msgstr "檢索結果" + +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:28 +msgid "Trial Balance" +msgstr "試算表" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:43 +msgid "Cash Book Summary - [_1]" +msgstr "現金帳摘要 - [_1]" + +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:41 +msgid "Ledger Summary - [_1]" +msgstr "分類帳摘要 - [_1]" diff --git a/po/selima/zh_TW.pox b/po/selima/zh_TW.pox new file mode 100644 index 0000000..767dc92 --- /dev/null +++ b/po/selima/zh_TW.pox @@ -0,0 +1,3376 @@ +# Traditional Chinese PO file for the Selima common subroutines. +# Copyright (C) 2003-2018 imacat +# This file is distributed under the same license as the selima package. +# imacat , 2003-2018. +# +msgid "" +msgstr "" +"Project-Id-Version: selima 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-02-17 11:07+0800\n" +"PO-Revision-Date: 2018-11-02 01:03+0800\n" +"Last-Translator: imacat \n" +"Language-Team: Traditional Chinese \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: lib/perl5/Selima/Checker.pm:130 +msgid "Please select a user." +msgstr "請選擇使用者。" + +#: lib/perl5/Selima/Checker.pm:133 +msgid "This user does not exist anymore. Please select another one." +msgstr "查無此人,請重新選擇。" + +#: lib/perl5/Selima/Checker.pm:151 +msgid "Please select a group." +msgstr "請選擇群組。" + +#: lib/perl5/Selima/Checker.pm:154 +msgid "This group does not exist anymore. Please select another one." +msgstr "查無此群組,請重新選擇。" + +#: lib/perl5/Selima/Checker.pm:172 +msgid "Please fill in the script." +msgstr "請填上程式檔名。" + +#: lib/perl5/Selima/Checker.pm:175 +msgid "This script is too long. (Max. length [#,_1])" +msgstr "程式檔名太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:179 +msgid "This script is not a valid script. Please specify another one." +msgstr "查無此程式,請重新設定執行的程式。" + +#: lib/perl5/Selima/Checker.pm:197 +msgid "Please fill in the author." +msgstr "請填上作者。" + +#: lib/perl5/Selima/Checker.pm:200 +msgid "This author is too long. (Max. length [#,_1])" +msgstr "作者太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:220 lib/perl5/Selima/Form.pm:1700 +msgid "Fill in the content here." +msgstr "請填上內文。" + +#: lib/perl5/Selima/Checker.pm:221 +msgid "Please fill in the content." +msgstr "請填上內文。" + +#: lib/perl5/Selima/Checker.pm:224 +msgid "This content is too long. (Max. length [#,_1])" +msgstr "內文太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:243 +msgid "Please fill in a date." +msgstr "請填上日期。" + +#: lib/perl5/Selima/Checker.pm:246 lib/perl5/Selima/Checker.pm:249 +#: lib/perl5/Selima/Checker.pm:251 +msgid "Please fill in a valid date in YYYY-MM-DD format." +msgstr "日期請以 YYYY-MM-DD 格式正確填寫。" + +#: lib/perl5/Selima/Checker.pm:270 lib/perl5/Selima/Form.pm:1756 +msgid "Fill in the description here." +msgstr "請填上說明。" + +#: lib/perl5/Selima/Checker.pm:271 +msgid "Please fill in the description." +msgstr "請填上說明。" + +#: lib/perl5/Selima/Checker.pm:274 +msgid "This description is too long. (Max. length [#,_1])" +msgstr "說明太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:293 +msgid "Please fill in the ID." +msgstr "請填上代號。" + +#: lib/perl5/Selima/Checker.pm:296 +msgid "This ID. is too long. (Max. length [#,_1])" +msgstr "代號太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:299 +msgid "This ID. is too short. (Max. length [#,_1])" +msgstr "代號太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:303 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"ID." +msgstr "代號限用小寫英文字母、數字和底線。" + +#: lib/perl5/Selima/Checker.pm:321 +msgid "Please fill in the keywords." +msgstr "請填上關鍵字。" + +#: lib/perl5/Selima/Checker.pm:324 +msgid "This keyword list is too long. (Max. length [#,_1])" +msgstr "關鍵字太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:344 lib/perl5/Selima/Form.pm:1830 +msgid "Fill in the message here." +msgstr "請填上留言。" + +#: lib/perl5/Selima/Checker.pm:345 +msgid "Please fill in the message." +msgstr "請填上留言。" + +#: lib/perl5/Selima/Checker.pm:348 +msgid "This message is too long. (Max. length [#,_1])" +msgstr "留言太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:367 +msgid "Please fill in the order." +msgstr "請填上先後次序。" + +#: lib/perl5/Selima/Checker.pm:370 +msgid "This order is too long. (Max. length [#,_1])" +msgstr "次序太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:374 +msgid "Please fill in a positive integer order." +msgstr "次序請填正整數。" + +#: lib/perl5/Selima/Checker.pm:400 +msgid "Please fill in the page path." +msgstr "請填上網頁路徑。" + +#: lib/perl5/Selima/Checker.pm:403 +msgid "This page path is too long. (Max. length [#,_1])" +msgstr "網頁路徑太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:414 +msgid "This page already exists. You cannot create a duplicated one." +msgstr "已有同一網頁,請勿重複建檔。" + +#: lib/perl5/Selima/Checker.pm:417 +msgid "Please fill in an absolute page path." +msgstr "網頁路徑請填上絕對路徑。" + +#: lib/perl5/Selima/Checker.pm:420 +msgid "Please fill in a valid page path." +msgstr "網頁路徑請填上正確路徑。" + +#: lib/perl5/Selima/Checker.pm:423 +msgid "You cannot overwrite the cover home page." +msgstr "不可以程式設定首頁。" + +#: lib/perl5/Selima/Checker.pm:426 +msgid "You can only fill in an HTML page path (*.html)." +msgstr "網頁路徑限填 HTML 位址( *.html )。" + +#: lib/perl5/Selima/Checker.pm:454 +msgid "This picture does not exist anymore. Please upload another one." +msgstr "查無此圖,請重新上傳圖檔。" + +#: lib/perl5/Selima/Checker.pm:458 +msgid "" +"This picture is too large. Please upload another one. (Max. length [#,_1])" +msgstr "圖檔太大,請重新上傳圖檔(最大 [#,_1] )。" + +#: lib/perl5/Selima/Checker.pm:482 +msgid "Please fill in the picture caption." +msgstr "請填上圖片標題。" + +#: lib/perl5/Selima/Checker.pm:485 +msgid "This picture caption is too long. (Max. length [#,_1])" +msgstr "圖片標題太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:509 +msgid "" +"This picture position is invalid. Please choose a proper picture position." +msgstr "圖片位置無效。請由表上選擇適當的圖片位置。" + +#: lib/perl5/Selima/Checker.pm:527 +msgid "Please fill in the title." +msgstr "請填上標題。" + +#: lib/perl5/Selima/Checker.pm:530 +msgid "This title is too long. (Max. length [#,_1])" +msgstr "標題太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:549 +msgid "Please fill in the English title." +msgstr "請填上英文標題。" + +#: lib/perl5/Selima/Checker.pm:552 +msgid "This English title is too long. (Max. length [#,_1])" +msgstr "英文標題太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker.pm:699 lib/perl5/Selima/Preview.pm:38 +msgid "The following field was not received: \"[_1]\"." +msgstr "程式沒有收到下列欄位:「 [_1] 」" + +#: lib/perl5/Selima/ChkWrite.pm:35 +msgid "[_1]: It is not a file." +msgstr "[_1]: 這不是檔案。" + +#: lib/perl5/Selima/ChkWrite.pm:39 +msgid "[_1]: You have no permission to overwrite this file." +msgstr "[_1]: 存檔的權限不足,無法存檔。" + +#: lib/perl5/Selima/ChkWrite.pm:50 +msgid "[_1]: You cannot create anything under the root directory." +msgstr "[_1]: 不可在根目錄下建檔。" + +#: lib/perl5/Selima/ChkWrite.pm:54 +msgid "" +"[_1]: One of the parents of this file ([_2]) is not a directory. You cannot " +"create any new file inside." +msgstr "[_1]: 路徑中間有一部份( [_2] )不是目錄,無法往下建檔。" + +#: lib/perl5/Selima/ChkWrite.pm:58 +msgid "[_1]: You have no permission to create any file under [_2]." +msgstr "[_1]: 權限不足,無法在 [_2] 建檔。" + +#: lib/perl5/Selima/CommText.pm:24 +msgid "(not set)" +msgstr "(未設定)" + +#: lib/perl5/Selima/CommText.pm:25 +msgid "(none)" +msgstr "(無)" + +#: lib/perl5/Selima/CommText.pm:26 +msgid "(N/A)" +msgstr "(不可考)" + +#: lib/perl5/Selima/Format.pm:48 +msgid "[#,_1] bytes" +msgstr "[#,_1] 位元組" + +#: lib/perl5/Selima/Form.pm:116 +msgid "Delete it." +msgstr "刪掉" + +#: lib/perl5/Selima/Form.pm:119 +msgid "*" +msgstr "" + +#: lib/perl5/Selima/Form.pm:140 +msgid "This table provides you a form to add a new data record." +msgstr "本表提供建新資料的表單。" + +#: lib/perl5/Selima/Form.pm:143 +msgid "This table provides you a form to update a current data record." +msgstr "本表提供異動資料的表單。" + +#: lib/perl5/Selima/Form.pm:146 +msgid "This table provides you a form to delete a data record." +msgstr "本表提供刪除資料的表單。" + +#: lib/perl5/Selima/Form.pm:185 +msgid "Add a New Data Record" +msgstr "建新資料" + +#: lib/perl5/Selima/Form.pm:188 +msgid "Update a Current Data Record" +msgstr "異動資料" + +#: lib/perl5/Selima/Form.pm:191 +msgid "Delete a Data Record" +msgstr "刪除資料" + +#: lib/perl5/Selima/Form.pm:212 +msgid "Preview it." +msgstr "預覽。" + +#: lib/perl5/Selima/Form.pm:271 lib/perl5/Selima/Form.pm:284 +msgid "Convert from Simplified Chinese" +msgstr "轉自簡體中文" + +#: lib/perl5/Selima/Form.pm:273 lib/perl5/Selima/Form.pm:286 +msgid "Convert from Traditional Chinese" +msgstr "轉自正體中文" + +#: lib/perl5/Selima/Form.pm:447 lib/perl5/Selima/Form.pm:451 +#: lib/perl5/Selima/Form.pm:559 lib/perl5/Selima/Form.pm:563 +#: lib/perl5/Selima/Form/AcctTrx.pm:89 lib/perl5/Selima/Form/AcctTrx.pm:94 +msgid "Submit" +msgstr "傳送" + +#: lib/perl5/Selima/Form.pm:448 lib/perl5/Selima/Form.pm:452 +#: lib/perl5/Selima/Form.pm:560 lib/perl5/Selima/Form.pm:564 +#: lib/perl5/Selima/Form/AcctTrx.pm:90 lib/perl5/Selima/Form/AcctTrx.pm:95 +msgid "Save" +msgstr "存檔" + +#: lib/perl5/Selima/Form.pm:571 lib/perl5/Selima/Form.pm:1139 +#: lib/perl5/Selima/Form.pm:1229 lib/perl5/Selima/List.pm:1390 +msgid "Delete" +msgstr "刪除" + +#: lib/perl5/Selima/Form.pm:572 lib/perl5/Selima/Form/Rebuild.pm:42 +msgid "Cancel" +msgstr "取消" + +#: lib/perl5/Selima/Form.pm:577 +msgid "" +"Are you sure you want to delete this data? You cannot recover it if you do " +"so." +msgstr "妳真的要刪掉嗎?資料刪掉就救不回來了。" + +#: lib/perl5/Selima/Form.pm:855 lib/perl5/Selima/Form.pm:951 +#: lib/perl5/Selima/Form.pm:1013 lib/perl5/Selima/Form.pm:1097 +#: lib/perl5/Selima/Form.pm:1175 lib/perl5/Selima/Form.pm:1282 +#: lib/perl5/Selima/Form.pm:1362 lib/perl5/Selima/Form.pm:1435 +#: lib/perl5/Selima/Form.pm:1528 lib/perl5/Selima/Form.pm:1620 +#: lib/perl5/Selima/Form.pm:2057 lib/perl5/Selima/Form/AcctRec.pm:122 +#: lib/perl5/Selima/Form/AcctTrx.pm:519 lib/perl5/Selima/Form/Group.pm:165 +#: lib/perl5/Selima/Form/Group.pm:294 lib/perl5/Selima/Form/Group.pm:421 +#: lib/perl5/Selima/Form/Link.pm:138 lib/perl5/Selima/Form/User.pm:291 +msgid "Original:" +msgstr "原:" + +#: lib/perl5/Selima/Form.pm:856 lib/perl5/Selima/Form.pm:952 +#: lib/perl5/Selima/Form.pm:1014 lib/perl5/Selima/Form.pm:1098 +#: lib/perl5/Selima/Form.pm:1176 lib/perl5/Selima/Form.pm:1283 +#: lib/perl5/Selima/Form.pm:1363 lib/perl5/Selima/Form.pm:1436 +#: lib/perl5/Selima/Form.pm:1529 lib/perl5/Selima/Form.pm:1621 +#: lib/perl5/Selima/Form.pm:2058 lib/perl5/Selima/Form/AcctRec.pm:123 +#: lib/perl5/Selima/Form/AcctTrx.pm:520 lib/perl5/Selima/Form/Group.pm:166 +#: lib/perl5/Selima/Form/Group.pm:295 lib/perl5/Selima/Form/Group.pm:422 +#: lib/perl5/Selima/Form/Link.pm:139 lib/perl5/Selima/Form/User.pm:292 +msgid "New:" +msgstr "新:" + +#: lib/perl5/Selima/Form.pm:860 lib/perl5/Selima/Form.pm:1018 +#: lib/perl5/Selima/Form.pm:1625 lib/perl5/Selima/Form.pm:2122 +msgid "Source:" +msgstr "原文:" + +#: lib/perl5/Selima/Form.pm:1138 lib/perl5/Selima/Form.pm:1228 +#: lib/perl5/Selima/Form/AcctRec.pm:100 lib/perl5/Selima/Form/AcctTrx.pm:214 +msgid "Choose" +msgstr "挑選" + +#: lib/perl5/Selima/Form.pm:1689 +msgid "Address:" +msgstr "地址:" + +#: lib/perl5/Selima/Form.pm:1694 +msgid "Author:" +msgstr "作者:" + +#: lib/perl5/Selima/Form.pm:1699 +msgid "Content:" +msgstr "內文:" + +#: lib/perl5/Selima/Form.pm:1713 +msgid "Current Website:" +msgstr "目前網站:" + +#: lib/perl5/Selima/Form.pm:1718 +msgid "Enter your website URL here." +msgstr "請填上妳的網站網址。" + +#: lib/perl5/Selima/Form.pm:1734 +msgid "Created:" +msgstr "建檔日期:" + +#: lib/perl5/Selima/Form.pm:1739 +msgid "Created by:" +msgstr "建檔者:" + +#: lib/perl5/Selima/Form.pm:1744 lib/perl5/Selima/List.pm:167 +#: lib/perl5/Selima/Form/User.pm:160 lib/perl5/Selima/Form/User.pm:163 +msgid "Disabled?" +msgstr "停用?" + +#: lib/perl5/Selima/Form.pm:1745 lib/perl5/Selima/Form/User.pm:161 +#: lib/perl5/Selima/Form/User.pm:164 +msgid "Disabled" +msgstr "停用" + +#: lib/perl5/Selima/Form.pm:1745 lib/perl5/Selima/Form/User.pm:161 +#: lib/perl5/Selima/Form/User.pm:164 +msgid "Enabled" +msgstr "未停用" + +#: lib/perl5/Selima/Form.pm:1745 +msgid "Disable it." +msgstr "停用。" + +#: lib/perl5/Selima/Form.pm:1750 +msgid "Date:" +msgstr "日期:" + +#: lib/perl5/Selima/Form.pm:1755 lib/perl5/Selima/Form/Group.pm:97 +msgid "Description:" +msgstr "說明:" + +#: lib/perl5/Selima/Form.pm:1761 +msgid "E-mail:" +msgstr "E-mail :" + +#: lib/perl5/Selima/Form.pm:1766 +msgid "Fax.:" +msgstr "傳真:" + +#: lib/perl5/Selima/Form.pm:1771 +msgid "Group:" +msgstr "群組:" + +#: lib/perl5/Selima/Form.pm:1776 lib/perl5/Selima/Form/Guestbook.pm:82 +#: lib/perl5/Selima/Form/LinkCat.pm:88 lib/perl5/Selima/Form/Link.pm:87 +#: lib/perl5/Selima/Form/Page.pm:81 +msgid "Hide?" +msgstr "隱藏?" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Hide it" +msgstr "隱藏起來" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Show it" +msgstr "秀出來" + +#: lib/perl5/Selima/Form.pm:1777 +msgid "Hide it currently." +msgstr "暫勿秀出。" + +#: lib/perl5/Selima/Form.pm:1782 lib/perl5/Selima/List.pm:171 +msgid "HTML?" +msgstr "HTML ?" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "HTML" +msgstr "HTML" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "Plain text" +msgstr "純文字" + +#: lib/perl5/Selima/Form.pm:1783 +msgid "The submitted content is HTML." +msgstr "以上內文為 HTML 格式。" + +#: lib/perl5/Selima/Form.pm:1788 +msgid "Host:" +msgstr "主機:" + +#: lib/perl5/Selima/Form.pm:1793 lib/perl5/Selima/Form/LinkCat.pm:95 +msgid "ID.:" +msgstr "代號:" + +#: lib/perl5/Selima/Form.pm:1798 +msgid "Identity:" +msgstr "身份:" + +#: lib/perl5/Selima/Form.pm:1803 +msgid "Introduction:" +msgstr "簡介:" + +#: lib/perl5/Selima/Form.pm:1804 +msgid "Fill in the introduction here." +msgstr "請填上簡介。" + +#: lib/perl5/Selima/Form.pm:1809 +msgid "IP:" +msgstr "IP :" + +#: lib/perl5/Selima/Form.pm:1814 +msgid "Keywords:" +msgstr "關鍵字:" + +#: lib/perl5/Selima/Form.pm:1819 +msgid "Language:" +msgstr "語言:" + +#: lib/perl5/Selima/Form.pm:1824 +msgid "Location:" +msgstr "所在地:" + +#: lib/perl5/Selima/Form.pm:1829 +msgid "Message:" +msgstr "留言:" + +#: lib/perl5/Selima/Form.pm:1835 +msgid "Name:" +msgstr "名字:" + +#: lib/perl5/Selima/Form.pm:1847 lib/perl5/Selima/Form/AcctTrx.pm:319 +msgid "Order:" +msgstr "次序:" + +#: lib/perl5/Selima/Form.pm:1853 +msgid "Parent category:" +msgstr "大類:" + +#: lib/perl5/Selima/Form.pm:1854 lib/perl5/Selima/Form/AcctSubj.pm:94 +msgid "At the very top" +msgstr "最上層" + +#: lib/perl5/Selima/Form.pm:1866 lib/perl5/Selima/Form/User.pm:201 +msgid "Password:" +msgstr "密碼:" + +#: lib/perl5/Selima/Form.pm:1867 +msgid "Confirm password:" +msgstr "確認密碼:" + +#: lib/perl5/Selima/Form.pm:1978 +msgid "Page path:" +msgstr "網頁路徑:" + +#: lib/perl5/Selima/Form.pm:1992 +msgid "Picture:" +msgstr "圖片:" + +#: lib/perl5/Selima/Form.pm:1993 +msgid "Pic. caption:" +msgstr "圖片標題:" + +#: lib/perl5/Selima/Form.pm:1994 +msgid "Pic. position:" +msgstr "圖片位置:" + +#: lib/perl5/Selima/Form.pm:1997 +msgid "Set the picture" +msgstr "設定圖片" + +#: lib/perl5/Selima/Form.pm:1998 +msgid "Delete this picture" +msgstr "刪掉圖片" + +#: lib/perl5/Selima/Form.pm:2003 lib/perl5/Selima/Form.pm:2178 +msgid "Picture preview" +msgstr "圖片預覽" + +#: lib/perl5/Selima/Form.pm:2059 +msgid "Original picture preview" +msgstr "原圖片預覽" + +#: lib/perl5/Selima/Form.pm:2060 +msgid "New picture preview" +msgstr "新圖片預覽" + +#: lib/perl5/Selima/Form.pm:2078 +msgid "Please upload a new picture from [_1]." +msgstr "請由[_1]建新圖片。" + +#: lib/perl5/Selima/Form.pm:2228 +msgid "[numerate,_1,Subcategory,Subcategories]:" +msgstr "子類:" + +#: lib/perl5/Selima/Form.pm:2256 +msgid "Script:" +msgstr "程式:" + +#: lib/perl5/Selima/Form.pm:2261 +msgid "S/N:" +msgstr "編號:" + +#: lib/perl5/Selima/Form.pm:2266 +msgid "Tel.:" +msgstr "電話:" + +#: lib/perl5/Selima/Form.pm:2271 +msgid "Title:" +msgstr "標題:" + +#: lib/perl5/Selima/Form.pm:2276 +msgid "English title:" +msgstr "英文標題:" + +#: lib/perl5/Selima/Form.pm:2281 +msgid "Updated:" +msgstr "維護日期:" + +#: lib/perl5/Selima/Form.pm:2286 +msgid "Updated by:" +msgstr "維護者:" + +#: lib/perl5/Selima/Form.pm:2291 +msgid "URL:" +msgstr "網址:" + +#: lib/perl5/Selima/Form.pm:2296 lib/perl5/Selima/Form/UserPref.pm:94 +msgid "Value:" +msgstr "值:" + +#: lib/perl5/Selima/Form.pm:2301 +msgid "Visited:" +msgstr "上站日期:" + +#: lib/perl5/Selima/Form.pm:2306 +msgid "Visits:" +msgstr "上站次數:" + +#: lib/perl5/Selima/Init.pm:216 +msgid "" +"Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, " +"My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) " +"are are not welcome. It duplicates your request and produces high load and " +"even crashes to our server. Please remove it first before you visit us." +msgstr "" +"抱歉,我們不歡迎加裝 FunWebProduct 外掛(如 Smiley Central 、 PopSwatter 、 " +"Spin4Dough 、 My Mail Signature 、 My Mail Stationery 、 My Mail Stamp 、 " +"Cursor Mania ……等等)的瀏覽器。 FunWebProduct 會重抓你看過的每一頁網頁,造" +"成網站負荷加倍,甚至當機。請先移除 FunWebProduct ,再上來瀏覽。" + +#: lib/perl5/Selima/Links.pm:242 +msgid "Related Links" +msgstr "相關網站連結" + +#: lib/perl5/Selima/List.pm:109 +msgid "Select" +msgstr "選擇" + +#: lib/perl5/Selima/List.pm:112 +msgid "Select A Data Record" +msgstr "選擇資料" + +#: lib/perl5/Selima/List.pm:114 +msgid "Edit" +msgstr "設定" + +#: lib/perl5/Selima/List.pm:116 +msgid "Manage Data" +msgstr "管理資料" + +#: lib/perl5/Selima/List.pm:158 +msgid "S/N" +msgstr "編號" + +#: lib/perl5/Selima/List.pm:159 +msgid "Created" +msgstr "建檔日期" + +#: lib/perl5/Selima/List.pm:160 +msgid "Created by" +msgstr "建檔者" + +#: lib/perl5/Selima/List.pm:161 +msgid "Updated" +msgstr "維護日期" + +#: lib/perl5/Selima/List.pm:162 +msgid "Updated by" +msgstr "維護者" + +#: lib/perl5/Selima/List.pm:164 +msgid "Content" +msgstr "內文" + +#: lib/perl5/Selima/List.pm:165 +msgid "Category" +msgstr "分類" + +#: lib/perl5/Selima/List.pm:166 +msgid "Date" +msgstr "日期" + +#: lib/perl5/Selima/List.pm:168 lib/perl5/Selima/List/Groups.pm:30 +msgid "Description" +msgstr "說明" + +#: lib/perl5/Selima/List.pm:169 lib/perl5/Selima/List/Guestbook/Public.pm:138 +msgid "E-mail" +msgstr "E-mail" + +#: lib/perl5/Selima/List.pm:170 +msgid "Hidden?" +msgstr "隱藏?" + +#: lib/perl5/Selima/List.pm:172 +msgid "ID." +msgstr "代號" + +#: lib/perl5/Selima/List.pm:173 +msgid "Keywords" +msgstr "關鍵字" + +#: lib/perl5/Selima/List.pm:174 +msgid "Name" +msgstr "名字" + +#: lib/perl5/Selima/List.pm:175 +msgid "Order" +msgstr "次序" + +#: lib/perl5/Selima/List.pm:176 lib/perl5/Selima/List/Pages.pm:32 +msgid "Page path" +msgstr "網頁路徑" + +#: lib/perl5/Selima/List.pm:177 +msgid "Picture" +msgstr "圖片" + +#: lib/perl5/Selima/List.pm:178 +msgid "Pic. ratio" +msgstr "圖片比例" + +#: lib/perl5/Selima/List.pm:179 +msgid "Pic. caption" +msgstr "圖片標題" + +#: lib/perl5/Selima/List.pm:180 +msgid "Pic. position" +msgstr "圖片位置" + +#: lib/perl5/Selima/List.pm:181 +msgid "Title" +msgstr "標題" + +#: lib/perl5/Selima/List.pm:182 +msgid "English title" +msgstr "英文標題" + +#: lib/perl5/Selima/List.pm:183 +msgid "URL." +msgstr "網址" + +#: lib/perl5/Selima/List.pm:184 +msgid "Status (slow)" +msgstr "狀態(慢)" + +#: lib/perl5/Selima/List.pm:423 +msgid "Nothing found. Please try another query." +msgstr "查無相符的資料,請重新搜尋。" + +#: lib/perl5/Selima/List.pm:426 +msgid "The database is empty." +msgstr "現無任何資料。" + +#: lib/perl5/Selima/List.pm:432 +msgid "Your query found [*,_1,record]." +msgstr "共 [#,_1] 筆相符的資料。" + +#: lib/perl5/Selima/List.pm:435 +msgid "[*,_1,record]." +msgstr "共 [#,_1] 筆資料。" + +#: lib/perl5/Selima/List.pm:441 +msgid "Your query found [*,_1,record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的資料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List.pm:445 +msgid "[*,_1,record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆資料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List.pm:456 +msgid "First" +msgstr "第一頁" + +#: lib/perl5/Selima/List.pm:457 +msgid "Previous" +msgstr "前一頁" + +#: lib/perl5/Selima/List.pm:458 +msgid "Next" +msgstr "下一頁" + +#: lib/perl5/Selima/List.pm:459 +msgid "Last" +msgstr "最末頁" + +#: lib/perl5/Selima/List.pm:502 +msgid "Picture unavailable" +msgstr "圖片無法顯示" + +#: lib/perl5/Selima/List.pm:530 +msgid "Page number ([_1]) invalid. Please specify a valid page number." +msgstr "頁數([_1])無效,請設成有效的數字。" + +#: lib/perl5/Selima/List.pm:536 +msgid "" +"Page number ([#,_1]) out of range. Please specify between 1 and [#,_2]." +msgstr "頁數([#,_1])超出範圍,請設在 1 到 [#,_2] 之間。" + +#: lib/perl5/Selima/List.pm:613 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:61 +msgid "Please fill in your query." +msgstr "請填上查詢的內容。" + +#: lib/perl5/Selima/List.pm:749 lib/perl5/Selima/List.pm:759 +msgid "You cannot sort by \"[_1]\"." +msgstr "無法以「 [_1] 」排序。" + +#: lib/perl5/Selima/List.pm:1082 +#: lib/perl5/Selima/List/Accounting/Reports.pm:412 +msgid "Search" +msgstr "搜尋" + +#: lib/perl5/Selima/List.pm:1181 +msgid "Index" +msgstr "目錄" + +#: lib/perl5/Selima/List.pm:1319 +msgid "Page:" +msgstr "頁:" + +#: lib/perl5/Selima/List.pm:1320 lib/perl5/Selima/List.pm:1392 +#: lib/perl5/Selima/List.pm:1449 +msgid "View" +msgstr "瀏覽" + +#: lib/perl5/Selima/List.pm:1364 lib/perl5/Selima/List.pm:1476 +msgid "Delete the selected items." +msgstr "刪除勾選的項目。" + +#: lib/perl5/Selima/List.pm:1389 +msgid "No." +msgstr "編號" + +#: lib/perl5/Selima/List.pm:1500 +#: lib/perl5/Selima/List/Accounting/Reports.pm:587 +msgid "Set" +msgstr "設定" + +#: lib/perl5/Selima/List.pm:1521 +#: lib/perl5/Selima/List/Accounting/Reports.pm:604 +msgid "Rows per page:" +msgstr "每頁顯示筆數:" + +#: lib/perl5/Selima/List.pm:1529 +msgid "Display columns:" +msgstr "顯示欄位:" + +#: lib/perl5/Selima/List.pm:1564 +msgid "Malformed" +msgstr "格式錯亂" + +#: lib/perl5/Selima/List.pm:1598 +msgid "OK" +msgstr "好" + +#: lib/perl5/Selima/List.pm:1598 +msgid "Unreachable" +msgstr "連不上" + +#: lib/perl5/Selima/LnInfo.pm:49 +msgid "Traditional Chinese" +msgstr "正體中文" + +#: lib/perl5/Selima/LnInfo.pm:59 +msgid "Simplified Chinese" +msgstr "簡體中文" + +#: lib/perl5/Selima/LnInfo.pm:69 +msgid "English" +msgstr "英文" + +#: lib/perl5/Selima/LnInfo.pm:79 +msgid "Japanese" +msgstr "日文" + +#: lib/perl5/Selima/LnInfo.pm:89 +msgid "German" +msgstr "德文" + +#: lib/perl5/Selima/LnInfo.pm:242 +#, c-format +msgid "Switch to the %s version of this page." +msgstr "切換到本頁的%s版。" + +#: lib/perl5/Selima/PageFunc.pm:221 +msgid "Web pages" +msgstr "網頁" + +#: lib/perl5/Selima/PageFunc.pm:222 +msgid "News" +msgstr "新聞" + +#: lib/perl5/Selima/PageFunc.pm:223 +msgid "Related links" +msgstr "相關連結" + +#: lib/perl5/Selima/PageFunc.pm:224 +msgid "Home page" +msgstr "首頁" + +#: lib/perl5/Selima/PageFunc.pm:225 +msgid "Whole web site" +msgstr "整個網站" + +#: lib/perl5/Selima/Picture.pm:49 +msgid "Left-aligned" +msgstr "靠左" + +#: lib/perl5/Selima/Picture.pm:50 +msgid "Right-aligned" +msgstr "靠右" + +#: lib/perl5/Selima/Picture.pm:87 +#, c-format +msgid "Width: [#,_1], height: [#,_2], ratio: [sprintf,%0.2f,_3]" +msgstr "寬: [#,_1] ,高: [#,_2] ,比例: [sprintf,%0.2f,_3]" + +#: lib/perl5/Selima/Picture.pm:113 +msgid "Please specify a numeric ratio." +msgstr "比例請設定數字。" + +#: lib/perl5/Selima/Picture.pm:116 +msgid "Please specify a positive ratio." +msgstr "比例請設定正數。" + +#: lib/perl5/Selima/Picture.pm:118 +#, c-format +msgid "Please specify a ratio less than or equal to [sprintf,%0.2f,_1]." +msgstr "比例請勿大於 [sprintf,%0.2f,_1] 。" + +#: lib/perl5/Selima/Picture.pm:122 +msgid "This image is too large to display." +msgstr "圖片太大,無法顯示。" + +#: lib/perl5/Selima/Preview.pm:53 lib/perl5/Selima/Preview.pm:115 +msgid "Unknown preview source: \"[_1]\"." +msgstr "預覽資料源不明:「 [_1] 」。" + +#: lib/perl5/Selima/Preview.pm:69 +msgid "Unknown preview form: \"[_1]\"." +msgstr "預覽表格不明: [_1] 。" + +#: lib/perl5/Selima/Preview.pm:126 +msgid "Preview" +msgstr "預覽" + +#: lib/perl5/Selima/Preview.pm:127 +msgid "Finish preview and return." +msgstr "結束預覽回前頁。" + +#: lib/perl5/Selima/Processor.pm:203 +msgid "This record was not modified." +msgstr "資料未異動。" + +#: lib/perl5/Selima/Processor.pm:207 +msgid "This record has been successfully added." +msgstr "資料建好了。" + +#: lib/perl5/Selima/Processor.pm:211 +msgid "This record has been successfully updated." +msgstr "資料存好了。" + +#: lib/perl5/Selima/Processor.pm:215 +msgid "This record has been successfully deleted." +msgstr "資料刪掉了。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:41 +msgid "Please select a accounting transaction." +msgstr "請選擇會計傳票。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:44 +msgid "" +"This accounting transaction does not exist anymore. Please select another " +"one." +msgstr "查無此會計傳票,請重新選擇。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:62 +msgid "This option is invalid. Please select a proper type." +msgstr "類型選項無效,請由表上選擇適當的類型。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:83 +msgid "Please select a accounting subject." +msgstr "請選擇會計科目。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:86 +msgid "" +"This accounting subject does not exist anymore. Please select another one." +msgstr "查無此會計科目,請重新選擇。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:93 +msgid "" +"Only a last-level accounting subject is allowed for an accounting subject." +msgstr "限選最下層的會計科目。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:113 +msgid "This summary is too long. (Max. length [#,_1])" +msgstr "摘要太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/AcctRec.pm:137 +msgid "Please fill in the amount." +msgstr "請填上金額。" + +#: lib/perl5/Selima/Checker/AcctRec.pm:140 +msgid "This amount is too long. (Max. length [#,_1])" +msgstr "金額太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/AcctRec.pm:144 +msgid "Please fill in a positive integer amount." +msgstr "金額請填正整數。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:39 +msgid "Please fill in the code." +msgstr "請填上代碼。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:42 +msgid "This code is too long. (Max. length [#,_1])" +msgstr "代碼太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:46 +msgid "Only numbers are allowed for the code." +msgstr "代碼限用數字。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:56 +msgid "" +"This accounting subject already exists. You cannot create a duplicated one." +msgstr "已有該會計科目,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:65 +msgid "" +"Accounting subject [_1] does not exist. You cannot create a subject under " +"that." +msgstr "查無會計科目 [_1] ,請勿建立其下的科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:80 +#: lib/perl5/Selima/Checker/AcctSubj.pm:101 +msgid "Please select a parent accounting subject." +msgstr "請選擇所屬的大會計科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:85 +msgid "" +"This option is invalid. Please select a proper parent accounting subject." +msgstr "大會計科目選項無效,請由表上選擇適當的大會計科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:92 +msgid "" +"An accounting subject having its code with a single digit must not have a " +"parent." +msgstr "會計科目代碼一位數時,不可設所屬的大會計科目。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:104 +msgid "" +"An accounting subject cannot belong to itself. Please select another one." +msgstr "科目不可屬於自己本身,請重新選擇。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:108 +msgid "" +"This parent accounting subject does not exist anymore. Please select " +"another one." +msgstr "查無此大會計科目,請重新選擇。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:113 +msgid "" +"The parent accounting subject of accounting subject [_1] must be of code " +"[_2], not [_3]." +msgstr "會計科目 [_1] 所屬的大會計科目代碼須為 [_2] ,不可為 [_3] 。" + +#: lib/perl5/Selima/Checker/AcctSubj.pm:122 +msgid "" +"An accounting subject having its code with more than one digit must have a " +"parent." +msgstr "會計科目代碼兩位數或以上時,須設所屬的大會計科目。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:53 +msgid "This form suptype is invalid. Please specify a proper user." +msgstr "子表單無效,請設定適當的子表單。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:73 +msgid "Please fill in the credit side of the accounting transaction." +msgstr "請填上會計傳票的貸方。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:75 +#: lib/perl5/Selima/Checker/AcctTrx.pm:98 +msgid "Please fill in the accounting transaction content." +msgstr "請填上會計傳票內容。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:96 +msgid "Please fill in the debit side of the accounting transaction." +msgstr "請填上會計傳票的借方。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:162 +msgid "" +"The total amounts of the debit side and the credit side are not balanced " +"(debit [_1], credit [_2]." +msgstr "借方和貸方總金額未平衡。(借方合計 [_1] ,貸方合計 [_2] )" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:182 +#: lib/perl5/Selima/Form/AcctTrx.pm:802 +msgid "Fill in the note here." +msgstr "請填上註記。" + +#: lib/perl5/Selima/Checker/AcctTrx.pm:185 +msgid "This note is too long. (Max. length [#,_1])" +msgstr "註記太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/GroupMem.pm:54 +msgid "Please select a different belonging group." +msgstr "隸屬群組請選擇別的群組。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:74 +#: lib/perl5/Selima/Checker/UserMem.pm:59 +msgid "Please select a member." +msgstr "請選擇成員。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:77 +#: lib/perl5/Selima/Checker/UserMem.pm:62 +msgid "This member does not exist anymore. Please select another one." +msgstr "查無此成員,請重新選擇。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:80 +msgid "Please select a different group member." +msgstr "群組成員請選擇別的群組。" + +#: lib/perl5/Selima/Checker/GroupMem.pm:103 +#: lib/perl5/Selima/Checker/UserMem.pm:83 +msgid "" +"This membership record already exists. You cannot create a duplicated one." +msgstr "已有同一成員關係,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/Group.pm:45 +msgid "Please fill in the group ID." +msgstr "請填上群組代號。" + +#: lib/perl5/Selima/Checker/Group.pm:48 +msgid "This group ID. is too long. (Max. length [#,_1])" +msgstr "群組代號太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Group.pm:51 +msgid "This group ID. is too short. (Min. length [#,_1])" +msgstr "群組代號太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/Group.pm:55 +msgid "" +"Only lower-case English letters, numbers and underscores are allowed for the " +"group ID." +msgstr "群組代號限用小寫英文字母、數字和底線。" + +#: lib/perl5/Selima/Checker/Group.pm:65 +msgid "This group already exists. You cannot create a duplicated one." +msgstr "已有同一群組,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/Group.pm:83 +msgid "Please fill in the privilege description." +msgstr "請填上權限說明。" + +#: lib/perl5/Selima/Checker/Group.pm:86 +msgid "This privilege description is too long. (Max. length [#,_1])" +msgstr "權限說明太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:38 +#: lib/perl5/Selima/Checker/Guestbook.pm:60 +msgid "This signature is too long. (Max. length [#,_1])" +msgstr "簽名太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:57 +msgid "Please fill in the signature." +msgstr "請填上簽名。" + +#: lib/perl5/Selima/Checker/Guestbook.pm:79 +msgid "This identity is too long. (Max. length [#,_1])" +msgstr "身份太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:98 +msgid "This location is too long. (Max. length [#,_1])" +msgstr "所在地太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:117 +#: lib/perl5/Selima/Checker/Link.pm:92 lib/perl5/Selima/Checker/User.pm:229 +msgid "This e-mail is too long. (Max. length [#,_1])" +msgstr "E-mail 信箱太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook.pm:136 +msgid "This website URL is too long. (Max. length [#,_1])" +msgstr "網站網址太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/LinkCat.pm:40 +msgid "" +"\"index\" is dedicated to the index file index.html. You cannot set the ID. " +"as \"index\"." +msgstr "「 index 」為目錄檔 index.html 專用,代號不可設為「 index 」。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:56 +msgid "This category already exists. You cannot create a duplicated one." +msgstr "已有同一分類,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:70 +#: lib/perl5/Selima/Checker/LinkCat.pm:85 +msgid "Please select a parent category." +msgstr "請選擇所屬的大類。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:75 +msgid "This option is invalid. Please select a proper parent category." +msgstr "大類選項無效,請由表上選擇適當的大類。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:88 +msgid "" +"This parent category does not exist anymore. Please select another one." +msgstr "查無此大類,請重新選擇。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:92 +msgid "A category cannot belong to itself. Please select another one." +msgstr "分類不可屬於自己本身,請重新選擇。" + +#: lib/perl5/Selima/Checker/LinkCat.pm:99 +msgid "A category cannot belong to its descendant. Please select another one." +msgstr "分類不可屬於自己的子類,請重新選擇。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:56 lib/perl5/Selima/Checker/Link.pm:72 +msgid "Please select a category." +msgstr "請選擇分類。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:59 lib/perl5/Selima/Checker/Link.pm:67 +msgid "This category does not exist anymore. Please select another one." +msgstr "查無此分類,請重新選擇。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:77 +msgid "Please select a related link." +msgstr "請選擇相關連結。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:80 +msgid "This related link does not exist anymore. Please select another one." +msgstr "查無此相關連結,請重新選擇。" + +#: lib/perl5/Selima/Checker/LinkCatz.pm:101 +msgid "" +"This categorization record already exists. You cannot create a duplicated " +"one." +msgstr "已有同一分類資料,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/Link.pm:44 +msgid "This address is too long. (Max. length [#,_1])" +msgstr "地址太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:64 +msgid "This category is duplicated. You cannot set duplicated ones." +msgstr "分類重複,請勿重複設定。" + +#: lib/perl5/Selima/Checker/Link.pm:95 lib/perl5/Selima/Checker/User.pm:232 +msgid "This e-mail is too short. (Min. length [#,_1])" +msgstr "E-mail 信箱太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:99 lib/perl5/Selima/Checker/MailTo.pm:36 +#: lib/perl5/Selima/Checker/User.pm:236 +msgid "Please fill in a valid e-mail address." +msgstr "請填上正確的 E-mail 信箱。" + +#: lib/perl5/Selima/Checker/Link.pm:101 lib/perl5/Selima/Checker/MailTo.pm:38 +#: lib/perl5/Selima/Checker/User.pm:238 +msgid "" +"The domain of this e-mail does not exists. Check if there is any typo in it." +msgstr "查無這個信箱的所屬網域,請檢查有沒有拼錯。" + +#: lib/perl5/Selima/Checker/Link.pm:122 +msgid "This facsimile number is too long. (Max. length [#,_1])" +msgstr "傳真號碼太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:143 +msgid "This link icon URL is too long. (Max. length [#,_1])" +msgstr "連結小圖網址太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:147 +msgid "Please fill in a valid link icon URL." +msgstr "請填上正確的連結小圖網址。" + +#: lib/perl5/Selima/Checker/Link.pm:150 +msgid "This link icon URL is not reachable. Check if there is any typo in it." +msgstr "連結小圖連不上,請檢查有沒有拼錯。" + +#: lib/perl5/Selima/Checker/Link.pm:171 +msgid "This telephone number is too long. (Max. length [#,_1])" +msgstr "電話號碼太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:192 +msgid "This 2nd language title is too long. (Max. length [#,_1])" +msgstr "第二語言標題太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:211 +msgid "Please fill in the URL." +msgstr "請填上網址。" + +#: lib/perl5/Selima/Checker/Link.pm:214 +msgid "This URL is too long. (Max. length [#,_1])" +msgstr "網址太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Link.pm:218 +msgid "Please fill in a valid URL." +msgstr "請填上正確的網址。" + +#: lib/perl5/Selima/Checker/Link.pm:228 +msgid "This related link already exists. You cannot create a duplicated one." +msgstr "已有同一相關連結,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/Link.pm:231 +msgid "This URL is not reachable. Check if there is any typo in it." +msgstr "這個網址連不上,請檢查有沒有拼錯。" + +#: lib/perl5/Selima/Checker/ListPref.pm:42 +#: lib/perl5/Selima/Checker/UserPref.pm:88 +msgid "Please fill in the preference domain." +msgstr "請填上偏好的適用範圍。" + +#: lib/perl5/Selima/Checker/ListPref.pm:45 +#: lib/perl5/Selima/Checker/UserPref.pm:91 +msgid "This preference domain is too long. (Max. length [#,_1])" +msgstr "偏好適用範圍太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/ListPref.pm:90 +msgid "Please fill in the number of rows per page." +msgstr "請填上每頁顯示筆數。" + +#: lib/perl5/Selima/Checker/ListPref.pm:93 +msgid "Please fill in a positive integer number of rows per page." +msgstr "每頁顯示筆數請填正整數。" + +#: lib/perl5/Selima/Checker/ListPref.pm:100 +msgid "This number of rows per page is too long. (Max. length [#,_1])" +msgstr "每頁顯示筆數太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/LogIn.pm:63 +msgid "Please fill in your user ID." +msgstr "請填上妳的帳號。" + +#: lib/perl5/Selima/Checker/LogIn.pm:70 lib/perl5/Selima/Checker/LogIn.pm:76 +#: lib/perl5/Selima/Checker/LogIn.pm:91 lib/perl5/Selima/Checker/LogIn.pm:136 +#: lib/perl5/Selima/Checker/LogIn.pm:142 lib/perl5/Selima/Checker/LogIn.pm:151 +#: lib/perl5/Selima/Checker/LogIn.pm:178 +msgid "Log in failed. Either your user ID or your password is incorrect." +msgstr "登入錯誤,使用者代號或密碼有誤。" + +#: lib/perl5/Selima/Checker/LogIn.pm:109 +msgid "" +"Your account is disabled. Contact our system administrator for assistence." +msgstr "帳號停用中,請洽系統管理員。" + +#: lib/perl5/Selima/Checker/LogIn.pm:129 +msgid "Please fill in your password." +msgstr "請填上妳的密碼。" + +#: lib/perl5/Selima/Checker/LogIn.pm:199 +msgid "You are not an administrator and cannot log into here." +msgstr "非管理員勿入。" + +#: lib/perl5/Selima/Checker/LogIn.pm:218 +msgid "You are an administrator and cannot log into here." +msgstr "管理人員勿入。" + +#: lib/perl5/Selima/Checker/MailTo.pm:29 lib/perl5/Selima/Checker/User.pm:226 +msgid "Please fill in the e-mail." +msgstr "請填上 E-mail 信箱。" + +#: lib/perl5/Selima/Checker/Rebuild.pm:28 +msgid "Please select the type." +msgstr "請選擇類型。" + +#: lib/perl5/Selima/Checker/Rebuild.pm:31 +msgid "This type does not exist anymore. Please select another one." +msgstr "查無此類型,請重新選擇。" + +#: lib/perl5/Selima/Checker/ScptPriv.pm:63 +msgid "" +"This script privilege record already exists. You cannot create a duplicated " +"one." +msgstr "已有同一程式權限資料,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/User.pm:85 +msgid "Please fill in the user ID." +msgstr "請填上帳號。" + +#: lib/perl5/Selima/Checker/User.pm:88 +msgid "This user ID. is too long. (Max. length [#,_1])" +msgstr "帳號太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:91 +msgid "This user ID. is too short. (Min. length [#,_1])" +msgstr "帳號太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:95 +msgid "" +"Only English letters, numbers, at-signs, dots, dashes and underscores are " +"allowed for the user ID." +msgstr "帳號限用英文字母、數字、 @ 號、點、橫線和底線。" + +#: lib/perl5/Selima/Checker/User.pm:105 +msgid "This user already has an account. You cannot create a duplicated one." +msgstr "該使用者已有帳號,請勿重複建檔。" + +#: lib/perl5/Selima/Checker/User.pm:129 +msgid "Please fill in the password." +msgstr "請填上密碼。" + +#: lib/perl5/Selima/Checker/User.pm:131 +msgid "Please confirm the password." +msgstr "請確認密碼。" + +#: lib/perl5/Selima/Checker/User.pm:134 +msgid "This password is too long. (Max. length [#,_1])" +msgstr "密碼太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:137 +msgid "This password is too short. (Min. length [#,_1])" +msgstr "密碼太短了。(最短 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:142 +msgid "The 2 passwords are different. Please fill in the password again." +msgstr "兩次密碼不合,請重新設定密碼。" + +#: lib/perl5/Selima/Checker/User.pm:151 +msgid "This password is based on the user ID." +msgstr "密碼不可由帳號組成。" + +#: lib/perl5/Selima/Checker/User.pm:166 +msgid "This password does not contain enough different characters." +msgstr "密碼重複的字元太多。" + +#: lib/perl5/Selima/Checker/User.pm:170 +msgid "This password is too simplistic/systematic." +msgstr "密碼結構太簡單。" + +#: lib/perl5/Selima/Checker/User.pm:174 +msgid "This password is based on a dictionary word." +msgstr "密碼不可由字典單字組成。" + +#: lib/perl5/Selima/Checker/User.pm:176 +msgid "This password is based on a (reversed) dictionary word." +msgstr "密碼不可由倒過來的字典單字組成。" + +#: lib/perl5/Selima/Checker/User.pm:178 +msgid "This password is too simple." +msgstr "密碼太簡單。" + +#: lib/perl5/Selima/Checker/User.pm:183 +msgid "You cannot use a password that is based on your user ID." +msgstr "密碼不可由帳號組成。" + +#: lib/perl5/Selima/Checker/User.pm:203 +msgid "Please fill in the name." +msgstr "請填上姓名。" + +#: lib/perl5/Selima/Checker/User.pm:206 +msgid "This name is too long. (Max. length [#,_1])" +msgstr "姓名太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/User.pm:259 +msgid "This belonging group is duplicated. You cannot set duplicated ones." +msgstr "隸屬群組重複,請勿重複設定。" + +#: lib/perl5/Selima/Checker/User.pm:271 +msgid "You cannot submit the super-user group along with other groups." +msgstr "總管理員群組不可與其它群組一起設定。" + +#: lib/perl5/Selima/Checker/User.pm:273 +msgid "You cannot set the administrators group." +msgstr "不可設定所有網站管理員群組" + +#: lib/perl5/Selima/Checker/User.pm:275 +msgid "You cannot set the all-users group." +msgstr "不可設定所有登入使用者群組。" + +#: lib/perl5/Selima/Checker/UserPref.pm:50 +msgid "Please select the user." +msgstr "請選擇使用者。" + +#: lib/perl5/Selima/Checker/UserPref.pm:55 +msgid "This option is invalid. Please select a proper user." +msgstr "使用者選項無效,請由表上選擇適當的使用者。" + +#: lib/perl5/Selima/Checker/UserPref.pm:73 +msgid "Please set the preference domain." +msgstr "請設定適用範圍。" + +#: lib/perl5/Selima/Checker/UserPref.pm:78 +msgid "This option is invalid. Please set a proper preference domain." +msgstr "適用範圍選項無效,請設定適當的適用範圍。" + +#: lib/perl5/Selima/Checker/UserPref.pm:111 +msgid "Please fill in the preference name." +msgstr "請填上偏好的名稱。" + +#: lib/perl5/Selima/Checker/UserPref.pm:114 +msgid "This preference name is too long. (Max. length [#,_1])" +msgstr "偏好名稱太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/UserPref.pm:133 +msgid "Please fill in the preference value." +msgstr "請填上偏好的值。" + +#: lib/perl5/Selima/Checker/UserPref.pm:136 +msgid "This preference value is too long. (Max. length [#,_1])" +msgstr "偏好值太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/UserPref.pm:167 +msgid "" +"This user preference already exists. You cannot create a duplicated one." +msgstr "已有同一使用者偏好,請勿重複建檔。" + +#: lib/perl5/Selima/Form/AcctRec.pm:33 +msgid "Delete this accounting record" +msgstr "刪掉這筆會計分錄" + +#: lib/perl5/Selima/Form/AcctRec.pm:38 +msgid "This table provides you a form to add a new accounting record." +msgstr "本表提供建新會計分錄的表單。" + +#: lib/perl5/Selima/Form/AcctRec.pm:41 +msgid "This table provides you a form to edit a current accounting record." +msgstr "本表提供編輯會計分錄的表單。" + +#: lib/perl5/Selima/Form/AcctRec.pm:44 +msgid "This table provides you a form to delete an accounting record." +msgstr "本表提供刪除會計分錄的表單。" + +#: lib/perl5/Selima/Form/AcctRec.pm:61 +msgid "Add a New Accounting Record" +msgstr "建新會計分錄。" + +#: lib/perl5/Selima/Form/AcctRec.pm:64 +msgid "Edit a Current Accounting Record" +msgstr "編輯會計分錄" + +#: lib/perl5/Selima/Form/AcctRec.pm:67 +msgid "Delete an Accounting Record" +msgstr "刪除會計分錄" + +#: lib/perl5/Selima/Form/AcctRec.pm:76 +msgid "Accounting transaction:" +msgstr "會計傳票:" + +#: lib/perl5/Selima/Form/AcctRec.pm:85 lib/perl5/Selima/Form/AcctTrx.pm:334 +#: lib/perl5/Selima/List/Accounting/Reports.pm:75 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:233 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:226 +msgid "Debit" +msgstr "借方" + +#: lib/perl5/Selima/Form/AcctRec.pm:87 lib/perl5/Selima/Form/AcctTrx.pm:335 +#: lib/perl5/Selima/List/Accounting/Reports.pm:76 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:237 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:230 +msgid "Credit" +msgstr "貸方" + +#: lib/perl5/Selima/Form/AcctRec.pm:88 lib/perl5/Selima/Form/Rebuild.pm:52 +msgid "Type:" +msgstr "類型:" + +#: lib/perl5/Selima/Form/AcctRec.pm:99 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:284 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:268 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:328 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:284 +msgid "Accounting subject:" +msgstr "會計科目:" + +#: lib/perl5/Selima/Form/AcctRec.pm:157 +msgid "Summary:" +msgstr "摘要:" + +#: lib/perl5/Selima/Form/AcctRec.pm:162 +msgid "Amount:" +msgstr "金額:" + +#: lib/perl5/Selima/Form/AcctSubj.pm:34 +msgid "Delete this accounting subject" +msgstr "刪掉這個會計科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:39 +msgid "This table provides you a form to add a new accounting subject." +msgstr "本表提供建新會計科目的表單。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:42 +msgid "This table provides you a form to edit a current accounting subject." +msgstr "本表提供編輯會計科目的表單。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:45 +msgid "This table provides you a form to delete an accounting subject." +msgstr "本表提供刪除會計科目的表單。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:62 +msgid "Add a New Accounting Subject" +msgstr "建新會計科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:65 +msgid "Edit a Current Accounting Subject" +msgstr "編輯會計科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:68 +msgid "Delete an Accounting Subject" +msgstr "刪除會計科目" + +#: lib/perl5/Selima/Form/AcctSubj.pm:75 +msgid "" +"This accounting subject has [numerate,_1,an accounting sub-subject," +"accounting sub-subjects]. It cannot be deleted. To delete the accounting " +"subject, [numerate,_1,its accounting sub-subject,all of its accounting sub-" +"subjects] must first be deleted." +msgstr "" +"本會計科目下有子會計科目,不可直接刪除。要刪除本科目,請先刪除其下的子會計科" +"目。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:79 +msgid "" +"This accounting subject has [numerate,_1,an accounting record,accounting " +"records]. It cannot be deleted. To delete the accounting subject, " +"[numerate,_1,its accounting record,all of its accounting records] must first " +"be deleted." +msgstr "" +"本會計科目下有會計分錄,不可直接刪除。要刪除本會計科目,請先刪除其下的會計分" +"錄。" + +#: lib/perl5/Selima/Form/AcctSubj.pm:87 +msgid "Code:" +msgstr "代碼:" + +#: lib/perl5/Selima/Form/AcctSubj.pm:93 +msgid "Parent subject:" +msgstr "大科目:" + +#: lib/perl5/Selima/Form/AcctSubj.pm:106 +msgid "[numerate,_1,Sub-subject,Sub-subjects]:" +msgstr "子科目:" + +#: lib/perl5/Selima/Form/AcctTrx.pm:37 +msgid "Delete this accounting transaction" +msgstr "刪掉這筆會計傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:43 +msgid "This table provides you a form to add a new accounting transaction." +msgstr "本表提供建新會計傳票的表單。" + +#: lib/perl5/Selima/Form/AcctTrx.pm:46 +msgid "" +"This table provides you a form to edit a current accounting transaction." +msgstr "本表提供編輯會計傳票的表單。" + +#: lib/perl5/Selima/Form/AcctTrx.pm:49 +msgid "This table provides you a form to delete an accounting transaction." +msgstr "本表提供刪除會計傳票的表單。" + +#: lib/perl5/Selima/Form/AcctTrx.pm:92 lib/perl5/Selima/Form/AcctTrx.pm:97 +msgid "Convert to a transfer transaction" +msgstr "轉為轉帳傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:102 +msgid "Add a New Cache Expense Transaction" +msgstr "建新現金支出傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:104 +msgid "Add a New Cache Income Transaction" +msgstr "建新現金收入傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:106 +msgid "Add a New Transfer Transaction" +msgstr "建新轉帳傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:111 +msgid "Edit a Current Cache Expense Transaction" +msgstr "編輯現金支出傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:113 +msgid "Edit a Current Cache Income Transaction" +msgstr "編輯現金收入傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:115 +msgid "Edit a Current Transfer Transaction" +msgstr "編輯轉帳傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:120 +msgid "Delete a Cache Expense Transaction" +msgstr "刪除現金支出傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:122 +msgid "Delete a Cache Income Transaction" +msgstr "刪除現金收入傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:124 +msgid "Delete a Transfer Transaction" +msgstr "刪掉轉帳傳票" + +#: lib/perl5/Selima/Form/AcctTrx.pm:336 +#: lib/perl5/Selima/List/Accounting/Records.pm:35 +#: lib/perl5/Selima/List/Accounting/Reports.pm:73 +msgid "Accounting subject" +msgstr "會計科目" + +#: lib/perl5/Selima/Form/AcctTrx.pm:337 +#: lib/perl5/Selima/List/Accounting/Records.pm:36 +#: lib/perl5/Selima/List/Accounting/Reports.pm:74 +msgid "Summary" +msgstr "摘要" + +#: lib/perl5/Selima/Form/AcctTrx.pm:338 +#: lib/perl5/Selima/List/Accounting/Records.pm:37 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:40 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:41 +msgid "Amount" +msgstr "金額" + +#: lib/perl5/Selima/Form/AcctTrx.pm:339 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:173 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:196 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:200 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:152 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:130 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:151 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:177 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:166 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:189 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:144 +msgid "Total" +msgstr "合計" + +#: lib/perl5/Selima/Form/AcctTrx.pm:379 lib/perl5/Selima/Form/AcctTrx.pm:518 +#: lib/perl5/Selima/Form/AcctTrx.pm:708 +msgid "[numerate,_1,Content]:" +msgstr "內容:" + +#: lib/perl5/Selima/Form/AcctTrx.pm:801 +msgid "Note:" +msgstr "註記:" + +#: lib/perl5/Selima/Form/GroupMem.pm:33 lib/perl5/Selima/Form/UserMem.pm:33 +msgid "Delete this membership record" +msgstr "刪掉這筆成員關係" + +#: lib/perl5/Selima/Form/GroupMem.pm:38 lib/perl5/Selima/Form/UserMem.pm:38 +msgid "This table provides you a form to add a new membership record." +msgstr "本表提供建新成員關係的表單。" + +#: lib/perl5/Selima/Form/GroupMem.pm:41 lib/perl5/Selima/Form/UserMem.pm:41 +msgid "This table provides you a form to change a current membership record." +msgstr "本表提供變更成員關係的表單。" + +#: lib/perl5/Selima/Form/GroupMem.pm:44 lib/perl5/Selima/Form/UserMem.pm:44 +msgid "This table provides you a form to delete a membership record." +msgstr "本表提供刪除成員關係的表單。" + +#: lib/perl5/Selima/Form/GroupMem.pm:61 +msgid "Add A New Group Membership Record" +msgstr "建新群組成員關係" + +#: lib/perl5/Selima/Form/GroupMem.pm:64 +msgid "Change a Current Group Membership Record" +msgstr "變更群組成員關係" + +#: lib/perl5/Selima/Form/GroupMem.pm:67 +msgid "Delete a Group Membership Record" +msgstr "刪除群組成員關係" + +#: lib/perl5/Selima/Form/GroupMem.pm:76 lib/perl5/Selima/Form/UserMem.pm:76 +msgid "Member:" +msgstr "成員:" + +#: lib/perl5/Selima/Form/Group.pm:37 +msgid "Delete this group" +msgstr "刪掉這個群組" + +#: lib/perl5/Selima/Form/Group.pm:42 +msgid "This table provides you a form to add a new group." +msgstr "本表提供建新群組的表單。" + +#: lib/perl5/Selima/Form/Group.pm:45 +msgid "This table provides you a form to update a current group." +msgstr "本表提供設定群組的表單。" + +#: lib/perl5/Selima/Form/Group.pm:48 +msgid "This table provides you a form to delete a group." +msgstr "本表提供刪除群組的表單。" + +#: lib/perl5/Selima/Form/Group.pm:65 +msgid "Add a New Group" +msgstr "建新群組" + +#: lib/perl5/Selima/Form/Group.pm:68 +msgid "Update a Current Group" +msgstr "設定群組" + +#: lib/perl5/Selima/Form/Group.pm:71 +msgid "Delete a Group" +msgstr "刪除群組" + +#: lib/perl5/Selima/Form/Group.pm:77 +msgid "" +"This is a super-user group. You can only change parts of its infomation." +msgstr "這是最高管理員的群組,妳只能設定它部份的資料。" + +#: lib/perl5/Selima/Form/Group.pm:89 lib/perl5/Selima/Form/Group.pm:91 +msgid "Group ID.:" +msgstr "群組代號:" + +#: lib/perl5/Selima/Form/Group.pm:110 +msgid "Add a user" +msgstr "增加成員" + +#: lib/perl5/Selima/Form/Group.pm:114 lib/perl5/Selima/Form/Group.pm:148 +#: lib/perl5/Selima/Form/Group.pm:164 lib/perl5/Selima/Form/Group.pm:211 +msgid "[numerate,_1,User member]:" +msgstr "使用者成員:" + +#: lib/perl5/Selima/Form/Group.pm:239 lib/perl5/Selima/Form/Group.pm:369 +msgid "Add a group" +msgstr "增加群組" + +#: lib/perl5/Selima/Form/Group.pm:243 lib/perl5/Selima/Form/Group.pm:277 +#: lib/perl5/Selima/Form/Group.pm:293 lib/perl5/Selima/Form/Group.pm:340 +msgid "[numerate,_1,Group member]:" +msgstr "群組成員:" + +#: lib/perl5/Selima/Form/Group.pm:368 lib/perl5/Selima/Form/User.pm:223 +msgid "Belonging to:" +msgstr "隸屬群組:" + +#: lib/perl5/Selima/Form/Guestbook.pm:32 +msgid "Delete this message" +msgstr "刪掉這則留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:37 +msgid "This table provides you a form to add a new message." +msgstr "本表提供寫新留言的表單。" + +#: lib/perl5/Selima/Form/Guestbook.pm:40 +msgid "This table provides you a form to edit a current message." +msgstr "本表提供編輯留言的表單。" + +#: lib/perl5/Selima/Form/Guestbook.pm:43 +msgid "This table provides you a form to delete a message." +msgstr "本表提供刪除留言的表單。" + +#: lib/perl5/Selima/Form/Guestbook.pm:61 +msgid "Write a New Message" +msgstr "寫新留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:64 +msgid "Edit a Current Message" +msgstr "編輯留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:67 +msgid "Delete a Message" +msgstr "刪除留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:77 lib/perl5/Selima/Form/User.pm:149 +msgid "Country:" +msgstr "國家:" + +#: lib/perl5/Selima/Form/Guestbook.pm:83 +msgid "Hide this message" +msgstr "隱藏這則留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:83 +msgid "Show this message" +msgstr "秀出這則留言" + +#: lib/perl5/Selima/Form/Guestbook.pm:84 +msgid "Hide this message currently." +msgstr "暫勿秀出這則留言。" + +#: lib/perl5/Selima/Form/Guestbook.pm:89 +msgid "Signature:" +msgstr "簽名:" + +#: lib/perl5/Selima/Form/Guestbook.pm:94 +msgid "Old page no.:" +msgstr "舊頁數:" + +#: lib/perl5/Selima/Form/Guestbook.pm:99 +msgid "Page no.:" +msgstr "頁數:" + +#: lib/perl5/Selima/Form/LinkCat.pm:33 +msgid "Delete this category" +msgstr "刪掉這個分類" + +#: lib/perl5/Selima/Form/LinkCat.pm:38 +msgid "This table provides you a form to add a new category." +msgstr "本表提供建新分類的表單。" + +#: lib/perl5/Selima/Form/LinkCat.pm:41 +msgid "This table provides you a form to edit a current category." +msgstr "本表提供編輯分類的表單。" + +#: lib/perl5/Selima/Form/LinkCat.pm:44 +msgid "This table provides you a form to delete a category." +msgstr "本表提供刪除分類的表單。" + +#: lib/perl5/Selima/Form/LinkCat.pm:62 +msgid "Add a New Link Category" +msgstr "建新連結分類" + +#: lib/perl5/Selima/Form/LinkCat.pm:65 +msgid "Edit a Current Link Category" +msgstr "編輯連結分類" + +#: lib/perl5/Selima/Form/LinkCat.pm:68 +msgid "Delete a Link Category" +msgstr "刪除連結分類" + +#: lib/perl5/Selima/Form/LinkCat.pm:76 +msgid "" +"This category has [numerate,_1,a subcategory,subcategories]. It cannot be " +"deleted. To delete the category, [numerate,_1,its subcategory,all of its " +"subcategories] must first be deleted." +msgstr "本分類下有子類,不可直接刪除。要刪除本分類,請先刪除其下的子類。" + +#: lib/perl5/Selima/Form/LinkCat.pm:80 +msgid "" +"This category has [numerate,_1,a link,links]. It cannot be deleted. To " +"delete the category, [numerate,_1,its link,all of its links] must first be " +"deleted." +msgstr "本分類下有連結,不可直接刪除。要刪除本分類,請先刪除其下的連結。" + +#: lib/perl5/Selima/Form/LinkCat.pm:89 +msgid "Hide this category" +msgstr "隱藏這個分類" + +#: lib/perl5/Selima/Form/LinkCat.pm:89 +msgid "Show this category" +msgstr "秀出這個分類" + +#: lib/perl5/Selima/Form/LinkCat.pm:90 +msgid "Hide this category currently." +msgstr "暫勿秀出這個分類。" + +#: lib/perl5/Selima/Form/LinkCat.pm:106 +msgid "[numerate,_1,Link,Links]:" +msgstr "連結:" + +#: lib/perl5/Selima/Form/LinkCatz.pm:33 +msgid "Delete this categorization record" +msgstr "刪掉這筆分類資料" + +#: lib/perl5/Selima/Form/LinkCatz.pm:38 +msgid "This table provides you a form to add a new categorization record." +msgstr "本表提供建新分類資料的表單。" + +#: lib/perl5/Selima/Form/LinkCatz.pm:41 +msgid "" +"This table provides you a form to change a current categorization record." +msgstr "本表提供變更分類資料的表單。" + +#: lib/perl5/Selima/Form/LinkCatz.pm:44 +msgid "This table provides you a form to delete a categorization record." +msgstr "本表提供刪除分類資料的表單。" + +#: lib/perl5/Selima/Form/LinkCatz.pm:61 +msgid "Add A New Link Categorization Record" +msgstr "建新連結分類資料" + +#: lib/perl5/Selima/Form/LinkCatz.pm:64 +msgid "Change a Current Link Categorization Record" +msgstr "變更連結分類資料" + +#: lib/perl5/Selima/Form/LinkCatz.pm:67 +msgid "Delete a Link Categorization Record" +msgstr "刪除連結分類資料" + +#: lib/perl5/Selima/Form/LinkCatz.pm:76 +msgid "Category:" +msgstr "分類:" + +#: lib/perl5/Selima/Form/LinkCatz.pm:81 +msgid "Link:" +msgstr "連結:" + +#: lib/perl5/Selima/Form/Link.pm:35 +msgid "Delete this related link" +msgstr "刪掉這筆相關連結" + +#: lib/perl5/Selima/Form/Link.pm:40 +msgid "This table provides you a form to add a new related link." +msgstr "本表提供建新相關連結的表單。" + +#: lib/perl5/Selima/Form/Link.pm:43 +msgid "This table provides you a form to edit a current related link." +msgstr "本表提供編輯相關連結的表單。" + +#: lib/perl5/Selima/Form/Link.pm:46 +msgid "This table provides you a form to delete a related link." +msgstr "本表提供刪除相關連結的表單。" + +#: lib/perl5/Selima/Form/Link.pm:65 +msgid "Add a New Related Link" +msgstr "建新相關連結" + +#: lib/perl5/Selima/Form/Link.pm:68 +msgid "Edit a Current Related Link" +msgstr "編輯相關連結" + +#: lib/perl5/Selima/Form/Link.pm:71 +msgid "Delete a Related Link" +msgstr "刪除相關連結" + +#: lib/perl5/Selima/Form/Link.pm:81 +msgid "[numerate,_1,Category,Categories]:" +msgstr "分類:" + +#: lib/perl5/Selima/Form/Link.pm:88 +msgid "Hide this related link" +msgstr "隱藏這筆相關連結" + +#: lib/perl5/Selima/Form/Link.pm:88 +msgid "Show this related link" +msgstr "秀出這筆相關連結" + +#: lib/perl5/Selima/Form/Link.pm:89 +msgid "Hide this related link currently." +msgstr "暫勿秀出這筆相關連結。" + +#: lib/perl5/Selima/Form/Link.pm:100 +msgid "Link icon:" +msgstr "連結小圖:" + +#: lib/perl5/Selima/Form/Link.pm:101 +msgid "Link icon unavailable" +msgstr "連結小圖無法顯示" + +#: lib/perl5/Selima/Form/Link.pm:173 +msgid "2nd language title:" +msgstr "第二語言標題:" + +#: lib/perl5/Selima/Form/Page.pm:32 +msgid "Delete this page" +msgstr "刪掉這一頁" + +#: lib/perl5/Selima/Form/Page.pm:37 +msgid "This table provides you a form to write a new page." +msgstr "本表提供寫新網頁的表單。" + +#: lib/perl5/Selima/Form/Page.pm:40 +msgid "This table provides you a form to edit a current page." +msgstr "本表提供編輯網頁的表單。" + +#: lib/perl5/Selima/Form/Page.pm:43 +msgid "This table provides you a form to delete a page." +msgstr "本表提供刪除網頁的表單。" + +#: lib/perl5/Selima/Form/Page.pm:60 +msgid "Write a New Page" +msgstr "寫新網頁" + +#: lib/perl5/Selima/Form/Page.pm:63 +msgid "Edit a Current Page" +msgstr "編輯網頁" + +#: lib/perl5/Selima/Form/Page.pm:66 +msgid "Delete a Page" +msgstr "刪除網頁" + +#: lib/perl5/Selima/Form/Page.pm:73 +msgid "Preview this page." +msgstr "預覽本頁。" + +#: lib/perl5/Selima/Form/Page.pm:82 +msgid "Hide this page" +msgstr "隱藏這頁網頁" + +#: lib/perl5/Selima/Form/Page.pm:82 +msgid "Show this page" +msgstr "秀出這頁網頁" + +#: lib/perl5/Selima/Form/Page.pm:83 +msgid "Hide this page currently." +msgstr "暫勿秀出這頁網頁。" + +#: lib/perl5/Selima/Form/Rebuild.pm:36 +msgid "Rebuild the Pages" +msgstr "重製網頁" + +#: lib/perl5/Selima/Form/Rebuild.pm:41 +msgid "Confirm" +msgstr "確定" + +#: lib/perl5/Selima/Form/ScptPriv.pm:33 +msgid "Delete this script privilege record" +msgstr "刪掉這筆程式權限資料" + +#: lib/perl5/Selima/Form/ScptPriv.pm:38 +msgid "This table provides you a form to add a new script privilege record." +msgstr "本表提供建新程式權限資料的表單。" + +#: lib/perl5/Selima/Form/ScptPriv.pm:41 +msgid "" +"This table provides you a form to change a current script privilege record." +msgstr "本表提供變更程式權限資料的表單。" + +#: lib/perl5/Selima/Form/ScptPriv.pm:44 +msgid "This table provides you a form to delete a script privilege record." +msgstr "本表提供刪除程式權限資料的表單。" + +#: lib/perl5/Selima/Form/ScptPriv.pm:61 +msgid "Add A New Script Privilege Record" +msgstr "建新程式權限資料" + +#: lib/perl5/Selima/Form/ScptPriv.pm:64 +msgid "Change a Current Script Privilege Record" +msgstr "變更程式權限資料" + +#: lib/perl5/Selima/Form/ScptPriv.pm:67 +msgid "Delete a Script Privilege Record" +msgstr "刪除程式權限資料" + +#: lib/perl5/Selima/Form/ScptPriv.pm:76 +msgid "Privilege:" +msgstr "權限:" + +#: lib/perl5/Selima/Form/UserMem.pm:61 +msgid "Add A New User Membership Record" +msgstr "建新使用者成員關係" + +#: lib/perl5/Selima/Form/UserMem.pm:64 +msgid "Change a Current User Membership Record" +msgstr "變更使用者成員關係" + +#: lib/perl5/Selima/Form/UserMem.pm:67 +msgid "Delete a User Membership Record" +msgstr "刪除使用者成員關係" + +#: lib/perl5/Selima/Form/User.pm:39 +msgid "Delete this user account" +msgstr "刪掉這個帳號" + +#: lib/perl5/Selima/Form/User.pm:46 +msgid "This table provides you a form to add a new user account." +msgstr "本表提供建新帳號的表單。" + +#: lib/perl5/Selima/Form/User.pm:49 +msgid "This table provides you a form to update a current user account." +msgstr "本表提供設定帳號的表單。" + +#: lib/perl5/Selima/Form/User.pm:52 +msgid "This table provides you a form to delete a user account." +msgstr "本表提供刪除帳號的表單。" + +#: lib/perl5/Selima/Form/User.pm:70 +msgid "Add a New User Account" +msgstr "建新帳號" + +#: lib/perl5/Selima/Form/User.pm:73 +msgid "Update a Current User Account" +msgstr "設定帳號" + +#: lib/perl5/Selima/Form/User.pm:76 +msgid "Delete a User Account" +msgstr "刪除帳號" + +#: lib/perl5/Selima/Form/User.pm:84 +msgid "This is a super-user. You can only change parts of her/his infomation." +msgstr "這個人是總管理員,妳只能設定她/他部份的資料。" + +#: lib/perl5/Selima/Form/User.pm:143 +msgid "Administrator?" +msgstr "網站管理員?" + +#: lib/perl5/Selima/Form/User.pm:144 +msgid "Administrator" +msgstr "網站管理員" + +#: lib/perl5/Selima/Form/User.pm:144 +msgid "Non-administrator" +msgstr "普通使用者" + +#: lib/perl5/Selima/Form/User.pm:165 +msgid "Disable this user account." +msgstr "帳號停用。" + +#: lib/perl5/Selima/Form/User.pm:176 lib/perl5/Selima/Form/User.pm:178 +msgid "User ID.:" +msgstr "使用者代號:" + +#: lib/perl5/Selima/Form/User.pm:184 +msgid "Pref. language:" +msgstr "語言偏好:" + +#: lib/perl5/Selima/Form/User.pm:189 +msgid "Full name:" +msgstr "姓名:" + +#: lib/perl5/Selima/Form/UserPref.pm:35 +msgid "Delete this user preference" +msgstr "刪掉這筆使用者偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:40 +msgid "This table provides you a form to add a new user preference." +msgstr "本表提供建新使用者偏好的表單。" + +#: lib/perl5/Selima/Form/UserPref.pm:43 +msgid "This table provides you a form to modify a current user preference." +msgstr "本表提供設定使用者偏好的表單。" + +#: lib/perl5/Selima/Form/UserPref.pm:46 +msgid "This table provides you a form to delete a user preference." +msgstr "本表提供刪除使用者偏好的表單。" + +#: lib/perl5/Selima/Form/UserPref.pm:63 +msgid "Add A New User Preference" +msgstr "建新使用者偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:66 +msgid "Modify a Current User Preference" +msgstr "設定使用者偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:69 +msgid "Delete a User Preference" +msgstr "刪除使用者偏好" + +#: lib/perl5/Selima/Form/UserPref.pm:82 +msgid "Domain:" +msgstr "適用範圍:" + +#: lib/perl5/Selima/Form/UserPref.pm:83 +msgid "Everywhere" +msgstr "所有地方" + +#: lib/perl5/Selima/Form/UserPref.pm:88 +msgid "User:" +msgstr "使用者:" + +#: lib/perl5/Selima/Form/UserPref.pm:89 +msgid "Everyone" +msgstr "所有人" + +#: lib/perl5/Selima/List/ActLog.pm:31 +msgid "Browse the Activity Log" +msgstr "查閱網站活動日誌" + +#: lib/perl5/Selima/List/ActLog.pm:132 +msgid "Please fill in the number of rows to display." +msgstr "請填上顯示筆數。" + +#: lib/perl5/Selima/List/ActLog.pm:135 +msgid "Please fill in a positive integer number of rows to display." +msgstr "顯示筆數請填正整數。" + +#: lib/perl5/Selima/List/ActLog.pm:140 +msgid "This number of rows to display is too long. (Max. length [#,_1])" +msgstr "顯示筆數太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/List/ActLog.pm:157 +msgid "Search for log entries:" +msgstr "搜尋記錄:" + +#: lib/perl5/Selima/List/ActLog.pm:162 +msgid "Display" +msgstr "顯示" + +#: lib/perl5/Selima/List/ActLog.pm:163 +msgid "Display rows:" +msgstr "顯示筆數:" + +#: lib/perl5/Selima/List/ActLog.pm:198 +msgid "Your query found [*,_1,log entry,log entries]." +msgstr "共 [#,_1] 筆相符的記錄。" + +#: lib/perl5/Selima/List/ActLog.pm:201 +msgid "[*,_1,log entry,log entries]." +msgstr "共 [#,_1] 筆記錄。" + +#: lib/perl5/Selima/List/ActLog.pm:207 +msgid "" +"Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的記錄,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/ActLog.pm:211 +msgid "[*,_1,log entry,log entries], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆記錄,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Category.pm:18 +msgid "Add a new category." +msgstr "建新連結分類。" + +#: lib/perl5/Selima/List/Category.pm:24 +msgid "Search for a category:" +msgstr "搜尋分類:" + +#: lib/perl5/Selima/List/Category.pm:41 +msgid "Your query found [*,_1,category,categories]." +msgstr "共 [#,_1] 個相符的分類。" + +#: lib/perl5/Selima/List/Category.pm:44 +msgid "[*,_1,category,categories]." +msgstr "共 [#,_1] 個分類。" + +#: lib/perl5/Selima/List/Category.pm:50 +msgid "Your query found [*,_1,category,categories], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個相符的分類,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: lib/perl5/Selima/List/Category.pm:54 +msgid "[*,_1,category,categories], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個分類,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: lib/perl5/Selima/List/Categorz.pm:18 +msgid "Add a new categorization record." +msgstr "建新分類資料。" + +#: lib/perl5/Selima/List/Categorz.pm:24 +msgid "Search for a categorization record:" +msgstr "搜尋分類資料:" + +#: lib/perl5/Selima/List/Categorz.pm:41 +msgid "Your query found [*,_1,categorization record]." +msgstr "共 [#,_1] 筆相符的分類資料。" + +#: lib/perl5/Selima/List/Categorz.pm:44 +msgid "[*,_1,categorization record]." +msgstr "共 [#,_1] 筆分類資料。" + +#: lib/perl5/Selima/List/Categorz.pm:50 +msgid "" +"Your query found [*,_1,categorization record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的分類資料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Categorz.pm:54 +msgid "[*,_1,categorization record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆分類資料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/GroupMem.pm:24 +msgid "Select a Group Membership Record" +msgstr "選擇群組成員關係" + +#: lib/perl5/Selima/List/GroupMem.pm:25 +msgid "Manage Group Membership" +msgstr "管理群組成員關係" + +#: lib/perl5/Selima/List/GroupMem.pm:30 lib/perl5/Selima/List/UserMem.pm:30 +msgid "Group" +msgstr "群組" + +#: lib/perl5/Selima/List/GroupMem.pm:31 lib/perl5/Selima/List/UserMem.pm:31 +msgid "Member" +msgstr "成員" + +#: lib/perl5/Selima/List/GroupMem.pm:39 lib/perl5/Selima/List/UserMem.pm:39 +msgid "Add a new membership record." +msgstr "建新成員關係。" + +#: lib/perl5/Selima/List/GroupMem.pm:45 lib/perl5/Selima/List/UserMem.pm:45 +msgid "Search for a membership record:" +msgstr "搜尋成員關係:" + +#: lib/perl5/Selima/List/GroupMem.pm:62 lib/perl5/Selima/List/UserMem.pm:62 +msgid "Your query found [*,_1,membership record]." +msgstr "共 [#,_1] 筆相符的成員關係。" + +#: lib/perl5/Selima/List/GroupMem.pm:65 lib/perl5/Selima/List/UserMem.pm:65 +msgid "[*,_1,membership record]." +msgstr "共 [#,_1] 筆成員關係。" + +#: lib/perl5/Selima/List/GroupMem.pm:71 lib/perl5/Selima/List/UserMem.pm:71 +msgid "Your query found [*,_1,membership record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的成員關係,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/GroupMem.pm:75 lib/perl5/Selima/List/UserMem.pm:75 +msgid "[*,_1,membership record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆成員關係,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Groups.pm:23 +msgid "Select a Group" +msgstr "選擇群組" + +#: lib/perl5/Selima/List/Groups.pm:24 +msgid "Manage Groups" +msgstr "管理群組" + +#: lib/perl5/Selima/List/Groups.pm:29 +msgid "Group ID." +msgstr "群組代號" + +#: lib/perl5/Selima/List/Groups.pm:38 +msgid "Add a new group." +msgstr "建新群組。" + +#: lib/perl5/Selima/List/Groups.pm:44 +msgid "Search for a group:" +msgstr "搜尋群組:" + +#: lib/perl5/Selima/List/Groups.pm:61 +msgid "Your query found [*,_1,group]." +msgstr "共 [#,_1] 個相符的群組。" + +#: lib/perl5/Selima/List/Groups.pm:64 +msgid "[*,_1,group]." +msgstr "共 [#,_1] 個群組。" + +#: lib/perl5/Selima/List/Groups.pm:70 +msgid "Your query found [*,_1,group], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個相符的群組,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: lib/perl5/Selima/List/Groups.pm:74 +msgid "[*,_1,group], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個群組,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: lib/perl5/Selima/List/Guestbook.pm:26 +msgid "Select a Message" +msgstr "選擇留言" + +#: lib/perl5/Selima/List/Guestbook.pm:27 +msgid "Manage Guestbook" +msgstr "管理留言簿" + +#: lib/perl5/Selima/List/Guestbook.pm:38 +msgid "Signature" +msgstr "簽名" + +#: lib/perl5/Selima/List/Guestbook.pm:39 +msgid "Identity" +msgstr "身份" + +#: lib/perl5/Selima/List/Guestbook.pm:40 +msgid "Location" +msgstr "所在地" + +#: lib/perl5/Selima/List/Guestbook.pm:41 +msgid "Message" +msgstr "留言" + +#: lib/perl5/Selima/List/Guestbook.pm:42 lib/perl5/Selima/List/Users.pm:35 +msgid "IP" +msgstr "IP" + +#: lib/perl5/Selima/List/Guestbook.pm:43 lib/perl5/Selima/List/Users.pm:36 +msgid "Host" +msgstr "主機" + +#: lib/perl5/Selima/List/Guestbook.pm:44 lib/perl5/Selima/List/Users.pm:37 +msgid "Country" +msgstr "國家" + +#: lib/perl5/Selima/List/Guestbook.pm:45 +msgid "Page No." +msgstr "頁數" + +#: lib/perl5/Selima/List/Guestbook.pm:46 +msgid "Old page No." +msgstr "舊頁數" + +#: lib/perl5/Selima/List/Guestbook.pm:54 +msgid "Write a new message." +msgstr "寫新留言。" + +#: lib/perl5/Selima/List/Guestbook.pm:60 +msgid "Search for a message:" +msgstr "搜尋留言:" + +#: lib/perl5/Selima/List/Guestbook.pm:77 +msgid "Your query found [*,_1,message]." +msgstr "共 [#,_1] 則相符的留言。" + +#: lib/perl5/Selima/List/Guestbook.pm:80 +msgid "[*,_1,message]." +msgstr "共 [#,_1] 則留言。" + +#: lib/perl5/Selima/List/Guestbook.pm:86 +msgid "Your query found [*,_1,message], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則相符的留言,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: lib/perl5/Selima/List/Guestbook.pm:90 +msgid "[*,_1,message], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 則留言,列出第 [#,_2] 則到第 [#,_3] 則。" + +#: lib/perl5/Selima/List/LinkCat.pm:24 +msgid "Select a Link Category" +msgstr "選擇連結分類" + +#: lib/perl5/Selima/List/LinkCat.pm:25 +msgid "Manage Link Categories" +msgstr "管理連結分類" + +#: lib/perl5/Selima/List/LinkCatz.pm:24 +msgid "Select a Link Categorization Record" +msgstr "選擇連結分類資料" + +#: lib/perl5/Selima/List/LinkCatz.pm:25 +msgid "Manage Link Categorization" +msgstr "管理連結分類表" + +#: lib/perl5/Selima/List/LinkCatz.pm:30 +msgid "Link" +msgstr "連結" + +#: lib/perl5/Selima/List/Links.pm:24 +msgid "Select a Related Link" +msgstr "選擇相關連結" + +#: lib/perl5/Selima/List/Links.pm:25 +msgid "Manage Related Links" +msgstr "管理相關連結" + +#: lib/perl5/Selima/List/Links.pm:32 +msgid "2nd language title" +msgstr "第二語言標題" + +#: lib/perl5/Selima/List/Links.pm:33 +msgid "Link icon" +msgstr "連結小圖" + +#: lib/perl5/Selima/List/Links.pm:34 +msgid "Address" +msgstr "地址" + +#: lib/perl5/Selima/List/Links.pm:35 +msgid "Tel." +msgstr "電話" + +#: lib/perl5/Selima/List/Links.pm:36 +msgid "Fax." +msgstr "傳真" + +#: lib/perl5/Selima/List/Links.pm:44 +msgid "Add a new related link." +msgstr "建新相關連結。" + +#: lib/perl5/Selima/List/Links.pm:50 +msgid "Search for a related link:" +msgstr "搜尋相關連結:" + +#: lib/perl5/Selima/List/Links.pm:67 +msgid "Your query found [*,_1,related link]." +msgstr "共 [#,_1] 筆相符的相關連結。" + +#: lib/perl5/Selima/List/Links.pm:70 +msgid "[*,_1,related link]." +msgstr "共 [#,_1] 筆相關連結。" + +#: lib/perl5/Selima/List/Links.pm:76 +msgid "Your query found [*,_1,related link], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的相關連結,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Links.pm:80 +msgid "[*,_1,related link], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相關連結,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Pages.pm:24 +msgid "Select a Page" +msgstr "選擇網頁" + +#: lib/perl5/Selima/List/Pages.pm:25 +msgid "Manage Pages" +msgstr "管理網頁" + +#: lib/perl5/Selima/List/Pages.pm:40 +msgid "Write a new page." +msgstr "寫新網頁。" + +#: lib/perl5/Selima/List/Pages.pm:46 +msgid "Search for a page:" +msgstr "搜尋網頁:" + +#: lib/perl5/Selima/List/Pages.pm:63 +msgid "Your query found [*,_1,page]." +msgstr "共 [#,_1] 頁相符的網頁。" + +#: lib/perl5/Selima/List/Pages.pm:66 +msgid "[*,_1,page]." +msgstr "共 [#,_1] 頁網頁。" + +#: lib/perl5/Selima/List/Pages.pm:72 +msgid "Your query found [*,_1,page], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 頁相符的網頁,列出第 [#,_2] 頁到第 [#,_3] 頁。" + +#: lib/perl5/Selima/List/Pages.pm:76 +msgid "[*,_1,page], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 頁網頁,列出第 [#,_2] 頁到第 [#,_3] 頁。" + +#: lib/perl5/Selima/List/ScptPriv.pm:24 +msgid "Select a Script Privilege Record" +msgstr "選擇程式權限資料" + +#: lib/perl5/Selima/List/ScptPriv.pm:25 +msgid "Manage Script Privileges" +msgstr "管理程式權限表" + +#: lib/perl5/Selima/List/ScptPriv.pm:30 +msgid "Script" +msgstr "程式" + +#: lib/perl5/Selima/List/ScptPriv.pm:31 +msgid "Privilege" +msgstr "權限說明" + +#: lib/perl5/Selima/List/ScptPriv.pm:39 +msgid "Add a new script privilege record." +msgstr "建新程式權限資料。" + +#: lib/perl5/Selima/List/ScptPriv.pm:45 +msgid "Search for a script privilege record:" +msgstr "搜尋程式權限資料:" + +#: lib/perl5/Selima/List/ScptPriv.pm:62 +msgid "Your query found [*,_1,script privilege record]." +msgstr "共 [#,_1] 筆相符的程式權限資料。" + +#: lib/perl5/Selima/List/ScptPriv.pm:65 +msgid "[*,_1,script privilege record]." +msgstr "共 [#,_1] 筆程式權限資料。" + +#: lib/perl5/Selima/List/ScptPriv.pm:71 +msgid "" +"Your query found [*,_1,script privilege record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的程式權限資料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/ScptPriv.pm:75 +msgid "[*,_1,script privilege record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆程式權限資料,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/UserMem.pm:24 +msgid "Select a User Membership Record" +msgstr "選擇使用者成員關係" + +#: lib/perl5/Selima/List/UserMem.pm:25 +msgid "Manage User Membership" +msgstr "管理使用者成員關係" + +#: lib/perl5/Selima/List/UserPref.pm:24 +msgid "Select a User Preference" +msgstr "選擇使用者偏好" + +#: lib/perl5/Selima/List/UserPref.pm:25 +msgid "Manage User Preferences" +msgstr "管理使用者偏好" + +#: lib/perl5/Selima/List/UserPref.pm:30 +msgid "User" +msgstr "使用者" + +#: lib/perl5/Selima/List/UserPref.pm:31 +msgid "Domain" +msgstr "適用範圍" + +#: lib/perl5/Selima/List/UserPref.pm:32 +msgid "Value" +msgstr "值" + +#: lib/perl5/Selima/List/UserPref.pm:40 +msgid "Add a new user preference." +msgstr "建新使用者偏好。" + +#: lib/perl5/Selima/List/UserPref.pm:46 +msgid "Search for a user preference:" +msgstr "搜尋使用者偏好:" + +#: lib/perl5/Selima/List/UserPref.pm:63 +msgid "Your query found [*,_1,user preference]." +msgstr "共 [#,_1] 筆相符的使用者偏好。" + +#: lib/perl5/Selima/List/UserPref.pm:66 +msgid "[*,_1,user preference]." +msgstr "共 [#,_1] 筆使用者偏好。" + +#: lib/perl5/Selima/List/UserPref.pm:72 +msgid "Your query found [*,_1,user preference], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的使用者偏好,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/UserPref.pm:76 +msgid "[*,_1,user preference], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆使用者偏好,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Users.pm:23 +msgid "Select a User" +msgstr "選擇使用者" + +#: lib/perl5/Selima/List/Users.pm:24 +msgid "Manage Users" +msgstr "管理帳號" + +#: lib/perl5/Selima/List/Users.pm:29 +msgid "User ID." +msgstr "使用者代號" + +#: lib/perl5/Selima/List/Users.pm:30 +msgid "Full name" +msgstr "姓名" + +#: lib/perl5/Selima/List/Users.pm:31 +msgid "Deleted?" +msgstr "已刪?" + +#: lib/perl5/Selima/List/Users.pm:32 +msgid "Pref. language" +msgstr "語言偏好" + +#: lib/perl5/Selima/List/Users.pm:33 +msgid "Visits" +msgstr "上站次數" + +#: lib/perl5/Selima/List/Users.pm:34 +msgid "Visited" +msgstr "上站日期" + +#: lib/perl5/Selima/List/Users.pm:45 +msgid "Add a new user account." +msgstr "建新帳號。" + +#: lib/perl5/Selima/List/Users.pm:51 +msgid "Search for a user:" +msgstr "搜尋使用者:" + +#: lib/perl5/Selima/List/Users.pm:68 +msgid "Your query found [*,_1,user]." +msgstr "共 [#,_1] 位相符的使用者。" + +#: lib/perl5/Selima/List/Users.pm:71 +msgid "[*,_1,user]." +msgstr "共 [#,_1] 位使用者。" + +#: lib/perl5/Selima/List/Users.pm:77 +msgid "Your query found [*,_1,user], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位相符的使用者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: lib/perl5/Selima/List/Users.pm:81 +msgid "[*,_1,user], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 位使用者,列出第 [#,_2] 位到第 [#,_3] 位。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:103 +msgid "This accounting record was not modified." +msgstr "會計分錄未異動。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:107 +msgid "This accounting record has been successfully added." +msgstr "會計分錄建好了。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:111 +msgid "This accounting record has been successfully updated." +msgstr "會計分錄存好了。" + +#: lib/perl5/Selima/Processor/AcctRec.pm:115 +msgid "This accounting record has been successfully deleted." +msgstr "會計分錄刪掉了。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:86 +msgid "This accounting subject was not modified." +msgstr "會計科目未異動。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:90 +msgid "This accounting subject has been successfully added." +msgstr "會計科目建好了。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:94 +msgid "This accounting subject has been successfully updated." +msgstr "會計科目存好了。" + +#: lib/perl5/Selima/Processor/AcctSubj.pm:98 +msgid "This accounting subject has been successfully deleted." +msgstr "會計科目刪掉了。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:418 +msgid "This accounting transaction was not modified." +msgstr "會計傳票未異動。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:422 +msgid "This accounting transaction has been successfully added." +msgstr "會計傳票建好了。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:426 +msgid "This accounting transaction has been successfully updated." +msgstr "會計傳票存好了。" + +#: lib/perl5/Selima/Processor/AcctTrx.pm:430 +msgid "This accounting transaction has been successfully deleted." +msgstr "會計傳票刪掉了。" + +#: lib/perl5/Selima/Processor/Category.pm:20 +msgid "This category was not modified." +msgstr "分類未異動。" + +#: lib/perl5/Selima/Processor/Category.pm:24 +msgid "This category has been successfully added." +msgstr "分類建好了。" + +#: lib/perl5/Selima/Processor/Category.pm:28 +msgid "This category has been successfully updated." +msgstr "分類存好了。" + +#: lib/perl5/Selima/Processor/Category.pm:32 +msgid "This category has been successfully deleted." +msgstr "分類刪掉了。" + +#: lib/perl5/Selima/Processor/Categorz.pm:20 +msgid "This categorization record was not modified." +msgstr "分類資料未異動。" + +#: lib/perl5/Selima/Processor/Categorz.pm:24 +msgid "This categorization record has been successfully added." +msgstr "分類資料建好了。" + +#: lib/perl5/Selima/Processor/Categorz.pm:28 +msgid "This categorization record has been successfully updated." +msgstr "分類資料存好了。" + +#: lib/perl5/Selima/Processor/Categorz.pm:32 +msgid "This categorization record has been successfully deleted." +msgstr "分類資料刪掉了。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:79 +msgid "This group membership record was not modified." +msgstr "群組成員關係未異動。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:83 +msgid "This group membership record has been successfully added." +msgstr "群組成員關係建好了。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:87 +msgid "This group membership record has been successfully updated." +msgstr "群組成員關係存好了。" + +#: lib/perl5/Selima/Processor/GroupMem.pm:91 +msgid "This group membership record has been successfully deleted." +msgstr "群組成員關係刪掉了。" + +#: lib/perl5/Selima/Processor/Group.pm:253 +msgid "This group was not modified." +msgstr "群組未異動。" + +#: lib/perl5/Selima/Processor/Group.pm:257 +msgid "This group has been successfully added." +msgstr "群組建好了。" + +#: lib/perl5/Selima/Processor/Group.pm:261 +msgid "This group has been successfully updated." +msgstr "群組存好了。" + +#: lib/perl5/Selima/Processor/Group.pm:265 +msgid "This group has been successfully deleted." +msgstr "群組刪掉了。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:117 +msgid "This message was not modified." +msgstr "留言未異動。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:121 +msgid "This message has been successfully added." +msgstr "留言寫好了。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:125 +msgid "This message has been successfully updated." +msgstr "留言存好了。" + +#: lib/perl5/Selima/Processor/Guestbook.pm:129 +msgid "This message has been successfully deleted." +msgstr "留言刪掉了。" + +#: lib/perl5/Selima/Processor/Link.pm:168 +msgid "This related link was not modified." +msgstr "相關連結未異動。" + +#: lib/perl5/Selima/Processor/Link.pm:172 +msgid "This related link has been successfully added." +msgstr "相關連結建好了。" + +#: lib/perl5/Selima/Processor/Link.pm:176 +msgid "This related link has been successfully updated." +msgstr "相關連結存好了。" + +#: lib/perl5/Selima/Processor/Link.pm:180 +msgid "This related link has been successfully deleted." +msgstr "相關連結刪掉了。" + +#: lib/perl5/Selima/Processor/LogOut.pm:52 +msgid "You have successfully logged out." +msgstr "登出了。" + +#: lib/perl5/Selima/Processor/Page.pm:89 +msgid "This page was not modified." +msgstr "網頁未異動。" + +#: lib/perl5/Selima/Processor/Page.pm:93 +msgid "This page has been successfully added." +msgstr "網頁寫好了。" + +#: lib/perl5/Selima/Processor/Page.pm:97 +msgid "This page has been successfully updated." +msgstr "網頁存好了。" + +#: lib/perl5/Selima/Processor/Page.pm:101 +msgid "This page has been successfully deleted." +msgstr "網頁刪掉了。" + +#: lib/perl5/Selima/Processor/Rebuild.pm:48 +#, c-format +msgid "" +"The specified web pages have been successfully rebuilt. ([sprintf,%0.3f,_1] " +"seconds)" +msgstr "指定的網頁重製好了。( [sprintf,%0.3f,_1] 秒)" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:79 +msgid "This script privilege record was not modified." +msgstr "程式權限未異動。" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:83 +msgid "This script privilege record has been successfully added." +msgstr "程式權限建好了。" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:87 +msgid "This script privilege record has been successfully updated." +msgstr "程式權限存好了。" + +#: lib/perl5/Selima/Processor/ScptPriv.pm:91 +msgid "This script privilege record has been successfully deleted." +msgstr "程式權限刪掉了。" + +#: lib/perl5/Selima/Processor/UserMem.pm:79 +msgid "This user membership record was not modified." +msgstr "使用者成員關係未異動。" + +#: lib/perl5/Selima/Processor/UserMem.pm:83 +msgid "This user membership record has been successfully added." +msgstr "使用者成員關係建好了。" + +#: lib/perl5/Selima/Processor/UserMem.pm:87 +msgid "This user membership record has been successfully updated." +msgstr "使用者成員關係存好了。" + +#: lib/perl5/Selima/Processor/UserMem.pm:91 +msgid "This user membership record has been successfully deleted." +msgstr "使用者成員關係刪掉了。" + +#: lib/perl5/Selima/Processor/User.pm:185 +msgid "This user account was not modified." +msgstr "帳號未異動。" + +#: lib/perl5/Selima/Processor/User.pm:189 +msgid "This user account has been successfully added." +msgstr "帳號建好了。" + +#: lib/perl5/Selima/Processor/User.pm:193 +msgid "This user account has been successfully updated." +msgstr "帳號存好了。" + +#: lib/perl5/Selima/Processor/User.pm:197 +msgid "This user account has been successfully deleted." +msgstr "帳號刪掉了。" + +#: lib/perl5/Selima/Processor/UserPref.pm:128 +msgid "This user preference was not modified." +msgstr "使用者偏好未異動。" + +#: lib/perl5/Selima/Processor/UserPref.pm:132 +msgid "This user preference has been successfully added." +msgstr "使用者偏好建好了。" + +#: lib/perl5/Selima/Processor/UserPref.pm:136 +msgid "This user preference has been successfully updated." +msgstr "使用者偏好存好了。" + +#: lib/perl5/Selima/Processor/UserPref.pm:140 +msgid "This user preference has been successfully deleted." +msgstr "使用者偏好刪掉了。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:37 +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:59 +msgid "Your signature is too long. (Max. length [#,_1])" +msgstr "妳的簽名太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:56 +msgid "Please fill in your signature." +msgstr "請填上妳的簽名。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:80 +msgid "Your identity is too long. (Max. length [#,_1])" +msgstr "妳的身份太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:101 +msgid "Your location is too long. (Max. length [#,_1])" +msgstr "妳的所在地太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:122 +msgid "Your e-mail is too long. (Max. length [#,_1])" +msgstr "妳的 E-mail 信箱太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:143 +msgid "Your website URL is too long. (Max. length [#,_1])" +msgstr "妳的網站網址太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:163 +#: lib/perl5/Selima/Form/Guestbook/Public.pm:60 +msgid "Fill in your message here." +msgstr "請填上妳的留言。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:164 +msgid "Please fill in your message." +msgstr "請填上妳的留言。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:167 +msgid "Your message is too long. (Max. length [#,_1])" +msgstr "妳的留言太長了。(最長 [#,_1] )" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:186 +msgid "You can post at most 5 messages in 1 hour." +msgstr "一小時最多只能留五篇留言。" + +#: lib/perl5/Selima/Checker/Guestbook/Public.pm:204 +msgid "Your message is already posted." +msgstr "留言已經留了。" + +#: lib/perl5/Selima/Form/Guestbook/Public.pm:40 +msgid "Leave a messsage" +msgstr "留言" + +#: lib/perl5/Selima/Form/Guestbook/Public.pm:42 +msgid "This table provides you a form to leave a message." +msgstr "本表提供留言的表單。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:27 +msgid "Select an Accounting Record" +msgstr "選擇會計分錄" + +#: lib/perl5/Selima/List/Accounting/Records.pm:28 +msgid "Manage Accounting Records" +msgstr "管理會計分錄" + +#: lib/perl5/Selima/List/Accounting/Records.pm:33 +msgid "Accounting transaction" +msgstr "會計傳票" + +#: lib/perl5/Selima/List/Accounting/Records.pm:34 +msgid "Debit/credit" +msgstr "借/貸" + +#: lib/perl5/Selima/List/Accounting/Records.pm:46 +msgid "Add a new accounting record." +msgstr "建新會計分錄。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:52 +msgid "Search for an accounting record:" +msgstr "搜尋會計分錄:" + +#: lib/perl5/Selima/List/Accounting/Records.pm:69 +#: lib/perl5/Selima/List/Accounting/Reports.pm:634 +msgid "Your query found [*,_1,accounting record]." +msgstr "共 [#,_1] 筆相符的會計分錄。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:72 +#: lib/perl5/Selima/List/Accounting/Reports.pm:637 +msgid "[*,_1,accounting record]." +msgstr "共 [#,_1] 筆會計分錄。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:78 +#: lib/perl5/Selima/List/Accounting/Reports.pm:643 +msgid "Your query found [*,_1,accounting record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的會計分錄,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Accounting/Records.pm:82 +#: lib/perl5/Selima/List/Accounting/Reports.pm:647 +msgid "[*,_1,accounting record], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆會計分錄,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:31 +msgid "View the Accounting Reports" +msgstr "瀏覽會計報表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:72 +msgid "Month" +msgstr "月份" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:77 +msgid "Income" +msgstr "收入" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:78 +msgid "Expense" +msgstr "支出" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:79 +msgid "Balance" +msgstr "餘額" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:137 +msgid "Please specify a month." +msgstr "請設定月份。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:141 +msgid "Please specify a valid month in YYYY-MM format." +msgstr "月份請以 YYYY-MM 格式正確設定。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:176 +msgid "Please specify a year." +msgstr "請設定年份。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:180 +msgid "Please specify a valid year in YYYY format." +msgstr "年份請以 YYYY 格式正確設定。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:211 +msgid "Please specify the start date." +msgstr "請設定啟始日期。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:215 +msgid "Please specify a valid start date in YYYY-MM-DD format." +msgstr "啟始日期請以 YYYY-MM-DD 格式正確填寫。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:226 +msgid "Please specify the end date." +msgstr "請設定結束日期。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:229 +msgid "Please specify a valid end date in YYYY-MM-DD format." +msgstr "結束日期請以 YYYY-MM-DD 格式正確填寫。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:250 +msgid "This option is invalid. Please select a proper date range." +msgstr "日期範圍選項無效,請由表上選擇適當的日期範圍。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:319 +#: lib/perl5/Selima/List/Accounting/Transacts.pm:53 +msgid "" +"Add a new cash expense transaction, add a new cash income transaction or add a new " +"transfer transaction." +msgstr "" +"建新現金支出傳票建新現金收入傳票" +"或建新轉帳傳票。" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:339 +msgid "Report type:" +msgstr "報表類型:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:343 +msgid "Cash book" +msgstr "現金帳" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:347 +msgid "Cash book summary" +msgstr "現金帳摘要" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:351 +msgid "Ledger" +msgstr "分類帳" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:355 +msgid "Ledger summary" +msgstr "分類帳摘要" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:359 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:31 +msgid "Journal" +msgstr "日記簿" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:363 +msgid "Trial balance" +msgstr "試算表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:367 +msgid "Income statement" +msgstr "損益表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:371 +msgid "Balance sheet" +msgstr "資產負債表" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:408 +msgid "Search the accounting records:" +msgstr "帳目檢索:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:442 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:297 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:253 +msgid "Query" +msgstr "查詢" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:443 +msgid "Date range:" +msgstr "日期範圍:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:444 +msgid "By month:" +msgstr "依月份:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:445 +msgid "By year:" +msgstr "依年度:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:446 +msgid "Specified date range:" +msgstr "特定期間:" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:447 +msgid "All" +msgstr "全部" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:448 +msgid "From" +msgstr "自" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:449 +msgid "to" +msgstr "至" + +#: lib/perl5/Selima/List/Accounting/Reports.pm:563 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:332 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:326 +msgid "From [_1] to [_2]." +msgstr "自 [_1] 至 [_2] 。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:24 +msgid "Select an Accounting Subject" +msgstr "選擇會計科目" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:25 +msgid "Manage Accounting Subjects" +msgstr "管理會計科目" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:30 +msgid "Parent subject" +msgstr "大科目" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:31 +msgid "Code" +msgstr "代碼" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:39 +msgid "Add a new accounting subject." +msgstr "建新會計科目。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:45 +msgid "Search for an accounting subject:" +msgstr "搜尋會計科目:" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:62 +msgid "Your query found [*,_1,accounting subject]." +msgstr "共 [#,_1] 個相符的會計科目。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:65 +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:355 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:349 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:251 +msgid "[*,_1,accounting subject]." +msgstr "[#,_1] 個會計科目。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:71 +msgid "Your query found [*,_1,accounting subject], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個相符的會計科目,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: lib/perl5/Selima/List/Accounting/Subjects.pm:75 +msgid "[*,_1,accounting subject], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 個會計科目,列出第 [#,_2] 個到第 [#,_3] 個。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:26 +msgid "Select an Accounting Transaction" +msgstr "選擇會計傳票" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:27 +msgid "Manage Accounting Transactions" +msgstr "管理會計傳票" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:32 +msgid "Number" +msgstr "編號" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:33 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:42 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:40 +msgid "Note" +msgstr "註記" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:66 +msgid "Search for an accounting transaction:" +msgstr "搜尋會計傳票:" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:83 +msgid "Your query found [*,_1,accounting transaction]." +msgstr "共 [#,_1] 筆相符的會計傳票。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:86 +msgid "[*,_1,accounting transaction]." +msgstr "[#,_1] 筆會計傳票。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:92 +msgid "" +"Your query found [*,_1,accounting transaction], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆相符的會計傳票,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Accounting/Transacts.pm:96 +msgid "[*,_1,accounting transaction], listing [#,_2] to [#,_3]." +msgstr "共 [#,_1] 筆會計傳票,列出第 [#,_2] 筆到第 [#,_3] 筆。" + +#: lib/perl5/Selima/List/Guestbook/Public.pm:196 +msgid "~[Edit~]" +msgstr "~[編輯~]" + +#: lib/perl5/Selima/List/Guestbook/Public.pm:205 +msgid "The message entry seperator" +msgstr "留言分隔線" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:29 +msgid "Balance Sheet" +msgstr "資產負債表" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:40 +msgid "Assets accounting subject" +msgstr "資產會計科目" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:41 +msgid "Assets amount" +msgstr "資產金額" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:42 +msgid "Liabilities accounting subject" +msgstr "負債會計科目" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:43 +msgid "Liabilities amount" +msgstr "負債金額" + +#: lib/perl5/Selima/List/Accounting/Reports/BlncShet.pm:289 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:379 +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:283 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:273 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:351 +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:204 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:421 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:366 +msgid "Download the data as a CSV file." +msgstr "下載 CSV 格式資料檔。" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:45 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:150 +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:339 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:40 +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:383 +msgid "current assets and liabilities" +msgstr "流動資產與負債" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash.pm:48 +msgid "Cash book - [_1]" +msgstr "現金帳 - [_1]" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:29 +msgid "Income Statement" +msgstr "損益表" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:187 +msgid "Gross income" +msgstr "營業毛利" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:189 +msgid "Operating income" +msgstr "營業淨利" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:191 +msgid "Before tax income" +msgstr "稅前淨利" + +#: lib/perl5/Selima/List/Accounting/Reports/IncmStat.pm:193 +msgid "After tax income" +msgstr "稅後淨利" + +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:41 +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:39 +msgid "Transaction Number" +msgstr "傳票編號" + +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:127 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:138 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:151 +#: lib/perl5/Selima/List/Accounting/Reports/Journal.pm:162 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:126 +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:140 +msgid "Brought forward" +msgstr "上期結轉" + +#: lib/perl5/Selima/List/Accounting/Reports/Ledger.pm:46 +msgid "Ledger - [_1]" +msgstr "分類帳 - [_1]" + +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:26 +msgid "Search the Accounting Records" +msgstr "帳目檢索" + +#: lib/perl5/Selima/List/Accounting/Reports/Search.pm:28 +msgid "Search Result" +msgstr "檢索結果" + +#: lib/perl5/Selima/List/Accounting/Reports/TriBlnc.pm:28 +msgid "Trial Balance" +msgstr "試算表" + +#: lib/perl5/Selima/List/Accounting/Reports/Cash/Summary.pm:43 +msgid "Cash Book Summary - [_1]" +msgstr "現金帳摘要 - [_1]" + +#: lib/perl5/Selima/List/Accounting/Reports/Ledger/Summary.pm:41 +msgid "Ledger Summary - [_1]" +msgstr "分類帳摘要 - [_1]" diff --git a/w3c/cssom.gif b/w3c/cssom.gif new file mode 100644 index 0000000..7813294 Binary files /dev/null and b/w3c/cssom.gif differ diff --git a/w3c/cssom.png b/w3c/cssom.png new file mode 100644 index 0000000..c2bf67d Binary files /dev/null and b/w3c/cssom.png differ diff --git a/w3c/cssos.gif b/w3c/cssos.gif new file mode 100644 index 0000000..922cfee Binary files /dev/null and b/w3c/cssos.gif differ diff --git a/w3c/cssos.png b/w3c/cssos.png new file mode 100644 index 0000000..65025ee Binary files /dev/null and b/w3c/cssos.png differ diff --git a/w3c/csstm.gif b/w3c/csstm.gif new file mode 100644 index 0000000..a4a406e Binary files /dev/null and b/w3c/csstm.gif differ diff --git a/w3c/csstm.png b/w3c/csstm.png new file mode 100644 index 0000000..b6ea406 Binary files /dev/null and b/w3c/csstm.png differ diff --git a/w3c/cssts.gif b/w3c/cssts.gif new file mode 100644 index 0000000..b55c632 Binary files /dev/null and b/w3c/cssts.gif differ diff --git a/w3c/cssts.png b/w3c/cssts.png new file mode 100644 index 0000000..d2a750b Binary files /dev/null and b/w3c/cssts.png differ diff --git a/w3c/mwcos.gif b/w3c/mwcos.gif new file mode 100644 index 0000000..f7ec53e Binary files /dev/null and b/w3c/mwcos.gif differ diff --git a/w3c/mwcos.png b/w3c/mwcos.png new file mode 100644 index 0000000..40d88c3 Binary files /dev/null and b/w3c/mwcos.png differ diff --git a/w3c/mwcss.gif b/w3c/mwcss.gif new file mode 100644 index 0000000..f7ec53e Binary files /dev/null and b/w3c/mwcss.gif differ diff --git a/w3c/mwcts.gif b/w3c/mwcts.gif new file mode 100644 index 0000000..74a06ca Binary files /dev/null and b/w3c/mwcts.gif differ diff --git a/w3c/mwcts.png b/w3c/mwcts.png new file mode 100644 index 0000000..0ab1ce0 Binary files /dev/null and b/w3c/mwcts.png differ diff --git a/w3c/valid-css.gif b/w3c/valid-css.gif new file mode 100644 index 0000000..020c75a Binary files /dev/null and b/w3c/valid-css.gif differ diff --git a/w3c/valid-css.png b/w3c/valid-css.png new file mode 100644 index 0000000..9b2f596 Binary files /dev/null and b/w3c/valid-css.png differ diff --git a/w3c/valid-html32.gif b/w3c/valid-html32.gif new file mode 100644 index 0000000..30efab6 Binary files /dev/null and b/w3c/valid-html32.gif differ diff --git a/w3c/valid-html32.png b/w3c/valid-html32.png new file mode 100644 index 0000000..3d62200 Binary files /dev/null and b/w3c/valid-html32.png differ diff --git a/w3c/valid-html40.gif b/w3c/valid-html40.gif new file mode 100644 index 0000000..c5e9402 Binary files /dev/null and b/w3c/valid-html40.gif differ diff --git a/w3c/valid-html40.png b/w3c/valid-html40.png new file mode 100644 index 0000000..a6cf106 Binary files /dev/null and b/w3c/valid-html40.png differ diff --git a/w3c/valid-html401.gif b/w3c/valid-html401.gif new file mode 100644 index 0000000..1270561 Binary files /dev/null and b/w3c/valid-html401.gif differ diff --git a/w3c/valid-html401.png b/w3c/valid-html401.png new file mode 100644 index 0000000..3855210 Binary files /dev/null and b/w3c/valid-html401.png differ diff --git a/w3c/valid-xhtml10.gif b/w3c/valid-xhtml10.gif new file mode 100644 index 0000000..4eba962 Binary files /dev/null and b/w3c/valid-xhtml10.gif differ diff --git a/w3c/valid-xhtml10.png b/w3c/valid-xhtml10.png new file mode 100644 index 0000000..2275ee6 Binary files /dev/null and b/w3c/valid-xhtml10.png differ diff --git a/w3c/valid-xhtml11.gif b/w3c/valid-xhtml11.gif new file mode 100644 index 0000000..61dd32a Binary files /dev/null and b/w3c/valid-xhtml11.gif differ diff --git a/w3c/valid-xhtml11.png b/w3c/valid-xhtml11.png new file mode 100644 index 0000000..2c63d93 Binary files /dev/null and b/w3c/valid-xhtml11.png differ diff --git a/w3c/valid-xml10.gif b/w3c/valid-xml10.gif new file mode 100644 index 0000000..5585f2c Binary files /dev/null and b/w3c/valid-xml10.gif differ diff --git a/w3c/vcss-new.gif b/w3c/vcss-new.gif new file mode 100644 index 0000000..7530d30 Binary files /dev/null and b/w3c/vcss-new.gif differ diff --git a/w3c/vcss-new.png b/w3c/vcss-new.png new file mode 100644 index 0000000..ae2caf3 Binary files /dev/null and b/w3c/vcss-new.png differ diff --git a/w3c/vcss-old.gif b/w3c/vcss-old.gif new file mode 100644 index 0000000..6a5feb7 Binary files /dev/null and b/w3c/vcss-old.gif differ diff --git a/w3c/vcss-old.png b/w3c/vcss-old.png new file mode 100644 index 0000000..7f998ef Binary files /dev/null and b/w3c/vcss-old.png differ diff --git a/w3c/vcss.gif b/w3c/vcss.gif new file mode 100644 index 0000000..020c75a Binary files /dev/null and b/w3c/vcss.gif differ diff --git a/w3c/vcss.png b/w3c/vcss.png new file mode 100644 index 0000000..9b2f596 Binary files /dev/null and b/w3c/vcss.png differ diff --git a/w3c/vh20.gif b/w3c/vh20.gif new file mode 100644 index 0000000..b908c3a Binary files /dev/null and b/w3c/vh20.gif differ diff --git a/w3c/vh20.png b/w3c/vh20.png new file mode 100644 index 0000000..bac6553 Binary files /dev/null and b/w3c/vh20.png differ diff --git a/w3c/vh30.gif b/w3c/vh30.gif new file mode 100644 index 0000000..e7e42f0 Binary files /dev/null and b/w3c/vh30.gif differ diff --git a/w3c/vh30.png b/w3c/vh30.png new file mode 100644 index 0000000..c460b5e Binary files /dev/null and b/w3c/vh30.png differ diff --git a/w3c/vh32.gif b/w3c/vh32.gif new file mode 100644 index 0000000..30efab6 Binary files /dev/null and b/w3c/vh32.gif differ diff --git a/w3c/vh32.png b/w3c/vh32.png new file mode 100644 index 0000000..3d62200 Binary files /dev/null and b/w3c/vh32.png differ diff --git a/w3c/vh40.gif b/w3c/vh40.gif new file mode 100644 index 0000000..c5e9402 Binary files /dev/null and b/w3c/vh40.gif differ diff --git a/w3c/vh40.png b/w3c/vh40.png new file mode 100644 index 0000000..a6cf106 Binary files /dev/null and b/w3c/vh40.png differ diff --git a/w3c/vh401.gif b/w3c/vh401.gif new file mode 100644 index 0000000..1270561 Binary files /dev/null and b/w3c/vh401.gif differ diff --git a/w3c/vh401.png b/w3c/vh401.png new file mode 100644 index 0000000..3855210 Binary files /dev/null and b/w3c/vh401.png differ diff --git a/w3c/vhhj.gif b/w3c/vhhj.gif new file mode 100644 index 0000000..8116436 Binary files /dev/null and b/w3c/vhhj.gif differ diff --git a/w3c/vhhj.png b/w3c/vhhj.png new file mode 100644 index 0000000..eec18f5 Binary files /dev/null and b/w3c/vhhj.png differ diff --git a/w3c/vhns.gif b/w3c/vhns.gif new file mode 100644 index 0000000..b2ab3f6 Binary files /dev/null and b/w3c/vhns.gif differ diff --git a/w3c/vhns.png b/w3c/vhns.png new file mode 100644 index 0000000..9113d55 Binary files /dev/null and b/w3c/vhns.png differ diff --git a/w3c/vxhtml-basic10.gif b/w3c/vxhtml-basic10.gif new file mode 100644 index 0000000..e4c2830 Binary files /dev/null and b/w3c/vxhtml-basic10.gif differ diff --git a/w3c/vxhtml-basic10.png b/w3c/vxhtml-basic10.png new file mode 100644 index 0000000..9c1a831 Binary files /dev/null and b/w3c/vxhtml-basic10.png differ diff --git a/w3c/vxhtml10.gif b/w3c/vxhtml10.gif new file mode 100644 index 0000000..4eba962 Binary files /dev/null and b/w3c/vxhtml10.gif differ diff --git a/w3c/vxhtml10.png b/w3c/vxhtml10.png new file mode 100644 index 0000000..2275ee6 Binary files /dev/null and b/w3c/vxhtml10.png differ diff --git a/w3c/vxhtml11.gif b/w3c/vxhtml11.gif new file mode 100644 index 0000000..61dd32a Binary files /dev/null and b/w3c/vxhtml11.gif differ diff --git a/w3c/vxhtml11.png b/w3c/vxhtml11.png new file mode 100644 index 0000000..2c63d93 Binary files /dev/null and b/w3c/vxhtml11.png differ diff --git a/w3c/vxml10.gif b/w3c/vxml10.gif new file mode 100644 index 0000000..5585f2c Binary files /dev/null and b/w3c/vxml10.gif differ diff --git a/w3c/wcag1A.gif b/w3c/wcag1A.gif new file mode 100644 index 0000000..b82d6e7 Binary files /dev/null and b/w3c/wcag1A.gif differ diff --git a/w3c/wcag1A.png b/w3c/wcag1A.png new file mode 100644 index 0000000..c31d479 Binary files /dev/null and b/w3c/wcag1A.png differ diff --git a/w3c/wcag1AA.gif b/w3c/wcag1AA.gif new file mode 100644 index 0000000..fa2c6ee Binary files /dev/null and b/w3c/wcag1AA.gif differ diff --git a/w3c/wcag1AA.png b/w3c/wcag1AA.png new file mode 100644 index 0000000..9cbacba Binary files /dev/null and b/w3c/wcag1AA.png differ diff --git a/w3c/wcag1AAA.gif b/w3c/wcag1AAA.gif new file mode 100644 index 0000000..e3f239d Binary files /dev/null and b/w3c/wcag1AAA.gif differ diff --git a/w3c/wcag1AAA.png b/w3c/wcag1AAA.png new file mode 100644 index 0000000..46d9f93 Binary files /dev/null and b/w3c/wcag1AAA.png differ